summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/admin-guide/pm/cpufreq.rst96
-rw-r--r--Documentation/devicetree/bindings/arm/freescale/mxc_ion.txt23
-rw-r--r--Documentation/devicetree/bindings/ata/imx-sata.txt4
-rw-r--r--Documentation/devicetree/bindings/clock/imx7ulp-clock.txt59
-rw-r--r--Documentation/devicetree/bindings/crypto/fsl-dcp.txt2
-rw-r--r--Documentation/devicetree/bindings/crypto/fsl-sec4.txt492
-rw-r--r--Documentation/devicetree/bindings/display/bridge/adi,adv7511.txt33
-rw-r--r--Documentation/devicetree/bindings/display/bridge/it6263.txt29
-rw-r--r--Documentation/devicetree/bindings/display/bridge/nwl_dsi.txt115
-rw-r--r--Documentation/devicetree/bindings/display/bridge/nxp,seiko-43wvfig.txt40
-rw-r--r--Documentation/devicetree/bindings/display/bridge/sec_dsim.txt60
-rw-r--r--Documentation/devicetree/bindings/display/imx/dsi_nwl.txt78
-rw-r--r--Documentation/devicetree/bindings/display/imx/fsl-imx-drm.txt265
-rw-r--r--Documentation/devicetree/bindings/display/imx/ldb.txt49
-rw-r--r--Documentation/devicetree/bindings/display/mxsfb.txt57
-rw-r--r--Documentation/devicetree/bindings/display/panel/jdi,tx26d202vm0bwa.txt9
-rw-r--r--Documentation/devicetree/bindings/display/panel/raydium,rm67191.txt61
-rw-r--r--Documentation/devicetree/bindings/display/panel/seiko,43wvf1g.txt23
-rw-r--r--Documentation/devicetree/bindings/dma/fsl-edma-v3.txt73
-rw-r--r--Documentation/devicetree/bindings/dma/fsl-edma.txt1
-rw-r--r--Documentation/devicetree/bindings/dma/fsl-imx-dma.txt15
-rw-r--r--Documentation/devicetree/bindings/dma/fsl-imx-sdma.txt13
-rw-r--r--Documentation/devicetree/bindings/extcon/extcon-ptn5150.txt28
-rw-r--r--Documentation/devicetree/bindings/fb/fsl_ipuv3_fb.txt105
-rw-r--r--Documentation/devicetree/bindings/gpio/gpio-imx-rpmsg.txt57
-rw-r--r--Documentation/devicetree/bindings/gpio/gpio-max732x.txt1
-rw-r--r--Documentation/devicetree/bindings/gpio/gpio-vf610.txt6
-rw-r--r--Documentation/devicetree/bindings/i2c/i2c-imx-lpi2c.txt4
-rw-r--r--Documentation/devicetree/bindings/i2c/i2c-mux-pca954x.txt3
-rw-r--r--Documentation/devicetree/bindings/i2c/i2c-rpmsg-imx.txt29
-rw-r--r--Documentation/devicetree/bindings/i2c/i2c-xen.txt14
-rw-r--r--Documentation/devicetree/bindings/input/imx-rpmsg-input.txt12
-rw-r--r--Documentation/devicetree/bindings/input/imx-sc-pwrkey.txt22
-rw-r--r--Documentation/devicetree/bindings/input/rpmsg-keys.txt33
-rw-r--r--Documentation/devicetree/bindings/input/touchscreen/focaltech-ts.txt48
-rw-r--r--Documentation/devicetree/bindings/input/touchscreen/vtl_ts.txt18
-rw-r--r--Documentation/devicetree/bindings/interrupt-controller/nxp,imx-intmux.txt55
-rw-r--r--Documentation/devicetree/bindings/interrupt-controller/nxp,imx-irqsteer.txt44
-rw-r--r--Documentation/devicetree/bindings/media/i2c/ov5640_mipi.txt114
-rw-r--r--Documentation/devicetree/bindings/mfd/syscon.txt8
-rw-r--r--Documentation/devicetree/bindings/mlb/mxc_mlb.txt26
-rw-r--r--Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.txt7
-rw-r--r--Documentation/devicetree/bindings/mmc/mmc.txt5
-rw-r--r--Documentation/devicetree/bindings/mtd/fsl-quadspi.txt16
-rw-r--r--Documentation/devicetree/bindings/mtd/gpmi-nand.txt7
-rw-r--r--Documentation/devicetree/bindings/mtd/spi-nor-flash.txt7
-rw-r--r--Documentation/devicetree/bindings/net/can/fsl-flexcan.txt16
-rw-r--r--Documentation/devicetree/bindings/net/fsl-fec.txt13
-rw-r--r--Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.txt23
-rw-r--r--Documentation/devicetree/bindings/phy/mixel,lvds-combo-phy.txt20
-rw-r--r--Documentation/devicetree/bindings/phy/mixel,lvds-phy.txt39
-rw-r--r--Documentation/devicetree/bindings/phy/mixel,mipi-dsi-phy.txt23
-rw-r--r--Documentation/devicetree/bindings/phy/mxs-usb-phy.txt3
-rw-r--r--Documentation/devicetree/bindings/pinctrl/fsl,imx8mm-pinctrl.txt36
-rw-r--r--Documentation/devicetree/bindings/pinctrl/fsl,imx8mq-pinctrl.txt36
-rw-r--r--Documentation/devicetree/bindings/pinctrl/fsl,imx8qm-pinctrl.txt73
-rw-r--r--Documentation/devicetree/bindings/pinctrl/fsl,imx8qxp-pinctrl.txt73
-rw-r--r--Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt7
-rw-r--r--Documentation/devicetree/bindings/pwm/nxp,tpm-pwm.txt18
-rw-r--r--Documentation/devicetree/bindings/regulator/pfuze100.txt2
-rw-r--r--Documentation/devicetree/bindings/reset/gpio-reset.txt36
-rw-r--r--Documentation/devicetree/bindings/rpmsg/imx-rpmsg.txt63
-rw-r--r--Documentation/devicetree/bindings/serial/fsl-lpuart.txt10
-rw-r--r--Documentation/devicetree/bindings/sim/imx_emvsim.txt22
-rw-r--r--Documentation/devicetree/bindings/sim/imx_sim.txt20
-rw-r--r--Documentation/devicetree/bindings/sound/ak4458.txt23
-rw-r--r--Documentation/devicetree/bindings/sound/ak4497.txt23
-rw-r--r--Documentation/devicetree/bindings/sound/ak5558.txt20
-rw-r--r--Documentation/devicetree/bindings/sound/fsl,acm.txt18
-rw-r--r--Documentation/devicetree/bindings/sound/fsl,amix.txt67
-rw-r--r--Documentation/devicetree/bindings/sound/fsl,asrc.txt3
-rw-r--r--Documentation/devicetree/bindings/sound/fsl,dsp.txt16
-rw-r--r--Documentation/devicetree/bindings/sound/fsl,esai.txt9
-rw-r--r--Documentation/devicetree/bindings/sound/fsl,micfil.txt38
-rw-r--r--Documentation/devicetree/bindings/sound/fsl,mqs.txt23
-rw-r--r--Documentation/devicetree/bindings/sound/fsl,rpmsg-i2s.txt22
-rw-r--r--Documentation/devicetree/bindings/sound/fsl,spdif.txt9
-rw-r--r--Documentation/devicetree/bindings/sound/fsl,ssi.txt4
-rw-r--r--Documentation/devicetree/bindings/sound/fsl-sai.txt3
-rw-r--r--Documentation/devicetree/bindings/sound/imx-audio-ak4458.txt30
-rw-r--r--Documentation/devicetree/bindings/sound/imx-audio-ak4497.txt27
-rw-r--r--Documentation/devicetree/bindings/sound/imx-audio-ak5558.txt30
-rw-r--r--Documentation/devicetree/bindings/sound/imx-audio-cdnhdmi.txt16
-rw-r--r--Documentation/devicetree/bindings/sound/imx-audio-cs42888.txt27
-rw-r--r--Documentation/devicetree/bindings/sound/imx-audio-mqs.txt18
-rw-r--r--Documentation/devicetree/bindings/sound/imx-audio-rpmsg.txt13
-rw-r--r--Documentation/devicetree/bindings/sound/imx-audio-si476x.txt24
-rw-r--r--Documentation/devicetree/bindings/sound/imx-audio-wm8524.txt29
-rw-r--r--Documentation/devicetree/bindings/sound/imx-audio-wm8960.txt68
-rw-r--r--Documentation/devicetree/bindings/sound/imx-audio-wm8962.txt12
-rw-r--r--Documentation/devicetree/bindings/sound/imx-audio-xtor.txt30
-rw-r--r--Documentation/devicetree/bindings/sound/imx-pdm-mic.txt16
-rw-r--r--Documentation/devicetree/bindings/sound/wm8962.txt8
-rw-r--r--Documentation/devicetree/bindings/spi/fsl-imx-cspi.txt2
-rw-r--r--Documentation/devicetree/bindings/spi/spi-fsl-lpspi.txt3
-rw-r--r--Documentation/devicetree/bindings/thermal/imx-sc-thermal.txt17
-rw-r--r--Documentation/devicetree/bindings/thermal/imx8mm-thermal.txt17
-rw-r--r--Documentation/devicetree/bindings/trivial-devices.txt3
-rw-r--r--Documentation/devicetree/bindings/usb/cdns-usb3.txt39
-rw-r--r--Documentation/devicetree/bindings/usb/ci-hdrc-usb2.txt45
-rw-r--r--Documentation/devicetree/bindings/usb/dwc3.txt3
-rw-r--r--Documentation/devicetree/bindings/usb/typec-tcpci.txt40
-rw-r--r--Documentation/devicetree/bindings/usb/typec.txt50
-rw-r--r--Documentation/devicetree/bindings/usb/usb-xhci.txt2
-rw-r--r--Documentation/devicetree/bindings/usb/usbmisc-imx.txt2
-rw-r--r--Documentation/devicetree/bindings/vendor-prefixes.txt3
-rw-r--r--Documentation/devicetree/bindings/watchdog/fsl-imx-wdt.txt3
-rw-r--r--Documentation/gpu/drm-kms.rst6
-rw-r--r--Documentation/gpu/kms-properties.csv1
-rw-r--r--Documentation/usb/chipidea.txt13
-rw-r--r--arch/arm/Kconfig11
-rw-r--r--arch/arm/Kconfig.debug8
-rw-r--r--arch/arm/boot/dts/Makefile172
-rw-r--r--arch/arm/boot/dts/imx6dl-aristainetos_4.dts48
-rw-r--r--arch/arm/boot/dts/imx6dl-aristainetos_7.dts51
-rw-r--r--arch/arm/boot/dts/imx6dl-riotboard.dts33
-rw-r--r--arch/arm/boot/dts/imx6dl-sabreauto-ecspi.dts39
-rw-r--r--arch/arm/boot/dts/imx6dl-sabreauto-enetirq.dts19
-rw-r--r--arch/arm/boot/dts/imx6dl-sabreauto-flexcan1.dts18
-rw-r--r--arch/arm/boot/dts/imx6dl-sabreauto-gpmi-weim.dts48
-rw-r--r--arch/arm/boot/dts/imx6dl-sabreauto.dts14
-rw-r--r--arch/arm/boot/dts/imx6dl-sabresd-btwifi.dts10
-rw-r--r--arch/arm/boot/dts/imx6dl-sabresd-enetirq.dts18
-rw-r--r--arch/arm/boot/dts/imx6dl-sabresd-hdcp.dts36
-rw-r--r--arch/arm/boot/dts/imx6dl-sabresd-ldo.dts34
-rw-r--r--arch/arm/boot/dts/imx6dl-sabresd.dts137
-rw-r--r--arch/arm/boot/dts/imx6dl-tx6dl-comtft.dts42
-rw-r--r--arch/arm/boot/dts/imx6dl-tx6u-801x.dts135
-rw-r--r--arch/arm/boot/dts/imx6dl.dtsi113
-rw-r--r--arch/arm/boot/dts/imx6dqscm-1gb-evb-btwifi-fix-ldo.dts10
-rw-r--r--arch/arm/boot/dts/imx6dqscm-1gb-evb-enetirq-fix-ldo.dts18
-rw-r--r--arch/arm/boot/dts/imx6dqscm-1gb-evb-fix-ldo.dts219
-rw-r--r--arch/arm/boot/dts/imx6dqscm-1gb-evb-hdcp-fix-ldo.dts19
-rw-r--r--arch/arm/boot/dts/imx6dqscm-1gb-evb-interleave-android-ldo.dts209
-rw-r--r--arch/arm/boot/dts/imx6dqscm-1gb-fix.dtsi14
-rw-r--r--arch/arm/boot/dts/imx6dqscm-1gb-interleave-android.dtsi14
-rw-r--r--arch/arm/boot/dts/imx6dqscm-1gb-qwks-rev2-fix-ldo.dts62
-rw-r--r--arch/arm/boot/dts/imx6dqscm-1gb-qwks-rev2-hdcp-fix-ldo.dts19
-rw-r--r--arch/arm/boot/dts/imx6dqscm-1gb-qwks-rev2-interleave-android-ldo.dts62
-rw-r--r--arch/arm/boot/dts/imx6dqscm-1gb-qwks-rev2-wifi-fix-ldo.dts10
-rw-r--r--arch/arm/boot/dts/imx6dqscm-1gb-qwks-rev3-btwifi-fix-ldo.dts10
-rw-r--r--arch/arm/boot/dts/imx6dqscm-1gb-qwks-rev3-fix-ldo.dts147
-rw-r--r--arch/arm/boot/dts/imx6dqscm-1gb-qwks-rev3-hdcp-fix-ldo.dts19
-rw-r--r--arch/arm/boot/dts/imx6dqscm-qwks-rev2.dtsi610
-rw-r--r--arch/arm/boot/dts/imx6dqscm-qwks-rev3-btwifi.dtsi86
-rw-r--r--arch/arm/boot/dts/imx6dqscm-qwks-wifi.dtsi94
-rw-r--r--arch/arm/boot/dts/imx6q-arm2-hsic.dts24
-rw-r--r--arch/arm/boot/dts/imx6q-arm2.dts30
-rw-r--r--arch/arm/boot/dts/imx6q-gk802.dts33
-rw-r--r--arch/arm/boot/dts/imx6q-gw5400-a.dts30
-rw-r--r--arch/arm/boot/dts/imx6q-pop-arm2.dts437
-rw-r--r--arch/arm/boot/dts/imx6q-sabreauto-ecspi.dts40
-rw-r--r--arch/arm/boot/dts/imx6q-sabreauto-enetirq.dts19
-rw-r--r--arch/arm/boot/dts/imx6q-sabreauto-flexcan1.dts18
-rw-r--r--arch/arm/boot/dts/imx6q-sabreauto-gpmi-weim.dts49
-rw-r--r--arch/arm/boot/dts/imx6q-sabreauto.dts22
-rw-r--r--arch/arm/boot/dts/imx6q-sabresd-btwifi.dts10
-rw-r--r--arch/arm/boot/dts/imx6q-sabresd-enetirq.dts18
-rw-r--r--arch/arm/boot/dts/imx6q-sabresd-hdcp.dts40
-rw-r--r--arch/arm/boot/dts/imx6q-sabresd-ldo.dts34
-rw-r--r--arch/arm/boot/dts/imx6q-sabresd.dts34
-rw-r--r--arch/arm/boot/dts/imx6q-tbs2910.dts37
-rw-r--r--arch/arm/boot/dts/imx6q-tx6q-1010-comtft.dts42
-rw-r--r--arch/arm/boot/dts/imx6q-tx6q-1010.dts136
-rw-r--r--arch/arm/boot/dts/imx6q-tx6q-1020-comtft.dts42
-rw-r--r--arch/arm/boot/dts/imx6q-tx6q-1020.dts136
-rw-r--r--arch/arm/boot/dts/imx6q.dtsi113
-rw-r--r--arch/arm/boot/dts/imx6qdl-aristainetos.dtsi56
-rw-r--r--arch/arm/boot/dts/imx6qdl-cubox-i.dtsi9
-rw-r--r--arch/arm/boot/dts/imx6qdl-gw51xx.dtsi30
-rw-r--r--arch/arm/boot/dts/imx6qdl-gw52xx.dtsi30
-rw-r--r--arch/arm/boot/dts/imx6qdl-gw53xx.dtsi30
-rw-r--r--arch/arm/boot/dts/imx6qdl-gw54xx.dtsi30
-rw-r--r--arch/arm/boot/dts/imx6qdl-gw552x.dtsi30
-rw-r--r--arch/arm/boot/dts/imx6qdl-hummingboard.dtsi35
-rw-r--r--arch/arm/boot/dts/imx6qdl-nitrogen6x.dtsi33
-rw-r--r--arch/arm/boot/dts/imx6qdl-phytec-pbab01.dtsi27
-rw-r--r--arch/arm/boot/dts/imx6qdl-rex.dtsi33
-rw-r--r--arch/arm/boot/dts/imx6qdl-sabreauto.dtsi593
-rw-r--r--arch/arm/boot/dts/imx6qdl-sabrelite.dtsi10
-rw-r--r--arch/arm/boot/dts/imx6qdl-sabresd-btwifi.dtsi99
-rw-r--r--arch/arm/boot/dts/imx6qdl-sabresd.dtsi575
-rw-r--r--arch/arm/boot/dts/imx6qdl-udoo.dtsi30
-rw-r--r--arch/arm/boot/dts/imx6qdl-wandboard.dtsi7
-rw-r--r--arch/arm/boot/dts/imx6qdl.dtsi221
-rw-r--r--arch/arm/boot/dts/imx6qp-sabreauto-ecspi.dts40
-rw-r--r--arch/arm/boot/dts/imx6qp-sabreauto-flexcan1.dts18
-rw-r--r--arch/arm/boot/dts/imx6qp-sabreauto-gpmi-weim.dts50
-rw-r--r--arch/arm/boot/dts/imx6qp-sabreauto.dts98
-rw-r--r--arch/arm/boot/dts/imx6qp-sabresd-btwifi.dts10
-rw-r--r--arch/arm/boot/dts/imx6qp-sabresd-hdcp.dts39
-rw-r--r--arch/arm/boot/dts/imx6qp-sabresd-ldo-pcie-cert.dts21
-rw-r--r--arch/arm/boot/dts/imx6qp-sabresd-ldo.dts42
-rw-r--r--arch/arm/boot/dts/imx6qp-sabresd.dts108
-rw-r--r--arch/arm/boot/dts/imx6qp.dtsi137
-rw-r--r--arch/arm/boot/dts/imx6sl-evk-btwifi.dts99
-rw-r--r--arch/arm/boot/dts/imx6sl-evk-csi.dts21
-rw-r--r--arch/arm/boot/dts/imx6sl-evk-ldo.dts26
-rw-r--r--arch/arm/boot/dts/imx6sl-evk-uart.dts23
-rw-r--r--arch/arm/boot/dts/imx6sl-evk.dts346
-rw-r--r--arch/arm/boot/dts/imx6sl.dtsi180
-rw-r--r--arch/arm/boot/dts/imx6sll-evk-btwifi.dts78
-rw-r--r--arch/arm/boot/dts/imx6sll-evk-reva.dts13
-rw-r--r--arch/arm/boot/dts/imx6sll-evk.dts821
-rw-r--r--arch/arm/boot/dts/imx6sll-lpddr2-arm2.dts10
-rw-r--r--arch/arm/boot/dts/imx6sll-lpddr3-arm2-csi.dts21
-rw-r--r--arch/arm/boot/dts/imx6sll-lpddr3-arm2-ecspi.dts17
-rw-r--r--arch/arm/boot/dts/imx6sll-lpddr3-arm2-spdif.dts42
-rw-r--r--arch/arm/boot/dts/imx6sll-lpddr3-arm2.dts836
-rwxr-xr-xarch/arm/boot/dts/imx6sll-pinfunc.h882
-rw-r--r--arch/arm/boot/dts/imx6sll.dtsi865
-rw-r--r--arch/arm/boot/dts/imx6sx-14x14-arm2.dts1331
-rw-r--r--arch/arm/boot/dts/imx6sx-19x19-arm2-csi.dts25
-rw-r--r--arch/arm/boot/dts/imx6sx-19x19-arm2-gpmi-weim.dts20
-rw-r--r--arch/arm/boot/dts/imx6sx-19x19-arm2-ldo.dts21
-rw-r--r--arch/arm/boot/dts/imx6sx-19x19-arm2.dts1261
-rw-r--r--arch/arm/boot/dts/imx6sx-pinfunc.h28
-rw-r--r--arch/arm/boot/dts/imx6sx-sabreauto-m4.dts93
-rw-r--r--arch/arm/boot/dts/imx6sx-sabreauto.dts828
-rw-r--r--arch/arm/boot/dts/imx6sx-sdb-btwifi.dts113
-rw-r--r--arch/arm/boot/dts/imx6sx-sdb-emmc.dts30
-rw-r--r--arch/arm/boot/dts/imx6sx-sdb-lcdif1.dts37
-rw-r--r--arch/arm/boot/dts/imx6sx-sdb-ldo.dts39
-rw-r--r--arch/arm/boot/dts/imx6sx-sdb-m4.dts91
-rw-r--r--arch/arm/boot/dts/imx6sx-sdb-mqs.dts55
-rw-r--r--arch/arm/boot/dts/imx6sx-sdb-reva-ldo.dts21
-rw-r--r--arch/arm/boot/dts/imx6sx-sdb-reva.dts49
-rw-r--r--arch/arm/boot/dts/imx6sx-sdb-sai.dts4
-rw-r--r--arch/arm/boot/dts/imx6sx-sdb.dts135
-rw-r--r--arch/arm/boot/dts/imx6sx-sdb.dtsi570
-rw-r--r--arch/arm/boot/dts/imx6sx.dtsi376
-rw-r--r--arch/arm/boot/dts/imx6sxscm-1gb-evb-btwifi-ldo.dts10
-rw-r--r--arch/arm/boot/dts/imx6sxscm-1gb-evb-lcdif1-ldo.dts42
-rw-r--r--arch/arm/boot/dts/imx6sxscm-1gb-evb-ldo.dts9
-rw-r--r--arch/arm/boot/dts/imx6sxscm-1gb-evb-m4-ldo.dts90
-rw-r--r--arch/arm/boot/dts/imx6sxscm-1gb-evb-mqs-ldo.dts43
-rw-r--r--arch/arm/boot/dts/imx6sxscm-1gb-evb-sai-ldo.dts31
-rw-r--r--arch/arm/boot/dts/imx6sxscm-512mb-evb-ldo.dts10
-rw-r--r--arch/arm/boot/dts/imx6sxscm-512mb-evb-m4-ldo.dts19
-rw-r--r--arch/arm/boot/dts/imx6sxscm-512mb.dtsi14
-rw-r--r--arch/arm/boot/dts/imx6sxscm-emmc.dtsi21
-rw-r--r--arch/arm/boot/dts/imx6sxscm-epop-evb-ldo.dts9
-rw-r--r--arch/arm/boot/dts/imx6sxscm-epop-evb-m4-ldo.dts9
-rw-r--r--arch/arm/boot/dts/imx6sxscm-evb-btwifi.dtsi131
-rw-r--r--arch/arm/boot/dts/imx6sxscm-evb-ldo.dts34
-rw-r--r--arch/arm/boot/dts/imx6sxscm-evb.dts1156
-rw-r--r--arch/arm/boot/dts/imx6ul-14x14-ddr3-arm2-emmc.dts23
-rw-r--r--arch/arm/boot/dts/imx6ul-14x14-ddr3-arm2-flexcan2.dts18
-rw-r--r--arch/arm/boot/dts/imx6ul-14x14-ddr3-arm2-gpmi-weim.dts34
-rw-r--r--arch/arm/boot/dts/imx6ul-14x14-ddr3-arm2-mqs.dts41
-rw-r--r--arch/arm/boot/dts/imx6ul-14x14-ddr3-arm2-spdif.dts42
-rw-r--r--arch/arm/boot/dts/imx6ul-14x14-ddr3-arm2-wm8958.dts102
-rw-r--r--arch/arm/boot/dts/imx6ul-14x14-ddr3-arm2.dts774
-rw-r--r--arch/arm/boot/dts/imx6ul-14x14-evk-btwifi-oob.dts10
-rw-r--r--arch/arm/boot/dts/imx6ul-14x14-evk-btwifi.dts10
-rw-r--r--arch/arm/boot/dts/imx6ul-14x14-evk-csi.dts22
-rw-r--r--arch/arm/boot/dts/imx6ul-14x14-evk-ecspi-slave.dts21
-rw-r--r--arch/arm/boot/dts/imx6ul-14x14-evk-ecspi.dts48
-rw-r--r--arch/arm/boot/dts/imx6ul-14x14-evk-emmc.dts20
-rw-r--r--arch/arm/boot/dts/imx6ul-14x14-evk-gpmi-weim.dts49
-rw-r--r--arch/arm/boot/dts/imx6ul-14x14-evk-pf1550.dts133
-rw-r--r--arch/arm/boot/dts/imx6ul-14x14-evk-usb-certi.dts34
-rw-r--r--arch/arm/boot/dts/imx6ul-14x14-evk.dts368
-rw-r--r--arch/arm/boot/dts/imx6ul-14x14-lpddr2-arm2.dts788
-rw-r--r--arch/arm/boot/dts/imx6ul-9x9-evk-btwifi-oob.dts10
-rw-r--r--arch/arm/boot/dts/imx6ul-9x9-evk-btwifi.dts10
-rw-r--r--arch/arm/boot/dts/imx6ul-9x9-evk-csi.dts22
-rw-r--r--arch/arm/boot/dts/imx6ul-9x9-evk-ldo.dts39
-rw-r--r--arch/arm/boot/dts/imx6ul-9x9-evk.dts813
-rw-r--r--arch/arm/boot/dts/imx6ul-evk-btwifi-oob.dtsi30
-rw-r--r--arch/arm/boot/dts/imx6ul-evk-btwifi.dtsi69
-rw-r--r--arch/arm/boot/dts/imx6ul-pinfunc.h169
-rw-r--r--arch/arm/boot/dts/imx6ul.dtsi298
-rw-r--r--arch/arm/boot/dts/imx6ull-14x14-ddr3-arm2-adc.dts20
-rw-r--r--arch/arm/boot/dts/imx6ull-14x14-ddr3-arm2-cs42888.dts158
-rw-r--r--arch/arm/boot/dts/imx6ull-14x14-ddr3-arm2-ecspi.dts22
-rw-r--r--arch/arm/boot/dts/imx6ull-14x14-ddr3-arm2-emmc.dts20
-rw-r--r--arch/arm/boot/dts/imx6ull-14x14-ddr3-arm2-epdc.dts25
-rw-r--r--arch/arm/boot/dts/imx6ull-14x14-ddr3-arm2-flexcan2.dts19
-rw-r--r--arch/arm/boot/dts/imx6ull-14x14-ddr3-arm2-gpmi-weim.dts21
-rw-r--r--arch/arm/boot/dts/imx6ull-14x14-ddr3-arm2-lcdif.dts29
-rw-r--r--arch/arm/boot/dts/imx6ull-14x14-ddr3-arm2-ldo.dts41
-rw-r--r--arch/arm/boot/dts/imx6ull-14x14-ddr3-arm2-qspi-all.dts18
-rw-r--r--arch/arm/boot/dts/imx6ull-14x14-ddr3-arm2-qspi.dts9
-rw-r--r--arch/arm/boot/dts/imx6ull-14x14-ddr3-arm2-tsc.dts39
-rw-r--r--arch/arm/boot/dts/imx6ull-14x14-ddr3-arm2-uart2.dts21
-rw-r--r--arch/arm/boot/dts/imx6ull-14x14-ddr3-arm2-usb.dts60
-rw-r--r--arch/arm/boot/dts/imx6ull-14x14-ddr3-arm2-wm8958.dts155
-rw-r--r--arch/arm/boot/dts/imx6ull-14x14-ddr3-arm2.dts1029
-rw-r--r--arch/arm/boot/dts/imx6ull-14x14-evk-btwifi-oob.dts10
-rw-r--r--arch/arm/boot/dts/imx6ull-14x14-evk-btwifi.dts10
-rw-r--r--arch/arm/boot/dts/imx6ull-14x14-evk-emmc.dts19
-rw-r--r--arch/arm/boot/dts/imx6ull-14x14-evk-gpmi-weim.dts49
-rw-r--r--arch/arm/boot/dts/imx6ull-14x14-evk-usb-certi.dts34
-rw-r--r--arch/arm/boot/dts/imx6ull-14x14-evk.dts784
-rw-r--r--arch/arm/boot/dts/imx6ull-9x9-evk-btwifi-oob.dts10
-rw-r--r--arch/arm/boot/dts/imx6ull-9x9-evk-btwifi.dts10
-rw-r--r--arch/arm/boot/dts/imx6ull-9x9-evk-ldo.dts36
-rw-r--r--arch/arm/boot/dts/imx6ull-9x9-evk.dts813
-rw-r--r--arch/arm/boot/dts/imx6ull-pinfunc-snvs.h29
-rw-r--r--arch/arm/boot/dts/imx6ull-pinfunc.h36
-rw-r--r--arch/arm/boot/dts/imx6ull.dtsi1178
-rw-r--r--arch/arm/boot/dts/imx6ulz-14x14-evk-btwifi-oob.dts16
-rw-r--r--arch/arm/boot/dts/imx6ulz-14x14-evk-btwifi.dts16
-rw-r--r--arch/arm/boot/dts/imx6ulz-14x14-evk-emmc.dts25
-rw-r--r--arch/arm/boot/dts/imx6ulz-14x14-evk-gpmi-weim.dts55
-rw-r--r--arch/arm/boot/dts/imx6ulz-14x14-evk.dts31
-rw-r--r--arch/arm/boot/dts/imx7d-12x12-ddr3-arm2.dts558
-rw-r--r--arch/arm/boot/dts/imx7d-12x12-lpddr3-arm2-ecspi.dts27
-rw-r--r--arch/arm/boot/dts/imx7d-12x12-lpddr3-arm2-enet2.dts17
-rw-r--r--arch/arm/boot/dts/imx7d-12x12-lpddr3-arm2-flexcan.dts29
-rw-r--r--arch/arm/boot/dts/imx7d-12x12-lpddr3-arm2-m4.dts76
-rw-r--r--arch/arm/boot/dts/imx7d-12x12-lpddr3-arm2-mipi_dsi.dts29
-rw-r--r--arch/arm/boot/dts/imx7d-12x12-lpddr3-arm2-mqs.dts49
-rw-r--r--arch/arm/boot/dts/imx7d-12x12-lpddr3-arm2-pcie.dts22
-rw-r--r--arch/arm/boot/dts/imx7d-12x12-lpddr3-arm2-qspi.dts84
-rw-r--r--arch/arm/boot/dts/imx7d-12x12-lpddr3-arm2-sai.dts46
-rw-r--r--arch/arm/boot/dts/imx7d-12x12-lpddr3-arm2.dts1017
-rw-r--r--arch/arm/boot/dts/imx7d-19x19-lpddr2-arm2.dts454
-rw-r--r--arch/arm/boot/dts/imx7d-pinfunc.h6
-rw-r--r--arch/arm/boot/dts/imx7d-sdb-epdc.dts9
-rw-r--r--arch/arm/boot/dts/imx7d-sdb-epdc.dtsi58
-rw-r--r--arch/arm/boot/dts/imx7d-sdb-gpmi-weim.dts9
-rw-r--r--arch/arm/boot/dts/imx7d-sdb-gpmi-weim.dtsi23
-rw-r--r--arch/arm/boot/dts/imx7d-sdb-m4.dts9
-rw-r--r--arch/arm/boot/dts/imx7d-sdb-m4.dtsi68
-rw-r--r--arch/arm/boot/dts/imx7d-sdb-mipi-dsi.dts31
-rw-r--r--arch/arm/boot/dts/imx7d-sdb-qspi.dts9
-rw-r--r--arch/arm/boot/dts/imx7d-sdb-qspi.dtsi44
-rw-r--r--arch/arm/boot/dts/imx7d-sdb-reva-epdc.dts9
-rw-r--r--arch/arm/boot/dts/imx7d-sdb-reva-gpmi-weim.dts9
-rw-r--r--arch/arm/boot/dts/imx7d-sdb-reva-hdmi-audio.dts20
-rw-r--r--arch/arm/boot/dts/imx7d-sdb-reva-m4.dts9
-rw-r--r--arch/arm/boot/dts/imx7d-sdb-reva-qspi.dts9
-rw-r--r--arch/arm/boot/dts/imx7d-sdb-reva-touch.dts21
-rw-r--r--arch/arm/boot/dts/imx7d-sdb-reva-wm8960.dts20
-rw-r--r--arch/arm/boot/dts/imx7d-sdb-reva.dts89
-rw-r--r--arch/arm/boot/dts/imx7d-sdb.dts655
-rw-r--r--arch/arm/boot/dts/imx7d.dtsi346
-rw-r--r--arch/arm/boot/dts/imx7s.dtsi81
-rw-r--r--arch/arm/boot/dts/imx7ulp-14x14-arm2.dts72
-rw-r--r--arch/arm/boot/dts/imx7ulp-evk-emmc-qspi.dts18
-rw-r--r--arch/arm/boot/dts/imx7ulp-evk-ft5416.dts17
-rw-r--r--arch/arm/boot/dts/imx7ulp-evk-mipi.dts10
-rw-r--r--arch/arm/boot/dts/imx7ulp-evk-mipi.dtsi23
-rw-r--r--arch/arm/boot/dts/imx7ulp-evk-qspi.dts76
-rw-r--r--arch/arm/boot/dts/imx7ulp-evk-wm8960.dts200
-rw-r--r--arch/arm/boot/dts/imx7ulp-evk.dts579
-rw-r--r--arch/arm/boot/dts/imx7ulp-evkb-emmc.dts26
-rw-r--r--arch/arm/boot/dts/imx7ulp-evkb-lpuart.dts17
-rw-r--r--arch/arm/boot/dts/imx7ulp-evkb-mipi.dts26
-rw-r--r--arch/arm/boot/dts/imx7ulp-evkb-rm68191-qhd.dts13
-rw-r--r--arch/arm/boot/dts/imx7ulp-evkb-rm68200-wxga.dts13
-rw-r--r--arch/arm/boot/dts/imx7ulp-evkb-sd1.dts48
-rw-r--r--arch/arm/boot/dts/imx7ulp-evkb-sensors-to-i2c5.dts22
-rw-r--r--arch/arm/boot/dts/imx7ulp-evkb-spi-slave.dts28
-rw-r--r--arch/arm/boot/dts/imx7ulp-evkb.dts39
-rw-r--r--arch/arm/boot/dts/imx7ulp-pinfunc.h978
-rw-r--r--arch/arm/boot/dts/imx7ulp.dtsi694
-rw-r--r--arch/arm/configs/imx_v7_defconfig464
-rw-r--r--arch/arm/include/asm/outercache.h23
-rw-r--r--arch/arm/include/debug/imx-uart.h10
-rw-r--r--arch/arm/mach-imx/Kconfig74
-rw-r--r--arch/arm/mach-imx/Makefile58
-rw-r--r--arch/arm/mach-imx/anatop.c188
-rw-r--r--arch/arm/mach-imx/busfreq-imx.c1453
-rw-r--r--arch/arm/mach-imx/busfreq_ddr3.c773
-rw-r--r--arch/arm/mach-imx/busfreq_lpddr2.c373
-rw-r--r--arch/arm/mach-imx/busfreq_optee.c310
-rw-r--r--arch/arm/mach-imx/common.c166
-rw-r--r--arch/arm/mach-imx/common.h109
-rw-r--r--arch/arm/mach-imx/cpu.c14
-rw-r--r--arch/arm/mach-imx/cpuidle-imx6q.c32
-rw-r--r--arch/arm/mach-imx/cpuidle-imx6sl.c195
-rw-r--r--arch/arm/mach-imx/cpuidle-imx6sll.c277
-rw-r--r--arch/arm/mach-imx/cpuidle-imx6sx.c251
-rw-r--r--arch/arm/mach-imx/cpuidle-imx6ul.c327
-rw-r--r--arch/arm/mach-imx/cpuidle-imx7d.c390
-rw-r--r--arch/arm/mach-imx/cpuidle-imx7ulp.c62
-rw-r--r--arch/arm/mach-imx/cpuidle.h28
-rw-r--r--arch/arm/mach-imx/ddr3_freq_imx6.S1103
-rw-r--r--arch/arm/mach-imx/ddr3_freq_imx6sx.S764
-rw-r--r--arch/arm/mach-imx/ddr3_freq_imx7d.S586
-rw-r--r--arch/arm/mach-imx/ddrc.c86
-rw-r--r--arch/arm/mach-imx/gpc.c283
-rw-r--r--arch/arm/mach-imx/gpcv2.c851
-rw-r--r--arch/arm/mach-imx/hardware.h16
-rw-r--r--arch/arm/mach-imx/headsmp.S13
-rw-r--r--arch/arm/mach-imx/hotplug.c5
-rw-r--r--arch/arm/mach-imx/imx6sl_low_power_idle.S776
-rw-r--r--arch/arm/mach-imx/imx6sll_low_power_idle.S780
-rw-r--r--arch/arm/mach-imx/imx6sx_low_power_idle.S887
-rw-r--r--arch/arm/mach-imx/imx6ul_low_power_idle.S821
-rw-r--r--arch/arm/mach-imx/imx6ull_low_power_idle.S764
-rw-r--r--arch/arm/mach-imx/imx7d_low_power_idle.S787
-rw-r--r--arch/arm/mach-imx/lpddr2_freq_imx6.S618
-rw-r--r--arch/arm/mach-imx/lpddr2_freq_imx6q.S765
-rw-r--r--arch/arm/mach-imx/lpddr2_freq_imx6sll.S460
-rw-r--r--arch/arm/mach-imx/lpddr2_freq_imx6sx.S492
-rw-r--r--arch/arm/mach-imx/lpddr3_freq_imx.S444
-rw-r--r--arch/arm/mach-imx/mach-imx6q.c103
-rw-r--r--arch/arm/mach-imx/mach-imx6sl.c39
-rw-r--r--arch/arm/mach-imx/mach-imx6sx.c49
-rw-r--r--arch/arm/mach-imx/mach-imx6ul.c138
-rw-r--r--arch/arm/mach-imx/mach-imx7d.c58
-rw-r--r--arch/arm/mach-imx/mach-imx7ulp.c109
-rw-r--r--arch/arm/mach-imx/mmdc.c11
-rw-r--r--arch/arm/mach-imx/mu.c434
-rw-r--r--arch/arm/mach-imx/mx6.h51
-rw-r--r--arch/arm/mach-imx/mx7.h54
-rw-r--r--arch/arm/mach-imx/mx7ulp.h63
-rw-r--r--arch/arm/mach-imx/mxc.h34
-rw-r--r--arch/arm/mach-imx/platsmp.c38
-rw-r--r--arch/arm/mach-imx/pm-imx6.c960
-rw-r--r--arch/arm/mach-imx/pm-imx7.c1227
-rw-r--r--arch/arm/mach-imx/pm-imx7ulp.c826
-rw-r--r--arch/arm/mach-imx/pm-rpmsg.c354
-rw-r--r--arch/arm/mach-imx/smc_sip.h36
-rw-r--r--arch/arm/mach-imx/smp_wfe.S110
-rw-r--r--arch/arm/mach-imx/smp_wfe_imx6.S186
-rw-r--r--arch/arm/mach-imx/src.c93
-rw-r--r--arch/arm/mach-imx/suspend-imx6.S531
-rw-r--r--arch/arm/mach-imx/suspend-imx7.S714
-rw-r--r--arch/arm/mach-imx/suspend-imx7ulp.S625
-rw-r--r--arch/arm/mm/Kconfig2
-rw-r--r--arch/arm/mm/cache-l2x0.c163
-rw-r--r--arch/arm/mm/cache-v7.S3
-rw-r--r--arch/arm/mm/proc-syms.c4
-rw-r--r--arch/arm64/Kconfig1
-rw-r--r--arch/arm64/Kconfig.platforms60
-rw-r--r--arch/arm64/boot/dts/freescale/Makefile117
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8-ca35.dtsi76
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8-ca53.dtsi100
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8-ca72.dtsi81
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8dm-lpddr4-arm2.dts109
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8dm.dtsi42
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8dx-17x17-val.dts26
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8dx-lpddr4-arm2.dts26
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8dx.dtsi3581
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8dxp-lpddr4-arm2.dts35
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8dxp.dtsi39
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8mm-ddr3l-val.dts418
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8mm-ddr4-evk-rm67191.dts49
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8mm-ddr4-evk.dts113
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8mm-ddr4-qca9377-evk.dts33
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8mm-ddr4-val.dts541
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8mm-evk-ak4497.dts78
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8mm-evk-ak5558.dts32
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8mm-evk-audio-tdm.dts25
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8mm-evk-inmate.dts224
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8mm-evk-m4.dts85
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8mm-evk-revb-rm67191.dts49
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8mm-evk-revb.dts32
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8mm-evk-rm67191.dts35
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8mm-evk-root.dts113
-rwxr-xr-xarch/arm64/boot/dts/freescale/fsl-imx8mm-evk.dts1045
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8mm.dtsi1293
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8mq-ddr3l-arm2.dts371
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8mq-ddr4-arm2-gpmi-nand.dts52
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8mq-ddr4-arm2.dts363
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8mq-evk-ak4497.dts95
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8mq-evk-audio-tdm.dts25
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8mq-evk-b3.dts99
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8mq-evk-dcss-adv7535-b3.dts16
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8mq-evk-dcss-adv7535.dts16
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8mq-evk-dcss-adv7535.dtsi79
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8mq-evk-dcss-rm67191-b3.dts16
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8mq-evk-dcss-rm67191.dts16
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8mq-evk-dcss-rm67191.dtsi131
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8mq-evk-dp.dts26
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8mq-evk-drm.dts41
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8mq-evk-dual-display-b3.dts42
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8mq-evk-dual-display.dts42
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8mq-evk-edp.dts25
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8mq-evk-inmate.dts207
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8mq-evk-lcdif-adv7535-b3.dts16
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8mq-evk-lcdif-adv7535.dts16
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8mq-evk-lcdif-adv7535.dtsi71
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8mq-evk-lcdif-rm67191-b3.dts16
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8mq-evk-lcdif-rm67191.dts16
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8mq-evk-lcdif-rm67191.dtsi101
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8mq-evk-m4.dts63
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8mq-evk-mipi-csi2.dts38
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8mq-evk-pcie1-m2.dts82
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8mq-evk-pdm.dts46
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8mq-evk-root.dts110
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8mq-evk.dts1017
-rwxr-xr-xarch/arm64/boot/dts/freescale/fsl-imx8mq.dtsi1466
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8q-arm2.dtsi1320
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8qm-ddr4-arm2-hdmi.dts103
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8qm-ddr4-arm2.dts1300
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8qm-device.dtsi4414
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8qm-enet2-tja1100.dtsi72
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8qm-lpddr4-arm2-8cam.dts45
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8qm-lpddr4-arm2-dom0.dts331
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8qm-lpddr4-arm2-domu.dts630
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8qm-lpddr4-arm2-dp-dig-pll.dts46
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8qm-lpddr4-arm2-dp.dts60
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8qm-lpddr4-arm2-dsi-rm67191.dts65
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8qm-lpddr4-arm2-enet2-tja1100.dts16
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8qm-lpddr4-arm2-hdmi-in.dts70
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8qm-lpddr4-arm2-hdmi.dts107
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8qm-lpddr4-arm2-hsic.dts75
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8qm-lpddr4-arm2-it6263-dual-channel.dts35
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8qm-lpddr4-arm2-jdi-wuxga-lvds1-panel.dts71
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8qm-lpddr4-arm2-lpspi-slave.dts32
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8qm-lpddr4-arm2-lpspi.dts79
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8qm-lpddr4-arm2-mqs.dts198
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8qm-lpddr4-arm2-spdif.dts205
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8qm-lpddr4-arm2-usb3.dts113
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8qm-lpddr4-arm2.dts34
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8qm-lpddr4-arm2_ca53.dts24
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8qm-lpddr4-arm2_ca72.dts32
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8qm-mek-dom0-dpu2.dts784
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8qm-mek-dom0.dts929
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8qm-mek-domu-car.dts747
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8qm-mek-domu-dpu1-hdmi.dts43
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8qm-mek-domu-dpu1.dts991
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8qm-mek-domu-hdmi.dts98
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8qm-mek-domu.dts1269
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8qm-mek-dsi-rm67191.dts65
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8qm-mek-dsp.dts198
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8qm-mek-enet2-tja1100.dts16
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8qm-mek-hdmi-in.dts67
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8qm-mek-hdmi.dts88
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8qm-mek-inmate.dts287
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8qm-mek-jdi-wuxga-lvds1-panel.dts71
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8qm-mek-ov5640.dts153
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8qm-mek-root.dts119
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8qm-mek-rpmsg.dts17
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8qm-mek-rpmsg.dtsi109
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8qm-mek.dts17
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8qm-mek.dtsi1522
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8qm-mek_ca53.dts23
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8qm-mek_ca72.dts31
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8qm-xen.dtsi576
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8qm.dtsi355
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8qp-lpddr4-arm2.dts25
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8qp.dtsi43
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8qxp-17x17-val.dts26
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8qxp-ddr3l-val.dts30
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8qxp-enet2-tja1100.dtsi59
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8qxp-lpddr4-arm2-a0.dts24
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8qxp-lpddr4-arm2-dsi-rm67191.dts61
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8qxp-lpddr4-arm2-dsp.dts112
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8qxp-lpddr4-arm2-enet2-tja1100.dts16
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8qxp-lpddr4-arm2-enet2.dts27
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8qxp-lpddr4-arm2-gpmi-nand.dts67
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8qxp-lpddr4-arm2-lpspi-slave.dts32
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8qxp-lpddr4-arm2-lpspi.dts78
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8qxp-lpddr4-arm2-mlb.dts23
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8qxp-lpddr4-arm2-mqs.dts60
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8qxp-lpddr4-arm2-spdif.dts59
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8qxp-lpddr4-arm2-wm8962.dts113
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8qxp-lpddr4-arm2.dts35
-rwxr-xr-xarch/arm64/boot/dts/freescale/fsl-imx8qxp-mek-a0.dts23
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8qxp-mek-dom0.dts90
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8qxp-mek-dsi-rm67191.dts63
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8qxp-mek-dsp.dts171
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8qxp-mek-enet2-tja1100.dts16
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8qxp-mek-enet2.dts27
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8qxp-mek-inmate.dts294
-rwxr-xr-xarch/arm64/boot/dts/freescale/fsl-imx8qxp-mek-it6263-lvds0-dual-channel.dts30
-rwxr-xr-xarch/arm64/boot/dts/freescale/fsl-imx8qxp-mek-it6263-lvds1-dual-channel.dts30
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8qxp-mek-jdi-wuxga-lvds0-panel.dts50
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8qxp-mek-jdi-wuxga-lvds1-panel.dts50
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8qxp-mek-lcdif.dts97
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8qxp-mek-lvds0-it6263.dtsi58
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8qxp-mek-lvds1-it6263.dtsi58
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8qxp-mek-ov5640-rpmsg.dts24
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8qxp-mek-ov5640.dts24
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8qxp-mek-ov5640.dtsi126
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8qxp-mek-root.dts111
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8qxp-mek-rpmsg.dts17
-rwxr-xr-xarch/arm64/boot/dts/freescale/fsl-imx8qxp-mek-rpmsg.dtsi212
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8qxp-mek.dts17
-rwxr-xr-xarch/arm64/boot/dts/freescale/fsl-imx8qxp-mek.dtsi1397
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8qxp-xen.dtsi61
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8qxp.dtsi51
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8x-17x17-val.dtsi155
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8x-arm2.dtsi1013
-rw-r--r--arch/arm64/configs/defconfig333
-rw-r--r--arch/arm64/include/asm/tlbflush.h41
-rw-r--r--arch/arm64/mm/dma-mapping.c49
-rw-r--r--block/blk-core.c179
-rw-r--r--block/blk-lib.c12
-rw-r--r--block/blk-map.c15
-rw-r--r--block/blk-mq-sysfs.c9
-rw-r--r--block/blk-mq.c14
-rw-r--r--block/blk-sysfs.c47
-rw-r--r--block/blk-throttle.c10
-rw-r--r--block/blk.h3
-rw-r--r--block/elevator.c10
-rw-r--r--block/genhd.c95
-rw-r--r--block/scsi_ioctl.c27
-rw-r--r--crypto/ccm.c13
-rw-r--r--crypto/ecc.c89
-rw-r--r--crypto/ecc.h4
-rw-r--r--crypto/ecc_curve_defs.h22
-rw-r--r--crypto/ecdh.c4
-rw-r--r--crypto/gcm.c15
-rw-r--r--crypto/tcrypt.c11
-rw-r--r--crypto/testmgr.c2
-rw-r--r--crypto/testmgr.h2
-rw-r--r--drivers/Kconfig2
-rw-r--r--drivers/Makefile1
-rw-r--r--drivers/ata/Kconfig2
-rw-r--r--drivers/ata/ahci_imx.c659
-rw-r--r--drivers/base/Kconfig1
-rw-r--r--drivers/base/firmware_class.c2
-rw-r--r--drivers/base/power/domain.c40
-rw-r--r--drivers/base/regmap/regmap-mmio.c20
-rw-r--r--drivers/block/pktcdvd.c2
-rw-r--r--drivers/char/Kconfig16
-rw-r--r--drivers/char/Makefile2
-rw-r--r--drivers/char/fsl_otp.c738
-rw-r--r--drivers/char/hw_random/Kconfig12
-rw-r--r--drivers/char/hw_random/Makefile1
-rw-r--r--drivers/char/hw_random/imx-rng.c440
-rw-r--r--drivers/char/imx_amp/Kconfig9
-rw-r--r--drivers/char/imx_amp/Makefile5
-rw-r--r--drivers/char/imx_amp/imx_sema4.c413
-rw-r--r--drivers/clk/Makefile1
-rw-r--r--drivers/clk/clk-divider.c100
-rw-r--r--drivers/clk/clk-fractional-divider.c10
-rw-r--r--drivers/clk/clk.c28
-rw-r--r--drivers/clk/imx/Makefile16
-rw-r--r--drivers/clk/imx/clk-busy.c2
-rw-r--r--drivers/clk/imx/clk-composite-7ulp.c103
-rw-r--r--drivers/clk/imx/clk-composite-8m.c186
-rw-r--r--drivers/clk/imx/clk-divider-scu.c250
-rw-r--r--drivers/clk/imx/clk-frac-pll.c230
-rw-r--r--drivers/clk/imx/clk-gate-scu.c448
-rw-r--r--drivers/clk/imx/clk-gate2.c70
-rw-r--r--drivers/clk/imx/clk-imx6q.c262
-rw-r--r--drivers/clk/imx/clk-imx6sl.c108
-rw-r--r--drivers/clk/imx/clk-imx6sll.c380
-rw-r--r--drivers/clk/imx/clk-imx6sx.c285
-rw-r--r--drivers/clk/imx/clk-imx6ul.c43
-rw-r--r--drivers/clk/imx/clk-imx7d.c194
-rw-r--r--drivers/clk/imx/clk-imx7ulp.c322
-rw-r--r--drivers/clk/imx/clk-imx8.c68
-rw-r--r--drivers/clk/imx/clk-imx8.h131
-rw-r--r--drivers/clk/imx/clk-imx8mm.c988
-rw-r--r--drivers/clk/imx/clk-imx8mq.c629
-rw-r--r--drivers/clk/imx/clk-imx8qm.c954
-rw-r--r--drivers/clk/imx/clk-imx8qxp.c739
-rw-r--r--drivers/clk/imx/clk-intpll.c430
-rw-r--r--drivers/clk/imx/clk-mux-scu.c445
-rw-r--r--drivers/clk/imx/clk-pfd.c52
-rw-r--r--drivers/clk/imx/clk-pfdv2.c207
-rw-r--r--drivers/clk/imx/clk-pllv3.c133
-rw-r--r--drivers/clk/imx/clk-pllv4.c215
-rw-r--r--drivers/clk/imx/clk-pllv5.c199
-rw-r--r--drivers/clk/imx/clk-sccg-pll.c540
-rw-r--r--drivers/clk/imx/clk.c13
-rw-r--r--drivers/clk/imx/clk.h227
-rw-r--r--drivers/clocksource/Kconfig6
-rw-r--r--drivers/clocksource/Makefile1
-rw-r--r--drivers/clocksource/timer-imx-gpt.c34
-rw-r--r--drivers/clocksource/timer-imx-sysctr.c187
-rw-r--r--drivers/cpufreq/Kconfig30
-rw-r--r--drivers/cpufreq/Kconfig.arm24
-rw-r--r--drivers/cpufreq/Makefile4
-rw-r--r--drivers/cpufreq/cpufreq_governor.h8
-rw-r--r--drivers/cpufreq/cpufreq_interactive.c1368
-rw-r--r--drivers/cpufreq/imx6q-cpufreq.c199
-rw-r--r--drivers/cpufreq/imx7ulp-cpufreq.c266
-rw-r--r--drivers/cpufreq/imx8-cpufreq.c293
-rw-r--r--drivers/cpufreq/imx8mq-cpufreq.c275
-rw-r--r--drivers/crypto/caam/Kconfig63
-rw-r--r--drivers/crypto/caam/Makefile7
-rw-r--r--drivers/crypto/caam/caamalg.c385
-rw-r--r--drivers/crypto/caam/caamalg_desc.c30
-rw-r--r--drivers/crypto/caam/caamhash.c388
-rw-r--r--drivers/crypto/caam/caampkc.c9
-rw-r--r--drivers/crypto/caam/caamrng.c58
-rw-r--r--drivers/crypto/caam/ctrl.c1265
-rw-r--r--drivers/crypto/caam/ctrl.h3
-rw-r--r--drivers/crypto/caam/desc.h31
-rw-r--r--drivers/crypto/caam/desc_constr.h46
-rw-r--r--drivers/crypto/caam/error.c14
-rw-r--r--drivers/crypto/caam/inst_rng.c377
-rw-r--r--drivers/crypto/caam/inst_rng.h18
-rw-r--r--drivers/crypto/caam/intern.h62
-rw-r--r--drivers/crypto/caam/jr.c384
-rw-r--r--drivers/crypto/caam/pdb.h50
-rw-r--r--drivers/crypto/caam/regs.h208
-rw-r--r--drivers/crypto/caam/secvio.c340
-rw-r--r--drivers/crypto/caam/secvio.h67
-rw-r--r--drivers/crypto/caam/sm.h125
-rw-r--r--drivers/crypto/caam/sm_store.c1336
-rw-r--r--drivers/crypto/caam/sm_test.c527
-rw-r--r--drivers/crypto/caam/snvsregs.h237
-rw-r--r--drivers/crypto/caam/tag_object.c260
-rw-r--r--drivers/crypto/caam/tag_object.h100
-rw-r--r--drivers/crypto/mxs-dcp.c97
-rw-r--r--drivers/dma-buf/dma-buf.c31
-rw-r--r--drivers/dma/Kconfig19
-rw-r--r--drivers/dma/Makefile3
-rw-r--r--drivers/dma/fsl-edma-v3.c1094
-rw-r--r--drivers/dma/fsl-edma.c266
-rw-r--r--drivers/dma/imx-sdma.c1166
-rw-r--r--drivers/dma/mxs-dma.c182
-rw-r--r--drivers/dma/pxp/Kconfig22
-rw-r--r--drivers/dma/pxp/Makefile3
-rw-r--r--drivers/dma/pxp/pxp_device.c878
-rw-r--r--drivers/dma/pxp/pxp_dma_v2.c1865
-rw-r--r--drivers/dma/pxp/pxp_dma_v3.c8138
-rw-r--r--drivers/dma/pxp/reg_bitfields.h280
-rw-r--r--drivers/dma/pxp/regs-pxp_v2.h1152
-rw-r--r--drivers/dma/pxp/regs-pxp_v3.h26952
-rw-r--r--drivers/dma/virt-dma.c5
-rw-r--r--drivers/extcon/Kconfig8
-rw-r--r--drivers/extcon/Makefile1
-rw-r--r--drivers/extcon/extcon-ptn5150.c271
-rw-r--r--drivers/gpio/Kconfig15
-rw-r--r--drivers/gpio/Makefile1
-rw-r--r--drivers/gpio/gpio-74x164.c3
-rw-r--r--drivers/gpio/gpio-imx-rpmsg.c430
-rw-r--r--drivers/gpio/gpio-max732x.c22
-rw-r--r--drivers/gpio/gpio-mxc.c376
-rw-r--r--drivers/gpio/gpio-pca953x.c5
-rw-r--r--drivers/gpio/gpio-vf610.c27
-rw-r--r--drivers/gpu/Makefile2
-rw-r--r--drivers/gpu/drm/Kconfig7
-rw-r--r--drivers/gpu/drm/Makefile5
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c16
-rw-r--r--drivers/gpu/drm/amd/amdgpu/dce_virtual.c4
-rw-r--r--drivers/gpu/drm/ast/ast_mode.c2
-rw-r--r--drivers/gpu/drm/bochs/bochs_kms.c2
-rw-r--r--drivers/gpu/drm/bridge/Kconfig28
-rw-r--r--drivers/gpu/drm/bridge/Makefile4
-rw-r--r--drivers/gpu/drm/bridge/adv7511/adv7511.h17
-rw-r--r--drivers/gpu/drm/bridge/adv7511/adv7511_drv.c123
-rw-r--r--drivers/gpu/drm/bridge/adv7511/adv7533.c112
-rw-r--r--drivers/gpu/drm/bridge/it6263.c1024
-rw-r--r--drivers/gpu/drm/bridge/nwl-dsi.c1426
-rw-r--r--drivers/gpu/drm/bridge/nxp-seiko-43wvfig.c247
-rw-r--r--drivers/gpu/drm/bridge/sec-dsim.c1963
-rw-r--r--drivers/gpu/drm/cirrus/cirrus_mode.c2
-rw-r--r--drivers/gpu/drm/drm_atomic.c39
-rw-r--r--drivers/gpu/drm/drm_atomic_helper.c8
-rw-r--r--drivers/gpu/drm/drm_auth.c38
-rw-r--r--drivers/gpu/drm/drm_bufs.c2
-rw-r--r--drivers/gpu/drm/drm_color_mgmt.c4
-rw-r--r--drivers/gpu/drm/drm_connector.c213
-rw-r--r--drivers/gpu/drm/drm_crtc.c8
-rw-r--r--drivers/gpu/drm/drm_crtc_internal.h1
-rw-r--r--drivers/gpu/drm/drm_drv.c3
-rw-r--r--drivers/gpu/drm/drm_edid.c171
-rw-r--r--drivers/gpu/drm/drm_encoder.c7
-rw-r--r--drivers/gpu/drm/drm_fb_helper.c19
-rw-r--r--drivers/gpu/drm/drm_fourcc.c1
-rw-r--r--drivers/gpu/drm/drm_framebuffer.c9
-rw-r--r--drivers/gpu/drm/drm_ioctl.c4
-rw-r--r--drivers/gpu/drm/drm_lease.c767
-rw-r--r--drivers/gpu/drm/drm_mode_config.c22
-rw-r--r--drivers/gpu/drm/drm_mode_object.c33
-rw-r--r--drivers/gpu/drm/drm_modeset_helper.c76
-rw-r--r--drivers/gpu/drm/drm_of.c31
-rw-r--r--drivers/gpu/drm/drm_plane.c30
-rw-r--r--drivers/gpu/drm/drm_probe_helper.c2
-rw-r--r--drivers/gpu/drm/drm_property.c6
-rw-r--r--drivers/gpu/drm/drm_simple_kms_helper.c15
-rw-r--r--drivers/gpu/drm/drm_vblank.c23
-rw-r--r--drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c2
-rw-r--r--drivers/gpu/drm/i915/intel_display.c2
-rw-r--r--drivers/gpu/drm/i915/intel_overlay.c2
-rw-r--r--drivers/gpu/drm/i915/intel_sprite.c2
-rw-r--r--drivers/gpu/drm/imx/Kconfig37
-rw-r--r--drivers/gpu/drm/imx/Makefile11
-rw-r--r--drivers/gpu/drm/imx/dcss/Kconfig6
-rw-r--r--drivers/gpu/drm/imx/dcss/Makefile4
-rw-r--r--drivers/gpu/drm/imx/dcss/dcss-crtc.c531
-rw-r--r--drivers/gpu/drm/imx/dcss/dcss-crtc.h12
-rw-r--r--drivers/gpu/drm/imx/dcss/dcss-kms.c208
-rw-r--r--drivers/gpu/drm/imx/dcss/dcss-kms.h20
-rw-r--r--drivers/gpu/drm/imx/dcss/dcss-plane.c716
-rw-r--r--drivers/gpu/drm/imx/dcss/dcss-plane.h28
-rw-r--r--drivers/gpu/drm/imx/dpu/Kconfig6
-rw-r--r--drivers/gpu/drm/imx/dpu/Makefile7
-rw-r--r--drivers/gpu/drm/imx/dpu/dpu-blit.c313
-rw-r--r--drivers/gpu/drm/imx/dpu/dpu-crtc.c1181
-rw-r--r--drivers/gpu/drm/imx/dpu/dpu-crtc.h88
-rw-r--r--drivers/gpu/drm/imx/dpu/dpu-kms.c860
-rw-r--r--drivers/gpu/drm/imx/dpu/dpu-kms.h20
-rw-r--r--drivers/gpu/drm/imx/dpu/dpu-plane.c977
-rw-r--r--drivers/gpu/drm/imx/dpu/dpu-plane.h214
-rw-r--r--drivers/gpu/drm/imx/hdp/API_AFE_mcu1_dp.c434
-rw-r--r--drivers/gpu/drm/imx/hdp/API_AFE_mcu1_dp.h168
-rw-r--r--drivers/gpu/drm/imx/hdp/API_AFE_mcu2_dp.c711
-rw-r--r--drivers/gpu/drm/imx/hdp/API_AFE_mcu2_dp.h195
-rw-r--r--drivers/gpu/drm/imx/hdp/API_AFE_ss28fdsoi_kiran_hdmitx.c550
-rw-r--r--drivers/gpu/drm/imx/hdp/API_AFE_ss28fdsoi_kiran_hdmitx.h56
-rw-r--r--drivers/gpu/drm/imx/hdp/API_AFE_t28hpc_hdmitx.c781
-rw-r--r--drivers/gpu/drm/imx/hdp/API_AFE_t28hpc_hdmitx.h60
-rw-r--r--drivers/gpu/drm/imx/hdp/Kconfig19
-rw-r--r--drivers/gpu/drm/imx/hdp/Makefile9
-rw-r--r--drivers/gpu/drm/imx/hdp/hdmitx_firmware.h77
-rw-r--r--drivers/gpu/drm/imx/hdp/imx-arc.c103
-rw-r--r--drivers/gpu/drm/imx/hdp/imx-dp.c661
-rw-r--r--drivers/gpu/drm/imx/hdp/imx-dp.h33
-rw-r--r--drivers/gpu/drm/imx/hdp/imx-hdcp-private.h25
-rw-r--r--drivers/gpu/drm/imx/hdp/imx-hdcp.c689
-rw-r--r--drivers/gpu/drm/imx/hdp/imx-hdcp.h26
-rw-r--r--drivers/gpu/drm/imx/hdp/imx-hdmi.c531
-rw-r--r--drivers/gpu/drm/imx/hdp/imx-hdmi.h35
-rw-r--r--drivers/gpu/drm/imx/hdp/imx-hdp-audio.c241
-rw-r--r--drivers/gpu/drm/imx/hdp/imx-hdp.c1729
-rw-r--r--drivers/gpu/drm/imx/hdp/imx-hdp.h272
-rw-r--r--drivers/gpu/drm/imx/hdp/mhdp_firmware.h77
-rw-r--r--drivers/gpu/drm/imx/hdp/ss28fdsoi_hdmitx_table.c113
-rw-r--r--drivers/gpu/drm/imx/hdp/ss28fdsoi_hdmitx_table.h104
-rw-r--r--drivers/gpu/drm/imx/hdp/t28hpc_hdmitx_table.c202
-rw-r--r--drivers/gpu/drm/imx/hdp/t28hpc_hdmitx_table.h156
-rw-r--r--drivers/gpu/drm/imx/imx-drm-core.c304
-rw-r--r--drivers/gpu/drm/imx/imx-drm.h18
-rw-r--r--drivers/gpu/drm/imx/imx-ldb.c962
-rw-r--r--drivers/gpu/drm/imx/imx-tve.c5
-rw-r--r--drivers/gpu/drm/imx/ipuv3/Kconfig6
-rw-r--r--drivers/gpu/drm/imx/ipuv3/Makefile4
-rw-r--r--drivers/gpu/drm/imx/ipuv3/ipuv3-crtc.c (renamed from drivers/gpu/drm/imx/ipuv3-crtc.c)29
-rw-r--r--drivers/gpu/drm/imx/ipuv3/ipuv3-kms.c98
-rw-r--r--drivers/gpu/drm/imx/ipuv3/ipuv3-kms.h20
-rw-r--r--drivers/gpu/drm/imx/ipuv3/ipuv3-plane.c (renamed from drivers/gpu/drm/imx/ipuv3-plane.c)0
-rw-r--r--drivers/gpu/drm/imx/ipuv3/ipuv3-plane.h (renamed from drivers/gpu/drm/imx/ipuv3-plane.h)0
-rw-r--r--drivers/gpu/drm/imx/lcdif/Kconfig8
-rw-r--r--drivers/gpu/drm/imx/lcdif/Makefile4
-rw-r--r--drivers/gpu/drm/imx/lcdif/lcdif-crtc.c389
-rw-r--r--drivers/gpu/drm/imx/lcdif/lcdif-kms.c46
-rw-r--r--drivers/gpu/drm/imx/lcdif/lcdif-kms.h21
-rw-r--r--drivers/gpu/drm/imx/lcdif/lcdif-plane.c233
-rw-r--r--drivers/gpu/drm/imx/lcdif/lcdif-plane.h37
-rw-r--r--drivers/gpu/drm/imx/nwl_dsi-imx.c1028
-rw-r--r--drivers/gpu/drm/imx/sec_mipi_dphy_ln14lpp.h227
-rw-r--r--drivers/gpu/drm/imx/sec_mipi_dsim-imx.c390
-rw-r--r--drivers/gpu/drm/imx/sec_mipi_pll_1432x.h49
-rw-r--r--drivers/gpu/drm/mgag200/mgag200_mode.c2
-rw-r--r--drivers/gpu/drm/mxsfb/mxsfb_crtc.c287
-rw-r--r--drivers/gpu/drm/mxsfb/mxsfb_drv.c414
-rw-r--r--drivers/gpu/drm/mxsfb/mxsfb_drv.h26
-rw-r--r--drivers/gpu/drm/mxsfb/mxsfb_out.c25
-rw-r--r--drivers/gpu/drm/mxsfb/mxsfb_regs.h115
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_connector.c4
-rw-r--r--drivers/gpu/drm/panel/Kconfig18
-rw-r--r--drivers/gpu/drm/panel/Makefile2
-rw-r--r--drivers/gpu/drm/panel/panel-raydium-rm67191.c731
-rw-r--r--drivers/gpu/drm/panel/panel-seiko-43wvf1g.c372
-rw-r--r--drivers/gpu/drm/panel/panel-simple.c39
-rw-r--r--drivers/gpu/drm/radeon/r100.c2
-rw-r--r--drivers/gpu/drm/radeon/r600_cs.c2
-rw-r--r--drivers/gpu/drm/radeon/radeon_connectors.c16
-rw-r--r--drivers/gpu/drm/udl/udl_connector.c2
-rw-r--r--drivers/gpu/drm/vivante/Makefile29
-rw-r--r--drivers/gpu/drm/vivante/vivante_drv.c140
-rw-r--r--drivers/gpu/drm/vivante/vivante_drv.h66
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c4
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_kms.c2
-rw-r--r--drivers/gpu/imx/Kconfig20
-rw-r--r--drivers/gpu/imx/Makefile9
-rw-r--r--drivers/gpu/imx/dcss/Kconfig9
-rw-r--r--drivers/gpu/imx/dcss/Makefile6
-rw-r--r--drivers/gpu/imx/dcss/dcss-blkctl.c143
-rw-r--r--drivers/gpu/imx/dcss/dcss-common.c728
-rw-r--r--drivers/gpu/imx/dcss/dcss-ctxld.c517
-rw-r--r--drivers/gpu/imx/dcss/dcss-dec400d.c321
-rw-r--r--drivers/gpu/imx/dcss/dcss-dpr.c771
-rw-r--r--drivers/gpu/imx/dcss/dcss-dtg.c771
-rw-r--r--drivers/gpu/imx/dcss/dcss-dtrc.c612
-rw-r--r--drivers/gpu/imx/dcss/dcss-hdr10-tables.h1541
-rw-r--r--drivers/gpu/imx/dcss/dcss-hdr10.c655
-rw-r--r--drivers/gpu/imx/dcss/dcss-prv.h199
-rw-r--r--drivers/gpu/imx/dcss/dcss-rdsrc.c155
-rw-r--r--drivers/gpu/imx/dcss/dcss-scaler.c996
-rw-r--r--drivers/gpu/imx/dcss/dcss-ss.c227
-rw-r--r--drivers/gpu/imx/dcss/dcss-wrscl.c189
-rw-r--r--drivers/gpu/imx/dpu-blit/Kconfig5
-rw-r--r--drivers/gpu/imx/dpu-blit/Makefile5
-rw-r--r--drivers/gpu/imx/dpu-blit/dpu-blit-registers.h283
-rw-r--r--drivers/gpu/imx/dpu-blit/dpu-blit.c440
-rw-r--r--drivers/gpu/imx/dpu-blit/dpu-blit.h47
-rw-r--r--drivers/gpu/imx/dpu/Kconfig12
-rw-r--r--drivers/gpu/imx/dpu/Makefile7
-rw-r--r--drivers/gpu/imx/dpu/dpu-common.c1917
-rw-r--r--drivers/gpu/imx/dpu/dpu-constframe.c283
-rw-r--r--drivers/gpu/imx/dpu/dpu-disengcfg.c148
-rw-r--r--drivers/gpu/imx/dpu/dpu-extdst.c546
-rw-r--r--drivers/gpu/imx/dpu/dpu-fetchdecode.c778
-rw-r--r--drivers/gpu/imx/dpu/dpu-fetcheco.c434
-rw-r--r--drivers/gpu/imx/dpu/dpu-fetchlayer.c330
-rw-r--r--drivers/gpu/imx/dpu/dpu-fetchunit.c339
-rw-r--r--drivers/gpu/imx/dpu/dpu-fetchwarp.c332
-rw-r--r--drivers/gpu/imx/dpu/dpu-framegen.c778
-rw-r--r--drivers/gpu/imx/dpu/dpu-hscaler.c395
-rw-r--r--drivers/gpu/imx/dpu/dpu-layerblend.c343
-rw-r--r--drivers/gpu/imx/dpu/dpu-prv.h441
-rw-r--r--drivers/gpu/imx/dpu/dpu-store.c140
-rw-r--r--drivers/gpu/imx/dpu/dpu-tcon.c339
-rw-r--r--drivers/gpu/imx/dpu/dpu-vscaler.c447
-rw-r--r--drivers/gpu/imx/imx8_dprc.c908
-rw-r--r--drivers/gpu/imx/imx8_pc.c217
-rw-r--r--drivers/gpu/imx/imx8_prg.c451
-rw-r--r--drivers/gpu/imx/ipu-v3/Kconfig (renamed from drivers/gpu/ipu-v3/Kconfig)0
-rw-r--r--drivers/gpu/imx/ipu-v3/Makefile (renamed from drivers/gpu/ipu-v3/Makefile)0
-rw-r--r--drivers/gpu/imx/ipu-v3/ipu-common.c (renamed from drivers/gpu/ipu-v3/ipu-common.c)0
-rw-r--r--drivers/gpu/imx/ipu-v3/ipu-cpmem.c (renamed from drivers/gpu/ipu-v3/ipu-cpmem.c)0
-rw-r--r--drivers/gpu/imx/ipu-v3/ipu-csi.c (renamed from drivers/gpu/ipu-v3/ipu-csi.c)0
-rw-r--r--drivers/gpu/imx/ipu-v3/ipu-dc.c (renamed from drivers/gpu/ipu-v3/ipu-dc.c)0
-rw-r--r--drivers/gpu/imx/ipu-v3/ipu-di.c (renamed from drivers/gpu/ipu-v3/ipu-di.c)0
-rw-r--r--drivers/gpu/imx/ipu-v3/ipu-dmfc.c (renamed from drivers/gpu/ipu-v3/ipu-dmfc.c)0
-rw-r--r--drivers/gpu/imx/ipu-v3/ipu-dp.c (renamed from drivers/gpu/ipu-v3/ipu-dp.c)0
-rw-r--r--drivers/gpu/imx/ipu-v3/ipu-ic.c (renamed from drivers/gpu/ipu-v3/ipu-ic.c)0
-rw-r--r--drivers/gpu/imx/ipu-v3/ipu-image-convert.c (renamed from drivers/gpu/ipu-v3/ipu-image-convert.c)0
-rw-r--r--drivers/gpu/imx/ipu-v3/ipu-pre.c (renamed from drivers/gpu/ipu-v3/ipu-pre.c)0
-rw-r--r--drivers/gpu/imx/ipu-v3/ipu-prg.c (renamed from drivers/gpu/ipu-v3/ipu-prg.c)0
-rw-r--r--drivers/gpu/imx/ipu-v3/ipu-prv.h (renamed from drivers/gpu/ipu-v3/ipu-prv.h)0
-rw-r--r--drivers/gpu/imx/ipu-v3/ipu-smfc.c (renamed from drivers/gpu/ipu-v3/ipu-smfc.c)0
-rw-r--r--drivers/gpu/imx/ipu-v3/ipu-vdi.c (renamed from drivers/gpu/ipu-v3/ipu-vdi.c)0
-rw-r--r--drivers/gpu/imx/lcdif/Kconfig8
-rw-r--r--drivers/gpu/imx/lcdif/Makefile3
-rw-r--r--drivers/gpu/imx/lcdif/lcdif-common.c800
-rw-r--r--drivers/gpu/imx/lcdif/lcdif-regs.h144
-rw-r--r--drivers/hwmon/Kconfig26
-rw-r--r--drivers/hwmon/Makefile3
-rw-r--r--drivers/hwmon/mag3110.c654
-rw-r--r--drivers/hwmon/max17135-hwmon.c176
-rw-r--r--drivers/hwmon/mxc_mma8451.c599
-rw-r--r--drivers/i2c/busses/Kconfig30
-rw-r--r--drivers/i2c/busses/Makefile4
-rw-r--r--drivers/i2c/busses/i2c-imx-lpi2c.c170
-rw-r--r--drivers/i2c/busses/i2c-imx.c71
-rw-r--r--drivers/i2c/busses/i2c-rpmsg-imx.c459
-rw-r--r--drivers/i2c/busses/xen-i2cback.c494
-rw-r--r--drivers/i2c/busses/xen-i2cfront.c515
-rw-r--r--drivers/i2c/muxes/i2c-mux-pca954x.c7
-rw-r--r--drivers/iio/adc/Kconfig10
-rw-r--r--drivers/iio/adc/Makefile1
-rw-r--r--drivers/iio/adc/imx8qxp_adc.c724
-rw-r--r--drivers/iio/adc/vf610_adc.c10
-rw-r--r--drivers/input/keyboard/Kconfig26
-rw-r--r--drivers/input/keyboard/Makefile3
-rw-r--r--drivers/input/keyboard/atkbd.c3
-rw-r--r--drivers/input/keyboard/gpio_keys.c4
-rw-r--r--drivers/input/keyboard/imx_keypad.c8
-rw-r--r--drivers/input/keyboard/imx_sc_pwrkey.c173
-rw-r--r--drivers/input/keyboard/pf1550_onkey.c206
-rw-r--r--drivers/input/keyboard/rpmsg-keys.c310
-rw-r--r--drivers/input/misc/Kconfig35
-rw-r--r--drivers/input/misc/Makefile4
-rw-r--r--drivers/input/misc/fxls8471.c583
-rw-r--r--drivers/input/misc/fxls8471.h94
-rw-r--r--drivers/input/misc/fxls8471_i2c.c111
-rw-r--r--drivers/input/misc/isl29023.c1075
-rw-r--r--drivers/input/misc/mma8450.c173
-rw-r--r--drivers/input/misc/mpl3115.c356
-rw-r--r--drivers/input/misc/rpmsg_input.c528
-rw-r--r--drivers/input/touchscreen/Kconfig28
-rw-r--r--drivers/input/touchscreen/Makefile4
-rw-r--r--drivers/input/touchscreen/ads7846.c8
-rw-r--r--drivers/input/touchscreen/egalax_ts.c55
-rw-r--r--drivers/input/touchscreen/elan_ts.c472
-rw-r--r--drivers/input/touchscreen/focaltech_touch/Kconfig16
-rw-r--r--drivers/input/touchscreen/focaltech_touch/Makefile13
-rw-r--r--drivers/input/touchscreen/focaltech_touch/focaltech_common.h211
-rw-r--r--drivers/input/touchscreen/focaltech_touch/focaltech_config.h219
-rw-r--r--drivers/input/touchscreen/focaltech_touch/focaltech_core.c1439
-rw-r--r--drivers/input/touchscreen/focaltech_touch/focaltech_core.h189
-rw-r--r--drivers/input/touchscreen/focaltech_touch/focaltech_esdcheck.c473
-rw-r--r--drivers/input/touchscreen/focaltech_touch/focaltech_ex_mode.c357
-rw-r--r--drivers/input/touchscreen/focaltech_touch/focaltech_gesture.c652
-rw-r--r--drivers/input/touchscreen/focaltech_touch/focaltech_i2c.c209
-rw-r--r--drivers/input/touchscreen/focaltech_touch/focaltech_point_report_check.c151
-rw-r--r--drivers/input/touchscreen/focaltech_touch/focaltech_sensor.c311
-rw-r--r--drivers/input/touchscreen/focaltech_touch/include/firmware/FT8716_app_sample.i0
-rw-r--r--drivers/input/touchscreen/focaltech_touch/include/firmware/lcd_cfg.i0
-rw-r--r--drivers/input/touchscreen/focaltech_touch/include/pramboot/FT8606_Pramboot_V0.7_20150507.i244
-rw-r--r--drivers/input/touchscreen/focaltech_touch/include/pramboot/FT8607_Pramboot_V0.3_20160727.i248
-rw-r--r--drivers/input/touchscreen/focaltech_touch/include/pramboot/FT8716_Pramboot_V0.5_20160723.i303
-rw-r--r--drivers/input/touchscreen/focaltech_touch/include/pramboot/FT8736_Pramboot_V0.4_20160627.i288
-rw-r--r--drivers/input/touchscreen/max11801_ts.c161
-rw-r--r--drivers/input/touchscreen/synaptics_dsx/Kconfig27
-rw-r--r--drivers/input/touchscreen/synaptics_dsx/Makefile2
-rw-r--r--drivers/input/touchscreen/synaptics_dsx/synaptics_dsx.h86
-rw-r--r--drivers/input/touchscreen/synaptics_dsx/synaptics_dsx_i2c.c3622
-rw-r--r--drivers/input/touchscreen/synaptics_dsx/synaptics_dsx_i2c.h421
-rw-r--r--drivers/input/touchscreen/vtl/Makefile5
-rw-r--r--drivers/input/touchscreen/vtl/vtl_ts.c496
-rw-r--r--drivers/input/touchscreen/vtl/vtl_ts.h181
-rw-r--r--drivers/iommu/io-pgtable-arm.c3
-rw-r--r--drivers/irqchip/Kconfig12
-rw-r--r--drivers/irqchip/Makefile2
-rw-r--r--drivers/irqchip/irq-gic-v3.c29
-rw-r--r--drivers/irqchip/irq-imx-intmux.c237
-rw-r--r--drivers/irqchip/irq-imx-irqsteer.c337
-rw-r--r--drivers/media/platform/Kconfig23
-rw-r--r--drivers/media/platform/Makefile6
-rw-r--r--drivers/media/platform/imx8/Kconfig57
-rw-r--r--drivers/media/platform/imx8/Makefile15
-rw-r--r--drivers/media/platform/imx8/hdmi/API_AFE_ss28fdsoi_hdmirx.c1233
-rw-r--r--drivers/media/platform/imx8/hdmi/API_AFE_ss28fdsoi_hdmirx.h142
-rw-r--r--drivers/media/platform/imx8/hdmi/Kconfig4
-rw-r--r--drivers/media/platform/imx8/hdmi/Makefile2
-rw-r--r--drivers/media/platform/imx8/hdmi/mxc-hdmi-hw.c523
-rw-r--r--drivers/media/platform/imx8/hdmi/mxc-hdmi-rx-audio.c250
-rw-r--r--drivers/media/platform/imx8/hdmi/mxc-hdmi-rx.c1051
-rw-r--r--drivers/media/platform/imx8/hdmi/mxc-hdmi-rx.h153
-rw-r--r--drivers/media/platform/imx8/max9286.c3386
-rw-r--r--drivers/media/platform/imx8/mxc-isi-cap.c1795
-rw-r--r--drivers/media/platform/imx8/mxc-isi-core.c281
-rw-r--r--drivers/media/platform/imx8/mxc-isi-core.h355
-rw-r--r--drivers/media/platform/imx8/mxc-isi-hw.c803
-rw-r--r--drivers/media/platform/imx8/mxc-isi-hw.h507
-rw-r--r--drivers/media/platform/imx8/mxc-isi-m2m.c1117
-rw-r--r--drivers/media/platform/imx8/mxc-jpeg-hw.c244
-rw-r--r--drivers/media/platform/imx8/mxc-jpeg-hw.h142
-rw-r--r--drivers/media/platform/imx8/mxc-jpeg.c1772
-rw-r--r--drivers/media/platform/imx8/mxc-jpeg.h144
-rw-r--r--drivers/media/platform/imx8/mxc-media-dev.c884
-rw-r--r--drivers/media/platform/imx8/mxc-media-dev.h126
-rw-r--r--drivers/media/platform/imx8/mxc-mipi-csi2.c853
-rw-r--r--drivers/media/platform/imx8/mxc-mipi-csi2.h279
-rw-r--r--drivers/media/platform/imx8/mxc-mipi-csi2_yav.c748
-rw-r--r--drivers/media/platform/imx8/mxc-parallel-csi.c672
-rw-r--r--drivers/media/platform/imx8/mxc-parallel-csi.h170
-rw-r--r--drivers/media/platform/imx8/ov5640_mipi_v3.c1383
-rw-r--r--drivers/media/platform/imx8/ov5640_v3.c1741
-rw-r--r--drivers/media/platform/mxc/capture/Kconfig125
-rw-r--r--drivers/media/platform/mxc/capture/Makefile38
-rw-r--r--drivers/media/platform/mxc/capture/adv7180.c1380
-rw-r--r--drivers/media/platform/mxc/capture/ipu_bg_overlay_sdc.c552
-rw-r--r--drivers/media/platform/mxc/capture/ipu_csi_enc.c430
-rw-r--r--drivers/media/platform/mxc/capture/ipu_fg_overlay_sdc.c638
-rw-r--r--drivers/media/platform/mxc/capture/ipu_prp_enc.c597
-rw-r--r--drivers/media/platform/mxc/capture/ipu_prp_sw.h43
-rw-r--r--drivers/media/platform/mxc/capture/ipu_prp_vf_sdc.c582
-rw-r--r--drivers/media/platform/mxc/capture/ipu_prp_vf_sdc_bg.c521
-rw-r--r--drivers/media/platform/mxc/capture/ipu_still.c268
-rw-r--r--drivers/media/platform/mxc/capture/mx6s_capture.c2047
-rw-r--r--drivers/media/platform/mxc/capture/mxc_mipi_csi.c1317
-rw-r--r--drivers/media/platform/mxc/capture/mxc_v4l2_capture.c3148
-rw-r--r--drivers/media/platform/mxc/capture/mxc_v4l2_capture.h262
-rw-r--r--drivers/media/platform/mxc/capture/mxc_vadc.c830
-rw-r--r--drivers/media/platform/mxc/capture/mxc_vadc.h239
-rw-r--r--drivers/media/platform/mxc/capture/ov5640.c1950
-rw-r--r--drivers/media/platform/mxc/capture/ov5640_mipi.c2142
-rw-r--r--drivers/media/platform/mxc/capture/ov5640_mipi_v2.c1818
-rw-r--r--drivers/media/platform/mxc/capture/ov5640_v2.c1895
-rw-r--r--drivers/media/platform/mxc/capture/ov5642.c4252
-rw-r--r--drivers/media/platform/mxc/capture/ov5647_mipi.c1721
-rw-r--r--drivers/media/platform/mxc/capture/v4l2-int-device.c165
-rw-r--r--drivers/media/platform/mxc/capture/v4l2-int-device.h309
-rw-r--r--drivers/media/platform/mxc/output/Kconfig16
-rw-r--r--drivers/media/platform/mxc/output/Makefile2
-rw-r--r--drivers/media/platform/mxc/output/mxc_pxp_v4l2.c1346
-rw-r--r--drivers/media/platform/mxc/output/mxc_pxp_v4l2.h87
-rw-r--r--drivers/media/platform/mxc/output/mxc_vout.c2331
-rw-r--r--drivers/media/radio/radio-si476x.c24
-rw-r--r--drivers/media/v4l2-core/v4l2-async.c7
-rw-r--r--drivers/media/v4l2-core/v4l2-dev.c29
-rw-r--r--drivers/media/v4l2-core/v4l2-device.c1
-rw-r--r--drivers/media/v4l2-core/v4l2-ioctl.c37
-rw-r--r--drivers/media/v4l2-core/videobuf-core.c7
-rw-r--r--drivers/mfd/Kconfig37
-rw-r--r--drivers/mfd/Makefile5
-rw-r--r--drivers/mfd/bd71837.c310
-rw-r--r--drivers/mfd/max17135-core.c281
-rw-r--r--drivers/mfd/mxc-hdmi-core.c821
-rw-r--r--drivers/mfd/pf1550.c311
-rw-r--r--drivers/mfd/si476x-i2c.c23
-rw-r--r--drivers/misc/Kconfig20
-rw-r--r--drivers/misc/Makefile2
-rw-r--r--drivers/misc/eeprom/at25.c2
-rw-r--r--drivers/misc/fxas2100x.c628
-rw-r--r--drivers/misc/fxos8700.c978
-rw-r--r--drivers/misc/sram.c2
-rw-r--r--drivers/mmc/Kconfig10
-rw-r--r--drivers/mmc/core/block.c708
-rw-r--r--drivers/mmc/core/block.h11
-rw-r--r--drivers/mmc/core/bus.c7
-rw-r--r--drivers/mmc/core/core.c293
-rw-r--r--drivers/mmc/core/core.h50
-rw-r--r--drivers/mmc/core/debugfs.c10
-rw-r--r--drivers/mmc/core/host.c31
-rw-r--r--drivers/mmc/core/host.h11
-rw-r--r--drivers/mmc/core/mmc.c33
-rw-r--r--drivers/mmc/core/mmc_ops.c7
-rw-r--r--drivers/mmc/core/queue.c491
-rw-r--r--drivers/mmc/core/queue.h50
-rw-r--r--drivers/mmc/core/sd.c11
-rw-r--r--drivers/mmc/core/sdio.c44
-rw-r--r--drivers/mmc/core/sdio_irq.c3
-rw-r--r--drivers/mmc/host/Kconfig16
-rw-r--r--drivers/mmc/host/Makefile1
-rw-r--r--drivers/mmc/host/cqhci.c1157
-rw-r--r--drivers/mmc/host/cqhci.h240
-rw-r--r--drivers/mmc/host/sdhci-esdhc-imx.c429
-rw-r--r--drivers/mmc/host/sdhci-of-esdhc.c10
-rw-r--r--drivers/mmc/host/sdhci-pltfm.c6
-rw-r--r--drivers/mmc/host/sdhci.c114
-rw-r--r--drivers/mmc/host/sdhci.h3
-rw-r--r--drivers/mtd/Makefile2
-rw-r--r--drivers/mtd/nand/gpmi-nand/bch-regs.h22
-rw-r--r--drivers/mtd/nand/gpmi-nand/gpmi-lib.c111
-rw-r--r--drivers/mtd/nand/gpmi-nand/gpmi-nand.c451
-rw-r--r--drivers/mtd/nand/gpmi-nand/gpmi-nand.h30
-rw-r--r--drivers/mtd/spi-nor/Kconfig6
-rw-r--r--drivers/mtd/spi-nor/Makefile1
-rw-r--r--drivers/mtd/spi-nor/fsl-flexspi.c1590
-rw-r--r--drivers/mtd/spi-nor/fsl-quadspi.c548
-rw-r--r--drivers/mtd/spi-nor/spi-nor.c67
-rw-r--r--drivers/mtd/ubi/build.c2
-rwxr-xr-xdrivers/mxc/Kconfig46
-rwxr-xr-xdrivers/mxc/Makefile15
-rw-r--r--drivers/mxc/gpu-viv/Kbuild326
-rw-r--r--drivers/mxc/gpu-viv/Kconfig11
-rw-r--r--drivers/mxc/gpu-viv/config72
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/arch/gc_hal_kernel_context.c4794
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/arch/gc_hal_kernel_context.h188
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/arch/gc_hal_kernel_hardware.c18555
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/arch/gc_hal_kernel_hardware.h376
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/arch/gc_hal_kernel_recorder.c728
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/archvg/gc_hal_kernel_hardware_command_vg.c1411
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/archvg/gc_hal_kernel_hardware_command_vg.h353
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/archvg/gc_hal_kernel_hardware_vg.c2450
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/archvg/gc_hal_kernel_hardware_vg.h110
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.c6637
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.h2113
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_async_command.c477
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_command.c3472
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_command_vg.c3950
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_db.c1877
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_debug.c2871
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_event.c3017
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_heap.c892
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_interrupt_vg.c911
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_mmu.c2990
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_mmu_vg.c556
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_power.c381
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_precomp.h63
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_security.c286
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_security_v1.c320
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_vg.c644
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_vg.h119
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_video_memory.c3590
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/inc/gc_feature_database.h108065
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal.h2854
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_base.h6048
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_driver.h1402
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_driver_vg.h302
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_drm.h200
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_dump.h125
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_eglplatform.h589
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_eglplatform_type.h326
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_engine.h2977
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_engine_vg.h1320
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_enum.h2194
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_kernel_buffer.h314
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_mem.h566
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_metadata.h121
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_options.h1408
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_profiler.h1175
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_raster.h1109
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_rename.h279
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_resource.h69
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_security_interface.h186
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_statistics.h135
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_types.h1037
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_version.h71
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_vg.h918
-rw-r--r--drivers/mxc/gpu-viv/hal/os/linux/kernel/allocator/default/gc_hal_kernel_allocator_array.h119
-rw-r--r--drivers/mxc/gpu-viv/hal/os/linux/kernel/allocator/default/gc_hal_kernel_allocator_dma.c604
-rw-r--r--drivers/mxc/gpu-viv/hal/os/linux/kernel/allocator/default/gc_hal_kernel_allocator_dmabuf.c546
-rw-r--r--drivers/mxc/gpu-viv/hal/os/linux/kernel/allocator/default/gc_hal_kernel_allocator_gfp.c1153
-rw-r--r--drivers/mxc/gpu-viv/hal/os/linux/kernel/allocator/default/gc_hal_kernel_allocator_reserved_mem.c511
-rw-r--r--drivers/mxc/gpu-viv/hal/os/linux/kernel/allocator/default/gc_hal_kernel_allocator_user_memory.c854
-rw-r--r--drivers/mxc/gpu-viv/hal/os/linux/kernel/allocator/freescale/gc_hal_kernel_allocator_array.h131
-rw-r--r--drivers/mxc/gpu-viv/hal/os/linux/kernel/allocator/freescale/gc_hal_kernel_allocator_cma.c603
-rw-r--r--drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_allocator.c260
-rw-r--r--drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_allocator.h572
-rw-r--r--drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_debug.h151
-rw-r--r--drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_debugfs.c965
-rw-r--r--drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_debugfs.h170
-rw-r--r--drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_device.c2362
-rw-r--r--drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_device.h273
-rw-r--r--drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_driver.c1331
-rw-r--r--drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_drm.c856
-rw-r--r--drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_iommu.c250
-rw-r--r--drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_linux.c510
-rw-r--r--drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_linux.h411
-rw-r--r--drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_math.c66
-rw-r--r--drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_mutex.h89
-rw-r--r--drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.c7822
-rw-r--r--drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.h123
-rw-r--r--drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_platform.h307
-rw-r--r--drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_security_channel.c426
-rw-r--r--drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_security_channel_emulator.c116
-rw-r--r--drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_sync.c378
-rw-r--r--drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_sync.h151
-rw-r--r--drivers/mxc/gpu-viv/hal/os/linux/kernel/platform/default/gc_hal_kernel_platform_default.c146
-rw-r--r--drivers/mxc/gpu-viv/hal/os/linux/kernel/platform/freescale/gc_hal_kernel_platform_imx.c1644
-rw-r--r--drivers/mxc/gpu-viv/hal/os/linux/kernel/platform/freescale/gc_hal_kernel_platform_imx.config29
-rw-r--r--drivers/mxc/gpu-viv/hal/security_v1/gc_hal_ta.c348
-rw-r--r--drivers/mxc/gpu-viv/hal/security_v1/gc_hal_ta.h373
-rw-r--r--drivers/mxc/gpu-viv/hal/security_v1/gc_hal_ta_hardware.c1073
-rw-r--r--drivers/mxc/gpu-viv/hal/security_v1/gc_hal_ta_hardware.h139
-rw-r--r--drivers/mxc/gpu-viv/hal/security_v1/gc_hal_ta_mmu.c586
-rw-r--r--drivers/mxc/gpu-viv/hal/security_v1/os/emulator/gc_hal_ta_emulator.c324
-rwxr-xr-xdrivers/mxc/hantro/Kconfig14
-rwxr-xr-xdrivers/mxc/hantro/Makefile8
-rwxr-xr-xdrivers/mxc/hantro/dwl_defs.h94
-rwxr-xr-xdrivers/mxc/hantro/hantrodec.c1938
-rwxr-xr-xdrivers/mxc/hantro_845/Kconfig14
-rwxr-xr-xdrivers/mxc/hantro_845/Makefile8
-rw-r--r--drivers/mxc/hantro_845/dwl_defs.h94
-rwxr-xr-xdrivers/mxc/hantro_845/hantrodec_845s.c2039
-rwxr-xr-xdrivers/mxc/hantro_845_h1/Kconfig14
-rwxr-xr-xdrivers/mxc/hantro_845_h1/Makefile8
-rwxr-xr-xdrivers/mxc/hantro_845_h1/hx280enc.c883
-rwxr-xr-xdrivers/mxc/hantro_845_h1/hx280enc.h79
-rw-r--r--drivers/mxc/hdmi-cec/Kconfig11
-rw-r--r--drivers/mxc/hdmi-cec/Makefile1
-rw-r--r--drivers/mxc/hdmi-cec/mxc_hdmi-cec.c665
-rw-r--r--drivers/mxc/hdmi-cec/mxc_hdmi-cec.h38
-rw-r--r--drivers/mxc/hdp-cec/Kconfig5
-rw-r--r--drivers/mxc/hdp-cec/Makefile1
-rw-r--r--drivers/mxc/hdp-cec/imx-hdp-cec.c316
-rw-r--r--drivers/mxc/hdp-cec/imx-hdp-cec.h346
-rw-r--r--drivers/mxc/hdp/API_AFE.c188
-rw-r--r--drivers/mxc/hdp/API_AFE.h111
-rw-r--r--drivers/mxc/hdp/API_Audio.c432
-rw-r--r--drivers/mxc/hdp/API_Audio.h159
-rw-r--r--drivers/mxc/hdp/API_DPTX.c1060
-rw-r--r--drivers/mxc/hdp/API_DPTX.h540
-rw-r--r--drivers/mxc/hdp/API_General.c518
-rw-r--r--drivers/mxc/hdp/API_General.h248
-rw-r--r--drivers/mxc/hdp/API_HDCP.c447
-rw-r--r--drivers/mxc/hdp/API_HDCP.h263
-rw-r--r--drivers/mxc/hdp/API_HDMIRX.c236
-rw-r--r--drivers/mxc/hdp/API_HDMIRX.h135
-rw-r--r--drivers/mxc/hdp/API_HDMITX.c494
-rw-r--r--drivers/mxc/hdp/API_HDMITX.h165
-rw-r--r--drivers/mxc/hdp/API_HDMI_RX_Audio.c191
-rw-r--r--drivers/mxc/hdp/API_HDMI_RX_Audio.h80
-rw-r--r--drivers/mxc/hdp/API_Infoframe.c166
-rw-r--r--drivers/mxc/hdp/API_Infoframe.h64
-rw-r--r--drivers/mxc/hdp/Kconfig5
-rw-r--r--drivers/mxc/hdp/Makefile13
-rw-r--r--drivers/mxc/hdp/address.h109
-rw-r--r--drivers/mxc/hdp/aif_pckt2smp.h168
-rw-r--r--drivers/mxc/hdp/all.h64
-rw-r--r--drivers/mxc/hdp/apb_cfg.h185
-rw-r--r--drivers/mxc/hdp/clock_meters.h157
-rw-r--r--drivers/mxc/hdp/dptx_framer.h372
-rw-r--r--drivers/mxc/hdp/dptx_stream.h208
-rw-r--r--drivers/mxc/hdp/general_handler.h160
-rw-r--r--drivers/mxc/hdp/hdcp.h52
-rw-r--r--drivers/mxc/hdp/hdcp2.h289
-rw-r--r--drivers/mxc/hdp/hdcp_tran.h258
-rw-r--r--drivers/mxc/hdp/hdmi.h122
-rw-r--r--drivers/mxc/hdp/mailBox.h116
-rw-r--r--drivers/mxc/hdp/mhl_hdtx_top.h220
-rw-r--r--drivers/mxc/hdp/opcodes.h117
-rw-r--r--drivers/mxc/hdp/sink_aif_encoder.h367
-rw-r--r--drivers/mxc/hdp/sink_car.h168
-rw-r--r--drivers/mxc/hdp/sink_clk_meters.h241
-rw-r--r--drivers/mxc/hdp/sink_core.h117
-rw-r--r--drivers/mxc/hdp/sink_mhl_hd.h418
-rw-r--r--drivers/mxc/hdp/sink_pif.h160
-rw-r--r--drivers/mxc/hdp/sink_vif.h285
-rw-r--r--drivers/mxc/hdp/source_aif_decoder.h452
-rw-r--r--drivers/mxc/hdp/source_aif_smpl2pckt.h113
-rw-r--r--drivers/mxc/hdp/source_car.h173
-rw-r--r--drivers/mxc/hdp/source_phy.h180
-rw-r--r--drivers/mxc/hdp/source_pif.h170
-rw-r--r--drivers/mxc/hdp/source_vif.h93
-rw-r--r--drivers/mxc/hdp/util.c360
-rw-r--r--drivers/mxc/hdp/util.h396
-rw-r--r--drivers/mxc/ipu3/Kconfig21
-rw-r--r--drivers/mxc/ipu3/Makefile7
-rw-r--r--drivers/mxc/ipu3/ipu_calc_stripes_sizes.c495
-rw-r--r--drivers/mxc/ipu3/ipu_capture.c816
-rw-r--r--drivers/mxc/ipu3/ipu_common.c3494
-rw-r--r--drivers/mxc/ipu3/ipu_device.c3755
-rw-r--r--drivers/mxc/ipu3/ipu_disp.c1993
-rw-r--r--drivers/mxc/ipu3/ipu_ic.c924
-rw-r--r--drivers/mxc/ipu3/ipu_param_mem.h998
-rw-r--r--drivers/mxc/ipu3/ipu_pixel_clk.c317
-rw-r--r--drivers/mxc/ipu3/ipu_prv.h369
-rw-r--r--drivers/mxc/ipu3/ipu_regs.h702
-rw-r--r--drivers/mxc/ipu3/pre-regs.h480
-rw-r--r--drivers/mxc/ipu3/pre.c999
-rw-r--r--drivers/mxc/ipu3/prg-regs.h70
-rw-r--r--drivers/mxc/ipu3/prg.c506
-rw-r--r--drivers/mxc/ipu3/vdoa.c537
-rw-r--r--drivers/mxc/ipu3/vdoa.h62
-rw-r--r--drivers/mxc/mipi/Kconfig14
-rw-r--r--drivers/mxc/mipi/Makefile4
-rw-r--r--drivers/mxc/mipi/mxc_mipi_csi2.c540
-rw-r--r--drivers/mxc/mipi/mxc_mipi_csi2.h46
-rw-r--r--drivers/mxc/mlb/Kconfig17
-rw-r--r--drivers/mxc/mlb/Makefile5
-rwxr-xr-xdrivers/mxc/mlb/mxc_mlb.c2813
-rw-r--r--drivers/mxc/sim/Kconfig27
-rw-r--r--drivers/mxc/sim/Makefile6
-rw-r--r--drivers/mxc/sim/imx_emvsim.c1638
-rwxr-xr-xdrivers/mxc/sim/imx_sim.c1865
-rw-r--r--drivers/mxc/vpu/Kconfig31
-rw-r--r--drivers/mxc/vpu/Makefile9
-rw-r--r--drivers/mxc/vpu/mxc_vpu.c1349
-rw-r--r--drivers/mxc/vpu_legacy/Kconfig20
-rw-r--r--drivers/mxc/vpu_legacy/Makefile197
-rwxr-xr-xdrivers/mxc/vpu_legacy/Malone_Firmware/DecKLib/Control/DecKernelLibHWControl.c326
-rwxr-xr-xdrivers/mxc/vpu_legacy/Malone_Firmware/DecKLib/Control/DecKernelLibHWControl.h175
-rwxr-xr-xdrivers/mxc/vpu_legacy/Malone_Firmware/DecKLib/Control/DecKernelLibHWIsr.c514
-rwxr-xr-xdrivers/mxc/vpu_legacy/Malone_Firmware/DecKLib/Incl/DecKernelLib.h121
-rwxr-xr-xdrivers/mxc/vpu_legacy/Malone_Firmware/DecKLib/Incl/mvd.h157
-rwxr-xr-xdrivers/mxc/vpu_legacy/Malone_Firmware/DecKLib/Incl/mvd_reg_map.h1676
-rwxr-xr-xdrivers/mxc/vpu_legacy/Malone_Firmware/DecKLib/Incl/mvd_sif_control.h975
-rwxr-xr-xdrivers/mxc/vpu_legacy/Malone_Firmware/DecKLib/Incl/mvd_types.h132
-rwxr-xr-xdrivers/mxc/vpu_legacy/Malone_Firmware/DecKLib/KernelIF/DecKernelLib.c152
-rwxr-xr-xdrivers/mxc/vpu_legacy/Malone_Firmware/DecKLib/KernelIF/DecKernelLibCfg.h95
-rwxr-xr-xdrivers/mxc/vpu_legacy/Malone_Firmware/DecKLib/KernelIF/DecKernelLibPrivate.c171
-rwxr-xr-xdrivers/mxc/vpu_legacy/Malone_Firmware/DecKLib/KernelIF/DecKernelLibPrivate.h69
-rwxr-xr-xdrivers/mxc/vpu_legacy/Malone_Firmware/Incl/basetype.h343
-rwxr-xr-xdrivers/mxc/vpu_legacy/Malone_Firmware/Incl/mediaip_fw_defines.h249
-rwxr-xr-xdrivers/mxc/vpu_legacy/Malone_Firmware/Incl/mediaip_fw_types.h1991
-rwxr-xr-xdrivers/mxc/vpu_legacy/Malone_Firmware/Incl/pal.h337
-rwxr-xr-xdrivers/mxc/vpu_legacy/Malone_Firmware/Incl/status_codes.h99
-rwxr-xr-xdrivers/mxc/vpu_legacy/Malone_Firmware/Incl/trace_types.h261
-rwxr-xr-xdrivers/mxc/vpu_legacy/Malone_Firmware/PAL/Incl/pal_linux_map.h149
-rwxr-xr-xdrivers/mxc/vpu_legacy/Malone_Firmware/PAL/Incl/pal_types.h170
-rwxr-xr-xdrivers/mxc/vpu_legacy/Malone_Firmware/PAL/pal.c780
-rw-r--r--drivers/mxc/vpu_legacy/VPU_debug.h95
-rw-r--r--drivers/mxc/vpu_legacy/VPU_regdef.h57
-rw-r--r--drivers/mxc/vpu_legacy/mxc_vpu-malone.c1344
-rw-r--r--drivers/mxc/vpu_malone/Kconfig20
-rw-r--r--drivers/mxc/vpu_malone/Makefile16
-rw-r--r--drivers/mxc/vpu_malone/insert_startcode.c546
-rw-r--r--drivers/mxc/vpu_malone/insert_startcode.h39
-rw-r--r--drivers/mxc/vpu_malone/mediasys_types.h793
-rw-r--r--drivers/mxc/vpu_malone/vpu_b0.c4321
-rw-r--r--drivers/mxc/vpu_malone/vpu_b0.h324
-rw-r--r--drivers/mxc/vpu_malone/vpu_debug_log.c137
-rw-r--r--drivers/mxc/vpu_malone/vpu_debug_log.h48
-rw-r--r--drivers/mxc/vpu_malone/vpu_rpc.c364
-rw-r--r--drivers/mxc/vpu_malone/vpu_rpc.h118
-rw-r--r--drivers/mxc/vpu_windsor/Kconfig25
-rw-r--r--drivers/mxc/vpu_windsor/Makefile15
-rw-r--r--drivers/mxc/vpu_windsor/mediasys_types.h705
-rw-r--r--drivers/mxc/vpu_windsor/vpu_encoder_b0.c5811
-rw-r--r--drivers/mxc/vpu_windsor/vpu_encoder_b0.h468
-rw-r--r--drivers/mxc/vpu_windsor/vpu_encoder_config.h51
-rw-r--r--drivers/mxc/vpu_windsor/vpu_encoder_ctrl.c609
-rw-r--r--drivers/mxc/vpu_windsor/vpu_encoder_ctrl.h19
-rw-r--r--drivers/mxc/vpu_windsor/vpu_encoder_mem.c619
-rw-r--r--drivers/mxc/vpu_windsor/vpu_encoder_mem.h31
-rw-r--r--drivers/mxc/vpu_windsor/vpu_encoder_rpc.c448
-rw-r--r--drivers/mxc/vpu_windsor/vpu_encoder_rpc.h132
-rw-r--r--drivers/mxc/vpu_windsor/vpu_event_msg.c237
-rw-r--r--drivers/mxc/vpu_windsor/vpu_event_msg.h35
-rw-r--r--drivers/net/Kconfig4
-rw-r--r--drivers/net/Makefile2
-rw-r--r--drivers/net/can/Kconfig2
-rw-r--r--drivers/net/can/flexcan.c834
-rw-r--r--drivers/net/can/rx-offload.c25
-rw-r--r--drivers/net/ethernet/freescale/Kconfig6
-rw-r--r--drivers/net/ethernet/freescale/Makefile2
-rw-r--r--drivers/net/ethernet/freescale/fec.h65
-rw-r--r--drivers/net/ethernet/freescale/fec_fixup.c278
-rw-r--r--drivers/net/ethernet/freescale/fec_main.c431
-rw-r--r--drivers/net/ethernet/freescale/fec_ptp.c4
-rw-r--r--drivers/net/ivshmem-net.c984
-rw-r--r--drivers/net/phy/Kconfig5
-rw-r--r--drivers/net/phy/Makefile1
-rw-r--r--drivers/net/phy/at803x.c137
-rw-r--r--drivers/net/phy/phy_device.c51
-rw-r--r--drivers/net/phy/tja110x.c2542
-rw-r--r--drivers/net/phy/tja110x.h274
-rw-r--r--drivers/net/wireless/ath/ath10k/core.c4
-rw-r--r--drivers/net/wireless/ath/ath10k/pci.c4
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c32
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h10
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c264
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h41
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c73
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.h1
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c199
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h9
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c183
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h11
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c11
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil.c2
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h44
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c156
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c14
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c27
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c38
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.c5
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c366
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h62
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c33
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor.c6
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h2
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/include/brcmu_wifi.h1
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/include/chipcommon.h4
-rw-r--r--drivers/nvme/target/io-cmd.c2
-rw-r--r--drivers/nvmem/Kconfig14
-rw-r--r--drivers/nvmem/Makefile2
-rw-r--r--drivers/nvmem/imx-ocotp.c31
-rw-r--r--drivers/nvmem/imx-scu-ocotp.c180
-rw-r--r--drivers/of/base.c30
-rw-r--r--drivers/of/of_reserved_mem.c43
-rw-r--r--drivers/pci/dwc/Kconfig24
-rw-r--r--drivers/pci/dwc/Makefile1
-rw-r--r--drivers/pci/dwc/pci-imx6-ep-driver.c209
-rw-r--r--drivers/pci/dwc/pci-imx6.c2531
-rw-r--r--drivers/pci/dwc/pcie-designware-host.c69
-rw-r--r--drivers/pci/dwc/pcie-designware.c3
-rw-r--r--drivers/pci/dwc/pcie-designware.h14
-rw-r--r--drivers/pci/host/Kconfig1
-rw-r--r--drivers/pci/host/pci-host-common.c14
-rw-r--r--drivers/pci/host/pci-host-generic.c1
-rw-r--r--drivers/pci/pci.c6
-rw-r--r--drivers/pci/quirks.c2
-rw-r--r--drivers/perf/Kconfig3
-rw-r--r--drivers/perf/Makefile1
-rw-r--r--drivers/perf/ddr-perf.c531
-rw-r--r--drivers/phy/Kconfig24
-rw-r--r--drivers/phy/Makefile4
-rw-r--r--drivers/phy/phy-fsl-imx8mq-usb.c136
-rw-r--r--drivers/phy/phy-mixel-lvds-combo.c285
-rw-r--r--drivers/phy/phy-mixel-lvds.c309
-rw-r--r--drivers/phy/phy-mixel-mipi-dsi.c545
-rw-r--r--drivers/pinctrl/devicetree.c47
-rw-r--r--drivers/pinctrl/freescale/Kconfig58
-rw-r--r--drivers/pinctrl/freescale/Makefile7
-rw-r--r--drivers/pinctrl/freescale/pinctrl-imx.c295
-rw-r--r--drivers/pinctrl/freescale/pinctrl-imx.h92
-rw-r--r--drivers/pinctrl/freescale/pinctrl-imx6sll.c388
-rw-r--r--drivers/pinctrl/freescale/pinctrl-imx6ul.c52
-rw-r--r--drivers/pinctrl/freescale/pinctrl-imx7d.c17
-rw-r--r--drivers/pinctrl/freescale/pinctrl-imx7ulp.c165
-rw-r--r--drivers/pinctrl/freescale/pinctrl-imx8mm.c384
-rw-r--r--drivers/pinctrl/freescale/pinctrl-imx8mq.c385
-rw-r--r--drivers/pinctrl/freescale/pinctrl-imx8qm.c358
-rw-r--r--drivers/pinctrl/freescale/pinctrl-imx8qxp.c263
-rw-r--r--drivers/pinctrl/freescale/pinctrl-memmap.c212
-rw-r--r--drivers/pinctrl/freescale/pinctrl-scu.c109
-rw-r--r--drivers/pinctrl/freescale/pinctrl-vf610.c2
-rw-r--r--drivers/power/supply/Kconfig14
-rw-r--r--drivers/power/supply/Makefile2
-rw-r--r--drivers/power/supply/pf1550_charger.c656
-rw-r--r--drivers/power/supply/sabresd_battery.c1014
-rw-r--r--drivers/pwm/Kconfig11
-rw-r--r--drivers/pwm/Makefile1
-rw-r--r--drivers/pwm/pwm-fsl-ftm.c49
-rw-r--r--drivers/pwm/pwm-imx.c58
-rw-r--r--drivers/pwm/pwm-tpm.c258
-rw-r--r--drivers/regulator/Kconfig25
-rw-r--r--drivers/regulator/Makefile4
-rw-r--r--drivers/regulator/anatop-regulator.c96
-rw-r--r--drivers/regulator/bd71837-regulator.c1054
-rw-r--r--drivers/regulator/core.c40
-rw-r--r--drivers/regulator/fixed.c24
-rw-r--r--drivers/regulator/max17135-regulator.c858
-rw-r--r--drivers/regulator/pf1550-regulator-rpmsg.c512
-rw-r--r--drivers/regulator/pf1550.c390
-rw-r--r--drivers/regulator/pfuze100-regulator.c110
-rw-r--r--drivers/regulator/userspace-consumer.c53
-rw-r--r--drivers/regulator/virtual.c38
-rw-r--r--drivers/reset/Kconfig8
-rw-r--r--drivers/reset/Makefile1
-rw-r--r--drivers/reset/gpio-reset.c216
-rw-r--r--drivers/rpmsg/Kconfig15
-rw-r--r--drivers/rpmsg/Makefile3
-rw-r--r--drivers/rpmsg/imx_rpmsg.c838
-rw-r--r--drivers/rpmsg/imx_rpmsg_pingpong.c108
-rw-r--r--drivers/rpmsg/imx_rpmsg_tty.c252
-rw-r--r--drivers/rpmsg/virtio_rpmsg_bus.c45
-rw-r--r--drivers/rtc/Kconfig14
-rw-r--r--drivers/rtc/Makefile2
-rw-r--r--drivers/rtc/rtc-imx-rpmsg.c383
-rw-r--r--drivers/rtc/rtc-imx-sc.c219
-rw-r--r--drivers/rtc/rtc-snvs.c2
-rw-r--r--drivers/scsi/scsi_error.c20
-rw-r--r--drivers/soc/Makefile2
-rw-r--r--drivers/soc/imx/Kconfig45
-rw-r--r--drivers/soc/imx/Makefile6
-rw-r--r--drivers/soc/imx/busfreq-imx8mq.c748
-rw-r--r--drivers/soc/imx/gpc-psci.c425
-rw-r--r--drivers/soc/imx/gpc.c326
-rw-r--r--drivers/soc/imx/gpcv2.c206
-rw-r--r--drivers/soc/imx/mu/Makefile1
-rw-r--r--drivers/soc/imx/mu/mx8_mu.c187
-rw-r--r--drivers/soc/imx/pm-domain-imx8.h60
-rw-r--r--drivers/soc/imx/pm-domains.c658
-rw-r--r--drivers/soc/imx/sc/Makefile9
-rw-r--r--drivers/soc/imx/sc/main/ipc.c420
-rw-r--r--drivers/soc/imx/sc/main/rpc.h158
-rw-r--r--drivers/soc/imx/sc/svc/irq/rpc.h46
-rw-r--r--drivers/soc/imx/sc/svc/irq/rpc_clnt.c74
-rw-r--r--drivers/soc/imx/sc/svc/misc/rpc.h79
-rw-r--r--drivers/soc/imx/sc/svc/misc/rpc_clnt.c707
-rw-r--r--drivers/soc/imx/sc/svc/pad/rpc.h60
-rw-r--r--drivers/soc/imx/sc/svc/pad/rpc_clnt.c423
-rw-r--r--drivers/soc/imx/sc/svc/pm/rpc.h71
-rw-r--r--drivers/soc/imx/sc/svc/pm/rpc_clnt.c561
-rw-r--r--drivers/soc/imx/sc/svc/rm/rpc.h77
-rw-r--r--drivers/soc/imx/sc/svc/rm/rpc_clnt.c672
-rw-r--r--drivers/soc/imx/sc/svc/seco/rpc.h64
-rw-r--r--drivers/soc/imx/sc/svc/seco/rpc_clnt.c430
-rw-r--r--drivers/soc/imx/sc/svc/timer/rpc.h62
-rw-r--r--drivers/soc/imx/sc/svc/timer/rpc_clnt.c392
-rw-r--r--drivers/soc/imx/soc-imx8.c627
-rw-r--r--drivers/spi/Kconfig4
-rw-r--r--drivers/spi/spi-fsl-lpspi.c776
-rw-r--r--drivers/spi/spi-imx.c486
-rw-r--r--drivers/staging/Makefile2
-rw-r--r--drivers/staging/android/Kconfig4
-rw-r--r--drivers/staging/typec/pd.h12
-rw-r--r--drivers/staging/typec/tcpci.c494
-rw-r--r--drivers/staging/typec/tcpci.h9
-rw-r--r--drivers/staging/typec/tcpm.c294
-rw-r--r--drivers/staging/typec/tcpm.h20
-rw-r--r--drivers/staging/vboxvideo/vbox_mode.c2
-rw-r--r--drivers/tee/optee/call.c24
-rw-r--r--drivers/tee/optee/core.c90
-rw-r--r--drivers/tee/optee/optee_private.h43
-rw-r--r--drivers/tee/optee/optee_smc.h43
-rw-r--r--drivers/tee/optee/rpc.c4
-rw-r--r--drivers/tee/optee/supp.c375
-rw-r--r--drivers/tee/tee_core.c195
-rw-r--r--drivers/tee/tee_shm.c136
-rw-r--r--drivers/thermal/Kconfig36
-rw-r--r--drivers/thermal/Makefile4
-rw-r--r--drivers/thermal/device_cooling.c151
-rw-r--r--drivers/thermal/imx8mm_thermal.c240
-rw-r--r--drivers/thermal/imx_sc_thermal.c242
-rw-r--r--drivers/thermal/imx_thermal.c565
-rw-r--r--drivers/thermal/qoriq_thermal.c81
-rw-r--r--drivers/tty/serial/Kconfig2
-rw-r--r--drivers/tty/serial/fsl_lpuart.c1252
-rw-r--r--drivers/tty/serial/imx.c673
-rw-r--r--drivers/usb/Kconfig2
-rw-r--r--drivers/usb/Makefile1
-rw-r--r--drivers/usb/cdns3/Kconfig26
-rw-r--r--drivers/usb/cdns3/Makefile5
-rw-r--r--drivers/usb/cdns3/cdns3-nxp-reg-def.h174
-rw-r--r--drivers/usb/cdns3/core.c1009
-rw-r--r--drivers/usb/cdns3/core.h131
-rw-r--r--drivers/usb/cdns3/dev-regs-macro.h894
-rw-r--r--drivers/usb/cdns3/dev-regs-map.h126
-rw-r--r--drivers/usb/cdns3/gadget-export.h36
-rw-r--r--drivers/usb/cdns3/gadget.c2555
-rw-r--r--drivers/usb/cdns3/gadget.h225
-rw-r--r--drivers/usb/cdns3/host-export.h43
-rw-r--r--drivers/usb/cdns3/host.c286
-rw-r--r--drivers/usb/cdns3/io.h35
-rw-r--r--drivers/usb/chipidea/ci.h45
-rw-r--r--drivers/usb/chipidea/ci_hdrc_imx.c319
-rw-r--r--drivers/usb/chipidea/ci_hdrc_imx.h22
-rw-r--r--drivers/usb/chipidea/core.c202
-rw-r--r--drivers/usb/chipidea/host.c332
-rw-r--r--drivers/usb/chipidea/host.h8
-rw-r--r--drivers/usb/chipidea/otg.c112
-rw-r--r--drivers/usb/chipidea/otg.h14
-rw-r--r--drivers/usb/chipidea/otg_fsm.c218
-rw-r--r--drivers/usb/chipidea/otg_fsm.h28
-rw-r--r--drivers/usb/chipidea/udc.c228
-rw-r--r--drivers/usb/chipidea/udc.h13
-rw-r--r--drivers/usb/chipidea/usbmisc_imx.c672
-rw-r--r--drivers/usb/common/usb-otg-fsm.c54
-rw-r--r--drivers/usb/core/hcd.c134
-rw-r--r--drivers/usb/core/hub.c23
-rw-r--r--drivers/usb/core/otg_whitelist.h88
-rw-r--r--drivers/usb/dwc3/core.c83
-rw-r--r--drivers/usb/dwc3/core.h4
-rw-r--r--drivers/usb/dwc3/dwc3-of-simple.c1
-rw-r--r--drivers/usb/dwc3/gadget.c22
-rw-r--r--drivers/usb/gadget/Kconfig6
-rw-r--r--drivers/usb/gadget/function/f_mass_storage.c70
-rw-r--r--drivers/usb/gadget/function/fsl_updater.c644
-rw-r--r--drivers/usb/gadget/function/fsl_updater.h152
-rw-r--r--drivers/usb/host/ehci-hcd.c6
-rw-r--r--drivers/usb/host/ehci-hub.c141
-rw-r--r--drivers/usb/host/ehci-q.c14
-rw-r--r--drivers/usb/host/pci-quirks.c20
-rw-r--r--drivers/usb/host/pci-quirks.h1
-rw-r--r--drivers/usb/host/xhci-dbg.c6
-rw-r--r--drivers/usb/host/xhci-hub.c10
-rw-r--r--drivers/usb/host/xhci-pci.c7
-rw-r--r--drivers/usb/host/xhci-plat.c31
-rw-r--r--drivers/usb/host/xhci-ring.c135
-rw-r--r--drivers/usb/host/xhci.c5
-rw-r--r--drivers/usb/host/xhci.h13
-rw-r--r--drivers/usb/misc/ehset.c25
-rw-r--r--drivers/usb/phy/Kconfig2
-rw-r--r--drivers/usb/phy/phy-mxs-usb.c627
-rw-r--r--drivers/usb/phy/phy.c14
-rw-r--r--drivers/usb/typec/typec.c48
-rw-r--r--drivers/video/Kconfig2
-rw-r--r--drivers/video/backlight/gpio_backlight.c16
-rw-r--r--drivers/video/backlight/pwm_bl.c19
-rw-r--r--drivers/video/fbdev/Kconfig26
-rw-r--r--drivers/video/fbdev/Makefile1
-rw-r--r--drivers/video/fbdev/core/fbcon.c2
-rw-r--r--drivers/video/fbdev/mxc/Kconfig146
-rw-r--r--drivers/video/fbdev/mxc/Makefile20
-rw-r--r--drivers/video/fbdev/mxc/adv7535.c376
-rw-r--r--drivers/video/fbdev/mxc/crtc.h57
-rw-r--r--drivers/video/fbdev/mxc/epdc_regs.h442
-rw-r--r--drivers/video/fbdev/mxc/epdc_v2_regs.h533
-rw-r--r--drivers/video/fbdev/mxc/hannstar_cabc.c82
-rw-r--r--drivers/video/fbdev/mxc/imx_dcss.c3556
-rw-r--r--drivers/video/fbdev/mxc/imx_dcss_table.h9761
-rw-r--r--drivers/video/fbdev/mxc/ldb.c910
-rw-r--r--drivers/video/fbdev/mxc/mipi_dsi.c1039
-rw-r--r--drivers/video/fbdev/mxc/mipi_dsi.h151
-rw-r--r--drivers/video/fbdev/mxc/mipi_dsi_northwest.c1555
-rw-r--r--drivers/video/fbdev/mxc/mipi_dsi_samsung.c952
-rw-r--r--drivers/video/fbdev/mxc/mxc_dcic.c593
-rw-r--r--drivers/video/fbdev/mxc/mxc_dispdrv.c148
-rw-r--r--drivers/video/fbdev/mxc/mxc_dispdrv.h52
-rw-r--r--drivers/video/fbdev/mxc/mxc_edid.c771
-rw-r--r--drivers/video/fbdev/mxc/mxc_epdc_fb.c5601
-rw-r--r--drivers/video/fbdev/mxc/mxc_epdc_v2_fb.c6879
-rw-r--r--drivers/video/fbdev/mxc/mxc_hdmi.c2983
-rw-r--r--drivers/video/fbdev/mxc/mxc_ipuv3_fb.c3673
-rw-r--r--drivers/video/fbdev/mxc/mxc_lcdif.c237
-rw-r--r--drivers/video/fbdev/mxc/mxcfb_hx8363_wvga.c220
-rw-r--r--drivers/video/fbdev/mxc/mxcfb_hx8369_wvga.c453
-rw-r--r--drivers/video/fbdev/mxc/mxcfb_otm8018b_wvga.c266
-rw-r--r--drivers/video/fbdev/mxc/mxcfb_rm68191_qhd.c264
-rw-r--r--drivers/video/fbdev/mxc/mxcfb_rm68200_wxga.c438
-rw-r--r--drivers/video/fbdev/mxc/mxsfb_sii902x.c563
-rw-r--r--drivers/video/fbdev/mxsfb.c1852
-rw-r--r--drivers/video/hdmi.c138
-rw-r--r--drivers/virtio/virtio_ring.c4
-rw-r--r--drivers/watchdog/Kconfig26
-rw-r--r--drivers/watchdog/Makefile2
-rw-r--r--drivers/watchdog/imx2_wdt.c11
-rw-r--r--drivers/watchdog/imx7ulp_wdt.c291
-rw-r--r--drivers/watchdog/imx8_wdt.c233
-rw-r--r--fs/block_dev.c4
-rw-r--r--fs/btrfs/check-integrity.c2
-rw-r--r--fs/direct-io.c2
-rw-r--r--fs/iomap.c2
-rw-r--r--fs/proc/task_mmu.c2
-rw-r--r--include/drm/bridge/nwl_dsi.h42
-rw-r--r--include/drm/bridge/sec_mipi_dsim.h112
-rw-r--r--include/drm/drmP.h4
-rw-r--r--include/drm/drm_auth.h21
-rw-r--r--include/drm/drm_connector.h51
-rw-r--r--include/drm/drm_crtc.h5
-rw-r--r--include/drm/drm_device.h9
-rw-r--r--include/drm/drm_dp_helper.h68
-rw-r--r--include/drm/drm_edid.h4
-rw-r--r--include/drm/drm_encoder.h3
-rw-r--r--include/drm/drm_framebuffer.h1
-rw-r--r--include/drm/drm_hdcp.h253
-rw-r--r--include/drm/drm_lease.h46
-rw-r--r--include/drm/drm_mode_config.h28
-rw-r--r--include/drm/drm_mode_object.h5
-rw-r--r--include/drm/drm_modeset_helper.h3
-rw-r--r--include/drm/drm_of.h13
-rw-r--r--include/drm/drm_plane.h6
-rw-r--r--include/drm/drm_property.h3
-rw-r--r--include/drm/drm_simple_kms_helper.h14
-rw-r--r--include/dt-bindings/clock/imx6qdl-clock.h11
-rw-r--r--include/dt-bindings/clock/imx6sl-clock.h3
-rw-r--r--include/dt-bindings/clock/imx6sll-clock.h206
-rw-r--r--include/dt-bindings/clock/imx6sx-clock.h8
-rw-r--r--include/dt-bindings/clock/imx7d-clock.h17
-rw-r--r--include/dt-bindings/clock/imx7ulp-clock.h169
-rw-r--r--include/dt-bindings/clock/imx8mm-clock.h473
-rw-r--r--include/dt-bindings/clock/imx8mq-clock.h410
-rw-r--r--include/dt-bindings/clock/imx8qm-clock.h866
-rw-r--r--include/dt-bindings/clock/imx8qxp-clock.h597
-rw-r--r--include/dt-bindings/input/input.h3
-rw-r--r--include/dt-bindings/pinctrl/pads-imx8qm.h1002
-rw-r--r--include/dt-bindings/pinctrl/pads-imx8qxp.h793
-rw-r--r--include/dt-bindings/pinctrl/pins-imx8mm.h638
-rw-r--r--include/dt-bindings/pinctrl/pins-imx8mq.h632
-rw-r--r--include/dt-bindings/soc/imx8_hsio.h31
-rw-r--r--include/dt-bindings/soc/imx8_pd.h219
-rw-r--r--include/dt-bindings/soc/imx_rsrc.h566
-rw-r--r--include/linux/backlight.h32
-rw-r--r--include/linux/blk_types.h9
-rw-r--r--include/linux/blkdev.h7
-rw-r--r--include/linux/busfreq-imx.h77
-rw-r--r--include/linux/can/platform/flexcan.h20
-rw-r--r--include/linux/can/rx-offload.h4
-rw-r--r--include/linux/clk-provider.h18
-rw-r--r--include/linux/cpufreq.h12
-rw-r--r--include/linux/device_cooling.h45
-rw-r--r--include/linux/dmaengine.h4
-rw-r--r--include/linux/elevator.h2
-rw-r--r--include/linux/genhd.h8
-rwxr-xr-xinclude/linux/hantrodec.h29
-rw-r--r--include/linux/hdmi.h20
-rwxr-xr-xinclude/linux/hx280enc.h31
-rw-r--r--include/linux/imx_gpc.h30
-rw-r--r--include/linux/imx_rpmsg.h46
-rw-r--r--include/linux/imx_sema4.h83
-rw-r--r--include/linux/ipu-v3-pre.h155
-rw-r--r--include/linux/ipu-v3-prg.h61
-rw-r--r--include/linux/ipu-v3.h770
-rw-r--r--include/linux/ipu.h38
-rw-r--r--include/linux/isl29023.h47
-rw-r--r--include/linux/mfd/bd71837.h413
-rw-r--r--include/linux/mfd/max17135.h220
-rw-r--r--include/linux/mfd/mxc-hdmi-core.h56
-rw-r--r--include/linux/mfd/pf1550.h250
-rw-r--r--include/linux/mfd/si476x-core.h2
-rw-r--r--include/linux/mfd/syscon/imx6q-iomuxc-gpr.h55
-rw-r--r--include/linux/mfd/syscon/imx7-iomuxc-gpr.h2
-rw-r--r--include/linux/mfd/syscon/imx8mq-iomuxc-gpr.h63
-rw-r--r--include/linux/mipi_csi2.h93
-rw-r--r--include/linux/mipi_dsi.h165
-rw-r--r--include/linux/mipi_dsi_northwest.h164
-rw-r--r--include/linux/mipi_dsi_samsung.h131
-rw-r--r--include/linux/mmc/host.h12
-rw-r--r--include/linux/mmc/pm.h1
-rw-r--r--include/linux/mmc/sdio.h4
-rw-r--r--include/linux/mmc/sdio_ids.h2
-rw-r--r--include/linux/mtd/cfi.h1
-rw-r--r--include/linux/mtd/map.h2
-rw-r--r--include/linux/mtd/spi-nor.h8
-rw-r--r--include/linux/mx8_mu.h48
-rw-r--r--include/linux/mxc_dcic.h126
-rw-r--r--include/linux/mxc_mlb.h55
-rw-r--r--include/linux/mxc_sim_interface.h124
-rw-r--r--include/linux/mxc_v4l2.h27
-rwxr-xr-xinclude/linux/mxc_vpu-malone.h49
-rw-r--r--include/linux/mxc_vpu.h118
-rw-r--r--include/linux/mxcfb.h46
-rw-r--r--include/linux/mxcfb_epdc.h45
-rw-r--r--include/linux/of.h6
-rw-r--r--include/linux/of_reserved_mem.h4
-rw-r--r--include/linux/pci-ecam.h1
-rw-r--r--include/linux/pci.h3
-rw-r--r--include/linux/phy.h1
-rw-r--r--include/linux/phy/phy-mixel-lvds-combo.h38
-rw-r--r--include/linux/phy/phy-mixel-lvds.h36
-rw-r--r--include/linux/phy/phy-mixel-mipi-dsi.h35
-rw-r--r--include/linux/platform_data/brcmfmac.h1
-rw-r--r--include/linux/platform_data/dma-imx-sdma.h5
-rw-r--r--include/linux/platform_data/dma-imx.h14
-rw-r--r--include/linux/platform_data/mmc-esdhc-imx.h3
-rw-r--r--include/linux/pm_domain.h10
-rw-r--r--include/linux/pmic_status.h82
-rw-r--r--include/linux/power/sabresd_battery.h65
-rw-r--r--include/linux/pwm_backlight.h1
-rw-r--r--include/linux/pxp_device.h68
-rw-r--r--include/linux/pxp_dma.h82
-rw-r--r--include/linux/regulator/consumer.h3
-rw-r--r--include/linux/regulator/fixed.h1
-rw-r--r--include/linux/rpmsg.h2
-rw-r--r--include/linux/tee_drv.h47
-rw-r--r--include/linux/usb.h1
-rw-r--r--include/linux/usb/chipidea.h13
-rw-r--r--include/linux/usb/hcd.h13
-rw-r--r--include/linux/usb/otg-fsm.h13
-rw-r--r--include/linux/usb/phy.h43
-rw-r--r--include/linux/usb/typec.h4
-rw-r--r--include/linux/wakelock.h67
-rw-r--r--include/media/v4l2-chip-ident.h355
-rw-r--r--include/media/v4l2-dev.h1
-rw-r--r--include/media/v4l2-device.h2
-rw-r--r--include/media/v4l2-ioctl.h2
-rw-r--r--include/media/v4l2-subdev.h2
-rw-r--r--include/net/cfg80211.h37
-rw-r--r--include/soc/imx/fsl_hvc.h15
-rw-r--r--include/soc/imx/fsl_sip.h68
-rw-r--r--include/soc/imx/gpc.h7
-rw-r--r--include/soc/imx/src.h6
-rw-r--r--include/soc/imx8/fsl_bitaccess.h129
-rw-r--r--include/soc/imx8/imx8qm/lpcg.h201
-rw-r--r--include/soc/imx8/imx8qxp/lpcg.h196
-rw-r--r--include/soc/imx8/sc/ipc.h71
-rw-r--r--include/soc/imx8/sc/scfw.h34
-rw-r--r--include/soc/imx8/sc/sci.h42
-rw-r--r--include/soc/imx8/sc/svc/irq/api.h173
-rw-r--r--include/soc/imx8/sc/svc/misc/api.h547
-rw-r--r--include/soc/imx8/sc/svc/pad/api.h571
-rw-r--r--include/soc/imx8/sc/svc/pm/api.h808
-rw-r--r--include/soc/imx8/sc/svc/rm/api.h803
-rw-r--r--include/soc/imx8/sc/svc/seco/api.h512
-rw-r--r--include/soc/imx8/sc/svc/timer/api.h364
-rw-r--r--include/soc/imx8/sc/types.h886
-rw-r--r--include/soc/imx8/soc.h33
-rw-r--r--include/sound/dmaengine_pcm.h13
-rw-r--r--include/sound/soc.h1
-rw-r--r--include/trace/events/cpufreq_interactive.h112
-rw-r--r--include/uapi/drm/drm.h5
-rw-r--r--include/uapi/drm/drm_fourcc.h48
-rw-r--r--include/uapi/drm/drm_mode.h98
-rw-r--r--include/uapi/drm/imx_drm.h89
-rw-r--r--include/uapi/linux/dma-buf.h5
-rwxr-xr-xinclude/uapi/linux/hantrodec.h93
-rwxr-xr-xinclude/uapi/linux/hx280enc.h79
-rw-r--r--include/uapi/linux/ipu.h293
-rw-r--r--include/uapi/linux/isl29023.h47
-rw-r--r--include/uapi/linux/media-bus-format.h6
-rw-r--r--include/uapi/linux/mxc_asrc.h171
-rw-r--r--include/uapi/linux/mxc_dcic.h47
-rw-r--r--include/uapi/linux/mxc_dsp.h152
-rw-r--r--include/uapi/linux/mxc_mlb.h55
-rw-r--r--include/uapi/linux/mxc_sim_interface.h124
-rw-r--r--include/uapi/linux/mxc_v4l2.h73
-rw-r--r--include/uapi/linux/mxcfb.h198
-rw-r--r--include/uapi/linux/pxp_device.h63
-rw-r--r--include/uapi/linux/pxp_dma.h346
-rw-r--r--include/uapi/linux/tee.h36
-rw-r--r--include/uapi/linux/usb/ch9.h2
-rw-r--r--include/uapi/linux/videodev2.h19
-rw-r--r--include/video/dpu.h847
-rw-r--r--include/video/imx-dcss.h190
-rw-r--r--include/video/imx-lcdif.h42
-rw-r--r--include/video/imx8-pc.h33
-rw-r--r--include/video/imx8-prefetch.h74
-rw-r--r--include/video/mxc_edid.h107
-rw-r--r--include/video/mxc_hdmi.h1015
-rw-r--r--include/video/viv-metadata.h116
-rw-r--r--include/xen/interface/io/i2cif.h95
-rw-r--r--kernel/sched/cpufreq_schedutil.c8
-rw-r--r--kernel/time/clockevents.c21
-rw-r--r--mm/page_io.c2
-rw-r--r--net/bluetooth/l2cap_sock.c5
-rw-r--r--net/wireless/chan.c3
-rw-r--r--net/wireless/db.txt1312
-rw-r--r--net/wireless/reg.c1
-rw-r--r--net/wireless/util.c51
-rw-r--r--sound/core/pcm_dmaengine.c13
-rw-r--r--sound/soc/codecs/Kconfig44
-rw-r--r--sound/soc/codecs/Makefile19
-rw-r--r--sound/soc/codecs/ak4458-i2c.c79
-rw-r--r--sound/soc/codecs/ak4458-spi.c61
-rw-r--r--sound/soc/codecs/ak4458.c1248
-rw-r--r--sound/soc/codecs/ak4458.h135
-rw-r--r--sound/soc/codecs/ak4497.c1094
-rw-r--r--sound/soc/codecs/ak4497.h90
-rw-r--r--sound/soc/codecs/ak5558.c844
-rw-r--r--sound/soc/codecs/ak5558.h55
-rw-r--r--sound/soc/codecs/cs42xx8.c198
-rw-r--r--sound/soc/codecs/fsl_mqs.c359
-rw-r--r--sound/soc/codecs/hdmi-codec.c54
-rw-r--r--sound/soc/codecs/rpmsg_ak4497.c1107
-rw-r--r--sound/soc/codecs/rpmsg_cs42xx8.c753
-rw-r--r--sound/soc/codecs/rpmsg_cs42xx8.h232
-rw-r--r--sound/soc/codecs/rpmsg_wm8960.c1542
-rw-r--r--sound/soc/codecs/si476x.c19
-rw-r--r--sound/soc/codecs/wm8524.c3
-rw-r--r--sound/soc/codecs/wm8960.c77
-rw-r--r--sound/soc/codecs/wm8962.c27
-rw-r--r--sound/soc/codecs/wm8994.c67
-rw-r--r--sound/soc/fsl/Kconfig273
-rw-r--r--sound/soc/fsl/Makefile64
-rw-r--r--sound/soc/fsl/fsl_acm.c55
-rw-r--r--sound/soc/fsl/fsl_acm.h93
-rw-r--r--sound/soc/fsl/fsl_amix.c684
-rw-r--r--sound/soc/fsl/fsl_amix.h102
-rw-r--r--sound/soc/fsl/fsl_asrc.c523
-rw-r--r--sound/soc/fsl/fsl_asrc.h117
-rw-r--r--sound/soc/fsl/fsl_asrc_dma.c146
-rw-r--r--sound/soc/fsl/fsl_asrc_m2m.c1065
-rw-r--r--sound/soc/fsl/fsl_dma_workaround.c254
-rw-r--r--sound/soc/fsl/fsl_dma_workaround.h102
-rw-r--r--sound/soc/fsl/fsl_dsd.h58
-rw-r--r--sound/soc/fsl/fsl_dsp.c1166
-rw-r--r--sound/soc/fsl/fsl_dsp.h141
-rw-r--r--sound/soc/fsl/fsl_dsp_cpu.c97
-rw-r--r--sound/soc/fsl/fsl_dsp_cpu.h16
-rw-r--r--sound/soc/fsl/fsl_dsp_library_load.c642
-rw-r--r--sound/soc/fsl/fsl_dsp_library_load.h92
-rw-r--r--sound/soc/fsl/fsl_dsp_platform.h21
-rw-r--r--sound/soc/fsl/fsl_dsp_platform_compress.c480
-rw-r--r--sound/soc/fsl/fsl_dsp_pool.c151
-rw-r--r--sound/soc/fsl/fsl_dsp_pool.h113
-rw-r--r--sound/soc/fsl/fsl_dsp_proxy.c859
-rw-r--r--sound/soc/fsl/fsl_dsp_proxy.h520
-rw-r--r--sound/soc/fsl/fsl_dsp_xaf_api.c490
-rw-r--r--sound/soc/fsl/fsl_dsp_xaf_api.h136
-rw-r--r--sound/soc/fsl/fsl_esai.c499
-rw-r--r--sound/soc/fsl/fsl_hdmi.c750
-rw-r--r--sound/soc/fsl/fsl_micfil.c2456
-rw-r--r--sound/soc/fsl/fsl_micfil.h317
-rw-r--r--sound/soc/fsl/fsl_rpmsg_i2s.c380
-rw-r--r--sound/soc/fsl/fsl_rpmsg_i2s.h448
-rw-r--r--sound/soc/fsl/fsl_sai.c1048
-rw-r--r--sound/soc/fsl/fsl_sai.h191
-rw-r--r--sound/soc/fsl/fsl_spdif.c726
-rw-r--r--sound/soc/fsl/fsl_spdif.h3
-rw-r--r--sound/soc/fsl/fsl_ssi.c109
-rw-r--r--sound/soc/fsl/hdmi_pcm.S246
-rw-r--r--sound/soc/fsl/imx-ak4458.c407
-rw-r--r--sound/soc/fsl/imx-ak4497.c265
-rw-r--r--sound/soc/fsl/imx-ak5558.c369
-rw-r--r--sound/soc/fsl/imx-amix.c329
-rw-r--r--sound/soc/fsl/imx-audmux.c56
-rw-r--r--sound/soc/fsl/imx-cdnhdmi.c549
-rw-r--r--sound/soc/fsl/imx-cs42888.c489
-rw-r--r--sound/soc/fsl/imx-dsp.c203
-rw-r--r--sound/soc/fsl/imx-hdmi-dma.c1169
-rw-r--r--sound/soc/fsl/imx-hdmi.c114
-rw-r--r--sound/soc/fsl/imx-hdmi.h106
-rw-r--r--sound/soc/fsl/imx-micfil.c173
-rw-r--r--sound/soc/fsl/imx-mqs.c277
-rw-r--r--sound/soc/fsl/imx-pcm-dma-v2.c301
-rw-r--r--sound/soc/fsl/imx-pcm-dma.c42
-rw-r--r--sound/soc/fsl/imx-pcm-rpmsg.c897
-rw-r--r--sound/soc/fsl/imx-pcm.h49
-rw-r--r--sound/soc/fsl/imx-pdm.c195
-rw-r--r--sound/soc/fsl/imx-rpmsg.c163
-rw-r--r--sound/soc/fsl/imx-si476x.c205
-rw-r--r--sound/soc/fsl/imx-sii902x.c276
-rw-r--r--sound/soc/fsl/imx-spdif.c31
-rw-r--r--sound/soc/fsl/imx-wm8524.c205
-rw-r--r--sound/soc/fsl/imx-wm8958.c576
-rw-r--r--sound/soc/fsl/imx-wm8960.c689
-rw-r--r--sound/soc/fsl/imx-wm8962.c656
-rw-r--r--sound/soc/fsl/imx-xtor.c318
-rw-r--r--sound/soc/soc-pcm.c47
1924 files changed, 722717 insertions, 9064 deletions
diff --git a/Documentation/admin-guide/pm/cpufreq.rst b/Documentation/admin-guide/pm/cpufreq.rst
index 47153e64dfb5..0bf4c126a8a0 100644
--- a/Documentation/admin-guide/pm/cpufreq.rst
+++ b/Documentation/admin-guide/pm/cpufreq.rst
@@ -587,6 +587,102 @@ This governor exposes the following tunables:
It effectively causes the frequency to go down ``sampling_down_factor``
times slower than it ramps up.
+``interactive``
+---------------
+
+The CPUfreq governor "interactive" is designed for latency-sensitive,
+interactive workloads. This governor sets the CPU speed depending on
+usage, similar to "ondemand" and "conservative" governors, but with a
+different set of configurable behaviors.
+
+The tunable values for this governor are:
+
+``above_hispeed_delay``
+ When speed is at or above hispeed_freq, wait for
+ this long before raising speed in response to continued high load.
+ The format is a single delay value, optionally followed by pairs of
+ CPU speeds and the delay to use at or above those speeds. Colons can
+ be used between the speeds and associated delays for readability. For
+ example:
+
+ 80000 1300000:200000 1500000:40000
+
+ uses delay 80000 uS until CPU speed 1.3 GHz, at which speed delay
+ 200000 uS is used until speed 1.5 GHz, at which speed (and above)
+ delay 40000 uS is used. If speeds are specified these must appear in
+ ascending order. Default is 20000 uS.
+
+``boost``
+ If non-zero, immediately boost speed of all CPUs to at least
+ hispeed_freq until zero is written to this attribute. If zero, allow
+ CPU speeds to drop below hispeed_freq according to load as usual.
+ Default is zero.
+
+``boostpulse``
+ On each write, immediately boost speed of all CPUs to
+ hispeed_freq for at least the period of time specified by
+ boostpulse_duration, after which speeds are allowed to drop below
+ hispeed_freq according to load as usual. Its a write-only file.
+
+``boostpulse_duration``
+ Length of time to hold CPU speed at hispeed_freq
+ on a write to boostpulse, before allowing speed to drop according to
+ load as usual. Default is 80000 uS.
+
+``go_hispeed_load``
+ The CPU load at which to ramp to hispeed_freq.
+ Default is 99%.
+
+``hispeed_freq``
+ An intermediate "high speed" at which to initially ramp
+ when CPU load hits the value specified in go_hispeed_load. If load
+ stays high for the amount of time specified in above_hispeed_delay,
+ then speed may be bumped higher. Default is the maximum speed allowed
+ by the policy at governor initialization time.
+
+``io_is_busy``
+ If set, the governor accounts IO time as CPU busy time.
+
+``min_sample_time``
+ The minimum amount of time to spend at the current
+ frequency before ramping down. Default is 80000 uS.
+
+``target_loads``
+ CPU load values used to adjust speed to influence the
+ current CPU load toward that value. In general, the lower the target
+ load, the more often the governor will raise CPU speeds to bring load
+ below the target. The format is a single target load, optionally
+ followed by pairs of CPU speeds and CPU loads to target at or above
+ those speeds. Colons can be used between the speeds and associated
+ target loads for readability. For example:
+
+ 85 1000000:90 1700000:99
+
+ targets CPU load 85% below speed 1GHz, 90% at or above 1GHz, until
+ 1.7GHz and above, at which load 99% is targeted. If speeds are
+ specified these must appear in ascending order. Higher target load
+ values are typically specified for higher speeds, that is, target load
+ values also usually appear in an ascending order. The default is
+ target load 90% for all speeds.
+
+``timer_rate``
+ Sample rate for reevaluating CPU load when the CPU is not
+ idle. A deferrable timer is used, such that the CPU will not be woken
+ from idle to service this timer until something else needs to run.
+ (The maximum time to allow deferring this timer when not running at
+ minimum speed is configurable via timer_slack.) Default is 20000 uS.
+
+``timer_slack``
+ Maximum additional time to defer handling the governor
+ sampling timer beyond timer_rate when running at speeds above the
+ minimum. For platforms that consume additional power at idle when
+ CPUs are running at speeds greater than minimum, this places an upper
+ bound on how long the timer will be deferred prior to re-evaluating
+ load and dropping speed. For example, if timer_rate is 20000uS and
+ timer_slack is 10000uS then timers will be deferred for up to 30msec
+ when not at lowest speed. A value of -1 means defer timers
+ indefinitely at all speeds. Default is 80000 uS.
+
Frequency Boost Support
=======================
diff --git a/Documentation/devicetree/bindings/arm/freescale/mxc_ion.txt b/Documentation/devicetree/bindings/arm/freescale/mxc_ion.txt
new file mode 100644
index 000000000000..cb3e96775284
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/freescale/mxc_ion.txt
@@ -0,0 +1,23 @@
+ION Memory Manager (ION)
+
+ION is a memory manager that allows for sharing of buffers between different
+processes and between user space and kernel space. ION manages different
+memory spaces by separating the memory spaces into "heaps".
+
+Required properties for Ion
+
+- compatible: "fsl,mxc-ion"
+
+
+All child nodes of a fsl,mxc-ion node are interpreted as Ion heap
+configurations.
+
+Required properties for Ion heaps
+
+- fsl,heap-id: The ID of the ION heap.
+
+Example:
+ imx_ion {
+ compatible = "fsl,mxc-ion";
+ fsl,heap-id = <0>;
+ };
diff --git a/Documentation/devicetree/bindings/ata/imx-sata.txt b/Documentation/devicetree/bindings/ata/imx-sata.txt
index fa511db18408..49c4135dd9f2 100644
--- a/Documentation/devicetree/bindings/ata/imx-sata.txt
+++ b/Documentation/devicetree/bindings/ata/imx-sata.txt
@@ -7,6 +7,7 @@ Required properties:
- compatible : should be one of the following:
- "fsl,imx53-ahci" for i.MX53 SATA controller
- "fsl,imx6q-ahci" for i.MX6Q SATA controller
+ - "fsl,imx8qm-ahci" for i.MX8QM SATA controller
- interrupts : interrupt mapping for SATA IRQ
- reg : registers mapping
- clocks : list of clock specifiers, must contain an entry for each
@@ -22,6 +23,9 @@ Optional properties:
for the list of legal values for these options.
- fsl,no-spread-spectrum : disable spread-spectrum clocking on the SATA
link.
+- fsl,phy-imp: PHY impedance ratio value refer to the differnt HW design.
+ Set it to 0x6c when 85OHM is used, keep it to default value 0x80 when
+ 100OHM is used.
Examples:
diff --git a/Documentation/devicetree/bindings/clock/imx7ulp-clock.txt b/Documentation/devicetree/bindings/clock/imx7ulp-clock.txt
new file mode 100644
index 000000000000..b2f4dac59d49
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/imx7ulp-clock.txt
@@ -0,0 +1,59 @@
+* Clock bindings for Freescale i.MX7ULP
+
+i.MX7ULP Clock functions are under joint control of the System
+Clock Generation (SCG) modules, Peripheral Clock Control (PCC)
+modules, and Core Mode Controller (CMC)1 blocks
+
+The clocking scheme provides clear separation between M4 domain
+and A7 domain. Except for a few clock sources shared between two
+domains, such as the System Oscillator clock, the Slow IRC (SIRC),
+and and the Fast IRC clock (FIRCLK), clock sources and clock
+management are separated and contained within each domain.
+
+M4 clock management consists of SCG0, PCC0, PCC1, and CMC0 modules.
+A7 clock management consists of SCG1, PCC2, PCC3, and CMC1 modules.
+
+Note: this binding doc is only for A7 clock domain.
+
+Required properties:
+
+- compatible: Should be "fsl,imx7ulp-scg0" or "fsl,imx7ulp-scg1".
+- reg : Should contain registers location and length.
+- #clock-cells: Should be <1>.
+- clocks: Should contain the fixed input clocks.
+- clock-name: Should contain the following clock names:"cm4_rosc",
+ "cm4_sosc", "cm4_sirc", "cm4_firc" for scg0.
+Or
+ Should contain the following clock names:"rsoc", "sosc",
+ "sirc", "firc", "upll", "mpll" for scg1.
+
+The clock consumer should specify the desired clock by having the clock
+ID in its "clocks" phandle cell.
+See include/dt-bindings/clock/imx7ulp-clock.h
+for the full list of i.MX7ULP clock IDs.
+
+Examples:
+
+#include <dt-bindings/clock/imx7ulp-clock.h>
+
+clks: scg1@403e0000 {
+ compatible = "fsl,imx7ulp-clock";
+ reg = <0x403e0000 0x10000>;
+ clocks = <&rsoc>, <&sosc>, <&sirc>,
+ <&firc>, <&upll>, <&mpll>;
+ clock-names = "rsoc", "sosc", "sirc",
+ "firc", "upll", "mpll";
+ #clock-cells = <1>;
+};
+
+usdhc1: usdhc@40380000 {
+ compatible = "fsl,imx7ulp-usdhc";
+ reg = <0x40380000 0x10000>;
+ interrupts = <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX7ULP_CLK_NIC1_BUS_DIV>,
+ <&clks IMX7ULP_CLK_NIC1_DIV>,
+ <&clks IMX7ULP_CLK_USDHC1>;
+ clock-names ="ipg", "ahb", "per";
+ bus-width = <4>;
+ status = "disabled";
+};
diff --git a/Documentation/devicetree/bindings/crypto/fsl-dcp.txt b/Documentation/devicetree/bindings/crypto/fsl-dcp.txt
index 76a0b4e80e83..9c2ef99e8ab3 100644
--- a/Documentation/devicetree/bindings/crypto/fsl-dcp.txt
+++ b/Documentation/devicetree/bindings/crypto/fsl-dcp.txt
@@ -10,7 +10,7 @@ Required properties:
Example:
dcp@80028000 {
- compatible = "fsl,imx28-dcp", "fsl,imx23-dcp";
+ compatible = "fsl,imx6sl-dcp", "fsl,imx28-dcp", "fsl,imx23-dcp";
reg = <0x80028000 0x2000>;
interrupts = <52 53>;
};
diff --git a/Documentation/devicetree/bindings/crypto/fsl-sec4.txt b/Documentation/devicetree/bindings/crypto/fsl-sec4.txt
index 7aef0eae58d4..e20d8b15ff04 100644
--- a/Documentation/devicetree/bindings/crypto/fsl-sec4.txt
+++ b/Documentation/devicetree/bindings/crypto/fsl-sec4.txt
@@ -54,7 +54,7 @@ PROPERTIES
- compatible
Usage: required
Value type: <string>
- Definition: Must include "fsl,sec-v4.0"
+ Definition: Must include "fsl,sec-v4.0" or "fsl,sec4.0"
- fsl,sec-era
Usage: optional
@@ -126,38 +126,84 @@ EXAMPLE
iMX6QDL/SX requires four clocks
- crypto@300000 {
- compatible = "fsl,sec-v4.0";
- fsl,sec-era = <2>;
- #address-cells = <1>;
- #size-cells = <1>;
- reg = <0x300000 0x10000>;
- ranges = <0 0x300000 0x10000>;
- interrupt-parent = <&mpic>;
- interrupts = <92 2>;
- clocks = <&clks IMX6QDL_CLK_CAAM_MEM>,
- <&clks IMX6QDL_CLK_CAAM_ACLK>,
- <&clks IMX6QDL_CLK_CAAM_IPG>,
- <&clks IMX6QDL_CLK_EIM_SLOW>;
- clock-names = "mem", "aclk", "ipg", "emi_slow";
- };
+ crypto@300000 {
+ compatible = "fsl,sec-v4.0";
+ fsl,sec-era = <2>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x300000 0x10000>;
+ ranges = <0 0x300000 0x10000>;
+ interrupt-parent = <&mpic>;
+ interrupts = <92 2>;
+ clocks = <&clks IMX6QDL_CLK_CAAM_MEM>,
+ <&clks IMX6QDL_CLK_CAAM_ACLK>,
+ <&clks IMX6QDL_CLK_CAAM_IPG>,
+ <&clks IMX6QDL_CLK_EIM_SLOW>;
+ clock-names = "mem", "aclk", "ipg", "emi_slow";
+ };
iMX6UL does only require three clocks
- crypto: caam@2140000 {
- compatible = "fsl,sec-v4.0";
- #address-cells = <1>;
- #size-cells = <1>;
- reg = <0x2140000 0x3c000>;
- ranges = <0 0x2140000 0x3c000>;
- interrupts = <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>;
+ crypto: caam@2140000 {
+ compatible = "fsl,sec-v4.0";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x2140000 0x3c000>;
+ ranges = <0 0x2140000 0x3c000>;
+ interrupts = <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&clks IMX6UL_CLK_CAAM_MEM>,
- <&clks IMX6UL_CLK_CAAM_ACLK>,
- <&clks IMX6UL_CLK_CAAM_IPG>;
- clock-names = "mem", "aclk", "ipg";
- };
+ clocks = <&clks IMX6UL_CLK_CAAM_MEM>,
+ <&clks IMX6UL_CLK_CAAM_ACLK>,
+ <&clks IMX6UL_CLK_CAAM_IPG>;
+ clock-names = "mem", "aclk", "ipg";
+ };
+
+=====================================================================
+SEC 4 Page 0
+
+Description
+
+ Most of CAAM's configuration registers are accessible in block0
+ of CAAM's register space. These registers are intended to be
+ accessed by specially privileged software (e.g. boot software,
+ hypervisor, secure operating system).
+
+PROPERTIES
+
+ - compatible
+ Usage: required
+ Value type: <string>
+ Definition: Must include "fsl,sec-v4.0-ctrl".
+
+ platform precision:
+ - "fsl,imx7d-caam"
+
+ - reg
+ Usage: required
+ Value type: <prop-encoded-array>
+ Definition: A standard property. Specifies the physical
+ address and length of the SEC4 configuration registers.
+
+ - secure-status
+ Usage: required
+ Value type: <string>
+ Definition: Must include "okay".
+
+ - status
+ Usage: required
+ Value type: <string>
+ Definition: Must include "disabled".
+
+EXAMPLE
+ sec_ctrl: ctrl@0 {
+ /* CAAM Page 0 only accessible */
+ /* by secure world */
+ compatible = "fsl,sec-v4.0-ctrl";
+ reg = <0x2100000 0x1000>;
+ secure-status = "okay";
+ status = "disabled";
+ };
=====================================================================
Job Ring (JR) Node
@@ -207,14 +253,33 @@ Job Ring (JR) Node
is being mapped.
EXAMPLE
- jr@1000 {
- compatible = "fsl,sec-v4.0-job-ring";
- reg = <0x1000 0x1000>;
- fsl,liodn = <0x081>;
- interrupt-parent = <&mpic>;
- interrupts = <88 2>;
- };
+ jr@1000 {
+ compatible = "fsl,sec-v4.0-job-ring";
+ reg = <0x1000 0x1000>;
+ fsl,liodn = <0x081>;
+ interrupt-parent = <&mpic>;
+ interrupts = <88 2>;
+ };
+
+=====================================================================
+Secure memory (SM) Node
+
+ - compatible
+ Usage: required
+ Value type: <string>
+ Definition: Must include "fsl,imx6q-caam-sm"
+
+ - reg
+ Usage: required
+ Value type: <prop-encoded-array>
+ Definition: Specifies a two SM parameters: an offset from
+ the parent physical address and the length the SM registers.
+EXAMPLE
+ caam_sm: caam-sm@00100000 {
+ compatible = "fsl,imx6q-caam-sm";
+ reg = <0x00100000 0x4000>;
+ };
=====================================================================
Run Time Integrity Check (RTIC) Node
@@ -262,13 +327,13 @@ Run Time Integrity Check (RTIC) Node
length.
EXAMPLE
- rtic@6000 {
- compatible = "fsl,sec-v4.0-rtic";
- #address-cells = <1>;
- #size-cells = <1>;
- reg = <0x6000 0x100>;
- ranges = <0x0 0x6100 0xe00>;
- };
+ rtic@6000 {
+ compatible = "fsl,sec-v4.0-rtic";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x6000 0x100>;
+ ranges = <0x0 0x6100 0xe00>;
+ };
=====================================================================
Run Time Integrity Check (RTIC) Memory Node
@@ -312,20 +377,19 @@ Run Time Integrity Check (RTIC) Memory Node
property is normally set by boot firmware.
EXAMPLE
- rtic-a@0 {
- compatible = "fsl,sec-v4.0-rtic-memory";
- reg = <0x00 0x20 0x100 0x80>;
- fsl,liodn = <0x03c>;
- fsl,rtic-region = <0x12345678 0x12345678 0x12345678>;
- };
+ rtic-a@0 {
+ compatible = "fsl,sec-v4.0-rtic-memory";
+ reg = <0x00 0x20 0x100 0x80>;
+ fsl,liodn = <0x03c>;
+ fsl,rtic-region = <0x12345678 0x12345678 0x12345678>;
+ };
=====================================================================
Secure Non-Volatile Storage (SNVS) Node
Node defines address range and the associated
interrupt for the SNVS function. This function
- monitors security state information & reports
- security violations. This also included rtc,
+ monitors security state information. This also included rtc,
system power off and ON/OFF key.
- compatible
@@ -378,13 +442,86 @@ Secure Non-Volatile Storage (SNVS) Node
is being mapped.
EXAMPLE
- sec_mon@314000 {
- compatible = "fsl,sec-v4.0-mon", "syscon";
- reg = <0x314000 0x1000>;
- ranges = <0 0x314000 0x1000>;
- interrupt-parent = <&mpic>;
- interrupts = <93 2>;
- };
+ sec_mon@314000 {
+ compatible = "fsl,sec-v4.0-mon", "syscon";
+ reg = <0x314000 0x1000>;
+ ranges = <0 0x314000 0x1000>;
+ interrupt-parent = <&mpic>;
+ interrupts = <93 2>;
+ };
+
+=====================================================================
+CAAM SNVS Node
+ Load the SECVIO node.
+
+ - compatible
+ Usage: required
+ Value type: <string>
+ Definition: Must include "fsl,imx6q-caam-snvs".
+
+ - reg
+ Usage: required
+ Value type: <prop-encoded-array>
+ Definition: A standard property. Specifies the physical
+ address and length of the SEC4 configuration
+ registers.
+
+=====================================================================
+Security Violation (SECVIO) Node
+ Reports security violations.
+
+ - compatible
+ Usage: required
+ Value type: <string>
+ Definition: Must include "fsl,imx7d-caam-secvio" or
+ "fsl,imx6q-caam-secvio".
+
+ - interrupts
+ Usage: required
+ Value type: <prop_encoded-array>
+ Definition: Specifies the interrupts generated by this
+ device. The value of the interrupts property
+ consists of one interrupt specifier. The format
+ of the specifier is defined by the binding document
+ describing the node's interrupt parent.
+
+ - jtag-tamper
+ Usage: optional-but-recommended
+ Value type: <string>
+ Definition:
+ Security tamper on the JTAG
+ Must include "enabled" to enable.
+
+ - watchdog-tamper
+ Usage: optional-but-recommended
+ Value type: <string>
+ Definition:
+ Security tamper on the watchdog
+ Must include "enabled" to enable.
+
+ - internal-boot-tamper
+ Usage: optional-but-recommended
+ Value type: <string>
+ Definition:
+ Security tamper on the internal boot
+ Must include "enabled" to enable.
+
+ - external-pin-tamper
+ Usage: optional-but-recommended
+ Value type: <string>
+ Definition:
+ Security tamper on the external pin
+ Must include "enabled" to enable.
+
+EXAMPLE
+ irq_sec_vio: caam_secvio {
+ compatible = "fsl,imx7d-caam-secvio", "fsl,imx6q-caam-secvio";
+ interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
+ jtag-tamper = "disabled";
+ watchdog-tamper = "enabled";
+ internal-boot-tamper = "enabled";
+ external-pin-tamper = "disabled";
+ };
=====================================================================
Secure Non-Volatile Storage (SNVS) Low Power (LP) RTC Node
@@ -400,28 +537,37 @@ Secure Non-Volatile Storage (SNVS) Low Power (LP) RTC Node
Usage: required
Value type: <prop_encoded-array>
Definition: Specifies the interrupts generated by this
- device. The value of the interrupts property
- consists of one interrupt specifier. The format
- of the specifier is defined by the binding document
- describing the node's interrupt parent.
+ device. The value of the interrupts property
+ consists of one interrupt specifier. The format
+ of the specifier is defined by the binding document
+ describing the node's interrupt parent.
- regmap
- Usage: required
- Value type: <phandle>
- Definition: this is phandle to the register map node.
+ Usage: required
+ Value type: <phandle>
+ Definition: this is phandle to the register map node.
- offset
- Usage: option
- value type: <u32>
- Definition: LP register offset. default it is 0x34.
+ Usage: option
+ value type: <u32>
+ Definition: LP register offset. default it is 0x34.
+
+ - clocks
+ Usage: optional
+ Value type: <prop-encoded-array>
+ Definition: A standard property. Specifies the source clock for
+ snvs register access. If i.MX clk driver defines the clock node,
+ it needs user to specify the clocks in device tree for all modules
+ with snvs LP/HP registers access. The modules involved snvs LP/HP
+ registers access are snvs-power key, snvs-rtc, and caam.
EXAMPLE
- sec_mon_rtc_lp@1 {
- compatible = "fsl,sec-v4.0-mon-rtc-lp";
- interrupts = <93 2>;
- regmap = <&snvs>;
- offset = <0x34>;
- };
+ sec_mon_rtc_lp@1 {
+ compatible = "fsl,sec-v4.0-mon-rtc-lp";
+ interrupts = <93 2>;
+ regmap = <&snvs>;
+ offset = <0x34>;
+ };
=====================================================================
System ON/OFF key driver
@@ -456,102 +602,116 @@ System ON/OFF key driver
Definition: this is phandle to the register map node.
EXAMPLE:
- snvs-pwrkey@0x020cc000 {
- compatible = "fsl,sec-v4.0-pwrkey";
- regmap = <&snvs>;
- interrupts = <0 4 0x4>
- linux,keycode = <116>; /* KEY_POWER */
- wakeup-source;
- };
+ snvs-pwrkey@0x020cc000 {
+ compatible = "fsl,sec-v4.0-pwrkey";
+ regmap = <&snvs>;
+ interrupts = <0 4 0x4>
+ linux,keycode = <116>; /* KEY_POWER */
+ wakeup-source;
+ };
=====================================================================
FULL EXAMPLE
- crypto: crypto@300000 {
- compatible = "fsl,sec-v4.0";
- #address-cells = <1>;
- #size-cells = <1>;
- reg = <0x300000 0x10000>;
- ranges = <0 0x300000 0x10000>;
- interrupt-parent = <&mpic>;
- interrupts = <92 2>;
-
- sec_jr0: jr@1000 {
- compatible = "fsl,sec-v4.0-job-ring";
- reg = <0x1000 0x1000>;
- interrupt-parent = <&mpic>;
- interrupts = <88 2>;
- };
-
- sec_jr1: jr@2000 {
- compatible = "fsl,sec-v4.0-job-ring";
- reg = <0x2000 0x1000>;
- interrupt-parent = <&mpic>;
- interrupts = <89 2>;
- };
-
- sec_jr2: jr@3000 {
- compatible = "fsl,sec-v4.0-job-ring";
- reg = <0x3000 0x1000>;
- interrupt-parent = <&mpic>;
- interrupts = <90 2>;
- };
-
- sec_jr3: jr@4000 {
- compatible = "fsl,sec-v4.0-job-ring";
- reg = <0x4000 0x1000>;
- interrupt-parent = <&mpic>;
- interrupts = <91 2>;
- };
-
- rtic@6000 {
- compatible = "fsl,sec-v4.0-rtic";
- #address-cells = <1>;
- #size-cells = <1>;
- reg = <0x6000 0x100>;
- ranges = <0x0 0x6100 0xe00>;
-
- rtic_a: rtic-a@0 {
- compatible = "fsl,sec-v4.0-rtic-memory";
- reg = <0x00 0x20 0x100 0x80>;
- };
-
- rtic_b: rtic-b@20 {
- compatible = "fsl,sec-v4.0-rtic-memory";
- reg = <0x20 0x20 0x200 0x80>;
- };
-
- rtic_c: rtic-c@40 {
- compatible = "fsl,sec-v4.0-rtic-memory";
- reg = <0x40 0x20 0x300 0x80>;
- };
-
- rtic_d: rtic-d@60 {
- compatible = "fsl,sec-v4.0-rtic-memory";
- reg = <0x60 0x20 0x500 0x80>;
- };
- };
- };
-
- sec_mon: sec_mon@314000 {
- compatible = "fsl,sec-v4.0-mon";
- reg = <0x314000 0x1000>;
- ranges = <0 0x314000 0x1000>;
-
- sec_mon_rtc_lp@34 {
- compatible = "fsl,sec-v4.0-mon-rtc-lp";
- regmap = <&sec_mon>;
- offset = <0x34>;
- interrupts = <93 2>;
- };
-
- snvs-pwrkey@0x020cc000 {
- compatible = "fsl,sec-v4.0-pwrkey";
- regmap = <&sec_mon>;
- interrupts = <0 4 0x4>;
- linux,keycode = <116>; /* KEY_POWER */
- wakeup-source;
- };
- };
+ crypto: crypto@300000 {
+ compatible = "fsl,sec-v4.0";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x300000 0x10000>;
+ ranges = <0 0x300000 0x10000>;
+ interrupt-parent = <&mpic>;
+ interrupts = <92 2>;
+
+ sec_jr0: jr@1000 {
+ compatible = "fsl,sec-v4.0-job-ring";
+ reg = <0x1000 0x1000>;
+ interrupt-parent = <&mpic>;
+ interrupts = <88 2>;
+ };
+
+ sec_jr1: jr@2000 {
+ compatible = "fsl,sec-v4.0-job-ring";
+ reg = <0x2000 0x1000>;
+ interrupt-parent = <&mpic>;
+ interrupts = <89 2>;
+ };
+
+ sec_jr2: jr@3000 {
+ compatible = "fsl,sec-v4.0-job-ring";
+ reg = <0x3000 0x1000>;
+ interrupt-parent = <&mpic>;
+ interrupts = <90 2>;
+ };
+
+ sec_jr3: jr@4000 {
+ compatible = "fsl,sec-v4.0-job-ring";
+ reg = <0x4000 0x1000>;
+ interrupt-parent = <&mpic>;
+ interrupts = <91 2>;
+ };
+
+ rtic@6000 {
+ compatible = "fsl,sec-v4.0-rtic";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x6000 0x100>;
+ ranges = <0x0 0x6100 0xe00>;
+
+ rtic_a: rtic-a@0 {
+ compatible = "fsl,sec-v4.0-rtic-memory";
+ reg = <0x00 0x20 0x100 0x80>;
+ };
+
+ rtic_b: rtic-b@20 {
+ compatible = "fsl,sec-v4.0-rtic-memory";
+ reg = <0x20 0x20 0x200 0x80>;
+ };
+
+ rtic_c: rtic-c@40 {
+ compatible = "fsl,sec-v4.0-rtic-memory";
+ reg = <0x40 0x20 0x300 0x80>;
+ };
+
+ rtic_d: rtic-d@60 {
+ compatible = "fsl,sec-v4.0-rtic-memory";
+ reg = <0x60 0x20 0x500 0x80>;
+ };
+ };
+ };
+
+ sec_mon: sec_mon@314000 {
+ compatible = "fsl,sec-v4.0-mon";
+ reg = <0x314000 0x1000>;
+ ranges = <0 0x314000 0x1000>;
+
+ sec_mon_rtc_lp@34 {
+ compatible = "fsl,sec-v4.0-mon-rtc-lp";
+ regmap = <&sec_mon>;
+ offset = <0x34>;
+ interrupts = <93 2>;
+ };
+
+ snvs-pwrkey@0x020cc000 {
+ compatible = "fsl,sec-v4.0-pwrkey";
+ regmap = <&sec_mon>;
+ interrupts = <0 4 0x4>;
+ linux,keycode = <116>; /* KEY_POWER */
+ wakeup-source;
+ };
+ };
+
+ caam_snvs: caam-snvs@30370000 {
+ compatible = "fsl,imx6q-caam-snvs";
+ reg = <0x30370000 0x10000>;
+ };
+
+ irq_sec_vio: caam_secvio {
+ compatible = "fsl,imx7d-caam-secvio", "fsl,imx6q-caam-secvio";
+ interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
+ jtag-tamper = "disabled";
+ watchdog-tamper = "enabled";
+ internal-boot-tamper = "enabled";
+ external-pin-tamper = "disabled";
+ };
=====================================================================
diff --git a/Documentation/devicetree/bindings/display/bridge/adi,adv7511.txt b/Documentation/devicetree/bindings/display/bridge/adi,adv7511.txt
index 06668bca7ffc..98d437d7e885 100644
--- a/Documentation/devicetree/bindings/display/bridge/adi,adv7511.txt
+++ b/Documentation/devicetree/bindings/display/bridge/adi,adv7511.txt
@@ -1,10 +1,10 @@
-Analog Device ADV7511(W)/13/33 HDMI Encoders
+Analog Device ADV7511(W)/13/33/35 HDMI Encoders
-----------------------------------------
-The ADV7511, ADV7511W, ADV7513 and ADV7533 are HDMI audio and video transmitters
-compatible with HDMI 1.4 and DVI 1.0. They support color space conversion,
-S/PDIF, CEC and HDCP. ADV7533 supports the DSI interface for input pixels, while
-the others support RGB interface.
+The ADV7511, ADV7511W, ADV7513, ADV7533 and ADV7535 are HDMI audio and video
+transmitters compatible with HDMI 1.4 and DVI 1.0. They support color space
+conversion, S/PDIF, CEC and HDCP. ADV7533 and ADV7535 support the DSI interface
+for input pixels, while the others support RGB interface.
Required properties:
@@ -13,6 +13,7 @@ Required properties:
"adi,adv7511w"
"adi,adv7513"
"adi,adv7533"
+ "adi,adv7535"
- reg: I2C slave address
@@ -46,7 +47,7 @@ The following input format properties are required except in "rgb 1x" and
- bgvdd-supply: A 1.8V supply that powers up the BGVDD pin. This is
needed only for ADV7511.
-The following properties are required for ADV7533:
+The following properties are required for ADV7533 and ADV7535:
- adi,dsi-lanes: Number of DSI data lanes connected to the DSI host. It should
be one of 1, 2, 3 or 4.
@@ -65,18 +66,26 @@ Optional properties:
- adi,embedded-sync: The input uses synchronization signals embedded in the
data stream (similar to BT.656). Defaults to separate H/V synchronization
signals.
-- adi,disable-timing-generator: Only for ADV7533. Disables the internal timing
- generator. The chip will rely on the sync signals in the DSI data lanes,
- rather than generate its own timings for HDMI output.
+- adi,disable-timing-generator: Only for ADV7533 and ADV7535. Disables the
+ internal timing generator. The chip will rely on the sync signals in the DSI
+ data lanes, rather than generate its own timings for HDMI output.
+- adi,dsi-channel: Only for ADV7533 and ADV7535. DSI channel number to be used
+ when communicating with the DSI peripheral. It should be one of 0, 1, 2 or 3.
+- adi,addr-cec: Only for ADV7533 and ADV7535. The I2C DSI-CEC register map
+ address to be programmed into the MAIN register map.
+- adi,addr-edid: Only for ADV7533 and ADV7535. The I2C EDID register map
+ to be programmed into the MAIN register map.
+- adi,addr-pkt: Only for ADV7533 and ADV7535. The I2C PACKET register map
+ to be programmed into the MAIN register map.
Required nodes:
The ADV7511 has two video ports. Their connections are modelled using the OF
graph bindings specified in Documentation/devicetree/bindings/graph.txt.
-- Video port 0 for the RGB, YUV or DSI input. In the case of ADV7533, the
- remote endpoint phandle should be a reference to a valid mipi_dsi_host device
- node.
+- Video port 0 for the RGB, YUV or DSI input. In the case of ADV7533 and
+ ADV7535, the remote endpoint phandle should be a reference to a valid
+ mipi_dsi_host device node.
- Video port 1 for the HDMI output
- Audio port 2 for the HDMI audio input
diff --git a/Documentation/devicetree/bindings/display/bridge/it6263.txt b/Documentation/devicetree/bindings/display/bridge/it6263.txt
new file mode 100644
index 000000000000..5bab1bd4dacc
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/bridge/it6263.txt
@@ -0,0 +1,29 @@
+ITE IT6263 LVDS to HDMI bridge bindings
+
+Required properties:
+ - compatible: "ite,it6263"
+ - reg: i2c address of the bridge
+ - video input: this subnode can contain a video input port node
+ to connect the bridge to a LVDS output interface (See this
+ documentation [1]).
+
+Optional properties:
+ - split-mode: boolean. if this exists, split mode is enabled,
+ otherwise, single mode is enabled.
+ - reset-gpios: OF device-tree gpio specification for SYSRSTN pin.
+
+[1]: Documentation/devicetree/bindings/media/video-interfaces.txt
+
+Example:
+ lvds-to-hdmi-bridge@4c {
+ compatible = "ite,it6263";
+ reg = <0x4c>;
+
+ port {
+ it6263_0_in: endpoint {
+ clock-lanes = <3>;
+ data-lanes = <0 1 2 4 5>;
+ remote-endpoint = <&lvds0_out>;
+ };
+ };
+ };
diff --git a/Documentation/devicetree/bindings/display/bridge/nwl_dsi.txt b/Documentation/devicetree/bindings/display/bridge/nwl_dsi.txt
new file mode 100644
index 000000000000..5d4242bae3f0
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/bridge/nwl_dsi.txt
@@ -0,0 +1,115 @@
+Northwest Logic MIPI-DSI bridge bindings
+
+The MIPI-DSI host controller drives the video signals from
+display controller to video peripherals using DSI protocol.
+This is an un-managed DSI bridge. In order to use this bridge, an encoder
+or bridge must be implemented to manage the platform specific initializations.
+
+Required properties:
+- compatible: "nwl,mipi-dsi"
+- reg: the register range of the MIPI-DSI controller
+- interrupts: the interrupt number for this module
+- clock, clock-names: phandles to the MIPI-DSI clocks
+ "phy_ref" - PHY_REF clock
+ "tx_esc" - TX_ESC clock (used in escape mode)
+ "rx_esc" - RX_ESC clock (used in escape mode)
+- assigned-clocks: phandles to clocks that requires initial configuration
+- assigned-clock-rates: rates of the clocks that requires initial configuration
+ The following clocks needs to have an initial configuration:
+ "tx_esc" and "rx_esc"
+- port: input and output port nodes with endpoint definitions as
+ defined in Documentation/devicetree/bindings/graph.txt;
+ the input port should be connected to an encoder or a
+ bridge that manages this MIPI-DSI host and the output
+ port should be connected to a panel or a bridge input
+ port
+- phys: phandle to the phy module representing the DPHY
+ inside MIPI-DSI IP block
+- phy-names: should be "dphy"
+
+
+Optional properties:
+- power-domains phandle to the power domain
+- interrupt-parent phandle to the interrupt parent, if there is one;
+ usually, on i.MX8qm and i.MX8qxp there is an irq
+ steer handling the MIPI DSI interrupts
+- assigned-clock-parents phandles to parent clocks that needs to be assigned as
+ parents to clocks defined in assigned-clocks
+
+* The clock assignments must follow the rules defined in:
+Documentation/devicetree/bindings/clock/clock-bindings.txt
+
+Example:
+ mipi_dsi_bridge1: mipi_dsi_bridge@56228000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "nwl,mipi-dsi";
+ reg = <0x0 0x56228000 0x0 0x300>;
+ interrupts = <16 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-parent = <&irqsteer_dsi0>;
+ clocks =
+ <&clk IMX8QM_CLK_DUMMY>,
+ <&clk IMX8QM_MIPI0_DSI_TX_ESC_CLK>,
+ <&clk IMX8QM_MIPI0_DSI_RX_ESC_CLK>;
+ clock-names = "phy_ref", "tx_esc", "rx_esc";
+ assigned-clocks = <&clk IMX8QM_MIPI0_DSI_TX_ESC_DIV>,
+ <&clk IMX8QM_MIPI0_DSI_RX_ESC_DIV>;
+ assigned-clock-rates = <18000000>, <72000000>;
+ power-domains = <&pd_mipi0>;
+ phys = <&mipi_dsi_phy1>;
+ phy-names = "dphy";
+
+ port@0 {
+ mipi_dsi_bridge1_in: endpoint {
+ remote-endpoint = <&mipi_dsi1_out>;
+ };
+ };
+
+ port@1 {
+ mipi_dsi0_out: endpoint {
+ remote-endpoint = <&adv7535_0_in>;
+ };
+ };
+ };
+
+Another example, for a platform with a complex clock tree, like 8QXP:
+ mipi_dsi_bridge1: mipi_dsi_bridge@56228000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "nwl,mipi-dsi";
+ reg = <0x0 0x56228000 0x0 0x300>;
+ interrupts = <16 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-parent = <&irqsteer_mipi_lvds0>;
+ clocks =
+ <&clk IMX8QXP_CLK_DUMMY>,
+ <&clk IMX8QXP_MIPI0_DSI_TX_ESC_CLK>,
+ <&clk IMX8QXP_MIPI0_DSI_RX_ESC_CLK>;
+ clock-names = "phy_ref", "tx_esc", "rx_esc";
+ assigned-clocks =
+ <&clk IMX8QXP_MIPI0_DSI_TX_ESC_SEL>,
+ <&clk IMX8QXP_MIPI0_DSI_RX_ESC_SEL>,
+ <&clk IMX8QXP_MIPI0_DSI_TX_ESC_CLK>,
+ <&clk IMX8QXP_MIPI0_DSI_RX_ESC_CLK>;
+ assigned-clock-rates = <0>, <0>, <18000000>, <72000000>;
+ assigned-clock-parents =
+ <&clk IMX8QXP_MIPI0_DSI_PLL_DIV2_CLK>,
+ <&clk IMX8QXP_MIPI0_DSI_PLL_DIV2_CLK>;
+ power-domains = <&pd_mipi_dsi0>;
+ phys = <&mipi_dsi_phy1>;
+ phy-names = "dphy";
+
+ port@0 {
+ mipi_dsi_bridge1_in: endpoint {
+ remote-endpoint = <&mipi_dsi1_out>;
+ };
+ };
+
+ port@1 {
+ mipi_dsi0_out: endpoint {
+ remote-endpoint = <&adv7535_0_in>;
+ };
+ };
+ };
+
+* Here, we set the clock parents for the *_SEL clocks (which are the sources of
+the *_CLK clocks) and also the clock rate of the *_CLK clocks.
diff --git a/Documentation/devicetree/bindings/display/bridge/nxp,seiko-43wvfig.txt b/Documentation/devicetree/bindings/display/bridge/nxp,seiko-43wvfig.txt
new file mode 100644
index 000000000000..9021e6ad9299
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/bridge/nxp,seiko-43wvfig.txt
@@ -0,0 +1,40 @@
+Legacy Freescale RA169Z20 adapter card for Seiko 43WVFIG panel, driver bindings
+
+This is an adapter card made for the 4.3", 800x480, LCD panel Seiko 43WVFIG.
+The LCD panel is a 24bit DPI bus, while the adapter card has two ports:
+18-bit and 24-bit data input. For the 18-bit data input, the adapter card
+is demuxing some of the data lines, in order to feed all of the 24 lines
+needed by the LCD.
+
+Required properties:
+- compatible: "nxp,seiko-43wvfig"
+- bus_mode: must be one of <18> or <24>, depending on the input port
+ used (18-bit or 24-bit)
+- port: input and output port nodes with endpoint definitions as
+ defined in Documentation/devicetree/bindings/graph.txt;
+ the input port should be connected to an lcd controller
+ while the output port should be connected to the Seiko
+ 43wvfig LCD panel
+
+Example:
+ seiko_adapter: seiko-adapter {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "nxp,seiko-43wvfig";
+ bus_mode = <18>;
+
+ port@0 {
+ reg = <0>;
+ adapter_in: endpoint {
+ remote-endpoint = <&lcdif_out>;
+ };
+ };
+ port@1 {
+ reg = <1>;
+ adapter_out: endpoint {
+ remote-endpoint = <&panel_in>;
+ };
+ };
+ };
+
+-
diff --git a/Documentation/devicetree/bindings/display/bridge/sec_dsim.txt b/Documentation/devicetree/bindings/display/bridge/sec_dsim.txt
new file mode 100644
index 000000000000..fd4246136d37
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/bridge/sec_dsim.txt
@@ -0,0 +1,60 @@
+Samsung MIPI DSIM bridge bindings
+
+The MIPI DSIM host controller drives the video signals from
+display controller to video peripherals using DSI protocol.
+This is an un-managed DSI bridge. In order to use this bridge,
+an encoder or bridge must be implemented to manage the platform
+specific initializations.
+
+Required properties:
+- compatible: "fsl,imx8mm-mipi-dsim"
+- reg: the register range of the MIPI DSIM controller
+- interrupts: the interrupt number for this module
+- clock, clock-names: phandles to the MIPI-DSI clocks described in
+ Documentation/devicetree/bindings/clock/clock-bindings.txt
+ "cfg" - DSIM access clock
+ "pll-ref" - DSIM PHY PLL reference clock
+- assigned-clocks: phandles to clocks that requires initial configuration
+- assigned-clock-rates: rates of the clocks that requires initial configuration
+- pref-clk: Assign DPHY PLL reference clock frequency. If not exists,
+ DSIM bridge driver will use the default lock frequency
+ which is 27MHz.
+- port: input and output port nodes with endpoint definitions as
+ defined in Documentation/devicetree/bindings/graph.txt;
+ the input port should be connected to an encoder or a
+ bridge that manages this MIPI DSIM host and the output
+ port should be connected to a panel or a bridge input
+ port
+
+Optional properties:
+-dsi-gpr: a phandle which provides the MIPI DSIM control and gpr registers
+
+example:
+ mipi_dsi: mipi_dsi@32E10000 {
+ compatible = "fsl,imx8mm-mipi-dsim";
+ reg = <0x0 0x32e10000 0x0 0x400>;
+ clocks = <&clk IMX8MM_CLK_DSI_CORE_DIV>,
+ <&clk IMX8MM_CLK_DSI_PHY_REF_DIV>;
+ clock-names = "cfg", "pll-ref";
+ assigned-clocks = <&clk IMX8MM_CLK_DSI_CORE_SRC>,
+ <&clk IMX8MM_CLK_DSI_PHY_REF_SRC>;
+ assigned-clock-parents = <&clk IMX8MM_SYS_PLL1_266M>,
+ <&clk IMX8MM_VIDEO_PLL1_OUT>;
+ assigned-clock-rates = <266000000>, <594000000>;
+ interrupts = <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>;
+ dsi-gpr = <&dispmix_gpr>;
+ status = "disabled";
+
+ port@0 {
+ dsim_from_lcdif: endpoint {
+ remote-endpoint = <&lcdif_to_dsim>;
+ };
+ };
+
+ port@1 {
+ dsim_to_adv7535: endpoint {
+ remote-endpoint = <&adv7535_from_dsim>;
+ };
+ };
+
+ };
diff --git a/Documentation/devicetree/bindings/display/imx/dsi_nwl.txt b/Documentation/devicetree/bindings/display/imx/dsi_nwl.txt
new file mode 100644
index 000000000000..f37ddfe45c6f
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/imx/dsi_nwl.txt
@@ -0,0 +1,78 @@
+NXP specific extensions to the Northwest Logic MIPI-DSI
+================================
+
+Platform specific extentions for the NWL MIPI-DSI host controller found in
+MX8 platforms. This is an encoder/bridge that manages the platform specific
+initializations required for the NWL MIPI-DSI host.
+
+Required properties:
+- compatible: "fsl,<chip>-mipi-dsi"
+ The following strings are expected:
+ "fsl,imx8qm-mipi-dsi"
+ "fsl,imx8qxp-mipi-dsi"
+- reg: the register range of the MIPI-DSI controller
+- interrupts: the interrupt number for this module
+- clock, clock-names: phandles to the MIPI-DSI clocks
+ The following clocks are expected on all platforms:
+ "phy_ref" - PHY_REF clock
+ "tx_esc" - TX_ESC clock (used in escape mode)
+ "rx_esc" - RX_ESC clock (used in escape mode)
+ The following clocks are expected on i.MX8qm and i.MX8qxp:
+ "bypass" - bypass clock
+ "pixel" - pixel clock (for the pixel link)
+- assigned-clocks: phandles to clocks that requires initial configuration
+- assigned-clock-rates: rates of the clocks that requires initial configuration
+ The following clocks needs to have an initial configuration:
+ "tx_esc" and "rx_esc"
+- port: input and output port nodes with endpoint definitions as
+ defined in Documentation/devicetree/bindings/graph.txt;
+ the input port should be connected to a display
+ interface and the output port should be connected to a
+ NWL MIPI-DSI host
+- phys: phandle to the phy module representing the DPHY
+ inside MIPI-DSI IP block
+- phy-names: should be "dphy"
+
+Optional properties:
+- power-domains phandle to the power domain
+- interrupt-parent phandle to the interrupt parent, if there is one;
+ usually, on i.MX8qm and i.MX8qxp there is an irq
+ steer handling the MIPI DSI interrupts
+- csr phandle to the CSR register set (required on i.MX8qm
+ and i.MX8qxp for the reset functions)
+- assigned-clock-parents phandles to parent clocks that needs to be assigned as
+ parents to clocks defined in assigned-clocks
+- sync-pol horizontal and vertical sync polarity of the input
+ signal; can be <0> for LOW (negative) or <1> for HIGH
+ (positive) polarity; default value is <0>, when this
+ property is ommited
+- pwr-delay delay used in enable, before enabling the clocks; this is
+ useful when the PLL needs some time to become stable;
+ this value represents milliseconds
+
+Example:
+ mipi_dsi1: mipi_dsi {
+ compatible = "fsl,imx8qxp-mipi-dsi";
+ clocks =
+ <&clk IMX8QXP_MIPI0_PIXEL_CLK>,
+ <&clk IMX8QXP_MIPI0_BYPASS_CLK>,
+ <&clk IMX8QXP_CLK_DUMMY>;
+ clock-names = "pixel", "bypass", "phy_ref";
+ power-domains = <&pd_mipi_dsi0>;
+ csr = <&mipi_dsi_csr1>;
+ phys = <&mipi_dsi_phy1>;
+ phy-names = "dphy";
+ status = "disabled";
+
+ port@0 {
+ mipi_dsi1_in: endpoint {
+ remote-endpoint = <&dpu_disp0_mipi_dsi>;
+ };
+ };
+
+ port@1 {
+ mipi_dsi1_out: endpoint {
+ remote-endpoint = <&mipi_dsi_bridge1_in>;
+ };
+ };
+ };
diff --git a/Documentation/devicetree/bindings/display/imx/fsl-imx-drm.txt b/Documentation/devicetree/bindings/display/imx/fsl-imx-drm.txt
index f79854783c2c..a7b35da0a100 100644
--- a/Documentation/devicetree/bindings/display/imx/fsl-imx-drm.txt
+++ b/Documentation/devicetree/bindings/display/imx/fsl-imx-drm.txt
@@ -108,6 +108,271 @@ prg@21cc000 {
<&clks IMX6QDL_CLK_PRG0_AXI>;
clock-names = "ipg", "axi";
fsl,pres = <&pre1>, <&pre2>, <&pre3>;
+
+Freescale i.MX DPU
+====================
+
+Required properties:
+- compatible: Should be "fsl,<chip>-dpu"
+- reg: should be register base and length as documented in the
+ datasheet
+- intsteer: phandle pointing to interrupt steer.
+- interrupts, interrupt-names: Should contain interrupts and names as
+ documented in the datasheet.
+- clocks, clock-names: phandles to the DPU clocks described in
+ Documentation/devicetree/bindings/clock/clock-bindings.txt
+ The following clocks are expected on i.MX8qm and i.MX8qxp:
+ "pll0" - PLL clock for display interface 0
+ "pll1" - PLL clock for display interface 1
+ "disp0" - pixel clock for display interface 0
+ "disp1" - pixel clock for display interface 1
+ The needed clock numbers for each are documented in
+ Documentation/devicetree/bindings/clock/imx8qm-clock.txt, and in
+ Documentation/devicetree/bindings/clock/imx8qxp-clock.txt.
+- power-domains: phandle pointing to power domain.
+- fsl,dpr-channels: phandles to the DPR channels attached to this DPU,
+ sorted by memory map addresses. Only valid for i.MX8qm and i.MX8qxp.
+- fsl,pixel-combiner: phandle to the pixel combiner unit attached to this DPU.
+Optional properties:
+- port@[0-1]: Port nodes with endpoint definitions as defined in
+ Documentation/devicetree/bindings/media/video-interfaces.txt.
+ ports 0 and 1 should correspond to display interface 0 and
+ display interface 1, respectively.
+
+example:
+
+dpu: dpu@56180000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx8qm-dpu";
+ reg = <0x0 0x56180000 0x0 0x40000>;
+ intsteer = <&dpu1_intsteer>;
+ interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 47 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "irq_common",
+ "irq_stream0a",
+ "irq_stream0b",
+ "irq_stream1a",
+ "irq_stream1b",
+ "irq_reserved0",
+ "irq_reserved1",
+ "irq_blit";
+ clocks = <&clk IMX8QM_DC0_PLL0_CLK>,
+ <&clk IMX8QM_DC0_PLL1_CLK>,
+ <&clk IMX8QM_DC0_DISP0_CLK>,
+ <&clk IMX8QM_DC0_DISP1_CLK>;
+ clock-names = "pll0", "pll1", "disp0", "disp1";
+ power-domains = <&pd_dc0>;
+ fsl,dpr-channels = <&dpr1_channel1>, <&dpr1_channel2>,
+ <&dpr1_channel3>, <&dpr2_channel1>,
+ <&dpr2_channel2>, <&dpr2_channel3>;
+ fsl,pixel-combiner = <&pixel_combiner1>;
+
+ dpu1_disp1: port@1 {
+ reg = <1>;
+
+ dpu1_disp1_lvds0: lvds0-endpoint {
+ remote-endpoint = <&ldb1_lvds0>;
+ };
+
+ dpu1_disp1_lvds1: lvds1-endpoint {
+ remote-endpoint = <&ldb1_lvds1>;
+ };
+ };
+};
+
+
+NXP i.MX Display Controller Subsystem (DCSS)
+=============================================
+
+Required properties:
+- compatible: Should be "nxp,<chip>-dcss"
+- reg: should be register base and length as documented in the
+ datasheet.
+- interrupts, interrupt-names: Should contain interrupts and names as
+ documented in the datasheet.
+- interrupt-parent: contains the phandle to IRQ Steer module.
+- clocks, clock-names: phandles to the DCSS clocks described in
+ Documentation/devicetree/bindings/clock/clock-bindings.txt
+- disp-dev: can take following values:
+ - hdmi_disp: DCSS output goes to HDMI
+ - mipi_disp: DCSS output goes to MIPI_DSI
+Optional properties:
+- port@[0-1]: Port nodes with endpoint definitions as defined in
+ Documentation/devicetree/bindings/media/video-interfaces.txt.
+ ports 0 and 1 should correspond to display interface 0 and
+ display interface 1, respectively.
+
+
+example:
+
+dcss_drm: dcss@0x32e00000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "nxp,imx8mq-dcss";
+ reg = <0x0 0x32e00000 0x0 0x30000>;
+ interrupts = <3 IRQ_TYPE_LEVEL_HIGH>, <4 IRQ_TYPE_LEVEL_HIGH>, <5 IRQ_TYPE_LEVEL_HIGH>,
+ <6 IRQ_TYPE_LEVEL_HIGH>, <8 IRQ_TYPE_EDGE_RISING>;
+ interrupt-names = "dpr_dc_ch0", "dpr_dc_ch1", "dpr_dc_ch2", "ctx_ld",
+ "dtg_prg1";
+ interrupt-parent = <&irqsteer_dcss>;
+ clocks = <&clk IMX8MQ_CLK_DISP_APB_ROOT>,
+ <&clk IMX8MQ_CLK_DISP_AXI_ROOT>,
+ <&clk IMX8MQ_CLK_DISP_RTRM_ROOT>,
+ <&clk IMX8MQ_CLK_DC_PIXEL_DIV>,
+ <&clk IMX8MQ_CLK_DISP_DTRC_DIV>;
+ clock-names = "apb", "axi", "rtrm", "pixel", "dtrc";
+ assigned-clocks = <&clk IMX8MQ_CLK_DISP_APB_SRC>,
+ <&clk IMX8MQ_CLK_DISP_AXI_SRC>,
+ <&clk IMX8MQ_CLK_DISP_RTRM_SRC>,
+ <&clk IMX8MQ_CLK_DC_PIXEL_SRC>,
+ <&clk IMX8MQ_CLK_DISP_DTRC_SRC>;
+ assigned-clock-parents = <&clk IMX8MQ_SYS1_PLL_800M>,
+ <&clk IMX8MQ_SYS1_PLL_800M>,
+ <&clk IMX8MQ_SYS1_PLL_800M>,
+ <&clk IMX8MQ_VIDEO_PLL1_OUT>,
+ <&clk IMX8MQ_CLK_25M>;
+ assigned-clock-rate = <800000000>, <800000000>, <800000000>, <594000000>, <25000000>;
+
+ disp-dev = "hdmi_disp";
+
+ status = "okay";
+
+ dcss_disp0: port@0 {
+ reg = <0>;
+
+ dcss_disp0_imx_stub: imx_stub_conenc {
+ remote-endpoint = <&imx_stub_conenc0>;
+ };
+ };
+};
+
+NXP i.MX eLCDIF (Enhanced LCD Interface)
+========================================
+Required properties:
+- compatible: should be "fsl,imx8mm-lcdif"
+- reg: should be register base and length as documented in the
+ datasheet.
+- interrupts, interrupt-names: Should contain interrupts and names as
+ documented in the datasheet.
+- interrupt-parent: contains the phandle to IRQ Steer module.
+- clocks, clock-names: phandles to the LCDIF clocks described in
+ Documentation/devicetree/bindings/clock/clock-bindings.txt
+- assigned-clocks, assigned-clock-parents, assigned-clock-rate: configure
+ LCDIF related clock sources, clock source parents and clock source rates.
+- lcdif-gpr: a phandle which provides the LCDIF control and gpr registers
+ configuration.
+Optional properties:
+- port@0: Port nodes with endpoint definitions as defined in
+ Documentation/devicetree/bindings/media/video-interfaces.txt.
+ ports 0 should correspond to display interface 0.
+
+example:
+ lcdif: lcdif@32E00000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx8mm-lcdif";
+ reg = <0x0 0x32e00000 0x0 0x10000>;
+ clocks = <&clk IMX8MM_CLK_LCDIF_PIXEL_DIV>,
+ <&clk IMX8MM_CLK_DISP_AXI_ROOT>,
+ <&clk IMX8MM_CLK_DISP_APB_ROOT>;
+ clock-names = "pix", "disp-axi", "disp-apb";
+ assigned-clocks = <&clk IMX8MM_CLK_LCDIF_PIXEL_SRC>,
+ <&clk IMX8MM_CLK_DISP_AXI_SRC>,
+ <&clk IMX8MM_CLK_DISP_APB_SRC>;
+ assigned-clock-parents = <&clk IMX8MM_VIDEO_PLL1_OUT>,
+ <&clk IMX8MM_SYS_PLL2_1000M>,
+ <&clk IMX8MM_SYS_PLL1_800M>;
+ assigned-clock-rate = <594000000>, <500000000>, <200000000>;
+ interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>;
+ lcdif-gpr = <&dispmix_gpr>;
+ status = "disabled";
+
+ lcdif_disp0: port@0 {
+ reg = <0>;
+
+ lcdif_to_dsim: endpoint {
+ remote-endpoint = <&dsim_from_lcdif>;
+ };
+ };
+ };
+
+Freescale i.MX8 PC (Pixel Combiner)
+=============================================
+Required properties:
+- compatible: should be "fsl,<chip>-pixel-combiner"
+- reg: should be register base and length as documented in the
+ datasheet
+- power-domains: phandle pointing to power domain
+
+example:
+
+pixel-combiner@56020000 {
+ compatible = "fsl,imx8qm-pixel-combiner";
+ reg = <0x0 0x56020000 0x0 0x10000>;
+ power-domains = <&pd_dc0>;
+};
+
+Freescale i.MX8 PRG (Prefetch Resolve Gasket)
+=============================================
+Required properties:
+- compatible: should be "fsl,<chip>-prg"
+- reg: should be register base and length as documented in the
+ datasheet
+- clocks: phandles to the PRG apb and rtram clocks, as described in
+ Documentation/devicetree/bindings/clock/clock-bindings.txt,
+ Documentation/devicetree/bindings/clock/imx8qm-clock.txt and
+ Documentation/devicetree/bindings/clock/imx8qxp-clock.txt
+- clock-names: should be "apb" and "rtram"
+- power-domains: phandle pointing to power domain
+
+example:
+
+prg@56040000 {
+ compatible = "fsl,imx8qm-prg";
+ reg = <0x0 0x56040000 0x0 0x10000>;
+ clocks = <&clk IMX8QM_DC0_PRG0_APB_CLK>,
+ <&clk IMX8QM_DC0_PRG0_RTRAM_CLK>;
+ clock-names = "apb", "rtram";
+ power-domains = <&pd_dc0>;
+};
+
+Freescale i.MX8 DPRC (Display Prefetch Resolve Channel)
+=======================================================
+Required properties:
+- compatible: should be "fsl,<chip>-dpr-channel"
+- reg: should be register base and length as documented in the
+ datasheet
+- fsl,sc-resource: SCU resource number as described in
+ Documentation/devicetree/bindings/soc/fsl/imx_rsrc.txt
+- fsl,prgs: phandles to the PRG unit(s) attached to this DPRC, the first one
+ is the primary PRG and the second one(if available) is the auxiliary PRG
+ which is used to fetch luma chunk of a YUV frame with 2 planars.
+- clocks: phandles to the DPRC apb, b and rtram clocks, as described in
+ Documentation/devicetree/bindings/clock/clock-bindings.txt,
+ Documentation/devicetree/bindings/clock/imx8qm-clock.txt and
+ Documentation/devicetree/bindings/clock/imx8qxp-clock.txt
+- clock-names: should be "apb", "b" and "rtram"
+- power-domains: phandle pointing to power domain
+
+example:
+
+dpr-channel@56100000 {
+ compatible = "fsl,imx8qm-dpr-channel";
+ reg = <0x0 0x56100000 0x0 0x10000>;
+ fsl,sc-resource = <SC_R_DC_0_VIDEO0>;
+ fsl,prgs = <&prg4>, <&prg5>;
+ clocks = <&clk IMX8QM_DC0_DPR1_APB_CLK>,
+ <&clk IMX8QM_DC0_DPR1_B_CLK>,
+ <&clk IMX8QM_DC0_RTRAM1_CLK>;
+ clock-names = "apb", "b", "rtram";
+ power-domains = <&pd_dc0>;
};
Parallel display support
diff --git a/Documentation/devicetree/bindings/display/imx/ldb.txt b/Documentation/devicetree/bindings/display/imx/ldb.txt
index 38c637fa39dd..e0c7a9775675 100644
--- a/Documentation/devicetree/bindings/display/imx/ldb.txt
+++ b/Documentation/devicetree/bindings/display/imx/ldb.txt
@@ -9,10 +9,16 @@ nodes describing each of the two LVDS encoder channels of the bridge.
Required properties:
- #address-cells : should be <1>
- #size-cells : should be <0>
- - compatible : should be "fsl,imx53-ldb" or "fsl,imx6q-ldb".
- Both LDB versions are similar, but i.MX6 has an additional
- multiplexer in the front to select any of the four IPU display
- interfaces as input for each LVDS channel.
+ - compatible : should be "fsl,imx53-ldb" or "fsl,imx6q-ldb" or
+ "fsl,imx8qm-ldb" or "fsl,imx8qxp-ldb".
+ All LDB versions are similar.
+ i.MX6q/dl has an additional multiplexer in the front to select
+ any of the two or four IPU display interfaces as input for each
+ LVDS channel.
+ i.MX8qm LDB supports 10bit RGB input and needs an additional
+ phy.
+ i.MX8qxp LDB only supports one LVDS encoder channel(either
+ channel0 or channel1).
- gpr : should be <&gpr> on i.MX53 and i.MX6q.
The phandle points to the iomuxc-gpr region containing the LVDS
control register.
@@ -29,17 +35,32 @@ Required properties:
On i.MX6q the following additional clocks are needed:
"di2_sel" - IPU2 DI0 mux
"di3_sel" - IPU2 DI1 mux
+ The following clocks are expected on i.MX8qm:
+ "pixel" - pixel clock
+ "bypass" - bypass clock
+ The following clocks are expected on i.MX8qxp:
+ "pixel" - pixel clock
+ "bypass" - bypass clock
+ "aux_pixel" - pixel clock of the auxiliary LDB
+ "aux_bypass" - bypass clock of the auxiliary LDB
The needed clock numbers for each are documented in
Documentation/devicetree/bindings/clock/imx5-clock.txt, and in
Documentation/devicetree/bindings/clock/imx6q-clock.txt.
+- power-domains : phandle pointing to power domain, only required by i.MX8qm and
+ i.MX8qxp.
Optional properties:
- - pinctrl-names : should be "default" on i.MX53, not used on i.MX6q
+ - pinctrl-names : should be "default" on i.MX53, not used on i.MX6q, i.MX8qm
+ and i.MX8qxp
- pinctrl-0 : a phandle pointing to LVDS pin settings on i.MX53,
- not used on i.MX6q
+ not used on i.MX6q, i.MX8qm and i.MX8qxp
- fsl,dual-channel : boolean. if it exists, only LVDS channel 0 should
be configured - one input will be distributed on both outputs in dual
- channel mode
+ channel mode(i.MX8qxp uses two LDBs to support this). Note that when
+ i.MX8qxp LDB works in dual channel mode, only the primary LDB node
+ should be active and the auxiliary LDB node should be disabled.
+ - aux-gpr : the phandle points to the auxiliary LVDS region containing
+ the LVDS control register(only required by i.MX8qxp)
LVDS Channel
============
@@ -57,9 +78,16 @@ Required properties:
(lvds-channel@[0,1], respectively).
On i.MX6, there should be four input ports (port@[0-3]) that correspond
to the four LVDS multiplexer inputs.
- A single output port (port@2 on i.MX5, port@4 on i.MX6) must be connected
- to a panel input port. Optionally, the output port can be left out if
- display-timings are used instead.
+ On i.MX8qm, the two channels of LDB connect to one display interface of DPU.
+ A single output port (port@2 on i.MX5, port@4 on i.MX6, port@1 on i.MX8qm
+ and i.MX8qxp) must be connected to a panel input port or a bridge input port.
+ Optionally, the output port can be left out if display-timings are used
+ instead.
+ - phys: the phandle for the LVDS PHY devices. Valid only on i.MX8qm and
+ i.MX8qxp. For i.MX8qxp, two PHYs should be provided for LVDS
+ channel0, one for primary LDB and the other for auxiliary LDB.
+ - phy-names: should be "ldb_phy" for i.MX8qm, and "ldb_phy", "aux_ldb_phy"
+ for i.MX8qxp. Valid only on i.MX8qm and i.MX8qxp.
Optional properties (required if display-timings are used):
- ddc-i2c-bus: phandle of an I2C controller used for DDC EDID probing
@@ -69,6 +97,7 @@ Optional properties (required if display-timings are used):
This describes how the color bits are laid out in the
serialized LVDS signal.
- fsl,data-width : should be <18> or <24>
+ Additionally, <30> for i.MX8qm.
example:
diff --git a/Documentation/devicetree/bindings/display/mxsfb.txt b/Documentation/devicetree/bindings/display/mxsfb.txt
index 472e1ea6c591..234481c5d52d 100644
--- a/Documentation/devicetree/bindings/display/mxsfb.txt
+++ b/Documentation/devicetree/bindings/display/mxsfb.txt
@@ -13,10 +13,18 @@ Required properties:
- clock-names: A list of clock names. For MXSFB it should contain:
- "pix" for the LCDIF block clock
- (MX6SX-only) "axi", "disp_axi" for the bus interface clock
+ - (MX8-only) "video_pll, "osc_25", "osc_27" for the VIDEO_PLL,
+ OSC_25M and OSC_27M clocks
Required sub-nodes:
- port: The connection to an encoder chip.
+Optional properties:
+- max-res: an array with a maximum of two integers, representing the
+ maximum supported resolution, in the form of
+ <maxX>, <maxY>; if one of the item is <0>, the default
+ driver-defined maximum resolution for that axis is used
+
Example:
lcdif1: display-controller@2220000 {
@@ -44,6 +52,12 @@ Required properties:
- interrupts: Should contain LCDIF interrupts
- display: phandle to display node (see below for details)
+Optional properties:
+- disp-dev: Display device driver name
+- disp-videomode: Display device video mode name; this is used if the panel
+ supports multiple video modes, in order to chose the right one (see below for
+ examples)
+
* display node
Required properties:
@@ -84,3 +98,46 @@ lcdif@80030000 {
};
};
};
+
+Examples - optional properties:
+
+Snippet from imx7d-sdb-mipi-dsi.dts:
+
+&lcdif {
+ disp-dev = "mipi_dsi_samsung";
+ disp-videomode = "TRUULY-WVGA-SYNC-LOW";
+};
+
+&mipi_dsi {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_mipi_dsi_reset>;
+ lcd_panel = "TRULY-WVGA-TFT3P5581E";
+ resets = <&mipi_dsi_reset>;
+ status = "okay";
+};
+
+In the above example, the panel supports 2 video modes (snippet from
+drivers/video/fbdev/mxc/mxcfb_hx8363_wvga.c):
+
+#define ACTIVE_HIGH_NAME "TRUULY-WVGA-SYNC-HIGH"
+#define ACTIVE_LOW_NAME "TRUULY-WVGA-SYNC-LOW"
+
+static struct fb_videomode truly_lcd_modedb[] = {
+ {
+ ACTIVE_HIGH_NAME, 50, 480, 854, 41042,
+ 40, 60,
+ 3, 3,
+ 8, 4,
+ 0x0,
+ FB_VMODE_NONINTERLACED,
+ 0,
+ }, {
+ ACTIVE_LOW_NAME, 50, 480, 854, 41042,
+ 40, 60,
+ 3, 3,
+ 8, 4,
+ FB_SYNC_OE_LOW_ACT,
+ FB_VMODE_NONINTERLACED,
+ 0,
+ },
+};
diff --git a/Documentation/devicetree/bindings/display/panel/jdi,tx26d202vm0bwa.txt b/Documentation/devicetree/bindings/display/panel/jdi,tx26d202vm0bwa.txt
new file mode 100644
index 000000000000..b245b4d68d0f
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/panel/jdi,tx26d202vm0bwa.txt
@@ -0,0 +1,9 @@
+Japan Display Inc. 10.1" WUXGA (1920x1200) TFT LCD panel
+
+The panel has dual LVDS channels.
+
+Required properties:
+- compatible: should be "jdi,tx26d202vm0bwa"
+
+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/display/panel/raydium,rm67191.txt b/Documentation/devicetree/bindings/display/panel/raydium,rm67191.txt
new file mode 100644
index 000000000000..efda9db05eec
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/panel/raydium,rm67191.txt
@@ -0,0 +1,61 @@
+Raydium RM67171 OLED LCD panel with MIPI-DSI protocol
+
+Required properties:
+- compatible: "raydium,rm67191"
+- reg: virtual channel for MIPI-DSI protocol
+ must be <0>
+- dsi-lanes: number of DSI lanes to be used
+ must be <3> or <4>
+- port: input port node with endpoint definition as
+ defined in Documentation/devicetree/bindings/graph.txt;
+ the input port should be connected to a MIPI-DSI device
+ driver
+
+Optional properties:
+- reset-gpio: a GPIO spec for the RST_B GPIO pin
+- display-timings: timings for the connected panel according to [1]
+- pinctrl-0 phandle to the pin settings for the reset pin
+- panel-width-mm: physical panel width [mm]
+- panel-height-mm: physical panel height [mm]
+- video-mode: Video data transfer mode
+ must be <0>, <1> or <2> as
+ follows:
+ <0>: Burst mode
+ <1>: Non-burst mode with sync event
+ <2>: Non-burst mode with sync pulse
+
+[1]: Documentation/devicetree/bindings/display/display-timing.txt
+
+Example:
+
+ panel@0 {
+ compatible = "raydium,rm67191";
+ reg = <0>;
+ pinctrl-0 = <&pinctrl_mipi_dsi_0_1_en>;
+ reset-gpio = <&gpio1 7 GPIO_ACTIVE_HIGH>;
+ dsi-lanes = <4>;
+ panel-width-mm = <68>;
+ panel-height-mm = <121>;
+ display-timings {
+ timing {
+ clock-frequency = <132000000>;
+ hactive = <1080>;
+ vactive = <1920>;
+ hback-porch = <11>;
+ hfront-porch = <4>;
+ vback-porch = <48>;
+ vfront-porch = <20>;
+ hsync-len = <5>;
+ vsync-len = <12>;
+ hsync-active = <0>;
+ vsync-active = <0>;
+ de-active = <0>;
+ pixelclk-active = <0>;
+ };
+ };
+ port {
+ panel1_in: endpoint {
+ remote-endpoint = <&mipi1_out>;
+ };
+ };
+ };
diff --git a/Documentation/devicetree/bindings/display/panel/seiko,43wvf1g.txt b/Documentation/devicetree/bindings/display/panel/seiko,43wvf1g.txt
new file mode 100644
index 000000000000..aae57ef36cdd
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/panel/seiko,43wvf1g.txt
@@ -0,0 +1,23 @@
+Seiko Instruments Inc. 4.3" WVGA (800 x RGB x 480) TFT with Touch-Panel
+
+Required properties:
+- compatible: should be "sii,43wvf1g".
+- "dvdd-supply": 3v3 digital regulator.
+- "avdd-supply": 5v analog regulator.
+
+Optional properties:
+- backlight: phandle for the backlight control.
+
+Example:
+
+ panel {
+ compatible = "sii,43wvf1g";
+ backlight = <&backlight_display>;
+ dvdd-supply = <&reg_lcd_3v3>;
+ avdd-supply = <&reg_lcd_5v>;
+ port {
+ panel_in: endpoint {
+ remote-endpoint = <&display_out>;
+ };
+ };
+ };
diff --git a/Documentation/devicetree/bindings/dma/fsl-edma-v3.txt b/Documentation/devicetree/bindings/dma/fsl-edma-v3.txt
new file mode 100644
index 000000000000..a8d05427f954
--- /dev/null
+++ b/Documentation/devicetree/bindings/dma/fsl-edma-v3.txt
@@ -0,0 +1,73 @@
+* Freescale enhanced Direct Memory Access(eDMA-v3) Controller
+
+ The eDMA-v3 controller is inherited from FSL eDMA, and firstly is intergrated
+ on Freescale i.MX8QM SOC chip. The eDMA channels have multiplex capability by
+ programmble memory-mapped registers. Specific DMA request source has fixed channel.
+
+* eDMA Controller
+Required properties:
+- compatible :
+ - "fsl,imx8qm-edma" for eDMA used similar to that on i.MX8QM SoC
+ - "fsl,imx8qm-adma" for audio eDMA used on i.MX8QM
+- reg : Specifies base physical address(s) and size of the eDMA channel registers.
+ Each eDMA channel has separated register's address and size.
+- interrupts : A list of interrupt-specifiers, each channel has one interrupt.
+- interrupt-names : Should contain below template:
+ "edmaX-chanX-Xx"
+ | | |---> receive/transmit, r or t
+ | |---> channel id, the max number is 32
+ |---> edma controller instance, 0, 1, 2,..etc
+
+- #dma-cells : Must be <3>.
+ The 1st cell specifies the channel ID.
+ The 2nd cell specifies the channel priority.
+ The 3rd cell specifies the channel attributes which include below:
+ BIT(0): transmit or receive:
+ 0: transmit, 1: receive.
+ BIT(1): local or remote access:
+ 0: local, 1: remote.
+ BIT(2): dualfifo case or not(only in Audio cyclic now):
+ 0: not dual fifo case, 1: dualfifo case.
+ See the SoC's reference manual for all the supported request sources.
+- dma-channels : Number of channels supported by the controller
+
+Examples:
+edma0: dma-controller@40018000 {
+ compatible = "fsl,imx8qm-edma";
+ reg = <0x0 0x5a2c0000 0x0 0x10000>, /* channel12 UART0 rx */
+ <0x0 0x5a2d0000 0x0 0x10000>, /* channel13 UART0 tx */
+ <0x0 0x5a2e0000 0x0 0x10000>, /* channel14 UART1 rx */
+ <0x0 0x5a2f0000 0x0 0x10000>; /* channel15 UART1 tx */
+ #dma-cells = <3>;
+ dma-channels = <4>;
+ interrupts = <GIC_SPI 434 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 435 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 436 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 437 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "edma0-chan12-rx", "edma0-chan13-tx",
+ "edma0-chan14-rx", "edma0-chan15-tx";
+ status = "okay";
+};
+
+* DMA clients
+DMA client drivers that uses the DMA function must use the format described
+in the dma.txt file, using a three-cell specifier for each channel: the 1st
+specifies the channel number, the 2nd specifies the priority, and the 3rd
+specifies the channel type is for transmit or receive: 0: transmit, 1: receive.
+
+Examples:
+lpuart1: serial@5a070000 {
+ compatible = "fsl,imx8qm-lpuart";
+ reg = <0x0 0x5a070000 0x0 0x1000>;
+ interrupts = <GIC_SPI 226 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-parent = <&gic>;
+ clocks = <&clk IMX8QM_UART1_CLK>;
+ clock-names = "ipg";
+ assigned-clock-names = <&clk IMX8QM_UART1_CLK>;
+ assigned-clock-rates = <80000000>;
+ power-domains = <&pd_dma_lpuart1>;
+ dma-names = "tx","rx";
+ dmas = <&edma0 15 0 0>,
+ <&edma0 14 0 1>;
+ status = "disabled";
+};
diff --git a/Documentation/devicetree/bindings/dma/fsl-edma.txt b/Documentation/devicetree/bindings/dma/fsl-edma.txt
index 97e213e07660..3960fdeb6a7e 100644
--- a/Documentation/devicetree/bindings/dma/fsl-edma.txt
+++ b/Documentation/devicetree/bindings/dma/fsl-edma.txt
@@ -9,6 +9,7 @@ group, DMAMUX0 or DMAMUX1, but not both.
Required properties:
- compatible :
- "fsl,vf610-edma" for eDMA used similar to that on Vybrid vf610 SoC
+ - "nxp,imx7ulp-edma" for eDMA used similar to that on NXP i.MX7ULP SoC
- reg : Specifies base physical address(s) and size of the eDMA registers.
The 1st region is eDMA control register's address and size.
The 2nd and the 3rd regions are programmable channel multiplexing
diff --git a/Documentation/devicetree/bindings/dma/fsl-imx-dma.txt b/Documentation/devicetree/bindings/dma/fsl-imx-dma.txt
index 7bd8847d6394..63010924d42a 100644
--- a/Documentation/devicetree/bindings/dma/fsl-imx-dma.txt
+++ b/Documentation/devicetree/bindings/dma/fsl-imx-dma.txt
@@ -46,3 +46,18 @@ Example:
dma-names = "rx-tx";
...
};
+
+* DMA capability limitation
+
+Specify the DMA capability limitations.
+For example, some SoCs only support up to 32bit DMA capability, although
+they are 64bit SoCs.
+
+- only-dma-mask32: 1 means that the SoCs only suppot up to 32bit DMA
+ capability.
+
+Example:
+ dma_cap: dma_cap {
+ compatible = "dma-capability";
+ only-dma-mask32 = <1>;
+ };
diff --git a/Documentation/devicetree/bindings/dma/fsl-imx-sdma.txt b/Documentation/devicetree/bindings/dma/fsl-imx-sdma.txt
index 3c9a57a8443b..80174b587df3 100644
--- a/Documentation/devicetree/bindings/dma/fsl-imx-sdma.txt
+++ b/Documentation/devicetree/bindings/dma/fsl-imx-sdma.txt
@@ -9,6 +9,7 @@ Required properties:
"fsl,imx53-sdma"
"fsl,imx6q-sdma"
"fsl,imx7d-sdma"
+ "fsl,imx8mq-sdma"
The -to variants should be preferred since they allow to determine the
correct ROM script addresses needed for the driver to work without additional
firmware.
@@ -50,8 +51,14 @@ The full ID of peripheral types can be found below.
22 SSI Dual FIFO (needs firmware ver >= 2)
23 Shared ASRC
24 SAI
+ 25 HDMI Audio
-The third cell specifies the transfer priority as below.
+The third cell specifies the transfer priority and software done
+as below.
+
+ Bit31: sw_done
+ Bit15~Bit8: selector
+ Bit7~Bit0: priority level
ID transfer priority
-------------------------
@@ -59,6 +66,9 @@ The third cell specifies the transfer priority as below.
1 Medium
2 Low
+For example: 0x80000000 means sw_done enabled for done0 sector and
+ High priority for PDM on i.mx8mm.
+
Optional properties:
- gpr : The phandle to the General Purpose Register (GPR) node.
@@ -67,6 +77,7 @@ Optional properties:
reg is the GPR register offset.
shift is the bit position inside the GPR register.
val is the value of the bit (0 or 1).
+- fsl,ratio-1-1: AHB/SDMA core clock ration 1:1, 2:1 without this.
Examples:
diff --git a/Documentation/devicetree/bindings/extcon/extcon-ptn5150.txt b/Documentation/devicetree/bindings/extcon/extcon-ptn5150.txt
new file mode 100644
index 000000000000..1865132a0441
--- /dev/null
+++ b/Documentation/devicetree/bindings/extcon/extcon-ptn5150.txt
@@ -0,0 +1,28 @@
+PTN5150 Extcon device
+
+NXP PTN5150 is an i2c interface Type-C application chip, it can detect
+CC flip, attach and detech, the user can get these events through
+i2c registers by GPIO interrupt.
+
+Required properties:
+- compatible: Should be "nxp,ptn5150"
+- connect-gpios: gpio interrupt for attach and detach events.
+- reg: i2c slave address
+
+Example:
+&i2c1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lpi2c1>;
+ status = "okay";
+
+ typec_ptn5150: typec@3d {
+ compatible = "nxp,ptn5150";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ptn5150>;
+ reg = <0x3d>;
+ connect-gpios = <&gpio1 7 GPIO_ACTIVE_HIGH>;
+ };
+};
diff --git a/Documentation/devicetree/bindings/fb/fsl_ipuv3_fb.txt b/Documentation/devicetree/bindings/fb/fsl_ipuv3_fb.txt
new file mode 100644
index 000000000000..b8d27ef108fe
--- /dev/null
+++ b/Documentation/devicetree/bindings/fb/fsl_ipuv3_fb.txt
@@ -0,0 +1,105 @@
+* FSL IPUv3 Display/FB
+
+The FSL IPUv3 is Image Processing Unit version 3, a part of video and graphics
+subsystem in an application processor. The goal of the IPU is to provide
+comprehensive support for the flow of data from an image sensor or/and to a
+display device.
+
+Two IPU units are on the imx6q SOC while only one IPU unit on the imx6dl SOC.
+Each IPU unit has two display interfaces.
+
+Required properties for IPU:
+- bypass_reset :Bypass reset to avoid display channel being.
+ stopped by probe since it may start to work in bootloader: 0 or 1.
+- compatible : should be "fsl,imx6q-ipu".
+- reg : the register address range.
+- interrupts : the error and sync interrupts request.
+- clocks : the clock sources that it depends on.
+- clock-names: the related clock names.
+- resets : IPU reset specifier. See reset.txt and fsl,imx-src.txt in
+ Documentation/devicetree/bindings/reset/ for details.
+
+Required properties for fb:
+- compatible : should be "fsl,mxc_sdc_fb".
+- disp_dev : display device: "ldb", "lcd", "hdmi", "mipi_dsi".
+- mode_str : "CLAA-WVGA" for lcd, "TRULY-WVGA" for TRULY mipi_dsi lcd panel,
+ "1920x1080M@60" for hdmi.
+- default_bpp : default bits per pixel: 8/16/24/32
+- int_clk : use internal clock as pixel clock: 0 or 1
+- late_init : to avoid display channel being re-initialized
+ as we've probably setup the channel in bootloader: 0 or 1
+- interface_pix_fmt : display interface pixel format as below:
+ RGB666 IPU_PIX_FMT_RGB666
+ RGB565 IPU_PIX_FMT_RGB565
+ RGB24 IPU_PIX_FMT_RGB24
+ BGR24 IPU_PIX_FMT_BGR24
+ GBR24 IPU_PIX_FMT_GBR24
+ YUV444 IPU_PIX_FMT_YUV444
+ YUYV IPU_PIX_FMT_YUYV
+ UYVY IPU_PIX_FMT_UYVY
+ YVYV IPU_PIX_FMT_YVYU
+ VYUY IPU_PIX_FMT_VYUY
+
+Required properties for display:
+- compatible : should be "fsl,lcd" for lcd panel
+- reg : the register address range if necessary to have.
+- interrupts : the error and sync interrupts if necessary to have.
+- clocks : the clock sources that it depends on if necessary to have.
+- clock-names: the related clock names if necessary to have.
+- ipu_id : ipu id for the first display device: 0 or 1
+- disp_id : display interface id for the first display interface: 0 or 1
+- default_ifmt : save as above display interface pixel format for lcd
+- pinctrl-names : should be "default"
+- pinctrl-0 : should be pinctrl_ipu1_1 or pinctrl_ipu2_1, which depends on the
+ IPU connected.
+- gpr : the mux controller for the display engine's display interfaces and the display encoder
+ (only valid for mipi dsi now).
+- disp-power-on-supply : the regulator to control display panel's power.
+ (only valid for mipi dsi now).
+- resets : the gpio pin to reset the display device(only valid for mipi display panel now).
+- lcd_panel : the video mode name for the display device(only valid for mipi display panel now).
+- dev_id : the display engine's identity within the system, which intends to replace ipu_id
+ (only valid for mipi dsi now).
+
+Example for IPU:
+ ipu1: ipu@02400000 {
+ compatible = "fsl,imx6q-ipu";
+ reg = <0x02400000 0x400000>;
+ interrupts = <0 6 0x4 0 5 0x4>;
+ clocks = <&clks 130>, <&clks 131>, <&clks 132>,
+ <&clks 39>, <&clks 40>,
+ <&clks 135>, <&clks 136>;
+ clock-names = "bus", "di0", "di1",
+ "di0_sel", "di1_sel",
+ "ldb_di0", "ldb_di1";
+ resets = <&src 2>;
+ bypass_reset = <0>;
+ };
+
+Example for fb:
+ fb0 {
+ compatible = "fsl,mxc_sdc_fb";
+ disp_dev = "ldb";
+ interface_pix_fmt = "RGB666";
+ mode_str ="LDB-XGA";
+ default_bpp = <16>;
+ int_clk = <0>;
+ late_init = <0>;
+ status = "okay";
+ };
+
+Example for mipi dsi display:
+ mipi_dsi: mipi@021e0000 {
+ compatible = "fsl,imx6q-mipi-dsi";
+ reg = <0x021e0000 0x4000>;
+ interrupts = <0 102 0x04>;
+ gpr = <&gpr>;
+ clocks = <&clks 138>, <&clks 204>;
+ clock-names = "mipi_pllref_clk", "mipi_cfg_clk";
+ dev_id = <0>;
+ disp_id = <0>;
+ lcd_panel = "TRULY-WVGA";
+ disp-power-on-supply = <&reg_mipi_dsi_pwr_on>
+ resets = <&mipi_dsi_reset>;
+ status = "okay";
+ };
diff --git a/Documentation/devicetree/bindings/gpio/gpio-imx-rpmsg.txt b/Documentation/devicetree/bindings/gpio/gpio-imx-rpmsg.txt
new file mode 100644
index 000000000000..25001da92da5
--- /dev/null
+++ b/Documentation/devicetree/bindings/gpio/gpio-imx-rpmsg.txt
@@ -0,0 +1,57 @@
+Device-Tree bindings for drivers/gpio/gpio-imx-rpmsg.c gpio driver over
+rpmsg. On i.mx7ULP PTA PTB are connected on M4 side, so rpmsg gpio driver
+needed to get/set gpio status from M4 side by rpmsg.
+
+Required properties:
+- compatible : Should be "fsl,imx-rpmsg-gpio".
+- port_idx : Specify the GPIO PORT index, PTA:0, PTB:1.
+- gpio-controller : Mark the device node as a gpio controller.
+- #gpio-cells : Should be two. The first cell is the pin number and
+ the second cell is used to specify the gpio polarity:
+ 0 = active high
+ 1 = active low
+- interrupt-controller: Marks the device node as an interrupt controller.
+- #interrupt-cells : Should be 2. The first cell is the GPIO number.
+ The second cell bits[3:0] is used to specify trigger type and level flags:
+ 1 = low-to-high edge triggered.
+ 2 = high-to-low edge triggered.
+ 4 = active high level-sensitive.
+ 8 = active low level-sensitive.
+
+Note: Each GPIO port should have an alias correctly numbered in "aliases"
+node.
+
+Examples:
+
+aliases {
+ gpio4 = &rpmsg_gpio0;
+ gpio5 = &rpmsg_gpio1;
+};
+
+rpmsg_gpio0: rpmsg-gpio0 {
+ compatible = "fsl,imx-rpmsg-gpio";
+ port_idx = <0>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ interrupt-parent = <&rpmsg_gpio0>;
+ status = "okay";
+};
+
+rpmsg_gpio1: rpmsg-gpio1 {
+ compatible = "fsl,imx-rpmsg-gpio";
+ port_idx = <1>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ interrupt-parent = <&rpmsg_gpio1>;
+ status = "okay";
+};
+
+&skeleton_node {
+ interrupt-parent = <&rpmsg_gpio1>;
+ interrupts = <7 2>;
+ wakeup-gpios = <&rpmsg_gpio1 7 GPIO_ACTIVE_LOW>;
+};
diff --git a/Documentation/devicetree/bindings/gpio/gpio-max732x.txt b/Documentation/devicetree/bindings/gpio/gpio-max732x.txt
index 5fdc843b4542..c79dcaa0b89e 100644
--- a/Documentation/devicetree/bindings/gpio/gpio-max732x.txt
+++ b/Documentation/devicetree/bindings/gpio/gpio-max732x.txt
@@ -32,6 +32,7 @@ Optional properties:
- second cell is used to specify flags
- interrupt-parent: phandle of the parent interrupt controller.
- interrupts: Interrupt specifier for the controllers interrupt.
+ - out-default: set the output IO default voltage. Exp: out-default = /bits/ 16 <mask val>;
Please refer to gpio.txt in this directory for details of the common GPIO
bindings used by client devices.
diff --git a/Documentation/devicetree/bindings/gpio/gpio-vf610.txt b/Documentation/devicetree/bindings/gpio/gpio-vf610.txt
index 0ccbae44019c..42130d9a2ef2 100644
--- a/Documentation/devicetree/bindings/gpio/gpio-vf610.txt
+++ b/Documentation/devicetree/bindings/gpio/gpio-vf610.txt
@@ -27,6 +27,12 @@ Required properties for GPIO node:
Note: Each GPIO port should have an alias correctly numbered in "aliases"
node.
+Optional properties:
+- clocks : phandle + clock specifier pairs, one for each entry in
+ clock-names.
+- clock-names : should contain: "port" - the Port module clock and
+ "gpio" - the GPIO module clock.
+
Examples:
aliases {
diff --git a/Documentation/devicetree/bindings/i2c/i2c-imx-lpi2c.txt b/Documentation/devicetree/bindings/i2c/i2c-imx-lpi2c.txt
index 70c054a9a997..8aa0ccba8936 100644
--- a/Documentation/devicetree/bindings/i2c/i2c-imx-lpi2c.txt
+++ b/Documentation/devicetree/bindings/i2c/i2c-imx-lpi2c.txt
@@ -3,7 +3,7 @@
Required properties:
- compatible :
- "fsl,imx7ulp-lpi2c" for LPI2C compatible with the one integrated on i.MX7ULP soc
- - "fsl,imx8dv-lpi2c" for LPI2C compatible with the one integrated on i.MX8DV soc
+ - "fsl,imx8qm-lpi2c" for LPI2C compatible with the one integrated on i.MX8QM soc
- reg : address and length of the lpi2c master registers
- interrupt-parent : core interrupt controller
- interrupts : lpi2c interrupt
@@ -12,7 +12,7 @@ Required properties:
Examples:
lpi2c7: lpi2c7@40A50000 {
- compatible = "fsl,imx8dv-lpi2c";
+ compatible = "fsl,imx8qm-lpi2c";
reg = <0x40A50000 0x10000>;
interrupt-parent = <&intc>;
interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
diff --git a/Documentation/devicetree/bindings/i2c/i2c-mux-pca954x.txt b/Documentation/devicetree/bindings/i2c/i2c-mux-pca954x.txt
index aa097045a10e..198161da5aa2 100644
--- a/Documentation/devicetree/bindings/i2c/i2c-mux-pca954x.txt
+++ b/Documentation/devicetree/bindings/i2c/i2c-mux-pca954x.txt
@@ -4,7 +4,8 @@ Required Properties:
- compatible: Must contain one of the following.
"nxp,pca9540", "nxp,pca9542", "nxp,pca9543", "nxp,pca9544",
- "nxp,pca9545", "nxp,pca9546", "nxp,pca9547", "nxp,pca9548"
+ "nxp,pca9545", "nxp,pca9546", "nxp,pca9547", "nxp,pca9548",
+ "nxp,pca9646"
- reg: The I2C address of the device.
diff --git a/Documentation/devicetree/bindings/i2c/i2c-rpmsg-imx.txt b/Documentation/devicetree/bindings/i2c/i2c-rpmsg-imx.txt
new file mode 100644
index 000000000000..fce660d0f179
--- /dev/null
+++ b/Documentation/devicetree/bindings/i2c/i2c-rpmsg-imx.txt
@@ -0,0 +1,29 @@
+* Freescale Virtual I2C RPMSG bus driver for i.MX
+
+Required properties:
+- compatible :
+ - "fsl,i2c-rpbus" for I2C bus over RPMSG compatible on i.MX8QXP/QM soc
+The i2c-rpbus node should define its bus id (which is the node communicating
+with M4) in alias.
+
+Examples:
+
+aliases {
+ ...
+ i2c1 = &i2c_rpbus_1;
+ ...
+};
+
+&i2c_rpbus_1 {
+ compatible = "fsl,i2c-rpbus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "okay";
+
+ devs_in_this_i2c_bus__for_example: pca6416@20 {
+ compatible = "ti,tca6416";
+ reg = <0x20>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+};
diff --git a/Documentation/devicetree/bindings/i2c/i2c-xen.txt b/Documentation/devicetree/bindings/i2c/i2c-xen.txt
new file mode 100644
index 000000000000..26864a15c1b5
--- /dev/null
+++ b/Documentation/devicetree/bindings/i2c/i2c-xen.txt
@@ -0,0 +1,14 @@
+* XEN frontend i2c controller
+
+Required properties:
+- compatible :
+ - "xen,i2c" for xen i2c frontend
+- be-adapter : the backend i2c adapter name
+
+Examples:
+
+xen_i2c0: xen_i2c@0 {
+ compatible = "xen,i2c";
+ be-adapter = "5a800000.i2c";
+ status = "okay";
+};
diff --git a/Documentation/devicetree/bindings/input/imx-rpmsg-input.txt b/Documentation/devicetree/bindings/input/imx-rpmsg-input.txt
new file mode 100644
index 000000000000..397d1957e6fd
--- /dev/null
+++ b/Documentation/devicetree/bindings/input/imx-rpmsg-input.txt
@@ -0,0 +1,12 @@
+Device-Tree bindings for inputc/rpmsg_input.c input driver over
+rpmsg. For NXP i.MX7ULP EVK platform, all sensors connect with
+M4, A core access sensor should communicate with M4 core by rpmsg
+bus.
+
+Required properties:
+ - compatible = "fsl,rpmsg-input";
+
+Examples:
+ rpmsg_sensor: rpmsg-sensor {
+ compatible = "fsl,rpmsg-input";
+ };
diff --git a/Documentation/devicetree/bindings/input/imx-sc-pwrkey.txt b/Documentation/devicetree/bindings/input/imx-sc-pwrkey.txt
new file mode 100644
index 000000000000..1084baa48d4f
--- /dev/null
+++ b/Documentation/devicetree/bindings/input/imx-sc-pwrkey.txt
@@ -0,0 +1,22 @@
+Device-Tree bindings for input/keyboard/imx_sc_pwrkey.c poweron/off driver
+over SCU. On i.mx8QM/QXP poweron/off key is connected on SCU side, so need
+to get key event by MU.
+
+Required properties:
+ - compatible = "fsl,imx8-pwrkey";
+
+Each button/key looked as the sub node:
+Required properties:
+ - linux,code: the key value defined in
+ include/dt-bindings/input/input.h
+Optional property:
+ - wakeup-source: wakeup feature, the keys can wakeup from
+ suspend if the keys with this property pressed.
+
+Example nodes:
+ sc_pwrkey: sc-powerkey {
+ compatible = "fsl,imx8-pwrkey";
+ linux,keycode = <KEY_POWER>;
+ wakeup-source;
+ };
+
diff --git a/Documentation/devicetree/bindings/input/rpmsg-keys.txt b/Documentation/devicetree/bindings/input/rpmsg-keys.txt
new file mode 100644
index 000000000000..d9279802cc9c
--- /dev/null
+++ b/Documentation/devicetree/bindings/input/rpmsg-keys.txt
@@ -0,0 +1,33 @@
+Device-Tree bindings for input/keyboard/rpmsg-keys.c keys driver over
+rpmsg. On i.mx7ULP keys are connected on M4 side, so rpmsg-keys driver
+needed to get the key status from M4 side by rpmsg.
+
+Required properties:
+ - compatible = "fsl,rpmsg-keys";
+
+Each button/key looked as the sub node:
+Required properties:
+ - label: the key name
+ - linux,code: the key value defined in
+ include/dt-bindings/input/input.h
+Optional property:
+ - rpmsg-key,wakeup: wakeup feature, the keys can wakeup from
+ suspend if the keys with this property pressed.
+
+Example nodes:
+ rpmsg_keys: rpmsg-keys {
+ compatible = "fsl,rpmsg-keys";
+
+ volume-up {
+ label = "Volume Up";
+ rpmsg-key,wakeup;
+ linux,code = <KEY_VOLUMEUP>;
+ };
+
+ volume-down {
+ label = "Volume Down";
+ rpmsg-key,wakeup;
+ linux,code = <KEY_VOLUMEDOWN>;
+ };
+ };
+
diff --git a/Documentation/devicetree/bindings/input/touchscreen/focaltech-ts.txt b/Documentation/devicetree/bindings/input/touchscreen/focaltech-ts.txt
new file mode 100644
index 000000000000..8e5257db88f6
--- /dev/null
+++ b/Documentation/devicetree/bindings/input/touchscreen/focaltech-ts.txt
@@ -0,0 +1,48 @@
+FocalTech touch controller
+
+The focaltech controller is connected to host processor via i2c.
+The controller generates interrupts when the user touches the panel.
+The host controller is expected to read the touch coordinates over
+i2c and pass the coordinates to the rest of the system.
+
+Required properties:
+ - compatible : should be "focaltech,fts"
+ - reg : i2c slave address of the device, should be <0x38>
+ - interrupt-parent : parent of interrupt
+ - interrupts : irq gpio, "0x02" stands for that the irq triggered by falling edge.
+ - focaltech,irq-gpio : irq gpio, same as "interrupts" node.
+ - focaltech,reset-gpio : reset gpio
+ - focaltech,num-max-touches : maximum number of touches support
+ - focaltech,display-coords : display resolution in pixels. A four tuple consisting of minX, minY, maxX and maxY.
+
+Optional properties:
+ - focaltech,have-key : specify if virtual keys are supported
+ - focaltech,key-number : number of keys
+ - focaltech,keys : virtual key codes mapping to the coords
+ - focaltech,key-y-coord : constant y coordinate of keys, depends on the y resolution
+ - focaltech,key-x-coords : constant x coordinates of keys, depends on the x resolution
+ - focaltech,swap-xy : swap x-y coordinates
+ - focaltech,panel-type : set panel type, default is FT5416 panel
+ - focaltech,scaling-down-half : scale down the x-y coordiantes to half
+
+
+Example:
+ i2c@f9927000 {
+ focaltech@38{
+ compatible = "focaltech,fts";
+ reg = <0x38>;
+ interrupt-parent = <&msm_gpio>;
+ interrupts = <13 0x02>;
+ focaltech,reset-gpio = <&msm_gpio 12 0x01>;
+ focaltech,irq-gpio = <&msm_gpio 13 0x02>;
+ focaltech,max-touch-number = <5>;
+ focaltech,display-coords = <0 0 1080 1920>;
+
+ focaltech,have-key;
+ focaltech,key-number = <3>;
+ focaltech,keys = <139 102 158>;
+ focaltech,key-y-coord = <2000>;
+ focaltech,key-x-coords = <200 600 800>;
+ focaltech,swap-xy;
+ };
+ };
diff --git a/Documentation/devicetree/bindings/input/touchscreen/vtl_ts.txt b/Documentation/devicetree/bindings/input/touchscreen/vtl_ts.txt
new file mode 100644
index 000000000000..a41a0b993006
--- /dev/null
+++ b/Documentation/devicetree/bindings/input/touchscreen/vtl_ts.txt
@@ -0,0 +1,18 @@
+* VTL Touchscreen Controller
+
+Required properties:
+- compatible: must be "vtl,ct365"
+- reg: i2c slave address
+- interrupt-parent: the phandle for the interrupt controller
+- interrupts: touch controller interrupt
+- gpios: the gpio pin to be used for reset
+
+Example:
+
+ touchscreen@01 {
+ compatible = "vtl,ct365";
+ reg = <0x01>;
+ interrupt-parent = <&gpio6>;
+ interrupts = <14 0>;
+ gpios = <&gpio4 10 0>;
+ };
diff --git a/Documentation/devicetree/bindings/interrupt-controller/nxp,imx-intmux.txt b/Documentation/devicetree/bindings/interrupt-controller/nxp,imx-intmux.txt
new file mode 100644
index 000000000000..8598a92bcf67
--- /dev/null
+++ b/Documentation/devicetree/bindings/interrupt-controller/nxp,imx-intmux.txt
@@ -0,0 +1,55 @@
+* NXP i.MX8QM/i.MX8QXP INTMUX Interrupt Multiplexing
+
+Required properties:
+- compatible: "nxp,imx-intmux".
+- reg: should contain IC registers location and length.
+- clocks : ipg clock for intmux.
+- interrupts: an interrupt to the parent interrupt controller.
+- interrupt-controller: identifies the node as an interrupt controller.
+- interrupt-parent: gic interrupt controller, link to parent
+- #interrupt-cells: the number of cells to define an interrupt, should be 2.
+ The first cell is the IRQ number, the second cell is used to specify
+ one of the supported IRQ types:
+ IRQ_TYPE_EDGE_RISING = low-to-high edge triggered,
+ IRQ_TYPE_EDGE_FALLING = high-to-low edge triggered,
+ IRQ_TYPE_LEVEL_HIGH = active high level-sensitive,
+ IRQ_TYPE_LEVEL_LOW = active low level-sensitive.
+
+Optional properties:
+- nxp,intmux_chans: specify the interrupt channel number, default is 1.
+
+Examples:
+
+ intmux_cm40: intmux@37400000 {
+ compatible = "nxp,imx-intmux";
+ reg = <0x0 0x37400000 0x0 0x1000>;
+ interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>,
+ <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>;
+ interrupt-controller;
+ interrupt-parent = <&gic>;
+ #interrupt-cells = <2>;
+ clocks = <&clk IMX8QXP_CM40_IPG_CLK>;
+ clock-names = "ipg";
+ power-domains = <&pd_cm40_intmux>;
+ status = "disabled";
+ };
+
+ i2c0_cm40: i2c@37230000 {
+ compatible = "fsl,imx8qm-lpi2c";
+ reg = <0x0 0x37230000 0x0 0x1000>;
+ interrupts = <9 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-parent = <&intmux_cm40>;
+ clocks = <&clk IMX8QXP_CM40_I2C_CLK>,
+ <&clk IMX8QXP_CM40_I2C_IPG_CLK>;
+ clock-names = "per", "ipg";
+ assigned-clocks = <&clk IMX8QXP_CM40_I2C_CLK>;
+ assigned-clock-rates = <24000000>;
+ power-domains = <&pd_cm40_i2c>;
+ status = "disabled";
+ };
diff --git a/Documentation/devicetree/bindings/interrupt-controller/nxp,imx-irqsteer.txt b/Documentation/devicetree/bindings/interrupt-controller/nxp,imx-irqsteer.txt
new file mode 100644
index 000000000000..671622c296f0
--- /dev/null
+++ b/Documentation/devicetree/bindings/interrupt-controller/nxp,imx-irqsteer.txt
@@ -0,0 +1,44 @@
+* NXP i.MX8QM/i.MX8QXP IRQSteer Interrupt Controllers
+
+Required properties:
+- compatible: "nxp,imx-irqsteer".
+- reg: should contain IC registers location and length.
+- clocks : ipg clock for irqsteer.
+- interrupts: an interrupt to the parent interrupt controller.
+- interrupt-controller: identifies the node as an interrupt controller.
+- interrupt-parent: gic interrupt controller, link to parent
+- #interrupt-cells: the number of cells to define an interrupt, should be 2.
+ The first cell is the IRQ number, the second cell is used to specify
+ one of the supported IRQ types:
+ IRQ_TYPE_EDGE_RISING = low-to-high edge triggered,
+ IRQ_TYPE_EDGE_FALLING = high-to-low edge triggered,
+ IRQ_TYPE_LEVEL_HIGH = active high level-sensitive,
+ IRQ_TYPE_LEVEL_LOW = active low level-sensitive.
+
+Optional properties:
+- nxp,irqsteer_chans: specify the interrupt channel number, default is 1.
+
+Examples:
+
+ irqsteer_hdmi: irqsteer@56260000 {
+ compatible = "nxp,imx-irqsteer";
+ reg = <0x0 0x56260000 0x0 0x1000>;
+ interrupts = <GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-controller;
+ interrupt-parent = <&gic>;
+ #interrupt-cells = <2>;
+ power-domains = <&pd_hdmi_i2c0>;
+ };
+
+ i2c0_hdmi: i2c@56266000 {
+ compatible = "fsl,imx8qm-lpi2c";
+ reg = <0x0 0x56266000 0x0 0x1000>;
+ interrupts = <8 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-parent = <&irqsteer_hdmi>;
+ clocks = <&clk IMX8QM_HDMI_I2C0_CLK>;
+ clock-names = "per";
+ assigned-clocks = <&clk IMX8QM_HDMI_I2C0_CLK>;
+ assigned-clock-rates = <24000000>;
+ power-domains = <&pd_hdmi_i2c0>;
+ status = "disabled";
+ };
diff --git a/Documentation/devicetree/bindings/media/i2c/ov5640_mipi.txt b/Documentation/devicetree/bindings/media/i2c/ov5640_mipi.txt
new file mode 100644
index 000000000000..e37fef7bc6c2
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/i2c/ov5640_mipi.txt
@@ -0,0 +1,114 @@
+* Omnivision OV5640 image sensor
+
+The Omnivision OV5640 is a 1/4" color CMOS QSXGA 5 megapixel image sensor.
+All image processing functions are programmable through the SCCB interface
+or embedded microcontroller.
+The OV5640 supports both a digital video parallel port and a dual lane
+serial MIPI port.
+
+The OV5640 sensor supports multiple resolutions output, such as QSXGA, 1080p,
+720p, VGA, QVGA. It also can support YUV422/420, YCbCr422, RGB565/555/444,
+CCIR656 or raw RGB output formats.
+
+
+Required Properties:
+- compatible: should be "ovti,ov5640_mipi"
+- clocks: reference to the csi_mclk input clock.
+- clock-names: should be "csi_mclk".
+- reg: I2C slave address
+- csi-id: virtual channel for this sensor
+- mclk: used to calculate xvclk (sensor master input clock, xvclk = mclk /10000)
+
+
+Optional Properties:
+- rst-gpios: reference to the GPIO connected to the resetb pin, if any.
+- pwn-gpios: reference to the GPIO connected to the pwdn pin, if any.
+
+The device node must contain one 'port' child node for its digital output
+video port, in accordance with the video interface bindings defined in
+Documentation/devicetree/bindings/media/video-interfaces.txt.
+
+Please note that the default I2C slave address is 0x3c.
+In case dual-camera is used, it might be necessary to change
+the I2C slave address for both cameras, and disable the reset pin,
+this is if the board has only one reset line for both cameras, for
+example imx-8mq-evk rev B3. Also, unique csi-id is needed for each
+camera. See the dual-camera example.
+
+
+Example for single camera:
+
+i2c1: i2c@30a20000 {
+ ov5640_mipi: ov5640_mipi@3c {
+ compatible = "ovti,ov5640_mipi";
+ reg = <0x3c>;
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_csi1_pwn>, <&pinctrl_csi_rst>;
+ clocks = <&clk IMX8MQ_CLK_CLKO2_DIV>;
+ clock-names = "csi_mclk";
+ assigned-clocks = <&clk IMX8MQ_CLK_CLKO2_SRC>,
+ <&clk IMX8MQ_CLK_CLKO2_DIV>;
+ assigned-clock-parents = <&clk IMX8MQ_SYS2_PLL_200M>;
+ assigned-clock-rates = <0>, <20000000>;
+ csi_id = <0>;
+ pwn-gpios = <&gpio1 3 GPIO_ACTIVE_HIGH>;
+ rst-gpios = <&gpio1 6 GPIO_ACTIVE_HIGH>;
+ mclk = <20000000>;
+ mclk_source = <0>;
+ port {
+ ov5640_mipi1_ep: endpoint {
+ remote-endpoint = <&mipi1_sensor_ep>;
+ };
+ };
+ };
+
+
+Example for dual-camera:
+
+ ov5640_mipi: ov5640_mipi@1c {
+ compatible = "ovti,ov5640_mipi";
+ reg = <0x1c>;
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_csi1_pwn>, <&pinctrl_csi_rst>;
+ clocks = <&clk IMX8MQ_CLK_CLKO2_DIV>;
+ clock-names = "csi_mclk";
+ assigned-clocks = <&clk IMX8MQ_CLK_CLKO2_SRC>,
+ <&clk IMX8MQ_CLK_CLKO2_DIV>;
+ assigned-clock-parents = <&clk IMX8MQ_SYS2_PLL_200M>;
+ assigned-clock-rates = <0>, <20000000>;
+ csi_id = <0>;
+ pwn-gpios = <&gpio1 3 GPIO_ACTIVE_HIGH>;
+ mclk = <20000000>;
+ mclk_source = <0>;
+ port {
+ ov5640_mipi1_ep: endpoint {
+ remote-endpoint = <&mipi1_sensor_ep>;
+ };
+ };
+ };
+
+ ov5640_mipi2: ov5640_mipi2@2c {
+ compatible = "ovti,ov5640_mipi";
+ reg = <0x2c>;
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_csi2_pwn>;
+ clocks = <&clk IMX8MQ_CLK_CLKO2_DIV>;
+ clock-names = "csi_mclk";
+ assigned-clocks = <&clk IMX8MQ_CLK_CLKO2_SRC>,
+ <&clk IMX8MQ_CLK_CLKO2_DIV>;
+ assigned-clock-parents = <&clk IMX8MQ_SYS2_PLL_200M>;
+ assigned-clock-rates = <0>, <20000000>;
+ csi_id = <1>;
+ pwn-gpios = <&gpio1 5 GPIO_ACTIVE_HIGH>;
+ mclk = <20000000>;
+ mclk_source = <0>;
+ port {
+ ov5640_mipi2_ep: endpoint {
+ remote-endpoint = <&mipi2_sensor_ep>;
+ };
+ };
+ };
+};
diff --git a/Documentation/devicetree/bindings/mfd/syscon.txt b/Documentation/devicetree/bindings/mfd/syscon.txt
index 408f768686f1..29bc9182ea50 100644
--- a/Documentation/devicetree/bindings/mfd/syscon.txt
+++ b/Documentation/devicetree/bindings/mfd/syscon.txt
@@ -13,12 +13,18 @@ Required properties:
- compatible: Should contain "syscon".
- reg: the register region can be accessed from syscon
-Optional property:
+Optional properties:
- reg-io-width: the size (in bytes) of the IO accesses that should be
performed on the device.
+- clocks: clock used for accessing the regmap
Examples:
gpr: iomuxc-gpr@020e0000 {
compatible = "fsl,imx6q-iomuxc-gpr", "syscon";
reg = <0x020e0000 0x38>;
};
+
+hsio: hsio@5f080000 {
+ compatible = "fsl,imx8qm-hsio", "syscon";
+ reg = <0x0 0x5f080000 0x0 0xF0000>; /* lpcg, csr, msic, gpio */
+};
diff --git a/Documentation/devicetree/bindings/mlb/mxc_mlb.txt b/Documentation/devicetree/bindings/mlb/mxc_mlb.txt
new file mode 100644
index 000000000000..e19c4e364d25
--- /dev/null
+++ b/Documentation/devicetree/bindings/mlb/mxc_mlb.txt
@@ -0,0 +1,26 @@
+*MediaLB (MLB) for i.MX
+
+Required properties:
+- compatible :
+ - "fsl,imx6sx-mlb50" for MLB compatible with the one integrated on i.MX6SX soc
+ - "fsl,imx6q-mlb150" for MLB compatible with the one integrated on i.MX6Q and i.MX8 soc
+- reg : address and length for mlb registers
+- interrupt-parent : core interrupt controller
+- interrupts : MLB Break/Error interrupt and ahb interrupt
+ Two ahb interrupt for imx6, ahb_int[0] and ahb_int[1]
+ One ahb interrupt for imx8, ahb_int[0]
+- clocks : mlb clock specifier
+
+Examples:
+
+mlb: mlb@5B060000 {
+ compatible = "fsl,imx6q-mlb150";
+ reg = <0x0 0x5B060000 0x0 0x10000>;
+ interrupt-parent = <&gic>;
+ interrupts = <0 265 IRQ_TYPE_LEVEL_HIGH>,
+ <0 266 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8QM_MLB_CLK>,
+ <&clk IMX8QM_MLB_HCLK>,
+ <&clk IMX8QM_MLB_IPG_CLK>;
+ status = "disabled";
+};
diff --git a/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.txt b/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.txt
index 3e29050ec769..229fe25a54c8 100644
--- a/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.txt
+++ b/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.txt
@@ -35,6 +35,13 @@ Optional properties:
This property allows user to change the tuning step to more than one delay
cells which is useful for some special boards or cards when the default
tuning step can't find the proper delay window within limited tuning retries.
+- fsl,strobe-dll-delay-target: Specify the strobe dll control slave delay target.
+ This delay target programming host controller loopback read clock, and this
+ property allows user to change the delay target for the strobe input read clock.
+ If not use this property, driver default set the delay target to value 7.
+ Only eMMC HS400 mode need to take care of this property.
+- wifi-host : assigned as a wifi host.
+ This is required for Broadcom BCM WiFi cards to do card detect
Examples:
diff --git a/Documentation/devicetree/bindings/mmc/mmc.txt b/Documentation/devicetree/bindings/mmc/mmc.txt
index b32ade645ad9..b57d67afe64c 100644
--- a/Documentation/devicetree/bindings/mmc/mmc.txt
+++ b/Documentation/devicetree/bindings/mmc/mmc.txt
@@ -12,6 +12,8 @@ Only one of the properties in this section should be supplied:
- broken-cd: There is no card detection available; polling must be used.
- cd-gpios: Specify GPIOs for card detection, see gpio binding
- non-removable: non-removable slot (like eMMC); assume always present.
+ - cd-post: postone card detect from start host for non-removable cards
+ and let client driver to start it when ready
Optional properties:
- bus-width: Number of data lines, can be <1>, <4>, or <8>. The default
@@ -75,6 +77,9 @@ Optional SDIO properties:
- keep-power-in-suspend: Preserves card power during a suspend/resume cycle
- wakeup-source: Enables wake up of host system on SDIO IRQ assertion
(Legacy property supported: "enable-sdio-wakeup")
+- pm-ignore-notify: Ignore mmc PM notify. This will prevent MMC core automatically
+ to re-detect cards after sysem resume back.
+
MMC power
---------
diff --git a/Documentation/devicetree/bindings/mtd/fsl-quadspi.txt b/Documentation/devicetree/bindings/mtd/fsl-quadspi.txt
index c34aa6f8a424..951655466a11 100644
--- a/Documentation/devicetree/bindings/mtd/fsl-quadspi.txt
+++ b/Documentation/devicetree/bindings/mtd/fsl-quadspi.txt
@@ -1,5 +1,11 @@
* Freescale Quad Serial Peripheral Interface(QuadSPI)
+The QuadSPI controller acts as the SPI master. It is described with a node
+for the controller and a set of child nodes for each SPI NOR flash.
+
+Part I - The DT node for the controller:
+------------------------------
+
Required properties:
- compatible : Should be "fsl,vf610-qspi", "fsl,imx6sx-qspi",
"fsl,imx7d-qspi", "fsl,imx6ul-qspi",
@@ -24,6 +30,16 @@ Optional properties:
(Please check the board's schematic.)
- big-endian : That means the IP register is big endian
+Part II - The DT nodes for each SPI NOR flash
+------------------------------
+Required properties:
+- spi-max-frequency : Maximum frequency of the SPI bus the chip can operate at
+
+Optional properties:
+ Please refer to the Documentation/devicetree/bindings/mtd/spi-nor-flash.txt
+ If you set the "spi-nor,ddr-quad-read-dummy", it means you enable the DDR
+ quad read feature for the driver.
+
Example:
qspi0: quadspi@40044000 {
diff --git a/Documentation/devicetree/bindings/mtd/gpmi-nand.txt b/Documentation/devicetree/bindings/mtd/gpmi-nand.txt
index b289ef3c1b7e..68514043ede2 100644
--- a/Documentation/devicetree/bindings/mtd/gpmi-nand.txt
+++ b/Documentation/devicetree/bindings/mtd/gpmi-nand.txt
@@ -8,8 +8,11 @@ Required properties:
* imx23
* imx28
* imx6q
+ * imx6qp
* imx6sx
+ * imx6ul
* imx7d
+ * imx6ull
- reg : should contain registers location and length for gpmi and bch.
- reg-names: Should contain the reg names "gpmi-nand" and "bch"
- interrupts : BCH interrupt number.
@@ -47,6 +50,10 @@ Optional properties:
partitions written from Linux with this feature
turned on may not be accessible by the BootROM
code.
+ - fsl,legacy-bch-geometry: Use legacy bch geometry(ECC scheme) that
+ compatible with 3.10 kernel. Without the property,
+ software may use ECC strength according to NAND chip
+ spec, e.g. ONFI standard.
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/mtd/spi-nor-flash.txt b/Documentation/devicetree/bindings/mtd/spi-nor-flash.txt
new file mode 100644
index 000000000000..aba4d54233d2
--- /dev/null
+++ b/Documentation/devicetree/bindings/mtd/spi-nor-flash.txt
@@ -0,0 +1,7 @@
+This file defines some DT properties for specific SPI NOR flash features.
+The SPI NOR controller drivers may refer to this file, such as fsl-quadspi.txt
+
+Optional properties:
+ - spi-nor,ddr-quad-read-dummy: The dummy cycles used by the DDR Quad read.
+ Please refer to the chip's datasheet. This
+ property can be 4 or 6 which is less then 8.
diff --git a/Documentation/devicetree/bindings/net/can/fsl-flexcan.txt b/Documentation/devicetree/bindings/net/can/fsl-flexcan.txt
index 56d6cc336e1c..c5ed89cd9c8f 100644
--- a/Documentation/devicetree/bindings/net/can/fsl-flexcan.txt
+++ b/Documentation/devicetree/bindings/net/can/fsl-flexcan.txt
@@ -17,6 +17,22 @@ Optional properties:
- clock-frequency : The oscillator frequency driving the flexcan device
- xceiver-supply: Regulator that powers the CAN transceiver
+- stop-mode: register bits of stop mode control, the format is
+ <&gpr req_gpr req_bit ack_gpr ack_bit>.
+ gpr is the phandle to general purpose register node.
+ req_gpr is the gpr register offset of CAN stop request.
+ req_bit is the bit offset of CAN stop request.
+ ack_gpr is the gpr register offset of CAN stop acknowledge.
+ ack_bit is the bit offset of CAN stop acknowledge.
+ stop-mode = <&gpr req_gpr req_bit ack_gpr ack_bit>, this format is for i.MX6/7
+ series to set stop mode. For i.MX8 series, stop mode feature is supported by default.
+- trx_en_gpio : enable gpio
+- trx_stby_gpio : standby gpio
+- trx_nerr_gpio : NERR gpio
+- disable-fd-mode : disable CAN FD mode support. Valid since i.MX8 series.
+- clk-src : Selects the clock source to the CAN Protocol Engine (PE). It's SoC
+ Implementation dependent. Refer to RM for detailed definition.
+ 0: clock source 0 1: clock source 1
Example:
diff --git a/Documentation/devicetree/bindings/net/fsl-fec.txt b/Documentation/devicetree/bindings/net/fsl-fec.txt
index 6f55bdd52f8a..a357df3fd9f6 100644
--- a/Documentation/devicetree/bindings/net/fsl-fec.txt
+++ b/Documentation/devicetree/bindings/net/fsl-fec.txt
@@ -5,6 +5,13 @@ Required properties:
- reg : Address and length of the register set for the device
- interrupts : Should contain fec interrupt
- phy-mode : See ethernet.txt file in the same directory
+- clock-name: Should be the names of the clocks
+ - "ipg" for MAC ipg_clk_s, ipg_clk_mac_s that are for register accessing
+ - "ahb" for MAC ipg_clk, ipg_clk_mac that are bus clock
+ - "ptp" for IEEE1588 timer clock
+ - "enet_clk_ref" for MAC transmit/receiver reference clock
+ - "enet_out" output clock for external device
+- clocks: Phandles to input clocks.
Optional properties:
- phy-reset-gpios : Should specify the gpio for phy reset
@@ -34,6 +41,12 @@ Optional properties:
- fsl,err006687-workaround-present: If present indicates that the system has
the hardware workaround for ERR006687 applied and does not need a software
workaround.
+- fsl,wakeup_irq : The property define the wakeup irq index in enet irq source.
+- stop-mode : If present, indicates soc need to set gpr bit to request stop
+ mode.
+- fsl,ar8031-phy-fixup : If present, indicates board need to do phy fixup setting.
+- mii-exclusive: If present, each MAC has their exclusive MDIO bus in current board
+ design, otherwise mutiple MACs share one MDIO bus to reduce Pins utilize.
Optional subnodes:
- mdio : specifies the mdio bus in the FEC, used as a container for phy nodes
diff --git a/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.txt b/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.txt
index 7b1e48bf172b..45deda18524e 100644
--- a/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.txt
+++ b/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.txt
@@ -9,6 +9,10 @@ Required properties:
- "fsl,imx6sx-pcie",
- "fsl,imx6qp-pcie"
- "fsl,imx7d-pcie"
+ - "fsl,imx8qm-pcie"
+ - "fsl,imx8qxp-pcie"
+ - "fsl,imx8mq-pcie"
+ - "fsl,imx8mm-pcie"
- reg: base address and length of the PCIe controller
- interrupts: A list of interrupt outputs of the controller. Must contain an
entry for each entry in the interrupt-names property.
@@ -16,6 +20,8 @@ Required properties:
- "msi": The interrupt that is asserted when an MSI is received
- clock-names: Must include the following additional entries:
- "pcie_phy"
+- ext_osc: use the external oscillator or not.
+- hard-wired: the port is hard wired in hw design or not.
Optional properties:
- fsl,tx-deemph-gen1: Gen1 De-emphasis value. Default: 0
@@ -50,6 +56,23 @@ Additional required properties for imx7d-pcie:
- "pciephy"
- "apps"
+Additional required properties for imx8 pcie:
+- hsio : should be <&hsio>.
+ The phandle points to the hsio region containing the hsio
+ such as the pcie and sata control registers.
+- hsio-cfg: hsio configration mode when the pcie node is supported.
+ mode 1: pciea 2 lanes and one sata ahci port.
+ mode 2: pciea 1 lane, pcieb 1 lane and one sata ahci port.
+ mode 3: pciea 2 lanes, pcieb 1 lane.
+- ctrl-id: used to distinguish pciea or pcieb.
+ 0: pciea, 1: pcieb.
+- cpu-base-addr: the base cpu address mapped from hsio address.
+ Example:
+ hsio-cfg = <PCIEAX1PCIEBX1SATA>;
+ hsio = <&hsio>;
+ ctrl-id = <0>; /* pciea */
+ cpu-base-addr = <0x40000000>;
+
Example:
pcie@0x01000000 {
diff --git a/Documentation/devicetree/bindings/phy/mixel,lvds-combo-phy.txt b/Documentation/devicetree/bindings/phy/mixel,lvds-combo-phy.txt
new file mode 100644
index 000000000000..7d36747871fa
--- /dev/null
+++ b/Documentation/devicetree/bindings/phy/mixel,lvds-combo-phy.txt
@@ -0,0 +1,20 @@
+Mixel LVDS combo PHY
+
+Required properties:
+- compatible: must be "mixel,lvds-combo-phy".
+- reg: offset and length of the register block.
+- #phy-cells: see phy-bindings.txt in the same directory, must be <0>.
+- clocks: clock phandle and specifier pair.
+- clock-names: string, clock input name, must be "phy".
+- power-domains: phandle pointing to power domain.
+
+Example:
+ ldb1_phy: ldb_phy@56221000 {
+ compatible = "mixel,lvds-combo-phy";
+ reg = <0x0 0x56221000 0x0 0x100>, <0x0 0x56228000 0x0 0x1000>;
+ #phy-cells = <0>;
+ clocks = <&clk IMX8QXP_MIPI0_LVDS_PHY_CLK>;
+ clock-names = "phy";
+ power-domains = <&pd_mipi_dsi0>;
+ status = "disabled";
+ };
diff --git a/Documentation/devicetree/bindings/phy/mixel,lvds-phy.txt b/Documentation/devicetree/bindings/phy/mixel,lvds-phy.txt
new file mode 100644
index 000000000000..27fb5a4c182d
--- /dev/null
+++ b/Documentation/devicetree/bindings/phy/mixel,lvds-phy.txt
@@ -0,0 +1,39 @@
+Mixel LVDS PHY
+
+This LVDS PHY supports two LVDS channels.
+
+Required properties:
+- compatible: must be "mixel,lvds-phy".
+- reg: offset and length of the register block.
+- #address-cells: number of address cells for the LVDS channel subnodes, must
+ be <1>.
+- #size-cells: number of size cells for the LVDS channel subnodes, must be <0>.
+- clocks: clock phandle and specifier pair.
+- clock-names: string, clock input name, must be "phy".
+- power-domains: phandle pointing to power domain.
+
+The LVDS PHY device tree node should have the subnodes corresponding to the two
+LVDS channels. These subnodes must contain the following properties:
+- reg: the PHY ID.
+- #phy-cells: see phy-bindings.txt in the same directory, must be <0>.
+
+Example:
+ ldb1_phy: ldb_phy@56241000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "mixel,lvds-phy";
+ reg = <0x0 0x56241000 0x0 0x100>;
+ clocks = <&clk IMX8QM_LVDS0_PHY_CLK>;
+ clock-names = "phy";
+ power-domains = <&pd_lvds0>;
+
+ ldb1_phy1: port@0 {
+ reg = <0>;
+ #phy-cells = <0>;
+ };
+
+ ldb1_phy2: port@1 {
+ reg = <1>;
+ #phy-cells = <0>;
+ };
+ };
diff --git a/Documentation/devicetree/bindings/phy/mixel,mipi-dsi-phy.txt b/Documentation/devicetree/bindings/phy/mixel,mipi-dsi-phy.txt
new file mode 100644
index 000000000000..c868b39a88b7
--- /dev/null
+++ b/Documentation/devicetree/bindings/phy/mixel,mipi-dsi-phy.txt
@@ -0,0 +1,23 @@
+Mixel DSI DPHY for MX8
+
+The MIPI-DSI DPHY IP block found on MX8 platforms comes along the MIPI-DSI
+IP from Northwest Logic and represents the physical layer for the electrical
+signals for DSI.
+
+Required properties:
+- compatible: "mixel,<soc>-mipi-dsi-phy"
+- reg: the register range of the PHY controller
+- #phy-cells: number of cells in PHY, as defined in
+ Documentation/devicetree/bindings/phy/phy-bindings.txt
+ this must be <0>
+
+Optional properties:
+- power-domains: phandle to power domain
+
+Example:
+ mipi0_phy: mipi0_phy@56228300 {
+ compatible = "mixel,imx8qm-mipi-dsi-phy";
+ reg = <0x0 0x56228300 0x0 0x100>;
+ power-domains = <&pd_mipi0>;
+ #phy-cells = <0>;
+ };
diff --git a/Documentation/devicetree/bindings/phy/mxs-usb-phy.txt b/Documentation/devicetree/bindings/phy/mxs-usb-phy.txt
index 1d25b04cd05e..c795eba2daa2 100644
--- a/Documentation/devicetree/bindings/phy/mxs-usb-phy.txt
+++ b/Documentation/devicetree/bindings/phy/mxs-usb-phy.txt
@@ -7,6 +7,8 @@ Required properties:
* "fsl,imx6sl-usbphy" for imx6sl
* "fsl,vf610-usbphy" for Vybrid vf610
* "fsl,imx6sx-usbphy" for imx6sx
+ * "fsl,imx6ul-usbphy" for imx6ul
+ * "fsl,imx7ulp-usbphy" for imx7ulp
"fsl,imx23-usbphy" is still a fallback for other strings
- reg: Should contain registers location and length
- interrupts: Should contain phy interrupt
@@ -28,4 +30,5 @@ usbphy1: usbphy@020c9000 {
reg = <0x020c9000 0x1000>;
interrupts = <0 44 0x04>;
fsl,anatop = <&anatop>;
+ fsl,tx-d-cal = <106>;
};
diff --git a/Documentation/devicetree/bindings/pinctrl/fsl,imx8mm-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/fsl,imx8mm-pinctrl.txt
new file mode 100644
index 000000000000..380233d3931a
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/fsl,imx8mm-pinctrl.txt
@@ -0,0 +1,36 @@
+* Freescale i.MX8M Mini IOMUX Controller
+
+Please refer to fsl,imx-pinctrl.txt in this directory for common binding part
+and usage.
+
+Required properties:
+- compatible: "fsl,imx8mm-iomuxc" for IOMUXC controller.
+- fsl,pins: each entry consists of 6 integers and represents the mux and config
+ setting for one pin. The first 5 integers <mux_reg conf_reg input_reg mux_val
+ input_val> are specified using a PIN_FUNC_ID macro, which can be found in
+ pins-imx8mm.h under device tree source folder. The last integer CONFIG is
+ the pad setting value like pull-up on this pin. Please refer to i.MX8M Mini
+ Reference Manual for detailed CONFIG settings.
+
+CONFIG bits definition:
+PAD_CTL_LVTTL (1 << 8)
+PAD_CTL_HYS (1 << 7)
+PAD_CTL_PUE (1 << 6)
+PAD_CTL_ODE (1 << 5)
+PAD_CTL_SRE_SLOW (0 << 3)
+PAD_CTL_SRE_MED (1 << 3)
+PAD_CTL_SRE_FAST (2 << 3)
+PAD_CTL_SRE_MAX (3 << 3)
+PAD_CTL_DSE_HIZ (0 << 0)
+PAD_CTL_DSE_255 (1 << 0)
+PAD_CTL_DSE_105 (2 << 0)
+PAD_CTL_DSE_75 (3 << 0)
+PAD_CTL_DSE_85 (4 << 0)
+PAD_CTL_DSE_65 (5 << 0)
+PAD_CTL_DSE_45 (6 << 0)
+PAD_CTL_DSE_40 (7 << 0)
+
+iomuxc: pinctrl@30330000 {
+ compatible = "fsl,imx8mm-iomuxc";
+ reg = <0x0 0x30330000 0x0 0x10000>;
+};
diff --git a/Documentation/devicetree/bindings/pinctrl/fsl,imx8mq-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/fsl,imx8mq-pinctrl.txt
new file mode 100644
index 000000000000..efee1106a6d6
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/fsl,imx8mq-pinctrl.txt
@@ -0,0 +1,36 @@
+* Freescale i.MX8M Qual IOMUX Controller
+
+Please refer to fsl,imx-pinctrl.txt in this directory for common binding part
+and usage.
+
+Required properties:
+- compatible: "fsl,imx8mq-iomuxc" for IOMUXC controller.
+- fsl,pins: each entry consists of 6 integers and represents the mux and config
+ setting for one pin. The first 5 integers <mux_reg conf_reg input_reg mux_val
+ input_val> are specified using a PIN_FUNC_ID macro, which can be found in
+ pins-imx8mq.h under device tree source folder. The last integer CONFIG is
+ the pad setting value like pull-up on this pin. Please refer to i.MX8M Qual
+ Reference Manual for detailed CONFIG settings.
+
+CONFIG bits definition:
+PAD_CTL_LVTTL (1 << 8)
+PAD_CTL_HYS (1 << 7)
+PAD_CTL_PUE (1 << 6)
+PAD_CTL_ODE (1 << 5)
+PAD_CTL_SRE_SLOW (0 << 3)
+PAD_CTL_SRE_MED (1 << 3)
+PAD_CTL_SRE_FAST (2 << 3)
+PAD_CTL_SRE_MAX (3 << 3)
+PAD_CTL_DSE_HIZ (0 << 0)
+PAD_CTL_DSE_255 (1 << 0)
+PAD_CTL_DSE_105 (2 << 0)
+PAD_CTL_DSE_75 (3 << 0)
+PAD_CTL_DSE_85 (4 << 0)
+PAD_CTL_DSE_65 (5 << 0)
+PAD_CTL_DSE_45 (6 << 0)
+PAD_CTL_DSE_40 (7 << 0)
+
+iomuxc: iomuxc@30330000 {
+ compatible = "fsl,imx8mq-iomuxc";
+ reg = <0x0 0x30330000 0x0 0x10000>;
+};
diff --git a/Documentation/devicetree/bindings/pinctrl/fsl,imx8qm-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/fsl,imx8qm-pinctrl.txt
new file mode 100644
index 000000000000..68423ea288bc
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/fsl,imx8qm-pinctrl.txt
@@ -0,0 +1,73 @@
+* Freescale i.MX8QM IOMUX Controller
+
+Required properties:
+- compatible: "fsl,imx8qm-iomuxc"
+- fsl,pins: each entry consists of 2 integers. Its format is
+ <pin_id pin_config>.
+
+pin_config definition:
+- i.MX8QM have different pad types, please refer to below pad
+ register definitions, the pinctrl driver will just write the
+ pin_config into the hardware register.
+
+typedef union _hw_pad_iomux
+{
+ uint32_t U;
+ struct _hw_pad_iomux_bitfields0
+ {
+ uint32_t GP : 19; /*!< [18:0] GP controls. */
+ uint32_t WAKEUP : 3; /*!< [21:19] Wakeup controls. */
+ uint32_t WAKEUP_ENB : 1; /*!< [22] Wakeup write enable. */
+ uint32_t LPCONFIG : 2; /*!< [24:23] Low-power config. */
+ uint32_t CONFIG : 2; /*!< [26:25] Config. */
+ uint32_t IFMUX : 3; /*!< [29:27] Mux. */
+ uint32_t GP_ENB : 1; /*!< [30] GP write enable. */
+ uint32_t IFMUX_ENB : 1; /*!< [31] Mux write enable. */
+ } B;
+ struct _hw_pad_iomux_28fdsoi
+ {
+ uint32_t DSE : 3; /*!< [2:0] Drive strength. */
+ uint32_t _reserved1 : 2; /*!< [4:3] */
+ uint32_t PS : 2; /*!< [6:5] Pull select. */
+ uint32_t _reserved2 : 12; /*!< [18:7] */
+ uint32_t WAKEUP : 3; /*!< [21:19] Wakeup controls. */
+ uint32_t WAKEUP_ENB : 1; /*!< [22] Wakeup write enable. */
+ uint32_t LPCONFIG : 2; /*!< [24:23] Low-power config. */
+ uint32_t CONFIG : 2; /*!< [26:25] Config. */
+ uint32_t IFMUX : 3; /*!< [29:27] Mux. */
+ uint32_t GP_ENB : 1; /*!< [30] GP write enable. */
+ uint32_t IFMUX_ENB : 1; /*!< [31] Mux write enable. */
+ } FDS0I28;
+ struct _hw_pad_iomux_28fdsoi_hsic
+ {
+ uint32_t DSE : 3; /*!< [2:0] Drive strength. */
+ uint32_t HYS : 1; /*!< [3] Hysteresis. */
+ uint32_t PUS : 2; /*!< [5:4] Pull-up select. */
+ uint32_t PKE : 1; /*!< [6] Pad keeper enable. */
+ uint32_t PUE : 1; /*!< [7] Pull-up enable. */
+ uint32_t _reserved2 : 11; /*!< [18:8] */
+ uint32_t WAKEUP : 3; /*!< [21:19] Wakeup controls. */
+ uint32_t WAKEUP_ENB : 1; /*!< [22] Wakeup write enable. */
+ uint32_t LPCONFIG : 2; /*!< [24:23] Low-power config. */
+ uint32_t CONFIG : 2; /*!< [26:25] Config. */
+ uint32_t IFMUX : 3; /*!< [29:27] Mux. */
+ uint32_t GP_ENB : 1; /*!< [30] GP write enable. */
+ uint32_t IFMUX_ENB : 1; /*!< [31] Mux write enable. */
+ } FDS0I28_HSIC;
+ struct _hw_pad_iomux_28fdsoi_comp
+ {
+ uint32_t COMPEN : 3; /*!< [2:0] Mode. */
+ uint32_t FASTFRZ : 1; /*!< [3] Fast freeze. */
+ uint32_t PSW_OVR : 1; /*!< [4] 2.5 volt override */
+ uint32_t RASRCP : 4; /*!< [8:5] PMOS comp. */
+ uint32_t RASRCN : 4; /*!< [12:9] NMOS comp. */
+ uint32_t NASRC_SEL : 1; /*!< [13] Read NASRC select. */
+ uint32_t COMPOK : 1; /*!< [14] Comp status. */
+ uint32_t NASRC : 4; /*!< [18:15] NASRC value. */
+ uint32_t _reserved2 : 4; /*!< [22:19] */
+ uint32_t LPCONFIG : 2; /*!< [24:23] Low-power config. */
+ uint32_t _reserved3 : 5; /*!< [29:25] */
+ uint32_t GP_ENB : 1; /*!< [30] GP write enable. */
+ uint32_t IFMUX_ENB : 1; /*!< [31] Mux write enable. */
+ } FDS0I28_COMP;
+} hw_pad_iomux_t;
diff --git a/Documentation/devicetree/bindings/pinctrl/fsl,imx8qxp-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/fsl,imx8qxp-pinctrl.txt
new file mode 100644
index 000000000000..4ea92de8e1ca
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/fsl,imx8qxp-pinctrl.txt
@@ -0,0 +1,73 @@
+* Freescale i.MX8QXP IOMUX Controller
+
+Required properties:
+- compatible: "fsl,imx8qxp-iomuxc"
+- fsl,pins: each entry consists of 2 integers. Its format is
+ <pin_id pin_config>.
+
+pin_config definition:
+- i.MX8QXP have different pad types, please refer to below pad
+ register definitions, the pinctrl driver will just write the
+ pin_config into the hardware register.
+
+typedef union _hw_pad_iomux
+{
+ uint32_t U;
+ struct _hw_pad_iomux_bitfields0
+ {
+ uint32_t GP : 19; /*!< [18:0] GP controls. */
+ uint32_t WAKEUP : 3; /*!< [21:19] Wakeup controls. */
+ uint32_t WAKEUP_ENB : 1; /*!< [22] Wakeup write enable. */
+ uint32_t LPCONFIG : 2; /*!< [24:23] Low-power config. */
+ uint32_t CONFIG : 2; /*!< [26:25] Config. */
+ uint32_t IFMUX : 3; /*!< [29:27] Mux. */
+ uint32_t GP_ENB : 1; /*!< [30] GP write enable. */
+ uint32_t IFMUX_ENB : 1; /*!< [31] Mux write enable. */
+ } B;
+ struct _hw_pad_iomux_28fdsoi
+ {
+ uint32_t DSE : 3; /*!< [2:0] Drive strength. */
+ uint32_t _reserved1 : 2; /*!< [4:3] */
+ uint32_t PS : 2; /*!< [6:5] Pull select. */
+ uint32_t _reserved2 : 12; /*!< [18:7] */
+ uint32_t WAKEUP : 3; /*!< [21:19] Wakeup controls. */
+ uint32_t WAKEUP_ENB : 1; /*!< [22] Wakeup write enable. */
+ uint32_t LPCONFIG : 2; /*!< [24:23] Low-power config. */
+ uint32_t CONFIG : 2; /*!< [26:25] Config. */
+ uint32_t IFMUX : 3; /*!< [29:27] Mux. */
+ uint32_t GP_ENB : 1; /*!< [30] GP write enable. */
+ uint32_t IFMUX_ENB : 1; /*!< [31] Mux write enable. */
+ } FDS0I28;
+ struct _hw_pad_iomux_28fdsoi_hsic
+ {
+ uint32_t DSE : 3; /*!< [2:0] Drive strength. */
+ uint32_t HYS : 1; /*!< [3] Hysteresis. */
+ uint32_t PUS : 2; /*!< [5:4] Pull-up select. */
+ uint32_t PKE : 1; /*!< [6] Pad keeper enable. */
+ uint32_t PUE : 1; /*!< [7] Pull-up enable. */
+ uint32_t _reserved2 : 11; /*!< [18:8] */
+ uint32_t WAKEUP : 3; /*!< [21:19] Wakeup controls. */
+ uint32_t WAKEUP_ENB : 1; /*!< [22] Wakeup write enable. */
+ uint32_t LPCONFIG : 2; /*!< [24:23] Low-power config. */
+ uint32_t CONFIG : 2; /*!< [26:25] Config. */
+ uint32_t IFMUX : 3; /*!< [29:27] Mux. */
+ uint32_t GP_ENB : 1; /*!< [30] GP write enable. */
+ uint32_t IFMUX_ENB : 1; /*!< [31] Mux write enable. */
+ } FDS0I28_HSIC;
+ struct _hw_pad_iomux_28fdsoi_comp
+ {
+ uint32_t COMPEN : 3; /*!< [2:0] Mode. */
+ uint32_t FASTFRZ : 1; /*!< [3] Fast freeze. */
+ uint32_t PSW_OVR : 1; /*!< [4] 2.5 volt override */
+ uint32_t RASRCP : 4; /*!< [8:5] PMOS comp. */
+ uint32_t RASRCN : 4; /*!< [12:9] NMOS comp. */
+ uint32_t NASRC_SEL : 1; /*!< [13] Read NASRC select. */
+ uint32_t COMPOK : 1; /*!< [14] Comp status. */
+ uint32_t NASRC : 4; /*!< [18:15] NASRC value. */
+ uint32_t _reserved2 : 4; /*!< [22:19] */
+ uint32_t LPCONFIG : 2; /*!< [24:23] Low-power config. */
+ uint32_t _reserved3 : 5; /*!< [29:25] */
+ uint32_t GP_ENB : 1; /*!< [30] GP write enable. */
+ uint32_t IFMUX_ENB : 1; /*!< [31] Mux write enable. */
+ } FDS0I28_COMP;
+} hw_pad_iomux_t;
diff --git a/Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt b/Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt
index 4483cc31e531..6e85a14ed8b5 100644
--- a/Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt
+++ b/Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt
@@ -71,6 +71,13 @@ pinctrl-names: The list of names to assign states. List entry 0 defines the
name for integer state ID 0, list entry 1 for state ID 1, and
so on.
+pinctrl-assert-gpios:
+ List of phandles, each pointing at a GPIO which is used by some
+ board design to steer pins between two peripherals on the board.
+ It plays like a board level pin multiplexer to choose different
+ functions for given pins by pulling up/down the GPIOs. See
+ bindings/gpio/gpio.txt for details of how to specify GPIO.
+
For example:
/* For a client device requiring named states */
diff --git a/Documentation/devicetree/bindings/pwm/nxp,tpm-pwm.txt b/Documentation/devicetree/bindings/pwm/nxp,tpm-pwm.txt
new file mode 100644
index 000000000000..ac445a7ceb93
--- /dev/null
+++ b/Documentation/devicetree/bindings/pwm/nxp,tpm-pwm.txt
@@ -0,0 +1,18 @@
+NXP TPM PWM controller
+
+Required properties:
+- compatible: should be "nxp,tpm-pwm"
+- reg: physical base address and length of the controller's registers
+- #pwm-cells: should be 2. See pwm.txt in this directory for a description of
+ the cells format.
+- nxp,pwm-number: the number of PWM devices
+
+Example:
+
+pwm0: tpm@40250000 {
+ compatible = "nxp,tpm-pwm";
+ reg = <0x40250000 0x1000>;
+ nxp,pwm-number = <6>;
+ #pwm-cells = <2>;
+};
+
diff --git a/Documentation/devicetree/bindings/regulator/pfuze100.txt b/Documentation/devicetree/bindings/regulator/pfuze100.txt
index 444c47831a40..24bf4071209f 100644
--- a/Documentation/devicetree/bindings/regulator/pfuze100.txt
+++ b/Documentation/devicetree/bindings/regulator/pfuze100.txt
@@ -3,6 +3,8 @@ PFUZE100 family of regulators
Required properties:
- compatible: "fsl,pfuze100", "fsl,pfuze200", "fsl,pfuze3000"
- reg: I2C slave address
+- fsl,lpsr-mode: some registers need to be saved and restored in lpsr mode
+ for pfuze3000
Required child node:
- regulators: This is the list of child nodes that specify the regulator
diff --git a/Documentation/devicetree/bindings/reset/gpio-reset.txt b/Documentation/devicetree/bindings/reset/gpio-reset.txt
new file mode 100644
index 000000000000..7d45d8b810ea
--- /dev/null
+++ b/Documentation/devicetree/bindings/reset/gpio-reset.txt
@@ -0,0 +1,36 @@
+GPIO reset controller
+=====================
+
+A GPIO reset controller controls a single GPIO that is connected to the reset
+pin of a peripheral IC. Please also refer to reset.txt in this directory for
+common reset controller binding usage.
+
+Required properties:
+- compatible: Should be "gpio-reset"
+- reset-gpios: A gpio used as reset line. The gpio specifier for this property
+ depends on the gpio controller that provides the gpio.
+- #reset-cells: 0, see below
+
+Optional properties:
+- reset-delay-us: delay in microseconds. The gpio reset line will be asserted for
+ this duration to reset.
+- reset-post-delay-ms: delay in milliseconds to wait after reset.
+- initially-in-reset: boolean. If not set, the initial state should be a
+ deasserted reset line. If this property exists, the
+ reset line should be kept in reset.
+
+example:
+
+sii902x_reset: gpio-reset {
+ compatible = "gpio-reset";
+ reset-gpios = <&gpio5 0 GPIO_ACTIVE_LOW>;
+ reset-delay-us = <10000>;
+ initially-in-reset;
+ #reset-cells = <0>;
+};
+
+/* Device with nRESET pin connected to GPIO5_0 */
+sii902x@39 {
+ /* ... */
+ resets = <&sii902x_reset>; /* active-low GPIO5_0, 10 ms delay */
+};
diff --git a/Documentation/devicetree/bindings/rpmsg/imx-rpmsg.txt b/Documentation/devicetree/bindings/rpmsg/imx-rpmsg.txt
new file mode 100644
index 000000000000..c2712d69a59a
--- /dev/null
+++ b/Documentation/devicetree/bindings/rpmsg/imx-rpmsg.txt
@@ -0,0 +1,63 @@
+i.MX RPMSG platform implementations
+
+Required properties:
+- compatible : "fsl,imx7d-rpmsg", "fsl,imx6sx-rpmsg".
+ "fsl,rpmsg-bus", "simple-bus", "fsl,imx8qxp-rpmsg".
+ "fsl,imx8qm-rpmsg".
+- vdev-nums : The number of the remote virtual devices.
+- reg : The reserved DDR phisical memory used to store
+ vring descriptors.
+- multi-core-id: The id number of the remote processors.
+ And it is optional for the legacy platforms, since they
+ only have one remote processors.
+- mub-partition: The partition ID of muB side, that's optional
+ and used on i.mx8qm/8qxp for partition reset. The default
+ value is 3 in driver without this property.
+
+
+=====================================================================
+message unit module for RPMSG
+
+- mu_rpmsg : The message unit module used to do the communications
+ between the asymmetric cores.
+- compatible : "fsl,imx8mq-mu", "fsl,imx6sx-mu", "fsl,imx-mu-rpmsg1".
+ Different mu module would be used by the different remote processor.
+ The "fsl, imx6sx-mu" is used by the first remote processor.
+ The "fsl,imx-mu-rpmsg1" is used by the second remote process.
+- reg : Should contain MU registers location and length.
+- interrupts : interrupt mapping for RPMSG MU IRQ
+- interrupt-parent : A single value that points to the interrupt
+ parent to which the child domain is being mapped.
+ Value must be "&intmux_cm40" or "&intmux_cm41"
+
+Example:
+rpmsg: rpmsg{
+ compatible = "fsl,imx6sx-rpmsg";
+ status = "disabled";
+};
+
+&rpmsg{
+ vdev-nums = <1>;
+ reg = <0xbfff0000 0x10000>;
+ status = "okay";
+};
+
+imx_rpmsg: imx_rpmsg {
+ compatible = "fsl,rpmsg-bus", "simple-bus";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ mu_rpmsg: mu_rpmsg@37440000 {
+ compatible = "fsl,imx6sx-mu";
+ reg = <0x0 0x37440000 0x0 0x10000>;
+ interrupts = <31 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-parent = <&intmux_cm40>;
+ status = "okay";
+ };
+
+ rpmsg: rpmsg{
+ compatible = "fsl,imx8qxp-rpmsg";
+ status = "disabled";
+ };
+};
diff --git a/Documentation/devicetree/bindings/serial/fsl-lpuart.txt b/Documentation/devicetree/bindings/serial/fsl-lpuart.txt
index a1252a047f78..75a93ffa19fc 100644
--- a/Documentation/devicetree/bindings/serial/fsl-lpuart.txt
+++ b/Documentation/devicetree/bindings/serial/fsl-lpuart.txt
@@ -8,14 +8,22 @@ Required properties:
on LS1021A SoC with 32-bit big-endian register organization
- "fsl,imx7ulp-lpuart" for lpuart compatible with the one integrated
on i.MX7ULP SoC with 32-bit little-endian register organization
+ - "fsl,imx8qm-lpuart"for lpuart compatible with the one integrated
+ on i.MX8QM SoC with 32-bit little-endian register organization, which
+ is based on i.MX7ULP lpuart IP but add EEOP new feature.
- reg : Address and length of the register set for the device
- interrupts : Should contain uart interrupt
- clocks : phandle + clock specifier pairs, one for each entry in clock-names
-- clock-names : should contain: "ipg" - the uart clock
+- clock-names : should contain: "ipg" - the uart peripheral register accessing
+ clock source, if "per" clock missing, the "ipg" clock also is the uart module
+ clock.
Optional properties:
- dmas: A list of two dma specifiers, one for each entry in dma-names.
- dma-names: should contain "tx" and "rx".
+- clocks : phandle + clock specifier pairs, one for each entry in clock-names
+- clock-names : "per" - the uart module clock.
+ clock.
Note: Optional properties for DMA support. Write them both or both not.
diff --git a/Documentation/devicetree/bindings/sim/imx_emvsim.txt b/Documentation/devicetree/bindings/sim/imx_emvsim.txt
new file mode 100644
index 000000000000..29efb4a956ff
--- /dev/null
+++ b/Documentation/devicetree/bindings/sim/imx_emvsim.txt
@@ -0,0 +1,22 @@
+* NXP EMVSIM for i.MX8
+
+Required properties:
+- compatible :
+ - "fsl,imx8-emvsim" for EMVSIM compatible with the one integrated on i.MX8 soc
+- reg : address and length of EMVSIM registers
+- interrupt : core interrupt controller
+- clocks : EMVSIM clock specifier
+- power-domains : power domain for EMVSIM
+
+Examples:
+
+emvsim0: sim0@5a0d0000 {
+ compatible = "fsl,imx8-emvsim";
+ reg = <0x0 0x5a0d0000 0x0 0x10000>;
+ interrupts = <GIC_SPI 230 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8QM_EMVSIM0_CLK>,
+ <&clk IMX8QM_EMVSIM0_IPG_CLK>;
+ clock-names = "sim", "ipg";
+ power-domains = <&pd_ldo1_sim>;
+ status = "disabled";
+};
diff --git a/Documentation/devicetree/bindings/sim/imx_sim.txt b/Documentation/devicetree/bindings/sim/imx_sim.txt
new file mode 100644
index 000000000000..58e709b09ae3
--- /dev/null
+++ b/Documentation/devicetree/bindings/sim/imx_sim.txt
@@ -0,0 +1,20 @@
+* NXP SIMv2 for i.MX6ul and i.MX7d
+
+Required properties:
+- compatible :
+ - "fsl,imx7d-sim" for SIMv2 compatible with the one integrated on i.MX7d soc
+ - "fsl,imx6ul-sim" for SIMv2 compatible with the one integrated on i.MX6ul soc
+- reg : address and length of SIMv2 registers
+- interrupt : core interrupt controller
+- clocks : SIMv2 clock specifier
+
+Examples:
+
+sim2: sim@021b4000 {
+ compatible = "fsl,imx6ul-sim";
+ reg = <0x021b4000 0x4000>;
+ interrupts = <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6UL_CLK_SIM2>;
+ clock-names = "sim";
+ status = "disabled";
+};
diff --git a/Documentation/devicetree/bindings/sound/ak4458.txt b/Documentation/devicetree/bindings/sound/ak4458.txt
new file mode 100644
index 000000000000..b9e6eb3b103d
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/ak4458.txt
@@ -0,0 +1,23 @@
+AK4458 audio DAC
+
+This device supports both I2C and SPI modes.
+
+Required properties:
+
+- compatible : "asahi-kasei,ak4458"
+- reg : The I2C address of the device for I2C, the chip select number for SPI.
+- asahi-kasei,pdn-gpios: A GPIO specifier for the GPIO controlling
+ the power down & reset pin.
+- asahi-kasei,mute-gpios: A GPIO specifier for the GPIO controlling
+ the soft mute pin.
+
+Example:
+
+&i2c {
+ ak4458: ak4458@10 {
+ compatible = "asahi-kasei,ak4458";
+ reg = <0x10>;
+ asahi-kasei,pdn-gpios = <&gpio1 10 GPIO_ACTIVE_HIGH>
+ asahi-kasei,mute-gpios = <&gpio1 11 GPIO_ACTIVE_HIGH>
+ };
+};
diff --git a/Documentation/devicetree/bindings/sound/ak4497.txt b/Documentation/devicetree/bindings/sound/ak4497.txt
new file mode 100644
index 000000000000..f1fd59f3c959
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/ak4497.txt
@@ -0,0 +1,23 @@
+AK4497 audio codec
+
+This device supports I2C mode only.
+
+Required properties:
+
+- compatible : "asahi-kasei,ak4497"
+- reg : The I2C address of the device.
+- asahi-kasei,pdn-gpio: A GPIO specifier for the GPIO controlling
+ the power down & reset pin.
+- asahi-kasei,mute-gpio: A GPIO specifier for the GPIO controlling
+ the soft mute pin.
+
+Example:
+
+&i2c {
+ ak4458: ak4458@0x10 {
+ compatible = "asahi-kasei,ak4458";
+ reg = <0x10>;
+ asahi-kasei,pdn-gpios = <&gpio1 10 GPIO_ACTIVE_HIGH>
+ asahi-kasei,mute-gpios = <&gpio1 11 GPIO_ACTIVE_HIGH>
+ };
+};
diff --git a/Documentation/devicetree/bindings/sound/ak5558.txt b/Documentation/devicetree/bindings/sound/ak5558.txt
new file mode 100644
index 000000000000..11b36f9c9fee
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/ak5558.txt
@@ -0,0 +1,20 @@
+AK5558 audio ADC
+
+This device supports I2C mode only.
+
+Required properties:
+
+- compatible : "asahi-kasei,ak5558"
+- reg : The I2C address of the device for I2C.
+- asahi-kasei,pdn-gpios: A GPIO specifier for the GPIO controlling
+ the power down & reset pin.
+
+Example:
+
+&i2c {
+ ak5558: ak5558@10 {
+ compatible = "asahi-kasei,ak5558";
+ reg = <0x10>;
+ asahi-kasei,pdn-gpios = <&gpio1 10 GPIO_ACTIVE_HIGH>;
+ };
+};
diff --git a/Documentation/devicetree/bindings/sound/fsl,acm.txt b/Documentation/devicetree/bindings/sound/fsl,acm.txt
new file mode 100644
index 000000000000..05d224ad18ab
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/fsl,acm.txt
@@ -0,0 +1,18 @@
+NXP Audio Clock Mux (ACM)
+
+The Audio Clock Mux (ACM) is a collection of control registers and multiplexers
+that are used to route the audio source clocks to the audio peripherals.
+Each audio peripheral has its dedicated audio clock mux and control register.
+
+Required properties:
+
+ - compatible : Contains "nxp,imx8qm-acm".
+ - reg : Offset and length of the register set for the device.
+
+Example:
+
+acm: acm@59e00000 {
+ compatible = "nxp,imx8qm-acm";
+ reg = <0x0 0x59e00000 0x0 0x1D0000>;
+ status = "okay";
+};
diff --git a/Documentation/devicetree/bindings/sound/fsl,amix.txt b/Documentation/devicetree/bindings/sound/fsl,amix.txt
new file mode 100644
index 000000000000..d4920e88e466
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/fsl,amix.txt
@@ -0,0 +1,67 @@
+NXP Audio Mixer (AMIX).
+
+The Audio Mixer is a on-chip functional module that allows mixing of two audio
+streams into a single audio stream. Audio Mixer has two input serial audio
+interfaces. These are driven by two Synchronous Audio interface modules (SAI).
+Each input serial interface carries 8 audio channels in its frame in TDM manner.
+Mixer mixes audio samples of corresponding channels from two interfaces into a
+single sample. Before mixing, audio samples of two inputs can be attenuated
+based on configuration. The output of the Audio Mixer is also a serial audio
+interface. Like input interfaces it has the same TDM frame format. This output
+is used to drive the serial DAC TDM interface of audio codec and also sent to
+the external pins along with the receive path of normal audio SAI module for
+readback by the CPU.
+
+The output of Audio mixer can be selected from any of the three streams
+ - serial audio input 1
+ - serial audio input 2
+ - Mixed audio
+
+Mixing operation is independent of audio sample rate but the two audio input
+streams must have same audio sample rate with same number of channels in TDM
+frame to be eligible for mixing.
+
+Device driver required properties:
+=================================
+ - compatible : Compatible list, contains "fsl,imx8qm-amix"
+
+ - reg : Offset and length of the register set for the device.
+
+ - clocks : Must contain an entry for each entry in clock-names.
+
+ - clock-names : Must include the "ipg" for register access.
+
+ - power-domains : Must contain the phandle to the AMIX power domain node
+
+Device driver configuration example:
+======================================
+ amix: amix@59840000 {
+ compatible = "fsl,imx8qm-amix";
+ reg = <0x0 0x59840000 0x0 0x10000>;
+ clocks = <&clk IMX8QXP_AUD_AMIX_IPG>;
+ clock-names = "ipg";
+ power-domains = <&pd_amix>;
+ };
+
+Machine driver required properties:
+===================================
+ - compatible : Compatible list, contains "fsl,imx-audio-amix"
+
+ - model : Short audio card description.
+
+ - dais : Must contain a list of phandles to AMIX connected
+ DAIs. The current implementation requires two phandles
+ to SAI interfaces to be provided, the first SAI in the
+ list being used to route the AMIX output.
+
+ - amix-controller : Must contain the phandle to the AMIX device node.
+
+Machine driver configuration example:
+====================================
+ sound-amix-sai {
+ compatible = "fsl,imx-audio-amix";
+ model = "amix-audio-sai";
+ dais = <&sai4>, <&sai5>;
+ amix-controller = <&amix>;
+ };
+
diff --git a/Documentation/devicetree/bindings/sound/fsl,asrc.txt b/Documentation/devicetree/bindings/sound/fsl,asrc.txt
index 65979b205893..f5116be626c4 100644
--- a/Documentation/devicetree/bindings/sound/fsl,asrc.txt
+++ b/Documentation/devicetree/bindings/sound/fsl,asrc.txt
@@ -8,7 +8,8 @@ three substreams within totally 10 channels.
Required properties:
- - compatible : Contains "fsl,imx35-asrc" or "fsl,imx53-asrc".
+ - compatible : Contains "fsl,imx35-asrc", "fsl,imx53-asrc",
+ "fsl,imx8qm-asrc0" or "fsl,imx8qm-asrc1".
- reg : Offset and length of the register set for the device.
diff --git a/Documentation/devicetree/bindings/sound/fsl,dsp.txt b/Documentation/devicetree/bindings/sound/fsl,dsp.txt
new file mode 100644
index 000000000000..84bc228b4e32
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/fsl,dsp.txt
@@ -0,0 +1,16 @@
+NXP DSP
+
+The IP is from Cadence.
+
+Required properties:
+
+ - compatible : Contains "fsl,imx8qxp-dsp".
+ - reg : Offset and length of the register set for the device.
+
+Example:
+
+dsp: dsp@596e8000 {
+ compatible = "fsl,imx8qxp-dsp";
+ reg = <0x0 0x596e8000 0x0 0x88000>;
+ status = "okay";
+};
diff --git a/Documentation/devicetree/bindings/sound/fsl,esai.txt b/Documentation/devicetree/bindings/sound/fsl,esai.txt
index 21c401e2ccda..30bd18e460d3 100644
--- a/Documentation/devicetree/bindings/sound/fsl,esai.txt
+++ b/Documentation/devicetree/bindings/sound/fsl,esai.txt
@@ -7,8 +7,9 @@ other DSPs. It has up to six transmitters and four receivers.
Required properties:
- - compatible : Compatible list, must contain "fsl,imx35-esai" or
- "fsl,vf610-esai"
+ - compatible : Compatible list, must contain "fsl,imx6ull-esai",
+ "fsl,imx8qxp-v1-esai", "fsl,imx8qm-esai"
+ "fsl,imx35-esai" or "fsl,vf610-esai"
- reg : Offset and length of the register set for the device.
@@ -46,6 +47,10 @@ Required properties:
will be in use as default, or the big endian mode
will be in use for all the device registers.
+ - fsl,dma-buffer-size: It specify the audio buffer size of playback and
+ capture. If this property is absent, using the default value of audio buffer
+ size.
+
Example:
esai: esai@02024000 {
diff --git a/Documentation/devicetree/bindings/sound/fsl,micfil.txt b/Documentation/devicetree/bindings/sound/fsl,micfil.txt
new file mode 100644
index 000000000000..d7830af62062
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/fsl,micfil.txt
@@ -0,0 +1,38 @@
+Freescale MICFIL PDM Interface (MICFIL).
+
+The MICFIL digital interface provides a 16-bit audio signal from a PDM
+microphone bitstream in a configurable output sampling rate.
+
+Required properties:
+
+ - compatible : Compatible list, contains "fsl,imx8mm-micfil"
+
+ - reg : Offset and length of the register set for the device.
+
+ - interrupts : Contains the micfil interrupts.
+
+ - clocks : Must contain an entry for each entry in clock-names.
+
+ - clock-names : Must include the "ipg_clk" for register access and
+ "ipg_clk_app" for internal micfil clock.
+
+ - dmas : Generic dma devicetree binding as described in
+ Documentation/devicetree/bindings/dma/dma.txt.
+
+ - dma-names : One "rx" dma must be configured.
+
+Example:
+micfil: micfil@30080000 {
+ compatible = "fsl,imx8mm-micfil";
+ reg = <0x0 0x30080000 0x0 0x10000>;
+ interrupts = <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8MM_CLK_PDM_IPG>,
+ <&clk IMX8MM_CLK_PDM_ROOT>;
+ clock-names = "ipg_clk", "ipg_clk_app";
+ dmas = <&sdma2 24 26 0x80000000>;
+ dma-names = "rx";
+ status = "disabled";
+};
diff --git a/Documentation/devicetree/bindings/sound/fsl,mqs.txt b/Documentation/devicetree/bindings/sound/fsl,mqs.txt
new file mode 100644
index 000000000000..4e81e902541c
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/fsl,mqs.txt
@@ -0,0 +1,23 @@
+fsl,mqs audio CODEC
+
+Required properties:
+
+ - compatible : must contain one of "fsl,imx6sx-mqs", "fsl,codec-mqs"
+ "fsl,imx8qm-mqs", "fsl,imx8qxp-mqs".
+
+ - clocks : a list of phandles + clock-specifiers, one for each entry in
+ clock-names
+
+ - clock-names : must contain "mclk"
+
+ - gpr : the gpr node.
+
+Example:
+
+mqs: mqs {
+ compatible = "fsl,imx6sx-mqs";
+ gpr = <&gpr>;
+ clocks = <&clks IMX6SX_CLK_SAI1>;
+ clock-names = "mclk";
+ status = "disabled";
+};
diff --git a/Documentation/devicetree/bindings/sound/fsl,rpmsg-i2s.txt b/Documentation/devicetree/bindings/sound/fsl,rpmsg-i2s.txt
new file mode 100644
index 000000000000..27de48eb2519
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/fsl,rpmsg-i2s.txt
@@ -0,0 +1,22 @@
+Freescale rpmsg i2s interface.
+
+The rpmsg i2s is based on RPMSG that used communicating with M4 core,
+which provides a synchronous audio interface that supports fullduplex
+serial interfaces with frame synchronization such as I2S.
+
+Required properties:
+
+ - compatible : Compatible list, contains "fsl,imx7ulp-rpmsg-i2s".
+ "fsl,imx8mq-rpmsg-i2s", "fsl,imx8qxp-rpmsg-i2s"
+ "fsl,imx8qm-rpmsg-i2s"
+
+ - fsl,audioindex : This is an index indicating the audio device index in
+ the M4 side.
+
+Example:
+rpmsg_i2s: rpmsg-i2s {
+ compatible = "fsl,imx7ulp-rpmsg-i2s";
+ /* the audio device index in m4 domain */
+ fsl,audioindex = <0> ;
+ status = "okay";
+};
diff --git a/Documentation/devicetree/bindings/sound/fsl,spdif.txt b/Documentation/devicetree/bindings/sound/fsl,spdif.txt
index 0f97e54c3d43..ff7dc3f9d3fa 100644
--- a/Documentation/devicetree/bindings/sound/fsl,spdif.txt
+++ b/Documentation/devicetree/bindings/sound/fsl,spdif.txt
@@ -6,7 +6,10 @@ a fibre cable.
Required properties:
- - compatible : Compatible list, must contain "fsl,imx35-spdif".
+ - compatible : Compatible list, must contain "fsl,imx35-spdif",
+ "fsl,vf610-spdif", "fsl,imx8qm-spdif",
+ "fsl,imx8qxp-v1-spdif", "fsl,imx8mq-spdif",
+ "fsl,imx8mm-spdif"
- reg : Offset and length of the register set for the device.
@@ -37,6 +40,10 @@ Required properties:
will be in use as default, or the big endian mode
will be in use for all the device registers.
+ - fsl,dma-buffer-size: It specify the audio buffer size of playback and
+ capture. If this property is absent, using the default value of audio buffer
+ size.
+
Example:
spdif: spdif@02004000 {
diff --git a/Documentation/devicetree/bindings/sound/fsl,ssi.txt b/Documentation/devicetree/bindings/sound/fsl,ssi.txt
index d415888e1316..1a61722dc719 100644
--- a/Documentation/devicetree/bindings/sound/fsl,ssi.txt
+++ b/Documentation/devicetree/bindings/sound/fsl,ssi.txt
@@ -64,6 +64,10 @@ Optional properties:
by SOC design. See the notes below.
Only used on Power Architecture.
+- fsl,dma-buffer-size: It specify the audio buffer size of playback and
+ capture. If this property is absent, using the default value of audio buffer
+ size.
+
Child 'codec' node required properties:
- compatible: Compatible list, contains the name of the codec
diff --git a/Documentation/devicetree/bindings/sound/fsl-sai.txt b/Documentation/devicetree/bindings/sound/fsl-sai.txt
index 740b467adf7d..13528e46d05b 100644
--- a/Documentation/devicetree/bindings/sound/fsl-sai.txt
+++ b/Documentation/devicetree/bindings/sound/fsl-sai.txt
@@ -8,7 +8,8 @@ codec/DSP interfaces.
Required properties:
- compatible : Compatible list, contains "fsl,vf610-sai",
- "fsl,imx6sx-sai" or "fsl,imx6ul-sai"
+ "fsl,imx6sx-sai", "fsl,imx6ul-sai",
+ "fsl,imx8qm-sai" or "fsl,imx8mq-sai"
- reg : Offset and length of the register set for the device.
diff --git a/Documentation/devicetree/bindings/sound/imx-audio-ak4458.txt b/Documentation/devicetree/bindings/sound/imx-audio-ak4458.txt
new file mode 100644
index 000000000000..a442d3edd62d
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/imx-audio-ak4458.txt
@@ -0,0 +1,30 @@
+Freescale i.MX audio complex with AK4458 DAC
+
+Required properties:
+
+- compatible : "fsl,imx-audio-ak4458", "fsl,imx-audio-ak4458-mq"
+- model : The user-visible name of this sound complex
+- audio-cpu : The phandle of CPU DAI
+- audio-codec : The phandle of the AK4458 audio DAC
+- audio-routing : A list of the connections between audio components. Each entry
+ is a pair of strings, the first being the connection's sink, the second being
+ the connection's source. Valid names could be power supplies, AK4458 pins,
+ and the jacks on the board.
+
+Example:
+
+sound {
+ compatible = "fsl,imx-audio-ak4458";
+ model = "ak4458-audio";
+ audio-cpu = <&sai1>;
+ audio-codec = <&codec>;
+ audio-routing =
+ "AOUTL1", "Playback",
+ "AOUTR1", "Playback",
+ "AOUTL2", "Playback",
+ "AOUTR2", "Playback",
+ "AOUTL3", "Playback",
+ "AOUTR3", "Playback",
+ "AOUTL4", "Playback",
+ "AOUTR4", "Playback";
+};
diff --git a/Documentation/devicetree/bindings/sound/imx-audio-ak4497.txt b/Documentation/devicetree/bindings/sound/imx-audio-ak4497.txt
new file mode 100644
index 000000000000..7eeeeeda74f5
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/imx-audio-ak4497.txt
@@ -0,0 +1,27 @@
+Freescale i.MX audio complex with AK4497 DAC
+
+Required properties:
+
+- compatible : "fsl,imx-audio-ak4497", "fsl,imx-audio-ak4497-mq"
+- model : The user-visible name of this sound complex
+- audio-cpu : The phandle of CPU DAI
+- audio-codec : The phandle of the ak4497 audio DAC
+- audio-routing : A list of the connections between audio components. Each entry
+ is a pair of strings, the first being the connection's sink, the second being
+ the connection's source. Valid names could be power supplies, ak4497 pins,
+ and the jacks on the board.
+
+Example:
+
+sound {
+ compatible = "fsl,imx-audio-ak4497";
+ model = "ak4497-audio";
+ audio-cpu = <&sai3>;
+ audio-codec = <&codec>;
+ audio-routing =
+ "AOUTLN", "Playback",
+ "AOUTLP", "Playback",
+ "AOUTRN", "Playback",
+ "AOUTRP", "Playback",
+};
+
diff --git a/Documentation/devicetree/bindings/sound/imx-audio-ak5558.txt b/Documentation/devicetree/bindings/sound/imx-audio-ak5558.txt
new file mode 100644
index 000000000000..7b62fbb14f8d
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/imx-audio-ak5558.txt
@@ -0,0 +1,30 @@
+Freescale i.MX audio complex with AK5558 ADC
+
+Required properties:
+
+- compatible : "fsl,imx-audio-ak5558", "fsl,imx-audio-ak5558-mq"
+- model : The user-visible name of this sound complex
+- audio-cpu : The phandle of CPU DAI
+- audio-codec : The phandle of the AK5558 audio ADC
+- audio-routing : A list of the connections between audio components. Each entry
+ is a pair of strings, the first being the connection's sink, the second being
+ the connection's source. Valid names could be power supplies, AK5558 pins,
+ and the jacks on the board.
+
+Example:
+
+sound {
+ compatible = "fsl,imx-audio-ak5558";
+ model = "ak5558-audio";
+ audio-cpu = <&sai1>;
+ audio-codec = <&codec>;
+ audio-routing =
+ "AIN1", "Capture",
+ "AIN2", "Capture",
+ "AIN3", "Capture",
+ "AIN4", "Capture",
+ "AIN5", "Capture",
+ "AIN6", "Capture",
+ "AIN7", "Capture",
+ "AIN8", "Capture";
+};
diff --git a/Documentation/devicetree/bindings/sound/imx-audio-cdnhdmi.txt b/Documentation/devicetree/bindings/sound/imx-audio-cdnhdmi.txt
new file mode 100644
index 000000000000..6d41217dd7be
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/imx-audio-cdnhdmi.txt
@@ -0,0 +1,16 @@
+Freescale i.MX audio complex with Cadence HDMI
+
+Required properties:
+- compatible : "fsl,imx-audio-cdnhdmi", "fsl,imx8mq-evk-cdnhdmi"
+- model : The user-visible name of this sound complex
+- audio-cpu : The phandle of the i.MX SAI controller
+- protocol : 0 is hdmi, 1 is dp.
+
+Example:
+
+sound-hdmi {
+ compatible = "fsl,imx-audio-cdnhdmi";
+ model = "imx-audio-hdmi";
+ audio-cpu = <&sai4>;
+ protocol = <0>;
+};
diff --git a/Documentation/devicetree/bindings/sound/imx-audio-cs42888.txt b/Documentation/devicetree/bindings/sound/imx-audio-cs42888.txt
new file mode 100644
index 000000000000..7e5148f081b3
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/imx-audio-cs42888.txt
@@ -0,0 +1,27 @@
+Freescale i.MX audio complex with CS42888 codec
+
+Required properties:
+- compatible : "fsl,imx-audio-cs42888", or
+ "fsl,imx8qm-sabreauto-cs42888" or
+ "fsl,imx8qxp-sabreauto-cs42888"
+- model : The user-visible name of this sound complex
+- esai-controller : The phandle of the i.MX SSI controller
+- audio-codec : The phandle of the CS42888 audio codec
+
+Optional properties:
+- asrc-controller : The phandle of the i.MX ASRC controller
+- audio-routing : A list of the connections between audio components.
+ Each entry is a pair of strings, the first being the connection's sink,
+ the second being the connection's source. Valid names could be power
+ supplies, CS42888 pins, and the jacks on the board:
+
+Example:
+
+sound {
+ compatible = "fsl,imx6q-sabresd-wm8962",
+ "fsl,imx-audio-wm8962";
+ model = "cs42888-audio";
+ esai-controller = <&esai>;
+ asrc-controller = <&asrc_p2p>;
+ audio-codec = <&codec>;
+};
diff --git a/Documentation/devicetree/bindings/sound/imx-audio-mqs.txt b/Documentation/devicetree/bindings/sound/imx-audio-mqs.txt
new file mode 100644
index 000000000000..10ae15a645d3
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/imx-audio-mqs.txt
@@ -0,0 +1,18 @@
+Freescale i.MX audio complex with mqs codec
+
+Required properties:
+- compatible : "fsl,imx-audio-mqs", "fsl,imx8qm-lpddr4-arm2-mqs", "fsl,imx8qxp-lpddr4-arm2-mqs"
+- model : The user-visible name of this sound complex
+- cpu-dai : The phandle of the i.MX sai controller
+- audio-codec : The phandle of the mqs audio codec
+
+Example:
+
+sound-mqs {
+ compatible = "fsl,imx6sx-sdb-mqs",
+ "fsl,imx-audio-mqs";
+ model = "mqs-audio";
+ cpu-dai = <&sai1>;
+ audio-codec = <&mqs>;
+};
+
diff --git a/Documentation/devicetree/bindings/sound/imx-audio-rpmsg.txt b/Documentation/devicetree/bindings/sound/imx-audio-rpmsg.txt
new file mode 100644
index 000000000000..3f015974ffeb
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/imx-audio-rpmsg.txt
@@ -0,0 +1,13 @@
+Freescale i.MX audio complex with rpmsg devices
+
+Required properties:
+- compatible : "fsl,imx-audio-rpmsg"
+- model : The user-visible name of this sound complex
+- cpu-dai : The phandle of the i.MX rpmsg i2s device.
+
+Example:
+sound-rpmsg {
+ compatible = "fsl,imx-audio-rpmsg";
+ model = "rpmsg-audio";
+ cpu-dai = <&rpmsg_i2s>;
+};
diff --git a/Documentation/devicetree/bindings/sound/imx-audio-si476x.txt b/Documentation/devicetree/bindings/sound/imx-audio-si476x.txt
new file mode 100644
index 000000000000..53cd34afe6b8
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/imx-audio-si476x.txt
@@ -0,0 +1,24 @@
+Freescale i.MX audio complex with si476x codec
+
+Required properties:
+- compatible : "fsl,imx-audio-si476x"
+- model : The user-visible name of this sound complex
+- ssi-controller : The phandle of the i.MX SSI controller
+
+- mux-int-port : The internal port of the i.MX audio muxer (AUDMUX)
+- mux-ext-port : The external port of the i.MX audio muxer
+
+Note: The AUDMUX port numbering should start at 1, which is consistent with
+hardware manual.
+
+Example:
+
+sound {
+ compatible = "fsl,imx-audio-si476x",
+ "fsl,imx-tuner-si476x";
+ model = "imx-radio-si476x";
+
+ ssi-controller = <&ssi1>;
+ mux-int-port = <2>;
+ mux-ext-port = <5>;
+};
diff --git a/Documentation/devicetree/bindings/sound/imx-audio-wm8524.txt b/Documentation/devicetree/bindings/sound/imx-audio-wm8524.txt
new file mode 100644
index 000000000000..b3e3c01464bd
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/imx-audio-wm8524.txt
@@ -0,0 +1,29 @@
+Freescale i.MX audio complex with WM8524 codec
+
+Required properties:
+
+ - compatible : "fsl,imx-audio-wm8524"
+
+ - model : The user-visible name of this sound complex
+
+ - audio-cpu : The phandle of CPU DAI
+
+ - audio-codec : The phandle of the WM8962 audio codec
+
+ - audio-routing : A list of the connections between audio components.
+ Each entry is a pair of strings, the first being the
+ connection's sink, the second being the connection's
+ source. Valid names could be power supplies, WM8524
+ pins, and the jacks on the board:
+
+Example:
+
+sound {
+ compatible = "fsl,imx-audio-wm8524";
+ model = "wm8524-audio";
+ audio-cpu = <&sai2>;
+ audio-codec = <&codec>;
+ audio-routing =
+ "Line Out Jack", "LINEVOUTL",
+ "Line Out Jack", "LINEVOUTR";
+};
diff --git a/Documentation/devicetree/bindings/sound/imx-audio-wm8960.txt b/Documentation/devicetree/bindings/sound/imx-audio-wm8960.txt
new file mode 100644
index 000000000000..dd153b5df3f3
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/imx-audio-wm8960.txt
@@ -0,0 +1,68 @@
+Freescale i.MX audio complex with WM8960 codec
+
+Required properties:
+
+ - compatible : "fsl,imx-audio-wm8960", "fsl,imx7d-evk-wm8960"
+
+ - model : The user-visible name of this sound complex
+
+ - cpu-dai : The phandle of CPU DAI
+
+ - audio-codec : The phandle of the WM8960 audio codec
+
+ - audio-routing : A list of the connections between audio components.
+ Each entry is a pair of strings, the first being the
+ connection's sink, the second being the connection's
+ source. Valid names could be power supplies, WM8960
+ pins, and the jacks on the board:
+
+ Power supplies:
+ * Mic Bias
+
+ Board connectors:
+ * Mic Jack
+ * Headphone Jack
+ * Ext Spk
+
+Optional properties:
+- hp-det-gpios : The gpio pin to detect plug in/out event that happens to
+ Headphone jack.
+- mic-det-gpios: The gpio pin to detect plug in/out event that happens to
+ Microphone jack.
+
+Example:
+
+ sound: sound {
+ compatible = "fsl,imx7d-evk-wm8960",
+ "fsl,imx-audio-wm8960";
+ model = "wm8960-audio";
+ cpu-dai = <&sai1>;
+ audio-codec = <&wm8960>;
+ codec-master;
+ /*
+ * hp-det = <hp-det-pin hp-det-polarity>;
+ * hp-det-pin: JD1 JD2 or JD3
+ * hp-det-polarity = 0: hp detect high for headphone
+ * hp-det-polarity = 1: hp detect high for speaker
+ */
+ hp-det = <2 0>;
+ hp-det-gpios = <&gpio1 0 0>;
+ mic-det-gpios = <&gpio1 0 0>;
+ audio-routing =
+ "Headphone Jack", "HP_L",
+ "Headphone Jack", "HP_R",
+ "Ext Spk", "SPK_LP",
+ "Ext Spk", "SPK_LN",
+ "Ext Spk", "SPK_RP",
+ "Ext Spk", "SPK_RN",
+ "LINPUT2", "Mic Jack",
+ "LINPUT3", "Mic Jack",
+ "RINPUT1", "Main MIC",
+ "RINPUT2", "Main MIC",
+ "Mic Jack", "MICB",
+ "Main MIC", "MICB",
+ "CPU-Playback", "ASRC-Playback",
+ "Playback", "CPU-Playback",
+ "ASRC-Capture", "CPU-Capture",
+ "CPU-Capture", "Capture";
+ };
diff --git a/Documentation/devicetree/bindings/sound/imx-audio-wm8962.txt b/Documentation/devicetree/bindings/sound/imx-audio-wm8962.txt
index acea71bee34f..06bc12d4cc76 100644
--- a/Documentation/devicetree/bindings/sound/imx-audio-wm8962.txt
+++ b/Documentation/devicetree/bindings/sound/imx-audio-wm8962.txt
@@ -6,7 +6,7 @@ Required properties:
- model : The user-visible name of this sound complex
- - ssi-controller : The phandle of the i.MX SSI controller
+ - cpu-dai : The phandle of CPU DAI
- audio-codec : The phandle of the WM8962 audio codec
@@ -31,13 +31,19 @@ Required properties:
Note: The AUDMUX port numbering should start at 1, which is consistent with
hardware manual.
+Optional properties:
+- hp-det-gpios : The gpio pin to detect plug in/out event that happens to
+ Headphone jack.
+- mic-det-gpios: The gpio pin to detect plug in/out event that happens to
+ Microphone jack.
+
Example:
sound {
compatible = "fsl,imx6q-sabresd-wm8962",
"fsl,imx-audio-wm8962";
model = "wm8962-audio";
- ssi-controller = <&ssi2>;
+ cpu-dai = <&ssi2>;
audio-codec = <&codec>;
audio-routing =
"Headphone Jack", "HPOUTL",
@@ -50,4 +56,6 @@ sound {
"DMICDAT", "DMIC";
mux-int-port = <2>;
mux-ext-port = <3>;
+ hp-det-gpios = <&gpio7 8 1>;
+ mic-det-gpios = <&gpio1 9 1>;
};
diff --git a/Documentation/devicetree/bindings/sound/imx-audio-xtor.txt b/Documentation/devicetree/bindings/sound/imx-audio-xtor.txt
new file mode 100644
index 000000000000..ed55891bca96
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/imx-audio-xtor.txt
@@ -0,0 +1,30 @@
+Freescale i.MX audio complex with Freescale DAI transceiver.
+Currently supports Freescale SAI or ESAI digital audio interface.
+
+Required properties:
+
+ - compatible : "fsl,imx-audio-xtor"
+
+ - model : The user-visible name of this sound complex
+
+ - cpu-dai : The phandle of the i.MX DAI, currently supports
+ SAI or ESAI controller
+
+Optional properties:
+
+ - asrc-controller : The phandle of the i.MX ASRC controller associated with DAI.
+
+Examples:
+
+sound-xtor-sai {
+ compatible = "fsl,imx-audio-xtor";
+ model = "xtor-audio-sai";
+ cpu-dai = <&sai0>;
+ asrc-controller = <&asrc0>;
+};
+
+sound-xtor-esai {
+ compatible = "fsl,imx-audio-xtor";
+ model = "xtor-audio-esai";
+ cpu-dai = <&esai0>;
+};
diff --git a/Documentation/devicetree/bindings/sound/imx-pdm-mic.txt b/Documentation/devicetree/bindings/sound/imx-pdm-mic.txt
new file mode 100644
index 000000000000..bde8313cba7e
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/imx-pdm-mic.txt
@@ -0,0 +1,16 @@
+Freescale i.MX audio complex PDM microphone
+
+Required properties:
+- compatible: "fsl,imx-pdm-mic"
+- model: The user-visible name of this sound complex
+- audio-cpu : The phandle of the i.MX SAI controller
+- decimation : The PDM decimation factor <64>
+
+Example:
+
+sound-pdm {
+ compatible = "fsl,imx-pdm-mic";
+ model = "imx-pdm-audio";
+ audio-cpu = <&sai3>;
+ decimation = <64>;
+};
diff --git a/Documentation/devicetree/bindings/sound/wm8962.txt b/Documentation/devicetree/bindings/sound/wm8962.txt
index 7f82b59ec8f9..d15b9c82fd15 100644
--- a/Documentation/devicetree/bindings/sound/wm8962.txt
+++ b/Documentation/devicetree/bindings/sound/wm8962.txt
@@ -13,6 +13,14 @@ Optional properties:
of R51 (Class D Control 2) gets set, indicating that the speaker is
in mono mode.
+ - amic-mono: This is a boolean property. If present, indicating that the
+ analog micphone is hardware mono input, the driver would enable monomix
+ for it.
+
+ - dmic-mono: This is a boolean property. If present, indicating that the
+ digital micphone is hardware mono input, the driver would enable monomix
+ for it.
+
- mic-cfg : Default register value for R48 (Additional Control 4).
If absent, the default should be the register default.
diff --git a/Documentation/devicetree/bindings/spi/fsl-imx-cspi.txt b/Documentation/devicetree/bindings/spi/fsl-imx-cspi.txt
index 5bf13960f7f4..6b75a72d51fa 100644
--- a/Documentation/devicetree/bindings/spi/fsl-imx-cspi.txt
+++ b/Documentation/devicetree/bindings/spi/fsl-imx-cspi.txt
@@ -19,6 +19,8 @@ See the clock consumer binding,
Documentation/devicetree/bindings/clock/clock-bindings.txt
- dmas: DMA specifiers for tx and rx dma. See the DMA client binding,
Documentation/devicetree/bindings/dma/dma.txt
+ For the description of the second cell of dma phandle, see this document,
+ Documentation/devicetree/bindings/dma/fsl-imx-sdma.txt
- dma-names: DMA request names should include "tx" and "rx" if present.
Obsolete properties:
diff --git a/Documentation/devicetree/bindings/spi/spi-fsl-lpspi.txt b/Documentation/devicetree/bindings/spi/spi-fsl-lpspi.txt
index 225ace1d0c65..9e44d85e0a68 100644
--- a/Documentation/devicetree/bindings/spi/spi-fsl-lpspi.txt
+++ b/Documentation/devicetree/bindings/spi/spi-fsl-lpspi.txt
@@ -7,6 +7,8 @@ Required properties:
- interrupt-parent : core interrupt controller
- interrupts : lpspi interrupt
- clocks : lpspi clock specifier
+- spi-slave : spi slave mode support. In slave mode, add this attribute without
+ value. In master mode, remove it.
Examples:
@@ -16,4 +18,5 @@ lpspi2: lpspi@40290000 {
interrupt-parent = <&intc>;
interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clks IMX7ULP_CLK_LPSPI2>;
+ spi-slave;
};
diff --git a/Documentation/devicetree/bindings/thermal/imx-sc-thermal.txt b/Documentation/devicetree/bindings/thermal/imx-sc-thermal.txt
new file mode 100644
index 000000000000..290e3bc3c4af
--- /dev/null
+++ b/Documentation/devicetree/bindings/thermal/imx-sc-thermal.txt
@@ -0,0 +1,17 @@
+* IMX8QM/QXP SoC Temperature Sensor
+
+Required properties:
+- compatible :
+- "nxp,imx8qm-sc-tsens"
+- "nxp,imx8qxp-sc-tsens"
+
+- reg: Address range of the thermal registers
+- #thermal-sensor-cells : Should be 1. See ./thermal.txt for a description.
+- tsens-num: the number of temp sensor on this SOC.
+
+Example:
+tsens: thermal-sensor@ {
+ compatible = "nxp,imx8qm-sc-tsens";
+ tsens-num = <5>;
+ #thermal-sensor-cells = <1>;
+};
diff --git a/Documentation/devicetree/bindings/thermal/imx8mm-thermal.txt b/Documentation/devicetree/bindings/thermal/imx8mm-thermal.txt
new file mode 100644
index 000000000000..4a9d0c5d9ae0
--- /dev/null
+++ b/Documentation/devicetree/bindings/thermal/imx8mm-thermal.txt
@@ -0,0 +1,17 @@
+* Temperature Monitor (TMU) on Freescale i.MX8MM SoCs
+
+Required properties:
+- compatible : "fsl,imx8mm-tmu"
+- reg: Address and length of the register
+- clocks : thermal sensor's clock source.
+- #thermal-sensor-cells : Should be 0. See ./thermal.txt for a description.
+Example:
+
+tmu: tmu@0x30260000 {
+ compatible = "fsl,imx8mm-tmu";
+ reg = <0x0 0x30260000 0x0 0x10000>;
+ clocks = <&clk IMX8MM_CLK_TMU_ROOT>;
+ interrupts = <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>;
+ #thermal-sensor-cells = <0>;
+};
+
diff --git a/Documentation/devicetree/bindings/trivial-devices.txt b/Documentation/devicetree/bindings/trivial-devices.txt
index af284fbd4d23..0fd6f2c0e79e 100644
--- a/Documentation/devicetree/bindings/trivial-devices.txt
+++ b/Documentation/devicetree/bindings/trivial-devices.txt
@@ -56,6 +56,9 @@ domintech,dmard10 DMARD10: 3-axis Accelerometer
epson,rx8010 I2C-BUS INTERFACE REAL TIME CLOCK MODULE
epson,rx8025 High-Stability. I2C-Bus INTERFACE REAL TIME CLOCK MODULE
epson,rx8581 I2C-BUS INTERFACE REAL TIME CLOCK MODULE
+fsl,fxas2100x FXAS2100X: Gyroscope sensor
+fsl,fxos8700 FXOS8700: Accelerometer + Magnetometer Combo
+fsl,isl29023 ISL29023: Intersil ISL29023 ambient light sensor
fsl,mag3110 MAG3110: Xtrinsic High Accuracy, 3D Magnetometer
fsl,mc13892 MC13892: Power Management Integrated Circuit (PMIC) for i.MX35/51
fsl,mma7660 MMA7660FC: 3-Axis Orientation/Motion Detection Sensor
diff --git a/Documentation/devicetree/bindings/usb/cdns-usb3.txt b/Documentation/devicetree/bindings/usb/cdns-usb3.txt
new file mode 100644
index 000000000000..13daee1b053b
--- /dev/null
+++ b/Documentation/devicetree/bindings/usb/cdns-usb3.txt
@@ -0,0 +1,39 @@
+* Cadence USB3 Controller
+
+Required properties:
+- compatible: "Cadence,usb3";
+- reg: base address and length of the registers
+- interrupts: interrupt for the USB controller
+- interrupt-parent: the interrupt parent for this module
+- clocks: reference to the USB clock
+- clock-names: the name of clocks
+- cdns3,usbphy: reference to the USB PHY
+
+Optional properties:
+- dr_mode: One of "host", "peripheral" or "otg". Defaults to "otg"
+- extcon: extcon phandler for cdns3 device
+- power-domains: the power domain for cdns3 controller and phy
+
+Examples:
+
+usbotg3: cdns3@5b110000 {
+ compatible = "Cadence,usb3";
+ reg = <0x0 0x5B110000 0x0 0x10000>,
+ <0x0 0x5B130000 0x0 0x10000>,
+ <0x0 0x5B140000 0x0 0x10000>,
+ <0x0 0x5B160000 0x0 0x40000>;
+ interrupt-parent = <&gic>;
+ interrupts = <GIC_SPI 271 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8QM_USB3_LPM_CLK>,
+ <&clk IMX8QM_USB3_BUS_CLK>,
+ <&clk IMX8QM_USB3_ACLK>,
+ <&clk IMX8QM_USB3_IPG_CLK>,
+ <&clk IMX8QM_USB3_CORE_PCLK>;
+ clock-names = "usb3_lpm_clk", "usb3_bus_clk", "usb3_aclk",
+ "usb3_ipg_clk", "usb3_core_pclk";
+ power-domains = <&pd_conn_usb2>;
+ cdns3,usbphy = <&usbphynop1>;
+ dr_mode = "otg";
+ extcon = <&typec_ptn5150>;
+ status = "disabled";
+};
diff --git a/Documentation/devicetree/bindings/usb/ci-hdrc-usb2.txt b/Documentation/devicetree/bindings/usb/ci-hdrc-usb2.txt
index 0e03344e2e8b..1c06710fa915 100644
--- a/Documentation/devicetree/bindings/usb/ci-hdrc-usb2.txt
+++ b/Documentation/devicetree/bindings/usb/ci-hdrc-usb2.txt
@@ -10,6 +10,9 @@ Required properties:
"fsl,imx6sx-usb"
"fsl,imx6ul-usb"
"fsl,imx7d-usb"
+ "fsl,imx7ulp-usb"
+ "fsl,imx8qm-usb"
+ "fsl,imx8mm-usb"
"lsi,zevio-usb"
"qcom,ci-hdrc"
"chipidea,usb2"
@@ -76,6 +79,8 @@ Optional properties:
needs to make sure it does not send more than 90%
maximum_periodic_data_per_frame. The use case is multiple transactions, but
less frame rate.
+- ci-disable-lpm: Some chipidea hardware need to disable low power mode
+- phy-charger-detection: enable USB PHY charger detection function
i.mx specific properties
- fsl,usbmisc: phandler of non-core register device, with one
@@ -84,8 +89,28 @@ i.mx specific properties
- over-current-active-high: over current signal polarity is high active,
typically over current signal polarity is low active.
- external-vbus-divider: enables off-chip resistor divider for Vbus
+- imx6-usb-charger-detection: enable imx6 usb charger detect function,
+ only set it when the user wants SoC usb charger detection capabilities.
+ If the user wants to use charger IC's usb charger detection capabilities,
+ please do not set it.
+- fsl,anatop: phandle for anatop module, anatop module is only existed
+ at imx6 SoC series.
+- pinctrl-names: for names of hsic pin group
+- pinctrl-0: hsic "idle" pin group
+- pinctrl-1: hsic "active" pin group
+- osc-clkgate-delay: the delay between powering up the xtal 24MHz clock
+ and release the clock to the digital logic inside the analog block,
+ 0 <= osc-clkgate-delay <= 7.
+- power-polarity-active-high: add this property if port power function of ehci
+ is used to enable vbus, and the vbus power supply chip enable signal is high
+ active.
+- picophy,pre-emp-curr-control: picophy is used for imx7d and imx845.
+ HS Treansmitter Pre-Emphasis Current Control may need to tune for USB signal
+ See USBNC_n_PHY_CFG1 for detail.
+- picophy,dc-vol-level-adjust: HS DC Voltage Level Adjustment may need to
+ turn for USB signal, see USBNC_n_PHY_CFG1 for detail.
-Example:
+Examples:
usb@f7ed0000 {
compatible = "chipidea,usb2";
@@ -103,3 +128,21 @@ Example:
extcon = <0>, <&usb_id>;
phy-clkgate-delay-us = <400>;
};
+
+ usb@02184000 { /* USB OTG */
+ compatible = "fsl,imx6q-usb", "fsl,imx27-usb";
+ reg = <0x02184000 0x200>;
+ interrupts = <0 43 0x04>;
+ fsl,usbphy = <&usbphy1>;
+ fsl,usbmisc = <&usbmisc 0>;
+ disable-over-current;
+ external-vbus-divider;
+ imx6-usb-charger-detection;
+ fsl,anatop = <&anatop>;
+ pinctrl-names = "idle", "active";
+ pinctrl-0 = <&pinctrl_usbh2_1>;
+ pinctrl-1 = <&pinctrl_usbh2_2>;
+ osc-clkgate-delay = <0x3>;
+ maximum-speed = "full-speed";
+ tpl-support;
+ };
diff --git a/Documentation/devicetree/bindings/usb/dwc3.txt b/Documentation/devicetree/bindings/usb/dwc3.txt
index 44e8bab159ad..681bcd9590b6 100644
--- a/Documentation/devicetree/bindings/usb/dwc3.txt
+++ b/Documentation/devicetree/bindings/usb/dwc3.txt
@@ -57,6 +57,9 @@ Optional properties:
- snps,quirk-frame-length-adjustment: Value for GFLADJ_30MHZ field of GFLADJ
register for post-silicon frame length adjustment when the
fladj_30mhz_sdbnd signal is invalid or incorrect.
+- snps,power-down-scale: Value for number of scale(16kHz) of suspend clock if
+ the default value is not correct, valid range is 2~8000, means suspend
+ clock is from 32KHz to 125MHz.
- <DEPRECATED> tx-fifo-resize: determines if the FIFO *has* to be reallocated.
diff --git a/Documentation/devicetree/bindings/usb/typec-tcpci.txt b/Documentation/devicetree/bindings/usb/typec-tcpci.txt
new file mode 100644
index 000000000000..7ef2167ba767
--- /dev/null
+++ b/Documentation/devicetree/bindings/usb/typec-tcpci.txt
@@ -0,0 +1,40 @@
+TCPCI(Typec port cotroller interface) binding
+---------------------------------------------
+
+Required properties:
+- compatible: should be "usb,tcpci".
+- reg: the i2c slave address of typec port controller device.
+- interrupt-parent: the phandle to the interrupt controller which provides
+ the interrupt.
+- interrupts: interrupt specification for tcpci alert.
+- port-type: typec port type.
+- default-role: preferred power role if port type is "drp".
+
+Required properties only for power source or drp:
+- src-pdos
+
+Required properties only for power sink or drp:
+- snk-pdos
+- max-snk-mv
+- max-snk-ma
+- op-snk-mw
+
+Optional properties:
+- sink-disable: disable vbus sink in sink role in case we only can be source
+ for power but need dual data role.
+
+Example:
+
+ptn5110@50 {
+ compatible = "usb,tcpci";
+ reg = <0x50>;
+ interrupt-parent = <&gpio3>;
+ interrupts = <3 IRQ_TYPE_LEVEL_LOW>;
+ port-type = "drp";
+ default-role = "sink";
+ src-pdos = <0x380190c8>;
+ snk-pdos = <0x380190c8 0x3802d0c8>;
+ max-snk-mv = <9000>;
+ max-snk-ma = <1000>;
+ op-snk-mw = <9000>;
+};
diff --git a/Documentation/devicetree/bindings/usb/typec.txt b/Documentation/devicetree/bindings/usb/typec.txt
new file mode 100644
index 000000000000..f1339dce5978
--- /dev/null
+++ b/Documentation/devicetree/bindings/usb/typec.txt
@@ -0,0 +1,50 @@
+Generic typec and power delivery properties
+-------------------------------------------
+
+Required properties:
+- port-type: should be one of "drp", "dfp" or "ufp".
+- default-role: preferred power role if drp, should be "sink" or "source".
+- src-pdos: An array of u32 with each entry providing supported power
+ source data object(PDO), the detailed bit definitions of
+ PDO can be found in "Universal Serial Bus Power Delivery
+ Specification" chapter 6.4.1.2 Source_Capabilities Message,
+ the order of each entry(PDO) should follow the PD spec chapter
+ 6.4.1. Required only for power source and power dual role with
+ power delivery support.
+- snk-pdos: An array of u32 with each entry providing supported power
+ sink data object(PDO), the detailed bit definitions of PDO
+ can be found in "Universal Serial Bus Power Delivery
+ Specification" chapter 6.4.1.3 Sink Capabilities Message,
+ the order of each entry(PDO) should follow the PD spec chapter
+ 6.4.1. Required only for power sink and power dual role with
+ power delivery support.
+- max-snk-mv: The max voltage the sink can support in millivoltage, required
+ only for power sink and power dual role with power delivery
+ support.
+- max-snk-ma: The max current the sink can support in milliampere, required
+ only for power sink and power dual role with power delivery
+ support.
+- op-snk-mw: Sink required operating power in milliwatts, if source offered
+ power is less then it, Capability Mismatch is set, required
+ only for power sink and power dual role with power delivery
+ support.
+- max-snk-mw: The max power the sink can support in milliwatts, required
+ for power sink and power dual role with power delivery support,
+ power sink needs this property to get the max current based on
+ the selected PDO.
+
+Example:
+
+ptn5110@50 {
+ compatible = "usb,tcpci";
+ reg = <0x50>;
+ interrupt-parent = <&gpio3>;
+ interrupts = <3 IRQ_TYPE_LEVEL_LOW>;
+ port-type = "drp";
+ default-role = "sink";
+ src-pdos = <0x380190c8>;
+ snk-pdos = <0x380190c8 0x3802d0c8>;
+ max-snk-mv = <9000>;
+ max-snk-ma = <1000>;
+ op-snk-mw = <9000>;
+};
diff --git a/Documentation/devicetree/bindings/usb/usb-xhci.txt b/Documentation/devicetree/bindings/usb/usb-xhci.txt
index 7a69b8b47b97..050ed02bb33a 100644
--- a/Documentation/devicetree/bindings/usb/usb-xhci.txt
+++ b/Documentation/devicetree/bindings/usb/usb-xhci.txt
@@ -29,6 +29,8 @@ Optional properties:
- clocks: reference to a clock
- usb3-lpm-capable: determines if platform is USB3 LPM capable
- quirk-broken-port-ped: set if the controller has broken port disable mechanism
+ - usb3-resume-missing-cas: set if the CAS(Cold Attach Status) may lose in case
+ device plugged in while system sleep.
Example:
usb@f0931000 {
diff --git a/Documentation/devicetree/bindings/usb/usbmisc-imx.txt b/Documentation/devicetree/bindings/usb/usbmisc-imx.txt
index f1e27faf528e..fe37ac11e873 100644
--- a/Documentation/devicetree/bindings/usb/usbmisc-imx.txt
+++ b/Documentation/devicetree/bindings/usb/usbmisc-imx.txt
@@ -7,6 +7,8 @@ Required properties:
"fsl,vf610-usbmisc" for Vybrid vf610
"fsl,imx6sx-usbmisc" for imx6sx
"fsl,imx7d-usbmisc" for imx7d
+ "fsl,imx6ul-usbmisc" for imx6ul
+ "fsl,imx7ulp-usbmisc" for imx7ulp
- reg: Should contain registers location and length
Examples:
diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt
index f4a98c85340a..d8eac2dcfaa7 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.txt
+++ b/Documentation/devicetree/bindings/vendor-prefixes.txt
@@ -165,6 +165,7 @@ isee ISEE 2007 S.L.
isil Intersil
issi Integrated Silicon Solutions Inc.
itead ITEAD Intelligent Systems Co.Ltd
+ite ITE Tech. Inc.
iwave iWave Systems Technologies Pvt. Ltd.
jdi Japan Display Inc.
jedec JEDEC Solid State Technology Association
@@ -210,6 +211,7 @@ micron Micron Technology Inc.
minix MINIX Technology Ltd.
miramems MiraMEMS Sensing Technology Co., Ltd.
mitsubishi Mitsubishi Electric Corporation
+mixel Mixel, Inc.
mosaixtech Mosaix Technologies, Inc.
motorola Motorola, Inc.
moxa Moxa Inc.
@@ -239,6 +241,7 @@ nordic Nordic Semiconductor
nuvoton Nuvoton Technology Corporation
nvd New Vision Display
nvidia NVIDIA
+nwl Northwest Logic
nxp NXP Semiconductors
okaya Okaya Electric America, Inc.
oki Oki Electric Industry Co., Ltd.
diff --git a/Documentation/devicetree/bindings/watchdog/fsl-imx-wdt.txt b/Documentation/devicetree/bindings/watchdog/fsl-imx-wdt.txt
index 107280ef0025..10771fbf9c63 100644
--- a/Documentation/devicetree/bindings/watchdog/fsl-imx-wdt.txt
+++ b/Documentation/devicetree/bindings/watchdog/fsl-imx-wdt.txt
@@ -5,6 +5,9 @@ Required properties:
- reg : Should contain WDT registers location and length
- interrupts : Should contain WDT interrupt
+For imx8-wdt, it's a software watchdog which implemented by timer tick
+in SCFW. In this case, only compatible name required.
+
Optional properties:
- big-endian: If present the watchdog device's registers are implemented
in big endian mode, otherwise in native mode(same with CPU), for more
diff --git a/Documentation/gpu/drm-kms.rst b/Documentation/gpu/drm-kms.rst
index 307284125d7a..fab8a6080386 100644
--- a/Documentation/gpu/drm-kms.rst
+++ b/Documentation/gpu/drm-kms.rst
@@ -508,6 +508,12 @@ Standard Connector Properties
.. kernel-doc:: drivers/gpu/drm/drm_connector.c
:doc: standard connector properties
+HDMI Specific Connector Properties
+-----------------------------
+
+.. kernel-doc:: drivers/gpu/drm/drm_connector.c
+ :doc: HDMI connector properties
+
Plane Composition Properties
----------------------------
diff --git a/Documentation/gpu/kms-properties.csv b/Documentation/gpu/kms-properties.csv
index 927b65e14219..2e748d76041f 100644
--- a/Documentation/gpu/kms-properties.csv
+++ b/Documentation/gpu/kms-properties.csv
@@ -18,6 +18,7 @@ Owner Module/Drivers,Group,Property Name,Type,Property Values,Object attached,De
,Virtual GPU,“suggested X”,RANGE,"Min=0, Max=0xffffffff",Connector,property to suggest an X offset for a connector
,,“suggested Y”,RANGE,"Min=0, Max=0xffffffff",Connector,property to suggest an Y offset for a connector
,Optional,"""aspect ratio""",ENUM,"{ ""None"", ""4:3"", ""16:9"" }",Connector,TDB
+,Optional,"""content type""",ENUM,"{ ""No Data"", ""Graphics"", ""Photo"", ""Cinema"", ""Game"" }",Connector,TBD
i915,Generic,"""Broadcast RGB""",ENUM,"{ ""Automatic"", ""Full"", ""Limited 16:235"" }",Connector,"When this property is set to Limited 16:235 and CTM is set, the hardware will be programmed with the result of the multiplication of CTM by the limited range matrix to ensure the pixels normaly in the range 0..1.0 are remapped to the range 16/255..235/255."
,,“audio”,ENUM,"{ ""force-dvi"", ""off"", ""auto"", ""on"" }",Connector,TBD
,SDVO-TV,“mode”,ENUM,"{ ""NTSC_M"", ""NTSC_J"", ""NTSC_443"", ""PAL_B"" } etc.",Connector,TBD
diff --git a/Documentation/usb/chipidea.txt b/Documentation/usb/chipidea.txt
index edf7cdfddc88..2b0c435f4cc9 100644
--- a/Documentation/usb/chipidea.txt
+++ b/Documentation/usb/chipidea.txt
@@ -32,7 +32,10 @@ cat /sys/kernel/debug/ci_hdrc.0/registers
B-device should take host role and enumrate A-device.
4) A-device switch back to host.
- On B-device:
+ On A-device:
+ echo 1 > /sys/bus/platform/devices/ci_hdrc.0/inputs/a_bus_req
+
+ or, on B-device:
echo 0 > /sys/bus/platform/devices/ci_hdrc.0/inputs/b_bus_req
or, by introducing HNP polling, B-Host can know when A-peripheral wish
@@ -74,6 +77,14 @@ cat /sys/kernel/debug/ci_hdrc.0/registers
"On-The-Go and Embedded Host Supplement to the USB Revision 2.0 Specification
July 27, 2012 Revision 2.0 version 1.1a"
+1.4 OTG compliance test
+----------------------
+Only below 3 popular gadget drivers are declared to be USB OTG and EH 2.0
+compliant(with otg descriptor comply with USB OTG and EH 2.0 as a peripheral):
+- mass storage
+- ether
+- serial
+
2. How to enable USB as system wakeup source
-----------------------------------
Below is the example for how to enable USB as system wakeup source
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index cf69aab648fb..60f2424db339 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1195,6 +1195,16 @@ config ARM_ERRATA_825619
DMB NSHST or DMB ISHST instruction followed by a mix of Cacheable
and Device/Strongly-Ordered loads and stores might cause deadlock
+config ARM_ERRATA_814220
+ bool "ARM errata: Cache maintenance by set/way operations can execute out of order"
+ depends on CPU_V7
+ help
+ The v7 ARM states that all cache and branch predictor maintenance operations
+ that do not specify an address execute, relative to each other, in program order.
+ However, because of this erratum, an L2 set/way cache maintenance operation can
+ overtake an L1 set/way cache maintenance operation. This ERRATA only affected the
+ Cortex-A7 and present in r0p2, r0p3, r0p4, r0p5.
+
config ARM_ERRATA_852421
bool "ARM errata: A17: DMB ST might fail to create order between stores"
depends on CPU_V7
@@ -1729,6 +1739,7 @@ config FORCE_MAX_ZONEORDER
int "Maximum zone order"
default "12" if SOC_AM33XX
default "9" if SA1111 || ARCH_EFM32
+ default "14" if ARCH_MXC
default "11"
help
The kernel memory allocator divides physically contiguous memory
diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug
index b14f154919a5..b7dac0b03b37 100644
--- a/arch/arm/Kconfig.debug
+++ b/arch/arm/Kconfig.debug
@@ -415,6 +415,13 @@ choice
Say Y here if you want kernel low-level debugging support
on i.MX6SL.
+ config DEBUG_IMX6SLL_UART
+ bool "i.MX6SLL Debug UART"
+ depends on SOC_IMX6SLL
+ help
+ Say Y here if you want kernel low-level debugging support
+ on i.MX6SLL.
+
config DEBUG_IMX6SX_UART
bool "i.MX6SX Debug UART"
depends on SOC_IMX6SX
@@ -1447,6 +1454,7 @@ config DEBUG_LL_INCLUDE
DEBUG_IMX53_UART ||\
DEBUG_IMX6Q_UART || \
DEBUG_IMX6SL_UART || \
+ DEBUG_IMX6SLL_UART || \
DEBUG_IMX6SX_UART || \
DEBUG_IMX6UL_UART || \
DEBUG_IMX7D_UART
diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index eff87a344566..76780229f9d6 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -383,8 +383,15 @@ dtb-$(CONFIG_SOC_IMX6Q) += \
imx6dl-rex-basic.dtb \
imx6dl-riotboard.dtb \
imx6dl-sabreauto.dtb \
+ imx6dl-sabreauto-ecspi.dtb \
+ imx6dl-sabreauto-enetirq.dtb \
+ imx6dl-sabreauto-flexcan1.dtb \
+ imx6dl-sabreauto-gpmi-weim.dtb \
imx6dl-sabrelite.dtb \
imx6dl-sabresd.dtb \
+ imx6dl-sabresd-btwifi.dtb \
+ imx6dl-sabresd-hdcp.dtb \
+ imx6dl-sabresd-ldo.dtb \
imx6dl-savageboard.dtb \
imx6dl-ts4900.dtb \
imx6dl-tx6dl-comtft.dtb \
@@ -395,16 +402,31 @@ dtb-$(CONFIG_SOC_IMX6Q) += \
imx6dl-tx6u-811x.dtb \
imx6dl-tx6u-81xx-mb7.dtb \
imx6dl-udoo.dtb \
+ imx6dl-sabresd-enetirq.dtb \
imx6dl-wandboard.dtb \
imx6dl-wandboard-revb1.dtb \
+ imx6dqscm-1gb-qwks-rev2-fix-ldo.dtb \
+ imx6dqscm-1gb-qwks-rev2-interleave-android-ldo.dtb \
+ imx6dqscm-1gb-qwks-rev2-wifi-fix-ldo.dtb \
+ imx6dqscm-1gb-qwks-rev2-hdcp-fix-ldo.dtb \
+ imx6dqscm-1gb-evb-fix-ldo.dtb \
+ imx6dqscm-1gb-evb-interleave-android-ldo.dtb \
+ imx6dqscm-1gb-evb-btwifi-fix-ldo.dtb \
+ imx6dqscm-1gb-evb-enetirq-fix-ldo.dtb \
+ imx6dqscm-1gb-evb-hdcp-fix-ldo.dtb \
+ imx6dqscm-1gb-qwks-rev3-fix-ldo.dtb \
+ imx6dqscm-1gb-qwks-rev3-hdcp-fix-ldo.dtb \
+ imx6dqscm-1gb-qwks-rev3-btwifi-fix-ldo.dtb \
imx6q-apalis-eval.dtb \
imx6q-apalis-ixora.dtb \
imx6q-apalis-ixora-v1.1.dtb \
imx6q-apf6dev.dtb \
imx6q-arm2.dtb \
+ imx6q-arm2-hsic.dtb \
imx6q-b450v3.dtb \
imx6q-b650v3.dtb \
imx6q-b850v3.dtb \
+ imx6q-pop-arm2.dtb \
imx6q-cm-fx6.dtb \
imx6q-cubox-i.dtb \
imx6q-dfi-fs700-m60.dtb \
@@ -437,8 +459,16 @@ dtb-$(CONFIG_SOC_IMX6Q) += \
imx6q-phytec-pbab01.dtb \
imx6q-rex-pro.dtb \
imx6q-sabreauto.dtb \
+ imx6q-sabreauto-ecspi.dtb \
+ imx6q-sabreauto-enetirq.dtb \
+ imx6q-sabreauto-flexcan1.dtb \
+ imx6q-sabreauto-gpmi-weim.dtb \
imx6q-sabrelite.dtb \
imx6q-sabresd.dtb \
+ imx6q-sabresd-btwifi.dtb \
+ imx6q-sabresd-hdcp.dtb \
+ imx6q-sabresd-ldo.dtb \
+ imx6q-sabresd-enetirq.dtb \
imx6q-savageboard.dtb \
imx6q-sbc6x.dtb \
imx6q-tbs2910.dtb \
@@ -458,22 +488,62 @@ dtb-$(CONFIG_SOC_IMX6Q) += \
imx6qp-nitrogen6_max.dtb \
imx6qp-nitrogen6_som2.dtb \
imx6qp-sabreauto.dtb \
+ imx6qp-sabreauto-ecspi.dtb \
+ imx6qp-sabreauto-flexcan1.dtb \
+ imx6qp-sabreauto-gpmi-weim.dtb \
imx6qp-sabresd.dtb \
+ imx6qp-sabresd-btwifi.dtb \
+ imx6qp-sabresd-hdcp.dtb \
+ imx6qp-sabresd-ldo.dtb \
+ imx6qp-sabresd-ldo-pcie-cert.dtb \
imx6qp-zii-rdu2.dtb
dtb-$(CONFIG_SOC_IMX6SL) += \
imx6sl-evk.dtb \
+ imx6sl-evk-btwifi.dtb \
+ imx6sl-evk-ldo.dtb \
+ imx6sl-evk-csi.dtb \
+ imx6sl-evk-uart.dtb \
imx6sl-warp.dtb
dtb-$(CONFIG_SOC_IMX6SX) += \
imx6sx-nitrogen6sx.dtb \
+ imx6sx-14x14-arm2.dtb \
imx6sx-sabreauto.dtb \
+ imx6sx-sabreauto-m4.dtb \
imx6sx-sdb-reva.dtb \
+ imx6sx-sdb-reva-ldo.dtb \
imx6sx-sdb-sai.dtb \
imx6sx-sdb.dtb \
+ imx6sx-sdb-btwifi.dtb \
+ imx6sx-sdb-emmc.dtb \
+ imx6sx-sdb-lcdif1.dtb \
+ imx6sx-sdb-ldo.dtb \
+ imx6sx-sdb-m4.dtb \
+ imx6sx-sdb-mqs.dtb \
+ imx6sx-19x19-arm2.dtb \
+ imx6sx-19x19-arm2-ldo.dtb \
+ imx6sx-19x19-arm2-csi.dtb \
+ imx6sx-19x19-arm2-gpmi-weim.dtb \
imx6sx-udoo-neo-basic.dtb \
imx6sx-udoo-neo-extended.dtb \
- imx6sx-udoo-neo-full.dtb
+ imx6sx-udoo-neo-full.dtb \
+ imx6sxscm-1gb-evb-ldo.dtb \
+ imx6sxscm-1gb-evb-lcdif1-ldo.dtb \
+ imx6sxscm-1gb-evb-m4-ldo.dtb \
+ imx6sxscm-1gb-evb-mqs-ldo.dtb \
+ imx6sxscm-1gb-evb-sai-ldo.dtb \
+ imx6sxscm-1gb-evb-btwifi-ldo.dtb \
+ imx6sxscm-epop-evb-ldo.dtb \
+ imx6sxscm-epop-evb-m4-ldo.dtb
dtb-$(CONFIG_SOC_IMX6UL) += \
imx6ul-14x14-evk.dtb \
+ imx6ul-14x14-evk-btwifi.dtb \
+ imx6ul-14x14-evk-btwifi-oob.dtb \
+ imx6ul-14x14-evk-csi.dtb \
+ imx6ul-14x14-evk-emmc.dtb \
+ imx6ul-14x14-evk-ecspi.dtb \
+ imx6ul-14x14-evk-ecspi-slave.dtb \
+ imx6ul-14x14-evk-gpmi-weim.dtb \
+ imx6ul-14x14-evk-usb-certi.dtb \
imx6ul-geam.dtb \
imx6ul-isiot-emmc.dtb \
imx6ul-isiot-nand.dtb \
@@ -483,7 +553,61 @@ dtb-$(CONFIG_SOC_IMX6UL) += \
imx6ul-tx6ul-0010.dtb \
imx6ul-tx6ul-0011.dtb \
imx6ul-tx6ul-mainboard.dtb \
- imx6ull-14x14-evk.dtb
+ imx6ul-14x14-ddr3-arm2.dtb \
+ imx6ul-14x14-ddr3-arm2-emmc.dtb \
+ imx6ul-14x14-ddr3-arm2-flexcan2.dtb \
+ imx6ul-14x14-ddr3-arm2-gpmi-weim.dtb \
+ imx6ul-14x14-ddr3-arm2-mqs.dtb \
+ imx6ul-14x14-ddr3-arm2-spdif.dtb \
+ imx6ul-14x14-ddr3-arm2-wm8958.dtb \
+ imx6ul-14x14-lpddr2-arm2.dtb \
+ imx6ul-14x14-evk-pf1550.dtb \
+ imx6ul-9x9-evk.dtb \
+ imx6ul-9x9-evk-csi.dtb \
+ imx6ul-9x9-evk-btwifi.dtb \
+ imx6ul-9x9-evk-btwifi-oob.dtb \
+ imx6ul-9x9-evk-ldo.dtb
+dtb-$(CONFIG_SOC_IMX6ULL) += \
+ imx6ull-14x14-ddr3-arm2.dtb \
+ imx6ull-14x14-ddr3-arm2-adc.dtb \
+ imx6ull-14x14-ddr3-arm2-cs42888.dtb \
+ imx6ull-14x14-ddr3-arm2-ecspi.dtb \
+ imx6ull-14x14-ddr3-arm2-emmc.dtb \
+ imx6ull-14x14-ddr3-arm2-epdc.dtb \
+ imx6ull-14x14-ddr3-arm2-flexcan2.dtb \
+ imx6ull-14x14-ddr3-arm2-gpmi-weim.dtb \
+ imx6ull-14x14-ddr3-arm2-lcdif.dtb \
+ imx6ull-14x14-ddr3-arm2-ldo.dtb \
+ imx6ull-14x14-ddr3-arm2-qspi.dtb \
+ imx6ull-14x14-ddr3-arm2-qspi-all.dtb \
+ imx6ull-14x14-ddr3-arm2-tsc.dtb \
+ imx6ull-14x14-ddr3-arm2-uart2.dtb \
+ imx6ull-14x14-ddr3-arm2-usb.dtb \
+ imx6ull-14x14-ddr3-arm2-wm8958.dtb \
+ imx6ull-14x14-evk.dtb \
+ imx6ull-14x14-evk-btwifi.dtb \
+ imx6ull-14x14-evk-btwifi-oob.dtb \
+ imx6ull-14x14-evk-emmc.dtb \
+ imx6ull-14x14-evk-gpmi-weim.dtb \
+ imx6ull-14x14-evk-usb-certi.dtb \
+ imx6ull-9x9-evk.dtb \
+ imx6ull-9x9-evk-btwifi.dtb \
+ imx6ull-9x9-evk-btwifi-oob.dtb \
+ imx6ull-9x9-evk-ldo.dtb \
+ imx6ulz-14x14-evk.dtb \
+ imx6ulz-14x14-evk-btwifi.dtb \
+ imx6ulz-14x14-evk-btwifi-oob.dtb \
+ imx6ulz-14x14-evk-emmc.dtb \
+ imx6ulz-14x14-evk-gpmi-weim.dtb
+dtb-$(CONFIG_SOC_IMX6SLL) += \
+ imx6sll-lpddr2-arm2.dtb \
+ imx6sll-lpddr3-arm2.dtb \
+ imx6sll-lpddr3-arm2-csi.dtb \
+ imx6sll-lpddr3-arm2-ecspi.dtb \
+ imx6sll-lpddr3-arm2-spdif.dtb \
+ imx6sll-evk.dtb \
+ imx6sll-evk-reva.dtb \
+ imx6sll-evk-btwifi.dtb
dtb-$(CONFIG_SOC_IMX7D) += \
imx7d-cl-som-imx7.dtb \
imx7d-colibri-eval-v3.dtb \
@@ -491,9 +615,51 @@ dtb-$(CONFIG_SOC_IMX7D) += \
imx7d-pico.dtb \
imx7d-sbc-imx7.dtb \
imx7d-sdb.dtb \
+ imx7d-sdb-epdc.dtb \
+ imx7d-sdb-gpmi-weim.dtb \
+ imx7d-sdb-m4.dtb \
imx7d-sdb-sht11.dtb \
+ imx7d-sdb-qspi.dtb \
+ imx7d-sdb-mipi-dsi.dtb \
+ imx7d-sdb-reva.dtb \
+ imx7d-sdb-reva-epdc.dtb \
+ imx7d-sdb-reva-gpmi-weim.dtb \
+ imx7d-sdb-reva-hdmi-audio.dtb \
+ imx7d-sdb-reva-m4.dtb \
+ imx7d-sdb-reva-qspi.dtb \
+ imx7d-sdb-reva-touch.dtb \
+ imx7d-sdb-reva-wm8960.dtb \
imx7s-colibri-eval-v3.dtb \
- imx7s-warp.dtb
+ imx7s-warp.dtb \
+ imx7d-12x12-ddr3-arm2.dtb \
+ imx7d-12x12-lpddr3-arm2.dtb \
+ imx7d-12x12-lpddr3-arm2-m4.dtb \
+ imx7d-12x12-lpddr3-arm2-ecspi.dtb \
+ imx7d-12x12-lpddr3-arm2-enet2.dtb \
+ imx7d-12x12-lpddr3-arm2-flexcan.dtb \
+ imx7d-12x12-lpddr3-arm2-mipi_dsi.dtb \
+ imx7d-12x12-lpddr3-arm2-qspi.dtb \
+ imx7d-12x12-lpddr3-arm2-sai.dtb \
+ imx7d-12x12-lpddr3-arm2-mqs.dtb \
+ imx7d-12x12-lpddr3-arm2-pcie.dtb \
+ imx7d-19x19-lpddr2-arm2.dtb
+dtb-$(CONFIG_SOC_IMX7ULP) += \
+ imx7ulp-14x14-arm2.dtb \
+ imx7ulp-evk.dtb \
+ imx7ulp-evkb-spi-slave.dtb \
+ imx7ulp-evkb-emmc.dtb \
+ imx7ulp-evk-emmc-qspi.dtb \
+ imx7ulp-evk-ft5416.dtb \
+ imx7ulp-evkb-sd1.dtb \
+ imx7ulp-evkb-lpuart.dtb \
+ imx7ulp-evk-qspi.dtb \
+ imx7ulp-evk-wm8960.dtb \
+ imx7ulp-evk-mipi.dtb \
+ imx7ulp-evkb-sensors-to-i2c5.dtb \
+ imx7ulp-evkb.dtb \
+ imx7ulp-evkb-mipi.dtb \
+ imx7ulp-evkb-rm68200-wxga.dtb \
+ imx7ulp-evkb-rm68191-qhd.dtb
dtb-$(CONFIG_SOC_LS1021A) += \
ls1021a-qds.dtb \
ls1021a-twr.dtb
diff --git a/arch/arm/boot/dts/imx6dl-aristainetos_4.dts b/arch/arm/boot/dts/imx6dl-aristainetos_4.dts
index 32a812b1839e..821c3de8ffc6 100644
--- a/arch/arm/boot/dts/imx6dl-aristainetos_4.dts
+++ b/arch/arm/boot/dts/imx6dl-aristainetos_4.dts
@@ -3,6 +3,8 @@
*
* Copyright (C) 2014 Heiko Schocher <hs@denx.de>
*
+ * Copyright 2015 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
@@ -30,39 +32,19 @@
memory {
reg = <0x10000000 0x40000000>;
};
+};
- soc {
- display0: display@di0 {
- compatible = "fsl,imx-parallel-display";
- interface-pix-fmt = "rgb24";
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_ipu_disp>;
- status = "okay";
-
- display-timings {
- 480x800p60 {
- native-mode;
- clock-frequency = <30000000>;
- hactive = <480>;
- vactive = <800>;
- hfront-porch = <59>;
- hback-porch = <10>;
- hsync-len = <10>;
- vback-porch = <15>;
- vfront-porch = <15>;
- vsync-len = <15>;
- hsync-active = <1>;
- vsync-active = <1>;
- };
- };
+&mxcfb1 {
+ status = "okay";
+};
- port {
- display0_in: endpoint {
- remote-endpoint = <&ipu1_di0_disp0>;
- };
- };
- };
- };
+&lcd {
+ ipu_id = <0>;
+ disp_id = <0>;
+ default_ifmt = "RGB24";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ipu_disp>;
+ status = "okay";
};
&ecspi2 {
@@ -79,10 +61,6 @@
status = "okay";
};
-&ipu1_di0_disp0 {
- remote-endpoint = <&display0_in>;
-};
-
&pwm1 {
status = "okay";
};
diff --git a/arch/arm/boot/dts/imx6dl-aristainetos_7.dts b/arch/arm/boot/dts/imx6dl-aristainetos_7.dts
index 15203f0e9725..bad1e22b6bd7 100644
--- a/arch/arm/boot/dts/imx6dl-aristainetos_7.dts
+++ b/arch/arm/boot/dts/imx6dl-aristainetos_7.dts
@@ -3,6 +3,8 @@
*
* Copyright (C) 2014 Heiko Schocher <hs@denx.de>
*
+ * Copyright 2015 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
@@ -20,38 +22,6 @@
reg = <0x10000000 0x40000000>;
};
- soc {
- display0: display@di0 {
- compatible = "fsl,imx-parallel-display";
- interface-pix-fmt = "rgb24";
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_ipu_disp>;
- status = "okay";
-
- display-timings {
- 800x480p60 {
- native-mode;
- clock-frequency = <33246000>;
- hactive = <800>;
- vactive = <480>;
- hfront-porch = <88>;
- hback-porch = <88>;
- hsync-len = <80>;
- vback-porch = <10>;
- vfront-porch = <10>;
- vsync-len = <25>;
- vsync-active = <1>;
- };
- };
-
- port {
- display0_in: endpoint {
- remote-endpoint = <&ipu1_di0_disp0>;
- };
- };
- };
- };
-
backlight {
compatible = "pwm-backlight";
pwms = <&pwm3 0 3000>;
@@ -62,6 +32,19 @@
};
};
+&mxcfb1 {
+ status = "okay";
+};
+
+&lcd {
+ ipu_id = <0>;
+ disp_id = <0>;
+ default_ifmt = "RGB24";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ipu_disp>;
+ status = "okay";
+};
+
&i2c2 {
clock-frequency = <100000>;
pinctrl-names = "default";
@@ -69,10 +52,6 @@
status = "okay";
};
-&ipu1_di0_disp0 {
- remote-endpoint = <&display0_in>;
-};
-
&pwm3 {
status = "okay";
};
diff --git a/arch/arm/boot/dts/imx6dl-riotboard.dts b/arch/arm/boot/dts/imx6dl-riotboard.dts
index 275c6c05219d..1639f40bd767 100644
--- a/arch/arm/boot/dts/imx6dl-riotboard.dts
+++ b/arch/arm/boot/dts/imx6dl-riotboard.dts
@@ -1,6 +1,8 @@
/*
* Copyright 2014 Iain Paton <ipaton0@gmail.com>
*
+ * Copyright 2015 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
@@ -15,6 +17,10 @@
model = "RIoTboard i.MX6S";
compatible = "riot,imx6s-riotboard", "fsl,imx6dl";
+ aliases {
+ mxcfb0 = &mxcfb1;
+ };
+
memory {
reg = <0x10000000 0x40000000>;
};
@@ -82,6 +88,17 @@
mux-int-port = <1>;
mux-ext-port = <3>;
};
+
+ mxcfb1: fb@0 {
+ compatible = "fsl,mxc_sdc_fb";
+ disp_dev = "hdmi";
+ interface_pix_fmt = "RGB24";
+ mode_str ="1920x1080M@60";
+ default_bpp = <24>;
+ int_clk = <0>;
+ late_init = <0>;
+ status = "okay";
+ };
};
&audmux {
@@ -146,8 +163,15 @@
"", "", "", "", "", "", "", "";
};
-&hdmi {
- ddc-i2c-bus = <&i2c2>;
+&hdmi_core {
+ ipu_id = <0>;
+ disp_id = <0>;
+ status = "okay";
+};
+
+&hdmi_video {
+ fsl,phy_reg_vlev = <0x0294>;
+ fsl,phy_reg_cksymtx = <0x800d>;
status = "okay";
};
@@ -265,6 +289,11 @@
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_i2c2>;
status = "okay";
+
+ hdmi_edid: edid@50 {
+ compatible = "fsl,imx6-hdmi-i2c";
+ reg = <0x50>;
+ };
};
&i2c4 {
diff --git a/arch/arm/boot/dts/imx6dl-sabreauto-ecspi.dts b/arch/arm/boot/dts/imx6dl-sabreauto-ecspi.dts
new file mode 100644
index 000000000000..45ae16283627
--- /dev/null
+++ b/arch/arm/boot/dts/imx6dl-sabreauto-ecspi.dts
@@ -0,0 +1,39 @@
+/*
+ * 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 "imx6dl-sabreauto.dts"
+
+&ecspi1 {
+ pinctrl-assert-gpios = <&gpio5 4 GPIO_ACTIVE_LOW>;
+ status = "okay";
+};
+
+&can2 {
+ /* max7310_c on i2c3 is gone */
+ status = "disabled";
+};
+
+&i2c3 {
+ /* pin conflict with ecspi1 */
+ status = "disabled";
+};
+
+&uart3 {
+ /* the uart3 depends on the i2c3, so disable it too. */
+ status = "disabled";
+};
+
+&usbh1 {
+ /* max7310_b on i2c3 is gone */
+ status = "disabled";
+};
+
+&usbotg {
+ dr_mode = "peripheral";
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx6dl-sabreauto-enetirq.dts b/arch/arm/boot/dts/imx6dl-sabreauto-enetirq.dts
new file mode 100644
index 000000000000..906d1d9bcda0
--- /dev/null
+++ b/arch/arm/boot/dts/imx6dl-sabreauto-enetirq.dts
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2015 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 "imx6dl-sabreauto.dts"
+
+&fec {
+ pinctrl-0 = <&pinctrl_enet &pinctrl_enet_irq>;
+ interrupts-extended = <&gpio1 6 IRQ_TYPE_LEVEL_HIGH>,
+ <&gpc 0 119 IRQ_TYPE_LEVEL_HIGH>;
+};
+
+&mlb {
+ status = "disabled";
+};
diff --git a/arch/arm/boot/dts/imx6dl-sabreauto-flexcan1.dts b/arch/arm/boot/dts/imx6dl-sabreauto-flexcan1.dts
new file mode 100644
index 000000000000..f101f7c7b7b0
--- /dev/null
+++ b/arch/arm/boot/dts/imx6dl-sabreauto-flexcan1.dts
@@ -0,0 +1,18 @@
+/*
+ * Copyright (C) 2013 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 "imx6dl-sabreauto.dts"
+
+&can1{
+ status = "okay";
+};
+
+&fec {
+ /* pin conflict with flexcan1 */
+ status = "disabled";
+};
diff --git a/arch/arm/boot/dts/imx6dl-sabreauto-gpmi-weim.dts b/arch/arm/boot/dts/imx6dl-sabreauto-gpmi-weim.dts
new file mode 100644
index 000000000000..ad2e937d4ffa
--- /dev/null
+++ b/arch/arm/boot/dts/imx6dl-sabreauto-gpmi-weim.dts
@@ -0,0 +1,48 @@
+/*
+ * 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 "imx6dl-sabreauto.dts"
+
+&ecspi1 {
+ /* pin conflict with weim */
+ status = "disabled";
+};
+
+&can2 {
+ /* max7310_c on i2c3 is gone */
+ status = "disabled";
+};
+
+&gpmi {
+ status = "okay";
+};
+
+&i2c3 {
+ /* pin conflict with weim */
+ status = "disabled";
+};
+
+&uart3 {
+ /* pin conflict with gpmi and weim */
+ status = "disabled";
+};
+
+&usbh1 {
+ /* max7310_b on i2c3 is gone */
+ status = "disabled";
+};
+
+&usbotg {
+ dr_mode = "peripheral";
+ status = "okay";
+};
+
+&weim {
+ pinctrl-assert-gpios = <&gpio5 4 GPIO_ACTIVE_LOW>;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx6dl-sabreauto.dts b/arch/arm/boot/dts/imx6dl-sabreauto.dts
index a6ce7b487ad7..bd13b3592091 100644
--- a/arch/arm/boot/dts/imx6dl-sabreauto.dts
+++ b/arch/arm/boot/dts/imx6dl-sabreauto.dts
@@ -15,3 +15,17 @@
model = "Freescale i.MX6 DualLite/Solo SABRE Automotive Board";
compatible = "fsl,imx6dl-sabreauto", "fsl,imx6dl";
};
+&ldb {
+ lvds-channel@0 {
+ crtc = "ipu1-di0";
+ };
+ lvds-channel@1 {
+ crtc = "ipu1-di1";
+ };
+};
+&mxcfb1 {
+ status = "okay";
+};
+&mxcfb2 {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx6dl-sabresd-btwifi.dts b/arch/arm/boot/dts/imx6dl-sabresd-btwifi.dts
new file mode 100644
index 000000000000..814c93530a76
--- /dev/null
+++ b/arch/arm/boot/dts/imx6dl-sabresd-btwifi.dts
@@ -0,0 +1,10 @@
+/*
+ * Copyright (C) 2015 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 "imx6dl-sabresd.dts"
+#include "imx6qdl-sabresd-btwifi.dtsi"
diff --git a/arch/arm/boot/dts/imx6dl-sabresd-enetirq.dts b/arch/arm/boot/dts/imx6dl-sabresd-enetirq.dts
new file mode 100644
index 000000000000..ff4144113d5a
--- /dev/null
+++ b/arch/arm/boot/dts/imx6dl-sabresd-enetirq.dts
@@ -0,0 +1,18 @@
+/*
+ * 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 "imx6dl-sabresd.dts"
+
+&fec {
+ pinctrl-0 = <&pinctrl_enet &pinctrl_enet_irq>;
+ interrupts-extended = <&gpio1 6 0x04>, <&gpc 0 119 0x04>;
+};
+
+&i2c3 {
+ status = "disabled";
+};
diff --git a/arch/arm/boot/dts/imx6dl-sabresd-hdcp.dts b/arch/arm/boot/dts/imx6dl-sabresd-hdcp.dts
new file mode 100644
index 000000000000..2c7f04456cbb
--- /dev/null
+++ b/arch/arm/boot/dts/imx6dl-sabresd-hdcp.dts
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2013-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 "imx6dl-sabresd.dts"
+
+&gpc {
+ /* use ldo-enable, u-boot will check it and configure */
+ fsl,ldo-bypass = <0>;
+};
+
+&hdmi_video {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_hdmi_hdcp>;
+ fsl,hdcp;
+};
+
+&i2c2 {
+ status = "disable";
+};
+
+&reg_arm {
+ /delete-property/ vin-supply;
+};
+
+&reg_pu {
+ /delete-property/ vin-supply;
+};
+
+&reg_soc {
+ /delete-property/ vin-supply;
+};
diff --git a/arch/arm/boot/dts/imx6dl-sabresd-ldo.dts b/arch/arm/boot/dts/imx6dl-sabresd-ldo.dts
new file mode 100644
index 000000000000..e5c623d85e4e
--- /dev/null
+++ b/arch/arm/boot/dts/imx6dl-sabresd-ldo.dts
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2015 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 "imx6dl-sabresd.dts"
+
+&gpc {
+ /* use ldo-enable, u-boot will check it and configure */
+ fsl,ldo-bypass = <0>;
+};
+
+&reg_arm {
+ /delete-property/ vin-supply;
+};
+
+&reg_pu {
+ /delete-property/ vin-supply;
+};
+
+&reg_soc {
+ /delete-property/ vin-supply;
+};
+
+&wdog1 {
+ status = "okay";
+};
+
+&wdog2 {
+ status = "disabled";
+};
diff --git a/arch/arm/boot/dts/imx6dl-sabresd.dts b/arch/arm/boot/dts/imx6dl-sabresd.dts
index 9607afe088fc..ec392a6402b2 100644
--- a/arch/arm/boot/dts/imx6dl-sabresd.dts
+++ b/arch/arm/boot/dts/imx6dl-sabresd.dts
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013 Freescale Semiconductor, Inc.
+ * Copyright (C) 2013-2015 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
@@ -16,7 +16,142 @@
compatible = "fsl,imx6dl-sabresd", "fsl,imx6dl";
};
+&battery {
+ offset-charger = <1485>;
+ offset-discharger = <1464>;
+ offset-usb-charger = <1285>;
+};
+
+&iomuxc {
+ epdc {
+ pinctrl_epdc_0: epdcgrp-0 {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_A16__EPDC_DATA00 0x80000000
+ MX6QDL_PAD_EIM_DA10__EPDC_DATA01 0x80000000
+ MX6QDL_PAD_EIM_DA12__EPDC_DATA02 0x80000000
+ MX6QDL_PAD_EIM_DA11__EPDC_DATA03 0x80000000
+ MX6QDL_PAD_EIM_LBA__EPDC_DATA04 0x80000000
+ MX6QDL_PAD_EIM_EB2__EPDC_DATA05 0x80000000
+ MX6QDL_PAD_EIM_CS0__EPDC_DATA06 0x80000000
+ MX6QDL_PAD_EIM_RW__EPDC_DATA07 0x80000000
+ MX6QDL_PAD_EIM_A21__EPDC_GDCLK 0x80000000
+ MX6QDL_PAD_EIM_A22__EPDC_GDSP 0x80000000
+ MX6QDL_PAD_EIM_A23__EPDC_GDOE 0x80000000
+ MX6QDL_PAD_EIM_A24__EPDC_GDRL 0x80000000
+ MX6QDL_PAD_EIM_D31__EPDC_SDCLK_P 0x80000000
+ MX6QDL_PAD_EIM_D27__EPDC_SDOE 0x80000000
+ MX6QDL_PAD_EIM_DA1__EPDC_SDLE 0x80000000
+ MX6QDL_PAD_EIM_EB1__EPDC_SDSHR 0x80000000
+ MX6QDL_PAD_EIM_DA2__EPDC_BDR0 0x80000000
+ MX6QDL_PAD_EIM_DA4__EPDC_SDCE0 0x80000000
+ MX6QDL_PAD_EIM_DA5__EPDC_SDCE1 0x80000000
+ MX6QDL_PAD_EIM_DA6__EPDC_SDCE2 0x80000000
+ >;
+ };
+ };
+};
+
+&epdc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_epdc_0>;
+ V3P3-supply = <&V3P3_reg>;
+ VCOM-supply = <&VCOM_reg>;
+ DISPLAY-supply = <&DISPLAY_reg>;
+ status = "okay";
+};
+
+&i2c3 {
+ max17135@48 {
+ compatible = "maxim,max17135";
+ reg = <0x48>;
+ vneg_pwrup = <1>;
+ gvee_pwrup = <1>;
+ vpos_pwrup = <2>;
+ gvdd_pwrup = <1>;
+ gvdd_pwrdn = <1>;
+ vpos_pwrdn = <2>;
+ gvee_pwrdn = <1>;
+ vneg_pwrdn = <1>;
+ SENSOR-supply = <&reg_sensor>;
+ gpio_pmic_pwrgood = <&gpio2 21 0>;
+ gpio_pmic_vcom_ctrl = <&gpio3 17 0>;
+ gpio_pmic_wakeup = <&gpio3 20 0>;
+ gpio_pmic_v3p3 = <&gpio2 20 0>;
+ gpio_pmic_intr = <&gpio2 25 0>;
+
+ regulators {
+ DISPLAY_reg: DISPLAY {
+ regulator-name = "DISPLAY";
+ };
+
+ GVDD_reg: GVDD {
+ /* 20v */
+ regulator-name = "GVDD";
+ };
+
+ GVEE_reg: GVEE {
+ /* -22v */
+ regulator-name = "GVEE";
+ };
+
+ HVINN_reg: HVINN {
+ /* -22v */
+ regulator-name = "HVINN";
+ };
+
+ HVINP_reg: HVINP {
+ /* 20v */
+ regulator-name = "HVINP";
+ };
+
+ VCOM_reg: VCOM {
+ regulator-name = "VCOM";
+ /* Real max: -500000 */
+ regulator-max-microvolt = <4325000>;
+ /* Real min: -4325000 */
+ regulator-min-microvolt = <500000>;
+ };
+
+ VNEG_reg: VNEG {
+ /* -15v */
+ regulator-name = "VNEG";
+ };
+
+ VPOS_reg: VPOS {
+ /* 15v */
+ regulator-name = "VPOS";
+ };
+
+ V3P3_reg: V3P3 {
+ regulator-name = "V3P3";
+ };
+ };
+ };
+};
+
&ipu1_csi1_from_ipu1_csi1_mux {
clock-lanes = <0>;
data-lanes = <1 2>;
};
+
+&ldb {
+ lvds-channel@0 {
+ crtc = "ipu1-di0";
+ };
+
+ lvds-channel@1 {
+ crtc = "ipu1-di1";
+ };
+};
+
+&mxcfb1 {
+ status = "okay";
+};
+
+&mxcfb2 {
+ status = "okay";
+};
+
+&pxp {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx6dl-tx6dl-comtft.dts b/arch/arm/boot/dts/imx6dl-tx6dl-comtft.dts
index aac42ac465b6..c6eba8ff33c7 100644
--- a/arch/arm/boot/dts/imx6dl-tx6dl-comtft.dts
+++ b/arch/arm/boot/dts/imx6dl-tx6dl-comtft.dts
@@ -47,10 +47,6 @@
model = "Ka-Ro electronics TX6DL Module on CoMpact TFT";
compatible = "karo,imx6dl-tx6dl", "fsl,imx6dl";
- aliases {
- display = &display;
- };
-
backlight: backlight {
compatible = "pwm-backlight";
pwms = <&pwm2 0 500000 0>;
@@ -73,38 +69,14 @@
default-brightness-level = <50>;
};
- display: display@di0 {
- compatible = "fsl,imx-parallel-display";
- interface-pix-fmt = "rgb24";
+ lcd@0 {
+ compatible = "fsl,lcd";
+ ipu_id = <0>;
+ disp_id = <0>;
+ default_ifmt = "RGB565";
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_disp0_1>;
status = "okay";
-
- port {
- display0_in: endpoint {
- remote-endpoint = <&ipu1_di0_disp0>;
- };
- };
-
- display-timings {
- native-mode = <&ET070001DM6>;
-
- ET070001DM6: CoMTFT { /* same as ET0700 but with inverted pixel clock */
- clock-frequency = <33264000>;
- hactive = <800>;
- vactive = <480>;
- hback-porch = <88>;
- hsync-len = <128>;
- hfront-porch = <40>;
- vback-porch = <33>;
- vsync-len = <2>;
- vfront-porch = <10>;
- hsync-active = <0>;
- vsync-active = <0>;
- de-active = <1>;
- pixelclk-active = <1>;
- };
- };
};
};
@@ -116,10 +88,6 @@
xceiver-supply = <&reg_3v3>;
};
-&ipu1_di0_disp0 {
- remote-endpoint = <&display0_in>;
-};
-
&kpp {
status = "disabled";
};
diff --git a/arch/arm/boot/dts/imx6dl-tx6u-801x.dts b/arch/arm/boot/dts/imx6dl-tx6u-801x.dts
index d1f1298ec55a..34cb356b85f6 100644
--- a/arch/arm/boot/dts/imx6dl-tx6u-801x.dts
+++ b/arch/arm/boot/dts/imx6dl-tx6u-801x.dts
@@ -47,10 +47,6 @@
model = "Ka-Ro electronics TX6U-801x Module";
compatible = "karo,imx6dl-tx6dl", "fsl,imx6dl";
- aliases {
- display = &display;
- };
-
backlight: backlight {
compatible = "pwm-backlight";
pwms = <&pwm2 0 500000 PWM_POLARITY_INVERTED>;
@@ -73,135 +69,14 @@
default-brightness-level = <50>;
};
- display: display@di0 {
- compatible = "fsl,imx-parallel-display";
- interface-pix-fmt = "rgb24";
+ lcd@0 {
+ compatible = "fsl,lcd";
+ ipu_id = <0>;
+ disp_id = <0>;
+ default_ifmt = "RGB565";
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_disp0_1>;
status = "okay";
-
- port {
- display0_in: endpoint {
- remote-endpoint = <&ipu1_di0_disp0>;
- };
- };
-
- display-timings {
- VGA {
- clock-frequency = <25200000>;
- hactive = <640>;
- vactive = <480>;
- hback-porch = <48>;
- hsync-len = <96>;
- hfront-porch = <16>;
- vback-porch = <31>;
- vsync-len = <2>;
- vfront-porch = <12>;
- hsync-active = <0>;
- vsync-active = <0>;
- de-active = <1>;
- pixelclk-active = <0>;
- };
-
- ETV570 {
- clock-frequency = <25200000>;
- hactive = <640>;
- vactive = <480>;
- hback-porch = <114>;
- hsync-len = <30>;
- hfront-porch = <16>;
- vback-porch = <32>;
- vsync-len = <3>;
- vfront-porch = <10>;
- hsync-active = <0>;
- vsync-active = <0>;
- de-active = <1>;
- pixelclk-active = <0>;
- };
-
- ET0350 {
- clock-frequency = <6413760>;
- hactive = <320>;
- vactive = <240>;
- hback-porch = <34>;
- hsync-len = <34>;
- hfront-porch = <20>;
- vback-porch = <15>;
- vsync-len = <3>;
- vfront-porch = <4>;
- hsync-active = <0>;
- vsync-active = <0>;
- de-active = <1>;
- pixelclk-active = <0>;
- };
-
- ET0430 {
- clock-frequency = <9009000>;
- hactive = <480>;
- vactive = <272>;
- hback-porch = <2>;
- hsync-len = <41>;
- hfront-porch = <2>;
- vback-porch = <2>;
- vsync-len = <10>;
- vfront-porch = <2>;
- hsync-active = <0>;
- vsync-active = <0>;
- de-active = <1>;
- pixelclk-active = <1>;
- };
-
- ET0500 {
- clock-frequency = <33264000>;
- hactive = <800>;
- vactive = <480>;
- hback-porch = <88>;
- hsync-len = <128>;
- hfront-porch = <40>;
- vback-porch = <33>;
- vsync-len = <2>;
- vfront-porch = <10>;
- hsync-active = <0>;
- vsync-active = <0>;
- de-active = <1>;
- pixelclk-active = <0>;
- };
-
- ET0700 { /* same as ET0500 */
- clock-frequency = <33264000>;
- hactive = <800>;
- vactive = <480>;
- hback-porch = <88>;
- hsync-len = <128>;
- hfront-porch = <40>;
- vback-porch = <33>;
- vsync-len = <2>;
- vfront-porch = <10>;
- hsync-active = <0>;
- vsync-active = <0>;
- de-active = <1>;
- pixelclk-active = <0>;
- };
-
- ETQ570 {
- clock-frequency = <6596040>;
- hactive = <320>;
- vactive = <240>;
- hback-porch = <38>;
- hsync-len = <30>;
- hfront-porch = <30>;
- vback-porch = <16>;
- vsync-len = <3>;
- vfront-porch = <4>;
- hsync-active = <0>;
- vsync-active = <0>;
- de-active = <1>;
- pixelclk-active = <0>;
- };
- };
};
};
-&ipu1_di0_disp0 {
- remote-endpoint = <&display0_in>;
-};
diff --git a/arch/arm/boot/dts/imx6dl.dtsi b/arch/arm/boot/dts/imx6dl.dtsi
index 8475e6cc59ac..0f8faa5dbbe5 100644
--- a/arch/arm/boot/dts/imx6dl.dtsi
+++ b/arch/arm/boot/dts/imx6dl.dtsi
@@ -1,6 +1,7 @@
/*
- * Copyright 2013 Freescale Semiconductor, Inc.
+ * Copyright 2013-2015 Freescale Semiconductor, Inc.
+ * Copyright 2018 NXP
*
* 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
@@ -43,9 +44,13 @@
<&clks IMX6QDL_CLK_PLL2_PFD2_396M>,
<&clks IMX6QDL_CLK_STEP>,
<&clks IMX6QDL_CLK_PLL1_SW>,
- <&clks IMX6QDL_CLK_PLL1_SYS>;
+ <&clks IMX6QDL_CLK_PLL1_SYS>,
+ <&clks IMX6QDL_CLK_PLL1>,
+ <&clks IMX6QDL_PLL1_BYPASS>,
+ <&clks IMX6QDL_PLL1_BYPASS_SRC>;
clock-names = "arm", "pll2_pfd2_396m", "step",
- "pll1_sw", "pll1_sys";
+ "pll1_sw", "pll1_sys", "pll1",
+ "pll1_bypass", "pll1_bypass_src";
arm-supply = <&reg_arm>;
pu-supply = <&reg_pu>;
soc-supply = <&reg_soc>;
@@ -59,26 +64,95 @@
};
};
+ reserved-memory {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ /* global autoconfigured region for contiguous allocations */
+ linux,cma {
+ compatible = "shared-dma-pool";
+ reusable;
+ size = <0x14000000>;
+ linux,cma-default;
+ };
+ };
+
soc {
- ocram: sram@00900000 {
+ busfreq {
+ compatible = "fsl,imx_busfreq";
+ clocks = <&clks IMX6QDL_CLK_PLL2_BUS>, <&clks IMX6QDL_CLK_PLL2_PFD2_396M>,
+ <&clks IMX6QDL_CLK_PLL2_198M>, <&clks IMX6QDL_CLK_ARM>,
+ <&clks IMX6QDL_CLK_PLL3_USB_OTG>, <&clks IMX6QDL_CLK_PERIPH>,
+ <&clks IMX6QDL_CLK_PERIPH_PRE>, <&clks IMX6QDL_CLK_PERIPH_CLK2>,
+ <&clks IMX6QDL_CLK_PERIPH_CLK2_SEL>, <&clks IMX6QDL_CLK_OSC>,
+ <&clks IMX6QDL_CLK_AXI_ALT_SEL>, <&clks IMX6QDL_CLK_AXI_SEL> ,
+ <&clks IMX6QDL_CLK_PLL3_PFD1_540M>;
+ clock-names = "pll2_bus", "pll2_pfd2_396m", "pll2_198m", "arm", "pll3_usb_otg", "periph",
+ "periph_pre", "periph_clk2", "periph_clk2_sel", "osc", "axi_alt_sel", "axi_sel", "pll3_pfd1_540m";
+ interrupts = <0 107 0x04>, <0 112 0x4>;
+ interrupt-names = "irq_busfreq_0", "irq_busfreq_1";
+ fsl,max_ddr_freq = <400000000>;
+ };
+
+ gpu: gpu@00130000 {
+ compatible = "fsl,imx6dl-gpu", "fsl,imx6q-gpu";
+ reg = <0x00130000 0x4000>, <0x00134000 0x4000>,
+ <0x10000000 0x0>, <0x0 0x8000000>;
+ reg-names = "iobase_3d", "iobase_2d",
+ "phys_baseaddr", "contiguous_mem";
+ interrupts = <0 9 IRQ_TYPE_LEVEL_HIGH>,
+ <0 10 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "irq_3d", "irq_2d";
+ clocks = <&clks IMX6QDL_CLK_OPENVG_AXI>, <&clks IMX6QDL_CLK_GPU3D_AXI>,
+ <&clks IMX6QDL_CLK_GPU2D_CORE>, <&clks IMX6QDL_CLK_GPU3D_CORE>,
+ <&clks IMX6QDL_CLK_DUMMY>;
+ clock-names = "gpu2d_axi_clk", "gpu3d_axi_clk",
+ "gpu2d_clk", "gpu3d_clk",
+ "gpu3d_shader_clk";
+ resets = <&src 0>, <&src 3>;
+ reset-names = "gpu3d", "gpu2d";
+ power-domains = <&pd_pu>;
+ };
+
+ ocram: sram@00905000 {
compatible = "mmio-sram";
- reg = <0x00900000 0x20000>;
+ reg = <0x00905000 0x1B000>;
clocks = <&clks IMX6QDL_CLK_OCRAM>;
};
+ ocram_optee: sram@00918000 {
+ compatible = "fsl,optee-lpm-sram";
+ reg = <0x00918000 0x8000>;
+ overw_reg = <&ocram 0x00905000 0x13000>;
+ };
+
aips1: aips-bus@02000000 {
iomuxc: iomuxc@020e0000 {
compatible = "fsl,imx6dl-iomuxc";
};
+ dcic2: dcic@020e8000 {
+ clocks = <&clks IMX6QDL_CLK_DCIC1 >,
+ <&clks IMX6QDL_CLK_DCIC2>; /* DCIC2 depend on DCIC1 clock in imx6dl*/
+ clock-names = "dcic", "disp-axi";
+ };
+
pxp: pxp@020f0000 {
+ compatible = "fsl,imx6dl-pxp-dma";
reg = <0x020f0000 0x4000>;
interrupts = <0 98 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6QDL_CLK_IPU2>, <&clks IMX6QDL_CLK_DUMMY>;
+ clock-names = "pxp-axi", "disp-axi";
+ status = "disabled";
};
epdc: epdc@020f4000 {
+ compatible = "fsl,imx6dl-epdc";
reg = <0x020f4000 0x4000>;
interrupts = <0 97 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6QDL_CLK_IPU2>, <&clks IMX6QDL_CLK_IPU2_DI1>;
+ clock-names = "epdc_axi", "epdc_pix";
};
lcdif: lcdif@020f8000 {
@@ -88,6 +162,16 @@
};
aips2: aips-bus@02100000 {
+ mipi_dsi: mipi@021e0000 {
+ compatible = "fsl,imx6dl-mipi-dsi";
+ reg = <0x021e0000 0x4000>;
+ interrupts = <0 102 0x04>;
+ gpr = <&gpr>;
+ clocks = <&clks IMX6QDL_CLK_HSI_TX>, <&clks IMX6QDL_CLK_VIDEO_27M>;
+ clock-names = "mipi_pllref_clk", "mipi_cfg_clk";
+ status = "disabled";
+ };
+
i2c4: i2c@021f8000 {
#address-cells = <1>;
#size-cells = <0>;
@@ -294,12 +378,19 @@
};
&ldb {
- clocks = <&clks IMX6QDL_CLK_LDB_DI0_SEL>, <&clks IMX6QDL_CLK_LDB_DI1_SEL>,
+ compatible = "fsl,imx6dl-ldb", "fsl,imx53-ldb";
+ clocks = <&clks IMX6QDL_CLK_LDB_DI0>, <&clks IMX6QDL_CLK_LDB_DI1>,
<&clks IMX6QDL_CLK_IPU1_DI0_SEL>, <&clks IMX6QDL_CLK_IPU1_DI1_SEL>,
- <&clks IMX6QDL_CLK_LDB_DI0>, <&clks IMX6QDL_CLK_LDB_DI1>;
- clock-names = "di0_pll", "di1_pll",
+ <&clks IMX6QDL_CLK_IPU2_DI0_SEL>,
+ <&clks IMX6QDL_CLK_LDB_DI0_DIV_3_5>, <&clks IMX6QDL_CLK_LDB_DI1_DIV_3_5>,
+ <&clks IMX6QDL_CLK_LDB_DI0_DIV_7>, <&clks IMX6QDL_CLK_LDB_DI1_DIV_7>,
+ <&clks IMX6QDL_CLK_LDB_DI0_DIV_SEL>, <&clks IMX6QDL_CLK_LDB_DI1_DIV_SEL>;
+ clock-names = "ldb_di0", "ldb_di1",
"di0_sel", "di1_sel",
- "di0", "di1";
+ "di2_sel",
+ "ldb_di0_div_3_5", "ldb_di1_div_3_5",
+ "ldb_di0_div_7", "ldb_di1_div_7",
+ "ldb_di0_div_sel", "ldb_di1_div_sel";
};
&mipi_csi {
@@ -373,3 +464,7 @@
&vpu {
compatible = "fsl,imx6dl-vpu", "cnm,coda960";
};
+
+&vpu_fsl {
+ iramsize = <0>;
+};
diff --git a/arch/arm/boot/dts/imx6dqscm-1gb-evb-btwifi-fix-ldo.dts b/arch/arm/boot/dts/imx6dqscm-1gb-evb-btwifi-fix-ldo.dts
new file mode 100644
index 000000000000..d29e57254a54
--- /dev/null
+++ b/arch/arm/boot/dts/imx6dqscm-1gb-evb-btwifi-fix-ldo.dts
@@ -0,0 +1,10 @@
+/*
+ * Copyright (C) 2016 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 "imx6dqscm-1gb-evb-fix-ldo.dts"
+#include "imx6qdl-sabresd-btwifi.dtsi"
diff --git a/arch/arm/boot/dts/imx6dqscm-1gb-evb-enetirq-fix-ldo.dts b/arch/arm/boot/dts/imx6dqscm-1gb-evb-enetirq-fix-ldo.dts
new file mode 100644
index 000000000000..a6630d32e71f
--- /dev/null
+++ b/arch/arm/boot/dts/imx6dqscm-1gb-evb-enetirq-fix-ldo.dts
@@ -0,0 +1,18 @@
+/*
+ * Copyright (C) 2016 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 "imx6dqscm-1gb-evb-fix-ldo.dts"
+
+&fec {
+ pinctrl-0 = <&pinctrl_enet &pinctrl_enet_irq>;
+ interrupts-extended = <&gpio1 6 0x04>, <&intc 0 119 0x04>;
+};
+
+&i2c3 {
+ status = "disabled";
+};
diff --git a/arch/arm/boot/dts/imx6dqscm-1gb-evb-fix-ldo.dts b/arch/arm/boot/dts/imx6dqscm-1gb-evb-fix-ldo.dts
new file mode 100644
index 000000000000..1013cf7d3997
--- /dev/null
+++ b/arch/arm/boot/dts/imx6dqscm-1gb-evb-fix-ldo.dts
@@ -0,0 +1,219 @@
+/*
+ * Copyright (C) 2016 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 "imx6q-sabresd-ldo.dts"
+
+/ {
+ model = "Freescale i.MX6D SCM EVB";
+ compatible = "fsl,imx6q-sabresd", "fsl,imx6q";
+ memory: memory {
+ linux,usable-memory = <0x10000000 0x20000000
+ 0x80000000 0x20000000>;
+ };
+ soc {
+ busfreq {
+ fsl,max_ddr_freq = <400000000>;
+ status = "okay";
+ clocks = <&clks 171>, <&clks 6>, <&clks 11>, <&clks 104>, <&clks 172>, <&clks 58>,
+ <&clks 18>, <&clks 60>, <&clks 20>, <&clks 3>, <&clks 140>;
+ clock-names = "pll2_bus", "pll2_pfd2_396m", "pll2_198m", "arm", "pll3_usb_otg", "periph",
+ "periph_pre", "periph_clk2", "periph_clk2_sel", "osc", "mmdc";
+ };
+ };
+};
+
+&ecspi1 {
+ cs-gpios = <&gpio2 30 0>;
+ internal_scm_flash: m25p80@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "micron,n25q128a13", "jedec,spi-nor";
+ spi-max-frequency = <20000000>;
+ reg = <0>;
+ };
+};
+
+&i2c1 {
+ ov564x: ov564x@3c {
+ DOVDD-supply = <&sw4_reg>; /* 1.8v */
+ };
+};
+
+&clks {
+ assigned-clocks = <&clks IMX6QDL_CLK_LDB_DI0_SEL>,
+ <&clks IMX6QDL_CLK_LDB_DI1_SEL>;
+ assigned-clock-parents = <&clks IMX6QDL_CLK_MMDC_CH1_AXI>,
+ <&clks IMX6QDL_CLK_MMDC_CH1_AXI>;
+};
+
+&i2c2 {
+ pmic: pfuze100@08 {
+ regulators {
+ sw1a_reg: sw1ab {
+ regulator-min-microvolt = <300000>;
+ regulator-max-microvolt = <1875000>;
+ regulator-boot-on;
+ regulator-always-on;
+ regulator-ramp-delay = <6250>;
+ };
+
+ sw1c_reg: sw1c {
+ regulator-min-microvolt = <300000>;
+ regulator-max-microvolt = <1875000>;
+ regulator-boot-on;
+ regulator-always-on;
+ regulator-ramp-delay = <6250>;
+ };
+
+ sw2_reg: sw2 {
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ sw3a_reg: sw3a {
+ regulator-min-microvolt = <400000>;
+ regulator-max-microvolt = <1250000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ sw3b_reg: sw3b {
+ regulator-min-microvolt = <400000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ sw4_reg: sw4 {
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-boot-on;
+ regulator-always-on;
+
+ };
+
+ swbst_reg: swbst {
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5150000>;
+ regulator-boot-on;
+ regulator-always-on;
+
+ };
+
+ snvs_reg: vsnvs {
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ vref_reg: vrefddr {
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ vgen1_reg: vgen1 {
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1550000>;
+ regulator-always-on;
+ };
+
+ vgen2_reg: vgen2 {
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1550000>;
+ regulator-always-on;
+ };
+
+ vgen3_reg: vgen3 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <2800000>;
+ regulator-always-on;
+ };
+
+ vgen4_reg: vgen4 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <2500000>;
+ regulator-always-on;
+ };
+
+ vgen5_reg: vgen5 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ vgen6_reg: vgen6 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+ };
+ };
+
+ ov564x_mipi: ov564x_mipi@3c {
+ DOVDD-supply = <&sw4_reg>; /* 1.8v */
+ };
+
+};
+&iomuxc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_hog>;
+
+ imx6qdl-sabresd {
+ pinctrl_hog: hoggrp {
+ fsl,pins = <
+ MX6QDL_PAD_NANDF_D0__GPIO2_IO00 0x80000000
+ MX6QDL_PAD_NANDF_D1__GPIO2_IO01 0x80000000
+ MX6QDL_PAD_NANDF_D2__GPIO2_IO02 0x80000000
+ MX6QDL_PAD_NANDF_D3__GPIO2_IO03 0x80000000
+ MX6QDL_PAD_GPIO_0__CCM_CLKO1 0x130b0
+ MX6QDL_PAD_NANDF_CLE__GPIO6_IO07 0x80000000
+ MX6QDL_PAD_NANDF_ALE__GPIO6_IO08 0x80000000
+ MX6QDL_PAD_ENET_TXD1__GPIO1_IO29 0x80000000
+ MX6QDL_PAD_EIM_D22__GPIO3_IO22 0x80000000
+ MX6QDL_PAD_ENET_CRS_DV__GPIO1_IO25 0x80000000
+ MX6QDL_PAD_EIM_D26__GPIO3_IO26 0x80000000
+ MX6QDL_PAD_EIM_CS1__GPIO2_IO24 0x80000000
+ MX6QDL_PAD_ENET_RXD0__GPIO1_IO27 0x80000000
+ MX6QDL_PAD_EIM_A25__GPIO5_IO02 0x80000000
+ MX6QDL_PAD_EIM_D23__GPIO3_IO23 0x80000000
+ MX6QDL_PAD_EIM_EB3__GPIO2_IO31 0x80000000
+ MX6QDL_PAD_SD1_CMD__GPIO1_IO18 0x80000000
+ MX6QDL_PAD_SD3_RST__GPIO7_IO08 0x80000000
+ MX6QDL_PAD_GPIO_9__GPIO1_IO09 0x80000000
+ MX6QDL_PAD_EIM_DA9__GPIO3_IO09 0x80000000
+ MX6QDL_PAD_GPIO_1__WDOG2_B 0x80000000
+ MX6QDL_PAD_NANDF_CS0__GPIO6_IO11 0x80000000
+ MX6QDL_PAD_NANDF_CS1__GPIO6_IO14 0x80000000
+ >;
+ };
+ pinctrl_ecspi1: ecspi1grp {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_D17__ECSPI1_MISO 0x100b1
+ MX6QDL_PAD_EIM_D18__ECSPI1_MOSI 0x100b1
+ MX6QDL_PAD_EIM_D16__ECSPI1_SCLK 0x100b1
+ >;
+ };
+ pinctrl_usdhc3: usdhc3grp {
+ fsl,pins = <
+ MX6QDL_PAD_SD3_CMD__SD3_CMD 0x170f9
+ MX6QDL_PAD_SD3_CLK__SD3_CLK 0x100f9
+ MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x170f9
+ MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x170f9
+ MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x170f9
+ MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x170f9
+ MX6QDL_PAD_SD3_DAT4__SD3_DATA4 0x170f9
+ MX6QDL_PAD_SD3_DAT5__SD3_DATA5 0x170f9
+ MX6QDL_PAD_SD3_DAT6__SD3_DATA6 0x170f9
+ MX6QDL_PAD_SD3_DAT7__SD3_DATA7 0x170f9
+ >;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/imx6dqscm-1gb-evb-hdcp-fix-ldo.dts b/arch/arm/boot/dts/imx6dqscm-1gb-evb-hdcp-fix-ldo.dts
new file mode 100644
index 000000000000..4bb67eab0aaa
--- /dev/null
+++ b/arch/arm/boot/dts/imx6dqscm-1gb-evb-hdcp-fix-ldo.dts
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2016 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 "imx6dqscm-1gb-evb-fix-ldo.dts"
+
+&hdmi_video {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_hdmi_hdcp>;
+ fsl,hdcp;
+};
+
+&i2c2 {
+ status = "disable";
+};
diff --git a/arch/arm/boot/dts/imx6dqscm-1gb-evb-interleave-android-ldo.dts b/arch/arm/boot/dts/imx6dqscm-1gb-evb-interleave-android-ldo.dts
new file mode 100644
index 000000000000..5136cd77ed4b
--- /dev/null
+++ b/arch/arm/boot/dts/imx6dqscm-1gb-evb-interleave-android-ldo.dts
@@ -0,0 +1,209 @@
+/*
+ * Copyright (C) 2016 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 "imx6q-sabresd-ldo.dts"
+
+/ {
+ model = "Freescale i.MX6D SCM EVB";
+ compatible = "fsl,imx6q-sabresd", "fsl,imx6q";
+ soc {
+ busfreq {
+ fsl,max_ddr_freq = <400000000>;
+ status = "okay";
+ clocks = <&clks 171>, <&clks 6>, <&clks 11>, <&clks 104>, <&clks 172>, <&clks 58>,
+ <&clks 18>, <&clks 60>, <&clks 20>, <&clks 3>, <&clks 140>;
+ clock-names = "pll2_bus", "pll2_pfd2_396m", "pll2_198m", "arm", "pll3_usb_otg", "periph",
+ "periph_pre", "periph_clk2", "periph_clk2_sel", "osc", "mmdc";
+ };
+ };
+};
+
+&ecspi1 {
+ cs-gpios = <&gpio2 30 0>;
+ internal_scm_flash: m25p80@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "micron,n25q128a13", "jedec,spi-nor";
+ spi-max-frequency = <20000000>;
+ reg = <0>;
+ };
+};
+
+&i2c1 {
+ ov564x: ov564x@3c {
+ DOVDD-supply = <&sw4_reg>; /* 1.8v */
+ };
+};
+
+&i2c2 {
+ pmic: pfuze100@08 {
+ regulators {
+ sw1a_reg: sw1ab {
+ regulator-min-microvolt = <300000>;
+ regulator-max-microvolt = <1875000>;
+ regulator-boot-on;
+ regulator-always-on;
+ regulator-ramp-delay = <6250>;
+ };
+
+ sw1c_reg: sw1c {
+ regulator-min-microvolt = <300000>;
+ regulator-max-microvolt = <1875000>;
+ regulator-boot-on;
+ regulator-always-on;
+ regulator-ramp-delay = <6250>;
+ };
+
+ sw2_reg: sw2 {
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ sw3a_reg: sw3a {
+ regulator-min-microvolt = <400000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ sw3b_reg: sw3b {
+ regulator-min-microvolt = <400000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ sw4_reg: sw4 {
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-boot-on;
+ regulator-always-on;
+
+ };
+
+ swbst_reg: swbst {
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5150000>;
+ regulator-boot-on;
+ regulator-always-on;
+
+ };
+
+ snvs_reg: vsnvs {
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ vref_reg: vrefddr {
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ vgen1_reg: vgen1 {
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1550000>;
+ regulator-always-on;
+ };
+
+ vgen2_reg: vgen2 {
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1550000>;
+ regulator-always-on;
+ };
+
+ vgen3_reg: vgen3 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <2800000>;
+ regulator-always-on;
+ };
+
+ vgen4_reg: vgen4 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <2500000>;
+ regulator-always-on;
+ };
+
+ vgen5_reg: vgen5 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ vgen6_reg: vgen6 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+ };
+ };
+
+ ov564x_mipi: ov564x_mipi@3c {
+ DOVDD-supply = <&sw4_reg>; /* 1.8v */
+ };
+
+};
+&iomuxc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_hog>;
+
+ imx6qdl-sabresd {
+ pinctrl_hog: hoggrp {
+ fsl,pins = <
+ MX6QDL_PAD_NANDF_D0__GPIO2_IO00 0x80000000
+ MX6QDL_PAD_NANDF_D1__GPIO2_IO01 0x80000000
+ MX6QDL_PAD_NANDF_D2__GPIO2_IO02 0x80000000
+ MX6QDL_PAD_NANDF_D3__GPIO2_IO03 0x80000000
+ MX6QDL_PAD_GPIO_0__CCM_CLKO1 0x130b0
+ MX6QDL_PAD_NANDF_CLE__GPIO6_IO07 0x80000000
+ MX6QDL_PAD_NANDF_ALE__GPIO6_IO08 0x80000000
+ MX6QDL_PAD_ENET_TXD1__GPIO1_IO29 0x80000000
+ MX6QDL_PAD_EIM_D22__GPIO3_IO22 0x80000000
+ MX6QDL_PAD_ENET_CRS_DV__GPIO1_IO25 0x80000000
+ MX6QDL_PAD_EIM_D26__GPIO3_IO26 0x80000000
+ MX6QDL_PAD_EIM_CS1__GPIO2_IO24 0x80000000
+ MX6QDL_PAD_ENET_RXD0__GPIO1_IO27 0x80000000
+ MX6QDL_PAD_EIM_A25__GPIO5_IO02 0x80000000
+ MX6QDL_PAD_EIM_D23__GPIO3_IO23 0x80000000
+ MX6QDL_PAD_EIM_EB3__GPIO2_IO31 0x80000000
+ MX6QDL_PAD_SD1_CMD__GPIO1_IO18 0x80000000
+ MX6QDL_PAD_SD3_RST__GPIO7_IO08 0x80000000
+ MX6QDL_PAD_GPIO_9__GPIO1_IO09 0x80000000
+ MX6QDL_PAD_EIM_DA9__GPIO3_IO09 0x80000000
+ MX6QDL_PAD_GPIO_1__WDOG2_B 0x80000000
+ MX6QDL_PAD_NANDF_CS0__GPIO6_IO11 0x80000000
+ MX6QDL_PAD_NANDF_CS1__GPIO6_IO14 0x80000000
+ >;
+ };
+ pinctrl_ecspi1: ecspi1grp {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_D17__ECSPI1_MISO 0x100b1
+ MX6QDL_PAD_EIM_D18__ECSPI1_MOSI 0x100b1
+ MX6QDL_PAD_EIM_D16__ECSPI1_SCLK 0x100b1
+ >;
+ };
+ pinctrl_usdhc3: usdhc3grp {
+ fsl,pins = <
+ MX6QDL_PAD_SD3_CMD__SD3_CMD 0x170f9
+ MX6QDL_PAD_SD3_CLK__SD3_CLK 0x100f9
+ MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x170f9
+ MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x170f9
+ MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x170f9
+ MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x170f9
+ MX6QDL_PAD_SD3_DAT4__SD3_DATA4 0x170f9
+ MX6QDL_PAD_SD3_DAT5__SD3_DATA5 0x170f9
+ MX6QDL_PAD_SD3_DAT6__SD3_DATA6 0x170f9
+ MX6QDL_PAD_SD3_DAT7__SD3_DATA7 0x170f9
+ >;
+ };
+ };
+};
+
diff --git a/arch/arm/boot/dts/imx6dqscm-1gb-fix.dtsi b/arch/arm/boot/dts/imx6dqscm-1gb-fix.dtsi
new file mode 100644
index 000000000000..606d361aae18
--- /dev/null
+++ b/arch/arm/boot/dts/imx6dqscm-1gb-fix.dtsi
@@ -0,0 +1,14 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+/ {
+ memory: memory {
+ linux,usable-memory = <0x10000000 0x20000000
+ 0x80000000 0x20000000>;
+ };
+};
diff --git a/arch/arm/boot/dts/imx6dqscm-1gb-interleave-android.dtsi b/arch/arm/boot/dts/imx6dqscm-1gb-interleave-android.dtsi
new file mode 100644
index 000000000000..6edda09a9967
--- /dev/null
+++ b/arch/arm/boot/dts/imx6dqscm-1gb-interleave-android.dtsi
@@ -0,0 +1,14 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+/ {
+ memory: memory {
+ linux,usable-memory = <0x10000000 0x40000000>;
+ };
+
+};
diff --git a/arch/arm/boot/dts/imx6dqscm-1gb-qwks-rev2-fix-ldo.dts b/arch/arm/boot/dts/imx6dqscm-1gb-qwks-rev2-fix-ldo.dts
new file mode 100644
index 000000000000..436a90d8045d
--- /dev/null
+++ b/arch/arm/boot/dts/imx6dqscm-1gb-qwks-rev2-fix-ldo.dts
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2016 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 "imx6q.dtsi"
+#include "imx6dqscm-qwks-rev2.dtsi"
+#include "imx6dqscm-1gb-fix.dtsi"
+
+/ {
+ model = "Freescale i.MX6DQ SCM QWKS";
+ compatible = "fsl,imx6q";
+};
+
+&ldb {
+ lvds-channel@0 {
+ crtc = "ipu2-di0";
+ };
+
+ lvds-channel@1 {
+ crtc = "ipu2-di1";
+ };
+};
+
+&mxcfb1 {
+ status = "okay";
+};
+
+&mxcfb2 {
+ status = "okay";
+};
+
+&mxcfb3 {
+ status = "okay";
+};
+
+&mxcfb4 {
+ status = "okay";
+};
+
+&cpu0 {
+ arm-supply = <&reg_arm>;
+ soc-supply = <&reg_soc>;
+};
+
+&gpc {
+ /* use ldo-enable, u-boot will check it and configure */
+ fsl,ldo-bypass = <0>;
+};
+
+&wdog1 {
+ status = "okay";
+};
+
+&wdog2 {
+ status = "disabled";
+};
diff --git a/arch/arm/boot/dts/imx6dqscm-1gb-qwks-rev2-hdcp-fix-ldo.dts b/arch/arm/boot/dts/imx6dqscm-1gb-qwks-rev2-hdcp-fix-ldo.dts
new file mode 100644
index 000000000000..4aafc0deb162
--- /dev/null
+++ b/arch/arm/boot/dts/imx6dqscm-1gb-qwks-rev2-hdcp-fix-ldo.dts
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2016 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 "imx6dqscm-1gb-qwks-rev2-fix-ldo.dts"
+
+&hdmi_video {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_hdmi_hdcp>;
+ fsl,hdcp;
+};
+
+&i2c2 {
+ status = "disable";
+};
diff --git a/arch/arm/boot/dts/imx6dqscm-1gb-qwks-rev2-interleave-android-ldo.dts b/arch/arm/boot/dts/imx6dqscm-1gb-qwks-rev2-interleave-android-ldo.dts
new file mode 100644
index 000000000000..65734218691c
--- /dev/null
+++ b/arch/arm/boot/dts/imx6dqscm-1gb-qwks-rev2-interleave-android-ldo.dts
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2016 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 "imx6q.dtsi"
+#include "imx6dqscm-qwks-rev2.dtsi"
+#include "imx6dqscm-1gb-interleave-android.dtsi"
+
+/ {
+ model = "Freescale i.MX6DQ SCM QWKS";
+ compatible = "fsl,imx6q";
+};
+
+&ldb {
+ lvds-channel@0 {
+ crtc = "ipu2-di0";
+ };
+
+ lvds-channel@1 {
+ crtc = "ipu2-di1";
+ };
+};
+
+&mxcfb1 {
+ status = "okay";
+};
+
+&mxcfb2 {
+ status = "okay";
+};
+
+&mxcfb3 {
+ status = "okay";
+};
+
+&mxcfb4 {
+ status = "okay";
+};
+
+&cpu0 {
+ arm-supply = <&reg_arm>;
+ soc-supply = <&reg_soc>;
+};
+
+&gpc {
+ /* use ldo-enable, u-boot will check it and configure */
+ fsl,ldo-bypass = <0>;
+};
+
+&wdog1 {
+ status = "okay";
+};
+
+&wdog2 {
+ status = "disabled";
+};
diff --git a/arch/arm/boot/dts/imx6dqscm-1gb-qwks-rev2-wifi-fix-ldo.dts b/arch/arm/boot/dts/imx6dqscm-1gb-qwks-rev2-wifi-fix-ldo.dts
new file mode 100644
index 000000000000..16171a23fa27
--- /dev/null
+++ b/arch/arm/boot/dts/imx6dqscm-1gb-qwks-rev2-wifi-fix-ldo.dts
@@ -0,0 +1,10 @@
+/*
+ * Copyright (C) 2016 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 "imx6dqscm-1gb-qwks-rev2-fix-ldo.dts"
+#include "imx6dqscm-qwks-wifi.dtsi"
diff --git a/arch/arm/boot/dts/imx6dqscm-1gb-qwks-rev3-btwifi-fix-ldo.dts b/arch/arm/boot/dts/imx6dqscm-1gb-qwks-rev3-btwifi-fix-ldo.dts
new file mode 100644
index 000000000000..d376141dcb7a
--- /dev/null
+++ b/arch/arm/boot/dts/imx6dqscm-1gb-qwks-rev3-btwifi-fix-ldo.dts
@@ -0,0 +1,10 @@
+/*
+ * Copyright (C) 2016 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 "imx6dqscm-1gb-qwks-rev3-fix-ldo.dts"
+#include "imx6dqscm-qwks-rev3-btwifi.dtsi"
diff --git a/arch/arm/boot/dts/imx6dqscm-1gb-qwks-rev3-fix-ldo.dts b/arch/arm/boot/dts/imx6dqscm-1gb-qwks-rev3-fix-ldo.dts
new file mode 100644
index 000000000000..3a42eaa538ef
--- /dev/null
+++ b/arch/arm/boot/dts/imx6dqscm-1gb-qwks-rev3-fix-ldo.dts
@@ -0,0 +1,147 @@
+/*
+ * Copyright (C) 2016 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 "imx6dqscm-1gb-qwks-rev2-fix-ldo.dts"
+
+/ {
+ regulators {
+ reg_usb_otg_vbus: regulator@0 {
+ compatible = "regulator-fixed";
+ reg = <0>;
+ regulator-name = "usb_otg_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&gpio4 15 0>;
+ enable-active-high;
+ };
+ };
+
+ v4l2_cap_1 {
+ compatible = "fsl,imx6q-v4l2-capture";
+ ipu_id = <0>;
+ csi_id = <1>;
+ mclk_source = <0>;
+ status = "okay";
+ };
+};
+
+&i2c2 {
+ ov564x_mipi: ov564x_mipi@3c {
+ compatible = "ovti,ov564x_mipi";
+ reg = <0x3c>;
+ clocks = <&clks 201>;
+ clock-names = "csi_mclk";
+ DOVDD-supply = <&sw4_reg>;
+ AVDD-supply = <&vgen3_reg>;
+ DVDD-supply = <&vgen2_reg>;
+ pwn-gpios = <&gpio1 19 1>;
+ rst-gpios = <&gpio1 20 0>;
+ csi_id = <1>;
+ mclk = <24000000>;
+ mclk_source = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_cam>;
+ };
+
+ pmic: pfuze100@08 {
+ regulators {
+ vgen5_reg: vgen5 {
+ regulator-max-microvolt = <2500000>;
+ };
+ };
+ };
+};
+
+&i2c3 {
+ egalax_ts@04 {
+ compatible = "eeti,egalax_ts";
+ reg = <0x04>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c3_egalax_int>;
+ interrupt-parent = <&gpio6>;
+ interrupts = <14 0>;
+ wakeup-gpios = <&gpio4 10 GPIO_ACTIVE_HIGH>;
+ };
+};
+
+&mipi_csi {
+ status = "okay";
+ ipu_id = <0>;
+ csi_id = <1>;
+ v_channel = <0>;
+ lanes = <2>;
+};
+
+&usdhc3 {
+ cd-gpios = <&gpio7 1 GPIO_ACTIVE_LOW>;
+};
+
+&fec {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_enet>;
+ phy-mode = "rmii";
+ phy-reset-gpios = <&gpio5 12 0>;
+ fsl,magic-packet;
+ assigned-clocks = <&clks IMX6QDL_CLK_ENET_REF >;
+ assigned-clock-rates = <50000000>;
+ status = "okay";
+};
+
+&iomuxc {
+ imx6dqscm-cam {
+ pinctrl_cam: camgrp {
+ fsl,pins = <
+ MX6QDL_PAD_GPIO_0__CCM_CLKO1 0x130b0
+ MX6QDL_PAD_SD1_CLK__GPIO1_IO20 0x13069
+ MX6QDL_PAD_SD1_DAT2__GPIO1_IO19 0x13069
+ >;
+ };
+ };
+
+ imx6qdl-sabresd {
+ 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
+ MX6QDL_PAD_SD3_DAT4__GPIO7_IO01 0x80000000
+ >;
+ };
+
+ pinctrl_i2c1: i2c1grp {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_D28__I2C1_SDA 0x4001b8b1
+ MX6QDL_PAD_EIM_D21__I2C1_SCL 0x4001b8b1
+ >;
+ };
+
+ pinctrl_usbotg: usbotggrp {
+ fsl,pins = <
+ MX6QDL_PAD_GPIO_1__USB_OTG_ID 0x17059
+ MX6QDL_PAD_KEY_ROW4__GPIO4_IO15 0x17059
+ >;
+ };
+ pinctrl_enet: enetgrp {
+ fsl,pins = <
+ MX6QDL_PAD_GPIO_16__ENET_REF_CLK 0x4001b0a8
+ MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x1b0b0
+ MX6QDL_PAD_ENET_MDC__ENET_MDC 0x1b0b0
+ MX6QDL_PAD_ENET_TXD0__ENET_TX_DATA0 0x1b0b0
+ MX6QDL_PAD_ENET_TXD1__ENET_TX_DATA1 0x1b0b0
+ MX6QDL_PAD_ENET_TX_EN__ENET_TX_EN 0x1b0b0
+ MX6QDL_PAD_ENET_RX_ER__ENET_RX_ER 0x1b0b0
+ MX6QDL_PAD_ENET_RXD0__ENET_RX_DATA0 0x1b0b0
+ MX6QDL_PAD_ENET_RXD1__ENET_RX_DATA1 0x1b0b0
+ MX6QDL_PAD_ENET_CRS_DV__ENET_RX_EN 0x1b0b0
+ >;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/imx6dqscm-1gb-qwks-rev3-hdcp-fix-ldo.dts b/arch/arm/boot/dts/imx6dqscm-1gb-qwks-rev3-hdcp-fix-ldo.dts
new file mode 100644
index 000000000000..1a789fe21858
--- /dev/null
+++ b/arch/arm/boot/dts/imx6dqscm-1gb-qwks-rev3-hdcp-fix-ldo.dts
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2016 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 "imx6dqscm-1gb-qwks-rev3-fix-ldo.dts"
+
+&hdmi_video {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_hdmi_hdcp>;
+ fsl,hdcp;
+};
+
+&i2c2 {
+ status = "disable";
+};
diff --git a/arch/arm/boot/dts/imx6dqscm-qwks-rev2.dtsi b/arch/arm/boot/dts/imx6dqscm-qwks-rev2.dtsi
new file mode 100644
index 000000000000..cff0b7525bd1
--- /dev/null
+++ b/arch/arm/boot/dts/imx6dqscm-qwks-rev2.dtsi
@@ -0,0 +1,610 @@
+/*
+ * Copyright (C) 2016 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 <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+ aliases {
+ mxcfb0 = &mxcfb1;
+ mxcfb1 = &mxcfb2;
+ mxcfb2 = &mxcfb3;
+ mxcfb3 = &mxcfb4;
+ };
+
+ soc {
+ busfreq {
+ fsl,max_ddr_freq = <400000000>;
+ status = "okay";
+ };
+ };
+
+ hannstar_cabc {
+ compatible = "hannstar,cabc";
+
+ lvds0 {
+ gpios = <&gpio6 15 GPIO_ACTIVE_LOW>;
+
+ };
+ };
+
+ chosen {
+ stdout-path = &uart1;
+ };
+
+ memory: memory {
+ reg = <0x10000000 0x40000000>;
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ reg_usb_otg_vbus: regulator@0 {
+ compatible = "regulator-fixed";
+ reg = <0>;
+ regulator-name = "usb_otg_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&gpio3 22 0>;
+ enable-active-high;
+ };
+ };
+
+ sound-hdmi {
+ compatible = "fsl,imx6q-audio-hdmi",
+ "fsl,imx-audio-hdmi";
+ model = "imx-audio-hdmi";
+ hdmi-controller = <&hdmi_audio>;
+ };
+
+ mxcfb1: fb@0 {
+ compatible = "fsl,mxc_sdc_fb";
+ disp_dev = "ldb";
+ interface_pix_fmt = "RGB666";
+ default_bpp = <16>;
+ int_clk = <0>;
+ late_init = <0>;
+ status = "disabled";
+ };
+
+ mxcfb2: fb@1 {
+ compatible = "fsl,mxc_sdc_fb";
+ disp_dev = "hdmi";
+ interface_pix_fmt = "RGB24";
+ mode_str ="1920x1080M@60";
+ default_bpp = <24>;
+ int_clk = <0>;
+ late_init = <0>;
+ status = "disabled";
+ };
+
+ mxcfb3: fb@2 {
+ compatible = "fsl,mxc_sdc_fb";
+ disp_dev = "lcd";
+ interface_pix_fmt = "RGB565";
+ mode_str ="CLAA-WVGA";
+ default_bpp = <16>;
+ int_clk = <0>;
+ late_init = <0>;
+ status = "disabled";
+ };
+
+ mxcfb4: fb@3 {
+ compatible = "fsl,mxc_sdc_fb";
+ disp_dev = "ldb";
+ interface_pix_fmt = "RGB666";
+ default_bpp = <16>;
+ int_clk = <0>;
+ late_init = <0>;
+ status = "disabled";
+ };
+ backlight {
+ compatible = "pwm-backlight";
+ pwms = <&pwm4 0 5000000>;
+ brightness-levels = <0 4 8 16 32 64 128 255>;
+ default-brightness-level = <7>;
+ status = "okay";
+ };
+
+ v4l2_out {
+ compatible = "fsl,mxc_v4l2_output";
+ status = "okay";
+ };
+ gpio-keys {
+ compatible = "gpio-keys";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpio_keys>;
+
+ power {
+ label = "Power Button";
+ gpios = <&gpio5 2 GPIO_ACTIVE_LOW>;
+ wakeup-source;
+ linux,code = <KEY_POWER>;
+ };
+ };
+
+};
+
+&reg_arm {
+ vin-supply = <&sw1a_reg>;
+ regulator-allow-bypass;
+};
+
+&reg_soc {
+ vin-supply = <&sw1c_reg>;
+ regulator-allow-bypass;
+};
+
+&reg_pu {
+ vin-supply = <&sw1c_reg>;
+ regulator-allow-bypass;
+};
+
+&clks {
+ assigned-clocks = <&clks IMX6QDL_CLK_LDB_DI0_SEL>,
+ <&clks IMX6QDL_CLK_LDB_DI1_SEL>;
+ assigned-clock-parents = <&clks IMX6QDL_CLK_MMDC_CH1_AXI>,
+ <&clks IMX6QDL_CLK_MMDC_CH1_AXI>;
+};
+
+&ecspi1 {
+ fsl,spi-num-chipselects = <1>;
+ cs-gpios = <&gpio2 30 0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ecspi1>;
+ status = "okay";
+ flash: m25p80@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "micron,n25q128a13", "jedec,spi-nor";
+ spi-max-frequency = <20000000>;
+ reg = <0>;
+ };
+};
+
+&i2c1 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c1>;
+ status = "okay";
+};
+
+&i2c2 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c2>;
+ status = "okay";
+
+ hdmi_edid: edid@50 {
+ compatible = "fsl,imx6-hdmi-i2c";
+ reg = <0x50>;
+ };
+
+ pmic: pfuze100@08 {
+ compatible = "fsl,pfuze100";
+ reg = <0x08>;
+ regulators {
+ sw1a_reg: sw1ab {
+ regulator-min-microvolt = <300000>;
+ regulator-max-microvolt = <1875000>;
+ regulator-boot-on;
+ regulator-always-on;
+ regulator-ramp-delay = <6250>;
+ };
+
+ sw1c_reg: sw1c {
+ regulator-min-microvolt = <300000>;
+ regulator-max-microvolt = <1875000>;
+ regulator-boot-on;
+ regulator-always-on;
+ regulator-ramp-delay = <6250>;
+ };
+
+ sw2_reg: sw2 {
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ sw3a_reg: sw3a {
+ regulator-min-microvolt = <400000>;
+ regulator-max-microvolt = <1250000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ sw3b_reg: sw3b {
+ regulator-min-microvolt = <400000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ sw4_reg: sw4 {
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ swbst_reg: swbst {
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5150000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ snvs_reg: vsnvs {
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ vref_reg: vrefddr {
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ vgen1_reg: vgen1 {
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1550000>;
+ regulator-always-on;
+ };
+
+ vgen2_reg: vgen2 {
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1550000>;
+ regulator-always-on;
+ };
+
+ vgen3_reg: vgen3 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <2800000>;
+ regulator-always-on;
+ };
+
+ vgen4_reg: vgen4 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <2500000>;
+ regulator-always-on;
+ };
+
+ vgen5_reg: vgen5 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ vgen6_reg: vgen6 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+ };
+ };
+
+ egalax_ts@04 {
+ compatible = "eeti,egalax_ts";
+ reg = <0x04>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c2_egalax_int>;
+ interrupt-parent = <&gpio6>;
+ interrupts = <8 2>;
+ wakeup-gpios = <&gpio6 8 GPIO_ACTIVE_HIGH>;
+ };
+
+};
+
+&i2c3 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c3>;
+ status = "okay";
+ egalax_ts@04 {
+ compatible = "eeti,egalax_ts";
+ reg = <0x04>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c3_egalax_int>;
+ interrupt-parent = <&gpio6>;
+ interrupts = <7 2>;
+ wakeup-gpios = <&gpio6 7 GPIO_ACTIVE_HIGH>;
+ };
+
+ touchscreen@01 {
+ compatible = "vtl,ct365";
+ reg = <0x01>;
+ interrupt-parent = <&gpio6>;
+ interrupts = <14 0>;
+ gpios = <&gpio4 10 0>;
+ };
+
+};
+
+&iomuxc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_hog>;
+
+ imx6qdl-sabresd {
+ pinctrl_hog: hoggrp {
+ fsl,pins = <
+ MX6QDL_PAD_NANDF_D0__GPIO2_IO00 0x80000000
+ MX6QDL_PAD_NANDF_CS1__GPIO6_IO14 0x80000000
+ MX6QDL_PAD_NANDF_CS2__GPIO6_IO15 0x80000000
+ MX6QDL_PAD_KEY_COL2__GPIO4_IO10 0x80000000
+ MX6QDL_PAD_EIM_EB2__GPIO2_IO30 0x80000000
+ MX6QDL_PAD_EIM_D22__GPIO3_IO22 0x80000000
+ >;
+ };
+
+ pinctrl_gpio_keys: gpio_keysgrp {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_A25__GPIO5_IO02 0x1b0b0
+ >;
+ };
+
+ pinctrl_ecspi1: ecspi1grp {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_D17__ECSPI1_MISO 0x100b1
+ MX6QDL_PAD_EIM_D18__ECSPI1_MOSI 0x100b1
+ MX6QDL_PAD_EIM_D16__ECSPI1_SCLK 0x100b1
+ >;
+ };
+
+ pinctrl_i2c2_egalax_int: egalax_i2c2_intgrp {
+ fsl,pins = <
+ MX6QDL_PAD_NANDF_ALE__GPIO6_IO08 0x80000000
+ >;
+ };
+
+ pinctrl_i2c3_egalax_int: egalax_i2c3_intgrp {
+ fsl,pins = <
+ MX6QDL_PAD_NANDF_CLE__GPIO6_IO07 0x80000000
+ >;
+ };
+
+ pinctrl_hdmi_cec: hdmicecgrp {
+ fsl,pins = <
+ MX6QDL_PAD_KEY_ROW2__HDMI_TX_CEC_LINE 0x108b0
+ >;
+ };
+
+ pinctrl_hdmi_hdcp: hdmihdcpgrp {
+ fsl,pins = <
+ MX6QDL_PAD_KEY_COL3__HDMI_TX_DDC_SCL 0x4001b8b1
+ MX6QDL_PAD_KEY_ROW3__HDMI_TX_DDC_SDA 0x4001b8b1
+ >;
+ };
+
+ pinctrl_i2c1: i2c1grp {
+ fsl,pins = <
+ MX6QDL_PAD_CSI0_DAT8__I2C1_SDA 0x4001b8b1
+ MX6QDL_PAD_CSI0_DAT9__I2C1_SCL 0x4001b8b1
+ >;
+ };
+
+ 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_3__I2C3_SCL 0x4001b8b1
+ MX6QDL_PAD_GPIO_6__I2C3_SDA 0x4001b8b1
+ >;
+ };
+
+ pinctrl_pwm4: pwm4grp {
+ fsl,pins = <
+ MX6QDL_PAD_SD1_CMD__PWM4_OUT 0x1b0b1
+ >;
+ };
+
+ pinctrl_uart1: uart1grp {
+ fsl,pins = <
+ MX6QDL_PAD_CSI0_DAT10__UART1_TX_DATA 0x1b0b1
+ MX6QDL_PAD_CSI0_DAT11__UART1_RX_DATA 0x1b0b1
+ >;
+ };
+
+ pinctrl_usbotg: usbotggrp {
+ fsl,pins = <
+ MX6QDL_PAD_GPIO_1__USB_OTG_ID 0x17059
+ >;
+ };
+
+ pinctrl_usdhc2: usdhc2grp {
+ fsl,pins = <
+ MX6QDL_PAD_SD2_CMD__SD2_CMD 0x17059
+ MX6QDL_PAD_SD2_CLK__SD2_CLK 0x10059
+ MX6QDL_PAD_SD2_DAT0__SD2_DATA0 0x17059
+ MX6QDL_PAD_SD2_DAT1__SD2_DATA1 0x17059
+ MX6QDL_PAD_SD2_DAT2__SD2_DATA2 0x17059
+ MX6QDL_PAD_SD2_DAT3__SD2_DATA3 0x17059
+ >;
+ };
+
+ 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
+ >;
+ };
+
+ pinctrl_wdog: wdoggrp {
+ fsl,pins = <
+ MX6QDL_PAD_GPIO_1__WDOG2_B 0x80000000
+ >;
+ };
+
+ };
+};
+
+&dcic1 {
+ dcic_id = <0>;
+ dcic_mux = "dcic-hdmi";
+ status = "okay";
+};
+
+&dcic2 {
+ dcic_id = <1>;
+ dcic_mux = "dcic-lvds1";
+ status = "okay";
+};
+
+&gpc {
+ fsl,ldo-bypass = <1>;
+};
+
+&hdmi_audio {
+ status = "okay";
+};
+
+&hdmi_cec {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_hdmi_cec>;
+ status = "okay";
+};
+
+&hdmi_core {
+ ipu_id = <0>;
+ disp_id = <1>;
+ status = "okay";
+};
+
+&hdmi_video {
+ fsl,phy_reg_vlev = <0x0294>;
+ fsl,phy_reg_cksymtx = <0x800d>;
+ status = "okay";
+};
+
+&ldb {
+ status = "okay";
+
+ lvds-channel@0 {
+ fsl,data-mapping = "spwg";
+ fsl,data-width = <18>;
+ status = "okay";
+
+ display-timings {
+ native-mode = <&timing0>;
+ timing0: hsd100pxn1 {
+ clock-frequency = <65000000>;
+ hactive = <1024>;
+ vactive = <768>;
+ hback-porch = <220>;
+ hfront-porch = <40>;
+ vback-porch = <21>;
+ vfront-porch = <7>;
+ hsync-len = <60>;
+ vsync-len = <10>;
+ };
+ };
+ };
+
+ lvds-channel@1 {
+ fsl,data-mapping = "spwg";
+ fsl,data-width = <18>;
+ primary;
+ status = "okay";
+
+ display-timings {
+ native-mode = <&timing1>;
+ timing1: hsd100pxn1 {
+ clock-frequency = <65000000>;
+ hactive = <1024>;
+ vactive = <768>;
+ hback-porch = <220>;
+ hfront-porch = <40>;
+ vback-porch = <21>;
+ vfront-porch = <7>;
+ hsync-len = <60>;
+ vsync-len = <10>;
+ };
+ };
+ };
+};
+
+&pwm4 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pwm4>;
+ status = "okay";
+};
+
+&snvs_poweroff {
+ status = "okay";
+};
+
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart1>;
+ status = "okay";
+};
+
+&usbotg {
+ vbus-supply = <&reg_usb_otg_vbus>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usbotg>;
+ disable-over-current;
+ srp-disable;
+ hnp-disable;
+ adp-disable;
+ status = "okay";
+};
+
+&usbphy1 {
+ fsl,tx-d-cal = <106>;
+};
+
+&usbphy2 {
+ fsl,tx-d-cal = <106>;
+};
+
+&usdhc2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usdhc2>;
+ bus-width = <4>;
+ cd-gpios = <&gpio1 4 GPIO_ACTIVE_LOW>;
+ wp-gpios = <&gpio1 2 GPIO_ACTIVE_HIGH>;
+ no-1-8-v;
+ keep-power-in-suspend;
+ enable-sdio-wakeup;
+ status = "okay";
+};
+
+&usdhc3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usdhc3>;
+ bus-width = <4>;
+ cd-gpios = <&gpio2 0 GPIO_ACTIVE_LOW>;
+ no-1-8-v;
+ keep-power-in-suspend;
+ enable-sdio-wakeup;
+ status = "okay";
+};
+
+&wdog1 {
+ status = "disabled";
+};
+
+&wdog2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_wdog>;
+ fsl,ext-reset-output;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx6dqscm-qwks-rev3-btwifi.dtsi b/arch/arm/boot/dts/imx6dqscm-qwks-rev3-btwifi.dtsi
new file mode 100644
index 000000000000..dc41db6b1517
--- /dev/null
+++ b/arch/arm/boot/dts/imx6dqscm-qwks-rev3-btwifi.dtsi
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+/ {
+ modem_reset: modem-reset {
+ compatible = "gpio-reset";
+ reset-gpios = <&gpio6 1 GPIO_ACTIVE_LOW>;
+ reset-delay-us = <1000>;
+ #reset-cells = <0>;
+ };
+
+ regulators {
+ wlreg_on: fixedregulator@100 {
+ compatible = "regulator-fixed";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-name = "wlreg_on";
+ gpio = <&gpio6 5 0>;
+ startup-delay-us = <100>;
+ enable-active-high;
+ };
+ };
+
+ bcmdhd_wlan_0: bcmdhd_wlan@0 {
+ compatible = "android,bcmdhd_wlan";
+ wlreg_on-supply = <&wlreg_on>;
+ gpios = <&gpio6 4 0>; /* WL_HOST_WAKE */
+ };
+};
+
+&uart4 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart4
+ &pinctrl_bt>;
+ fsl,uart-has-rtscts;
+ resets = <&modem_reset>;
+ status = "okay";
+};
+
+&usdhc2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_wifi>;
+ bus-width = <4>;
+ no-1-8-v;
+ non-removable;
+ cd-post;
+ pm-ignore-notify;
+ wifi-host;
+};
+
+&iomuxc {
+ imx6dqscm-murata-v2 {
+ pinctrl_bt: btgrp {
+ fsl,pins = <
+ MX6QDL_PAD_CSI0_DAT15__GPIO6_IO01 0x13069
+ MX6QDL_PAD_CSI0_DAT14__GPIO6_IO00 0x13069
+ >;
+ };
+
+ pinctrl_wifi: wifigrp {
+ fsl,pins = <
+ MX6QDL_PAD_SD2_CMD__SD2_CMD 0x17059
+ MX6QDL_PAD_SD2_CLK__SD2_CLK 0x10059
+ MX6QDL_PAD_SD2_DAT0__SD2_DATA0 0x17059
+ MX6QDL_PAD_SD2_DAT1__SD2_DATA1 0x17059
+ MX6QDL_PAD_SD2_DAT2__SD2_DATA2 0x17059
+ MX6QDL_PAD_SD2_DAT3__SD2_DATA3 0x17059
+ MX6QDL_PAD_CSI0_DAT19__GPIO6_IO05 0x13069
+ MX6QDL_PAD_CSI0_DAT18__GPIO6_IO04 0x13069
+ >;
+ };
+ pinctrl_uart4: uart4grp {
+ fsl,pins = <
+ MX6QDL_PAD_CSI0_DAT12__UART4_TX_DATA 0x1f0b1
+ MX6QDL_PAD_CSI0_DAT13__UART4_RX_DATA 0x1f0b1
+ MX6QDL_PAD_CSI0_DAT16__UART4_RTS_B 0x1b0b1
+ MX6QDL_PAD_CSI0_DAT17__UART4_CTS_B 0x1b0b1
+ >;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/imx6dqscm-qwks-wifi.dtsi b/arch/arm/boot/dts/imx6dqscm-qwks-wifi.dtsi
new file mode 100644
index 000000000000..bafca7465bb2
--- /dev/null
+++ b/arch/arm/boot/dts/imx6dqscm-qwks-wifi.dtsi
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+/ {
+ regulators {
+ wlreg_on: fixedregulator@100 {
+ compatible = "regulator-fixed";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-name = "wlreg_on";
+ gpio = <&gpio4 30 0>;
+ startup-delay-us = <100>;
+ enable-active-high;
+ };
+ };
+
+ bcmdhd_wlan_0: bcmdhd_wlan@0 {
+ compatible = "android,bcmdhd_wlan";
+ wlreg_on-supply = <&wlreg_on>;
+ };
+};
+
+&iomuxc {
+ imx6qdl-sabresd-murata-v2 {
+ /* add MUXing entry for SD2 4-bit interface
+ * and configure control pins
+ */
+ pinctrl_wifi: wifigrp {
+ fsl,pins = <
+ MX6QDL_PAD_SD2_CMD__SD2_CMD 0x17059
+ MX6QDL_PAD_SD2_CLK__SD2_CLK 0x10059
+ MX6QDL_PAD_SD2_DAT0__SD2_DATA0 0x17059
+ MX6QDL_PAD_SD2_DAT1__SD2_DATA1 0x17059
+ MX6QDL_PAD_SD2_DAT2__SD2_DATA2 0x17059
+ MX6QDL_PAD_SD2_DAT3__SD2_DATA3 0x17059
+ MX6QDL_PAD_DISP0_DAT9__GPIO4_IO30 0x13069
+ >;
+ };
+ pinctrl_uart2: uart2grp {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_D26__UART2_TX_DATA 0x1f0b1
+ MX6QDL_PAD_EIM_D27__UART2_RX_DATA 0x1f0b1
+ MX6QDL_PAD_EIM_D28__UART2_CTS_B 0x1b0b1
+ MX6QDL_PAD_EIM_D29__UART2_RTS_B 0x1b0b1
+ MX6QDL_PAD_ENET_REF_CLK__GPIO1_IO23 0x13069
+ >;
+ };
+ pinctrl_uart5_1: uart5grp-1 {
+ fsl,pins = <
+ MX6QDL_PAD_KEY_COL1__UART5_TX_DATA 0x1b0b1
+ MX6QDL_PAD_KEY_ROW1__UART5_RX_DATA 0x1b0b1
+ MX6QDL_PAD_KEY_COL4__UART5_RTS_B 0x1b0b1
+ MX6QDL_PAD_KEY_ROW4__UART5_CTS_B 0x1b0b1
+ >;
+ };
+
+ };
+};
+
+&uart2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart2>;
+ fsl,uart-has-rtscts;
+ status = "okay";
+ /* for DTE mode, add below change */
+ /* fsl,dte-mode; */
+ /*pinctrl-0 = <&pinctrl_uart2dte>; */
+};
+
+&uart5 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart5_1>;
+ fsl,uart-has-rtscts;
+ status = "okay";
+ /* for DTE mode, add below change */
+ /* fsl,dte-mode; */
+ /* pinctrl-0 = <&pinctrl_uart5dte_1>; */
+};
+
+&usdhc2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_wifi>;
+ bus-width = <4>;
+ no-1-8-v;
+ non-removable;
+ cd-post;
+ pm-ignore-notify;
+ wifi-host;
+};
diff --git a/arch/arm/boot/dts/imx6q-arm2-hsic.dts b/arch/arm/boot/dts/imx6q-arm2-hsic.dts
new file mode 100644
index 000000000000..10c95ad96761
--- /dev/null
+++ b/arch/arm/boot/dts/imx6q-arm2-hsic.dts
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2015 Freescale Semiconductor, Inc.
+ *
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include "imx6q-arm2.dts"
+
+&fec {
+ status = "disabled";
+};
+
+&usbh2 {
+ pinctrl-names = "idle", "active";
+ pinctrl-0 = <&pinctrl_usbh2_1>;
+ pinctrl-1 = <&pinctrl_usbh2_2>;
+ osc-clkgate-delay = <0x3>;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx6q-arm2.dts b/arch/arm/boot/dts/imx6q-arm2.dts
index 4989d0bff10f..7793d73839e6 100644
--- a/arch/arm/boot/dts/imx6q-arm2.dts
+++ b/arch/arm/boot/dts/imx6q-arm2.dts
@@ -62,6 +62,7 @@
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_gpmi_nand>;
status = "disabled"; /* gpmi nand conflicts with SD */
+ nand-on-flash-bbt;
};
&iomuxc {
@@ -140,6 +141,32 @@
>;
};
+ pinctrl_usbh2_1: usbh2grp-1 {
+ fsl,pins = <
+ MX6QDL_PAD_RGMII_TXC__USB_H2_DATA 0x40013030
+ MX6QDL_PAD_RGMII_TX_CTL__USB_H2_STROBE 0x40013030
+ >;
+ };
+
+ pinctrl_usbh2_2: usbh2grp-2 {
+ fsl,pins = <
+ MX6QDL_PAD_RGMII_TX_CTL__USB_H2_STROBE 0x40017030
+ >;
+ };
+
+ pinctrl_usbh3_1: usbh3grp-1 {
+ fsl,pins = <
+ MX6QDL_PAD_RGMII_RX_CTL__USB_H3_DATA 0x40013030
+ MX6QDL_PAD_RGMII_RXC__USB_H3_STROBE 0x40013030
+ >;
+ };
+
+ pinctrl_usbh3_2: usbh3grp-2 {
+ fsl,pins = <
+ MX6QDL_PAD_RGMII_RXC__USB_H3_STROBE 0x40017030
+ >;
+ };
+
pinctrl_usdhc3: usdhc3grp {
fsl,pins = <
MX6QDL_PAD_SD3_CMD__SD3_CMD 0x17059
@@ -194,6 +221,9 @@
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_usbotg>;
disable-over-current;
+ srp-disable;
+ hnp-disable;
+ adp-disable;
status = "okay";
};
diff --git a/arch/arm/boot/dts/imx6q-gk802.dts b/arch/arm/boot/dts/imx6q-gk802.dts
index b715deb4ea46..b27b8aad987c 100644
--- a/arch/arm/boot/dts/imx6q-gk802.dts
+++ b/arch/arm/boot/dts/imx6q-gk802.dts
@@ -1,6 +1,8 @@
/*
* Copyright (C) 2013 Philipp Zabel
*
+ * Copyright 2015 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
* 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.
@@ -14,6 +16,10 @@
model = "Zealz GK802";
compatible = "zealz,imx6q-gk802", "fsl,imx6q";
+ aliases {
+ mxcfb0 = &mxcfb1;
+ };
+
chosen {
stdout-path = &uart4;
};
@@ -47,10 +53,28 @@
wakeup-source;
};
};
+
+ mxcfb1: fb@0 {
+ compatible = "fsl,mxc_sdc_fb";
+ disp_dev = "hdmi";
+ interface_pix_fmt = "RGB24";
+ mode_str ="1920x1080M@60";
+ default_bpp = <24>;
+ int_clk = <0>;
+ late_init = <0>;
+ status = "okay";
+ };
};
-&hdmi {
- ddc-i2c-bus = <&i2c3>;
+&hdmi_core {
+ ipu_id = <0>;
+ disp_id = <0>;
+ status = "okay";
+};
+
+&hdmi_video {
+ fsl,phy_reg_vlev = <0x0294>;
+ fsl,phy_reg_cksymtx = <0x800d>;
status = "okay";
};
@@ -74,6 +98,11 @@
pinctrl-0 = <&pinctrl_i2c3>;
clock-frequency = <100000>;
status = "okay";
+
+ hdmi_edid: edid@50 {
+ compatible = "fsl,imx6-hdmi-i2c";
+ reg = <0x50>;
+ };
};
&iomuxc {
diff --git a/arch/arm/boot/dts/imx6q-gw5400-a.dts b/arch/arm/boot/dts/imx6q-gw5400-a.dts
index 9dbeea05a949..427b2cd104f7 100644
--- a/arch/arm/boot/dts/imx6q-gw5400-a.dts
+++ b/arch/arm/boot/dts/imx6q-gw5400-a.dts
@@ -1,6 +1,8 @@
/*
* Copyright 2013 Gateworks Corporation
*
+ * Copyright 2015 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
* 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:
@@ -29,6 +31,7 @@
spi0 = &ecspi1;
usb0 = &usbh1;
usb1 = &usbotg;
+ mxcfb0 = &mxcfb1;
};
chosen {
@@ -128,6 +131,17 @@
mux-int-port = <1>;
mux-ext-port = <4>;
};
+
+ mxcfb1: fb@0 {
+ compatible = "fsl,mxc_sdc_fb";
+ disp_dev = "hdmi";
+ interface_pix_fmt = "RGB24";
+ mode_str ="1920x1080M@60";
+ default_bpp = <24>;
+ int_clk = <0>;
+ late_init = <0>;
+ status = "okay";
+ };
};
&audmux {
@@ -157,8 +171,15 @@
status = "okay";
};
-&hdmi {
- ddc-i2c-bus = <&i2c3>;
+&hdmi_core {
+ ipu_id = <0>;
+ disp_id = <0>;
+ status = "okay";
+};
+
+&hdmi_video {
+ fsl,phy_reg_vlev = <0x0294>;
+ fsl,phy_reg_cksymtx = <0x800d>;
status = "okay";
};
@@ -330,6 +351,11 @@
VDDIO-supply = <&reg_3p3v>;
};
+ hdmi_edid: edid@50 {
+ compatible = "fsl,imx6-hdmi-i2c";
+ reg = <0x50>;
+ };
+
touchscreen: egalax_ts@04 {
compatible = "eeti,egalax_ts";
reg = <0x04>;
diff --git a/arch/arm/boot/dts/imx6q-pop-arm2.dts b/arch/arm/boot/dts/imx6q-pop-arm2.dts
new file mode 100644
index 000000000000..df6e2a329aa9
--- /dev/null
+++ b/arch/arm/boot/dts/imx6q-pop-arm2.dts
@@ -0,0 +1,437 @@
+/*
+ * Copyright 2015 Freescale Semiconductor, Inc.
+ *
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/dts-v1/;
+#include <dt-bindings/gpio/gpio.h>
+#include "imx6q.dtsi"
+
+/ {
+ model = "Freescale i.MX6 Quad Armadillo2 Board";
+ compatible = "fsl,imx6q-pop-arm2", "fsl,imx6q";
+
+ aliases {
+ mxcfb0 = &mxcfb1;
+ mxcfb1 = &mxcfb2;
+ };
+
+ pwm-backlight {
+ compatible = "pwm-backlight";
+ pwms = <&pwm1 0 50000>;
+ power-supply = <&reg_lvds_3p3v>;
+ brightness-levels = <
+ 0 1 2 3 4 5 6 7 8 9
+ 10 11 12 13 14 15 16 17 18 19
+ 20 21 22 23 24 25 26 27 28 29
+ 30 31 32 33 34 35 36 37 38 39
+ 40 41 42 43 44 45 46 47 48 49
+ 50 51 52 53 54 55 56 57 58 59
+ 60 61 62 63 64 65 66 67 68 69
+ 70 71 72 73 74 75 76 77 78 79
+ 80 81 82 83 84 85 86 87 88 89
+ 90 91 92 93 94 95 96 97 98 99
+ 100
+ >;
+ default-brightness-level = <94>;
+ status = "okay";
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpio_keys>;
+
+ power {
+ label = "Power Button";
+ gpios = <&gpio3 30 1>;
+ linux,code = <116>;
+ gpio-key,wakeup;
+ };
+ };
+
+ hannstar_cabc {
+ compatible = "hannstar,cabc";
+ lvds_share {
+ gpios = <&max7310_a 0 GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ memory {
+ linux,usable-memory = <0x10000000 0x20000000>,
+ <0x80000000 0x20000000>;
+ };
+
+ mxcfb1: fb@0 {
+ compatible = "fsl,mxc_sdc_fb";
+ disp_dev = "ldb";
+ interface_pix_fmt = "RGB666";
+ default_bpp = <16>;
+ int_clk = <0>;
+ late_init = <0>;
+ status = "okay";
+ };
+
+ mxcfb2: fb@1 {
+ compatible = "fsl,mxc_sdc_fb";
+ disp_dev = "hdmi";
+ interface_pix_fmt = "RGB24";
+ mode_str = "1920x1080M@60";
+ default_bpp = <24>;
+ int_clk = <0>;
+ late_init = <0>;
+ status = "okay";
+ };
+
+ sound-hdmi {
+ compatible = "fsl,imx6q-audio-hdmi", "fsl,imx-audio-hdmi";
+ model = "imx-audio-hdmi";
+ hdmi-controller = <&hdmi_audio>;
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ reg_3p3v: regulator@0 {
+ compatible = "regulator-fixed";
+ reg = <0>;
+ regulator-name = "3P3V";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ reg_usb_otg_vbus: regulator@1 {
+ compatible = "regulator-fixed";
+ reg = <1>;
+ regulator-name = "usb_otg_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&gpio3 22 0>;
+ enable-active-high;
+ };
+
+ reg_lvds_3p3v: regulator@2 {
+ compatible = "regulator-fixed";
+ reg = <2>;
+ regulator-name = "LVDS-3P3V";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&max7310_b 1 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ regulator-always-on;
+ };
+ };
+};
+
+&cpu0 {
+ fsl,arm-soc-shared = <1>;
+};
+
+&busfreq {
+ fsl,max_ddr_freq = <400000000>;
+};
+
+&dcic1 {
+ dcic_id = <0>;
+ dcic_mux = "dcic-hdmi";
+ status = "okay";
+};
+
+&dcic2 {
+ dcic_id = <1>;
+ dcic_mux = "dcic-lvds0";
+ status = "okay";
+};
+
+&fec {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_enet>;
+ phy-mode = "rgmii";
+ status = "okay";
+};
+
+&hdmi_audio {
+ status = "okay";
+};
+
+&hdmi_cec {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_hdmi_cec>;
+ status = "okay";
+};
+
+&hdmi_core {
+ ipu_id = <0>;
+ disp_id = <1>;
+ status = "okay";
+};
+
+&hdmi_video {
+ fsl,phy_reg_vlev = <0x0294>;
+ fsl,phy_reg_cksymtx = <0x800d>;
+ status = "okay";
+};
+
+&i2c2 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c2>;
+ status = "okay";
+
+ hdmi_edid: edid@50 {
+ compatible = "fsl,imx6-hdmi-i2c";
+ reg = <0x50>;
+ };
+
+ egalax_ts@04 {
+ compatible = "eeti,egalax_ts";
+ reg = <0x04>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_egalax_int>;
+ interrupt-parent = <&gpio3>;
+ interrupts = <31 2>;
+ wakeup-gpios = <&gpio3 31 0>;
+ };
+};
+
+&i2c3 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c3>;
+ status = "okay";
+
+ max7310_a: gpio@1b {
+ compatible = "maxim,max7310";
+ reg = <0x1b>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ max7310_b: gpio@1f {
+ compatible = "maxim,max7310";
+ reg = <0x1f>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+};
+
+&iomuxc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_hog>;
+
+ imx6q-arm2 {
+ pinctrl_hog: hoggrp {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_D25__GPIO3_IO25 0x80000000
+ >;
+ };
+
+ pinctrl_enet: enetgrp {
+ fsl,pins = <
+ MX6QDL_PAD_KEY_COL1__ENET_MDIO 0x1b0b0
+ MX6QDL_PAD_KEY_COL2__ENET_MDC 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_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
+ >;
+ };
+
+ pinctrl_gpio_keys: gpio_keysgrp {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_D30__GPIO3_IO30 0x1b0b0
+ >;
+ };
+
+ pinctrl_hdmi_cec: hdmicecgrp {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_A25__HDMI_TX_CEC_LINE 0x108b0
+ >;
+ };
+
+ pinctrl_hdmi_hdcp: hdmihdcpgrp {
+ fsl,pins = <
+ MX6QDL_PAD_KEY_COL3__HDMI_TX_DDC_SCL 0x4001b8b1
+ MX6QDL_PAD_KEY_ROW3__HDMI_TX_DDC_SDA 0x4001b8b1
+ >;
+ };
+
+ 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_egalax_int: egalax_intgrp {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_D31__GPIO3_IO31 0x80000000
+ >;
+ };
+
+ pinctrl_pwm1: pwm1grp {
+ fsl,pins = <
+ MX6QDL_PAD_GPIO_9__PWM1_OUT 0x1b0b1
+ >;
+ };
+
+ pinctrl_uart2: uart2grp {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_D26__UART2_RX_DATA 0x1b0b1
+ MX6QDL_PAD_EIM_D27__UART2_TX_DATA 0x1b0b1
+ MX6QDL_PAD_EIM_D28__UART2_DTE_CTS_B 0x1b0b1
+ MX6QDL_PAD_EIM_D29__UART2_DTE_RTS_B 0x1b0b1
+ >;
+ };
+
+ pinctrl_uart4: uart4grp {
+ fsl,pins = <
+ MX6QDL_PAD_KEY_COL0__UART4_TX_DATA 0x1b0b1
+ MX6QDL_PAD_KEY_ROW0__UART4_RX_DATA 0x1b0b1
+ >;
+ };
+
+ pinctrl_usbotg: usbotggrp {
+ fsl,pins = <
+ MX6QDL_PAD_GPIO_1__USB_OTG_ID 0x17059
+ >;
+ };
+
+ 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
+ MX6QDL_PAD_SD3_DAT4__SD3_DATA4 0x17059
+ MX6QDL_PAD_SD3_DAT5__SD3_DATA5 0x17059
+ MX6QDL_PAD_SD3_DAT6__SD3_DATA6 0x17059
+ MX6QDL_PAD_SD3_DAT7__SD3_DATA7 0x17059
+ >;
+ };
+
+ pinctrl_usdhc3_cdwp: usdhc3cdwp {
+ fsl,pins = <
+ MX6QDL_PAD_NANDF_CS0__GPIO6_IO11 0x80000000
+ MX6QDL_PAD_NANDF_CS1__GPIO6_IO14 0x80000000
+ >;
+ };
+
+ pinctrl_usdhc4: usdhc4grp {
+ fsl,pins = <
+ MX6QDL_PAD_SD4_CMD__SD4_CMD 0x17059
+ MX6QDL_PAD_SD4_CLK__SD4_CLK 0x10059
+ MX6QDL_PAD_SD4_DAT0__SD4_DATA0 0x17059
+ MX6QDL_PAD_SD4_DAT1__SD4_DATA1 0x17059
+ MX6QDL_PAD_SD4_DAT2__SD4_DATA2 0x17059
+ MX6QDL_PAD_SD4_DAT3__SD4_DATA3 0x17059
+ MX6QDL_PAD_SD4_DAT4__SD4_DATA4 0x17059
+ MX6QDL_PAD_SD4_DAT5__SD4_DATA5 0x17059
+ MX6QDL_PAD_SD4_DAT6__SD4_DATA6 0x17059
+ MX6QDL_PAD_SD4_DAT7__SD4_DATA7 0x17059
+ >;
+ };
+ };
+};
+
+&ldb {
+ status = "okay";
+
+ lvds-channel@0 {
+ fsl,data-mapping = "spwg";
+ fsl,data-width = <18>;
+ crtc = "ipu2-di0";
+ primary;
+ status = "okay";
+
+ display-timings {
+ native-mode = <&timing0>;
+ timing0: hsd100pxn1 {
+ clock-frequency = <65000000>;
+ hactive = <1024>;
+ vactive = <768>;
+ hback-porch = <220>;
+ hfront-porch = <40>;
+ vback-porch = <21>;
+ vfront-porch = <7>;
+ hsync-len = <60>;
+ vsync-len = <10>;
+ };
+ };
+ };
+};
+
+&pwm1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pwm1>;
+ status = "okay";
+};
+
+&uart2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart2>;
+ fsl,dte-mode;
+ fsl,uart-has-rtscts;
+ status = "okay";
+};
+
+&uart4 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart4>;
+ status = "okay";
+};
+
+&usbotg {
+ vbus-supply = <&reg_usb_otg_vbus>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usbotg>;
+ disable-over-current;
+ srp-disable;
+ hnp-disable;
+ adp-disable;
+ status = "okay";
+};
+
+&usdhc3 {
+ wp-gpios = <&gpio6 14 0>;
+ vmmc-supply = <&reg_3p3v>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usdhc3
+ &pinctrl_usdhc3_cdwp>;
+ status = "okay";
+};
+
+&usdhc4 {
+ non-removable;
+ vmmc-supply = <&reg_3p3v>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usdhc4>;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx6q-sabreauto-ecspi.dts b/arch/arm/boot/dts/imx6q-sabreauto-ecspi.dts
new file mode 100644
index 000000000000..3cf99ed9be6b
--- /dev/null
+++ b/arch/arm/boot/dts/imx6q-sabreauto-ecspi.dts
@@ -0,0 +1,40 @@
+/*
+ * 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 "imx6q-sabreauto.dts"
+
+&ecspi1 {
+ pinctrl-assert-gpios = <&gpio5 4 GPIO_ACTIVE_LOW>;
+ status = "okay";
+};
+
+&can2 {
+ /* max7310_c on i2c3 is gone */
+ status = "disabled";
+};
+
+&i2c3 {
+ /* pin conflict with ecspi1 */
+ status = "disabled";
+};
+
+&uart3 {
+ /* the uart3 depends on the i2c3, so disable it too. */
+ status = "disabled";
+};
+
+&usbh1 {
+ /* max7310_b on i2c3 is gone */
+ status = "disabled";
+};
+
+&usbotg {
+ /* max7310_c on i2c3 is gone */
+ status = "okay";
+ dr_mode = "peripheral";
+};
diff --git a/arch/arm/boot/dts/imx6q-sabreauto-enetirq.dts b/arch/arm/boot/dts/imx6q-sabreauto-enetirq.dts
new file mode 100644
index 000000000000..7acb794fbaa6
--- /dev/null
+++ b/arch/arm/boot/dts/imx6q-sabreauto-enetirq.dts
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2015 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 "imx6q-sabreauto.dts"
+
+&fec {
+ pinctrl-0 = <&pinctrl_enet &pinctrl_enet_irq>;
+ interrupts-extended = <&gpio1 6 IRQ_TYPE_LEVEL_HIGH>,
+ <&gpc 0 119 IRQ_TYPE_LEVEL_HIGH>;
+};
+
+&mlb {
+ status = "disabled";
+};
diff --git a/arch/arm/boot/dts/imx6q-sabreauto-flexcan1.dts b/arch/arm/boot/dts/imx6q-sabreauto-flexcan1.dts
new file mode 100644
index 000000000000..71dd58944801
--- /dev/null
+++ b/arch/arm/boot/dts/imx6q-sabreauto-flexcan1.dts
@@ -0,0 +1,18 @@
+/*
+ * Copyright (C) 2013 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 "imx6q-sabreauto.dts"
+
+&can1{
+ status = "okay";
+};
+
+&fec {
+ /* pin conflict with flexcan1 */
+ status = "disabled";
+};
diff --git a/arch/arm/boot/dts/imx6q-sabreauto-gpmi-weim.dts b/arch/arm/boot/dts/imx6q-sabreauto-gpmi-weim.dts
new file mode 100644
index 000000000000..579aeb26e05d
--- /dev/null
+++ b/arch/arm/boot/dts/imx6q-sabreauto-gpmi-weim.dts
@@ -0,0 +1,49 @@
+/*
+ * 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 "imx6q-sabreauto.dts"
+
+&ecspi1 {
+ /* pin conflict with weim */
+ status = "disabled";
+};
+
+&can2 {
+ /* max7310_c on i2c3 is gone */
+ status = "disabled";
+};
+
+&gpmi {
+ status = "okay";
+};
+
+&i2c3 {
+ /* pin conflict with weim */
+ status = "disabled";
+};
+
+&uart3 {
+ /* pin conflict with gpmi and weim */
+ status = "disabled";
+};
+
+&usbh1 {
+ /* max7310_b on i2c3 is gone */
+ status = "disabled";
+};
+
+&usbotg {
+ /* max7310_c on i2c3 is gone */
+ status = "okay";
+ dr_mode = "peripheral";
+};
+
+&weim {
+ pinctrl-assert-gpios = <&gpio5 4 GPIO_ACTIVE_LOW>;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx6q-sabreauto.dts b/arch/arm/boot/dts/imx6q-sabreauto.dts
index 334b9247e78c..a321a20832df 100644
--- a/arch/arm/boot/dts/imx6q-sabreauto.dts
+++ b/arch/arm/boot/dts/imx6q-sabreauto.dts
@@ -1,5 +1,5 @@
/*
- * Copyright 2012 Freescale Semiconductor, Inc.
+ * Copyright 2012-2015 Freescale Semiconductor, Inc.
* Copyright 2011 Linaro Ltd.
*
* The code contained herein is licensed under the GNU General Public
@@ -20,6 +20,26 @@
compatible = "fsl,imx6q-sabreauto", "fsl,imx6q";
};
+&ldb {
+ lvds-channel@0 {
+ crtc = "ipu2-di0";
+ };
+ lvds-channel@1 {
+ crtc = "ipu2-di1";
+ };
+};
+&mxcfb1 {
+ status = "okay";
+};
+&mxcfb2 {
+ status = "okay";
+};
+&mxcfb3 {
+ status = "okay";
+};
+&mxcfb4 {
+ status = "okay";
+};
&sata {
status = "okay";
};
diff --git a/arch/arm/boot/dts/imx6q-sabresd-btwifi.dts b/arch/arm/boot/dts/imx6q-sabresd-btwifi.dts
new file mode 100644
index 000000000000..af65f3ad76f8
--- /dev/null
+++ b/arch/arm/boot/dts/imx6q-sabresd-btwifi.dts
@@ -0,0 +1,10 @@
+/*
+ * Copyright (C) 2015 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 "imx6q-sabresd.dts"
+#include "imx6qdl-sabresd-btwifi.dtsi"
diff --git a/arch/arm/boot/dts/imx6q-sabresd-enetirq.dts b/arch/arm/boot/dts/imx6q-sabresd-enetirq.dts
new file mode 100644
index 000000000000..69da4046a75b
--- /dev/null
+++ b/arch/arm/boot/dts/imx6q-sabresd-enetirq.dts
@@ -0,0 +1,18 @@
+/*
+ * 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 "imx6q-sabresd.dts"
+
+&fec {
+ pinctrl-0 = <&pinctrl_enet &pinctrl_enet_irq>;
+ interrupts-extended = <&gpio1 6 0x04>, <&gpc 0 119 0x04>;
+};
+
+&i2c3 {
+ status = "disabled";
+};
diff --git a/arch/arm/boot/dts/imx6q-sabresd-hdcp.dts b/arch/arm/boot/dts/imx6q-sabresd-hdcp.dts
new file mode 100644
index 000000000000..3116e3efb835
--- /dev/null
+++ b/arch/arm/boot/dts/imx6q-sabresd-hdcp.dts
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2012-2014 Freescale Semiconductor, Inc.
+ * Copyright 2011 Linaro Ltd.
+ *
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include "imx6q-sabresd.dts"
+
+&gpc {
+ /* use ldo-enable, u-boot will check it and configure */
+ fsl,ldo-bypass = <0>;
+};
+
+&hdmi_video {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_hdmi_hdcp>;
+ fsl,hdcp;
+};
+
+&i2c2 {
+ status = "disable";
+};
+
+&reg_arm {
+ /delete-property/ vin-supply;
+};
+
+&reg_pu {
+ /delete-property/ vin-supply;
+};
+
+&reg_soc {
+ /delete-property/ vin-supply;
+};
diff --git a/arch/arm/boot/dts/imx6q-sabresd-ldo.dts b/arch/arm/boot/dts/imx6q-sabresd-ldo.dts
new file mode 100644
index 000000000000..8363302dca35
--- /dev/null
+++ b/arch/arm/boot/dts/imx6q-sabresd-ldo.dts
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2015 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 "imx6q-sabresd.dts"
+
+&gpc {
+ /* use ldo-enable, u-boot will check it and configure */
+ fsl,ldo-bypass = <0>;
+};
+
+&reg_arm {
+ /delete-property/ vin-supply;
+};
+
+&reg_pu {
+ /delete-property/ vin-supply;
+};
+
+&reg_soc {
+ /delete-property/ vin-supply;
+};
+
+&wdog1 {
+ status = "okay";
+};
+
+&wdog2 {
+ status = "disabled";
+};
diff --git a/arch/arm/boot/dts/imx6q-sabresd.dts b/arch/arm/boot/dts/imx6q-sabresd.dts
index 527772b62fee..15db54c00d61 100644
--- a/arch/arm/boot/dts/imx6q-sabresd.dts
+++ b/arch/arm/boot/dts/imx6q-sabresd.dts
@@ -1,5 +1,5 @@
/*
- * Copyright 2012 Freescale Semiconductor, Inc.
+ * Copyright 2012=2015 Freescale Semiconductor, Inc.
* Copyright 2011 Linaro Ltd.
*
* The code contained herein is licensed under the GNU General Public
@@ -20,6 +20,38 @@
compatible = "fsl,imx6q-sabresd", "fsl,imx6q";
};
+&battery {
+ offset-charger = <1900>;
+ offset-discharger = <1694>;
+ offset-usb-charger = <1685>;
+};
+
+&ldb {
+ lvds-channel@0 {
+ crtc = "ipu2-di0";
+ };
+
+ lvds-channel@1 {
+ crtc = "ipu2-di1";
+ };
+};
+
+&mxcfb1 {
+ status = "okay";
+};
+
+&mxcfb2 {
+ status = "okay";
+};
+
+&mxcfb3 {
+ status = "okay";
+};
+
+&mxcfb4 {
+ status = "okay";
+};
+
&sata {
status = "okay";
};
diff --git a/arch/arm/boot/dts/imx6q-tbs2910.dts b/arch/arm/boot/dts/imx6q-tbs2910.dts
index 06f492e17ca7..43ff8f5b04fe 100644
--- a/arch/arm/boot/dts/imx6q-tbs2910.dts
+++ b/arch/arm/boot/dts/imx6q-tbs2910.dts
@@ -1,6 +1,8 @@
/*
* Copyright 2014 Soeren Moch <smoch@web.de>
*
+ * Copyright 2015 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
* 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
@@ -55,6 +57,10 @@
model = "TBS2910 Matrix ARM mini PC";
compatible = "tbs,imx6q-tbs2910", "fsl,imx6q";
+ aliases {
+ mxcfb0 = &mxcfb1;
+ };
+
chosen {
stdout-path = &uart1;
};
@@ -131,6 +137,17 @@
spdif-controller = <&spdif>;
spdif-out;
};
+
+ mxcfb1: fb@0 {
+ compatible = "fsl,mxc_sdc_fb";
+ disp_dev = "hdmi";
+ interface_pix_fmt = "RGB24";
+ mode_str ="1920x1080M@60";
+ default_bpp = <24>;
+ int_clk = <0>;
+ late_init = <0>;
+ status = "okay";
+ };
};
&audmux {
@@ -145,10 +162,21 @@
status = "okay";
};
-&hdmi {
+&hdmi_cec {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_hdmi>;
- ddc-i2c-bus = <&i2c2>;
+ status = "okay";
+};
+
+&hdmi_core {
+ ipu_id = <0>;
+ disp_id = <0>;
+ status = "okay";
+};
+
+&hdmi_video {
+ fsl,phy_reg_vlev = <0x0294>;
+ fsl,phy_reg_cksymtx = <0x800d>;
status = "okay";
};
@@ -174,6 +202,11 @@
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_i2c2>;
status = "okay";
+
+ hdmi_edid: edid@50 {
+ compatible = "fsl,imx6-hdmi-i2c";
+ reg = <0x50>;
+ };
};
&i2c3 {
diff --git a/arch/arm/boot/dts/imx6q-tx6q-1010-comtft.dts b/arch/arm/boot/dts/imx6q-tx6q-1010-comtft.dts
index 71746edc2ee9..2a129af46c73 100644
--- a/arch/arm/boot/dts/imx6q-tx6q-1010-comtft.dts
+++ b/arch/arm/boot/dts/imx6q-tx6q-1010-comtft.dts
@@ -47,10 +47,6 @@
model = "Ka-Ro electronics TX6Q-1010 Module on CoMpact TFT";
compatible = "karo,imx6q-tx6q", "fsl,imx6q";
- aliases {
- display = &display;
- };
-
backlight: backlight {
compatible = "pwm-backlight";
pwms = <&pwm2 0 500000 0>;
@@ -73,38 +69,14 @@
default-brightness-level = <50>;
};
- display: display@di0 {
- compatible = "fsl,imx-parallel-display";
- interface-pix-fmt = "rgb24";
+ lcd@0 {
+ compatible = "fsl,lcd";
+ ipu_id = <0>;
+ disp_id = <0>;
+ default_ifmt = "RGB565";
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_disp0_1>;
status = "okay";
-
- port {
- display0_in: endpoint {
- remote-endpoint = <&ipu1_di0_disp0>;
- };
- };
-
- display-timings {
- native-mode = <&ET070001DM6>;
-
- ET070001DM6: CoMTFT { /* same as ET0700 but with inverted pixel clock */
- clock-frequency = <33264000>;
- hactive = <800>;
- vactive = <480>;
- hback-porch = <88>;
- hsync-len = <128>;
- hfront-porch = <40>;
- vback-porch = <33>;
- vsync-len = <2>;
- vfront-porch = <10>;
- hsync-active = <0>;
- vsync-active = <0>;
- de-active = <1>;
- pixelclk-active = <1>;
- };
- };
};
};
@@ -116,10 +88,6 @@
xceiver-supply = <&reg_3v3>;
};
-&ipu1_di0_disp0 {
- remote-endpoint = <&display0_in>;
-};
-
&kpp {
status = "disabled";
};
diff --git a/arch/arm/boot/dts/imx6q-tx6q-1010.dts b/arch/arm/boot/dts/imx6q-tx6q-1010.dts
index f9cd21a41a79..2d2df48878be 100644
--- a/arch/arm/boot/dts/imx6q-tx6q-1010.dts
+++ b/arch/arm/boot/dts/imx6q-tx6q-1010.dts
@@ -47,10 +47,6 @@
model = "Ka-Ro electronics TX6Q-1010 Module";
compatible = "karo,imx6q-tx6q", "fsl,imx6q";
- aliases {
- display = &display;
- };
-
backlight: backlight {
compatible = "pwm-backlight";
pwms = <&pwm2 0 500000 PWM_POLARITY_INVERTED>;
@@ -73,135 +69,13 @@
default-brightness-level = <50>;
};
- display: display@di0 {
- compatible = "fsl,imx-parallel-display";
- interface-pix-fmt = "rgb24";
+ lcd@0 {
+ compatible = "fsl,lcd";
+ ipu_id = <0>;
+ disp_id = <0>;
+ default_ifmt = "RGB565";
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_disp0_1>;
status = "okay";
-
- port {
- display0_in: endpoint {
- remote-endpoint = <&ipu1_di0_disp0>;
- };
- };
-
- display-timings {
- VGA {
- clock-frequency = <25200000>;
- hactive = <640>;
- vactive = <480>;
- hback-porch = <48>;
- hsync-len = <96>;
- hfront-porch = <16>;
- vback-porch = <31>;
- vsync-len = <2>;
- vfront-porch = <12>;
- hsync-active = <0>;
- vsync-active = <0>;
- de-active = <1>;
- pixelclk-active = <0>;
- };
-
- ETV570 {
- clock-frequency = <25200000>;
- hactive = <640>;
- vactive = <480>;
- hback-porch = <114>;
- hsync-len = <30>;
- hfront-porch = <16>;
- vback-porch = <32>;
- vsync-len = <3>;
- vfront-porch = <10>;
- hsync-active = <0>;
- vsync-active = <0>;
- de-active = <1>;
- pixelclk-active = <0>;
- };
-
- ET0350 {
- clock-frequency = <6413760>;
- hactive = <320>;
- vactive = <240>;
- hback-porch = <34>;
- hsync-len = <34>;
- hfront-porch = <20>;
- vback-porch = <15>;
- vsync-len = <3>;
- vfront-porch = <4>;
- hsync-active = <0>;
- vsync-active = <0>;
- de-active = <1>;
- pixelclk-active = <0>;
- };
-
- ET0430 {
- clock-frequency = <9009000>;
- hactive = <480>;
- vactive = <272>;
- hback-porch = <2>;
- hsync-len = <41>;
- hfront-porch = <2>;
- vback-porch = <2>;
- vsync-len = <10>;
- vfront-porch = <2>;
- hsync-active = <0>;
- vsync-active = <0>;
- de-active = <1>;
- pixelclk-active = <1>;
- };
-
- ET0500 {
- clock-frequency = <33264000>;
- hactive = <800>;
- vactive = <480>;
- hback-porch = <88>;
- hsync-len = <128>;
- hfront-porch = <40>;
- vback-porch = <33>;
- vsync-len = <2>;
- vfront-porch = <10>;
- hsync-active = <0>;
- vsync-active = <0>;
- de-active = <1>;
- pixelclk-active = <0>;
- };
-
- ET0700 { /* same as ET0500 */
- clock-frequency = <33264000>;
- hactive = <800>;
- vactive = <480>;
- hback-porch = <88>;
- hsync-len = <128>;
- hfront-porch = <40>;
- vback-porch = <33>;
- vsync-len = <2>;
- vfront-porch = <10>;
- hsync-active = <0>;
- vsync-active = <0>;
- de-active = <1>;
- pixelclk-active = <0>;
- };
-
- ETQ570 {
- clock-frequency = <6596040>;
- hactive = <320>;
- vactive = <240>;
- hback-porch = <38>;
- hsync-len = <30>;
- hfront-porch = <30>;
- vback-porch = <16>;
- vsync-len = <3>;
- vfront-porch = <4>;
- hsync-active = <0>;
- vsync-active = <0>;
- de-active = <1>;
- pixelclk-active = <0>;
- };
- };
};
};
-
-&ipu1_di0_disp0 {
- remote-endpoint = <&display0_in>;
-};
diff --git a/arch/arm/boot/dts/imx6q-tx6q-1020-comtft.dts b/arch/arm/boot/dts/imx6q-tx6q-1020-comtft.dts
index 959ff3fb7304..51d8b010bafc 100644
--- a/arch/arm/boot/dts/imx6q-tx6q-1020-comtft.dts
+++ b/arch/arm/boot/dts/imx6q-tx6q-1020-comtft.dts
@@ -47,10 +47,6 @@
model = "Ka-Ro electronics TX6Q-1020 Module on CoMpact TFT";
compatible = "karo,imx6q-tx6q", "fsl,imx6q";
- aliases {
- display = &display;
- };
-
backlight: backlight {
compatible = "pwm-backlight";
pwms = <&pwm2 0 500000 0>;
@@ -73,38 +69,14 @@
default-brightness-level = <50>;
};
- display: display@di0 {
- compatible = "fsl,imx-parallel-display";
- interface-pix-fmt = "rgb24";
+ lcd@0 {
+ compatible = "fsl,lcd";
+ ipu_id = <0>;
+ disp_id = <0>;
+ default_ifmt = "RGB565";
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_disp0_1>;
status = "okay";
-
- port {
- display0_in: endpoint {
- remote-endpoint = <&ipu1_di0_disp0>;
- };
- };
-
- display-timings {
- native-mode = <&ET070001DM6>;
-
- ET070001DM6: CoMTFT { /* same as ET0700 but with inverted pixel clock */
- clock-frequency = <33264000>;
- hactive = <800>;
- vactive = <480>;
- hback-porch = <88>;
- hsync-len = <128>;
- hfront-porch = <40>;
- vback-porch = <33>;
- vsync-len = <2>;
- vfront-porch = <10>;
- hsync-active = <0>;
- vsync-active = <0>;
- de-active = <1>;
- pixelclk-active = <1>;
- };
- };
};
};
@@ -124,10 +96,6 @@
status = "disabled";
};
-&ipu1_di0_disp0 {
- remote-endpoint = <&display0_in>;
-};
-
&kpp {
status = "disabled";
};
diff --git a/arch/arm/boot/dts/imx6q-tx6q-1020.dts b/arch/arm/boot/dts/imx6q-tx6q-1020.dts
index b49133d25d80..a3a87cc41295 100644
--- a/arch/arm/boot/dts/imx6q-tx6q-1020.dts
+++ b/arch/arm/boot/dts/imx6q-tx6q-1020.dts
@@ -47,10 +47,6 @@
model = "Ka-Ro electronics TX6Q-1020 Module";
compatible = "karo,imx6q-tx6q", "fsl,imx6q";
- aliases {
- display = &display;
- };
-
backlight: backlight {
compatible = "pwm-backlight";
pwms = <&pwm2 0 500000 PWM_POLARITY_INVERTED>;
@@ -73,132 +69,14 @@
default-brightness-level = <50>;
};
- display: display@di0 {
- compatible = "fsl,imx-parallel-display";
- interface-pix-fmt = "rgb24";
+ lcd@0 {
+ compatible = "fsl,lcd";
+ ipu_id = <0>;
+ disp_id = <0>;
+ default_ifmt = "RGB565";
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_disp0_1>;
status = "okay";
-
- port {
- display0_in: endpoint {
- remote-endpoint = <&ipu1_di0_disp0>;
- };
- };
-
- display-timings {
- VGA {
- clock-frequency = <25200000>;
- hactive = <640>;
- vactive = <480>;
- hback-porch = <48>;
- hsync-len = <96>;
- hfront-porch = <16>;
- vback-porch = <31>;
- vsync-len = <2>;
- vfront-porch = <12>;
- hsync-active = <0>;
- vsync-active = <0>;
- de-active = <1>;
- pixelclk-active = <0>;
- };
-
- ETV570 {
- clock-frequency = <25200000>;
- hactive = <640>;
- vactive = <480>;
- hback-porch = <114>;
- hsync-len = <30>;
- hfront-porch = <16>;
- vback-porch = <32>;
- vsync-len = <3>;
- vfront-porch = <10>;
- hsync-active = <0>;
- vsync-active = <0>;
- de-active = <1>;
- pixelclk-active = <0>;
- };
-
- ET0350 {
- clock-frequency = <6413760>;
- hactive = <320>;
- vactive = <240>;
- hback-porch = <34>;
- hsync-len = <34>;
- hfront-porch = <20>;
- vback-porch = <15>;
- vsync-len = <3>;
- vfront-porch = <4>;
- hsync-active = <0>;
- vsync-active = <0>;
- de-active = <1>;
- pixelclk-active = <0>;
- };
-
- ET0430 {
- clock-frequency = <9009000>;
- hactive = <480>;
- vactive = <272>;
- hback-porch = <2>;
- hsync-len = <41>;
- hfront-porch = <2>;
- vback-porch = <2>;
- vsync-len = <10>;
- vfront-porch = <2>;
- hsync-active = <0>;
- vsync-active = <0>;
- de-active = <1>;
- pixelclk-active = <1>;
- };
-
- ET0500 {
- clock-frequency = <33264000>;
- hactive = <800>;
- vactive = <480>;
- hback-porch = <88>;
- hsync-len = <128>;
- hfront-porch = <40>;
- vback-porch = <33>;
- vsync-len = <2>;
- vfront-porch = <10>;
- hsync-active = <0>;
- vsync-active = <0>;
- de-active = <1>;
- pixelclk-active = <0>;
- };
-
- ET0700 { /* same as ET0500 */
- clock-frequency = <33264000>;
- hactive = <800>;
- vactive = <480>;
- hback-porch = <88>;
- hsync-len = <128>;
- hfront-porch = <40>;
- vback-porch = <33>;
- vsync-len = <2>;
- vfront-porch = <10>;
- hsync-active = <0>;
- vsync-active = <0>;
- de-active = <1>;
- pixelclk-active = <0>;
- };
-
- ETQ570 {
- clock-frequency = <6596040>;
- hactive = <320>;
- vactive = <240>;
- hback-porch = <38>;
- hsync-len = <30>;
- hfront-porch = <30>;
- vback-porch = <16>;
- vsync-len = <3>;
- vfront-porch = <4>;
- hsync-active = <0>;
- vsync-active = <0>;
- de-active = <1>;
- pixelclk-active = <0>;
- };
- };
};
};
@@ -210,10 +88,6 @@
status = "disabled";
};
-&ipu1_di0_disp0 {
- remote-endpoint = <&display0_in>;
-};
-
&usdhc4 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_usdhc4>;
diff --git a/arch/arm/boot/dts/imx6q.dtsi b/arch/arm/boot/dts/imx6q.dtsi
index 4747ede61acd..4dabb0997aeb 100644
--- a/arch/arm/boot/dts/imx6q.dtsi
+++ b/arch/arm/boot/dts/imx6q.dtsi
@@ -1,6 +1,7 @@
/*
- * Copyright 2013 Freescale Semiconductor, Inc.
+ * Copyright 2013-2015 Freescale Semiconductor, Inc.
+ * Copyright 2018 NXP
*
* 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
@@ -48,9 +49,15 @@
<&clks IMX6QDL_CLK_PLL2_PFD2_396M>,
<&clks IMX6QDL_CLK_STEP>,
<&clks IMX6QDL_CLK_PLL1_SW>,
- <&clks IMX6QDL_CLK_PLL1_SYS>;
+ <&clks IMX6QDL_CLK_PLL1_SYS>,
+ <&clks IMX6QDL_CLK_PLL1>,
+ <&clks IMX6QDL_PLL1_BYPASS>,
+ <&clks IMX6QDL_PLL1_BYPASS_SRC>,
+ <&clks IMX6QDL_CLK_VPU_AXI_PODF>;
clock-names = "arm", "pll2_pfd2_396m", "step",
- "pll1_sw", "pll1_sys";
+ "pll1_sw", "pll1_sys", "pll1",
+ "pll1_bypass", "pll1_bypass_src",
+ "vpu_axi_podf";
arm-supply = <&reg_arm>;
pu-supply = <&reg_pu>;
soc-supply = <&reg_soc>;
@@ -78,13 +85,67 @@
};
};
+ reserved-memory {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ /* global autoconfigured region for contiguous allocations */
+ linux,cma {
+ compatible = "shared-dma-pool";
+ reusable;
+ size = <0x14000000>;
+ linux,cma-default;
+ };
+ };
+
soc {
- ocram: sram@00900000 {
+ busfreq: busfreq {
+ compatible = "fsl,imx_busfreq";
+ clocks = <&clks 171>, <&clks 6>, <&clks 11>, <&clks 104>, <&clks 172>, <&clks 58>,
+ <&clks 18>, <&clks 60>, <&clks 20>, <&clks 3>;
+ clock-names = "pll2_bus", "pll2_pfd2_396m", "pll2_198m", "arm", "pll3_usb_otg", "periph",
+ "periph_pre", "periph_clk2", "periph_clk2_sel", "osc";
+ interrupts = <0 107 0x04>, <0 112 0x4>, <0 113 0x4>, <0 114 0x4>;
+ interrupt-names = "irq_busfreq_0", "irq_busfreq_1", "irq_busfreq_2", "irq_busfreq_3";
+ fsl,max_ddr_freq = <528000000>;
+ };
+
+ gpu: gpu@00130000 {
+ compatible = "fsl,imx6q-gpu";
+ reg = <0x00130000 0x4000>, <0x00134000 0x4000>,
+ <0x02204000 0x4000>, <0x10000000 0x0>,
+ <0x0 0x8000000>;
+ reg-names = "iobase_3d", "iobase_2d",
+ "iobase_vg", "phys_baseaddr",
+ "contiguous_mem";
+ interrupts = <0 9 IRQ_TYPE_LEVEL_HIGH>,
+ <0 10 IRQ_TYPE_LEVEL_HIGH>,
+ <0 11 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "irq_3d", "irq_2d", "irq_vg";
+ clocks = <&clks IMX6QDL_CLK_GPU2D_AXI>, <&clks IMX6QDL_CLK_OPENVG_AXI>,
+ <&clks IMX6QDL_CLK_GPU3D_AXI>, <&clks IMX6QDL_CLK_GPU2D_CORE>,
+ <&clks IMX6QDL_CLK_GPU3D_CORE>, <&clks IMX6QDL_CLK_GPU3D_SHADER>;
+ clock-names = "gpu2d_axi_clk", "openvg_axi_clk",
+ "gpu3d_axi_clk", "gpu2d_clk",
+ "gpu3d_clk", "gpu3d_shader_clk";
+ resets = <&src 0>, <&src 3>, <&src 3>;
+ reset-names = "gpu3d", "gpu2d", "gpuvg";
+ power-domains = <&pd_pu>;
+ };
+
+ ocram: sram@00905000 {
compatible = "mmio-sram";
- reg = <0x00900000 0x40000>;
+ reg = <0x00905000 0x3B000>;
clocks = <&clks IMX6QDL_CLK_OCRAM>;
};
+ ocram_optee: sram@00938000 {
+ compatible = "fsl,optee-lpm-sram";
+ reg = <0x00938000 0x8000>;
+ overw_reg = <&ocram 0x00905000 0x33000>;
+ };
+
aips-bus@02000000 { /* AIPS1 */
spba-bus@02000000 {
ecspi5: ecspi@02018000 {
@@ -107,6 +168,18 @@
};
};
+ aips-bus@02100000 { /* AIPS2 */
+ mipi_dsi: mipi@021e0000 {
+ compatible = "fsl,imx6q-mipi-dsi";
+ reg = <0x021e0000 0x4000>;
+ interrupts = <0 102 0x04>;
+ gpr = <&gpr>;
+ clocks = <&clks IMX6QDL_CLK_HSI_TX>, <&clks IMX6QDL_CLK_VIDEO_27M>;
+ clock-names = "mipi_pllref_clk", "mipi_cfg_clk";
+ status = "disabled";
+ };
+ };
+
sata: sata@02200000 {
compatible = "fsl,imx6q-ahci";
reg = <0x02200000 0x4000>;
@@ -137,9 +210,18 @@
<0 7 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clks IMX6QDL_CLK_IPU2>,
<&clks IMX6QDL_CLK_IPU2_DI0>,
- <&clks IMX6QDL_CLK_IPU2_DI1>;
- clock-names = "bus", "di0", "di1";
+ <&clks IMX6QDL_CLK_IPU2_DI1>,
+ <&clks IMX6QDL_CLK_IPU2_DI0_SEL>,
+ <&clks IMX6QDL_CLK_IPU2_DI1_SEL>,
+ <&clks IMX6QDL_CLK_LDB_DI0>,
+ <&clks IMX6QDL_CLK_LDB_DI1>;
+ clock-names = "bus",
+ "di0", "di1",
+ "di0_sel", "di1_sel",
+ "ldb_di0", "ldb_di1";
+
resets = <&src 4>;
+ bypass_reset = <0>;
ipu2_csi0: port@0 {
reg = <0>;
@@ -348,13 +430,20 @@
};
&ldb {
- clocks = <&clks IMX6QDL_CLK_LDB_DI0_SEL>, <&clks IMX6QDL_CLK_LDB_DI1_SEL>,
+ compatible = "fsl,imx6q-ldb", "fsl,imx53-ldb";
+
+ clocks = <&clks IMX6QDL_CLK_LDB_DI0>, <&clks IMX6QDL_CLK_LDB_DI1>,
<&clks IMX6QDL_CLK_IPU1_DI0_SEL>, <&clks IMX6QDL_CLK_IPU1_DI1_SEL>,
<&clks IMX6QDL_CLK_IPU2_DI0_SEL>, <&clks IMX6QDL_CLK_IPU2_DI1_SEL>,
- <&clks IMX6QDL_CLK_LDB_DI0>, <&clks IMX6QDL_CLK_LDB_DI1>;
- clock-names = "di0_pll", "di1_pll",
- "di0_sel", "di1_sel", "di2_sel", "di3_sel",
- "di0", "di1";
+ <&clks IMX6QDL_CLK_LDB_DI0_DIV_3_5>, <&clks IMX6QDL_CLK_LDB_DI1_DIV_3_5>,
+ <&clks IMX6QDL_CLK_LDB_DI0_DIV_7>, <&clks IMX6QDL_CLK_LDB_DI1_DIV_7>,
+ <&clks IMX6QDL_CLK_LDB_DI0_DIV_SEL>, <&clks IMX6QDL_CLK_LDB_DI1_DIV_SEL>;
+ clock-names = "ldb_di0", "ldb_di1",
+ "di0_sel", "di1_sel",
+ "di2_sel", "di3_sel",
+ "ldb_di0_div_3_5", "ldb_di1_div_3_5",
+ "ldb_di0_div_7", "ldb_di1_div_7",
+ "ldb_di0_div_sel", "ldb_di1_div_sel";
lvds-channel@0 {
port@2 {
diff --git a/arch/arm/boot/dts/imx6qdl-aristainetos.dtsi b/arch/arm/boot/dts/imx6qdl-aristainetos.dtsi
index 7d64075204ae..6763c54fa26e 100644
--- a/arch/arm/boot/dts/imx6qdl-aristainetos.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-aristainetos.dtsi
@@ -3,6 +3,8 @@
*
* Copyright (C) 2014 Heiko Schocher <hs@denx.de>
*
+ * Copyright 2015 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
@@ -12,6 +14,13 @@
#include <dt-bindings/gpio/gpio.h>
/ {
+ aliases {
+ mxcfb0 = &mxcfb1;
+ mxcfb1 = &mxcfb2;
+ mxcfb2 = &mxcfb3;
+ mxcfb3 = &mxcfb4;
+ };
+
regulators {
compatible = "simple-bus";
#address-cells = <1>;
@@ -55,6 +64,53 @@
regulator-max-microvolt = <5000000>;
};
};
+
+ mxcfb1: fb@0 {
+ compatible = "fsl,mxc_sdc_fb";
+ disp_dev = "ldb";
+ interface_pix_fmt = "RGB666";
+ default_bpp = <16>;
+ int_clk = <0>;
+ late_init = <0>;
+ status = "disabled";
+ };
+
+ mxcfb2: fb@1 {
+ compatible = "fsl,mxc_sdc_fb";
+ disp_dev = "hdmi";
+ interface_pix_fmt = "RGB24";
+ mode_str ="1920x1080M@60";
+ default_bpp = <24>;
+ int_clk = <0>;
+ late_init = <0>;
+ status = "disabled";
+ };
+
+ mxcfb3: fb@2 {
+ compatible = "fsl,mxc_sdc_fb";
+ disp_dev = "lcd";
+ interface_pix_fmt = "RGB565";
+ mode_str ="CLAA-WVGA";
+ default_bpp = <16>;
+ int_clk = <0>;
+ late_init = <0>;
+ status = "disabled";
+ };
+
+ mxcfb4: fb@3 {
+ compatible = "fsl,mxc_sdc_fb";
+ disp_dev = "ldb";
+ interface_pix_fmt = "RGB666";
+ default_bpp = <16>;
+ int_clk = <0>;
+ late_init = <0>;
+ status = "disabled";
+ };
+
+ lcd: lcd@0 {
+ compatible = "fsl,lcd";
+ status = "disabled";
+ };
};
&audmux {
diff --git a/arch/arm/boot/dts/imx6qdl-cubox-i.dtsi b/arch/arm/boot/dts/imx6qdl-cubox-i.dtsi
index 14fff4ee6516..f65ff866bd86 100644
--- a/arch/arm/boot/dts/imx6qdl-cubox-i.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-cubox-i.dtsi
@@ -1,6 +1,8 @@
/*
* Copyright (C) 2014 Russell King
*
+ * Copyright 2015 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
* 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
@@ -119,13 +121,6 @@
};
};
-&hdmi {
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_cubox_i_hdmi>;
- ddc-i2c-bus = <&i2c2>;
- status = "okay";
-};
-
&i2c2 {
clock-frequency = <100000>;
pinctrl-names = "default";
diff --git a/arch/arm/boot/dts/imx6qdl-gw51xx.dtsi b/arch/arm/boot/dts/imx6qdl-gw51xx.dtsi
index 885556260bd0..dfc11fd4b540 100644
--- a/arch/arm/boot/dts/imx6qdl-gw51xx.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-gw51xx.dtsi
@@ -1,6 +1,8 @@
/*
* Copyright 2013 Gateworks Corporation
*
+ * Copyright 2015 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
* 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:
@@ -19,6 +21,7 @@
nand = &gpmi;
usb0 = &usbh1;
usb1 = &usbotg;
+ mxcfb0 = &mxcfb1;
};
chosen {
@@ -80,6 +83,17 @@
gpio = <&gpio3 22 GPIO_ACTIVE_HIGH>;
enable-active-high;
};
+
+ mxcfb1: fb@0 {
+ compatible = "fsl,mxc_sdc_fb";
+ disp_dev = "hdmi";
+ interface_pix_fmt = "RGB24";
+ mode_str ="1920x1080M@60";
+ default_bpp = <24>;
+ int_clk = <0>;
+ late_init = <0>;
+ status = "okay";
+ };
};
&fec {
@@ -96,8 +110,15 @@
status = "okay";
};
-&hdmi {
- ddc-i2c-bus = <&i2c3>;
+&hdmi_core {
+ ipu_id = <0>;
+ disp_id = <0>;
+ status = "okay";
+};
+
+&hdmi_video {
+ fsl,phy_reg_vlev = <0x0294>;
+ fsl,phy_reg_cksymtx = <0x800d>;
status = "okay";
};
@@ -248,6 +269,11 @@
};
};
};
+
+ hdmi_edid: edid@50 {
+ compatible = "fsl,imx6-hdmi-i2c";
+ reg = <0x50>;
+ };
};
&ipu1_csi0_from_ipu1_csi0_mux {
diff --git a/arch/arm/boot/dts/imx6qdl-gw52xx.dtsi b/arch/arm/boot/dts/imx6qdl-gw52xx.dtsi
index 115d706228ef..f45e33507253 100644
--- a/arch/arm/boot/dts/imx6qdl-gw52xx.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-gw52xx.dtsi
@@ -1,6 +1,8 @@
/*
* Copyright 2013 Gateworks Corporation
*
+ * Copyright 2015 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
* 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:
@@ -21,6 +23,7 @@
ssi0 = &ssi1;
usb0 = &usbh1;
usb1 = &usbotg;
+ mxcfb0 = &mxcfb1;
};
chosen {
@@ -104,6 +107,17 @@
enable-active-high;
};
+ mxcfb1: fb@0 {
+ compatible = "fsl,mxc_sdc_fb";
+ disp_dev = "hdmi";
+ interface_pix_fmt = "RGB24";
+ mode_str ="1920x1080M@60";
+ default_bpp = <24>;
+ int_clk = <0>;
+ late_init = <0>;
+ status = "okay";
+ };
+
sound {
compatible = "fsl,imx6q-ventana-sgtl5000",
"fsl,imx-audio-sgtl5000";
@@ -159,8 +173,15 @@
status = "okay";
};
-&hdmi {
- ddc-i2c-bus = <&i2c3>;
+&hdmi_core {
+ ipu_id = <0>;
+ disp_id = <0>;
+ status = "okay";
+};
+
+&hdmi_video {
+ fsl,phy_reg_vlev = <0x0294>;
+ fsl,phy_reg_cksymtx = <0x800d>;
status = "okay";
};
@@ -311,6 +332,11 @@
VDDIO-supply = <&reg_3p3v>;
};
+ hdmi_edid: edid@50 {
+ compatible = "fsl,imx6-hdmi-i2c";
+ reg = <0x50>;
+ };
+
touchscreen: egalax_ts@04 {
compatible = "eeti,egalax_ts";
reg = <0x04>;
diff --git a/arch/arm/boot/dts/imx6qdl-gw53xx.dtsi b/arch/arm/boot/dts/imx6qdl-gw53xx.dtsi
index 24be7965056c..6afb0245f0d4 100644
--- a/arch/arm/boot/dts/imx6qdl-gw53xx.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-gw53xx.dtsi
@@ -1,6 +1,8 @@
/*
* Copyright 2013 Gateworks Corporation
*
+ * Copyright 2015 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
* 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:
@@ -21,6 +23,7 @@
ssi0 = &ssi1;
usb0 = &usbh1;
usb1 = &usbotg;
+ mxcfb0 = &mxcfb1;
};
chosen {
@@ -117,6 +120,17 @@
mux-int-port = <1>;
mux-ext-port = <4>;
};
+
+ mxcfb1: fb@0 {
+ compatible = "fsl,mxc_sdc_fb";
+ disp_dev = "hdmi";
+ interface_pix_fmt = "RGB24";
+ mode_str ="1920x1080M@60";
+ default_bpp = <24>;
+ int_clk = <0>;
+ late_init = <0>;
+ status = "okay";
+ };
};
&audmux {
@@ -152,8 +166,15 @@
status = "okay";
};
-&hdmi {
- ddc-i2c-bus = <&i2c3>;
+&hdmi_core {
+ ipu_id = <0>;
+ disp_id = <0>;
+ status = "okay";
+};
+
+&hdmi_video {
+ fsl,phy_reg_vlev = <0x0294>;
+ fsl,phy_reg_cksymtx = <0x800d>;
status = "okay";
};
@@ -302,6 +323,11 @@
VDDIO-supply = <&reg_3p3v>;
};
+ hdmi_edid: edid@50 {
+ compatible = "fsl,imx6-hdmi-i2c";
+ reg = <0x50>;
+ };
+
touchscreen: egalax_ts@04 {
compatible = "eeti,egalax_ts";
reg = <0x04>;
diff --git a/arch/arm/boot/dts/imx6qdl-gw54xx.dtsi b/arch/arm/boot/dts/imx6qdl-gw54xx.dtsi
index 4594b2279169..8d358254fb32 100644
--- a/arch/arm/boot/dts/imx6qdl-gw54xx.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-gw54xx.dtsi
@@ -1,6 +1,8 @@
/*
* Copyright 2013 Gateworks Corporation
*
+ * Copyright 2015 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
* 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:
@@ -21,6 +23,7 @@
ssi0 = &ssi1;
usb0 = &usbh1;
usb1 = &usbotg;
+ mxcfb0 = &mxcfb1;
};
chosen {
@@ -127,6 +130,17 @@
mux-int-port = <1>;
mux-ext-port = <4>;
};
+
+ mxcfb1: fb@0 {
+ compatible = "fsl,mxc_sdc_fb";
+ disp_dev = "hdmi";
+ interface_pix_fmt = "RGB24";
+ mode_str ="1920x1080M@60";
+ default_bpp = <24>;
+ int_clk = <0>;
+ late_init = <0>;
+ status = "okay";
+ };
};
&audmux {
@@ -169,8 +183,15 @@
status = "okay";
};
-&hdmi {
- ddc-i2c-bus = <&i2c3>;
+&hdmi_core {
+ ipu_id = <0>;
+ disp_id = <0>;
+ status = "okay";
+};
+
+&hdmi_video {
+ fsl,phy_reg_vlev = <0x0294>;
+ fsl,phy_reg_cksymtx = <0x800d>;
status = "okay";
};
@@ -339,6 +360,11 @@
VDDIO-supply = <&reg_3p3v>;
};
+ hdmi_edid: edid@50 {
+ compatible = "fsl,imx6-hdmi-i2c";
+ reg = <0x50>;
+ };
+
touchscreen: egalax_ts@04 {
compatible = "eeti,egalax_ts";
reg = <0x04>;
diff --git a/arch/arm/boot/dts/imx6qdl-gw552x.dtsi b/arch/arm/boot/dts/imx6qdl-gw552x.dtsi
index 67613dd7cc92..ef8b51466f4a 100644
--- a/arch/arm/boot/dts/imx6qdl-gw552x.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-gw552x.dtsi
@@ -1,6 +1,8 @@
/*
* Copyright 2014 Gateworks Corporation
*
+ * Copyright 2015 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
* 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:
@@ -20,6 +22,7 @@
nand = &gpmi;
usb0 = &usbh1;
usb1 = &usbotg;
+ mxcfb0 = &mxcfb1;
};
chosen {
@@ -78,6 +81,17 @@
regulator-max-microvolt = <5000000>;
regulator-always-on;
};
+
+ mxcfb1: fb@0 {
+ compatible = "fsl,mxc_sdc_fb";
+ disp_dev = "hdmi";
+ interface_pix_fmt = "RGB24";
+ mode_str ="1920x1080M@60";
+ default_bpp = <24>;
+ int_clk = <0>;
+ late_init = <0>;
+ status = "okay";
+ };
};
&gpmi {
@@ -86,8 +100,15 @@
status = "okay";
};
-&hdmi {
- ddc-i2c-bus = <&i2c3>;
+&hdmi_core {
+ ipu_id = <0>;
+ disp_id = <0>;
+ status = "okay";
+};
+
+&hdmi_video {
+ fsl,phy_reg_vlev = <0x0294>;
+ fsl,phy_reg_cksymtx = <0x800d>;
status = "okay";
};
@@ -221,6 +242,11 @@
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_i2c3>;
status = "okay";
+
+ hdmi_edid: edid@50 {
+ compatible = "fsl,imx6-hdmi-i2c";
+ reg = <0x50>;
+ };
};
&pcie {
diff --git a/arch/arm/boot/dts/imx6qdl-hummingboard.dtsi b/arch/arm/boot/dts/imx6qdl-hummingboard.dtsi
index 988334c889eb..53c18ad37c0c 100644
--- a/arch/arm/boot/dts/imx6qdl-hummingboard.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-hummingboard.dtsi
@@ -1,6 +1,8 @@
/*
* Copyright (C) 2013,2014 Russell King
*
+ * Copyright 2015 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
* 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
@@ -42,6 +44,10 @@
#include "imx6qdl-microsom-ar8035.dtsi"
/ {
+ aliases {
+ mxcfb0 = &mxcfb1;
+ };
+
chosen {
stdout-path = &uart1;
};
@@ -107,6 +113,17 @@
spdif-controller = <&spdif>;
spdif-out;
};
+
+ mxcfb1: fb@0 {
+ compatible = "fsl,mxc_sdc_fb";
+ disp_dev = "hdmi";
+ interface_pix_fmt = "RGB24";
+ mode_str ="1920x1080M@60";
+ default_bpp = <24>;
+ int_clk = <0>;
+ late_init = <0>;
+ status = "okay";
+ };
};
&audmux {
@@ -119,10 +136,15 @@
status = "okay";
};
-&hdmi {
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_hummingboard_hdmi>;
- ddc-i2c-bus = <&i2c2>;
+&hdmi_core {
+ ipu_id = <0>;
+ disp_id = <0>;
+ status = "okay";
+};
+
+&hdmi_video {
+ fsl,phy_reg_vlev = <0x0294>;
+ fsl,phy_reg_cksymtx = <0x800d>;
status = "okay";
};
@@ -154,6 +176,11 @@
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_hummingboard_i2c2>;
status = "okay";
+
+ hdmi_edid: edid@50 {
+ compatible = "fsl,imx6-hdmi-i2c";
+ reg = <0x50>;
+ };
};
&iomuxc {
diff --git a/arch/arm/boot/dts/imx6qdl-nitrogen6x.dtsi b/arch/arm/boot/dts/imx6qdl-nitrogen6x.dtsi
index d309a4d0eb08..a81a8e2848df 100644
--- a/arch/arm/boot/dts/imx6qdl-nitrogen6x.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-nitrogen6x.dtsi
@@ -1,6 +1,6 @@
/*
* Copyright 2013 Boundary Devices, Inc.
- * Copyright 2011 Freescale Semiconductor, Inc.
+ * Copyright 2011-2015 Freescale Semiconductor, Inc.
* Copyright 2011 Linaro Ltd.
*
* This file is dual-licensed: you can use it either under the terms
@@ -44,6 +44,10 @@
#include <dt-bindings/input/input.h>
/ {
+ aliases {
+ mxcfb0 = &mxcfb1;
+ };
+
chosen {
stdout-path = &uart2;
};
@@ -244,6 +248,17 @@
};
};
};
+
+ mxcfb1: fb@0 {
+ compatible = "fsl,mxc_sdc_fb";
+ disp_dev = "hdmi";
+ interface_pix_fmt = "RGB24";
+ mode_str ="1920x1080M@60";
+ default_bpp = <24>;
+ int_clk = <0>;
+ late_init = <0>;
+ status = "okay";
+ };
};
&audmux {
@@ -302,8 +317,15 @@
status = "okay";
};
-&hdmi {
- ddc-i2c-bus = <&i2c2>;
+&hdmi_core {
+ ipu_id = <0>;
+ disp_id = <0>;
+ status = "okay";
+};
+
+&hdmi_video {
+ fsl,phy_reg_vlev = <0x0294>;
+ fsl,phy_reg_cksymtx = <0x800d>;
status = "okay";
};
@@ -332,6 +354,11 @@
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_i2c2>;
status = "okay";
+
+ hdmi_edid: edid@50 {
+ compatible = "fsl,imx6-hdmi-i2c";
+ reg = <0x50>;
+ };
};
&i2c3 {
diff --git a/arch/arm/boot/dts/imx6qdl-phytec-pbab01.dtsi b/arch/arm/boot/dts/imx6qdl-phytec-pbab01.dtsi
index 585b4f6986c1..044d46ec99e2 100644
--- a/arch/arm/boot/dts/imx6qdl-phytec-pbab01.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-phytec-pbab01.dtsi
@@ -1,6 +1,8 @@
/*
* Copyright 2013 Christian Hemp, Phytec Messtechnik GmbH
*
+ * Copyright 2015 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
* 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:
@@ -12,6 +14,10 @@
#include <dt-bindings/sound/fsl-imx-audmux.h>
/ {
+ aliases {
+ mxcfb0 = &mxcfb1;
+ };
+
chosen {
linux,stdout-path = &uart4;
};
@@ -76,6 +82,17 @@
};
};
+ mxcfb1: fb@0 {
+ compatible = "fsl,mxc_sdc_fb";
+ disp_dev = "hdmi";
+ interface_pix_fmt = "RGB24";
+ mode_str ="1920x1080M@60";
+ default_bpp = <24>;
+ int_clk = <0>;
+ late_init = <0>;
+ status = "okay";
+ };
+
};
&audmux {
@@ -109,7 +126,15 @@
status = "okay";
};
-&hdmi {
+&hdmi_core {
+ ipu_id = <0>;
+ disp_id = <0>;
+ status = "okay";
+};
+
+&hdmi_video {
+ fsl,phy_reg_vlev = <0x0294>;
+ fsl,phy_reg_cksymtx = <0x800d>;
status = "okay";
};
diff --git a/arch/arm/boot/dts/imx6qdl-rex.dtsi b/arch/arm/boot/dts/imx6qdl-rex.dtsi
index 5cf90c24c707..e7bceddfb100 100644
--- a/arch/arm/boot/dts/imx6qdl-rex.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-rex.dtsi
@@ -1,6 +1,8 @@
/*
* Copyright 2014 FEDEVEL, Inc.
*
+ * Copyright 2015 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
* Author: Robert Nelson <robertcnelson@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
@@ -13,6 +15,10 @@
#include <dt-bindings/input/input.h>
/ {
+ aliases {
+ mxcfb0 = &mxcfb1;
+ };
+
chosen {
stdout-path = &uart1;
};
@@ -80,6 +86,17 @@
mux-int-port = <1>;
mux-ext-port = <3>;
};
+
+ mxcfb1: fb@0 {
+ compatible = "fsl,mxc_sdc_fb";
+ disp_dev = "hdmi";
+ interface_pix_fmt = "RGB24";
+ mode_str ="1920x1080M@60";
+ default_bpp = <24>;
+ int_clk = <0>;
+ late_init = <0>;
+ status = "okay";
+ };
};
&audmux {
@@ -110,8 +127,15 @@
status = "okay";
};
-&hdmi {
- ddc-i2c-bus = <&i2c2>;
+&hdmi_core {
+ ipu_id = <0>;
+ disp_id = <0>;
+ status = "okay";
+};
+
+&hdmi_video {
+ fsl,phy_reg_vlev = <0x0294>;
+ fsl,phy_reg_cksymtx = <0x800d>;
status = "okay";
};
@@ -136,6 +160,11 @@
pinctrl-0 = <&pinctrl_i2c2>;
status = "okay";
+ hdmi_edid: edid@50 {
+ compatible = "fsl,imx6-hdmi-i2c";
+ reg = <0x50>;
+ };
+
eeprom@57 {
compatible = "at,24c02";
reg = <0x57>;
diff --git a/arch/arm/boot/dts/imx6qdl-sabreauto.dtsi b/arch/arm/boot/dts/imx6qdl-sabreauto.dtsi
index 6a7594e5d183..1937b200f32c 100644
--- a/arch/arm/boot/dts/imx6qdl-sabreauto.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-sabreauto.dtsi
@@ -1,6 +1,7 @@
/*
- * Copyright 2012 Freescale Semiconductor, Inc.
+ * Copyright 2012-2015 Freescale Semiconductor, Inc.
* Copyright 2011 Linaro Ltd.
+ * Copyright 2017 NXP.
*
* The code contained herein is licensed under the GNU General Public
* License. You may obtain a copy of the GNU General Public License
@@ -11,9 +12,62 @@
*/
#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
/ {
- memory {
+ aliases {
+ mxcfb0 = &mxcfb1;
+ mxcfb1 = &mxcfb2;
+ mxcfb2 = &mxcfb3;
+ mxcfb3 = &mxcfb4;
+ };
+
+ chosen {
+ stdout-path = &uart4;
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys1";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpio_keys>;
+
+ home {
+ label = "Home";
+ gpios = <&gpio1 11 GPIO_ACTIVE_LOW>;
+ gpio-key,wakeup;
+ linux,code = <KEY_HOME>;
+ };
+
+ back {
+ label = "Back";
+ gpios = <&gpio1 12 GPIO_ACTIVE_LOW>;
+ gpio-key,wakeup;
+ linux,code = <KEY_BACK>;
+ };
+
+ program {
+ label = "Program";
+ gpios = <&gpio2 12 GPIO_ACTIVE_LOW>;
+ gpio-key,wakeup;
+ linux,code = <KEY_PROGRAM>;
+ };
+
+ volume-up {
+ label = "Volume Up";
+ gpios = <&gpio2 15 GPIO_ACTIVE_LOW>;
+ gpio-key,wakeup;
+ linux,code = <KEY_VOLUMEUP>;
+ };
+
+ volume-down {
+ label = "Volume Down";
+ gpios = <&gpio5 14 GPIO_ACTIVE_LOW>;
+ gpio-key,wakeup;
+ linux,code = <KEY_VOLUMEDOWN>;
+ };
+ };
+
+ memory: memory {
reg = <0x10000000 0x80000000>;
};
@@ -50,6 +104,14 @@
regulator-always-on;
};
+ reg_3p3v: 3p3v {
+ compatible = "regulator-fixed";
+ regulator-name = "3P3V";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
reg_usb_h1_vbus: regulator@1 {
compatible = "regulator-fixed";
reg = <1>;
@@ -69,28 +131,159 @@
gpio = <&max7310_c 1 GPIO_ACTIVE_HIGH>;
enable-active-high;
};
+
+ reg_si4763_vio1: regulator@3 {
+ compatible = "regulator-fixed";
+ reg = <3>;
+ regulator-name = "vio1";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ reg_si4763_vio2: regulator@4 {
+ compatible = "regulator-fixed";
+ reg = <4>;
+ regulator-name = "vio2";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ reg_si4763_vd: regulator@5 {
+ compatible = "regulator-fixed";
+ reg = <5>;
+ regulator-name = "vd";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ reg_si4763_va: regulator@6 {
+ compatible = "regulator-fixed";
+ reg = <6>;
+ regulator-name = "va";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-always-on;
+ };
+
+ reg_sd3_vmmc: regulator@7 {
+ compatible = "regulator-fixed";
+ regulator-name = "P3V3_SDa_SWITCHED";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&gpio7 8 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ off-on-delay = <20000>;
+ /* remove below line to enable this regulator */
+ status = "disabled";
+ };
+
+ reg_can_en: regulator@8 {
+ compatible = "regulator-fixed";
+ reg = <8>;
+ regulator-name = "can-en";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&max7310_b 6 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ reg_can_stby: regulator@9 {
+ compatible = "regulator-fixed";
+ reg = <9>;
+ regulator-name = "can-stby";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&max7310_b 5 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ vin-supply = <&reg_can_en>;
+ };
+ };
+
+ hannstar_cabc {
+ compatible = "hannstar,cabc";
+
+ lvds_share {
+ gpios = <&max7310_a 0 GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ sound-hdmi {
+ compatible = "fsl,imx6q-audio-hdmi",
+ "fsl,imx-audio-hdmi";
+ model = "imx-audio-hdmi";
+ hdmi-controller = <&hdmi_audio>;
+ };
+
+ mxcfb1: fb@0 {
+ compatible = "fsl,mxc_sdc_fb";
+ disp_dev = "ldb";
+ interface_pix_fmt = "RGB666";
+ default_bpp = <16>;
+ int_clk = <0>;
+ late_init = <0>;
+ status = "disabled";
+ };
+
+ mxcfb2: fb@1 {
+ compatible = "fsl,mxc_sdc_fb";
+ disp_dev = "hdmi";
+ interface_pix_fmt = "RGB24";
+ mode_str ="1920x1080M@60";
+ default_bpp = <24>;
+ int_clk = <0>;
+ late_init = <0>;
+ status = "disabled";
+ };
+
+ mxcfb3: fb@2 {
+ compatible = "fsl,mxc_sdc_fb";
+ disp_dev = "lcd";
+ interface_pix_fmt = "RGB565";
+ mode_str ="CLAA-WVGA";
+ default_bpp = <16>;
+ int_clk = <0>;
+ late_init = <0>;
+ status = "disabled";
+ };
+
+ mxcfb4: fb@3 {
+ compatible = "fsl,mxc_sdc_fb";
+ disp_dev = "ldb";
+ interface_pix_fmt = "RGB666";
+ default_bpp = <16>;
+ int_clk = <0>;
+ late_init = <0>;
+ status = "disabled";
+ };
+
+ clocks {
+ codec_osc: anaclk2 {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <24576000>;
+ };
};
sound-cs42888 {
compatible = "fsl,imx6-sabreauto-cs42888",
- "fsl,imx-audio-cs42888";
+ "fsl,imx-audio-cs42888";
model = "imx-cs42888";
- audio-cpu = <&esai>;
- audio-asrc = <&asrc>;
+ esai-controller = <&esai>;
+ asrc-controller = <&asrc>;
audio-codec = <&codec>;
- audio-routing =
- "Line Out Jack", "AOUT1L",
- "Line Out Jack", "AOUT1R",
- "Line Out Jack", "AOUT2L",
- "Line Out Jack", "AOUT2R",
- "Line Out Jack", "AOUT3L",
- "Line Out Jack", "AOUT3R",
- "Line Out Jack", "AOUT4L",
- "Line Out Jack", "AOUT4R",
- "AIN1L", "Line In Jack",
- "AIN1R", "Line In Jack",
- "AIN2L", "Line In Jack",
- "AIN2R", "Line In Jack";
+ };
+
+ sound-fm {
+ compatible = "fsl,imx-audio-si476x",
+ "fsl,imx-tuner-si476x";
+ model = "imx-radio-si4763";
+ ssi-controller = <&ssi2>;
+ fm-controller = <&si476x_codec>;
+ mux-int-port = <2>;
+ mux-ext-port = <5>;
};
sound-spdif {
@@ -124,19 +317,22 @@
#size-cells = <0>;
reg = <1>;
- adv7180: camera@21 {
- compatible = "adi,adv7180";
+ adv7180: adv7180@21 {
+ compatible = "adv,adv7180";
reg = <0x21>;
- powerdown-gpios = <&max7310_b 2 GPIO_ACTIVE_LOW>;
- interrupt-parent = <&gpio1>;
- interrupts = <27 IRQ_TYPE_LEVEL_LOW>;
-
- port {
- adv7180_to_ipu1_csi0_mux: endpoint {
- remote-endpoint = <&ipu1_csi0_mux_from_parallel_sensor>;
- bus-width = <8>;
- };
- };
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ipu1_1>;
+ clocks = <&clks IMX6QDL_CLK_CKO>;
+ clock-names = "csi_mclk";
+ DOVDD-supply = <&reg_3p3v>; /* 3.3v, enabled via 2.8 VGEN6 */
+ AVDD-supply = <&reg_3p3v>; /* 1.8v */
+ DVDD-supply = <&reg_3p3v>; /* 1.8v */
+ PVDD-supply = <&reg_3p3v>; /* 1.8v */
+ pwn-gpios = <&max7310_b 2 0>;
+ csi_id = <0>;
+ mclk = <24000000>;
+ mclk_source = <0>;
+ cvbs = <1>;
};
max7310_a: gpio@30 {
@@ -162,8 +358,46 @@
gpio-controller;
#gpio-cells = <2>;
};
+
+ isl29023@44 {
+ compatible = "fsl,isl29023";
+ reg = <0x44>;
+ rext = <499>;
+ interrupt-parent = <&gpio5>;
+ interrupts = <17 2>;
+ };
+
+ mag3110@0e {
+ compatible = "fsl,mag3110";
+ reg = <0x0e>;
+ position = <2>;
+ interrupt-parent = <&gpio2>;
+ interrupts = <29 1>;
+ };
+
+ mma8451@1c {
+ compatible = "fsl,mma8451";
+ reg = <0x1c>;
+ position = <7>;
+ interrupt-parent = <&gpio6>;
+ interrupts = <31 8>;
+ interrupt-route = <1>;
+ };
};
};
+
+ v4l2_cap_0 {
+ compatible = "fsl,imx6q-v4l2-capture";
+ ipu_id = <0>;
+ csi_id = <0>;
+ mclk_source = <0>;
+ status = "okay";
+ };
+
+ v4l2_out {
+ compatible = "fsl,mxc_v4l2_output";
+ status = "okay";
+ };
};
&ipu1_csi0_from_ipu1_csi0_mux {
@@ -171,7 +405,10 @@
};
&ipu1_csi0_mux_from_parallel_sensor {
+ /* Downstream driver doesn't use endpoints */
+ /*
remote-endpoint = <&adv7180_to_ipu1_csi0_mux>;
+ */
bus-width = <8>;
};
@@ -180,6 +417,12 @@
pinctrl-0 = <&pinctrl_ipu1_csi0>;
};
+&audmux {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_audmux>;
+ status = "okay";
+};
+
&clks {
assigned-clocks = <&clks IMX6QDL_PLL4_BYPASS_SRC>,
<&clks IMX6QDL_PLL4_BYPASS>,
@@ -188,11 +431,23 @@
<&clks IMX6QDL_CLK_PLL4_POST_DIV>;
assigned-clock-parents = <&clks IMX6QDL_CLK_LVDS2_IN>,
<&clks IMX6QDL_PLL4_BYPASS_SRC>,
- <&clks IMX6QDL_CLK_PLL3_USB_OTG>,
- <&clks IMX6QDL_CLK_PLL3_USB_OTG>;
+ <&clks IMX6QDL_CLK_PLL2_PFD0_352M>,
+ <&clks IMX6QDL_CLK_PLL2_PFD0_352M>;
assigned-clock-rates = <0>, <0>, <0>, <0>, <24576000>;
};
+&dcic1 {
+ dcic_id = <0>;
+ dcic_mux = "dcic-hdmi";
+ status = "okay";
+};
+
+&dcic2 {
+ dcic_id = <1>;
+ dcic_mux = "dcic-lvds0";
+ status = "okay";
+};
+
&ecspi1 {
cs-gpios = <&gpio3 19 0>;
pinctrl-names = "default";
@@ -222,19 +477,52 @@
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_enet>;
phy-mode = "rgmii";
- interrupts-extended = <&gpio1 6 IRQ_TYPE_LEVEL_HIGH>,
- <&intc 0 119 IRQ_TYPE_LEVEL_HIGH>;
+ fsl,magic-packet;
fsl,err006687-workaround-present;
status = "okay";
};
+&can1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_flexcan1>;
+ pinctrl-assert-gpios = <&max7310_b 3 GPIO_ACTIVE_HIGH>; /* TX */
+ xceiver-supply = <&reg_can_stby>;
+ status = "disabled"; /* pin conflict with fec */
+};
+
+&can2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_flexcan2>;
+ xceiver-supply = <&reg_can_stby>;
+ status = "okay";
+};
+
&gpmi {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_gpmi_nand>;
+ status = "disabled"; /* pin conflict with uart3 */
+ nand-on-flash-bbt;
+};
+
+&hdmi_audio {
+ status = "okay";
+};
+
+&hdmi_cec {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_hdmi_cec>;
status = "okay";
};
-&hdmi {
+&hdmi_core {
+ ipu_id = <0>;
+ disp_id = <1>;
+ status = "okay";
+};
+
+&hdmi_video {
+ fsl,phy_reg_vlev = <0x0294>;
+ fsl,phy_reg_cksymtx = <0x800d>;
status = "okay";
};
@@ -244,6 +532,16 @@
pinctrl-0 = <&pinctrl_i2c2>;
status = "okay";
+ egalax_ts@04 {
+ compatible = "eeti,egalax_ts";
+ reg = <0x04>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_egalax_int>;
+ interrupt-parent = <&gpio2>;
+ interrupts = <28 2>;
+ wakeup-gpios = <&gpio2 28 GPIO_ACTIVE_HIGH>;
+ };
+
pmic: pfuze100@08 {
compatible = "fsl,pfuze100";
reg = <0x08>;
@@ -289,6 +587,7 @@
sw4_reg: sw4 {
regulator-min-microvolt = <800000>;
regulator-max-microvolt = <3300000>;
+ regulator-always-on;
};
swbst_reg: swbst {
@@ -343,6 +642,11 @@
};
};
+ hdmi_edid: edid@50 {
+ compatible = "fsl,imx6-hdmi-i2c";
+ reg = <0x50>;
+ };
+
codec: cs42888@48 {
compatible = "cirrus,cs42888";
reg = <0x48>;
@@ -354,6 +658,19 @@
VLC-supply = <&reg_audio>;
};
+ si4763: si4763@63 {
+ compatible = "si4761";
+ reg = <0x63>;
+ va-supply = <&reg_si4763_va>;
+ vd-supply = <&reg_si4763_vd>;
+ vio1-supply = <&reg_si4763_vio1>;
+ vio2-supply = <&reg_si4763_vio2>;
+ revision-a10; /* set to default A10 compatible command set */
+
+ si476x_codec: si476x-codec {
+ compatible = "si476x-codec";
+ };
+ };
};
&i2c3 {
@@ -367,11 +684,25 @@
pinctrl-0 = <&pinctrl_hog>;
imx6qdl-sabreauto {
+ pinctrl_audmux: audmux {
+ fsl,pins = <
+ MX6QDL_PAD_DISP0_DAT16__AUD5_TXC 0x130b0
+ MX6QDL_PAD_DISP0_DAT18__AUD5_TXFS 0x130b0
+ MX6QDL_PAD_DISP0_DAT19__AUD5_RXD 0x130b0
+ >;
+ };
+
pinctrl_hog: hoggrp {
fsl,pins = <
- MX6QDL_PAD_NANDF_CS2__GPIO6_IO15 0x80000000
+ MX6QDL_PAD_NANDF_CS2__GPIO6_IO15 0x1f059
MX6QDL_PAD_SD2_DAT2__GPIO1_IO13 0x80000000
MX6QDL_PAD_GPIO_18__SD3_VSELECT 0x17059
+ MX6QDL_PAD_EIM_BCLK__GPIO6_IO31 0x80000000
+ MX6QDL_PAD_EIM_EB1__GPIO2_IO29 0x80000000
+ MX6QDL_PAD_DISP0_DAT23__GPIO5_IO17 0x80000000
+ MX6QDL_PAD_SD3_RST__GPIO7_IO08 0x80000000
+ MX6QDL_PAD_CSI0_DATA_EN__GPIO5_IO20 0x17059
+ MX6QDL_PAD_GPIO_1__GPIO1_IO01 0x17059
>;
};
@@ -389,6 +720,12 @@
>;
};
+ pinctrl_egalax_int: egalax_intgrp {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_EB0__GPIO2_IO28 0x80000000
+ >;
+ };
+
pinctrl_enet: enetgrp {
fsl,pins = <
MX6QDL_PAD_KEY_COL1__ENET_MDIO 0x1b0b0
@@ -406,6 +743,12 @@
MX6QDL_PAD_RGMII_RD2__RGMII_RD2 0x1b030
MX6QDL_PAD_RGMII_RD3__RGMII_RD3 0x1b030
MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x1b030
+ MX6QDL_PAD_GPIO_16__ENET_REF_CLK 0x4001b0a8
+ >;
+ };
+
+ pinctrl_enet_irq: enetirqgrp {
+ fsl,pins = <
MX6QDL_PAD_GPIO_6__ENET_IRQ 0x000b1
>;
};
@@ -425,6 +768,30 @@
>;
};
+ pinctrl_flexcan1: flexcan1grp {
+ fsl,pins = <
+ MX6QDL_PAD_KEY_ROW2__FLEXCAN1_RX 0x17059
+ MX6QDL_PAD_KEY_COL2__FLEXCAN1_TX 0x17059
+ >;
+ };
+
+ pinctrl_flexcan2: flexcan2grp {
+ fsl,pins = <
+ MX6QDL_PAD_KEY_COL4__FLEXCAN2_TX 0x17059
+ MX6QDL_PAD_KEY_ROW4__FLEXCAN2_RX 0x17059
+ >;
+ };
+
+ pinctrl_gpio_keys: gpio_keysgrp {
+ fsl,pins = <
+ MX6QDL_PAD_SD2_CMD__GPIO1_IO11 0x1b0b0
+ MX6QDL_PAD_SD2_DAT3__GPIO1_IO12 0x1b0b0
+ MX6QDL_PAD_SD4_DAT4__GPIO2_IO12 0x1b0b0
+ MX6QDL_PAD_SD4_DAT7__GPIO2_IO15 0x1b0b0
+ MX6QDL_PAD_DISP0_DAT20__GPIO5_IO14 0x1b0b0
+ >;
+ };
+
pinctrl_gpio_leds: gpioledsgrp {
fsl,pins = <
MX6QDL_PAD_DISP0_DAT21__GPIO5_IO15 0x80000000
@@ -460,6 +827,30 @@
>;
};
+ pinctrl_ipu1_1: ipu1grp-1 { /* parallel port 16-bit */
+ fsl,pins = <
+ MX6QDL_PAD_CSI0_DAT4__IPU1_CSI0_DATA04 0x80000000
+ MX6QDL_PAD_CSI0_DAT5__IPU1_CSI0_DATA05 0x80000000
+ MX6QDL_PAD_CSI0_DAT6__IPU1_CSI0_DATA06 0x80000000
+ MX6QDL_PAD_CSI0_DAT7__IPU1_CSI0_DATA07 0x80000000
+ MX6QDL_PAD_CSI0_DAT8__IPU1_CSI0_DATA08 0x80000000
+ MX6QDL_PAD_CSI0_DAT9__IPU1_CSI0_DATA09 0x80000000
+ MX6QDL_PAD_CSI0_DAT10__IPU1_CSI0_DATA10 0x80000000
+ MX6QDL_PAD_CSI0_DAT11__IPU1_CSI0_DATA11 0x80000000
+ MX6QDL_PAD_CSI0_DAT12__IPU1_CSI0_DATA12 0x80000000
+ MX6QDL_PAD_CSI0_DAT13__IPU1_CSI0_DATA13 0x80000000
+ MX6QDL_PAD_CSI0_DAT14__IPU1_CSI0_DATA14 0x80000000
+ MX6QDL_PAD_CSI0_DAT15__IPU1_CSI0_DATA15 0x80000000
+ MX6QDL_PAD_CSI0_DAT16__IPU1_CSI0_DATA16 0x80000000
+ MX6QDL_PAD_CSI0_DAT17__IPU1_CSI0_DATA17 0x80000000
+ MX6QDL_PAD_CSI0_DAT18__IPU1_CSI0_DATA18 0x80000000
+ MX6QDL_PAD_CSI0_DAT19__IPU1_CSI0_DATA19 0x80000000
+ MX6QDL_PAD_CSI0_PIXCLK__IPU1_CSI0_PIXCLK 0x80000000
+ MX6QDL_PAD_CSI0_MCLK__IPU1_CSI0_HSYNC 0x80000000
+ MX6QDL_PAD_CSI0_VSYNC__IPU1_CSI0_VSYNC 0x80000000
+ >;
+ };
+
pinctrl_i2c3: i2c3grp {
fsl,pins = <
MX6QDL_PAD_GPIO_3__I2C3_SCL 0x4001b8b1
@@ -495,6 +886,14 @@
>;
};
+ pinctrl_mlb: mlb {
+ fsl,pins = <
+ MX6QDL_PAD_ENET_TXD1__MLB_CLK 0x80000000
+ MX6QDL_PAD_GPIO_6__MLB_SIG 0x80000000
+ MX6QDL_PAD_GPIO_2__MLB_DATA 0x80000000
+ >;
+ };
+
pinctrl_pwm3: pwm1grp {
fsl,pins = <
MX6QDL_PAD_SD4_DAT1__PWM3_OUT 0x1b0b1
@@ -519,6 +918,24 @@
>;
};
+ pinctrl_uart3_1: uart3grp-1 {
+ fsl,pins = <
+ MX6QDL_PAD_SD4_CLK__UART3_RX_DATA 0x1b0b1
+ MX6QDL_PAD_SD4_CMD__UART3_TX_DATA 0x1b0b1
+ MX6QDL_PAD_EIM_D30__UART3_CTS_B 0x1b0b1
+ MX6QDL_PAD_EIM_EB3__UART3_RTS_B 0x1b0b1
+ >;
+ };
+
+ pinctrl_uart3dte_1: uart3dtegrp-1 {
+ fsl,pins = <
+ MX6QDL_PAD_SD4_CLK__UART3_TX_DATA 0x1b0b1
+ MX6QDL_PAD_SD4_CMD__UART3_RX_DATA 0x1b0b1
+ MX6QDL_PAD_EIM_D30__UART3_RTS_B 0x1b0b1
+ MX6QDL_PAD_EIM_EB3__UART3_CTS_B 0x1b0b1
+ >;
+ };
+
pinctrl_uart4: uart4grp {
fsl,pins = <
MX6QDL_PAD_KEY_COL0__UART4_TX_DATA 0x1b0b1
@@ -532,6 +949,17 @@
>;
};
+ pinctrl_usdhc1: usdhc1grp {
+ fsl,pins = <
+ MX6QDL_PAD_SD1_CMD__SD1_CMD 0x17071
+ MX6QDL_PAD_SD1_CLK__SD1_CLK 0x10071
+ MX6QDL_PAD_SD1_DAT0__SD1_DATA0 0x17071
+ MX6QDL_PAD_SD1_DAT1__SD1_DATA1 0x17071
+ MX6QDL_PAD_SD1_DAT2__SD1_DATA2 0x17071
+ MX6QDL_PAD_SD1_DAT3__SD1_DATA3 0x17071
+ >;
+ };
+
pinctrl_usdhc3: usdhc3grp {
fsl,pins = <
MX6QDL_PAD_SD3_CMD__SD3_CMD 0x17059
@@ -630,6 +1058,12 @@
MX6QDL_PAD_EIM_DA0__EIM_AD00 0xb0b1
>;
};
+
+ pinctrl_hdmi_cec: hdmicecgrp {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_A25__HDMI_TX_CEC_LINE 0x1f8b0
+ >;
+ };
};
};
@@ -639,6 +1073,7 @@
lvds-channel@0 {
fsl,data-mapping = "spwg";
fsl,data-width = <18>;
+ primary;
status = "okay";
display-timings {
@@ -656,6 +1091,33 @@
};
};
};
+
+ lvds-channel@1 {
+ fsl,data-mapping = "spwg";
+ fsl,data-width = <18>;
+ status = "okay";
+
+ display-timings {
+ native-mode = <&timing1>;
+ timing1: hsd100pxn1 {
+ clock-frequency = <65000000>;
+ hactive = <1024>;
+ vactive = <768>;
+ hback-porch = <220>;
+ hfront-porch = <40>;
+ vback-porch = <21>;
+ vfront-porch = <7>;
+ hsync-len = <60>;
+ vsync-len = <10>;
+ };
+ };
+ };
+};
+
+&mlb {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_mlb>;
+ status = "okay";
};
&pwm3 {
@@ -664,12 +1126,44 @@
status = "okay";
};
+&pcie {
+ status = "okay";
+};
+
&spdif {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_spdif>;
+ assigned-clocks = <&clks IMX6QDL_CLK_SPDIF_SEL>,
+ <&clks IMX6QDL_CLK_SPDIF_PODF>;
+ assigned-clock-parents = <&clks IMX6QDL_CLK_PLL3_PFD3_454M>;
+ assigned-clock-rates = <0>, <227368421>;
status = "okay";
};
+&snvs_poweroff {
+ status = "okay";
+};
+
+&ssi2 {
+ assigned-clocks = <&clks IMX6QDL_CLK_SSI2_SEL>;
+ assigned-clock-parents = <&clks IMX6QDL_CLK_PLL4_AUDIO_DIV>;
+ assigned-clock-rates = <0>;
+ fsl,mode = "i2s-master";
+ status = "okay";
+};
+
+&uart3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart3_1>;
+ pinctrl-assert-gpios = <&max7310_b 4 GPIO_ACTIVE_HIGH>, /* CTS */
+ <&max7310_c 3 GPIO_ACTIVE_HIGH>; /* RXD and TXD */
+ fsl,uart-has-rtscts;
+ status = "okay";
+ /* for DTE mode, add below change */
+ /* fsl,dte-mode; */
+ /* pinctrl-0 = <&pinctrl_uart3dte_1>; */
+};
+
&uart4 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_uart4>;
@@ -685,6 +1179,19 @@
vbus-supply = <&reg_usb_otg_vbus>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_usbotg>;
+ srp-disable;
+ hnp-disable;
+ adp-disable;
+ status = "okay";
+};
+
+&usdhc1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usdhc1>;
+ cd-gpios = <&gpio1 1 GPIO_ACTIVE_LOW>;
+ no-1-8-v;
+ keep-power-in-suspend;
+ enable-sdio-wakeup;
status = "okay";
};
@@ -695,6 +1202,20 @@
pinctrl-2 = <&pinctrl_usdhc3_200mhz>;
cd-gpios = <&gpio6 15 GPIO_ACTIVE_LOW>;
wp-gpios = <&gpio1 13 GPIO_ACTIVE_HIGH>;
+ /*
+ * Due to board issue, we can not use external regulator for card slot
+ * by default since the card power is shared with card detect pullup.
+ * Disabling the vmmc regulator will cause unexpected card detect
+ * interrupts.
+ * HW rework is needed to fix this isssue. Remove R695 first, then you
+ * can open below line to enable the using of external regulator.
+ * Then you will be able to power off the card during suspend. This is
+ * especially needed for a SD3.0 card re-enumeration working on UHS mode
+ * Note: reg_sd3_vmmc is also need to be enabled
+ */
+ /* vmmc-supply = <&reg_sd3_vmmc>; */
+ keep-power-in-suspend;
+ enable-sdio-wakeup;
status = "okay";
};
diff --git a/arch/arm/boot/dts/imx6qdl-sabrelite.dtsi b/arch/arm/boot/dts/imx6qdl-sabrelite.dtsi
index 756c5054f047..cf1c559c29e9 100644
--- a/arch/arm/boot/dts/imx6qdl-sabrelite.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-sabrelite.dtsi
@@ -1,5 +1,5 @@
/*
- * Copyright 2011 Freescale Semiconductor, Inc.
+ * Copyright 2011-2015 Freescale Semiconductor, Inc.
* Copyright 2011 Linaro Ltd.
*
* This file is dual-licensed: you can use it either under the terms
@@ -339,11 +339,6 @@
status = "okay";
};
-&hdmi {
- ddc-i2c-bus = <&i2c2>;
- status = "okay";
-};
-
&i2c1 {
clock-frequency = <100000>;
pinctrl-names = "default";
@@ -732,6 +727,9 @@
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_usbotg>;
disable-over-current;
+ srp-disable;
+ hnp-disable;
+ adp-disable;
status = "okay";
};
diff --git a/arch/arm/boot/dts/imx6qdl-sabresd-btwifi.dtsi b/arch/arm/boot/dts/imx6qdl-sabresd-btwifi.dtsi
new file mode 100644
index 000000000000..7aecd3c6199d
--- /dev/null
+++ b/arch/arm/boot/dts/imx6qdl-sabresd-btwifi.dtsi
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2015 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.
+ */
+
+/*
+ * NOTE: This DTS file is written for plugging in Murata Wi-Fi/BT EVK into SD2
+ * slot using Murata i.MX InterConnect Ver 2.0 Adapter & connecting Bluetooth
+ * UART & control signals via ribbon cable.
+ * This configuration supports both WLAN and Bluetooth.
+ * WL_REG_ON/BT_REG_ON/WL_HOST_WAKE are connected via ribbon cable (J13 connector
+ * on board).
+ * ==> Hardware modification is required. Refer to schematic.
+ */
+
+/ {
+ leds {
+ compatible = "gpio-leds";
+ status = "disabled";
+ };
+
+ modem_reset: modem-reset {
+ compatible = "gpio-reset";
+ reset-gpios = <&gpio1 2 GPIO_ACTIVE_LOW>;
+ reset-delay-us = <1000>;
+ #reset-cells = <0>;
+ };
+
+ usdhc1_pwrseq: usdhc1_pwrseq {
+ compatible = "mmc-pwrseq-simple";
+ reset-gpios = <&gpio4 7 GPIO_ACTIVE_LOW>;
+ };
+};
+
+&ecspi1 {
+ status = "disabled";
+};
+
+&iomuxc {
+ imx6qdl-sabresd-murata-v2 {
+ pinctrl_btreg: btreggrp {
+ fsl,pins = <
+ MX6QDL_PAD_GPIO_2__GPIO1_IO02 0x1b0b0
+ >;
+ };
+
+ /* add MUXing entry for SD2 4-bit interface and configure control pins */
+ pinctrl_wifi: wifigrp {
+ fsl,pins = <
+ MX6QDL_PAD_SD2_CMD__SD2_CMD 0x17059
+ MX6QDL_PAD_SD2_CLK__SD2_CLK 0x10059
+ MX6QDL_PAD_SD2_DAT0__SD2_DATA0 0x17059
+ MX6QDL_PAD_SD2_DAT1__SD2_DATA1 0x17059
+ MX6QDL_PAD_SD2_DAT2__SD2_DATA2 0x17059
+ MX6QDL_PAD_SD2_DAT3__SD2_DATA3 0x17059
+ MX6QDL_PAD_KEY_ROW0__GPIO4_IO07 0x13069 /* WL_REG_ON */
+ MX6QDL_PAD_KEY_COL0__GPIO4_IO06 0x13069 /* WL_HOST_WAKE */
+ >;
+ };
+ };
+};
+
+&pinctrl_gpio_leds {
+ fsl,pins = <
+ >;
+};
+
+&uart5 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart5_1
+ &pinctrl_btreg>;
+ fsl,uart-has-rtscts;
+ resets = <&modem_reset>;
+ status = "okay";
+ /* for DTE mode, add below change */
+ /* fsl,dte-mode; */
+ /* pinctrl-0 = <&pinctrl_uart5dte_1>; */
+};
+
+&usdhc2 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_wifi>;
+ bus-width = <4>;
+ no-1-8-v;
+ non-removable;
+ mmc-pwrseq = <&usdhc1_pwrseq>;
+ pm-ignore-notify;
+ cap-power-off-card;
+
+ brcmf: bcrmf@1 {
+ reg = <1>;
+ compatible = "brcm,bcm4329-fmac";
+ };
+};
diff --git a/arch/arm/boot/dts/imx6qdl-sabresd.dtsi b/arch/arm/boot/dts/imx6qdl-sabresd.dtsi
index b72b6fa47580..a9ba5318e3ea 100644
--- a/arch/arm/boot/dts/imx6qdl-sabresd.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-sabresd.dtsi
@@ -1,6 +1,7 @@
/*
- * Copyright 2012 Freescale Semiconductor, Inc.
+ * Copyright 2012-2016 Freescale Semiconductor, Inc.
* Copyright 2011 Linaro Ltd.
+ * Copyright 2017 NXP.
*
* The code contained herein is licensed under the GNU General Public
* License. You may obtain a copy of the GNU General Public License
@@ -15,11 +16,41 @@
#include <dt-bindings/input/input.h>
/ {
+ aliases {
+ mxcfb0 = &mxcfb1;
+ mxcfb1 = &mxcfb2;
+ mxcfb2 = &mxcfb3;
+ mxcfb3 = &mxcfb4;
+ };
+
+ battery: max8903@0 {
+ compatible = "fsl,max8903-charger";
+ pinctrl-names = "default";
+ dok_input = <&gpio2 24 1>;
+ uok_input = <&gpio1 27 1>;
+ chg_input = <&gpio3 23 1>;
+ flt_input = <&gpio5 2 1>;
+ fsl,dcm_always_high;
+ fsl,dc_valid;
+ fsl,usb_valid;
+ status = "okay";
+ };
+
+ hannstar_cabc {
+ compatible = "hannstar,cabc";
+ lvds0 {
+ gpios = <&gpio6 15 GPIO_ACTIVE_HIGH>;
+ };
+ lvds1 {
+ gpios = <&gpio6 16 GPIO_ACTIVE_HIGH>;
+ };
+ };
+
chosen {
stdout-path = &uart1;
};
- memory {
+ memory: memory {
reg = <0x10000000 0x40000000>;
};
@@ -70,6 +101,34 @@
regulator-always-on;
enable-active-high;
};
+
+ reg_sensor: regulator@4 {
+ compatible = "regulator-fixed";
+ reg = <4>;
+ regulator-name = "sensor-supply";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&gpio2 31 0>;
+ startup-delay-us = <500>;
+ enable-active-high;
+ };
+
+ reg_hdmi: regulator@5 {
+ compatible = "regulator-fixed";
+ reg = <5>;
+ regulator-name = "hdmi-5v-supply";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ enable-active-high;
+ hdmi-5v-supply = <&swbst_reg>;
+ };
+
+ reg_mipi_dsi_pwr_on: mipi_dsi_pwr_on {
+ compatible = "regulator-fixed";
+ regulator-name = "mipi_dsi_pwr_on";
+ gpio = <&gpio6 14 0>;
+ enable-active-high;
+ };
};
gpio-keys {
@@ -103,20 +162,89 @@
compatible = "fsl,imx6q-sabresd-wm8962",
"fsl,imx-audio-wm8962";
model = "wm8962-audio";
- ssi-controller = <&ssi2>;
+ cpu-dai = <&ssi2>;
audio-codec = <&codec>;
+ asrc-controller = <&asrc>;
audio-routing =
"Headphone Jack", "HPOUTL",
"Headphone Jack", "HPOUTR",
"Ext Spk", "SPKOUTL",
"Ext Spk", "SPKOUTR",
"AMIC", "MICBIAS",
- "IN3R", "AMIC";
+ "IN3R", "AMIC",
+ "DMIC", "MICBIAS",
+ "DMICDAT", "DMIC",
+ "CPU-Playback", "ASRC-Playback",
+ "Playback", "CPU-Playback",
+ "ASRC-Capture", "CPU-Capture",
+ "CPU-Capture", "Capture";
mux-int-port = <2>;
mux-ext-port = <3>;
+ codec-master;
+ hp-det-gpios = <&gpio7 8 1>;
+ mic-det-gpios = <&gpio1 9 1>;
+ };
+
+ sound-hdmi {
+ compatible = "fsl,imx6q-audio-hdmi",
+ "fsl,imx-audio-hdmi";
+ model = "imx-audio-hdmi";
+ hdmi-controller = <&hdmi_audio>;
+ };
+
+ mxcfb1: fb@0 {
+ compatible = "fsl,mxc_sdc_fb";
+ disp_dev = "ldb";
+ interface_pix_fmt = "RGB666";
+ default_bpp = <16>;
+ int_clk = <0>;
+ late_init = <0>;
+ status = "disabled";
+ };
+
+ mxcfb2: fb@1 {
+ compatible = "fsl,mxc_sdc_fb";
+ disp_dev = "hdmi";
+ interface_pix_fmt = "RGB24";
+ mode_str ="1920x1080M@60";
+ default_bpp = <24>;
+ int_clk = <0>;
+ late_init = <0>;
+ status = "disabled";
+ };
+
+ mxcfb3: fb@2 {
+ compatible = "fsl,mxc_sdc_fb";
+ disp_dev = "lcd";
+ interface_pix_fmt = "RGB565";
+ mode_str ="CLAA-WVGA";
+ default_bpp = <16>;
+ int_clk = <0>;
+ late_init = <0>;
+ status = "disabled";
+ };
+
+ mxcfb4: fb@3 {
+ compatible = "fsl,mxc_sdc_fb";
+ disp_dev = "ldb";
+ interface_pix_fmt = "RGB666";
+ default_bpp = <16>;
+ int_clk = <0>;
+ late_init = <0>;
+ status = "disabled";
+ };
+
+ lcd@0 {
+ compatible = "fsl,lcd";
+ ipu_id = <0>;
+ disp_id = <0>;
+ default_ifmt = "RGB565";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ipu1>;
+ status = "okay";
};
- backlight_lvds: backlight-lvds {
+ backlight {
compatible = "pwm-backlight";
pwms = <&pwm1 0 5000000>;
brightness-levels = <0 4 8 16 32 64 128 255>;
@@ -129,21 +257,32 @@
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_gpio_leds>;
- red {
+ charger-led {
gpios = <&gpio1 2 0>;
- default-state = "on";
+ linux,default-trigger = "max8903-charger-charging";
+ retain-state-suspended;
};
};
- panel {
- compatible = "hannstar,hsd100pxn1";
- backlight = <&backlight_lvds>;
+ v4l2_cap_0 {
+ compatible = "fsl,imx6q-v4l2-capture";
+ ipu_id = <0>;
+ csi_id = <0>;
+ mclk_source = <0>;
+ status = "okay";
+ };
- port {
- panel_in: endpoint {
- remote-endpoint = <&lvds0_out>;
- };
- };
+ v4l2_cap_1 {
+ compatible = "fsl,imx6q-v4l2-capture";
+ ipu_id = <0>;
+ csi_id = <1>;
+ mclk_source = <0>;
+ status = "okay";
+ };
+
+ v4l2_out {
+ compatible = "fsl,mxc_v4l2_output";
+ status = "okay";
};
};
@@ -155,7 +294,10 @@
};
&ipu1_csi0_mux_from_parallel_sensor {
+ /* Downstream driver doesn't use endpoints */
+ /*
remote-endpoint = <&ov5642_to_ipu1_csi0_mux>;
+ */
};
&ipu1_csi0 {
@@ -165,16 +307,6 @@
&mipi_csi {
status = "okay";
-
- port@0 {
- reg = <0>;
-
- mipi_csi2_in: endpoint {
- remote-endpoint = <&ov5640_to_mipi_csi2>;
- clock-lanes = <0>;
- data-lanes = <1 2>;
- };
- };
};
&audmux {
@@ -186,8 +318,8 @@
&clks {
assigned-clocks = <&clks IMX6QDL_CLK_LDB_DI0_SEL>,
<&clks IMX6QDL_CLK_LDB_DI1_SEL>;
- assigned-clock-parents = <&clks IMX6QDL_CLK_PLL3_USB_OTG>,
- <&clks IMX6QDL_CLK_PLL3_USB_OTG>;
+ assigned-clock-parents = <&clks IMX6QDL_CLK_PLL2_PFD0_352M>,
+ <&clks IMX6QDL_CLK_PLL2_PFD0_352M>;
};
&ecspi1 {
@@ -210,11 +342,46 @@
pinctrl-0 = <&pinctrl_enet>;
phy-mode = "rgmii";
phy-reset-gpios = <&gpio1 25 GPIO_ACTIVE_LOW>;
+ fsl,magic-packet;
+ status = "okay";
+};
+
+&gpc {
+ fsl,ldo-bypass = <1>;
+};
+
+&dcic1 {
+ dcic_id = <0>;
+ dcic_mux = "dcic-hdmi";
status = "okay";
};
-&hdmi {
- ddc-i2c-bus = <&i2c2>;
+&dcic2 {
+ dcic_id = <1>;
+ dcic_mux = "dcic-lvds1";
+ status = "okay";
+};
+
+&hdmi_audio {
+ status = "okay";
+};
+
+&hdmi_cec {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_hdmi_cec>;
+ status = "okay";
+};
+
+&hdmi_core {
+ ipu_id = <0>;
+ disp_id = <0>;
+ status = "okay";
+};
+
+&hdmi_video {
+ fsl,phy_reg_vlev = <0x0294>;
+ fsl,phy_reg_cksymtx = <0x800d>;
+ HDMI-supply = <&reg_hdmi>;
status = "okay";
};
@@ -244,64 +411,64 @@
0x8014 /* 4:FN_DMICCDAT */
0x0000 /* 5:Default */
>;
+ amic-mono;
};
- ov5642: camera@3c {
- compatible = "ovti,ov5642";
+ mma8451@1c {
+ compatible = "fsl,mma8451";
+ reg = <0x1c>;
+ position = <0>;
+ vdd-supply = <&reg_sensor>;
+ vddio-supply = <&reg_sensor>;
+ interrupt-parent = <&gpio1>;
+ interrupts = <18 8>;
+ interrupt-route = <1>;
+ };
+
+ ov564x: ov564x@3c {
+ compatible = "ovti,ov564x";
+ reg = <0x3c>;
pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_ov5642>;
+ pinctrl-0 = <&pinctrl_ipu1_2>;
clocks = <&clks IMX6QDL_CLK_CKO>;
- clock-names = "xclk";
- reg = <0x3c>;
+ clock-names = "csi_mclk";
DOVDD-supply = <&vgen4_reg>; /* 1.8v */
- AVDD-supply = <&vgen3_reg>; /* 2.8v, rev C board is VGEN3
- rev B board is VGEN5 */
+ AVDD-supply = <&vgen3_reg>; /* 2.8v, on rev C board is VGEN3,
+ on rev B board is VGEN5 */
DVDD-supply = <&vgen2_reg>; /* 1.5v*/
- powerdown-gpios = <&gpio1 16 GPIO_ACTIVE_HIGH>;
- reset-gpios = <&gpio1 17 GPIO_ACTIVE_LOW>;
- status = "disabled";
-
- port {
- ov5642_to_ipu1_csi0_mux: endpoint {
- remote-endpoint = <&ipu1_csi0_mux_from_parallel_sensor>;
- bus-width = <8>;
- hsync-active = <1>;
- vsync-active = <1>;
- };
- };
+ pwn-gpios = <&gpio1 16 1>; /* active low: SD1_DAT0 */
+ rst-gpios = <&gpio1 17 0>; /* active high: SD1_DAT1 */
+ csi_id = <0>;
+ mclk = <24000000>;
+ mclk_source = <0>;
};
};
&i2c2 {
clock-frequency = <100000>;
- pinctrl-names = "default";
+ pinctrl-names = "default", "gpio";
pinctrl-0 = <&pinctrl_i2c2>;
+ pinctrl-1 = <&pinctrl_i2c2_gpio>;
+ scl-gpios = <&gpio4 12 GPIO_ACTIVE_HIGH>;
+ sda-gpios = <&gpio4 13 GPIO_ACTIVE_HIGH>;
status = "okay";
- ov5640: camera@3c {
- compatible = "ovti,ov5640";
+ egalax_ts@04 {
+ compatible = "eeti,egalax_ts";
+ reg = <0x04>;
pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_ov5640>;
- reg = <0x3c>;
- clocks = <&clks IMX6QDL_CLK_CKO>;
- clock-names = "xclk";
- DOVDD-supply = <&vgen4_reg>; /* 1.8v */
- AVDD-supply = <&vgen3_reg>; /* 2.8v, rev C board is VGEN3
- rev B board is VGEN5 */
- DVDD-supply = <&vgen2_reg>; /* 1.5v*/
- powerdown-gpios = <&gpio1 19 GPIO_ACTIVE_HIGH>;
- reset-gpios = <&gpio1 20 GPIO_ACTIVE_LOW>;
-
- port {
- #address-cells = <1>;
- #size-cells = <0>;
+ pinctrl-0 = <&pinctrl_i2c2_egalax_int>;
+ interrupt-parent = <&gpio6>;
+ interrupts = <8 2>;
+ wakeup-gpios = <&gpio6 8 0>;
+ };
- ov5640_to_mipi_csi2: endpoint {
- remote-endpoint = <&mipi_csi2_in>;
- clock-lanes = <0>;
- data-lanes = <1 2>;
- };
- };
+ max11801@48 {
+ compatible = "maxim,max11801";
+ reg = <0x48>;
+ interrupt-parent = <&gpio3>;
+ interrupts = <26 2>;
+ work-mode = <1>;/*DCM mode*/
};
pmic: pfuze100@08 {
@@ -350,6 +517,7 @@
sw4_reg: sw4 {
regulator-min-microvolt = <800000>;
regulator-max-microvolt = <3300000>;
+ regulator-always-on;
};
swbst_reg: swbst {
@@ -403,6 +571,27 @@
};
};
};
+
+ hdmi_edid: edid@50 {
+ compatible = "fsl,imx6-hdmi-i2c";
+ reg = <0x50>;
+ };
+
+ ov564x_mipi: ov564x_mipi@3c { /* i2c2 driver */
+ compatible = "ovti,ov564x_mipi";
+ reg = <0x3c>;
+ clocks = <&clks 201>;
+ clock-names = "csi_mclk";
+ DOVDD-supply = <&vgen4_reg>; /* 1.8v */
+ AVDD-supply = <&vgen3_reg>; /* 2.8v, rev C board is VGEN3
+ rev B board is VGEN5 */
+ DVDD-supply = <&vgen2_reg>; /* 1.5v*/
+ pwn-gpios = <&gpio1 19 1>; /* active low: SD1_CLK */
+ rst-gpios = <&gpio1 20 0>; /* active high: SD1_DAT2 */
+ csi_id = <1>;
+ mclk = <24000000>;
+ mclk_source = <0>;
+ };
};
&i2c3 {
@@ -414,10 +603,31 @@
egalax_ts@04 {
compatible = "eeti,egalax_ts";
reg = <0x04>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c3_egalax_int>;
interrupt-parent = <&gpio6>;
interrupts = <7 2>;
wakeup-gpios = <&gpio6 7 0>;
};
+
+ isl29023@44 {
+ compatible = "fsl,isl29023";
+ reg = <0x44>;
+ rext = <499>;
+ vdd-supply = <&reg_sensor>;
+ interrupt-parent = <&gpio3>;
+ interrupts = <9 2>;
+ };
+
+ mag3110@0e {
+ compatible = "fsl,mag3110";
+ reg = <0x0e>;
+ position = <2>;
+ vdd-supply = <&reg_sensor>;
+ vddio-supply = <&reg_sensor>;
+ interrupt-parent = <&gpio3>;
+ interrupts = <16 1>;
+ };
};
&iomuxc {
@@ -427,15 +637,29 @@
imx6qdl-sabresd {
pinctrl_hog: hoggrp {
fsl,pins = <
- MX6QDL_PAD_NANDF_D0__GPIO2_IO00 0x1b0b0
- MX6QDL_PAD_NANDF_D1__GPIO2_IO01 0x1b0b0
- MX6QDL_PAD_NANDF_D2__GPIO2_IO02 0x1b0b0
- MX6QDL_PAD_NANDF_D3__GPIO2_IO03 0x1b0b0
+ MX6QDL_PAD_NANDF_D0__GPIO2_IO00 0x80000000
+ MX6QDL_PAD_NANDF_D1__GPIO2_IO01 0x80000000
+ MX6QDL_PAD_NANDF_D2__GPIO2_IO02 0x80000000
+ MX6QDL_PAD_NANDF_D3__GPIO2_IO03 0x80000000
MX6QDL_PAD_GPIO_0__CCM_CLKO1 0x130b0
- MX6QDL_PAD_NANDF_CLE__GPIO6_IO07 0x1b0b0
- MX6QDL_PAD_ENET_TXD1__GPIO1_IO29 0x1b0b0
- MX6QDL_PAD_EIM_D22__GPIO3_IO22 0x1b0b0
- MX6QDL_PAD_ENET_CRS_DV__GPIO1_IO25 0x1b0b0
+ MX6QDL_PAD_ENET_TXD1__GPIO1_IO29 0x80000000
+ MX6QDL_PAD_EIM_D22__GPIO3_IO22 0x80000000
+ MX6QDL_PAD_ENET_CRS_DV__GPIO1_IO25 0x80000000
+ MX6QDL_PAD_EIM_D26__GPIO3_IO26 0x80000000
+ MX6QDL_PAD_EIM_CS1__GPIO2_IO24 0x80000000
+ MX6QDL_PAD_ENET_RXD0__GPIO1_IO27 0x80000000
+ MX6QDL_PAD_EIM_A25__GPIO5_IO02 0x80000000
+ MX6QDL_PAD_EIM_D23__GPIO3_IO23 0x80000000
+ MX6QDL_PAD_EIM_EB3__GPIO2_IO31 0x80000000
+ MX6QDL_PAD_SD1_CMD__GPIO1_IO18 0x80000000
+ MX6QDL_PAD_EIM_D16__GPIO3_IO16 0x80000000
+ MX6QDL_PAD_SD3_RST__GPIO7_IO08 0x80000000
+ MX6QDL_PAD_GPIO_9__GPIO1_IO09 0x80000000
+ MX6QDL_PAD_EIM_DA9__GPIO3_IO09 0x80000000
+ MX6QDL_PAD_NANDF_CS0__GPIO6_IO11 0x80000000
+ MX6QDL_PAD_NANDF_CS1__GPIO6_IO14 0x80000000
+ MX6QDL_PAD_NANDF_CS2__GPIO6_IO15 0x80000000
+ MX6QDL_PAD_NANDF_CS3__GPIO6_IO16 0x80000000
>;
};
@@ -457,6 +681,18 @@
>;
};
+ pinctrl_i2c2_egalax_int: egalax_i2c2_intgrp {
+ fsl,pins = <
+ MX6QDL_PAD_NANDF_ALE__GPIO6_IO08 0x80000000
+ >;
+ };
+
+ pinctrl_i2c3_egalax_int: egalax_i2c3_intgrp {
+ fsl,pins = <
+ MX6QDL_PAD_NANDF_CLE__GPIO6_IO07 0x80000000
+ >;
+ };
+
pinctrl_enet: enetgrp {
fsl,pins = <
MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x1b0b0
@@ -478,6 +714,12 @@
>;
};
+ pinctrl_enet_irq: enetirqgrp {
+ fsl,pins = <
+ MX6QDL_PAD_GPIO_6__ENET_IRQ 0x000b1
+ >;
+ };
+
pinctrl_gpio_keys: gpio_keysgrp {
fsl,pins = <
MX6QDL_PAD_EIM_D29__GPIO3_IO29 0x1b0b0
@@ -486,6 +728,19 @@
>;
};
+ pinctrl_hdmi_cec: hdmicecgrp {
+ fsl,pins = <
+ MX6QDL_PAD_KEY_ROW2__HDMI_TX_CEC_LINE 0x108b0
+ >;
+ };
+
+ pinctrl_hdmi_hdcp: hdmihdcpgrp {
+ fsl,pins = <
+ MX6QDL_PAD_KEY_COL3__HDMI_TX_DDC_SCL 0x4001b8b1
+ MX6QDL_PAD_KEY_ROW3__HDMI_TX_DDC_SDA 0x4001b8b1
+ >;
+ };
+
pinctrl_i2c1: i2c1grp {
fsl,pins = <
MX6QDL_PAD_CSI0_DAT8__I2C1_SDA 0x4001b8b1
@@ -500,6 +755,13 @@
>;
};
+ pinctrl_i2c2_gpio: i2c2_gpio_grp {
+ fsl,pins = <
+ MX6QDL_PAD_KEY_COL3__GPIO4_IO12 0x1b0b0
+ MX6QDL_PAD_KEY_ROW3__GPIO4_IO13 0x1b0b0
+ >;
+ };
+
pinctrl_i2c3: i2c3grp {
fsl,pins = <
MX6QDL_PAD_GPIO_3__I2C3_SCL 0x4001b8b1
@@ -507,6 +769,59 @@
>;
};
+ pinctrl_ipu1: ipu1grp {
+ fsl,pins = <
+ MX6QDL_PAD_DI0_DISP_CLK__IPU1_DI0_DISP_CLK 0x10
+ MX6QDL_PAD_DI0_PIN15__IPU1_DI0_PIN15 0x10
+ MX6QDL_PAD_DI0_PIN2__IPU1_DI0_PIN02 0x10
+ MX6QDL_PAD_DI0_PIN3__IPU1_DI0_PIN03 0x10
+ MX6QDL_PAD_DI0_PIN4__IPU1_DI0_PIN04 0x80000000
+ MX6QDL_PAD_DISP0_DAT0__IPU1_DISP0_DATA00 0x10
+ MX6QDL_PAD_DISP0_DAT1__IPU1_DISP0_DATA01 0x10
+ MX6QDL_PAD_DISP0_DAT2__IPU1_DISP0_DATA02 0x10
+ MX6QDL_PAD_DISP0_DAT3__IPU1_DISP0_DATA03 0x10
+ MX6QDL_PAD_DISP0_DAT4__IPU1_DISP0_DATA04 0x10
+ MX6QDL_PAD_DISP0_DAT5__IPU1_DISP0_DATA05 0x10
+ MX6QDL_PAD_DISP0_DAT6__IPU1_DISP0_DATA06 0x10
+ MX6QDL_PAD_DISP0_DAT7__IPU1_DISP0_DATA07 0x10
+ MX6QDL_PAD_DISP0_DAT8__IPU1_DISP0_DATA08 0x10
+ MX6QDL_PAD_DISP0_DAT9__IPU1_DISP0_DATA09 0x10
+ MX6QDL_PAD_DISP0_DAT10__IPU1_DISP0_DATA10 0x10
+ MX6QDL_PAD_DISP0_DAT11__IPU1_DISP0_DATA11 0x10
+ MX6QDL_PAD_DISP0_DAT12__IPU1_DISP0_DATA12 0x10
+ MX6QDL_PAD_DISP0_DAT13__IPU1_DISP0_DATA13 0x10
+ MX6QDL_PAD_DISP0_DAT14__IPU1_DISP0_DATA14 0x10
+ MX6QDL_PAD_DISP0_DAT15__IPU1_DISP0_DATA15 0x10
+ MX6QDL_PAD_DISP0_DAT16__IPU1_DISP0_DATA16 0x10
+ MX6QDL_PAD_DISP0_DAT17__IPU1_DISP0_DATA17 0x10
+ MX6QDL_PAD_DISP0_DAT18__IPU1_DISP0_DATA18 0x10
+ MX6QDL_PAD_DISP0_DAT19__IPU1_DISP0_DATA19 0x10
+ MX6QDL_PAD_DISP0_DAT20__IPU1_DISP0_DATA20 0x10
+ MX6QDL_PAD_DISP0_DAT21__IPU1_DISP0_DATA21 0x10
+ MX6QDL_PAD_DISP0_DAT22__IPU1_DISP0_DATA22 0x10
+ MX6QDL_PAD_DISP0_DAT23__IPU1_DISP0_DATA23 0x10
+ >;
+ };
+
+ pinctrl_ipu1_2: ipu1grp-2 { /* parallel camera */
+ fsl,pins = <
+ MX6QDL_PAD_CSI0_DAT12__IPU1_CSI0_DATA12 0x80000000
+ MX6QDL_PAD_CSI0_DAT13__IPU1_CSI0_DATA13 0x80000000
+ MX6QDL_PAD_CSI0_DAT14__IPU1_CSI0_DATA14 0x80000000
+ MX6QDL_PAD_CSI0_DAT15__IPU1_CSI0_DATA15 0x80000000
+ MX6QDL_PAD_CSI0_DAT16__IPU1_CSI0_DATA16 0x80000000
+ MX6QDL_PAD_CSI0_DAT17__IPU1_CSI0_DATA17 0x80000000
+ MX6QDL_PAD_CSI0_DAT18__IPU1_CSI0_DATA18 0x80000000
+ MX6QDL_PAD_CSI0_DAT19__IPU1_CSI0_DATA19 0x80000000
+ MX6QDL_PAD_CSI0_DATA_EN__IPU1_CSI0_DATA_EN 0x80000000
+ MX6QDL_PAD_CSI0_PIXCLK__IPU1_CSI0_PIXCLK 0x80000000
+ MX6QDL_PAD_CSI0_MCLK__IPU1_CSI0_HSYNC 0x80000000
+ MX6QDL_PAD_CSI0_VSYNC__IPU1_CSI0_VSYNC 0x80000000
+ MX6QDL_PAD_SD1_DAT1__GPIO1_IO17 0x80000000
+ MX6QDL_PAD_SD1_DAT0__GPIO1_IO16 0x80000000
+ >;
+ };
+
pinctrl_ipu1_csi0: ipu1csi0grp {
fsl,pins = <
MX6QDL_PAD_CSI0_DAT12__IPU1_CSI0_DATA12 0x1b0b0
@@ -562,6 +877,24 @@
>;
};
+ pinctrl_uart5_1: uart5grp-1 {
+ fsl,pins = <
+ MX6QDL_PAD_KEY_COL1__UART5_TX_DATA 0x1b0b1
+ MX6QDL_PAD_KEY_ROW1__UART5_RX_DATA 0x1b0b1
+ MX6QDL_PAD_KEY_COL4__UART5_RTS_B 0x1b0b1
+ MX6QDL_PAD_KEY_ROW4__UART5_CTS_B 0x1b0b1
+ >;
+ };
+
+ pinctrl_uart5dte_1: uart5dtegrp-1 {
+ fsl,pins = <
+ MX6QDL_PAD_KEY_ROW1__UART5_TX_DATA 0x1b0b1
+ MX6QDL_PAD_KEY_COL1__UART5_RX_DATA 0x1b0b1
+ MX6QDL_PAD_KEY_ROW4__UART5_RTS_B 0x1b0b1
+ MX6QDL_PAD_KEY_COL4__UART5_CTS_B 0x1b0b1
+ >;
+ };
+
pinctrl_usbotg: usbotggrp {
fsl,pins = <
MX6QDL_PAD_ENET_RX_ER__USB_OTG_ID 0x17059
@@ -615,7 +948,7 @@
pinctrl_wdog: wdoggrp {
fsl,pins = <
- MX6QDL_PAD_GPIO_1__WDOG2_B 0x1b0b0
+ MX6QDL_PAD_GPIO_1__WDOG2_B 0x80000000
>;
};
};
@@ -632,21 +965,68 @@
&ldb {
status = "okay";
- lvds-channel@1 {
+ lvds-channel@0 {
fsl,data-mapping = "spwg";
fsl,data-width = <18>;
status = "okay";
- port@4 {
- reg = <4>;
+ display-timings {
+ native-mode = <&timing0>;
+ timing0: hsd100pxn1 {
+ clock-frequency = <65000000>;
+ hactive = <1024>;
+ vactive = <768>;
+ hback-porch = <220>;
+ hfront-porch = <40>;
+ vback-porch = <21>;
+ vfront-porch = <7>;
+ hsync-len = <60>;
+ vsync-len = <10>;
+ };
+ };
+ };
- lvds0_out: endpoint {
- remote-endpoint = <&panel_in>;
+ lvds-channel@1 {
+ fsl,data-mapping = "spwg";
+ fsl,data-width = <18>;
+ primary;
+ status = "okay";
+
+ display-timings {
+ native-mode = <&timing1>;
+ timing1: hsd100pxn1 {
+ clock-frequency = <65000000>;
+ hactive = <1024>;
+ vactive = <768>;
+ hback-porch = <220>;
+ hfront-porch = <40>;
+ vback-porch = <21>;
+ vfront-porch = <7>;
+ hsync-len = <60>;
+ vsync-len = <10>;
};
};
};
};
+&mipi_csi {
+ status = "okay";
+ ipu_id = <0>;
+ csi_id = <1>;
+ v_channel = <0>;
+ lanes = <2>;
+};
+
+&mipi_dsi {
+ dev_id = <0>;
+ disp_id = <1>;
+ lcd_panel = "TRULY-WVGA";
+ disp-power-on-supply = <&reg_mipi_dsi_pwr_on>;
+ reset-gpios = <&gpio6 11 GPIO_ACTIVE_LOW>;
+ reset-delay-us = <50>;
+ status = "okay";
+};
+
&pcie {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_pcie>;
@@ -677,6 +1057,13 @@
};
&ssi2 {
+ assigned-clocks = <&clks IMX6QDL_CLK_PLL4>,
+ <&clks IMX6QDL_PLL4_BYPASS>,
+ <&clks IMX6QDL_CLK_SSI2_SEL>;
+ assigned-clock-parents = <&clks IMX6QDL_CLK_OSC>,
+ <&clks IMX6QDL_CLK_PLL4>,
+ <&clks IMX6QDL_CLK_PLL4_AUDIO_DIV>;
+ assigned-clock-rates = <737280000>, <0>, <0>;
status = "okay";
};
@@ -696,15 +1083,29 @@
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_usbotg>;
disable-over-current;
+ srp-disable;
+ hnp-disable;
+ adp-disable;
status = "okay";
};
+&usbphy1 {
+ fsl,tx-d-cal = <106>;
+};
+
+&usbphy2 {
+ fsl,tx-d-cal = <106>;
+};
+
&usdhc2 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_usdhc2>;
bus-width = <8>;
cd-gpios = <&gpio2 2 GPIO_ACTIVE_LOW>;
wp-gpios = <&gpio2 3 GPIO_ACTIVE_HIGH>;
+ no-1-8-v;
+ keep-power-in-suspend;
+ enable-sdio-wakeup;
status = "okay";
};
@@ -714,6 +1115,9 @@
bus-width = <8>;
cd-gpios = <&gpio2 0 GPIO_ACTIVE_LOW>;
wp-gpios = <&gpio2 1 GPIO_ACTIVE_HIGH>;
+ no-1-8-v;
+ keep-power-in-suspend;
+ enable-sdio-wakeup;
status = "okay";
};
@@ -723,6 +1127,7 @@
bus-width = <8>;
non-removable;
no-1-8-v;
+ keep-power-in-suspend;
status = "okay";
};
diff --git a/arch/arm/boot/dts/imx6qdl-udoo.dtsi b/arch/arm/boot/dts/imx6qdl-udoo.dtsi
index c96c91d83678..6b4984feea93 100644
--- a/arch/arm/boot/dts/imx6qdl-udoo.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-udoo.dtsi
@@ -1,5 +1,5 @@
/*
- * Copyright 2013 Freescale Semiconductor, Inc.
+ * Copyright 2013-2015 Freescale Semiconductor, Inc.
*
* Author: Fabio Estevam <fabio.estevam@freescale.com>
*
@@ -15,6 +15,7 @@
panelchan = &panelchan;
panel7 = &panel7;
touchscreenp7 = &touchscreenp7;
+ mxcfb0 = &mxcfb1;
};
chosen {
@@ -89,6 +90,17 @@
mux-int-port = <1>;
mux-ext-port = <6>;
};
+
+ mxcfb1: fb@0 {
+ compatible = "fsl,mxc_sdc_fb";
+ disp_dev = "hdmi";
+ interface_pix_fmt = "RGB24";
+ mode_str ="1920x1080M@60";
+ default_bpp = <24>;
+ int_clk = <0>;
+ late_init = <0>;
+ status = "okay";
+ };
};
&fec {
@@ -98,8 +110,15 @@
status = "okay";
};
-&hdmi {
- ddc-i2c-bus = <&i2c2>;
+&hdmi_core {
+ ipu_id = <0>;
+ disp_id = <0>;
+ status = "okay";
+};
+
+&hdmi_video {
+ fsl,phy_reg_vlev = <0x0294>;
+ fsl,phy_reg_cksymtx = <0x800d>;
status = "okay";
};
@@ -108,6 +127,11 @@
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_i2c2>;
status = "okay";
+
+ hdmi_edid: edid@50 {
+ compatible = "fsl,imx6-hdmi-i2c";
+ reg = <0x50>;
+ };
};
&i2c3 {
diff --git a/arch/arm/boot/dts/imx6qdl-wandboard.dtsi b/arch/arm/boot/dts/imx6qdl-wandboard.dtsi
index b4fa7f1d63da..287d7f5f93d1 100644
--- a/arch/arm/boot/dts/imx6qdl-wandboard.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-wandboard.dtsi
@@ -1,5 +1,5 @@
/*
- * Copyright 2013 Freescale Semiconductor, Inc.
+ * Copyright 2013-2015 Freescale Semiconductor, Inc.
*
* Author: Fabio Estevam <fabio.estevam@freescale.com>
*
@@ -64,11 +64,6 @@
status = "okay";
};
-&hdmi {
- ddc-i2c-bus = <&i2c1>;
- status = "okay";
-};
-
&i2c1 {
clock-frequency = <100000>;
pinctrl-names = "default";
diff --git a/arch/arm/boot/dts/imx6qdl.dtsi b/arch/arm/boot/dts/imx6qdl.dtsi
index 0fedb0c24eca..0691cceca4da 100644
--- a/arch/arm/boot/dts/imx6qdl.dtsi
+++ b/arch/arm/boot/dts/imx6qdl.dtsi
@@ -1,5 +1,5 @@
/*
- * Copyright 2011 Freescale Semiconductor, Inc.
+ * Copyright 2011-2016 Freescale Semiconductor, Inc.
* Copyright 2011 Linaro Ltd.
*
* The code contained herein is licensed under the GNU General Public
@@ -87,6 +87,11 @@
interrupt-parent = <&gpc>;
ranges;
+ caam_sm: caam-sm@00100000 {
+ compatible = "fsl,imx6q-caam-sm";
+ reg = <0x00100000 0x4000>;
+ };
+
dma_apbh: dma-apbh@00110000 {
compatible = "fsl,imx6q-dma-apbh", "fsl,imx28-dma-apbh";
reg = <0x00110000 0x2000>;
@@ -100,6 +105,16 @@
clocks = <&clks IMX6QDL_CLK_APBH_DMA>;
};
+ irq_sec_vio: caam_secvio {
+ compatible = "fsl,imx6q-caam-secvio";
+ interrupts = <0 20 0x04>;
+ secvio_src = <0x8000001d>;
+ jtag-tamper = "disabled";
+ watchdog-tamper = "enabled";
+ internal-boot-tamper = "enabled";
+ external-pin-tamper = "disabled";
+ };
+
gpmi: gpmi-nand@00112000 {
compatible = "fsl,imx6q-gpmi-nand";
#address-cells = <1>;
@@ -169,6 +184,18 @@
power-domains = <&pd_pu>;
};
+ ocrams: sram@00900000 {
+ compatible = "fsl,lpm-sram";
+ reg = <0x00900000 0x4000>;
+ clocks = <&clks IMX6QDL_CLK_OCRAM>;
+ };
+
+ ocrams_ddr: sram@00904000 {
+ compatible = "fsl,ddr-lpm-sram";
+ reg = <0x00904000 0x1000>;
+ clocks = <&clks IMX6QDL_CLK_OCRAM>;
+ };
+
timer@00a00600 {
compatible = "arm,cortex-a9-twd-timer";
reg = <0x00a00600 0x20>;
@@ -221,6 +248,7 @@
<&clks IMX6QDL_CLK_LVDS1_GATE>,
<&clks IMX6QDL_CLK_PCIE_REF_125M>;
clock-names = "pcie", "pcie_bus", "pcie_phy";
+ fsl,max-link-speed = <2>;
status = "disabled";
};
@@ -229,6 +257,45 @@
interrupts = <0 94 IRQ_TYPE_LEVEL_HIGH>;
};
+ hdmi_core: hdmi_core@00120000 {
+ compatible = "fsl,imx6q-hdmi-core";
+ reg = <0x00120000 0x9000>;
+ clocks = <&clks IMX6QDL_CLK_HDMI_ISFR>,
+ <&clks IMX6QDL_CLK_HDMI_IAHB>,
+ <&clks IMX6QDL_CLK_HSI_TX>;
+ clock-names = "hdmi_isfr", "hdmi_iahb", "mipi_core";
+ status = "disabled";
+ };
+
+ hdmi_video: hdmi_video@020e0000 {
+ compatible = "fsl,imx6q-hdmi-video";
+ reg = <0x020e0000 0x1000>;
+ reg-names = "hdmi_gpr";
+ interrupts = <0 115 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6QDL_CLK_HDMI_ISFR>,
+ <&clks IMX6QDL_CLK_HDMI_IAHB>,
+ <&clks IMX6QDL_CLK_HSI_TX>;
+ clock-names = "hdmi_isfr", "hdmi_iahb", "mipi_core";
+ status = "disabled";
+ };
+
+ hdmi_audio: hdmi_audio@00120000 {
+ compatible = "fsl,imx6q-hdmi-audio";
+ clocks = <&clks IMX6QDL_CLK_HDMI_ISFR>,
+ <&clks IMX6QDL_CLK_HDMI_IAHB>,
+ <&clks IMX6QDL_CLK_HSI_TX>;
+ clock-names = "hdmi_isfr", "hdmi_iahb", "mipi_core";
+ dmas = <&sdma 2 25 0>;
+ dma-names = "tx";
+ status = "disabled";
+ };
+
+ hdmi_cec: hdmi_cec@00120000 {
+ compatible = "fsl,imx6q-hdmi-cec";
+ interrupts = <0 115 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
+
aips-bus@02000000 { /* AIPS1 */
compatible = "fsl,aips-bus", "simple-bus";
#address-cells = <1>;
@@ -253,7 +320,7 @@
clocks = <&clks IMX6QDL_CLK_SPDIF_GCLK>, <&clks IMX6QDL_CLK_OSC>,
<&clks IMX6QDL_CLK_SPDIF>, <&clks IMX6QDL_CLK_ASRC>,
<&clks IMX6QDL_CLK_DUMMY>, <&clks IMX6QDL_CLK_ESAI_EXTAL>,
- <&clks IMX6QDL_CLK_IPG>, <&clks IMX6QDL_CLK_DUMMY>,
+ <&clks IMX6QDL_CLK_IPG>, <&clks IMX6QDL_CLK_MLB>,
<&clks IMX6QDL_CLK_DUMMY>, <&clks IMX6QDL_CLK_SPBA>;
clock-names = "core", "rxtx0",
"rxtx1", "rxtx2",
@@ -272,7 +339,7 @@
clocks = <&clks IMX6QDL_CLK_ECSPI1>,
<&clks IMX6QDL_CLK_ECSPI1>;
clock-names = "ipg", "per";
- dmas = <&sdma 3 8 1>, <&sdma 4 8 2>;
+ dmas = <&sdma 3 7 1>, <&sdma 4 7 2>;
dma-names = "rx", "tx";
status = "disabled";
};
@@ -286,7 +353,7 @@
clocks = <&clks IMX6QDL_CLK_ECSPI2>,
<&clks IMX6QDL_CLK_ECSPI2>;
clock-names = "ipg", "per";
- dmas = <&sdma 5 8 1>, <&sdma 6 8 2>;
+ dmas = <&sdma 5 7 1>, <&sdma 6 7 2>;
dma-names = "rx", "tx";
status = "disabled";
};
@@ -300,7 +367,7 @@
clocks = <&clks IMX6QDL_CLK_ECSPI3>,
<&clks IMX6QDL_CLK_ECSPI3>;
clock-names = "ipg", "per";
- dmas = <&sdma 7 8 1>, <&sdma 8 8 2>;
+ dmas = <&sdma 7 7 1>, <&sdma 8 7 2>;
dma-names = "rx", "tx";
status = "disabled";
};
@@ -314,7 +381,7 @@
clocks = <&clks IMX6QDL_CLK_ECSPI4>,
<&clks IMX6QDL_CLK_ECSPI4>;
clock-names = "ipg", "per";
- dmas = <&sdma 9 8 1>, <&sdma 10 8 2>;
+ dmas = <&sdma 9 7 1>, <&sdma 10 7 2>;
dma-names = "rx", "tx";
status = "disabled";
};
@@ -356,8 +423,8 @@
clocks = <&clks IMX6QDL_CLK_SSI1_IPG>,
<&clks IMX6QDL_CLK_SSI1>;
clock-names = "ipg", "baud";
- dmas = <&sdma 37 1 0>,
- <&sdma 38 1 0>;
+ dmas = <&sdma 37 22 0>,
+ <&sdma 38 22 0>;
dma-names = "rx", "tx";
fsl,fifo-depth = <15>;
status = "disabled";
@@ -372,8 +439,8 @@
clocks = <&clks IMX6QDL_CLK_SSI2_IPG>,
<&clks IMX6QDL_CLK_SSI2>;
clock-names = "ipg", "baud";
- dmas = <&sdma 41 1 0>,
- <&sdma 42 1 0>;
+ dmas = <&sdma 41 22 0>,
+ <&sdma 42 22 0>;
dma-names = "rx", "tx";
fsl,fifo-depth = <15>;
status = "disabled";
@@ -388,8 +455,8 @@
clocks = <&clks IMX6QDL_CLK_SSI3_IPG>,
<&clks IMX6QDL_CLK_SSI3>;
clock-names = "ipg", "baud";
- dmas = <&sdma 45 1 0>,
- <&sdma 46 1 0>;
+ dmas = <&sdma 45 22 0>,
+ <&sdma 46 22 0>;
dma-names = "rx", "tx";
fsl,fifo-depth = <15>;
status = "disabled";
@@ -437,6 +504,24 @@
power-domains = <&pd_pu>;
resets = <&src 1>;
iram = <&ocram>;
+ status = "disabled";
+ };
+
+ vpu_fsl: vpu_fsl@02040000 {
+ compatible = "fsl,imx6-vpu";
+ reg = <0x02040000 0x3c000>;
+ reg-names = "vpu_regs";
+ interrupts = <0 3 IRQ_TYPE_EDGE_RISING>,
+ <0 12 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "vpu_jpu_irq", "vpu_ipi_irq";
+ clocks = <&clks IMX6QDL_CLK_VPU_AXI>,
+ <&clks IMX6QDL_CLK_MMDC_CH0_AXI>,
+ <&clks IMX6QDL_CLK_OCRAM>;
+ clock-names = "vpu_clk", "mmdc_ch0_axi", "ocram";
+ iramsize = <0x21000>;
+ iram = <&ocram>;
+ resets = <&src 1>;
+ power-domains = <&pd_pu>;
};
aipstz@0207c000 { /* AIPSTZ1 */
@@ -494,6 +579,7 @@
clocks = <&clks IMX6QDL_CLK_CAN1_IPG>,
<&clks IMX6QDL_CLK_CAN1_SERIAL>;
clock-names = "ipg", "per";
+ stop-mode = <&gpr 0x34 28 0x10 17>;
status = "disabled";
};
@@ -504,6 +590,7 @@
clocks = <&clks IMX6QDL_CLK_CAN2_IPG>,
<&clks IMX6QDL_CLK_CAN2_SERIAL>;
clock-names = "ipg", "per";
+ stop-mode = <&gpr 0x34 29 0x10 18>;
status = "disabled";
};
@@ -647,12 +734,11 @@
anatop-enable-bit = <0>;
};
- regulator-3p0 {
+ anatop_reg_3p0: regulator-3p0@120 {
compatible = "fsl,anatop-regulator";
regulator-name = "vdd3p0";
- regulator-min-microvolt = <2800000>;
- regulator-max-microvolt = <3150000>;
- regulator-always-on;
+ regulator-min-microvolt = <2625000>;
+ regulator-max-microvolt = <3400000>;
anatop-reg-offset = <0x120>;
anatop-vol-bit-shift = <8>;
anatop-vol-bit-width = <5>;
@@ -692,6 +778,7 @@
anatop-min-bit-val = <1>;
anatop-min-voltage = <725000>;
anatop-max-voltage = <1450000>;
+ regulator-allow-bypass;
};
reg_pu: regulator-vddpu {
@@ -709,6 +796,7 @@
anatop-min-bit-val = <1>;
anatop-min-voltage = <725000>;
anatop-max-voltage = <1450000>;
+ regulator-allow-bypass;
};
reg_soc: regulator-vddsoc {
@@ -726,6 +814,7 @@
anatop-min-bit-val = <1>;
anatop-min-voltage = <725000>;
anatop-max-voltage = <1450000>;
+ regulator-allow-bypass;
};
};
@@ -742,6 +831,7 @@
reg = <0x020c9000 0x1000>;
interrupts = <0 44 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clks IMX6QDL_CLK_USBPHY1>;
+ phy-3p0-supply = <&anatop_reg_3p0>;
fsl,anatop = <&anatop>;
};
@@ -750,9 +840,27 @@
reg = <0x020ca000 0x1000>;
interrupts = <0 45 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clks IMX6QDL_CLK_USBPHY2>;
+ phy-3p0-supply = <&anatop_reg_3p0>;
fsl,anatop = <&anatop>;
};
+ usbphy_nop1: usbphy_nop1 {
+ compatible = "usb-nop-xceiv";
+ clocks = <&clks IMX6QDL_CLK_USBPHY1>;
+ clock-names = "main_clk";
+ };
+
+ usbphy_nop2: usbphy_nop2 {
+ compatible = "usb-nop-xceiv";
+ clocks = <&clks IMX6QDL_CLK_USBPHY1>;
+ clock-names = "main_clk";
+ };
+
+ caam_snvs: caam-snvs@020cc000 {
+ compatible = "fsl,imx6q-caam-snvs";
+ reg = <0x020cc000 0x4000>;
+ };
+
snvs: snvs@020cc000 {
compatible = "fsl,sec-v4.0-mon", "syscon", "simple-mfd";
reg = <0x020cc000 0x4000>;
@@ -769,8 +877,8 @@
compatible = "syscon-poweroff";
regmap = <&snvs>;
offset = <0x38>;
- value = <0x60>;
- mask = <0x60>;
+ value = <0x61>;
+ mask = <0x61>;
status = "disabled";
};
};
@@ -896,13 +1004,23 @@
};
dcic1: dcic@020e4000 {
+ compatible = "fsl,imx6q-dcic";
reg = <0x020e4000 0x4000>;
interrupts = <0 124 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6QDL_CLK_DCIC1>, <&clks IMX6QDL_CLK_DCIC1>;
+ clock-names = "dcic", "disp-axi";
+ gpr = <&gpr>;
+ status = "disabled";
};
dcic2: dcic@020e8000 {
+ compatible = "fsl,imx6q-dcic";
reg = <0x020e8000 0x4000>;
interrupts = <0 125 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6QDL_CLK_DCIC2>, <&clks IMX6QDL_CLK_DCIC2>;
+ clock-names = "dcic", "disp-axi";
+ gpr = <&gpr>;
+ status = "disabled";
};
sdma: sdma@020ec000 {
@@ -926,17 +1044,26 @@
crypto: caam@2100000 {
compatible = "fsl,sec-v4.0";
- fsl,sec-era = <4>;
#address-cells = <1>;
#size-cells = <1>;
reg = <0x2100000 0x10000>;
- ranges = <0 0x2100000 0x10000>;
+ ranges = <0 0x2100000 0x40000>;
+ interrupt-parent = <&intc>; /* interrupts = <0 92 0x4>; */
clocks = <&clks IMX6QDL_CLK_CAAM_MEM>,
<&clks IMX6QDL_CLK_CAAM_ACLK>,
<&clks IMX6QDL_CLK_CAAM_IPG>,
<&clks IMX6QDL_CLK_EIM_SLOW>;
clock-names = "mem", "aclk", "ipg", "emi_slow";
+ sec_ctrl: ctrl@0 {
+ /* CAAM Page 0 only accessible */
+ /* by secure world */
+ compatible = "fsl,sec-v4.0-ctrl";
+ reg = <0x2100000 0x1000>;
+ secure-status = "okay";
+ status = "disabled";
+ };
+
sec_jr0: jr0@1000 {
compatible = "fsl,sec-v4.0-job-ring";
reg = <0x1000 0x1000>;
@@ -964,6 +1091,7 @@
ahb-burst-config = <0x0>;
tx-burst-size-dword = <0x10>;
rx-burst-size-dword = <0x10>;
+ fsl,anatop = <&anatop>;
status = "disabled";
};
@@ -991,6 +1119,9 @@
ahb-burst-config = <0x0>;
tx-burst-size-dword = <0x10>;
rx-burst-size-dword = <0x10>;
+ phy_type = "hsic";
+ fsl,usbphy = <&usbphy_nop1>;
+ fsl,anatop = <&anatop>;
status = "disabled";
};
@@ -1004,6 +1135,9 @@
ahb-burst-config = <0x0>;
tx-burst-size-dword = <0x10>;
rx-burst-size-dword = <0x10>;
+ phy_type = "hsic";
+ fsl,usbphy = <&usbphy_nop2>;
+ fsl,anatop = <&anatop>;
status = "disabled";
};
@@ -1018,20 +1152,27 @@
compatible = "fsl,imx6q-fec";
reg = <0x02188000 0x4000>;
interrupts-extended =
- <&intc 0 118 IRQ_TYPE_LEVEL_HIGH>,
- <&intc 0 119 IRQ_TYPE_LEVEL_HIGH>;
+ <&gpc 0 118 IRQ_TYPE_LEVEL_HIGH>,
+ <&gpc 0 119 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clks IMX6QDL_CLK_ENET>,
<&clks IMX6QDL_CLK_ENET>,
<&clks IMX6QDL_CLK_ENET_REF>;
clock-names = "ipg", "ahb", "ptp";
+ stop-mode = <&gpr 0x34 27>;
+ fsl,wakeup_irq = <0>;
status = "disabled";
};
- mlb@0218c000 {
+ mlb: mlb@0218c000 {
+ compatible = "fsl,imx6q-mlb150";
reg = <0x0218c000 0x4000>;
interrupts = <0 53 IRQ_TYPE_LEVEL_HIGH>,
<0 117 IRQ_TYPE_LEVEL_HIGH>,
<0 126 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6QDL_CLK_MLB>;
+ clock-names = "mlb";
+ iram = <&ocram>;
+ status = "disabled";
};
usdhc1: usdhc@02190000 {
@@ -1116,6 +1257,11 @@
reg = <0x021ac000 0x4000>;
};
+ mmdc0-1@021b0000 { /* MMDC0-1 */
+ compatible = "fsl,imx6q-mmdc-combine";
+ reg = <0x021b0000 0x8000>;
+ };
+
mmdc0: mmdc@021b0000 { /* MMDC0 */
compatible = "fsl,imx6q-mmdc";
reg = <0x021b0000 0x4000>;
@@ -1158,20 +1304,25 @@
status = "disabled";
};
- mipi_csi: mipi@021dc000 {
- compatible = "fsl,imx6-mipi-csi2";
+ mipi_csi: mipi_csi@021dc000 { /* MIPI-CSI */
+ compatible = "fsl,imx6q-mipi-csi2";
reg = <0x021dc000 0x4000>;
#address-cells = <1>;
#size-cells = <0>;
interrupts = <0 100 0x04>, <0 101 0x04>;
clocks = <&clks IMX6QDL_CLK_HSI_TX>,
- <&clks IMX6QDL_CLK_VIDEO_27M>,
- <&clks IMX6QDL_CLK_EIM_PODF>;
- clock-names = "dphy", "ref", "pix";
+ <&clks IMX6QDL_CLK_EIM_SEL>,
+ <&clks IMX6QDL_CLK_VIDEO_27M>;
+ /* Note: clks 138 is hsi_tx, however, the dphy_c
+ * hsi_tx and pll_refclk use the same clk gate.
+ * In current clk driver, open/close clk gate do
+ * use hsi_tx for a temporary debug purpose.
+ */
+ clock-names = "dphy_clk", "pixel_clk", "cfg_clk";
status = "disabled";
};
- mipi_dsi: mipi@021e0000 {
+ mipi_dsi: mipi@021e0000 { /* MIPI-DSI */
#address-cells = <1>;
#size-cells = <0>;
reg = <0x021e0000 0x4000>;
@@ -1204,6 +1355,7 @@
reg = <0x021e4000 0x4000>;
interrupts = <0 18 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clks IMX6QDL_CLK_VDOA>;
+ iram = <&ocram>;
};
uart2: serial@021e8000 {
@@ -1263,10 +1415,15 @@
interrupts = <0 6 IRQ_TYPE_LEVEL_HIGH>,
<0 5 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clks IMX6QDL_CLK_IPU1>,
- <&clks IMX6QDL_CLK_IPU1_DI0>,
- <&clks IMX6QDL_CLK_IPU1_DI1>;
- clock-names = "bus", "di0", "di1";
+ <&clks IMX6QDL_CLK_IPU1_DI0>, <&clks IMX6QDL_CLK_IPU1_DI1>,
+ <&clks IMX6QDL_CLK_IPU1_DI0_SEL>, <&clks IMX6QDL_CLK_IPU1_DI1_SEL>,
+ <&clks IMX6QDL_CLK_LDB_DI0>, <&clks IMX6QDL_CLK_LDB_DI1>;
+ clock-names = "bus",
+ "di0", "di1",
+ "di0_sel", "di1_sel",
+ "ldb_di0", "ldb_di1";
resets = <&src 2>;
+ bypass_reset = <0>;
ipu1_csi0: port@0 {
reg = <0>;
diff --git a/arch/arm/boot/dts/imx6qp-sabreauto-ecspi.dts b/arch/arm/boot/dts/imx6qp-sabreauto-ecspi.dts
new file mode 100644
index 000000000000..8846739a5558
--- /dev/null
+++ b/arch/arm/boot/dts/imx6qp-sabreauto-ecspi.dts
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2015 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 "imx6qp-sabreauto.dts"
+
+&ecspi1 {
+ pinctrl-assert-gpios = <&gpio5 4 GPIO_ACTIVE_LOW>;
+ status = "okay";
+};
+
+&can2 {
+ /* max7310_c on i2c3 is gone */
+ status = "disabled";
+};
+
+&i2c3 {
+ /* pin conflict with ecspi1 */
+ status = "disabled";
+};
+
+&uart3 {
+ /* the uart3 depends on the i2c3, so disable it too. */
+ status = "disabled";
+};
+
+&usbh1 {
+ /* max7310_b on i2c3 is gone */
+ status = "disabled";
+};
+
+&usbotg {
+ /* max7310_c on i2c3 is gone */
+ status = "okay";
+ dr_mode = "peripheral";
+};
diff --git a/arch/arm/boot/dts/imx6qp-sabreauto-flexcan1.dts b/arch/arm/boot/dts/imx6qp-sabreauto-flexcan1.dts
new file mode 100644
index 000000000000..b57607b0c222
--- /dev/null
+++ b/arch/arm/boot/dts/imx6qp-sabreauto-flexcan1.dts
@@ -0,0 +1,18 @@
+/*
+ * Copyright (C) 2015 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 "imx6qp-sabreauto.dts"
+
+&can1{
+ status = "okay";
+};
+
+&fec {
+ /* pin conflict with flexcan1 */
+ status = "disabled";
+};
diff --git a/arch/arm/boot/dts/imx6qp-sabreauto-gpmi-weim.dts b/arch/arm/boot/dts/imx6qp-sabreauto-gpmi-weim.dts
new file mode 100644
index 000000000000..b91ebad61116
--- /dev/null
+++ b/arch/arm/boot/dts/imx6qp-sabreauto-gpmi-weim.dts
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2015 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 "imx6qp-sabreauto.dts"
+
+&ecspi1 {
+ /* pin conflict with weim */
+ status = "disabled";
+};
+
+&can2 {
+ /* max7310_c on i2c3 is gone */
+ status = "disabled";
+};
+
+&gpmi {
+ compatible = "fsl,imx6qp-gpmi-nand";
+ status = "okay";
+};
+
+&i2c3 {
+ /* pin conflict with weim */
+ status = "disabled";
+};
+
+&uart3 {
+ /* pin conflict with gpmi and weim */
+ status = "disabled";
+};
+
+&usbh1 {
+ /* max7310_b on i2c3 is gone */
+ status = "disabled";
+};
+
+&usbotg {
+ /* max7310_c on i2c3 is gone */
+ status = "okay";
+ dr_mode = "peripheral";
+};
+
+&weim {
+ pinctrl-assert-gpios = <&gpio5 4 GPIO_ACTIVE_LOW>;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx6qp-sabreauto.dts b/arch/arm/boot/dts/imx6qp-sabreauto.dts
index 5ce3840d83d3..59778f046cce 100644
--- a/arch/arm/boot/dts/imx6qp-sabreauto.dts
+++ b/arch/arm/boot/dts/imx6qp-sabreauto.dts
@@ -50,6 +50,40 @@
compatible = "fsl,imx6qp-sabreauto", "fsl,imx6qp";
};
+&ldb {
+ lvds-channel@0 {
+ crtc = "ipu2-di0";
+ };
+
+ lvds-channel@1 {
+ crtc = "ipu2-di1";
+ };
+};
+
+&mxcfb1 {
+ prefetch;
+ status = "okay";
+};
+
+&mxcfb2 {
+ prefetch;
+ status = "okay";
+};
+
+&mxcfb3 {
+ prefetch;
+ status = "okay";
+};
+
+&mxcfb4 {
+ prefetch;
+ status = "okay";
+};
+
+&fec {
+ pinctrl-assert-gpios = <&max7322 0 GPIO_ACTIVE_HIGH>;
+};
+
&i2c2 {
max7322: gpio@68 {
compatible = "maxim,max7322";
@@ -59,33 +93,47 @@
};
};
-&iomuxc {
- imx6qdl-sabreauto {
- pinctrl_enet: enetgrp {
- fsl,pins = <
- MX6QDL_PAD_KEY_COL1__ENET_MDIO 0x1b0b0
- MX6QDL_PAD_KEY_COL2__ENET_MDC 0x1b0b0
- MX6QDL_PAD_RGMII_TXC__RGMII_TXC 0x1b018
- MX6QDL_PAD_RGMII_TD0__RGMII_TD0 0x1b018
- MX6QDL_PAD_RGMII_TD1__RGMII_TD1 0x1b018
- MX6QDL_PAD_RGMII_TD2__RGMII_TD2 0x1b018
- MX6QDL_PAD_RGMII_TD3__RGMII_TD3 0x1b018
- MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x1b018
- MX6QDL_PAD_RGMII_RXC__RGMII_RXC 0x1b018
- MX6QDL_PAD_RGMII_RD0__RGMII_RD0 0x1b018
- MX6QDL_PAD_RGMII_RD1__RGMII_RD1 0x1b018
- MX6QDL_PAD_RGMII_RD2__RGMII_RD2 0x1b018
- MX6QDL_PAD_RGMII_RD3__RGMII_RD3 0x1b018
- MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x1b018
- MX6QDL_PAD_GPIO_16__ENET_REF_CLK 0x4001b0a8
- MX6QDL_PAD_GPIO_6__ENET_IRQ 0x000b1
- >;
- };
- };
+&pcie {
+ reset-gpio = <&max7310_c 5 GPIO_ACTIVE_LOW>;
+ status = "okay";
};
-&pcie {
- status = "disabled";
+&pre1 {
+ status = "okay";
+};
+
+&pre2 {
+ status = "okay";
+};
+
+&pre3 {
+ status = "okay";
+};
+
+&pre4 {
+ status = "okay";
+};
+
+&prg1 {
+ memory-region = <&memory>;
+ status = "okay";
+};
+
+&prg2 {
+ memory-region = <&memory>;
+ status = "okay";
+};
+
+&reg_sd3_vmmc {
+ status = "okay";
+};
+
+&sata {
+ status = "okay";
+};
+
+&usdhc3 {
+ vmmc-supply = <&reg_sd3_vmmc>;
};
&vgen3_reg {
diff --git a/arch/arm/boot/dts/imx6qp-sabresd-btwifi.dts b/arch/arm/boot/dts/imx6qp-sabresd-btwifi.dts
new file mode 100644
index 000000000000..38d39cab570c
--- /dev/null
+++ b/arch/arm/boot/dts/imx6qp-sabresd-btwifi.dts
@@ -0,0 +1,10 @@
+/*
+ * Copyright (C) 2015 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 "imx6qp-sabresd.dts"
+#include "imx6qdl-sabresd-btwifi.dtsi"
diff --git a/arch/arm/boot/dts/imx6qp-sabresd-hdcp.dts b/arch/arm/boot/dts/imx6qp-sabresd-hdcp.dts
new file mode 100644
index 000000000000..e19ff136c226
--- /dev/null
+++ b/arch/arm/boot/dts/imx6qp-sabresd-hdcp.dts
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2015 Freescale Semiconductor, Inc.
+ *
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include "imx6qp-sabresd.dts"
+
+&gpc {
+ /* use ldo-enable, u-boot will check it and configure */
+ fsl,ldo-bypass = <0>;
+};
+
+&hdmi_video {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_hdmi_hdcp>;
+ fsl,hdcp;
+};
+
+&i2c2 {
+ status = "disable";
+};
+
+&reg_arm {
+ /delete-property/ vin-supply;
+};
+
+&reg_pu {
+ /delete-property/ vin-supply;
+};
+
+&reg_soc {
+ /delete-property/ vin-supply;
+};
diff --git a/arch/arm/boot/dts/imx6qp-sabresd-ldo-pcie-cert.dts b/arch/arm/boot/dts/imx6qp-sabresd-ldo-pcie-cert.dts
new file mode 100644
index 000000000000..da6b11773680
--- /dev/null
+++ b/arch/arm/boot/dts/imx6qp-sabresd-ldo-pcie-cert.dts
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2016 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 "imx6qp-sabresd-ldo.dts"
+
+&fec {
+ status = "disabled";
+};
+
+&pcie {
+ ext_osc = <1>;
+};
+
+&sata {
+ status = "disabled";
+};
diff --git a/arch/arm/boot/dts/imx6qp-sabresd-ldo.dts b/arch/arm/boot/dts/imx6qp-sabresd-ldo.dts
new file mode 100644
index 000000000000..f33eb65a793e
--- /dev/null
+++ b/arch/arm/boot/dts/imx6qp-sabresd-ldo.dts
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2015 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 "imx6qp-sabresd.dts"
+
+&wdog1 {
+ status = "okay";
+};
+
+&wdog2 {
+ status = "disabled";
+};
+
+&gpc {
+ /* use ldo-enable, u-boot will check it and configure */
+ fsl,ldo-bypass = <0>;
+};
+
+&reg_arm {
+ /delete-property/ vin-supply;
+};
+
+&reg_pu {
+ /delete-property/ vin-supply;
+};
+
+&reg_soc {
+ /delete-property/ vin-supply;
+};
+
+&wdog1 {
+ status = "okay";
+};
+
+&wdog2 {
+ status = "disabled";
+};
diff --git a/arch/arm/boot/dts/imx6qp-sabresd.dts b/arch/arm/boot/dts/imx6qp-sabresd.dts
index a8a5004dd9c8..59636a0bad9f 100644
--- a/arch/arm/boot/dts/imx6qp-sabresd.dts
+++ b/arch/arm/boot/dts/imx6qp-sabresd.dts
@@ -88,6 +88,112 @@
};
};
+&iomuxc {
+ imx6qdl-sabresd {
+ pinctrl_usdhc2: usdhc2grp {
+ fsl,pins = <
+ MX6QDL_PAD_SD2_CMD__SD2_CMD 0x17059
+ MX6QDL_PAD_SD2_CLK__SD2_CLK 0x10071
+ MX6QDL_PAD_SD2_DAT0__SD2_DATA0 0x17059
+ MX6QDL_PAD_SD2_DAT1__SD2_DATA1 0x17059
+ MX6QDL_PAD_SD2_DAT2__SD2_DATA2 0x17059
+ MX6QDL_PAD_SD2_DAT3__SD2_DATA3 0x17059
+ MX6QDL_PAD_NANDF_D4__SD2_DATA4 0x17059
+ MX6QDL_PAD_NANDF_D5__SD2_DATA5 0x17059
+ MX6QDL_PAD_NANDF_D6__SD2_DATA6 0x17059
+ MX6QDL_PAD_NANDF_D7__SD2_DATA7 0x17059
+ >;
+ };
+
+ pinctrl_usdhc3: usdhc3grp {
+ fsl,pins = <
+ MX6QDL_PAD_SD3_CMD__SD3_CMD 0x17059
+ MX6QDL_PAD_SD3_CLK__SD3_CLK 0x10071
+ 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
+ MX6QDL_PAD_SD3_DAT4__SD3_DATA4 0x17059
+ MX6QDL_PAD_SD3_DAT5__SD3_DATA5 0x17059
+ MX6QDL_PAD_SD3_DAT6__SD3_DATA6 0x17059
+ MX6QDL_PAD_SD3_DAT7__SD3_DATA7 0x17059
+ >;
+ };
+ };
+};
+
+&ldb {
+ lvds-channel@0 {
+ crtc = "ipu2-di0";
+ };
+
+ lvds-channel@1 {
+ crtc = "ipu2-di1";
+ };
+};
+
+&mxcfb1 {
+ prefetch;
+ status = "okay";
+};
+
+&mxcfb2 {
+ prefetch;
+ status = "okay";
+};
+
+&mxcfb3 {
+ prefetch;
+ status = "okay";
+};
+
+&mxcfb4 {
+ prefetch;
+ status = "okay";
+};
+
+&ov564x {
+ AVDD-supply = <&vgen6_reg>; /* 2.8v */
+ DOVDD-supply = <&sw4_reg>; /* 1.8v */
+};
+
+&ov564x_mipi {
+ AVDD-supply = <&vgen6_reg>; /* 2.8v */
+ DOVDD-supply = <&sw4_reg>; /* 1.8v */
+};
+
&pcie {
- status = "disabled";
+ pcie-bus-supply = <&vgen3_reg>; /* 1.8v pwr up pcie ext osc on revb */
+ reset-gpio = <&gpio7 12 0>;
+ status = "okay";
+};
+
+&pre1 {
+ status = "okay";
+};
+
+&pre2 {
+ status = "okay";
+};
+
+&pre3 {
+ status = "okay";
+};
+
+&pre4 {
+ status = "okay";
+};
+
+&prg1 {
+ memory-region = <&memory>;
+ status = "okay";
+};
+
+&prg2 {
+ memory-region = <&memory>;
+ status = "okay";
+};
+
+&sata {
+ status = "okay";
};
diff --git a/arch/arm/boot/dts/imx6qp.dtsi b/arch/arm/boot/dts/imx6qp.dtsi
index 299d863690c5..cc98c4be4dc1 100644
--- a/arch/arm/boot/dts/imx6qp.dtsi
+++ b/arch/arm/boot/dts/imx6qp.dtsi
@@ -43,6 +43,15 @@
#include "imx6q.dtsi"
/ {
+ aliases {
+ pre0 = &pre1;
+ pre1 = &pre2;
+ pre2 = &pre3;
+ pre3 = &pre4;
+ prg0 = &prg1;
+ prg1 = &prg2;
+ };
+
soc {
ocram2: sram@00940000 {
compatible = "mmio-sram";
@@ -56,61 +65,115 @@
clocks = <&clks IMX6QDL_CLK_OCRAM>;
};
- aips-bus@02100000 {
- pre1: pre@21c8000 {
- compatible = "fsl,imx6qp-pre";
+ pcie: pcie@1ffc000 {
+ compatible = "fsl,imx6qp-pcie", "snps,dw-pcie";
+ reg = <0x01ffc000 0x4000>, <0x01f00000 0x80000>;
+ reg-names = "dbi", "config";
+ #address-cells = <3>;
+ #size-cells = <2>;
+ device_type = "pci";
+ bus-range = <0x00 0xff>;
+ ranges = <0x81000000 0 0 0x01f80000 0 0x00010000 /* downstream I/O */
+ 0x82000000 0 0x01000000 0x01000000 0 0x00f00000>; /* non-prefetchable memory */
+ num-lanes = <1>;
+ interrupts = <0 120 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "msi";
+ #interrupt-cells = <1>;
+ interrupt-map-mask = <0 0 0 0x7>;
+ interrupt-map = <0 0 0 1 &intc 0 123 IRQ_TYPE_LEVEL_HIGH>,
+ <0 0 0 2 &intc 0 122 IRQ_TYPE_LEVEL_HIGH>,
+ <0 0 0 3 &intc 0 121 IRQ_TYPE_LEVEL_HIGH>,
+ <0 0 0 4 &intc 0 120 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6QDL_CLK_PCIE_REF_125M>, <&clks IMX6QDL_PLL6_BYPASS>,
+ <&clks IMX6QDL_PLL6_BYPASS_SRC>,
+ <&clks IMX6QDL_CLK_LVDS1_GATE>, <&clks IMX6QDL_CLK_PCIE_AXI>;
+ clock-names = "pcie_phy", "pcie_ext", "pcie_ext_src", "pcie_bus", "pcie";
+ status = "disabled";
+ };
+
+ aips-bus@02100000 { /* AIPS2 */
+ pre1: pre@021c8000 {
+ compatible = "fsl,imx6q-pre";
reg = <0x021c8000 0x1000>;
- interrupts = <GIC_SPI 90 IRQ_TYPE_EDGE_RISING>;
clocks = <&clks IMX6QDL_CLK_PRE0>;
- clock-names = "axi";
- fsl,iram = <&ocram2>;
+ interrupts = <0 90 IRQ_TYPE_EDGE_RISING>;
+ ocram = <&ocram2>;
+ status = "disabled";
};
- pre2: pre@21c9000 {
- compatible = "fsl,imx6qp-pre";
+ pre2: pre@021c9000 {
+ compatible = "fsl,imx6q-pre";
reg = <0x021c9000 0x1000>;
- interrupts = <GIC_SPI 97 IRQ_TYPE_EDGE_RISING>;
clocks = <&clks IMX6QDL_CLK_PRE1>;
- clock-names = "axi";
- fsl,iram = <&ocram2>;
+ interrupts = <0 97 IRQ_TYPE_EDGE_RISING>;
+ ocram = <&ocram2>;
+ status = "disabled";
};
- pre3: pre@21ca000 {
- compatible = "fsl,imx6qp-pre";
+ pre3: pre@021ca000 {
+ compatible = "fsl,imx6q-pre";
reg = <0x021ca000 0x1000>;
- interrupts = <GIC_SPI 98 IRQ_TYPE_EDGE_RISING>;
clocks = <&clks IMX6QDL_CLK_PRE2>;
- clock-names = "axi";
- fsl,iram = <&ocram3>;
+ interrupts = <0 98 IRQ_TYPE_EDGE_RISING>;
+ ocram = <&ocram3>;
+ status = "disabled";
};
- pre4: pre@21cb000 {
- compatible = "fsl,imx6qp-pre";
+ pre4: pre@021cb000 {
+ compatible = "fsl,imx6q-pre";
reg = <0x021cb000 0x1000>;
- interrupts = <GIC_SPI 99 IRQ_TYPE_EDGE_RISING>;
clocks = <&clks IMX6QDL_CLK_PRE3>;
- clock-names = "axi";
- fsl,iram = <&ocram3>;
+ interrupts = <0 99 IRQ_TYPE_EDGE_RISING>;
+ ocram = <&ocram3>;
+ status = "disabled";
};
- prg1: prg@21cc000 {
- compatible = "fsl,imx6qp-prg";
+ prg1: prg@021cc000 {
+ compatible = "fsl,imx6q-prg";
reg = <0x021cc000 0x1000>;
- clocks = <&clks IMX6QDL_CLK_PRG0_APB>,
- <&clks IMX6QDL_CLK_PRG0_AXI>;
- clock-names = "ipg", "axi";
- fsl,pres = <&pre1>, <&pre2>, <&pre3>;
+ clocks = <&clks IMX6QDL_CLK_PRG0_AXI>,
+ <&clks IMX6QDL_CLK_PRG0_APB>;
+ clock-names = "axi", "apb";
+ gpr = <&gpr>;
+ status = "disabled";
};
- prg2: prg@21cd000 {
- compatible = "fsl,imx6qp-prg";
+ prg2: prg@021cd000 {
+ compatible = "fsl,imx6q-prg";
reg = <0x021cd000 0x1000>;
- clocks = <&clks IMX6QDL_CLK_PRG1_APB>,
- <&clks IMX6QDL_CLK_PRG1_AXI>;
- clock-names = "ipg", "axi";
- fsl,pres = <&pre4>, <&pre2>, <&pre3>;
+ clocks = <&clks IMX6QDL_CLK_PRG1_AXI>,
+ <&clks IMX6QDL_CLK_PRG1_APB>;
+ clock-names = "axi", "apb";
+ gpr = <&gpr>;
+ status = "disabled";
};
};
+
+ ipu1: ipu@02400000 {
+ compatible = "fsl,imx6qp-ipu", "fsl,imx6q-ipu";
+ clocks = <&clks IMX6QDL_CLK_IPU1>,
+ <&clks IMX6QDL_CLK_IPU1_DI0>, <&clks IMX6QDL_CLK_IPU1_DI1>,
+ <&clks IMX6QDL_CLK_IPU1_DI0_SEL>, <&clks IMX6QDL_CLK_IPU1_DI1_SEL>,
+ <&clks IMX6QDL_CLK_LDB_DI0_DIV_SEL>, <&clks IMX6QDL_CLK_LDB_DI1_DIV_SEL>,
+ <&clks IMX6QDL_CLK_PRG0_APB>;
+ clock-names = "bus",
+ "di0", "di1",
+ "di0_sel", "di1_sel",
+ "ldb_di0", "ldb_di1", "prg";
+ };
+
+ ipu2: ipu@02800000 {
+ compatible = "fsl,imx6qp-ipu", "fsl,imx6q-ipu";
+ clocks = <&clks IMX6QDL_CLK_IPU2>,
+ <&clks IMX6QDL_CLK_IPU2_DI0>, <&clks IMX6QDL_CLK_IPU2_DI1>,
+ <&clks IMX6QDL_CLK_IPU2_DI0_SEL>, <&clks IMX6QDL_CLK_IPU2_DI1_SEL>,
+ <&clks IMX6QDL_CLK_LDB_DI0_DIV_SEL>, <&clks IMX6QDL_CLK_LDB_DI1_DIV_SEL>,
+ <&clks IMX6QDL_CLK_PRG1_APB>;
+ clock-names = "bus",
+ "di0", "di1",
+ "di0_sel", "di1_sel",
+ "ldb_di0", "ldb_di1", "prg";
+ };
};
};
@@ -135,13 +198,7 @@
};
&ldb {
- clocks = <&clks IMX6QDL_CLK_LDB_DI0_SEL>, <&clks IMX6QDL_CLK_LDB_DI1_SEL>,
- <&clks IMX6QDL_CLK_IPU1_DI0_SEL>, <&clks IMX6QDL_CLK_IPU1_DI1_SEL>,
- <&clks IMX6QDL_CLK_IPU2_DI0_SEL>, <&clks IMX6QDL_CLK_IPU2_DI1_SEL>,
- <&clks IMX6QDL_CLK_LDB_DI0_PODF>, <&clks IMX6QDL_CLK_LDB_DI1_PODF>;
- clock-names = "di0_pll", "di1_pll",
- "di0_sel", "di1_sel", "di2_sel", "di3_sel",
- "di0", "di1";
+ compatible = "fsl,imx6qp-ldb", "fsl,imx6q-ldb", "fsl,imx53-ldb";
};
&mmdc0 {
diff --git a/arch/arm/boot/dts/imx6sl-evk-btwifi.dts b/arch/arm/boot/dts/imx6sl-evk-btwifi.dts
new file mode 100644
index 000000000000..6eb8b4f913ac
--- /dev/null
+++ b/arch/arm/boot/dts/imx6sl-evk-btwifi.dts
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2015 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.
+ */
+
+/* NOTE: This DTS file is written for plugging in Murata Wi-Fi/BT EVK into SD1
+ * slot using Murata i.MX InterConnect Ver 1.0 Adapter AND wiring in control
+ * signals with SD Card Extender on SD3 slot.
+ * Bluetooth UART connect via SD1 EMMC/MMC Plus pinout.
+ * WL_REG_ON/BT_REG_ON/WL_HOST_WAKE are connected from SD Card Extender on SD3
+ * slot.
+ */
+#include "imx6sl-evk.dts"
+
+/ {
+ modem_reset: modem-reset {
+ compatible = "gpio-reset";
+ reset-gpios = <&gpio5 17 GPIO_ACTIVE_LOW>;
+ reset-delay-us = <1000>;
+ #reset-cells = <0>;
+ };
+
+ usdhc1_pwrseq: usdhc1_pwrseq {
+ compatible = "mmc-pwrseq-simple";
+ reset-gpios = <&gpio5 16 GPIO_ACTIVE_LOW>;
+ };
+};
+
+&iomuxc {
+ imx6sl-evk-murata-v1_sdext {
+ /* Only MUX SD1_DAT0..3 lines so UART4 can be MUXed on higher data lines. */
+ pinctrl_btreg: btreggrp {
+ fsl,pins = <
+ MX6SL_PAD_SD3_DAT3__GPIO5_IO17 0x13069 /* BT_REG_ON */
+ >;
+ };
+
+ pinctrl_wifi: wifigrp {
+ fsl,pins = <
+ MX6SL_PAD_SD1_CMD__SD1_CMD 0x17059
+ MX6SL_PAD_SD1_CLK__SD1_CLK 0x10059
+ MX6SL_PAD_SD1_DAT0__SD1_DATA0 0x17059
+ MX6SL_PAD_SD1_DAT1__SD1_DATA1 0x17059
+ MX6SL_PAD_SD1_DAT2__SD1_DATA2 0x17059
+ MX6SL_PAD_SD1_DAT3__SD1_DATA3 0x17059
+ MX6SL_PAD_SD3_DAT1__GPIO5_IO20 0x13069 /* WL_HOST_WAKE */
+ MX6SL_PAD_SD3_DAT2__GPIO5_IO16 0x13069 /* WL_REG_ON */
+ >;
+ };
+
+ pinctrl_usdhc3_1: usdhc3grp-1 {
+ fsl,pins = <
+ MX6SL_PAD_SD3_CMD__SD3_CMD 0x17059
+ MX6SL_PAD_SD3_CLK__SD3_CLK 0x10059
+ MX6SL_PAD_SD3_DAT0__SD3_DATA0 0x17059
+ >;
+ };
+ };
+};
+/* Murata: declare UART4 interface for Bluetooth. */
+&uart4 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart4_1
+ &pinctrl_btreg>;
+ fsl,uart-has-rtscts;
+ resets = <&modem_reset>;
+ status = "okay";
+ /* for DTE mode, add below change */
+ /* fsl,dte-mode; */
+ /* pinctrl-0 = <&pinctrl_uart4dte_1>; */
+};
+
+&usdhc1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_wifi>;
+ bus-width = <4>;
+ no-1-8-v;
+ non-removable;
+ mmc-pwrseq = <&usdhc1_pwrseq>;
+ pm-ignore-notify;
+ cap-power-off-card;
+
+ brcmf: bcrmf@1 {
+ reg = <1>;
+ compatible = "brcm,bcm4329-fmac";
+ };
+};
+
+&usdhc3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usdhc3_1>;
+ bus-width = <1>;
+ no-1-8-v;
+};
diff --git a/arch/arm/boot/dts/imx6sl-evk-csi.dts b/arch/arm/boot/dts/imx6sl-evk-csi.dts
new file mode 100644
index 000000000000..56d824b60e41
--- /dev/null
+++ b/arch/arm/boot/dts/imx6sl-evk-csi.dts
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2013 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 "imx6sl-evk.dts"
+
+&csi {
+ status = "okay";
+};
+
+&i2c3 {
+ status = "okay";
+};
+
+&epdc {
+ status = "disabled";
+};
diff --git a/arch/arm/boot/dts/imx6sl-evk-ldo.dts b/arch/arm/boot/dts/imx6sl-evk-ldo.dts
new file mode 100644
index 000000000000..5ca3a09df2b9
--- /dev/null
+++ b/arch/arm/boot/dts/imx6sl-evk-ldo.dts
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2015 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 "imx6sl-evk.dts"
+
+&gpc {
+ /* use ldo-enable, u-boot will check it and configure */
+ fsl,ldo-bypass = <0>;
+};
+
+&reg_arm {
+ /delete-property/ vin-supply;
+};
+
+&reg_pu {
+ /delete-property/ vin-supply;
+};
+
+&reg_soc {
+ /delete-property/ vin-supply;
+};
diff --git a/arch/arm/boot/dts/imx6sl-evk-uart.dts b/arch/arm/boot/dts/imx6sl-evk-uart.dts
new file mode 100644
index 000000000000..6179842731a7
--- /dev/null
+++ b/arch/arm/boot/dts/imx6sl-evk-uart.dts
@@ -0,0 +1,23 @@
+/*
+ * 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 "imx6sl-evk.dts"
+
+&uart4 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart4_1>;
+ fsl,uart-has-rtscts;
+ status = "okay";
+ /* for DTE mode, add below change */
+ /* fsl,dte-mode; */
+ /* pinctrl-0 = <&pinctrl_uart4dte_1>; */
+};
+
+&usdhc1 {
+ status = "disabled";
+};
diff --git a/arch/arm/boot/dts/imx6sl-evk.dts b/arch/arm/boot/dts/imx6sl-evk.dts
index 0a90eea17018..0a2d24f251f2 100644
--- a/arch/arm/boot/dts/imx6sl-evk.dts
+++ b/arch/arm/boot/dts/imx6sl-evk.dts
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2013 Freescale Semiconductor, Inc.
+ * Copyright 2017 NXP.
*
* 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
@@ -16,6 +17,23 @@
model = "Freescale i.MX6 SoloLite EVK Board";
compatible = "fsl,imx6sl-evk", "fsl,imx6sl";
+ battery: max8903@0 {
+ compatible = "fsl,max8903-charger";
+ pinctrl-names = "default";
+ dok_input = <&gpio4 13 1>;
+ uok_input = <&gpio4 13 1>;
+ chg_input = <&gpio4 15 1>;
+ flt_input = <&gpio4 14 1>;
+ fsl,dcm_always_high;
+ fsl,dc_valid;
+ fsl,adc_disable;
+ status = "okay";
+ };
+
+ chosen {
+ stdout-path = &uart1;
+ };
+
memory {
reg = <0x80000000 0x40000000>;
};
@@ -39,6 +57,11 @@
};
};
+ pxp_v4l2_out {
+ compatible = "fsl,imx6sl-pxp-v4l2";
+ status = "okay";
+ };
+
regulators {
compatible = "simple-bus";
#address-cells = <1>;
@@ -96,7 +119,7 @@
sound {
compatible = "fsl,imx6sl-evk-wm8962", "fsl,imx-audio-wm8962";
model = "wm8962-audio";
- ssi-controller = <&ssi2>;
+ cpu-dai = <&ssi2>;
audio-codec = <&codec>;
audio-routing =
"Headphone Jack", "HPOUTL",
@@ -107,6 +130,23 @@
"IN3R", "AMIC";
mux-int-port = <2>;
mux-ext-port = <3>;
+ codec-master;
+ hp-det-gpios = <&gpio4 19 1>;
+ };
+
+ sound-spdif {
+ compatible = "fsl,imx-audio-spdif",
+ "fsl,imx6sl-evk-spdif";
+ model = "imx-spdif";
+ spdif-controller = <&spdif>;
+ spdif-out;
+ };
+
+ sii902x_reset: sii902x-reset {
+ compatible = "gpio-reset";
+ reset-gpios = <&gpio2 19 1>;
+ reset-delay-us = <100000>;
+ #reset-cells = <0>;
};
};
@@ -116,6 +156,29 @@
status = "okay";
};
+&reg_arm {
+ vin-supply = <&sw1a_reg>;
+ regulator-allow-bypass;
+};
+
+&reg_soc {
+ vin-supply = <&sw1c_reg>;
+ regulator-allow-bypass;
+};
+
+&reg_pu {
+ vin-supply = <&sw1c_reg>;
+ regulator-allow-bypass;
+};
+
+&csi {
+ port {
+ csi_ep: endpoint {
+ remote-endpoint = <&ov5640_ep>;
+ };
+ };
+};
+
&ecspi1 {
cs-gpios = <&gpio4 11 0>;
pinctrl-names = "default";
@@ -131,6 +194,15 @@
};
};
+&epdc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_epdc_0>;
+ V3P3-supply = <&V3P3_reg>;
+ VCOM-supply = <&VCOM_reg>;
+ DISPLAY-supply = <&DISPLAY_reg>;
+ status = "okay";
+};
+
&fec {
pinctrl-names = "default", "sleep";
pinctrl-0 = <&pinctrl_fec>;
@@ -139,6 +211,10 @@
status = "okay";
};
+&gpc {
+ fsl,ldo-bypass = <1>;
+};
+
&i2c1 {
clock-frequency = <100000>;
pinctrl-names = "default";
@@ -190,6 +266,7 @@
sw4_reg: sw4 {
regulator-min-microvolt = <800000>;
regulator-max-microvolt = <3300000>;
+ regulator-always-on;
};
swbst_reg: swbst {
@@ -244,6 +321,89 @@
};
};
};
+
+ elan@10 {
+ compatible = "elan,elan-touch";
+ reg = <0x10>;
+ interrupt-parent = <&gpio2>;
+ interrupts = <10 2>;
+ gpio_elan_cs = <&gpio2 9 0>;
+ gpio_elan_rst = <&gpio4 4 0>;
+ gpio_intr = <&gpio2 10 0>;
+ status = "okay";
+ };
+
+ mma8450@1c {
+ compatible = "fsl,mma8450";
+ reg = <0x1c>;
+ };
+
+ max17135@48 {
+ compatible = "maxim,max17135";
+ reg = <0x48>;
+ vneg_pwrup = <1>;
+ gvee_pwrup = <2>;
+ vpos_pwrup = <10>;
+ gvdd_pwrup = <12>;
+ gvdd_pwrdn = <1>;
+ vpos_pwrdn = <2>;
+ gvee_pwrdn = <8>;
+ vneg_pwrdn = <10>;
+ gpio_pmic_pwrgood = <&gpio2 13 0>;
+ gpio_pmic_vcom_ctrl = <&gpio2 3 0>;
+ gpio_pmic_wakeup = <&gpio2 14 0>;
+ gpio_pmic_v3p3 = <&gpio2 7 0>;
+ gpio_pmic_intr = <&gpio2 12 0>;
+
+ regulators {
+ DISPLAY_reg: DISPLAY {
+ regulator-name = "DISPLAY";
+ };
+
+ GVDD_reg: GVDD {
+ /* 20v */
+ regulator-name = "GVDD";
+ };
+
+ GVEE_reg: GVEE {
+ /* -22v */
+ regulator-name = "GVEE";
+ };
+
+ HVINN_reg: HVINN {
+ /* -22v */
+ regulator-name = "HVINN";
+ };
+
+ HVINP_reg: HVINP {
+ /* 20v */
+ regulator-name = "HVINP";
+ };
+
+ VCOM_reg: VCOM {
+ regulator-name = "VCOM";
+ /* Real max value: -500000 */
+ regulator-max-microvolt = <4325000>;
+ /* Real min value: -4325000 */
+ regulator-min-microvolt = <500000>;
+ };
+
+ VNEG_reg: VNEG {
+ /* -15v */
+ regulator-name = "VNEG";
+ };
+
+ VPOS_reg: VPOS {
+ /* 15v */
+ regulator-name = "VPOS";
+ };
+
+ V3P3_reg: V3P3 {
+ regulator-name = "V3P3";
+ };
+ };
+ };
+
};
&i2c2 {
@@ -264,6 +424,45 @@
PLLVDD-supply = <&vgen3_reg>;
SPKVDD1-supply = <&reg_aud4v>;
SPKVDD2-supply = <&reg_aud4v>;
+ amic-mono;
+ };
+
+ sii902x@39 {
+ compatible = "SiI,sii902x";
+ interrupt-parent = <&gpio2>;
+ interrupts = <10 2>;
+ mode_str ="1280x720M@60";
+ bits-per-pixel = <16>;
+ resets = <&sii902x_reset>;
+ reg = <0x39>;
+ };
+};
+
+&i2c3 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c3>;
+ status = "disabled";
+
+ ov5640: ov5640@3c {
+ compatible = "ovti,ov5640";
+ reg = <0x3c>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_csi_0>;
+ clocks = <&clks IMX6SL_CLK_CSI>;
+ clock-names = "csi_mclk";
+ AVDD-supply = <&vgen6_reg>; /* 2.8v */
+ DVDD-supply = <&vgen2_reg>; /* 1.5v*/
+ pwn-gpios = <&gpio1 25 1>;
+ rst-gpios = <&gpio1 26 0>;
+ csi_id = <0>;
+ mclk = <24000000>;
+ mclk_source = <0>;
+ port {
+ ov5640_ep: endpoint {
+ remote-endpoint = <&csi_ep>;
+ };
+ };
};
};
@@ -282,6 +481,17 @@
MX6SL_PAD_KEY_COL4__GPIO4_IO00 0x80000000
MX6SL_PAD_KEY_COL5__GPIO4_IO02 0x80000000
MX6SL_PAD_AUD_MCLK__AUDIO_CLK_OUT 0x4130b0
+ MX6SL_PAD_ECSPI2_MISO__GPIO4_IO14 0x17000
+ MX6SL_PAD_ECSPI2_MOSI__GPIO4_IO13 0x17000
+ MX6SL_PAD_ECSPI2_SS0__GPIO4_IO15 0x17000
+ MX6SL_PAD_FEC_RX_ER__GPIO4_IO19 0x1b0b0
+ MX6SL_PAD_EPDC_PWRCTRL3__GPIO2_IO10 0x17000
+ MX6SL_PAD_EPDC_PWRCTRL2__GPIO2_IO09 0x80000000
+ MX6SL_PAD_KEY_COL6__GPIO4_IO04 0x110b0
+ MX6SL_PAD_LCD_RESET__GPIO2_IO19 0x1b0b0
+ MX6SL_PAD_ECSPI2_MISO__GPIO4_IO14 0x17000
+ MX6SL_PAD_ECSPI2_MOSI__GPIO4_IO13 0x17000
+ MX6SL_PAD_ECSPI2_SS0__GPIO4_IO15 0x17000
>;
};
@@ -303,6 +513,39 @@
>;
};
+ pinctrl_epdc_0: epdcgrp-0 {
+ fsl,pins = <
+ MX6SL_PAD_EPDC_D0__EPDC_DATA00 0x80000000
+ MX6SL_PAD_EPDC_D1__EPDC_DATA01 0x80000000
+ MX6SL_PAD_EPDC_D2__EPDC_DATA02 0x80000000
+ MX6SL_PAD_EPDC_D3__EPDC_DATA03 0x80000000
+ MX6SL_PAD_EPDC_D4__EPDC_DATA04 0x80000000
+ MX6SL_PAD_EPDC_D5__EPDC_DATA05 0x80000000
+ MX6SL_PAD_EPDC_D6__EPDC_DATA06 0x80000000
+ MX6SL_PAD_EPDC_D7__EPDC_DATA07 0x80000000
+ MX6SL_PAD_EPDC_D8__EPDC_DATA08 0x80000000
+ MX6SL_PAD_EPDC_D9__EPDC_DATA09 0x80000000
+ MX6SL_PAD_EPDC_D10__EPDC_DATA10 0x80000000
+ MX6SL_PAD_EPDC_D11__EPDC_DATA11 0x80000000
+ MX6SL_PAD_EPDC_D12__EPDC_DATA12 0x80000000
+ MX6SL_PAD_EPDC_D13__EPDC_DATA13 0x80000000
+ MX6SL_PAD_EPDC_D14__EPDC_DATA14 0x80000000
+ MX6SL_PAD_EPDC_D15__EPDC_DATA15 0x80000000
+ MX6SL_PAD_EPDC_GDCLK__EPDC_GDCLK 0x80000000
+ MX6SL_PAD_EPDC_GDSP__EPDC_GDSP 0x80000000
+ MX6SL_PAD_EPDC_GDOE__EPDC_GDOE 0x80000000
+ MX6SL_PAD_EPDC_GDRL__EPDC_GDRL 0x80000000
+ MX6SL_PAD_EPDC_SDCLK__EPDC_SDCLK_P 0x80000000
+ MX6SL_PAD_EPDC_SDOE__EPDC_SDOE 0x80000000
+ MX6SL_PAD_EPDC_SDLE__EPDC_SDLE 0x80000000
+ MX6SL_PAD_EPDC_SDSHR__EPDC_SDSHR 0x80000000
+ MX6SL_PAD_EPDC_BDR0__EPDC_BDR0 0x80000000
+ MX6SL_PAD_EPDC_SDCE0__EPDC_SDCE0 0x80000000
+ MX6SL_PAD_EPDC_SDCE1__EPDC_SDCE1 0x80000000
+ MX6SL_PAD_EPDC_SDCE2__EPDC_SDCE2 0x80000000
+ >;
+ };
+
pinctrl_fec: fecgrp {
fsl,pins = <
MX6SL_PAD_FEC_MDC__FEC_MDC 0x1b0b0
@@ -345,6 +588,13 @@
>;
};
+ pinctrl_i2c3: i2c3grp {
+ fsl,pins = <
+ MX6SL_PAD_EPDC_SDCE2__I2C3_SCL 0x4001b8b1
+ MX6SL_PAD_EPDC_SDCE3__I2C3_SDA 0x4001b8b1
+ >;
+ };
+
pinctrl_kpp: kppgrp {
fsl,pins = <
MX6SL_PAD_KEY_ROW0__KEY_ROW0 0x1b010
@@ -356,7 +606,7 @@
>;
};
- pinctrl_lcd: lcdgrp {
+ pinctrl_lcdif_dat: lcdifdatgrp {
fsl,pins = <
MX6SL_PAD_LCD_DAT0__LCD_DATA00 0x1b0b0
MX6SL_PAD_LCD_DAT1__LCD_DATA01 0x1b0b0
@@ -382,6 +632,11 @@
MX6SL_PAD_LCD_DAT21__LCD_DATA21 0x1b0b0
MX6SL_PAD_LCD_DAT22__LCD_DATA22 0x1b0b0
MX6SL_PAD_LCD_DAT23__LCD_DATA23 0x1b0b0
+ >;
+ };
+
+ pinctrl_lcdif_ctrl: lcdifctrlgrp {
+ fsl,pins = <
MX6SL_PAD_LCD_CLK__LCD_CLK 0x1b0b0
MX6SL_PAD_LCD_ENABLE__LCD_ENABLE 0x1b0b0
MX6SL_PAD_LCD_HSYNC__LCD_HSYNC 0x1b0b0
@@ -401,6 +656,12 @@
>;
};
+ pinctrl_spdif: spdifgrp {
+ fsl,pins = <
+ MX6SL_PAD_SD2_DAT4__SPDIF_OUT 0x80000000
+ >;
+ };
+
pinctrl_uart1: uart1grp {
fsl,pins = <
MX6SL_PAD_UART1_RXD__UART1_RX_DATA 0x1b0b1
@@ -408,6 +669,24 @@
>;
};
+ pinctrl_uart4_1: uart4grp-1 {
+ fsl,pins = <
+ MX6SL_PAD_SD1_DAT4__UART4_RX_DATA 0x1b0b1
+ MX6SL_PAD_SD1_DAT5__UART4_TX_DATA 0x1b0b1
+ MX6SL_PAD_SD1_DAT7__UART4_CTS_B 0x1b0b1
+ MX6SL_PAD_SD1_DAT6__UART4_RTS_B 0x1b0b1
+ >;
+ };
+
+ pinctrl_uart4dte_1: uart4dtegrp-1 {
+ fsl,pins = <
+ MX6SL_PAD_SD1_DAT5__UART4_RX_DATA 0x1b0b1
+ MX6SL_PAD_SD1_DAT4__UART4_TX_DATA 0x1b0b1
+ MX6SL_PAD_SD1_DAT6__UART4_CTS_B 0x1b0b1
+ MX6SL_PAD_SD1_DAT7__UART4_RTS_B 0x1b0b1
+ >;
+ };
+
pinctrl_usbotg1: usbotg1grp {
fsl,pins = <
MX6SL_PAD_EPDC_PWRCOM__USB_OTG1_ID 0x17059
@@ -524,9 +803,34 @@
MX6SL_PAD_SD3_DAT3__SD3_DATA3 0x170f9
>;
};
+
+ pinctrl_csi_0: csigrp-0 {
+ fsl,pins = <
+ MX6SL_PAD_EPDC_GDRL__CSI_MCLK 0x110b0
+ MX6SL_PAD_EPDC_GDCLK__CSI_PIXCLK 0x110b0
+ MX6SL_PAD_EPDC_GDSP__CSI_VSYNC 0x110b0
+ MX6SL_PAD_EPDC_GDOE__CSI_HSYNC 0x110b0
+ MX6SL_PAD_EPDC_SDLE__CSI_DATA09 0x110b0
+ MX6SL_PAD_EPDC_SDCLK__CSI_DATA08 0x110b0
+ MX6SL_PAD_EPDC_D7__CSI_DATA07 0x110b0
+ MX6SL_PAD_EPDC_D6__CSI_DATA06 0x110b0
+ MX6SL_PAD_EPDC_D5__CSI_DATA05 0x110b0
+ MX6SL_PAD_EPDC_D4__CSI_DATA04 0x110b0
+ MX6SL_PAD_EPDC_D3__CSI_DATA03 0x110b0
+ MX6SL_PAD_EPDC_D2__CSI_DATA02 0x110b0
+ MX6SL_PAD_EPDC_D1__CSI_DATA01 0x110b0
+ MX6SL_PAD_EPDC_D0__CSI_DATA00 0x110b0
+ MX6SL_PAD_EPDC_SDSHR__GPIO1_IO26 0x80000000
+ MX6SL_PAD_EPDC_SDOE__GPIO1_IO25 0x80000000
+ >;
+ };
};
};
+&pxp {
+ status = "okay";
+};
+
&kpp {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_kpp>;
@@ -545,13 +849,14 @@
&lcdif {
pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_lcd>;
+ pinctrl-0 = <&pinctrl_lcdif_dat
+ &pinctrl_lcdif_ctrl>;
lcd-supply = <&reg_lcd_3v3>;
display = <&display0>;
status = "okay";
- display0: display0 {
- bits-per-pixel = <32>;
+ display0: display@0 {
+ bits-per-pixel = <16>;
bus-width = <24>;
display-timings {
@@ -585,7 +890,21 @@
status = "okay";
};
+&spdif {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_spdif>;
+ assigned-clocks = <&clks IMX6SL_CLK_SPDIF0_SEL>,
+ <&clks IMX6SL_CLK_SPDIF0_PODF>;
+ assigned-clock-parents = <&clks IMX6SL_CLK_PLL3_PFD3>;
+ assigned-clock-rates = <0>, <227368421>;
+ status = "okay";
+};
+
&ssi2 {
+ fsl,mode = "i2s-slave";
+ assigned-clocks = <&clks IMX6SL_CLK_SSI2_SEL>,
+ <&clks IMX6SL_CLK_SSI2>;
+ assigned-clock-rates = <0>, <24000000>;
status = "okay";
};
@@ -600,6 +919,9 @@
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_usbotg1>;
disable-over-current;
+ srp-disable;
+ hnp-disable;
+ adp-disable;
status = "okay";
};
@@ -610,6 +932,14 @@
status = "okay";
};
+&usbphy1 {
+ fsl,tx-d-cal = <106>;
+};
+
+&usbphy2 {
+ fsl,tx-d-cal = <106>;
+};
+
&usdhc1 {
pinctrl-names = "default", "state_100mhz", "state_200mhz";
pinctrl-0 = <&pinctrl_usdhc1>;
@@ -618,6 +948,8 @@
bus-width = <8>;
cd-gpios = <&gpio4 7 GPIO_ACTIVE_LOW>;
wp-gpios = <&gpio4 6 GPIO_ACTIVE_HIGH>;
+ keep-power-in-suspend;
+ enable-sdio-wakeup;
status = "okay";
};
@@ -628,6 +960,8 @@
pinctrl-2 = <&pinctrl_usdhc2_200mhz>;
cd-gpios = <&gpio5 0 GPIO_ACTIVE_LOW>;
wp-gpios = <&gpio4 29 GPIO_ACTIVE_HIGH>;
+ keep-power-in-suspend;
+ enable-sdio-wakeup;
status = "okay";
};
@@ -637,5 +971,7 @@
pinctrl-1 = <&pinctrl_usdhc3_100mhz>;
pinctrl-2 = <&pinctrl_usdhc3_200mhz>;
cd-gpios = <&gpio3 22 GPIO_ACTIVE_LOW>;
+ keep-power-in-suspend;
+ enable-sdio-wakeup;
status = "okay";
};
diff --git a/arch/arm/boot/dts/imx6sl.dtsi b/arch/arm/boot/dts/imx6sl.dtsi
index bd9308b222ba..608b277c7295 100644
--- a/arch/arm/boot/dts/imx6sl.dtsi
+++ b/arch/arm/boot/dts/imx6sl.dtsi
@@ -1,5 +1,6 @@
/*
- * Copyright 2013 Freescale Semiconductor, Inc.
+ * Copyright 2013-2016 Freescale Semiconductor, Inc.
+ * Copyright 2018 NXP
*
* 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
@@ -30,6 +31,10 @@
gpio2 = &gpio3;
gpio3 = &gpio4;
gpio4 = &gpio5;
+ mmc0 = &usdhc1;
+ mmc1 = &usdhc2;
+ mmc2 = &usdhc3;
+ mmc3 = &usdhc4;
serial0 = &uart1;
serial1 = &uart2;
serial2 = &uart3;
@@ -65,17 +70,37 @@
396000 1175000
>;
clock-latency = <61036>; /* two CLK32 periods */
- clocks = <&clks IMX6SL_CLK_ARM>, <&clks IMX6SL_CLK_PLL2_PFD2>,
- <&clks IMX6SL_CLK_STEP>, <&clks IMX6SL_CLK_PLL1_SW>,
- <&clks IMX6SL_CLK_PLL1_SYS>;
+ clocks = <&clks IMX6SL_CLK_ARM>,
+ <&clks IMX6SL_CLK_PLL2_PFD2>,
+ <&clks IMX6SL_CLK_STEP>,
+ <&clks IMX6SL_CLK_PLL1_SW>,
+ <&clks IMX6SL_CLK_PLL1_SYS>,
+ <&clks IMX6SL_CLK_PLL1>,
+ <&clks IMX6SL_PLL1_BYPASS>,
+ <&clks IMX6SL_PLL1_BYPASS_SRC>;
clock-names = "arm", "pll2_pfd2_396m", "step",
- "pll1_sw", "pll1_sys";
+ "pll1_sw", "pll1_sys", "pll1", "pll1_bypass",
+ "pll1_bypass_src";
arm-supply = <&reg_arm>;
pu-supply = <&reg_pu>;
soc-supply = <&reg_soc>;
};
};
+ reserved-memory {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ /* global autoconfigured region for contiguous allocations */
+ linux,cma {
+ compatible = "shared-dma-pool";
+ reusable;
+ size = <0x14000000>;
+ linux,cma-default;
+ };
+ };
+
intc: interrupt-controller@00a01000 {
compatible = "arm,cortex-a9-gic";
#interrupt-cells = <3>;
@@ -102,6 +127,10 @@
};
};
+ reg_vbus_wakeup: usb_vbus_wakeup {
+ compatible = "fsl,imx6-dummy-ldo2p5";
+ };
+
soc {
#address-cells = <1>;
#size-cells = <1>;
@@ -109,12 +138,51 @@
interrupt-parent = <&gpc>;
ranges;
- ocram: sram@00900000 {
+ busfreq { /* BUSFREQ */
+ compatible = "fsl,imx_busfreq";
+ clocks = <&clks IMX6SL_CLK_PLL2_BUS>, <&clks IMX6SL_CLK_PLL2_PFD2>,
+ <&clks IMX6SL_CLK_PLL2_198M>, <&clks IMX6SL_CLK_ARM>,
+ <&clks IMX6SL_CLK_PLL3_USB_OTG>, <&clks IMX6SL_CLK_PERIPH>,
+ <&clks IMX6SL_CLK_PRE_PERIPH_SEL>, <&clks IMX6SL_CLK_PERIPH_CLK2_PODF>,
+ <&clks IMX6SL_CLK_PERIPH_CLK2_SEL>, <&clks IMX6SL_CLK_OSC>,
+ <&clks IMX6SL_CLK_PLL1_SYS>, <&clks IMX6SL_CLK_PERIPH2>,
+ <&clks IMX6SL_CLK_AHB>, <&clks IMX6SL_CLK_OCRAM_PODF>,
+ <&clks IMX6SL_CLK_PLL1_SW>, <&clks IMX6SL_CLK_PRE_PERIPH2_SEL>,
+ <&clks IMX6SL_CLK_PERIPH2_CLK2_SEL>, <&clks IMX6SL_CLK_PERIPH2_CLK2_PODF>,
+ <&clks IMX6SL_CLK_STEP>, <&clks IMX6SL_PLL2_BYPASS_SRC>, <&clks IMX6SL_PLL2_BYPASS>,
+ <&clks IMX6SL_CLK_PLL2>, <&clks IMX6SL_CLK_PLL1>, <&clks IMX6SL_PLL1_BYPASS>,
+ <&clks IMX6SL_PLL1_BYPASS_SRC>;
+ clock-names = "pll2_bus", "pll2_pfd2_396m", "pll2_198m", "arm", "pll3_usb_otg", "periph",
+ "periph_pre", "periph_clk2", "periph_clk2_sel", "osc", "pll1_sys", "periph2", "ahb",
+ "ocram", "pll1_sw", "periph2_pre", "periph2_clk2_sel", "periph2_clk2", "step", "pll2_bypass_src",
+ "pll2_bypass", "pll2", "pll1", "pll1_bypass", "pll1_bypass_src";
+ fsl,max_ddr_freq = <400000000>;
+ };
+
+ ocrams: sram@00900000 {
+ compatible = "fsl,lpm-sram";
+ reg = <0x00900000 0x4000>;
+ clocks = <&clks IMX6SL_CLK_OCRAM>;
+ };
+
+ ocrams_ddr: sram@00904000 {
+ compatible = "fsl,ddr-lpm-sram";
+ reg = <0x00904000 0x1000>;
+ clocks = <&clks IMX6SL_CLK_OCRAM>;
+ };
+
+ ocram: sram@00905000 {
compatible = "mmio-sram";
- reg = <0x00900000 0x20000>;
+ reg = <0x00905000 0x1B000>;
clocks = <&clks IMX6SL_CLK_OCRAM>;
};
+ ocram_optee: sram@00918000 {
+ compatible = "fsl,optee-lpm-sram";
+ reg = <0x00918000 0x8000>;
+ overw_reg = <&ocram 0x00905000 0x13000>;
+ };
+
L2: l2-cache@00a02000 {
compatible = "arm,pl310-cache";
reg = <0x00a02000 0x1000>;
@@ -174,6 +242,8 @@
clocks = <&clks IMX6SL_CLK_ECSPI1>,
<&clks IMX6SL_CLK_ECSPI1>;
clock-names = "ipg", "per";
+ dmas = <&sdma 3 7 1>, <&sdma 4 7 2>;
+ dma-names = "rx", "tx";
status = "disabled";
};
@@ -186,6 +256,8 @@
clocks = <&clks IMX6SL_CLK_ECSPI2>,
<&clks IMX6SL_CLK_ECSPI2>;
clock-names = "ipg", "per";
+ dmas = <&sdma 5 7 1>, <&sdma 6 7 2>;
+ dma-names = "rx", "tx";
status = "disabled";
};
@@ -198,6 +270,8 @@
clocks = <&clks IMX6SL_CLK_ECSPI3>,
<&clks IMX6SL_CLK_ECSPI3>;
clock-names = "ipg", "per";
+ dmas = <&sdma 7 7 1>, <&sdma 8 7 2>;
+ dma-names = "rx", "tx";
status = "disabled";
};
@@ -210,6 +284,8 @@
clocks = <&clks IMX6SL_CLK_ECSPI4>,
<&clks IMX6SL_CLK_ECSPI4>;
clock-names = "ipg", "per";
+ dmas = <&sdma 9 7 1>, <&sdma 10 7 2>;
+ dma-names = "rx", "tx";
status = "disabled";
};
@@ -261,8 +337,8 @@
clocks = <&clks IMX6SL_CLK_SSI1_IPG>,
<&clks IMX6SL_CLK_SSI1>;
clock-names = "ipg", "baud";
- dmas = <&sdma 37 1 0>,
- <&sdma 38 1 0>;
+ dmas = <&sdma 37 22 0>,
+ <&sdma 38 22 0>;
dma-names = "rx", "tx";
fsl,fifo-depth = <15>;
status = "disabled";
@@ -277,8 +353,8 @@
clocks = <&clks IMX6SL_CLK_SSI2_IPG>,
<&clks IMX6SL_CLK_SSI2>;
clock-names = "ipg", "baud";
- dmas = <&sdma 41 1 0>,
- <&sdma 42 1 0>;
+ dmas = <&sdma 41 22 0>,
+ <&sdma 42 22 0>;
dma-names = "rx", "tx";
fsl,fifo-depth = <15>;
status = "disabled";
@@ -293,8 +369,8 @@
clocks = <&clks IMX6SL_CLK_SSI3_IPG>,
<&clks IMX6SL_CLK_SSI3>;
clock-names = "ipg", "baud";
- dmas = <&sdma 45 1 0>,
- <&sdma 46 1 0>;
+ dmas = <&sdma 45 22 0>,
+ <&sdma 46 22 0>;
dma-names = "rx", "tx";
fsl,fifo-depth = <15>;
status = "disabled";
@@ -533,12 +609,11 @@
anatop-enable-bit = <0>;
};
- regulator-3p0 {
+ reg_3p0: regulator-3p0@120 {
compatible = "fsl,anatop-regulator";
regulator-name = "vdd3p0";
- regulator-min-microvolt = <2800000>;
- regulator-max-microvolt = <3150000>;
- regulator-always-on;
+ regulator-min-microvolt = <2625000>;
+ regulator-max-microvolt = <3400000>;
anatop-reg-offset = <0x120>;
anatop-vol-bit-shift = <8>;
anatop-vol-bit-width = <5>;
@@ -578,6 +653,7 @@
anatop-min-bit-val = <1>;
anatop-min-voltage = <725000>;
anatop-max-voltage = <1450000>;
+ regulator-allow-bypass;
};
reg_pu: regulator-vddpu {
@@ -585,7 +661,8 @@
regulator-name = "vddpu";
regulator-min-microvolt = <725000>;
regulator-max-microvolt = <1450000>;
- regulator-always-on;
+ regulator-enable-ramp-delay = <150>;
+ regulator-boot-on;
anatop-reg-offset = <0x140>;
anatop-vol-bit-shift = <9>;
anatop-vol-bit-width = <5>;
@@ -595,6 +672,7 @@
anatop-min-bit-val = <1>;
anatop-min-voltage = <725000>;
anatop-max-voltage = <1450000>;
+ regulator-allow-bypass;
};
reg_soc: regulator-vddsoc {
@@ -612,6 +690,7 @@
anatop-min-bit-val = <1>;
anatop-min-voltage = <725000>;
anatop-max-voltage = <1450000>;
+ regulator-allow-bypass;
};
};
@@ -628,6 +707,7 @@
reg = <0x020c9000 0x1000>;
interrupts = <0 44 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clks IMX6SL_CLK_USBPHY1>;
+ phy-3p0-supply = <&reg_3p0>;
fsl,anatop = <&anatop>;
};
@@ -636,9 +716,16 @@
reg = <0x020ca000 0x1000>;
interrupts = <0 45 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clks IMX6SL_CLK_USBPHY2>;
+ phy-3p0-supply = <&reg_3p0>;
fsl,anatop = <&anatop>;
};
+ usbphy_nop1: usbphy_nop1 {
+ compatible = "usb-nop-xceiv";
+ clocks = <&clks IMX6SL_CLK_USBPHY1>;
+ clock-names = "main_clk";
+ };
+
snvs: snvs@020cc000 {
compatible = "fsl,sec-v4.0-mon", "syscon", "simple-mfd";
reg = <0x020cc000 0x4000>;
@@ -655,8 +742,8 @@
compatible = "syscon-poweroff";
regmap = <&snvs>;
offset = <0x38>;
- value = <0x60>;
- mask = <0x60>;
+ value = <0x61>;
+ mask = <0x61>;
status = "disabled";
};
};
@@ -687,8 +774,12 @@
interrupts = <0 89 IRQ_TYPE_LEVEL_HIGH>;
interrupt-parent = <&intc>;
pu-supply = <&reg_pu>;
- clocks = <&clks IMX6SL_CLK_GPU2D_OVG>,
- <&clks IMX6SL_CLK_GPU2D_PODF>;
+ clocks = <&clks IMX6SL_CLK_GPU2D_PODF>, <&clks IMX6SL_CLK_GPU2D_OVG>,
+ <&clks IMX6SL_CLK_IPG>, <&clks IMX6SL_CLK_LCDIF_AXI>,
+ <&clks IMX6SL_CLK_LCDIF_PIX>, <&clks IMX6SL_CLK_EPDC_AXI>,
+ <&clks IMX6SL_CLK_EPDC_PIX>, <&clks IMX6SL_CLK_PXP_AXI>;
+ clock-names = "gpu2d_podf", "gpu2d_ovg", "ipg", "lcd_axi",
+ "lcd_pix", "epdc_axi", "epdc_pix", "pxp_axi";
#power-domain-cells = <1>;
};
@@ -704,8 +795,14 @@
};
csi: csi@020e4000 {
+ compatible = "fsl,imx6sl-csi";
reg = <0x020e4000 0x4000>;
interrupts = <0 7 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SL_CLK_DUMMY>,
+ <&clks IMX6SL_CLK_DUMMY>,
+ <&clks IMX6SL_CLK_DUMMY>;
+ clock-names = "disp-axi", "csi_mclk", "disp_dcic";
+ status = "disabled";
};
spdc: spdc@020e8000 {
@@ -721,18 +818,26 @@
<&clks IMX6SL_CLK_AHB>;
clock-names = "ipg", "ahb";
#dma-cells = <3>;
+ iram = <&ocram>;
/* imx6sl reuses imx6q sdma firmware */
fsl,sdma-ram-script-name = "imx/sdma/sdma-imx6q.bin";
};
pxp: pxp@020f0000 {
+ compatible = "fsl,imx6sl-pxp-dma", "fsl,imx6dl-pxp-dma";
reg = <0x020f0000 0x4000>;
interrupts = <0 98 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SL_CLK_PXP_AXI>, <&clks IMX6SL_CLK_DUMMY>;
+ clock-names = "pxp-axi", "disp-axi";
+ status = "disabled";
};
epdc: epdc@020f4000 {
+ compatible = "fsl,imx6sl-epdc", "fsl,imx6dl-epdc";
reg = <0x020f4000 0x4000>;
interrupts = <0 97 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SL_CLK_EPDC_AXI>, <&clks IMX6SL_CLK_EPDC_PIX>;
+ clock-names = "epdc_axi", "epdc_pix";
};
lcdif: lcdif@020f8000 {
@@ -752,6 +857,10 @@
interrupts = <0 99 IRQ_TYPE_LEVEL_HIGH>,
<0 100 IRQ_TYPE_LEVEL_HIGH>,
<0 101 IRQ_TYPE_LEVEL_HIGH>;
+ /* DCP clock always on */
+ clocks = <&clks IMX6SL_CLK_DUMMY>;
+ clock-names = "dcp";
+ status = "okay";
};
};
@@ -772,6 +881,7 @@
ahb-burst-config = <0x0>;
tx-burst-size-dword = <0x10>;
rx-burst-size-dword = <0x10>;
+ fsl,anatop = <&anatop>;
status = "disabled";
};
@@ -798,6 +908,9 @@
ahb-burst-config = <0x0>;
tx-burst-size-dword = <0x10>;
rx-burst-size-dword = <0x10>;
+ phy_type = "hsic";
+ fsl,usbphy = <&usbphy_nop1>;
+ fsl,anatop = <&anatop>;
status = "disabled";
};
@@ -806,6 +919,7 @@
compatible = "fsl,imx6sl-usbmisc", "fsl,imx6q-usbmisc";
reg = <0x02184800 0x200>;
clocks = <&clks IMX6SL_CLK_USBOH3>;
+ vbus-wakeup-supply = <&reg_vbus_wakeup>;
};
fec: ethernet@02188000 {
@@ -901,9 +1015,11 @@
reg = <0x021b0000 0x4000>;
};
- rngb: rngb@021b4000 {
+ rng: rng@021b4000 {
+ compatible = "fsl,imx6sl-rng", "fsl,imx-rng", "imx-rng";
reg = <0x021b4000 0x4000>;
interrupts = <0 5 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SL_CLK_DUMMY>;
};
weim: weim@021b8000 {
@@ -926,6 +1042,24 @@
reg = <0x021d8000 0x4000>;
status = "disabled";
};
+
+ gpu: gpu@02200000 {
+ compatible = "fsl,imx6sl-gpu", "fsl,imx6q-gpu";
+ reg = <0x02200000 0x4000>, <0x02204000 0x4000>,
+ <0x80000000 0x0>, <0x0 0x8000000>;
+ reg-names = "iobase_2d", "iobase_vg",
+ "phys_baseaddr", "contiguous_mem";
+ interrupts = <0 10 IRQ_TYPE_LEVEL_HIGH>, <0 11 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "irq_2d", "irq_vg";
+ clocks = <&clks IMX6SL_CLK_MMDC_ROOT>,
+ <&clks IMX6SL_CLK_MMDC_ROOT>,
+ <&clks IMX6SL_CLK_GPU2D_OVG>;
+ clock-names = "gpu2d_axi_clk", "openvg_axi_clk",
+ "gpu2d_clk";
+ resets = <&src 3>, <&src 3>;
+ reset-names = "gpu2d", "gpuvg";
+ power-domains = <&gpc 1>;
+ };
};
};
};
diff --git a/arch/arm/boot/dts/imx6sll-evk-btwifi.dts b/arch/arm/boot/dts/imx6sll-evk-btwifi.dts
new file mode 100644
index 000000000000..d5f9ffba13ee
--- /dev/null
+++ b/arch/arm/boot/dts/imx6sll-evk-btwifi.dts
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+/*
+ * NOTE: This DTS file is written for plugging in Murata Wi-Fi/BT EVK into Slot
+ * SD1 and using Murata i.MX InterConnect Ver 2.0 Adapter. Bluetooth UART &
+ * control signals are connected via ribbon cable (J4 connector).
+ */
+
+#include "imx6sll-evk.dts"
+
+/ {
+ modem_reset: modem-reset {
+ compatible = "gpio-reset";
+ reset-gpios = <&gpio3 27 GPIO_ACTIVE_LOW>;
+ reset-delay-us = <1000>;
+ #reset-cells = <0>;
+ };
+
+ usdhc1_pwrseq: usdhc1_pwrseq {
+ compatible = "mmc-pwrseq-simple";
+ reset-gpios = <&gpio3 24 GPIO_ACTIVE_LOW>;
+ };
+};
+
+&iomuxc {
+ imx6sll-evk-murata-v2 {
+ pinctrl_wifi: wifigrp {
+ fsl,pins = <
+ MX6SLL_PAD_SD3_CMD__SD3_CMD 0x170b9
+ MX6SLL_PAD_SD3_CLK__SD3_CLK 0x130b9
+ MX6SLL_PAD_SD3_DATA0__SD3_DATA0 0x170b9
+ MX6SLL_PAD_SD3_DATA1__SD3_DATA1 0x170b9
+ MX6SLL_PAD_SD3_DATA2__SD3_DATA2 0x170b9
+ MX6SLL_PAD_SD3_DATA3__SD3_DATA3 0x170b9
+
+ MX6SLL_PAD_KEY_COL0__GPIO3_IO24 0x17059 /* WL_REG_ON */
+ MX6SLL_PAD_KEY_COL1__GPIO3_IO26 0x17059 /* WL_HOST_WAKE */
+ >;
+ };
+ };
+};
+
+&lcdif {
+ status = "disabled";
+};
+
+&reg_sd3_vmmc {
+ regulator-always-on;
+};
+
+&uart5 {
+ resets = <&modem_reset>;
+ status = "okay";
+};
+
+&usdhc3 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_wifi>;
+ bus-width = <4>;
+ no-1-8-v;
+ non-removable;
+ mmc-pwrseq = <&usdhc1_pwrseq>;
+ pm-ignore-notify;
+ cap-power-off-card;
+
+ brcmf: bcrmf@1 {
+ reg = <1>;
+ compatible = "brcm,bcm4329-fmac";
+ };
+};
diff --git a/arch/arm/boot/dts/imx6sll-evk-reva.dts b/arch/arm/boot/dts/imx6sll-evk-reva.dts
new file mode 100644
index 000000000000..8562facad609
--- /dev/null
+++ b/arch/arm/boot/dts/imx6sll-evk-reva.dts
@@ -0,0 +1,13 @@
+/*
+ * Copyright (C) 2016 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 "imx6sll-evk.dts"
+
+&usdhc2 {
+ compatible = "fsl,imx6sll-usdhc", "fsl,imx6sx-usdhc";
+};
diff --git a/arch/arm/boot/dts/imx6sll-evk.dts b/arch/arm/boot/dts/imx6sll-evk.dts
new file mode 100644
index 000000000000..ee423bc2e001
--- /dev/null
+++ b/arch/arm/boot/dts/imx6sll-evk.dts
@@ -0,0 +1,821 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017 NXP.
+ *
+ * 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 <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include "imx6sll.dtsi"
+
+/ {
+ model = "Freescale i.MX6SLL EVK Board";
+ compatible = "fsl,imx6sll-evk", "fsl,imx6sll";
+
+ chosen {
+ stdout-path = &uart1;
+ };
+
+ memory {
+ reg = <0x80000000 0x80000000>;
+ };
+
+ backlight {
+ compatible = "pwm-backlight";
+ pwms = <&pwm1 0 5000000>;
+ brightness-levels = <0 4 8 16 32 64 128 255>;
+ default-brightness-level = <6>;
+ status = "okay";
+ };
+
+ battery: max8903@0 {
+ compatible = "fsl,max8903-charger";
+ pinctrl-names = "default";
+ dok_input = <&gpio4 13 1>;
+ uok_input = <&gpio4 13 1>;
+ chg_input = <&gpio4 15 1>;
+ flt_input = <&gpio4 14 1>;
+ fsl,dcm_always_high;
+ fsl,dc_valid;
+ fsl,adc_disable;
+ status = "okay";
+ };
+
+ pxp_v4l2_out {
+ compatible = "fsl,imx6sl-pxp-v4l2";
+ status = "okay";
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ reg_usb_otg1_vbus: regulator@0 {
+ compatible = "regulator-fixed";
+ reg = <0>;
+ regulator-name = "usb_otg1_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&gpio4 0 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ reg_usb_otg2_vbus: regulator@1 {
+ compatible = "regulator-fixed";
+ reg = <1>;
+ regulator-name = "usb_otg2_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&gpio4 2 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ reg_aud3v: regulator@2 {
+ compatible = "regulator-fixed";
+ reg = <2>;
+ regulator-name = "wm8962-supply-3v15";
+ regulator-min-microvolt = <3150000>;
+ regulator-max-microvolt = <3150000>;
+ regulator-boot-on;
+ };
+
+ reg_aud4v: regulator@3 {
+ compatible = "regulator-fixed";
+ reg = <3>;
+ regulator-name = "wm8962-supply-4v2";
+ regulator-min-microvolt = <4325000>;
+ regulator-max-microvolt = <4325000>;
+ regulator-boot-on;
+ };
+
+ reg_lcd: regulator@4 {
+ compatible = "regulator-fixed";
+ reg = <4>;
+ regulator-name = "lcd-pwr";
+ gpio = <&gpio4 8 0>;
+ enable-active-high;
+ };
+
+ reg_sd1_vmmc: sd1_vmmc {
+ compatible = "regulator-fixed";
+ regulator-name = "SD1_SPWR";
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ gpio = <&gpio3 30 GPIO_ACTIVE_HIGH>;
+ off-on-delay = <20000>;
+ enable-active-high;
+ };
+
+ reg_sd2_vmmc: sd2_vmmc {
+ compatible = "regulator-fixed";
+ regulator-name = "eMMC-VCCQ";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-boot-on;
+ };
+
+ reg_sd3_vmmc: sd3_vmmc {
+ compatible = "regulator-fixed";
+ regulator-name = "SD3_WIFI";
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ gpio = <&gpio4 4 GPIO_ACTIVE_HIGH>;
+ off-on-delay = <20000>;
+ enable-active-high;
+ };
+
+ };
+
+ sound {
+ compatible = "fsl,imx6sl-evk-wm8962", "fsl,imx-audio-wm8962";
+ model = "wm8962-audio";
+ cpu-dai = <&ssi2>;
+ audio-codec = <&codec>;
+ audio-routing =
+ "Headphone Jack", "HPOUTL",
+ "Headphone Jack", "HPOUTR",
+ "Ext Spk", "SPKOUTL",
+ "Ext Spk", "SPKOUTR",
+ "AMIC", "MICBIAS",
+ "IN3R", "AMIC";
+ mux-int-port = <2>;
+ mux-ext-port = <3>;
+ codec-master;
+ hp-det-gpios = <&gpio4 24 1>;
+ };
+};
+
+&audmux {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_audmux3>;
+ status = "okay";
+};
+
+&clks {
+ assigned-clocks = <&clks IMX6SLL_CLK_PLL4_AUDIO_DIV>;
+ assigned-clock-rates = <393216000>;
+};
+
+&cpu0 {
+ arm-supply = <&sw1a_reg>;
+ soc-supply = <&sw1c_reg>;
+};
+
+&i2c1 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c1>;
+ status = "okay";
+
+ pmic: pfuze100@08 {
+ compatible = "fsl,pfuze100";
+ reg = <0x08>;
+
+ regulators {
+ sw1a_reg: sw1ab {
+ regulator-min-microvolt = <300000>;
+ regulator-max-microvolt = <1875000>;
+ regulator-boot-on;
+ regulator-always-on;
+ regulator-ramp-delay = <6250>;
+ };
+
+ sw1c_reg: sw1c {
+ regulator-min-microvolt = <300000>;
+ regulator-max-microvolt = <1875000>;
+ regulator-boot-on;
+ regulator-always-on;
+ regulator-ramp-delay = <6250>;
+ };
+
+ sw2_reg: sw2 {
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ sw3a_reg: sw3a {
+ regulator-min-microvolt = <400000>;
+ regulator-max-microvolt = <1975000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ sw3b_reg: sw3b {
+ regulator-min-microvolt = <400000>;
+ regulator-max-microvolt = <1975000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ sw4_reg: sw4 {
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ swbst_reg: swbst {
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5150000>;
+ };
+
+ snvs_reg: vsnvs {
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ vref_reg: vrefddr {
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ vgen1_reg: vgen1 {
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1550000>;
+ regulator-always-on;
+ };
+
+ vgen2_reg: vgen2 {
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1550000>;
+ };
+
+ vgen3_reg: vgen3 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ vgen4_reg: vgen4 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ vgen5_reg: vgen5 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ vgen6_reg: vgen6 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+ };
+ };
+
+ max17135: max17135@48 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_max17135>;
+ compatible = "maxim,max17135";
+ reg = <0x48>;
+ status = "okay";
+
+ vneg_pwrup = <1>;
+ gvee_pwrup = <2>;
+ vpos_pwrup = <10>;
+ gvdd_pwrup = <12>;
+ gvdd_pwrdn = <1>;
+ vpos_pwrdn = <2>;
+ gvee_pwrdn = <8>;
+ vneg_pwrdn = <10>;
+ gpio_pmic_pwrgood = <&gpio2 13 0>;
+ gpio_pmic_vcom_ctrl = <&gpio2 3 0>;
+ gpio_pmic_wakeup = <&gpio2 14 0>;
+ gpio_pmic_v3p3 = <&gpio2 7 0>;
+ gpio_pmic_intr = <&gpio2 12 0>;
+
+ regulators {
+ DISPLAY_reg: DISPLAY {
+ regulator-name = "DISPLAY";
+ };
+
+ GVDD_reg: GVDD {
+ /* 20v */
+ regulator-name = "GVDD";
+ };
+
+ GVEE_reg: GVEE {
+ /* -22v */
+ regulator-name = "GVEE";
+ };
+
+ HVINN_reg: HVINN {
+ /* -22v */
+ regulator-name = "HVINN";
+ };
+
+ HVINP_reg: HVINP {
+ /* 20v */
+ regulator-name = "HVINP";
+ };
+
+ VCOM_reg: VCOM {
+ regulator-name = "VCOM";
+ /* Real max value: -500000 */
+ regulator-max-microvolt = <4325000>;
+ /* Real min value: -4325000 */
+ regulator-min-microvolt = <500000>;
+ };
+
+ VNEG_reg: VNEG {
+ /* -15v */
+ regulator-name = "VNEG";
+ };
+
+ VPOS_reg: VPOS {
+ /* 15v */
+ regulator-name = "VPOS";
+ };
+
+ V3P3_reg: V3P3 {
+ regulator-name = "V3P3";
+ };
+ };
+ };
+};
+
+&i2c3 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c3>;
+ status = "okay";
+
+ codec: wm8962@1a {
+ compatible = "wlf,wm8962";
+ reg = <0x1a>;
+ clocks = <&clks IMX6SLL_CLK_EXTERN_AUDIO>;
+ DCVDD-supply = <&vgen3_reg>;
+ DBVDD-supply = <&reg_aud3v>;
+ AVDD-supply = <&vgen3_reg>;
+ CPVDD-supply = <&vgen3_reg>;
+ MICVDD-supply = <&reg_aud3v>;
+ PLLVDD-supply = <&vgen3_reg>;
+ SPKVDD1-supply = <&reg_aud4v>;
+ SPKVDD2-supply = <&reg_aud4v>;
+ amic-mono;
+ };
+};
+
+&gpc {
+ fsl,ldo-bypass = <1>;
+};
+
+&iomuxc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_hog>;
+
+ imx6sll-evk {
+ pinctrl_hog: hoggrp {
+ fsl,pins = <
+ MX6SLL_PAD_KEY_ROW7__GPIO4_IO07 0x17059
+ MX6SLL_PAD_GPIO4_IO22__GPIO4_IO22 0x17059
+ MX6SLL_PAD_KEY_COL3__GPIO3_IO30 0x17059
+ /*
+ * Must set the LVE of pad SD2_RESET, otherwise current
+ * leakage through eMMC chip will pull high the VCCQ to
+ * 2.6v, which will impact SD1 and SD3 SD3.0 voltage switch.
+ */
+ MX6SLL_PAD_SD2_RESET__GPIO4_IO27 0x417059
+ MX6SLL_PAD_KEY_COL4__GPIO4_IO00 0x17059
+ MX6SLL_PAD_REF_CLK_32K__GPIO3_IO22 0x17059 /* SD3 CD */
+ MX6SLL_PAD_KEY_COL6__GPIO4_IO04 0x17059 /*SD3 RESET */
+ MX6SLL_PAD_KEY_COL5__GPIO4_IO02 0x17059
+ MX6SLL_PAD_GPIO4_IO24__GPIO4_IO24 0x17059 /* HP DETECT */
+ /* CHG_FLT, CHG_UOK/DOK, CHG_STATUS */
+ MX6SLL_PAD_ECSPI2_MISO__GPIO4_IO14 0x17000
+ MX6SLL_PAD_ECSPI2_MOSI__GPIO4_IO13 0x17000
+ MX6SLL_PAD_ECSPI2_SS0__GPIO4_IO15 0x17000
+ >;
+ };
+
+ pinctrl_audmux3: audmux3grp {
+ fsl,pins = <
+ MX6SLL_PAD_AUD_TXC__AUD3_TXC 0x4130b0
+ MX6SLL_PAD_AUD_TXFS__AUD3_TXFS 0x4130b0
+ MX6SLL_PAD_AUD_TXD__AUD3_TXD 0x4110b0
+ MX6SLL_PAD_AUD_RXD__AUD3_RXD 0x4130b0
+ MX6SLL_PAD_AUD_MCLK__AUDIO_CLK_OUT 0x4130b0
+ >;
+ };
+
+ pinctrl_csi1: csi1grp {
+ fsl,pins = <
+ MX6SLL_PAD_EPDC_GDRL__CSI_MCLK 0x1b088
+ MX6SLL_PAD_EPDC_GDCLK__CSI_PIXCLK 0x1b088
+ MX6SLL_PAD_EPDC_GDSP__CSI_VSYNC 0x1b088
+ MX6SLL_PAD_EPDC_GDOE__CSI_HSYNC 0x1b088
+ MX6SLL_PAD_EPDC_DATA02__CSI_DATA02 0x1b088
+ MX6SLL_PAD_EPDC_DATA03__CSI_DATA03 0x1b088
+ MX6SLL_PAD_EPDC_DATA04__CSI_DATA04 0x1b088
+ MX6SLL_PAD_EPDC_DATA05__CSI_DATA05 0x1b088
+ MX6SLL_PAD_EPDC_DATA06__CSI_DATA06 0x1b088
+ MX6SLL_PAD_EPDC_DATA07__CSI_DATA07 0x1b088
+ MX6SLL_PAD_EPDC_SDCLK__CSI_DATA08 0x1b088
+ MX6SLL_PAD_EPDC_SDLE__CSI_DATA09 0x1b088
+ MX6SLL_PAD_EPDC_SDSHR__GPIO1_IO26 0x80000000
+ MX6SLL_PAD_EPDC_SDOE__GPIO1_IO25 0x80000000
+ >;
+ };
+
+ pinctrl_epdc0: epdcgrp0 {
+ fsl,pins = <
+ MX6SLL_PAD_EPDC_DATA00__EPDC_DATA00 0x100b1
+ MX6SLL_PAD_EPDC_DATA01__EPDC_DATA01 0x100b1
+ MX6SLL_PAD_EPDC_DATA02__EPDC_DATA02 0x100b1
+ MX6SLL_PAD_EPDC_DATA03__EPDC_DATA03 0x100b1
+ MX6SLL_PAD_EPDC_DATA04__EPDC_DATA04 0x100b1
+ MX6SLL_PAD_EPDC_DATA05__EPDC_DATA05 0x100b1
+ MX6SLL_PAD_EPDC_DATA06__EPDC_DATA06 0x100b1
+ MX6SLL_PAD_EPDC_DATA07__EPDC_DATA07 0x100b1
+ MX6SLL_PAD_EPDC_DATA08__EPDC_DATA08 0x100b1
+ MX6SLL_PAD_EPDC_DATA09__EPDC_DATA09 0x100b1
+ MX6SLL_PAD_EPDC_DATA10__EPDC_DATA10 0x100b1
+ MX6SLL_PAD_EPDC_DATA11__EPDC_DATA11 0x100b1
+ MX6SLL_PAD_EPDC_DATA12__EPDC_DATA12 0x100b1
+ MX6SLL_PAD_EPDC_DATA13__EPDC_DATA13 0x100b1
+ MX6SLL_PAD_EPDC_DATA14__EPDC_DATA14 0x100b1
+ MX6SLL_PAD_EPDC_DATA15__EPDC_DATA15 0x100b1
+ MX6SLL_PAD_EPDC_SDCLK__EPDC_SDCLK_P 0x100b1
+ MX6SLL_PAD_EPDC_SDLE__EPDC_SDLE 0x100b1
+ MX6SLL_PAD_EPDC_SDOE__EPDC_SDOE 0x100b1
+ MX6SLL_PAD_EPDC_SDSHR__EPDC_SDSHR 0x100b1
+ MX6SLL_PAD_EPDC_SDCE0__EPDC_SDCE0 0x100b1
+ MX6SLL_PAD_EPDC_GDCLK__EPDC_GDCLK 0x100b1
+ MX6SLL_PAD_EPDC_GDOE__EPDC_GDOE 0x100b1
+ MX6SLL_PAD_EPDC_GDRL__EPDC_GDRL 0x100b1
+ MX6SLL_PAD_EPDC_GDSP__EPDC_GDSP 0x100b1
+ >;
+ };
+
+ pinctrl_lcdif_dat: lcdifdatgrp {
+ fsl,pins = <
+ MX6SLL_PAD_LCD_DATA00__LCD_DATA00 0x79
+ MX6SLL_PAD_LCD_DATA01__LCD_DATA01 0x79
+ MX6SLL_PAD_LCD_DATA02__LCD_DATA02 0x79
+ MX6SLL_PAD_LCD_DATA03__LCD_DATA03 0x79
+ MX6SLL_PAD_LCD_DATA04__LCD_DATA04 0x79
+ MX6SLL_PAD_LCD_DATA05__LCD_DATA05 0x79
+ MX6SLL_PAD_LCD_DATA06__LCD_DATA06 0x79
+ MX6SLL_PAD_LCD_DATA07__LCD_DATA07 0x79
+ MX6SLL_PAD_LCD_DATA08__LCD_DATA08 0x79
+ MX6SLL_PAD_LCD_DATA09__LCD_DATA09 0x79
+ MX6SLL_PAD_LCD_DATA10__LCD_DATA10 0x79
+ MX6SLL_PAD_LCD_DATA11__LCD_DATA11 0x79
+ MX6SLL_PAD_LCD_DATA12__LCD_DATA12 0x79
+ MX6SLL_PAD_LCD_DATA13__LCD_DATA13 0x79
+ MX6SLL_PAD_LCD_DATA14__LCD_DATA14 0x79
+ MX6SLL_PAD_LCD_DATA15__LCD_DATA15 0x79
+ MX6SLL_PAD_LCD_DATA16__LCD_DATA16 0x79
+ MX6SLL_PAD_LCD_DATA17__LCD_DATA17 0x79
+ MX6SLL_PAD_LCD_DATA18__LCD_DATA18 0x79
+ MX6SLL_PAD_LCD_DATA19__LCD_DATA19 0x79
+ MX6SLL_PAD_LCD_DATA20__LCD_DATA20 0x79
+ MX6SLL_PAD_LCD_DATA21__LCD_DATA21 0x79
+ MX6SLL_PAD_LCD_DATA22__LCD_DATA22 0x79
+ MX6SLL_PAD_LCD_DATA23__LCD_DATA23 0x79
+ >;
+ };
+
+ pinctrl_lcdif_ctrl: lcdifctrlgrp {
+ fsl,pins = <
+ MX6SLL_PAD_LCD_CLK__LCD_CLK 0x79
+ MX6SLL_PAD_LCD_ENABLE__LCD_ENABLE 0x79
+ MX6SLL_PAD_LCD_HSYNC__LCD_HSYNC 0x79
+ MX6SLL_PAD_LCD_VSYNC__LCD_VSYNC 0x79
+ MX6SLL_PAD_LCD_RESET__LCD_RESET 0x79
+ MX6SLL_PAD_ECSPI1_SCLK__GPIO4_IO08 0x79
+ >;
+ };
+
+ pinctrl_max17135: max17135grp-1 {
+ fsl,pins = <
+ MX6SLL_PAD_EPDC_PWR_STAT__GPIO2_IO13 0x80000000 /* pwrgood */
+ MX6SLL_PAD_EPDC_VCOM0__GPIO2_IO03 0x80000000 /* vcom_ctrl */
+ MX6SLL_PAD_EPDC_PWR_WAKE__GPIO2_IO14 0x80000000 /* wakeup */
+ MX6SLL_PAD_EPDC_PWR_CTRL0__GPIO2_IO07 0x80000000 /* v3p3 */
+ MX6SLL_PAD_EPDC_PWR_IRQ__GPIO2_IO12 0x80000000 /* pwr int */
+ >;
+ };
+
+ pinctrl_spdif: spdifgrp {
+ fsl,pins = <
+ MX6SLL_PAD_SD2_DATA4__SPDIF_OUT 0x4130b0
+ >;
+ };
+
+ pinctrl_uart1: uart1grp {
+ fsl,pins = <
+ MX6SLL_PAD_UART1_TXD__UART1_DCE_TX 0x1b0b1
+ MX6SLL_PAD_UART1_RXD__UART1_DCE_RX 0x1b0b1
+ >;
+ };
+
+ pinctrl_uart5: uart5grp {
+ fsl,pins = <
+ MX6SLL_PAD_KEY_ROW1__GPIO3_IO27 0x1b0b1 /* bt reg on */
+ MX6SLL_PAD_ECSPI1_MOSI__UART5_DCE_TX 0x1b0b1
+ MX6SLL_PAD_ECSPI1_SCLK__UART5_DCE_RX 0x1b0b1
+ MX6SLL_PAD_ECSPI1_SS0__UART5_DCE_CTS 0x1b0b1
+ MX6SLL_PAD_ECSPI1_MISO__UART5_DCE_RTS 0x1b0b1
+ >;
+ };
+
+ pinctrl_uart5dte: uart5dtegrp {
+ fsl,pins = <
+ MX6SLL_PAD_ECSPI1_MOSI__UART5_DTE_RX 0x1b0b1
+ MX6SLL_PAD_ECSPI1_SCLK__UART5_DTE_TX 0x1b0b1
+ MX6SLL_PAD_ECSPI1_SS0__UART5_DTE_RTS 0x1b0b1
+ MX6SLL_PAD_ECSPI1_MISO__UART5_DTE_CTS 0x1b0b1
+ >;
+ };
+
+ pinctrl_usdhc1: usdhc1grp {
+ fsl,pins = <
+ MX6SLL_PAD_SD1_CMD__SD1_CMD 0x17061
+ MX6SLL_PAD_SD1_CLK__SD1_CLK 0x13061
+ MX6SLL_PAD_SD1_DATA0__SD1_DATA0 0x17061
+ MX6SLL_PAD_SD1_DATA1__SD1_DATA1 0x17061
+ MX6SLL_PAD_SD1_DATA2__SD1_DATA2 0x17061
+ MX6SLL_PAD_SD1_DATA3__SD1_DATA3 0x17061
+ >;
+ };
+
+ pinctrl_usdhc1_100mhz: usdhc1grp_100mhz {
+ fsl,pins = <
+ MX6SLL_PAD_SD1_CMD__SD1_CMD 0x170a1
+ MX6SLL_PAD_SD1_CLK__SD1_CLK 0x130a1
+ MX6SLL_PAD_SD1_DATA0__SD1_DATA0 0x170a1
+ MX6SLL_PAD_SD1_DATA1__SD1_DATA1 0x170a1
+ MX6SLL_PAD_SD1_DATA2__SD1_DATA2 0x170a1
+ MX6SLL_PAD_SD1_DATA3__SD1_DATA3 0x170a1
+ >;
+ };
+
+ pinctrl_usdhc1_200mhz: usdhc1grp_200mhz {
+ fsl,pins = <
+ MX6SLL_PAD_SD1_CMD__SD1_CMD 0x170e9
+ MX6SLL_PAD_SD1_CLK__SD1_CLK 0x130f9
+ MX6SLL_PAD_SD1_DATA0__SD1_DATA0 0x170e9
+ MX6SLL_PAD_SD1_DATA1__SD1_DATA1 0x170e9
+ MX6SLL_PAD_SD1_DATA2__SD1_DATA2 0x170e9
+ MX6SLL_PAD_SD1_DATA3__SD1_DATA3 0x170e9
+ >;
+ };
+
+ pinctrl_usdhc2: usdhc2grp {
+ fsl,pins = <
+ MX6SLL_PAD_SD2_CMD__SD2_CMD 0x17059
+ MX6SLL_PAD_SD2_CLK__SD2_CLK 0x13059
+ MX6SLL_PAD_SD2_DATA0__SD2_DATA0 0x17059
+ MX6SLL_PAD_SD2_DATA1__SD2_DATA1 0x17059
+ MX6SLL_PAD_SD2_DATA2__SD2_DATA2 0x17059
+ MX6SLL_PAD_SD2_DATA3__SD2_DATA3 0x17059
+ MX6SLL_PAD_SD2_DATA4__SD2_DATA4 0x17059
+ MX6SLL_PAD_SD2_DATA5__SD2_DATA5 0x17059
+ MX6SLL_PAD_SD2_DATA6__SD2_DATA6 0x17059
+ MX6SLL_PAD_SD2_DATA7__SD2_DATA7 0x17059
+ MX6SLL_PAD_GPIO4_IO21__SD2_STROBE 0x413059
+ >;
+ };
+
+ pinctrl_usdhc2_100mhz: usdhc2grp_100mhz {
+ fsl,pins = <
+ MX6SLL_PAD_SD2_CMD__SD2_CMD 0x170b9
+ MX6SLL_PAD_SD2_CLK__SD2_CLK 0x130b9
+ MX6SLL_PAD_SD2_DATA0__SD2_DATA0 0x170b9
+ MX6SLL_PAD_SD2_DATA1__SD2_DATA1 0x170b9
+ MX6SLL_PAD_SD2_DATA2__SD2_DATA2 0x170b9
+ MX6SLL_PAD_SD2_DATA3__SD2_DATA3 0x170b9
+ MX6SLL_PAD_SD2_DATA4__SD2_DATA4 0x170b9
+ MX6SLL_PAD_SD2_DATA5__SD2_DATA5 0x170b9
+ MX6SLL_PAD_SD2_DATA6__SD2_DATA6 0x170b9
+ MX6SLL_PAD_SD2_DATA7__SD2_DATA7 0x170b9
+ MX6SLL_PAD_GPIO4_IO21__SD2_STROBE 0x4130b9
+ >;
+ };
+
+ pinctrl_usdhc2_200mhz: usdhc2grp_200mhz {
+ fsl,pins = <
+ MX6SLL_PAD_SD2_CMD__SD2_CMD 0x170f9
+ MX6SLL_PAD_SD2_CLK__SD2_CLK 0x130f9
+ MX6SLL_PAD_SD2_DATA0__SD2_DATA0 0x170f9
+ MX6SLL_PAD_SD2_DATA1__SD2_DATA1 0x170f9
+ MX6SLL_PAD_SD2_DATA2__SD2_DATA2 0x170f9
+ MX6SLL_PAD_SD2_DATA3__SD2_DATA3 0x170f9
+ MX6SLL_PAD_SD2_DATA4__SD2_DATA4 0x170f9
+ MX6SLL_PAD_SD2_DATA5__SD2_DATA5 0x170f9
+ MX6SLL_PAD_SD2_DATA6__SD2_DATA6 0x170f9
+ MX6SLL_PAD_SD2_DATA7__SD2_DATA7 0x170f9
+ MX6SLL_PAD_GPIO4_IO21__SD2_STROBE 0x4130f9
+ >;
+ };
+
+ pinctrl_usdhc3: usdhc3grp {
+ fsl,pins = <
+ MX6SLL_PAD_SD3_CMD__SD3_CMD 0x17061
+ MX6SLL_PAD_SD3_CLK__SD3_CLK 0x13061
+ MX6SLL_PAD_SD3_DATA0__SD3_DATA0 0x17061
+ MX6SLL_PAD_SD3_DATA1__SD3_DATA1 0x17061
+ MX6SLL_PAD_SD3_DATA2__SD3_DATA2 0x17061
+ MX6SLL_PAD_SD3_DATA3__SD3_DATA3 0x17061
+ >;
+ };
+
+ pinctrl_usdhc3_100mhz: usdhc3grp_100mhz {
+ fsl,pins = <
+ MX6SLL_PAD_SD3_CMD__SD3_CMD 0x170a1
+ MX6SLL_PAD_SD3_CLK__SD3_CLK 0x130a1
+ MX6SLL_PAD_SD3_DATA0__SD3_DATA0 0x170a1
+ MX6SLL_PAD_SD3_DATA1__SD3_DATA1 0x170a1
+ MX6SLL_PAD_SD3_DATA2__SD3_DATA2 0x170a1
+ MX6SLL_PAD_SD3_DATA3__SD3_DATA3 0x170a1
+ >;
+ };
+
+ pinctrl_usdhc3_200mhz: usdhc3grp_200mhz {
+ fsl,pins = <
+ MX6SLL_PAD_SD3_CMD__SD3_CMD 0x170e9
+ MX6SLL_PAD_SD3_CLK__SD3_CLK 0x130f9
+ MX6SLL_PAD_SD3_DATA0__SD3_DATA0 0x170e9
+ MX6SLL_PAD_SD3_DATA1__SD3_DATA1 0x170e9
+ MX6SLL_PAD_SD3_DATA2__SD3_DATA2 0x170e9
+ MX6SLL_PAD_SD3_DATA3__SD3_DATA3 0x170e9
+ >;
+ };
+
+ pinctrl_usbotg1: usbotg1grp {
+ fsl,pins = <
+ MX6SLL_PAD_EPDC_PWR_COM__USB_OTG1_ID 0x17059
+ >;
+ };
+
+ pinctrl_i2c1: i2c1grp {
+ fsl,pins = <
+ MX6SLL_PAD_I2C1_SCL__I2C1_SCL 0x4001b8b1
+ MX6SLL_PAD_I2C1_SDA__I2C1_SDA 0x4001b8b1
+ >;
+ };
+
+ pinctrl_i2c3: i2c3grp {
+ fsl,pins = <
+ MX6SLL_PAD_AUD_RXFS__I2C3_SCL 0x4041b8b1
+ MX6SLL_PAD_AUD_RXC__I2C3_SDA 0x4041b8b1
+ >;
+ };
+
+ pinctrl_pwm1: pmw1grp {
+ fsl,pins = <
+ MX6SLL_PAD_PWM1__PWM1_OUT 0x110b0
+ >;
+ };
+
+ pinctrl_wdog1: wdog1grp {
+ fsl,pins = <
+ MX6SLL_PAD_WDOG_B__WDOG1_B 0x170b0
+ >;
+ };
+ };
+};
+
+&lcdif {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lcdif_dat
+ &pinctrl_lcdif_ctrl>;
+ lcd-supply = <&reg_lcd>;
+ display = <&display0>;
+ status = "okay";
+
+ display0: display@0 {
+ bits-per-pixel = <16>;
+ bus-width = <24>;
+
+ display-timings {
+ native-mode = <&timing0>;
+ timing0: timing0 {
+ clock-frequency = <33500000>;
+ hactive = <800>;
+ vactive = <480>;
+ hback-porch = <89>;
+ hfront-porch = <164>;
+ vback-porch = <23>;
+ vfront-porch = <10>;
+ hsync-len = <10>;
+ vsync-len = <10>;
+ hsync-active = <0>;
+ vsync-active = <0>;
+ de-active = <1>;
+ pixelclk-active = <0>;
+ };
+ };
+ };
+};
+
+&pxp {
+ status = "okay";
+};
+
+&pwm1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pwm1>;
+ status = "okay";
+};
+
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart1>;
+ status = "okay";
+};
+
+&uart5 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart5>;
+ fsl,uart-has-rtscts;
+ /* for DTE mode, add below change */
+ /* fsl,dte-mode; */
+ /* pinctrl-0 = <&pinctrl_uart5dte>; */
+ status = "disabled";
+};
+
+&usdhc1 {
+ pinctrl-names = "default", "state_100mhz", "state_200mhz";
+ pinctrl-0 = <&pinctrl_usdhc1>;
+ pinctrl-1 = <&pinctrl_usdhc1_100mhz>;
+ pinctrl-2 = <&pinctrl_usdhc1_200mhz>;
+ cd-gpios = <&gpio4 7 GPIO_ACTIVE_LOW>;
+ wp-gpios = <&gpio4 22 GPIO_ACTIVE_HIGH>;
+ keep-power-in-suspend;
+ enable-sdio-wakeup;
+ vmmc-supply = <&reg_sd1_vmmc>;
+ status = "okay";
+};
+
+&usdhc2 {
+ pinctrl-names = "default", "state_100mhz", "state_200mhz";
+ pinctrl-0 = <&pinctrl_usdhc2>;
+ pinctrl-1 = <&pinctrl_usdhc2_100mhz>;
+ pinctrl-2 = <&pinctrl_usdhc2_200mhz>;
+ vqmmc-supply = <&reg_sd2_vmmc>;
+ bus-width = <8>;
+ no-removable;
+ status = "okay";
+};
+
+&usdhc3 {
+ pinctrl-names = "default", "state_100mhz", "state_200mhz";
+ pinctrl-0 = <&pinctrl_usdhc3>;
+ pinctrl-1 = <&pinctrl_usdhc3_100mhz>;
+ pinctrl-2 = <&pinctrl_usdhc3_200mhz>;
+ cd-gpios = <&gpio3 22 GPIO_ACTIVE_LOW>;
+ keep-power-in-suspend;
+ enable-sdio-wakeup;
+ vmmc-supply = <&reg_sd3_vmmc>;
+ status = "okay";
+};
+
+&usbotg1 {
+ vbus-supply = <&reg_usb_otg1_vbus>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usbotg1>;
+ disable-over-current;
+ srp-disable;
+ hnp-disable;
+ adp-disable;
+ status = "okay";
+};
+
+&usbotg2 {
+ vbus-supply = <&reg_usb_otg2_vbus>;
+ dr_mode = "host";
+ disable-over-current;
+ status = "okay";
+};
+
+&epdc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_epdc0>;
+ V3P3-supply = <&V3P3_reg>;
+ VCOM-supply = <&VCOM_reg>;
+ DISPLAY-supply = <&DISPLAY_reg>;
+ status = "okay";
+};
+
+&ssi2 {
+ status = "okay";
+};
+
+&wdog1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_wdog1>;
+ fsl,ext-reset-output;
+};
diff --git a/arch/arm/boot/dts/imx6sll-lpddr2-arm2.dts b/arch/arm/boot/dts/imx6sll-lpddr2-arm2.dts
new file mode 100644
index 000000000000..33f230f9c972
--- /dev/null
+++ b/arch/arm/boot/dts/imx6sll-lpddr2-arm2.dts
@@ -0,0 +1,10 @@
+/*
+ * Copyright (C) 2016 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 "imx6sll-lpddr3-arm2.dts"
+
diff --git a/arch/arm/boot/dts/imx6sll-lpddr3-arm2-csi.dts b/arch/arm/boot/dts/imx6sll-lpddr3-arm2-csi.dts
new file mode 100644
index 000000000000..59a0c0223610
--- /dev/null
+++ b/arch/arm/boot/dts/imx6sll-lpddr3-arm2-csi.dts
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2016 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 "imx6sll-lpddr3-arm2.dts"
+
+&csi {
+ status = "okay";
+};
+
+&epdc {
+ status = "disabled";
+};
+
+&ov5640 {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx6sll-lpddr3-arm2-ecspi.dts b/arch/arm/boot/dts/imx6sll-lpddr3-arm2-ecspi.dts
new file mode 100644
index 000000000000..d1facfc26f7c
--- /dev/null
+++ b/arch/arm/boot/dts/imx6sll-lpddr3-arm2-ecspi.dts
@@ -0,0 +1,17 @@
+/*
+ * Copyright (C) 2016 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 "imx6sll-lpddr3-arm2.dts"
+
+&ecspi1 {
+ status = "okay";
+};
+
+&lcdif {
+ status = "disabled";
+};
diff --git a/arch/arm/boot/dts/imx6sll-lpddr3-arm2-spdif.dts b/arch/arm/boot/dts/imx6sll-lpddr3-arm2-spdif.dts
new file mode 100644
index 000000000000..5bcbc0170ac2
--- /dev/null
+++ b/arch/arm/boot/dts/imx6sll-lpddr3-arm2-spdif.dts
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2016 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 "imx6sll-lpddr3-arm2.dts"
+
+/ {
+
+ sound-spdif {
+ compatible = "fsl,imx-audio-spdif",
+ "fsl,imx6sl-evk-spdif";
+ model = "imx-spdif";
+ spdif-controller = <&spdif>;
+ spdif-out;
+ };
+};
+
+
+&iomuxc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_hog>;
+};
+
+&spdif {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_spdif>;
+ assigned-clocks = <&clks IMX6SLL_CLK_SPDIF_SEL>,
+ <&clks IMX6SLL_CLK_SPDIF_PODF>;
+ assigned-clock-parents = <&clks IMX6SLL_CLK_PLL4_AUDIO_DIV>;
+ assigned-clock-rates = <0>, <98304000>;
+ status = "okay";
+};
+
+&usdhc2 {
+ status = "disabled";
+};
+
+
diff --git a/arch/arm/boot/dts/imx6sll-lpddr3-arm2.dts b/arch/arm/boot/dts/imx6sll-lpddr3-arm2.dts
new file mode 100644
index 000000000000..dd05117e5167
--- /dev/null
+++ b/arch/arm/boot/dts/imx6sll-lpddr3-arm2.dts
@@ -0,0 +1,836 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017 NXP.
+ *
+ * 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 <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include "imx6sll.dtsi"
+
+/ {
+ model = "Freescale i.MX6SLL LPDDR3 ARM2 Board";
+ compatible = "fsl,imx6sll-lpddr3-arm2", "fsl,imx6sll";
+
+ memory {
+ reg = <0x80000000 0x80000000>;
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_led>;
+
+ users {
+ label = "debug";
+ gpios = <&gpio2 4 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "heartbeat";
+ };
+ };
+
+ backlight {
+ compatible = "pwm-backlight";
+ pwms = <&pwm1 0 5000000>;
+ brightness-levels = <0 4 8 16 32 64 128 255>;
+ default-brightness-level = <6>;
+ status = "okay";
+ };
+
+ pxp_v4l2_out {
+ compatible = "fsl,imx6sl-pxp-v4l2";
+ status = "okay";
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ reg_usb_otg1_vbus: regulator@0 {
+ compatible = "regulator-fixed";
+ reg = <0>;
+ regulator-name = "usb_otg1_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&gpio4 0 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ vin-supply = <&swbst_reg>;
+ };
+
+ reg_usb_otg2_vbus: regulator@1 {
+ compatible = "regulator-fixed";
+ reg = <1>;
+ regulator-name = "usb_otg2_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&gpio4 2 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ vin-supply = <&swbst_reg>;
+ };
+
+ reg_aud3v: regulator@2 {
+ compatible = "regulator-fixed";
+ reg = <2>;
+ regulator-name = "wm8962-supply-3v15";
+ regulator-min-microvolt = <3150000>;
+ regulator-max-microvolt = <3150000>;
+ regulator-boot-on;
+ };
+
+ reg_aud4v: regulator@3 {
+ compatible = "regulator-fixed";
+ reg = <3>;
+ regulator-name = "wm8962-supply-4v2";
+ regulator-min-microvolt = <4325000>;
+ regulator-max-microvolt = <4325000>;
+ regulator-boot-on;
+ };
+
+ reg_lcd: regulator@4 {
+ compatible = "regulator-fixed";
+ reg = <4>;
+ regulator-name = "lcd-pwr";
+ gpio = <&gpio4 8 0>;
+ enable-active-high;
+ };
+
+ reg_sd1_vmmc: sd1_vmmc {
+ compatible = "regulator-fixed";
+ regulator-name = "SD1_SPWR";
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ gpio = <&gpio3 30 GPIO_ACTIVE_HIGH>;
+ off-on-delay = <20000>;
+ enable-active-high;
+ };
+
+ reg_sd2_vmmc: sd2_vmmc {
+ compatible = "regulator-fixed";
+ regulator-name = "eMMC_VCCQ";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-boot-on;
+ };
+
+ reg_sd3_vmmc: sd3_vmmc {
+ compatible = "regulator-fixed";
+ regulator-name = "SD3_WIFI";
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ gpio = <&gpio4 4 GPIO_ACTIVE_HIGH>;
+ off-on-delay = <20000>;
+ enable-active-high;
+ };
+
+ };
+
+ sound {
+ compatible = "fsl,imx6sl-evk-wm8962", "fsl,imx-audio-wm8962";
+ model = "wm8962-audio";
+ cpu-dai = <&ssi2>;
+ audio-codec = <&codec>;
+ audio-routing =
+ "Headphone Jack", "HPOUTL",
+ "Headphone Jack", "HPOUTR",
+ "Ext Spk", "SPKOUTL",
+ "Ext Spk", "SPKOUTR",
+ "AMIC", "MICBIAS",
+ "IN3R", "AMIC";
+ mux-int-port = <2>;
+ mux-ext-port = <3>;
+ codec-master;
+ hp-det-gpios = <&gpio4 24 1>;
+ };
+};
+
+&audmux {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_audmux3>;
+ status = "okay";
+};
+
+&clks {
+ assigned-clocks = <&clks IMX6SLL_CLK_PLL4_AUDIO_DIV>;
+ assigned-clock-rates = <393216000>;
+};
+
+&cpu0 {
+ arm-supply = <&sw1a_reg>;
+ soc-supply = <&sw1c_reg>;
+};
+
+&csi {
+ status = "disabled";
+
+ port {
+ csi1_ep: endpoint {
+ remote-endpoint = <&ov5640_ep>;
+ };
+ };
+};
+
+&i2c1 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c1>;
+ status = "okay";
+
+ pmic: pfuze100@08 {
+ compatible = "fsl,pfuze100";
+ reg = <0x08>;
+
+ regulators {
+ sw1a_reg: sw1ab {
+ regulator-min-microvolt = <300000>;
+ regulator-max-microvolt = <1875000>;
+ regulator-boot-on;
+ regulator-always-on;
+ regulator-ramp-delay = <6250>;
+ };
+
+ sw1c_reg: sw1c {
+ regulator-min-microvolt = <300000>;
+ regulator-max-microvolt = <1875000>;
+ regulator-boot-on;
+ regulator-always-on;
+ regulator-ramp-delay = <6250>;
+ };
+
+ sw2_reg: sw2 {
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ sw3a_reg: sw3a {
+ regulator-min-microvolt = <400000>;
+ regulator-max-microvolt = <1975000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ sw3b_reg: sw3b {
+ regulator-min-microvolt = <400000>;
+ regulator-max-microvolt = <1975000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ sw4_reg: sw4 {
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ swbst_reg: swbst {
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5150000>;
+ };
+
+ snvs_reg: vsnvs {
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ vref_reg: vrefddr {
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ vgen1_reg: vgen1 {
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1550000>;
+ regulator-always-on;
+ };
+
+ vgen2_reg: vgen2 {
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1550000>;
+ };
+
+ vgen3_reg: vgen3 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ vgen4_reg: vgen4 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ vgen5_reg: vgen5 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ vgen6_reg: vgen6 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+ };
+ };
+
+ max17135: max17135@48 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_max17135>;
+ compatible = "maxim,max17135";
+ reg = <0x48>;
+ status = "okay";
+
+ vneg_pwrup = <1>;
+ gvee_pwrup = <2>;
+ vpos_pwrup = <10>;
+ gvdd_pwrup = <12>;
+ gvdd_pwrdn = <1>;
+ vpos_pwrdn = <2>;
+ gvee_pwrdn = <8>;
+ vneg_pwrdn = <10>;
+ gpio_pmic_pwrgood = <&gpio2 13 0>;
+ gpio_pmic_vcom_ctrl = <&gpio2 3 0>;
+ gpio_pmic_wakeup = <&gpio2 14 0>;
+ gpio_pmic_v3p3 = <&gpio2 7 0>;
+ gpio_pmic_intr = <&gpio2 12 0>;
+
+ regulators {
+ DISPLAY_reg: DISPLAY {
+ regulator-name = "DISPLAY";
+ };
+
+ GVDD_reg: GVDD {
+ /* 20v */
+ regulator-name = "GVDD";
+ };
+
+ GVEE_reg: GVEE {
+ /* -22v */
+ regulator-name = "GVEE";
+ };
+
+ HVINN_reg: HVINN {
+ /* -22v */
+ regulator-name = "HVINN";
+ };
+
+ HVINP_reg: HVINP {
+ /* 20v */
+ regulator-name = "HVINP";
+ };
+
+ VCOM_reg: VCOM {
+ regulator-name = "VCOM";
+ /* Real max value: -500000 */
+ regulator-max-microvolt = <4325000>;
+ /* Real min value: -4325000 */
+ regulator-min-microvolt = <500000>;
+ };
+
+ VNEG_reg: VNEG {
+ /* -15v */
+ regulator-name = "VNEG";
+ };
+
+ VPOS_reg: VPOS {
+ /* 15v */
+ regulator-name = "VPOS";
+ };
+
+ V3P3_reg: V3P3 {
+ regulator-name = "V3P3";
+ };
+ };
+ };
+};
+
+&i2c3 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c3>;
+ status = "okay";
+
+ codec: wm8962@1a {
+ compatible = "wlf,wm8962";
+ reg = <0x1a>;
+ clocks = <&clks IMX6SLL_CLK_EXTERN_AUDIO>;
+ DCVDD-supply = <&vgen3_reg>;
+ DBVDD-supply = <&reg_aud3v>;
+ AVDD-supply = <&vgen3_reg>;
+ CPVDD-supply = <&vgen3_reg>;
+ MICVDD-supply = <&reg_aud3v>;
+ PLLVDD-supply = <&vgen3_reg>;
+ SPKVDD1-supply = <&reg_aud4v>;
+ SPKVDD2-supply = <&reg_aud4v>;
+ amic-mono;
+ };
+
+ ov5640: ov5640@3c {
+ compatible = "ovti,ov5640";
+ reg = <0x3c>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_csi1>;
+ clocks = <&clks IMX6SLL_CLK_CSI>;
+ clock-names = "csi_mclk";
+ AVDD-supply = <&vgen6_reg>; /* 2.8v */
+ DVDD-supply = <&vgen2_reg>; /* 1.5v*/
+ pwn-gpios = <&gpio1 25 1>;
+ rst-gpios = <&gpio1 26 0>;
+ csi_id = <0>;
+ mclk = <24000000>;
+ mclk_source = <0>;
+ status = "disabled";
+ port {
+ ov5640_ep: endpoint {
+ remote-endpoint = <&csi1_ep>;
+ };
+ };
+ };
+};
+
+&gpc {
+ fsl,ldo-bypass = <1>;
+};
+
+&iomuxc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_hog &pinctrl_hog_sd2_reset>;
+
+ imx6sll-lpddr3-arm2 {
+ pinctrl_hog: hoggrp {
+ fsl,pins = <
+ MX6SLL_PAD_KEY_ROW7__GPIO4_IO07 0x17059
+ MX6SLL_PAD_GPIO4_IO22__GPIO4_IO22 0x17059
+ MX6SLL_PAD_KEY_COL3__GPIO3_IO30 0x17059
+ MX6SLL_PAD_KEY_COL4__GPIO4_IO00 0x17059
+ MX6SLL_PAD_REF_CLK_32K__GPIO3_IO22 0x17059 /* SD3 CD */
+ MX6SLL_PAD_KEY_COL6__GPIO4_IO04 0x17059 /*SD3 RESET */
+ MX6SLL_PAD_KEY_COL5__GPIO4_IO02 0x17059
+ MX6SLL_PAD_GPIO4_IO24__GPIO4_IO24 0x17059 /* HP DETECT */
+ >;
+ };
+
+ pinctrl_hog_sd2_reset: hoggrp-1 {
+ fsl,pins = <
+ MX6SLL_PAD_SD2_RESET__GPIO4_IO27 0x417059
+ >;
+ };
+
+ pinctrl_audmux3: audmux3grp {
+ fsl,pins = <
+ MX6SLL_PAD_AUD_TXC__AUD3_TXC 0x4130b0
+ MX6SLL_PAD_AUD_TXFS__AUD3_TXFS 0x4130b0
+ MX6SLL_PAD_AUD_TXD__AUD3_TXD 0x4110b0
+ MX6SLL_PAD_AUD_RXD__AUD3_RXD 0x4130b0
+ MX6SLL_PAD_AUD_MCLK__AUDIO_CLK_OUT 0x4130b0
+ >;
+ };
+
+ pinctrl_csi1: csi1grp {
+ fsl,pins = <
+ MX6SLL_PAD_EPDC_GDRL__CSI_MCLK 0x1b088
+ MX6SLL_PAD_EPDC_GDCLK__CSI_PIXCLK 0x1b088
+ MX6SLL_PAD_EPDC_GDSP__CSI_VSYNC 0x1b088
+ MX6SLL_PAD_EPDC_GDOE__CSI_HSYNC 0x1b088
+ MX6SLL_PAD_EPDC_DATA02__CSI_DATA02 0x1b088
+ MX6SLL_PAD_EPDC_DATA03__CSI_DATA03 0x1b088
+ MX6SLL_PAD_EPDC_DATA04__CSI_DATA04 0x1b088
+ MX6SLL_PAD_EPDC_DATA05__CSI_DATA05 0x1b088
+ MX6SLL_PAD_EPDC_DATA06__CSI_DATA06 0x1b088
+ MX6SLL_PAD_EPDC_DATA07__CSI_DATA07 0x1b088
+ MX6SLL_PAD_EPDC_SDCLK__CSI_DATA08 0x1b088
+ MX6SLL_PAD_EPDC_SDLE__CSI_DATA09 0x1b088
+ MX6SLL_PAD_EPDC_SDSHR__GPIO1_IO26 0x80000000
+ MX6SLL_PAD_EPDC_SDOE__GPIO1_IO25 0x80000000
+ >;
+ };
+
+ pinctrl_led: ledgrp {
+ fsl,pins = <
+ MX6SLL_PAD_EPDC_VCOM1__GPIO2_IO04 0x17059
+ >;
+ };
+
+ pinctrl_epdc0: epdcgrp0 {
+ fsl,pins = <
+ MX6SLL_PAD_EPDC_DATA00__EPDC_DATA00 0x100b1
+ MX6SLL_PAD_EPDC_DATA01__EPDC_DATA01 0x100b1
+ MX6SLL_PAD_EPDC_DATA02__EPDC_DATA02 0x100b1
+ MX6SLL_PAD_EPDC_DATA03__EPDC_DATA03 0x100b1
+ MX6SLL_PAD_EPDC_DATA04__EPDC_DATA04 0x100b1
+ MX6SLL_PAD_EPDC_DATA05__EPDC_DATA05 0x100b1
+ MX6SLL_PAD_EPDC_DATA06__EPDC_DATA06 0x100b1
+ MX6SLL_PAD_EPDC_DATA07__EPDC_DATA07 0x100b1
+ MX6SLL_PAD_EPDC_DATA08__EPDC_DATA08 0x100b1
+ MX6SLL_PAD_EPDC_DATA09__EPDC_DATA09 0x100b1
+ MX6SLL_PAD_EPDC_DATA10__EPDC_DATA10 0x100b1
+ MX6SLL_PAD_EPDC_DATA11__EPDC_DATA11 0x100b1
+ MX6SLL_PAD_EPDC_DATA12__EPDC_DATA12 0x100b1
+ MX6SLL_PAD_EPDC_DATA13__EPDC_DATA13 0x100b1
+ MX6SLL_PAD_EPDC_DATA14__EPDC_DATA14 0x100b1
+ MX6SLL_PAD_EPDC_DATA15__EPDC_DATA15 0x100b1
+ MX6SLL_PAD_EPDC_SDCLK__EPDC_SDCLK_P 0x100b1
+ MX6SLL_PAD_EPDC_SDLE__EPDC_SDLE 0x100b1
+ MX6SLL_PAD_EPDC_SDOE__EPDC_SDOE 0x100b1
+ MX6SLL_PAD_EPDC_SDSHR__EPDC_SDSHR 0x100b1
+ MX6SLL_PAD_EPDC_SDCE0__EPDC_SDCE0 0x100b1
+ MX6SLL_PAD_EPDC_GDCLK__EPDC_GDCLK 0x100b1
+ MX6SLL_PAD_EPDC_GDOE__EPDC_GDOE 0x100b1
+ MX6SLL_PAD_EPDC_GDRL__EPDC_GDRL 0x100b1
+ MX6SLL_PAD_EPDC_GDSP__EPDC_GDSP 0x100b1
+ >;
+ };
+
+ pinctrl_lcdif_dat: lcdifdatgrp {
+ fsl,pins = <
+ MX6SLL_PAD_LCD_DATA00__LCD_DATA00 0x79
+ MX6SLL_PAD_LCD_DATA01__LCD_DATA01 0x79
+ MX6SLL_PAD_LCD_DATA02__LCD_DATA02 0x79
+ MX6SLL_PAD_LCD_DATA03__LCD_DATA03 0x79
+ MX6SLL_PAD_LCD_DATA04__LCD_DATA04 0x79
+ MX6SLL_PAD_LCD_DATA05__LCD_DATA05 0x79
+ MX6SLL_PAD_LCD_DATA06__LCD_DATA06 0x79
+ MX6SLL_PAD_LCD_DATA07__LCD_DATA07 0x79
+ MX6SLL_PAD_LCD_DATA08__LCD_DATA08 0x79
+ MX6SLL_PAD_LCD_DATA09__LCD_DATA09 0x79
+ MX6SLL_PAD_LCD_DATA10__LCD_DATA10 0x79
+ MX6SLL_PAD_LCD_DATA11__LCD_DATA11 0x79
+ MX6SLL_PAD_LCD_DATA12__LCD_DATA12 0x79
+ MX6SLL_PAD_LCD_DATA13__LCD_DATA13 0x79
+ MX6SLL_PAD_LCD_DATA14__LCD_DATA14 0x79
+ MX6SLL_PAD_LCD_DATA15__LCD_DATA15 0x79
+ MX6SLL_PAD_LCD_DATA16__LCD_DATA16 0x79
+ MX6SLL_PAD_LCD_DATA17__LCD_DATA17 0x79
+ MX6SLL_PAD_LCD_DATA18__LCD_DATA18 0x79
+ MX6SLL_PAD_LCD_DATA19__LCD_DATA19 0x79
+ MX6SLL_PAD_LCD_DATA20__LCD_DATA20 0x79
+ MX6SLL_PAD_LCD_DATA21__LCD_DATA21 0x79
+ MX6SLL_PAD_LCD_DATA22__LCD_DATA22 0x79
+ MX6SLL_PAD_LCD_DATA23__LCD_DATA23 0x79
+ >;
+ };
+
+ pinctrl_lcdif_ctrl: lcdifctrlgrp {
+ fsl,pins = <
+ MX6SLL_PAD_LCD_CLK__LCD_CLK 0x79
+ MX6SLL_PAD_LCD_ENABLE__LCD_ENABLE 0x79
+ MX6SLL_PAD_LCD_HSYNC__LCD_HSYNC 0x79
+ MX6SLL_PAD_LCD_VSYNC__LCD_VSYNC 0x79
+ MX6SLL_PAD_LCD_RESET__LCD_RESET 0x79
+ MX6SLL_PAD_ECSPI1_SCLK__GPIO4_IO08 0x79
+ >;
+ };
+
+ pinctrl_max17135: max17135grp-1 {
+ fsl,pins = <
+ MX6SLL_PAD_EPDC_PWR_STAT__GPIO2_IO13 0x80000000 /* pwrgood */
+ MX6SLL_PAD_EPDC_VCOM0__GPIO2_IO03 0x80000000 /* vcom_ctrl */
+ MX6SLL_PAD_EPDC_PWR_WAKE__GPIO2_IO14 0x80000000 /* wakeup */
+ MX6SLL_PAD_EPDC_PWR_CTRL0__GPIO2_IO07 0x80000000 /* v3p3 */
+ MX6SLL_PAD_EPDC_PWR_IRQ__GPIO2_IO12 0x80000000 /* pwr int */
+ >;
+ };
+
+ pinctrl_spdif: spdifgrp {
+ fsl,pins = <
+ MX6SLL_PAD_SD2_RESET__SPDIF_OUT 0x4130b0
+ >;
+ };
+
+ pinctrl_uart1: uart1grp {
+ fsl,pins = <
+ MX6SLL_PAD_UART1_TXD__UART1_DCE_TX 0x1b0b1
+ MX6SLL_PAD_UART1_RXD__UART1_DCE_RX 0x1b0b1
+ >;
+ };
+
+ pinctrl_usdhc1: usdhc1grp {
+ fsl,pins = <
+ MX6SLL_PAD_SD1_CMD__SD1_CMD 0x17059
+ MX6SLL_PAD_SD1_CLK__SD1_CLK 0x17059
+ MX6SLL_PAD_SD1_DATA0__SD1_DATA0 0x17059
+ MX6SLL_PAD_SD1_DATA1__SD1_DATA1 0x17059
+ MX6SLL_PAD_SD1_DATA2__SD1_DATA2 0x17059
+ MX6SLL_PAD_SD1_DATA3__SD1_DATA3 0x17059
+ >;
+ };
+
+ pinctrl_usdhc1_100mhz: usdhc1grp_100mhz {
+ fsl,pins = <
+ MX6SLL_PAD_SD1_CMD__SD1_CMD 0x170b9
+ MX6SLL_PAD_SD1_CLK__SD1_CLK 0x170b9
+ MX6SLL_PAD_SD1_DATA0__SD1_DATA0 0x170b9
+ MX6SLL_PAD_SD1_DATA1__SD1_DATA1 0x170b9
+ MX6SLL_PAD_SD1_DATA2__SD1_DATA2 0x170b9
+ MX6SLL_PAD_SD1_DATA3__SD1_DATA3 0x170b9
+ >;
+ };
+
+ pinctrl_usdhc1_200mhz: usdhc1grp_200mhz {
+ fsl,pins = <
+ MX6SLL_PAD_SD1_CMD__SD1_CMD 0x170f9
+ MX6SLL_PAD_SD1_CLK__SD1_CLK 0x170f9
+ MX6SLL_PAD_SD1_DATA0__SD1_DATA0 0x170f9
+ MX6SLL_PAD_SD1_DATA1__SD1_DATA1 0x170f9
+ MX6SLL_PAD_SD1_DATA2__SD1_DATA2 0x170f9
+ MX6SLL_PAD_SD1_DATA3__SD1_DATA3 0x170f9
+ >;
+ };
+
+ pinctrl_usdhc2: usdhc2grp {
+ fsl,pins = <
+ MX6SLL_PAD_SD2_CMD__SD2_CMD 0x17059
+ MX6SLL_PAD_SD2_CLK__SD2_CLK 0x13059
+ MX6SLL_PAD_SD2_DATA0__SD2_DATA0 0x17059
+ MX6SLL_PAD_SD2_DATA1__SD2_DATA1 0x17059
+ MX6SLL_PAD_SD2_DATA2__SD2_DATA2 0x17059
+ MX6SLL_PAD_SD2_DATA3__SD2_DATA3 0x17059
+ MX6SLL_PAD_SD2_DATA4__SD2_DATA4 0x17059
+ MX6SLL_PAD_SD2_DATA5__SD2_DATA5 0x17059
+ MX6SLL_PAD_SD2_DATA6__SD2_DATA6 0x17059
+ MX6SLL_PAD_SD2_DATA7__SD2_DATA7 0x17059
+ MX6SLL_PAD_GPIO4_IO21__SD2_STROBE 0x413059
+ >;
+ };
+
+ pinctrl_usdhc2_100mhz: usdhc2grp_100mhz {
+ fsl,pins = <
+ MX6SLL_PAD_SD2_CMD__SD2_CMD 0x170b9
+ MX6SLL_PAD_SD2_CLK__SD2_CLK 0x130b9
+ MX6SLL_PAD_SD2_DATA0__SD2_DATA0 0x170b9
+ MX6SLL_PAD_SD2_DATA1__SD2_DATA1 0x170b9
+ MX6SLL_PAD_SD2_DATA2__SD2_DATA2 0x170b9
+ MX6SLL_PAD_SD2_DATA3__SD2_DATA3 0x170b9
+ MX6SLL_PAD_SD2_DATA4__SD2_DATA4 0x170b9
+ MX6SLL_PAD_SD2_DATA5__SD2_DATA5 0x170b9
+ MX6SLL_PAD_SD2_DATA6__SD2_DATA6 0x170b9
+ MX6SLL_PAD_SD2_DATA7__SD2_DATA7 0x170b9
+ MX6SLL_PAD_GPIO4_IO21__SD2_STROBE 0x4130b9
+ >;
+ };
+
+ pinctrl_usdhc2_200mhz: usdhc2grp_200mhz {
+ fsl,pins = <
+ MX6SLL_PAD_SD2_CMD__SD2_CMD 0x170f9
+ MX6SLL_PAD_SD2_CLK__SD2_CLK 0x130f9
+ MX6SLL_PAD_SD2_DATA0__SD2_DATA0 0x170f9
+ MX6SLL_PAD_SD2_DATA1__SD2_DATA1 0x170f9
+ MX6SLL_PAD_SD2_DATA2__SD2_DATA2 0x170f9
+ MX6SLL_PAD_SD2_DATA3__SD2_DATA3 0x170f9
+ MX6SLL_PAD_SD2_DATA4__SD2_DATA4 0x170f9
+ MX6SLL_PAD_SD2_DATA5__SD2_DATA5 0x170f9
+ MX6SLL_PAD_SD2_DATA6__SD2_DATA6 0x170f9
+ MX6SLL_PAD_SD2_DATA7__SD2_DATA7 0x170f9
+ MX6SLL_PAD_GPIO4_IO21__SD2_STROBE 0x4130f9
+ >;
+ };
+ pinctrl_usdhc3: usdhc3grp {
+ fsl,pins = <
+ MX6SLL_PAD_SD3_CMD__SD3_CMD 0x17059
+ MX6SLL_PAD_SD3_CLK__SD3_CLK 0x17059
+ MX6SLL_PAD_SD3_DATA0__SD3_DATA0 0x17059
+ MX6SLL_PAD_SD3_DATA1__SD3_DATA1 0x17059
+ MX6SLL_PAD_SD3_DATA2__SD3_DATA2 0x17059
+ MX6SLL_PAD_SD3_DATA3__SD3_DATA3 0x17059
+ >;
+ };
+
+ pinctrl_usdhc3_100mhz: usdhc3grp_100mhz {
+ fsl,pins = <
+ MX6SLL_PAD_SD3_CMD__SD3_CMD 0x170b9
+ MX6SLL_PAD_SD3_CLK__SD3_CLK 0x170b9
+ MX6SLL_PAD_SD3_DATA0__SD3_DATA0 0x170b9
+ MX6SLL_PAD_SD3_DATA1__SD3_DATA1 0x170b9
+ MX6SLL_PAD_SD3_DATA2__SD3_DATA2 0x170b9
+ MX6SLL_PAD_SD3_DATA3__SD3_DATA3 0x170b9
+ >;
+ };
+
+ pinctrl_usdhc3_200mhz: usdhc3grp_200mhz {
+ fsl,pins = <
+ MX6SLL_PAD_SD3_CMD__SD3_CMD 0x170f9
+ MX6SLL_PAD_SD3_CLK__SD3_CLK 0x170f9
+ MX6SLL_PAD_SD3_DATA0__SD3_DATA0 0x170f9
+ MX6SLL_PAD_SD3_DATA1__SD3_DATA1 0x170f9
+ MX6SLL_PAD_SD3_DATA2__SD3_DATA2 0x170f9
+ MX6SLL_PAD_SD3_DATA3__SD3_DATA3 0x170f9
+ >;
+ };
+
+ pinctrl_usbotg1: usbotg1grp {
+ fsl,pins = <
+ MX6SLL_PAD_EPDC_PWR_COM__USB_OTG1_ID 0x17059
+ >;
+ };
+
+ pinctrl_i2c1: i2c1grp {
+ fsl,pins = <
+ MX6SLL_PAD_I2C1_SCL__I2C1_SCL 0x4001b8b1
+ MX6SLL_PAD_I2C1_SDA__I2C1_SDA 0x4001b8b1
+ >;
+ };
+
+ pinctrl_i2c3: i2c3grp {
+ fsl,pins = <
+ MX6SLL_PAD_EPDC_SDCE2__I2C3_SCL 0x4041b8b1
+ MX6SLL_PAD_EPDC_SDCE3__I2C3_SDA 0x4041b8b1
+ >;
+ };
+
+ pinctrl_pwm1: pmw1grp {
+ fsl,pins = <
+ MX6SLL_PAD_PWM1__PWM1_OUT 0x110b0
+ >;
+ };
+
+ pinctrl_ecspi1: ecspi1grp {
+ fsl,pins = <
+ MX6SLL_PAD_ECSPI1_MISO__ECSPI1_MISO 0x100b1
+ MX6SLL_PAD_ECSPI1_MOSI__ECSPI1_MOSI 0x100b1
+ MX6SLL_PAD_ECSPI1_SCLK__ECSPI1_SCLK 0x100b1
+ MX6SLL_PAD_ECSPI1_SS0__GPIO4_IO11 0x100b1
+ >;
+ };
+ };
+};
+
+&lcdif {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lcdif_dat
+ &pinctrl_lcdif_ctrl>;
+ lcd-supply = <&reg_lcd>;
+ display = <&display0>;
+ status = "okay";
+
+ display0: display@0 {
+ bits-per-pixel = <16>;
+ bus-width = <24>;
+
+ display-timings {
+ native-mode = <&timing0>;
+ timing0: timing0 {
+ clock-frequency = <33500000>;
+ hactive = <800>;
+ vactive = <480>;
+ hback-porch = <89>;
+ hfront-porch = <164>;
+ vback-porch = <23>;
+ vfront-porch = <10>;
+ hsync-len = <10>;
+ vsync-len = <10>;
+ hsync-active = <0>;
+ vsync-active = <0>;
+ de-active = <1>;
+ pixelclk-active = <0>;
+ };
+ };
+ };
+};
+
+&pxp {
+ status = "okay";
+};
+
+&pwm1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pwm1>;
+ status = "okay";
+};
+
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart1>;
+ status = "okay";
+};
+
+&usdhc1 {
+ pinctrl-names = "default", "state_100mhz", "state_200mhz";
+ pinctrl-0 = <&pinctrl_usdhc1>;
+ pinctrl-1 = <&pinctrl_usdhc1_100mhz>;
+ pinctrl-2 = <&pinctrl_usdhc1_200mhz>;
+ cd-gpios = <&gpio4 7 GPIO_ACTIVE_LOW>;
+ wp-gpios = <&gpio4 22 GPIO_ACTIVE_HIGH>;
+ keep-power-in-suspend;
+ enable-sdio-wakeup;
+ vmmc-supply = <&reg_sd1_vmmc>;
+ status = "okay";
+};
+
+&usdhc2 {
+ pinctrl-names = "default", "state_100mhz", "state_200mhz";
+ pinctrl-0 = <&pinctrl_usdhc2>;
+ pinctrl-1 = <&pinctrl_usdhc2_100mhz>;
+ pinctrl-2 = <&pinctrl_usdhc2_200mhz>;
+ vqmmc-supply = <&reg_sd2_vmmc>;
+ bus-width = <8>;
+ no-removable;
+ status = "okay";
+};
+
+&usdhc3 {
+ pinctrl-names = "default", "state_100mhz", "state_200mhz";
+ pinctrl-0 = <&pinctrl_usdhc3>;
+ pinctrl-1 = <&pinctrl_usdhc3_100mhz>;
+ pinctrl-2 = <&pinctrl_usdhc3_200mhz>;
+ cd-gpios = <&gpio3 22 GPIO_ACTIVE_LOW>;
+ keep-power-in-suspend;
+ enable-sdio-wakeup;
+ vmmc-supply = <&reg_sd3_vmmc>;
+ status = "okay";
+};
+
+&usbotg1 {
+ vbus-supply = <&reg_usb_otg1_vbus>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usbotg1>;
+ disable-over-current;
+ srp-disable;
+ hnp-disable;
+ adp-disable;
+ status = "okay";
+};
+
+&usbotg2 {
+ vbus-supply = <&reg_usb_otg2_vbus>;
+ dr_mode = "host";
+ disable-over-current;
+ status = "okay";
+};
+
+&ecspi1 {
+ fsl,spi-num-chipselects = <1>;
+ cs-gpios = <&gpio4 11 0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ecspi1>;
+ status = "disabled";
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ flash: m25p80@0 {
+ compatible = "st,m25p32";
+ spi-max-frequency = <20000000>;
+ reg = <0>;
+ };
+};
+
+&epdc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_epdc0>;
+ V3P3-supply = <&V3P3_reg>;
+ VCOM-supply = <&VCOM_reg>;
+ DISPLAY-supply = <&DISPLAY_reg>;
+ status = "okay";
+};
+
+&ssi2 {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx6sll-pinfunc.h b/arch/arm/boot/dts/imx6sll-pinfunc.h
new file mode 100755
index 000000000000..5a3700b0a0ff
--- /dev/null
+++ b/arch/arm/boot/dts/imx6sll-pinfunc.h
@@ -0,0 +1,882 @@
+/*
+ * Copyright 2016 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.
+ *
+ */
+
+#ifndef __DTS_IMX6SLL_PINFUNC_H
+#define __DTS_IMX6SLL_PINFUNC_H
+
+/*
+ * The pin function ID is a tuple of
+ * <mux_reg conf_reg input_reg mux_mode input_val>
+ */
+#define MX6SLL_PAD_WDOG_B__WDOG1_B 0x0014 0x02DC 0x0000 0x0 0x0
+#define MX6SLL_PAD_WDOG_B__WDOG1_RESET_B_DEB 0x0014 0x02DC 0x0000 0x1 0x0
+#define MX6SLL_PAD_WDOG_B__UART5_RI_B 0x0014 0x02DC 0x0000 0x2 0x0
+#define MX6SLL_PAD_WDOG_B__GPIO3_IO18 0x0014 0x02DC 0x0000 0x5 0x0
+#define MX6SLL_PAD_REF_CLK_24M__XTALOSC_REF_CLK_24M 0x0018 0x02E0 0x0000 0x0 0x0
+#define MX6SLL_PAD_REF_CLK_24M__I2C3_SCL 0x0018 0x02E0 0x068C 0x1 0x0
+#define MX6SLL_PAD_REF_CLK_24M__PWM3_OUT 0x0018 0x02E0 0x0000 0x2 0x0
+#define MX6SLL_PAD_REF_CLK_24M__USB_OTG2_ID 0x0018 0x02E0 0x0560 0x3 0x0
+#define MX6SLL_PAD_REF_CLK_24M__CCM_PMIC_READY 0x0018 0x02E0 0x05AC 0x4 0x0
+#define MX6SLL_PAD_REF_CLK_24M__GPIO3_IO21 0x0018 0x02E0 0x0000 0x5 0x0
+#define MX6SLL_PAD_REF_CLK_24M__SD3_WP 0x0018 0x02E0 0x0794 0x6 0x0
+#define MX6SLL_PAD_REF_CLK_32K__XTALOSC_REF_CLK_32K 0x001C 0x02E4 0x0000 0x0 0x0
+#define MX6SLL_PAD_REF_CLK_32K__I2C3_SDA 0x001C 0x02E4 0x0690 0x1 0x0
+#define MX6SLL_PAD_REF_CLK_32K__PWM4_OUT 0x001C 0x02E4 0x0000 0x2 0x0
+#define MX6SLL_PAD_REF_CLK_32K__USB_OTG1_ID 0x001C 0x02E4 0x055C 0x3 0x0
+#define MX6SLL_PAD_REF_CLK_32K__SD1_LCTL 0x001C 0x02E4 0x0000 0x4 0x0
+#define MX6SLL_PAD_REF_CLK_32K__GPIO3_IO22 0x001C 0x02E4 0x0000 0x5 0x0
+#define MX6SLL_PAD_REF_CLK_32K__SD3_CD_B 0x001C 0x02E4 0x0780 0x6 0x0
+#define MX6SLL_PAD_PWM1__PWM1_OUT 0x0020 0x02E8 0x0000 0x0 0x0
+#define MX6SLL_PAD_PWM1__CCM_CLKO 0x0020 0x02E8 0x0000 0x1 0x0
+#define MX6SLL_PAD_PWM1__AUDIO_CLK_OUT 0x0020 0x02E8 0x0000 0x2 0x0
+#define MX6SLL_PAD_PWM1__CSI_MCLK 0x0020 0x02E8 0x0000 0x4 0x0
+#define MX6SLL_PAD_PWM1__GPIO3_IO23 0x0020 0x02E8 0x0000 0x5 0x0
+#define MX6SLL_PAD_PWM1__EPIT1_OUT 0x0020 0x02E8 0x0000 0x6 0x0
+#define MX6SLL_PAD_KEY_COL0__KEY_COL0 0x0024 0x02EC 0x06A0 0x0 0x0
+#define MX6SLL_PAD_KEY_COL0__I2C2_SCL 0x0024 0x02EC 0x0684 0x1 0x0
+#define MX6SLL_PAD_KEY_COL0__LCD_DATA00 0x0024 0x02EC 0x06D8 0x2 0x0
+#define MX6SLL_PAD_KEY_COL0__SD1_CD_B 0x0024 0x02EC 0x0770 0x4 0x1
+#define MX6SLL_PAD_KEY_COL0__GPIO3_IO24 0x0024 0x02EC 0x0000 0x5 0x0
+#define MX6SLL_PAD_KEY_ROW0__KEY_ROW0 0x0028 0x02F0 0x06C0 0x0 0x0
+#define MX6SLL_PAD_KEY_ROW0__I2C2_SDA 0x0028 0x02F0 0x0688 0x1 0x0
+#define MX6SLL_PAD_KEY_ROW0__LCD_DATA01 0x0028 0x02F0 0x06DC 0x2 0x0
+#define MX6SLL_PAD_KEY_ROW0__SD1_WP 0x0028 0x02F0 0x0774 0x4 0x1
+#define MX6SLL_PAD_KEY_ROW0__GPIO3_IO25 0x0028 0x02F0 0x0000 0x5 0x0
+#define MX6SLL_PAD_KEY_COL1__KEY_COL1 0x002C 0x02F4 0x06A4 0x0 0x0
+#define MX6SLL_PAD_KEY_COL1__ECSPI4_MOSI 0x002C 0x02F4 0x0658 0x1 0x1
+#define MX6SLL_PAD_KEY_COL1__LCD_DATA02 0x002C 0x02F4 0x06E0 0x2 0x0
+#define MX6SLL_PAD_KEY_COL1__SD3_DATA4 0x002C 0x02F4 0x0784 0x4 0x0
+#define MX6SLL_PAD_KEY_COL1__GPIO3_IO26 0x002C 0x02F4 0x0000 0x5 0x0
+#define MX6SLL_PAD_KEY_ROW1__KEY_ROW1 0x0030 0x02F8 0x06C4 0x0 0x0
+#define MX6SLL_PAD_KEY_ROW1__ECSPI4_MISO 0x0030 0x02F8 0x0654 0x1 0x1
+#define MX6SLL_PAD_KEY_ROW1__LCD_DATA03 0x0030 0x02F8 0x06E4 0x2 0x0
+#define MX6SLL_PAD_KEY_ROW1__CSI_FIELD 0x0030 0x02F8 0x0000 0x3 0x0
+#define MX6SLL_PAD_KEY_ROW1__SD3_DATA5 0x0030 0x02F8 0x0788 0x4 0x0
+#define MX6SLL_PAD_KEY_ROW1__GPIO3_IO27 0x0030 0x02F8 0x0000 0x5 0x0
+#define MX6SLL_PAD_KEY_COL2__KEY_COL2 0x0034 0x02FC 0x06A8 0x0 0x0
+#define MX6SLL_PAD_KEY_COL2__ECSPI4_SS0 0x0034 0x02FC 0x065C 0x1 0x1
+#define MX6SLL_PAD_KEY_COL2__LCD_DATA04 0x0034 0x02FC 0x06E8 0x2 0x0
+#define MX6SLL_PAD_KEY_COL2__CSI_DATA12 0x0034 0x02FC 0x05B8 0x3 0x1
+#define MX6SLL_PAD_KEY_COL2__SD3_DATA6 0x0034 0x02FC 0x078C 0x4 0x0
+#define MX6SLL_PAD_KEY_COL2__GPIO3_IO28 0x0034 0x02FC 0x0000 0x5 0x0
+#define MX6SLL_PAD_KEY_ROW2__KEY_ROW2 0x0038 0x0300 0x06C8 0x0 0x0
+#define MX6SLL_PAD_KEY_ROW2__ECSPI4_SCLK 0x0038 0x0300 0x0650 0x1 0x1
+#define MX6SLL_PAD_KEY_ROW2__LCD_DATA05 0x0038 0x0300 0x06EC 0x2 0x0
+#define MX6SLL_PAD_KEY_ROW2__CSI_DATA13 0x0038 0x0300 0x05BC 0x3 0x1
+#define MX6SLL_PAD_KEY_ROW2__SD3_DATA7 0x0038 0x0300 0x0790 0x4 0x0
+#define MX6SLL_PAD_KEY_ROW2__GPIO3_IO29 0x0038 0x0300 0x0000 0x5 0x0
+#define MX6SLL_PAD_KEY_COL3__KEY_COL3 0x003C 0x0304 0x06AC 0x0 0x0
+#define MX6SLL_PAD_KEY_COL3__AUD6_RXFS 0x003C 0x0304 0x05A0 0x1 0x1
+#define MX6SLL_PAD_KEY_COL3__LCD_DATA06 0x003C 0x0304 0x06F0 0x2 0x0
+#define MX6SLL_PAD_KEY_COL3__CSI_DATA14 0x003C 0x0304 0x05C0 0x3 0x1
+#define MX6SLL_PAD_KEY_COL3__GPIO3_IO30 0x003C 0x0304 0x0000 0x5 0x0
+#define MX6SLL_PAD_KEY_COL3__SD1_RESET 0x003C 0x0304 0x0000 0x6 0x0
+#define MX6SLL_PAD_KEY_ROW3__KEY_ROW3 0x0040 0x0308 0x06CC 0x0 0x1
+#define MX6SLL_PAD_KEY_ROW3__AUD6_RXC 0x0040 0x0308 0x059C 0x1 0x1
+#define MX6SLL_PAD_KEY_ROW3__LCD_DATA07 0x0040 0x0308 0x06F4 0x2 0x1
+#define MX6SLL_PAD_KEY_ROW3__CSI_DATA15 0x0040 0x0308 0x05C4 0x3 0x2
+#define MX6SLL_PAD_KEY_ROW3__GPIO3_IO31 0x0040 0x0308 0x0000 0x5 0x0
+#define MX6SLL_PAD_KEY_ROW3__SD1_VSELECT 0x0040 0x0308 0x0000 0x6 0x0
+#define MX6SLL_PAD_KEY_COL4__KEY_COL4 0x0044 0x030C 0x06B0 0x0 0x1
+#define MX6SLL_PAD_KEY_COL4__AUD6_RXD 0x0044 0x030C 0x0594 0x1 0x1
+#define MX6SLL_PAD_KEY_COL4__LCD_DATA08 0x0044 0x030C 0x06F8 0x2 0x1
+#define MX6SLL_PAD_KEY_COL4__CSI_DATA16 0x0044 0x030C 0x0000 0x3 0x0
+#define MX6SLL_PAD_KEY_COL4__GPIO4_IO00 0x0044 0x030C 0x0000 0x5 0x0
+#define MX6SLL_PAD_KEY_COL4__USB_OTG1_PWR 0x0044 0x030C 0x0000 0x6 0x0
+#define MX6SLL_PAD_KEY_ROW4__KEY_ROW4 0x0048 0x0310 0x06D0 0x0 0x1
+#define MX6SLL_PAD_KEY_ROW4__AUD6_TXC 0x0048 0x0310 0x05A4 0x1 0x1
+#define MX6SLL_PAD_KEY_ROW4__LCD_DATA09 0x0048 0x0310 0x06FC 0x2 0x1
+#define MX6SLL_PAD_KEY_ROW4__CSI_DATA17 0x0048 0x0310 0x0000 0x3 0x0
+#define MX6SLL_PAD_KEY_ROW4__GPIO4_IO01 0x0048 0x0310 0x0000 0x5 0x0
+#define MX6SLL_PAD_KEY_ROW4__USB_OTG1_OC 0x0048 0x0310 0x076C 0x6 0x2
+#define MX6SLL_PAD_KEY_COL5__KEY_COL5 0x004C 0x0314 0x0694 0x0 0x1
+#define MX6SLL_PAD_KEY_COL5__AUD6_TXFS 0x004C 0x0314 0x05A8 0x1 0x1
+#define MX6SLL_PAD_KEY_COL5__LCD_DATA10 0x004C 0x0314 0x0700 0x2 0x0
+#define MX6SLL_PAD_KEY_COL5__CSI_DATA18 0x004C 0x0314 0x0000 0x3 0x0
+#define MX6SLL_PAD_KEY_COL5__GPIO4_IO02 0x004C 0x0314 0x0000 0x5 0x0
+#define MX6SLL_PAD_KEY_COL5__USB_OTG2_PWR 0x004C 0x0314 0x0000 0x6 0x0
+#define MX6SLL_PAD_KEY_ROW5__KEY_ROW5 0x0050 0x0318 0x06B4 0x0 0x2
+#define MX6SLL_PAD_KEY_ROW5__AUD6_TXD 0x0050 0x0318 0x0598 0x1 0x1
+#define MX6SLL_PAD_KEY_ROW5__LCD_DATA11 0x0050 0x0318 0x0704 0x2 0x1
+#define MX6SLL_PAD_KEY_ROW5__CSI_DATA19 0x0050 0x0318 0x0000 0x3 0x0
+#define MX6SLL_PAD_KEY_ROW5__GPIO4_IO03 0x0050 0x0318 0x0000 0x5 0x0
+#define MX6SLL_PAD_KEY_ROW5__USB_OTG2_OC 0x0050 0x0318 0x0768 0x6 0x3
+#define MX6SLL_PAD_KEY_COL6__KEY_COL6 0x0054 0x031C 0x0698 0x0 0x2
+#define MX6SLL_PAD_KEY_COL6__UART4_DCE_RX 0x0054 0x031C 0x075C 0x1 0x2
+#define MX6SLL_PAD_KEY_COL6__UART4_DTE_TX 0x0054 0x031C 0x0000 0x1 0x0
+#define MX6SLL_PAD_KEY_COL6__LCD_DATA12 0x0054 0x031C 0x0708 0x2 0x1
+#define MX6SLL_PAD_KEY_COL6__CSI_DATA20 0x0054 0x031C 0x0000 0x3 0x0
+#define MX6SLL_PAD_KEY_COL6__GPIO4_IO04 0x0054 0x031C 0x0000 0x5 0x0
+#define MX6SLL_PAD_KEY_COL6__SD3_RESET 0x0054 0x031C 0x0000 0x6 0x0
+#define MX6SLL_PAD_KEY_ROW6__KEY_ROW6 0x0058 0x0320 0x06B8 0x0 0x2
+#define MX6SLL_PAD_KEY_ROW6__UART4_DCE_TX 0x0058 0x0320 0x0000 0x1 0x0
+#define MX6SLL_PAD_KEY_ROW6__UART4_DTE_RX 0x0058 0x0320 0x075C 0x1 0x3
+#define MX6SLL_PAD_KEY_ROW6__LCD_DATA13 0x0058 0x0320 0x070C 0x2 0x1
+#define MX6SLL_PAD_KEY_ROW6__CSI_DATA21 0x0058 0x0320 0x0000 0x3 0x0
+#define MX6SLL_PAD_KEY_ROW6__GPIO4_IO05 0x0058 0x0320 0x0000 0x5 0x0
+#define MX6SLL_PAD_KEY_ROW6__SD3_VSELECT 0x0058 0x0320 0x0000 0x6 0x0
+#define MX6SLL_PAD_KEY_COL7__KEY_COL7 0x005C 0x0324 0x069C 0x0 0x2
+#define MX6SLL_PAD_KEY_COL7__UART4_DCE_RTS 0x005C 0x0324 0x0758 0x1 0x2
+#define MX6SLL_PAD_KEY_COL7__UART4_DTE_CTS 0x005C 0x0324 0x0000 0x1 0x0
+#define MX6SLL_PAD_KEY_COL7__LCD_DATA14 0x005C 0x0324 0x0710 0x2 0x1
+#define MX6SLL_PAD_KEY_COL7__CSI_DATA22 0x005C 0x0324 0x0000 0x3 0x0
+#define MX6SLL_PAD_KEY_COL7__GPIO4_IO06 0x005C 0x0324 0x0000 0x5 0x0
+#define MX6SLL_PAD_KEY_COL7__SD1_WP 0x005C 0x0324 0x0774 0x6 0x3
+#define MX6SLL_PAD_KEY_ROW7__KEY_ROW7 0x0060 0x0328 0x06BC 0x0 0x2
+#define MX6SLL_PAD_KEY_ROW7__UART4_DCE_CTS 0x0060 0x0328 0x0000 0x1 0x0
+#define MX6SLL_PAD_KEY_ROW7__UART4_DTE_RTS 0x0060 0x0328 0x0758 0x1 0x3
+#define MX6SLL_PAD_KEY_ROW7__LCD_DATA15 0x0060 0x0328 0x0714 0x2 0x1
+#define MX6SLL_PAD_KEY_ROW7__CSI_DATA23 0x0060 0x0328 0x0000 0x3 0x0
+#define MX6SLL_PAD_KEY_ROW7__GPIO4_IO07 0x0060 0x0328 0x0000 0x5 0x0
+#define MX6SLL_PAD_KEY_ROW7__SD1_CD_B 0x0060 0x0328 0x0770 0x6 0x3
+#define MX6SLL_PAD_EPDC_DATA00__EPDC_DATA00 0x0064 0x032C 0x0000 0x0 0x0
+#define MX6SLL_PAD_EPDC_DATA00__ECSPI4_MOSI 0x0064 0x032C 0x0658 0x1 0x2
+#define MX6SLL_PAD_EPDC_DATA00__LCD_DATA24 0x0064 0x032C 0x0000 0x2 0x0
+#define MX6SLL_PAD_EPDC_DATA00__CSI_DATA00 0x0064 0x032C 0x05C8 0x3 0x2
+#define MX6SLL_PAD_EPDC_DATA00__GPIO1_IO07 0x0064 0x032C 0x0000 0x5 0x0
+#define MX6SLL_PAD_EPDC_DATA01__EPDC_DATA01 0x0068 0x0330 0x0000 0x0 0x0
+#define MX6SLL_PAD_EPDC_DATA01__ECSPI4_MISO 0x0068 0x0330 0x0654 0x1 0x2
+#define MX6SLL_PAD_EPDC_DATA01__LCD_DATA25 0x0068 0x0330 0x0000 0x2 0x0
+#define MX6SLL_PAD_EPDC_DATA01__CSI_DATA01 0x0068 0x0330 0x05CC 0x3 0x2
+#define MX6SLL_PAD_EPDC_DATA01__GPIO1_IO08 0x0068 0x0330 0x0000 0x5 0x0
+#define MX6SLL_PAD_EPDC_DATA02__EPDC_DATA02 0x006C 0x0334 0x0000 0x0 0x0
+#define MX6SLL_PAD_EPDC_DATA02__ECSPI4_SS0 0x006C 0x0334 0x065C 0x1 0x2
+#define MX6SLL_PAD_EPDC_DATA02__LCD_DATA26 0x006C 0x0334 0x0000 0x2 0x0
+#define MX6SLL_PAD_EPDC_DATA02__CSI_DATA02 0x006C 0x0334 0x05D0 0x3 0x2
+#define MX6SLL_PAD_EPDC_DATA02__GPIO1_IO09 0x006C 0x0334 0x0000 0x5 0x0
+#define MX6SLL_PAD_EPDC_DATA03__EPDC_DATA03 0x0070 0x0338 0x0000 0x0 0x0
+#define MX6SLL_PAD_EPDC_DATA03__ECSPI4_SCLK 0x0070 0x0338 0x0650 0x1 0x2
+#define MX6SLL_PAD_EPDC_DATA03__LCD_DATA27 0x0070 0x0338 0x0000 0x2 0x0
+#define MX6SLL_PAD_EPDC_DATA03__CSI_DATA03 0x0070 0x0338 0x05D4 0x3 0x2
+#define MX6SLL_PAD_EPDC_DATA03__GPIO1_IO10 0x0070 0x0338 0x0000 0x5 0x0
+#define MX6SLL_PAD_EPDC_DATA04__EPDC_DATA04 0x0074 0x033C 0x0000 0x0 0x0
+#define MX6SLL_PAD_EPDC_DATA04__ECSPI4_SS1 0x0074 0x033C 0x0660 0x1 0x1
+#define MX6SLL_PAD_EPDC_DATA04__LCD_DATA28 0x0074 0x033C 0x0000 0x2 0x0
+#define MX6SLL_PAD_EPDC_DATA04__CSI_DATA04 0x0074 0x033C 0x05D8 0x3 0x2
+#define MX6SLL_PAD_EPDC_DATA04__GPIO1_IO11 0x0074 0x033C 0x0000 0x5 0x0
+#define MX6SLL_PAD_EPDC_DATA05__EPDC_DATA05 0x0078 0x0340 0x0000 0x0 0x0
+#define MX6SLL_PAD_EPDC_DATA05__ECSPI4_SS2 0x0078 0x0340 0x0664 0x1 0x1
+#define MX6SLL_PAD_EPDC_DATA05__LCD_DATA29 0x0078 0x0340 0x0000 0x2 0x0
+#define MX6SLL_PAD_EPDC_DATA05__CSI_DATA05 0x0078 0x0340 0x05DC 0x3 0x2
+#define MX6SLL_PAD_EPDC_DATA05__GPIO1_IO12 0x0078 0x0340 0x0000 0x5 0x0
+#define MX6SLL_PAD_EPDC_DATA06__EPDC_DATA06 0x007C 0x0344 0x0000 0x0 0x0
+#define MX6SLL_PAD_EPDC_DATA06__ECSPI4_SS3 0x007C 0x0344 0x0000 0x1 0x0
+#define MX6SLL_PAD_EPDC_DATA06__LCD_DATA30 0x007C 0x0344 0x0000 0x2 0x0
+#define MX6SLL_PAD_EPDC_DATA06__CSI_DATA06 0x007C 0x0344 0x05E0 0x3 0x2
+#define MX6SLL_PAD_EPDC_DATA06__GPIO1_IO13 0x007C 0x0344 0x0000 0x5 0x0
+#define MX6SLL_PAD_EPDC_DATA07__EPDC_DATA07 0x0080 0x0348 0x0000 0x0 0x0
+#define MX6SLL_PAD_EPDC_DATA07__ECSPI4_RDY 0x0080 0x0348 0x0000 0x1 0x0
+#define MX6SLL_PAD_EPDC_DATA07__LCD_DATA31 0x0080 0x0348 0x0000 0x2 0x0
+#define MX6SLL_PAD_EPDC_DATA07__CSI_DATA07 0x0080 0x0348 0x05E4 0x3 0x2
+#define MX6SLL_PAD_EPDC_DATA07__GPIO1_IO14 0x0080 0x0348 0x0000 0x5 0x0
+#define MX6SLL_PAD_EPDC_DATA08__EPDC_DATA08 0x0084 0x034C 0x0000 0x0 0x0
+#define MX6SLL_PAD_EPDC_DATA08__ECSPI3_MOSI 0x0084 0x034C 0x063C 0x1 0x2
+#define MX6SLL_PAD_EPDC_DATA08__EPDC_PWR_CTRL0 0x0084 0x034C 0x0000 0x2 0x0
+#define MX6SLL_PAD_EPDC_DATA08__GPIO1_IO15 0x0084 0x034C 0x0000 0x5 0x0
+#define MX6SLL_PAD_EPDC_DATA09__EPDC_DATA09 0x0088 0x0350 0x0000 0x0 0x0
+#define MX6SLL_PAD_EPDC_DATA09__ECSPI3_MISO 0x0088 0x0350 0x0638 0x1 0x2
+#define MX6SLL_PAD_EPDC_DATA09__EPDC_PWR_CTRL1 0x0088 0x0350 0x0000 0x2 0x0
+#define MX6SLL_PAD_EPDC_DATA09__GPIO1_IO16 0x0088 0x0350 0x0000 0x5 0x0
+#define MX6SLL_PAD_EPDC_DATA10__EPDC_DATA10 0x008C 0x0354 0x0000 0x0 0x0
+#define MX6SLL_PAD_EPDC_DATA10__ECSPI3_SS0 0x008C 0x0354 0x0648 0x1 0x2
+#define MX6SLL_PAD_EPDC_DATA10__EPDC_PWR_CTRL2 0x008C 0x0354 0x0000 0x2 0x0
+#define MX6SLL_PAD_EPDC_DATA10__GPIO1_IO17 0x008C 0x0354 0x0000 0x5 0x0
+#define MX6SLL_PAD_EPDC_DATA11__EPDC_DATA11 0x0090 0x0358 0x0000 0x0 0x0
+#define MX6SLL_PAD_EPDC_DATA11__ECSPI3_SCLK 0x0090 0x0358 0x0630 0x1 0x2
+#define MX6SLL_PAD_EPDC_DATA11__EPDC_PWR_CTRL3 0x0090 0x0358 0x0000 0x2 0x0
+#define MX6SLL_PAD_EPDC_DATA11__GPIO1_IO18 0x0090 0x0358 0x0000 0x5 0x0
+#define MX6SLL_PAD_EPDC_DATA12__EPDC_DATA12 0x0094 0x035C 0x0000 0x0 0x0
+#define MX6SLL_PAD_EPDC_DATA12__UART2_DCE_RX 0x0094 0x035C 0x074C 0x1 0x4
+#define MX6SLL_PAD_EPDC_DATA12__UART2_DTE_TX 0x0094 0x035C 0x0000 0x1 0x0
+#define MX6SLL_PAD_EPDC_DATA12__EPDC_PWR_COM 0x0094 0x035C 0x0000 0x2 0x0
+#define MX6SLL_PAD_EPDC_DATA12__GPIO1_IO19 0x0094 0x035C 0x0000 0x5 0x0
+#define MX6SLL_PAD_EPDC_DATA12__ECSPI3_SS1 0x0094 0x035C 0x064C 0x6 0x1
+#define MX6SLL_PAD_EPDC_DATA13__EPDC_DATA13 0x0098 0x0360 0x0000 0x0 0x0
+#define MX6SLL_PAD_EPDC_DATA13__UART2_DCE_TX 0x0098 0x0360 0x0000 0x1 0x0
+#define MX6SLL_PAD_EPDC_DATA13__UART2_DTE_RX 0x0098 0x0360 0x074C 0x1 0x5
+#define MX6SLL_PAD_EPDC_DATA13__EPDC_PWR_IRQ 0x0098 0x0360 0x0668 0x2 0x0
+#define MX6SLL_PAD_EPDC_DATA13__GPIO1_IO20 0x0098 0x0360 0x0000 0x5 0x0
+#define MX6SLL_PAD_EPDC_DATA13__ECSPI3_SS2 0x0098 0x0360 0x0640 0x6 0x1
+#define MX6SLL_PAD_EPDC_DATA14__EPDC_DATA14 0x009C 0x0364 0x0000 0x0 0x0
+#define MX6SLL_PAD_EPDC_DATA14__UART2_DCE_RTS 0x009C 0x0364 0x0748 0x1 0x4
+#define MX6SLL_PAD_EPDC_DATA14__UART2_DTE_CTS 0x009C 0x0364 0x0000 0x1 0x0
+#define MX6SLL_PAD_EPDC_DATA14__EPDC_PWR_STAT 0x009C 0x0364 0x066C 0x2 0x0
+#define MX6SLL_PAD_EPDC_DATA14__GPIO1_IO21 0x009C 0x0364 0x0000 0x5 0x0
+#define MX6SLL_PAD_EPDC_DATA14__ECSPI3_SS3 0x009C 0x0364 0x0644 0x6 0x1
+#define MX6SLL_PAD_EPDC_DATA15__EPDC_DATA15 0x00A0 0x0368 0x0000 0x0 0x0
+#define MX6SLL_PAD_EPDC_DATA15__UART2_DCE_CTS 0x00A0 0x0368 0x0000 0x1 0x0
+#define MX6SLL_PAD_EPDC_DATA15__UART2_DTE_RTS 0x00A0 0x0368 0x0748 0x1 0x5
+#define MX6SLL_PAD_EPDC_DATA15__EPDC_PWR_WAKE 0x00A0 0x0368 0x0000 0x2 0x0
+#define MX6SLL_PAD_EPDC_DATA15__GPIO1_IO22 0x00A0 0x0368 0x0000 0x5 0x0
+#define MX6SLL_PAD_EPDC_DATA15__ECSPI3_RDY 0x00A0 0x0368 0x0634 0x6 0x1
+#define MX6SLL_PAD_EPDC_SDCLK__EPDC_SDCLK_P 0x00A4 0x036C 0x0000 0x0 0x0
+#define MX6SLL_PAD_EPDC_SDCLK__ECSPI2_MOSI 0x00A4 0x036C 0x0624 0x1 0x2
+#define MX6SLL_PAD_EPDC_SDCLK__I2C2_SCL 0x00A4 0x036C 0x0684 0x2 0x2
+#define MX6SLL_PAD_EPDC_SDCLK__CSI_DATA08 0x00A4 0x036C 0x05E8 0x3 0x2
+#define MX6SLL_PAD_EPDC_SDCLK__GPIO1_IO23 0x00A4 0x036C 0x0000 0x5 0x0
+#define MX6SLL_PAD_EPDC_SDLE__EPDC_SDLE 0x00A8 0x0370 0x0000 0x0 0x0
+#define MX6SLL_PAD_EPDC_SDLE__ECSPI2_MISO 0x00A8 0x0370 0x0620 0x1 0x2
+#define MX6SLL_PAD_EPDC_SDLE__I2C2_SDA 0x00A8 0x0370 0x0688 0x2 0x2
+#define MX6SLL_PAD_EPDC_SDLE__CSI_DATA09 0x00A8 0x0370 0x05EC 0x3 0x2
+#define MX6SLL_PAD_EPDC_SDLE__GPIO1_IO24 0x00A8 0x0370 0x0000 0x5 0x0
+#define MX6SLL_PAD_EPDC_SDOE__EPDC_SDOE 0x00AC 0x0374 0x0000 0x0 0x0
+#define MX6SLL_PAD_EPDC_SDOE__ECSPI2_SS0 0x00AC 0x0374 0x0628 0x1 0x1
+#define MX6SLL_PAD_EPDC_SDOE__CSI_DATA10 0x00AC 0x0374 0x05B0 0x3 0x2
+#define MX6SLL_PAD_EPDC_SDOE__GPIO1_IO25 0x00AC 0x0374 0x0000 0x5 0x0
+#define MX6SLL_PAD_EPDC_SDSHR__EPDC_SDSHR 0x00B0 0x0378 0x0000 0x0 0x0
+#define MX6SLL_PAD_EPDC_SDSHR__ECSPI2_SCLK 0x00B0 0x0378 0x061C 0x1 0x2
+#define MX6SLL_PAD_EPDC_SDSHR__EPDC_SDCE4 0x00B0 0x0378 0x0000 0x2 0x0
+#define MX6SLL_PAD_EPDC_SDSHR__CSI_DATA11 0x00B0 0x0378 0x05B4 0x3 0x2
+#define MX6SLL_PAD_EPDC_SDSHR__GPIO1_IO26 0x00B0 0x0378 0x0000 0x5 0x0
+#define MX6SLL_PAD_EPDC_SDCE0__EPDC_SDCE0 0x00B4 0x037C 0x0000 0x0 0x0
+#define MX6SLL_PAD_EPDC_SDCE0__ECSPI2_SS1 0x00B4 0x037C 0x062C 0x1 0x1
+#define MX6SLL_PAD_EPDC_SDCE0__PWM3_OUT 0x00B4 0x037C 0x0000 0x2 0x0
+#define MX6SLL_PAD_EPDC_SDCE0__GPIO1_IO27 0x00B4 0x037C 0x0000 0x5 0x0
+#define MX6SLL_PAD_EPDC_SDCE1__EPDC_SDCE1 0x00B8 0x0380 0x0000 0x0 0x0
+#define MX6SLL_PAD_EPDC_SDCE1__WDOG2_B 0x00B8 0x0380 0x0000 0x1 0x0
+#define MX6SLL_PAD_EPDC_SDCE1__PWM4_OUT 0x00B8 0x0380 0x0000 0x2 0x0
+#define MX6SLL_PAD_EPDC_SDCE1__GPIO1_IO28 0x00B8 0x0380 0x0000 0x5 0x0
+#define MX6SLL_PAD_EPDC_SDCE2__EPDC_SDCE2 0x00BC 0x0384 0x0000 0x0 0x0
+#define MX6SLL_PAD_EPDC_SDCE2__I2C3_SCL 0x00BC 0x0384 0x068C 0x1 0x2
+#define MX6SLL_PAD_EPDC_SDCE2__PWM1_OUT 0x00BC 0x0384 0x0000 0x2 0x0
+#define MX6SLL_PAD_EPDC_SDCE2__GPIO1_IO29 0x00BC 0x0384 0x0000 0x5 0x0
+#define MX6SLL_PAD_EPDC_SDCE3__EPDC_SDCE3 0x00C0 0x0388 0x0000 0x0 0x0
+#define MX6SLL_PAD_EPDC_SDCE3__I2C3_SDA 0x00C0 0x0388 0x0690 0x1 0x2
+#define MX6SLL_PAD_EPDC_SDCE3__PWM2_OUT 0x00C0 0x0388 0x0000 0x2 0x0
+#define MX6SLL_PAD_EPDC_SDCE3__GPIO1_IO30 0x00C0 0x0388 0x0000 0x5 0x0
+#define MX6SLL_PAD_EPDC_GDCLK__EPDC_GDCLK 0x00C4 0x038C 0x0000 0x0 0x0
+#define MX6SLL_PAD_EPDC_GDCLK__ECSPI2_SS2 0x00C4 0x038C 0x0000 0x1 0x0
+#define MX6SLL_PAD_EPDC_GDCLK__CSI_PIXCLK 0x00C4 0x038C 0x05F4 0x3 0x2
+#define MX6SLL_PAD_EPDC_GDCLK__GPIO1_IO31 0x00C4 0x038C 0x0000 0x5 0x0
+#define MX6SLL_PAD_EPDC_GDCLK__SD2_RESET 0x00C4 0x038C 0x0000 0x6 0x0
+#define MX6SLL_PAD_EPDC_GDOE__EPDC_GDOE 0x00C8 0x0390 0x0000 0x0 0x0
+#define MX6SLL_PAD_EPDC_GDOE__ECSPI2_SS3 0x00C8 0x0390 0x0000 0x1 0x0
+#define MX6SLL_PAD_EPDC_GDOE__CSI_HSYNC 0x00C8 0x0390 0x05F0 0x3 0x2
+#define MX6SLL_PAD_EPDC_GDOE__GPIO2_IO00 0x00C8 0x0390 0x0000 0x5 0x0
+#define MX6SLL_PAD_EPDC_GDOE__SD2_VSELECT 0x00C8 0x0390 0x0000 0x6 0x0
+#define MX6SLL_PAD_EPDC_GDRL__EPDC_GDRL 0x00CC 0x0394 0x0000 0x0 0x0
+#define MX6SLL_PAD_EPDC_GDRL__ECSPI2_RDY 0x00CC 0x0394 0x0000 0x1 0x0
+#define MX6SLL_PAD_EPDC_GDRL__CSI_MCLK 0x00CC 0x0394 0x0000 0x3 0x0
+#define MX6SLL_PAD_EPDC_GDRL__GPIO2_IO01 0x00CC 0x0394 0x0000 0x5 0x0
+#define MX6SLL_PAD_EPDC_GDRL__SD2_WP 0x00CC 0x0394 0x077C 0x6 0x2
+#define MX6SLL_PAD_EPDC_GDSP__EPDC_GDSP 0x00D0 0x0398 0x0000 0x0 0x0
+#define MX6SLL_PAD_EPDC_GDSP__PWM4_OUT 0x00D0 0x0398 0x0000 0x1 0x0
+#define MX6SLL_PAD_EPDC_GDSP__CSI_VSYNC 0x00D0 0x0398 0x05F8 0x3 0x2
+#define MX6SLL_PAD_EPDC_GDSP__GPIO2_IO02 0x00D0 0x0398 0x0000 0x5 0x0
+#define MX6SLL_PAD_EPDC_GDSP__SD2_CD_B 0x00D0 0x0398 0x0778 0x6 0x2
+#define MX6SLL_PAD_EPDC_VCOM0__EPDC_VCOM0 0x00D4 0x039C 0x0000 0x0 0x0
+#define MX6SLL_PAD_EPDC_VCOM0__AUD5_RXFS 0x00D4 0x039C 0x0588 0x1 0x1
+#define MX6SLL_PAD_EPDC_VCOM0__UART3_DCE_RX 0x00D4 0x039C 0x0754 0x2 0x4
+#define MX6SLL_PAD_EPDC_VCOM0__UART3_DTE_TX 0x00D4 0x039C 0x0000 0x2 0x0
+#define MX6SLL_PAD_EPDC_VCOM0__GPIO2_IO03 0x00D4 0x039C 0x0000 0x5 0x0
+#define MX6SLL_PAD_EPDC_VCOM0__EPDC_SDCE5 0x00D4 0x039C 0x0000 0x6 0x0
+#define MX6SLL_PAD_EPDC_VCOM1__EPDC_VCOM1 0x00D8 0x03A0 0x0000 0x0 0x0
+#define MX6SLL_PAD_EPDC_VCOM1__AUD5_RXD 0x00D8 0x03A0 0x057C 0x1 0x1
+#define MX6SLL_PAD_EPDC_VCOM1__UART3_DCE_TX 0x00D8 0x03A0 0x0000 0x2 0x0
+#define MX6SLL_PAD_EPDC_VCOM1__UART3_DTE_RX 0x00D8 0x03A0 0x0754 0x2 0x5
+#define MX6SLL_PAD_EPDC_VCOM1__GPIO2_IO04 0x00D8 0x03A0 0x0000 0x5 0x0
+#define MX6SLL_PAD_EPDC_VCOM1__EPDC_SDCE6 0x00D8 0x03A0 0x0000 0x6 0x0
+#define MX6SLL_PAD_EPDC_BDR0__EPDC_BDR0 0x00DC 0x03A4 0x0000 0x0 0x0
+#define MX6SLL_PAD_EPDC_BDR0__UART3_DCE_RTS 0x00DC 0x03A4 0x0750 0x2 0x2
+#define MX6SLL_PAD_EPDC_BDR0__UART3_DTE_CTS 0x00DC 0x03A4 0x0000 0x2 0x0
+#define MX6SLL_PAD_EPDC_BDR0__GPIO2_IO05 0x00DC 0x03A4 0x0000 0x5 0x0
+#define MX6SLL_PAD_EPDC_BDR0__EPDC_SDCE7 0x00DC 0x03A4 0x0000 0x6 0x0
+#define MX6SLL_PAD_EPDC_BDR1__EPDC_BDR1 0x00E0 0x03A8 0x0000 0x0 0x0
+#define MX6SLL_PAD_EPDC_BDR1__UART3_DCE_CTS 0x00E0 0x03A8 0x0000 0x2 0x0
+#define MX6SLL_PAD_EPDC_BDR1__UART3_DTE_RTS 0x00E0 0x03A8 0x0750 0x2 0x3
+#define MX6SLL_PAD_EPDC_BDR1__GPIO2_IO06 0x00E0 0x03A8 0x0000 0x5 0x0
+#define MX6SLL_PAD_EPDC_BDR1__EPDC_SDCE8 0x00E0 0x03A8 0x0000 0x6 0x0
+#define MX6SLL_PAD_EPDC_PWR_CTRL0__EPDC_PWR_CTRL0 0x00E4 0x03AC 0x0000 0x0 0x0
+#define MX6SLL_PAD_EPDC_PWR_CTRL0__AUD5_RXC 0x00E4 0x03AC 0x0584 0x1 0x1
+#define MX6SLL_PAD_EPDC_PWR_CTRL0__LCD_DATA16 0x00E4 0x03AC 0x0718 0x2 0x1
+#define MX6SLL_PAD_EPDC_PWR_CTRL0__GPIO2_IO07 0x00E4 0x03AC 0x0000 0x5 0x0
+#define MX6SLL_PAD_EPDC_PWR_CTRL1__EPDC_PWR_CTRL1 0x00E8 0x03B0 0x0000 0x0 0x0
+#define MX6SLL_PAD_EPDC_PWR_CTRL1__AUD5_TXFS 0x00E8 0x03B0 0x0590 0x1 0x1
+#define MX6SLL_PAD_EPDC_PWR_CTRL1__LCD_DATA17 0x00E8 0x03B0 0x071C 0x2 0x1
+#define MX6SLL_PAD_EPDC_PWR_CTRL1__GPIO2_IO08 0x00E8 0x03B0 0x0000 0x5 0x0
+#define MX6SLL_PAD_EPDC_PWR_CTRL2__EPDC_PWR_CTRL2 0x00EC 0x03B4 0x0000 0x0 0x0
+#define MX6SLL_PAD_EPDC_PWR_CTRL2__AUD5_TXD 0x00EC 0x03B4 0x0580 0x1 0x1
+#define MX6SLL_PAD_EPDC_PWR_CTRL2__LCD_DATA18 0x00EC 0x03B4 0x0720 0x2 0x1
+#define MX6SLL_PAD_EPDC_PWR_CTRL2__GPIO2_IO09 0x00EC 0x03B4 0x0000 0x5 0x0
+#define MX6SLL_PAD_EPDC_PWR_CTRL3__EPDC_PWR_CTRL3 0x00F0 0x03B8 0x0000 0x0 0x0
+#define MX6SLL_PAD_EPDC_PWR_CTRL3__AUD5_TXC 0x00F0 0x03B8 0x058C 0x1 0x1
+#define MX6SLL_PAD_EPDC_PWR_CTRL3__LCD_DATA19 0x00F0 0x03B8 0x0724 0x2 0x1
+#define MX6SLL_PAD_EPDC_PWR_CTRL3__GPIO2_IO10 0x00F0 0x03B8 0x0000 0x5 0x0
+#define MX6SLL_PAD_EPDC_PWR_COM__EPDC_PWR_COM 0x00F4 0x03BC 0x0000 0x0 0x0
+#define MX6SLL_PAD_EPDC_PWR_COM__LCD_DATA20 0x00F4 0x03BC 0x0728 0x2 0x1
+#define MX6SLL_PAD_EPDC_PWR_COM__USB_OTG1_ID 0x00F4 0x03BC 0x055C 0x4 0x4
+#define MX6SLL_PAD_EPDC_PWR_COM__GPIO2_IO11 0x00F4 0x03BC 0x0000 0x5 0x0
+#define MX6SLL_PAD_EPDC_PWR_COM__SD3_RESET 0x00F4 0x03BC 0x0000 0x6 0x0
+#define MX6SLL_PAD_EPDC_PWR_IRQ__EPDC_PWR_IRQ 0x00F8 0x03C0 0x0668 0x0 0x1
+#define MX6SLL_PAD_EPDC_PWR_IRQ__LCD_DATA21 0x00F8 0x03C0 0x072C 0x2 0x1
+#define MX6SLL_PAD_EPDC_PWR_IRQ__USB_OTG2_ID 0x00F8 0x03C0 0x0560 0x4 0x3
+#define MX6SLL_PAD_EPDC_PWR_IRQ__GPIO2_IO12 0x00F8 0x03C0 0x0000 0x5 0x0
+#define MX6SLL_PAD_EPDC_PWR_IRQ__SD3_VSELECT 0x00F8 0x03C0 0x0000 0x6 0x0
+#define MX6SLL_PAD_EPDC_PWR_STAT__EPDC_PWR_STAT 0x00FC 0x03C4 0x066C 0x0 0x1
+#define MX6SLL_PAD_EPDC_PWR_STAT__LCD_DATA22 0x00FC 0x03C4 0x0730 0x2 0x1
+#define MX6SLL_PAD_EPDC_PWR_STAT__ARM_EVENTI 0x00FC 0x03C4 0x0000 0x4 0x0
+#define MX6SLL_PAD_EPDC_PWR_STAT__GPIO2_IO13 0x00FC 0x03C4 0x0000 0x5 0x0
+#define MX6SLL_PAD_EPDC_PWR_STAT__SD3_WP 0x00FC 0x03C4 0x0794 0x6 0x2
+#define MX6SLL_PAD_EPDC_PWR_WAKE__EPDC_PWR_WAKE 0x0100 0x03C8 0x0000 0x0 0x0
+#define MX6SLL_PAD_EPDC_PWR_WAKE__LCD_DATA23 0x0100 0x03C8 0x0734 0x2 0x1
+#define MX6SLL_PAD_EPDC_PWR_WAKE__ARM_EVENTO 0x0100 0x03C8 0x0000 0x4 0x0
+#define MX6SLL_PAD_EPDC_PWR_WAKE__GPIO2_IO14 0x0100 0x03C8 0x0000 0x5 0x0
+#define MX6SLL_PAD_EPDC_PWR_WAKE__SD3_CD_B 0x0100 0x03C8 0x0780 0x6 0x2
+#define MX6SLL_PAD_LCD_CLK__LCD_CLK 0x0104 0x03CC 0x0000 0x0 0x0
+#define MX6SLL_PAD_LCD_CLK__LCD_WR_RWN 0x0104 0x03CC 0x0000 0x2 0x0
+#define MX6SLL_PAD_LCD_CLK__PWM4_OUT 0x0104 0x03CC 0x0000 0x4 0x0
+#define MX6SLL_PAD_LCD_CLK__GPIO2_IO15 0x0104 0x03CC 0x0000 0x5 0x0
+#define MX6SLL_PAD_LCD_ENABLE__LCD_ENABLE 0x0108 0x03D0 0x0000 0x0 0x0
+#define MX6SLL_PAD_LCD_ENABLE__LCD_RD_E 0x0108 0x03D0 0x0000 0x2 0x0
+#define MX6SLL_PAD_LCD_ENABLE__UART2_DCE_RX 0x0108 0x03D0 0x0000 0x4 0x0
+#define MX6SLL_PAD_LCD_ENABLE__UART2_DTE_TX 0x0108 0x03D0 0x0000 0x4 0x0
+#define MX6SLL_PAD_LCD_ENABLE__GPIO2_IO16 0x0108 0x03D0 0x0000 0x5 0x0
+#define MX6SLL_PAD_LCD_HSYNC__LCD_HSYNC 0x010C 0x03D4 0x06D4 0x0 0x0
+#define MX6SLL_PAD_LCD_HSYNC__LCD_CS 0x010C 0x03D4 0x0000 0x2 0x0
+#define MX6SLL_PAD_LCD_HSYNC__UART2_DCE_TX 0x010C 0x03D4 0x0000 0x4 0x0
+#define MX6SLL_PAD_LCD_HSYNC__UART2_DTE_RX 0x010C 0x03D4 0x074C 0x4 0x1
+#define MX6SLL_PAD_LCD_HSYNC__GPIO2_IO17 0x010C 0x03D4 0x0000 0x5 0x0
+#define MX6SLL_PAD_LCD_HSYNC__ARM_TRACE_CLK 0x010C 0x03D4 0x0000 0x6 0x0
+#define MX6SLL_PAD_LCD_VSYNC__LCD_VSYNC 0x0110 0x03D8 0x0000 0x0 0x0
+#define MX6SLL_PAD_LCD_VSYNC__LCD_RS 0x0110 0x03D8 0x0000 0x2 0x0
+#define MX6SLL_PAD_LCD_VSYNC__UART2_DCE_RTS 0x0110 0x03D8 0x0748 0x4 0x0
+#define MX6SLL_PAD_LCD_VSYNC__UART2_DTE_CTS 0x0110 0x03D8 0x0000 0x4 0x0
+#define MX6SLL_PAD_LCD_VSYNC__GPIO2_IO18 0x0110 0x03D8 0x0000 0x5 0x0
+#define MX6SLL_PAD_LCD_VSYNC__ARM_TRACE_CTL 0x0110 0x03D8 0x0000 0x6 0x0
+#define MX6SLL_PAD_LCD_RESET__LCD_RESET 0x0114 0x03DC 0x0000 0x0 0x0
+#define MX6SLL_PAD_LCD_RESET__LCD_BUSY 0x0114 0x03DC 0x06D4 0x2 0x1
+#define MX6SLL_PAD_LCD_RESET__UART2_DCE_CTS 0x0114 0x03DC 0x0000 0x4 0x0
+#define MX6SLL_PAD_LCD_RESET__UART2_DTE_RTS 0x0114 0x03DC 0x0748 0x4 0x1
+#define MX6SLL_PAD_LCD_RESET__GPIO2_IO19 0x0114 0x03DC 0x0000 0x5 0x0
+#define MX6SLL_PAD_LCD_RESET__CCM_PMIC_READY 0x0114 0x03DC 0x05AC 0x6 0x2
+#define MX6SLL_PAD_LCD_DATA00__LCD_DATA00 0x0118 0x03E0 0x06D8 0x0 0x1
+#define MX6SLL_PAD_LCD_DATA00__ECSPI1_MOSI 0x0118 0x03E0 0x0608 0x1 0x0
+#define MX6SLL_PAD_LCD_DATA00__USB_OTG2_ID 0x0118 0x03E0 0x0560 0x2 0x2
+#define MX6SLL_PAD_LCD_DATA00__PWM1_OUT 0x0118 0x03E0 0x0000 0x3 0x0
+#define MX6SLL_PAD_LCD_DATA00__UART5_DTR_B 0x0118 0x03E0 0x0000 0x4 0x0
+#define MX6SLL_PAD_LCD_DATA00__GPIO2_IO20 0x0118 0x03E0 0x0000 0x5 0x0
+#define MX6SLL_PAD_LCD_DATA00__ARM_TRACE00 0x0118 0x03E0 0x0000 0x6 0x0
+#define MX6SLL_PAD_LCD_DATA00__SRC_BOOT_CFG00 0x0118 0x03E0 0x0000 0x7 0x0
+#define MX6SLL_PAD_LCD_DATA01__LCD_DATA01 0x011C 0x03E4 0x06DC 0x0 0x1
+#define MX6SLL_PAD_LCD_DATA01__ECSPI1_MISO 0x011C 0x03E4 0x0604 0x1 0x0
+#define MX6SLL_PAD_LCD_DATA01__USB_OTG1_ID 0x011C 0x03E4 0x055C 0x2 0x3
+#define MX6SLL_PAD_LCD_DATA01__PWM2_OUT 0x011C 0x03E4 0x0000 0x3 0x0
+#define MX6SLL_PAD_LCD_DATA01__AUD4_RXFS 0x011C 0x03E4 0x0570 0x4 0x0
+#define MX6SLL_PAD_LCD_DATA01__GPIO2_IO21 0x011C 0x03E4 0x0000 0x5 0x0
+#define MX6SLL_PAD_LCD_DATA01__ARM_TRACE01 0x011C 0x03E4 0x0000 0x6 0x0
+#define MX6SLL_PAD_LCD_DATA01__SRC_BOOT_CFG01 0x011C 0x03E4 0x0000 0x7 0x0
+#define MX6SLL_PAD_LCD_DATA02__LCD_DATA02 0x0120 0x03E8 0x06E0 0x0 0x1
+#define MX6SLL_PAD_LCD_DATA02__ECSPI1_SS0 0x0120 0x03E8 0x0614 0x1 0x0
+#define MX6SLL_PAD_LCD_DATA02__EPIT2_OUT 0x0120 0x03E8 0x0000 0x2 0x0
+#define MX6SLL_PAD_LCD_DATA02__PWM3_OUT 0x0120 0x03E8 0x0000 0x3 0x0
+#define MX6SLL_PAD_LCD_DATA02__AUD4_RXC 0x0120 0x03E8 0x056C 0x4 0x0
+#define MX6SLL_PAD_LCD_DATA02__GPIO2_IO22 0x0120 0x03E8 0x0000 0x5 0x0
+#define MX6SLL_PAD_LCD_DATA02__ARM_TRACE02 0x0120 0x03E8 0x0000 0x6 0x0
+#define MX6SLL_PAD_LCD_DATA02__SRC_BOOT_CFG02 0x0120 0x03E8 0x0000 0x7 0x0
+#define MX6SLL_PAD_LCD_DATA03__LCD_DATA03 0x0124 0x03EC 0x06E4 0x0 0x1
+#define MX6SLL_PAD_LCD_DATA03__ECSPI1_SCLK 0x0124 0x03EC 0x05FC 0x1 0x0
+#define MX6SLL_PAD_LCD_DATA03__UART5_DSR_B 0x0124 0x03EC 0x0000 0x2 0x0
+#define MX6SLL_PAD_LCD_DATA03__PWM4_OUT 0x0124 0x03EC 0x0000 0x3 0x0
+#define MX6SLL_PAD_LCD_DATA03__AUD4_RXD 0x0124 0x03EC 0x0564 0x4 0x0
+#define MX6SLL_PAD_LCD_DATA03__GPIO2_IO23 0x0124 0x03EC 0x0000 0x5 0x0
+#define MX6SLL_PAD_LCD_DATA03__ARM_TRACE03 0x0124 0x03EC 0x0000 0x6 0x0
+#define MX6SLL_PAD_LCD_DATA03__SRC_BOOT_CFG03 0x0124 0x03EC 0x0000 0x7 0x0
+#define MX6SLL_PAD_LCD_DATA04__LCD_DATA04 0x0128 0x03F0 0x06E8 0x0 0x1
+#define MX6SLL_PAD_LCD_DATA04__ECSPI1_SS1 0x0128 0x03F0 0x060C 0x1 0x1
+#define MX6SLL_PAD_LCD_DATA04__CSI_VSYNC 0x0128 0x03F0 0x05F8 0x2 0x0
+#define MX6SLL_PAD_LCD_DATA04__WDOG2_RESET_B_DEB 0x0128 0x03F0 0x0000 0x3 0x0
+#define MX6SLL_PAD_LCD_DATA04__AUD4_TXC 0x0128 0x03F0 0x0574 0x4 0x0
+#define MX6SLL_PAD_LCD_DATA04__GPIO2_IO24 0x0128 0x03F0 0x0000 0x5 0x0
+#define MX6SLL_PAD_LCD_DATA04__ARM_TRACE04 0x0128 0x03F0 0x0000 0x6 0x0
+#define MX6SLL_PAD_LCD_DATA04__SRC_BOOT_CFG04 0x0128 0x03F0 0x0000 0x7 0x0
+#define MX6SLL_PAD_LCD_DATA05__LCD_DATA05 0x012C 0x03F4 0x06EC 0x0 0x1
+#define MX6SLL_PAD_LCD_DATA05__ECSPI1_SS2 0x012C 0x03F4 0x0610 0x1 0x1
+#define MX6SLL_PAD_LCD_DATA05__CSI_HSYNC 0x012C 0x03F4 0x05F0 0x2 0x0
+#define MX6SLL_PAD_LCD_DATA05__AUD4_TXFS 0x012C 0x03F4 0x0578 0x4 0x0
+#define MX6SLL_PAD_LCD_DATA05__GPIO2_IO25 0x012C 0x03F4 0x0000 0x5 0x0
+#define MX6SLL_PAD_LCD_DATA05__ARM_TRACE05 0x012C 0x03F4 0x0000 0x6 0x0
+#define MX6SLL_PAD_LCD_DATA05__SRC_BOOT_CFG05 0x012C 0x03F4 0x0000 0x7 0x0
+#define MX6SLL_PAD_LCD_DATA06__LCD_DATA06 0x0130 0x03F8 0x06F0 0x0 0x1
+#define MX6SLL_PAD_LCD_DATA06__ECSPI1_SS3 0x0130 0x03F8 0x0618 0x1 0x0
+#define MX6SLL_PAD_LCD_DATA06__CSI_PIXCLK 0x0130 0x03F8 0x05F4 0x2 0x0
+#define MX6SLL_PAD_LCD_DATA06__AUD4_TXD 0x0130 0x03F8 0x0568 0x4 0x0
+#define MX6SLL_PAD_LCD_DATA06__GPIO2_IO26 0x0130 0x03F8 0x0000 0x5 0x0
+#define MX6SLL_PAD_LCD_DATA06__ARM_TRACE06 0x0130 0x03F8 0x0000 0x6 0x0
+#define MX6SLL_PAD_LCD_DATA06__SRC_BOOT_CFG06 0x0130 0x03F8 0x0000 0x7 0x0
+#define MX6SLL_PAD_LCD_DATA07__LCD_DATA07 0x0134 0x03FC 0x06F4 0x0 0x0
+#define MX6SLL_PAD_LCD_DATA07__ECSPI1_RDY 0x0134 0x03FC 0x0600 0x1 0x0
+#define MX6SLL_PAD_LCD_DATA07__CSI_MCLK 0x0134 0x03FC 0x0000 0x2 0x0
+#define MX6SLL_PAD_LCD_DATA07__AUDIO_CLK_OUT 0x0134 0x03FC 0x0000 0x4 0x0
+#define MX6SLL_PAD_LCD_DATA07__GPIO2_IO27 0x0134 0x03FC 0x0000 0x5 0x0
+#define MX6SLL_PAD_LCD_DATA07__ARM_TRACE07 0x0134 0x03FC 0x0000 0x6 0x0
+#define MX6SLL_PAD_LCD_DATA07__SRC_BOOT_CFG07 0x0134 0x03FC 0x0000 0x7 0x0
+#define MX6SLL_PAD_LCD_DATA08__LCD_DATA08 0x0138 0x0400 0x06F8 0x0 0x0
+#define MX6SLL_PAD_LCD_DATA08__KEY_COL0 0x0138 0x0400 0x06A0 0x1 0x1
+#define MX6SLL_PAD_LCD_DATA08__CSI_DATA09 0x0138 0x0400 0x05EC 0x2 0x0
+#define MX6SLL_PAD_LCD_DATA08__ECSPI2_SCLK 0x0138 0x0400 0x061C 0x4 0x0
+#define MX6SLL_PAD_LCD_DATA08__GPIO2_IO28 0x0138 0x0400 0x0000 0x5 0x0
+#define MX6SLL_PAD_LCD_DATA08__ARM_TRACE08 0x0138 0x0400 0x0000 0x6 0x0
+#define MX6SLL_PAD_LCD_DATA08__SRC_BOOT_CFG08 0x0138 0x0400 0x0000 0x7 0x0
+#define MX6SLL_PAD_LCD_DATA09__LCD_DATA09 0x013C 0x0404 0x06FC 0x0 0x0
+#define MX6SLL_PAD_LCD_DATA09__KEY_ROW0 0x013C 0x0404 0x06C0 0x1 0x1
+#define MX6SLL_PAD_LCD_DATA09__CSI_DATA08 0x013C 0x0404 0x05E8 0x2 0x0
+#define MX6SLL_PAD_LCD_DATA09__ECSPI2_MOSI 0x013C 0x0404 0x0624 0x4 0x0
+#define MX6SLL_PAD_LCD_DATA09__GPIO2_IO29 0x013C 0x0404 0x0000 0x5 0x0
+#define MX6SLL_PAD_LCD_DATA09__ARM_TRACE09 0x013C 0x0404 0x0000 0x6 0x0
+#define MX6SLL_PAD_LCD_DATA09__SRC_BOOT_CFG09 0x013C 0x0404 0x0000 0x7 0x0
+#define MX6SLL_PAD_LCD_DATA10__LCD_DATA10 0x0140 0x0408 0x0700 0x0 0x1
+#define MX6SLL_PAD_LCD_DATA10__KEY_COL1 0x0140 0x0408 0x06A4 0x1 0x1
+#define MX6SLL_PAD_LCD_DATA10__CSI_DATA07 0x0140 0x0408 0x05E4 0x2 0x0
+#define MX6SLL_PAD_LCD_DATA10__ECSPI2_MISO 0x0140 0x0408 0x0620 0x4 0x0
+#define MX6SLL_PAD_LCD_DATA10__GPIO2_IO30 0x0140 0x0408 0x0000 0x5 0x0
+#define MX6SLL_PAD_LCD_DATA10__ARM_TRACE10 0x0140 0x0408 0x0000 0x6 0x0
+#define MX6SLL_PAD_LCD_DATA10__SRC_BOOT_CFG10 0x0140 0x0408 0x0000 0x7 0x0
+#define MX6SLL_PAD_LCD_DATA11__LCD_DATA11 0x0144 0x040C 0x0704 0x0 0x0
+#define MX6SLL_PAD_LCD_DATA11__KEY_ROW1 0x0144 0x040C 0x06C4 0x1 0x1
+#define MX6SLL_PAD_LCD_DATA11__CSI_DATA06 0x0144 0x040C 0x05E0 0x2 0x0
+#define MX6SLL_PAD_LCD_DATA11__ECSPI2_SS1 0x0144 0x040C 0x062C 0x4 0x0
+#define MX6SLL_PAD_LCD_DATA11__GPIO2_IO31 0x0144 0x040C 0x0000 0x5 0x0
+#define MX6SLL_PAD_LCD_DATA11__ARM_TRACE11 0x0144 0x040C 0x0000 0x6 0x0
+#define MX6SLL_PAD_LCD_DATA11__SRC_BOOT_CFG11 0x0144 0x040C 0x0000 0x7 0x0
+#define MX6SLL_PAD_LCD_DATA12__LCD_DATA12 0x0148 0x0410 0x0708 0x0 0x0
+#define MX6SLL_PAD_LCD_DATA12__KEY_COL2 0x0148 0x0410 0x06A8 0x1 0x1
+#define MX6SLL_PAD_LCD_DATA12__CSI_DATA05 0x0148 0x0410 0x05DC 0x2 0x0
+#define MX6SLL_PAD_LCD_DATA12__UART5_DCE_RTS 0x0148 0x0410 0x0760 0x4 0x0
+#define MX6SLL_PAD_LCD_DATA12__UART5_DTE_CTS 0x0148 0x0410 0x0000 0x4 0x0
+#define MX6SLL_PAD_LCD_DATA12__GPIO3_IO00 0x0148 0x0410 0x0000 0x5 0x0
+#define MX6SLL_PAD_LCD_DATA12__ARM_TRACE12 0x0148 0x0410 0x0000 0x6 0x0
+#define MX6SLL_PAD_LCD_DATA12__SRC_BOOT_CFG12 0x0148 0x0410 0x0000 0x7 0x0
+#define MX6SLL_PAD_LCD_DATA13__LCD_DATA13 0x014C 0x0414 0x070C 0x0 0x0
+#define MX6SLL_PAD_LCD_DATA13__KEY_ROW2 0x014C 0x0414 0x06C8 0x1 0x1
+#define MX6SLL_PAD_LCD_DATA13__CSI_DATA04 0x014C 0x0414 0x05D8 0x2 0x0
+#define MX6SLL_PAD_LCD_DATA13__UART5_DCE_CTS 0x014C 0x0414 0x0000 0x4 0x0
+#define MX6SLL_PAD_LCD_DATA13__UART5_DTE_RTS 0x014C 0x0414 0x0760 0x4 0x1
+#define MX6SLL_PAD_LCD_DATA13__GPIO3_IO01 0x014C 0x0414 0x0000 0x5 0x0
+#define MX6SLL_PAD_LCD_DATA13__ARM_TRACE13 0x014C 0x0414 0x0000 0x6 0x0
+#define MX6SLL_PAD_LCD_DATA13__SRC_BOOT_CFG13 0x014C 0x0414 0x0000 0x7 0x0
+#define MX6SLL_PAD_LCD_DATA14__LCD_DATA14 0x0150 0x0418 0x0710 0x0 0x0
+#define MX6SLL_PAD_LCD_DATA14__KEY_COL3 0x0150 0x0418 0x06AC 0x1 0x1
+#define MX6SLL_PAD_LCD_DATA14__CSI_DATA03 0x0150 0x0418 0x05D4 0x2 0x0
+#define MX6SLL_PAD_LCD_DATA14__UART5_DCE_RX 0x0150 0x0418 0x0764 0x4 0x0
+#define MX6SLL_PAD_LCD_DATA14__UART5_DTE_TX 0x0150 0x0418 0x0000 0x4 0x0
+#define MX6SLL_PAD_LCD_DATA14__GPIO3_IO02 0x0150 0x0418 0x0000 0x5 0x0
+#define MX6SLL_PAD_LCD_DATA14__ARM_TRACE14 0x0150 0x0418 0x0000 0x6 0x0
+#define MX6SLL_PAD_LCD_DATA14__SRC_BOOT_CFG14 0x0150 0x0418 0x0000 0x7 0x0
+#define MX6SLL_PAD_LCD_DATA15__LCD_DATA15 0x0154 0x041C 0x0714 0x0 0x0
+#define MX6SLL_PAD_LCD_DATA15__KEY_ROW3 0x0154 0x041C 0x06CC 0x1 0x0
+#define MX6SLL_PAD_LCD_DATA15__CSI_DATA02 0x0154 0x041C 0x05D0 0x2 0x0
+#define MX6SLL_PAD_LCD_DATA15__UART5_DCE_TX 0x0154 0x041C 0x0000 0x4 0x0
+#define MX6SLL_PAD_LCD_DATA15__UART5_DTE_RX 0x0154 0x041C 0x0764 0x4 0x1
+#define MX6SLL_PAD_LCD_DATA15__GPIO3_IO03 0x0154 0x041C 0x0000 0x5 0x0
+#define MX6SLL_PAD_LCD_DATA15__ARM_TRACE15 0x0154 0x041C 0x0000 0x6 0x0
+#define MX6SLL_PAD_LCD_DATA15__SRC_BOOT_CFG15 0x0154 0x041C 0x0000 0x7 0x0
+#define MX6SLL_PAD_LCD_DATA16__LCD_DATA16 0x0158 0x0420 0x0718 0x0 0x0
+#define MX6SLL_PAD_LCD_DATA16__KEY_COL4 0x0158 0x0420 0x06B0 0x1 0x0
+#define MX6SLL_PAD_LCD_DATA16__CSI_DATA01 0x0158 0x0420 0x05CC 0x2 0x0
+#define MX6SLL_PAD_LCD_DATA16__I2C2_SCL 0x0158 0x0420 0x0684 0x4 0x1
+#define MX6SLL_PAD_LCD_DATA16__GPIO3_IO04 0x0158 0x0420 0x0000 0x5 0x0
+#define MX6SLL_PAD_LCD_DATA16__SRC_BOOT_CFG24 0x0158 0x0420 0x0000 0x7 0x0
+#define MX6SLL_PAD_LCD_DATA17__LCD_DATA17 0x015C 0x0424 0x071C 0x0 0x0
+#define MX6SLL_PAD_LCD_DATA17__KEY_ROW4 0x015C 0x0424 0x06D0 0x1 0x0
+#define MX6SLL_PAD_LCD_DATA17__CSI_DATA00 0x015C 0x0424 0x05C8 0x2 0x0
+#define MX6SLL_PAD_LCD_DATA17__I2C2_SDA 0x015C 0x0424 0x0688 0x4 0x1
+#define MX6SLL_PAD_LCD_DATA17__GPIO3_IO05 0x015C 0x0424 0x0000 0x5 0x0
+#define MX6SLL_PAD_LCD_DATA17__SRC_BOOT_CFG25 0x015C 0x0424 0x0000 0x7 0x0
+#define MX6SLL_PAD_LCD_DATA18__LCD_DATA18 0x0160 0x0428 0x0720 0x0 0x0
+#define MX6SLL_PAD_LCD_DATA18__KEY_COL5 0x0160 0x0428 0x0694 0x1 0x2
+#define MX6SLL_PAD_LCD_DATA18__CSI_DATA15 0x0160 0x0428 0x05C4 0x2 0x1
+#define MX6SLL_PAD_LCD_DATA18__GPT_CAPTURE1 0x0160 0x0428 0x0670 0x4 0x1
+#define MX6SLL_PAD_LCD_DATA18__GPIO3_IO06 0x0160 0x0428 0x0000 0x5 0x0
+#define MX6SLL_PAD_LCD_DATA18__SRC_BOOT_CFG26 0x0160 0x0428 0x0000 0x7 0x0
+#define MX6SLL_PAD_LCD_DATA19__LCD_DATA19 0x0164 0x042C 0x0724 0x0 0x0
+#define MX6SLL_PAD_LCD_DATA19__KEY_ROW5 0x0164 0x042C 0x06B4 0x1 0x1
+#define MX6SLL_PAD_LCD_DATA19__CSI_DATA14 0x0164 0x042C 0x05C0 0x2 0x2
+#define MX6SLL_PAD_LCD_DATA19__GPT_CAPTURE2 0x0164 0x042C 0x0674 0x4 0x1
+#define MX6SLL_PAD_LCD_DATA19__GPIO3_IO07 0x0164 0x042C 0x0000 0x5 0x0
+#define MX6SLL_PAD_LCD_DATA19__SRC_BOOT_CFG27 0x0164 0x042C 0x0000 0x7 0x0
+#define MX6SLL_PAD_LCD_DATA20__LCD_DATA20 0x0168 0x0430 0x0728 0x0 0x0
+#define MX6SLL_PAD_LCD_DATA20__KEY_COL6 0x0168 0x0430 0x0698 0x1 0x1
+#define MX6SLL_PAD_LCD_DATA20__CSI_DATA13 0x0168 0x0430 0x05BC 0x2 0x2
+#define MX6SLL_PAD_LCD_DATA20__GPT_COMPARE1 0x0168 0x0430 0x0000 0x4 0x0
+#define MX6SLL_PAD_LCD_DATA20__GPIO3_IO08 0x0168 0x0430 0x0000 0x5 0x0
+#define MX6SLL_PAD_LCD_DATA20__SRC_BOOT_CFG28 0x0168 0x0430 0x0000 0x7 0x0
+#define MX6SLL_PAD_LCD_DATA21__LCD_DATA21 0x016C 0x0434 0x072C 0x0 0x0
+#define MX6SLL_PAD_LCD_DATA21__KEY_ROW6 0x016C 0x0434 0x06B8 0x1 0x1
+#define MX6SLL_PAD_LCD_DATA21__CSI_DATA12 0x016C 0x0434 0x05B8 0x2 0x2
+#define MX6SLL_PAD_LCD_DATA21__GPT_COMPARE2 0x016C 0x0434 0x0000 0x4 0x0
+#define MX6SLL_PAD_LCD_DATA21__GPIO3_IO09 0x016C 0x0434 0x0000 0x5 0x0
+#define MX6SLL_PAD_LCD_DATA21__SRC_BOOT_CFG29 0x016C 0x0434 0x0000 0x7 0x0
+#define MX6SLL_PAD_LCD_DATA22__LCD_DATA22 0x0170 0x0438 0x0730 0x0 0x0
+#define MX6SLL_PAD_LCD_DATA22__KEY_COL7 0x0170 0x0438 0x069C 0x1 0x1
+#define MX6SLL_PAD_LCD_DATA22__CSI_DATA11 0x0170 0x0438 0x05B4 0x2 0x1
+#define MX6SLL_PAD_LCD_DATA22__GPT_COMPARE3 0x0170 0x0438 0x0000 0x4 0x0
+#define MX6SLL_PAD_LCD_DATA22__GPIO3_IO10 0x0170 0x0438 0x0000 0x5 0x0
+#define MX6SLL_PAD_LCD_DATA22__SRC_BOOT_CFG30 0x0170 0x0438 0x0000 0x7 0x0
+#define MX6SLL_PAD_LCD_DATA23__LCD_DATA23 0x0174 0x043C 0x0734 0x0 0x0
+#define MX6SLL_PAD_LCD_DATA23__KEY_ROW7 0x0174 0x043C 0x06BC 0x1 0x1
+#define MX6SLL_PAD_LCD_DATA23__CSI_DATA10 0x0174 0x043C 0x05B0 0x2 0x1
+#define MX6SLL_PAD_LCD_DATA23__GPT_CLKIN 0x0174 0x043C 0x0678 0x4 0x1
+#define MX6SLL_PAD_LCD_DATA23__GPIO3_IO11 0x0174 0x043C 0x0000 0x5 0x0
+#define MX6SLL_PAD_LCD_DATA23__SRC_BOOT_CFG31 0x0174 0x043C 0x0000 0x7 0x0
+#define MX6SLL_PAD_AUD_RXFS__AUD3_RXFS 0x0178 0x0440 0x0000 0x0 0x0
+#define MX6SLL_PAD_AUD_RXFS__I2C1_SCL 0x0178 0x0440 0x067C 0x1 0x1
+#define MX6SLL_PAD_AUD_RXFS__UART3_DCE_RX 0x0178 0x0440 0x0754 0x2 0x0
+#define MX6SLL_PAD_AUD_RXFS__UART3_DTE_TX 0x0178 0x0440 0x0000 0x2 0x0
+#define MX6SLL_PAD_AUD_RXFS__I2C3_SCL 0x0178 0x0440 0x068C 0x4 0x1
+#define MX6SLL_PAD_AUD_RXFS__GPIO1_IO00 0x0178 0x0440 0x0000 0x5 0x0
+#define MX6SLL_PAD_AUD_RXFS__ECSPI3_SS0 0x0178 0x0440 0x0648 0x6 0x0
+#define MX6SLL_PAD_AUD_RXFS__MBIST_BEND 0x0178 0x0440 0x0000 0x7 0x0
+#define MX6SLL_PAD_AUD_RXC__AUD3_RXC 0x017C 0x0444 0x0000 0x0 0x0
+#define MX6SLL_PAD_AUD_RXC__I2C1_SDA 0x017C 0x0444 0x0680 0x1 0x1
+#define MX6SLL_PAD_AUD_RXC__UART3_DCE_TX 0x017C 0x0444 0x0000 0x2 0x0
+#define MX6SLL_PAD_AUD_RXC__UART3_DTE_RX 0x017C 0x0444 0x0754 0x2 0x1
+#define MX6SLL_PAD_AUD_RXC__I2C3_SDA 0x017C 0x0444 0x0690 0x4 0x1
+#define MX6SLL_PAD_AUD_RXC__GPIO1_IO01 0x017C 0x0444 0x0000 0x5 0x0
+#define MX6SLL_PAD_AUD_RXC__ECSPI3_SS1 0x017C 0x0444 0x064C 0x6 0x0
+#define MX6SLL_PAD_AUD_RXD__AUD3_RXD 0x0180 0x0448 0x0000 0x0 0x0
+#define MX6SLL_PAD_AUD_RXD__ECSPI3_MOSI 0x0180 0x0448 0x063C 0x1 0x0
+#define MX6SLL_PAD_AUD_RXD__UART4_DCE_RX 0x0180 0x0448 0x075C 0x2 0x0
+#define MX6SLL_PAD_AUD_RXD__UART4_DTE_TX 0x0180 0x0448 0x0000 0x2 0x0
+#define MX6SLL_PAD_AUD_RXD__SD1_LCTL 0x0180 0x0448 0x0000 0x4 0x0
+#define MX6SLL_PAD_AUD_RXD__GPIO1_IO02 0x0180 0x0448 0x0000 0x5 0x0
+#define MX6SLL_PAD_AUD_TXC__AUD3_TXC 0x0184 0x044C 0x0000 0x0 0x0
+#define MX6SLL_PAD_AUD_TXC__ECSPI3_MISO 0x0184 0x044C 0x0638 0x1 0x0
+#define MX6SLL_PAD_AUD_TXC__UART4_DCE_TX 0x0184 0x044C 0x0000 0x2 0x0
+#define MX6SLL_PAD_AUD_TXC__UART4_DTE_RX 0x0184 0x044C 0x075C 0x2 0x1
+#define MX6SLL_PAD_AUD_TXC__SD2_LCTL 0x0184 0x044C 0x0000 0x4 0x0
+#define MX6SLL_PAD_AUD_TXC__GPIO1_IO03 0x0184 0x044C 0x0000 0x5 0x0
+#define MX6SLL_PAD_AUD_TXFS__AUD3_TXFS 0x0188 0x0450 0x0000 0x0 0x0
+#define MX6SLL_PAD_AUD_TXFS__PWM3_OUT 0x0188 0x0450 0x0000 0x1 0x0
+#define MX6SLL_PAD_AUD_TXFS__UART4_DCE_RTS 0x0188 0x0450 0x0758 0x2 0x0
+#define MX6SLL_PAD_AUD_TXFS__UART4_DTE_CTS 0x0188 0x0450 0x0000 0x2 0x0
+#define MX6SLL_PAD_AUD_TXFS__SD3_LCTL 0x0188 0x0450 0x0000 0x4 0x0
+#define MX6SLL_PAD_AUD_TXFS__GPIO1_IO04 0x0188 0x0450 0x0000 0x5 0x0
+#define MX6SLL_PAD_AUD_TXD__AUD3_TXD 0x018C 0x0454 0x0000 0x0 0x0
+#define MX6SLL_PAD_AUD_TXD__ECSPI3_SCLK 0x018C 0x0454 0x0630 0x1 0x0
+#define MX6SLL_PAD_AUD_TXD__UART4_DCE_CTS 0x018C 0x0454 0x0000 0x2 0x0
+#define MX6SLL_PAD_AUD_TXD__UART4_DTE_RTS 0x018C 0x0454 0x0758 0x2 0x1
+#define MX6SLL_PAD_AUD_TXD__GPIO1_IO05 0x018C 0x0454 0x0000 0x5 0x0
+#define MX6SLL_PAD_AUD_MCLK__AUDIO_CLK_OUT 0x0190 0x0458 0x0000 0x0 0x0
+#define MX6SLL_PAD_AUD_MCLK__PWM4_OUT 0x0190 0x0458 0x0000 0x1 0x0
+#define MX6SLL_PAD_AUD_MCLK__ECSPI3_RDY 0x0190 0x0458 0x0634 0x2 0x0
+#define MX6SLL_PAD_AUD_MCLK__WDOG2_RESET_B_DEB 0x0190 0x0458 0x0000 0x4 0x0
+#define MX6SLL_PAD_AUD_MCLK__GPIO1_IO06 0x0190 0x0458 0x0000 0x5 0x0
+#define MX6SLL_PAD_AUD_MCLK__SPDIF_EXT_CLK 0x0190 0x0458 0x073C 0x6 0x1
+#define MX6SLL_PAD_UART1_RXD__UART1_DCE_RX 0x0194 0x045C 0x0744 0x0 0x0
+#define MX6SLL_PAD_UART1_RXD__UART1_DTE_TX 0x0194 0x045C 0x0000 0x0 0x0
+#define MX6SLL_PAD_UART1_RXD__PWM1_OUT 0x0194 0x045C 0x0000 0x1 0x0
+#define MX6SLL_PAD_UART1_RXD__UART4_DCE_RX 0x0194 0x045C 0x075C 0x2 0x4
+#define MX6SLL_PAD_UART1_RXD__UART4_DTE_TX 0x0194 0x045C 0x0000 0x2 0x0
+#define MX6SLL_PAD_UART1_RXD__UART5_DCE_RX 0x0194 0x045C 0x0764 0x4 0x6
+#define MX6SLL_PAD_UART1_RXD__UART5_DTE_TX 0x0194 0x045C 0x0000 0x4 0x0
+#define MX6SLL_PAD_UART1_RXD__GPIO3_IO16 0x0194 0x045C 0x0000 0x5 0x0
+#define MX6SLL_PAD_UART1_TXD__UART1_DCE_TX 0x0198 0x0460 0x0000 0x0 0x0
+#define MX6SLL_PAD_UART1_TXD__UART1_DTE_RX 0x0198 0x0460 0x0744 0x0 0x1
+#define MX6SLL_PAD_UART1_TXD__PWM2_OUT 0x0198 0x0460 0x0000 0x1 0x0
+#define MX6SLL_PAD_UART1_TXD__UART4_DCE_TX 0x0198 0x0460 0x0000 0x2 0x0
+#define MX6SLL_PAD_UART1_TXD__UART4_DTE_RX 0x0198 0x0460 0x075C 0x2 0x5
+#define MX6SLL_PAD_UART1_TXD__UART5_DCE_TX 0x0198 0x0460 0x0000 0x4 0x0
+#define MX6SLL_PAD_UART1_TXD__UART5_DTE_RX 0x0198 0x0460 0x0764 0x4 0x7
+#define MX6SLL_PAD_UART1_TXD__GPIO3_IO17 0x0198 0x0460 0x0000 0x5 0x0
+#define MX6SLL_PAD_UART1_TXD__UART5_DCD_B 0x0198 0x0460 0x0000 0x7 0x0
+#define MX6SLL_PAD_I2C1_SCL__I2C1_SCL 0x019C 0x0464 0x067C 0x0 0x0
+#define MX6SLL_PAD_I2C1_SCL__UART1_DCE_RTS 0x019C 0x0464 0x0740 0x1 0x0
+#define MX6SLL_PAD_I2C1_SCL__UART1_DTE_CTS 0x019C 0x0464 0x0000 0x1 0x0
+#define MX6SLL_PAD_I2C1_SCL__ECSPI3_SS2 0x019C 0x0464 0x0640 0x2 0x0
+#define MX6SLL_PAD_I2C1_SCL__SD3_RESET 0x019C 0x0464 0x0000 0x4 0x0
+#define MX6SLL_PAD_I2C1_SCL__GPIO3_IO12 0x019C 0x0464 0x0000 0x5 0x0
+#define MX6SLL_PAD_I2C1_SCL__ECSPI1_SS1 0x019C 0x0464 0x060C 0x6 0x0
+#define MX6SLL_PAD_I2C1_SDA__I2C1_SDA 0x01A0 0x0468 0x0680 0x0 0x0
+#define MX6SLL_PAD_I2C1_SDA__UART1_DCE_CTS 0x01A0 0x0468 0x0000 0x1 0x0
+#define MX6SLL_PAD_I2C1_SDA__UART1_DTE_RTS 0x01A0 0x0468 0x0740 0x1 0x1
+#define MX6SLL_PAD_I2C1_SDA__ECSPI3_SS3 0x01A0 0x0468 0x0644 0x2 0x0
+#define MX6SLL_PAD_I2C1_SDA__SD3_VSELECT 0x01A0 0x0468 0x0000 0x4 0x0
+#define MX6SLL_PAD_I2C1_SDA__GPIO3_IO13 0x01A0 0x0468 0x0000 0x5 0x0
+#define MX6SLL_PAD_I2C1_SDA__ECSPI1_SS2 0x01A0 0x0468 0x0610 0x6 0x0
+#define MX6SLL_PAD_I2C2_SCL__I2C2_SCL 0x01A4 0x046C 0x0684 0x0 0x3
+#define MX6SLL_PAD_I2C2_SCL__AUD4_RXFS 0x01A4 0x046C 0x0570 0x1 0x2
+#define MX6SLL_PAD_I2C2_SCL__SPDIF_IN 0x01A4 0x046C 0x0738 0x2 0x2
+#define MX6SLL_PAD_I2C2_SCL__SD3_WP 0x01A4 0x046C 0x0794 0x4 0x3
+#define MX6SLL_PAD_I2C2_SCL__GPIO3_IO14 0x01A4 0x046C 0x0000 0x5 0x0
+#define MX6SLL_PAD_I2C2_SCL__ECSPI1_RDY 0x01A4 0x046C 0x0600 0x6 0x1
+#define MX6SLL_PAD_I2C2_SDA__I2C2_SDA 0x01A8 0x0470 0x0688 0x0 0x3
+#define MX6SLL_PAD_I2C2_SDA__AUD4_RXC 0x01A8 0x0470 0x056C 0x1 0x2
+#define MX6SLL_PAD_I2C2_SDA__SPDIF_OUT 0x01A8 0x0470 0x0000 0x2 0x0
+#define MX6SLL_PAD_I2C2_SDA__SD3_CD_B 0x01A8 0x0470 0x0780 0x4 0x3
+#define MX6SLL_PAD_I2C2_SDA__GPIO3_IO15 0x01A8 0x0470 0x0000 0x5 0x0
+#define MX6SLL_PAD_ECSPI1_SCLK__ECSPI1_SCLK 0x01AC 0x0474 0x05FC 0x0 0x1
+#define MX6SLL_PAD_ECSPI1_SCLK__AUD4_TXD 0x01AC 0x0474 0x0568 0x1 0x1
+#define MX6SLL_PAD_ECSPI1_SCLK__UART5_DCE_RX 0x01AC 0x0474 0x0764 0x2 0x2
+#define MX6SLL_PAD_ECSPI1_SCLK__UART5_DTE_TX 0x01AC 0x0474 0x0000 0x2 0x0
+#define MX6SLL_PAD_ECSPI1_SCLK__EPDC_VCOM0 0x01AC 0x0474 0x0000 0x3 0x0
+#define MX6SLL_PAD_ECSPI1_SCLK__SD2_RESET 0x01AC 0x0474 0x0000 0x4 0x0
+#define MX6SLL_PAD_ECSPI1_SCLK__GPIO4_IO08 0x01AC 0x0474 0x0000 0x5 0x0
+#define MX6SLL_PAD_ECSPI1_SCLK__USB_OTG2_OC 0x01AC 0x0474 0x0768 0x6 0x1
+#define MX6SLL_PAD_ECSPI1_MOSI__ECSPI1_MOSI 0x01B0 0x0478 0x0608 0x0 0x1
+#define MX6SLL_PAD_ECSPI1_MOSI__AUD4_TXC 0x01B0 0x0478 0x0574 0x1 0x1
+#define MX6SLL_PAD_ECSPI1_MOSI__UART5_DCE_TX 0x01B0 0x0478 0x0000 0x2 0x0
+#define MX6SLL_PAD_ECSPI1_MOSI__UART5_DTE_RX 0x01B0 0x0478 0x0764 0x2 0x3
+#define MX6SLL_PAD_ECSPI1_MOSI__EPDC_VCOM1 0x01B0 0x0478 0x0000 0x3 0x0
+#define MX6SLL_PAD_ECSPI1_MOSI__SD2_VSELECT 0x01B0 0x0478 0x0000 0x4 0x0
+#define MX6SLL_PAD_ECSPI1_MOSI__GPIO4_IO09 0x01B0 0x0478 0x0000 0x5 0x0
+#define MX6SLL_PAD_ECSPI1_MISO__ECSPI1_MISO 0x01B4 0x047C 0x0604 0x0 0x1
+#define MX6SLL_PAD_ECSPI1_MISO__AUD4_TXFS 0x01B4 0x047C 0x0578 0x1 0x1
+#define MX6SLL_PAD_ECSPI1_MISO__UART5_DCE_RTS 0x01B4 0x047C 0x0760 0x2 0x2
+#define MX6SLL_PAD_ECSPI1_MISO__UART5_DTE_CTS 0x01B4 0x047C 0x0000 0x2 0x0
+#define MX6SLL_PAD_ECSPI1_MISO__EPDC_BDR0 0x01B4 0x047C 0x0000 0x3 0x0
+#define MX6SLL_PAD_ECSPI1_MISO__SD2_WP 0x01B4 0x047C 0x077C 0x4 0x0
+#define MX6SLL_PAD_ECSPI1_MISO__GPIO4_IO10 0x01B4 0x047C 0x0000 0x5 0x0
+#define MX6SLL_PAD_ECSPI1_SS0__ECSPI1_SS0 0x01B8 0x0480 0x0614 0x0 0x1
+#define MX6SLL_PAD_ECSPI1_SS0__AUD4_RXD 0x01B8 0x0480 0x0564 0x1 0x1
+#define MX6SLL_PAD_ECSPI1_SS0__UART5_DCE_CTS 0x01B8 0x0480 0x0000 0x2 0x0
+#define MX6SLL_PAD_ECSPI1_SS0__UART5_DTE_RTS 0x01B8 0x0480 0x0760 0x2 0x3
+#define MX6SLL_PAD_ECSPI1_SS0__EPDC_BDR1 0x01B8 0x0480 0x0000 0x3 0x0
+#define MX6SLL_PAD_ECSPI1_SS0__SD2_CD_B 0x01B8 0x0480 0x0778 0x4 0x0
+#define MX6SLL_PAD_ECSPI1_SS0__GPIO4_IO11 0x01B8 0x0480 0x0000 0x5 0x0
+#define MX6SLL_PAD_ECSPI1_SS0__USB_OTG2_PWR 0x01B8 0x0480 0x0000 0x6 0x0
+#define MX6SLL_PAD_ECSPI2_SCLK__ECSPI2_SCLK 0x01BC 0x0484 0x061C 0x0 0x1
+#define MX6SLL_PAD_ECSPI2_SCLK__SPDIF_EXT_CLK 0x01BC 0x0484 0x073C 0x1 0x2
+#define MX6SLL_PAD_ECSPI2_SCLK__UART3_DCE_RX 0x01BC 0x0484 0x0754 0x2 0x2
+#define MX6SLL_PAD_ECSPI2_SCLK__UART3_DTE_TX 0x01BC 0x0484 0x0000 0x2 0x0
+#define MX6SLL_PAD_ECSPI2_SCLK__CSI_PIXCLK 0x01BC 0x0484 0x05F4 0x3 0x1
+#define MX6SLL_PAD_ECSPI2_SCLK__SD1_RESET 0x01BC 0x0484 0x0000 0x4 0x0
+#define MX6SLL_PAD_ECSPI2_SCLK__GPIO4_IO12 0x01BC 0x0484 0x0000 0x5 0x0
+#define MX6SLL_PAD_ECSPI2_SCLK__USB_OTG2_OC 0x01BC 0x0484 0x0768 0x6 0x2
+#define MX6SLL_PAD_ECSPI2_MOSI__ECSPI2_MOSI 0x01C0 0x0488 0x0624 0x0 0x1
+#define MX6SLL_PAD_ECSPI2_MOSI__SDMA_EXT_EVENT1 0x01C0 0x0488 0x0000 0x1 0x0
+#define MX6SLL_PAD_ECSPI2_MOSI__UART3_DCE_TX 0x01C0 0x0488 0x0000 0x2 0x0
+#define MX6SLL_PAD_ECSPI2_MOSI__UART3_DTE_RX 0x01C0 0x0488 0x0754 0x2 0x3
+#define MX6SLL_PAD_ECSPI2_MOSI__CSI_HSYNC 0x01C0 0x0488 0x05F0 0x3 0x1
+#define MX6SLL_PAD_ECSPI2_MOSI__SD1_VSELECT 0x01C0 0x0488 0x0000 0x4 0x0
+#define MX6SLL_PAD_ECSPI2_MOSI__GPIO4_IO13 0x01C0 0x0488 0x0000 0x5 0x0
+#define MX6SLL_PAD_ECSPI2_MISO__ECSPI2_MISO 0x01C4 0x048C 0x0620 0x0 0x1
+#define MX6SLL_PAD_ECSPI2_MISO__SDMA_EXT_EVENT0 0x01C4 0x048C 0x0000 0x1 0x0
+#define MX6SLL_PAD_ECSPI2_MISO__UART3_DCE_RTS 0x01C4 0x048C 0x0750 0x2 0x0
+#define MX6SLL_PAD_ECSPI2_MISO__UART3_DTE_CTS 0x01C4 0x048C 0x0000 0x2 0x0
+#define MX6SLL_PAD_ECSPI2_MISO__CSI_MCLK 0x01C4 0x048C 0x0000 0x3 0x0
+#define MX6SLL_PAD_ECSPI2_MISO__SD1_WP 0x01C4 0x048C 0x0774 0x4 0x2
+#define MX6SLL_PAD_ECSPI2_MISO__GPIO4_IO14 0x01C4 0x048C 0x0000 0x5 0x0
+#define MX6SLL_PAD_ECSPI2_MISO__USB_OTG1_OC 0x01C4 0x048C 0x076C 0x6 0x1
+#define MX6SLL_PAD_ECSPI2_SS0__ECSPI2_SS0 0x01C8 0x0490 0x0628 0x0 0x0
+#define MX6SLL_PAD_ECSPI2_SS0__ECSPI1_SS3 0x01C8 0x0490 0x0618 0x1 0x1
+#define MX6SLL_PAD_ECSPI2_SS0__UART3_DCE_CTS 0x01C8 0x0490 0x0000 0x2 0x0
+#define MX6SLL_PAD_ECSPI2_SS0__UART3_DTE_RTS 0x01C8 0x0490 0x0750 0x2 0x1
+#define MX6SLL_PAD_ECSPI2_SS0__CSI_VSYNC 0x01C8 0x0490 0x05F8 0x3 0x1
+#define MX6SLL_PAD_ECSPI2_SS0__SD1_CD_B 0x01C8 0x0490 0x0770 0x4 0x2
+#define MX6SLL_PAD_ECSPI2_SS0__GPIO4_IO15 0x01C8 0x0490 0x0000 0x5 0x0
+#define MX6SLL_PAD_ECSPI2_SS0__USB_OTG1_PWR 0x01C8 0x0490 0x0000 0x6 0x0
+#define MX6SLL_PAD_SD1_CLK__SD1_CLK 0x01CC 0x0494 0x0000 0x0 0x0
+#define MX6SLL_PAD_SD1_CLK__KEY_COL0 0x01CC 0x0494 0x06A0 0x2 0x2
+#define MX6SLL_PAD_SD1_CLK__EPDC_SDCE4 0x01CC 0x0494 0x0000 0x3 0x0
+#define MX6SLL_PAD_SD1_CLK__GPIO5_IO15 0x01CC 0x0494 0x0000 0x5 0x0
+#define MX6SLL_PAD_SD1_CMD__SD1_CMD 0x01D0 0x0498 0x0000 0x0 0x0
+#define MX6SLL_PAD_SD1_CMD__KEY_ROW0 0x01D0 0x0498 0x06C0 0x2 0x2
+#define MX6SLL_PAD_SD1_CMD__EPDC_SDCE5 0x01D0 0x0498 0x0000 0x3 0x0
+#define MX6SLL_PAD_SD1_CMD__GPIO5_IO14 0x01D0 0x0498 0x0000 0x5 0x0
+#define MX6SLL_PAD_SD1_DATA0__SD1_DATA0 0x01D4 0x049C 0x0000 0x0 0x0
+#define MX6SLL_PAD_SD1_DATA0__KEY_COL1 0x01D4 0x049C 0x06A4 0x2 0x2
+#define MX6SLL_PAD_SD1_DATA0__EPDC_SDCE6 0x01D4 0x049C 0x0000 0x3 0x0
+#define MX6SLL_PAD_SD1_DATA0__GPIO5_IO11 0x01D4 0x049C 0x0000 0x5 0x0
+#define MX6SLL_PAD_SD1_DATA1__SD1_DATA1 0x01D8 0x04A0 0x0000 0x0 0x0
+#define MX6SLL_PAD_SD1_DATA1__KEY_ROW1 0x01D8 0x04A0 0x06C4 0x2 0x2
+#define MX6SLL_PAD_SD1_DATA1__EPDC_SDCE7 0x01D8 0x04A0 0x0000 0x3 0x0
+#define MX6SLL_PAD_SD1_DATA1__GPIO5_IO08 0x01D8 0x04A0 0x0000 0x5 0x0
+#define MX6SLL_PAD_SD1_DATA2__SD1_DATA2 0x01DC 0x04A4 0x0000 0x0 0x0
+#define MX6SLL_PAD_SD1_DATA2__KEY_COL2 0x01DC 0x04A4 0x06A8 0x2 0x2
+#define MX6SLL_PAD_SD1_DATA2__EPDC_SDCE8 0x01DC 0x04A4 0x0000 0x3 0x0
+#define MX6SLL_PAD_SD1_DATA2__GPIO5_IO13 0x01DC 0x04A4 0x0000 0x5 0x0
+#define MX6SLL_PAD_SD1_DATA3__SD1_DATA3 0x01E0 0x04A8 0x0000 0x0 0x0
+#define MX6SLL_PAD_SD1_DATA3__KEY_ROW2 0x01E0 0x04A8 0x06C8 0x2 0x2
+#define MX6SLL_PAD_SD1_DATA3__EPDC_SDCE9 0x01E0 0x04A8 0x0000 0x3 0x0
+#define MX6SLL_PAD_SD1_DATA3__GPIO5_IO06 0x01E0 0x04A8 0x0000 0x5 0x0
+#define MX6SLL_PAD_SD1_DATA4__SD1_DATA4 0x01E4 0x04AC 0x0000 0x0 0x0
+#define MX6SLL_PAD_SD1_DATA4__KEY_COL3 0x01E4 0x04AC 0x06AC 0x2 0x2
+#define MX6SLL_PAD_SD1_DATA4__EPDC_SDCLK_N 0x01E4 0x04AC 0x0000 0x3 0x0
+#define MX6SLL_PAD_SD1_DATA4__UART4_DCE_RX 0x01E4 0x04AC 0x075C 0x4 0x6
+#define MX6SLL_PAD_SD1_DATA4__UART4_DTE_TX 0x01E4 0x04AC 0x0000 0x4 0x0
+#define MX6SLL_PAD_SD1_DATA4__GPIO5_IO12 0x01E4 0x04AC 0x0000 0x5 0x0
+#define MX6SLL_PAD_SD1_DATA5__SD1_DATA5 0x01E8 0x04B0 0x0000 0x0 0x0
+#define MX6SLL_PAD_SD1_DATA5__KEY_ROW3 0x01E8 0x04B0 0x06CC 0x2 0x2
+#define MX6SLL_PAD_SD1_DATA5__EPDC_SDOED 0x01E8 0x04B0 0x0000 0x3 0x0
+#define MX6SLL_PAD_SD1_DATA5__UART4_DCE_TX 0x01E8 0x04B0 0x0000 0x4 0x0
+#define MX6SLL_PAD_SD1_DATA5__UART4_DTE_RX 0x01E8 0x04B0 0x075C 0x4 0x7
+#define MX6SLL_PAD_SD1_DATA5__GPIO5_IO09 0x01E8 0x04B0 0x0000 0x5 0x0
+#define MX6SLL_PAD_SD1_DATA6__SD1_DATA6 0x01EC 0x04B4 0x0000 0x0 0x0
+#define MX6SLL_PAD_SD1_DATA6__KEY_COL4 0x01EC 0x04B4 0x06B0 0x2 0x2
+#define MX6SLL_PAD_SD1_DATA6__EPDC_SDOEZ 0x01EC 0x04B4 0x0000 0x3 0x0
+#define MX6SLL_PAD_SD1_DATA6__UART4_DCE_RTS 0x01EC 0x04B4 0x0758 0x4 0x4
+#define MX6SLL_PAD_SD1_DATA6__UART4_DTE_CTS 0x01EC 0x04B4 0x0000 0x4 0x0
+#define MX6SLL_PAD_SD1_DATA6__GPIO5_IO07 0x01EC 0x04B4 0x0000 0x5 0x0
+#define MX6SLL_PAD_SD1_DATA7__SD1_DATA7 0x01F0 0x04B8 0x0000 0x0 0x0
+#define MX6SLL_PAD_SD1_DATA7__KEY_ROW4 0x01F0 0x04B8 0x06D0 0x2 0x2
+#define MX6SLL_PAD_SD1_DATA7__CCM_PMIC_READY 0x01F0 0x04B8 0x05AC 0x3 0x3
+#define MX6SLL_PAD_SD1_DATA7__UART4_DCE_CTS 0x01F0 0x04B8 0x0000 0x4 0x0
+#define MX6SLL_PAD_SD1_DATA7__UART4_DTE_RTS 0x01F0 0x04B8 0x0758 0x4 0x5
+#define MX6SLL_PAD_SD1_DATA7__GPIO5_IO10 0x01F0 0x04B8 0x0000 0x5 0x0
+#define MX6SLL_PAD_SD2_RESET__SD2_RESET 0x01F4 0x04BC 0x0000 0x0 0x0
+#define MX6SLL_PAD_SD2_RESET__WDOG2_B 0x01F4 0x04BC 0x0000 0x2 0x0
+#define MX6SLL_PAD_SD2_RESET__SPDIF_OUT 0x01F4 0x04BC 0x0000 0x3 0x0
+#define MX6SLL_PAD_SD2_RESET__CSI_MCLK 0x01F4 0x04BC 0x0000 0x4 0x0
+#define MX6SLL_PAD_SD2_RESET__GPIO4_IO27 0x01F4 0x04BC 0x0000 0x5 0x0
+#define MX6SLL_PAD_SD2_CLK__SD2_CLK 0x01F8 0x04C0 0x0000 0x0 0x0
+#define MX6SLL_PAD_SD2_CLK__AUD4_RXFS 0x01F8 0x04C0 0x0570 0x1 0x1
+#define MX6SLL_PAD_SD2_CLK__ECSPI3_SCLK 0x01F8 0x04C0 0x0630 0x2 0x1
+#define MX6SLL_PAD_SD2_CLK__CSI_DATA00 0x01F8 0x04C0 0x05C8 0x3 0x1
+#define MX6SLL_PAD_SD2_CLK__GPIO5_IO05 0x01F8 0x04C0 0x0000 0x5 0x0
+#define MX6SLL_PAD_SD2_CMD__SD2_CMD 0x01FC 0x04C4 0x0000 0x0 0x0
+#define MX6SLL_PAD_SD2_CMD__AUD4_RXC 0x01FC 0x04C4 0x056C 0x1 0x1
+#define MX6SLL_PAD_SD2_CMD__ECSPI3_SS0 0x01FC 0x04C4 0x0648 0x2 0x1
+#define MX6SLL_PAD_SD2_CMD__CSI_DATA01 0x01FC 0x04C4 0x05CC 0x3 0x1
+#define MX6SLL_PAD_SD2_CMD__EPIT1_OUT 0x01FC 0x04C4 0x0000 0x4 0x0
+#define MX6SLL_PAD_SD2_CMD__GPIO5_IO04 0x01FC 0x04C4 0x0000 0x5 0x0
+#define MX6SLL_PAD_SD2_DATA0__SD2_DATA0 0x0200 0x04C8 0x0000 0x0 0x0
+#define MX6SLL_PAD_SD2_DATA0__AUD4_RXD 0x0200 0x04C8 0x0564 0x1 0x2
+#define MX6SLL_PAD_SD2_DATA0__ECSPI3_MOSI 0x0200 0x04C8 0x063C 0x2 0x1
+#define MX6SLL_PAD_SD2_DATA0__CSI_DATA02 0x0200 0x04C8 0x05D0 0x3 0x1
+#define MX6SLL_PAD_SD2_DATA0__UART5_DCE_RTS 0x0200 0x04C8 0x0760 0x4 0x4
+#define MX6SLL_PAD_SD2_DATA0__UART5_DTE_CTS 0x0200 0x04C8 0x0000 0x4 0x0
+#define MX6SLL_PAD_SD2_DATA0__GPIO5_IO01 0x0200 0x04C8 0x0000 0x5 0x0
+#define MX6SLL_PAD_SD2_DATA1__SD2_DATA1 0x0204 0x04CC 0x0000 0x0 0x0
+#define MX6SLL_PAD_SD2_DATA1__AUD4_TXC 0x0204 0x04CC 0x0574 0x1 0x2
+#define MX6SLL_PAD_SD2_DATA1__ECSPI3_MISO 0x0204 0x04CC 0x0638 0x2 0x1
+#define MX6SLL_PAD_SD2_DATA1__CSI_DATA03 0x0204 0x04CC 0x05D4 0x3 0x1
+#define MX6SLL_PAD_SD2_DATA1__UART5_DCE_CTS 0x0204 0x04CC 0x0000 0x4 0x0
+#define MX6SLL_PAD_SD2_DATA1__UART5_DTE_RTS 0x0204 0x04CC 0x0760 0x4 0x5
+#define MX6SLL_PAD_SD2_DATA1__GPIO4_IO30 0x0204 0x04CC 0x0000 0x5 0x0
+#define MX6SLL_PAD_SD2_DATA2__SD2_DATA2 0x0208 0x04D0 0x0000 0x0 0x0
+#define MX6SLL_PAD_SD2_DATA2__AUD4_TXFS 0x0208 0x04D0 0x0578 0x1 0x2
+#define MX6SLL_PAD_SD2_DATA2__CSI_DATA04 0x0208 0x04D0 0x05D8 0x3 0x1
+#define MX6SLL_PAD_SD2_DATA2__UART5_DCE_RX 0x0208 0x04D0 0x0764 0x4 0x4
+#define MX6SLL_PAD_SD2_DATA2__UART5_DTE_TX 0x0208 0x04D0 0x0000 0x4 0x0
+#define MX6SLL_PAD_SD2_DATA2__GPIO5_IO03 0x0208 0x04D0 0x0000 0x5 0x0
+#define MX6SLL_PAD_SD2_DATA3__SD2_DATA3 0x020C 0x04D4 0x0000 0x0 0x0
+#define MX6SLL_PAD_SD2_DATA3__AUD4_TXD 0x020C 0x04D4 0x0568 0x1 0x2
+#define MX6SLL_PAD_SD2_DATA3__CSI_DATA05 0x020C 0x04D4 0x05DC 0x3 0x1
+#define MX6SLL_PAD_SD2_DATA3__UART5_DCE_TX 0x020C 0x04D4 0x0000 0x4 0x0
+#define MX6SLL_PAD_SD2_DATA3__UART5_DTE_RX 0x020C 0x04D4 0x0764 0x4 0x5
+#define MX6SLL_PAD_SD2_DATA3__GPIO4_IO28 0x020C 0x04D4 0x0000 0x5 0x0
+#define MX6SLL_PAD_SD2_DATA4__SD2_DATA4 0x0210 0x04D8 0x0000 0x0 0x0
+#define MX6SLL_PAD_SD2_DATA4__SD3_DATA4 0x0210 0x04D8 0x0784 0x1 0x1
+#define MX6SLL_PAD_SD2_DATA4__UART2_DCE_RX 0x0210 0x04D8 0x074C 0x2 0x2
+#define MX6SLL_PAD_SD2_DATA4__UART2_DTE_TX 0x0210 0x04D8 0x0000 0x2 0x0
+#define MX6SLL_PAD_SD2_DATA4__CSI_DATA06 0x0210 0x04D8 0x05E0 0x3 0x1
+#define MX6SLL_PAD_SD2_DATA4__SPDIF_OUT 0x0210 0x04D8 0x0000 0x4 0x0
+#define MX6SLL_PAD_SD2_DATA4__GPIO5_IO02 0x0210 0x04D8 0x0000 0x5 0x0
+#define MX6SLL_PAD_SD2_DATA5__SD2_DATA5 0x0214 0x04DC 0x0000 0x0 0x0
+#define MX6SLL_PAD_SD2_DATA5__SD3_DATA5 0x0214 0x04DC 0x0788 0x1 0x1
+#define MX6SLL_PAD_SD2_DATA5__UART2_DCE_TX 0x0214 0x04DC 0x0000 0x2 0x0
+#define MX6SLL_PAD_SD2_DATA5__UART2_DTE_RX 0x0214 0x04DC 0x074C 0x2 0x3
+#define MX6SLL_PAD_SD2_DATA5__CSI_DATA07 0x0214 0x04DC 0x05E4 0x3 0x1
+#define MX6SLL_PAD_SD2_DATA5__SPDIF_IN 0x0214 0x04DC 0x0738 0x4 0x1
+#define MX6SLL_PAD_SD2_DATA5__GPIO4_IO31 0x0214 0x04DC 0x0000 0x5 0x0
+#define MX6SLL_PAD_SD2_DATA6__SD2_DATA6 0x0218 0x04E0 0x0000 0x0 0x0
+#define MX6SLL_PAD_SD2_DATA6__SD3_DATA6 0x0218 0x04E0 0x078C 0x1 0x1
+#define MX6SLL_PAD_SD2_DATA6__UART2_DCE_RTS 0x0218 0x04E0 0x0748 0x2 0x2
+#define MX6SLL_PAD_SD2_DATA6__UART2_DTE_CTS 0x0218 0x04E0 0x0000 0x2 0x0
+#define MX6SLL_PAD_SD2_DATA6__CSI_DATA08 0x0218 0x04E0 0x05E8 0x3 0x1
+#define MX6SLL_PAD_SD2_DATA6__SD2_WP 0x0218 0x04E0 0x077C 0x4 0x1
+#define MX6SLL_PAD_SD2_DATA6__GPIO4_IO29 0x0218 0x04E0 0x0000 0x5 0x0
+#define MX6SLL_PAD_SD2_DATA7__SD2_DATA7 0x021C 0x04E4 0x0000 0x0 0x0
+#define MX6SLL_PAD_SD2_DATA7__SD3_DATA7 0x021C 0x04E4 0x0790 0x1 0x1
+#define MX6SLL_PAD_SD2_DATA7__UART2_DCE_CTS 0x021C 0x04E4 0x0000 0x2 0x0
+#define MX6SLL_PAD_SD2_DATA7__UART2_DTE_RTS 0x021C 0x04E4 0x0748 0x2 0x3
+#define MX6SLL_PAD_SD2_DATA7__CSI_DATA09 0x021C 0x04E4 0x05EC 0x3 0x1
+#define MX6SLL_PAD_SD2_DATA7__SD2_CD_B 0x021C 0x04E4 0x0778 0x4 0x1
+#define MX6SLL_PAD_SD2_DATA7__GPIO5_IO00 0x021C 0x04E4 0x0000 0x5 0x0
+#define MX6SLL_PAD_SD3_CLK__SD3_CLK 0x0220 0x04E8 0x0000 0x0 0x0
+#define MX6SLL_PAD_SD3_CLK__AUD5_RXFS 0x0220 0x04E8 0x0588 0x1 0x0
+#define MX6SLL_PAD_SD3_CLK__KEY_COL5 0x0220 0x04E8 0x0694 0x2 0x0
+#define MX6SLL_PAD_SD3_CLK__CSI_DATA10 0x0220 0x04E8 0x05B0 0x3 0x0
+#define MX6SLL_PAD_SD3_CLK__WDOG1_RESET_B_DEB 0x0220 0x04E8 0x0000 0x4 0x0
+#define MX6SLL_PAD_SD3_CLK__GPIO5_IO18 0x0220 0x04E8 0x0000 0x5 0x0
+#define MX6SLL_PAD_SD3_CLK__USB_OTG1_PWR 0x0220 0x04E8 0x0000 0x6 0x0
+#define MX6SLL_PAD_SD3_CMD__SD3_CMD 0x0224 0x04EC 0x0000 0x0 0x0
+#define MX6SLL_PAD_SD3_CMD__AUD5_RXC 0x0224 0x04EC 0x0584 0x1 0x0
+#define MX6SLL_PAD_SD3_CMD__KEY_ROW5 0x0224 0x04EC 0x06B4 0x2 0x0
+#define MX6SLL_PAD_SD3_CMD__CSI_DATA11 0x0224 0x04EC 0x05B4 0x3 0x0
+#define MX6SLL_PAD_SD3_CMD__USB_OTG2_ID 0x0224 0x04EC 0x0560 0x4 0x1
+#define MX6SLL_PAD_SD3_CMD__GPIO5_IO21 0x0224 0x04EC 0x0000 0x5 0x0
+#define MX6SLL_PAD_SD3_CMD__USB_OTG2_PWR 0x0224 0x04EC 0x0000 0x6 0x0
+#define MX6SLL_PAD_SD3_DATA0__SD3_DATA0 0x0228 0x04F0 0x0000 0x0 0x0
+#define MX6SLL_PAD_SD3_DATA0__AUD5_RXD 0x0228 0x04F0 0x057C 0x1 0x0
+#define MX6SLL_PAD_SD3_DATA0__KEY_COL6 0x0228 0x04F0 0x0698 0x2 0x0
+#define MX6SLL_PAD_SD3_DATA0__CSI_DATA12 0x0228 0x04F0 0x05B8 0x3 0x0
+#define MX6SLL_PAD_SD3_DATA0__USB_OTG1_ID 0x0228 0x04F0 0x055C 0x4 0x1
+#define MX6SLL_PAD_SD3_DATA0__GPIO5_IO19 0x0228 0x04F0 0x0000 0x5 0x0
+#define MX6SLL_PAD_SD3_DATA1__SD3_DATA1 0x022C 0x04F4 0x0000 0x0 0x0
+#define MX6SLL_PAD_SD3_DATA1__AUD5_TXC 0x022C 0x04F4 0x058C 0x1 0x0
+#define MX6SLL_PAD_SD3_DATA1__KEY_ROW6 0x022C 0x04F4 0x06B8 0x2 0x0
+#define MX6SLL_PAD_SD3_DATA1__CSI_DATA13 0x022C 0x04F4 0x05BC 0x3 0x0
+#define MX6SLL_PAD_SD3_DATA1__SD1_VSELECT 0x022C 0x04F4 0x0000 0x4 0x0
+#define MX6SLL_PAD_SD3_DATA1__GPIO5_IO20 0x022C 0x04F4 0x0000 0x5 0x0
+#define MX6SLL_PAD_SD3_DATA1__JTAG_DE_B 0x022C 0x04F4 0x0000 0x6 0x0
+#define MX6SLL_PAD_SD3_DATA2__SD3_DATA2 0x0230 0x04F8 0x0000 0x0 0x0
+#define MX6SLL_PAD_SD3_DATA2__AUD5_TXFS 0x0230 0x04F8 0x0590 0x1 0x0
+#define MX6SLL_PAD_SD3_DATA2__KEY_COL7 0x0230 0x04F8 0x069C 0x2 0x0
+#define MX6SLL_PAD_SD3_DATA2__CSI_DATA14 0x0230 0x04F8 0x05C0 0x3 0x0
+#define MX6SLL_PAD_SD3_DATA2__EPIT1_OUT 0x0230 0x04F8 0x0000 0x4 0x0
+#define MX6SLL_PAD_SD3_DATA2__GPIO5_IO16 0x0230 0x04F8 0x0000 0x5 0x0
+#define MX6SLL_PAD_SD3_DATA2__USB_OTG2_OC 0x0230 0x04F8 0x0768 0x6 0x0
+#define MX6SLL_PAD_SD3_DATA3__SD3_DATA3 0x0234 0x04FC 0x0000 0x0 0x0
+#define MX6SLL_PAD_SD3_DATA3__AUD5_TXD 0x0234 0x04FC 0x0580 0x1 0x0
+#define MX6SLL_PAD_SD3_DATA3__KEY_ROW7 0x0234 0x04FC 0x06BC 0x2 0x0
+#define MX6SLL_PAD_SD3_DATA3__CSI_DATA15 0x0234 0x04FC 0x05C4 0x3 0x0
+#define MX6SLL_PAD_SD3_DATA3__EPIT2_OUT 0x0234 0x04FC 0x0000 0x4 0x0
+#define MX6SLL_PAD_SD3_DATA3__GPIO5_IO17 0x0234 0x04FC 0x0000 0x5 0x0
+#define MX6SLL_PAD_SD3_DATA3__USB_OTG1_OC 0x0234 0x04FC 0x076C 0x6 0x0
+#define MX6SLL_PAD_GPIO4_IO20__SD1_STROBE 0x0238 0x0500 0x0000 0x0 0x0
+#define MX6SLL_PAD_GPIO4_IO20__AUD6_RXFS 0x0238 0x0500 0x05A0 0x2 0x0
+#define MX6SLL_PAD_GPIO4_IO20__ECSPI4_SS0 0x0238 0x0500 0x065C 0x3 0x0
+#define MX6SLL_PAD_GPIO4_IO20__GPT_CAPTURE1 0x0238 0x0500 0x0670 0x4 0x0
+#define MX6SLL_PAD_GPIO4_IO20__GPIO4_IO20 0x0238 0x0500 0x0000 0x5 0x0
+#define MX6SLL_PAD_GPIO4_IO21__SD2_STROBE 0x023C 0x0504 0x0000 0x0 0x0
+#define MX6SLL_PAD_GPIO4_IO21__AUD6_RXC 0x023C 0x0504 0x059C 0x2 0x0
+#define MX6SLL_PAD_GPIO4_IO21__ECSPI4_SCLK 0x023C 0x0504 0x0650 0x3 0x0
+#define MX6SLL_PAD_GPIO4_IO21__GPT_CAPTURE2 0x023C 0x0504 0x0674 0x4 0x0
+#define MX6SLL_PAD_GPIO4_IO21__GPIO4_IO21 0x023C 0x0504 0x0000 0x5 0x0
+#define MX6SLL_PAD_GPIO4_IO19__SD3_STROBE 0x0240 0x0508 0x0000 0x0 0x0
+#define MX6SLL_PAD_GPIO4_IO19__AUD6_RXD 0x0240 0x0508 0x0594 0x2 0x0
+#define MX6SLL_PAD_GPIO4_IO19__ECSPI4_MOSI 0x0240 0x0508 0x0658 0x3 0x0
+#define MX6SLL_PAD_GPIO4_IO19__GPT_COMPARE1 0x0240 0x0508 0x0000 0x4 0x0
+#define MX6SLL_PAD_GPIO4_IO19__GPIO4_IO19 0x0240 0x0508 0x0000 0x5 0x0
+#define MX6SLL_PAD_GPIO4_IO25__AUD6_TXC 0x0244 0x050C 0x05A4 0x2 0x0
+#define MX6SLL_PAD_GPIO4_IO25__ECSPI4_MISO 0x0244 0x050C 0x0654 0x3 0x0
+#define MX6SLL_PAD_GPIO4_IO25__GPT_COMPARE2 0x0244 0x050C 0x0000 0x4 0x0
+#define MX6SLL_PAD_GPIO4_IO25__GPIO4_IO25 0x0244 0x050C 0x0000 0x5 0x0
+#define MX6SLL_PAD_GPIO4_IO18__AUD6_TXFS 0x0248 0x0510 0x05A8 0x2 0x0
+#define MX6SLL_PAD_GPIO4_IO18__ECSPI4_SS1 0x0248 0x0510 0x0660 0x3 0x0
+#define MX6SLL_PAD_GPIO4_IO18__GPT_COMPARE3 0x0248 0x0510 0x0000 0x4 0x0
+#define MX6SLL_PAD_GPIO4_IO18__GPIO4_IO18 0x0248 0x0510 0x0000 0x5 0x0
+#define MX6SLL_PAD_GPIO4_IO24__AUD6_TXD 0x024C 0x0514 0x0598 0x2 0x0
+#define MX6SLL_PAD_GPIO4_IO24__ECSPI4_SS2 0x024C 0x0514 0x0664 0x3 0x0
+#define MX6SLL_PAD_GPIO4_IO24__GPT_CLKIN 0x024C 0x0514 0x0678 0x4 0x0
+#define MX6SLL_PAD_GPIO4_IO24__GPIO4_IO24 0x024C 0x0514 0x0000 0x5 0x0
+#define MX6SLL_PAD_GPIO4_IO23__AUDIO_CLK_OUT 0x0250 0x0518 0x0000 0x2 0x0
+#define MX6SLL_PAD_GPIO4_IO23__SD1_RESET 0x0250 0x0518 0x0000 0x3 0x0
+#define MX6SLL_PAD_GPIO4_IO23__SD3_RESET 0x0250 0x0518 0x0000 0x4 0x0
+#define MX6SLL_PAD_GPIO4_IO23__GPIO4_IO23 0x0250 0x0518 0x0000 0x5 0x0
+#define MX6SLL_PAD_GPIO4_IO17__USB_OTG1_ID 0x0254 0x051C 0x055C 0x2 0x2
+#define MX6SLL_PAD_GPIO4_IO17__SD1_VSELECT 0x0254 0x051C 0x0000 0x3 0x0
+#define MX6SLL_PAD_GPIO4_IO17__SD3_VSELECT 0x0254 0x051C 0x0000 0x4 0x0
+#define MX6SLL_PAD_GPIO4_IO17__GPIO4_IO17 0x0254 0x051C 0x0000 0x5 0x0
+#define MX6SLL_PAD_GPIO4_IO22__SPDIF_IN 0x0258 0x0520 0x0738 0x2 0x0
+#define MX6SLL_PAD_GPIO4_IO22__SD1_WP 0x0258 0x0520 0x0774 0x3 0x0
+#define MX6SLL_PAD_GPIO4_IO22__SD3_WP 0x0258 0x0520 0x0794 0x4 0x1
+#define MX6SLL_PAD_GPIO4_IO22__GPIO4_IO22 0x0258 0x0520 0x0000 0x5 0x0
+#define MX6SLL_PAD_GPIO4_IO16__SPDIF_OUT 0x025C 0x0524 0x0000 0x2 0x0
+#define MX6SLL_PAD_GPIO4_IO16__SD1_CD_B 0x025C 0x0524 0x0770 0x3 0x0
+#define MX6SLL_PAD_GPIO4_IO16__SD3_CD_B 0x025C 0x0524 0x0780 0x4 0x1
+#define MX6SLL_PAD_GPIO4_IO16__GPIO4_IO16 0x025C 0x0524 0x0000 0x5 0x0
+#define MX6SLL_PAD_GPIO4_IO26__WDOG1_B 0x0260 0x0528 0x0000 0x2 0x0
+#define MX6SLL_PAD_GPIO4_IO26__PWM4_OUT 0x0260 0x0528 0x0000 0x3 0x0
+#define MX6SLL_PAD_GPIO4_IO26__CCM_PMIC_READY 0x0260 0x0528 0x05AC 0x4 0x1
+#define MX6SLL_PAD_GPIO4_IO26__GPIO4_IO26 0x0260 0x0528 0x0000 0x5 0x0
+#define MX6SLL_PAD_GPIO4_IO26__SPDIF_EXT_CLK 0x0260 0x0528 0x073C 0x6 0x0
+
+#endif /* __DTS_IMX6SLL_PINFUNC_H */
diff --git a/arch/arm/boot/dts/imx6sll.dtsi b/arch/arm/boot/dts/imx6sll.dtsi
new file mode 100644
index 000000000000..8b2e72bf61fe
--- /dev/null
+++ b/arch/arm/boot/dts/imx6sll.dtsi
@@ -0,0 +1,865 @@
+/*
+ * Copyright 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017-2018 NXP
+ *
+ * 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/imx6sll-clock.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include "imx6sll-pinfunc.h"
+#include "skeleton.dtsi"
+
+/ {
+ aliases {
+ gpio0 = &gpio1;
+ gpio1 = &gpio2;
+ gpio2 = &gpio3;
+ gpio3 = &gpio4;
+ gpio4 = &gpio5;
+ gpio5 = &gpio6;
+ i2c0 = &i2c1;
+ i2c1 = &i2c2;
+ i2c2 = &i2c3;
+ mmc0 = &usdhc1;
+ mmc1 = &usdhc2;
+ mmc2 = &usdhc3;
+ serial0 = &uart1;
+ serial1 = &uart2;
+ serial2 = &uart3;
+ serial3 = &uart4;
+ serial4 = &uart5;
+ spi0 = &ecspi1;
+ spi1 = &ecspi2;
+ spi3 = &ecspi3;
+ spi4 = &ecspi4;
+ usbphy0 = &usbphy1;
+ usbphy1 = &usbphy2;
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu0: cpu@0 {
+ compatible = "arm,cortex-a9";
+ device_type = "cpu";
+ reg = <0>;
+ next-level-cache = <&L2>;
+ operating-points = <
+ /* kHz uV */
+ 996000 1275000
+ 792000 1175000
+ 396000 1075000
+ 198000 975000
+ >;
+ fsl,soc-operating-points = <
+ /* ARM kHz SOC-PU uV */
+ 996000 1175000
+ 792000 1175000
+ 396000 1175000
+ 198000 1175000
+ >;
+ clock-latency = <61036>; /* two CLK32 periods */
+ fsl,low-power-run;
+ clocks = <&clks IMX6SLL_CLK_ARM>,
+ <&clks IMX6SLL_CLK_PLL2_PFD2>,
+ <&clks IMX6SLL_CLK_STEP>,
+ <&clks IMX6SLL_CLK_PLL1_SW>,
+ <&clks IMX6SLL_CLK_PLL1_SYS>,
+ <&clks IMX6SLL_CLK_PLL1>,
+ <&clks IMX6SLL_PLL1_BYPASS>,
+ <&clks IMX6SLL_PLL1_BYPASS_SRC>;
+ clock-names = "arm", "pll2_pfd2_396m", "step",
+ "pll1_sw", "pll1_sys", "pll1", "pll1_bypass",
+ "pll1_bypass_src";
+ };
+ };
+
+ intc: interrupt-controller@00a01000 {
+ compatible = "arm,cortex-a9-gic";
+ #interrupt-cells = <3>;
+ interrupt-controller;
+ reg = <0x00a01000 0x1000>,
+ <0x00a00100 0x100>;
+ interrupt-parent = <&intc>;
+ };
+
+ clocks {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ckil: clock@0 {
+ compatible = "fixed-clock";
+ reg = <0>;
+ #clock-cells = <0>;
+ clock-frequency = <32768>;
+ clock-output-names = "ckil";
+ };
+
+ osc: clock@1 {
+ compatible = "fixed-clock";
+ reg = <1>;
+ #clock-cells = <0>;
+ clock-frequency = <24000000>;
+ clock-output-names = "osc";
+ };
+
+ ipp_di0: clock@2 {
+ compatible = "fixed-clock";
+ reg = <2>;
+ #clock-cells = <0>;
+ clock-frequency = <0>;
+ clock-output-names = "ipp_di0";
+ };
+
+ ipp_di1: clock@3 {
+ compatible = "fixed-clock";
+ reg = <3>;
+ #clock-cells = <0>;
+ clock-frequency = <0>;
+ clock-output-names = "ipp_di1";
+ };
+ };
+
+ soc {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "simple-bus";
+ interrupt-parent = <&gpc>;
+ ranges;
+
+ busfreq {
+ compatible = "fsl,imx_busfreq";
+ clocks = <&clks IMX6SLL_CLK_PLL2_PFD2>, <&clks IMX6SLL_CLK_PLL2_198M>,
+ <&clks IMX6SLL_CLK_PLL2_BUS>, <&clks IMX6SLL_CLK_ARM>,
+ <&clks IMX6SLL_CLK_PLL3_USB_OTG>, <&clks IMX6SLL_CLK_PERIPH>,
+ <&clks IMX6SLL_CLK_PERIPH_PRE>, <&clks IMX6SLL_CLK_PERIPH_CLK2>,
+ <&clks IMX6SLL_CLK_PERIPH_CLK2_SEL>, <&clks IMX6SLL_CLK_OSC>,
+ <&clks IMX6SLL_CLK_AHB>, <&clks IMX6SLL_CLK_AXI_PODF>,
+ <&clks IMX6SLL_CLK_PERIPH2>, <&clks IMX6SLL_CLK_PERIPH2_PRE>,
+ <&clks IMX6SLL_CLK_PERIPH2_CLK2>, <&clks IMX6SLL_CLK_PERIPH2_CLK2_SEL>,
+ <&clks IMX6SLL_CLK_STEP>, <&clks IMX6SLL_CLK_MMDC_P0_FAST>, <&clks IMX6SLL_PLL1_BYPASS_SRC>,
+ <&clks IMX6SLL_PLL1_BYPASS>, <&clks IMX6SLL_CLK_PLL1_SYS>, <&clks IMX6SLL_CLK_PLL1_SW>,
+ <&clks IMX6SLL_CLK_PLL1>;
+ clock-names = "pll2_pfd2_396m", "pll2_198m", "pll2_bus", "arm", "pll3_usb_otg",
+ "periph", "periph_pre", "periph_clk2", "periph_clk2_sel", "osc",
+ "ahb", "ocram", "periph2", "periph2_pre", "periph2_clk2", "periph2_clk2_sel",
+ "step", "mmdc", "pll1_bypass_src", "pll1_bypass", "pll1_sys", "pll1_sw", "pll1";
+ fsl,max_ddr_freq = <400000000>;
+ };
+
+ ocrams: sram@00900000 {
+ compatible = "fsl,lpm-sram";
+ reg = <0x00900000 0x4000>;
+ };
+
+ ocrams_ddr: sram@00904000 {
+ compatible = "fsl,ddr-lpm-sram";
+ reg = <0x00904000 0x1000>;
+ };
+
+ ocram: sram@00905000 {
+ compatible = "mmio-sram";
+ reg = <0x00905000 0x1B000>;
+ };
+
+ ocram_optee: sram@00918000 {
+ compatible = "fsl,optee-lpm-sram";
+ reg = <0x00918000 0x8000>;
+ overw_reg = <&ocram 0x00905000 0x13000>;
+ };
+
+ L2: l2-cache@00a02000 {
+ compatible = "arm,pl310-cache";
+ reg = <0x00a02000 0x1000>;
+ interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_HIGH>;
+ cache-unified;
+ cache-level = <2>;
+ arm,tag-latency = <4 2 3>;
+ arm,data-latency = <4 2 3>;
+ };
+
+ aips1: aips-bus@02000000 {
+ compatible = "fsl,aips-bus", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x02000000 0x100000>;
+ ranges;
+
+ spba: spba-bus@02000000 {
+ compatible = "fsl,spba-bus", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x02000000 0x40000>;
+ ranges;
+
+ spdif: spdif@02004000 {
+ compatible = "fsl,imx6sl-spdif", "fsl,imx35-spdif";
+ reg = <0x02004000 0x4000>;
+ interrupts = <GIC_SPI 52 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&sdma 14 18 0>, <&sdma 15 18 0>;
+ dma-names = "rx", "tx";
+ clocks = <&clks IMX6SLL_CLK_SPDIF_GCLK>,
+ <&clks IMX6SLL_CLK_OSC>,
+ <&clks IMX6SLL_CLK_SPDIF>,
+ <&clks IMX6SLL_CLK_DUMMY>,
+ <&clks IMX6SLL_CLK_DUMMY>,
+ <&clks IMX6SLL_CLK_DUMMY>,
+ <&clks IMX6SLL_CLK_IPG>,
+ <&clks IMX6SLL_CLK_DUMMY>,
+ <&clks IMX6SLL_CLK_DUMMY>,
+ <&clks IMX6SLL_CLK_SPBA>;
+ clock-names = "core", "rxtx0",
+ "rxtx1", "rxtx2",
+ "rxtx3", "rxtx4",
+ "rxtx5", "rxtx6",
+ "rxtx7", "spba";
+ status = "disabled";
+ };
+
+ ecspi1: ecspi@02008000 {
+ compatible = "fsl,imx6ul-ecspi", "fsl,imx51-ecspi";
+ reg = <0x02008000 0x4000>;
+ interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&sdma 3 7 1>, <&sdma 4 7 2>;
+ dma-names = "rx", "tx";
+ clocks = <&clks IMX6SLL_CLK_ECSPI1>,
+ <&clks IMX6SLL_CLK_ECSPI1>;
+ clock-names = "ipg", "per";
+ status = "disabled";
+ };
+
+ ecspi2: ecspi@0200c000 {
+ compatible = "fsl,imx6ul-ecspi", "fsl,imx51-ecspi";
+ reg = <0x0200c000 0x4000>;
+ interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&sdma 5 7 1>, <&sdma 6 7 2>;
+ dma-names = "rx", "tx";
+ clocks = <&clks IMX6SLL_CLK_ECSPI2>,
+ <&clks IMX6SLL_CLK_ECSPI2>;
+ clock-names = "ipg", "per";
+ status = "disabled";
+ };
+
+ ecspi3: ecspi@02010000 {
+ compatible = "fsl,imx6ul-ecspi", "fsl,imx51-ecspi";
+ reg = <0x02010000 0x4000>;
+ interrupts = <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&sdma 7 7 1>, <&sdma 8 7 2>;
+ dma-names = "rx", "tx";
+ clocks = <&clks IMX6SLL_CLK_ECSPI3>,
+ <&clks IMX6SLL_CLK_ECSPI3>;
+ clock-names = "ipg", "per";
+ status = "disabled";
+ };
+
+ ecspi4: ecspi@02014000 {
+ compatible = "fsl,imx6ul-ecspi", "fsl,imx51-ecspi";
+ reg = <0x02014000 0x4000>;
+ interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&sdma 9 7 1>, <&sdma 10 7 2>;
+ dma-names = "rx", "tx";
+ clocks = <&clks IMX6SLL_CLK_ECSPI4>,
+ <&clks IMX6SLL_CLK_ECSPI4>;
+ clock-names = "ipg", "per";
+ status = "disabled";
+ };
+
+ uart4: serial@02018000 {
+ compatible = "fsl,imx6sll-uart", "fsl,imx6q-uart", "fsl,imx21-uart";
+ reg = <0x02018000 0x4000>;
+ interrupts =<GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&sdma 31 4 0>, <&sdma 32 4 0>;
+ dma-names = "rx", "tx";
+ clocks = <&clks IMX6SLL_CLK_UART4_IPG>,
+ <&clks IMX6SLL_CLK_UART4_SERIAL>;
+ clock-names = "ipg", "per";
+ status = "disabled";
+ };
+
+ uart1: serial@02020000 {
+ compatible = "fsl,imx6sll-uart", "fsl,imx6q-uart", "fsl,imx21-uart";
+ reg = <0x02020000 0x4000>;
+ interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&sdma 25 4 0>, <&sdma 26 4 0>;
+ dma-names = "rx", "tx";
+ clocks = <&clks IMX6SLL_CLK_UART1_IPG>,
+ <&clks IMX6SLL_CLK_UART1_SERIAL>;
+ clock-names = "ipg", "per";
+ status = "disabled";
+ };
+
+ uart2: serial@02024000 {
+ compatible = "fsl,imx6sll-uart", "fsl,imx6q-uart", "fsl,imx21-uart";
+ reg = <0x02024000 0x4000>;
+ interrupts = <GIC_SPI 27 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&sdma 27 4 0>, <&sdma 28 4 0>;
+ dma-names = "rx", "tx";
+ clocks = <&clks IMX6SLL_CLK_UART2_IPG>,
+ <&clks IMX6SLL_CLK_UART2_SERIAL>;
+ clock-names = "ipg", "per";
+ status = "disabled";
+ };
+
+ ssi1: ssi@02028000 {
+ compatible = "fsl,imx6sll-ssi", "fsl,imx51-ssi";
+ reg = <0x02028000 0x4000>;
+ interrupts = <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&sdma 37 22 0>, <&sdma 38 22 0>;
+ dma-names = "rx", "tx";
+ fsl,fifo-depth = <15>;
+ clocks = <&clks IMX6SLL_CLK_SSI1_IPG>,
+ <&clks IMX6SLL_CLK_SSI1>;
+ clock-names = "ipg", "baud";
+ status = "disabled";
+ };
+
+ ssi2: ssi2@0202c000 {
+ compatible = "fsl,imx6sll-ssi", "fsl,imx51-ssi";
+ reg = <0x0202c000 0x4000>;
+ interrupts = <GIC_SPI 47 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&sdma 41 22 0>, <&sdma 42 22 0>;
+ dma-names = "rx", "tx";
+ fsl,fifo-depth = <15>;
+ clocks = <&clks IMX6SLL_CLK_SSI2_IPG>,
+ <&clks IMX6SLL_CLK_SSI2>;
+ clock-names = "ipg", "baud";
+ status = "disabled";
+ };
+
+ ssi3: ssi@02030000 {
+ compatible = "fsl,imx6sll-ssi", "fsl,imx51-ssi";
+ reg = <0x02030000 0x4000>;
+ interrupts = <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&sdma 45 22 0>, <&sdma 46 22 0>;
+ dma-names = "rx", "tx";
+ fsl,fifo-depth = <15>;
+ clocks = <&clks IMX6SLL_CLK_SSI3_IPG>,
+ <&clks IMX6SLL_CLK_SSI3>;
+ clock-names = "ipg", "baud";
+ status = "disabled";
+ };
+
+ uart3: serial@02034000 {
+ compatible = "fsl,imx6sll-uart", "fsl,imx6q-uart", "fsl,imx21-uart";
+ reg = <0x02034000 0x4000>;
+ interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&sdma 29 4 0>, <&sdma 30 4 0>;
+ dma-name = "rx", "tx";
+ clocks = <&clks IMX6SLL_CLK_UART3_IPG>,
+ <&clks IMX6SLL_CLK_UART3_SERIAL>;
+ clock-names = "ipg", "per";
+ status = "disabled";
+ };
+ };
+
+ pwm1: pwm@02080000 {
+ compatible = "fsl,imx6sll-pwm", "fsl,imx27-pwm";
+ reg = <0x02080000 0x4000>;
+ interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SLL_CLK_PWM1>,
+ <&clks IMX6SLL_CLK_PWM1>;
+ clock-names = "ipg", "per";
+ #pwm-cells = <2>;
+ };
+
+ pwm2: pwm@02084000 {
+ compatible = "fsl,imx6sll-pwm", "fsl,imx27-pwm";
+ reg = <0x02084000 0x4000>;
+ interrupts = <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SLL_CLK_PWM2>,
+ <&clks IMX6SLL_CLK_PWM2>;
+ clock-names = "ipg", "per";
+ #pwm-cells = <2>;
+ };
+
+ pwm3: pwm@02088000 {
+ compatible = "fsl,imx6sll-pwm", "fsl,imx27-pwm";
+ reg = <0x02088000 0x4000>;
+ interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SLL_CLK_PWM3>,
+ <&clks IMX6SLL_CLK_PWM3>;
+ clock-names = "ipg", "per";
+ #pwm-cells = <2>;
+ };
+
+ pwm4: pwm@0208c000 {
+ compatible = "fsl,imx6sll-pwm", "fsl,imx27-pwm";
+ reg = <0x0208c000 0x4000>;
+ interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SLL_CLK_PWM4>,
+ <&clks IMX6SLL_CLK_PWM4>;
+ clock-names = "ipg", "per";
+ #pwm-cells = <2>;
+ };
+
+ gpt1: gpt@02098000 {
+ compatible = "fsl,imx6sll-gpt";
+ reg = <0x02098000 0x4000>;
+ interrupts = <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SLL_CLK_GPT_BUS>,
+ <&clks IMX6SLL_CLK_GPT_3M>;
+ clock-names = "ipg", "osc_per";
+ };
+
+ gpio1: gpio@0209c000 {
+ compatible = "fsl,imx6sll-gpio", "fsl,imx35-gpio";
+ reg = <0x0209c000 0x4000>;
+ interrupts = <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio2: gpio@020a0000 {
+ compatible = "fsl,imx6sll-gpio", "fsl,imx35-gpio";
+ reg = <0x020a0000 0x4000>;
+ interrupts = <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio3: gpio@020a4000 {
+ compatible = "fsl,imx6sll-gpio", "fsl,imx35-gpio";
+ reg = <0x020a4000 0x4000>;
+ interrupts = <GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio4: gpio@020a8000 {
+ compatible = "fsl,imx6sll-gpio", "fsl,imx35-gpio";
+ reg = <0x020a8000 0x4000>;
+ interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio5: gpio@020ac000 {
+ compatible = "fsl,imx6sll-gpio", "fsl,imx35-gpio";
+ reg = <0x020ac000 0x4000>;
+ interrupts = <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio6: gpio@020b0000 {
+ compatible = "fsl,imx6sll-gpio", "fsl,imx35-gpio";
+ reg = <0x020b0000 0x4000>;
+ interrupts = <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ kpp: kpp@020b8000 {
+ compatible = "fsl,imx6sll-kpp", "fsl,imx21-kpp";
+ reg = <0x020b8000 0x4000>;
+ interrupts = <GIC_SPI 82 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SLL_CLK_KPP>;
+ status = "disabled";
+ };
+
+ wdog1: wdog@020bc000 {
+ compatible = "fsl,imx6sll-wdt", "fsl,imx21-wdt";
+ reg = <0x020bc000 0x4000>;
+ interrupts = <GIC_SPI 80 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SLL_CLK_WDOG1>;
+ };
+
+ wdog2: wdog@020c0000 {
+ compatible = "fsl,imx6sll-wdt", "fsl,imx21-wdt";
+ reg = <0x020c0000 0x4000>;
+ interrupts = <GIC_SPI 81 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SLL_CLK_WDOG2>;
+ status = "disabled";
+ };
+
+ clks: ccm@020c4000 {
+ compatible = "fsl,imx6sll-ccm";
+ reg = <0x020c4000 0x4000>;
+ interrupts = <GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 88 IRQ_TYPE_LEVEL_HIGH>;
+ #clock-cells = <1>;
+ clocks = <&ckil>, <&osc>, <&ipp_di0>, <&ipp_di1>;
+ clock-names = "ckil", "osc", "ipp_di0", "ipp_di1";
+ };
+
+ anatop: anatop@020c8000 {
+ compatible = "fsl,imx6sll-anatop",
+ "fsl,imx6q-anatop",
+ "syscon", "simple-bus";
+ reg = <0x020c8000 0x4000>;
+ interrupts = <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 127 IRQ_TYPE_LEVEL_HIGH>;
+
+ reg_3p0: regulator-3p0@120 {
+ compatible = "fsl,anatop-regulator";
+ regulator-name = "vdd3p0";
+ regulator-min-microvolt = <2625000>;
+ regulator-max-microvolt = <3400000>;
+ anatop-reg-offset = <0x120>;
+ anatop-vol-bit-shift = <8>;
+ anatop-vol-bit-width = <5>;
+ anatop-min-bit-val = <0>;
+ anatop-min-voltage = <2625000>;
+ anatop-max-voltage = <3400000>;
+ anatop-enable-bit = <0>;
+ };
+ };
+
+ tempmon: tempmon {
+ compatible = "fsl,imx6sll-tempmon", "fsl,imx6sx-tempmon";
+ interrupts = <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>;
+ fsl,tempmon = <&anatop>;
+ fsl,tempmon-data = <&ocotp>;
+ clocks = <&clks IMX6SLL_CLK_PLL3_USB_OTG>;
+ };
+
+ usbphy1: usbphy@020c9000 {
+ compatible = "fsl,imx6sll-usbphy", "fsl,imx6ul-usbphy",
+ "fsl,imx23-usbphy";
+ reg = <0x020c9000 0x1000>;
+ interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SLL_CLK_USBPHY1>;
+ phy-3p0-supply = <&reg_3p0>;
+ fsl,anatop = <&anatop>;
+ };
+
+ usbphy2: usbphy@020ca000 {
+ compatible = "fsl,imx6sll-usbphy", "fsl,imx6ul-usbphy",
+ "fsl,imx23-usbphy";
+ reg = <0x020ca000 0x1000>;
+ interrupts = <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SLL_CLK_USBPHY2>;
+ phy-reg_3p0-supply = <&reg_3p0>;
+ fsl,anatop = <&anatop>;
+ };
+
+ snvs: snvs@020cc000 {
+ compatible = "fsl,sec-v4.0-mon", "syscon", "simple-mfd";
+ reg = <0x020cc000 0x4000>;
+
+ snvs_rtc: snvs-rtc-lp {
+ compatible = "fsl,sec-v4.0-mon-rtc-lp";
+ regmap = <&snvs>;
+ offset = <0x34>;
+ interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ snvs_poweroff: snvs-poweroff {
+ compatible = "syscon-poweroff";
+ regmap = <&snvs>;
+ offset = <0x38>;
+ mask = <0x61>;
+ };
+
+ snvs_pwrkey: snvs-powerkey {
+ compatible = "fsl,sec-v4.0-pwrkey";
+ regmap = <&snvs>;
+ interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>;
+ linux,keycode = <KEY_POWER>;
+ wakeup-source;
+ };
+ };
+
+ epit1: epit@020d0000 {
+ reg = <0x020d0000 0x4000>;
+ interrupts = <GIC_SPI 56 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ epit2: epit@020d4000 {
+ reg = <0x020d4000 0x4000>;
+ interrupts = <GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ src: src@020d8000 {
+ compatible = "fsl,imx6sll-src", "fsl,imx51-src";
+ reg = <0x020d8000 0x4000>;
+ interrupts = <GIC_SPI 91 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>;
+ #reset-cells = <1>;
+ };
+
+ gpc: gpc@020dc000 {
+ compatible = "fsl,imx6sll-gpc", "fsl,imx6q-gpc";
+ reg = <0x020dc000 0x4000>;
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ interrupts = <GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-parent = <&intc>;
+ fsl,mf-mix-wakeup-irq = <0x7c00000 0x7d00 0x0 0x1400640>;
+ };
+
+ iomuxc: iomuxc@020e0000 {
+ compatible = "fsl,imx6sll-iomuxc";
+ reg = <0x020e0000 0x4000>;
+ };
+
+ gpr: iomuxc-gpr@020e4000 {
+ compatible = "fsl,imx6sll-iomuxc-gpr",
+ "fsl,imx6q-iomuxc-gpr", "syscon";
+ reg = <0x020e4000 0x4000>;
+ };
+
+ csi: csi@020e8000 {
+ compatible = "fsl,imx6sll-csi", "fsl,imx6s-csi";
+ reg = <0x020e8000 0x4000>;
+ interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SLL_CLK_DUMMY>,
+ <&clks IMX6SLL_CLK_CSI>,
+ <&clks IMX6SLL_CLK_DUMMY>;
+ clock-names = "disp-axi", "csi_mclk", "disp_dcic";
+ status = "disabled";
+ };
+
+ sdma: sdma@020ec000 {
+ compatible = "fsl,imx6ul-sdma", "fsl,imx35-sdma";
+ reg = <0x020ec000 0x4000>;
+ interrupts = <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SLL_CLK_SDMA>,
+ <&clks IMX6SLL_CLK_SDMA>;
+ clock-names = "ipg", "ahb";
+ #dma-cells = <3>;
+ iram = <&ocram>;
+ fsl,sdma-ram-script-name = "imx/sdma/sdma-imx6q.bin";
+ };
+
+ pxp: pxp@020f0000 {
+ compatible = "fsl,imx6ull-pxp-dma", "fsl,imx7d-pxp-dma";
+ reg = <0x020f0000 0x4000>;
+ interrupts = <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SLL_CLK_DUMMY>,
+ <&clks IMX6SLL_CLK_PXP>;
+ clock-names = "pxp_ipg", "pxp_axi";
+ status = "disabled";
+ };
+
+ epdc: epdc@020f4000 {
+ compatible = "fsl,imx6sll-epdc", "fsl,imx7d-epdc";
+ reg = <0x020f4000 0x4000>;
+ interrupts = <GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SLL_CLK_EPDC_AXI>, <&clks IMX6SLL_CLK_EPDC_PIX>;
+ clock-names = "epdc_axi", "epdc_pix";
+ status = "disabled";
+ };
+
+ lcdif: lcdif@020f8000 {
+ compatible = "fsl,imx6sll-lcdif", "fsl,imx28-lcdif";
+ reg = <0x020f8000 0x4000>;
+ interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SLL_CLK_LCDIF_PIX>,
+ <&clks IMX6SLL_CLK_LCDIF_APB>,
+ <&clks IMX6SLL_CLK_DUMMY>;
+ clock-names = "pix", "axi", "disp_axi";
+ status = "disabled";
+ };
+
+ dcp: dcp@020fc000 {
+ compatible = "fsl,imx6sl-dcp";
+ reg = <0x020fc000 0x4000>;
+ interrupts = <GIC_SPI 99 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SLL_CLK_DCP>;
+ clock-names = "dcp";
+ };
+ };
+
+ aips2: aips-bus@02100000 {
+ compatible = "fsl,aips-bus", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x02100000 0x100000>;
+ ranges;
+
+ usbotg1: usb@02184000 {
+ compatible = "fsl,imx6sll-usb", "fsl,imx6ul-usb",
+ "fsl,imx27-usb";
+ reg = <0x02184000 0x200>;
+ interrupts = <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SLL_CLK_USBOH3>;
+ fsl,usbphy = <&usbphy1>;
+ fsl,usbmisc = <&usbmisc 0>;
+ fsl,anatop = <&anatop>;
+ ahb-burst-config = <0x0>;
+ tx-burst-size-dword = <0x10>;
+ rx-burst-size-dword = <0x10>;
+ status = "disabled";
+ };
+
+ usbotg2: usb@02184200 {
+ compatible = "fsl,imx6sll-usb", "fsl,imx6ul-usb",
+ "fsl,imx27-usb";
+ reg = <0x02184200 0x200>;
+ interrupts = <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SLL_CLK_USBOH3>;
+ fsl,usbphy = <&usbphy2>;
+ fsl,usbmisc = <&usbmisc 1>;
+ ahb-burst-config = <0x0>;
+ tx-burst-size-dword = <0x10>;
+ rx-burst-size-dword = <0x10>;
+ status = "disabled";
+ };
+
+ usbmisc: usbmisc@02184800 {
+ #index-cells = <1>;
+ compatible = "fsl,imx6sll-usbmisc", "fsl,imx6ul-usbmisc",
+ "fsl,imx6q-usbmisc";
+ reg = <0x02184800 0x200>;
+ };
+
+ usdhc1: usdhc@02190000 {
+ compatible = "fsl,imx6sll-usdhc", "fsl,imx7d-usdhc";
+ reg = <0x02190000 0x4000>;
+ interrupts = <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SLL_CLK_USDHC1>,
+ <&clks IMX6SLL_CLK_USDHC1>,
+ <&clks IMX6SLL_CLK_USDHC1>;
+ clock-names = "ipg", "ahb", "per";
+ bus-width = <4>;
+ fsl,tuning-step = <2>;
+ fsl,tuning-start-tap = <20>;
+ status = "disabled";
+ };
+
+ usdhc2: usdhc@02194000 {
+ compatible = "fsl,imx6sll-usdhc", "fsl,imx7d-usdhc";
+ reg = <0x02194000 0x4000>;
+ interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SLL_CLK_USDHC2>,
+ <&clks IMX6SLL_CLK_USDHC2>,
+ <&clks IMX6SLL_CLK_USDHC2>;
+ clock-names = "ipg", "ahb", "per";
+ bus-width = <4>;
+ fsl,tuning-step = <2>;
+ fsl,tuning-start-tap = <20>;
+ status = "disabled";
+ };
+
+ usdhc3: usdhc@02198000 {
+ compatible = "fsl,imx6sll-usdhc", "fsl,imx7d-usdhc";
+ reg = <0x02198000 0x4000>;
+ interrupts = <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SLL_CLK_USDHC3>,
+ <&clks IMX6SLL_CLK_USDHC3>,
+ <&clks IMX6SLL_CLK_USDHC3>;
+ clock-names = "ipg", "ahb", "per";
+ bus-width = <4>;
+ fsl,tuning-step = <2>;
+ fsl,tuning-start-tap = <20>;
+ status = "disabled";
+ };
+
+ i2c1: i2c@021a0000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fs,imx6sll-i2c", "fsl,imx21-i2c";
+ reg = <0x021a0000 0x4000>;
+ interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SLL_CLK_I2C1>;
+ status = "disabled";
+ };
+
+ i2c2: i2c@021a4000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx6sll-i2c", "fsl,imx21-i2c";
+ reg = <0x021a4000 0x4000>;
+ interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SLL_CLK_I2C2>;
+ status = "disabled";
+ };
+
+ i2c3: i2c@021a8000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx6sll-i2c", "fsl,imx21-i2c";
+ reg = <0x021a8000 0x4000>;
+ interrupts = <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SLL_CLK_I2C3>;
+ status = "disabled";
+ };
+
+ romcp@021ac000 {
+ compatible = "fsl,imx6sll-romcp", "syscon";
+ reg = <0x021ac000 0x4000>;
+ };
+
+ mmdc: mmdc@021b0000 {
+ compatible = "fsl,imx6sll-mmdc", "fsl,imx6q-mmdc";
+ reg = <0x021b0000 0x4000>;
+ };
+
+ rngb: rngb@021b4000 {
+ compatible = "fsl,imx6sl-rng", "fsl,imx-rng", "imx-rng";
+ reg = <0x021b4000 0x4000>;
+ interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SLL_CLK_DUMMY>;
+ };
+
+ ocotp: ocotp-ctrl@021bc000 {
+ compatible = "fsl,imx6sll-ocotp", "syscon";
+ reg = <0x021bc000 0x4000>;
+ clocks = <&clks IMX6SLL_CLK_OCOTP>;
+ };
+
+ csu: csu@021c0000 {
+ compatible = "fsl,imx6sll-csu";
+ reg = <0x021c0000 0x4000>;
+ interrupts = <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
+
+ snvs_gpr: snvs-gpr@0x021c4000 {
+ compatible = "fsl, imx6sll-snvs-gpr";
+ reg = <0x021c4000 0x10000>;
+ };
+
+ iomuxc_snvs: iomuxc-snvs@021c8000 {
+ compatible = "fsl,imx6sll-iomuxc-snvs";
+ reg = <0x021c80000 0x10000>;
+ };
+
+ audmux: audmux@021d8000 {
+ compatible = "fsl,imx6sll-audmux", "fsl,imx31-audmux";
+ reg = <0x021d8000 0x4000>;
+ status = "disabled";
+ };
+
+ uart5: serial@021f4000 {
+ compatible = "fsl,imx6sll-uart", "fsl,imx6q-uart", "fsl,imx21-uart";
+ reg = <0x021f4000 0x4000>;
+ interrupts =<GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&sdma 33 4 0>, <&sdma 34 4 0>;
+ dma-names = "rx", "tx";
+ clocks = <&clks IMX6SLL_CLK_UART5_IPG>,
+ <&clks IMX6SLL_CLK_UART5_SERIAL>;
+ clock-names = "ipg", "per";
+ status = "disabled";
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/imx6sx-14x14-arm2.dts b/arch/arm/boot/dts/imx6sx-14x14-arm2.dts
new file mode 100644
index 000000000000..896748c81d2e
--- /dev/null
+++ b/arch/arm/boot/dts/imx6sx-14x14-arm2.dts
@@ -0,0 +1,1331 @@
+/*
+ * Copyright (C) 2015 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 14x14 ARM2 Board";
+ compatible = "fsl,imx6sx-14x14-lpddr2-arm2", "fsl,imx6sx";
+
+ backlight {
+ compatible = "pwm-backlight";
+ pwms = <&pwm3 0 5000000>;
+ brightness-levels = <0 4 8 16 32 64 128 255>;
+ default-brightness-level = <6>;
+ };
+
+ clocks {
+ codec_osc: codec_osc {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <12000000>;
+ };
+ };
+
+ max7322_reset: max7322-reset {
+ compatible = "gpio-reset";
+ reset-gpios = <&gpio4 22 GPIO_ACTIVE_LOW>;
+ reset-delay-us = <1>;
+ #reset-cells = <0>;
+ };
+
+ pxp_v4l2_out {
+ compatible = "fsl,imx6sx-pxp-v4l2", "fsl,imx6sl-pxp-v4l2";
+ status = "okay";
+ };
+
+ regulators {
+ compatible = "simple-bus";
+
+ reg_3p3v: 3p3v {
+ compatible = "regulator-fixed";
+ regulator-name = "3P3V";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ reg_sdb_vmmc: sdb_vmmc{
+ compatible = "regulator-fixed";
+ regulator-name = "SD2_SPWR";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&gpio2 11 GPIO_ACTIVE_LOW>;
+ off-on-delay = <20000>;
+ };
+
+ reg_usb_otg1_vbus: usb_otg1_vbus {
+ compatible = "regulator-fixed";
+ regulator-name = "usb_otg1_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&gpio1 9 0>;
+ enable-active-high;
+ };
+
+ reg_usb_otg2_vbus: usb_otg2_vbus {
+ compatible = "regulator-fixed";
+ regulator-name = "usb_otg2_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&gpio1 12 0>;
+ enable-active-high;
+ };
+
+ reg_vref_3v3: regulator@0 {
+ compatible = "regulator-fixed";
+ regulator-name = "vref-3v3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+ };
+
+ memory {
+ reg = <0x80000000 0x40000000>;
+ };
+
+ sound {
+ compatible = "fsl,imx6sx-arm2-sgtl5000",
+ "fsl,imx-audio-sgtl5000";
+ model = "imx6sx-arm2-sgtl5000";
+ cpu-dai = <&ssi1>;
+ audio-codec = <&codec>;
+ audio-routing =
+ "LINE_IN", "Line In Jack",
+ "Headphone Jack", "HP_OUT";
+ mux-int-port = <1>;
+ mux-ext-port = <4>;
+ };
+};
+
+&adc1 {
+ vref-supply = <&reg_vref_3v3>;
+ status = "okay";
+};
+
+&adc2 {
+ vref-supply = <&reg_vref_3v3>;
+ status = "okay";
+};
+
+&audmux {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_audmux_2>;
+ status = "okay";
+};
+
+&cpu0 {
+ operating-points = <
+ /* kHz uV */
+ 996000 1250000
+ 792000 1175000
+ 396000 1175000
+ >;
+ fsl,soc-operating-points = <
+ /* ARM kHz SOC uV */
+ 996000 1250000
+ 792000 1175000
+ 396000 1175000
+ >;
+ fsl,arm-soc-shared = <1>;
+};
+
+&reg_arm {
+ vin-supply = <&sw1a_reg>;
+ regulator-allow-bypass;
+};
+
+&reg_soc {
+ vin-supply = <&sw1a_reg>;
+ regulator-allow-bypass;
+};
+
+&ecspi4 {
+ fsl,spi-num-chipselects = <1>;
+ cs-gpios = <&gpio7 4 0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ecspi4_1 &pinctrl_ecspi4_cs_1>;
+ status = "disabled"; /* pin conflict with USDHC3 */
+
+ flash: m25p80@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "st,m25p32";
+ spi-max-frequency = <20000000>;
+ reg = <0>;
+ };
+};
+
+&fec1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_enet1_1>;
+ phy-mode = "rgmii";
+ phy-id = <1>;
+ fsl,num_tx_queues=<3>;
+ fsl,num_rx_queues=<3>;
+ pinctrl-assert-gpios = <&max7322_1 0 GPIO_ACTIVE_HIGH>;
+ fsl,magic-packet;
+ status = "okay";
+};
+
+&fec2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_enet2_1>;
+ phy-mode = "rgmii";
+ phy-id = <0>;
+ fsl,num_tx_queues=<3>;
+ fsl,num_rx_queues=<3>;
+ pinctrl-assert-gpios = <&max7322_2 0 GPIO_ACTIVE_HIGH>;
+ fsl,magic-packet;
+ status = "okay";
+};
+
+&flexcan1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_flexcan1_1>;
+ trx-en-gpio = <&gpio4 25 GPIO_ACTIVE_HIGH>;
+ trx-stby-gpio = <&gpio4 27 GPIO_ACTIVE_HIGH>;
+ trx-err-gpio = <&gpio4 24 GPIO_ACTIVE_HIGH>;
+ status = "okay";
+};
+
+&flexcan2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_flexcan2_1>;
+ trx-en-gpio = <&gpio4 25 GPIO_ACTIVE_HIGH>;
+ trx-stby-gpio = <&gpio4 27 GPIO_ACTIVE_HIGH>;
+ trx-err-gpio = <&gpio4 30 GPIO_ACTIVE_HIGH>;
+ status = "okay";
+};
+
+&gpc {
+ fsl,cpu_pdnscr_iso2sw = <0x1>;
+ fsl,cpu_pdnscr_iso = <0x1>;
+ fsl,ldo-bypass = <1>; /* use ldo-bypass, u-boot will check it and configure */
+};
+
+&gpmi {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpmi_nand_1>;
+ status = "disabled"; /* pin conflict with qspi*/
+ nand-on-flash-bbt;
+};
+
+&i2c1 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c1_1>;
+ status = "okay";
+
+ pmic: pfuze100@08 {
+ compatible = "fsl,pfuze200";
+ reg = <0x08>;
+
+ regulators {
+ sw1a_reg: sw1ab {
+ regulator-min-microvolt = <300000>;
+ regulator-max-microvolt = <1875000>;
+ regulator-boot-on;
+ regulator-always-on;
+ regulator-ramp-delay = <6250>;
+ };
+
+ sw2_reg: sw2 {
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ sw3a_reg: sw3a {
+ regulator-min-microvolt = <400000>;
+ regulator-max-microvolt = <1975000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ sw3b_reg: sw3b {
+ regulator-min-microvolt = <400000>;
+ regulator-max-microvolt = <1975000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ swbst_reg: swbst {
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5150000>;
+ };
+
+ snvs_reg: vsnvs {
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ vref_reg: vrefddr {
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ vgen1_reg: vgen1 {
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1550000>;
+ };
+
+ vgen2_reg: vgen2 {
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1550000>;
+ };
+
+ vgen3_reg: vgen3 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ vgen4_reg: vgen4 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ vgen5_reg: vgen5 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ vgen6_reg: vgen6 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+ };
+ };
+};
+
+&i2c2 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c2_1>;
+ status = "okay";
+
+ max7322_1: gpio@68 {
+ compatible = "maxim,max7322";
+ reg = <0x68>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ resets = <&max7322_reset>;
+ };
+
+ max7322_2: gpio@69 {
+ compatible = "maxim,max7322";
+ reg = <0x69>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ resets = <&max7322_reset>;
+ };
+
+ codec: sgtl5000@0a {
+ compatible = "fsl,sgtl5000";
+ reg = <0x0a>;
+ clocks = <&codec_osc>;
+ VDDA-supply = <&vgen4_reg>;
+ VDDIO-supply = <&reg_3p3v>;
+ };
+};
+
+
+&i2c3 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c3_1>;
+ status = "okay";
+};
+
+&i2c4 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c4_1>;
+ status = "okay";
+};
+
+&iomuxc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_hog_1>;
+
+ hog {
+ pinctrl_hog_1: hoggrp-1 {
+ fsl,pins = <
+ MX6SX_PAD_KEY_COL0__GPIO2_IO_10 0x1f059
+ MX6SX_PAD_KEY_ROW0__GPIO2_IO_15 0x1f059
+ MX6SX_PAD_QSPI1A_SS0_B__GPIO4_IO_22 0x80000000
+ /* CAN1_2_EN */
+ MX6SX_PAD_QSPI1B_DATA1__GPIO4_IO_25 0x17059
+ /* CAN1_2_STBY_B */
+ MX6SX_PAD_QSPI1B_DATA3__GPIO4_IO_27 0x17059
+ /* CAN1_ERR_B */
+ MX6SX_PAD_QSPI1B_DATA0__GPIO4_IO_24 0x17059
+ /* CAN2_ERR_B */
+ MX6SX_PAD_QSPI1B_SS0_B__GPIO4_IO_30 0x17059
+ /* SD2_PWROFF */
+ MX6SX_PAD_KEY_COL1__GPIO2_IO_11 0x17059
+ >;
+ };
+ };
+};
+
+&lcdif1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lcdif_dat_0
+ &pinctrl_lcdif_ctrl_0>;
+ display = <&display0>;
+ status = "okay";
+
+ display0: display@0 {
+ bits-per-pixel = <16>;
+ bus-width = <24>;
+
+ display-timings {
+ native-mode = <&timing0>;
+ timing0: timing0 {
+ clock-frequency = <33500000>;
+ hactive = <800>;
+ vactive = <480>;
+ hback-porch = <89>;
+ hfront-porch = <164>;
+ vback-porch = <23>;
+ vfront-porch = <10>;
+ hsync-len = <10>;
+ vsync-len = <10>;
+ hsync-active = <0>;
+ vsync-active = <0>;
+ de-active = <1>;
+ pixelclk-active = <0>;
+ };
+ };
+ };
+};
+
+&mlb {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_mlb_1>;
+ status = "disabled";/* pin conflict with usdhc2*/
+};
+
+&pwm3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pwm3_0>;
+ status = "okay";
+};
+
+&pxp {
+ status = "okay";
+};
+
+&qspi2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_qspi2_1>;
+ status = "okay";
+ ddrsmp=<2>;
+
+ flash0: n25q256a@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "micron,n25q256a";
+ spi-max-frequency = <29000000>;
+ reg = <0>;
+ };
+
+ flash1: n25q256a@1 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "micron,n25q256a";
+ spi-max-frequency = <29000000>;
+ reg = <1>;
+ };
+};
+
+&sai2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_sai2_1>;
+ status = "disabled";
+};
+
+&spdif {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_spdif_1>;
+ status = "disabled";
+};
+
+&ssi1 {
+ fsl,mode = "i2s-slave";
+ status = "okay";
+};
+
+&snvs_poweroff {
+ status = "okay";
+};
+
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart1_1>;
+ status = "okay";
+};
+
+&uart2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart2_1>;
+ status = "okay";
+};
+
+&usbh {
+ pinctrl-names = "idle", "active";
+ pinctrl-0 = <&pinctrl_usbh_1>;
+ pinctrl-1 = <&pinctrl_usbh_2>;
+ osc-clkgate-delay = <0x3>;
+ pad-supply = <&vgen1_reg>;
+ status = "okay";
+};
+
+&usbotg1 {
+ vbus-supply = <&reg_usb_otg1_vbus>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usbotg1_1>;
+ disable-over-current;
+ status = "okay";
+};
+
+&usbotg2 {
+ /*
+ * Pin conflict with others, need to switch R580 & R579
+ * to B and disable pwm3 to enable it.
+ */
+ vbus-supply = <&reg_usb_otg2_vbus>;
+ disable-over-current;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usbotg2_1>;
+ status = "disabled";
+};
+
+&usdhc2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usdhc2_1>;
+ non-removable;
+ /* need hw rework to enable signal voltage switch */
+ no-1-8-v;
+ keep-power-in-suspend;
+ enable-sdio-wakeup;
+ status = "okay";
+};
+
+&usdhc3 {
+ pinctrl-names = "default", "state_100mhz", "state_200mhz";
+ pinctrl-0 = <&pinctrl_usdhc3_1>;
+ pinctrl-1 = <&pinctrl_usdhc3_1_100mhz>;
+ pinctrl-2 = <&pinctrl_usdhc3_1_200mhz>;
+ bus-width = <8>;
+ cd-gpios = <&gpio2 10 0>;
+ wp-gpios = <&gpio2 15 0>;
+ keep-power-in-suspend;
+ enable-sdio-wakeup;
+ vmmc-supply = <&reg_sdb_vmmc>;
+ status = "okay";
+};
+
+&usdhc4 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usdhc4_1>;
+ bus-width = <8>;
+ non-removable;
+ /* need hw rework to enable signal voltage switch */
+ no-1-8-v;
+ status = "okay";
+};
+
+&wdog1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_wdog>;
+ fsl,ext-reset-output;
+};
+
+&iomuxc {
+ audmux {
+ pinctrl_audmux_1: audmuxgrp-1 {
+ fsl,pins = <
+ MX6SX_PAD_CSI_DATA00__AUDMUX_AUD6_TXC 0x130B0
+ MX6SX_PAD_CSI_DATA01__AUDMUX_AUD6_TXFS 0x130B0
+ MX6SX_PAD_CSI_HSYNC__AUDMUX_AUD6_TXD 0x120B0
+ MX6SX_PAD_CSI_VSYNC__AUDMUX_AUD6_RXD 0x130B0
+ MX6SX_PAD_CSI_PIXCLK__AUDMUX_MCLK 0x130B0
+ >;
+ };
+
+ pinctrl_audmux_2: audmuxgrp-2 {
+ fsl,pins = <
+ MX6SX_PAD_ENET1_COL__AUDMUX_AUD4_TXC 0x130b0
+ MX6SX_PAD_ENET1_CRS__AUDMUX_AUD4_TXD 0x130b0
+ MX6SX_PAD_ENET1_RX_CLK__AUDMUX_AUD4_TXFS 0x130b0
+ MX6SX_PAD_ENET1_TX_CLK__AUDMUX_AUD4_RXD 0x130b0
+ >;
+ };
+
+ pinctrl_audmux_3: audmux-3 {
+ fsl,pins = <
+ MX6SX_PAD_SD1_CMD__AUDMUX_AUD5_RXC 0x130b0
+ MX6SX_PAD_SD1_CLK__AUDMUX_AUD5_RXFS 0x130b0
+ MX6SX_PAD_SD1_DATA3__AUDMUX_AUD5_RXD 0x130b0
+ >;
+ };
+ };
+
+ ecspi4 {
+ pinctrl_ecspi4_cs_1: ecspi4_cs_grp-1 {
+ fsl,pins = <
+ MX6SX_PAD_SD3_DATA2__GPIO7_IO_4 0x80000000
+ >;
+ };
+
+ pinctrl_ecspi4_1: ecspi4grp-1 {
+ fsl,pins = <
+ MX6SX_PAD_SD3_DATA3__ECSPI4_MISO 0x100b1
+ MX6SX_PAD_SD3_CMD__ECSPI4_MOSI 0x100b1
+ MX6SX_PAD_SD3_CLK__ECSPI4_SCLK 0x100b1
+ >;
+ };
+ };
+
+ csi {
+ pinctrl_csi_0: csigrp-0 {
+ fsl,pins = <
+ MX6SX_PAD_LCD1_DATA07__CSI1_MCLK 0x110b0
+ MX6SX_PAD_LCD1_DATA06__CSI1_PIXCLK 0x110b0
+ MX6SX_PAD_LCD1_DATA04__CSI1_VSYNC 0x110b0
+ MX6SX_PAD_LCD1_DATA05__CSI1_HSYNC 0x110b0
+ MX6SX_PAD_LCD1_DATA17__CSI1_DATA_0 0x110b0
+ MX6SX_PAD_LCD1_DATA16__CSI1_DATA_1 0x110b0
+ MX6SX_PAD_LCD1_DATA15__CSI1_DATA_2 0x110b0
+ MX6SX_PAD_LCD1_DATA14__CSI1_DATA_3 0x110b0
+ MX6SX_PAD_LCD1_DATA13__CSI1_DATA_4 0x110b0
+ MX6SX_PAD_LCD1_DATA12__CSI1_DATA_5 0x110b0
+ MX6SX_PAD_LCD1_DATA11__CSI1_DATA_6 0x110b0
+ MX6SX_PAD_LCD1_DATA10__CSI1_DATA_7 0x110b0
+ MX6SX_PAD_LCD1_DATA09__CSI1_DATA_8 0x110b0
+ MX6SX_PAD_LCD1_DATA08__CSI1_DATA_9 0x110b0
+ MX6SX_PAD_LCD1_RESET__GPIO3_IO_27 0x80000000
+ MX6SX_PAD_LCD1_VSYNC__GPIO3_IO_28 0x80000000
+ >;
+ };
+
+ pinctrl_csi_1: csigrp-1 {
+ fsl,pins = <
+ MX6SX_PAD_CSI_MCLK__CSI1_MCLK 0x110b0
+ MX6SX_PAD_CSI_PIXCLK__CSI1_PIXCLK 0x110b0
+ MX6SX_PAD_CSI_VSYNC__CSI1_VSYNC 0x110b0
+ MX6SX_PAD_CSI_HSYNC__CSI1_HSYNC 0x110b0
+ MX6SX_PAD_CSI_DATA00__CSI1_DATA_2 0x110b0
+ MX6SX_PAD_CSI_DATA01__CSI1_DATA_3 0x110b0
+ MX6SX_PAD_CSI_DATA02__CSI1_DATA_4 0x110b0
+ MX6SX_PAD_CSI_DATA03__CSI1_DATA_5 0x110b0
+ MX6SX_PAD_CSI_DATA04__CSI1_DATA_6 0x110b0
+ MX6SX_PAD_CSI_DATA05__CSI1_DATA_7 0x110b0
+ MX6SX_PAD_CSI_DATA06__CSI1_DATA_8 0x110b0
+ MX6SX_PAD_CSI_DATA07__CSI1_DATA_9 0x110b0
+
+ MX6SX_PAD_LCD1_ENABLE__GPIO3_IO_25 0x80000000
+ MX6SX_PAD_LCD1_HSYNC__GPIO3_IO_26 0x80000000
+ >;
+ };
+ };
+
+ enet1 {
+ pinctrl_enet1_1: enet1grp-1 {
+ fsl,pins = <
+ MX6SX_PAD_ENET1_MDIO__ENET1_MDIO 0xa0b1
+ MX6SX_PAD_ENET1_MDC__ENET1_MDC 0xa0b1
+ MX6SX_PAD_RGMII1_TXC__ENET1_RGMII_TXC 0xa0b9
+ MX6SX_PAD_RGMII1_TD0__ENET1_TX_DATA_0 0xa0b1
+ MX6SX_PAD_RGMII1_TD1__ENET1_TX_DATA_1 0xa0b1
+ MX6SX_PAD_RGMII1_TD2__ENET1_TX_DATA_2 0xa0b1
+ MX6SX_PAD_RGMII1_TD3__ENET1_TX_DATA_3 0xa0b1
+ MX6SX_PAD_RGMII1_TX_CTL__ENET1_TX_EN 0xa0b1
+ MX6SX_PAD_RGMII1_RXC__ENET1_RX_CLK 0x3081
+ MX6SX_PAD_RGMII1_RD0__ENET1_RX_DATA_0 0x3081
+ MX6SX_PAD_RGMII1_RD1__ENET1_RX_DATA_1 0x3081
+ MX6SX_PAD_RGMII1_RD2__ENET1_RX_DATA_2 0x3081
+ MX6SX_PAD_RGMII1_RD3__ENET1_RX_DATA_3 0x3081
+ MX6SX_PAD_RGMII1_RX_CTL__ENET1_RX_EN 0x3081
+ >;
+ };
+
+ pinctrl_enet1_clkout_1: enet1_clkoutgrp-1 {
+ fsl,pins = <
+ MX6SX_PAD_ENET2_RX_CLK__ENET2_REF_CLK_25M 0x91
+ >;
+ };
+ };
+
+ enet2 {
+ pinctrl_enet2_1: enet2grp-1 {
+ fsl,pins = <
+ MX6SX_PAD_RGMII2_TXC__ENET2_RGMII_TXC 0xa0b9
+ MX6SX_PAD_RGMII2_TD0__ENET2_TX_DATA_0 0xa0b1
+ MX6SX_PAD_RGMII2_TD1__ENET2_TX_DATA_1 0xa0b1
+ MX6SX_PAD_RGMII2_TD2__ENET2_TX_DATA_2 0xa0b1
+ MX6SX_PAD_RGMII2_TD3__ENET2_TX_DATA_3 0xa0b1
+ MX6SX_PAD_RGMII2_TX_CTL__ENET2_TX_EN 0xa0b1
+ MX6SX_PAD_RGMII2_RXC__ENET2_RX_CLK 0x3081
+ MX6SX_PAD_RGMII2_RD0__ENET2_RX_DATA_0 0x3081
+ MX6SX_PAD_RGMII2_RD1__ENET2_RX_DATA_1 0x3081
+ MX6SX_PAD_RGMII2_RD2__ENET2_RX_DATA_2 0x3081
+ MX6SX_PAD_RGMII2_RD3__ENET2_RX_DATA_3 0x3081
+ MX6SX_PAD_RGMII2_RX_CTL__ENET2_RX_EN 0x3081
+ >;
+ };
+ };
+
+ esai {
+ pinctrl_esai_1: esaigrp-1 {
+ fsl,pins = <
+ MX6SX_PAD_CSI_MCLK__ESAI_TX_HF_CLK 0x1b030
+ MX6SX_PAD_CSI_DATA00__ESAI_TX_CLK 0x1b030
+ MX6SX_PAD_CSI_DATA01__ESAI_TX_FS 0x1b030
+ MX6SX_PAD_CSI_HSYNC__ESAI_TX0 0x1b030
+ MX6SX_PAD_CSI_DATA04__ESAI_TX1 0x1b030
+ MX6SX_PAD_CSI_DATA06__ESAI_TX2_RX3 0x1b030
+ MX6SX_PAD_CSI_DATA07__ESAI_TX3_RX2 0x1b030
+ MX6SX_PAD_CSI_DATA02__ESAI_RX_CLK 0x1b030
+ MX6SX_PAD_CSI_DATA03__ESAI_RX_FS 0x1b030
+ MX6SX_PAD_CSI_VSYNC__ESAI_TX5_RX0 0x1b030
+ MX6SX_PAD_CSI_DATA05__ESAI_TX4_RX1 0x1b030
+ >;
+ };
+
+ pinctrl_esai_2: esaigrp-2 {
+ fsl,pins = <
+ MX6SX_PAD_CSI_DATA00__ESAI_TX_CLK 0x1b030
+ MX6SX_PAD_CSI_DATA01__ESAI_TX_FS 0x1b030
+ MX6SX_PAD_CSI_HSYNC__ESAI_TX0 0x1b030
+ MX6SX_PAD_CSI_DATA04__ESAI_TX1 0x1b030
+ MX6SX_PAD_CSI_DATA06__ESAI_TX2_RX3 0x1b030
+ MX6SX_PAD_CSI_DATA07__ESAI_TX3_RX2 0x1b030
+ MX6SX_PAD_CSI_DATA02__ESAI_RX_CLK 0x1b030
+ MX6SX_PAD_CSI_DATA03__ESAI_RX_FS 0x1b030
+ MX6SX_PAD_CSI_VSYNC__ESAI_TX5_RX0 0x1b030
+ MX6SX_PAD_CSI_DATA05__ESAI_TX4_RX1 0x1b030
+ >;
+ };
+ };
+
+ flexcan1 {
+ pinctrl_flexcan1_1: flexcan1grp-1 {
+ fsl,pins = <
+ MX6SX_PAD_QSPI1B_DQS__CAN1_TX 0x1b020
+ MX6SX_PAD_QSPI1A_SS1_B__CAN1_RX 0x1b020
+ >;
+ };
+ };
+
+ flexcan2 {
+ pinctrl_flexcan2_1: flexcan2grp-1 {
+ fsl,pins = <
+ MX6SX_PAD_QSPI1B_SS1_B__CAN2_RX 0x1b020
+ MX6SX_PAD_QSPI1A_DQS__CAN2_TX 0x1b020
+ >;
+ };
+ };
+
+ gpmi-nand {
+ pinctrl_gpmi_nand_1: gpmi-nand-1 {
+ fsl,pins = <
+ MX6SX_PAD_NAND_CLE__RAWNAND_CLE 0xb0b1
+ MX6SX_PAD_NAND_ALE__RAWNAND_ALE 0xb0b1
+ MX6SX_PAD_NAND_WP_B__RAWNAND_WP_B 0xb0b1
+ MX6SX_PAD_NAND_READY_B__RAWNAND_READY_B 0xb000
+ MX6SX_PAD_NAND_CE0_B__RAWNAND_CE0_B 0xb0b1
+ MX6SX_PAD_NAND_CE1_B__RAWNAND_CE1_B 0xb0b1
+ MX6SX_PAD_NAND_RE_B__RAWNAND_RE_B 0xb0b1
+ MX6SX_PAD_NAND_WE_B__RAWNAND_WE_B 0xb0b1
+ MX6SX_PAD_NAND_DATA00__RAWNAND_DATA00 0xb0b1
+ MX6SX_PAD_NAND_DATA01__RAWNAND_DATA01 0xb0b1
+ MX6SX_PAD_NAND_DATA02__RAWNAND_DATA02 0xb0b1
+ MX6SX_PAD_NAND_DATA03__RAWNAND_DATA03 0xb0b1
+ MX6SX_PAD_NAND_DATA04__RAWNAND_DATA04 0xb0b1
+ MX6SX_PAD_NAND_DATA05__RAWNAND_DATA05 0xb0b1
+ MX6SX_PAD_NAND_DATA06__RAWNAND_DATA06 0xb0b1
+ MX6SX_PAD_NAND_DATA07__RAWNAND_DATA07 0xb0b1
+ >;
+ };
+ };
+
+ i2c1 {
+ pinctrl_i2c1_1: i2c1grp-1 {
+ fsl,pins = <
+ MX6SX_PAD_GPIO1_IO01__I2C1_SDA 0x4001b8b1
+ MX6SX_PAD_GPIO1_IO00__I2C1_SCL 0x4001b8b1
+ >;
+ };
+
+ pinctrl_i2c1_2: i2c1grp-2 {
+ fsl,pins = <
+ MX6SX_PAD_CSI_DATA01__I2C1_SDA 0x4001b8b1
+ MX6SX_PAD_CSI_DATA00__I2C1_SCL 0x4001b8b1
+ >;
+ };
+ };
+
+ i2c2 {
+ pinctrl_i2c2_1: i2c2grp-1 {
+ fsl,pins = <
+ MX6SX_PAD_GPIO1_IO03__I2C2_SDA 0x4001b8b1
+ MX6SX_PAD_GPIO1_IO02__I2C2_SCL 0x4001b8b1
+ >;
+ };
+ };
+
+ i2c3 {
+ pinctrl_i2c3_1: i2c3grp-1 {
+ fsl,pins = <
+ MX6SX_PAD_ENET2_TX_CLK__I2C3_SDA 0x4001b8b1
+ MX6SX_PAD_KEY_COL4__I2C3_SCL 0x4001b8b1
+ >;
+ };
+
+ pinctrl_i2c3_2: i2c3grp-2 {
+ fsl,pins = <
+ MX6SX_PAD_KEY_ROW4__I2C3_SDA 0x4001b8b1
+ MX6SX_PAD_KEY_COL4__I2C3_SCL 0x4001b8b1
+ >;
+ };
+ };
+
+ i2c4 {
+ pinctrl_i2c4_1: i2c4grp-1 {
+ fsl,pins = <
+ MX6SX_PAD_CSI_DATA07__I2C4_SDA 0x4001b8b1
+ MX6SX_PAD_CSI_DATA06__I2C4_SCL 0x4001b8b1
+ >;
+ };
+ pinctrl_i2c4_2: i2c4grp-2 {
+ fsl,pins = <
+ MX6SX_PAD_SD3_DATA1__I2C4_SDA 0x4001b8b1
+ MX6SX_PAD_SD3_DATA0__I2C4_SCL 0x4001b8b1
+ >;
+ };
+ };
+
+ lcdif1 {
+ pinctrl_lcdif_dat_0: lcdifdatgrp-0 {
+ fsl,pins = <
+ MX6SX_PAD_LCD1_DATA00__LCDIF1_DATA_0 0x4001b0b0
+ MX6SX_PAD_LCD1_DATA01__LCDIF1_DATA_1 0x4001b0b0
+ MX6SX_PAD_LCD1_DATA02__LCDIF1_DATA_2 0x4001b0b0
+ MX6SX_PAD_LCD1_DATA03__LCDIF1_DATA_3 0x4001b0b0
+ MX6SX_PAD_LCD1_DATA04__LCDIF1_DATA_4 0x4001b0b0
+ MX6SX_PAD_LCD1_DATA05__LCDIF1_DATA_5 0x4001b0b0
+ MX6SX_PAD_LCD1_DATA06__LCDIF1_DATA_6 0x4001b0b0
+ MX6SX_PAD_LCD1_DATA07__LCDIF1_DATA_7 0x4001b0b0
+ MX6SX_PAD_LCD1_DATA08__LCDIF1_DATA_8 0x4001b0b0
+ MX6SX_PAD_LCD1_DATA09__LCDIF1_DATA_9 0x4001b0b0
+ MX6SX_PAD_LCD1_DATA10__LCDIF1_DATA_10 0x4001b0b0
+ MX6SX_PAD_LCD1_DATA11__LCDIF1_DATA_11 0x4001b0b0
+ MX6SX_PAD_LCD1_DATA12__LCDIF1_DATA_12 0x4001b0b0
+ MX6SX_PAD_LCD1_DATA13__LCDIF1_DATA_13 0x4001b0b0
+ MX6SX_PAD_LCD1_DATA14__LCDIF1_DATA_14 0x4001b0b0
+ MX6SX_PAD_LCD1_DATA15__LCDIF1_DATA_15 0x4001b0b0
+ MX6SX_PAD_LCD1_DATA16__LCDIF1_DATA_16 0x4001b0b0
+ MX6SX_PAD_LCD1_DATA17__LCDIF1_DATA_17 0x4001b0b0
+ MX6SX_PAD_LCD1_DATA18__LCDIF1_DATA_18 0x4001b0b0
+ MX6SX_PAD_LCD1_DATA19__LCDIF1_DATA_19 0x4001b0b0
+ MX6SX_PAD_LCD1_DATA20__LCDIF1_DATA_20 0x4001b0b0
+ MX6SX_PAD_LCD1_DATA21__LCDIF1_DATA_21 0x4001b0b0
+ MX6SX_PAD_LCD1_DATA22__LCDIF1_DATA_22 0x4001b0b0
+ MX6SX_PAD_LCD1_DATA23__LCDIF1_DATA_23 0x4001b0b0
+ >;
+ };
+
+ pinctrl_lcdif_ctrl_0: lcdifctrlgrp-0 {
+ fsl,pins = <
+ MX6SX_PAD_LCD1_CLK__LCDIF1_CLK 0x4001b0b0
+ MX6SX_PAD_LCD1_ENABLE__LCDIF1_ENABLE 0x4001b0b0
+ MX6SX_PAD_LCD1_VSYNC__LCDIF1_VSYNC 0x4001b0b0
+ MX6SX_PAD_LCD1_HSYNC__LCDIF1_HSYNC 0x4001b0b0
+ MX6SX_PAD_LCD1_RESET__GPIO3_IO_27 0x1b0b0
+ >;
+ };
+ };
+
+ mlb {
+ pinctrl_mlb_1: mlbgrp-1 {
+ fsl,pins = <
+ MX6SX_PAD_SD2_DATA3__MLB_DATA 0x31
+ MX6SX_PAD_SD2_CLK__MLB_SIG 0x31
+ MX6SX_PAD_SD2_CMD__MLB_CLK 0x31
+ >;
+ };
+
+ pinctrl_mlb_2: mlbgrp-2 {
+ fsl,pins = <
+ MX6SX_PAD_ENET2_RX_CLK__MLB_DATA 0x31
+ MX6SX_PAD_ENET2_CRS__MLB_SIG 0x31
+ MX6SX_PAD_ENET2_TX_CLK__MLB_CLK 0x31
+ >;
+ };
+ };
+
+ mqs {
+ pinctrl_mqs_1: mqsgrp-1 {
+ fsl,pins = <
+ MX6SX_PAD_SD2_CLK__MQS_RIGHT 0x80000000
+ MX6SX_PAD_SD2_CMD__MQS_LEFT 0x80000000
+ >;
+ };
+ };
+
+ pwm3 {
+ pinctrl_pwm3_0: pwm3grp-0 {
+ fsl,pins = <
+ MX6SX_PAD_GPIO1_IO12__PWM3_OUT 0x110b0
+ >;
+ };
+
+ pinctrl_pwm3_1: pwm3grp-1 {
+ fsl,pins = <
+ MX6SX_PAD_SD1_DATA2__PWM3_OUT 0x110b0
+ >;
+ };
+ };
+
+ pwm4 {
+ pinctrl_pwm4_0: pwm4grp-0 {
+ fsl,pins = <
+ MX6SX_PAD_SD1_DATA1__PWM4_OUT 0x110b0
+ >;
+ };
+ };
+
+ qspi1 {
+ pinctrl_qspi1_1: qspi1grp_1 {
+ fsl,pins = <
+ MX6SX_PAD_QSPI1A_DATA0__QSPI1_A_DATA_0 0x70a1
+ MX6SX_PAD_QSPI1A_DATA1__QSPI1_A_DATA_1 0x70a1
+ MX6SX_PAD_QSPI1A_DATA2__QSPI1_A_DATA_2 0x70a1
+ MX6SX_PAD_QSPI1A_DATA3__QSPI1_A_DATA_3 0x70a1
+ MX6SX_PAD_QSPI1A_SCLK__QSPI1_A_SCLK 0x70a1
+ MX6SX_PAD_QSPI1A_SS0_B__QSPI1_A_SS0_B 0x70a1
+ MX6SX_PAD_QSPI1B_DATA0__QSPI1_B_DATA_0 0x70a1
+ MX6SX_PAD_QSPI1B_DATA1__QSPI1_B_DATA_1 0x70a1
+ MX6SX_PAD_QSPI1B_DATA2__QSPI1_B_DATA_2 0x70a1
+ MX6SX_PAD_QSPI1B_DATA3__QSPI1_B_DATA_3 0x70a1
+ MX6SX_PAD_QSPI1B_SCLK__QSPI1_B_SCLK 0x70a1
+ MX6SX_PAD_QSPI1B_SS0_B__QSPI1_B_SS0_B 0x70a1
+ >;
+ };
+ };
+
+ qspi2 {
+ pinctrl_qspi2_1: qspi2grp_1 {
+ fsl,pins = <
+ MX6SX_PAD_NAND_WP_B__QSPI2_A_DATA_0 0x70a1
+ MX6SX_PAD_NAND_READY_B__QSPI2_A_DATA_1 0x70a1
+ MX6SX_PAD_NAND_CE0_B__QSPI2_A_DATA_2 0x70a1
+ MX6SX_PAD_NAND_CE1_B__QSPI2_A_DATA_3 0x70a1
+ MX6SX_PAD_NAND_CLE__QSPI2_A_SCLK 0x70a1
+ MX6SX_PAD_NAND_ALE__QSPI2_A_SS0_B 0x70a1
+ MX6SX_PAD_NAND_DATA01__QSPI2_B_DATA_0 0x70a1
+ MX6SX_PAD_NAND_DATA00__QSPI2_B_DATA_1 0x70a1
+ MX6SX_PAD_NAND_WE_B__QSPI2_B_DATA_2 0x70a1
+ MX6SX_PAD_NAND_RE_B__QSPI2_B_DATA_3 0x70a1
+ MX6SX_PAD_NAND_DATA02__QSPI2_B_SCLK 0x70a1
+ MX6SX_PAD_NAND_DATA03__QSPI2_B_SS0_B 0x70a1
+ >;
+ };
+ };
+
+ sai1 {
+ pinctrl_sai1_1: sai1grp_1 {
+ fsl,pins = <
+ MX6SX_PAD_CSI_DATA00__SAI1_TX_BCLK 0x1b030
+ MX6SX_PAD_CSI_DATA01__SAI1_TX_SYNC 0x1b030
+ MX6SX_PAD_CSI_DATA02__SAI1_RX_BCLK 0x1b030
+ MX6SX_PAD_CSI_DATA03__SAI1_RX_SYNC 0x1b030
+ MX6SX_PAD_CSI_HSYNC__SAI1_TX_DATA_0 0x1b030
+ MX6SX_PAD_CSI_VSYNC__SAI1_RX_DATA_0 0x1b030
+ >;
+ };
+
+ pinctrl_sai1_2: sai1grp_2 {
+ fsl,pins = <
+ MX6SX_PAD_CSI_DATA00__SAI1_TX_BCLK 0x130B0
+ MX6SX_PAD_CSI_DATA01__SAI1_TX_SYNC 0x130B0
+ MX6SX_PAD_CSI_HSYNC__SAI1_TX_DATA_0 0x120B0
+ MX6SX_PAD_CSI_VSYNC__SAI1_RX_DATA_0 0x130B0
+ MX6SX_PAD_CSI_PIXCLK__AUDMUX_MCLK 0x130B0
+ >;
+ };
+ };
+
+ sai2 {
+ pinctrl_sai2_1: sai2grp_1 {
+ fsl,pins = <
+ MX6SX_PAD_KEY_COL0__SAI2_TX_BCLK 0x1b030
+ MX6SX_PAD_KEY_COL1__SAI2_TX_SYNC 0x1b030
+ MX6SX_PAD_KEY_ROW0__SAI2_TX_DATA_0 0x1b030
+ MX6SX_PAD_KEY_ROW1__SAI2_RX_DATA_0 0x1b030
+ >;
+ };
+ };
+
+
+ spdif {
+ pinctrl_spdif_1: spdifgrp-1 {
+ fsl,pins = <
+ MX6SX_PAD_ENET1_RX_CLK__SPDIF_OUT 0x1b0b0
+ MX6SX_PAD_ENET2_COL__SPDIF_IN 0x1b0b0
+ >;
+ };
+
+ pinctrl_spdif_2: spdifgrp-2 {
+ fsl,pins = <
+ MX6SX_PAD_SD4_DATA4__SPDIF_OUT 0x1b0b0
+ >;
+ };
+
+ pinctrl_spdif_3: spdifgrp-3 {
+ fsl,pins = <
+ MX6SX_PAD_ENET2_COL__SPDIF_IN 0x1b0b0
+ >;
+ };
+ };
+
+ uart1 {
+ pinctrl_uart1_1: uart1grp-1 {
+ fsl,pins = <
+ MX6SX_PAD_GPIO1_IO04__UART1_TX 0x1b0b1
+ MX6SX_PAD_GPIO1_IO05__UART1_RX 0x1b0b1
+ >;
+ };
+
+ pinctrl_uart1_2: uart1grp-2 {
+ fsl,pins = <
+ MX6SX_PAD_ENET2_COL__UART1_RX 0x1b0b1
+ MX6SX_PAD_ENET2_CRS__UART1_TX 0x1b0b1
+ >;
+ };
+ };
+
+ uart2 {
+ pinctrl_uart2_1: uart2grp-1 {
+ fsl,pins = <
+ MX6SX_PAD_GPIO1_IO07__UART2_RX 0x1b0b1
+ MX6SX_PAD_GPIO1_IO06__UART2_TX 0x1b0b1
+ >;
+ };
+
+ pinctrl_uart2_2: uart2grp-2 {
+ fsl,pins = <
+ MX6SX_PAD_SD1_DATA0__UART2_RX 0x1b0b1
+ MX6SX_PAD_SD1_DATA1__UART2_TX 0x1b0b1
+ >;
+ };
+ };
+
+ uart5 {
+ pinctrl_uart5_1: uart5grp-1 {
+ fsl,pins = <
+ MX6SX_PAD_KEY_ROW3__UART5_RX 0x1b0b1
+ MX6SX_PAD_KEY_COL3__UART5_TX 0x1b0b1
+ MX6SX_PAD_KEY_ROW2__UART5_CTS_B 0x1b0b1
+ MX6SX_PAD_KEY_COL2__UART5_RTS_B 0x1b0b1
+ >;
+ };
+
+ pinctrl_uart5dte_1: uart5dtegrp-1 {
+ fsl,pins = <
+ MX6SX_PAD_KEY_ROW3__UART5_TX 0x1b0b1
+ MX6SX_PAD_KEY_COL3__UART5_RX 0x1b0b1
+ MX6SX_PAD_KEY_ROW2__UART5_RTS_B 0x1b0b1
+ MX6SX_PAD_KEY_COL2__UART5_CTS_B 0x1b0b1
+ >;
+ };
+ };
+
+ usbh {
+ pinctrl_usbh_1: usbhgrp-1 {
+ fsl,pins = <
+ MX6SX_PAD_USB_H_STROBE__USB_H_STROBE 0x40013030
+ MX6SX_PAD_USB_H_DATA__USB_H_DATA 0x40013030
+ >;
+ };
+
+ pinctrl_usbh_2: usbhgrp-2 {
+ fsl,pins = <
+ MX6SX_PAD_USB_H_STROBE__USB_H_STROBE 0x40017030
+ >;
+ };
+ };
+
+ usbotg1 {
+ pinctrl_usbotg1_1: usbotg1grp-1 {
+ fsl,pins = <
+ MX6SX_PAD_GPIO1_IO10__ANATOP_OTG1_ID 0x17059
+ >;
+ };
+
+ pinctrl_usbotg1_2: usbotg1grp-2 {
+ fsl,pins = <
+ MX6SX_PAD_ENET2_COL__ANATOP_OTG1_ID 0x17059
+ >;
+ };
+
+ pinctrl_usbotg1_3: usbotg1grp-3 {
+ fsl,pins = <
+ MX6SX_PAD_QSPI1A_DATA1__ANATOP_OTG1_ID 0x17059
+ >;
+ };
+ };
+
+ usbotg2 {
+ pinctrl_usbotg2_1: usbotg2grp-1 {
+ fsl,pins = <
+ MX6SX_PAD_GPIO1_IO13__ANATOP_OTG2_ID 0x17059
+ >;
+ };
+
+ pinctrl_usbotg2_2: usbotg2grp-2 {
+ fsl,pins = <
+ MX6SX_PAD_ENET2_CRS__ANATOP_OTG2_ID 0x17059
+ >;
+ };
+
+ pinctrl_usbotg2_3: usbotg2grp-3 {
+ fsl,pins = <
+ MX6SX_PAD_QSPI1A_SCLK__ANATOP_OTG2_ID 0x17059
+ >;
+ };
+ };
+
+ usdhc1 {
+ pinctrl_usdhc1_1: usdhc1grp-1 {
+ fsl,pins = <
+ MX6SX_PAD_SD1_CMD__USDHC1_CMD 0x17059
+ MX6SX_PAD_SD1_CLK__USDHC1_CLK 0x10059
+ MX6SX_PAD_SD1_DATA0__USDHC1_DATA0 0x17059
+ MX6SX_PAD_SD1_DATA1__USDHC1_DATA1 0x17059
+ MX6SX_PAD_SD1_DATA2__USDHC1_DATA2 0x17059
+ MX6SX_PAD_SD1_DATA3__USDHC1_DATA3 0x17059
+ >;
+ };
+ };
+
+ usdhc2 {
+ pinctrl_usdhc2_1: usdhc2grp-1 {
+ fsl,pins = <
+ MX6SX_PAD_SD2_CMD__USDHC2_CMD 0x17059
+ MX6SX_PAD_SD2_CLK__USDHC2_CLK 0x10059
+ MX6SX_PAD_SD2_DATA0__USDHC2_DATA0 0x17059
+ MX6SX_PAD_SD2_DATA1__USDHC2_DATA1 0x17059
+ MX6SX_PAD_SD2_DATA2__USDHC2_DATA2 0x17059
+ MX6SX_PAD_SD2_DATA3__USDHC2_DATA3 0x17059
+ >;
+ };
+ };
+
+ usdhc3 {
+ pinctrl_usdhc3_1: usdhc3grp-1 {
+ 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
+ >;
+ };
+
+ pinctrl_usdhc3_1_100mhz: usdhc3grp-1-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_1_200mhz: usdhc3grp-1-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
+ >;
+ };
+
+ };
+
+ usdhc4 {
+ pinctrl_usdhc4_1: usdhc4grp-1 {
+ 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_DATA4__USDHC4_DATA4 0x17059
+ MX6SX_PAD_SD4_DATA5__USDHC4_DATA5 0x17059
+ MX6SX_PAD_SD4_DATA6__USDHC4_DATA6 0x17059
+ MX6SX_PAD_SD4_DATA7__USDHC4_DATA7 0x17059
+ >;
+ };
+
+ pinctrl_usdhc4_1_100mhz: usdhc4grp-1-100mhz {
+ fsl,pins = <
+ MX6SX_PAD_SD4_CMD__USDHC4_CMD 0x170b9
+ MX6SX_PAD_SD4_CLK__USDHC4_CLK 0x100b9
+ MX6SX_PAD_SD4_DATA0__USDHC4_DATA0 0x170b9
+ MX6SX_PAD_SD4_DATA1__USDHC4_DATA1 0x170b9
+ MX6SX_PAD_SD4_DATA2__USDHC4_DATA2 0x170b9
+ MX6SX_PAD_SD4_DATA3__USDHC4_DATA3 0x170b9
+ MX6SX_PAD_SD4_DATA4__USDHC4_DATA4 0x170b9
+ MX6SX_PAD_SD4_DATA5__USDHC4_DATA5 0x170b9
+ MX6SX_PAD_SD4_DATA6__USDHC4_DATA6 0x170b9
+ MX6SX_PAD_SD4_DATA7__USDHC4_DATA7 0x170b9
+ >;
+ };
+
+ pinctrl_usdhc4_1_200mhz: usdhc4grp-1-200mhz {
+ fsl,pins = <
+ MX6SX_PAD_SD4_CMD__USDHC4_CMD 0x170f9
+ MX6SX_PAD_SD4_CLK__USDHC4_CLK 0x100f9
+ MX6SX_PAD_SD4_DATA0__USDHC4_DATA0 0x170f9
+ MX6SX_PAD_SD4_DATA1__USDHC4_DATA1 0x170f9
+ MX6SX_PAD_SD4_DATA2__USDHC4_DATA2 0x170f9
+ MX6SX_PAD_SD4_DATA3__USDHC4_DATA3 0x170f9
+ MX6SX_PAD_SD4_DATA4__USDHC4_DATA4 0x170f9
+ MX6SX_PAD_SD4_DATA5__USDHC4_DATA5 0x170f9
+ MX6SX_PAD_SD4_DATA6__USDHC4_DATA6 0x170f9
+ MX6SX_PAD_SD4_DATA7__USDHC4_DATA7 0x170f9
+ >;
+ };
+
+ pinctrl_usdhc4_2: usdhc4grp-2 {
+ 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
+ >;
+ };
+
+ pinctrl_usdhc4_3: usdhc4grp-3 {
+ fsl,pins = <
+ MX6SX_PAD_SD4_CMD__USDHC4_CMD 0x17071
+ MX6SX_PAD_SD4_CLK__USDHC4_CLK 0x10071
+ MX6SX_PAD_SD4_DATA0__USDHC4_DATA0 0x17071
+ MX6SX_PAD_SD4_DATA1__USDHC4_DATA1 0x17071
+ MX6SX_PAD_SD4_DATA2__USDHC4_DATA2 0x17071
+ MX6SX_PAD_SD4_DATA3__USDHC4_DATA3 0x17071
+ MX6SX_PAD_SD4_DATA4__USDHC4_DATA4 0x17071
+ MX6SX_PAD_SD4_DATA5__USDHC4_DATA5 0x17071
+ MX6SX_PAD_SD4_DATA6__USDHC4_DATA6 0x17071
+ MX6SX_PAD_SD4_DATA7__USDHC4_DATA7 0x17071
+ >;
+ };
+
+ };
+
+ wdog {
+ pinctrl_wdog: wdoggrp {
+ fsl,pins = <
+ MX6SX_PAD_GPIO1_IO13__WDOG1_WDOG_ANY 0x10b0
+ >;
+ };
+ };
+
+ weim {
+ pinctrl_weim_cs0_1: weim_cs0grp-1 {
+ fsl,pins = <
+ MX6SX_PAD_NAND_ALE__WEIM_CS0_B 0xb0b1
+ >;
+ };
+
+ pinctrl_weim_nor_1: weim_norgrp-1 {
+ fsl,pins = <
+ MX6SX_PAD_NAND_CE1_B__WEIM_OE 0xb0b1
+ MX6SX_PAD_NAND_RE_B__WEIM_RW 0xb0b1
+ MX6SX_PAD_NAND_WE_B__WEIM_WAIT 0xb060
+ /* data */
+ MX6SX_PAD_QSPI1A_SCLK__WEIM_DATA_0 0x1b0b0
+ MX6SX_PAD_QSPI1A_SS0_B__WEIM_DATA_1 0x1b0b0
+ MX6SX_PAD_QSPI1A_SS1_B__WEIM_DATA_2 0x1b0b0
+ MX6SX_PAD_QSPI1A_DATA3__WEIM_DATA_3 0x1b0b0
+ MX6SX_PAD_QSPI1A_DATA2__WEIM_DATA_4 0x1b0b0
+ MX6SX_PAD_QSPI1A_DATA1__WEIM_DATA_5 0x1b0b0
+ MX6SX_PAD_QSPI1A_DATA0__WEIM_DATA_6 0x1b0b0
+ MX6SX_PAD_QSPI1A_DQS__WEIM_DATA_7 0x1b0b0
+ MX6SX_PAD_QSPI1B_SCLK__WEIM_DATA_8 0x1b0b0
+ MX6SX_PAD_QSPI1B_SS0_B__WEIM_DATA_9 0x1b0b0
+ MX6SX_PAD_QSPI1B_SS1_B__WEIM_DATA_10 0x1b0b0
+ MX6SX_PAD_QSPI1B_DATA3__WEIM_DATA_11 0x1b0b0
+ MX6SX_PAD_QSPI1B_DATA2__WEIM_DATA_12 0x1b0b0
+ MX6SX_PAD_QSPI1B_DATA1__WEIM_DATA_13 0x1b0b0
+ MX6SX_PAD_QSPI1B_DATA0__WEIM_DATA_14 0x1b0b0
+ MX6SX_PAD_QSPI1B_DQS__WEIM_DATA_15 0x1b0b0
+ /* address */
+ MX6SX_PAD_NAND_DATA00__WEIM_AD_0 0xb0b1
+ MX6SX_PAD_NAND_DATA01__WEIM_AD_1 0xb0b1
+ MX6SX_PAD_NAND_DATA02__WEIM_AD_2 0xb0b1
+ MX6SX_PAD_NAND_DATA03__WEIM_AD_3 0xb0b1
+ MX6SX_PAD_NAND_DATA04__WEIM_AD_4 0xb0b1
+ MX6SX_PAD_NAND_DATA05__WEIM_AD_5 0xb0b1
+ MX6SX_PAD_NAND_DATA06__WEIM_AD_6 0xb0b1
+ MX6SX_PAD_NAND_DATA07__WEIM_AD_7 0xb0b1
+ MX6SX_PAD_LCD1_DATA08__WEIM_AD_8 0xb0b1
+ MX6SX_PAD_LCD1_DATA09__WEIM_AD_9 0xb0b1
+ MX6SX_PAD_LCD1_DATA10__WEIM_AD_10 0xb0b1
+ MX6SX_PAD_LCD1_DATA11__WEIM_AD_11 0xb0b1
+ MX6SX_PAD_LCD1_DATA12__WEIM_AD_12 0xb0b1
+ MX6SX_PAD_LCD1_DATA13__WEIM_AD_13 0xb0b1
+ MX6SX_PAD_LCD1_DATA14__WEIM_AD_14 0xb0b1
+ MX6SX_PAD_LCD1_DATA15__WEIM_AD_15 0xb0b1
+ MX6SX_PAD_LCD1_DATA16__WEIM_ADDR_16 0xb0b1
+ MX6SX_PAD_LCD1_DATA17__WEIM_ADDR_17 0xb0b1
+ MX6SX_PAD_LCD1_DATA18__WEIM_ADDR_18 0xb0b1
+ MX6SX_PAD_LCD1_DATA19__WEIM_ADDR_19 0xb0b1
+ MX6SX_PAD_LCD1_DATA20__WEIM_ADDR_20 0xb0b1
+ MX6SX_PAD_LCD1_DATA21__WEIM_ADDR_21 0xb0b1
+ MX6SX_PAD_LCD1_DATA22__WEIM_ADDR_22 0xb0b1
+ MX6SX_PAD_LCD1_DATA03__WEIM_ADDR_24 0xb0b1
+ MX6SX_PAD_LCD1_DATA04__WEIM_ADDR_25 0xb0b1
+ MX6SX_PAD_LCD1_DATA05__WEIM_ADDR_26 0xb0b1
+ >;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/imx6sx-19x19-arm2-csi.dts b/arch/arm/boot/dts/imx6sx-19x19-arm2-csi.dts
new file mode 100644
index 000000000000..411939594217
--- /dev/null
+++ b/arch/arm/boot/dts/imx6sx-19x19-arm2-csi.dts
@@ -0,0 +1,25 @@
+/*
+ * 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 "imx6sx-19x19-arm2.dts"
+
+&esai {
+ /* pin conflict with sai */
+ status = "disabled";
+};
+
+&sai1 {
+ status = "disabled";
+};
+
+&i2c2 {
+ ov5640: ov5640@3c {
+ status = "okay";
+ };
+};
+
diff --git a/arch/arm/boot/dts/imx6sx-19x19-arm2-gpmi-weim.dts b/arch/arm/boot/dts/imx6sx-19x19-arm2-gpmi-weim.dts
new file mode 100644
index 000000000000..a50f335adb80
--- /dev/null
+++ b/arch/arm/boot/dts/imx6sx-19x19-arm2-gpmi-weim.dts
@@ -0,0 +1,20 @@
+/*
+ * 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 "imx6sx-19x19-arm2.dts"
+
+&qspi2 {
+ status = "disabled";
+};
+
+&gpmi {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpmi_nand_1>;
+ status = "okay"; /* pin conflict with qspi*/
+ nand-on-flash-bbt;
+};
diff --git a/arch/arm/boot/dts/imx6sx-19x19-arm2-ldo.dts b/arch/arm/boot/dts/imx6sx-19x19-arm2-ldo.dts
new file mode 100644
index 000000000000..b7aeaca70e4a
--- /dev/null
+++ b/arch/arm/boot/dts/imx6sx-19x19-arm2-ldo.dts
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2015 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 "imx6sx-19x19-arm2.dts"
+
+&gpc {
+ fsl,ldo-bypass = <0>; /* use ldo-enable, u-boot will check it and configure */
+};
+
+&reg_arm {
+ /delete-property/ vin-supply;
+};
+
+&reg_soc {
+ /delete-property/ vin-supply;
+};
diff --git a/arch/arm/boot/dts/imx6sx-19x19-arm2.dts b/arch/arm/boot/dts/imx6sx-19x19-arm2.dts
new file mode 100644
index 000000000000..f1d3207d22f8
--- /dev/null
+++ b/arch/arm/boot/dts/imx6sx-19x19-arm2.dts
@@ -0,0 +1,1261 @@
+/*
+ * Copyright (C) 2014 Freescale Semiconductor, Inc.
+ * Copyright 2017 NXP.
+ *
+ * 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 19x19 ARM2 Board";
+ compatible = "fsl,imx6sx-19x19-arm2", "fsl,imx6sx";
+
+ backlight {
+ compatible = "pwm-backlight";
+ pwms = <&pwm3 0 5000000>;
+ brightness-levels = <0 4 8 16 32 64 128 255>;
+ default-brightness-level = <6>;
+ };
+
+ hannstar_cabc {
+ compatible = "hannstar,cabc";
+
+ lvds0 {
+ gpios = <&gpio2 16 GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ clocks {
+ codec_osc: codec_osc {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <12000000>;
+ };
+ };
+
+ max7322_reset: max7322-reset {
+ compatible = "gpio-reset";
+ reset-gpios = <&gpio6 18 GPIO_ACTIVE_LOW>;
+ reset-delay-us = <1>;
+ #reset-cells = <0>;
+ };
+
+ pxp_v4l2_out {
+ compatible = "fsl,imx6sx-pxp-v4l2", "fsl,imx6sl-pxp-v4l2";
+ status = "okay";
+ };
+
+ regulators {
+ compatible = "simple-bus";
+
+ reg_3p3v: 3p3v {
+ compatible = "regulator-fixed";
+ regulator-name = "3P3V";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ reg_usb_otg1_vbus: usb_otg1_vbus {
+ compatible = "regulator-fixed";
+ regulator-name = "usb_otg1_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&gpio1 9 0>;
+ enable-active-high;
+ };
+ };
+
+ memory {
+ reg = <0x80000000 0x40000000>;
+ };
+
+ sound-cs42888 {
+ compatible = "fsl,imx6-sabreauto-cs42888",
+ "fsl,imx-audio-cs42888";
+ model = "imx-cs42888";
+ esai-controller = <&esai>;
+ asrc-controller = <&asrc>;
+ audio-codec = <&cs42888>;
+ };
+};
+
+&esai {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_esai_1>;
+ status = "okay";
+};
+
+&csi1 {
+ status = "okay";
+
+ port {
+ csi1_ep: endpoint {
+ remote-endpoint = <&ov5640_ep>;
+ };
+ };
+};
+
+&csi2 {
+ status = "okay";
+ port {
+ csi2_ep: endpoint {
+ remote-endpoint = <&vadc_ep>;
+ };
+ };
+};
+
+&cpu0 {
+ operating-points = <
+ /* kHz uV */
+ 996000 1275000
+ 792000 1175000
+ 396000 1075000
+ 198000 975000
+ >;
+ fsl,soc-operating-points = <
+ /* ARM kHz SOC uV */
+ 996000 1175000
+ 792000 1175000
+ 396000 1175000
+ 198000 1175000
+ >;
+};
+
+&reg_arm {
+ vin-supply = <&sw1a_reg>;
+ regulator-allow-bypass;
+};
+
+&reg_soc {
+ vin-supply = <&sw1c_reg>;
+ regulator-allow-bypass;
+};
+
+&gpc {
+ fsl,ldo-bypass = <1>;
+};
+
+&fec1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_enet1_1>;
+ phy-mode = "rgmii";
+ phy-handle = <&ethphy1>;
+ pinctrl-assert-gpios = <&max7322_1 0 GPIO_ACTIVE_HIGH>;
+ fsl,magic-packet;
+ status = "okay";
+
+ mdio {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ethphy0: ethernet-phy@0 {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <0>;
+ };
+
+ ethphy1: ethernet-phy@1 {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <1>;
+ };
+ };
+};
+
+&fec2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_enet2_1>;
+ phy-mode = "rgmii";
+ phy-handle = <&ethphy0>;
+ pinctrl-assert-gpios = <&max7322_2 0 GPIO_ACTIVE_HIGH>;
+ fsl,magic-packet;
+ status = "okay";
+};
+
+&i2c1 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c1_1>;
+ status = "okay";
+
+ pmic: pfuze100@08 {
+ compatible = "fsl,pfuze100";
+ reg = <0x08>;
+
+ regulators {
+ sw1a_reg: sw1ab {
+ regulator-min-microvolt = <300000>;
+ regulator-max-microvolt = <1875000>;
+ regulator-boot-on;
+ regulator-always-on;
+ regulator-ramp-delay = <6250>;
+ };
+
+ sw1c_reg: sw1c {
+ regulator-min-microvolt = <300000>;
+ regulator-max-microvolt = <1875000>;
+ regulator-boot-on;
+ regulator-always-on;
+ regulator-ramp-delay = <6250>;
+ };
+
+ sw2_reg: sw2 {
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ sw3a_reg: sw3a {
+ regulator-min-microvolt = <400000>;
+ regulator-max-microvolt = <1975000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ sw3b_reg: sw3b {
+ regulator-min-microvolt = <400000>;
+ regulator-max-microvolt = <1975000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ sw4_reg: sw4 {
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ swbst_reg: swbst {
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5150000>;
+ };
+
+ snvs_reg: vsnvs {
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ vref_reg: vrefddr {
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ vgen1_reg: vgen1 {
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1550000>;
+ };
+
+ vgen2_reg: vgen2 {
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1550000>;
+ };
+
+ vgen3_reg: vgen3 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ vgen4_reg: vgen4 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ vgen5_reg: vgen5 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ vgen6_reg: vgen6 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+ };
+ };
+};
+
+&i2c2 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c2_1>;
+ status = "okay";
+
+ max7322_1: gpio@68 {
+ compatible = "maxim,max7322";
+ reg = <0x68>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ resets = <&max7322_reset>;
+ };
+
+ max7322_2: gpio@69 {
+ compatible = "maxim,max7322";
+ reg = <0x69>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ resets = <&max7322_reset>;
+ };
+
+ ov5640: ov5640@3c {
+ compatible = "ovti,ov5640";
+ reg = <0x3c>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_csi_1>;
+ clocks = <&clks IMX6SX_CLK_CSI>;
+ clock-names = "csi_mclk";
+ AVDD-supply = <&vgen3_reg>; /* 2.8v */
+ DVDD-supply = <&vgen2_reg>; /* 1.5v*/
+ pwn-gpios = <&gpio3 26 1>;
+ rst-gpios = <&gpio3 25 0>;
+ csi_id = <0>;
+ mclk = <24000000>;
+ mclk_source = <0>;
+ status = "disabled";
+ port {
+ ov5640_ep: endpoint {
+ remote-endpoint = <&csi1_ep>;
+ };
+ };
+ };
+};
+
+&i2c3 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c3_1>;
+ status = "okay";
+};
+
+&i2c4 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c4_2>;
+ status = "okay";
+
+ sgtl5000: sgtl5000@0a {
+ compatible = "fsl,sgtl5000";
+ reg = <0x0a>;
+ clocks = <&codec_osc>;
+ VDDA-supply = <&vgen4_reg>;
+ VDDIO-supply = <&reg_3p3v>;
+ };
+
+ cs42888: cs42888@048 {
+ compatible = "cirrus,cs42888";
+ reg = <0x048>;
+ clocks = <&clks IMX6SX_CLK_ESAI_EXTAL>;
+ clock-names = "mclk";
+ VA-supply = <&reg_3p3v>;
+ VD-supply = <&reg_3p3v>;
+ VLS-supply = <&reg_3p3v>;
+ VLC-supply = <&reg_3p3v>;
+ };
+};
+
+&iomuxc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_hog_1>;
+
+ hog {
+ pinctrl_hog_1: hoggrp-1 {
+ fsl,pins = <
+ MX6SX_PAD_SD4_DATA4__GPIO6_IO_18 0x1b0b0
+ MX6SX_PAD_KEY_ROW1__GPIO2_IO_16 0x1b0b0
+ >;
+ };
+ };
+};
+
+&lcdif1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lcdif_dat_0
+ &pinctrl_lcdif_ctrl_0>;
+ display = <&display0>;
+ status = "disabled";
+
+ display0: display {
+ bits-per-pixel = <16>;
+ bus-width = <24>;
+
+ display-timings {
+ native-mode = <&timing0>;
+ timing0: timing0 {
+ clock-frequency = <33500000>;
+ hactive = <800>;
+ vactive = <480>;
+ hback-porch = <89>;
+ hfront-porch = <164>;
+ vback-porch = <23>;
+ vfront-porch = <10>;
+ hsync-len = <10>;
+ vsync-len = <10>;
+ hsync-active = <0>;
+ vsync-active = <0>;
+ de-active = <1>;
+ pixelclk-active = <0>;
+ };
+ };
+ };
+};
+
+&lcdif2 {
+ display = <&display1>;
+ disp-dev = "ldb";
+ status = "okay";
+
+ display1: display {
+ bits-per-pixel = <16>;
+ bus-width = <18>;
+ };
+};
+
+&pwm3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pwm3_0>;
+ status = "okay";
+};
+
+&pxp {
+ status = "okay";
+};
+
+&sai1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_sai1_1>;
+ status = "disabled";
+};
+
+&snvs_poweroff {
+ status = "okay";
+};
+
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart1_1>;
+ status = "okay";
+};
+
+&uart2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart2_1>;
+ status = "okay";
+};
+
+&qspi2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_qspi2_1>;
+ status = "okay";
+ ddrsmp=<2>;
+
+ flash0: n25q256a@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "micron,n25q256a";
+ spi-max-frequency = <29000000>;
+ reg = <0>;
+ };
+
+ flash1: n25q256a@1 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "micron,n25q256a";
+ spi-max-frequency = <29000000>;
+ reg = <1>;
+ };
+};
+
+&usbh {
+ pinctrl-names = "idle", "active";
+ pinctrl-0 = <&pinctrl_usbh_1>;
+ pinctrl-1 = <&pinctrl_usbh_2>;
+ osc-clkgate-delay = <0x3>;
+ pad-supply = <&vgen1_reg>;
+ status = "okay";
+};
+
+&usbotg1 {
+ vbus-supply = <&reg_usb_otg1_vbus>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usbotg1_1>;
+ disable-over-current;
+ srp-disable;
+ hnp-disable;
+ adp-disable;
+ status = "okay";
+};
+
+&usdhc1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usdhc1_1>;
+ bus-width = <4>;
+ keep-power-in-suspend;
+ enable-sdio-wakeup;
+ no-1-8-v;
+ status = "okay";
+};
+
+&weim {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_weim_nor_1 &pinctrl_weim_cs0_1>;
+ #address-cells = <2>;
+ #size-cells = <1>;
+ ranges = <0 0 0x50000000 0x08000000>;
+ status = "disabled"; /* pin conflict with qspi, nand and lcd1 */
+
+ nor@0,0 {
+ compatible = "cfi-flash";
+ reg = <0 0 0x02000000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ bank-width = <2>;
+ fsl,weim-cs-timing = <0x00610081 0x00000001 0x1c022000
+ 0x0000c000 0x1404a38e 0x00000000>;
+ };
+};
+
+&vadc {
+ vadc_in = <0>;
+ csi_id = <1>;
+ status = "okay";
+ port {
+ vadc_ep: endpoint {
+ remote-endpoint = <&csi2_ep>;
+ };
+ };
+};
+
+&wdog1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_wdog>;
+ fsl,ext-reset-output;
+};
+
+&iomuxc {
+ audmux {
+ pinctrl_audmux_1: audmuxgrp-1 {
+ fsl,pins = <
+ MX6SX_PAD_CSI_DATA00__AUDMUX_AUD6_TXC 0x130B0
+ MX6SX_PAD_CSI_DATA01__AUDMUX_AUD6_TXFS 0x130B0
+ MX6SX_PAD_CSI_HSYNC__AUDMUX_AUD6_TXD 0x120B0
+ MX6SX_PAD_CSI_VSYNC__AUDMUX_AUD6_RXD 0x130B0
+ MX6SX_PAD_CSI_PIXCLK__AUDMUX_MCLK 0x130B0
+ >;
+ };
+
+ pinctrl_audmux_2: audmuxgrp-2 {
+ fsl,pins = <
+ MX6SX_PAD_ENET1_COL__AUDMUX_AUD4_TXC 0x130b0
+ MX6SX_PAD_ENET1_CRS__AUDMUX_AUD4_TXD 0x130b0
+ MX6SX_PAD_ENET1_RX_CLK__AUDMUX_AUD4_TXFS 0x130b0
+ MX6SX_PAD_ENET1_TX_CLK__AUDMUX_AUD4_RXD 0x130b0
+ >;
+ };
+ };
+
+ ecspi4 {
+ pinctrl_ecspi4_cs_1: ecspi4_cs_grp-1 {
+ fsl,pins = <
+ MX6SX_PAD_SD3_DATA2__GPIO7_IO_4 0x80000000
+ >;
+ };
+
+ pinctrl_ecspi4_1: ecspi4grp-1 {
+ fsl,pins = <
+ MX6SX_PAD_SD3_DATA3__ECSPI4_MISO 0x100b1
+ MX6SX_PAD_SD3_CMD__ECSPI4_MOSI 0x100b1
+ MX6SX_PAD_SD3_CLK__ECSPI4_SCLK 0x100b1
+ >;
+ };
+ };
+
+ canfd1 {
+ pinctrl_canfd1_1: canfd1grp-1 {
+ fsl,pins = <
+ MX6SX_PAD_QSPI1B_DQS__CANFD_TX1 0x1b0b0
+ MX6SX_PAD_QSPI1A_SS1_B__CANFD_RX1 0x1b0b0
+ >;
+ };
+ };
+
+ canfd2 {
+ pinctrl_canfd2_1: canfd2grp-1 {
+ fsl,pins = <
+ MX6SX_PAD_QSPI1B_SS1_B__CANFD_RX2 0x1b0b0
+ MX6SX_PAD_QSPI1A_DQS__CANFD_TX2 0x1b0b0
+ >;
+ };
+ };
+
+ csi {
+ pinctrl_csi_0: csigrp-0 {
+ fsl,pins = <
+ MX6SX_PAD_LCD1_DATA07__CSI1_MCLK 0x110b0
+ MX6SX_PAD_LCD1_DATA06__CSI1_PIXCLK 0x110b0
+ MX6SX_PAD_LCD1_DATA04__CSI1_VSYNC 0x110b0
+ MX6SX_PAD_LCD1_DATA05__CSI1_HSYNC 0x110b0
+ MX6SX_PAD_LCD1_DATA17__CSI1_DATA_0 0x110b0
+ MX6SX_PAD_LCD1_DATA16__CSI1_DATA_1 0x110b0
+ MX6SX_PAD_LCD1_DATA15__CSI1_DATA_2 0x110b0
+ MX6SX_PAD_LCD1_DATA14__CSI1_DATA_3 0x110b0
+ MX6SX_PAD_LCD1_DATA13__CSI1_DATA_4 0x110b0
+ MX6SX_PAD_LCD1_DATA12__CSI1_DATA_5 0x110b0
+ MX6SX_PAD_LCD1_DATA11__CSI1_DATA_6 0x110b0
+ MX6SX_PAD_LCD1_DATA10__CSI1_DATA_7 0x110b0
+ MX6SX_PAD_LCD1_DATA09__CSI1_DATA_8 0x110b0
+ MX6SX_PAD_LCD1_DATA08__CSI1_DATA_9 0x110b0
+ MX6SX_PAD_LCD1_RESET__GPIO3_IO_27 0x80000000
+ MX6SX_PAD_LCD1_VSYNC__GPIO3_IO_28 0x80000000
+ >;
+ };
+
+ pinctrl_csi_1: csigrp-1 {
+ fsl,pins = <
+ MX6SX_PAD_CSI_MCLK__CSI1_MCLK 0x110b0
+ MX6SX_PAD_CSI_PIXCLK__CSI1_PIXCLK 0x110b0
+ MX6SX_PAD_CSI_VSYNC__CSI1_VSYNC 0x110b0
+ MX6SX_PAD_CSI_HSYNC__CSI1_HSYNC 0x110b0
+ MX6SX_PAD_CSI_DATA00__CSI1_DATA_2 0x110b0
+ MX6SX_PAD_CSI_DATA01__CSI1_DATA_3 0x110b0
+ MX6SX_PAD_CSI_DATA02__CSI1_DATA_4 0x110b0
+ MX6SX_PAD_CSI_DATA03__CSI1_DATA_5 0x110b0
+ MX6SX_PAD_CSI_DATA04__CSI1_DATA_6 0x110b0
+ MX6SX_PAD_CSI_DATA05__CSI1_DATA_7 0x110b0
+ MX6SX_PAD_CSI_DATA06__CSI1_DATA_8 0x110b0
+ MX6SX_PAD_CSI_DATA07__CSI1_DATA_9 0x110b0
+
+ MX6SX_PAD_LCD1_ENABLE__GPIO3_IO_25 0x80000000
+ MX6SX_PAD_LCD1_HSYNC__GPIO3_IO_26 0x80000000
+ >;
+ };
+ };
+
+ enet1 {
+ pinctrl_enet1_1: enet1grp-1 {
+ fsl,pins = <
+ MX6SX_PAD_ENET1_MDIO__ENET1_MDIO 0xa0b1
+ MX6SX_PAD_ENET1_MDC__ENET1_MDC 0xa0b1
+ MX6SX_PAD_RGMII1_TXC__ENET1_RGMII_TXC 0xa0b9
+ MX6SX_PAD_RGMII1_TD0__ENET1_TX_DATA_0 0xa0b1
+ MX6SX_PAD_RGMII1_TD1__ENET1_TX_DATA_1 0xa0b1
+ MX6SX_PAD_RGMII1_TD2__ENET1_TX_DATA_2 0xa0b1
+ MX6SX_PAD_RGMII1_TD3__ENET1_TX_DATA_3 0xa0b1
+ MX6SX_PAD_RGMII1_TX_CTL__ENET1_TX_EN 0xa0b1
+ MX6SX_PAD_RGMII1_RXC__ENET1_RX_CLK 0x3081
+ MX6SX_PAD_RGMII1_RD0__ENET1_RX_DATA_0 0x3081
+ MX6SX_PAD_RGMII1_RD1__ENET1_RX_DATA_1 0x3081
+ MX6SX_PAD_RGMII1_RD2__ENET1_RX_DATA_2 0x3081
+ MX6SX_PAD_RGMII1_RD3__ENET1_RX_DATA_3 0x3081
+ MX6SX_PAD_RGMII1_RX_CTL__ENET1_RX_EN 0x3081
+ >;
+ };
+
+ pinctrl_enet1_clkout_1: enet1_clkoutgrp-1 {
+ fsl,pins = <
+ MX6SX_PAD_ENET2_RX_CLK__ENET2_REF_CLK_25M 0x91
+ >;
+ };
+ };
+
+ enet2 {
+ pinctrl_enet2_1: enet2grp-1 {
+ fsl,pins = <
+ MX6SX_PAD_RGMII2_TXC__ENET2_RGMII_TXC 0xa0b9
+ MX6SX_PAD_RGMII2_TD0__ENET2_TX_DATA_0 0xa0b1
+ MX6SX_PAD_RGMII2_TD1__ENET2_TX_DATA_1 0xa0b1
+ MX6SX_PAD_RGMII2_TD2__ENET2_TX_DATA_2 0xa0b1
+ MX6SX_PAD_RGMII2_TD3__ENET2_TX_DATA_3 0xa0b1
+ MX6SX_PAD_RGMII2_TX_CTL__ENET2_TX_EN 0xa0b1
+ MX6SX_PAD_RGMII2_RXC__ENET2_RX_CLK 0x3081
+ MX6SX_PAD_RGMII2_RD0__ENET2_RX_DATA_0 0x3081
+ MX6SX_PAD_RGMII2_RD1__ENET2_RX_DATA_1 0x3081
+ MX6SX_PAD_RGMII2_RD2__ENET2_RX_DATA_2 0x3081
+ MX6SX_PAD_RGMII2_RD3__ENET2_RX_DATA_3 0x3081
+ MX6SX_PAD_RGMII2_RX_CTL__ENET2_RX_EN 0x3081
+ >;
+ };
+ };
+
+ esai {
+ pinctrl_esai_1: esaigrp-1 {
+ fsl,pins = <
+ MX6SX_PAD_CSI_MCLK__ESAI_TX_HF_CLK 0x1b030
+ MX6SX_PAD_CSI_DATA00__ESAI_TX_CLK 0x1b030
+ MX6SX_PAD_CSI_DATA01__ESAI_TX_FS 0x1b030
+ MX6SX_PAD_CSI_HSYNC__ESAI_TX0 0x1b030
+ MX6SX_PAD_CSI_DATA04__ESAI_TX1 0x1b030
+ MX6SX_PAD_CSI_DATA06__ESAI_TX2_RX3 0x1b030
+ MX6SX_PAD_CSI_DATA07__ESAI_TX3_RX2 0x1b030
+ MX6SX_PAD_CSI_DATA02__ESAI_RX_CLK 0x1b030
+ MX6SX_PAD_CSI_DATA03__ESAI_RX_FS 0x1b030
+ MX6SX_PAD_CSI_VSYNC__ESAI_TX5_RX0 0x1b030
+ MX6SX_PAD_CSI_DATA05__ESAI_TX4_RX1 0x1b030
+ >;
+ };
+ };
+
+ flexcan1 {
+ pinctrl_flexcan1_1: flexcan1grp-1 {
+ fsl,pins = <
+ MX6SX_PAD_QSPI1B_DQS__CAN1_TX 0x1b0b0
+ MX6SX_PAD_QSPI1A_SS1_B__CAN1_RX 0x1b0b0
+ >;
+ };
+ };
+
+ flexcan2 {
+ pinctrl_flexcan2_1: flexcan2grp-1 {
+ fsl,pins = <
+ MX6SX_PAD_QSPI1B_SS1_B__CAN2_RX 0x1b0b0
+ MX6SX_PAD_QSPI1A_DQS__CAN2_TX 0x1b0b0
+ >;
+ };
+ };
+
+ gpmi-nand {
+ pinctrl_gpmi_nand_1: gpmi-nand-1 {
+ fsl,pins = <
+ MX6SX_PAD_NAND_CLE__RAWNAND_CLE 0xb0b1
+ MX6SX_PAD_NAND_ALE__RAWNAND_ALE 0xb0b1
+ MX6SX_PAD_NAND_WP_B__RAWNAND_WP_B 0xb0b1
+ MX6SX_PAD_NAND_READY_B__RAWNAND_READY_B 0xb000
+ MX6SX_PAD_NAND_CE0_B__RAWNAND_CE0_B 0xb0b1
+ MX6SX_PAD_NAND_CE1_B__RAWNAND_CE1_B 0xb0b1
+ MX6SX_PAD_NAND_RE_B__RAWNAND_RE_B 0xb0b1
+ MX6SX_PAD_NAND_WE_B__RAWNAND_WE_B 0xb0b1
+ MX6SX_PAD_NAND_DATA00__RAWNAND_DATA00 0xb0b1
+ MX6SX_PAD_NAND_DATA01__RAWNAND_DATA01 0xb0b1
+ MX6SX_PAD_NAND_DATA02__RAWNAND_DATA02 0xb0b1
+ MX6SX_PAD_NAND_DATA03__RAWNAND_DATA03 0xb0b1
+ MX6SX_PAD_NAND_DATA04__RAWNAND_DATA04 0xb0b1
+ MX6SX_PAD_NAND_DATA05__RAWNAND_DATA05 0xb0b1
+ MX6SX_PAD_NAND_DATA06__RAWNAND_DATA06 0xb0b1
+ MX6SX_PAD_NAND_DATA07__RAWNAND_DATA07 0xb0b1
+ >;
+ };
+ };
+
+ i2c1 {
+ pinctrl_i2c1_1: i2c1grp-1 {
+ fsl,pins = <
+ MX6SX_PAD_GPIO1_IO01__I2C1_SDA 0x4001b8b1
+ MX6SX_PAD_GPIO1_IO00__I2C1_SCL 0x4001b8b1
+ >;
+ };
+
+ pinctrl_i2c1_2: i2c1grp-2 {
+ fsl,pins = <
+ MX6SX_PAD_CSI_DATA01__I2C1_SDA 0x4001b8b1
+ MX6SX_PAD_CSI_DATA00__I2C1_SCL 0x4001b8b1
+ >;
+ };
+ };
+
+ i2c2 {
+ pinctrl_i2c2_1: i2c2grp-1 {
+ fsl,pins = <
+ MX6SX_PAD_GPIO1_IO03__I2C2_SDA 0x4001b8b1
+ MX6SX_PAD_GPIO1_IO02__I2C2_SCL 0x4001b8b1
+ >;
+ };
+ };
+
+ i2c3 {
+ pinctrl_i2c3_1: i2c3grp-1 {
+ fsl,pins = <
+ MX6SX_PAD_ENET2_TX_CLK__I2C3_SDA 0x4001b8b1
+ MX6SX_PAD_KEY_COL4__I2C3_SCL 0x4001b8b1
+ >;
+ };
+
+ pinctrl_i2c3_2: i2c3grp-2 {
+ fsl,pins = <
+ MX6SX_PAD_KEY_ROW4__I2C3_SDA 0x4001b8b1
+ MX6SX_PAD_KEY_COL4__I2C3_SCL 0x4001b8b1
+ >;
+ };
+ };
+
+ i2c4 {
+ pinctrl_i2c4_1: i2c4grp-1 {
+ fsl,pins = <
+ MX6SX_PAD_CSI_DATA07__I2C4_SDA 0x4001b8b1
+ MX6SX_PAD_CSI_DATA06__I2C4_SCL 0x4001b8b1
+ >;
+ };
+ pinctrl_i2c4_2: i2c4grp-2 {
+ fsl,pins = <
+ MX6SX_PAD_SD3_DATA1__I2C4_SDA 0x4001b8b1
+ MX6SX_PAD_SD3_DATA0__I2C4_SCL 0x4001b8b1
+ >;
+ };
+ };
+
+ lcdif1 {
+ pinctrl_lcdif_dat_0: lcdifdatgrp-0 {
+ fsl,pins = <
+ MX6SX_PAD_LCD1_DATA00__LCDIF1_DATA_0 0x4001b0b0
+ MX6SX_PAD_LCD1_DATA01__LCDIF1_DATA_1 0x4001b0b0
+ MX6SX_PAD_LCD1_DATA02__LCDIF1_DATA_2 0x4001b0b0
+ MX6SX_PAD_LCD1_DATA03__LCDIF1_DATA_3 0x4001b0b0
+ MX6SX_PAD_LCD1_DATA04__LCDIF1_DATA_4 0x4001b0b0
+ MX6SX_PAD_LCD1_DATA05__LCDIF1_DATA_5 0x4001b0b0
+ MX6SX_PAD_LCD1_DATA06__LCDIF1_DATA_6 0x4001b0b0
+ MX6SX_PAD_LCD1_DATA07__LCDIF1_DATA_7 0x4001b0b0
+ MX6SX_PAD_LCD1_DATA08__LCDIF1_DATA_8 0x4001b0b0
+ MX6SX_PAD_LCD1_DATA09__LCDIF1_DATA_9 0x4001b0b0
+ MX6SX_PAD_LCD1_DATA10__LCDIF1_DATA_10 0x4001b0b0
+ MX6SX_PAD_LCD1_DATA11__LCDIF1_DATA_11 0x4001b0b0
+ MX6SX_PAD_LCD1_DATA12__LCDIF1_DATA_12 0x4001b0b0
+ MX6SX_PAD_LCD1_DATA13__LCDIF1_DATA_13 0x4001b0b0
+ MX6SX_PAD_LCD1_DATA14__LCDIF1_DATA_14 0x4001b0b0
+ MX6SX_PAD_LCD1_DATA15__LCDIF1_DATA_15 0x4001b0b0
+ MX6SX_PAD_LCD1_DATA16__LCDIF1_DATA_16 0x4001b0b0
+ MX6SX_PAD_LCD1_DATA17__LCDIF1_DATA_17 0x4001b0b0
+ MX6SX_PAD_LCD1_DATA18__LCDIF1_DATA_18 0x4001b0b0
+ MX6SX_PAD_LCD1_DATA19__LCDIF1_DATA_19 0x4001b0b0
+ MX6SX_PAD_LCD1_DATA20__LCDIF1_DATA_20 0x4001b0b0
+ MX6SX_PAD_LCD1_DATA21__LCDIF1_DATA_21 0x4001b0b0
+ MX6SX_PAD_LCD1_DATA22__LCDIF1_DATA_22 0x4001b0b0
+ MX6SX_PAD_LCD1_DATA23__LCDIF1_DATA_23 0x4001b0b0
+ >;
+ };
+
+ pinctrl_lcdif_ctrl_0: lcdifctrlgrp-0 {
+ fsl,pins = <
+ MX6SX_PAD_LCD1_CLK__LCDIF1_CLK 0x4001b0b0
+ MX6SX_PAD_LCD1_ENABLE__LCDIF1_ENABLE 0x4001b0b0
+ MX6SX_PAD_LCD1_VSYNC__LCDIF1_VSYNC 0x4001b0b0
+ MX6SX_PAD_LCD1_HSYNC__LCDIF1_HSYNC 0x4001b0b0
+ MX6SX_PAD_LCD1_RESET__GPIO3_IO_27 0x4001b0b0
+ >;
+ };
+ };
+
+ mlb {
+ pinctrl_mlb_1: mlbgrp-1 {
+ fsl,pins = <
+ MX6SX_PAD_SD2_DATA3__MLB_DATA 0x31
+ MX6SX_PAD_SD2_CLK__MLB_SIG 0x31
+ MX6SX_PAD_SD2_CMD__MLB_CLK 0x31
+ >;
+ };
+ };
+
+ mqs {
+ pinctrl_mqs_1: mqsgrp-1 {
+ fsl,pins = <
+ MX6SX_PAD_SD2_CLK__MQS_RIGHT 0x80000000
+ MX6SX_PAD_SD2_CMD__MQS_LEFT 0x80000000
+ >;
+ };
+ };
+
+ pwm3 {
+ pinctrl_pwm3_0: pwm3grp-0 {
+ fsl,pins = <
+ MX6SX_PAD_GPIO1_IO12__PWM3_OUT 0x110b0
+ >;
+ };
+
+ pinctrl_pwm3_1: pwm3grp-1 {
+ fsl,pins = <
+ MX6SX_PAD_SD1_DATA2__PWM3_OUT 0x110b0
+ >;
+ };
+ };
+
+ pwm4 {
+ pinctrl_pwm4_0: pwm4grp-0 {
+ fsl,pins = <
+ MX6SX_PAD_SD1_DATA1__PWM4_OUT 0x110b0
+ >;
+ };
+ };
+
+ qspi2 {
+ pinctrl_qspi2_1: qspi2grp_1 {
+ fsl,pins = <
+ MX6SX_PAD_NAND_WP_B__QSPI2_A_DATA_0 0x70a1
+ MX6SX_PAD_NAND_READY_B__QSPI2_A_DATA_1 0x70a1
+ MX6SX_PAD_NAND_CE0_B__QSPI2_A_DATA_2 0x70a1
+ MX6SX_PAD_NAND_CE1_B__QSPI2_A_DATA_3 0x70a1
+ MX6SX_PAD_NAND_CLE__QSPI2_A_SCLK 0x70a1
+ MX6SX_PAD_NAND_ALE__QSPI2_A_SS0_B 0x70a1
+ MX6SX_PAD_NAND_DATA01__QSPI2_B_DATA_0 0x70a1
+ MX6SX_PAD_NAND_DATA00__QSPI2_B_DATA_1 0x70a1
+ MX6SX_PAD_NAND_WE_B__QSPI2_B_DATA_2 0x70a1
+ MX6SX_PAD_NAND_RE_B__QSPI2_B_DATA_3 0x70a1
+ MX6SX_PAD_NAND_DATA02__QSPI2_B_SCLK 0x70a1
+ MX6SX_PAD_NAND_DATA03__QSPI2_B_SS0_B 0x70a1
+ >;
+ };
+ };
+
+ sai1 {
+ pinctrl_sai1_1: sai1grp_1 {
+ fsl,pins = <
+ MX6SX_PAD_CSI_DATA00__SAI1_TX_BCLK 0x1b030
+ MX6SX_PAD_CSI_DATA01__SAI1_TX_SYNC 0x1b030
+ MX6SX_PAD_CSI_DATA02__SAI1_RX_BCLK 0x1b030
+ MX6SX_PAD_CSI_DATA03__SAI1_RX_SYNC 0x1b030
+ MX6SX_PAD_CSI_HSYNC__SAI1_TX_DATA_0 0x1b030
+ MX6SX_PAD_CSI_VSYNC__SAI1_RX_DATA_0 0x1b030
+ >;
+ };
+
+ pinctrl_sai1_2: sai1grp_2 {
+ fsl,pins = <
+ MX6SX_PAD_CSI_DATA00__SAI1_TX_BCLK 0x130B0
+ MX6SX_PAD_CSI_DATA01__SAI1_TX_SYNC 0x130B0
+ MX6SX_PAD_CSI_HSYNC__SAI1_TX_DATA_0 0x120B0
+ MX6SX_PAD_CSI_VSYNC__SAI1_RX_DATA_0 0x130B0
+ MX6SX_PAD_CSI_PIXCLK__AUDMUX_MCLK 0x130B0
+ >;
+ };
+ };
+
+ sai2 {
+ pinctrl_sai2_1: sai2grp_1 {
+ fsl,pins = <
+ MX6SX_PAD_KEY_COL0__SAI2_TX_BCLK 0x1b030
+ MX6SX_PAD_KEY_COL1__SAI2_TX_SYNC 0x1b030
+ MX6SX_PAD_KEY_ROW0__SAI2_TX_DATA_0 0x1b030
+ MX6SX_PAD_KEY_ROW1__SAI2_RX_DATA_0 0x1b030
+ >;
+ };
+ };
+
+
+ spdif {
+ pinctrl_spdif_1: spdifgrp-1 {
+ fsl,pins = <
+ MX6SX_PAD_ENET1_RX_CLK__SPDIF_OUT 0x1b0b0
+ MX6SX_PAD_ENET2_COL__SPDIF_IN 0x1b0b0
+ >;
+ };
+
+ pinctrl_spdif_2: spdifgrp-2 {
+ fsl,pins = <
+ MX6SX_PAD_SD4_DATA4__SPDIF_OUT 0x1b0b0
+ >;
+ };
+ };
+
+ uart1 {
+ pinctrl_uart1_1: uart1grp-1 {
+ fsl,pins = <
+ MX6SX_PAD_GPIO1_IO04__UART1_TX 0x1b0b1
+ MX6SX_PAD_GPIO1_IO05__UART1_RX 0x1b0b1
+ >;
+ };
+
+ pinctrl_uart1_2: uart1grp-2 {
+ fsl,pins = <
+ MX6SX_PAD_ENET2_COL__UART1_RX 0x1b0b1
+ MX6SX_PAD_ENET2_CRS__UART1_TX 0x1b0b1
+ >;
+ };
+ };
+
+ uart2 {
+ pinctrl_uart2_1: uart2grp-1 {
+ fsl,pins = <
+ MX6SX_PAD_GPIO1_IO07__UART2_RX 0x1b0b1
+ MX6SX_PAD_GPIO1_IO06__UART2_TX 0x1b0b1
+ >;
+ };
+
+ pinctrl_uart2_2: uart2grp-2 {
+ fsl,pins = <
+ MX6SX_PAD_SD1_DATA0__UART2_RX 0x1b0b1
+ MX6SX_PAD_SD1_DATA1__UART2_TX 0x1b0b1
+ >;
+ };
+ };
+
+ uart5 {
+ pinctrl_uart5_1: uart5grp-1 {
+ fsl,pins = <
+ MX6SX_PAD_KEY_ROW3__UART5_RX 0x1b0b1
+ MX6SX_PAD_KEY_COL3__UART5_TX 0x1b0b1
+ MX6SX_PAD_KEY_ROW2__UART5_CTS_B 0x1b0b1
+ MX6SX_PAD_KEY_COL2__UART5_RTS_B 0x1b0b1
+ >;
+ };
+
+ pinctrl_uart5dte_1: uart5dtegrp-1 {
+ fsl,pins = <
+ MX6SX_PAD_KEY_ROW3__UART5_TX 0x1b0b1
+ MX6SX_PAD_KEY_COL3__UART5_RX 0x1b0b1
+ MX6SX_PAD_KEY_ROW2__UART5_RTS_B 0x1b0b1
+ MX6SX_PAD_KEY_COL2__UART5_CTS_B 0x1b0b1
+ >;
+ };
+ };
+
+ usbh {
+ pinctrl_usbh_1: usbhgrp-1 {
+ fsl,pins = <
+ MX6SX_PAD_USB_H_STROBE__USB_H_STROBE 0x40013030
+ MX6SX_PAD_USB_H_DATA__USB_H_DATA 0x40013030
+ >;
+ };
+
+ pinctrl_usbh_2: usbhgrp-2 {
+ fsl,pins = <
+ MX6SX_PAD_USB_H_STROBE__USB_H_STROBE 0x40017030
+ >;
+ };
+ };
+
+ usbotg1 {
+ pinctrl_usbotg1_1: usbotg1grp-1 {
+ fsl,pins = <
+ MX6SX_PAD_GPIO1_IO10__ANATOP_OTG1_ID 0x17059
+ >;
+ };
+
+ pinctrl_usbotg1_2: usbotg1grp-2 {
+ fsl,pins = <
+ MX6SX_PAD_ENET2_COL__ANATOP_OTG1_ID 0x17059
+ >;
+ };
+
+ pinctrl_usbotg1_3: usbotg1grp-3 {
+ fsl,pins = <
+ MX6SX_PAD_QSPI1A_DATA1__ANATOP_OTG1_ID 0x17059
+ >;
+ };
+ };
+
+ usbotg2 {
+ pinctrl_usbotg2_1: usbotg2grp-1 {
+ fsl,pins = <
+ MX6SX_PAD_GPIO1_IO13__ANATOP_OTG2_ID 0x17059
+ >;
+ };
+
+ pinctrl_usbotg2_2: usbotg2grp-2 {
+ fsl,pins = <
+ MX6SX_PAD_ENET2_CRS__ANATOP_OTG2_ID 0x17059
+ >;
+ };
+
+ pinctrl_usbotg2_3: usbotg2grp-3 {
+ fsl,pins = <
+ MX6SX_PAD_QSPI1A_SCLK__ANATOP_OTG2_ID 0x17059
+ >;
+ };
+ };
+
+ usdhc1 {
+ pinctrl_usdhc1_1: usdhc1grp-1 {
+ fsl,pins = <
+ MX6SX_PAD_SD1_CMD__USDHC1_CMD 0x17059
+ MX6SX_PAD_SD1_CLK__USDHC1_CLK 0x10059
+ MX6SX_PAD_SD1_DATA0__USDHC1_DATA0 0x17059
+ MX6SX_PAD_SD1_DATA1__USDHC1_DATA1 0x17059
+ MX6SX_PAD_SD1_DATA2__USDHC1_DATA2 0x17059
+ MX6SX_PAD_SD1_DATA3__USDHC1_DATA3 0x17059
+ >;
+ };
+ };
+
+ usdhc2 {
+ pinctrl_usdhc2_1: usdhc2grp-1 {
+ fsl,pins = <
+ MX6SX_PAD_SD2_CMD__USDHC2_CMD 0x17059
+ MX6SX_PAD_SD2_CLK__USDHC2_CLK 0x10059
+ MX6SX_PAD_SD2_DATA0__USDHC2_DATA0 0x17059
+ MX6SX_PAD_SD2_DATA1__USDHC2_DATA1 0x17059
+ MX6SX_PAD_SD2_DATA2__USDHC2_DATA2 0x17059
+ MX6SX_PAD_SD2_DATA3__USDHC2_DATA3 0x17059
+ >;
+ };
+ };
+
+ usdhc3 {
+ pinctrl_usdhc3_1: usdhc3grp-1 {
+ 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
+ >;
+ };
+
+ pinctrl_usdhc3_1_100mhz: usdhc3grp-1-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_1_200mhz: usdhc3grp-1-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
+ >;
+ };
+
+ };
+
+ usdhc4 {
+ pinctrl_usdhc4_1: usdhc4grp-1 {
+ 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_DATA4__USDHC4_DATA4 0x17059
+ MX6SX_PAD_SD4_DATA5__USDHC4_DATA5 0x17059
+ MX6SX_PAD_SD4_DATA6__USDHC4_DATA6 0x17059
+ MX6SX_PAD_SD4_DATA7__USDHC4_DATA7 0x17059
+ >;
+ };
+
+ pinctrl_usdhc4_1_100mhz: usdhc4grp-1-100mhz {
+ fsl,pins = <
+ MX6SX_PAD_SD4_CMD__USDHC4_CMD 0x170b9
+ MX6SX_PAD_SD4_CLK__USDHC4_CLK 0x100b9
+ MX6SX_PAD_SD4_DATA0__USDHC4_DATA0 0x170b9
+ MX6SX_PAD_SD4_DATA1__USDHC4_DATA1 0x170b9
+ MX6SX_PAD_SD4_DATA2__USDHC4_DATA2 0x170b9
+ MX6SX_PAD_SD4_DATA3__USDHC4_DATA3 0x170b9
+ MX6SX_PAD_SD4_DATA4__USDHC4_DATA4 0x170b9
+ MX6SX_PAD_SD4_DATA5__USDHC4_DATA5 0x170b9
+ MX6SX_PAD_SD4_DATA6__USDHC4_DATA6 0x170b9
+ MX6SX_PAD_SD4_DATA7__USDHC4_DATA7 0x170b9
+ >;
+ };
+
+ pinctrl_usdhc4_1_200mhz: usdhc4grp-1-200mhz {
+ fsl,pins = <
+ MX6SX_PAD_SD4_CMD__USDHC4_CMD 0x170f9
+ MX6SX_PAD_SD4_CLK__USDHC4_CLK 0x100f9
+ MX6SX_PAD_SD4_DATA0__USDHC4_DATA0 0x170f9
+ MX6SX_PAD_SD4_DATA1__USDHC4_DATA1 0x170f9
+ MX6SX_PAD_SD4_DATA2__USDHC4_DATA2 0x170f9
+ MX6SX_PAD_SD4_DATA3__USDHC4_DATA3 0x170f9
+ MX6SX_PAD_SD4_DATA4__USDHC4_DATA4 0x170f9
+ MX6SX_PAD_SD4_DATA5__USDHC4_DATA5 0x170f9
+ MX6SX_PAD_SD4_DATA6__USDHC4_DATA6 0x170f9
+ MX6SX_PAD_SD4_DATA7__USDHC4_DATA7 0x170f9
+ >;
+ };
+
+ pinctrl_usdhc4_2: usdhc4grp-2 {
+ 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
+ >;
+ };
+
+ };
+
+ wdog {
+ pinctrl_wdog: wdoggrp {
+ fsl,pins = <
+ MX6SX_PAD_GPIO1_IO13__WDOG1_WDOG_ANY 0x10b0
+ >;
+ };
+ };
+
+ weim {
+ pinctrl_weim_cs0_1: weim_cs0grp-1 {
+ fsl,pins = <
+ MX6SX_PAD_NAND_ALE__WEIM_CS0_B 0xb0b1
+ >;
+ };
+
+ pinctrl_weim_nor_1: weim_norgrp-1 {
+ fsl,pins = <
+ MX6SX_PAD_NAND_CE1_B__WEIM_OE 0xb0b1
+ MX6SX_PAD_NAND_RE_B__WEIM_RW 0xb0b1
+ MX6SX_PAD_NAND_WE_B__WEIM_WAIT 0xb060
+ /* data */
+ MX6SX_PAD_QSPI1A_SCLK__WEIM_DATA_0 0x1b0b0
+ MX6SX_PAD_QSPI1A_SS0_B__WEIM_DATA_1 0x1b0b0
+ MX6SX_PAD_QSPI1A_SS1_B__WEIM_DATA_2 0x1b0b0
+ MX6SX_PAD_QSPI1A_DATA3__WEIM_DATA_3 0x1b0b0
+ MX6SX_PAD_QSPI1A_DATA2__WEIM_DATA_4 0x1b0b0
+ MX6SX_PAD_QSPI1A_DATA1__WEIM_DATA_5 0x1b0b0
+ MX6SX_PAD_QSPI1A_DATA0__WEIM_DATA_6 0x1b0b0
+ MX6SX_PAD_QSPI1A_DQS__WEIM_DATA_7 0x1b0b0
+ MX6SX_PAD_QSPI1B_SCLK__WEIM_DATA_8 0x1b0b0
+ MX6SX_PAD_QSPI1B_SS0_B__WEIM_DATA_9 0x1b0b0
+ MX6SX_PAD_QSPI1B_SS1_B__WEIM_DATA_10 0x1b0b0
+ MX6SX_PAD_QSPI1B_DATA3__WEIM_DATA_11 0x1b0b0
+ MX6SX_PAD_QSPI1B_DATA2__WEIM_DATA_12 0x1b0b0
+ MX6SX_PAD_QSPI1B_DATA1__WEIM_DATA_13 0x1b0b0
+ MX6SX_PAD_QSPI1B_DATA0__WEIM_DATA_14 0x1b0b0
+ MX6SX_PAD_QSPI1B_DQS__WEIM_DATA_15 0x1b0b0
+ /* address */
+ MX6SX_PAD_NAND_DATA00__WEIM_AD_0 0xb0b1
+ MX6SX_PAD_NAND_DATA01__WEIM_AD_1 0xb0b1
+ MX6SX_PAD_NAND_DATA02__WEIM_AD_2 0xb0b1
+ MX6SX_PAD_NAND_DATA03__WEIM_AD_3 0xb0b1
+ MX6SX_PAD_NAND_DATA04__WEIM_AD_4 0xb0b1
+ MX6SX_PAD_NAND_DATA05__WEIM_AD_5 0xb0b1
+ MX6SX_PAD_NAND_DATA06__WEIM_AD_6 0xb0b1
+ MX6SX_PAD_NAND_DATA07__WEIM_AD_7 0xb0b1
+ MX6SX_PAD_LCD1_DATA08__WEIM_AD_8 0xb0b1
+ MX6SX_PAD_LCD1_DATA09__WEIM_AD_9 0xb0b1
+ MX6SX_PAD_LCD1_DATA10__WEIM_AD_10 0xb0b1
+ MX6SX_PAD_LCD1_DATA11__WEIM_AD_11 0xb0b1
+ MX6SX_PAD_LCD1_DATA12__WEIM_AD_12 0xb0b1
+ MX6SX_PAD_LCD1_DATA13__WEIM_AD_13 0xb0b1
+ MX6SX_PAD_LCD1_DATA14__WEIM_AD_14 0xb0b1
+ MX6SX_PAD_LCD1_DATA15__WEIM_AD_15 0xb0b1
+ MX6SX_PAD_LCD1_DATA16__WEIM_ADDR_16 0xb0b1
+ MX6SX_PAD_LCD1_DATA17__WEIM_ADDR_17 0xb0b1
+ MX6SX_PAD_LCD1_DATA18__WEIM_ADDR_18 0xb0b1
+ MX6SX_PAD_LCD1_DATA19__WEIM_ADDR_19 0xb0b1
+ MX6SX_PAD_LCD1_DATA20__WEIM_ADDR_20 0xb0b1
+ MX6SX_PAD_LCD1_DATA21__WEIM_ADDR_21 0xb0b1
+ MX6SX_PAD_LCD1_DATA22__WEIM_ADDR_22 0xb0b1
+ MX6SX_PAD_LCD1_DATA03__WEIM_ADDR_24 0xb0b1
+ MX6SX_PAD_LCD1_DATA04__WEIM_ADDR_25 0xb0b1
+ MX6SX_PAD_LCD1_DATA05__WEIM_ADDR_26 0xb0b1
+ >;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/imx6sx-pinfunc.h b/arch/arm/boot/dts/imx6sx-pinfunc.h
index 42c4c800feea..5a989206f333 100644
--- a/arch/arm/boot/dts/imx6sx-pinfunc.h
+++ b/arch/arm/boot/dts/imx6sx-pinfunc.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2014 Freescale Semiconductor, Inc.
+ * 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
@@ -70,6 +70,7 @@
#define MX6SX_PAD_GPIO1_IO06__ENET2_MDC 0x002C 0x0374 0x0000 0x2 0x0
#define MX6SX_PAD_GPIO1_IO06__CSI1_MCLK 0x002C 0x0374 0x0000 0x3 0x0
#define MX6SX_PAD_GPIO1_IO06__UART1_RTS_B 0x002C 0x0374 0x082C 0x4 0x0
+#define MX6SX_PAD_GPIO1_IO06__UART1_CTS_B 0x002C 0x0374 0x0000 0x4 0x0
#define MX6SX_PAD_GPIO1_IO06__GPIO1_IO_6 0x002C 0x0374 0x0000 0x5 0x0
#define MX6SX_PAD_GPIO1_IO06__SRC_ANY_PU_RESET 0x002C 0x0374 0x0000 0x6 0x0
#define MX6SX_PAD_GPIO1_IO06__OCOTP_CTRL_WRAPPER_FUSE_LATCHED 0x002C 0x0374 0x0000 0x7 0x0
@@ -79,6 +80,7 @@
#define MX6SX_PAD_GPIO1_IO07__ENET2_MDIO 0x0030 0x0378 0x0770 0x2 0x0
#define MX6SX_PAD_GPIO1_IO07__AUDMUX_MCLK 0x0030 0x0378 0x0000 0x3 0x0
#define MX6SX_PAD_GPIO1_IO07__UART1_CTS_B 0x0030 0x0378 0x0000 0x4 0x0
+#define MX6SX_PAD_GPIO1_IO07__UART1_RTS_B 0x0030 0x0378 0x082C 0x4 0x1
#define MX6SX_PAD_GPIO1_IO07__GPIO1_IO_7 0x0030 0x0378 0x0000 0x5 0x0
#define MX6SX_PAD_GPIO1_IO07__SRC_EARLY_RESET 0x0030 0x0378 0x0000 0x6 0x0
#define MX6SX_PAD_GPIO1_IO07__DCIC2_OUT 0x0030 0x0378 0x0000 0x7 0x0
@@ -88,6 +90,7 @@
#define MX6SX_PAD_GPIO1_IO08__SDMA_EXT_EVENT_0 0x0034 0x037C 0x081C 0x2 0x0
#define MX6SX_PAD_GPIO1_IO08__CCM_PMIC_RDY 0x0034 0x037C 0x069C 0x3 0x1
#define MX6SX_PAD_GPIO1_IO08__UART2_RTS_B 0x0034 0x037C 0x0834 0x4 0x0
+#define MX6SX_PAD_GPIO1_IO08__UART2_CTS_B 0x0034 0x037C 0x0000 0x4 0x0
#define MX6SX_PAD_GPIO1_IO08__GPIO1_IO_8 0x0034 0x037C 0x0000 0x5 0x0
#define MX6SX_PAD_GPIO1_IO08__SRC_SYSTEM_RESET 0x0034 0x037C 0x0000 0x6 0x0
#define MX6SX_PAD_GPIO1_IO08__DCIC1_OUT 0x0034 0x037C 0x0000 0x7 0x0
@@ -97,6 +100,7 @@
#define MX6SX_PAD_GPIO1_IO09__SDMA_EXT_EVENT_1 0x0038 0x0380 0x0820 0x2 0x0
#define MX6SX_PAD_GPIO1_IO09__CCM_OUT0 0x0038 0x0380 0x0000 0x3 0x0
#define MX6SX_PAD_GPIO1_IO09__UART2_CTS_B 0x0038 0x0380 0x0000 0x4 0x0
+#define MX6SX_PAD_GPIO1_IO09__UART2_RTS_B 0x0038 0x0380 0x0834 0x4 0x1
#define MX6SX_PAD_GPIO1_IO09__GPIO1_IO_9 0x0038 0x0380 0x0000 0x5 0x0
#define MX6SX_PAD_GPIO1_IO09__SRC_INT_BOOT 0x0038 0x0380 0x0000 0x6 0x0
#define MX6SX_PAD_GPIO1_IO09__OBSERVE_MUX_OUT_4 0x0038 0x0380 0x0000 0x7 0x0
@@ -204,6 +208,7 @@
#define MX6SX_PAD_CSI_DATA06__I2C4_SCL 0x0064 0x03AC 0x07C0 0x2 0x2
#define MX6SX_PAD_CSI_DATA06__KPP_COL_7 0x0064 0x03AC 0x07D0 0x3 0x0
#define MX6SX_PAD_CSI_DATA06__UART6_RTS_B 0x0064 0x03AC 0x0854 0x4 0x0
+#define MX6SX_PAD_CSI_DATA06__UART6_CTS_B 0x0064 0x03AC 0x0000 0x4 0x0
#define MX6SX_PAD_CSI_DATA06__GPIO1_IO_20 0x0064 0x03AC 0x0000 0x5 0x0
#define MX6SX_PAD_CSI_DATA06__WEIM_DATA_17 0x0064 0x03AC 0x0000 0x6 0x0
#define MX6SX_PAD_CSI_DATA06__DCIC2_OUT 0x0064 0x03AC 0x0000 0x7 0x0
@@ -214,6 +219,7 @@
#define MX6SX_PAD_CSI_DATA07__I2C4_SDA 0x0068 0x03B0 0x07C4 0x2 0x2
#define MX6SX_PAD_CSI_DATA07__KPP_ROW_7 0x0068 0x03B0 0x07DC 0x3 0x0
#define MX6SX_PAD_CSI_DATA07__UART6_CTS_B 0x0068 0x03B0 0x0000 0x4 0x0
+#define MX6SX_PAD_CSI_DATA07__UART6_RTS_B 0x0068 0x03B0 0x0854 0x4 0x1
#define MX6SX_PAD_CSI_DATA07__GPIO1_IO_21 0x0068 0x03B0 0x0000 0x5 0x0
#define MX6SX_PAD_CSI_DATA07__WEIM_DATA_16 0x0068 0x03B0 0x0000 0x6 0x0
#define MX6SX_PAD_CSI_DATA07__DCIC1_OUT 0x0068 0x03B0 0x0000 0x7 0x0
@@ -223,6 +229,7 @@
#define MX6SX_PAD_CSI_HSYNC__ESAI_TX0 0x006C 0x03B4 0x0790 0x1 0x1
#define MX6SX_PAD_CSI_HSYNC__AUDMUX_AUD6_TXD 0x006C 0x03B4 0x0678 0x2 0x1
#define MX6SX_PAD_CSI_HSYNC__UART4_RTS_B 0x006C 0x03B4 0x0844 0x3 0x2
+#define MX6SX_PAD_CSI_HSYNC__UART4_CTS_B 0x006C 0x03B4 0x0000 0x3 0x0
#define MX6SX_PAD_CSI_HSYNC__MQS_LEFT 0x006C 0x03B4 0x0000 0x4 0x0
#define MX6SX_PAD_CSI_HSYNC__GPIO1_IO_22 0x006C 0x03B4 0x0000 0x5 0x0
#define MX6SX_PAD_CSI_HSYNC__WEIM_DATA_25 0x006C 0x03B4 0x0000 0x6 0x0
@@ -255,6 +262,7 @@
#define MX6SX_PAD_CSI_VSYNC__ESAI_TX5_RX0 0x0078 0x03C0 0x07A4 0x1 0x1
#define MX6SX_PAD_CSI_VSYNC__AUDMUX_AUD6_RXD 0x0078 0x03C0 0x0674 0x2 0x1
#define MX6SX_PAD_CSI_VSYNC__UART4_CTS_B 0x0078 0x03C0 0x0000 0x3 0x0
+#define MX6SX_PAD_CSI_VSYNC__UART4_RTS_B 0x0078 0x03C0 0x0844 0x3 0x3
#define MX6SX_PAD_CSI_VSYNC__MQS_RIGHT 0x0078 0x03C0 0x0000 0x4 0x0
#define MX6SX_PAD_CSI_VSYNC__GPIO1_IO_25 0x0078 0x03C0 0x0000 0x5 0x0
#define MX6SX_PAD_CSI_VSYNC__WEIM_DATA_24 0x0078 0x03C0 0x0000 0x6 0x0
@@ -357,6 +365,7 @@
#define MX6SX_PAD_ENET2_RX_CLK__ENET2_REF_CLK_25M 0x009C 0x03E4 0x0000 0x1 0x0
#define MX6SX_PAD_ENET2_RX_CLK__I2C3_SCL 0x009C 0x03E4 0x07B8 0x2 0x1
#define MX6SX_PAD_ENET2_RX_CLK__UART1_RTS_B 0x009C 0x03E4 0x082C 0x3 0x2
+#define MX6SX_PAD_ENET2_RX_CLK__UART1_CTS_B 0x009C 0x03E4 0x0000 0x3 0x0
#define MX6SX_PAD_ENET2_RX_CLK__MLB_DATA 0x009C 0x03E4 0x07EC 0x4 0x1
#define MX6SX_PAD_ENET2_RX_CLK__GPIO2_IO_8 0x009C 0x03E4 0x0000 0x5 0x0
#define MX6SX_PAD_ENET2_RX_CLK__USB_OTG2_OC 0x009C 0x03E4 0x085C 0x6 0x1
@@ -367,6 +376,7 @@
#define MX6SX_PAD_ENET2_TX_CLK__ENET2_REF_CLK2 0x00A0 0x03E8 0x076C 0x1 0x1
#define MX6SX_PAD_ENET2_TX_CLK__I2C3_SDA 0x00A0 0x03E8 0x07BC 0x2 0x1
#define MX6SX_PAD_ENET2_TX_CLK__UART1_CTS_B 0x00A0 0x03E8 0x0000 0x3 0x0
+#define MX6SX_PAD_ENET2_TX_CLK__UART1_RTS_B 0x00A0 0x03E8 0x082C 0x3 0x3
#define MX6SX_PAD_ENET2_TX_CLK__MLB_CLK 0x00A0 0x03E8 0x07E8 0x4 0x1
#define MX6SX_PAD_ENET2_TX_CLK__GPIO2_IO_9 0x00A0 0x03E8 0x0000 0x5 0x0
#define MX6SX_PAD_ENET2_TX_CLK__USB_OTG2_PWR 0x00A0 0x03E8 0x0000 0x6 0x0
@@ -376,6 +386,7 @@
#define MX6SX_PAD_KEY_COL0__KPP_COL_0 0x00A4 0x03EC 0x0000 0x0 0x0
#define MX6SX_PAD_KEY_COL0__USDHC3_CD_B 0x00A4 0x03EC 0x0000 0x1 0x0
#define MX6SX_PAD_KEY_COL0__UART6_RTS_B 0x00A4 0x03EC 0x0854 0x2 0x2
+#define MX6SX_PAD_KEY_COL0__UART6_CTS_B 0x00A4 0x03EC 0x0000 0x2 0x0
#define MX6SX_PAD_KEY_COL0__ECSPI1_SCLK 0x00A4 0x03EC 0x0710 0x3 0x0
#define MX6SX_PAD_KEY_COL0__AUDMUX_AUD5_TXC 0x00A4 0x03EC 0x066C 0x4 0x0
#define MX6SX_PAD_KEY_COL0__GPIO2_IO_10 0x00A4 0x03EC 0x0000 0x5 0x0
@@ -394,6 +405,7 @@
#define MX6SX_PAD_KEY_COL2__KPP_COL_2 0x00AC 0x03F4 0x0000 0x0 0x0
#define MX6SX_PAD_KEY_COL2__USDHC4_CD_B 0x00AC 0x03F4 0x0874 0x1 0x1
#define MX6SX_PAD_KEY_COL2__UART5_RTS_B 0x00AC 0x03F4 0x084C 0x2 0x2
+#define MX6SX_PAD_KEY_COL2__UART5_CTS_B 0x00AC 0x03F4 0x0000 0x2 0x0
#define MX6SX_PAD_KEY_COL2__CAN1_TX 0x00AC 0x03F4 0x0000 0x3 0x0
#define MX6SX_PAD_KEY_COL2__CANFD_TX1 0x00AC 0x03F4 0x0000 0x4 0x0
#define MX6SX_PAD_KEY_COL2__GPIO2_IO_12 0x00AC 0x03F4 0x0000 0x5 0x0
@@ -419,6 +431,7 @@
#define MX6SX_PAD_KEY_ROW0__KPP_ROW_0 0x00B8 0x0400 0x0000 0x0 0x0
#define MX6SX_PAD_KEY_ROW0__USDHC3_WP 0x00B8 0x0400 0x0000 0x1 0x0
#define MX6SX_PAD_KEY_ROW0__UART6_CTS_B 0x00B8 0x0400 0x0000 0x2 0x0
+#define MX6SX_PAD_KEY_ROW0__UART6_RTS_B 0x00B8 0x0400 0x0854 0x2 0x3
#define MX6SX_PAD_KEY_ROW0__ECSPI1_MOSI 0x00B8 0x0400 0x0718 0x3 0x0
#define MX6SX_PAD_KEY_ROW0__AUDMUX_AUD5_TXD 0x00B8 0x0400 0x0660 0x4 0x0
#define MX6SX_PAD_KEY_ROW0__GPIO2_IO_15 0x00B8 0x0400 0x0000 0x5 0x0
@@ -438,6 +451,7 @@
#define MX6SX_PAD_KEY_ROW2__KPP_ROW_2 0x00C0 0x0408 0x0000 0x0 0x0
#define MX6SX_PAD_KEY_ROW2__USDHC4_WP 0x00C0 0x0408 0x0878 0x1 0x1
#define MX6SX_PAD_KEY_ROW2__UART5_CTS_B 0x00C0 0x0408 0x0000 0x2 0x0
+#define MX6SX_PAD_KEY_ROW2__UART5_RTS_B 0x00C0 0x0408 0x084C 0x2 0x3
#define MX6SX_PAD_KEY_ROW2__CAN1_RX 0x00C0 0x0408 0x068C 0x3 0x1
#define MX6SX_PAD_KEY_ROW2__CANFD_RX1 0x00C0 0x0408 0x0694 0x4 0x1
#define MX6SX_PAD_KEY_ROW2__GPIO2_IO_17 0x00C0 0x0408 0x0000 0x5 0x0
@@ -820,6 +834,7 @@
#define MX6SX_PAD_NAND_DATA04__USDHC2_DATA4 0x0160 0x04A8 0x0000 0x1 0x0
#define MX6SX_PAD_NAND_DATA04__QSPI2_B_SS1_B 0x0160 0x04A8 0x0000 0x2 0x0
#define MX6SX_PAD_NAND_DATA04__UART3_RTS_B 0x0160 0x04A8 0x083C 0x3 0x0
+#define MX6SX_PAD_NAND_DATA04__UART3_CTS_B 0x0160 0x04A8 0x0000 0x3 0x0
#define MX6SX_PAD_NAND_DATA04__AUDMUX_AUD4_RXFS 0x0160 0x04A8 0x0650 0x4 0x0
#define MX6SX_PAD_NAND_DATA04__GPIO4_IO_8 0x0160 0x04A8 0x0000 0x5 0x0
#define MX6SX_PAD_NAND_DATA04__WEIM_AD_4 0x0160 0x04A8 0x0000 0x6 0x0
@@ -830,6 +845,7 @@
#define MX6SX_PAD_NAND_DATA05__USDHC2_DATA5 0x0164 0x04AC 0x0000 0x1 0x0
#define MX6SX_PAD_NAND_DATA05__QSPI2_B_DQS 0x0164 0x04AC 0x0000 0x2 0x0
#define MX6SX_PAD_NAND_DATA05__UART3_CTS_B 0x0164 0x04AC 0x0000 0x3 0x0
+#define MX6SX_PAD_NAND_DATA05__UART3_RTS_B 0x0164 0x04AC 0x083C 0x3 0x1
#define MX6SX_PAD_NAND_DATA05__AUDMUX_AUD4_RXC 0x0164 0x04AC 0x064C 0x4 0x0
#define MX6SX_PAD_NAND_DATA05__GPIO4_IO_9 0x0164 0x04AC 0x0000 0x5 0x0
#define MX6SX_PAD_NAND_DATA05__WEIM_AD_5 0x0164 0x04AC 0x0000 0x6 0x0
@@ -972,6 +988,7 @@
#define MX6SX_PAD_QSPI1A_SS1_B__SDMA_DEBUG_PC_3 0x019C 0x04E4 0x0000 0x9 0x0
#define MX6SX_PAD_QSPI1B_DATA0__QSPI1_B_DATA_0 0x01A0 0x04E8 0x0000 0x0 0x0
#define MX6SX_PAD_QSPI1B_DATA0__UART3_CTS_B 0x01A0 0x04E8 0x0000 0x1 0x0
+#define MX6SX_PAD_QSPI1B_DATA0__UART3_RTS_B 0x01A0 0x04E8 0x083C 0x1 0x4
#define MX6SX_PAD_QSPI1B_DATA0__ECSPI3_MOSI 0x01A0 0x04E8 0x0738 0x2 0x1
#define MX6SX_PAD_QSPI1B_DATA0__ESAI_RX_FS 0x01A0 0x04E8 0x0778 0x3 0x2
#define MX6SX_PAD_QSPI1B_DATA0__CSI1_DATA_22 0x01A0 0x04E8 0x06F4 0x4 0x1
@@ -980,6 +997,7 @@
#define MX6SX_PAD_QSPI1B_DATA0__SIM_M_HADDR_9 0x01A0 0x04E8 0x0000 0x7 0x0
#define MX6SX_PAD_QSPI1B_DATA1__QSPI1_B_DATA_1 0x01A4 0x04EC 0x0000 0x0 0x0
#define MX6SX_PAD_QSPI1B_DATA1__UART3_RTS_B 0x01A4 0x04EC 0x083C 0x1 0x5
+#define MX6SX_PAD_QSPI1B_DATA1__UART3_CTS_B 0x01A4 0x04EC 0x0000 0x1 0x0
#define MX6SX_PAD_QSPI1B_DATA1__ECSPI3_MISO 0x01A4 0x04EC 0x0734 0x2 0x1
#define MX6SX_PAD_QSPI1B_DATA1__ESAI_RX_CLK 0x01A4 0x04EC 0x0788 0x3 0x2
#define MX6SX_PAD_QSPI1B_DATA1__CSI1_DATA_21 0x01A4 0x04EC 0x06F0 0x4 0x1
@@ -1251,6 +1269,7 @@
#define MX6SX_PAD_SD1_DATA2__PWM3_OUT 0x0230 0x0578 0x0000 0x2 0x0
#define MX6SX_PAD_SD1_DATA2__GPT_COMPARE2 0x0230 0x0578 0x0000 0x3 0x0
#define MX6SX_PAD_SD1_DATA2__UART2_CTS_B 0x0230 0x0578 0x0000 0x4 0x0
+#define MX6SX_PAD_SD1_DATA2__UART2_RTS_B 0x0230 0x0578 0x0834 0x4 0x2
#define MX6SX_PAD_SD1_DATA2__GPIO6_IO_4 0x0230 0x0578 0x0000 0x5 0x0
#define MX6SX_PAD_SD1_DATA2__ECSPI4_RDY 0x0230 0x0578 0x0000 0x6 0x0
#define MX6SX_PAD_SD1_DATA2__CCM_OUT0 0x0230 0x0578 0x0000 0x7 0x0
@@ -1260,6 +1279,7 @@
#define MX6SX_PAD_SD1_DATA3__AUDMUX_AUD5_RXD 0x0234 0x057C 0x065C 0x2 0x2
#define MX6SX_PAD_SD1_DATA3__GPT_COMPARE3 0x0234 0x057C 0x0000 0x3 0x0
#define MX6SX_PAD_SD1_DATA3__UART2_RTS_B 0x0234 0x057C 0x0834 0x4 0x3
+#define MX6SX_PAD_SD1_DATA3__UART2_CTS_B 0x0234 0x057C 0x0000 0x4 0x0
#define MX6SX_PAD_SD1_DATA3__GPIO6_IO_5 0x0234 0x057C 0x0000 0x5 0x0
#define MX6SX_PAD_SD1_DATA3__ECSPI4_SS1 0x0234 0x057C 0x0000 0x6 0x0
#define MX6SX_PAD_SD1_DATA3__CCM_PMIC_RDY 0x0234 0x057C 0x069C 0x7 0x2
@@ -1330,6 +1350,7 @@
#define MX6SX_PAD_SD2_DATA3__MMDC_DEBUG_31 0x024C 0x0594 0x0000 0x9 0x0
#define MX6SX_PAD_SD3_CLK__USDHC3_CLK 0x0250 0x0598 0x0000 0x0 0x0
#define MX6SX_PAD_SD3_CLK__UART4_CTS_B 0x0250 0x0598 0x0000 0x1 0x0
+#define MX6SX_PAD_SD3_CLK__UART4_RTS_B 0x0250 0x0598 0x0844 0x1 0x0
#define MX6SX_PAD_SD3_CLK__ECSPI4_SCLK 0x0250 0x0598 0x0740 0x2 0x0
#define MX6SX_PAD_SD3_CLK__AUDMUX_AUD6_RXFS 0x0250 0x0598 0x0680 0x3 0x0
#define MX6SX_PAD_SD3_CLK__LCDIF2_VSYNC 0x0250 0x0598 0x0000 0x4 0x0
@@ -1369,6 +1390,7 @@
#define MX6SX_PAD_SD3_DATA1__SDMA_DEBUG_EVT_CHN_LINES_1 0x025C 0x05A4 0x0000 0x9 0x0
#define MX6SX_PAD_SD3_DATA2__USDHC3_DATA2 0x0260 0x05A8 0x0000 0x0 0x0
#define MX6SX_PAD_SD3_DATA2__UART4_RTS_B 0x0260 0x05A8 0x0844 0x1 0x1
+#define MX6SX_PAD_SD3_DATA2__UART4_CTS_B 0x0260 0x05A8 0x0000 0x1 0x0
#define MX6SX_PAD_SD3_DATA2__ECSPI4_SS0 0x0260 0x05A8 0x074C 0x2 0x0
#define MX6SX_PAD_SD3_DATA2__AUDMUX_AUD6_TXFS 0x0260 0x05A8 0x0688 0x3 0x0
#define MX6SX_PAD_SD3_DATA2__LCDIF2_CLK 0x0260 0x05A8 0x0000 0x4 0x0
@@ -1414,6 +1436,7 @@
#define MX6SX_PAD_SD3_DATA6__CAN2_TX 0x0270 0x05B8 0x0000 0x1 0x0
#define MX6SX_PAD_SD3_DATA6__CANFD_TX2 0x0270 0x05B8 0x0000 0x2 0x0
#define MX6SX_PAD_SD3_DATA6__UART3_RTS_B 0x0270 0x05B8 0x083C 0x3 0x2
+#define MX6SX_PAD_SD3_DATA6__UART3_CTS_B 0x0270 0x05B8 0x0000 0x3 0x0
#define MX6SX_PAD_SD3_DATA6__LCDIF2_DATA_4 0x0270 0x05B8 0x0000 0x4 0x0
#define MX6SX_PAD_SD3_DATA6__GPIO7_IO_8 0x0270 0x05B8 0x0000 0x5 0x0
#define MX6SX_PAD_SD3_DATA6__ENET1_1588_EVENT0_OUT 0x0270 0x05B8 0x0000 0x6 0x0
@@ -1424,6 +1447,7 @@
#define MX6SX_PAD_SD3_DATA7__CAN1_RX 0x0274 0x05BC 0x068C 0x1 0x0
#define MX6SX_PAD_SD3_DATA7__CANFD_RX1 0x0274 0x05BC 0x0694 0x2 0x0
#define MX6SX_PAD_SD3_DATA7__UART3_CTS_B 0x0274 0x05BC 0x0000 0x3 0x0
+#define MX6SX_PAD_SD3_DATA7__UART3_RTS_B 0x0274 0x05BC 0x083C 0x3 0x3
#define MX6SX_PAD_SD3_DATA7__LCDIF2_DATA_5 0x0274 0x05BC 0x0000 0x4 0x0
#define MX6SX_PAD_SD3_DATA7__GPIO7_IO_9 0x0274 0x05BC 0x0000 0x5 0x0
#define MX6SX_PAD_SD3_DATA7__ENET1_1588_EVENT0_IN 0x0274 0x05BC 0x0000 0x6 0x0
@@ -1515,6 +1539,7 @@
#define MX6SX_PAD_SD4_DATA6__USDHC4_DATA6 0x0298 0x05E0 0x0000 0x0 0x0
#define MX6SX_PAD_SD4_DATA6__RAWNAND_CE3_B 0x0298 0x05E0 0x0000 0x1 0x0
#define MX6SX_PAD_SD4_DATA6__UART5_RTS_B 0x0298 0x05E0 0x084C 0x2 0x0
+#define MX6SX_PAD_SD4_DATA6__UART5_CTS_B 0x0298 0x05E0 0x0000 0x2 0x0
#define MX6SX_PAD_SD4_DATA6__ECSPI3_MISO 0x0298 0x05E0 0x0734 0x3 0x0
#define MX6SX_PAD_SD4_DATA6__LCDIF2_DATA_6 0x0298 0x05E0 0x0000 0x4 0x0
#define MX6SX_PAD_SD4_DATA6__GPIO6_IO_20 0x0298 0x05E0 0x0000 0x5 0x0
@@ -1525,6 +1550,7 @@
#define MX6SX_PAD_SD4_DATA7__USDHC4_DATA7 0x029C 0x05E4 0x0000 0x0 0x0
#define MX6SX_PAD_SD4_DATA7__RAWNAND_DATA08 0x029C 0x05E4 0x0000 0x1 0x0
#define MX6SX_PAD_SD4_DATA7__UART5_CTS_B 0x029C 0x05E4 0x0000 0x2 0x0
+#define MX6SX_PAD_SD4_DATA7__UART5_RTS_B 0x029C 0x05E4 0x084C 0x2 0x1
#define MX6SX_PAD_SD4_DATA7__ECSPI3_SS0 0x029C 0x05E4 0x073C 0x3 0x0
#define MX6SX_PAD_SD4_DATA7__LCDIF2_DATA_15 0x029C 0x05E4 0x0000 0x4 0x0
#define MX6SX_PAD_SD4_DATA7__GPIO6_IO_21 0x029C 0x05E4 0x0000 0x5 0x0
diff --git a/arch/arm/boot/dts/imx6sx-sabreauto-m4.dts b/arch/arm/boot/dts/imx6sx-sabreauto-m4.dts
new file mode 100644
index 000000000000..a168992ffdd5
--- /dev/null
+++ b/arch/arm/boot/dts/imx6sx-sabreauto-m4.dts
@@ -0,0 +1,93 @@
+/*
+ * 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 "imx6sx-sabreauto.dts"
+
+/{
+ memory {
+ linux,usable-memory = <0x80000000 0x1ff00000>,
+ <0xa0000000 0x1ff00000>,
+ <0xc0000000 0x40000000>;
+ };
+};
+
+/*
+ * The flollowing modules are conflicting with M4, disable them when m4
+ * is running.
+ */
+&adc1 {
+ status = "disabled";
+};
+
+&adc2 {
+ status = "disabled";
+};
+
+&flexcan1 {
+ status = "disabled";
+};
+
+&flexcan2 {
+ status = "disabled";
+};
+
+&i2c3 {
+ status = "disabled";
+};
+
+&ocram {
+ reg = <0x00901000 0x1E000>;
+};
+
+&ocram {
+ reg = <0x00901000 0xf000>;
+};
+
+&qspi1 {
+ status = "disabled";
+};
+
+&qspi_m4 {
+ reg = <0x021e0000 0x4000>;
+ status = "okay";
+};
+
+&rpmsg{
+ vdev-nums = <1>;
+ reg = <0xbfff0000 0x10000>;
+ status = "okay";
+};
+
+&uart2 {
+ status = "disabled";
+};
+
+&clks {
+ fsl,shared-clks-number = <0x23>;
+ fsl,shared-clks-index = <IMX6SX_CLK_PLL2_BUS IMX6SX_CLK_PLL2_PFD0
+ IMX6SX_CLK_PLL2_PFD2 IMX6SX_CLK_PLL3_USB_OTG
+ IMX6SX_CLK_PLL3_PFD1 IMX6SX_CLK_PLL3_PFD2
+ IMX6SX_CLK_PLL3_PFD3 IMX6SX_CLK_PLL4_AUDIO
+ IMX6SX_CLK_PLL5_VIDEO
+ IMX6SX_CLK_OCRAM IMX6SX_CLK_CAN1_SERIAL
+ IMX6SX_CLK_CAN1_IPG IMX6SX_CLK_CAN2_SERIAL
+ IMX6SX_CLK_CAN2_IPG IMX6SX_CLK_CANFD
+ IMX6SX_CLK_ECSPI1 IMX6SX_CLK_ECSPI2
+ IMX6SX_CLK_ECSPI3 IMX6SX_CLK_ECSPI4
+ IMX6SX_CLK_ECSPI5 IMX6SX_CLK_QSPI1
+ IMX6SX_CLK_QSPI2 IMX6SX_CLK_SSI1
+ IMX6SX_CLK_SSI2 IMX6SX_CLK_SSI3
+ IMX6SX_CLK_UART_SERIAL IMX6SX_CLK_UART_IPG
+ IMX6SX_CLK_PERIPH_CLK2_SEL IMX6SX_CLK_DUMMY
+ IMX6SX_CLK_I2C1 IMX6SX_CLK_I2C2
+ IMX6SX_CLK_I2C3 IMX6SX_CLK_I2C4
+ IMX6SX_CLK_EPIT1 IMX6SX_CLK_EPIT2>;
+ fsl,shared-mem-addr = <0x91F000>;
+ fsl,shared-mem-size = <0x1000>;
+};
+
diff --git a/arch/arm/boot/dts/imx6sx-sabreauto.dts b/arch/arm/boot/dts/imx6sx-sabreauto.dts
index 240a2864d044..2cc8dd951db7 100644
--- a/arch/arm/boot/dts/imx6sx-sabreauto.dts
+++ b/arch/arm/boot/dts/imx6sx-sabreauto.dts
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2014 Freescale Semiconductor, Inc.
+ * Copyright 2017 NXP.
*
* 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
@@ -14,15 +15,83 @@
model = "Freescale i.MX6 SoloX Sabre Auto Board";
compatible = "fsl,imx6sx-sabreauto", "fsl,imx6sx";
+ backlight2 {
+ compatible = "pwm-backlight";
+ pwms = <&pwm4 0 5000000>;
+ brightness-levels = <0 4 8 16 32 64 128 255>;
+ default-brightness-level = <6>;
+ fb-names = "mxs-lcdif1";
+ };
+
+ clocks {
+ codec_osc: anaclk2 {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <24576000>;
+ };
+ };
+
+ max7310_reset: max7310-reset {
+ compatible = "gpio-reset";
+ reset-gpios = <&gpio1 15 GPIO_ACTIVE_LOW>;
+ reset-delay-us = <1>;
+ #reset-cells = <0>;
+ };
+
memory {
reg = <0x80000000 0x80000000>;
};
+ pxp_v4l2_out {
+ compatible = "fsl,imx6sx-pxp-v4l2", "fsl,imx6sl-pxp-v4l2";
+ status = "okay";
+ };
+
regulators {
compatible = "simple-bus";
#address-cells = <1>;
#size-cells = <0>;
+ reg_audio: cs42888_supply {
+ compatible = "regulator-fixed";
+ regulator-name = "cs42888_supply";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ si4763_vio1: vio1_tnr {
+ compatible = "regulator-fixed";
+ regulator-name = "vio1";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ si4763_vio2: vio2_tnr {
+ compatible = "regulator-fixed";
+ regulator-name = "vio2";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ si4763_vd: f3v3_tnr {
+ compatible = "regulator-fixed";
+ regulator-name = "vd";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ si4763_va: f5v_tnr {
+ compatible = "regulator-fixed";
+ regulator-name = "va";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-always-on;
+ };
+
vcc_sd3: regulator@0 {
compatible = "regulator-fixed";
reg = <0>;
@@ -34,15 +103,508 @@
gpio = <&gpio2 11 GPIO_ACTIVE_HIGH>;
enable-active-high;
};
+
+ reg_usb_otg1_vbus: usb_otg1_vbus {
+ compatible = "regulator-fixed";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usb_otg1_vbus>;
+ regulator-name = "usb_otg1_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&gpio1 9 0>;
+ enable-active-high;
+ };
+
+ reg_usb_otg2_vbus: usb_otg2_vbus {
+ compatible = "regulator-fixed";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usb_otg2_vbus>;
+ regulator-name = "usb_otg2_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&gpio1 12 0>;
+ enable-active-high;
+ };
+
+ reg_can_wake: regulator@1 {
+ compatible = "regulator-fixed";
+ reg = <1>;
+ regulator-name = "can-wake";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&max7310_b 7 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ reg_can_en: regulator@2 {
+ compatible = "regulator-fixed";
+ reg = <2>;
+ regulator-name = "can-en";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&max7310_b 5 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ vin-supply = <&reg_can_wake>;
+ };
+
+ reg_can_stby: regulator@3 {
+ compatible = "regulator-fixed";
+ reg = <3>;
+ regulator-name = "can-stby";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&max7310_b 4 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ vin-supply = <&reg_can_en>;
+ };
+
+ reg_vref_3v3: regulator@4 {
+ compatible = "regulator-fixed";
+ regulator-name = "vref-3v3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ };
+
+ sound-cs42888 {
+ compatible = "fsl,imx6-sabreauto-cs42888",
+ "fsl,imx-audio-cs42888";
+ model = "imx-cs42888";
+ esai-controller = <&esai>;
+ asrc-controller = <&asrc>;
+ audio-codec = <&codec>;
+ };
+
+ sound-fm {
+ compatible = "fsl,imx-audio-si476x",
+ "fsl,imx-tuner-si476x";
+ model = "imx-radio-si4763";
+
+ ssi-controller = <&ssi2>;
+ fm-controller = <&si476x_codec>;
+ mux-int-port = <2>;
+ mux-ext-port = <5>;
+ };
+
+ sound-spdif {
+ compatible = "fsl,imx-audio-spdif";
+ model = "imx-spdif";
+ spdif-controller = <&spdif>;
+ spdif-in;
};
};
+&adc1 {
+ vref-supply = <&reg_vref_3v3>;
+ status = "okay";
+};
+
+&adc2 {
+ vref-supply = <&reg_vref_3v3>;
+ status = "okay";
+};
+
+&audmux {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_audmux_3>;
+ status = "okay";
+};
+
+&clks {
+ assigned-clocks = <&clks IMX6SX_PLL4_BYPASS_SRC>,
+ <&clks IMX6SX_PLL4_BYPASS>,
+ <&clks IMX6SX_CLK_PLL4_POST_DIV>;
+ assigned-clock-parents = <&clks IMX6SX_CLK_LVDS2_IN>,
+ <&clks IMX6SX_PLL4_BYPASS_SRC>;
+ assigned-clock-rates = <0>, <0>, <24576000>;
+};
+
+&esai {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_esai_2>;
+ assigned-clocks = <&clks IMX6SX_CLK_ESAI_SEL>,
+ <&clks IMX6SX_CLK_ESAI_EXTAL>;
+ assigned-clock-parents = <&clks IMX6SX_CLK_PLL4_AUDIO_DIV>;
+ assigned-clock-rates = <0>, <24576000>;
+ status = "okay";
+};
+
+&fec1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_enet1_1>;
+ phy-mode = "rgmii";
+ phy-handle = <&ethphy1>;
+ fsl,magic-packet;
+ status = "okay";
+
+ mdio {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ethphy0: ethernet-phy@0 {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <0>;
+ };
+
+ ethphy1: ethernet-phy@1 {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <1>;
+ };
+ };
+};
+
+&fec2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_enet2_1>;
+ phy-mode = "rgmii";
+ phy-handle = <&ethphy0>;
+ fsl,magic-packet;
+ status = "okay";
+};
+
+&flexcan1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_flexcan1>;
+ xceiver-supply = <&reg_can_stby>;
+ status = "okay";
+};
+
+&flexcan2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_flexcan2>;
+ xceiver-supply = <&reg_can_stby>;
+ status = "okay";
+};
+
+&gpmi {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpmi_nand_1>;
+ nand-on-flash-bbt;
+ status = "okay";
+};
+
+&i2c2 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c2_1>;
+ status = "okay";
+
+ codec: cs42888@048 {
+ compatible = "cirrus,cs42888";
+ reg = <0x048>;
+ clocks = <&codec_osc 0>;
+ clock-names = "mclk";
+ VA-supply = <&reg_audio>;
+ VD-supply = <&reg_audio>;
+ VLS-supply = <&reg_audio>;
+ VLC-supply = <&reg_audio>;
+ };
+
+ egalax_ts@04 {
+ compatible = "eeti,egalax_ts";
+ reg = <0x04>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_egalax_int>;
+ interrupt-parent = <&gpio6>;
+ interrupts = <22 2>;
+ wakeup-gpios = <&gpio6 22 GPIO_ACTIVE_HIGH>;
+ };
+
+ si4763: si4763@63 {
+ compatible = "si4761";
+ reg = <0x63>;
+ va-supply = <&si4763_va>;
+ vd-supply = <&si4763_vd>;
+ vio1-supply = <&si4763_vio1>;
+ vio2-supply = <&si4763_vio2>;
+ revision-a10; /* set to default A10 compatible command set */
+
+ si476x_codec: si476x-codec {
+ compatible = "si476x-codec";
+ };
+ };
+
+ max7322: gpio@68 {
+ compatible = "maxim,max7322";
+ reg = <0x68>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ out-default = /bits/ 16 <0x1 0x1>;
+ };
+
+ pmic: pfuze100@08 {
+ compatible = "fsl,pfuze100";
+ reg = <0x08>;
+
+ regulators {
+ sw1a_reg: sw1ab {
+ regulator-min-microvolt = <300000>;
+ regulator-max-microvolt = <1875000>;
+ regulator-boot-on;
+ regulator-always-on;
+ regulator-ramp-delay = <6250>;
+ };
+
+ sw1c_reg: sw1c {
+ regulator-min-microvolt = <300000>;
+ regulator-max-microvolt = <1875000>;
+ regulator-boot-on;
+ regulator-always-on;
+ regulator-ramp-delay = <6250>;
+ };
+
+ sw2_reg: sw2 {
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ sw3a_reg: sw3a {
+ regulator-min-microvolt = <400000>;
+ regulator-max-microvolt = <1975000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ sw3b_reg: sw3b {
+ regulator-min-microvolt = <400000>;
+ regulator-max-microvolt = <1975000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ sw4_reg: sw4 {
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ swbst_reg: swbst {
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5150000>;
+ };
+
+ snvs_reg: vsnvs {
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ vref_reg: vrefddr {
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ vgen1_reg: vgen1 {
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1550000>;
+ regulator-always-on;
+ };
+
+ vgen2_reg: vgen2 {
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1550000>;
+ };
+
+ vgen3_reg: vgen3 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ vgen4_reg: vgen4 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ vgen5_reg: vgen5 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ vgen6_reg: vgen6 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+ };
+ };
+};
+
+&i2c3 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c3_2>;
+ status = "okay";
+
+ max7310_a: gpio@30 {
+ compatible = "maxim,max7310";
+ reg = <0x30>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ resets = <&max7310_reset>;
+ };
+
+ max7310_b: gpio@32 {
+ compatible = "maxim,max7310";
+ reg = <0x32>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ resets = <&max7310_reset>;
+ };
+
+ mma8451@1c {
+ compatible = "fsl,mma8451";
+ reg = <0x1c>;
+ position = <7>;
+ interrupt-parent = <&gpio3>;
+ interrupts = <24 8>;
+ interrupt-route = <1>;
+ };
+
+ mag3110@0e {
+ compatible = "fsl,mag3110";
+ reg = <0x0e>;
+ position = <2>;
+ interrupt-parent = <&gpio6>;
+ interrupts = <6 1>;
+ };
+
+ isl29023@44 {
+ compatible = "fsl,isl29023";
+ reg = <0x44>;
+ rext = <499>;
+ interrupt-parent = <&gpio3>;
+ interrupts = <23 2>;
+ };
+
+};
+
+&lcdif2 {
+ display = <&display1>;
+ disp-dev = "ldb";
+ status = "okay";
+
+ display1: display@1 {
+ bits-per-pixel = <16>;
+ bus-width = <18>;
+ };
+};
+
+&ldb {
+ status = "okay";
+
+ lvds-channel@0 {
+ fsl,data-mapping = "spwg";
+ fsl,data-width = <18>;
+ crtc = "lcdif2";
+ status = "okay";
+
+ display-timings {
+ native-mode = <&timing1>;
+ timing1: hsd100pxn1 {
+ clock-frequency = <65000000>;
+ hactive = <1024>;
+ vactive = <768>;
+ hback-porch = <220>;
+ hfront-porch = <40>;
+ vback-porch = <21>;
+ vfront-porch = <7>;
+ hsync-len = <60>;
+ vsync-len = <10>;
+ };
+ };
+ };
+};
+
+&mlb {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_mlb_2>;
+ status = "okay";
+};
+
+&pcie {
+ reset-gpio = <&max7310_b 3 0>;
+ status = "okay";
+};
+
+&qspi1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_qspi1_1>;
+ status = "okay";
+ ddrsmp=<2>;
+
+ flash0: n25q256a@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "micron,n25q256a";
+ spi-max-frequency = <29000000>;
+ reg = <0>;
+ };
+
+ flash1: n25q256a@1 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "micron,n25q256a";
+ spi-max-frequency = <29000000>;
+ reg = <1>;
+ };
+};
+
+&spdif {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_spdif_3>;
+ status = "okay";
+};
+
+&ssi2 {
+ fsl,mode = "i2s-master";
+ status = "okay";
+};
+
&uart1 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_uart1>;
status = "okay";
};
+&uart2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart2_1>;
+ status = "okay";
+};
+
+&uart5 { /* for bluetooth */
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart5_1>;
+ fsl,uart-has-rtscts;
+ status = "okay";
+ /* for DTE mode, add below change */
+ /* fsl,dte-mode;*/
+ /* pinctrl-0 = <&pinctrl_uart5dte_1>; */
+};
+
+&usbotg1 {
+ vbus-supply = <&reg_usb_otg1_vbus>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usb_otg1_id>;
+ srp-disable;
+ hnp-disable;
+ adp-disable;
+ status = "okay";
+};
+
+&usbotg2 {
+ vbus-supply = <&reg_usb_otg2_vbus>;
+ dr_mode = "host";
+ status = "okay";
+};
+
&usdhc3 {
pinctrl-names = "default", "state_100mhz", "state_200mhz";
pinctrl-0 = <&pinctrl_usdhc3>;
@@ -68,8 +630,169 @@
status = "okay";
};
+&pwm4 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pwm4_0>;
+ status = "okay";
+};
+
+&pxp {
+ status = "okay";
+};
+
&iomuxc {
imx6x-sabreauto {
+ pinctrl_audmux_3: audmux-3 {
+ fsl,pins = <
+ MX6SX_PAD_SD1_CMD__AUDMUX_AUD5_RXC 0x130b0
+ MX6SX_PAD_SD1_CLK__AUDMUX_AUD5_RXFS 0x130b0
+ MX6SX_PAD_SD1_DATA3__AUDMUX_AUD5_RXD 0x130b0
+ >;
+ };
+
+ pinctrl_egalax_int: egalax_intgrp {
+ fsl,pins = <
+ MX6SX_PAD_SD4_RESET_B__GPIO6_IO_22 0x80000000
+ >;
+ };
+
+ pinctrl_enet1_1: enet1grp-1 {
+ fsl,pins = <
+ MX6SX_PAD_ENET1_MDIO__ENET1_MDIO 0xa0b1
+ MX6SX_PAD_ENET1_MDC__ENET1_MDC 0xa0b1
+ MX6SX_PAD_RGMII1_TXC__ENET1_RGMII_TXC 0xa0b9
+ MX6SX_PAD_RGMII1_TD0__ENET1_TX_DATA_0 0xa0b1
+ MX6SX_PAD_RGMII1_TD1__ENET1_TX_DATA_1 0xa0b1
+ MX6SX_PAD_RGMII1_TD2__ENET1_TX_DATA_2 0xa0b1
+ MX6SX_PAD_RGMII1_TD3__ENET1_TX_DATA_3 0xa0b1
+ MX6SX_PAD_RGMII1_TX_CTL__ENET1_TX_EN 0xa0b1
+ MX6SX_PAD_RGMII1_RXC__ENET1_RX_CLK 0x3081
+ MX6SX_PAD_RGMII1_RD0__ENET1_RX_DATA_0 0x3081
+ MX6SX_PAD_RGMII1_RD1__ENET1_RX_DATA_1 0x3081
+ MX6SX_PAD_RGMII1_RD2__ENET1_RX_DATA_2 0x3081
+ MX6SX_PAD_RGMII1_RD3__ENET1_RX_DATA_3 0x3081
+ MX6SX_PAD_RGMII1_RX_CTL__ENET1_RX_EN 0x3081
+ >;
+ };
+
+ pinctrl_enet2_1: enet2grp-1 {
+ fsl,pins = <
+ MX6SX_PAD_RGMII2_TXC__ENET2_RGMII_TXC 0xa0b9
+ MX6SX_PAD_RGMII2_TD0__ENET2_TX_DATA_0 0xa0b1
+ MX6SX_PAD_RGMII2_TD1__ENET2_TX_DATA_1 0xa0b1
+ MX6SX_PAD_RGMII2_TD2__ENET2_TX_DATA_2 0xa0b1
+ MX6SX_PAD_RGMII2_TD3__ENET2_TX_DATA_3 0xa0b1
+ MX6SX_PAD_RGMII2_TX_CTL__ENET2_TX_EN 0xa0b1
+ MX6SX_PAD_RGMII2_RXC__ENET2_RX_CLK 0x3081
+ MX6SX_PAD_RGMII2_RD0__ENET2_RX_DATA_0 0x3081
+ MX6SX_PAD_RGMII2_RD1__ENET2_RX_DATA_1 0x3081
+ MX6SX_PAD_RGMII2_RD2__ENET2_RX_DATA_2 0x3081
+ MX6SX_PAD_RGMII2_RD3__ENET2_RX_DATA_3 0x3081
+ MX6SX_PAD_RGMII2_RX_CTL__ENET2_RX_EN 0x3081
+ >;
+ };
+
+ pinctrl_esai_2: esaigrp-2 {
+ fsl,pins = <
+ MX6SX_PAD_CSI_DATA00__ESAI_TX_CLK 0x1b030
+ MX6SX_PAD_CSI_DATA01__ESAI_TX_FS 0x1b030
+ MX6SX_PAD_CSI_HSYNC__ESAI_TX0 0x1b030
+ MX6SX_PAD_CSI_DATA04__ESAI_TX1 0x1b030
+ MX6SX_PAD_CSI_DATA06__ESAI_TX2_RX3 0x1b030
+ MX6SX_PAD_CSI_DATA07__ESAI_TX3_RX2 0x1b030
+ MX6SX_PAD_CSI_DATA02__ESAI_RX_CLK 0x1b030
+ MX6SX_PAD_CSI_DATA03__ESAI_RX_FS 0x1b030
+ MX6SX_PAD_CSI_VSYNC__ESAI_TX5_RX0 0x1b030
+ MX6SX_PAD_CSI_DATA05__ESAI_TX4_RX1 0x1b030
+ >;
+ };
+
+ pinctrl_flexcan1: flexcan1grp-1 {
+ fsl,pins = <
+ MX6SX_PAD_QSPI1B_DQS__CAN1_TX 0x1b020
+ MX6SX_PAD_QSPI1A_SS1_B__CAN1_RX 0x1b020
+ >;
+ };
+
+ pinctrl_flexcan2: flexcan2grp-1 {
+ fsl,pins = <
+ MX6SX_PAD_QSPI1B_SS1_B__CAN2_RX 0x1b020
+ MX6SX_PAD_QSPI1A_DQS__CAN2_TX 0x1b020
+ >;
+ };
+
+ pinctrl_gpmi_nand_1: gpmi-nand-1 {
+ fsl,pins = <
+ MX6SX_PAD_NAND_CLE__RAWNAND_CLE 0xb0b1
+ MX6SX_PAD_NAND_ALE__RAWNAND_ALE 0xb0b1
+ MX6SX_PAD_NAND_WP_B__RAWNAND_WP_B 0xb0b1
+ MX6SX_PAD_NAND_READY_B__RAWNAND_READY_B 0xb000
+ MX6SX_PAD_NAND_CE0_B__RAWNAND_CE0_B 0xb0b1
+ MX6SX_PAD_NAND_CE1_B__RAWNAND_CE1_B 0xb0b1
+ MX6SX_PAD_NAND_RE_B__RAWNAND_RE_B 0xb0b1
+ MX6SX_PAD_NAND_WE_B__RAWNAND_WE_B 0xb0b1
+ MX6SX_PAD_NAND_DATA00__RAWNAND_DATA00 0xb0b1
+ MX6SX_PAD_NAND_DATA01__RAWNAND_DATA01 0xb0b1
+ MX6SX_PAD_NAND_DATA02__RAWNAND_DATA02 0xb0b1
+ MX6SX_PAD_NAND_DATA03__RAWNAND_DATA03 0xb0b1
+ MX6SX_PAD_NAND_DATA04__RAWNAND_DATA04 0xb0b1
+ MX6SX_PAD_NAND_DATA05__RAWNAND_DATA05 0xb0b1
+ MX6SX_PAD_NAND_DATA06__RAWNAND_DATA06 0xb0b1
+ MX6SX_PAD_NAND_DATA07__RAWNAND_DATA07 0xb0b1
+ >;
+ };
+
+ pinctrl_i2c2_1: i2c2grp-1 {
+ fsl,pins = <
+ MX6SX_PAD_GPIO1_IO03__I2C2_SDA 0x4001b8b1
+ MX6SX_PAD_GPIO1_IO02__I2C2_SCL 0x4001b8b1
+ >;
+ };
+
+ pinctrl_i2c3_2: i2c3grp-2 {
+ fsl,pins = <
+ MX6SX_PAD_KEY_ROW4__I2C3_SDA 0x4001b8b1
+ MX6SX_PAD_KEY_COL4__I2C3_SCL 0x4001b8b1
+ >;
+ };
+
+ pinctrl_mlb_2: mlbgrp-2 {
+ fsl,pins = <
+ MX6SX_PAD_ENET2_RX_CLK__MLB_DATA 0x31
+ MX6SX_PAD_ENET2_CRS__MLB_SIG 0x31
+ MX6SX_PAD_ENET2_TX_CLK__MLB_CLK 0x31
+ >;
+ };
+
+ pinctrl_pwm4_0: pwm4grp-0 {
+ fsl,pins = <
+ MX6SX_PAD_SD1_DATA1__PWM4_OUT 0x110b0
+ >;
+ };
+
+ pinctrl_qspi1_1: qspi1grp_1 {
+ fsl,pins = <
+ MX6SX_PAD_QSPI1A_DATA0__QSPI1_A_DATA_0 0x70a1
+ MX6SX_PAD_QSPI1A_DATA1__QSPI1_A_DATA_1 0x70a1
+ MX6SX_PAD_QSPI1A_DATA2__QSPI1_A_DATA_2 0x70a1
+ MX6SX_PAD_QSPI1A_DATA3__QSPI1_A_DATA_3 0x70a1
+ MX6SX_PAD_QSPI1A_SCLK__QSPI1_A_SCLK 0x70a1
+ MX6SX_PAD_QSPI1A_SS0_B__QSPI1_A_SS0_B 0x70a1
+ MX6SX_PAD_QSPI1B_DATA0__QSPI1_B_DATA_0 0x70a1
+ MX6SX_PAD_QSPI1B_DATA1__QSPI1_B_DATA_1 0x70a1
+ MX6SX_PAD_QSPI1B_DATA2__QSPI1_B_DATA_2 0x70a1
+ MX6SX_PAD_QSPI1B_DATA3__QSPI1_B_DATA_3 0x70a1
+ MX6SX_PAD_QSPI1B_SCLK__QSPI1_B_SCLK 0x70a1
+ MX6SX_PAD_QSPI1B_SS0_B__QSPI1_B_SS0_B 0x70a1
+ >;
+ };
+
+ pinctrl_spdif_3: spdifgrp-3 {
+ fsl,pins = <
+ MX6SX_PAD_ENET2_COL__SPDIF_IN 0x1b0b0
+ >;
+ };
+
pinctrl_uart1: uart1grp {
fsl,pins = <
MX6SX_PAD_GPIO1_IO04__UART1_TX 0x1b0b1
@@ -77,6 +800,49 @@
>;
};
+ pinctrl_uart2_1: uart2grp-1 {
+ fsl,pins = <
+ MX6SX_PAD_GPIO1_IO07__UART2_RX 0x1b0b1
+ MX6SX_PAD_GPIO1_IO06__UART2_TX 0x1b0b1
+ >;
+ };
+
+ pinctrl_uart5_1: uart5grp-1 {
+ fsl,pins = <
+ MX6SX_PAD_KEY_ROW3__UART5_RX 0x1b0b1
+ MX6SX_PAD_KEY_COL3__UART5_TX 0x1b0b1
+ MX6SX_PAD_KEY_ROW2__UART5_CTS_B 0x1b0b1
+ MX6SX_PAD_KEY_COL2__UART5_RTS_B 0x1b0b1
+ >;
+ };
+
+ pinctrl_uart5dte_1: uart5dtegrp-1 {
+ fsl,pins = <
+ MX6SX_PAD_KEY_ROW3__UART5_TX 0x1b0b1
+ MX6SX_PAD_KEY_COL3__UART5_RX 0x1b0b1
+ MX6SX_PAD_KEY_ROW2__UART5_RTS_B 0x1b0b1
+ MX6SX_PAD_KEY_COL2__UART5_CTS_B 0x1b0b1
+ >;
+ };
+
+ pinctrl_usb_otg1_vbus: usbotg1vbusgrp {
+ fsl,pins = <
+ MX6SX_PAD_GPIO1_IO09__GPIO1_IO_9 0x10b0
+ >;
+ };
+
+ pinctrl_usb_otg1_id: usbotg1idgrp {
+ fsl,pins = <
+ MX6SX_PAD_GPIO1_IO10__ANATOP_OTG1_ID 0x17059
+ >;
+ };
+
+ pinctrl_usb_otg2_vbus: usbotg2vbusgrp {
+ fsl,pins = <
+ MX6SX_PAD_GPIO1_IO12__GPIO1_IO_12 0x10b0
+ >;
+ };
+
pinctrl_usdhc3: usdhc3grp {
fsl,pins = <
MX6SX_PAD_SD3_CMD__USDHC3_CMD 0x17059
@@ -89,8 +855,8 @@
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 */
+ MX6SX_PAD_USB_H_DATA__GPIO7_IO_10 0x17059 /* CD */
+ MX6SX_PAD_LCD1_DATA18__GPIO3_IO_19 0x17059 /* WP */
>;
};
@@ -126,14 +892,13 @@
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 */
+ MX6SX_PAD_SD4_CMD__USDHC4_CMD 0x17071
+ MX6SX_PAD_SD4_CLK__USDHC4_CLK 0x10071
+ MX6SX_PAD_SD4_DATA0__USDHC4_DATA0 0x17071
+ MX6SX_PAD_SD4_DATA1__USDHC4_DATA1 0x17071
+ MX6SX_PAD_SD4_DATA2__USDHC4_DATA2 0x17071
+ MX6SX_PAD_SD4_DATA3__USDHC4_DATA3 0x17071
+ MX6SX_PAD_USB_H_STROBE__GPIO7_IO_11 0x17071 /* CD */
>;
};
@@ -142,5 +907,48 @@
MX6SX_PAD_KEY_COL1__GPIO2_IO_11 0x17059
>;
};
+
+ pinctrl_wdog: wdoggrp {
+ fsl,pins = <
+ MX6SX_PAD_GPIO1_IO13__WDOG1_WDOG_ANY 0x30b0
+ >;
+ };
+ };
+};
+&csi2 {
+ status = "okay";
+ port {
+ csi2_ep: endpoint {
+ remote-endpoint = <&vadc_ep>;
+ };
};
};
+
+&dcic1 {
+ dcic_id = <0>;
+ dcic_mux = "dcic-lcdif1";
+ status = "okay";
+};
+
+&dcic2 {
+ dcic_id = <1>;
+ dcic_mux = "dcic-lvds";
+ status = "okay";
+};
+
+&vadc {
+ vadc_in = <0>;
+ csi_id = <1>;
+ status = "okay";
+ port {
+ vadc_ep: endpoint {
+ remote-endpoint = <&csi2_ep>;
+ };
+ };
+};
+
+&wdog1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_wdog>;
+ fsl,ext-reset-output;
+};
diff --git a/arch/arm/boot/dts/imx6sx-sdb-btwifi.dts b/arch/arm/boot/dts/imx6sx-sdb-btwifi.dts
new file mode 100644
index 000000000000..e6386401cb7b
--- /dev/null
+++ b/arch/arm/boot/dts/imx6sx-sdb-btwifi.dts
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2015 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.
+ */
+
+/*
+ * NOTE: This DTS file is written for plugging in Murata Wi-Fi/BT EVK into SD3
+ * slot using Murata i.MX InterConnect Ver 1.0 Adapter AND SD Card Extender on
+ * SD2 slot. Bluetooth UART connects via SD3 EMMC/MMC Plus pinout.
+ * WL_REG_ON/BT_REG_ON/WL_HOST_WAKE connect via SD Card Extender.
+ */
+
+#include "imx6sx-sdb.dts"
+
+/ {
+ modem_reset: modem-reset {
+ compatible = "gpio-reset";
+ reset-gpios = <&gpio6 11 GPIO_ACTIVE_LOW>;
+ reset-delay-us = <1000>;
+ #reset-cells = <0>;
+ };
+
+ usdhc3_pwrseq: usdhc3_pwrseq {
+ compatible = "mmc-pwrseq-simple";
+ reset-gpios = <&gpio6 10 GPIO_ACTIVE_LOW>;
+ };
+};
+
+&iomuxc {
+ imx6sx-sdb-murata-v1_sdext {
+ pinctrl_bt: btgrp {
+ fsl,pins = <
+ MX6SX_PAD_SD2_DATA3__GPIO6_IO_11 0x13069 /* BT_REG_ON */
+ >;
+ };
+
+ pinctrl_uart3: uart3grp {
+ fsl,pins = <
+ MX6SX_PAD_SD3_DATA4__UART3_RX 0x1b0b1
+ MX6SX_PAD_SD3_DATA5__UART3_TX 0x1b0b1
+ MX6SX_PAD_SD3_DATA7__UART3_CTS_B 0x1b0b1
+ MX6SX_PAD_SD3_DATA6__UART3_RTS_B 0x1b0b1
+ >;
+ };
+
+ /* change MUXing on SD2 slot for control signals. */
+ pinctrl_usdhc2_1: usdhc2grp-1 {
+ fsl,pins = <
+ MX6SX_PAD_SD2_CMD__USDHC2_CMD 0x17059
+ MX6SX_PAD_SD2_CLK__USDHC2_CLK 0x10059
+ MX6SX_PAD_SD2_DATA0__USDHC2_DATA0 0x17059
+ >;
+ };
+
+ /* Murata change SD3 to 4-bit SDIO only; use upper 4-bits for UART. */
+ pinctrl_wifi: wifigrp {
+ fsl,pins = <
+ MX6SX_PAD_SD3_CMD__USDHC3_CMD 0x17069
+ MX6SX_PAD_SD3_CLK__USDHC3_CLK 0x10071
+ MX6SX_PAD_SD3_DATA0__USDHC3_DATA0 0x17069
+ MX6SX_PAD_SD3_DATA1__USDHC3_DATA1 0x17069
+ MX6SX_PAD_SD3_DATA2__USDHC3_DATA2 0x17069
+ MX6SX_PAD_SD3_DATA3__USDHC3_DATA3 0x17069
+ MX6SX_PAD_KEY_COL0__GPIO2_IO_10 0x17059 /* CD */
+ MX6SX_PAD_KEY_ROW0__GPIO2_IO_15 0x17059 /* WP */
+ /* Murata Module control signals */
+ MX6SX_PAD_SD2_DATA1__GPIO6_IO_9 0x13069 /* WL_HOST_WAKE */
+ MX6SX_PAD_SD2_DATA2__GPIO6_IO_10 0x13069 /* WL_REG_ON */
+ >;
+ };
+ };
+};
+
+&uart3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart3
+ &pinctrl_bt>;
+ fsl,uart-has-rtscts;
+ resets = <&modem_reset>;
+ status = "okay";
+};
+
+&usdhc2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usdhc2_1>;
+ bus-width = <1>;
+};
+
+&vcc_sd3 {
+ regulator-always-on;
+};
+
+&usdhc3 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_wifi>;
+ bus-width = <4>;
+ no-1-8-v; /* force 3.3V VIO */
+ non-removable;
+ mmc-pwrseq = <&usdhc3_pwrseq>;
+ pm-ignore-notify;
+ cap-power-off-card;
+ status = "okay";
+
+ brcmf: bcrmf@1 {
+ reg = <1>;
+ compatible = "brcm,bcm4329-fmac";
+ };
+};
diff --git a/arch/arm/boot/dts/imx6sx-sdb-emmc.dts b/arch/arm/boot/dts/imx6sx-sdb-emmc.dts
new file mode 100644
index 000000000000..6a2a07b0e2ba
--- /dev/null
+++ b/arch/arm/boot/dts/imx6sx-sdb-emmc.dts
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2015 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 "imx6sx-sdb.dts"
+
+/*
+ * The eMMC chip on imx6sx sdb board is DNP by default.
+ * Need do hw rework to burn the eMMC4.5 chip on the eMMC socket on uSDHC4
+ * and connect eMMC signals as well as disconnect BOOT SD CARD slot signals
+ */
+&usdhc4 {
+ pinctrl-names = "default", "state_100mhz", "state_200mhz";
+ pinctrl-0 = <&pinctrl_usdhc4_1>;
+ pinctrl-1 = <&pinctrl_usdhc4_1_100mhz>;
+ pinctrl-2 = <&pinctrl_usdhc4_1_200mhz>;
+ bus-width = <8>;
+ /*
+ * overwrite cd-gpios and wp-gpios since they are reused as eMMC DATA
+ * signals after rework
+ */
+ cd-gpios = <>;
+ wp-gpios = <>;
+ non-removable;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx6sx-sdb-lcdif1.dts b/arch/arm/boot/dts/imx6sx-sdb-lcdif1.dts
new file mode 100644
index 000000000000..280540453aeb
--- /dev/null
+++ b/arch/arm/boot/dts/imx6sx-sdb-lcdif1.dts
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2014-2015 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 "imx6sx-sdb.dts"
+
+/ {
+ sii902x_reset: sii902x-reset {
+ status = "okay";
+ };
+};
+
+&csi1 {
+ status = "disabled";
+};
+
+&lcdif1 {
+ status = "okay";
+};
+
+&i2c1 {
+ sii902x@39 {
+ status = "okay";
+ };
+};
+
+&ov5640 {
+ status = "disabled";
+};
+
+&crypto {
+ status = "disabled";
+};
diff --git a/arch/arm/boot/dts/imx6sx-sdb-ldo.dts b/arch/arm/boot/dts/imx6sx-sdb-ldo.dts
new file mode 100644
index 000000000000..3a8c194ba2d6
--- /dev/null
+++ b/arch/arm/boot/dts/imx6sx-sdb-ldo.dts
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2015 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 "imx6sx-sdb.dts"
+
+&cpu0 {
+ operating-points = <
+ /* kHz uV */
+ 996000 1250000
+ 792000 1175000
+ 396000 1075000
+ 198000 975000
+ >;
+ fsl,soc-operating-points = <
+ /* ARM kHz SOC uV */
+ 996000 1175000
+ 792000 1175000
+ 396000 1175000
+ 198000 1175000
+ >;
+ fsl,arm-soc-shared = <0>;
+};
+
+&gpc {
+ fsl,ldo-bypass = <0>; /* use ldo-enable, u-boot will check it and configure */
+};
+
+&reg_arm {
+ /delete-property/ vin-supply;
+};
+
+&reg_soc {
+ /delete-property/ vin-supply;
+};
diff --git a/arch/arm/boot/dts/imx6sx-sdb-m4.dts b/arch/arm/boot/dts/imx6sx-sdb-m4.dts
new file mode 100644
index 000000000000..61a1db351dd6
--- /dev/null
+++ b/arch/arm/boot/dts/imx6sx-sdb-m4.dts
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2014-2015 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 "imx6sx-sdb.dts"
+
+/{
+ memory {
+ linux,usable-memory = <0x80000000 0x1ff00000>,
+ <0xa0000000 0x1ff00000>;
+ };
+};
+
+&iomuxc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_hog>;
+};
+
+/*
+ * The flollowing modules are conflicting with M4, disable them when m4
+ * is running.
+ */
+&adc1 {
+ status = "disabled";
+};
+
+&adc2 {
+ status = "disabled";
+};
+
+&flexcan1 {
+ status = "disabled";
+};
+
+&flexcan2 {
+ status = "disabled";
+};
+
+&i2c3 {
+ status = "disabled";
+};
+
+&ocram {
+ reg = <0x00901000 0xf000>;
+};
+
+&qspi2 {
+ status = "disabled";
+};
+
+&qspi_m4 {
+ status = "okay";
+};
+
+&rpmsg{
+ vdev-nums = <1>;
+ reg = <0xbfff0000 0x10000>;
+ status = "okay";
+};
+
+&uart2 {
+ status = "disabled";
+};
+
+&clks {
+ fsl,shared-clks-number = <0x23>;
+ fsl,shared-clks-index = <IMX6SX_CLK_PLL2_BUS IMX6SX_CLK_PLL2_PFD0
+ IMX6SX_CLK_PLL2_PFD2 IMX6SX_CLK_PLL3_USB_OTG
+ IMX6SX_CLK_PLL3_PFD1 IMX6SX_CLK_PLL3_PFD2
+ IMX6SX_CLK_PLL3_PFD3 IMX6SX_CLK_PLL4_AUDIO
+ IMX6SX_CLK_PLL5_VIDEO
+ IMX6SX_CLK_OCRAM IMX6SX_CLK_CAN1_SERIAL
+ IMX6SX_CLK_CAN1_IPG IMX6SX_CLK_CAN2_SERIAL
+ IMX6SX_CLK_CAN2_IPG IMX6SX_CLK_CANFD
+ IMX6SX_CLK_ECSPI1 IMX6SX_CLK_ECSPI2
+ IMX6SX_CLK_ECSPI3 IMX6SX_CLK_ECSPI4
+ IMX6SX_CLK_ECSPI5 IMX6SX_CLK_QSPI1
+ IMX6SX_CLK_QSPI2 IMX6SX_CLK_SSI1
+ IMX6SX_CLK_SSI2 IMX6SX_CLK_SSI3
+ IMX6SX_CLK_UART_SERIAL IMX6SX_CLK_UART_IPG
+ IMX6SX_CLK_PERIPH_CLK2_SEL IMX6SX_CLK_DUMMY
+ IMX6SX_CLK_I2C1 IMX6SX_CLK_I2C2
+ IMX6SX_CLK_I2C3 IMX6SX_CLK_I2C4
+ IMX6SX_CLK_EPIT1 IMX6SX_CLK_EPIT2>;
+ fsl,shared-mem-addr = <0x91F000>;
+ fsl,shared-mem-size = <0x1000>;
+};
diff --git a/arch/arm/boot/dts/imx6sx-sdb-mqs.dts b/arch/arm/boot/dts/imx6sx-sdb-mqs.dts
new file mode 100644
index 000000000000..bf388accfe7d
--- /dev/null
+++ b/arch/arm/boot/dts/imx6sx-sdb-mqs.dts
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2014-2015 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.
+ *
+ * This feature is supported by the MX6SX-SD-EXP1 board
+ *
+ */
+
+#include "imx6sx-sdb.dts"
+/ {
+
+ sound {
+ status = "disabled";
+ };
+
+ sound-mqs {
+ compatible = "fsl,imx6sx-sdb-mqs",
+ "fsl,imx-audio-mqs";
+ model = "mqs-audio";
+ cpu-dai = <&sai1>;
+ asrc-controller = <&asrc>;
+ audio-codec = <&mqs>;
+ };
+};
+
+&usdhc2 {
+ /* pin conflict with mqs*/
+ status = "disabled";
+};
+
+&mqs {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_mqs>;
+ clocks = <&clks IMX6SX_CLK_SAI1>;
+ clock-names = "mclk";
+ status = "okay";
+};
+
+&sai1 {
+ pinctrl-0 = <>;
+ status = "okay";
+};
+
+&ssi2 {
+ status = "disabled";
+};
+
+&sdma {
+ gpr = <&gpr>;
+ /* SDMA event remap for SAI1 */
+ fsl,sdma-event-remap = <0 15 1>, <0 16 1>;
+};
diff --git a/arch/arm/boot/dts/imx6sx-sdb-reva-ldo.dts b/arch/arm/boot/dts/imx6sx-sdb-reva-ldo.dts
new file mode 100644
index 000000000000..867199915236
--- /dev/null
+++ b/arch/arm/boot/dts/imx6sx-sdb-reva-ldo.dts
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2015 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 "imx6sx-sdb-reva.dts"
+
+&gpc {
+ fsl,ldo-bypass = <0>; /* use ldo-enable, u-boot will check it and configure */
+};
+
+&reg_arm {
+ /delete-property/ vin-supply;
+};
+
+&reg_soc {
+ /delete-property/ vin-supply;
+};
diff --git a/arch/arm/boot/dts/imx6sx-sdb-reva.dts b/arch/arm/boot/dts/imx6sx-sdb-reva.dts
index 71005478cdf0..4f41b271b60f 100644
--- a/arch/arm/boot/dts/imx6sx-sdb-reva.dts
+++ b/arch/arm/boot/dts/imx6sx-sdb-reva.dts
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2015 Freescale Semiconductor, Inc.
+ * Copyright 2017 NXP.
*
* 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
@@ -10,6 +11,48 @@
/ {
model = "Freescale i.MX6 SoloX SDB RevA Board";
+
+ regulators {
+ /* Transceiver EN/STBY is active high on RevA board */
+ reg_can_en: regulator@9 {
+ gpio = <&gpio4 25 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ reg_can_stby: regulator@10 {
+ gpio = <&gpio4 27 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ vin-supply = <&reg_can_en>;
+ };
+ };
+};
+
+&cpu0 {
+ operating-points = <
+ /* kHz uV */
+ 996000 1250000
+ 792000 1175000
+ 396000 1075000
+ 198000 975000
+ >;
+ fsl,soc-operating-points = <
+ /* ARM kHz SOC uV */
+ 996000 1175000
+ 792000 1175000
+ 396000 1175000
+ 198000 1175000
+ >;
+ fsl,arm-soc-shared = <0>;
+};
+
+&reg_arm {
+ vin-supply = <&sw1a_reg>;
+ regulator-allow-bypass;
+};
+
+&reg_soc {
+ vin-supply = <&sw1c_reg>;
+ regulator-allow-bypass;
};
&i2c1 {
@@ -63,6 +106,7 @@
sw4_reg: sw4 {
regulator-min-microvolt = <800000>;
regulator-max-microvolt = <3300000>;
+ regulator-always-on;
};
swbst_reg: swbst {
@@ -124,13 +168,14 @@
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_qspi2>;
status = "okay";
+ ddrsmp=<0>;
flash0: s25fl128s@0 {
reg = <0>;
#address-cells = <1>;
#size-cells = <1>;
compatible = "spansion,s25fl128s", "jedec,spi-nor";
- spi-max-frequency = <66000000>;
+ spi-max-frequency = <29000000>;
};
flash1: s25fl128s@1 {
@@ -138,6 +183,6 @@
#address-cells = <1>;
#size-cells = <1>;
compatible = "spansion,s25fl128s", "jedec,spi-nor";
- spi-max-frequency = <66000000>;
+ spi-max-frequency = <29000000>;
};
};
diff --git a/arch/arm/boot/dts/imx6sx-sdb-sai.dts b/arch/arm/boot/dts/imx6sx-sdb-sai.dts
index 2ac865b7c364..614cffe3ee40 100644
--- a/arch/arm/boot/dts/imx6sx-sdb-sai.dts
+++ b/arch/arm/boot/dts/imx6sx-sdb-sai.dts
@@ -43,7 +43,7 @@
/ {
sound {
- audio-cpu = <&sai1>;
+ cpu-dai = <&sai1>;
};
};
@@ -53,6 +53,8 @@
};
&sai1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_sai1>;
status = "okay";
};
diff --git a/arch/arm/boot/dts/imx6sx-sdb.dts b/arch/arm/boot/dts/imx6sx-sdb.dts
index c0139d7e497a..ca02fdbf633b 100644
--- a/arch/arm/boot/dts/imx6sx-sdb.dts
+++ b/arch/arm/boot/dts/imx6sx-sdb.dts
@@ -10,101 +10,40 @@
/ {
model = "Freescale i.MX6 SoloX SDB RevB Board";
-};
-
-&i2c1 {
- clock-frequency = <100000>;
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_i2c1>;
- status = "okay";
-
- pmic: pfuze100@08 {
- compatible = "fsl,pfuze200";
- reg = <0x08>;
-
- regulators {
- sw1a_reg: sw1ab {
- regulator-min-microvolt = <300000>;
- regulator-max-microvolt = <1875000>;
- regulator-boot-on;
- regulator-always-on;
- regulator-ramp-delay = <6250>;
- };
-
- sw2_reg: sw2 {
- regulator-min-microvolt = <800000>;
- regulator-max-microvolt = <3300000>;
- regulator-boot-on;
- regulator-always-on;
- };
-
- sw3a_reg: sw3a {
- regulator-min-microvolt = <400000>;
- regulator-max-microvolt = <1975000>;
- regulator-boot-on;
- regulator-always-on;
- };
- sw3b_reg: sw3b {
- regulator-min-microvolt = <400000>;
- regulator-max-microvolt = <1975000>;
- regulator-boot-on;
- regulator-always-on;
- };
-
- swbst_reg: swbst {
- regulator-min-microvolt = <5000000>;
- regulator-max-microvolt = <5150000>;
- };
-
- snvs_reg: vsnvs {
- regulator-min-microvolt = <1000000>;
- regulator-max-microvolt = <3000000>;
- regulator-boot-on;
- regulator-always-on;
- };
-
- vref_reg: vrefddr {
- regulator-boot-on;
- regulator-always-on;
- };
-
- vgen1_reg: vgen1 {
- regulator-min-microvolt = <800000>;
- regulator-max-microvolt = <1550000>;
- regulator-always-on;
- };
-
- vgen2_reg: vgen2 {
- regulator-min-microvolt = <800000>;
- regulator-max-microvolt = <1550000>;
- };
-
- vgen3_reg: vgen3 {
- regulator-min-microvolt = <1800000>;
- regulator-max-microvolt = <3300000>;
- regulator-always-on;
- };
+ regulators {
+ /* Transceiver EN/STBY is active low on RevB board */
+ reg_can_stby: regulator@10 {
+ gpio = <&gpio4 27 GPIO_ACTIVE_LOW>;
+ };
+ };
+};
- vgen4_reg: vgen4 {
- regulator-min-microvolt = <1800000>;
- regulator-max-microvolt = <3300000>;
- regulator-always-on;
- };
+&cpu0 {
+ operating-points = <
+ /* kHz uV */
+ 996000 1250000
+ 792000 1175000
+ 396000 1175000
+ >;
+ fsl,soc-operating-points = <
+ /* ARM kHz SOC uV */
+ 996000 1250000
+ 792000 1175000
+ 396000 1175000
+ >;
+
+ fsl,arm-soc-shared = <1>;
+};
- vgen5_reg: vgen5 {
- regulator-min-microvolt = <1800000>;
- regulator-max-microvolt = <3300000>;
- regulator-always-on;
- };
+&reg_arm {
+ vin-supply = <&sw1a_reg>;
+ regulator-allow-bypass;
+};
- vgen6_reg: vgen6 {
- regulator-min-microvolt = <1800000>;
- regulator-max-microvolt = <3300000>;
- regulator-always-on;
- };
- };
- };
+&reg_soc {
+ vin-supply = <&sw1a_reg>;
+ regulator-allow-bypass;
};
&qspi2 {
@@ -112,6 +51,9 @@
pinctrl-0 = <&pinctrl_qspi2>;
status = "okay";
+#ifndef SPANSIONFLASH
+ ddrsmp=<0>;
+
flash0: n25q256a@0 {
#address-cells = <1>;
#size-cells = <1>;
@@ -127,12 +69,23 @@
spi-max-frequency = <29000000>;
reg = <1>;
};
+#endif
};
&reg_arm {
vin-supply = <&sw1a_reg>;
+ regulator-allow-bypass;
};
&reg_soc {
vin-supply = <&sw1a_reg>;
+ regulator-allow-bypass;
+};
+
+&usbphy1 {
+ fsl,tx-d-cal = <106>;
+};
+
+&usbphy2 {
+ fsl,tx-d-cal = <106>;
};
diff --git a/arch/arm/boot/dts/imx6sx-sdb.dtsi b/arch/arm/boot/dts/imx6sx-sdb.dtsi
index da815527a7f8..156c413ff544 100644
--- a/arch/arm/boot/dts/imx6sx-sdb.dtsi
+++ b/arch/arm/boot/dts/imx6sx-sdb.dtsi
@@ -24,11 +24,19 @@
reg = <0x80000000 0x40000000>;
};
- backlight {
+ backlight1 {
compatible = "pwm-backlight";
pwms = <&pwm3 0 5000000>;
brightness-levels = <0 4 8 16 32 64 128 255>;
default-brightness-level = <6>;
+ fb-names = "mxs-lcdif0";
+ };
+ backlight2 {
+ compatible = "pwm-backlight";
+ pwms = <&pwm4 0 5000000>;
+ brightness-levels = <0 4 8 16 32 64 128 255>;
+ default-brightness-level = <6>;
+ fb-names = "mxs-lcdif1";
};
gpio-keys {
@@ -49,6 +57,18 @@
};
};
+ hannstar_cabc {
+ compatible = "hannstar,cabc";
+ lvds0 {
+ gpios = <&gpio4 26 GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ pxp_v4l2_out {
+ compatible = "fsl,imx6sx-pxp-v4l2", "fsl,imx6sl-pxp-v4l2";
+ status = "okay";
+ };
+
regulators {
compatible = "simple-bus";
#address-cells = <1>;
@@ -63,6 +83,7 @@
regulator-min-microvolt = <3000000>;
regulator-max-microvolt = <3000000>;
gpio = <&gpio2 11 GPIO_ACTIVE_HIGH>;
+ off-on-delay = <20000>;
enable-active-high;
};
@@ -104,6 +125,7 @@
regulator-name = "lcd-3v3";
gpio = <&gpio3 27 0>;
enable-active-high;
+ status = "disabled";
};
reg_peri_3v3: regulator@5 {
@@ -129,12 +151,49 @@
regulator-max-microvolt = <3300000>;
gpios = <&gpio2 6 GPIO_ACTIVE_LOW>;
};
+
+ reg_vref_3v3: regulator@7 {
+ compatible = "regulator-fixed";
+ reg = <7>;
+ regulator-name = "vref-3v3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ reg_pcie: regulator@8 {
+ compatible = "regulator-fixed";
+ reg = <8>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pcie_reg>;
+ regulator-name = "MPCIE_3V3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&gpio2 1 0>;
+ regulator-always-on;
+ enable-active-high;
+ };
+
+ reg_can_en: regulator@9 {
+ compatible = "regulator-fixed";
+ reg = <9>;
+ regulator-name = "can-en";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ reg_can_stby: regulator@10 {
+ compatible = "regulator-fixed";
+ reg = <10>;
+ regulator-name = "can-stby";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
};
sound {
compatible = "fsl,imx6sx-sdb-wm8962", "fsl,imx-audio-wm8962";
model = "wm8962-audio";
- ssi-controller = <&ssi2>;
+ cpu-dai = <&ssi2>;
audio-codec = <&codec>;
audio-routing =
"Headphone Jack", "HPOUTL",
@@ -145,15 +204,48 @@
"IN3R", "AMIC";
mux-int-port = <2>;
mux-ext-port = <6>;
+ codec-master;
+ hp-det-gpios = <&gpio1 17 1>;
+ };
+
+ sound-spdif {
+ compatible = "fsl,imx-audio-spdif",
+ "fsl,imx6sx-sdb-spdif";
+ model = "imx-spdif";
+ spdif-controller = <&spdif>;
+ spdif-out;
+ };
+
+ sii902x_reset: sii902x-reset {
+ compatible = "gpio-reset";
+ reset-gpios = <&gpio3 27 1>;
+ reset-delay-us = <100000>;
+ #reset-cells = <0>;
+ status = "disabled";
};
};
+&adc1 {
+ vref-supply = <&reg_vref_3v3>;
+ status = "okay";
+};
+
+&adc2 {
+ vref-supply = <&reg_vref_3v3>;
+ status = "okay";
+};
+
&audmux {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_audmux>;
status = "okay";
};
+
+&gpc {
+ fsl,ldo-bypass = <1>;
+};
+
&fec1 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_enet1>;
@@ -176,6 +268,37 @@
};
};
+&csi1 {
+ status = "okay";
+
+ port {
+ csi1_ep: endpoint {
+ remote-endpoint = <&ov5640_ep>;
+ };
+ };
+};
+
+&csi2 {
+ status = "okay";
+ port {
+ csi2_ep: endpoint {
+ remote-endpoint = <&vadc_ep>;
+ };
+ };
+};
+
+&dcic1 {
+ dcic_id = <0>;
+ dcic_mux = "dcic-lcdif1";
+ status = "okay";
+};
+
+&dcic2 {
+ dcic_id = <1>;
+ dcic_mux = "dcic-lvds";
+ status = "okay";
+};
+
&fec2 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_enet2>;
@@ -184,11 +307,196 @@
status = "okay";
};
+&flexcan1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_flexcan1>;
+ xceiver-supply = <&reg_can_stby>;
+ status = "okay";
+};
+
+&flexcan2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_flexcan2>;
+ xceiver-supply = <&reg_can_stby>;
+ status = "okay";
+};
+
+&i2c1 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c1>;
+ status = "okay";
+
+ pmic: pfuze100@08 {
+ compatible = "fsl,pfuze200";
+ reg = <0x08>;
+
+ regulators {
+ sw1a_reg: sw1ab {
+ regulator-min-microvolt = <300000>;
+ regulator-max-microvolt = <1875000>;
+ regulator-boot-on;
+ regulator-always-on;
+ regulator-ramp-delay = <6250>;
+ };
+
+ sw2_reg: sw2 {
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ sw3a_reg: sw3a {
+ regulator-min-microvolt = <400000>;
+ regulator-max-microvolt = <1975000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ sw3b_reg: sw3b {
+ regulator-min-microvolt = <400000>;
+ regulator-max-microvolt = <1975000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ swbst_reg: swbst {
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5150000>;
+ };
+
+ snvs_reg: vsnvs {
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ vref_reg: vrefddr {
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ vgen1_reg: vgen1 {
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1550000>;
+ regulator-always-on;
+ };
+
+ vgen2_reg: vgen2 {
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1550000>;
+ };
+
+ vgen3_reg: vgen3 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ vgen4_reg: vgen4 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ vgen5_reg: vgen5 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ vgen6_reg: vgen6 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+ };
+ };
+
+ ov5640: ov5640@3c {
+ compatible = "ovti,ov5640";
+ reg = <0x3c>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_csi_0>;
+ clocks = <&clks IMX6SX_CLK_CSI>;
+ clock-names = "csi_mclk";
+ AVDD-supply = <&vgen3_reg>; /* 2.8v */
+ DVDD-supply = <&vgen2_reg>; /* 1.5v*/
+ pwn-gpios = <&gpio3 28 1>;
+ rst-gpios = <&gpio3 27 0>;
+ csi_id = <0>;
+ mclk = <24000000>;
+ mclk_source = <0>;
+ port {
+ ov5640_ep: endpoint {
+ remote-endpoint = <&csi1_ep>;
+ };
+ };
+ };
+
+ sii902x@39 {
+ compatible = "SiI,sii902x";
+ interrupt-parent = <&gpio4>;
+ interrupts = <21 2>;
+ mode_str ="1280x720M@60";
+ bits-per-pixel = <16>;
+ resets = <&sii902x_reset>;
+ reg = <0x39>;
+ status = "disabled";
+ };
+};
+
+&i2c2 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c2>;
+ status = "okay";
+
+ egalax_ts@04 {
+ compatible = "eeti,egalax_ts";
+ reg = <0x04>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_egalax_int>;
+ interrupt-parent = <&gpio4>;
+ interrupts = <19 2>;
+ wakeup-gpios = <&gpio4 19 GPIO_ACTIVE_HIGH>;
+ };
+};
+
&i2c3 {
clock-frequency = <100000>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_i2c3>;
status = "okay";
+
+ isl29023@44 {
+ compatible = "fsl,isl29023";
+ reg = <0x44>;
+ rext = <499>;
+ interrupt-parent = <&gpio6>;
+ interrupts = <5 1>;
+ shared-interrupt;
+ };
+
+ mag3110@0e {
+ compatible = "fsl,mag3110";
+ reg = <0x0e>;
+ position = <2>;
+ interrupt-parent = <&gpio6>;
+ interrupts = <5 1>;
+ shared-interrupt;
+ };
+
+ mma8451@1c {
+ compatible = "fsl,mma8451";
+ reg = <0x1c>;
+ position = <1>;
+ interrupt-parent = <&gpio6>;
+ interrupts = <2 8>;
+ interrupt-route = <2>;
+ };
};
&i2c4 {
@@ -209,6 +517,7 @@
PLLVDD-supply = <&vgen4_reg>;
SPKVDD1-supply = <&reg_psu_5v>;
SPKVDD2-supply = <&reg_psu_5v>;
+ amic-mono;
};
};
@@ -217,9 +526,9 @@
pinctrl-0 = <&pinctrl_lcd>;
lcd-supply = <&reg_lcd_3v3>;
display = <&display0>;
- status = "okay";
+ status = "disabled";
- display0: display0 {
+ display0: display@0 {
bits-per-pixel = <16>;
bus-width = <24>;
@@ -244,12 +553,62 @@
};
};
+&pcie {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pcie>;
+ reset-gpio = <&gpio2 0 0>;
+ status = "okay";
+};
+
+&lcdif2 {
+ display = <&display1>;
+ disp-dev = "ldb";
+ status = "okay";
+ display1: display@1 {
+ bits-per-pixel = <16>;
+ bus-width = <18>;
+ };
+};
+&ldb {
+ status = "okay";
+ lvds-channel@0 {
+ fsl,data-mapping = "spwg";
+ fsl,data-width = <18>;
+ crtc = "lcdif2";
+ status = "okay";
+ display-timings {
+ native-mode = <&timing1>;
+ timing1: hsd100pxn1 {
+ clock-frequency = <65000000>;
+ hactive = <1024>;
+ vactive = <768>;
+ hback-porch = <220>;
+ hfront-porch = <40>;
+ vback-porch = <21>;
+ vfront-porch = <7>;
+ hsync-len = <60>;
+ vsync-len = <10>;
+ };
+ };
+ };
+};
+
&pwm3 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_pwm3>;
status = "okay";
};
+&pwm4 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pwm4>;
+ status = "okay";
+};
+
+&pxp {
+ status = "okay";
+};
+
&snvs_poweroff {
status = "okay";
};
@@ -260,7 +619,20 @@
status = "disabled";
};
+&spdif {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_spdif>;
+ status = "okay";
+};
+
&ssi2 {
+ assigned-clocks = <&clks IMX6SX_CLK_PLL4>,
+ <&clks IMX6SX_PLL4_BYPASS>,
+ <&clks IMX6SX_CLK_SSI2_SEL>;
+ assigned-clock-parents = <&clks IMX6SX_CLK_OSC>,
+ <&clks IMX6SX_CLK_PLL4>,
+ <&clks IMX6SX_CLK_PLL4_AUDIO_DIV>;
+ assigned-clock-rates = <737280000>, <0>, <0>;
status = "okay";
};
@@ -275,12 +647,18 @@
pinctrl-0 = <&pinctrl_uart5>;
uart-has-rtscts;
status = "okay";
+ /* for DTE mode, add below change */
+ /* fsl,dte-mode;*/
+ /* pinctrl-0 = <&pinctrl_uart5dte_1>; */
};
&usbotg1 {
vbus-supply = <&reg_usb_otg1_vbus>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_usb_otg1_id>;
+ srp-disable;
+ hnp-disable;
+ adp-disable;
status = "okay";
};
@@ -337,7 +715,25 @@
};
&iomuxc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_hog &pinctrl_can_gpios>;
+
imx6x-sdb {
+ pinctrl_hog: hoggrp {
+ fsl,pins = <
+ MX6SX_PAD_SD1_DATA0__GPIO6_IO_2 0x17059
+ MX6SX_PAD_SD1_DATA3__GPIO6_IO_5 0xb000
+ MX6SX_PAD_CSI_DATA03__GPIO1_IO_17 0x17059
+ >;
+ };
+
+ pinctrl_can_gpios: can-gpios {
+ fsl,pins = <
+ MX6SX_PAD_QSPI1B_DATA1__GPIO4_IO_25 0x17059
+ MX6SX_PAD_QSPI1B_DATA3__GPIO4_IO_27 0x17059
+ >;
+ };
+
pinctrl_audmux: audmuxgrp {
fsl,pins = <
MX6SX_PAD_CSI_DATA00__AUDMUX_AUD6_TXC 0x130b0
@@ -348,11 +744,38 @@
>;
};
+ pinctrl_csi_0: csigrp-0 {
+ fsl,pins = <
+ MX6SX_PAD_LCD1_DATA07__CSI1_MCLK 0x110b0
+ MX6SX_PAD_LCD1_DATA06__CSI1_PIXCLK 0x110b0
+ MX6SX_PAD_LCD1_DATA04__CSI1_VSYNC 0x110b0
+ MX6SX_PAD_LCD1_DATA05__CSI1_HSYNC 0x110b0
+ MX6SX_PAD_LCD1_DATA17__CSI1_DATA_0 0x110b0
+ MX6SX_PAD_LCD1_DATA16__CSI1_DATA_1 0x110b0
+ MX6SX_PAD_LCD1_DATA15__CSI1_DATA_2 0x110b0
+ MX6SX_PAD_LCD1_DATA14__CSI1_DATA_3 0x110b0
+ MX6SX_PAD_LCD1_DATA13__CSI1_DATA_4 0x110b0
+ MX6SX_PAD_LCD1_DATA12__CSI1_DATA_5 0x110b0
+ MX6SX_PAD_LCD1_DATA11__CSI1_DATA_6 0x110b0
+ MX6SX_PAD_LCD1_DATA10__CSI1_DATA_7 0x110b0
+ MX6SX_PAD_LCD1_DATA09__CSI1_DATA_8 0x110b0
+ MX6SX_PAD_LCD1_DATA08__CSI1_DATA_9 0x110b0
+ MX6SX_PAD_LCD1_RESET__GPIO3_IO_27 0x80000000
+ MX6SX_PAD_LCD1_VSYNC__GPIO3_IO_28 0x80000000
+ >;
+ };
+
+ pinctrl_egalax_int: egalax_intgrp {
+ fsl,pins = <
+ MX6SX_PAD_QSPI1A_DATA3__GPIO4_IO_19 0x80000000
+ >;
+ };
+
pinctrl_enet1: enet1grp {
fsl,pins = <
MX6SX_PAD_ENET1_MDIO__ENET1_MDIO 0xa0b1
MX6SX_PAD_ENET1_MDC__ENET1_MDC 0xa0b1
- MX6SX_PAD_RGMII1_TXC__ENET1_RGMII_TXC 0xa0b1
+ MX6SX_PAD_RGMII1_TXC__ENET1_RGMII_TXC 0xa0b9
MX6SX_PAD_RGMII1_TD0__ENET1_TX_DATA_0 0xa0b1
MX6SX_PAD_RGMII1_TD1__ENET1_TX_DATA_1 0xa0b1
MX6SX_PAD_RGMII1_TD2__ENET1_TX_DATA_2 0xa0b1
@@ -391,6 +814,20 @@
>;
};
+ pinctrl_flexcan1: flexcan1grp {
+ fsl,pins = <
+ MX6SX_PAD_QSPI1B_DQS__CAN1_TX 0x1b020
+ MX6SX_PAD_QSPI1A_SS1_B__CAN1_RX 0x1b020
+ >;
+ };
+
+ pinctrl_flexcan2: flexcan2grp {
+ fsl,pins = <
+ MX6SX_PAD_QSPI1B_SS1_B__CAN2_RX 0x1b020
+ MX6SX_PAD_QSPI1A_DQS__CAN2_TX 0x1b020
+ >;
+ };
+
pinctrl_gpio_keys: gpio_keysgrp {
fsl,pins = <
MX6SX_PAD_CSI_DATA04__GPIO1_IO_18 0x17059
@@ -405,6 +842,13 @@
>;
};
+ pinctrl_i2c2: i2c2grp {
+ fsl,pins = <
+ MX6SX_PAD_GPIO1_IO03__I2C2_SDA 0x4001b8b1
+ MX6SX_PAD_GPIO1_IO02__I2C2_SCL 0x4001b8b1
+ >;
+ };
+
pinctrl_i2c3: i2c3grp {
fsl,pins = <
MX6SX_PAD_KEY_ROW4__I2C3_SDA 0x4001b8b1
@@ -453,6 +897,25 @@
>;
};
+ pinctrl_mqs: mqsgrp {
+ fsl,pins = <
+ MX6SX_PAD_SD2_CLK__MQS_RIGHT 0x120b0
+ MX6SX_PAD_SD2_CMD__MQS_LEFT 0x120b0
+ >;
+ };
+
+ pinctrl_pcie: pciegrp {
+ fsl,pins = <
+ MX6SX_PAD_ENET1_COL__GPIO2_IO_0 0x10b0
+ >;
+ };
+
+ pinctrl_pcie_reg: pciereggrp {
+ fsl,pins = <
+ MX6SX_PAD_ENET1_CRS__GPIO2_IO_1 0x10b0
+ >;
+ };
+
pinctrl_peri_3v3: peri3v3grp {
fsl,pins = <
MX6SX_PAD_QSPI1A_DATA0__GPIO4_IO_16 0x80000000
@@ -465,6 +928,12 @@
>;
};
+ pinctrl_pwm4: pwm4grp-1 {
+ fsl,pins = <
+ MX6SX_PAD_SD1_DATA1__PWM4_OUT 0x110b0
+ >;
+ };
+
pinctrl_qspi2: qspi2grp {
fsl,pins = <
MX6SX_PAD_NAND_WP_B__QSPI2_A_DATA_0 0x70f1
@@ -482,6 +951,12 @@
>;
};
+ pinctrl_spdif: spdifgrp {
+ fsl,pins = <
+ MX6SX_PAD_SD4_DATA4__SPDIF_OUT 0x1b0b0
+ >;
+ };
+
pinctrl_vcc_sd3: vccsd3grp {
fsl,pins = <
MX6SX_PAD_KEY_COL1__GPIO2_IO_11 0x17059
@@ -514,6 +989,15 @@
>;
};
+ pinctrl_uart5dte_1: uart5dtegrp-1 {
+ fsl,pins = <
+ MX6SX_PAD_KEY_ROW3__UART5_TX 0x1b0b1
+ MX6SX_PAD_KEY_COL3__UART5_RX 0x1b0b1
+ MX6SX_PAD_KEY_ROW2__UART5_RTS_B 0x1b0b1
+ MX6SX_PAD_KEY_COL2__UART5_CTS_B 0x1b0b1
+ >;
+ };
+
pinctrl_usb_otg1: usbotg1grp {
fsl,pins = <
MX6SX_PAD_GPIO1_IO09__GPIO1_IO_9 0x10b0
@@ -545,16 +1029,16 @@
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_SD3_CMD__USDHC3_CMD 0x17069
+ MX6SX_PAD_SD3_CLK__USDHC3_CLK 0x10071
+ MX6SX_PAD_SD3_DATA0__USDHC3_DATA0 0x17069
+ MX6SX_PAD_SD3_DATA1__USDHC3_DATA1 0x17069
+ MX6SX_PAD_SD3_DATA2__USDHC3_DATA2 0x17069
+ MX6SX_PAD_SD3_DATA3__USDHC3_DATA3 0x17069
+ MX6SX_PAD_SD3_DATA4__USDHC3_DATA4 0x17069
+ MX6SX_PAD_SD3_DATA5__USDHC3_DATA5 0x17069
+ MX6SX_PAD_SD3_DATA6__USDHC3_DATA6 0x17069
+ MX6SX_PAD_SD3_DATA7__USDHC3_DATA7 0x17069
MX6SX_PAD_KEY_COL0__GPIO2_IO_10 0x17059 /* CD */
MX6SX_PAD_KEY_ROW0__GPIO2_IO_15 0x17059 /* WP */
>;
@@ -603,6 +1087,51 @@
>;
};
+ pinctrl_usdhc4_1: usdhc4grp-1 {
+ 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_DATA4__USDHC4_DATA4 0x17059
+ MX6SX_PAD_SD4_DATA5__USDHC4_DATA5 0x17059
+ MX6SX_PAD_SD4_DATA6__USDHC4_DATA6 0x17059
+ MX6SX_PAD_SD4_DATA7__USDHC4_DATA7 0x17059
+ >;
+ };
+
+ pinctrl_usdhc4_1_100mhz: usdhc4grp-1-100mhz {
+ fsl,pins = <
+ MX6SX_PAD_SD4_CMD__USDHC4_CMD 0x170b9
+ MX6SX_PAD_SD4_CLK__USDHC4_CLK 0x100b9
+ MX6SX_PAD_SD4_DATA0__USDHC4_DATA0 0x170b9
+ MX6SX_PAD_SD4_DATA1__USDHC4_DATA1 0x170b9
+ MX6SX_PAD_SD4_DATA2__USDHC4_DATA2 0x170b9
+ MX6SX_PAD_SD4_DATA3__USDHC4_DATA3 0x170b9
+ MX6SX_PAD_SD4_DATA4__USDHC4_DATA4 0x170b9
+ MX6SX_PAD_SD4_DATA5__USDHC4_DATA5 0x170b9
+ MX6SX_PAD_SD4_DATA6__USDHC4_DATA6 0x170b9
+ MX6SX_PAD_SD4_DATA7__USDHC4_DATA7 0x170b9
+ >;
+ };
+
+ pinctrl_usdhc4_1_200mhz: usdhc4grp-1-200mhz {
+ fsl,pins = <
+ MX6SX_PAD_SD4_CMD__USDHC4_CMD 0x170f9
+ MX6SX_PAD_SD4_CLK__USDHC4_CLK 0x100f9
+ MX6SX_PAD_SD4_DATA0__USDHC4_DATA0 0x170f9
+ MX6SX_PAD_SD4_DATA1__USDHC4_DATA1 0x170f9
+ MX6SX_PAD_SD4_DATA2__USDHC4_DATA2 0x170f9
+ MX6SX_PAD_SD4_DATA3__USDHC4_DATA3 0x170f9
+ MX6SX_PAD_SD4_DATA4__USDHC4_DATA4 0x170f9
+ MX6SX_PAD_SD4_DATA5__USDHC4_DATA5 0x170f9
+ MX6SX_PAD_SD4_DATA6__USDHC4_DATA6 0x170f9
+ MX6SX_PAD_SD4_DATA7__USDHC4_DATA7 0x170f9
+ >;
+ };
+
pinctrl_wdog: wdoggrp {
fsl,pins = <
MX6SX_PAD_GPIO1_IO13__WDOG1_WDOG_ANY 0x30b0
@@ -610,3 +1139,14 @@
};
};
};
+
+&vadc {
+ vadc_in = <0>;
+ csi_id = <1>;
+ status = "okay";
+ port {
+ vadc_ep: endpoint {
+ remote-endpoint = <&csi2_ep>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/imx6sx.dtsi b/arch/arm/boot/dts/imx6sx.dtsi
index 61ad4e296257..d6d218306bf1 100644
--- a/arch/arm/boot/dts/imx6sx.dtsi
+++ b/arch/arm/boot/dts/imx6sx.dtsi
@@ -1,5 +1,6 @@
/*
- * Copyright 2014 Freescale Semiconductor, Inc.
+ * Copyright 2014-2016 Freescale Semiconductor, Inc.
+ * Copyright 2018 NXP
*
* 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
@@ -57,6 +58,8 @@
spi4 = &ecspi5;
usbphy0 = &usbphy1;
usbphy1 = &usbphy2;
+ lcdif0 = &lcdif1;
+ lcdif1 = &lcdif2;
};
cpus {
@@ -87,14 +90,32 @@
<&clks IMX6SX_CLK_PLL2_PFD2>,
<&clks IMX6SX_CLK_STEP>,
<&clks IMX6SX_CLK_PLL1_SW>,
- <&clks IMX6SX_CLK_PLL1_SYS>;
+ <&clks IMX6SX_CLK_PLL1_SYS>,
+ <&clks IMX6SX_CLK_PLL1>,
+ <&clks IMX6SX_PLL1_BYPASS>,
+ <&clks IMX6SX_PLL1_BYPASS_SRC>;
clock-names = "arm", "pll2_pfd2_396m", "step",
- "pll1_sw", "pll1_sys";
+ "pll1_sw", "pll1_sys", "pll1",
+ "pll1_bypass", "pll1_bypass_src";
arm-supply = <&reg_arm>;
soc-supply = <&reg_soc>;
};
};
+ reserved-memory {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ /* global autoconfigured region for contiguous allocations */
+ linux,cma {
+ compatible = "shared-dma-pool";
+ reusable;
+ size = <0x14000000>;
+ linux,cma-default;
+ };
+ };
+
intc: interrupt-controller@00a01000 {
compatible = "arm,cortex-a9-gic";
#interrupt-cells = <3>;
@@ -148,17 +169,66 @@
interrupt-parent = <&gpc>;
ranges;
+ busfreq {
+ compatible = "fsl,imx_busfreq";
+ clocks = <&clks IMX6SX_CLK_PLL2_BUS>, <&clks IMX6SX_CLK_PLL2_PFD2>,
+ <&clks IMX6SX_CLK_PLL2_198M>, <&clks IMX6SX_CLK_ARM>,
+ <&clks IMX6SX_CLK_PLL3_USB_OTG>, <&clks IMX6SX_CLK_PERIPH>,
+ <&clks IMX6SX_CLK_PERIPH_PRE>, <&clks IMX6SX_CLK_PERIPH_CLK2>,
+ <&clks IMX6SX_CLK_PERIPH_CLK2_SEL>, <&clks IMX6SX_CLK_OSC>,
+ <&clks IMX6SX_CLK_PLL1_SYS>, <&clks IMX6SX_CLK_PERIPH2>,
+ <&clks IMX6SX_CLK_AHB>, <&clks IMX6SX_CLK_OCRAM_PODF>,
+ <&clks IMX6SX_CLK_PLL1_SW>, <&clks IMX6SX_CLK_PERIPH2_PRE>,
+ <&clks IMX6SX_CLK_PERIPH2_CLK2_SEL>, <&clks IMX6SX_CLK_PERIPH2_CLK2>,
+ <&clks IMX6SX_CLK_STEP>, <&clks IMX6SX_CLK_MMDC_PODF>,
+ <&clks IMX6SX_CLK_M4>;
+ clock-names = "pll2_bus", "pll2_pfd2_396m", "pll2_198m", "arm",
+ "pll3_usb_otg", "periph", "periph_pre", "periph_clk2",
+ "periph_clk2_sel", "osc", "pll1_sys", "periph2",
+ "ahb", "ocram", "pll1_sw", "periph2_pre",
+ "periph2_clk2_sel", "periph2_clk2", "step", "mmdc",
+ "m4";
+ fsl,max_ddr_freq = <400000000>;
+ };
+
pmu {
compatible = "arm,cortex-a9-pmu";
interrupts = <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH>;
};
- ocram: sram@00900000 {
+ ocrams: sram@008f8000 {
+ compatible = "fsl,lpm-sram";
+ reg = <0x008f8000 0x4000>;
+ clocks = <&clks IMX6SX_CLK_OCRAM_S>;
+ };
+
+ ocrams_ddr: sram@00900000 {
+ compatible = "fsl,ddr-lpm-sram";
+ reg = <0x00900000 0x1000>;
+ clocks = <&clks IMX6SX_CLK_OCRAM>;
+ };
+
+ ocram: sram@00901000 {
compatible = "mmio-sram";
+ reg = <0x00901000 0x1F000>;
+ clocks = <&clks IMX6SX_CLK_OCRAM>;
+ };
+
+ ocram_mf: sram-mf@00900000 {
+ compatible = "fsl,mega-fast-sram";
reg = <0x00900000 0x20000>;
clocks = <&clks IMX6SX_CLK_OCRAM>;
};
+ ocram_optee {
+ compatible = "fsl,optee-lpm-sram";
+ reg = <0x008f8000 0x4000>;
+ overw_reg = <&ocrams_ddr 0x00904000 0x1000>,
+ <&ocram 0x00905000 0x1b000>,
+ <&ocrams 0x00900000 0x4000>;
+ overw_clock = <&ocrams &clks IMX6SX_CLK_OCRAM>;
+ };
+
L2: l2-cache@00a02000 {
compatible = "arm,pl310-cache";
reg = <0x00a02000 0x1000>;
@@ -192,6 +262,37 @@
clocks = <&clks IMX6SX_CLK_APBH_DMA>;
};
+ caam_sm: caam-sm@00100000 {
+ compatible = "fsl,imx6q-caam-sm";
+ reg = <0x00100000 0x8000>;
+ };
+
+ irq_sec_vio: caam_secvio {
+ compatible = "fsl,imx6q-caam-secvio";
+ interrupts = <0 20 0x04>;
+ secvio_src = <0x8000001d>;
+ jtag-tamper = "disabled";
+ watchdog-tamper = "enabled";
+ internal-boot-tamper = "enabled";
+ external-pin-tamper = "disabled";
+ };
+
+ gpu3d: gpu3d@01800000 {
+ compatible = "fsl,imx6sx-gpu", "fsl,imx6q-gpu";
+ reg = <0x01800000 0x4000>, <0x80000000 0x0>,
+ <0x0 0x8000000>;
+ reg-names = "iobase_3d", "phys_baseaddr", "contiguous_mem";
+ interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "irq_3d";
+ clocks = <&clks IMX6SX_CLK_GPU_AXI_PODF>, <&clks IMX6SX_CLK_GPU>,
+ <&clks 0>;
+ clock-names = "gpu3d_axi_clk", "gpu3d_clk",
+ "gpu3d_shader_clk";
+ resets = <&src 0>;
+ reset-names = "gpu3d";
+ power-domains = <&pd_pu>;
+ };
+
gpmi: gpmi-nand@01806000{
compatible = "fsl,imx6sx-gpmi-nand";
#address-cells = <1>;
@@ -257,6 +358,8 @@
clocks = <&clks IMX6SX_CLK_ECSPI1>,
<&clks IMX6SX_CLK_ECSPI1>;
clock-names = "ipg", "per";
+ dmas = <&sdma 3 7 1>, <&sdma 4 7 2>;
+ dma-names = "rx", "tx";
status = "disabled";
};
@@ -269,6 +372,8 @@
clocks = <&clks IMX6SX_CLK_ECSPI2>,
<&clks IMX6SX_CLK_ECSPI2>;
clock-names = "ipg", "per";
+ dmas = <&sdma 5 7 1>, <&sdma 6 7 2>;
+ dma-names = "rx", "tx";
status = "disabled";
};
@@ -281,6 +386,8 @@
clocks = <&clks IMX6SX_CLK_ECSPI3>,
<&clks IMX6SX_CLK_ECSPI3>;
clock-names = "ipg", "per";
+ dmas = <&sdma 7 7 1>, <&sdma 8 7 2>;
+ dma-names = "rx", "tx";
status = "disabled";
};
@@ -293,6 +400,8 @@
clocks = <&clks IMX6SX_CLK_ECSPI4>,
<&clks IMX6SX_CLK_ECSPI4>;
clock-names = "ipg", "per";
+ dmas = <&sdma 9 7 1>, <&sdma 10 7 2>;
+ dma-names = "rx", "tx";
status = "disabled";
};
@@ -310,6 +419,7 @@
};
esai: esai@02024000 {
+ compatible = "fsl,imx35-esai";
reg = <0x02024000 0x4000>;
interrupts = <GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clks IMX6SX_CLK_ESAI_IPG>,
@@ -319,6 +429,9 @@
<&clks IMX6SX_CLK_SPBA>;
clock-names = "core", "mem", "extal",
"fsys", "spba";
+ dmas = <&sdma 23 21 0>,
+ <&sdma 24 21 0>;
+ dma-names = "rx", "tx";
status = "disabled";
};
@@ -330,7 +443,7 @@
clocks = <&clks IMX6SX_CLK_SSI1_IPG>,
<&clks IMX6SX_CLK_SSI1>;
clock-names = "ipg", "baud";
- dmas = <&sdma 37 1 0>, <&sdma 38 1 0>;
+ dmas = <&sdma 37 26 0>, <&sdma 38 26 0>;
dma-names = "rx", "tx";
fsl,fifo-depth = <15>;
status = "disabled";
@@ -344,7 +457,7 @@
clocks = <&clks IMX6SX_CLK_SSI2_IPG>,
<&clks IMX6SX_CLK_SSI2>;
clock-names = "ipg", "baud";
- dmas = <&sdma 41 1 0>, <&sdma 42 1 0>;
+ dmas = <&sdma 41 26 0>, <&sdma 42 26 0>;
dma-names = "rx", "tx";
fsl,fifo-depth = <15>;
status = "disabled";
@@ -358,25 +471,34 @@
clocks = <&clks IMX6SX_CLK_SSI3_IPG>,
<&clks IMX6SX_CLK_SSI3>;
clock-names = "ipg", "baud";
- dmas = <&sdma 45 1 0>, <&sdma 46 1 0>;
+ dmas = <&sdma 45 26 0>, <&sdma 46 26 0>;
dma-names = "rx", "tx";
fsl,fifo-depth = <15>;
status = "disabled";
};
asrc: asrc@02034000 {
+ compatible = "fsl,imx53-asrc";
reg = <0x02034000 0x4000>;
interrupts = <GIC_SPI 50 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&clks IMX6SX_CLK_ASRC_MEM>,
- <&clks IMX6SX_CLK_ASRC_IPG>,
- <&clks IMX6SX_CLK_SPDIF>,
- <&clks IMX6SX_CLK_SPBA>;
- clock-names = "mem", "ipg", "asrck", "spba";
- dmas = <&sdma 17 20 1>, <&sdma 18 20 1>,
- <&sdma 19 20 1>, <&sdma 20 20 1>,
- <&sdma 21 20 1>, <&sdma 22 20 1>;
+ clocks = <&clks IMX6SX_CLK_ASRC_IPG>,
+ <&clks IMX6SX_CLK_ASRC_MEM>, <&clks 0>,
+ <&clks 0>, <&clks 0>, <&clks 0>, <&clks 0>,
+ <&clks 0>, <&clks 0>, <&clks 0>, <&clks 0>,
+ <&clks 0>, <&clks 0>, <&clks 0>, <&clks 0>,
+ <&clks IMX6SX_CLK_SPDIF>, <&clks 0>, <&clks 0>,
+ <&clks IMX6SX_CLK_SPBA>;
+ clock-names = "mem", "ipg", "asrck_0",
+ "asrck_1", "asrck_2", "asrck_3", "asrck_4",
+ "asrck_5", "asrck_6", "asrck_7", "asrck_8",
+ "asrck_9", "asrck_a", "asrck_b", "asrck_c",
+ "asrck_d", "asrck_e", "asrck_f", "spba";
+ dmas = <&sdma 17 23 1>, <&sdma 18 23 1>, <&sdma 19 23 1>,
+ <&sdma 20 23 1>, <&sdma 21 23 1>, <&sdma 22 23 1>;
dma-names = "rxa", "rxb", "rxc",
"txa", "txb", "txc";
+ fsl,asrc-rate = <48000>;
+ fsl,asrc-width = <16>;
status = "okay";
};
};
@@ -428,6 +550,7 @@
clocks = <&clks IMX6SX_CLK_CAN1_IPG>,
<&clks IMX6SX_CLK_CAN1_SERIAL>;
clock-names = "ipg", "per";
+ stop-mode = <&gpr 0x10 1 0x10 17>;
status = "disabled";
};
@@ -438,6 +561,7 @@
clocks = <&clks IMX6SX_CLK_CAN2_IPG>,
<&clks IMX6SX_CLK_CAN2_SERIAL>;
clock-names = "ipg", "per";
+ stop-mode = <&gpr 0x10 2 0x10 18>;
status = "disabled";
};
@@ -534,6 +658,12 @@
gpio-ranges = <&iomuxc 0 148 10>, <&iomuxc 10 169 2>;
};
+ mqs: mqs {
+ compatible = "fsl,imx6sx-mqs";
+ gpr = <&gpr>;
+ status = "disabled";
+ };
+
kpp: kpp@020b8000 {
compatible = "fsl,imx6sx-kpp", "fsl,imx21-kpp";
reg = <0x020b8000 0x4000>;
@@ -590,12 +720,11 @@
anatop-enable-bit = <0>;
};
- regulator-3p0 {
+ reg_3p0: regulator-3p0@120 {
compatible = "fsl,anatop-regulator";
regulator-name = "vdd3p0";
- regulator-min-microvolt = <2800000>;
- regulator-max-microvolt = <3150000>;
- regulator-always-on;
+ regulator-min-microvolt = <2625000>;
+ regulator-max-microvolt = <3400000>;
anatop-reg-offset = <0x120>;
anatop-vol-bit-shift = <8>;
anatop-vol-bit-width = <5>;
@@ -637,9 +766,9 @@
anatop-max-voltage = <1450000>;
};
- reg_pcie: regulator-vddpcie {
+ reg_pcie_phy: regulator-vddpcie-phy@140 {
compatible = "fsl,anatop-regulator";
- regulator-name = "vddpcie";
+ regulator-name = "vddpcie-phy";
regulator-min-microvolt = <725000>;
regulator-max-microvolt = <1450000>;
anatop-reg-offset = <0x140>;
@@ -684,6 +813,7 @@
reg = <0x020c9000 0x1000>;
interrupts = <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clks IMX6SX_CLK_USBPHY1>;
+ phy-3p0-supply = <&reg_3p0>;
fsl,anatop = <&anatop>;
};
@@ -692,9 +822,21 @@
reg = <0x020ca000 0x1000>;
interrupts = <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clks IMX6SX_CLK_USBPHY2>;
+ phy-3p0-supply = <&reg_3p0>;
fsl,anatop = <&anatop>;
};
+ usbphy_nop1: usbphy_nop1 {
+ compatible = "usb-nop-xceiv";
+ clocks = <&clks IMX6SX_CLK_USBPHY1>;
+ clock-names = "main_clk";
+ };
+
+ caam_snvs: caam-snvs@020cc000 {
+ compatible = "fsl,imx6q-caam-snvs";
+ reg = <0x020cc000 0x4000>;
+ };
+
snvs: snvs@020cc000 {
compatible = "fsl,sec-v4.0-mon", "syscon", "simple-mfd";
reg = <0x020cc000 0x4000>;
@@ -710,8 +852,8 @@
compatible = "syscon-poweroff";
regmap = <&snvs>;
offset = <0x38>;
- value = <0x60>;
- mask = <0x60>;
+ value = <0x61>;
+ mask = <0x61>;
status = "disabled";
};
@@ -749,6 +891,39 @@
#interrupt-cells = <3>;
interrupts = <GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH>;
interrupt-parent = <&intc>;
+ fsl,mf-mix-wakeup-irq = <0x7c00000 0x3d00 0x0 0x400240>;
+ clocks = <&clks IMX6SX_CLK_IPG>;
+ clock-names = "ipg";
+ pcie-phy-supply = <&reg_pcie_phy>;
+
+ pgc {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ power-domain@0 {
+ reg = <0>;
+ #power-domain-cells = <0>;
+ };
+
+ pd_pu: power-domain@1 {
+ reg = <1>;
+ #power-domain-cells = <0>;
+ power-supply = <&reg_soc>;
+ clocks = <&clks IMX6SX_CLK_GPU>;
+ };
+
+ pd_disp: power-domain@2 {
+ reg = <2>;
+ #power-domain-cells = <0>;
+ clocks = <&clks IMX6SX_CLK_PXP_AXI>,
+ <&clks IMX6SX_CLK_DISPLAY_AXI>,
+ <&clks IMX6SX_CLK_LCDIF1_PIX>,
+ <&clks IMX6SX_CLK_LCDIF_APB>,
+ <&clks IMX6SX_CLK_LCDIF2_PIX>,
+ <&clks IMX6SX_CLK_CSI>,
+ <&clks IMX6SX_CLK_VADC>;
+ };
+ };
};
iomuxc: iomuxc@020e0000 {
@@ -762,8 +937,32 @@
reg = <0x020e4000 0x4000>;
};
+ ldb: ldb@020e0014 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx6sx-ldb", "fsl,imx53-ldb";
+ gpr = <&gpr>;
+ status = "disabled";
+ clocks = <&clks IMX6SX_CLK_LDB_DI0>,
+ <&clks IMX6SX_CLK_LCDIF1_SEL>,
+ <&clks IMX6SX_CLK_LCDIF2_SEL>,
+ <&clks IMX6SX_CLK_LDB_DI0_DIV_3_5>,
+ <&clks IMX6SX_CLK_LDB_DI0_DIV_7>,
+ <&clks IMX6SX_CLK_LDB_DI0_DIV_SEL>;
+ clock-names = "ldb_di0",
+ "di0_sel",
+ "di1_sel",
+ "ldb_di0_div_3_5",
+ "ldb_di0_div_7",
+ "ldb_di0_div_sel";
+ lvds-channel@0 {
+ reg = <0>;
+ status = "disabled";
+ };
+ };
+
sdma: sdma@020ec000 {
- compatible = "fsl,imx6sx-sdma", "fsl,imx6q-sdma";
+ compatible = "fsl,imx6sx-sdma", "fsl,imx35-sdma";
reg = <0x020ec000 0x4000>;
interrupts = <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clks IMX6SX_CLK_IPG>,
@@ -784,18 +983,25 @@
crypto: caam@2100000 {
compatible = "fsl,sec-v4.0";
- fsl,sec-era = <4>;
#address-cells = <1>;
#size-cells = <1>;
- reg = <0x2100000 0x10000>;
- ranges = <0 0x2100000 0x10000>;
- interrupt-parent = <&intc>;
+ reg = <0x2100000 0x40000>;
+ ranges = <0 0x2100000 0x40000>;
clocks = <&clks IMX6SX_CLK_CAAM_MEM>,
<&clks IMX6SX_CLK_CAAM_ACLK>,
<&clks IMX6SX_CLK_CAAM_IPG>,
<&clks IMX6SX_CLK_EIM_SLOW>;
clock-names = "mem", "aclk", "ipg", "emi_slow";
+ sec_ctrl: ctrl@0 {
+ /* CAAM Page 0 only accessible */
+ /* by secure world */
+ compatible = "fsl,sec-v4.0-ctrl";
+ reg = <0x2100000 0x1000>;
+ secure-status = "okay";
+ status = "disabled";
+ };
+
sec_jr0: jr0@1000 {
compatible = "fsl,sec-v4.0-job-ring";
reg = <0x1000 0x1000>;
@@ -843,6 +1049,7 @@
clocks = <&clks IMX6SX_CLK_USBOH3>;
fsl,usbmisc = <&usbmisc 2>;
phy_type = "hsic";
+ fsl,usbphy = <&usbphy_nop1>;
fsl,anatop = <&anatop>;
dr_mode = "host";
ahb-burst-config = <0x0>;
@@ -872,15 +1079,20 @@
"enet_clk_ref", "enet_out";
fsl,num-tx-queues=<3>;
fsl,num-rx-queues=<3>;
+ stop-mode = <&gpr 0x10 3>;
+ fsl,wakeup_irq = <0>;
status = "disabled";
};
mlb: mlb@0218c000 {
+ compatible = "fsl,imx6sx-mlb50";
reg = <0x0218c000 0x4000>;
interrupts = <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 126 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clks IMX6SX_CLK_MLB>;
+ clock-names = "mlb";
+ iram = <&ocram>;
status = "disabled";
};
@@ -979,6 +1191,10 @@
<&clks IMX6SX_CLK_ENET_PTP>;
clock-names = "ipg", "ahb", "ptp",
"enet_clk_ref", "enet_out";
+ fsl,num-tx-queues=<3>;
+ fsl,num-rx-queues=<3>;
+ stop-mode = <&gpr 0x10 4>;
+ fsl,wakeup_irq = <0>;
status = "disabled";
};
@@ -994,21 +1210,28 @@
};
ocotp: ocotp@021bc000 {
- compatible = "fsl,imx6sx-ocotp", "syscon";
+ compatible = "fsl,imx6sx-ocotp", "fsl,imx6q-ocotp", "syscon";
reg = <0x021bc000 0x4000>;
clocks = <&clks IMX6SX_CLK_OCOTP>;
};
+ romcp@021ac000 {
+ compatible = "fsl,imx6sx-romcp", "syscon";
+ reg = <0x021ac000 0x4000>;
+ };
+
sai1: sai@021d4000 {
compatible = "fsl,imx6sx-sai";
reg = <0x021d4000 0x4000>;
interrupts = <GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clks IMX6SX_CLK_SAI1_IPG>,
+ <&clks IMX6SX_CLK_DUMMY>,
<&clks IMX6SX_CLK_SAI1>,
<&clks 0>, <&clks 0>;
- clock-names = "bus", "mclk1", "mclk2", "mclk3";
+ clock-names = "bus", "mclk0", "mclk1", "mclk2", "mclk3";
dma-names = "rx", "tx";
dmas = <&sdma 31 24 0>, <&sdma 32 24 0>;
+ dma-source = <&gpr 0 15 0 16>;
status = "disabled";
};
@@ -1023,9 +1246,10 @@
reg = <0x021dc000 0x4000>;
interrupts = <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clks IMX6SX_CLK_SAI2_IPG>,
+ <&clks IMX6SX_CLK_DUMMY>,
<&clks IMX6SX_CLK_SAI2>,
<&clks 0>, <&clks 0>;
- clock-names = "bus", "mclk1", "mclk2", "mclk3";
+ clock-names = "bus", "mclk0", "mclk1", "mclk2", "mclk3";
dma-names = "rx", "tx";
dmas = <&sdma 33 24 0>, <&sdma 34 24 0>;
status = "disabled";
@@ -1057,6 +1281,12 @@
status = "disabled";
};
+ qspi_m4: qspi-m4 {
+ compatible = "fsl,imx6sx-qspi-m4-restore";
+ reg = <0x021e4000 0x4000>;
+ status = "disabled";
+ };
+
uart2: serial@021e8000 {
compatible = "fsl,imx6sx-uart",
"fsl,imx6q-uart", "fsl,imx21-uart";
@@ -1118,6 +1348,11 @@
clocks = <&clks IMX6SX_CLK_I2C4>;
status = "disabled";
};
+
+ qosc: qosc@021fc000 {
+ compatible = "fsl,imx6sx-qosc";
+ reg = <0x021fc000 0x4000>;
+ };
};
aips3: aips-bus@02200000 {
@@ -1135,31 +1370,57 @@
ranges;
csi1: csi@02214000 {
+ compatible = "fsl,imx6s-csi";
reg = <0x02214000 0x4000>;
interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clks IMX6SX_CLK_DISPLAY_AXI>,
<&clks IMX6SX_CLK_CSI>,
<&clks IMX6SX_CLK_DCIC1>;
- clock-names = "disp-axi", "csi_mclk", "dcic";
+ clock-names = "disp-axi", "csi_mclk", "disp_dcic";
+ status = "disabled";
+ };
+
+ dcic1: dcic@0220c000 {
+ compatible = "fsl,imx6sx-dcic";
+ reg = <0x0220c000 0x4000>;
+ interrupts = <0 124 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SX_CLK_DCIC1>,
+ <&clks IMX6SX_CLK_DISPLAY_AXI>;
+ clock-names = "dcic", "disp-axi";
+ gpr = <&gpr>;
+ status = "disabled";
+ };
+
+ dcic2: dcic@02210000 {
+ compatible = "fsl,imx6sx-dcic";
+ reg = <0x02210000 0x4000>;
+ interrupts = <0 125 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SX_CLK_DCIC2>,
+ <&clks IMX6SX_CLK_DISPLAY_AXI>;
+ clock-names = "dcic", "disp-axi";
+ gpr = <&gpr>;
status = "disabled";
};
pxp: pxp@02218000 {
+ compatible = "fsl,imx6sx-pxp-dma", "fsl,imx6sl-pxp-dma", "fsl,imx6dl-pxp-dma";
reg = <0x02218000 0x4000>;
interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clks IMX6SX_CLK_PXP_AXI>,
<&clks IMX6SX_CLK_DISPLAY_AXI>;
clock-names = "pxp-axi", "disp-axi";
+ power-domains = <&pd_disp>;
status = "disabled";
};
csi2: csi@0221c000 {
+ compatible = "fsl,imx6s-csi";
reg = <0x0221c000 0x4000>;
interrupts = <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clks IMX6SX_CLK_DISPLAY_AXI>,
<&clks IMX6SX_CLK_CSI>,
<&clks IMX6SX_CLK_DCIC2>;
- clock-names = "disp-axi", "csi_mclk", "dcic";
+ clock-names = "disp-axi", "csi_mclk", "disp_dcic";
status = "disabled";
};
@@ -1171,6 +1432,7 @@
<&clks IMX6SX_CLK_LCDIF_APB>,
<&clks IMX6SX_CLK_DISPLAY_AXI>;
clock-names = "pix", "axi", "disp_axi";
+ power-domains = <&pd_disp>;
status = "disabled";
};
@@ -1182,15 +1444,19 @@
<&clks IMX6SX_CLK_LCDIF_APB>,
<&clks IMX6SX_CLK_DISPLAY_AXI>;
clock-names = "pix", "axi", "disp_axi";
+ power-domains = <&pd_disp>;
status = "disabled";
};
vadc: vadc@02228000 {
+ compatible = "fsl,imx6sx-vadc";
reg = <0x02228000 0x4000>, <0x0222c000 0x4000>;
reg-names = "vadc-vafe", "vadc-vdec";
clocks = <&clks IMX6SX_CLK_VADC>,
<&clks IMX6SX_CLK_CSI>;
clock-names = "vadc", "csi";
+ power-domains = <&pd_disp>;
+ gpr = <&gpr>;
status = "disabled";
};
};
@@ -1200,6 +1466,7 @@
reg = <0x02280000 0x4000>;
interrupts = <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clks IMX6SX_CLK_IPG>;
+ num-channels = <4>;
clock-names = "adc";
fsl,adck-max-frequency = <30000000>, <40000000>,
<20000000>;
@@ -1211,6 +1478,7 @@
reg = <0x02284000 0x4000>;
interrupts = <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clks IMX6SX_CLK_IPG>;
+ num-channels = <4>;
clock-names = "adc";
fsl,adck-max-frequency = <30000000>, <40000000>,
<20000000>;
@@ -1237,6 +1505,25 @@
status = "disabled";
};
+ sema4: sema4@02290000 { /* sema4 */
+ compatible = "fsl,imx6sx-sema4";
+ reg = <0x02290000 0x4000>;
+ interrupts = <0 116 0x04>;
+ status = "okay";
+ };
+
+ mu: mu@02294000 { /* mu */
+ compatible = "fsl,imx6sx-mu";
+ reg = <0x02294000 0x4000>;
+ interrupts = <0 90 0x04>;
+ status = "okay";
+ };
+
+ rpmsg: rpmsg{
+ compatible = "fsl,imx6sx-rpmsg";
+ status = "disabled";
+ };
+
uart6: serial@022a0000 {
compatible = "fsl,imx6sx-uart",
"fsl,imx6q-uart", "fsl,imx21-uart";
@@ -1293,12 +1580,12 @@
pcie: pcie@8ffc000 {
compatible = "fsl,imx6sx-pcie", "snps,dw-pcie";
- reg = <0x08ffc000 0x4000>; /* DBI */
+ reg = <0x08ffc000 0x4000>, <0x08f00000 0x80000>;
+ reg-names = "dbi", "config";
#address-cells = <3>;
#size-cells = <2>;
device_type = "pci";
- /* configuration space */
- ranges = <0x00000800 0 0x08f00000 0x08f00000 0 0x00080000
+ ranges = <
/* downstream I/O */
0x81000000 0 0 0x08f80000 0 0x00010000
/* non-prefetchable memory */
@@ -1306,12 +1593,21 @@
bus-range = <0x00 0xff>;
num-lanes = <1>;
interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&clks IMX6SX_CLK_PCIE_REF_125M>,
- <&clks IMX6SX_CLK_PCIE_AXI>,
+ interrupt-names = "msi";
+ #interrupt-cells = <1>;
+ interrupt-map-mask = <0 0 0 0x7>;
+ interrupt-map = <0 0 0 1 &intc GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>,
+ <0 0 0 2 &intc GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>,
+ <0 0 0 3 &intc GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>,
+ <0 0 0 4 &intc GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SX_CLK_PCIE_AXI>,
<&clks IMX6SX_CLK_LVDS1_OUT>,
+ <&clks IMX6SX_CLK_PCIE_REF_125M>,
<&clks IMX6SX_CLK_DISPLAY_AXI>;
- clock-names = "pcie_ref_125m", "pcie_axi",
- "lvds_gate", "display_axi";
+ clock-names = "pcie", "pcie_bus", "pcie_phy", "pcie_inbound_axi";
+ pcie-phy-supply = <&reg_pcie_phy>;
+ power-domains = <&pd_disp>;
+ fsl,max-link-speed = <2>;
status = "disabled";
};
};
diff --git a/arch/arm/boot/dts/imx6sxscm-1gb-evb-btwifi-ldo.dts b/arch/arm/boot/dts/imx6sxscm-1gb-evb-btwifi-ldo.dts
new file mode 100644
index 000000000000..a31c4d69bd0e
--- /dev/null
+++ b/arch/arm/boot/dts/imx6sxscm-1gb-evb-btwifi-ldo.dts
@@ -0,0 +1,10 @@
+/*
+ * Copyright (C) 2016 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 "imx6sxscm-1gb-evb-ldo.dts"
+#include "imx6sxscm-evb-btwifi.dtsi"
diff --git a/arch/arm/boot/dts/imx6sxscm-1gb-evb-lcdif1-ldo.dts b/arch/arm/boot/dts/imx6sxscm-1gb-evb-lcdif1-ldo.dts
new file mode 100644
index 000000000000..03ddbe9e6525
--- /dev/null
+++ b/arch/arm/boot/dts/imx6sxscm-1gb-evb-lcdif1-ldo.dts
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2016 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 "imx6sxscm-1gb-evb-ldo.dts"
+/ {
+ regulators {
+ reg_lcd_3v3: regulator@4 {
+ status = "okay";
+ };
+ };
+
+ sii902x_reset: sii902x-reset {
+ status = "okay";
+ };
+};
+
+&csi1 {
+ status = "disabled";
+};
+
+&lcdif1 {
+ status = "okay";
+};
+
+&i2c4 {
+ sii902x@39 {
+ status = "okay";
+ };
+};
+
+&ov5640 {
+ status = "disabled";
+};
+
+&crypto {
+ status = "disabled";
+};
diff --git a/arch/arm/boot/dts/imx6sxscm-1gb-evb-ldo.dts b/arch/arm/boot/dts/imx6sxscm-1gb-evb-ldo.dts
new file mode 100644
index 000000000000..357b92098318
--- /dev/null
+++ b/arch/arm/boot/dts/imx6sxscm-1gb-evb-ldo.dts
@@ -0,0 +1,9 @@
+/*
+ * Copyright (C) 2016 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 "imx6sxscm-evb-ldo.dts"
diff --git a/arch/arm/boot/dts/imx6sxscm-1gb-evb-m4-ldo.dts b/arch/arm/boot/dts/imx6sxscm-1gb-evb-m4-ldo.dts
new file mode 100644
index 000000000000..af0e8be603ed
--- /dev/null
+++ b/arch/arm/boot/dts/imx6sxscm-1gb-evb-m4-ldo.dts
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2016 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 "imx6sxscm-1gb-evb-ldo.dts"
+/{
+ memory {
+ linux,usable-memory = <0x80000000 0x1ff00000>,
+ <0xa0000000 0x1ff00000>;
+ };
+};
+
+&iomuxc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_hog>;
+};
+
+/*
+ * The flollowing modules are conflicting with M4, disable them when m4
+ * is running.
+ */
+&adc1 {
+ status = "disabled";
+};
+
+&adc2 {
+ status = "disabled";
+};
+
+&flexcan1 {
+ status = "disabled";
+};
+
+&flexcan2 {
+ status = "disabled";
+};
+
+&i2c3 {
+ status = "disabled";
+};
+
+&ocram {
+ reg = <0x00901000 0xf000>;
+};
+
+&qspi2 {
+ status = "disabled";
+};
+
+&qspi_m4 {
+ status = "okay";
+};
+
+&rpmsg{
+ vdev-nums = <1>;
+ reg = <0xbfff0000 0x10000>;
+ status = "okay";
+};
+
+&uart2 {
+ status = "disabled";
+};
+
+&clks {
+ fsl,shared-clks-number = <0x23>;
+ fsl,shared-clks-index = <IMX6SX_CLK_PLL2_BUS IMX6SX_CLK_PLL2_PFD0
+ IMX6SX_CLK_PLL2_PFD2 IMX6SX_CLK_PLL3_USB_OTG
+ IMX6SX_CLK_PLL3_PFD1 IMX6SX_CLK_PLL3_PFD2
+ IMX6SX_CLK_PLL3_PFD3 IMX6SX_CLK_PLL4_AUDIO
+ IMX6SX_CLK_PLL5_VIDEO
+ IMX6SX_CLK_OCRAM IMX6SX_CLK_CAN1_SERIAL
+ IMX6SX_CLK_CAN1_IPG IMX6SX_CLK_CAN2_SERIAL
+ IMX6SX_CLK_CAN2_IPG IMX6SX_CLK_CANFD
+ IMX6SX_CLK_ECSPI1 IMX6SX_CLK_ECSPI2
+ IMX6SX_CLK_ECSPI3 IMX6SX_CLK_ECSPI4
+ IMX6SX_CLK_ECSPI5 IMX6SX_CLK_QSPI1
+ IMX6SX_CLK_QSPI2 IMX6SX_CLK_SSI1
+ IMX6SX_CLK_SSI2 IMX6SX_CLK_SSI3
+ IMX6SX_CLK_UART_SERIAL IMX6SX_CLK_UART_IPG
+ IMX6SX_CLK_PERIPH_CLK2_SEL IMX6SX_CLK_DUMMY
+ IMX6SX_CLK_I2C1 IMX6SX_CLK_I2C2
+ IMX6SX_CLK_I2C3 IMX6SX_CLK_I2C4
+ IMX6SX_CLK_EPIT1 IMX6SX_CLK_EPIT2>;
+ fsl,shared-mem-addr = <0x91F000>;
+ fsl,shared-mem-size = <0x1000>;
+};
diff --git a/arch/arm/boot/dts/imx6sxscm-1gb-evb-mqs-ldo.dts b/arch/arm/boot/dts/imx6sxscm-1gb-evb-mqs-ldo.dts
new file mode 100644
index 000000000000..08aac2c6636f
--- /dev/null
+++ b/arch/arm/boot/dts/imx6sxscm-1gb-evb-mqs-ldo.dts
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2016 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 "imx6sxscm-1gb-evb-ldo.dts"
+/ {
+ sound-mqs {
+ compatible = "fsl,imx6sx-sdb-mqs",
+ "fsl,imx-audio-mqs";
+ model = "mqs-audio";
+ cpu-dai = <&sai1>;
+ asrc-controller = <&asrc>;
+ audio-codec = <&mqs>;
+ };
+};
+
+&usdhc2 {
+ /* pin conflict with mqs*/
+ status = "disabled";
+};
+
+&mqs {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_mqs>;
+ clocks = <&clks IMX6SX_CLK_SAI1>;
+ clock-names = "mclk";
+ status = "okay";
+};
+
+&sai1 {
+ pinctrl-0 = <>;
+ status = "okay";
+};
+
+&sdma {
+ gpr = <&gpr>;
+ /* SDMA event remap for SAI1 */
+ fsl,sdma-event-remap = <0 15 1>, <0 16 1>;
+};
diff --git a/arch/arm/boot/dts/imx6sxscm-1gb-evb-sai-ldo.dts b/arch/arm/boot/dts/imx6sxscm-1gb-evb-sai-ldo.dts
new file mode 100644
index 000000000000..d95d2e6f45c3
--- /dev/null
+++ b/arch/arm/boot/dts/imx6sxscm-1gb-evb-sai-ldo.dts
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2016 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 "imx6sxscm-1gb-evb-ldo.dts"
+/ {
+ sound {
+ cpu-dai = <&sai1>;
+ };
+};
+
+&audmux {
+ /* pin conflict with sai */
+ status = "disabled";
+};
+
+&sai1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_sai1>;
+ status = "okay";
+};
+
+&sdma {
+ gpr = <&gpr>;
+ /* SDMA event remap for SAI1 */
+ fsl,sdma-event-remap = <0 15 1>, <0 16 1>;
+};
diff --git a/arch/arm/boot/dts/imx6sxscm-512mb-evb-ldo.dts b/arch/arm/boot/dts/imx6sxscm-512mb-evb-ldo.dts
new file mode 100644
index 000000000000..f34b35802167
--- /dev/null
+++ b/arch/arm/boot/dts/imx6sxscm-512mb-evb-ldo.dts
@@ -0,0 +1,10 @@
+/*
+ * Copyright (C) 2016 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 "imx6sxscm-1gb-evb-ldo.dts"
+#include "imx6sxscm-512mb.dtsi"
diff --git a/arch/arm/boot/dts/imx6sxscm-512mb-evb-m4-ldo.dts b/arch/arm/boot/dts/imx6sxscm-512mb-evb-m4-ldo.dts
new file mode 100644
index 000000000000..240859445747
--- /dev/null
+++ b/arch/arm/boot/dts/imx6sxscm-512mb-evb-m4-ldo.dts
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2016 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 "imx6sxscm-1gb-evb-m4-ldo.dts"
+/{
+ memory {
+ linux,usable-memory = <0x80000000 0x1ff00000> ;
+ };
+};
+
+&rpmsg{
+ vdev-nums = <1>;
+ reg = <0x9FFF0000 0x10000>;
+};
diff --git a/arch/arm/boot/dts/imx6sxscm-512mb.dtsi b/arch/arm/boot/dts/imx6sxscm-512mb.dtsi
new file mode 100644
index 000000000000..023c997640bc
--- /dev/null
+++ b/arch/arm/boot/dts/imx6sxscm-512mb.dtsi
@@ -0,0 +1,14 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+/ {
+ memory {
+ reg = <0x80000000 0x20000000>;
+ };
+
+};
diff --git a/arch/arm/boot/dts/imx6sxscm-emmc.dtsi b/arch/arm/boot/dts/imx6sxscm-emmc.dtsi
new file mode 100644
index 000000000000..7e616f40ce51
--- /dev/null
+++ b/arch/arm/boot/dts/imx6sxscm-emmc.dtsi
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+&usdhc4 {
+ pinctrl-names = "default", "state_100mhz", "state_200mhz";
+ pinctrl-0 = <&pinctrl_usdhc4_1>;
+ pinctrl-1 = <&pinctrl_usdhc4_1_100mhz>;
+ pinctrl-2 = <&pinctrl_usdhc4_1_200mhz>;
+ bus-width = <8>;
+ no-1-8-v;
+ non-removable;
+ status = "okay";
+};
+
+&spdif {
+ status = "disabled";
+};
diff --git a/arch/arm/boot/dts/imx6sxscm-epop-evb-ldo.dts b/arch/arm/boot/dts/imx6sxscm-epop-evb-ldo.dts
new file mode 100644
index 000000000000..62bc1ff83776
--- /dev/null
+++ b/arch/arm/boot/dts/imx6sxscm-epop-evb-ldo.dts
@@ -0,0 +1,9 @@
+/*
+ * Copyright (C) 2016 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 "imx6sxscm-512mb-evb-ldo.dts"
+#include "imx6sxscm-emmc.dtsi"
diff --git a/arch/arm/boot/dts/imx6sxscm-epop-evb-m4-ldo.dts b/arch/arm/boot/dts/imx6sxscm-epop-evb-m4-ldo.dts
new file mode 100644
index 000000000000..ab6060283f92
--- /dev/null
+++ b/arch/arm/boot/dts/imx6sxscm-epop-evb-m4-ldo.dts
@@ -0,0 +1,9 @@
+/*
+ * Copyright (C) 2016 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 "imx6sxscm-512mb-evb-m4-ldo.dts"
+#include "imx6sxscm-emmc.dtsi"
diff --git a/arch/arm/boot/dts/imx6sxscm-evb-btwifi.dtsi b/arch/arm/boot/dts/imx6sxscm-evb-btwifi.dtsi
new file mode 100644
index 000000000000..36583898f5dc
--- /dev/null
+++ b/arch/arm/boot/dts/imx6sxscm-evb-btwifi.dtsi
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+/ {
+ modem_reset: modem-reset {
+ compatible = "gpio-reset";
+ reset-gpios = <&gpio4 9 GPIO_ACTIVE_LOW>;
+ reset-delay-us = <1000>;
+ #reset-cells = <0>;
+ };
+
+ regulators {
+ wlreg_on: fixedregulator@100 {
+ compatible = "regulator-fixed";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-name = "wlreg_on";
+ gpio = <&gpio4 8 0>;
+ startup-delay-us = <100>;
+ enable-active-high;
+ };
+ vcc_sd3: regulator@0 {
+ status = "disabled";
+ };
+
+ };
+
+ bcmdhd_wlan_0: bcmdhd_wlan@0 {
+ compatible = "android,bcmdhd_wlan";
+ wlreg_on-supply = <&wlreg_on>;
+ gpios = <&gpio7 9 0>; /* WL_HOST_WAKE */
+ };
+};
+
+&iomuxc {
+ imx6sxscm-evb-murata-v2_rc {
+ pinctrl_bt: btgrp {
+ fsl,pins = <
+ MX6SX_PAD_NAND_DATA05__GPIO4_IO_9 0x13069
+ >;
+ };
+
+ pinctrl_uart6: uart6grp {
+ fsl,pins = <
+ MX6SX_PAD_KEY_COL1__UART6_TX 0x1b0b1
+ MX6SX_PAD_KEY_ROW1__UART6_RX 0x1b0b1
+ MX6SX_PAD_KEY_COL0__UART6_RTS_B 0x1b0b1
+ MX6SX_PAD_KEY_ROW0__UART6_CTS_B 0x1b0b1
+ >;
+ };
+
+ pinctrl_usdhc3_1: usdhc3grp-1 {
+ fsl,pins = <
+ MX6SX_PAD_SD3_CMD__USDHC3_CMD 0x17069
+ MX6SX_PAD_SD3_CLK__USDHC3_CLK 0x10071
+ MX6SX_PAD_SD3_DATA0__USDHC3_DATA0 0x17069
+ MX6SX_PAD_SD3_DATA1__USDHC3_DATA1 0x17069
+ MX6SX_PAD_SD3_DATA2__USDHC3_DATA2 0x17069
+ MX6SX_PAD_SD3_DATA3__USDHC3_DATA3 0x17069
+ >;
+ };
+
+ pinctrl_usdhc3_1_100mhz: usdhc3grp-1-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
+ >;
+ };
+
+ pinctrl_usdhc3_1_200mhz: usdhc3grp-1-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
+ >;
+ };
+
+ /* For Murata, SD to 4-bit SDIO; use upper 4-bits for UART */
+ pinctrl_wifi: wifigrp {
+ fsl,pins = <
+ MX6SX_PAD_SD2_CMD__USDHC2_CMD 0x17069
+ MX6SX_PAD_SD2_CLK__USDHC2_CLK 0x10071
+ MX6SX_PAD_SD2_DATA0__USDHC2_DATA0 0x17069
+ MX6SX_PAD_SD2_DATA1__USDHC2_DATA1 0x17069
+ MX6SX_PAD_SD2_DATA2__USDHC2_DATA2 0x17069
+ MX6SX_PAD_SD2_DATA3__USDHC2_DATA3 0x17069
+ /* Murata Module control signals */
+ MX6SX_PAD_NAND_DATA04__GPIO4_IO_8 0x13069
+ MX6SX_PAD_SD3_DATA7__GPIO7_IO_9 0x13069
+ >;
+ };
+ };
+};
+
+&uart6 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart6
+ &pinctrl_bt>;
+ fsl,uart-has-rtscts;
+ resets = <&modem_reset>;
+ status = "okay";
+};
+
+&usdhc2 {
+ pinctrl-0 = <&pinctrl_wifi>;
+ bus-width = <4>;
+ non-removable;
+ cd-post;
+ pm-ignore-notify;
+};
+
+&usdhc3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usdhc3_1>;
+ pinctrl-1 = <&pinctrl_usdhc3_1_100mhz>;
+ pinctrl-2 = <&pinctrl_usdhc3_1_200mhz>;
+ bus-width = <4>;
+};
+
diff --git a/arch/arm/boot/dts/imx6sxscm-evb-ldo.dts b/arch/arm/boot/dts/imx6sxscm-evb-ldo.dts
new file mode 100644
index 000000000000..954057769c87
--- /dev/null
+++ b/arch/arm/boot/dts/imx6sxscm-evb-ldo.dts
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2016 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 "imx6sxscm-evb.dts"
+
+&cpu0 {
+ operating-points = <
+ /* kHz uV */
+ 996000 1250000
+ 792000 1175000
+ 396000 1075000
+ 198000 975000
+ >;
+ fsl,soc-operating-points = <
+ /* ARM kHz SOC uV */
+ 996000 1175000
+ 792000 1175000
+ 396000 1175000
+ 198000 1175000
+ >;
+ arm-supply = <&reg_arm>;
+ soc-supply = <&reg_soc>;
+ fsl,arm-soc-shared = <0>;
+};
+
+&gpc {
+ /* use ldo-enable, u-boot will check it and configure */
+ fsl,ldo-bypass = <0>;
+};
diff --git a/arch/arm/boot/dts/imx6sxscm-evb.dts b/arch/arm/boot/dts/imx6sxscm-evb.dts
new file mode 100644
index 000000000000..97651e7e6b6c
--- /dev/null
+++ b/arch/arm/boot/dts/imx6sxscm-evb.dts
@@ -0,0 +1,1156 @@
+/*
+ * Copyright (C) 2016 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 <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include "imx6sx.dtsi"
+
+/ {
+ model = "Freescale i.MX6 SXSCM EVB Board";
+ compatible = "fsl,imx6sx-sdb", "fsl,imx6sx";
+
+ chosen {
+ stdout-path = &uart3;
+ };
+
+ memory {
+ reg = <0x80000000 0x40000000>;
+ };
+
+ backlight1 {
+ compatible = "pwm-backlight";
+ pwms = <&pwm3 0 5000000>;
+ brightness-levels = <0 4 8 16 32 64 128 255>;
+ default-brightness-level = <6>;
+ fb-names = "mxs-lcdif0";
+ };
+
+ backlight2 {
+ compatible = "pwm-backlight";
+ pwms = <&pwm4 0 5000000>;
+ brightness-levels = <0 4 8 16 32 64 128 255>;
+ default-brightness-level = <6>;
+ fb-names = "mxs-lcdif1";
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpio_keys>;
+
+ volume-up {
+ label = "Volume Up";
+ gpios = <&gpio1 18 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_VOLUMEUP>;
+ };
+
+ volume-down {
+ label = "Volume Down";
+ gpios = <&gpio1 19 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_VOLUMEDOWN>;
+ };
+ };
+
+ hannstar_cabc {
+ compatible = "hannstar,cabc";
+
+ lvds0 {
+ gpios = <&gpio4 18 GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ pxp_v4l2_out {
+ compatible = "fsl,imx6sx-pxp-v4l2", "fsl,imx6sl-pxp-v4l2";
+ status = "okay";
+ };
+
+ 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>;
+ off-on-delay = <20000>;
+ enable-active-high;
+ };
+
+ reg_usb_otg1_vbus: regulator@1 {
+ compatible = "regulator-fixed";
+ reg = <1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usb_otg1>;
+ regulator-name = "usb_otg1_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&gpio1 9 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ reg_usb_otg2_vbus: regulator@2 {
+ compatible = "regulator-fixed";
+ reg = <2>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usb_otg2>;
+ regulator-name = "usb_otg2_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ enable-active-high;
+ };
+
+ reg_psu_5v: regulator@3 {
+ compatible = "regulator-fixed";
+ reg = <3>;
+ regulator-name = "PSU-5V0";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ };
+
+ reg_lcd_3v3: regulator@4 {
+ compatible = "regulator-fixed";
+ reg = <4>;
+ regulator-name = "lcd-3v3";
+ gpio = <&gpio3 27 0>;
+ enable-active-high;
+ status = "disabled";
+ };
+
+ reg_peri_3v3: regulator@5 {
+ compatible = "regulator-fixed";
+ reg = <5>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_peri_3v3>;
+ regulator-name = "peri_3v3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&gpio4 16 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ regulator-always-on;
+ };
+
+ reg_enet_3v3: regulator@6 {
+ compatible = "regulator-fixed";
+ reg = <6>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_enet_3v3>;
+ regulator-name = "enet_3v3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpios = <&gpio4 25 GPIO_ACTIVE_LOW>,
+ <&gpio4 26 GPIO_ACTIVE_HIGH>;
+ };
+
+ reg_vref_3v3: regulator@7 {
+ compatible = "regulator-fixed";
+ reg = <7>;
+ regulator-name = "vref-3v3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ reg_pcie: regulator@8 {
+ compatible = "regulator-fixed";
+ reg = <8>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pcie_reg>;
+ regulator-name = "MPCIE_3V3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&gpio2 1 0>;
+ regulator-always-on;
+ enable-active-high;
+ };
+
+ reg_can_en: regulator@9 {
+ compatible = "regulator-fixed";
+ reg = <9>;
+ regulator-name = "can-en";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ reg_can_stby: regulator@10 {
+ compatible = "regulator-fixed";
+ reg = <10>;
+ regulator-name = "can-stby";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&gpio4 27 GPIO_ACTIVE_LOW>;
+ };
+ };
+
+ sound {
+ compatible = "fsl,imx6sxscm-evb-wm8962", "fsl,imx-audio-wm8962";
+ model = "wm8962-audio";
+ cpu-dai = <&ssi2>;
+ audio-codec = <&codec>;
+ audio-routing =
+ "Headphone Jack", "HPOUTL",
+ "Headphone Jack", "HPOUTR",
+ "Ext Spk", "SPKOUTL",
+ "Ext Spk", "SPKOUTR",
+ "AMIC", "MICBIAS",
+ "IN3R", "AMIC";
+ mux-int-port = <2>;
+ mux-ext-port = <6>;
+ codec-master;
+ hp-det-gpios = <&gpio1 17 1>;
+ };
+
+ sound-spdif {
+ compatible = "fsl,imx-audio-spdif",
+ "fsl,imx6sx-sdb-spdif";
+ model = "imx-spdif";
+ spdif-controller = <&spdif>;
+ spdif-out;
+ };
+
+ sii902x_reset: sii902x-reset {
+ compatible = "gpio-reset";
+ reset-gpios = <&gpio3 27 1>;
+ reset-delay-us = <100000>;
+ #reset-cells = <0>;
+ status = "disabled";
+ };
+};
+
+&adc1 {
+ vref-supply = <&reg_vref_3v3>;
+ status = "okay";
+};
+
+&adc2 {
+ vref-supply = <&reg_vref_3v3>;
+ status = "okay";
+};
+
+&audmux {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_audmux>;
+ status = "okay";
+};
+
+&gpc {
+ fsl,ldo-bypass = <1>;
+};
+
+&fec1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_enet1>;
+ phy-supply = <&reg_enet_3v3>;
+ phy-mode = "rgmii";
+ phy-reset-gpios = <&gpio4 26 0>;
+ fsl,magic-packet;
+ status = "okay";
+};
+
+&csi1 {
+ status = "okay";
+
+ port {
+ csi1_ep: endpoint {
+ remote-endpoint = <&ov5640_ep>;
+ };
+ };
+};
+
+&csi2 {
+ status = "okay";
+ port {
+ csi2_ep: endpoint {
+ remote-endpoint = <&vadc_ep>;
+ };
+ };
+};
+
+&dcic1 {
+ dcic_id = <0>;
+ dcic_mux = "dcic-lcdif1";
+ status = "okay";
+};
+
+&dcic2 {
+ dcic_id = <1>;
+ dcic_mux = "dcic-lvds";
+ status = "okay";
+};
+
+&flexcan1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_flexcan1>;
+ xceiver-supply = <&reg_can_stby>;
+ status = "okay";
+};
+
+&flexcan2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_flexcan2>;
+ xceiver-supply = <&reg_can_stby>;
+ status = "okay";
+};
+
+&i2c1 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c1>;
+ status = "okay";
+};
+
+&i2c2 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c2>;
+ status = "okay";
+
+ pmic: pfuze100@08 {
+ compatible = "fsl,pfuze100";
+ reg = <0x08>;
+
+ regulators {
+ sw1a_reg: sw1ab {
+ regulator-min-microvolt = <300000>;
+ regulator-max-microvolt = <1875000>;
+ regulator-boot-on;
+ regulator-always-on;
+ regulator-ramp-delay = <6250>;
+ };
+
+ sw2_reg: sw2 {
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ sw3a_reg: sw3a {
+ regulator-min-microvolt = <400000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ swbst_reg: swbst {
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5150000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ snvs_reg: vsnvs {
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ vref_reg: vrefddr {
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ vgen2_reg: vgen2 {
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1550000>;
+ };
+
+ vgen3_reg: vgen3 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <2800000>;
+ regulator-always-on;
+ };
+
+ vgen4_reg: vgen4 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
+ vgen6_reg: vgen6 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+ };
+ };
+
+ egalax_ts@04 {
+ compatible = "eeti,egalax_ts";
+ reg = <0x04>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_egalax_int>;
+ interrupt-parent = <&gpio4>;
+ interrupts = <19 2>;
+ wakeup-gpios = <&gpio4 19 GPIO_ACTIVE_HIGH>;
+ };
+};
+
+&i2c3 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c3>;
+ status = "okay";
+
+ mma8451@1c {
+ compatible = "fsl,mma8451";
+ reg = <0x1c>;
+ position = <1>;
+ interrupt-parent = <&gpio4>;
+ interrupts = <17 8>;
+ interrupt-route = <2>;
+ };
+
+ mag3110@0e {
+ compatible = "fsl,mag3110";
+ reg = <0x0e>;
+ position = <2>;
+ interrupt-parent = <&gpio4>;
+ interrupts = <22 1>;
+ shared-interrupt;
+ };
+
+ isl29023@44 {
+ compatible = "fsl,isl29023";
+ reg = <0x44>;
+ rext = <499>;
+ interrupt-parent = <&gpio4>;
+ interrupts = <22 1>;
+ shared-interrupt;
+ };
+};
+
+&i2c4 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c4>;
+ status = "okay";
+
+ codec: wm8962@1a {
+ compatible = "wlf,wm8962";
+ reg = <0x1a>;
+ clocks = <&clks IMX6SX_CLK_AUDIO>;
+ DCVDD-supply = <&vgen4_reg>;
+ DBVDD-supply = <&vgen4_reg>;
+ AVDD-supply = <&vgen4_reg>;
+ CPVDD-supply = <&vgen4_reg>;
+ MICVDD-supply = <&vgen3_reg>;
+ PLLVDD-supply = <&vgen4_reg>;
+ SPKVDD1-supply = <&reg_psu_5v>;
+ SPKVDD2-supply = <&reg_psu_5v>;
+ amic-mono;
+ };
+ ov5640: ov5640@3c {
+ compatible = "ovti,ov5640";
+ reg = <0x3c>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_csi_0>;
+ clocks = <&clks IMX6SX_CLK_CSI>;
+ clock-names = "csi_mclk";
+ AVDD-supply = <&vgen3_reg>;
+ DVDD-supply = <&vgen2_reg>;
+ pwn-gpios = <&gpio3 28 1>;
+ rst-gpios = <&gpio3 27 0>;
+ csi_id = <0>;
+ mclk = <24000000>;
+ mclk_source = <0>;
+ port {
+ ov5640_ep: endpoint {
+ remote-endpoint = <&csi1_ep>;
+ };
+ };
+ };
+
+ sii902x: sii902x@39 {
+ compatible = "SiI,sii902x";
+ interrupt-parent = <&gpio4>;
+ interrupts = <21 2>;
+ mode_str ="1280x720M@60";
+ bits-per-pixel = <16>;
+ resets = <&sii902x_reset>;
+ reg = <0x39>;
+ status = "disabled";
+ };
+};
+
+&cpu0 {
+ operating-points = <
+ /* kHz uV */
+ 996000 1250000
+ 792000 1175000
+ 396000 1175000
+ 198000 1175000
+ >;
+ fsl,soc-operating-points = <
+ /* ARM kHz SOC uV */
+ 996000 1250000
+ 792000 1175000
+ 396000 1175000
+ 198000 1175000
+ >;
+ fsl,arm-soc-shared = <1>;
+};
+
+&reg_arm {
+ vin-supply = <&sw1a_reg>;
+ regulator-allow-bypass;
+};
+
+&reg_soc {
+ vin-supply = <&sw1a_reg>;
+ regulator-allow-bypass;
+};
+
+
+&qspi2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_qspi2_1>;
+ status = "okay";
+
+#ifndef SPANSIONFLASH
+ ddrsmp=<0>;
+
+ flash0: n25q256a@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "micron,n25q256a";
+ spi-max-frequency = <29000000>;
+ spi-nor,ddr-quad-read-dummy = <6>;
+ reg = <0>;
+ };
+
+ flash1: n25q256a@1 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "micron,n25q256a";
+ spi-max-frequency = <29000000>;
+ spi-nor,ddr-quad-read-dummy = <6>;
+ reg = <1>;
+ };
+#endif
+};
+
+&lcdif1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lcd>;
+ lcd-supply = <&reg_lcd_3v3>;
+ display = <&display0>;
+ status = "disabled";
+
+ display0: display@0 {
+ bits-per-pixel = <16>;
+ bus-width = <24>;
+
+ display-timings {
+ native-mode = <&timing0>;
+ timing0: timing0 {
+ clock-frequency = <33500000>;
+ hactive = <800>;
+ vactive = <480>;
+ hback-porch = <89>;
+ hfront-porch = <164>;
+ vback-porch = <23>;
+ vfront-porch = <10>;
+ hsync-len = <10>;
+ vsync-len = <10>;
+ hsync-active = <0>;
+ vsync-active = <0>;
+ de-active = <1>;
+ pixelclk-active = <0>;
+ };
+ };
+ };
+};
+
+&lcdif2 {
+ display = <&display1>;
+ disp-dev = "ldb";
+ status = "okay";
+
+ display1: display@1 {
+ bits-per-pixel = <16>;
+ bus-width = <18>;
+ };
+};
+
+&ldb {
+ status = "okay";
+
+ lvds-channel@0 {
+ fsl,data-mapping = "spwg";
+ fsl,data-width = <18>;
+ crtc = "lcdif2";
+ status = "okay";
+
+ display-timings {
+ native-mode = <&timing1>;
+ timing1: hsd100pxn1 {
+ clock-frequency = <65000000>;
+ hactive = <1024>;
+ vactive = <768>;
+ hback-porch = <220>;
+ hfront-porch = <40>;
+ vback-porch = <21>;
+ vfront-porch = <7>;
+ hsync-len = <60>;
+ vsync-len = <10>;
+ };
+ };
+ };
+};
+
+&pwm3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pwm3>;
+ status = "okay";
+};
+
+&pwm4 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pwm4>;
+ status = "okay";
+};
+
+&pxp {
+ status = "okay";
+};
+
+&snvs_poweroff {
+ status = "okay";
+};
+
+&sai1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_sai1>;
+ status = "disabled";
+};
+
+&spdif {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_spdif>;
+ status = "okay";
+};
+
+&ssi2 {
+ status = "okay";
+};
+
+&uart3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart3>;
+ status = "okay";
+};
+
+&usbotg1 {
+ vbus-supply = <&reg_usb_otg1_vbus>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usb_otg1_id>;
+ srp-disable;
+ hnp-disable;
+ adp-disable;
+ status = "okay";
+};
+
+&usbotg2 {
+ vbus-supply = <&reg_usb_otg2_vbus>;
+ dr_mode = "host";
+ status = "okay";
+};
+
+&usdhc2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usdhc2>;
+ wifi-host;
+ no-1-8-v;
+ keep-power-in-suspend;
+ wakeup-source;
+ 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 = <>;
+ wp-gpios = <>;
+ keep-power-in-suspend;
+ wakeup-source;
+ pm-ignore-notify;
+ vmmc-supply = <>;
+ status = "okay";
+};
+
+&usdhc4 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usdhc4>;
+ cd-gpios = <&gpio6 21 GPIO_ACTIVE_LOW>;
+ wp-gpios = <&gpio6 20 GPIO_ACTIVE_HIGH>;
+ status = "okay";
+};
+
+&iomuxc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_hog &pinctrl_can_gpios>;
+
+ imx6x-sdb {
+ pinctrl_hog: hoggrp {
+ fsl,pins = <
+ MX6SX_PAD_QSPI1A_DATA1__GPIO4_IO_17 0x17059
+ MX6SX_PAD_QSPI1A_SS0_B__GPIO4_IO_22 0xb000
+ MX6SX_PAD_CSI_DATA03__GPIO1_IO_17 0x17059
+ MX6SX_PAD_GPIO1_IO13__WDOG1_WDOG_ANY 0x30b0
+ MX6SX_PAD_QSPI1A_SCLK__GPIO4_IO_21 0x17059
+ >;
+ };
+
+ pinctrl_can_gpios: can-gpios {
+ fsl,pins = <
+ MX6SX_PAD_QSPI1B_DATA3__GPIO4_IO_27 0x17059
+ >;
+ };
+
+ pinctrl_audmux: audmuxgrp {
+ fsl,pins = <
+ MX6SX_PAD_CSI_DATA00__AUDMUX_AUD6_TXC 0x130b0
+ MX6SX_PAD_CSI_DATA01__AUDMUX_AUD6_TXFS 0x130b0
+ MX6SX_PAD_CSI_HSYNC__AUDMUX_AUD6_TXD 0x120b0
+ MX6SX_PAD_CSI_VSYNC__AUDMUX_AUD6_RXD 0x130b0
+ MX6SX_PAD_CSI_PIXCLK__AUDMUX_MCLK 0x130b0
+ >;
+ };
+
+ pinctrl_canfd1: canfd1grp-1 {
+ fsl,pins = <
+ MX6SX_PAD_QSPI1B_DQS__CANFD_TX1 0x1b0b0
+ MX6SX_PAD_QSPI1A_SS1_B__CANFD_RX1 0x1b0b0
+ >;
+ };
+
+ pinctrl_canfd2: canfd2grp-1 {
+ fsl,pins = <
+ MX6SX_PAD_QSPI1B_SS1_B__CANFD_RX2 0x1b0b0
+ MX6SX_PAD_QSPI1A_DQS__CANFD_TX2 0x1b0b0
+ >;
+ };
+
+ pinctrl_csi_0: csigrp-0 {
+ fsl,pins = <
+ MX6SX_PAD_LCD1_DATA07__CSI1_MCLK 0x110b0
+ MX6SX_PAD_LCD1_DATA06__CSI1_PIXCLK 0x110b0
+ MX6SX_PAD_LCD1_DATA04__CSI1_VSYNC 0x110b0
+ MX6SX_PAD_LCD1_DATA05__CSI1_HSYNC 0x110b0
+ MX6SX_PAD_LCD1_DATA17__CSI1_DATA_0 0x110b0
+ MX6SX_PAD_LCD1_DATA16__CSI1_DATA_1 0x110b0
+ MX6SX_PAD_LCD1_DATA15__CSI1_DATA_2 0x110b0
+ MX6SX_PAD_LCD1_DATA14__CSI1_DATA_3 0x110b0
+ MX6SX_PAD_LCD1_DATA13__CSI1_DATA_4 0x110b0
+ MX6SX_PAD_LCD1_DATA12__CSI1_DATA_5 0x110b0
+ MX6SX_PAD_LCD1_DATA11__CSI1_DATA_6 0x110b0
+ MX6SX_PAD_LCD1_DATA10__CSI1_DATA_7 0x110b0
+ MX6SX_PAD_LCD1_DATA09__CSI1_DATA_8 0x110b0
+ MX6SX_PAD_LCD1_DATA08__CSI1_DATA_9 0x110b0
+ MX6SX_PAD_LCD1_RESET__GPIO3_IO_27 0x80000000
+ MX6SX_PAD_LCD1_VSYNC__GPIO3_IO_28 0x80000000
+ >;
+ };
+
+ pinctrl_egalax_int: egalax_intgrp {
+ fsl,pins = <
+ MX6SX_PAD_QSPI1A_DATA3__GPIO4_IO_19 0x80000000
+ >;
+ };
+
+ pinctrl_enet1: enet1grp {
+ fsl,pins = <
+ MX6SX_PAD_GPIO1_IO05__ENET1_MDIO 0xa0b1
+ MX6SX_PAD_GPIO1_IO04__ENET1_MDC 0xa0b1
+ MX6SX_PAD_RGMII1_TXC__ENET1_RGMII_TXC 0xa0b9
+ MX6SX_PAD_RGMII1_TD0__ENET1_TX_DATA_0 0xa0b1
+ MX6SX_PAD_RGMII1_TD1__ENET1_TX_DATA_1 0xa0b1
+ MX6SX_PAD_RGMII1_TD2__ENET1_TX_DATA_2 0xa0b1
+ MX6SX_PAD_RGMII1_TD3__ENET1_TX_DATA_3 0xa0b1
+ MX6SX_PAD_RGMII1_TX_CTL__ENET1_TX_EN 0xa0b1
+ MX6SX_PAD_RGMII1_RXC__ENET1_RX_CLK 0x3081
+ MX6SX_PAD_RGMII1_RD0__ENET1_RX_DATA_0 0x3081
+ MX6SX_PAD_RGMII1_RD1__ENET1_RX_DATA_1 0x3081
+ MX6SX_PAD_RGMII1_RD2__ENET1_RX_DATA_2 0x3081
+ MX6SX_PAD_RGMII1_RD3__ENET1_RX_DATA_3 0x3081
+ MX6SX_PAD_RGMII1_RX_CTL__ENET1_RX_EN 0x3081
+ MX6SX_PAD_ENET2_RX_CLK__ENET2_REF_CLK_25M 0x91
+ >;
+ };
+
+ pinctrl_enet_3v3: enet3v3grp {
+ fsl,pins = <
+ MX6SX_PAD_QSPI1B_DATA1__GPIO4_IO_25 0x80000000
+ MX6SX_PAD_QSPI1B_DATA2__GPIO4_IO_26 0x80000000
+ >;
+ };
+
+ pinctrl_enet2: enet2grp {
+ fsl,pins = <
+ MX6SX_PAD_RGMII2_TXC__ENET2_RGMII_TXC 0xa0b9
+ MX6SX_PAD_RGMII2_TD0__ENET2_TX_DATA_0 0xa0b1
+ MX6SX_PAD_RGMII2_TD1__ENET2_TX_DATA_1 0xa0b1
+ MX6SX_PAD_RGMII2_TD2__ENET2_TX_DATA_2 0xa0b1
+ MX6SX_PAD_RGMII2_TD3__ENET2_TX_DATA_3 0xa0b1
+ MX6SX_PAD_RGMII2_TX_CTL__ENET2_TX_EN 0xa0b1
+ MX6SX_PAD_RGMII2_RXC__ENET2_RX_CLK 0x3081
+ MX6SX_PAD_RGMII2_RD0__ENET2_RX_DATA_0 0x3081
+ MX6SX_PAD_RGMII2_RD1__ENET2_RX_DATA_1 0x3081
+ MX6SX_PAD_RGMII2_RD2__ENET2_RX_DATA_2 0x3081
+ MX6SX_PAD_RGMII2_RD3__ENET2_RX_DATA_3 0x3081
+ MX6SX_PAD_RGMII2_RX_CTL__ENET2_RX_EN 0x3081
+ >;
+ };
+
+ pinctrl_flexcan1: flexcan1grp {
+ fsl,pins = <
+ MX6SX_PAD_QSPI1B_DQS__CAN1_TX 0x1b020
+ MX6SX_PAD_QSPI1A_SS1_B__CAN1_RX 0x1b020
+ >;
+ };
+
+ pinctrl_flexcan2: flexcan2grp {
+ fsl,pins = <
+ MX6SX_PAD_QSPI1B_SS1_B__CAN2_RX 0x1b020
+ MX6SX_PAD_QSPI1A_DQS__CAN2_TX 0x1b020
+ >;
+ };
+
+ pinctrl_gpio_keys: gpio_keysgrp {
+ fsl,pins = <
+ MX6SX_PAD_CSI_DATA04__GPIO1_IO_18 0x17059
+ MX6SX_PAD_CSI_DATA05__GPIO1_IO_19 0x17059
+ >;
+ };
+
+ pinctrl_i2c1: i2c1grp {
+ fsl,pins = <
+ MX6SX_PAD_GPIO1_IO01__I2C1_SDA 0x4001b8b1
+ MX6SX_PAD_GPIO1_IO00__I2C1_SCL 0x4001b8b1
+ >;
+ };
+
+ pinctrl_i2c2: i2c2grp {
+ fsl,pins = <
+ MX6SX_PAD_GPIO1_IO03__I2C2_SDA 0x4001b8b1
+ MX6SX_PAD_GPIO1_IO02__I2C2_SCL 0x4001b8b1
+ >;
+ };
+
+ pinctrl_i2c3: i2c3grp {
+ fsl,pins = <
+ MX6SX_PAD_KEY_ROW4__I2C3_SDA 0x4001b8b1
+ MX6SX_PAD_KEY_COL4__I2C3_SCL 0x4001b8b1
+ >;
+ };
+
+ pinctrl_i2c4: i2c4grp {
+ fsl,pins = <
+ MX6SX_PAD_CSI_DATA07__I2C4_SDA 0x4001b8b1
+ MX6SX_PAD_CSI_DATA06__I2C4_SCL 0x4001b8b1
+ >;
+ };
+
+ pinctrl_lcd: lcdgrp {
+ fsl,pins = <
+ MX6SX_PAD_LCD1_DATA00__LCDIF1_DATA_0 0x4001b0b0
+ MX6SX_PAD_LCD1_DATA01__LCDIF1_DATA_1 0x4001b0b0
+ MX6SX_PAD_LCD1_DATA02__LCDIF1_DATA_2 0x4001b0b0
+ MX6SX_PAD_LCD1_DATA03__LCDIF1_DATA_3 0x4001b0b0
+ MX6SX_PAD_LCD1_DATA04__LCDIF1_DATA_4 0x4001b0b0
+ MX6SX_PAD_LCD1_DATA05__LCDIF1_DATA_5 0x4001b0b0
+ MX6SX_PAD_LCD1_DATA06__LCDIF1_DATA_6 0x4001b0b0
+ MX6SX_PAD_LCD1_DATA07__LCDIF1_DATA_7 0x4001b0b0
+ MX6SX_PAD_LCD1_DATA08__LCDIF1_DATA_8 0x4001b0b0
+ MX6SX_PAD_LCD1_DATA09__LCDIF1_DATA_9 0x4001b0b0
+ MX6SX_PAD_LCD1_DATA10__LCDIF1_DATA_10 0x4001b0b0
+ MX6SX_PAD_LCD1_DATA11__LCDIF1_DATA_11 0x4001b0b0
+ MX6SX_PAD_LCD1_DATA12__LCDIF1_DATA_12 0x4001b0b0
+ MX6SX_PAD_LCD1_DATA13__LCDIF1_DATA_13 0x4001b0b0
+ MX6SX_PAD_LCD1_DATA14__LCDIF1_DATA_14 0x4001b0b0
+ MX6SX_PAD_LCD1_DATA15__LCDIF1_DATA_15 0x4001b0b0
+ MX6SX_PAD_LCD1_DATA16__LCDIF1_DATA_16 0x4001b0b0
+ MX6SX_PAD_LCD1_DATA17__LCDIF1_DATA_17 0x4001b0b0
+ MX6SX_PAD_LCD1_DATA18__LCDIF1_DATA_18 0x4001b0b0
+ MX6SX_PAD_LCD1_DATA19__LCDIF1_DATA_19 0x4001b0b0
+ MX6SX_PAD_LCD1_DATA20__LCDIF1_DATA_20 0x4001b0b0
+ MX6SX_PAD_LCD1_DATA21__LCDIF1_DATA_21 0x4001b0b0
+ MX6SX_PAD_LCD1_DATA22__LCDIF1_DATA_22 0x4001b0b0
+ MX6SX_PAD_LCD1_DATA23__LCDIF1_DATA_23 0x4001b0b0
+ MX6SX_PAD_LCD1_CLK__LCDIF1_CLK 0x4001b0b0
+ MX6SX_PAD_LCD1_ENABLE__LCDIF1_ENABLE 0x4001b0b0
+ MX6SX_PAD_LCD1_VSYNC__LCDIF1_VSYNC 0x4001b0b0
+ MX6SX_PAD_LCD1_HSYNC__LCDIF1_HSYNC 0x4001b0b0
+ MX6SX_PAD_LCD1_RESET__GPIO3_IO_27 0x4001b0b0
+ >;
+ };
+
+ pinctrl_mqs: mqsgrp {
+ fsl,pins = <
+ MX6SX_PAD_SD2_CLK__MQS_RIGHT 0x120b0
+ MX6SX_PAD_SD2_CMD__MQS_LEFT 0x120b0
+ >;
+ };
+
+ pinctrl_pcie: pciegrp {
+ fsl,pins = <
+ MX6SX_PAD_ENET1_COL__GPIO2_IO_0 0x10b0
+ >;
+ };
+
+ pinctrl_pcie_reg: pciereggrp {
+ fsl,pins = <
+ MX6SX_PAD_ENET1_CRS__GPIO2_IO_1 0x10b0
+ >;
+ };
+
+ pinctrl_peri_3v3: peri3v3grp {
+ fsl,pins = <
+ MX6SX_PAD_QSPI1A_DATA0__GPIO4_IO_16 0x80000000
+ >;
+ };
+ pinctrl_pwm3: pwm3grp {
+ fsl,pins = <
+ MX6SX_PAD_NAND_DATA06__PWM3_OUT 0x110b0
+ >;
+ };
+
+ pinctrl_pwm4: pwm4grp {
+ fsl,pins = <
+ MX6SX_PAD_NAND_DATA07__PWM4_OUT 0x110b0
+ >;
+ };
+
+ pinctrl_qspi2_1: qspi2grp_1 {
+ 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_sai1: sai1grp {
+ fsl,pins = <
+ MX6SX_PAD_CSI_DATA00__SAI1_TX_BCLK 0x130b0
+ MX6SX_PAD_CSI_DATA01__SAI1_TX_SYNC 0x130b0
+ MX6SX_PAD_CSI_HSYNC__SAI1_TX_DATA_0 0x120b0
+ MX6SX_PAD_CSI_VSYNC__SAI1_RX_DATA_0 0x130b0
+ MX6SX_PAD_CSI_PIXCLK__AUDMUX_MCLK 0x130b0
+ >;
+ };
+
+ pinctrl_spdif: spdifgrp {
+ fsl,pins = <
+ MX6SX_PAD_SD4_DATA4__SPDIF_OUT 0x1b0b0
+ >;
+ };
+
+ pinctrl_vcc_sd3: vccsd3grp {
+ fsl,pins = <
+ MX6SX_PAD_KEY_COL1__GPIO2_IO_11 0x17059
+ >;
+ };
+
+ pinctrl_uart1: uart1grp {
+ fsl,pins = <
+ MX6SX_PAD_GPIO1_IO04__UART1_TX 0x1b0b1
+ MX6SX_PAD_GPIO1_IO05__UART1_RX 0x1b0b1
+ >;
+ };
+
+ pinctrl_uart5: uart5grp {
+ fsl,pins = <
+ MX6SX_PAD_KEY_ROW3__UART5_RX 0x1b0b1
+ MX6SX_PAD_KEY_COL3__UART5_TX 0x1b0b1
+ MX6SX_PAD_KEY_ROW2__UART5_CTS_B 0x1b0b1
+ MX6SX_PAD_KEY_COL2__UART5_RTS_B 0x1b0b1
+ >;
+ };
+
+ pinctrl_uart5dte_1: uart5dtegrp-1 {
+ fsl,pins = <
+ MX6SX_PAD_KEY_ROW3__UART5_TX 0x1b0b1
+ MX6SX_PAD_KEY_COL3__UART5_RX 0x1b0b1
+ MX6SX_PAD_KEY_ROW2__UART5_RTS_B 0x1b0b1
+ MX6SX_PAD_KEY_COL2__UART5_CTS_B 0x1b0b1
+ >;
+ };
+
+ pinctrl_usb_otg1: usbotg1grp {
+ fsl,pins = <
+ MX6SX_PAD_GPIO1_IO09__GPIO1_IO_9 0x10b0
+ >;
+ };
+
+ pinctrl_usb_otg1_id: usbotg1idgrp {
+ fsl,pins = <
+ MX6SX_PAD_GPIO1_IO10__ANATOP_OTG1_ID 0x17059
+ >;
+ };
+
+ pinctrl_usb_otg2: usbot2ggrp {
+ fsl,pins = <
+ MX6SX_PAD_GPIO1_IO12__GPIO1_IO_12 0x10b0
+ >;
+ };
+
+ pinctrl_usdhc2: usdhc2grp {
+ fsl,pins = <
+ MX6SX_PAD_SD2_CMD__USDHC2_CMD 0x17059
+ MX6SX_PAD_SD2_CLK__USDHC2_CLK 0x10059
+ MX6SX_PAD_SD2_DATA0__USDHC2_DATA0 0x17059
+ MX6SX_PAD_SD2_DATA1__USDHC2_DATA1 0x17059
+ MX6SX_PAD_SD2_DATA2__USDHC2_DATA2 0x17059
+ MX6SX_PAD_SD2_DATA3__USDHC2_DATA3 0x17059
+ >;
+ };
+
+ pinctrl_usdhc3: usdhc3grp {
+ fsl,pins = <
+ MX6SX_PAD_SD3_CMD__USDHC3_CMD 0x17069
+ MX6SX_PAD_SD3_CLK__USDHC3_CLK 0x10071
+ MX6SX_PAD_SD3_DATA0__USDHC3_DATA0 0x17069
+ MX6SX_PAD_SD3_DATA1__USDHC3_DATA1 0x17069
+ MX6SX_PAD_SD3_DATA2__USDHC3_DATA2 0x17069
+ MX6SX_PAD_SD3_DATA3__USDHC3_DATA3 0x17069
+ MX6SX_PAD_SD3_DATA4__USDHC3_DATA4 0x17069
+ MX6SX_PAD_SD3_DATA5__USDHC3_DATA5 0x17069
+ MX6SX_PAD_SD3_DATA6__USDHC3_DATA6 0x17069
+ MX6SX_PAD_SD3_DATA7__USDHC3_DATA7 0x17069
+ MX6SX_PAD_KEY_COL0__GPIO2_IO_10 0x17059
+ MX6SX_PAD_KEY_ROW0__GPIO2_IO_15 0x17059
+ >;
+ };
+
+ 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
+ MX6SX_PAD_SD4_DATA6__GPIO6_IO_20 0x17059
+ >;
+ };
+
+ pinctrl_usdhc4_1: usdhc4grp-1 {
+ 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_DATA4__USDHC4_DATA4 0x17059
+ MX6SX_PAD_SD4_DATA5__USDHC4_DATA5 0x17059
+ MX6SX_PAD_SD4_DATA6__USDHC4_DATA6 0x17059
+ MX6SX_PAD_SD4_DATA7__USDHC4_DATA7 0x17059
+ >;
+ };
+
+ pinctrl_usdhc4_1_100mhz: usdhc4grp-1-100mhz {
+ fsl,pins = <
+ MX6SX_PAD_SD4_CMD__USDHC4_CMD 0x170b9
+ MX6SX_PAD_SD4_CLK__USDHC4_CLK 0x100b9
+ MX6SX_PAD_SD4_DATA0__USDHC4_DATA0 0x170b9
+ MX6SX_PAD_SD4_DATA1__USDHC4_DATA1 0x170b9
+ MX6SX_PAD_SD4_DATA2__USDHC4_DATA2 0x170b9
+ MX6SX_PAD_SD4_DATA3__USDHC4_DATA3 0x170b9
+ MX6SX_PAD_SD4_DATA4__USDHC4_DATA4 0x170b9
+ MX6SX_PAD_SD4_DATA5__USDHC4_DATA5 0x170b9
+ MX6SX_PAD_SD4_DATA6__USDHC4_DATA6 0x170b9
+ MX6SX_PAD_SD4_DATA7__USDHC4_DATA7 0x170b9
+ >;
+ };
+
+ pinctrl_usdhc4_1_200mhz: usdhc4grp-1-200mhz {
+ fsl,pins = <
+ MX6SX_PAD_SD4_CMD__USDHC4_CMD 0x170f9
+ MX6SX_PAD_SD4_CLK__USDHC4_CLK 0x100f9
+ MX6SX_PAD_SD4_DATA0__USDHC4_DATA0 0x170f9
+ MX6SX_PAD_SD4_DATA1__USDHC4_DATA1 0x170f9
+ MX6SX_PAD_SD4_DATA2__USDHC4_DATA2 0x170f9
+ MX6SX_PAD_SD4_DATA3__USDHC4_DATA3 0x170f9
+ MX6SX_PAD_SD4_DATA4__USDHC4_DATA4 0x170f9
+ MX6SX_PAD_SD4_DATA5__USDHC4_DATA5 0x170f9
+ MX6SX_PAD_SD4_DATA6__USDHC4_DATA6 0x170f9
+ MX6SX_PAD_SD4_DATA7__USDHC4_DATA7 0x170f9
+ >;
+ };
+
+ pinctrl_uart3: uart3grp {
+ fsl,pins = <
+ MX6SX_PAD_QSPI1B_SS0_B__UART3_TX 0x1b0b1
+ MX6SX_PAD_QSPI1B_SCLK__UART3_RX 0x1b0b1
+ >;
+ };
+ };
+};
+
+&vadc {
+ vadc_in = <0>;
+ csi_id = <1>;
+ status = "disabled";
+ port {
+ vadc_ep: endpoint {
+ remote-endpoint = <&csi2_ep>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/imx6ul-14x14-ddr3-arm2-emmc.dts b/arch/arm/boot/dts/imx6ul-14x14-ddr3-arm2-emmc.dts
new file mode 100644
index 000000000000..2e35ed6d353e
--- /dev/null
+++ b/arch/arm/boot/dts/imx6ul-14x14-ddr3-arm2-emmc.dts
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2015 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 "imx6ul-14x14-ddr3-arm2.dts"
+
+&usdhc1 {
+ pinctrl-names = "default", "state_100mhz", "state_200mhz";
+ pinctrl-0 = <&pinctrl_usdhc1_8bit>;
+ pinctrl-1 = <&pinctrl_usdhc1_8bit_100mhz>;
+ pinctrl-2 = <&pinctrl_usdhc1_8bit_200mhz>;
+ bus-width = <8>;
+ cd-gpios = <>;
+ wp-gpios = <>;
+ vmmc-supply = <>;
+ tuning-step = <2>;
+ non-removable;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx6ul-14x14-ddr3-arm2-flexcan2.dts b/arch/arm/boot/dts/imx6ul-14x14-ddr3-arm2-flexcan2.dts
new file mode 100644
index 000000000000..1a3a0141d747
--- /dev/null
+++ b/arch/arm/boot/dts/imx6ul-14x14-ddr3-arm2-flexcan2.dts
@@ -0,0 +1,18 @@
+/*
+ * Copyright (C) 2015 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 "imx6ul-14x14-ddr3-arm2.dts"
+
+&uart2{
+ status = "disabled";
+};
+
+&can2 {
+ status = "okay";
+};
+
diff --git a/arch/arm/boot/dts/imx6ul-14x14-ddr3-arm2-gpmi-weim.dts b/arch/arm/boot/dts/imx6ul-14x14-ddr3-arm2-gpmi-weim.dts
new file mode 100644
index 000000000000..2e6b54495d05
--- /dev/null
+++ b/arch/arm/boot/dts/imx6ul-14x14-ddr3-arm2-gpmi-weim.dts
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2015 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 "imx6ul-14x14-ddr3-arm2.dts"
+
+/*
+ * solve pin conflict with NAND
+ *
+ * USDHC2_CD, SD2_RST_B, USDHC2_WP conflict with RAWNAND CE pins , also
+ * overwritten the conflict of SD2_RST_B with RAWNAND ALE in hog
+ * QSPI CLK, CE and DATA pins conflict with RAWNAND data pins and CE, CLE, RB,
+ * WP, DQS pin
+ *
+ */
+&iomuxc {
+ pinctrl-0 = <&pinctrl_hog>;
+};
+
+&qspi{
+ status = "disabled";
+};
+
+&gpmi{
+ status = "okay";
+};
+
+&usdhc2 {
+ status = "disabled";
+};
diff --git a/arch/arm/boot/dts/imx6ul-14x14-ddr3-arm2-mqs.dts b/arch/arm/boot/dts/imx6ul-14x14-ddr3-arm2-mqs.dts
new file mode 100644
index 000000000000..3427bc330638
--- /dev/null
+++ b/arch/arm/boot/dts/imx6ul-14x14-ddr3-arm2-mqs.dts
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2015 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 "imx6ul-14x14-ddr3-arm2.dts"
+
+/ {
+ sound-mqs {
+ compatible = "fsl,imx6ul-ddr3-arm2-mqs",
+ "fsl,imx-audio-mqs";
+ model = "mqs-audio";
+ cpu-dai = <&sai1>;
+ asrc-controller = <&asrc>;
+ audio-codec = <&mqs>;
+ };
+};
+
+&clks {
+ assigned-clocks = <&clks IMX6UL_CLK_PLL4_AUDIO_DIV>;
+ assigned-clock-rates = <786432000>;
+};
+
+&sai1 {
+ assigned-clocks = <&clks IMX6UL_CLK_SAI1_SEL>,
+ <&clks IMX6UL_CLK_SAI1>;
+ assigned-clock-parents = <&clks IMX6UL_CLK_PLL4_AUDIO_DIV>;
+ assigned-clock-rates = <0>, <24576000>;
+ status = "okay";
+};
+
+&mqs {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_mqs>;
+ clocks = <&clks IMX6UL_CLK_SAI1>;
+ clock-names = "mclk";
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx6ul-14x14-ddr3-arm2-spdif.dts b/arch/arm/boot/dts/imx6ul-14x14-ddr3-arm2-spdif.dts
new file mode 100644
index 000000000000..7191f0572e3b
--- /dev/null
+++ b/arch/arm/boot/dts/imx6ul-14x14-ddr3-arm2-spdif.dts
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2015 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 "imx6ul-14x14-ddr3-arm2.dts"
+
+/ {
+ sound-spdif {
+ compatible = "fsl,imx-audio-spdif";
+ model = "imx-spdif";
+ spdif-controller = <&spdif>;
+ spdif-in;
+ spdif-out;
+ };
+};
+
+&iomuxc {
+ pinctrl-0 = <&pinctrl_hog &pinctrl_hog1>;
+};
+
+&usdhc1 {
+ no-1-8-v;
+ vmmc-supply = <>;
+};
+
+&usdhc2 {
+ no-1-8-v;
+};
+
+&spdif {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_spdif>;
+ assigned-clocks = <&clks IMX6UL_CLK_SPDIF_SEL>,
+ <&clks IMX6UL_CLK_SPDIF_PODF>;
+ assigned-clock-parents = <&clks IMX6UL_CLK_PLL4_AUDIO_DIV>;
+ assigned-clock-rates = <0>, <98304000>;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx6ul-14x14-ddr3-arm2-wm8958.dts b/arch/arm/boot/dts/imx6ul-14x14-ddr3-arm2-wm8958.dts
new file mode 100644
index 000000000000..bdc5b903602a
--- /dev/null
+++ b/arch/arm/boot/dts/imx6ul-14x14-ddr3-arm2-wm8958.dts
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2015 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 "imx6ul-14x14-ddr3-arm2.dts"
+
+/ {
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ reg_codec_5v: codec_5v {
+ compatible = "regulator-fixed";
+ regulator-name = "CODEC_5V";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ enable-active-high;
+ };
+
+ reg_aud_3v3: aud_3v3 {
+ compatible = "regulator-fixed";
+ regulator-name = "AUD_3V3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ enable-active-high;
+ };
+
+ reg_aud_1v8: aud_1v8 {
+ compatible = "regulator-fixed";
+ regulator-name = "AUD_1V8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ enable-active-high;
+ };
+ };
+
+ sound-wm8958 {
+ compatible = "fsl,imx6ul-ddr3-arm2-wm8958",
+ "fsl,imx-audio-wm8958";
+ model = "wm8958-audio";
+ cpu-dai = <&sai2>;
+ audio-codec = <&codec>;
+ codec-master;
+ gpr = <&gpr 4 0x100000 0x100000>;
+ hp-det-gpios = <&gpio5 0 1>;
+ };
+};
+
+&clks {
+ assigned-clocks = <&clks IMX6UL_CLK_PLL4_AUDIO_DIV>;
+ assigned-clock-rates = <786432000>;
+};
+
+&i2c4 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c4>;
+ status = "okay";
+
+ codec: wm8958@1a {
+ compatible = "wlf,wm8958";
+ reg = <0x1a>;
+ clocks = <&clks IMX6UL_CLK_SAI2>,
+ <&clks IMX6UL_CLK_DUMMY>;
+ clock-names = "mclk1", "mclk2";
+
+ DBVDD1-supply = <&reg_aud_1v8>;
+ DBVDD2-supply = <&reg_aud_1v8>;
+ DBVDD3-supply = <&reg_aud_3v3>;
+ AVDD2-supply = <&reg_aud_1v8>;
+ CPVDD-supply = <&reg_aud_1v8>;
+ SPKVDD1-supply = <&reg_codec_5v>;
+ SPKVDD2-supply = <&reg_codec_5v>;
+
+ wlf,ldo1ena;
+ wlf,ldo2ena;
+ };
+};
+
+&sai2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_sai2>;
+ assigned-clocks = <&clks IMX6UL_CLK_SAI2_SEL>,
+ <&clks IMX6UL_CLK_SAI2>;
+ assigned-clock-parents = <&clks IMX6UL_CLK_PLL4_AUDIO_DIV>;
+ assigned-clock-rates = <0>, <24576000>;
+ status = "okay";
+};
+
+&uart2 {
+ status = "disabled";
+};
+
+&usdhc1 {
+ status = "disabled";
+};
diff --git a/arch/arm/boot/dts/imx6ul-14x14-ddr3-arm2.dts b/arch/arm/boot/dts/imx6ul-14x14-ddr3-arm2.dts
new file mode 100644
index 000000000000..e79ab43870b7
--- /dev/null
+++ b/arch/arm/boot/dts/imx6ul-14x14-ddr3-arm2.dts
@@ -0,0 +1,774 @@
+/*
+ * Copyright (C) 2015 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 <dt-bindings/input/input.h>
+#include "imx6ul.dtsi"
+
+/ {
+ model = "Freescale i.MX6 UltraLite DDR3 ARM2 Board";
+ compatible = "fsl,imx6ul-14x14-ddr3-arm2", "fsl,imx6ul";
+
+ chosen {
+ stdout-path = &uart1;
+ };
+
+ memory {
+ reg = <0x80000000 0x40000000>;
+ };
+
+ reserved-memory {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ linux,cma {
+ compatible = "shared-dma-pool";
+ reusable;
+ size = <0x14000000>;
+ linux,cma-default;
+ };
+ };
+
+ pxp_v4l2 {
+ compatible = "fsl,imx6ul-pxp-v4l2", "fsl,imx6sx-pxp-v4l2", "fsl,imx6sl-pxp-v4l2";
+ status = "okay";
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ reg_sd1_vmmc: sd1_vmmc {
+ compatible = "regulator-fixed";
+ regulator-name = "SD1_SPWR";
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ gpio = <&gpio1 9 GPIO_ACTIVE_HIGH>;
+ off-on-delay = <20000>;
+ enable-active-high;
+ };
+
+ reg_sd2_vmmc: sd2_vmmc {
+ compatible = "regulator-fixed";
+ regulator-name = "SD2_SPWR";
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ gpio = <&gpio4 10 GPIO_ACTIVE_HIGH>;
+ off-on-delay = <20000>;
+ enable-active-high;
+ };
+
+ reg_can2_3v3: regulator@0 {
+ compatible = "regulator-fixed";
+ reg = <0>;
+ regulator-name = "can2-3v3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&gpio1 15 GPIO_ACTIVE_LOW>;
+ };
+
+ reg_vref_3v3: regulator@1 {
+ compatible = "regulator-fixed";
+ regulator-name = "vref-3v3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ reg_usb_otg1_vbus: regulator@2 {
+ compatible = "regulator-fixed";
+ reg = <2>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usb_otg1>;
+ regulator-name = "usb_otg1_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&gpio1 4 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+ };
+};
+
+&clks {
+ assigned-clocks = <&clks IMX6UL_CLK_PLL4_AUDIO_DIV>;
+ assigned-clock-rates = <786432000>;
+};
+
+&cpu0 {
+ /*
+ * on i.MX6UL, no seperated VDD_ARM_IN and VDD_SOC_IN,
+ * to align with other platform and use the same cpufreq
+ * driver, still use the seperated OPP define for arm
+ * and soc.
+ */
+ operating-points = <
+ /* kHz uV */
+ 528000 1175000
+ 396000 1175000
+ 198000 1175000
+ >;
+ fsl,soc-operating-points = <
+ /* KHz uV */
+ 528000 1175000
+ 396000 1175000
+ 198000 1175000
+ >;
+ fsl,arm-soc-shared = <1>;
+};
+
+&reg_arm {
+ vin-supply = <&sw1a_reg>;
+ regulator-allow-bypass;
+};
+
+&reg_soc {
+ vin-supply = <&sw1a_reg>;
+ regulator-allow-bypass;
+};
+
+&ecspi1 {
+ fsl,spi-num-chipselects = <1>;
+ cs-gpios = <&gpio4 26 0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ecspi1_1 &pinctrl_ecspi1_cs_1>;
+ status = "okay";
+
+ flash: n25q032@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "st,n25q032";
+ spi-max-frequency = <20000000>;
+ reg = <0>;
+ };
+};
+
+&fec1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_enet1>;
+ phy-mode = "rmii";
+ phy-handle = <&ethphy0>;
+ status = "okay";
+};
+
+&fec2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_enet2>;
+ phy-mode = "mii";
+ phy-handle = <&ethphy1>;
+ status = "okay";
+
+ mdio {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ethphy0: ethernet-phy@1 {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <1>;
+ };
+
+ ethphy1: ethernet-phy@2 {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <2>;
+ };
+ };
+};
+
+&can2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_flexcan2>;
+ xceiver-supply = <&reg_can2_3v3>;
+ status = "disabled";
+};
+
+&gpc {
+ fsl,cpu_pupscr_sw2iso = <0xf>;
+ fsl,cpu_pupscr_sw = <0x0>;
+ fsl,cpu_pdnscr_iso2sw = <0x1>;
+ fsl,cpu_pdnscr_iso = <0x1>;
+ fsl,ldo-bypass = <1>; /* use ldo-bypass, u-boot will check it and configure */
+};
+
+&gpmi {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpmi_nand_1>;
+ status = "disabled";
+ nand-on-flash-bbt;
+};
+
+&i2c1 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c1>;
+ status = "okay";
+
+ pmic: pfuze100@08 {
+ compatible = "fsl,pfuze200";
+ reg = <0x08>;
+
+ regulators {
+ sw1a_reg: sw1ab {
+ regulator-min-microvolt = <300000>;
+ regulator-max-microvolt = <1875000>;
+ regulator-always-on;
+ regulator-ramp-delay = <6250>;
+ };
+
+ sw2_reg: sw2 {
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ sw3a_reg: sw3a {
+ regulator-min-microvolt = <400000>;
+ regulator-max-microvolt = <1975000>;
+ regulator-always-on;
+ };
+
+ sw3b_reg: sw3b {
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ swbst_reg: swbst {
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5150000>;
+ };
+
+ snvs_reg: vsnvs {
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-always-on;
+ };
+
+ vref_reg: vrefddr {
+ regulator-always-on;
+ };
+
+ vgen1_reg: vgen1 {
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1550000>;
+ };
+
+ vgen2_reg: vgen2 {
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1550000>;
+ };
+
+ vgen3_reg: vgen3 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ vgen4_reg: vgen4 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ vgen5_reg: vgen5 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ vgen6_reg: vgen6 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+ };
+ };
+};
+
+&iomuxc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_hog &pinctrl_hog1 &pinctrl_hog_sd>;
+
+ imx6ul-ddr3-arm2 {
+ pinctrl_hog: hoggrp {
+ fsl,pins = <
+ MX6UL_PAD_UART1_RTS_B__GPIO1_IO19 0x17059 /* SD1 CD */
+ MX6UL_PAD_UART1_CTS_B__GPIO1_IO18 0x17059 /* SD1 WP */
+ MX6UL_PAD_GPIO1_IO05__USDHC1_VSELECT 0x17059 /* SD1 VSELECT */
+ MX6UL_PAD_CSI_MCLK__GPIO4_IO17 0x17059 /* SD2 CD */
+ MX6UL_PAD_CSI_PIXCLK__GPIO4_IO18 0x17059 /* SD2 WP */
+ >;
+ };
+
+ pinctrl_hog1: hoggrp1 {
+ fsl,pins = <
+ MX6UL_PAD_NAND_ALE__GPIO4_IO10 0x17059 /* SD2 RESECT */
+ >;
+ };
+
+ pinctrl_hog_sd: hoggrp_sd {
+ fsl,pins = <
+ MX6UL_PAD_GPIO1_IO09__GPIO1_IO09 0x17059 /* SD1 RESET */
+ MX6UL_PAD_GPIO1_IO08__USDHC2_VSELECT 0x17059 /* SD2 VSELECT */
+ >;
+ };
+
+ pinctrl_adc1: adc1grp {
+ fsl,pins = <
+ MX6UL_PAD_GPIO1_IO00__GPIO1_IO00 0xb0
+ MX6UL_PAD_GPIO1_IO01__GPIO1_IO01 0xb0
+ >;
+ };
+
+ pinctrl_bt: btgrp {
+ fsl,pins = <
+ MX6UL_PAD_SNVS_TAMPER6__GPIO5_IO06 0x80000000
+ MX6UL_PAD_SNVS_TAMPER9__GPIO5_IO09 0x80000000
+ MX6UL_PAD_SNVS_TAMPER5__GPIO5_IO05 0x80000000
+ >;
+ };
+
+ pinctrl_ecspi1_cs_1: ecspi1_cs_grp-1 {
+ fsl,pins = <
+ MX6UL_PAD_CSI_DATA05__GPIO4_IO26 0x10b0
+ >;
+ };
+
+ pinctrl_ecspi1_1: ecspi1grp-1 {
+ fsl,pins = <
+ MX6UL_PAD_CSI_DATA06__ECSPI1_MOSI 0x10b0
+ MX6UL_PAD_CSI_DATA07__ECSPI1_MISO 0x10b0
+ MX6UL_PAD_CSI_DATA04__ECSPI1_SCLK 0x10b0
+ >;
+ };
+
+ pinctrl_enet1: enet1grp {
+ fsl,pins = <
+ MX6UL_PAD_ENET1_RX_EN__ENET1_RX_EN 0x1b0b0
+ MX6UL_PAD_ENET1_RX_ER__ENET1_RX_ER 0x1b0b0
+ MX6UL_PAD_ENET1_RX_DATA0__ENET1_RDATA00 0x1b0b0
+ MX6UL_PAD_ENET1_RX_DATA1__ENET1_RDATA01 0x1b0b0
+ MX6UL_PAD_ENET1_TX_EN__ENET1_TX_EN 0x1b0b0
+ MX6UL_PAD_ENET1_TX_DATA0__ENET1_TDATA00 0x1b0b0
+ MX6UL_PAD_ENET1_TX_DATA1__ENET1_TDATA01 0x1b0b0
+ MX6UL_PAD_ENET1_TX_CLK__ENET1_REF_CLK1 0x4001b0a8
+ >;
+ };
+
+ pinctrl_enet2: enet2grp {
+ fsl,pins = <
+ MX6UL_PAD_GPIO1_IO07__ENET2_MDC 0x1b0b0
+ MX6UL_PAD_GPIO1_IO06__ENET2_MDIO 0x1b0b0
+ MX6UL_PAD_ENET2_TX_DATA0__ENET2_TDATA00 0x1b0b0
+ MX6UL_PAD_ENET2_TX_DATA1__ENET2_TDATA01 0x1b0b0
+ MX6UL_PAD_UART4_TX_DATA__ENET2_TDATA02 0x1b0b0
+ MX6UL_PAD_UART4_RX_DATA__ENET2_TDATA03 0x1b0b0
+ MX6UL_PAD_ENET2_TX_CLK__ENET2_TX_CLK 0x4001b0a8
+ MX6UL_PAD_ENET2_TX_EN__ENET2_TX_EN 0x1b0b0
+ MX6UL_PAD_ENET2_RX_DATA0__ENET2_RDATA00 0x1b0b0
+ MX6UL_PAD_ENET2_RX_DATA1__ENET2_RDATA01 0x1b0b0
+ MX6UL_PAD_UART3_TX_DATA__ENET2_RDATA02 0x1b0b0
+ MX6UL_PAD_UART3_RX_DATA__ENET2_RDATA03 0x1b0b0
+ MX6UL_PAD_ENET2_RX_EN__ENET2_RX_EN 0x1b0b0
+ MX6UL_PAD_ENET2_RX_ER__ENET2_RX_ER 0x1b0b0
+ MX6UL_PAD_UART3_CTS_B__ENET2_RX_CLK 0x4001b0a8
+ MX6UL_PAD_UART5_RX_DATA__ENET2_COL 0x1b0b0
+ MX6UL_PAD_UART5_TX_DATA__ENET2_CRS 0x1b0b0
+ >;
+ };
+
+ pinctrl_flexcan2: flexcan2grp{
+ fsl,pins = <
+ MX6UL_PAD_UART2_RTS_B__FLEXCAN2_RX 0x1b020
+ MX6UL_PAD_UART2_CTS_B__FLEXCAN2_TX 0x1b020
+ MX6UL_PAD_JTAG_TRST_B__GPIO1_IO15 0x17059 /* STBY */
+ >;
+ };
+
+ pinctrl_gpmi_nand_1: gpmi-nand-1 {
+ fsl,pins = <
+ MX6UL_PAD_NAND_CLE__RAWNAND_CLE 0xb0b1
+ MX6UL_PAD_NAND_ALE__RAWNAND_ALE 0xb0b1
+ MX6UL_PAD_NAND_WP_B__RAWNAND_WP_B 0xb0b1
+ MX6UL_PAD_NAND_READY_B__RAWNAND_READY_B 0xb000
+ MX6UL_PAD_NAND_CE0_B__RAWNAND_CE0_B 0xb0b1
+ MX6UL_PAD_NAND_CE1_B__RAWNAND_CE1_B 0xb0b1
+ MX6UL_PAD_NAND_RE_B__RAWNAND_RE_B 0xb0b1
+ MX6UL_PAD_NAND_WE_B__RAWNAND_WE_B 0xb0b1
+ MX6UL_PAD_NAND_DATA00__RAWNAND_DATA00 0xb0b1
+ MX6UL_PAD_NAND_DATA01__RAWNAND_DATA01 0xb0b1
+ MX6UL_PAD_NAND_DATA02__RAWNAND_DATA02 0xb0b1
+ MX6UL_PAD_NAND_DATA03__RAWNAND_DATA03 0xb0b1
+ MX6UL_PAD_NAND_DATA04__RAWNAND_DATA04 0xb0b1
+ MX6UL_PAD_NAND_DATA05__RAWNAND_DATA05 0xb0b1
+ MX6UL_PAD_NAND_DATA06__RAWNAND_DATA06 0xb0b1
+ MX6UL_PAD_NAND_DATA07__RAWNAND_DATA07 0xb0b1
+ >;
+ };
+
+ pinctrl_i2c1: i2c1grp {
+ fsl,pins = <
+ MX6UL_PAD_GPIO1_IO03__I2C1_SDA 0x4001b8b1
+ MX6UL_PAD_GPIO1_IO02__I2C1_SCL 0x4001b8b1
+ >;
+ };
+
+ pinctrl_i2c4: i2c4grp {
+ fsl,pins = <
+ MX6UL_PAD_UART2_TX_DATA__I2C4_SCL 0x4001b8b0
+ MX6UL_PAD_UART2_RX_DATA__I2C4_SDA 0x4001b8b0
+ >;
+ };
+
+ pinctrl_lcdif_dat: lcdifdatgrp {
+ fsl,pins = <
+ MX6UL_PAD_LCD_DATA00__LCDIF_DATA00 0x79
+ MX6UL_PAD_LCD_DATA01__LCDIF_DATA01 0x79
+ MX6UL_PAD_LCD_DATA02__LCDIF_DATA02 0x79
+ MX6UL_PAD_LCD_DATA03__LCDIF_DATA03 0x79
+ MX6UL_PAD_LCD_DATA04__LCDIF_DATA04 0x79
+ MX6UL_PAD_LCD_DATA05__LCDIF_DATA05 0x79
+ MX6UL_PAD_LCD_DATA06__LCDIF_DATA06 0x79
+ MX6UL_PAD_LCD_DATA07__LCDIF_DATA07 0x79
+ MX6UL_PAD_LCD_DATA08__LCDIF_DATA08 0x79
+ MX6UL_PAD_LCD_DATA09__LCDIF_DATA09 0x79
+ MX6UL_PAD_LCD_DATA10__LCDIF_DATA10 0x79
+ MX6UL_PAD_LCD_DATA11__LCDIF_DATA11 0x79
+ MX6UL_PAD_LCD_DATA12__LCDIF_DATA12 0x79
+ MX6UL_PAD_LCD_DATA13__LCDIF_DATA13 0x79
+ MX6UL_PAD_LCD_DATA14__LCDIF_DATA14 0x79
+ MX6UL_PAD_LCD_DATA15__LCDIF_DATA15 0x79
+ MX6UL_PAD_LCD_DATA16__LCDIF_DATA16 0x79
+ MX6UL_PAD_LCD_DATA17__LCDIF_DATA17 0x79
+ MX6UL_PAD_LCD_DATA18__LCDIF_DATA18 0x79
+ MX6UL_PAD_LCD_DATA19__LCDIF_DATA19 0x79
+ MX6UL_PAD_LCD_DATA20__LCDIF_DATA20 0x79
+ MX6UL_PAD_LCD_DATA21__LCDIF_DATA21 0x79
+ MX6UL_PAD_LCD_DATA22__LCDIF_DATA22 0x79
+ MX6UL_PAD_LCD_DATA23__LCDIF_DATA23 0x79
+ >;
+ };
+
+ pinctrl_lcdif_ctrl: lcdifctrlgrp {
+ fsl,pins = <
+ MX6UL_PAD_LCD_CLK__LCDIF_CLK 0x79
+ MX6UL_PAD_LCD_ENABLE__LCDIF_ENABLE 0x79
+ MX6UL_PAD_LCD_HSYNC__LCDIF_HSYNC 0x79
+ MX6UL_PAD_LCD_VSYNC__LCDIF_VSYNC 0x79
+ MX6UL_PAD_LCD_RESET__LCDIF_RESET 0x79
+ >;
+ };
+
+ pinctrl_mqs: mqsgrp {
+ fsl,pins = <
+ MX6UL_PAD_JTAG_TDI__MQS_LEFT 0x11088
+ MX6UL_PAD_JTAG_TDO__MQS_RIGHT 0x11088
+ >;
+ };
+
+ pinctrl_pwm1: pmw1grp {
+ fsl,pins = <
+ MX6UL_PAD_ENET1_RX_DATA0__PWM1_OUT 0x110b0
+ >;
+ };
+
+ pinctrl_qspi: qspigrp {
+ fsl,pins = <
+ MX6UL_PAD_NAND_WP_B__QSPI_A_SCLK 0x70a1
+ MX6UL_PAD_NAND_READY_B__QSPI_A_DATA00 0x70a1
+ MX6UL_PAD_NAND_CE0_B__QSPI_A_DATA01 0x70a1
+ MX6UL_PAD_NAND_CE1_B__QSPI_A_DATA02 0x70a1
+ MX6UL_PAD_NAND_CLE__QSPI_A_DATA03 0x70a1
+ MX6UL_PAD_NAND_DQS__QSPI_A_SS0_B 0x70a1
+ MX6UL_PAD_NAND_DATA07__QSPI_A_SS1_B 0x70a1
+ MX6UL_PAD_NAND_RE_B__QSPI_B_SCLK 0x70a1
+ MX6UL_PAD_NAND_DATA02__QSPI_B_DATA00 0x70a1
+ MX6UL_PAD_NAND_DATA03__QSPI_B_DATA01 0x70a1
+ MX6UL_PAD_NAND_DATA04__QSPI_B_DATA02 0x70a1
+ MX6UL_PAD_NAND_DATA05__QSPI_B_DATA03 0x70a1
+ MX6UL_PAD_NAND_WE_B__QSPI_B_SS0_B 0x70a1
+ MX6UL_PAD_NAND_DATA00__QSPI_B_SS1_B 0x70a1
+ >;
+ };
+
+ pinctrl_sai2: sai2grp {
+ fsl,pins = <
+ MX6UL_PAD_SD1_DATA0__SAI2_TX_SYNC 0x1b0b0
+ MX6UL_PAD_SD1_DATA1__SAI2_TX_BCLK 0x1b0b0
+ MX6UL_PAD_SD1_DATA2__SAI2_RX_DATA 0x110b0
+ MX6UL_PAD_SD1_DATA3__SAI2_TX_DATA 0x1f0b8
+ MX6UL_PAD_SD1_CLK__SAI2_MCLK 0x1b0b0
+ MX6UL_PAD_SNVS_TAMPER0__GPIO5_IO00 0x17059
+ >;
+ };
+
+ pinctrl_spdif: spdifgrp {
+ fsl,pins = <
+ MX6UL_PAD_GPIO1_IO08__SPDIF_OUT 0x1b0b0
+ MX6UL_PAD_GPIO1_IO09__SPDIF_IN 0x1b0b0
+ >;
+ };
+
+ pinctrl_tsc: tscgrp {
+ fsl,pins = <
+ MX6UL_PAD_GPIO1_IO01__GPIO1_IO01 0xb0
+ MX6UL_PAD_GPIO1_IO02__GPIO1_IO02 0xb0
+ MX6UL_PAD_GPIO1_IO03__GPIO1_IO03 0xb0
+ MX6UL_PAD_GPIO1_IO04__GPIO1_IO04 0xb0
+ >;
+ };
+
+ pinctrl_uart1: uart1grp {
+ fsl,pins = <
+ MX6UL_PAD_UART1_TX_DATA__UART1_DCE_TX 0x1b0b1
+ MX6UL_PAD_UART1_RX_DATA__UART1_DCE_RX 0x1b0b1
+ >;
+ };
+
+ pinctrl_uart2: uart2grp {
+ fsl,pins = <
+ MX6UL_PAD_UART2_TX_DATA__UART2_DCE_TX 0x1b0b1
+ MX6UL_PAD_UART2_RX_DATA__UART2_DCE_RX 0x1b0b1
+ MX6UL_PAD_UART2_CTS_B__UART2_DCE_CTS 0x1b0b1
+ MX6UL_PAD_UART2_RTS_B__UART2_DCE_RTS 0x1b0b1
+ >;
+ };
+
+ pinctrl_uart2dte: uart2dtegrp {
+ fsl,pins = <
+ MX6UL_PAD_UART2_TX_DATA__UART2_DTE_RX 0x1b0b1
+ MX6UL_PAD_UART2_RX_DATA__UART2_DTE_TX 0x1b0b1
+ MX6UL_PAD_UART2_CTS_B__UART2_DTE_RTS 0x1b0b1
+ MX6UL_PAD_UART2_RTS_B__UART2_DTE_CTS 0x1b0b1
+ >;
+ };
+
+ pinctrl_usb_otg1_id: usbotg1idgrp {
+ fsl,pins = <
+ MX6UL_PAD_GPIO1_IO00__ANATOP_OTG1_ID 0x17059
+ >;
+ };
+
+ pinctrl_usb_otg1: usbotg1grp {
+ fsl,pins = <
+ MX6UL_PAD_GPIO1_IO04__GPIO1_IO04 0x10b0
+ >;
+ };
+
+ pinctrl_usdhc1: usdhc1grp {
+ fsl,pins = <
+ MX6UL_PAD_SD1_CMD__USDHC1_CMD 0x17059
+ MX6UL_PAD_SD1_CLK__USDHC1_CLK 0x10059
+ MX6UL_PAD_SD1_DATA0__USDHC1_DATA0 0x17059
+ MX6UL_PAD_SD1_DATA1__USDHC1_DATA1 0x17059
+ MX6UL_PAD_SD1_DATA2__USDHC1_DATA2 0x17059
+ MX6UL_PAD_SD1_DATA3__USDHC1_DATA3 0x17059
+ >;
+ };
+
+ pinctrl_usdhc1_100mhz: usdhc1grp100mhz {
+ fsl,pins = <
+ MX6UL_PAD_SD1_CMD__USDHC1_CMD 0x170b9
+ MX6UL_PAD_SD1_CLK__USDHC1_CLK 0x100b9
+ MX6UL_PAD_SD1_DATA0__USDHC1_DATA0 0x170b9
+ MX6UL_PAD_SD1_DATA1__USDHC1_DATA1 0x170b9
+ MX6UL_PAD_SD1_DATA2__USDHC1_DATA2 0x170b9
+ MX6UL_PAD_SD1_DATA3__USDHC1_DATA3 0x170b9
+ >;
+ };
+
+ pinctrl_usdhc1_200mhz: usdhc1grp200mhz {
+ fsl,pins = <
+ MX6UL_PAD_SD1_CMD__USDHC1_CMD 0x170f9
+ MX6UL_PAD_SD1_CLK__USDHC1_CLK 0x100f9
+ MX6UL_PAD_SD1_DATA0__USDHC1_DATA0 0x170f9
+ MX6UL_PAD_SD1_DATA1__USDHC1_DATA1 0x170f9
+ MX6UL_PAD_SD1_DATA2__USDHC1_DATA2 0x170f9
+ MX6UL_PAD_SD1_DATA3__USDHC1_DATA3 0x170f9
+ >;
+ };
+
+ pinctrl_usdhc1_8bit: usdhc1_8bit_grp {
+ fsl,pins = <
+ MX6UL_PAD_SD1_CMD__USDHC1_CMD 0x17059
+ MX6UL_PAD_SD1_CLK__USDHC1_CLK 0x10059
+ MX6UL_PAD_SD1_DATA0__USDHC1_DATA0 0x17059
+ MX6UL_PAD_SD1_DATA1__USDHC1_DATA1 0x17059
+ MX6UL_PAD_SD1_DATA2__USDHC1_DATA2 0x17059
+ MX6UL_PAD_SD1_DATA3__USDHC1_DATA3 0x17059
+ MX6UL_PAD_NAND_READY_B__USDHC1_DATA4 0x17059
+ MX6UL_PAD_NAND_CE0_B__USDHC1_DATA5 0x17059
+ MX6UL_PAD_NAND_CE1_B__USDHC1_DATA6 0x17059
+ MX6UL_PAD_NAND_CLE__USDHC1_DATA7 0x17059
+ >;
+ };
+
+ pinctrl_usdhc1_8bit_100mhz: usdhc1_8bit_100mhz_grp {
+ fsl,pins = <
+ MX6UL_PAD_SD1_CMD__USDHC1_CMD 0x170b9
+ MX6UL_PAD_SD1_CLK__USDHC1_CLK 0x100b9
+ MX6UL_PAD_SD1_DATA0__USDHC1_DATA0 0x170b9
+ MX6UL_PAD_SD1_DATA1__USDHC1_DATA1 0x170b9
+ MX6UL_PAD_SD1_DATA2__USDHC1_DATA2 0x170b9
+ MX6UL_PAD_SD1_DATA3__USDHC1_DATA3 0x170b9
+ MX6UL_PAD_NAND_READY_B__USDHC1_DATA4 0x170b9
+ MX6UL_PAD_NAND_CE0_B__USDHC1_DATA5 0x170b9
+ MX6UL_PAD_NAND_CE1_B__USDHC1_DATA6 0x170b9
+ MX6UL_PAD_NAND_CLE__USDHC1_DATA7 0x170b9
+ >;
+ };
+
+ pinctrl_usdhc1_8bit_200mhz: usdhc1_8bit_200mhz_grp {
+ fsl,pins = <
+ MX6UL_PAD_SD1_CMD__USDHC1_CMD 0x170f9
+ MX6UL_PAD_SD1_CLK__USDHC1_CLK 0x100f9
+ MX6UL_PAD_SD1_DATA0__USDHC1_DATA0 0x170f9
+ MX6UL_PAD_SD1_DATA1__USDHC1_DATA1 0x170f9
+ MX6UL_PAD_SD1_DATA2__USDHC1_DATA2 0x170f9
+ MX6UL_PAD_SD1_DATA3__USDHC1_DATA3 0x170f9
+ MX6UL_PAD_NAND_READY_B__USDHC1_DATA4 0x170f9
+ MX6UL_PAD_NAND_CE0_B__USDHC1_DATA5 0x170f9
+ MX6UL_PAD_NAND_CE1_B__USDHC1_DATA6 0x170f9
+ MX6UL_PAD_NAND_CLE__USDHC1_DATA7 0x170f9
+ >;
+ };
+
+ pinctrl_usdhc2: usdhc2grp {
+ fsl,pins = <
+ MX6UL_PAD_CSI_HSYNC__USDHC2_CMD 0x17059
+ MX6UL_PAD_CSI_VSYNC__USDHC2_CLK 0x10059
+ MX6UL_PAD_CSI_DATA00__USDHC2_DATA0 0x17059
+ MX6UL_PAD_CSI_DATA01__USDHC2_DATA1 0x17059
+ MX6UL_PAD_CSI_DATA02__USDHC2_DATA2 0x17059
+ MX6UL_PAD_CSI_DATA03__USDHC2_DATA3 0x17059
+ >;
+ };
+
+ pinctrl_usdhc2_100mhz: usdhc2grp100mhz {
+ fsl,pins = <
+ MX6UL_PAD_CSI_HSYNC__USDHC2_CMD 0x170b9
+ MX6UL_PAD_CSI_VSYNC__USDHC2_CLK 0x100b9
+ MX6UL_PAD_CSI_DATA00__USDHC2_DATA0 0x170b9
+ MX6UL_PAD_CSI_DATA01__USDHC2_DATA1 0x170b9
+ MX6UL_PAD_CSI_DATA02__USDHC2_DATA2 0x170b9
+ MX6UL_PAD_CSI_DATA03__USDHC2_DATA3 0x170b9
+ >;
+ };
+
+ pinctrl_usdhc2_200mhz: usdhc2grp200mhz {
+ fsl,pins = <
+ MX6UL_PAD_CSI_HSYNC__USDHC2_CMD 0x170f9
+ MX6UL_PAD_CSI_VSYNC__USDHC2_CLK 0x100f9
+ MX6UL_PAD_CSI_DATA00__USDHC2_DATA0 0x170f9
+ MX6UL_PAD_CSI_DATA01__USDHC2_DATA1 0x170f9
+ MX6UL_PAD_CSI_DATA02__USDHC2_DATA2 0x170f9
+ MX6UL_PAD_CSI_DATA03__USDHC2_DATA3 0x170f9
+ >;
+ };
+ };
+};
+
+&pxp {
+ status = "okay";
+};
+
+&qspi {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_qspi>;
+ status = "okay";
+ fsl,qspi-has-second-chip = <1>;
+ ddrsmp=<0>;
+
+ flash0: n25q256a@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "micron,n25q256a";
+ spi-max-frequency = <29000000>;
+ spi-nor,ddr-quad-read-dummy = <6>;
+ reg = <0>;
+ };
+
+ flash1: n25q256a@1 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "micron,n25q256a";
+ spi-max-frequency = <29000000>;
+ spi-nor,ddr-quad-read-dummy = <6>;
+ reg = <1>;
+ };
+
+ flash2: n25q256a@2 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "micron,n25q256a";
+ spi-max-frequency = <29000000>;
+ spi-nor,ddr-quad-read-dummy = <6>;
+ reg = <2>;
+ };
+
+ flash3: n25q256a@3 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "micron,n25q256a";
+ spi-max-frequency = <29000000>;
+ spi-nor,ddr-quad-read-dummy = <6>;
+ reg = <3>;
+ };
+};
+
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart1>;
+ status = "okay";
+};
+
+&uart2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart2
+ &pinctrl_bt>;
+ fsl,uart-has-rtscts;
+ /* for DTE mode, add below change */
+ /* fsl,dte-mode; */
+ /* pinctrl-0 = <&pinctrl_uart2dte>; */
+ status = "okay";
+};
+
+&usbotg1 {
+ vbus-supply = <&reg_usb_otg1_vbus>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usb_otg1_id>;
+ srp-disable;
+ hnp-disable;
+ adp-disable;
+ status = "okay";
+};
+
+&usdhc1 {
+ pinctrl-names = "default", "state_100mhz", "state_200mhz";
+ pinctrl-0 = <&pinctrl_usdhc1>;
+ pinctrl-1 = <&pinctrl_usdhc1_100mhz>;
+ pinctrl-2 = <&pinctrl_usdhc1_200mhz>;
+ cd-gpios = <&gpio1 19 GPIO_ACTIVE_LOW>;
+ wp-gpios = <&gpio1 18 GPIO_ACTIVE_HIGH>;
+ keep-power-in-suspend;
+ enable-sdio-wakeup;
+ vmmc-supply = <&reg_sd1_vmmc>;
+ status = "okay";
+};
+
+&usdhc2 {
+ pinctrl-names = "default", "state_100mhz", "state_200mhz";
+ pinctrl-0 = <&pinctrl_usdhc2>;
+ pinctrl-1 = <&pinctrl_usdhc2_100mhz>;
+ pinctrl-2 = <&pinctrl_usdhc2_200mhz>;
+ cd-gpios = <&gpio4 17 GPIO_ACTIVE_LOW>;
+ wp-gpios = <&gpio4 18 GPIO_ACTIVE_HIGH>;
+ keep-power-in-suspend;
+ enable-sdio-wakeup;
+ vmmc-supply = <&reg_sd2_vmmc>;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx6ul-14x14-evk-btwifi-oob.dts b/arch/arm/boot/dts/imx6ul-14x14-evk-btwifi-oob.dts
new file mode 100644
index 000000000000..90e0045fa2e4
--- /dev/null
+++ b/arch/arm/boot/dts/imx6ul-14x14-evk-btwifi-oob.dts
@@ -0,0 +1,10 @@
+/*
+ * Copyright (C) 2017 NXP
+ *
+ * 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 "imx6ul-14x14-evk-btwifi.dts"
+#include "imx6ul-evk-btwifi-oob.dtsi"
diff --git a/arch/arm/boot/dts/imx6ul-14x14-evk-btwifi.dts b/arch/arm/boot/dts/imx6ul-14x14-evk-btwifi.dts
new file mode 100644
index 000000000000..4613799a97c7
--- /dev/null
+++ b/arch/arm/boot/dts/imx6ul-14x14-evk-btwifi.dts
@@ -0,0 +1,10 @@
+/*
+ * Copyright (C) 2015 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 "imx6ul-14x14-evk.dts"
+#include "imx6ul-evk-btwifi.dtsi"
diff --git a/arch/arm/boot/dts/imx6ul-14x14-evk-csi.dts b/arch/arm/boot/dts/imx6ul-14x14-evk-csi.dts
new file mode 100644
index 000000000000..f2bf26fff351
--- /dev/null
+++ b/arch/arm/boot/dts/imx6ul-14x14-evk-csi.dts
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2015 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 "imx6ul-14x14-evk.dts"
+
+
+&csi {
+ status = "okay";
+};
+
+&ov5640 {
+ status = "okay";
+};
+
+&sim2 {
+ status = "disabled";
+};
diff --git a/arch/arm/boot/dts/imx6ul-14x14-evk-ecspi-slave.dts b/arch/arm/boot/dts/imx6ul-14x14-evk-ecspi-slave.dts
new file mode 100644
index 000000000000..9c91f2553031
--- /dev/null
+++ b/arch/arm/boot/dts/imx6ul-14x14-evk-ecspi-slave.dts
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2018 NXP
+ *
+ * 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 file for ECSPI Slave Certification at i.mx6ul 14x14 evk board.
+ * NOTE: Because Ethernet2 use the same pins with ecspi4, so disable
+ * fec1/fec2 for ECSPI4 test.
+ */
+
+#include "imx6ul-14x14-evk-ecspi.dts"
+
+/delete-node/&spidev0;
+
+&ecspi4 {
+ spi-slave;
+};
diff --git a/arch/arm/boot/dts/imx6ul-14x14-evk-ecspi.dts b/arch/arm/boot/dts/imx6ul-14x14-evk-ecspi.dts
new file mode 100644
index 000000000000..146700209693
--- /dev/null
+++ b/arch/arm/boot/dts/imx6ul-14x14-evk-ecspi.dts
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2018 NXP
+ *
+ * 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 file for ECSPI Certification at i.mx6ul 14x14 evk board.
+ * NOTE: Because Ethernet2 use the same pins with ecspi4, so disable
+ * fec1/fec2 for ECSPI4 test.
+ */
+
+#include "imx6ul-14x14-evk.dts"
+
+&iomuxc {
+ pinctrl_ecspi4: ecspi4grp {
+ fsl,pins = <
+ MX6UL_PAD_ENET2_TX_DATA1__ECSPI4_SCLK 0x70a1
+ MX6UL_PAD_ENET2_TX_EN__ECSPI4_MOSI 0x70a1
+ MX6UL_PAD_ENET2_TX_CLK__ECSPI4_MISO 0x70a1
+ MX6UL_PAD_ENET2_RX_ER__ECSPI4_SS0 0x70a1
+ >;
+ };
+};
+
+&ecspi4 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ecspi4>;
+ status = "okay";
+
+ spidev0: spi@0 {
+ reg = <0>;
+ compatible = "rohm,dh2228fv";
+ spi-max-frequency = <20000000>;
+ };
+};
+
+&fec1 {
+ status = "disabled";
+};
+
+&fec2 {
+ status = "disabled";
+};
diff --git a/arch/arm/boot/dts/imx6ul-14x14-evk-emmc.dts b/arch/arm/boot/dts/imx6ul-14x14-evk-emmc.dts
new file mode 100644
index 000000000000..b56d34d9f8a4
--- /dev/null
+++ b/arch/arm/boot/dts/imx6ul-14x14-evk-emmc.dts
@@ -0,0 +1,20 @@
+
+/*
+ * Copyright (C) 2016 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 "imx6ul-14x14-evk.dts"
+
+&usdhc2 {
+ pinctrl-names = "default", "state_100mhz", "state_200mhz";
+ pinctrl-0 = <&pinctrl_usdhc2_8bit>;
+ pinctrl-1 = <&pinctrl_usdhc2_8bit_100mhz>;
+ pinctrl-2 = <&pinctrl_usdhc2_8bit_200mhz>;
+ bus-width = <8>;
+ non-removable;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx6ul-14x14-evk-gpmi-weim.dts b/arch/arm/boot/dts/imx6ul-14x14-evk-gpmi-weim.dts
new file mode 100644
index 000000000000..7cff0874697b
--- /dev/null
+++ b/arch/arm/boot/dts/imx6ul-14x14-evk-gpmi-weim.dts
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2015 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 "imx6ul-14x14-evk.dts"
+
+&gpmi {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpmi_nand_1>;
+ status = "okay";
+ nand-on-flash-bbt;
+};
+
+&iomuxc {
+ imx6ul-evk-gpmi-rework {
+ pinctrl_gpmi_nand_1: gpmi-nand-1 {
+ fsl,pins = <
+ MX6UL_PAD_NAND_CLE__RAWNAND_CLE 0xb0b1
+ MX6UL_PAD_NAND_ALE__RAWNAND_ALE 0xb0b1
+ MX6UL_PAD_NAND_WP_B__RAWNAND_WP_B 0xb0b1
+ MX6UL_PAD_NAND_READY_B__RAWNAND_READY_B 0xb000
+ MX6UL_PAD_NAND_CE0_B__RAWNAND_CE0_B 0xb0b1
+ MX6UL_PAD_NAND_CE1_B__RAWNAND_CE1_B 0xb0b1
+ MX6UL_PAD_NAND_RE_B__RAWNAND_RE_B 0xb0b1
+ MX6UL_PAD_NAND_WE_B__RAWNAND_WE_B 0xb0b1
+ MX6UL_PAD_NAND_DATA00__RAWNAND_DATA00 0xb0b1
+ MX6UL_PAD_NAND_DATA01__RAWNAND_DATA01 0xb0b1
+ MX6UL_PAD_NAND_DATA02__RAWNAND_DATA02 0xb0b1
+ MX6UL_PAD_NAND_DATA03__RAWNAND_DATA03 0xb0b1
+ MX6UL_PAD_NAND_DATA04__RAWNAND_DATA04 0xb0b1
+ MX6UL_PAD_NAND_DATA05__RAWNAND_DATA05 0xb0b1
+ MX6UL_PAD_NAND_DATA06__RAWNAND_DATA06 0xb0b1
+ MX6UL_PAD_NAND_DATA07__RAWNAND_DATA07 0xb0b1
+ >;
+ };
+ };
+};
+
+&qspi {
+ status = "disabled";
+};
+
+&usdhc2 {
+ status = "disabled";
+};
diff --git a/arch/arm/boot/dts/imx6ul-14x14-evk-pf1550.dts b/arch/arm/boot/dts/imx6ul-14x14-evk-pf1550.dts
new file mode 100644
index 000000000000..d319f2ea551d
--- /dev/null
+++ b/arch/arm/boot/dts/imx6ul-14x14-evk-pf1550.dts
@@ -0,0 +1,133 @@
+/*
+ * Copyright (C) 2016 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 "imx6ul-14x14-evk.dts"
+
+&cpu0 {
+ /*
+ * on i.MX6UL, no separated VDD_ARM_IN and VDD_SOC_IN,
+ * to align with other platform and use the same cpufreq
+ * driver, still use the separated OPP define for arm
+ * and soc.
+ */
+ operating-points = <
+ /* kHz uV */
+ 696000 1275000
+ 528000 1175000
+ 396000 1175000
+ 198000 1175000
+ >;
+ fsl,soc-operating-points = <
+ /* KHz uV */
+ 696000 1275000
+ 528000 1175000
+ 396000 1175000
+ 198000 1175000
+ >;
+ fsl,arm-soc-shared = <1>;
+};
+
+&reg_arm {
+ vin-supply = <&sw1_reg>;
+ regulator-allow-bypass;
+};
+
+&reg_soc {
+ vin-supply = <&sw1_reg>;
+ regulator-allow-bypass;
+};
+
+&gpc {
+ fsl,ldo-bypass = <1>; /* use ldo-bypass */
+};
+
+&i2c1 {
+ pmic: pf1550@08 {
+ compatible = "fsl,pf1550";
+ interrupt-parent = <&gpio5>;
+ interrupts = <4 8>;
+ reg = <0x08>;
+ pinctrl-0 = <&pinctrl_pf1550>;
+
+ onkey {
+ compatible = "fsl,pf1550-onkey";
+ linux,keycode = <KEY_POWER>;
+ wakeup;
+ };
+
+ charger {
+ compatible = "fsl,pf1550-charger";
+ };
+
+ regulators {
+ compatible = "fsl,pf1550-regulator";
+
+ sw1_reg: SW1 {
+ regulator-name = "SW1";
+ regulator-min-microvolt = <600000>;
+ regulator-max-microvolt = <1387500>;
+ regulator-boot-on;
+ regulator-always-on;
+ regulator-ramp-delay = <6250>;
+ };
+
+ sw2_reg: SW2 {
+ regulator-name = "SW2";
+ regulator-min-microvolt = <600000>;
+ regulator-max-microvolt = <1387500>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ sw3_reg: SW3 {
+ regulator-name = "SW3";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ vref_reg: VREFDDR {
+ regulator-name = "VREFDDR";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ vldo1_reg: LDO1 {
+ regulator-name = "LDO1";
+ regulator-min-microvolt = <750000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ vldo2_reg: LDO2 {
+ regulator-name = "LDO2";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ vldo3_reg: LDO3 {
+ regulator-name = "LDO3";
+ regulator-min-microvolt = <750000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+ };
+ };
+};
+
+&sai2 {
+ status = "disabled";
+};
+
+&sound {
+ status = "disabled";
+};
diff --git a/arch/arm/boot/dts/imx6ul-14x14-evk-usb-certi.dts b/arch/arm/boot/dts/imx6ul-14x14-evk-usb-certi.dts
new file mode 100644
index 000000000000..8aaf248812e6
--- /dev/null
+++ b/arch/arm/boot/dts/imx6ul-14x14-evk-usb-certi.dts
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2016 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 file for USB Certification at i.mx6ul 14x14 evk board */
+
+#include "imx6ul-14x14-evk.dts"
+
+/ {
+ regulators {
+ reg_usb_otg2_vbus: regulator@3 {
+ compatible = "regulator-fixed";
+ reg = <3>;
+ regulator-name = "usb_otg2_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&gpio1 2 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+ };
+};
+
+&usbotg2 {
+ vbus-supply = <&reg_usb_otg2_vbus>; /* hardware rework is needed */
+ tpl-support;
+};
+
+&tsc {
+ status = "disabled";
+};
diff --git a/arch/arm/boot/dts/imx6ul-14x14-evk.dts b/arch/arm/boot/dts/imx6ul-14x14-evk.dts
index 9c23e017d86a..d61ce3637e5b 100644
--- a/arch/arm/boot/dts/imx6ul-14x14-evk.dts
+++ b/arch/arm/boot/dts/imx6ul-14x14-evk.dts
@@ -22,6 +22,19 @@
reg = <0x80000000 0x20000000>;
};
+ reserved-memory {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ linux,cma {
+ compatible = "shared-dma-pool";
+ reusable;
+ size = <0x14000000>;
+ linux,cma-default;
+ };
+ };
+
backlight_display: backlight-display {
compatible = "pwm-backlight";
pwms = <&pwm1 0 5000000>;
@@ -30,6 +43,11 @@
status = "okay";
};
+ pxp_v4l2 {
+ compatible = "fsl,imx6ul-pxp-v4l2", "fsl,imx6sx-pxp-v4l2", "fsl,imx6sl-pxp-v4l2";
+ status = "okay";
+ };
+
regulators {
compatible = "simple-bus";
#address-cells = <1>;
@@ -41,52 +59,90 @@
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
gpio = <&gpio1 9 GPIO_ACTIVE_HIGH>;
+ off-on-delay = <20000>;
enable-active-high;
};
+
+ reg_can_3v3: regulator@0 {
+ compatible = "regulator-fixed";
+ reg = <0>;
+ regulator-name = "can-3v3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpios = <&gpio_spi 3 GPIO_ACTIVE_LOW>;
+ };
+
+ reg_gpio_dvfs: regulator-gpio {
+ compatible = "regulator-gpio";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_dvfs>;
+ regulator-min-microvolt = <1300000>;
+ regulator-max-microvolt = <1400000>;
+ regulator-name = "gpio_dvfs";
+ regulator-type = "voltage";
+ gpios = <&gpio5 3 GPIO_ACTIVE_HIGH>;
+ states = <1300000 0x1 1400000 0x0>;
+ };
};
- sound {
- compatible = "simple-audio-card";
- simple-audio-card,name = "mx6ul-wm8960";
- simple-audio-card,format = "i2s";
- simple-audio-card,bitclock-master = <&dailink_master>;
- simple-audio-card,frame-master = <&dailink_master>;
- simple-audio-card,widgets =
- "Microphone", "Mic Jack",
- "Line", "Line In",
- "Line", "Line Out",
- "Speaker", "Speaker",
- "Headphone", "Headphone Jack";
- simple-audio-card,routing =
+ sound: sound {
+ compatible = "fsl,imx6ul-evk-wm8960",
+ "fsl,imx-audio-wm8960";
+ model = "wm8960-audio";
+ cpu-dai = <&sai2>;
+ audio-codec = <&codec>;
+ asrc-controller = <&asrc>;
+ codec-master;
+ gpr = <&gpr 4 0x100000 0x100000>;
+ /*
+ * hp-det = <hp-det-pin hp-det-polarity>;
+ * hp-det-pin: JD1 JD2 or JD3
+ * hp-det-polarity = 0: hp detect high for headphone
+ * hp-det-polarity = 1: hp detect high for speaker
+ */
+ hp-det = <3 0>;
+ hp-det-gpios = <&gpio5 4 0>;
+ mic-det-gpios = <&gpio5 4 0>;
+ audio-routing =
"Headphone Jack", "HP_L",
"Headphone Jack", "HP_R",
- "Speaker", "SPK_LP",
- "Speaker", "SPK_LN",
- "Speaker", "SPK_RP",
- "Speaker", "SPK_RN",
- "LINPUT1", "Mic Jack",
+ "Ext Spk", "SPK_LP",
+ "Ext Spk", "SPK_LN",
+ "Ext Spk", "SPK_RP",
+ "Ext Spk", "SPK_RN",
+ "LINPUT2", "Mic Jack",
"LINPUT3", "Mic Jack",
- "RINPUT1", "Mic Jack",
- "RINPUT2", "Mic Jack";
-
- simple-audio-card,cpu {
- sound-dai = <&sai2>;
- };
-
- dailink_master: simple-audio-card,codec {
- sound-dai = <&codec>;
- clocks = <&clks IMX6UL_CLK_SAI2>;
- };
+ "RINPUT1", "Main MIC",
+ "RINPUT2", "Main MIC",
+ "Mic Jack", "MICB",
+ "Main MIC", "MICB",
+ "CPU-Playback", "ASRC-Playback",
+ "Playback", "CPU-Playback",
+ "ASRC-Capture", "CPU-Capture",
+ "CPU-Capture", "Capture";
};
- panel {
- compatible = "innolux,at043tn24";
- backlight = <&backlight_display>;
+ spi4 {
+ compatible = "spi-gpio";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_spi4>;
+ pinctrl-assert-gpios = <&gpio5 8 GPIO_ACTIVE_LOW>;
+ status = "okay";
+ gpio-sck = <&gpio5 11 0>;
+ gpio-mosi = <&gpio5 10 0>;
+ cs-gpios = <&gpio5 7 0>;
+ num-chipselects = <1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
- port {
- panel_in: endpoint {
- remote-endpoint = <&display_out>;
- };
+ gpio_spi: gpio_spi@0 {
+ compatible = "fairchild,74hc595";
+ gpio-controller;
+ #gpio-cells = <2>;
+ reg = <0>;
+ registers-number = <1>;
+ registers-default = /bits/ 8 <0x57>;
+ spi-max-frequency = <100000>;
};
};
};
@@ -96,6 +152,10 @@
assigned-clock-rates = <786432000>;
};
+&cpu0 {
+ dc-supply = <&reg_gpio_dvfs>;
+};
+
&i2c2 {
clock_frequency = <100000>;
pinctrl-names = "default";
@@ -107,6 +167,38 @@
compatible = "wlf,wm8960";
reg = <0x1a>;
wlf,shared-lrclk;
+ clocks = <&clks IMX6UL_CLK_SAI2>;
+ clock-names = "mclk";
+ };
+
+ ov5640: ov5640@3c {
+ compatible = "ovti,ov5640";
+ reg = <0x3c>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_csi1>;
+ clocks = <&clks IMX6UL_CLK_CSI>;
+ clock-names = "csi_mclk";
+ pwn-gpios = <&gpio_spi 6 1>;
+ rst-gpios = <&gpio_spi 5 0>;
+ csi_id = <0>;
+ mclk = <24000000>;
+ mclk_source = <0>;
+ status = "disabled";
+ port {
+ ov5640_ep: endpoint {
+ remote-endpoint = <&csi1_ep>;
+ };
+ };
+ };
+};
+
+&csi {
+ status = "disabled";
+
+ port {
+ csi1_ep: endpoint {
+ remote-endpoint = <&ov5640_ep>;
+ };
};
};
@@ -130,6 +222,7 @@
#size-cells = <0>;
ethphy0: ethernet-phy@2 {
+ compatible = "ethernet-phy-ieee802.3-c22";
reg = <2>;
micrel,led-mode = <1>;
clocks = <&clks IMX6UL_CLK_ENET_REF>;
@@ -137,6 +230,7 @@
};
ethphy1: ethernet-phy@1 {
+ compatible = "ethernet-phy-ieee802.3-c22";
reg = <1>;
micrel,led-mode = <1>;
clocks = <&clks IMX6UL_CLK_ENET2_REF>;
@@ -145,16 +239,78 @@
};
};
+&can1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_flexcan1>;
+ xceiver-supply = <&reg_can_3v3>;
+ status = "okay";
+};
+
+&can2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_flexcan2>;
+ xceiver-supply = <&reg_can_3v3>;
+ status = "okay";
+};
+
+&gpc {
+ fsl,cpu_pupscr_sw2iso = <0xf>;
+ fsl,cpu_pupscr_sw = <0x0>;
+ fsl,cpu_pdnscr_iso2sw = <0x1>;
+ fsl,cpu_pdnscr_iso = <0x1>;
+ fsl,ldo-bypass = <0>; /* DCDC, ldo-enable */
+};
+
+&i2c1 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c1>;
+ status = "okay";
+
+ mag3110@0e {
+ compatible = "fsl,mag3110";
+ reg = <0x0e>;
+ position = <2>;
+ };
+
+ fxls8471@1e {
+ compatible = "fsl,fxls8471";
+ reg = <0x1e>;
+ position = <0>;
+ interrupt-parent = <&gpio5>;
+ interrupts = <0 8>;
+ };
+};
&lcdif {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_lcdif_dat
&pinctrl_lcdif_ctrl>;
+ display = <&display0>;
status = "okay";
- port {
- display_out: endpoint {
- remote-endpoint = <&panel_in>;
+ display0: display {
+ bits-per-pixel = <16>;
+ bus-width = <24>;
+
+ display-timings {
+ native-mode = <&timing0>;
+
+ timing0: timing0 {
+ clock-frequency = <9200000>;
+ hactive = <480>;
+ vactive = <272>;
+ hfront-porch = <8>;
+ hback-porch = <4>;
+ hsync-len = <41>;
+ vback-porch = <2>;
+ vfront-porch = <4>;
+ vsync-len = <10>;
+ hsync-active = <0>;
+ vsync-active = <0>;
+ de-active = <1>;
+ pixelclk-active = <0>;
+ };
};
};
};
@@ -165,16 +321,22 @@
status = "okay";
};
+&pxp {
+ status = "okay";
+};
+
&qspi {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_qspi>;
status = "okay";
+ ddrsmp=<0>;
flash0: n25q256a@0 {
#address-cells = <1>;
#size-cells = <1>;
compatible = "micron,n25q256a";
spi-max-frequency = <29000000>;
+ spi-nor,ddr-quad-read-dummy = <6>;
reg = <0>;
};
};
@@ -194,6 +356,22 @@
status = "okay";
};
+&sim2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_sim2>;
+ assigned-clocks = <&clks IMX6UL_CLK_SIM_SEL>;
+ assigned-clock-parents = <&clks IMX6UL_CLK_SIM_PODF>;
+ assigned-clock-rates = <240000000>;
+ /* GPIO_ACTIVE_HIGH/LOW:sim card voltage control
+ * NCN8025:Vcc = ACTIVE_HIGH?5V:3V
+ * TDA8035:Vcc = ACTIVE_HIGH?5V:1.8V
+ */
+ pinctrl-assert-gpios = <&gpio4 23 GPIO_ACTIVE_HIGH>;
+ port = <1>;
+ sven_low_active;
+ status = "okay";
+};
+
&tsc {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_tsc>;
@@ -213,11 +391,19 @@
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_uart2>;
uart-has-rtscts;
+ /* for DTE mode, add below change */
+ /* fsl,dte-mode; */
+ /* pinctrl-0 = <&pinctrl_uart2dte>; */
status = "okay";
};
&usbotg1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usb_otg1_id>;
dr_mode = "otg";
+ srp-disable;
+ hnp-disable;
+ adp-disable;
status = "okay";
};
@@ -250,9 +436,7 @@
&usdhc2 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_usdhc2>;
- no-1-8-v;
- keep-power-in-suspend;
- wakeup-source;
+ non-removable;
status = "okay";
};
@@ -264,6 +448,13 @@
&iomuxc {
pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_hog_1>;
+
+ pinctrl_hog_1: hoggrp-1 {
+ fsl,pins = <
+ MX6UL_PAD_SNVS_TAMPER0__GPIO5_IO00 0x17059
+ >;
+ };
pinctrl_csi1: csi1grp {
fsl,pins = <
@@ -282,6 +473,12 @@
>;
};
+ pinctrl_dvfs: dvfsgrp {
+ fsl,pins = <
+ MX6UL_PAD_SNVS_TAMPER3__GPIO5_IO03 0x79
+ >;
+ };
+
pinctrl_enet1: enet1grp {
fsl,pins = <
MX6UL_PAD_ENET1_RX_EN__ENET1_RX_EN 0x1b0b0
@@ -400,6 +597,12 @@
>;
};
+ pinctrl_pf1550: pf1550 {
+ fsl,pins = <
+ MX6UL_PAD_SNVS_TAMPER4__GPIO5_IO04 0x80000000
+ >;
+ };
+
pinctrl_pwm1: pwm1grp {
fsl,pins = <
MX6UL_PAD_GPIO1_IO08__PWM1_OUT 0x110b0
@@ -409,14 +612,23 @@
pinctrl_sim2: sim2grp {
fsl,pins = <
MX6UL_PAD_CSI_DATA03__SIM2_PORT1_PD 0xb808
- MX6UL_PAD_CSI_DATA04__SIM2_PORT1_CLK 0x31
- MX6UL_PAD_CSI_DATA05__SIM2_PORT1_RST_B 0xb808
- MX6UL_PAD_CSI_DATA06__SIM2_PORT1_SVEN 0xb808
- MX6UL_PAD_CSI_DATA07__SIM2_PORT1_TRXD 0xb809
+ MX6UL_PAD_CSI_DATA04__SIM2_PORT1_CLK 0x11
+ MX6UL_PAD_CSI_DATA05__SIM2_PORT1_RST_B 0xb810
+ MX6UL_PAD_CSI_DATA06__SIM2_PORT1_SVEN 0xb810
+ MX6UL_PAD_CSI_DATA07__SIM2_PORT1_TRXD 0xb811
MX6UL_PAD_CSI_DATA02__GPIO4_IO23 0x3008
>;
};
+ pinctrl_spi4: spi4grp {
+ fsl,pins = <
+ MX6UL_PAD_BOOT_MODE0__GPIO5_IO10 0x70a1
+ MX6UL_PAD_BOOT_MODE1__GPIO5_IO11 0x70a1
+ MX6UL_PAD_SNVS_TAMPER7__GPIO5_IO07 0x70a1
+ MX6UL_PAD_SNVS_TAMPER8__GPIO5_IO08 0x80000000
+ >;
+ };
+
pinctrl_tsc: tscgrp {
fsl,pins = <
MX6UL_PAD_GPIO1_IO01__GPIO1_IO01 0xb0
@@ -442,10 +654,25 @@
>;
};
+ pinctrl_uart2dte: uart2dtegrp {
+ fsl,pins = <
+ MX6UL_PAD_UART2_TX_DATA__UART2_DTE_RX 0x1b0b1
+ MX6UL_PAD_UART2_RX_DATA__UART2_DTE_TX 0x1b0b1
+ MX6UL_PAD_UART3_RX_DATA__UART2_DTE_CTS 0x1b0b1
+ MX6UL_PAD_UART3_TX_DATA__UART2_DTE_RTS 0x1b0b1
+ >;
+ };
+
+ pinctrl_usb_otg1_id: usbotg1idgrp {
+ fsl,pins = <
+ MX6UL_PAD_GPIO1_IO00__ANATOP_OTG1_ID 0x17059
+ >;
+ };
+
pinctrl_usdhc1: usdhc1grp {
fsl,pins = <
MX6UL_PAD_SD1_CMD__USDHC1_CMD 0x17059
- MX6UL_PAD_SD1_CLK__USDHC1_CLK 0x10059
+ MX6UL_PAD_SD1_CLK__USDHC1_CLK 0x10071
MX6UL_PAD_SD1_DATA0__USDHC1_DATA0 0x17059
MX6UL_PAD_SD1_DATA1__USDHC1_DATA1 0x17059
MX6UL_PAD_SD1_DATA2__USDHC1_DATA2 0x17059
@@ -481,7 +708,7 @@
pinctrl_usdhc2: usdhc2grp {
fsl,pins = <
- MX6UL_PAD_NAND_RE_B__USDHC2_CLK 0x17059
+ MX6UL_PAD_NAND_RE_B__USDHC2_CLK 0x10069
MX6UL_PAD_NAND_WE_B__USDHC2_CMD 0x17059
MX6UL_PAD_NAND_DATA00__USDHC2_DATA0 0x17059
MX6UL_PAD_NAND_DATA01__USDHC2_DATA1 0x17059
@@ -490,6 +717,51 @@
>;
};
+ pinctrl_usdhc2_8bit: usdhc2grp_8bit {
+ fsl,pins = <
+ MX6UL_PAD_NAND_RE_B__USDHC2_CLK 0x10069
+ MX6UL_PAD_NAND_WE_B__USDHC2_CMD 0x17059
+ MX6UL_PAD_NAND_DATA00__USDHC2_DATA0 0x17059
+ MX6UL_PAD_NAND_DATA01__USDHC2_DATA1 0x17059
+ MX6UL_PAD_NAND_DATA02__USDHC2_DATA2 0x17059
+ MX6UL_PAD_NAND_DATA03__USDHC2_DATA3 0x17059
+ MX6UL_PAD_NAND_DATA04__USDHC2_DATA4 0x17059
+ MX6UL_PAD_NAND_DATA05__USDHC2_DATA5 0x17059
+ MX6UL_PAD_NAND_DATA06__USDHC2_DATA6 0x17059
+ MX6UL_PAD_NAND_DATA07__USDHC2_DATA7 0x17059
+ >;
+ };
+
+ pinctrl_usdhc2_8bit_100mhz: usdhc2grp_8bit_100mhz {
+ fsl,pins = <
+ MX6UL_PAD_NAND_RE_B__USDHC2_CLK 0x100b9
+ MX6UL_PAD_NAND_WE_B__USDHC2_CMD 0x170b9
+ MX6UL_PAD_NAND_DATA00__USDHC2_DATA0 0x170b9
+ MX6UL_PAD_NAND_DATA01__USDHC2_DATA1 0x170b9
+ MX6UL_PAD_NAND_DATA02__USDHC2_DATA2 0x170b9
+ MX6UL_PAD_NAND_DATA03__USDHC2_DATA3 0x170b9
+ MX6UL_PAD_NAND_DATA04__USDHC2_DATA4 0x170b9
+ MX6UL_PAD_NAND_DATA05__USDHC2_DATA5 0x170b9
+ MX6UL_PAD_NAND_DATA06__USDHC2_DATA6 0x170b9
+ MX6UL_PAD_NAND_DATA07__USDHC2_DATA7 0x170b9
+ >;
+ };
+
+ pinctrl_usdhc2_8bit_200mhz: usdhc2grp_8bit_200mhz {
+ fsl,pins = <
+ MX6UL_PAD_NAND_RE_B__USDHC2_CLK 0x100f9
+ MX6UL_PAD_NAND_WE_B__USDHC2_CMD 0x170f9
+ MX6UL_PAD_NAND_DATA00__USDHC2_DATA0 0x170f9
+ MX6UL_PAD_NAND_DATA01__USDHC2_DATA1 0x170f9
+ MX6UL_PAD_NAND_DATA02__USDHC2_DATA2 0x170f9
+ MX6UL_PAD_NAND_DATA03__USDHC2_DATA3 0x170f9
+ MX6UL_PAD_NAND_DATA04__USDHC2_DATA4 0x170f9
+ MX6UL_PAD_NAND_DATA05__USDHC2_DATA5 0x170f9
+ MX6UL_PAD_NAND_DATA06__USDHC2_DATA6 0x170f9
+ MX6UL_PAD_NAND_DATA07__USDHC2_DATA7 0x170f9
+ >;
+ };
+
pinctrl_wdog: wdoggrp {
fsl,pins = <
MX6UL_PAD_LCD_RESET__WDOG1_WDOG_ANY 0x30b0
diff --git a/arch/arm/boot/dts/imx6ul-14x14-lpddr2-arm2.dts b/arch/arm/boot/dts/imx6ul-14x14-lpddr2-arm2.dts
new file mode 100644
index 000000000000..26ae7339035d
--- /dev/null
+++ b/arch/arm/boot/dts/imx6ul-14x14-lpddr2-arm2.dts
@@ -0,0 +1,788 @@
+/*
+ * Copyright (C) 2015 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 <dt-bindings/input/input.h>
+#include "imx6ul.dtsi"
+
+/ {
+ model = "Freescale i.MX6 UltraLite 14X14 LPDDR2 ARM2 Board";
+ compatible = "fsl,imx6ul-14x14-lpddr2-arm2", "fsl,imx6ul";
+
+ chosen {
+ stdout-path = &uart1;
+ };
+
+ memory {
+ reg = <0x80000000 0x20000000>;
+ };
+
+ reserved-memory {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ linux,cma {
+ compatible = "shared-dma-pool";
+ reusable;
+ size = <0x14000000>;
+ linux,cma-default;
+ };
+ };
+
+ pxp_v4l2 {
+ compatible = "fsl,imx6ul-pxp-v4l2", "fsl,imx6sx-pxp-v4l2", "fsl,imx6sl-pxp-v4l2";
+ status = "okay";
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ reg_sd1_vmmc: sd1_vmmc {
+ compatible = "regulator-fixed";
+ regulator-name = "SD1_SPWR";
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ gpio = <&gpio4 11 GPIO_ACTIVE_HIGH>;
+ off-on-delay = <20000>;
+ enable-active-high;
+ };
+
+ reg_sd2_vmmc: sd2_vmmc {
+ compatible = "regulator-fixed";
+ regulator-name = "SD2_SPWR";
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ gpio = <&gpio4 10 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ reg_can1_3v3: regulator@0 {
+ compatible = "regulator-fixed";
+ reg = <0>;
+ regulator-name = "can1-3v3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&gpio1 15 GPIO_ACTIVE_LOW>;
+ };
+
+ reg_vref_3v3: regulator@1 {
+ compatible = "regulator-fixed";
+ regulator-name = "vref-3v3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ reg_usb_otg1_vbus: regulator@2 {
+ compatible = "regulator-fixed";
+ reg = <2>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usb_otg1>;
+ regulator-name = "usb_otg1_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&gpio1 4 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+ };
+};
+
+&ecspi2 {
+ fsl,spi-num-chipselects = <1>;
+ cs-gpios = <&gpio4 22 0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ecspi2_1 &pinctrl_ecspi2_cs_1>;
+ status = "disabled";
+
+ flash: n25q032@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "st,n25q032";
+ spi-max-frequency = <20000000>;
+ reg = <0>;
+ };
+};
+
+&cpu0 {
+ /*
+ * on i.MX6UL, no seperated VDD_ARM_IN and VDD_SOC_IN,
+ * to align with other platform and use the same cpufreq
+ * driver, still use the seperated OPP define for arm
+ * and soc.
+ */
+ operating-points = <
+ /* kHz uV */
+ 528000 1175000
+ 396000 1175000
+ 198000 1175000
+ >;
+ fsl,soc-operating-points = <
+ /* KHz uV */
+ 528000 1175000
+ 396000 1175000
+ 198000 1175000
+ >;
+ fsl,arm-soc-shared = <1>;
+};
+
+&reg_arm {
+ vin-supply = <&sw1a_reg>;
+ regulator-allow-bypass;
+};
+
+&reg_soc {
+ vin-supply = <&sw1a_reg>;
+ regulator-allow-bypass;
+};
+
+&fec1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_enet1>;
+ phy-mode = "mii";
+ phy-handle = <&ethphy0>;
+ status = "disabled";
+};
+
+&fec2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_enet2>;
+ phy-mode = "rmii";
+ phy-handle = <&ethphy1>;
+ status = "okay";
+
+ mdio {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ethphy0: ethernet-phy@1 {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <2>;
+ };
+
+ ethphy1: ethernet-phy@2 {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <1>;
+ };
+ };
+};
+
+&can1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_flexcan1>;
+ xceiver-supply = <&reg_can1_3v3>;
+ status = "disabled";
+};
+
+&gpc {
+ fsl,cpu_pupscr_sw2iso = <0xf>;
+ fsl,cpu_pupscr_sw = <0x0>;
+ fsl,cpu_pdnscr_iso2sw = <0x1>;
+ fsl,cpu_pdnscr_iso = <0x1>;
+ fsl,ldo-bypass = <1>; /* use ldo-bypass, u-boot will check it and configure */
+};
+
+&gpmi {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpmi_nand_1>;
+ status = "disabled";
+ nand-on-flash-bbt;
+};
+
+&i2c1 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c1>;
+ status = "okay";
+
+ pmic: pfuze100@08 {
+ compatible = "fsl,pfuze200";
+ reg = <0x08>;
+
+ regulators {
+ sw1a_reg: sw1ab {
+ regulator-min-microvolt = <300000>;
+ regulator-max-microvolt = <1875000>;
+ regulator-always-on;
+ regulator-ramp-delay = <6250>;
+ };
+
+ sw2_reg: sw2 {
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ sw3a_reg: sw3a {
+ regulator-min-microvolt = <400000>;
+ regulator-max-microvolt = <1975000>;
+ regulator-always-on;
+ };
+
+ sw3b_reg: sw3b {
+ regulator-min-microvolt = <400000>;
+ regulator-max-microvolt = <1975000>;
+ regulator-always-on;
+ };
+
+ swbst_reg: swbst {
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5150000>;
+ };
+
+ snvs_reg: vsnvs {
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-always-on;
+ };
+
+ vref_reg: vrefddr {
+ regulator-always-on;
+ };
+
+ vgen1_reg: vgen1 {
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1550000>;
+ };
+
+ vgen2_reg: vgen2 {
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1550000>;
+ };
+
+ vgen3_reg: vgen3 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ vgen4_reg: vgen4 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ vgen5_reg: vgen5 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ vgen6_reg: vgen6 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+ };
+ };
+};
+
+&pxp {
+ status = "okay";
+};
+
+&qspi {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_qspi>;
+ status = "disabled";
+ fsl,qspi-has-second-chip = <1>;
+ ddrsmp=<0>;
+
+ flash0: n25q256a@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "micron,n25q256a";
+ spi-max-frequency = <29000000>;
+ spi-nor,ddr-quad-read-dummy = <6>;
+ reg = <0>;
+ };
+
+ flash1: n25q256a@1 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "micron,n25q256a";
+ spi-max-frequency = <29000000>;
+ spi-nor,ddr-quad-read-dummy = <6>;
+ reg = <1>;
+ };
+
+ flash2: n25q256a@2 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "micron,n25q256a";
+ spi-max-frequency = <29000000>;
+ spi-nor,ddr-quad-read-dummy = <6>;
+ reg = <2>;
+ };
+
+ flash3: n25q256a@3 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "micron,n25q256a";
+ spi-max-frequency = <29000000>;
+ spi-nor,ddr-quad-read-dummy = <6>;
+ reg = <3>;
+ };
+};
+
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart1>;
+ status = "okay";
+};
+
+&usbotg1 {
+ vbus-supply = <&reg_usb_otg1_vbus>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usb_otg1_id>;
+ status = "okay";
+};
+
+&usdhc1 {
+ pinctrl-names = "default", "state_100mhz", "state_200mhz";
+ pinctrl-0 = <&pinctrl_usdhc1>;
+ pinctrl-1 = <&pinctrl_usdhc1_100mhz>;
+ pinctrl-2 = <&pinctrl_usdhc1_200mhz>;
+ cd-gpios = <&gpio4 26 GPIO_ACTIVE_LOW>;
+ wp-gpios = <&gpio4 25 GPIO_ACTIVE_HIGH>;
+ keep-power-in-suspend;
+ enable-sdio-wakeup;
+ vmmc-supply = <&reg_sd1_vmmc>;
+ status = "okay";
+};
+
+&usdhc2 {
+ pinctrl-names = "default", "state_100mhz", "state_200mhz";
+ pinctrl-0 = <&pinctrl_usdhc2_8bit>;
+ pinctrl-1 = <&pinctrl_usdhc2_8bit_100mhz>;
+ pinctrl-2 = <&pinctrl_usdhc2_8bit_200mhz>;
+ keep-power-in-suspend;
+ vmmc-supply = <&reg_sd2_vmmc>;
+ bus-width = <8>;
+ non-removable;
+ status = "okay";
+};
+
+&iomuxc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_hog &pinctrl_hog_nand>;
+
+ imx6ul-14x14-lpddr2-arm2 {
+ pinctrl_hog: hoggrp {
+ fsl,pins = <
+ MX6UL_PAD_CSI_DATA05__GPIO4_IO26 0x17059 /* SD1 CD */
+ MX6UL_PAD_CSI_DATA04__GPIO4_IO25 0x17059 /* SD1 WP */
+ MX6UL_PAD_GPIO1_IO05__USDHC1_VSELECT 0x17059 /* SD1 VSELECT */
+ MX6UL_PAD_GPIO1_IO08__USDHC2_VSELECT 0x17059 /* SD2 VSELECT */
+ >;
+ };
+
+ pinctrl_hog_nand: hoggrp_nand {
+ fsl,pins = <
+ MX6UL_PAD_NAND_WP_B__GPIO4_IO11 0x17059 /* SD1 RESET */
+ MX6UL_PAD_NAND_ALE__GPIO4_IO10 0x17059 /* SD2 RESET */
+ >;
+ };
+
+ pinctrl_ecspi2_cs_1: ecspi2_cs_grp-1 {
+ fsl,pins = <
+ MX6UL_PAD_CSI_DATA01__GPIO4_IO22 0x10b0
+ >;
+ };
+
+ pinctrl_ecspi2_1: ecspi2grp-1 {
+ fsl,pins = <
+ MX6UL_PAD_CSI_DATA02__ECSPI2_MOSI 0x10b0
+ MX6UL_PAD_CSI_DATA03__ECSPI2_MISO 0x10b0
+ MX6UL_PAD_CSI_DATA00__ECSPI2_SCLK 0x10b0
+ >;
+ };
+
+ pinctrl_enet1: enet1grp {
+ fsl,pins = <
+ MX6UL_PAD_ENET1_RX_EN__ENET1_RX_EN 0x1b0b0
+ MX6UL_PAD_ENET1_RX_ER__ENET1_RX_ER 0x1b0b0
+ MX6UL_PAD_ENET1_RX_DATA0__ENET1_RDATA00 0x1b0b0
+ MX6UL_PAD_ENET1_RX_DATA1__ENET1_RDATA01 0x1b0b0
+ MX6UL_PAD_UART2_TX_DATA__ENET1_TDATA02 0x1b0b0
+ MX6UL_PAD_UART1_RX_DATA__ENET1_RDATA03 0x1b0b0
+ MX6UL_PAD_UART1_CTS_B__ENET1_RX_CLK 0x4b01b0a8
+ MX6UL_PAD_ENET1_TX_DATA0__ENET1_TDATA00 0x1b0b0
+ MX6UL_PAD_ENET1_TX_DATA1__ENET1_TDATA01 0x1b0b0
+ MX6UL_PAD_UART2_TX_DATA__ENET1_TDATA02 0x1b0b0
+ MX6UL_PAD_UART2_RX_DATA__ENET1_TDATA03 0x1b0b0
+ MX6UL_PAD_ENET1_TX_CLK__ENET1_TX_CLK 0x4b01b0a8
+ MX6UL_PAD_ENET1_TX_EN__ENET1_TX_EN 0x1b0b0
+ MX6UL_PAD_UART2_RTS_B__ENET1_COL 0x1b0b0
+ MX6UL_PAD_UART2_CTS_B__ENET1_CRS 0x1b0b0
+ >;
+ };
+
+ pinctrl_enet2: enet2grp {
+ fsl,pins = <
+ MX6UL_PAD_GPIO1_IO07__ENET2_MDC 0x1b0b0
+ MX6UL_PAD_GPIO1_IO06__ENET2_MDIO 0x1b0b0
+ MX6UL_PAD_ENET2_TX_DATA0__ENET2_TDATA00 0x1b0b0
+ MX6UL_PAD_ENET2_TX_DATA1__ENET2_TDATA01 0x1b0b0
+ MX6UL_PAD_ENET2_TX_EN__ENET2_TX_EN 0x1b0b0
+ MX6UL_PAD_ENET2_TX_CLK__ENET2_REF_CLK2 0x4001b0a8
+ MX6UL_PAD_ENET2_RX_DATA0__ENET2_RDATA00 0x1b0b0
+ MX6UL_PAD_ENET2_RX_DATA1__ENET2_RDATA01 0x1b0b0
+ MX6UL_PAD_ENET2_RX_EN__ENET2_RX_EN 0x1b0b0
+ MX6UL_PAD_ENET2_RX_ER__ENET2_RX_ER 0x1b0b0
+ MX6UL_PAD_UART3_CTS_B__ENET2_RX_CLK 0x4001b0a8
+ MX6UL_PAD_UART5_RX_DATA__ENET2_COL 0x1b0b0
+ MX6UL_PAD_UART5_TX_DATA__ENET2_CRS 0x1b0b0
+ >;
+ };
+
+ pinctrl_flexcan1: flexcan1grp{
+ fsl,pins = <
+ MX6UL_PAD_ENET1_RX_DATA0__FLEXCAN1_TX 0x1b020
+ MX6UL_PAD_ENET1_RX_DATA1__FLEXCAN1_RX 0x1b020
+ MX6UL_PAD_JTAG_TRST_B__GPIO1_IO15 0x17059 /* STBY */
+ >;
+ };
+
+ pinctrl_gpmi_nand_1: gpmi-nand-1 {
+ fsl,pins = <
+ MX6UL_PAD_NAND_CLE__RAWNAND_CLE 0xb0b1
+ MX6UL_PAD_NAND_ALE__RAWNAND_ALE 0xb0b1
+ MX6UL_PAD_NAND_WP_B__RAWNAND_WP_B 0xb0b1
+ MX6UL_PAD_NAND_READY_B__RAWNAND_READY_B 0xb000
+ MX6UL_PAD_NAND_CE0_B__RAWNAND_CE0_B 0xb0b1
+ MX6UL_PAD_NAND_CE1_B__RAWNAND_CE1_B 0xb0b1
+ MX6UL_PAD_NAND_RE_B__RAWNAND_RE_B 0xb0b1
+ MX6UL_PAD_NAND_WE_B__RAWNAND_WE_B 0xb0b1
+ MX6UL_PAD_NAND_DATA00__RAWNAND_DATA00 0xb0b1
+ MX6UL_PAD_NAND_DATA01__RAWNAND_DATA01 0xb0b1
+ MX6UL_PAD_NAND_DATA02__RAWNAND_DATA02 0xb0b1
+ MX6UL_PAD_NAND_DATA03__RAWNAND_DATA03 0xb0b1
+ MX6UL_PAD_NAND_DATA04__RAWNAND_DATA04 0xb0b1
+ MX6UL_PAD_NAND_DATA05__RAWNAND_DATA05 0xb0b1
+ MX6UL_PAD_NAND_DATA06__RAWNAND_DATA06 0xb0b1
+ MX6UL_PAD_NAND_DATA07__RAWNAND_DATA07 0xb0b1
+ >;
+ };
+
+ pinctrl_i2c2: i2c2grp {
+ fsl,pins = <
+ MX6UL_PAD_CSI_VSYNC__I2C2_SDA 0x4001b8b0
+ MX6UL_PAD_CSI_HSYNC__I2C2_SCL 0x4001b8b0
+ >;
+ };
+
+ pinctrl_lcdif_dat: lcdifdatgrp {
+ fsl,pins = <
+ MX6UL_PAD_LCD_DATA00__LCDIF_DATA00 0x79
+ MX6UL_PAD_LCD_DATA01__LCDIF_DATA01 0x79
+ MX6UL_PAD_LCD_DATA02__LCDIF_DATA02 0x79
+ MX6UL_PAD_LCD_DATA03__LCDIF_DATA03 0x79
+ MX6UL_PAD_LCD_DATA04__LCDIF_DATA04 0x79
+ MX6UL_PAD_LCD_DATA05__LCDIF_DATA05 0x79
+ MX6UL_PAD_LCD_DATA06__LCDIF_DATA06 0x79
+ MX6UL_PAD_LCD_DATA07__LCDIF_DATA07 0x79
+ MX6UL_PAD_LCD_DATA08__LCDIF_DATA08 0x79
+ MX6UL_PAD_LCD_DATA09__LCDIF_DATA09 0x79
+ MX6UL_PAD_LCD_DATA10__LCDIF_DATA10 0x79
+ MX6UL_PAD_LCD_DATA11__LCDIF_DATA11 0x79
+ MX6UL_PAD_LCD_DATA12__LCDIF_DATA12 0x79
+ MX6UL_PAD_LCD_DATA13__LCDIF_DATA13 0x79
+ MX6UL_PAD_LCD_DATA14__LCDIF_DATA14 0x79
+ MX6UL_PAD_LCD_DATA15__LCDIF_DATA15 0x79
+ MX6UL_PAD_LCD_DATA16__LCDIF_DATA16 0x79
+ MX6UL_PAD_LCD_DATA17__LCDIF_DATA17 0x79
+ MX6UL_PAD_LCD_DATA18__LCDIF_DATA18 0x79
+ MX6UL_PAD_LCD_DATA19__LCDIF_DATA19 0x79
+ MX6UL_PAD_LCD_DATA20__LCDIF_DATA20 0x79
+ MX6UL_PAD_LCD_DATA21__LCDIF_DATA21 0x79
+ MX6UL_PAD_LCD_DATA22__LCDIF_DATA22 0x79
+ MX6UL_PAD_LCD_DATA23__LCDIF_DATA23 0x79
+ >;
+ };
+
+ pinctrl_lcdif_ctrl: lcdifctrlgrp {
+ fsl,pins = <
+ MX6UL_PAD_LCD_CLK__LCDIF_CLK 0x79
+ MX6UL_PAD_LCD_ENABLE__LCDIF_ENABLE 0x79
+ MX6UL_PAD_LCD_HSYNC__LCDIF_HSYNC 0x79
+ MX6UL_PAD_LCD_VSYNC__LCDIF_VSYNC 0x79
+ MX6UL_PAD_LCD_RESET__LCDIF_RESET 0x79
+ >;
+ };
+
+ pinctrl_pwm1: pmw1grp {
+ fsl,pins = <
+ MX6UL_PAD_NAND_DQS__PWM5_OUT 0x110b0
+ >;
+ };
+
+ pinctrl_qspi: qspigrp {
+ fsl,pins = <
+ MX6UL_PAD_NAND_WP_B__QSPI_A_SCLK 0x70a1
+ MX6UL_PAD_NAND_READY_B__QSPI_A_DATA00 0x70a1
+ MX6UL_PAD_NAND_CE0_B__QSPI_A_DATA01 0x70a1
+ MX6UL_PAD_NAND_CE1_B__QSPI_A_DATA02 0x70a1
+ MX6UL_PAD_NAND_CLE__QSPI_A_DATA03 0x70a1
+ MX6UL_PAD_NAND_DQS__QSPI_A_SS0_B 0x70a1
+ MX6UL_PAD_NAND_DATA07__QSPI_A_SS1_B 0x70a1
+ MX6UL_PAD_NAND_RE_B__QSPI_B_SCLK 0x70a1
+ MX6UL_PAD_NAND_DATA02__QSPI_B_DATA00 0x70a1
+ MX6UL_PAD_NAND_DATA03__QSPI_B_DATA01 0x70a1
+ MX6UL_PAD_NAND_DATA04__QSPI_B_DATA02 0x70a1
+ MX6UL_PAD_NAND_DATA05__QSPI_B_DATA03 0x70a1
+ MX6UL_PAD_NAND_WE_B__QSPI_B_SS0_B 0x70a1
+ MX6UL_PAD_NAND_DATA00__QSPI_B_SS1_B 0x70a1
+ >;
+ };
+
+ pinctrl_mqs: mqsgrp {
+ fsl,pins = <
+ MX6UL_PAD_GPIO1_IO01__MQS_LEFT 0x11088
+ MX6UL_PAD_GPIO1_IO00__MQS_RIGHT 0x11088
+ >;
+ };
+
+ pinctrl_sai1: sai1grp {
+ fsl,pins = <
+ MX6UL_PAD_CSI_DATA01__SAI1_MCLK 0x1b0b0
+ MX6UL_PAD_CSI_DATA02__SAI1_RX_SYNC 0x1b0b0
+ MX6UL_PAD_CSI_DATA03__SAI1_RX_BCLK 0x1b0b0
+ MX6UL_PAD_CSI_DATA04__SAI1_TX_SYNC 0x1b0b0
+ MX6UL_PAD_CSI_DATA05__SAI1_TX_BCLK 0x1b0b0
+ MX6UL_PAD_CSI_DATA06__SAI1_RX_DATA 0x110b0
+ MX6UL_PAD_CSI_DATA07__SAI1_TX_DATA 0x1f0b8
+ MX6UL_PAD_SNVS_TAMPER0__GPIO5_IO00 0x17059
+ >;
+ };
+
+ pinctrl_spdif: spdifgrp {
+ fsl,pins = <
+ MX6UL_PAD_SD1_CMD__SPDIF_OUT 0x1b0b0
+ MX6UL_PAD_SD1_CLK__SPDIF_IN 0x1b0b0
+ >;
+ };
+
+ pinctrl_tsc: tscgrp {
+ fsl,pin = <
+ MX6UL_PAD_GPIO1_IO01__GPIO1_IO01 0xb0
+ MX6UL_PAD_GPIO1_IO02__GPIO1_IO02 0xb0
+ MX6UL_PAD_GPIO1_IO03__GPIO1_IO03 0xb0
+ MX6UL_PAD_GPIO1_IO04__GPIO1_IO04 0xb0
+ >;
+ };
+
+ pinctrl_adc1: adc1grp {
+ fsl,pin = <
+ MX6UL_PAD_GPIO1_IO00__GPIO1_IO00 0xb0
+ MX6UL_PAD_GPIO1_IO01__GPIO1_IO01 0xb0
+ >;
+ };
+
+ pinctrl_i2c1: i2c1grp {
+ fsl,pin = <
+ MX6UL_PAD_GPIO1_IO03__I2C1_SDA 0x4001b8b1
+ MX6UL_PAD_GPIO1_IO02__I2C1_SCL 0x4001b8b1
+ >;
+ };
+
+ pinctrl_uart1: uart1grp {
+ fsl,pins = <
+ MX6UL_PAD_UART1_TX_DATA__UART1_DCE_TX 0x1b0b1
+ MX6UL_PAD_UART1_RX_DATA__UART1_DCE_RX 0x1b0b1
+ >;
+ };
+
+ pinctrl_uart2: uart2grp {
+ fsl,pins = <
+ MX6UL_PAD_UART2_TX_DATA__UART2_DCE_TX 0x1b0b1
+ MX6UL_PAD_UART2_RX_DATA__UART2_DCE_RX 0x1b0b1
+ MX6UL_PAD_UART2_CTS_B__UART2_DCE_CTS 0x1b0b1
+ MX6UL_PAD_UART2_RTS_B__UART2_DCE_RTS 0x1b0b1
+ >;
+ };
+
+ pinctrl_uart2dte: uart2dtegrp {
+ fsl,pins = <
+ MX6UL_PAD_UART2_TX_DATA__UART2_DTE_RX 0x1b0b1
+ MX6UL_PAD_UART2_RX_DATA__UART2_DTE_TX 0x1b0b1
+ MX6UL_PAD_UART2_CTS_B__UART2_DTE_RTS 0x1b0b1
+ MX6UL_PAD_UART2_RTS_B__UART2_DTE_CTS 0x1b0b1
+ >;
+ };
+
+ pinctrl_usb_otg1_id: usbotg1idgrp {
+ fsl,pins = <
+ MX6UL_PAD_GPIO1_IO00__ANATOP_OTG1_ID 0x17059
+ >;
+ };
+
+ pinctrl_usb_otg1: usbotg1grp {
+ fsl,pins = <
+ MX6UL_PAD_GPIO1_IO04__GPIO1_IO04 0x10b0
+ >;
+ };
+
+ pinctrl_usdhc1: usdhc1grp {
+ fsl,pins = <
+ MX6UL_PAD_SD1_CMD__USDHC1_CMD 0x17059
+ MX6UL_PAD_SD1_CLK__USDHC1_CLK 0x10059
+ MX6UL_PAD_SD1_DATA0__USDHC1_DATA0 0x17059
+ MX6UL_PAD_SD1_DATA1__USDHC1_DATA1 0x17059
+ MX6UL_PAD_SD1_DATA2__USDHC1_DATA2 0x17059
+ MX6UL_PAD_SD1_DATA3__USDHC1_DATA3 0x17059
+ >;
+ };
+
+ pinctrl_usdhc1_100mhz: usdhc1grp100mhz {
+ fsl,pins = <
+ MX6UL_PAD_SD1_CMD__USDHC1_CMD 0x170b9
+ MX6UL_PAD_SD1_CLK__USDHC1_CLK 0x100b9
+ MX6UL_PAD_SD1_DATA0__USDHC1_DATA0 0x170b9
+ MX6UL_PAD_SD1_DATA1__USDHC1_DATA1 0x170b9
+ MX6UL_PAD_SD1_DATA2__USDHC1_DATA2 0x170b9
+ MX6UL_PAD_SD1_DATA3__USDHC1_DATA3 0x170b9
+ >;
+ };
+
+ pinctrl_usdhc1_200mhz: usdhc1grp200mhz {
+ fsl,pins = <
+ MX6UL_PAD_SD1_CMD__USDHC1_CMD 0x170f9
+ MX6UL_PAD_SD1_CLK__USDHC1_CLK 0x100f9
+ MX6UL_PAD_SD1_DATA0__USDHC1_DATA0 0x170f9
+ MX6UL_PAD_SD1_DATA1__USDHC1_DATA1 0x170f9
+ MX6UL_PAD_SD1_DATA2__USDHC1_DATA2 0x170f9
+ MX6UL_PAD_SD1_DATA3__USDHC1_DATA3 0x170f9
+ >;
+ };
+
+ pinctrl_usdhc1_8bit: usdhc1_8bit_grp {
+ fsl,pins = <
+ MX6UL_PAD_SD1_CMD__USDHC1_CMD 0x17059
+ MX6UL_PAD_SD1_CLK__USDHC1_CLK 0x10059
+ MX6UL_PAD_SD1_DATA0__USDHC1_DATA0 0x17059
+ MX6UL_PAD_SD1_DATA1__USDHC1_DATA1 0x17059
+ MX6UL_PAD_SD1_DATA2__USDHC1_DATA2 0x17059
+ MX6UL_PAD_SD1_DATA3__USDHC1_DATA3 0x17059
+ MX6UL_PAD_NAND_READY_B__USDHC1_DATA4 0x17059
+ MX6UL_PAD_NAND_CE0_B__USDHC1_DATA5 0x17059
+ MX6UL_PAD_NAND_CE1_B__USDHC1_DATA6 0x17059
+ MX6UL_PAD_NAND_CLE__USDHC1_DATA7 0x17059
+ >;
+ };
+
+ pinctrl_usdhc1_8bit_100mhz: usdhc1_8bit_100mhz_grp {
+ fsl,pins = <
+ MX6UL_PAD_SD1_CMD__USDHC1_CMD 0x170b9
+ MX6UL_PAD_SD1_CLK__USDHC1_CLK 0x100b9
+ MX6UL_PAD_SD1_DATA0__USDHC1_DATA0 0x170b9
+ MX6UL_PAD_SD1_DATA1__USDHC1_DATA1 0x170b9
+ MX6UL_PAD_SD1_DATA2__USDHC1_DATA2 0x170b9
+ MX6UL_PAD_SD1_DATA3__USDHC1_DATA3 0x170b9
+ MX6UL_PAD_NAND_READY_B__USDHC1_DATA4 0x170b9
+ MX6UL_PAD_NAND_CE0_B__USDHC1_DATA5 0x170b9
+ MX6UL_PAD_NAND_CE1_B__USDHC1_DATA6 0x170b9
+ MX6UL_PAD_NAND_CLE__USDHC1_DATA7 0x170b9
+ >;
+ };
+
+ pinctrl_usdhc1_8bit_200mhz: usdhc1_8bit_200mhz_grp {
+ fsl,pins = <
+ MX6UL_PAD_SD1_CMD__USDHC1_CMD 0x170f9
+ MX6UL_PAD_SD1_CLK__USDHC1_CLK 0x100f9
+ MX6UL_PAD_SD1_DATA0__USDHC1_DATA0 0x170f9
+ MX6UL_PAD_SD1_DATA1__USDHC1_DATA1 0x170f9
+ MX6UL_PAD_SD1_DATA2__USDHC1_DATA2 0x170f9
+ MX6UL_PAD_SD1_DATA3__USDHC1_DATA3 0x170f9
+ MX6UL_PAD_NAND_READY_B__USDHC1_DATA4 0x170f9
+ MX6UL_PAD_NAND_CE0_B__USDHC1_DATA5 0x170f9
+ MX6UL_PAD_NAND_CE1_B__USDHC1_DATA6 0x170f9
+ MX6UL_PAD_NAND_CLE__USDHC1_DATA7 0x170f9
+ >;
+ };
+
+ pinctrl_usdhc2: usdhc2grp {
+ fsl,pins = <
+ MX6UL_PAD_NAND_WE_B__USDHC2_CMD 0x17059
+ MX6UL_PAD_NAND_RE_B__USDHC2_CLK 0x10059
+ MX6UL_PAD_NAND_DATA00__USDHC2_DATA0 0x17059
+ MX6UL_PAD_NAND_DATA01__USDHC2_DATA1 0x17059
+ MX6UL_PAD_NAND_DATA02__USDHC2_DATA2 0x17059
+ MX6UL_PAD_NAND_DATA03__USDHC2_DATA3 0x17059
+ >;
+ };
+
+ pinctrl_usdhc2_100mhz: usdhc2grp100mhz {
+ fsl,pins = <
+ MX6UL_PAD_NAND_WE_B__USDHC2_CMD 0x170b9
+ MX6UL_PAD_NAND_RE_B__USDHC2_CLK 0x100b9
+ MX6UL_PAD_NAND_DATA00__USDHC2_DATA0 0x170b9
+ MX6UL_PAD_NAND_DATA01__USDHC2_DATA1 0x170b9
+ MX6UL_PAD_NAND_DATA02__USDHC2_DATA2 0x170b9
+ MX6UL_PAD_NAND_DATA03__USDHC2_DATA3 0x170b9
+ >;
+ };
+
+ pinctrl_usdhc2_200mhz: usdhc2grp200mhz {
+ fsl,pins = <
+ MX6UL_PAD_NAND_WE_B__USDHC2_CMD 0x170f9
+ MX6UL_PAD_NAND_RE_B__USDHC2_CLK 0x100f9
+ MX6UL_PAD_NAND_DATA00__USDHC2_DATA0 0x170f9
+ MX6UL_PAD_NAND_DATA01__USDHC2_DATA1 0x170f9
+ MX6UL_PAD_NAND_DATA02__USDHC2_DATA2 0x170f9
+ MX6UL_PAD_NAND_DATA03__USDHC2_DATA3 0x170f9
+ >;
+ };
+
+ pinctrl_usdhc2_8bit: usdhc2_8bit_grp {
+ fsl,pins = <
+ MX6UL_PAD_NAND_WE_B__USDHC2_CMD 0x17059
+ MX6UL_PAD_NAND_RE_B__USDHC2_CLK 0x10059
+ MX6UL_PAD_NAND_DATA00__USDHC2_DATA0 0x17059
+ MX6UL_PAD_NAND_DATA01__USDHC2_DATA1 0x17059
+ MX6UL_PAD_NAND_DATA02__USDHC2_DATA2 0x17059
+ MX6UL_PAD_NAND_DATA03__USDHC2_DATA3 0x17059
+ MX6UL_PAD_NAND_DATA04__USDHC2_DATA4 0x17059
+ MX6UL_PAD_NAND_DATA05__USDHC2_DATA5 0x17059
+ MX6UL_PAD_NAND_DATA06__USDHC2_DATA6 0x17059
+ MX6UL_PAD_NAND_DATA07__USDHC2_DATA7 0x17059
+ >;
+ };
+
+ pinctrl_usdhc2_8bit_100mhz: usdhc2_8bit_100mhz_grp {
+ fsl,pins = <
+ MX6UL_PAD_NAND_WE_B__USDHC2_CMD 0x170b9
+ MX6UL_PAD_NAND_RE_B__USDHC2_CLK 0x100b9
+ MX6UL_PAD_NAND_DATA00__USDHC2_DATA0 0x170b9
+ MX6UL_PAD_NAND_DATA01__USDHC2_DATA1 0x170b9
+ MX6UL_PAD_NAND_DATA02__USDHC2_DATA2 0x170b9
+ MX6UL_PAD_NAND_DATA03__USDHC2_DATA3 0x170b9
+ MX6UL_PAD_NAND_DATA04__USDHC2_DATA4 0x170b9
+ MX6UL_PAD_NAND_DATA05__USDHC2_DATA5 0x170b9
+ MX6UL_PAD_NAND_DATA06__USDHC2_DATA6 0x170b9
+ MX6UL_PAD_NAND_DATA07__USDHC2_DATA7 0x170b9
+ >;
+ };
+
+ pinctrl_usdhc2_8bit_200mhz: usdhc2_8bit_200mhz_grp {
+ fsl,pins = <
+ MX6UL_PAD_NAND_WE_B__USDHC2_CMD 0x170f9
+ MX6UL_PAD_NAND_RE_B__USDHC2_CLK 0x100f9
+ MX6UL_PAD_NAND_DATA00__USDHC2_DATA0 0x170f9
+ MX6UL_PAD_NAND_DATA01__USDHC2_DATA1 0x170f9
+ MX6UL_PAD_NAND_DATA02__USDHC2_DATA2 0x170f9
+ MX6UL_PAD_NAND_DATA03__USDHC2_DATA3 0x170f9
+ MX6UL_PAD_NAND_DATA04__USDHC2_DATA4 0x170f9
+ MX6UL_PAD_NAND_DATA05__USDHC2_DATA5 0x170f9
+ MX6UL_PAD_NAND_DATA06__USDHC2_DATA6 0x170f9
+ MX6UL_PAD_NAND_DATA07__USDHC2_DATA7 0x170f9
+ >;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/imx6ul-9x9-evk-btwifi-oob.dts b/arch/arm/boot/dts/imx6ul-9x9-evk-btwifi-oob.dts
new file mode 100644
index 000000000000..8a8ece34d775
--- /dev/null
+++ b/arch/arm/boot/dts/imx6ul-9x9-evk-btwifi-oob.dts
@@ -0,0 +1,10 @@
+/*
+ * Copyright (C) 2017 NXP
+ *
+ * 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 "imx6ul-9x9-evk-btwifi.dts"
+#include "imx6ul-evk-btwifi-oob.dtsi"
diff --git a/arch/arm/boot/dts/imx6ul-9x9-evk-btwifi.dts b/arch/arm/boot/dts/imx6ul-9x9-evk-btwifi.dts
new file mode 100644
index 000000000000..de89052d97fc
--- /dev/null
+++ b/arch/arm/boot/dts/imx6ul-9x9-evk-btwifi.dts
@@ -0,0 +1,10 @@
+/*
+ * Copyright (C) 2015 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 "imx6ul-9x9-evk.dts"
+#include "imx6ul-evk-btwifi.dtsi"
diff --git a/arch/arm/boot/dts/imx6ul-9x9-evk-csi.dts b/arch/arm/boot/dts/imx6ul-9x9-evk-csi.dts
new file mode 100644
index 000000000000..21778070fb18
--- /dev/null
+++ b/arch/arm/boot/dts/imx6ul-9x9-evk-csi.dts
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2015 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 "imx6ul-9x9-evk.dts"
+
+
+&csi {
+ status = "okay";
+};
+
+&ov5640 {
+ status = "okay";
+};
+
+&sim2 {
+ status = "disabled";
+};
diff --git a/arch/arm/boot/dts/imx6ul-9x9-evk-ldo.dts b/arch/arm/boot/dts/imx6ul-9x9-evk-ldo.dts
new file mode 100644
index 000000000000..715efcb9512e
--- /dev/null
+++ b/arch/arm/boot/dts/imx6ul-9x9-evk-ldo.dts
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2015 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 "imx6ul-9x9-evk.dts"
+
+&cpu0 {
+ operating-points = <
+ /* kHz uV */
+ 696000 1275000
+ 528000 1175000
+ 396000 1025000
+ 198000 950000
+ >;
+ fsl,soc-operating-points = <
+ /* KHz uV */
+ 696000 1275000
+ 528000 1175000
+ 396000 1175000
+ 198000 1175000
+ >;
+ fsl,arm-soc-shared = <0>;
+};
+
+&gpc {
+ fsl,ldo-bypass = <0>; /* use ldo-enable, u-boot will check it and configure */
+};
+
+&reg_arm {
+ /delete-property/ vin-supply;
+};
+
+&reg_soc {
+ /delete-property/ vin-supply;
+};
diff --git a/arch/arm/boot/dts/imx6ul-9x9-evk.dts b/arch/arm/boot/dts/imx6ul-9x9-evk.dts
new file mode 100644
index 000000000000..caa2ed53313c
--- /dev/null
+++ b/arch/arm/boot/dts/imx6ul-9x9-evk.dts
@@ -0,0 +1,813 @@
+/*
+ * Copyright (C) 2015 Freescale Semiconductor, Inc.
+ * Copyright 2017 NXP
+ *
+ * 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 <dt-bindings/input/input.h>
+#include "imx6ul.dtsi"
+
+/ {
+ model = "Freescale i.MX6 UltraLite 9x9 EVK Board";
+ compatible = "fsl,imx6ul-9x9-evk", "fsl,imx6ul";
+
+ backlight {
+ compatible = "pwm-backlight";
+ pwms = <&pwm1 0 5000000>;
+ brightness-levels = <0 4 8 16 32 64 128 255>;
+ default-brightness-level = <6>;
+ status = "okay";
+ };
+
+ chosen {
+ stdout-path = &uart1;
+ };
+
+ memory {
+ reg = <0x80000000 0x10000000>;
+ };
+
+ reserved-memory {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ linux,cma {
+ compatible = "shared-dma-pool";
+ reusable;
+ size = <0x6000000>;
+ linux,cma-default;
+ };
+ };
+
+ pxp_v4l2 {
+ compatible = "fsl,imx6ul-pxp-v4l2", "fsl,imx6sx-pxp-v4l2", "fsl,imx6sl-pxp-v4l2";
+ status = "okay";
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ reg_can_3v3: regulator@0 {
+ compatible = "regulator-fixed";
+ reg = <0>;
+ regulator-name = "can-3v3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpios = <&gpio_spi 3 GPIO_ACTIVE_LOW>;
+ };
+
+ reg_gpio_dvfs: regulator-gpio {
+ compatible = "regulator-gpio";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_dvfs>;
+ regulator-min-microvolt = <1300000>;
+ regulator-max-microvolt = <1400000>;
+ regulator-name = "gpio_dvfs";
+ regulator-type = "voltage";
+ gpios = <&gpio5 3 GPIO_ACTIVE_HIGH>;
+ states = <1300000 0x1 1400000 0x0>;
+ };
+
+ reg_sd1_vmmc: regulator@1 {
+ compatible = "regulator-fixed";
+ regulator-name = "VSD_3V3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&gpio1 9 GPIO_ACTIVE_HIGH>;
+ off-on-delay = <20000>;
+ enable-active-high;
+ };
+ };
+
+ sound {
+ compatible = "fsl,imx6ul-evk-wm8960",
+ "fsl,imx-audio-wm8960";
+ model = "wm8960-audio";
+ cpu-dai = <&sai2>;
+ audio-codec = <&codec>;
+ asrc-controller = <&asrc>;
+ codec-master;
+ gpr = <&gpr 4 0x100000 0x100000>;
+ /*
+ * hp-det = <hp-det-pin hp-det-polarity>;
+ * hp-det-pin: JD1 JD2 or JD3
+ * hp-det-polarity = 0: hp detect high for headphone
+ * hp-det-polarity = 1: hp detect high for speaker
+ */
+ hp-det = <3 0>;
+ hp-det-gpios = <&gpio5 4 0>;
+ mic-det-gpios = <&gpio5 4 0>;
+ audio-routing =
+ "Headphone Jack", "HP_L",
+ "Headphone Jack", "HP_R",
+ "Ext Spk", "SPK_LP",
+ "Ext Spk", "SPK_LN",
+ "Ext Spk", "SPK_RP",
+ "Ext Spk", "SPK_RN",
+ "LINPUT2", "Mic Jack",
+ "LINPUT3", "Mic Jack",
+ "RINPUT1", "Main MIC",
+ "RINPUT2", "Main MIC",
+ "Mic Jack", "MICB",
+ "Main MIC", "MICB",
+ "CPU-Playback", "ASRC-Playback",
+ "Playback", "CPU-Playback",
+ "ASRC-Capture", "CPU-Capture",
+ "CPU-Capture", "Capture";
+ };
+
+ spi4 {
+ compatible = "spi-gpio";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_spi4>;
+ pinctrl-assert-gpios = <&gpio5 8 GPIO_ACTIVE_LOW>;
+ status = "okay";
+ gpio-sck = <&gpio5 11 0>;
+ gpio-mosi = <&gpio5 10 0>;
+ cs-gpios = <&gpio5 7 0>;
+ num-chipselects = <1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ gpio_spi: gpio_spi@0 {
+ compatible = "fairchild,74hc595";
+ gpio-controller;
+ #gpio-cells = <2>;
+ reg = <0>;
+ registers-number = <1>;
+ registers-default = /bits/ 8 <0x57>;
+ spi-max-frequency = <100000>;
+ };
+ };
+};
+
+&clks {
+ assigned-clocks = <&clks IMX6UL_CLK_PLL4_AUDIO_DIV>;
+ assigned-clock-rates = <786432000>;
+};
+
+&cpu0 {
+ /*
+ * on i.MX6UL, no seperated VDD_ARM_IN and VDD_SOC_IN,
+ * to align with other platform and use the same cpufreq
+ * driver, still use the seperated OPP define for arm
+ * and soc.
+ */
+ operating-points = <
+ /* kHz uV */
+ 528000 1175000
+ 396000 1175000
+ 198000 1175000
+ >;
+ fsl,soc-operating-points = <
+ /* KHz uV */
+ 528000 1175000
+ 396000 1175000
+ 198000 1175000
+ >;
+ fsl,arm-soc-shared = <1>;
+};
+
+&reg_arm {
+ vin-supply = <&sw1c_reg>;
+ regulator-allow-bypass;
+};
+
+&reg_soc {
+ vin-supply = <&sw1c_reg>;
+ regulator-allow-bypass;
+};
+
+&csi {
+ status = "disabled";
+
+ port {
+ csi1_ep: endpoint {
+ remote-endpoint = <&ov5640_ep>;
+ };
+ };
+};
+
+&fec1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_enet1>;
+ phy-mode = "rmii";
+ phy-handle = <&ethphy0>;
+ status = "okay";
+};
+
+&fec2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_enet2>;
+ phy-mode = "rmii";
+ phy-handle = <&ethphy1>;
+ status = "okay";
+
+ mdio {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ethphy0: ethernet-phy@2 {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <2>;
+ };
+
+ ethphy1: ethernet-phy@1 {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <1>;
+ };
+ };
+};
+
+&can1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_flexcan1>;
+ xceiver-supply = <&reg_can_3v3>;
+ status = "okay";
+};
+
+&can2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_flexcan2>;
+ xceiver-supply = <&reg_can_3v3>;
+ status = "okay";
+};
+
+&gpc {
+ fsl,cpu_pupscr_sw2iso = <0xf>;
+ fsl,cpu_pupscr_sw = <0x0>;
+ fsl,cpu_pdnscr_iso2sw = <0x1>;
+ fsl,cpu_pdnscr_iso = <0x1>;
+ fsl,ldo-bypass = <1>;
+};
+
+&i2c1 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c1>;
+ status = "okay";
+
+ pmic: pfuze3000@08 {
+ compatible = "fsl,pfuze3000";
+ reg = <0x08>;
+
+ regulators {
+ sw1a_reg: sw1a {
+ regulator-min-microvolt = <700000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ regulator-ramp-delay = <6250>;
+ };
+
+ /* use sw1c_reg to align with pfuze100/pfuze200 */
+ sw1c_reg: sw1b {
+ regulator-min-microvolt = <700000>;
+ regulator-max-microvolt = <1475000>;
+ regulator-boot-on;
+ regulator-always-on;
+ regulator-ramp-delay = <6250>;
+ };
+
+ sw2_reg: sw2 {
+ regulator-min-microvolt = <2500000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ sw3a_reg: sw3 {
+ regulator-min-microvolt = <900000>;
+ regulator-max-microvolt = <1650000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ swbst_reg: swbst {
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5150000>;
+ };
+
+ snvs_reg: vsnvs {
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ vref_reg: vrefddr {
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ vgen1_reg: vldo1 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ vgen2_reg: vldo2 {
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1550000>;
+ regulator-always-on;
+ };
+
+ vgen3_reg: vccsd {
+ regulator-min-microvolt = <2850000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ vgen4_reg: v33 {
+ regulator-min-microvolt = <2850000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ vgen5_reg: vldo3 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ vgen6_reg: vldo4 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+ };
+ };
+
+ mag3110@0e {
+ compatible = "fsl,mag3110";
+ reg = <0x0e>;
+ position = <2>;
+ };
+
+ fxls8471@1e {
+ compatible = "fsl,fxls8471";
+ reg = <0x1e>;
+ position = <0>;
+ interrupt-parent = <&gpio5>;
+ interrupts = <0 8>;
+ };
+};
+
+&i2c2 {
+ clock_frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c2>;
+ status = "okay";
+
+ codec: wm8960@1a {
+ compatible = "wlf,wm8960";
+ reg = <0x1a>;
+ clocks = <&clks IMX6UL_CLK_SAI2>;
+ clock-names = "mclk";
+ wlf,shared-lrclk;
+ };
+
+ ov5640: ov5640@3c {
+ compatible = "ovti,ov5640";
+ reg = <0x3c>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_csi1>;
+ clocks = <&clks IMX6UL_CLK_CSI>;
+ clock-names = "csi_mclk";
+ pwn-gpios = <&gpio_spi 6 1>;
+ rst-gpios = <&gpio_spi 5 0>;
+ csi_id = <0>;
+ mclk = <24000000>;
+ mclk_source = <0>;
+ status = "disabled";
+ port {
+ ov5640_ep: endpoint {
+ remote-endpoint = <&csi1_ep>;
+ };
+ };
+ };
+};
+
+&iomuxc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_hog_1>;
+ imx6ul-evk {
+ pinctrl_csi1: csi1grp {
+ fsl,pins = <
+ MX6UL_PAD_CSI_MCLK__CSI_MCLK 0x1b088
+ MX6UL_PAD_CSI_PIXCLK__CSI_PIXCLK 0x1b088
+ MX6UL_PAD_CSI_VSYNC__CSI_VSYNC 0x1b088
+ MX6UL_PAD_CSI_HSYNC__CSI_HSYNC 0x1b088
+ MX6UL_PAD_CSI_DATA00__CSI_DATA02 0x1b088
+ MX6UL_PAD_CSI_DATA01__CSI_DATA03 0x1b088
+ MX6UL_PAD_CSI_DATA02__CSI_DATA04 0x1b088
+ MX6UL_PAD_CSI_DATA03__CSI_DATA05 0x1b088
+ MX6UL_PAD_CSI_DATA04__CSI_DATA06 0x1b088
+ MX6UL_PAD_CSI_DATA05__CSI_DATA07 0x1b088
+ MX6UL_PAD_CSI_DATA06__CSI_DATA08 0x1b088
+ MX6UL_PAD_CSI_DATA07__CSI_DATA09 0x1b088
+ >;
+ };
+
+ pinctrl_dvfs: dvfsgrp {
+ fsl,pins = <
+ MX6UL_PAD_SNVS_TAMPER3__GPIO5_IO03 0x79
+ >;
+ };
+
+ pinctrl_enet1: enet1grp {
+ fsl,pins = <
+ MX6UL_PAD_ENET1_RX_EN__ENET1_RX_EN 0x1b0b0
+ MX6UL_PAD_ENET1_RX_ER__ENET1_RX_ER 0x1b0b0
+ MX6UL_PAD_ENET1_RX_DATA0__ENET1_RDATA00 0x1b0b0
+ MX6UL_PAD_ENET1_RX_DATA1__ENET1_RDATA01 0x1b0b0
+ MX6UL_PAD_ENET1_TX_EN__ENET1_TX_EN 0x1b0b0
+ MX6UL_PAD_ENET1_TX_DATA0__ENET1_TDATA00 0x1b0b0
+ MX6UL_PAD_ENET1_TX_DATA1__ENET1_TDATA01 0x1b0b0
+ MX6UL_PAD_ENET1_TX_CLK__ENET1_REF_CLK1 0x4001b031
+ >;
+ };
+
+ pinctrl_enet2: enet2grp {
+ fsl,pins = <
+ MX6UL_PAD_GPIO1_IO07__ENET2_MDC 0x1b0b0
+ MX6UL_PAD_GPIO1_IO06__ENET2_MDIO 0x1b0b0
+ MX6UL_PAD_ENET2_RX_EN__ENET2_RX_EN 0x1b0b0
+ MX6UL_PAD_ENET2_RX_ER__ENET2_RX_ER 0x1b0b0
+ MX6UL_PAD_ENET2_RX_DATA0__ENET2_RDATA00 0x1b0b0
+ MX6UL_PAD_ENET2_RX_DATA1__ENET2_RDATA01 0x1b0b0
+ MX6UL_PAD_ENET2_TX_EN__ENET2_TX_EN 0x1b0b0
+ MX6UL_PAD_ENET2_TX_DATA0__ENET2_TDATA00 0x1b0b0
+ MX6UL_PAD_ENET2_TX_DATA1__ENET2_TDATA01 0x1b0b0
+ MX6UL_PAD_ENET2_TX_CLK__ENET2_REF_CLK2 0x4001b031
+ MX6UL_PAD_SNVS_TAMPER0__GPIO5_IO00 0x80000000
+ >;
+ };
+
+ pinctrl_flexcan1: flexcan1grp{
+ fsl,pins = <
+ MX6UL_PAD_UART3_RTS_B__FLEXCAN1_RX 0x1b020
+ MX6UL_PAD_UART3_CTS_B__FLEXCAN1_TX 0x1b020
+ >;
+ };
+
+ pinctrl_flexcan2: flexcan2grp{
+ fsl,pins = <
+ MX6UL_PAD_UART2_RTS_B__FLEXCAN2_RX 0x1b020
+ MX6UL_PAD_UART2_CTS_B__FLEXCAN2_TX 0x1b020
+ >;
+ };
+
+ pinctrl_hog_1: hoggrp-1 {
+ fsl,pins = <
+ MX6UL_PAD_UART1_RTS_B__GPIO1_IO19 0x17059 /* SD1 CD */
+ MX6UL_PAD_GPIO1_IO05__USDHC1_VSELECT 0x17059 /* SD1 VSELECT */
+ MX6UL_PAD_GPIO1_IO09__GPIO1_IO09 0x17059 /* SD1 RESET */
+ >;
+ };
+
+ pinctrl_i2c1: i2c1grp {
+ fsl,pins = <
+ MX6UL_PAD_UART4_TX_DATA__I2C1_SCL 0x4001b8b0
+ MX6UL_PAD_UART4_RX_DATA__I2C1_SDA 0x4001b8b0
+ >;
+ };
+
+ pinctrl_i2c2: i2c2grp {
+ fsl,pins = <
+ MX6UL_PAD_UART5_TX_DATA__I2C2_SCL 0x4001b8b0
+ MX6UL_PAD_UART5_RX_DATA__I2C2_SDA 0x4001b8b0
+ >;
+ };
+
+ pinctrl_lcdif_ctrl: lcdifctrlgrp {
+ fsl,pins = <
+ MX6UL_PAD_LCD_CLK__LCDIF_CLK 0x79
+ MX6UL_PAD_LCD_ENABLE__LCDIF_ENABLE 0x79
+ MX6UL_PAD_LCD_HSYNC__LCDIF_HSYNC 0x79
+ MX6UL_PAD_LCD_VSYNC__LCDIF_VSYNC 0x79
+ /* used for lcd reset */
+ MX6UL_PAD_SNVS_TAMPER9__GPIO5_IO09 0x79
+ >;
+ };
+
+ pinctrl_lcdif_dat: lcdifdatgrp {
+ fsl,pins = <
+ MX6UL_PAD_LCD_DATA00__LCDIF_DATA00 0x79
+ MX6UL_PAD_LCD_DATA01__LCDIF_DATA01 0x79
+ MX6UL_PAD_LCD_DATA02__LCDIF_DATA02 0x79
+ MX6UL_PAD_LCD_DATA03__LCDIF_DATA03 0x79
+ MX6UL_PAD_LCD_DATA04__LCDIF_DATA04 0x79
+ MX6UL_PAD_LCD_DATA05__LCDIF_DATA05 0x79
+ MX6UL_PAD_LCD_DATA06__LCDIF_DATA06 0x79
+ MX6UL_PAD_LCD_DATA07__LCDIF_DATA07 0x79
+ MX6UL_PAD_LCD_DATA08__LCDIF_DATA08 0x79
+ MX6UL_PAD_LCD_DATA09__LCDIF_DATA09 0x79
+ MX6UL_PAD_LCD_DATA10__LCDIF_DATA10 0x79
+ MX6UL_PAD_LCD_DATA11__LCDIF_DATA11 0x79
+ MX6UL_PAD_LCD_DATA12__LCDIF_DATA12 0x79
+ MX6UL_PAD_LCD_DATA13__LCDIF_DATA13 0x79
+ MX6UL_PAD_LCD_DATA14__LCDIF_DATA14 0x79
+ MX6UL_PAD_LCD_DATA15__LCDIF_DATA15 0x79
+ MX6UL_PAD_LCD_DATA16__LCDIF_DATA16 0x79
+ MX6UL_PAD_LCD_DATA17__LCDIF_DATA17 0x79
+ MX6UL_PAD_LCD_DATA18__LCDIF_DATA18 0x79
+ MX6UL_PAD_LCD_DATA19__LCDIF_DATA19 0x79
+ MX6UL_PAD_LCD_DATA20__LCDIF_DATA20 0x79
+ MX6UL_PAD_LCD_DATA21__LCDIF_DATA21 0x79
+ MX6UL_PAD_LCD_DATA22__LCDIF_DATA22 0x79
+ MX6UL_PAD_LCD_DATA23__LCDIF_DATA23 0x79
+ >;
+ };
+
+ pinctrl_pwm1: pwm1grp {
+ fsl,pins = <
+ MX6UL_PAD_GPIO1_IO08__PWM1_OUT 0x110b0
+ >;
+ };
+
+ pinctrl_qspi: qspigrp {
+ fsl,pins = <
+ MX6UL_PAD_NAND_WP_B__QSPI_A_SCLK 0x70a1
+ MX6UL_PAD_NAND_READY_B__QSPI_A_DATA00 0x70a1
+ MX6UL_PAD_NAND_CE0_B__QSPI_A_DATA01 0x70a1
+ MX6UL_PAD_NAND_CE1_B__QSPI_A_DATA02 0x70a1
+ MX6UL_PAD_NAND_CLE__QSPI_A_DATA03 0x70a1
+ MX6UL_PAD_NAND_DQS__QSPI_A_SS0_B 0x70a1
+ >;
+ };
+
+ pinctrl_sai2: sai2grp {
+ fsl,pins = <
+ MX6UL_PAD_JTAG_TDI__SAI2_TX_BCLK 0x17088
+ MX6UL_PAD_JTAG_TDO__SAI2_TX_SYNC 0x17088
+ MX6UL_PAD_JTAG_TRST_B__SAI2_TX_DATA 0x11088
+ MX6UL_PAD_JTAG_TCK__SAI2_RX_DATA 0x11088
+ MX6UL_PAD_JTAG_TMS__SAI2_MCLK 0x17088
+ MX6UL_PAD_SNVS_TAMPER4__GPIO5_IO04 0x17059
+ >;
+ };
+
+ pinctrl_sim2_1: sim2grp-1 {
+ fsl,pins = <
+ MX6UL_PAD_CSI_DATA03__SIM2_PORT1_PD 0xb808
+ MX6UL_PAD_CSI_DATA04__SIM2_PORT1_CLK 0x31
+ MX6UL_PAD_CSI_DATA05__SIM2_PORT1_RST_B 0xb808
+ MX6UL_PAD_CSI_DATA06__SIM2_PORT1_SVEN 0xb808
+ MX6UL_PAD_CSI_DATA07__SIM2_PORT1_TRXD 0xb809
+ MX6UL_PAD_CSI_DATA02__GPIO4_IO23 0x3008
+ >;
+ };
+
+ pinctrl_spi4: spi4grp {
+ fsl,pins = <
+ MX6UL_PAD_BOOT_MODE0__GPIO5_IO10 0x70a1
+ MX6UL_PAD_BOOT_MODE1__GPIO5_IO11 0x70a1
+ MX6UL_PAD_SNVS_TAMPER7__GPIO5_IO07 0x70a1
+ MX6UL_PAD_SNVS_TAMPER8__GPIO5_IO08 0x80000000
+ >;
+ };
+
+ pinctrl_tsc: tscgrp {
+ fsl,pins = <
+ MX6UL_PAD_GPIO1_IO01__GPIO1_IO01 0xb0
+ MX6UL_PAD_GPIO1_IO02__GPIO1_IO02 0xb0
+ MX6UL_PAD_GPIO1_IO03__GPIO1_IO03 0xb0
+ MX6UL_PAD_GPIO1_IO04__GPIO1_IO04 0xb0
+ >;
+ };
+
+ pinctrl_uart1: uart1grp {
+ fsl,pins = <
+ MX6UL_PAD_UART1_TX_DATA__UART1_DCE_TX 0x1b0b1
+ MX6UL_PAD_UART1_RX_DATA__UART1_DCE_RX 0x1b0b1
+ >;
+ };
+
+ pinctrl_uart2: uart2grp {
+ fsl,pins = <
+ MX6UL_PAD_UART2_TX_DATA__UART2_DCE_TX 0x1b0b1
+ MX6UL_PAD_UART2_RX_DATA__UART2_DCE_RX 0x1b0b1
+ MX6UL_PAD_UART3_RX_DATA__UART2_DCE_RTS 0x1b0b1
+ MX6UL_PAD_UART3_TX_DATA__UART2_DCE_CTS 0x1b0b1
+ >;
+ };
+
+ pinctrl_uart2dte: uart2dtegrp {
+ fsl,pins = <
+ MX6UL_PAD_UART2_TX_DATA__UART2_DTE_RX 0x1b0b1
+ MX6UL_PAD_UART2_RX_DATA__UART2_DTE_TX 0x1b0b1
+ MX6UL_PAD_UART3_RX_DATA__UART2_DTE_CTS 0x1b0b1
+ MX6UL_PAD_UART3_TX_DATA__UART2_DTE_RTS 0x1b0b1
+ >;
+ };
+
+ pinctrl_usdhc1: usdhc1grp {
+ fsl,pins = <
+ MX6UL_PAD_SD1_CMD__USDHC1_CMD 0x17059
+ MX6UL_PAD_SD1_CLK__USDHC1_CLK 0x10059
+ MX6UL_PAD_SD1_DATA0__USDHC1_DATA0 0x17059
+ MX6UL_PAD_SD1_DATA1__USDHC1_DATA1 0x17059
+ MX6UL_PAD_SD1_DATA2__USDHC1_DATA2 0x17059
+ MX6UL_PAD_SD1_DATA3__USDHC1_DATA3 0x17059
+ >;
+ };
+
+ pinctrl_usdhc1_100mhz: usdhc1grp100mhz {
+ fsl,pins = <
+ MX6UL_PAD_SD1_CMD__USDHC1_CMD 0x170b9
+ MX6UL_PAD_SD1_CLK__USDHC1_CLK 0x100b9
+ MX6UL_PAD_SD1_DATA0__USDHC1_DATA0 0x170b9
+ MX6UL_PAD_SD1_DATA1__USDHC1_DATA1 0x170b9
+ MX6UL_PAD_SD1_DATA2__USDHC1_DATA2 0x170b9
+ MX6UL_PAD_SD1_DATA3__USDHC1_DATA3 0x170b9
+ >;
+ };
+
+ pinctrl_usdhc1_200mhz: usdhc1grp200mhz {
+ fsl,pins = <
+ MX6UL_PAD_SD1_CMD__USDHC1_CMD 0x170f9
+ MX6UL_PAD_SD1_CLK__USDHC1_CLK 0x100f9
+ MX6UL_PAD_SD1_DATA0__USDHC1_DATA0 0x170f9
+ MX6UL_PAD_SD1_DATA1__USDHC1_DATA1 0x170f9
+ MX6UL_PAD_SD1_DATA2__USDHC1_DATA2 0x170f9
+ MX6UL_PAD_SD1_DATA3__USDHC1_DATA3 0x170f9
+ >;
+ };
+
+ pinctrl_usdhc2: usdhc2grp {
+ fsl,pins = <
+ MX6UL_PAD_NAND_RE_B__USDHC2_CLK 0x17059
+ MX6UL_PAD_NAND_WE_B__USDHC2_CMD 0x17059
+ MX6UL_PAD_NAND_DATA00__USDHC2_DATA0 0x17059
+ MX6UL_PAD_NAND_DATA01__USDHC2_DATA1 0x17059
+ MX6UL_PAD_NAND_DATA02__USDHC2_DATA2 0x17059
+ MX6UL_PAD_NAND_DATA03__USDHC2_DATA3 0x17059
+ >;
+ };
+
+ pinctrl_wdog: wdoggrp {
+ fsl,pins = <
+ MX6UL_PAD_LCD_RESET__WDOG1_WDOG_ANY 0x30b0
+ >;
+ };
+ };
+};
+
+&lcdif {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lcdif_dat
+ &pinctrl_lcdif_ctrl>;
+ display = <&display0>;
+ status = "okay";
+
+ display0: display {
+ bits-per-pixel = <16>;
+ bus-width = <24>;
+
+ display-timings {
+ native-mode = <&timing0>;
+ timing0: timing0 {
+ clock-frequency = <9200000>;
+ hactive = <480>;
+ vactive = <272>;
+ hfront-porch = <8>;
+ hback-porch = <4>;
+ hsync-len = <41>;
+ vback-porch = <2>;
+ vfront-porch = <4>;
+ vsync-len = <10>;
+
+ hsync-active = <0>;
+ vsync-active = <0>;
+ de-active = <1>;
+ pixelclk-active = <0>;
+ };
+ };
+ };
+};
+
+&pwm1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pwm1>;
+ status = "okay";
+};
+
+&pxp {
+ status = "okay";
+};
+
+&qspi {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_qspi>;
+ status = "okay";
+ ddrsmp=<0>;
+
+ flash0: n25q256a@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "micron,n25q256a";
+ spi-max-frequency = <29000000>;
+ spi-nor,ddr-quad-read-dummy = <6>;
+ reg = <0>;
+ };
+};
+
+&sai2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_sai2>;
+
+ assigned-clocks = <&clks IMX6UL_CLK_SAI2_SEL>,
+ <&clks IMX6UL_CLK_SAI2>;
+ assigned-clock-parents = <&clks IMX6UL_CLK_PLL4_AUDIO_DIV>;
+ assigned-clock-rates = <0>, <12288000>;
+
+ status = "okay";
+};
+
+&sim2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_sim2_1>;
+ assigned-clocks = <&clks IMX6UL_CLK_SIM_SEL>;
+ assigned-clock-parents = <&clks IMX6UL_CLK_SIM_PODF>;
+ assigned-clock-rates = <240000000>;
+ pinctrl-assert-gpios = <&gpio4 23 GPIO_ACTIVE_LOW>;
+ port = <1>;
+ sven_low_active;
+ status = "okay";
+};
+
+&tsc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_tsc>;
+ xnur-gpio = <&gpio1 3 GPIO_ACTIVE_LOW>;
+ measure_delay_time = <0xffff>;
+ pre_charge_time = <0xfff>;
+ status = "okay";
+};
+
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart1>;
+ status = "okay";
+};
+
+&uart2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart2>;
+ fsl,uart-has-rtscts;
+ /* for DTE mode, add below change */
+ /* fsl,dte-mode; */
+ /* pinctrl-0 = <&pinctrl_uart2dte>; */
+ status = "okay";
+};
+
+&usbotg1 {
+ dr_mode = "otg";
+ srp-disable;
+ hnp-disable;
+ adp-disable;
+ status = "okay";
+};
+
+&usbotg2 {
+ dr_mode = "host";
+ disable-over-current;
+ status = "okay";
+};
+
+&usdhc1 {
+ pinctrl-names = "default", "state_100mhz", "state_200mhz";
+ pinctrl-0 = <&pinctrl_usdhc1>;
+ pinctrl-1 = <&pinctrl_usdhc1_100mhz>;
+ pinctrl-2 = <&pinctrl_usdhc1_200mhz>;
+ cd-gpios = <&gpio1 19 GPIO_ACTIVE_LOW>;
+ keep-power-in-suspend;
+ enable-sdio-wakeup;
+ vmmc-supply = <&reg_sd1_vmmc>;
+ status = "okay";
+};
+
+&usdhc2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usdhc2>;
+ no-1-8-v;
+ non-removable;
+ keep-power-in-suspend;
+ enable-sdio-wakeup;
+ status = "okay";
+};
+
+&wdog1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_wdog>;
+ fsl,ext-reset-output;
+};
diff --git a/arch/arm/boot/dts/imx6ul-evk-btwifi-oob.dtsi b/arch/arm/boot/dts/imx6ul-evk-btwifi-oob.dtsi
new file mode 100644
index 000000000000..36c013bd253b
--- /dev/null
+++ b/arch/arm/boot/dts/imx6ul-evk-btwifi-oob.dtsi
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2017 NXP
+ *
+ * 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_wifi {
+ fsl,pins = <
+ /* MUXing for WL_HOST_WAKE */
+ MX6UL_PAD_ENET2_RX_ER__GPIO2_IO15 0x13041
+ >;
+};
+
+/*
+ * For WL_HOST_WAKE (OOB_IRQ) to function correctly, we must disable
+ * the secondary ethernet port (FEC2). Hardware re-work is to remove
+ * R1633 and populate R1704 with 0 Ohm resistor.
+ * Refer to Murata Hardware Reference Manual for more details.
+ */
+&fec2 {
+ status = "disabled";
+};
+
+&brcmf {
+ interrupt-parent = <&gpio2>;
+ interrupts = <15 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "host-wake";
+};
diff --git a/arch/arm/boot/dts/imx6ul-evk-btwifi.dtsi b/arch/arm/boot/dts/imx6ul-evk-btwifi.dtsi
new file mode 100644
index 000000000000..a2958fb8c137
--- /dev/null
+++ b/arch/arm/boot/dts/imx6ul-evk-btwifi.dtsi
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2015 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.
+ */
+
+/*
+ * NOTE: This DTS file is written for plugging in Murata Wi-Fi/BT EVK into Slot
+ * SD1 and using Murata i.MX InterConnect Ver 2.0 Adapter. Bluetooth UART &
+ * control signals are connected via ribbon cable (J1701 connector).
+ */
+
+/ {
+ modem_reset: modem-reset {
+ compatible = "gpio-reset";
+ reset-gpios = <&gpio_spi 4 GPIO_ACTIVE_LOW>;
+ reset-delay-us = <1000>;
+ #reset-cells = <0>;
+ };
+
+ usdhc1_pwrseq: usdhc1_pwrseq {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_wifi>;
+ compatible = "mmc-pwrseq-simple";
+ reset-gpios = <&gpio5 1 GPIO_ACTIVE_LOW>;
+ };
+};
+
+&iomuxc {
+ pinctrl_wifi: wifigrp {
+ fsl,pins = <
+ MX6UL_PAD_SNVS_TAMPER1__GPIO5_IO01 0x03029
+ >;
+ };
+};
+
+&reg_sd1_vmmc {
+ regulator-always-on;
+};
+
+&uart2 {
+ resets = <&modem_reset>;
+};
+
+&usdhc1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usdhc1>;
+ no-1-8-v;
+ non-removable;
+ pm-ignore-notify;
+ mmc-pwrseq = <&usdhc1_pwrseq>;
+ cap-power-off-card;
+
+ brcmf: bcrmf@1 {
+ reg = <1>;
+ compatible = "brcm,bcm4329-fmac";
+ };
+};
+
+&gpio_spi {
+ /* Murata: modify default setting so that BT_nPWD/BT_REG_ON
+ * is low (0V) during kernel boot.
+ */
+ registers-default = /bits/ 8 <0x47>;
+};
diff --git a/arch/arm/boot/dts/imx6ul-pinfunc.h b/arch/arm/boot/dts/imx6ul-pinfunc.h
index 0034eeb84542..9538b0ed5c11 100644
--- a/arch/arm/boot/dts/imx6ul-pinfunc.h
+++ b/arch/arm/boot/dts/imx6ul-pinfunc.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2015 Freescale Semiconductor, Inc.
+ * Copyright 2014 - 2015 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
@@ -34,14 +34,14 @@
#define MX6UL_PAD_JTAG_MOD__ENET1_REF_CLK_25M 0x0044 0x02d0 0x0000 3 0
#define MX6UL_PAD_JTAG_MOD__CCM_PMIC_RDY 0x0044 0x02d0 0x04c0 4 0
#define MX6UL_PAD_JTAG_MOD__GPIO1_IO10 0x0044 0x02d0 0x0000 5 0
-#define MX6UL_PAD_JTAG_MOD__SDMA_EXT_EVENT00 0x0044 0x02d0 0x0000 6 0
+#define MX6UL_PAD_JTAG_MOD__SDMA_EXT_EVENT00 0x0044 0x02d0 0x0610 6 0
#define MX6UL_PAD_JTAG_TMS__SJC_TMS 0x0048 0x02d4 0x0000 0 0
#define MX6UL_PAD_JTAG_TMS__GPT2_CAPTURE1 0x0048 0x02d4 0x0598 1 0
-#define MX6UL_PAD_JTAG_TMS__SAI2_MCLK 0x0048 0x02d4 0x0000 2 0
+#define MX6UL_PAD_JTAG_TMS__SAI2_MCLK 0x0048 0x02d4 0x05f0 2 0
#define MX6UL_PAD_JTAG_TMS__CCM_CLKO1 0x0048 0x02d4 0x0000 3 0
#define MX6UL_PAD_JTAG_TMS__CCM_WAIT 0x0048 0x02d4 0x0000 4 0
#define MX6UL_PAD_JTAG_TMS__GPIO1_IO11 0x0048 0x02d4 0x0000 5 0
-#define MX6UL_PAD_JTAG_TMS__SDMA_EXT_EVENT01 0x0048 0x02d4 0x0000 6 0
+#define MX6UL_PAD_JTAG_TMS__SDMA_EXT_EVENT01 0x0048 0x02d4 0x0614 6 0
#define MX6UL_PAD_JTAG_TMS__EPIT1_OUT 0x0048 0x02d4 0x0000 8 0
#define MX6UL_PAD_JTAG_TDO__SJC_TDO 0x004c 0x02d8 0x0000 0 0
#define MX6UL_PAD_JTAG_TDO__GPT2_CAPTURE2 0x004c 0x02d8 0x059c 1 0
@@ -63,12 +63,14 @@
#define MX6UL_PAD_JTAG_TCK__SAI2_RX_DATA 0x0054 0x02e0 0x05f4 2 0
#define MX6UL_PAD_JTAG_TCK__PWM7_OUT 0x0054 0x02e0 0x0000 4 0
#define MX6UL_PAD_JTAG_TCK__GPIO1_IO14 0x0054 0x02e0 0x0000 5 0
+#define MX6UL_PAD_JTAG_TCK__REF_CLK_32K 0x0054 0x02e0 0x0000 6 0
#define MX6UL_PAD_JTAG_TCK__SIM2_POWER_FAIL 0x0054 0x02e0 0x0000 8 0
#define MX6UL_PAD_JTAG_TRST_B__SJC_TRSTB 0x0058 0x02e4 0x0000 0 0
#define MX6UL_PAD_JTAG_TRST_B__GPT2_COMPARE3 0x0058 0x02e4 0x0000 1 0
#define MX6UL_PAD_JTAG_TRST_B__SAI2_TX_DATA 0x0058 0x02e4 0x0000 2 0
#define MX6UL_PAD_JTAG_TRST_B__PWM8_OUT 0x0058 0x02e4 0x0000 4 0
#define MX6UL_PAD_JTAG_TRST_B__GPIO1_IO15 0x0058 0x02e4 0x0000 5 0
+#define MX6UL_PAD_JTAG_TRST_B__REF_CLK_24M 0x0058 0x02e4 0x0000 6 0
#define MX6UL_PAD_JTAG_TRST_B__CAAM_RNG_OSC_OBS 0x0058 0x02e4 0x0000 8 0
#define MX6UL_PAD_GPIO1_IO00__I2C2_SCL 0x005c 0x02e8 0x05ac 0 1
#define MX6UL_PAD_GPIO1_IO00__GPT1_CAPTURE1 0x005c 0x02e8 0x058c 1 0
@@ -94,22 +96,24 @@
#define MX6UL_PAD_GPIO1_IO02__ENET1_REF_CLK_25M 0x0064 0x02f0 0x0000 3 0
#define MX6UL_PAD_GPIO1_IO02__USDHC1_WP 0x0064 0x02f0 0x066c 4 0
#define MX6UL_PAD_GPIO1_IO02__GPIO1_IO02 0x0064 0x02f0 0x0000 5 0
-#define MX6UL_PAD_GPIO1_IO02__SDMA_EXT_EVENT00 0x0064 0x02f0 0x0000 6 0
+#define MX6UL_PAD_GPIO1_IO02__SDMA_EXT_EVENT00 0x0064 0x02f0 0x0610 6 1
#define MX6UL_PAD_GPIO1_IO02__SRC_ANY_PU_RESET 0x0064 0x02f0 0x0000 7 0
#define MX6UL_PAD_GPIO1_IO02__UART1_DCE_TX 0x0064 0x02f0 0x0000 8 0
#define MX6UL_PAD_GPIO1_IO02__UART1_DTE_RX 0x0064 0x02f0 0x0624 8 0
#define MX6UL_PAD_GPIO1_IO03__I2C1_SDA 0x0068 0x02f4 0x05a8 0 1
#define MX6UL_PAD_GPIO1_IO03__GPT1_COMPARE3 0x0068 0x02f4 0x0000 1 0
#define MX6UL_PAD_GPIO1_IO03__USB_OTG2_OC 0x0068 0x02f4 0x0660 2 0
+#define MX6UL_PAD_GPIO1_IO03__REF_CLK_32K 0x0068 0x02f4 0x0000 3 0
#define MX6UL_PAD_GPIO1_IO03__USDHC1_CD_B 0x0068 0x02f4 0x0668 4 0
#define MX6UL_PAD_GPIO1_IO03__GPIO1_IO03 0x0068 0x02f4 0x0000 5 0
-#define MX6UL_PAD_GPIO1_IO03__CCM_DI0_eXT_CLK 0x0068 0x02f4 0x0000 6 0
+#define MX6UL_PAD_GPIO1_IO03__CCM_DI0_EXT_CLK 0x0068 0x02f4 0x0000 6 0
#define MX6UL_PAD_GPIO1_IO03__SRC_TESTER_ACK 0x0068 0x02f4 0x0000 7 0
-#define MX6UL_PAD_GPIO1_IO03__UART1_DTE_TX 0x0068 0x02f4 0x0000 8 0
#define MX6UL_PAD_GPIO1_IO03__UART1_DCE_RX 0x0068 0x02f4 0x0624 8 1
+#define MX6UL_PAD_GPIO1_IO03__UART1_DTE_TX 0x0068 0x02f4 0x0000 8 0
#define MX6UL_PAD_GPIO1_IO04__ENET1_REF_CLK1 0x006c 0x02f8 0x0574 0 1
#define MX6UL_PAD_GPIO1_IO04__PWM3_OUT 0x006c 0x02f8 0x0000 1 0
#define MX6UL_PAD_GPIO1_IO04__USB_OTG1_PWR 0x006c 0x02f8 0x0000 2 0
+#define MX6UL_PAD_GPIO1_IO04__REF_CLK_24M 0x006c 0x02f8 0x0000 3 0
#define MX6UL_PAD_GPIO1_IO04__USDHC1_RESET_B 0x006c 0x02f8 0x0000 4 0
#define MX6UL_PAD_GPIO1_IO04__GPIO1_IO04 0x006c 0x02f8 0x0000 5 0
#define MX6UL_PAD_GPIO1_IO04__ENET2_1588_EVENT0_IN 0x006c 0x02f8 0x0000 6 0
@@ -200,7 +204,7 @@
#define MX6UL_PAD_UART2_TX_DATA__CSI_DATA06 0x0094 0x0320 0x04dc 3 0
#define MX6UL_PAD_UART2_TX_DATA__GPT1_CAPTURE1 0x0094 0x0320 0x058c 4 1
#define MX6UL_PAD_UART2_TX_DATA__GPIO1_IO20 0x0094 0x0320 0x0000 5 0
-#define MX6UL_PAD_UART2_TX_DATA__ECSPI3_SS0 0x0094 0x0320 0x0000 8 0
+#define MX6UL_PAD_UART2_TX_DATA__ECSPI3_SS0 0x0094 0x0320 0x0560 8 0
#define MX6UL_PAD_UART2_RX_DATA__UART2_DCE_RX 0x0098 0x0324 0x062c 0 1
#define MX6UL_PAD_UART2_RX_DATA__UART2_DTE_TX 0x0098 0x0324 0x0000 0 0
#define MX6UL_PAD_UART2_RX_DATA__ENET1_TDATA03 0x0098 0x0324 0x0000 1 0
@@ -232,7 +236,7 @@
#define MX6UL_PAD_UART3_TX_DATA__UART3_DTE_RX 0x00a4 0x0330 0x0634 0 0
#define MX6UL_PAD_UART3_TX_DATA__ENET2_RDATA02 0x00a4 0x0330 0x0000 1 0
#define MX6UL_PAD_UART3_TX_DATA__SIM1_PORT0_PD 0x00a4 0x0330 0x0000 2 0
-#define MX6UL_PAD_UART3_TX_DATA__CSI_DATA01 0x00a4 0x0330 0x0000 3 0
+#define MX6UL_PAD_UART3_TX_DATA__CSI_DATA01 0x00a4 0x0330 0x04d4 3 0
#define MX6UL_PAD_UART3_TX_DATA__UART2_DCE_CTS 0x00a4 0x0330 0x0000 4 0
#define MX6UL_PAD_UART3_TX_DATA__UART2_DTE_RTS 0x00a4 0x0330 0x0628 4 2
#define MX6UL_PAD_UART3_TX_DATA__GPIO1_IO24 0x00a4 0x0330 0x0000 5 0
@@ -242,7 +246,7 @@
#define MX6UL_PAD_UART3_RX_DATA__UART3_DTE_TX 0x00a8 0x0334 0x0000 0 0
#define MX6UL_PAD_UART3_RX_DATA__ENET2_RDATA03 0x00a8 0x0334 0x0000 1 0
#define MX6UL_PAD_UART3_RX_DATA__SIM2_PORT0_PD 0x00a8 0x0334 0x0000 2 0
-#define MX6UL_PAD_UART3_RX_DATA__CSI_DATA00 0x00a8 0x0334 0x0000 3 0
+#define MX6UL_PAD_UART3_RX_DATA__CSI_DATA00 0x00a8 0x0334 0x04d0 3 0
#define MX6UL_PAD_UART3_RX_DATA__UART2_DCE_RTS 0x00a8 0x0334 0x0628 4 3
#define MX6UL_PAD_UART3_RX_DATA__UART2_DTE_CTS 0x00a8 0x0334 0x0000 4 0
#define MX6UL_PAD_UART3_RX_DATA__GPIO1_IO25 0x00a8 0x0334 0x0000 5 0
@@ -251,7 +255,7 @@
#define MX6UL_PAD_UART3_CTS_B__UART3_DTE_RTS 0x00ac 0x0338 0x0630 0 0
#define MX6UL_PAD_UART3_CTS_B__ENET2_RX_CLK 0x00ac 0x0338 0x0000 1 0
#define MX6UL_PAD_UART3_CTS_B__FLEXCAN1_TX 0x00ac 0x0338 0x0000 2 0
-#define MX6UL_PAD_UART3_CTS_B__CSI_DATA10 0x00ac 0x0338 0x0000 3 0
+#define MX6UL_PAD_UART3_CTS_B__CSI_DATA10 0x00ac 0x0338 0x04ec 3 0
#define MX6UL_PAD_UART3_CTS_B__ENET1_1588_EVENT1_IN 0x00ac 0x0338 0x0000 4 0
#define MX6UL_PAD_UART3_CTS_B__GPIO1_IO26 0x00ac 0x0338 0x0000 5 0
#define MX6UL_PAD_UART3_CTS_B__EPIT2_OUT 0x00ac 0x0338 0x0000 8 0
@@ -259,7 +263,7 @@
#define MX6UL_PAD_UART3_RTS_B__UART3_DTE_CTS 0x00b0 0x033c 0x0000 0 0
#define MX6UL_PAD_UART3_RTS_B__ENET2_TX_ER 0x00b0 0x033c 0x0000 1 0
#define MX6UL_PAD_UART3_RTS_B__FLEXCAN1_RX 0x00b0 0x033c 0x0584 2 0
-#define MX6UL_PAD_UART3_RTS_B__CSI_DATA11 0x00b0 0x033c 0x0000 3 0
+#define MX6UL_PAD_UART3_RTS_B__CSI_DATA11 0x00b0 0x033c 0x04f0 3 0
#define MX6UL_PAD_UART3_RTS_B__ENET1_1588_EVENT1_OUT 0x00b0 0x033c 0x0000 4 0
#define MX6UL_PAD_UART3_RTS_B__GPIO1_IO27 0x00b0 0x033c 0x0000 5 0
#define MX6UL_PAD_UART3_RTS_B__WDOG1_WDOG_B 0x00b0 0x033c 0x0000 8 0
@@ -267,7 +271,7 @@
#define MX6UL_PAD_UART4_TX_DATA__UART4_DTE_RX 0x00b4 0x0340 0x063c 0 0
#define MX6UL_PAD_UART4_TX_DATA__ENET2_TDATA02 0x00b4 0x0340 0x0000 1 0
#define MX6UL_PAD_UART4_TX_DATA__I2C1_SCL 0x00b4 0x0340 0x05a4 2 1
-#define MX6UL_PAD_UART4_TX_DATA__CSI_DATA12 0x00b4 0x0340 0x0000 3 0
+#define MX6UL_PAD_UART4_TX_DATA__CSI_DATA12 0x00b4 0x0340 0x04f4 3 0
#define MX6UL_PAD_UART4_TX_DATA__CSU_CSU_ALARM_AUT02 0x00b4 0x0340 0x0000 4 0
#define MX6UL_PAD_UART4_TX_DATA__GPIO1_IO28 0x00b4 0x0340 0x0000 5 0
#define MX6UL_PAD_UART4_TX_DATA__ECSPI2_SCLK 0x00b4 0x0340 0x0544 8 1
@@ -275,23 +279,23 @@
#define MX6UL_PAD_UART4_RX_DATA__UART4_DTE_TX 0x00b8 0x0344 0x0000 0 0
#define MX6UL_PAD_UART4_RX_DATA__ENET2_TDATA03 0x00b8 0x0344 0x0000 1 0
#define MX6UL_PAD_UART4_RX_DATA__I2C1_SDA 0x00b8 0x0344 0x05a8 2 2
-#define MX6UL_PAD_UART4_RX_DATA__CSI_DATA13 0x00b8 0x0344 0x0000 3 0
+#define MX6UL_PAD_UART4_RX_DATA__CSI_DATA13 0x00b8 0x0344 0x04f8 3 0
#define MX6UL_PAD_UART4_RX_DATA__CSU_CSU_ALARM_AUT01 0x00b8 0x0344 0x0000 4 0
#define MX6UL_PAD_UART4_RX_DATA__GPIO1_IO29 0x00b8 0x0344 0x0000 5 0
-#define MX6UL_PAD_UART4_RX_DATA__ECSPI2_SS0 0x00b8 0x0344 0x0000 8 0
+#define MX6UL_PAD_UART4_RX_DATA__ECSPI2_SS0 0x00b8 0x0344 0x0550 8 1
#define MX6UL_PAD_UART5_TX_DATA__GPIO1_IO30 0x00bc 0x0348 0x0000 5 0
#define MX6UL_PAD_UART5_TX_DATA__ECSPI2_MOSI 0x00bc 0x0348 0x054c 8 0
#define MX6UL_PAD_UART5_TX_DATA__UART5_DCE_TX 0x00bc 0x0348 0x0000 0 0
#define MX6UL_PAD_UART5_TX_DATA__UART5_DTE_RX 0x00bc 0x0348 0x0644 0 4
#define MX6UL_PAD_UART5_TX_DATA__ENET2_CRS 0x00bc 0x0348 0x0000 1 0
#define MX6UL_PAD_UART5_TX_DATA__I2C2_SCL 0x00bc 0x0348 0x05ac 2 2
-#define MX6UL_PAD_UART5_TX_DATA__CSI_DATA14 0x00bc 0x0348 0x0000 3 0
+#define MX6UL_PAD_UART5_TX_DATA__CSI_DATA14 0x00bc 0x0348 0x04fc 3 0
#define MX6UL_PAD_UART5_TX_DATA__CSU_CSU_ALARM_AUT00 0x00bc 0x0348 0x0000 4 0
#define MX6UL_PAD_UART5_RX_DATA__UART5_DCE_RX 0x00c0 0x034c 0x0644 0 5
#define MX6UL_PAD_UART5_RX_DATA__UART5_DTE_TX 0x00c0 0x034c 0x0000 0 0
#define MX6UL_PAD_UART5_RX_DATA__ENET2_COL 0x00c0 0x034c 0x0000 1 0
#define MX6UL_PAD_UART5_RX_DATA__I2C2_SDA 0x00c0 0x034c 0x05b0 2 2
-#define MX6UL_PAD_UART5_RX_DATA__CSI_DATA15 0x00c0 0x034c 0x0000 3 0
+#define MX6UL_PAD_UART5_RX_DATA__CSI_DATA15 0x00c0 0x034c 0x0500 3 0
#define MX6UL_PAD_UART5_RX_DATA__CSU_CSU_INT_DEB 0x00c0 0x034c 0x0000 4 0
#define MX6UL_PAD_UART5_RX_DATA__GPIO1_IO31 0x00c0 0x034c 0x0000 5 0
#define MX6UL_PAD_UART5_RX_DATA__ECSPI2_MISO 0x00c0 0x034c 0x0548 8 1
@@ -299,59 +303,61 @@
#define MX6UL_PAD_ENET1_RX_DATA0__UART4_DCE_RTS 0x00c4 0x0350 0x0638 1 0
#define MX6UL_PAD_ENET1_RX_DATA0__UART4_DTE_CTS 0x00c4 0x0350 0x0000 1 0
#define MX6UL_PAD_ENET1_RX_DATA0__PWM1_OUT 0x00c4 0x0350 0x0000 2 0
-#define MX6UL_PAD_ENET1_RX_DATA0__CSI_DATA16 0x00c4 0x0350 0x0000 3 0
+#define MX6UL_PAD_ENET1_RX_DATA0__CSI_DATA16 0x00c4 0x0350 0x0504 3 0
#define MX6UL_PAD_ENET1_RX_DATA0__FLEXCAN1_TX 0x00c4 0x0350 0x0000 4 0
#define MX6UL_PAD_ENET1_RX_DATA0__GPIO2_IO00 0x00c4 0x0350 0x0000 5 0
-#define MX6UL_PAD_ENET1_RX_DATA0__KPP_ROW00 0x00c4 0x0350 0x0000 6 0
+#define MX6UL_PAD_ENET1_RX_DATA0__KPP_ROW00 0x00c4 0x0350 0x05d0 6 0
#define MX6UL_PAD_ENET1_RX_DATA0__USDHC1_LCTL 0x00c4 0x0350 0x0000 8 0
#define MX6UL_PAD_ENET1_RX_DATA1__ENET1_RDATA01 0x00c8 0x0354 0x0000 0 0
#define MX6UL_PAD_ENET1_RX_DATA1__UART4_DCE_CTS 0x00c8 0x0354 0x0000 1 0
#define MX6UL_PAD_ENET1_RX_DATA1__UART4_DTE_RTS 0x00c8 0x0354 0x0638 1 1
#define MX6UL_PAD_ENET1_RX_DATA1__PWM2_OUT 0x00c8 0x0354 0x0000 2 0
-#define MX6UL_PAD_ENET1_RX_DATA1__CSI_DATA17 0x00c8 0x0354 0x0000 3 0
+#define MX6UL_PAD_ENET1_RX_DATA1__CSI_DATA17 0x00c8 0x0354 0x0508 3 0
#define MX6UL_PAD_ENET1_RX_DATA1__FLEXCAN1_RX 0x00c8 0x0354 0x0584 4 1
#define MX6UL_PAD_ENET1_RX_DATA1__GPIO2_IO01 0x00c8 0x0354 0x0000 5 0
-#define MX6UL_PAD_ENET1_RX_DATA1__KPP_COL00 0x00c8 0x0354 0x0000 6 0
+#define MX6UL_PAD_ENET1_RX_DATA1__KPP_COL00 0x00c8 0x0354 0x05c4 6 0
#define MX6UL_PAD_ENET1_RX_DATA1__USDHC2_LCTL 0x00c8 0x0354 0x0000 8 0
#define MX6UL_PAD_ENET1_RX_EN__ENET1_RX_EN 0x00cc 0x0358 0x0000 0 0
#define MX6UL_PAD_ENET1_RX_EN__UART5_DCE_RTS 0x00cc 0x0358 0x0640 1 3
#define MX6UL_PAD_ENET1_RX_EN__UART5_DTE_CTS 0x00cc 0x0358 0x0000 1 0
-#define MX6UL_PAD_ENET1_RX_EN__CSI_DATA18 0x00cc 0x0358 0x0000 3 0
+#define MX6UL_PAD_ENET1_RX_EN__REF_CLK_32K 0x00cc 0x0358 0x0000 2 0
+#define MX6UL_PAD_ENET1_RX_EN__CSI_DATA18 0x00cc 0x0358 0x050c 3 0
#define MX6UL_PAD_ENET1_RX_EN__FLEXCAN2_TX 0x00cc 0x0358 0x0000 4 0
#define MX6UL_PAD_ENET1_RX_EN__GPIO2_IO02 0x00cc 0x0358 0x0000 5 0
-#define MX6UL_PAD_ENET1_RX_EN__KPP_ROW01 0x00cc 0x0358 0x0000 6 0
+#define MX6UL_PAD_ENET1_RX_EN__KPP_ROW01 0x00cc 0x0358 0x05d4 6 0
#define MX6UL_PAD_ENET1_RX_EN__USDHC1_VSELECT 0x00cc 0x0358 0x0000 8 0
#define MX6UL_PAD_ENET1_TX_DATA0__ENET1_TDATA00 0x00d0 0x035c 0x0000 0 0
#define MX6UL_PAD_ENET1_TX_DATA0__UART5_DCE_CTS 0x00d0 0x035c 0x0000 1 0
#define MX6UL_PAD_ENET1_TX_DATA0__UART5_DTE_RTS 0x00d0 0x035c 0x0640 1 4
-#define MX6UL_PAD_ENET1_TX_DATA0__CSI_DATA19 0x00d0 0x035c 0x0000 3 0
+#define MX6UL_PAD_ENET1_TX_DATA0__REF_CLK_24M 0x00d0 0x035c 0x0000 2 0
+#define MX6UL_PAD_ENET1_TX_DATA0__CSI_DATA19 0x00d0 0x035c 0x0510 3 0
#define MX6UL_PAD_ENET1_TX_DATA0__FLEXCAN2_RX 0x00d0 0x035c 0x0588 4 1
#define MX6UL_PAD_ENET1_TX_DATA0__GPIO2_IO03 0x00d0 0x035c 0x0000 5 0
-#define MX6UL_PAD_ENET1_TX_DATA0__KPP_COL01 0x00d0 0x035c 0x0000 6 0
+#define MX6UL_PAD_ENET1_TX_DATA0__KPP_COL01 0x00d0 0x035c 0x05c8 6 0
#define MX6UL_PAD_ENET1_TX_DATA0__USDHC2_VSELECT 0x00d0 0x035c 0x0000 8 0
#define MX6UL_PAD_ENET1_TX_DATA1__ENET1_TDATA01 0x00d4 0x0360 0x0000 0 0
#define MX6UL_PAD_ENET1_TX_DATA1__UART6_DCE_CTS 0x00d4 0x0360 0x0000 1 0
#define MX6UL_PAD_ENET1_TX_DATA1__UART6_DTE_RTS 0x00d4 0x0360 0x0648 1 2
#define MX6UL_PAD_ENET1_TX_DATA1__PWM5_OUT 0x00d4 0x0360 0x0000 2 0
-#define MX6UL_PAD_ENET1_TX_DATA1__CSI_DATA20 0x00d4 0x0360 0x0000 3 0
+#define MX6UL_PAD_ENET1_TX_DATA1__CSI_DATA20 0x00d4 0x0360 0x0514 3 0
#define MX6UL_PAD_ENET1_TX_DATA1__ENET2_MDIO 0x00d4 0x0360 0x0580 4 1
#define MX6UL_PAD_ENET1_TX_DATA1__GPIO2_IO04 0x00d4 0x0360 0x0000 5 0
-#define MX6UL_PAD_ENET1_TX_DATA1__KPP_ROW02 0x00d4 0x0360 0x0000 6 0
+#define MX6UL_PAD_ENET1_TX_DATA1__KPP_ROW02 0x00d4 0x0360 0x05d8 6 0
#define MX6UL_PAD_ENET1_TX_DATA1__WDOG1_WDOG_RST_B_DEB 0x00d4 0x0360 0x0000 8 0
#define MX6UL_PAD_ENET1_TX_EN__ENET1_TX_EN 0x00d8 0x0364 0x0000 0 0
#define MX6UL_PAD_ENET1_TX_EN__UART6_DCE_RTS 0x00d8 0x0364 0x0648 1 3
#define MX6UL_PAD_ENET1_TX_EN__UART6_DTE_CTS 0x00d8 0x0364 0x0000 1 0
#define MX6UL_PAD_ENET1_TX_EN__PWM6_OUT 0x00d8 0x0364 0x0000 2 0
-#define MX6UL_PAD_ENET1_TX_EN__CSI_DATA21 0x00d8 0x0364 0x0000 3 0
+#define MX6UL_PAD_ENET1_TX_EN__CSI_DATA21 0x00d8 0x0364 0x0518 3 0
#define MX6UL_PAD_ENET1_TX_EN__ENET2_MDC 0x00d8 0x0364 0x0000 4 0
#define MX6UL_PAD_ENET1_TX_EN__GPIO2_IO05 0x00d8 0x0364 0x0000 5 0
-#define MX6UL_PAD_ENET1_TX_EN__KPP_COL02 0x00d8 0x0364 0x0000 6 0
+#define MX6UL_PAD_ENET1_TX_EN__KPP_COL02 0x00d8 0x0364 0x05cc 6 0
#define MX6UL_PAD_ENET1_TX_EN__WDOG2_WDOG_RST_B_DEB 0x00d8 0x0364 0x0000 8 0
#define MX6UL_PAD_ENET1_TX_CLK__ENET1_TX_CLK 0x00dc 0x0368 0x0000 0 0
#define MX6UL_PAD_ENET1_TX_CLK__UART7_DCE_CTS 0x00dc 0x0368 0x0000 1 0
#define MX6UL_PAD_ENET1_TX_CLK__UART7_DTE_RTS 0x00dc 0x0368 0x0650 1 0
#define MX6UL_PAD_ENET1_TX_CLK__PWM7_OUT 0x00dc 0x0368 0x0000 2 0
-#define MX6UL_PAD_ENET1_TX_CLK__CSI_DATA22 0x00dc 0x0368 0x0000 3 0
+#define MX6UL_PAD_ENET1_TX_CLK__CSI_DATA22 0x00dc 0x0368 0x051c 3 0
#define MX6UL_PAD_ENET1_TX_CLK__ENET1_REF_CLK1 0x00dc 0x0368 0x0574 4 2
#define MX6UL_PAD_ENET1_TX_CLK__GPIO2_IO06 0x00dc 0x0368 0x0000 5 0
#define MX6UL_PAD_ENET1_TX_CLK__KPP_ROW03 0x00dc 0x0368 0x0000 6 0
@@ -360,7 +366,7 @@
#define MX6UL_PAD_ENET1_RX_ER__UART7_DCE_RTS 0x00e0 0x036c 0x0650 1 1
#define MX6UL_PAD_ENET1_RX_ER__UART7_DTE_CTS 0x00e0 0x036c 0x0000 1 0
#define MX6UL_PAD_ENET1_RX_ER__PWM8_OUT 0x00e0 0x036c 0x0000 2 0
-#define MX6UL_PAD_ENET1_RX_ER__CSI_DATA23 0x00e0 0x036c 0x0000 3 0
+#define MX6UL_PAD_ENET1_RX_ER__CSI_DATA23 0x00e0 0x036c 0x0520 3 0
#define MX6UL_PAD_ENET1_RX_ER__EIM_CRE 0x00e0 0x036c 0x0000 4 0
#define MX6UL_PAD_ENET1_RX_ER__GPIO2_IO07 0x00e0 0x036c 0x0000 5 0
#define MX6UL_PAD_ENET1_RX_ER__KPP_COL03 0x00e0 0x036c 0x0000 6 0
@@ -377,7 +383,7 @@
#define MX6UL_PAD_ENET2_RX_DATA1__ENET2_RDATA01 0x00e8 0x0374 0x0000 0 0
#define MX6UL_PAD_ENET2_RX_DATA1__UART6_DCE_RX 0x00e8 0x0374 0x064c 1 2
#define MX6UL_PAD_ENET2_RX_DATA1__UART6_DTE_TX 0x00e8 0x0374 0x0000 1 0
-#define MX6UL_PAD_ENET2_RX_DATA1__SIM1_PORT0_cLK 0x00e8 0x0374 0x0000 2 0
+#define MX6UL_PAD_ENET2_RX_DATA1__SIM1_PORT0_CLK 0x00e8 0x0374 0x0000 2 0
#define MX6UL_PAD_ENET2_RX_DATA1__I2C3_SDA 0x00e8 0x0374 0x05b8 3 1
#define MX6UL_PAD_ENET2_RX_DATA1__ENET1_MDC 0x00e8 0x0374 0x0000 4 0
#define MX6UL_PAD_ENET2_RX_DATA1__GPIO2_IO09 0x00e8 0x0374 0x0000 5 0
@@ -400,6 +406,7 @@
#define MX6UL_PAD_ENET2_TX_DATA0__EIM_EB_B02 0x00f0 0x037c 0x0000 4 0
#define MX6UL_PAD_ENET2_TX_DATA0__GPIO2_IO11 0x00f0 0x037c 0x0000 5 0
#define MX6UL_PAD_ENET2_TX_DATA0__KPP_COL05 0x00f0 0x037c 0x0000 6 0
+#define MX6UL_PAD_ENET2_TX_DATA0__REF_CLK_24M 0x00f0 0x037c 0x0000 8 0
#define MX6UL_PAD_ENET2_TX_DATA1__ENET2_TDATA01 0x00f4 0x0380 0x0000 0 0
#define MX6UL_PAD_ENET2_TX_DATA1__UART8_DCE_TX 0x00f4 0x0380 0x0000 1 0
#define MX6UL_PAD_ENET2_TX_DATA1__UART8_DTE_RX 0x00f4 0x0380 0x065c 1 0
@@ -412,7 +419,7 @@
#define MX6UL_PAD_ENET2_TX_EN__ENET2_TX_EN 0x00f8 0x0384 0x0000 0 0
#define MX6UL_PAD_ENET2_TX_EN__UART8_DCE_RX 0x00f8 0x0384 0x065c 1 1
#define MX6UL_PAD_ENET2_TX_EN__UART8_DTE_TX 0x00f8 0x0384 0x0000 1 0
-#define MX6UL_PAD_ENET2_TX_EN__SIM2_PORT0_cLK 0x00f8 0x0384 0x0000 2 0
+#define MX6UL_PAD_ENET2_TX_EN__SIM2_PORT0_CLK 0x00f8 0x0384 0x0000 2 0
#define MX6UL_PAD_ENET2_TX_EN__ECSPI4_MOSI 0x00f8 0x0384 0x056c 3 0
#define MX6UL_PAD_ENET2_TX_EN__EIM_ACLK_FREERUN 0x00f8 0x0384 0x0000 4 0
#define MX6UL_PAD_ENET2_TX_EN__GPIO2_IO13 0x00f8 0x0384 0x0000 5 0
@@ -431,7 +438,7 @@
#define MX6UL_PAD_ENET2_RX_ER__UART8_DCE_RTS 0x0100 0x038c 0x0658 1 1
#define MX6UL_PAD_ENET2_RX_ER__UART8_DTE_CTS 0x0100 0x038c 0x0000 1 0
#define MX6UL_PAD_ENET2_RX_ER__SIM2_PORT0_SVEN 0x0100 0x038c 0x0000 2 0
-#define MX6UL_PAD_ENET2_RX_ER__ECSPI4_SS0 0x0100 0x038c 0x0000 3 0
+#define MX6UL_PAD_ENET2_RX_ER__ECSPI4_SS0 0x0100 0x038c 0x0570 3 0
#define MX6UL_PAD_ENET2_RX_ER__EIM_ADDR25 0x0100 0x038c 0x0000 4 0
#define MX6UL_PAD_ENET2_RX_ER__GPIO2_IO15 0x0100 0x038c 0x0000 5 0
#define MX6UL_PAD_ENET2_RX_ER__KPP_COL07 0x0100 0x038c 0x0000 6 0
@@ -440,7 +447,7 @@
#define MX6UL_PAD_LCD_CLK__LCDIF_WR_RWN 0x0104 0x0390 0x0000 1 0
#define MX6UL_PAD_LCD_CLK__UART4_DCE_TX 0x0104 0x0390 0x0000 2 0
#define MX6UL_PAD_LCD_CLK__UART4_DTE_RX 0x0104 0x0390 0x063c 2 2
-#define MX6UL_PAD_LCD_CLK__SAI3_MCLK 0x0104 0x0390 0x0000 3 0
+#define MX6UL_PAD_LCD_CLK__SAI3_MCLK 0x0104 0x0390 0x0600 3 0
#define MX6UL_PAD_LCD_CLK__EIM_CS2_B 0x0104 0x0390 0x0000 4 0
#define MX6UL_PAD_LCD_CLK__GPIO3_IO00 0x0104 0x0390 0x0000 5 0
#define MX6UL_PAD_LCD_CLK__WDOG1_WDOG_RST_B_DEB 0x0104 0x0390 0x0000 8 0
@@ -464,7 +471,7 @@
#define MX6UL_PAD_LCD_VSYNC__LCDIF_BUSY 0x0110 0x039c 0x05dc 1 1
#define MX6UL_PAD_LCD_VSYNC__UART4_DCE_RTS 0x0110 0x039c 0x0638 2 3
#define MX6UL_PAD_LCD_VSYNC__UART4_DTE_CTS 0x0110 0x039c 0x0000 2 0
-#define MX6UL_PAD_LCD_VSYNC__SAI3_RX_DATA 0x0110 0x039c 0x0000 3 0
+#define MX6UL_PAD_LCD_VSYNC__SAI3_RX_DATA 0x0110 0x039c 0x0604 3 0
#define MX6UL_PAD_LCD_VSYNC__WDOG2_WDOG_B 0x0110 0x039c 0x0000 4 0
#define MX6UL_PAD_LCD_VSYNC__GPIO3_IO03 0x0110 0x039c 0x0000 5 0
#define MX6UL_PAD_LCD_VSYNC__ECSPI2_SS2 0x0110 0x039c 0x0000 8 0
@@ -477,13 +484,15 @@
#define MX6UL_PAD_LCD_RESET__ECSPI2_SS3 0x0114 0x03a0 0x0000 8 0
#define MX6UL_PAD_LCD_DATA00__LCDIF_DATA00 0x0118 0x03a4 0x0000 0 0
#define MX6UL_PAD_LCD_DATA00__PWM1_OUT 0x0118 0x03a4 0x0000 1 0
+#define MX6UL_PAD_LCD_DATA00__CA7_MX6UL_TRACE0 0x0118 0x03a4 0x0000 2 0
#define MX6UL_PAD_LCD_DATA00__ENET1_1588_EVENT2_IN 0x0118 0x03a4 0x0000 3 0
#define MX6UL_PAD_LCD_DATA00__I2C3_SDA 0x0118 0x03a4 0x05b8 4 2
#define MX6UL_PAD_LCD_DATA00__GPIO3_IO05 0x0118 0x03a4 0x0000 5 0
#define MX6UL_PAD_LCD_DATA00__SRC_BT_CFG00 0x0118 0x03a4 0x0000 6 0
-#define MX6UL_PAD_LCD_DATA00__SAI1_MCLK 0x0118 0x03a4 0x0000 8 0
+#define MX6UL_PAD_LCD_DATA00__SAI1_MCLK 0x0118 0x03a4 0x05e0 8 1
#define MX6UL_PAD_LCD_DATA01__LCDIF_DATA01 0x011c 0x03a8 0x0000 0 0
#define MX6UL_PAD_LCD_DATA01__PWM2_OUT 0x011c 0x03a8 0x0000 1 0
+#define MX6UL_PAD_LCD_DATA01__CA7_MX6UL_TRACE1 0x011c 0x03a8 0x0000 2 0
#define MX6UL_PAD_LCD_DATA01__ENET1_1588_EVENT2_OUT 0x011c 0x03a8 0x0000 3 0
#define MX6UL_PAD_LCD_DATA01__I2C3_SCL 0x011c 0x03a8 0x05b4 4 2
#define MX6UL_PAD_LCD_DATA01__GPIO3_IO06 0x011c 0x03a8 0x0000 5 0
@@ -491,6 +500,7 @@
#define MX6UL_PAD_LCD_DATA01__SAI1_TX_SYNC 0x011c 0x03a8 0x05ec 8 0
#define MX6UL_PAD_LCD_DATA02__LCDIF_DATA02 0x0120 0x03ac 0x0000 0 0
#define MX6UL_PAD_LCD_DATA02__PWM3_OUT 0x0120 0x03ac 0x0000 1 0
+#define MX6UL_PAD_LCD_DATA02__CA7_MX6UL_TRACE2 0x0120 0x03ac 0x0000 2 0
#define MX6UL_PAD_LCD_DATA02__ENET1_1588_EVENT3_IN 0x0120 0x03ac 0x0000 3 0
#define MX6UL_PAD_LCD_DATA02__I2C4_SDA 0x0120 0x03ac 0x05c0 4 2
#define MX6UL_PAD_LCD_DATA02__GPIO3_IO07 0x0120 0x03ac 0x0000 5 0
@@ -498,14 +508,16 @@
#define MX6UL_PAD_LCD_DATA02__SAI1_TX_BCLK 0x0120 0x03ac 0x05e8 8 0
#define MX6UL_PAD_LCD_DATA03__LCDIF_DATA03 0x0124 0x03b0 0x0000 0 0
#define MX6UL_PAD_LCD_DATA03__PWM4_OUT 0x0124 0x03b0 0x0000 1 0
+#define MX6UL_PAD_LCD_DATA03__CA7_MX6UL_TRACE3 0x0124 0x03b0 0x0000 2 0
#define MX6UL_PAD_LCD_DATA03__ENET1_1588_EVENT3_OUT 0x0124 0x03b0 0x0000 3 0
#define MX6UL_PAD_LCD_DATA03__I2C4_SCL 0x0124 0x03b0 0x05bc 4 2
#define MX6UL_PAD_LCD_DATA03__GPIO3_IO08 0x0124 0x03b0 0x0000 5 0
#define MX6UL_PAD_LCD_DATA03__SRC_BT_CFG03 0x0124 0x03b0 0x0000 6 0
-#define MX6UL_PAD_LCD_DATA03__SAI1_RX_DATA 0x0124 0x03b0 0x0000 8 0
+#define MX6UL_PAD_LCD_DATA03__SAI1_RX_DATA 0x0124 0x03b0 0x05e4 8 0
#define MX6UL_PAD_LCD_DATA04__LCDIF_DATA04 0x0128 0x03b4 0x0000 0 0
#define MX6UL_PAD_LCD_DATA04__UART8_DCE_CTS 0x0128 0x03b4 0x0000 1 0
#define MX6UL_PAD_LCD_DATA04__UART8_DTE_RTS 0x0128 0x03b4 0x0658 1 2
+#define MX6UL_PAD_LCD_DATA04__CA7_MX6UL_TRACE4 0x0128 0x03b4 0x0000 2 0
#define MX6UL_PAD_LCD_DATA04__ENET2_1588_EVENT2_IN 0x0128 0x03b4 0x0000 3 0
#define MX6UL_PAD_LCD_DATA04__SPDIF_SR_CLK 0x0128 0x03b4 0x0000 4 0
#define MX6UL_PAD_LCD_DATA04__GPIO3_IO09 0x0128 0x03b4 0x0000 5 0
@@ -514,6 +526,7 @@
#define MX6UL_PAD_LCD_DATA05__LCDIF_DATA05 0x012c 0x03b8 0x0000 0 0
#define MX6UL_PAD_LCD_DATA05__UART8_DCE_RTS 0x012c 0x03b8 0x0658 1 3
#define MX6UL_PAD_LCD_DATA05__UART8_DTE_CTS 0x012c 0x03b8 0x0000 1 0
+#define MX6UL_PAD_LCD_DATA05__CA7_MX6UL_TRACE5 0x012c 0x03b8 0x0000 2 0
#define MX6UL_PAD_LCD_DATA05__ENET2_1588_EVENT2_OUT 0x012c 0x03b8 0x0000 3 0
#define MX6UL_PAD_LCD_DATA05__SPDIF_OUT 0x012c 0x03b8 0x0000 4 0
#define MX6UL_PAD_LCD_DATA05__GPIO3_IO10 0x012c 0x03b8 0x0000 5 0
@@ -522,6 +535,7 @@
#define MX6UL_PAD_LCD_DATA06__LCDIF_DATA06 0x0130 0x03bc 0x0000 0 0
#define MX6UL_PAD_LCD_DATA06__UART7_DCE_CTS 0x0130 0x03bc 0x0000 1 0
#define MX6UL_PAD_LCD_DATA06__UART7_DTE_RTS 0x0130 0x03bc 0x0650 1 2
+#define MX6UL_PAD_LCD_DATA06__CA7_MX6UL_TRACE6 0x0130 0x03bc 0x0000 2 0
#define MX6UL_PAD_LCD_DATA06__ENET2_1588_EVENT3_IN 0x0130 0x03bc 0x0000 3 0
#define MX6UL_PAD_LCD_DATA06__SPDIF_LOCK 0x0130 0x03bc 0x0000 4 0
#define MX6UL_PAD_LCD_DATA06__GPIO3_IO11 0x0130 0x03bc 0x0000 5 0
@@ -530,6 +544,7 @@
#define MX6UL_PAD_LCD_DATA07__LCDIF_DATA07 0x0134 0x03c0 0x0000 0 0
#define MX6UL_PAD_LCD_DATA07__UART7_DCE_RTS 0x0134 0x03c0 0x0650 1 3
#define MX6UL_PAD_LCD_DATA07__UART7_DTE_CTS 0x0134 0x03c0 0x0000 1 0
+#define MX6UL_PAD_LCD_DATA07__CA7_MX6UL_TRACE7 0x0134 0x03c0 0x0000 2 0
#define MX6UL_PAD_LCD_DATA07__ENET2_1588_EVENT3_OUT 0x0134 0x03c0 0x0000 3 0
#define MX6UL_PAD_LCD_DATA07__SPDIF_EXT_CLK 0x0134 0x03c0 0x061c 4 0
#define MX6UL_PAD_LCD_DATA07__GPIO3_IO12 0x0134 0x03c0 0x0000 5 0
@@ -537,56 +552,64 @@
#define MX6UL_PAD_LCD_DATA07__ECSPI1_SS3 0x0134 0x03c0 0x0000 8 0
#define MX6UL_PAD_LCD_DATA08__LCDIF_DATA08 0x0138 0x03c4 0x0000 0 0
#define MX6UL_PAD_LCD_DATA08__SPDIF_IN 0x0138 0x03c4 0x0618 1 2
-#define MX6UL_PAD_LCD_DATA08__CSI_DATA16 0x0138 0x03c4 0x0000 3 0
+#define MX6UL_PAD_LCD_DATA08__CA7_MX6UL_TRACE8 0x0138 0x03c4 0x0000 2 0
+#define MX6UL_PAD_LCD_DATA08__CSI_DATA16 0x0138 0x03c4 0x0504 3 1
#define MX6UL_PAD_LCD_DATA08__EIM_DATA00 0x0138 0x03c4 0x0000 4 0
#define MX6UL_PAD_LCD_DATA08__GPIO3_IO13 0x0138 0x03c4 0x0000 5 0
#define MX6UL_PAD_LCD_DATA08__SRC_BT_CFG08 0x0138 0x03c4 0x0000 6 0
#define MX6UL_PAD_LCD_DATA08__FLEXCAN1_TX 0x0138 0x03c4 0x0000 8 0
#define MX6UL_PAD_LCD_DATA09__LCDIF_DATA09 0x013c 0x03c8 0x0000 0 0
-#define MX6UL_PAD_LCD_DATA09__SAI3_MCLK 0x013c 0x03c8 0x0000 1 0
-#define MX6UL_PAD_LCD_DATA09__CSI_DATA17 0x013c 0x03c8 0x0000 3 0
+#define MX6UL_PAD_LCD_DATA09__SAI3_MCLK 0x013c 0x03c8 0x0600 1 1
+#define MX6UL_PAD_LCD_DATA09__CA7_MX6UL_TRACE9 0x013c 0x03c8 0x0000 2 0
+#define MX6UL_PAD_LCD_DATA09__CSI_DATA17 0x013c 0x03c8 0x0508 3 1
#define MX6UL_PAD_LCD_DATA09__EIM_DATA01 0x013c 0x03c8 0x0000 4 0
#define MX6UL_PAD_LCD_DATA09__GPIO3_IO14 0x013c 0x03c8 0x0000 5 0
#define MX6UL_PAD_LCD_DATA09__SRC_BT_CFG09 0x013c 0x03c8 0x0000 6 0
#define MX6UL_PAD_LCD_DATA09__FLEXCAN1_RX 0x013c 0x03c8 0x0584 8 2
#define MX6UL_PAD_LCD_DATA10__LCDIF_DATA10 0x0140 0x03cc 0x0000 0 0
#define MX6UL_PAD_LCD_DATA10__SAI3_RX_SYNC 0x0140 0x03cc 0x0000 1 0
-#define MX6UL_PAD_LCD_DATA10__CSI_DATA18 0x0140 0x03cc 0x0000 3 0
+#define MX6UL_PAD_LCD_DATA10__CA7_MX6UL_TRACE10 0x0140 0x03cc 0x0000 2 0
+#define MX6UL_PAD_LCD_DATA10__CSI_DATA18 0x0140 0x03cc 0x050c 3 1
#define MX6UL_PAD_LCD_DATA10__EIM_DATA02 0x0140 0x03cc 0x0000 4 0
#define MX6UL_PAD_LCD_DATA10__GPIO3_IO15 0x0140 0x03cc 0x0000 5 0
#define MX6UL_PAD_LCD_DATA10__SRC_BT_CFG10 0x0140 0x03cc 0x0000 6 0
#define MX6UL_PAD_LCD_DATA10__FLEXCAN2_TX 0x0140 0x03cc 0x0000 8 0
#define MX6UL_PAD_LCD_DATA11__LCDIF_DATA11 0x0144 0x03d0 0x0000 0 0
#define MX6UL_PAD_LCD_DATA11__SAI3_RX_BCLK 0x0144 0x03d0 0x0000 1 0
-#define MX6UL_PAD_LCD_DATA11__CSI_DATA19 0x0144 0x03d0 0x0000 3 0
+#define MX6UL_PAD_LCD_DATA11__CA7_MX6UL_TRACE11 0x0144 0x03d0 0x0000 2 0
+#define MX6UL_PAD_LCD_DATA11__CSI_DATA19 0x0144 0x03d0 0x0510 3 1
#define MX6UL_PAD_LCD_DATA11__EIM_DATA03 0x0144 0x03d0 0x0000 4 0
#define MX6UL_PAD_LCD_DATA11__GPIO3_IO16 0x0144 0x03d0 0x0000 5 0
#define MX6UL_PAD_LCD_DATA11__SRC_BT_CFG11 0x0144 0x03d0 0x0000 6 0
#define MX6UL_PAD_LCD_DATA11__FLEXCAN2_RX 0x0144 0x03d0 0x0588 8 2
#define MX6UL_PAD_LCD_DATA12__LCDIF_DATA12 0x0148 0x03d4 0x0000 0 0
#define MX6UL_PAD_LCD_DATA12__SAI3_TX_SYNC 0x0148 0x03d4 0x060c 1 1
-#define MX6UL_PAD_LCD_DATA12__CSI_DATA20 0x0148 0x03d4 0x0000 3 0
+#define MX6UL_PAD_LCD_DATA12__CA7_MX6UL_TRACE12 0x0148 0x03d4 0x0000 2 0
+#define MX6UL_PAD_LCD_DATA12__CSI_DATA20 0x0148 0x03d4 0x0514 3 1
#define MX6UL_PAD_LCD_DATA12__EIM_DATA04 0x0148 0x03d4 0x0000 4 0
#define MX6UL_PAD_LCD_DATA12__GPIO3_IO17 0x0148 0x03d4 0x0000 5 0
#define MX6UL_PAD_LCD_DATA12__SRC_BT_CFG12 0x0148 0x03d4 0x0000 6 0
#define MX6UL_PAD_LCD_DATA12__ECSPI1_RDY 0x0148 0x03d4 0x0000 8 0
#define MX6UL_PAD_LCD_DATA13__LCDIF_DATA13 0x014c 0x03d8 0x0000 0 0
#define MX6UL_PAD_LCD_DATA13__SAI3_TX_BCLK 0x014c 0x03d8 0x0608 1 1
-#define MX6UL_PAD_LCD_DATA13__CSI_DATA21 0x014c 0x03d8 0x0000 3 0
+#define MX6UL_PAD_LCD_DATA13__CA7_MX6UL_TRACE13 0x014c 0x03d8 0x0000 2 0
+#define MX6UL_PAD_LCD_DATA13__CSI_DATA21 0x014c 0x03d8 0x0518 3 1
#define MX6UL_PAD_LCD_DATA13__EIM_DATA05 0x014c 0x03d8 0x0000 4 0
#define MX6UL_PAD_LCD_DATA13__GPIO3_IO18 0x014c 0x03d8 0x0000 5 0
#define MX6UL_PAD_LCD_DATA13__SRC_BT_CFG13 0x014c 0x03d8 0x0000 6 0
#define MX6UL_PAD_LCD_DATA13__USDHC2_RESET_B 0x014c 0x03d8 0x0000 8 0
#define MX6UL_PAD_LCD_DATA14__LCDIF_DATA14 0x0150 0x03dc 0x0000 0 0
-#define MX6UL_PAD_LCD_DATA14__SAI3_RX_DATA 0x0150 0x03dc 0x0000 1 0
-#define MX6UL_PAD_LCD_DATA14__CSI_DATA22 0x0150 0x03dc 0x0000 3 0
+#define MX6UL_PAD_LCD_DATA14__SAI3_RX_DATA 0x0150 0x03dc 0x0604 1 1
+#define MX6UL_PAD_LCD_DATA14__CA7_MX6UL_TRACE14 0x0150 0x03dc 0x0000 2 0
+#define MX6UL_PAD_LCD_DATA14__CSI_DATA22 0x0150 0x03dc 0x051c 3 1
#define MX6UL_PAD_LCD_DATA14__EIM_DATA06 0x0150 0x03dc 0x0000 4 0
#define MX6UL_PAD_LCD_DATA14__GPIO3_IO19 0x0150 0x03dc 0x0000 5 0
#define MX6UL_PAD_LCD_DATA14__SRC_BT_CFG14 0x0150 0x03dc 0x0000 6 0
#define MX6UL_PAD_LCD_DATA14__USDHC2_DATA4 0x0150 0x03dc 0x068c 8 0
#define MX6UL_PAD_LCD_DATA15__LCDIF_DATA15 0x0154 0x03e0 0x0000 0 0
#define MX6UL_PAD_LCD_DATA15__SAI3_TX_DATA 0x0154 0x03e0 0x0000 1 0
-#define MX6UL_PAD_LCD_DATA15__CSI_DATA23 0x0154 0x03e0 0x0000 3 0
+#define MX6UL_PAD_LCD_DATA15__CA7_MX6UL_TRACE15 0x0154 0x03e0 0x0000 2 0
+#define MX6UL_PAD_LCD_DATA15__CSI_DATA23 0x0154 0x03e0 0x0520 3 1
#define MX6UL_PAD_LCD_DATA15__EIM_DATA07 0x0154 0x03e0 0x0000 4 0
#define MX6UL_PAD_LCD_DATA15__GPIO3_IO20 0x0154 0x03e0 0x0000 5 0
#define MX6UL_PAD_LCD_DATA15__SRC_BT_CFG15 0x0154 0x03e0 0x0000 6 0
@@ -594,7 +617,8 @@
#define MX6UL_PAD_LCD_DATA16__LCDIF_DATA16 0x0158 0x03e4 0x0000 0 0
#define MX6UL_PAD_LCD_DATA16__UART7_DCE_TX 0x0158 0x03e4 0x0000 1 0
#define MX6UL_PAD_LCD_DATA16__UART7_DTE_RX 0x0158 0x03e4 0x0654 1 2
-#define MX6UL_PAD_LCD_DATA16__CSI_DATA01 0x0158 0x03e4 0x0000 3 0
+#define MX6UL_PAD_LCD_DATA16__CA7_MX6UL_TRACE_CLK 0x0158 0x03e4 0x0000 2 0
+#define MX6UL_PAD_LCD_DATA16__CSI_DATA01 0x0158 0x03e4 0x04d4 3 1
#define MX6UL_PAD_LCD_DATA16__EIM_DATA08 0x0158 0x03e4 0x0000 4 0
#define MX6UL_PAD_LCD_DATA16__GPIO3_IO21 0x0158 0x03e4 0x0000 5 0
#define MX6UL_PAD_LCD_DATA16__SRC_BT_CFG24 0x0158 0x03e4 0x0000 6 0
@@ -602,7 +626,8 @@
#define MX6UL_PAD_LCD_DATA17__LCDIF_DATA17 0x015c 0x03e8 0x0000 0 0
#define MX6UL_PAD_LCD_DATA17__UART7_DCE_RX 0x015c 0x03e8 0x0654 1 3
#define MX6UL_PAD_LCD_DATA17__UART7_DTE_TX 0x015c 0x03e8 0x0000 1 0
-#define MX6UL_PAD_LCD_DATA17__CSI_DATA00 0x015c 0x03e8 0x0000 3 0
+#define MX6UL_PAD_LCD_DATA17__CA7_MX6UL_TRACE_CTL 0x015c 0x03e8 0x0000 2 0
+#define MX6UL_PAD_LCD_DATA17__CSI_DATA00 0x015c 0x03e8 0x04d0 3 1
#define MX6UL_PAD_LCD_DATA17__EIM_DATA09 0x015c 0x03e8 0x0000 4 0
#define MX6UL_PAD_LCD_DATA17__GPIO3_IO22 0x015c 0x03e8 0x0000 5 0
#define MX6UL_PAD_LCD_DATA17__SRC_BT_CFG25 0x015c 0x03e8 0x0000 6 0
@@ -610,7 +635,7 @@
#define MX6UL_PAD_LCD_DATA18__LCDIF_DATA18 0x0160 0x03ec 0x0000 0 0
#define MX6UL_PAD_LCD_DATA18__PWM5_OUT 0x0160 0x03ec 0x0000 1 0
#define MX6UL_PAD_LCD_DATA18__CA7_MX6UL_EVENTO 0x0160 0x03ec 0x0000 2 0
-#define MX6UL_PAD_LCD_DATA18__CSI_DATA10 0x0160 0x03ec 0x0000 3 0
+#define MX6UL_PAD_LCD_DATA18__CSI_DATA10 0x0160 0x03ec 0x04ec 3 1
#define MX6UL_PAD_LCD_DATA18__EIM_DATA10 0x0160 0x03ec 0x0000 4 0
#define MX6UL_PAD_LCD_DATA18__GPIO3_IO23 0x0160 0x03ec 0x0000 5 0
#define MX6UL_PAD_LCD_DATA18__SRC_BT_CFG26 0x0160 0x03ec 0x0000 6 0
@@ -622,7 +647,7 @@
#define MX6UL_PAD_LCD_DATA19__LCDIF_DATA19 0x0164 0x03f0 0x0000 0 0
#define MX6UL_PAD_LCD_DATA19__PWM6_OUT 0x0164 0x03f0 0x0000 1 0
#define MX6UL_PAD_LCD_DATA19__WDOG1_WDOG_ANY 0x0164 0x03f0 0x0000 2 0
-#define MX6UL_PAD_LCD_DATA19__CSI_DATA11 0x0164 0x03f0 0x0000 3 0
+#define MX6UL_PAD_LCD_DATA19__CSI_DATA11 0x0164 0x03f0 0x04f0 3 1
#define MX6UL_PAD_LCD_DATA20__EIM_DATA12 0x0168 0x03f4 0x0000 4 0
#define MX6UL_PAD_LCD_DATA20__GPIO3_IO25 0x0168 0x03f4 0x0000 5 0
#define MX6UL_PAD_LCD_DATA20__SRC_BT_CFG28 0x0168 0x03f4 0x0000 6 0
@@ -631,12 +656,12 @@
#define MX6UL_PAD_LCD_DATA20__UART8_DCE_TX 0x0168 0x03f4 0x0000 1 0
#define MX6UL_PAD_LCD_DATA20__UART8_DTE_RX 0x0168 0x03f4 0x065c 1 2
#define MX6UL_PAD_LCD_DATA20__ECSPI1_SCLK 0x0168 0x03f4 0x0534 2 0
-#define MX6UL_PAD_LCD_DATA20__CSI_DATA12 0x0168 0x03f4 0x0000 3 0
+#define MX6UL_PAD_LCD_DATA20__CSI_DATA12 0x0168 0x03f4 0x04f4 3 1
#define MX6UL_PAD_LCD_DATA21__LCDIF_DATA21 0x016c 0x03f8 0x0000 0 0
#define MX6UL_PAD_LCD_DATA21__UART8_DCE_RX 0x016c 0x03f8 0x065c 1 3
#define MX6UL_PAD_LCD_DATA21__UART8_DTE_TX 0x016c 0x03f8 0x0000 1 0
-#define MX6UL_PAD_LCD_DATA21__ECSPI1_SS0 0x016c 0x03f8 0x0000 2 0
-#define MX6UL_PAD_LCD_DATA21__CSI_DATA13 0x016c 0x03f8 0x0000 3 0
+#define MX6UL_PAD_LCD_DATA21__ECSPI1_SS0 0x016c 0x03f8 0x0540 2 0
+#define MX6UL_PAD_LCD_DATA21__CSI_DATA13 0x016c 0x03f8 0x04f8 3 1
#define MX6UL_PAD_LCD_DATA21__EIM_DATA13 0x016c 0x03f8 0x0000 4 0
#define MX6UL_PAD_LCD_DATA21__GPIO3_IO26 0x016c 0x03f8 0x0000 5 0
#define MX6UL_PAD_LCD_DATA21__SRC_BT_CFG29 0x016c 0x03f8 0x0000 6 0
@@ -644,7 +669,7 @@
#define MX6UL_PAD_LCD_DATA22__LCDIF_DATA22 0x0170 0x03fc 0x0000 0 0
#define MX6UL_PAD_LCD_DATA22__MQS_RIGHT 0x0170 0x03fc 0x0000 1 0
#define MX6UL_PAD_LCD_DATA22__ECSPI1_MOSI 0x0170 0x03fc 0x053c 2 0
-#define MX6UL_PAD_LCD_DATA22__CSI_DATA14 0x0170 0x03fc 0x0000 3 0
+#define MX6UL_PAD_LCD_DATA22__CSI_DATA14 0x0170 0x03fc 0x04fc 3 1
#define MX6UL_PAD_LCD_DATA22__EIM_DATA14 0x0170 0x03fc 0x0000 4 0
#define MX6UL_PAD_LCD_DATA22__GPIO3_IO27 0x0170 0x03fc 0x0000 5 0
#define MX6UL_PAD_LCD_DATA22__SRC_BT_CFG30 0x0170 0x03fc 0x0000 6 0
@@ -652,7 +677,7 @@
#define MX6UL_PAD_LCD_DATA23__LCDIF_DATA23 0x0174 0x0400 0x0000 0 0
#define MX6UL_PAD_LCD_DATA23__MQS_LEFT 0x0174 0x0400 0x0000 1 0
#define MX6UL_PAD_LCD_DATA23__ECSPI1_MISO 0x0174 0x0400 0x0538 2 0
-#define MX6UL_PAD_LCD_DATA23__CSI_DATA15 0x0174 0x0400 0x0000 3 0
+#define MX6UL_PAD_LCD_DATA23__CSI_DATA15 0x0174 0x0400 0x0500 3 1
#define MX6UL_PAD_LCD_DATA23__EIM_DATA15 0x0174 0x0400 0x0000 4 0
#define MX6UL_PAD_LCD_DATA23__GPIO3_IO28 0x0174 0x0400 0x0000 5 0
#define MX6UL_PAD_LCD_DATA23__SRC_BT_CFG31 0x0174 0x0400 0x0000 6 0
@@ -660,42 +685,42 @@
#define MX6UL_PAD_NAND_RE_B__RAWNAND_RE_B 0x0178 0x0404 0x0000 0 0
#define MX6UL_PAD_NAND_RE_B__USDHC2_CLK 0x0178 0x0404 0x0670 1 2
#define MX6UL_PAD_NAND_RE_B__QSPI_B_SCLK 0x0178 0x0404 0x0000 2 0
-#define MX6UL_PAD_NAND_RE_B__KPP_ROW00 0x0178 0x0404 0x0000 3 0
+#define MX6UL_PAD_NAND_RE_B__KPP_ROW00 0x0178 0x0404 0x05d0 3 1
#define MX6UL_PAD_NAND_RE_B__EIM_EB_B00 0x0178 0x0404 0x0000 4 0
#define MX6UL_PAD_NAND_RE_B__GPIO4_IO00 0x0178 0x0404 0x0000 5 0
#define MX6UL_PAD_NAND_RE_B__ECSPI3_SS2 0x0178 0x0404 0x0000 8 0
#define MX6UL_PAD_NAND_WE_B__RAWNAND_WE_B 0x017c 0x0408 0x0000 0 0
#define MX6UL_PAD_NAND_WE_B__USDHC2_CMD 0x017c 0x0408 0x0678 1 2
#define MX6UL_PAD_NAND_WE_B__QSPI_B_SS0_B 0x017c 0x0408 0x0000 2 0
-#define MX6UL_PAD_NAND_WE_B__KPP_COL00 0x017c 0x0408 0x0000 3 0
+#define MX6UL_PAD_NAND_WE_B__KPP_COL00 0x017c 0x0408 0x05c4 3 1
#define MX6UL_PAD_NAND_WE_B__EIM_EB_B01 0x017c 0x0408 0x0000 4 0
#define MX6UL_PAD_NAND_WE_B__GPIO4_IO01 0x017c 0x0408 0x0000 5 0
#define MX6UL_PAD_NAND_WE_B__ECSPI3_SS3 0x017c 0x0408 0x0000 8 0
#define MX6UL_PAD_NAND_DATA00__RAWNAND_DATA00 0x0180 0x040c 0x0000 0 0
#define MX6UL_PAD_NAND_DATA00__USDHC2_DATA0 0x0180 0x040c 0x067c 1 2
#define MX6UL_PAD_NAND_DATA00__QSPI_B_SS1_B 0x0180 0x040c 0x0000 2 0
-#define MX6UL_PAD_NAND_DATA00__KPP_ROW01 0x0180 0x040c 0x0000 3 0
+#define MX6UL_PAD_NAND_DATA00__KPP_ROW01 0x0180 0x040c 0x05d4 3 1
#define MX6UL_PAD_NAND_DATA00__EIM_AD08 0x0180 0x040c 0x0000 4 0
#define MX6UL_PAD_NAND_DATA00__GPIO4_IO02 0x0180 0x040c 0x0000 5 0
#define MX6UL_PAD_NAND_DATA00__ECSPI4_RDY 0x0180 0x040c 0x0000 8 0
#define MX6UL_PAD_NAND_DATA01__RAWNAND_DATA01 0x0184 0x0410 0x0000 0 0
#define MX6UL_PAD_NAND_DATA01__USDHC2_DATA1 0x0184 0x0410 0x0680 1 2
#define MX6UL_PAD_NAND_DATA01__QSPI_B_DQS 0x0184 0x0410 0x0000 2 0
-#define MX6UL_PAD_NAND_DATA01__KPP_COL01 0x0184 0x0410 0x0000 3 0
+#define MX6UL_PAD_NAND_DATA01__KPP_COL01 0x0184 0x0410 0x05c8 3 1
#define MX6UL_PAD_NAND_DATA01__EIM_AD09 0x0184 0x0410 0x0000 4 0
#define MX6UL_PAD_NAND_DATA01__GPIO4_IO03 0x0184 0x0410 0x0000 5 0
#define MX6UL_PAD_NAND_DATA01__ECSPI4_SS1 0x0184 0x0410 0x0000 8 0
#define MX6UL_PAD_NAND_DATA02__RAWNAND_DATA02 0x0188 0x0414 0x0000 0 0
#define MX6UL_PAD_NAND_DATA02__USDHC2_DATA2 0x0188 0x0414 0x0684 1 1
#define MX6UL_PAD_NAND_DATA02__QSPI_B_DATA00 0x0188 0x0414 0x0000 2 0
-#define MX6UL_PAD_NAND_DATA02__KPP_ROW02 0x0188 0x0414 0x0000 3 0
+#define MX6UL_PAD_NAND_DATA02__KPP_ROW02 0x0188 0x0414 0x05d8 3 1
#define MX6UL_PAD_NAND_DATA02__EIM_AD10 0x0188 0x0414 0x0000 4 0
#define MX6UL_PAD_NAND_DATA02__GPIO4_IO04 0x0188 0x0414 0x0000 5 0
#define MX6UL_PAD_NAND_DATA02__ECSPI4_SS2 0x0188 0x0414 0x0000 8 0
#define MX6UL_PAD_NAND_DATA03__RAWNAND_DATA03 0x018c 0x0418 0x0000 0 0
#define MX6UL_PAD_NAND_DATA03__USDHC2_DATA3 0x018c 0x0418 0x0688 1 2
#define MX6UL_PAD_NAND_DATA03__QSPI_B_DATA01 0x018c 0x0418 0x0000 2 0
-#define MX6UL_PAD_NAND_DATA03__KPP_COL02 0x018c 0x0418 0x0000 3 0
+#define MX6UL_PAD_NAND_DATA03__KPP_COL02 0x018c 0x0418 0x05cc 3 1
#define MX6UL_PAD_NAND_DATA03__EIM_AD11 0x018c 0x0418 0x0000 4 0
#define MX6UL_PAD_NAND_DATA03__GPIO4_IO05 0x018c 0x0418 0x0000 5 0
#define MX6UL_PAD_NAND_DATA03__ECSPI4_SS3 0x018c 0x0418 0x0000 8 0
@@ -726,7 +751,7 @@
#define MX6UL_PAD_NAND_DATA07__RAWNAND_DATA07 0x019c 0x0428 0x0000 0 0
#define MX6UL_PAD_NAND_DATA07__USDHC2_DATA7 0x019c 0x0428 0x0698 1 1
#define MX6UL_PAD_NAND_DATA07__QSPI_A_SS1_B 0x019c 0x0428 0x0000 2 0
-#define MX6UL_PAD_NAND_DATA07__ECSPI4_SS0 0x019c 0x0428 0x0000 3 0
+#define MX6UL_PAD_NAND_DATA07__ECSPI4_SS0 0x019c 0x0428 0x0570 3 1
#define MX6UL_PAD_NAND_DATA07__EIM_AD15 0x019c 0x0428 0x0000 4 0
#define MX6UL_PAD_NAND_DATA07__GPIO4_IO09 0x019c 0x0428 0x0000 5 0
#define MX6UL_PAD_NAND_DATA07__UART2_DCE_RTS 0x019c 0x0428 0x0628 8 5
@@ -748,7 +773,7 @@
#define MX6UL_PAD_NAND_READY_B__RAWNAND_READY_B 0x01a8 0x0434 0x0000 0 0
#define MX6UL_PAD_NAND_READY_B__USDHC1_DATA4 0x01a8 0x0434 0x0000 1 0
#define MX6UL_PAD_NAND_READY_B__QSPI_A_DATA00 0x01a8 0x0434 0x0000 2 0
-#define MX6UL_PAD_NAND_READY_B__ECSPI3_SS0 0x01a8 0x0434 0x0000 3 0
+#define MX6UL_PAD_NAND_READY_B__ECSPI3_SS0 0x01a8 0x0434 0x0560 3 1
#define MX6UL_PAD_NAND_READY_B__EIM_CS1_B 0x01a8 0x0434 0x0000 4 0
#define MX6UL_PAD_NAND_READY_B__GPIO4_IO12 0x01a8 0x0434 0x0000 5 0
#define MX6UL_PAD_NAND_READY_B__UART3_DCE_TX 0x01a8 0x0434 0x0000 8 0
@@ -783,7 +808,7 @@
#define MX6UL_PAD_NAND_DQS__PWM5_OUT 0x01b8 0x0444 0x0000 3 0
#define MX6UL_PAD_NAND_DQS__EIM_WAIT 0x01b8 0x0444 0x0000 4 0
#define MX6UL_PAD_NAND_DQS__GPIO4_IO16 0x01b8 0x0444 0x0000 5 0
-#define MX6UL_PAD_NAND_DQS__SDMA_EXT_EVENT01 0x01b8 0x0444 0x0000 6 0
+#define MX6UL_PAD_NAND_DQS__SDMA_EXT_EVENT01 0x01b8 0x0444 0x0614 6 1
#define MX6UL_PAD_NAND_DQS__SPDIF_EXT_CLK 0x01b8 0x0444 0x061c 8 1
#define MX6UL_PAD_SD1_CMD__USDHC1_CMD 0x01bc 0x0448 0x0000 0 0
#define MX6UL_PAD_SD1_CMD__GPT2_COMPARE1 0x01bc 0x0448 0x0000 1 0
@@ -791,11 +816,11 @@
#define MX6UL_PAD_SD1_CMD__SPDIF_OUT 0x01bc 0x0448 0x0000 3 0
#define MX6UL_PAD_SD1_CMD__EIM_ADDR19 0x01bc 0x0448 0x0000 4 0
#define MX6UL_PAD_SD1_CMD__GPIO2_IO16 0x01bc 0x0448 0x0000 5 0
-#define MX6UL_PAD_SD1_CMD__SDMA_EXT_EVENT00 0x01bc 0x0448 0x0000 6 0
+#define MX6UL_PAD_SD1_CMD__SDMA_EXT_EVENT00 0x01bc 0x0448 0x0610 6 2
#define MX6UL_PAD_SD1_CMD__USB_OTG1_PWR 0x01bc 0x0448 0x0000 8 0
#define MX6UL_PAD_SD1_CLK__USDHC1_CLK 0x01c0 0x044c 0x0000 0 0
#define MX6UL_PAD_SD1_CLK__GPT2_COMPARE2 0x01c0 0x044c 0x0000 1 0
-#define MX6UL_PAD_SD1_CLK__SAI2_MCLK 0x01c0 0x044c 0x0000 2 0
+#define MX6UL_PAD_SD1_CLK__SAI2_MCLK 0x01c0 0x044c 0x05f0 2 1
#define MX6UL_PAD_SD1_CLK__SPDIF_IN 0x01c0 0x044c 0x0618 3 3
#define MX6UL_PAD_SD1_CLK__EIM_ADDR20 0x01c0 0x044c 0x0000 4 0
#define MX6UL_PAD_SD1_CLK__GPIO2_IO17 0x01c0 0x044c 0x0000 5 0
@@ -878,10 +903,10 @@
#define MX6UL_PAD_CSI_DATA01__CSI_DATA03 0x01e8 0x0474 0x04c8 0 0
#define MX6UL_PAD_CSI_DATA01__USDHC2_DATA1 0x01e8 0x0474 0x0680 1 0
#define MX6UL_PAD_CSI_DATA01__SIM1_PORT1_SVEN 0x01e8 0x0474 0x0000 2 0
-#define MX6UL_PAD_CSI_DATA01__ECSPI2_SS0 0x01e8 0x0474 0x0000 3 0
+#define MX6UL_PAD_CSI_DATA01__ECSPI2_SS0 0x01e8 0x0474 0x0550 3 0
#define MX6UL_PAD_CSI_DATA01__EIM_AD01 0x01e8 0x0474 0x0000 4 0
#define MX6UL_PAD_CSI_DATA01__GPIO4_IO22 0x01e8 0x0474 0x0000 5 0
-#define MX6UL_PAD_CSI_DATA01__SAI1_MCLK 0x01e8 0x0474 0x0000 6 0
+#define MX6UL_PAD_CSI_DATA01__SAI1_MCLK 0x01e8 0x0474 0x05e0 6 0
#define MX6UL_PAD_CSI_DATA01__UART5_DCE_RX 0x01e8 0x0474 0x0644 8 1
#define MX6UL_PAD_CSI_DATA01__UART5_DTE_TX 0x01e8 0x0474 0x0000 8 0
#define MX6UL_PAD_CSI_DATA02__CSI_DATA04 0x01ec 0x0478 0x04d8 0 1
@@ -913,7 +938,7 @@
#define MX6UL_PAD_CSI_DATA05__CSI_DATA07 0x01f8 0x0484 0x04e0 0 1
#define MX6UL_PAD_CSI_DATA05__USDHC2_DATA5 0x01f8 0x0484 0x0690 1 2
#define MX6UL_PAD_CSI_DATA05__SIM2_PORT1_RST_B 0x01f8 0x0484 0x0000 2 0
-#define MX6UL_PAD_CSI_DATA05__ECSPI1_SS0 0x01f8 0x0484 0x0000 3 0
+#define MX6UL_PAD_CSI_DATA05__ECSPI1_SS0 0x01f8 0x0484 0x0540 3 1
#define MX6UL_PAD_CSI_DATA05__EIM_AD05 0x01f8 0x0484 0x0000 4 0
#define MX6UL_PAD_CSI_DATA05__GPIO4_IO26 0x01f8 0x0484 0x0000 5 0
#define MX6UL_PAD_CSI_DATA05__SAI1_TX_BCLK 0x01f8 0x0484 0x05e8 6 1
@@ -924,7 +949,7 @@
#define MX6UL_PAD_CSI_DATA06__ECSPI1_MOSI 0x01fc 0x0488 0x053c 3 1
#define MX6UL_PAD_CSI_DATA06__EIM_AD06 0x01fc 0x0488 0x0000 4 0
#define MX6UL_PAD_CSI_DATA06__GPIO4_IO27 0x01fc 0x0488 0x0000 5 0
-#define MX6UL_PAD_CSI_DATA06__SAI1_RX_DATA 0x01fc 0x0488 0x0000 6 0
+#define MX6UL_PAD_CSI_DATA06__SAI1_RX_DATA 0x01fc 0x0488 0x05e4 6 1
#define MX6UL_PAD_CSI_DATA06__USDHC1_RESET_B 0x01fc 0x0488 0x0000 8 0
#define MX6UL_PAD_CSI_DATA07__CSI_DATA09 0x0200 0x048c 0x04e8 0 1
#define MX6UL_PAD_CSI_DATA07__USDHC2_DATA7 0x0200 0x048c 0x0698 1 2
diff --git a/arch/arm/boot/dts/imx6ul.dtsi b/arch/arm/boot/dts/imx6ul.dtsi
index 49f4bdc0d864..5a9ad916f952 100644
--- a/arch/arm/boot/dts/imx6ul.dtsi
+++ b/arch/arm/boot/dts/imx6ul.dtsi
@@ -1,5 +1,6 @@
/*
- * Copyright 2015 Freescale Semiconductor, Inc.
+ * Copyright 2015-2016 Freescale Semiconductor, Inc.
+ * Copyright 2017-2018 NXP
*
* 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
@@ -68,12 +69,14 @@
clock-latency = <61036>; /* two CLK32 periods */
operating-points = <
/* kHz uV */
+ 696000 1275000
528000 1175000
396000 1025000
198000 950000
>;
fsl,soc-operating-points = <
/* KHz uV */
+ 696000 1275000
528000 1175000
396000 1175000
198000 1175000
@@ -143,15 +146,49 @@
interrupt-parent = <&gpc>;
ranges;
+ busfreq {
+ compatible = "fsl,imx_busfreq";
+ clocks = <&clks IMX6UL_CLK_PLL2_PFD2>, <&clks IMX6UL_CLK_PLL2_198M>,
+ <&clks IMX6UL_CLK_PLL2_BUS>, <&clks IMX6UL_CLK_ARM>,
+ <&clks IMX6UL_CLK_PLL3_USB_OTG>, <&clks IMX6UL_CLK_PERIPH>,
+ <&clks IMX6UL_CLK_PERIPH_PRE>, <&clks IMX6UL_CLK_PERIPH_CLK2>,
+ <&clks IMX6UL_CLK_PERIPH_CLK2_SEL>, <&clks IMX6UL_CLK_OSC>,
+ <&clks IMX6UL_CLK_AHB>, <&clks IMX6UL_CLK_AXI>,
+ <&clks IMX6UL_CLK_PERIPH2>, <&clks IMX6UL_CLK_PERIPH2_PRE>,
+ <&clks IMX6UL_CLK_PERIPH2_CLK2>, <&clks IMX6UL_CLK_PERIPH2_CLK2_SEL>,
+ <&clks IMX6UL_CLK_STEP>, <&clks IMX6UL_CLK_MMDC_P0_FAST>;
+ clock-names = "pll2_pfd2_396m", "pll2_198m", "pll2_bus", "arm", "pll3_usb_otg",
+ "periph", "periph_pre", "periph_clk2", "periph_clk2_sel", "osc",
+ "ahb", "ocram", "periph2", "periph2_pre", "periph2_clk2", "periph2_clk2_sel",
+ "step", "mmdc";
+ fsl,max_ddr_freq = <400000000>;
+ };
+
pmu {
compatible = "arm,cortex-a7-pmu";
interrupts = <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH>;
status = "disabled";
};
- ocram: sram@00900000 {
+ ocrams: sram@00900000 {
+ compatible = "fsl,lpm-sram";
+ reg = <0x00900000 0x4000>;
+ };
+
+ ocrams_ddr: sram@00904000 {
+ compatible = "fsl,ddr-lpm-sram";
+ reg = <0x00904000 0x1000>;
+ };
+
+ ocram: sram@00905000 {
compatible = "mmio-sram";
- reg = <0x00900000 0x20000>;
+ reg = <0x00905000 0x1B000>;
+ };
+
+ ocram_optee: sram@00918000 {
+ compatible = "fsl,optee-lpm-sram";
+ reg = <0x00918000 0x8000>;
+ overw_reg = <&ocram 0x00905000 0x13000>;
};
dma_apbh: dma-apbh@01804000 {
@@ -167,6 +204,21 @@
clocks = <&clks IMX6UL_CLK_APBHDMA>;
};
+ caam_sm: caam-sm@00100000 {
+ compatible = "fsl,imx7d-caam-sm", "fsl,imx6q-caam-sm";
+ reg = <0x00100000 0x8000>;
+ };
+
+ irq_sec_vio: caam_secvio {
+ compatible = "fsl,imx7d-caam-secvio", "fsl,imx6q-caam-secvio";
+ interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
+ jtag-tamper = "disabled";
+ watchdog-tamper = "enabled";
+ internal-boot-tamper = "enabled";
+ external-pin-tamper = "disabled";
+ };
+
+
gpmi: gpmi-nand@01806000 {
compatible = "fsl,imx6q-gpmi-nand";
#address-cells = <1>;
@@ -201,6 +253,28 @@
reg = <0x02000000 0x40000>;
ranges;
+ spdif: spdif@02004000 {
+ compatible = "fsl,imx6ul-spdif", "fsl,imx35-spdif";
+ reg = <0x02004000 0x4000>;
+ interrupts = <GIC_SPI 52 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&sdma 41 18 0>,
+ <&sdma 42 18 0>;
+ dma-names = "rx", "tx";
+ clocks = <&clks IMX6UL_CLK_SPDIF_GCLK>,
+ <&clks IMX6UL_CLK_OSC>,
+ <&clks IMX6UL_CLK_SPDIF>,
+ <&clks IMX6UL_CLK_DUMMY>, <&clks IMX6UL_CLK_DUMMY>, <&clks IMX6UL_CLK_DUMMY>,
+ <&clks IMX6UL_CLK_IPG>,
+ <&clks IMX6UL_CLK_DUMMY>, <&clks IMX6UL_CLK_DUMMY>,
+ <&clks IMX6UL_CLK_SPBA>;
+ clock-names = "core", "rxtx0",
+ "rxtx1", "rxtx2",
+ "rxtx3", "rxtx4",
+ "rxtx5", "rxtx6",
+ "rxtx7", "spba";
+ status = "disabled";
+ };
+
ecspi1: ecspi@02008000 {
#address-cells = <1>;
#size-cells = <0>;
@@ -210,6 +284,8 @@
clocks = <&clks IMX6UL_CLK_ECSPI1>,
<&clks IMX6UL_CLK_ECSPI1>;
clock-names = "ipg", "per";
+ dmas = <&sdma 3 7 1>, <&sdma 4 7 2>;
+ dma-names = "rx", "tx";
status = "disabled";
};
@@ -222,6 +298,8 @@
clocks = <&clks IMX6UL_CLK_ECSPI2>,
<&clks IMX6UL_CLK_ECSPI2>;
clock-names = "ipg", "per";
+ dmas = <&sdma 5 7 1>, <&sdma 6 7 2>;
+ dma-names = "rx", "tx";
status = "disabled";
};
@@ -234,6 +312,8 @@
clocks = <&clks IMX6UL_CLK_ECSPI3>,
<&clks IMX6UL_CLK_ECSPI3>;
clock-names = "ipg", "per";
+ dmas = <&sdma 7 7 1>, <&sdma 8 7 2>;
+ dma-names = "rx", "tx";
status = "disabled";
};
@@ -246,23 +326,27 @@
clocks = <&clks IMX6UL_CLK_ECSPI4>,
<&clks IMX6UL_CLK_ECSPI4>;
clock-names = "ipg", "per";
+ dmas = <&sdma 9 7 1>, <&sdma 10 7 2>;
+ dma-names = "rx", "tx";
status = "disabled";
};
uart7: serial@02018000 {
compatible = "fsl,imx6ul-uart",
- "fsl,imx6q-uart";
+ "fsl,imx6q-uart", "fsl,imx21-uart";
reg = <0x02018000 0x4000>;
interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clks IMX6UL_CLK_UART7_IPG>,
<&clks IMX6UL_CLK_UART7_SERIAL>;
clock-names = "ipg", "per";
+ dmas = <&sdma 43 4 0>, <&sdma 44 4 0>;
+ dma-names = "rx", "tx";
status = "disabled";
};
uart1: serial@02020000 {
compatible = "fsl,imx6ul-uart",
- "fsl,imx6q-uart";
+ "fsl,imx6q-uart", "fsl,imx21-uart";
reg = <0x02020000 0x4000>;
interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clks IMX6UL_CLK_UART1_IPG>,
@@ -273,12 +357,14 @@
uart8: serial@02024000 {
compatible = "fsl,imx6ul-uart",
- "fsl,imx6q-uart";
+ "fsl,imx6q-uart", "fsl,imx21-uart";
reg = <0x02024000 0x4000>;
interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clks IMX6UL_CLK_UART8_IPG>,
<&clks IMX6UL_CLK_UART8_SERIAL>;
clock-names = "ipg", "per";
+ dmas = <&sdma 45 4 0>, <&sdma 46 4 0>;
+ dma-names = "rx", "tx";
status = "disabled";
};
@@ -288,9 +374,10 @@
reg = <0x02028000 0x4000>;
interrupts = <GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clks IMX6UL_CLK_SAI1_IPG>,
+ <&clks IMX6UL_CLK_DUMMY>,
<&clks IMX6UL_CLK_SAI1>,
<&clks IMX6UL_CLK_DUMMY>, <&clks IMX6UL_CLK_DUMMY>;
- clock-names = "bus", "mclk1", "mclk2", "mclk3";
+ clock-names = "bus", "mclk0", "mclk1", "mclk2", "mclk3";
dmas = <&sdma 35 24 0>,
<&sdma 36 24 0>;
dma-names = "rx", "tx";
@@ -303,9 +390,11 @@
reg = <0x0202c000 0x4000>;
interrupts = <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clks IMX6UL_CLK_SAI2_IPG>,
+ <&clks IMX6UL_CLK_DUMMY>,
<&clks IMX6UL_CLK_SAI2>,
<&clks IMX6UL_CLK_DUMMY>, <&clks IMX6UL_CLK_DUMMY>;
- clock-names = "bus", "mclk1", "mclk2", "mclk3";
+ clock-names = "bus", "mclk0", "mclk1", "mclk2", "mclk3";
+
dmas = <&sdma 37 24 0>,
<&sdma 38 24 0>;
dma-names = "rx", "tx";
@@ -318,14 +407,40 @@
reg = <0x02030000 0x4000>;
interrupts = <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clks IMX6UL_CLK_SAI3_IPG>,
+ <&clks IMX6UL_CLK_DUMMY>,
<&clks IMX6UL_CLK_SAI3>,
<&clks IMX6UL_CLK_DUMMY>, <&clks IMX6UL_CLK_DUMMY>;
- clock-names = "bus", "mclk1", "mclk2", "mclk3";
+ clock-names = "bus", "mclk0", "mclk1", "mclk2", "mclk3";
dmas = <&sdma 39 24 0>,
<&sdma 40 24 0>;
dma-names = "rx", "tx";
status = "disabled";
};
+
+ asrc: asrc@02034000 {
+ compatible = "fsl,imx53-asrc";
+ reg = <0x02034000 0x4000>;
+ interrupts = <GIC_SPI 50 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6UL_CLK_ASRC_IPG>,
+ <&clks IMX6UL_CLK_ASRC_MEM>, <&clks 0>,
+ <&clks 0>, <&clks 0>, <&clks 0>, <&clks 0>,
+ <&clks 0>, <&clks 0>, <&clks 0>, <&clks 0>,
+ <&clks 0>, <&clks 0>, <&clks 0>, <&clks 0>,
+ <&clks IMX6UL_CLK_SPDIF>, <&clks 0>, <&clks 0>,
+ <&clks IMX6UL_CLK_SPBA>;
+ clock-names = "mem", "ipg", "asrck_0",
+ "asrck_1", "asrck_2", "asrck_3", "asrck_4",
+ "asrck_5", "asrck_6", "asrck_7", "asrck_8",
+ "asrck_9", "asrck_a", "asrck_b", "asrck_c",
+ "asrck_d", "asrck_e", "asrck_f", "spba";
+ dmas = <&sdma 17 23 1>, <&sdma 18 23 1>, <&sdma 19 23 1>,
+ <&sdma 20 23 1>, <&sdma 21 23 1>, <&sdma 22 23 1>;
+ dma-names = "rxa", "rxb", "rxc",
+ "txa", "txb", "txc";
+ fsl,asrc-rate = <48000>;
+ fsl,asrc-width = <16>;
+ status = "okay";
+ };
};
tsc: tsc@02040000 {
@@ -339,6 +454,13 @@
status = "disabled";
};
+ bee: bee@02044000 {
+ compatible = "fsl,imx6ul-bee";
+ reg = <0x02044000 0x4000>;
+ interrupts = <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
+
pwm1: pwm@02080000 {
compatible = "fsl,imx6ul-pwm", "fsl,imx27-pwm";
reg = <0x02080000 0x4000>;
@@ -390,6 +512,7 @@
clocks = <&clks IMX6UL_CLK_CAN1_IPG>,
<&clks IMX6UL_CLK_CAN1_SERIAL>;
clock-names = "ipg", "per";
+ stop-mode = <&gpr 0x10 1 0x10 17>;
status = "disabled";
};
@@ -400,6 +523,7 @@
clocks = <&clks IMX6UL_CLK_CAN2_IPG>,
<&clks IMX6UL_CLK_CAN2_SERIAL>;
clock-names = "ipg", "per";
+ stop-mode = <&gpr 0x10 2 0x10 18>;
status = "disabled";
};
@@ -408,8 +532,8 @@
reg = <0x02098000 0x4000>;
interrupts = <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clks IMX6UL_CLK_GPT1_BUS>,
- <&clks IMX6UL_CLK_GPT1_SERIAL>;
- clock-names = "ipg", "per";
+ <&clks IMX6UL_CLK_GPT_3M>;
+ clock-names = "ipg", "osc_per";
};
gpio1: gpio@0209c000 {
@@ -473,6 +597,12 @@
gpio-ranges = <&iomuxc 0 7 10>, <&iomuxc 10 5 2>;
};
+ snvslp: snvs@020b0000 {
+ compatible = "fsl,imx6ul-snvs";
+ reg = <0x020b0000 0x4000>;
+ interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
fec2: ethernet@020b4000 {
compatible = "fsl,imx6ul-fec", "fsl,imx6q-fec";
reg = <0x020b4000 0x4000>;
@@ -485,8 +615,11 @@
<&clks IMX6UL_CLK_ENET2_REF_125M>;
clock-names = "ipg", "ahb", "ptp",
"enet_clk_ref", "enet_out";
+ stop-mode = <&gpr 0x10 4>;
fsl,num-tx-queues=<1>;
fsl,num-rx-queues=<1>;
+ fsl,magic-packet;
+ fsl,wakeup_irq = <0>;
status = "disabled";
};
@@ -598,6 +731,19 @@
fsl,anatop = <&anatop>;
};
+ tempmon: tempmon {
+ compatible = "fsl,imx6ul-tempmon", "fsl,imx6sx-tempmon";
+ interrupts = <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>;
+ fsl,tempmon = <&anatop>;
+ fsl,tempmon-data = <&ocotp>;
+ clocks = <&clks IMX6UL_CLK_PLL3_USB_OTG>;
+ };
+
+ caam_snvs: caam-snvs@020cc000 {
+ compatible = "fsl,imx6q-caam-snvs";
+ reg = <0x020cc000 0x4000>;
+ };
+
snvs: snvs@020cc000 {
compatible = "fsl,sec-v4.0-mon", "syscon", "simple-mfd";
reg = <0x020cc000 0x4000>;
@@ -614,8 +760,8 @@
compatible = "syscon-poweroff";
regmap = <&snvs>;
offset = <0x38>;
- value = <0x60>;
- mask = <0x60>;
+ value = <0x61>;
+ mask = <0x61>;
status = "disabled";
};
@@ -653,6 +799,7 @@
#interrupt-cells = <3>;
interrupts = <GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH>;
interrupt-parent = <&intc>;
+ fsl,mf-mix-wakeup-irq = <0x7c00000 0x7d00 0x0 0x1400640>;
};
iomuxc: iomuxc@020e0000 {
@@ -675,6 +822,13 @@
clock-names = "ipg", "per";
};
+ mqs: mqs {
+ compatible = "fsl,imx6sx-mqs";
+ gpr = <&gpr>;
+ status = "disabled";
+ };
+
+
sdma: sdma@020ec000 {
compatible = "fsl,imx6ul-sdma", "fsl,imx6q-sdma",
"fsl,imx35-sdma";
@@ -684,6 +838,7 @@
<&clks IMX6UL_CLK_SDMA>;
clock-names = "ipg", "ahb";
#dma-cells = <3>;
+ iram = <&ocram>;
fsl,sdma-ram-script-name = "imx/sdma/sdma-imx6q.bin";
};
@@ -739,6 +894,44 @@
reg = <0x02100000 0x100000>;
ranges;
+ crypto: caam@2140000 {
+ compatible = "fsl,imx6ul-caam", "fsl,sec-v4.0";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x2140000 0x3c000>;
+ ranges = <0 0x2140000 0x3c000>;
+ interrupts = <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6UL_CLK_CAAM_IPG>, <&clks IMX6UL_CLK_CAAM_ACLK>,
+ <&clks IMX6UL_CLK_CAAM_MEM>;
+ clock-names = "ipg", "aclk", "mem";
+
+ sec_ctrl: ctrl@0 {
+ /* CAAM Page 0 only accessible */
+ /* by secure world */
+ compatible = "fsl,sec-v4.0-ctrl";
+ reg = <0x2140000 0x1000>;
+ secure-status = "okay";
+ status = "disabled";
+ };
+
+ sec_jr0: jr0@1000 {
+ compatible = "fsl,sec-v4.0-job-ring";
+ reg = <0x1000 0x1000>;
+ interrupts = <GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ sec_jr1: jr1@2000 {
+ compatible = "fsl,sec-v4.0-job-ring";
+ reg = <0x2000 0x1000>;
+ interrupts = <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>;
+ };
+ sec_jr2: jr2@3000 {
+ compatible = "fsl,sec-v4.0-job-ring";
+ reg = <0x3000 0x1000>;
+ interrupts = <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>;
+ };
+ };
+
usbotg1: usb@02184000 {
compatible = "fsl,imx6ul-usb", "fsl,imx27-usb";
reg = <0x02184000 0x200>;
@@ -784,8 +977,18 @@
<&clks IMX6UL_CLK_ENET_REF>;
clock-names = "ipg", "ahb", "ptp",
"enet_clk_ref", "enet_out";
+ stop-mode = <&gpr 0x10 3>;
fsl,num-tx-queues=<1>;
fsl,num-rx-queues=<1>;
+ fsl,magic-packet;
+ fsl,wakeup_irq = <0>;
+ status = "disabled";
+ };
+
+ sim1: sim@0218c000 {
+ compatible = "fsl,imx6ul-sim";
+ reg = <0x0218c000 0x4000>;
+ interrupts = <GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>;
status = "disabled";
};
@@ -855,17 +1058,56 @@
status = "disabled";
};
+ romcp@021ac000 {
+ compatible = "fsl,imx6ul-romcp", "syscon";
+ reg = <0x021ac000 0x4000>;
+ };
+
mmdc: mmdc@021b0000 {
compatible = "fsl,imx6ul-mmdc", "fsl,imx6q-mmdc";
reg = <0x021b0000 0x4000>;
};
+ sim2: sim@021b4000 {
+ compatible = "fsl,imx6ul-sim";
+ reg = <0x021b4000 0x4000>;
+ interrupts = <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6UL_CLK_SIM2>;
+ clock-names = "sim";
+ status = "disabled";
+ };
+
+ weim: weim@021b8000 {
+ compatible = "fsl,imx6ul-weim", "fsl,imx6q-weim";
+ reg = <0x021b8000 0x4000>;
+ interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6UL_CLK_DUMMY>;
+ };
+
ocotp: ocotp-ctrl@021bc000 {
compatible = "fsl,imx6ul-ocotp", "syscon";
reg = <0x021bc000 0x4000>;
clocks = <&clks IMX6UL_CLK_OCOTP>;
};
+ csu: csu@021c0000 {
+ compatible = "fsl,imx6ul-csu";
+ reg = <0x021c0000 0x4000>;
+ interrupts = <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
+
+ csi: csi@021c4000 {
+ compatible = "fsl,imx6ul-csi", "fsl,imx6s-csi";
+ reg = <0x021c4000 0x4000>;
+ interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6UL_CLK_DUMMY>,
+ <&clks IMX6UL_CLK_CSI>,
+ <&clks IMX6UL_CLK_DUMMY>;
+ clock-names = "disp-axi", "csi_mclk", "disp_dcic";
+ status = "disabled";
+ };
+
lcdif: lcdif@021c8000 {
compatible = "fsl,imx6ul-lcdif", "fsl,imx28-lcdif";
reg = <0x021c8000 0x4000>;
@@ -890,47 +1132,65 @@
status = "disabled";
};
+ pxp: pxp@021cc000 {
+ compatible = "fsl,imx6ul-pxp-dma", "fsl,imx6sl-pxp-dma", "fsl,imx6dl-pxp-dma";
+ reg = <0x021cc000 0x4000>;
+ interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6UL_CLK_PXP>,
+ <&clks IMX6UL_CLK_DUMMY>;
+ clock-names = "pxp-axi", "disp-axi";
+ status = "disabled";
+ };
+
uart2: serial@021e8000 {
compatible = "fsl,imx6ul-uart",
- "fsl,imx6q-uart";
+ "fsl,imx6q-uart", "fsl,imx21-uart";
reg = <0x021e8000 0x4000>;
interrupts = <GIC_SPI 27 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clks IMX6UL_CLK_UART2_IPG>,
<&clks IMX6UL_CLK_UART2_SERIAL>;
clock-names = "ipg", "per";
+ dmas = <&sdma 27 4 0>, <&sdma 28 4 0>;
+ dma-names = "rx", "tx";
status = "disabled";
};
uart3: serial@021ec000 {
compatible = "fsl,imx6ul-uart",
- "fsl,imx6q-uart";
+ "fsl,imx6q-uart", "fsl,imx21-uart";
reg = <0x021ec000 0x4000>;
interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clks IMX6UL_CLK_UART3_IPG>,
<&clks IMX6UL_CLK_UART3_SERIAL>;
clock-names = "ipg", "per";
+ dmas = <&sdma 29 4 0>, <&sdma 30 4 0>;
+ dma-names = "rx", "tx";
status = "disabled";
};
uart4: serial@021f0000 {
compatible = "fsl,imx6ul-uart",
- "fsl,imx6q-uart";
+ "fsl,imx6q-uart", "fsl,imx21-uart";
reg = <0x021f0000 0x4000>;
interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clks IMX6UL_CLK_UART4_IPG>,
<&clks IMX6UL_CLK_UART4_SERIAL>;
clock-names = "ipg", "per";
+ dmas = <&sdma 31 4 0>, <&sdma 32 4 0>;
+ dma-names = "rx", "tx";
status = "disabled";
};
uart5: serial@021f4000 {
compatible = "fsl,imx6ul-uart",
- "fsl,imx6q-uart";
+ "fsl,imx6q-uart", "fsl,imx21-uart";
reg = <0x021f4000 0x4000>;
interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clks IMX6UL_CLK_UART5_IPG>,
<&clks IMX6UL_CLK_UART5_SERIAL>;
clock-names = "ipg", "per";
+ dmas = <&sdma 33 4 0>, <&sdma 34 4 0>;
+ dma-names = "rx", "tx";
status = "disabled";
};
@@ -946,12 +1206,14 @@
uart6: serial@021fc000 {
compatible = "fsl,imx6ul-uart",
- "fsl,imx6q-uart";
+ "fsl,imx6q-uart", "fsl,imx21-uart";
reg = <0x021fc000 0x4000>;
interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clks IMX6UL_CLK_UART6_IPG>,
<&clks IMX6UL_CLK_UART6_SERIAL>;
clock-names = "ipg", "per";
+ dmas = <&sdma 0 4 0>, <&sdma 47 4 0>;
+ dma-names = "rx", "tx";
status = "disabled";
};
};
diff --git a/arch/arm/boot/dts/imx6ull-14x14-ddr3-arm2-adc.dts b/arch/arm/boot/dts/imx6ull-14x14-ddr3-arm2-adc.dts
new file mode 100644
index 000000000000..334597cac3ce
--- /dev/null
+++ b/arch/arm/boot/dts/imx6ull-14x14-ddr3-arm2-adc.dts
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2016 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 "imx6ull-14x14-ddr3-arm2.dts"
+
+&usbotg1 {
+ status = "disabled";
+};
+
+&adc1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_adc1>;
+ vref-supply = <&reg_vref_3v3>;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx6ull-14x14-ddr3-arm2-cs42888.dts b/arch/arm/boot/dts/imx6ull-14x14-ddr3-arm2-cs42888.dts
new file mode 100644
index 000000000000..cf14b6f3f92a
--- /dev/null
+++ b/arch/arm/boot/dts/imx6ull-14x14-ddr3-arm2-cs42888.dts
@@ -0,0 +1,158 @@
+/*
+ * Copyright (C) 2016 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 "imx6ull-14x14-ddr3-arm2-lcdif.dts"
+
+/ {
+ clocks {
+ codec_osc: anaclk2 {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <24576000>;
+ };
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ reg_audio: cs42888_supply {
+ compatible = "regulator-fixed";
+ regulator-name = "cs42888_supply";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ reg_codec_5v: codec_5v {
+ compatible = "regulator-fixed";
+ regulator-name = "CODEC_5V";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ enable-active-high;
+ };
+
+ reg_aud_3v3: aud_3v3 {
+ compatible = "regulator-fixed";
+ regulator-name = "AUD_3V3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ enable-active-high;
+ };
+
+ reg_aud_1v8: aud_1v8 {
+ compatible = "regulator-fixed";
+ regulator-name = "AUD_1V8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ enable-active-high;
+ };
+ };
+
+ sound-cs42888 {
+ compatible = "fsl,imx6-sabreauto-cs42888",
+ "fsl,imx-audio-cs42888";
+ model = "imx-cs42888";
+ esai-controller = <&esai>;
+ asrc-controller = <&asrc>;
+ audio-codec = <&codec_a>;
+ codec-master;
+ };
+
+ sound-wm8958 {
+ compatible = "fsl,imx6ul-ddr3-arm2-wm8958",
+ "fsl,imx-audio-wm8958";
+ model = "wm8958-audio";
+ cpu-dai = <&sai2>;
+ audio-codec = <&codec_b>;
+ codec-master;
+ gpr = <&gpr 4 0x100000 0x100000>;
+ hp-det-gpios = <&gpio5 0 1>;
+ };
+};
+
+&clks {
+ assigned-clocks = <&clks IMX6UL_CLK_PLL4_AUDIO_DIV>;
+ assigned-clock-rates = <786432000>;
+};
+
+&esai {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_esai>;
+ assigned-clocks = <&clks IMX6ULL_CLK_ESAI_SEL>,
+ <&clks IMX6ULL_CLK_ESAI_EXTAL>;
+ assigned-clock-parents = <&clks IMX6UL_CLK_PLL4_AUDIO_DIV>;
+ assigned-clock-rates = <0>, <24576000>;
+ status = "okay";
+};
+
+&i2c4 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c4>;
+ status = "okay";
+
+ codec_a: cs42888@048 {
+ compatible = "cirrus,cs42888";
+ reg = <0x048>;
+ clocks = <&codec_osc 0>;
+ clock-names = "mclk";
+ VA-supply = <&reg_audio>;
+ VD-supply = <&reg_audio>;
+ VLS-supply = <&reg_audio>;
+ VLC-supply = <&reg_audio>;
+ };
+
+ codec_b: wm8958@1a {
+ compatible = "wlf,wm8958";
+ reg = <0x1a>;
+ clocks = <&clks IMX6UL_CLK_SAI2>,
+ <&clks IMX6UL_CLK_DUMMY>;
+ clock-names = "mclk1", "mclk2";
+
+ DBVDD1-supply = <&reg_aud_1v8>;
+ DBVDD2-supply = <&reg_aud_1v8>;
+ DBVDD3-supply = <&reg_aud_3v3>;
+ AVDD2-supply = <&reg_aud_1v8>;
+ CPVDD-supply = <&reg_aud_1v8>;
+ SPKVDD1-supply = <&reg_codec_5v>;
+ SPKVDD2-supply = <&reg_codec_5v>;
+
+ wlf,ldo1ena;
+ wlf,ldo2ena;
+ };
+};
+
+&ov5640 {
+ status = "disabled";
+};
+
+&sai2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_sai2 &pinctrl_sai2_hp_det_b>;
+ assigned-clocks = <&clks IMX6UL_CLK_SAI2_SEL>,
+ <&clks IMX6UL_CLK_SAI2>;
+ assigned-clock-parents = <&clks IMX6UL_CLK_PLL4_AUDIO_DIV>;
+ assigned-clock-rates = <0>, <24576000>;
+ status = "okay";
+};
+
+&sdma {
+ gpr = <&gpr>;
+ /* SDMA event remap for ESAI */
+ fsl,sdma-event-remap = <0 14 1>, <0 15 1>;
+};
+
+&uart2 {
+ status = "disabled";
+};
+
+&usdhc1 {
+ status = "disabled";
+};
diff --git a/arch/arm/boot/dts/imx6ull-14x14-ddr3-arm2-ecspi.dts b/arch/arm/boot/dts/imx6ull-14x14-ddr3-arm2-ecspi.dts
new file mode 100644
index 000000000000..f86931fce693
--- /dev/null
+++ b/arch/arm/boot/dts/imx6ull-14x14-ddr3-arm2-ecspi.dts
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2016 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 "imx6ull-14x14-ddr3-arm2.dts"
+
+&ecspi1 {
+ status = "okay";
+};
+
+&esai {
+ status = "disabled";
+};
+
+&ov5640{
+ status = "disabled";
+};
+
diff --git a/arch/arm/boot/dts/imx6ull-14x14-ddr3-arm2-emmc.dts b/arch/arm/boot/dts/imx6ull-14x14-ddr3-arm2-emmc.dts
new file mode 100644
index 000000000000..934e6f6b8502
--- /dev/null
+++ b/arch/arm/boot/dts/imx6ull-14x14-ddr3-arm2-emmc.dts
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2016 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 "imx6ull-14x14-ddr3-arm2.dts"
+
+&usdhc1 {
+ pinctrl-0 = <&pinctrl_usdhc1>;
+ pinctrl-1 = <&pinctrl_usdhc1_100mhz>;
+ pinctrl-2 = <&pinctrl_usdhc1_200mhz>;
+ cd-gpios = <>;
+ wp-gpios = <>;
+ vmmc-supply = <>;
+ non-removable;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx6ull-14x14-ddr3-arm2-epdc.dts b/arch/arm/boot/dts/imx6ull-14x14-ddr3-arm2-epdc.dts
new file mode 100644
index 000000000000..c476f442efdf
--- /dev/null
+++ b/arch/arm/boot/dts/imx6ull-14x14-ddr3-arm2-epdc.dts
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2016 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 "imx6ull-14x14-ddr3-arm2.dts"
+
+&epdc {
+ status = "okay";
+};
+
+&fec2 {
+ status = "disabled";
+};
+
+&lcdif {
+ status = "disabled";
+};
+
+&max17135 {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx6ull-14x14-ddr3-arm2-flexcan2.dts b/arch/arm/boot/dts/imx6ull-14x14-ddr3-arm2-flexcan2.dts
new file mode 100644
index 000000000000..c8c92c392266
--- /dev/null
+++ b/arch/arm/boot/dts/imx6ull-14x14-ddr3-arm2-flexcan2.dts
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2016 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 "imx6ull-14x14-ddr3-arm2.dts"
+
+/* flexcan2 tx/rx pin conflicts with uart2 */
+
+&uart2 {
+ status = "disabled";
+};
+
+&flexcan2 {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx6ull-14x14-ddr3-arm2-gpmi-weim.dts b/arch/arm/boot/dts/imx6ull-14x14-ddr3-arm2-gpmi-weim.dts
new file mode 100644
index 000000000000..327677aafa7d
--- /dev/null
+++ b/arch/arm/boot/dts/imx6ull-14x14-ddr3-arm2-gpmi-weim.dts
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2016 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 "imx6ull-14x14-ddr3-arm2.dts"
+
+&gpmi {
+ status ="okay";
+};
+
+&qspi {
+ status ="disabled";
+};
+
+&usdhc2{
+ status ="disabled";
+};
diff --git a/arch/arm/boot/dts/imx6ull-14x14-ddr3-arm2-lcdif.dts b/arch/arm/boot/dts/imx6ull-14x14-ddr3-arm2-lcdif.dts
new file mode 100644
index 000000000000..40e86a4e08c3
--- /dev/null
+++ b/arch/arm/boot/dts/imx6ull-14x14-ddr3-arm2-lcdif.dts
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2016 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 file for LCDIF at imx6ull ddr3 arm2 board */
+
+#include "imx6ull-14x14-ddr3-arm2.dts"
+
+/ {
+ backlight {
+ status = "okay";
+ };
+};
+
+&fec1 {
+ status = "disabled";
+};
+
+&lcdif {
+ status = "okay";
+};
+
+&pwm1 {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx6ull-14x14-ddr3-arm2-ldo.dts b/arch/arm/boot/dts/imx6ull-14x14-ddr3-arm2-ldo.dts
new file mode 100644
index 000000000000..4266dc243da6
--- /dev/null
+++ b/arch/arm/boot/dts/imx6ull-14x14-ddr3-arm2-ldo.dts
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2016 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 "imx6ull-14x14-ddr3-arm2.dts"
+
+&cpu0 {
+ operating-points = <
+ /* kHz uV */
+ 996000 1275000
+ 792000 1225000
+ 528000 1175000
+ 396000 1025000
+ 198000 950000
+ >;
+ fsl,soc-operating-points = <
+ /* KHz uV */
+ 996000 1175000
+ 792000 1175000
+ 528000 1175000
+ 396000 1175000
+ 198000 1175000
+ >;
+ fsl,arm-soc-shared = <0>;
+};
+
+&gpc {
+ fsl,ldo-bypass = <0>; /* use ldo-enable, u-boot will check it and configure */
+};
+
+&reg_arm {
+ /delete-property/ vin-supply;
+};
+
+&reg_soc {
+ /delete-property/ vin-supply;
+};
diff --git a/arch/arm/boot/dts/imx6ull-14x14-ddr3-arm2-qspi-all.dts b/arch/arm/boot/dts/imx6ull-14x14-ddr3-arm2-qspi-all.dts
new file mode 100644
index 000000000000..a4cdbe588d83
--- /dev/null
+++ b/arch/arm/boot/dts/imx6ull-14x14-ddr3-arm2-qspi-all.dts
@@ -0,0 +1,18 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+#define REWORKED_ENABLE_ALL_QSPI
+#include "imx6ull-14x14-ddr3-arm2.dts"
+
+&gpmi {
+ status ="disabled";
+};
+
+&usdhc2{
+ status ="disabled";
+};
diff --git a/arch/arm/boot/dts/imx6ull-14x14-ddr3-arm2-qspi.dts b/arch/arm/boot/dts/imx6ull-14x14-ddr3-arm2-qspi.dts
new file mode 100644
index 000000000000..2155c7af1b77
--- /dev/null
+++ b/arch/arm/boot/dts/imx6ull-14x14-ddr3-arm2-qspi.dts
@@ -0,0 +1,9 @@
+/*
+ * Copyright (C) 2016 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 "imx6ull-14x14-ddr3-arm2.dts"
diff --git a/arch/arm/boot/dts/imx6ull-14x14-ddr3-arm2-tsc.dts b/arch/arm/boot/dts/imx6ull-14x14-ddr3-arm2-tsc.dts
new file mode 100644
index 000000000000..8893e39b0ac3
--- /dev/null
+++ b/arch/arm/boot/dts/imx6ull-14x14-ddr3-arm2-tsc.dts
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2016 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 "imx6ull-14x14-ddr3-arm2-lcdif.dts"
+
+&csi {
+ status = "disabled";
+};
+
+&i2c1 {
+ status = "disabled";
+};
+
+&reg_usb_otg1_vbus {
+ pinctrl-0 = < >;
+ gpio = < >;
+};
+
+&ov5640 {
+ status = "disabled";
+};
+
+&usbotg1 {
+ status = "disabled";
+};
+
+&tsc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_tsc>;
+ status = "okay";
+ xnur-gpio = <&gpio1 3 0>;
+ measure_delay_time = <0xfff>;
+ pre_charge_time = <0xffff>;
+};
diff --git a/arch/arm/boot/dts/imx6ull-14x14-ddr3-arm2-uart2.dts b/arch/arm/boot/dts/imx6ull-14x14-ddr3-arm2-uart2.dts
new file mode 100644
index 000000000000..6f157ea4656d
--- /dev/null
+++ b/arch/arm/boot/dts/imx6ull-14x14-ddr3-arm2-uart2.dts
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2016 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 "imx6ull-14x14-ddr3-arm2.dts"
+
+&flexcan2 {
+ status = "disabled";
+};
+
+&i2c4 {
+ status = "disabled";
+};
+
+&uart2 {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx6ull-14x14-ddr3-arm2-usb.dts b/arch/arm/boot/dts/imx6ull-14x14-ddr3-arm2-usb.dts
new file mode 100644
index 000000000000..619c28b89d46
--- /dev/null
+++ b/arch/arm/boot/dts/imx6ull-14x14-ddr3-arm2-usb.dts
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2016 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 file for validate USB at i.mx6ull ddr3 arm2 board */
+
+#include "imx6ull-14x14-ddr3-arm2.dts"
+
+/ {
+ regulators {
+ reg_usb_otg2_vbus: regulator@3 {
+ compatible = "regulator-fixed";
+ reg = <3>;
+ regulator-name = "usb_otg2_vbus";
+ pinctrl-0 = <&pinctrl_usb_otg2>;
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&gpio1 9 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+ };
+};
+
+&iomuxc {
+ usbotg2 {
+ pinctrl_usb_otg2_id: usbotg2idgrp {
+ fsl,pins = <
+ MX6UL_PAD_GPIO1_IO05__ANATOP_OTG2_ID 0x17059
+ >;
+ };
+
+ pinctrl_usb_otg2: usbotg2grp {
+ fsl,pins = <
+ MX6UL_PAD_GPIO1_IO09__GPIO1_IO09 0x10b0
+ >;
+ };
+ };
+};
+
+&usbotg2 {
+ vbus-supply = <&reg_usb_otg2_vbus>; /* hardware rework is needed */
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usb_otg2_id>;
+ srp-disable;
+ hnp-disable;
+ adp-disable;
+ status = "okay";
+};
+
+&usdhc1 {
+ no-1-8-v;
+ vmmc-supply = <>;
+ pinctrl-0 = <&pinctrl_usdhc1>, <&pinctrl_usdhc1_cd_wp>;
+ pinctrl-1 = <&pinctrl_usdhc1_100mhz>, <&pinctrl_usdhc1_cd_wp>;
+ pinctrl-2 = <&pinctrl_usdhc1_200mhz>, <&pinctrl_usdhc1_cd_wp>;
+};
diff --git a/arch/arm/boot/dts/imx6ull-14x14-ddr3-arm2-wm8958.dts b/arch/arm/boot/dts/imx6ull-14x14-ddr3-arm2-wm8958.dts
new file mode 100644
index 000000000000..498281b2c88b
--- /dev/null
+++ b/arch/arm/boot/dts/imx6ull-14x14-ddr3-arm2-wm8958.dts
@@ -0,0 +1,155 @@
+/*
+ * Copyright (C) 2016 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 "imx6ull-14x14-ddr3-arm2.dts"
+
+/ {
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ reg_codec_5v: codec_5v {
+ compatible = "regulator-fixed";
+ regulator-name = "CODEC_5V";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ enable-active-high;
+ };
+
+ reg_aud_3v3: aud_3v3 {
+ compatible = "regulator-fixed";
+ regulator-name = "AUD_3V3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ enable-active-high;
+ };
+
+ reg_aud_1v8: aud_1v8 {
+ compatible = "regulator-fixed";
+ regulator-name = "AUD_1V8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ enable-active-high;
+ };
+ };
+
+ sound-mqs {
+ compatible = "fsl,imx6ul-ddr3-arm2-mqs",
+ "fsl,imx-audio-mqs";
+ model = "mqs-audio";
+ cpu-dai = <&sai1>;
+ asrc-controller = <&asrc>;
+ audio-codec = <&mqs>;
+ };
+
+ sound-wm8958 {
+ compatible = "fsl,imx6ul-ddr3-arm2-wm8958",
+ "fsl,imx-audio-wm8958";
+ model = "wm8958-audio";
+ cpu-dai = <&sai2>;
+ audio-codec = <&codec_b>;
+ codec-master;
+ gpr = <&gpr 4 0x100000 0x100000>;
+ hp-det-gpios = <&gpio5 0 1>;
+ };
+
+ sound-spdif {
+ compatible = "fsl,imx-audio-spdif";
+ model = "imx-spdif";
+ spdif-controller = <&spdif>;
+ spdif-in;
+ spdif-out;
+ };
+};
+
+&clks {
+ assigned-clocks = <&clks IMX6UL_CLK_PLL4_AUDIO_DIV>;
+ assigned-clock-rates = <786432000>;
+};
+
+&i2c4 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c4>;
+ status = "okay";
+
+ codec_b: wm8958@1a {
+ compatible = "wlf,wm8958";
+ reg = <0x1a>;
+ clocks = <&clks IMX6UL_CLK_SAI2>,
+ <&clks IMX6UL_CLK_DUMMY>;
+ clock-names = "mclk1", "mclk2";
+
+ DBVDD1-supply = <&reg_aud_1v8>;
+ DBVDD2-supply = <&reg_aud_1v8>;
+ DBVDD3-supply = <&reg_aud_3v3>;
+ AVDD2-supply = <&reg_aud_1v8>;
+ CPVDD-supply = <&reg_aud_1v8>;
+ SPKVDD1-supply = <&reg_codec_5v>;
+ SPKVDD2-supply = <&reg_codec_5v>;
+
+ wlf,ldo1ena;
+ wlf,ldo2ena;
+ };
+};
+
+&sai2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_sai2 &pinctrl_sai2_hp_det_b>;
+ assigned-clocks = <&clks IMX6UL_CLK_SAI2_SEL>,
+ <&clks IMX6UL_CLK_SAI2>;
+ assigned-clock-parents = <&clks IMX6UL_CLK_PLL4_AUDIO_DIV>;
+ assigned-clock-rates = <0>, <24576000>;
+ status = "okay";
+};
+
+&sai1 {
+ assigned-clocks = <&clks IMX6UL_CLK_SAI1_SEL>,
+ <&clks IMX6UL_CLK_SAI1>;
+ assigned-clock-parents = <&clks IMX6UL_CLK_PLL4_AUDIO_DIV>;
+ assigned-clock-rates = <0>, <24576000>;
+ status = "okay";
+};
+
+&mqs {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_mqs>;
+ clocks = <&clks IMX6UL_CLK_SAI1>;
+ clock-names = "mclk";
+ status = "okay";
+};
+
+&spdif {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_spdif>;
+ assigned-clocks = <&clks IMX6UL_CLK_SPDIF_SEL>,
+ <&clks IMX6UL_CLK_SPDIF_PODF>;
+ assigned-clock-parents = <&clks IMX6UL_CLK_PLL4_AUDIO_DIV>;
+ assigned-clock-rates = <0>, <49152000>;
+ status = "okay";
+};
+
+&uart2 {
+ status = "disabled";
+};
+
+&usdhc1 {
+ no-1-8-v;
+ vmmc-supply = <>;
+ status = "disabled";
+};
+
+&usdhc2 {
+ no-1-8-v;
+};
+
+&wdog1 {
+ status = "disabled";
+};
diff --git a/arch/arm/boot/dts/imx6ull-14x14-ddr3-arm2.dts b/arch/arm/boot/dts/imx6ull-14x14-ddr3-arm2.dts
new file mode 100644
index 000000000000..292e72d17f92
--- /dev/null
+++ b/arch/arm/boot/dts/imx6ull-14x14-ddr3-arm2.dts
@@ -0,0 +1,1029 @@
+/*
+ * Copyright (C) 2016 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 <dt-bindings/input/input.h>
+#include "imx6ull.dtsi"
+
+/ {
+ model = "Freescale i.MX6 ULL DDR3 ARM2 Board";
+ compatible = "fsl,imx6ull-ddr3-arm2", "fsl,imx6ull";
+
+ chosen {
+ stdout-path = &uart1;
+ };
+
+ memory {
+ reg = <0x80000000 0x40000000>;
+ };
+
+ backlight {
+ compatible = "pwm-backlight";
+ pwms = <&pwm1 0 5000000>;
+ brightness-levels = <0 4 8 16 32 64 128 255>;
+ default-brightness-level = <6>;
+ status = "disabled";
+ };
+
+ pxp_v4l2 {
+ compatible = "fsl,imx6ul-pxp-v4l2", "fsl,imx6sx-pxp-v4l2", "fsl,imx6sl-pxp-v4l2";
+ status = "okay";
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ reg_sd1_vmmc: sd1_vmmc {
+ compatible = "regulator-fixed";
+ regulator-name = "SD1_SPWR";
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ gpio = <&gpio1 9 GPIO_ACTIVE_HIGH>;
+ off-on-delay = <20000>;
+ enable-active-high;
+ };
+
+ reg_sd2_vmmc: sd2_vmmc {
+ compatible = "regulator-fixed";
+ regulator-name = "SD2_SPWR";
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ gpio = <&gpio4 10 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ reg_can2_3v3: regulator@0 {
+ compatible = "regulator-fixed";
+ reg = <0>;
+ regulator-name = "can2-3v3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&gpio1 15 GPIO_ACTIVE_LOW>;
+ };
+
+ reg_vref_3v3: regulator@1 {
+ compatible = "regulator-fixed";
+ regulator-name = "vref-3v3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ reg_usb_otg1_vbus: regulator@2 {
+ compatible = "regulator-fixed";
+ reg = <2>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usb_otg1>;
+ regulator-name = "usb_otg1_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&gpio1 4 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+ };
+};
+
+&clks {
+ /* For bringup, comments this.
+ assigned-clocks = <&clks IMX6UL_CLK_PLL4_AUDIO_DIV>;
+ assigned-clock-rates = <786432000>;
+ */
+};
+
+&cpu0 {
+ /*
+ * on i.MX6ULL, no seperated VDD_ARM_IN and VDD_SOC_IN,
+ * to align with other platform and use the same cpufreq
+ * driver, still use the seperated OPP define for arm
+ * and soc.
+ */
+ operating-points = <
+ /* kHz uV */
+ 528000 1175000
+ 396000 1175000
+ 198000 1175000
+ >;
+ fsl,soc-operating-points = <
+ /* KHz uV */
+ 528000 1175000
+ 396000 1175000
+ 198000 1175000
+ >;
+ fsl,arm-soc-shared = <1>;
+};
+
+&reg_arm {
+ vin-supply = <&sw1a_reg>;
+ regulator-allow-bypass;
+};
+
+&reg_soc {
+ vin-supply = <&sw1a_reg>;
+ regulator-allow-bypass;
+};
+
+&csi {
+ status = "okay";
+
+ port {
+ csi1_ep: endpoint {
+ remote-endpoint = <&ov5640_ep>;
+ };
+ };
+};
+
+&ecspi1 {
+ fsl,spi-num-chipselects = <1>;
+ cs-gpios = <&gpio4 26 0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ecspi1_1 &pinctrl_ecspi1_cs_1>;
+ status = "disabled";
+
+ flash: n25q032@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "st,n25q032";
+ spi-max-frequency = <20000000>;
+ reg = <0>;
+ };
+};
+
+&epdc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_epdc0>;
+ V3P3-supply = <&V3P3_reg>;
+ VCOM-supply = <&VCOM_reg>;
+ DISPLAY-supply = <&DISPLAY_reg>;
+ status = "disabled";
+};
+
+&fec1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_enet1>;
+ phy-mode = "rmii";
+ phy-handle = <&ethphy0>;
+ status = "okay";
+};
+
+&fec2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_enet2>;
+ phy-mode = "mii";
+ phy-handle = <&ethphy1>;
+ status = "okay";
+
+ mdio {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ethphy0: ethernet-phy@1 {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <1>;
+ };
+
+ ethphy1: ethernet-phy@2 {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <2>;
+ };
+ };
+};
+
+&flexcan2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_flexcan2>;
+ xceiver-supply = <&reg_can2_3v3>;
+ status = "disabled";
+};
+
+&gpc {
+ fsl,cpu_pupscr_sw2iso = <0xf>;
+ fsl,cpu_pupscr_sw = <0x0>;
+ fsl,cpu_pdnscr_iso2sw = <0x1>;
+ fsl,cpu_pdnscr_iso = <0x1>;
+ fsl,ldo-bypass = <1>; /* use ldo-bypass, u-boot will check it and configure */
+};
+
+&gpmi {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpmi_nand_1>;
+ status = "disabled";
+ nand-on-flash-bbt;
+};
+
+&i2c1 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c1>;
+ status = "okay";
+
+ pmic: pfuze100@08 {
+ compatible = "fsl,pfuze200";
+ reg = <0x08>;
+
+ regulators {
+ sw1a_reg: sw1ab {
+ regulator-min-microvolt = <300000>;
+ regulator-max-microvolt = <1875000>;
+ regulator-always-on;
+ regulator-ramp-delay = <6250>;
+ };
+
+ sw2_reg: sw2 {
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ sw3a_reg: sw3a {
+ regulator-min-microvolt = <400000>;
+ regulator-max-microvolt = <1975000>;
+ regulator-always-on;
+ };
+
+ sw3b_reg: sw3b {
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ swbst_reg: swbst {
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5150000>;
+ };
+
+ snvs_reg: vsnvs {
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-always-on;
+ };
+
+ vref_reg: vrefddr {
+ regulator-always-on;
+ };
+
+ vgen1_reg: vgen1 {
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1550000>;
+ };
+
+ vgen2_reg: vgen2 {
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1550000>;
+ };
+
+ vgen3_reg: vgen3 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ vgen4_reg: vgen4 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ vgen5_reg: vgen5 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ vgen6_reg: vgen6 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+ };
+ };
+
+
+ ov5640: ov5640@3c {
+ compatible = "ovti,ov5640";
+ reg = <0x3c>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_csi1>;
+ clocks = <&clks IMX6UL_CLK_CSI>;
+ clock-names = "csi_mclk";
+ AVDD-supply = <&vgen3_reg>; /* 2.8v */
+ DVDD-supply = <&vgen2_reg>; /* 1.5v*/
+ pwn-gpios = <&gpio5 8 1>;
+ rst-gpios = <&gpio5 7 0>;
+ csi_id = <0>;
+ mclk = <24000000>;
+ mclk_source = <0>;
+ status = "okay";
+ port {
+ ov5640_ep: endpoint {
+ remote-endpoint = <&csi1_ep>;
+ };
+ };
+ };
+};
+
+&i2c4 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c4>;
+ status = "okay";
+
+ max17135: max17135@48 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_max17135>;
+ compatible = "maxim,max17135";
+ reg = <0x48>;
+ status = "disabled";
+
+ vneg_pwrup = <1>;
+ gvee_pwrup = <2>;
+ vpos_pwrup = <10>;
+ gvdd_pwrup = <12>;
+ gvdd_pwrdn = <1>;
+ vpos_pwrdn = <2>;
+ gvee_pwrdn = <8>;
+ vneg_pwrdn = <10>;
+ gpio_pmic_pwrgood = <&gpio3 16 0>;
+ gpio_pmic_vcom_ctrl = <&gpio3 24 0>;
+ gpio_pmic_wakeup = <&gpio3 14 0>;
+ gpio_pmic_v3p3 = <&gpio3 17 0>;
+ gpio_pmic_intr = <&gpio3 13 0>;
+
+ regulators {
+ DISPLAY_reg: DISPLAY {
+ regulator-name = "DISPLAY";
+ };
+
+ GVDD_reg: GVDD {
+ /* 20v */
+ regulator-name = "GVDD";
+ };
+
+ GVEE_reg: GVEE {
+ /* -22v */
+ regulator-name = "GVEE";
+ };
+
+ HVINN_reg: HVINN {
+ /* -22v */
+ regulator-name = "HVINN";
+ };
+
+ HVINP_reg: HVINP {
+ /* 20v */
+ regulator-name = "HVINP";
+ };
+
+ VCOM_reg: VCOM {
+ regulator-name = "VCOM";
+ /* Real max: -500000 */
+ regulator-max-microvolt = <4325000>;
+ /* Real min: -4325000 */
+ regulator-min-microvolt = <500000>;
+ };
+
+ VNEG_reg: VNEG {
+ /* -15v */
+ regulator-name = "VNEG";
+ };
+
+ VPOS_reg: VPOS {
+ /* 15v */
+ regulator-name = "VPOS";
+ };
+
+ V3P3_reg: V3P3 {
+ regulator-name = "V3P3";
+ };
+ };
+ };
+};
+
+&iomuxc {
+ imx6ul-ddr3-arm2 {
+ pinctrl_adc1: adc1grp {
+ fsl,pins = <
+ MX6UL_PAD_GPIO1_IO00__GPIO1_IO00 0xb0
+ MX6UL_PAD_GPIO1_IO01__GPIO1_IO01 0xb0
+ >;
+ };
+
+
+ pinctrl_csi1: csi1grp {
+ fsl,pins = <
+ MX6UL_PAD_CSI_MCLK__CSI_MCLK 0x1b088
+ MX6UL_PAD_CSI_PIXCLK__CSI_PIXCLK 0x1b088
+ MX6UL_PAD_CSI_VSYNC__CSI_VSYNC 0x1b088
+ MX6UL_PAD_CSI_HSYNC__CSI_HSYNC 0x1b088
+ MX6UL_PAD_CSI_DATA00__CSI_DATA02 0x1b088
+ MX6UL_PAD_CSI_DATA01__CSI_DATA03 0x1b088
+ MX6UL_PAD_CSI_DATA02__CSI_DATA04 0x1b088
+ MX6UL_PAD_CSI_DATA03__CSI_DATA05 0x1b088
+ MX6UL_PAD_CSI_DATA04__CSI_DATA06 0x1b088
+ MX6UL_PAD_CSI_DATA05__CSI_DATA07 0x1b088
+ MX6UL_PAD_CSI_DATA06__CSI_DATA08 0x1b088
+ MX6UL_PAD_CSI_DATA07__CSI_DATA09 0x1b088
+ >;
+ };
+
+ pinctrl_ecspi1_cs_1: ecspi1_cs_grp-1 {
+ fsl,pins = <
+ MX6UL_PAD_CSI_DATA05__GPIO4_IO26 0x10b0
+ >;
+ };
+
+ pinctrl_ecspi1_1: ecspi1grp-1 {
+ fsl,pins = <
+ MX6UL_PAD_CSI_DATA06__ECSPI1_MOSI 0x10b0
+ MX6UL_PAD_CSI_DATA07__ECSPI1_MISO 0x10b0
+ MX6UL_PAD_CSI_DATA04__ECSPI1_SCLK 0x10b0
+ >;
+ };
+
+ pinctrl_enet1: enet1grp {
+ fsl,pins = <
+ MX6UL_PAD_ENET1_RX_EN__ENET1_RX_EN 0x1b0b0
+ MX6UL_PAD_ENET1_RX_ER__ENET1_RX_ER 0x1b0b0
+ MX6UL_PAD_ENET1_RX_DATA0__ENET1_RDATA00 0x1b0b0
+ MX6UL_PAD_ENET1_RX_DATA1__ENET1_RDATA01 0x1b0b0
+ MX6UL_PAD_ENET1_TX_EN__ENET1_TX_EN 0x1b0b0
+ MX6UL_PAD_ENET1_TX_DATA0__ENET1_TDATA00 0x1b0b0
+ MX6UL_PAD_ENET1_TX_DATA1__ENET1_TDATA01 0x1b0b0
+ MX6UL_PAD_ENET1_TX_CLK__ENET1_REF_CLK1 0x4001b0a0
+ >;
+ };
+
+ pinctrl_enet2: enet2grp {
+ fsl,pins = <
+ MX6UL_PAD_GPIO1_IO07__ENET2_MDC 0x1b098
+ MX6UL_PAD_GPIO1_IO06__ENET2_MDIO 0x1b0b0
+ MX6UL_PAD_ENET2_TX_DATA0__ENET2_TDATA00 0x1b0a0
+ MX6UL_PAD_ENET2_TX_DATA1__ENET2_TDATA01 0x1b0a0
+ MX6UL_PAD_UART4_TX_DATA__ENET2_TDATA02 0x1b0a0
+ MX6UL_PAD_UART4_RX_DATA__ENET2_TDATA03 0x1b0a0
+ MX6UL_PAD_ENET2_TX_CLK__ENET2_TX_CLK 0x4001b0a8
+ MX6UL_PAD_ENET2_TX_EN__ENET2_TX_EN 0x1b0b0
+ MX6UL_PAD_ENET2_RX_DATA0__ENET2_RDATA00 0x1b0b0
+ MX6UL_PAD_ENET2_RX_DATA1__ENET2_RDATA01 0x1b0b0
+ MX6UL_PAD_UART3_TX_DATA__ENET2_RDATA02 0x1b0b0
+ MX6UL_PAD_UART3_RX_DATA__ENET2_RDATA03 0x1b0b0
+ MX6UL_PAD_ENET2_RX_EN__ENET2_RX_EN 0x1b0b0
+ MX6UL_PAD_ENET2_RX_ER__ENET2_RX_ER 0x1b0b0
+ MX6UL_PAD_UART3_CTS_B__ENET2_RX_CLK 0x4001b0a8
+ MX6UL_PAD_UART5_RX_DATA__ENET2_COL 0x1b0b0
+ MX6UL_PAD_UART5_TX_DATA__ENET2_CRS 0x1b0b0
+ >;
+ };
+
+ pinctrl_epdc0: epdcgrp0 {
+ fsl,pins = <
+ MX6ULL_PAD_ENET2_RX_DATA0__EPDC_SDDO08 0x10b1
+ MX6ULL_PAD_ENET2_RX_DATA1__EPDC_SDDO09 0x10b1
+ MX6ULL_PAD_ENET2_RX_EN__EPDC_SDDO10 0x10b1
+ MX6ULL_PAD_ENET2_TX_DATA0__EPDC_SDDO11 0x10b1
+ MX6ULL_PAD_ENET2_TX_DATA1__EPDC_SDDO12 0x10b1
+ MX6ULL_PAD_ENET2_TX_EN__EPDC_SDDO13 0x10b1
+ MX6ULL_PAD_ENET2_TX_CLK__EPDC_SDDO14 0x10b1
+ MX6ULL_PAD_ENET2_RX_ER__EPDC_SDDO15 0x10b1
+ MX6ULL_PAD_LCD_CLK__EPDC_SDCLK 0x10b1
+ MX6ULL_PAD_LCD_ENABLE__EPDC_SDLE 0x10b1
+ MX6ULL_PAD_LCD_HSYNC__EPDC_SDOE 0x10b1
+ MX6ULL_PAD_LCD_VSYNC__EPDC_SDCE0 0x10b1
+ MX6ULL_PAD_LCD_DATA00__EPDC_SDDO00 0x10b1
+ MX6ULL_PAD_LCD_DATA01__EPDC_SDDO01 0x10b1
+ MX6ULL_PAD_LCD_DATA02__EPDC_SDDO02 0x10b1
+ MX6ULL_PAD_LCD_DATA03__EPDC_SDDO03 0x10b1
+ MX6ULL_PAD_LCD_DATA04__EPDC_SDDO04 0x10b1
+ MX6ULL_PAD_LCD_DATA05__EPDC_SDDO05 0x10b1
+ MX6ULL_PAD_LCD_DATA06__EPDC_SDDO06 0x10b1
+ MX6ULL_PAD_LCD_DATA07__EPDC_SDDO07 0x10b1
+ MX6ULL_PAD_LCD_DATA14__EPDC_SDSHR 0x10b1
+ MX6ULL_PAD_LCD_DATA15__EPDC_GDRL 0x10b1
+ MX6ULL_PAD_LCD_DATA16__EPDC_GDCLK 0x10b1
+ MX6ULL_PAD_LCD_DATA17__EPDC_GDSP 0x10b1
+ MX6ULL_PAD_LCD_RESET__EPDC_GDOE 0x10b1
+ >;
+ };
+
+ pinctrl_esai: esaigrp {
+ fsl,pins = <
+ MX6ULL_PAD_CSI_DATA00__ESAI_TX_HF_CLK 0x1b0b0
+ MX6ULL_PAD_CSI_DATA01__ESAI_RX_HF_CLK 0x1b0b0
+ MX6ULL_PAD_CSI_DATA04__ESAI_TX_FS 0x1b0b0
+ MX6ULL_PAD_CSI_DATA05__ESAI_TX_CLK 0x1b0b0
+ MX6ULL_PAD_CSI_DATA07__ESAI_T0 0x1b0b0
+ MX6ULL_PAD_CSI_HSYNC__ESAI_TX1 0x1b0b0
+ MX6ULL_PAD_CSI_PIXCLK__ESAI_TX2_RX3 0x1b0b0
+ MX6ULL_PAD_CSI_MCLK__ESAI_TX3_RX2 0x1b0b0
+ MX6ULL_PAD_CSI_DATA02__ESAI_RX_FS 0x1b0b0
+ MX6ULL_PAD_CSI_DATA03__ESAI_RX_CLK 0x1b0b0
+ MX6ULL_PAD_CSI_DATA06__ESAI_TX5_RX0 0x1b0b0
+ MX6ULL_PAD_CSI_VSYNC__ESAI_TX4_RX1 0x1b0b0
+ >;
+ };
+
+ pinctrl_flexcan2: flexcan2grp{
+ fsl,pins = <
+ MX6UL_PAD_UART2_RTS_B__FLEXCAN2_RX 0x1b020
+ MX6UL_PAD_UART2_CTS_B__FLEXCAN2_TX 0x1b020
+ MX6UL_PAD_JTAG_TRST_B__GPIO1_IO15 0x17059 /* STBY */
+ >;
+ };
+
+ pinctrl_gpmi_nand_1: gpmi-nand-1 {
+ fsl,pins = <
+ MX6UL_PAD_NAND_CLE__RAWNAND_CLE 0xb0b1
+ MX6UL_PAD_NAND_ALE__RAWNAND_ALE 0xb0b1
+ MX6UL_PAD_NAND_WP_B__RAWNAND_WP_B 0xb0b1
+ MX6UL_PAD_NAND_READY_B__RAWNAND_READY_B 0xb000
+ MX6UL_PAD_NAND_CE0_B__RAWNAND_CE0_B 0xb0b1
+ MX6UL_PAD_NAND_CE1_B__RAWNAND_CE1_B 0xb0b1
+ MX6UL_PAD_NAND_RE_B__RAWNAND_RE_B 0xb0b1
+ MX6UL_PAD_NAND_WE_B__RAWNAND_WE_B 0xb0b1
+ MX6UL_PAD_NAND_DATA00__RAWNAND_DATA00 0xb0b1
+ MX6UL_PAD_NAND_DATA01__RAWNAND_DATA01 0xb0b1
+ MX6UL_PAD_NAND_DATA02__RAWNAND_DATA02 0xb0b1
+ MX6UL_PAD_NAND_DATA03__RAWNAND_DATA03 0xb0b1
+ MX6UL_PAD_NAND_DATA04__RAWNAND_DATA04 0xb0b1
+ MX6UL_PAD_NAND_DATA05__RAWNAND_DATA05 0xb0b1
+ MX6UL_PAD_NAND_DATA06__RAWNAND_DATA06 0xb0b1
+ MX6UL_PAD_NAND_DATA07__RAWNAND_DATA07 0xb0b1
+ >;
+ };
+
+ pinctrl_i2c1: i2c1grp {
+ fsl,pins = <
+ MX6UL_PAD_GPIO1_IO03__I2C1_SDA 0x4001b8b1
+ MX6UL_PAD_GPIO1_IO02__I2C1_SCL 0x4001b8b1
+ >;
+ };
+
+ pinctrl_i2c4: i2c4grp {
+ fsl,pins = <
+ MX6UL_PAD_UART2_TX_DATA__I2C4_SCL 0x4001b8b0
+ MX6UL_PAD_UART2_RX_DATA__I2C4_SDA 0x4001b8b0
+ >;
+ };
+
+ pinctrl_lcdif_dat: lcdifdatgrp {
+ fsl,pins = <
+ MX6UL_PAD_LCD_DATA00__LCDIF_DATA00 0x79
+ MX6UL_PAD_LCD_DATA01__LCDIF_DATA01 0x79
+ MX6UL_PAD_LCD_DATA02__LCDIF_DATA02 0x79
+ MX6UL_PAD_LCD_DATA03__LCDIF_DATA03 0x79
+ MX6UL_PAD_LCD_DATA04__LCDIF_DATA04 0x79
+ MX6UL_PAD_LCD_DATA05__LCDIF_DATA05 0x79
+ MX6UL_PAD_LCD_DATA06__LCDIF_DATA06 0x79
+ MX6UL_PAD_LCD_DATA07__LCDIF_DATA07 0x79
+ MX6UL_PAD_LCD_DATA08__LCDIF_DATA08 0x79
+ MX6UL_PAD_LCD_DATA09__LCDIF_DATA09 0x79
+ MX6UL_PAD_LCD_DATA10__LCDIF_DATA10 0x79
+ MX6UL_PAD_LCD_DATA11__LCDIF_DATA11 0x79
+ MX6UL_PAD_LCD_DATA12__LCDIF_DATA12 0x79
+ MX6UL_PAD_LCD_DATA13__LCDIF_DATA13 0x79
+ MX6UL_PAD_LCD_DATA14__LCDIF_DATA14 0x79
+ MX6UL_PAD_LCD_DATA15__LCDIF_DATA15 0x79
+ MX6UL_PAD_LCD_DATA16__LCDIF_DATA16 0x79
+ MX6UL_PAD_LCD_DATA17__LCDIF_DATA17 0x79
+ MX6UL_PAD_LCD_DATA18__LCDIF_DATA18 0x79
+ MX6UL_PAD_LCD_DATA19__LCDIF_DATA19 0x79
+ MX6UL_PAD_LCD_DATA20__LCDIF_DATA20 0x79
+ MX6UL_PAD_LCD_DATA21__LCDIF_DATA21 0x79
+ MX6UL_PAD_LCD_DATA22__LCDIF_DATA22 0x79
+ MX6UL_PAD_LCD_DATA23__LCDIF_DATA23 0x79
+ >;
+ };
+
+ pinctrl_lcdif_ctrl: lcdifctrlgrp {
+ fsl,pins = <
+ MX6UL_PAD_LCD_CLK__LCDIF_CLK 0x79
+ MX6UL_PAD_LCD_ENABLE__LCDIF_ENABLE 0x79
+ MX6UL_PAD_LCD_HSYNC__LCDIF_HSYNC 0x79
+ MX6UL_PAD_LCD_VSYNC__LCDIF_VSYNC 0x79
+ MX6UL_PAD_LCD_RESET__LCDIF_RESET 0x79
+ >;
+ };
+
+ pinctrl_max17135: max17135grp-1 {
+ fsl,pins = <
+ MX6UL_PAD_LCD_DATA11__GPIO3_IO16 0x80000000 /* pwrgood */
+ MX6UL_PAD_LCD_DATA19__GPIO3_IO24 0x80000000 /* vcom_ctrl */
+ MX6UL_PAD_LCD_DATA09__GPIO3_IO14 0x80000000 /* wakeup */
+ MX6UL_PAD_LCD_DATA12__GPIO3_IO17 0x80000000 /* v3p3 */
+ MX6UL_PAD_LCD_DATA08__GPIO3_IO13 0x80000000 /* pwr int */
+ >;
+ };
+
+ pinctrl_mqs: mqsgrp {
+ fsl,pins = <
+ MX6UL_PAD_JTAG_TDI__MQS_LEFT 0x11088
+ MX6UL_PAD_JTAG_TDO__MQS_RIGHT 0x11088
+ >;
+ };
+
+ pinctrl_pwm1: pmw1grp {
+ fsl,pins = <
+ MX6UL_PAD_ENET1_RX_DATA0__PWM1_OUT 0x110b0
+ >;
+ };
+
+ pinctrl_qspi: qspigrp {
+ fsl,pins = <
+ MX6UL_PAD_NAND_WP_B__QSPI_A_SCLK 0x70a1
+ MX6UL_PAD_NAND_READY_B__QSPI_A_DATA00 0x70a1
+ MX6UL_PAD_NAND_CE0_B__QSPI_A_DATA01 0x70a1
+ MX6UL_PAD_NAND_CE1_B__QSPI_A_DATA02 0x70a1
+ MX6UL_PAD_NAND_CLE__QSPI_A_DATA03 0x70a1
+ MX6UL_PAD_NAND_DQS__QSPI_A_SS0_B 0x70a1
+#ifdef REWORKED_ENABLE_ALL_QSPI
+ MX6UL_PAD_NAND_DATA07__QSPI_A_SS1_B 0x70a1
+ MX6UL_PAD_NAND_RE_B__QSPI_B_SCLK 0x70a1
+ MX6UL_PAD_NAND_DATA02__QSPI_B_DATA00 0x70a1
+ MX6UL_PAD_NAND_DATA03__QSPI_B_DATA01 0x70a1
+ MX6UL_PAD_NAND_DATA04__QSPI_B_DATA02 0x70a1
+ MX6UL_PAD_NAND_DATA05__QSPI_B_DATA03 0x70a1
+ MX6UL_PAD_NAND_WE_B__QSPI_B_SS0_B 0x70a1
+ MX6UL_PAD_NAND_DATA00__QSPI_B_SS1_B 0x70a1
+#endif
+ >;
+ };
+
+ pinctrl_sai2: sai2grp {
+ fsl,pins = <
+ MX6UL_PAD_SD1_DATA0__SAI2_TX_SYNC 0x1b0b0
+ MX6UL_PAD_SD1_DATA1__SAI2_TX_BCLK 0x1b0b0
+ MX6UL_PAD_SD1_DATA2__SAI2_RX_DATA 0x110b0
+ MX6UL_PAD_SD1_DATA3__SAI2_TX_DATA 0x110b0
+ MX6UL_PAD_SD1_CLK__SAI2_MCLK 0x1b0b0
+ >;
+ };
+
+ pinctrl_spdif: spdifgrp {
+ fsl,pins = <
+ MX6UL_PAD_GPIO1_IO08__SPDIF_OUT 0x1b0b0
+ MX6UL_PAD_GPIO1_IO09__SPDIF_IN 0x1b0b0
+ >;
+ };
+
+ pinctrl_tsc: tscgrp {
+ fsl,pins = <
+ MX6UL_PAD_GPIO1_IO01__GPIO1_IO01 0xb0
+ MX6UL_PAD_GPIO1_IO02__GPIO1_IO02 0xb0
+ MX6UL_PAD_GPIO1_IO03__GPIO1_IO03 0xb0
+ MX6UL_PAD_GPIO1_IO04__GPIO1_IO04 0xb0
+ >;
+ };
+
+ pinctrl_uart1: uart1grp {
+ fsl,pins = <
+ MX6UL_PAD_UART1_TX_DATA__UART1_DCE_TX 0x1b0b1
+ MX6UL_PAD_UART1_RX_DATA__UART1_DCE_RX 0x1b0b1
+ >;
+ };
+
+ pinctrl_uart2: uart2grp {
+ fsl,pins = <
+ MX6UL_PAD_UART2_TX_DATA__UART2_DCE_TX 0x1b0b1
+ MX6UL_PAD_UART2_RX_DATA__UART2_DCE_RX 0x1b0b1
+ MX6UL_PAD_UART2_CTS_B__UART2_DCE_CTS 0x1b0b1
+ MX6UL_PAD_UART2_RTS_B__UART2_DCE_RTS 0x1b0b1
+ >;
+ };
+
+ pinctrl_uart2dte: uart2dtegrp {
+ fsl,pins = <
+ MX6UL_PAD_UART2_TX_DATA__UART2_DTE_RX 0x1b0b1
+ MX6UL_PAD_UART2_RX_DATA__UART2_DTE_TX 0x1b0b1
+ MX6UL_PAD_UART2_CTS_B__UART2_DTE_RTS 0x1b0b1
+ MX6UL_PAD_UART2_RTS_B__UART2_DTE_CTS 0x1b0b1
+ >;
+ };
+
+ pinctrl_usb_otg1_id: usbotg1idgrp {
+ fsl,pins = <
+ MX6UL_PAD_GPIO1_IO00__ANATOP_OTG1_ID 0x17059
+ >;
+ };
+
+ pinctrl_usb_otg1: usbotg1grp {
+ fsl,pins = <
+ MX6UL_PAD_GPIO1_IO04__GPIO1_IO04 0x10b0
+ >;
+ };
+
+ pinctrl_usdhc1: usdhc1grp {
+ fsl,pins = <
+ MX6UL_PAD_SD1_CMD__USDHC1_CMD 0x17059
+ MX6UL_PAD_SD1_CLK__USDHC1_CLK 0x10059
+ MX6UL_PAD_SD1_DATA0__USDHC1_DATA0 0x17059
+ MX6UL_PAD_SD1_DATA1__USDHC1_DATA1 0x17059
+ MX6UL_PAD_SD1_DATA2__USDHC1_DATA2 0x17059
+ MX6UL_PAD_SD1_DATA3__USDHC1_DATA3 0x17059
+ >;
+ };
+
+ pinctrl_usdhc1_100mhz: usdhc1grp100mhz {
+ fsl,pins = <
+ MX6UL_PAD_SD1_CMD__USDHC1_CMD 0x170b9
+ MX6UL_PAD_SD1_CLK__USDHC1_CLK 0x100b9
+ MX6UL_PAD_SD1_DATA0__USDHC1_DATA0 0x170b9
+ MX6UL_PAD_SD1_DATA1__USDHC1_DATA1 0x170b9
+ MX6UL_PAD_SD1_DATA2__USDHC1_DATA2 0x170b9
+ MX6UL_PAD_SD1_DATA3__USDHC1_DATA3 0x170b9
+ >;
+ };
+
+ pinctrl_usdhc1_200mhz: usdhc1grp200mhz {
+ fsl,pins = <
+ MX6UL_PAD_SD1_CMD__USDHC1_CMD 0x170f9
+ MX6UL_PAD_SD1_CLK__USDHC1_CLK 0x100f9
+ MX6UL_PAD_SD1_DATA0__USDHC1_DATA0 0x170f9
+ MX6UL_PAD_SD1_DATA1__USDHC1_DATA1 0x170f9
+ MX6UL_PAD_SD1_DATA2__USDHC1_DATA2 0x170f9
+ MX6UL_PAD_SD1_DATA3__USDHC1_DATA3 0x170f9
+ >;
+ };
+
+ pinctrl_usdhc1_8bit: usdhc1_8bit_grp {
+ fsl,pins = <
+ MX6UL_PAD_SD1_CMD__USDHC1_CMD 0x17059
+ MX6UL_PAD_SD1_CLK__USDHC1_CLK 0x10059
+ MX6UL_PAD_SD1_DATA0__USDHC1_DATA0 0x17059
+ MX6UL_PAD_SD1_DATA1__USDHC1_DATA1 0x17059
+ MX6UL_PAD_SD1_DATA2__USDHC1_DATA2 0x17059
+ MX6UL_PAD_SD1_DATA3__USDHC1_DATA3 0x17059
+ MX6UL_PAD_NAND_READY_B__USDHC1_DATA4 0x17059
+ MX6UL_PAD_NAND_CE0_B__USDHC1_DATA5 0x17059
+ MX6UL_PAD_NAND_CE1_B__USDHC1_DATA6 0x17059
+ MX6UL_PAD_NAND_CLE__USDHC1_DATA7 0x17059
+ >;
+ };
+
+ pinctrl_usdhc1_8bit_100mhz: usdhc1_8bit_100mhz_grp {
+ fsl,pins = <
+ MX6UL_PAD_SD1_CMD__USDHC1_CMD 0x170b9
+ MX6UL_PAD_SD1_CLK__USDHC1_CLK 0x100b9
+ MX6UL_PAD_SD1_DATA0__USDHC1_DATA0 0x170b9
+ MX6UL_PAD_SD1_DATA1__USDHC1_DATA1 0x170b9
+ MX6UL_PAD_SD1_DATA2__USDHC1_DATA2 0x170b9
+ MX6UL_PAD_SD1_DATA3__USDHC1_DATA3 0x170b9
+ MX6UL_PAD_NAND_READY_B__USDHC1_DATA4 0x170b9
+ MX6UL_PAD_NAND_CE0_B__USDHC1_DATA5 0x170b9
+ MX6UL_PAD_NAND_CE1_B__USDHC1_DATA6 0x170b9
+ MX6UL_PAD_NAND_CLE__USDHC1_DATA7 0x170b9
+ >;
+ };
+
+ pinctrl_usdhc1_8bit_200mhz: usdhc1_8bit_200mhz_grp {
+ fsl,pins = <
+ MX6UL_PAD_SD1_CMD__USDHC1_CMD 0x170f9
+ MX6UL_PAD_SD1_CLK__USDHC1_CLK 0x100f9
+ MX6UL_PAD_SD1_DATA0__USDHC1_DATA0 0x170f9
+ MX6UL_PAD_SD1_DATA1__USDHC1_DATA1 0x170f9
+ MX6UL_PAD_SD1_DATA2__USDHC1_DATA2 0x170f9
+ MX6UL_PAD_SD1_DATA3__USDHC1_DATA3 0x170f9
+ MX6UL_PAD_NAND_READY_B__USDHC1_DATA4 0x170f9
+ MX6UL_PAD_NAND_CE0_B__USDHC1_DATA5 0x170f9
+ MX6UL_PAD_NAND_CE1_B__USDHC1_DATA6 0x170f9
+ MX6UL_PAD_NAND_CLE__USDHC1_DATA7 0x170f9
+ >;
+ };
+
+ pinctrl_usdhc1_cd_wp: usdhc1_cd_wp_grp {
+ fsl,pins = <
+ MX6UL_PAD_UART1_RTS_B__GPIO1_IO19 0x17059 /* SD1 CD */
+ MX6UL_PAD_UART1_CTS_B__GPIO1_IO18 0x17059 /* SD1 WP */
+ >;
+ };
+
+ pinctrl_usdhc1_rst: usdhc1_rst_grp {
+ fsl,pins = <
+ MX6UL_PAD_GPIO1_IO09__GPIO1_IO09 0x17059 /* SD1 RESET */
+ >;
+ };
+
+ pinctrl_usdhc1_vselect: usdhc1_vselect_grp {
+ fsl,pins = <
+ MX6UL_PAD_GPIO1_IO05__USDHC1_VSELECT 0x17059 /* SD1 VSELECT */
+ >;
+ };
+
+ pinctrl_usdhc2: usdhc2grp {
+ fsl,pins = <
+ MX6UL_PAD_NAND_WE_B__USDHC2_CMD 0x17059
+ MX6UL_PAD_NAND_RE_B__USDHC2_CLK 0x10059
+ MX6UL_PAD_NAND_DATA00__USDHC2_DATA0 0x17059
+ MX6UL_PAD_NAND_DATA01__USDHC2_DATA1 0x17059
+ MX6UL_PAD_NAND_DATA02__USDHC2_DATA2 0x17059
+ MX6UL_PAD_NAND_DATA03__USDHC2_DATA3 0x17059
+ >;
+ };
+
+ pinctrl_usdhc2_100mhz: usdhc2grp100mhz {
+ fsl,pins = <
+ MX6UL_PAD_NAND_WE_B__USDHC2_CMD 0x170b9
+ MX6UL_PAD_NAND_RE_B__USDHC2_CLK 0x100a9
+ MX6UL_PAD_NAND_DATA00__USDHC2_DATA0 0x170a9
+ MX6UL_PAD_NAND_DATA01__USDHC2_DATA1 0x170a9
+ MX6UL_PAD_NAND_DATA02__USDHC2_DATA2 0x170a9
+ MX6UL_PAD_NAND_DATA03__USDHC2_DATA3 0x170a9
+ >;
+ };
+
+ pinctrl_usdhc2_200mhz: usdhc2grp200mhz {
+ fsl,pins = <
+ MX6UL_PAD_NAND_WE_B__USDHC2_CMD 0x170f9
+ MX6UL_PAD_NAND_RE_B__USDHC2_CLK 0x100f9
+ MX6UL_PAD_NAND_DATA00__USDHC2_DATA0 0x170f9
+ MX6UL_PAD_NAND_DATA01__USDHC2_DATA1 0x170f9
+ MX6UL_PAD_NAND_DATA02__USDHC2_DATA2 0x170f9
+ MX6UL_PAD_NAND_DATA03__USDHC2_DATA3 0x170f9
+ >;
+ };
+
+ pinctrl_usdhc2_rst: usdhc2_rst_grp {
+ fsl,pins = <
+ MX6UL_PAD_NAND_ALE__GPIO4_IO10 0x17059 /* SD2 RESET */
+ >;
+ };
+
+ pinctrl_wdog: wdoggrp {
+ fsl,pins = <
+ MX6UL_PAD_GPIO1_IO08__WDOG1_WDOG_B 0x30b0
+ >;
+ };
+ };
+};
+
+&iomuxc_snvs {
+ imx6ul-ddr3-arm2 {
+ pinctrl_bt: btgrp {
+ fsl,pins = <
+ MX6ULL_PAD_SNVS_TAMPER6__GPIO5_IO06 0x80000000
+ MX6ULL_PAD_SNVS_TAMPER9__GPIO5_IO09 0x80000000
+ MX6ULL_PAD_SNVS_TAMPER5__GPIO5_IO05 0x80000000
+ >;
+ };
+
+ pinctrl_sai2_hp_det_b: sai2_hp_det_grp {
+ fsl,pins = <
+ MX6ULL_PAD_SNVS_TAMPER0__GPIO5_IO00 0x17059
+ >;
+ };
+ };
+};
+
+&lcdif {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lcdif_dat
+ &pinctrl_lcdif_ctrl>;
+ display = <&display0>;
+ status = "disabled";
+
+ display0: display {
+ bits-per-pixel = <16>;
+ bus-width = <24>;
+
+ display-timings {
+ native-mode = <&timing0>;
+ timing0: timing0 {
+ clock-frequency = <33500000>;
+ hactive = <800>;
+ vactive = <480>;
+ hback-porch = <89>;
+ hfront-porch = <164>;
+ vback-porch = <23>;
+ vfront-porch = <10>;
+ hsync-len = <10>;
+ vsync-len = <10>;
+ hsync-active = <0>;
+ vsync-active = <0>;
+ de-active = <1>;
+ pixelclk-active = <0>;
+ };
+ };
+ };
+};
+
+&pwm1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pwm1>;
+ status = "disabled";
+};
+
+&pxp {
+ status = "okay";
+};
+
+&qspi {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_qspi>;
+ status = "okay";
+#ifdef REWORKED_ENABLE_ALL_QSPI
+ fsl,qspi-has-second-chip = <1>;
+#endif
+ ddrsmp=<0>;
+
+ flash0: n25q256a@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "micron,n25q256a";
+ spi-max-frequency = <29000000>;
+ spi-nor,ddr-quad-read-dummy = <6>;
+ reg = <0>;
+ };
+
+#ifdef REWORKED_ENABLE_ALL_QSPI
+
+ flash1: n25q256a@1 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "micron,n25q256a";
+ spi-max-frequency = <29000000>;
+ spi-nor,ddr-quad-read-dummy = <6>;
+ reg = <1>;
+ };
+
+ flash2: n25q256a@2 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "micron,n25q256a";
+ spi-max-frequency = <29000000>;
+ spi-nor,ddr-quad-read-dummy = <6>;
+ reg = <2>;
+ };
+
+ flash3: n25q256a@3 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "micron,n25q256a";
+ spi-max-frequency = <29000000>;
+ spi-nor,ddr-quad-read-dummy = <6>;
+ reg = <3>;
+ };
+#endif
+};
+
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart1>;
+ status = "okay";
+};
+
+&uart2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart2
+ &pinctrl_bt>;
+ fsl,uart-has-rtscts;
+ /* for DTE mode, add below change */
+ /* fsl,dte-mode; */
+ /* pinctrl-0 = <&pinctrl_uart2dte>; */
+ status = "disabled";
+};
+
+&usbotg1 {
+ vbus-supply = <&reg_usb_otg1_vbus>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usb_otg1_id>;
+ srp-disable;
+ hnp-disable;
+ adp-disable;
+ status = "okay";
+};
+
+&usdhc1 {
+ pinctrl-names = "default", "state_100mhz", "state_200mhz";
+ pinctrl-0 = <&pinctrl_usdhc1>, <&pinctrl_usdhc1_cd_wp>, <&pinctrl_usdhc1_rst>, <&pinctrl_usdhc1_vselect>;
+ pinctrl-1 = <&pinctrl_usdhc1_100mhz>, <&pinctrl_usdhc1_cd_wp>, <&pinctrl_usdhc1_rst>, <&pinctrl_usdhc1_vselect>;
+ pinctrl-2 = <&pinctrl_usdhc1_200mhz>, <&pinctrl_usdhc1_cd_wp>, <&pinctrl_usdhc1_rst>, <&pinctrl_usdhc1_vselect>;
+ cd-gpios = <&gpio1 19 GPIO_ACTIVE_LOW>;
+ wp-gpios = <&gpio1 18 GPIO_ACTIVE_HIGH>;
+ keep-power-in-suspend;
+ enable-sdio-wakeup;
+ vmmc-supply = <&reg_sd1_vmmc>;
+ status = "okay";
+};
+
+&usdhc2 {
+ pinctrl-names = "default", "state_100mhz", "state_200mhz";
+ pinctrl-0 = <&pinctrl_usdhc2>, <&pinctrl_usdhc2_rst>;
+ pinctrl-1 = <&pinctrl_usdhc2_100mhz>, <&pinctrl_usdhc2_rst>;
+ pinctrl-2 = <&pinctrl_usdhc2_200mhz>, <&pinctrl_usdhc2_rst>;
+ non-removable;
+ no-1-8-v; /* VSELECT not connected by default */
+ keep-power-in-suspend;
+ enable-sdio-wakeup;
+ vmmc-supply = <&reg_sd2_vmmc>;
+ status = "okay";
+};
+
+&wdog1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_wdog>;
+ fsl,ext-reset-output;
+};
diff --git a/arch/arm/boot/dts/imx6ull-14x14-evk-btwifi-oob.dts b/arch/arm/boot/dts/imx6ull-14x14-evk-btwifi-oob.dts
new file mode 100644
index 000000000000..85ea147de16f
--- /dev/null
+++ b/arch/arm/boot/dts/imx6ull-14x14-evk-btwifi-oob.dts
@@ -0,0 +1,10 @@
+/*
+ * Copyright (C) 2017 NXP
+ *
+ * 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 "imx6ull-14x14-evk-btwifi.dts"
+#include "imx6ul-evk-btwifi-oob.dtsi"
diff --git a/arch/arm/boot/dts/imx6ull-14x14-evk-btwifi.dts b/arch/arm/boot/dts/imx6ull-14x14-evk-btwifi.dts
new file mode 100644
index 000000000000..8a0a85d2e197
--- /dev/null
+++ b/arch/arm/boot/dts/imx6ull-14x14-evk-btwifi.dts
@@ -0,0 +1,10 @@
+/*
+ * Copyright (C) 2016 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 "imx6ull-14x14-evk.dts"
+#include "imx6ul-evk-btwifi.dtsi"
diff --git a/arch/arm/boot/dts/imx6ull-14x14-evk-emmc.dts b/arch/arm/boot/dts/imx6ull-14x14-evk-emmc.dts
new file mode 100644
index 000000000000..4ea3d91e2cb6
--- /dev/null
+++ b/arch/arm/boot/dts/imx6ull-14x14-evk-emmc.dts
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2016 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 "imx6ull-14x14-evk.dts"
+
+&usdhc2 {
+ pinctrl-names = "default", "state_100mhz", "state_200mhz";
+ pinctrl-0 = <&pinctrl_usdhc2_8bit>;
+ pinctrl-1 = <&pinctrl_usdhc2_8bit_100mhz>;
+ pinctrl-2 = <&pinctrl_usdhc2_8bit_200mhz>;
+ bus-width = <8>;
+ non-removable;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx6ull-14x14-evk-gpmi-weim.dts b/arch/arm/boot/dts/imx6ull-14x14-evk-gpmi-weim.dts
new file mode 100644
index 000000000000..924696ee6d7d
--- /dev/null
+++ b/arch/arm/boot/dts/imx6ull-14x14-evk-gpmi-weim.dts
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2016 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 "imx6ull-14x14-evk.dts"
+
+&gpmi {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpmi_nand_1>;
+ status = "okay";
+ nand-on-flash-bbt;
+};
+
+&iomuxc {
+ imx6ull-evk-gpmi-rework {
+ pinctrl_gpmi_nand_1: gpmi-nand-1 {
+ fsl,pins = <
+ MX6UL_PAD_NAND_CLE__RAWNAND_CLE 0xb0b1
+ MX6UL_PAD_NAND_ALE__RAWNAND_ALE 0xb0b1
+ MX6UL_PAD_NAND_WP_B__RAWNAND_WP_B 0xb0b1
+ MX6UL_PAD_NAND_READY_B__RAWNAND_READY_B 0xb000
+ MX6UL_PAD_NAND_CE0_B__RAWNAND_CE0_B 0xb0b1
+ MX6UL_PAD_NAND_CE1_B__RAWNAND_CE1_B 0xb0b1
+ MX6UL_PAD_NAND_RE_B__RAWNAND_RE_B 0xb0b1
+ MX6UL_PAD_NAND_WE_B__RAWNAND_WE_B 0xb0b1
+ MX6UL_PAD_NAND_DATA00__RAWNAND_DATA00 0xb0b1
+ MX6UL_PAD_NAND_DATA01__RAWNAND_DATA01 0xb0b1
+ MX6UL_PAD_NAND_DATA02__RAWNAND_DATA02 0xb0b1
+ MX6UL_PAD_NAND_DATA03__RAWNAND_DATA03 0xb0b1
+ MX6UL_PAD_NAND_DATA04__RAWNAND_DATA04 0xb0b1
+ MX6UL_PAD_NAND_DATA05__RAWNAND_DATA05 0xb0b1
+ MX6UL_PAD_NAND_DATA06__RAWNAND_DATA06 0xb0b1
+ MX6UL_PAD_NAND_DATA07__RAWNAND_DATA07 0xb0b1
+ >;
+ };
+ };
+};
+
+&qspi {
+ status = "disabled";
+};
+
+&usdhc2 {
+ status = "disabled";
+};
diff --git a/arch/arm/boot/dts/imx6ull-14x14-evk-usb-certi.dts b/arch/arm/boot/dts/imx6ull-14x14-evk-usb-certi.dts
new file mode 100644
index 000000000000..15d9176fdd59
--- /dev/null
+++ b/arch/arm/boot/dts/imx6ull-14x14-evk-usb-certi.dts
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2016 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 file for USB Certification at i.mx6ull 14x14 evk board */
+
+#include "imx6ull-14x14-evk.dts"
+
+/ {
+ regulators {
+ reg_usb_otg2_vbus: regulator@3 {
+ compatible = "regulator-fixed";
+ reg = <3>;
+ regulator-name = "usb_otg2_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&gpio1 2 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+ };
+};
+
+&usbotg2 {
+ vbus-supply = <&reg_usb_otg2_vbus>; /* hardware rework is needed */
+ tpl-support;
+};
+
+&tsc {
+ status = "disabled";
+};
diff --git a/arch/arm/boot/dts/imx6ull-14x14-evk.dts b/arch/arm/boot/dts/imx6ull-14x14-evk.dts
index 4741871434dd..99d0046acfe9 100644
--- a/arch/arm/boot/dts/imx6ull-14x14-evk.dts
+++ b/arch/arm/boot/dts/imx6ull-14x14-evk.dts
@@ -1,52 +1,756 @@
/*
* Copyright (C) 2016 Freescale Semiconductor, Inc.
*
- * 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
- * version 2 as published by the Free Software Foundation.
- *
- * 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.
+ * 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 "imx6ul-14x14-evk.dts"
+/dts-v1/;
+
+#include <dt-bindings/input/input.h>
+#include "imx6ull.dtsi"
/ {
- model = "Freescale i.MX6 UlltraLite 14x14 EVK Board";
+ model = "Freescale i.MX6 ULL 14x14 EVK Board";
compatible = "fsl,imx6ull-14x14-evk", "fsl,imx6ull";
+
+ chosen {
+ stdout-path = &uart1;
+ };
+
+ memory {
+ reg = <0x80000000 0x20000000>;
+ };
+
+ reserved-memory {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ linux,cma {
+ compatible = "shared-dma-pool";
+ reusable;
+ size = <0x14000000>;
+ linux,cma-default;
+ };
+ };
+
+ backlight {
+ compatible = "pwm-backlight";
+ pwms = <&pwm1 0 5000000>;
+ brightness-levels = <0 4 8 16 32 64 128 255>;
+ default-brightness-level = <6>;
+ status = "okay";
+ };
+
+ pxp_v4l2 {
+ compatible = "fsl,imx6ul-pxp-v4l2", "fsl,imx6sx-pxp-v4l2", "fsl,imx6sl-pxp-v4l2";
+ status = "okay";
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ reg_can_3v3: regulator@0 {
+ compatible = "regulator-fixed";
+ reg = <0>;
+ regulator-name = "can-3v3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpios = <&gpio_spi 3 GPIO_ACTIVE_LOW>;
+ };
+
+ reg_sd1_vmmc: regulator@1 {
+ compatible = "regulator-fixed";
+ regulator-name = "VSD_3V3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&gpio1 9 GPIO_ACTIVE_HIGH>;
+ off-on-delay = <20000>;
+ enable-active-high;
+ };
+
+ reg_gpio_dvfs: regulator-gpio {
+ compatible = "regulator-gpio";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_dvfs>;
+ regulator-min-microvolt = <1300000>;
+ regulator-max-microvolt = <1400000>;
+ regulator-name = "gpio_dvfs";
+ regulator-type = "voltage";
+ gpios = <&gpio5 3 GPIO_ACTIVE_HIGH>;
+ states = <1300000 0x1 1400000 0x0>;
+ };
+ };
+
+ sound {
+ compatible = "fsl,imx6ul-evk-wm8960",
+ "fsl,imx-audio-wm8960";
+ model = "wm8960-audio";
+ cpu-dai = <&sai2>;
+ audio-codec = <&codec>;
+ asrc-controller = <&asrc>;
+ codec-master;
+ gpr = <&gpr 4 0x100000 0x100000>;
+ /*
+ * hp-det = <hp-det-pin hp-det-polarity>;
+ * hp-det-pin: JD1 JD2 or JD3
+ * hp-det-polarity = 0: hp detect high for headphone
+ * hp-det-polarity = 1: hp detect high for speaker
+ */
+ hp-det = <3 0>;
+ hp-det-gpios = <&gpio5 4 0>;
+ mic-det-gpios = <&gpio5 4 0>;
+ audio-routing =
+ "Headphone Jack", "HP_L",
+ "Headphone Jack", "HP_R",
+ "Ext Spk", "SPK_LP",
+ "Ext Spk", "SPK_LN",
+ "Ext Spk", "SPK_RP",
+ "Ext Spk", "SPK_RN",
+ "LINPUT2", "Mic Jack",
+ "LINPUT3", "Mic Jack",
+ "RINPUT1", "Main MIC",
+ "RINPUT2", "Main MIC",
+ "Mic Jack", "MICB",
+ "Main MIC", "MICB",
+ "CPU-Playback", "ASRC-Playback",
+ "Playback", "CPU-Playback",
+ "ASRC-Capture", "CPU-Capture",
+ "CPU-Capture", "Capture";
+ };
+
+ spi4 {
+ compatible = "spi-gpio";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_spi4>;
+ pinctrl-assert-gpios = <&gpio5 8 GPIO_ACTIVE_LOW>;
+ status = "okay";
+ gpio-sck = <&gpio5 11 0>;
+ gpio-mosi = <&gpio5 10 0>;
+ cs-gpios = <&gpio5 7 0>;
+ num-chipselects = <1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ gpio_spi: gpio_spi@0 {
+ compatible = "fairchild,74hc595";
+ gpio-controller;
+ #gpio-cells = <2>;
+ reg = <0>;
+ registers-number = <1>;
+ registers-default = /bits/ 8 <0x57>;
+ spi-max-frequency = <100000>;
+ };
+ };
+};
+
+&cpu0 {
+ dc-supply = <&reg_gpio_dvfs>;
};
&clks {
- assigned-clocks = <&clks IMX6UL_CLK_PLL3_PFD2>;
- assigned-clock-rates = <320000000>;
+ assigned-clocks = <&clks IMX6UL_CLK_PLL4_AUDIO_DIV>;
+ assigned-clock-rates = <786432000>;
+};
+
+&csi {
+ status = "okay";
+
+ port {
+ csi1_ep: endpoint {
+ remote-endpoint = <&ov5640_ep>;
+ };
+ };
+};
+
+&fec1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_enet1>;
+ phy-mode = "rmii";
+ phy-handle = <&ethphy0>;
+ status = "okay";
+};
+
+&fec2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_enet2>;
+ phy-mode = "rmii";
+ phy-handle = <&ethphy1>;
+ status = "okay";
+
+ mdio {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ethphy0: ethernet-phy@2 {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <2>;
+ micrel,led-mode = <1>;
+ clocks = <&clks IMX6UL_CLK_ENET_REF>;
+ clock-names = "rmii-ref";
+ };
+
+ ethphy1: ethernet-phy@1 {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <1>;
+ micrel,led-mode = <1>;
+ clocks = <&clks IMX6UL_CLK_ENET2_REF>;
+ clock-names = "rmii-ref";
+ };
+ };
+};
+
+&flexcan1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_flexcan1>;
+ xceiver-supply = <&reg_can_3v3>;
+ status = "okay";
+};
+
+&flexcan2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_flexcan2>;
+ xceiver-supply = <&reg_can_3v3>;
+ status = "okay";
+};
+
+&gpc {
+ fsl,cpu_pupscr_sw2iso = <0xf>;
+ fsl,cpu_pupscr_sw = <0x0>;
+ fsl,cpu_pdnscr_iso2sw = <0x1>;
+ fsl,cpu_pdnscr_iso = <0x1>;
+ fsl,ldo-bypass = <0>; /* DCDC, ldo-enable */
+};
+
+&i2c1 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c1>;
+ status = "okay";
+
+ mag3110@0e {
+ compatible = "fsl,mag3110";
+ reg = <0x0e>;
+ position = <2>;
+ };
+
+ fxls8471@1e {
+ compatible = "fsl,fxls8471";
+ reg = <0x1e>;
+ position = <0>;
+ interrupt-parent = <&gpio5>;
+ interrupts = <0 8>;
+ };
+};
+
+&i2c2 {
+ clock_frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c2>;
+ status = "okay";
+
+ codec: wm8960@1a {
+ compatible = "wlf,wm8960";
+ reg = <0x1a>;
+ clocks = <&clks IMX6UL_CLK_SAI2>;
+ clock-names = "mclk";
+ wlf,shared-lrclk;
+ };
+
+ ov5640: ov5640@3c {
+ compatible = "ovti,ov5640";
+ reg = <0x3c>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_csi1>;
+ clocks = <&clks IMX6UL_CLK_CSI>;
+ clock-names = "csi_mclk";
+ pwn-gpios = <&gpio_spi 6 1>;
+ rst-gpios = <&gpio_spi 5 0>;
+ csi_id = <0>;
+ mclk = <24000000>;
+ mclk_source = <0>;
+ status = "okay";
+ port {
+ ov5640_ep: endpoint {
+ remote-endpoint = <&csi1_ep>;
+ };
+ };
+ };
+};
+
+&iomuxc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_hog_1>;
+ pinctrl_hog_1: hoggrp-1 {
+ fsl,pins = <
+ MX6UL_PAD_UART1_RTS_B__GPIO1_IO19 0x17059 /* SD1 CD */
+ MX6UL_PAD_GPIO1_IO05__USDHC1_VSELECT 0x17059 /* SD1 VSELECT */
+ MX6UL_PAD_GPIO1_IO09__GPIO1_IO09 0x17059 /* SD1 RESET */
+ >;
+ };
+
+ pinctrl_csi1: csi1grp {
+ fsl,pins = <
+ MX6UL_PAD_CSI_MCLK__CSI_MCLK 0x1b088
+ MX6UL_PAD_CSI_PIXCLK__CSI_PIXCLK 0x1b088
+ MX6UL_PAD_CSI_VSYNC__CSI_VSYNC 0x1b088
+ MX6UL_PAD_CSI_HSYNC__CSI_HSYNC 0x1b088
+ MX6UL_PAD_CSI_DATA00__CSI_DATA02 0x1b088
+ MX6UL_PAD_CSI_DATA01__CSI_DATA03 0x1b088
+ MX6UL_PAD_CSI_DATA02__CSI_DATA04 0x1b088
+ MX6UL_PAD_CSI_DATA03__CSI_DATA05 0x1b088
+ MX6UL_PAD_CSI_DATA04__CSI_DATA06 0x1b088
+ MX6UL_PAD_CSI_DATA05__CSI_DATA07 0x1b088
+ MX6UL_PAD_CSI_DATA06__CSI_DATA08 0x1b088
+ MX6UL_PAD_CSI_DATA07__CSI_DATA09 0x1b088
+ >;
+ };
+
+ pinctrl_enet1: enet1grp {
+ fsl,pins = <
+ MX6UL_PAD_ENET1_RX_EN__ENET1_RX_EN 0x1b0b0
+ MX6UL_PAD_ENET1_RX_ER__ENET1_RX_ER 0x1b0b0
+ MX6UL_PAD_ENET1_RX_DATA0__ENET1_RDATA00 0x1b0b0
+ MX6UL_PAD_ENET1_RX_DATA1__ENET1_RDATA01 0x1b0b0
+ MX6UL_PAD_ENET1_TX_EN__ENET1_TX_EN 0x1b0b0
+ MX6UL_PAD_ENET1_TX_DATA0__ENET1_TDATA00 0x1b0b0
+ MX6UL_PAD_ENET1_TX_DATA1__ENET1_TDATA01 0x1b0b0
+ MX6UL_PAD_ENET1_TX_CLK__ENET1_REF_CLK1 0x4001b031
+ >;
+ };
+
+ pinctrl_enet2: enet2grp {
+ fsl,pins = <
+ MX6UL_PAD_GPIO1_IO07__ENET2_MDC 0x1b0b0
+ MX6UL_PAD_GPIO1_IO06__ENET2_MDIO 0x1b0b0
+ MX6UL_PAD_ENET2_RX_EN__ENET2_RX_EN 0x1b0b0
+ MX6UL_PAD_ENET2_RX_ER__ENET2_RX_ER 0x1b0b0
+ MX6UL_PAD_ENET2_RX_DATA0__ENET2_RDATA00 0x1b0b0
+ MX6UL_PAD_ENET2_RX_DATA1__ENET2_RDATA01 0x1b0b0
+ MX6UL_PAD_ENET2_TX_EN__ENET2_TX_EN 0x1b0b0
+ MX6UL_PAD_ENET2_TX_DATA0__ENET2_TDATA00 0x1b0b0
+ MX6UL_PAD_ENET2_TX_DATA1__ENET2_TDATA01 0x1b0b0
+ MX6UL_PAD_ENET2_TX_CLK__ENET2_REF_CLK2 0x4001b031
+ >;
+ };
+
+ pinctrl_flexcan1: flexcan1grp{
+ fsl,pins = <
+ MX6UL_PAD_UART3_RTS_B__FLEXCAN1_RX 0x1b020
+ MX6UL_PAD_UART3_CTS_B__FLEXCAN1_TX 0x1b020
+ >;
+ };
+
+ pinctrl_flexcan2: flexcan2grp{
+ fsl,pins = <
+ MX6UL_PAD_UART2_RTS_B__FLEXCAN2_RX 0x1b020
+ MX6UL_PAD_UART2_CTS_B__FLEXCAN2_TX 0x1b020
+ >;
+ };
+
+ pinctrl_i2c1: i2c1grp {
+ fsl,pins = <
+ MX6UL_PAD_UART4_TX_DATA__I2C1_SCL 0x4001b8b0
+ MX6UL_PAD_UART4_RX_DATA__I2C1_SDA 0x4001b8b0
+ >;
+ };
+
+ pinctrl_i2c2: i2c2grp {
+ fsl,pins = <
+ MX6UL_PAD_UART5_TX_DATA__I2C2_SCL 0x4001b8b0
+ MX6UL_PAD_UART5_RX_DATA__I2C2_SDA 0x4001b8b0
+ >;
+ };
+
+ pinctrl_lcdif_dat: lcdifdatgrp {
+ fsl,pins = <
+ MX6UL_PAD_LCD_DATA00__LCDIF_DATA00 0x79
+ MX6UL_PAD_LCD_DATA01__LCDIF_DATA01 0x79
+ MX6UL_PAD_LCD_DATA02__LCDIF_DATA02 0x79
+ MX6UL_PAD_LCD_DATA03__LCDIF_DATA03 0x79
+ MX6UL_PAD_LCD_DATA04__LCDIF_DATA04 0x79
+ MX6UL_PAD_LCD_DATA05__LCDIF_DATA05 0x79
+ MX6UL_PAD_LCD_DATA06__LCDIF_DATA06 0x79
+ MX6UL_PAD_LCD_DATA07__LCDIF_DATA07 0x79
+ MX6UL_PAD_LCD_DATA08__LCDIF_DATA08 0x79
+ MX6UL_PAD_LCD_DATA09__LCDIF_DATA09 0x79
+ MX6UL_PAD_LCD_DATA10__LCDIF_DATA10 0x79
+ MX6UL_PAD_LCD_DATA11__LCDIF_DATA11 0x79
+ MX6UL_PAD_LCD_DATA12__LCDIF_DATA12 0x79
+ MX6UL_PAD_LCD_DATA13__LCDIF_DATA13 0x79
+ MX6UL_PAD_LCD_DATA14__LCDIF_DATA14 0x79
+ MX6UL_PAD_LCD_DATA15__LCDIF_DATA15 0x79
+ MX6UL_PAD_LCD_DATA16__LCDIF_DATA16 0x79
+ MX6UL_PAD_LCD_DATA17__LCDIF_DATA17 0x79
+ MX6UL_PAD_LCD_DATA18__LCDIF_DATA18 0x79
+ MX6UL_PAD_LCD_DATA19__LCDIF_DATA19 0x79
+ MX6UL_PAD_LCD_DATA20__LCDIF_DATA20 0x79
+ MX6UL_PAD_LCD_DATA21__LCDIF_DATA21 0x79
+ MX6UL_PAD_LCD_DATA22__LCDIF_DATA22 0x79
+ MX6UL_PAD_LCD_DATA23__LCDIF_DATA23 0x79
+ >;
+ };
+
+ pinctrl_lcdif_ctrl: lcdifctrlgrp {
+ fsl,pins = <
+ MX6UL_PAD_LCD_CLK__LCDIF_CLK 0x79
+ MX6UL_PAD_LCD_ENABLE__LCDIF_ENABLE 0x79
+ MX6UL_PAD_LCD_HSYNC__LCDIF_HSYNC 0x79
+ MX6UL_PAD_LCD_VSYNC__LCDIF_VSYNC 0x79
+ >;
+ };
+
+ pinctrl_pwm1: pwm1grp {
+ fsl,pins = <
+ MX6UL_PAD_GPIO1_IO08__PWM1_OUT 0x110b0
+ >;
+ };
+
+ pinctrl_qspi: qspigrp {
+ fsl,pins = <
+ MX6UL_PAD_NAND_WP_B__QSPI_A_SCLK 0x70a1
+ MX6UL_PAD_NAND_READY_B__QSPI_A_DATA00 0x70a1
+ MX6UL_PAD_NAND_CE0_B__QSPI_A_DATA01 0x70a1
+ MX6UL_PAD_NAND_CE1_B__QSPI_A_DATA02 0x70a1
+ MX6UL_PAD_NAND_CLE__QSPI_A_DATA03 0x70a1
+ MX6UL_PAD_NAND_DQS__QSPI_A_SS0_B 0x70a1
+ >;
+ };
+
+ pinctrl_sai2: sai2grp {
+ fsl,pins = <
+ MX6UL_PAD_JTAG_TDI__SAI2_TX_BCLK 0x17088
+ MX6UL_PAD_JTAG_TDO__SAI2_TX_SYNC 0x17088
+ MX6UL_PAD_JTAG_TRST_B__SAI2_TX_DATA 0x11088
+ MX6UL_PAD_JTAG_TCK__SAI2_RX_DATA 0x11088
+ MX6UL_PAD_JTAG_TMS__SAI2_MCLK 0x17088
+ >;
+ };
+
+ pinctrl_tsc: tscgrp {
+ fsl,pins = <
+ MX6UL_PAD_GPIO1_IO01__GPIO1_IO01 0xb0
+ MX6UL_PAD_GPIO1_IO02__GPIO1_IO02 0xb0
+ MX6UL_PAD_GPIO1_IO03__GPIO1_IO03 0xb0
+ MX6UL_PAD_GPIO1_IO04__GPIO1_IO04 0xb0
+ >;
+ };
+
+ pinctrl_uart1: uart1grp {
+ fsl,pins = <
+ MX6UL_PAD_UART1_TX_DATA__UART1_DCE_TX 0x1b0b1
+ MX6UL_PAD_UART1_RX_DATA__UART1_DCE_RX 0x1b0b1
+ >;
+ };
+
+ pinctrl_uart2: uart2grp {
+ fsl,pins = <
+ MX6UL_PAD_UART2_TX_DATA__UART2_DCE_TX 0x1b0b1
+ MX6UL_PAD_UART2_RX_DATA__UART2_DCE_RX 0x1b0b1
+ MX6UL_PAD_UART3_RX_DATA__UART2_DCE_RTS 0x1b0b1
+ MX6UL_PAD_UART3_TX_DATA__UART2_DCE_CTS 0x1b0b1
+ >;
+ };
+
+ pinctrl_uart2dte: uart2dtegrp {
+ fsl,pins = <
+ MX6UL_PAD_UART2_TX_DATA__UART2_DTE_RX 0x1b0b1
+ MX6UL_PAD_UART2_RX_DATA__UART2_DTE_TX 0x1b0b1
+ MX6UL_PAD_UART3_RX_DATA__UART2_DTE_CTS 0x1b0b1
+ MX6UL_PAD_UART3_TX_DATA__UART2_DTE_RTS 0x1b0b1
+ >;
+ };
+
+ pinctrl_usb_otg1_id: usbotg1idgrp {
+ fsl,pins = <
+ MX6UL_PAD_GPIO1_IO00__ANATOP_OTG1_ID 0x17059
+ >;
+ };
+
+ pinctrl_usdhc1: usdhc1grp {
+ fsl,pins = <
+ MX6UL_PAD_SD1_CMD__USDHC1_CMD 0x17059
+ MX6UL_PAD_SD1_CLK__USDHC1_CLK 0x10071
+ MX6UL_PAD_SD1_DATA0__USDHC1_DATA0 0x17059
+ MX6UL_PAD_SD1_DATA1__USDHC1_DATA1 0x17059
+ MX6UL_PAD_SD1_DATA2__USDHC1_DATA2 0x17059
+ MX6UL_PAD_SD1_DATA3__USDHC1_DATA3 0x17059
+ >;
+ };
+
+ pinctrl_usdhc1_100mhz: usdhc1grp100mhz {
+ fsl,pins = <
+ MX6UL_PAD_SD1_CMD__USDHC1_CMD 0x170b9
+ MX6UL_PAD_SD1_CLK__USDHC1_CLK 0x100b9
+ MX6UL_PAD_SD1_DATA0__USDHC1_DATA0 0x170b9
+ MX6UL_PAD_SD1_DATA1__USDHC1_DATA1 0x170b9
+ MX6UL_PAD_SD1_DATA2__USDHC1_DATA2 0x170b9
+ MX6UL_PAD_SD1_DATA3__USDHC1_DATA3 0x170b9
+ >;
+ };
+
+ pinctrl_usdhc1_200mhz: usdhc1grp200mhz {
+ fsl,pins = <
+ MX6UL_PAD_SD1_CMD__USDHC1_CMD 0x170f9
+ MX6UL_PAD_SD1_CLK__USDHC1_CLK 0x100f9
+ MX6UL_PAD_SD1_DATA0__USDHC1_DATA0 0x170f9
+ MX6UL_PAD_SD1_DATA1__USDHC1_DATA1 0x170f9
+ MX6UL_PAD_SD1_DATA2__USDHC1_DATA2 0x170f9
+ MX6UL_PAD_SD1_DATA3__USDHC1_DATA3 0x170f9
+ >;
+ };
+
+ pinctrl_usdhc2: usdhc2grp {
+ fsl,pins = <
+ MX6UL_PAD_NAND_RE_B__USDHC2_CLK 0x10069
+ MX6UL_PAD_NAND_WE_B__USDHC2_CMD 0x17059
+ MX6UL_PAD_NAND_DATA00__USDHC2_DATA0 0x17059
+ MX6UL_PAD_NAND_DATA01__USDHC2_DATA1 0x17059
+ MX6UL_PAD_NAND_DATA02__USDHC2_DATA2 0x17059
+ MX6UL_PAD_NAND_DATA03__USDHC2_DATA3 0x17059
+ >;
+ };
+
+ pinctrl_usdhc2_8bit: usdhc2grp_8bit {
+ fsl,pins = <
+ MX6UL_PAD_NAND_RE_B__USDHC2_CLK 0x10069
+ MX6UL_PAD_NAND_WE_B__USDHC2_CMD 0x17059
+ MX6UL_PAD_NAND_DATA00__USDHC2_DATA0 0x17059
+ MX6UL_PAD_NAND_DATA01__USDHC2_DATA1 0x17059
+ MX6UL_PAD_NAND_DATA02__USDHC2_DATA2 0x17059
+ MX6UL_PAD_NAND_DATA03__USDHC2_DATA3 0x17059
+ MX6UL_PAD_NAND_DATA04__USDHC2_DATA4 0x17059
+ MX6UL_PAD_NAND_DATA05__USDHC2_DATA5 0x17059
+ MX6UL_PAD_NAND_DATA06__USDHC2_DATA6 0x17059
+ MX6UL_PAD_NAND_DATA07__USDHC2_DATA7 0x17059
+ >;
+ };
+
+ pinctrl_usdhc2_8bit_100mhz: usdhc2grp_8bit_100mhz {
+ fsl,pins = <
+ MX6UL_PAD_NAND_RE_B__USDHC2_CLK 0x100b9
+ MX6UL_PAD_NAND_WE_B__USDHC2_CMD 0x170b9
+ MX6UL_PAD_NAND_DATA00__USDHC2_DATA0 0x170b9
+ MX6UL_PAD_NAND_DATA01__USDHC2_DATA1 0x170b9
+ MX6UL_PAD_NAND_DATA02__USDHC2_DATA2 0x170b9
+ MX6UL_PAD_NAND_DATA03__USDHC2_DATA3 0x170b9
+ MX6UL_PAD_NAND_DATA04__USDHC2_DATA4 0x170b9
+ MX6UL_PAD_NAND_DATA05__USDHC2_DATA5 0x170b9
+ MX6UL_PAD_NAND_DATA06__USDHC2_DATA6 0x170b9
+ MX6UL_PAD_NAND_DATA07__USDHC2_DATA7 0x170b9
+ >;
+ };
+
+ pinctrl_usdhc2_8bit_200mhz: usdhc2grp_8bit_200mhz {
+ fsl,pins = <
+ MX6UL_PAD_NAND_RE_B__USDHC2_CLK 0x100f9
+ MX6UL_PAD_NAND_WE_B__USDHC2_CMD 0x170f9
+ MX6UL_PAD_NAND_DATA00__USDHC2_DATA0 0x170f9
+ MX6UL_PAD_NAND_DATA01__USDHC2_DATA1 0x170f9
+ MX6UL_PAD_NAND_DATA02__USDHC2_DATA2 0x170f9
+ MX6UL_PAD_NAND_DATA03__USDHC2_DATA3 0x170f9
+ MX6UL_PAD_NAND_DATA04__USDHC2_DATA4 0x170f9
+ MX6UL_PAD_NAND_DATA05__USDHC2_DATA5 0x170f9
+ MX6UL_PAD_NAND_DATA06__USDHC2_DATA6 0x170f9
+ MX6UL_PAD_NAND_DATA07__USDHC2_DATA7 0x170f9
+ >;
+ };
+
+ pinctrl_wdog: wdoggrp {
+ fsl,pins = <
+ MX6UL_PAD_LCD_RESET__WDOG1_WDOG_ANY 0x30b0
+ >;
+ };
+};
+
+&iomuxc_snvs {
+ pinctrl-names = "default_snvs";
+ pinctrl-0 = <&pinctrl_hog_2>;
+ imx6ul-evk {
+ pinctrl_hog_2: hoggrp-2 {
+ fsl,pins = <
+ MX6ULL_PAD_SNVS_TAMPER0__GPIO5_IO00 0x80000000
+ >;
+ };
+
+ pinctrl_dvfs: dvfsgrp {
+ fsl,pins = <
+ MX6ULL_PAD_SNVS_TAMPER3__GPIO5_IO03 0x79
+ >;
+ };
+
+ pinctrl_lcdif_reset: lcdifresetgrp {
+ fsl,pins = <
+ /* used for lcd reset */
+ MX6ULL_PAD_SNVS_TAMPER9__GPIO5_IO09 0x79
+ >;
+ };
+
+ pinctrl_spi4: spi4grp {
+ fsl,pins = <
+ MX6ULL_PAD_BOOT_MODE0__GPIO5_IO10 0x70a1
+ MX6ULL_PAD_BOOT_MODE1__GPIO5_IO11 0x70a1
+ MX6ULL_PAD_SNVS_TAMPER7__GPIO5_IO07 0x70a1
+ MX6ULL_PAD_SNVS_TAMPER8__GPIO5_IO08 0x80000000
+ >;
+ };
+
+ pinctrl_sai2_hp_det_b: sai2_hp_det_grp {
+ fsl,pins = <
+ MX6ULL_PAD_SNVS_TAMPER4__GPIO5_IO04 0x17059
+ >;
+ };
+ };
+};
+
+
+&lcdif {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lcdif_dat
+ &pinctrl_lcdif_ctrl
+ &pinctrl_lcdif_reset>;
+ display = <&display0>;
+ status = "okay";
+
+ display0: display@0 {
+ bits-per-pixel = <16>;
+ bus-width = <24>;
+
+ display-timings {
+ native-mode = <&timing0>;
+ timing0: timing0 {
+ clock-frequency = <9200000>;
+ hactive = <480>;
+ vactive = <272>;
+ hfront-porch = <8>;
+ hback-porch = <4>;
+ hsync-len = <41>;
+ vback-porch = <2>;
+ vfront-porch = <4>;
+ vsync-len = <10>;
+
+ hsync-active = <0>;
+ vsync-active = <0>;
+ de-active = <1>;
+ pixelclk-active = <0>;
+ };
+ };
+ };
+};
+
+&pwm1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pwm1>;
+ status = "okay";
+};
+
+&pxp {
+ status = "okay";
+};
+
+&qspi {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_qspi>;
+ status = "okay";
+ ddrsmp=<0>;
+
+ flash0: n25q256a@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "micron,n25q256a";
+ spi-max-frequency = <29000000>;
+ spi-nor,ddr-quad-read-dummy = <6>;
+ reg = <0>;
+ };
+};
+
+&sai2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_sai2
+ &pinctrl_sai2_hp_det_b>;
+
+ assigned-clocks = <&clks IMX6UL_CLK_SAI2_SEL>,
+ <&clks IMX6UL_CLK_SAI2>;
+ assigned-clock-parents = <&clks IMX6UL_CLK_PLL4_AUDIO_DIV>;
+ assigned-clock-rates = <0>, <12288000>;
+
+ status = "okay";
+};
+
+&tsc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_tsc>;
+ xnur-gpio = <&gpio1 3 GPIO_ACTIVE_LOW>;
+ measure-delay-time = <0xffff>;
+ pre-charge-time = <0xfff>;
+ status = "okay";
+};
+
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart1>;
+ status = "okay";
+};
+
+&uart2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart2>;
+ fsl,uart-has-rtscts;
+ /* for DTE mode, add below change */
+ /* fsl,dte-mode; */
+ /* pinctrl-0 = <&pinctrl_uart2dte>; */
+ status = "okay";
+};
+
+&usbotg1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usb_otg1_id>;
+ dr_mode = "otg";
+ srp-disable;
+ hnp-disable;
+ adp-disable;
+ status = "okay";
+};
+
+&usbotg2 {
+ dr_mode = "host";
+ disable-over-current;
+ status = "okay";
+};
+
+&usbphy1 {
+ fsl,tx-d-cal = <106>;
+};
+
+&usbphy2 {
+ fsl,tx-d-cal = <106>;
+};
+
+&usdhc1 {
+ pinctrl-names = "default", "state_100mhz", "state_200mhz";
+ pinctrl-0 = <&pinctrl_usdhc1>;
+ pinctrl-1 = <&pinctrl_usdhc1_100mhz>;
+ pinctrl-2 = <&pinctrl_usdhc1_200mhz>;
+ cd-gpios = <&gpio1 19 GPIO_ACTIVE_LOW>;
+ keep-power-in-suspend;
+ enable-sdio-wakeup;
+ vmmc-supply = <&reg_sd1_vmmc>;
+ status = "okay";
+};
+
+&usdhc2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usdhc2>;
+ non-removable;
+ status = "okay";
+};
+
+&wdog1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_wdog>;
+ fsl,ext-reset-output;
};
diff --git a/arch/arm/boot/dts/imx6ull-9x9-evk-btwifi-oob.dts b/arch/arm/boot/dts/imx6ull-9x9-evk-btwifi-oob.dts
new file mode 100644
index 000000000000..8d00a908ee94
--- /dev/null
+++ b/arch/arm/boot/dts/imx6ull-9x9-evk-btwifi-oob.dts
@@ -0,0 +1,10 @@
+/*
+ * Copyright (C) 2017 NXP
+ *
+ * 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 "imx6ull-9x9-evk-btwifi.dts"
+#include "imx6ul-evk-btwifi-oob.dtsi"
diff --git a/arch/arm/boot/dts/imx6ull-9x9-evk-btwifi.dts b/arch/arm/boot/dts/imx6ull-9x9-evk-btwifi.dts
new file mode 100644
index 000000000000..c8a51006213f
--- /dev/null
+++ b/arch/arm/boot/dts/imx6ull-9x9-evk-btwifi.dts
@@ -0,0 +1,10 @@
+/*
+ * Copyright (C) 2015 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 "imx6ull-9x9-evk.dts"
+#include "imx6ul-evk-btwifi.dtsi"
diff --git a/arch/arm/boot/dts/imx6ull-9x9-evk-ldo.dts b/arch/arm/boot/dts/imx6ull-9x9-evk-ldo.dts
new file mode 100644
index 000000000000..a878fe5bbb78
--- /dev/null
+++ b/arch/arm/boot/dts/imx6ull-9x9-evk-ldo.dts
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2017 NXP.
+ *
+ * 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 "imx6ull-9x9-evk.dts"
+&cpu0 {
+ operating-points = <
+ /* kHz uV */
+ 528000 1175000
+ 396000 1025000
+ 198000 950000
+ >;
+ fsl,soc-operating-points = <
+ /* KHz uV */
+ 528000 1175000
+ 396000 1175000
+ 198000 1175000
+ >;
+ fsl,arm-soc-shared = <0>;
+};
+
+&gpc {
+ fsl,ldo-bypass = <0>; /* use ldo-enable, u-boot will check it and configure */
+};
+
+&reg_arm {
+ /delete-property/ vin-supply;
+};
+
+&reg_soc {
+ /delete-property/ vin-supply;
+};
diff --git a/arch/arm/boot/dts/imx6ull-9x9-evk.dts b/arch/arm/boot/dts/imx6ull-9x9-evk.dts
new file mode 100644
index 000000000000..9991169f7fae
--- /dev/null
+++ b/arch/arm/boot/dts/imx6ull-9x9-evk.dts
@@ -0,0 +1,813 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017 NXP
+ *
+ * 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 <dt-bindings/input/input.h>
+#include "imx6ull.dtsi"
+
+/ {
+ model = "Freescale i.MX6 ULL 9x9 EVK Board";
+ compatible = "fsl,imx6ull-9x9-evk", "fsl,imx6ull";
+
+ backlight {
+ compatible = "pwm-backlight";
+ pwms = <&pwm1 0 5000000>;
+ brightness-levels = <0 4 8 16 32 64 128 255>;
+ default-brightness-level = <6>;
+ status = "okay";
+ };
+
+ chosen {
+ stdout-path = &uart1;
+ };
+
+ memory {
+ reg = <0x80000000 0x10000000>;
+ };
+
+ reserved-memory {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ linux,cma {
+ compatible = "shared-dma-pool";
+ reusable;
+ size = <0x6000000>;
+ linux,cma-default;
+ };
+ };
+
+ pxp_v4l2 {
+ compatible = "fsl,imx6ul-pxp-v4l2", "fsl,imx6sx-pxp-v4l2", "fsl,imx6sl-pxp-v4l2";
+ status = "okay";
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ reg_can_3v3: regulator@0 {
+ compatible = "regulator-fixed";
+ reg = <0>;
+ regulator-name = "can-3v3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpios = <&gpio_spi 3 GPIO_ACTIVE_LOW>;
+ };
+
+ reg_gpio_dvfs: regulator-gpio {
+ compatible = "regulator-gpio";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_dvfs>;
+ regulator-min-microvolt = <1300000>;
+ regulator-max-microvolt = <1400000>;
+ regulator-name = "gpio_dvfs";
+ regulator-type = "voltage";
+ gpios = <&gpio5 3 GPIO_ACTIVE_HIGH>;
+ states = <1300000 0x1 1400000 0x0>;
+ };
+
+ reg_sd1_vmmc: regulator@1 {
+ compatible = "regulator-fixed";
+ regulator-name = "VSD_3V3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&gpio1 9 GPIO_ACTIVE_HIGH>;
+ off-on-delay = <20000>;
+ enable-active-high;
+ };
+ };
+
+ sound {
+ compatible = "fsl,imx6ul-evk-wm8960",
+ "fsl,imx-audio-wm8960";
+ model = "wm8960-audio";
+ cpu-dai = <&sai2>;
+ audio-codec = <&codec>;
+ asrc-controller = <&asrc>;
+ codec-master;
+ gpr = <&gpr 4 0x100000 0x100000>;
+ /*
+ * hp-det = <hp-det-pin hp-det-polarity>;
+ * hp-det-pin: JD1 JD2 or JD3
+ * hp-det-polarity = 0: hp detect high for headphone
+ * hp-det-polarity = 1: hp detect high for speaker
+ */
+ hp-det = <3 0>;
+ hp-det-gpios = <&gpio5 4 0>;
+ mic-det-gpios = <&gpio5 4 0>;
+ audio-routing =
+ "Headphone Jack", "HP_L",
+ "Headphone Jack", "HP_R",
+ "Ext Spk", "SPK_LP",
+ "Ext Spk", "SPK_LN",
+ "Ext Spk", "SPK_RP",
+ "Ext Spk", "SPK_RN",
+ "LINPUT2", "Mic Jack",
+ "LINPUT3", "Mic Jack",
+ "RINPUT1", "Main MIC",
+ "RINPUT2", "Main MIC",
+ "Mic Jack", "MICB",
+ "Main MIC", "MICB",
+ "CPU-Playback", "ASRC-Playback",
+ "Playback", "CPU-Playback",
+ "ASRC-Capture", "CPU-Capture",
+ "CPU-Capture", "Capture";
+ };
+
+ spi4 {
+ compatible = "spi-gpio";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_spi4>;
+ pinctrl-assert-gpios = <&gpio5 8 GPIO_ACTIVE_LOW>;
+ status = "okay";
+ gpio-sck = <&gpio5 11 0>;
+ gpio-mosi = <&gpio5 10 0>;
+ cs-gpios = <&gpio5 7 0>;
+ num-chipselects = <1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ gpio_spi: gpio_spi@0 {
+ compatible = "fairchild,74hc595";
+ gpio-controller;
+ #gpio-cells = <2>;
+ reg = <0>;
+ registers-number = <1>;
+ registers-default = /bits/ 8 <0x57>;
+ spi-max-frequency = <100000>;
+ };
+ };
+};
+
+&clks {
+ assigned-clocks = <&clks IMX6UL_CLK_PLL4_AUDIO_DIV>;
+ assigned-clock-rates = <786432000>;
+};
+
+&cpu0 {
+ /*
+ * on i.MX6ULL, no seperated VDD_ARM_IN and VDD_SOC_IN,
+ * to align with other platform and use the same cpufreq
+ * driver, still use the seperated OPP define for arm
+ * and soc.
+ */
+ operating-points = <
+ /* kHz uV */
+ 528000 1175000
+ 396000 1175000
+ 198000 1175000
+ >;
+ fsl,soc-operating-points = <
+ /* KHz uV */
+ 528000 1175000
+ 396000 1175000
+ 198000 1175000
+ >;
+ fsl,arm-soc-shared = <1>;
+};
+
+&reg_arm {
+ vin-supply = <&sw1c_reg>;
+ regulator-allow-bypass;
+};
+
+&reg_soc {
+ vin-supply = <&sw1c_reg>;
+ regulator-allow-bypass;
+};
+
+&csi {
+ status = "okay";
+
+ port {
+ csi1_ep: endpoint {
+ remote-endpoint = <&ov5640_ep>;
+ };
+ };
+};
+
+&fec1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_enet1>;
+ phy-mode = "rmii";
+ phy-handle = <&ethphy0>;
+ status = "okay";
+};
+
+&fec2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_enet2>;
+ phy-mode = "rmii";
+ phy-handle = <&ethphy1>;
+ status = "okay";
+
+ mdio {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ethphy0: ethernet-phy@2 {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <2>;
+ };
+
+ ethphy1: ethernet-phy@1 {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <1>;
+ };
+ };
+};
+
+&flexcan1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_flexcan1>;
+ xceiver-supply = <&reg_can_3v3>;
+ status = "okay";
+};
+
+&flexcan2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_flexcan2>;
+ xceiver-supply = <&reg_can_3v3>;
+ status = "okay";
+};
+
+&gpc {
+ fsl,cpu_pupscr_sw2iso = <0xf>;
+ fsl,cpu_pupscr_sw = <0x0>;
+ fsl,cpu_pdnscr_iso2sw = <0x1>;
+ fsl,cpu_pdnscr_iso = <0x1>;
+ fsl,ldo-bypass = <1>;
+};
+
+&i2c1 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c1>;
+ status = "okay";
+
+ pmic: pfuze3000@08 {
+ compatible = "fsl,pfuze3000";
+ reg = <0x08>;
+
+ regulators {
+ sw1a_reg: sw1a {
+ regulator-min-microvolt = <700000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ regulator-ramp-delay = <6250>;
+ };
+
+ /* use sw1c_reg to align with pfuze100/pfuze200 */
+ sw1c_reg: sw1b {
+ regulator-min-microvolt = <700000>;
+ regulator-max-microvolt = <1475000>;
+ regulator-boot-on;
+ regulator-always-on;
+ regulator-ramp-delay = <6250>;
+ };
+
+ sw2_reg: sw2 {
+ regulator-min-microvolt = <2500000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ sw3a_reg: sw3 {
+ regulator-min-microvolt = <900000>;
+ regulator-max-microvolt = <1650000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ swbst_reg: swbst {
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5150000>;
+ };
+
+ snvs_reg: vsnvs {
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ vref_reg: vrefddr {
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ vgen1_reg: vldo1 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ vgen2_reg: vldo2 {
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1550000>;
+ regulator-always-on;
+ };
+
+ vgen3_reg: vccsd {
+ regulator-min-microvolt = <2850000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ vgen4_reg: v33 {
+ regulator-min-microvolt = <2850000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ vgen5_reg: vldo3 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ vgen6_reg: vldo4 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+ };
+ };
+
+ mag3110@0e {
+ compatible = "fsl,mag3110";
+ reg = <0x0e>;
+ position = <2>;
+ };
+
+ fxls8471@1e {
+ compatible = "fsl,fxls8471";
+ reg = <0x1e>;
+ position = <0>;
+ interrupt-parent = <&gpio5>;
+ interrupts = <0 8>;
+ };
+};
+
+&i2c2 {
+ clock_frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c2>;
+ status = "okay";
+
+ codec: wm8960@1a {
+ compatible = "wlf,wm8960";
+ reg = <0x1a>;
+ clocks = <&clks IMX6UL_CLK_SAI2>;
+ clock-names = "mclk";
+ wlf,shared-lrclk;
+ };
+
+ ov5640: ov5640@3c {
+ compatible = "ovti,ov5640";
+ reg = <0x3c>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_csi1>;
+ clocks = <&clks IMX6UL_CLK_CSI>;
+ clock-names = "csi_mclk";
+ pwn-gpios = <&gpio_spi 6 1>;
+ rst-gpios = <&gpio_spi 5 0>;
+ csi_id = <0>;
+ mclk = <24000000>;
+ mclk_source = <0>;
+ status = "okay";
+ port {
+ ov5640_ep: endpoint {
+ remote-endpoint = <&csi1_ep>;
+ };
+ };
+ };
+};
+
+&iomuxc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_hog_1>;
+ imx6ul-evk {
+ pinctrl_csi1: csi1grp {
+ fsl,pins = <
+ MX6UL_PAD_CSI_MCLK__CSI_MCLK 0x1b088
+ MX6UL_PAD_CSI_PIXCLK__CSI_PIXCLK 0x1b088
+ MX6UL_PAD_CSI_VSYNC__CSI_VSYNC 0x1b088
+ MX6UL_PAD_CSI_HSYNC__CSI_HSYNC 0x1b088
+ MX6UL_PAD_CSI_DATA00__CSI_DATA02 0x1b088
+ MX6UL_PAD_CSI_DATA01__CSI_DATA03 0x1b088
+ MX6UL_PAD_CSI_DATA02__CSI_DATA04 0x1b088
+ MX6UL_PAD_CSI_DATA03__CSI_DATA05 0x1b088
+ MX6UL_PAD_CSI_DATA04__CSI_DATA06 0x1b088
+ MX6UL_PAD_CSI_DATA05__CSI_DATA07 0x1b088
+ MX6UL_PAD_CSI_DATA06__CSI_DATA08 0x1b088
+ MX6UL_PAD_CSI_DATA07__CSI_DATA09 0x1b088
+ >;
+ };
+
+ pinctrl_enet1: enet1grp {
+ fsl,pins = <
+ MX6UL_PAD_ENET1_RX_EN__ENET1_RX_EN 0x1b0b0
+ MX6UL_PAD_ENET1_RX_ER__ENET1_RX_ER 0x1b0b0
+ MX6UL_PAD_ENET1_RX_DATA0__ENET1_RDATA00 0x1b0b0
+ MX6UL_PAD_ENET1_RX_DATA1__ENET1_RDATA01 0x1b0b0
+ MX6UL_PAD_ENET1_TX_EN__ENET1_TX_EN 0x1b0b0
+ MX6UL_PAD_ENET1_TX_DATA0__ENET1_TDATA00 0x1b0b0
+ MX6UL_PAD_ENET1_TX_DATA1__ENET1_TDATA01 0x1b0b0
+ MX6UL_PAD_ENET1_TX_CLK__ENET1_REF_CLK1 0x4001b031
+ >;
+ };
+
+ pinctrl_enet2: enet2grp {
+ fsl,pins = <
+ MX6UL_PAD_GPIO1_IO07__ENET2_MDC 0x1b0b0
+ MX6UL_PAD_GPIO1_IO06__ENET2_MDIO 0x1b0b0
+ MX6UL_PAD_ENET2_RX_EN__ENET2_RX_EN 0x1b0b0
+ MX6UL_PAD_ENET2_RX_ER__ENET2_RX_ER 0x1b0b0
+ MX6UL_PAD_ENET2_RX_DATA0__ENET2_RDATA00 0x1b0b0
+ MX6UL_PAD_ENET2_RX_DATA1__ENET2_RDATA01 0x1b0b0
+ MX6UL_PAD_ENET2_TX_EN__ENET2_TX_EN 0x1b0b0
+ MX6UL_PAD_ENET2_TX_DATA0__ENET2_TDATA00 0x1b0b0
+ MX6UL_PAD_ENET2_TX_DATA1__ENET2_TDATA01 0x1b0b0
+ MX6UL_PAD_ENET2_TX_CLK__ENET2_REF_CLK2 0x4001b031
+ >;
+ };
+
+ pinctrl_flexcan1: flexcan1grp{
+ fsl,pins = <
+ MX6UL_PAD_UART3_RTS_B__FLEXCAN1_RX 0x1b020
+ MX6UL_PAD_UART3_CTS_B__FLEXCAN1_TX 0x1b020
+ >;
+ };
+
+ pinctrl_flexcan2: flexcan2grp{
+ fsl,pins = <
+ MX6UL_PAD_UART2_RTS_B__FLEXCAN2_RX 0x1b020
+ MX6UL_PAD_UART2_CTS_B__FLEXCAN2_TX 0x1b020
+ >;
+ };
+
+ pinctrl_hog_1: hoggrp-1 {
+ fsl,pins = <
+ MX6UL_PAD_UART1_RTS_B__GPIO1_IO19 0x17059 /* SD1 CD */
+ MX6UL_PAD_GPIO1_IO05__USDHC1_VSELECT 0x17059 /* SD1 VSELECT */
+ MX6UL_PAD_GPIO1_IO09__GPIO1_IO09 0x17059 /* SD1 RESET */
+ >;
+ };
+
+ pinctrl_i2c1: i2c1grp {
+ fsl,pins = <
+ MX6UL_PAD_UART4_TX_DATA__I2C1_SCL 0x4001b8b0
+ MX6UL_PAD_UART4_RX_DATA__I2C1_SDA 0x4001b8b0
+ >;
+ };
+
+ pinctrl_i2c2: i2c2grp {
+ fsl,pins = <
+ MX6UL_PAD_UART5_TX_DATA__I2C2_SCL 0x4001b8b0
+ MX6UL_PAD_UART5_RX_DATA__I2C2_SDA 0x4001b8b0
+ >;
+ };
+
+ pinctrl_lcdif_ctrl: lcdifctrlgrp {
+ fsl,pins = <
+ MX6UL_PAD_LCD_CLK__LCDIF_CLK 0x79
+ MX6UL_PAD_LCD_ENABLE__LCDIF_ENABLE 0x79
+ MX6UL_PAD_LCD_HSYNC__LCDIF_HSYNC 0x79
+ MX6UL_PAD_LCD_VSYNC__LCDIF_VSYNC 0x79
+ >;
+ };
+
+ pinctrl_lcdif_dat: lcdifdatgrp {
+ fsl,pins = <
+ MX6UL_PAD_LCD_DATA00__LCDIF_DATA00 0x79
+ MX6UL_PAD_LCD_DATA01__LCDIF_DATA01 0x79
+ MX6UL_PAD_LCD_DATA02__LCDIF_DATA02 0x79
+ MX6UL_PAD_LCD_DATA03__LCDIF_DATA03 0x79
+ MX6UL_PAD_LCD_DATA04__LCDIF_DATA04 0x79
+ MX6UL_PAD_LCD_DATA05__LCDIF_DATA05 0x79
+ MX6UL_PAD_LCD_DATA06__LCDIF_DATA06 0x79
+ MX6UL_PAD_LCD_DATA07__LCDIF_DATA07 0x79
+ MX6UL_PAD_LCD_DATA08__LCDIF_DATA08 0x79
+ MX6UL_PAD_LCD_DATA09__LCDIF_DATA09 0x79
+ MX6UL_PAD_LCD_DATA10__LCDIF_DATA10 0x79
+ MX6UL_PAD_LCD_DATA11__LCDIF_DATA11 0x79
+ MX6UL_PAD_LCD_DATA12__LCDIF_DATA12 0x79
+ MX6UL_PAD_LCD_DATA13__LCDIF_DATA13 0x79
+ MX6UL_PAD_LCD_DATA14__LCDIF_DATA14 0x79
+ MX6UL_PAD_LCD_DATA15__LCDIF_DATA15 0x79
+ MX6UL_PAD_LCD_DATA16__LCDIF_DATA16 0x79
+ MX6UL_PAD_LCD_DATA17__LCDIF_DATA17 0x79
+ MX6UL_PAD_LCD_DATA18__LCDIF_DATA18 0x79
+ MX6UL_PAD_LCD_DATA19__LCDIF_DATA19 0x79
+ MX6UL_PAD_LCD_DATA20__LCDIF_DATA20 0x79
+ MX6UL_PAD_LCD_DATA21__LCDIF_DATA21 0x79
+ MX6UL_PAD_LCD_DATA22__LCDIF_DATA22 0x79
+ MX6UL_PAD_LCD_DATA23__LCDIF_DATA23 0x79
+ >;
+ };
+
+ pinctrl_pwm1: pwm1grp {
+ fsl,pins = <
+ MX6UL_PAD_GPIO1_IO08__PWM1_OUT 0x110b0
+ >;
+ };
+
+ pinctrl_qspi: qspigrp {
+ fsl,pins = <
+ MX6UL_PAD_NAND_WP_B__QSPI_A_SCLK 0x70a1
+ MX6UL_PAD_NAND_READY_B__QSPI_A_DATA00 0x70a1
+ MX6UL_PAD_NAND_CE0_B__QSPI_A_DATA01 0x70a1
+ MX6UL_PAD_NAND_CE1_B__QSPI_A_DATA02 0x70a1
+ MX6UL_PAD_NAND_CLE__QSPI_A_DATA03 0x70a1
+ MX6UL_PAD_NAND_DQS__QSPI_A_SS0_B 0x70a1
+ >;
+ };
+
+ pinctrl_sai2: sai2grp {
+ fsl,pins = <
+ MX6UL_PAD_JTAG_TDI__SAI2_TX_BCLK 0x17088
+ MX6UL_PAD_JTAG_TDO__SAI2_TX_SYNC 0x17088
+ MX6UL_PAD_JTAG_TRST_B__SAI2_TX_DATA 0x11088
+ MX6UL_PAD_JTAG_TCK__SAI2_RX_DATA 0x11088
+ MX6UL_PAD_JTAG_TMS__SAI2_MCLK 0x17088
+ >;
+ };
+
+ pinctrl_tsc: tscgrp {
+ fsl,pins = <
+ MX6UL_PAD_GPIO1_IO01__GPIO1_IO01 0xb0
+ MX6UL_PAD_GPIO1_IO02__GPIO1_IO02 0xb0
+ MX6UL_PAD_GPIO1_IO03__GPIO1_IO03 0xb0
+ MX6UL_PAD_GPIO1_IO04__GPIO1_IO04 0xb0
+ >;
+ };
+
+ pinctrl_uart1: uart1grp {
+ fsl,pins = <
+ MX6UL_PAD_UART1_TX_DATA__UART1_DCE_TX 0x1b0b1
+ MX6UL_PAD_UART1_RX_DATA__UART1_DCE_RX 0x1b0b1
+ >;
+ };
+
+ pinctrl_uart2: uart2grp {
+ fsl,pins = <
+ MX6UL_PAD_UART2_TX_DATA__UART2_DCE_TX 0x1b0b1
+ MX6UL_PAD_UART2_RX_DATA__UART2_DCE_RX 0x1b0b1
+ MX6UL_PAD_UART3_RX_DATA__UART2_DCE_RTS 0x1b0b1
+ MX6UL_PAD_UART3_TX_DATA__UART2_DCE_CTS 0x1b0b1
+ >;
+ };
+
+ pinctrl_uart2dte: uart2dtegrp {
+ fsl,pins = <
+ MX6UL_PAD_UART2_TX_DATA__UART2_DTE_RX 0x1b0b1
+ MX6UL_PAD_UART2_RX_DATA__UART2_DTE_TX 0x1b0b1
+ MX6UL_PAD_UART3_RX_DATA__UART2_DTE_CTS 0x1b0b1
+ MX6UL_PAD_UART3_TX_DATA__UART2_DTE_RTS 0x1b0b1
+ >;
+ };
+
+ pinctrl_usdhc1: usdhc1grp {
+ fsl,pins = <
+ MX6UL_PAD_SD1_CMD__USDHC1_CMD 0x17059
+ MX6UL_PAD_SD1_CLK__USDHC1_CLK 0x10059
+ MX6UL_PAD_SD1_DATA0__USDHC1_DATA0 0x17059
+ MX6UL_PAD_SD1_DATA1__USDHC1_DATA1 0x17059
+ MX6UL_PAD_SD1_DATA2__USDHC1_DATA2 0x17059
+ MX6UL_PAD_SD1_DATA3__USDHC1_DATA3 0x17059
+ >;
+ };
+
+ pinctrl_usdhc1_100mhz: usdhc1grp100mhz {
+ fsl,pins = <
+ MX6UL_PAD_SD1_CMD__USDHC1_CMD 0x170b9
+ MX6UL_PAD_SD1_CLK__USDHC1_CLK 0x100b9
+ MX6UL_PAD_SD1_DATA0__USDHC1_DATA0 0x170b9
+ MX6UL_PAD_SD1_DATA1__USDHC1_DATA1 0x170b9
+ MX6UL_PAD_SD1_DATA2__USDHC1_DATA2 0x170b9
+ MX6UL_PAD_SD1_DATA3__USDHC1_DATA3 0x170b9
+ >;
+ };
+
+ pinctrl_usdhc1_200mhz: usdhc1grp200mhz {
+ fsl,pins = <
+ MX6UL_PAD_SD1_CMD__USDHC1_CMD 0x170f9
+ MX6UL_PAD_SD1_CLK__USDHC1_CLK 0x100f9
+ MX6UL_PAD_SD1_DATA0__USDHC1_DATA0 0x170f9
+ MX6UL_PAD_SD1_DATA1__USDHC1_DATA1 0x170f9
+ MX6UL_PAD_SD1_DATA2__USDHC1_DATA2 0x170f9
+ MX6UL_PAD_SD1_DATA3__USDHC1_DATA3 0x170f9
+ >;
+ };
+
+ pinctrl_usdhc2: usdhc2grp {
+ fsl,pins = <
+ MX6UL_PAD_NAND_RE_B__USDHC2_CLK 0x17059
+ MX6UL_PAD_NAND_WE_B__USDHC2_CMD 0x17059
+ MX6UL_PAD_NAND_DATA00__USDHC2_DATA0 0x17059
+ MX6UL_PAD_NAND_DATA01__USDHC2_DATA1 0x17059
+ MX6UL_PAD_NAND_DATA02__USDHC2_DATA2 0x17059
+ MX6UL_PAD_NAND_DATA03__USDHC2_DATA3 0x17059
+ >;
+ };
+
+ pinctrl_wdog: wdoggrp {
+ fsl,pins = <
+ MX6UL_PAD_LCD_RESET__WDOG1_WDOG_ANY 0x30b0
+ >;
+ };
+ };
+};
+
+&iomuxc_snvs {
+ pinctrl-names = "default_snvs";
+ pinctrl-0 = <&pinctrl_hog_2>;
+ imx6ull-evk {
+ pinctrl_hog_2: hoggrp-2 {
+ fsl,pins = <
+ MX6ULL_PAD_SNVS_TAMPER0__GPIO5_IO00 0x80000000
+ >;
+ };
+
+ pinctrl_dvfs: dvfsgrp {
+ fsl,pins = <
+ MX6ULL_PAD_SNVS_TAMPER3__GPIO5_IO03 0x79
+ >;
+ };
+
+ pinctrl_lcdif_reset: lcdifresetgrp {
+ fsl,pins = <
+ /* used for lcd reset */
+ MX6ULL_PAD_SNVS_TAMPER9__GPIO5_IO09 0x79
+ >;
+ };
+
+ pinctrl_spi4: spi4grp {
+ fsl,pins = <
+ MX6ULL_PAD_BOOT_MODE0__GPIO5_IO10 0x70a1
+ MX6ULL_PAD_BOOT_MODE1__GPIO5_IO11 0x70a1
+ MX6ULL_PAD_SNVS_TAMPER7__GPIO5_IO07 0x70a1
+ MX6ULL_PAD_SNVS_TAMPER8__GPIO5_IO08 0x80000000
+ >;
+ };
+
+ pinctrl_sai2_hp_det_b: sai2_hp_det_grp {
+ fsl,pins = <
+ MX6ULL_PAD_SNVS_TAMPER4__GPIO5_IO04 0x17059
+ >;
+ };
+ };
+};
+
+&lcdif {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lcdif_dat
+ &pinctrl_lcdif_ctrl
+ &pinctrl_lcdif_reset>;
+ display = <&display0>;
+ status = "okay";
+
+ display0: display {
+ bits-per-pixel = <16>;
+ bus-width = <24>;
+
+ display-timings {
+ native-mode = <&timing0>;
+ timing0: timing0 {
+ clock-frequency = <9200000>;
+ hactive = <480>;
+ vactive = <272>;
+ hfront-porch = <8>;
+ hback-porch = <4>;
+ hsync-len = <41>;
+ vback-porch = <2>;
+ vfront-porch = <4>;
+ vsync-len = <10>;
+
+ hsync-active = <0>;
+ vsync-active = <0>;
+ de-active = <1>;
+ pixelclk-active = <0>;
+ };
+ };
+ };
+};
+
+&pwm1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pwm1>;
+ status = "okay";
+};
+
+&pxp {
+ status = "okay";
+};
+
+&qspi {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_qspi>;
+ status = "okay";
+ ddrsmp=<0>;
+
+ flash0: n25q256a@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "micron,n25q256a";
+ spi-max-frequency = <29000000>;
+ spi-nor,ddr-quad-read-dummy = <6>;
+ reg = <0>;
+ };
+};
+
+&sai2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_sai2
+ &pinctrl_sai2_hp_det_b>;
+
+ assigned-clocks = <&clks IMX6UL_CLK_SAI2_SEL>,
+ <&clks IMX6UL_CLK_SAI2>;
+ assigned-clock-parents = <&clks IMX6UL_CLK_PLL4_AUDIO_DIV>;
+ assigned-clock-rates = <0>, <12288000>;
+
+ status = "okay";
+};
+
+&tsc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_tsc>;
+ xnur-gpio = <&gpio1 3 GPIO_ACTIVE_LOW>;
+ measure_delay_time = <0xffff>;
+ pre_charge_time = <0xfff>;
+ status = "okay";
+};
+
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart1>;
+ status = "okay";
+};
+
+&uart2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart2>;
+ fsl,uart-has-rtscts;
+ /* for DTE mode, add below change */
+ /* fsl,dte-mode; */
+ /* pinctrl-0 = <&pinctrl_uart2dte>; */
+ status = "okay";
+};
+
+&usbotg1 {
+ dr_mode = "otg";
+ srp-disable;
+ hnp-disable;
+ adp-disable;
+ status = "okay";
+};
+
+&usbotg2 {
+ dr_mode = "host";
+ disable-over-current;
+ status = "okay";
+};
+
+&usdhc1 {
+ pinctrl-names = "default", "state_100mhz", "state_200mhz";
+ pinctrl-0 = <&pinctrl_usdhc1>;
+ pinctrl-1 = <&pinctrl_usdhc1_100mhz>;
+ pinctrl-2 = <&pinctrl_usdhc1_200mhz>;
+ cd-gpios = <&gpio1 19 GPIO_ACTIVE_LOW>;
+ keep-power-in-suspend;
+ enable-sdio-wakeup;
+ vmmc-supply = <&reg_sd1_vmmc>;
+ status = "okay";
+};
+
+&usdhc2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usdhc2>;
+ no-1-8-v;
+ non-removable;
+ keep-power-in-suspend;
+ enable-sdio-wakeup;
+ status = "okay";
+};
+
+&wdog1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_wdog>;
+ fsl,ext-reset-output;
+};
diff --git a/arch/arm/boot/dts/imx6ull-pinfunc-snvs.h b/arch/arm/boot/dts/imx6ull-pinfunc-snvs.h
new file mode 100644
index 000000000000..da3f412e4269
--- /dev/null
+++ b/arch/arm/boot/dts/imx6ull-pinfunc-snvs.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+#ifndef __DTS_IMX6ULL_PINFUNC_SNVS_H
+#define __DTS_IMX6ULL_PINFUNC_SNVS_H
+/*
+ * The pin function ID is a tuple of
+ * <mux_reg conf_reg input_reg mux_mode input_val>
+ */
+#define MX6ULL_PAD_BOOT_MODE0__GPIO5_IO10 0x0000 0x0044 0x0000 0x5 0x0
+#define MX6ULL_PAD_BOOT_MODE1__GPIO5_IO11 0x0004 0x0048 0x0000 0x5 0x0
+#define MX6ULL_PAD_SNVS_TAMPER0__GPIO5_IO00 0x0008 0x004C 0x0000 0x5 0x0
+#define MX6ULL_PAD_SNVS_TAMPER1__GPIO5_IO01 0x000C 0x0050 0x0000 0x5 0x0
+#define MX6ULL_PAD_SNVS_TAMPER2__GPIO5_IO02 0x0010 0x0054 0x0000 0x5 0x0
+#define MX6ULL_PAD_SNVS_TAMPER3__GPIO5_IO03 0x0014 0x0058 0x0000 0x5 0x0
+#define MX6ULL_PAD_SNVS_TAMPER4__GPIO5_IO04 0x0018 0x005C 0x0000 0x5 0x0
+#define MX6ULL_PAD_SNVS_TAMPER5__GPIO5_IO05 0x001C 0x0060 0x0000 0x5 0x0
+#define MX6ULL_PAD_SNVS_TAMPER6__GPIO5_IO06 0x0020 0x0064 0x0000 0x5 0x0
+#define MX6ULL_PAD_SNVS_TAMPER7__GPIO5_IO07 0x0024 0x0068 0x0000 0x5 0x0
+#define MX6ULL_PAD_SNVS_TAMPER8__GPIO5_IO08 0x0028 0x006C 0x0000 0x5 0x0
+#define MX6ULL_PAD_SNVS_TAMPER9__GPIO5_IO09 0x002C 0x0070 0x0000 0x5 0x0
+
+#endif /* __DTS_IMX6ULL_PINFUNC_SNVS_H */
+
diff --git a/arch/arm/boot/dts/imx6ull-pinfunc.h b/arch/arm/boot/dts/imx6ull-pinfunc.h
index 118202336691..06c6912aac84 100644
--- a/arch/arm/boot/dts/imx6ull-pinfunc.h
+++ b/arch/arm/boot/dts/imx6ull-pinfunc.h
@@ -14,6 +14,14 @@
* The pin function ID is a tuple of
* <mux_reg conf_reg input_reg mux_mode input_val>
*/
+#define MX6ULL_PAD_ENET1_RX_DATA0__EPDC_SDCE04 0x00C4 0x0350 0x0000 0x9 0x0
+#define MX6ULL_PAD_ENET1_RX_DATA1__EPDC_SDCE05 0x00C8 0x0354 0x0000 0x9 0x0
+#define MX6ULL_PAD_ENET1_RX_EN__EPDC_SDCE06 0x00CC 0x0358 0x0000 0x9 0x0
+#define MX6ULL_PAD_ENET1_TX_DATA0__EPDC_SDCE07 0x00D0 0x035C 0x0000 0x9 0x0
+#define MX6ULL_PAD_ENET1_TX_DATA1__EPDC_SDCE08 0x00D4 0x0360 0x0000 0x9 0x0
+#define MX6ULL_PAD_ENET1_TX_EN__EPDC_SDCE09 0x00D8 0x0364 0x0000 0x9 0x0
+#define MX6ULL_PAD_ENET1_TX_CLK__EPDC_SDOED 0x00DC 0x0368 0x0000 0x9 0x0
+#define MX6ULL_PAD_ENET1_RX_ER__EPDC_SDOEZ 0x00E0 0x036C 0x0000 0x9 0x0
#define MX6ULL_PAD_ENET2_RX_DATA0__EPDC_SDDO08 0x00E4 0x0370 0x0000 0x9 0x0
#define MX6ULL_PAD_ENET2_RX_DATA1__EPDC_SDDO09 0x00E8 0x0374 0x0000 0x9 0x0
#define MX6ULL_PAD_ENET2_RX_EN__EPDC_SDDO10 0x00EC 0x0378 0x0000 0x9 0x0
@@ -40,6 +48,8 @@
#define MX6ULL_PAD_LCD_DATA16__EPDC_GDCLK 0x0158 0x03E4 0x0000 0x9 0x0
#define MX6ULL_PAD_LCD_DATA17__EPDC_GDSP 0x015C 0x03E8 0x0000 0x9 0x0
#define MX6ULL_PAD_LCD_DATA21__EPDC_SDCE1 0x016C 0x03F8 0x0000 0x9 0x0
+#define MX6ULL_PAD_LCD_DATA22__EPDC_SDCE02 0x0170 0x03FC 0x0000 0x9 0x0
+#define MX6ULL_PAD_LCD_DATA23__EPDC_SDCE03 0x0174 0x0400 0x0000 0x9 0x0
#define MX6ULL_PAD_CSI_MCLK__ESAI_TX3_RX2 0x01D4 0x0460 0x0000 0x9 0x0
#define MX6ULL_PAD_CSI_PIXCLK__ESAI_TX2_RX3 0x01D8 0x0464 0x0000 0x9 0x0
#define MX6ULL_PAD_CSI_VSYNC__ESAI_TX4_RX1 0x01DC 0x0468 0x0000 0x9 0x0
@@ -53,4 +63,30 @@
#define MX6ULL_PAD_CSI_DATA06__ESAI_TX5_RX0 0x01FC 0x0488 0x0000 0x9 0x0
#define MX6ULL_PAD_CSI_DATA07__ESAI_T0 0x0200 0x048C 0x0000 0x9 0x0
+#define MX6UL_PAD_UART1_TX_DATA__UART5_DCE_TX 0x0084 0x0310 0x0000 0x9 0x0
+#define MX6UL_PAD_UART1_TX_DATA__UART5_DTE_RX 0x0084 0x0310 0x0644 0x9 0x4
+#define MX6UL_PAD_UART1_RX_DATA__UART5_DCE_RX 0x0088 0x0314 0x0644 0x9 0x5
+#define MX6UL_PAD_UART1_RX_DATA__UART5_DTE_TX 0x0088 0x0314 0x0000 0x9 0x0
+#define MX6UL_PAD_UART1_CTS_B__UART5_DCE_CTS 0x008C 0x0318 0x0000 0x9 0x0
+#define MX6UL_PAD_UART1_CTS_B__UART5_DTE_RTS 0x008C 0x0318 0x0640 0x9 0x3
+#define MX6UL_PAD_UART1_RTS_B__UART5_DCE_RTS 0x0090 0x031C 0x0640 0x9 0x4
+#define MX6UL_PAD_UART1_RTS_B__UART5_DTE_CTS 0x0090 0x031C 0x0000 0x9 0x0
+#define MX6UL_PAD_UART4_RX_DATA__EPDC_PWRCTRL01 0x00B8 0x0344 0x0000 0x9 0x0
+#define MX6UL_PAD_UART5_TX_DATA__EPDC_PWRCTRL02 0x00BC 0x0348 0x0000 0x9 0x0
+#define MX6UL_PAD_UART5_RX_DATA__EPDC_PWRCTRL03 0x00C0 0x034C 0x0000 0x9 0x0
+
+/* Below pinfunc are different with i.MX6UL, so override them in here
+ * To avoid build warning, firstly undef them.
+ */
+#undef MX6UL_PAD_UART5_TX_DATA__UART5_DTE_RX
+#undef MX6UL_PAD_UART5_RX_DATA__UART5_DCE_RX
+#undef MX6UL_PAD_ENET1_RX_EN__UART5_DCE_RTS
+#undef MX6UL_PAD_ENET1_TX_DATA0__UART5_DTE_RTS
+#undef MX6UL_PAD_CSI_DATA02__UART5_DCE_RTS
+#define MX6UL_PAD_UART5_TX_DATA__UART5_DTE_RX 0x00BC 0x0348 0x0644 0x0 0x6
+#define MX6UL_PAD_UART5_RX_DATA__UART5_DCE_RX 0x00C0 0x034C 0x0644 0x0 0x7
+#define MX6UL_PAD_ENET1_RX_EN__UART5_DCE_RTS 0x00CC 0x0358 0x0640 0x1 0x5
+#define MX6UL_PAD_ENET1_TX_DATA0__UART5_DTE_RTS 0x00D0 0x035C 0x0640 0x1 0x6
+#define MX6UL_PAD_CSI_DATA02__UART5_DCE_RTS 0x01EC 0x0478 0x0640 0x8 0x7
+
#endif /* __DTS_IMX6ULL_PINFUNC_H */
diff --git a/arch/arm/boot/dts/imx6ull.dtsi b/arch/arm/boot/dts/imx6ull.dtsi
index 0c182917b863..88d3f878d0da 100644
--- a/arch/arm/boot/dts/imx6ull.dtsi
+++ b/arch/arm/boot/dts/imx6ull.dtsi
@@ -1,5 +1,6 @@
/*
* Copyright 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017-2018 NXP
*
* 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
@@ -39,5 +40,1180 @@
* OTHER DEALINGS IN THE SOFTWARE.
*/
-#include "imx6ul.dtsi"
+#include <dt-bindings/clock/imx6ul-clock.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
#include "imx6ull-pinfunc.h"
+#include "imx6ull-pinfunc-snvs.h"
+#include "skeleton.dtsi"
+
+/ {
+ aliases {
+ can0 = &flexcan1;
+ can1 = &flexcan2;
+ ethernet0 = &fec1;
+ ethernet1 = &fec2;
+ gpio0 = &gpio1;
+ gpio1 = &gpio2;
+ gpio2 = &gpio3;
+ gpio3 = &gpio4;
+ gpio4 = &gpio5;
+ i2c0 = &i2c1;
+ i2c1 = &i2c2;
+ i2c2 = &i2c3;
+ i2c3 = &i2c4;
+ mmc0 = &usdhc1;
+ mmc1 = &usdhc2;
+ serial0 = &uart1;
+ serial1 = &uart2;
+ serial2 = &uart3;
+ serial3 = &uart4;
+ serial4 = &uart5;
+ serial5 = &uart6;
+ serial6 = &uart7;
+ serial7 = &uart8;
+ spi0 = &ecspi1;
+ spi1 = &ecspi2;
+ spi2 = &ecspi3;
+ spi3 = &ecspi4;
+ usbphy0 = &usbphy1;
+ usbphy1 = &usbphy2;
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu0: cpu@0 {
+ compatible = "arm,cortex-a7";
+ device_type = "cpu";
+ reg = <0>;
+ clock-latency = <61036>; /* two CLK32 periods */
+ operating-points = <
+ /* kHz uV */
+ 900000 1275000
+ 792000 1225000
+ 528000 1175000
+ 396000 1025000
+ 198000 950000
+ >;
+ fsl,soc-operating-points = <
+ /* KHz uV */
+ 900000 1250000
+ 792000 1175000
+ 528000 1175000
+ 396000 1175000
+ 198000 1175000
+ >;
+ fsl,low-power-run;
+ clocks = <&clks IMX6UL_CLK_ARM>,
+ <&clks IMX6UL_CLK_PLL2_BUS>,
+ <&clks IMX6UL_CLK_PLL2_PFD2>,
+ <&clks IMX6UL_CA7_SECONDARY_SEL>,
+ <&clks IMX6UL_CLK_STEP>,
+ <&clks IMX6UL_CLK_PLL1_SW>,
+ <&clks IMX6UL_CLK_PLL1_SYS>,
+ <&clks IMX6UL_PLL1_BYPASS>,
+ <&clks IMX6UL_CLK_PLL1>,
+ <&clks IMX6UL_PLL1_BYPASS_SRC>,
+ <&clks IMX6UL_CLK_OSC>;
+ clock-names = "arm", "pll2_bus", "pll2_pfd2_396m", "secondary_sel", "step",
+ "pll1_sw", "pll1_sys", "pll1_bypass", "pll1", "pll1_bypass_src", "osc";
+ arm-supply = <&reg_arm>;
+ soc-supply = <&reg_soc>;
+ };
+ };
+
+ intc: interrupt-controller@00a01000 {
+ compatible = "arm,cortex-a7-gic";
+ #interrupt-cells = <3>;
+ interrupt-controller;
+ reg = <0x00a01000 0x1000>,
+ <0x00a02000 0x100>;
+ };
+
+ clocks {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ckil: clock@0 {
+ compatible = "fixed-clock";
+ reg = <0>;
+ #clock-cells = <0>;
+ clock-frequency = <32768>;
+ clock-output-names = "ckil";
+ };
+
+ osc: clock@1 {
+ compatible = "fixed-clock";
+ reg = <1>;
+ #clock-cells = <0>;
+ clock-frequency = <24000000>;
+ clock-output-names = "osc";
+ };
+
+ ipp_di0: clock@2 {
+ compatible = "fixed-clock";
+ reg = <2>;
+ #clock-cells = <0>;
+ clock-frequency = <0>;
+ clock-output-names = "ipp_di0";
+ };
+
+ ipp_di1: clock@3 {
+ compatible = "fixed-clock";
+ reg = <3>;
+ #clock-cells = <0>;
+ clock-frequency = <0>;
+ clock-output-names = "ipp_di1";
+ };
+ };
+
+ soc {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "simple-bus";
+ interrupt-parent = <&gpc>;
+ ranges;
+
+ busfreq {
+ compatible = "fsl,imx_busfreq";
+ clocks = <&clks IMX6UL_CLK_PLL2_PFD2>, <&clks IMX6UL_CLK_PLL2_198M>,
+ <&clks IMX6UL_CLK_PLL2_BUS>, <&clks IMX6UL_CLK_ARM>,
+ <&clks IMX6UL_CLK_PLL3_USB_OTG>, <&clks IMX6UL_CLK_PERIPH>,
+ <&clks IMX6UL_CLK_PERIPH_PRE>, <&clks IMX6UL_CLK_PERIPH_CLK2>,
+ <&clks IMX6UL_CLK_PERIPH_CLK2_SEL>, <&clks IMX6UL_CLK_OSC>,
+ <&clks IMX6UL_CLK_AHB>, <&clks IMX6UL_CLK_AXI>,
+ <&clks IMX6UL_CLK_PERIPH2>, <&clks IMX6UL_CLK_PERIPH2_PRE>,
+ <&clks IMX6UL_CLK_PERIPH2_CLK2>, <&clks IMX6UL_CLK_PERIPH2_CLK2_SEL>,
+ <&clks IMX6UL_CLK_STEP>, <&clks IMX6UL_CLK_MMDC_P0_FAST>, <&clks IMX6UL_PLL1_BYPASS_SRC>,
+ <&clks IMX6UL_PLL1_BYPASS>, <&clks IMX6UL_CLK_PLL1_SYS>, <&clks IMX6UL_CLK_PLL1_SW>,
+ <&clks IMX6UL_CLK_PLL1>;
+ clock-names = "pll2_pfd2_396m", "pll2_198m", "pll2_bus", "arm", "pll3_usb_otg",
+ "periph", "periph_pre", "periph_clk2", "periph_clk2_sel", "osc",
+ "ahb", "ocram", "periph2", "periph2_pre", "periph2_clk2", "periph2_clk2_sel",
+ "step", "mmdc", "pll1_bypass_src", "pll1_bypass", "pll1_sys", "pll1_sw", "pll1";
+ fsl,max_ddr_freq = <400000000>;
+ };
+
+ pmu {
+ compatible = "arm,cortex-a7-pmu";
+ interrupts = <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
+
+ ocrams: sram@00900000 {
+ compatible = "fsl,lpm-sram";
+ reg = <0x00900000 0x4000>;
+ };
+
+ ocrams_ddr: sram@00904000 {
+ compatible = "fsl,ddr-lpm-sram";
+ reg = <0x00904000 0x1000>;
+ };
+
+ ocram: sram@00905000 {
+ compatible = "mmio-sram";
+ reg = <0x00905000 0x1B000>;
+ };
+
+ ocram_optee: sram@00918000 {
+ compatible = "fsl,optee-lpm-sram";
+ reg = <0x00918000 0x8000>;
+ overw_reg = <&ocram 0x00905000 0x13000>;
+ };
+
+ dma_apbh: dma-apbh@01804000 {
+ compatible = "fsl,imx6ul-dma-apbh", "fsl,imx28-dma-apbh";
+ reg = <0x01804000 0x2000>;
+ interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "gpmi0", "gpmi1", "gpmi2", "gpmi3";
+ #dma-cells = <1>;
+ dma-channels = <4>;
+ clocks = <&clks IMX6UL_CLK_APBHDMA>;
+ };
+
+ gpmi: gpmi-nand@01806000{
+ compatible = "fsl,imx6ull-gpmi-nand", "fsl, imx6ul-gpmi-nand";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x01806000 0x2000>, <0x01808000 0x4000>;
+ reg-names = "gpmi-nand", "bch";
+ interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "bch";
+ clocks = <&clks IMX6UL_CLK_GPMI_IO>,
+ <&clks IMX6UL_CLK_GPMI_APB>,
+ <&clks IMX6UL_CLK_GPMI_BCH>,
+ <&clks IMX6UL_CLK_GPMI_BCH_APB>,
+ <&clks IMX6UL_CLK_PER_BCH>;
+ clock-names = "gpmi_io", "gpmi_apb", "gpmi_bch",
+ "gpmi_bch_apb", "per1_bch";
+ dmas = <&dma_apbh 0>;
+ dma-names = "rx-tx";
+ status = "disabled";
+ };
+
+ aips1: aips-bus@02000000 {
+ compatible = "fsl,aips-bus", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x02000000 0x100000>;
+ ranges;
+
+ spba-bus@02000000 {
+ compatible = "fsl,spba-bus", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x02000000 0x40000>;
+ ranges;
+
+ spdif: spdif@02004000 {
+ compatible = "fsl,imx6ul-spdif", "fsl,imx35-spdif";
+ reg = <0x02004000 0x4000>;
+ interrupts = <GIC_SPI 52 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&sdma 41 18 0>,
+ <&sdma 42 18 0>;
+ dma-names = "rx", "tx";
+ clocks = <&clks IMX6UL_CLK_SPDIF_GCLK>,
+ <&clks IMX6UL_CLK_OSC>,
+ <&clks IMX6UL_CLK_SPDIF>,
+ <&clks IMX6UL_CLK_DUMMY>, <&clks IMX6UL_CLK_DUMMY>, <&clks IMX6UL_CLK_DUMMY>,
+ <&clks IMX6UL_CLK_IPG>,
+ <&clks IMX6UL_CLK_DUMMY>, <&clks IMX6UL_CLK_DUMMY>,
+ <&clks IMX6UL_CLK_SPBA>;
+ clock-names = "core", "rxtx0",
+ "rxtx1", "rxtx2",
+ "rxtx3", "rxtx4",
+ "rxtx5", "rxtx6",
+ "rxtx7", "spba";
+ status = "disabled";
+ };
+
+ ecspi1: ecspi@02008000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx6ul-ecspi", "fsl,imx51-ecspi";
+ reg = <0x02008000 0x4000>;
+ interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6UL_CLK_ECSPI1>,
+ <&clks IMX6UL_CLK_ECSPI1>;
+ clock-names = "ipg", "per";
+ dmas = <&sdma 3 7 1>, <&sdma 4 7 2>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ ecspi2: ecspi@0200c000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx6ul-ecspi", "fsl,imx51-ecspi";
+ reg = <0x0200c000 0x4000>;
+ interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6UL_CLK_ECSPI2>,
+ <&clks IMX6UL_CLK_ECSPI2>;
+ clock-names = "ipg", "per";
+ dmas = <&sdma 5 7 1>, <&sdma 6 7 2>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ ecspi3: ecspi@02010000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx6ul-ecspi", "fsl,imx51-ecspi";
+ reg = <0x02010000 0x4000>;
+ interrupts = <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6UL_CLK_ECSPI3>,
+ <&clks IMX6UL_CLK_ECSPI3>;
+ clock-names = "ipg", "per";
+ dmas = <&sdma 7 7 1>, <&sdma 8 7 2>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ ecspi4: ecspi@02014000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx6ul-ecspi", "fsl,imx51-ecspi";
+ reg = <0x02014000 0x4000>;
+ interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6UL_CLK_ECSPI4>,
+ <&clks IMX6UL_CLK_ECSPI4>;
+ clock-names = "ipg", "per";
+ dmas = <&sdma 9 7 1>, <&sdma 10 7 2>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ uart7: serial@02018000 {
+ compatible = "fsl,imx6ul-uart",
+ "fsl,imx6q-uart", "fsl,imx21-uart";
+ reg = <0x02018000 0x4000>;
+ interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6UL_CLK_UART7_IPG>,
+ <&clks IMX6UL_CLK_UART7_SERIAL>;
+ clock-names = "ipg", "per";
+ dmas = <&sdma 43 4 0>, <&sdma 44 4 0>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ uart1: serial@02020000 {
+ compatible = "fsl,imx6ul-uart",
+ "fsl,imx6q-uart", "fsl,imx21-uart";
+ reg = <0x02020000 0x4000>;
+ interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6UL_CLK_UART1_IPG>,
+ <&clks IMX6UL_CLK_UART1_SERIAL>;
+ clock-names = "ipg", "per";
+ status = "disabled";
+ };
+
+ esai: esai@02024000 {
+ compatible = "fsl,imx6ull-esai";
+ reg = <0x02024000 0x4000>;
+ interrupts = <GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6ULL_CLK_ESAI_IPG>,
+ <&clks IMX6ULL_CLK_ESAI_MEM>,
+ <&clks IMX6ULL_CLK_ESAI_EXTAL>,
+ <&clks IMX6ULL_CLK_ESAI_IPG>,
+ <&clks IMX6UL_CLK_SPBA>;
+ clock-names = "core", "mem", "extal",
+ "fsys", "spba";
+ dmas = <&sdma 0 21 0>, <&sdma 47 21 0>;
+ dma-names = "rx", "tx";
+ dma-source = <&gpr 0 14 0 15>;
+ status = "disabled";
+ };
+
+ sai1: sai@02028000 {
+ compatible = "fsl,imx6ul-sai",
+ "fsl,imx6sx-sai";
+ reg = <0x02028000 0x4000>;
+ interrupts = <GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6UL_CLK_SAI1_IPG>,
+ <&clks IMX6UL_CLK_DUMMY>,
+ <&clks IMX6UL_CLK_SAI1>,
+ <&clks 0>, <&clks 0>;
+ clock-names = "bus", "mclk0", "mclk1", "mclk2", "mclk3";
+ dma-names = "rx", "tx";
+ dmas = <&sdma 35 24 0>, <&sdma 36 24 0>;
+ status = "disabled";
+ };
+
+ sai2: sai@0202c000 {
+ compatible = "fsl,imx6ul-sai",
+ "fsl,imx6sx-sai";
+ reg = <0x0202c000 0x4000>;
+ interrupts = <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6UL_CLK_SAI2_IPG>,
+ <&clks IMX6UL_CLK_DUMMY>,
+ <&clks IMX6UL_CLK_SAI2>,
+ <&clks 0>, <&clks 0>;
+ clock-names = "bus", "mclk0", "mclk1", "mclk2", "mclk3";
+ dma-names = "rx", "tx";
+ dmas = <&sdma 37 24 0>, <&sdma 38 24 0>;
+ status = "disabled";
+ };
+
+ sai3: sai@02030000 {
+ compatible = "fsl,imx6ul-sai",
+ "fsl,imx6sx-sai";
+ reg = <0x02030000 0x4000>;
+ interrupts = <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6UL_CLK_SAI3_IPG>,
+ <&clks IMX6UL_CLK_DUMMY>,
+ <&clks IMX6UL_CLK_SAI3>,
+ <&clks 0>, <&clks 0>;
+ clock-names = "bus", "mclk0", "mclk1", "mclk2", "mclk3";
+ dma-names = "rx", "tx";
+ dmas = <&sdma 39 24 0>, <&sdma 40 24 0>;
+ status = "disabled";
+ };
+
+ asrc: asrc@02034000 {
+ compatible = "fsl,imx53-asrc";
+ reg = <0x02034000 0x4000>;
+ interrupts = <GIC_SPI 50 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6UL_CLK_ASRC_IPG>,
+ <&clks IMX6UL_CLK_ASRC_MEM>, <&clks 0>,
+ <&clks 0>, <&clks 0>, <&clks 0>, <&clks 0>,
+ <&clks 0>, <&clks 0>, <&clks 0>, <&clks 0>,
+ <&clks 0>, <&clks 0>, <&clks 0>, <&clks 0>,
+ <&clks IMX6UL_CLK_SPDIF>, <&clks 0>, <&clks 0>,
+ <&clks IMX6UL_CLK_SPBA>;
+ clock-names = "mem", "ipg", "asrck_0",
+ "asrck_1", "asrck_2", "asrck_3", "asrck_4",
+ "asrck_5", "asrck_6", "asrck_7", "asrck_8",
+ "asrck_9", "asrck_a", "asrck_b", "asrck_c",
+ "asrck_d", "asrck_e", "asrck_f", "spba";
+ dmas = <&sdma 17 23 1>, <&sdma 18 23 1>, <&sdma 19 23 1>,
+ <&sdma 20 23 1>, <&sdma 21 23 1>, <&sdma 22 23 1>;
+ dma-names = "rxa", "rxb", "rxc",
+ "txa", "txb", "txc";
+ fsl,asrc-rate = <48000>;
+ fsl,asrc-width = <16>;
+ status = "okay";
+ };
+ };
+
+ tsc: tsc@02040000 {
+ compatible = "fsl,imx6ul-tsc";
+ reg = <0x02040000 0x4000>, <0x0219c000 0x4000>;
+ interrupts = <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6UL_CLK_IPG>,
+ <&clks IMX6UL_CLK_ADC2>;
+ clock-names = "tsc", "adc";
+ status = "disabled";
+ };
+
+ pwm1: pwm@02080000 {
+ compatible = "fsl,imx6ul-pwm", "fsl,imx27-pwm";
+ reg = <0x02080000 0x4000>;
+ interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6UL_CLK_PWM1>,
+ <&clks IMX6UL_CLK_PWM1>;
+ clock-names = "ipg", "per";
+ #pwm-cells = <2>;
+ };
+
+ pwm2: pwm@02084000 {
+ compatible = "fsl,imx6ul-pwm", "fsl,imx27-pwm";
+ reg = <0x02084000 0x4000>;
+ interrupts = <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6UL_CLK_DUMMY>,
+ <&clks IMX6UL_CLK_DUMMY>;
+ clock-names = "ipg", "per";
+ #pwm-cells = <2>;
+ };
+
+ pwm3: pwm@02088000 {
+ compatible = "fsl,imx6ul-pwm", "fsl,imx27-pwm";
+ reg = <0x02088000 0x4000>;
+ interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6UL_CLK_PWM3>,
+ <&clks IMX6UL_CLK_PWM3>;
+ clock-names = "ipg", "per";
+ #pwm-cells = <2>;
+ };
+
+ pwm4: pwm@0208c000 {
+ compatible = "fsl,imx6ul-pwm", "fsl,imx27-pwm";
+ reg = <0x0208c000 0x4000>;
+ interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6UL_CLK_DUMMY>,
+ <&clks IMX6UL_CLK_DUMMY>;
+ clock-names = "ipg", "per";
+ #pwm-cells = <2>;
+ };
+
+ flexcan1: can@02090000 {
+ compatible = "fsl,imx6ul-flexcan", "fsl,imx6q-flexcan";
+ reg = <0x02090000 0x4000>;
+ interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6UL_CLK_CAN1_IPG>,
+ <&clks IMX6UL_CLK_CAN1_SERIAL>;
+ clock-names = "ipg", "per";
+ stop-mode = <&gpr 0x10 1 0x10 17>;
+ status = "disabled";
+ };
+
+ flexcan2: can@02094000 {
+ compatible = "fsl,imx6ul-flexcan", "fsl,imx6q-flexcan";
+ reg = <0x02094000 0x4000>;
+ interrupts = <GIC_SPI 111 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6UL_CLK_CAN2_IPG>,
+ <&clks IMX6UL_CLK_CAN2_SERIAL>;
+ clock-names = "ipg", "per";
+ stop-mode = <&gpr 0x10 2 0x10 18>;
+ status = "disabled";
+ };
+
+ gpt1: gpt@02098000 {
+ compatible = "fsl,imx6ul-gpt", "fsl,imx31-gpt";
+ reg = <0x02098000 0x4000>;
+ interrupts = <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6UL_CLK_GPT1_BUS>,
+ <&clks IMX6UL_CLK_GPT_3M>;
+ clock-names = "ipg", "osc_per";
+ };
+
+ gpio1: gpio@0209c000 {
+ compatible = "fsl,imx6ul-gpio", "fsl,imx35-gpio";
+ reg = <0x0209c000 0x4000>;
+ interrupts = <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio2: gpio@020a0000 {
+ compatible = "fsl,imx6ul-gpio", "fsl,imx35-gpio";
+ reg = <0x020a0000 0x4000>;
+ interrupts = <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio3: gpio@020a4000 {
+ compatible = "fsl,imx6ul-gpio", "fsl,imx35-gpio";
+ reg = <0x020a4000 0x4000>;
+ interrupts = <GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio4: gpio@020a8000 {
+ compatible = "fsl,imx6ul-gpio", "fsl,imx35-gpio";
+ reg = <0x020a8000 0x4000>;
+ interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio5: gpio@020ac000 {
+ compatible = "fsl,imx6ul-gpio", "fsl,imx35-gpio";
+ reg = <0x020ac000 0x4000>;
+ interrupts = <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ snvslp: snvs@020b0000 {
+ compatible = "fsl,imx6ul-snvs";
+ reg = <0x020b0000 0x4000>;
+ interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ fec2: ethernet@020b4000 {
+ compatible = "fsl,imx6ul-fec", "fsl,imx6q-fec";
+ reg = <0x020b4000 0x4000>;
+ interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6UL_CLK_ENET>,
+ <&clks IMX6UL_CLK_ENET_AHB>,
+ <&clks IMX6UL_CLK_ENET_PTP>,
+ <&clks IMX6UL_CLK_ENET2_REF_125M>,
+ <&clks IMX6UL_CLK_ENET2_REF_125M>;
+ clock-names = "ipg", "ahb", "ptp",
+ "enet_clk_ref", "enet_out";
+ stop-mode = <&gpr 0x10 4>;
+ fsl,num-tx-queues=<1>;
+ fsl,num-rx-queues=<1>;
+ fsl,magic-packet;
+ fsl,wakeup_irq = <0>;
+ status = "disabled";
+ };
+
+ kpp: kpp@020b8000 {
+ compatible = "fsl,imx6ul-kpp", "fsl,imx21-kpp";
+ reg = <0x020b8000 0x4000>;
+ interrupts = <GIC_SPI 82 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6UL_CLK_DUMMY>;
+ status = "disabled";
+ };
+
+ wdog1: wdog@020bc000 {
+ compatible = "fsl,imx6ul-wdt", "fsl,imx21-wdt";
+ reg = <0x020bc000 0x4000>;
+ interrupts = <GIC_SPI 80 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6UL_CLK_WDOG1>;
+ };
+
+ wdog2: wdog@020c0000 {
+ compatible = "fsl,imx6ul-wdt", "fsl,imx21-wdt";
+ reg = <0x020c0000 0x4000>;
+ interrupts = <GIC_SPI 81 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6UL_CLK_WDOG2>;
+ status = "disabled";
+ };
+
+ clks: ccm@020c4000 {
+ compatible = "fsl,imx6ul-ccm";
+ reg = <0x020c4000 0x4000>;
+ interrupts = <GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 88 IRQ_TYPE_LEVEL_HIGH>;
+ #clock-cells = <1>;
+ clocks = <&ckil>, <&osc>, <&ipp_di0>, <&ipp_di1>;
+ clock-names = "ckil", "osc", "ipp_di0", "ipp_di1";
+ };
+
+ anatop: anatop@020c8000 {
+ compatible = "fsl,imx6ul-anatop", "fsl,imx6q-anatop",
+ "syscon", "simple-bus";
+ reg = <0x020c8000 0x1000>;
+ interrupts = <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 127 IRQ_TYPE_LEVEL_HIGH>;
+
+ reg_3p0: regulator-3p0@120 {
+ compatible = "fsl,anatop-regulator";
+ regulator-name = "vdd3p0";
+ regulator-min-microvolt = <2625000>;
+ regulator-max-microvolt = <3400000>;
+ anatop-reg-offset = <0x120>;
+ anatop-vol-bit-shift = <8>;
+ anatop-vol-bit-width = <5>;
+ anatop-min-bit-val = <0>;
+ anatop-min-voltage = <2625000>;
+ anatop-max-voltage = <3400000>;
+ anatop-enable-bit = <0>;
+ };
+
+ reg_arm: regulator-vddcore@140 {
+ compatible = "fsl,anatop-regulator";
+ regulator-name = "cpu";
+ regulator-min-microvolt = <725000>;
+ regulator-max-microvolt = <1450000>;
+ regulator-always-on;
+ anatop-reg-offset = <0x140>;
+ anatop-vol-bit-shift = <0>;
+ anatop-vol-bit-width = <5>;
+ anatop-delay-reg-offset = <0x170>;
+ anatop-delay-bit-shift = <24>;
+ anatop-delay-bit-width = <2>;
+ anatop-min-bit-val = <1>;
+ anatop-min-voltage = <725000>;
+ anatop-max-voltage = <1450000>;
+ };
+
+ reg_soc: regulator-vddsoc@140 {
+ compatible = "fsl,anatop-regulator";
+ regulator-name = "vddsoc";
+ regulator-min-microvolt = <725000>;
+ regulator-max-microvolt = <1450000>;
+ regulator-always-on;
+ anatop-reg-offset = <0x140>;
+ anatop-vol-bit-shift = <18>;
+ anatop-vol-bit-width = <5>;
+ anatop-delay-reg-offset = <0x170>;
+ anatop-delay-bit-shift = <28>;
+ anatop-delay-bit-width = <2>;
+ anatop-min-bit-val = <1>;
+ anatop-min-voltage = <725000>;
+ anatop-max-voltage = <1450000>;
+ };
+ };
+
+ usbphy1: usbphy@020c9000 {
+ compatible = "fsl,imx6ul-usbphy", "fsl,imx23-usbphy";
+ reg = <0x020c9000 0x1000>;
+ interrupts = <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6UL_CLK_USBPHY1>;
+ phy-3p0-supply = <&reg_3p0>;
+ fsl,anatop = <&anatop>;
+ };
+
+ usbphy2: usbphy@020ca000 {
+ compatible = "fsl,imx6ul-usbphy", "fsl,imx23-usbphy";
+ reg = <0x020ca000 0x1000>;
+ interrupts = <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6UL_CLK_USBPHY2>;
+ phy-3p0-supply = <&reg_3p0>;
+ fsl,anatop = <&anatop>;
+ };
+
+ tempmon: tempmon {
+ compatible = "fsl,imx6ul-tempmon", "fsl,imx6sx-tempmon";
+ interrupts = <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>;
+ fsl,tempmon = <&anatop>;
+ fsl,tempmon-data = <&ocotp>;
+ clocks = <&clks IMX6UL_CLK_PLL3_USB_OTG>;
+ };
+
+ snvs: snvs@020cc000 {
+ compatible = "fsl,sec-v4.0-mon", "syscon", "simple-mfd";
+ reg = <0x020cc000 0x4000>;
+
+ snvs_rtc: snvs-rtc-lp {
+ compatible = "fsl,sec-v4.0-mon-rtc-lp";
+ regmap = <&snvs>;
+ offset = <0x34>;
+ interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ snvs_poweroff: snvs-poweroff {
+ compatible = "syscon-poweroff";
+ regmap = <&snvs>;
+ offset = <0x38>;
+ mask = <0x61>;
+ };
+
+ snvs_pwrkey: snvs-powerkey {
+ compatible = "fsl,sec-v4.0-pwrkey";
+ regmap = <&snvs>;
+ interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>;
+ linux,keycode = <KEY_POWER>;
+ wakeup-source;
+ };
+ };
+
+ epit1: epit@020d0000 {
+ reg = <0x020d0000 0x4000>;
+ interrupts = <GIC_SPI 56 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ epit2: epit@020d4000 {
+ reg = <0x020d4000 0x4000>;
+ interrupts = <GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ src: src@020d8000 {
+ compatible = "fsl,imx6ul-src", "fsl,imx51-src";
+ reg = <0x020d8000 0x4000>;
+ interrupts = <GIC_SPI 91 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>;
+ #reset-cells = <1>;
+ };
+
+ gpc: gpc@020dc000 {
+ compatible = "fsl,imx6ul-gpc", "fsl,imx6q-gpc";
+ reg = <0x020dc000 0x4000>;
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ interrupts = <GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-parent = <&intc>;
+ fsl,mf-mix-wakeup-irq = <0xfc00000 0x7d00 0x0 0x1400640>;
+ };
+
+ iomuxc: iomuxc@020e0000 {
+ compatible = "fsl,imx6ul-iomuxc";
+ reg = <0x020e0000 0x4000>;
+ };
+
+ gpr: iomuxc-gpr@020e4000 {
+ compatible = "fsl,imx6ul-iomuxc-gpr",
+ "fsl,imx6q-iomuxc-gpr", "syscon";
+ reg = <0x020e4000 0x4000>;
+ };
+
+ mqs: mqs {
+ compatible = "fsl,imx6sx-mqs";
+ gpr = <&gpr>;
+ status = "disabled";
+ };
+
+ gpt2: gpt@020e8000 {
+ compatible = "fsl,imx6ul-gpt", "fsl,imx31-gpt";
+ reg = <0x020e8000 0x4000>;
+ interrupts = <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6UL_CLK_DUMMY>,
+ <&clks IMX6UL_CLK_DUMMY>;
+ clock-names = "ipg", "per";
+ };
+
+ sdma: sdma@020ec000 {
+ compatible = "fsl,imx6ul-sdma", "fsl,imx35-sdma";
+ reg = <0x020ec000 0x4000>;
+ interrupts = <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6UL_CLK_SDMA>,
+ <&clks IMX6UL_CLK_SDMA>;
+ clock-names = "ipg", "ahb";
+ #dma-cells = <3>;
+ iram = <&ocram>;
+ fsl,sdma-ram-script-name = "imx/sdma/sdma-imx6q.bin";
+ };
+
+ pwm5: pwm@020f0000 {
+ compatible = "fsl,imx6ul-pwm", "fsl,imx27-pwm";
+ reg = <0x020f0000 0x4000>;
+ interrupts = <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6UL_CLK_DUMMY>,
+ <&clks IMX6UL_CLK_DUMMY>;
+ clock-names = "ipg", "per";
+ #pwm-cells = <2>;
+ };
+
+ pwm6: pwm@020f4000 {
+ compatible = "fsl,imx6ul-pwm", "fsl,imx27-pwm";
+ reg = <0x020f4000 0x4000>;
+ interrupts = <GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6UL_CLK_DUMMY>,
+ <&clks IMX6UL_CLK_DUMMY>;
+ clock-names = "ipg", "per";
+ #pwm-cells = <2>;
+ };
+
+ pwm7: pwm@020f8000 {
+ compatible = "fsl,imx6ul-pwm", "fsl,imx27-pwm";
+ reg = <0x020f8000 0x4000>;
+ interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6UL_CLK_DUMMY>,
+ <&clks IMX6UL_CLK_DUMMY>;
+ clock-names = "ipg", "per";
+ #pwm-cells = <2>;
+ };
+
+ pwm8: pwm@020fc000 {
+ compatible = "fsl,imx6ul-pwm", "fsl,imx27-pwm";
+ reg = <0x020fc000 0x4000>;
+ interrupts = <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6UL_CLK_DUMMY>,
+ <&clks IMX6UL_CLK_DUMMY>;
+ clock-names = "ipg", "per";
+ #pwm-cells = <2>;
+ };
+ };
+
+ aips2: aips-bus@02100000 {
+ compatible = "fsl,aips-bus", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x02100000 0x100000>;
+ ranges;
+
+ usbotg1: usb@02184000 {
+ compatible = "fsl,imx6ul-usb", "fsl,imx27-usb";
+ reg = <0x02184000 0x200>;
+ interrupts = <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6UL_CLK_USBOH3>;
+ fsl,usbphy = <&usbphy1>;
+ fsl,usbmisc = <&usbmisc 0>;
+ fsl,anatop = <&anatop>;
+ ahb-burst-config = <0x0>;
+ tx-burst-size-dword = <0x10>;
+ rx-burst-size-dword = <0x10>;
+ status = "disabled";
+ };
+
+ usbotg2: usb@02184200 {
+ compatible = "fsl,imx6ul-usb", "fsl,imx27-usb";
+ reg = <0x02184200 0x200>;
+ interrupts = <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6UL_CLK_USBOH3>;
+ fsl,usbphy = <&usbphy2>;
+ fsl,usbmisc = <&usbmisc 1>;
+ ahb-burst-config = <0x0>;
+ tx-burst-size-dword = <0x10>;
+ rx-burst-size-dword = <0x10>;
+ status = "disabled";
+ };
+
+ usbmisc: usbmisc@02184800 {
+ #index-cells = <1>;
+ compatible = "fsl,imx6ul-usbmisc", "fsl,imx6q-usbmisc";
+ reg = <0x02184800 0x200>;
+ };
+
+ fec1: ethernet@02188000 {
+ compatible = "fsl,imx6ul-fec", "fsl,imx6q-fec";
+ reg = <0x02188000 0x4000>;
+ interrupts = <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6UL_CLK_ENET>,
+ <&clks IMX6UL_CLK_ENET_AHB>,
+ <&clks IMX6UL_CLK_ENET_PTP>,
+ <&clks IMX6UL_CLK_ENET_REF>,
+ <&clks IMX6UL_CLK_ENET_REF>;
+ clock-names = "ipg", "ahb", "ptp",
+ "enet_clk_ref", "enet_out";
+ stop-mode = <&gpr 0x10 3>;
+ fsl,num-tx-queues=<1>;
+ fsl,num-rx-queues=<1>;
+ fsl,magic-packet;
+ fsl,wakeup_irq = <0>;
+ status = "disabled";
+ };
+
+ usdhc1: usdhc@02190000 {
+ compatible = "fsl,imx6ull-usdhc", "fsl,imx6sx-usdhc";
+ reg = <0x02190000 0x4000>;
+ interrupts = <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6UL_CLK_USDHC1>,
+ <&clks IMX6UL_CLK_USDHC1>,
+ <&clks IMX6UL_CLK_USDHC1>;
+ clock-names = "ipg", "ahb", "per";
+ assigned-clocks = <&clks IMX6UL_CLK_USDHC1_SEL>, <&clks IMX6UL_CLK_USDHC1>;
+ assigned-clock-parents = <&clks IMX6UL_CLK_PLL2_PFD2>;
+ assigned-clock-rates = <0>, <132000000>;
+ bus-width = <4>;
+ fsl,tuning-step= <2>;
+ status = "disabled";
+ };
+
+ usdhc2: usdhc@02194000 {
+ compatible = "fsl,imx6ull-usdhc", "fsl,imx6sx-usdhc";
+ reg = <0x02194000 0x4000>;
+ interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6UL_CLK_USDHC2>,
+ <&clks IMX6UL_CLK_USDHC2>,
+ <&clks IMX6UL_CLK_USDHC2>;
+ clock-names = "ipg", "ahb", "per";
+ assigned-clocks = <&clks IMX6UL_CLK_USDHC2_SEL>, <&clks IMX6UL_CLK_USDHC2>;
+ assigned-clock-parents = <&clks IMX6UL_CLK_PLL2_PFD2>;
+ assigned-clock-rates = <0>, <132000000>;
+ bus-width = <4>;
+ fsl,tuning-step= <2>;
+ status = "disabled";
+ };
+
+ adc1: adc@02198000 {
+ compatible = "fsl,imx6ul-adc", "fsl,vf610-adc";
+ reg = <0x02198000 0x4000>;
+ interrupts = <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6UL_CLK_ADC1>;
+ num-channels = <2>;
+ clock-names = "adc";
+ status = "disabled";
+ };
+
+ i2c1: i2c@021a0000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx6ul-i2c", "fsl,imx21-i2c";
+ reg = <0x021a0000 0x4000>;
+ interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6UL_CLK_I2C1>;
+ status = "disabled";
+ };
+
+ i2c2: i2c@021a4000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx6ul-i2c", "fsl,imx21-i2c";
+ reg = <0x021a4000 0x4000>;
+ interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6UL_CLK_I2C2>;
+ status = "disabled";
+ };
+
+ i2c3: i2c@021a8000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx6ul-i2c", "fsl,imx21-i2c";
+ reg = <0x021a8000 0x4000>;
+ interrupts = <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6UL_CLK_I2C3>;
+ status = "disabled";
+ };
+
+ romcp@021ac000 {
+ compatible = "fsl,imx6ul-romcp", "syscon";
+ reg = <0x021ac000 0x4000>;
+ };
+
+ mmdc: mmdc@021b0000 {
+ compatible = "fsl,imx6ul-mmdc", "fsl,imx6q-mmdc";
+ reg = <0x021b0000 0x4000>;
+ };
+
+ weim: weim@021b8000 {
+ compatible = "fsl,imx6ul-weim", "fsl,imx6q-weim";
+ reg = <0x021b8000 0x4000>;
+ interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6UL_CLK_DUMMY>;
+ };
+
+ ocotp: ocotp-ctrl@021bc000 {
+ compatible = "fsl,imx6ull-ocotp", "syscon";
+ reg = <0x021bc000 0x4000>;
+ clocks = <&clks IMX6UL_CLK_OCOTP>;
+ };
+
+ csu: csu@021c0000 {
+ compatible = "fsl,imx6ul-csu";
+ reg = <0x021c0000 0x4000>;
+ interrupts = <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
+
+ csi: csi@021c4000 {
+ compatible = "fsl,imx6ul-csi", "fsl,imx6s-csi";
+ reg = <0x021c4000 0x4000>;
+ interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6UL_CLK_DUMMY>,
+ <&clks IMX6UL_CLK_CSI>,
+ <&clks IMX6UL_CLK_DUMMY>;
+ clock-names = "disp-axi", "csi_mclk", "disp_dcic";
+ status = "disabled";
+ };
+
+ lcdif: lcdif@021c8000 {
+ compatible = "fsl,imx6ul-lcdif", "fsl,imx28-lcdif";
+ reg = <0x021c8000 0x4000>;
+ interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6UL_CLK_LCDIF_PIX>,
+ <&clks IMX6UL_CLK_LCDIF_APB>,
+ <&clks IMX6UL_CLK_DUMMY>;
+ clock-names = "pix", "axi", "disp_axi";
+ status = "disabled";
+ };
+
+ pxp: pxp@021cc000 {
+ compatible = "fsl,imx6ull-pxp-dma", "fsl,imx7d-pxp-dma";
+ reg = <0x021cc000 0x4000>;
+ interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6UL_CLK_DUMMY>, <&clks IMX6UL_CLK_PXP>;
+ clock-names = "pxp_ipg", "pxp_axi";
+ status = "disabled";
+ };
+
+ qspi: qspi@021e0000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx6ull-qspi", "fsl,imx6ul-qspi";
+ reg = <0x021e0000 0x4000>, <0x60000000 0x10000000>;
+ reg-names = "QuadSPI", "QuadSPI-memory";
+ interrupts = <GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6UL_CLK_QSPI>,
+ <&clks IMX6UL_CLK_QSPI>;
+ clock-names = "qspi_en", "qspi";
+ status = "disabled";
+ };
+
+ uart2: serial@021e8000 {
+ compatible = "fsl,imx6ul-uart",
+ "fsl,imx6q-uart", "fsl,imx21-uart";
+ reg = <0x021e8000 0x4000>;
+ interrupts = <GIC_SPI 27 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6UL_CLK_UART2_IPG>,
+ <&clks IMX6UL_CLK_UART2_SERIAL>;
+ clock-names = "ipg", "per";
+ dmas = <&sdma 27 4 0>, <&sdma 28 4 0>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ uart3: serial@021ec000 {
+ compatible = "fsl,imx6ul-uart",
+ "fsl,imx6q-uart", "fsl,imx21-uart";
+ reg = <0x021ec000 0x4000>;
+ interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6UL_CLK_UART3_IPG>,
+ <&clks IMX6UL_CLK_UART3_SERIAL>;
+ clock-names = "ipg", "per";
+ dmas = <&sdma 29 4 0>, <&sdma 30 4 0>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ uart4: serial@021f0000 {
+ compatible = "fsl,imx6ul-uart",
+ "fsl,imx6q-uart", "fsl,imx21-uart";
+ reg = <0x021f0000 0x4000>;
+ interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6UL_CLK_UART4_IPG>,
+ <&clks IMX6UL_CLK_UART4_SERIAL>;
+ clock-names = "ipg", "per";
+ dmas = <&sdma 31 4 0>, <&sdma 32 4 0>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ uart5: serial@021f4000 {
+ compatible = "fsl,imx6ul-uart",
+ "fsl,imx6q-uart", "fsl,imx21-uart";
+ reg = <0x021f4000 0x4000>;
+ interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6UL_CLK_UART5_IPG>,
+ <&clks IMX6UL_CLK_UART5_SERIAL>;
+ clock-names = "ipg", "per";
+ dmas = <&sdma 33 4 0>, <&sdma 34 4 0>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ i2c4: i2c@021f8000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx6ul-i2c", "fsl,imx21-i2c";
+ reg = <0x021f8000 0x4000>;
+ interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6UL_CLK_I2C4>;
+ status = "disabled";
+ };
+
+ uart6: serial@021fc000 {
+ compatible = "fsl,imx6ul-uart",
+ "fsl,imx6q-uart", "fsl,imx21-uart";
+ reg = <0x021fc000 0x4000>;
+ interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6UL_CLK_UART6_IPG>,
+ <&clks IMX6UL_CLK_UART6_SERIAL>;
+ clock-names = "ipg", "per";
+ dmas = <&sdma 0 4 0>, <&sdma 47 4 0>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+ };
+
+ aips3: aips-bus@02200000 {
+ compatible = "fsl,aips-bus", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x02200000 0x100000>;
+ ranges;
+
+ dcp: dcp@02280000 {
+ compatible = "fsl,imx6sl-dcp";
+ reg = <0x02280000 0x4000>;
+ interrupts = <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 47 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6ULL_CLK_DCP_CLK>;
+ clock-names = "dcp";
+ };
+
+ rngb: rngb@02284000 {
+ compatible = "fsl,imx6sl-rng", "fsl,imx-rng", "imx-rng";
+ reg = <0x02284000 0x4000>;
+ interrupts = <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6UL_CLK_DUMMY>;
+ };
+
+ uart8: serial@02288000 {
+ compatible = "fsl,imx6ul-uart",
+ "fsl,imx6q-uart", "fsl,imx21-uart";
+ reg = <0x02288000 0x4000>;
+ interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6UL_CLK_UART8_IPG>,
+ <&clks IMX6UL_CLK_UART8_SERIAL>;
+ clock-names = "ipg", "per";
+ dmas = <&sdma 45 4 0>, <&sdma 46 4 0>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ epdc: epdc@0228c000 {
+ compatible = "fsl,imx7d-epdc";
+ interrupts = <GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>;
+ reg = <0x0228c000 0x4000>;
+ clocks = <&clks IMX6ULL_CLK_EPDC_ACLK>,
+ <&clks IMX6ULL_CLK_EPDC_PIX>;
+ clock-names = "epdc_axi", "epdc_pix";
+ /* Need to fix epdc-ram */
+ /* epdc-ram = <&gpr 0x4 30>; */
+ status = "disabled";
+ };
+
+ iomuxc_snvs: iomuxc-snvs@02290000 {
+ compatible = "fsl,imx6ull-iomuxc-snvs";
+ reg = <0x02290000 0x10000>;
+ };
+
+ snvs_gpr: snvs-gpr@0x02294000 {
+ compatible = "fsl, imx6ull-snvs-gpr";
+ reg = <0x02294000 0x10000>;
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/imx6ulz-14x14-evk-btwifi-oob.dts b/arch/arm/boot/dts/imx6ulz-14x14-evk-btwifi-oob.dts
new file mode 100644
index 000000000000..aa9c0c05180d
--- /dev/null
+++ b/arch/arm/boot/dts/imx6ulz-14x14-evk-btwifi-oob.dts
@@ -0,0 +1,16 @@
+/*
+ * Copyright 2018 NXP
+ *
+ * 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 "imx6ulz-14x14-evk-btwifi.dts"
+#include "imx6ul-evk-btwifi-oob.dtsi"
diff --git a/arch/arm/boot/dts/imx6ulz-14x14-evk-btwifi.dts b/arch/arm/boot/dts/imx6ulz-14x14-evk-btwifi.dts
new file mode 100644
index 000000000000..bac48ee3ae95
--- /dev/null
+++ b/arch/arm/boot/dts/imx6ulz-14x14-evk-btwifi.dts
@@ -0,0 +1,16 @@
+/*
+ * Copyright 2018 NXP
+ *
+ * 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 "imx6ulz-14x14-evk.dts"
+#include "imx6ul-evk-btwifi.dtsi"
diff --git a/arch/arm/boot/dts/imx6ulz-14x14-evk-emmc.dts b/arch/arm/boot/dts/imx6ulz-14x14-evk-emmc.dts
new file mode 100644
index 000000000000..8d527c29e3a0
--- /dev/null
+++ b/arch/arm/boot/dts/imx6ulz-14x14-evk-emmc.dts
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2018 NXP
+ *
+ * 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 "imx6ulz-14x14-evk.dts"
+
+&usdhc2 {
+ pinctrl-names = "default", "state_100mhz", "state_200mhz";
+ pinctrl-0 = <&pinctrl_usdhc2_8bit>;
+ pinctrl-1 = <&pinctrl_usdhc2_8bit_100mhz>;
+ pinctrl-2 = <&pinctrl_usdhc2_8bit_200mhz>;
+ bus-width = <8>;
+ non-removable;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx6ulz-14x14-evk-gpmi-weim.dts b/arch/arm/boot/dts/imx6ulz-14x14-evk-gpmi-weim.dts
new file mode 100644
index 000000000000..65f68851e0ee
--- /dev/null
+++ b/arch/arm/boot/dts/imx6ulz-14x14-evk-gpmi-weim.dts
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2018 NXP
+ *
+ * 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 "imx6ulz-14x14-evk.dts"
+
+&gpmi {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpmi_nand_1>;
+ status = "okay";
+ nand-on-flash-bbt;
+};
+
+&iomuxc {
+ imx6ulz-evk-gpmi-rework {
+ pinctrl_gpmi_nand_1: gpmi-nand-1 {
+ fsl,pins = <
+ MX6UL_PAD_NAND_CLE__RAWNAND_CLE 0xb0b1
+ MX6UL_PAD_NAND_ALE__RAWNAND_ALE 0xb0b1
+ MX6UL_PAD_NAND_WP_B__RAWNAND_WP_B 0xb0b1
+ MX6UL_PAD_NAND_READY_B__RAWNAND_READY_B 0xb000
+ MX6UL_PAD_NAND_CE0_B__RAWNAND_CE0_B 0xb0b1
+ MX6UL_PAD_NAND_CE1_B__RAWNAND_CE1_B 0xb0b1
+ MX6UL_PAD_NAND_RE_B__RAWNAND_RE_B 0xb0b1
+ MX6UL_PAD_NAND_WE_B__RAWNAND_WE_B 0xb0b1
+ MX6UL_PAD_NAND_DATA00__RAWNAND_DATA00 0xb0b1
+ MX6UL_PAD_NAND_DATA01__RAWNAND_DATA01 0xb0b1
+ MX6UL_PAD_NAND_DATA02__RAWNAND_DATA02 0xb0b1
+ MX6UL_PAD_NAND_DATA03__RAWNAND_DATA03 0xb0b1
+ MX6UL_PAD_NAND_DATA04__RAWNAND_DATA04 0xb0b1
+ MX6UL_PAD_NAND_DATA05__RAWNAND_DATA05 0xb0b1
+ MX6UL_PAD_NAND_DATA06__RAWNAND_DATA06 0xb0b1
+ MX6UL_PAD_NAND_DATA07__RAWNAND_DATA07 0xb0b1
+ >;
+ };
+ };
+};
+
+&qspi {
+ status = "disabled";
+};
+
+&usdhc2 {
+ status = "disabled";
+};
diff --git a/arch/arm/boot/dts/imx6ulz-14x14-evk.dts b/arch/arm/boot/dts/imx6ulz-14x14-evk.dts
new file mode 100644
index 000000000000..813fd0021191
--- /dev/null
+++ b/arch/arm/boot/dts/imx6ulz-14x14-evk.dts
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2018 NXP
+ *
+ * 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.
+ */
+
+
+/dts-v1/;
+
+#include "imx6ull-14x14-evk.dts"
+
+/ {
+ model = "Freescale i.MX6 ULZ 14x14 EVK Board";
+ compatible = "fsl,imx6ulz-14x14-evk", "fsl,imx6ulz";
+
+ backlight {
+ status = "disabled";
+ };
+
+ pxp_v4l2 {
+ status = "disabled";
+ };
+};
diff --git a/arch/arm/boot/dts/imx7d-12x12-ddr3-arm2.dts b/arch/arm/boot/dts/imx7d-12x12-ddr3-arm2.dts
new file mode 100644
index 000000000000..8455815c8cad
--- /dev/null
+++ b/arch/arm/boot/dts/imx7d-12x12-ddr3-arm2.dts
@@ -0,0 +1,558 @@
+/*
+ * Copyright (C) 2015 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 <dt-bindings/input/input.h>
+#include "imx7d.dtsi"
+
+/ {
+ model = "Freescale i.MX7 DDR3 12x12 ARM2 Board";
+ compatible = "fsl,imx7d-12x12-ddr3-arm2", "fsl,imx7d";
+
+ backlight {
+ compatible = "pwm-backlight";
+ pwms = <&pwm1 0 5000000 0>;
+ brightness-levels = <0 4 8 16 32 64 128 255>;
+ default-brightness-level = <6>;
+ status = "okay";
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpio_keys>;
+
+ volume-up {
+ label = "Volume Up";
+ gpios = <&gpio3 17 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_VOLUMEUP>;
+ };
+
+ volume-down {
+ label = "Volume Down";
+ gpios = <&gpio3 18 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_VOLUMEDOWN>;
+ };
+ };
+
+ pxp_v4l2_out {
+ compatible = "fsl,imx7d-pxp-v4l2", "fsl,imx6sx-pxp-v4l2", "fsl,imx6sl-pxp-v4l2";
+ status = "okay";
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ reg_sd3_vmmc: sd3_vmmc {
+ compatible = "regulator-fixed";
+ regulator-name = "VCC_SD3";
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ gpio = <&gpio6 11 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ reg_usb_otg1_vbus: regulator@0 {
+ compatible = "regulator-fixed";
+ reg = <0>;
+ regulator-name = "usb_otg1_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&gpio4 5 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ reg_usb_otg2_vbus: regulator@1 {
+ compatible = "regulator-fixed";
+ reg = <1>;
+ regulator-name = "usb_otg2_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&gpio4 7 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ reg_vref_1v8: regulator@2 {
+ compatible = "regulator-fixed";
+ regulator-name = "vref-1v8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ reg_can1_3v3: can1-3v3 {
+ compatible = "regulator-fixed";
+ regulator-name = "can1-3v3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&gpio1 2 GPIO_ACTIVE_LOW>;
+ };
+
+ reg_can2_3v3: can2-3v3 {
+ compatible = "regulator-fixed";
+ regulator-name = "can2-3v3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&gpio1 3 GPIO_ACTIVE_LOW>;
+ };
+ };
+
+ memory {
+ reg = <0x80000000 0x80000000>;
+ };
+};
+
+&adc1 {
+ vref-supply = <&reg_vref_1v8>;
+ status = "okay";
+};
+
+&cpu0 {
+ arm-supply = <&sw1a_reg>;
+};
+
+&ecspi4 {
+ fsl,spi-num-chipselects = <4>;
+ cs-gpios = <&gpio5 3 0>, <&gpio5 4 0>, <&gpio5 5 0>, <&gpio5 6 0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ecspi4_1 &pinctrl_ecspi4_cs_1>;
+ status = "disabled";
+
+ flash: m25p80@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "st,m25p32";
+ spi-max-frequency = <20000000>;
+ reg = <0>;
+ };
+};
+
+&epxp {
+ status = "okay";
+};
+
+&flexcan1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_flexcan1>;
+ xceiver-supply = <&reg_can1_3v3>;
+ status = "disabled";
+};
+
+&flexcan2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_flexcan2>;
+ xceiver-supply = <&reg_can2_3v3>;
+ status = "disabled";
+};
+
+&i2c1 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c1_1>;
+ status = "okay";
+
+ pmic: pfuze3000@08 {
+ compatible = "fsl,pfuze3000";
+ reg = <0x08>;
+
+ regulators {
+ sw1a_reg: sw1a {
+ regulator-min-microvolt = <700000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ regulator-ramp-delay = <6250>;
+ };
+ /* use sw1c_reg to align with pfuze100/pfuze200 */
+ sw1c_reg: sw1b {
+ regulator-min-microvolt = <700000>;
+ regulator-max-microvolt = <1475000>;
+ regulator-boot-on;
+ regulator-always-on;
+ regulator-ramp-delay = <6250>;
+ };
+
+ sw2_reg: sw2 {
+ regulator-min-microvolt = <1500000>;
+ regulator-max-microvolt = <1850000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ sw3a_reg: sw3 {
+ regulator-min-microvolt = <900000>;
+ regulator-max-microvolt = <1650000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ swbst_reg: swbst {
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5150000>;
+ };
+
+ snvs_reg: vsnvs {
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ vref_reg: vrefddr {
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ vgen1_reg: vldo1 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ vgen2_reg: vldo2 {
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1550000>;
+ };
+
+ vgen3_reg: vccsd {
+ regulator-min-microvolt = <2850000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ vgen4_reg: v33 {
+ regulator-min-microvolt = <2850000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ vgen5_reg: vldo3 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ vgen6_reg: vldo4 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+ };
+ };
+};
+
+&i2c3 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c3_1>;
+ status = "okay";
+};
+
+&iomuxc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_hog_1>;
+
+ imx7d-12x12-ddr3-arm2 {
+ pinctrl_hog_1: hoggrp-1 {
+ fsl,pins = <
+ MX7D_PAD_GPIO1_IO14__GPIO1_IO14 0x59
+ MX7D_PAD_GPIO1_IO15__GPIO1_IO15 0x59
+ MX7D_PAD_SD2_RESET_B__GPIO5_IO11 0x59
+ >;
+ };
+
+ pinctrl_ecspi4_cs_1: ecspi4_cs_grp-1 {
+ fsl,pins = <
+ MX7D_PAD_SD1_CLK__GPIO5_IO3 0x2
+ MX7D_PAD_SD1_CMD__GPIO5_IO4 0x2
+ MX7D_PAD_SD1_DATA0__GPIO5_IO5 0x2
+ MX7D_PAD_SD1_DATA1__GPIO5_IO6 0x2
+ >;
+ };
+
+ pinctrl_ecspi4_1: ecspi4grp-1 {
+ fsl,pins = <
+ MX7D_PAD_SD1_RESET_B__ECSPI4_SCLK 0x2
+ MX7D_PAD_SD1_WP__ECSPI4_MOSI 0x2
+ MX7D_PAD_SD1_CD_B__ECSPI4_MISO 0x2
+ >;
+ };
+
+ pinctrl_flexcan1: flexcan1grp {
+ fsl,pins = <
+ MX7D_PAD_SD3_DATA5__FLEXCAN1_TX 0x59
+ MX7D_PAD_SD3_DATA7__FLEXCAN1_RX 0x59
+ >;
+ };
+
+ pinctrl_flexcan2: flexcan2grp {
+ fsl,pins = <
+ MX7D_PAD_SD3_DATA6__FLEXCAN2_TX 0x59
+ MX7D_PAD_SD3_DATA4__FLEXCAN2_RX 0x59
+ >;
+ };
+
+ pinctrl_gpio_keys: gpio_keysgrp {
+ fsl,pins = <
+ MX7D_PAD_LCD_DATA12__GPIO3_IO17 0x32
+ MX7D_PAD_LCD_DATA13__GPIO3_IO18 0x32
+ >;
+ };
+
+ pinctrl_i2c3_1: i2c3grp-1 {
+ fsl,pins = <
+ MX7D_PAD_ENET1_RGMII_RD0__I2C3_SCL 0x4000007f
+ MX7D_PAD_ENET1_RGMII_RD1__I2C3_SDA 0x4000007f
+ >;
+ };
+
+ pinctrl_i2c4_1: i2c4grp-1 {
+ fsl,pins = <
+ MX7D_PAD_ENET1_RGMII_TD2__I2C4_SCL 0x4000007f
+ MX7D_PAD_ENET1_RGMII_TD3__I2C4_SDA 0x4000007f
+ >;
+ };
+
+ pinctrl_lcdif_dat: lcdifdatgrp {
+ fsl,pins = <
+ MX7D_PAD_EPDC_DATA00__LCD_DATA0 0x4001b0b0
+ MX7D_PAD_EPDC_DATA01__LCD_DATA1 0x4001b0b0
+ MX7D_PAD_EPDC_DATA02__LCD_DATA2 0x4001b0b0
+ MX7D_PAD_EPDC_DATA03__LCD_DATA3 0x4001b0b0
+ MX7D_PAD_EPDC_DATA04__LCD_DATA4 0x4001b0b0
+ MX7D_PAD_EPDC_DATA05__LCD_DATA5 0x4001b0b0
+ MX7D_PAD_EPDC_DATA06__LCD_DATA6 0x4001b0b0
+ MX7D_PAD_EPDC_DATA07__LCD_DATA7 0x4001b0b0
+ MX7D_PAD_EPDC_DATA08__LCD_DATA8 0x4001b0b0
+ MX7D_PAD_EPDC_DATA09__LCD_DATA9 0x4001b0b0
+ MX7D_PAD_EPDC_DATA10__LCD_DATA10 0x4001b0b0
+ MX7D_PAD_EPDC_DATA11__LCD_DATA11 0x4001b0b0
+ MX7D_PAD_EPDC_DATA12__LCD_DATA12 0x4001b0b0
+ MX7D_PAD_EPDC_DATA13__LCD_DATA13 0x4001b0b0
+ MX7D_PAD_EPDC_DATA14__LCD_DATA14 0x4001b0b0
+ MX7D_PAD_EPDC_DATA15__LCD_DATA15 0x4001b0b0
+ MX7D_PAD_EPDC_SDLE__LCD_DATA16 0x4001b0b0
+ MX7D_PAD_EPDC_SDOE__LCD_DATA17 0x4001b0b0
+ MX7D_PAD_EPDC_SDSHR__LCD_DATA18 0x4001b0b0
+ MX7D_PAD_EPDC_SDCE0__LCD_DATA19 0x4001b0b0
+ MX7D_PAD_EPDC_SDCE1__LCD_DATA20 0x4001b0b0
+ MX7D_PAD_EPDC_SDCE2__LCD_DATA21 0x4001b0b0
+ MX7D_PAD_EPDC_SDCE3__LCD_DATA22 0x4001b0b0
+ MX7D_PAD_EPDC_GDCLK__LCD_DATA23 0x4001b0b0
+ >;
+ };
+
+ pinctrl_lcdif_ctrl: lcdifctrlgrp {
+ fsl,pins = <
+ MX7D_PAD_EPDC_SDCLK__LCD_CLK 0x4001b0b0
+ MX7D_PAD_EPDC_BDR1__LCD_ENABLE 0x4001b0b0
+ MX7D_PAD_EPDC_PWR_STAT__LCD_VSYNC 0x4001b0b0
+ MX7D_PAD_EPDC_PWR_COM__LCD_HSYNC 0x4001b0b0
+ >;
+ };
+
+ pinctrl_pwm1: pwm1grp {
+ fsl,pins = <
+ MX7D_PAD_GPIO1_IO08__PWM1_OUT 0x110b0
+ >;
+ };
+
+ pinctrl_uart1_1: uart1grp-1 {
+ fsl,pins = <
+ MX7D_PAD_UART1_TX_DATA__UART1_DCE_TX 0x79
+ MX7D_PAD_UART1_RX_DATA__UART1_DCE_RX 0x79
+ >;
+ };
+
+ pinctrl_usdhc2_1: usdhc2grp-1 {
+ fsl,pins = <
+ MX7D_PAD_SD2_CMD__SD2_CMD 0x59
+ MX7D_PAD_SD2_CLK__SD2_CLK 0x19
+ MX7D_PAD_SD2_DATA0__SD2_DATA0 0x59
+ MX7D_PAD_SD2_DATA1__SD2_DATA1 0x59
+ MX7D_PAD_SD2_DATA2__SD2_DATA2 0x59
+ MX7D_PAD_SD2_DATA3__SD2_DATA3 0x59
+ MX7D_PAD_ECSPI1_SCLK__SD2_DATA4 0x59
+ MX7D_PAD_ECSPI1_MOSI__SD2_DATA5 0x59
+ MX7D_PAD_ECSPI1_MISO__SD2_DATA6 0x59
+ MX7D_PAD_ECSPI1_SS0__SD2_DATA7 0x59
+ >;
+ };
+
+ pinctrl_usdhc2_1_100mhz: usdhc2grp-1_100mhz {
+ fsl,pins = <
+ MX7D_PAD_SD2_CMD__SD2_CMD 0x5a
+ MX7D_PAD_SD2_CLK__SD2_CLK 0x1a
+ MX7D_PAD_SD2_DATA0__SD2_DATA0 0x5a
+ MX7D_PAD_SD2_DATA1__SD2_DATA1 0x5a
+ MX7D_PAD_SD2_DATA2__SD2_DATA2 0x5a
+ MX7D_PAD_SD2_DATA3__SD2_DATA3 0x5a
+ MX7D_PAD_ECSPI1_SCLK__SD2_DATA4 0x5a
+ MX7D_PAD_ECSPI1_MOSI__SD2_DATA5 0x5a
+ MX7D_PAD_ECSPI1_MISO__SD2_DATA6 0x5a
+ MX7D_PAD_ECSPI1_SS0__SD2_DATA7 0x5a
+ >;
+ };
+
+ pinctrl_usdhc2_1_200mhz: usdhc2grp-1_200mhz {
+ fsl,pins = <
+ MX7D_PAD_SD2_CMD__SD2_CMD 0x5b
+ MX7D_PAD_SD2_CLK__SD2_CLK 0x1b
+ MX7D_PAD_SD2_DATA0__SD2_DATA0 0x5b
+ MX7D_PAD_SD2_DATA1__SD2_DATA1 0x5b
+ MX7D_PAD_SD2_DATA2__SD2_DATA2 0x5b
+ MX7D_PAD_SD2_DATA3__SD2_DATA3 0x5b
+ MX7D_PAD_ECSPI1_SCLK__SD2_DATA4 0x5b
+ MX7D_PAD_ECSPI1_MOSI__SD2_DATA5 0x5b
+ MX7D_PAD_ECSPI1_MISO__SD2_DATA6 0x5b
+ MX7D_PAD_ECSPI1_SS0__SD2_DATA7 0x5b
+ >;
+ };
+
+ pinctrl_usdhc3_1: usdhc3grp-1 {
+ fsl,pins = <
+ MX7D_PAD_SD3_CMD__SD3_CMD 0x59
+ MX7D_PAD_SD3_CLK__SD3_CLK 0x19
+ MX7D_PAD_SD3_DATA0__SD3_DATA0 0x59
+ MX7D_PAD_SD3_DATA1__SD3_DATA1 0x59
+ MX7D_PAD_SD3_DATA2__SD3_DATA2 0x59
+ MX7D_PAD_SD3_DATA3__SD3_DATA3 0x59
+ >;
+ };
+ };
+};
+
+&iomuxc_lpsr {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_hog_2>;
+
+ imx7d-12x12-ddr3-arm2 {
+ pinctrl_hog_2: hoggrp-2 {
+ fsl,pins = <
+ MX7D_PAD_LPSR_GPIO1_IO02__GPIO1_IO2 0x59 /* flexcan stby1 */
+ MX7D_PAD_LPSR_GPIO1_IO03__GPIO1_IO3 0x59 /* flexcan stby2 */
+ MX7D_PAD_LPSR_GPIO1_IO01__ANATOP_24M_OUT 0x80000000
+ >;
+ };
+
+ pinctrl_i2c1_1: i2c1grp-1 {
+ fsl,pins = <
+ MX7D_PAD_LPSR_GPIO1_IO04__I2C1_SCL 0x4000007f
+ MX7D_PAD_LPSR_GPIO1_IO05__I2C1_SDA 0x4000007f
+ >;
+ };
+
+ pinctrl_i2c2_1: i2c2grp-1 {
+ fsl,pins = <
+ MX7D_PAD_LPSR_GPIO1_IO06__I2C2_SCL 0x4000007f
+ MX7D_PAD_LPSR_GPIO1_IO07__I2C2_SDA 0x4000007f
+ >;
+ };
+ };
+};
+
+&lcdif {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lcdif_dat
+ &pinctrl_lcdif_ctrl>;
+ display = <&display0>;
+ status = "okay";
+
+ display0: display {
+ bits-per-pixel = <16>;
+ bus-width = <24>;
+
+ display-timings {
+ native-mode = <&timing0>;
+ timing0: timing0 {
+ clock-frequency = <33500000>;
+ hactive = <800>;
+ vactive = <480>;
+ hback-porch = <89>;
+ hfront-porch = <164>;
+ vback-porch = <23>;
+ vfront-porch = <10>;
+ hsync-len = <10>;
+ vsync-len = <10>;
+ hsync-active = <0>;
+ vsync-active = <0>;
+ de-active = <1>;
+ pixelclk-active = <0>;
+ };
+ };
+ };
+};
+
+&sdma {
+ status = "okay";
+};
+
+&pcie {
+ pinctrl-names = "default";
+ status = "disabled";
+};
+
+&pwm1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pwm1>;
+ status = "okay";
+};
+
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart1_1>;
+ status = "okay";
+};
+
+&usbh {
+ status = "okay";
+};
+
+&usbotg1 {
+ vbus-supply = <&reg_usb_otg1_vbus>;
+ srp-disable;
+ hnp-disable;
+ adp-disable;
+ status = "okay";
+};
+
+&usbotg2 {
+ vbus-supply = <&reg_usb_otg2_vbus>;
+ srp-disable;
+ hnp-disable;
+ adp-disable;
+ status = "okay";
+};
+
+&usdhc2 {
+ pinctrl-names = "default", "state_100mhz", "state_200mhz";
+ pinctrl-0 = <&pinctrl_usdhc2_1>;
+ pinctrl-1 = <&pinctrl_usdhc2_1_100mhz>;
+ pinctrl-2 = <&pinctrl_usdhc2_1_200mhz>;
+ assigned-clocks = <&clks IMX7D_USDHC2_ROOT_CLK>;
+ assigned-clocks-rates = <400000000>;
+ bus-width = <8>;
+ tuning-step = <2>;
+ non-removable;
+ keep-power-in-suspend;
+ status = "okay";
+};
+
+&usdhc3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usdhc3_1>;
+ vmmc-supply = <&reg_sd3_vmmc>;
+ cd-gpios = <&gpio1 14>;
+ wp-gpios = <&gpio1 15>;
+ keep-power-in-suspend;
+ enable-sdio-wakeup;
+ no-1-8-v;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx7d-12x12-lpddr3-arm2-ecspi.dts b/arch/arm/boot/dts/imx7d-12x12-lpddr3-arm2-ecspi.dts
new file mode 100644
index 000000000000..16dd447a141f
--- /dev/null
+++ b/arch/arm/boot/dts/imx7d-12x12-lpddr3-arm2-ecspi.dts
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2015 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 "imx7d-12x12-lpddr3-arm2.dts"
+
+&epdc {
+ status = "disabled";
+};
+
+&ecspi1{
+ status = "okay";
+};
+
+/*
+ * pin conflict with ecspi1
+ * default hog setting conflicts with ECSPI1 MOSI and MISO
+ * EPDC PWRCTRL conflicts with ECSPI1 CS pin
+ */
+&iomuxc {
+ pinctrl-0 = <&pinctrl_hog_1>;
+ pinctrl-1 = <&pinctrl_hog_1>;
+};
diff --git a/arch/arm/boot/dts/imx7d-12x12-lpddr3-arm2-enet2.dts b/arch/arm/boot/dts/imx7d-12x12-lpddr3-arm2-enet2.dts
new file mode 100644
index 000000000000..151853dc1712
--- /dev/null
+++ b/arch/arm/boot/dts/imx7d-12x12-lpddr3-arm2-enet2.dts
@@ -0,0 +1,17 @@
+/*
+ * Copyright (C) 2015 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 "imx7d-12x12-lpddr3-arm2.dts"
+
+&epdc {
+ status = "disabled";
+};
+
+&fec2 {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx7d-12x12-lpddr3-arm2-flexcan.dts b/arch/arm/boot/dts/imx7d-12x12-lpddr3-arm2-flexcan.dts
new file mode 100644
index 000000000000..90ea88599b70
--- /dev/null
+++ b/arch/arm/boot/dts/imx7d-12x12-lpddr3-arm2-flexcan.dts
@@ -0,0 +1,29 @@
+/*
+* Copyright (C) 2015 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 "imx7d-12x12-lpddr3-arm2.dts"
+
+&fec1 {
+ status = "disabled";
+};
+
+&flexcan1 {
+ status = "okay";
+};
+
+&flexcan2 {
+ status = "okay";
+};
+
+&sai1 {
+ status = "disabled";
+};
+
+&sim1 {
+ status = "disabled";
+};
diff --git a/arch/arm/boot/dts/imx7d-12x12-lpddr3-arm2-m4.dts b/arch/arm/boot/dts/imx7d-12x12-lpddr3-arm2-m4.dts
new file mode 100644
index 000000000000..d5579f2b437c
--- /dev/null
+++ b/arch/arm/boot/dts/imx7d-12x12-lpddr3-arm2-m4.dts
@@ -0,0 +1,76 @@
+
+#include "imx7d-12x12-lpddr3-arm2.dts"
+
+/ {
+ memory {
+ linux,usable-memory = <0x80000000 0x1ff00000>,
+ <0xa0000000 0x1ff00000>,
+ <0xc0000000 0x40000000>;
+ };
+
+ gpio-keys {
+ status = "disabled";
+ };
+
+ m4_tcm: tcml@007f8000 {
+ compatible = "fsl, m4_tcml";
+ reg = <0x007f8000 0x8000>;
+ };
+};
+
+&adc1 {
+ status = "disabled";
+};
+
+&adc2 {
+ status = "disabled";
+};
+
+
+&i2c1 {
+ status = "disabled";
+};
+
+&flexcan1 {
+ status = "disabled";
+};
+
+&flexcan2 {
+ status = "disabled";
+};
+
+&gpt3 {
+ status = "disabled";
+};
+
+&gpt4 {
+ status = "disabled";
+};
+
+&ocram {
+ reg = <0x00901000 0xf000>;
+};
+
+&reg_can2_3v3 {
+ status = "disabled";
+};
+
+&rpmsg{
+ status = "okay";
+};
+
+&sim1 {
+ status = "disabled";
+};
+
+&tempmon {
+ status = "disabled";
+};
+
+&uart2 {
+ status = "disabled";
+};
+
+&wdog3{
+ status = "disabled";
+};
diff --git a/arch/arm/boot/dts/imx7d-12x12-lpddr3-arm2-mipi_dsi.dts b/arch/arm/boot/dts/imx7d-12x12-lpddr3-arm2-mipi_dsi.dts
new file mode 100644
index 000000000000..db38d4120f34
--- /dev/null
+++ b/arch/arm/boot/dts/imx7d-12x12-lpddr3-arm2-mipi_dsi.dts
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2015 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 "imx7d-12x12-lpddr3-arm2.dts"
+
+/ {
+ mipi_dsi_reset: mipi-dsi-reset {
+ compatible = "gpio-reset";
+ reset-gpios = <&gpio4 17 GPIO_ACTIVE_LOW>;
+ reset-delay-us = <50>;
+ #reset-cells = <0>;
+ };
+};
+
+&lcdif {
+ disp-dev = "mipi_dsi_samsung";
+};
+
+&mipi_dsi {
+ lcd_panel = "TRULY-WVGA";
+ disp-power-on-supply = <&reg_mipi_dsi_pwr_on>;
+ resets = <&mipi_dsi_reset>;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx7d-12x12-lpddr3-arm2-mqs.dts b/arch/arm/boot/dts/imx7d-12x12-lpddr3-arm2-mqs.dts
new file mode 100644
index 000000000000..7fcdf6a060d8
--- /dev/null
+++ b/arch/arm/boot/dts/imx7d-12x12-lpddr3-arm2-mqs.dts
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2015 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 "imx7d-12x12-lpddr3-arm2.dts"
+
+/ {
+ sound-mqs {
+ compatible = "fsl,imx7d-12x12-lpddr3-arm2-mqs",
+ "fsl,imx-audio-mqs";
+ model = "mqs-audio";
+ cpu-dai = <&sai1>;
+ audio-codec = <&mqs>;
+ };
+};
+
+&clks {
+ assigned-clocks = <&clks IMX7D_PLL_AUDIO_POST_DIV>;
+ assigned-clock-rates = <786432000>;
+};
+
+&mqs {
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&pinctrl_mqs>;
+ pinctrl-1 = <&pinctrl_mqs>;
+ clocks = <&clks IMX7D_SAI1_ROOT_CLK>;
+ clock-names = "mclk";
+ status = "okay";
+};
+
+&sai1 {
+ assigned-clocks = <&clks IMX7D_SAI1_ROOT_SRC>,
+ <&clks IMX7D_SAI1_ROOT_CLK>;
+ assigned-clock-parents = <&clks IMX7D_PLL_AUDIO_POST_DIV>;
+ assigned-clock-rates = <0>, <24576000>;
+ status = "okay";
+};
+
+&sdma {
+ status = "okay";
+};
+
+&sim1 {
+ status = "disabled";
+};
diff --git a/arch/arm/boot/dts/imx7d-12x12-lpddr3-arm2-pcie.dts b/arch/arm/boot/dts/imx7d-12x12-lpddr3-arm2-pcie.dts
new file mode 100644
index 000000000000..ffe65d934331
--- /dev/null
+++ b/arch/arm/boot/dts/imx7d-12x12-lpddr3-arm2-pcie.dts
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2015 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 "imx7d-12x12-lpddr3-arm2.dts"
+
+/*
+ * On imx7d 12x12 arm2 board, there is pin(gpio6_21) iomux
+ * between ecspi3 and pcie_rst_b. In order to resove this
+ * pin conflict, disable ecspi3 in this pcie named dts file.
+ */
+&ecspi3 {
+ status = "disabled";
+};
+
+&pcie{
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx7d-12x12-lpddr3-arm2-qspi.dts b/arch/arm/boot/dts/imx7d-12x12-lpddr3-arm2-qspi.dts
new file mode 100644
index 000000000000..3a7af2e8bf92
--- /dev/null
+++ b/arch/arm/boot/dts/imx7d-12x12-lpddr3-arm2-qspi.dts
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2015 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 "imx7d-12x12-lpddr3-arm2.dts"
+
+/* disable epdc, conflict with qspi */
+&epdc {
+ status = "disabled";
+};
+
+&iomuxc {
+ qspi1 {
+ pinctrl_qspi1_1: qspi1grp_1 {
+ fsl,pins = <
+ MX7D_PAD_EPDC_DATA00__QSPI_A_DATA0 0x51
+ MX7D_PAD_EPDC_DATA01__QSPI_A_DATA1 0x51
+ MX7D_PAD_EPDC_DATA02__QSPI_A_DATA2 0x51
+ MX7D_PAD_EPDC_DATA03__QSPI_A_DATA3 0x51
+ MX7D_PAD_EPDC_DATA04__QSPI_A_DQS 0x51
+ MX7D_PAD_EPDC_DATA05__QSPI_A_SCLK 0x51
+ MX7D_PAD_EPDC_DATA06__QSPI_A_SS0_B 0x51
+ MX7D_PAD_EPDC_DATA07__QSPI_A_SS1_B 0x51
+ MX7D_PAD_EPDC_DATA08__QSPI_B_DATA0 0x51
+ MX7D_PAD_EPDC_DATA09__QSPI_B_DATA1 0x51
+ MX7D_PAD_EPDC_DATA10__QSPI_B_DATA2 0x51
+ MX7D_PAD_EPDC_DATA11__QSPI_B_DATA3 0x51
+ MX7D_PAD_EPDC_DATA12__QSPI_B_DQS 0x51
+ MX7D_PAD_EPDC_DATA13__QSPI_B_SCLK 0x51
+ MX7D_PAD_EPDC_DATA14__QSPI_B_SS0_B 0x51
+ MX7D_PAD_EPDC_DATA15__QSPI_B_SS1_B 0x51
+ >;
+ };
+ };
+};
+
+&qspi1 {
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&pinctrl_qspi1_1>;
+ pinctrl-1 = <&pinctrl_qspi1_1>;
+ status = "okay";
+ fsl,qspi-has-second-chip = <1>;
+ ddrsmp=<0>;
+
+ flash0: n25q256a@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "micron,n25q256a";
+ spi-max-frequency = <29000000>;
+ spi-nor,ddr-quad-read-dummy = <6>;
+ reg = <0>;
+ };
+
+ flash1: n25q256a@1 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "micron,n25q256a";
+ spi-max-frequency = <29000000>;
+ spi-nor,ddr-quad-read-dummy = <6>;
+ reg = <1>;
+ };
+
+ flash2: n25q256a@2 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "micron,n25q256a";
+ spi-max-frequency = <29000000>;
+ spi-nor,ddr-quad-read-dummy = <6>;
+ reg = <2>;
+ };
+
+ flash3: n25q256a@3 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "micron,n25q256a";
+ spi-max-frequency = <29000000>;
+ spi-nor,ddr-quad-read-dummy = <6>;
+ reg = <3>;
+ };
+};
diff --git a/arch/arm/boot/dts/imx7d-12x12-lpddr3-arm2-sai.dts b/arch/arm/boot/dts/imx7d-12x12-lpddr3-arm2-sai.dts
new file mode 100644
index 000000000000..f1d36ce65119
--- /dev/null
+++ b/arch/arm/boot/dts/imx7d-12x12-lpddr3-arm2-sai.dts
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2015 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 "imx7d-12x12-lpddr3-arm2.dts"
+
+/ {
+ sound {
+ compatible = "fsl,imx7d-12x12-lpddr3-arm2-wm8958",
+ "fsl,imx-audio-wm8958";
+ model = "wm8958-audio";
+ cpu-dai = <&sai1>;
+ audio-codec = <&codec>;
+ codec-master;
+ hp-det-gpios = <&gpio1 12 1>;
+ };
+};
+
+&iomuxc {
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&pinctrl_hog_1 &pinctrl_hog_headphone_det>;
+ pinctrl-1 = <&pinctrl_hog_1 &pinctrl_hog_sd2_vselect>;
+};
+
+&sai1 {
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&pinctrl_sai1>;
+ pinctrl-1 = <&pinctrl_sai1>;
+ status = "okay";
+};
+
+&sdma {
+ status = "okay";
+};
+
+&sim1 {
+ status = "disabled";
+};
+
+&usdhc2 {
+ no-1-8-v;
+};
diff --git a/arch/arm/boot/dts/imx7d-12x12-lpddr3-arm2.dts b/arch/arm/boot/dts/imx7d-12x12-lpddr3-arm2.dts
new file mode 100644
index 000000000000..f8f1eed2161b
--- /dev/null
+++ b/arch/arm/boot/dts/imx7d-12x12-lpddr3-arm2.dts
@@ -0,0 +1,1017 @@
+/*
+ * Copyright (C) 2015 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 "imx7d.dtsi"
+
+/ {
+ model = "Freescale i.MX7 LPDDR3 12x12 ARM2 Board";
+ compatible = "fsl,imx7d-12x12-lpddr3-arm2", "fsl,imx7d";
+
+ backlight {
+ compatible = "pwm-backlight";
+ pwms = <&pwm1 0 5000000 0>;
+ brightness-levels = <0 4 8 16 32 64 128 255>;
+ default-brightness-level = <6>;
+ status = "okay";
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&pinctrl_gpio_keys>;
+ pinctrl-1 = <&pinctrl_gpio_keys_sleep>;
+
+ volume-up {
+ label = "Volume Up";
+ gpios = <&gpio1 14 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_VOLUMEUP>;
+ };
+
+ volume-down {
+ label = "Volume Down";
+ gpios = <&gpio1 15 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_VOLUMEDOWN>;
+ };
+ };
+
+ pxp_v4l2_out {
+ compatible = "fsl,imx7d-pxp-v4l2", "fsl,imx6sx-pxp-v4l2", "fsl,imx6sl-pxp-v4l2";
+ status = "okay";
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ reg_aud_1v8: aud_1v8 {
+ compatible = "regulator-fixed";
+ regulator-name = "AUD_1V8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ gpio = <&gpio1 13 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ reg_can1_3v3: can1-3v3 {
+ compatible = "regulator-fixed";
+ regulator-name = "can1-3v3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&gpio1 10 GPIO_ACTIVE_LOW>;
+ };
+
+ reg_can2_3v3: can2-3v3 {
+ compatible = "regulator-fixed";
+ regulator-name = "can2-3v3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&gpio1 11 GPIO_ACTIVE_LOW>;
+ };
+
+ reg_coedc_5v: coedc_5v {
+ compatible = "regulator-fixed";
+ regulator-name = "CODEC_5V";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&gpio1 13 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ reg_sd1_vmmc: sd1_vmmc{
+ compatible = "regulator-fixed";
+ regulator-name = "VCC_SD1";
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ gpio = <&gpio5 2 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ reg_sd2_vmmc: sd2_vmmc{
+ compatible = "regulator-fixed";
+ regulator-name = "VCC_SD2";
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ gpio = <&gpio5 11 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ reg_usb_otg1_vbus: regulator@0 {
+ compatible = "regulator-fixed";
+ reg = <0>;
+ regulator-name = "usb_otg1_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&gpio1 5 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ reg_usb_otg2_vbus: regulator@1 {
+ compatible = "regulator-fixed";
+ reg = <1>;
+ regulator-name = "usb_otg2_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&gpio1 7 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ reg_vref_1v8: regulator@2 {
+ compatible = "regulator-fixed";
+ regulator-name = "vref-1v8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ reg_mipi_dsi_pwr_on: mipi_dsi_pwr_on {
+ compatible = "regulator-fixed";
+ regulator-name = "mipi_dsi_pwr_on";
+ gpio = <&gpio4 16 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+ };
+
+ memory {
+ reg = <0x80000000 0x80000000>;
+ };
+};
+
+&adc1 {
+ vref-supply = <&reg_vref_1v8>;
+ status = "okay";
+};
+
+&cpu0 {
+ arm-supply = <&sw1a_reg>;
+};
+
+&epdc {
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&pinctrl_epdc_0>;
+ pinctrl-1 = <&pinctrl_epdc_0>;
+ V3P3-supply = <&V3P3_reg>;
+ VCOM-supply = <&VCOM_reg>;
+ DISPLAY-supply = <&DISPLAY_reg>;
+ status = "okay";
+};
+
+&epxp {
+ status = "okay";
+};
+
+&ecspi1 {
+ fsl,spi-num-chipselects = <1>;
+ cs-gpios = <&gpio4 19 0>;
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&pinctrl_ecspi1_1 &pinctrl_ecspi1_cs_1>;
+ pinctrl-1 = <&pinctrl_ecspi1_1 &pinctrl_ecspi1_cs_1>;
+ status = "disabled";
+
+ spi_flash1: m25p80@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "st,m25p32";
+ spi-max-frequency = <20000000>;
+ reg = <0>;
+ };
+};
+
+&fec1 {
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&pinctrl_enet1>;
+ pinctrl-1 = <&pinctrl_enet1>;
+ assigned-clocks = <&clks IMX7D_ENET1_TIME_ROOT_SRC>,
+ <&clks IMX7D_ENET1_TIME_ROOT_CLK>;
+ assigned-clock-parents = <&clks IMX7D_PLL_ENET_MAIN_100M_CLK>;
+ assigned-clock-rates = <0>, <100000000>;
+ phy-mode = "rgmii";
+ phy-handle = <&ethphy1>;
+ fsl,magic-packet;
+ status = "okay";
+
+ mdio {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ethphy0: ethernet-phy@5 {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <5>;
+ };
+
+ ethphy1: ethernet-phy@1 {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <1>;
+ };
+ };
+};
+
+&fec2 {
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&pinctrl_enet2>;
+ pinctrl-1 = <&pinctrl_enet2>;
+ pinctrl-assert-gpios = <&max7322 0 GPIO_ACTIVE_HIGH>;
+ assigned-clocks = <&clks IMX7D_ENET2_TIME_ROOT_SRC>,
+ <&clks IMX7D_ENET2_TIME_ROOT_CLK>;
+ assigned-clock-parents = <&clks IMX7D_PLL_ENET_MAIN_100M_CLK>;
+ assigned-clock-rates = <0>, <100000000>;
+ phy-mode = "rgmii";
+ phy-handle = <&ethphy0>;
+ fsl,magic-packet;
+ status = "disabled";
+};
+
+&flexcan1 {
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&pinctrl_flexcan1>;
+ pinctrl-1 = <&pinctrl_flexcan1>;
+ xceiver-supply = <&reg_can1_3v3>;
+ status = "disabled";
+};
+
+&flexcan2 {
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&pinctrl_flexcan2>;
+ pinctrl-1 = <&pinctrl_flexcan2>;
+ xceiver-supply = <&reg_can2_3v3>;
+ status = "disabled";
+};
+
+&i2c1 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&pinctrl_i2c1_1>;
+ pinctrl-1 = <&pinctrl_i2c1_1>;
+ status = "okay";
+
+ pmic: pfuze3000@08 {
+ compatible = "fsl,pfuze3000";
+ reg = <0x08>;
+ fsl,lpsr-mode;
+
+ regulators {
+ sw1a_reg: sw1a {
+ regulator-min-microvolt = <700000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ regulator-ramp-delay = <6250>;
+ };
+ /* use sw1c_reg to align with pfuze100/pfuze200 */
+ sw1c_reg: sw1b {
+ regulator-min-microvolt = <700000>;
+ regulator-max-microvolt = <1475000>;
+ regulator-boot-on;
+ regulator-always-on;
+ regulator-ramp-delay = <6250>;
+ };
+
+ sw2_reg: sw2 {
+ regulator-min-microvolt = <1500000>;
+ regulator-max-microvolt = <1850000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ sw3a_reg: sw3 {
+ regulator-min-microvolt = <900000>;
+ regulator-max-microvolt = <1650000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ swbst_reg: swbst {
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5150000>;
+ };
+
+ snvs_reg: vsnvs {
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ vref_reg: vrefddr {
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ vgen1_reg: vldo1 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ vgen2_reg: vldo2 {
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1550000>;
+ };
+
+ vgen3_reg: vccsd {
+ regulator-min-microvolt = <2850000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ vgen4_reg: v33 {
+ regulator-min-microvolt = <2850000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ vgen5_reg: vldo3 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ vgen6_reg: vldo4 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+ };
+ };
+};
+
+&i2c3 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&pinctrl_i2c3_1>;
+ pinctrl-1 = <&pinctrl_i2c3_1>;
+ status = "okay";
+
+ max7322: gpio@68 {
+ compatible = "maxim,max7322";
+ reg = <0x68>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ max17135@48 {
+ compatible = "maxim,max17135";
+ reg = <0x48>;
+ vneg_pwrup = <1>;
+ gvee_pwrup = <2>;
+ vpos_pwrup = <10>;
+ gvdd_pwrup = <12>;
+ gvdd_pwrdn = <1>;
+ vpos_pwrdn = <2>;
+ gvee_pwrdn = <8>;
+ vneg_pwrdn = <10>;
+ gpio_pmic_pwrgood = <&gpio2 31 0>;
+ gpio_pmic_vcom_ctrl = <&gpio4 14 0>;
+ gpio_pmic_wakeup = <&gpio4 23 0>;
+ gpio_pmic_v3p3 = <&gpio4 20 0>;
+ gpio_pmic_intr = <&gpio4 18 0>;
+
+ regulators {
+ DISPLAY_reg: DISPLAY {
+ regulator-name = "DISPLAY";
+ };
+
+ GVDD_reg: GVDD {
+ /* 20v */
+ regulator-name = "GVDD";
+ };
+
+ GVEE_reg: GVEE {
+ /* -22v */
+ regulator-name = "GVEE";
+ };
+
+ HVINN_reg: HVINN {
+ /* -22v */
+ regulator-name = "HVINN";
+ };
+
+ HVINP_reg: HVINP {
+ /* 20v */
+ regulator-name = "HVINP";
+ };
+
+ VCOM_reg: VCOM {
+ regulator-name = "VCOM";
+ /* Real max value: -500000 */
+ regulator-max-microvolt = <4325000>;
+ /* Real min value: -4325000 */
+ regulator-min-microvolt = <500000>;
+ };
+
+ VNEG_reg: VNEG {
+ /* -15v */
+ regulator-name = "VNEG";
+ };
+
+ VPOS_reg: VPOS {
+ /* 15v */
+ regulator-name = "VPOS";
+ };
+
+ V3P3_reg: V3P3 {
+ regulator-name = "V3P3";
+ };
+ };
+ };
+
+ codec: wm8958@1a {
+ compatible = "wlf,wm8958";
+ reg = <0x1a>;
+ clocks = <&clks IMX7D_AUDIO_MCLK_ROOT_CLK>,
+ <&clks IMX7D_CLK_DUMMY>;
+ clock-names = "mclk1", "mclk2";
+
+ DBVDD1-supply = <&reg_aud_1v8>;
+ DBVDD2-supply = <&reg_aud_1v8>;
+ DBVDD3-supply = <&reg_aud_1v8>;
+ AVDD2-supply = <&reg_aud_1v8>;
+ CPVDD-supply = <&reg_aud_1v8>;
+ SPKVDD1-supply = <&reg_coedc_5v>;
+ SPKVDD2-supply = <&reg_coedc_5v>;
+ wlf,ldo1ena;
+ wlf,ldo2ena;
+ };
+};
+
+&iomuxc {
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&pinctrl_hog_1 &pinctrl_hog_sd2_vselect &pinctrl_hog_mipi>;
+ pinctrl-1 = <&pinctrl_hog_1 &pinctrl_hog_sd2_vselect &pinctrl_hog_mipi>;
+
+ imx7d-12x12-lpddr3-arm2 {
+
+ pinctrl_bt: btgrp-1 {
+ fsl,pins = <
+ MX7D_PAD_ENET1_CRS__GPIO7_IO14 0x80000000 /* BT REG on */
+ >;
+ };
+
+ pinctrl_ecspi1_cs_1: ecspi1_cs_grp-1 {
+ fsl,pins = <
+ MX7D_PAD_ECSPI1_SS0__GPIO4_IO19 0x2
+ >;
+ };
+
+ pinctrl_ecspi1_1: ecspi1grp-1 {
+ fsl,pins = <
+ MX7D_PAD_ECSPI1_MISO__ECSPI1_MISO 0x2
+ MX7D_PAD_ECSPI1_MOSI__ECSPI1_MOSI 0x2
+ MX7D_PAD_ECSPI1_SCLK__ECSPI1_SCLK 0x2
+ >;
+ };
+
+ pinctrl_enet1: enet1grp {
+ fsl,pins = <
+ MX7D_PAD_GPIO1_IO10__ENET1_MDIO 0x3
+ MX7D_PAD_GPIO1_IO11__ENET1_MDC 0x3
+ MX7D_PAD_ENET1_RGMII_TXC__ENET1_RGMII_TXC 0x1
+ MX7D_PAD_ENET1_RGMII_TD0__ENET1_RGMII_TD0 0x1
+ MX7D_PAD_ENET1_RGMII_TD1__ENET1_RGMII_TD1 0x1
+ MX7D_PAD_ENET1_RGMII_TD2__ENET1_RGMII_TD2 0x1
+ MX7D_PAD_ENET1_RGMII_TD3__ENET1_RGMII_TD3 0x1
+ MX7D_PAD_ENET1_RGMII_TX_CTL__ENET1_RGMII_TX_CTL 0x1
+ MX7D_PAD_ENET1_RGMII_RXC__ENET1_RGMII_RXC 0x1
+ MX7D_PAD_ENET1_RGMII_RD0__ENET1_RGMII_RD0 0x1
+ MX7D_PAD_ENET1_RGMII_RD1__ENET1_RGMII_RD1 0x1
+ MX7D_PAD_ENET1_RGMII_RD2__ENET1_RGMII_RD2 0x1
+ MX7D_PAD_ENET1_RGMII_RD3__ENET1_RGMII_RD3 0x1
+ MX7D_PAD_ENET1_RGMII_RX_CTL__ENET1_RGMII_RX_CTL 0x1
+ >;
+ };
+
+ pinctrl_enet2: enet2grp {
+ fsl,pins = <
+ MX7D_PAD_EPDC_GDSP__ENET2_RGMII_TXC 0x1
+ MX7D_PAD_EPDC_SDCE2__ENET2_RGMII_TD0 0x1
+ MX7D_PAD_EPDC_SDCE3__ENET2_RGMII_TD1 0x1
+ MX7D_PAD_EPDC_GDCLK__ENET2_RGMII_TD2 0x1
+ MX7D_PAD_EPDC_GDOE__ENET2_RGMII_TD3 0x1
+ MX7D_PAD_EPDC_GDRL__ENET2_RGMII_TX_CTL 0x1
+ MX7D_PAD_EPDC_SDCE1__ENET2_RGMII_RXC 0x1
+ MX7D_PAD_EPDC_SDCLK__ENET2_RGMII_RD0 0x1
+ MX7D_PAD_EPDC_SDLE__ENET2_RGMII_RD1 0x1
+ MX7D_PAD_EPDC_SDOE__ENET2_RGMII_RD2 0x1
+ MX7D_PAD_EPDC_SDSHR__ENET2_RGMII_RD3 0x1
+ MX7D_PAD_EPDC_SDCE0__ENET2_RGMII_RX_CTL 0x1
+ >;
+ };
+
+ pinctrl_epdc_0: epdcgrp-0 {
+ fsl,pins = <
+ MX7D_PAD_EPDC_DATA00__EPDC_DATA0 0x2
+ MX7D_PAD_EPDC_DATA01__EPDC_DATA1 0x2
+ MX7D_PAD_EPDC_DATA02__EPDC_DATA2 0x2
+ MX7D_PAD_EPDC_DATA03__EPDC_DATA3 0x2
+ MX7D_PAD_EPDC_DATA04__EPDC_DATA4 0x2
+ MX7D_PAD_EPDC_DATA05__EPDC_DATA5 0x2
+ MX7D_PAD_EPDC_DATA06__EPDC_DATA6 0x2
+ MX7D_PAD_EPDC_DATA07__EPDC_DATA7 0x2
+ MX7D_PAD_EPDC_DATA08__EPDC_DATA8 0x2
+ MX7D_PAD_EPDC_DATA09__EPDC_DATA9 0x2
+ MX7D_PAD_EPDC_DATA10__EPDC_DATA10 0x2
+ MX7D_PAD_EPDC_DATA11__EPDC_DATA11 0x2
+ MX7D_PAD_EPDC_DATA12__EPDC_DATA12 0x2
+ MX7D_PAD_EPDC_DATA13__EPDC_DATA13 0x2
+ MX7D_PAD_EPDC_DATA14__EPDC_DATA14 0x2
+ MX7D_PAD_EPDC_DATA15__EPDC_DATA15 0x2
+ MX7D_PAD_EPDC_SDCLK__EPDC_SDCLK 0x2
+ MX7D_PAD_EPDC_SDLE__EPDC_SDLE 0x2
+ MX7D_PAD_EPDC_SDOE__EPDC_SDOE 0x2
+ MX7D_PAD_EPDC_SDSHR__EPDC_SDSHR 0x2
+ MX7D_PAD_EPDC_SDCE0__EPDC_SDCE0 0x2
+ MX7D_PAD_EPDC_SDCE1__EPDC_SDCE1 0x2
+ MX7D_PAD_EPDC_SDCE2__EPDC_SDCE2 0x2
+ MX7D_PAD_EPDC_SDCE3__EPDC_SDCE3 0x2
+ MX7D_PAD_EPDC_GDCLK__EPDC_GDCLK 0x2
+ MX7D_PAD_EPDC_GDOE__EPDC_GDOE 0x2
+ MX7D_PAD_EPDC_GDRL__EPDC_GDRL 0x2
+ MX7D_PAD_EPDC_GDSP__EPDC_GDSP 0x2
+ MX7D_PAD_EPDC_BDR0__EPDC_BDR0 0x2
+ MX7D_PAD_EPDC_BDR1__EPDC_BDR1 0x2
+ MX7D_PAD_ECSPI1_MISO__GPIO4_IO18 0x80000000 /* pwr int */
+ >;
+ };
+
+ pinctrl_flexcan1: flexcan1grp {
+ fsl,pins = <
+ MX7D_PAD_SAI1_RX_DATA__FLEXCAN1_RX 0x59
+ MX7D_PAD_SAI1_TX_BCLK__FLEXCAN1_TX 0x59
+ MX7D_PAD_GPIO1_IO10__GPIO1_IO10 0x59 /* STBY */
+ >;
+ };
+
+ pinctrl_flexcan2: flexcan2grp {
+ fsl,pins = <
+ MX7D_PAD_SAI1_TX_SYNC__FLEXCAN2_RX 0x59
+ MX7D_PAD_SAI1_TX_DATA__FLEXCAN2_TX 0x59
+ MX7D_PAD_GPIO1_IO11__GPIO1_IO11 0x59 /* STBY */
+ >;
+ };
+
+ pinctrl_gpio_keys: gpio_keysgrp {
+ fsl,pins = <
+ MX7D_PAD_GPIO1_IO14__GPIO1_IO14 0x32
+ MX7D_PAD_GPIO1_IO15__GPIO1_IO15 0x32
+ >;
+ };
+
+ pinctrl_gpio_keys_sleep: gpio_keysgrp_sleep {
+ fsl,pins = <
+ MX7D_PAD_GPIO1_IO14__GPIO1_IO14 0x14
+ MX7D_PAD_GPIO1_IO15__GPIO1_IO15 0x14
+ >;
+ };
+
+ pinctrl_hog_1: hoggrp-1 {
+ fsl,pins = <
+ MX7D_PAD_I2C4_SCL__GPIO4_IO14 0x80000000
+ MX7D_PAD_EPDC_PWR_STAT__GPIO2_IO31 0x80000000
+ MX7D_PAD_ECSPI2_SCLK__GPIO4_IO20 0x80000000
+ MX7D_PAD_ECSPI2_MOSI__GPIO4_IO21 0x80000000
+ MX7D_PAD_ECSPI2_MISO__GPIO4_IO22 0x80000000
+ MX7D_PAD_ECSPI2_SS0__GPIO4_IO23 0x80000000
+ MX7D_PAD_SD1_RESET_B__GPIO5_IO2 0x59
+ MX7D_PAD_SD1_CD_B__GPIO5_IO0 0x59
+ MX7D_PAD_SD1_WP__GPIO5_IO1 0x59
+ MX7D_PAD_SD2_CD_B__GPIO5_IO9 0x59
+ MX7D_PAD_SD2_WP__GPIO5_IO10 0x59
+ MX7D_PAD_SD2_RESET_B__GPIO5_IO11 0x59
+ MX7D_PAD_GPIO1_IO13__GPIO1_IO13 0x59
+ >;
+ };
+
+ pinctrl_hog_mipi: hoggrp_mipi {
+ fsl,pins = <
+ MX7D_PAD_ECSPI1_SCLK__GPIO4_IO16 0x59
+ MX7D_PAD_ECSPI1_MOSI__GPIO4_IO17 0x59
+ >;
+ };
+
+ pinctrl_hog_sd2_vselect: hoggrp_sd2vselect {
+ fsl,pins = <
+ MX7D_PAD_GPIO1_IO12__SD2_VSELECT 0x59
+ >;
+ };
+
+ pinctrl_hog_headphone_det: hoggrp_headphone_det {
+ fsl,pins = <
+ MX7D_PAD_GPIO1_IO12__GPIO1_IO12 0x59
+ >;
+ };
+
+ pinctrl_i2c1_1: i2c1grp-1 {
+ fsl,pins = <
+ MX7D_PAD_I2C1_SDA__I2C1_SDA 0x4000007f
+ MX7D_PAD_I2C1_SCL__I2C1_SCL 0x4000007f
+ >;
+ };
+
+ pinctrl_i2c2_1: i2c2grp-1 {
+ fsl,pins = <
+ MX7D_PAD_I2C2_SDA__I2C2_SDA 0x4000007f
+ MX7D_PAD_I2C2_SCL__I2C2_SCL 0x4000007f
+ >;
+ };
+
+ pinctrl_i2c3_1: i2c3grp-1 {
+ fsl,pins = <
+ MX7D_PAD_I2C3_SDA__I2C3_SDA 0x4000007f
+ MX7D_PAD_I2C3_SCL__I2C3_SCL 0x4000007f
+ >;
+ };
+
+ pinctrl_i2c4_1: i2c4grp-1 {
+ fsl,pins = <
+ MX7D_PAD_I2C4_SDA__I2C4_SDA 0x4000007f
+ MX7D_PAD_I2C4_SCL__I2C4_SCL 0x4000007f
+ >;
+ };
+
+ pinctrl_lcdif_dat: lcdifdatgrp {
+ fsl,pins = <
+ MX7D_PAD_LCD_DATA00__LCD_DATA0 0x79
+ MX7D_PAD_LCD_DATA01__LCD_DATA1 0x79
+ MX7D_PAD_LCD_DATA02__LCD_DATA2 0x79
+ MX7D_PAD_LCD_DATA03__LCD_DATA3 0x79
+ MX7D_PAD_LCD_DATA04__LCD_DATA4 0x79
+ MX7D_PAD_LCD_DATA05__LCD_DATA5 0x79
+ MX7D_PAD_LCD_DATA06__LCD_DATA6 0x79
+ MX7D_PAD_LCD_DATA07__LCD_DATA7 0x79
+ MX7D_PAD_LCD_DATA08__LCD_DATA8 0x79
+ MX7D_PAD_LCD_DATA09__LCD_DATA9 0x79
+ MX7D_PAD_LCD_DATA10__LCD_DATA10 0x79
+ MX7D_PAD_LCD_DATA11__LCD_DATA11 0x79
+ MX7D_PAD_LCD_DATA12__LCD_DATA12 0x79
+ MX7D_PAD_LCD_DATA13__LCD_DATA13 0x79
+ MX7D_PAD_LCD_DATA14__LCD_DATA14 0x79
+ MX7D_PAD_LCD_DATA15__LCD_DATA15 0x79
+ MX7D_PAD_LCD_DATA16__LCD_DATA16 0x79
+ MX7D_PAD_LCD_DATA17__LCD_DATA17 0x79
+ MX7D_PAD_LCD_DATA18__LCD_DATA18 0x79
+ MX7D_PAD_LCD_DATA19__LCD_DATA19 0x79
+ MX7D_PAD_LCD_DATA20__LCD_DATA20 0x79
+ MX7D_PAD_LCD_DATA21__LCD_DATA21 0x79
+ MX7D_PAD_LCD_DATA22__LCD_DATA22 0x79
+ MX7D_PAD_LCD_DATA23__LCD_DATA23 0x79
+ >;
+ };
+
+ pinctrl_lcdif_ctrl: lcdifctrlgrp {
+ fsl,pins = <
+ MX7D_PAD_LCD_CLK__LCD_CLK 0x79
+ MX7D_PAD_LCD_ENABLE__LCD_ENABLE 0x79
+ MX7D_PAD_LCD_VSYNC__LCD_VSYNC 0x79
+ MX7D_PAD_LCD_HSYNC__LCD_HSYNC 0x79
+ >;
+ };
+
+ pinctrl_mqs: mqsgrp {
+ fsl,pins = <
+ MX7D_PAD_SAI1_RX_SYNC__MQS_RIGHT 0x0
+ MX7D_PAD_SAI1_RX_BCLK__MQS_LEFT 0x0
+ >;
+ };
+
+ pinctrl_pcie: pciegrp {
+ fsl,pins = <
+ MX7D_PAD_SAI2_TX_SYNC__GPIO6_IO19 0x2
+ MX7D_PAD_SAI2_RX_DATA__GPIO6_IO21 0x2
+ >;
+ };
+
+ pinctrl_sai1: sai1grp {
+ fsl,pins = <
+ MX7D_PAD_SAI1_MCLK__SAI1_MCLK 0x1f
+ MX7D_PAD_SAI1_TX_BCLK__SAI1_TX_BCLK 0x1f
+ MX7D_PAD_SAI1_TX_SYNC__SAI1_TX_SYNC 0x1f
+ MX7D_PAD_SAI1_RX_SYNC__SAI1_RX_SYNC 0x1f
+ MX7D_PAD_SAI1_RX_DATA__SAI1_RX_DATA0 0x1f
+ MX7D_PAD_SAI1_TX_DATA__SAI1_TX_DATA0 0
+ >;
+ };
+
+ pinctrl_sai2: sai2grp {
+ fsl,pins = <
+ MX7D_PAD_SAI2_TX_BCLK__SAI2_TX_BCLK 0x1f
+ MX7D_PAD_SAI2_TX_SYNC__SAI2_TX_SYNC 0x1f
+ MX7D_PAD_SAI2_RX_DATA__SAI2_RX_DATA0 0x1f
+ MX7D_PAD_SAI2_TX_DATA__SAI2_TX_DATA0 0
+ >;
+ };
+
+ pinctrl_uart1_1: uart1grp-1 {
+ fsl,pins = <
+ MX7D_PAD_UART1_TX_DATA__UART1_DCE_TX 0x79
+ MX7D_PAD_UART1_RX_DATA__UART1_DCE_RX 0x79
+ >;
+ };
+
+ pinctrl_uart3_1: uart3grp-1 {
+ fsl,pins = <
+ MX7D_PAD_UART3_TX_DATA__UART3_DCE_TX 0x79
+ MX7D_PAD_UART3_RX_DATA__UART3_DCE_RX 0x79
+ MX7D_PAD_UART3_CTS_B__UART3_DCE_CTS 0x79
+ MX7D_PAD_UART3_RTS_B__UART3_DCE_RTS 0x79
+ >;
+ };
+
+ pinctrl_uart3dte_1: uart3dtegrp-1 {
+ fsl,pins = <
+ MX7D_PAD_UART3_TX_DATA__UART3_DTE_RX 0x79
+ MX7D_PAD_UART3_RX_DATA__UART3_DTE_TX 0x79
+ MX7D_PAD_UART3_RTS_B__UART3_DTE_CTS 0x79
+ MX7D_PAD_UART3_CTS_B__UART3_DTE_RTS 0x79
+ >;
+ };
+
+ pinctrl_usdhc1_1: usdhc1grp-1 {
+ fsl,pins = <
+ MX7D_PAD_SD1_CMD__SD1_CMD 0x59
+ MX7D_PAD_SD1_CLK__SD1_CLK 0x19
+ MX7D_PAD_SD1_DATA0__SD1_DATA0 0x59
+ MX7D_PAD_SD1_DATA1__SD1_DATA1 0x59
+ MX7D_PAD_SD1_DATA2__SD1_DATA2 0x59
+ MX7D_PAD_SD1_DATA3__SD1_DATA3 0x59
+ >;
+ };
+
+ pinctrl_usdhc2_1: usdhc2grp-1 {
+ fsl,pins = <
+ MX7D_PAD_SD2_CMD__SD2_CMD 0x59
+ MX7D_PAD_SD2_CLK__SD2_CLK 0x19
+ MX7D_PAD_SD2_DATA0__SD2_DATA0 0x59
+ MX7D_PAD_SD2_DATA1__SD2_DATA1 0x59
+ MX7D_PAD_SD2_DATA2__SD2_DATA2 0x59
+ MX7D_PAD_SD2_DATA3__SD2_DATA3 0x59
+ >;
+ };
+
+ pinctrl_usdhc2_1_100mhz: usdhc2grp-1_100mhz {
+ fsl,pins = <
+ MX7D_PAD_SD2_CMD__SD2_CMD 0x5a
+ MX7D_PAD_SD2_CLK__SD2_CLK 0x1a
+ MX7D_PAD_SD2_DATA0__SD2_DATA0 0x5a
+ MX7D_PAD_SD2_DATA1__SD2_DATA1 0x5a
+ MX7D_PAD_SD2_DATA2__SD2_DATA2 0x5a
+ MX7D_PAD_SD2_DATA3__SD2_DATA3 0x5a
+ >;
+ };
+
+ pinctrl_usdhc2_1_200mhz: usdhc2grp-1_200mhz {
+ fsl,pins = <
+ MX7D_PAD_SD2_CMD__SD2_CMD 0x5b
+ MX7D_PAD_SD2_CLK__SD2_CLK 0x1b
+ MX7D_PAD_SD2_DATA0__SD2_DATA0 0x5b
+ MX7D_PAD_SD2_DATA1__SD2_DATA1 0x5b
+ MX7D_PAD_SD2_DATA2__SD2_DATA2 0x5b
+ MX7D_PAD_SD2_DATA3__SD2_DATA3 0x5b
+ >;
+ };
+
+ pinctrl_usdhc3_1: usdhc3grp-1 {
+ fsl,pins = <
+ MX7D_PAD_SD3_CMD__SD3_CMD 0x59
+ MX7D_PAD_SD3_CLK__SD3_CLK 0x19
+ MX7D_PAD_SD3_DATA0__SD3_DATA0 0x59
+ MX7D_PAD_SD3_DATA1__SD3_DATA1 0x59
+ MX7D_PAD_SD3_DATA2__SD3_DATA2 0x59
+ MX7D_PAD_SD3_DATA3__SD3_DATA3 0x59
+ MX7D_PAD_SD3_DATA4__SD3_DATA4 0x59
+ MX7D_PAD_SD3_DATA5__SD3_DATA5 0x59
+ MX7D_PAD_SD3_DATA6__SD3_DATA6 0x59
+ MX7D_PAD_SD3_DATA7__SD3_DATA7 0x59
+ MX7D_PAD_SD3_STROBE__SD3_STROBE 0x19
+ >;
+ };
+
+ pinctrl_usdhc3_1_100mhz: usdhc3grp-1_100mhz {
+ fsl,pins = <
+ MX7D_PAD_SD3_CMD__SD3_CMD 0x5a
+ MX7D_PAD_SD3_CLK__SD3_CLK 0x1a
+ MX7D_PAD_SD3_DATA0__SD3_DATA0 0x5a
+ MX7D_PAD_SD3_DATA1__SD3_DATA1 0x5a
+ MX7D_PAD_SD3_DATA2__SD3_DATA2 0x5a
+ MX7D_PAD_SD3_DATA3__SD3_DATA3 0x5a
+ MX7D_PAD_SD3_DATA4__SD3_DATA4 0x5a
+ MX7D_PAD_SD3_DATA5__SD3_DATA5 0x5a
+ MX7D_PAD_SD3_DATA6__SD3_DATA6 0x5a
+ MX7D_PAD_SD3_DATA7__SD3_DATA7 0x5a
+ MX7D_PAD_SD3_STROBE__SD3_STROBE 0x1a
+ >;
+ };
+
+ pinctrl_usdhc3_1_200mhz: usdhc3grp-1_200mhz {
+ fsl,pins = <
+ MX7D_PAD_SD3_CMD__SD3_CMD 0x5b
+ MX7D_PAD_SD3_CLK__SD3_CLK 0x1b
+ MX7D_PAD_SD3_DATA0__SD3_DATA0 0x5b
+ MX7D_PAD_SD3_DATA1__SD3_DATA1 0x5b
+ MX7D_PAD_SD3_DATA2__SD3_DATA2 0x5b
+ MX7D_PAD_SD3_DATA3__SD3_DATA3 0x5b
+ MX7D_PAD_SD3_DATA4__SD3_DATA4 0x5b
+ MX7D_PAD_SD3_DATA5__SD3_DATA5 0x5b
+ MX7D_PAD_SD3_DATA6__SD3_DATA6 0x5b
+ MX7D_PAD_SD3_DATA7__SD3_DATA7 0x5b
+ MX7D_PAD_SD3_STROBE__SD3_STROBE 0x1b
+ >;
+ };
+
+ pinctrl_sim1_1: sim1grp-1 {
+ fsl,pins = <
+ MX7D_PAD_SAI1_TX_SYNC__SIM1_PORT1_RST_B 0x77
+ MX7D_PAD_SAI1_RX_SYNC__SIM1_PORT1_PD 0x77
+ MX7D_PAD_SAI1_TX_DATA__SIM1_PORT1_SVEN 0x77
+ MX7D_PAD_SAI1_TX_BCLK__SIM1_PORT1_CLK 0x73
+ MX7D_PAD_SAI1_RX_DATA__SIM1_PORT1_TRXD 0x73
+ >;
+ };
+
+ };
+};
+
+&iomuxc_lpsr {
+ imx7d-12x12-lpddr3-arm2 {
+ pinctrl_pwm1: pwm1grp {
+ fsl,pins = <
+ MX7D_PAD_LPSR_GPIO1_IO01__PWM1_OUT 0x30
+ >;
+ };
+ };
+
+ imx7d-sdb {
+ pinctrl_usbotg1_vbus: usbotg1vbusgrp {
+ fsl,pins = <
+ MX7D_PAD_LPSR_GPIO1_IO05__GPIO1_IO5 0x14
+ >;
+ };
+
+ pinctrl_usbotg2_vbus: usbotg2vbusgrp {
+ fsl,pins = <
+ MX7D_PAD_LPSR_GPIO1_IO07__GPIO1_IO7 0x14
+ >;
+ };
+
+ pinctrl_wdog: wdoggrp {
+ fsl,pins = <
+ MX7D_PAD_LPSR_GPIO1_IO00__WDOG1_WDOG_B 0x74
+ >;
+ };
+ };
+};
+
+&lcdif {
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&pinctrl_lcdif_dat
+ &pinctrl_lcdif_ctrl>;
+ pinctrl-1 = <&pinctrl_lcdif_dat
+ &pinctrl_lcdif_ctrl>;
+ display = <&display0>;
+ status = "okay";
+
+ display0: display {
+ bits-per-pixel = <16>;
+ bus-width = <24>;
+
+ display-timings {
+ native-mode = <&timing0>;
+ timing0: timing0 {
+ clock-frequency = <33500000>;
+ hactive = <800>;
+ vactive = <480>;
+ hback-porch = <89>;
+ hfront-porch = <164>;
+ vback-porch = <23>;
+ vfront-porch = <10>;
+ hsync-len = <10>;
+ vsync-len = <10>;
+ hsync-active = <0>;
+ vsync-active = <0>;
+ de-active = <1>;
+ pixelclk-active = <0>;
+ };
+ };
+ };
+};
+
+&ocrams {
+ fsl,enable-lpsr;
+};
+
+&pcie {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pcie>;
+ reset-gpio = <&gpio6 21 GPIO_ACTIVE_LOW>;
+ power-on-gpio = <&gpio6 19 GPIO_ACTIVE_HIGH>;
+ status = "disabled";
+};
+
+&pwm1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pwm1>;
+ status = "okay";
+};
+
+&sim1 {
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&pinctrl_sim1_1>;
+ pinctrl-1 = <&pinctrl_sim1_1>;
+ status = "okay";
+};
+
+&uart1 {
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&pinctrl_uart1_1>;
+ pinctrl-1 = <&pinctrl_uart1_1>;
+ assigned-clocks = <&clks IMX7D_UART1_ROOT_SRC>;
+ assigned-clock-parents = <&clks IMX7D_OSC_24M_CLK>;
+ status = "okay";
+};
+
+&uart3 {
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&pinctrl_uart3_1
+ &pinctrl_bt>;
+ pinctrl-1 = <&pinctrl_uart3_1
+ &pinctrl_bt>;
+ fsl,uart-has-rtscts;
+ assigned-clocks = <&clks IMX7D_UART3_ROOT_SRC>;
+ assigned-clock-parents = <&clks IMX7D_PLL_SYS_MAIN_240M_CLK>;
+ status = "okay";
+ /* for DTE mode, add below change */
+ /* fsl,dte-mode;*/
+ /* pinctrl-0 = <&pinctrl_uart3dte_1>; */
+};
+
+&usbotg1 {
+ vbus-supply = <&reg_usb_otg1_vbus>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usbotg1_vbus>;
+ srp-disable;
+ hnp-disable;
+ adp-disable;
+ status = "okay";
+};
+
+&usbotg2 {
+ vbus-supply = <&reg_usb_otg2_vbus>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usbotg2_vbus>;
+ srp-disable;
+ hnp-disable;
+ adp-disable;
+ status = "okay";
+};
+
+&usdhc1 {
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&pinctrl_usdhc1_1>;
+ pinctrl-1 = <&pinctrl_usdhc1_1>;
+ cd-gpios = <&gpio5 0 GPIO_ACTIVE_LOW>;
+ wp-gpios = <&gpio5 1 GPIO_ACTIVE_HIGH>;
+ no-1-8-v;
+ keep-power-in-suspend;
+ enable-sdio-wakeup;
+ vmmc-supply = <&reg_sd1_vmmc>;
+ status = "okay";
+};
+
+&usdhc2 {
+ pinctrl-names = "default", "state_100mhz", "state_200mhz", "sleep";
+ pinctrl-0 = <&pinctrl_usdhc2_1>;
+ pinctrl-1 = <&pinctrl_usdhc2_1_100mhz>;
+ pinctrl-2 = <&pinctrl_usdhc2_1_200mhz>;
+ pinctrl-3 = <&pinctrl_usdhc2_1>;
+ cd-gpios = <&gpio5 9 GPIO_ACTIVE_LOW>;
+ wp-gpios = <&gpio5 10 GPIO_ACTIVE_HIGH>;
+ keep-power-in-suspend;
+ enable-sdio-wakeup;
+ vmmc-supply = <&reg_sd2_vmmc>;
+ status = "okay";
+};
+
+&usdhc3 {
+ pinctrl-names = "default", "state_100mhz", "state_200mhz", "sleep";
+ pinctrl-0 = <&pinctrl_usdhc3_1>;
+ pinctrl-1 = <&pinctrl_usdhc3_1_100mhz>;
+ pinctrl-2 = <&pinctrl_usdhc3_1_200mhz>;
+ pinctrl-3 = <&pinctrl_usdhc3_1>;
+ assigned-clocks = <&clks IMX7D_USDHC3_ROOT_CLK>;
+ assigned-clock-rates = <400000000>;
+ bus-width = <8>;
+ non-removable;
+ keep-power-in-suspend;
+ status = "okay";
+};
+
+&wdog1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_wdog>;
+ fsl,ext-reset-output;
+};
diff --git a/arch/arm/boot/dts/imx7d-19x19-lpddr2-arm2.dts b/arch/arm/boot/dts/imx7d-19x19-lpddr2-arm2.dts
new file mode 100644
index 000000000000..9234b169f8df
--- /dev/null
+++ b/arch/arm/boot/dts/imx7d-19x19-lpddr2-arm2.dts
@@ -0,0 +1,454 @@
+/*
+ * Copyright (C) 2015 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 <dt-bindings/input/input.h>
+#include "imx7d.dtsi"
+
+/ {
+ model = "Freescale i.MX7D LPDDR2 19x19 ARM2 Board";
+ compatible = "fsl,imx7d-19x19-lpddr2-arm2", "fsl,imx7d";
+
+ gpio-keys {
+ compatible = "gpio-keys";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpio_keys>;
+ status = "disabled";
+
+ volume-up {
+ label = "Volume Up";
+ gpios = <&gpio1 14 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_VOLUMEUP>;
+ };
+
+ volume-down {
+ label = "Volume Down";
+ gpios = <&gpio1 15 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_VOLUMEDOWN>;
+ };
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ reg_sd1_vmmc: sd1_vmmc {
+ compatible = "regulator-fixed";
+ regulator-name = "VCC_SD1";
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ gpio = <&gpio5 2 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ reg_usb_otg1_vbus: regulator@0 {
+ compatible = "regulator-fixed";
+ reg = <0>;
+ regulator-name = "usb_otg1_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&gpio1 5 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ reg_usb_otg2_vbus: regulator@1 {
+ compatible = "regulator-fixed";
+ reg = <1>;
+ regulator-name = "usb_otg2_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&gpio1 7 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ reg_vref_1v8: regulator@2 {
+ compatible = "regulator-fixed";
+ regulator-name = "vref-1v8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+ };
+
+ memory {
+ reg = <0x80000000 0x20000000>;
+ };
+};
+
+&adc1 {
+ vref-supply = <&reg_vref_1v8>;
+ status = "okay";
+};
+
+&cpu0 {
+ arm-supply = <&sw1a_reg>;
+};
+
+&i2c1 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c1_1>;
+ status = "okay";
+
+ pmic: pfuze3000@08 {
+ compatible = "fsl,pfuze3000";
+ reg = <0x08>;
+
+ regulators {
+ sw1a_reg: sw1a {
+ regulator-min-microvolt = <700000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ regulator-ramp-delay = <6250>;
+ };
+ /* use sw1c_reg to align with pfuze100/pfuze200 */
+ sw1c_reg: sw1b {
+ regulator-min-microvolt = <700000>;
+ regulator-max-microvolt = <1475000>;
+ regulator-boot-on;
+ regulator-always-on;
+ regulator-ramp-delay = <6250>;
+ };
+
+ sw2_reg: sw2 {
+ regulator-min-microvolt = <1500000>;
+ regulator-max-microvolt = <1850000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ sw3a_reg: sw3 {
+ regulator-min-microvolt = <900000>;
+ regulator-max-microvolt = <1650000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ swbst_reg: swbst {
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5150000>;
+ };
+
+ snvs_reg: vsnvs {
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ vref_reg: vrefddr {
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ vgen1_reg: vldo1 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ vgen2_reg: vldo2 {
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1550000>;
+ };
+
+ vgen3_reg: vccsd {
+ regulator-min-microvolt = <2850000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ vgen4_reg: v33 {
+ regulator-min-microvolt = <2850000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ vgen5_reg: vldo3 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ vgen6_reg: vldo4 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+ };
+ };
+};
+
+&i2c2 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c2_1>;
+ status = "okay";
+};
+
+&iomuxc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_hog_1>;
+
+ imx7d-19x19-lpddr3-arm2 {
+ pinctrl_hog_1: hoggrp-1 {
+ fsl,pins = <
+ MX7D_PAD_I2C4_SCL__GPIO4_IO14 0x80000000
+
+ MX7D_PAD_SD1_CD_B__GPIO5_IO0 0x59
+ MX7D_PAD_SD1_WP__GPIO5_IO1 0x59
+ MX7D_PAD_SD1_RESET_B__GPIO5_IO2 0x59
+
+ MX7D_PAD_GPIO1_IO14__GPIO1_IO14 0x59
+ MX7D_PAD_GPIO1_IO15__GPIO1_IO15 0x59
+ >;
+ };
+
+ pinctrl_gpio_keys: gpio_keysgrp {
+ fsl,pins = <
+ MX7D_PAD_GPIO1_IO14__GPIO1_IO14 0x32
+ MX7D_PAD_GPIO1_IO15__GPIO1_IO15 0x32
+ >;
+ };
+
+ pinctrl_gpmi_nand_1: gpmi-nand-1 {
+ fsl,pins = <
+ MX7D_PAD_SD3_CLK__NAND_CLE 0x71
+ MX7D_PAD_SD3_CMD__NAND_ALE 0x71
+ MX7D_PAD_SAI1_MCLK__NAND_WP_B 0x71
+ MX7D_PAD_SAI1_TX_BCLK__NAND_CE0_B 0x71
+ MX7D_PAD_SAI1_RX_DATA__NAND_CE1_B 0x71
+ MX7D_PAD_SAI1_TX_DATA__NAND_READY_B 0x74
+ MX7D_PAD_SD3_STROBE__NAND_RE_B 0x71
+ MX7D_PAD_SD3_RESET_B__NAND_WE_B 0x71
+ MX7D_PAD_SD3_DATA0__NAND_DATA00 0x71
+ MX7D_PAD_SD3_DATA1__NAND_DATA01 0x71
+ MX7D_PAD_SD3_DATA2__NAND_DATA02 0x71
+ MX7D_PAD_SD3_DATA3__NAND_DATA03 0x71
+ MX7D_PAD_SD3_DATA4__NAND_DATA04 0x71
+ MX7D_PAD_SD3_DATA5__NAND_DATA05 0x71
+ MX7D_PAD_SD3_DATA6__NAND_DATA06 0x71
+ MX7D_PAD_SD3_DATA7__NAND_DATA07 0x71
+ >;
+ };
+
+ pinctrl_i2c1_1: i2c1grp-1 {
+ fsl,pins = <
+ MX7D_PAD_I2C1_SDA__I2C1_SDA 0x4000007f
+ MX7D_PAD_I2C1_SCL__I2C1_SCL 0x4000007f
+ >;
+ };
+
+ pinctrl_i2c2_1: i2c2grp-1 {
+ fsl,pins = <
+ MX7D_PAD_I2C2_SDA__I2C2_SDA 0x4000007f
+ MX7D_PAD_I2C2_SCL__I2C2_SCL 0x4000007f
+ >;
+ };
+
+ pinctrl_weim_cs0_1: weim_cs0grp-1 {
+ fsl,pins = <
+ MX7D_PAD_EPDC_DATA10__EIM_CS0_B 0x71
+ >;
+ };
+
+ pinctrl_weim_nor_1: weim_norgrp-1 {
+ fsl,pins = <
+ MX7D_PAD_EPDC_DATA08__EIM_OE 0x71
+ MX7D_PAD_EPDC_DATA09__EIM_RW 0x71
+ MX7D_PAD_EPDC_DATA11__EIM_BCLK 0x71
+ MX7D_PAD_EPDC_DATA12__EIM_LBA_B 0x71
+ MX7D_PAD_EPDC_DATA13__EIM_WAIT 0x75
+ /* data */
+ MX7D_PAD_LCD_DATA00__EIM_DATA0 0x7d
+ MX7D_PAD_LCD_DATA01__EIM_DATA1 0x7d
+ MX7D_PAD_LCD_DATA02__EIM_DATA2 0x7d
+ MX7D_PAD_LCD_DATA03__EIM_DATA3 0x7d
+ MX7D_PAD_LCD_DATA04__EIM_DATA4 0x7d
+ MX7D_PAD_LCD_DATA05__EIM_DATA5 0x7d
+ MX7D_PAD_LCD_DATA06__EIM_DATA6 0x7d
+ MX7D_PAD_LCD_DATA07__EIM_DATA7 0x7d
+ MX7D_PAD_LCD_DATA08__EIM_DATA8 0x7d
+ MX7D_PAD_LCD_DATA09__EIM_DATA9 0x7d
+ MX7D_PAD_LCD_DATA10__EIM_DATA10 0x7d
+ MX7D_PAD_LCD_DATA11__EIM_DATA11 0x7d
+ MX7D_PAD_LCD_DATA12__EIM_DATA12 0x7d
+ MX7D_PAD_LCD_DATA13__EIM_DATA13 0x7d
+ MX7D_PAD_LCD_DATA14__EIM_DATA14 0x7d
+ MX7D_PAD_LCD_DATA15__EIM_DATA15 0x7d
+ /* address */
+ MX7D_PAD_EPDC_DATA00__EIM_AD0 0x71
+ MX7D_PAD_EPDC_DATA01__EIM_AD1 0x71
+ MX7D_PAD_EPDC_DATA02__EIM_AD2 0x71
+ MX7D_PAD_EPDC_DATA03__EIM_AD3 0x71
+ MX7D_PAD_EPDC_DATA04__EIM_AD4 0x71
+ MX7D_PAD_EPDC_DATA05__EIM_AD5 0x71
+ MX7D_PAD_EPDC_DATA06__EIM_AD6 0x71
+ MX7D_PAD_EPDC_DATA07__EIM_AD7 0x71
+ MX7D_PAD_EPDC_BDR1__EIM_AD8 0x71
+ MX7D_PAD_EPDC_PWR_COM__EIM_AD9 0x71
+ MX7D_PAD_EPDC_SDCLK__EIM_AD10 0x71
+ MX7D_PAD_EPDC_SDLE__EIM_AD11 0x71
+ MX7D_PAD_EPDC_SDOE__EIM_AD12 0x71
+ MX7D_PAD_EPDC_SDSHR__EIM_AD13 0x71
+ MX7D_PAD_EPDC_SDCE0__EIM_AD14 0x71
+ MX7D_PAD_EPDC_SDCE1__EIM_AD15 0x71
+ MX7D_PAD_EPDC_SDCE2__EIM_ADDR16 0x71
+ MX7D_PAD_EPDC_SDCE3__EIM_ADDR17 0x71
+ MX7D_PAD_EPDC_GDCLK__EIM_ADDR18 0x71
+ MX7D_PAD_EPDC_GDOE__EIM_ADDR19 0x71
+ MX7D_PAD_EPDC_GDRL__EIM_ADDR20 0x71
+ MX7D_PAD_EPDC_GDSP__EIM_ADDR21 0x71
+ MX7D_PAD_EPDC_BDR0__EIM_ADDR22 0x71
+ MX7D_PAD_LCD_DATA20__EIM_ADDR23 0x71
+ MX7D_PAD_LCD_DATA21__EIM_ADDR24 0x71
+ MX7D_PAD_LCD_DATA22__EIM_ADDR25 0x71
+ >;
+ };
+
+ pinctrl_uart1_1: uart1grp-1 {
+ fsl,pins = <
+ MX7D_PAD_UART1_TX_DATA__UART1_DCE_TX 0x79
+ MX7D_PAD_UART1_RX_DATA__UART1_DCE_RX 0x79
+ >;
+ };
+
+ pinctrl_uart3_1: uart3grp-1 {
+ fsl,pins = <
+ MX7D_PAD_UART3_TX_DATA__UART3_DCE_TX 0x79
+ MX7D_PAD_UART3_RX_DATA__UART3_DCE_RX 0x79
+ MX7D_PAD_UART3_CTS_B__UART3_DCE_CTS 0x79
+ MX7D_PAD_UART3_RTS_B__UART3_DCE_RTS 0x79
+ >;
+ };
+
+ pinctrl_uart3dte_1: uart3dtegrp-1 {
+ fsl,pins = <
+ MX7D_PAD_UART3_TX_DATA__UART3_DTE_RX 0x79
+ MX7D_PAD_UART3_RX_DATA__UART3_DTE_TX 0x79
+ MX7D_PAD_UART3_RTS_B__UART3_DTE_CTS 0x79
+ MX7D_PAD_UART3_CTS_B__UART3_DTE_RTS 0x79
+ >;
+ };
+
+ pinctrl_usdhc1: usdhc1grp {
+ fsl,pins = <
+ MX7D_PAD_SD1_CMD__SD1_CMD 0x59
+ MX7D_PAD_SD1_CLK__SD1_CLK 0x19
+ MX7D_PAD_SD1_DATA0__SD1_DATA0 0x59
+ MX7D_PAD_SD1_DATA1__SD1_DATA1 0x59
+ MX7D_PAD_SD1_DATA2__SD1_DATA2 0x59
+ MX7D_PAD_SD1_DATA3__SD1_DATA3 0x59
+ >;
+ };
+
+ pinctrl_usdhc1_100mhz: usdhc1grp_100mhz {
+ fsl,pins = <
+ MX7D_PAD_SD1_CMD__SD1_CMD 0x5a
+ MX7D_PAD_SD1_CLK__SD1_CLK 0x1a
+ MX7D_PAD_SD1_DATA0__SD1_DATA0 0x5a
+ MX7D_PAD_SD1_DATA1__SD1_DATA1 0x5a
+ MX7D_PAD_SD1_DATA2__SD1_DATA2 0x5a
+ MX7D_PAD_SD1_DATA3__SD1_DATA3 0x5a
+ >;
+ };
+
+ pinctrl_usdhc1_200mhz: usdhc1grp_200mhz {
+ fsl,pins = <
+ MX7D_PAD_SD1_CMD__SD1_CMD 0x5b
+ MX7D_PAD_SD1_CLK__SD1_CLK 0x1b
+ MX7D_PAD_SD1_DATA0__SD1_DATA0 0x5b
+ MX7D_PAD_SD1_DATA1__SD1_DATA1 0x5b
+ MX7D_PAD_SD1_DATA2__SD1_DATA2 0x5b
+ MX7D_PAD_SD1_DATA3__SD1_DATA3 0x5b
+ >;
+ };
+ };
+};
+
+&iomuxc_lpsr {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_hog_2>;
+
+ imx7d-19x19-lpddr3-arm2 {
+ pinctrl_hog_2: hoggrp-2 {
+ fsl,pins = <
+ MX7D_PAD_LPSR_GPIO1_IO03__GPIO1_IO3 0x14
+ MX7D_PAD_LPSR_GPIO1_IO05__GPIO1_IO5 0x14
+ MX7D_PAD_LPSR_GPIO1_IO07__GPIO1_IO7 0x14
+ >;
+ };
+ };
+};
+
+&sdma {
+ status = "okay";
+};
+
+&weim {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_weim_nor_1 &pinctrl_weim_cs0_1>;
+ #address-cells = <2>;
+ #size-cells = <1>;
+ ranges = <0 0 0x28000000 0x08000000>;
+ status = "okay";
+
+ nor@0,0 {
+ compatible = "cfi-flash";
+ reg = <0 0 0x08000000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ bank-width = <2>;
+ fsl,weim-cs-timing = <0x00610081 0x00000001 0x1c022000
+ 0x0000c000 0x1404a38e 0x00000000>;
+ };
+};
+
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart1_1>;
+ assigned-clocks = <&clks IMX7D_UART1_ROOT_SRC>;
+ assigned-clock-parents = <&clks IMX7D_OSC_24M_CLK>;
+ status = "okay";
+};
+
+&uart3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart3_1>;
+ fsl,uart-has-rtscts;
+ assigned-clocks = <&clks IMX7D_UART3_ROOT_SRC>;
+ assigned-clock-parents = <&clks IMX7D_PLL_SYS_MAIN_240M_CLK>;
+ status = "okay";
+ /* for DTE mode, add below change */
+ /* fsl,dte-mode;*/
+ pinctrl-0 = <&pinctrl_uart3dte_1>;
+};
+
+&usbotg1 {
+ vbus-supply = <&reg_usb_otg1_vbus>;
+ status = "okay";
+};
+
+&usbotg2 {
+ vbus-supply = <&reg_usb_otg2_vbus>;
+ status = "okay";
+};
+
+&usdhc1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usdhc1>;
+ cd-gpios = <&gpio5 0 GPIO_ACTIVE_LOW>;
+ wp-gpios = <&gpio5 1 GPIO_ACTIVE_HIGH>;
+ no-1-8-v;
+ keep-power-in-suspend;
+ enable-sdio-wakeup;
+ vmmc-supply = <&reg_sd1_vmmc>;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx7d-pinfunc.h b/arch/arm/boot/dts/imx7d-pinfunc.h
index f2493bc63da4..aa9dbead4b8b 100644
--- a/arch/arm/boot/dts/imx7d-pinfunc.h
+++ b/arch/arm/boot/dts/imx7d-pinfunc.h
@@ -592,7 +592,7 @@
#define MX7D_PAD_UART2_RX_DATA__UART2_DCE_RX 0x0130 0x03A0 0x06FC 0x0 0x2
#define MX7D_PAD_UART2_RX_DATA__UART2_DTE_TX 0x0130 0x03A0 0x0000 0x0 0x0
#define MX7D_PAD_UART2_RX_DATA__I2C2_SCL 0x0130 0x03A0 0x05DC 0x1 0x0
-#define MX7D_PAD_UART2_RX_DATA__SAI3_RX_BCLK 0x0130 0x03A0 0x0000 0x2 0x0
+#define MX7D_PAD_UART2_RX_DATA__SAI3_RX_BCLK 0x0130 0x03A0 0x06C4 0x2 0x0
#define MX7D_PAD_UART2_RX_DATA__ECSPI1_SS3 0x0130 0x03A0 0x0000 0x3 0x0
#define MX7D_PAD_UART2_RX_DATA__ENET2_1588_EVENT1_IN 0x0130 0x03A0 0x0000 0x4 0x0
#define MX7D_PAD_UART2_RX_DATA__GPIO4_IO2 0x0130 0x03A0 0x0000 0x5 0x0
@@ -1112,13 +1112,13 @@
#define MX7D_PAD_ENET1_RGMII_TD3__GPIO7_IO9 0x0250 0x04C0 0x0000 0x5 0x0
#define MX7D_PAD_ENET1_RGMII_TD3__CAAM_RNG_OSC_OBS 0x0250 0x04C0 0x0000 0x7 0x0
#define MX7D_PAD_ENET1_RGMII_TX_CTL__ENET1_RGMII_TX_CTL 0x0254 0x04C4 0x0000 0x0 0x0
-#define MX7D_PAD_ENET1_RGMII_TX_CTL__SAI1_RX_SYNC 0x0254 0x04C4 0x0000 0x2 0x0
+#define MX7D_PAD_ENET1_RGMII_TX_CTL__SAI1_RX_SYNC 0x0254 0x04C4 0x06A4 0x2 0x1
#define MX7D_PAD_ENET1_RGMII_TX_CTL__GPT2_COMPARE1 0x0254 0x04C4 0x0000 0x3 0x0
#define MX7D_PAD_ENET1_RGMII_TX_CTL__EPDC_PWR_CTRL2 0x0254 0x04C4 0x0000 0x4 0x0
#define MX7D_PAD_ENET1_RGMII_TX_CTL__GPIO7_IO10 0x0254 0x04C4 0x0000 0x5 0x0
#define MX7D_PAD_ENET1_RGMII_TXC__ENET1_RGMII_TXC 0x0258 0x04C8 0x0000 0x0 0x0
#define MX7D_PAD_ENET1_RGMII_TXC__ENET1_TX_ER 0x0258 0x04C8 0x0000 0x1 0x0
-#define MX7D_PAD_ENET1_RGMII_TXC__SAI1_RX_BCLK 0x0258 0x04C8 0x0000 0x2 0x0
+#define MX7D_PAD_ENET1_RGMII_TXC__SAI1_RX_BCLK 0x0258 0x04C8 0x069C 0x2 0x1
#define MX7D_PAD_ENET1_RGMII_TXC__GPT2_COMPARE2 0x0258 0x04C8 0x0000 0x3 0x0
#define MX7D_PAD_ENET1_RGMII_TXC__EPDC_PWR_CTRL3 0x0258 0x04C8 0x0000 0x4 0x0
#define MX7D_PAD_ENET1_RGMII_TXC__GPIO7_IO11 0x0258 0x04C8 0x0000 0x5 0x0
diff --git a/arch/arm/boot/dts/imx7d-sdb-epdc.dts b/arch/arm/boot/dts/imx7d-sdb-epdc.dts
new file mode 100644
index 000000000000..e263ad446373
--- /dev/null
+++ b/arch/arm/boot/dts/imx7d-sdb-epdc.dts
@@ -0,0 +1,9 @@
+/*
+ * Copyright (C) 2015 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 "imx7d-sdb.dts"
+#include "imx7d-sdb-epdc.dtsi"
diff --git a/arch/arm/boot/dts/imx7d-sdb-epdc.dtsi b/arch/arm/boot/dts/imx7d-sdb-epdc.dtsi
new file mode 100644
index 000000000000..765fdc4bba72
--- /dev/null
+++ b/arch/arm/boot/dts/imx7d-sdb-epdc.dtsi
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2015 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.
+ */
+
+&epdc {
+ status = "okay";
+};
+
+&fec1 {
+ status = "okay";
+};
+
+&fec2 {
+ status = "disabled";
+};
+
+&reg_can2_3v3 {
+ status = "disabled";
+};
+
+&flexcan2 {
+ status = "disabled";
+};
+
+&max17135 {
+ status = "okay";
+};
+
+&sii902x {
+ status = "disabled";
+};
+
+&sim1 {
+ status = "disabled";
+};
+
+&uart5 {
+ status = "disabled";
+};
+
+&i2c3 {
+ elan@10 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_epdc_elan_touch>;
+ compatible = "elan,elan-touch";
+ reg = <0x10>;
+ interrupt-parent = <&gpio6>;
+ interrupts = <12 IRQ_TYPE_EDGE_FALLING>;
+ gpio_elan_cs = <&gpio6 13 0>;
+ gpio_elan_rst = <&gpio6 15 0>;
+ gpio_intr = <&gpio6 12 0>;
+ status = "okay";
+ };
+};
diff --git a/arch/arm/boot/dts/imx7d-sdb-gpmi-weim.dts b/arch/arm/boot/dts/imx7d-sdb-gpmi-weim.dts
new file mode 100644
index 000000000000..346e38cca609
--- /dev/null
+++ b/arch/arm/boot/dts/imx7d-sdb-gpmi-weim.dts
@@ -0,0 +1,9 @@
+/*
+ * Copyright (C) 2015 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 "imx7d-sdb.dts"
+#include "imx7d-sdb-gpmi-weim.dtsi"
diff --git a/arch/arm/boot/dts/imx7d-sdb-gpmi-weim.dtsi b/arch/arm/boot/dts/imx7d-sdb-gpmi-weim.dtsi
new file mode 100644
index 000000000000..3a1208f44242
--- /dev/null
+++ b/arch/arm/boot/dts/imx7d-sdb-gpmi-weim.dtsi
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2015 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.
+ */
+
+&gpmi{
+ status = "okay";
+};
+
+&sai1{
+ status = "disabled";
+};
+
+&usdhc3{
+ status = "disabled";
+};
+
+&uart5{
+ status = "disabled";
+};
diff --git a/arch/arm/boot/dts/imx7d-sdb-m4.dts b/arch/arm/boot/dts/imx7d-sdb-m4.dts
new file mode 100644
index 000000000000..7aa803559ef5
--- /dev/null
+++ b/arch/arm/boot/dts/imx7d-sdb-m4.dts
@@ -0,0 +1,9 @@
+/*
+ * Copyright (C) 2015 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 "imx7d-sdb.dts"
+#include "imx7d-sdb-m4.dtsi"
diff --git a/arch/arm/boot/dts/imx7d-sdb-m4.dtsi b/arch/arm/boot/dts/imx7d-sdb-m4.dtsi
new file mode 100644
index 000000000000..deba9ef75646
--- /dev/null
+++ b/arch/arm/boot/dts/imx7d-sdb-m4.dtsi
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2015 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.
+ */
+
+/ {
+ memory {
+ linux,usable-memory = <0x80000000 0x1ff00000>,
+ <0xa0000000 0x1ff00000>;
+ };
+ m4_tcm: tcml@007f8000 {
+ compatible = "fsl, m4_tcml";
+ reg = <0x007f8000 0x8000>;
+ };
+};
+
+&adc1 {
+ status = "disabled";
+};
+
+&adc2 {
+ status = "disabled";
+};
+
+&flexcan1 {
+ status = "disabled";
+};
+
+&flexcan2 {
+ status = "disabled";
+};
+
+&i2c2 {
+ status = "disabled";
+};
+
+&gpt3 {
+ status = "disabled";
+};
+
+&gpt4 {
+ status = "disabled";
+};
+
+&ocram {
+ reg = <0x00901000 0xf000>;
+};
+
+&reg_can2_3v3 {
+ status = "disabled";
+};
+
+&rpmsg{
+ vdev-nums = <1>;
+ reg = <0xbfff0000 0x10000>;
+ status = "okay";
+};
+
+&uart2 {
+ status = "disabled";
+};
+
+&wdog3{
+ status = "disabled";
+};
diff --git a/arch/arm/boot/dts/imx7d-sdb-mipi-dsi.dts b/arch/arm/boot/dts/imx7d-sdb-mipi-dsi.dts
new file mode 100644
index 000000000000..327d976e4066
--- /dev/null
+++ b/arch/arm/boot/dts/imx7d-sdb-mipi-dsi.dts
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2016 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 "imx7d-sdb.dts"
+
+/ {
+ mipi_dsi_reset: mipi-dsi-reset {
+ compatible = "gpio-reset";
+ reset-gpios = <&gpio6 15 GPIO_ACTIVE_LOW>;
+ reset-delay-us = <1000>;
+ #reset-cells = <0>;
+ };
+};
+
+&lcdif {
+ disp-dev = "mipi_dsi_samsung";
+ disp-videomode = "TRUULY-WVGA-SYNC-LOW";
+};
+
+&mipi_dsi {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_mipi_dsi_reset>;
+ lcd_panel = "TRULY-WVGA-TFT3P5581E";
+ resets = <&mipi_dsi_reset>;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx7d-sdb-qspi.dts b/arch/arm/boot/dts/imx7d-sdb-qspi.dts
new file mode 100644
index 000000000000..a46990554d28
--- /dev/null
+++ b/arch/arm/boot/dts/imx7d-sdb-qspi.dts
@@ -0,0 +1,9 @@
+/*
+ * Copyright (C) 2015 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 "imx7d-sdb.dts"
+#include "imx7d-sdb-qspi.dtsi"
diff --git a/arch/arm/boot/dts/imx7d-sdb-qspi.dtsi b/arch/arm/boot/dts/imx7d-sdb-qspi.dtsi
new file mode 100644
index 000000000000..1ba3e66c974a
--- /dev/null
+++ b/arch/arm/boot/dts/imx7d-sdb-qspi.dtsi
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2015 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.
+ */
+
+/* disable epdc, conflict with qspi */
+&epdc {
+ status = "disabled";
+};
+
+&iomuxc {
+ qspi1 {
+ pinctrl_qspi1_1: qspi1grp_1 {
+ fsl,pins = <
+ MX7D_PAD_EPDC_DATA00__QSPI_A_DATA0 0x51
+ MX7D_PAD_EPDC_DATA01__QSPI_A_DATA1 0x51
+ MX7D_PAD_EPDC_DATA02__QSPI_A_DATA2 0x51
+ MX7D_PAD_EPDC_DATA03__QSPI_A_DATA3 0x51
+ MX7D_PAD_EPDC_DATA05__QSPI_A_SCLK 0x51
+ MX7D_PAD_EPDC_DATA06__QSPI_A_SS0_B 0x51
+ >;
+ };
+ };
+};
+
+&qspi1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_qspi1_1>;
+ status = "okay";
+ ddrsmp=<0>;
+
+ flash0: mx25l51245g@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "macronix,mx25l51245g";
+ spi-max-frequency = <29000000>;
+ /* take off one dummy cycle */
+ spi-nor,ddr-quad-read-dummy = <5>;
+ reg = <0>;
+ };
+};
diff --git a/arch/arm/boot/dts/imx7d-sdb-reva-epdc.dts b/arch/arm/boot/dts/imx7d-sdb-reva-epdc.dts
new file mode 100644
index 000000000000..341a8ad0b696
--- /dev/null
+++ b/arch/arm/boot/dts/imx7d-sdb-reva-epdc.dts
@@ -0,0 +1,9 @@
+/*
+ * Copyright (C) 2015 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 "imx7d-sdb-reva.dts"
+#include "imx7d-sdb-epdc.dtsi"
diff --git a/arch/arm/boot/dts/imx7d-sdb-reva-gpmi-weim.dts b/arch/arm/boot/dts/imx7d-sdb-reva-gpmi-weim.dts
new file mode 100644
index 000000000000..4d221f8d7dd7
--- /dev/null
+++ b/arch/arm/boot/dts/imx7d-sdb-reva-gpmi-weim.dts
@@ -0,0 +1,9 @@
+/*
+ * Copyright (C) 2015 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 "imx7d-sdb-reva.dts"
+#include "imx7d-sdb-gpmi-weim.dtsi"
diff --git a/arch/arm/boot/dts/imx7d-sdb-reva-hdmi-audio.dts b/arch/arm/boot/dts/imx7d-sdb-reva-hdmi-audio.dts
new file mode 100644
index 000000000000..221fdd0750d1
--- /dev/null
+++ b/arch/arm/boot/dts/imx7d-sdb-reva-hdmi-audio.dts
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2015 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 "imx7d-sdb.dts"
+
+/ {
+ sound {
+ status = "disabled";
+ };
+
+ sound-hdmi {
+ status = "okay";
+ };
+};
+
diff --git a/arch/arm/boot/dts/imx7d-sdb-reva-m4.dts b/arch/arm/boot/dts/imx7d-sdb-reva-m4.dts
new file mode 100644
index 000000000000..78148f0d0a04
--- /dev/null
+++ b/arch/arm/boot/dts/imx7d-sdb-reva-m4.dts
@@ -0,0 +1,9 @@
+/*
+ * Copyright (C) 2015 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 "imx7d-sdb-reva.dts"
+#include "imx7d-sdb-m4.dtsi"
diff --git a/arch/arm/boot/dts/imx7d-sdb-reva-qspi.dts b/arch/arm/boot/dts/imx7d-sdb-reva-qspi.dts
new file mode 100644
index 000000000000..7b523cac9575
--- /dev/null
+++ b/arch/arm/boot/dts/imx7d-sdb-reva-qspi.dts
@@ -0,0 +1,9 @@
+/*
+ * Copyright (C) 2015 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 "imx7d-sdb-reva.dts"
+#include "imx7d-sdb-qspi.dtsi"
diff --git a/arch/arm/boot/dts/imx7d-sdb-reva-touch.dts b/arch/arm/boot/dts/imx7d-sdb-reva-touch.dts
new file mode 100644
index 000000000000..d3855e8d7978
--- /dev/null
+++ b/arch/arm/boot/dts/imx7d-sdb-reva-touch.dts
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2015 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 "imx7d-sdb-reva.dts"
+
+&sii902x {
+ status = "disabled";
+};
+
+&ecspi3 {
+ status = "okay";
+
+ tsc2046 {
+ interrupts = <13 0>;
+ pendown-gpio = <&gpio2 13 0>;
+ };
+};
diff --git a/arch/arm/boot/dts/imx7d-sdb-reva-wm8960.dts b/arch/arm/boot/dts/imx7d-sdb-reva-wm8960.dts
new file mode 100644
index 000000000000..d9f38298f154
--- /dev/null
+++ b/arch/arm/boot/dts/imx7d-sdb-reva-wm8960.dts
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2015 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 "imx7d-sdb.dts"
+
+/ {
+ sound {
+ status = "okay";
+ };
+
+ sound-hdmi {
+ status = "disabled";
+ };
+};
+
diff --git a/arch/arm/boot/dts/imx7d-sdb-reva.dts b/arch/arm/boot/dts/imx7d-sdb-reva.dts
new file mode 100644
index 000000000000..73e0b0b66e01
--- /dev/null
+++ b/arch/arm/boot/dts/imx7d-sdb-reva.dts
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2015 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 "imx7d-sdb.dts"
+
+/ {
+ reg_usb_otg2_vbus: regulator-usb-otg2-vbus {
+ gpio = <&gpio4 7 GPIO_ACTIVE_HIGH>;
+ };
+
+ reg_pcie: regulator-pcie {
+ compatible = "regulator-fixed";
+ regulator-name = "MPCIE_3V3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&extended_io 6 GPIO_ACTIVE_HIGH>;
+ regulator-always-on;
+ enable-active-high;
+ };
+
+ sound-hdmi {
+ cpu-dai = <&sai1>;
+ };
+};
+
+&ecspi3 {
+ status = "disabled";
+};
+
+&epdc {
+ pinctrl-0 = <&pinctrl_epdc0>;
+ en-gpios = <&extended_io 5 GPIO_ACTIVE_LOW>;
+};
+
+&fec2 {
+ pinctrl-0 = <&pinctrl_enet2>;
+ pinctrl-assert-gpios = <>;
+};
+
+&i2c4 {
+ ov5647_mipi: ov5647_mipi@36 {
+ pwn-gpios = <&extended_io 7 GPIO_ACTIVE_HIGH>;
+ };
+};
+
+&iomuxc {
+ imx7d-sdb {
+ pinctrl_tsc2046_pendown: tsc2046_pendown {
+ fsl,pins = <
+ MX7D_PAD_EPDC_DATA13__GPIO2_IO13 0x59
+ >;
+ };
+
+ pinctrl_uart5: uart5grp {
+ fsl,pins = <
+ MX7D_PAD_SAI1_TX_BCLK__UART5_DCE_TX 0x79
+ MX7D_PAD_SAI1_RX_DATA__UART5_DCE_RX 0x79
+ MX7D_PAD_SAI1_TX_SYNC__UART5_DCE_CTS 0x79
+ MX7D_PAD_SAI1_TX_DATA__UART5_DCE_RTS 0x79
+ >;
+ };
+
+ pinctrl_uart5dte: uart5dtegrp {
+ fsl,pins = <
+ MX7D_PAD_SAI1_TX_BCLK__UART5_DTE_RX 0x79
+ MX7D_PAD_SAI1_RX_DATA__UART5_DTE_TX 0x79
+ MX7D_PAD_SAI1_TX_SYNC__UART5_DTE_RTS 0x79
+ MX7D_PAD_SAI1_TX_DATA__UART5_DTE_CTS 0x79
+ >;
+ };
+ };
+};
+
+&iomuxc {
+ pinctrl-0 = <&pinctrl_hog_1 &pinctrl_usbotg2_pwr_1>;
+};
+
+&iomuxc_lpsr {
+ pinctrl-0 = <&pinctrl_hog_2>;
+};
+
+&uart5 {
+ fsl,uart-has-rtscts;
+};
diff --git a/arch/arm/boot/dts/imx7d-sdb.dts b/arch/arm/boot/dts/imx7d-sdb.dts
index 255e64ba32e2..8b43113a0c26 100644
--- a/arch/arm/boot/dts/imx7d-sdb.dts
+++ b/arch/arm/boot/dts/imx7d-sdb.dts
@@ -48,10 +48,21 @@
model = "Freescale i.MX7 SabreSD Board";
compatible = "fsl,imx7d-sdb", "fsl,imx7d";
+ chosen {
+ stdout-path = &uart1;
+ };
+
memory {
reg = <0x80000000 0x80000000>;
};
+ modem_reset: modem-reset {
+ compatible = "gpio-reset";
+ reset-gpios = <&gpio4 23 GPIO_ACTIVE_LOW>;
+ reset-delay-us = <1000>;
+ #reset-cells = <0>;
+ };
+
spi4 {
compatible = "spi-gpio";
pinctrl-names = "default";
@@ -69,6 +80,7 @@
#gpio-cells = <2>;
reg = <0>;
registers-number = <1>;
+ registers-default = /bits/ 8 <0x74>; /* Enable PERI_3V3, SENSOR_RST_B and HDMI_RST*/
spi-max-frequency = <100000>;
};
};
@@ -87,18 +99,10 @@
regulator-name = "usb_otg2_vbus";
regulator-min-microvolt = <5000000>;
regulator-max-microvolt = <5000000>;
- gpio = <&gpio4 7 GPIO_ACTIVE_HIGH>;
+ gpio = <&gpio1 7 GPIO_ACTIVE_HIGH>;
enable-active-high;
};
- reg_can2_3v3: regulator-can2-3v3 {
- compatible = "regulator-fixed";
- regulator-name = "can2-3v3";
- regulator-min-microvolt = <3300000>;
- regulator-max-microvolt = <3300000>;
- gpio = <&gpio1 7 GPIO_ACTIVE_LOW>;
- };
-
reg_vref_1v8: regulator-vref-1v8 {
compatible = "regulator-fixed";
regulator-name = "vref-1v8";
@@ -106,47 +110,78 @@
regulator-max-microvolt = <1800000>;
};
- reg_brcm: regulator-brcm {
+ reg_can2_3v3: regulator-can2-3v3 {
compatible = "regulator-fixed";
- gpio = <&gpio4 21 GPIO_ACTIVE_HIGH>;
- enable-active-high;
- regulator-name = "brcm_reg";
+ regulator-name = "can2-3v3";
pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_brcm_reg>;
+ pinctrl-0 = <&pinctrl_flexcan2_reg>;
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
- startup-delay-us = <200000>;
+ gpio = <&gpio2 14 GPIO_ACTIVE_LOW>;
};
- reg_lcd_3v3: regulator-lcd-3v3 {
+ reg_sd1_vmmc: regulator-sd1-vmmc {
compatible = "regulator-fixed";
- regulator-name = "lcd-3v3";
+ regulator-name = "VDD_SD1";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
- gpio = <&extended_io 7 GPIO_ACTIVE_LOW>;
+ gpio = <&gpio5 2 GPIO_ACTIVE_HIGH>;
+ startup-delay-us = <200000>;
+ off-on-delay = <20000>;
+ enable-active-high;
};
- reg_can2_3v3: regulator-can2-3v3 {
- compatible = "regulator-fixed";
- regulator-name = "can2-3v3";
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_flexcan2_reg>;
- regulator-min-microvolt = <3300000>;
- regulator-max-microvolt = <3300000>;
- gpio = <&gpio2 14 GPIO_ACTIVE_LOW>;
+ backlight {
+ compatible = "pwm-backlight";
+ pwms = <&pwm1 0 5000000 0>;
+ brightness-levels = <0 4 8 16 32 64 128 255>;
+ default-brightness-level = <6>;
+ status = "okay";
};
- panel {
- compatible = "innolux,at043tn24";
- pinctrl-0 = <&pinctrl_backlight>;
- enable-gpios = <&gpio1 1 GPIO_ACTIVE_HIGH>;
- power-supply = <&reg_lcd_3v3>;
+ pxp_v4l2_out {
+ compatible = "fsl,imx7d-pxp-v4l2", "fsl,imx6sx-pxp-v4l2", "fsl,imx6sl-pxp-v4l2";
+ status = "okay";
+ };
- port {
- panel_in: endpoint {
- remote-endpoint = <&display_out>;
- };
- };
+ sound {
+ compatible = "fsl,imx7d-evk-wm8960",
+ "fsl,imx-audio-wm8960";
+ model = "wm8960-audio";
+ cpu-dai = <&sai1>;
+ audio-codec = <&codec>;
+ codec-master;
+ /* JD2: hp detect high for headphone*/
+ hp-det = <2 0>;
+ hp-det-gpios = <&gpio2 28 0>;
+ audio-routing =
+ "Headphone Jack", "HP_L",
+ "Headphone Jack", "HP_R",
+ "Ext Spk", "SPK_LP",
+ "Ext Spk", "SPK_LN",
+ "Ext Spk", "SPK_RP",
+ "Ext Spk", "SPK_RN",
+ "LINPUT1", "Main MIC",
+ "Main MIC", "MICB";
+ assigned-clocks = <&clks IMX7D_AUDIO_MCLK_ROOT_SRC>,
+ <&clks IMX7D_AUDIO_MCLK_ROOT_CLK>;
+ assigned-clock-parents = <&clks IMX7D_PLL_AUDIO_POST_DIV>;
+ assigned-clock-rates = <0>, <12288000>;
+ };
+
+ sound-hdmi {
+ compatible = "fsl,imx7d-sdb-sii902x",
+ "fsl,imx-audio-sii902x";
+ model = "sii902x-audio";
+ cpu-dai = <&sai3>;
+ hdmi-controler = <&sii902x>;
+ };
+
+ usdhc2_pwrseq: usdhc2_pwrseq {
+ compatible = "mmc-pwrseq-simple";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_brcm_reg>;
+ reset-gpios = <&gpio4 21 GPIO_ACTIVE_LOW>;
};
};
@@ -165,8 +200,9 @@
};
&ecspi3 {
+ fsl,spi-num-chipselects = <1>;
pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_ecspi3>;
+ pinctrl-0 = <&pinctrl_ecspi3 &pinctrl_ecspi3_cs>;
cs-gpios = <&gpio5 9 GPIO_ACTIVE_HIGH>;
status = "okay";
@@ -189,13 +225,49 @@
};
};
+&clks {
+ assigned-clocks = <&clks IMX7D_PLL_AUDIO_POST_DIV>;
+ assigned-clock-rates = <884736000>;
+};
+
+&csi1 {
+ csi-mux-mipi = <&gpr 0x14 4>;
+ fsl,mipi-mode;
+ status = "okay";
+
+ port {
+ csi_ep: endpoint {
+ remote-endpoint = <&csi_mipi_ep>;
+ };
+ };
+};
+
+&epdc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_epdc0 &pinctrl_enet2_epdc0_en>;
+ V3P3-supply = <&V3P3_reg>;
+ VCOM-supply = <&VCOM_reg>;
+ DISPLAY-supply = <&DISPLAY_reg>;
+ en-gpios = <&gpio1 4 GPIO_ACTIVE_HIGH>;
+ status = "disabled";
+};
+
+&epxp {
+ status = "okay";
+};
+
&fec1 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_enet1>;
- assigned-clocks = <&clks IMX7D_ENET1_TIME_ROOT_SRC>,
- <&clks IMX7D_ENET1_TIME_ROOT_CLK>;
- assigned-clock-parents = <&clks IMX7D_PLL_ENET_MAIN_100M_CLK>;
- assigned-clock-rates = <0>, <100000000>;
+ assigned-clocks = <&clks IMX7D_ENET_PHY_REF_ROOT_SRC>,
+ <&clks IMX7D_ENET_AXI_ROOT_SRC>,
+ <&clks IMX7D_ENET1_TIME_ROOT_SRC>,
+ <&clks IMX7D_ENET1_TIME_ROOT_CLK>,
+ <&clks IMX7D_ENET_AXI_ROOT_CLK>;
+ assigned-clock-parents = <&clks IMX7D_PLL_ENET_MAIN_25M_CLK>,
+ <&clks IMX7D_PLL_ENET_MAIN_250M_CLK>,
+ <&clks IMX7D_PLL_ENET_MAIN_100M_CLK>;
+ assigned-clock-rates = <0>, <0>, <0>, <100000000>, <250000000>;
phy-mode = "rgmii";
phy-handle = <&ethphy0>;
fsl,magic-packet;
@@ -207,10 +279,12 @@
#size-cells = <0>;
ethphy0: ethernet-phy@0 {
+ compatible = "ethernet-phy-ieee802.3-c22";
reg = <0>;
};
ethphy1: ethernet-phy@1 {
+ compatible = "ethernet-phy-ieee802.3-c22";
reg = <1>;
};
};
@@ -218,11 +292,17 @@
&fec2 {
pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_enet2>;
- assigned-clocks = <&clks IMX7D_ENET2_TIME_ROOT_SRC>,
- <&clks IMX7D_ENET2_TIME_ROOT_CLK>;
- assigned-clock-parents = <&clks IMX7D_PLL_ENET_MAIN_100M_CLK>;
- assigned-clock-rates = <0>, <100000000>;
+ pinctrl-0 = <&pinctrl_enet2 &pinctrl_enet2_epdc0_en>;
+ pinctrl-assert-gpios = <&gpio1 4 GPIO_ACTIVE_LOW>;
+ assigned-clocks = <&clks IMX7D_ENET_PHY_REF_ROOT_SRC>,
+ <&clks IMX7D_ENET_AXI_ROOT_SRC>,
+ <&clks IMX7D_ENET2_TIME_ROOT_SRC>,
+ <&clks IMX7D_ENET2_TIME_ROOT_CLK>,
+ <&clks IMX7D_ENET_AXI_ROOT_CLK>;
+ assigned-clock-parents = <&clks IMX7D_PLL_ENET_MAIN_25M_CLK>,
+ <&clks IMX7D_PLL_ENET_MAIN_250M_CLK>,
+ <&clks IMX7D_PLL_ENET_MAIN_100M_CLK>;
+ assigned-clock-rates = <0>, <0>, <0>, <100000000>, <250000000>;
phy-mode = "rgmii";
phy-handle = <&ethphy1>;
fsl,magic-packet;
@@ -236,7 +316,26 @@
status = "okay";
};
+&mipi_csi {
+ clock-frequency = <240000000>;
+ status = "okay";
+ port {
+ mipi_sensor_ep: endpoint1 {
+ remote-endpoint = <&ov5640_mipi_ep>;
+ data-lanes = <2>;
+ csis-hs-settle = <13>;
+ csis-clk-settle = <2>;
+ csis-wclk;
+ };
+
+ csi_mipi_ep: endpoint2 {
+ remote-endpoint = <&csi_ep>;
+ };
+ };
+};
+
&i2c1 {
+ clock-frequency = <100000>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_i2c1>;
status = "okay";
@@ -248,7 +347,7 @@
regulators {
sw1a_reg: sw1a {
regulator-min-microvolt = <700000>;
- regulator-max-microvolt = <1475000>;
+ regulator-max-microvolt = <3300000>;
regulator-boot-on;
regulator-always-on;
regulator-ramp-delay = <6250>;
@@ -333,18 +432,117 @@
};
&i2c2 {
+ clock-frequency = <100000>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_i2c2>;
status = "okay";
+
+ fxas2100x@20 {
+ compatible = "fsl,fxas2100x";
+ reg = <0x20>;
+ };
+
+ fxos8700@1e {
+ compatible = "fsl,fxos8700";
+ reg = <0x1e>;
+ };
+
+ mpl3115@60 {
+ compatible = "fsl,mpl3115";
+ reg = <0x60>;
+ };
};
&i2c3 {
+ clock-frequency = <100000>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_i2c3>;
status = "okay";
+ sii902x: sii902x@39 {
+ compatible = "SiI,sii902x";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_sii902x>;
+ interrupt-parent = <&gpio2>;
+ interrupts = <13 IRQ_TYPE_EDGE_FALLING>;
+ mode_str ="1280x720M@60";
+ bits-per-pixel = <16>;
+ reg = <0x39>;
+ status = "okay";
+ };
+
+ max17135: max17135@48 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_max17135>;
+ compatible = "maxim,max17135";
+ reg = <0x48>;
+ status = "disabled";
+
+ vneg_pwrup = <1>;
+ gvee_pwrup = <2>;
+ vpos_pwrup = <10>;
+ gvdd_pwrup = <12>;
+ gvdd_pwrdn = <1>;
+ vpos_pwrdn = <2>;
+ gvee_pwrdn = <8>;
+ vneg_pwrdn = <10>;
+ gpio_pmic_pwrgood = <&gpio2 31 0>;
+ gpio_pmic_vcom_ctrl = <&gpio4 14 0>;
+ gpio_pmic_wakeup = <&gpio2 23 0>;
+ gpio_pmic_v3p3 = <&gpio2 30 0>;
+ gpio_pmic_intr = <&gpio2 22 0>;
+
+ regulators {
+ DISPLAY_reg: DISPLAY {
+ regulator-name = "DISPLAY";
+ };
+
+ GVDD_reg: GVDD {
+ /* 20v */
+ regulator-name = "GVDD";
+ };
+
+ GVEE_reg: GVEE {
+ /* -22v */
+ regulator-name = "GVEE";
+ };
+
+ HVINN_reg: HVINN {
+ /* -22v */
+ regulator-name = "HVINN";
+ };
+
+ HVINP_reg: HVINP {
+ /* 20v */
+ regulator-name = "HVINP";
+ };
+
+ VCOM_reg: VCOM {
+ regulator-name = "VCOM";
+ /* Real max value: -500000 */
+ regulator-max-microvolt = <4325000>;
+ /* Real min value: -4325000 */
+ regulator-min-microvolt = <500000>;
+ };
+
+ VNEG_reg: VNEG {
+ /* -15v */
+ regulator-name = "VNEG";
+ };
+
+ VPOS_reg: VPOS {
+ /* 15v */
+ regulator-name = "VPOS";
+ };
+
+ V3P3_reg: V3P3 {
+ regulator-name = "V3P3";
+ };
+ };
+ };
};
&i2c4 {
+ clock-frequency = <100000>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_i2c4>;
status = "okay";
@@ -356,30 +554,157 @@
clock-names = "mclk";
wlf,shared-lrclk;
};
+
+ ov5640_mipi: ov5640_mipi@3c {
+ compatible = "ovti,ov5640_mipi";
+ reg = <0x3c>;
+ clocks = <&clks IMX7D_CLK_DUMMY>;
+ clock-names = "csi_mclk";
+ csi_id = <0>;
+ pwn-gpios = <&extended_io 6 GPIO_ACTIVE_HIGH>;
+ AVDD-supply = <&vgen6_reg>;
+ mclk = <24000000>;
+ mclk_source = <0>;
+ port {
+ ov5640_mipi_ep: endpoint {
+ remote-endpoint = <&mipi_sensor_ep>;
+ };
+ };
+ };
};
&lcdif {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_lcdif>;
+ enable-gpio = <&extended_io 7 GPIO_ACTIVE_LOW>;
+ display = <&display0>;
status = "okay";
- port {
- display_out: endpoint {
- remote-endpoint = <&panel_in>;
+ display0: display {
+ bits-per-pixel = <16>;
+ bus-width = <24>;
+
+ display-timings {
+ native-mode = <&timing0>;
+
+ timing0: timing0 {
+ clock-frequency = <9200000>;
+ hactive = <480>;
+ vactive = <272>;
+ hfront-porch = <8>;
+ hback-porch = <4>;
+ hsync-len = <41>;
+ vback-porch = <2>;
+ vfront-porch = <4>;
+ vsync-len = <10>;
+ hsync-active = <0>;
+ vsync-active = <0>;
+ de-active = <1>;
+ pixelclk-active = <0>;
+ };
};
};
};
+&sai1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_sai1>;
+ assigned-clocks = <&clks IMX7D_SAI1_ROOT_SRC>,
+ <&clks IMX7D_SAI1_ROOT_CLK>;
+ assigned-clock-parents = <&clks IMX7D_PLL_AUDIO_POST_DIV>;
+ assigned-clock-rates = <0>, <36864000>;
+ status = "okay";
+};
+
+&sai3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_sai3 &pinctrl_sai3_mclk>;
+ assigned-clocks = <&clks IMX7D_SAI3_ROOT_SRC>,
+ <&clks IMX7D_SAI3_ROOT_CLK>;
+ assigned-clock-parents = <&clks IMX7D_PLL_AUDIO_POST_DIV>;
+ assigned-clock-rates = <0>, <36864000>;
+ status = "okay";
+};
+
+&sdma {
+ status = "okay";
+};
+
+&pwm1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pwm1>;
+ status = "okay";
+};
+
&pcie {
+ pinctrl-names = "default";
reset-gpio = <&extended_io 1 GPIO_ACTIVE_LOW>;
+ disable-gpio = <&extended_io 0 GPIO_ACTIVE_LOW>;
+ status = "okay";
+};
+
+&iomuxc_lpsr {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_hog_2 &pinctrl_usbotg2_pwr_2>;
+
+ imx7d-sdb {
+ pinctrl_hog_2: hoggrp-2 {
+ fsl,pins = <
+ MX7D_PAD_LPSR_GPIO1_IO05__GPIO1_IO5 0x14
+ >;
+ };
+
+ pinctrl_pwm1: pwm1grp {
+ fsl,pins = <
+ MX7D_PAD_LPSR_GPIO1_IO01__PWM1_OUT 0x30
+ >;
+ };
+
+ pinctrl_usbotg2_pwr_2: usbotg2-2 {
+ fsl,pins = <
+ MX7D_PAD_LPSR_GPIO1_IO07__GPIO1_IO7 0x14
+ >;
+ };
+
+ pinctrl_enet2_epdc0_en: enet2_epdc0_grp {
+ fsl,pins = <
+ MX7D_PAD_LPSR_GPIO1_IO04__GPIO1_IO4 0x80000000
+ >;
+ };
+
+ pinctrl_sai3_mclk: sai3grp_mclk {
+ fsl,pins = <
+ MX7D_PAD_LPSR_GPIO1_IO03__SAI3_MCLK 0x1f
+ >;
+ };
+ };
+};
+
+&sim1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_sim1_1>;
+ port = <0>;
+ sven_low_active;
status = "okay";
};
+
&uart1 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_uart1>;
assigned-clocks = <&clks IMX7D_UART1_ROOT_SRC>;
+ assigned-clock-parents = <&clks IMX7D_OSC_24M_CLK>;
+ status = "okay";
+};
+
+&uart5 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart5>;
+ assigned-clocks = <&clks IMX7D_UART5_ROOT_SRC>;
assigned-clock-parents = <&clks IMX7D_PLL_SYS_MAIN_240M_CLK>;
+ /* for DTE mode, add below change */
+ /* fsl,dte-mode; */
+ /* pinctrl-0 = <&pinctrl_uart5dte>; */
status = "okay";
};
@@ -389,11 +714,15 @@
assigned-clocks = <&clks IMX7D_UART6_ROOT_SRC>;
assigned-clock-parents = <&clks IMX7D_PLL_SYS_MAIN_240M_CLK>;
uart-has-rtscts;
+ resets = <&modem_reset>;
status = "okay";
};
&usbotg1 {
vbus-supply = <&reg_usb_otg1_vbus>;
+ srp-disable;
+ hnp-disable;
+ adp-disable;
status = "okay";
};
@@ -404,26 +733,39 @@
};
&usdhc1 {
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_usdhc1>;
+ pinctrl-names = "default", "state_100mhz", "state_200mhz";
+ pinctrl-0 = <&pinctrl_usdhc1>, <&pinctrl_usdhc1_gpio>;
+ pinctrl-1 = <&pinctrl_usdhc1_100mhz>, <&pinctrl_usdhc1_gpio>;
+ pinctrl-2 = <&pinctrl_usdhc1_200mhz>, <&pinctrl_usdhc1_gpio>;
cd-gpios = <&gpio5 0 GPIO_ACTIVE_LOW>;
wp-gpios = <&gpio5 1 GPIO_ACTIVE_HIGH>;
wakeup-source;
+ vmmc-supply = <&reg_sd1_vmmc>;
+ enable-sdio-wakeup;
keep-power-in-suspend;
status = "okay";
};
&usdhc2 {
+ #address-cells = <1>;
+ #size-cells = <0>;
pinctrl-names = "default", "state_100mhz", "state_200mhz";
- pinctrl-0 = <&pinctrl_usdhc2>;
- pinctrl-1 = <&pinctrl_usdhc2_100mhz>;
- pinctrl-2 = <&pinctrl_usdhc2_200mhz>;
+ pinctrl-0 = <&pinctrl_usdhc2 &pinctrl_wifi>;
+ pinctrl-1 = <&pinctrl_usdhc2_100mhz &pinctrl_wifi>;
+ pinctrl-2 = <&pinctrl_usdhc2_200mhz &pinctrl_wifi>;
wakeup-source;
keep-power-in-suspend;
non-removable;
- vmmc-supply = <&reg_brcm>;
+ mmc-pwrseq = <&usdhc2_pwrseq>;
fsl,tuning-step = <2>;
+ pm-ignore-notify;
+ cap-power-off-card;
status = "okay";
+
+ brcmf: bcrmf@1 {
+ reg = <1>;
+ compatible = "brcm,bcm4329-fmac";
+ };
};
&usdhc3 {
@@ -434,7 +776,6 @@
assigned-clocks = <&clks IMX7D_USDHC3_ROOT_CLK>;
assigned-clock-rates = <400000000>;
bus-width = <8>;
- fsl,tuning-step = <2>;
non-removable;
status = "okay";
};
@@ -445,9 +786,16 @@
fsl,ext-reset-output;
};
+&gpmi {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpmi_nand_1>;
+ status = "disabled";
+ nand-on-flash-bbt;
+};
+
&iomuxc {
pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_hog>;
+ pinctrl-0 = <&pinctrl_hog_1>;
imx7d-sdb {
pinctrl_brcm_reg: brcmreggrp {
@@ -456,12 +804,37 @@
>;
};
+ pinctrl_epdc_elan_touch: epdc_elan_touch_grp {
+ fsl,pins = <
+ MX7D_PAD_SAI1_RX_DATA__GPIO6_IO12 0x59
+ MX7D_PAD_SAI1_TX_DATA__GPIO6_IO15 0x1b
+ MX7D_PAD_SAI1_TX_BCLK__GPIO6_IO13 0x80000000
+ >;
+ };
+
+ pinctrl_hog_1: hoggrp-1 {
+ fsl,pins = <
+ MX7D_PAD_EPDC_BDR0__GPIO2_IO28 0x59 /* headphone detect */
+ >;
+ };
+
+ pinctrl_mipi_dsi_reset: mipi_dsi_reset_grp {
+ fsl,pins = <
+ MX7D_PAD_SAI1_TX_DATA__GPIO6_IO15 0x1b
+ >;
+ };
+
pinctrl_ecspi3: ecspi3grp {
fsl,pins = <
MX7D_PAD_SAI2_TX_SYNC__ECSPI3_MISO 0x2
MX7D_PAD_SAI2_TX_BCLK__ECSPI3_MOSI 0x2
MX7D_PAD_SAI2_RX_DATA__ECSPI3_SCLK 0x2
- MX7D_PAD_SD2_CD_B__GPIO5_IO9 0x59
+ >;
+ };
+
+ pinctrl_ecspi3_cs: ecspi3_cs_grp {
+ fsl,pins = <
+ MX7D_PAD_SD2_CD_B__GPIO5_IO9 0x80000000
>;
};
@@ -514,11 +887,56 @@
>;
};
-
- pinctrl_hog: hoggrp {
+ pinctrl_epdc0: epdcgrp0 {
+ fsl,pins = <
+ MX7D_PAD_EPDC_DATA00__EPDC_DATA0 0x2
+ MX7D_PAD_EPDC_DATA01__EPDC_DATA1 0x2
+ MX7D_PAD_EPDC_DATA02__EPDC_DATA2 0x2
+ MX7D_PAD_EPDC_DATA03__EPDC_DATA3 0x2
+ MX7D_PAD_EPDC_DATA04__EPDC_DATA4 0x2
+ MX7D_PAD_EPDC_DATA05__EPDC_DATA5 0x2
+ MX7D_PAD_EPDC_DATA06__EPDC_DATA6 0x2
+ MX7D_PAD_EPDC_DATA07__EPDC_DATA7 0x2
+ MX7D_PAD_EPDC_DATA08__EPDC_DATA8 0x2
+ MX7D_PAD_EPDC_DATA09__EPDC_DATA9 0x2
+ MX7D_PAD_EPDC_DATA10__EPDC_DATA10 0x2
+ MX7D_PAD_EPDC_DATA11__EPDC_DATA11 0x2
+ MX7D_PAD_EPDC_DATA12__EPDC_DATA12 0x2
+ MX7D_PAD_EPDC_DATA13__EPDC_DATA13 0x2
+ MX7D_PAD_EPDC_DATA14__EPDC_DATA14 0x2
+ MX7D_PAD_EPDC_DATA15__EPDC_DATA15 0x2
+ MX7D_PAD_EPDC_SDCLK__EPDC_SDCLK 0x2
+ MX7D_PAD_EPDC_SDLE__EPDC_SDLE 0x2
+ MX7D_PAD_EPDC_SDOE__EPDC_SDOE 0x2
+ MX7D_PAD_EPDC_SDSHR__EPDC_SDSHR 0x2
+ MX7D_PAD_EPDC_SDCE0__EPDC_SDCE0 0x2
+ MX7D_PAD_EPDC_SDCE1__EPDC_SDCE1 0x2
+ MX7D_PAD_EPDC_GDCLK__EPDC_GDCLK 0x2
+ MX7D_PAD_EPDC_GDOE__EPDC_GDOE 0x2
+ MX7D_PAD_EPDC_GDRL__EPDC_GDRL 0x2
+ MX7D_PAD_EPDC_GDSP__EPDC_GDSP 0x2
+ >;
+ };
+
+ pinctrl_gpmi_nand_1: gpmi-nand-1 {
fsl,pins = <
- MX7D_PAD_UART3_CTS_B__GPIO4_IO7 0x14
- MX7D_PAD_ECSPI2_SS0__GPIO4_IO23 0x34 /* bt reg on */
+ MX7D_PAD_SD3_CLK__NAND_CLE 0x71
+ MX7D_PAD_SD3_CMD__NAND_ALE 0x71
+ MX7D_PAD_SAI1_MCLK__NAND_WP_B 0x71
+ MX7D_PAD_SAI1_TX_BCLK__NAND_CE0_B 0x71
+ MX7D_PAD_SAI1_RX_DATA__NAND_CE1_B 0x71
+ MX7D_PAD_SAI1_TX_DATA__NAND_READY_B 0x74
+ MX7D_PAD_SD3_STROBE__NAND_RE_B 0x71
+ MX7D_PAD_SD3_RESET_B__NAND_WE_B 0x71
+ MX7D_PAD_SD3_DATA0__NAND_DATA00 0x71
+ MX7D_PAD_SD3_DATA1__NAND_DATA01 0x71
+ MX7D_PAD_SD3_DATA2__NAND_DATA02 0x71
+ MX7D_PAD_SD3_DATA3__NAND_DATA03 0x71
+ MX7D_PAD_SD3_DATA4__NAND_DATA04 0x71
+ MX7D_PAD_SD3_DATA5__NAND_DATA05 0x71
+ MX7D_PAD_SD3_DATA6__NAND_DATA06 0x71
+ MX7D_PAD_SD3_DATA7__NAND_DATA07 0x71
+
>;
};
@@ -584,6 +1002,43 @@
>;
};
+ pinctrl_max17135: max17135grp-1 {
+ fsl,pins = <
+ MX7D_PAD_EPDC_PWR_STAT__GPIO2_IO31 0x80000000 /* pwrgood */
+ MX7D_PAD_I2C4_SCL__GPIO4_IO14 0x80000000 /* vcom_ctrl */
+ MX7D_PAD_EPDC_SDCE3__GPIO2_IO23 0x80000000 /* wakeup */
+ MX7D_PAD_EPDC_PWR_COM__GPIO2_IO30 0x80000000 /* v3p3 */
+ MX7D_PAD_EPDC_SDCE2__GPIO2_IO22 0x80000000 /* pwr int */
+ >;
+ };
+
+ pinctrl_sai1: sai1grp {
+ fsl,pins = <
+ MX7D_PAD_SAI1_MCLK__SAI1_MCLK 0x1f
+ MX7D_PAD_ENET1_RX_CLK__SAI1_TX_BCLK 0x1f
+ MX7D_PAD_ENET1_CRS__SAI1_TX_SYNC 0x1f
+ MX7D_PAD_ENET1_COL__SAI1_TX_DATA0 0x30
+ MX7D_PAD_ENET1_TX_CLK__SAI1_RX_DATA0 0x1f
+ >;
+ };
+
+ pinctrl_sai2: sai2grp {
+ fsl,pins = <
+ MX7D_PAD_SAI2_TX_BCLK__SAI2_TX_BCLK 0x1f
+ MX7D_PAD_SAI2_TX_SYNC__SAI2_TX_SYNC 0x1f
+ MX7D_PAD_SAI2_TX_DATA__SAI2_TX_DATA0 0x30
+ MX7D_PAD_SAI2_RX_DATA__SAI2_RX_DATA0 0x1f
+ >;
+ };
+
+ pinctrl_sai3: sai3grp {
+ fsl,pins = <
+ MX7D_PAD_UART3_TX_DATA__SAI3_TX_BCLK 0x1f
+ MX7D_PAD_UART3_CTS_B__SAI3_TX_SYNC 0x1f
+ MX7D_PAD_UART3_RTS_B__SAI3_TX_DATA0 0x30
+ >;
+ };
+
pinctrl_spi4: spi4grp {
fsl,pins = <
MX7D_PAD_GPIO1_IO09__GPIO1_IO9 0x59
@@ -598,6 +1053,23 @@
>;
};
+
+ pinctrl_sii902x: hdmigrp-1 {
+ fsl,pins = <
+ MX7D_PAD_EPDC_DATA13__GPIO2_IO13 0x59
+ >;
+ };
+
+ pinctrl_sim1_1: sim1grp-1 {
+ fsl,pins = <
+ MX7D_PAD_EPDC_DATA10__SIM1_PORT1_RST_B 0x77
+ MX7D_PAD_EPDC_DATA12__SIM1_PORT1_PD 0x77
+ MX7D_PAD_EPDC_DATA11__SIM1_PORT1_SVEN 0x77
+ MX7D_PAD_EPDC_DATA09__SIM1_PORT1_CLK 0x73
+ MX7D_PAD_EPDC_DATA08__SIM1_PORT1_TRXD 0x73
+ >;
+ };
+
pinctrl_uart1: uart1grp {
fsl,pins = <
MX7D_PAD_UART1_TX_DATA__UART1_DCE_TX 0x79
@@ -609,8 +1081,13 @@
fsl,pins = <
MX7D_PAD_SAI1_TX_BCLK__UART5_DCE_TX 0x79
MX7D_PAD_SAI1_RX_DATA__UART5_DCE_RX 0x79
- MX7D_PAD_SAI1_TX_SYNC__UART5_DCE_CTS 0x79
- MX7D_PAD_SAI1_TX_DATA__UART5_DCE_RTS 0x79
+ >;
+ };
+
+ pinctrl_uart5dte: uart5dtegrp {
+ fsl,pins = <
+ MX7D_PAD_SAI1_TX_BCLK__UART5_DTE_RX 0x79
+ MX7D_PAD_SAI1_RX_DATA__UART5_DTE_TX 0x79
>;
};
@@ -620,6 +1097,22 @@
MX7D_PAD_ECSPI1_SCLK__UART6_DCE_RX 0x79
MX7D_PAD_ECSPI1_SS0__UART6_DCE_CTS 0x79
MX7D_PAD_ECSPI1_MISO__UART6_DCE_RTS 0x79
+ MX7D_PAD_ECSPI2_SS0__GPIO4_IO23 0x19 /* BT_REG_ON */
+ >;
+ };
+
+ pinctrl_usdhc1_gpio: usdhc1_gpiogrp {
+ fsl,pins = <
+ MX7D_PAD_SD1_CD_B__GPIO5_IO0 0x59 /* CD */
+ MX7D_PAD_SD1_WP__GPIO5_IO1 0x59 /* WP */
+ MX7D_PAD_SD1_RESET_B__GPIO5_IO2 0x59 /* vmmc */
+ MX7D_PAD_GPIO1_IO08__SD1_VSELECT 0x59 /* VSELECT */
+ >;
+ };
+
+ pinctrl_usbotg2_pwr_1: usbotg2-1 {
+ fsl,pins = <
+ MX7D_PAD_UART3_CTS_B__GPIO4_IO7 0x14
>;
};
@@ -631,9 +1124,29 @@
MX7D_PAD_SD1_DATA1__SD1_DATA1 0x59
MX7D_PAD_SD1_DATA2__SD1_DATA2 0x59
MX7D_PAD_SD1_DATA3__SD1_DATA3 0x59
- MX7D_PAD_SD1_CD_B__GPIO5_IO0 0x59 /* CD */
- MX7D_PAD_SD1_WP__GPIO5_IO1 0x59 /* WP */
- MX7D_PAD_SD1_RESET_B__GPIO5_IO2 0x59 /* vmmc */
+
+ >;
+ };
+
+ pinctrl_usdhc1_100mhz: usdhc1grp_100mhz {
+ fsl,pins = <
+ MX7D_PAD_SD1_CMD__SD1_CMD 0x5a
+ MX7D_PAD_SD1_CLK__SD1_CLK 0x1a
+ MX7D_PAD_SD1_DATA0__SD1_DATA0 0x5a
+ MX7D_PAD_SD1_DATA1__SD1_DATA1 0x5a
+ MX7D_PAD_SD1_DATA2__SD1_DATA2 0x5a
+ MX7D_PAD_SD1_DATA3__SD1_DATA3 0x5a
+ >;
+ };
+
+ pinctrl_usdhc1_200mhz: usdhc1grp_200mhz {
+ fsl,pins = <
+ MX7D_PAD_SD1_CMD__SD1_CMD 0x5b
+ MX7D_PAD_SD1_CLK__SD1_CLK 0x1b
+ MX7D_PAD_SD1_DATA0__SD1_DATA0 0x5b
+ MX7D_PAD_SD1_DATA1__SD1_DATA1 0x5b
+ MX7D_PAD_SD1_DATA2__SD1_DATA2 0x5b
+ MX7D_PAD_SD1_DATA3__SD1_DATA3 0x5b
>;
};
@@ -718,6 +1231,12 @@
MX7D_PAD_SD3_STROBE__SD3_STROBE 0x1b
>;
};
+
+ pinctrl_wifi: wifigrp {
+ fsl,pins = <
+ MX7D_PAD_ECSPI2_SCLK__GPIO4_IO20 0x19 /* WL_HOST_WAKE */
+ >;
+ };
};
};
diff --git a/arch/arm/boot/dts/imx7d.dtsi b/arch/arm/boot/dts/imx7d.dtsi
index 119b63ffb0fe..034629cab258 100644
--- a/arch/arm/boot/dts/imx7d.dtsi
+++ b/arch/arm/boot/dts/imx7d.dtsi
@@ -1,6 +1,7 @@
/*
- * Copyright 2015 Freescale Semiconductor, Inc.
+ * Copyright 2015-2016 Freescale Semiconductor, Inc.
* Copyright 2016 Toradex AG
+ * Copyright 2017-2018 NXP
*
* 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
@@ -49,6 +50,7 @@
cpu0: cpu@0 {
operating-points = <
/* KHz uV */
+ 1200000 1225000
996000 1075000
792000 975000
>;
@@ -63,6 +65,20 @@
};
};
+ reserved-memory {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ /* global autoconfigured region for contiguous allocations */
+ linux,cma {
+ compatible = "shared-dma-pool";
+ reusable;
+ size = <0x14000000>;
+ linux,cma-default;
+ };
+ };
+
soc {
etm@3007d000 {
compatible = "arm,coresight-etm3x", "arm,primecell";
@@ -84,6 +100,217 @@
};
};
};
+
+ busfreq {
+ compatible = "fsl,imx_busfreq";
+ fsl,max_ddr_freq = <533000000>;
+ clocks = <&clks IMX7D_OSC_24M_CLK>, <&clks IMX7D_MAIN_AXI_ROOT_SRC>,
+ <&clks IMX7D_AHB_CHANNEL_ROOT_SRC>, <&clks IMX7D_PLL_SYS_PFD0_392M_CLK>,
+ <&clks IMX7D_DRAM_ROOT_SRC>, <&clks IMX7D_DRAM_ALT_ROOT_SRC>,
+ <&clks IMX7D_PLL_DRAM_MAIN_CLK>, <&clks IMX7D_DRAM_ALT_ROOT_CLK>,
+ <&clks IMX7D_PLL_SYS_PFD2_270M_CLK>, <&clks IMX7D_PLL_SYS_PFD1_332M_CLK>,
+ <&clks IMX7D_AHB_CHANNEL_ROOT_CLK>, <&clks IMX7D_MAIN_AXI_ROOT_DIV>;
+ clock-names = "osc", "axi_sel", "ahb_sel", "pfd0_392m", "dram_root", "dram_alt_sel",
+ "pll_dram", "dram_alt_root", "pfd2_270m", "pfd1_332m", "ahb", "axi";
+ interrupts = <0 112 0x04>, <0 113 0x04>;
+ interrupt-names = "irq_busfreq_0", "irq_busfreq_1";
+ };
+
+ caam_sm: caam-sm@00100000 {
+ compatible = "fsl,imx7d-caam-sm", "fsl,imx6q-caam-sm";
+ reg = <0x00100000 0x8000>;
+ };
+
+ irq_sec_vio: caam_secvio {
+ compatible = "fsl,imx7d-caam-secvio", "fsl,imx6q-caam-secvio";
+ interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
+ jtag-tamper = "disabled";
+ watchdog-tamper = "enabled";
+ internal-boot-tamper = "enabled";
+ external-pin-tamper = "disabled";
+ };
+
+ pmu {
+ compatible = "arm,cortex-a7-pmu";
+ interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
+
+ ocrams_ddr: sram@00900000 {
+ compatible = "fsl,ddr-lpm-sram";
+ reg = <0x00900000 0x1000>;
+ clocks = <&clks IMX7D_OCRAM_CLK>;
+ };
+
+ ocram: sram@901000 {
+ compatible = "mmio-sram";
+ reg = <0x00901000 0x1f000>;
+ clocks = <&clks IMX7D_OCRAM_CLK>;
+ };
+
+ ocrams: sram@00180000 {
+ compatible = "fsl,lpm-sram";
+ reg = <0x00180000 0x8000>;
+ clocks = <&clks IMX7D_OCRAM_S_CLK>;
+ status = "disabled";
+ };
+
+ ocrams_mf: sram-mf@00900000 {
+ compatible = "fsl,mega-fast-sram";
+ reg = <0x00900000 0x20000>;
+ clocks = <&clks IMX7D_OCRAM_CLK>;
+ };
+
+ ocram_optee {
+ compatible = "fsl,optee-lpm-sram";
+ reg = <0x00180000 0x8000>;
+ overw_reg = <&ocrams_ddr 0x00904000 0x1000>,
+ <&ocram 0x00905000 0x1b000>,
+ <&ocrams 0x00900000 0x4000>;
+ overw_clock = <&ocrams &clks IMX7D_OCRAM_CLK>;
+ };
+ };
+};
+
+&aips1 {
+ kpp: kpp@30320000 {
+ compatible = "fsl,imx7d-kpp", "fsl,imx21-kpp";
+ reg = <0x30320000 0x10000>;
+ interrupts = <GIC_SPI 80 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX7D_CLK_DUMMY>;
+ status = "disabled";
+ };
+
+ mqs: mqs {
+ compatible = "fsl,imx6sx-mqs";
+ gpr = <&gpr>;
+ status = "disabled";
+ };
+
+ ocotp: ocotp-ctrl@30350000 {
+ compatible = "fsl,imx7d-ocotp", "syscon";
+ reg = <0x30350000 0x10000>;
+ clocks = <&clks IMX7D_OCOTP_CLK>;
+ status = "okay";
+ };
+
+ tempmon: tempmon {
+ compatible = "fsl,imx7d-tempmon";
+ interrupts = <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>;
+ fsl,tempmon =<&anatop>;
+ fsl,tempmon-data = <&ocotp>;
+ clocks = <&clks IMX7D_PLL_SYS_MAIN_CLK>;
+ };
+
+ caam_snvs: caam-snvs@30370000 {
+ compatible = "fsl,imx6q-caam-snvs";
+ reg = <0x30370000 0x10000>;
+ };
+ iomuxc_lpsr_gpr: lpsr-gpr@30270000 {
+ compatible = "fsl,imx7d-lpsr-gpr";
+ reg = <0x30270000 0x10000>;
+ };
+};
+
+&aips2 {
+ flextimer1: flextimer@30640000 {
+ compatible = "fsl,imx7d-flextimer";
+ reg = <0x30640000 0x10000>;
+ interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
+
+ flextimer2: flextimer@30650000 {
+ compatible = "fsl,imx7d-flextimer";
+ reg = <0x30650000 0x10000>;
+ interrupts = <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
+
+ system_counter_rd: system-counter-rd@306a0000 {
+ compatible = "fsl,imx7d-system-counter-rd";
+ reg = <0x306a0000 0x10000>;
+ status = "disabled";
+ };
+
+ system_counter_cmp: system-counter-cmp@306b0000 {
+ compatible = "fsl,imx7d-system-counter-cmp";
+ reg = <0x306b0000 0x10000>;
+ status = "disabled";
+ };
+
+ system_counter_ctrl: system-counter-ctrl@306c0000 {
+ compatible = "fsl,imx7d-system-counter-ctrl";
+ reg = <0x306c0000 0x10000>;
+ interrupts = <GIC_SPI 47 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
+
+ epdc: epdc@306f0000 {
+ compatible = "fsl,imx7d-epdc";
+ interrupts = <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>;
+ reg = <0x306f0000 0x10000>;
+ clocks = <&clks IMX7D_CLK_DUMMY>, <&clks IMX7D_EPDC_PIXEL_ROOT_CLK>;
+ clock-names = "epdc_axi", "epdc_pix";
+ epdc-ram = <&gpr 0x4 30>;
+ qos = <&qosc>;
+ status = "disabled";
+ };
+
+ epxp: epxp@30700000 {
+ compatible = "fsl,imx7d-pxp-dma";
+ interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>;
+ reg = <0x30700000 0x10000>;
+ clocks = <&clks IMX7D_PXP_IPG_CLK>, <&clks IMX7D_PXP_AXI_CLK>;
+ clock-names = "pxp_ipg", "pxp_axi";
+ status = "disabled";
+ };
+
+ csi1: csi@30710000 {
+ compatible = "fsl,imx7d-csi", "fsl,imx6s-csi";
+ reg = <0x30710000 0x10000>;
+ interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX7D_CLK_DUMMY>,
+ <&clks IMX7D_CSI_MCLK_ROOT_CLK>,
+ <&clks IMX7D_CLK_DUMMY>;
+ clock-names = "disp-axi", "csi_mclk", "disp_dcic";
+ status = "disabled";
+ };
+
+ mipi_csi: mipi-csi@30750000 {
+ compatible = "fsl,imx7d-mipi-csi";
+ reg = <0x30750000 0x10000>;
+ interrupts = <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX7D_MIPI_CSI_ROOT_CLK>,
+ <&clks IMX7D_MIPI_DPHY_ROOT_CLK>;
+ clock-names = "mipi_clk", "phy_clk";
+ mipi-phy-supply = <&reg_1p0d>;
+ csis-phy-reset = <&src 0x28 2>;
+ bus-width = <4>;
+ status = "disabled";
+ };
+
+ mipi_dsi: mipi-dsi@30760000 {
+ compatible = "fsl,imx7d-mipi-dsi";
+ reg = <0x30760000 0x10000>;
+ interrupts = <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX7D_MIPI_DSI_ROOT_CLK>,
+ <&clks IMX7D_MIPI_DPHY_ROOT_CLK>;
+ clock-names = "mipi_cfg_clk", "mipi_pllref_clk";
+ mipi-phy-supply = <&reg_1p0d>;
+ status = "disabled";
+ };
+
+ ddrc: ddrc@307a0000 {
+ compatible = "fsl,imx7-ddrc";
+ reg = <0x307a0000 0x10000>;
+ };
+
+ qosc: qosc@307f0000 {
+ compatible = "fsl,imx7d-qosc", "syscon";
+ reg = <0x307f0000 0x4000>;
};
};
@@ -96,6 +323,9 @@
fsl,usbphy = <&usbphynop2>;
fsl,usbmisc = <&usbmisc2 0>;
phy-clkgate-delay-us = <400>;
+ ahb-burst-config = <0x0>;
+ tx-burst-size-dword = <0x10>;
+ rx-burst-size-dword = <0x10>;
status = "disabled";
};
@@ -117,11 +347,11 @@
interrupts = <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&clks IMX7D_ENET_AXI_ROOT_CLK>,
+ clocks = <&clks IMX7D_ENET2_IPG_ROOT_CLK>,
<&clks IMX7D_ENET_AXI_ROOT_CLK>,
<&clks IMX7D_ENET2_TIME_ROOT_CLK>,
<&clks IMX7D_PLL_ENET_MAIN_125M_CLK>,
- <&clks IMX7D_ENET_PHY_REF_ROOT_CLK>;
+ <&clks IMX7D_ENET_PHY_REF_ROOT_DIV>;
clock-names = "ipg", "ahb", "ptp",
"enet_clk_ref", "enet_out";
fsl,num-tx-queues=<3>;
@@ -132,15 +362,17 @@
pcie: pcie@0x33800000 {
compatible = "fsl,imx7d-pcie", "snps,dw-pcie";
reg = <0x33800000 0x4000>,
+ <0x306d0000 0x10000>,
<0x4ff00000 0x80000>;
- reg-names = "dbi", "config";
+ reg-names = "dbi", "phy", "config";
#address-cells = <3>;
#size-cells = <2>;
device_type = "pci";
ranges = <0x81000000 0 0 0x4ff80000 0 0x00010000 /* downstream I/O */
0x82000000 0 0x40000000 0x40000000 0 0x0ff00000>; /* non-prefetchable memory */
num-lanes = <1>;
- interrupts = <GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 127 IRQ_TYPE_LEVEL_HIGH>; /* eDMA */
interrupt-names = "msi";
#interrupt-cells = <1>;
interrupt-map-mask = <0 0 0 0x7>;
@@ -168,6 +400,110 @@
reset-names = "pciephy", "apps";
status = "disabled";
};
+
+ crypto: caam@30900000 {
+ compatible = "fsl,imx7d-caam", "fsl,sec-v4.0";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x30900000 0x40000>;
+ ranges = <0 0x30900000 0x40000>;
+ interrupts = <GIC_SPI 91 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX7D_CAAM_CLK>,
+ <&clks IMX7D_AHB_CHANNEL_ROOT_CLK>;
+ clock-names = "ipg", "aclk";
+
+ sec_ctrl: ctrl@0 {
+ /* CAAM Page 0 only accessible */
+ /* by secure world */
+ compatible = "fsl,sec-v4.0-ctrl";
+ reg = <0x30900000 0x1000>;
+ secure-status = "okay";
+ status = "disabled";
+ };
+
+ sec_jr0: jr0@1000 {
+ compatible = "fsl,sec-v4.0-job-ring";
+ reg = <0x1000 0x1000>;
+ interrupts = <GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ sec_jr1: jr1@2000 {
+ compatible = "fsl,sec-v4.0-job-ring";
+ reg = <0x2000 0x1000>;
+ interrupts = <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ sec_jr2: jr2@3000 {
+ compatible = "fsl,sec-v4.0-job-ring";
+ reg = <0x3000 0x1000>;
+ interrupts = <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>;
+ };
+ };
+
+ mu: mu@30aa0000 {
+ compatible = "fsl,imx7d-mu", "fsl,imx6sx-mu";
+ reg = <0x30aa0000 0x10000>;
+ interrupts = <GIC_SPI 88 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX7D_MU_ROOT_CLK>;
+ clock-names = "mu";
+ status = "okay";
+ };
+
+ rpmsg: rpmsg{
+ compatible = "fsl,imx7d-rpmsg";
+ status = "disabled";
+ };
+
+ sema4: sema4@30ac0000 {
+ compatible = "fsl,imx7d-sema4";
+ reg = <0x30ac0000 0x10000>;
+ interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX7D_SEMA4_HS_ROOT_CLK>;
+ clock-names = "sema4";
+ status = "okay";
+ };
+
+ sim1: sim@30b90000 {
+ compatible = "fsl,imx7d-sim";
+ reg = <0x30b90000 0x10000>;
+ interrupts = <GIC_SPI 90 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX7D_SIM1_ROOT_CLK>;
+ clock-names = "sim";
+ status = "disabled";
+ };
+
+ sim2: sim@30ba0000 {
+ compatible = "fsl,imx7d-sim";
+ reg = <0x30ba0000 0x10000>;
+ interrupts = <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
+
+ qspi1: qspi@30bb0000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx7d-qspi";
+ reg = <0x30bb0000 0x10000>, <0x60000000 0x10000000>;
+ reg-names = "QuadSPI", "QuadSPI-memory";
+ interrupts = <GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX7D_QSPI_ROOT_CLK>,
+ <&clks IMX7D_QSPI_ROOT_CLK>;
+ clock-names = "qspi_en", "qspi";
+ status = "disabled";
+ };
+
+ weim: weim@30bc0000 {
+ compatible = "fsl,imx7d-weim", "fsl,imx6sx-weim", "fsl,imx6q-weim";
+ reg = <0x30bc0000 0x10000>;
+ interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX7D_EIM_ROOT_CLK>;
+ status = "disabled";
+ };
+
+};
+
+&usbphynop3 {
+ vcc-supply = <&reg_1p2>;
};
&ca_funnel_ports {
diff --git a/arch/arm/boot/dts/imx7s.dtsi b/arch/arm/boot/dts/imx7s.dtsi
index 836550f2297a..11ed757b5d19 100644
--- a/arch/arm/boot/dts/imx7s.dtsi
+++ b/arch/arm/boot/dts/imx7s.dtsi
@@ -311,11 +311,13 @@
timer {
compatible = "arm,armv7-timer";
+ arm,cpu-registers-not-fw-configured;
interrupt-parent = <&intc>;
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 = <8000000>;
};
aips1: aips-bus@30000000 {
@@ -451,8 +453,9 @@
reg = <0x302d0000 0x10000>;
interrupts = <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clks IMX7D_GPT1_ROOT_CLK>,
- <&clks IMX7D_GPT1_ROOT_CLK>;
- clock-names = "ipg", "per";
+ <&clks IMX7D_GPT1_ROOT_CLK>,
+ <&clks IMX7D_GPT_3M_CLK>;
+ clock-names = "ipg", "per", "osc_per";
};
gpt2: gpt@302e0000 {
@@ -522,6 +525,21 @@
anatop-max-voltage = <1200000>;
anatop-enable-bit = <0>;
};
+
+ reg_1p2: regulator-vdd1p2@220 {
+ compatible = "fsl,anatop-regulator";
+ regulator-name = "vdd1p2";
+ regulator-min-microvolt = <1100000>;
+ regulator-max-microvolt = <1300000>;
+ anatop-reg-offset = <0x220>;
+ anatop-vol-bit-shift = <8>;
+ anatop-vol-bit-width = <5>;
+ anatop-min-bit-val = <0x14>;
+ anatop-min-voltage = <1100000>;
+ anatop-max-voltage = <1300000>;
+ anatop-enable-bit = <31>;
+ };
+
};
snvs: snvs@30370000 {
@@ -540,8 +558,8 @@
compatible = "syscon-poweroff";
regmap = <&snvs>;
offset = <0x38>;
- value = <0x60>;
- mask = <0x60>;
+ value = <0x61>;
+ mask = <0x61>;
};
snvs_pwrkey: snvs-powerkey {
@@ -564,7 +582,7 @@
};
src: src@30390000 {
- compatible = "fsl,imx7d-src", "syscon";
+ compatible = "fsl,imx7d-src", "fsl,imx51-src", "syscon";
reg = <0x30390000 0x10000>;
interrupts = <GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH>;
#reset-cells = <1>;
@@ -578,6 +596,10 @@
#interrupt-cells = <3>;
interrupt-parent = <&intc>;
#power-domain-cells = <1>;
+ fsl,mf-mix-wakeup-irq = <0x54010000 0xc00 0x0 0x1040640>;
+ mipi-phy-supply = <&reg_1p0d>;
+ pcie-phy-supply = <&reg_1p0d>;
+ vcc-supply = <&reg_1p2>;
pgc {
#address-cells = <1>;
@@ -626,6 +648,8 @@
clocks = <&clks IMX7D_ECSPI4_ROOT_CLK>,
<&clks IMX7D_ECSPI4_ROOT_CLK>;
clock-names = "ipg", "per";
+ dmas = <&sdma 6 7 1>, <&sdma 7 7 2>;
+ dma-names = "rx", "tx";
status = "disabled";
};
@@ -678,8 +702,9 @@
reg = <0x30730000 0x10000>;
interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clks IMX7D_LCDIF_PIXEL_ROOT_CLK>,
- <&clks IMX7D_LCDIF_PIXEL_ROOT_CLK>;
- clock-names = "pix", "axi";
+ <&clks IMX7D_CLK_DUMMY>,
+ <&clks IMX7D_CLK_DUMMY>;
+ clock-names = "pix", "axi", "disp_axi";
status = "disabled";
};
};
@@ -700,6 +725,8 @@
clocks = <&clks IMX7D_ECSPI1_ROOT_CLK>,
<&clks IMX7D_ECSPI1_ROOT_CLK>;
clock-names = "ipg", "per";
+ dmas = <&sdma 0 7 1>, <&sdma 1 7 2>;
+ dma-names = "rx", "tx";
status = "disabled";
};
@@ -712,6 +739,8 @@
clocks = <&clks IMX7D_ECSPI2_ROOT_CLK>,
<&clks IMX7D_ECSPI2_ROOT_CLK>;
clock-names = "ipg", "per";
+ dmas = <&sdma 2 7 1>, <&sdma 3 7 2>;
+ dma-names = "rx", "tx";
status = "disabled";
};
@@ -724,6 +753,8 @@
clocks = <&clks IMX7D_ECSPI3_ROOT_CLK>,
<&clks IMX7D_ECSPI3_ROOT_CLK>;
clock-names = "ipg", "per";
+ dmas = <&sdma 4 7 1>, <&sdma 5 7 2>;
+ dma-names = "rx", "tx";
status = "disabled";
};
@@ -746,6 +777,8 @@
clocks = <&clks IMX7D_UART2_ROOT_CLK>,
<&clks IMX7D_UART2_ROOT_CLK>;
clock-names = "ipg", "per";
+ dmas = <&sdma 24 4 0>, <&sdma 25 4 0>;
+ dma-names = "rx", "tx";
status = "disabled";
};
@@ -757,6 +790,8 @@
clocks = <&clks IMX7D_UART3_ROOT_CLK>,
<&clks IMX7D_UART3_ROOT_CLK>;
clock-names = "ipg", "per";
+ dmas = <&sdma 26 4 0>, <&sdma 27 4 0>;
+ dma-names = "rx", "tx";
status = "disabled";
};
@@ -766,10 +801,11 @@
reg = <0x308a0000 0x10000>;
interrupts = <GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clks IMX7D_SAI1_IPG_CLK>,
+ <&clks IMX7D_CLK_DUMMY>,
<&clks IMX7D_SAI1_ROOT_CLK>,
<&clks IMX7D_CLK_DUMMY>,
<&clks IMX7D_CLK_DUMMY>;
- clock-names = "bus", "mclk1", "mclk2", "mclk3";
+ clock-names = "bus", "mclk0", "mclk1", "mclk2", "mclk3";
dma-names = "rx", "tx";
dmas = <&sdma 8 24 0>, <&sdma 9 24 0>;
status = "disabled";
@@ -781,10 +817,11 @@
reg = <0x308b0000 0x10000>;
interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clks IMX7D_SAI2_IPG_CLK>,
+ <&clks IMX7D_CLK_DUMMY>,
<&clks IMX7D_SAI2_ROOT_CLK>,
<&clks IMX7D_CLK_DUMMY>,
<&clks IMX7D_CLK_DUMMY>;
- clock-names = "bus", "mclk1", "mclk2", "mclk3";
+ clock-names = "bus", "mclk0", "mclk1", "mclk2", "mclk3";
dma-names = "rx", "tx";
dmas = <&sdma 10 24 0>, <&sdma 11 24 0>;
status = "disabled";
@@ -796,10 +833,11 @@
reg = <0x308c0000 0x10000>;
interrupts = <GIC_SPI 50 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clks IMX7D_SAI3_IPG_CLK>,
+ <&clks IMX7D_CLK_DUMMY>,
<&clks IMX7D_SAI3_ROOT_CLK>,
<&clks IMX7D_CLK_DUMMY>,
<&clks IMX7D_CLK_DUMMY>;
- clock-names = "bus", "mclk1", "mclk2", "mclk3";
+ clock-names = "bus", "mclk0", "mclk1", "mclk2", "mclk3";
dma-names = "rx", "tx";
dmas = <&sdma 12 24 0>, <&sdma 13 24 0>;
status = "disabled";
@@ -812,6 +850,7 @@
clocks = <&clks IMX7D_CLK_DUMMY>,
<&clks IMX7D_CAN1_ROOT_CLK>;
clock-names = "ipg", "per";
+ stop-mode = <&gpr 0x10 1 0x10 17>;
status = "disabled";
};
@@ -822,6 +861,7 @@
clocks = <&clks IMX7D_CLK_DUMMY>,
<&clks IMX7D_CAN2_ROOT_CLK>;
clock-names = "ipg", "per";
+ stop-mode = <&gpr 0x10 2 0x10 18>;
status = "disabled";
};
@@ -873,6 +913,8 @@
clocks = <&clks IMX7D_UART4_ROOT_CLK>,
<&clks IMX7D_UART4_ROOT_CLK>;
clock-names = "ipg", "per";
+ dmas = <&sdma 28 4 0>, <&sdma 29 4 0>;
+ dma-names = "rx", "tx";
status = "disabled";
};
@@ -884,6 +926,8 @@
clocks = <&clks IMX7D_UART5_ROOT_CLK>,
<&clks IMX7D_UART5_ROOT_CLK>;
clock-names = "ipg", "per";
+ dmas = <&sdma 30 4 0>, <&sdma 31 4 0>;
+ dma-names = "rx", "tx";
status = "disabled";
};
@@ -895,6 +939,8 @@
clocks = <&clks IMX7D_UART6_ROOT_CLK>,
<&clks IMX7D_UART6_ROOT_CLK>;
clock-names = "ipg", "per";
+ dmas = <&sdma 32 4 0>, <&sdma 33 4 0>;
+ dma-names = "rx", "tx";
status = "disabled";
};
@@ -906,6 +952,8 @@
clocks = <&clks IMX7D_UART7_ROOT_CLK>,
<&clks IMX7D_UART7_ROOT_CLK>;
clock-names = "ipg", "per";
+ dmas = <&sdma 34 4 0>, <&sdma 35 4 0>;
+ dma-names = "rx", "tx";
status = "disabled";
};
@@ -917,6 +965,9 @@
fsl,usbphy = <&usbphynop1>;
fsl,usbmisc = <&usbmisc1 0>;
phy-clkgate-delay-us = <400>;
+ ahb-burst-config = <0x0>;
+ tx-burst-size-dword = <0x10>;
+ rx-burst-size-dword = <0x10>;
status = "disabled";
};
@@ -965,6 +1016,8 @@
<&clks IMX7D_NAND_USDHC_BUS_ROOT_CLK>,
<&clks IMX7D_USDHC1_ROOT_CLK>;
clock-names = "ipg", "ahb", "per";
+ fsl,tuning-start-tap = <20>;
+ fsl,tuning-step= <2>;
bus-width = <4>;
status = "disabled";
};
@@ -977,6 +1030,8 @@
<&clks IMX7D_NAND_USDHC_BUS_ROOT_CLK>,
<&clks IMX7D_USDHC2_ROOT_CLK>;
clock-names = "ipg", "ahb", "per";
+ fsl,tuning-start-tap = <20>;
+ fsl,tuning-step= <2>;
bus-width = <4>;
status = "disabled";
};
@@ -989,6 +1044,8 @@
<&clks IMX7D_NAND_USDHC_BUS_ROOT_CLK>,
<&clks IMX7D_USDHC3_ROOT_CLK>;
clock-names = "ipg", "ahb", "per";
+ fsl,tuning-start-tap = <20>;
+ fsl,tuning-step= <2>;
bus-width = <4>;
status = "disabled";
};
@@ -1010,11 +1067,11 @@
interrupts = <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&clks IMX7D_ENET_AXI_ROOT_CLK>,
+ clocks = <&clks IMX7D_ENET1_IPG_ROOT_CLK>,
<&clks IMX7D_ENET_AXI_ROOT_CLK>,
<&clks IMX7D_ENET1_TIME_ROOT_CLK>,
<&clks IMX7D_PLL_ENET_MAIN_125M_CLK>,
- <&clks IMX7D_ENET_PHY_REF_ROOT_CLK>;
+ <&clks IMX7D_ENET_PHY_REF_ROOT_DIV>;
clock-names = "ipg", "ahb", "ptp",
"enet_clk_ref", "enet_out";
fsl,num-tx-queues=<3>;
diff --git a/arch/arm/boot/dts/imx7ulp-14x14-arm2.dts b/arch/arm/boot/dts/imx7ulp-14x14-arm2.dts
new file mode 100644
index 000000000000..8a67474e2fc9
--- /dev/null
+++ b/arch/arm/boot/dts/imx7ulp-14x14-arm2.dts
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2016 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 "imx7ulp.dtsi"
+
+/ {
+ model = "NXP i.MX7ULP 14x14 arm2";
+ compatible = "fsl,imx7ulp-14x14-arm2", "fsl,imx7ulp", "Generic DT based system";
+
+ chosen {
+ bootargs = "console=ttyLP0,115200 earlycon=lpuart32,0x402D0000,115200";
+ stdout-path = &lpuart4;
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x60000000 0x40000000>;
+ };
+};
+
+&iomuxc1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_hog_1>;
+
+ imx7ulp-14x14-arm2 {
+ pinctrl_hog_1: hoggrp-1 {
+ fsl,pins = <
+ IMX7ULP_PAD_PTC10__PTC10 0x30100
+ IMX7ULP_PAD_PTC1__PTC1 0x20100
+ >;
+ };
+
+ pinctrl_lpuart4: lpuart4grp {
+ fsl,pins = <
+ IMX7ULP_PAD_PTC3__LPUART4_RX 0x400
+ IMX7ULP_PAD_PTC2__LPUART4_TX 0x400
+ >;
+ };
+
+ pinctrl_usdhc1: usdhc1grp {
+ fsl,pins = <
+ IMX7ULP_PAD_PTE3__SDHC1_CMD 0x843
+ IMX7ULP_PAD_PTE2__SDHC1_CLK 0x843
+ IMX7ULP_PAD_PTE4__SDHC1_D3 0x843
+ IMX7ULP_PAD_PTE5__SDHC1_D2 0x843
+ IMX7ULP_PAD_PTE0__SDHC1_D1 0x843
+ IMX7ULP_PAD_PTE1__SDHC1_D0 0x843
+ >;
+ };
+ };
+};
+
+&lpuart4 { /* console */
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lpuart4>;
+ status = "okay";
+};
+
+&usdhc1 {
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&pinctrl_usdhc1>;
+ pinctrl-1 = <&pinctrl_usdhc1>;
+ non-removable;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx7ulp-evk-emmc-qspi.dts b/arch/arm/boot/dts/imx7ulp-evk-emmc-qspi.dts
new file mode 100644
index 000000000000..47289c636e94
--- /dev/null
+++ b/arch/arm/boot/dts/imx7ulp-evk-emmc-qspi.dts
@@ -0,0 +1,18 @@
+/*
+ * Copyright 2017 NXP
+ *
+ * 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 "imx7ulp-evk-qspi.dts"
+
+&usdhc0 {
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&pinctrl_usdhc0_8bit>;
+ pinctrl-1 = <&pinctrl_usdhc0_8bit>;
+ non-removable;
+ bus-width = <8>;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx7ulp-evk-ft5416.dts b/arch/arm/boot/dts/imx7ulp-evk-ft5416.dts
new file mode 100644
index 000000000000..be626ec2e119
--- /dev/null
+++ b/arch/arm/boot/dts/imx7ulp-evk-ft5416.dts
@@ -0,0 +1,17 @@
+/*
+ * Copyright 2017 NXP
+ *
+ * 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 "imx7ulp-evk.dts"
+
+&lpi2c7 {
+ focaltech@38 {
+ focaltech,panel-type = <FT5416>;
+ focaltech,swap-xy;
+ /delete-property/focaltech,scaling-down-half;
+ };
+};
diff --git a/arch/arm/boot/dts/imx7ulp-evk-mipi.dts b/arch/arm/boot/dts/imx7ulp-evk-mipi.dts
new file mode 100644
index 000000000000..a467fad79846
--- /dev/null
+++ b/arch/arm/boot/dts/imx7ulp-evk-mipi.dts
@@ -0,0 +1,10 @@
+/*
+ * Copyright 2017-2018 NXP.
+ *
+ * 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 "imx7ulp-evk.dts"
+#include "imx7ulp-evk-mipi.dtsi"
diff --git a/arch/arm/boot/dts/imx7ulp-evk-mipi.dtsi b/arch/arm/boot/dts/imx7ulp-evk-mipi.dtsi
new file mode 100644
index 000000000000..4caeefbf3b68
--- /dev/null
+++ b/arch/arm/boot/dts/imx7ulp-evk-mipi.dtsi
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2018 NXP.
+ *
+ * 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.
+ */
+
+&adv7535 {
+ status = "disabled";
+
+ /delete-node/ port;
+};
+
+&mipi_dsi {
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&pinctrl_mipi_dsi_reset>;
+ pinctrl-1 = <&pinctrl_mipi_dsi_reset>;
+ lcd_panel = "TRULY-WVGA-TFT3P5581E";
+ resets = <&mipi_dsi_reset>;
+
+ /delete-node/ port;
+};
diff --git a/arch/arm/boot/dts/imx7ulp-evk-qspi.dts b/arch/arm/boot/dts/imx7ulp-evk-qspi.dts
new file mode 100644
index 000000000000..ca8bfc0e9834
--- /dev/null
+++ b/arch/arm/boot/dts/imx7ulp-evk-qspi.dts
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2018 NXP
+ *
+ * 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 "imx7ulp-evk.dts"
+
+/ {
+ regulators {
+ compatible = "simple-bus";
+
+ dummy: regulator-dummy {
+ compatible = "regulator-fixed";
+ regulator-name = "dummy";
+ regulator-always-on;
+ };
+ };
+};
+
+&qspi1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_qspi1_1>;
+ status = "okay";
+
+ flash0: mx25r6435f@0 {
+ reg = <0>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "macronix,mx25r6435f";
+ spi-max-frequency = <29000000>;
+ };
+};
+
+&rpmsg{
+ status = "disabled";
+};
+
+&cpu0 {
+ arm-supply= <&dummy>;
+ operating-points = <
+ /* KHz uV */
+ 500210 1025000
+ >;
+};
+
+&usdhc0 {
+ vqmmc-supply = <&dummy>;
+ no-1-8-v;
+ non-removable;
+};
+
+&iomuxc {
+ status = "okay";
+};
+
+&iomuxc {
+ imx7ulp-evk {
+ pinctrl_qspi1_1: qspi1grp_1 {
+ fsl,pins = <
+ IMX7ULP_PAD_PTB7__QSPIA_SS1_B 0x43 /* SS1 */
+ IMX7ULP_PAD_PTB8__QSPIA_SS0_B 0x43 /* SS0 */
+ IMX7ULP_PAD_PTB15__QSPIA_SCLK 0x43 /* SCLK */
+ IMX7ULP_PAD_PTB9__QSPIA_DQS 0x43 /* DQS */
+ IMX7ULP_PAD_PTB16__QSPIA_DATA3 0x43 /* D3 */
+ IMX7ULP_PAD_PTB17__QSPIA_DATA2 0x43 /* D2 */
+ IMX7ULP_PAD_PTB18__QSPIA_DATA1 0x43 /* D1 */
+ IMX7ULP_PAD_PTB19__QSPIA_DATA0 0x43 /* D0 */
+ >;
+ };
+ };
+};
+
diff --git a/arch/arm/boot/dts/imx7ulp-evk-wm8960.dts b/arch/arm/boot/dts/imx7ulp-evk-wm8960.dts
new file mode 100644
index 000000000000..e3598f5b8bd9
--- /dev/null
+++ b/arch/arm/boot/dts/imx7ulp-evk-wm8960.dts
@@ -0,0 +1,200 @@
+/*
+ * Copyright 2016 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 "imx7ulp-evk.dts"
+
+/ {
+
+ aips0: aips-bus@41000000 {
+ compatible = "fsl,aips-bus", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x41000000 0x80000>;
+ ranges;
+
+ pcc0: pcc0@41026000 {
+ compatible = "fsl,imx7ulp-pcc0";
+ reg = <0x41026000 0x1000>;
+ };
+
+ clks_m4: scg0@41027000 {
+ compatible = "fsl,imx7ulp-scg0";
+ reg = <0x41027000 0x1000>;
+ clocks = <&cm4_rosc>, <&cm4_sosc>, <&cm4_sirc>, <&cm4_firc>;
+ clock-names = "cm4_rosc", "cm4_sosc", "cm4_sirc", "cm4_firc";
+ #clock-cells = <1>;
+ };
+
+ sai0: sai@41037000 {
+ compatible = "fsl,imx7ulp-sai";
+ reg = <0x41037000 0x1000>;
+ interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks_m4 IMX7ULP_CM4_CLK_SAI0_IPG>,
+ <&clks_m4 IMX7ULP_CM4_CLK_DUMMY>,
+ <&clks_m4 IMX7ULP_CM4_CLK_SAI0_ROOT>,
+ <&clks_m4 IMX7ULP_CM4_CLK_DUMMY>,
+ <&clks_m4 IMX7ULP_CM4_CLK_DUMMY>;
+ clock-names = "bus", "mclk0", "mclk1", "mclk2", "mclk3";
+ dma-names = "rx", "tx";
+ dmas = <&edma0 0 59>, <&edma0 0 60>;
+ status = "disabled";
+ };
+ };
+
+ aips1: aips-bus@41080000 {
+ compatible = "fsl,aips-bus", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x41080000 0x80000>;
+ ranges;
+
+ smc0: smc0@410a4000 {
+ compatible = "fsl,imx7ulp-smc0";
+ reg = <0x410a4000 0x1000>;
+ };
+
+ sai1: sai@410AA000 {
+ compatible = "fsl,imx7ulp-sai";
+ reg = <0x410AA000 0x1000>;
+ interrupts = <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks_m4 IMX7ULP_CM4_CLK_SAI1_IPG>,
+ <&clks_m4 IMX7ULP_CM4_CLK_DUMMY>,
+ <&clks_m4 IMX7ULP_CM4_CLK_SAI1_ROOT>,
+ <&clks_m4 IMX7ULP_CM4_CLK_DUMMY>,
+ <&clks_m4 IMX7ULP_CM4_CLK_DUMMY>;
+ clock-names = "bus", "mclk0", "mclk1", "mclk2", "mclk3";
+ dma-names = "rx", "tx";
+ dmas = <&edma0 0 61>, <&edma0 0 62>;
+ status = "disabled";
+ };
+
+ pcc1: pcc1@410b2000 {
+ compatible = "fsl,imx7ulp-pcc1";
+ reg = <0x410b2000 0x1000>;
+ };
+ };
+
+ clocks_m4 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cm4_rosc: clock@6 {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <32768>;
+ clock-output-names = "cm4_rosc";
+ };
+
+ cm4_sosc: clock@7 {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <24000000>;
+ clock-output-names = "cm4_sosc";
+ };
+
+ cm4_sirc: clock@8 {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <16000000>;
+ clock-output-names = "cm4_sirc";
+ };
+
+ cm4_firc: clock@9 {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <48000000>;
+ clock-output-names = "cm4_firc";
+ };
+ };
+
+ sound-rpmsg {
+ status = "disabled";
+ };
+
+ sound {
+ compatible = "fsl,imx7d-evk-wm8960",
+ "fsl,imx-audio-wm8960";
+ model = "wm8960-audio";
+ cpu-dai = <&sai0>;
+ audio-codec = <&codec>;
+ codec-master;
+ /* JD3: hp detect high for headphone*/
+ hp-det = <3 0>;
+ audio-routing =
+ "Headphone Jack", "HP_L",
+ "Headphone Jack", "HP_R",
+ "Ext Spk", "SPK_LP",
+ "Ext Spk", "SPK_LN",
+ "Ext Spk", "SPK_RP",
+ "Ext Spk", "SPK_RN",
+ "LINPUT1", "Mic Jack",
+ "LINPUT3", "Mic Jack",
+ "Mic Jack", "MICB";
+
+ };
+};
+
+&iomuxc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_hog_0_1>;
+ status = "okay";
+
+ imx7ulp-evk-0 {
+ pinctrl_hog_0_1: hoggrp-0-1 {
+ fsl,pins = <
+ IMX7ULP_PAD_PTA24__PTA24 0x127
+ IMX7ULP_PAD_PTB0__CLKOUT0 0x900
+ >;
+ };
+
+ pinctrl_sai0: sai0_grp {
+ fsl,pins = <
+ IMX7ULP_PAD_PTA4__I2S0_MCLK 0x700
+ IMX7ULP_PAD_PTA5__I2S0_TX_BCLK 0x0700
+ IMX7ULP_PAD_PTA2__I2S0_RXD0 0x0700
+ IMX7ULP_PAD_PTA6__I2S0_TX_FS 0x0700
+ IMX7ULP_PAD_PTA7__I2S0_TXD0 0x0700
+ >;
+ };
+ };
+};
+
+&lpi2c7 {
+ status = "okay";
+
+ codec: wm8960@1a {
+ compatible = "wlf,wm8960";
+ reg = <0x1a>;
+ clocks = <&clks_m4 IMX7ULP_CLK_SCG0_CLKOUT>;
+ clock-names = "mclk";
+ wlf,shared-lrclk;
+ assigned-clocks = <&clks_m4 IMX7ULP_CLK_SCG0_CLKOUT>;
+ assigned-clock-parents = <&clks_m4 IMX7ULP_CM4_CLK_SOSC>;
+ };
+};
+
+&clks_m4 {
+ assigned-clocks = <&clks_m4 IMX7ULP_CM4_CLK_APLL_VCO_PRE_SEL>,
+ <&clks_m4 IMX7ULP_CM4_CLK_APLL_VCO>,
+ <&clks_m4 IMX7ULP_CM4_CLK_APLL_VCO_POST_DIV1>,
+ <&clks_m4 IMX7ULP_CM4_CLK_APLL_VCO_POST_DIV2>,
+ <&clks_m4 IMX7ULP_CM4_CLK_APLL_PFD0_PRE_DIV>;
+ assigned-clock-parents = <&clks_m4 IMX7ULP_CM4_CLK_SOSC>;
+ assigned-clock-rates = <0>, <540672000>, <49152000>, <12288000>, <270336000>;
+};
+
+&sai0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_sai0>;
+ assigned-clocks = <&clks_m4 IMX7ULP_CM4_CLK_SAI0_SEL>,
+ <&clks_m4 IMX7ULP_CM4_CLK_SAI0_DIV>;
+ assigned-clock-parents = <&clks_m4 IMX7ULP_CM4_CLK_APLL_PFD0_PRE_DIV>;
+ assigned-clock-rates = <0>, <12288000>;
+ fsl,dataline = <0 0x1 0x1>;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx7ulp-evk.dts b/arch/arm/boot/dts/imx7ulp-evk.dts
new file mode 100644
index 000000000000..366abe6fedcc
--- /dev/null
+++ b/arch/arm/boot/dts/imx7ulp-evk.dts
@@ -0,0 +1,579 @@
+/*
+ * Copyright 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017-2018 NXP.
+ *
+ * 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 "imx7ulp.dtsi"
+#include <dt-bindings/input/input.h>
+
+/ {
+ model = "NXP i.MX7ULP EVK";
+ compatible = "fsl,imx7ulp-evk", "fsl,imx7ulp", "Generic DT based system";
+
+ aliases {
+ gpio4 = &rpmsg_gpio0;
+ gpio5 = &rpmsg_gpio1;
+ };
+
+ chosen {
+ stdout-path = &lpuart4;
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x60000000 0x40000000>;
+ };
+
+ backlight {
+ compatible = "pwm-backlight";
+ pwms = <&pwm0 1 50000>;
+ brightness-levels = <0 20 25 30 35 40 100>;
+ default-brightness-level = <6>;
+ status = "okay";
+ };
+
+ mipi_dsi_reset: mipi-dsi-reset {
+ compatible = "gpio-reset";
+ reset-gpios = <&gpio_ptc 19 GPIO_ACTIVE_LOW>;
+ reset-delay-us = <1000>;
+ #reset-cells = <0>;
+ };
+
+ modem_reset: modem-reset {
+ compatible = "gpio-reset";
+ reset-gpios = <&rpmsg_gpio0 15 GPIO_ACTIVE_LOW>;
+ reset-delay-us = <1000>;
+ #reset-cells = <0>;
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ reg_usb_otg1_vbus: regulator@0 {
+ compatible = "regulator-fixed";
+ reg = <0>;
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&pinctrl_usbotg1_vbus>;
+ pinctrl-1 = <&pinctrl_usbotg1_vbus>;
+ regulator-name = "usb_otg1_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&gpio_ptc 0 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ reg_vsd_3v3: regulator@1 {
+ compatible = "regulator-fixed";
+ reg = <1>;
+ regulator-name = "VSD_3V3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&gpio_ptd 0 GPIO_ACTIVE_HIGH>;
+ off-on-delay = <20000>;
+ enable-active-high;
+ };
+
+ reg_sd1_vmmc: sd1_regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "WLAN_EN";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&rpmsg_gpio0 14 GPIO_ACTIVE_HIGH>;
+ off-on-delay = <20000>;
+ startup-delay-us = <100>;
+ enable-active-high;
+ };
+ };
+
+ pf1550-rpmsg {
+ compatible = "fsl,pf1550-rpmsg";
+ sw1_reg: SW1 {
+ regulator-name = "SW1";
+ regulator-min-microvolt = <600000>;
+ regulator-max-microvolt = <1387500>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ sw2_reg: SW2 {
+ regulator-name = "SW2";
+ regulator-min-microvolt = <600000>;
+ regulator-max-microvolt = <1387500>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ sw3_reg: SW3 {
+ regulator-name = "SW3";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ vref_reg: VREFDDR {
+ regulator-name = "VREFDDR";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ vldo1_reg: LDO1 {
+ regulator-name = "LDO1";
+ regulator-min-microvolt = <750000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ vldo2_reg: LDO2 {
+ regulator-name = "LDO2";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ vldo3_reg: LDO3 {
+ regulator-name = "LDO3";
+ regulator-min-microvolt = <750000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+ };
+
+ rpmsg_i2s: rpmsg-i2s {
+ compatible = "fsl,imx7ulp-rpmsg-i2s";
+ /* the audio device index in m4 domain */
+ fsl,audioindex = <0> ;
+ status = "okay";
+ };
+
+ rpmsg_gpio0: rpmsg-gpio0 {
+ compatible = "fsl,imx-rpmsg-gpio";
+ port_idx = <0>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ interrupt-parent = <&rpmsg_gpio0>;
+ status = "okay";
+ };
+
+ rpmsg_gpio1: rpmsg-gpio1 {
+ compatible = "fsl,imx-rpmsg-gpio";
+ port_idx = <1>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ interrupt-parent = <&rpmsg_gpio1>;
+ status = "okay";
+ };
+
+ rpmsg_keys: rpmsg-keys {
+ compatible = "fsl,rpmsg-keys";
+
+ volume-up {
+ label = "Volume Up";
+ linux,code = <KEY_VOLUMEUP>;
+ };
+
+ volume-down {
+ label = "Volume Down";
+ linux,code = <KEY_VOLUMEDOWN>;
+ };
+
+ power-on {
+ label = "PowerOn";
+ linux,code = <KEY_POWER>;
+ rpmsg-key,wakeup;
+ };
+ };
+
+ rpmsg_sensor: rpmsg-sensor {
+ compatible = "fsl,rpmsg-input";
+ };
+
+ sound-rpmsg {
+ compatible = "fsl,imx-audio-rpmsg";
+ model = "rpmsg-audio";
+ cpu-dai = <&rpmsg_i2s>;
+ rpmsg-out;
+ rpmsg-in;
+ audio-routing =
+ "Headphone Jack", "HP_L",
+ "Headphone Jack", "HP_R",
+ "Ext Spk", "SPK_LP",
+ "Ext Spk", "SPK_LN",
+ "Ext Spk", "SPK_RP",
+ "Ext Spk", "SPK_RN",
+ "LINPUT2", "Mic Jack",
+ "LINPUT3", "Mic Jack",
+ "RINPUT1", "Main MIC",
+ "RINPUT2", "Main MIC",
+ "Mic Jack", "MICB",
+ "Main MIC", "MICB",
+ "Playback", "CPU-Playback",
+ "CPU-Capture", "Capture";
+ };
+};
+
+&cpu0 {
+ arm-supply= <&sw1_reg>;
+};
+
+&iomuxc1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_hog_1>;
+
+ imx7ulp-evk {
+ pinctrl_hog_1: hoggrp-1 {
+ fsl,pins = <
+ IMX7ULP_PAD_PTC1__PTC1 0x20000
+ >;
+ };
+
+ pinctrl_pwm0: pwm0_grp {
+ fsl,pins = <
+ IMX7ULP_PAD_PTF2__TPM4_CH1 0x3
+ >;
+ };
+
+ pinctrl_lpi2c5: lpi2c5grp {
+ fsl,pins = <
+ IMX7ULP_PAD_PTC4__LPI2C5_SCL 0x27
+ IMX7ULP_PAD_PTC5__LPI2C5_SDA 0x27
+ >;
+ };
+
+ pinctrl_mipi_dsi_reset: mipi_dsi_reset_grp {
+ fsl,pins = <
+ IMX7ULP_PAD_PTC19__PTC19 0x20003
+ >;
+ };
+
+ pinctrl_lpuart4: lpuart4grp {
+ fsl,pins = <
+ IMX7ULP_PAD_PTC3__LPUART4_RX 0x3
+ IMX7ULP_PAD_PTC2__LPUART4_TX 0x3
+ >;
+ };
+
+ pinctrl_lpuart6: lpuart6grp {
+ fsl,pins = <
+ IMX7ULP_PAD_PTE10__LPUART6_TX 0x3
+ IMX7ULP_PAD_PTE11__LPUART6_RX 0x3
+ IMX7ULP_PAD_PTE9__LPUART6_RTS_B 0x3
+ IMX7ULP_PAD_PTE8__LPUART6_CTS_B 0x3
+ IMX7ULP_PAD_PTE7__PTE7 0x20000 /* BT_REG_ON */
+ >;
+ };
+
+ pinctrl_lpuart7: lpuart7grp {
+ fsl,pins = <
+ IMX7ULP_PAD_PTF14__LPUART7_TX 0x3
+ IMX7ULP_PAD_PTF15__LPUART7_RX 0x3
+ IMX7ULP_PAD_PTF13__LPUART7_RTS_B 0x3
+ IMX7ULP_PAD_PTF12__LPUART7_CTS_B 0x3
+ >;
+ };
+
+ pinctrl_usdhc0: usdhc0grp {
+ fsl,pins = <
+ IMX7ULP_PAD_PTD1__SDHC0_CMD 0x43
+ IMX7ULP_PAD_PTD2__SDHC0_CLK 0x10042
+ IMX7ULP_PAD_PTD7__SDHC0_D3 0x43
+ IMX7ULP_PAD_PTD8__SDHC0_D2 0x43
+ IMX7ULP_PAD_PTD9__SDHC0_D1 0x43
+ IMX7ULP_PAD_PTD10__SDHC0_D0 0x43
+ IMX7ULP_PAD_PTC10__PTC10 0x10000 /* USDHC0 CD */
+ IMX7ULP_PAD_PTD0__PTD0 0x20000 /* USDHC0 RST */
+ >;
+ };
+
+ pinctrl_usdhc0_8bit: usdhc0grp_8bit {
+ fsl,pins = <
+ IMX7ULP_PAD_PTD1__SDHC0_CMD 0x43
+ IMX7ULP_PAD_PTD2__SDHC0_CLK 0x10042
+ IMX7ULP_PAD_PTD3__SDHC0_D7 0x43
+ IMX7ULP_PAD_PTD4__SDHC0_D6 0x43
+ IMX7ULP_PAD_PTD5__SDHC0_D5 0x43
+ IMX7ULP_PAD_PTD6__SDHC0_D4 0x43
+ IMX7ULP_PAD_PTD7__SDHC0_D3 0x43
+ IMX7ULP_PAD_PTD8__SDHC0_D2 0x43
+ IMX7ULP_PAD_PTD9__SDHC0_D1 0x43
+ IMX7ULP_PAD_PTD10__SDHC0_D0 0x43
+ IMX7ULP_PAD_PTD11__SDHC0_DQS 0x42
+ >;
+ };
+
+ pinctrl_lpi2c7: lpi2c7grp {
+ fsl,pins = <
+ IMX7ULP_PAD_PTF12__LPI2C7_SCL 0x27
+ IMX7ULP_PAD_PTF13__LPI2C7_SDA 0x27
+ >;
+ };
+
+ pinctrl_lpspi3: lpspi3grp {
+ fsl,pins = <
+ IMX7ULP_PAD_PTF16__LPSPI3_SIN 0x0
+ IMX7ULP_PAD_PTF17__LPSPI3_SOUT 0x0
+ IMX7ULP_PAD_PTF18__LPSPI3_SCK 0x0
+ IMX7ULP_PAD_PTF19__LPSPI3_PCS0 0x0
+ >;
+ };
+
+ pinctrl_usbotg1_vbus: otg1vbusgrp {
+ fsl,pins = <
+ IMX7ULP_PAD_PTC0__PTC0 0x20000
+ >;
+ };
+
+ pinctrl_usbotg1_id: otg1idgrp {
+ fsl,pins = <
+ IMX7ULP_PAD_PTC13__USB0_ID 0x10003
+ >;
+ };
+
+ pinctrl_touch_io: touchiogrp {
+ fsl,pins = <
+ IMX7ULP_PAD_PTF0__PTF0 0x10043
+ IMX7ULP_PAD_PTF1__PTF1 0x20043
+ >;
+ };
+
+ pinctrl_usdhc1: usdhc1grp {
+ fsl,pins = <
+ IMX7ULP_PAD_PTE3__SDHC1_CMD 0x43
+ IMX7ULP_PAD_PTE2__SDHC1_CLK 0x10042
+ IMX7ULP_PAD_PTE1__SDHC1_D0 0x43
+ IMX7ULP_PAD_PTE0__SDHC1_D1 0x43
+ IMX7ULP_PAD_PTE5__SDHC1_D2 0x43
+ IMX7ULP_PAD_PTE4__SDHC1_D3 0x43
+ >;
+ };
+
+ pinctrl_usdhc1_rst: usdhc1grp_rst {
+ fsl,pins = <
+ IMX7ULP_PAD_PTE11__PTE11 0x20000 /* USDHC1 RST */
+ IMX7ULP_PAD_PTE13__PTE13 0x10003 /* USDHC1 CD */
+ IMX7ULP_PAD_PTE12__PTE12 0x10003 /* USDHC1 WP */
+ IMX7ULP_PAD_PTE14__SDHC1_VS 0x43 /* USDHC1 VSEL */
+ >;
+ };
+
+ pinctrl_dsi_hdmi: dsi_hdmi_grp {
+ fsl,pins = <
+ IMX7ULP_PAD_PTC18__PTC18 0x10003 /* DSI_HDMI_INT */
+ >;
+ };
+ };
+};
+
+&lcdif {
+ status = "okay";
+ disp-dev = "mipi_dsi_northwest";
+ display = <&display0>;
+
+ display0: display@0 {
+ bits-per-pixel = <16>;
+ bus-width = <24>;
+
+ display-timings {
+ native-mode = <&timing0>;
+ timing0: timing0 {
+ clock-frequency = <9200000>;
+ hactive = <480>;
+ vactive = <272>;
+ hfront-porch = <8>;
+ hback-porch = <4>;
+ hsync-len = <41>;
+ vback-porch = <2>;
+ vfront-porch = <4>;
+ vsync-len = <10>;
+
+ hsync-active = <0>;
+ vsync-active = <0>;
+ de-active = <1>;
+ pixelclk-active = <0>;
+ };
+ };
+ };
+};
+
+&lpi2c7 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&pinctrl_lpi2c7 &pinctrl_touch_io>;
+ pinctrl-1 = <&pinctrl_lpi2c7 &pinctrl_touch_io>;
+ status = "okay";
+
+ focaltech@38 {
+ compatible = "focaltech,fts";
+ reg = <0x38>;
+ interrupt-parent = <&gpio_ptf>;
+ interrupts = <0 0x02>;
+ focaltech,panel-type = <FT5426>;
+ focaltech,reset-gpio = <&gpio_ptf 1 0x01>;
+ focaltech,irq-gpio = <&gpio_ptf 0 0x02>;
+ focaltech,max-touch-number = <5>;
+ focaltech,display-coords = <0 0 480 854>;
+
+ focaltech,have-key;
+ focaltech,key-number = <3>;
+ focaltech,keys = <139 102 158>;
+ focaltech,key-y-coord = <2000>;
+ focaltech,key-x-coords = <200 600 800>;
+ };
+};
+
+&lpi2c5 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&pinctrl_lpi2c5>;
+ pinctrl-1 = <&pinctrl_lpi2c5>;
+ status = "okay";
+
+ adv7535: adv7535@3d {
+ compatible = "adi,adv7535";
+ reg = <0x3d>; /* PD pin is low */
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_dsi_hdmi>;
+ interrupt-parent = <&gpio_ptc>;
+ interrupts = <18 IRQ_TYPE_EDGE_FALLING>;
+ video-mode = <1>; /*
+ * Only support CEA modes.
+ * Reference mxc_edid.c
+ */
+ dsi-traffic-mode = <0>;
+ bpp = <24>;
+ status = "disabled";
+ };
+};
+
+&lpspi3 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ fsl,spi-num-chipselects = <1>;
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&pinctrl_lpspi3>;
+ pinctrl-1 = <&pinctrl_lpspi3>;
+ status = "okay";
+
+ spidev0: spi@0 {
+ reg = <0>;
+ compatible = "rohm,dh2228fv";
+ spi-max-frequency = <1000000>;
+ };
+};
+
+
+&adv7535 {
+ status = "okay";
+
+ port {
+ dsi_to_hdmi: endpoint {
+ remote-endpoint = <&mipi_dsi_ep>;
+ };
+ };
+};
+
+&mipi_dsi {
+ status = "okay";
+
+ port {
+ mipi_dsi_ep: endpoint {
+ remote-endpoint = <&dsi_to_hdmi>;
+ };
+ };
+};
+
+&lpuart4 { /* console */
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&pinctrl_lpuart4>;
+ pinctrl-1 = <&pinctrl_lpuart4>;
+ status = "okay";
+};
+
+&lpuart6 { /* BT */
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&pinctrl_lpuart6>;
+ pinctrl-1 = <&pinctrl_lpuart6>;
+ resets = <&modem_reset>;
+ status = "okay";
+};
+
+&lpuart7 { /* Uart test */
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&pinctrl_lpuart7>;
+ pinctrl-1 = <&pinctrl_lpuart7>;
+ status = "disabled";
+};
+
+&pwm0 {
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&pinctrl_pwm0>;
+ pinctrl-1 = <&pinctrl_pwm0>;
+ status = "okay";
+};
+
+&rpmsg{
+ /*
+ * 64K for one rpmsg instance, default using 2 rpmsg instances:
+ * --0x9FF00000~0x9FF0FFFF: pmic,pm,audio,keys,gpio,sensor
+ * --0x9FF10000~0x9FF1FFFF: pingpong,virtual tty
+ */
+ vdev-nums = <2>;
+ reg = <0x9FF00000 0x20000>;
+ status = "okay";
+};
+
+&usbotg1 {
+ vbus-supply = <&reg_usb_otg1_vbus>;
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&pinctrl_usbotg1_id>;
+ pinctrl-1 = <&pinctrl_usbotg1_id>;
+ srp-disable;
+ hnp-disable;
+ adp-disable;
+ status = "okay";
+};
+
+&usbphy1 {
+ fsl,tx-d-cal = <88>;
+};
+
+&usdhc0 {
+ pinctrl-names = "default", "state_100mhz", "state_200mhz", "sleep";
+ pinctrl-0 = <&pinctrl_usdhc0>;
+ pinctrl-1 = <&pinctrl_usdhc0>;
+ pinctrl-2 = <&pinctrl_usdhc0>;
+ pinctrl-3 = <&pinctrl_usdhc0>;
+ cd-gpios = <&gpio_ptc 10 GPIO_ACTIVE_LOW>;
+ vmmc-supply = <&reg_vsd_3v3>;
+ vqmmc-supply = <&vldo2_reg>;
+ status = "okay";
+};
+
+&usdhc1 {
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&pinctrl_usdhc1>;
+ pinctrl-1 = <&pinctrl_usdhc1>;
+ bus-width = <4>;
+ no-1-8-v;
+ vmmc-supply = <&reg_sd1_vmmc>;
+ pm-ignore-notify;
+ keep-power-in-suspend;
+ non-removable;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx7ulp-evkb-emmc.dts b/arch/arm/boot/dts/imx7ulp-evkb-emmc.dts
new file mode 100644
index 000000000000..fbd04b8c8868
--- /dev/null
+++ b/arch/arm/boot/dts/imx7ulp-evkb-emmc.dts
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2018 NXP.
+ *
+ * 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 "imx7ulp-evkb.dts"
+
+/* To support eMMC HS200/HS400, need to do the following reowrk:
+ * 1,remove TF sd slot, replace eMMC chip
+ * 2,fix eMMC I/O voltage to 1.8v, remove R183, short TP3 and TP89
+ * 3,add R107, make eMMC boot work
+ */
+&usdhc0 {
+ pinctrl-names = "default", "state_100mhz", "state_200mhz", "sleep";
+ pinctrl-0 = <&pinctrl_usdhc0_8bit>;
+ pinctrl-1 = <&pinctrl_usdhc0_8bit>;
+ pinctrl-2 = <&pinctrl_usdhc0_8bit>;
+ pinctrl-3 = <&pinctrl_usdhc0_8bit>;
+ non-removable;
+ bus-width = <8>;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx7ulp-evkb-lpuart.dts b/arch/arm/boot/dts/imx7ulp-evkb-lpuart.dts
new file mode 100644
index 000000000000..a5e804c6e7d6
--- /dev/null
+++ b/arch/arm/boot/dts/imx7ulp-evkb-lpuart.dts
@@ -0,0 +1,17 @@
+/*
+ * Copyright (C) 2016 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 "imx7ulp-evkb.dts"
+
+&lpi2c7 {
+ status = "disabled";
+};
+
+&lpuart7 { /* Uart test */
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx7ulp-evkb-mipi.dts b/arch/arm/boot/dts/imx7ulp-evkb-mipi.dts
new file mode 100644
index 000000000000..16159b08c615
--- /dev/null
+++ b/arch/arm/boot/dts/imx7ulp-evkb-mipi.dts
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2018 NXP.
+ *
+ * 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 "imx7ulp-evkb.dts"
+#include "imx7ulp-evk-mipi.dtsi"
+
+&lpi2c7 {
+
+ focaltech@38 {
+ status = "disabled";
+ };
+
+ goodix@14 {
+ compatible = "goodix,gt911";
+ reg = <0x14>;
+ interrupt-parent = <&gpio_ptf>;
+ interrupts = <0 IRQ_TYPE_EDGE_FALLING>;
+ irq-gpios = <&gpio_ptf 0 GPIO_ACTIVE_HIGH>;
+ reset-gpios = <&gpio_ptf 1 GPIO_ACTIVE_HIGH>;
+ };
+};
diff --git a/arch/arm/boot/dts/imx7ulp-evkb-rm68191-qhd.dts b/arch/arm/boot/dts/imx7ulp-evkb-rm68191-qhd.dts
new file mode 100644
index 000000000000..c482087c08e0
--- /dev/null
+++ b/arch/arm/boot/dts/imx7ulp-evkb-rm68191-qhd.dts
@@ -0,0 +1,13 @@
+/*
+ * Copyright 2018 NXP.
+ *
+ * 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 "imx7ulp-evkb-mipi.dts"
+
+&mipi_dsi {
+ lcd_panel = "ROCKTECH-QHD-RK055IQH042";
+};
diff --git a/arch/arm/boot/dts/imx7ulp-evkb-rm68200-wxga.dts b/arch/arm/boot/dts/imx7ulp-evkb-rm68200-wxga.dts
new file mode 100644
index 000000000000..28b83c388101
--- /dev/null
+++ b/arch/arm/boot/dts/imx7ulp-evkb-rm68200-wxga.dts
@@ -0,0 +1,13 @@
+/*
+ * Copyright 2018 NXP.
+ *
+ * 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 "imx7ulp-evkb-mipi.dts"
+
+&mipi_dsi {
+ lcd_panel = "ROCKTECH-WXGA-RK055AHD042";
+};
diff --git a/arch/arm/boot/dts/imx7ulp-evkb-sd1.dts b/arch/arm/boot/dts/imx7ulp-evkb-sd1.dts
new file mode 100644
index 000000000000..c29134dbacfb
--- /dev/null
+++ b/arch/arm/boot/dts/imx7ulp-evkb-sd1.dts
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017 NXP
+ *
+ * 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 "imx7ulp-evkb.dts"
+
+/ {
+ regulators {
+ reg_vsd_3v3b: regulator@2 {
+ compatible = "regulator-fixed";
+ reg = <2>;
+ regulator-name = "VSD_3V3B";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&gpio_pte 11 GPIO_ACTIVE_HIGH>;
+ off-on-delay = <20000>;
+ enable-active-high;
+ };
+ };
+};
+
+&lpuart6 {
+ status = "disabled";
+};
+
+&usdhc1 {
+ pinctrl-names = "default", "state_100mhz", "state_200mhz", "sleep";
+ pinctrl-0 = <&pinctrl_usdhc1 &pinctrl_usdhc1_rst>;
+ pinctrl-1 = <&pinctrl_usdhc1 &pinctrl_usdhc1_rst>;
+ pinctrl-2 = <&pinctrl_usdhc1 &pinctrl_usdhc1_rst>;
+ pinctrl-3 = <&pinctrl_usdhc1 &pinctrl_usdhc1_rst>;
+ cd-gpios = <&gpio_pte 13 GPIO_ACTIVE_LOW>;
+ wp-gpios = <&gpio_pte 12 GPIO_ACTIVE_HIGH>;
+ vmmc-supply = <&reg_vsd_3v3b>;
+ /delete-property/non-removable;
+ /delete-property/cd-post;
+ /delete-property/wifi-host;
+ /delete-property/pm-ignore-notify;
+ /delete-property/keep-power-in-suspend;
+ /delete-property/non-removable;
+ /delete-property/no-1-8-v;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx7ulp-evkb-sensors-to-i2c5.dts b/arch/arm/boot/dts/imx7ulp-evkb-sensors-to-i2c5.dts
new file mode 100644
index 000000000000..cfc7402b1b60
--- /dev/null
+++ b/arch/arm/boot/dts/imx7ulp-evkb-sensors-to-i2c5.dts
@@ -0,0 +1,22 @@
+
+#include "imx7ulp-evkb.dts"
+
+&lpi2c5 {
+
+ fxas2100x@20 {
+ compatible = "fsl,fxas2100x";
+ reg = <0x20>;
+ };
+
+ fxos8700@1e {
+ compatible = "fsl,fxos8700";
+ reg = <0x1e>;
+ };
+
+ mpl3115@60 {
+ compatible = "fsl,mpl3115";
+ reg = <0x60>;
+ };
+
+};
+
diff --git a/arch/arm/boot/dts/imx7ulp-evkb-spi-slave.dts b/arch/arm/boot/dts/imx7ulp-evkb-spi-slave.dts
new file mode 100644
index 000000000000..3e38544add00
--- /dev/null
+++ b/arch/arm/boot/dts/imx7ulp-evkb-spi-slave.dts
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017-2018 NXP.
+ *
+ * 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 "imx7ulp-evkb.dts"
+
+/delete-node/&spidev0;
+
+&pinctrl_lpspi3 {
+ fsl,pins = <
+ IMX7ULP_PAD_PTF16__LPSPI3_SIN 0x0
+ IMX7ULP_PAD_PTF17__LPSPI3_SOUT 0x0
+ IMX7ULP_PAD_PTF18__LPSPI3_SCK 0x0
+ IMX7ULP_PAD_PTF19__LPSPI3_PCS0 0x0
+ >;
+};
+
+&lpspi3 {
+ pinctrl-0 = <&pinctrl_lpspi3>;
+ pinctrl-1 = <&pinctrl_lpspi3>;
+ /delete-property/ cs-gpios;
+ spi-slave;
+};
diff --git a/arch/arm/boot/dts/imx7ulp-evkb.dts b/arch/arm/boot/dts/imx7ulp-evkb.dts
new file mode 100644
index 000000000000..c65676c4afac
--- /dev/null
+++ b/arch/arm/boot/dts/imx7ulp-evkb.dts
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2018 NXP
+ *
+ * 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 "imx7ulp-evk.dts"
+
+/ {
+ model = "NXP i.MX7ULP EVKB";
+ compatible = "fsl,imx7ulp-evkb", "fsl,imx7ulp", "Generic DT based system";
+
+ regulators {
+ reg_sd1_vmmc: sd1_regulator {
+ status = "disabled";
+ };
+ };
+
+ usdhc1_pwrseq: usdhc1_pwrseq {
+ compatible = "mmc-pwrseq-simple";
+ reset-gpios = <&rpmsg_gpio0 14 GPIO_ACTIVE_LOW>;
+ post-power-on-delay-ms = <80>;
+ };
+};
+
+&usdhc1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ /delete-property/ vmmc-supply;
+ mmc-pwrseq = <&usdhc1_pwrseq>;
+ cap-power-off-card;
+
+ brcmf: bcrmf@1 {
+ reg = <1>;
+ compatible = "brcm,bcm4329-fmac";
+ };
+};
diff --git a/arch/arm/boot/dts/imx7ulp-pinfunc.h b/arch/arm/boot/dts/imx7ulp-pinfunc.h
index fe511775b518..777d7f094751 100644
--- a/arch/arm/boot/dts/imx7ulp-pinfunc.h
+++ b/arch/arm/boot/dts/imx7ulp-pinfunc.h
@@ -1,6 +1,6 @@
/*
* Copyright 2016 Freescale Semiconductor, Inc.
- * Copyright 2017 NXP
+ * Copyright 2017 - 2018 NXP
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -15,234 +15,654 @@
* The pin function ID is a tuple of
* <mux_conf_reg input_reg mux_mode input_val>
*/
-
+#define IMX7ULP_PAD_PTA0__CMP0_IN1_3V 0x0000 0x0000 0x0 0x0
+#define IMX7ULP_PAD_PTA0__PTA0 0x0000 0x0000 0x1 0x0
+#define IMX7ULP_PAD_PTA0__LPSPI0_PCS1 0x0000 0x0104 0x3 0x2
+#define IMX7ULP_PAD_PTA0__LPUART0_CTS_B 0x0000 0x01F8 0x4 0x2
+#define IMX7ULP_PAD_PTA0__LPI2C0_SCL 0x0000 0x017C 0x5 0x2
+#define IMX7ULP_PAD_PTA0__TPM0_CLKIN 0x0000 0x01A8 0x6 0x2
+#define IMX7ULP_PAD_PTA0__I2S0_RX_BCLK 0x0000 0x01B8 0x7 0x2
+#define IMX7ULP_PAD_PTA0__LLWU0_P0 0x0000 0x0000 0xd 0x0
+#define IMX7ULP_PAD_PTA1__CMP0_IN2_3V 0x0004 0x0000 0x0 0x0
+#define IMX7ULP_PAD_PTA1__PTA1 0x0004 0x0000 0x1 0x0
+#define IMX7ULP_PAD_PTA1__LPSPI0_PCS2 0x0004 0x0108 0x3 0x1
+#define IMX7ULP_PAD_PTA1__LPUART0_RTS_B 0x0004 0x0000 0x4 0x0
+#define IMX7ULP_PAD_PTA1__LPI2C0_SDA 0x0004 0x0180 0x5 0x1
+#define IMX7ULP_PAD_PTA1__TPM0_CH0 0x0004 0x0138 0x6 0x1
+#define IMX7ULP_PAD_PTA1__I2S0_RX_FS 0x0004 0x01BC 0x7 0x1
+#define IMX7ULP_PAD_PTA2__CMP1_IN2_3V 0x0008 0x0000 0x0 0x0
+#define IMX7ULP_PAD_PTA2__PTA2 0x0008 0x0000 0x1 0x0
+#define IMX7ULP_PAD_PTA2__LPSPI0_PCS3 0x0008 0x010C 0x3 0x1
+#define IMX7ULP_PAD_PTA2__LPUART0_TX 0x0008 0x0200 0x4 0x1
+#define IMX7ULP_PAD_PTA2__LPI2C0_HREQ 0x0008 0x0178 0x5 0x1
+#define IMX7ULP_PAD_PTA2__TPM0_CH1 0x0008 0x013C 0x6 0x1
+#define IMX7ULP_PAD_PTA2__I2S0_RXD0 0x0008 0x01DC 0x7 0x1
+#define IMX7ULP_PAD_PTA3__CMP1_IN4_3V 0x000C 0x0000 0x0 0x0
+#define IMX7ULP_PAD_PTA3__PTA3 0x000C 0x0000 0x1 0x0
+#define IMX7ULP_PAD_PTA3__LPSPI0_PCS0 0x000C 0x0100 0x3 0x1
+#define IMX7ULP_PAD_PTA3__LPUART0_RX 0x000C 0x01FC 0x4 0x1
+#define IMX7ULP_PAD_PTA3__TPM0_CH2 0x000C 0x0140 0x6 0x1
+#define IMX7ULP_PAD_PTA3__I2S0_RXD1 0x000C 0x01E0 0x7 0x1
+#define IMX7ULP_PAD_PTA3__CMP0_OUT 0x000C 0x0000 0xb 0x0
+#define IMX7ULP_PAD_PTA3__LLWU0_P1 0x000C 0x0000 0xd 0x0
+#define IMX7ULP_PAD_PTA4__ADC1_CH3A 0x0010 0x0000 0x0 0x0
+#define IMX7ULP_PAD_PTA4__PTA4 0x0010 0x0000 0x1 0x0
+#define IMX7ULP_PAD_PTA4__LPSPI0_SIN 0x0010 0x0114 0x3 0x1
+#define IMX7ULP_PAD_PTA4__LPUART1_CTS_B 0x0010 0x0204 0x4 0x1
+#define IMX7ULP_PAD_PTA4__LPI2C1_SCL 0x0010 0x0188 0x5 0x1
+#define IMX7ULP_PAD_PTA4__TPM0_CH3 0x0010 0x0144 0x6 0x1
+#define IMX7ULP_PAD_PTA4__I2S0_MCLK 0x0010 0x01B4 0x7 0x1
+#define IMX7ULP_PAD_PTA5__ADC1_CH3B 0x0014 0x0000 0x0 0x0
+#define IMX7ULP_PAD_PTA5__PTA5 0x0014 0x0000 0x1 0x0
+#define IMX7ULP_PAD_PTA5__LPSPI0_SOUT 0x0014 0x0118 0x3 0x1
+#define IMX7ULP_PAD_PTA5__LPUART1_RTS_B 0x0014 0x0000 0x4 0x0
+#define IMX7ULP_PAD_PTA5__LPI2C1_SDA 0x0014 0x018C 0x5 0x1
+#define IMX7ULP_PAD_PTA5__TPM0_CH4 0x0014 0x0148 0x6 0x1
+#define IMX7ULP_PAD_PTA5__I2S0_TX_BCLK 0x0014 0x01C0 0x7 0x1
+#define IMX7ULP_PAD_PTA6__ADC1_CH4A 0x0018 0x0000 0x0 0x0
+#define IMX7ULP_PAD_PTA6__PTA6 0x0018 0x0000 0x1 0x0
+#define IMX7ULP_PAD_PTA6__LPSPI0_SCK 0x0018 0x0110 0x3 0x1
+#define IMX7ULP_PAD_PTA6__LPUART1_TX 0x0018 0x020C 0x4 0x1
+#define IMX7ULP_PAD_PTA6__LPI2C1_HREQ 0x0018 0x0184 0x5 0x1
+#define IMX7ULP_PAD_PTA6__TPM0_CH5 0x0018 0x014C 0x6 0x1
+#define IMX7ULP_PAD_PTA6__I2S0_TX_FS 0x0018 0x01C4 0x7 0x1
+#define IMX7ULP_PAD_PTA7__ADC1_CH4B 0x001C 0x0000 0x0 0x0
+#define IMX7ULP_PAD_PTA7__PTA7 0x001C 0x0000 0x1 0x0
+#define IMX7ULP_PAD_PTA7__LPUART1_RX 0x001C 0x0208 0x4 0x1
+#define IMX7ULP_PAD_PTA7__TPM1_CH1 0x001C 0x0154 0x6 0x1
+#define IMX7ULP_PAD_PTA7__I2S0_TXD0 0x001C 0x0000 0x7 0x0
+#define IMX7ULP_PAD_PTA8__ADC1_CH5A 0x0020 0x0000 0x0 0x0
+#define IMX7ULP_PAD_PTA8__PTA8 0x0020 0x0000 0x1 0x0
+#define IMX7ULP_PAD_PTA8__LPSPI1_PCS1 0x0020 0x0120 0x3 0x1
+#define IMX7ULP_PAD_PTA8__LPUART2_CTS_B 0x0020 0x0210 0x4 0x1
+#define IMX7ULP_PAD_PTA8__LPI2C2_SCL 0x0020 0x0194 0x5 0x1
+#define IMX7ULP_PAD_PTA8__TPM1_CLKIN 0x0020 0x01AC 0x6 0x1
+#define IMX7ULP_PAD_PTA8__I2S0_TXD1 0x0020 0x0000 0x7 0x0
+#define IMX7ULP_PAD_PTA9__ADC1_CH5B 0x0024 0x0000 0x0 0x0
+#define IMX7ULP_PAD_PTA9__PTA9 0x0024 0x0000 0x1 0x0
+#define IMX7ULP_PAD_PTA9__LPSPI1_PCS2 0x0024 0x0124 0x3 0x1
+#define IMX7ULP_PAD_PTA9__LPUART2_RTS_B 0x0024 0x0000 0x4 0x0
+#define IMX7ULP_PAD_PTA9__LPI2C2_SDA 0x0024 0x0198 0x5 0x1
+#define IMX7ULP_PAD_PTA9__TPM1_CH0 0x0024 0x0150 0x6 0x1
+#define IMX7ULP_PAD_PTA9__NMI0_B 0x0024 0x0000 0xb 0x0
+#define IMX7ULP_PAD_PTA10__ADC1_CH6A 0x0028 0x0000 0x0 0x0
+#define IMX7ULP_PAD_PTA10__PTA10 0x0028 0x0000 0x1 0x0
+#define IMX7ULP_PAD_PTA10__LPSPI1_PCS3 0x0028 0x0128 0x3 0x1
+#define IMX7ULP_PAD_PTA10__LPUART2_TX 0x0028 0x0218 0x4 0x1
+#define IMX7ULP_PAD_PTA10__LPI2C2_HREQ 0x0028 0x0190 0x5 0x1
+#define IMX7ULP_PAD_PTA10__TPM2_CLKIN 0x0028 0x01F4 0x6 0x1
+#define IMX7ULP_PAD_PTA10__I2S0_RX_BCLK 0x0028 0x01B8 0x7 0x1
+#define IMX7ULP_PAD_PTA11__ADC1_CH6B 0x002C 0x0000 0x0 0x0
+#define IMX7ULP_PAD_PTA11__PTA11 0x002C 0x0000 0x1 0x0
+#define IMX7ULP_PAD_PTA11__LPUART2_RX 0x002C 0x0214 0x4 0x1
+#define IMX7ULP_PAD_PTA11__TPM2_CH0 0x002C 0x0158 0x6 0x1
+#define IMX7ULP_PAD_PTA11__I2S0_RX_FS 0x002C 0x01BC 0x7 0x2
+#define IMX7ULP_PAD_PTA12__ADC1_CH7A 0x0030 0x0000 0x0 0x0
+#define IMX7ULP_PAD_PTA12__PTA12 0x0030 0x0000 0x1 0x0
+#define IMX7ULP_PAD_PTA12__LPSPI1_SIN 0x0030 0x0130 0x3 0x1
+#define IMX7ULP_PAD_PTA12__LPUART3_CTS_B 0x0030 0x021C 0x4 0x1
+#define IMX7ULP_PAD_PTA12__LPI2C3_SCL 0x0030 0x01A0 0x5 0x1
+#define IMX7ULP_PAD_PTA12__TPM2_CH1 0x0030 0x015C 0x6 0x1
+#define IMX7ULP_PAD_PTA12__I2S0_RXD0 0x0030 0x01DC 0x7 0x2
+#define IMX7ULP_PAD_PTA13__ADC1_CH7B 0x0034 0x0000 0x0 0x0
+#define IMX7ULP_PAD_PTA13__PTA13 0x0034 0x0000 0x1 0x0
+#define IMX7ULP_PAD_PTA13__LPSPI1_SOUT 0x0034 0x0134 0x3 0x2
+#define IMX7ULP_PAD_PTA13__LPUART3_RTS_B 0x0034 0x0000 0x4 0x0
+#define IMX7ULP_PAD_PTA13__LPI2C3_SDA 0x0034 0x01A4 0x5 0x2
+#define IMX7ULP_PAD_PTA13__TPM3_CLKIN 0x0034 0x01B0 0x6 0x1
+#define IMX7ULP_PAD_PTA13__I2S0_RXD1 0x0034 0x01E0 0x7 0x2
+#define IMX7ULP_PAD_PTA13__CMP0_OUT 0x0034 0x0000 0xb 0x0
+#define IMX7ULP_PAD_PTA13__LLWU0_P2 0x0034 0x0000 0xd 0x0
+#define IMX7ULP_PAD_PTA14__ADC1_CH8A 0x0038 0x0000 0x0 0x0
+#define IMX7ULP_PAD_PTA14__PTA14 0x0038 0x0000 0x1 0x0
+#define IMX7ULP_PAD_PTA14__LPSPI1_SCK 0x0038 0x012C 0x3 0x2
+#define IMX7ULP_PAD_PTA14__LPUART3_TX 0x0038 0x0224 0x4 0x2
+#define IMX7ULP_PAD_PTA14__LPI2C3_HREQ 0x0038 0x019C 0x5 0x2
+#define IMX7ULP_PAD_PTA14__TPM3_CH0 0x0038 0x0160 0x6 0x1
+#define IMX7ULP_PAD_PTA14__I2S0_MCLK 0x0038 0x01B4 0x7 0x2
+#define IMX7ULP_PAD_PTA14__LLWU0_P3 0x0038 0x0000 0xd 0x0
+#define IMX7ULP_PAD_PTA15__ADC1_CH8B 0x003C 0x0000 0x0 0x0
+#define IMX7ULP_PAD_PTA15__PTA15 0x003C 0x0000 0x1 0x0
+#define IMX7ULP_PAD_PTA15__LPSPI1_PCS0 0x003C 0x011C 0x3 0x1
+#define IMX7ULP_PAD_PTA15__LPUART3_RX 0x003C 0x0220 0x4 0x1
+#define IMX7ULP_PAD_PTA15__TPM3_CH1 0x003C 0x0164 0x6 0x1
+#define IMX7ULP_PAD_PTA15__I2S0_TX_BCLK 0x003C 0x01C0 0x7 0x2
+#define IMX7ULP_PAD_PTA16__CMP1_IN5_3V 0x0040 0x0000 0x0 0x0
+#define IMX7ULP_PAD_PTA16__PTA16 0x0040 0x0000 0x1 0x0
+#define IMX7ULP_PAD_PTA16__FXIO0_D0 0x0040 0x0000 0x2 0x0
+#define IMX7ULP_PAD_PTA16__LPSPI0_SOUT 0x0040 0x0118 0x3 0x2
+#define IMX7ULP_PAD_PTA16__LPUART0_CTS_B 0x0040 0x01F8 0x4 0x1
+#define IMX7ULP_PAD_PTA16__LPI2C0_SCL 0x0040 0x017C 0x5 0x1
+#define IMX7ULP_PAD_PTA16__TPM3_CH2 0x0040 0x0168 0x6 0x1
+#define IMX7ULP_PAD_PTA16__I2S0_TX_FS 0x0040 0x01C4 0x7 0x2
+#define IMX7ULP_PAD_PTA17__CMP1_IN6_3V 0x0044 0x0000 0x0 0x0
+#define IMX7ULP_PAD_PTA17__PTA17 0x0044 0x0000 0x1 0x0
+#define IMX7ULP_PAD_PTA17__FXIO0_D1 0x0044 0x0000 0x2 0x0
+#define IMX7ULP_PAD_PTA17__LPSPI0_SCK 0x0044 0x0110 0x3 0x2
+#define IMX7ULP_PAD_PTA17__LPUART0_RTS_B 0x0044 0x0000 0x4 0x0
+#define IMX7ULP_PAD_PTA17__LPI2C0_SDA 0x0044 0x0180 0x5 0x2
+#define IMX7ULP_PAD_PTA17__TPM3_CH3 0x0044 0x016C 0x6 0x1
+#define IMX7ULP_PAD_PTA17__I2S0_TXD0 0x0044 0x0000 0x7 0x0
+#define IMX7ULP_PAD_PTA18__CMP1_IN1_3V 0x0048 0x0000 0x0 0x0
+#define IMX7ULP_PAD_PTA18__PTA18 0x0048 0x0000 0x1 0x0
+#define IMX7ULP_PAD_PTA18__FXIO0_D2 0x0048 0x0000 0x2 0x0
+#define IMX7ULP_PAD_PTA18__LPSPI0_PCS0 0x0048 0x0100 0x3 0x2
+#define IMX7ULP_PAD_PTA18__LPUART0_TX 0x0048 0x0200 0x4 0x2
+#define IMX7ULP_PAD_PTA18__LPI2C0_HREQ 0x0048 0x0178 0x5 0x2
+#define IMX7ULP_PAD_PTA18__TPM3_CH4 0x0048 0x0170 0x6 0x1
+#define IMX7ULP_PAD_PTA18__I2S0_TXD1 0x0048 0x0000 0x7 0x0
+#define IMX7ULP_PAD_PTA18__LLWU0_P4 0x0048 0x0000 0xd 0x0
+#define IMX7ULP_PAD_PTA19__CMP1_IN3_3V 0x004C 0x0000 0x0 0x0
+#define IMX7ULP_PAD_PTA19__PTA19 0x004C 0x0000 0x1 0x0
+#define IMX7ULP_PAD_PTA19__FXIO0_D3 0x004C 0x0000 0x2 0x0
+#define IMX7ULP_PAD_PTA19__LPUART0_RX 0x004C 0x01FC 0x4 0x2
+#define IMX7ULP_PAD_PTA19__TPM3_CH5 0x004C 0x0174 0x6 0x1
+#define IMX7ULP_PAD_PTA19__I2S1_RX_BCLK 0x004C 0x01CC 0x7 0x1
+#define IMX7ULP_PAD_PTA19__LPTMR0_ALT3 0x004C 0x0000 0xb 0x0
+#define IMX7ULP_PAD_PTA19__LLWU0_P5 0x004C 0x0000 0xd 0x0
+#define IMX7ULP_PAD_PTA20__ADC0_CH10A 0x0050 0x0000 0x0 0x0
+#define IMX7ULP_PAD_PTA20__PTA20 0x0050 0x0000 0x1 0x0
+#define IMX7ULP_PAD_PTA20__FXIO0_D4 0x0050 0x0000 0x2 0x0
+#define IMX7ULP_PAD_PTA20__LPSPI0_SIN 0x0050 0x0114 0x3 0x2
+#define IMX7ULP_PAD_PTA20__LPUART1_CTS_B 0x0050 0x0204 0x4 0x2
+#define IMX7ULP_PAD_PTA20__LPI2C1_SCL 0x0050 0x0188 0x5 0x2
+#define IMX7ULP_PAD_PTA20__TPM0_CLKIN 0x0050 0x01A8 0x6 0x1
+#define IMX7ULP_PAD_PTA20__I2S1_RX_FS 0x0050 0x01D0 0x7 0x1
+#define IMX7ULP_PAD_PTA21__ADC0_CH10B 0x0054 0x0000 0x0 0x0
+#define IMX7ULP_PAD_PTA21__PTA21 0x0054 0x0000 0x1 0x0
+#define IMX7ULP_PAD_PTA21__FXIO0_D5 0x0054 0x0000 0x2 0x0
+#define IMX7ULP_PAD_PTA21__LPSPI0_PCS1 0x0054 0x0104 0x3 0x1
+#define IMX7ULP_PAD_PTA21__LPUART1_RTS_B 0x0054 0x0000 0x4 0x0
+#define IMX7ULP_PAD_PTA21__LPI2C1_SDA 0x0054 0x018C 0x5 0x2
+#define IMX7ULP_PAD_PTA21__TPM0_CH0 0x0054 0x0138 0x6 0x2
+#define IMX7ULP_PAD_PTA21__I2S1_RXD0 0x0054 0x01E4 0x7 0x1
+#define IMX7ULP_PAD_PTA22__ADC0_CH9A 0x0058 0x0000 0x0 0x0
+#define IMX7ULP_PAD_PTA22__PTA22 0x0058 0x0000 0x1 0x0
+#define IMX7ULP_PAD_PTA22__FXIO0_D6 0x0058 0x0000 0x2 0x0
+#define IMX7ULP_PAD_PTA22__LPSPI0_PCS2 0x0058 0x0108 0x3 0x2
+#define IMX7ULP_PAD_PTA22__LPUART1_TX 0x0058 0x020C 0x4 0x2
+#define IMX7ULP_PAD_PTA22__LPI2C1_HREQ 0x0058 0x0184 0x5 0x2
+#define IMX7ULP_PAD_PTA22__TPM0_CH1 0x0058 0x013C 0x6 0x2
+#define IMX7ULP_PAD_PTA22__I2S1_RXD1 0x0058 0x01E8 0x7 0x1
+#define IMX7ULP_PAD_PTA22__LPTMR0_ALT2 0x0058 0x0000 0xb 0x0
+#define IMX7ULP_PAD_PTA22__EWM_OUT_B 0x0058 0x0000 0xc 0x0
+#define IMX7ULP_PAD_PTA23__ADC0_CH9B 0x005C 0x0000 0x0 0x0
+#define IMX7ULP_PAD_PTA23__PTA23 0x005C 0x0000 0x1 0x0
+#define IMX7ULP_PAD_PTA23__FXIO0_D7 0x005C 0x0000 0x2 0x0
+#define IMX7ULP_PAD_PTA23__LPSPI0_PCS3 0x005C 0x010C 0x3 0x2
+#define IMX7ULP_PAD_PTA23__LPUART1_RX 0x005C 0x0208 0x4 0x2
+#define IMX7ULP_PAD_PTA23__TPM0_CH2 0x005C 0x0140 0x6 0x2
+#define IMX7ULP_PAD_PTA23__I2S1_MCLK 0x005C 0x01C8 0x7 0x1
+#define IMX7ULP_PAD_PTA23__LLWU0_P6 0x005C 0x0000 0xd 0x0
+#define IMX7ULP_PAD_PTA24__ADC0_CH8A 0x0060 0x0000 0x0 0x0
+#define IMX7ULP_PAD_PTA24__PTA24 0x0060 0x0000 0x1 0x0
+#define IMX7ULP_PAD_PTA24__FXIO0_D8 0x0060 0x0000 0x2 0x0
+#define IMX7ULP_PAD_PTA24__LPSPI1_PCS1 0x0060 0x0120 0x3 0x2
+#define IMX7ULP_PAD_PTA24__LPUART2_CTS_B 0x0060 0x0210 0x4 0x2
+#define IMX7ULP_PAD_PTA24__LPI2C2_SCL 0x0060 0x0194 0x5 0x2
+#define IMX7ULP_PAD_PTA24__TPM0_CH3 0x0060 0x0144 0x6 0x2
+#define IMX7ULP_PAD_PTA24__I2S1_TX_BCLK 0x0060 0x01D4 0x7 0x1
+#define IMX7ULP_PAD_PTA25__ADC0_CH8B 0x0064 0x0000 0x0 0x0
+#define IMX7ULP_PAD_PTA25__PTA25 0x0064 0x0000 0x1 0x0
+#define IMX7ULP_PAD_PTA25__FXIO0_D9 0x0064 0x0000 0x2 0x0
+#define IMX7ULP_PAD_PTA25__LPSPI1_PCS2 0x0064 0x0124 0x3 0x2
+#define IMX7ULP_PAD_PTA25__LPUART2_RTS_B 0x0064 0x0000 0x4 0x0
+#define IMX7ULP_PAD_PTA25__LPI2C2_SDA 0x0064 0x0198 0x5 0x2
+#define IMX7ULP_PAD_PTA25__TPM0_CH4 0x0064 0x0148 0x6 0x2
+#define IMX7ULP_PAD_PTA25__I2S1_TX_FS 0x0064 0x01D8 0x7 0x1
+#define IMX7ULP_PAD_PTA26__PTA26 0x0068 0x0000 0x1 0x0
+#define IMX7ULP_PAD_PTA26__JTAG_TMS_SWD_DIO 0x0068 0x0000 0xa 0x0
+#define IMX7ULP_PAD_PTA26__FXIO0_D10 0x0068 0x0000 0x2 0x0
+#define IMX7ULP_PAD_PTA26__LPSPI1_PCS3 0x0068 0x0128 0x3 0x2
+#define IMX7ULP_PAD_PTA26__LPUART2_TX 0x0068 0x0218 0x4 0x2
+#define IMX7ULP_PAD_PTA26__LPI2C2_HREQ 0x0068 0x0190 0x5 0x2
+#define IMX7ULP_PAD_PTA26__TPM0_CH5 0x0068 0x014C 0x6 0x2
+#define IMX7ULP_PAD_PTA26__I2S1_RXD2 0x0068 0x01EC 0x7 0x1
+#define IMX7ULP_PAD_PTA27__PTA27 0x006C 0x0000 0x1 0x0
+#define IMX7ULP_PAD_PTA27__JTAG_TDO 0x006C 0x0000 0xa 0x0
+#define IMX7ULP_PAD_PTA27__FXIO0_D11 0x006C 0x0000 0x2 0x0
+#define IMX7ULP_PAD_PTA27__LPUART2_RX 0x006C 0x0214 0x4 0x2
+#define IMX7ULP_PAD_PTA27__TPM1_CH1 0x006C 0x0154 0x6 0x2
+#define IMX7ULP_PAD_PTA27__I2S1_RXD3 0x006C 0x01F0 0x7 0x1
+#define IMX7ULP_PAD_PTA28__PTA28 0x0070 0x0000 0x1 0x0
+#define IMX7ULP_PAD_PTA28__JTAG_TDI 0x0070 0x0000 0xa 0x0
+#define IMX7ULP_PAD_PTA28__FXIO0_D12 0x0070 0x0000 0x2 0x0
+#define IMX7ULP_PAD_PTA28__LPSPI1_SIN 0x0070 0x0130 0x3 0x2
+#define IMX7ULP_PAD_PTA28__LPUART3_CTS_B 0x0070 0x021C 0x4 0x2
+#define IMX7ULP_PAD_PTA28__LPI2C3_SCL 0x0070 0x01A0 0x5 0x2
+#define IMX7ULP_PAD_PTA28__TPM1_CLKIN 0x0070 0x01AC 0x6 0x2
+#define IMX7ULP_PAD_PTA28__I2S1_TXD2 0x0070 0x0000 0x7 0x0
+#define IMX7ULP_PAD_PTA29__PTA29 0x0074 0x0000 0x1 0x0
+#define IMX7ULP_PAD_PTA29__JTAG_TCLK_SWD_CLK 0x0074 0x0000 0xa 0x0
+#define IMX7ULP_PAD_PTA29__FXIO0_D13 0x0074 0x0000 0x2 0x0
+#define IMX7ULP_PAD_PTA29__LPSPI1_SOUT 0x0074 0x0134 0x3 0x1
+#define IMX7ULP_PAD_PTA29__LPUART3_RTS_B 0x0074 0x0000 0x4 0x0
+#define IMX7ULP_PAD_PTA29__LPI2C3_SDA 0x0074 0x01A4 0x5 0x1
+#define IMX7ULP_PAD_PTA29__TPM1_CH0 0x0074 0x0150 0x6 0x2
+#define IMX7ULP_PAD_PTA29__I2S1_TXD3 0x0074 0x0000 0x7 0x0
+#define IMX7ULP_PAD_PTA30__ADC0_CH1A 0x0078 0x0000 0x0 0x0
+#define IMX7ULP_PAD_PTA30__PTA30 0x0078 0x0000 0x1 0x0
+#define IMX7ULP_PAD_PTA30__FXIO0_D14 0x0078 0x0000 0x2 0x0
+#define IMX7ULP_PAD_PTA30__LPSPI1_SCK 0x0078 0x012C 0x3 0x1
+#define IMX7ULP_PAD_PTA30__LPUART3_TX 0x0078 0x0224 0x4 0x1
+#define IMX7ULP_PAD_PTA30__LPI2C3_HREQ 0x0078 0x019C 0x5 0x1
+#define IMX7ULP_PAD_PTA30__TPM2_CLKIN 0x0078 0x01F4 0x6 0x2
+#define IMX7ULP_PAD_PTA30__I2S1_TXD0 0x0078 0x0000 0x7 0x0
+#define IMX7ULP_PAD_PTA30__JTAG_TRST_B 0x0078 0x0000 0xa 0x0
+#define IMX7ULP_PAD_PTA31__ADC0_CH1B 0x007C 0x0000 0x0 0x0
+#define IMX7ULP_PAD_PTA31__PTA31 0x007C 0x0000 0x1 0x0
+#define IMX7ULP_PAD_PTA31__FXIO0_D15 0x007C 0x0000 0x2 0x0
+#define IMX7ULP_PAD_PTA31__LPSPI1_PCS0 0x007C 0x011C 0x3 0x2
+#define IMX7ULP_PAD_PTA31__LPUART3_RX 0x007C 0x0220 0x4 0x2
+#define IMX7ULP_PAD_PTA31__TPM2_CH0 0x007C 0x0158 0x6 0x2
+#define IMX7ULP_PAD_PTA31__I2S1_TXD1 0x007C 0x0000 0x7 0x0
+#define IMX7ULP_PAD_PTA31__LPTMR0_ALT1 0x007C 0x0000 0xb 0x0
+#define IMX7ULP_PAD_PTA31__EWM_IN 0x007C 0x0228 0xc 0x1
+#define IMX7ULP_PAD_PTA31__LLWU0_P7 0x007C 0x0000 0xd 0x0
+#define IMX7ULP_PAD_PTB0__ADC0_CH0A 0x0080 0x0000 0x0 0x0
+#define IMX7ULP_PAD_PTB0__PTB0 0x0080 0x0000 0x1 0x0
+#define IMX7ULP_PAD_PTB0__FXIO0_D16 0x0080 0x0000 0x2 0x0
+#define IMX7ULP_PAD_PTB0__LPSPI0_SIN 0x0080 0x0114 0x3 0x3
+#define IMX7ULP_PAD_PTB0__LPUART0_TX 0x0080 0x0200 0x4 0x3
+#define IMX7ULP_PAD_PTB0__TPM2_CH1 0x0080 0x015C 0x6 0x2
+#define IMX7ULP_PAD_PTB0__CLKOUT0 0x0080 0x0000 0x9 0x0
+#define IMX7ULP_PAD_PTB0__CMP1_OUT 0x0080 0x0000 0xb 0x0
+#define IMX7ULP_PAD_PTB0__EWM_OUT_B 0x0080 0x0000 0xc 0x0
+#define IMX7ULP_PAD_PTB1__ADC0_CH0B 0x0084 0x0000 0x0 0x0
+#define IMX7ULP_PAD_PTB1__PTB1 0x0084 0x0000 0x1 0x0
+#define IMX7ULP_PAD_PTB1__FXIO0_D17 0x0084 0x0000 0x2 0x0
+#define IMX7ULP_PAD_PTB1__LPSPI0_SOUT 0x0084 0x0118 0x3 0x3
+#define IMX7ULP_PAD_PTB1__LPUART0_RX 0x0084 0x01FC 0x4 0x3
+#define IMX7ULP_PAD_PTB1__TPM3_CLKIN 0x0084 0x01B0 0x6 0x3
+#define IMX7ULP_PAD_PTB1__I2S1_TX_BCLK 0x0084 0x01D4 0x7 0x2
+#define IMX7ULP_PAD_PTB1__RTC_CLKOUT 0x0084 0x0000 0xb 0x0
+#define IMX7ULP_PAD_PTB1__EWM_IN 0x0084 0x0228 0xc 0x2
+#define IMX7ULP_PAD_PTB1__LLWU0_P8 0x0084 0x0000 0xd 0x0
+#define IMX7ULP_PAD_PTB2__ADC0_CH6A 0x0088 0x0000 0x0 0x0
+#define IMX7ULP_PAD_PTB2__PTB2 0x0088 0x0000 0x1 0x0
+#define IMX7ULP_PAD_PTB2__FXIO0_D18 0x0088 0x0000 0x2 0x0
+#define IMX7ULP_PAD_PTB2__LPSPI0_SCK 0x0088 0x0110 0x3 0x3
+#define IMX7ULP_PAD_PTB2__LPUART1_TX 0x0088 0x020C 0x4 0x3
+#define IMX7ULP_PAD_PTB2__TPM3_CH0 0x0088 0x0160 0x6 0x2
+#define IMX7ULP_PAD_PTB2__I2S1_TX_FS 0x0088 0x01D8 0x7 0x2
+#define IMX7ULP_PAD_PTB2__TRACE_CLKOUT 0x0088 0x0000 0xa 0x0
+#define IMX7ULP_PAD_PTB3__ADC0_CH6B 0x008C 0x0000 0x0 0x0
+#define IMX7ULP_PAD_PTB3__PTB3 0x008C 0x0000 0x1 0x0
+#define IMX7ULP_PAD_PTB3__FXIO0_D19 0x008C 0x0000 0x2 0x0
+#define IMX7ULP_PAD_PTB3__LPSPI0_PCS0 0x008C 0x0100 0x3 0x3
+#define IMX7ULP_PAD_PTB3__LPUART1_RX 0x008C 0x0208 0x4 0x3
+#define IMX7ULP_PAD_PTB3__TPM3_CH1 0x008C 0x0164 0x6 0x2
+#define IMX7ULP_PAD_PTB3__I2S1_TXD0 0x008C 0x0000 0x7 0x0
+#define IMX7ULP_PAD_PTB3__TRACE_D0 0x008C 0x0000 0xa 0x0
+#define IMX7ULP_PAD_PTB3__LPTMR1_ALT2 0x008C 0x0000 0xb 0x0
+#define IMX7ULP_PAD_PTB3__LLWU0_P9 0x008C 0x0000 0xd 0x0
+#define IMX7ULP_PAD_PTB4__PTB4 0x0090 0x0000 0x1 0x0
+#define IMX7ULP_PAD_PTB4__FXIO0_D20 0x0090 0x0000 0x2 0x0
+#define IMX7ULP_PAD_PTB4__LPSPI0_PCS1 0x0090 0x0104 0x3 0x3
+#define IMX7ULP_PAD_PTB4__LPUART2_TX 0x0090 0x0218 0x4 0x3
+#define IMX7ULP_PAD_PTB4__LPI2C0_HREQ 0x0090 0x0178 0x5 0x3
+#define IMX7ULP_PAD_PTB4__TPM3_CH2 0x0090 0x0168 0x6 0x2
+#define IMX7ULP_PAD_PTB4__I2S1_TXD1 0x0090 0x0000 0x7 0x0
+#define IMX7ULP_PAD_PTB4__QSPIA_DATA7 0x0090 0x0000 0x8 0x0
+#define IMX7ULP_PAD_PTB4__TRACE_D1 0x0090 0x0000 0xa 0x0
+#define IMX7ULP_PAD_PTB4__SEC_VIO_B 0x0090 0x0000 0xb 0x0
+#define IMX7ULP_PAD_PTB5__PTB5 0x0094 0x0000 0x1 0x0
+#define IMX7ULP_PAD_PTB5__FXIO0_D21 0x0094 0x0000 0x2 0x0
+#define IMX7ULP_PAD_PTB5__LPSPI0_PCS2 0x0094 0x0108 0x3 0x3
+#define IMX7ULP_PAD_PTB5__LPUART2_RX 0x0094 0x0214 0x4 0x3
+#define IMX7ULP_PAD_PTB5__LPI2C1_HREQ 0x0094 0x0184 0x5 0x3
+#define IMX7ULP_PAD_PTB5__TPM3_CH3 0x0094 0x016C 0x6 0x2
+#define IMX7ULP_PAD_PTB5__I2S1_TXD2 0x0094 0x0000 0x7 0x0
+#define IMX7ULP_PAD_PTB5__QSPIA_DATA6 0x0094 0x0000 0x8 0x0
+#define IMX7ULP_PAD_PTB5__TRACE_D2 0x0094 0x0000 0xa 0x0
+#define IMX7ULP_PAD_PTB5__RTC_CLKOUT 0x0094 0x0000 0xb 0x0
+#define IMX7ULP_PAD_PTB6__ADC1_CH1A 0x0098 0x0000 0x0 0x0
+#define IMX7ULP_PAD_PTB6__PTB6 0x0098 0x0000 0x1 0x0
+#define IMX7ULP_PAD_PTB6__FXIO0_D22 0x0098 0x0000 0x2 0x0
+#define IMX7ULP_PAD_PTB6__LPSPI0_PCS3 0x0098 0x010C 0x3 0x3
+#define IMX7ULP_PAD_PTB6__LPUART3_TX 0x0098 0x0224 0x4 0x3
+#define IMX7ULP_PAD_PTB6__LPI2C0_SCL 0x0098 0x017C 0x5 0x3
+#define IMX7ULP_PAD_PTB6__TPM3_CH4 0x0098 0x0170 0x6 0x2
+#define IMX7ULP_PAD_PTB6__I2S1_TXD3 0x0098 0x0000 0x7 0x0
+#define IMX7ULP_PAD_PTB6__QSPIA_DATA5 0x0098 0x0000 0x8 0x0
+#define IMX7ULP_PAD_PTB6__TRACE_D3 0x0098 0x0000 0xa 0x0
+#define IMX7ULP_PAD_PTB6__LPTMR1_ALT3 0x0098 0x0000 0xb 0x0
+#define IMX7ULP_PAD_PTB6__LLWU0_P10 0x0098 0x0000 0xd 0x0
+#define IMX7ULP_PAD_PTB7__ADC1_CH1B 0x009C 0x0000 0x0 0x0
+#define IMX7ULP_PAD_PTB7__PTB7 0x009C 0x0000 0x1 0x0
+#define IMX7ULP_PAD_PTB7__FXIO0_D23 0x009C 0x0000 0x2 0x0
+#define IMX7ULP_PAD_PTB7__LPSPI1_SIN 0x009C 0x0130 0x3 0x3
+#define IMX7ULP_PAD_PTB7__LPUART3_RX 0x009C 0x0220 0x4 0x3
+#define IMX7ULP_PAD_PTB7__LPI2C0_SDA 0x009C 0x0180 0x5 0x3
+#define IMX7ULP_PAD_PTB7__TPM3_CH5 0x009C 0x0174 0x6 0x2
+#define IMX7ULP_PAD_PTB7__I2S1_MCLK 0x009C 0x01C8 0x7 0x2
+#define IMX7ULP_PAD_PTB7__QSPIA_SS1_B 0x009C 0x0000 0x8 0x0
+#define IMX7ULP_PAD_PTB7__CMP1_OUT 0x009C 0x0000 0xb 0x0
+#define IMX7ULP_PAD_PTB7__LLWU0_P11 0x009C 0x0000 0xd 0x0
+#define IMX7ULP_PAD_PTB8__ADC0_CH14A_CMP0_IN0 0x00A0 0x0000 0x0 0x0
+#define IMX7ULP_PAD_PTB8__PTB8 0x00A0 0x0000 0x1 0x0
+#define IMX7ULP_PAD_PTB8__FXIO0_D24 0x00A0 0x0000 0x2 0x0
+#define IMX7ULP_PAD_PTB8__LPSPI1_SOUT 0x00A0 0x0134 0x3 0x3
+#define IMX7ULP_PAD_PTB8__LPI2C1_SCL 0x00A0 0x0188 0x5 0x3
+#define IMX7ULP_PAD_PTB8__TPM0_CLKIN 0x00A0 0x01A8 0x6 0x3
+#define IMX7ULP_PAD_PTB8__I2S1_RX_BCLK 0x00A0 0x01CC 0x7 0x2
+#define IMX7ULP_PAD_PTB8__QSPIA_SS0_B 0x00A0 0x0000 0x8 0x0
+#define IMX7ULP_PAD_PTB8__RTC_CLKOUT 0x00A0 0x0000 0xb 0x0
+#define IMX7ULP_PAD_PTB9__ADC0_CH14B_CMP0_IN2 0x00A4 0x0000 0x0 0x0
+#define IMX7ULP_PAD_PTB9__PTB9 0x00A4 0x0000 0x1 0x0
+#define IMX7ULP_PAD_PTB9__FXIO0_D25 0x00A4 0x0000 0x2 0x0
+#define IMX7ULP_PAD_PTB9__LPSPI1_SCK 0x00A4 0x012C 0x3 0x3
+#define IMX7ULP_PAD_PTB9__LPI2C1_SDA 0x00A4 0x018C 0x5 0x3
+#define IMX7ULP_PAD_PTB9__TPM0_CH0 0x00A4 0x0138 0x6 0x3
+#define IMX7ULP_PAD_PTB9__I2S1_RX_FS 0x00A4 0x01D0 0x7 0x2
+#define IMX7ULP_PAD_PTB9__QSPIA_DQS 0x00A4 0x0000 0x8 0x0
+#define IMX7ULP_PAD_PTB9__LLWU0_P12 0x00A4 0x0000 0xd 0x0
+#define IMX7ULP_PAD_PTB10__CMP0_IN1 0x00A8 0x0000 0x0 0x0
+#define IMX7ULP_PAD_PTB10__PTB10 0x00A8 0x0000 0x1 0x0
+#define IMX7ULP_PAD_PTB10__FXIO0_D26 0x00A8 0x0000 0x2 0x0
+#define IMX7ULP_PAD_PTB10__LPSPI1_PCS0 0x00A8 0x011C 0x3 0x3
+#define IMX7ULP_PAD_PTB10__LPI2C2_SCL 0x00A8 0x0194 0x5 0x3
+#define IMX7ULP_PAD_PTB10__TPM0_CH1 0x00A8 0x013C 0x6 0x3
+#define IMX7ULP_PAD_PTB10__I2S1_RXD0 0x00A8 0x01E4 0x7 0x2
+#define IMX7ULP_PAD_PTB10__TRACE_D4 0x00A8 0x0000 0xa 0x0
+#define IMX7ULP_PAD_PTB11__CMP0_IN3 0x00AC 0x0000 0x0 0x0
+#define IMX7ULP_PAD_PTB11__PTB11 0x00AC 0x0000 0x1 0x0
+#define IMX7ULP_PAD_PTB11__FXIO0_D27 0x00AC 0x0000 0x2 0x0
+#define IMX7ULP_PAD_PTB11__LPSPI1_PCS1 0x00AC 0x0120 0x3 0x3
+#define IMX7ULP_PAD_PTB11__LPI2C2_SDA 0x00AC 0x0198 0x5 0x3
+#define IMX7ULP_PAD_PTB11__TPM1_CLKIN 0x00AC 0x01AC 0x6 0x3
+#define IMX7ULP_PAD_PTB11__I2S1_RXD1 0x00AC 0x01E8 0x7 0x2
+#define IMX7ULP_PAD_PTB11__TRACE_D5 0x00AC 0x0000 0xa 0x0
+#define IMX7ULP_PAD_PTB12__ADC1_CH13A_CMP1_IN0 0x00B0 0x0000 0x0 0x0
+#define IMX7ULP_PAD_PTB12__PTB12 0x00B0 0x0000 0x1 0x0
+#define IMX7ULP_PAD_PTB12__FXIO0_D28 0x00B0 0x0000 0x2 0x0
+#define IMX7ULP_PAD_PTB12__LPSPI1_PCS2 0x00B0 0x0124 0x3 0x3
+#define IMX7ULP_PAD_PTB12__LPUART2_TX 0x00B0 0x0218 0x4 0x4
+#define IMX7ULP_PAD_PTB12__LPI2C3_SCL 0x00B0 0x01A0 0x5 0x3
+#define IMX7ULP_PAD_PTB12__TPM1_CH0 0x00B0 0x0150 0x6 0x3
+#define IMX7ULP_PAD_PTB12__I2S1_RXD2 0x00B0 0x01EC 0x7 0x2
+#define IMX7ULP_PAD_PTB12__TRACE_D6 0x00B0 0x0000 0xa 0x0
+#define IMX7ULP_PAD_PTB13__ADC1_CH13B_CMP1_IN1 0x00B4 0x0000 0x0 0x0
+#define IMX7ULP_PAD_PTB13__PTB13 0x00B4 0x0000 0x1 0x0
+#define IMX7ULP_PAD_PTB13__FXIO0_D29 0x00B4 0x0000 0x2 0x0
+#define IMX7ULP_PAD_PTB13__LPSPI1_PCS3 0x00B4 0x0128 0x3 0x3
+#define IMX7ULP_PAD_PTB13__LPUART2_RX 0x00B4 0x0214 0x4 0x4
+#define IMX7ULP_PAD_PTB13__LPI2C3_SDA 0x00B4 0x01A4 0x5 0x3
+#define IMX7ULP_PAD_PTB13__TPM1_CH1 0x00B4 0x0154 0x6 0x3
+#define IMX7ULP_PAD_PTB13__I2S1_RXD3 0x00B4 0x01F0 0x7 0x2
+#define IMX7ULP_PAD_PTB13__QSPIA_DATA4 0x00B4 0x0000 0x8 0x0
+#define IMX7ULP_PAD_PTB13__TRACE_D7 0x00B4 0x0000 0xa 0x0
+#define IMX7ULP_PAD_PTB14__ADC1_CH2A 0x00B8 0x0000 0x0 0x0
+#define IMX7ULP_PAD_PTB14__PTB14 0x00B8 0x0000 0x1 0x0
+#define IMX7ULP_PAD_PTB14__FXIO0_D30 0x00B8 0x0000 0x2 0x0
+#define IMX7ULP_PAD_PTB14__LPI2C2_HREQ 0x00B8 0x0190 0x5 0x3
+#define IMX7ULP_PAD_PTB14__TPM2_CLKIN 0x00B8 0x01F4 0x6 0x3
+#define IMX7ULP_PAD_PTB14__QSPIA_SS1_B 0x00B8 0x0000 0x8 0x0
+#define IMX7ULP_PAD_PTB14__QSPIA_SCLK_B 0x00B8 0x0000 0x9 0x0
+#define IMX7ULP_PAD_PTB14__RTC_CLKOUT 0x00B8 0x0000 0xb 0x0
+#define IMX7ULP_PAD_PTB14__LLWU0_P13 0x00B8 0x0000 0xd 0x0
+#define IMX7ULP_PAD_PTB15__ADC1_CH2B 0x00BC 0x0000 0x0 0x0
+#define IMX7ULP_PAD_PTB15__PTB15 0x00BC 0x0000 0x1 0x0
+#define IMX7ULP_PAD_PTB15__FXIO0_D31 0x00BC 0x0000 0x2 0x0
+#define IMX7ULP_PAD_PTB15__LPI2C3_HREQ 0x00BC 0x019C 0x5 0x3
+#define IMX7ULP_PAD_PTB15__TPM2_CH0 0x00BC 0x0158 0x6 0x3
+#define IMX7ULP_PAD_PTB15__QSPIA_SCLK 0x00BC 0x0000 0x8 0x0
+#define IMX7ULP_PAD_PTB16__ADC0_CH4A 0x00C0 0x0000 0x0 0x0
+#define IMX7ULP_PAD_PTB16__PTB16 0x00C0 0x0000 0x1 0x0
+#define IMX7ULP_PAD_PTB16__TPM2_CH1 0x00C0 0x015C 0x6 0x3
+#define IMX7ULP_PAD_PTB16__QSPIA_DATA3 0x00C0 0x0000 0x8 0x0
+#define IMX7ULP_PAD_PTB16__LLWU0_P14 0x00C0 0x0000 0xd 0x0
+#define IMX7ULP_PAD_PTB17__ADC0_CH4B 0x00C4 0x0000 0x0 0x0
+#define IMX7ULP_PAD_PTB17__PTB17 0x00C4 0x0000 0x1 0x0
+#define IMX7ULP_PAD_PTB17__TPM3_CLKIN 0x00C4 0x01B0 0x6 0x2
+#define IMX7ULP_PAD_PTB17__QSPIA_DATA2 0x00C4 0x0000 0x8 0x0
+#define IMX7ULP_PAD_PTB18__ADC0_CH5A 0x00C8 0x0000 0x0 0x0
+#define IMX7ULP_PAD_PTB18__PTB18 0x00C8 0x0000 0x1 0x0
+#define IMX7ULP_PAD_PTB18__TPM3_CH0 0x00C8 0x0160 0x6 0x3
+#define IMX7ULP_PAD_PTB18__QSPIA_DATA1 0x00C8 0x0000 0x8 0x0
+#define IMX7ULP_PAD_PTB19__ADC0_CH5B 0x00CC 0x0000 0x0 0x0
+#define IMX7ULP_PAD_PTB19__PTB19 0x00CC 0x0000 0x1 0x0
+#define IMX7ULP_PAD_PTB19__TPM3_CH1 0x00CC 0x0164 0x6 0x3
+#define IMX7ULP_PAD_PTB19__QSPIA_DATA0 0x00CC 0x0000 0x8 0x0
+#define IMX7ULP_PAD_PTB19__USB0_ID 0x00CC 0x0338 0xa 0x0
+#define IMX7ULP_PAD_PTB19__LLWU0_P15 0x00CC 0x0000 0xd 0x0
#define IMX7ULP_PAD_PTC0__PTC0 0x0000 0x0000 0x1 0x0
-#define IMX7ULP_PAD_PTC0__TRACE_D15 0x0000 0x0000 0xa 0x0
#define IMX7ULP_PAD_PTC0__LPUART4_CTS_B 0x0000 0x0244 0x4 0x1
#define IMX7ULP_PAD_PTC0__LPI2C4_SCL 0x0000 0x0278 0x5 0x1
#define IMX7ULP_PAD_PTC0__TPM4_CLKIN 0x0000 0x0298 0x6 0x1
#define IMX7ULP_PAD_PTC0__FB_AD0 0x0000 0x0000 0x9 0x0
+#define IMX7ULP_PAD_PTC0__TRACE_D15 0x0000 0x0000 0xa 0x0
#define IMX7ULP_PAD_PTC1__PTC1 0x0004 0x0000 0x1 0x0
-#define IMX7ULP_PAD_PTC1__TRACE_D14 0x0004 0x0000 0xa 0x0
#define IMX7ULP_PAD_PTC1__LPUART4_RTS_B 0x0004 0x0000 0x4 0x0
-#define IMX7ULP_PAD_PTC1__LPI2C4_SDA 0x0004 0x027c 0x5 0x1
+#define IMX7ULP_PAD_PTC1__LPI2C4_SDA 0x0004 0x027C 0x5 0x1
#define IMX7ULP_PAD_PTC1__TPM4_CH0 0x0004 0x0280 0x6 0x1
#define IMX7ULP_PAD_PTC1__FB_AD1 0x0004 0x0000 0x9 0x0
+#define IMX7ULP_PAD_PTC1__TRACE_D14 0x0004 0x0000 0xa 0x0
#define IMX7ULP_PAD_PTC2__PTC2 0x0008 0x0000 0x1 0x0
-#define IMX7ULP_PAD_PTC2__TRACE_D13 0x0008 0x0000 0xa 0x0
-#define IMX7ULP_PAD_PTC2__LPUART4_TX 0x0008 0x024c 0x4 0x1
+#define IMX7ULP_PAD_PTC2__LPUART4_TX 0x0008 0x024C 0x4 0x1
#define IMX7ULP_PAD_PTC2__LPI2C4_HREQ 0x0008 0x0274 0x5 0x1
#define IMX7ULP_PAD_PTC2__TPM4_CH1 0x0008 0x0284 0x6 0x1
#define IMX7ULP_PAD_PTC2__FB_AD2 0x0008 0x0000 0x9 0x0
-#define IMX7ULP_PAD_PTC3__PTC3 0x000c 0x0000 0x1 0x0
-#define IMX7ULP_PAD_PTC3__TRACE_D12 0x000c 0x0000 0xa 0x0
-#define IMX7ULP_PAD_PTC3__LPUART4_RX 0x000c 0x0248 0x4 0x1
-#define IMX7ULP_PAD_PTC3__TPM4_CH2 0x000c 0x0288 0x6 0x1
-#define IMX7ULP_PAD_PTC3__FB_AD3 0x000c 0x0000 0x9 0x0
+#define IMX7ULP_PAD_PTC2__TRACE_D13 0x0008 0x0000 0xa 0x0
+#define IMX7ULP_PAD_PTC3__PTC3 0x000C 0x0000 0x1 0x0
+#define IMX7ULP_PAD_PTC3__LPUART4_RX 0x000C 0x0248 0x4 0x1
+#define IMX7ULP_PAD_PTC3__TPM4_CH2 0x000C 0x0288 0x6 0x1
+#define IMX7ULP_PAD_PTC3__FB_AD3 0x000C 0x0000 0x9 0x0
+#define IMX7ULP_PAD_PTC3__TRACE_D12 0x000C 0x0000 0xa 0x0
#define IMX7ULP_PAD_PTC4__PTC4 0x0010 0x0000 0x1 0x0
-#define IMX7ULP_PAD_PTC4__TRACE_D11 0x0010 0x0000 0xa 0x0
#define IMX7ULP_PAD_PTC4__FXIO1_D0 0x0010 0x0204 0x2 0x1
-#define IMX7ULP_PAD_PTC4__LPSPI2_PCS1 0x0010 0x02a0 0x3 0x1
+#define IMX7ULP_PAD_PTC4__LPSPI2_PCS1 0x0010 0x02A0 0x3 0x1
#define IMX7ULP_PAD_PTC4__LPUART5_CTS_B 0x0010 0x0250 0x4 0x1
-#define IMX7ULP_PAD_PTC4__LPI2C5_SCL 0x0010 0x02bc 0x5 0x1
-#define IMX7ULP_PAD_PTC4__TPM4_CH3 0x0010 0x028c 0x6 0x1
+#define IMX7ULP_PAD_PTC4__LPI2C5_SCL 0x0010 0x02BC 0x5 0x1
+#define IMX7ULP_PAD_PTC4__TPM4_CH3 0x0010 0x028C 0x6 0x1
#define IMX7ULP_PAD_PTC4__FB_AD4 0x0010 0x0000 0x9 0x0
+#define IMX7ULP_PAD_PTC4__TRACE_D11 0x0010 0x0000 0xa 0x0
#define IMX7ULP_PAD_PTC5__PTC5 0x0014 0x0000 0x1 0x0
-#define IMX7ULP_PAD_PTC5__TRACE_D10 0x0014 0x0000 0xa 0x0
#define IMX7ULP_PAD_PTC5__FXIO1_D1 0x0014 0x0208 0x2 0x1
-#define IMX7ULP_PAD_PTC5__LPSPI2_PCS2 0x0014 0x02a4 0x3 0x1
+#define IMX7ULP_PAD_PTC5__LPSPI2_PCS2 0x0014 0x02A4 0x3 0x1
#define IMX7ULP_PAD_PTC5__LPUART5_RTS_B 0x0014 0x0000 0x4 0x0
-#define IMX7ULP_PAD_PTC5__LPI2C5_SDA 0x0014 0x02c0 0x5 0x1
+#define IMX7ULP_PAD_PTC5__LPI2C5_SDA 0x0014 0x02C0 0x5 0x1
#define IMX7ULP_PAD_PTC5__TPM4_CH4 0x0014 0x0290 0x6 0x1
#define IMX7ULP_PAD_PTC5__FB_AD5 0x0014 0x0000 0x9 0x0
+#define IMX7ULP_PAD_PTC5__TRACE_D10 0x0014 0x0000 0xa 0x0
#define IMX7ULP_PAD_PTC6__PTC6 0x0018 0x0000 0x1 0x0
-#define IMX7ULP_PAD_PTC6__TRACE_D9 0x0018 0x0000 0xa 0x0
-#define IMX7ULP_PAD_PTC6__FXIO1_D2 0x0018 0x020c 0x2 0x1
-#define IMX7ULP_PAD_PTC6__LPSPI2_PCS3 0x0018 0x02a8 0x3 0x1
+#define IMX7ULP_PAD_PTC6__FXIO1_D2 0x0018 0x020C 0x2 0x1
+#define IMX7ULP_PAD_PTC6__LPSPI2_PCS3 0x0018 0x02A8 0x3 0x1
#define IMX7ULP_PAD_PTC6__LPUART5_TX 0x0018 0x0258 0x4 0x1
-#define IMX7ULP_PAD_PTC6__LPI2C5_HREQ 0x0018 0x02b8 0x5 0x1
+#define IMX7ULP_PAD_PTC6__LPI2C5_HREQ 0x0018 0x02B8 0x5 0x1
#define IMX7ULP_PAD_PTC6__TPM4_CH5 0x0018 0x0294 0x6 0x1
#define IMX7ULP_PAD_PTC6__FB_AD6 0x0018 0x0000 0x9 0x0
-#define IMX7ULP_PAD_PTC7__PTC7 0x001c 0x0000 0x1 0x0
-#define IMX7ULP_PAD_PTC7__TRACE_D8 0x001c 0x0000 0xa 0x0
-#define IMX7ULP_PAD_PTC7__FXIO1_D3 0x001c 0x0210 0x2 0x1
-#define IMX7ULP_PAD_PTC7__LPUART5_RX 0x001c 0x0254 0x4 0x1
-#define IMX7ULP_PAD_PTC7__TPM5_CH1 0x001c 0x02c8 0x6 0x1
-#define IMX7ULP_PAD_PTC7__FB_AD7 0x001c 0x0000 0x9 0x0
+#define IMX7ULP_PAD_PTC6__TRACE_D9 0x0018 0x0000 0xa 0x0
+#define IMX7ULP_PAD_PTC7__PTC7 0x001C 0x0000 0x1 0x0
+#define IMX7ULP_PAD_PTC7__FXIO1_D3 0x001C 0x0210 0x2 0x1
+#define IMX7ULP_PAD_PTC7__LPUART5_RX 0x001C 0x0254 0x4 0x1
+#define IMX7ULP_PAD_PTC7__TPM5_CH1 0x001C 0x02C8 0x6 0x1
+#define IMX7ULP_PAD_PTC7__FB_AD7 0x001C 0x0000 0x9 0x0
+#define IMX7ULP_PAD_PTC7__TRACE_D8 0x001C 0x0000 0xa 0x0
#define IMX7ULP_PAD_PTC8__PTC8 0x0020 0x0000 0x1 0x0
-#define IMX7ULP_PAD_PTC8__TRACE_D7 0x0020 0x0000 0xa 0x0
#define IMX7ULP_PAD_PTC8__FXIO1_D4 0x0020 0x0214 0x2 0x1
-#define IMX7ULP_PAD_PTC8__LPSPI2_SIN 0x0020 0x02b0 0x3 0x1
-#define IMX7ULP_PAD_PTC8__LPUART6_CTS_B 0x0020 0x025c 0x4 0x1
-#define IMX7ULP_PAD_PTC8__LPI2C6_SCL 0x0020 0x02fc 0x5 0x1
-#define IMX7ULP_PAD_PTC8__TPM5_CLKIN 0x0020 0x02cc 0x6 0x1
+#define IMX7ULP_PAD_PTC8__LPSPI2_SIN 0x0020 0x02B0 0x3 0x1
+#define IMX7ULP_PAD_PTC8__LPUART6_CTS_B 0x0020 0x025C 0x4 0x1
+#define IMX7ULP_PAD_PTC8__LPI2C6_SCL 0x0020 0x02FC 0x5 0x1
+#define IMX7ULP_PAD_PTC8__TPM5_CLKIN 0x0020 0x02CC 0x6 0x1
#define IMX7ULP_PAD_PTC8__FB_AD8 0x0020 0x0000 0x9 0x0
+#define IMX7ULP_PAD_PTC8__TRACE_D7 0x0020 0x0000 0xa 0x0
#define IMX7ULP_PAD_PTC9__PTC9 0x0024 0x0000 0x1 0x0
-#define IMX7ULP_PAD_PTC9__TRACE_D6 0x0024 0x0000 0xa 0x0
#define IMX7ULP_PAD_PTC9__FXIO1_D5 0x0024 0x0218 0x2 0x1
-#define IMX7ULP_PAD_PTC9__LPSPI2_SOUT 0x0024 0x02b4 0x3 0x1
+#define IMX7ULP_PAD_PTC9__LPSPI2_SOUT 0x0024 0x02B4 0x3 0x1
#define IMX7ULP_PAD_PTC9__LPUART6_RTS_B 0x0024 0x0000 0x4 0x0
#define IMX7ULP_PAD_PTC9__LPI2C6_SDA 0x0024 0x0300 0x5 0x1
-#define IMX7ULP_PAD_PTC9__TPM5_CH0 0x0024 0x02c4 0x6 0x1
+#define IMX7ULP_PAD_PTC9__TPM5_CH0 0x0024 0x02C4 0x6 0x1
#define IMX7ULP_PAD_PTC9__FB_AD9 0x0024 0x0000 0x9 0x0
+#define IMX7ULP_PAD_PTC9__TRACE_D6 0x0024 0x0000 0xa 0x0
#define IMX7ULP_PAD_PTC10__PTC10 0x0028 0x0000 0x1 0x0
-#define IMX7ULP_PAD_PTC10__TRACE_D5 0x0028 0x0000 0xa 0x0
-#define IMX7ULP_PAD_PTC10__FXIO1_D6 0x0028 0x021c 0x2 0x1
-#define IMX7ULP_PAD_PTC10__LPSPI2_SCK 0x0028 0x02ac 0x3 0x1
+#define IMX7ULP_PAD_PTC10__FXIO1_D6 0x0028 0x021C 0x2 0x1
+#define IMX7ULP_PAD_PTC10__LPSPI2_SCK 0x0028 0x02AC 0x3 0x1
#define IMX7ULP_PAD_PTC10__LPUART6_TX 0x0028 0x0264 0x4 0x1
-#define IMX7ULP_PAD_PTC10__LPI2C6_HREQ 0x0028 0x02f8 0x5 0x1
-#define IMX7ULP_PAD_PTC10__TPM7_CH3 0x0028 0x02e8 0x6 0x1
+#define IMX7ULP_PAD_PTC10__LPI2C6_HREQ 0x0028 0x02F8 0x5 0x1
+#define IMX7ULP_PAD_PTC10__TPM7_CH3 0x0028 0x02E8 0x6 0x1
#define IMX7ULP_PAD_PTC10__FB_AD10 0x0028 0x0000 0x9 0x0
-#define IMX7ULP_PAD_PTC11__PTC11 0x002c 0x0000 0x1 0x0
-#define IMX7ULP_PAD_PTC11__TRACE_D4 0x002c 0x0000 0xa 0x0
-#define IMX7ULP_PAD_PTC11__FXIO1_D7 0x002c 0x0220 0x2 0x1
-#define IMX7ULP_PAD_PTC11__LPSPI2_PCS0 0x002c 0x029c 0x3 0x1
-#define IMX7ULP_PAD_PTC11__LPUART6_RX 0x002c 0x0260 0x4 0x1
-#define IMX7ULP_PAD_PTC11__TPM7_CH4 0x002c 0x02ec 0x6 0x1
-#define IMX7ULP_PAD_PTC11__FB_AD11 0x002c 0x0000 0x9 0x0
+#define IMX7ULP_PAD_PTC10__TRACE_D5 0x0028 0x0000 0xa 0x0
+#define IMX7ULP_PAD_PTC11__PTC11 0x002C 0x0000 0x1 0x0
+#define IMX7ULP_PAD_PTC11__FXIO1_D7 0x002C 0x0220 0x2 0x1
+#define IMX7ULP_PAD_PTC11__LPSPI2_PCS0 0x002C 0x029C 0x3 0x1
+#define IMX7ULP_PAD_PTC11__LPUART6_RX 0x002C 0x0260 0x4 0x1
+#define IMX7ULP_PAD_PTC11__TPM7_CH4 0x002C 0x02EC 0x6 0x1
+#define IMX7ULP_PAD_PTC11__FB_AD11 0x002C 0x0000 0x9 0x0
+#define IMX7ULP_PAD_PTC11__TRACE_D4 0x002C 0x0000 0xa 0x0
#define IMX7ULP_PAD_PTC12__PTC12 0x0030 0x0000 0x1 0x0
-#define IMX7ULP_PAD_PTC12__TRACE_D3 0x0030 0x0000 0xa 0x0
#define IMX7ULP_PAD_PTC12__FXIO1_D8 0x0030 0x0224 0x2 0x1
#define IMX7ULP_PAD_PTC12__LPSPI3_PCS1 0x0030 0x0314 0x3 0x1
#define IMX7ULP_PAD_PTC12__LPUART7_CTS_B 0x0030 0x0268 0x4 0x1
#define IMX7ULP_PAD_PTC12__LPI2C7_SCL 0x0030 0x0308 0x5 0x1
-#define IMX7ULP_PAD_PTC12__TPM7_CH5 0x0030 0x02f0 0x6 0x1
+#define IMX7ULP_PAD_PTC12__TPM7_CH5 0x0030 0x02F0 0x6 0x1
#define IMX7ULP_PAD_PTC12__FB_AD12 0x0030 0x0000 0x9 0x0
+#define IMX7ULP_PAD_PTC12__TRACE_D3 0x0030 0x0000 0xa 0x0
#define IMX7ULP_PAD_PTC13__PTC13 0x0034 0x0000 0x1 0x0
-#define IMX7ULP_PAD_PTC13__TRACE_D2 0x0034 0x0000 0xa 0x0
#define IMX7ULP_PAD_PTC13__FXIO1_D9 0x0034 0x0228 0x2 0x1
#define IMX7ULP_PAD_PTC13__LPSPI3_PCS2 0x0034 0x0318 0x3 0x1
#define IMX7ULP_PAD_PTC13__LPUART7_RTS_B 0x0034 0x0000 0x4 0x0
-#define IMX7ULP_PAD_PTC13__LPI2C7_SDA 0x0034 0x030c 0x5 0x1
-#define IMX7ULP_PAD_PTC13__TPM7_CLKIN 0x0034 0x02f4 0x6 0x1
+#define IMX7ULP_PAD_PTC13__LPI2C7_SDA 0x0034 0x030C 0x5 0x1
+#define IMX7ULP_PAD_PTC13__TPM7_CLKIN 0x0034 0x02F4 0x6 0x1
#define IMX7ULP_PAD_PTC13__FB_AD13 0x0034 0x0000 0x9 0x0
+#define IMX7ULP_PAD_PTC13__TRACE_D2 0x0034 0x0000 0xa 0x0
+#define IMX7ULP_PAD_PTC13__USB0_ID 0x0034 0x0338 0xb 0x1
#define IMX7ULP_PAD_PTC14__PTC14 0x0038 0x0000 0x1 0x0
-#define IMX7ULP_PAD_PTC14__TRACE_D1 0x0038 0x0000 0xa 0x0
-#define IMX7ULP_PAD_PTC14__FXIO1_D10 0x0038 0x022c 0x2 0x1
-#define IMX7ULP_PAD_PTC14__LPSPI3_PCS3 0x0038 0x031c 0x3 0x1
+#define IMX7ULP_PAD_PTC14__FXIO1_D10 0x0038 0x022C 0x2 0x1
+#define IMX7ULP_PAD_PTC14__LPSPI3_PCS3 0x0038 0x031C 0x3 0x1
#define IMX7ULP_PAD_PTC14__LPUART7_TX 0x0038 0x0270 0x4 0x1
#define IMX7ULP_PAD_PTC14__LPI2C7_HREQ 0x0038 0x0304 0x5 0x1
-#define IMX7ULP_PAD_PTC14__TPM7_CH0 0x0038 0x02dc 0x6 0x1
+#define IMX7ULP_PAD_PTC14__TPM7_CH0 0x0038 0x02DC 0x6 0x1
#define IMX7ULP_PAD_PTC14__FB_AD14 0x0038 0x0000 0x9 0x0
-#define IMX7ULP_PAD_PTC15__PTC15 0x003c 0x0000 0x1 0x0
-#define IMX7ULP_PAD_PTC15__TRACE_D0 0x003c 0x0000 0xa 0x0
-#define IMX7ULP_PAD_PTC15__FXIO1_D11 0x003c 0x0230 0x2 0x1
-#define IMX7ULP_PAD_PTC15__LPUART7_RX 0x003c 0x026c 0x4 0x1
-#define IMX7ULP_PAD_PTC15__TPM7_CH1 0x003c 0x02e0 0x6 0x1
-#define IMX7ULP_PAD_PTC15__FB_AD15 0x003c 0x0000 0x9 0x0
+#define IMX7ULP_PAD_PTC14__TRACE_D1 0x0038 0x0000 0xa 0x0
+#define IMX7ULP_PAD_PTC15__PTC15 0x003C 0x0000 0x1 0x0
+#define IMX7ULP_PAD_PTC15__FXIO1_D11 0x003C 0x0230 0x2 0x1
+#define IMX7ULP_PAD_PTC15__LPUART7_RX 0x003C 0x026C 0x4 0x1
+#define IMX7ULP_PAD_PTC15__TPM7_CH1 0x003C 0x02E0 0x6 0x1
+#define IMX7ULP_PAD_PTC15__FB_AD15 0x003C 0x0000 0x9 0x0
+#define IMX7ULP_PAD_PTC15__TRACE_D0 0x003C 0x0000 0xa 0x0
#define IMX7ULP_PAD_PTC16__PTC16 0x0040 0x0000 0x1 0x0
-#define IMX7ULP_PAD_PTC16__TRACE_CLKOUT 0x0040 0x0000 0xa 0x0
#define IMX7ULP_PAD_PTC16__FXIO1_D12 0x0040 0x0234 0x2 0x1
#define IMX7ULP_PAD_PTC16__LPSPI3_SIN 0x0040 0x0324 0x3 0x1
-#define IMX7ULP_PAD_PTC16__TPM7_CH2 0x0040 0x02e4 0x6 0x1
+#define IMX7ULP_PAD_PTC16__TPM7_CH2 0x0040 0x02E4 0x6 0x1
#define IMX7ULP_PAD_PTC16__FB_ALE_FB_CS1_B_FB_TS_B 0x0040 0x0000 0x9 0x0
+#define IMX7ULP_PAD_PTC16__TRACE_CLKOUT 0x0040 0x0000 0xa 0x0
+#define IMX7ULP_PAD_PTC16__USB1_OC2 0x0040 0x0334 0xb 0x1
#define IMX7ULP_PAD_PTC17__PTC17 0x0044 0x0000 0x1 0x0
#define IMX7ULP_PAD_PTC17__FXIO1_D13 0x0044 0x0238 0x2 0x1
#define IMX7ULP_PAD_PTC17__LPSPI3_SOUT 0x0044 0x0328 0x3 0x1
-#define IMX7ULP_PAD_PTC17__TPM6_CLKIN 0x0044 0x02d8 0x6 0x1
+#define IMX7ULP_PAD_PTC17__TPM6_CLKIN 0x0044 0x02D8 0x6 0x1
#define IMX7ULP_PAD_PTC17__FB_CS0_B 0x0044 0x0000 0x9 0x0
#define IMX7ULP_PAD_PTC18__PTC18 0x0048 0x0000 0x1 0x0
-#define IMX7ULP_PAD_PTC18__FXIO1_D14 0x0048 0x023c 0x2 0x1
+#define IMX7ULP_PAD_PTC18__FXIO1_D14 0x0048 0x023C 0x2 0x1
#define IMX7ULP_PAD_PTC18__LPSPI3_SCK 0x0048 0x0320 0x3 0x1
-#define IMX7ULP_PAD_PTC18__TPM6_CH0 0x0048 0x02d0 0x6 0x1
+#define IMX7ULP_PAD_PTC18__TPM6_CH0 0x0048 0x02D0 0x6 0x1
#define IMX7ULP_PAD_PTC18__FB_OE_B 0x0048 0x0000 0x9 0x0
-#define IMX7ULP_PAD_PTC19__PTC19 0x004c 0x0000 0x1 0x0
-#define IMX7ULP_PAD_PTC19__FXIO1_D15 0x004c 0x0240 0x2 0x1
-#define IMX7ULP_PAD_PTC19__LPSPI3_PCS0 0x004c 0x0310 0x3 0x1
-#define IMX7ULP_PAD_PTC19__TPM6_CH1 0x004c 0x02d4 0x6 0x1
-#define IMX7ULP_PAD_PTC19__FB_A16 0x004c 0x0000 0x9 0x0
+#define IMX7ULP_PAD_PTC18__USB0_ID 0x0048 0x0338 0xb 0x2
+#define IMX7ULP_PAD_PTC18__VIU_DE 0x0048 0x033C 0xc 0x1
+#define IMX7ULP_PAD_PTC19__PTC19 0x004C 0x0000 0x1 0x0
+#define IMX7ULP_PAD_PTC19__FXIO1_D15 0x004C 0x0240 0x2 0x1
+#define IMX7ULP_PAD_PTC19__LPSPI3_PCS0 0x004C 0x0310 0x3 0x1
+#define IMX7ULP_PAD_PTC19__TPM6_CH1 0x004C 0x02D4 0x6 0x1
+#define IMX7ULP_PAD_PTC19__FB_A16 0x004C 0x0000 0x9 0x0
+#define IMX7ULP_PAD_PTC19__USB0_ID 0x004C 0x0338 0xa 0x3
+#define IMX7ULP_PAD_PTC19__USB1_PWR2 0x004C 0x0000 0xb 0x0
+#define IMX7ULP_PAD_PTC19__VIU_DE 0x004C 0x033C 0xc 0x3
#define IMX7ULP_PAD_PTD0__PTD0 0x0080 0x0000 0x1 0x0
#define IMX7ULP_PAD_PTD0__SDHC0_RESET_B 0x0080 0x0000 0x8 0x0
#define IMX7ULP_PAD_PTD1__PTD1 0x0084 0x0000 0x1 0x0
#define IMX7ULP_PAD_PTD1__SDHC0_CMD 0x0084 0x0000 0x8 0x0
#define IMX7ULP_PAD_PTD2__PTD2 0x0088 0x0000 0x1 0x0
#define IMX7ULP_PAD_PTD2__SDHC0_CLK 0x0088 0x0000 0x8 0x0
-#define IMX7ULP_PAD_PTD3__PTD3 0x008c 0x0000 0x1 0x0
-#define IMX7ULP_PAD_PTD3__SDHC0_D7 0x008c 0x0000 0x8 0x0
+#define IMX7ULP_PAD_PTD3__PTD3 0x008C 0x0000 0x1 0x0
+#define IMX7ULP_PAD_PTD3__SDHC0_D7 0x008C 0x0000 0x8 0x0
#define IMX7ULP_PAD_PTD4__PTD4 0x0090 0x0000 0x1 0x0
#define IMX7ULP_PAD_PTD4__SDHC0_D6 0x0090 0x0000 0x8 0x0
#define IMX7ULP_PAD_PTD5__PTD5 0x0094 0x0000 0x1 0x0
#define IMX7ULP_PAD_PTD5__SDHC0_D5 0x0094 0x0000 0x8 0x0
#define IMX7ULP_PAD_PTD6__PTD6 0x0098 0x0000 0x1 0x0
#define IMX7ULP_PAD_PTD6__SDHC0_D4 0x0098 0x0000 0x8 0x0
-#define IMX7ULP_PAD_PTD7__PTD7 0x009c 0x0000 0x1 0x0
-#define IMX7ULP_PAD_PTD7__SDHC0_D3 0x009c 0x0000 0x8 0x0
-#define IMX7ULP_PAD_PTD8__PTD8 0x00a0 0x0000 0x1 0x0
-#define IMX7ULP_PAD_PTD8__TPM4_CLKIN 0x00a0 0x0298 0x6 0x2
-#define IMX7ULP_PAD_PTD8__SDHC0_D2 0x00a0 0x0000 0x8 0x0
-#define IMX7ULP_PAD_PTD9__PTD9 0x00a4 0x0000 0x1 0x0
-#define IMX7ULP_PAD_PTD9__TPM4_CH0 0x00a4 0x0280 0x6 0x2
-#define IMX7ULP_PAD_PTD9__SDHC0_D1 0x00a4 0x0000 0x8 0x0
-#define IMX7ULP_PAD_PTD10__PTD10 0x00a8 0x0000 0x1 0x0
-#define IMX7ULP_PAD_PTD10__TPM4_CH1 0x00a8 0x0284 0x6 0x2
-#define IMX7ULP_PAD_PTD10__SDHC0_D0 0x00a8 0x0000 0x8 0x0
-#define IMX7ULP_PAD_PTD11__PTD11 0x00ac 0x0000 0x1 0x0
-#define IMX7ULP_PAD_PTD11__TPM4_CH2 0x00ac 0x0288 0x6 0x2
-#define IMX7ULP_PAD_PTD11__SDHC0_DQS 0x00ac 0x0000 0x8 0x0
+#define IMX7ULP_PAD_PTD7__PTD7 0x009C 0x0000 0x1 0x0
+#define IMX7ULP_PAD_PTD7__SDHC0_D3 0x009C 0x0000 0x8 0x0
+#define IMX7ULP_PAD_PTD8__PTD8 0x00A0 0x0000 0x1 0x0
+#define IMX7ULP_PAD_PTD8__TPM4_CLKIN 0x00A0 0x0298 0x6 0x2
+#define IMX7ULP_PAD_PTD8__SDHC0_D2 0x00A0 0x0000 0x8 0x0
+#define IMX7ULP_PAD_PTD9__PTD9 0x00A4 0x0000 0x1 0x0
+#define IMX7ULP_PAD_PTD9__TPM4_CH0 0x00A4 0x0280 0x6 0x2
+#define IMX7ULP_PAD_PTD9__SDHC0_D1 0x00A4 0x0000 0x8 0x0
+#define IMX7ULP_PAD_PTD10__PTD10 0x00A8 0x0000 0x1 0x0
+#define IMX7ULP_PAD_PTD10__TPM4_CH1 0x00A8 0x0284 0x6 0x2
+#define IMX7ULP_PAD_PTD10__SDHC0_D0 0x00A8 0x0000 0x8 0x0
+#define IMX7ULP_PAD_PTD11__PTD11 0x00AC 0x0000 0x1 0x0
+#define IMX7ULP_PAD_PTD11__TPM4_CH2 0x00AC 0x0288 0x6 0x2
+#define IMX7ULP_PAD_PTD11__SDHC0_DQS 0x00AC 0x0000 0x8 0x0
#define IMX7ULP_PAD_PTE0__PTE0 0x0100 0x0000 0x1 0x0
#define IMX7ULP_PAD_PTE0__FXIO1_D31 0x0100 0x0000 0x2 0x0
-#define IMX7ULP_PAD_PTE0__LPSPI2_PCS1 0x0100 0x02a0 0x3 0x2
+#define IMX7ULP_PAD_PTE0__LPSPI2_PCS1 0x0100 0x02A0 0x3 0x2
#define IMX7ULP_PAD_PTE0__LPUART4_CTS_B 0x0100 0x0244 0x4 0x2
#define IMX7ULP_PAD_PTE0__LPI2C4_SCL 0x0100 0x0278 0x5 0x2
#define IMX7ULP_PAD_PTE0__SDHC1_D1 0x0100 0x0000 0x8 0x0
#define IMX7ULP_PAD_PTE0__FB_A25 0x0100 0x0000 0x9 0x0
#define IMX7ULP_PAD_PTE1__PTE1 0x0104 0x0000 0x1 0x0
#define IMX7ULP_PAD_PTE1__FXIO1_D30 0x0104 0x0000 0x2 0x0
-#define IMX7ULP_PAD_PTE1__LPSPI2_PCS2 0x0104 0x02a4 0x3 0x2
+#define IMX7ULP_PAD_PTE1__LPSPI2_PCS2 0x0104 0x02A4 0x3 0x2
#define IMX7ULP_PAD_PTE1__LPUART4_RTS_B 0x0104 0x0000 0x4 0x0
-#define IMX7ULP_PAD_PTE1__LPI2C4_SDA 0x0104 0x027c 0x5 0x2
+#define IMX7ULP_PAD_PTE1__LPI2C4_SDA 0x0104 0x027C 0x5 0x2
#define IMX7ULP_PAD_PTE1__SDHC1_D0 0x0104 0x0000 0x8 0x0
#define IMX7ULP_PAD_PTE1__FB_A26 0x0104 0x0000 0x9 0x0
#define IMX7ULP_PAD_PTE2__PTE2 0x0108 0x0000 0x1 0x0
#define IMX7ULP_PAD_PTE2__FXIO1_D29 0x0108 0x0000 0x2 0x0
-#define IMX7ULP_PAD_PTE2__LPSPI2_PCS3 0x0108 0x02a8 0x3 0x2
-#define IMX7ULP_PAD_PTE2__LPUART4_TX 0x0108 0x024c 0x4 0x2
+#define IMX7ULP_PAD_PTE2__LPSPI2_PCS3 0x0108 0x02A8 0x3 0x2
+#define IMX7ULP_PAD_PTE2__LPUART4_TX 0x0108 0x024C 0x4 0x2
#define IMX7ULP_PAD_PTE2__LPI2C4_HREQ 0x0108 0x0274 0x5 0x2
#define IMX7ULP_PAD_PTE2__SDHC1_CLK 0x0108 0x0000 0x8 0x0
-#define IMX7ULP_PAD_PTE3__PTE3 0x010c 0x0000 0x1 0x0
-#define IMX7ULP_PAD_PTE3__FXIO1_D28 0x010c 0x0000 0x2 0x0
-#define IMX7ULP_PAD_PTE3__LPUART4_RX 0x010c 0x0248 0x4 0x2
-#define IMX7ULP_PAD_PTE3__TPM5_CH1 0x010c 0x02c8 0x6 0x2
-#define IMX7ULP_PAD_PTE3__SDHC1_CMD 0x010c 0x0000 0x8 0x0
+#define IMX7ULP_PAD_PTE3__PTE3 0x010C 0x0000 0x1 0x0
+#define IMX7ULP_PAD_PTE3__FXIO1_D28 0x010C 0x0000 0x2 0x0
+#define IMX7ULP_PAD_PTE3__LPUART4_RX 0x010C 0x0248 0x4 0x2
+#define IMX7ULP_PAD_PTE3__TPM5_CH1 0x010C 0x02C8 0x6 0x2
+#define IMX7ULP_PAD_PTE3__SDHC1_CMD 0x010C 0x0000 0x8 0x0
#define IMX7ULP_PAD_PTE4__PTE4 0x0110 0x0000 0x1 0x0
#define IMX7ULP_PAD_PTE4__FXIO1_D27 0x0110 0x0000 0x2 0x0
-#define IMX7ULP_PAD_PTE4__LPSPI2_SIN 0x0110 0x02b0 0x3 0x2
+#define IMX7ULP_PAD_PTE4__LPSPI2_SIN 0x0110 0x02B0 0x3 0x2
#define IMX7ULP_PAD_PTE4__LPUART5_CTS_B 0x0110 0x0250 0x4 0x2
-#define IMX7ULP_PAD_PTE4__LPI2C5_SCL 0x0110 0x02bc 0x5 0x2
-#define IMX7ULP_PAD_PTE4__TPM5_CLKIN 0x0110 0x02cc 0x6 0x2
+#define IMX7ULP_PAD_PTE4__LPI2C5_SCL 0x0110 0x02BC 0x5 0x2
+#define IMX7ULP_PAD_PTE4__TPM5_CLKIN 0x0110 0x02CC 0x6 0x2
#define IMX7ULP_PAD_PTE4__SDHC1_D3 0x0110 0x0000 0x8 0x0
#define IMX7ULP_PAD_PTE5__PTE5 0x0114 0x0000 0x1 0x0
#define IMX7ULP_PAD_PTE5__FXIO1_D26 0x0114 0x0000 0x2 0x0
-#define IMX7ULP_PAD_PTE5__LPSPI2_SOUT 0x0114 0x02b4 0x3 0x2
+#define IMX7ULP_PAD_PTE5__LPSPI2_SOUT 0x0114 0x02B4 0x3 0x2
#define IMX7ULP_PAD_PTE5__LPUART5_RTS_B 0x0114 0x0000 0x4 0x0
-#define IMX7ULP_PAD_PTE5__LPI2C5_SDA 0x0114 0x02c0 0x5 0x2
-#define IMX7ULP_PAD_PTE5__TPM5_CH0 0x0114 0x02c4 0x6 0x2
+#define IMX7ULP_PAD_PTE5__LPI2C5_SDA 0x0114 0x02C0 0x5 0x2
+#define IMX7ULP_PAD_PTE5__TPM5_CH0 0x0114 0x02C4 0x6 0x2
#define IMX7ULP_PAD_PTE5__SDHC1_D2 0x0114 0x0000 0x8 0x0
+#define IMX7ULP_PAD_PTE5__VIU_DE 0x0114 0x033C 0xc 0x2
#define IMX7ULP_PAD_PTE6__PTE6 0x0118 0x0000 0x1 0x0
#define IMX7ULP_PAD_PTE6__FXIO1_D25 0x0118 0x0000 0x2 0x0
-#define IMX7ULP_PAD_PTE6__LPSPI2_SCK 0x0118 0x02ac 0x3 0x2
+#define IMX7ULP_PAD_PTE6__LPSPI2_SCK 0x0118 0x02AC 0x3 0x2
#define IMX7ULP_PAD_PTE6__LPUART5_TX 0x0118 0x0258 0x4 0x2
-#define IMX7ULP_PAD_PTE6__LPI2C5_HREQ 0x0118 0x02b8 0x5 0x2
-#define IMX7ULP_PAD_PTE6__TPM7_CH3 0x0118 0x02e8 0x6 0x2
+#define IMX7ULP_PAD_PTE6__LPI2C5_HREQ 0x0118 0x02B8 0x5 0x2
+#define IMX7ULP_PAD_PTE6__TPM7_CH3 0x0118 0x02E8 0x6 0x2
#define IMX7ULP_PAD_PTE6__SDHC1_D4 0x0118 0x0000 0x8 0x0
#define IMX7ULP_PAD_PTE6__FB_A17 0x0118 0x0000 0x9 0x0
-#define IMX7ULP_PAD_PTE7__PTE7 0x011c 0x0000 0x1 0x0
-#define IMX7ULP_PAD_PTE7__TRACE_D7 0x011c 0x0000 0xa 0x0
-#define IMX7ULP_PAD_PTE7__VIU_FID 0x011c 0x0000 0xc 0x0
-#define IMX7ULP_PAD_PTE7__FXIO1_D24 0x011c 0x0000 0x2 0x0
-#define IMX7ULP_PAD_PTE7__LPSPI2_PCS0 0x011c 0x029c 0x3 0x2
-#define IMX7ULP_PAD_PTE7__LPUART5_RX 0x011c 0x0254 0x4 0x2
-#define IMX7ULP_PAD_PTE7__TPM7_CH4 0x011c 0x02ec 0x6 0x2
-#define IMX7ULP_PAD_PTE7__SDHC1_D5 0x011c 0x0000 0x8 0x0
-#define IMX7ULP_PAD_PTE7__FB_A18 0x011c 0x0000 0x9 0x0
+#define IMX7ULP_PAD_PTE6__USB0_OC 0x0118 0x0330 0xb 0x1
+#define IMX7ULP_PAD_PTE7__PTE7 0x011C 0x0000 0x1 0x0
+#define IMX7ULP_PAD_PTE7__FXIO1_D24 0x011C 0x0000 0x2 0x0
+#define IMX7ULP_PAD_PTE7__LPSPI2_PCS0 0x011C 0x029C 0x3 0x2
+#define IMX7ULP_PAD_PTE7__LPUART5_RX 0x011C 0x0254 0x4 0x2
+#define IMX7ULP_PAD_PTE7__TPM7_CH4 0x011C 0x02EC 0x6 0x2
+#define IMX7ULP_PAD_PTE7__SDHC1_D5 0x011C 0x0000 0x8 0x0
+#define IMX7ULP_PAD_PTE7__FB_A18 0x011C 0x0000 0x9 0x0
+#define IMX7ULP_PAD_PTE7__TRACE_D7 0x011C 0x0000 0xa 0x0
+#define IMX7ULP_PAD_PTE7__USB0_PWR 0x011C 0x0000 0xb 0x0
+#define IMX7ULP_PAD_PTE7__VIU_FID 0x011C 0x0000 0xc 0x0
#define IMX7ULP_PAD_PTE8__PTE8 0x0120 0x0000 0x1 0x0
#define IMX7ULP_PAD_PTE8__TRACE_D6 0x0120 0x0000 0xa 0x0
#define IMX7ULP_PAD_PTE8__VIU_D16 0x0120 0x0000 0xc 0x0
#define IMX7ULP_PAD_PTE8__FXIO1_D23 0x0120 0x0000 0x2 0x0
#define IMX7ULP_PAD_PTE8__LPSPI3_PCS1 0x0120 0x0314 0x3 0x2
-#define IMX7ULP_PAD_PTE8__LPUART6_CTS_B 0x0120 0x025c 0x4 0x2
-#define IMX7ULP_PAD_PTE8__LPI2C6_SCL 0x0120 0x02fc 0x5 0x2
-#define IMX7ULP_PAD_PTE8__TPM7_CH5 0x0120 0x02f0 0x6 0x2
+#define IMX7ULP_PAD_PTE8__LPUART6_CTS_B 0x0120 0x025C 0x4 0x2
+#define IMX7ULP_PAD_PTE8__LPI2C6_SCL 0x0120 0x02FC 0x5 0x2
+#define IMX7ULP_PAD_PTE8__TPM7_CH5 0x0120 0x02F0 0x6 0x2
#define IMX7ULP_PAD_PTE8__SDHC1_WP 0x0120 0x0200 0x7 0x1
#define IMX7ULP_PAD_PTE8__SDHC1_D6 0x0120 0x0000 0x8 0x0
#define IMX7ULP_PAD_PTE8__FB_CS3_B_FB_BE7_0_BLS31_24_B 0x0120 0x0000 0x9 0x0
@@ -253,216 +673,220 @@
#define IMX7ULP_PAD_PTE9__LPSPI3_PCS2 0x0124 0x0318 0x3 0x2
#define IMX7ULP_PAD_PTE9__LPUART6_RTS_B 0x0124 0x0000 0x4 0x0
#define IMX7ULP_PAD_PTE9__LPI2C6_SDA 0x0124 0x0300 0x5 0x2
-#define IMX7ULP_PAD_PTE9__TPM7_CLKIN 0x0124 0x02f4 0x6 0x2
-#define IMX7ULP_PAD_PTE9__SDHC1_CD 0x0124 0x032c 0x7 0x1
+#define IMX7ULP_PAD_PTE9__TPM7_CLKIN 0x0124 0x02F4 0x6 0x2
+#define IMX7ULP_PAD_PTE9__SDHC1_CD 0x0124 0x032C 0x7 0x1
#define IMX7ULP_PAD_PTE9__SDHC1_D7 0x0124 0x0000 0x8 0x0
#define IMX7ULP_PAD_PTE9__FB_TBST_B_FB_CS2_B_FB_BE15_8_BLS23_16_B 0x0124 0x0000 0x9 0x0
#define IMX7ULP_PAD_PTE10__PTE10 0x0128 0x0000 0x1 0x0
#define IMX7ULP_PAD_PTE10__TRACE_D4 0x0128 0x0000 0xa 0x0
#define IMX7ULP_PAD_PTE10__VIU_D18 0x0128 0x0000 0xc 0x0
#define IMX7ULP_PAD_PTE10__FXIO1_D21 0x0128 0x0000 0x2 0x0
-#define IMX7ULP_PAD_PTE10__LPSPI3_PCS3 0x0128 0x031c 0x3 0x2
+#define IMX7ULP_PAD_PTE10__LPSPI3_PCS3 0x0128 0x031C 0x3 0x2
#define IMX7ULP_PAD_PTE10__LPUART6_TX 0x0128 0x0264 0x4 0x2
-#define IMX7ULP_PAD_PTE10__LPI2C6_HREQ 0x0128 0x02f8 0x5 0x2
-#define IMX7ULP_PAD_PTE10__TPM7_CH0 0x0128 0x02dc 0x6 0x2
+#define IMX7ULP_PAD_PTE10__LPI2C6_HREQ 0x0128 0x02F8 0x5 0x2
+#define IMX7ULP_PAD_PTE10__TPM7_CH0 0x0128 0x02DC 0x6 0x2
#define IMX7ULP_PAD_PTE10__SDHC1_VS 0x0128 0x0000 0x7 0x0
#define IMX7ULP_PAD_PTE10__SDHC1_DQS 0x0128 0x0000 0x8 0x0
#define IMX7ULP_PAD_PTE10__FB_A19 0x0128 0x0000 0x9 0x0
-#define IMX7ULP_PAD_PTE11__PTE11 0x012c 0x0000 0x1 0x0
-#define IMX7ULP_PAD_PTE11__TRACE_D3 0x012c 0x0000 0xa 0x0
-#define IMX7ULP_PAD_PTE11__VIU_D19 0x012c 0x0000 0xc 0x0
-#define IMX7ULP_PAD_PTE11__FXIO1_D20 0x012c 0x0000 0x2 0x0
-#define IMX7ULP_PAD_PTE11__LPUART6_RX 0x012c 0x0260 0x4 0x2
-#define IMX7ULP_PAD_PTE11__TPM7_CH1 0x012c 0x02e0 0x6 0x2
-#define IMX7ULP_PAD_PTE11__SDHC1_RESET_B 0x012c 0x0000 0x8 0x0
-#define IMX7ULP_PAD_PTE11__FB_A20 0x012c 0x0000 0x9 0x0
+#define IMX7ULP_PAD_PTE11__PTE11 0x012C 0x0000 0x1 0x0
+#define IMX7ULP_PAD_PTE11__TRACE_D3 0x012C 0x0000 0xa 0x0
+#define IMX7ULP_PAD_PTE11__VIU_D19 0x012C 0x0000 0xc 0x0
+#define IMX7ULP_PAD_PTE11__FXIO1_D20 0x012C 0x0000 0x2 0x0
+#define IMX7ULP_PAD_PTE11__LPUART6_RX 0x012C 0x0260 0x4 0x2
+#define IMX7ULP_PAD_PTE11__TPM7_CH1 0x012C 0x02E0 0x6 0x2
+#define IMX7ULP_PAD_PTE11__SDHC1_RESET_B 0x012C 0x0000 0x8 0x0
+#define IMX7ULP_PAD_PTE11__FB_A20 0x012C 0x0000 0x9 0x0
#define IMX7ULP_PAD_PTE12__PTE12 0x0130 0x0000 0x1 0x0
-#define IMX7ULP_PAD_PTE12__TRACE_D2 0x0130 0x0000 0xa 0x0
-#define IMX7ULP_PAD_PTE12__VIU_D20 0x0130 0x0000 0xc 0x0
#define IMX7ULP_PAD_PTE12__FXIO1_D19 0x0130 0x0000 0x2 0x0
#define IMX7ULP_PAD_PTE12__LPSPI3_SIN 0x0130 0x0324 0x3 0x2
#define IMX7ULP_PAD_PTE12__LPUART7_CTS_B 0x0130 0x0268 0x4 0x2
#define IMX7ULP_PAD_PTE12__LPI2C7_SCL 0x0130 0x0308 0x5 0x2
-#define IMX7ULP_PAD_PTE12__TPM7_CH2 0x0130 0x02e4 0x6 0x2
+#define IMX7ULP_PAD_PTE12__TPM7_CH2 0x0130 0x02E4 0x6 0x2
#define IMX7ULP_PAD_PTE12__SDHC1_WP 0x0130 0x0200 0x8 0x2
#define IMX7ULP_PAD_PTE12__FB_A21 0x0130 0x0000 0x9 0x0
+#define IMX7ULP_PAD_PTE12__TRACE_D2 0x0130 0x0000 0xa 0x0
+#define IMX7ULP_PAD_PTE12__USB1_OC2 0x0130 0x0334 0xb 0x2
+#define IMX7ULP_PAD_PTE12__VIU_D20 0x0130 0x0000 0xc 0x0
#define IMX7ULP_PAD_PTE13__PTE13 0x0134 0x0000 0x1 0x0
-#define IMX7ULP_PAD_PTE13__TRACE_D1 0x0134 0x0000 0xa 0x0
-#define IMX7ULP_PAD_PTE13__VIU_D21 0x0134 0x0000 0xc 0x0
#define IMX7ULP_PAD_PTE13__FXIO1_D18 0x0134 0x0000 0x2 0x0
#define IMX7ULP_PAD_PTE13__LPSPI3_SOUT 0x0134 0x0328 0x3 0x2
#define IMX7ULP_PAD_PTE13__LPUART7_RTS_B 0x0134 0x0000 0x4 0x0
-#define IMX7ULP_PAD_PTE13__LPI2C7_SDA 0x0134 0x030c 0x5 0x2
-#define IMX7ULP_PAD_PTE13__TPM6_CLKIN 0x0134 0x02d8 0x6 0x2
-#define IMX7ULP_PAD_PTE13__SDHC1_CD 0x0134 0x032c 0x8 0x2
+#define IMX7ULP_PAD_PTE13__LPI2C7_SDA 0x0134 0x030C 0x5 0x2
+#define IMX7ULP_PAD_PTE13__TPM6_CLKIN 0x0134 0x02D8 0x6 0x2
+#define IMX7ULP_PAD_PTE13__SDHC1_CD 0x0134 0x032C 0x8 0x2
#define IMX7ULP_PAD_PTE13__FB_A22 0x0134 0x0000 0x9 0x0
+#define IMX7ULP_PAD_PTE13__TRACE_D1 0x0134 0x0000 0xa 0x0
+#define IMX7ULP_PAD_PTE13__USB1_PWR2 0x0134 0x0000 0xb 0x0
+#define IMX7ULP_PAD_PTE13__VIU_D21 0x0134 0x0000 0xc 0x0
#define IMX7ULP_PAD_PTE14__PTE14 0x0138 0x0000 0x1 0x0
-#define IMX7ULP_PAD_PTE14__TRACE_D0 0x0138 0x0000 0xa 0x0
-#define IMX7ULP_PAD_PTE14__VIU_D22 0x0138 0x0000 0xc 0x0
#define IMX7ULP_PAD_PTE14__FXIO1_D17 0x0138 0x0000 0x2 0x0
#define IMX7ULP_PAD_PTE14__LPSPI3_SCK 0x0138 0x0320 0x3 0x2
#define IMX7ULP_PAD_PTE14__LPUART7_TX 0x0138 0x0270 0x4 0x2
#define IMX7ULP_PAD_PTE14__LPI2C7_HREQ 0x0138 0x0304 0x5 0x2
-#define IMX7ULP_PAD_PTE14__TPM6_CH0 0x0138 0x02d0 0x6 0x2
+#define IMX7ULP_PAD_PTE14__TPM6_CH0 0x0138 0x02D0 0x6 0x2
#define IMX7ULP_PAD_PTE14__SDHC1_VS 0x0138 0x0000 0x8 0x0
#define IMX7ULP_PAD_PTE14__FB_A23 0x0138 0x0000 0x9 0x0
-#define IMX7ULP_PAD_PTE15__PTE15 0x013c 0x0000 0x1 0x0
-#define IMX7ULP_PAD_PTE15__TRACE_CLKOUT 0x013c 0x0000 0xa 0x0
-#define IMX7ULP_PAD_PTE15__VIU_D23 0x013c 0x0000 0xc 0x0
-#define IMX7ULP_PAD_PTE15__FXIO1_D16 0x013c 0x0000 0x2 0x0
-#define IMX7ULP_PAD_PTE15__LPSPI3_PCS0 0x013c 0x0310 0x3 0x2
-#define IMX7ULP_PAD_PTE15__LPUART7_RX 0x013c 0x026c 0x4 0x2
-#define IMX7ULP_PAD_PTE15__TPM6_CH1 0x013c 0x02d4 0x6 0x2
-#define IMX7ULP_PAD_PTE15__FB_A24 0x013c 0x0000 0x9 0x0
+#define IMX7ULP_PAD_PTE14__TRACE_D0 0x0138 0x0000 0xa 0x0
+#define IMX7ULP_PAD_PTE14__USB0_OC 0x0138 0x0330 0xb 0x2
+#define IMX7ULP_PAD_PTE14__VIU_D22 0x0138 0x0000 0xc 0x0
+#define IMX7ULP_PAD_PTE15__PTE15 0x013C 0x0000 0x1 0x0
+#define IMX7ULP_PAD_PTE15__FXIO1_D16 0x013C 0x0000 0x2 0x0
+#define IMX7ULP_PAD_PTE15__LPSPI3_PCS0 0x013C 0x0310 0x3 0x2
+#define IMX7ULP_PAD_PTE15__LPUART7_RX 0x013C 0x026C 0x4 0x2
+#define IMX7ULP_PAD_PTE15__TPM6_CH1 0x013C 0x02D4 0x6 0x2
+#define IMX7ULP_PAD_PTE15__FB_A24 0x013C 0x0000 0x9 0x0
+#define IMX7ULP_PAD_PTE15__TRACE_CLKOUT 0x013C 0x0000 0xa 0x0
+#define IMX7ULP_PAD_PTE15__USB0_PWR 0x013C 0x0000 0xb 0x0
+#define IMX7ULP_PAD_PTE15__VIU_D23 0x013C 0x0000 0xc 0x0
#define IMX7ULP_PAD_PTF0__PTF0 0x0180 0x0000 0x1 0x0
-#define IMX7ULP_PAD_PTF0__VIU_DE 0x0180 0x0000 0xc 0x0
#define IMX7ULP_PAD_PTF0__LPUART4_CTS_B 0x0180 0x0244 0x4 0x3
#define IMX7ULP_PAD_PTF0__LPI2C4_SCL 0x0180 0x0278 0x5 0x3
#define IMX7ULP_PAD_PTF0__TPM4_CLKIN 0x0180 0x0298 0x6 0x3
#define IMX7ULP_PAD_PTF0__FB_RW_B 0x0180 0x0000 0x9 0x0
+#define IMX7ULP_PAD_PTF0__VIU_DE 0x0180 0x033C 0xc 0x0
#define IMX7ULP_PAD_PTF1__PTF1 0x0184 0x0000 0x1 0x0
-#define IMX7ULP_PAD_PTF1__VIU_HSYNC 0x0184 0x0000 0xc 0x0
#define IMX7ULP_PAD_PTF1__LPUART4_RTS_B 0x0184 0x0000 0x4 0x0
-#define IMX7ULP_PAD_PTF1__LPI2C4_SDA 0x0184 0x027c 0x5 0x3
+#define IMX7ULP_PAD_PTF1__LPI2C4_SDA 0x0184 0x027C 0x5 0x3
#define IMX7ULP_PAD_PTF1__TPM4_CH0 0x0184 0x0280 0x6 0x3
#define IMX7ULP_PAD_PTF1__CLKOUT 0x0184 0x0000 0x9 0x0
+#define IMX7ULP_PAD_PTF1__VIU_HSYNC 0x0184 0x0000 0xc 0x0
#define IMX7ULP_PAD_PTF2__PTF2 0x0188 0x0000 0x1 0x0
-#define IMX7ULP_PAD_PTF2__VIU_VSYNC 0x0188 0x0000 0xc 0x0
-#define IMX7ULP_PAD_PTF2__LPUART4_TX 0x0188 0x024c 0x4 0x3
+#define IMX7ULP_PAD_PTF2__LPUART4_TX 0x0188 0x024C 0x4 0x3
#define IMX7ULP_PAD_PTF2__LPI2C4_HREQ 0x0188 0x0274 0x5 0x3
#define IMX7ULP_PAD_PTF2__TPM4_CH1 0x0188 0x0284 0x6 0x3
#define IMX7ULP_PAD_PTF2__FB_TSIZ1_FB_CS5_B_FB_BE23_16_BLS15_8_B 0x0188 0x0000 0x9 0x0
-#define IMX7ULP_PAD_PTF3__PTF3 0x018c 0x0000 0x1 0x0
-#define IMX7ULP_PAD_PTF3__VIU_PCLK 0x018c 0x0000 0xc 0x0
-#define IMX7ULP_PAD_PTF3__LPUART4_RX 0x018c 0x0248 0x4 0x3
-#define IMX7ULP_PAD_PTF3__TPM4_CH2 0x018c 0x0288 0x6 0x3
-#define IMX7ULP_PAD_PTF3__FB_AD16 0x018c 0x0000 0x9 0x0
+#define IMX7ULP_PAD_PTF2__VIU_VSYNC 0x0188 0x0000 0xc 0x0
+#define IMX7ULP_PAD_PTF3__PTF3 0x018C 0x0000 0x1 0x0
+#define IMX7ULP_PAD_PTF3__LPUART4_RX 0x018C 0x0248 0x4 0x3
+#define IMX7ULP_PAD_PTF3__TPM4_CH2 0x018C 0x0288 0x6 0x3
+#define IMX7ULP_PAD_PTF3__FB_AD16 0x018C 0x0000 0x9 0x0
+#define IMX7ULP_PAD_PTF3__VIU_PCLK 0x018C 0x0000 0xc 0x0
#define IMX7ULP_PAD_PTF4__PTF4 0x0190 0x0000 0x1 0x0
-#define IMX7ULP_PAD_PTF4__VIU_D0 0x0190 0x0000 0xc 0x0
#define IMX7ULP_PAD_PTF4__FXIO1_D0 0x0190 0x0204 0x2 0x2
-#define IMX7ULP_PAD_PTF4__LPSPI2_PCS1 0x0190 0x02a0 0x3 0x3
+#define IMX7ULP_PAD_PTF4__LPSPI2_PCS1 0x0190 0x02A0 0x3 0x3
#define IMX7ULP_PAD_PTF4__LPUART5_CTS_B 0x0190 0x0250 0x4 0x3
-#define IMX7ULP_PAD_PTF4__LPI2C5_SCL 0x0190 0x02bc 0x5 0x3
-#define IMX7ULP_PAD_PTF4__TPM4_CH3 0x0190 0x028c 0x6 0x2
+#define IMX7ULP_PAD_PTF4__LPI2C5_SCL 0x0190 0x02BC 0x5 0x3
+#define IMX7ULP_PAD_PTF4__TPM4_CH3 0x0190 0x028C 0x6 0x2
#define IMX7ULP_PAD_PTF4__FB_AD17 0x0190 0x0000 0x9 0x0
+#define IMX7ULP_PAD_PTF4__VIU_D0 0x0190 0x0000 0xc 0x0
#define IMX7ULP_PAD_PTF5__PTF5 0x0194 0x0000 0x1 0x0
-#define IMX7ULP_PAD_PTF5__VIU_D1 0x0194 0x0000 0xc 0x0
#define IMX7ULP_PAD_PTF5__FXIO1_D1 0x0194 0x0208 0x2 0x2
-#define IMX7ULP_PAD_PTF5__LPSPI2_PCS2 0x0194 0x02a4 0x3 0x3
+#define IMX7ULP_PAD_PTF5__LPSPI2_PCS2 0x0194 0x02A4 0x3 0x3
#define IMX7ULP_PAD_PTF5__LPUART5_RTS_B 0x0194 0x0000 0x4 0x0
-#define IMX7ULP_PAD_PTF5__LPI2C5_SDA 0x0194 0x02c0 0x5 0x3
+#define IMX7ULP_PAD_PTF5__LPI2C5_SDA 0x0194 0x02C0 0x5 0x3
#define IMX7ULP_PAD_PTF5__TPM4_CH4 0x0194 0x0290 0x6 0x2
#define IMX7ULP_PAD_PTF5__FB_AD18 0x0194 0x0000 0x9 0x0
+#define IMX7ULP_PAD_PTF5__VIU_D1 0x0194 0x0000 0xc 0x0
#define IMX7ULP_PAD_PTF6__PTF6 0x0198 0x0000 0x1 0x0
-#define IMX7ULP_PAD_PTF6__VIU_D2 0x0198 0x0000 0xc 0x0
-#define IMX7ULP_PAD_PTF6__FXIO1_D2 0x0198 0x020c 0x2 0x2
-#define IMX7ULP_PAD_PTF6__LPSPI2_PCS3 0x0198 0x02a8 0x3 0x3
+#define IMX7ULP_PAD_PTF6__FXIO1_D2 0x0198 0x020C 0x2 0x2
+#define IMX7ULP_PAD_PTF6__LPSPI2_PCS3 0x0198 0x02A8 0x3 0x3
#define IMX7ULP_PAD_PTF6__LPUART5_TX 0x0198 0x0258 0x4 0x3
-#define IMX7ULP_PAD_PTF6__LPI2C5_HREQ 0x0198 0x02b8 0x5 0x3
+#define IMX7ULP_PAD_PTF6__LPI2C5_HREQ 0x0198 0x02B8 0x5 0x3
#define IMX7ULP_PAD_PTF6__TPM4_CH5 0x0198 0x0294 0x6 0x2
#define IMX7ULP_PAD_PTF6__FB_AD19 0x0198 0x0000 0x9 0x0
-#define IMX7ULP_PAD_PTF7__PTF7 0x019c 0x0000 0x1 0x0
-#define IMX7ULP_PAD_PTF7__VIU_D3 0x019c 0x0000 0xc 0x0
-#define IMX7ULP_PAD_PTF7__FXIO1_D3 0x019c 0x0210 0x2 0x2
-#define IMX7ULP_PAD_PTF7__LPUART5_RX 0x019c 0x0254 0x4 0x3
-#define IMX7ULP_PAD_PTF7__TPM5_CH1 0x019c 0x02c8 0x6 0x3
-#define IMX7ULP_PAD_PTF7__FB_AD20 0x019c 0x0000 0x9 0x0
-#define IMX7ULP_PAD_PTF8__PTF8 0x01a0 0x0000 0x1 0x0
-#define IMX7ULP_PAD_PTF8__USB1_ULPI_CLK 0x01a0 0x0000 0xb 0x0
-#define IMX7ULP_PAD_PTF8__VIU_D4 0x01a0 0x0000 0xc 0x0
-#define IMX7ULP_PAD_PTF8__FXIO1_D4 0x01a0 0x0214 0x2 0x2
-#define IMX7ULP_PAD_PTF8__LPSPI2_SIN 0x01a0 0x02b0 0x3 0x3
-#define IMX7ULP_PAD_PTF8__LPUART6_CTS_B 0x01a0 0x025c 0x4 0x3
-#define IMX7ULP_PAD_PTF8__LPI2C6_SCL 0x01a0 0x02fc 0x5 0x3
-#define IMX7ULP_PAD_PTF8__TPM5_CLKIN 0x01a0 0x02cc 0x6 0x3
-#define IMX7ULP_PAD_PTF8__FB_AD21 0x01a0 0x0000 0x9 0x0
-#define IMX7ULP_PAD_PTF9__PTF9 0x01a4 0x0000 0x1 0x0
-#define IMX7ULP_PAD_PTF9__USB1_ULPI_NXT 0x01a4 0x0000 0xb 0x0
-#define IMX7ULP_PAD_PTF9__VIU_D5 0x01a4 0x0000 0xc 0x0
-#define IMX7ULP_PAD_PTF9__FXIO1_D5 0x01a4 0x0218 0x2 0x2
-#define IMX7ULP_PAD_PTF9__LPSPI2_SOUT 0x01a4 0x02b4 0x3 0x3
-#define IMX7ULP_PAD_PTF9__LPUART6_RTS_B 0x01a4 0x0000 0x4 0x0
-#define IMX7ULP_PAD_PTF9__LPI2C6_SDA 0x01a4 0x0300 0x5 0x3
-#define IMX7ULP_PAD_PTF9__TPM5_CH0 0x01a4 0x02c4 0x6 0x3
-#define IMX7ULP_PAD_PTF9__FB_AD22 0x01a4 0x0000 0x9 0x0
-#define IMX7ULP_PAD_PTF10__PTF10 0x01a8 0x0000 0x1 0x0
-#define IMX7ULP_PAD_PTF10__USB1_ULPI_STP 0x01a8 0x0000 0xb 0x0
-#define IMX7ULP_PAD_PTF10__VIU_D6 0x01a8 0x0000 0xc 0x0
-#define IMX7ULP_PAD_PTF10__FXIO1_D6 0x01a8 0x021c 0x2 0x2
-#define IMX7ULP_PAD_PTF10__LPSPI2_SCK 0x01a8 0x02ac 0x3 0x3
-#define IMX7ULP_PAD_PTF10__LPUART6_TX 0x01a8 0x0264 0x4 0x3
-#define IMX7ULP_PAD_PTF10__LPI2C6_HREQ 0x01a8 0x02f8 0x5 0x3
-#define IMX7ULP_PAD_PTF10__TPM7_CH3 0x01a8 0x02e8 0x6 0x3
-#define IMX7ULP_PAD_PTF10__FB_AD23 0x01a8 0x0000 0x9 0x0
-#define IMX7ULP_PAD_PTF11__PTF11 0x01ac 0x0000 0x1 0x0
-#define IMX7ULP_PAD_PTF11__USB1_ULPI_DIR 0x01ac 0x0000 0xb 0x0
-#define IMX7ULP_PAD_PTF11__VIU_D7 0x01ac 0x0000 0xc 0x0
-#define IMX7ULP_PAD_PTF11__FXIO1_D7 0x01ac 0x0220 0x2 0x2
-#define IMX7ULP_PAD_PTF11__LPSPI2_PCS0 0x01ac 0x029c 0x3 0x3
-#define IMX7ULP_PAD_PTF11__LPUART6_RX 0x01ac 0x0260 0x4 0x3
-#define IMX7ULP_PAD_PTF11__TPM7_CH4 0x01ac 0x02ec 0x6 0x3
-#define IMX7ULP_PAD_PTF11__FB_CS4_B_FB_TSIZ0_FB_BE31_24_BLS7_0_B 0x01ac 0x0000 0x9 0x0
-#define IMX7ULP_PAD_PTF12__PTF12 0x01b0 0x0000 0x1 0x0
-#define IMX7ULP_PAD_PTF12__USB1_ULPI_DATA0 0x01b0 0x0000 0xb 0x0
-#define IMX7ULP_PAD_PTF12__VIU_D8 0x01b0 0x0000 0xc 0x0
-#define IMX7ULP_PAD_PTF12__FXIO1_D8 0x01b0 0x0224 0x2 0x2
-#define IMX7ULP_PAD_PTF12__LPSPI3_PCS1 0x01b0 0x0314 0x3 0x3
-#define IMX7ULP_PAD_PTF12__LPUART7_CTS_B 0x01b0 0x0268 0x4 0x3
-#define IMX7ULP_PAD_PTF12__LPI2C7_SCL 0x01b0 0x0308 0x5 0x3
-#define IMX7ULP_PAD_PTF12__TPM7_CH5 0x01b0 0x02f0 0x6 0x3
-#define IMX7ULP_PAD_PTF12__FB_AD24 0x01b0 0x0000 0x9 0x0
-#define IMX7ULP_PAD_PTF13__PTF13 0x01b4 0x0000 0x1 0x0
-#define IMX7ULP_PAD_PTF13__USB1_ULPI_DATA1 0x01b4 0x0000 0xb 0x0
-#define IMX7ULP_PAD_PTF13__VIU_D9 0x01b4 0x0000 0xc 0x0
-#define IMX7ULP_PAD_PTF13__FXIO1_D9 0x01b4 0x0228 0x2 0x2
-#define IMX7ULP_PAD_PTF13__LPSPI3_PCS2 0x01b4 0x0318 0x3 0x3
-#define IMX7ULP_PAD_PTF13__LPUART7_RTS_B 0x01b4 0x0000 0x4 0x0
-#define IMX7ULP_PAD_PTF13__LPI2C7_SDA 0x01b4 0x030c 0x5 0x3
-#define IMX7ULP_PAD_PTF13__TPM7_CLKIN 0x01b4 0x02f4 0x6 0x3
-#define IMX7ULP_PAD_PTF13__FB_AD25 0x01b4 0x0000 0x9 0x0
-#define IMX7ULP_PAD_PTF14__PTF14 0x01b8 0x0000 0x1 0x0
-#define IMX7ULP_PAD_PTF14__USB1_ULPI_DATA2 0x01b8 0x0000 0xb 0x0
-#define IMX7ULP_PAD_PTF14__VIU_D10 0x01b8 0x0000 0xc 0x0
-#define IMX7ULP_PAD_PTF14__FXIO1_D10 0x01b8 0x022c 0x2 0x2
-#define IMX7ULP_PAD_PTF14__LPSPI3_PCS3 0x01b8 0x031c 0x3 0x3
-#define IMX7ULP_PAD_PTF14__LPUART7_TX 0x01b8 0x0270 0x4 0x3
-#define IMX7ULP_PAD_PTF14__LPI2C7_HREQ 0x01b8 0x0304 0x5 0x3
-#define IMX7ULP_PAD_PTF14__TPM7_CH0 0x01b8 0x02dc 0x6 0x3
-#define IMX7ULP_PAD_PTF14__FB_AD26 0x01b8 0x0000 0x9 0x0
-#define IMX7ULP_PAD_PTF15__PTF15 0x01bc 0x0000 0x1 0x0
-#define IMX7ULP_PAD_PTF15__USB1_ULPI_DATA3 0x01bc 0x0000 0xb 0x0
-#define IMX7ULP_PAD_PTF15__VIU_D11 0x01bc 0x0000 0xc 0x0
-#define IMX7ULP_PAD_PTF15__FXIO1_D11 0x01bc 0x0230 0x2 0x2
-#define IMX7ULP_PAD_PTF15__LPUART7_RX 0x01bc 0x026c 0x4 0x3
-#define IMX7ULP_PAD_PTF15__TPM7_CH1 0x01bc 0x02e0 0x6 0x3
-#define IMX7ULP_PAD_PTF15__FB_AD27 0x01bc 0x0000 0x9 0x0
-#define IMX7ULP_PAD_PTF16__PTF16 0x01c0 0x0000 0x1 0x0
-#define IMX7ULP_PAD_PTF16__USB1_ULPI_DATA4 0x01c0 0x0000 0xb 0x0
-#define IMX7ULP_PAD_PTF16__VIU_D12 0x01c0 0x0000 0xc 0x0
-#define IMX7ULP_PAD_PTF16__FXIO1_D12 0x01c0 0x0234 0x2 0x2
-#define IMX7ULP_PAD_PTF16__LPSPI3_SIN 0x01c0 0x0324 0x3 0x3
-#define IMX7ULP_PAD_PTF16__TPM7_CH2 0x01c0 0x02e4 0x6 0x3
-#define IMX7ULP_PAD_PTF16__FB_AD28 0x01c0 0x0000 0x9 0x0
-#define IMX7ULP_PAD_PTF17__PTF17 0x01c4 0x0000 0x1 0x0
-#define IMX7ULP_PAD_PTF17__USB1_ULPI_DATA5 0x01c4 0x0000 0xb 0x0
-#define IMX7ULP_PAD_PTF17__VIU_D13 0x01c4 0x0000 0xc 0x0
-#define IMX7ULP_PAD_PTF17__FXIO1_D13 0x01c4 0x0238 0x2 0x2
-#define IMX7ULP_PAD_PTF17__LPSPI3_SOUT 0x01c4 0x0328 0x3 0x3
-#define IMX7ULP_PAD_PTF17__TPM6_CLKIN 0x01c4 0x02d8 0x6 0x3
-#define IMX7ULP_PAD_PTF17__FB_AD29 0x01c4 0x0000 0x9 0x0
-#define IMX7ULP_PAD_PTF18__PTF18 0x01c8 0x0000 0x1 0x0
-#define IMX7ULP_PAD_PTF18__USB1_ULPI_DATA6 0x01c8 0x0000 0xb 0x0
-#define IMX7ULP_PAD_PTF18__VIU_D14 0x01c8 0x0000 0xc 0x0
-#define IMX7ULP_PAD_PTF18__FXIO1_D14 0x01c8 0x023c 0x2 0x2
-#define IMX7ULP_PAD_PTF18__LPSPI3_SCK 0x01c8 0x0320 0x3 0x3
-#define IMX7ULP_PAD_PTF18__TPM6_CH0 0x01c8 0x02d0 0x6 0x3
-#define IMX7ULP_PAD_PTF18__FB_AD30 0x01c8 0x0000 0x9 0x0
-#define IMX7ULP_PAD_PTF19__PTF19 0x01cc 0x0000 0x1 0x0
-#define IMX7ULP_PAD_PTF19__USB1_ULPI_DATA7 0x01cc 0x0000 0xb 0x0
-#define IMX7ULP_PAD_PTF19__VIU_D15 0x01cc 0x0000 0xc 0x0
-#define IMX7ULP_PAD_PTF19__FXIO1_D15 0x01cc 0x0240 0x2 0x2
-#define IMX7ULP_PAD_PTF19__LPSPI3_PCS0 0x01cc 0x0310 0x3 0x3
-#define IMX7ULP_PAD_PTF19__TPM6_CH1 0x01cc 0x02d4 0x6 0x3
-#define IMX7ULP_PAD_PTF19__FB_AD31 0x01cc 0x0000 0x9 0x0
+#define IMX7ULP_PAD_PTF6__VIU_D2 0x0198 0x0000 0xc 0x0
+#define IMX7ULP_PAD_PTF7__PTF7 0x019C 0x0000 0x1 0x0
+#define IMX7ULP_PAD_PTF7__FXIO1_D3 0x019C 0x0210 0x2 0x2
+#define IMX7ULP_PAD_PTF7__LPUART5_RX 0x019C 0x0254 0x4 0x3
+#define IMX7ULP_PAD_PTF7__TPM5_CH1 0x019C 0x02C8 0x6 0x3
+#define IMX7ULP_PAD_PTF7__FB_AD20 0x019C 0x0000 0x9 0x0
+#define IMX7ULP_PAD_PTF7__VIU_D3 0x019C 0x0000 0xc 0x0
+#define IMX7ULP_PAD_PTF8__PTF8 0x01A0 0x0000 0x1 0x0
+#define IMX7ULP_PAD_PTF8__FXIO1_D4 0x01A0 0x0214 0x2 0x2
+#define IMX7ULP_PAD_PTF8__LPSPI2_SIN 0x01A0 0x02B0 0x3 0x3
+#define IMX7ULP_PAD_PTF8__LPUART6_CTS_B 0x01A0 0x025C 0x4 0x3
+#define IMX7ULP_PAD_PTF8__LPI2C6_SCL 0x01A0 0x02FC 0x5 0x3
+#define IMX7ULP_PAD_PTF8__TPM5_CLKIN 0x01A0 0x02CC 0x6 0x3
+#define IMX7ULP_PAD_PTF8__FB_AD21 0x01A0 0x0000 0x9 0x0
+#define IMX7ULP_PAD_PTF8__USB1_CLK 0x01A0 0x0000 0xb 0x0
+#define IMX7ULP_PAD_PTF8__VIU_D4 0x01A0 0x0000 0xc 0x0
+#define IMX7ULP_PAD_PTF9__PTF9 0x01A4 0x0000 0x1 0x0
+#define IMX7ULP_PAD_PTF9__FXIO1_D5 0x01A4 0x0218 0x2 0x2
+#define IMX7ULP_PAD_PTF9__LPSPI2_SOUT 0x01A4 0x02B4 0x3 0x3
+#define IMX7ULP_PAD_PTF9__LPUART6_RTS_B 0x01A4 0x0000 0x4 0x0
+#define IMX7ULP_PAD_PTF9__LPI2C6_SDA 0x01A4 0x0300 0x5 0x3
+#define IMX7ULP_PAD_PTF9__TPM5_CH0 0x01A4 0x02C4 0x6 0x3
+#define IMX7ULP_PAD_PTF9__FB_AD22 0x01A4 0x0000 0x9 0x0
+#define IMX7ULP_PAD_PTF9__USB1_NXT 0x01A4 0x0000 0xb 0x0
+#define IMX7ULP_PAD_PTF9__VIU_D5 0x01A4 0x0000 0xc 0x0
+#define IMX7ULP_PAD_PTF10__PTF10 0x01A8 0x0000 0x1 0x0
+#define IMX7ULP_PAD_PTF10__FXIO1_D6 0x01A8 0x021C 0x2 0x2
+#define IMX7ULP_PAD_PTF10__LPSPI2_SCK 0x01A8 0x02AC 0x3 0x3
+#define IMX7ULP_PAD_PTF10__LPUART6_TX 0x01A8 0x0264 0x4 0x3
+#define IMX7ULP_PAD_PTF10__LPI2C6_HREQ 0x01A8 0x02F8 0x5 0x3
+#define IMX7ULP_PAD_PTF10__TPM7_CH3 0x01A8 0x02E8 0x6 0x3
+#define IMX7ULP_PAD_PTF10__FB_AD23 0x01A8 0x0000 0x9 0x0
+#define IMX7ULP_PAD_PTF10__USB1_STP 0x01A8 0x0000 0xb 0x0
+#define IMX7ULP_PAD_PTF10__VIU_D6 0x01A8 0x0000 0xc 0x0
+#define IMX7ULP_PAD_PTF11__PTF11 0x01AC 0x0000 0x1 0x0
+#define IMX7ULP_PAD_PTF11__FXIO1_D7 0x01AC 0x0220 0x2 0x2
+#define IMX7ULP_PAD_PTF11__LPSPI2_PCS0 0x01AC 0x029C 0x3 0x3
+#define IMX7ULP_PAD_PTF11__LPUART6_RX 0x01AC 0x0260 0x4 0x3
+#define IMX7ULP_PAD_PTF11__TPM7_CH4 0x01AC 0x02EC 0x6 0x3
+#define IMX7ULP_PAD_PTF11__FB_CS4_B_FB_TSIZ0_FB_BE31_24_BLS7_0_B 0x01AC 0x0000 0x9 0x0
+#define IMX7ULP_PAD_PTF11__USB1_DIR 0x01AC 0x0000 0xb 0x0
+#define IMX7ULP_PAD_PTF11__VIU_D7 0x01AC 0x0000 0xc 0x0
+#define IMX7ULP_PAD_PTF12__PTF12 0x01B0 0x0000 0x1 0x0
+#define IMX7ULP_PAD_PTF12__FXIO1_D8 0x01B0 0x0224 0x2 0x2
+#define IMX7ULP_PAD_PTF12__LPSPI3_PCS1 0x01B0 0x0314 0x3 0x3
+#define IMX7ULP_PAD_PTF12__LPUART7_CTS_B 0x01B0 0x0268 0x4 0x3
+#define IMX7ULP_PAD_PTF12__LPI2C7_SCL 0x01B0 0x0308 0x5 0x3
+#define IMX7ULP_PAD_PTF12__TPM7_CH5 0x01B0 0x02F0 0x6 0x3
+#define IMX7ULP_PAD_PTF12__FB_AD24 0x01B0 0x0000 0x9 0x0
+#define IMX7ULP_PAD_PTF12__USB1_DATA0 0x01B0 0x0000 0xb 0x0
+#define IMX7ULP_PAD_PTF12__VIU_D8 0x01B0 0x0000 0xc 0x0
+#define IMX7ULP_PAD_PTF13__PTF13 0x01B4 0x0000 0x1 0x0
+#define IMX7ULP_PAD_PTF13__FXIO1_D9 0x01B4 0x0228 0x2 0x2
+#define IMX7ULP_PAD_PTF13__LPSPI3_PCS2 0x01B4 0x0318 0x3 0x3
+#define IMX7ULP_PAD_PTF13__LPUART7_RTS_B 0x01B4 0x0000 0x4 0x0
+#define IMX7ULP_PAD_PTF13__LPI2C7_SDA 0x01B4 0x030C 0x5 0x3
+#define IMX7ULP_PAD_PTF13__TPM7_CLKIN 0x01B4 0x02F4 0x6 0x3
+#define IMX7ULP_PAD_PTF13__FB_AD25 0x01B4 0x0000 0x9 0x0
+#define IMX7ULP_PAD_PTF13__USB1_DATA1 0x01B4 0x0000 0xb 0x0
+#define IMX7ULP_PAD_PTF13__VIU_D9 0x01B4 0x0000 0xc 0x0
+#define IMX7ULP_PAD_PTF14__PTF14 0x01B8 0x0000 0x1 0x0
+#define IMX7ULP_PAD_PTF14__FXIO1_D10 0x01B8 0x022C 0x2 0x2
+#define IMX7ULP_PAD_PTF14__LPSPI3_PCS3 0x01B8 0x031C 0x3 0x3
+#define IMX7ULP_PAD_PTF14__LPUART7_TX 0x01B8 0x0270 0x4 0x3
+#define IMX7ULP_PAD_PTF14__LPI2C7_HREQ 0x01B8 0x0304 0x5 0x3
+#define IMX7ULP_PAD_PTF14__TPM7_CH0 0x01B8 0x02DC 0x6 0x3
+#define IMX7ULP_PAD_PTF14__FB_AD26 0x01B8 0x0000 0x9 0x0
+#define IMX7ULP_PAD_PTF14__USB1_DATA2 0x01B8 0x0000 0xb 0x0
+#define IMX7ULP_PAD_PTF14__VIU_D10 0x01B8 0x0000 0xc 0x0
+#define IMX7ULP_PAD_PTF15__PTF15 0x01BC 0x0000 0x1 0x0
+#define IMX7ULP_PAD_PTF15__FXIO1_D11 0x01BC 0x0230 0x2 0x2
+#define IMX7ULP_PAD_PTF15__LPUART7_RX 0x01BC 0x026C 0x4 0x3
+#define IMX7ULP_PAD_PTF15__TPM7_CH1 0x01BC 0x02E0 0x6 0x3
+#define IMX7ULP_PAD_PTF15__FB_AD27 0x01BC 0x0000 0x9 0x0
+#define IMX7ULP_PAD_PTF15__USB1_DATA3 0x01BC 0x0000 0xb 0x0
+#define IMX7ULP_PAD_PTF15__VIU_D11 0x01BC 0x0000 0xc 0x0
+#define IMX7ULP_PAD_PTF16__PTF16 0x01C0 0x0000 0x1 0x0
+#define IMX7ULP_PAD_PTF16__USB1_DATA4 0x01C0 0x0000 0xb 0x0
+#define IMX7ULP_PAD_PTF16__VIU_D12 0x01C0 0x0000 0xc 0x0
+#define IMX7ULP_PAD_PTF16__FXIO1_D12 0x01C0 0x0234 0x2 0x2
+#define IMX7ULP_PAD_PTF16__LPSPI3_SIN 0x01C0 0x0324 0x3 0x3
+#define IMX7ULP_PAD_PTF16__TPM7_CH2 0x01C0 0x02E4 0x6 0x3
+#define IMX7ULP_PAD_PTF16__FB_AD28 0x01C0 0x0000 0x9 0x0
+#define IMX7ULP_PAD_PTF17__PTF17 0x01C4 0x0000 0x1 0x0
+#define IMX7ULP_PAD_PTF17__USB1_DATA5 0x01C4 0x0000 0xb 0x0
+#define IMX7ULP_PAD_PTF17__VIU_D13 0x01C4 0x0000 0xc 0x0
+#define IMX7ULP_PAD_PTF17__FXIO1_D13 0x01C4 0x0238 0x2 0x2
+#define IMX7ULP_PAD_PTF17__LPSPI3_SOUT 0x01C4 0x0328 0x3 0x3
+#define IMX7ULP_PAD_PTF17__TPM6_CLKIN 0x01C4 0x02D8 0x6 0x3
+#define IMX7ULP_PAD_PTF17__FB_AD29 0x01C4 0x0000 0x9 0x0
+#define IMX7ULP_PAD_PTF18__PTF18 0x01C8 0x0000 0x1 0x0
+#define IMX7ULP_PAD_PTF18__USB1_DATA6 0x01C8 0x0000 0xb 0x0
+#define IMX7ULP_PAD_PTF18__VIU_D14 0x01C8 0x0000 0xc 0x0
+#define IMX7ULP_PAD_PTF18__FXIO1_D14 0x01C8 0x023C 0x2 0x2
+#define IMX7ULP_PAD_PTF18__LPSPI3_SCK 0x01C8 0x0320 0x3 0x3
+#define IMX7ULP_PAD_PTF18__TPM6_CH0 0x01C8 0x02D0 0x6 0x3
+#define IMX7ULP_PAD_PTF18__FB_AD30 0x01C8 0x0000 0x9 0x0
+#define IMX7ULP_PAD_PTF19__PTF19 0x01CC 0x0000 0x1 0x0
+#define IMX7ULP_PAD_PTF19__USB1_DATA7 0x01CC 0x0000 0xb 0x0
+#define IMX7ULP_PAD_PTF19__VIU_D15 0x01CC 0x0000 0xc 0x0
+#define IMX7ULP_PAD_PTF19__FXIO1_D15 0x01CC 0x0240 0x2 0x2
+#define IMX7ULP_PAD_PTF19__LPSPI3_PCS0 0x01CC 0x0310 0x3 0x3
+#define IMX7ULP_PAD_PTF19__TPM6_CH1 0x01CC 0x02D4 0x6 0x3
+#define IMX7ULP_PAD_PTF19__FB_AD31 0x01CC 0x0000 0x9 0x0
#endif /* __DTS_IMX7ULP_PINFUNC_H */
diff --git a/arch/arm/boot/dts/imx7ulp.dtsi b/arch/arm/boot/dts/imx7ulp.dtsi
new file mode 100644
index 000000000000..58d4062d38e5
--- /dev/null
+++ b/arch/arm/boot/dts/imx7ulp.dtsi
@@ -0,0 +1,694 @@
+/*
+ * Copyright 2015-2016 Freescale Semiconductor, Inc.
+ * Copyright 2017 NXP
+ *
+ * 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/imx7ulp-clock.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/pwm/pwm.h>
+#include "skeleton.dtsi"
+#include "imx7ulp-pinfunc.h"
+
+/ {
+ interrupt-parent = <&intc>;
+
+ aliases {
+ gpio0 = &gpio_ptc;
+ gpio1 = &gpio_ptd;
+ gpio2 = &gpio_pte;
+ gpio3 = &gpio_ptf;
+ mmc0 = &usdhc0;
+ mmc1 = &usdhc1;
+ serial0 = &lpuart4;
+ serial1 = &lpuart5;
+ serial2 = &lpuart6;
+ serial3 = &lpuart7;
+ usbphy0 = &usbphy1;
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu0: cpu@0 {
+ compatible = "arm,cortex-a7";
+ device_type = "cpu";
+ clock-latency = <61036>; /* two CLK32 periods */
+ reg = <0>;
+
+ operating-points = <
+ /* KHz uV */
+ 720000 1125000
+ 500210 1025000
+ >;
+ clocks = <&clks IMX7ULP_CLK_ARM>,
+ <&clks IMX7ULP_CLK_CORE_DIV>,
+ <&clks IMX7ULP_CLK_SYS_SEL>,
+ <&clks IMX7ULP_CLK_HSRUN_SYS_SEL>,
+ <&clks IMX7ULP_CLK_HSRUN_CORE>,
+ <&clks IMX7ULP_CLK_SPLL_PFD0>,
+ <&clks IMX7ULP_CLK_SPLL_SEL>,
+ <&clks IMX7ULP_CLK_FIRC>,
+ <&clks IMX7ULP_CLK_SPLL>;
+ clock-names = "arm", "core_div", "sys_sel", "hsrun_sys_sel",
+ "hsrun_core", "spll_pfd0", "spll_sel", "firc",
+ "spll";
+ };
+ };
+
+ reserved-memory {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ /* global autoconfigured region for contiguous allocations */
+ linux,cma {
+ compatible = "shared-dma-pool";
+ reusable;
+ size = <0xC000000>;
+ alignment = <0x2000>;
+ linux,cma-default;
+ };
+
+ rpmsg_reserved: rpmsg@9FFF0000 {
+ no-map;
+ reg = <0x9FF00000 0x100000>;
+ };
+
+ };
+
+ intc: interrupt-controller@40021000 {
+ compatible = "arm,cortex-a7-gic";
+ #interrupt-cells = <3>;
+ interrupt-controller;
+ reg = <0x40021000 0x1000>,
+ <0x40022000 0x100>;
+ };
+
+ clocks {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ rosc: clock@0 {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <32768>;
+ clock-output-names = "rosc";
+ };
+
+ sosc: clock@1 {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <24000000>;
+ clock-output-names = "sosc";
+ };
+
+ sirc: clock@2 {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <16000000>;
+ clock-output-names = "sirc";
+ };
+
+ firc: clock@3 {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <48000000>;
+ clock-output-names = "firc";
+ };
+
+ upll: clock@4 {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <480000000>;
+ clock-output-names = "upll";
+ };
+
+ mpll: clock@5 {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <480000000>;
+ clock-output-names = "mpll";
+ };
+ };
+
+ sram: sram@20000000 {
+ compatible = "fsl,lpm-sram";
+ reg = <0x1fffc000 0x4000>;
+ };
+
+ pmu: pmu@a7 {
+ compatible = "arm,cortex-a7-pmu";
+ };
+
+ caam_sm: caam-sm@26000000 {
+ compatible = "fsl,imx6q-caam-sm";
+ reg = <0x26000000 0x8000>;
+ };
+
+ ahbbridge0: ahb-bridge0@40000000 {
+ compatible = "fsl,aips-bus", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x40000000 0x800000>;
+ ranges;
+
+ edma0: dma-controller@40080000 {
+ #dma-cells = <2>;
+ compatible = "nxp,imx7ulp-edma";
+ reg = <0x40080000 0x2000>,
+ <0x40210000 0x1000>;
+ dma-channels = <32>;
+ interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>;
+ clock-names = "dma", "dmamux0";
+ clocks = <&clks IMX7ULP_CLK_DMA1>, <&clks IMX7ULP_CLK_DMA_MUX1>;
+ };
+
+ mu: mu@40220000 {
+ compatible = "fsl,imx7ulp-mu", "fsl,imx6sx-mu";
+ reg = <0x40220000 0x1000>;
+ interrupts = <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>;
+ status = "okay";
+ };
+
+ nmi: nmi@40220000 {
+ compatible = "fsl,imx7ulp-nmi";
+ reg = <0x40220000 0x1000>;
+ interrupts = <GIC_SPI 90 IRQ_TYPE_LEVEL_HIGH>;
+ status = "okay";
+ };
+
+ crypto: caam@40240000 {
+ compatible = "fsl,imx7d-caam", "fsl,sec-v4.0";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x40240000 0x40000>;
+ ranges = <0 0x40240000 0x40000>;
+ clocks = <&clks IMX7ULP_CLK_CAAM>,
+ <&clks IMX7ULP_CLK_NIC1_DIV>;
+ clock-names = "ipg", "aclk";
+
+ sec_ctrl: ctrl@0 {
+ /* CAAM Page 0 only accessible */
+ /* by secure world */
+ compatible = "fsl,sec-v4.0-ctrl";
+ reg = <0x40240000 0x1000>;
+ secure-status = "okay";
+ status = "disabled";
+ };
+
+ sec_jr0: jr0@1000 {
+ compatible = "fsl,sec-v4.0-job-ring";
+ reg = <0x1000 0x1000>;
+ interrupts = <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ sec_jr1: jr1@2000 {
+ compatible = "fsl,sec-v4.0-job-ring";
+ reg = <0x2000 0x1000>;
+ interrupts = <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
+ };
+
+ rpmsg: rpmsg{
+ compatible = "fsl,imx7ulp-rpmsg";
+ memory-region = <&rpmsg_reserved>;
+ status = "disabled";
+ };
+
+ pwm0: tpm@40250000 {
+ compatible = "nxp,tpm-pwm";
+ reg = <0x40250000 0x1000>;
+ nxp,pwm-number = <6>;
+ assigned-clocks = <&clks IMX7ULP_CLK_LPTPM4>;
+ assigned-clock-parents = <&clks IMX7ULP_CLK_SOSC_BUS_CLK>;
+ clocks = <&clks IMX7ULP_CLK_LPTPM4>;
+ #pwm-cells = <2>;
+ };
+
+ tpm5: tpm@40260000 {
+ compatible = "fsl,imx7ulp-tpm";
+ reg = <0x40260000 0x1000>;
+ interrupts = <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX7ULP_CLK_LPTPM5>,
+ <&clks IMX7ULP_CLK_NIC1_BUS_DIV>;
+ clock-names = "per", "ipg";
+ };
+
+ lpit: 1@40270000 {
+ compatible = "fsl,imx-lpit";
+ reg = <0x40270000 0x1000>;
+ interrupts = <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>;
+ /* clocks = <&lpclk>;*/
+ clocks = <&clks IMX7ULP_CLK_LPIT1>;
+ assigned-clock-rates = <48000000>;
+ assigned-clocks = <&clks IMX7ULP_CLK_LPIT1>;
+ assigned-clock-parents = <&clks IMX7ULP_CLK_FIRC_BUS_CLK>;
+ };
+
+ lpi2c4: lpi2c4@402B0000 {
+ compatible = "fsl,imx7ulp-lpi2c";
+ reg = <0x402B0000 0x10000>;
+ interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX7ULP_CLK_LPI2C4>,
+ <&clks IMX7ULP_CLK_NIC1_BUS_DIV>;
+ clock-names = "per", "ipg";
+ assigned-clocks = <&clks IMX7ULP_CLK_LPI2C4>;
+ assigned-clock-parents = <&clks IMX7ULP_CLK_FIRC_BUS_CLK>;
+ assigned-clock-rates = <48000000>;
+ status = "disabled";
+ };
+
+ lpi2c5: lpi2c5@402C0000 {
+ compatible = "fsl,imx7ulp-lpi2c";
+ reg = <0x402C0000 0x10000>;
+ interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX7ULP_CLK_LPI2C5>,
+ <&clks IMX7ULP_CLK_NIC1_BUS_DIV>;
+ clock-names = "per", "ipg";
+ assigned-clocks = <&clks IMX7ULP_CLK_LPI2C5>;
+ assigned-clock-parents = <&clks IMX7ULP_CLK_FIRC_BUS_CLK>;
+ assigned-clock-rates = <48000000>;
+ };
+
+ lpspi2: lpspi@40290000 {
+ compatible = "fsl,imx7ulp-spi";
+ reg = <0x40290000 0x10000>;
+ interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX7ULP_CLK_LPSPI2>,
+ <&clks IMX7ULP_CLK_DUMMY>;
+ clock-names = "per", "ipg";
+ assigned-clocks = <&clks IMX7ULP_CLK_LPSPI2>;
+ assigned-clock-parents = <&clks IMX7ULP_CLK_FIRC_BUS_CLK>;
+ assigned-clock-rates = <48000000>;
+ dmas = <&edma0 0 26>, <&edma0 0 25>;
+ dma-names = "tx","rx";
+ status = "disabled";
+ };
+
+ lpspi3: lpspi@402A0000 {
+ compatible = "fsl,imx7ulp-spi";
+ reg = <0x402A0000 0x10000>;
+ interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX7ULP_CLK_LPSPI3>,
+ <&clks IMX7ULP_CLK_DUMMY>;
+ clock-names = "per", "ipg";
+ assigned-clocks = <&clks IMX7ULP_CLK_LPSPI3>;
+ assigned-clock-parents = <&clks IMX7ULP_CLK_FIRC_BUS_CLK>;
+ assigned-clock-rates = <48000000>;
+ dmas = <&edma0 0 28>, <&edma0 0 27>;
+ dma-names = "tx","rx";
+ status = "disabled";
+ };
+
+ lpuart4: serial@402D0000 {
+ compatible = "fsl,imx7ulp-lpuart";
+ reg = <0x402D0000 0x1000>;
+ interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX7ULP_CLK_LPUART4>;
+ clock-names = "ipg";
+ assigned-clocks = <&clks IMX7ULP_CLK_LPUART4>;
+ assigned-clock-parents = <&clks IMX7ULP_CLK_SOSC_BUS_CLK>;
+ assigned-clock-rates = <24000000>;
+ status = "disabled";
+ };
+
+ lpuart5: serial@402E0000 {
+ compatible = "fsl,imx7ulp-lpuart";
+ reg = <0x402E0000 0x1000>;
+ interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX7ULP_CLK_LPUART5>;
+ clock-names = "ipg";
+ assigned-clocks = <&clks IMX7ULP_CLK_LPUART5>;
+ assigned-clock-parents = <&clks IMX7ULP_CLK_FIRC_BUS_CLK>;
+ assigned-clock-rates = <48000000>;
+ dmas = <&edma0 0 20>, <&edma0 0 19>;
+ dma-names = "tx","rx";
+ status = "disabled";
+ };
+
+ usbotg1: usb@40330000 {
+ compatible = "fsl,imx7ulp-usb", "fsl,imx6ul-usb",
+ "fsl,imx27-usb";
+ reg = <0x40330000 0x200>;
+ interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX7ULP_CLK_USB0>;
+ fsl,usbphy = <&usbphy1>;
+ fsl,usbmisc = <&usbmisc1 0>;
+ ahb-burst-config = <0x0>;
+ tx-burst-size-dword = <0x8>;
+ rx-burst-size-dword = <0x8>;
+ status = "disabled";
+ };
+
+ usbmisc1: usbmisc@40330200 {
+ #index-cells = <1>;
+ compatible = "fsl,imx7ulp-usbmisc", "fsl,imx7d-usbmisc",
+ "fsl,imx6q-usbmisc";
+ reg = <0x40330200 0x200>;
+ };
+
+ usbphy1: usbphy@0x40350000 {
+ compatible = "fsl,imx7ulp-usbphy",
+ "fsl,imx6ul-usbphy", "fsl,imx23-usbphy";
+ reg = <0x40350000 0x1000>;
+ interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX7ULP_CLK_USB_PHY>;
+ nxp,sim = <&sim>;
+ };
+
+ usdhc0: usdhc@40370000 {
+ compatible = "fsl,imx7ulp-usdhc";
+ reg = <0x40370000 0x10000>;
+ interrupts = <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX7ULP_CLK_NIC1_BUS_DIV>,
+ <&clks IMX7ULP_CLK_NIC1_DIV>,
+ <&clks IMX7ULP_CLK_USDHC0>;
+ clock-names ="ipg", "ahb", "per";
+ bus-width = <4>;
+ assigned-clocks = <&clks IMX7ULP_CLK_APLL_PFD1>, <&clks IMX7ULP_CLK_USDHC0>;
+ assigned-clock-parents = <0>, <&clks IMX7ULP_CLK_APLL_PFD1>;
+ assigned-clock-rates = <0>, <352800000>;
+ fsl,tuning-start-tap = <20>;
+ fsl,tuning-step= <2>;
+ status = "disabled";
+ };
+
+ usdhc1: usdhc@40380000 {
+ compatible = "fsl,imx7ulp-usdhc";
+ reg = <0x40380000 0x10000>;
+ interrupts = <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX7ULP_CLK_NIC1_BUS_DIV>,
+ <&clks IMX7ULP_CLK_NIC1_DIV>,
+ <&clks IMX7ULP_CLK_USDHC1>;
+ clock-names ="ipg", "ahb", "per";
+ bus-width = <4>;
+ assigned-clocks = <&clks IMX7ULP_CLK_APLL_PFD1>, <&clks IMX7ULP_CLK_USDHC1>;
+ assigned-clock-parents = <0>, <&clks IMX7ULP_CLK_APLL_PFD1>;
+ assigned-clock-rates = <0>, <176400000>;
+ fsl,tuning-start-tap = <20>;
+ fsl,tuning-step= <2>;
+ status = "disabled";
+ };
+
+ wdog1: wdog@403D0000 {
+ compatible = "fsl,imx7ulp-wdt";
+ reg = <0x403D0000 0x10000>;
+ interrupts = <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX7ULP_CLK_WDG1>;
+ assigned-clocks = <&clks IMX7ULP_CLK_WDG1>;
+ assigned-clocks-parents = <&clks IMX7ULP_CLK_FIRC_BUS_CLK>;
+ /*
+ * As the 1KHz LPO clock rate is not trimed,the actually clock
+ * is about 667Hz, so the init timeout 60s should set 40*1000
+ * in the TOVAL register.
+ */
+ timeout-sec = <40>;
+ };
+
+ wdog2: wdog@40430000 {
+ compatible = "fsl,imx7ulp-wdt";
+ reg = <0x40430000 0x10000>;
+ interrupts = <GIC_SPI 56 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX7ULP_CLK_WDG2>;
+ assigned-clocks = <&clks IMX7ULP_CLK_WDG2>;
+ assigned-clocks-parents = <&clks IMX7ULP_CLK_FIRC_BUS_CLK>;
+ timeout-sec = <40>;
+ };
+
+ clks: scg1@403E0000 {
+ compatible = "fsl,imx7ulp-scg1";
+ reg = <0x403E0000 0x10000>;
+ clocks = <&rosc>, <&sosc>, <&sirc>,
+ <&firc>, <&upll>, <&mpll>;
+ clock-names = "rosc", "sosc", "sirc",
+ "firc", "upll", "mpll";
+ #clock-cells = <1>;
+ assigned-clocks = <&clks IMX7ULP_CLK_LPTPM5>;
+ assigned-clock-parents = <&clks IMX7ULP_CLK_SOSC_BUS_CLK>;
+ };
+
+ pcc2: pcc2@403F0000 {
+ compatible = "fsl,imx7ulp-pcc2";
+ reg = <0x403F0000 0x10000>;
+ };
+
+ pmc1: pmc1@40400000 {
+ compatible = "fsl,imx7ulp-pmc1";
+ reg = <0x40400000 0x1000>;
+ };
+
+ smc1: smc1@40410000 {
+ compatible = "fsl,imx7ulp-smc1";
+ reg = <0x40410000 0x1000>;
+ };
+
+ };
+
+ ahbbridge1: ahb-bridge1@40800000 {
+ compatible = "fsl,aips-bus", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x40800000 0x800000>;
+ ranges;
+
+ lpi2c6: lpi2c6@40A40000 {
+ compatible = "fsl,imx7ulp-lpi2c";
+ reg = <0x40A40000 0x10000>;
+ interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX7ULP_CLK_LPI2C6>,
+ <&clks IMX7ULP_CLK_NIC1_BUS_DIV>;
+ clock-names = "per", "ipg";
+ assigned-clocks = <&clks IMX7ULP_CLK_LPI2C6>;
+ assigned-clock-parents = <&clks IMX7ULP_CLK_FIRC_BUS_CLK>;
+ assigned-clock-rates = <48000000>;
+ status = "disabled";
+ };
+
+ lpi2c7: lpi2c7@40A50000 {
+ compatible = "fsl,imx7ulp-lpi2c";
+ reg = <0x40A50000 0x10000>;
+ interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX7ULP_CLK_LPI2C7>,
+ <&clks IMX7ULP_CLK_NIC1_BUS_DIV>;
+ clock-names = "per", "ipg";
+ assigned-clocks = <&clks IMX7ULP_CLK_LPI2C7>;
+ assigned-clock-parents = <&clks IMX7ULP_CLK_FIRC_BUS_CLK>;
+ assigned-clock-rates = <48000000>;
+ status = "disabled";
+ };
+
+ lpuart6: serial@40A60000 {
+ compatible = "fsl,imx7ulp-lpuart";
+ reg = <0x40A60000 0x1000>;
+ interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX7ULP_CLK_LPUART6>;
+ clock-names = "ipg";
+ assigned-clocks = <&clks IMX7ULP_CLK_LPUART6>;
+ assigned-clock-parents = <&clks IMX7ULP_CLK_FIRC_BUS_CLK>;
+ assigned-clock-rates = <48000000>;
+ dmas = <&edma0 0 22>, <&edma0 0 21>;
+ dma-names = "tx","rx";
+ status = "disabled";
+ };
+
+ lpuart7: serial@40A70000 {
+ compatible = "fsl,imx7ulp-lpuart";
+ reg = <0x40A70000 0x1000>;
+ interrupts = <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX7ULP_CLK_LPUART7>;
+ clock-names = "ipg";
+ assigned-clocks = <&clks IMX7ULP_CLK_LPUART7>;
+ assigned-clock-parents = <&clks IMX7ULP_CLK_FIRC_BUS_CLK>;
+ assigned-clock-rates = <48000000>;
+ dmas = <&edma0 0 24>, <&edma0 0 23>;
+ dma-names = "tx","rx";
+ status = "disabled";
+ };
+
+ lcdif: lcdif@40AA0000 {
+ compatible = "fsl,imx7ulp-lcdif";
+ reg = <0x40aa0000 0x10000>;
+ interrupts = <GIC_SPI 47 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX7ULP_CLK_DUMMY>,
+ <&clks IMX7ULP_CLK_LCDIF>,
+ <&clks IMX7ULP_CLK_DUMMY>;
+ clock-names = "axi", "pix", "disp_axi";
+ status = "disabled";
+ };
+
+ mipi_dsi: mipi_dsi@40A90000 {
+ compatible = "fsl,imx7ulp-mipi-dsi";
+ reg = <0x40A90000 0x10000>;
+ interrupts = <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX7ULP_CLK_DSI>;
+ clock-names = "mipi_dsi_clk";
+ data-lanes-num = <2>;
+ phy-ref-clkfreq = <24000000>;
+ max-data-rate = <800000000>;
+ sim = <&sim>;
+ status = "disabled";
+ };
+
+ mmdc: mmdc@40ab0000 {
+ compatible = "fsl,imx7ulp-mmdc", "fsl,imx6q-mmdc";
+ reg = <0x40ab0000 0x4000>;
+ };
+
+ pcc3: pcc3@40B30000 {
+ compatible = "fsl,imx7ulp-pcc3";
+ reg = <0x40B30000 0x10000>;
+ };
+
+ iomuxc: iomuxc@4103D000 {
+ compatible = "fsl,imx7ulp-iomuxc-0";
+ reg = <0x4103D000 0x1000>;
+ status = "disabled";
+ };
+
+ iomuxc1: iomuxc1@40ac0000 {
+ compatible = "fsl,imx7ulp-iomuxc-1";
+ reg = <0x40ac0000 0x1000>;
+ };
+
+ gpio_ptc: gpio@40ae0000 {
+ compatible = "fsl,vf610-gpio";
+ reg = <0x40ae0000 0x1000 0x400F0000 0x40>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupts = <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ clocks = <&clks IMX7ULP_CLK_RGPIO2P1>,
+ <&clks IMX7ULP_CLK_PCTLC>;
+ clock-names = "port", "gpio";
+ gpio-ranges = <&iomuxc1 0 0 32>;
+ };
+
+ gpio_ptd: gpio@40af0000 {
+ compatible = "fsl,vf610-gpio";
+ reg = <0x40af0000 0x1000 0x400F0040 0x40>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupts = <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ clocks = <&clks IMX7ULP_CLK_RGPIO2P1>,
+ <&clks IMX7ULP_CLK_PCTLD>;
+ clock-names = "port", "gpio";
+ gpio-ranges = <&iomuxc1 0 32 32>;
+ };
+
+ gpio_pte: gpio@40b00000 {
+ compatible = "fsl,vf610-gpio";
+ reg = <0x40b00000 0x1000 0x400F0080 0x40>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupts = <GIC_SPI 50 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ clocks = <&clks IMX7ULP_CLK_RGPIO2P1>,
+ <&clks IMX7ULP_CLK_PCTLE>;
+ clock-names = "port", "gpio";
+ gpio-ranges = <&iomuxc1 0 64 32>;
+ };
+
+ gpio_ptf: gpio@40b10000 {
+ compatible = "fsl,vf610-gpio";
+ reg = <0x40b10000 0x1000 0x400F00c0 0x40>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupts = <GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ clocks = <&clks IMX7ULP_CLK_RGPIO2P1>,
+ <&clks IMX7ULP_CLK_PCTLF>;
+ clock-names = "port", "gpio";
+ gpio-ranges = <&iomuxc1 0 96 32>;
+ };
+
+ pmc0: pmc0@410a1000 {
+ compatible = "fsl,imx7ulp-pmc0";
+ reg = <0x410a1000 0x1000>;
+ };
+
+ sim: sim@410a3000 {
+ compatible = "fsl,imx7ulp-sim", "syscon";
+ reg = <0x410a3000 0x1000>;
+ };
+
+ qspi1: qspi@410A5000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx7ulp-qspi";
+ reg = <0x410A5000 0x1000>, <0xC0000000 0x10000000>;
+ reg-names = "QuadSPI", "QuadSPI-memory";
+ interrupts = <GIC_SPI 64 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX7ULP_CLK_DUMMY>,
+ <&clks IMX7ULP_CLK_DUMMY>;
+ clock-names = "qspi_en", "qspi";
+ status = "disabled";
+ };
+
+ ocotp: ocotp@410a6000 {
+ compatible = "fsl,imx7ulp-ocotp";
+ reg = <0x410a6000 0x4000>;
+ clocks = <&clks IMX7ULP_CLK_DUMMY>;
+ };
+
+ gpu: gpu@41800000 {
+ compatible = "fsl,imx7ulp-gpu", "fsl,imx6q-gpu";
+ reg = <0x41800000 0x80000>, <0x41880000 0x80000>,
+ <0x60000000 0x40000000>, <0x0 0x4000000>;
+ reg-names = "iobase_3d", "iobase_2d",
+ "phys_baseaddr", "contiguous_mem";
+ interrupts = <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 52 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "irq_3d", "irq_2d";
+ clocks = <&clks IMX7ULP_CLK_GPU3D>,
+ <&clks IMX7ULP_CLK_DUMMY>,
+ <&clks IMX7ULP_CLK_GPU_DIV>,
+ <&clks IMX7ULP_CLK_GPU2D>,
+ <&clks IMX7ULP_CLK_NIC1_DIV>;
+ clock-names = "gpu3d_clk", "gpu3d_shader_clk",
+ "gpu3d_axi_clk", "gpu2d_clk",
+ "gpu2d_axi_clk";
+ };
+ };
+
+ heartbeat-rpmsg {
+ compatible = "fsl,heartbeat-rpmsg";
+ };
+
+ rtc-rpmsg {
+ compatible = "fsl,imx-rpmsg-rtc";
+ };
+
+ imx_ion {
+ compatible = "fsl,mxc-ion";
+ fsl,heap-id = <0>;
+ };
+};
diff --git a/arch/arm/configs/imx_v7_defconfig b/arch/arm/configs/imx_v7_defconfig
new file mode 100644
index 000000000000..1bd44d45f190
--- /dev/null
+++ b/arch/arm/configs/imx_v7_defconfig
@@ -0,0 +1,464 @@
+CONFIG_KERNEL_LZO=y
+CONFIG_SYSVIPC=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=18
+CONFIG_CGROUPS=y
+CONFIG_RELAY=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_EXPERT=y
+CONFIG_KALLSYMS_ALL=y
+CONFIG_PERF_EVENTS=y
+# CONFIG_SLUB_DEBUG is not set
+# CONFIG_COMPAT_BRK is not set
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+# CONFIG_BLK_DEV_BSG is not set
+CONFIG_ARCH_MXC=y
+CONFIG_SOC_IMX50=y
+CONFIG_SOC_IMX53=y
+CONFIG_SOC_IMX6Q=y
+CONFIG_SOC_IMX6SL=y
+CONFIG_SOC_IMX6SX=y
+CONFIG_SOC_IMX6ULL=y
+CONFIG_SOC_IMX7D=y
+CONFIG_SOC_IMX6SLL=y
+CONFIG_SOC_IMX7ULP=y
+CONFIG_SOC_VF610=y
+# CONFIG_SWP_EMULATE is not set
+CONFIG_SMP=y
+CONFIG_VMSPLIT_2G=y
+CONFIG_ARM_PSCI=y
+CONFIG_PREEMPT=y
+CONFIG_HIGHMEM=y
+CONFIG_CMA=y
+CONFIG_CMDLINE="noinitrd console=ttymxc0,115200"
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_STAT=y
+CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
+CONFIG_CPU_FREQ_GOV_POWERSAVE=y
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
+CONFIG_CPU_FREQ_GOV_INTERACTIVE=y
+CONFIG_CPUFREQ_DT=y
+CONFIG_ARM_IMX6Q_CPUFREQ=y
+CONFIG_ARM_IMX7ULP_CPUFREQ=y
+CONFIG_CPU_IDLE=y
+CONFIG_VFP=y
+CONFIG_NEON=y
+CONFIG_BINFMT_MISC=m
+CONFIG_PM_DEBUG=y
+CONFIG_PM_TEST_SUSPEND=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_VLAN_8021Q=y
+CONFIG_LLC2=y
+CONFIG_CAN=y
+CONFIG_CAN_FLEXCAN=y
+CONFIG_CAN_M_CAN=y
+CONFIG_BT=y
+CONFIG_BT_RFCOMM=y
+CONFIG_BT_RFCOMM_TTY=y
+CONFIG_BT_BNEP=y
+CONFIG_BT_BNEP_MC_FILTER=y
+CONFIG_BT_BNEP_PROTO_FILTER=y
+CONFIG_BT_HIDP=y
+CONFIG_BT_HCIBTUSB=y
+CONFIG_BT_HCIUART=y
+CONFIG_BT_HCIUART_BCSP=y
+CONFIG_BT_HCIUART_ATH3K=y
+CONFIG_BT_HCIBCM203X=y
+CONFIG_BT_ATH3K=y
+CONFIG_CFG80211=y
+CONFIG_NL80211_TESTMODE=y
+CONFIG_CFG80211_INTERNAL_REGDB=y
+CONFIG_CFG80211_WEXT=y
+CONFIG_MAC80211=y
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+# CONFIG_STANDALONE is not set
+CONFIG_DMA_CMA=y
+CONFIG_CMA_SIZE_MBYTES=0
+CONFIG_IMX_WEIM=y
+CONFIG_CONNECTOR=y
+CONFIG_MTD=y
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_JEDECPROBE=y
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_CFI_AMDSTD=y
+CONFIG_MTD_CFI_STAA=y
+CONFIG_MTD_PHYSMAP_OF=y
+CONFIG_MTD_DATAFLASH=y
+CONFIG_MTD_M25P80=y
+CONFIG_MTD_SST25L=y
+CONFIG_MTD_NAND=y
+CONFIG_MTD_NAND_GPMI_NAND=y
+CONFIG_MTD_NAND_MXC=y
+CONFIG_MTD_SPI_NOR=y
+# CONFIG_MTD_SPI_NOR_USE_4K_SECTORS is not set
+CONFIG_SPI_FSL_QUADSPI=y
+CONFIG_MTD_UBI=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=65536
+CONFIG_SENSORS_FXOS8700=y
+CONFIG_SENSORS_FXAS2100X=y
+CONFIG_EEPROM_AT24=y
+CONFIG_EEPROM_AT25=y
+# CONFIG_SCSI_PROC_FS is not set
+CONFIG_BLK_DEV_SD=y
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_LOGGING=y
+CONFIG_SCSI_SCAN_ASYNC=y
+# CONFIG_SCSI_LOWLEVEL is not set
+CONFIG_ATA=y
+CONFIG_SATA_AHCI_PLATFORM=y
+CONFIG_AHCI_IMX=y
+CONFIG_PATA_IMX=y
+CONFIG_NETDEVICES=y
+# CONFIG_NET_VENDOR_BROADCOM is not set
+CONFIG_CS89x0=y
+CONFIG_CS89x0_PLATFORM=y
+# 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_MICROCHIP is not set
+# CONFIG_NET_VENDOR_NATSEMI is not set
+# CONFIG_NET_VENDOR_SEEQ is not set
+CONFIG_SMC91X=y
+CONFIG_SMC911X=y
+CONFIG_SMSC911X=y
+# CONFIG_NET_VENDOR_STMICRO is not set
+CONFIG_MICREL_PHY=y
+CONFIG_USB_KAWETH=y
+CONFIG_USB_PEGASUS=y
+CONFIG_USB_RTL8150=y
+CONFIG_USB_RTL8152=y
+CONFIG_USB_USBNET=y
+CONFIG_USB_NET_CDC_EEM=m
+CONFIG_ATH6KL=m
+CONFIG_ATH6KL_SDIO=m
+CONFIG_BRCMFMAC=m
+CONFIG_HOSTAP=y
+CONFIG_INPUT_EVDEV=y
+CONFIG_INPUT_EVBUG=m
+CONFIG_KEYBOARD_GPIO=y
+CONFIG_KEYBOARD_RPMSG=y
+CONFIG_KEYBOARD_PF1550_ONKEY=y
+CONFIG_KEYBOARD_IMX=y
+CONFIG_MOUSE_PS2=m
+CONFIG_MOUSE_PS2_ELANTECH=y
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_ADS7846=y
+CONFIG_TOUCHSCREEN_EGALAX=y
+CONFIG_TOUCHSCREEN_ELAN_TS=y
+CONFIG_TOUCHSCREEN_GOODIX=y
+CONFIG_TOUCHSCREEN_MAX11801=y
+CONFIG_TOUCHSCREEN_IMX6UL_TSC=y
+CONFIG_TOUCHSCREEN_MC13783=y
+CONFIG_TOUCHSCREEN_TSC2007=y
+CONFIG_TOUCHSCREEN_STMPE=y
+CONFIG_TOUCHSCREEN_FTS=y
+CONFIG_INPUT_MISC=y
+CONFIG_INPUT_MMA8450=y
+CONFIG_INPUT_MPL3115=y
+CONFIG_SENSOR_FXLS8471=y
+CONFIG_SENSOR_IMX_RPMSG=y
+CONFIG_INPUT_ISL29023=y
+CONFIG_SERIO_SERPORT=m
+# CONFIG_LEGACY_PTYS is not set
+CONFIG_SERIAL_IMX=y
+CONFIG_SERIAL_IMX_CONSOLE=y
+CONFIG_SERIAL_FSL_LPUART=y
+CONFIG_SERIAL_FSL_LPUART_CONSOLE=y
+CONFIG_FSL_OTP=y
+CONFIG_HW_RANDOM_IMX_RNG=y
+# CONFIG_I2C_COMPAT is not set
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_MUX_GPIO=y
+# CONFIG_I2C_HELPER_AUTO is not set
+CONFIG_I2C_ALGOPCF=m
+CONFIG_I2C_ALGOPCA=m
+CONFIG_I2C_IMX=y
+CONFIG_I2C_IMX_LPI2C=y
+CONFIG_SPI=y
+CONFIG_SPI_FSL_LPSPI=y
+CONFIG_SPI_GPIO=y
+CONFIG_SPI_IMX=y
+CONFIG_SPI_SPIDEV=y
+CONFIG_SPI_SLAVE=y
+CONFIG_SPI_SLAVE_TIME=y
+CONFIG_SPI_SLAVE_SYSTEM_CONTROL=y
+CONFIG_GPIO_SYSFS=y
+CONFIG_GPIO_IMX_RPMSG=y
+CONFIG_GPIO_MAX732X=y
+CONFIG_GPIO_PCA953X=y
+CONFIG_GPIO_74X164=y
+CONFIG_POWER_RESET=y
+CONFIG_POWER_RESET_SYSCON_POWEROFF=y
+CONFIG_POWER_SUPPLY=y
+CONFIG_CHARGER_PF1550=y
+CONFIG_SABRESD_MAX8903=y
+CONFIG_SENSORS_MAX17135=y
+CONFIG_SENSORS_MAG3110=y
+CONFIG_THERMAL=y
+CONFIG_THERMAL_WRITABLE_TRIPS=y
+CONFIG_CPU_THERMAL=y
+CONFIG_IMX_THERMAL=y
+CONFIG_DEVICE_THERMAL=y
+CONFIG_WATCHDOG=y
+CONFIG_IMX2_WDT=y
+CONFIG_IMX7ULP_WDT=y
+CONFIG_MFD_DA9052_I2C=y
+CONFIG_MFD_MC13XXX_SPI=y
+CONFIG_MFD_MC13XXX_I2C=y
+CONFIG_MFD_PF1550=y
+CONFIG_MFD_MAX17135=y
+CONFIG_MFD_SI476X_CORE=y
+CONFIG_MFD_STMPE=y
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_FIXED_VOLTAGE=y
+CONFIG_REGULATOR_ANATOP=y
+CONFIG_REGULATOR_DA9052=y
+CONFIG_REGULATOR_GPIO=y
+CONFIG_REGULATOR_MAX17135=y
+CONFIG_REGULATOR_MC13783=y
+CONFIG_REGULATOR_MC13892=y
+CONFIG_REGULATOR_PFUZE100=y
+CONFIG_REGULATOR_PF1550=y
+CONFIG_REGULATOR_PF1550_RPMSG=y
+CONFIG_RC_DEVICES=y
+CONFIG_IR_GPIO_CIR=y
+CONFIG_MEDIA_SUPPORT=y
+CONFIG_MEDIA_CAMERA_SUPPORT=y
+CONFIG_MEDIA_RADIO_SUPPORT=y
+CONFIG_MEDIA_USB_SUPPORT=y
+CONFIG_USB_VIDEO_CLASS=m
+CONFIG_V4L_PLATFORM_DRIVERS=y
+CONFIG_VIDEO_MXC_OUTPUT=y
+CONFIG_VIDEO_MXC_CAPTURE=m
+CONFIG_VIDEO_MXC_CSI_CAMERA=m
+CONFIG_MXC_VADC=m
+CONFIG_MXC_MIPI_CSI=m
+CONFIG_MXC_CAMERA_OV5640=m
+CONFIG_MXC_CAMERA_OV5640_V2=m
+CONFIG_MXC_CAMERA_OV5642=m
+CONFIG_MXC_CAMERA_OV5640_MIPI=m
+CONFIG_MXC_CAMERA_OV5640_MIPI_V2=m
+CONFIG_MXC_CAMERA_OV5647_MIPI=m
+CONFIG_MXC_TVIN_ADV7180=m
+CONFIG_MXC_IPU_DEVICE_QUEUE_SDC=m
+CONFIG_VIDEO_MXC_IPU_OUTPUT=y
+CONFIG_VIDEO_MXC_PXP_V4L2=y
+CONFIG_SOC_CAMERA=y
+CONFIG_V4L_MEM2MEM_DRIVERS=y
+CONFIG_VIDEO_CODA=y
+CONFIG_RADIO_SI476X=y
+CONFIG_DRM=y
+CONFIG_DRM_VIVANTE=y
+CONFIG_FB_MXS=y
+CONFIG_FB_MXC_SYNC_PANEL=y
+CONFIG_FB_MXC_OVERLAY=y
+CONFIG_FB_MXC_MIPI_DSI=y
+CONFIG_FB_MXC_MIPI_DSI_SAMSUNG=y
+CONFIG_FB_MXC_MIPI_DSI_NORTHWEST=y
+CONFIG_FB_MXC_TRULY_WVGA_SYNC_PANEL=y
+CONFIG_FB_MXC_TRULY_PANEL_TFT3P5079E=y
+CONFIG_FB_MXC_TRULY_PANEL_TFT3P5581E=y
+CONFIG_FB_MXC_RK_PANEL_RK055AHD042=y
+CONFIG_FB_MXC_RK_PANEL_RK055IQH042=y
+CONFIG_FB_MXC_LDB=y
+CONFIG_FB_MXC_HDMI=y
+CONFIG_FB_MXS_SII902X=y
+CONFIG_FB_MXC_DCIC=m
+CONFIG_FB_MXC_ADV7535=y
+CONFIG_HANNSTAR_CABC=y
+CONFIG_FB_MXC_EINK_PANEL=y
+CONFIG_FB_MXC_EINK_V2_PANEL=y
+CONFIG_LCD_CLASS_DEVICE=y
+CONFIG_LCD_L4F00242T03=y
+CONFIG_LCD_PLATFORM=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_IMX_SOC=y
+CONFIG_SND_SOC_EUKREA_TLV320=y
+CONFIG_SND_SOC_IMX_WM8960=y
+CONFIG_SND_SOC_IMX_SII902X=y
+CONFIG_SND_SOC_IMX_WM8958=y
+CONFIG_SND_SOC_IMX_CS42888=y
+CONFIG_SND_SOC_IMX_WM8962=y
+CONFIG_SND_SOC_IMX_RPMSG=y
+CONFIG_SND_SOC_IMX_SGTL5000=y
+CONFIG_SND_SOC_IMX_MQS=y
+CONFIG_SND_SOC_IMX_SPDIF=y
+CONFIG_SND_SOC_IMX_MC13783=y
+CONFIG_SND_SOC_IMX_SI476X=y
+CONFIG_SND_SOC_IMX_HDMI=y
+CONFIG_USB=y
+CONFIG_USB_OTG_WHITELIST=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_MXC=y
+CONFIG_USB_HCD_TEST_MODE=y
+CONFIG_USB_ACM=m
+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_TEST=m
+CONFIG_USB_EHSET_TEST_FIXTURE=y
+CONFIG_NOP_USB_XCEIV=y
+CONFIG_USB_MXS_PHY=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_CONFIGFS=y
+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_FSL_UTP=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
+CONFIG_MMC_SDHCI_ESDHC_IMX=y
+CONFIG_MXC_SIM=y
+CONFIG_MXC_SIMv2=y
+CONFIG_MXC_IPU=y
+CONFIG_MXC_IPU_V3_PRE=y
+CONFIG_MXC_MIPI_CSI2=y
+CONFIG_MXC_HDMI_CEC=y
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_GPIO=y
+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_GPIO=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_INTF_DEV_UIE_EMUL=y
+CONFIG_RTC_DRV_MC13XXX=y
+CONFIG_RTC_DRV_MXC=y
+CONFIG_RTC_DRV_SNVS=y
+CONFIG_RTC_DRV_IMX_RPMSG=y
+CONFIG_DMADEVICES=y
+CONFIG_FSL_EDMA=y
+CONFIG_IMX_SDMA=y
+CONFIG_MXS_DMA=y
+CONFIG_MXC_PXP_V2=y
+CONFIG_MXC_PXP_V3=y
+CONFIG_DMATEST=m
+CONFIG_STAGING=y
+CONFIG_STAGING_MEDIA=y
+# CONFIG_IOMMU_SUPPORT is not set
+CONFIG_EXTCON_USB_GPIO=y
+CONFIG_IIO=y
+CONFIG_IMX7D_ADC=y
+CONFIG_VF610_ADC=y
+CONFIG_PWM=y
+CONFIG_PWM_IMX=y
+CONFIG_PWM_TPM=y
+CONFIG_TEE=y
+CONFIG_OPTEE=y
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+CONFIG_EXT2_FS_SECURITY=y
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS_POSIX_ACL=y
+CONFIG_EXT3_FS_SECURITY=y
+CONFIG_QUOTA=y
+CONFIG_QUOTA_NETLINK_INTERFACE=y
+# CONFIG_PRINT_QUOTA_WARNING is not set
+CONFIG_AUTOFS4_FS=y
+CONFIG_FUSE_FS=y
+CONFIG_ISO9660_FS=m
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
+CONFIG_UDF_FS=m
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=y
+CONFIG_TMPFS=y
+CONFIG_JFFS2_FS=y
+CONFIG_UBIFS_FS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=y
+CONFIG_ROOT_NFS=y
+CONFIG_NLS_DEFAULT="cp437"
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_ISO8859_15=m
+CONFIG_NLS_UTF8=y
+CONFIG_DEBUG_FS=y
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_SCHED_DEBUG is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_FTRACE is not set
+CONFIG_SECURITYFS=y
+CONFIG_CRYPTO_USER=y
+CONFIG_CRYPTO_TEST=m
+CONFIG_CRYPTO_CTS=y
+CONFIG_CRYPTO_LRW=y
+CONFIG_CRYPTO_XTS=y
+CONFIG_CRYPTO_MD4=y
+CONFIG_CRYPTO_MD5=y
+CONFIG_CRYPTO_RMD128=y
+CONFIG_CRYPTO_RMD160=y
+CONFIG_CRYPTO_RMD256=y
+CONFIG_CRYPTO_RMD320=y
+CONFIG_CRYPTO_SHA512=y
+CONFIG_CRYPTO_TGR192=y
+CONFIG_CRYPTO_WP512=y
+CONFIG_CRYPTO_BLOWFISH=y
+CONFIG_CRYPTO_CAMELLIA=y
+CONFIG_CRYPTO_TWOFISH=y
+CONFIG_CRYPTO_DEV_FSL_CAAM=y
+CONFIG_CRYPTO_DEV_FSL_CAAM_SM=y
+CONFIG_CRYPTO_DEV_FSL_CAAM_SM_TEST=y
+CONFIG_CRYPTO_DEV_FSL_CAAM_SECVIO=y
+CONFIG_CRYPTO_DEV_MXS_DCP=y
+CONFIG_CRC_CCITT=m
+CONFIG_CRC_T10DIF=y
+CONFIG_CRC7=m
+CONFIG_LIBCRC32C=m
+CONFIG_FONTS=y
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
diff --git a/arch/arm/include/asm/outercache.h b/arch/arm/include/asm/outercache.h
index c2bf24f40177..405ec8ddcd1a 100644
--- a/arch/arm/include/asm/outercache.h
+++ b/arch/arm/include/asm/outercache.h
@@ -39,6 +39,11 @@ struct outer_cache_fns {
/* This is an ARM L2C thing */
void (*write_sec)(unsigned long, unsigned);
void (*configure)(const struct l2x0_regs *);
+
+#ifdef CONFIG_OPTEE
+ /* Set a mutex with OPTEE for maintenance */
+ int (*set_mutex)(void *mutex);
+#endif
};
extern struct outer_cache_fns outer_cache;
@@ -115,6 +120,24 @@ static inline void outer_resume(void)
outer_cache.resume();
}
+#ifdef CONFIG_OPTEE
+/**
+ * @brief Setup the Cache Mutex
+ *
+ * @param[in] Reference to the Mutex object
+ *
+ * @retval 0 Success
+ * @retval -EINVAL Invalid value
+ */
+static inline int outer_mutex(void *mutex)
+{
+ if (outer_cache.set_mutex)
+ return outer_cache.set_mutex(mutex);
+
+ return -EINVAL;
+}
+#endif
+
#else
static inline void outer_inv_range(phys_addr_t start, phys_addr_t end)
diff --git a/arch/arm/include/debug/imx-uart.h b/arch/arm/include/debug/imx-uart.h
index bce58e975ad1..24e60ce18347 100644
--- a/arch/arm/include/debug/imx-uart.h
+++ b/arch/arm/include/debug/imx-uart.h
@@ -81,6 +81,14 @@
#define IMX6SL_UART_BASE_ADDR(n) IMX6SL_UART##n##_BASE_ADDR
#define IMX6SL_UART_BASE(n) IMX6SL_UART_BASE_ADDR(n)
+#define IMX6SLL_UART1_BASE_ADDR 0x02020000
+#define IMX6SLL_UART2_BASE_ADDR 0x02024000
+#define IMX6SLL_UART3_BASE_ADDR 0x02034000
+#define IMX6SLL_UART4_BASE_ADDR 0x02018000
+#define IMX6SLL_UART5_BASE_ADDR 0x021f4000
+#define IMX6SLL_UART_BASE_ADDR(n) IMX6SLL_UART##n##_BASE_ADDR
+#define IMX6SLL_UART_BASE(n) IMX6SLL_UART_BASE_ADDR(n)
+
#define IMX6SX_UART1_BASE_ADDR 0x02020000
#define IMX6SX_UART2_BASE_ADDR 0x021e8000
#define IMX6SX_UART3_BASE_ADDR 0x021ec000
@@ -133,6 +141,8 @@
#define UART_PADDR IMX_DEBUG_UART_BASE(IMX6Q)
#elif defined(CONFIG_DEBUG_IMX6SL_UART)
#define UART_PADDR IMX_DEBUG_UART_BASE(IMX6SL)
+#elif defined(CONFIG_DEBUG_IMX6SLL_UART)
+#define UART_PADDR IMX_DEBUG_UART_BASE(IMX6SLL)
#elif defined(CONFIG_DEBUG_IMX6SX_UART)
#define UART_PADDR IMX_DEBUG_UART_BASE(IMX6SX)
#elif defined(CONFIG_DEBUG_IMX6UL_UART)
diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index 782699e67600..7693cbdf1a9f 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -44,6 +44,9 @@ config MXC_USE_EPIT
uses the same clocks as the GPT. Anyway, on some systems the GPT
may be in use for other purposes.
+config HAVE_IMX_RNG
+ bool
+
config HAVE_IMX_ANATOP
bool
@@ -51,9 +54,26 @@ config HAVE_IMX_GPC
bool
select PM_GENERIC_DOMAINS if PM
+config HAVE_IMX_GPCV2
+ bool
+ select PM_GENERIC_DOMAINS if PM
+
config HAVE_IMX_MMDC
bool
+config HAVE_IMX_AMP
+ bool
+
+config HAVE_IMX_DDRC
+ bool
+
+config HAVE_IMX_MU
+ bool
+
+config HAVE_IMX_RPMSG
+ select RPMSG_VIRTIO
+ bool
+
config HAVE_IMX_SRC
def_bool y if SMP
select ARCH_HAS_RESET_CONTROLLER
@@ -491,6 +511,8 @@ config SOC_IMX6
select HAVE_IMX_MMDC
select HAVE_IMX_SRC
select MFD_SYSCON
+ select HAVE_ARM_SCU if SMP
+ select HAVE_ARM_TWD if SMP
select PL310_ERRATA_769419 if CACHE_L2X0
config SOC_IMX6Q
@@ -498,14 +520,17 @@ config SOC_IMX6Q
select ARM_ERRATA_764369 if SMP
select HAVE_ARM_SCU if SMP
select HAVE_ARM_TWD
+ select PCI_DOMAINS if PCI
select PINCTRL_IMX6Q
select SOC_IMX6
+ select MXC_MLB150
help
This enables support for Freescale i.MX6 Quad processor.
config SOC_IMX6SL
bool "i.MX6 SoloLite support"
+ select HAVE_IMX_RNG
select PINCTRL_IMX6SL
select SOC_IMX6
@@ -515,7 +540,14 @@ config SOC_IMX6SL
config SOC_IMX6SX
bool "i.MX6 SoloX support"
select PINCTRL_IMX6SX
+ select HAVE_IMX_AMP
select SOC_IMX6
+ select HAVE_IMX_MU
+ select HAVE_IMX_RPMSG
+ select RPMSG
+ select IMX_SEMA4
+ select MXC_MLB150
+ select KEYBOARD_SNVS_PWRKEY
help
This enables support for Freescale i.MX6 SoloX processor.
@@ -524,19 +556,42 @@ config SOC_IMX6UL
bool "i.MX6 UltraLite support"
select PINCTRL_IMX6UL
select SOC_IMX6
+ select KEYBOARD_SNVS_PWRKEY
+ select ARM_ERRATA_814220
help
This enables support for Freescale i.MX6 UltraLite processor.
+config SOC_IMX6ULL
+ bool "i.MX6 ULL support"
+ select SOC_IMX6UL
+
+ help
+ This enables support for Freescale i.MX6 ULL processor.
+
+config SOC_IMX7
+ bool
+ select CPU_V7
+ select ARM_GIC
+ select HAVE_IMX_MU
+ select HAVE_IMX_RPMSG
+ select RPMSG
+
config SOC_IMX7D
bool "i.MX7 Dual support"
+ select SOC_IMX7
+ select PCI_DOMAINS if PCI
select PINCTRL_IMX7D
- select ARM_GIC
select HAVE_ARM_ARCH_TIMER
select HAVE_IMX_ANATOP
select HAVE_IMX_MMDC
+ select HAVE_IMX_DDRC
select HAVE_IMX_SRC
select IMX_GPCV2
+ select KEYBOARD_SNVS_PWRKEY
+ select HAVE_IMX_GPCV2
+ select ARM_ERRATA_814220
+
help
This enables support for Freescale i.MX7 Dual processor.
@@ -554,6 +609,23 @@ comment "Cortex-A/Cortex-M asymmetric multiprocessing platforms"
if ARCH_MULTI_V7 || ARM_SINGLE_ARMV7M
+config SOC_IMX6SLL
+ bool "i.MX6 SLL support"
+ select PINCTRL_IMX6SLL
+ select SOC_IMX6
+ select KEYBOARD_SNVS_PWRKEY
+
+ help
+ This enables support for Freescale i.MX6 SLL processor.
+
+config SOC_IMX7ULP
+ bool "i.MX7ULP support"
+ select SOC_IMX7
+ select CLKSRC_IMX_TPM
+ select PINCTRL_IMX7ULP
+ help
+ This enables support for Freescale i.MX7 Ultra Low Power processor.
+
config SOC_VF610
bool "Vybrid Family VF610 support"
select ARM_GIC if ARCH_MULTI_V7
diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile
index 8ff71058207d..b52bc47ccdd7 100644
--- a/arch/arm/mach-imx/Makefile
+++ b/arch/arm/mach-imx/Makefile
@@ -1,5 +1,5 @@
# SPDX-License-Identifier: GPL-2.0
-obj-y := cpu.o system.o irq-common.o
+obj-y := cpu.o system.o irq-common.o common.o
obj-$(CONFIG_SOC_IMX21) += mm-imx21.o
@@ -26,9 +26,19 @@ obj-$(CONFIG_MXC_DEBUG_BOARD) += 3ds_debugboard.o
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
-obj-$(CONFIG_SOC_IMX6SX) += cpuidle-imx6sx.o
-obj-$(CONFIG_SOC_IMX6UL) += cpuidle-imx6sx.o
+obj-$(CONFIG_SOC_IMX7ULP) += cpuidle-imx7ulp.o
+AFLAGS_imx6sl_low_power_idle.o :=-Wa,-march=armv7-a
+obj-$(CONFIG_SOC_IMX6SL) += cpuidle-imx6sl.o imx6sl_low_power_idle.o
+AFLAGS_imx6sx_low_power_idle.o :=-Wa,-march=armv7-a
+obj-$(CONFIG_SOC_IMX6SX) += cpuidle-imx6sx.o imx6sx_low_power_idle.o
+AFLAGS_imx6ul_low_power_idle.o :=-Wa,-march=armv7-a
+obj-$(CONFIG_SOC_IMX6UL) += cpuidle-imx6ul.o imx6ul_low_power_idle.o
+AFLAGS_imx6ull_low_power_idle.o :=-Wa,-march=armv7-a
+obj-$(CONFIG_SOC_IMX6ULL) += imx6ull_low_power_idle.o
+AFLAGS_imx6sll_low_power_idle.o :=-Wa,-march=armv7-a
+obj-$(CONFIG_SOC_IMX6SLL) += cpuidle-imx6sll.o imx6sll_low_power_idle.o
+AFLAGS_imx7d_low_power_idle.o :=-Wa,-march=armv7-a
+obj-$(CONFIG_SOC_IMX7D) += cpuidle-imx7d.o imx7d_low_power_idle.o
endif
ifdef CONFIG_SND_IMX_SOC
@@ -69,25 +79,50 @@ obj-$(CONFIG_MACH_IMX35_DT) += imx35-dt.o
obj-$(CONFIG_HAVE_IMX_ANATOP) += anatop.o
obj-$(CONFIG_HAVE_IMX_GPC) += gpc.o
+obj-$(CONFIG_HAVE_IMX_GPCV2) += gpcv2.o
obj-$(CONFIG_HAVE_IMX_MMDC) += mmdc.o
+obj-$(CONFIG_HAVE_IMX_DDRC) += ddrc.o
obj-$(CONFIG_HAVE_IMX_SRC) += src.o
-ifneq ($(CONFIG_SOC_IMX6)$(CONFIG_SOC_LS1021A),)
+obj-$(CONFIG_HAVE_IMX_MU) += mu.o
+ifneq ($(CONFIG_SOC_IMX6)$(CONFIG_SOC_IMX7)$(CONFIG_SOC_LS1021A),)
AFLAGS_headsmp.o :=-Wa,-march=armv7-a
obj-$(CONFIG_SMP) += headsmp.o platsmp.o
obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
endif
-obj-$(CONFIG_SOC_IMX6Q) += mach-imx6q.o
-obj-$(CONFIG_SOC_IMX6SL) += mach-imx6sl.o
-obj-$(CONFIG_SOC_IMX6SX) += mach-imx6sx.o
-obj-$(CONFIG_SOC_IMX6UL) += mach-imx6ul.o
+obj-y += busfreq_lpddr2.o busfreq-imx.o busfreq_ddr3.o
+AFLAGS_ddr3_freq_imx6.o :=-Wa,-march=armv7-a
+AFLAGS_smp_wfe_imx6.o :=-Wa,-march=armv7-a
+AFLAGS_lpddr2_freq_imx6q.o :=-Wa,-march=armv7-a
+obj-$(CONFIG_SOC_IMX6Q) += mach-imx6q.o ddr3_freq_imx6.o smp_wfe_imx6.o \
+ lpddr2_freq_imx6q.o
+AFLAGS_lpddr2_freq_imx6.o :=-Wa,-march=armv7-a
+obj-$(CONFIG_SOC_IMX6SL) += mach-imx6sl.o lpddr2_freq_imx6.o
+AFLAGS_lpddr2_freq_imx6sll.o :=-Wa,-march=armv7-a
+obj-$(CONFIG_SOC_IMX6SLL) += mach-imx6sl.o lpddr2_freq_imx6sll.o
+AFLAGS_lpddr2_freq_imx6sx.o :=-Wa,-march=armv7-a
+AFLAGS_ddr3_freq_imx6sx.o :=-Wa,-march=armv7-a
+obj-$(CONFIG_SOC_IMX6SX) += mach-imx6sx.o ddr3_freq_imx6sx.o \
+ lpddr2_freq_imx6sx.o
+obj-$(CONFIG_SOC_IMX6UL) += mach-imx6ul.o ddr3_freq_imx6sx.o \
+ lpddr2_freq_imx6sx.o
obj-$(CONFIG_SOC_IMX7D) += mach-imx7d.o
+obj-$(CONFIG_SOC_IMX7ULP) += mach-imx7ulp.o pm-imx7ulp.o pm-rpmsg.o
ifeq ($(CONFIG_SUSPEND),y)
AFLAGS_suspend-imx6.o :=-Wa,-march=armv7-a
+AFLAGS_suspend-imx7.o :=-Wa,-march=armv7-a
+AFLAGS_suspend-imx7ulp.o :=-Wa,-march=armv7-a
obj-$(CONFIG_SOC_IMX6) += suspend-imx6.o
+obj-$(CONFIG_SOC_IMX7D) += suspend-imx7.o
obj-$(CONFIG_SOC_IMX53) += suspend-imx53.o
+obj-$(CONFIG_SOC_IMX7ULP) += suspend-imx7ulp.o
endif
obj-$(CONFIG_SOC_IMX6) += pm-imx6.o
+AFLAGS_smp_wfe.o :=-Wa,-march=armv7-a
+AFLAGS_ddr3_freq_imx7d.o :=-Wa,-march=armv7-a
+AFLAGS_lpddr3_freq_imx.o :=-Wa,-march=armv7-a
+obj-$(CONFIG_SOC_IMX7D) += pm-imx7.o ddr3_freq_imx7d.o smp_wfe.o \
+ lpddr3_freq_imx.o
obj-$(CONFIG_SOC_IMX1) += mach-imx1.o
obj-$(CONFIG_SOC_IMX50) += mach-imx50.o
@@ -98,4 +133,9 @@ obj-$(CONFIG_SOC_VF610) += mach-vf610.o
obj-$(CONFIG_SOC_LS1021A) += mach-ls1021a.o
+ifneq ($(CONFIG_SOC_IMX6)$(CONFIG_SOC_IMX7),)
+# Bus frequency by OPTEE OS
+obj-$(CONFIG_OPTEE) += busfreq_optee.o
+endif
+
obj-y += devices/
diff --git a/arch/arm/mach-imx/anatop.c b/arch/arm/mach-imx/anatop.c
index 649a84c251ad..7716fd5fe58a 100644
--- a/arch/arm/mach-imx/anatop.c
+++ b/arch/arm/mach-imx/anatop.c
@@ -1,5 +1,6 @@
/*
- * Copyright (C) 2013-2015 Freescale Semiconductor, Inc.
+ * Copyright (C) 2013-2016 Freescale Semiconductor, Inc.
+ * Copyright 2017 NXP.
*
* The code contained herein is licensed under the GNU General Public
* License. You may obtain a copy of the GNU General Public License
@@ -9,6 +10,7 @@
* http://www.gnu.org/copyleft/gpl.html
*/
+#include <linux/delay.h>
#include <linux/err.h>
#include <linux/io.h>
#include <linux/of.h>
@@ -21,9 +23,17 @@
#define REG_SET 0x4
#define REG_CLR 0x8
+#define ANADIG_ARM_PLL 0x60
+#define ANADIG_DDR_PLL 0x70
+#define ANADIG_SYS_PLL 0xb0
+#define ANADIG_ENET_PLL 0xe0
+#define ANADIG_AUDIO_PLL 0xf0
+#define ANADIG_VIDEO_PLL 0x130
+
#define ANADIG_REG_2P5 0x130
#define ANADIG_REG_CORE 0x140
#define ANADIG_ANA_MISC0 0x150
+#define ANADIG_ANA_MISC2 0x170
#define ANADIG_USB1_CHRG_DETECT 0x1b0
#define ANADIG_USB2_CHRG_DETECT 0x210
#define ANADIG_DIGPROG 0x260
@@ -33,24 +43,43 @@
#define BM_ANADIG_REG_2P5_ENABLE_WEAK_LINREG 0x40000
#define BM_ANADIG_REG_2P5_ENABLE_PULLDOWN 0x8
#define BM_ANADIG_REG_CORE_FET_ODRIVE 0x20000000
+#define BM_ANADIG_REG_CORE_REG1 (0x1f << 9)
+#define BM_ANADIG_REG_CORE_REG2 (0x1f << 18)
+#define BP_ANADIG_REG_CORE_REG2 (18)
#define BM_ANADIG_ANA_MISC0_STOP_MODE_CONFIG 0x1000
+#define BM_ANADIG_ANA_MISC0_V2_STOP_MODE_CONFIG 0x800
+#define BM_ANADIG_ANA_MISC0_V3_STOP_MODE_CONFIG 0xc00
+#define BM_ANADIG_ANA_MISC2_REG1_STEP_TIME (0x3 << 26)
+#define BP_ANADIG_ANA_MISC2_REG1_STEP_TIME (26)
/* Below MISC0_DISCON_HIGH_SNVS is only for i.MX6SL */
#define BM_ANADIG_ANA_MISC0_DISCON_HIGH_SNVS 0x2000
+/* Since i.MX6SX, DISCON_HIGH_SNVS is changed to bit 12 */
+#define BM_ANADIG_ANA_MISC0_V2_DISCON_HIGH_SNVS 0x1000
#define BM_ANADIG_USB_CHRG_DETECT_CHK_CHRG_B 0x80000
#define BM_ANADIG_USB_CHRG_DETECT_EN_B 0x100000
+#define LDO_RAMP_UP_UNIT_IN_CYCLES 64 /* 64 cycles per step */
+#define LDO_RAMP_UP_FREQ_IN_MHZ 24 /* cycle based on 24M OSC */
+
static struct regmap *anatop;
static void imx_anatop_enable_weak2p5(bool enable)
{
- u32 reg, val;
+ u32 reg, val, mask;
regmap_read(anatop, ANADIG_ANA_MISC0, &val);
+ if (cpu_is_imx6sx() || cpu_is_imx6ul() || cpu_is_imx6ull()
+ || cpu_is_imx6sll())
+ mask = BM_ANADIG_ANA_MISC0_V3_STOP_MODE_CONFIG;
+ else if (cpu_is_imx6sl())
+ mask = BM_ANADIG_ANA_MISC0_V2_STOP_MODE_CONFIG;
+ else
+ mask = BM_ANADIG_ANA_MISC0_STOP_MODE_CONFIG;
+
/* can only be enabled when stop_mode_config is clear. */
reg = ANADIG_REG_2P5;
- reg += (enable && (val & BM_ANADIG_ANA_MISC0_STOP_MODE_CONFIG) == 0) ?
- REG_SET : REG_CLR;
+ reg += (enable && (val & mask) == 0) ? REG_SET : REG_CLR;
regmap_write(anatop, reg, BM_ANADIG_REG_2P5_ENABLE_WEAK_LINREG);
}
@@ -68,35 +97,100 @@ static inline void imx_anatop_enable_2p5_pulldown(bool enable)
static inline void imx_anatop_disconnect_high_snvs(bool enable)
{
- regmap_write(anatop, ANADIG_ANA_MISC0 + (enable ? REG_SET : REG_CLR),
- BM_ANADIG_ANA_MISC0_DISCON_HIGH_SNVS);
+ if (cpu_is_imx6sx() || cpu_is_imx6ul() || cpu_is_imx6ull() ||
+ cpu_is_imx6sll())
+ regmap_write(anatop, ANADIG_ANA_MISC0 +
+ (enable ? REG_SET : REG_CLR),
+ BM_ANADIG_ANA_MISC0_V2_DISCON_HIGH_SNVS);
+ else
+ regmap_write(anatop, ANADIG_ANA_MISC0 +
+ (enable ? REG_SET : REG_CLR),
+ BM_ANADIG_ANA_MISC0_DISCON_HIGH_SNVS);
+}
+
+static void imx_anatop_disable_pu(bool off)
+{
+ u32 val, soc, delay;
+ if (off) {
+ regmap_read(anatop, ANADIG_REG_CORE, &val);
+ val &= ~BM_ANADIG_REG_CORE_REG1;
+ regmap_write(anatop, ANADIG_REG_CORE, val);
+ } else {
+ /* track vddpu with vddsoc */
+ regmap_read(anatop, ANADIG_REG_CORE, &val);
+ soc = val & BM_ANADIG_REG_CORE_REG2;
+ val &= ~BM_ANADIG_REG_CORE_REG1;
+ val |= soc >> 9;
+ regmap_write(anatop, ANADIG_REG_CORE, val);
+ /* wait PU LDO ramp */
+ regmap_read(anatop, ANADIG_ANA_MISC2, &val);
+ val &= BM_ANADIG_ANA_MISC2_REG1_STEP_TIME;
+ val >>= BP_ANADIG_ANA_MISC2_REG1_STEP_TIME;
+ delay = (soc >> BP_ANADIG_REG_CORE_REG2) *
+ (LDO_RAMP_UP_UNIT_IN_CYCLES << val) /
+ LDO_RAMP_UP_FREQ_IN_MHZ + 1;
+ udelay(delay);
+ }
}
void imx_anatop_pre_suspend(void)
{
- if (imx_mmdc_get_ddr_type() == IMX_DDR_TYPE_LPDDR2)
+ if (cpu_is_imx7d()) {
+ /* PLL and PFDs overwrite set */
+ regmap_write(anatop, ANADIG_ARM_PLL + REG_SET, 1 << 20);
+ regmap_write(anatop, ANADIG_DDR_PLL + REG_SET, 1 << 19);
+ regmap_write(anatop, ANADIG_SYS_PLL + REG_SET, 0x1ff << 17);
+ regmap_write(anatop, ANADIG_ENET_PLL + REG_SET, 1 << 13);
+ regmap_write(anatop, ANADIG_AUDIO_PLL + REG_SET, 1 << 24);
+ regmap_write(anatop, ANADIG_VIDEO_PLL + REG_SET, 1 << 24);
+ return;
+ }
+
+ if (cpu_is_imx6q() && imx_get_soc_revision() >= IMX_CHIP_REVISION_2_0)
+ imx_anatop_disable_pu(true);
+
+ if ((imx_mmdc_get_ddr_type() == IMX_DDR_TYPE_LPDDR2 ||
+ imx_mmdc_get_ddr_type() == IMX_MMDC_DDR_TYPE_LPDDR3) &&
+ !imx_gpc_usb_wakeup_enabled() && !imx_gpc_enet_wakeup_enabled())
imx_anatop_enable_2p5_pulldown(true);
else
imx_anatop_enable_weak2p5(true);
imx_anatop_enable_fet_odrive(true);
- if (cpu_is_imx6sl())
+ if (cpu_is_imx6sl() || cpu_is_imx6sx() || cpu_is_imx6ul() ||
+ cpu_is_imx6ull() || cpu_is_imx6sll())
imx_anatop_disconnect_high_snvs(true);
}
void imx_anatop_post_resume(void)
{
- if (imx_mmdc_get_ddr_type() == IMX_DDR_TYPE_LPDDR2)
+ if (cpu_is_imx7d()) {
+ /* PLL and PFDs overwrite clear */
+ regmap_write(anatop, ANADIG_ARM_PLL + REG_CLR, 1 << 20);
+ regmap_write(anatop, ANADIG_DDR_PLL + REG_CLR, 1 << 19);
+ regmap_write(anatop, ANADIG_SYS_PLL + REG_CLR, 0x1ff << 17);
+ regmap_write(anatop, ANADIG_ENET_PLL + REG_CLR, 1 << 13);
+ regmap_write(anatop, ANADIG_AUDIO_PLL + REG_CLR, 1 << 24);
+ regmap_write(anatop, ANADIG_VIDEO_PLL + REG_CLR, 1 << 24);
+ return;
+ }
+
+ if (cpu_is_imx6q() && imx_get_soc_revision() >= IMX_CHIP_REVISION_2_0)
+ imx_anatop_disable_pu(false);
+
+ if ((imx_mmdc_get_ddr_type() == IMX_DDR_TYPE_LPDDR2 ||
+ imx_mmdc_get_ddr_type() == IMX_MMDC_DDR_TYPE_LPDDR3) &&
+ !imx_gpc_usb_wakeup_enabled() && !imx_gpc_enet_wakeup_enabled())
imx_anatop_enable_2p5_pulldown(false);
else
imx_anatop_enable_weak2p5(false);
imx_anatop_enable_fet_odrive(false);
- if (cpu_is_imx6sl())
+ if (cpu_is_imx6sl() || cpu_is_imx6sx() || cpu_is_imx6ul() ||
+ cpu_is_imx6ull() || cpu_is_imx6sll())
imx_anatop_disconnect_high_snvs(false);
-
}
static void imx_anatop_usb_chrg_detect_disable(void)
@@ -113,9 +207,11 @@ void __init imx_init_revision_from_anatop(void)
{
struct device_node *np;
void __iomem *anatop_base;
+ void __iomem *src_base;
unsigned int revision;
- u32 digprog;
+ u32 digprog, sbmr2 = 0;
u16 offset = ANADIG_DIGPROG;
+ u16 major_part, minor_part;
np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-anatop");
anatop_base = of_iomap(np, 0);
@@ -127,45 +223,39 @@ void __init imx_init_revision_from_anatop(void)
digprog = readl_relaxed(anatop_base + offset);
iounmap(anatop_base);
- switch (digprog & 0xff) {
- case 0:
- /*
- * For i.MX6QP, most of the code for i.MX6Q can be resued,
- * so internally, we identify it as i.MX6Q Rev 2.0
- */
- if (digprog >> 8 & 0x01)
- revision = IMX_CHIP_REVISION_2_0;
- else
- revision = IMX_CHIP_REVISION_1_0;
- break;
- case 1:
- revision = IMX_CHIP_REVISION_1_1;
- break;
- case 2:
- revision = IMX_CHIP_REVISION_1_2;
- break;
- case 3:
- revision = IMX_CHIP_REVISION_1_3;
- break;
- case 4:
- revision = IMX_CHIP_REVISION_1_4;
- break;
- case 5:
- /*
- * i.MX6DQ TO1.5 is defined as Rev 1.3 in Data Sheet, marked
- * as 'D' in Part Number last character.
- */
- revision = IMX_CHIP_REVISION_1_5;
- break;
- default:
+ if ((digprog >> 16) == MXC_CPU_IMX6ULL) {
+ np = of_find_compatible_node(NULL, NULL, "fsl,imx6ul-src");
+ if (np) {
+ src_base = of_iomap(np, 0);
+ WARN_ON(!src_base);
+ sbmr2 = readl_relaxed(src_base + 0x1c);
+ iounmap(src_base);
+ }
+ if (sbmr2 & (1 << 6)) {
+ digprog &= ~(0xff << 16);
+ digprog |= (MXC_CPU_IMX6ULZ << 16);
+ }
+ }
+
+ /*
+ * On i.MX7D digprog value match linux version format, so
+ * it needn't map again and we can use register value directly.
+ */
+ if (of_device_is_compatible(np, "fsl,imx7d-anatop")) {
+ revision = digprog & 0xff;
+ } else {
/*
- * Fail back to return raw register value instead of 0xff.
- * It will be easy to know version information in SOC if it
- * can't be recognized by known version. And some chip's (i.MX7D)
- * digprog value match linux version format, so it needn't map
- * again and we can use register value directly.
+ * MAJOR: [15:8], the major silicon revison;
+ * MINOR: [7: 0], the minor silicon revison;
+ *
+ * please refer to the i.MX RM for the detailed
+ * silicon revison bit define.
+ * format the major part and minor part to match the
+ * linux kernel soc version format.
*/
- revision = digprog & 0xff;
+ major_part = (digprog >> 8) & 0xf;
+ minor_part = digprog & 0xf;
+ revision = ((major_part + 1) << 4) | minor_part;
}
mxc_set_cpu_type(digprog >> 16 & 0xff);
diff --git a/arch/arm/mach-imx/busfreq-imx.c b/arch/arm/mach-imx/busfreq-imx.c
new file mode 100644
index 000000000000..4c355e2374ba
--- /dev/null
+++ b/arch/arm/mach-imx/busfreq-imx.c
@@ -0,0 +1,1453 @@
+/*
+ * Copyright (C) 2011-2016 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2017 NXP.
+ * Copyright 2018 NXP.
+ *
+ * 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 <asm/cacheflush.h>
+#include <asm/fncpy.h>
+#include <asm/io.h>
+#include <asm/mach/map.h>
+#include <asm/mach-types.h>
+#include <asm/tlb.h>
+#include <linux/busfreq-imx.h>
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/delay.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/of.h>
+#include <linux/of_fdt.h>
+#include <linux/platform_device.h>
+#include <linux/proc_fs.h>
+#include <linux/reboot.h>
+#include <linux/regulator/consumer.h>
+#include <linux/sched.h>
+#include <linux/suspend.h>
+#include "hardware.h"
+#include "common.h"
+
+#define LPAPM_CLK 24000000
+#define LOW_AUDIO_CLK 50000000
+#define HIGH_AUDIO_CLK 100000000
+
+#define LOW_POWER_RUN_VOLTAGE 950000
+
+#define MMDC_MDMISC_DDR_TYPE_DDR3 0
+#define MMDC_MDMISC_DDR_TYPE_LPDDR2 1
+
+unsigned int ddr_med_rate;
+unsigned int ddr_normal_rate;
+unsigned long ddr_freq_change_total_size;
+unsigned long ddr_freq_change_iram_base;
+unsigned long ddr_freq_change_iram_phys;
+
+static int ddr_type;
+static int low_bus_freq_mode;
+static int audio_bus_freq_mode;
+static int ultra_low_bus_freq_mode;
+static int high_bus_freq_mode;
+static int med_bus_freq_mode;
+static int bus_freq_scaling_initialized;
+static bool cancel_reduce_bus_freq;
+static struct device *busfreq_dev;
+static int busfreq_suspended;
+static int bus_freq_scaling_is_active;
+static int high_bus_count, med_bus_count, audio_bus_count, low_bus_count;
+static unsigned int ddr_low_rate;
+static int cur_bus_freq_mode;
+static u32 org_arm_rate;
+static int origin_arm_volt, origin_soc_volt;
+
+extern unsigned long iram_tlb_phys_addr;
+extern int unsigned long iram_tlb_base_addr;
+
+/*
+ * Bus frequency management by Linux
+ */
+extern int init_mmdc_lpddr2_settings(struct platform_device *dev);
+extern int init_mmdc_lpddr2_settings_mx6q(struct platform_device *dev);
+extern int init_mmdc_ddr3_settings_imx6_up(struct platform_device *dev);
+extern int init_mmdc_ddr3_settings_imx6_smp(struct platform_device *dev);
+extern int init_ddrc_ddr_settings(struct platform_device *dev);
+extern int update_ddr_freq_imx_smp(int ddr_rate);
+extern int update_ddr_freq_imx6_up(int ddr_rate);
+extern int update_lpddr2_freq(int ddr_rate);
+extern int update_lpddr2_freq_smp(int ddr_rate);
+
+#ifdef CONFIG_OPTEE
+/*
+ * Bus frequency management by OPTEE OS
+ */
+extern int update_freq_optee(int ddr_rate);
+extern int init_freq_optee(struct platform_device *busfreq_pdev);
+#endif
+
+/**
+ * @brief Functions to init and update the busfreq function of
+ * device and memory type
+ */
+static struct busfreq_func {
+ int (*init)(struct platform_device *dev);
+ int (*update)(int ddr_rate);
+} busfreq_func = {NULL, NULL};
+
+DEFINE_MUTEX(bus_freq_mutex);
+
+static struct clk *osc_clk;
+static struct clk *ahb_clk;
+static struct clk *axi_sel_clk;
+static struct clk *dram_root;
+static struct clk *dram_alt_sel;
+static struct clk *dram_alt_root;
+static struct clk *pfd0_392m;
+static struct clk *pfd2_270m;
+static struct clk *pfd1_332m;
+static struct clk *pll_dram;
+static struct clk *ahb_sel_clk;
+static struct clk *axi_clk;
+
+static struct clk *m4_clk;
+static struct clk *arm_clk;
+static struct clk *pll3_clk;
+static struct clk *step_clk;
+static struct clk *mmdc_clk;
+static struct clk *ocram_clk;
+static struct clk *pll1_clk;
+static struct clk *pll1_bypass_clk;
+static struct clk *pll1_bypass_src_clk;
+static struct clk *pll1_sys_clk;
+static struct clk *pll1_sw_clk;
+static struct clk *pll2_bypass_src_clk;
+static struct clk *pll2_bypass_clk;
+static struct clk *pll2_clk;
+static struct clk *pll2_400_clk;
+static struct clk *pll2_200_clk;
+static struct clk *pll2_bus_clk;
+static struct clk *periph_clk;
+static struct clk *periph_pre_clk;
+static struct clk *periph_clk2_clk;
+static struct clk *periph_clk2_sel_clk;
+static struct clk *periph2_clk;
+static struct clk *periph2_pre_clk;
+static struct clk *periph2_clk2_clk;
+static struct clk *periph2_clk2_sel_clk;
+static struct clk *axi_alt_sel_clk;
+static struct clk *pll3_pfd1_540m_clk;
+
+static struct delayed_work low_bus_freq_handler;
+static struct delayed_work bus_freq_daemon;
+
+static RAW_NOTIFIER_HEAD(busfreq_notifier_chain);
+
+static bool check_m4_sleep(void)
+{
+ unsigned long timeout = jiffies + msecs_to_jiffies(500);
+
+ while (imx_gpc_is_m4_sleeping() == 0)
+ if (time_after(jiffies, timeout))
+ return false;
+ return true;
+}
+
+static bool busfreq_notified_low = false;
+
+static int busfreq_notify(enum busfreq_event event)
+{
+ int ret;
+
+ if (event == LOW_BUSFREQ_ENTER) {
+ WARN_ON(busfreq_notified_low);
+ busfreq_notified_low = true;
+ } else if (event == LOW_BUSFREQ_EXIT) {
+ WARN_ON(!busfreq_notified_low);
+ busfreq_notified_low = false;
+ }
+ ret = raw_notifier_call_chain(&busfreq_notifier_chain, event, NULL);
+
+ return notifier_to_errno(ret);
+}
+
+int register_busfreq_notifier(struct notifier_block *nb)
+{
+ return raw_notifier_chain_register(&busfreq_notifier_chain, nb);
+}
+EXPORT_SYMBOL(register_busfreq_notifier);
+
+int unregister_busfreq_notifier(struct notifier_block *nb)
+{
+ return raw_notifier_chain_unregister(&busfreq_notifier_chain, nb);
+}
+EXPORT_SYMBOL(unregister_busfreq_notifier);
+
+static struct clk *origin_step_parent;
+
+/*
+ * on i.MX6ULL, when entering low bus mode, the ARM core
+ * can run at 24MHz to support the low power run mode per
+ * to design team.
+ */
+static void imx6ull_lower_cpu_rate(bool enter)
+{
+ int ret;
+
+ if (enter) {
+ org_arm_rate = clk_get_rate(arm_clk);
+ origin_arm_volt = regulator_get_voltage(arm_reg);
+ origin_soc_volt = regulator_get_voltage(soc_reg);
+ }
+
+ clk_set_parent(pll1_bypass_clk, pll1_bypass_src_clk);
+ clk_set_parent(pll1_sw_clk, pll1_sys_clk);
+
+ if (enter) {
+ origin_step_parent = clk_get_parent(step_clk);
+ clk_set_parent(step_clk, osc_clk);
+ clk_set_parent(pll1_sw_clk, step_clk);
+ clk_set_rate(arm_clk, LPAPM_CLK);
+ if (cpu_is_imx6sll() && uart_from_osc) {
+ ret = regulator_set_voltage_tol(arm_reg, LOW_POWER_RUN_VOLTAGE, 0);
+ if (ret)
+ pr_err("set arm reg voltage failed\n");
+ ret = regulator_set_voltage_tol(soc_reg, LOW_POWER_RUN_VOLTAGE, 0);
+ if (ret)
+ pr_err("set soc reg voltage failed\n");
+ }
+ } else {
+ if (uart_from_osc) {
+ ret = regulator_set_voltage_tol(soc_reg, origin_soc_volt, 0);
+ if (ret)
+ pr_err("set soc reg voltage failed\n");
+ ret = regulator_set_voltage_tol(arm_reg, origin_arm_volt, 0);
+ if (ret)
+ pr_err("set arm reg voltage failed\n");
+ }
+ clk_set_parent(step_clk, origin_step_parent);
+ clk_set_parent(pll1_sw_clk, step_clk);
+ clk_set_rate(arm_clk, org_arm_rate);
+ clk_set_parent(pll1_bypass_clk, pll1_clk);
+ }
+}
+
+/*
+ * enter_lpm_imx6_up and exit_lpm_imx6_up is used by
+ * i.MX6SX/i.MX6UL for entering and exiting lpm mode.
+ */
+static void enter_lpm_imx6_up(void)
+{
+ if (cpu_is_imx6sx() && imx_src_is_m4_enabled())
+ if (!check_m4_sleep())
+ pr_err("M4 is NOT in sleep!!!\n");
+
+ /* set periph_clk2 to source from OSC for periph */
+ clk_set_parent(periph_clk2_sel_clk, osc_clk);
+ clk_set_parent(periph_clk, periph_clk2_clk);
+ /* set ahb/ocram to 24MHz */
+ clk_set_rate(ahb_clk, LPAPM_CLK);
+ clk_set_rate(ocram_clk, LPAPM_CLK);
+
+ if (audio_bus_count) {
+ /* Need to ensure that PLL2_PFD_400M is kept ON. */
+ clk_prepare_enable(pll2_400_clk);
+ if (ddr_type == IMX_DDR_TYPE_DDR3)
+ busfreq_func.update(LOW_AUDIO_CLK);
+ else if (ddr_type == IMX_DDR_TYPE_LPDDR2 ||
+ ddr_type == IMX_MMDC_DDR_TYPE_LPDDR3)
+ busfreq_func.update(HIGH_AUDIO_CLK);
+ clk_set_parent(periph2_clk2_sel_clk, pll3_clk);
+ clk_set_parent(periph2_pre_clk, pll2_400_clk);
+ clk_set_parent(periph2_clk, periph2_pre_clk);
+ /*
+ * As periph2_clk's parent is not changed from
+ * high mode to audio mode, so clk framework
+ * will not update its children's freq, but we
+ * change the mmdc's podf in asm code, so here
+ * need to update mmdc rate to make sure clk
+ * tree is right, although it will not do any
+ * change to hardware.
+ */
+ if (high_bus_freq_mode) {
+ if (ddr_type == IMX_DDR_TYPE_DDR3)
+ clk_set_rate(mmdc_clk, LOW_AUDIO_CLK);
+ else if (ddr_type == IMX_DDR_TYPE_LPDDR2 ||
+ ddr_type == IMX_MMDC_DDR_TYPE_LPDDR3)
+ clk_set_rate(mmdc_clk, HIGH_AUDIO_CLK);
+ }
+
+ if ((cpu_is_imx6ull() || cpu_is_imx6sll()) && low_bus_freq_mode)
+ imx6ull_lower_cpu_rate(false);
+
+ audio_bus_freq_mode = 1;
+ low_bus_freq_mode = 0;
+ cur_bus_freq_mode = BUS_FREQ_AUDIO;
+ } else {
+ busfreq_func.update(LPAPM_CLK);
+
+ clk_set_parent(periph2_clk2_sel_clk, osc_clk);
+ clk_set_parent(periph2_clk, periph2_clk2_clk);
+
+ if (audio_bus_freq_mode)
+ clk_disable_unprepare(pll2_400_clk);
+
+ if (cpu_is_imx6ull() || cpu_is_imx6sll())
+ imx6ull_lower_cpu_rate(true);
+
+ low_bus_freq_mode = 1;
+ audio_bus_freq_mode = 0;
+ cur_bus_freq_mode = BUS_FREQ_LOW;
+ }
+}
+
+static void enter_lpm_imx6_smp(void)
+{
+ if (cpu_is_imx6dl())
+ /* Set axi to periph_clk */
+ clk_set_parent(axi_sel_clk, periph_clk);
+
+ if (audio_bus_count) {
+ /* Need to ensure that PLL2_PFD_400M is kept ON. */
+ clk_prepare_enable(pll2_400_clk);
+ if (ddr_type == MMDC_MDMISC_DDR_TYPE_DDR3)
+ busfreq_func.update(LOW_AUDIO_CLK);
+ else if (ddr_type == MMDC_MDMISC_DDR_TYPE_LPDDR2)
+ busfreq_func.update(HIGH_AUDIO_CLK);
+ /* Make sure periph clk's parent also got updated */
+ clk_set_parent(periph_clk2_sel_clk, pll3_clk);
+ if (ddr_type == MMDC_MDMISC_DDR_TYPE_DDR3)
+ clk_set_parent(periph_pre_clk, pll2_200_clk);
+ else if (ddr_type == MMDC_MDMISC_DDR_TYPE_LPDDR2)
+ clk_set_parent(periph_pre_clk, pll2_400_clk);
+ clk_set_parent(periph_clk, periph_pre_clk);
+
+ /*
+ * As periph_pre_clk's parent is not changed from
+ * high mode to audio mode on lpddr2, the clk framework
+ * will not update its children's freq, but we
+ * change the mmdc_ch0_axi podf in asm code, so here
+ * need to update mmdc rate to make sure clk
+ * tree is right, although it will not do any
+ * change to hardware. Calling get_rate will only call
+ * the .rate_recalc which is all we need.
+ */
+ if (high_bus_freq_mode && mmdc_clk)
+ if (ddr_type == IMX_DDR_TYPE_LPDDR2)
+ clk_get_rate(mmdc_clk);
+
+ audio_bus_freq_mode = 1;
+ low_bus_freq_mode = 0;
+ cur_bus_freq_mode = BUS_FREQ_AUDIO;
+ } else {
+ busfreq_func.update(LPAPM_CLK);
+
+ /* Make sure periph clk's parent also got updated */
+ clk_set_parent(periph_clk2_sel_clk, osc_clk);
+ /* Set periph_clk parent to OSC via periph_clk2_sel */
+ clk_set_parent(periph_clk, periph_clk2_clk);
+ if (audio_bus_freq_mode)
+ clk_disable_unprepare(pll2_400_clk);
+ low_bus_freq_mode = 1;
+ audio_bus_freq_mode = 0;
+ cur_bus_freq_mode = BUS_FREQ_LOW;
+ }
+}
+
+static void exit_lpm_imx6_up(void)
+{
+ if ((cpu_is_imx6ull() || cpu_is_imx6sll()) && low_bus_freq_mode)
+ imx6ull_lower_cpu_rate(false);
+
+ clk_prepare_enable(pll2_400_clk);
+
+ /*
+ * lower ahb/ocram's freq first to avoid too high
+ * freq during parent switch from OSC to pll3.
+ */
+ if (cpu_is_imx6ul() || cpu_is_imx6ull() || cpu_is_imx6sll())
+ clk_set_rate(ahb_clk, LPAPM_CLK / 4);
+ else
+ clk_set_rate(ahb_clk, LPAPM_CLK / 3);
+
+ clk_set_rate(ocram_clk, LPAPM_CLK / 2);
+ /* set periph clk to from pll2_bus on i.MX6UL */
+ if (cpu_is_imx6ul() || cpu_is_imx6ull() || cpu_is_imx6sll())
+ clk_set_parent(periph_pre_clk, pll2_bus_clk);
+ /* set periph clk to from pll2_400 */
+ else
+ clk_set_parent(periph_pre_clk, pll2_400_clk);
+ clk_set_parent(periph_clk, periph_pre_clk);
+ /* set periph_clk2 to pll3 */
+ clk_set_parent(periph_clk2_sel_clk, pll3_clk);
+
+ busfreq_func.update(ddr_normal_rate);
+
+ /* correct parent info after ddr freq change in asm code */
+ clk_set_parent(periph2_pre_clk, pll2_400_clk);
+ clk_set_parent(periph2_clk, periph2_pre_clk);
+ clk_set_parent(periph2_clk2_sel_clk, pll3_clk);
+
+ /*
+ * As periph2_clk's parent is not changed from
+ * audio mode to high mode, so clk framework
+ * will not update its children's freq, but we
+ * change the mmdc's podf in asm code, so here
+ * need to update mmdc rate to make sure clk
+ * tree is right, although it will not do any
+ * change to hardware.
+ */
+ if (audio_bus_freq_mode)
+ clk_set_rate(mmdc_clk, ddr_normal_rate);
+
+ clk_disable_unprepare(pll2_400_clk);
+
+ if (audio_bus_freq_mode)
+ clk_disable_unprepare(pll2_400_clk);
+}
+
+static void exit_lpm_imx6_smp(void)
+{
+ struct clk *periph_clk_parent;
+
+ if (cpu_is_imx6q() && ddr_type == MMDC_MDMISC_DDR_TYPE_DDR3)
+ periph_clk_parent = pll2_bus_clk;
+ else
+ periph_clk_parent = pll2_400_clk;
+
+ clk_prepare_enable(pll2_400_clk);
+
+ busfreq_func.update(ddr_normal_rate);
+
+ /* Make sure periph clk's parent also got updated */
+ clk_set_parent(periph_clk2_sel_clk, pll3_clk);
+ clk_set_parent(periph_pre_clk, periph_clk_parent);
+ clk_set_parent(periph_clk, periph_pre_clk);
+ if (cpu_is_imx6dl()) {
+ /* Set axi to pll3_pfd1_540m */
+ clk_set_parent(axi_alt_sel_clk, pll3_pfd1_540m_clk);
+ clk_set_parent(axi_sel_clk, axi_alt_sel_clk);
+ }
+ /*
+ * As periph_pre_clk's parent is not changed from
+ * high mode to audio mode on lpddr2, the clk framework
+ * will not update its children's freq, but we
+ * change the mmdc_ch0_axi podf in asm code, so here
+ * need to update mmdc rate to make sure clk
+ * tree is right, although it will not do any
+ * change to hardware. Calling get_rate will only call
+ * the .rate_recalc which is all we need.
+ */
+ if (audio_bus_freq_mode && mmdc_clk)
+ if (ddr_type == IMX_DDR_TYPE_LPDDR2)
+ clk_get_rate(mmdc_clk);
+
+ clk_disable_unprepare(pll2_400_clk);
+ if (audio_bus_freq_mode)
+ clk_disable_unprepare(pll2_400_clk);
+}
+
+static void enter_lpm_imx6sl(void)
+{
+ if (high_bus_freq_mode) {
+ /* Set periph_clk to be sourced from OSC_CLK */
+ clk_set_parent(periph_clk2_sel_clk, osc_clk);
+ clk_set_parent(periph_clk, periph_clk2_clk);
+ /* Ensure AHB/AXI clks are at 24MHz. */
+ clk_set_rate(ahb_clk, LPAPM_CLK);
+ clk_set_rate(ocram_clk, LPAPM_CLK);
+ }
+ if (audio_bus_count) {
+ /* Set AHB to 8MHz to lower pwer.*/
+ clk_set_rate(ahb_clk, LPAPM_CLK / 3);
+
+ /* Set up DDR to 100MHz. */
+ busfreq_func.update(HIGH_AUDIO_CLK);
+
+ /* Fix the clock tree in kernel */
+ clk_set_parent(periph2_pre_clk, pll2_200_clk);
+ clk_set_parent(periph2_clk, periph2_pre_clk);
+
+ if (low_bus_freq_mode || ultra_low_bus_freq_mode) {
+ /*
+ * Fix the clock tree in kernel, make sure
+ * pll2_bypass is updated as it is
+ * sourced from PLL2.
+ */
+ clk_set_parent(pll2_bypass_clk, pll2_clk);
+ /*
+ * Swtich ARM to run off PLL2_PFD2_400MHz
+ * since DDR is anyway at 100MHz.
+ */
+ clk_set_parent(step_clk, pll2_400_clk);
+ clk_set_parent(pll1_sw_clk, step_clk);
+
+ /*
+ * Need to ensure that PLL1 is bypassed and enabled
+ * before ARM-PODF is set.
+ */
+ clk_set_parent(pll1_bypass_clk, pll1_bypass_src_clk);
+
+ /*
+ * Ensure that the clock will be
+ * at original speed.
+ */
+ clk_set_rate(arm_clk, org_arm_rate);
+ }
+ low_bus_freq_mode = 0;
+ ultra_low_bus_freq_mode = 0;
+ audio_bus_freq_mode = 1;
+ cur_bus_freq_mode = BUS_FREQ_AUDIO;
+ } else {
+ u32 arm_div, pll1_rate;
+ org_arm_rate = clk_get_rate(arm_clk);
+ if (org_arm_rate == 0) {
+ WARN_ON(1);
+ return;
+ }
+ if (low_bus_freq_mode && low_bus_count == 0) {
+ /*
+ * We are already in DDR @ 24MHz state, but
+ * no one but ARM needs the DDR. In this case,
+ * we can lower the DDR freq to 1MHz when ARM
+ * enters WFI in this state. Keep track of this state.
+ */
+ ultra_low_bus_freq_mode = 1;
+ low_bus_freq_mode = 0;
+ audio_bus_freq_mode = 0;
+ cur_bus_freq_mode = BUS_FREQ_ULTRA_LOW;
+ } else {
+ if (!ultra_low_bus_freq_mode && !low_bus_freq_mode) {
+ /*
+ * Anyway, make sure the AHB is running at 24MHz
+ * in low_bus_freq_mode.
+ */
+ if (audio_bus_freq_mode)
+ clk_set_rate(ahb_clk, LPAPM_CLK);
+ /*
+ * Set DDR to 24MHz.
+ * Since we are going to bypass PLL2,
+ * we need to move ARM clk off PLL2_PFD2
+ * to PLL1. Make sure the PLL1 is running
+ * at the lowest possible freq.
+ * To work well with CPUFREQ we want to ensure that
+ * the CPU freq does not change, so attempt to
+ * get a freq as close to 396MHz as possible.
+ */
+ clk_set_rate(pll1_clk,
+ clk_round_rate(pll1_clk, (org_arm_rate * 2)));
+ pll1_rate = clk_get_rate(pll1_clk);
+ arm_div = pll1_rate / org_arm_rate;
+ if (pll1_rate / arm_div > org_arm_rate)
+ arm_div++;
+ /*
+ * Need to ensure that PLL1 is bypassed and enabled
+ * before ARM-PODF is set.
+ */
+ clk_set_parent(pll1_bypass_clk, pll1_clk);
+ /*
+ * Ensure ARM CLK is lower before
+ * changing the parent.
+ */
+ clk_set_rate(arm_clk, org_arm_rate / arm_div);
+ /* Now set the ARM clk parent to PLL1_SYS. */
+ clk_set_parent(pll1_sw_clk, pll1_sys_clk);
+
+ /*
+ * Set STEP_CLK back to OSC to save power and
+ * also to maintain the parent.The WFI iram code
+ * will switch step_clk to osc, but the clock API
+ * is not aware of the change and when a new request
+ * to change the step_clk parent to pll2_pfd2_400M
+ * is requested sometime later, the change is ignored.
+ */
+ clk_set_parent(step_clk, osc_clk);
+
+ /* Now set DDR to 24MHz. */
+ busfreq_func.update(LPAPM_CLK);
+
+ /*
+ * Fix the clock tree in kernel.
+ * Make sure PLL2 rate is updated as it gets
+ * bypassed in the DDR freq change code.
+ */
+ clk_set_parent(pll2_bypass_clk, pll2_bypass_src_clk);
+ clk_set_parent(periph2_clk2_sel_clk, pll2_bus_clk);
+ clk_set_parent(periph2_clk, periph2_clk2_clk);
+ }
+ if (low_bus_count == 0) {
+ ultra_low_bus_freq_mode = 1;
+ low_bus_freq_mode = 0;
+ cur_bus_freq_mode = BUS_FREQ_ULTRA_LOW;
+ } else {
+ ultra_low_bus_freq_mode = 0;
+ low_bus_freq_mode = 1;
+ cur_bus_freq_mode = BUS_FREQ_LOW;
+ }
+ audio_bus_freq_mode = 0;
+ }
+ }
+}
+
+static void exit_lpm_imx6sl(void)
+{
+ /* Change DDR freq in IRAM. */
+ busfreq_func.update(ddr_normal_rate);
+
+ /*
+ * Fix the clock tree in kernel.
+ * Make sure PLL2 rate is updated as it gets
+ * un-bypassed in the DDR freq change code.
+ */
+ clk_set_parent(pll2_bypass_clk, pll2_clk);
+ clk_set_parent(periph2_pre_clk, pll2_400_clk);
+ clk_set_parent(periph2_clk, periph2_pre_clk);
+
+ /* Ensure that periph_clk is sourced from PLL2_400. */
+ clk_set_parent(periph_pre_clk, pll2_400_clk);
+ /*
+ * Before switching the perhiph_clk, ensure that the
+ * AHB/AXI will not be too fast.
+ */
+ clk_set_rate(ahb_clk, LPAPM_CLK / 3);
+ clk_set_rate(ocram_clk, LPAPM_CLK / 2);
+ clk_set_parent(periph_clk, periph_pre_clk);
+
+ if (low_bus_freq_mode || ultra_low_bus_freq_mode) {
+ /* Move ARM from PLL1_SW_CLK to PLL2_400. */
+ clk_set_parent(step_clk, pll2_400_clk);
+ clk_set_parent(pll1_sw_clk, step_clk);
+ /*
+ * Need to ensure that PLL1 is bypassed and enabled
+ * before ARM-PODF is set.
+ */
+ clk_set_parent(pll1_bypass_clk, pll1_bypass_src_clk);
+ clk_set_rate(arm_clk, org_arm_rate);
+ ultra_low_bus_freq_mode = 0;
+ }
+}
+
+static void enter_lpm_imx7d(void)
+{
+ /*
+ * The AHB clock parent switch and divider change
+ * needs to keep previous/current parent enabled
+ * per design requirement, but when we switch the
+ * clock parent, previous AHB clock parent may be
+ * disabled by common clock framework, so here we
+ * have to make sure AHB's previous parent pfd2_270m
+ * is enabled during AHB set rate.
+ */
+ clk_prepare_enable(pfd2_270m);
+ if (audio_bus_count) {
+ clk_prepare_enable(pfd0_392m);
+ busfreq_func.update(HIGH_AUDIO_CLK);
+
+ clk_set_parent(dram_alt_sel, pfd0_392m);
+ clk_set_parent(dram_root, dram_alt_root);
+ if (high_bus_freq_mode) {
+ clk_set_parent(axi_sel_clk, osc_clk);
+ clk_set_parent(ahb_sel_clk, osc_clk);
+ clk_set_rate(ahb_clk, LPAPM_CLK);
+ }
+ clk_disable_unprepare(pfd0_392m);
+ audio_bus_freq_mode = 1;
+ low_bus_freq_mode = 0;
+ cur_bus_freq_mode = BUS_FREQ_AUDIO;
+ } else {
+ busfreq_func.update(LPAPM_CLK);
+
+ clk_set_parent(dram_alt_sel, osc_clk);
+ clk_set_parent(dram_root, dram_alt_root);
+ if (high_bus_freq_mode) {
+ clk_set_parent(axi_sel_clk, osc_clk);
+ clk_set_parent(ahb_sel_clk, osc_clk);
+ clk_set_rate(ahb_clk, LPAPM_CLK);
+ }
+ low_bus_freq_mode = 1;
+ audio_bus_freq_mode = 0;
+ cur_bus_freq_mode = BUS_FREQ_LOW;
+ }
+ clk_disable_unprepare(pfd2_270m);
+}
+
+static void exit_lpm_imx7d(void)
+{
+ clk_set_parent(axi_sel_clk, pfd1_332m);
+ clk_set_rate(ahb_clk, LPAPM_CLK / 2);
+ clk_set_parent(ahb_sel_clk, pfd2_270m);
+
+ busfreq_func.update(ddr_normal_rate);
+
+ clk_set_parent(dram_root, pll_dram);
+}
+
+static void reduce_bus_freq(void)
+{
+ if (cpu_is_imx6())
+ clk_prepare_enable(pll3_clk);
+
+ if (audio_bus_count && (low_bus_freq_mode || ultra_low_bus_freq_mode))
+ busfreq_notify(LOW_BUSFREQ_EXIT);
+ else if (!audio_bus_count)
+ busfreq_notify(LOW_BUSFREQ_ENTER);
+
+ if (cpu_is_imx7d())
+ enter_lpm_imx7d();
+ else if (cpu_is_imx6sx() || cpu_is_imx6ul() || cpu_is_imx6ull() || cpu_is_imx6sll())
+ enter_lpm_imx6_up();
+ else if (cpu_is_imx6q() || cpu_is_imx6dl())
+ enter_lpm_imx6_smp();
+ else if (cpu_is_imx6sl())
+ enter_lpm_imx6sl();
+
+ med_bus_freq_mode = 0;
+ high_bus_freq_mode = 0;
+
+ if (cpu_is_imx6())
+ clk_disable_unprepare(pll3_clk);
+
+ if (audio_bus_freq_mode)
+ dev_dbg(busfreq_dev,
+ "Bus freq set to audio mode. Count: high %d, med %d, audio %d\n",
+ high_bus_count, med_bus_count, audio_bus_count);
+ if (low_bus_freq_mode)
+ dev_dbg(busfreq_dev,
+ "Bus freq set to low mode. Count: high %d, med %d, audio %d\n",
+ high_bus_count, med_bus_count, audio_bus_count);
+}
+
+static inline void cancel_low_bus_freq_handler(void)
+{
+ cancel_delayed_work(&low_bus_freq_handler);
+ cancel_reduce_bus_freq = true;
+}
+
+static void reduce_bus_freq_handler(struct work_struct *work)
+{
+ mutex_lock(&bus_freq_mutex);
+
+ if (!cancel_reduce_bus_freq) {
+ reduce_bus_freq();
+ cancel_low_bus_freq_handler();
+ }
+
+ mutex_unlock(&bus_freq_mutex);
+}
+
+/*
+ * Set the DDR, AHB to 24MHz.
+ * This mode will be activated only when none of the modules that
+ * need a higher DDR or AHB frequency are active.
+ */
+static int set_low_bus_freq(void)
+{
+ if (busfreq_suspended)
+ return 0;
+
+ if (!bus_freq_scaling_initialized || !bus_freq_scaling_is_active)
+ return 0;
+
+ cancel_reduce_bus_freq = false;
+
+ /*
+ * Check to see if we need to got from
+ * low bus freq mode to audio bus freq mode.
+ * If so, the change needs to be done immediately.
+ */
+ if (audio_bus_count && (low_bus_freq_mode || ultra_low_bus_freq_mode))
+ reduce_bus_freq();
+ else
+ /*
+ * Don't lower the frequency immediately. Instead
+ * scheduled a delayed work and drop the freq if
+ * the conditions still remain the same.
+ */
+ schedule_delayed_work(&low_bus_freq_handler,
+ usecs_to_jiffies(3000000));
+ return 0;
+}
+
+/*
+ * Set the DDR to either 528MHz or 400MHz for iMX6qd
+ * or 400MHz for iMX6dl.
+ */
+static int set_high_bus_freq(int high_bus_freq)
+{
+ if (bus_freq_scaling_initialized && bus_freq_scaling_is_active)
+ cancel_low_bus_freq_handler();
+
+ if (busfreq_suspended)
+ return 0;
+
+ if (!bus_freq_scaling_initialized || !bus_freq_scaling_is_active)
+ return 0;
+
+ if (high_bus_freq_mode)
+ return 0;
+
+ /* medium bus freq is only supported for MX6DQ */
+ if (med_bus_freq_mode && !high_bus_freq)
+ return 0;
+
+ if (low_bus_freq_mode || ultra_low_bus_freq_mode)
+ busfreq_notify(LOW_BUSFREQ_EXIT);
+
+ if (cpu_is_imx6())
+ clk_prepare_enable(pll3_clk);
+
+ if (cpu_is_imx7d())
+ exit_lpm_imx7d();
+ else if (cpu_is_imx6sx() || cpu_is_imx6ul() || cpu_is_imx6ull() || cpu_is_imx6sll())
+ exit_lpm_imx6_up();
+ else if (cpu_is_imx6q() || cpu_is_imx6dl())
+ exit_lpm_imx6_smp();
+ else if (cpu_is_imx6sl())
+ exit_lpm_imx6sl();
+
+ high_bus_freq_mode = 1;
+ med_bus_freq_mode = 0;
+ low_bus_freq_mode = 0;
+ audio_bus_freq_mode = 0;
+ cur_bus_freq_mode = BUS_FREQ_HIGH;
+
+ if (cpu_is_imx6())
+ clk_disable_unprepare(pll3_clk);
+
+ if (high_bus_freq_mode)
+ dev_dbg(busfreq_dev,
+ "Bus freq set to high mode. Count: high %d, med %d, audio %d\n",
+ high_bus_count, med_bus_count, audio_bus_count);
+ if (med_bus_freq_mode)
+ dev_dbg(busfreq_dev,
+ "Bus freq set to med mode. Count: high %d, med %d, audio %d\n",
+ high_bus_count, med_bus_count, audio_bus_count);
+
+ return 0;
+}
+
+void request_bus_freq(enum bus_freq_mode mode)
+{
+ mutex_lock(&bus_freq_mutex);
+
+ if (mode == BUS_FREQ_ULTRA_LOW) {
+ dev_dbg(busfreq_dev, "This mode cannot be requested!\n");
+ mutex_unlock(&bus_freq_mutex);
+ return;
+ }
+
+ if (mode == BUS_FREQ_HIGH)
+ high_bus_count++;
+ else if (mode == BUS_FREQ_MED)
+ med_bus_count++;
+ else if (mode == BUS_FREQ_AUDIO)
+ audio_bus_count++;
+ else if (mode == BUS_FREQ_LOW)
+ low_bus_count++;
+
+ if (busfreq_suspended || !bus_freq_scaling_initialized ||
+ !bus_freq_scaling_is_active) {
+ mutex_unlock(&bus_freq_mutex);
+ return;
+ }
+
+ cancel_low_bus_freq_handler();
+
+ if ((mode == BUS_FREQ_HIGH) && (!high_bus_freq_mode)) {
+ set_high_bus_freq(1);
+ mutex_unlock(&bus_freq_mutex);
+ return;
+ }
+
+ if ((mode == BUS_FREQ_MED) && (!high_bus_freq_mode) &&
+ (!med_bus_freq_mode)) {
+ set_high_bus_freq(0);
+ mutex_unlock(&bus_freq_mutex);
+ return;
+ }
+ if ((mode == BUS_FREQ_AUDIO) && (!high_bus_freq_mode) &&
+ (!med_bus_freq_mode) && (!audio_bus_freq_mode)) {
+ set_low_bus_freq();
+ mutex_unlock(&bus_freq_mutex);
+ return;
+ }
+ mutex_unlock(&bus_freq_mutex);
+}
+EXPORT_SYMBOL(request_bus_freq);
+
+void release_bus_freq(enum bus_freq_mode mode)
+{
+ mutex_lock(&bus_freq_mutex);
+
+ if (mode == BUS_FREQ_ULTRA_LOW) {
+ dev_dbg(busfreq_dev,
+ "This mode cannot be released!\n");
+ mutex_unlock(&bus_freq_mutex);
+ return;
+ }
+
+ if (mode == BUS_FREQ_HIGH) {
+ if (high_bus_count == 0) {
+ dev_err(busfreq_dev, "high bus count mismatch!\n");
+ dump_stack();
+ mutex_unlock(&bus_freq_mutex);
+ return;
+ }
+ high_bus_count--;
+ } else if (mode == BUS_FREQ_MED) {
+ if (med_bus_count == 0) {
+ dev_err(busfreq_dev, "med bus count mismatch!\n");
+ dump_stack();
+ mutex_unlock(&bus_freq_mutex);
+ return;
+ }
+ med_bus_count--;
+ } else if (mode == BUS_FREQ_AUDIO) {
+ if (audio_bus_count == 0) {
+ dev_err(busfreq_dev, "audio bus count mismatch!\n");
+ dump_stack();
+ mutex_unlock(&bus_freq_mutex);
+ return;
+ }
+ audio_bus_count--;
+ } else if (mode == BUS_FREQ_LOW) {
+ if (low_bus_count == 0) {
+ dev_err(busfreq_dev, "low bus count mismatch!\n");
+ dump_stack();
+ mutex_unlock(&bus_freq_mutex);
+ return;
+ }
+ low_bus_count--;
+ }
+
+ if (busfreq_suspended || !bus_freq_scaling_initialized ||
+ !bus_freq_scaling_is_active) {
+ mutex_unlock(&bus_freq_mutex);
+ return;
+ }
+
+ if ((!audio_bus_freq_mode) && (high_bus_count == 0) &&
+ (med_bus_count == 0) && (audio_bus_count != 0)) {
+ set_low_bus_freq();
+ mutex_unlock(&bus_freq_mutex);
+ return;
+ }
+ if ((!low_bus_freq_mode) && (high_bus_count == 0) &&
+ (med_bus_count == 0) && (audio_bus_count == 0) &&
+ (low_bus_count != 0)) {
+ set_low_bus_freq();
+ mutex_unlock(&bus_freq_mutex);
+ return;
+ }
+ if ((!ultra_low_bus_freq_mode) && (high_bus_count == 0) &&
+ (med_bus_count == 0) && (audio_bus_count == 0) &&
+ (low_bus_count == 0)) {
+ set_low_bus_freq();
+ mutex_unlock(&bus_freq_mutex);
+ return;
+ }
+
+ mutex_unlock(&bus_freq_mutex);
+}
+EXPORT_SYMBOL(release_bus_freq);
+
+int get_bus_freq_mode(void)
+{
+ return cur_bus_freq_mode;
+}
+EXPORT_SYMBOL(get_bus_freq_mode);
+
+static struct map_desc ddr_iram_io_desc __initdata = {
+ /* .virtual and .pfn are run-time assigned */
+ .length = SZ_1M,
+ .type = MT_MEMORY_RWX_NONCACHED,
+};
+
+const static char *ddr_freq_iram_match[] __initconst = {
+ "fsl,ddr-lpm-sram",
+ NULL
+};
+
+static int __init imx_dt_find_ddr_sram(unsigned long node,
+ const char *uname, int depth, void *data)
+{
+ unsigned long ddr_iram_addr;
+ const __be32 *prop;
+
+ if (of_flat_dt_match(node, ddr_freq_iram_match)) {
+ unsigned int len;
+
+ prop = of_get_flat_dt_prop(node, "reg", &len);
+ if (prop == NULL || len != (sizeof(unsigned long) * 2))
+ return -EINVAL;
+ ddr_iram_addr = be32_to_cpu(prop[0]);
+ ddr_freq_change_total_size = be32_to_cpu(prop[1]);
+ ddr_freq_change_iram_phys = ddr_iram_addr;
+
+ /* Make sure ddr_freq_change_iram_phys is 8 byte aligned. */
+ if ((uintptr_t)(ddr_freq_change_iram_phys) & (FNCPY_ALIGN - 1))
+ ddr_freq_change_iram_phys += FNCPY_ALIGN -
+ ((uintptr_t)ddr_freq_change_iram_phys %
+ (FNCPY_ALIGN));
+ }
+ return 0;
+}
+
+void __init imx_busfreq_map_io(void)
+{
+ /*
+ * Get the address of IRAM to be used by the ddr frequency
+ * change code from the device tree.
+ */
+ WARN_ON(of_scan_flat_dt(imx_dt_find_ddr_sram, NULL));
+ if (ddr_freq_change_iram_phys) {
+ ddr_freq_change_iram_base = IMX_IO_P2V(
+ ddr_freq_change_iram_phys);
+ if ((iram_tlb_phys_addr & 0xFFF00000) !=
+ (ddr_freq_change_iram_phys & 0xFFF00000)) {
+ /* We need to create a 1M page table entry. */
+ ddr_iram_io_desc.virtual = IMX_IO_P2V(
+ ddr_freq_change_iram_phys & 0xFFF00000);
+ ddr_iram_io_desc.pfn = __phys_to_pfn(
+ ddr_freq_change_iram_phys & 0xFFF00000);
+ iotable_init(&ddr_iram_io_desc, 1);
+ }
+ memset((void *)ddr_freq_change_iram_base, 0,
+ ddr_freq_change_total_size);
+ }
+}
+
+static void bus_freq_daemon_handler(struct work_struct *work)
+{
+ mutex_lock(&bus_freq_mutex);
+ if ((!low_bus_freq_mode) && (!ultra_low_bus_freq_mode)
+ && (high_bus_count == 0) &&
+ (med_bus_count == 0) && (audio_bus_count == 0))
+ set_low_bus_freq();
+ mutex_unlock(&bus_freq_mutex);
+}
+
+static ssize_t bus_freq_scaling_enable_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ if (bus_freq_scaling_is_active)
+ return sprintf(buf, "Bus frequency scaling is enabled\n");
+ else
+ return sprintf(buf, "Bus frequency scaling is disabled\n");
+}
+
+static ssize_t bus_freq_scaling_enable_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+ if (strncmp(buf, "1", 1) == 0) {
+ bus_freq_scaling_is_active = 1;
+ set_high_bus_freq(1);
+ /*
+ * We set bus freq to highest at the beginning,
+ * so we use this daemon thread to make sure system
+ * can enter low bus mode if
+ * there is no high bus request pending
+ */
+ schedule_delayed_work(&bus_freq_daemon,
+ usecs_to_jiffies(5000000));
+ } else if (strncmp(buf, "0", 1) == 0) {
+ if (bus_freq_scaling_is_active)
+ set_high_bus_freq(1);
+ bus_freq_scaling_is_active = 0;
+ }
+ return size;
+}
+
+static int bus_freq_pm_notify(struct notifier_block *nb, unsigned long event,
+ void *dummy)
+{
+ mutex_lock(&bus_freq_mutex);
+
+ if (event == PM_SUSPEND_PREPARE) {
+ if (cpu_is_imx7d() && imx_src_is_m4_enabled())
+ imx_mu_lpm_ready(false);
+ high_bus_count++;
+ set_high_bus_freq(1);
+ busfreq_suspended = 1;
+ } else if (event == PM_POST_SUSPEND) {
+ busfreq_suspended = 0;
+ high_bus_count--;
+ if (cpu_is_imx7d() && imx_src_is_m4_enabled())
+ imx_mu_lpm_ready(true);
+ schedule_delayed_work(&bus_freq_daemon,
+ usecs_to_jiffies(5000000));
+ }
+
+ mutex_unlock(&bus_freq_mutex);
+
+ return NOTIFY_OK;
+}
+
+static int busfreq_reboot_notifier_event(struct notifier_block *this,
+ unsigned long event, void *ptr)
+{
+ /* System is rebooting. Set the system into high_bus_freq_mode. */
+ request_bus_freq(BUS_FREQ_HIGH);
+
+ return 0;
+}
+
+static struct notifier_block imx_bus_freq_pm_notifier = {
+ .notifier_call = bus_freq_pm_notify,
+};
+
+static struct notifier_block imx_busfreq_reboot_notifier = {
+ .notifier_call = busfreq_reboot_notifier_event,
+};
+
+
+static DEVICE_ATTR(enable, 0644, bus_freq_scaling_enable_show,
+ bus_freq_scaling_enable_store);
+
+/*!
+ * This is the probe routine for the bus frequency driver.
+ *
+ * @param pdev The platform device structure
+ *
+ * @return The function returns 0 on success
+ *
+ */
+
+static int busfreq_probe(struct platform_device *pdev)
+{
+ u32 err;
+#ifdef CONFIG_OPTEE
+ struct device_node *node_optee = 0;
+ uint32_t busfreq_val;
+#endif
+
+ busfreq_dev = &pdev->dev;
+
+ /* Return if no IRAM space is allocated for ddr freq change code. */
+ if (!ddr_freq_change_iram_base)
+ return -ENOMEM;
+
+ if (cpu_is_imx6()) {
+ osc_clk = devm_clk_get(&pdev->dev, "osc");
+ pll2_400_clk = devm_clk_get(&pdev->dev, "pll2_pfd2_396m");
+ pll2_200_clk = devm_clk_get(&pdev->dev, "pll2_198m");
+ pll2_bus_clk = devm_clk_get(&pdev->dev, "pll2_bus");
+ pll3_clk = devm_clk_get(&pdev->dev, "pll3_usb_otg");
+ periph_clk = devm_clk_get(&pdev->dev, "periph");
+ periph_pre_clk = devm_clk_get(&pdev->dev, "periph_pre");
+ periph_clk2_clk = devm_clk_get(&pdev->dev, "periph_clk2");
+ periph_clk2_sel_clk = devm_clk_get(&pdev->dev,
+ "periph_clk2_sel");
+ if (IS_ERR(osc_clk) || IS_ERR(pll2_400_clk)
+ || IS_ERR(pll2_200_clk) || IS_ERR(pll2_bus_clk)
+ || IS_ERR(pll3_clk) || IS_ERR(periph_clk)
+ || IS_ERR(periph_pre_clk) || IS_ERR(periph_clk2_clk)
+ || IS_ERR(periph_clk2_sel_clk)) {
+ dev_err(busfreq_dev,
+ "%s: failed to get busfreq clk\n", __func__);
+ return -EINVAL;
+ }
+ }
+
+ if (cpu_is_imx6dl()) {
+ axi_alt_sel_clk = devm_clk_get(&pdev->dev, "axi_alt_sel");
+ axi_sel_clk = devm_clk_get(&pdev->dev, "axi_sel");
+ pll3_pfd1_540m_clk = devm_clk_get(&pdev->dev, "pll3_pfd1_540m");
+ if (IS_ERR(axi_alt_sel_clk) || IS_ERR(axi_sel_clk)
+ || IS_ERR(pll3_pfd1_540m_clk)) {
+ dev_err(busfreq_dev,
+ "%s: failed to get busfreq clk\n", __func__);
+ return -EINVAL;
+ }
+ }
+
+ if (cpu_is_imx6sx() || cpu_is_imx6ul() || cpu_is_imx6sl() || cpu_is_imx6ull() ||
+ cpu_is_imx6sll()) {
+ ahb_clk = devm_clk_get(&pdev->dev, "ahb");
+ ocram_clk = devm_clk_get(&pdev->dev, "ocram");
+ periph2_clk = devm_clk_get(&pdev->dev, "periph2");
+ periph2_pre_clk = devm_clk_get(&pdev->dev, "periph2_pre");
+ periph2_clk2_clk = devm_clk_get(&pdev->dev, "periph2_clk2");
+ periph2_clk2_sel_clk =
+ devm_clk_get(&pdev->dev, "periph2_clk2_sel");
+ if (IS_ERR(ahb_clk) || IS_ERR(ocram_clk)
+ || IS_ERR(periph2_clk) || IS_ERR(periph2_pre_clk)
+ || IS_ERR(periph2_clk2_clk)
+ || IS_ERR(periph2_clk2_sel_clk)) {
+ dev_err(busfreq_dev,
+ "%s: failed to get busfreq clk for imx6ul/sx/sl.\n", __func__);
+ return -EINVAL;
+ }
+ }
+
+ if (cpu_is_imx6sx() || cpu_is_imx6ul() || cpu_is_imx6ull() || cpu_is_imx6sll()) {
+ mmdc_clk = devm_clk_get(&pdev->dev, "mmdc");
+ if (IS_ERR(mmdc_clk)) {
+ dev_err(busfreq_dev,
+ "%s: failed to get mmdc clk for imx6sx/ul.\n", __func__);
+ return -EINVAL;
+ }
+ }
+
+ if (cpu_is_imx6q()) {
+ mmdc_clk = devm_clk_get(&pdev->dev, "mmdc");
+ if (IS_ERR(mmdc_clk)) {
+ mmdc_clk = NULL;
+ }
+ }
+
+ if (cpu_is_imx6sx()) {
+ m4_clk = devm_clk_get(&pdev->dev, "m4");
+ if (IS_ERR(m4_clk)) {
+ dev_err(busfreq_dev, "%s: failed to get m4 clk.\n", __func__);
+ return -EINVAL;
+ }
+ }
+
+ if (cpu_is_imx6sl()) {
+ pll2_bypass_src_clk = devm_clk_get(&pdev->dev, "pll2_bypass_src");
+ pll2_bypass_clk = devm_clk_get(&pdev->dev, "pll2_bypass");
+ pll2_clk = devm_clk_get(&pdev->dev, "pll2");
+ if (IS_ERR(pll2_bypass_src_clk) || IS_ERR(pll2_bypass_clk)
+ || IS_ERR(pll2_clk)) {
+ dev_err(busfreq_dev,
+ "%s failed to get busfreq clk for imx6sl.\n", __func__);
+ return -EINVAL;
+ }
+ }
+
+ if (cpu_is_imx6ull() || cpu_is_imx6sl() || cpu_is_imx6sll()) {
+ arm_clk = devm_clk_get(&pdev->dev, "arm");
+ step_clk = devm_clk_get(&pdev->dev, "step");
+ pll1_clk = devm_clk_get(&pdev->dev, "pll1");
+ pll1_bypass_src_clk = devm_clk_get(&pdev->dev, "pll1_bypass_src");
+ pll1_bypass_clk = devm_clk_get(&pdev->dev, "pll1_bypass");
+ pll1_sys_clk = devm_clk_get(&pdev->dev, "pll1_sys");
+ pll1_sw_clk = devm_clk_get(&pdev->dev, "pll1_sw");
+ if (IS_ERR(arm_clk) || IS_ERR(step_clk) || IS_ERR(pll1_clk)
+ || IS_ERR(pll1_bypass_src_clk) || IS_ERR(pll1_bypass_clk)
+ || IS_ERR(pll1_sys_clk) || IS_ERR(pll1_sw_clk)) {
+ dev_err(busfreq_dev, "%s failed to get busfreq clk for imx6ull/sl.\n", __func__);
+ return -EINVAL;
+ }
+ }
+
+ if (cpu_is_imx7d()) {
+ osc_clk = devm_clk_get(&pdev->dev, "osc");
+ axi_sel_clk = devm_clk_get(&pdev->dev, "axi_sel");
+ ahb_sel_clk = devm_clk_get(&pdev->dev, "ahb_sel");
+ pfd0_392m = devm_clk_get(&pdev->dev, "pfd0_392m");
+ dram_root = devm_clk_get(&pdev->dev, "dram_root");
+ dram_alt_sel = devm_clk_get(&pdev->dev, "dram_alt_sel");
+ pll_dram = devm_clk_get(&pdev->dev, "pll_dram");
+ dram_alt_root = devm_clk_get(&pdev->dev, "dram_alt_root");
+ pfd1_332m = devm_clk_get(&pdev->dev, "pfd1_332m");
+ pfd2_270m = devm_clk_get(&pdev->dev, "pfd2_270m");
+ ahb_clk = devm_clk_get(&pdev->dev, "ahb");
+ axi_clk = devm_clk_get(&pdev->dev, "axi");
+ if (IS_ERR(osc_clk) || IS_ERR(axi_sel_clk) || IS_ERR(ahb_clk)
+ || IS_ERR(pfd0_392m) || IS_ERR(dram_root)
+ || IS_ERR(dram_alt_sel) || IS_ERR(pll_dram)
+ || IS_ERR(dram_alt_root) || IS_ERR(pfd1_332m)
+ || IS_ERR(ahb_clk) || IS_ERR(axi_clk)
+ || IS_ERR(pfd2_270m)) {
+ dev_err(busfreq_dev,
+ "%s: failed to get busfreq clk\n", __func__);
+ return -EINVAL;
+ }
+ }
+
+ err = sysfs_create_file(&busfreq_dev->kobj, &dev_attr_enable.attr);
+ if (err) {
+ dev_err(busfreq_dev,
+ "Unable to register sysdev entry for BUSFREQ");
+ return err;
+ }
+
+ if (of_property_read_u32(pdev->dev.of_node, "fsl,max_ddr_freq",
+ &ddr_normal_rate)) {
+ dev_err(busfreq_dev, "max_ddr_freq entry missing\n");
+ return -EINVAL;
+ }
+
+ high_bus_freq_mode = 1;
+ med_bus_freq_mode = 0;
+ low_bus_freq_mode = 0;
+ audio_bus_freq_mode = 0;
+ ultra_low_bus_freq_mode = 0;
+ cur_bus_freq_mode = BUS_FREQ_HIGH;
+
+ bus_freq_scaling_is_active = 1;
+ bus_freq_scaling_initialized = 1;
+
+ ddr_low_rate = LPAPM_CLK;
+
+ INIT_DELAYED_WORK(&low_bus_freq_handler, reduce_bus_freq_handler);
+ INIT_DELAYED_WORK(&bus_freq_daemon, bus_freq_daemon_handler);
+ register_pm_notifier(&imx_bus_freq_pm_notifier);
+ register_reboot_notifier(&imx_busfreq_reboot_notifier);
+
+ /* enter low bus mode if no high speed device enabled */
+ schedule_delayed_work(&bus_freq_daemon,
+ msecs_to_jiffies(10000));
+
+ /*
+ * Need to make sure to an entry for the ddr freq change code
+ * address in the IRAM page table.
+ * This is only required if the DDR freq code and suspend/idle
+ * code are in different OCRAM spaces.
+ */
+ if ((iram_tlb_phys_addr & 0xFFF00000) !=
+ (ddr_freq_change_iram_phys & 0xFFF00000)) {
+ unsigned long i;
+
+ /*
+ * Make sure the ddr_iram virtual address has a mapping
+ * in the IRAM page table.
+ */
+ i = ((IMX_IO_P2V(ddr_freq_change_iram_phys) >> 20) << 2) / 4;
+ *((unsigned long *)iram_tlb_base_addr + i) =
+ (ddr_freq_change_iram_phys & 0xFFF00000) |
+ TT_ATTRIB_NON_CACHEABLE_1M;
+ }
+
+ if (cpu_is_imx7d()) {
+ ddr_type = imx_ddrc_get_ddr_type();
+ /* reduce ddr3 normal rate to 400M due to CKE issue on TO1.1 */
+ if (imx_get_soc_revision() == IMX_CHIP_REVISION_1_1 &&
+ ddr_type == IMX_DDR_TYPE_DDR3) {
+ ddr_normal_rate = 400000000;
+ pr_info("ddr3 normal rate changed to 400MHz for TO1.1.\n");
+ }
+ busfreq_func.init = &init_ddrc_ddr_settings;
+ busfreq_func.update = &update_ddr_freq_imx_smp;
+ } else if (cpu_is_imx6sx() || cpu_is_imx6ul() || cpu_is_imx6ull() ||
+ cpu_is_imx6sll()) {
+ ddr_type = imx_mmdc_get_ddr_type();
+ if (ddr_type == IMX_DDR_TYPE_DDR3) {
+ busfreq_func.init = &init_mmdc_ddr3_settings_imx6_up;
+ busfreq_func.update = &update_ddr_freq_imx6_up;
+ } else if (ddr_type == IMX_DDR_TYPE_LPDDR2 ||
+ ddr_type == IMX_MMDC_DDR_TYPE_LPDDR3) {
+ busfreq_func.init = &init_mmdc_lpddr2_settings;
+ busfreq_func.update = &update_lpddr2_freq;
+ }
+ } else if (cpu_is_imx6q() || cpu_is_imx6dl()) {
+ ddr_type = imx_mmdc_get_ddr_type();
+ if (ddr_type == MMDC_MDMISC_DDR_TYPE_DDR3) {
+ busfreq_func.init = &init_mmdc_ddr3_settings_imx6_smp;
+ busfreq_func.update = &update_ddr_freq_imx_smp;
+ } else if (ddr_type == MMDC_MDMISC_DDR_TYPE_LPDDR2) {
+ busfreq_func.init = &init_mmdc_lpddr2_settings_mx6q;
+ busfreq_func.update = &update_lpddr2_freq_smp;
+ }
+ } else if (cpu_is_imx6sl()) {
+ busfreq_func.init = &init_mmdc_lpddr2_settings;
+ busfreq_func.update = &update_lpddr2_freq;
+ }
+
+#ifdef CONFIG_OPTEE
+ /*
+ * Find the OPTEE node in the DT and look for the
+ * busfreq property.
+ * If property present and set to 1, busfreq is done by
+ * calling the OPTEE OS
+ */
+ node_optee = of_find_compatible_node(NULL, NULL, "linaro,optee-tz");
+
+ if (node_optee) {
+ if (of_property_read_u32(node_optee, "busfreq",
+ &busfreq_val) == 0) {
+ pr_info("OPTEE busfreq %s",
+ (busfreq_val ? "Supported" : "Not Supported"));
+ if (busfreq_val) {
+ busfreq_func.init = &init_freq_optee;
+ busfreq_func.update = &update_freq_optee;
+ }
+ }
+ }
+#endif
+
+ if (busfreq_func.init)
+ err = busfreq_func.init(pdev);
+ else
+ err = -EINVAL;
+
+ if (!err) {
+ if (cpu_is_imx6sx()) {
+ /*
+ * If M4 is enabled and rate > 24MHz,
+ * add high bus count
+ */
+ if (imx_src_is_m4_enabled() &&
+ (clk_get_rate(m4_clk) > LPAPM_CLK))
+ high_bus_count++;
+ }
+
+ if (cpu_is_imx7d() && imx_src_is_m4_enabled()) {
+ high_bus_count++;
+ imx_mu_lpm_ready(true);
+ }
+ }
+
+ if (err) {
+ dev_err(busfreq_dev, "Busfreq init of ddr controller failed\n");
+ return err;
+ }
+ return 0;
+}
+
+static const struct of_device_id imx_busfreq_ids[] = {
+ { .compatible = "fsl,imx_busfreq", },
+ { /* sentinel */ }
+};
+
+static struct platform_driver busfreq_driver = {
+ .driver = {
+ .name = "imx_busfreq",
+ .owner = THIS_MODULE,
+ .of_match_table = imx_busfreq_ids,
+ },
+ .probe = busfreq_probe,
+};
+
+/*!
+ * Initialise the busfreq_driver.
+ *
+ * @return The function always returns 0.
+ */
+
+static int __init busfreq_init(void)
+{
+#ifndef CONFIG_MX6_VPU_352M
+ if (platform_driver_register(&busfreq_driver) != 0)
+ return -ENODEV;
+
+ pr_info("Bus freq driver module loaded\n");
+#endif
+ return 0;
+}
+
+static void __exit busfreq_cleanup(void)
+{
+ sysfs_remove_file(&busfreq_dev->kobj, &dev_attr_enable.attr);
+
+ /* Unregister the device structure */
+ platform_driver_unregister(&busfreq_driver);
+ bus_freq_scaling_initialized = 0;
+}
+
+module_init(busfreq_init);
+module_exit(busfreq_cleanup);
+
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("BusFreq driver");
+MODULE_LICENSE("GPL");
diff --git a/arch/arm/mach-imx/busfreq_ddr3.c b/arch/arm/mach-imx/busfreq_ddr3.c
new file mode 100644
index 000000000000..3a016f15d5bb
--- /dev/null
+++ b/arch/arm/mach-imx/busfreq_ddr3.c
@@ -0,0 +1,773 @@
+/*
+ * Copyright (C) 2011-2016 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/*!
+ * @file busfreq_ddr3.c
+ *
+ * @brief iMX6 DDR3 frequency change specific file.
+ *
+ * @ingroup PM
+ */
+#include <asm/cacheflush.h>
+#include <asm/fncpy.h>
+#include <asm/io.h>
+#include <asm/mach/map.h>
+#include <asm/mach-types.h>
+#include <asm/tlb.h>
+#include <linux/busfreq-imx.h>
+#include <linux/clk.h>
+#include <linux/clockchips.h>
+#include <linux/cpumask.h>
+#include <linux/delay.h>
+#include <linux/genalloc.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/irqchip/arm-gic.h>
+#include <linux/kernel.h>
+#include <linux/mutex.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/proc_fs.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/smp.h>
+
+#include "hardware.h"
+#include "common.h"
+
+#define SMP_WFE_CODE_SIZE 0x400
+
+#define MIN_DLL_ON_FREQ 333000000
+#define MAX_DLL_OFF_FREQ 125000000
+#define MMDC0_MPMUR0 0x8b8
+#define MMDC0_MPMUR0_OFFSET 16
+#define MMDC0_MPMUR0_MASK 0x3ff
+
+/*
+ * This structure is for passing necessary data for low level ocram
+ * busfreq code(arch/arm/mach-imx/ddr3_freq_imx6.S), if this struct
+ * definition is changed, the offset definition in
+ * arch/arm/mach-imx/ddr3_freq_imx6.S must be also changed accordingly,
+ * otherwise, the busfreq change function will be broken!
+ *
+ * This structure will be placed in front of the asm code on ocram.
+ */
+struct imx6_busfreq_info {
+ u32 freq;
+ void *ddr_settings;
+ u32 dll_off;
+ void *iomux_offsets;
+ u32 mu_delay_val;
+} __aligned(8);
+
+static struct imx6_busfreq_info *imx6_busfreq_info;
+
+/* DDR settings */
+static unsigned long (*iram_ddr_settings)[2];
+static unsigned long (*normal_mmdc_settings)[2];
+static unsigned long (*iram_iomux_settings)[2];
+
+static void __iomem *mmdc_base;
+static void __iomem *iomux_base;
+static void __iomem *gic_dist_base;
+
+static int ddr_settings_size;
+static int iomux_settings_size;
+static int curr_ddr_rate;
+
+void (*imx6_up_change_ddr_freq)(struct imx6_busfreq_info *busfreq_info);
+extern void imx6_up_ddr3_freq_change(struct imx6_busfreq_info *busfreq_info);
+void (*imx7d_change_ddr_freq)(u32 freq) = NULL;
+extern void imx7d_ddr3_freq_change(u32 freq);
+extern void imx_lpddr3_freq_change(u32 freq);
+
+void (*mx6_change_ddr_freq)(u32 freq, void *ddr_settings,
+ bool dll_mode, void *iomux_offsets) = NULL;
+
+extern unsigned int ddr_normal_rate;
+extern int low_bus_freq_mode;
+extern int audio_bus_freq_mode;
+extern void mx6_ddr3_freq_change(u32 freq, void *ddr_settings,
+ bool dll_mode, void *iomux_offsets);
+
+extern unsigned long save_ttbr1(void);
+extern void restore_ttbr1(unsigned long ttbr1);
+extern unsigned long ddr_freq_change_iram_base;
+
+extern unsigned long ddr_freq_change_total_size;
+extern unsigned long iram_tlb_phys_addr;
+
+extern unsigned long mx6_ddr3_freq_change_start asm("mx6_ddr3_freq_change_start");
+extern unsigned long mx6_ddr3_freq_change_end asm("mx6_ddr3_freq_change_end");
+extern unsigned long imx6_up_ddr3_freq_change_start asm("imx6_up_ddr3_freq_change_start");
+extern unsigned long imx6_up_ddr3_freq_change_end asm("imx6_up_ddr3_freq_change_end");
+
+#ifdef CONFIG_SMP
+static unsigned long wfe_freq_change_iram_base;
+volatile u32 *wait_for_ddr_freq_update;
+static unsigned int online_cpus;
+static u32 *irqs_used;
+
+void (*wfe_change_ddr_freq)(u32 cpuid, u32 *ddr_freq_change_done);
+void (*imx7_wfe_change_ddr_freq)(u32 cpuid, u32 ocram_base);
+extern void wfe_smp_freq_change(u32 cpuid, u32 *ddr_freq_change_done);
+extern void imx7_smp_wfe(u32 cpuid, u32 ocram_base);
+extern unsigned long wfe_smp_freq_change_start asm("wfe_smp_freq_change_start");
+extern unsigned long wfe_smp_freq_change_end asm("wfe_smp_freq_change_end");
+extern void __iomem *imx_scu_base;
+#endif
+
+unsigned long ddr3_dll_mx6sx[][2] = {
+ {0x0c, 0x0},
+ {0x10, 0x0},
+ {0x1C, 0x04008032},
+ {0x1C, 0x00048031},
+ {0x1C, 0x05208030},
+ {0x1C, 0x04008040},
+ {0x818, 0x0},
+ {0x18, 0x0},
+};
+
+unsigned long ddr3_calibration_mx6sx[][2] = {
+ {0x83c, 0x0},
+ {0x840, 0x0},
+ {0x848, 0x0},
+ {0x850, 0x0},
+};
+
+unsigned long iomux_offsets_mx6sx[][2] = {
+ {0x330, 0x0},
+ {0x334, 0x0},
+ {0x338, 0x0},
+ {0x33c, 0x0},
+};
+
+unsigned long iomux_offsets_mx6ul[][2] = {
+ {0x280, 0x0},
+ {0x284, 0x0},
+};
+
+unsigned long ddr3_dll_mx6q[][2] = {
+ {0x0c, 0x0},
+ {0x10, 0x0},
+ {0x1C, 0x04088032},
+ {0x1C, 0x0408803a},
+ {0x1C, 0x08408030},
+ {0x1C, 0x08408038},
+ {0x818, 0x0},
+ {0x18, 0x0},
+};
+
+unsigned long ddr3_calibration[][2] = {
+ {0x83c, 0x0},
+ {0x840, 0x0},
+ {0x483c, 0x0},
+ {0x4840, 0x0},
+ {0x848, 0x0},
+ {0x4848, 0x0},
+ {0x850, 0x0},
+ {0x4850, 0x0},
+};
+
+unsigned long iomux_offsets_mx6q[][2] = {
+ {0x5A8, 0x0},
+ {0x5B0, 0x0},
+ {0x524, 0x0},
+ {0x51C, 0x0},
+ {0x518, 0x0},
+ {0x50C, 0x0},
+ {0x5B8, 0x0},
+ {0x5C0, 0x0},
+};
+
+unsigned long ddr3_dll_mx6dl[][2] = {
+ {0x0c, 0x0},
+ {0x10, 0x0},
+ {0x1C, 0x04008032},
+ {0x1C, 0x0400803a},
+ {0x1C, 0x07208030},
+ {0x1C, 0x07208038},
+ {0x818, 0x0},
+ {0x18, 0x0},
+};
+
+unsigned long iomux_offsets_mx6dl[][2] = {
+ {0x4BC, 0x0},
+ {0x4C0, 0x0},
+ {0x4C4, 0x0},
+ {0x4C8, 0x0},
+ {0x4CC, 0x0},
+ {0x4D0, 0x0},
+ {0x4D4, 0x0},
+ {0x4D8, 0x0},
+};
+
+int can_change_ddr_freq(void)
+{
+ return 1;
+}
+
+#ifdef CONFIG_SMP
+/*
+ * each active core apart from the one changing
+ * the DDR frequency will execute this function.
+ * the rest of the cores have to remain in WFE
+ * state until the frequency is changed.
+ */
+static irqreturn_t wait_in_wfe_irq(int irq, void *dev_id)
+{
+ u32 me;
+
+ me = smp_processor_id();
+#ifdef CONFIG_LOCAL_TIMERS
+ clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER,
+ &me);
+#endif
+ if (cpu_is_imx7d())
+ imx7_wfe_change_ddr_freq(0x8 * me,
+ (u32)ddr_freq_change_iram_base);
+ else
+ wfe_change_ddr_freq(0xff << (me * 8),
+ (u32 *)&iram_iomux_settings[0][1]);
+#ifdef CONFIG_LOCAL_TIMERS
+ clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT,
+ &me);
+#endif
+
+ return IRQ_HANDLED;
+}
+#endif
+
+/* change the DDR frequency. */
+int update_ddr_freq_imx_smp(int ddr_rate)
+{
+ int me = 0;
+ unsigned long ttbr1;
+ bool dll_off = false;
+ int i;
+#ifdef CONFIG_SMP
+ unsigned int reg = 0;
+ int cpu = 0;
+#endif
+ int mode = get_bus_freq_mode();
+
+ if (!can_change_ddr_freq())
+ return -1;
+
+ if (ddr_rate == curr_ddr_rate)
+ return 0;
+
+ printk(KERN_DEBUG "\nBus freq set to %d start...\n", ddr_rate);
+
+ if (cpu_is_imx6()) {
+ if ((mode == BUS_FREQ_LOW) || (mode == BUS_FREQ_AUDIO))
+ dll_off = true;
+
+ iram_ddr_settings[0][0] = ddr_settings_size;
+ iram_iomux_settings[0][0] = iomux_settings_size;
+ if (ddr_rate == ddr_normal_rate) {
+ for (i = 0; i < iram_ddr_settings[0][0]; i++) {
+ iram_ddr_settings[i + 1][0] =
+ normal_mmdc_settings[i][0];
+ iram_ddr_settings[i + 1][1] =
+ normal_mmdc_settings[i][1];
+ }
+ }
+ }
+
+ /* ensure that all Cores are in WFE. */
+ local_irq_disable();
+
+#ifdef CONFIG_SMP
+ me = smp_processor_id();
+
+ /* Make sure all the online cores are active */
+ while (1) {
+ bool not_exited_busfreq = false;
+ u32 reg = 0;
+
+ for_each_online_cpu(cpu) {
+ if (cpu_is_imx7d())
+ reg = *(wait_for_ddr_freq_update + 1);
+ else if (cpu_is_imx6())
+ reg = __raw_readl(imx_scu_base + 0x08);
+
+ if (reg & (0x02 << (cpu * 8)))
+ not_exited_busfreq = true;
+ }
+ if (!not_exited_busfreq)
+ break;
+ }
+
+ wmb();
+ *wait_for_ddr_freq_update = 1;
+ dsb();
+ if (cpu_is_imx7d())
+ online_cpus = *(wait_for_ddr_freq_update + 1);
+ else if (cpu_is_imx6())
+ online_cpus = readl_relaxed(imx_scu_base + 0x08);
+ for_each_online_cpu(cpu) {
+ *((char *)(&online_cpus) + (u8)cpu) = 0x02;
+ if (cpu != me) {
+ /* set the interrupt to be pending in the GIC. */
+ reg = 1 << (irqs_used[cpu] % 32);
+ writel_relaxed(reg, gic_dist_base + GIC_DIST_PENDING_SET
+ + (irqs_used[cpu] / 32) * 4);
+ }
+ }
+ /* Wait for the other active CPUs to idle */
+ while (1) {
+ u32 reg = 0;
+
+ if (cpu_is_imx7d())
+ reg = *(wait_for_ddr_freq_update + 1);
+ else if (cpu_is_imx6())
+ reg = readl_relaxed(imx_scu_base + 0x08);
+ reg |= (0x02 << (me * 8));
+ if (reg == online_cpus)
+ break;
+ }
+#endif
+
+ /* Ensure iram_tlb_phys_addr is flushed to DDR. */
+ __cpuc_flush_dcache_area(&iram_tlb_phys_addr,
+ sizeof(iram_tlb_phys_addr));
+ if (cpu_is_imx6())
+ outer_clean_range(__pa(&iram_tlb_phys_addr),
+ __pa(&iram_tlb_phys_addr + 1));
+
+ ttbr1 = save_ttbr1();
+ /* Now we can change the DDR frequency. */
+ if (cpu_is_imx7d())
+ imx7d_change_ddr_freq(ddr_rate);
+ else if (cpu_is_imx6())
+ mx6_change_ddr_freq(ddr_rate, iram_ddr_settings,
+ dll_off, iram_iomux_settings);
+ restore_ttbr1(ttbr1);
+ curr_ddr_rate = ddr_rate;
+
+#ifdef CONFIG_SMP
+ wmb();
+ /* DDR frequency change is done . */
+ *wait_for_ddr_freq_update = 0;
+ dsb();
+
+ /* wake up all the cores. */
+ sev();
+#endif
+
+ local_irq_enable();
+
+ printk(KERN_DEBUG "Bus freq set to %d done! cpu=%d\n", ddr_rate, me);
+
+ return 0;
+}
+
+/* Used by i.MX6SX/i.MX6UL for updating the ddr frequency */
+int update_ddr_freq_imx6_up(int ddr_rate)
+{
+ int i;
+ bool dll_off = false;
+ unsigned long ttbr1;
+ int mode = get_bus_freq_mode();
+
+ if (ddr_rate == curr_ddr_rate)
+ return 0;
+
+ printk(KERN_DEBUG "\nBus freq set to %d start...\n", ddr_rate);
+
+ if ((mode == BUS_FREQ_LOW) || (mode == BUS_FREQ_AUDIO))
+ dll_off = true;
+
+ imx6_busfreq_info->dll_off = dll_off;
+ iram_ddr_settings[0][0] = ddr_settings_size;
+ iram_iomux_settings[0][0] = iomux_settings_size;
+ for (i = 0; i < iram_ddr_settings[0][0]; i++) {
+ iram_ddr_settings[i + 1][0] =
+ normal_mmdc_settings[i][0];
+ iram_ddr_settings[i + 1][1] =
+ normal_mmdc_settings[i][1];
+ }
+
+ local_irq_disable();
+
+ ttbr1 = save_ttbr1();
+ imx6_busfreq_info->freq = ddr_rate;
+ imx6_busfreq_info->ddr_settings = iram_ddr_settings;
+ imx6_busfreq_info->iomux_offsets = iram_iomux_settings;
+ imx6_busfreq_info->mu_delay_val = ((readl_relaxed(mmdc_base + MMDC0_MPMUR0)
+ >> MMDC0_MPMUR0_OFFSET) & MMDC0_MPMUR0_MASK);
+
+ imx6_up_change_ddr_freq(imx6_busfreq_info);
+ restore_ttbr1(ttbr1);
+ curr_ddr_rate = ddr_rate;
+
+ local_irq_enable();
+
+ printk(KERN_DEBUG "Bus freq set to %d done!\n", ddr_rate);
+
+ return 0;
+}
+
+int init_ddrc_ddr_settings(struct platform_device *busfreq_pdev)
+{
+ int ddr_type = imx_ddrc_get_ddr_type();
+#ifdef CONFIG_SMP
+ struct device_node *node;
+ u32 cpu;
+ struct device *dev = &busfreq_pdev->dev;
+ int err;
+ struct irq_data *d;
+
+ node = of_find_compatible_node(NULL, NULL, "arm,cortex-a7-gic");
+ if (!node) {
+ printk(KERN_ERR "failed to find imx7d-a7-gic device tree data!\n");
+ return -EINVAL;
+ }
+ gic_dist_base = of_iomap(node, 0);
+ WARN(!gic_dist_base, "unable to map gic dist registers\n");
+
+ irqs_used = devm_kzalloc(dev, sizeof(u32) * num_present_cpus(),
+ GFP_KERNEL);
+ for_each_online_cpu(cpu) {
+ int irq;
+ /*
+ * set up a reserved interrupt to get all
+ * the active cores into a WFE state
+ * before changing the DDR frequency.
+ */
+ irq = platform_get_irq(busfreq_pdev, cpu);
+ err = request_irq(irq, wait_in_wfe_irq,
+ IRQF_PERCPU, "ddrc", NULL);
+ if (err) {
+ dev_err(dev,
+ "Busfreq:request_irq failed %d, err = %d\n",
+ irq, err);
+ return err;
+ }
+ err = irq_set_affinity(irq, cpumask_of(cpu));
+ if (err) {
+ dev_err(dev,
+ "Busfreq: Cannot set irq affinity irq=%d\n",
+ irq);
+ return err;
+ }
+ d = irq_get_irq_data(irq);
+ irqs_used[cpu] = d->hwirq + 32;
+ }
+
+ /* Store the variable used to communicate between cores */
+ wait_for_ddr_freq_update = (u32 *)ddr_freq_change_iram_base;
+ imx7_wfe_change_ddr_freq = (void *)fncpy(
+ (void *)ddr_freq_change_iram_base + 0x8,
+ &imx7_smp_wfe, SMP_WFE_CODE_SIZE - 0x8);
+#endif
+ if (ddr_type == IMX_DDR_TYPE_DDR3)
+ imx7d_change_ddr_freq = (void *)fncpy(
+ (void *)ddr_freq_change_iram_base + SMP_WFE_CODE_SIZE,
+ &imx7d_ddr3_freq_change,
+ MX7_BUSFREQ_OCRAM_SIZE - SMP_WFE_CODE_SIZE);
+ else if (ddr_type == IMX_DDR_TYPE_LPDDR3
+ || ddr_type == IMX_DDR_TYPE_LPDDR2)
+ imx7d_change_ddr_freq = (void *)fncpy(
+ (void *)ddr_freq_change_iram_base +
+ SMP_WFE_CODE_SIZE,
+ &imx_lpddr3_freq_change,
+ MX7_BUSFREQ_OCRAM_SIZE - SMP_WFE_CODE_SIZE);
+
+ curr_ddr_rate = ddr_normal_rate;
+
+ return 0;
+}
+
+/* Used by i.MX6SX/i.MX6UL for mmdc setting init. */
+int init_mmdc_ddr3_settings_imx6_up(struct platform_device *busfreq_pdev)
+{
+ int i;
+ struct device_node *node;
+ unsigned long ddr_code_size;
+
+ node = of_find_compatible_node(NULL, NULL, "fsl,imx6q-mmdc");
+ if (!node) {
+ printk(KERN_ERR "failed to find mmdc device tree data!\n");
+ return -EINVAL;
+ }
+ mmdc_base = of_iomap(node, 0);
+ WARN(!mmdc_base, "unable to map mmdc registers\n");
+
+ if (cpu_is_imx6sx())
+ node = of_find_compatible_node(NULL, NULL, "fsl,imx6sx-iomuxc");
+ else
+ node = of_find_compatible_node(NULL, NULL, "fsl,imx6ul-iomuxc");
+ if (!node) {
+ printk(KERN_ERR "failed to find iomuxc device tree data!\n");
+ return -EINVAL;
+ }
+ iomux_base = of_iomap(node, 0);
+ WARN(!iomux_base, "unable to map iomux registers\n");
+
+ ddr_settings_size = ARRAY_SIZE(ddr3_dll_mx6sx) +
+ ARRAY_SIZE(ddr3_calibration_mx6sx);
+
+ normal_mmdc_settings = kmalloc((ddr_settings_size * 8), GFP_KERNEL);
+ memcpy(normal_mmdc_settings, ddr3_dll_mx6sx,
+ sizeof(ddr3_dll_mx6sx));
+ memcpy(((char *)normal_mmdc_settings + sizeof(ddr3_dll_mx6sx)),
+ ddr3_calibration_mx6sx, sizeof(ddr3_calibration_mx6sx));
+
+ /* store the original DDR settings at boot. */
+ for (i = 0; i < ddr_settings_size; i++) {
+ /*
+ * writes via command mode register cannot be read back.
+ * hence hardcode them in the initial static array.
+ * this may require modification on a per customer basis.
+ */
+ if (normal_mmdc_settings[i][0] != 0x1C)
+ normal_mmdc_settings[i][1] =
+ readl_relaxed(mmdc_base
+ + normal_mmdc_settings[i][0]);
+ }
+
+ if (cpu_is_imx6ul() || cpu_is_imx6ull())
+ iomux_settings_size = ARRAY_SIZE(iomux_offsets_mx6ul);
+ else
+ iomux_settings_size = ARRAY_SIZE(iomux_offsets_mx6sx);
+
+ ddr_code_size = (&imx6_up_ddr3_freq_change_end -&imx6_up_ddr3_freq_change_start) *4 +
+ sizeof(*imx6_busfreq_info);
+
+ imx6_busfreq_info = (struct imx6_busfreq_info *)ddr_freq_change_iram_base;
+
+ imx6_up_change_ddr_freq = (void *)fncpy((void *)ddr_freq_change_iram_base + sizeof(*imx6_busfreq_info),
+ &imx6_up_ddr3_freq_change, ddr_code_size - sizeof(*imx6_busfreq_info));
+
+ /*
+ * Store the size of the array in iRAM also,
+ * increase the size by 8 bytes.
+ */
+ iram_iomux_settings = (void *)(ddr_freq_change_iram_base + ddr_code_size);
+ iram_ddr_settings = iram_iomux_settings + (iomux_settings_size * 8) + 8;
+
+ if ((ddr_code_size + (iomux_settings_size + ddr_settings_size) * 8 + 16)
+ > ddr_freq_change_total_size) {
+ printk(KERN_ERR "Not enough memory allocated for DDR Frequency change code.\n");
+ return EINVAL;
+ }
+
+ for (i = 0; i < iomux_settings_size; i++) {
+ if (cpu_is_imx6ul() || cpu_is_imx6ull()) {
+ iomux_offsets_mx6ul[i][1] =
+ readl_relaxed(iomux_base +
+ iomux_offsets_mx6ul[i][0]);
+ iram_iomux_settings[i + 1][0] =
+ iomux_offsets_mx6ul[i][0];
+ iram_iomux_settings[i + 1][1] =
+ iomux_offsets_mx6ul[i][1];
+ } else {
+ iomux_offsets_mx6sx[i][1] =
+ readl_relaxed(iomux_base +
+ iomux_offsets_mx6sx[i][0]);
+ iram_iomux_settings[i + 1][0] =
+ iomux_offsets_mx6sx[i][0];
+ iram_iomux_settings[i + 1][1] =
+ iomux_offsets_mx6sx[i][1];
+ }
+ }
+
+ curr_ddr_rate = ddr_normal_rate;
+
+ return 0;
+}
+
+int init_mmdc_ddr3_settings_imx6_smp(struct platform_device *busfreq_pdev)
+{
+ int i;
+ struct device_node *node;
+ unsigned long ddr_code_size;
+ unsigned long wfe_code_size = 0;
+#ifdef CONFIG_SMP
+ u32 cpu;
+ struct device *dev = &busfreq_pdev->dev;
+ int err;
+ struct irq_data *d;
+#endif
+
+ node = of_find_compatible_node(NULL, NULL, "fsl,imx6q-mmdc-combine");
+ if (!node) {
+ printk(KERN_ERR "failed to find imx6q-mmdc device tree data!\n");
+ return -EINVAL;
+ }
+ mmdc_base = of_iomap(node, 0);
+ WARN(!mmdc_base, "unable to map mmdc registers\n");
+
+ node = NULL;
+ if (cpu_is_imx6q())
+ node = of_find_compatible_node(NULL, NULL, "fsl,imx6q-iomuxc");
+ if (cpu_is_imx6dl())
+ node = of_find_compatible_node(NULL, NULL,
+ "fsl,imx6dl-iomuxc");
+ if (!node) {
+ printk(KERN_ERR "failed to find imx6q-iomux device tree data!\n");
+ return -EINVAL;
+ }
+ iomux_base = of_iomap(node, 0);
+ WARN(!iomux_base, "unable to map iomux registers\n");
+
+ node = NULL;
+ node = of_find_compatible_node(NULL, NULL, "arm,cortex-a9-gic");
+ if (!node) {
+ printk(KERN_ERR "failed to find imx6q-a9-gic device tree data!\n");
+ return -EINVAL;
+ }
+ gic_dist_base = of_iomap(node, 0);
+ WARN(!gic_dist_base, "unable to map gic dist registers\n");
+
+ if (cpu_is_imx6q())
+ ddr_settings_size = ARRAY_SIZE(ddr3_dll_mx6q) +
+ ARRAY_SIZE(ddr3_calibration);
+ if (cpu_is_imx6dl())
+ ddr_settings_size = ARRAY_SIZE(ddr3_dll_mx6dl) +
+ ARRAY_SIZE(ddr3_calibration);
+
+ normal_mmdc_settings = kmalloc((ddr_settings_size * 8), GFP_KERNEL);
+ if (cpu_is_imx6q()) {
+ memcpy(normal_mmdc_settings, ddr3_dll_mx6q,
+ sizeof(ddr3_dll_mx6q));
+ memcpy(((char *)normal_mmdc_settings + sizeof(ddr3_dll_mx6q)),
+ ddr3_calibration, sizeof(ddr3_calibration));
+ }
+ if (cpu_is_imx6dl()) {
+ memcpy(normal_mmdc_settings, ddr3_dll_mx6dl,
+ sizeof(ddr3_dll_mx6dl));
+ memcpy(((char *)normal_mmdc_settings + sizeof(ddr3_dll_mx6dl)),
+ ddr3_calibration, sizeof(ddr3_calibration));
+ }
+ /* store the original DDR settings at boot. */
+ for (i = 0; i < ddr_settings_size; i++) {
+ /*
+ * writes via command mode register cannot be read back.
+ * hence hardcode them in the initial static array.
+ * this may require modification on a per customer basis.
+ */
+ if (normal_mmdc_settings[i][0] != 0x1C)
+ normal_mmdc_settings[i][1] =
+ readl_relaxed(mmdc_base
+ + normal_mmdc_settings[i][0]);
+ }
+
+#ifdef CONFIG_SMP
+ irqs_used = devm_kzalloc(dev, sizeof(u32) * num_present_cpus(),
+ GFP_KERNEL);
+
+ for_each_online_cpu(cpu) {
+ int irq;
+
+ /*
+ * set up a reserved interrupt to get all
+ * the active cores into a WFE state
+ * before changing the DDR frequency.
+ */
+ irq = platform_get_irq(busfreq_pdev, cpu);
+ err = request_irq(irq, wait_in_wfe_irq,
+ IRQF_PERCPU, "mmdc_1", NULL);
+ if (err) {
+ dev_err(dev,
+ "Busfreq:request_irq failed %d, err = %d\n",
+ irq, err);
+ return err;
+ }
+ err = irq_set_affinity(irq, cpumask_of(cpu));
+ if (err) {
+ dev_err(dev,
+ "Busfreq: Cannot set irq affinity irq=%d,\n",
+ irq);
+ return err;
+ }
+ d = irq_get_irq_data(irq);
+ irqs_used[cpu] = d->hwirq + 32;
+ }
+#endif
+ iomux_settings_size = ARRAY_SIZE(iomux_offsets_mx6q);
+
+ ddr_code_size = (&mx6_ddr3_freq_change_end -
+ &mx6_ddr3_freq_change_start) * 4;
+
+ mx6_change_ddr_freq = (void *)fncpy((void *)ddr_freq_change_iram_base,
+ &mx6_ddr3_freq_change, ddr_code_size);
+
+ /*
+ * Store the size of the array in iRAM also,
+ * increase the size by 8 bytes.
+ */
+ iram_iomux_settings = (void *)(ddr_freq_change_iram_base +
+ ddr_code_size);
+ iram_ddr_settings = iram_iomux_settings + (iomux_settings_size * 8) + 8;
+#ifdef CONFIG_SMP
+ wfe_freq_change_iram_base = (unsigned long)((u32 *)iram_ddr_settings +
+ (ddr_settings_size * 8) + 8);
+
+ if (wfe_freq_change_iram_base & (FNCPY_ALIGN - 1))
+ wfe_freq_change_iram_base += FNCPY_ALIGN -
+ ((uintptr_t)wfe_freq_change_iram_base % (FNCPY_ALIGN));
+
+ wfe_code_size = (&wfe_smp_freq_change_end -
+ &wfe_smp_freq_change_start) *4;
+
+ wfe_change_ddr_freq = (void *)fncpy((void *)wfe_freq_change_iram_base,
+ &wfe_smp_freq_change, wfe_code_size);
+
+ /*
+ * Store the variable used to communicate
+ * between cores in a non-cacheable IRAM area
+ */
+ wait_for_ddr_freq_update = (u32 *)&iram_iomux_settings[0][1];
+#endif
+
+ if ((ddr_code_size + wfe_code_size + (iomux_settings_size +
+ ddr_settings_size) * 8 + 16)
+ > ddr_freq_change_total_size) {
+ printk(KERN_ERR "Not enough memory for DDR Freq scale.\n");
+ return EINVAL;
+ }
+
+ if (cpu_is_imx6q()) {
+ /* store the IOMUX settings at boot. */
+ for (i = 0; i < iomux_settings_size; i++) {
+ iomux_offsets_mx6q[i][1] =
+ readl_relaxed(iomux_base +
+ iomux_offsets_mx6q[i][0]);
+ iram_iomux_settings[i + 1][0] =
+ iomux_offsets_mx6q[i][0];
+ iram_iomux_settings[i + 1][1] =
+ iomux_offsets_mx6q[i][1];
+ }
+ }
+
+ if (cpu_is_imx6dl()) {
+ for (i = 0; i < iomux_settings_size; i++) {
+ iomux_offsets_mx6dl[i][1] =
+ readl_relaxed(iomux_base +
+ iomux_offsets_mx6dl[i][0]);
+ iram_iomux_settings[i + 1][0] =
+ iomux_offsets_mx6dl[i][0];
+ iram_iomux_settings[i + 1][1] =
+ iomux_offsets_mx6dl[i][1];
+ }
+ }
+
+ curr_ddr_rate = ddr_normal_rate;
+
+ return 0;
+}
diff --git a/arch/arm/mach-imx/busfreq_lpddr2.c b/arch/arm/mach-imx/busfreq_lpddr2.c
new file mode 100644
index 000000000000..2ef1806bbc35
--- /dev/null
+++ b/arch/arm/mach-imx/busfreq_lpddr2.c
@@ -0,0 +1,373 @@
+/*
+ * Copyright (C) 2011-2016 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2017 NXP.
+ */
+
+/*
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/*!
+ * @file busfreq_lpddr2.c
+ *
+ * @brief iMX6 LPDDR2 frequency change specific file.
+ *
+ * @ingroup PM
+ */
+#include <asm/cacheflush.h>
+#include <asm/fncpy.h>
+#include <asm/io.h>
+#include <asm/mach/map.h>
+#include <asm/mach-types.h>
+#include <asm/tlb.h>
+#include <linux/busfreq-imx.h>
+#include <linux/clk.h>
+#include <linux/clockchips.h>
+#include <linux/cpumask.h>
+#include <linux/delay.h>
+#include <linux/genalloc.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/irqchip/arm-gic.h>
+#include <linux/kernel.h>
+#include <linux/mutex.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/proc_fs.h>
+#include <linux/sched.h>
+#include <linux/smp.h>
+#include <linux/slab.h>
+
+#include "common.h"
+#include "hardware.h"
+
+static struct device *busfreq_dev;
+static int curr_ddr_rate;
+static DEFINE_SPINLOCK(freq_lock);
+
+void (*mx6_change_lpddr2_freq)(u32 ddr_freq, int bus_freq_mode) = NULL;
+
+extern unsigned int ddr_normal_rate;
+extern void mx6_lpddr2_freq_change(u32 freq, int bus_freq_mode);
+extern void imx6_up_lpddr2_freq_change(u32 freq, int bus_freq_mode);
+extern void imx6sll_lpddr2_freq_change(u32 freq, int bus_freq_mode);
+extern unsigned long save_ttbr1(void);
+extern void restore_ttbr1(unsigned long ttbr1);
+extern void mx6q_lpddr2_freq_change(u32 freq, void *ddr_settings);
+extern unsigned long ddr_freq_change_iram_base;
+extern unsigned long imx6_lpddr2_freq_change_start asm("imx6_lpddr2_freq_change_start");
+extern unsigned long imx6_lpddr2_freq_change_end asm("imx6_lpddr2_freq_change_end");
+extern unsigned long mx6q_lpddr2_freq_change_start asm("mx6q_lpddr2_freq_change_start");
+extern unsigned long mx6q_lpddr2_freq_change_end asm("mx6q_lpddr2_freq_change_end");
+extern unsigned long iram_tlb_phys_addr;
+
+struct mmdc_settings_info {
+ u32 size;
+ void *settings;
+ int freq;
+} __aligned(8);
+static struct mmdc_settings_info *mmdc_settings_info;
+void (*mx6_change_lpddr2_freq_smp)(u32 ddr_freq, struct mmdc_settings_info
+ *mmdc_settings_info) = NULL;
+
+static int mmdc_settings_size;
+static unsigned long (*mmdc_settings)[2];
+static unsigned long (*iram_mmdc_settings)[2];
+static unsigned long *iram_settings_size;
+static unsigned long *iram_ddr_freq_chage;
+unsigned long mmdc_timing_settings[][2] = {
+ {0x0C, 0x0}, /* mmdc_mdcfg0 */
+ {0x10, 0x0}, /* mmdc_mdcfg1 */
+ {0x14, 0x0}, /* mmdc_mdcfg2 */
+ {0x18, 0x0}, /* mmdc_mdmisc */
+ {0x38, 0x0}, /* mmdc_mdcfg3lp */
+};
+
+#ifdef CONFIG_SMP
+volatile u32 *wait_for_lpddr2_freq_update;
+static unsigned int online_cpus;
+static u32 *irqs_used;
+void (*wfe_change_lpddr2_freq)(u32 cpuid, u32 *ddr_freq_change_done);
+extern void wfe_smp_freq_change(u32 cpuid, u32 *ddr_freq_change_done);
+extern unsigned long wfe_smp_freq_change_start asm("wfe_smp_freq_change_start");
+extern unsigned long wfe_smp_freq_change_end asm("wfe_smp_freq_change_end");
+extern void __iomem *imx_scu_base;
+static void __iomem *gic_dist_base;
+#endif
+
+#ifdef CONFIG_SMP
+static irqreturn_t wait_in_wfe_irq(int irq, void *dev_id)
+{
+ u32 me;
+
+ me = smp_processor_id();
+#ifdef CONFIG_LOCAL_TIMERS
+ clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &me);
+#endif
+ wfe_change_lpddr2_freq(0xff << (me * 8),
+ (u32 *)ddr_freq_change_iram_base);
+#ifdef CONFIG_LOCAL_TIMERS
+ clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &me);
+#endif
+ return IRQ_HANDLED;
+}
+#endif
+
+/* change the DDR frequency. */
+int update_lpddr2_freq(int ddr_rate)
+{
+ unsigned long ttbr1, flags;
+ int mode = get_bus_freq_mode();
+
+ if (ddr_rate == curr_ddr_rate)
+ return 0;
+
+ printk(KERN_DEBUG "\nBus freq set to %d start...\n", ddr_rate);
+
+ spin_lock_irqsave(&freq_lock, flags);
+ /*
+ * Flush the TLB, to ensure no TLB maintenance occurs
+ * when DDR is in self-refresh.
+ */
+ ttbr1 = save_ttbr1();
+
+ /* Now change DDR frequency. */
+ if (cpu_is_imx6sl())
+ mx6_change_lpddr2_freq(ddr_rate,
+ (mode == BUS_FREQ_LOW || mode == BUS_FREQ_ULTRA_LOW) ? 1 : 0);
+ else
+ mx6_change_lpddr2_freq(ddr_rate,
+ (mode == BUS_FREQ_LOW || mode == BUS_FREQ_AUDIO) ? 1 : 0);
+
+ restore_ttbr1(ttbr1);
+
+ curr_ddr_rate = ddr_rate;
+ spin_unlock_irqrestore(&freq_lock, flags);
+
+ printk(KERN_DEBUG "\nBus freq set to %d done...\n", ddr_rate);
+
+ return 0;
+}
+
+int init_mmdc_lpddr2_settings(struct platform_device *busfreq_pdev)
+{
+ unsigned long ddr_code_size;
+ busfreq_dev = &busfreq_pdev->dev;
+
+ ddr_code_size = SZ_4K;
+
+ if (cpu_is_imx6sl())
+ mx6_change_lpddr2_freq = (void *)fncpy(
+ (void *)ddr_freq_change_iram_base,
+ &mx6_lpddr2_freq_change, ddr_code_size);
+ if (cpu_is_imx6sx() || cpu_is_imx6ul() || cpu_is_imx6ull())
+ mx6_change_lpddr2_freq = (void *)fncpy(
+ (void *)ddr_freq_change_iram_base,
+ &imx6_up_lpddr2_freq_change, ddr_code_size);
+ if (cpu_is_imx6sll())
+ mx6_change_lpddr2_freq = (void *)fncpy(
+ (void *)ddr_freq_change_iram_base,
+ &imx6sll_lpddr2_freq_change, ddr_code_size);
+
+ curr_ddr_rate = ddr_normal_rate;
+
+ return 0;
+}
+
+int update_lpddr2_freq_smp(int ddr_rate)
+{
+ unsigned long ttbr1;
+ int i, me = 0;
+#ifdef CONFIG_SMP
+ int cpu = 0;
+ u32 reg = 0;
+#endif
+
+ if (ddr_rate == curr_ddr_rate)
+ return 0;
+
+ printk(KERN_DEBUG "Bus freq set to %d start...\n", ddr_rate);
+
+ for (i=0; i < mmdc_settings_size; i++) {
+ iram_mmdc_settings[i][0] = mmdc_settings[i][0];
+ iram_mmdc_settings[i][1] = mmdc_settings[i][1];
+ }
+
+ mmdc_settings_info->size = mmdc_settings_size;
+ mmdc_settings_info->settings = iram_mmdc_settings;
+ mmdc_settings_info->freq = curr_ddr_rate;
+
+ /* ensure that all Cores are in WFE. */
+ local_irq_disable();
+
+#ifdef CONFIG_SMP
+ me = smp_processor_id();
+
+ /* Make sure all the online cores are active */
+ while (1) {
+ bool not_exited_busfreq = false;
+ for_each_online_cpu(cpu) {
+ reg = __raw_readl(imx_scu_base + 0x08);
+ if (reg & (0x02 << (cpu * 8)))
+ not_exited_busfreq = true;
+ }
+ if (!not_exited_busfreq)
+ break;
+ }
+
+ wmb();
+ *wait_for_lpddr2_freq_update = 1;
+ dsb();
+ online_cpus = readl_relaxed(imx_scu_base + 0x08);
+ for_each_online_cpu(cpu) {
+ *((char *)(&online_cpus) + (u8)cpu) = 0x02;
+ if (cpu != me) {
+ reg = 1 << (irqs_used[cpu] % 32);
+ writel_relaxed(reg, gic_dist_base + GIC_DIST_PENDING_SET
+ + (irqs_used[cpu] / 32) * 4);
+ }
+ }
+
+ /* Wait for the other active CPUs to idle */
+ while (1) {
+ reg = 0;
+ reg = readl_relaxed(imx_scu_base + 0x08);
+ reg |= (0x02 << (me * 8));
+ if (reg == online_cpus)
+ break;
+ }
+#endif
+
+ /* Ensure iram_tlb_phys_addr is flushed to DDR. */
+ __cpuc_flush_dcache_area(&iram_tlb_phys_addr,
+ sizeof(iram_tlb_phys_addr));
+ outer_clean_range(__pa(&iram_tlb_phys_addr),
+ __pa(&iram_tlb_phys_addr + 1));
+ /*
+ * Flush the TLB, to ensure no TLB maintenance occurs
+ * when DDR is in self-refresh.
+ */
+ ttbr1 = save_ttbr1();
+
+ curr_ddr_rate = ddr_rate;
+
+ /* Now change DDR frequency. */
+ mx6_change_lpddr2_freq_smp(ddr_rate, mmdc_settings_info);
+
+ restore_ttbr1(ttbr1);
+
+#ifdef CONFIG_SMP
+ wmb();
+ /* DDR frequency change is done . */
+ *wait_for_lpddr2_freq_update = 0;
+ dsb();
+ /* wake up all the cores. */
+ sev();
+#endif
+
+ local_irq_enable();
+
+ printk(KERN_DEBUG "Bus freq set to %d done! cpu=%d\n", ddr_rate, me);
+
+ return 0;
+}
+
+int init_mmdc_lpddr2_settings_mx6q(struct platform_device *busfreq_pdev)
+{
+ struct device *dev = &busfreq_pdev->dev;
+ unsigned long ddr_code_size = 0;
+ unsigned long wfe_code_size = 0;
+ struct device_node *node;
+ void __iomem *mmdc_base;
+ int i;
+#ifdef CONFIG_SMP
+ struct irq_data *d;
+ u32 cpu;
+ int err;
+#endif
+
+ node = of_find_compatible_node(NULL, NULL, "fsl,imx6q-mmdc");
+ if (!node) {
+ printk(KERN_ERR "failed to find mmdc device tree data!\n");
+ return -EINVAL;
+ }
+
+ mmdc_base = of_iomap(node, 0);
+ if (!mmdc_base) {
+ dev_err(dev, "unable to map mmdc registers\n");
+ return -EINVAL;
+ }
+
+ mmdc_settings_size = ARRAY_SIZE(mmdc_timing_settings);
+ mmdc_settings = kmalloc((mmdc_settings_size * 8), GFP_KERNEL);
+ memcpy(mmdc_settings, mmdc_timing_settings,
+ sizeof(mmdc_timing_settings));
+
+#ifdef CONFIG_SMP
+ node = of_find_compatible_node(NULL, NULL, "arm,cortex-a9-gic");
+ if (!node) {
+ printk(KERN_ERR "failed to find imx6q-a9-gic device tree data!\n");
+ return -EINVAL;
+ }
+
+ gic_dist_base = of_iomap(node, 0);
+ WARN(!gic_dist_base, "unable to map gic dist registers\n");
+
+ irqs_used = devm_kzalloc(dev, sizeof(u32) * num_present_cpus(),
+ GFP_KERNEL);
+
+ for_each_online_cpu(cpu) {
+ int irq = platform_get_irq(busfreq_pdev, cpu);
+ err = request_irq(irq, wait_in_wfe_irq, IRQF_PERCPU,
+ "mmdc_1", NULL);
+ if (err) {
+ dev_err(dev,
+ "Busfreq:request_irq failed %d, err = %d\n",
+ irq, err);
+ return err;
+ }
+ err = irq_set_affinity(irq, cpumask_of(cpu));
+ if (err) {
+ dev_err(dev,
+ "Busfreq: Cannot set irq affinity irq=%d,\n",
+ irq);
+ return err;
+ }
+ d = irq_get_irq_data(irq);
+ irqs_used[cpu] = d->hwirq + 32;
+ }
+
+ /* Stoange_iram_basee the variable used to communicate between cores in
+ * a non-cacheable IRAM area */
+ wait_for_lpddr2_freq_update = (u32 *)ddr_freq_change_iram_base;
+ wfe_code_size = (&wfe_smp_freq_change_end - &wfe_smp_freq_change_start) *4;
+
+ wfe_change_lpddr2_freq = (void *)fncpy((void *)ddr_freq_change_iram_base + 0x8,
+ &wfe_smp_freq_change, wfe_code_size);
+#endif
+ iram_settings_size = (void *)ddr_freq_change_iram_base + wfe_code_size + 0x8;
+ iram_mmdc_settings = (void *)iram_settings_size + sizeof(*mmdc_settings_info);
+ iram_ddr_freq_chage = (void *)iram_mmdc_settings + (mmdc_settings_size * 8) + 0x8;
+ mmdc_settings_info = (struct mmdc_settings_info *)iram_settings_size;
+
+ ddr_code_size = (&mx6q_lpddr2_freq_change_end -&mx6q_lpddr2_freq_change_start) *4;
+
+ mx6_change_lpddr2_freq_smp = (void *)fncpy(iram_ddr_freq_chage,
+ &mx6q_lpddr2_freq_change, ddr_code_size);
+
+ /* save initial mmdc boot timing settings */
+ for (i=0; i < mmdc_settings_size; i++)
+ mmdc_settings[i][1] = readl_relaxed(mmdc_base +
+ mmdc_settings[i][0]);
+
+ curr_ddr_rate = ddr_normal_rate;
+
+ return 0;
+}
diff --git a/arch/arm/mach-imx/busfreq_optee.c b/arch/arm/mach-imx/busfreq_optee.c
new file mode 100644
index 000000000000..c475402dd153
--- /dev/null
+++ b/arch/arm/mach-imx/busfreq_optee.c
@@ -0,0 +1,310 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2018 NXP
+ */
+
+/*
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/*!
+ * @file busfreq_optee.c
+ *
+ * @brief iMX.6 and i.MX7 Bus Frequency change.\n
+ * Call OPTEE busfreq function regardless memory type and device.
+ *
+ * @ingroup PM
+ */
+#include <asm/fncpy.h>
+#include <linux/busfreq-imx.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/irqchip/arm-gic.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/slab.h>
+#include <linux/platform_device.h>
+
+#include "hardware.h"
+#include "smc_sip.h"
+
+
+extern unsigned int ddr_normal_rate;
+static int curr_ddr_rate;
+
+#ifdef CONFIG_SMP
+/*
+ * External declaration
+ */
+extern void imx_smp_wfe_optee(u32 cpuid, u32 status_addr);
+extern unsigned long imx_smp_wfe_start asm("imx_smp_wfe_optee");
+extern unsigned long imx_smp_wfe_end asm("imx_smp_wfe_optee_end");
+
+extern unsigned long ddr_freq_change_iram_base;
+
+
+/**
+ * @brief Definition of the synchronization status
+ * structure used to control to CPUs status
+ * and on-going frequency change
+ */
+struct busfreq_sync {
+ uint32_t change_ongoing;
+ uint32_t wfe_status[NR_CPUS];
+} __aligned(8);
+
+static struct busfreq_sync *pSync;
+
+static void (*wfe_change_freq)(uint32_t *wfe_status, uint32_t *freq_done);
+
+static uint32_t *irqs_for_wfe;
+static void __iomem *gic_dist_base;
+
+/**
+ * @brief Switch all active cores, except the one changing the
+ * bus frequency, in WFE mode until completion of the
+ * frequency change
+ *
+ * @param[in] irq Interrupt ID - not used
+ * @param[in] dev_id Client data - not used
+ *
+ * @retval IRQ_HANDLED Interrupt handled
+ */
+static irqreturn_t wait_in_wfe_irq(int irq, void *dev_id)
+{
+ uint32_t me;
+
+ me = smp_processor_id();
+#ifdef CONFIG_LOCAL_TIMERS
+ clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER,
+ &me);
+#endif
+
+ wfe_change_freq(&pSync->wfe_status[me], &pSync->change_ongoing);
+
+#ifdef CONFIG_LOCAL_TIMERS
+ clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT,
+ &me);
+#endif
+
+ return IRQ_HANDLED;
+}
+#endif
+
+/**
+ * @brief Request OPTEE OS to change the memory bus frequency
+ * to \a ddr_rate value
+ *
+ * @param[in] rate Bus Frequency
+ *
+ * @retval 0 Success
+ */
+int update_freq_optee(int ddr_rate)
+{
+ struct arm_smccc_res res;
+
+ uint32_t me = 0;
+ uint32_t dll_off = 0;
+ int mode = get_bus_freq_mode();
+
+#ifdef CONFIG_SMP
+ uint32_t reg = 0;
+ uint32_t cpu = 0;
+ uint32_t online_cpus = 0;
+ uint32_t all_cpus = 0;
+#endif
+
+ pr_info("\nBusfreq OPTEE set from %d to %d start...\n",
+ curr_ddr_rate, ddr_rate);
+
+ if (ddr_rate == curr_ddr_rate)
+ return 0;
+
+ if (cpu_is_imx6()) {
+ if ((mode == BUS_FREQ_LOW) || (mode == BUS_FREQ_AUDIO))
+ dll_off = 1;
+ }
+
+ local_irq_disable();
+
+#ifdef CONFIG_SMP
+ me = smp_processor_id();
+
+ /* Make sure all the online cores to be active */
+ do {
+ all_cpus = 0;
+
+ for_each_online_cpu(cpu)
+ all_cpus |= (pSync->wfe_status[cpu] << cpu);
+ } while (all_cpus);
+
+ pSync->change_ongoing = 1;
+ dsb();
+
+ for_each_online_cpu(cpu) {
+ if (cpu != me) {
+ online_cpus |= (1 << cpu);
+ /* Set the interrupt to be pending in the GIC. */
+ reg = 1 << (irqs_for_wfe[cpu] % 32);
+ writel_relaxed(reg, gic_dist_base + GIC_DIST_PENDING_SET
+ + (irqs_for_wfe[cpu] / 32) * 4);
+ }
+ }
+
+ /* Wait for all active CPUs to be in WFE */
+ do {
+ all_cpus = 0;
+
+ for_each_online_cpu(cpu)
+ all_cpus |= (pSync->wfe_status[cpu] << cpu);
+ } while (all_cpus != online_cpus);
+
+#endif
+
+ /* Now we can change the DDR frequency. */
+ /* Call the TEE SiP */
+ arm_smccc_smc(OPTEE_SMC_FAST_CALL_SIP_VAL(IMX_SIP_BUSFREQ_CHANGE),
+ ddr_rate, dll_off, 0, 0, 0, 0, 0, &res);
+
+ curr_ddr_rate = ddr_rate;
+
+#ifdef CONFIG_SMP
+ /* DDR frequency change is done */
+ pSync->change_ongoing = 0;
+ dsb();
+
+ /* wake up all the cores. */
+ sev();
+#endif
+
+ local_irq_enable();
+
+ pr_info("Busfreq OPTEE set to %d done! cpu=%d\n",
+ ddr_rate, me);
+
+ return 0;
+}
+
+#ifdef CONFIG_SMP
+static int init_freq_optee_smp(struct platform_device *busfreq_pdev)
+{
+ struct device_node *node = 0;
+ struct device *dev = &busfreq_pdev->dev;
+ uint32_t cpu;
+ int err;
+ int irq;
+ struct irq_data *irq_data;
+ unsigned long wfe_iram_base;
+
+ if (cpu_is_imx6()) {
+ node = of_find_compatible_node(NULL, NULL, "arm,cortex-a9-gic");
+ if (!node) {
+ if (cpu_is_imx6q())
+ pr_debug("failed to find imx6q-a9-gic device tree data!\n");
+
+ return -EINVAL;
+ }
+ } else {
+ node = of_find_compatible_node(NULL, NULL, "arm,cortex-a7-gic");
+ if (!node) {
+ pr_debug("failed to find imx7d-a7-gic device tree data!\n");
+ return -EINVAL;
+ }
+ }
+
+ gic_dist_base = of_iomap(node, 0);
+ WARN(!gic_dist_base, "unable to map gic dist registers\n");
+
+ irqs_for_wfe = devm_kzalloc(dev, sizeof(uint32_t) * num_present_cpus(),
+ GFP_KERNEL);
+
+ for_each_online_cpu(cpu) {
+ /*
+ * set up a reserved interrupt to get all
+ * the active cores into a WFE state
+ * before changing the DDR frequency.
+ */
+ irq = platform_get_irq(busfreq_pdev, cpu);
+
+ if (cpu_is_imx6()) {
+ err = request_irq(irq, wait_in_wfe_irq,
+ IRQF_PERCPU, "mmdc_1", NULL);
+ } else {
+ err = request_irq(irq, wait_in_wfe_irq,
+ IRQF_PERCPU, "ddrc", NULL);
+ }
+
+ if (err) {
+ dev_err(dev,
+ "Busfreq:request_irq failed %d, err = %d\n",
+ irq, err);
+ return err;
+ }
+
+ err = irq_set_affinity(irq, cpumask_of(cpu));
+ if (err) {
+ dev_err(dev,
+ "Busfreq: Cannot set irq affinity irq=%d,\n",
+ irq);
+ return err;
+ }
+
+ irq_data = irq_get_irq_data(irq);
+ irqs_for_wfe[cpu] = irq_data->hwirq + 32;
+ }
+
+ /* Store the variable used to communicate between cores */
+ pSync = (void *)ddr_freq_change_iram_base;
+
+ memset(pSync, 0, sizeof(*pSync));
+
+ wfe_iram_base = ddr_freq_change_iram_base + sizeof(*pSync);
+
+ if (wfe_iram_base & (FNCPY_ALIGN - 1))
+ wfe_iram_base += FNCPY_ALIGN -
+ ((uintptr_t)wfe_iram_base % (FNCPY_ALIGN));
+
+ wfe_change_freq = (void *)fncpy((void *)wfe_iram_base,
+ &imx_smp_wfe_optee,
+ ((&imx_smp_wfe_end -&imx_smp_wfe_start) *4));
+
+ return 0;
+
+}
+
+int init_freq_optee(struct platform_device *busfreq_pdev)
+{
+ int err = -EINVAL;
+ struct device *dev = &busfreq_pdev->dev;
+
+ if (num_present_cpus() <= 1) {
+ wfe_change_freq = NULL;
+
+ /* Allocate the cores synchronization variables (not used) */
+ pSync = devm_kzalloc(dev, sizeof(*pSync), GFP_KERNEL);
+
+ if (pSync)
+ err = 0;
+ } else {
+ err = init_freq_optee_smp(busfreq_pdev);
+ }
+
+ if (err == 0)
+ curr_ddr_rate = ddr_normal_rate;
+
+ return err;
+}
+#else
+int init_freq_optee(struct platform_device *busfreq_pdev)
+{
+ curr_ddr_rate = ddr_normal_rate;
+ return 0;
+}
+#endif
+
diff --git a/arch/arm/mach-imx/common.c b/arch/arm/mach-imx/common.c
new file mode 100644
index 000000000000..cf57b55a369b
--- /dev/null
+++ b/arch/arm/mach-imx/common.c
@@ -0,0 +1,166 @@
+/*
+ * Copyright (C) 2015-2016 Freescale Semiconductor, Inc.
+ *
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_net.h>
+#include <linux/slab.h>
+
+#include "hardware.h"
+
+unsigned long iram_tlb_base_addr;
+unsigned long iram_tlb_phys_addr;
+
+unsigned long save_ttbr1(void)
+{
+ unsigned long lttbr1;
+ asm volatile(
+ ".align 4\n"
+ "mrc p15, 0, %0, c2, c0, 1\n"
+ : "=r" (lttbr1)
+ );
+ return lttbr1;
+}
+
+void restore_ttbr1(unsigned long ttbr1)
+{
+ asm volatile(
+ ".align 4\n"
+ "mcr p15, 0, %0, c2, c0, 1\n"
+ : : "r" (ttbr1)
+ );
+}
+
+#define OCOTP_MAC_OFF (cpu_is_imx7d() ? 0x640 : 0x620)
+#define OCOTP_MACn(n) (OCOTP_MAC_OFF + (n) * 0x10)
+void __init imx6_enet_mac_init(const char *enet_compat, const char *ocotp_compat)
+{
+ struct device_node *ocotp_np, *enet_np, *from = NULL;
+ void __iomem *base;
+ struct property *newmac;
+ u32 macaddr_low;
+ u32 macaddr_high = 0;
+ u32 macaddr1_high = 0;
+ u8 *macaddr;
+ int i, id;
+
+ for (i = 0; i < 2; i++) {
+ enet_np = of_find_compatible_node(from, NULL, enet_compat);
+ if (!enet_np)
+ return;
+
+ from = enet_np;
+
+ if (of_get_mac_address(enet_np))
+ goto put_enet_node;
+
+ id = of_alias_get_id(enet_np, "ethernet");
+ if (id < 0)
+ id = i;
+
+ ocotp_np = of_find_compatible_node(NULL, NULL, ocotp_compat);
+ if (!ocotp_np) {
+ pr_warn("failed to find ocotp node\n");
+ goto put_enet_node;
+ }
+
+ base = of_iomap(ocotp_np, 0);
+ if (!base) {
+ pr_warn("failed to map ocotp\n");
+ goto put_ocotp_node;
+ }
+
+ macaddr_low = readl_relaxed(base + OCOTP_MACn(1));
+ if (id)
+ macaddr1_high = readl_relaxed(base + OCOTP_MACn(2));
+ else
+ macaddr_high = readl_relaxed(base + OCOTP_MACn(0));
+
+ newmac = kzalloc(sizeof(*newmac) + 6, GFP_KERNEL);
+ if (!newmac)
+ goto put_ocotp_node;
+
+ newmac->value = newmac + 1;
+ newmac->length = 6;
+ newmac->name = kstrdup("local-mac-address", GFP_KERNEL);
+ if (!newmac->name) {
+ kfree(newmac);
+ goto put_ocotp_node;
+ }
+
+ macaddr = newmac->value;
+ if (id) {
+ macaddr[5] = (macaddr_low >> 16) & 0xff;
+ macaddr[4] = (macaddr_low >> 24) & 0xff;
+ macaddr[3] = macaddr1_high & 0xff;
+ macaddr[2] = (macaddr1_high >> 8) & 0xff;
+ macaddr[1] = (macaddr1_high >> 16) & 0xff;
+ macaddr[0] = (macaddr1_high >> 24) & 0xff;
+ } else {
+ macaddr[5] = macaddr_high & 0xff;
+ macaddr[4] = (macaddr_high >> 8) & 0xff;
+ macaddr[3] = (macaddr_high >> 16) & 0xff;
+ macaddr[2] = (macaddr_high >> 24) & 0xff;
+ macaddr[1] = macaddr_low & 0xff;
+ macaddr[0] = (macaddr_low >> 8) & 0xff;
+ }
+
+ of_update_property(enet_np, newmac);
+
+put_ocotp_node:
+ of_node_put(ocotp_np);
+put_enet_node:
+ of_node_put(enet_np);
+ }
+}
+
+#ifndef CONFIG_HAVE_IMX_GPC
+int imx_gpc_mf_request_on(unsigned int irq, unsigned int on) { return 0; }
+EXPORT_SYMBOL_GPL(imx_gpc_mf_request_on);
+#endif
+
+#if !defined(CONFIG_SOC_IMX6SL)
+u32 imx6_lpddr2_freq_change_start, imx6_lpddr2_freq_change_end;
+void mx6_lpddr2_freq_change(u32 freq, int bus_freq_mode) {}
+#endif
+
+#if !defined(CONFIG_SOC_IMX6SLL)
+void imx6sll_lpddr2_freq_change(u32 freq, int bus_freq_mode) {}
+#endif
+
+#if !defined(CONFIG_SOC_IMX6SX) && !defined(CONFIG_SOC_IMX6UL)
+u32 imx6_up_ddr3_freq_change_start, imx6_up_ddr3_freq_change_end;
+struct imx6_busfreq_info {
+} __aligned(8);
+void imx6_up_ddr3_freq_change(struct imx6_busfreq_info *busfreq_info) {}
+void imx6_up_lpddr2_freq_change(u32 freq, int bus_freq_mode) {}
+#endif
+
+#if !defined(CONFIG_SOC_IMX6ULL)
+u32 mx6ull_lpm_wfi_start, mx6ull_lpm_wfi_end;
+void imx6ull_low_power_idle(void) {}
+#endif
+
+#if !defined(CONFIG_SOC_IMX6Q)
+u32 mx6_ddr3_freq_change_start, mx6_ddr3_freq_change_end;
+u32 mx6q_lpddr2_freq_change_start, mx6q_lpddr2_freq_change_end;
+u32 wfe_smp_freq_change_start, wfe_smp_freq_change_end;
+void mx6_ddr3_freq_change(u32 freq, void *ddr_settings,
+ bool dll_mode, void *iomux_offsets) {}
+void mx6q_lpddr2_freq_change(u32 freq, void *ddr_settings) {}
+void wfe_smp_freq_change(u32 cpuid, u32 *ddr_freq_change_done) {}
+#endif
+
+#if !defined(CONFIG_SOC_IMX7D)
+void imx7_smp_wfe(u32 cpuid, u32 ocram_base) {}
+void imx7d_ddr3_freq_change(u32 freq) {}
+#endif
+
diff --git a/arch/arm/mach-imx/common.h b/arch/arm/mach-imx/common.h
index b09a2ec19267..02529cda7cb1 100644
--- a/arch/arm/mach-imx/common.h
+++ b/arch/arm/mach-imx/common.h
@@ -1,5 +1,6 @@
/*
- * Copyright 2004-2014 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2004-2016 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2017 NXP
*/
/*
@@ -12,11 +13,13 @@
#define __ASM_ARCH_MXC_COMMON_H__
#include <linux/reboot.h>
+#include <soc/imx/src.h>
struct irq_data;
struct platform_device;
struct pt_regs;
struct clk;
+struct clk_hw;
struct device_node;
enum mxc_cpu_pwr_mode;
struct of_device_id;
@@ -62,6 +65,28 @@ void imx_gpc_set_arm_power_up_timing(u32 sw2iso, u32 sw);
void imx_gpc_set_arm_power_down_timing(u32 sw2iso, u32 sw);
void imx25_pm_init(void);
void imx27_pm_init(void);
+unsigned int imx_gpc_is_mf_mix_off(void);
+void imx6sx_set_m4_highfreq(bool high_freq);
+void imx_mu_enable_m4_irqs_in_gic(bool enable);
+#ifdef CONFIG_HAVE_IMX_GPC
+void imx_gpc_add_m4_wake_up_irq(u32 irq, bool enable);
+unsigned int imx_gpc_is_m4_sleeping(void);
+#else
+static inline void imx_gpc_add_m4_wake_up_irq(u32 irq, bool enable) {}
+static inline unsigned int imx_gpc_is_m4_sleeping(void) { return 0; }
+#endif
+void imx_gpc_hold_m4_in_sleep(void);
+void imx_gpc_release_m4_in_sleep(void);
+void mcc_receive_from_mu_buffer(unsigned int index, unsigned int *data);
+void mcc_send_via_mu_buffer(unsigned int index, unsigned int data);
+bool imx_mu_is_m4_in_low_freq(void);
+bool imx_mu_is_m4_in_stop(void);
+void imx_mu_set_m4_run_mode(void);
+#ifdef CONFIG_HAVE_IMX_MU
+int imx_mu_lpm_ready(bool ready);
+#else
+static inline int imx_mu_lpm_ready(bool ready) { return 0; }
+#endif
enum mxc_cpu_pwr_mode {
WAIT_CLOCKED, /* wfi only */
@@ -78,6 +103,17 @@ enum mx3_cpu_pwr_mode {
MX3_SLEEP,
};
+enum imx7ulp_cpu_pwr_mode {
+ HSRUN,
+ RUN,
+ VLPR,
+ WAIT,
+ VLPW,
+ STOP,
+ VLPS,
+ VLLS,
+};
+
void mx3_cpu_lp_set(enum mx3_cpu_pwr_mode mode);
void imx_enable_cpu(int cpu, bool enable);
@@ -92,9 +128,35 @@ void imx_smp_prepare(void);
static inline void imx_scu_map_io(void) {}
static inline void imx_smp_prepare(void) {}
#endif
+void imx6_pm_map_io(void);
+void imx7_pm_map_io(void);
+void imx7ulp_pm_map_io(void);
void imx_src_init(void);
void imx_gpc_pre_suspend(bool arm_power_off);
void imx_gpc_post_resume(void);
+void imx_gpc_switch_pupscr_clk(bool flag);
+unsigned int imx_gpc_is_mf_mix_off(void);
+void imx_gpcv2_pre_suspend(bool arm_power_off);
+void imx_gpcv2_post_resume(void);
+unsigned int imx_gpcv2_is_mf_mix_off(void);
+void imx_gpcv2_enable_wakeup_for_m4(void);
+void imx_gpcv2_disable_wakeup_for_m4(void);
+int imx_gpc_mf_power_on(unsigned int irq, unsigned int on);
+#ifdef CONFIG_HAVE_IMX_GPCV2
+int imx_gpcv2_mf_power_on(unsigned int irq, unsigned int on);
+void imx_gpcv2_set_core1_pdn_pup_by_software(bool pdn);
+void imx_gpcv2_add_m4_wake_up_irq(u32 hwirq, bool enable);
+#else
+static inline int imx_gpcv2_mf_power_on(unsigned int irq, unsigned int on) { return 0; }
+static inline void imx_gpcv2_set_core1_pdn_pup_by_software(bool pdn) {}
+static inline void imx_gpcv2_add_m4_wake_up_irq(u32 hwirq, bool enable) {}
+#endif
+void __init imx_gpcv2_check_dt(void);
+void imx_gpcv2_set_lpm_mode(enum mxc_cpu_pwr_mode mode);
+void imx_gpcv2_set_cpu_power_gate_in_idle(bool pdn);
+void imx_gpcv2_enable_rbc(bool enable);
+unsigned long save_ttbr1(void);
+void restore_ttbr1(unsigned long ttbr1);
void imx_gpc_mask_all(void);
void imx_gpc_restore_all(void);
void imx_gpc_hwirq_mask(unsigned int hwirq);
@@ -105,21 +167,56 @@ void imx_anatop_post_resume(void);
int imx6_set_lpm(enum mxc_cpu_pwr_mode mode);
void imx6_set_int_mem_clk_lpm(bool enable);
void imx6sl_set_wait_clk(bool enter);
+void imx6_enet_mac_init(const char *enet_compat, const char *ocotp_compat);
+int imx7ulp_set_lpm(enum imx7ulp_cpu_pwr_mode mode);
+#ifdef CONFIG_HAVE_IMX_MMDC
int imx_mmdc_get_ddr_type(void);
-
+int imx_mmdc_get_lpddr2_2ch_mode(void);
+#else
+static inline int imx_mmdc_get_ddr_type(void) { return 0; }
+static inline int imx_mmdc_get_lpddr2_2ch_mode(void) { return 0; }
+#endif
+#ifdef CONFIG_HAVE_IMX_DDRC
+int imx_ddrc_get_ddr_type(void);
+#else
+static inline int imx_ddrc_get_ddr_type(void) { return 0; }
+#endif
void imx_cpu_die(unsigned int cpu);
int imx_cpu_kill(unsigned int cpu);
+void imx_busfreq_map_io(void);
+void imx7d_low_power_idle(void);
+void imx6sx_low_power_idle(void);
+void imx6ul_low_power_idle(void);
+void imx6ull_low_power_idle(void);
+void imx6sl_low_power_idle(void);
+void imx6sll_low_power_idle(void);
+bool imx_gpc_usb_wakeup_enabled(void);
+bool imx_gpc_enet_wakeup_enabled(void);
#ifdef CONFIG_SUSPEND
void v7_cpu_resume(void);
+void ca7_cpu_resume(void);
void imx53_suspend(void __iomem *ocram_vbase);
extern const u32 imx53_suspend_sz;
+void imx7ulp_cpu_resume(void);
void imx6_suspend(void __iomem *ocram_vbase);
+void imx7_suspend(void __iomem *ocram_vbase);
+void imx7ulp_suspend(void __iomem *ocram_vbase);
#else
static inline void v7_cpu_resume(void) {}
+static inline void ca7_cpu_resume(void) {}
static inline void imx53_suspend(void __iomem *ocram_vbase) {}
static const u32 imx53_suspend_sz;
+static inline void imx7ulp_cpu_resume(void) {}
static inline void imx6_suspend(void __iomem *ocram_vbase) {}
+static inline void imx7_suspend(void __iomem *ocram_vbase) {}
+static inline void imx7ulp_suspend(void __iomem *ocram_vbase) {}
+#endif
+
+#ifdef CONFIG_SOC_IMX7ULP
+void pm_shutdown_notify_m4(void);
+#else
+static inline void pm_shutdown_notify_m4(void) {}
#endif
void imx6_pm_ccm_init(const char *ccm_compat);
@@ -128,6 +225,12 @@ void imx6dl_pm_init(void);
void imx6sl_pm_init(void);
void imx6sx_pm_init(void);
void imx6ul_pm_init(void);
+void imx6ull_pm_init(void);
+void imx7d_pm_init(void);
+void imx7ulp_pm_init(void);
+void imx7ulp_enable_nmi(void);
+void imx7ulp_poweroff(void);
+void imx6q_pm_set_ccm_base(void __iomem *base);
#ifdef CONFIG_PM
void imx51_pm_init(void);
@@ -152,4 +255,6 @@ static inline void imx_init_l2cache(void) {}
extern const struct smp_operations imx_smp_ops;
extern const struct smp_operations ls1021a_smp_ops;
+extern bool uart_from_osc;
+
#endif
diff --git a/arch/arm/mach-imx/cpu.c b/arch/arm/mach-imx/cpu.c
index d4e55f2a897e..9f53229d8b5a 100644
--- a/arch/arm/mach-imx/cpu.c
+++ b/arch/arm/mach-imx/cpu.c
@@ -127,7 +127,10 @@ struct device * __init imx_soc_device_init(void)
soc_id = "i.MX6SX";
break;
case MXC_CPU_IMX6Q:
- soc_id = "i.MX6Q";
+ if (imx_get_soc_revision() >= IMX_CHIP_REVISION_2_0)
+ soc_id = "i.MX6QP";
+ else
+ soc_id = "i.MX6Q";
break;
case MXC_CPU_IMX6UL:
soc_id = "i.MX6UL";
@@ -135,9 +138,18 @@ struct device * __init imx_soc_device_init(void)
case MXC_CPU_IMX6ULL:
soc_id = "i.MX6ULL";
break;
+ case MXC_CPU_IMX6ULZ:
+ soc_id = "i.MX6ULZ";
+ break;
case MXC_CPU_IMX7D:
soc_id = "i.MX7D";
break;
+ case MXC_CPU_IMX6SLL:
+ soc_id = "i.MX6SLL";
+ break;
+ case MXC_CPU_IMX7ULP:
+ soc_id = "i.MX7ULP";
+ break;
default:
soc_id = "Unknown";
}
diff --git a/arch/arm/mach-imx/cpuidle-imx6q.c b/arch/arm/mach-imx/cpuidle-imx6q.c
index 326e870d7123..02d55ae7e0eb 100644
--- a/arch/arm/mach-imx/cpuidle-imx6q.c
+++ b/arch/arm/mach-imx/cpuidle-imx6q.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012 Freescale Semiconductor, Inc.
+ * Copyright (C) 2012, 2016 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
@@ -16,24 +16,34 @@
#include "cpuidle.h"
#include "hardware.h"
-static int num_idle_cpus = 0;
-static DEFINE_SPINLOCK(cpuidle_lock);
+static atomic_t master = ATOMIC_INIT(0);
+static DEFINE_SPINLOCK(master_lock);
static int imx6q_enter_wait(struct cpuidle_device *dev,
struct cpuidle_driver *drv, int index)
{
- spin_lock(&cpuidle_lock);
- if (++num_idle_cpus == num_online_cpus())
+ if (atomic_inc_return(&master) == num_online_cpus()) {
+ /*
+ * With this lock, we prevent other cpu to exit and enter
+ * this function again and become the master.
+ */
+ if (!spin_trylock(&master_lock))
+ goto idle;
imx6_set_lpm(WAIT_UNCLOCKED);
- spin_unlock(&cpuidle_lock);
+ if (atomic_read(&master) != num_online_cpus())
+ imx6_set_lpm(WAIT_CLOCKED);
+ cpu_do_idle();
+ imx6_set_lpm(WAIT_CLOCKED);
+ spin_unlock(&master_lock);
+ goto done;
+ }
+idle:
cpu_do_idle();
+done:
+ atomic_dec(&master);
- spin_lock(&cpuidle_lock);
- if (num_idle_cpus-- == num_online_cpus())
- imx6_set_lpm(WAIT_CLOCKED);
- spin_unlock(&cpuidle_lock);
-
+ imx6_set_lpm(WAIT_CLOCKED);
return index;
}
diff --git a/arch/arm/mach-imx/cpuidle-imx6sl.c b/arch/arm/mach-imx/cpuidle-imx6sl.c
index 8d866fb674a8..4abfe1767195 100644
--- a/arch/arm/mach-imx/cpuidle-imx6sl.c
+++ b/arch/arm/mach-imx/cpuidle-imx6sl.c
@@ -1,29 +1,105 @@
/*
- * Copyright (C) 2014 Freescale Semiconductor, Inc.
+ * Copyright (C) 2014-2015 Freescale Semiconductor, Inc.
+ * Copyright 2017-2018 NXP.
*
* 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/busfreq-imx.h>
#include <linux/cpuidle.h>
#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/psci.h>
+#include <linux/regulator/consumer.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/machine.h>
#include <asm/cpuidle.h>
+#include <asm/fncpy.h>
+#include <asm/proc-fns.h>
+
+#include <uapi/linux/psci.h>
#include "common.h"
#include "cpuidle.h"
+#include "hardware.h"
+
+#define MAX_MMDC_IO_NUM 19
+
+static void __iomem *wfi_iram_base;
+extern unsigned long iram_tlb_base_addr;
+
+#ifdef CONFIG_CPU_FREQ
+extern unsigned long mx6sl_lpm_wfi_start asm("mx6sl_lpm_wfi_start");
+extern unsigned long mx6sl_lpm_wfi_end asm("mx6sl_lpm_wfi_end");
+#endif
+
+struct imx6_cpuidle_pm_info {
+ u32 pm_info_size; /* Size of pm_info */
+ u32 ttbr;
+ void __iomem *mmdc_base;
+ void __iomem *iomuxc_base;
+ void __iomem *ccm_base;
+ void __iomem *l2_base;
+ void __iomem *anatop_base;
+ u32 mmdc_io_num; /*Number of MMDC IOs which need saved/restored. */
+ u32 mmdc_io_val[MAX_MMDC_IO_NUM][2]; /* To save offset and value */
+} __aligned(8);
+
+static const u32 imx6sl_mmdc_io_offset[] __initconst = {
+ 0x30c, 0x310, 0x314, 0x318, /* DQM0 ~ DQM3 */
+ 0x5c4, 0x5cc, 0x5d4, 0x5d8, /* GPR_B0DS ~ GPR_B3DS */
+ 0x300, 0x31c, 0x338, 0x5ac, /*CAS, RAS, SDCLK_0, GPR_ADDS */
+ 0x33c, 0x340, 0x5b0, 0x5c0, /*SODT0, SODT1, ,MODE_CTL, MODE */
+ 0x330, 0x334, 0x320, /*SDCKE0, SDCK1, RESET */
+};
+
+static struct regulator *vbus_ldo;
+static struct regulator_dev *ldo2p5_dummy_regulator_rdev;
+static struct regulator_init_data ldo2p5_dummy_initdata = {
+ .constraints = {
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ },
+};
+static int ldo2p5_dummy_enable;
+
+static void (*imx6sl_wfi_in_iram_fn)(void __iomem *iram_vbase,
+ int audio_mode, bool vbus_ldo);
+
+#define MX6SL_POWERDWN_IDLE_PARAM \
+ ((1 << PSCI_0_2_POWER_STATE_ID_SHIFT) | \
+ (1 << PSCI_0_2_POWER_STATE_AFFL_SHIFT) | \
+ (PSCI_POWER_STATE_TYPE_POWER_DOWN << PSCI_0_2_POWER_STATE_TYPE_SHIFT))
static int imx6sl_enter_wait(struct cpuidle_device *dev,
struct cpuidle_driver *drv, int index)
{
+ int mode = get_bus_freq_mode();
+
imx6_set_lpm(WAIT_UNCLOCKED);
- /*
- * Software workaround for ERR005311, see function
- * description for details.
- */
- imx6sl_set_wait_clk(true);
- cpu_do_idle();
- imx6sl_set_wait_clk(false);
+
+ if ((mode == BUS_FREQ_AUDIO) || (mode == BUS_FREQ_ULTRA_LOW)) {
+ /*
+ * bit 2 used for low power mode;
+ * bit 1 used for the ldo2p5_dummmy enable
+ */
+ if (psci_ops.cpu_suspend) {
+ psci_ops.cpu_suspend((MX6SL_POWERDWN_IDLE_PARAM | ((mode == BUS_FREQ_AUDIO ? 1 : 0) << 2) |
+ (ldo2p5_dummy_enable ? 1 : 0) << 1), __pa(cpu_resume));
+ } else {
+ imx6sl_wfi_in_iram_fn(wfi_iram_base, (mode == BUS_FREQ_AUDIO) ? 1 : 0,
+ ldo2p5_dummy_enable);
+ }
+ } else {
+ /*
+ * Software workaround for ERR005311, see function
+ * description for details.
+ */
+ imx6sl_set_wait_clk(true);
+ cpu_do_idle();
+ imx6sl_set_wait_clk(false);
+ }
imx6_set_lpm(WAIT_CLOCKED);
return index;
@@ -51,5 +127,108 @@ static struct cpuidle_driver imx6sl_cpuidle_driver = {
int __init imx6sl_cpuidle_init(void)
{
+
+#ifdef CONFIG_CPU_FREQ
+ struct imx6_cpuidle_pm_info *pm_info;
+ int i;
+ const u32 *mmdc_offset_array;
+ u32 wfi_code_size;
+
+ vbus_ldo = regulator_get(NULL, "ldo2p5-dummy");
+ if (IS_ERR(vbus_ldo))
+ vbus_ldo = NULL;
+
+ wfi_iram_base = (void *)(iram_tlb_base_addr + MX6_CPUIDLE_IRAM_ADDR_OFFSET);
+
+ /* Make sure wif_iram_base is 8 byte aligned. */
+ if ((uintptr_t)(wfi_iram_base) & (FNCPY_ALIGN - 1))
+ wfi_iram_base += FNCPY_ALIGN - ((uintptr_t)wfi_iram_base % (FNCPY_ALIGN));
+
+ pm_info = wfi_iram_base;
+ pm_info->pm_info_size = sizeof(*pm_info);
+ pm_info->mmdc_io_num = ARRAY_SIZE(imx6sl_mmdc_io_offset);
+ mmdc_offset_array = imx6sl_mmdc_io_offset;
+ pm_info->mmdc_base = (void __iomem *)IMX_IO_P2V(MX6Q_MMDC_P0_BASE_ADDR);
+ pm_info->ccm_base = (void __iomem *)IMX_IO_P2V(MX6Q_CCM_BASE_ADDR);
+ pm_info->anatop_base = (void __iomem *)IMX_IO_P2V(MX6Q_ANATOP_BASE_ADDR);
+ pm_info->iomuxc_base = (void __iomem *)IMX_IO_P2V(MX6Q_IOMUXC_BASE_ADDR);
+ pm_info->l2_base = (void __iomem *)IMX_IO_P2V(MX6Q_L2_BASE_ADDR);
+
+ /* Only save mmdc io offset, settings will be saved in asm code */
+ for (i = 0; i < pm_info->mmdc_io_num; i++)
+ pm_info->mmdc_io_val[i][0] = mmdc_offset_array[i];
+
+ /* calculate the wfi code size */
+ wfi_code_size = (&mx6sl_lpm_wfi_end -&mx6sl_lpm_wfi_start) *4;
+
+ imx6sl_wfi_in_iram_fn = (void *)fncpy(wfi_iram_base + sizeof(*pm_info),
+ &imx6sl_low_power_idle, wfi_code_size);
+#endif
+
return cpuidle_register(&imx6sl_cpuidle_driver, NULL);
}
+
+static int imx_ldo2p5_dummy_enable(struct regulator_dev *rdev)
+{
+ ldo2p5_dummy_enable = 1;
+ return 0;
+}
+
+static int imx_ldo2p5_dummy_disable(struct regulator_dev *rdev)
+{
+ ldo2p5_dummy_enable = 0;
+ return 0;
+}
+
+static int imx_ldo2p5_dummy_is_enable(struct regulator_dev *rdev)
+{
+ return ldo2p5_dummy_enable;
+}
+
+static struct regulator_ops ldo2p5_dummy_ops = {
+ .enable = imx_ldo2p5_dummy_enable,
+ .disable = imx_ldo2p5_dummy_disable,
+ .is_enabled = imx_ldo2p5_dummy_is_enable,
+};
+
+static struct regulator_desc ldo2p5_dummy_desc = {
+ .name = "ldo2p5-dummy",
+ .id = -1,
+ .type = REGULATOR_VOLTAGE,
+ .owner = THIS_MODULE,
+ .ops = &ldo2p5_dummy_ops,
+};
+
+static int ldo2p5_dummy_probe(struct platform_device *pdev)
+{
+ struct regulator_config config = { };
+ int ret;
+
+ config.dev = &pdev->dev;
+ config.init_data = &ldo2p5_dummy_initdata;
+ config.of_node = pdev->dev.of_node;
+
+ ldo2p5_dummy_regulator_rdev = regulator_register(&ldo2p5_dummy_desc, &config);
+ if (IS_ERR(ldo2p5_dummy_regulator_rdev)) {
+ ret = PTR_ERR(ldo2p5_dummy_regulator_rdev);
+ dev_err(&pdev->dev, "Failed to register dummy ldo2p5 regulator: %d\n", ret);
+ return ret;
+ }
+ return 0;
+}
+
+static const struct of_device_id imx_ldo2p5_dummy_ids[] = {
+ { .compatible = "fsl,imx6-dummy-ldo2p5"},
+ };
+MODULE_DEVICE_TABLE(ofm, imx_ldo2p5_dummy_ids);
+
+static struct platform_driver ldo2p5_dummy_driver = {
+ .probe = ldo2p5_dummy_probe,
+ .driver = {
+ .name = "ldo2p5-dummy",
+ .owner = THIS_MODULE,
+ .of_match_table = imx_ldo2p5_dummy_ids,
+ },
+};
+
+module_platform_driver(ldo2p5_dummy_driver);
diff --git a/arch/arm/mach-imx/cpuidle-imx6sll.c b/arch/arm/mach-imx/cpuidle-imx6sll.c
new file mode 100644
index 000000000000..bb8678ff56f0
--- /dev/null
+++ b/arch/arm/mach-imx/cpuidle-imx6sll.c
@@ -0,0 +1,277 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017 NXP.
+ *
+ * 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/busfreq-imx.h>
+#include <linux/cpuidle.h>
+#include <linux/cpu_pm.h>
+#include <linux/delay.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/psci.h>
+#include <linux/regulator/consumer.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/machine.h>
+#include <asm/cpuidle.h>
+#include <asm/fncpy.h>
+#include <asm/proc-fns.h>
+#include <asm/suspend.h>
+
+#include <uapi/linux/psci.h>
+
+#include "common.h"
+#include "cpuidle.h"
+#include "hardware.h"
+
+#define MAX_MMDC_IO_NUM 14
+
+#define PMU_LOW_PWR_CTRL 0x270
+#define XTALOSC24M_OSC_CONFIG0 0x2a0
+#define XTALOSC24M_OSC_CONFIG1 0x2b0
+#define XTALOSC24M_OSC_CONFIG2 0x2c0
+#define XTALOSC24M_OSC_CONFIG0_RC_OSC_PROG_CUR_SHIFT 24
+#define XTALOSC24M_OSC_CONFIG0_HYST_MINUS_MASK 0xf
+#define XTALOSC24M_OSC_CONFIG0_HYST_MINUS_SHIFT 16
+#define XTALOSC24M_OSC_CONFIG0_HYST_PLUS_MASK 0xf
+#define XTALOSC24M_OSC_CONFIG0_HYST_PLUS_SHIFT 12
+#define XTALOSC24M_OSC_CONFIG0_RC_OSC_PROG_SHIFT 4
+#define XTALOSC24M_OSC_CONFIG0_ENABLE_SHIFT 1
+#define XTALOSC24M_OSC_CONFIG0_START_SHIFT 0
+#define XTALOSC24M_OSC_CONFIG1_COUNT_RC_CUR_SHIFT 20
+#define XTALOSC24M_OSC_CONFIG1_COUNT_RC_TRG_SHIFT 0
+#define XTALOSC24M_OSC_CONFIG2_COUNT_1M_TRG_MASK 0xfff
+#define XTALOSC24M_OSC_CONFIG2_COUNT_1M_TRG_SHIFT 0
+
+extern unsigned long iram_tlb_phys_addr;
+static void __iomem *wfi_iram_base;
+
+#ifdef CONFIG_CPU_FREQ
+static void __iomem *wfi_iram_base_phys;
+extern unsigned long mx6sll_lpm_wfi_start asm("mx6sll_lpm_wfi_start");
+extern unsigned long mx6sll_lpm_wfi_end asm("mx6sll_lpm_wfi_end");
+#endif
+
+struct imx6_pm_base {
+ phys_addr_t pbase;
+ void __iomem *vbase;
+};
+
+struct imx6_cpuidle_pm_info {
+ phys_addr_t pbase; /* The physical address of pm_info. */
+ phys_addr_t resume_addr; /* The physical resume address for asm code */
+ u32 pm_info_size; /* Size of pm_info. */
+ u32 ttbr;
+ struct imx6_pm_base mmdc_base;
+ struct imx6_pm_base iomuxc_base;
+ struct imx6_pm_base ccm_base;
+ struct imx6_pm_base gpc_base;
+ struct imx6_pm_base anatop_base;
+ struct imx6_pm_base src_base;
+ struct imx6_pm_base l2_base;
+ u32 saved_diagnostic; /* To save disagnostic register */
+ u32 mmdc_io_num; /* Number of MMDC IOs which need saved/restored. */
+ u32 mmdc_io_val[MAX_MMDC_IO_NUM][2]; /* To save offset and value */
+} __aligned(8);
+
+static const u32 imx6sll_mmdc_io_offset[] __initconst = {
+ 0x294, 0x298, 0x29c, 0x2a0, /* DQM0, DQM1, RAS, CAS */
+ 0x544, 0x54c, 0x554, 0x558, /* GPR_B0DS ~ GPR_B3DS */
+ 0x530, 0x540, 0x2ac, 0x52c, /* MODE_CTL, MODE, SDCLK0, GPR_ADDS */
+ 0x2a4, 0x2a8, /* SDCKE0, SDCKE1 */
+};
+
+static void (*imx6sll_wfi_in_iram_fn)(void __iomem *iram_vbase);
+
+#define MX6SLL_POWERDWN_IDLE_PARAM \
+ ((1 << PSCI_0_2_POWER_STATE_ID_SHIFT) | \
+ (1 << PSCI_0_2_POWER_STATE_AFFL_SHIFT) | \
+ (PSCI_POWER_STATE_TYPE_POWER_DOWN << PSCI_0_2_POWER_STATE_TYPE_SHIFT))
+
+static int imx6sll_idle_finish(unsigned long val)
+{
+ if (psci_ops.cpu_suspend)
+ psci_ops.cpu_suspend(MX6SLL_POWERDWN_IDLE_PARAM,
+ __pa(cpu_resume));
+ else
+ imx6sll_wfi_in_iram_fn(wfi_iram_base);
+
+ return 0;
+}
+
+static int imx6sll_enter_wait(struct cpuidle_device *dev,
+ struct cpuidle_driver *drv, int index)
+{
+ int mode = get_bus_freq_mode();
+
+ imx6_set_lpm(WAIT_UNCLOCKED);
+ if ((index == 1) || ((mode != BUS_FREQ_LOW) && index == 2)) {
+ index = 1;
+ cpu_do_idle();
+ } else {
+ imx_gpc_switch_pupscr_clk(true);
+ /* Need to notify there is a cpu pm operation. */
+ cpu_pm_enter();
+ cpu_cluster_pm_enter();
+
+ cpu_suspend(0, imx6sll_idle_finish);
+
+ cpu_cluster_pm_exit();
+ cpu_pm_exit();
+ imx6_enable_rbc(false);
+
+ imx_gpc_switch_pupscr_clk(false);
+ }
+
+ imx6_set_lpm(WAIT_CLOCKED);
+
+ return index;
+}
+
+static struct cpuidle_driver imx6sll_cpuidle_driver = {
+ .name = "imx6sll_cpuidle",
+ .owner = THIS_MODULE,
+ .states = {
+ /* WFI */
+ ARM_CPUIDLE_WFI_STATE,
+ /* WAIT */
+ {
+ .exit_latency = 50,
+ .target_residency = 75,
+ .enter = imx6sll_enter_wait,
+ .name = "WAIT",
+ .desc = "Clock off",
+ },
+ /* LOW POWER IDLE */
+ {
+ /*
+ * RBC 130us + ARM gating 43us + RBC clear 65us
+ * + PLL2 relock 450us and some margin, here set
+ * it to 700us.
+ */
+ .exit_latency = 700,
+ .target_residency = 1000,
+ .enter = imx6sll_enter_wait,
+ .name = "LOW-POWER-IDLE",
+ .desc = "ARM power off",
+ }
+ },
+ .state_count = 3,
+ .safe_state_index = 0,
+};
+
+int __init imx6sll_cpuidle_init(void)
+{
+ void __iomem *anatop_base = (void __iomem *)IMX_IO_P2V(MX6Q_ANATOP_BASE_ADDR);
+ u32 val;
+#ifdef CONFIG_CPU_FREQ
+ struct imx6_cpuidle_pm_info *cpuidle_pm_info;
+ int i;
+ const u32 *mmdc_offset_array;
+ u32 wfi_code_size;
+
+ wfi_iram_base_phys = (void *)(iram_tlb_phys_addr + MX6_CPUIDLE_IRAM_ADDR_OFFSET);
+
+ /* Make sure wfi_iram_base is 8 byte aligned. */
+ if ((uintptr_t)(wfi_iram_base_phys) & (FNCPY_ALIGN - 1))
+ wfi_iram_base_phys += FNCPY_ALIGN - ((uintptr_t)wfi_iram_base_phys % (FNCPY_ALIGN));
+
+ wfi_iram_base = (void *)IMX_IO_P2V((unsigned long) wfi_iram_base_phys);
+
+ cpuidle_pm_info = wfi_iram_base;
+ cpuidle_pm_info->pbase = (phys_addr_t) wfi_iram_base_phys;
+ cpuidle_pm_info->pm_info_size = sizeof(*cpuidle_pm_info);
+ cpuidle_pm_info->resume_addr = virt_to_phys(v7_cpu_resume);
+ cpuidle_pm_info->mmdc_io_num = ARRAY_SIZE(imx6sll_mmdc_io_offset);
+ mmdc_offset_array = imx6sll_mmdc_io_offset;
+
+ cpuidle_pm_info->mmdc_base.pbase = MX6Q_MMDC_P0_BASE_ADDR;
+ cpuidle_pm_info->mmdc_base.vbase = (void __iomem *)IMX_IO_P2V(MX6Q_MMDC_P0_BASE_ADDR);
+
+ cpuidle_pm_info->ccm_base.pbase = MX6Q_CCM_BASE_ADDR;
+ cpuidle_pm_info->ccm_base.vbase = (void __iomem *)IMX_IO_P2V(MX6Q_CCM_BASE_ADDR);
+
+ cpuidle_pm_info->anatop_base.pbase = MX6Q_ANATOP_BASE_ADDR;
+ cpuidle_pm_info->anatop_base.vbase = (void __iomem *)IMX_IO_P2V(MX6Q_ANATOP_BASE_ADDR);
+
+ cpuidle_pm_info->gpc_base.pbase = MX6Q_GPC_BASE_ADDR;
+ cpuidle_pm_info->gpc_base.vbase = (void __iomem *)IMX_IO_P2V(MX6Q_GPC_BASE_ADDR);
+
+ cpuidle_pm_info->iomuxc_base.pbase = MX6Q_IOMUXC_BASE_ADDR;
+ cpuidle_pm_info->iomuxc_base.vbase = (void __iomem *)IMX_IO_P2V(MX6Q_IOMUXC_BASE_ADDR);
+
+ cpuidle_pm_info->src_base.pbase = MX6Q_SRC_BASE_ADDR;
+ cpuidle_pm_info->src_base.vbase = (void __iomem *)IMX_IO_P2V(MX6Q_SRC_BASE_ADDR);
+
+ cpuidle_pm_info->l2_base.pbase = MX6Q_L2_BASE_ADDR;
+ cpuidle_pm_info->l2_base.vbase = (void __iomem *)IMX_IO_P2V(MX6Q_L2_BASE_ADDR);
+
+ /* Only save mmdc io offset, settings will be saved in asm code */
+ for (i = 0; i < cpuidle_pm_info->mmdc_io_num; i++)
+ cpuidle_pm_info->mmdc_io_val[i][0] = mmdc_offset_array[i];
+
+ wfi_code_size = (&mx6sll_lpm_wfi_end -&mx6sll_lpm_wfi_start) *4;
+
+ imx6sll_wfi_in_iram_fn = (void *)fncpy(wfi_iram_base + sizeof(*cpuidle_pm_info),
+ &imx6sll_low_power_idle, wfi_code_size);
+#endif
+
+ imx6_set_int_mem_clk_lpm(true);
+
+ /*
+ * enable RC-OSC here, as it needs at least 4ms for RC-OSC to
+ * be stable, low power idle flow can NOT endure this big
+ * latency, so we make RC-OSC self-tuning enabled here.
+ */
+ val = readl_relaxed(anatop_base + PMU_LOW_PWR_CTRL);
+ val |= 0x1;
+ writel_relaxed(val, anatop_base + PMU_LOW_PWR_CTRL);
+ /*
+ * config RC-OSC freq
+ * tune_enable = 1;tune_start = 1;hyst_plus = 0;hyst_minus = 0;
+ * osc_prog = 0xa7;
+ */
+ writel_relaxed(
+ 0x4 << XTALOSC24M_OSC_CONFIG0_RC_OSC_PROG_CUR_SHIFT |
+ 0xa7 << XTALOSC24M_OSC_CONFIG0_RC_OSC_PROG_SHIFT |
+ 0x1 << XTALOSC24M_OSC_CONFIG0_ENABLE_SHIFT |
+ 0x1 << XTALOSC24M_OSC_CONFIG0_START_SHIFT,
+ anatop_base + XTALOSC24M_OSC_CONFIG0);
+ /* set count_trg = 0x2dc */
+ writel_relaxed(
+ 0x40 << XTALOSC24M_OSC_CONFIG1_COUNT_RC_CUR_SHIFT |
+ 0x2dc << XTALOSC24M_OSC_CONFIG1_COUNT_RC_TRG_SHIFT,
+ anatop_base + XTALOSC24M_OSC_CONFIG1);
+ /* wait 4ms according to hardware design */
+ msleep(4);
+ /*
+ * now add some hysteresis, hyst_plus=3, hyst_minus=3
+ * (the minimum hysteresis that looks good is 2)
+ */
+ val = readl_relaxed(anatop_base + XTALOSC24M_OSC_CONFIG0);
+ val &= ~((XTALOSC24M_OSC_CONFIG0_HYST_MINUS_MASK <<
+ XTALOSC24M_OSC_CONFIG0_HYST_MINUS_SHIFT) |
+ (XTALOSC24M_OSC_CONFIG0_HYST_PLUS_MASK <<
+ XTALOSC24M_OSC_CONFIG0_HYST_PLUS_SHIFT));
+ val |= (0x3 << XTALOSC24M_OSC_CONFIG0_HYST_MINUS_SHIFT) |
+ (0x3 << XTALOSC24M_OSC_CONFIG0_HYST_PLUS_SHIFT);
+ writel_relaxed(val, anatop_base + XTALOSC24M_OSC_CONFIG0);
+ /* set the count_1m_trg = 0x2d7 */
+ val = readl_relaxed(anatop_base + XTALOSC24M_OSC_CONFIG2);
+ val &= ~(XTALOSC24M_OSC_CONFIG2_COUNT_1M_TRG_MASK <<
+ XTALOSC24M_OSC_CONFIG2_COUNT_1M_TRG_SHIFT);
+ val |= 0x2d7 << XTALOSC24M_OSC_CONFIG2_COUNT_1M_TRG_SHIFT;
+ writel_relaxed(val, anatop_base + XTALOSC24M_OSC_CONFIG2);
+ /*
+ * hardware design require to write XTALOSC24M_OSC_CONFIG0 or
+ * XTALOSC24M_OSC_CONFIG1 to
+ * make XTALOSC24M_OSC_CONFIG2 write work
+ */
+ val = readl_relaxed(anatop_base + XTALOSC24M_OSC_CONFIG1);
+
+ return cpuidle_register(&imx6sll_cpuidle_driver, NULL);
+}
diff --git a/arch/arm/mach-imx/cpuidle-imx6sx.c b/arch/arm/mach-imx/cpuidle-imx6sx.c
index c6aa77dfd00a..534e47ff037b 100644
--- a/arch/arm/mach-imx/cpuidle-imx6sx.c
+++ b/arch/arm/mach-imx/cpuidle-imx6sx.c
@@ -1,23 +1,100 @@
/*
- * Copyright (C) 2014 Freescale Semiconductor, Inc.
+ * Copyright (C) 2014-2015 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/busfreq-imx.h>
#include <linux/cpuidle.h>
#include <linux/cpu_pm.h>
+#include <linux/delay.h>
+#include <linux/genalloc.h>
+#include <linux/interrupt.h>
#include <linux/module.h>
+#include <linux/psci.h>
#include <asm/cacheflush.h>
#include <asm/cpuidle.h>
+#include <asm/fncpy.h>
+#include <asm/mach/map.h>
+#include <asm/proc-fns.h>
#include <asm/suspend.h>
+#include <asm/tlb.h>
+
+#include <uapi/linux/psci.h>
#include "common.h"
#include "cpuidle.h"
#include "hardware.h"
-static int imx6sx_idle_finish(unsigned long val)
+#define MX6_MAX_MMDC_IO_NUM 19
+
+#define PMU_LOW_PWR_CTRL 0x270
+#define XTALOSC24M_OSC_CONFIG0 0x2a0
+#define XTALOSC24M_OSC_CONFIG1 0x2b0
+#define XTALOSC24M_OSC_CONFIG2 0x2c0
+#define XTALOSC24M_OSC_CONFIG0_RC_OSC_PROG_CUR_SHIFT 24
+#define XTALOSC24M_OSC_CONFIG0_HYST_MINUS_MASK 0xf
+#define XTALOSC24M_OSC_CONFIG0_HYST_MINUS_SHIFT 16
+#define XTALOSC24M_OSC_CONFIG0_HYST_PLUS_MASK 0xf
+#define XTALOSC24M_OSC_CONFIG0_HYST_PLUS_SHIFT 12
+#define XTALOSC24M_OSC_CONFIG0_RC_OSC_PROG_SHIFT 4
+#define XTALOSC24M_OSC_CONFIG0_ENABLE_SHIFT 1
+#define XTALOSC24M_OSC_CONFIG0_START_SHIFT 0
+#define XTALOSC24M_OSC_CONFIG1_COUNT_RC_CUR_SHIFT 20
+#define XTALOSC24M_OSC_CONFIG1_COUNT_RC_TRG_SHIFT 0
+#define XTALOSC24M_OSC_CONFIG2_COUNT_1M_TRG_MASK 0xfff
+#define XTALOSC24M_OSC_CONFIG2_COUNT_1M_TRG_SHIFT 0
+
+extern unsigned long iram_tlb_phys_addr;
+
+static void __iomem *wfi_iram_base;
+#ifdef CONFIG_CPU_FREQ
+static void __iomem *wfi_iram_base_phys;
+extern unsigned long mx6sx_lpm_wfi_start asm("mx6sx_lpm_wfi_start");
+extern unsigned long mx6sx_lpm_wfi_end asm("mx6sx_lpm_wfi_end");
+#endif
+
+struct imx6_pm_base {
+ phys_addr_t pbase;
+ void __iomem *vbase;
+};
+
+static const u32 imx6sx_mmdc_io_offset[] __initconst = {
+ 0x2ec, 0x2f0, 0x2f4, 0x2f8, /* DQM0 ~ DQM3 */
+ 0x330, 0x334, 0x338, 0x33c, /* SDQS0 ~ SDQS3 */
+ 0x60c, 0x610, 0x61c, 0x620, /* B0DS ~ B3DS */
+ 0x5f8, 0x608, 0x310, 0x314, /* CTL, MODE, SODT0, SODT1 */
+ 0x300, 0x2fc, 0x32c, /* CAS, RAS, SDCLK_0 */
+};
+
+struct imx6_cpuidle_pm_info {
+ phys_addr_t pbase; /* The physical address of pm_info. */
+ phys_addr_t resume_addr; /* The physical resume address for asm code */
+ u32 pm_info_size; /* Size of pm_info. */
+ u32 ttbr;
+ struct imx6_pm_base mmdc_base;
+ struct imx6_pm_base iomuxc_base;
+ struct imx6_pm_base ccm_base;
+ struct imx6_pm_base gpc_base;
+ struct imx6_pm_base l2_base;
+ struct imx6_pm_base anatop_base;
+ struct imx6_pm_base src_base;
+ struct imx6_pm_base sema4_base;
+ u32 saved_diagnostic; /* To save disagnostic register */
+ u32 mmdc_io_num; /* Number of MMDC IOs which need saved/restored. */
+ u32 mmdc_io_val[MX6_MAX_MMDC_IO_NUM][2]; /* To save offset and value */
+} __aligned(8);
+
+static void (*imx6sx_wfi_in_iram_fn)(void __iomem *iram_vbase);
+
+#define MX6SX_POWERDWN_IDLE_PARAM \
+ ((1 << PSCI_0_2_POWER_STATE_ID_SHIFT) | \
+ (1 << PSCI_0_2_POWER_STATE_AFFL_SHIFT) | \
+ (PSCI_POWER_STATE_TYPE_POWER_DOWN << PSCI_0_2_POWER_STATE_TYPE_SHIFT))
+
+static int imx6_idle_finish(unsigned long val)
{
/*
* for Cortex-A7 which has an internal L2
@@ -28,7 +105,11 @@ static int imx6sx_idle_finish(unsigned long val)
* just call flush_cache_all() is fine.
*/
flush_cache_all();
- cpu_do_idle();
+ if (psci_ops.cpu_suspend)
+ psci_ops.cpu_suspend(MX6SX_POWERDWN_IDLE_PARAM,
+ __pa(cpu_resume));
+ else
+ imx6sx_wfi_in_iram_fn(wfi_iram_base);
return 0;
}
@@ -36,29 +117,22 @@ static int imx6sx_idle_finish(unsigned long val)
static int imx6sx_enter_wait(struct cpuidle_device *dev,
struct cpuidle_driver *drv, int index)
{
- imx6_set_lpm(WAIT_UNCLOCKED);
+ int mode = get_bus_freq_mode();
- switch (index) {
- case 1:
+ imx6_set_lpm(WAIT_UNCLOCKED);
+ if ((index == 1) || ((mode != BUS_FREQ_LOW) && index == 2)) {
+ index = 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;
+ } else {
+ /* Need to notify there is a cpu pm operation. */
+ cpu_pm_enter();
+ cpu_cluster_pm_enter();
+
+ cpu_suspend(0, imx6_idle_finish);
+
+ cpu_cluster_pm_exit();
+ cpu_pm_exit();
+ imx6_enable_rbc(false);
}
imx6_set_lpm(WAIT_CLOCKED);
@@ -72,24 +146,23 @@ static struct cpuidle_driver imx6sx_cpuidle_driver = {
.states = {
/* WFI */
ARM_CPUIDLE_WFI_STATE,
- /* WAIT */
+ /* WAIT MODE */
{
.exit_latency = 50,
.target_residency = 75,
- .flags = CPUIDLE_FLAG_TIMER_STOP,
.enter = imx6sx_enter_wait,
.name = "WAIT",
.desc = "Clock off",
},
- /* WAIT + ARM power off */
+ /* LOW POWER IDLE */
{
/*
- * ARM gating 31us * 5 + RBC clear 65us
- * and some margin for SW execution, here set it
- * to 300us.
+ * RBC 130us + ARM gating 93us + RBC clear 65us
+ * + PLL2 relock 450us and some margin, here set
+ * it to 800us.
*/
- .exit_latency = 300,
- .target_residency = 500,
+ .exit_latency = 800,
+ .target_residency = 1000,
.enter = imx6sx_enter_wait,
.name = "LOW-POWER-IDLE",
.desc = "ARM power off",
@@ -101,6 +174,64 @@ static struct cpuidle_driver imx6sx_cpuidle_driver = {
int __init imx6sx_cpuidle_init(void)
{
+ void __iomem *anatop_base = (void __iomem *)IMX_IO_P2V(MX6Q_ANATOP_BASE_ADDR);
+ u32 val;
+#ifdef CONFIG_CPU_FREQ
+ struct imx6_cpuidle_pm_info *cpuidle_pm_info;
+ int i;
+ const u32 *mmdc_offset_array;
+ u32 wfi_code_size;
+
+ wfi_iram_base_phys = (void *)(iram_tlb_phys_addr + MX6_CPUIDLE_IRAM_ADDR_OFFSET);
+
+ /* Make sure wfi_iram_base is 8 byte aligned. */
+ if ((uintptr_t)(wfi_iram_base_phys) & (FNCPY_ALIGN - 1))
+ wfi_iram_base_phys += FNCPY_ALIGN - ((uintptr_t)wfi_iram_base_phys % (FNCPY_ALIGN));
+
+ wfi_iram_base = (void *)IMX_IO_P2V((unsigned long) wfi_iram_base_phys);
+
+ cpuidle_pm_info = wfi_iram_base;
+ cpuidle_pm_info->pbase = (phys_addr_t) wfi_iram_base_phys;
+ cpuidle_pm_info->pm_info_size = sizeof(*cpuidle_pm_info);
+ cpuidle_pm_info->resume_addr = virt_to_phys(v7_cpu_resume);
+ cpuidle_pm_info->mmdc_io_num = ARRAY_SIZE(imx6sx_mmdc_io_offset);
+ mmdc_offset_array = imx6sx_mmdc_io_offset;
+
+ cpuidle_pm_info->mmdc_base.pbase = MX6Q_MMDC_P0_BASE_ADDR;
+ cpuidle_pm_info->mmdc_base.vbase = (void __iomem *)IMX_IO_P2V(MX6Q_MMDC_P0_BASE_ADDR);
+
+ cpuidle_pm_info->ccm_base.pbase = MX6Q_CCM_BASE_ADDR;
+ cpuidle_pm_info->ccm_base.vbase = (void __iomem *)IMX_IO_P2V(MX6Q_CCM_BASE_ADDR);
+
+ cpuidle_pm_info->anatop_base.pbase = MX6Q_ANATOP_BASE_ADDR;
+ cpuidle_pm_info->anatop_base.vbase = (void __iomem *)IMX_IO_P2V(MX6Q_ANATOP_BASE_ADDR);
+
+ cpuidle_pm_info->gpc_base.pbase = MX6Q_GPC_BASE_ADDR;
+ cpuidle_pm_info->gpc_base.vbase = (void __iomem *)IMX_IO_P2V(MX6Q_GPC_BASE_ADDR);
+
+ cpuidle_pm_info->iomuxc_base.pbase = MX6Q_IOMUXC_BASE_ADDR;
+ cpuidle_pm_info->iomuxc_base.vbase = (void __iomem *)IMX_IO_P2V(MX6Q_IOMUXC_BASE_ADDR);
+
+ cpuidle_pm_info->l2_base.pbase = MX6Q_L2_BASE_ADDR;
+ cpuidle_pm_info->l2_base.vbase = (void __iomem *)IMX_IO_P2V(MX6Q_L2_BASE_ADDR);
+
+ cpuidle_pm_info->src_base.pbase = MX6Q_SRC_BASE_ADDR;
+ cpuidle_pm_info->src_base.vbase = (void __iomem *)IMX_IO_P2V(MX6Q_SRC_BASE_ADDR);
+
+ cpuidle_pm_info->sema4_base.pbase = MX6Q_SEMA4_BASE_ADDR;
+ cpuidle_pm_info->sema4_base.vbase =
+ (void __iomem *)IMX_IO_P2V(MX6Q_SEMA4_BASE_ADDR);
+
+ /* only save mmdc io offset, settings will be saved in asm code */
+ for (i = 0; i < cpuidle_pm_info->mmdc_io_num; i++)
+ cpuidle_pm_info->mmdc_io_val[i][0] = mmdc_offset_array[i];
+
+ /* code size should include cpuidle_pm_info size */
+ wfi_code_size = (&mx6sx_lpm_wfi_end -&mx6sx_lpm_wfi_start) *4 + sizeof(*cpuidle_pm_info);
+ imx6sx_wfi_in_iram_fn = (void *)fncpy(wfi_iram_base + sizeof(*cpuidle_pm_info),
+ &imx6sx_low_power_idle, wfi_code_size);
+#endif
+
imx6_set_int_mem_clk_lpm(true);
imx6_enable_rbc(false);
/*
@@ -109,8 +240,62 @@ int __init imx6sx_cpuidle_init(void)
* except for power up sw2iso which need to be
* larger than LDO ramp up time.
*/
- imx_gpc_set_arm_power_up_timing(cpu_is_imx6sx() ? 0xf : 0x2, 1);
+ imx_gpc_set_arm_power_up_timing(0xf, 1);
imx_gpc_set_arm_power_down_timing(1, 1);
+ if (imx_get_soc_revision() >= IMX_CHIP_REVISION_1_2) {
+ /*
+ * enable RC-OSC here, as it needs at least 4ms for RC-OSC to
+ * be stable, low power idle flow can NOT endure this big
+ * latency, so we make RC-OSC self-tuning enabled here.
+ */
+ val = readl_relaxed(anatop_base + PMU_LOW_PWR_CTRL);
+ val |= 0x1;
+ writel_relaxed(val, anatop_base + PMU_LOW_PWR_CTRL);
+ /*
+ * config RC-OSC freq
+ * tune_enable = 1;tune_start = 1;hyst_plus = 0;hyst_minus = 0;
+ * osc_prog = 0xa7;
+ */
+ writel_relaxed(
+ 0x4 << XTALOSC24M_OSC_CONFIG0_RC_OSC_PROG_CUR_SHIFT |
+ 0xa7 << XTALOSC24M_OSC_CONFIG0_RC_OSC_PROG_SHIFT |
+ 0x1 << XTALOSC24M_OSC_CONFIG0_ENABLE_SHIFT |
+ 0x1 << XTALOSC24M_OSC_CONFIG0_START_SHIFT,
+ anatop_base + XTALOSC24M_OSC_CONFIG0);
+ /* set count_trg = 0x2dc */
+ writel_relaxed(
+ 0x40 << XTALOSC24M_OSC_CONFIG1_COUNT_RC_CUR_SHIFT |
+ 0x2dc << XTALOSC24M_OSC_CONFIG1_COUNT_RC_TRG_SHIFT,
+ anatop_base + XTALOSC24M_OSC_CONFIG1);
+ /* wait 4ms according to hardware design */
+ msleep(4);
+ /*
+ * now add some hysteresis, hyst_plus=3, hyst_minus=3
+ * (the minimum hysteresis that looks good is 2)
+ */
+ val = readl_relaxed(anatop_base + XTALOSC24M_OSC_CONFIG0);
+ val &= ~((XTALOSC24M_OSC_CONFIG0_HYST_MINUS_MASK <<
+ XTALOSC24M_OSC_CONFIG0_HYST_MINUS_SHIFT) |
+ (XTALOSC24M_OSC_CONFIG0_HYST_PLUS_MASK <<
+ XTALOSC24M_OSC_CONFIG0_HYST_PLUS_SHIFT));
+ val |= (0x3 << XTALOSC24M_OSC_CONFIG0_HYST_MINUS_SHIFT) |
+ (0x3 << XTALOSC24M_OSC_CONFIG0_HYST_PLUS_SHIFT);
+ writel_relaxed(val, anatop_base + XTALOSC24M_OSC_CONFIG0);
+ /* set the count_1m_trg = 0x2d7 */
+ val = readl_relaxed(anatop_base + XTALOSC24M_OSC_CONFIG2);
+ val &= ~(XTALOSC24M_OSC_CONFIG2_COUNT_1M_TRG_MASK <<
+ XTALOSC24M_OSC_CONFIG2_COUNT_1M_TRG_SHIFT);
+ val |= 0x2d7 << XTALOSC24M_OSC_CONFIG2_COUNT_1M_TRG_SHIFT;
+ writel_relaxed(val, anatop_base + XTALOSC24M_OSC_CONFIG2);
+ /*
+ * hardware design require to write XTALOSC24M_OSC_CONFIG0 or
+ * XTALOSC24M_OSC_CONFIG1 to
+ * make XTALOSC24M_OSC_CONFIG2 write work
+ */
+ val = readl_relaxed(anatop_base + XTALOSC24M_OSC_CONFIG1);
+ writel_relaxed(val, anatop_base + XTALOSC24M_OSC_CONFIG1);
+ }
+
return cpuidle_register(&imx6sx_cpuidle_driver, NULL);
}
diff --git a/arch/arm/mach-imx/cpuidle-imx6ul.c b/arch/arm/mach-imx/cpuidle-imx6ul.c
new file mode 100644
index 000000000000..4f22b8f0d02b
--- /dev/null
+++ b/arch/arm/mach-imx/cpuidle-imx6ul.c
@@ -0,0 +1,327 @@
+/*
+ * Copyright (C) 2015-2016 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/busfreq-imx.h>
+#include <linux/cpuidle.h>
+#include <linux/cpu_pm.h>
+#include <linux/delay.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/psci.h>
+#include <linux/regulator/consumer.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/machine.h>
+#include <asm/cpuidle.h>
+#include <asm/fncpy.h>
+#include <asm/proc-fns.h>
+#include <asm/suspend.h>
+
+#include <uapi/linux/psci.h>
+
+#include "common.h"
+#include "cpuidle.h"
+#include "hardware.h"
+
+#define MAX_MMDC_IO_NUM 14
+
+#define PMU_LOW_PWR_CTRL 0x270
+#define XTALOSC24M_OSC_CONFIG0 0x2a0
+#define XTALOSC24M_OSC_CONFIG1 0x2b0
+#define XTALOSC24M_OSC_CONFIG2 0x2c0
+#define XTALOSC24M_OSC_CONFIG0_RC_OSC_PROG_CUR_SHIFT 24
+#define XTALOSC24M_OSC_CONFIG0_HYST_MINUS_MASK 0xf
+#define XTALOSC24M_OSC_CONFIG0_HYST_MINUS_SHIFT 16
+#define XTALOSC24M_OSC_CONFIG0_HYST_PLUS_MASK 0xf
+#define XTALOSC24M_OSC_CONFIG0_HYST_PLUS_SHIFT 12
+#define XTALOSC24M_OSC_CONFIG0_RC_OSC_PROG_SHIFT 4
+#define XTALOSC24M_OSC_CONFIG0_ENABLE_SHIFT 1
+#define XTALOSC24M_OSC_CONFIG0_START_SHIFT 0
+#define XTALOSC24M_OSC_CONFIG1_COUNT_RC_CUR_SHIFT 20
+#define XTALOSC24M_OSC_CONFIG1_COUNT_RC_TRG_SHIFT 0
+#define XTALOSC24M_OSC_CONFIG2_COUNT_1M_TRG_MASK 0xfff
+#define XTALOSC24M_OSC_CONFIG2_COUNT_1M_TRG_SHIFT 0
+
+extern unsigned long iram_tlb_phys_addr;
+static void __iomem *wfi_iram_base;
+
+#ifdef CONFIG_CPU_FREQ
+static void __iomem *wfi_iram_base_phys;
+extern unsigned long mx6ul_lpm_wfi_start asm("mx6ul_lpm_wfi_start");
+extern unsigned long mx6ul_lpm_wfi_end asm("mx6ul_lpm_wfi_end");
+extern unsigned long mx6ull_lpm_wfi_start asm("mx6ull_lpm_wfi_start");
+extern unsigned long mx6ull_lpm_wfi_end asm("mx6ull_lpm_wfi_end");
+#endif
+
+struct imx6_pm_base {
+ phys_addr_t pbase;
+ void __iomem *vbase;
+};
+
+struct imx6_cpuidle_pm_info {
+ phys_addr_t pbase; /* The physical address of pm_info. */
+ phys_addr_t resume_addr; /* The physical resume address for asm code */
+ u32 pm_info_size; /* Size of pm_info. */
+ u32 ttbr;
+ struct imx6_pm_base mmdc_base;
+ struct imx6_pm_base iomuxc_base;
+ struct imx6_pm_base ccm_base;
+ struct imx6_pm_base gpc_base;
+ struct imx6_pm_base anatop_base;
+ struct imx6_pm_base src_base;
+ u32 mmdc_io_num; /* Number of MMDC IOs which need saved/restored. */
+ u32 mmdc_io_val[MAX_MMDC_IO_NUM][2]; /* To save offset and value */
+} __aligned(8);
+
+static const u32 imx6ul_mmdc_io_offset[] __initconst = {
+ 0x244, 0x248, 0x24c, 0x250, /* DQM0, DQM1, RAS, CAS */
+ 0x27c, 0x498, 0x4a4, 0x490, /* SDCLK0, GPR_B0DS-B1DS, GPR_ADDS */
+ 0x280, 0x284, 0x260, 0x264, /* SDQS0~1, SODT0, SODT1 */
+ 0x494, 0x4b0, /* MODE_CTL, MODE, */
+};
+
+static void (*imx6ul_wfi_in_iram_fn)(void __iomem *iram_vbase);
+
+#define MX6UL_POWERDWN_IDLE_PARAM \
+ ((1 << PSCI_0_2_POWER_STATE_ID_SHIFT) | \
+ (1 << PSCI_0_2_POWER_STATE_AFFL_SHIFT) | \
+ (PSCI_POWER_STATE_TYPE_POWER_DOWN << PSCI_0_2_POWER_STATE_TYPE_SHIFT))
+
+static int imx6ul_idle_finish(unsigned long val)
+{
+ if (psci_ops.cpu_suspend)
+ psci_ops.cpu_suspend(MX6UL_POWERDWN_IDLE_PARAM,
+ __pa(cpu_resume));
+ else
+ imx6ul_wfi_in_iram_fn(wfi_iram_base);
+
+ return 0;
+}
+
+static int imx6ul_enter_wait(struct cpuidle_device *dev,
+ struct cpuidle_driver *drv, int index)
+{
+ int mode = get_bus_freq_mode();
+
+ imx6_set_lpm(WAIT_UNCLOCKED);
+ if ((index == 1) || ((mode != BUS_FREQ_LOW) && index == 2)) {
+ cpu_do_idle();
+ index = 1;
+ } else {
+ /*
+ * i.MX6UL TO1.0 ARM power up uses IPG/2048 as clock source,
+ * from TO1.1, PGC_CPU_PUPSCR bit [5] is re-defined to switch
+ * clock to IPG/32, enable this bit to speed up the ARM power
+ * up process in low power idle case.
+ */
+ if (cpu_is_imx6ul() && imx_get_soc_revision() >
+ IMX_CHIP_REVISION_1_0)
+ imx_gpc_switch_pupscr_clk(true);
+ /* Need to notify there is a cpu pm operation. */
+ cpu_pm_enter();
+ cpu_cluster_pm_enter();
+
+ cpu_suspend(0, imx6ul_idle_finish);
+
+ cpu_cluster_pm_exit();
+ cpu_pm_exit();
+ imx6_enable_rbc(false);
+
+ if (cpu_is_imx6ul() && imx_get_soc_revision() >
+ IMX_CHIP_REVISION_1_0)
+ imx_gpc_switch_pupscr_clk(false);
+ }
+
+ imx6_set_lpm(WAIT_CLOCKED);
+
+ return index;
+}
+
+static struct cpuidle_driver imx6ul_cpuidle_driver_v2 = {
+ .name = "imx6ul_cpuidle",
+ .owner = THIS_MODULE,
+ .states = {
+ /* WFI */
+ ARM_CPUIDLE_WFI_STATE,
+ /* WAIT */
+ {
+ .exit_latency = 50,
+ .target_residency = 75,
+ .enter = imx6ul_enter_wait,
+ .name = "WAIT",
+ .desc = "Clock off",
+ },
+ /* LOW POWER IDLE */
+ {
+ /*
+ * RBC 130us + ARM gating 43us + RBC clear 65us
+ * + PLL2 relock 450us and some margin, here set
+ * it to 700us.
+ */
+ .exit_latency = 700,
+ .target_residency = 1000,
+ .enter = imx6ul_enter_wait,
+ .name = "LOW-POWER-IDLE",
+ .desc = "ARM power off",
+ }
+ },
+ .state_count = 3,
+ .safe_state_index = 0,
+};
+
+static struct cpuidle_driver imx6ul_cpuidle_driver = {
+ .name = "imx6ul_cpuidle",
+ .owner = THIS_MODULE,
+ .states = {
+ /* WFI */
+ ARM_CPUIDLE_WFI_STATE,
+ /* WAIT */
+ {
+ .exit_latency = 50,
+ .target_residency = 75,
+ .enter = imx6ul_enter_wait,
+ .name = "WAIT",
+ .desc = "Clock off",
+ },
+ /* LOW POWER IDLE */
+ {
+ /*
+ * RBC 130us + ARM gating 1370us + RBC clear 65us
+ * + PLL2 relock 450us and some margin, here set
+ * it to 2100us.
+ */
+ .exit_latency = 2100,
+ .target_residency = 2500,
+ .enter = imx6ul_enter_wait,
+ .name = "LOW-POWER-IDLE",
+ .desc = "ARM power off",
+ }
+ },
+ .state_count = 3,
+ .safe_state_index = 0,
+};
+
+int __init imx6ul_cpuidle_init(void)
+{
+ void __iomem *anatop_base = (void __iomem *)IMX_IO_P2V(MX6Q_ANATOP_BASE_ADDR);
+ u32 val;
+#ifdef CONFIG_CPU_FREQ
+ struct imx6_cpuidle_pm_info *cpuidle_pm_info;
+ int i;
+ const u32 *mmdc_offset_array;
+ u32 wfi_code_size;
+
+ wfi_iram_base_phys = (void *)(iram_tlb_phys_addr + MX6_CPUIDLE_IRAM_ADDR_OFFSET);
+
+ /* Make sure wfi_iram_base is 8 byte aligned. */
+ if ((uintptr_t)(wfi_iram_base_phys) & (FNCPY_ALIGN - 1))
+ wfi_iram_base_phys += FNCPY_ALIGN - ((uintptr_t)wfi_iram_base_phys % (FNCPY_ALIGN));
+
+ wfi_iram_base = (void *)IMX_IO_P2V((unsigned long) wfi_iram_base_phys);
+
+ cpuidle_pm_info = wfi_iram_base;
+ cpuidle_pm_info->pbase = (phys_addr_t) wfi_iram_base_phys;
+ cpuidle_pm_info->pm_info_size = sizeof(*cpuidle_pm_info);
+ cpuidle_pm_info->resume_addr = virt_to_phys(v7_cpu_resume);
+ cpuidle_pm_info->mmdc_io_num = ARRAY_SIZE(imx6ul_mmdc_io_offset);
+ mmdc_offset_array = imx6ul_mmdc_io_offset;
+
+ cpuidle_pm_info->mmdc_base.pbase = MX6Q_MMDC_P0_BASE_ADDR;
+ cpuidle_pm_info->mmdc_base.vbase = (void __iomem *)IMX_IO_P2V(MX6Q_MMDC_P0_BASE_ADDR);
+
+ cpuidle_pm_info->ccm_base.pbase = MX6Q_CCM_BASE_ADDR;
+ cpuidle_pm_info->ccm_base.vbase = (void __iomem *)IMX_IO_P2V(MX6Q_CCM_BASE_ADDR);
+
+ cpuidle_pm_info->anatop_base.pbase = MX6Q_ANATOP_BASE_ADDR;
+ cpuidle_pm_info->anatop_base.vbase = (void __iomem *)IMX_IO_P2V(MX6Q_ANATOP_BASE_ADDR);
+
+ cpuidle_pm_info->gpc_base.pbase = MX6Q_GPC_BASE_ADDR;
+ cpuidle_pm_info->gpc_base.vbase = (void __iomem *)IMX_IO_P2V(MX6Q_GPC_BASE_ADDR);
+
+ cpuidle_pm_info->iomuxc_base.pbase = MX6Q_IOMUXC_BASE_ADDR;
+ cpuidle_pm_info->iomuxc_base.vbase = (void __iomem *)IMX_IO_P2V(MX6Q_IOMUXC_BASE_ADDR);
+
+ cpuidle_pm_info->src_base.pbase = MX6Q_SRC_BASE_ADDR;
+ cpuidle_pm_info->src_base.vbase = (void __iomem *)IMX_IO_P2V(MX6Q_SRC_BASE_ADDR);
+
+ /* Only save mmdc io offset, settings will be saved in asm code */
+ for (i = 0; i < cpuidle_pm_info->mmdc_io_num; i++)
+ cpuidle_pm_info->mmdc_io_val[i][0] = mmdc_offset_array[i];
+
+ /* calculate the wfi code size */
+ if (cpu_is_imx6ul()) {
+ wfi_code_size = (&mx6ul_lpm_wfi_end -&mx6ul_lpm_wfi_start) *4;
+
+ imx6ul_wfi_in_iram_fn = (void *)fncpy(wfi_iram_base + sizeof(*cpuidle_pm_info),
+ &imx6ul_low_power_idle, wfi_code_size);
+ } else {
+ wfi_code_size = (&mx6ull_lpm_wfi_end -&mx6ull_lpm_wfi_start) *4;
+
+ imx6ul_wfi_in_iram_fn = (void *)fncpy(wfi_iram_base + sizeof(*cpuidle_pm_info),
+ &imx6ull_low_power_idle, wfi_code_size);
+ }
+#endif
+
+ imx6_set_int_mem_clk_lpm(true);
+
+ /*
+ * enable RC-OSC here, as it needs at least 4ms for RC-OSC to
+ * be stable, low power idle flow can NOT endure this big
+ * latency, so we make RC-OSC self-tuning enabled here.
+ */
+ val = readl_relaxed(anatop_base + PMU_LOW_PWR_CTRL);
+ val |= 0x1;
+ writel_relaxed(val, anatop_base + PMU_LOW_PWR_CTRL);
+ /*
+ * config RC-OSC freq
+ * tune_enable = 1;tune_start = 1;hyst_plus = 0;hyst_minus = 0;
+ * osc_prog = 0xa7;
+ */
+ writel_relaxed(
+ 0x4 << XTALOSC24M_OSC_CONFIG0_RC_OSC_PROG_CUR_SHIFT |
+ 0xa7 << XTALOSC24M_OSC_CONFIG0_RC_OSC_PROG_SHIFT |
+ 0x1 << XTALOSC24M_OSC_CONFIG0_ENABLE_SHIFT |
+ 0x1 << XTALOSC24M_OSC_CONFIG0_START_SHIFT,
+ anatop_base + XTALOSC24M_OSC_CONFIG0);
+ /* set count_trg = 0x2dc */
+ writel_relaxed(
+ 0x40 << XTALOSC24M_OSC_CONFIG1_COUNT_RC_CUR_SHIFT |
+ 0x2dc << XTALOSC24M_OSC_CONFIG1_COUNT_RC_TRG_SHIFT,
+ anatop_base + XTALOSC24M_OSC_CONFIG1);
+ /* wait 4ms according to hardware design */
+ msleep(4);
+ /*
+ * now add some hysteresis, hyst_plus=3, hyst_minus=3
+ * (the minimum hysteresis that looks good is 2)
+ */
+ val = readl_relaxed(anatop_base + XTALOSC24M_OSC_CONFIG0);
+ val &= ~((XTALOSC24M_OSC_CONFIG0_HYST_MINUS_MASK <<
+ XTALOSC24M_OSC_CONFIG0_HYST_MINUS_SHIFT) |
+ (XTALOSC24M_OSC_CONFIG0_HYST_PLUS_MASK <<
+ XTALOSC24M_OSC_CONFIG0_HYST_PLUS_SHIFT));
+ val |= (0x3 << XTALOSC24M_OSC_CONFIG0_HYST_MINUS_SHIFT) |
+ (0x3 << XTALOSC24M_OSC_CONFIG0_HYST_PLUS_SHIFT);
+ writel_relaxed(val, anatop_base + XTALOSC24M_OSC_CONFIG0);
+ /* set the count_1m_trg = 0x2d7 */
+ val = readl_relaxed(anatop_base + XTALOSC24M_OSC_CONFIG2);
+ val &= ~(XTALOSC24M_OSC_CONFIG2_COUNT_1M_TRG_MASK <<
+ XTALOSC24M_OSC_CONFIG2_COUNT_1M_TRG_SHIFT);
+ val |= 0x2d7 << XTALOSC24M_OSC_CONFIG2_COUNT_1M_TRG_SHIFT;
+ writel_relaxed(val, anatop_base + XTALOSC24M_OSC_CONFIG2);
+ /*
+ * hardware design require to write XTALOSC24M_OSC_CONFIG0 or
+ * XTALOSC24M_OSC_CONFIG1 to
+ * make XTALOSC24M_OSC_CONFIG2 write work
+ */
+ val = readl_relaxed(anatop_base + XTALOSC24M_OSC_CONFIG1);
+
+ /* ARM power up time is reduced since TO1.1 */
+ if (imx_get_soc_revision() > IMX_CHIP_REVISION_1_0)
+ return cpuidle_register(&imx6ul_cpuidle_driver_v2, NULL);
+ else
+ return cpuidle_register(&imx6ul_cpuidle_driver, NULL);
+}
diff --git a/arch/arm/mach-imx/cpuidle-imx7d.c b/arch/arm/mach-imx/cpuidle-imx7d.c
new file mode 100644
index 000000000000..8e1e61c5503b
--- /dev/null
+++ b/arch/arm/mach-imx/cpuidle-imx7d.c
@@ -0,0 +1,390 @@
+/*
+ * Copyright (C) 2015 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/busfreq-imx.h>
+#include <linux/cpuidle.h>
+#include <linux/cpu_pm.h>
+#include <linux/delay.h>
+#include <linux/genalloc.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/psci.h>
+#include <asm/cp15.h>
+#include <asm/cpuidle.h>
+#include <asm/fncpy.h>
+#include <asm/mach/map.h>
+#include <asm/proc-fns.h>
+#include <asm/suspend.h>
+#include <asm/tlb.h>
+
+#include <uapi/linux/psci.h>
+
+#include "common.h"
+#include "cpuidle.h"
+#include "hardware.h"
+
+#define XTALOSC24M_OSC_CONFIG0 0x10
+#define XTALOSC24M_OSC_CONFIG1 0x20
+#define XTALOSC24M_OSC_CONFIG2 0x30
+#define XTALOSC24M_OSC_CONFIG0_RC_OSC_PROG_CUR_SHIFT 24
+#define XTALOSC24M_OSC_CONFIG0_HYST_MINUS_MASK 0xf
+#define XTALOSC24M_OSC_CONFIG0_HYST_MINUS_SHIFT 16
+#define XTALOSC24M_OSC_CONFIG0_HYST_PLUS_MASK 0xf
+#define XTALOSC24M_OSC_CONFIG0_HYST_PLUS_SHIFT 12
+#define XTALOSC24M_OSC_CONFIG0_RC_OSC_PROG_SHIFT 4
+#define XTALOSC24M_OSC_CONFIG0_ENABLE_SHIFT 1
+#define XTALOSC24M_OSC_CONFIG0_START_SHIFT 0
+#define XTALOSC24M_OSC_CONFIG1_COUNT_RC_CUR_SHIFT 20
+#define XTALOSC24M_OSC_CONFIG1_COUNT_RC_TRG_SHIFT 0
+#define XTALOSC24M_OSC_CONFIG2_COUNT_1M_TRG_MASK 0xfff
+#define XTALOSC24M_OSC_CONFIG2_COUNT_1M_TRG_SHIFT 0
+
+#define XTALOSC_CTRL_24M 0x0
+#define XTALOSC_CTRL_24M_RC_OSC_EN_SHIFT 13
+#define REG_SET 0x4
+
+static void __iomem *wfi_iram_base;
+static void __iomem *wfi_iram_base_phys;
+extern unsigned long iram_tlb_phys_addr;
+
+struct imx7_pm_base {
+ phys_addr_t pbase;
+ void __iomem *vbase;
+};
+
+struct imx7_cpuidle_pm_info {
+ phys_addr_t vbase; /* The virtual address of pm_info. */
+ phys_addr_t pbase; /* The physical address of pm_info. */
+ phys_addr_t resume_addr; /* The physical resume address for asm code */
+ u32 pm_info_size;
+ u32 ttbr;
+ u32 num_online_cpus;
+ u32 num_lpi_cpus;
+ atomic_t val;
+ atomic_t flag0;
+ atomic_t flag1;
+ struct imx7_pm_base ddrc_base;
+ struct imx7_pm_base ccm_base;
+ struct imx7_pm_base anatop_base;
+ struct imx7_pm_base src_base;
+ struct imx7_pm_base iomuxc_gpr_base;
+ struct imx7_pm_base gpc_base;
+ struct imx7_pm_base gic_dist_base;
+} __aligned(8);
+
+static atomic_t master_lpi = ATOMIC_INIT(0);
+static atomic_t master_wait = ATOMIC_INIT(0);
+
+static void (*imx7d_wfi_in_iram_fn)(void __iomem *iram_vbase);
+static struct imx7_cpuidle_pm_info *cpuidle_pm_info;
+
+#define MX7D_POWERDWN_IDLE_PARAM \
+ ((1 << PSCI_0_2_POWER_STATE_ID_SHIFT) | \
+ (1 << PSCI_0_2_POWER_STATE_AFFL_SHIFT) | \
+ (PSCI_POWER_STATE_TYPE_POWER_DOWN << PSCI_0_2_POWER_STATE_TYPE_SHIFT))
+
+#define MX7D_STANDBY_IDLE_PARAM \
+ ((1 << PSCI_0_2_POWER_STATE_ID_SHIFT) | \
+ (1 << PSCI_0_2_POWER_STATE_AFFL_SHIFT) | \
+ (PSCI_POWER_STATE_TYPE_STANDBY << PSCI_0_2_POWER_STATE_TYPE_SHIFT))
+
+/* Mapped for the kernel, unlike cpuidle_pm_info->gic_dist_base.vbase */
+static void __iomem *imx7d_cpuidle_gic_base;
+
+static void imx_pen_lock(int cpu)
+{
+ if (cpu == 0) {
+ atomic_set(&cpuidle_pm_info->flag0, 1);
+ dsb();
+ atomic_set(&cpuidle_pm_info->val, cpu);
+ do {
+ dsb();
+ } while (atomic_read(&cpuidle_pm_info->flag1) == 1
+ && atomic_read(&cpuidle_pm_info->val) == cpu)
+ ;
+ } else {
+ atomic_set(&cpuidle_pm_info->flag1, 1);
+ dsb();
+ atomic_set(&cpuidle_pm_info->val, cpu);
+ do {
+ dsb();
+ } while (atomic_read(&cpuidle_pm_info->flag0) == 1
+ && atomic_read(&cpuidle_pm_info->val) == cpu)
+ ;
+ }
+}
+
+static void imx_pen_unlock(int cpu)
+{
+ dsb();
+ if (cpu == 0)
+ atomic_set(&cpuidle_pm_info->flag0, 0);
+ else
+ atomic_set(&cpuidle_pm_info->flag1, 0);
+}
+
+static int imx7d_idle_finish(unsigned long val)
+{
+ if (psci_ops.cpu_suspend)
+ psci_ops.cpu_suspend(MX7D_POWERDWN_IDLE_PARAM, __pa(cpu_resume));
+ else
+ imx7d_wfi_in_iram_fn(wfi_iram_base);
+
+ return 0;
+}
+
+static bool imx7d_gic_sgis_pending(void)
+{
+ void __iomem *sgip_base = imx7d_cpuidle_gic_base + 0x1f20;
+
+ return (readl_relaxed(sgip_base + 0x0) |
+ readl_relaxed(sgip_base + 0x4) |
+ readl_relaxed(sgip_base + 0x8) |
+ readl_relaxed(sgip_base + 0xc));
+}
+
+static DEFINE_SPINLOCK(psci_lock);
+static int imx7d_enter_low_power_idle(struct cpuidle_device *dev,
+ struct cpuidle_driver *drv, int index)
+{
+ int mode = get_bus_freq_mode();
+
+
+ if ((index == 1) || ((mode != BUS_FREQ_LOW) && index == 2)) {
+ index = 1;
+ if (atomic_inc_return(&master_wait) == num_online_cpus())
+ imx_gpcv2_set_lpm_mode(WAIT_UNCLOCKED);
+
+ cpu_do_idle();
+
+ atomic_dec(&master_wait);
+ imx_gpcv2_set_lpm_mode(WAIT_CLOCKED);
+ } else {
+ if (psci_ops.cpu_suspend) {
+ cpu_pm_enter();
+ spin_lock(&psci_lock);
+ if (atomic_inc_return(&master_lpi) == num_online_cpus()) {
+ if (imx7d_gic_sgis_pending()) {
+ atomic_dec(&master_lpi);
+ index = -1;
+ goto psci_skip_lpi_flow;
+ }
+
+ imx_gpcv2_set_lpm_mode(WAIT_UNCLOCKED);
+ imx_gpcv2_set_cpu_power_gate_in_idle(true);
+
+ cpu_cluster_pm_enter();
+ }
+ spin_unlock(&psci_lock);
+
+ cpu_suspend(0, imx7d_idle_finish);
+
+ spin_lock(&psci_lock);
+ if (atomic_read(&master_lpi) == num_online_cpus()) {
+ cpu_cluster_pm_exit();
+ imx_gpcv2_set_cpu_power_gate_in_idle(false);
+ imx_gpcv2_set_lpm_mode(WAIT_CLOCKED);
+ }
+
+ atomic_dec(&master_lpi);
+psci_skip_lpi_flow:
+ spin_unlock(&psci_lock);
+ cpu_pm_exit();
+ } else {
+ imx_pen_lock(dev->cpu);
+ cpuidle_pm_info->num_online_cpus = num_online_cpus();
+ ++cpuidle_pm_info->num_lpi_cpus;
+ cpu_pm_enter();
+ if (cpuidle_pm_info->num_lpi_cpus ==
+ cpuidle_pm_info->num_online_cpus) {
+ /*
+ * GPC will not wake on SGIs so check for them
+ * manually here. At this point we know the other cpu
+ * is in wfi or waiting for the lock and can't send
+ * any additional IPIs.
+ */
+ if (imx7d_gic_sgis_pending()) {
+ index = -1;
+ goto skip_lpi_flow;
+ }
+ imx_gpcv2_set_lpm_mode(WAIT_UNCLOCKED);
+ imx_gpcv2_set_cpu_power_gate_in_idle(true);
+ cpu_cluster_pm_enter();
+ } else {
+ imx_set_cpu_jump(dev->cpu, ca7_cpu_resume);
+ }
+
+ cpu_suspend(0, imx7d_idle_finish);
+
+ if (cpuidle_pm_info->num_lpi_cpus ==
+ cpuidle_pm_info->num_online_cpus) {
+ cpu_cluster_pm_exit();
+ imx_gpcv2_set_cpu_power_gate_in_idle(false);
+ imx_gpcv2_set_lpm_mode(WAIT_CLOCKED);
+ }
+
+skip_lpi_flow:
+ cpu_pm_exit();
+ --cpuidle_pm_info->num_lpi_cpus;
+ imx_pen_unlock(dev->cpu);
+ }
+ }
+
+ return index;
+}
+
+static struct cpuidle_driver imx7d_cpuidle_driver = {
+ .name = "imx7d_cpuidle",
+ .owner = THIS_MODULE,
+ .states = {
+ /* WFI */
+ ARM_CPUIDLE_WFI_STATE,
+ /* WAIT MODE */
+ {
+ .exit_latency = 50,
+ .target_residency = 75,
+ .flags = CPUIDLE_FLAG_TIMER_STOP,
+ .enter = imx7d_enter_low_power_idle,
+ .name = "WAIT",
+ .desc = "Clock off",
+ },
+ /* LOW POWER IDLE */
+ {
+ .exit_latency = 10000,
+ .target_residency = 20000,
+ .flags = CPUIDLE_FLAG_TIMER_STOP,
+ .enter = imx7d_enter_low_power_idle,
+ .name = "LOW-POWER-IDLE",
+ .desc = "ARM power off",
+ },
+ },
+ .state_count = 3,
+ .safe_state_index = 0,
+};
+
+int imx7d_enable_rcosc(void)
+{
+ void __iomem *anatop_base =
+ (void __iomem *)IMX_IO_P2V(MX7D_ANATOP_BASE_ADDR);
+ u32 val;
+
+ imx_gpcv2_set_lpm_mode(WAIT_CLOCKED);
+ /* set RC-OSC freq and turn it on */
+ writel_relaxed(0x1 << XTALOSC_CTRL_24M_RC_OSC_EN_SHIFT,
+ anatop_base + XTALOSC_CTRL_24M + REG_SET);
+ /*
+ * config RC-OSC freq
+ * tune_enable = 1;tune_start = 1;hyst_plus = 0;hyst_minus = 0;
+ * osc_prog = 0xa7;
+ */
+ writel_relaxed(
+ 0x4 << XTALOSC24M_OSC_CONFIG0_RC_OSC_PROG_CUR_SHIFT |
+ 0xa7 << XTALOSC24M_OSC_CONFIG0_RC_OSC_PROG_SHIFT |
+ 0x1 << XTALOSC24M_OSC_CONFIG0_ENABLE_SHIFT |
+ 0x1 << XTALOSC24M_OSC_CONFIG0_START_SHIFT,
+ anatop_base + XTALOSC24M_OSC_CONFIG0);
+ /* set count_trg = 0x2dc */
+ writel_relaxed(
+ 0x40 << XTALOSC24M_OSC_CONFIG1_COUNT_RC_CUR_SHIFT |
+ 0x2dc << XTALOSC24M_OSC_CONFIG1_COUNT_RC_TRG_SHIFT,
+ anatop_base + XTALOSC24M_OSC_CONFIG1);
+ /* wait at least 4ms according to hardware design */
+ mdelay(6);
+ /*
+ * now add some hysteresis, hyst_plus=3, hyst_minus=3
+ * (the minimum hysteresis that looks good is 2)
+ */
+ val = readl_relaxed(anatop_base + XTALOSC24M_OSC_CONFIG0);
+ val &= ~((XTALOSC24M_OSC_CONFIG0_HYST_MINUS_MASK <<
+ XTALOSC24M_OSC_CONFIG0_HYST_MINUS_SHIFT) |
+ (XTALOSC24M_OSC_CONFIG0_HYST_PLUS_MASK <<
+ XTALOSC24M_OSC_CONFIG0_HYST_PLUS_SHIFT));
+ val |= (0x3 << XTALOSC24M_OSC_CONFIG0_HYST_MINUS_SHIFT) |
+ (0x3 << XTALOSC24M_OSC_CONFIG0_HYST_PLUS_SHIFT);
+ writel_relaxed(val, anatop_base + XTALOSC24M_OSC_CONFIG0);
+ /* set the count_1m_trg = 0x2d7 */
+ val = readl_relaxed(anatop_base + XTALOSC24M_OSC_CONFIG2);
+ val &= ~(XTALOSC24M_OSC_CONFIG2_COUNT_1M_TRG_MASK <<
+ XTALOSC24M_OSC_CONFIG2_COUNT_1M_TRG_SHIFT);
+ val |= 0x2d7 << XTALOSC24M_OSC_CONFIG2_COUNT_1M_TRG_SHIFT;
+ writel_relaxed(val, anatop_base + XTALOSC24M_OSC_CONFIG2);
+ /*
+ * hardware design require to write XTALOSC24M_OSC_CONFIG0 or
+ * XTALOSC24M_OSC_CONFIG1 to
+ * make XTALOSC24M_OSC_CONFIG2 write work
+ */
+ val = readl_relaxed(anatop_base + XTALOSC24M_OSC_CONFIG1);
+ writel_relaxed(val, anatop_base + XTALOSC24M_OSC_CONFIG1);
+
+ return 0;
+}
+
+int __init imx7d_cpuidle_init(void)
+{
+ wfi_iram_base_phys = (void *)(iram_tlb_phys_addr +
+ MX7_CPUIDLE_OCRAM_ADDR_OFFSET);
+
+ /* Make sure wfi_iram_base is 8 byte aligned. */
+ if ((uintptr_t)(wfi_iram_base_phys) & (FNCPY_ALIGN - 1))
+ wfi_iram_base_phys += FNCPY_ALIGN -
+ ((uintptr_t)wfi_iram_base_phys % (FNCPY_ALIGN));
+
+ wfi_iram_base = (void *)IMX_IO_P2V((unsigned long) wfi_iram_base_phys);
+
+ cpuidle_pm_info = wfi_iram_base;
+ cpuidle_pm_info->vbase = (phys_addr_t) wfi_iram_base;
+ cpuidle_pm_info->pbase = (phys_addr_t) wfi_iram_base_phys;
+ cpuidle_pm_info->pm_info_size = sizeof(*cpuidle_pm_info);
+ cpuidle_pm_info->resume_addr = virt_to_phys(ca7_cpu_resume);
+ cpuidle_pm_info->num_online_cpus = num_online_cpus();
+
+ cpuidle_pm_info->ddrc_base.pbase = MX7D_DDRC_BASE_ADDR;
+ cpuidle_pm_info->ddrc_base.vbase =
+ (void __iomem *)IMX_IO_P2V(MX7D_DDRC_BASE_ADDR);
+
+ cpuidle_pm_info->ccm_base.pbase = MX7D_CCM_BASE_ADDR;
+ cpuidle_pm_info->ccm_base.vbase =
+ (void __iomem *)IMX_IO_P2V(MX7D_CCM_BASE_ADDR);
+
+ cpuidle_pm_info->anatop_base.pbase = MX7D_ANATOP_BASE_ADDR;
+ cpuidle_pm_info->anatop_base.vbase =
+ (void __iomem *)IMX_IO_P2V(MX7D_ANATOP_BASE_ADDR);
+
+ cpuidle_pm_info->src_base.pbase = MX7D_SRC_BASE_ADDR;
+ cpuidle_pm_info->src_base.vbase =
+ (void __iomem *)IMX_IO_P2V(MX7D_SRC_BASE_ADDR);
+
+ cpuidle_pm_info->iomuxc_gpr_base.pbase = MX7D_IOMUXC_GPR_BASE_ADDR;
+ cpuidle_pm_info->iomuxc_gpr_base.vbase =
+ (void __iomem *)IMX_IO_P2V(MX7D_IOMUXC_GPR_BASE_ADDR);
+
+ cpuidle_pm_info->gpc_base.pbase = MX7D_GPC_BASE_ADDR;
+ cpuidle_pm_info->gpc_base.vbase =
+ (void __iomem *)IMX_IO_P2V(MX7D_GPC_BASE_ADDR);
+
+ cpuidle_pm_info->gic_dist_base.pbase = MX7D_GIC_BASE_ADDR;
+ cpuidle_pm_info->gic_dist_base.vbase =
+ (void __iomem *)IMX_IO_P2V(MX7D_GIC_BASE_ADDR);
+
+ imx7d_cpuidle_gic_base = ioremap(MX7D_GIC_BASE_ADDR, MX7D_GIC_SIZE);
+
+ imx7d_enable_rcosc();
+
+ /* code size should include cpuidle_pm_info size */
+ if (!psci_ops.cpu_suspend) {
+ imx7d_wfi_in_iram_fn = (void *)fncpy(wfi_iram_base +
+ sizeof(*cpuidle_pm_info),
+ &imx7d_low_power_idle,
+ MX7_CPUIDLE_OCRAM_SIZE - sizeof(*cpuidle_pm_info));
+ }
+
+ return cpuidle_register(&imx7d_cpuidle_driver, NULL);
+}
diff --git a/arch/arm/mach-imx/cpuidle-imx7ulp.c b/arch/arm/mach-imx/cpuidle-imx7ulp.c
new file mode 100644
index 000000000000..924a19c16321
--- /dev/null
+++ b/arch/arm/mach-imx/cpuidle-imx7ulp.c
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2016 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/module.h>
+#include <asm/cpuidle.h>
+
+#include "common.h"
+#include "cpuidle.h"
+#include "hardware.h"
+
+static int imx7ulp_enter_wait(struct cpuidle_device *dev,
+ struct cpuidle_driver *drv, int index)
+{
+ if (index == 1)
+ imx7ulp_set_lpm(WAIT);
+ else
+ imx7ulp_set_lpm(STOP);
+
+ cpu_do_idle();
+
+ imx7ulp_set_lpm(RUN);
+
+ return index;
+}
+
+static struct cpuidle_driver imx7ulp_cpuidle_driver = {
+ .name = "imx7ulp_cpuidle",
+ .owner = THIS_MODULE,
+ .states = {
+ /* WFI */
+ ARM_CPUIDLE_WFI_STATE,
+ /* WAIT */
+ {
+ .exit_latency = 50,
+ .target_residency = 75,
+ .enter = imx7ulp_enter_wait,
+ .name = "WAIT",
+ .desc = "PSTOP2",
+ },
+ /* STOP */
+ {
+ .exit_latency = 100,
+ .target_residency = 150,
+ .enter = imx7ulp_enter_wait,
+ .name = "STOP",
+ .desc = "PSTOP1",
+ },
+ },
+ .state_count = 3,
+ .safe_state_index = 0,
+};
+
+int __init imx7ulp_cpuidle_init(void)
+{
+ return cpuidle_register(&imx7ulp_cpuidle_driver, NULL);
+}
diff --git a/arch/arm/mach-imx/cpuidle.h b/arch/arm/mach-imx/cpuidle.h
index f9140128ba05..762412733a5a 100644
--- a/arch/arm/mach-imx/cpuidle.h
+++ b/arch/arm/mach-imx/cpuidle.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2012 Freescale Semiconductor, Inc.
+ * Copyright 2012-2016 Freescale Semiconductor, Inc.
* Copyright 2012 Linaro Ltd.
*
* The code contained herein is licensed under the GNU General Public
@@ -15,6 +15,10 @@ extern int imx5_cpuidle_init(void);
extern int imx6q_cpuidle_init(void);
extern int imx6sl_cpuidle_init(void);
extern int imx6sx_cpuidle_init(void);
+extern int imx6ul_cpuidle_init(void);
+extern int imx7d_cpuidle_init(void);
+extern int imx7d_enable_rcosc(void);
+extern int imx7ulp_cpuidle_init(void);
#else
static inline int imx5_cpuidle_init(void)
{
@@ -32,4 +36,26 @@ static inline int imx6sx_cpuidle_init(void)
{
return 0;
}
+static inline int imx6ul_cpuidle_init(void)
+{
+ return 0;
+}
+static inline int imx7d_cpuidle_init(void)
+{
+ return 0;
+}
+static inline int imx7d_enable_rcosc(void)
+{
+ return 0;
+}
+static inline int imx7ulp_cpuidle_init(void)
+{
+ return 0;
+}
+#endif
+
+#if defined(CONFIG_CPU_IDLE) && defined (CONFIG_SOC_IMX6SLL)
+extern int imx6sll_cpuidle_init(void);
+#else
+static inline int imx6sll_cpuidle_init(void) { return 0; }
#endif
diff --git a/arch/arm/mach-imx/ddr3_freq_imx6.S b/arch/arm/mach-imx/ddr3_freq_imx6.S
new file mode 100644
index 000000000000..e6f7f74f7d32
--- /dev/null
+++ b/arch/arm/mach-imx/ddr3_freq_imx6.S
@@ -0,0 +1,1103 @@
+/*
+ * Copyright (C) 2011-2015 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/linkage.h>
+#include <asm/smp_scu.h>
+#include "hardware.h"
+
+#define MMDC0_MDPDC 0x4
+#define MMDC0_MDCF0 0x0c
+#define MMDC0_MDCF1 0x10
+#define MMDC0_MDMISC 0x18
+#define MMDC0_MDSCR 0x1c
+#define MMDC0_MAARCR 0x400
+#define MMDC0_MAPSR 0x404
+#define MMDC0_MADPCR0 0x410
+#define MMDC0_MPZQHWCTRL 0x800
+#define MMDC1_MPZQHWCTRL 0x4800
+#define MMDC0_MPODTCTRL 0x818
+#define MMDC1_MPODTCTRL 0x4818
+#define MMDC0_MPDGCTRL0 0x83c
+#define MMDC1_MPDGCTRL0 0x483c
+#define MMDC0_MPMUR0 0x8b8
+#define MMDC1_MPMUR0 0x48b8
+
+#define CCM_CBCDR 0x14
+#define CCM_CBCMR 0x18
+#define CCM_CSCMR1 0x1c
+#define CCM_CDHIPR 0x48
+
+#define L2_CACHE_SYNC 0x730
+#define PL310_AUX_CTRL 0x104
+#define PL310_DCACHE_LOCKDOWN_BASE 0x900
+#define PL310_AUX_16WAY_BIT 0x10000
+#define PL310_LOCKDOWN_NBREGS 8
+#define PL310_LOCKDOWN_SZREG 4
+#define PL310_8WAYS_MASK 0x00FF
+#define PL310_16WAYS_UPPERMASK 0xFF00
+
+#define IMX6QP_REVISION_ID 0x630100
+#define ANADIG_DIGPROG 0x260
+
+.extern iram_tlb_phys_addr
+
+.globl mx6_ddr3_freq_change_start
+.globl mx6_ddr3_freq_change_end
+
+ .align 3
+
+ .macro is_mx6qp
+
+ /* check if the SOC is i.MX6QP */
+ ldr r0, =IMX_IO_P2V(MX6Q_ANATOP_BASE_ADDR)
+ ldr r1, [r0, #ANADIG_DIGPROG]
+ ldr r2, =IMX6QP_REVISION_ID
+ cmp r1, r2
+
+ .endm
+
+ .macro switch_to_528MHz
+
+ /* check if periph_clk_sel is already set */
+ ldr r0, [r6, #CCM_CBCDR]
+ and r0, r0, #(1 << 25)
+ cmp r0, #(1 << 25)
+ beq set_ahb_podf_before_switch
+
+ /* change periph_clk to be sourced from pll3_clk. */
+ ldr r0, [r6, #CCM_CBCMR]
+ bic r0, r0, #(3 << 12)
+ str r0, [r6, #CCM_CBCMR]
+
+ ldr r0, [r6, #CCM_CBCDR]
+ bic r0, r0, #(0x38 << 20)
+ str r0, [r6, #CCM_CBCDR]
+
+ /*
+ * set the AHB dividers before the switch,
+ * don't change AXI clock divider,
+ * set the MMDC_DIV=1, AXI_DIV = 2, AHB_DIV=4,
+ */
+ ldr r0, [r6, #CCM_CBCDR]
+ ldr r2, =0x3f1f00
+ bic r0, r0, r2
+ orr r0, r0, #0xd00
+ orr r0, r0, #(1 << 16)
+ str r0, [r6, #CCM_CBCDR]
+
+wait_div_update528:
+ ldr r0, [r6, #CCM_CDHIPR]
+ cmp r0, #0
+ bne wait_div_update528
+
+ /* now switch periph_clk to pll3_main_clk. */
+ ldr r0, [r6, #CCM_CBCDR]
+ orr r0, r0, #(1 << 25)
+ str r0, [r6, #CCM_CBCDR]
+
+periph_clk_switch3:
+ ldr r0, [r6, #CCM_CDHIPR]
+ cmp r0, #0
+ bne periph_clk_switch3
+
+ b switch_pre_periph_clk_528
+
+set_ahb_podf_before_switch:
+ /*
+ * set the MMDC_DIV=1, AXI_DIV = 2, AHB_DIV=4,
+ */
+ ldr r0, [r6, #CCM_CBCDR]
+ ldr r2, =0x3f1f00
+ bic r0, r0, r2
+ orr r0, r0, #0xd00
+ orr r0, r0, #(1 << 16)
+ str r0, [r6, #CCM_CBCDR]
+
+wait_div_update528_1:
+ ldr r0, [r6, #CCM_CDHIPR]
+ cmp r0, #0
+ bne wait_div_update528_1
+
+switch_pre_periph_clk_528:
+
+ /* now switch pre_periph_clk to PLL2_528MHz. */
+ ldr r0, [r6, #CCM_CBCMR]
+ bic r0, r0, #(0xc << 16)
+ str r0, [r6, #CCM_CBCMR]
+
+ /* now switch periph_clk back. */
+ ldr r0, [r6, #CCM_CBCDR]
+ bic r0, r0, #(1 << 25)
+ str r0, [r6, #CCM_CBCDR]
+
+periph_clk_switch4:
+ ldr r0, [r6, #CCM_CDHIPR]
+ cmp r0, #0
+ bne periph_clk_switch4
+
+ .endm
+
+ .macro switch_to_400MHz
+
+ /* check if periph_clk_sel is already set. */
+ ldr r0, [r6, #CCM_CBCDR]
+ and r0, r0, #(1 << 25)
+ cmp r0, #(1 << 25)
+ beq set_ahb_podf_before_switch1
+
+ /* change periph_clk to be sourced from pll3_clk. */
+ ldr r0, [r6, #CCM_CBCMR]
+ bic r0, r0, #(3 << 12)
+ str r0, [r6, #CCM_CBCMR]
+
+ ldr r0, [r6, #CCM_CBCDR]
+ bic r0, r0, #(0x38 << 24)
+ str r0, [r6, #CCM_CBCDR]
+
+ /* now switch periph_clk to pll3_main_clk. */
+ ldr r0, [r6, #CCM_CBCDR]
+ orr r0, r0, #(1 << 25)
+ str r0, [r6, #CCM_CBCDR]
+
+periph_clk_switch5:
+ ldr r0, [r6, #CCM_CDHIPR]
+ cmp r0, #0
+ bne periph_clk_switch5
+
+ b switch_pre_periph_clk_400
+
+set_ahb_podf_before_switch1:
+ /*
+ * set the MMDC_DIV=1, AXI_DIV = 2, AHB_DIV=4,
+ */
+ ldr r0, [r6, #CCM_CBCDR]
+ ldr r2, =0x3f1f00
+ bic r0, r0, r2
+ orr r0, r0, #(0x9 << 8)
+ orr r0, r0, #(1 << 16)
+ str r0, [r6, #CCM_CBCDR]
+
+wait_div_update400_1:
+ ldr r0, [r6, #CCM_CDHIPR]
+ cmp r0, #0
+ bne wait_div_update400_1
+
+switch_pre_periph_clk_400:
+
+ /* now switch pre_periph_clk to PFD_400MHz. */
+ ldr r0, [r6, #CCM_CBCMR]
+ bic r0, r0, #(0xc << 16)
+ orr r0, r0, #(0x4 << 16)
+ str r0, [r6, #CCM_CBCMR]
+
+ /* now switch periph_clk back. */
+ ldr r0, [r6, #CCM_CBCDR]
+ bic r0, r0, #(1 << 25)
+ str r0, [r6, #CCM_CBCDR]
+
+periph_clk_switch6:
+ ldr r0, [r6, #CCM_CDHIPR]
+ cmp r0, #0
+ bne periph_clk_switch6
+
+ /*
+ * change AHB divider so that we are at 400/3=133MHz.
+ * don't change AXI clock divider.
+ * set the MMDC_DIV=1, AXI_DIV=2, AHB_DIV=3,
+ */
+ ldr r0, [r6, #CCM_CBCDR]
+ ldr r2, =0x3f1f00
+ bic r0, r0, r2
+ orr r0, r0, #(0x9 << 8)
+ orr r0, r0, #(1 << 16)
+ str r0, [r6, #CCM_CBCDR]
+
+wait_div_update400_2:
+ ldr r0, [r6, #CCM_CDHIPR]
+ cmp r0, #0
+ bne wait_div_update400_2
+
+ .endm
+
+ .macro switch_to_50MHz
+
+ /* check if periph_clk_sel is already set. */
+ ldr r0, [r6, #CCM_CBCDR]
+ and r0, r0, #(1 << 25)
+ cmp r0, #(1 << 25)
+ beq switch_pre_periph_clk_50
+
+ /*
+ * set the periph_clk to be sourced from PLL2_PFD_200M
+ * change periph_clk to be sourced from pll3_clk.
+ * ensure PLL3 is the source and set the divider to 1.
+ */
+ ldr r0, [r6, #CCM_CBCMR]
+ bic r0, r0, #(0x3 << 12)
+ str r0, [r6, #CCM_CBCMR]
+
+ ldr r0, [r6, #CCM_CBCDR]
+ bic r0, r0, #(0x38 << 24)
+ str r0, [r6, #CCM_CBCDR]
+
+ /* now switch periph_clk to pll3_main_clk. */
+ ldr r0, [r6, #CCM_CBCDR]
+ orr r0, r0, #(1 << 25)
+ str r0, [r6, #CCM_CBCDR]
+
+periph_clk_switch_50:
+ ldr r0, [r6, #CCM_CDHIPR]
+ cmp r0, #0
+ bne periph_clk_switch_50
+
+switch_pre_periph_clk_50:
+
+ /* now switch pre_periph_clk to PFD_200MHz. */
+ ldr r0, [r6, #CCM_CBCMR]
+ orr r0, r0, #(0xc << 16)
+ str r0, [r6, #CCM_CBCMR]
+
+ /*
+ * set the MMDC_DIV=4, AXI_DIV = 4, AHB_DIV=8,
+ */
+ ldr r0, [r6, #CCM_CBCDR]
+ ldr r2, =0x3f1f00
+ bic r0, r0, r2
+ orr r0, r0, #(0x18 << 16)
+ orr r0, r0, #(0x3 << 16)
+
+ /*
+ * if changing AHB divider remember to change
+ * the IPGPER divider too below.
+ */
+ orr r0, r0, #0x1d00
+ str r0, [r6, #CCM_CBCDR]
+
+wait_div_update_50:
+ ldr r0, [r6, #CCM_CDHIPR]
+ cmp r0, #0
+ bne wait_div_update_50
+
+ /* now switch periph_clk back. */
+ ldr r0, [r6, #CCM_CBCDR]
+ bic r0, r0, #(1 << 25)
+ str r0, [r6, #CCM_CBCDR]
+
+periph_clk_switch2:
+ ldr r0, [r6, #CCM_CDHIPR]
+ cmp r0, #0
+ bne periph_clk_switch2
+
+ .endm
+
+ .macro switch_to_24MHz
+ /*
+ * change the freq now try setting DDR to 24MHz.
+ * source it from the periph_clk2 ensure the
+ * periph_clk2 is sourced from 24MHz and the
+ * divider is 1.
+ */
+
+ ldr r0, [r6, #CCM_CBCMR]
+ bic r0, r0, #(0x3 << 12)
+ orr r0, r0, #(1 << 12)
+ str r0, [r6, #CCM_CBCMR]
+
+ ldr r0, [r6, #CCM_CBCDR]
+ bic r0, r0, #(0x38 << 24)
+ str r0, [r6, #CCM_CBCDR]
+
+ /* now switch periph_clk to 24MHz. */
+ ldr r0, [r6, #CCM_CBCDR]
+ orr r0, r0, #(1 << 25)
+ str r0, [r6, #CCM_CBCDR]
+
+periph_clk_switch1:
+ ldr r0, [r6, #CCM_CDHIPR]
+ cmp r0, #0
+ bne periph_clk_switch1
+
+ /* change all the dividers to 1. */
+ ldr r0, [r6, #CCM_CBCDR]
+ ldr r2, =0x3f1f00
+ bic r0, r0, r2
+ orr r0, r0, #(1 << 8)
+ str r0, [r6, #CCM_CBCDR]
+
+ /* Wait for the divider to change. */
+wait_div_update:
+ ldr r0, [r6, #CCM_CDHIPR]
+ cmp r0, #0
+ bne wait_div_update
+
+ .endm
+
+ .macro disable_l1_dcache
+
+ /*
+ * Flush all data from the L1 data cache before disabling
+ * SCTLR.C bit.
+ */
+ push {r0 - r11, lr}
+
+ ldr r7, =v7_flush_kern_cache_all
+ mov lr, pc
+ mov pc, r7
+ pop {r0 - r11, lr}
+
+ /* disable d-cache */
+ mrc p15, 0, r6, c1, c0, 0
+ bic r6, r6, #0x4
+ mcr p15, 0, r6, c1, c0, 0
+ dsb
+ isb
+
+ push {r0 - r11, lr}
+
+ ldr r7, =v7_flush_kern_cache_all
+ mov lr, pc
+ mov pc, r7
+ pop {r0 - r11, lr}
+
+ .endm
+
+/*
+ * mx6_ddr3_freq_change
+ *
+ * idle the processor (eg, wait for interrupt).
+ * make sure DDR is in self-refresh.
+ * IRQs are already disabled.
+ */
+ENTRY(mx6_ddr3_freq_change)
+
+mx6_ddr3_freq_change_start:
+ stmfd sp!, {r4-r12}
+
+ /*
+ * r5 -> mmdc_base
+ * r6 -> ccm_base
+ * r7 -> iomux_base
+ * r12 -> l2_base
+ */
+ mov r4, r0
+ mov r8, r1
+ mov r9, r2
+ mov r11, r3
+
+ /* flush the TLB */
+ ldr r6, =0x0
+ mcr p15, 0, r6, c8, c3, 0
+
+ ldr r6, =iram_tlb_phys_addr
+ ldr r7, [r6]
+
+ /*
+ * Need to flush and disable L1 before
+ * disabling L2, we need data to
+ * coherent. Flushing L1 pushes
+ * everyhting to L2. We sync L2 later, but
+ * it can still have dirty lines.
+ * While exiting, we need to enable L2 first
+ * and then L1.
+ */
+ disable_l1_dcache
+
+#ifdef CONFIG_CACHE_L2X0
+ /*
+ * Make sure the L2 buffers are drained.
+ * Sync operation on L2 drains the buffers.
+ */
+ ldr r12, =IMX_IO_P2V(MX6Q_L2_BASE_ADDR)
+
+ /* Wait for background operations to complete. */
+wait_for_l2_to_idle:
+ ldr r1, [r12, #L2_CACHE_SYNC]
+ cmp r1, #0x0
+ bne wait_for_l2_to_idle
+
+ mov r1, #0x0
+ str r1, [r12, #L2_CACHE_SYNC]
+
+ dsb
+ isb
+
+ ldr r1, [r12, #PL310_AUX_CTRL]
+ tst r1, #PL310_AUX_16WAY_BIT
+ mov r1, #PL310_8WAYS_MASK
+ orrne r1, #PL310_16WAYS_UPPERMASK
+ mov r6, #PL310_LOCKDOWN_NBREGS
+ add r5, r12, #PL310_DCACHE_LOCKDOWN_BASE
+1: /* lock Dcache and Icache */
+ str r1, [r5], #PL310_LOCKDOWN_SZREG
+ str r1, [r5], #PL310_LOCKDOWN_SZREG
+ subs r6, r6, #1
+ bne 1b
+#endif
+
+ /*
+ * To ensure no page table walks occur in DDR, we
+ * have a another page table stored in IRAM that only
+ * contains entries pointing to IRAM, AIPS1 and AIPS2.
+ * We need to set the TTBR1 to the new IRAM TLB.
+ * Do the following steps:
+ * 1. Flush the Branch Target Address Cache (BTAC)
+ * 2. Set TTBR1 to point to IRAM page table.
+ * 3. Disable page table walks in TTBR0 (PD0 = 1)
+ * 4. Set TTBR0.N=1, implying 0-2G is translated by TTBR0
+ * and 2-4G is translated by TTBR1.
+ */
+
+
+ /* Now switch the TTBR. */
+ /* Disable Branch Prediction, Z bit in SCTLR. */
+ mrc p15, 0, r6, c1, c0, 0
+ bic r6, r6, #0x800
+ mcr p15, 0, r6, c1, c0, 0
+
+ /* Flush the Branch Target Address Cache (BTAC) */
+ ldr r6, =0x0
+ mcr p15, 0, r6, c7, c1, 6
+
+ dsb
+ isb
+
+ /* Store the IRAM table in TTBR1 */
+ mcr p15, 0, r7, c2, c0, 1
+
+ /* Read TTBCR and set PD0=1, N = 1 */
+ mrc p15, 0, r6, c2, c0, 2
+ orr r6, r6, #0x11
+ mcr p15, 0, r6, c2, c0, 2
+
+ dsb
+ isb
+
+ /* flush the TLB */
+ ldr r6, =0x0
+ mcr p15, 0, r6, c8, c3, 0
+
+ dsb
+ isb
+
+
+ ldr r5, =IMX_IO_P2V(MX6Q_MMDC_P0_BASE_ADDR)
+ ldr r6, =IMX_IO_P2V(MX6Q_CCM_BASE_ADDR)
+ ldr r7, =IMX_IO_P2V(MX6Q_IOMUXC_BASE_ADDR)
+
+ /* Read the Original MU delay value */
+ ldr r1, [r5, #MMDC0_MPMUR0]
+ mov r10, r1, lsr #16
+ ldr r1, =0x3ff
+ and r10, r10, r1
+
+ /* disable automatic power saving. */
+ ldr r0, [r5, #MMDC0_MAPSR]
+ orr r0, r0, #0x01
+ str r0, [r5, #MMDC0_MAPSR]
+
+ /* disable MMDC power down timer. */
+ ldr r0, [r5, #MMDC0_MDPDC]
+ bic r0, r0, #(0xff << 8)
+ str r0, [r5, #MMDC0_MDPDC]
+
+ /* delay for a while */
+ ldr r1, =4
+delay1:
+ ldr r2, =0
+cont1:
+ ldr r0, [r5, r2]
+ add r2, r2, #4
+ cmp r2, #16
+ bne cont1
+ sub r1, r1, #1
+ cmp r1, #0
+ bgt delay1
+
+ /* set CON_REG */
+ ldr r0, =0x8000
+ str r0, [r5, #MMDC0_MDSCR]
+poll_conreq_set_1:
+ ldr r0, [r5, #MMDC0_MDSCR]
+ and r0, r0, #(0x4 << 12)
+ cmp r0, #(0x4 << 12)
+ bne poll_conreq_set_1
+
+ /*
+ * if requested frequency is great than
+ * 300MHz, skip setting bypass adopt mode.
+ */
+ ldr r1, =300000000
+ cmp r4, r1
+ bge 1f
+
+ is_mx6qp
+ bne 1f
+ /* Switch to adopt mode, set MMDC0_MAARCR bit25~26 to 2b'01 */
+ ldr r0, [r5, #MMDC0_MAARCR]
+ bic r0, r0, #(0x3 << 25)
+ orr r0, #(0x01 << 25)
+ str r0 , [r5, #MMDC0_MAARCR]
+1:
+ ldr r0, =0x00008050
+ str r0, [r5, #MMDC0_MDSCR]
+ ldr r0, =0x00008058
+ str r0, [r5, #MMDC0_MDSCR]
+
+ /*
+ * if requested frequency is greater than
+ * 300MHz go to DLL on mode.
+ */
+ ldr r1, =300000000
+ cmp r4, r1
+ bge dll_on_mode
+
+dll_off_mode:
+
+ /* if DLL is currently on, turn it off. */
+ cmp r9, #1
+ beq continue_dll_off_1
+
+ ldr r0, =0x00018031
+ str r0, [r5, #MMDC0_MDSCR]
+
+ ldr r0, =0x00018039
+ str r0, [r5, #MMDC0_MDSCR]
+
+ ldr r1, =10
+delay1a:
+ ldr r2, =0
+cont1a:
+ ldr r0, [r5, r2]
+ add r2, r2, #4
+ cmp r2, #16
+ bne cont1a
+ sub r1, r1, #1
+ cmp r1, #0
+ bgt delay1a
+
+continue_dll_off_1:
+ /* set DVFS - enter self refresh mode */
+ ldr r0, [r5, #MMDC0_MAPSR]
+ orr r0, r0, #(1 << 21)
+ str r0, [r5, #MMDC0_MAPSR]
+
+ /* de-assert con_req */
+ mov r0, #0x0
+ str r0, [r5, #MMDC0_MDSCR]
+
+poll_dvfs_set_1:
+ ldr r0, [r5, #MMDC0_MAPSR]
+ and r0, r0, #(1 << 25)
+ cmp r0, #(1 << 25)
+ bne poll_dvfs_set_1
+
+ ldr r1, =24000000
+ cmp r4, r1
+ beq switch_freq_24
+
+ switch_to_50MHz
+ b continue_dll_off_2
+
+switch_freq_24:
+ switch_to_24MHz
+
+continue_dll_off_2:
+
+ /* set SBS - block ddr accesses */
+ ldr r0, [r5, #MMDC0_MADPCR0]
+ orr r0, r0, #(1 << 8)
+ str r0, [r5, #MMDC0_MADPCR0]
+
+ /* clear DVFS - exit from self refresh mode */
+ ldr r0, [r5, #MMDC0_MAPSR]
+ bic r0, r0, #(1 << 21)
+ str r0, [r5, #MMDC0_MAPSR]
+
+poll_dvfs_clear_1:
+ ldr r0, [r5, #MMDC0_MAPSR]
+ and r0, r0, #(1 << 25)
+ cmp r0, #(1 << 25)
+ beq poll_dvfs_clear_1
+
+ /* if DLL was previously on, continue DLL off routine. */
+ cmp r9, #1
+ beq continue_dll_off_3
+
+ ldr r0, =0x00018031
+ str r0, [r5, #MMDC0_MDSCR]
+
+ ldr r0, =0x00018039
+ str r0, [r5, #MMDC0_MDSCR]
+
+ ldr r0, =0x08208030
+ str r0, [r5, #MMDC0_MDSCR]
+
+ ldr r0, =0x08208038
+ str r0, [r5, #MMDC0_MDSCR]
+
+ ldr r0, =0x00088032
+ str r0, [r5, #MMDC0_MDSCR]
+
+ ldr r0, =0x0008803A
+ str r0, [r5, #MMDC0_MDSCR]
+
+ /* delay for a while. */
+ ldr r1, =4
+delay_1:
+ ldr r2, =0
+cont_1:
+ ldr r0, [r5, r2]
+ add r2, r2, #4
+ cmp r2, #16
+ bne cont_1
+ sub r1, r1, #1
+ cmp r1, #0
+ bgt delay_1
+
+ ldr r0, [r5, #MMDC0_MDCF0]
+ bic r0, r0, #0xf
+ orr r0, r0, #0x3
+ str r0, [r5, #MMDC0_MDCF0]
+
+ ldr r0, [r5, #MMDC0_MDCF1]
+ bic r0, r0, #0x7
+ orr r0, r0, #0x4
+ str r0, [r5, #MMDC0_MDCF1]
+
+ ldr r0, [r5, #MMDC0_MDMISC]
+ bic r0, r0, #(0x3 << 16) /* walat = 0x1 */
+ orr r0, r0, #(0x1 << 16)
+ bic r0, r0, #(0x7 << 6) /* ralat = 0x2 */
+ orr r0, r0, #(0x2 << 6)
+ str r0, [r5, #MMDC0_MDMISC]
+
+ /* enable dqs pull down in the IOMUX. */
+ ldr r1, [r11]
+ add r11, r11, #8
+ ldr r2, =0x3028
+update_iomux:
+ ldr r0, [r11, #0x0]
+ ldr r3, [r7, r0]
+ bic r3, r3, r2
+ orr r3, r3, #(0x3 << 12)
+ orr r3, r3, #0x28
+ str r3, [r7, r0]
+ add r11, r11, #8
+ sub r1, r1, #1
+ cmp r1, #0
+ bgt update_iomux
+
+ /* ODT disabled. */
+ ldr r0, =0x0
+ ldr r2, =MMDC0_MPODTCTRL
+ str r0, [r5, r2]
+ ldr r2, =MMDC1_MPODTCTRL
+ str r0, [r5, r2]
+
+ /* DQS gating disabled. */
+ ldr r2, =MMDC0_MPDGCTRL0
+ ldr r0, [r5, r2]
+ orr r0, r0, #(1 << 29)
+ str r0, [r5, r2]
+
+ ldr r2, =MMDC1_MPDGCTRL0
+ ldr r0, [r5, r2]
+ orr r0, r0, #(0x1 << 29)
+ str r0, [r5, r2]
+
+ /* Add workaround for ERR005778.*/
+ /* double the original MU_UNIT_DEL_NUM. */
+ lsl r10, r10, #1
+
+ /* Bypass the automatic MU by setting the mu_byp_en */
+ ldr r2, [r5, #MMDC0_MPMUR0]
+ orr r2, r2, #0x400
+ orr r2, r2, r10
+ str r2, [r5, #MMDC0_MPMUR0]
+ ldr r0, =MMDC1_MPMUR0
+ str r2, [r5, r0]
+
+ /* Now perform a force measure */
+ ldr r0, [r5, #MMDC0_MPMUR0]
+ orr r0, r0, #0x800
+ str r0, [r5, #MMDC0_MPMUR0]
+ ldr r2, =MMDC1_MPMUR0
+ str r0, [r5, r2]
+ /* Wait for FRC_MSR to clear. */
+1:
+ ldr r0, [r5, #MMDC0_MPMUR0]
+ and r0, r0, #0x800
+ ldr r1, [r5, r2]
+ and r1, r1, #0x800
+ orr r0, r0, r1
+ cmp r0, #0x0
+ bne 1b
+
+continue_dll_off_3:
+ /* clear SBS - unblock accesses to DDR. */
+ ldr r0, [r5, #MMDC0_MADPCR0]
+ bic r0, r0, #(0x1 << 8)
+ str r0, [r5, #MMDC0_MADPCR0]
+
+ mov r0, #0x0
+ str r0, [r5, #MMDC0_MDSCR]
+poll_conreq_clear_1:
+ ldr r0, [r5, #MMDC0_MDSCR]
+ and r0, r0, #(0x4 << 12)
+ cmp r0, #(0x4 << 12)
+ beq poll_conreq_clear_1
+
+ b done
+
+dll_on_mode:
+ /* assert DVFS - enter self refresh mode. */
+ ldr r0, [r5, #MMDC0_MAPSR]
+ orr r0, r0, #(1 << 21)
+ str r0, [r5, #MMDC0_MAPSR]
+
+ /* de-assert CON_REQ. */
+ mov r0, #0x0
+ str r0, [r5, #MMDC0_MDSCR]
+
+ /* poll DVFS ack. */
+poll_dvfs_set_2:
+ ldr r0, [r5, #MMDC0_MAPSR]
+ and r0, r0, #(1 << 25)
+ cmp r0, #(1 << 25)
+ bne poll_dvfs_set_2
+
+ ldr r1, =528000000
+ cmp r4, r1
+ beq switch_freq_528
+
+ switch_to_400MHz
+
+ b continue_dll_on
+
+switch_freq_528:
+ switch_to_528MHz
+
+continue_dll_on:
+
+ /* set SBS step-by-step mode. */
+ ldr r0, [r5, #MMDC0_MADPCR0]
+ orr r0, r0, #( 1 << 8)
+ str r0, [r5, #MMDC0_MADPCR0]
+
+ /* clear DVFS - exit self refresh mode. */
+ ldr r0, [r5, #MMDC0_MAPSR]
+ bic r0, r0, #(1 << 21)
+ str r0, [r5, #MMDC0_MAPSR]
+
+poll_dvfs_clear_2:
+ ldr r0, [r5, #MMDC0_MAPSR]
+ and r0, r0, #(1 << 25)
+ cmp r0, #(1 << 25)
+ beq poll_dvfs_clear_2
+
+ /* if DLL is currently off, turn it back on. */
+ cmp r9, #0
+ beq update_calibration_only
+
+ /* issue zq calibration command */
+ ldr r0, [r5, #MMDC0_MPZQHWCTRL]
+ orr r0, r0, #0x3
+ str r0, [r5, #MMDC0_MPZQHWCTRL]
+ ldr r2, =MMDC1_MPZQHWCTRL
+ str r0, [r5, r2]
+
+ /* enable DQS gating. */
+ ldr r2, =MMDC0_MPDGCTRL0
+ ldr r0, [r5, r2]
+ bic r0, r0, #(1 << 29)
+ str r0, [r5, r2]
+
+ ldr r2, =MMDC1_MPDGCTRL0
+ ldr r0, [r5, r2]
+ bic r0, r0, #(1 << 29)
+ str r0, [r5, r2]
+
+ /* force measure. */
+ ldr r0, =0x00000800
+ str r0, [r5, #MMDC0_MPMUR0]
+ ldr r2, =MMDC1_MPMUR0
+ str r0, [r5, r2]
+
+ /* Wait for FRC_MSR to clear. */
+1:
+ ldr r0, [r5, #MMDC0_MPMUR0]
+ and r0, r0, #0x800
+ ldr r1, [r5, r2]
+ and r1, r1, #0x800
+ orr r0, r0, r1
+ cmp r0, #0x0
+ bne 1b
+
+ /* disable dqs pull down in the IOMUX. */
+ ldr r1, [r11]
+ add r11, r11, #8
+update_iomux1:
+ ldr r0, [r11, #0x0]
+ ldr r3, [r11, #0x4]
+ str r3, [r7, r0]
+ add r11, r11, #8
+ sub r1, r1, #1
+ cmp r1, #0
+ bgt update_iomux1
+
+ /* config MMDC timings to 528MHz. */
+ ldr r9, [r8]
+ add r8, r8, #8
+ ldr r0, [r8, #0x0]
+ ldr r3, [r8, #0x4]
+ str r3, [r5, r0]
+ add r8, r8, #8
+
+ ldr r0, [r8, #0x0]
+ ldr r3, [r8, #0x4]
+ str r3, [r5, r0]
+ add r8, r8, #8
+
+ /* configure ddr devices to dll on, odt. */
+ ldr r0, =0x00048031
+ str r0, [r5, #MMDC0_MDSCR]
+
+ ldr r0, =0x00048039
+ str r0, [r5, #MMDC0_MDSCR]
+
+ /* delay for while. */
+ ldr r1, =4
+delay7:
+ ldr r2, =0
+cont7:
+ ldr r0, [r5, r2]
+ add r2, r2, #4
+ cmp r2, #16
+ bne cont7
+ sub r1, r1, #1
+ cmp r1, #0
+ bgt delay7
+
+ /* reset dll. */
+ ldr r0, =0x09408030
+ str r0, [r5, #MMDC0_MDSCR]
+
+ ldr r0, =0x09408038
+ str r0, [r5, #MMDC0_MDSCR]
+
+ /* delay for while. */
+ ldr r1, =100
+delay8:
+ ldr r2, =0
+cont8:
+ ldr r0, [r5, r2]
+ add r2, r2, #4
+ cmp r2, #16
+ bne cont8
+ sub r1, r1, #1
+ cmp r1, #0
+ bgt delay8
+
+ ldr r0, [r8, #0x0]
+ ldr r3, [r8, #0x4]
+ str r3, [r5, r0]
+ add r8, r8, #8
+
+ ldr r0, [r8, #0x0]
+ ldr r3, [r8, #0x4]
+ str r3, [r5, r0]
+ add r8, r8, #8
+
+ ldr r0, =0x00428031
+ str r0, [r5, #MMDC0_MDSCR]
+
+ ldr r0, =0x00428039
+ str r0, [r5, #MMDC0_MDSCR]
+
+ ldr r0, [r8, #0x0]
+ ldr r3, [r8, #0x4]
+ str r3, [r5, r0]
+ add r8, r8, #8
+
+ ldr r0, [r8, #0x0]
+ ldr r3, [r8, #0x4]
+ str r3, [r5, r0]
+ add r8, r8, #8
+
+ /* issue a zq command. */
+ ldr r0, =0x04008040
+ str r0, [r5, #MMDC0_MDSCR]
+
+ ldr r0, =0x04008048
+ str r0, [r5, #MMDC0_MDSCR]
+
+ /* MMDC ODT enable. */
+ ldr r0, [r8, #0x0]
+ ldr r3, [r8, #0x4]
+ str r3, [r5, r0]
+ add r8, r8, #8
+
+ ldr r2, =0x4818
+ str r3, [r5, r2]
+
+ /* delay for while. */
+ ldr r1, =40
+delay15:
+ ldr r2, =0
+cont15:
+ ldr r0, [r5, r2]
+ add r2, r2, #4
+ cmp r2, #16
+ bne cont15
+ sub r1, r1, #1
+ cmp r1, #0
+ bgt delay15
+
+ /* enable MMDC power down timer. */
+ ldr r0, [r5, #MMDC0_MDPDC]
+ orr r0, r0, #(0x55 << 8)
+ str r0, [r5, #MMDC0_MDPDC]
+
+ b update_calibration
+
+update_calibration_only:
+ ldr r1, [r8]
+ sub r1, r1, #7
+ add r8, r8, #64
+ b update_calib
+
+update_calibration:
+ /* write the new calibration values. */
+ mov r1, r9
+ sub r1, r1, #7
+
+update_calib:
+ ldr r0, [r8, #0x0]
+ ldr r3, [r8, #0x4]
+ str r3, [r5, r0]
+ add r8, r8, #8
+ sub r1, r1, #1
+ cmp r1, #0
+ bgt update_calib
+
+ /* perform a force measurement. */
+ ldr r0, =0x800
+ str r0, [r5, #MMDC0_MPMUR0]
+ ldr r2, =MMDC1_MPMUR0
+ str r0, [r5, r2]
+
+ /* Wait for FRC_MSR to clear. */
+1:
+ ldr r0, [r5, #MMDC0_MPMUR0]
+ and r0, r0, #0x800
+ ldr r1, [r5, r2]
+ and r1, r1, #0x800
+ orr r0, r0, r1
+ cmp r0, #0x0
+ bne 1b
+
+ /* clear SBS - unblock DDR accesses. */
+ ldr r0, [r5, #MMDC0_MADPCR0]
+ bic r0, r0, #(1 << 8)
+ str r0, [r5, #MMDC0_MADPCR0]
+
+ is_mx6qp
+ bne 3f
+ /*
+ * Switch back to adopt_bp mode, set MMDC0_MAARCR
+ * bit25~26 to 2b'10.
+ */
+ ldr r0, [r5, #MMDC0_MAARCR]
+ bic r0, r0, #(0x3 << 25)
+ orr r0, r0, #(0x2 << 25)
+ str r0, [r5, #MMDC0_MAARCR]
+3:
+ mov r0, #0x0
+ str r0, [r5, #MMDC0_MDSCR]
+poll_conreq_clear_2:
+ ldr r0, [r5, #MMDC0_MDSCR]
+ and r0, r0, #(0x4 << 12)
+ cmp r0, #(0x4 << 12)
+ beq poll_conreq_clear_2
+
+done:
+ /* MMDC0_MAPSR adopt power down enable. */
+ ldr r0, [r5, #MMDC0_MAPSR]
+ bic r0, r0, #0x01
+ str r0, [r5, #MMDC0_MAPSR]
+
+#ifdef CONFIG_CACHE_L2X0
+ ldr r1, [r12, #PL310_AUX_CTRL]
+ tst r1, #PL310_AUX_16WAY_BIT
+ mov r6, #PL310_LOCKDOWN_NBREGS
+ mov r1, #0x00 /* 8 ways mask */
+ orrne r1, #0x0000 /* 16 ways mask */
+ add r5, r12, #PL310_DCACHE_LOCKDOWN_BASE
+1: /* lock Dcache and Icache */
+ str r1, [r5], #PL310_LOCKDOWN_SZREG
+ str r1, [r5], #PL310_LOCKDOWN_SZREG
+ subs r6, r6, #1
+ bne 1b
+
+ isb
+ dsb
+#endif
+
+ /* Enable L1 data cache. */
+ mrc p15, 0, r6, c1, c0, 0
+ orr r6, r6, #0x4
+ mcr p15, 0, r6, c1, c0, 0
+
+ /* Restore the TTBCR */
+ dsb
+ isb
+
+ /* Read TTBCR and set PD0=0, N = 0 */
+ mrc p15, 0, r6, c2, c0, 2
+ bic r6, r6, #0x11
+ mcr p15, 0, r6, c2, c0, 2
+ dsb
+ isb
+
+ /* flush the TLB */
+ ldr r6, =0x0
+ mcr p15, 0, r6, c8, c3, 0
+
+ dsb
+ isb
+
+ /* Enable Branch Prediction, Z bit in SCTLR. */
+ mrc p15, 0, r6, c1, c0, 0
+ orr r6, r6, #0x800
+ mcr p15, 0, r6, c1, c0, 0
+
+ isb
+
+ /* Flush the Branch Target Address Cache (BTAC) */
+ ldr r6, =0x0
+ mcr p15, 0, r6, c7, c1, 6
+ isb
+ dsb
+
+ /* restore registers */
+ ldmfd sp!, {r4-r12}
+ mov pc, lr
+
+ /*
+ * Add ltorg here to ensure that all
+ * literals are stored here and are
+ * within the text space.
+ */
+ .ltorg
+mx6_ddr3_freq_change_end:
diff --git a/arch/arm/mach-imx/ddr3_freq_imx6sx.S b/arch/arm/mach-imx/ddr3_freq_imx6sx.S
new file mode 100644
index 000000000000..1ac0d017bdf9
--- /dev/null
+++ b/arch/arm/mach-imx/ddr3_freq_imx6sx.S
@@ -0,0 +1,764 @@
+/*
+ * Copyright (C) 2011-2015 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/linkage.h>
+#include "hardware.h"
+
+.globl imx6_up_ddr3_freq_change_start
+.globl imx6_up_ddr3_freq_change_end
+
+#define MMDC0_MDPDC 0x4
+#define MMDC0_MDCF0 0xc
+#define MMDC0_MDCF1 0x10
+#define MMDC0_MDMISC 0x18
+#define MMDC0_MDSCR 0x1c
+#define MMDC0_MAPSR 0x404
+#define MMDC0_MADPCR0 0x410
+#define MMDC0_MPZQHWCTRL 0x800
+#define MMDC0_MPODTCTRL 0x818
+#define MMDC0_MPDGCTRL0 0x83c
+#define MMDC0_MPMUR0 0x8b8
+
+#define CCM_CBCDR 0x14
+#define CCM_CBCMR 0x18
+#define CCM_CSCMR1 0x1c
+#define CCM_CDHIPR 0x48
+
+#define L2_CACHE_SYNC 0x730
+#define PL310_AUX_CTRL 0x104
+#define PL310_DCACHE_LOCKDOWN_BASE 0x900
+#define PL310_AUX_16WAY_BIT 0x10000
+#define PL310_LOCKDOWN_NBREGS 8
+#define PL310_LOCKDOWN_SZREG 4
+#define PL310_8WAYS_MASK 0x00FF
+#define PL310_16WAYS_UPPERMASK 0xFF00
+
+#define BUSFREQ_INFO_FREQ_OFFSET 0x0
+#define BUSFREQ_INFO_DDR_SETTINGS_OFFSET 0x4
+#define BUSFREQ_INFO_DLL_OFF_OFFSET 0x8
+#define BUSFREQ_INFO_IOMUX_OFFSETS_OFFSET 0xc
+#define BUSFREQ_INFO_MU_DELAY_OFFSET 0x10
+
+.extern iram_tlb_phys_addr
+
+ .align 3
+
+ /* Check if the cpu is cortex-a7 */
+ .macro is_ca7
+
+ /* Read the primary cpu number is MPIDR */
+ mrc p15, 0, r7, c0, c0, 0
+ ldr r8, =0xfff0
+ and r7, r7, r8
+ ldr r8, =0xc070
+ cmp r7, r8
+
+ .endm
+
+ .macro do_delay
+
+1:
+ ldr r9, =0
+2:
+ ldr r10, [r4, r9]
+ add r9, r9, #4
+ cmp r9, #16
+ bne 2b
+ sub r8, r8, #1
+ cmp r8, #0
+ bgt 1b
+
+ .endm
+
+ .macro wait_for_ccm_handshake
+
+3:
+ ldr r8, [r5, #CCM_CDHIPR]
+ cmp r8, #0
+ bne 3b
+
+ .endm
+
+ .macro switch_to_400MHz
+
+ /* check whether periph2_clk is already from top path */
+ ldr r8, [r5, #CCM_CBCDR]
+ ands r8, #(1 << 26)
+ beq skip_periph2_clk2_switch_400m
+
+ /* now switch periph2_clk back. */
+ ldr r8, [r5, #CCM_CBCDR]
+ bic r8, r8, #(1 << 26)
+ str r8, [r5, #CCM_CBCDR]
+
+ wait_for_ccm_handshake
+
+ /*
+ * on i.MX6SX, pre_periph2_clk will be always from
+ * pll2_pfd2, so no need to set pre_periph2_clk
+ * parent, just set the mmdc divider directly.
+ */
+skip_periph2_clk2_switch_400m:
+
+ /* fabric_mmdc_podf to 0 */
+ ldr r8, [r5, #CCM_CBCDR]
+ bic r8, r8, #(0x7 << 3)
+ str r8, [r5, #CCM_CBCDR]
+
+ wait_for_ccm_handshake
+
+ .endm
+
+ .macro switch_to_50MHz
+
+ /* check whether periph2_clk is already from top path */
+ ldr r8, [r5, #CCM_CBCDR]
+ ands r8, #(1 << 26)
+ beq skip_periph2_clk2_switch_50m
+
+ /* now switch periph2_clk back. */
+ ldr r8, [r5, #CCM_CBCDR]
+ bic r8, r8, #(1 << 26)
+ str r8, [r5, #CCM_CBCDR]
+
+ wait_for_ccm_handshake
+
+ /*
+ * on i.MX6SX, pre_periph2_clk will be always from
+ * pll2_pfd2, so no need to set pre_periph2_clk
+ * parent, just set the mmdc divider directly.
+ */
+skip_periph2_clk2_switch_50m:
+
+ /* fabric_mmdc_podf to 7 so that mmdc is 400 / 8 = 50MHz */
+ ldr r8, [r5, #CCM_CBCDR]
+ orr r8, r8, #(0x7 << 3)
+ str r8, [r5, #CCM_CBCDR]
+
+ wait_for_ccm_handshake
+
+ .endm
+
+ .macro switch_to_24MHz
+
+ /* periph2_clk2 sel to OSC_CLK */
+ ldr r8, [r5, #CCM_CBCMR]
+ orr r8, r8, #(1 << 20)
+ str r8, [r5, #CCM_CBCMR]
+
+ /* periph2_clk2_podf to 0 */
+ ldr r8, [r5, #CCM_CBCDR]
+ bic r8, r8, #0x7
+ str r8, [r5, #CCM_CBCDR]
+
+ /* periph2_clk sel to periph2_clk2 */
+ ldr r8, [r5, #CCM_CBCDR]
+ orr r8, r8, #(0x1 << 26)
+ str r8, [r5, #CCM_CBCDR]
+
+ wait_for_ccm_handshake
+
+ /* fabric_mmdc_podf to 0 */
+ ldr r8, [r5, #CCM_CBCDR]
+ bic r8, r8, #(0x7 << 3)
+ str r8, [r5, #CCM_CBCDR]
+
+ wait_for_ccm_handshake
+
+ .endm
+
+/*
+ * imx6_up_ddr3_freq_change
+ * Below code can be used by i.MX6SX and i.MX6UL.
+ *
+ * idle the processor (eg, wait for interrupt).
+ * make sure DDR is in self-refresh.
+ * IRQs are already disabled.
+ */
+ENTRY(imx6_up_ddr3_freq_change)
+
+imx6_up_ddr3_freq_change_start:
+ stmfd sp!, {r4 - r11}
+
+ ldr r1, [r0, #BUSFREQ_INFO_DDR_SETTINGS_OFFSET]
+ ldr r2, [r0, #BUSFREQ_INFO_DLL_OFF_OFFSET]
+ ldr r3, [r0, #BUSFREQ_INFO_IOMUX_OFFSETS_OFFSET]
+
+ /*
+ * To ensure no page table walks occur in DDR, we
+ * have a another page table stored in IRAM that only
+ * contains entries pointing to IRAM, AIPS1 and AIPS2.
+ * We need to set the TTBR1 to the new IRAM TLB.
+ * Do the following steps:
+ * 1. Flush the Branch Target Address Cache (BTAC)
+ * 2. Set TTBR1 to point to IRAM page table.
+ * 3. Disable page table walks in TTBR0 (PD0 = 1)
+ * 4. Set TTBR0.N=1, implying 0-2G is translated by TTBR0
+ * and 2-4G is translated by TTBR1.
+ */
+
+ ldr r6, =iram_tlb_phys_addr
+ ldr r7, [r6]
+
+ /* Disable Branch Prediction, Z bit in SCTLR. */
+ mrc p15, 0, r6, c1, c0, 0
+ bic r6, r6, #0x800
+ mcr p15, 0, r6, c1, c0, 0
+
+ /* Flush the Branch Target Address Cache (BTAC) */
+ ldr r6, =0x0
+ mcr p15, 0, r6, c7, c1, 6
+
+ dsb
+ isb
+
+ /* Store the IRAM table in TTBR1 */
+ mcr p15, 0, r7, c2, c0, 1
+
+ /* Read TTBCR and set PD0=1, N = 1 */
+ mrc p15, 0, r6, c2, c0, 2
+ orr r6, r6, #0x11
+ mcr p15, 0, r6, c2, c0, 2
+
+ dsb
+ isb
+
+ /* flush the TLB */
+ ldr r6, =0x0
+ mcr p15, 0, r6, c8, c3, 0
+
+ dsb
+ isb
+
+ /* Disable L1 data cache. */
+ mrc p15, 0, r6, c1, c0, 0
+ bic r6, r6, #0x4
+ mcr p15, 0, r6, c1, c0, 0
+
+ ldr r4, =IMX_IO_P2V(MX6Q_MMDC_P0_BASE_ADDR)
+ ldr r5, =IMX_IO_P2V(MX6Q_CCM_BASE_ADDR)
+ ldr r6, =IMX_IO_P2V(MX6Q_IOMUXC_BASE_ADDR)
+
+ is_ca7
+ beq skip_disable_l2
+
+#ifdef CONFIG_CACHE_L2X0
+ /*
+ * make sure the L2 buffers are drained,
+ * sync operation on L2 drains the buffers.
+ */
+ ldr r8, =IMX_IO_P2V(MX6Q_L2_BASE_ADDR)
+
+ /* Wait for background operations to complete. */
+wait_for_l2_to_idle:
+ ldr r7, [r8, #0x730]
+ cmp r7, #0x0
+ bne wait_for_l2_to_idle
+
+ mov r7, #0x0
+ str r7, [r8, #L2_CACHE_SYNC]
+
+ /* Lock L2. */
+
+ ldr r9, [r8, #PL310_AUX_CTRL]
+ tst r9, #PL310_AUX_16WAY_BIT
+ mov r9, #PL310_8WAYS_MASK
+ orrne r9, #PL310_16WAYS_UPPERMASK
+ mov r10, #PL310_LOCKDOWN_NBREGS
+ add r11, r8, #PL310_DCACHE_LOCKDOWN_BASE
+1: /* lock Dcache and Icache */
+ str r9, [r11], #PL310_LOCKDOWN_SZREG
+ str r9, [r11], #PL310_LOCKDOWN_SZREG
+ subs r10, r10, #1
+ bne 1b
+
+ /*
+ * The second dsb might be needed to keep cache sync (device write)
+ * ordering with the memory accesses before it.
+ */
+ dsb
+ isb
+#endif
+
+skip_disable_l2:
+ /* disable automatic power saving. */
+ ldr r8, [r4, #MMDC0_MAPSR]
+ orr r8, r8, #0x1
+ str r8, [r4, #MMDC0_MAPSR]
+
+ /* disable MMDC power down timer. */
+ ldr r8, [r4, #MMDC0_MDPDC]
+ bic r8, r8, #(0xff << 8)
+ str r8, [r4, #MMDC0_MDPDC]
+
+ /* delay for a while */
+ ldr r8, =4
+ do_delay
+
+ /* set CON_REG */
+ ldr r8, =0x8000
+ str r8, [r4, #MMDC0_MDSCR]
+poll_conreq_set_1:
+ ldr r8, [r4, #MMDC0_MDSCR]
+ and r8, r8, #(0x4 << 12)
+ cmp r8, #(0x4 << 12)
+ bne poll_conreq_set_1
+
+ /*
+ * if requested frequency is greater than
+ * 300MHz go to DLL on mode.
+ */
+ ldr r8, [r0, #BUSFREQ_INFO_FREQ_OFFSET]
+ ldr r9, =300000000
+ cmp r8, r9
+ bge dll_on_mode
+
+dll_off_mode:
+ /* if DLL is currently on, turn it off. */
+ cmp r2, #1
+ beq continue_dll_off_1
+
+ ldr r8, =0x00018031
+ str r8, [r4, #MMDC0_MDSCR]
+
+ ldr r8, =0x00018039
+ str r8, [r4, #MMDC0_MDSCR]
+
+ ldr r8, =10
+ do_delay
+
+continue_dll_off_1:
+ /* set DVFS - enter self refresh mode */
+ ldr r8, [r4, #MMDC0_MAPSR]
+ orr r8, r8, #(1 << 21)
+ str r8, [r4, #MMDC0_MAPSR]
+
+ /* de-assert con_req */
+ mov r8, #0x0
+ str r8, [r4, #MMDC0_MDSCR]
+
+poll_dvfs_set_1:
+ ldr r8, [r4, #MMDC0_MAPSR]
+ and r8, r8, #(1 << 25)
+ cmp r8, #(1 << 25)
+ bne poll_dvfs_set_1
+
+ ldr r8, [r0, #BUSFREQ_INFO_FREQ_OFFSET]
+ ldr r9, =24000000
+ cmp r8, r9
+ beq switch_freq_24
+
+ switch_to_50MHz
+ b continue_dll_off_2
+
+switch_freq_24:
+ switch_to_24MHz
+
+continue_dll_off_2:
+ /* set SBS - block ddr accesses */
+ ldr r8, [r4, #MMDC0_MADPCR0]
+ orr r8, r8, #(1 << 8)
+ str r8, [r4, #MMDC0_MADPCR0]
+
+ /* clear DVFS - exit from self refresh mode */
+ ldr r8, [r4, #MMDC0_MAPSR]
+ bic r8, r8, #(1 << 21)
+ str r8, [r4, #MMDC0_MAPSR]
+
+poll_dvfs_clear_1:
+ ldr r8, [r4, #MMDC0_MAPSR]
+ and r8, r8, #(1 << 25)
+ cmp r8, #(1 << 25)
+ beq poll_dvfs_clear_1
+
+ /* if DLL was previously on, continue DLL off routine. */
+ cmp r2, #1
+ beq continue_dll_off_3
+
+ ldr r8, =0x00018031
+ str r8, [r4, #MMDC0_MDSCR]
+
+ ldr r8, =0x00018039
+ str r8, [r4, #MMDC0_MDSCR]
+
+ ldr r8, =0x04208030
+ str r8, [r4, #MMDC0_MDSCR]
+
+ ldr r8, =0x04208038
+ str r8, [r4, #MMDC0_MDSCR]
+
+ ldr r8, =0x00088032
+ str r8, [r4, #MMDC0_MDSCR]
+
+ ldr r8, =0x0008803A
+ str r8, [r4, #MMDC0_MDSCR]
+
+ /* delay for a while. */
+ ldr r8, =4
+ do_delay
+
+ ldr r8, [r4, #MMDC0_MDCF0]
+ bic r8, r8, #0xf
+ orr r8, r8, #0x3
+ str r8, [r4, #MMDC0_MDCF0]
+
+ ldr r8, [r4, #MMDC0_MDCF1]
+ bic r8, r8, #0x7
+ orr r8, r8, #0x4
+ str r8, [r4, #MMDC0_MDCF1]
+
+ ldr r8, [r4, #MMDC0_MDMISC]
+ bic r8, r8, #(0x3 << 16) /* walat = 0x1 */
+ orr r8, r8, #(0x1 << 16)
+ bic r8, r8, #(0x7 << 6) /* ralat = 0x2 */
+ orr r8, r8, #(0x2 << 6)
+ str r8, [r4, #MMDC0_MDMISC]
+
+ /* enable dqs pull down in the IOMUX. */
+ ldr r8, [r3]
+ add r3, r3, #8
+ ldr r9, =0x3028
+update_iomux:
+ ldr r10, [r3]
+ ldr r11, [r6, r10]
+ bic r11, r11, r9
+ orr r11, r11, #(0x3 << 12)
+ orr r11, r11, #0x28
+ str r11, [r6, r10]
+ add r3, r3, #8
+ sub r8, r8, #1
+ cmp r8, #0
+ bgt update_iomux
+
+ /* ODT disabled. */
+ ldr r8, =0x0
+ str r8, [r4, #MMDC0_MPODTCTRL]
+
+ /* DQS gating disabled. */
+ ldr r8, [r4, #MMDC0_MPDGCTRL0]
+ orr r8, r8, #(1 << 29)
+ str r8, [r4, #MMDC0_MPDGCTRL0]
+
+ /* Add workaround for ERR005778.*/
+ /* double the original MU_UNIT_DEL_NUM. */
+ ldr r8, [r0, #BUSFREQ_INFO_MU_DELAY_OFFSET]
+ lsl r8, r8, #1
+
+ /* Bypass the automatic MU by setting the mu_byp_en */
+ ldr r10, [r4, #MMDC0_MPMUR0]
+ orr r10, r10, #0x400
+ /* Set the MU_BYP_VAL */
+ orr r10, r10, r8
+ str r10, [r4, #MMDC0_MPMUR0]
+
+ /* Now perform a force measure */
+ ldr r8, [r4, #MMDC0_MPMUR0]
+ orr r8, r8, #0x800
+ str r8, [r4, #MMDC0_MPMUR0]
+ /* Wait for FRC_MSR to clear. */
+1:
+ ldr r8, [r4, #MMDC0_MPMUR0]
+ and r8, r8, #0x800
+ cmp r8, #0x0
+ bne 1b
+
+continue_dll_off_3:
+ /* clear SBS - unblock accesses to DDR. */
+ ldr r8, [r4, #MMDC0_MADPCR0]
+ bic r8, r8, #(0x1 << 8)
+ str r8, [r4, #MMDC0_MADPCR0]
+
+ mov r8, #0x0
+ str r8, [r4, #MMDC0_MDSCR]
+poll_conreq_clear_1:
+ ldr r8, [r4, #MMDC0_MDSCR]
+ and r8, r8, #(0x4 << 12)
+ cmp r8, #(0x4 << 12)
+ beq poll_conreq_clear_1
+
+ b done
+
+dll_on_mode:
+ /* assert DVFS - enter self refresh mode. */
+ ldr r8, [r4, #MMDC0_MAPSR]
+ orr r8, r8, #(1 << 21)
+ str r8, [r4, #MMDC0_MAPSR]
+
+ /* de-assert CON_REQ. */
+ mov r8, #0x0
+ str r8, [r4, #MMDC0_MDSCR]
+
+ /* poll DVFS ack. */
+poll_dvfs_set_2:
+ ldr r8, [r4, #MMDC0_MAPSR]
+ and r8, r8, #(1 << 25)
+ cmp r8, #(1 << 25)
+ bne poll_dvfs_set_2
+
+ switch_to_400MHz
+
+ /* set SBS step-by-step mode. */
+ ldr r8, [r4, #MMDC0_MADPCR0]
+ orr r8, r8, #(1 << 8)
+ str r8, [r4, #MMDC0_MADPCR0]
+
+ /* clear DVFS - exit self refresh mode. */
+ ldr r8, [r4, #MMDC0_MAPSR]
+ bic r8, r8, #(1 << 21)
+ str r8, [r4, #MMDC0_MAPSR]
+
+poll_dvfs_clear_2:
+ ldr r8, [r4, #MMDC0_MAPSR]
+ ands r8, r8, #(1 << 25)
+ bne poll_dvfs_clear_2
+
+ /* if DLL is currently off, turn it back on. */
+ cmp r2, #0
+ beq update_calibration_only
+
+ /* issue zq calibration command */
+ ldr r8, [r4, #MMDC0_MPZQHWCTRL]
+ orr r8, r8, #0x3
+ str r8, [r4, #MMDC0_MPZQHWCTRL]
+
+ /* enable DQS gating. */
+ ldr r10, =MMDC0_MPDGCTRL0
+ ldr r8, [r4, r10]
+ bic r8, r8, #(1 << 29)
+ str r8, [r4, r10]
+
+ /* Now perform a force measure */
+ ldr r8, =0x00000800
+ str r8, [r4, #MMDC0_MPMUR0]
+ /* Wait for FRC_MSR to clear. */
+1:
+ ldr r8, [r4, #MMDC0_MPMUR0]
+ and r8, r8, #0x800
+ cmp r8, #0x0
+ bne 1b
+
+ /* disable dqs pull down in the IOMUX. */
+ ldr r8, [r3]
+ add r3, r3, #8
+update_iomux1:
+ ldr r10, [r3, #0x0]
+ ldr r11, [r3, #0x4]
+ str r11, [r6, r10]
+ add r3, r3, #8
+ sub r8, r8, #1
+ cmp r8, #0
+ bgt update_iomux1
+
+ /* config MMDC timings to 400MHz. */
+ ldr r1, [r0, #BUSFREQ_INFO_DDR_SETTINGS_OFFSET]
+ ldr r7, [r1]
+ add r1, r1, #8
+ ldr r10, [r1, #0x0]
+ ldr r11, [r1, #0x4]
+ str r11, [r4, r10]
+ add r1, r1, #8
+
+ ldr r10, [r1, #0x0]
+ ldr r11, [r1, #0x4]
+ str r11, [r4, r10]
+ add r1, r1, #8
+
+ /* configure ddr devices to dll on, odt. */
+ ldr r8, =0x00028031
+ str r8, [r4, #MMDC0_MDSCR]
+
+ ldr r8, =0x00028039
+ str r8, [r4, #MMDC0_MDSCR]
+
+ /* delay for while. */
+ ldr r8, =4
+ do_delay
+
+ /* reset dll. */
+ ldr r8, =0x09208030
+ str r8, [r4, #MMDC0_MDSCR]
+
+ ldr r8, =0x09208038
+ str r8, [r4, #MMDC0_MDSCR]
+
+ /* delay for while. */
+ ldr r8, =100
+ do_delay
+
+ ldr r10, [r1, #0x0]
+ ldr r11, [r1, #0x4]
+ str r11, [r4, r10]
+ add r1, r1, #8
+
+ ldr r10, [r1, #0x0]
+ ldr r11, [r1, #0x4]
+ str r11, [r4, r10]
+ add r1, r1, #8
+
+ ldr r8, =0x00428031
+ str r8, [r4, #MMDC0_MDSCR]
+
+ ldr r8, =0x00428039
+ str r8, [r4, #MMDC0_MDSCR]
+
+ ldr r10, [r1, #0x0]
+ ldr r11, [r1, #0x4]
+ str r11, [r4, r10]
+ add r1, r1, #8
+
+ ldr r10, [r1, #0x0]
+ ldr r11, [r1, #0x4]
+ str r11, [r4, r10]
+ add r1, r1, #8
+
+ /* issue a zq command. */
+ ldr r8, =0x04008040
+ str r8, [r4, #MMDC0_MDSCR]
+
+ ldr r8, =0x04008048
+ str r8, [r4, #MMDC0_MDSCR]
+
+ /* MMDC ODT enable. */
+ ldr r10, [r1, #0x0]
+ ldr r11, [r1, #0x4]
+ str r11, [r4, r10]
+ add r1, r1, #8
+
+ /* delay for while. */
+ ldr r8, =40
+ do_delay
+
+ /* enable MMDC power down timer. */
+ ldr r8, [r4, #MMDC0_MDPDC]
+ orr r8, r8, #(0x55 << 8)
+ str r8, [r4, #MMDC0_MDPDC]
+
+ b update_calibration
+
+update_calibration_only:
+ ldr r8, [r1]
+ sub r8, r8, #7
+ add r1, r1, #64
+ b update_calib
+
+update_calibration:
+ /* write the new calibration values. */
+ mov r8, r7
+ sub r8, r8, #7
+
+update_calib:
+ ldr r10, [r1, #0x0]
+ ldr r11, [r1, #0x4]
+ str r11, [r4, r10]
+ add r1, r1, #8
+ sub r8, r8, #1
+ cmp r8, #0
+ bgt update_calib
+
+ /* perform a force measurement. */
+ ldr r8, =0x800
+ str r8, [r4, #MMDC0_MPMUR0]
+ /* Wait for FRC_MSR to clear. */
+1:
+ ldr r8, [r4, #MMDC0_MPMUR0]
+ and r8, r8, #0x800
+ cmp r8, #0x0
+ bne 1b
+
+ /* clear SBS - unblock DDR accesses. */
+ ldr r8, [r4, #MMDC0_MADPCR0]
+ bic r8, r8, #(1 << 8)
+ str r8, [r4, #MMDC0_MADPCR0]
+
+ mov r8, #0x0
+ str r8, [r4, #MMDC0_MDSCR]
+poll_conreq_clear_2:
+ ldr r8, [r4, #MMDC0_MDSCR]
+ and r8, r8, #(0x4 << 12)
+ cmp r8, #(0x4 << 12)
+ beq poll_conreq_clear_2
+
+done:
+
+ /* MMDC0_MAPSR adopt power down enable. */
+ ldr r8, [r4, #MMDC0_MAPSR]
+ bic r8, r8, #0x01
+ str r8, [r4, #MMDC0_MAPSR]
+
+ is_ca7
+ beq skip_enable_l2
+
+#ifdef CONFIG_CACHE_L2X0
+ /* Unlock L2. */
+ ldr r8, =IMX_IO_P2V(MX6Q_L2_BASE_ADDR)
+ ldr r9, [r8, #PL310_AUX_CTRL]
+ tst r9, #PL310_AUX_16WAY_BIT
+ mov r10, #PL310_LOCKDOWN_NBREGS
+ mov r9, #0x00 /* 8 ways mask */
+ orrne r9, #0x0000 /* 16 ways mask */
+ add r11, r8, #PL310_DCACHE_LOCKDOWN_BASE
+1: /* lock Dcache and Icache */
+ str r9, [r11], #PL310_LOCKDOWN_SZREG
+ str r9, [r11], #PL310_LOCKDOWN_SZREG
+ subs r10, r10, #1
+ bne 1b
+
+#endif
+
+skip_enable_l2:
+ /* Enable L1 data cache. */
+ mrc p15, 0, r7, c1, c0, 0
+ orr r7, r7, #0x4
+ mcr p15, 0, r7, c1, c0, 0
+
+ /* Restore the TTBCR */
+ dsb
+ isb
+
+ /* Read TTBCR and set PD0=0, N = 0 */
+ mrc p15, 0, r6, c2, c0, 2
+ bic r6, r6, #0x11
+ mcr p15, 0, r6, c2, c0, 2
+
+ dsb
+ isb
+
+ /* flush the TLB */
+ ldr r6, =0x0
+ mcr p15, 0, r6, c8, c3, 0
+
+ dsb
+ isb
+
+ /* Enable Branch Prediction, Z bit in SCTLR. */
+ mrc p15, 0, r7, c1, c0, 0
+ orr r7, r7, #0x800
+ mcr p15, 0, r7, c1, c0, 0
+
+ /* Flush the Branch Target Address Cache (BTAC) */
+ ldr r7, =0x0
+ mcr p15, 0, r7, c7, c1, 6
+
+ /* restore registers */
+ ldmfd sp!, {r4 - r11}
+ mov pc, lr
+
+ /*
+ * Add ltorg here to ensure that all
+ * literals are stored here and are
+ * within the text space.
+ */
+ .ltorg
+imx6_up_ddr3_freq_change_end:
+ENDPROC(imx6_up_ddr3_freq_change)
diff --git a/arch/arm/mach-imx/ddr3_freq_imx7d.S b/arch/arm/mach-imx/ddr3_freq_imx7d.S
new file mode 100644
index 000000000000..9342e0d83f5e
--- /dev/null
+++ b/arch/arm/mach-imx/ddr3_freq_imx7d.S
@@ -0,0 +1,586 @@
+/*
+ * Copyright (C) 2015-2016 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/linkage.h>
+#include "hardware.h"
+
+#define DDRC_MSTR 0x0
+#define DDRC_STAT 0x4
+#define DDRC_MRCTRL0 0x10
+#define DDRC_MRCTRL1 0x14
+#define DDRC_MRSTAT 0x18
+#define DDRC_PWRCTL 0x30
+#define DDRC_RFSHCTL3 0x60
+#define DDRC_RFSHTMG 0x64
+#define DDRC_DBG1 0x304
+#define DDRC_SWCTL 0x320
+#define DDRC_SWSTAT 0x324
+#define DDRC_PSTAT 0x3fc
+#define DDRC_PCTRL_0 0x490
+#define DDRC_ZQCTL0 0x180
+#define DDRC_DFIMISC 0x1b0
+#define DDRC_DBGCAM 0x308
+#define DDRPHY_LP_CON0 0x18
+#define IOMUXC_GPR8 0x20
+#define DDRPHY_MDLL_CON0 0xb0
+#define DDRPHY_MDLL_CON1 0xb4
+#define DDRPHY_OFFSETD_CON0 0x50
+#define DDRPHY_OFFSETR_CON0 0x20
+#define DDRPHY_OFFSETR_CON1 0x24
+#define DDRPHY_OFFSETR_CON2 0x28
+#define DDRPHY_OFFSETW_CON0 0x30
+#define DDRPHY_OFFSETW_CON1 0x34
+#define DDRPHY_OFFSETW_CON2 0x38
+#define DDRPHY_CA_WLDSKEW_CON0 0x6c
+#define DDRPHY_CA_DSKEW_CON0 0x7c
+#define DDRPHY_CA_DSKEW_CON1 0x80
+#define DDRPHY_CA_DSKEW_CON2 0x84
+
+#define ANADIG_DIGPROG 0x800
+
+ .align 3
+
+ .macro switch_to_below_100m
+
+ ldr r7, =0x2
+ str r7, [r4, #DDRC_DBG1]
+
+ ldr r6, =0x36000000
+1:
+ ldr r7, [r4, #DDRC_DBGCAM]
+ and r7, r7, r6
+ cmp r7, r6
+ bne 1b
+
+ ldr r6, =0x1
+2:
+ ldr r7, [r4, #DDRC_MRSTAT]
+ and r7, r7, r6
+ cmp r7, r6
+ beq 2b
+
+ ldr r7, =0x10f0
+ str r7, [r4, #DDRC_MRCTRL0]
+ ldr r7, =0x0
+ str r7, [r4, #DDRC_MRCTRL1]
+ ldr r7, =0x800010f0
+ str r7, [r4, #DDRC_MRCTRL0]
+
+ ldr r6, =0x1
+3:
+ ldr r7, [r4, #DDRC_MRSTAT]
+ and r7, r7, r6
+ cmp r7, r6
+ beq 3b
+
+ ldr r7, =0x20f0
+ str r7, [r4, #DDRC_MRCTRL0]
+ ldr r7, =0x8
+ str r7, [r4, #DDRC_MRCTRL1]
+ ldr r7, =0x800020f0
+ str r7, [r4, #DDRC_MRCTRL0]
+
+ ldr r6, =0x1
+4:
+ ldr r7, [r4, #DDRC_MRSTAT]
+ and r7, r7, r6
+ cmp r7, r6
+ beq 4b
+
+ ldr r7, =0x10f0
+ str r7, [r4, #DDRC_MRCTRL0]
+ ldr r7, =0x1
+ str r7, [r4, #DDRC_MRCTRL1]
+ ldr r7, =0x800010f0
+ str r7, [r4, #DDRC_MRCTRL0]
+
+ ldr r7, =0x20
+ str r7, [r4, #DDRC_PWRCTL]
+
+ ldr r6, =0x23
+5:
+ ldr r7, [r4, #DDRC_STAT]
+ and r7, r7, r6
+ cmp r7, r6
+ bne 5b
+
+ ldr r7, =0x0
+ str r7, [r4, #DDRC_SWCTL]
+
+ ldr r7, =0x03048001
+ str r7, [r4, #DDRC_MSTR]
+
+ ldr r7, =0x1
+ str r7, [r4, #DDRC_SWCTL]
+
+ ldr r6, =0x1
+6:
+ ldr r7, [r4, #DDRC_SWSTAT]
+ and r7, r7, r6
+ cmp r7, r6
+ bne 6b
+
+ ldr r7, =0x10010100
+ str r7, [r5, #0x4]
+
+ ldr r6, =24000000
+ cmp r0, r6
+ beq 25f
+
+ ldr r7, =0x000B000D
+ str r7,[r4, #DDRC_RFSHTMG]
+ b 7f
+
+25:
+ ldr r7, =0x00030004
+ str r7,[r4, #DDRC_RFSHTMG]
+
+ /* dram alt sel set to OSC */
+ ldr r7, =0x10000000
+ ldr r8, =0xa080
+ str r7, [r2, r8]
+ /* dram root set to from dram alt, div by 1 */
+ ldr r7, =0x11000000
+ ldr r8, =0x9880
+ str r7, [r2, r8]
+ b 8f
+7:
+ /* dram alt sel set to pfd0_392m */
+ ldr r7, =0x15000000
+ ldr r8, =0xa080
+ str r7, [r2, r8]
+ /* dram root set to from dram alt, div by 4 */
+ ldr r7, =0x11000003
+ ldr r8, =0x9880
+ str r7, [r2, r8]
+8:
+ ldr r7, =0x202ffd0
+ str r7, [r5, #DDRPHY_MDLL_CON0]
+
+ ldr r7, =0x1000007f
+ str r7, [r5, #DDRPHY_OFFSETD_CON0]
+
+ ldr r7, =0x7f7f7f7f
+ str r7, [r5, #DDRPHY_OFFSETR_CON0]
+ str r7, [r5, #DDRPHY_OFFSETR_CON1]
+ ldr r7, =0x7f
+ str r7, [r5, #DDRPHY_OFFSETR_CON2]
+
+ ldr r7, =0x7f7f7f7f
+ str r7, [r5, #DDRPHY_OFFSETW_CON0]
+ str r7, [r5, #DDRPHY_OFFSETW_CON1]
+ ldr r7, =0x7f
+ str r7, [r5, #DDRPHY_OFFSETW_CON2]
+
+ ldr r7, [r9, #ANADIG_DIGPROG]
+ and r7, r7, #0x11
+ cmp r7, #0x11
+ bne 20f
+
+ ldr r7, =0x0
+ str r7, [r5, #DDRPHY_CA_WLDSKEW_CON0]
+ ldr r7, =0x60606060
+ str r7, [r5, #DDRPHY_CA_DSKEW_CON0]
+ str r7, [r5, #DDRPHY_CA_DSKEW_CON1]
+ ldr r7, =0x00006060
+ str r7, [r5, #DDRPHY_CA_DSKEW_CON2]
+ b 21f
+20:
+ ldr r7, =0x0
+ str r7, [r5, #DDRPHY_CA_DSKEW_CON0]
+ str r7, [r5, #DDRPHY_CA_DSKEW_CON1]
+ str r7, [r5, #DDRPHY_CA_DSKEW_CON2]
+21:
+ ldr r7, =0x1100007f
+ str r7, [r5, #DDRPHY_OFFSETD_CON0]
+ ldr r7, =0x1000007f
+ str r7, [r5, #DDRPHY_OFFSETD_CON0]
+
+ ldr r7, =0x0
+ str r7, [r4, #DDRC_PWRCTL]
+
+ ldr r6, =0x1
+9:
+ ldr r7, [r4, #DDRC_MRSTAT]
+ and r7, r7, r6
+ cmp r7, r6
+ beq 9b
+
+ ldr r7, =0xf0
+ str r7, [r4, #DDRC_MRCTRL0]
+ ldr r7, =0x820
+ str r7, [r4, #DDRC_MRCTRL1]
+ ldr r7, =0x800000f0
+ str r7, [r4, #DDRC_MRCTRL0]
+
+ ldr r6, =0x1
+10:
+ ldr r7, [r4, #DDRC_MRSTAT]
+ and r7, r7, r6
+ cmp r7, r6
+ beq 10b
+
+ ldr r7, =0x800020
+ str r7, [r4, #DDRC_ZQCTL0]
+
+ ldr r7, =0x0
+ str r7, [r4, #DDRC_DBG1]
+
+ /* enable auto self-refresh */
+ ldr r7, [r4, #DDRC_PWRCTL]
+ orr r7, r7, #(1 << 0)
+ str r7, [r4, #DDRC_PWRCTL]
+
+ .endm
+
+ .macro switch_to_533m
+
+ ldr r7, =0x2
+ str r7, [r4, #DDRC_DBG1]
+
+ ldr r7, =0x78
+ str r7, [r3, #IOMUXC_GPR8]
+ orr r7, r7, #0x100
+ str r7, [r3, #IOMUXC_GPR8]
+
+ ldr r6, =0x30000000
+11:
+ ldr r7, [r4, #DDRC_DBGCAM]
+ and r7, r7, r6
+ cmp r7, r6
+ bne 11b
+
+ ldr r6, =0x1
+12:
+ ldr r7, [r4, #DDRC_MRSTAT]
+ and r7, r7, r6
+ cmp r7, r6
+ beq 12b
+
+ ldr r7, =0x10f0
+ str r7, [r4, #DDRC_MRCTRL0]
+ ldr r7, =0x1
+ str r7, [r4, #DDRC_MRCTRL1]
+ ldr r7, =0x800010f0
+ str r7, [r4, #DDRC_MRCTRL0]
+
+ ldr r7, =0x20
+ str r7, [r4, #DDRC_PWRCTL]
+
+ ldr r6, =0x23
+13:
+ ldr r7, [r4, #DDRC_STAT]
+ and r7, r7, r6
+ cmp r7, r6
+ bne 13b
+
+ ldr r7, =0x03040001
+ str r7, [r4, #DDRC_MSTR]
+
+ ldr r7, =0x40800020
+ str r7, [r4, #DDRC_ZQCTL0]
+
+
+ ldr r7, =0x10210100
+ str r7, [r5, #0x4]
+
+ ldr r7, =0x00040046
+ str r7, [r4, #DDRC_RFSHTMG]
+
+ /* dram root set to from dram main, div by 2 */
+ ldr r7, =0x10000001
+ ldr r8, =0x9880
+ str r7, [r2, r8]
+
+ ldr r7, =0x1010007e
+ str r7, [r5, #DDRPHY_MDLL_CON0]
+
+ ldr r7, =0x10000008
+ str r7, [r5, #DDRPHY_OFFSETD_CON0]
+
+ ldr r7, =0x08080808
+ str r7, [r5, #DDRPHY_OFFSETR_CON0]
+ str r7, [r5, #DDRPHY_OFFSETR_CON1]
+ ldr r7, =0x8
+ str r7, [r5, #DDRPHY_OFFSETR_CON2]
+
+ ldr r7, =0x08080808
+ str r7, [r5, #DDRPHY_OFFSETW_CON0]
+ str r7, [r5, #DDRPHY_OFFSETW_CON1]
+ ldr r7, =0x8
+ str r7, [r5, #DDRPHY_OFFSETW_CON2]
+
+ ldr r7, [r9, #ANADIG_DIGPROG]
+ and r7, r7, #0x11
+ cmp r7, #0x11
+ bne 22f
+
+ ldr r7, =0x40404040
+ str r7, [r5, #DDRPHY_CA_WLDSKEW_CON0]
+ ldr r7, =0x18181818
+ str r7, [r5, #DDRPHY_CA_DSKEW_CON0]
+ str r7, [r5, #DDRPHY_CA_DSKEW_CON1]
+ ldr r7, =0x40401818
+ str r7, [r5, #DDRPHY_CA_DSKEW_CON2]
+ b 23f
+22:
+ ldr r7, =0x0
+ str r7, [r5, #DDRPHY_CA_DSKEW_CON0]
+ str r7, [r5, #DDRPHY_CA_DSKEW_CON1]
+ str r7, [r5, #DDRPHY_CA_DSKEW_CON2]
+23:
+ ldr r7, =0x11000008
+ str r7, [r5, #DDRPHY_OFFSETD_CON0]
+ ldr r7, =0x10000008
+ str r7, [r5, #DDRPHY_OFFSETD_CON0]
+
+ ldr r6, =0x4
+14:
+ ldr r7, [r5, #DDRPHY_MDLL_CON1]
+ and r7, r7, r6
+ cmp r7, r6
+ bne 14b
+
+ ldr r7, =0x1
+ str r7, [r4, #DDRC_RFSHCTL3]
+ ldr r7, =0x3
+ str r7, [r4, #DDRC_RFSHCTL3]
+
+ ldr r7, =0x0
+ str r7, [r4, #DDRC_PWRCTL]
+
+ ldr r6, =0x1
+15:
+ ldr r7, [r4, #DDRC_MRSTAT]
+ and r7, r7, r6
+ cmp r7, r6
+ beq 15b
+
+ ldr r7, =0x10f0
+ str r7, [r4, #DDRC_MRCTRL0]
+ ldr r7, =0x0
+ str r7, [r4, #DDRC_MRCTRL1]
+ ldr r7, =0x800010f0
+ str r7, [r4, #DDRC_MRCTRL0]
+
+ ldr r6, =0x1
+16:
+ ldr r7, [r4, #DDRC_MRSTAT]
+ and r7, r7, r6
+ cmp r7, r6
+ beq 16b
+
+ ldr r7, =0xf0
+ str r7, [r4, #DDRC_MRCTRL0]
+ ldr r7, =0x930
+ str r7, [r4, #DDRC_MRCTRL1]
+ ldr r7, =0x800000f0
+ str r7, [r4, #DDRC_MRCTRL0]
+
+ ldr r7, =0x0
+ str r7, [r4, #DDRC_RFSHCTL3]
+ ldr r7, =0x2
+ str r7, [r4, #DDRC_RFSHCTL3]
+
+ ldr r6, =0x1
+17:
+ ldr r7, [r4, #DDRC_MRSTAT]
+ and r7, r7, r6
+ cmp r7, r6
+ beq 17b
+
+ ldr r7, =0xf0
+ str r7, [r4, #DDRC_MRCTRL0]
+ ldr r7, =0x930
+ str r7, [r4, #DDRC_MRCTRL1]
+ ldr r7, =0x800000f0
+ str r7, [r4, #DDRC_MRCTRL0]
+
+ ldr r6, =0x1
+18:
+ ldr r7, [r4, #DDRC_MRSTAT]
+ and r7, r7, r6
+ cmp r7, r6
+ beq 18b
+
+ ldr r7, =0x20f0
+ str r7, [r4, #DDRC_MRCTRL0]
+ ldr r7, =0x408
+ str r7, [r4, #DDRC_MRCTRL1]
+ ldr r7, =0x800020f0
+ str r7, [r4, #DDRC_MRCTRL0]
+
+ ldr r6, =0x1
+19:
+ ldr r7, [r4, #DDRC_MRSTAT]
+ and r7, r7, r6
+ cmp r7, r6
+ beq 19b
+
+ ldr r7, =0x10f0
+ str r7, [r4, #DDRC_MRCTRL0]
+ ldr r7, =0x4
+ str r7, [r4, #DDRC_MRCTRL1]
+ ldr r7, =0x800010f0
+ str r7, [r4, #DDRC_MRCTRL0]
+
+ ldr r7, =0x0
+ str r7, [r4, #DDRC_DBG1]
+
+ /* enable auto self-refresh */
+ ldr r7, [r4, #DDRC_PWRCTL]
+ orr r7, r7, #(1 << 0)
+ str r7, [r4, #DDRC_PWRCTL]
+
+ .endm
+
+ENTRY(imx7d_ddr3_freq_change)
+ push {r2 - r9}
+
+ /*
+ * To ensure no page table walks occur in DDR, we
+ * have a another page table stored in IRAM that only
+ * contains entries pointing to IRAM, AIPS1 and AIPS2.
+ * We need to set the TTBR1 to the new IRAM TLB.
+ * Do the following steps:
+ * 1. Flush the Branch Target Address Cache (BTAC)
+ * 2. Set TTBR1 to point to IRAM page table.
+ * 3. Disable page table walks in TTBR0 (PD0 = 1)
+ * 4. Set TTBR0.N=1, implying 0-2G is translated by TTBR0
+ * and 2-4G is translated by TTBR1.
+ */
+ ldr r6, =0x0
+ mcr p15, 0, r6, c8, c3, 0
+
+ ldr r6, =iram_tlb_phys_addr
+ ldr r7, [r6]
+
+ /* Disable Branch Prediction, Z bit in SCTLR. */
+ mrc p15, 0, r6, c1, c0, 0
+ bic r6, r6, #0x800
+ mcr p15, 0, r6, c1, c0, 0
+
+ /* Flush the Branch Target Address Cache (BTAC) */
+ ldr r6, =0x0
+ mcr p15, 0, r6, c7, c1, 6
+
+ dsb
+ isb
+ /* Store the IRAM table in TTBR1 */
+ mcr p15, 0, r7, c2, c0, 1
+
+ /* Read TTBCR and set PD0=1, N = 1 */
+ mrc p15, 0, r6, c2, c0, 2
+ orr r6, r6, #0x11
+ mcr p15, 0, r6, c2, c0, 2
+
+ dsb
+ isb
+
+ /* flush the TLB */
+ ldr r6, =0x0
+ mcr p15, 0, r6, c8, c3, 0
+
+ dsb
+ isb
+
+ ldr r2, =IMX_IO_P2V(MX7D_CCM_BASE_ADDR)
+ ldr r3, =IMX_IO_P2V(MX7D_IOMUXC_GPR_BASE_ADDR)
+ ldr r4, =IMX_IO_P2V(MX7D_DDRC_BASE_ADDR)
+ ldr r5, =IMX_IO_P2V(MX7D_DDRC_PHY_BASE_ADDR)
+ ldr r9, =IMX_IO_P2V(MX7D_ANATOP_BASE_ADDR)
+
+ ldr r6, =100000000
+ cmp r0, r6
+ bgt set_to_533m
+
+set_to_below_100m:
+ switch_to_below_100m
+ b done
+
+set_to_533m:
+ switch_to_533m
+ b done
+
+done:
+ /* Enable L1 data cache. */
+ mrc p15, 0, r6, c1, c0, 0
+ orr r6, r6, #0x4
+ mcr p15, 0, r6, c1, c0, 0
+
+ /* Restore the TTBCR */
+ dsb
+ isb
+
+ /* Read TTBCR and set PD0=0, N = 0 */
+ mrc p15, 0, r6, c2, c0, 2
+ bic r6, r6, #0x11
+ mcr p15, 0, r6, c2, c0, 2
+ dsb
+ isb
+
+ /* flush the TLB */
+ ldr r6, =0x0
+ mcr p15, 0, r6, c8, c3, 0
+
+ dsb
+ isb
+
+ /* Enable Branch Prediction, Z bit in SCTLR. */
+ mrc p15, 0, r6, c1, c0, 0
+ orr r6, r6, #0x800
+ mcr p15, 0, r6, c1, c0, 0
+
+ /* Flush the Branch Target Address Cache (BTAC) */
+ ldr r6, =0x0
+ mcr p15, 0, r6, c7, c1, 6
+
+ dsb
+ isb
+
+ nop
+ nop
+ nop
+ nop
+ nop
+
+ nop
+ nop
+ nop
+ nop
+ nop
+
+ nop
+ nop
+ nop
+ nop
+ nop
+
+ nop
+ nop
+ nop
+ nop
+ nop
+
+ nop
+ nop
+ nop
+ nop
+ nop
+
+ /* Restore registers */
+ pop {r2 - r9}
+ mov pc, lr
+ .ltorg
+ENDPROC(imx7d_ddr3_freq_change)
diff --git a/arch/arm/mach-imx/ddrc.c b/arch/arm/mach-imx/ddrc.c
new file mode 100644
index 000000000000..9c7f627d465e
--- /dev/null
+++ b/arch/arm/mach-imx/ddrc.c
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2015 Freescale Semiconductor, Inc.
+ *
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+
+#include "hardware.h"
+
+#define DDRC_MSTR 0x0
+#define BM_DDRC_MSTR_DDR3 0x1
+#define BM_DDRC_MSTR_LPDDR2 0x4
+#define BM_DDRC_MSTR_LPDDR3 0x8
+
+static int ddr_type;
+
+static int imx_ddrc_probe(struct platform_device *pdev)
+{
+ struct device_node *np = pdev->dev.of_node;
+ void __iomem *ddrc_base, *reg;
+ u32 val;
+
+ ddrc_base = of_iomap(np, 0);
+ WARN_ON(!ddrc_base);
+
+ reg = ddrc_base + DDRC_MSTR;
+ /* Get ddr type */
+ val = readl_relaxed(reg);
+ val &= (BM_DDRC_MSTR_DDR3 | BM_DDRC_MSTR_LPDDR2
+ | BM_DDRC_MSTR_LPDDR3);
+
+ switch (val) {
+ case BM_DDRC_MSTR_DDR3:
+ pr_info("DDR type is DDR3!\n");
+ ddr_type = IMX_DDR_TYPE_DDR3;
+ break;
+ case BM_DDRC_MSTR_LPDDR2:
+ pr_info("DDR type is LPDDR2!\n");
+ ddr_type = IMX_DDR_TYPE_LPDDR2;
+ break;
+ case BM_DDRC_MSTR_LPDDR3:
+ pr_info("DDR type is LPDDR3!\n");
+ ddr_type = IMX_DDR_TYPE_LPDDR3;
+ break;
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+int imx_ddrc_get_ddr_type(void)
+{
+ return ddr_type;
+}
+
+static struct of_device_id imx_ddrc_dt_ids[] = {
+ { .compatible = "fsl,imx7-ddrc", },
+ { /* sentinel */ }
+};
+
+static struct platform_driver imx_ddrc_driver = {
+ .driver = {
+ .name = "imx-ddrc",
+ .owner = THIS_MODULE,
+ .of_match_table = imx_ddrc_dt_ids,
+ },
+ .probe = imx_ddrc_probe,
+};
+
+static int __init imx_ddrc_init(void)
+{
+ return platform_driver_register(&imx_ddrc_driver);
+}
+postcore_initcall(imx_ddrc_init);
diff --git a/arch/arm/mach-imx/gpc.c b/arch/arm/mach-imx/gpc.c
index de535cb679b3..e0ab6807ef54 100644
--- a/arch/arm/mach-imx/gpc.c
+++ b/arch/arm/mach-imx/gpc.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2011-2013 Freescale Semiconductor, Inc.
+ * Copyright 2011-2016 Freescale Semiconductor, Inc.
* Copyright 2011 Linaro Ltd.
*
* The code contained herein is licensed under the GNU General Public
@@ -20,19 +20,157 @@
#include "common.h"
#include "hardware.h"
+#define GPC_CNTR 0x000
+#define GPC_CNTR_L2_PGE 22
+
#define GPC_IMR1 0x008
+#define GPC_PGC_MF_PDN 0x220
#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 GPC_M4_LPSR 0x2c
+#define GPC_M4_LPSR_M4_SLEEPING_SHIFT 4
+#define GPC_M4_LPSR_M4_SLEEPING_MASK 0x1
+#define GPC_M4_LPSR_M4_SLEEP_HOLD_REQ_MASK 0x1
+#define GPC_M4_LPSR_M4_SLEEP_HOLD_REQ_SHIFT 0
+#define GPC_M4_LPSR_M4_SLEEP_HOLD_ACK_MASK 0x1
+#define GPC_M4_LPSR_M4_SLEEP_HOLD_ACK_SHIFT 1
+
+#define GPC_PGC_CPU_SW_SHIFT 0
+#define GPC_PGC_CPU_SW_MASK 0x3f
+#define GPC_PGC_CPU_SW2ISO_SHIFT 8
+#define GPC_PGC_CPU_SW2ISO_MASK 0x3f
#define IMR_NUM 4
#define GPC_MAX_IRQS (IMR_NUM * 32)
+/* for irq #74 and #75 */
+#define GPC_USB_VBUS_WAKEUP_IRQ_MASK 0xc00
+
+/* for irq #150 and #151 */
+#define GPC_ENET_WAKEUP_IRQ_MASK 0xC00000
+
static void __iomem *gpc_base;
static u32 gpc_wake_irqs[IMR_NUM];
static u32 gpc_saved_imrs[IMR_NUM];
+static u32 gpc_mf_irqs[IMR_NUM];
+static u32 gpc_mf_request_on[IMR_NUM];
+static DEFINE_SPINLOCK(gpc_lock);
+
+/* implemented in drivers/soc/imx/gpc.c */
+extern void _imx6_pm_pu_power_off(void);
+extern void _imx6_pm_pu_power_on(void);
+
+void imx_gpc_add_m4_wake_up_irq(u32 hwirq, bool enable)
+{
+ unsigned int idx = hwirq / 32;
+ unsigned long flags;
+ u32 mask;
+
+ /* Sanity check for SPI irq */
+ if (hwirq < 32)
+ return;
+
+ mask = 1 << hwirq % 32;
+ spin_lock_irqsave(&gpc_lock, flags);
+ gpc_wake_irqs[idx] = enable ? gpc_wake_irqs[idx] | mask :
+ gpc_wake_irqs[idx] & ~mask;
+ spin_unlock_irqrestore(&gpc_lock, flags);
+}
+
+void imx_gpc_hold_m4_in_sleep(void)
+{
+ int val;
+ unsigned long timeout = jiffies + msecs_to_jiffies(500);
+
+ /* wait M4 in wfi before asserting hold request */
+ while (!imx_gpc_is_m4_sleeping())
+ if (time_after(jiffies, timeout))
+ pr_err("M4 is NOT in expected sleep!\n");
+
+ val = readl_relaxed(gpc_base + GPC_M4_LPSR);
+ val &= ~(GPC_M4_LPSR_M4_SLEEP_HOLD_REQ_MASK <<
+ GPC_M4_LPSR_M4_SLEEP_HOLD_REQ_SHIFT);
+ writel_relaxed(val, gpc_base + GPC_M4_LPSR);
+
+ timeout = jiffies + msecs_to_jiffies(500);
+ while (readl_relaxed(gpc_base + GPC_M4_LPSR)
+ & (GPC_M4_LPSR_M4_SLEEP_HOLD_ACK_MASK <<
+ GPC_M4_LPSR_M4_SLEEP_HOLD_ACK_SHIFT))
+ if (time_after(jiffies, timeout))
+ pr_err("Wait M4 hold ack timeout!\n");
+}
+
+void imx_gpc_release_m4_in_sleep(void)
+{
+ int val;
+
+ val = readl_relaxed(gpc_base + GPC_M4_LPSR);
+ val |= GPC_M4_LPSR_M4_SLEEP_HOLD_REQ_MASK <<
+ GPC_M4_LPSR_M4_SLEEP_HOLD_REQ_SHIFT;
+ writel_relaxed(val, gpc_base + GPC_M4_LPSR);
+}
+
+unsigned int imx_gpc_is_m4_sleeping(void)
+{
+ if (readl_relaxed(gpc_base + GPC_M4_LPSR) &
+ (GPC_M4_LPSR_M4_SLEEPING_MASK <<
+ GPC_M4_LPSR_M4_SLEEPING_SHIFT))
+ return 1;
+
+ return 0;
+}
+
+bool imx_gpc_usb_wakeup_enabled(void)
+{
+ if (!(cpu_is_imx6sx() || cpu_is_imx6ul() || cpu_is_imx6ull()
+ || cpu_is_imx6sll()))
+ return false;
+
+ /*
+ * for SoC later than i.MX6SX, USB vbus wakeup
+ * only needs weak 2P5 on, stop_mode_config is
+ * NOT needed, so we check if is USB vbus wakeup
+ * is enabled(assume irq #74 and #75) to decide
+ * if to keep weak 2P5 on.
+ */
+ if (gpc_wake_irqs[1] & GPC_USB_VBUS_WAKEUP_IRQ_MASK)
+ return true;
+
+ return false;
+}
+
+bool imx_gpc_enet_wakeup_enabled(void)
+{
+ if (!cpu_is_imx6q())
+ return false;
+
+ if (gpc_wake_irqs[3] & GPC_ENET_WAKEUP_IRQ_MASK)
+ return true;
+
+ return false;
+}
+
+unsigned int imx_gpc_is_mf_mix_off(void)
+{
+ return readl_relaxed(gpc_base + GPC_PGC_MF_PDN);
+}
+
+static void imx_gpc_mf_mix_off(void)
+{
+ int i;
+
+ for (i = 0; i < IMR_NUM; i++)
+ if (((gpc_wake_irqs[i] | gpc_mf_request_on[i]) &
+ gpc_mf_irqs[i]) != 0)
+ return;
+
+ pr_info("Turn off M/F mix!\n");
+ /* turn off mega/fast mix */
+ writel_relaxed(0x1, gpc_base + GPC_PGC_MF_PDN);
+}
void imx_gpc_set_arm_power_up_timing(u32 sw2iso, u32 sw)
{
@@ -56,6 +194,14 @@ void imx_gpc_pre_suspend(bool arm_power_off)
void __iomem *reg_imr1 = gpc_base + GPC_IMR1;
int i;
+ if (cpu_is_imx6q() && imx_get_soc_revision() >= IMX_CHIP_REVISION_2_0)
+ _imx6_pm_pu_power_off();
+
+ /* power down the mega-fast power domain */
+ if ((cpu_is_imx6sx() || cpu_is_imx6ul() || cpu_is_imx6ull()
+ || cpu_is_imx6sll()) && arm_power_off)
+ imx_gpc_mf_mix_off();
+
/* Tell GPC to power off ARM core when suspend */
if (arm_power_off)
imx_gpc_set_arm_power_in_lpm(arm_power_off);
@@ -71,8 +217,15 @@ void imx_gpc_post_resume(void)
void __iomem *reg_imr1 = gpc_base + GPC_IMR1;
int i;
+ if (cpu_is_imx6q() && imx_get_soc_revision() >= IMX_CHIP_REVISION_2_0)
+ _imx6_pm_pu_power_on();
+
/* Keep ARM core powered on for other low-power modes */
imx_gpc_set_arm_power_in_lpm(false);
+ /* Keep M/F mix powered on for other low-power modes */
+ if (cpu_is_imx6sx() || cpu_is_imx6ul() || cpu_is_imx6ull()
+ || cpu_is_imx6sll())
+ writel_relaxed(0x0, gpc_base + GPC_PGC_MF_PDN);
for (i = 0; i < IMR_NUM; i++)
writel_relaxed(gpc_saved_imrs[i], reg_imr1 + i * 4);
@@ -81,11 +234,14 @@ void imx_gpc_post_resume(void)
static int imx_gpc_irq_set_wake(struct irq_data *d, unsigned int on)
{
unsigned int idx = d->hwirq / 32;
+ unsigned long flags;
u32 mask;
mask = 1 << d->hwirq % 32;
+ spin_lock_irqsave(&gpc_lock, flags);
gpc_wake_irqs[idx] = on ? gpc_wake_irqs[idx] | mask :
gpc_wake_irqs[idx] & ~mask;
+ spin_unlock_irqrestore(&gpc_lock, flags);
/*
* Do *not* call into the parent, as the GIC doesn't have any
@@ -217,11 +373,78 @@ static const struct irq_domain_ops imx_gpc_domain_ops = {
.free = irq_domain_free_irqs_common,
};
+int imx_gpc_mf_power_on(unsigned int irq, unsigned int on)
+{
+ struct irq_desc *d = irq_to_desc(irq);
+ unsigned int idx = d->irq_data.hwirq / 32;
+ unsigned long flags;
+ u32 mask;
+
+ mask = 1 << (d->irq_data.hwirq % 32);
+ spin_lock_irqsave(&gpc_lock, flags);
+ gpc_mf_request_on[idx] = on ? gpc_mf_request_on[idx] | mask :
+ gpc_mf_request_on[idx] & ~mask;
+ spin_unlock_irqrestore(&gpc_lock, flags);
+
+ return 0;
+}
+
+int imx_gpc_mf_request_on(unsigned int irq, unsigned int on)
+{
+ if (cpu_is_imx6sx() || cpu_is_imx6ul() || cpu_is_imx6ull()
+ || cpu_is_imx6sll())
+ return imx_gpc_mf_power_on(irq, on);
+ else if (cpu_is_imx7d())
+ return imx_gpcv2_mf_power_on(irq, on);
+ else
+ return 0;
+}
+EXPORT_SYMBOL_GPL(imx_gpc_mf_request_on);
+
+void imx_gpc_switch_pupscr_clk(bool flag)
+{
+ static u32 pupscr_sw2iso, pupscr_sw;
+ u32 ratio, pupscr = readl_relaxed(gpc_base + GPC_PGC_CPU_PUPSCR);
+
+ if (flag) {
+ /* save the init clock setting IPG/2048 for IPG@66Mhz */
+ pupscr_sw2iso = (pupscr >> GPC_PGC_CPU_SW2ISO_SHIFT) &
+ GPC_PGC_CPU_SW2ISO_MASK;
+ pupscr_sw = (pupscr >> GPC_PGC_CPU_SW_SHIFT) &
+ GPC_PGC_CPU_SW_MASK;
+ /*
+ * i.MX6UL TO1.0 ARM power up uses IPG/2048 as clock source,
+ * from TO1.1, PGC_CPU_PUPSCR bit [5] is re-defined to switch
+ * clock to IPG/32, enable this bit to speed up the ARM power
+ * up process in low power idle case(IPG@1.5Mhz). So the sw and
+ * sw2iso need to be adjusted as below:
+ * sw_new(sw2iso_new) = (2048 * 1.5 / 66 * 32) * sw(sw2iso)
+ */
+ ratio = 3072 / (66 * 32);
+ pupscr &= ~(GPC_PGC_CPU_SW_MASK << GPC_PGC_CPU_SW_SHIFT |
+ GPC_PGC_CPU_SW2ISO_MASK << GPC_PGC_CPU_SW2ISO_SHIFT);
+ pupscr |= (ratio * pupscr_sw + 1) << GPC_PGC_CPU_SW_SHIFT |
+ 1 << 5 | (ratio * pupscr_sw2iso + 1) <<
+ GPC_PGC_CPU_SW2ISO_SHIFT;
+ writel_relaxed(pupscr, gpc_base + GPC_PGC_CPU_PUPSCR);
+ } else {
+ /* restore back after exit from low power idle */
+ pupscr &= ~(GPC_PGC_CPU_SW_MASK << GPC_PGC_CPU_SW_SHIFT |
+ GPC_PGC_CPU_SW2ISO_MASK << GPC_PGC_CPU_SW2ISO_SHIFT);
+ pupscr |= pupscr_sw << GPC_PGC_CPU_SW_SHIFT |
+ pupscr_sw2iso << GPC_PGC_CPU_SW2ISO_SHIFT;
+ writel_relaxed(pupscr, gpc_base + GPC_PGC_CPU_PUPSCR);
+ }
+}
+
static int __init imx_gpc_init(struct device_node *node,
struct device_node *parent)
{
struct irq_domain *parent_domain, *domain;
int i;
+ u32 val;
+ u32 cpu_pupscr_sw2iso, cpu_pupscr_sw;
+ u32 cpu_pdnscr_iso2sw, cpu_pdnscr_iso;
if (!parent) {
pr_err("%pOF: no parent, giving up\n", node);
@@ -250,12 +473,70 @@ static int __init imx_gpc_init(struct device_node *node,
for (i = 0; i < IMR_NUM; i++)
writel_relaxed(~0, gpc_base + GPC_IMR1 + i * 4);
+ /* Read supported wakeup source in M/F domain */
+ if (cpu_is_imx6sx() || cpu_is_imx6ul() || cpu_is_imx6ull()
+ || cpu_is_imx6sll()) {
+ of_property_read_u32_index(node, "fsl,mf-mix-wakeup-irq", 0,
+ &gpc_mf_irqs[0]);
+ of_property_read_u32_index(node, "fsl,mf-mix-wakeup-irq", 1,
+ &gpc_mf_irqs[1]);
+ of_property_read_u32_index(node, "fsl,mf-mix-wakeup-irq", 2,
+ &gpc_mf_irqs[2]);
+ of_property_read_u32_index(node, "fsl,mf-mix-wakeup-irq", 3,
+ &gpc_mf_irqs[3]);
+ if (!(gpc_mf_irqs[0] | gpc_mf_irqs[1] |
+ gpc_mf_irqs[2] | gpc_mf_irqs[3]))
+ pr_info("No wakeup source in Mega/Fast domain found!\n");
+ }
+
+ /* clear the L2_PGE bit on i.MX6SLL */
+ if (cpu_is_imx6sll()) {
+ val = readl_relaxed(gpc_base + GPC_CNTR);
+ val &= ~(1 << GPC_CNTR_L2_PGE);
+ writel_relaxed(val, gpc_base + GPC_CNTR);
+ }
+
/*
* Clear the OF_POPULATED flag set in of_irq_init so that
* later the GPC power domain driver will not be skipped.
*/
of_node_clear_flag(node, OF_POPULATED);
+ /*
+ * If there are CPU isolation timing settings in dts,
+ * update them according to dts, otherwise, keep them
+ * with default value in registers.
+ */
+ cpu_pupscr_sw2iso = cpu_pupscr_sw =
+ cpu_pdnscr_iso2sw = cpu_pdnscr_iso = 0;
+
+ /* Read CPU isolation setting for GPC */
+ of_property_read_u32(node, "fsl,cpu_pupscr_sw2iso", &cpu_pupscr_sw2iso);
+ of_property_read_u32(node, "fsl,cpu_pupscr_sw", &cpu_pupscr_sw);
+ of_property_read_u32(node, "fsl,cpu_pdnscr_iso2sw", &cpu_pdnscr_iso2sw);
+ of_property_read_u32(node, "fsl,cpu_pdnscr_iso", &cpu_pdnscr_iso);
+
+ /* Return if no property found in dtb */
+ if ((cpu_pupscr_sw2iso | cpu_pupscr_sw
+ | cpu_pdnscr_iso2sw | cpu_pdnscr_iso) == 0)
+ return 0;
+
+ /* Update CPU PUPSCR timing if it is defined in dts */
+ val = readl_relaxed(gpc_base + GPC_PGC_CPU_PUPSCR);
+ val &= ~(GPC_PGC_CPU_SW2ISO_MASK << GPC_PGC_CPU_SW2ISO_SHIFT);
+ val &= ~(GPC_PGC_CPU_SW_MASK << GPC_PGC_CPU_SW_SHIFT);
+ val |= cpu_pupscr_sw2iso << GPC_PGC_CPU_SW2ISO_SHIFT;
+ val |= cpu_pupscr_sw << GPC_PGC_CPU_SW_SHIFT;
+ writel_relaxed(val, gpc_base + GPC_PGC_CPU_PUPSCR);
+
+ /* Update CPU PDNSCR timing if it is defined in dts */
+ val = readl_relaxed(gpc_base + GPC_PGC_CPU_PDNSCR);
+ val &= ~(GPC_PGC_CPU_SW2ISO_MASK << GPC_PGC_CPU_SW2ISO_SHIFT);
+ val &= ~(GPC_PGC_CPU_SW_MASK << GPC_PGC_CPU_SW_SHIFT);
+ val |= cpu_pdnscr_iso2sw << GPC_PGC_CPU_SW2ISO_SHIFT;
+ val |= cpu_pdnscr_iso << GPC_PGC_CPU_SW_SHIFT;
+ writel_relaxed(val, gpc_base + GPC_PGC_CPU_PDNSCR);
+
return 0;
}
IRQCHIP_DECLARE(imx_gpc, "fsl,imx6q-gpc", imx_gpc_init);
diff --git a/arch/arm/mach-imx/gpcv2.c b/arch/arm/mach-imx/gpcv2.c
new file mode 100644
index 000000000000..3e8ab91cb97f
--- /dev/null
+++ b/arch/arm/mach-imx/gpcv2.c
@@ -0,0 +1,851 @@
+/*
+ * Copyright (C) 2015-2016 Freescale Semiconductor, Inc.
+ *
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/irqchip/arm-gic.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/platform_device.h>
+#include <linux/pm_domain.h>
+#include <linux/regulator/consumer.h>
+
+#include "common.h"
+#include "hardware.h"
+
+#define IMR_NUM 4
+#define GPC_MAX_IRQS (IMR_NUM * 32)
+#define GPC_LPCR_A7_BSC 0x0
+#define GPC_LPCR_A7_AD 0x4
+#define GPC_LPCR_M4 0x8
+#define GPC_SLPCR 0x14
+#define GPC_MLPCR 0x20
+#define GPC_PGC_ACK_SEL_A7 0x24
+#define GPC_MISC 0x2c
+#define GPC_IMR1_CORE0 0x30
+#define GPC_IMR1_CORE1 0x40
+#define GPC_IMR1_M4 0x50
+#define GPC_SLOT0_CFG 0xb0
+#define GPC_PGC_CPU_MAPPING 0xec
+#define GPC_CPU_PGC_SW_PUP_REQ 0xf0
+#define GPC_PU_PGC_SW_PUP_REQ 0xf8
+#define GPC_CPU_PGC_SW_PDN_REQ 0xfc
+#define GPC_PU_PGC_SW_PDN_REQ 0x104
+#define GPC_GTOR 0x124
+#define GPC_PGC_C0 0x800
+#define GPC_PGC_C0_PUPSCR 0x804
+#define GPC_PGC_SCU_TIMING 0x890
+#define GPC_PGC_C1 0x840
+#define GPC_PGC_C1_PUPSCR 0x844
+#define GPC_PGC_SCU 0x880
+#define GPC_PGC_FM 0xa00
+
+#define BM_LPCR_A7_BSC_IRQ_SRC_A7_WAKEUP 0x70000000
+#define BM_LPCR_A7_BSC_CPU_CLK_ON_LPM 0x4000
+#define BM_LPCR_A7_BSC_LPM1 0xc
+#define BM_LPCR_A7_BSC_LPM0 0x3
+#define BP_LPCR_A7_BSC_LPM1 2
+#define BP_LPCR_A7_BSC_LPM0 0
+#define BM_LPCR_M4_MASK_DSM_TRIGGER 0x80000000
+#define BM_SLPCR_EN_DSM 0x80000000
+#define BM_SLPCR_RBC_EN 0x40000000
+#define BM_SLPCR_REG_BYPASS_COUNT 0x3f000000
+#define BM_SLPCR_VSTBY 0x4
+#define BM_SLPCR_SBYOS 0x2
+#define BM_SLPCR_BYPASS_PMIC_READY 0x1
+#define BM_SLPCR_EN_A7_FASTWUP_WAIT_MODE 0x10000
+#define BM_LPCR_A7_AD_L2PGE 0x10000
+#define BM_LPCR_A7_AD_EN_C1_PUP 0x800
+#define BM_LPCR_A7_AD_EN_C1_IRQ_PUP 0x400
+#define BM_LPCR_A7_AD_EN_C0_PUP 0x200
+#define BM_LPCR_A7_AD_EN_C0_IRQ_PUP 0x100
+#define BM_LPCR_A7_AD_EN_PLAT_PDN 0x10
+#define BM_LPCR_A7_AD_EN_C1_PDN 0x8
+#define BM_LPCR_A7_AD_EN_C1_WFI_PDN 0x4
+#define BM_LPCR_A7_AD_EN_C0_PDN 0x2
+#define BM_LPCR_A7_AD_EN_C0_WFI_PDN 0x1
+
+#define BM_CPU_PGC_SW_PDN_PUP_REQ_CORE1_A7 0x2
+#define BM_GPC_PGC_PCG 0x1
+#define BM_GPC_PGC_CORE_PUPSCR 0x7fff80
+
+#define BM_GPC_PGC_ACK_SEL_A7_DUMMY_PUP_ACK 0x80000000
+#define BM_GPC_PGC_ACK_SEL_A7_DUMMY_PDN_ACK 0x8000
+#define BM_GPC_MLPCR_MEMLP_CTL_DIS 0x1
+
+#define BP_LPCR_A7_BSC_IRQ_SRC 28
+
+#define MAX_SLOT_NUMBER 10
+#define A7_LPM_WAIT 0x5
+#define A7_LPM_STOP 0xa
+
+enum imx_gpc_slot {
+ CORE0_A7,
+ CORE1_A7,
+ SCU_A7,
+ FAST_MEGA_MIX,
+ MIPI_PHY,
+ PCIE_PHY,
+ USB_OTG1_PHY,
+ USB_OTG2_PHY,
+ USB_HSIC_PHY,
+ CORE0_M4,
+};
+
+static void __iomem *gpc_base;
+static u32 gpcv2_wake_irqs[IMR_NUM];
+static u32 gpcv2_saved_imrs[IMR_NUM];
+static u32 gpcv2_saved_imrs_m4[IMR_NUM];
+static u32 gpcv2_mf_irqs[IMR_NUM];
+static u32 gpcv2_mf_request_on[IMR_NUM];
+static DEFINE_SPINLOCK(gpcv2_lock);
+
+void imx_gpcv2_add_m4_wake_up_irq(u32 hwirq, bool enable)
+{
+ unsigned int idx = hwirq / 32;
+ unsigned long flags;
+ u32 mask;
+
+ /* Sanity check for SPI irq */
+ if (hwirq < 32)
+ return;
+
+ mask = 1 << hwirq % 32;
+ spin_lock_irqsave(&gpcv2_lock, flags);
+ gpcv2_wake_irqs[idx] = enable ? gpcv2_wake_irqs[idx] | mask :
+ gpcv2_wake_irqs[idx] & ~mask;
+ spin_unlock_irqrestore(&gpcv2_lock, flags);
+}
+
+static int imx_gpcv2_irq_set_wake(struct irq_data *d, unsigned int on)
+{
+ unsigned int idx = d->hwirq / 32;
+ unsigned long flags;
+ u32 mask;
+
+ BUG_ON(idx >= IMR_NUM);
+
+ mask = 1 << d->hwirq % 32;
+ spin_lock_irqsave(&gpcv2_lock, flags);
+ gpcv2_wake_irqs[idx] = on ? gpcv2_wake_irqs[idx] | mask :
+ gpcv2_wake_irqs[idx] & ~mask;
+ spin_unlock_irqrestore(&gpcv2_lock, flags);
+
+ return 0;
+}
+
+void imx_gpcv2_mask_all(void)
+{
+ void __iomem *reg_imr1 = gpc_base + GPC_IMR1_CORE0;
+ int i;
+
+ for (i = 0; i < IMR_NUM; i++) {
+ gpcv2_saved_imrs[i] = readl_relaxed(reg_imr1 + i * 4);
+ writel_relaxed(~0, reg_imr1 + i * 4);
+ }
+}
+
+void imx_gpcv2_restore_all(void)
+{
+ void __iomem *reg_imr1 = gpc_base + GPC_IMR1_CORE0;
+ int i;
+
+ for (i = 0; i < IMR_NUM; i++)
+ writel_relaxed(gpcv2_saved_imrs[i], reg_imr1 + i * 4);
+}
+
+void imx_gpcv2_hwirq_unmask(unsigned int hwirq)
+{
+ void __iomem *reg;
+ u32 val;
+
+ reg = gpc_base + GPC_IMR1_CORE0 + (hwirq / 32) * 4;
+ val = readl_relaxed(reg);
+ val &= ~(1 << hwirq % 32);
+ writel_relaxed(val, reg);
+}
+
+void imx_gpcv2_hwirq_mask(unsigned int hwirq)
+{
+ void __iomem *reg;
+ u32 val;
+
+ reg = gpc_base + GPC_IMR1_CORE0 + (hwirq / 32) * 4;
+ val = readl_relaxed(reg);
+ val |= 1 << (hwirq % 32);
+ writel_relaxed(val, reg);
+}
+
+static void imx_gpcv2_irq_unmask(struct irq_data *d)
+{
+ imx_gpcv2_hwirq_unmask(d->hwirq);
+ irq_chip_unmask_parent(d);
+}
+
+static void imx_gpcv2_irq_mask(struct irq_data *d)
+{
+ imx_gpcv2_hwirq_mask(d->hwirq);
+ irq_chip_mask_parent(d);
+}
+
+void imx_gpcv2_set_slot_ack(u32 index, enum imx_gpc_slot m_core,
+ bool mode, bool ack)
+{
+ u32 val;
+
+ if (index >= MAX_SLOT_NUMBER)
+ pr_err("Invalid slot index!\n");
+ /* set slot */
+ writel_relaxed(readl_relaxed(gpc_base + GPC_SLOT0_CFG + index * 4) |
+ ((mode + 1) << (m_core * 2)),
+ gpc_base + GPC_SLOT0_CFG + index * 4);
+
+ if (ack) {
+ /* set ack */
+ val = readl_relaxed(gpc_base + GPC_PGC_ACK_SEL_A7);
+ /* clear dummy ack */
+ val &= ~(1 << (15 + (mode ? 16 : 0)));
+ val |= 1 << (m_core + (mode ? 16 : 0));
+ writel_relaxed(val, gpc_base + GPC_PGC_ACK_SEL_A7);
+ }
+}
+
+void imx_gpcv2_set_lpm_mode(enum mxc_cpu_pwr_mode mode)
+{
+ unsigned long flags;
+ u32 val1, val2;
+
+ spin_lock_irqsave(&gpcv2_lock, flags);
+
+ val1 = readl_relaxed(gpc_base + GPC_LPCR_A7_BSC);
+ val2 = readl_relaxed(gpc_base + GPC_SLPCR);
+
+ /* all cores' LPM settings must be same */
+ val1 &= ~(BM_LPCR_A7_BSC_LPM0 | BM_LPCR_A7_BSC_LPM1);
+
+ val1 |= BM_LPCR_A7_BSC_CPU_CLK_ON_LPM;
+
+ val2 &= ~(BM_SLPCR_EN_DSM | BM_SLPCR_VSTBY | BM_SLPCR_RBC_EN |
+ BM_SLPCR_SBYOS | BM_SLPCR_BYPASS_PMIC_READY);
+ /*
+ * GPC: When improper low-power sequence is used,
+ * the SoC enters low power mode before the ARM core executes WFI.
+ *
+ * Software workaround:
+ * 1) Software should trigger IRQ #32 (IOMUX) to be always pending
+ * by setting IOMUX_GPR1_IRQ.
+ * 2) Software should then unmask IRQ #32 in GPC before setting GPC
+ * Low-Power mode.
+ * 3) Software should mask IRQ #32 right after GPC Low-Power mode
+ * is set.
+ */
+ switch (mode) {
+ case WAIT_CLOCKED:
+ imx_gpcv2_hwirq_unmask(0);
+ break;
+ case WAIT_UNCLOCKED:
+ val1 |= A7_LPM_WAIT << BP_LPCR_A7_BSC_LPM0;
+ val1 &= ~BM_LPCR_A7_BSC_CPU_CLK_ON_LPM;
+ imx_gpcv2_hwirq_mask(0);
+ break;
+ case STOP_POWER_ON:
+ val1 |= A7_LPM_STOP << BP_LPCR_A7_BSC_LPM0;
+ val1 &= ~BM_LPCR_A7_BSC_CPU_CLK_ON_LPM;
+ val2 |= BM_SLPCR_EN_DSM;
+ val2 |= BM_SLPCR_RBC_EN;
+ val2 |= BM_SLPCR_BYPASS_PMIC_READY;
+ imx_gpcv2_hwirq_mask(0);
+ break;
+ case STOP_POWER_OFF:
+ val1 |= A7_LPM_STOP << BP_LPCR_A7_BSC_LPM0;
+ val1 &= ~BM_LPCR_A7_BSC_CPU_CLK_ON_LPM;
+ val2 |= BM_SLPCR_EN_DSM;
+ val2 |= BM_SLPCR_RBC_EN;
+ val2 |= BM_SLPCR_SBYOS;
+ val2 |= BM_SLPCR_VSTBY;
+ val2 |= BM_SLPCR_BYPASS_PMIC_READY;
+ imx_gpcv2_hwirq_mask(0);
+ break;
+ default:
+ return;
+ }
+ writel_relaxed(val1, gpc_base + GPC_LPCR_A7_BSC);
+ writel_relaxed(val2, gpc_base + GPC_SLPCR);
+
+ spin_unlock_irqrestore(&gpcv2_lock, flags);
+}
+
+void imx_gpcv2_set_plat_power_gate_by_lpm(bool pdn)
+{
+ u32 val = readl_relaxed(gpc_base + GPC_LPCR_A7_AD);
+
+ val &= ~(BM_LPCR_A7_AD_EN_PLAT_PDN | BM_LPCR_A7_AD_L2PGE);
+ if (pdn)
+ val |= BM_LPCR_A7_AD_EN_PLAT_PDN | BM_LPCR_A7_AD_L2PGE;
+
+ writel_relaxed(val, gpc_base + GPC_LPCR_A7_AD);
+}
+
+void imx_gpcv2_set_m_core_pgc(bool enable, u32 offset)
+{
+ u32 val = readl_relaxed(gpc_base + offset) & (~BM_GPC_PGC_PCG);
+
+ if (enable)
+ val |= BM_GPC_PGC_PCG;
+
+ writel_relaxed(val, gpc_base + offset);
+}
+
+void imx_gpcv2_set_core1_pdn_pup_by_software(bool pdn)
+{
+ u32 val = readl_relaxed(gpc_base + (pdn ?
+ GPC_CPU_PGC_SW_PDN_REQ : GPC_CPU_PGC_SW_PUP_REQ));
+
+ imx_gpcv2_set_m_core_pgc(true, GPC_PGC_C1);
+ val |= BM_CPU_PGC_SW_PDN_PUP_REQ_CORE1_A7;
+ writel_relaxed(val, gpc_base + (pdn ?
+ GPC_CPU_PGC_SW_PDN_REQ : GPC_CPU_PGC_SW_PUP_REQ));
+
+ while ((readl_relaxed(gpc_base + (pdn ?
+ GPC_CPU_PGC_SW_PDN_REQ : GPC_CPU_PGC_SW_PUP_REQ)) &
+ BM_CPU_PGC_SW_PDN_PUP_REQ_CORE1_A7) != 0)
+ ;
+ imx_gpcv2_set_m_core_pgc(false, GPC_PGC_C1);
+}
+
+void imx_gpcv2_set_cpu_power_gate_by_wfi(u32 cpu, bool pdn)
+{
+ unsigned long flags;
+ u32 val;
+
+ spin_lock_irqsave(&gpcv2_lock, flags);
+ val = readl_relaxed(gpc_base + GPC_LPCR_A7_AD);
+
+ if (cpu == 0) {
+ if (pdn) {
+ imx_gpcv2_set_m_core_pgc(true, GPC_PGC_C0);
+ val |= BM_LPCR_A7_AD_EN_C0_WFI_PDN |
+ BM_LPCR_A7_AD_EN_C0_IRQ_PUP;
+ } else {
+ imx_gpcv2_set_m_core_pgc(false, GPC_PGC_C0);
+ val &= ~(BM_LPCR_A7_AD_EN_C0_WFI_PDN |
+ BM_LPCR_A7_AD_EN_C0_IRQ_PUP);
+ }
+ }
+ if (cpu == 1) {
+ if (pdn) {
+ imx_gpcv2_set_m_core_pgc(true, GPC_PGC_C1);
+ val |= BM_LPCR_A7_AD_EN_C1_WFI_PDN |
+ BM_LPCR_A7_AD_EN_C1_IRQ_PUP;
+ } else {
+ imx_gpcv2_set_m_core_pgc(false, GPC_PGC_C1);
+ val &= ~(BM_LPCR_A7_AD_EN_C1_WFI_PDN |
+ BM_LPCR_A7_AD_EN_C1_IRQ_PUP);
+ }
+ }
+ writel_relaxed(val, gpc_base + GPC_LPCR_A7_AD);
+ spin_unlock_irqrestore(&gpcv2_lock, flags);
+}
+
+void imx_gpcv2_set_cpu_power_gate_by_lpm(u32 cpu, bool pdn)
+{
+ unsigned long flags;
+ u32 val;
+
+ spin_lock_irqsave(&gpcv2_lock, flags);
+
+ val = readl_relaxed(gpc_base + GPC_LPCR_A7_AD);
+ if (cpu == 0) {
+ if (pdn)
+ val |= BM_LPCR_A7_AD_EN_C0_PDN |
+ BM_LPCR_A7_AD_EN_C0_PUP;
+ else
+ val &= ~(BM_LPCR_A7_AD_EN_C0_PDN |
+ BM_LPCR_A7_AD_EN_C0_PUP);
+ }
+ if (cpu == 1) {
+ if (pdn)
+ val |= BM_LPCR_A7_AD_EN_C1_PDN |
+ BM_LPCR_A7_AD_EN_C1_PUP;
+ else
+ val &= ~(BM_LPCR_A7_AD_EN_C1_PDN |
+ BM_LPCR_A7_AD_EN_C1_PUP);
+ }
+
+ writel_relaxed(val, gpc_base + GPC_LPCR_A7_AD);
+ spin_unlock_irqrestore(&gpcv2_lock, flags);
+}
+
+void imx_gpcv2_set_cpu_power_gate_in_idle(bool pdn)
+{
+ unsigned long flags;
+ u32 cpu;
+
+ for_each_possible_cpu(cpu)
+ imx_gpcv2_set_cpu_power_gate_by_lpm(cpu, pdn);
+
+ spin_lock_irqsave(&gpcv2_lock, flags);
+
+ imx_gpcv2_set_m_core_pgc(pdn, GPC_PGC_C0);
+ if (num_online_cpus() > 1)
+ imx_gpcv2_set_m_core_pgc(pdn, GPC_PGC_C1);
+ imx_gpcv2_set_m_core_pgc(pdn, GPC_PGC_SCU);
+ imx_gpcv2_set_plat_power_gate_by_lpm(pdn);
+
+ if (pdn) {
+ imx_gpcv2_set_slot_ack(0, CORE0_A7, false, false);
+ if (num_online_cpus() > 1)
+ imx_gpcv2_set_slot_ack(2, CORE1_A7, false, false);
+ imx_gpcv2_set_slot_ack(3, SCU_A7, false, true);
+ imx_gpcv2_set_slot_ack(6, SCU_A7, true, false);
+ if (num_online_cpus() > 1)
+ imx_gpcv2_set_slot_ack(6, CORE1_A7, true, false);
+ imx_gpcv2_set_slot_ack(6, CORE0_A7, true, true);
+ } else {
+ writel_relaxed(0x0, gpc_base + GPC_SLOT0_CFG + 0 * 0x4);
+ writel_relaxed(0x0, gpc_base + GPC_SLOT0_CFG + 2 * 0x4);
+ writel_relaxed(0x0, gpc_base + GPC_SLOT0_CFG + 3 * 0x4);
+ writel_relaxed(0x0, gpc_base + GPC_SLOT0_CFG + 6 * 0x4);
+ writel_relaxed(0x0, gpc_base + GPC_SLOT0_CFG + 7 * 0x4);
+ writel_relaxed(0x0, gpc_base + GPC_SLOT0_CFG + 8 * 0x4);
+ writel_relaxed(BM_GPC_PGC_ACK_SEL_A7_DUMMY_PUP_ACK |
+ BM_GPC_PGC_ACK_SEL_A7_DUMMY_PDN_ACK,
+ gpc_base + GPC_PGC_ACK_SEL_A7);
+ imx_gpcv2_enable_rbc(false);
+ }
+ spin_unlock_irqrestore(&gpcv2_lock, flags);
+}
+
+void imx_gpcv2_set_mix_phy_gate_by_lpm(u32 pdn_index, u32 pup_index)
+{
+ /* set power down slot */
+ writel_relaxed(1 << (FAST_MEGA_MIX * 2),
+ gpc_base + GPC_SLOT0_CFG + pdn_index * 4);
+
+ /* set power up slot */
+ writel_relaxed(1 << (FAST_MEGA_MIX * 2 + 1),
+ gpc_base + GPC_SLOT0_CFG + pup_index * 4);
+}
+
+unsigned int imx_gpcv2_is_mf_mix_off(void)
+{
+ return readl_relaxed(gpc_base + GPC_PGC_FM);
+}
+
+static void imx_gpcv2_mf_mix_off(void)
+{
+ int i;
+
+ for (i = 0; i < IMR_NUM; i++)
+ if (((gpcv2_wake_irqs[i] | gpcv2_mf_request_on[i]) &
+ gpcv2_mf_irqs[i]) != 0)
+ return;
+
+ pr_info("Turn off Mega/Fast mix in DSM\n");
+ imx_gpcv2_set_slot_ack(1, FAST_MEGA_MIX, false, false);
+ imx_gpcv2_set_slot_ack(5, FAST_MEGA_MIX, true, false);
+ imx_gpcv2_set_m_core_pgc(true, GPC_PGC_FM);
+}
+
+int imx_gpcv2_mf_power_on(unsigned int irq, unsigned int on)
+{
+ struct irq_desc *desc = irq_to_desc(irq);
+ unsigned long hwirq = desc->irq_data.hwirq;
+ unsigned int idx = hwirq / 32;
+ unsigned long flags;
+ u32 mask = 1 << (hwirq % 32);
+
+ BUG_ON(idx >= IMR_NUM);
+
+ spin_lock_irqsave(&gpcv2_lock, flags);
+ gpcv2_mf_request_on[idx] = on ? gpcv2_mf_request_on[idx] | mask :
+ gpcv2_mf_request_on[idx] & ~mask;
+ spin_unlock_irqrestore(&gpcv2_lock, flags);
+
+ return 0;
+}
+
+void imx_gpcv2_enable_rbc(bool enable)
+{
+ u32 val;
+
+ /*
+ * need to mask all interrupts in GPC before
+ * operating RBC configurations
+ */
+ imx_gpcv2_mask_all();
+
+ /* configure RBC enable bit */
+ val = readl_relaxed(gpc_base + GPC_SLPCR);
+ val &= ~BM_SLPCR_RBC_EN;
+ val |= enable ? BM_SLPCR_RBC_EN : 0;
+ writel_relaxed(val, gpc_base + GPC_SLPCR);
+
+ /* configure RBC count */
+ val = readl_relaxed(gpc_base + GPC_SLPCR);
+ val &= ~BM_SLPCR_REG_BYPASS_COUNT;
+ val |= enable ? BM_SLPCR_REG_BYPASS_COUNT : 0;
+ writel(val, gpc_base + GPC_SLPCR);
+
+ /*
+ * need to delay at least 2 cycles of CKIL(32K)
+ * due to hardware design requirement, which is
+ * ~61us, here we use 65us for safe
+ */
+ udelay(65);
+
+ /* restore GPC interrupt mask settings */
+ imx_gpcv2_restore_all();
+}
+
+
+void imx_gpcv2_pre_suspend(bool arm_power_off)
+{
+ void __iomem *reg_imr1 = gpc_base + GPC_IMR1_CORE0;
+ int i;
+
+ if (arm_power_off) {
+ imx_gpcv2_set_lpm_mode(STOP_POWER_OFF);
+ /* enable core0 power down/up with low power mode */
+ imx_gpcv2_set_cpu_power_gate_by_lpm(0, true);
+ /* enable plat power down with low power mode */
+ imx_gpcv2_set_plat_power_gate_by_lpm(true);
+
+ /*
+ * To avoid confuse, we use slot 0~4 for power down,
+ * slot 5~9 for power up.
+ *
+ * Power down slot sequence:
+ * Slot0 -> CORE0
+ * Slot1 -> Mega/Fast MIX
+ * Slot2 -> SCU
+ *
+ * Power up slot sequence:
+ * Slot5 -> Mega/Fast MIX
+ * Slot6 -> SCU
+ * Slot7 -> CORE0
+ */
+ imx_gpcv2_set_slot_ack(0, CORE0_A7, false, false);
+ imx_gpcv2_set_slot_ack(2, SCU_A7, false, true);
+
+ if ((!imx_src_is_m4_enabled()) ||
+ (imx_src_is_m4_enabled() && imx_mu_is_m4_in_stop()))
+ imx_gpcv2_mf_mix_off();;
+
+ imx_gpcv2_set_slot_ack(6, SCU_A7, true, false);
+ imx_gpcv2_set_slot_ack(6, CORE0_A7, true, true);
+
+ /* enable core0, scu */
+ imx_gpcv2_set_m_core_pgc(true, GPC_PGC_C0);
+ imx_gpcv2_set_m_core_pgc(true, GPC_PGC_SCU);
+ } else {
+ imx_gpcv2_set_lpm_mode(STOP_POWER_ON);
+ }
+
+ for (i = 0; i < IMR_NUM; i++) {
+ gpcv2_saved_imrs[i] = readl_relaxed(reg_imr1 + i * 4);
+ writel_relaxed(~gpcv2_wake_irqs[i], reg_imr1 + i * 4);
+ }
+}
+
+void imx_gpcv2_enable_wakeup_for_m4(void)
+{
+ void __iomem *reg_imr2 = gpc_base + GPC_IMR1_M4;
+ u32 i;
+
+ for (i = 0; i < IMR_NUM; i++) {
+ gpcv2_saved_imrs_m4[i] = readl_relaxed(reg_imr2 + i * 4);
+ writel_relaxed(~gpcv2_wake_irqs[i], reg_imr2 + i * 4);
+ }
+}
+
+void imx_gpcv2_disable_wakeup_for_m4(void)
+{
+ void __iomem *reg_imr2 = gpc_base + GPC_IMR1_M4;
+ u32 i;
+
+ for (i = 0; i < IMR_NUM; i++)
+ writel_relaxed(gpcv2_saved_imrs_m4[i], reg_imr2 + i * 4);
+}
+
+void imx_gpcv2_post_resume(void)
+{
+ void __iomem *reg_imr1 = gpc_base + GPC_IMR1_CORE0;
+ int i, val;
+
+ /* only external IRQs to wake up LPM and core 0/1 */
+ val = readl_relaxed(gpc_base + GPC_LPCR_A7_BSC);
+ val |= BM_LPCR_A7_BSC_IRQ_SRC_A7_WAKEUP;
+ writel_relaxed(val, gpc_base + GPC_LPCR_A7_BSC);
+ /* mask m4 dsm trigger if M4 NOT enabled */
+ if (!imx_src_is_m4_enabled())
+ writel_relaxed(readl_relaxed(gpc_base + GPC_LPCR_M4) |
+ BM_LPCR_M4_MASK_DSM_TRIGGER, gpc_base + GPC_LPCR_M4);
+ /* set mega/fast mix in A7 domain */
+ writel_relaxed(0x1, gpc_base + GPC_PGC_CPU_MAPPING);
+ /* set SCU timing */
+ writel_relaxed((0x59 << 10) | 0x5B | (0x2 << 20),
+ gpc_base + GPC_PGC_SCU_TIMING);
+
+ /* set C0/C1 power up timming per design requirement */
+ val = readl_relaxed(gpc_base + GPC_PGC_C0_PUPSCR);
+ val &= ~BM_GPC_PGC_CORE_PUPSCR;
+ val |= (0x1A << 7);
+ writel_relaxed(val, gpc_base + GPC_PGC_C0_PUPSCR);
+
+ val = readl_relaxed(gpc_base + GPC_PGC_C1_PUPSCR);
+ val &= ~BM_GPC_PGC_CORE_PUPSCR;
+ val |= (0x1A << 7);
+ writel_relaxed(val, gpc_base + GPC_PGC_C1_PUPSCR);
+
+ val = readl_relaxed(gpc_base + GPC_SLPCR);
+ val &= ~(BM_SLPCR_EN_DSM);
+ if (!imx_src_is_m4_enabled())
+ val &= ~(BM_SLPCR_VSTBY | BM_SLPCR_RBC_EN |
+ BM_SLPCR_SBYOS | BM_SLPCR_BYPASS_PMIC_READY);
+ val |= BM_SLPCR_EN_A7_FASTWUP_WAIT_MODE;
+ writel_relaxed(val, gpc_base + GPC_SLPCR);
+
+ if (imx_get_soc_revision() == IMX_CHIP_REVISION_1_0) {
+ /* disable memory low power mode */
+ val = readl_relaxed(gpc_base + GPC_MLPCR);
+ val |= BM_GPC_MLPCR_MEMLP_CTL_DIS;
+ writel_relaxed(val, gpc_base + GPC_MLPCR);
+ }
+
+ for (i = 0; i < IMR_NUM; i++)
+ writel_relaxed(gpcv2_saved_imrs[i], reg_imr1 + i * 4);
+
+ imx_gpcv2_set_lpm_mode(WAIT_CLOCKED);
+ imx_gpcv2_set_cpu_power_gate_by_lpm(0, false);
+ imx_gpcv2_set_plat_power_gate_by_lpm(false);
+
+ imx_gpcv2_set_m_core_pgc(false, GPC_PGC_C0);
+ imx_gpcv2_set_m_core_pgc(false, GPC_PGC_SCU);
+ imx_gpcv2_set_m_core_pgc(false, GPC_PGC_FM);
+ for (i = 0; i < MAX_SLOT_NUMBER; i++){
+ if (i == 1 || i == 5) /* skip slts m4 uses */
+ continue;
+ writel_relaxed(0x0, gpc_base + GPC_SLOT0_CFG + i * 0x4);
+ }
+ writel_relaxed(BM_GPC_PGC_ACK_SEL_A7_DUMMY_PUP_ACK |
+ BM_GPC_PGC_ACK_SEL_A7_DUMMY_PDN_ACK,
+ gpc_base + GPC_PGC_ACK_SEL_A7);
+
+ /* disable RBC */
+ imx_gpcv2_enable_rbc(false);
+}
+
+static struct irq_chip imx_gpcv2_chip = {
+ .name = "GPCV2",
+ .irq_eoi = irq_chip_eoi_parent,
+ .irq_mask = imx_gpcv2_irq_mask,
+ .irq_unmask = imx_gpcv2_irq_unmask,
+ .irq_retrigger = irq_chip_retrigger_hierarchy,
+ .irq_set_wake = imx_gpcv2_irq_set_wake,
+#ifdef CONFIG_SMP
+ .irq_set_affinity = irq_chip_set_affinity_parent,
+#endif
+};
+
+static int imx_gpcv2_domain_xlate(struct irq_domain *domain,
+ struct device_node *controller,
+ const u32 *intspec,
+ unsigned int intsize,
+ unsigned long *out_hwirq,
+ unsigned int *out_type)
+{
+ if (irq_domain_get_of_node(domain) != controller)
+ return -EINVAL; /* Shouldn't happen, really... */
+ if (intsize != 3)
+ return -EINVAL; /* Not GIC compliant */
+ if (intspec[0] != 0)
+ return -EINVAL; /* No PPI should point to this domain */
+
+ *out_hwirq = intspec[1];
+ *out_type = intspec[2];
+ return 0;
+}
+
+static int imx_gpcv2_domain_alloc(struct irq_domain *domain,
+ unsigned int irq,
+ unsigned int nr_irqs, void *data)
+{
+ struct irq_fwspec *fwspec = data;
+ struct irq_fwspec parent_fwspec;
+ irq_hw_number_t hwirq;
+ int i;
+
+ if (fwspec->param_count != 3)
+ return -EINVAL; /* Not GIC compliant */
+ if (fwspec->param[0] != 0)
+ return -EINVAL; /* No PPI should point to this domain */
+
+ hwirq = fwspec->param[1];
+ if (hwirq >= GPC_MAX_IRQS)
+ return -EINVAL; /* Can't deal with this */
+
+ for (i = 0; i < nr_irqs; i++)
+ irq_domain_set_hwirq_and_chip(domain, irq + i, hwirq + i,
+ &imx_gpcv2_chip, NULL);
+
+ parent_fwspec.fwnode = domain->parent->fwnode;
+ parent_fwspec.param_count = 3;
+ parent_fwspec.param[0] = 0;
+ parent_fwspec.param[1] = hwirq;
+ parent_fwspec.param[2] = fwspec->param[2];
+
+ return irq_domain_alloc_irqs_parent(domain, irq, nr_irqs,
+ &parent_fwspec);
+}
+
+static struct irq_domain_ops imx_gpcv2_domain_ops = {
+ .xlate = imx_gpcv2_domain_xlate,
+ .alloc = imx_gpcv2_domain_alloc,
+ .free = irq_domain_free_irqs_common,
+};
+
+static int __init imx_gpcv2_init(struct device_node *node,
+ struct device_node *parent)
+{
+ struct irq_domain *parent_domain, *domain;
+ int i, val;
+
+ if (!parent) {
+ pr_err("%s: no parent, giving up\n", node->full_name);
+ return -ENODEV;
+ }
+
+ parent_domain = irq_find_host(parent);
+ if (!parent_domain) {
+ pr_err("%s: unable to obtain parent domain\n", node->full_name);
+ return -ENXIO;
+ }
+
+ gpc_base = of_iomap(node, 0);
+ if (WARN_ON(!gpc_base))
+ return -ENOMEM;
+
+ domain = irq_domain_add_hierarchy(parent_domain, 0, GPC_MAX_IRQS,
+ node, &imx_gpcv2_domain_ops,
+ NULL);
+ if (!domain) {
+ iounmap(gpc_base);
+ return -ENOMEM;
+ }
+
+ /* Initially mask all interrupts */
+ for (i = 0; i < IMR_NUM; i++) {
+ writel_relaxed(~0, gpc_base + GPC_IMR1_CORE0 + i * 4);
+ writel_relaxed(~0, gpc_base + GPC_IMR1_CORE1 + i * 4);
+ }
+ /*
+ * Due to hardware design requirement, need to make sure GPR
+ * interrupt(#32) is unmasked during RUN mode to avoid entering
+ * DSM by mistake.
+ */
+ writel_relaxed(~0x1, gpc_base + GPC_IMR1_CORE0);
+
+ /* Read supported wakeup source in M/F domain */
+ if (cpu_is_imx7d()) {
+ of_property_read_u32_index(node, "fsl,mf-mix-wakeup-irq", 0,
+ &gpcv2_mf_irqs[0]);
+ of_property_read_u32_index(node, "fsl,mf-mix-wakeup-irq", 1,
+ &gpcv2_mf_irqs[1]);
+ of_property_read_u32_index(node, "fsl,mf-mix-wakeup-irq", 2,
+ &gpcv2_mf_irqs[2]);
+ of_property_read_u32_index(node, "fsl,mf-mix-wakeup-irq", 3,
+ &gpcv2_mf_irqs[3]);
+ if (!(gpcv2_mf_irqs[0] | gpcv2_mf_irqs[1] |
+ gpcv2_mf_irqs[2] | gpcv2_mf_irqs[3]))
+ pr_info("No wakeup source in Mega/Fast domain found!\n");
+ }
+
+ /* only external IRQs to wake up LPM and core 0/1 */
+ val = readl_relaxed(gpc_base + GPC_LPCR_A7_BSC);
+ val |= BM_LPCR_A7_BSC_IRQ_SRC_A7_WAKEUP;
+ writel_relaxed(val, gpc_base + GPC_LPCR_A7_BSC);
+ /* mask m4 dsm trigger if M4 NOT enabled */
+ if (!imx_src_is_m4_enabled())
+ writel_relaxed(readl_relaxed(gpc_base + GPC_LPCR_M4) |
+ BM_LPCR_M4_MASK_DSM_TRIGGER, gpc_base + GPC_LPCR_M4);
+ /* set mega/fast mix in A7 domain */
+ writel_relaxed(0x1, gpc_base + GPC_PGC_CPU_MAPPING);
+ /* set SCU timing */
+ writel_relaxed((0x59 << 10) | 0x5B | (0x2 << 20),
+ gpc_base + GPC_PGC_SCU_TIMING);
+
+ /* set C0/C1 power up timming per design requirement */
+ val = readl_relaxed(gpc_base + GPC_PGC_C0_PUPSCR);
+ val &= ~BM_GPC_PGC_CORE_PUPSCR;
+ val |= (0x1A << 7);
+ writel_relaxed(val, gpc_base + GPC_PGC_C0_PUPSCR);
+
+ val = readl_relaxed(gpc_base + GPC_PGC_C1_PUPSCR);
+ val &= ~BM_GPC_PGC_CORE_PUPSCR;
+ val |= (0x1A << 7);
+ writel_relaxed(val, gpc_base + GPC_PGC_C1_PUPSCR);
+
+ writel_relaxed(BM_GPC_PGC_ACK_SEL_A7_DUMMY_PUP_ACK |
+ BM_GPC_PGC_ACK_SEL_A7_DUMMY_PDN_ACK,
+ gpc_base + GPC_PGC_ACK_SEL_A7);
+
+ val = readl_relaxed(gpc_base + GPC_SLPCR);
+ val &= ~(BM_SLPCR_EN_DSM);
+ if (!imx_src_is_m4_enabled())
+ val &= ~(BM_SLPCR_VSTBY | BM_SLPCR_RBC_EN |
+ BM_SLPCR_SBYOS | BM_SLPCR_BYPASS_PMIC_READY);
+ val |= BM_SLPCR_EN_A7_FASTWUP_WAIT_MODE;
+ writel_relaxed(val, gpc_base + GPC_SLPCR);
+
+ if (imx_get_soc_revision() == IMX_CHIP_REVISION_1_0) {
+ /* disable memory low power mode */
+ val = readl_relaxed(gpc_base + GPC_MLPCR);
+ val |= BM_GPC_MLPCR_MEMLP_CTL_DIS;
+ writel_relaxed(val, gpc_base + GPC_MLPCR);
+ }
+
+ /* disable RBC */
+ imx_gpcv2_enable_rbc(false);
+
+ /*
+ * Clear the OF_POPULATED flag set in of_irq_init so that
+ * later the GPC power domain driver will not be skipped.
+ */
+ of_node_clear_flag(node, OF_POPULATED);
+
+ return 0;
+}
+
+/*
+ * We cannot use the IRQCHIP_DECLARE macro that lives in
+ * drivers/irqchip, so we're forced to roll our own. Not very nice.
+ */
+OF_DECLARE_2(irqchip, imx_gpcv2, "fsl,imx7d-gpc", imx_gpcv2_init);
+
+void __init imx_gpcv2_check_dt(void)
+{
+ struct device_node *np;
+
+ np = of_find_compatible_node(NULL, NULL, "fsl,imx7d-gpc");
+ if (WARN_ON(!np))
+ return;
+
+ if (WARN_ON(!of_find_property(np, "interrupt-controller", NULL))) {
+ pr_warn("Outdated DT detected, suspend/resume will NOT work\n");
+
+ /* map GPC, so that at least CPUidle and WARs keep working */
+ gpc_base = of_iomap(np, 0);
+ }
+}
diff --git a/arch/arm/mach-imx/hardware.h b/arch/arm/mach-imx/hardware.h
index 90e10cbd8fd1..665c596a0b76 100644
--- a/arch/arm/mach-imx/hardware.h
+++ b/arch/arm/mach-imx/hardware.h
@@ -94,13 +94,16 @@
* CCM 0x020c4000+0x004000 -> 0xf42c4000+0x004000
* ANATOP 0x020c8000+0x004000 -> 0xf42c8000+0x004000
* UART4 0x021f0000+0x004000 -> 0xf42f0000+0x004000
- */
+ * mx7d:
+ * CCM 0x30380000+0x010000 -> 0xf5380000+0x010000
+ * ANATOP 0x30360000+0x010000 -> 0xf5360000+0x010000
+ * UART1 0x30860000+0x010000 -> 0xf5860000+0x010000
+*/
#define IMX_IO_P2V(x) ( \
- (((x) & 0x80000000) >> 7) | \
(0xf4000000 + \
- (((x) & 0x50000000) >> 6) + \
- (((x) & 0x0b000000) >> 4) + \
- (((x) & 0x000fffff))))
+ (((x) & 0x50000000) >> 4) + \
+ (((x) & 0x0a000000) >> 4) + \
+ (((x) & 0x00ffffff))))
#define IMX_IO_ADDRESS(x) IOMEM(IMX_IO_P2V(x))
@@ -112,6 +115,9 @@
#include "mx2x.h"
#include "mx21.h"
#include "mx27.h"
+#include "mx6.h"
+#include "mx7.h"
+#include "mx7ulp.h"
#define imx_map_entry(soc, name, _type) { \
.virtual = soc ## _IO_P2V(soc ## _ ## name ## _BASE_ADDR), \
diff --git a/arch/arm/mach-imx/headsmp.S b/arch/arm/mach-imx/headsmp.S
index 6c28d28b3c64..5d6a5e2fe9ee 100644
--- a/arch/arm/mach-imx/headsmp.S
+++ b/arch/arm/mach-imx/headsmp.S
@@ -1,5 +1,5 @@
/*
- * Copyright 2011 Freescale Semiconductor, Inc.
+ * Copyright 2011-2015 Freescale Semiconductor, Inc.
* Copyright 2011 Linaro Ltd.
*
* The code contained herein is licensed under the GNU General Public
@@ -27,6 +27,17 @@ diag_reg_offset:
ENTRY(v7_secondary_startup)
ARM_BE8(setend be) @ go BE8 if entered LE
+ mrc p15, 0, r0, c0, c0, 0
+ ldr r1, =0xf00
+ orr r1, r1, #0xff
+ mov r0, r0, lsr #4
+ and r0, r0, r1
+ /* 0xc07 is cortex A7's ID */
+ ldr r1, =0xc00
+ orr r1, r1, #0x7
+ cmp r0, r1
+ beq secondary_startup
+
set_diag_reg
b secondary_startup
ENDPROC(v7_secondary_startup)
diff --git a/arch/arm/mach-imx/hotplug.c b/arch/arm/mach-imx/hotplug.c
index b35e99cc5e5b..06dab2fc1c25 100644
--- a/arch/arm/mach-imx/hotplug.c
+++ b/arch/arm/mach-imx/hotplug.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2011 Freescale Semiconductor, Inc.
+ * Copyright 2011-2015 Freescale Semiconductor, Inc.
* Copyright 2011 Linaro Ltd.
*
* The code contained herein is licensed under the GNU General Public
@@ -16,6 +16,7 @@
#include <asm/proc-fns.h>
#include "common.h"
+#include "hardware.h"
static inline void cpu_enter_lowpower(void)
{
@@ -66,5 +67,7 @@ int imx_cpu_kill(unsigned int cpu)
return 0;
imx_enable_cpu(cpu, false);
imx_set_cpu_arg(cpu, 0);
+ if (cpu_is_imx7d())
+ imx_gpcv2_set_core1_pdn_pup_by_software(true);
return 1;
}
diff --git a/arch/arm/mach-imx/imx6sl_low_power_idle.S b/arch/arm/mach-imx/imx6sl_low_power_idle.S
new file mode 100644
index 000000000000..978f8d1cc234
--- /dev/null
+++ b/arch/arm/mach-imx/imx6sl_low_power_idle.S
@@ -0,0 +1,776 @@
+/*
+ * Copyright (C) 2015 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the license, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in teh 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/linkage.h>
+
+#define PM_INFO_PM_INFO_SIZE_OFFSET 0x0
+#define PM_INFO_TTBR_OFFSET 0x4
+#define PM_INFO_MMDC_V_OFFSET 0x8
+#define PM_INFO_IOMUXC_V_OFFSET 0xc
+#define PM_INFO_CCM_V_OFFSET 0x10
+#define PM_INFO_L2_V_OFFSET 0x14
+#define PM_INFO_ANATOP_V_OFFSET 0x18
+#define PM_INFO_IO_NUM_OFFSET 0x1c
+#define PM_INFO_IO_VAL_OFFSET 0x20
+
+#define MX6Q_MMDC_MAPSR 0x404
+#define MX6Q_MMDC_MPDGCTRL0 0x83c
+
+.global mx6sl_lpm_wfi_start
+.global mx6sl_lpm_wfi_end
+
+ .macro pll_do_wait_lock
+1:
+ ldr r7, [r10, r8]
+ ands r7, #0x80000000
+ beq 1b
+
+ .endm
+
+ .macro ccm_do_wait
+2:
+ ldr r7, [r10, #0x48]
+ cmp r7, #0x0
+ bne 2b
+
+ .endm
+
+ .macro ccm_enter_idle
+
+ ldr r10, [r0, #PM_INFO_CCM_V_OFFSET]
+ /*
+ * if in audio_bus_freq_mode, skip to
+ * audio_mode low power setting.
+ */
+ cmp r1, #0x1
+ beq audio_mode
+ /*
+ * Now set DDR rate to 1MHz.
+ * DDR is from bypassed PLL2 on periph2_clk2 path.
+ * Set the periph2_clk2_podf to divide by 8.
+ */
+ ldr r6, [r10, #0x14]
+ orr r6, r6, #0x07
+ str r6, [r10, #0x14]
+
+ /* Now set MMDC PODF to divide by 3. */
+ ldr r6, [r10, #0x14]
+ bic r6, r6, #0x38
+ orr r6, r6, #0x10
+ str r6, [r10, #0x14]
+
+ ccm_do_wait
+
+ /* Set the AHB to 3MHz. AXI to 3MHz. */
+ ldr r6, [r10, #0x14]
+ /*r12 stores the origin AHB podf value */
+ mov r12, r6
+ orr r6, r6, #0x1c00
+ orr r6, r6, #0x70000
+ str r6, [r10, #0x14]
+
+ ccm_do_wait
+
+ /* Now set ARM to 24MHz.
+ * Move ARM to be sourced from step_clk
+ * after setting step_clk to 24MHz.
+ */
+ ldr r6, [r10, #0x0c]
+ bic r6, r6, #0x100
+ str r6, [r10, #0xc]
+ /*Now pll1_sw_clk to step_clk */
+ ldr r6, [r10, #0x0c]
+ orr r6, r6, #0x4
+ str r6, [r10, #0x0c]
+
+ /* Bypass PLL1 and power it down */
+ ldr r10, [r0, #PM_INFO_ANATOP_V_OFFSET]
+ ldr r6, =(1 << 16)
+ orr r6, r6, #0x1000
+ str r6, [r10, #0x04]
+
+ /*
+ * Set the ARM PODF to divide by 8.
+ * IPG is at 1.5MHz here, we need ARM to
+ * run at the 12:5 ratio (WAIT mode issue).
+ */
+ ldr r10, [r0, #PM_INFO_CCM_V_OFFSET]
+ ldr r11, [r10, #0x10]
+ ldr r6, =0x07
+ str r6, [r10, #0x10]
+
+ ccm_do_wait
+
+ b ccm_idle_done
+
+audio_mode:
+ /*
+ * MMDC is sourced from pll2_200M.
+ * Set the mmdc_podf to div by 8
+ */
+ ldr r10, [r0, #PM_INFO_CCM_V_OFFSET]
+ ldr r6, [r10, #0x14]
+ orr r6, r6, #0x38
+ str r6, [r10, #0x14]
+
+ ccm_do_wait
+
+ /*
+ * ARM is sourced from pll2_pfd2_400M here.
+ * switch ARM to bypassed PLL1
+ */
+ ldr r10, [r0, #PM_INFO_CCM_V_OFFSET]
+ ldr r6, [r10, #0x0c]
+ bic r6, r6, #0x4
+ str r6, [r10, #0xc]
+
+ /*
+ * set the arm_podf to divide by 3
+ * as IPG is at 4MHz, we cannot run
+ * arm clk above 9.6MHz when system
+ * enter WAIT mode
+ */
+ ldr r11, [r10, #0x10]
+ ldr r6, =0x2
+ str r6, [r10, #0x10]
+
+ ccm_do_wait
+
+ccm_idle_done:
+
+ .endm
+
+ .macro ccm_exit_idle
+
+ /*
+ * If in audio_bus_freq_mode, skip to
+ * audio_mode ccm restore.
+ */
+ cmp r1, #0x1
+ beq audio_ccm_restore
+
+ ldr r10, [r0, #PM_INFO_ANATOP_V_OFFSET]
+ /* Power up PLL1 and un-bypass it. */
+ ldr r6, =(1 << 12)
+ str r6, [r10, #0x08]
+
+ /* Wait for PLL1 to relock */
+ ldr r8, =0x0
+ pll_do_wait_lock
+
+ ldr r6, =(1 << 16)
+ str r6, [r10, #0x08]
+
+ ldr r10, [r0, #PM_INFO_CCM_V_OFFSET]
+ /* Set PLL1_sw_clk back to PLL1 */
+ ldr r6, [r10, #0x0c]
+ bic r6, r6, #0x4
+ str r6, [r10, #0x0c]
+
+ /* Restore AHB/AXI back */
+ str r12, [r10, #0x14]
+
+ ccm_do_wait
+
+ /* restore mmdc back to 24MHz*/
+ ldr r6, [r10, #0x14]
+ bic r6, r6, #0x3f
+ str r6, [r10, #0x14]
+
+ ccm_do_wait
+ b ccm_exit_done
+
+audio_ccm_restore:
+ /* move arm clk back to pll2_pfd2_400M */
+ ldr r6, [r10, #0xc]
+ orr r6, r6, #0x4
+ str r6, [r10, #0xc]
+
+ /* restore mmdc podf */
+ ldr r10, [r0, #PM_INFO_CCM_V_OFFSET]
+ ldr r6, [r10, #0x14]
+ bic r6, r6, #0x38
+ orr r6, #0x8
+ str r6, [r10, #0x14]
+
+ ccm_do_wait
+
+ccm_exit_done:
+
+ .endm
+
+ .macro check_pll_state
+
+ ldr r10, [r0, #PM_INFO_ANATOP_V_OFFSET]
+ /*
+ * Check whether any PLL is enabled, as only when
+ * there is no PLLs enabled, 2p5 can be off and
+ * only enable the weak one. PLL1 will be powered
+ * down late, so no need to check PLL1 state.
+ */
+
+ /* sys PLL2 */
+ ldr r6, [r10, #0x30]
+ ands r6, r6, #(1 << 31)
+ bne 1f
+
+ /* usb PLL3 */
+ ldr r6, [r10, #0x10]
+ ands r6, r6, #(1 << 31)
+ bne 1f
+
+ /* audio PLL4 */
+ ldr r6, [r10, #0x70]
+ ands r6, r6, #(1 << 31)
+ bne 1f
+
+ /* video PLL5 */
+ ldr r6, [r10, #0xa0]
+ ands r6, r6, #(1 << 31)
+ bne 1f
+
+ /* enet PLL6 */
+ ldr r6, [r10, #0xe0]
+ ands r6, r6, #(1 << 31)
+ bne 1f
+
+ /* usb host PLL7 */
+ ldr r6, [r10, #0x20]
+ ands r6, r6, #(1 << 31)
+ bne 1f
+
+ ldr r4, =0x1
+ b check_done
+1:
+ ldr r4, =0x0
+
+check_done:
+ .endm
+
+ .macro anatop_enter_idle
+
+ ldr r10, [r0, #PM_INFO_ANATOP_V_OFFSET]
+ cmp r4, #0x0
+ beq anatop_enter_done
+
+ /* Disable 1p1 brown out. */
+ ldr r10, [r0, #PM_INFO_ANATOP_V_OFFSET]
+ ldr r6, [r10, #0x110]
+ bic r6, r6, #0x2
+ str r6, [r10, #0x110]
+ /*
+ * Set the OSC bias current to -37.5%
+ * to drop the power on VDDHIGH.
+ */
+ ldr r6, [r10, #0x150]
+ orr r6, r6, #0xc000
+ str r6, [r10, #0x150]
+
+ /*
+ * if the usb VBUS wakeup is enabled, skip
+ * disable main 2p5.
+ */
+ cmp r2, #0x1
+ beq anatop_enter_done
+
+ /* Enable the week 2p5 */
+ ldr r6, [r10, #0x130]
+ orr r6, r6, #0x40000
+ str r6, [r10, #0x130]
+
+ /* Disable main 2p5. */
+ ldr r6, [r10, #0x130]
+ bic r6, r6, #0x1
+ str r6, [r10, #0x130]
+
+ /*
+ * Cannot diable regular bandgap
+ * in LDO-enable mode. The bandgap
+ * is required for ARM-LDO to regulate
+ * the voltage.
+ */
+ ldr r6, [r10, #0x140]
+ and r6, r6, #0x1f
+ cmp r6, #0x1f
+ bne anatop_enter_done
+
+ /* Enable low power bandgap */
+ ldr r6, [r10, #0x260]
+ orr r6, r6, #0x20
+ str r6, [r10, #0x260]
+
+ /*
+ * Turn off the bias current
+ * from the regular bandgap.
+ */
+ ldr r6, [r10, #0x260]
+ orr r6, r6, #0x80
+ str r6, [r10, #0x260]
+
+ /*
+ * Clear the REFTTOP+SELFBIASOFF,
+ * self_bais circuit of the band gap.
+ * Per RM, should be cleared when
+ * band gap is powered down.
+ */
+ ldr r6, [r10, #0x150]
+ bic r6, r6, #0x8
+ str r6, [r10, #0x150]
+
+ /* Power down the regular bandgap */
+ ldr r6, [r10, #0x150]
+ orr r6, r6, #0x1
+ str r6, [r10, #0x150]
+anatop_enter_done:
+
+ .endm
+
+ .macro anatop_exit_idle
+
+ ldr r10, [r0, #PM_INFO_ANATOP_V_OFFSET]
+ cmp r4, #0x0
+ beq skip_anatop_restore
+
+ cmp r2, #0x1
+ beq ldo2p5_not_disabled
+ /*
+ * Regular bandgap will not be disabled
+ * in LDO-enabled mode as it is required
+ * for ARM-LDO to reguulate the voltage.
+ */
+ ldr r6, [r10, #0x140]
+ and r6, r6, #0x1f
+ cmp r6, #0x1f
+ bne skip_bandgap_restore
+
+ /* Power up the regular bandgap */
+ ldr r6, [r10, #0x150]
+ bic r6, r6, #0x1
+ str r6, [r10, #0x150]
+
+ /* wait for bandgap stable */
+3:
+ ldr r6, [r10, #0x150]
+ and r6, r6, #0x80
+ cmp r6, #0x80
+ bne 3b
+
+ /* now disable bandgap self-bias circuit */
+ ldr r6, [r10, #0x150]
+ orr r6, r6, #0x8
+ str r6, [r10, #0x150]
+
+ /* Turn on the bias current
+ * from the regular bandgap.
+ */
+ ldr r6, [r10, #0x260]
+ bic r6, r6, #0x80
+ str r6, [r10, #0x260]
+
+ /* Disable the low power bandgap */
+ ldr r6, [r10, #0x260]
+ bic r6, r6, #0x20
+ str r6, [r10, #0x260]
+
+skip_bandgap_restore:
+ /* Enable main 2p5. */
+ ldr r6, [r10, #0x130]
+ orr r6, r6, #0x1
+ str r6, [r10, #0x130]
+
+ /* Ensure the 2p5 is up */
+5:
+ ldr r6, [r10, #0x130]
+ and r6, r6, #0x20000
+ cmp r6, #0x20000
+ bne 5b
+
+ /* Disable the weak 2p5 */
+ ldr r6, [r10, #0x130]
+ bic r6, r6, #0x40000
+ str r6, [r10, #0x130]
+
+ldo2p5_not_disabled:
+ /*
+ * Set the OSC bias current to max
+ * value for normal operation.
+ */
+ ldr r6, [r10, #0x150]
+ bic r6, r6, #0xc000
+ str r6, [r10, #0x150]
+
+ /* Enable 1p1 brown out, */
+ ldr r6, [r10, #0x110]
+ orr r6, r6, #0x2
+ str r6, [r10, #0x110]
+
+skip_anatop_restore:
+
+ .endm
+
+ .macro disable_l1_dcache
+
+ /* disable d-cache */
+ mrc p15, 0, r7, c1, c0, 0
+ bic r7, r7, #(1 << 2)
+ mcr p15, 0, r7, c1, c0, 0
+
+ dsb
+ isb
+
+ .endm
+
+ .macro mmdc_enter_dvfs_mode
+
+ /* disable automatic power saving. */
+ ldr r7, [r10, #MX6Q_MMDC_MAPSR]
+ orr r7, r7, #0x1
+ str r7, [r10, #MX6Q_MMDC_MAPSR]
+
+ /* disable power down timer */
+ ldr r7, [r10, #0x04]
+ bic r7, r7, #0xff00
+ str r7, [r10, #0x04]
+
+ /* Make the DDR explicitly enter self-refresh. */
+ ldr r7, [r10, #MX6Q_MMDC_MAPSR]
+ orr r7, r7, #(1 << 21)
+ str r7, [r10, #MX6Q_MMDC_MAPSR]
+
+poll_dvfs_set:
+ ldr r7, [r10, #MX6Q_MMDC_MAPSR]
+ ands r7, r7, #(1 << 25)
+ beq poll_dvfs_set
+
+ /* set SBS step-by step mode */
+ ldr r7, [r10, #0x410]
+ orr r7, r7, #0x100
+ str r7, [r10, #0x410]
+
+ .endm
+
+ .macro resume_mmdc
+ /* restore MMDC IO */
+ ldr r10, [r0, #PM_INFO_IOMUXC_V_OFFSET]
+
+ ldr r6, [r0, #PM_INFO_IO_NUM_OFFSET]
+ ldr r7, =PM_INFO_IO_VAL_OFFSET
+ add r7, r7, r0
+6:
+ ldr r8, [r7], #0x4
+ ldr r9, [r7], #0x4
+ str r9, [r10, r8]
+ subs r6, r6, #0x1
+ bne 6b
+
+ /*
+ * Need to reset the FIFO to avoid MMDC lockup
+ * caused because of floating/changing the
+ * configuration of many DDR IO pads.
+ */
+ ldr r10, [r0, #PM_INFO_MMDC_V_OFFSET]
+ /* reset read FIFO, RST_RD_FIFO */
+ ldr r7, =MX6Q_MMDC_MPDGCTRL0
+ ldr r6, [r10, r7]
+ orr r6, r6, #(1 << 31)
+ str r6, [r10, r7]
+7:
+ ldr r6, [r10, r7]
+ ands r6, r6, #(1 << 31)
+ bne 7b
+
+ /* reset FIFO a second time */
+ ldr r7, =MX6Q_MMDC_MPDGCTRL0
+ ldr r6, [r10, r7]
+ orr r6, r6, #(1 << 31)
+ str r6, [r10, r7]
+8:
+ ldr r6, [r10, r7]
+ ands r6, r6, #(1 <<31)
+ bne 8b
+
+ ldr r10, [r0, #PM_INFO_MMDC_V_OFFSET]
+ /* Let DDR out of self-refresh */
+ ldr r7, [r10, #MX6Q_MMDC_MAPSR]
+ bic r7, r7, #(1 << 21)
+ str r7, [r10, #MX6Q_MMDC_MAPSR]
+9:
+ ldr r7, [r10, #MX6Q_MMDC_MAPSR]
+ ands r7, r7, #(1 << 25)
+ bne 9b
+
+ /* enable power down timer */
+ ldr r7, [r10, #0x04]
+ orr r7, r7, #0x5500
+ str r7, [r10, #0x04]
+
+ /* enable DDR auto power saving */
+ ldr r7, [r10, #MX6Q_MMDC_MAPSR]
+ bic r7, r7, #0x1
+ str r7, [r10, #MX6Q_MMDC_MAPSR]
+
+ /* Clear SBS - unblock DDR accesses */
+ ldr r7, [r10, #0x410]
+ bic r7, r7, #0x100
+ str r7, [r10, #0x410]
+
+ .endm
+
+ .macro tlb_set_to_ocram
+
+ /* save ttbr */
+ mrc p15, 0, r7, c2, c0, 1
+ str r7, [r0, #PM_INFO_TTBR_OFFSET]
+
+ /*
+ * To ensure no page table walks occur in DDR, we
+ * have a another page table stored in IRAM that only
+ * contains entries pointing to IRAM, AIPS1 and AIPS2.
+ * we need to set the TTBR1 to the new IRAM TLB.
+ * Do the following steps:
+ * 1. Flush the Branch Target Address Cache (BTAC)
+ * 2. Set TTBR1 to point to the IRAM page table.
+ * 3. Disable page table walks in TTBR0 (PD0 = 1)
+ * 4. Set TTBR0.N=1, implying 0-2G is transslated by TTBR0
+ * and 2-4G is translated by TTBR1.
+ */
+
+ ldr r6, =iram_tlb_phys_addr
+ ldr r7, [r6]
+
+ /* Disable Branch Prediction, Z bit in SCTLR */
+ mrc p15, 0, r6, c1, c0, 0
+ bic r6, r6, #0x800
+ mcr p15, 0, r6, c1, c0, 0
+
+ /* Flush the BTAC. */
+ ldr r6, =0x0
+ mcr p15, 0, r6, c7, c1, 6
+
+ dsb
+ isb
+
+ /* store the IRAM table in TTBR1 */
+ mcr p15, 0, r7, c2, c0, 1
+ /* Read TTBCR and set PD0=1, N=1 */
+ mrc p15, 0, r6, c2, c0, 2
+ orr r6, r6, #0x11
+ mcr p15, 0, r6, c2, c0, 2
+
+ dsb
+ isb
+
+ /* Flush the TLB */
+ ldr r6, =0x0
+ mcr p15, 0, r6, c8, c3, 0
+
+ .endm
+
+ .macro tlb_back_to_ddr
+
+ /* Restore the TTBCR */
+ dsb
+ isb
+
+ /* Read TTBCR and set PD0=0, N=0 */
+ mrc p15, 0, r6, c2, c0, 2
+ bic r6, r6, #0x11
+ mcr p15, 0, r6, c2, c0, 2
+ /* Flush the TLB */
+ ldr r6, =0x0
+ mcr p15, 0, r6, c8, c3, 0
+
+ dsb
+ isb
+
+ /* Enable Branch Prediction, Z bit in SCTLR. */
+ mrc p15, 0, r6, c1, c0, 0
+ orr r6, r6, #0x800
+ mcr p15, 0 ,r6, c1, c0, 0
+ /* Flush the Branch Target Address Cache (BTAC) */
+ ldr r6, =0x0
+ mcr p15, 0, r6, c7, c1, 6
+ /* Restore ttbr */
+ ldr r7, [r0, #PM_INFO_TTBR_OFFSET]
+ mcr p15, 0, r7, c2, c0, 1
+
+ .endm
+
+.extern iram_tlb_phys_addr
+
+/*
+ * imx6sl_low_power_wfi code
+ * r0: wfi code base address
+ * r1: audio_bus_freq mode stat
+ * r2: vbus_ldo status
+ * r4: used for store the PLLs state
+ * r11: used for saving the ARM_PODF origin value
+ * r12: used for saving AHB_PODF origin value
+ */
+ .align 3
+ENTRY(imx6sl_low_power_idle)
+
+mx6sl_lpm_wfi_start:
+ push {r4-r12}
+
+ tlb_set_to_ocram
+ disable_l1_dcache
+
+#ifdef CONFIG_CACHE_L2X0
+ /* sync L2 */
+ ldr r10, [r0, #PM_INFO_L2_V_OFFSET]
+ /* Wait for background operations to complete. */
+wait_for_l2_idle:
+ ldr r6, [r10, #0x730]
+ cmp r6, #0x0
+ bne wait_for_l2_idle
+
+ mov r6, #0x0
+ str r6, [r10, #0x730]
+ /* disable L2 */
+ str r6, [r10, #0x100]
+
+ dsb
+ isb
+#endif
+
+ /* make sure MMDC in self-refresh */
+ ldr r10, [r0, #PM_INFO_MMDC_V_OFFSET]
+ mmdc_enter_dvfs_mode
+ /* save DDR IO settings and set to LPM mode*/
+ ldr r10, [r0, #PM_INFO_IOMUXC_V_OFFSET]
+ ldr r6, =0x0
+ ldr r7, [r0, #PM_INFO_IO_NUM_OFFSET]
+ ldr r8, =PM_INFO_IO_VAL_OFFSET
+ add r8, r8, r0
+
+ /* imx6sl's last 3 IOs need special setting */
+ sub r7, r7, #0x3
+save_and_set_mmdc_io_lpm:
+ ldr r9, [r8], #0x4
+ ldr r5, [r10, r9]
+ str r6, [r10, r9]
+ str r5, [r8], #0x4
+ subs r7, r7, #0x1
+ bne save_and_set_mmdc_io_lpm
+ ldr r6, =0x1000
+ ldr r9, [r8], #0x4
+ ldr r5, [r10, r9]
+ str r5, [r8], #0x4
+ str r6, [r10, r9]
+ ldr r9, [r8], #0x4
+ ldr r5, [r10, r9]
+ str r6, [r10, r9]
+ str r5, [r8], #0x4
+ ldr r6, =0x80000
+ ldr r9, [r8], #0x4
+ ldr r5, [r10, r9]
+ str r6, [r10, r9]
+ str r5, [r8], #0x4
+
+
+ /* check the PLLs lock state */
+ check_pll_state
+
+ ccm_enter_idle
+ /* if in audio low power mode, no
+ * need to do anatop setting.
+ */
+ cmp r1, #0x1
+ beq do_wfi
+ anatop_enter_idle
+do_wfi:
+ wfi
+ /*
+ * Add these nops so that the
+ * prefetcher will not try to get
+ * any instrutions from DDR.
+ * The prefetch depth is about 23
+ * on A9, so adding 25 nops.
+ */
+ nop
+ nop
+ nop
+ nop
+ nop
+
+ nop
+ nop
+ nop
+ nop
+ nop
+
+ nop
+ nop
+ nop
+ nop
+ nop
+
+ nop
+ nop
+ nop
+ nop
+ nop
+
+ nop
+ nop
+ nop
+ nop
+ nop
+
+ /*
+ * restore the ARM PODF first to speed
+ * up the restore procedure
+ */
+ ldr r10, [r0, #PM_INFO_CCM_V_OFFSET]
+ /* Restore arm_clk_podf */
+ str r11, [r10, #0x10]
+ ccm_do_wait
+
+ /*
+ * if in audio low power mode, skip
+ * restore the anatop setting.
+ */
+ cmp r1, #0x1
+ beq skip_analog_restore
+ anatop_exit_idle
+
+skip_analog_restore:
+ ccm_exit_idle
+ resume_mmdc
+
+ /* enable d-cache */
+ mrc p15, 0, r7, c1, c0, 0
+ orr r7, r7, #(1 << 2)
+ mcr p15, 0, r7, c1, c0, 0
+
+#ifdef CONFIG_CACHE_L2X0
+ ldr r10, [r0, #PM_INFO_L2_V_OFFSET]
+ mov r7, #0x1
+ /* enable L2 */
+ str r7, [r10, #0x100]
+#endif
+ tlb_back_to_ddr
+
+ /* Restore register */
+ pop {r4 - r12}
+ mov pc, lr
+
+ /*
+ * Add ltorg here to ensure that all
+ * literals are stored here and are
+ * within the text space.
+ */
+ .ltorg
+mx6sl_lpm_wfi_end:
diff --git a/arch/arm/mach-imx/imx6sll_low_power_idle.S b/arch/arm/mach-imx/imx6sll_low_power_idle.S
new file mode 100644
index 000000000000..a7e206ecbb42
--- /dev/null
+++ b/arch/arm/mach-imx/imx6sll_low_power_idle.S
@@ -0,0 +1,780 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/linkage.h>
+
+#define PM_INFO_PBASE_OFFSET 0x0
+#define PM_INFO_RESUME_ADDR_OFFSET 0x4
+#define PM_INFO_PM_INFO_SIZE_OFFSET 0x8
+#define PM_INFO_PM_INFO_TTBR_OFFSET 0xc
+#define PM_INFO_MX6Q_MMDC_P_OFFSET 0x10
+#define PM_INFO_MX6Q_MMDC_V_OFFSET 0x14
+#define PM_INFO_MX6Q_IOMUXC_P_OFFSET 0x18
+#define PM_INFO_MX6Q_IOMUXC_V_OFFSET 0x1c
+#define PM_INFO_MX6Q_CCM_P_OFFSET 0x20
+#define PM_INFO_MX6Q_CCM_V_OFFSET 0x24
+#define PM_INFO_MX6Q_GPC_P_OFFSET 0x28
+#define PM_INFO_MX6Q_GPC_V_OFFSET 0x2c
+#define PM_INFO_MX6Q_ANATOP_P_OFFSET 0x30
+#define PM_INFO_MX6Q_ANATOP_V_OFFSET 0x34
+#define PM_INFO_MX6Q_SRC_P_OFFSET 0x38
+#define PM_INFO_MX6Q_SRC_V_OFFSET 0x3c
+#define PM_INFO_MX6Q_L2_P_OFFSET 0x40
+#define PM_INFO_MX6Q_L2_V_OFFSET 0x44
+#define PM_INFO_MX6Q_SAVED_DIAGNOSTIC_OFFSET 0x48
+
+#define PM_INFO_MMDC_IO_NUM_OFFSET 0x4c
+#define PM_INFO_MMDC_IO_VAL_OFFSET 0x50
+
+#define MX6Q_MMDC_MAPSR 0x404
+#define MX6Q_MMDC_MPDGCTRL0 0x83c
+#define MX6Q_SRC_GPR1 0x20
+#define MX6Q_SRC_GPR2 0x24
+#define MX6Q_GPC_IMR1 0x08
+#define MX6Q_GPC_IMR2 0x0c
+#define MX6Q_GPC_IMR3 0x10
+#define MX6Q_GPC_IMR4 0x14
+#define MX6Q_CCM_CCR 0x0
+
+.globl mx6sll_lpm_wfi_start
+.globl mx6sll_lpm_wfi_end
+
+ .macro pll_do_wait_lock
+1:
+ ldr r7, [r10, r8]
+ ands r7, #0x80000000
+ beq 1b
+
+ .endm
+
+ .macro ccm_do_wait
+2:
+ ldr r7, [r10, #0x48]
+ cmp r7, #0x0
+ bne 2b
+
+ .endm
+
+ .macro ccm_enter_idle
+
+ ldr r10, [r0, #PM_INFO_MX6Q_CCM_V_OFFSET]
+
+ /* set ahb to 3MHz */
+ ldr r7, [r10, #0x14]
+ orr r7, r7, #0x1c00
+ str r7, [r10, #0x14]
+
+ /* set perclk to 6MHz */
+ ldr r7, [r10, #0x1c]
+ bic r7, r7, #0x3f
+ orr r7, r7, #0x3
+ str r7, [r10, #0x1c]
+
+ /* set mmdc to 1MHz, periph2_clk2 need to be @8MHz */
+ ldr r7, [r10, #0x14]
+ orr r7, r7, #0x2
+ orr r7, r7, #(0x7 << 3)
+ str r7, [r10, #0x14]
+
+ ccm_do_wait
+
+ ldr r10, [r0, #PM_INFO_MX6Q_ANATOP_V_OFFSET]
+
+ /*
+ * disable pll2, suppose when system enter low
+ * power idle mode, only 396MHz pfd needs pll2,
+ * now we switch arm clock to OSC, we can disable
+ * pll2 now, gate pll2_pfd2 first.
+ */
+ ldr r7, [r10, #0x100]
+ orr r7, #0x800000
+ str r7, [r10, #0x100]
+
+ ldr r7, [r10, #0x30]
+ orr r7, r7, #0x1000
+ bic r7, r7, #0x2000
+ str r7, [r10, #0x30]
+
+ .endm
+
+ .macro ccm_exit_idle
+
+ cmp r5, #0x0
+ ldreq r10, [r0, #PM_INFO_MX6Q_ANATOP_V_OFFSET]
+ ldrne r10, [r0, #PM_INFO_MX6Q_ANATOP_P_OFFSET]
+
+ /* enable pll2 and pll2_pfd2 */
+ ldr r7, [r10, #0x30]
+ bic r7, r7, #0x1000
+ orr r7, r7, #0x2000
+ str r7, [r10, #0x30]
+
+ ldr r8, =0x30
+ pll_do_wait_lock
+
+ ldr r7, [r10, #0x100]
+ bic r7, #0x800000
+ str r7, [r10, #0x100]
+
+ cmp r5, #0x0
+ ldreq r10, [r0, #PM_INFO_MX6Q_CCM_V_OFFSET]
+ ldrne r10, [r0, #PM_INFO_MX6Q_CCM_P_OFFSET]
+
+ /* set perclk back to 24MHz */
+ ldr r7, [r10, #0x1c]
+ bic r7, r7, #0x3f
+ str r7, [r10, #0x1c]
+
+ /* set mmdc back to 24MHz */
+ ldr r7, [r10, #0x14]
+ bic r7, r7, #0x7
+ bic r7, r7, #(0x7 << 3)
+ str r7, [r10, #0x14]
+
+ /* set ahb div back to 24MHz */
+ ldr r7, [r10, #0x14]
+ bic r7, r7, #0x1c00
+ str r7, [r10, #0x14]
+
+ ccm_do_wait
+
+ .endm
+
+ .macro anatop_enter_idle
+
+ ldr r10, [r0, #PM_INFO_MX6Q_ANATOP_V_OFFSET]
+
+ /*
+ * check whether any PLL is enabled, as only when
+ * there is no PLLs enabled, 2P5 and 1P1 can be
+ * off and only enable weak ones.
+ */
+
+ /* arm pll1 */
+ ldr r7, [r10, #0]
+ ands r7, r7, #(1 << 31)
+ bne 10f
+
+ /* sys pll2 */
+ ldr r7, [r10, #0x30]
+ ands r7, r7, #(1 << 31)
+ bne 10f
+
+ /* usb pll3 */
+ ldr r7, [r10, #0x10]
+ ands r7, r7, #(1 << 31)
+ bne 10f
+
+ /* audio pll4 */
+ ldr r7, [r10, #0x70]
+ ands r7, r7, #(1 << 31)
+ bne 10f
+
+ /* vidio pll5 */
+ ldr r7, [r10, #0xa0]
+ ands r7, r7, #(1 << 31)
+ bne 10f
+
+ /* enet pll6 */
+ ldr r7, [r10, #0xe0]
+ ands r7, r7, #(1 << 31)
+ bne 10f
+
+ /* usb host pll7 */
+ ldr r7, [r10, #0x20]
+ ands r7, r7, #(1 << 31)
+ bne 10f
+
+ /* enable weak 2P5 and turn off regular 2P5 */
+ ldr r7, [r10, #0x130]
+ orr r7, r7, #0x40000
+ str r7, [r10, #0x130]
+ bic r7, r7, #0x1
+ str r7, [r10, #0x130]
+
+ /* enable weak 1p1 and turn off regular 1P1 */
+ ldr r7, [r10, #0x110]
+ orr r7, r7, #0x40000
+ str r7, [r10, #0x110]
+ bic r7, r7, #0x1
+ str r7, [r10, #0x110]
+
+ /* low power band gap enable */
+ ldr r7, [r10, #0x270]
+ orr r7, r7, #0x20
+ str r7, [r10, #0x270]
+
+ /* turn off the bias current from the regular bandgap */
+ ldr r7, [r10, #0x270]
+ orr r7, r7, #0x80
+ str r7, [r10, #0x270]
+
+ /*
+ * clear the REFTOP_SELFBIASOFF,
+ * self-bias circuit of the band gap.
+ * Per RM, should be cleared when
+ * band gap is powered down.
+ */
+ ldr r7, [r10, #0x150]
+ bic r7, r7, #0x8
+ str r7, [r10, #0x150]
+
+ /* turn off regular bandgap */
+ ldr r7, [r10, #0x150]
+ orr r7, r7, #0x1
+ str r7, [r10, #0x150]
+
+10:
+ /* switch to RC-OSC */
+ ldr r7, [r10, #0x270]
+ orr r7, r7, #0x10
+ str r7, [r10, #0x270]
+
+ /* turn off XTAL-OSC */
+ ldr r7, [r10, #0x150]
+ orr r7, r7, #0x40000000
+ str r7, [r10, #0x150]
+
+ /* lower OSC current by 37.5% */
+ ldr r7, [r10, #0x150]
+ orr r7, r7, #0x6000
+ str r7, [r10, #0x150]
+
+ /* disconnect vdd_high_in and vdd_snvs_in */
+ ldr r7, [r10, #0x150]
+ orr r7, r7, #0x1000
+ str r7, [r10, #0x150]
+
+ .endm
+
+ .macro anatop_exit_idle
+
+ cmp r5, #0x0
+ ldreq r10, [r0, #PM_INFO_MX6Q_ANATOP_V_OFFSET]
+ ldrne r10, [r0, #PM_INFO_MX6Q_ANATOP_P_OFFSET]
+
+ /* increase OSC current to normal */
+ ldr r7, [r10, #0x150]
+ bic r7, r7, #0x6000
+ str r7, [r10, #0x150]
+
+ /* turn on XTAL-OSC and detector */
+ ldr r7, [r10, #0x150]
+ bic r7, r7, #0x40000000
+ orr r7, r7, #0x10000
+ str r7, [r10, #0x150]
+
+ /* wait for XTAL stable */
+14:
+ ldr r7, [r10, #0x150]
+ ands r7, r7, #0x8000
+ beq 14b
+
+ /* switch to XTAL-OSC */
+ ldr r7, [r10, #0x270]
+ bic r7, r7, #0x10
+ str r7, [r10, #0x270]
+
+ /* turn off XTAL-OSC detector */
+ ldr r7, [r10, #0x150]
+ bic r7, r7, #0x10000
+ str r7, [r10, #0x150]
+15:
+ /* check whether we need to enable 2P5/1P1 */
+ ldr r7, [r10, #0x110]
+ ands r7, r7, #0x40000
+ beq 11f
+
+ /* turn on regular bandgap and wait for stable */
+ ldr r7, [r10, #0x150]
+ bic r7, r7, #0x1
+ str r7, [r10, #0x150]
+13:
+ ldr r7, [r10, #0x150]
+ ands r7, #0x80
+ beq 13b
+
+ /*
+ * set the REFTOP_SELFBIASOFF,
+ * self-bias circuit of the band gap.
+ */
+ ldr r7, [r10, #0x150]
+ orr r7, r7, #0x8
+ str r7, [r10, #0x150]
+
+ /* turn on the bias current from the regular bandgap */
+ ldr r7, [r10, #0x270]
+ bic r7, r7, #0x80
+ str r7, [r10, #0x270]
+
+ /* low power band gap disable */
+ ldr r7, [r10, #0x270]
+ bic r7, r7, #0x20
+ str r7, [r10, #0x270]
+12:
+ /* enable regular 2P5 and turn off weak 2P5 */
+ ldr r7, [r10, #0x130]
+ orr r7, r7, #0x1
+ str r7, [r10, #0x130]
+
+ /* Ensure the 2P5 is up. */
+3:
+ ldr r7, [r10, #0x130]
+ ands r7, r7, #0x20000
+ beq 3b
+ ldr r7, [r10, #0x130]
+ bic r7, r7, #0x40000
+ str r7, [r10, #0x130]
+
+ /* enable regular 1p1 and turn off weak 1P1 */
+ ldr r7, [r10, #0x110]
+ orr r7, r7, #0x1
+ str r7, [r10, #0x110]
+4:
+ ldr r7, [r10, #0x110]
+ ands r7, r7, #0x20000
+ beq 4b
+ ldr r7, [r10, #0x110]
+ bic r7, r7, #0x40000
+ str r7, [r10, #0x110]
+11:
+ .endm
+
+ .macro disable_l1_dcache
+
+ /*
+ * Flush all data from the L1 data cache before disabling
+ * SCTLR.C bit.
+ */
+ push {r0 - r10, lr}
+ ldr r7, =v7_flush_dcache_all
+ mov lr, pc
+ mov pc, r7
+ pop {r0 - r10, lr}
+
+ /* disable d-cache */
+ mrc p15, 0, r7, c1, c0, 0
+ bic r7, r7, #(1 << 2)
+ mcr p15, 0, r7, c1, c0, 0
+ dsb
+ isb
+
+ push {r0 - r10, lr}
+ ldr r7, =v7_flush_dcache_all
+ mov lr, pc
+ mov pc, r7
+ pop {r0 - r10, lr}
+
+ .endm
+
+ .macro mmdc_enter_dvfs_mode
+
+ /* disable automatic power savings. */
+ ldr r7, [r10, #MX6Q_MMDC_MAPSR]
+ orr r7, r7, #0x1
+ str r7, [r10, #MX6Q_MMDC_MAPSR]
+
+ /* make the DDR explicitly enter self-refresh. */
+ ldr r7, [r10, #MX6Q_MMDC_MAPSR]
+ orr r7, r7, #(1 << 21)
+ str r7, [r10, #MX6Q_MMDC_MAPSR]
+5:
+ ldr r7, [r10, #MX6Q_MMDC_MAPSR]
+ ands r7, r7, #(1 << 25)
+ beq 5b
+
+ .endm
+
+ .macro resume_mmdc
+
+ /* restore MMDC IO */
+ cmp r5, #0x0
+ ldreq r10, [r0, #PM_INFO_MX6Q_IOMUXC_V_OFFSET]
+ ldrne r10, [r0, #PM_INFO_MX6Q_IOMUXC_P_OFFSET]
+
+ ldr r6, [r0, #PM_INFO_MMDC_IO_NUM_OFFSET]
+ ldr r7, =PM_INFO_MMDC_IO_VAL_OFFSET
+ add r7, r7, r0
+6:
+ ldr r8, [r7], #0x4
+ ldr r9, [r7], #0x4
+ str r9, [r10, r8]
+ subs r6, r6, #0x1
+ bne 6b
+
+ cmp r5, #0x0
+ ldreq r10, [r0, #PM_INFO_MX6Q_MMDC_V_OFFSET]
+ ldrne r10, [r0, #PM_INFO_MX6Q_MMDC_P_OFFSET]
+
+ /* reset read FIFO, RST_RD_FIFO */
+ ldr r7, =MX6Q_MMDC_MPDGCTRL0
+ ldr r6, [r10, r7]
+ orr r6, r6, #(1 << 31)
+ str r6, [r10, r7]
+7:
+ ldr r6, [r10, r7]
+ ands r6, r6, #(1 << 31)
+ bne 7b
+
+ /* reset FIFO a second time */
+ ldr r6, [r10, r7]
+ orr r6, r6, #(1 << 31)
+ str r6, [r10, r7]
+8:
+ ldr r6, [r10, r7]
+ ands r6, r6, #(1 << 31)
+ bne 8b
+
+ /* let DDR out of self-refresh */
+ ldr r7, [r10, #MX6Q_MMDC_MAPSR]
+ bic r7, r7, #(1 << 21)
+ str r7, [r10, #MX6Q_MMDC_MAPSR]
+9:
+ ldr r7, [r10, #MX6Q_MMDC_MAPSR]
+ ands r7, r7, #(1 << 25)
+ bne 9b
+
+ /* enable DDR auto power saving */
+ ldr r7, [r10, #MX6Q_MMDC_MAPSR]
+ bic r7, r7, #0x1
+ str r7, [r10, #MX6Q_MMDC_MAPSR]
+
+ .endm
+
+ .macro tlb_set_to_ocram
+
+ /* save ttbr */
+ mrc p15, 0, r7, c2, c0, 1
+ str r7, [r0, #PM_INFO_PM_INFO_TTBR_OFFSET]
+
+ /*
+ * To ensure no page table walks occur in DDR, we
+ * have a another page table stored in IRAM that only
+ * contains entries pointing to IRAM, AIPS1 and AIPS2.
+ * We need to set the TTBR1 to the new IRAM TLB.
+ * Do the following steps:
+ * 1. Flush the Branch Target Address Cache (BTAC)
+ * 2. Set TTBR1 to point to IRAM page table.
+ * 3. Disable page table walks in TTBR0 (PD0 = 1)
+ * 4. Set TTBR0.N=1, implying 0-2G is translated by TTBR0
+ * and 2-4G is translated by TTBR1.
+ */
+
+ ldr r6, =iram_tlb_phys_addr
+ ldr r7, [r6]
+
+ /* Flush the BTAC. */
+ ldr r6, =0x0
+ mcr p15, 0, r6, c7, c1, 6
+
+ /* Disable Branch Prediction, Z bit in SCTLR. */
+ mrc p15, 0, r6, c1, c0, 0
+ bic r6, r6, #0x800
+ mcr p15, 0, r6, c1, c0, 0
+
+ dsb
+ isb
+
+ /* Store the IRAM table in TTBR1 */
+ mcr p15, 0, r7, c2, c0, 1
+
+ /* Read TTBCR and set PD0=1, N = 1 */
+ mrc p15, 0, r6, c2, c0, 2
+ orr r6, r6, #0x11
+ mcr p15, 0, r6, c2, c0, 2
+
+ dsb
+ isb
+
+ /* flush the TLB */
+ ldr r6, =0x0
+ mcr p15, 0, r6, c8, c3, 0
+
+ .endm
+
+ .macro tlb_back_to_ddr
+
+ /* Restore the TTBCR */
+
+ dsb
+ isb
+
+ /* Read TTBCR and set PD0=0, N = 0 */
+ mrc p15, 0, r6, c2, c0, 2
+ bic r6, r6, #0x11
+ mcr p15, 0, r6, c2, c0, 2
+
+ dsb
+ isb
+
+ /* flush the TLB */
+ ldr r6, =0x0
+ mcr p15, 0, r6, c8, c3, 0
+
+ dsb
+ isb
+
+ /* Enable Branch Prediction, Z bit in SCTLR. */
+ mrc p15, 0, r6, c1, c0, 0
+ orr r6, r6, #0x800
+ mcr p15, 0, r6, c1, c0, 0
+
+ /* Flush the Branch Target Address Cache (BTAC) */
+ ldr r6, =0x0
+ mcr p15, 0, r6, c7, c1, 6
+
+ /* restore ttbr */
+ ldr r7, [r0, #PM_INFO_PM_INFO_TTBR_OFFSET]
+ mcr p15, 0, r7, c2, c0, 1
+
+ .endm
+
+.extern iram_tlb_phys_addr
+
+/* imx6sx_low_power_idle */
+
+ .align 3
+ENTRY(imx6sll_low_power_idle)
+mx6sll_lpm_wfi_start:
+ push {r4 - r10}
+
+ /* get necessary info from pm_info */
+ ldr r1, [r0, #PM_INFO_PBASE_OFFSET]
+ ldr r2, [r0, #PM_INFO_PM_INFO_SIZE_OFFSET]
+
+ /*
+ * counting the resume address in iram
+ * to set it in SRC register.
+ */
+ ldr r5, =imx6sll_low_power_idle
+ ldr r6, =wakeup
+ sub r6, r6, r5
+ add r8, r1, r2
+ add r3, r8, r6
+
+ /* store physical resume addr and pm_info address. */
+ ldr r10, [r0, #PM_INFO_MX6Q_SRC_V_OFFSET]
+ str r3, [r10, #0x20]
+ str r1, [r10, #0x24]
+
+ /* save disagnostic register */
+ mrc p15, 0, r7, c15, c0, 1
+ str r7, [r0, #PM_INFO_MX6Q_SAVED_DIAGNOSTIC_OFFSET]
+
+ /* set ARM power to be gated */
+ ldr r10, [r0, #PM_INFO_MX6Q_GPC_V_OFFSET]
+ ldr r7, =0x1
+ str r7, [r10, #0x2a0]
+
+ disable_l1_dcache
+
+#ifdef CONFIG_CACHE_L2X0
+ /* sync L2 */
+ ldr r10, [r0, #PM_INFO_MX6Q_L2_V_OFFSET]
+
+ /* Wait for background operations to complete. */
+wait_for_l2_to_idle:
+ ldr r7, [r10, #0x730]
+ cmp r7, #0x0
+ bne wait_for_l2_to_idle
+
+ mov r7, #0x0
+ str r7, [r10, #0x730]
+ /* disable L2 */
+ str r7, [r10, #0x100]
+
+ dsb
+ isb
+#endif
+
+ tlb_set_to_ocram
+
+ /* make sure MMDC in self-refresh */
+ ldr r10, [r0, #PM_INFO_MX6Q_MMDC_V_OFFSET]
+ mmdc_enter_dvfs_mode
+
+ /* save DDR IO settings */
+ ldr r10, [r0, #PM_INFO_MX6Q_IOMUXC_V_OFFSET]
+ ldr r6, =0x0
+ ldr r7, [r0, #PM_INFO_MMDC_IO_NUM_OFFSET]
+ ldr r8, =PM_INFO_MMDC_IO_VAL_OFFSET
+ add r8, r8, r0
+save_and_set_mmdc_io_lpm:
+ ldr r9, [r8], #0x4
+ ldr r5, [r10, r9]
+ str r6, [r10, r9]
+ str r5, [r8], #0x4
+ subs r7, r7, #0x1
+ bne save_and_set_mmdc_io_lpm
+
+ mov r5, #0x0
+ ccm_enter_idle
+ anatop_enter_idle
+
+ /*
+ * mask all GPC interrupts before
+ * enabling the RBC counters to
+ * avoid the counter starting too
+ * early if an interupt is already
+ * pending.
+ */
+ ldr r10, [r0, #PM_INFO_MX6Q_GPC_V_OFFSET]
+ ldr r4, [r10, #MX6Q_GPC_IMR1]
+ ldr r5, [r10, #MX6Q_GPC_IMR2]
+ ldr r6, [r10, #MX6Q_GPC_IMR3]
+ ldr r7, [r10, #MX6Q_GPC_IMR4]
+
+ ldr r3, =0xffffffff
+ str r3, [r10, #MX6Q_GPC_IMR1]
+ str r3, [r10, #MX6Q_GPC_IMR2]
+ str r3, [r10, #MX6Q_GPC_IMR3]
+ str r3, [r10, #MX6Q_GPC_IMR4]
+
+ /*
+ * enable the RBC bypass counter here
+ * to hold off the interrupts. RBC counter
+ * = 4 (120us). With this setting, the latency
+ * from wakeup interrupt to ARM power up
+ * is ~130uS.
+ */
+ ldr r10, [r0, #PM_INFO_MX6Q_CCM_V_OFFSET]
+ ldr r3, [r10, #MX6Q_CCM_CCR]
+ bic r3, r3, #(0x3f << 21)
+ orr r3, r3, #(0x4 << 21)
+ str r3, [r10, #MX6Q_CCM_CCR]
+
+ /* enable the counter. */
+ ldr r3, [r10, #MX6Q_CCM_CCR]
+ orr r3, r3, #(0x1 << 27)
+ str r3, [r10, #MX6Q_CCM_CCR]
+
+ /* unmask all the GPC interrupts. */
+ ldr r10, [r0, #PM_INFO_MX6Q_GPC_V_OFFSET]
+ str r4, [r10, #MX6Q_GPC_IMR1]
+ str r5, [r10, #MX6Q_GPC_IMR2]
+ str r6, [r10, #MX6Q_GPC_IMR3]
+ str r7, [r10, #MX6Q_GPC_IMR4]
+
+ /*
+ * now delay for a short while (3usec)
+ * ARM is at 24MHz at this point
+ * so a short loop should be enough.
+ * this delay is required to ensure that
+ * the RBC counter can start counting in
+ * case an interrupt is already pending
+ * or in case an interrupt arrives just
+ * as ARM is about to assert DSM_request.
+ */
+ ldr r4, =50
+rbc_loop:
+ subs r4, r4, #0x1
+ bne rbc_loop
+
+ wfi
+
+ nop
+ nop
+ nop
+ nop
+ nop
+
+ nop
+ nop
+ nop
+ nop
+ nop
+
+ nop
+ nop
+ nop
+ nop
+ nop
+
+ nop
+ nop
+ nop
+ nop
+ nop
+
+ nop
+ nop
+ nop
+ nop
+ nop
+
+ mov r5, #0x0
+ anatop_exit_idle
+ ccm_exit_idle
+ resume_mmdc
+
+ /* clear ARM power gate setting */
+ ldr r10, [r0, #PM_INFO_MX6Q_GPC_V_OFFSET]
+ ldr r7, =0x0
+ str r7, [r10, #0x2a0]
+
+ /* enable d-cache */
+ mrc p15, 0, r7, c1, c0, 0
+ orr r7, r7, #(1 << 2)
+ mcr p15, 0, r7, c1, c0, 0
+
+#ifdef CONFIG_CACHE_L2X0
+ ldr r10, [r0, #PM_INFO_MX6Q_L2_V_OFFSET]
+ mov r7, #0x1
+ /* enable L2 */
+ str r7, [r10, #0x100]
+#endif
+
+ tlb_back_to_ddr
+
+ /* Restore registers */
+ pop {r4 - r10}
+ mov pc, lr
+
+wakeup:
+
+ /* invalidate L1 I-cache first */
+ mov r1, #0x0
+ mcr p15, 0, r1, c7, c5, 0
+ mcr p15, 0, r1, c7, c5, 0
+ mcr p15, 0, r1, c7, c5, 6
+ /* enable the Icache and branch prediction */
+ mov r1, #0x1800
+ mcr p15, 0, r1, c1, c0, 0
+ isb
+ /* restore disagnostic register */
+ ldr r7, [r0, #PM_INFO_MX6Q_SAVED_DIAGNOSTIC_OFFSET]
+ mcr p15, 0, r7, c15, c0, 1
+
+ /* get physical resume address from pm_info. */
+ ldr lr, [r0, #PM_INFO_RESUME_ADDR_OFFSET]
+ /* clear core0's entry and parameter */
+ ldr r10, [r0, #PM_INFO_MX6Q_SRC_P_OFFSET]
+ mov r7, #0x0
+ str r7, [r10, #MX6Q_SRC_GPR1]
+ str r7, [r10, #MX6Q_SRC_GPR2]
+
+ /* clear ARM power gate setting */
+ ldr r10, [r0, #PM_INFO_MX6Q_GPC_P_OFFSET]
+ ldr r7, =0x0
+ str r7, [r10, #0x2a0]
+
+ mov r5, #0x1
+ anatop_exit_idle
+ ccm_exit_idle
+ resume_mmdc
+
+ /* Restore registers */
+ mov pc, lr
+ .ltorg
+mx6sll_lpm_wfi_end:
diff --git a/arch/arm/mach-imx/imx6sx_low_power_idle.S b/arch/arm/mach-imx/imx6sx_low_power_idle.S
new file mode 100644
index 000000000000..7ddda1cd1a8f
--- /dev/null
+++ b/arch/arm/mach-imx/imx6sx_low_power_idle.S
@@ -0,0 +1,887 @@
+/*
+ * Copyright (C) 2014-2015 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/linkage.h>
+
+#define PM_INFO_PBASE_OFFSET 0x0
+#define PM_INFO_RESUME_ADDR_OFFSET 0x4
+#define PM_INFO_PM_INFO_SIZE_OFFSET 0x8
+#define PM_INFO_PM_INFO_TTBR_OFFSET 0xc
+#define PM_INFO_MX6Q_MMDC_P_OFFSET 0x10
+#define PM_INFO_MX6Q_MMDC_V_OFFSET 0x14
+#define PM_INFO_MX6Q_IOMUXC_P_OFFSET 0x18
+#define PM_INFO_MX6Q_IOMUXC_V_OFFSET 0x1c
+#define PM_INFO_MX6Q_CCM_P_OFFSET 0x20
+#define PM_INFO_MX6Q_CCM_V_OFFSET 0x24
+#define PM_INFO_MX6Q_GPC_P_OFFSET 0x28
+#define PM_INFO_MX6Q_GPC_V_OFFSET 0x2c
+#define PM_INFO_MX6Q_L2_P_OFFSET 0x30
+#define PM_INFO_MX6Q_L2_V_OFFSET 0x34
+#define PM_INFO_MX6Q_ANATOP_P_OFFSET 0x38
+#define PM_INFO_MX6Q_ANATOP_V_OFFSET 0x3c
+#define PM_INFO_MX6Q_SRC_P_OFFSET 0x40
+#define PM_INFO_MX6Q_SRC_V_OFFSET 0x44
+#define PM_INFO_MX6Q_SEMA4_P_OFFSET 0x48
+#define PM_INFO_MX6Q_SEMA4_V_OFFSET 0x4c
+#define PM_INFO_MX6Q_SAVED_DIAGNOSTIC_OFFSET 0x50
+#define PM_INFO_MMDC_IO_NUM_OFFSET 0x54
+#define PM_INFO_MMDC_IO_VAL_OFFSET 0x58
+
+#define MX6Q_MMDC_MAPSR 0x404
+#define MX6Q_MMDC_MPDGCTRL0 0x83c
+#define MX6Q_SRC_GPR1 0x20
+#define MX6Q_SRC_GPR2 0x24
+#define MX6Q_GPC_IMR1 0x08
+#define MX6Q_GPC_IMR2 0x0c
+#define MX6Q_GPC_IMR3 0x10
+#define MX6Q_GPC_IMR4 0x14
+#define MX6Q_CCM_CCR 0x0
+
+.globl mx6sx_lpm_wfi_start
+.globl mx6sx_lpm_wfi_end
+
+ .macro pll_do_wait_lock
+1:
+ ldr r7, [r10, r8]
+ ands r7, #0x80000000
+ beq 1b
+
+ .endm
+
+ .macro ccm_do_wait
+2:
+ ldr r7, [r10, #0x48]
+ cmp r7, #0x0
+ bne 2b
+
+ .endm
+
+ .macro ccm_enter_idle
+
+ ldr r10, [r0, #PM_INFO_MX6Q_CCM_V_OFFSET]
+
+ /* set ahb to 3MHz */
+ ldr r7, [r10, #0x14]
+ orr r7, r7, #0x1c00
+ str r7, [r10, #0x14]
+
+ /* set perclk to 6MHz */
+ ldr r7, [r10, #0x1c]
+ bic r7, r7, #0x3f
+ orr r7, r7, #0x3
+ str r7, [r10, #0x1c]
+
+ /* set mmdc to 1MHz, periph2_clk2 need to be @8MHz */
+ ldr r7, [r10, #0x14]
+ orr r7, r7, #0x2
+ orr r7, r7, #(0x7 << 3)
+ str r7, [r10, #0x14]
+
+ ccm_do_wait
+
+ ldr r10, [r0, #PM_INFO_MX6Q_CCM_V_OFFSET]
+
+ /* set pll1_sw to from pll1 main */
+ ldr r7, [r10, #0xc]
+ bic r7, r7, #0x4
+ str r7, [r10, #0xc]
+
+ /* set step from osc */
+ ldr r7, [r10, #0xc]
+ bic r7, r7, #0x100
+ str r7, [r10, #0xc]
+
+ /* set pll1_sw to from step */
+ ldr r7, [r10, #0xc]
+ orr r7, r7, #0x4
+ str r7, [r10, #0xc]
+
+ ldr r10, [r0, #PM_INFO_MX6Q_ANATOP_V_OFFSET]
+
+ /* Disable PLL1 bypass output */
+ ldr r7, [r10]
+ bic r7, r7, #0x12000
+ str r7, [r10]
+
+ /*
+ * disable pll2, suppose when system enter low
+ * power idle mode, only 396MHz pfd needs pll2,
+ * now we switch arm clock to OSC, we can disable
+ * pll2 now, gate pll2_pfd2 first.
+ */
+ ldr r7, [r10, #0x100]
+ orr r7, #0x800000
+ str r7, [r10, #0x100]
+
+ ldr r7, [r10, #0x30]
+ orr r7, r7, #0x1000
+ bic r7, r7, #0x2000
+ str r7, [r10, #0x30]
+
+ .endm
+
+ .macro ccm_exit_idle
+
+ cmp r5, #0x0
+ ldreq r10, [r0, #PM_INFO_MX6Q_ANATOP_V_OFFSET]
+ ldrne r10, [r0, #PM_INFO_MX6Q_ANATOP_P_OFFSET]
+
+ /* enable pll2 and pll2_pfd2 */
+ ldr r7, [r10, #0x30]
+ bic r7, r7, #0x1000
+ orr r7, r7, #0x2000
+ str r7, [r10, #0x30]
+
+ ldr r8, =0x30
+ pll_do_wait_lock
+
+ ldr r7, [r10, #0x100]
+ bic r7, #0x800000
+ str r7, [r10, #0x100]
+
+ /* enable PLL1 bypass output */
+ ldr r7, [r10]
+ orr r7, r7, #0x12000
+ str r7, [r10]
+
+ cmp r5, #0x0
+ ldreq r10, [r0, #PM_INFO_MX6Q_CCM_V_OFFSET]
+ ldrne r10, [r0, #PM_INFO_MX6Q_CCM_P_OFFSET]
+
+ /* set perclk back to 24MHz */
+ ldr r7, [r10, #0x1c]
+ bic r7, r7, #0x3f
+ str r7, [r10, #0x1c]
+
+ /* set mmdc back to 24MHz */
+ ldr r7, [r10, #0x14]
+ bic r7, r7, #0x7
+ bic r7, r7, #(0x7 << 3)
+ str r7, [r10, #0x14]
+
+ /* set ahb div back to 24MHz */
+ ldr r7, [r10, #0x14]
+ bic r7, r7, #0x1c00
+ str r7, [r10, #0x14]
+
+ ccm_do_wait
+
+ /* set pll1_sw to from pll1 main */
+ ldr r7, [r10, #0xc]
+ bic r7, r7, #0x4
+ str r7, [r10, #0xc]
+
+ /* set step from pll2_pfd2 */
+ ldr r7, [r10, #0xc]
+ orr r7, r7, #0x100
+ str r7, [r10, #0xc]
+
+ /* set pll1_sw to from step */
+ ldr r7, [r10, #0xc]
+ orr r7, r7, #0x4
+ str r7, [r10, #0xc]
+
+ cmp r5, #0x0
+ ldreq r10, [r0, #PM_INFO_MX6Q_ANATOP_V_OFFSET]
+ ldrne r10, [r0, #PM_INFO_MX6Q_ANATOP_P_OFFSET]
+
+ .endm
+
+ .macro anatop_enter_idle
+
+ ldr r10, [r0, #PM_INFO_MX6Q_ANATOP_V_OFFSET]
+
+ /*
+ * check whether any PLL is enabled, as only when
+ * there is no PLLs enabled, 2P5 and 1P1 can be
+ * off and only enable weak ones.
+ */
+
+ /* arm pll1 */
+ ldr r7, [r10, #0]
+ ands r7, r7, #(1 << 31)
+ bne 10f
+
+ /* sys pll2 */
+ ldr r7, [r10, #0x30]
+ ands r7, r7, #(1 << 31)
+ bne 10f
+
+ /* usb pll3 */
+ ldr r7, [r10, #0x10]
+ ands r7, r7, #(1 << 31)
+ bne 10f
+
+ /* audio pll4 */
+ ldr r7, [r10, #0x70]
+ ands r7, r7, #(1 << 31)
+ bne 10f
+
+ /* vidio pll5 */
+ ldr r7, [r10, #0xa0]
+ ands r7, r7, #(1 << 31)
+ bne 10f
+
+ /* enet pll6 */
+ ldr r7, [r10, #0xe0]
+ ands r7, r7, #(1 << 31)
+ bne 10f
+
+ /* usb host pll7 */
+ ldr r7, [r10, #0x20]
+ ands r7, r7, #(1 << 31)
+ bne 10f
+
+ /* enable weak 2P5 and turn off regular 2P5 */
+ ldr r7, [r10, #0x130]
+ orr r7, r7, #0x40000
+ str r7, [r10, #0x130]
+ bic r7, r7, #0x1
+ str r7, [r10, #0x130]
+
+ /* enable weak 1p1 and turn off regular 1P1 */
+ ldr r7, [r10, #0x110]
+ orr r7, r7, #0x40000
+ str r7, [r10, #0x110]
+ bic r7, r7, #0x1
+ str r7, [r10, #0x110]
+
+ /* check whether ARM LDO is bypassed */
+ ldr r7, [r10, #0x140]
+ and r7, r7, #0x1f
+ cmp r7, #0x1f
+ bne 10f
+
+ /* low power band gap enable */
+ ldr r7, [r10, #0x270]
+ orr r7, r7, #0x20
+ str r7, [r10, #0x270]
+
+ /* turn off the bias current from the regular bandgap */
+ ldr r7, [r10, #0x270]
+ orr r7, r7, #0x80
+ str r7, [r10, #0x270]
+
+ /*
+ * clear the REFTOP_SELFBIASOFF,
+ * self-bias circuit of the band gap.
+ * Per RM, should be cleared when
+ * band gap is powered down.
+ */
+ ldr r7, [r10, #0x150]
+ bic r7, r7, #0x8
+ str r7, [r10, #0x150]
+
+ /* turn off regular bandgap */
+ ldr r7, [r10, #0x150]
+ orr r7, r7, #0x1
+ str r7, [r10, #0x150]
+
+ /* only switch to RC-OSC clk after TO1.2 */
+ ldr r7, [r10, #0x260]
+ and r7, r7, #0x3
+ cmp r7, #0x2
+ blt 10f
+
+ /* switch to RC-OSC */
+ ldr r7, [r10, #0x270]
+ orr r7, r7, #0x10
+ str r7, [r10, #0x270]
+
+ /* turn off XTAL-OSC */
+ ldr r7, [r10, #0x150]
+ orr r7, r7, #0x40000000
+ str r7, [r10, #0x150]
+10:
+ /* lower OSC current by 37.5% */
+ ldr r7, [r10, #0x150]
+ orr r7, r7, #0x6000
+ str r7, [r10, #0x150]
+
+ .endm
+
+ .macro anatop_exit_idle
+
+ cmp r5, #0x0
+ ldreq r10, [r0, #PM_INFO_MX6Q_ANATOP_V_OFFSET]
+ ldrne r10, [r0, #PM_INFO_MX6Q_ANATOP_P_OFFSET]
+
+ /* increase OSC current to normal */
+ ldr r7, [r10, #0x150]
+ bic r7, r7, #0x6000
+ str r7, [r10, #0x150]
+
+ /* only switch to RC-OSC after TO1.2 */
+ ldr r7, [r10, #0x260]
+ and r7, r7, #0x3
+ cmp r7, #0x2
+ blt 15f
+
+ /* turn on XTAL-OSC and detector */
+ ldr r7, [r10, #0x150]
+ bic r7, r7, #0x40000000
+ orr r7, r7, #0x10000
+ str r7, [r10, #0x150]
+
+ /* wait for XTAL stable */
+14:
+ ldr r7, [r10, #0x150]
+ ands r7, r7, #0x8000
+ beq 14b
+
+ /* switch to XTAL-OSC */
+ ldr r7, [r10, #0x270]
+ bic r7, r7, #0x10
+ str r7, [r10, #0x270]
+
+ /* turn off XTAL-OSC detector */
+ ldr r7, [r10, #0x150]
+ bic r7, r7, #0x10000
+ str r7, [r10, #0x150]
+15:
+ /* check whether we need to enable 2P5/1P1 */
+ ldr r7, [r10, #0x110]
+ ands r7, r7, #0x40000
+ beq 11f
+
+ /* check whether ARM LDO is bypassed */
+ ldr r7, [r10, #0x140]
+ and r7, r7, #0x1f
+ cmp r7, #0x1f
+ bne 12f
+
+ /* turn on regular bandgap and wait for stable */
+ ldr r7, [r10, #0x150]
+ bic r7, r7, #0x1
+ str r7, [r10, #0x150]
+13:
+ ldr r7, [r10, #0x150]
+ ands r7, #0x80
+ beq 13b
+
+ /*
+ * set the REFTOP_SELFBIASOFF,
+ * self-bias circuit of the band gap.
+ */
+ ldr r7, [r10, #0x150]
+ orr r7, r7, #0x8
+ str r7, [r10, #0x150]
+
+ /* turn on the bias current from the regular bandgap */
+ ldr r7, [r10, #0x270]
+ bic r7, r7, #0x80
+ str r7, [r10, #0x270]
+
+ /* low power band gap disable */
+ ldr r7, [r10, #0x270]
+ bic r7, r7, #0x20
+ str r7, [r10, #0x270]
+12:
+ /* enable regular 2P5 and turn off weak 2P5 */
+ ldr r7, [r10, #0x130]
+ orr r7, r7, #0x1
+ str r7, [r10, #0x130]
+
+ /* Ensure the 2P5 is up. */
+3:
+ ldr r7, [r10, #0x130]
+ ands r7, r7, #0x20000
+ beq 3b
+ ldr r7, [r10, #0x130]
+ bic r7, r7, #0x40000
+ str r7, [r10, #0x130]
+
+ /* enable regular 1p1 and turn off weak 1P1 */
+ ldr r7, [r10, #0x110]
+ orr r7, r7, #0x1
+ str r7, [r10, #0x110]
+4:
+ ldr r7, [r10, #0x110]
+ ands r7, r7, #0x20000
+ beq 4b
+ ldr r7, [r10, #0x110]
+ bic r7, r7, #0x40000
+ str r7, [r10, #0x110]
+11:
+ .endm
+
+ .macro disable_l1_dcache
+
+ /*
+ * Flush all data from the L1 data cache before disabling
+ * SCTLR.C bit.
+ */
+ push {r0 - r10, lr}
+ ldr r7, =v7_flush_dcache_all
+ mov lr, pc
+ mov pc, r7
+ pop {r0 - r10, lr}
+
+ /* disable d-cache */
+ mrc p15, 0, r7, c1, c0, 0
+ bic r7, r7, #(1 << 2)
+ mcr p15, 0, r7, c1, c0, 0
+ dsb
+ isb
+
+ push {r0 - r10, lr}
+ ldr r7, =v7_flush_dcache_all
+ mov lr, pc
+ mov pc, r7
+ pop {r0 - r10, lr}
+
+ .endm
+
+ .macro mmdc_enter_dvfs_mode
+
+ /* disable automatic power savings. */
+ ldr r7, [r10, #MX6Q_MMDC_MAPSR]
+ orr r7, r7, #0x1
+ str r7, [r10, #MX6Q_MMDC_MAPSR]
+
+ /* disable power down timer */
+ ldr r7, [r10, #0x4]
+ bic r7, r7, #0xff00
+ str r7, [r10, #0x4]
+
+ /* make the DDR explicitly enter self-refresh. */
+ ldr r7, [r10, #MX6Q_MMDC_MAPSR]
+ orr r7, r7, #(1 << 21)
+ str r7, [r10, #MX6Q_MMDC_MAPSR]
+5:
+ ldr r7, [r10, #MX6Q_MMDC_MAPSR]
+ ands r7, r7, #(1 << 25)
+ beq 5b
+
+ .endm
+
+ .macro resume_mmdc
+
+ /* restore MMDC IO */
+ cmp r5, #0x0
+ ldreq r10, [r0, #PM_INFO_MX6Q_IOMUXC_V_OFFSET]
+ ldrne r10, [r0, #PM_INFO_MX6Q_IOMUXC_P_OFFSET]
+
+ ldr r6, [r0, #PM_INFO_MMDC_IO_NUM_OFFSET]
+ ldr r7, =PM_INFO_MMDC_IO_VAL_OFFSET
+ add r7, r7, r0
+6:
+ ldr r8, [r7], #0x4
+ ldr r9, [r7], #0x4
+ str r9, [r10, r8]
+ subs r6, r6, #0x1
+ bne 6b
+
+ cmp r5, #0x0
+ ldreq r10, [r0, #PM_INFO_MX6Q_MMDC_V_OFFSET]
+ ldrne r10, [r0, #PM_INFO_MX6Q_MMDC_P_OFFSET]
+
+ /* reset read FIFO, RST_RD_FIFO */
+ ldr r7, =MX6Q_MMDC_MPDGCTRL0
+ ldr r6, [r10, r7]
+ orr r6, r6, #(1 << 31)
+ str r6, [r10, r7]
+7:
+ ldr r6, [r10, r7]
+ ands r6, r6, #(1 << 31)
+ bne 7b
+
+ /* reset FIFO a second time */
+ ldr r6, [r10, r7]
+ orr r6, r6, #(1 << 31)
+ str r6, [r10, r7]
+8:
+ ldr r6, [r10, r7]
+ ands r6, r6, #(1 << 31)
+ bne 8b
+
+ /* let DDR out of self-refresh */
+ ldr r7, [r10, #MX6Q_MMDC_MAPSR]
+ bic r7, r7, #(1 << 21)
+ str r7, [r10, #MX6Q_MMDC_MAPSR]
+9:
+ ldr r7, [r10, #MX6Q_MMDC_MAPSR]
+ ands r7, r7, #(1 << 25)
+ bne 9b
+
+ /* enable power down timer */
+ ldr r7, [r10, #0x4]
+ orr r7, r7, #0x5500
+ str r7, [r10, #0x4]
+
+ /* enable DDR auto power saving */
+ ldr r7, [r10, #MX6Q_MMDC_MAPSR]
+ bic r7, r7, #0x1
+ str r7, [r10, #MX6Q_MMDC_MAPSR]
+
+ .endm
+
+ .macro sema4_lock
+
+ /* lock share memory sema4 */
+ cmp r5, #0x0
+ ldreq r10, [r0, #PM_INFO_MX6Q_SEMA4_V_OFFSET]
+ ldrne r10, [r0, #PM_INFO_MX6Q_SEMA4_P_OFFSET]
+ ldrb r6, =0x1
+16:
+ ldrb r7, [r10, #0x6]
+ cmp r7, #0x0
+ bne 16b
+ strb r6, [r10, #0x6]
+
+ .endm
+
+ .macro sema4_unlock
+
+ /* unlock share memory sema4 */
+ cmp r5, #0x0
+ ldreq r10, [r0, #PM_INFO_MX6Q_SEMA4_V_OFFSET]
+ ldrne r10, [r0, #PM_INFO_MX6Q_SEMA4_P_OFFSET]
+ ldrb r6, =0x0
+ strb r6, [r10, #0x6]
+
+ .endm
+
+ .macro tlb_set_to_ocram
+
+ /* save ttbr */
+ mrc p15, 0, r7, c2, c0, 1
+ str r7, [r0, #PM_INFO_PM_INFO_TTBR_OFFSET]
+
+ /*
+ * To ensure no page table walks occur in DDR, we
+ * have a another page table stored in IRAM that only
+ * contains entries pointing to IRAM, AIPS1 and AIPS2.
+ * We need to set the TTBR1 to the new IRAM TLB.
+ * Do the following steps:
+ * 1. Flush the Branch Target Address Cache (BTAC)
+ * 2. Set TTBR1 to point to IRAM page table.
+ * 3. Disable page table walks in TTBR0 (PD0 = 1)
+ * 4. Set TTBR0.N=1, implying 0-2G is translated by TTBR0
+ * and 2-4G is translated by TTBR1.
+ */
+
+ ldr r6, =iram_tlb_phys_addr
+ ldr r7, [r6]
+
+ /* Flush the BTAC. */
+ ldr r6, =0x0
+ mcr p15, 0, r6, c7, c1, 6
+
+ /* Disable Branch Prediction, Z bit in SCTLR. */
+ mrc p15, 0, r6, c1, c0, 0
+ bic r6, r6, #0x800
+ mcr p15, 0, r6, c1, c0, 0
+
+ dsb
+ isb
+
+ /* Store the IRAM table in TTBR1 */
+ mcr p15, 0, r7, c2, c0, 1
+
+ /* Read TTBCR and set PD0=1, N = 1 */
+ mrc p15, 0, r6, c2, c0, 2
+ orr r6, r6, #0x11
+ mcr p15, 0, r6, c2, c0, 2
+
+ dsb
+ isb
+
+ /* flush the TLB */
+ ldr r6, =0x0
+ mcr p15, 0, r6, c8, c3, 0
+
+ .endm
+
+ .macro tlb_back_to_ddr
+
+ /* Restore the TTBCR */
+
+ dsb
+ isb
+
+ /* Read TTBCR and set PD0=0, N = 0 */
+ mrc p15, 0, r6, c2, c0, 2
+ bic r6, r6, #0x11
+ mcr p15, 0, r6, c2, c0, 2
+
+ dsb
+ isb
+
+ /* flush the TLB */
+ ldr r6, =0x0
+ mcr p15, 0, r6, c8, c3, 0
+
+ dsb
+ isb
+
+ /* Enable Branch Prediction, Z bit in SCTLR. */
+ mrc p15, 0, r6, c1, c0, 0
+ orr r6, r6, #0x800
+ mcr p15, 0, r6, c1, c0, 0
+
+ /* Flush the Branch Target Address Cache (BTAC) */
+ ldr r6, =0x0
+ mcr p15, 0, r6, c7, c1, 6
+
+ /* restore ttbr */
+ ldr r7, [r0, #PM_INFO_PM_INFO_TTBR_OFFSET]
+ mcr p15, 0, r7, c2, c0, 1
+
+ .endm
+
+.extern iram_tlb_phys_addr
+
+/* imx6sx_low_power_idle */
+
+ .align 3
+ENTRY(imx6sx_low_power_idle)
+mx6sx_lpm_wfi_start:
+ push {r4 - r10}
+
+ /* get necessary info from pm_info */
+ ldr r1, [r0, #PM_INFO_PBASE_OFFSET]
+ ldr r2, [r0, #PM_INFO_PM_INFO_SIZE_OFFSET]
+
+ /*
+ * counting the resume address in iram
+ * to set it in SRC register.
+ */
+ ldr r5, =imx6sx_low_power_idle
+ ldr r6, =wakeup
+ sub r6, r6, r5
+ add r8, r1, r2
+ add r3, r8, r6
+
+ /* store physical resume addr and pm_info address. */
+ ldr r10, [r0, #PM_INFO_MX6Q_SRC_V_OFFSET]
+ str r3, [r10, #0x20]
+ str r1, [r10, #0x24]
+
+ /* save disagnostic register */
+ mrc p15, 0, r7, c15, c0, 1
+ str r7, [r0, #PM_INFO_MX6Q_SAVED_DIAGNOSTIC_OFFSET]
+
+ /* set ARM power to be gated */
+ ldr r10, [r0, #PM_INFO_MX6Q_GPC_V_OFFSET]
+ ldr r7, =0x1
+ str r7, [r10, #0x2a0]
+
+ disable_l1_dcache
+
+#ifdef CONFIG_CACHE_L2X0
+ /* sync L2 */
+ ldr r10, [r0, #PM_INFO_MX6Q_L2_V_OFFSET]
+
+ /* Wait for background operations to complete. */
+wait_for_l2_to_idle:
+ ldr r7, [r10, #0x730]
+ cmp r7, #0x0
+ bne wait_for_l2_to_idle
+
+ mov r7, #0x0
+ str r7, [r10, #0x730]
+ /* disable L2 */
+ str r7, [r10, #0x100]
+
+ dsb
+ isb
+#endif
+
+ tlb_set_to_ocram
+
+ /* make sure MMDC in self-refresh */
+ ldr r10, [r0, #PM_INFO_MX6Q_MMDC_V_OFFSET]
+ mmdc_enter_dvfs_mode
+
+ /* save DDR IO settings */
+ ldr r10, [r0, #PM_INFO_MX6Q_IOMUXC_V_OFFSET]
+ ldr r6, =0x0
+ ldr r7, [r0, #PM_INFO_MMDC_IO_NUM_OFFSET]
+ ldr r8, =PM_INFO_MMDC_IO_VAL_OFFSET
+ add r8, r8, r0
+save_and_set_mmdc_io_lpm:
+ ldr r9, [r8], #0x4
+ ldr r5, [r10, r9]
+ str r6, [r10, r9]
+ str r5, [r8], #0x4
+ subs r7, r7, #0x1
+ bne save_and_set_mmdc_io_lpm
+
+ mov r5, #0x0
+ sema4_lock
+ ccm_enter_idle
+ anatop_enter_idle
+ sema4_unlock
+
+ /*
+ * mask all GPC interrupts before
+ * enabling the RBC counters to
+ * avoid the counter starting too
+ * early if an interupt is already
+ * pending.
+ */
+ ldr r10, [r0, #PM_INFO_MX6Q_GPC_V_OFFSET]
+ ldr r4, [r10, #MX6Q_GPC_IMR1]
+ ldr r5, [r10, #MX6Q_GPC_IMR2]
+ ldr r6, [r10, #MX6Q_GPC_IMR3]
+ ldr r7, [r10, #MX6Q_GPC_IMR4]
+
+ ldr r3, =0xffffffff
+ str r3, [r10, #MX6Q_GPC_IMR1]
+ str r3, [r10, #MX6Q_GPC_IMR2]
+ str r3, [r10, #MX6Q_GPC_IMR3]
+ str r3, [r10, #MX6Q_GPC_IMR4]
+
+ /*
+ * enable the RBC bypass counter here
+ * to hold off the interrupts. RBC counter
+ * = 4 (120us). With this setting, the latency
+ * from wakeup interrupt to ARM power up
+ * is ~130uS.
+ */
+ ldr r10, [r0, #PM_INFO_MX6Q_CCM_V_OFFSET]
+ ldr r3, [r10, #MX6Q_CCM_CCR]
+ bic r3, r3, #(0x3f << 21)
+ orr r3, r3, #(0x4 << 21)
+ str r3, [r10, #MX6Q_CCM_CCR]
+
+ /* enable the counter. */
+ ldr r3, [r10, #MX6Q_CCM_CCR]
+ orr r3, r3, #(0x1 << 27)
+ str r3, [r10, #MX6Q_CCM_CCR]
+
+ /* unmask all the GPC interrupts. */
+ ldr r10, [r0, #PM_INFO_MX6Q_GPC_V_OFFSET]
+ str r4, [r10, #MX6Q_GPC_IMR1]
+ str r5, [r10, #MX6Q_GPC_IMR2]
+ str r6, [r10, #MX6Q_GPC_IMR3]
+ str r7, [r10, #MX6Q_GPC_IMR4]
+
+ /*
+ * now delay for a short while (3usec)
+ * ARM is at 24MHz at this point
+ * so a short loop should be enough.
+ * this delay is required to ensure that
+ * the RBC counter can start counting in
+ * case an interrupt is already pending
+ * or in case an interrupt arrives just
+ * as ARM is about to assert DSM_request.
+ */
+ ldr r4, =50
+rbc_loop:
+ subs r4, r4, #0x1
+ bne rbc_loop
+
+ wfi
+
+ nop
+ nop
+ nop
+ nop
+ nop
+
+ nop
+ nop
+ nop
+ nop
+ nop
+
+ nop
+ nop
+ nop
+ nop
+ nop
+
+ nop
+ nop
+ nop
+ nop
+ nop
+
+ nop
+ nop
+ nop
+ nop
+ nop
+
+ mov r5, #0x0
+ sema4_lock
+ anatop_exit_idle
+ ccm_exit_idle
+ sema4_unlock
+ resume_mmdc
+
+ /* clear ARM power gate setting */
+ ldr r10, [r0, #PM_INFO_MX6Q_GPC_V_OFFSET]
+ ldr r7, =0x0
+ str r7, [r10, #0x2a0]
+
+ /* enable d-cache */
+ mrc p15, 0, r7, c1, c0, 0
+ orr r7, r7, #(1 << 2)
+ mcr p15, 0, r7, c1, c0, 0
+
+#ifdef CONFIG_CACHE_L2X0
+ ldr r10, [r0, #PM_INFO_MX6Q_L2_V_OFFSET]
+ mov r7, #0x1
+ /* enable L2 */
+ str r7, [r10, #0x100]
+#endif
+
+ tlb_back_to_ddr
+
+ /* Restore registers */
+ pop {r4 - r10}
+ mov pc, lr
+
+wakeup:
+
+ /* invalidate L1 I-cache first */
+ mov r1, #0x0
+ mcr p15, 0, r1, c7, c5, 0
+ mcr p15, 0, r1, c7, c5, 0
+ mcr p15, 0, r1, c7, c5, 6
+ /* enable the Icache and branch prediction */
+ mov r1, #0x1800
+ mcr p15, 0, r1, c1, c0, 0
+ isb
+ /* restore disagnostic register */
+ ldr r7, [r0, #PM_INFO_MX6Q_SAVED_DIAGNOSTIC_OFFSET]
+ mcr p15, 0, r7, c15, c0, 1
+
+ /* get physical resume address from pm_info. */
+ ldr lr, [r0, #PM_INFO_RESUME_ADDR_OFFSET]
+ /* clear core0's entry and parameter */
+ ldr r10, [r0, #PM_INFO_MX6Q_SRC_P_OFFSET]
+ mov r7, #0x0
+ str r7, [r10, #MX6Q_SRC_GPR1]
+ str r7, [r10, #MX6Q_SRC_GPR2]
+
+ /* clear ARM power gate setting */
+ ldr r10, [r0, #PM_INFO_MX6Q_GPC_P_OFFSET]
+ ldr r7, =0x0
+ str r7, [r10, #0x2a0]
+
+ mov r5, #0x1
+ sema4_lock
+ anatop_exit_idle
+ ccm_exit_idle
+ sema4_unlock
+ resume_mmdc
+
+ /* Restore registers */
+ mov pc, lr
+ .ltorg
+mx6sx_lpm_wfi_end:
diff --git a/arch/arm/mach-imx/imx6ul_low_power_idle.S b/arch/arm/mach-imx/imx6ul_low_power_idle.S
new file mode 100644
index 000000000000..26bb83da1a7d
--- /dev/null
+++ b/arch/arm/mach-imx/imx6ul_low_power_idle.S
@@ -0,0 +1,821 @@
+/*
+ * Copyright (C) 2015 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/linkage.h>
+
+#define PM_INFO_PBASE_OFFSET 0x0
+#define PM_INFO_RESUME_ADDR_OFFSET 0x4
+#define PM_INFO_PM_INFO_SIZE_OFFSET 0x8
+#define PM_INFO_PM_INFO_TTBR_OFFSET 0xc
+#define PM_INFO_MX6Q_MMDC_P_OFFSET 0x10
+#define PM_INFO_MX6Q_MMDC_V_OFFSET 0x14
+#define PM_INFO_MX6Q_IOMUXC_P_OFFSET 0x18
+#define PM_INFO_MX6Q_IOMUXC_V_OFFSET 0x1c
+#define PM_INFO_MX6Q_CCM_P_OFFSET 0x20
+#define PM_INFO_MX6Q_CCM_V_OFFSET 0x24
+#define PM_INFO_MX6Q_GPC_P_OFFSET 0x28
+#define PM_INFO_MX6Q_GPC_V_OFFSET 0x2c
+#define PM_INFO_MX6Q_ANATOP_P_OFFSET 0x30
+#define PM_INFO_MX6Q_ANATOP_V_OFFSET 0x34
+#define PM_INFO_MX6Q_SRC_P_OFFSET 0x38
+#define PM_INFO_MX6Q_SRC_V_OFFSET 0x3c
+#define PM_INFO_MMDC_IO_NUM_OFFSET 0x40
+#define PM_INFO_MMDC_IO_VAL_OFFSET 0x44
+
+#define MX6Q_MMDC_MAPSR 0x404
+#define MX6Q_MMDC_MPDGCTRL0 0x83c
+#define MX6Q_SRC_GPR1 0x20
+#define MX6Q_SRC_GPR2 0x24
+#define MX6Q_GPC_IMR1 0x08
+#define MX6Q_GPC_IMR2 0x0c
+#define MX6Q_GPC_IMR3 0x10
+#define MX6Q_GPC_IMR4 0x14
+#define MX6Q_CCM_CCR 0x0
+
+.globl mx6ul_lpm_wfi_start
+.globl mx6ul_lpm_wfi_end
+
+ .macro pll_do_wait_lock
+1:
+ ldr r7, [r10, r8]
+ ands r7, #0x80000000
+ beq 1b
+
+ .endm
+
+ .macro ccm_do_wait
+2:
+ ldr r7, [r10, #0x48]
+ cmp r7, #0x0
+ bne 2b
+
+ .endm
+
+ .macro ccm_enter_idle
+
+ ldr r10, [r0, #PM_INFO_MX6Q_CCM_V_OFFSET]
+
+ /* set ahb to 3MHz */
+ ldr r7, [r10, #0x14]
+ orr r7, r7, #0x1c00
+ str r7, [r10, #0x14]
+
+ /* set perclk to 6MHz */
+ ldr r7, [r10, #0x1c]
+ bic r7, r7, #0x3f
+ orr r7, r7, #0x3
+ str r7, [r10, #0x1c]
+
+ /* set mmdc to 1MHz, periph2_clk2 need to be @8MHz */
+ ldr r7, [r10, #0x14]
+ orr r7, r7, #0x2
+ orr r7, r7, #(0x7 << 3)
+ str r7, [r10, #0x14]
+
+ ccm_do_wait
+
+ ldr r10, [r0, #PM_INFO_MX6Q_ANATOP_V_OFFSET]
+
+ /* bypass PLL1 output to OSC */
+ ldr r7, [r10]
+ orr r7, r7, #(0x1 << 16)
+ str r7, [r10]
+
+ ldr r10, [r0, #PM_INFO_MX6Q_CCM_V_OFFSET]
+
+ /* set pll1_sw to from pll1 main */
+ ldr r7, [r10, #0xc]
+ bic r7, r7, #0x4
+ str r7, [r10, #0xc]
+
+ /* set step from osc */
+ ldr r7, [r10, #0xc]
+ bic r7, r7, #0x100
+ str r7, [r10, #0xc]
+
+ /* set pll1_sw to from step */
+ ldr r7, [r10, #0xc]
+ orr r7, r7, #0x4
+ str r7, [r10, #0xc]
+
+ ldr r10, [r0, #PM_INFO_MX6Q_ANATOP_V_OFFSET]
+
+ /* Disable PLL1 bypass output */
+ ldr r7, [r10]
+ bic r7, r7, #0x12000
+ str r7, [r10]
+
+ /*
+ * disable pll2, suppose when system enter low
+ * power idle mode, only 396MHz pfd needs pll2,
+ * now we switch arm clock to OSC, we can disable
+ * pll2 now, gate pll2_pfd2 first.
+ */
+ ldr r7, [r10, #0x100]
+ orr r7, #0x800000
+ str r7, [r10, #0x100]
+
+ ldr r7, [r10, #0x30]
+ orr r7, r7, #0x1000
+ bic r7, r7, #0x2000
+ str r7, [r10, #0x30]
+
+ .endm
+
+ .macro ccm_exit_idle
+
+ cmp r5, #0x0
+ ldreq r10, [r0, #PM_INFO_MX6Q_ANATOP_V_OFFSET]
+ ldrne r10, [r0, #PM_INFO_MX6Q_ANATOP_P_OFFSET]
+
+ /* enable pll2 and pll2_pfd2 */
+ ldr r7, [r10, #0x30]
+ bic r7, r7, #0x1000
+ orr r7, r7, #0x2000
+ str r7, [r10, #0x30]
+
+ ldr r8, =0x30
+ pll_do_wait_lock
+
+ ldr r7, [r10, #0x100]
+ bic r7, #0x800000
+ str r7, [r10, #0x100]
+
+ /* enable PLL1 bypass output */
+ ldr r7, [r10]
+ orr r7, r7, #0x12000
+ str r7, [r10]
+
+ cmp r5, #0x0
+ ldreq r10, [r0, #PM_INFO_MX6Q_CCM_V_OFFSET]
+ ldrne r10, [r0, #PM_INFO_MX6Q_CCM_P_OFFSET]
+
+ /* set perclk back to 24MHz */
+ ldr r7, [r10, #0x1c]
+ bic r7, r7, #0x3f
+ str r7, [r10, #0x1c]
+
+ /* set mmdc back to 24MHz */
+ ldr r7, [r10, #0x14]
+ bic r7, r7, #0x7
+ bic r7, r7, #(0x7 << 3)
+ str r7, [r10, #0x14]
+
+ /* set ahb div back to 24MHz */
+ ldr r7, [r10, #0x14]
+ bic r7, r7, #0x1c00
+ str r7, [r10, #0x14]
+
+ ccm_do_wait
+
+ /* set pll1_sw to from pll1 main */
+ ldr r7, [r10, #0xc]
+ bic r7, r7, #0x4
+ str r7, [r10, #0xc]
+
+ /* set step from pll2_pfd2 */
+ ldr r7, [r10, #0xc]
+ orr r7, r7, #0x100
+ str r7, [r10, #0xc]
+
+ /* set pll1_sw to from step */
+ ldr r7, [r10, #0xc]
+ orr r7, r7, #0x4
+ str r7, [r10, #0xc]
+
+ cmp r5, #0x0
+ ldreq r10, [r0, #PM_INFO_MX6Q_ANATOP_V_OFFSET]
+ ldrne r10, [r0, #PM_INFO_MX6Q_ANATOP_P_OFFSET]
+
+ /* Unbypass PLL1 */
+ ldr r7, [r10]
+ bic r7, r7, #(0x1 << 16)
+ str r7, [r10]
+
+ .endm
+
+ .macro anatop_enter_idle
+
+ ldr r10, [r0, #PM_INFO_MX6Q_ANATOP_V_OFFSET]
+
+ /*
+ * check whether any PLL is enabled, as only when
+ * there is no PLLs enabled, 2P5 and 1P1 can be
+ * off and only enable weak ones.
+ */
+
+ /* arm pll1 */
+ ldr r7, [r10, #0]
+ ands r7, r7, #(1 << 31)
+ bne 10f
+
+ /* sys pll2 */
+ ldr r7, [r10, #0x30]
+ ands r7, r7, #(1 << 31)
+ bne 10f
+
+ /* usb pll3 */
+ ldr r7, [r10, #0x10]
+ ands r7, r7, #(1 << 31)
+ bne 10f
+
+ /* audio pll4 */
+ ldr r7, [r10, #0x70]
+ ands r7, r7, #(1 << 31)
+ bne 10f
+
+ /* vidio pll5 */
+ ldr r7, [r10, #0xa0]
+ ands r7, r7, #(1 << 31)
+ bne 10f
+
+ /* enet pll6 */
+ ldr r7, [r10, #0xe0]
+ ands r7, r7, #(1 << 31)
+ bne 10f
+
+ /* usb host pll7 */
+ ldr r7, [r10, #0x20]
+ ands r7, r7, #(1 << 31)
+ bne 10f
+
+ /* enable weak 2P5 and turn off regular 2P5 */
+ ldr r7, [r10, #0x130]
+ orr r7, r7, #0x40000
+ str r7, [r10, #0x130]
+ bic r7, r7, #0x1
+ str r7, [r10, #0x130]
+
+ /* enable weak 1p1 and turn off regular 1P1 */
+ ldr r7, [r10, #0x110]
+ orr r7, r7, #0x40000
+ str r7, [r10, #0x110]
+ bic r7, r7, #0x1
+ str r7, [r10, #0x110]
+
+ /* check whether ARM LDO is bypassed */
+ ldr r7, [r10, #0x140]
+ and r7, r7, #0x1f
+ cmp r7, #0x1f
+ bne 10f
+
+ /* low power band gap enable */
+ ldr r7, [r10, #0x270]
+ orr r7, r7, #0x20
+ str r7, [r10, #0x270]
+
+ /* turn off the bias current from the regular bandgap */
+ ldr r7, [r10, #0x270]
+ orr r7, r7, #0x80
+ str r7, [r10, #0x270]
+
+ /*
+ * clear the REFTOP_SELFBIASOFF,
+ * self-bias circuit of the band gap.
+ * Per RM, should be cleared when
+ * band gap is powered down.
+ */
+ ldr r7, [r10, #0x150]
+ bic r7, r7, #0x8
+ str r7, [r10, #0x150]
+
+ /* turn off regular bandgap */
+ ldr r7, [r10, #0x150]
+ orr r7, r7, #0x1
+ str r7, [r10, #0x150]
+
+ /* switch to RC-OSC */
+ ldr r7, [r10, #0x270]
+ orr r7, r7, #0x10
+ str r7, [r10, #0x270]
+
+ /* turn off XTAL-OSC */
+ ldr r7, [r10, #0x150]
+ orr r7, r7, #0x40000000
+ str r7, [r10, #0x150]
+10:
+ /* lower OSC current by 37.5% */
+ ldr r7, [r10, #0x150]
+ orr r7, r7, #0x6000
+ str r7, [r10, #0x150]
+
+ /* disconnect vdd_high_in and vdd_snvs_in */
+ ldr r7, [r10, #0x150]
+ orr r7, r7, #0x1000
+ str r7, [r10, #0x150]
+
+ .endm
+
+ .macro anatop_exit_idle
+
+ cmp r5, #0x0
+ ldreq r10, [r0, #PM_INFO_MX6Q_ANATOP_V_OFFSET]
+ ldrne r10, [r0, #PM_INFO_MX6Q_ANATOP_P_OFFSET]
+
+ /* increase OSC current to normal */
+ ldr r7, [r10, #0x150]
+ bic r7, r7, #0x6000
+ str r7, [r10, #0x150]
+
+ /* turn on XTAL-OSC and detector */
+ ldr r7, [r10, #0x150]
+ bic r7, r7, #0x40000000
+ orr r7, r7, #0x10000
+ str r7, [r10, #0x150]
+
+ /* wait for XTAL stable */
+14:
+ ldr r7, [r10, #0x150]
+ ands r7, r7, #0x8000
+ beq 14b
+
+ /* switch to XTAL-OSC */
+ ldr r7, [r10, #0x270]
+ bic r7, r7, #0x10
+ str r7, [r10, #0x270]
+
+ /* turn off XTAL-OSC detector */
+ ldr r7, [r10, #0x150]
+ bic r7, r7, #0x10000
+ str r7, [r10, #0x150]
+15:
+ /* check whether we need to enable 2P5/1P1 */
+ ldr r7, [r10, #0x110]
+ ands r7, r7, #0x40000
+ beq 11f
+
+ /* check whether ARM LDO is bypassed */
+ ldr r7, [r10, #0x140]
+ and r7, r7, #0x1f
+ cmp r7, #0x1f
+ bne 12f
+
+ /* turn on regular bandgap and wait for stable */
+ ldr r7, [r10, #0x150]
+ bic r7, r7, #0x1
+ str r7, [r10, #0x150]
+13:
+ ldr r7, [r10, #0x150]
+ ands r7, #0x80
+ beq 13b
+
+ /*
+ * set the REFTOP_SELFBIASOFF,
+ * self-bias circuit of the band gap.
+ */
+ ldr r7, [r10, #0x150]
+ orr r7, r7, #0x8
+ str r7, [r10, #0x150]
+
+ /* turn on the bias current from the regular bandgap */
+ ldr r7, [r10, #0x270]
+ bic r7, r7, #0x80
+ str r7, [r10, #0x270]
+
+ /* low power band gap disable */
+ ldr r7, [r10, #0x270]
+ bic r7, r7, #0x20
+ str r7, [r10, #0x270]
+12:
+ /* enable regular 2P5 and turn off weak 2P5 */
+ ldr r7, [r10, #0x130]
+ orr r7, r7, #0x1
+ str r7, [r10, #0x130]
+
+ /* Ensure the 2P5 is up. */
+3:
+ ldr r7, [r10, #0x130]
+ ands r7, r7, #0x20000
+ beq 3b
+ ldr r7, [r10, #0x130]
+ bic r7, r7, #0x40000
+ str r7, [r10, #0x130]
+
+ /* enable regular 1p1 and turn off weak 1P1 */
+ ldr r7, [r10, #0x110]
+ orr r7, r7, #0x1
+ str r7, [r10, #0x110]
+4:
+ ldr r7, [r10, #0x110]
+ ands r7, r7, #0x20000
+ beq 4b
+ ldr r7, [r10, #0x110]
+ bic r7, r7, #0x40000
+ str r7, [r10, #0x110]
+11:
+ .endm
+
+ .macro disable_l1_dcache
+
+ /*
+ * Flush all data from the L1 data cache before disabling
+ * SCTLR.C bit.
+ */
+ push {r0 - r10, lr}
+ ldr r7, =v7_flush_dcache_all
+ mov lr, pc
+ mov pc, r7
+ pop {r0 - r10, lr}
+
+ /* disable d-cache */
+ mrc p15, 0, r7, c1, c0, 0
+ bic r7, r7, #(1 << 2)
+ mcr p15, 0, r7, c1, c0, 0
+ dsb
+ isb
+
+ push {r0 - r10, lr}
+ ldr r7, =v7_flush_dcache_all
+ mov lr, pc
+ mov pc, r7
+ pop {r0 - r10, lr}
+
+ .endm
+
+ .macro mmdc_enter_dvfs_mode
+
+ /* disable automatic power savings. */
+ ldr r7, [r10, #MX6Q_MMDC_MAPSR]
+ orr r7, r7, #0x1
+ str r7, [r10, #MX6Q_MMDC_MAPSR]
+
+ /* disable power down timer */
+ ldr r7, [r10, #0x4]
+ bic r7, r7, #0xff00
+ str r7, [r10, #0x4]
+
+ /* make the DDR explicitly enter self-refresh. */
+ ldr r7, [r10, #MX6Q_MMDC_MAPSR]
+ orr r7, r7, #(1 << 21)
+ str r7, [r10, #MX6Q_MMDC_MAPSR]
+5:
+ ldr r7, [r10, #MX6Q_MMDC_MAPSR]
+ ands r7, r7, #(1 << 25)
+ beq 5b
+
+ .endm
+
+ .macro resume_mmdc
+
+ /* restore MMDC IO */
+ cmp r5, #0x0
+ ldreq r10, [r0, #PM_INFO_MX6Q_IOMUXC_V_OFFSET]
+ ldrne r10, [r0, #PM_INFO_MX6Q_IOMUXC_P_OFFSET]
+
+ ldr r6, [r0, #PM_INFO_MMDC_IO_NUM_OFFSET]
+ ldr r7, =PM_INFO_MMDC_IO_VAL_OFFSET
+ add r7, r7, r0
+6:
+ ldr r8, [r7], #0x4
+ ldr r9, [r7], #0x4
+ str r9, [r10, r8]
+ subs r6, r6, #0x1
+ bne 6b
+
+ cmp r5, #0x0
+ ldreq r10, [r0, #PM_INFO_MX6Q_MMDC_V_OFFSET]
+ ldrne r10, [r0, #PM_INFO_MX6Q_MMDC_P_OFFSET]
+
+ /* reset read FIFO, RST_RD_FIFO */
+ ldr r7, =MX6Q_MMDC_MPDGCTRL0
+ ldr r6, [r10, r7]
+ orr r6, r6, #(1 << 31)
+ str r6, [r10, r7]
+7:
+ ldr r6, [r10, r7]
+ ands r6, r6, #(1 << 31)
+ bne 7b
+
+ /* reset FIFO a second time */
+ ldr r6, [r10, r7]
+ orr r6, r6, #(1 << 31)
+ str r6, [r10, r7]
+8:
+ ldr r6, [r10, r7]
+ ands r6, r6, #(1 << 31)
+ bne 8b
+
+ /* let DDR out of self-refresh */
+ ldr r7, [r10, #MX6Q_MMDC_MAPSR]
+ bic r7, r7, #(1 << 21)
+ str r7, [r10, #MX6Q_MMDC_MAPSR]
+9:
+ ldr r7, [r10, #MX6Q_MMDC_MAPSR]
+ ands r7, r7, #(1 << 25)
+ bne 9b
+
+ /* enable power down timer */
+ ldr r7, [r10, #0x4]
+ orr r7, r7, #0x5500
+ str r7, [r10, #0x4]
+
+ /* enable DDR auto power saving */
+ ldr r7, [r10, #MX6Q_MMDC_MAPSR]
+ bic r7, r7, #0x1
+ str r7, [r10, #MX6Q_MMDC_MAPSR]
+
+ .endm
+
+ .macro tlb_set_to_ocram
+
+ /* save ttbr */
+ mrc p15, 0, r7, c2, c0, 1
+ str r7, [r0, #PM_INFO_PM_INFO_TTBR_OFFSET]
+
+ /*
+ * To ensure no page table walks occur in DDR, we
+ * have a another page table stored in IRAM that only
+ * contains entries pointing to IRAM, AIPS1 and AIPS2.
+ * We need to set the TTBR1 to the new IRAM TLB.
+ * Do the following steps:
+ * 1. Flush the Branch Target Address Cache (BTAC)
+ * 2. Set TTBR1 to point to IRAM page table.
+ * 3. Disable page table walks in TTBR0 (PD0 = 1)
+ * 4. Set TTBR0.N=1, implying 0-2G is translated by TTBR0
+ * and 2-4G is translated by TTBR1.
+ */
+
+ ldr r6, =iram_tlb_phys_addr
+ ldr r7, [r6]
+
+ /* Flush the BTAC. */
+ ldr r6, =0x0
+ mcr p15, 0, r6, c7, c1, 6
+
+ /* Disable Branch Prediction, Z bit in SCTLR. */
+ mrc p15, 0, r6, c1, c0, 0
+ bic r6, r6, #0x800
+ mcr p15, 0, r6, c1, c0, 0
+
+ dsb
+ isb
+
+ /* Store the IRAM table in TTBR1 */
+ mcr p15, 0, r7, c2, c0, 1
+
+ /* Read TTBCR and set PD0=1, N = 1 */
+ mrc p15, 0, r6, c2, c0, 2
+ orr r6, r6, #0x11
+ mcr p15, 0, r6, c2, c0, 2
+
+ dsb
+ isb
+
+ /* flush the TLB */
+ ldr r6, =0x0
+ mcr p15, 0, r6, c8, c3, 0
+
+ .endm
+
+ .macro tlb_back_to_ddr
+
+ /* Restore the TTBCR */
+
+ dsb
+ isb
+
+ /* Read TTBCR and set PD0=0, N = 0 */
+ mrc p15, 0, r6, c2, c0, 2
+ bic r6, r6, #0x11
+ mcr p15, 0, r6, c2, c0, 2
+
+ dsb
+ isb
+
+ /* flush the TLB */
+ ldr r6, =0x0
+ mcr p15, 0, r6, c8, c3, 0
+
+ dsb
+ isb
+
+ /* Enable Branch Prediction, Z bit in SCTLR. */
+ mrc p15, 0, r6, c1, c0, 0
+ orr r6, r6, #0x800
+ mcr p15, 0, r6, c1, c0, 0
+
+ /* Flush the Branch Target Address Cache (BTAC) */
+ ldr r6, =0x0
+ mcr p15, 0, r6, c7, c1, 6
+
+ /* restore ttbr */
+ ldr r7, [r0, #PM_INFO_PM_INFO_TTBR_OFFSET]
+ mcr p15, 0, r7, c2, c0, 1
+
+ .endm
+
+.extern iram_tlb_phys_addr
+
+/* imx6ul_low_power_idle */
+
+ .align 3
+ENTRY(imx6ul_low_power_idle)
+mx6ul_lpm_wfi_start:
+ push {r4 - r10}
+
+ /* get necessary info from pm_info */
+ ldr r1, [r0, #PM_INFO_PBASE_OFFSET]
+ ldr r2, [r0, #PM_INFO_PM_INFO_SIZE_OFFSET]
+
+ /*
+ * counting the resume address in iram
+ * to set it in SRC register.
+ */
+ ldr r5, =imx6ul_low_power_idle
+ ldr r6, =wakeup
+ sub r6, r6, r5
+ add r8, r1, r2
+ add r3, r8, r6
+
+ /* store physical resume addr and pm_info address. */
+ ldr r10, [r0, #PM_INFO_MX6Q_SRC_V_OFFSET]
+ str r3, [r10, #0x20]
+ str r1, [r10, #0x24]
+
+ /* set ARM power to be gated */
+ ldr r10, [r0, #PM_INFO_MX6Q_GPC_V_OFFSET]
+ ldr r7, =0x1
+ str r7, [r10, #0x2a0]
+
+ disable_l1_dcache
+
+ tlb_set_to_ocram
+
+ /* make sure MMDC in self-refresh */
+ ldr r10, [r0, #PM_INFO_MX6Q_MMDC_V_OFFSET]
+ mmdc_enter_dvfs_mode
+
+ /* save DDR IO settings */
+ ldr r10, [r0, #PM_INFO_MX6Q_IOMUXC_V_OFFSET]
+ ldr r6, =0x0
+ ldr r7, [r0, #PM_INFO_MMDC_IO_NUM_OFFSET]
+ ldr r8, =PM_INFO_MMDC_IO_VAL_OFFSET
+ add r8, r8, r0
+save_and_set_mmdc_io_lpm:
+ ldr r9, [r8], #0x4
+ ldr r5, [r10, r9]
+ str r6, [r10, r9]
+ str r5, [r8], #0x4
+ subs r7, r7, #0x1
+ bne save_and_set_mmdc_io_lpm
+
+ mov r5, #0x0
+ ccm_enter_idle
+ anatop_enter_idle
+
+ /*
+ * mask all GPC interrupts before
+ * enabling the RBC counters to
+ * avoid the counter starting too
+ * early if an interupt is already
+ * pending.
+ */
+ ldr r10, [r0, #PM_INFO_MX6Q_GPC_V_OFFSET]
+ ldr r4, [r10, #MX6Q_GPC_IMR1]
+ ldr r5, [r10, #MX6Q_GPC_IMR2]
+ ldr r6, [r10, #MX6Q_GPC_IMR3]
+ ldr r7, [r10, #MX6Q_GPC_IMR4]
+
+ ldr r3, =0xffffffff
+ str r3, [r10, #MX6Q_GPC_IMR1]
+ str r3, [r10, #MX6Q_GPC_IMR2]
+ str r3, [r10, #MX6Q_GPC_IMR3]
+ str r3, [r10, #MX6Q_GPC_IMR4]
+
+ /*
+ * enable the RBC bypass counter here
+ * to hold off the interrupts. RBC counter
+ * = 4 (120us). With this setting, the latency
+ * from wakeup interrupt to ARM power up
+ * is ~130uS.
+ */
+ ldr r10, [r0, #PM_INFO_MX6Q_CCM_V_OFFSET]
+ ldr r3, [r10, #MX6Q_CCM_CCR]
+ bic r3, r3, #(0x3f << 21)
+ orr r3, r3, #(0x4 << 21)
+ str r3, [r10, #MX6Q_CCM_CCR]
+
+ /* enable the counter. */
+ ldr r3, [r10, #MX6Q_CCM_CCR]
+ orr r3, r3, #(0x1 << 27)
+ str r3, [r10, #MX6Q_CCM_CCR]
+
+ /* unmask all the GPC interrupts. */
+ ldr r10, [r0, #PM_INFO_MX6Q_GPC_V_OFFSET]
+ str r4, [r10, #MX6Q_GPC_IMR1]
+ str r5, [r10, #MX6Q_GPC_IMR2]
+ str r6, [r10, #MX6Q_GPC_IMR3]
+ str r7, [r10, #MX6Q_GPC_IMR4]
+
+ /*
+ * now delay for a short while (3usec)
+ * ARM is at 24MHz at this point
+ * so a short loop should be enough.
+ * this delay is required to ensure that
+ * the RBC counter can start counting in
+ * case an interrupt is already pending
+ * or in case an interrupt arrives just
+ * as ARM is about to assert DSM_request.
+ */
+ ldr r4, =50
+rbc_loop:
+ subs r4, r4, #0x1
+ bne rbc_loop
+
+ wfi
+
+ nop
+ nop
+ nop
+ nop
+ nop
+
+ nop
+ nop
+ nop
+ nop
+ nop
+
+ nop
+ nop
+ nop
+ nop
+ nop
+
+ nop
+ nop
+ nop
+ nop
+ nop
+
+ nop
+ nop
+ nop
+ nop
+ nop
+
+ mov r5, #0x0
+ anatop_exit_idle
+ ccm_exit_idle
+
+ /* clear ARM power gate setting */
+ ldr r10, [r0, #PM_INFO_MX6Q_GPC_V_OFFSET]
+ ldr r7, =0x0
+ str r7, [r10, #0x2a0]
+
+ resume_mmdc
+ /* enable d-cache */
+ mrc p15, 0, r7, c1, c0, 0
+ orr r7, r7, #(1 << 2)
+ mcr p15, 0, r7, c1, c0, 0
+
+ tlb_back_to_ddr
+
+ /* Restore registers */
+ pop {r4 - r10}
+ mov pc, lr
+
+wakeup:
+ /* invalidate L1 I-cache first */
+ mov r1, #0x0
+ mcr p15, 0, r1, c7, c5, 0
+ mcr p15, 0, r1, c7, c5, 0
+ mcr p15, 0, r1, c7, c5, 6
+ /* enable the Icache and branch prediction */
+ mov r1, #0x1800
+ mcr p15, 0, r1, c1, c0, 0
+ isb
+
+ /* get physical resume address from pm_info. */
+ ldr lr, [r0, #PM_INFO_RESUME_ADDR_OFFSET]
+ /* clear core0's entry and parameter */
+ ldr r10, [r0, #PM_INFO_MX6Q_SRC_P_OFFSET]
+ mov r7, #0x0
+ str r7, [r10, #MX6Q_SRC_GPR1]
+ str r7, [r10, #MX6Q_SRC_GPR2]
+
+ /* clear ARM power gate setting */
+ ldr r10, [r0, #PM_INFO_MX6Q_GPC_P_OFFSET]
+ ldr r7, =0x0
+ str r7, [r10, #0x2a0]
+
+ mov r5, #0x1
+ anatop_exit_idle
+ ccm_exit_idle
+ resume_mmdc
+
+ /* Restore registers */
+ mov pc, lr
+ .ltorg
+mx6ul_lpm_wfi_end:
diff --git a/arch/arm/mach-imx/imx6ull_low_power_idle.S b/arch/arm/mach-imx/imx6ull_low_power_idle.S
new file mode 100644
index 000000000000..76ceac7fae26
--- /dev/null
+++ b/arch/arm/mach-imx/imx6ull_low_power_idle.S
@@ -0,0 +1,764 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/linkage.h>
+
+#define PM_INFO_PBASE_OFFSET 0x0
+#define PM_INFO_RESUME_ADDR_OFFSET 0x4
+#define PM_INFO_PM_INFO_SIZE_OFFSET 0x8
+#define PM_INFO_PM_INFO_TTBR_OFFSET 0xc
+#define PM_INFO_MX6Q_MMDC_P_OFFSET 0x10
+#define PM_INFO_MX6Q_MMDC_V_OFFSET 0x14
+#define PM_INFO_MX6Q_IOMUXC_P_OFFSET 0x18
+#define PM_INFO_MX6Q_IOMUXC_V_OFFSET 0x1c
+#define PM_INFO_MX6Q_CCM_P_OFFSET 0x20
+#define PM_INFO_MX6Q_CCM_V_OFFSET 0x24
+#define PM_INFO_MX6Q_GPC_P_OFFSET 0x28
+#define PM_INFO_MX6Q_GPC_V_OFFSET 0x2c
+#define PM_INFO_MX6Q_ANATOP_P_OFFSET 0x30
+#define PM_INFO_MX6Q_ANATOP_V_OFFSET 0x34
+#define PM_INFO_MX6Q_SRC_P_OFFSET 0x38
+#define PM_INFO_MX6Q_SRC_V_OFFSET 0x3c
+#define PM_INFO_MMDC_IO_NUM_OFFSET 0x40
+#define PM_INFO_MMDC_IO_VAL_OFFSET 0x44
+
+#define MX6Q_MMDC_MAPSR 0x404
+#define MX6Q_MMDC_MPDGCTRL0 0x83c
+#define MX6Q_SRC_GPR1 0x20
+#define MX6Q_SRC_GPR2 0x24
+#define MX6Q_GPC_IMR1 0x08
+#define MX6Q_GPC_IMR2 0x0c
+#define MX6Q_GPC_IMR3 0x10
+#define MX6Q_GPC_IMR4 0x14
+#define MX6Q_CCM_CCR 0x0
+
+.globl mx6ull_lpm_wfi_start
+.globl mx6ull_lpm_wfi_end
+
+ .macro pll_do_wait_lock
+1:
+ ldr r7, [r10, r8]
+ ands r7, #0x80000000
+ beq 1b
+
+ .endm
+
+ .macro ccm_do_wait
+2:
+ ldr r7, [r10, #0x48]
+ cmp r7, #0x0
+ bne 2b
+
+ .endm
+
+ .macro ccm_enter_idle
+
+ ldr r10, [r0, #PM_INFO_MX6Q_CCM_V_OFFSET]
+
+ /* set ahb to 3MHz */
+ ldr r7, [r10, #0x14]
+ orr r7, r7, #0x1c00
+ str r7, [r10, #0x14]
+
+ /* set perclk to 6MHz */
+ ldr r7, [r10, #0x1c]
+ bic r7, r7, #0x3f
+ orr r7, r7, #0x3
+ str r7, [r10, #0x1c]
+
+ /* set mmdc to 1MHz, periph2_clk2 need to be @8MHz */
+ ldr r7, [r10, #0x14]
+ orr r7, r7, #0x2
+ orr r7, r7, #(0x7 << 3)
+ str r7, [r10, #0x14]
+
+ ccm_do_wait
+
+ ldr r10, [r0, #PM_INFO_MX6Q_ANATOP_V_OFFSET]
+
+ /*
+ * disable pll2, suppose when system enter low
+ * power idle mode, only 396MHz pfd needs pll2,
+ * now we switch arm clock to OSC, we can disable
+ * pll2 now, gate pll2_pfd2 first.
+ */
+ ldr r7, [r10, #0x100]
+ orr r7, #0x800000
+ str r7, [r10, #0x100]
+
+ ldr r7, [r10, #0x30]
+ orr r7, r7, #0x1000
+ bic r7, r7, #0x2000
+ str r7, [r10, #0x30]
+
+ .endm
+
+ .macro ccm_exit_idle
+
+ cmp r5, #0x0
+ ldreq r10, [r0, #PM_INFO_MX6Q_ANATOP_V_OFFSET]
+ ldrne r10, [r0, #PM_INFO_MX6Q_ANATOP_P_OFFSET]
+
+ /* enable pll2 and pll2_pfd2 */
+ ldr r7, [r10, #0x30]
+ bic r7, r7, #0x1000
+ orr r7, r7, #0x2000
+ str r7, [r10, #0x30]
+
+ ldr r8, =0x30
+ pll_do_wait_lock
+
+ ldr r7, [r10, #0x100]
+ bic r7, #0x800000
+ str r7, [r10, #0x100]
+
+ cmp r5, #0x0
+ ldreq r10, [r0, #PM_INFO_MX6Q_CCM_V_OFFSET]
+ ldrne r10, [r0, #PM_INFO_MX6Q_CCM_P_OFFSET]
+
+ /* set perclk back to 24MHz */
+ ldr r7, [r10, #0x1c]
+ bic r7, r7, #0x3f
+ str r7, [r10, #0x1c]
+
+ /* set mmdc back to 24MHz */
+ ldr r7, [r10, #0x14]
+ bic r7, r7, #0x7
+ bic r7, r7, #(0x7 << 3)
+ str r7, [r10, #0x14]
+
+ /* set ahb div back to 24MHz */
+ ldr r7, [r10, #0x14]
+ bic r7, r7, #0x1c00
+ str r7, [r10, #0x14]
+
+ ccm_do_wait
+
+ .endm
+
+ .macro anatop_enter_idle
+
+ ldr r10, [r0, #PM_INFO_MX6Q_ANATOP_V_OFFSET]
+
+ /*
+ * check whether any PLL is enabled, as only when
+ * there is no PLLs enabled, 2P5 and 1P1 can be
+ * off and only enable weak ones.
+ */
+
+ /* arm pll1 */
+ ldr r7, [r10, #0]
+ ands r7, r7, #(1 << 31)
+ bne 10f
+
+ /* sys pll2 */
+ ldr r7, [r10, #0x30]
+ ands r7, r7, #(1 << 31)
+ bne 10f
+
+ /* usb pll3 */
+ ldr r7, [r10, #0x10]
+ ands r7, r7, #(1 << 31)
+ bne 10f
+
+ /* audio pll4 */
+ ldr r7, [r10, #0x70]
+ ands r7, r7, #(1 << 31)
+ bne 10f
+
+ /* vidio pll5 */
+ ldr r7, [r10, #0xa0]
+ ands r7, r7, #(1 << 31)
+ bne 10f
+
+ /* enet pll6 */
+ ldr r7, [r10, #0xe0]
+ ands r7, r7, #(1 << 31)
+ bne 10f
+
+ /* usb host pll7 */
+ ldr r7, [r10, #0x20]
+ ands r7, r7, #(1 << 31)
+ bne 10f
+
+ /* enable weak 2P5 and turn off regular 2P5 */
+ ldr r7, [r10, #0x130]
+ orr r7, r7, #0x40000
+ str r7, [r10, #0x130]
+ bic r7, r7, #0x1
+ str r7, [r10, #0x130]
+
+ /* enable weak 1p1 and turn off regular 1P1 */
+ ldr r7, [r10, #0x110]
+ orr r7, r7, #0x40000
+ str r7, [r10, #0x110]
+ bic r7, r7, #0x1
+ str r7, [r10, #0x110]
+
+ /* check whether ARM LDO is bypassed */
+ ldr r7, [r10, #0x140]
+ and r7, r7, #0x1f
+ cmp r7, #0x1f
+ bne 10f
+
+ /* low power band gap enable */
+ ldr r7, [r10, #0x270]
+ orr r7, r7, #0x20
+ str r7, [r10, #0x270]
+
+ /* turn off the bias current from the regular bandgap */
+ ldr r7, [r10, #0x270]
+ orr r7, r7, #0x80
+ str r7, [r10, #0x270]
+
+ /*
+ * clear the REFTOP_SELFBIASOFF,
+ * self-bias circuit of the band gap.
+ * Per RM, should be cleared when
+ * band gap is powered down.
+ */
+ ldr r7, [r10, #0x150]
+ bic r7, r7, #0x8
+ str r7, [r10, #0x150]
+
+ /* turn off regular bandgap */
+ ldr r7, [r10, #0x150]
+ orr r7, r7, #0x1
+ str r7, [r10, #0x150]
+
+10:
+ /* switch to RC-OSC */
+ ldr r7, [r10, #0x270]
+ orr r7, r7, #0x10
+ str r7, [r10, #0x270]
+
+ /* turn off XTAL-OSC */
+ ldr r7, [r10, #0x150]
+ orr r7, r7, #0x40000000
+ str r7, [r10, #0x150]
+
+ /* lower OSC current by 37.5% */
+ ldr r7, [r10, #0x150]
+ orr r7, r7, #0x6000
+ str r7, [r10, #0x150]
+
+ /* disconnect vdd_high_in and vdd_snvs_in */
+ ldr r7, [r10, #0x150]
+ orr r7, r7, #0x1000
+ str r7, [r10, #0x150]
+
+ .endm
+
+ .macro anatop_exit_idle
+
+ cmp r5, #0x0
+ ldreq r10, [r0, #PM_INFO_MX6Q_ANATOP_V_OFFSET]
+ ldrne r10, [r0, #PM_INFO_MX6Q_ANATOP_P_OFFSET]
+
+ /* increase OSC current to normal */
+ ldr r7, [r10, #0x150]
+ bic r7, r7, #0x6000
+ str r7, [r10, #0x150]
+
+ /* turn on XTAL-OSC and detector */
+ ldr r7, [r10, #0x150]
+ bic r7, r7, #0x40000000
+ orr r7, r7, #0x10000
+ str r7, [r10, #0x150]
+
+ /* wait for XTAL stable */
+14:
+ ldr r7, [r10, #0x150]
+ ands r7, r7, #0x8000
+ beq 14b
+
+ /* switch to XTAL-OSC */
+ ldr r7, [r10, #0x270]
+ bic r7, r7, #0x10
+ str r7, [r10, #0x270]
+
+ /* turn off XTAL-OSC detector */
+ ldr r7, [r10, #0x150]
+ bic r7, r7, #0x10000
+ str r7, [r10, #0x150]
+15:
+ /* check whether we need to enable 2P5/1P1 */
+ ldr r7, [r10, #0x110]
+ ands r7, r7, #0x40000
+ beq 11f
+
+ /* check whether ARM LDO is bypassed */
+ ldr r7, [r10, #0x140]
+ and r7, r7, #0x1f
+ cmp r7, #0x1f
+ bne 12f
+
+ /* turn on regular bandgap and wait for stable */
+ ldr r7, [r10, #0x150]
+ bic r7, r7, #0x1
+ str r7, [r10, #0x150]
+13:
+ ldr r7, [r10, #0x150]
+ ands r7, #0x80
+ beq 13b
+
+ /*
+ * set the REFTOP_SELFBIASOFF,
+ * self-bias circuit of the band gap.
+ */
+ ldr r7, [r10, #0x150]
+ orr r7, r7, #0x8
+ str r7, [r10, #0x150]
+
+ /* turn on the bias current from the regular bandgap */
+ ldr r7, [r10, #0x270]
+ bic r7, r7, #0x80
+ str r7, [r10, #0x270]
+
+ /* low power band gap disable */
+ ldr r7, [r10, #0x270]
+ bic r7, r7, #0x20
+ str r7, [r10, #0x270]
+12:
+ /* enable regular 2P5 and turn off weak 2P5 */
+ ldr r7, [r10, #0x130]
+ orr r7, r7, #0x1
+ str r7, [r10, #0x130]
+
+ /* Ensure the 2P5 is up. */
+3:
+ ldr r7, [r10, #0x130]
+ ands r7, r7, #0x20000
+ beq 3b
+ ldr r7, [r10, #0x130]
+ bic r7, r7, #0x40000
+ str r7, [r10, #0x130]
+
+ /* enable regular 1p1 and turn off weak 1P1 */
+ ldr r7, [r10, #0x110]
+ orr r7, r7, #0x1
+ str r7, [r10, #0x110]
+4:
+ ldr r7, [r10, #0x110]
+ ands r7, r7, #0x20000
+ beq 4b
+ ldr r7, [r10, #0x110]
+ bic r7, r7, #0x40000
+ str r7, [r10, #0x110]
+11:
+ .endm
+
+ .macro disable_l1_dcache
+
+ /*
+ * Flush all data from the L1 data cache before disabling
+ * SCTLR.C bit.
+ */
+ push {r0 - r10, lr}
+ ldr r7, =v7_flush_dcache_all
+ mov lr, pc
+ mov pc, r7
+ pop {r0 - r10, lr}
+
+ /* disable d-cache */
+ mrc p15, 0, r7, c1, c0, 0
+ bic r7, r7, #(1 << 2)
+ mcr p15, 0, r7, c1, c0, 0
+ dsb
+ isb
+
+ push {r0 - r10, lr}
+ ldr r7, =v7_flush_dcache_all
+ mov lr, pc
+ mov pc, r7
+ pop {r0 - r10, lr}
+
+ .endm
+
+ .macro mmdc_enter_dvfs_mode
+
+ /* disable automatic power savings. */
+ ldr r7, [r10, #MX6Q_MMDC_MAPSR]
+ orr r7, r7, #0x1
+ str r7, [r10, #MX6Q_MMDC_MAPSR]
+
+ /* disable power down timer */
+ ldr r7, [r10, #0x4]
+ bic r7, r7, #0xff00
+ str r7, [r10, #0x4]
+
+ /* make the DDR explicitly enter self-refresh. */
+ ldr r7, [r10, #MX6Q_MMDC_MAPSR]
+ orr r7, r7, #(1 << 21)
+ str r7, [r10, #MX6Q_MMDC_MAPSR]
+5:
+ ldr r7, [r10, #MX6Q_MMDC_MAPSR]
+ ands r7, r7, #(1 << 25)
+ beq 5b
+
+ .endm
+
+ .macro resume_mmdc
+
+ /* restore MMDC IO */
+ cmp r5, #0x0
+ ldreq r10, [r0, #PM_INFO_MX6Q_IOMUXC_V_OFFSET]
+ ldrne r10, [r0, #PM_INFO_MX6Q_IOMUXC_P_OFFSET]
+
+ ldr r6, [r0, #PM_INFO_MMDC_IO_NUM_OFFSET]
+ ldr r7, =PM_INFO_MMDC_IO_VAL_OFFSET
+ add r7, r7, r0
+6:
+ ldr r8, [r7], #0x4
+ ldr r9, [r7], #0x4
+ str r9, [r10, r8]
+ subs r6, r6, #0x1
+ bne 6b
+
+ cmp r5, #0x0
+ ldreq r10, [r0, #PM_INFO_MX6Q_MMDC_V_OFFSET]
+ ldrne r10, [r0, #PM_INFO_MX6Q_MMDC_P_OFFSET]
+
+ /* reset read FIFO, RST_RD_FIFO */
+ ldr r7, =MX6Q_MMDC_MPDGCTRL0
+ ldr r6, [r10, r7]
+ orr r6, r6, #(1 << 31)
+ str r6, [r10, r7]
+7:
+ ldr r6, [r10, r7]
+ ands r6, r6, #(1 << 31)
+ bne 7b
+
+ /* reset FIFO a second time */
+ ldr r6, [r10, r7]
+ orr r6, r6, #(1 << 31)
+ str r6, [r10, r7]
+8:
+ ldr r6, [r10, r7]
+ ands r6, r6, #(1 << 31)
+ bne 8b
+
+ /* let DDR out of self-refresh */
+ ldr r7, [r10, #MX6Q_MMDC_MAPSR]
+ bic r7, r7, #(1 << 21)
+ str r7, [r10, #MX6Q_MMDC_MAPSR]
+9:
+ ldr r7, [r10, #MX6Q_MMDC_MAPSR]
+ ands r7, r7, #(1 << 25)
+ bne 9b
+
+ /* enable power down timer */
+ ldr r7, [r10, #0x4]
+ orr r7, r7, #0x5500
+ str r7, [r10, #0x4]
+
+ /* enable DDR auto power saving */
+ ldr r7, [r10, #MX6Q_MMDC_MAPSR]
+ bic r7, r7, #0x1
+ str r7, [r10, #MX6Q_MMDC_MAPSR]
+
+ .endm
+
+ .macro tlb_set_to_ocram
+
+ /* save ttbr */
+ mrc p15, 0, r7, c2, c0, 1
+ str r7, [r0, #PM_INFO_PM_INFO_TTBR_OFFSET]
+
+ /*
+ * To ensure no page table walks occur in DDR, we
+ * have a another page table stored in IRAM that only
+ * contains entries pointing to IRAM, AIPS1 and AIPS2.
+ * We need to set the TTBR1 to the new IRAM TLB.
+ * Do the following steps:
+ * 1. Flush the Branch Target Address Cache (BTAC)
+ * 2. Set TTBR1 to point to IRAM page table.
+ * 3. Disable page table walks in TTBR0 (PD0 = 1)
+ * 4. Set TTBR0.N=1, implying 0-2G is translated by TTBR0
+ * and 2-4G is translated by TTBR1.
+ */
+
+ ldr r6, =iram_tlb_phys_addr
+ ldr r7, [r6]
+
+ /* Flush the BTAC. */
+ ldr r6, =0x0
+ mcr p15, 0, r6, c7, c1, 6
+
+ /* Disable Branch Prediction, Z bit in SCTLR. */
+ mrc p15, 0, r6, c1, c0, 0
+ bic r6, r6, #0x800
+ mcr p15, 0, r6, c1, c0, 0
+
+ dsb
+ isb
+
+ /* Store the IRAM table in TTBR1 */
+ mcr p15, 0, r7, c2, c0, 1
+
+ /* Read TTBCR and set PD0=1, N = 1 */
+ mrc p15, 0, r6, c2, c0, 2
+ orr r6, r6, #0x11
+ mcr p15, 0, r6, c2, c0, 2
+
+ dsb
+ isb
+
+ /* flush the TLB */
+ ldr r6, =0x0
+ mcr p15, 0, r6, c8, c3, 0
+
+ .endm
+
+ .macro tlb_back_to_ddr
+
+ /* Restore the TTBCR */
+
+ dsb
+ isb
+
+ /* Read TTBCR and set PD0=0, N = 0 */
+ mrc p15, 0, r6, c2, c0, 2
+ bic r6, r6, #0x11
+ mcr p15, 0, r6, c2, c0, 2
+
+ dsb
+ isb
+
+ /* flush the TLB */
+ ldr r6, =0x0
+ mcr p15, 0, r6, c8, c3, 0
+
+ dsb
+ isb
+
+ /* Enable Branch Prediction, Z bit in SCTLR. */
+ mrc p15, 0, r6, c1, c0, 0
+ orr r6, r6, #0x800
+ mcr p15, 0, r6, c1, c0, 0
+
+ /* Flush the Branch Target Address Cache (BTAC) */
+ ldr r6, =0x0
+ mcr p15, 0, r6, c7, c1, 6
+
+ /* restore ttbr */
+ ldr r7, [r0, #PM_INFO_PM_INFO_TTBR_OFFSET]
+ mcr p15, 0, r7, c2, c0, 1
+
+ .endm
+
+.extern iram_tlb_phys_addr
+
+/* imx6ull_low_power_idle */
+
+ .align 3
+ENTRY(imx6ull_low_power_idle)
+mx6ull_lpm_wfi_start:
+ push {r4 - r10}
+
+ /* get necessary info from pm_info */
+ ldr r1, [r0, #PM_INFO_PBASE_OFFSET]
+ ldr r2, [r0, #PM_INFO_PM_INFO_SIZE_OFFSET]
+
+ /*
+ * counting the resume address in iram
+ * to set it in SRC register.
+ */
+ ldr r5, =imx6ull_low_power_idle
+ ldr r6, =wakeup
+ sub r6, r6, r5
+ add r8, r1, r2
+ add r3, r8, r6
+
+ /* store physical resume addr and pm_info address. */
+ ldr r10, [r0, #PM_INFO_MX6Q_SRC_V_OFFSET]
+ str r3, [r10, #0x20]
+ str r1, [r10, #0x24]
+
+ /* set ARM power to be gated */
+ ldr r10, [r0, #PM_INFO_MX6Q_GPC_V_OFFSET]
+ ldr r7, =0x1
+ str r7, [r10, #0x2a0]
+
+ disable_l1_dcache
+
+ tlb_set_to_ocram
+
+ /* make sure MMDC in self-refresh */
+ ldr r10, [r0, #PM_INFO_MX6Q_MMDC_V_OFFSET]
+ mmdc_enter_dvfs_mode
+
+ /* save DDR IO settings */
+ ldr r10, [r0, #PM_INFO_MX6Q_IOMUXC_V_OFFSET]
+ ldr r6, =0x0
+ ldr r7, [r0, #PM_INFO_MMDC_IO_NUM_OFFSET]
+ ldr r8, =PM_INFO_MMDC_IO_VAL_OFFSET
+ add r8, r8, r0
+save_and_set_mmdc_io_lpm:
+ ldr r9, [r8], #0x4
+ ldr r5, [r10, r9]
+ str r6, [r10, r9]
+ str r5, [r8], #0x4
+ subs r7, r7, #0x1
+ bne save_and_set_mmdc_io_lpm
+
+ mov r5, #0x0
+ ccm_enter_idle
+ anatop_enter_idle
+
+ /*
+ * mask all GPC interrupts before
+ * enabling the RBC counters to
+ * avoid the counter starting too
+ * early if an interupt is already
+ * pending.
+ */
+ ldr r10, [r0, #PM_INFO_MX6Q_GPC_V_OFFSET]
+ ldr r4, [r10, #MX6Q_GPC_IMR1]
+ ldr r5, [r10, #MX6Q_GPC_IMR2]
+ ldr r6, [r10, #MX6Q_GPC_IMR3]
+ ldr r7, [r10, #MX6Q_GPC_IMR4]
+
+ ldr r3, =0xffffffff
+ str r3, [r10, #MX6Q_GPC_IMR1]
+ str r3, [r10, #MX6Q_GPC_IMR2]
+ str r3, [r10, #MX6Q_GPC_IMR3]
+ str r3, [r10, #MX6Q_GPC_IMR4]
+
+ /*
+ * enable the RBC bypass counter here
+ * to hold off the interrupts. RBC counter
+ * = 4 (120us). With this setting, the latency
+ * from wakeup interrupt to ARM power up
+ * is ~130uS.
+ */
+ ldr r10, [r0, #PM_INFO_MX6Q_CCM_V_OFFSET]
+ ldr r3, [r10, #MX6Q_CCM_CCR]
+ bic r3, r3, #(0x3f << 21)
+ orr r3, r3, #(0x4 << 21)
+ str r3, [r10, #MX6Q_CCM_CCR]
+
+ /* enable the counter. */
+ ldr r3, [r10, #MX6Q_CCM_CCR]
+ orr r3, r3, #(0x1 << 27)
+ str r3, [r10, #MX6Q_CCM_CCR]
+
+ /* unmask all the GPC interrupts. */
+ ldr r10, [r0, #PM_INFO_MX6Q_GPC_V_OFFSET]
+ str r4, [r10, #MX6Q_GPC_IMR1]
+ str r5, [r10, #MX6Q_GPC_IMR2]
+ str r6, [r10, #MX6Q_GPC_IMR3]
+ str r7, [r10, #MX6Q_GPC_IMR4]
+
+ /*
+ * now delay for a short while (3usec)
+ * ARM is at 24MHz at this point
+ * so a short loop should be enough.
+ * this delay is required to ensure that
+ * the RBC counter can start counting in
+ * case an interrupt is already pending
+ * or in case an interrupt arrives just
+ * as ARM is about to assert DSM_request.
+ */
+ ldr r4, =50
+rbc_loop:
+ subs r4, r4, #0x1
+ bne rbc_loop
+
+ wfi
+
+ nop
+ nop
+ nop
+ nop
+ nop
+
+ nop
+ nop
+ nop
+ nop
+ nop
+
+ nop
+ nop
+ nop
+ nop
+ nop
+
+ nop
+ nop
+ nop
+ nop
+ nop
+
+ nop
+ nop
+ nop
+ nop
+ nop
+
+ mov r5, #0x0
+ anatop_exit_idle
+ ccm_exit_idle
+
+ /* clear ARM power gate setting */
+ ldr r10, [r0, #PM_INFO_MX6Q_GPC_V_OFFSET]
+ ldr r7, =0x0
+ str r7, [r10, #0x2a0]
+
+ resume_mmdc
+ /* enable d-cache */
+ mrc p15, 0, r7, c1, c0, 0
+ orr r7, r7, #(1 << 2)
+ mcr p15, 0, r7, c1, c0, 0
+
+ tlb_back_to_ddr
+
+ /* Restore registers */
+ pop {r4 - r10}
+ mov pc, lr
+
+wakeup:
+ /* invalidate L1 I-cache first */
+ mov r1, #0x0
+ mcr p15, 0, r1, c7, c5, 0
+ mcr p15, 0, r1, c7, c5, 0
+ mcr p15, 0, r1, c7, c5, 6
+ /* enable the Icache and branch prediction */
+ mov r1, #0x1800
+ mcr p15, 0, r1, c1, c0, 0
+ isb
+
+ /* get physical resume address from pm_info. */
+ ldr lr, [r0, #PM_INFO_RESUME_ADDR_OFFSET]
+ /* clear core0's entry and parameter */
+ ldr r10, [r0, #PM_INFO_MX6Q_SRC_P_OFFSET]
+ mov r7, #0x0
+ str r7, [r10, #MX6Q_SRC_GPR1]
+ str r7, [r10, #MX6Q_SRC_GPR2]
+
+ /* clear ARM power gate setting */
+ ldr r10, [r0, #PM_INFO_MX6Q_GPC_P_OFFSET]
+ ldr r7, =0x0
+ str r7, [r10, #0x2a0]
+
+ mov r5, #0x1
+ anatop_exit_idle
+ ccm_exit_idle
+ resume_mmdc
+
+ /* Restore registers */
+ mov pc, lr
+ .ltorg
+mx6ull_lpm_wfi_end:
diff --git a/arch/arm/mach-imx/imx7d_low_power_idle.S b/arch/arm/mach-imx/imx7d_low_power_idle.S
new file mode 100644
index 000000000000..1551d2ce1acf
--- /dev/null
+++ b/arch/arm/mach-imx/imx7d_low_power_idle.S
@@ -0,0 +1,787 @@
+/*
+ * Copyright (C) 2015 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/linkage.h>
+
+#define PM_INFO_VBASE_OFFSET 0x0
+#define PM_INFO_PBASE_OFFSET 0x4
+#define PM_INFO_RESUME_ADDR_OFFSET 0x8
+#define PM_INFO_PM_INFO_SIZE_OFFSET 0xc
+#define PM_INFO_PM_INFO_TTBR_OFFSET 0x10
+#define PM_INFO_PM_INFO_NUM_ONLINE_CPUS_OFFSET 0x14
+#define PM_INFO_PM_INFO_NUM_LPI_CPUS_OFFSET 0x18
+#define PM_INFO_VAL_OFFSET 0x1c
+#define PM_INFO_FLAG0_OFFSET 0x20
+#define PM_INFO_FLAG1_OFFSET 0x24
+#define PM_INFO_MX7D_DDRC_P_OFFSET 0x28
+#define PM_INFO_MX7D_DDRC_V_OFFSET 0x2c
+#define PM_INFO_MX7D_CCM_P_OFFSET 0x30
+#define PM_INFO_MX7D_CCM_V_OFFSET 0x34
+#define PM_INFO_MX7D_ANATOP_P_OFFSET 0x38
+#define PM_INFO_MX7D_ANATOP_V_OFFSET 0x3c
+#define PM_INFO_MX7D_SRC_P_OFFSET 0x40
+#define PM_INFO_MX7D_SRC_V_OFFSET 0x44
+#define PM_INFO_MX7D_IOMUXC_GPR_P_OFFSET 0x48
+#define PM_INFO_MX7D_IOMUXC_GPR_V_OFFSET 0x4c
+#define PM_INFO_MX7D_GPC_P_OFFSET 0x50
+#define PM_INFO_MX7D_GPC_V_OFFSET 0x54
+#define PM_INFO_MX7D_GIC_DIST_P_OFFSET 0x58
+#define PM_INFO_MX7D_GIC_DIST_V_OFFSET 0x5c
+
+#define MX7D_SRC_GPR1 0x74
+#define MX7D_SRC_GPR2 0x78
+#define MX7D_SRC_GPR3 0x7c
+#define MX7D_SRC_GPR4 0x80
+#define MX7D_GPC_IMR1 0x30
+#define MX7D_GPC_IMR2 0x34
+#define MX7D_GPC_IMR3 0x38
+#define MX7D_GPC_IMR4 0x3c
+#define DDRC_STAT 0x4
+#define DDRC_PWRCTL 0x30
+#define DDRC_DBG1 0x304
+#define DDRC_DBGCAM 0x308
+#define DDRC_PSTAT 0x3fc
+#define DDRC_PCTRL_0 0x490
+
+/*
+ * imx_pen_lock
+ *
+ * The reference link of Peterson's algorithm:
+ * http://en.wikipedia.org/wiki/Peterson's_algorithm
+ *
+ * val1 = r1 = !turn (inverted from Peterson's algorithm)
+ * on cpu 0:
+ * r2 = flag[0] (in flag0)
+ * r3 = flag[1] (in flag1)
+ * on cpu1:
+ * r2 = flag[1] (in flag1)
+ * r3 = flag[0] (in flag0)
+ *
+ */
+ .macro imx_pen_lock
+
+ mov r8, r0
+ mrc p15, 0, r5, c0, c0, 5
+ and r5, r5, #3
+ add r6, r8, #PM_INFO_VAL_OFFSET
+ cmp r5, #0
+ addeq r7, r8, #PM_INFO_FLAG0_OFFSET
+ addeq r8, r8, #PM_INFO_FLAG1_OFFSET
+ addne r7, r8, #PM_INFO_FLAG1_OFFSET
+ addne r8, r8, #PM_INFO_FLAG0_OFFSET
+
+ mov r9, #1
+ str r9, [r7]
+ dsb
+ str r5, [r6]
+1:
+ dsb
+ ldr r9, [r8]
+ cmp r9, #1
+ ldreq r9, [r6]
+ cmpeq r9, r5
+ beq 1b
+
+ .endm
+
+ .macro imx_pen_unlock
+
+ dsb
+ mrc p15, 0, r6, c0, c0, 5
+ and r6, r6, #3
+ cmp r6, #0
+ addeq r7, r0, #PM_INFO_FLAG0_OFFSET
+ addne r7, r0, #PM_INFO_FLAG1_OFFSET
+ mov r9, #0
+ str r9, [r7]
+
+ .endm
+
+ .macro disable_l1_dcache
+
+ push {r0 - r12, lr}
+ ldr r7, =v7_flush_dcache_all
+ mov lr, pc
+ mov pc, r7
+ pop {r0 - r12, lr}
+
+ /* disable d-cache */
+ mrc p15, 0, r7, c1, c0, 0
+ bic r7, r7, #(1 << 2)
+ mcr p15, 0, r7, c1, c0, 0
+ dsb
+ isb
+
+ push {r0 - r12, lr}
+ ldr r7, =v7_flush_dcache_all
+ mov lr, pc
+ mov pc, r7
+ pop {r0 - r12, lr}
+
+#ifdef CONFIG_SMP
+ clrex
+
+ /* Turn off SMP bit. */
+ mrc p15, 0, r8, c1, c0, 1
+ bic r8, r8, #0x40
+ mcr p15, 0, r8, c1, c0, 1
+
+ isb
+ dsb
+#endif
+
+ .endm
+
+ .macro tlb_set_to_ocram
+
+ /* save ttbr */
+ mrc p15, 0, r7, c2, c0, 1
+ str r7, [r0, #PM_INFO_PM_INFO_TTBR_OFFSET]
+
+ /*
+ * To ensure no page table walks occur in DDR, we
+ * have a another page table stored in IRAM that only
+ * contains entries pointing to IRAM, AIPS1 and AIPS2.
+ * We need to set the TTBR1 to the new IRAM TLB.
+ * Do the following steps:
+ * 1. Flush the Branch Target Address Cache (BTAC)
+ * 2. Set TTBR1 to point to IRAM page table.
+ * 3. Disable page table walks in TTBR0 (PD0 = 1)
+ * 4. Set TTBR0.N=1, implying 0-2G is translated by TTBR0
+ * and 2-4G is translated by TTBR1.
+ */
+
+ /* Disable Branch Prediction, Z bit in SCTLR. */
+ mrc p15, 0, r6, c1, c0, 0
+ bic r6, r6, #0x800
+ mcr p15, 0, r6, c1, c0, 0
+
+ /* Flush the BTAC. */
+ ldr r6, =0x0
+ mcr p15, 0, r6, c7, c1, 6
+
+ ldr r6, =iram_tlb_phys_addr
+ ldr r7, [r6]
+
+ dsb
+ isb
+
+ /* Store the IRAM table in TTBR1 */
+ mcr p15, 0, r7, c2, c0, 1
+
+ /* Read TTBCR and set PD0=1, N = 1 */
+ mrc p15, 0, r6, c2, c0, 2
+ orr r6, r6, #0x11
+ mcr p15, 0, r6, c2, c0, 2
+
+ dsb
+ isb
+
+ /* flush the TLB */
+ ldr r6, =0x0
+ mcr p15, 0, r6, c8, c3, 0
+
+ .endm
+
+ .macro tlb_back_to_ddr
+
+ /* Read TTBCR and set PD0=0, N = 0 */
+ mrc p15, 0, r6, c2, c0, 2
+ bic r6, r6, #0x11
+ mcr p15, 0, r6, c2, c0, 2
+
+ dsb
+ isb
+
+ /* flush the TLB */
+ ldr r6, =0x0
+ mcr p15, 0, r6, c8, c3, 0
+
+ /* Enable Branch Prediction, Z bit in SCTLR. */
+ mrc p15, 0, r6, c1, c0, 0
+ orr r6, r6, #0x800
+ mcr p15, 0, r6, c1, c0, 0
+
+ /* Flush the Branch Target Address Cache (BTAC) */
+ ldr r6, =0x0
+ mcr p15, 0, r6, c7, c1, 6
+
+ /* restore ttbr */
+ ldr r7, [r0, #PM_INFO_PM_INFO_TTBR_OFFSET]
+ mcr p15, 0, r7, c2, c0, 1
+
+ .endm
+
+ /* r10 must be DDRC base address */
+ .macro ddrc_enter_self_refresh
+
+ ldr r10, [r0, #PM_INFO_MX7D_DDRC_V_OFFSET]
+
+ /* disable port */
+ ldr r7, =0x0
+ str r7, [r10, #DDRC_PCTRL_0]
+
+ /* let DDR out of self-refresh */
+ ldr r7, =0x0
+ str r7, [r10, #DDRC_PWRCTL]
+
+ /* wait rw port_busy clear */
+ ldr r6, =(0x1 << 16)
+ orr r6, r6, #0x1
+2:
+ ldr r7, [r10, #DDRC_PSTAT]
+ ands r7, r7, r6
+ bne 2b
+
+ ldr r7, =0x1
+ str r7, [r10, #DDRC_DBG1]
+
+ ldr r6, =0x36000000
+11:
+ ldr r7, [r10, #DDRC_DBGCAM]
+ and r7, r7, r6
+ cmp r7, r6
+ bne 11b
+
+ /* enter self-refresh bit 5 */
+ ldr r7, =(0x1 << 5)
+ str r7, [r10, #DDRC_PWRCTL]
+
+ /* wait until self-refresh mode entered */
+3:
+ ldr r7, [r10, #DDRC_STAT]
+ and r7, r7, #0x3
+ cmp r7, #0x3
+ bne 3b
+4:
+ ldr r7, [r10, #DDRC_STAT]
+ ands r7, r7, #0x20
+ beq 4b
+
+ /* disable dram clk */
+ ldr r7, [r10, #DDRC_PWRCTL]
+ orr r7, r7, #(1 << 3)
+ str r7, [r10, #DDRC_PWRCTL]
+
+ /*
+ * TO1.1 adds feature of DDR pads power down,
+ * although TO1.0 has no such function, but it is
+ * NOT harmful to program GPR registers for TO1.0,
+ * it can avoid the logic of version check in idle
+ * thread.
+ */
+ ldr r10, [r0, #PM_INFO_MX7D_IOMUXC_GPR_V_OFFSET]
+ ldr r7, =0xf0000
+ str r7, [r10]
+
+ /* delay 20us, measured by gpio */
+ ldr r7, =20
+12:
+ subs r7, r7, #0x1
+ bne 12b
+
+ .endm
+
+ /* r10 must be DDRC base address */
+ .macro ddrc_exit_self_refresh
+
+ cmp r5, #0x1
+ ldreq r10, [r0, #PM_INFO_MX7D_IOMUXC_GPR_P_OFFSET]
+ ldrne r10, [r0, #PM_INFO_MX7D_IOMUXC_GPR_V_OFFSET]
+
+ ldr r7, =0x0
+ str r7, [r10]
+
+ ldr r7, =20
+13:
+ subs r7, r7, #0x1
+ bne 13b
+
+ cmp r5, #0x1
+ ldreq r10, [r0, #PM_INFO_MX7D_DDRC_P_OFFSET]
+ ldrne r10, [r0, #PM_INFO_MX7D_DDRC_V_OFFSET]
+
+ ldr r7, =0x0
+ str r7, [r10, #DDRC_DBG1]
+
+ ldr r6, =0x30000000
+14:
+ ldr r7, [r10, #DDRC_DBGCAM]
+ and r7, r7, r6
+ cmp r7, r6
+ bne 14b
+
+ /* let DDR out of self-refresh */
+ ldr r7, =0x0
+ str r7, [r10, #DDRC_PWRCTL]
+
+ /* wait until self-refresh mode exited */
+5:
+ ldr r7, [r10, #DDRC_STAT]
+ and r7, r7, #0x3
+ cmp r7, #0x3
+ beq 5b
+
+ /* enable auto self-refresh */
+ ldr r7, [r10, #DDRC_PWRCTL]
+ orr r7, r7, #(1 << 0)
+ str r7, [r10, #DDRC_PWRCTL]
+
+ ldr r7, =0x1
+ str r7, [r10, #DDRC_PCTRL_0]
+
+ .endm
+
+ .macro pll_do_wait_lock
+6:
+ ldr r7, [r10, r8]
+ ands r7, #0x80000000
+ beq 6b
+
+ .endm
+
+ .macro ccm_enter_idle
+
+ ldr r10, [r0, #PM_INFO_MX7D_ANATOP_V_OFFSET]
+
+ /* ungate pfd1 332m for lower axi */
+ ldr r7, =0x8000
+ str r7, [r10, #0xc8]
+
+ ldr r10, [r0, #PM_INFO_MX7D_CCM_V_OFFSET]
+
+ /* switch ARM CLK to OSC */
+ ldr r8, =0x8000
+ ldr r7, [r10, r8]
+ bic r7, r7, #0x7000000
+ str r7, [r10, r8]
+
+ /* lower AXI clk from 24MHz to 3MHz */
+ ldr r8, =0x8800
+ ldr r7, [r10, r8]
+ orr r7, r7, #0x7
+ str r7, [r10, r8]
+
+ /* lower AHB clk from 24MHz to 3MHz */
+ ldr r8, =0x9000
+ ldr r7, [r10, r8]
+ orr r7, r7, #0x7
+ str r7, [r10, r8]
+
+ /* gate dram clk */
+ ldr r8, =0x9880
+ ldr r7, [r10, r8]
+ bic r7, r7, #0x10000000
+ str r7, [r10, r8]
+
+ ldr r10, [r0, #PM_INFO_MX7D_ANATOP_V_OFFSET]
+
+ /* gate pfd1 332m */
+ ldr r7, =0x8000
+ str r7, [r10, #0xc4]
+
+ /* gate system pll pfd div 1 */
+ ldr r7, =0x10
+ str r7, [r10, #0xb4]
+ /* power down ARM, 480 and DRAM PLL */
+ ldr r7, =0x1000
+ str r7, [r10, #0x64]
+ str r7, [r10, #0xb4]
+ ldr r7, =0x100000
+ str r7, [r10, #0x74]
+
+ .endm
+
+ .macro ccm_exit_idle
+
+ cmp r5, #0x1
+ ldreq r10, [r0, #PM_INFO_MX7D_ANATOP_P_OFFSET]
+ ldrne r10, [r0, #PM_INFO_MX7D_ANATOP_V_OFFSET]
+
+ /* power up ARM, 480 and DRAM PLL */
+ ldr r7, =0x1000
+ str r7, [r10, #0x68]
+ ldr r8, =0x60
+ pll_do_wait_lock
+
+ ldr r7, =0x1000
+ str r7, [r10, #0xb8]
+ ldr r8, =0xb0
+ pll_do_wait_lock
+
+ ldr r7, =0x100000
+ str r7, [r10, #0x78]
+ ldr r8, =0x70
+ pll_do_wait_lock
+
+ /* ungate pfd1 332m for lower axi */
+ ldr r7, =0x8000
+ str r7, [r10, #0xc8]
+
+ /* ungate system pll pfd div 1 */
+ ldr r7, =0x10
+ str r7, [r10, #0xb8]
+
+ cmp r5, #0x1
+ ldreq r10, [r0, #PM_INFO_MX7D_CCM_P_OFFSET]
+ ldrne r10, [r0, #PM_INFO_MX7D_CCM_V_OFFSET]
+
+ /* switch ARM CLK to PLL */
+ ldr r8, =0x8000
+ ldr r7, [r10, r8]
+ orr r7, r7, #0x1000000
+ str r7, [r10, r8]
+
+ /* restore AXI clk from 3MHz to 24MHz */
+ ldr r8, =0x8800
+ ldr r7, [r10, r8]
+ bic r7, r7, #0x7
+ str r7, [r10, r8]
+
+ /* restore AHB clk from 3MHz to 24MHz */
+ ldr r8, =0x9000
+ ldr r7, [r10, r8]
+ bic r7, r7, #0x7
+ str r7, [r10, r8]
+
+ /* ungate dram clk */
+ ldr r8, =0x9880
+ ldr r7, [r10, r8]
+ orr r7, r7, #0x10000000
+ str r7, [r10, r8]
+
+ cmp r5, #0x1
+ ldreq r10, [r0, #PM_INFO_MX7D_ANATOP_P_OFFSET]
+ ldrne r10, [r0, #PM_INFO_MX7D_ANATOP_V_OFFSET]
+
+ /* gate pfd1 332m for lower axi */
+ ldr r7, =0x8000
+ str r7, [r10, #0xc4]
+
+ .endm
+
+ .macro anatop_enter_idle
+
+ ldr r10, [r0, #PM_INFO_MX7D_ANATOP_V_OFFSET]
+
+ /* XTAL to RC-OSC switch */
+ ldr r7, [r10]
+ orr r7, r7, #0x1000
+ str r7, [r10]
+ /* power down XTAL */
+ ldr r7, [r10]
+ orr r7, r7, #0x1
+ str r7, [r10]
+
+ /* enable weak 1P0A */
+ ldr r7, [r10, #0x200]
+ orr r7, r7, #0x40000
+ str r7, [r10, #0x200]
+
+ /* disable LDO 1P0A */
+ ldr r7, [r10, #0x200]
+ bic r7, r7, #0x1
+ str r7, [r10, #0x200]
+
+ /* disable LDO 1P0D */
+ ldr r7, [r10, #0x210]
+ bic r7, r7, #0x1
+ str r7, [r10, #0x210]
+
+ /* disable LDO 1P2 */
+ ldr r7, [r10, #0x220]
+ bic r7, r7, #0x1
+ str r7, [r10, #0x220]
+
+ /* switch to low power bandgap */
+ ldr r7, [r10, #0x270]
+ orr r7, r7, #0x400
+ str r7, [r10, #0x270]
+ /* power down normal bandgap */
+ orr r7, r7, #0x1
+ str r7, [r10, #0x270]
+
+ .endm
+
+ .macro anatop_exit_idle
+
+ cmp r5, #0x1
+ ldreq r10, [r0, #PM_INFO_MX7D_ANATOP_P_OFFSET]
+ ldrne r10, [r0, #PM_INFO_MX7D_ANATOP_V_OFFSET]
+
+ /* power on normal bandgap */
+ ldr r7, [r10, #0x270]
+ bic r7, r7, #0x1
+ str r7, [r10, #0x270]
+ /* switch to normal bandgap */
+ bic r7, r7, #0x400
+ str r7, [r10, #0x270]
+
+ /* enable LDO 1P2 */
+ ldr r7, [r10, #0x220]
+ orr r7, r7, #0x1
+ str r7, [r10, #0x220]
+7:
+ ldr r7, [r10, #0x220]
+ ands r7, #0x20000
+ beq 7b
+
+ /* enable LDO 1P0D */
+ ldr r7, [r10, #0x210]
+ orr r7, r7, #0x1
+ str r7, [r10, #0x210]
+8:
+ ldr r7, [r10, #0x210]
+ ands r7, #0x20000
+ beq 8b
+
+ /* enable LDO 1P0A */
+ ldr r7, [r10, #0x200]
+ orr r7, r7, #0x1
+ str r7, [r10, #0x200]
+9:
+ ldr r7, [r10, #0x200]
+ ands r7, #0x20000
+ beq 9b
+ /* disable weak 1P0A */
+ ldr r7, [r10, #0x200]
+ bic r7, r7, #0x40000
+ str r7, [r10, #0x200]
+
+ /* power up XTAL and wait */
+ ldr r7, [r10]
+ bic r7, r7, #0x1
+ str r7, [r10]
+10:
+ ldr r7, [r10]
+ ands r7, r7, #0x4
+ beq 10b
+ /* RC-OSC to XTAL switch */
+ ldr r7, [r10]
+ bic r7, r7, #0x1000
+ str r7, [r10]
+
+ .endm
+
+.extern iram_tlb_phys_addr
+
+ .align 3
+ENTRY(imx7d_low_power_idle)
+ push {r0 - r12}
+
+ /* get necessary info from pm_info */
+ ldr r1, [r0, #PM_INFO_PBASE_OFFSET]
+ ldr r2, [r0, #PM_INFO_PM_INFO_SIZE_OFFSET]
+
+ /*
+ * counting the resume address in iram
+ * to set it in SRC register.
+ */
+ ldr r5, =imx7d_low_power_idle
+ ldr r6, =wakeup
+ sub r6, r6, r5
+ add r8, r1, r2
+ add r3, r8, r6
+
+ /* r11 is cpu id */
+ mrc p15, 0, r11, c0, c0, 5
+ and r11, r11, #3
+ cmp r11, #0x0
+ ldreq r6, =MX7D_SRC_GPR1
+ ldreq r7, =MX7D_SRC_GPR2
+ ldrne r6, =MX7D_SRC_GPR3
+ ldrne r7, =MX7D_SRC_GPR4
+ /* store physical resume addr and pm_info address. */
+ ldr r10, [r0, #PM_INFO_MX7D_SRC_V_OFFSET]
+ str r3, [r10, r6]
+ str r1, [r10, r7]
+
+ disable_l1_dcache
+
+ tlb_set_to_ocram
+
+ /* check last to sleep */
+ ldr r6, [r0, #PM_INFO_PM_INFO_NUM_ONLINE_CPUS_OFFSET]
+ ldr r7, [r0, #PM_INFO_PM_INFO_NUM_LPI_CPUS_OFFSET]
+ cmp r6, r7
+ bne lpi_enter_done
+
+ ddrc_enter_self_refresh
+ ccm_enter_idle
+ anatop_enter_idle
+
+ ldr r10, [r0, #PM_INFO_MX7D_GIC_DIST_V_OFFSET]
+ ldr r7, =0x0
+ ldr r8, =0x1000
+ str r7, [r10, r8]
+
+ ldr r10, [r0, #PM_INFO_MX7D_GPC_V_OFFSET]
+ ldr r4, [r10, #MX7D_GPC_IMR1]
+ ldr r5, [r10, #MX7D_GPC_IMR2]
+ ldr r6, [r10, #MX7D_GPC_IMR3]
+ ldr r7, [r10, #MX7D_GPC_IMR4]
+
+ ldr r8, =0xffffffff
+ str r8, [r10, #MX7D_GPC_IMR1]
+ str r8, [r10, #MX7D_GPC_IMR2]
+ str r8, [r10, #MX7D_GPC_IMR3]
+ str r8, [r10, #MX7D_GPC_IMR4]
+
+ /*
+ * enable the RBC bypass counter here
+ * to hold off the interrupts. RBC counter
+ * = 8 (240us). With this setting, the latency
+ * from wakeup interrupt to ARM power up
+ * is ~250uS.
+ */
+ ldr r8, [r10, #0x14]
+ bic r8, r8, #(0x3f << 24)
+ orr r8, r8, #(0x8 << 24)
+ str r8, [r10, #0x14]
+
+ /* enable the counter. */
+ ldr r8, [r10, #0x14]
+ orr r8, r8, #(0x1 << 30)
+ str r8, [r10, #0x14]
+
+ /* unmask all the GPC interrupts. */
+ str r4, [r10, #MX7D_GPC_IMR1]
+ str r5, [r10, #MX7D_GPC_IMR2]
+ str r6, [r10, #MX7D_GPC_IMR3]
+ str r7, [r10, #MX7D_GPC_IMR4]
+
+ /*
+ * now delay for a short while (30usec)
+ * ARM is at 24MHz at this point
+ * so a short loop should be enough.
+ * this delay is required to ensure that
+ * the RBC counter can start counting in
+ * case an interrupt is already pending
+ * or in case an interrupt arrives just
+ * as ARM is about to assert DSM_request.
+ */
+ ldr r4, =5
+rbc_loop:
+ subs r4, r4, #0x1
+ bne rbc_loop
+
+lpi_enter_done:
+
+ imx_pen_unlock
+
+ wfi
+
+ nop
+ nop
+ nop
+ nop
+ nop
+
+ nop
+ nop
+ nop
+ nop
+ nop
+
+ nop
+ nop
+ nop
+ nop
+ nop
+
+ nop
+ nop
+ nop
+ nop
+ nop
+
+ nop
+ nop
+ nop
+ nop
+ nop
+
+ imx_pen_lock
+
+ /* check first to wake */
+ ldr r6, [r0, #PM_INFO_PM_INFO_NUM_ONLINE_CPUS_OFFSET]
+ ldr r7, [r0, #PM_INFO_PM_INFO_NUM_LPI_CPUS_OFFSET]
+ cmp r6, r7
+ bne skip_lpi_flow
+
+ ldr r5, =0x0
+ anatop_exit_idle
+ ccm_exit_idle
+ ddrc_exit_self_refresh
+
+ ldr r10, [r0, #PM_INFO_MX7D_GIC_DIST_V_OFFSET]
+ ldr r7, =0x1
+ ldr r8, =0x1000
+ str r7, [r10, r8]
+
+skip_lpi_flow:
+ tlb_back_to_ddr
+
+#ifdef CONFIG_SMP
+ /* Turn on SMP bit. */
+ mrc p15, 0, r7, c1, c0, 1
+ orr r7, r7, #0x40
+ mcr p15, 0, r7, c1, c0, 1
+
+ isb
+#endif
+
+ /* enable d-cache */
+ mrc p15, 0, r7, c1, c0, 0
+ orr r7, r7, #(1 << 2)
+ mcr p15, 0, r7, c1, c0, 0
+ dsb
+ isb
+
+ /* Restore registers */
+ pop {r0 - r12}
+ mov pc, lr
+
+wakeup:
+ /* invalidate L1 I-cache first */
+ mov r1, #0x0
+ mcr p15, 0, r1, c7, c5, 0
+ mcr p15, 0, r1, c7, c5, 0
+ mcr p15, 0, r1, c7, c5, 6
+ /* enable the Icache and branch prediction */
+ mov r1, #0x1800
+ mcr p15, 0, r1, c1, c0, 0
+ isb
+
+ imx_pen_lock
+
+ /* check first to wake */
+ ldr r6, [r0, #PM_INFO_PM_INFO_NUM_ONLINE_CPUS_OFFSET]
+ ldr r7, [r0, #PM_INFO_PM_INFO_NUM_LPI_CPUS_OFFSET]
+ cmp r6, r7
+ bne wakeup_skip_lpi_flow
+
+ ldr r5, =0x1
+ anatop_exit_idle
+ ccm_exit_idle
+ ddrc_exit_self_refresh
+
+wakeup_skip_lpi_flow:
+ /* get physical resume address from pm_info. */
+ ldr lr, [r0, #PM_INFO_RESUME_ADDR_OFFSET]
+
+ /* Restore registers */
+ mov pc, lr
+ .ltorg
+ENDPROC(imx7d_low_power_idle)
diff --git a/arch/arm/mach-imx/lpddr2_freq_imx6.S b/arch/arm/mach-imx/lpddr2_freq_imx6.S
new file mode 100644
index 000000000000..21179fb2cb72
--- /dev/null
+++ b/arch/arm/mach-imx/lpddr2_freq_imx6.S
@@ -0,0 +1,618 @@
+/*
+ * Copyright (C) 2012-2016 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/linkage.h>
+#include "hardware.h"
+
+#define PL310_AUX_CTRL 0x104
+#define PL310_DCACHE_LOCKDOWN_BASE 0x900
+#define PL310_AUX_16WAY_BIT 0x10000
+#define PL310_LOCKDOWN_NBREGS 8
+#define PL310_LOCKDOWN_SZREG 4
+#define PL310_8WAYS_MASK 0x00FF
+#define PL310_16WAYS_UPPERMASK 0xFF00
+
+.globl imx6_lpddr2_freq_change_start
+.globl imx6_lpddr2_freq_change_end
+
+ .macro mx6sl_switch_to_24MHz
+
+ /*
+ * Set MMDC clock to be sourced from PLL3.
+ * Ensure first periph2_clk2 is sourced from PLL3.
+ * Set the PERIPH2_CLK2_PODF to divide by 2.
+ */
+ ldr r6, [r2, #0x14]
+ bic r6, r6, #0x7
+ orr r6, r6, #0x1
+ str r6, [r2, #0x14]
+
+ /* Select PLL3 to source MMDC. */
+ ldr r6, [r2, #0x18]
+ bic r6, r6, #0x100000
+ str r6, [r2, #0x18]
+
+ /* Swtich periph2_clk_sel to run from PLL3. */
+ ldr r6, [r2, #0x14]
+ orr r6, r6, #0x4000000
+ str r6, [r2, #0x14]
+
+periph2_clk_switch1:
+ ldr r6, [r2, #0x48]
+ cmp r6, #0
+ bne periph2_clk_switch1
+
+ /*
+ * Need to clock gate the 528 PFDs before
+ * powering down PLL2.
+ * Only the PLL2_PFD2_400M should be ON
+ * at this time, so only clock gate that one.
+ */
+ ldr r6, [r3, #0x100]
+ orr r6, r6, #0x800000
+ str r6, [r3, #0x100]
+
+ /*
+ * Set PLL2 to bypass state. We should be here
+ * only if MMDC is not sourced from PLL2.
+ */
+ ldr r6, [r3, #0x30]
+ orr r6, r6, #0x10000
+ str r6, [r3, #0x30]
+
+ ldr r6, [r3, #0x30]
+ orr r6, r6, #0x1000
+ str r6, [r3, #0x30]
+
+ /* Ensure pre_periph2_clk_mux is set to pll2 */
+ ldr r6, [r2, #0x18]
+ bic r6, r6, #0x600000
+ str r6, [r2, #0x18]
+
+ /* Set MMDC clock to be sourced from the bypassed PLL2. */
+ ldr r6, [r2, #0x14]
+ bic r6, r6, #0x4000000
+ str r6, [r2, #0x14]
+
+periph2_clk_switch2:
+ ldr r6, [r2, #0x48]
+ cmp r6, #0
+ bne periph2_clk_switch2
+
+ /*
+ * Now move MMDC back to periph2_clk2 source.
+ * after selecting PLL2 as the option.
+ * Select PLL2 as the source.
+ */
+ ldr r6, [r2, #0x18]
+ orr r6, r6, #0x100000
+ str r6, [r2, #0x18]
+
+ /* set periph2_clk2_podf to divide by 1. */
+ ldr r6, [r2, #0x14]
+ bic r6, r6, #0x7
+ str r6, [r2, #0x14]
+
+ /* Now move periph2_clk to periph2_clk2 source */
+ ldr r6, [r2, #0x14]
+ orr r6, r6, #0x4000000
+ str r6, [r2, #0x14]
+
+periph2_clk_switch3:
+ ldr r6, [r2, #0x48]
+ cmp r6, #0
+ bne periph2_clk_switch3
+
+ /* Now set the MMDC PODF back to 1.*/
+ ldr r6, [r2, #0x14]
+ bic r6, r6, #0x38
+ str r6, [r2, #0x14]
+
+mmdc_podf0:
+ ldr r6, [r2, #0x48]
+ cmp r6, #0
+ bne mmdc_podf0
+
+ .endm
+
+ .macro ddr_switch_400MHz
+
+ /* Set MMDC divider first, in case PLL3 is at 480MHz. */
+ ldr r6, [r3, #0x10]
+ and r6, r6, #0x10000
+ cmp r6, #0x10000
+ beq pll3_in_bypass
+
+ /* Set MMDC divder to divide by 2. */
+ ldr r6, [r2, #0x14]
+ bic r6, r6, #0x38
+ orr r6, r6, #0x8
+ str r6, [r2, #0x14]
+
+mmdc_podf:
+ ldr r6, [r2, #0x48]
+ cmp r6, #0
+ bne mmdc_podf
+
+pll3_in_bypass:
+ /*
+ * Check if we are switching between
+ * 400Mhz <-> 100MHz.If so, we should
+ * try to source MMDC from PLL2_200M.
+ */
+ cmp r1, #0
+ beq not_low_bus_freq
+
+ /* Ensure that MMDC is sourced from PLL2 mux first. */
+ ldr r6, [r2, #0x14]
+ bic r6, r6, #0x4000000
+ str r6, [r2, #0x14]
+
+periph2_clk_switch4:
+ ldr r6, [r2, #0x48]
+ cmp r6, #0
+ bne periph2_clk_switch4
+
+not_low_bus_freq:
+ /* Now ensure periph2_clk2_sel mux is set to PLL3 */
+ ldr r6, [r2, #0x18]
+ bic r6, r6, #0x100000
+ str r6, [r2, #0x18]
+
+ /* Now switch MMDC to PLL3. */
+ ldr r6, [r2, #0x14]
+ orr r6, r6, #0x4000000
+ str r6, [r2, #0x14]
+
+periph2_clk_switch5:
+ ldr r6, [r2, #0x48]
+ cmp r6, #0
+ bne periph2_clk_switch5
+
+ /*
+ * Check if PLL2 is already unlocked.
+ * If so do nothing with PLL2.
+ */
+ cmp r1, #0
+ beq pll2_already_on
+
+ /* Now power up PLL2 and unbypass it. */
+ ldr r6, [r3, #0x30]
+ bic r6, r6, #0x1000
+ str r6, [r3, #0x30]
+
+ /* Make sure PLL2 has locked.*/
+wait_for_pll_lock:
+ ldr r6, [r3, #0x30]
+ and r6, r6, #0x80000000
+ cmp r6, #0x80000000
+ bne wait_for_pll_lock
+
+ ldr r6, [r3, #0x30]
+ bic r6, r6, #0x10000
+ str r6, [r3, #0x30]
+
+ /*
+ * Need to enable the 528 PFDs after
+ * powering up PLL2.
+ * Only the PLL2_PFD2_400M should be ON
+ * as it feeds the MMDC. Rest should have
+ * been managed by clock code.
+ */
+ ldr r6, [r3, #0x100]
+ bic r6, r6, #0x800000
+ str r6, [r3, #0x100]
+
+pll2_already_on:
+ /*
+ * Now switch MMDC clk back to pll2_mux option.
+ * Ensure pre_periph2_clk2 is set to pll2_pfd_400M.
+ * If switching to audio DDR freq, set the
+ * pre_periph2_clk2 to PLL2_PFD_200M
+ */
+ ldr r6, =400000000
+ cmp r6, r0
+ bne use_pll2_pfd_200M
+
+ ldr r6, [r2, #0x18]
+ bic r6, r6, #0x600000
+ orr r6, r6, #0x200000
+ str r6, [r2, #0x18]
+ ldr r6, =400000000
+ b cont2
+
+use_pll2_pfd_200M:
+ ldr r6, [r2, #0x18]
+ orr r6, r6, #0x600000
+ str r6, [r2, #0x18]
+ ldr r6, =200000000
+
+cont2:
+ ldr r4, [r2, #0x14]
+ bic r4, r4, #0x4000000
+ str r4, [r2, #0x14]
+
+periph2_clk_switch6:
+ ldr r4, [r2, #0x48]
+ cmp r4, #0
+ bne periph2_clk_switch6
+
+change_divider_only:
+ /*
+ * Calculate the MMDC divider
+ * based on the requested freq.
+ */
+ ldr r4, =0
+Loop2:
+ sub r6, r6, r0
+ cmp r6, r0
+ blt Div_Found
+ add r4, r4, #1
+ bgt Loop2
+
+ /* Shift divider into correct offset. */
+ lsl r4, r4, #3
+Div_Found:
+ /* Set the MMDC PODF. */
+ ldr r6, [r2, #0x14]
+ bic r6, r6, #0x38
+ orr r6, r6, r4
+ str r6, [r2, #0x14]
+
+mmdc_podf1:
+ ldr r6, [r2, #0x48]
+ cmp r6, #0
+ bne mmdc_podf1
+
+ .endm
+
+ .macro mmdc_clk_lower_100MHz
+
+ /*
+ * Prior to reducing the DDR frequency (at 528/400 MHz),
+ * read the Measure unit count bits (MU_UNIT_DEL_NUM)
+ */
+ ldr r5, =0x8B8
+ ldr r6, [r8, r5]
+ /* Original MU unit count */
+ mov r6, r6, LSR #16
+ ldr r4, =0x3FF
+ and r6, r6, r4
+ /* Original MU unit count * 2 */
+ mov r7, r6, LSL #1
+ /*
+ * Bypass the automatic measure unit when below 100 MHz
+ * by setting the Measure unit bypass enable bit (MU_BYP_EN)
+ */
+ ldr r6, [r8, r5]
+ orr r6, r6, #0x400
+ str r6, [r8, r5]
+ /*
+ * Double the measure count value read in step 1 and program it in the
+ * measurement bypass bits (MU_BYP_VAL) of the MMDC PHY Measure Unit
+ * Register for the reduced frequency operation below 100 MHz
+ */
+ ldr r6, [r8, r5]
+ ldr r4, =0x3FF
+ bic r6, r6, r4
+ orr r6, r6, r7
+ str r6, [r8, r5]
+
+ .endm
+
+ .macro mmdc_clk_above_100MHz
+
+ /* Make sure that the PHY measurement unit is NOT in bypass mode */
+ ldr r5, =0x8B8
+ ldr r6, [r8, r5]
+ bic r6, r6, #0x400
+ str r6, [r8, r5]
+ /* Now perform a Force Measurement. */
+ ldr r6, [r8, r5]
+ orr r6, r6, #0x800
+ str r6, [r8, r5]
+ /* Wait for FRC_MSR to clear. */
+force_measure1:
+ ldr r6, [r8, r5]
+ and r6, r6, #0x800
+ cmp r6, #0x0
+ bne force_measure1
+ .endm
+
+/*
+ * mx6_lpddr2_freq_change
+ *
+ * Make sure DDR is in self-refresh.
+ * IRQs are already disabled.
+ * r0 : DDR freq.
+ * r1: low_bus_freq_mode flag
+ */
+ .align 3
+ENTRY(mx6_lpddr2_freq_change)
+imx6_lpddr2_freq_change_start:
+ push {r4-r10}
+
+ /*
+ * To ensure no page table walks occur in DDR, we
+ * have a another page table stored in IRAM that only
+ * contains entries pointing to IRAM, AIPS1 and AIPS2.
+ * We need to set the TTBR1 to the new IRAM TLB.
+ * Do the following steps:
+ * 1. Flush the Branch Target Address Cache (BTAC)
+ * 2. Set TTBR1 to point to IRAM page table.
+ * 3. Disable page table walks in TTBR0 (PD0 = 1)
+ * 4. Set TTBR0.N=1, implying 0-2G is translated by TTBR0
+ * and 2-4G is translated by TTBR1.
+ */
+
+ ldr r6, =iram_tlb_phys_addr
+ ldr r7, [r6]
+
+ /* Disable Branch Prediction, Z bit in SCTLR. */
+ mrc p15, 0, r6, c1, c0, 0
+ bic r6, r6, #0x800
+ mcr p15, 0, r6, c1, c0, 0
+
+ /* Flush the Branch Target Address Cache (BTAC) */
+ ldr r6, =0x0
+ mcr p15, 0, r6, c7, c1, 6
+
+ dsb
+ isb
+ /* Store the IRAM table in TTBR1 */
+ mcr p15, 0, r7, c2, c0, 1
+
+ /* Read TTBCR and set PD0=1, N = 1 */
+ mrc p15, 0, r6, c2, c0, 2
+ orr r6, r6, #0x11
+ mcr p15, 0, r6, c2, c0, 2
+
+ dsb
+ isb
+
+ /* flush the TLB */
+ ldr r6, =0x0
+ mcr p15, 0, r6, c8, c3, 0
+
+ /* Disable L1 data cache. */
+ mrc p15, 0, r6, c1, c0, 0
+ bic r6, r6, #0x4
+ mcr p15, 0, r6, c1, c0, 0
+
+ dsb
+ isb
+
+
+#ifdef CONFIG_CACHE_L2X0
+ /*
+ * Need to make sure the buffers in L2 are drained.
+ * Performing a sync operation does this.
+ */
+ ldr r7, =IMX_IO_P2V(MX6Q_L2_BASE_ADDR)
+
+ /* Wait for background operations to complete. */
+wait_for_l2_to_idle:
+ ldr r6, [r7, #0x730]
+ cmp r6, #0x0
+ bne wait_for_l2_to_idle
+
+ mov r6, #0x0
+ str r6, [r7, #0x730]
+
+ /*
+ * The second dsb might be needed to keep cache sync (device write)
+ * ordering with the memory accesses before it.
+ */
+ dsb
+ isb
+
+ ldr r3, [r7, #PL310_AUX_CTRL]
+ tst r3, #PL310_AUX_16WAY_BIT
+ mov r3, #PL310_8WAYS_MASK
+ orrne r3, #PL310_16WAYS_UPPERMASK
+ mov r6, #PL310_LOCKDOWN_NBREGS
+ add r5, r7, #PL310_DCACHE_LOCKDOWN_BASE
+1: /* lock Dcache and Icache */
+ str r3, [r5], #PL310_LOCKDOWN_SZREG
+ str r3, [r5], #PL310_LOCKDOWN_SZREG
+ subs r6, r6, #1
+ bne 1b
+#endif
+
+ ldr r3, =IMX_IO_P2V(MX6Q_ANATOP_BASE_ADDR)
+ ldr r2, =IMX_IO_P2V(MX6Q_CCM_BASE_ADDR)
+ ldr r8, =IMX_IO_P2V(MX6Q_MMDC_P0_BASE_ADDR)
+
+ /* Disable Automatic power savings. */
+ ldr r6, [r8, #0x404]
+ orr r6, r6, #0x01
+ str r6, [r8, #0x404]
+
+ /* MMDC0_MDPDC disable power down timer */
+ ldr r6, [r8, #0x4]
+ bic r6, r6, #0xff00
+ str r6, [r8, #0x4]
+
+ /* Delay for a while */
+ ldr r10, =10
+delay1:
+ ldr r7, =0
+cont1:
+ ldr r6, [r8, r7]
+ add r7, r7, #4
+ cmp r7, #16
+ bne cont1
+ sub r10, r10, #1
+ cmp r10, #0
+ bgt delay1
+
+ /* Make the DDR explicitly enter self-refresh. */
+ ldr r6, [r8, #0x404]
+ orr r6, r6, #0x200000
+ str r6, [r8, #0x404]
+
+poll_dvfs_set_1:
+ ldr r6, [r8, #0x404]
+ and r6, r6, #0x2000000
+ cmp r6, #0x2000000
+ bne poll_dvfs_set_1
+
+ /* set SBS step-by-step mode */
+ ldr r6, [r8, #0x410]
+ orr r6, r6, #0x100
+ str r6, [r8, #0x410]
+
+ ldr r10, =100000000
+ cmp r0, r10
+ bgt set_ddr_mu_above_100
+ mmdc_clk_lower_100MHz
+
+set_ddr_mu_above_100:
+ ldr r10, =24000000
+ cmp r0, r10
+ beq set_to_24MHz
+
+ ddr_switch_400MHz
+
+ ldr r10,=100000000
+ cmp r0, r10
+ blt done
+ mmdc_clk_above_100MHz
+
+ b done
+
+set_to_24MHz:
+ mx6sl_switch_to_24MHz
+
+done:
+ /* clear DVFS - exit from self refresh mode */
+ ldr r6, [r8, #0x404]
+ bic r6, r6, #0x200000
+ str r6, [r8, #0x404]
+
+poll_dvfs_clear_1:
+ ldr r6, [r8, #0x404]
+ and r6, r6, #0x2000000
+ cmp r6, #0x2000000
+ beq poll_dvfs_clear_1
+
+ /* Enable Automatic power savings. */
+ ldr r6, [r8, #0x404]
+ bic r6, r6, #0x01
+ str r6, [r8, #0x404]
+
+ ldr r10, =24000000
+ cmp r0, r10
+ beq skip_power_down
+
+ /* Enable MMDC power down timer. */
+ ldr r6, [r8, #0x4]
+ orr r6, r6, #0x5500
+ str r6, [r8, #0x4]
+
+skip_power_down:
+ /* clear SBS - unblock DDR accesses */
+ ldr r6, [r8, #0x410]
+ bic r6, r6, #0x100
+ str r6, [r8, #0x410]
+
+#ifdef CONFIG_CACHE_L2X0
+ ldr r7, =IMX_IO_P2V(MX6Q_L2_BASE_ADDR)
+ ldr r3, [r7, #PL310_AUX_CTRL]
+ tst r3, #PL310_AUX_16WAY_BIT
+ mov r6, #PL310_LOCKDOWN_NBREGS
+ mov r3, #0x00 /* 8 ways mask */
+ orrne r3, #0x0000 /* 16 ways mask */
+ add r5, r7, #PL310_DCACHE_LOCKDOWN_BASE
+1: /* lock Dcache and Icache */
+ str r3, [r5], #PL310_LOCKDOWN_SZREG
+ str r3, [r5], #PL310_LOCKDOWN_SZREG
+ subs r6, r6, #1
+ bne 1b
+#endif
+
+ /* Enable L1 data cache. */
+ mrc p15, 0, r6, c1, c0, 0
+ orr r6, r6, #0x4
+ mcr p15, 0, r6, c1, c0, 0
+
+ /* Restore the TTBCR */
+ dsb
+ isb
+
+ /* Read TTBCR and set PD0=0, N = 0 */
+ mrc p15, 0, r6, c2, c0, 2
+ bic r6, r6, #0x11
+ mcr p15, 0, r6, c2, c0, 2
+ dsb
+ isb
+
+ /* flush the TLB */
+ ldr r6, =0x0
+ mcr p15, 0, r6, c8, c3, 0
+
+ dsb
+ isb
+
+ /* Enable Branch Prediction, Z bit in SCTLR. */
+ mrc p15, 0, r6, c1, c0, 0
+ orr r6, r6, #0x800
+ mcr p15, 0, r6, c1, c0, 0
+
+ /* Flush the Branch Target Address Cache (BTAC) */
+ ldr r6, =0x0
+ mcr p15, 0, r6, c7, c1, 6
+
+ nop
+ nop
+ nop
+ nop
+ nop
+
+ nop
+ nop
+ nop
+ nop
+ nop
+
+ nop
+ nop
+ nop
+ nop
+ nop
+
+ nop
+ nop
+ nop
+ nop
+ nop
+
+ nop
+ nop
+ nop
+ nop
+ nop
+
+ pop {r4-r10}
+
+ /* Restore registers */
+ mov pc, lr
+
+ /*
+ * Add ltorg here to ensure that all
+ * literals are stored here and are
+ * within the text space.
+ */
+ .ltorg
+imx6_lpddr2_freq_change_end:
diff --git a/arch/arm/mach-imx/lpddr2_freq_imx6q.S b/arch/arm/mach-imx/lpddr2_freq_imx6q.S
new file mode 100644
index 000000000000..6c9aac07df16
--- /dev/null
+++ b/arch/arm/mach-imx/lpddr2_freq_imx6q.S
@@ -0,0 +1,765 @@
+/*
+ * Copyright (C) 2015-2016 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/linkage.h>
+#include <asm/smp_scu.h>
+#include "hardware.h"
+
+#define CCM_CBCDR 0x14
+#define CCM_CBCMR 0x18
+#define CCM_CSCMR1 0x1c
+#define CCM_CDHIPR 0x48
+
+.globl mx6q_lpddr2_freq_change_start
+.globl mx6q_lpddr2_freq_change_end
+
+ .macro wait_for_ccm_handshake
+ /* wait for div update */
+1:
+ ldr r9, [r2, #CCM_CDHIPR]
+ cmp r9, #0
+ bne 1b
+
+ .endm
+
+ .macro set_mmdc_misc_ralat_2_cycles
+
+ /* Set MMDCx_MISC[RALAT] = 2 cycles */
+ ldr r6, [r8, #0x18]
+ bic r6, r6, #(0x7 << 6)
+ orr r6, r6, #(0x2 << 6)
+ str r6, [r8, #0x18]
+
+ /* Check if lpddr2 channel 1 is enabled */
+ ldr r6, [r8, #0x18]
+ ands r6, r6, #(1 << 2)
+ beq 1f
+
+ ldr r6, [r4, #0x18]
+ bic r6, r6, #(0x7 << 6)
+ orr r6, r6, #(0x2 << 6)
+ str r6, [r4, #0x18]
+1:
+ .endm
+
+ .macro switch_to_400MHz
+ /* set the MMDC_DIV=1, AXI_DIV=2, AHB_DIV=3 */
+ ldr r9, [r2, #CCM_CBCDR]
+ ldr r6, =0x3f1f00
+ bic r9, r9, r6
+ orr r9, r9, #(0x9 << 8)
+ orr r9, r9, #(1 << 16)
+ str r9, [r2, #CCM_CBCDR]
+
+ wait_for_ccm_handshake
+
+ /* check periph_clk_sel */
+ ldr r9, [r2, #CCM_CBCDR]
+ and r9, r9, #(1 << 25)
+ cmp r9, #(1 << 25)
+ bne skip_periph_clk_switch_400m
+
+ /* now switch periph_clk back. */
+ ldr r9, [r2, #CCM_CBCDR]
+ bic r9, r9, #(1 << 25)
+ str r9, [r2, #CCM_CBCDR]
+
+ wait_for_ccm_handshake
+
+skip_periph_clk_switch_400m:
+
+ .endm
+
+ .macro switch_to_100MHz
+ /* set the MMDC_DIV=4, AXI_DIV=8, AHB_DIV=8 */
+ ldr r9, [r2, #CCM_CBCDR]
+ ldr r6, =0x3f1f00
+ bic r9, r9, r6
+ orr r9, r9, #(0x1F << 16)
+ orr r9, r9, #(0x1D << 8)
+ str r9, [r2, #CCM_CBCDR]
+
+ wait_for_ccm_handshake
+
+ /* check if periph_clk_sel is already set. */
+ ldr r9, [r2, #CCM_CBCDR]
+ and r9, r9, #(1 << 25)
+ cmp r9, #(1 << 25)
+ bne skip_periph_clk_switch_100m
+
+ /* now switch periph_clk back. */
+ ldr r9, [r2, #CCM_CBCDR]
+ bic r9, r9, #(1 << 25)
+ str r9, [r2, #CCM_CBCDR]
+
+ wait_for_ccm_handshake
+
+skip_periph_clk_switch_100m:
+
+ .endm
+
+ .macro switch_to_24MHz
+ /*
+ * change the freq now try setting DDR to 24MHz.
+ * source it from the periph_clk2 ensure the
+ * periph_clk2 is sourced from 24MHz and the
+ * divider is 1.
+ */
+
+ ldr r9, [r2, #CCM_CBCMR]
+ bic r9, r9, #(0x3 << 12)
+ orr r9, r9, #(1 << 12)
+ str r9, [r2, #CCM_CBCMR]
+
+ ldr r9, [r2, #CCM_CBCDR]
+ bic r9, r9, #(0x7 << 27)
+ str r9, [r2, #CCM_CBCDR]
+
+ /* now switch periph_clk to 24MHz. */
+ ldr r9, [r2, #CCM_CBCDR]
+ orr r9, r9, #(1 << 25)
+ str r9, [r2, #CCM_CBCDR]
+
+ wait_for_ccm_handshake
+
+ /* change all the dividers to 1. */
+ ldr r9, [r2, #CCM_CBCDR]
+ ldr r6, =0x3f1f00
+ bic r9, r9, r6
+ orr r9, r9, #(1 << 8)
+ str r9, [r2, #CCM_CBCDR]
+
+ /* Wait for the divider to change. */
+ wait_for_ccm_handshake
+
+ .endm
+
+ .macro switch_to_24MHZ_from_pll2
+ /* Change DDR freq settings from pll2_pfd2 (div 2) */
+
+ ldr r9, [r2, #CCM_CBCMR]
+ bic r9, r9, #(0x3 << 18)
+ orr r9, r9, #(0x3 << 18)
+ str r9, [r2, #CCM_CBCMR]
+
+ ldr r9, [r2, #CCM_CBCDR]
+ bic r9, r9, #(1 << 25)
+ str r9, [r2, #CCM_CBCDR]
+
+ wait_for_ccm_handshake
+
+ ldr r9, [r2, #CCM_CBCDR]
+ ldr r6, =0x3f1f00
+ bic r9, r9, r6
+ orr r9, r9, #(1 << 8)
+ orr r9, r9, #(0x7 << 19)
+ str r9, [r2, #CCM_CBCDR]
+
+ wait_for_ccm_handshake
+
+ .endm
+
+ .macro set_timings_below_100MHz_operation
+ set_mmdc_misc_ralat_2_cycles
+
+ /* Adjust LPDDR2 timings for 24Mhz operation */
+ ldr r5, =0x03162073
+ str r5, [r8, #0xC] /* MMDC0_MDCFG0 */
+ ldr r7, =0x00020482
+ str r7, [r8, #0x10] /* MMDC0_MDCFG1 */
+ ldr r9, =0x00000049
+ str r9, [r8, #0x14] /* MMDC0_MDCFG2 */
+ ldr r10, =0x00020333
+ str r10, [r8, #0x38] /* MMDC0_MDCFG3LP */
+
+ /* Check if lpddr2 channel 1 is enabled */
+ ldr r6, [r8, #0x18]
+ ands r6, r6, #(1 << 2)
+ beq skip_below_100Mhz_ch1_timings
+
+ str r5, [r4, #0xC] /* MMDC1_MDCFG0 */
+ str r7, [r4, #0x10] /* MMDC1_MDCFG1 */
+ str r9, [r4, #0x14] /* MMDC1_MDCFG2 */
+ str r10, [r4, #0x38] /* MMDC1_MDCFG3LP */
+
+skip_below_100Mhz_ch1_timings:
+
+ .endm
+
+ .macro restore_mmdc_settings_info
+ /* restore timing from mmdc_settings_info */
+ ldr r6, [r1, #0x0]
+ ldr r7, [r1, #0x4]
+1:
+ ldr r9, [r7], #0x4
+ ldr r10, [r7], #0x4
+ str r10, [r8, r9]
+ subs r6, r6, #0x1
+ bne 1b
+
+ /* Check if lpddr2 channel 1 is enabled */
+ ldr r6, [r8, #0x18]
+ ands r6, r6, #(1 << 2)
+ beq 3f
+
+ ldr r6, [r1, #0x0]
+ ldr r7, [r1, #0x4]
+2:
+ ldr r9, [r7], #0x4
+ ldr r10, [r7], #0x4
+ str r10, [r4, r9]
+ subs r6, r6, #0x1
+ bne 2b
+3:
+
+ .endm
+
+ .macro mmdc_clk_lower_equal_100MHz
+
+ ldr r10, =100000000
+ cmp r0, r10
+ beq set_timmings_100MHz
+ set_timings_below_100MHz_operation
+ b common_to_lower_equal_100MHz
+
+set_timmings_100MHz:
+ restore_mmdc_settings_info
+ set_mmdc_misc_ralat_2_cycles
+
+common_to_lower_equal_100MHz:
+
+ /* if MMDC is not in 400MHz mode, skip double mu count */
+ ldr r5, [r1, #0x8]
+ ldr r6, =400000000
+ cmp r5, r6
+ bne skip_lower_force_measure_ch1
+
+ /*
+ * Prior to reducing the DDR frequency (at 528/400 MHz),
+ * read the Measure unit count bits (MU_UNIT_DEL_NUM)
+ */
+ ldr r5, =0x8B8
+ ldr r6, [r8, r5]
+ /* Original MU unit count */
+ mov r6, r6, LSR #16
+ ldr r9, =0x3FF
+ and r6, r6, r9
+ /* Original MU unit count * 2 */
+ mov r7, r6, LSL #1
+ /*
+ * Bypass the automatic measure unit when below 100 MHz
+ * by setting the Measure unit bypass enable bit (MU_BYP_EN)
+ */
+ ldr r6, [r8, r5]
+ orr r6, r6, #0x400
+ str r6, [r8, r5]
+ /*
+ * Double the measure count value read in step 1 and program it in the
+ * measurement bypass bits (MU_BYP_VAL) of the MMDC PHY Measure Unit
+ * Register for the reduced frequency operation below 100 MHz
+ */
+ ldr r6, [r8, r5]
+ ldr r9, =0x3FF
+ bic r6, r6, r9
+ orr r6, r6, r7
+ str r6, [r8, r5]
+ /* Now perform a Force Measurement. */
+ ldr r6, [r8, r5]
+ orr r6, r6, #0x800
+ str r6, [r8, r5]
+ /* Wait for FRC_MSR to clear. */
+force_measure:
+ ldr r6, [r8, r5]
+ and r6, r6, #0x800
+ cmp r6, #0x0
+ bne force_measure
+
+ /* Check if lpddr2 channel 2 is enabled */
+ ldr r6, [r8, #0x18]
+ ands r6, r6, #(1 << 2)
+ beq skip_lower_force_measure_ch1
+
+ ldr r5, =0x8B8
+ ldr r6, [r4, r5]
+ /* Original MU unit count */
+ mov r6, r6, LSR #16
+ ldr r9, =0x3FF
+ and r6, r6, r9
+ /* Original MU unit count * 2 */
+ mov r7, r6, LSL #1
+ /*
+ * Bypass the automatic measure unit when below 100 MHz
+ * by setting the Measure unit bypass enable bit (MU_BYP_EN)
+ */
+ ldr r6, [r4, r5]
+ orr r6, r6, #0x400
+ str r6, [r4, r5]
+ /*
+ * Double the measure count value read in step 1 and program it in the
+ * measurement bypass bits (MU_BYP_VAL) of the MMDC PHY Measure Unit
+ * Register for the reduced frequency operation below 100 MHz
+ */
+ ldr r6, [r4, r5]
+ ldr r9, =0x3FF
+ bic r6, r6, r9
+ orr r6, r6, r7
+ str r6, [r4, r5]
+ /* Now perform a Force Measurement. */
+ ldr r6, [r4, r5]
+ orr r6, r6, #0x800
+ str r6, [r4, r5]
+ /* Wait for FRC_MSR to clear. */
+force_measure_ch1:
+ ldr r6, [r4, r5]
+ and r6, r6, #0x800
+ cmp r6, #0x0
+ bne force_measure_ch1
+
+skip_lower_force_measure_ch1:
+
+ .endm
+
+ .macro mmdc_clk_above_100MHz
+
+ restore_mmdc_settings_info
+
+ /* Make sure that the PHY measurement unit is NOT in bypass mode */
+ ldr r5, =0x8B8
+ ldr r6, [r8, r5]
+ bic r6, r6, #0x400
+ str r6, [r8, r5]
+ /* Now perform a Force Measurement. */
+ ldr r6, [r8, r5]
+ orr r6, r6, #0x800
+ str r6, [r8, r5]
+ /* Wait for FRC_MSR to clear. */
+force_measure1:
+ ldr r6, [r8, r5]
+ and r6, r6, #0x800
+ cmp r6, #0x0
+ bne force_measure1
+
+ /* Check if lpddr2 channel 2 is enabled */
+ ldr r6, [r8, #0x18]
+ ands r6, r6, #(1 << 2)
+ beq skip_above_force_measure_ch1
+
+ ldr r5, =0x8B8
+ ldr r6, [r4, r5]
+ bic r6, r6, #0x400
+ str r6, [r4, r5]
+ /* Now perform a Force Measurement. */
+ ldr r6, [r4, r5]
+ orr r6, r6, #0x800
+ str r6, [r4, r5]
+ /* Wait for FRC_MSR to clear. */
+force_measure1_ch1:
+ ldr r6, [r4, r5]
+ and r6, r6, #0x800
+ cmp r6, #0x0
+ bne force_measure1_ch1
+
+skip_above_force_measure_ch1:
+
+ .endm
+
+ .macro disable_l1_dcache
+
+ /*
+ * Flush all data from the L1 data cache before disabling
+ * SCTLR.C bit.
+ */
+ push {r0 - r11, lr}
+
+ ldr r7, =v7_flush_kern_cache_all
+ mov lr, pc
+ mov pc, r7
+ pop {r0 - r11, lr}
+
+ /* disable d-cache */
+ mrc p15, 0, r6, c1, c0, 0
+ bic r6, r6, #0x4
+ mcr p15, 0, r6, c1, c0, 0
+ dsb
+ isb
+
+ push {r0 - r11, lr}
+
+ ldr r7, =v7_flush_kern_cache_all
+ mov lr, pc
+ mov pc, r7
+ pop {r0 - r11, lr}
+
+ .endm
+
+/*
+ * mx6_lpddr2_freq_change
+ *
+ * Make sure DDR is in self-refresh.
+ * IRQs are already disabled.
+ * r0 : DDR freq.
+ * r1 : mmdc_settings_info
+ */
+ .align 3
+ENTRY(mx6q_lpddr2_freq_change)
+mx6q_lpddr2_freq_change_start:
+ push {r2-r10}
+
+ /*
+ * Need to flush and disable L1 before
+ * disabling L2, we need data to
+ * coherent. Flushing L1 pushes
+ * everyhting to L2. We sync L2 later, but
+ * it can still have dirty lines.
+ * While exiting, we need to enable L2 first
+ * and then L1.
+ */
+ disable_l1_dcache
+
+ /*
+ * To ensure no page table walks occur in DDR, we
+ * have a another page table stored in IRAM that only
+ * contains entries pointing to IRAM, AIPS1 and AIPS2.
+ * We need to set the TTBR1 to the new IRAM TLB.
+ * Do the following steps:
+ * 1. Flush the Branch Target Address Cache (BTAC)
+ * 2. Set TTBR1 to point to IRAM page table.
+ * 3. Disable page table walks in TTBR0 (PD0 = 1)
+ * 4. Set TTBR0.N=1, implying 0-2G is translated by TTBR0
+ * and 2-4G is translated by TTBR1.
+ */
+
+ ldr r6, =iram_tlb_phys_addr
+ ldr r7, [r6]
+
+ /* Flush the Branch Target Address Cache (BTAC) */
+ ldr r6, =0x0
+ mcr p15, 0, r6, c7, c1, 6
+
+ /* Disable Branch Prediction, Z bit in SCTLR. */
+ mrc p15, 0, r6, c1, c0, 0
+ bic r6, r6, #0x800
+ mcr p15, 0, r6, c1, c0, 0
+
+ dsb
+ isb
+ /* Store the IRAM table in TTBR1 */
+ mcr p15, 0, r7, c2, c0, 1
+
+ /* Read TTBCR and set PD0=1, N = 1 */
+ mrc p15, 0, r6, c2, c0, 2
+ orr r6, r6, #0x11
+ mcr p15, 0, r6, c2, c0, 2
+
+ dsb
+ isb
+
+ /* flush the TLB */
+ ldr r6, =0x0
+ mcr p15, 0, r6, c8, c3, 0
+
+#ifdef CONFIG_CACHE_L2X0
+ /*
+ * Need to make sure the buffers in L2 are drained.
+ * Performing a sync operation does this.
+ */
+ ldr r7, =IMX_IO_P2V(MX6Q_L2_BASE_ADDR)
+
+ /* Wait for background operations to complete. */
+wait_for_l2_to_idle:
+ ldr r6, [r7, #0x730]
+ cmp r6, #0x0
+ bne wait_for_l2_to_idle
+
+ mov r6, #0x0
+ str r6, [r7, #0x730]
+
+ /*
+ * The second dsb might be needed to keep cache sync (device write)
+ * ordering with the memory accesses before it.
+ */
+ dsb
+ isb
+
+ /* Disable L2. */
+ str r6, [r7, #0x100]
+#endif
+
+ ldr r3, =IMX_IO_P2V(MX6Q_ANATOP_BASE_ADDR)
+ ldr r2, =IMX_IO_P2V(MX6Q_CCM_BASE_ADDR)
+ ldr r8, =IMX_IO_P2V(MX6Q_MMDC_P0_BASE_ADDR)
+ ldr r4, =IMX_IO_P2V(MX6Q_MMDC_P1_BASE_ADDR)
+
+ /* Disable Automatic power savings. */
+ ldr r6, [r8, #0x404]
+ orr r6, r6, #0x01
+ str r6, [r8, #0x404]
+
+ /* MMDC0_MDPDC disable power down timer */
+ ldr r6, [r8, #0x4]
+ bic r6, r6, #0xff00
+ str r6, [r8, #0x4]
+
+ /* Check if lpddr2 channel 2 is enabled */
+ ldr r6, [r8, #0x18]
+ ands r6, r6, #(1 << 2)
+ beq skip_psd_ch1
+
+ ldr r6, [r4, #0x404]
+ orr r6, r6, #0x01
+ str r6, [r4, #0x404]
+
+ ldr r6, [r4, #0x4]
+ bic r6, r6, #0xff00
+ str r6, [r4, #0x4]
+
+skip_psd_ch1:
+ /* Delay for a while */
+ ldr r10, =10
+delay1:
+ ldr r7, =0
+cont1:
+ ldr r6, [r8, r7]
+ add r7, r7, #4
+ cmp r7, #16
+ bne cont1
+ sub r10, r10, #1
+ cmp r10, #0
+ bgt delay1
+
+ /* Make the DDR explicitly enter self-refresh. */
+ ldr r6, [r8, #0x404]
+ orr r6, r6, #0x200000
+ str r6, [r8, #0x404]
+
+poll_dvfs_set_1:
+ ldr r6, [r8, #0x404]
+ and r6, r6, #0x2000000
+ cmp r6, #0x2000000
+ bne poll_dvfs_set_1
+
+ /* set SBS step-by-step mode */
+ ldr r6, [r8, #0x410]
+ orr r6, r6, #0x100
+ str r6, [r8, #0x410]
+
+ /* Check if lpddr2 channel 2 is enabled */
+ ldr r6, [r8, #0x18]
+ ands r6, r6, #(1 << 2)
+ beq skip_sbs_ch1
+
+ ldr r6, [r4, #0x404]
+ orr r6, r6, #0x200000
+ str r6, [r4, #0x404]
+
+poll_dvfs_set_2:
+ ldr r6, [r4, #0x404]
+ and r6, r6, #0x2000000
+ cmp r6, #0x2000000
+ bne poll_dvfs_set_2
+
+ ldr r6, [r4, #0x410]
+ orr r6, r6, #0x100
+ str r6, [r4, #0x410]
+
+skip_sbs_ch1:
+ ldr r10, =100000000
+ cmp r0, r10
+ bgt set_ddr_mu_above_100
+ mmdc_clk_lower_equal_100MHz
+
+set_ddr_mu_above_100:
+ ldr r10, =24000000
+ cmp r0, r10
+ beq set_to_24MHz
+
+ ldr r10, =100000000
+ cmp r0, r10
+ beq set_to_100MHz
+
+ ldr r10, =400000000
+ cmp r0, r10
+ switch_to_400MHz
+ b done
+
+set_to_24MHz:
+/*
+ switch_to_24MHZ_from_pll2
+*/
+ switch_to_24MHz
+ b done
+
+set_to_100MHz:
+ switch_to_100MHz
+
+done:
+
+ ldr r10,=100000000
+ cmp r0, r10
+ ble skip_mmdc_clk_check
+ mmdc_clk_above_100MHz
+
+skip_mmdc_clk_check:
+
+ /* clear DVFS - exit from self refresh mode */
+ ldr r6, [r8, #0x404]
+ bic r6, r6, #0x200000
+ str r6, [r8, #0x404]
+
+poll_dvfs_clear_1:
+ ldr r6, [r8, #0x404]
+ and r6, r6, #0x2000000
+ cmp r6, #0x2000000
+ beq poll_dvfs_clear_1
+
+ /* Enable Automatic power savings. */
+ ldr r6, [r8, #0x404]
+ bic r6, r6, #0x01
+ str r6, [r8, #0x404]
+
+ /* Check if lpddr2 channel 2 is enabled */
+ ldr r6, [r8, #0x18]
+ ands r6, r6, #(1 << 2)
+ beq skip_enable_psd_ch1
+
+ ldr r6, [r4, #0x404]
+ bic r6, r6, #0x200000
+ str r6, [r4, #0x404]
+
+poll_dvfs_clear_2:
+ ldr r6, [r4, #0x404]
+ and r6, r6, #0x2000000
+ cmp r6, #0x2000000
+ beq poll_dvfs_clear_2
+
+ ldr r6, [r4, #0x404]
+ bic r6, r6, #0x01
+ str r6, [r4, #0x404]
+
+skip_enable_psd_ch1:
+ ldr r10, =24000000
+ cmp r0, r10
+ beq skip_power_down
+
+ /* Enable MMDC power down timer. */
+ ldr r6, [r8, #0x4]
+ orr r6, r6, #0x5500
+ str r6, [r8, #0x4]
+
+ /* Check if lpddr2 channel 2 is enabled */
+ ldr r6, [r8, #0x18]
+ ands r6, r6, #(1 << 2)
+ beq skip_power_down
+
+ ldr r6, [r4, #0x4]
+ orr r6, r6, #0x5500
+ str r6, [r4, #0x4]
+
+skip_power_down:
+ /* clear SBS - unblock DDR accesses */
+ ldr r6, [r8, #0x410]
+ bic r6, r6, #0x100
+ str r6, [r8, #0x410]
+
+ /* Check if lpddr2 channel 2 is enabled */
+ ldr r6, [r8, #0x18]
+ ands r6, r6, #(1 << 2)
+ beq skip_disable_sbs_ch1
+
+ ldr r6, [r4, #0x410]
+ bic r6, r6, #0x100
+ str r6, [r4, #0x410]
+
+skip_disable_sbs_ch1:
+#ifdef CONFIG_CACHE_L2X0
+ /* Enable L2. */
+ ldr r7, =IMX_IO_P2V(MX6Q_L2_BASE_ADDR)
+ ldr r6, =0x1
+ str r6, [r7, #0x100]
+#endif
+
+ /* Enable L1 data cache. */
+ mrc p15, 0, r6, c1, c0, 0
+ orr r6, r6, #0x4
+ mcr p15, 0, r6, c1, c0, 0
+
+ /* Restore the TTBCR */
+ dsb
+ isb
+
+ /* Read TTBCR and set PD0=0, N = 0 */
+ mrc p15, 0, r6, c2, c0, 2
+ bic r6, r6, #0x11
+ mcr p15, 0, r6, c2, c0, 2
+ dsb
+ isb
+
+ /* flush the TLB */
+ ldr r6, =0x0
+ mcr p15, 0, r6, c8, c3, 0
+
+ dsb
+ isb
+
+ /* Enable Branch Prediction, Z bit in SCTLR. */
+ mrc p15, 0, r6, c1, c0, 0
+ orr r6, r6, #0x800
+ mcr p15, 0, r6, c1, c0, 0
+
+ /* Flush the Branch Target Address Cache (BTAC) */
+ ldr r6, =0x0
+ mcr p15, 0, r6, c7, c1, 6
+
+ nop
+ nop
+ nop
+ nop
+ nop
+
+ nop
+ nop
+ nop
+ nop
+ nop
+
+ nop
+ nop
+ nop
+ nop
+ nop
+
+ nop
+ nop
+ nop
+ nop
+ nop
+
+ nop
+ nop
+ nop
+ nop
+ nop
+
+ pop {r2-r10}
+
+ /* Restore registers */
+ mov pc, lr
+
+ /*
+ * Add ltorg here to ensure that all
+ * literals are stored here and are
+ * within the text space.
+ */
+ .ltorg
+mx6q_lpddr2_freq_change_end:
diff --git a/arch/arm/mach-imx/lpddr2_freq_imx6sll.S b/arch/arm/mach-imx/lpddr2_freq_imx6sll.S
new file mode 100644
index 000000000000..c67d9e2b82ef
--- /dev/null
+++ b/arch/arm/mach-imx/lpddr2_freq_imx6sll.S
@@ -0,0 +1,460 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/linkage.h>
+#include "hardware.h"
+
+#define CCM_CBCDR 0x14
+#define CCM_CBCMR 0x18
+#define CCM_CSCMR1 0x1c
+#define CCM_CDHIPR 0x48
+
+#define L2_CACHE_SYNC 0x730
+#define PL310_AUX_CTRL 0x104
+#define PL310_DCACHE_LOCKDOWN_BASE 0x900
+#define PL310_AUX_16WAY_BIT 0x10000
+#define PL310_LOCKDOWN_NBREGS 8
+#define PL310_LOCKDOWN_SZREG 4
+#define PL310_8WAYS_MASK 0x00FF
+#define PL310_16WAYS_UPPERMASK 0xFF00
+
+#define MMDC0_MDPDC 0x4
+#define MMDC0_MAPSR 0x404
+#define MMDC0_MADPCR0 0x410
+
+#define HIGH_BUS_MODE 0x0
+
+ .macro wait_for_ccm_handshake
+
+1:
+ ldr r8, [r2, #CCM_CDHIPR]
+ cmp r8, #0
+ bne 1b
+
+ .endm
+
+ .macro switch_to_24MHz
+
+ /* periph2_clk2 sel to OSC_CLK */
+ ldr r8, [r2, #CCM_CBCMR]
+ orr r8, r8, #(1 << 20)
+ str r8, [r2, #CCM_CBCMR]
+
+ /* periph2_clk2_podf to 0 */
+ ldr r8, [r2, #CCM_CBCDR]
+ bic r8, r8, #0x7
+ str r8, [r2, #CCM_CBCDR]
+
+ /* periph2_clk sel to periph2_clk2 */
+ ldr r8, [r2, #CCM_CBCDR]
+ orr r8, r8, #(0x1 << 26)
+ str r8, [r2, #CCM_CBCDR]
+
+ wait_for_ccm_handshake
+
+ /* fabric_mmdc_podf to 0 */
+ ldr r8, [r2, #CCM_CBCDR]
+ bic r8, r8, #(0x7 << 3)
+ str r8, [r2, #CCM_CBCDR]
+
+ wait_for_ccm_handshake
+
+ .endm
+
+ .macro switch_to_100MHz
+
+ /* check whether periph2_clk is from top path */
+ ldr r8, [r2, #CCM_CBCDR]
+ ands r8, #(1 << 26)
+ beq skip_periph2_clk2_switch_100m
+
+ /* now switch periph2_clk back. */
+ ldr r8, [r2, #CCM_CBCDR]
+ bic r8, r8, #(1 << 26)
+ str r8, [r2, #CCM_CBCDR]
+
+ wait_for_ccm_handshake
+
+ /*
+ * on i.MX6SLL, pre_periph2_clk will be always from
+ * pll2_pfd2, so no need to set pre_periph2_clk
+ * parent, just set the mmdc divider directly.
+ */
+skip_periph2_clk2_switch_100m:
+
+ /* fabric_mmdc_podf to 3 so that mmdc is 400 / 4 = 100MHz */
+ ldr r8, [r2, #CCM_CBCDR]
+ bic r8, r8, #(0x7 << 3)
+ orr r8, r8, #(0x3 << 3)
+ str r8, [r2, #CCM_CBCDR]
+
+ wait_for_ccm_handshake
+
+ .endm
+
+ .macro switch_to_400MHz
+
+ /* check whether periph2_clk is from top path */
+ ldr r8, [r2, #CCM_CBCDR]
+ ands r8, #(1 << 26)
+ beq skip_periph2_clk2_switch_400m
+
+ /* now switch periph2_clk back. */
+ ldr r8, [r2, #CCM_CBCDR]
+ bic r8, r8, #(1 << 26)
+ str r8, [r2, #CCM_CBCDR]
+
+ wait_for_ccm_handshake
+
+ /*
+ * on i.MX6SLL, pre_periph2_clk will be always from
+ * pll2_pfd2, so no need to set pre_periph2_clk
+ * parent, just set the mmdc divider directly.
+ */
+skip_periph2_clk2_switch_400m:
+
+ /* fabric_mmdc_podf to 0 */
+ ldr r8, [r2, #CCM_CBCDR]
+ bic r8, r8, #(0x7 << 3)
+ str r8, [r2, #CCM_CBCDR]
+
+ wait_for_ccm_handshake
+
+ .endm
+
+ .macro mmdc_clk_lower_100MHz
+ /* if MMDC is not in 400MHz mode, skip double mu count */
+ cmp r1, #HIGH_BUS_MODE
+ bne 1f
+
+ /*
+ * Prior to reducing the DDR frequency (at 528/400 MHz),
+ * read the Measure unit count bits (MU_UNIT_DEL_NUM)
+ */
+ ldr r8, =0x8B8
+ ldr r6, [r5, r8]
+ /* Original MU unit count */
+ mov r6, r6, LSR #16
+ ldr r4, =0x3FF
+ and r6, r6, r4
+ /* Original MU unit count * 2 */
+ mov r7, r6, LSL #1
+ /*
+ * Bypass the automatic measure unit when below 100 MHz
+ * by setting the Measure unit bypass enable bit (MU_BYP_EN)
+ */
+ ldr r6, [r5, r8]
+ orr r6, r6, #0x400
+ str r6, [r5, r8]
+ /*
+ * Double the measure count value read in step 1 and program it in the
+ * measurement bypass bits (MU_BYP_VAL) of the MMDC PHY Measure Unit
+ * Register for the reduced frequency operation below 100 MHz
+ */
+ ldr r6, [r5, r8]
+ ldr r4, =0x3FF
+ bic r6, r6, r4
+ orr r6, r6, r7
+ str r6, [r5, r8]
+
+ /* For freq lower than 100MHz, need to set RALAT to 2 */
+ ldr r6, [r5, #0x18]
+ bic r6, r6, #(0x7 << 6)
+ orr r6, r6, #(0x2 << 6)
+ str r6, [r5, #0x18]
+1:
+ .endm
+
+ .macro mmdc_clk_above_100MHz
+
+ /* Make sure that the PHY measurement unit is NOT in bypass mode */
+ ldr r8, =0x8B8
+ ldr r6, [r5, r8]
+ bic r6, r6, #0x400
+ str r6, [r5, r8]
+ /* Now perform a Force Measurement. */
+ ldr r6, [r5, r8]
+ orr r6, r6, #0x800
+ str r6, [r5, r8]
+ /* Wait for FRC_MSR to clear. */
+force_measure1:
+ ldr r6, [r5, r8]
+ and r6, r6, #0x800
+ cmp r6, #0x0
+ bne force_measure1
+
+ /* For freq higher than 100MHz, need to set RALAT to 5 */
+ ldr r6, [r5, #0x18]
+ bic r6, r6, #(0x7 << 6)
+ orr r6, r6, #(0x5 << 6)
+ str r6, [r5, #0x18]
+
+ .endm
+
+ .align 3
+/*
+ * Below code can be used by i.MX6SLL when changing the
+ * frequency of MMDC. the MMDC is the same on these two SOCs.
+ */
+ENTRY(imx6sll_lpddr2_freq_change)
+ push {r2 - r8}
+
+ /*
+ * To ensure no page table walks occur in DDR, we
+ * have a another page table stored in IRAM that only
+ * contains entries pointing to IRAM, AIPS1 and AIPS2.
+ * We need to set the TTBR1 to the new IRAM TLB.
+ * Do the following steps:
+ * 1. Flush the Branch Target Address Cache (BTAC)
+ * 2. Set TTBR1 to point to IRAM page table.
+ * 3. Disable page table walks in TTBR0 (PD0 = 1)
+ * 4. Set TTBR0.N=1, implying 0-2G is translated by TTBR0
+ * and 2-4G is translated by TTBR1.
+ */
+
+ ldr r6, =iram_tlb_phys_addr
+ ldr r7, [r6]
+
+ /* Flush the Branch Target Address Cache (BTAC) */
+ ldr r6, =0x0
+ mcr p15, 0, r6, c7, c1, 6
+
+ /* Disable Branch Prediction, Z bit in SCTLR. */
+ mrc p15, 0, r6, c1, c0, 0
+ bic r6, r6, #0x800
+ mcr p15, 0, r6, c1, c0, 0
+
+ dsb
+ isb
+ /* Store the IRAM table in TTBR1 */
+ mcr p15, 0, r7, c2, c0, 1
+
+ /* Read TTBCR and set PD0=1, N = 1 */
+ mrc p15, 0, r6, c2, c0, 2
+ orr r6, r6, #0x11
+ mcr p15, 0, r6, c2, c0, 2
+
+ dsb
+ isb
+
+ /* flush the TLB */
+ ldr r6, =0x0
+ mcr p15, 0, r6, c8, c3, 0
+
+ /* Disable L1 data cache. */
+ mrc p15, 0, r6, c1, c0, 0
+ bic r6, r6, #0x4
+ mcr p15, 0, r6, c1, c0, 0
+
+ dsb
+ isb
+
+#ifdef CONFIG_CACHE_L2X0
+ /*
+ * Need to make sure the buffers in L2 are drained.
+ * Performing a sync operation does this.
+ */
+ ldr r7, =IMX_IO_P2V(MX6Q_L2_BASE_ADDR)
+ mov r6, #0x0
+ str r6, [r7, #L2_CACHE_SYNC]
+
+ /*
+ * The second dsb might be needed to keep cache sync (device write)
+ * ordering with the memory accesses before it.
+ */
+ dsb
+ isb
+
+ ldr r3, [r7, #PL310_AUX_CTRL]
+ tst r3, #PL310_AUX_16WAY_BIT
+ mov r3, #PL310_8WAYS_MASK
+ orrne r3, #PL310_16WAYS_UPPERMASK
+ mov r6, #PL310_LOCKDOWN_NBREGS
+ add r5, r7, #PL310_DCACHE_LOCKDOWN_BASE
+1: /* lock Dcache and Icache */
+ str r3, [r5], #PL310_LOCKDOWN_SZREG
+ str r3, [r5], #PL310_LOCKDOWN_SZREG
+ subs r6, r6, #1
+ bne 1b
+#endif
+
+ ldr r2, =IMX_IO_P2V(MX6Q_CCM_BASE_ADDR)
+ ldr r3, =IMX_IO_P2V(MX6Q_ANATOP_BASE_ADDR)
+ ldr r5, =IMX_IO_P2V(MX6Q_MMDC_P0_BASE_ADDR)
+
+ /* Disable Automatic power savings. */
+ ldr r6, [r5, #MMDC0_MAPSR]
+ orr r6, r6, #0x1
+ str r6, [r5, #MMDC0_MAPSR]
+
+ /* Delay for a while */
+ ldr r8, =10
+delay:
+ ldr r7, =0
+cont:
+ ldr r6, [r5, r7]
+ add r7, r7, #4
+ cmp r7, #16
+ bne cont
+ sub r8, r8, #1
+ cmp r8, #0
+ bgt delay
+
+ /* Make the DDR explicitly enter self-refresh. */
+ ldr r6, [r5, #MMDC0_MAPSR]
+ orr r6, r6, #0x200000
+ str r6, [r5, #MMDC0_MAPSR]
+
+poll_dvfs_set_1:
+ ldr r6, [r5, #MMDC0_MAPSR]
+ and r6, r6, #0x2000000
+ cmp r6, #0x2000000
+ bne poll_dvfs_set_1
+
+ /* set SBS step-by-step mode */
+ ldr r6, [r5, #MMDC0_MADPCR0]
+ orr r6, r6, #0x100
+ str r6, [r5, #MMDC0_MADPCR0]
+
+ ldr r6, =100000000
+ cmp r0, r6
+ bgt set_ddr_mu_above_100
+ mmdc_clk_lower_100MHz
+
+set_ddr_mu_above_100:
+ ldr r6, =24000000
+ cmp r0, r6
+ beq set_to_24MHz
+
+ ldr r6, =100000000
+ cmp r0, r6
+ beq set_to_100MHz
+
+ switch_to_400MHz
+
+ mmdc_clk_above_100MHz
+
+ b done
+
+set_to_24MHz:
+ switch_to_24MHz
+ b done
+set_to_100MHz:
+ switch_to_100MHz
+done:
+ /* clear DVFS - exit from self refresh mode */
+ ldr r6, [r5, #MMDC0_MAPSR]
+ bic r6, r6, #0x200000
+ str r6, [r5, #MMDC0_MAPSR]
+
+poll_dvfs_clear_1:
+ ldr r6, [r5, #MMDC0_MAPSR]
+ and r6, r6, #0x2000000
+ cmp r6, #0x2000000
+ beq poll_dvfs_clear_1
+
+ /* Enable Automatic power savings. */
+ ldr r6, [r5, #MMDC0_MAPSR]
+ bic r6, r6, #0x1
+ str r6, [r5, #MMDC0_MAPSR]
+
+ /* clear SBS - unblock DDR accesses */
+ ldr r6, [r5, #MMDC0_MADPCR0]
+ bic r6, r6, #0x100
+ str r6, [r5, #MMDC0_MADPCR0]
+
+ ldr r6, =0xa0000000
+ str r6, [r5, #0x83c]
+
+
+#ifdef CONFIG_CACHE_L2X0
+ ldr r7, =IMX_IO_P2V(MX6Q_L2_BASE_ADDR)
+ ldr r3, [r7, #PL310_AUX_CTRL]
+ tst r3, #PL310_AUX_16WAY_BIT
+ mov r6, #PL310_LOCKDOWN_NBREGS
+ mov r3, #0x00 /* 8 ways mask */
+ orrne r3, #0x0000 /* 16 ways mask */
+ add r5, r7, #PL310_DCACHE_LOCKDOWN_BASE
+1: /* lock Dcache and Icache */
+ str r3, [r5], #PL310_LOCKDOWN_SZREG
+ str r3, [r5], #PL310_LOCKDOWN_SZREG
+ subs r6, r6, #1
+ bne 1b
+#endif
+
+ /* Enable L1 data cache. */
+ mrc p15, 0, r6, c1, c0, 0
+ orr r6, r6, #0x4
+ mcr p15, 0, r6, c1, c0, 0
+
+ /* Restore the TTBCR */
+ dsb
+ isb
+
+ /* Read TTBCR and set PD0=0, N = 0 */
+ mrc p15, 0, r6, c2, c0, 2
+ bic r6, r6, #0x11
+ mcr p15, 0, r6, c2, c0, 2
+ dsb
+ isb
+
+ /* flush the TLB */
+ ldr r6, =0x0
+ mcr p15, 0, r6, c8, c3, 0
+
+ dsb
+ isb
+
+ /* Enable Branch Prediction, Z bit in SCTLR. */
+ mrc p15, 0, r6, c1, c0, 0
+ orr r6, r6, #0x800
+ mcr p15, 0, r6, c1, c0, 0
+
+ /* Flush the Branch Target Address Cache (BTAC) */
+ ldr r6, =0x0
+ mcr p15, 0, r6, c7, c1, 6
+
+ nop
+ nop
+ nop
+ nop
+ nop
+
+ nop
+ nop
+ nop
+ nop
+ nop
+
+ nop
+ nop
+ nop
+ nop
+ nop
+
+ nop
+ nop
+ nop
+ nop
+ nop
+
+ nop
+ nop
+ nop
+ nop
+ nop
+
+ /* Restore registers */
+ pop {r2 - r8}
+ mov pc, lr
diff --git a/arch/arm/mach-imx/lpddr2_freq_imx6sx.S b/arch/arm/mach-imx/lpddr2_freq_imx6sx.S
new file mode 100644
index 000000000000..ba3488cad9d4
--- /dev/null
+++ b/arch/arm/mach-imx/lpddr2_freq_imx6sx.S
@@ -0,0 +1,492 @@
+/*
+ * Copyright (C) 2014-2016 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/linkage.h>
+#include "hardware.h"
+
+#define CCM_CBCDR 0x14
+#define CCM_CBCMR 0x18
+#define CCM_CSCMR1 0x1c
+#define CCM_CDHIPR 0x48
+
+#define L2_CACHE_SYNC 0x730
+#define PL310_AUX_CTRL 0x104
+#define PL310_DCACHE_LOCKDOWN_BASE 0x900
+#define PL310_AUX_16WAY_BIT 0x10000
+#define PL310_LOCKDOWN_NBREGS 8
+#define PL310_LOCKDOWN_SZREG 4
+#define PL310_8WAYS_MASK 0x00FF
+#define PL310_16WAYS_UPPERMASK 0xFF00
+
+#define MMDC0_MDPDC 0x4
+#define MMDC0_MAPSR 0x404
+#define MMDC0_MADPCR0 0x410
+
+#define HIGH_BUS_MODE 0x0
+
+ /* Check if the cpu is cortex-a7 */
+ .macro is_ca7
+
+ /* Read the primary cpu number is MPIDR */
+ mrc p15, 0, r6, c0, c0, 0
+ ldr r7, =0xfff0
+ and r6, r6, r7
+ ldr r7, =0xc070
+ cmp r6, r7
+
+ .endm
+
+ .macro wait_for_ccm_handshake
+
+1:
+ ldr r8, [r2, #CCM_CDHIPR]
+ cmp r8, #0
+ bne 1b
+
+ .endm
+
+ .macro switch_to_24MHz
+
+ /* periph2_clk2 sel to OSC_CLK */
+ ldr r8, [r2, #CCM_CBCMR]
+ orr r8, r8, #(1 << 20)
+ str r8, [r2, #CCM_CBCMR]
+
+ /* periph2_clk2_podf to 0 */
+ ldr r8, [r2, #CCM_CBCDR]
+ bic r8, r8, #0x7
+ str r8, [r2, #CCM_CBCDR]
+
+ /* periph2_clk sel to periph2_clk2 */
+ ldr r8, [r2, #CCM_CBCDR]
+ orr r8, r8, #(0x1 << 26)
+ str r8, [r2, #CCM_CBCDR]
+
+ wait_for_ccm_handshake
+
+ /* fabric_mmdc_podf to 0 */
+ ldr r8, [r2, #CCM_CBCDR]
+ bic r8, r8, #(0x7 << 3)
+ str r8, [r2, #CCM_CBCDR]
+
+ wait_for_ccm_handshake
+
+ .endm
+
+ .macro switch_to_100MHz
+
+ /* check whether periph2_clk is from top path */
+ ldr r8, [r2, #CCM_CBCDR]
+ ands r8, #(1 << 26)
+ beq skip_periph2_clk2_switch_100m
+
+ /* now switch periph2_clk back. */
+ ldr r8, [r2, #CCM_CBCDR]
+ bic r8, r8, #(1 << 26)
+ str r8, [r2, #CCM_CBCDR]
+
+ wait_for_ccm_handshake
+
+ /*
+ * on i.MX6SX, pre_periph2_clk will be always from
+ * pll2_pfd2, so no need to set pre_periph2_clk
+ * parent, just set the mmdc divider directly.
+ */
+skip_periph2_clk2_switch_100m:
+
+ /* fabric_mmdc_podf to 3 so that mmdc is 400 / 4 = 100MHz */
+ ldr r8, [r2, #CCM_CBCDR]
+ bic r8, r8, #(0x7 << 3)
+ orr r8, r8, #(0x3 << 3)
+ str r8, [r2, #CCM_CBCDR]
+
+ wait_for_ccm_handshake
+
+ .endm
+
+ .macro switch_to_400MHz
+
+ /* check whether periph2_clk is from top path */
+ ldr r8, [r2, #CCM_CBCDR]
+ ands r8, #(1 << 26)
+ beq skip_periph2_clk2_switch_400m
+
+ /* now switch periph2_clk back. */
+ ldr r8, [r2, #CCM_CBCDR]
+ bic r8, r8, #(1 << 26)
+ str r8, [r2, #CCM_CBCDR]
+
+ wait_for_ccm_handshake
+
+ /*
+ * on i.MX6SX, pre_periph2_clk will be always from
+ * pll2_pfd2, so no need to set pre_periph2_clk
+ * parent, just set the mmdc divider directly.
+ */
+skip_periph2_clk2_switch_400m:
+
+ /* fabric_mmdc_podf to 0 */
+ ldr r8, [r2, #CCM_CBCDR]
+ bic r8, r8, #(0x7 << 3)
+ str r8, [r2, #CCM_CBCDR]
+
+ wait_for_ccm_handshake
+
+ .endm
+
+ .macro mmdc_clk_lower_100MHz
+ /* if MMDC is not in 400MHz mode, skip double mu count */
+ cmp r1, #HIGH_BUS_MODE
+ bne 1f
+
+ /*
+ * Prior to reducing the DDR frequency (at 528/400 MHz),
+ * read the Measure unit count bits (MU_UNIT_DEL_NUM)
+ */
+ ldr r8, =0x8B8
+ ldr r6, [r5, r8]
+ /* Original MU unit count */
+ mov r6, r6, LSR #16
+ ldr r4, =0x3FF
+ and r6, r6, r4
+ /* Original MU unit count * 2 */
+ mov r7, r6, LSL #1
+ /*
+ * Bypass the automatic measure unit when below 100 MHz
+ * by setting the Measure unit bypass enable bit (MU_BYP_EN)
+ */
+ ldr r6, [r5, r8]
+ orr r6, r6, #0x400
+ str r6, [r5, r8]
+ /*
+ * Double the measure count value read in step 1 and program it in the
+ * measurement bypass bits (MU_BYP_VAL) of the MMDC PHY Measure Unit
+ * Register for the reduced frequency operation below 100 MHz
+ */
+ ldr r6, [r5, r8]
+ ldr r4, =0x3FF
+ bic r6, r6, r4
+ orr r6, r6, r7
+ str r6, [r5, r8]
+
+ /* For freq lower than 100MHz, need to set RALAT to 2 */
+ ldr r6, [r5, #0x18]
+ bic r6, r6, #(0x7 << 6)
+ orr r6, r6, #(0x2 << 6)
+ str r6, [r5, #0x18]
+1:
+ .endm
+
+ .macro mmdc_clk_above_100MHz
+
+ /* Make sure that the PHY measurement unit is NOT in bypass mode */
+ ldr r8, =0x8B8
+ ldr r6, [r5, r8]
+ bic r6, r6, #0x400
+ str r6, [r5, r8]
+ /* Now perform a Force Measurement. */
+ ldr r6, [r5, r8]
+ orr r6, r6, #0x800
+ str r6, [r5, r8]
+ /* Wait for FRC_MSR to clear. */
+force_measure1:
+ ldr r6, [r5, r8]
+ and r6, r6, #0x800
+ cmp r6, #0x0
+ bne force_measure1
+
+ /* For freq higher than 100MHz, need to set RALAT to 5 */
+ ldr r6, [r5, #0x18]
+ bic r6, r6, #(0x7 << 6)
+ orr r6, r6, #(0x5 << 6)
+ str r6, [r5, #0x18]
+
+ .endm
+
+ .align 3
+/*
+ * Below code can be used by i.MX6SX and i.MX6UL when changing the
+ * frequency of MMDC. the MMDC is the same on these two SOCs.
+ */
+ENTRY(imx6_up_lpddr2_freq_change)
+
+ push {r2 - r8}
+
+ /*
+ * To ensure no page table walks occur in DDR, we
+ * have a another page table stored in IRAM that only
+ * contains entries pointing to IRAM, AIPS1 and AIPS2.
+ * We need to set the TTBR1 to the new IRAM TLB.
+ * Do the following steps:
+ * 1. Flush the Branch Target Address Cache (BTAC)
+ * 2. Set TTBR1 to point to IRAM page table.
+ * 3. Disable page table walks in TTBR0 (PD0 = 1)
+ * 4. Set TTBR0.N=1, implying 0-2G is translated by TTBR0
+ * and 2-4G is translated by TTBR1.
+ */
+
+ ldr r6, =iram_tlb_phys_addr
+ ldr r7, [r6]
+
+ /* Flush the Branch Target Address Cache (BTAC) */
+ ldr r6, =0x0
+ mcr p15, 0, r6, c7, c1, 6
+
+ /* Disable Branch Prediction, Z bit in SCTLR. */
+ mrc p15, 0, r6, c1, c0, 0
+ bic r6, r6, #0x800
+ mcr p15, 0, r6, c1, c0, 0
+
+ dsb
+ isb
+ /* Store the IRAM table in TTBR1 */
+ mcr p15, 0, r7, c2, c0, 1
+
+ /* Read TTBCR and set PD0=1, N = 1 */
+ mrc p15, 0, r6, c2, c0, 2
+ orr r6, r6, #0x11
+ mcr p15, 0, r6, c2, c0, 2
+
+ dsb
+ isb
+
+ /* flush the TLB */
+ ldr r6, =0x0
+ mcr p15, 0, r6, c8, c3, 0
+
+ /* Disable L1 data cache. */
+ mrc p15, 0, r6, c1, c0, 0
+ bic r6, r6, #0x4
+ mcr p15, 0, r6, c1, c0, 0
+
+ dsb
+ isb
+
+ is_ca7
+ beq skip_disable_l2
+
+#ifdef CONFIG_CACHE_L2X0
+ /*
+ * Need to make sure the buffers in L2 are drained.
+ * Performing a sync operation does this.
+ */
+ ldr r7, =IMX_IO_P2V(MX6Q_L2_BASE_ADDR)
+ mov r6, #0x0
+ str r6, [r7, #L2_CACHE_SYNC]
+
+ /*
+ * The second dsb might be needed to keep cache sync (device write)
+ * ordering with the memory accesses before it.
+ */
+ dsb
+ isb
+
+ ldr r3, [r7, #PL310_AUX_CTRL]
+ tst r3, #PL310_AUX_16WAY_BIT
+ mov r3, #PL310_8WAYS_MASK
+ orrne r3, #PL310_16WAYS_UPPERMASK
+ mov r6, #PL310_LOCKDOWN_NBREGS
+ add r5, r7, #PL310_DCACHE_LOCKDOWN_BASE
+1: /* lock Dcache and Icache */
+ str r3, [r5], #PL310_LOCKDOWN_SZREG
+ str r3, [r5], #PL310_LOCKDOWN_SZREG
+ subs r6, r6, #1
+ bne 1b
+#endif
+
+skip_disable_l2:
+ ldr r2, =IMX_IO_P2V(MX6Q_CCM_BASE_ADDR)
+ ldr r3, =IMX_IO_P2V(MX6Q_ANATOP_BASE_ADDR)
+ ldr r5, =IMX_IO_P2V(MX6Q_MMDC_P0_BASE_ADDR)
+
+ /* Disable Automatic power savings. */
+ ldr r6, [r5, #MMDC0_MAPSR]
+ orr r6, r6, #0x1
+ str r6, [r5, #MMDC0_MAPSR]
+
+ /* MMDC0_MDPDC disable power down timer */
+ ldr r6, [r5, #MMDC0_MDPDC]
+ bic r6, r6, #0xff00
+ str r6, [r5, #MMDC0_MDPDC]
+
+ /* Delay for a while */
+ ldr r8, =10
+delay:
+ ldr r7, =0
+cont:
+ ldr r6, [r5, r7]
+ add r7, r7, #4
+ cmp r7, #16
+ bne cont
+ sub r8, r8, #1
+ cmp r8, #0
+ bgt delay
+
+ /* Make the DDR explicitly enter self-refresh. */
+ ldr r6, [r5, #MMDC0_MAPSR]
+ orr r6, r6, #0x200000
+ str r6, [r5, #MMDC0_MAPSR]
+
+poll_dvfs_set_1:
+ ldr r6, [r5, #MMDC0_MAPSR]
+ and r6, r6, #0x2000000
+ cmp r6, #0x2000000
+ bne poll_dvfs_set_1
+
+ /* set SBS step-by-step mode */
+ ldr r6, [r5, #MMDC0_MADPCR0]
+ orr r6, r6, #0x100
+ str r6, [r5, #MMDC0_MADPCR0]
+
+ ldr r6, =100000000
+ cmp r0, r6
+ bgt set_ddr_mu_above_100
+ mmdc_clk_lower_100MHz
+
+set_ddr_mu_above_100:
+ ldr r6, =24000000
+ cmp r0, r6
+ beq set_to_24MHz
+
+ ldr r6, =100000000
+ cmp r0, r6
+ beq set_to_100MHz
+
+ switch_to_400MHz
+
+ mmdc_clk_above_100MHz
+
+ b done
+
+set_to_24MHz:
+ switch_to_24MHz
+ b done
+set_to_100MHz:
+ switch_to_100MHz
+done:
+ /* clear DVFS - exit from self refresh mode */
+ ldr r6, [r5, #MMDC0_MAPSR]
+ bic r6, r6, #0x200000
+ str r6, [r5, #MMDC0_MAPSR]
+
+poll_dvfs_clear_1:
+ ldr r6, [r5, #MMDC0_MAPSR]
+ and r6, r6, #0x2000000
+ cmp r6, #0x2000000
+ beq poll_dvfs_clear_1
+
+ /* Enable Automatic power savings. */
+ ldr r6, [r5, #MMDC0_MAPSR]
+ bic r6, r6, #0x1
+ str r6, [r5, #MMDC0_MAPSR]
+
+ ldr r6, =24000000
+ cmp r0, r6
+ beq skip_power_down
+
+ /* Enable MMDC power down timer. */
+ ldr r6, [r5, #MMDC0_MDPDC]
+ orr r6, r6, #0x5500
+ str r6, [r5, #MMDC0_MDPDC]
+
+skip_power_down:
+ /* clear SBS - unblock DDR accesses */
+ ldr r6, [r5, #MMDC0_MADPCR0]
+ bic r6, r6, #0x100
+ str r6, [r5, #MMDC0_MADPCR0]
+
+ is_ca7
+ beq skip_enable_l2
+
+#ifdef CONFIG_CACHE_L2X0
+ ldr r7, =IMX_IO_P2V(MX6Q_L2_BASE_ADDR)
+ ldr r3, [r7, #PL310_AUX_CTRL]
+ tst r3, #PL310_AUX_16WAY_BIT
+ mov r6, #PL310_LOCKDOWN_NBREGS
+ mov r3, #0x00 /* 8 ways mask */
+ orrne r3, #0x0000 /* 16 ways mask */
+ add r5, r7, #PL310_DCACHE_LOCKDOWN_BASE
+1: /* lock Dcache and Icache */
+ str r3, [r5], #PL310_LOCKDOWN_SZREG
+ str r3, [r5], #PL310_LOCKDOWN_SZREG
+ subs r6, r6, #1
+ bne 1b
+#endif
+
+skip_enable_l2:
+ /* Enable L1 data cache. */
+ mrc p15, 0, r6, c1, c0, 0
+ orr r6, r6, #0x4
+ mcr p15, 0, r6, c1, c0, 0
+
+ /* Restore the TTBCR */
+ dsb
+ isb
+
+ /* Read TTBCR and set PD0=0, N = 0 */
+ mrc p15, 0, r6, c2, c0, 2
+ bic r6, r6, #0x11
+ mcr p15, 0, r6, c2, c0, 2
+ dsb
+ isb
+
+ /* flush the TLB */
+ ldr r6, =0x0
+ mcr p15, 0, r6, c8, c3, 0
+
+ dsb
+ isb
+
+ /* Enable Branch Prediction, Z bit in SCTLR. */
+ mrc p15, 0, r6, c1, c0, 0
+ orr r6, r6, #0x800
+ mcr p15, 0, r6, c1, c0, 0
+
+ /* Flush the Branch Target Address Cache (BTAC) */
+ ldr r6, =0x0
+ mcr p15, 0, r6, c7, c1, 6
+
+ nop
+ nop
+ nop
+ nop
+ nop
+
+ nop
+ nop
+ nop
+ nop
+ nop
+
+ nop
+ nop
+ nop
+ nop
+ nop
+
+ nop
+ nop
+ nop
+ nop
+ nop
+
+ nop
+ nop
+ nop
+ nop
+ nop
+
+ /* Restore registers */
+ pop {r2 - r8}
+ mov pc, lr
diff --git a/arch/arm/mach-imx/lpddr3_freq_imx.S b/arch/arm/mach-imx/lpddr3_freq_imx.S
new file mode 100644
index 000000000000..80fb1184fa54
--- /dev/null
+++ b/arch/arm/mach-imx/lpddr3_freq_imx.S
@@ -0,0 +1,444 @@
+/*
+ * Copyright (C) 2015-2016 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/linkage.h>
+#include "hardware.h"
+
+#define DDRC_MSTR 0x0
+#define DDRC_STAT 0x4
+#define DDRC_PWRCTL 0x30
+#define DDRC_RFSHTMG 0x64
+#define DDRC_DBG1 0x304
+#define DDRC_PSTAT 0x3fc
+#define DDRC_PCTRL_0 0x490
+#define DDRC_DFIMISC 0x1b0
+#define DDRC_DBGCAM 0x308
+#define DDRC_SWCTL 0x320
+#define DDRC_SWSTAT 0x324
+#define DDRPHY_LP_CON0 0x18
+#define IOMUXC_GPR8 0x20
+#define DDRPHY_PHY_CON1 0x4
+#define DDRPHY_MDLL_CON0 0xb0
+#define DDRPHY_MDLL_CON1 0xb4
+#define DDRPHY_OFFSETD_CON0 0x50
+#define DDRPHY_OFFSETR_CON0 0x20
+#define DDRPHY_OFFSETR_CON1 0x24
+#define DDRPHY_OFFSETR_CON2 0x28
+#define DDRPHY_OFFSETW_CON0 0x30
+#define DDRPHY_OFFSETW_CON1 0x34
+#define DDRPHY_OFFSETW_CON2 0x38
+#define DDRPHY_RFSHTMG 0x64
+#define DDRPHY_CA_WLDSKEW_CON0 0x6c
+#define DDRPHY_CA_DSKEW_CON0 0x7c
+#define DDRPHY_CA_DSKEW_CON1 0x80
+#define DDRPHY_CA_DSKEW_CON2 0x84
+
+#define ANADIG_DIGPROG 0x800
+
+ .align 3
+
+ .macro ddrc_prepare
+
+ /* disable port */
+ ldr r7, =0x0
+ str r7, [r4, #DDRC_PCTRL_0]
+
+ /* wait port busy done */
+ ldr r6, =0x10001
+1:
+ ldr r7, [r4, #DDRC_PSTAT]
+ and r7, r7, r6
+ cmp r7, #0
+ bne 1b
+
+ ldr r7, =0x20
+ str r7, [r4, #DDRC_PWRCTL]
+
+ ldr r6, =0x23
+2:
+ ldr r7, [r4, #DDRC_STAT]
+ and r7, r7, r6
+ cmp r7, r6
+ bne 2b
+
+ ldr r7, =0x1
+ str r7, [r4, #DDRC_DBG1]
+
+ ldr r6, =0x30000000
+3:
+ ldr r7, [r4, #DDRC_DBGCAM]
+ and r7, r7, r6
+ cmp r7, r6
+ bne 3b
+
+ ldr r7, =0x0
+ str r7, [r4, #DDRC_SWCTL]
+
+ ldr r7, =0x0
+ str r7, [r4, #DDRC_DFIMISC]
+
+ ldr r7, =0x1
+ str r7, [r4, #DDRC_SWCTL]
+
+ ldr r6, =0x1
+4:
+ ldr r7, [r4, #DDRC_SWSTAT]
+ and r7, r7, r6
+ cmp r7, r6
+ bne 4b
+
+ .endm
+
+ .macro ddrc_done
+
+ ldr r7, =0x0
+ str r7, [r4, #DDRC_PWRCTL]
+
+ ldr r6, =0x3
+5:
+ ldr r7, [r4, #DDRC_STAT]
+ and r7, r7, r6
+ cmp r7, r6
+ beq 5b
+
+ ldr r7, =0x0
+ str r7, [r4, #DDRC_DBG1]
+
+ ldr r7, =0x1
+ str r7, [r4, #DDRC_PCTRL_0]
+
+ /* enable auto self-refresh */
+ ldr r7, [r4, #DDRC_PWRCTL]
+ orr r7, r7, #(1 << 0)
+ str r7, [r4, #DDRC_PWRCTL]
+
+ .endm
+
+ .macro switch_to_below_100m
+
+ /* LPDDR2 and LPDDR3 has different setting */
+ ldr r8, [r4, #DDRC_MSTR]
+ ands r8, r8, #0x4
+ bne 9f
+
+ /* LPDDR3 */
+ ldr r7, =0x00000100
+ str r7, [r5, #DDRPHY_PHY_CON1]
+ b 10f
+9:
+ /* LPDDR2 */
+ ldr r7, =0x10010100
+ str r7, [r5, #DDRPHY_PHY_CON1]
+10:
+ ldr r6, =24000000
+ cmp r0, r6
+ beq 16f
+
+ ldr r7, =0x0005000B
+ str r7, [r4, #DDRC_RFSHTMG]
+ b 6f
+16:
+ ldr r7, =0x00010003
+ str r7, [r4, #DDRC_RFSHTMG]
+
+ /* dram alt sel set to OSC */
+ ldr r7, =0x10000000
+ ldr r8, =0xa080
+ str r7, [r2, r8]
+ /* dram root set to from dram alt, div by 1 */
+ ldr r7, =0x11000000
+ ldr r8, =0x9880
+ str r7, [r2, r8]
+ b 7f
+
+6:
+ /* dram alt sel set to pfd0_392m */
+ ldr r7, =0x15000000
+ ldr r8, =0xa080
+ str r7, [r2, r8]
+ /* dram root set to from dram alt, div by 4 */
+ ldr r7, =0x11000003
+ ldr r8, =0x9880
+ str r7, [r2, r8]
+7:
+ ldr r7, =0x202ffd0
+ str r7, [r5, #DDRPHY_MDLL_CON0]
+
+ ldr r7, =0x7f
+ str r7, [r5, #DDRPHY_OFFSETD_CON0]
+
+ ldr r7, =0x7f7f7f7f
+ str r7, [r5, #DDRPHY_OFFSETR_CON0]
+ str r7, [r5, #DDRPHY_OFFSETR_CON1]
+ ldr r7, =0x7f
+ str r7, [r5, #DDRPHY_OFFSETR_CON2]
+
+ ldr r7, =0x7f7f7f7f
+ str r7, [r5, #DDRPHY_OFFSETW_CON0]
+ str r7, [r5, #DDRPHY_OFFSETW_CON1]
+ ldr r7, =0x7f
+ str r7, [r5, #DDRPHY_OFFSETW_CON2]
+
+ ldr r7, [r9, #ANADIG_DIGPROG]
+ and r7, r7, #0x11
+ cmp r7, #0x11
+ bne 11f
+
+ ldr r7, =0x0
+ str r7, [r5, #DDRPHY_CA_WLDSKEW_CON0]
+ ldr r7, =0x60606060
+ str r7, [r5, #DDRPHY_CA_DSKEW_CON0]
+ str r7, [r5, #DDRPHY_CA_DSKEW_CON1]
+ ldr r7, =0x00006060
+ str r7, [r5, #DDRPHY_CA_DSKEW_CON2]
+ b 12f
+11:
+ ldr r7, =0x0
+ str r7, [r5, #DDRPHY_CA_DSKEW_CON0]
+ str r7, [r5, #DDRPHY_CA_DSKEW_CON1]
+ str r7, [r5, #DDRPHY_CA_DSKEW_CON2]
+12:
+ ldr r7, =0x100007f
+ str r7, [r5, #DDRPHY_OFFSETD_CON0]
+ ldr r7, =0x7f
+ str r7, [r5, #DDRPHY_OFFSETD_CON0]
+
+ .endm
+
+ .macro switch_to_533m
+
+ ldr r7, =0x10210100
+ str r7, [r5, #DDRPHY_PHY_CON1]
+
+ ldr r7, =0x00200038
+ str r7, [r4, #DDRC_RFSHTMG]
+
+ /* dram root set to from dram main, div by 2 */
+ ldr r7, =0x10000001
+ ldr r8, =0x9880
+ str r7, [r2, r8]
+
+ ldr r7, =0x1010007e
+ str r7, [r5, #DDRPHY_MDLL_CON0]
+
+ ldr r7, =0x10000008
+ str r7, [r5, #DDRPHY_OFFSETD_CON0]
+
+ ldr r7, =0x08080808
+ str r7, [r5, #DDRPHY_OFFSETR_CON0]
+ str r7, [r5, #DDRPHY_OFFSETR_CON1]
+ ldr r7, =0x8
+ str r7, [r5, #DDRPHY_OFFSETR_CON2]
+
+ ldr r7, =0x08080808
+ str r7, [r5, #DDRPHY_OFFSETW_CON0]
+ str r7, [r5, #DDRPHY_OFFSETW_CON1]
+ ldr r7, =0x8
+ str r7, [r5, #DDRPHY_OFFSETW_CON2]
+
+ /* LPDDR2 and LPDDR3 has different setting */
+ ldr r8, [r4, #DDRC_MSTR]
+ ands r8, r8, #0x4
+ beq 15f
+
+ ldr r7, [r9, #ANADIG_DIGPROG]
+ and r7, r7, #0x11
+ cmp r7, #0x11
+ bne 14f
+
+ ldr r7, =0x08080808
+ str r7, [r5, #DDRPHY_CA_DSKEW_CON0]
+ str r7, [r5, #DDRPHY_CA_DSKEW_CON1]
+ ldr r7, =0x0a0a0808
+ str r7, [r5, #DDRPHY_CA_DSKEW_CON2]
+ ldr r7, =0x0a0a0a0a
+ str r7, [r5, #DDRPHY_CA_WLDSKEW_CON0]
+ b 14f
+15:
+ ldr r7, [r9, #ANADIG_DIGPROG]
+ and r7, r7, #0x11
+ cmp r7, #0x11
+ bne 13f
+
+ ldr r7, =0x1c1c1c1c
+ str r7, [r5, #DDRPHY_CA_DSKEW_CON0]
+ str r7, [r5, #DDRPHY_CA_DSKEW_CON1]
+ ldr r7, =0x30301c1c
+ str r7, [r5, #DDRPHY_CA_DSKEW_CON2]
+ ldr r7, =0x30303030
+ str r7, [r5, #DDRPHY_CA_WLDSKEW_CON0]
+ b 14f
+13:
+ ldr r7, =0x08080808
+ str r7, [r5, #DDRPHY_CA_DSKEW_CON0]
+ str r7, [r5, #DDRPHY_CA_DSKEW_CON1]
+ ldr r7, =0x0808
+ str r7, [r5, #DDRPHY_CA_DSKEW_CON2]
+14:
+ ldr r7, =0x11000008
+ str r7, [r5, #DDRPHY_OFFSETD_CON0]
+ ldr r7, =0x10000008
+ str r7, [r5, #DDRPHY_OFFSETD_CON0]
+
+ ldr r6, =0x4
+8:
+ ldr r7, [r5, #DDRPHY_MDLL_CON1]
+ and r7, r7, r6
+ cmp r7, r6
+ bne 8b
+
+ .endm
+
+ENTRY(imx_lpddr3_freq_change)
+ push {r2 - r9}
+
+ /*
+ * To ensure no page table walks occur in DDR, we
+ * have a another page table stored in IRAM that only
+ * contains entries pointing to IRAM, AIPS1 and AIPS2.
+ * We need to set the TTBR1 to the new IRAM TLB.
+ * Do the following steps:
+ * 1. Flush the Branch Target Address Cache (BTAC)
+ * 2. Set TTBR1 to point to IRAM page table.
+ * 3. Disable page table walks in TTBR0 (PD0 = 1)
+ * 4. Set TTBR0.N=1, implying 0-2G is translated by TTBR0
+ * and 2-4G is translated by TTBR1.
+ */
+
+ ldr r6, =iram_tlb_phys_addr
+ ldr r7, [r6]
+
+ /* Flush the Branch Target Address Cache (BTAC) */
+ ldr r6, =0x0
+ mcr p15, 0, r6, c7, c1, 6
+
+ /* Disable Branch Prediction, Z bit in SCTLR. */
+ mrc p15, 0, r6, c1, c0, 0
+ bic r6, r6, #0x800
+ mcr p15, 0, r6, c1, c0, 0
+
+ dsb
+ isb
+ /* Store the IRAM table in TTBR1 */
+ mcr p15, 0, r7, c2, c0, 1
+
+ /* Read TTBCR and set PD0=1, N = 1 */
+ mrc p15, 0, r6, c2, c0, 2
+ orr r6, r6, #0x11
+ mcr p15, 0, r6, c2, c0, 2
+
+ dsb
+ isb
+
+ /* flush the TLB */
+ ldr r6, =0x0
+ mcr p15, 0, r6, c8, c3, 0
+
+ /* Disable L1 data cache. */
+ mrc p15, 0, r6, c1, c0, 0
+ bic r6, r6, #0x4
+ mcr p15, 0, r6, c1, c0, 0
+
+ dsb
+ isb
+
+ ldr r2, =IMX_IO_P2V(MX7D_CCM_BASE_ADDR)
+ ldr r3, =IMX_IO_P2V(MX7D_IOMUXC_GPR_BASE_ADDR)
+ ldr r4, =IMX_IO_P2V(MX7D_DDRC_BASE_ADDR)
+ ldr r5, =IMX_IO_P2V(MX7D_DDRC_PHY_BASE_ADDR)
+ ldr r9, =IMX_IO_P2V(MX7D_ANATOP_BASE_ADDR)
+
+ ddrc_prepare
+
+ ldr r6, =100000000
+ cmp r0, r6
+ bgt set_to_533m
+
+set_to_below_100m:
+ switch_to_below_100m
+ b done
+
+set_to_533m:
+ switch_to_533m
+ b done
+
+done:
+ ddrc_done
+
+ /* Enable L1 data cache. */
+ mrc p15, 0, r6, c1, c0, 0
+ orr r6, r6, #0x4
+ mcr p15, 0, r6, c1, c0, 0
+
+ /* Restore the TTBCR */
+ dsb
+ isb
+
+ /* Read TTBCR and set PD0=0, N = 0 */
+ mrc p15, 0, r6, c2, c0, 2
+ bic r6, r6, #0x11
+ mcr p15, 0, r6, c2, c0, 2
+ dsb
+ isb
+
+ /* flush the TLB */
+ ldr r6, =0x0
+ mcr p15, 0, r6, c8, c3, 0
+
+ dsb
+ isb
+
+ /* Enable Branch Prediction, Z bit in SCTLR. */
+ mrc p15, 0, r6, c1, c0, 0
+ orr r6, r6, #0x800
+ mcr p15, 0, r6, c1, c0, 0
+
+ /* Flush the Branch Target Address Cache (BTAC) */
+ ldr r6, =0x0
+ mcr p15, 0, r6, c7, c1, 6
+
+ nop
+ nop
+ nop
+ nop
+ nop
+
+ nop
+ nop
+ nop
+ nop
+ nop
+
+ nop
+ nop
+ nop
+ nop
+ nop
+
+ nop
+ nop
+ nop
+ nop
+ nop
+
+ nop
+ nop
+ nop
+ nop
+ nop
+
+ /* Restore registers */
+ pop {r2 - r9}
+ mov pc, lr
+ENDPROC(imx_lpddr3_freq_change)
diff --git a/arch/arm/mach-imx/mach-imx6q.c b/arch/arm/mach-imx/mach-imx6q.c
index 45801b27ee5c..7b2462f7f598 100644
--- a/arch/arm/mach-imx/mach-imx6q.c
+++ b/arch/arm/mach-imx/mach-imx6q.c
@@ -1,6 +1,7 @@
/*
- * Copyright 2011-2013 Freescale Semiconductor, Inc.
+ * Copyright 2011-2015 Freescale Semiconductor, Inc.
* Copyright 2011 Linaro Ltd.
+ * Copyright 2017 NXP.
*
* The code contained herein is licensed under the GNU General Public
* License. You may obtain a copy of the GNU General Public License
@@ -31,6 +32,7 @@
#include <linux/micrel_phy.h>
#include <linux/mfd/syscon.h>
#include <linux/mfd/syscon/imx6q-iomuxc-gpr.h>
+#include <linux/of_net.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
#include <asm/system_misc.h>
@@ -112,6 +114,18 @@ static int ar8031_phy_fixup(struct phy_device *dev)
{
u16 val;
+ /* Set RGMII IO voltage to 1.8V */
+ phy_write(dev, 0x1d, 0x1f);
+ phy_write(dev, 0x1e, 0x8);
+
+ /* disable phy AR8031 SmartEEE function. */
+ phy_write(dev, 0xd, 0x3);
+ phy_write(dev, 0xe, 0x805d);
+ phy_write(dev, 0xd, 0x4003);
+ val = phy_read(dev, 0xe);
+ val &= ~(0x1 << 8);
+ phy_write(dev, 0xe, val);
+
/* To enable AR8031 output a 125MHz clk from CLK_25M */
phy_write(dev, 0xd, 0x7);
phy_write(dev, 0xe, 0x8016);
@@ -184,9 +198,7 @@ static void __init imx6q_1588_init(void)
{
struct device_node *np;
struct clk *ptp_clk;
- struct clk *enet_ref;
struct regmap *gpr;
- u32 clksel;
np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-fec");
if (!np) {
@@ -200,35 +212,55 @@ static void __init imx6q_1588_init(void)
goto put_node;
}
- enet_ref = clk_get_sys(NULL, "enet_ref");
- if (IS_ERR(enet_ref)) {
- pr_warn("%s: failed to get enet clock\n", __func__);
- goto put_ptp_clk;
- }
-
/*
* If enet_ref from ANATOP/CCM is the PTP clock source, we need to
* set bit IOMUXC_GPR1[21]. Or the PTP clock must be from pad
* (external OSC), and we need to clear the bit.
*/
- clksel = clk_is_match(ptp_clk, enet_ref) ?
- IMX6Q_GPR1_ENET_CLK_SEL_ANATOP :
- IMX6Q_GPR1_ENET_CLK_SEL_PAD;
gpr = syscon_regmap_lookup_by_compatible("fsl,imx6q-iomuxc-gpr");
if (!IS_ERR(gpr))
regmap_update_bits(gpr, IOMUXC_GPR1,
IMX6Q_GPR1_ENET_CLK_SEL_MASK,
- clksel);
+ IMX6Q_GPR1_ENET_CLK_SEL_ANATOP);
else
pr_err("failed to find fsl,imx6q-iomuxc-gpr regmap\n");
- clk_put(enet_ref);
-put_ptp_clk:
clk_put(ptp_clk);
put_node:
of_node_put(np);
}
+static void __init imx6q_csi_mux_init(void)
+{
+ /*
+ * MX6Q SabreSD board:
+ * IPU1 CSI0 connects to parallel interface.
+ * Set GPR1 bit 19 to 0x1.
+ *
+ * MX6DL SabreSD board:
+ * IPU1 CSI0 connects to parallel interface.
+ * Set GPR13 bit 0-2 to 0x4.
+ * IPU1 CSI1 connects to MIPI CSI2 virtual channel 1.
+ * Set GPR13 bit 3-5 to 0x1.
+ */
+ struct regmap *gpr;
+
+ gpr = syscon_regmap_lookup_by_compatible("fsl,imx6q-iomuxc-gpr");
+ if (!IS_ERR(gpr)) {
+ if (of_machine_is_compatible("fsl,imx6q-sabresd") ||
+ of_machine_is_compatible("fsl,imx6q-sabreauto") ||
+ of_machine_is_compatible("fsl,imx6qp-sabresd") ||
+ of_machine_is_compatible("fsl,imx6qp-sabreauto"))
+ regmap_update_bits(gpr, IOMUXC_GPR1, 1 << 19, 1 << 19);
+ else if (of_machine_is_compatible("fsl,imx6dl-sabresd") ||
+ of_machine_is_compatible("fsl,imx6dl-sabreauto"))
+ regmap_update_bits(gpr, IOMUXC_GPR13, 0x3F, 0x0C);
+ } else {
+ pr_err("%s(): failed to find fsl,imx6q-iomux-gpr regmap\n",
+ __func__);
+ }
+}
+
static void __init imx6q_axi_init(void)
{
struct regmap *gpr;
@@ -262,11 +294,32 @@ static void __init imx6q_axi_init(void)
}
}
+static void __init imx6q_enet_clk_sel(void)
+{
+ struct regmap *gpr;
+
+ gpr = syscon_regmap_lookup_by_compatible("fsl,imx6q-iomuxc-gpr");
+ if (!IS_ERR(gpr))
+ regmap_update_bits(gpr, IOMUXC_GPR5,
+ IMX6Q_GPR5_ENET_TX_CLK_SEL, IMX6Q_GPR5_ENET_TX_CLK_SEL);
+ else
+ pr_err("failed to find fsl,imx6q-iomux-gpr regmap\n");
+}
+
+static inline void imx6q_enet_init(void)
+{
+ imx6_enet_mac_init("fsl,imx6q-fec", "fsl,imx6q-ocotp");
+ imx6q_enet_phy_init();
+ imx6q_1588_init();
+ if (cpu_is_imx6q() && imx_get_soc_revision() >= IMX_CHIP_REVISION_2_0)
+ imx6q_enet_clk_sel();
+}
+
static void __init imx6q_init_machine(void)
{
struct device *parent;
- if (cpu_is_imx6q() && imx_get_soc_revision() == IMX_CHIP_REVISION_2_0)
+ if (cpu_is_imx6q() && imx_get_soc_revision() >= IMX_CHIP_REVISION_2_0)
imx_print_silicon_rev("i.MX6QP", IMX_CHIP_REVISION_1_0);
else
imx_print_silicon_rev(cpu_is_imx6dl() ? "i.MX6DL" : "i.MX6Q",
@@ -276,13 +329,12 @@ static void __init imx6q_init_machine(void)
if (parent == NULL)
pr_warn("failed to initialize soc device\n");
- imx6q_enet_phy_init();
-
of_platform_default_populate(NULL, NULL, parent);
+ imx6q_enet_init();
imx_anatop_init();
+ imx6q_csi_mux_init();
cpu_is_imx6q() ? imx6q_pm_init() : imx6dl_pm_init();
- imx6q_1588_init();
imx6q_axi_init();
}
@@ -334,6 +386,13 @@ static void __init imx6q_opp_check_speed_grading(struct device *cpu_dev)
pr_warn("failed to disable 852 MHz OPP\n");
}
iounmap(base);
+
+ if (IS_ENABLED(CONFIG_MX6_VPU_352M)) {
+ if (dev_pm_opp_disable(cpu_dev, 396000000))
+ pr_warn("failed to disable 396MHz OPP\n");
+ pr_info("remove 396MHz OPP for VPU running at 352MHz!\n");
+ }
+
put_node:
of_node_put(np);
}
@@ -374,7 +433,9 @@ static void __init imx6q_init_late(void)
* WAIT mode is broken on TO 1.0 and 1.1, so there is no point
* to run cpuidle on them.
*/
- if (imx_get_soc_revision() > IMX_CHIP_REVISION_1_1)
+ if ((cpu_is_imx6q() && imx_get_soc_revision() > IMX_CHIP_REVISION_1_1)
+ || (cpu_is_imx6dl() && imx_get_soc_revision() >
+ IMX_CHIP_REVISION_1_0))
imx6q_cpuidle_init();
if (IS_ENABLED(CONFIG_ARM_IMX6Q_CPUFREQ)) {
@@ -387,6 +448,8 @@ static void __init imx6q_map_io(void)
{
debug_ll_io_init();
imx_scu_map_io();
+ imx6_pm_map_io();
+ imx_busfreq_map_io();
}
static void __init imx6q_init_irq(void)
diff --git a/arch/arm/mach-imx/mach-imx6sl.c b/arch/arm/mach-imx/mach-imx6sl.c
index 04084900d810..58e5033c4b18 100644
--- a/arch/arm/mach-imx/mach-imx6sl.c
+++ b/arch/arm/mach-imx/mach-imx6sl.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2013 Freescale Semiconductor, Inc.
+ * Copyright 2013-2016 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
@@ -18,8 +18,9 @@
#include "common.h"
#include "cpuidle.h"
+#include "hardware.h"
-static void __init imx6sl_fec_init(void)
+static void __init imx6sl_fec_clk_init(void)
{
struct regmap *gpr;
@@ -30,9 +31,14 @@ static void __init imx6sl_fec_init(void)
IMX6SL_GPR1_FEC_CLOCK_MUX2_SEL_MASK, 0);
regmap_update_bits(gpr, IOMUXC_GPR1,
IMX6SL_GPR1_FEC_CLOCK_MUX1_SEL_MASK, 0);
- } else {
+ } else
pr_err("failed to find fsl,imx6sl-iomux-gpr regmap\n");
- }
+}
+
+static inline void imx6sl_fec_init(void)
+{
+ imx6sl_fec_clk_init();
+ imx6_enet_mac_init("fsl,imx6sl-fec", "fsl,imx6sl-ocotp");
}
static void __init imx6sl_init_late(void)
@@ -41,7 +47,11 @@ static void __init imx6sl_init_late(void)
if (IS_ENABLED(CONFIG_ARM_IMX6Q_CPUFREQ))
platform_device_register_simple("imx6q-cpufreq", -1, NULL, 0);
- imx6sl_cpuidle_init();
+ /* cpuidle will be enabled later for i.MX6SLL */
+ if (cpu_is_imx6sll())
+ imx6sll_cpuidle_init();
+ else
+ imx6sl_cpuidle_init();
}
static void __init imx6sl_init_machine(void)
@@ -54,7 +64,8 @@ static void __init imx6sl_init_machine(void)
of_platform_default_populate(NULL, NULL, parent);
- imx6sl_fec_init();
+ if (!cpu_is_imx6sll())
+ imx6sl_fec_init();
imx_anatop_init();
imx6sl_pm_init();
}
@@ -66,17 +77,31 @@ static void __init imx6sl_init_irq(void)
imx_init_l2cache();
imx_src_init();
irqchip_init();
- imx6_pm_ccm_init("fsl,imx6sl-ccm");
+ if (cpu_is_imx6sll())
+ imx6_pm_ccm_init("fsl,imx6sll-ccm");
+ else
+ imx6_pm_ccm_init("fsl,imx6sl-ccm");
+}
+
+static void __init imx6sl_map_io(void)
+{
+ debug_ll_io_init();
+ imx6_pm_map_io();
+#ifdef CONFIG_CPU_FREQ
+ imx_busfreq_map_io();
+#endif
}
static const char * const imx6sl_dt_compat[] __initconst = {
"fsl,imx6sl",
+ "fsl,imx6sll",
NULL,
};
DT_MACHINE_START(IMX6SL, "Freescale i.MX6 SoloLite (Device Tree)")
.l2c_aux_val = 0,
.l2c_aux_mask = ~0,
+ .map_io = imx6sl_map_io,
.init_irq = imx6sl_init_irq,
.init_machine = imx6sl_init_machine,
.init_late = imx6sl_init_late,
diff --git a/arch/arm/mach-imx/mach-imx6sx.c b/arch/arm/mach-imx/mach-imx6sx.c
index 7f52d9b1e8a4..304909083930 100644
--- a/arch/arm/mach-imx/mach-imx6sx.c
+++ b/arch/arm/mach-imx/mach-imx6sx.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2014 Freescale Semiconductor, Inc.
+ * Copyright 2014-2015 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
@@ -14,9 +14,30 @@
#include <linux/mfd/syscon/imx6q-iomuxc-gpr.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
+#include <linux/micrel_phy.h>
#include "common.h"
#include "cpuidle.h"
+static void mmd_write_reg(struct phy_device *dev, int device, int reg, int val)
+{
+ phy_write(dev, 0x0d, device);
+ phy_write(dev, 0x0e, reg);
+ phy_write(dev, 0x0d, (1 << 14) | device);
+ phy_write(dev, 0x0e, val);
+}
+
+static int ksz9031rn_phy_fixup(struct phy_device *dev)
+{
+ /*
+ * min rx data delay, max rx/tx clock delay,
+ * min rx/tx control delay
+ */
+ mmd_write_reg(dev, 2, 4, 0);
+ mmd_write_reg(dev, 2, 5, 0);
+ mmd_write_reg(dev, 2, 8, 0x003ff);
+
+ return 0;
+}
static int ar8031_phy_fixup(struct phy_device *dev)
{
@@ -26,6 +47,14 @@ static int ar8031_phy_fixup(struct phy_device *dev)
phy_write(dev, 0x1d, 0x1f);
phy_write(dev, 0x1e, 0x8);
+ /* disable phy AR8031 SmartEEE function. */
+ phy_write(dev, 0xd, 0x3);
+ phy_write(dev, 0xe, 0x805d);
+ phy_write(dev, 0xd, 0x4003);
+ val = phy_read(dev, 0xe);
+ val &= ~(0x1 << 8);
+ phy_write(dev, 0xe, val);
+
/* introduce tx clock delay */
phy_write(dev, 0x1d, 0x5);
val = phy_read(dev, 0x1e);
@@ -38,9 +67,12 @@ static int ar8031_phy_fixup(struct phy_device *dev)
#define PHY_ID_AR8031 0x004dd074
static void __init imx6sx_enet_phy_init(void)
{
- if (IS_BUILTIN(CONFIG_PHYLIB))
+ if (IS_BUILTIN(CONFIG_PHYLIB)) {
+ phy_register_fixup_for_uid(PHY_ID_KSZ9031, MICREL_PHY_ID_MASK,
+ ksz9031rn_phy_fixup);
phy_register_fixup_for_uid(PHY_ID_AR8031, 0xffffffff,
ar8031_phy_fixup);
+ }
}
static void __init imx6sx_enet_clk_sel(void)
@@ -60,6 +92,7 @@ static void __init imx6sx_enet_clk_sel(void)
static inline void imx6sx_enet_init(void)
{
+ imx6_enet_mac_init("fsl,imx6sx-fec", "fsl,imx6sx-ocotp");
imx6sx_enet_phy_init();
imx6sx_enet_clk_sel();
}
@@ -91,10 +124,17 @@ static void __init imx6sx_init_irq(void)
static void __init imx6sx_init_late(void)
{
- imx6sx_cpuidle_init();
-
if (IS_ENABLED(CONFIG_ARM_IMX6Q_CPUFREQ))
platform_device_register_simple("imx6q-cpufreq", -1, NULL, 0);
+
+ imx6sx_cpuidle_init();
+}
+
+static void __init imx6sx_map_io(void)
+{
+ debug_ll_io_init();
+ imx6_pm_map_io();
+ imx_busfreq_map_io();
}
static const char * const imx6sx_dt_compat[] __initconst = {
@@ -105,6 +145,7 @@ static const char * const imx6sx_dt_compat[] __initconst = {
DT_MACHINE_START(IMX6SX, "Freescale i.MX6 SoloX (Device Tree)")
.l2c_aux_val = 0,
.l2c_aux_mask = ~0,
+ .map_io = imx6sx_map_io,
.init_irq = imx6sx_init_irq,
.init_machine = imx6sx_init_machine,
.dt_compat = imx6sx_dt_compat,
diff --git a/arch/arm/mach-imx/mach-imx6ul.c b/arch/arm/mach-imx/mach-imx6ul.c
index 6cb8a22b617d..99eb8ad811cb 100644
--- a/arch/arm/mach-imx/mach-imx6ul.c
+++ b/arch/arm/mach-imx/mach-imx6ul.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2015 Freescale Semiconductor, Inc.
+ * Copyright (C) 2015-2016 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
@@ -9,14 +9,17 @@
#include <linux/mfd/syscon.h>
#include <linux/mfd/syscon/imx6q-iomuxc-gpr.h>
#include <linux/micrel_phy.h>
+#include <linux/of_address.h>
#include <linux/of_platform.h>
#include <linux/phy.h>
+#include <linux/pm_opp.h>
#include <linux/regmap.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
#include "common.h"
#include "cpuidle.h"
+#include "hardware.h"
static void __init imx6ul_enet_clk_init(void)
{
@@ -46,15 +49,122 @@ static int ksz8081_phy_fixup(struct phy_device *dev)
static void __init imx6ul_enet_phy_init(void)
{
- if (IS_BUILTIN(CONFIG_PHYLIB))
- phy_register_fixup_for_uid(PHY_ID_KSZ8081, MICREL_PHY_ID_MASK,
- ksz8081_phy_fixup);
+ if (IS_BUILTIN(CONFIG_PHYLIB)) {
+ /*
+ * i.MX6UL EVK board RevA, RevB, RevC all use KSZ8081
+ * Silicon revision 00, the PHY ID is 0x00221560, pass our
+ * test with the phy fixup.
+ */
+ phy_register_fixup(PHY_ANY_ID, PHY_ID_KSZ8081, 0xffffffff,
+ ksz8081_phy_fixup);
+
+ /*
+ * i.MX6UL EVK board RevC1 board use KSZ8081
+ * Silicon revision 01, the PHY ID is 0x00221561.
+ * This silicon revision still need the phy fixup setting.
+ */
+ #define PHY_ID_KSZ8081_MNRN61 0x00221561
+ phy_register_fixup(PHY_ANY_ID, PHY_ID_KSZ8081_MNRN61,
+ 0xffffffff, ksz8081_phy_fixup);
+ }
+}
+
+#define OCOTP_CFG3 0x440
+#define OCOTP_CFG3_SPEED_SHIFT 16
+#define OCOTP_CFG3_SPEED_696MHZ 0x2
+#define OCOTP_CFG3_SPEED_900MHZ 0x3
+
+static void __init imx6ul_opp_check_speed_grading(struct device *cpu_dev)
+{
+ struct device_node *np;
+ void __iomem *base;
+ u32 val;
+
+ if (cpu_is_imx6ul())
+ np = of_find_compatible_node(NULL, NULL, "fsl,imx6ul-ocotp");
+ else
+ np = of_find_compatible_node(NULL, NULL, "fsl,imx6ull-ocotp");
+
+ if (!np) {
+ pr_warn("failed to find ocotp node\n");
+ return;
+ }
+
+ base = of_iomap(np, 0);
+ if (!base) {
+ pr_warn("failed to map ocotp\n");
+ goto put_node;
+ }
+
+ /*
+ * Speed GRADING[1:0] defines the max speed of ARM:
+ * 2b'00: Reserved;
+ * 2b'01: 528000000Hz;
+ * 2b'10: 700000000Hz(i.MX6UL), 800000000Hz(i.MX6ULL);
+ * 2b'11: 900000000Hz(i.MX6ULL);
+ * We need to set the max speed of ARM according to fuse map.
+ */
+ val = readl_relaxed(base + OCOTP_CFG3);
+ val >>= OCOTP_CFG3_SPEED_SHIFT;
+ val &= 0x3;
+ if (cpu_is_imx6ul()) {
+ if (val < OCOTP_CFG3_SPEED_696MHZ) {
+ if (dev_pm_opp_disable(cpu_dev, 696000000))
+ pr_warn("Failed to disable 696MHz OPP\n");
+ }
+ }
+
+ if (cpu_is_imx6ull()) {
+ if (val != OCOTP_CFG3_SPEED_696MHZ) {
+ if (dev_pm_opp_disable(cpu_dev, 792000000))
+ pr_warn("Failed to disable 792MHz OPP\n");
+ }
+
+ if (val != OCOTP_CFG3_SPEED_900MHZ) {
+ if(dev_pm_opp_disable(cpu_dev, 900000000))
+ pr_warn("Failed to disable 900MHz OPP\n");
+ }
+ }
+ iounmap(base);
+
+put_node:
+ of_node_put(np);
+}
+
+static void __init imx6ul_opp_init(void)
+{
+ struct device_node *np;
+ struct device *cpu_dev = get_cpu_device(0);
+
+ if (!cpu_dev) {
+ pr_warn("failed to get cpu0 device\n");
+ return;
+ }
+ np = of_node_get(cpu_dev->of_node);
+ if (!np) {
+ pr_warn("failed to find cpu0 node\n");
+ return;
+ }
+
+ if (dev_pm_opp_of_add_table(cpu_dev)) {
+ pr_warn("failed to init OPP table\n");
+ goto put_node;
+ }
+
+ imx6ul_opp_check_speed_grading(cpu_dev);
+
+put_node:
+ of_node_put(np);
}
static inline void imx6ul_enet_init(void)
{
imx6ul_enet_clk_init();
imx6ul_enet_phy_init();
+ if (cpu_is_imx6ul())
+ imx6_enet_mac_init("fsl,imx6ul-fec", "fsl,imx6ul-ocotp");
+ else
+ imx6_enet_mac_init("fsl,imx6ul-fec", "fsl,imx6ull-ocotp");
}
static void __init imx6ul_init_machine(void)
@@ -73,6 +183,7 @@ static void __init imx6ul_init_machine(void)
static void __init imx6ul_init_irq(void)
{
+ imx_gpc_check_dt();
imx_init_revision_from_anatop();
imx_src_init();
irqchip_init();
@@ -81,19 +192,30 @@ static void __init imx6ul_init_irq(void)
static void __init imx6ul_init_late(void)
{
- imx6sx_cpuidle_init();
-
- if (IS_ENABLED(CONFIG_ARM_IMX6Q_CPUFREQ))
+ if (IS_ENABLED(CONFIG_ARM_IMX6Q_CPUFREQ)) {
+ imx6ul_opp_init();
platform_device_register_simple("imx6q-cpufreq", -1, NULL, 0);
+ }
+
+ imx6ul_cpuidle_init();
+}
+
+static void __init imx6ul_map_io(void)
+{
+ debug_ll_io_init();
+ imx6_pm_map_io();
+ imx_busfreq_map_io();
}
static const char * const imx6ul_dt_compat[] __initconst = {
"fsl,imx6ul",
"fsl,imx6ull",
+ "fsl,imx6ulz",
NULL,
};
-DT_MACHINE_START(IMX6UL, "Freescale i.MX6 Ultralite (Device Tree)")
+DT_MACHINE_START(IMX6UL, "Freescale i.MX6 UltraLite (Device Tree)")
+ .map_io = imx6ul_map_io,
.init_irq = imx6ul_init_irq,
.init_machine = imx6ul_init_machine,
.init_late = imx6ul_init_late,
diff --git a/arch/arm/mach-imx/mach-imx7d.c b/arch/arm/mach-imx/mach-imx7d.c
index 26ca744d3e2b..47bab33cd349 100644
--- a/arch/arm/mach-imx/mach-imx7d.c
+++ b/arch/arm/mach-imx/mach-imx7d.c
@@ -16,6 +16,13 @@
#include <asm/mach/map.h>
#include "common.h"
+#include "cpuidle.h"
+
+static struct property device_disabled = {
+ .name = "status",
+ .length = sizeof("disabled"),
+ .value = "disabled",
+};
static int ar8031_phy_fixup(struct phy_device *dev)
{
@@ -66,6 +73,23 @@ static void __init imx7d_enet_phy_init(void)
}
}
+static void __init imx7d_enet_mdio_fixup(void)
+{
+ struct regmap *gpr;
+
+ /* The management data input/output (MDIO) bus where often high-speed,
+ * open-drain operation is required. i.MX7D TO1.0 ENET MDIO pin has no
+ * open drain as IC ticket number: TKT252980, i.MX7D TO1.1 fix the issue.
+ * GPR1[8:7] are reserved bits at TO1.0, there no need to add version check.
+ */
+ gpr = syscon_regmap_lookup_by_compatible("fsl,imx7d-iomuxc-gpr");
+ if (!IS_ERR(gpr))
+ regmap_update_bits(gpr, IOMUXC_GPR0, IMX7D_GPR0_ENET_MDIO_OPEN_DRAIN_MASK,
+ IMX7D_GPR0_ENET_MDIO_OPEN_DRAIN_MASK);
+ else
+ pr_err("failed to find fsl,imx7d-iomux-gpr regmap\n");
+}
+
static void __init imx7d_enet_clk_sel(void)
{
struct regmap *gpr;
@@ -81,10 +105,23 @@ static void __init imx7d_enet_clk_sel(void)
static inline void imx7d_enet_init(void)
{
+ imx6_enet_mac_init("fsl,imx7d-fec", "fsl,imx7d-ocotp");
+ imx7d_enet_mdio_fixup();
imx7d_enet_phy_init();
imx7d_enet_clk_sel();
}
+static inline void imx7d_disable_arm_arch_timer(void)
+{
+ struct device_node *node;
+
+ node = of_find_compatible_node(NULL, NULL, "arm,armv7-timer");
+ if (node) {
+ pr_info("disable arm arch timer for nosmp!\n");
+ of_add_property(node, &device_disabled);
+ }
+}
+
static void __init imx7d_init_machine(void)
{
struct device *parent;
@@ -93,15 +130,33 @@ static void __init imx7d_init_machine(void)
if (parent == NULL)
pr_warn("failed to initialize soc device\n");
+ of_platform_default_populate(NULL, NULL, parent);
+ imx7d_pm_init();
imx_anatop_init();
imx7d_enet_init();
}
static void __init imx7d_init_irq(void)
{
+ imx_gpcv2_check_dt();
imx_init_revision_from_anatop();
imx_src_init();
irqchip_init();
+#ifndef CONFIG_SMP
+ imx7d_disable_arm_arch_timer();
+#endif
+}
+
+static void __init imx7d_init_late(void)
+{
+ imx7d_cpuidle_init();
+}
+
+static void __init imx7d_map_io(void)
+{
+ debug_ll_io_init();
+ imx7_pm_map_io();
+ imx_busfreq_map_io();
}
static const char *const imx7d_dt_compat[] __initconst = {
@@ -111,7 +166,10 @@ static const char *const imx7d_dt_compat[] __initconst = {
};
DT_MACHINE_START(IMX7D, "Freescale i.MX7 Dual (Device Tree)")
+ .map_io = imx7d_map_io,
+ .smp = smp_ops(imx_smp_ops),
.init_irq = imx7d_init_irq,
.init_machine = imx7d_init_machine,
+ .init_late = imx7d_init_late,
.dt_compat = imx7d_dt_compat,
MACHINE_END
diff --git a/arch/arm/mach-imx/mach-imx7ulp.c b/arch/arm/mach-imx/mach-imx7ulp.c
new file mode 100644
index 000000000000..bf385b44048a
--- /dev/null
+++ b/arch/arm/mach-imx/mach-imx7ulp.c
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017 NXP.
+ *
+ * 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/irqchip.h>
+#include <linux/mfd/syscon.h>
+#include <linux/of_platform.h>
+#include <linux/regmap.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include "common.h"
+#include "cpuidle.h"
+#include "hardware.h"
+
+/* static IO mapping, and ioremap() could always share the same mapping. */
+static struct map_desc mx7ulp_io_desc[] __initdata = {
+ mx7ulp_aips_map_entry(1, MT_DEVICE),
+ mx7ulp_aips_map_entry(2, MT_DEVICE),
+ mx7ulp_aips_map_entry(3, MT_DEVICE),
+ mx7ulp_aips_map_entry(4, MT_DEVICE),
+ mx7ulp_aips_map_entry(5, MT_DEVICE),
+};
+
+#define SIM_JTAG_ID_REG 0x8c
+
+static void __init imx7ulp_init_machine(void)
+{
+ struct device *parent;
+ struct regmap *sim;
+ u32 revision;
+ int ret;
+
+ sim = syscon_regmap_lookup_by_compatible("fsl,imx7ulp-sim");
+ if (IS_ERR(sim)) {
+ pr_err("failed to find fsl,imx7ulp-sim regmap!\n");
+ return;
+ }
+
+ ret = regmap_read(sim, SIM_JTAG_ID_REG, &revision);
+ if (ret)
+ pr_err("failed to read sim regmap!\n");
+
+ /*
+ * bit[31:28] of JTAG_ID register defines revision
+ * as below from B0:
+ * 0001 B0
+ * 0010 B1
+ */
+ switch (revision >> 28) {
+ case 1:
+ imx_set_soc_revision(IMX_CHIP_REVISION_2_0);
+ break;
+ case 2:
+ imx_set_soc_revision(IMX_CHIP_REVISION_2_1);
+ break;
+ default:
+ imx_set_soc_revision(IMX_CHIP_REVISION_1_0);
+ break;
+ }
+
+ parent = imx_soc_device_init();
+ if (parent == NULL)
+ pr_warn("failed to initialize soc device\n");
+
+ of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
+}
+
+static void __init imx7ulp_init_irq(void)
+{
+ /* TBD */
+ mxc_set_cpu_type(MXC_CPU_IMX7ULP);
+
+ irqchip_init();
+ imx7ulp_pm_init();
+}
+
+static void __init imx7ulp_map_io(void)
+{
+ iotable_init(mx7ulp_io_desc, ARRAY_SIZE(mx7ulp_io_desc));
+ imx7ulp_pm_map_io();
+}
+
+static void __init imx7ulp_init_late(void)
+{
+ if (IS_ENABLED(CONFIG_ARM_IMX7ULP_CPUFREQ))
+ platform_device_register_simple("imx7ulp-cpufreq", -1, NULL, 0);
+
+ imx7ulp_cpuidle_init();
+ imx7ulp_enable_nmi();
+}
+
+static const char *const imx7ulp_dt_compat[] __initconst = {
+ "fsl,imx7ulp",
+ NULL,
+};
+
+DT_MACHINE_START(IMX7ulp, "Freescale i.MX7ULP (Device Tree)")
+ .map_io = imx7ulp_map_io,
+ .init_irq = imx7ulp_init_irq,
+ .init_machine = imx7ulp_init_machine,
+ .init_late = imx7ulp_init_late,
+ .dt_compat = imx7ulp_dt_compat,
+MACHINE_END
diff --git a/arch/arm/mach-imx/mmdc.c b/arch/arm/mach-imx/mmdc.c
index 78262899a590..e73a6d56758d 100644
--- a/arch/arm/mach-imx/mmdc.c
+++ b/arch/arm/mach-imx/mmdc.c
@@ -31,6 +31,8 @@
#define MMDC_MDMISC 0x18
#define BM_MMDC_MDMISC_DDR_TYPE 0x18
#define BP_MMDC_MDMISC_DDR_TYPE 0x3
+#define BM_MMDC_MDMISC_LPDDR2_2CH 0x4
+#define BP_MMDC_MDMISC_LPDDR2_2CH 0x2
#define TOTAL_CYCLES 0x0
#define BUSY_CYCLES 0x1
@@ -64,6 +66,7 @@
#define to_mmdc_pmu(p) container_of(p, struct mmdc_pmu, pmu)
static int ddr_type;
+static int lpddr2_2ch_mode;
struct fsl_mmdc_devtype_data {
unsigned int flags;
@@ -557,6 +560,9 @@ static int imx_mmdc_probe(struct platform_device *pdev)
val = readl_relaxed(reg);
ddr_type = (val & BM_MMDC_MDMISC_DDR_TYPE) >>
BP_MMDC_MDMISC_DDR_TYPE;
+ /* Get lpddr2 2ch-mode */
+ lpddr2_2ch_mode = (val & BM_MMDC_MDMISC_LPDDR2_2CH) >>
+ BP_MMDC_MDMISC_LPDDR2_2CH;
reg = mmdc_base + MMDC_MAPSR;
@@ -583,6 +589,11 @@ int imx_mmdc_get_ddr_type(void)
return ddr_type;
}
+int imx_mmdc_get_lpddr2_2ch_mode(void)
+{
+ return lpddr2_2ch_mode;
+}
+
static struct platform_driver imx_mmdc_driver = {
.driver = {
.name = "imx-mmdc",
diff --git a/arch/arm/mach-imx/mu.c b/arch/arm/mach-imx/mu.c
new file mode 100644
index 000000000000..4ab7ef2f9d62
--- /dev/null
+++ b/arch/arm/mach-imx/mu.c
@@ -0,0 +1,434 @@
+/*
+ * Copyright (C) 2014-2015 Freescale Semiconductor, Inc.
+ *
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/busfreq-imx.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/notifier.h>
+#include <linux/platform_device.h>
+#include "common.h"
+#include "hardware.h"
+
+#define MU_ATR0_OFFSET 0x0
+#define MU_ARR0_OFFSET 0x10
+#define MU_ARR1_OFFSET 0x14
+#define MU_ASR 0x20
+#define MU_ACR 0x24
+#define MX7ULP_MU_TR0 0x20
+#define MX7ULP_MU_RR0 0x40
+#define MX7ULP_MU_RR1 0x44
+#define MX7ULP_MU_SR 0x60
+#define MX7ULP_MU_CR 0x64
+
+#define MU_LPM_HANDSHAKE_INDEX 0
+#define MU_RPMSG_HANDSHAKE_INDEX 1
+#define MU_LPM_BUS_HIGH_READY_FOR_M4 0xFFFF6666
+#define MU_LPM_M4_FREQ_CHANGE_READY 0xFFFF7777
+#define MU_LPM_M4_REQUEST_HIGH_BUS 0x2222CCCC
+#define MU_LPM_M4_RELEASE_HIGH_BUS 0x2222BBBB
+#define MU_LPM_M4_WAKEUP_SRC_VAL 0x55555000
+#define MU_LPM_M4_WAKEUP_SRC_MASK 0xFFFFF000
+#define MU_LPM_M4_WAKEUP_IRQ_MASK 0xFF0
+#define MU_LPM_M4_WAKEUP_IRQ_SHIFT 0x4
+#define MU_LPM_M4_WAKEUP_ENABLE_MASK 0xF
+#define MU_LPM_M4_WAKEUP_ENABLE_SHIFT 0x0
+
+#define MU_LPM_M4_RUN_MODE 0x5A5A0001
+#define MU_LPM_M4_WAIT_MODE 0x5A5A0002
+#define MU_LPM_M4_STOP_MODE 0x5A5A0003
+
+#define MAX_NUM 10 /* enlarge it if overflow happen */
+
+static void __iomem *mu_base;
+static u32 m4_message[MAX_NUM];
+static u32 in_idx, out_idx;
+static struct delayed_work mu_work;
+static u32 m4_wake_irqs[4];
+static bool m4_freq_low;
+struct irq_domain *domain;
+static bool m4_in_stop;
+static struct clk *clk;
+static DEFINE_SPINLOCK(mu_lock);
+
+void imx_mu_set_m4_run_mode(void)
+{
+ m4_in_stop = false;
+}
+
+bool imx_mu_is_m4_in_stop(void)
+{
+ return m4_in_stop;
+}
+
+bool imx_mu_is_m4_in_low_freq(void)
+{
+ return m4_freq_low;
+}
+
+void imx_mu_enable_m4_irqs_in_gic(bool enable)
+{
+ int i, j;
+
+ for (i = 0; i < 4; i++) {
+ if (m4_wake_irqs[i] == 0)
+ continue;
+ for (j = 0; j < 32; j++) {
+ if (m4_wake_irqs[i] & (1 << j)) {
+ if (enable)
+ enable_irq(irq_find_mapping(
+ domain, i * 32 + j));
+ else
+ disable_irq(irq_find_mapping(
+ domain, i * 32 + j));
+ }
+ }
+ }
+}
+
+static irqreturn_t mcc_m4_dummy_isr(int irq, void *param)
+{
+ return IRQ_HANDLED;
+}
+
+static int imx_mu_send_message(unsigned int index, unsigned int data)
+{
+ u32 val, ep;
+ int i, te_flag = 0;
+ unsigned long timeout = jiffies + msecs_to_jiffies(500);
+
+ /* wait for transfer buffer empty, and no event pending */
+ do {
+ if (cpu_is_imx7ulp())
+ val = readl_relaxed(mu_base + MX7ULP_MU_SR);
+ else
+ val = readl_relaxed(mu_base + MU_ASR);
+ ep = val & BIT(4);
+ if (time_after(jiffies, timeout)) {
+ pr_err("Waiting MU transmit buffer empty timeout!\n");
+ return -EIO;
+ }
+ } while (((val & (1 << (20 + 3 - index))) == 0) || (ep == BIT(4)));
+
+ if (cpu_is_imx7ulp())
+ writel_relaxed(data, mu_base + index * 0x4 + MX7ULP_MU_TR0);
+ else
+ writel_relaxed(data, mu_base + index * 0x4 + MU_ATR0_OFFSET);
+
+ /*
+ * make a double check that TEn is not empty after write
+ */
+ if (cpu_is_imx7ulp())
+ val = readl_relaxed(mu_base + MX7ULP_MU_SR);
+ else
+ val = readl_relaxed(mu_base + MU_ASR);
+ ep = val & BIT(4);
+ if (((val & (1 << (20 + (3 - index)))) == 0) || (ep == BIT(4)))
+ return 0;
+ else
+ te_flag = 1;
+
+ /*
+ * Make sure that TEn flag is changed, after the ATRn is filled up.
+ */
+ for (i = 0; i < 100; i++) {
+ if (cpu_is_imx7ulp())
+ val = readl_relaxed(mu_base + MX7ULP_MU_SR);
+ else
+ val = readl_relaxed(mu_base + MU_ASR);
+ ep = val & BIT(4);
+ if (((val & (1 << (20 + 3 - index))) == 0) || (ep == BIT(4))) {
+ /*
+ * BUG here. TEn flag is changes, after the
+ * ATRn is filled with MSG for a while.
+ */
+ te_flag = 0;
+ break;
+ } else if (time_after(jiffies, timeout)) {
+ /* Can't see TEn 1->0, maybe already handled! */
+ te_flag = 1;
+ break;
+ }
+ }
+ if (te_flag == 0)
+ pr_info("BUG: TEn is not changed immediately"
+ "when ATRn is filled up.\n");
+
+ return 0;
+}
+
+static void mu_work_handler(struct work_struct *work)
+{
+ int ret;
+ u32 irq, enable, idx, mask, virq;
+ struct of_phandle_args args;
+ u32 message;
+ unsigned long flags;
+
+ spin_lock_irqsave(&mu_lock, flags);
+ message = m4_message[out_idx % MAX_NUM];
+ spin_unlock_irqrestore(&mu_lock, flags);
+
+ pr_debug("receive M4 message 0x%x\n", message);
+
+ switch (message) {
+ case MU_LPM_M4_RUN_MODE:
+ case MU_LPM_M4_WAIT_MODE:
+ m4_in_stop = false;
+ break;
+ case MU_LPM_M4_STOP_MODE:
+ m4_in_stop = true;
+ break;
+ case MU_LPM_M4_REQUEST_HIGH_BUS:
+ request_bus_freq(BUS_FREQ_HIGH);
+#ifdef CONFIG_SOC_IMX6SX
+ if (cpu_is_imx6sx())
+ imx6sx_set_m4_highfreq(true);
+#endif
+ imx_mu_send_message(MU_LPM_HANDSHAKE_INDEX,
+ MU_LPM_BUS_HIGH_READY_FOR_M4);
+ m4_freq_low = false;
+ break;
+ case MU_LPM_M4_RELEASE_HIGH_BUS:
+ release_bus_freq(BUS_FREQ_HIGH);
+#ifdef CONFIG_SOC_IMX6SX
+ if (cpu_is_imx6sx()) {
+ imx6sx_set_m4_highfreq(false);
+ imx_mu_send_message(MU_LPM_HANDSHAKE_INDEX,
+ MU_LPM_M4_FREQ_CHANGE_READY);
+ }
+#endif
+ m4_freq_low = true;
+ break;
+ default:
+ if ((message & MU_LPM_M4_WAKEUP_SRC_MASK) ==
+ MU_LPM_M4_WAKEUP_SRC_VAL) {
+ irq = (message & MU_LPM_M4_WAKEUP_IRQ_MASK) >>
+ MU_LPM_M4_WAKEUP_IRQ_SHIFT;
+
+ enable = (message & MU_LPM_M4_WAKEUP_ENABLE_MASK) >>
+ MU_LPM_M4_WAKEUP_ENABLE_SHIFT;
+
+ /* to hwirq start from 0 */
+ irq -= 32;
+
+ idx = irq / 32;
+ mask = 1 << irq % 32;
+
+ args.np = of_find_compatible_node(NULL, NULL, "fsl,imx6sx-gpc");
+ args.args_count = 3;
+ args.args[0] = 0;
+ args.args[1] = irq;
+ args.args[2] = IRQ_TYPE_LEVEL_HIGH;
+
+ virq = irq_create_of_mapping(&args);
+
+ if (enable && can_request_irq(virq, 0)) {
+ ret = request_irq(virq, mcc_m4_dummy_isr,
+ IRQF_NO_SUSPEND, "imx-m4-dummy", NULL);
+ if (ret) {
+ pr_err("%s: register interrupt %d failed, rc %d\n",
+ __func__, virq, ret);
+ break;
+ }
+ disable_irq(virq);
+ m4_wake_irqs[idx] = m4_wake_irqs[idx] | mask;
+ }
+ imx_gpc_add_m4_wake_up_irq(irq, enable);
+ }
+ break;
+ }
+
+ spin_lock_irqsave(&mu_lock, flags);
+ m4_message[out_idx % MAX_NUM] = 0;
+ out_idx++;
+ spin_unlock_irqrestore(&mu_lock, flags);
+
+ /* enable RIE3 interrupt */
+ if (cpu_is_imx7ulp())
+ writel_relaxed(readl_relaxed(mu_base + MX7ULP_MU_CR) | BIT(27),
+ mu_base + MX7ULP_MU_CR);
+ else
+ writel_relaxed(readl_relaxed(mu_base + MU_ACR) | BIT(27),
+ mu_base + MU_ACR);
+}
+
+int imx_mu_lpm_ready(bool ready)
+{
+ u32 val;
+
+ if (cpu_is_imx7ulp()) {
+ val = readl_relaxed(mu_base + MX7ULP_MU_CR);
+ if (ready)
+ writel_relaxed(val | BIT(0), mu_base + MX7ULP_MU_CR);
+ else
+ writel_relaxed(val & ~BIT(0), mu_base + MX7ULP_MU_CR);
+ } else {
+ val = readl_relaxed(mu_base + MU_ACR);
+ if (ready)
+ writel_relaxed(val | BIT(0), mu_base + MU_ACR);
+ else
+ writel_relaxed(val & ~BIT(0), mu_base + MU_ACR);
+ }
+ return 0;
+}
+
+static irqreturn_t imx_mu_isr(int irq, void *param)
+{
+ u32 irqs;
+ unsigned long flags;
+
+ if (cpu_is_imx7ulp())
+ irqs = readl_relaxed(mu_base + MX7ULP_MU_SR);
+ else
+ irqs = readl_relaxed(mu_base + MU_ASR);
+
+ if (irqs & (1 << 27)) {
+ spin_lock_irqsave(&mu_lock, flags);
+ /* get message from receive buffer */
+ if (cpu_is_imx7ulp())
+ m4_message[in_idx % MAX_NUM] = readl_relaxed(mu_base +
+ MX7ULP_MU_RR0);
+ else
+ m4_message[in_idx % MAX_NUM] = readl_relaxed(mu_base +
+ MU_ARR0_OFFSET);
+ /* disable RIE3 interrupt */
+ if (cpu_is_imx7ulp())
+ writel_relaxed(readl_relaxed(mu_base + MX7ULP_MU_CR)
+ & (~BIT(27)), mu_base + MX7ULP_MU_CR);
+ else
+ writel_relaxed(readl_relaxed(mu_base + MU_ACR)
+ & (~BIT(27)), mu_base + MU_ACR);
+ in_idx++;
+ if (in_idx == out_idx) {
+ spin_unlock_irqrestore(&mu_lock, flags);
+ pr_err("MU overflow!\n");
+ return IRQ_HANDLED;
+ }
+ spin_unlock_irqrestore(&mu_lock, flags);
+
+ schedule_delayed_work(&mu_work, 0);
+ }
+
+ return IRQ_HANDLED;
+}
+
+static int imx_mu_probe(struct platform_device *pdev)
+{
+ int ret;
+ u32 irq;
+ struct device_node *np;
+ struct device *dev = &pdev->dev;
+
+ np = of_find_compatible_node(NULL, NULL, "fsl,imx6sx-mu");
+ mu_base = of_iomap(np, 0);
+ WARN_ON(!mu_base);
+
+ ret = of_device_is_compatible(np, "fsl,imx7ulp-mu");
+ if (ret)
+ irq = platform_get_irq(pdev, 1);
+ else
+ irq = platform_get_irq(pdev, 0);
+ ret = request_irq(irq, imx_mu_isr,
+ IRQF_EARLY_RESUME | IRQF_SHARED, "imx-mu", dev);
+ if (ret) {
+ pr_err("%s: register interrupt %d failed, rc %d\n",
+ __func__, irq, ret);
+ return ret;
+ }
+
+ ret = of_device_is_compatible(np, "fsl,imx7d-mu");
+ if (ret) {
+ clk = devm_clk_get(&pdev->dev, "mu");
+ if (IS_ERR(clk)) {
+ dev_err(&pdev->dev,
+ "mu clock source missing or invalid\n");
+ return PTR_ERR(clk);
+ } else {
+ ret = clk_prepare_enable(clk);
+ if (ret) {
+ dev_err(&pdev->dev,
+ "unable to enable mu clock\n");
+ return ret;
+ }
+ }
+
+ /* MU always as a wakeup source for low power mode */
+ imx_gpcv2_add_m4_wake_up_irq(irq_to_desc(irq)->irq_data.hwirq,
+ true);
+ } else {
+ /* MU always as a wakeup source for low power mode */
+ imx_gpc_add_m4_wake_up_irq(irq_to_desc(irq)->irq_data.hwirq, true);
+ }
+
+ INIT_DELAYED_WORK(&mu_work, mu_work_handler);
+ /* bit0 of MX7ULP_MU_CR used to let m4 to know MU is ready now */
+ if (cpu_is_imx7ulp())
+ writel_relaxed(readl_relaxed(mu_base + MX7ULP_MU_CR) |
+ BIT(0) | BIT(26) | BIT(27), mu_base + MX7ULP_MU_CR);
+ else
+ writel_relaxed(readl_relaxed(mu_base + MU_ACR) |
+ BIT(26) | BIT(27), mu_base + MU_ACR);
+
+ pr_info("MU is ready for cross core communication!\n");
+
+ return 0;
+}
+
+static const struct of_device_id imx_mu_ids[] = {
+ { .compatible = "fsl,imx6sx-mu" },
+ { .compatible = "fsl,imx7d-mu" },
+ { .compatible = "fsl,imx7ulp-mu" },
+ { }
+};
+
+#ifdef CONFIG_PM_SLEEP
+static int mu_suspend(struct device *dev)
+{
+ return 0;
+}
+
+static int mu_resume(struct device *dev)
+{
+ if (!cpu_is_imx7ulp())
+ return 0;
+
+ writel_relaxed(readl_relaxed(mu_base + MX7ULP_MU_CR) |
+ BIT(0) | BIT(26) | BIT(27), mu_base + MX7ULP_MU_CR);
+
+ return 0;
+}
+#endif
+static const struct dev_pm_ops mu_pm_ops = {
+ SET_LATE_SYSTEM_SLEEP_PM_OPS(mu_suspend, mu_resume)
+};
+
+static struct platform_driver imx_mu_driver = {
+ .driver = {
+ .name = "imx-mu",
+ .owner = THIS_MODULE,
+ .pm = &mu_pm_ops,
+ .of_match_table = imx_mu_ids,
+ },
+ .probe = imx_mu_probe,
+};
+
+static int __init imx_mu_init(void)
+{
+ return platform_driver_register(&imx_mu_driver);
+}
+subsys_initcall(imx_mu_init);
diff --git a/arch/arm/mach-imx/mx6.h b/arch/arm/mach-imx/mx6.h
new file mode 100644
index 000000000000..06b8135a9954
--- /dev/null
+++ b/arch/arm/mach-imx/mx6.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2004-2015 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * * This program is free software; you can redistribute it and/or modify
+ * * it under the terms of the GNU General Public License version 2 as
+ * * published by the Free Software Foundation.
+ * */
+
+#ifndef __ASM_ARCH_MXC_IOMAP_H__
+#define __ASM_ARCH_MXC_IOMAP_H__
+
+#define MX6Q_IO_P2V(x) IMX_IO_P2V(x)
+#define MX6Q_IO_ADDRESS(x) IOMEM(MX6Q_IO_P2V(x))
+
+#define MX6Q_L2_BASE_ADDR 0x00a02000
+#define MX6Q_L2_SIZE 0x1000
+#define MX6Q_IOMUXC_BASE_ADDR 0x020e0000
+#define MX6Q_IOMUXC_SIZE 0x4000
+#define MX6Q_SRC_BASE_ADDR 0x020d8000
+#define MX6Q_SRC_SIZE 0x4000
+#define MX6Q_CCM_BASE_ADDR 0x020c4000
+#define MX6Q_CCM_SIZE 0x4000
+#define MX6Q_ANATOP_BASE_ADDR 0x020c8000
+#define MX6Q_ANATOP_SIZE 0x1000
+#define MX6Q_GPC_BASE_ADDR 0x020dc000
+#define MX6Q_GPC_SIZE 0x4000
+#define MX6Q_SEMA4_BASE_ADDR 0x02290000
+#define MX6Q_SEMA4_SIZE 0x4000
+#define MX6Q_MMDC_P0_BASE_ADDR 0x021b0000
+#define MX6Q_MMDC_P0_SIZE 0x4000
+#define MX6Q_MMDC_P1_BASE_ADDR 0x021b4000
+#define MX6Q_MMDC_P1_SIZE 0x4000
+#define MX6Q_AIPS1_BASE_ADDR 0x02000000
+#define MX6Q_AIPS1_SIZE 0x100000
+#define MX6Q_AIPS2_BASE_ADDR 0x02100000
+#define MX6Q_AIPS2_SIZE 0x100000
+#define MX6Q_AIPS3_BASE_ADDR 0x02200000
+#define MX6Q_AIPS3_SIZE 0x100000
+
+#define MX6SX_IRAM_TLB_BASE_ADDR 0x008f8000
+#define MX6Q_IRAM_TLB_BASE_ADDR 0x00900000
+#define MX6Q_IRAM_TLB_SIZE 0x4000
+#define TT_ATTRIB_NON_CACHEABLE_1M 0x802
+#define MX6_SUSPEND_IRAM_DATA_SIZE 256
+#define MX6SL_WFI_IRAM_DATA_SIZE 100
+
+#define MX6_SUSPEND_IRAM_ADDR_OFFSET 0
+#define MX6_CPUIDLE_IRAM_ADDR_OFFSET 0x1000
+#endif
diff --git a/arch/arm/mach-imx/mx7.h b/arch/arm/mach-imx/mx7.h
new file mode 100644
index 000000000000..afbeaef12d07
--- /dev/null
+++ b/arch/arm/mach-imx/mx7.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2015 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * * This program is free software; you can redistribute it and/or modify
+ * * it under the terms of the GNU General Public License version 2 as
+ * * published by the Free Software Foundation.
+ * */
+
+#ifndef __ASM_ARCH_MX7_IOMAP_H__
+#define __ASM_ARCH_MX7_IOMAP_H__
+
+#define MX7D_IO_P2V(x) IMX_IO_P2V(x)
+#define MX7D_IO_ADDRESS(x) IOMEM(MX7D_IO_P2V(x))
+
+#define MX7D_LPSR_BASE_ADDR 0x30270000
+#define MX7D_LPSR_SIZE 0x10000
+#define MX7D_CCM_BASE_ADDR 0x30380000
+#define MX7D_CCM_SIZE 0x10000
+#define MX7D_IOMUXC_BASE_ADDR 0x30330000
+#define MX7D_IOMUXC_SIZE 0x10000
+#define MX7D_IOMUXC_GPR_BASE_ADDR 0x30340000
+#define MX7D_IOMUXC_GPR_SIZE 0x10000
+#define MX7D_ANATOP_BASE_ADDR 0x30360000
+#define MX7D_ANATOP_SIZE 0x10000
+#define MX7D_SNVS_BASE_ADDR 0x30370000
+#define MX7D_SNVS_SIZE 0x10000
+#define MX7D_GPC_BASE_ADDR 0x303a0000
+#define MX7D_GPC_SIZE 0x10000
+#define MX7D_SRC_BASE_ADDR 0x30390000
+#define MX7D_SRC_SIZE 0x10000
+#define MX7D_DDRC_BASE_ADDR 0x307a0000
+#define MX7D_DDRC_SIZE 0x10000
+#define MX7D_DDRC_PHY_BASE_ADDR 0x30790000
+#define MX7D_DDRC_PHY_SIZE 0x10000
+#define MX7D_AIPS1_BASE_ADDR 0x30000000
+#define MX7D_AIPS1_SIZE 0x400000
+#define MX7D_AIPS2_BASE_ADDR 0x30400000
+#define MX7D_AIPS2_SIZE 0x400000
+#define MX7D_AIPS3_BASE_ADDR 0x30900000
+#define MX7D_AIPS3_SIZE 0x300000
+#define MX7D_GIC_BASE_ADDR 0x31000000
+#define MX7D_GIC_SIZE 0x100000
+
+#define TT_ATTRIB_NON_CACHEABLE_1M 0x802
+#define MX7_IRAM_TLB_SIZE 0x4000
+#define MX7_SUSPEND_OCRAM_SIZE 0x1000
+#define MX7_CPUIDLE_OCRAM_ADDR_OFFSET 0x1000
+#define MX7_CPUIDLE_OCRAM_SIZE 0x1000
+#define MX7_BUSFREQ_OCRAM_ADDR_OFFSET 0x2000
+#define MX7_BUSFREQ_OCRAM_SIZE 0x1000
+
+#endif
diff --git a/arch/arm/mach-imx/mx7ulp.h b/arch/arm/mach-imx/mx7ulp.h
new file mode 100644
index 000000000000..a00e86f27e65
--- /dev/null
+++ b/arch/arm/mach-imx/mx7ulp.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright NXP 2017.
+ */
+
+/*
+ * * 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_MX7ULP_IOMAP_H__
+#define __ASM_ARCH_MX7ULP_IOMAP_H__
+
+#define MX7ULP_IO_P2V(x) IMX_IO_P2V(x)
+#define MX7ULP_IO_ADDRESS(x) IOMEM(MX7ULP_IO_P2V(x))
+
+#define MX7ULP_AIPS1_BASE_ADDR 0x40000000
+#define MX7ULP_AIPS1_SIZE 0x100000
+#define MX7ULP_AIPS2_BASE_ADDR 0x40300000
+#define MX7ULP_AIPS2_SIZE 0x100000
+#define MX7ULP_AIPS3_BASE_ADDR 0x40400000
+#define MX7ULP_AIPS3_SIZE 0x100000
+#define MX7ULP_AIPS4_BASE_ADDR 0x40a00000
+#define MX7ULP_AIPS4_SIZE 0x100000
+#define MX7ULP_AIPS5_BASE_ADDR 0x41000000
+#define MX7ULP_AIPS5_SIZE 0x100000
+#define MX7ULP_GPIOC_BASE_ADDR 0x400f0000
+#define MX7ULP_GPIOC_SIZE 0x1000
+#define MX7ULP_PCC3_BASE_ADDR 0x40b30000
+#define MX7ULP_PCC3_SIZE 0x1000
+#define MX7ULP_SCG1_BASE_ADDR 0x403e0000
+#define MX7ULP_SCG1_SIZE 0x1000
+#define MX7ULP_PCC2_BASE_ADDR 0x403f0000
+#define MX7ULP_PCC2_SIZE 0x1000
+#define MX7ULP_SIM_BASE_ADDR 0x410a3000
+#define MX7ULP_SIM_SIZE 0x1000
+#define MX7ULP_PMC1_BASE_ADDR 0x40400000
+#define MX7ULP_PMC1_SIZE 0x1000
+#define MX7ULP_SMC1_BASE_ADDR 0x40410000
+#define MX7ULP_SMC1_SIZE 0x1000
+#define MX7ULP_MMDC_BASE_ADDR 0x40ab0000
+#define MX7ULP_MMDC_SIZE 0x1000
+#define MX7ULP_IOMUXC1_BASE_ADDR 0x40ac0000
+#define MX7ULP_IOMUXC1_BASE__SIZE 0x1000
+#define MX7ULP_MMDC_IO_BASE_ADDR 0x40ad0000
+#define MX7ULP_MMDC_IO_SIZE 0x1000
+
+/* below is just used for static mapping of the AIPSx's memory region */
+#define MX7ULP_AIPS_VIRT_BASE(x) (0xf4000000 + ((x) * SZ_1M))
+
+#define mx7ulp_aips_map_entry(index, _type) { \
+ .virtual = MX7ULP_AIPS_VIRT_BASE(index), \
+ .pfn = __phys_to_pfn(MX7ULP_AIPS ## index ## _BASE_ADDR), \
+ .length = SZ_1M, \
+ .type = _type, \
+}
+
+#define TT_ATTRIB_NON_CACHEABLE_1M 0x802
+#define MX7ULP_IRAM_TLB_SIZE 0x4000
+#define MX7ULP_SUSPEND_OCRAM_SIZE 0x1000
+
+#endif
diff --git a/arch/arm/mach-imx/mxc.h b/arch/arm/mach-imx/mxc.h
index e00d6260c3df..95e7c3e6f141 100644
--- a/arch/arm/mach-imx/mxc.h
+++ b/arch/arm/mach-imx/mxc.h
@@ -40,9 +40,18 @@
#define MXC_CPU_IMX6Q 0x63
#define MXC_CPU_IMX6UL 0x64
#define MXC_CPU_IMX6ULL 0x65
+#define MXC_CPU_IMX6SLL 0x67
+#define MXC_CPU_IMX6ULZ 0x6B
#define MXC_CPU_IMX7D 0x72
+#define MXC_CPU_IMX7ULP 0xff /* TBD */
+#define IMX_DDR_TYPE_DDR3 0
#define IMX_DDR_TYPE_LPDDR2 1
+#define IMX_DDR_TYPE_LPDDR3 2
+#define IMX_MMDC_DDR_TYPE_LPDDR3 3
+
+#define IMX_LPDDR2_1CH_MODE 0
+#define IMX_LPDDR2_2CH_MODE 1
#ifndef __ASSEMBLY__
extern unsigned int __mxc_cpu_type;
@@ -76,7 +85,13 @@ static inline bool cpu_is_imx6ul(void)
static inline bool cpu_is_imx6ull(void)
{
- return __mxc_cpu_type == MXC_CPU_IMX6ULL;
+ return __mxc_cpu_type == MXC_CPU_IMX6ULL ||
+ __mxc_cpu_type == MXC_CPU_IMX6ULZ;
+}
+
+static inline bool cpu_is_imx6sll(void)
+{
+ return __mxc_cpu_type == MXC_CPU_IMX6SLL;
}
static inline bool cpu_is_imx6q(void)
@@ -84,11 +99,28 @@ static inline bool cpu_is_imx6q(void)
return __mxc_cpu_type == MXC_CPU_IMX6Q;
}
+static inline bool cpu_is_imx6(void)
+{
+ return __mxc_cpu_type == MXC_CPU_IMX6Q ||
+ __mxc_cpu_type == MXC_CPU_IMX6DL ||
+ __mxc_cpu_type == MXC_CPU_IMX6SL ||
+ __mxc_cpu_type == MXC_CPU_IMX6SX ||
+ __mxc_cpu_type == MXC_CPU_IMX6UL ||
+ __mxc_cpu_type == MXC_CPU_IMX6ULL ||
+ __mxc_cpu_type == MXC_CPU_IMX6SLL ||
+ __mxc_cpu_type == MXC_CPU_IMX6ULZ;
+}
+
static inline bool cpu_is_imx7d(void)
{
return __mxc_cpu_type == MXC_CPU_IMX7D;
}
+static inline bool cpu_is_imx7ulp(void)
+{
+ return __mxc_cpu_type == MXC_CPU_IMX7ULP;
+}
+
struct cpu_op {
u32 cpu_rate;
};
diff --git a/arch/arm/mach-imx/platsmp.c b/arch/arm/mach-imx/platsmp.c
index c2d1b329fba1..e1bf7c11616b 100644
--- a/arch/arm/mach-imx/platsmp.c
+++ b/arch/arm/mach-imx/platsmp.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2011 Freescale Semiconductor, Inc.
+ * Copyright 2011-2015 Freescale Semiconductor, Inc.
* Copyright 2011 Linaro Ltd.
*
* The code contained herein is licensed under the GNU General Public
@@ -24,7 +24,7 @@
#include "hardware.h"
u32 g_diag_reg;
-static void __iomem *scu_base;
+void __iomem *imx_scu_base;
static struct map_desc scu_io_desc __initdata = {
/* .virtual and .pfn are run-time assigned */
@@ -43,7 +43,7 @@ void __init imx_scu_map_io(void)
scu_io_desc.pfn = __phys_to_pfn(base);
iotable_init(&scu_io_desc, 1);
- scu_base = IMX_IO_ADDRESS(base);
+ imx_scu_base = IMX_IO_ADDRESS(base);
}
static int imx_boot_secondary(unsigned int cpu, struct task_struct *idle)
@@ -53,15 +53,39 @@ static int imx_boot_secondary(unsigned int cpu, struct task_struct *idle)
return 0;
}
+#define MXC_ARCH_CA7 0xc07
+static unsigned long __mxc_arch_type;
+
+static inline bool arm_is_ca7(void)
+{
+ return __mxc_arch_type == MXC_ARCH_CA7;
+}
/*
* Initialise the CPU possible map early - this describes the CPUs
* which may be present or become present in the system.
*/
static void __init imx_smp_init_cpus(void)
{
+ unsigned long arch_type;
int i, ncores;
- ncores = scu_get_core_count(scu_base);
+ asm volatile(
+ ".align 4\n"
+ "mrc p15, 0, %0, c0, c0, 0\n"
+ : "=r" (arch_type)
+ );
+ /* MIDR[15:4] defines ARCH type */
+ __mxc_arch_type = (arch_type >> 4) & 0xfff;
+
+ if (arm_is_ca7()) {
+ unsigned long val;
+
+ /* CA7 core number, [25:24] of CP15 L2CTLR */
+ asm volatile("mrc p15, 1, %0, c9, c0, 2" : "=r" (val));
+ ncores = ((val >> 24) & 0x3) + 1;
+ } else {
+ ncores = scu_get_core_count(imx_scu_base);
+ }
for (i = ncores; i < NR_CPUS; i++)
set_cpu_possible(i, false);
@@ -69,11 +93,15 @@ static void __init imx_smp_init_cpus(void)
void imx_smp_prepare(void)
{
- scu_enable(scu_base);
+ if (arm_is_ca7())
+ return;
+ scu_enable(imx_scu_base);
}
static void __init imx_smp_prepare_cpus(unsigned int max_cpus)
{
+ if (arm_is_ca7())
+ return;
imx_smp_prepare();
/*
diff --git a/arch/arm/mach-imx/pm-imx6.c b/arch/arm/mach-imx/pm-imx6.c
index 6078bcc9f594..e58cfa195794 100644
--- a/arch/arm/mach-imx/pm-imx6.c
+++ b/arch/arm/mach-imx/pm-imx6.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2011-2014 Freescale Semiconductor, Inc.
+ * Copyright 2011-2016 Freescale Semiconductor, Inc.
* Copyright 2011 Linaro Ltd.
*
* The code contained herein is licensed under the GNU General Public
@@ -19,15 +19,21 @@
#include <linux/mfd/syscon/imx6q-iomuxc-gpr.h>
#include <linux/of.h>
#include <linux/of_address.h>
+#include <linux/of_fdt.h>
#include <linux/of_platform.h>
+#include <linux/psci.h>
#include <linux/regmap.h>
+#include <linux/slab.h>
#include <linux/suspend.h>
#include <asm/cacheflush.h>
#include <asm/fncpy.h>
+#include <asm/mach/map.h>
#include <asm/proc-fns.h>
#include <asm/suspend.h>
#include <asm/tlb.h>
+#include <uapi/linux/psci.h>
+
#include "common.h"
#include "hardware.h"
@@ -60,13 +66,215 @@
#define CGPR 0x64
#define BM_CGPR_INT_MEM_CLK_LPM (0x1 << 17)
+#define CCGR4 0x78
+#define CCGR6 0x80
#define MX6Q_SUSPEND_OCRAM_SIZE 0x1000
-#define MX6_MAX_MMDC_IO_NUM 33
+#define MX6_MAX_MMDC_IO_NUM 36
+#define MX6_MAX_MMDC_NUM 36
+
+#define ROMC_ROMPATCH0D 0xf0
+#define ROMC_ROMPATCHCNTL 0xf4
+#define ROMC_ROMPATCHENL 0xfc
+#define ROMC_ROMPATCH0A 0x100
+#define BM_ROMPATCHCNTL_0D (0x1 << 0)
+#define BM_ROMPATCHCNTL_DIS (0x1 << 29)
+#define BM_ROMPATCHENL_0D (0x1 << 0)
+#define ROM_ADDR_FOR_INTERNAL_RAM_BASE 0x10d7c
+
+#define UART_UCR1 0x80
+#define UART_UCR2 0x84
+#define UART_UCR3 0x88
+#define UART_UCR4 0x8c
+#define UART_UFCR 0x90
+#define UART_UESC 0x9c
+#define UART_UTIM 0xa0
+#define UART_UBIR 0xa4
+#define UART_UBMR 0xa8
+#define UART_UBRC 0xac
+#define UART_UTS 0xb4
+
+#define IOMUXC_GPR5_CLOCK_AFCG_X_BYPASS_MASK 0xf800
+
+extern unsigned long iram_tlb_base_addr;
+extern unsigned long iram_tlb_phys_addr;
+
+/* QSPI register layout */
+#define QSPI_MCR 0x00
+#define QSPI_IPCR 0x08
+#define QSPI_BUF0CR 0x10
+#define QSPI_BUF1CR 0x14
+#define QSPI_BUF2CR 0x18
+#define QSPI_BUF3CR 0x1c
+#define QSPI_BFGENCR 0x20
+#define QSPI_BUF0IND 0x30
+#define QSPI_BUF1IND 0x34
+#define QSPI_BUF2IND 0x38
+#define QSPI_SFAR 0x100
+#define QSPI_SMPR 0x108
+#define QSPI_RBSR 0x10c
+#define QSPI_RBCT 0x110
+#define QSPI_TBSR 0x150
+#define QSPI_TBDR 0x154
+#define QSPI_SFA1AD 0x180
+#define QSPI_SFA2AD 0x184
+#define QSPI_SFB1AD 0x188
+#define QSPI_SFB2AD 0x18c
+#define QSPI_RBDR_BASE 0x200
+#define QSPI_LUTKEY 0x300
+#define QSPI_LCKCR 0x304
+#define QSPI_LUT_BASE 0x310
+
+#define QSPI_RBDR_(x) (QSPI_RBDR_BASE + (x) * 4)
+#define QSPI_LUT(x) (QSPI_LUT_BASE + (x) * 4)
+
+#define QSPI_LUTKEY_VALUE 0x5AF05AF0
+#define QSPI_LCKER_LOCK 0x1
+#define QSPI_LCKER_UNLOCK 0x2
+
+enum qspi_regs_valuetype {
+ QSPI_PREDEFINED,
+ QSPI_RETRIEVED,
+};
+
+struct qspi_regs {
+ int offset;
+ unsigned int value;
+ enum qspi_regs_valuetype valuetype;
+};
+
+struct qspi_regs qspi_regs_imx6sx[] = {
+ {QSPI_IPCR, 0, QSPI_RETRIEVED},
+ {QSPI_BUF0CR, 0, QSPI_RETRIEVED},
+ {QSPI_BUF1CR, 0, QSPI_RETRIEVED},
+ {QSPI_BUF2CR, 0, QSPI_RETRIEVED},
+ {QSPI_BUF3CR, 0, QSPI_RETRIEVED},
+ {QSPI_BFGENCR, 0, QSPI_RETRIEVED},
+ {QSPI_BUF0IND, 0, QSPI_RETRIEVED},
+ {QSPI_BUF1IND, 0, QSPI_RETRIEVED},
+ {QSPI_BUF2IND, 0, QSPI_RETRIEVED},
+ {QSPI_SFAR, 0, QSPI_RETRIEVED},
+ {QSPI_SMPR, 0, QSPI_RETRIEVED},
+ {QSPI_RBSR, 0, QSPI_RETRIEVED},
+ {QSPI_RBCT, 0, QSPI_RETRIEVED},
+ {QSPI_TBSR, 0, QSPI_RETRIEVED},
+ {QSPI_TBDR, 0, QSPI_RETRIEVED},
+ {QSPI_SFA1AD, 0, QSPI_RETRIEVED},
+ {QSPI_SFA2AD, 0, QSPI_RETRIEVED},
+ {QSPI_SFB1AD, 0, QSPI_RETRIEVED},
+ {QSPI_SFB2AD, 0, QSPI_RETRIEVED},
+ {QSPI_RBDR_(0), 0, QSPI_RETRIEVED},
+ {QSPI_RBDR_(1), 0, QSPI_RETRIEVED},
+ {QSPI_RBDR_(2), 0, QSPI_RETRIEVED},
+ {QSPI_RBDR_(3), 0, QSPI_RETRIEVED},
+ {QSPI_RBDR_(4), 0, QSPI_RETRIEVED},
+ {QSPI_RBDR_(5), 0, QSPI_RETRIEVED},
+ {QSPI_RBDR_(6), 0, QSPI_RETRIEVED},
+ {QSPI_RBDR_(7), 0, QSPI_RETRIEVED},
+ {QSPI_RBDR_(8), 0, QSPI_RETRIEVED},
+ {QSPI_RBDR_(9), 0, QSPI_RETRIEVED},
+ {QSPI_RBDR_(10), 0, QSPI_RETRIEVED},
+ {QSPI_RBDR_(11), 0, QSPI_RETRIEVED},
+ {QSPI_RBDR_(12), 0, QSPI_RETRIEVED},
+ {QSPI_RBDR_(13), 0, QSPI_RETRIEVED},
+ {QSPI_RBDR_(14), 0, QSPI_RETRIEVED},
+ {QSPI_RBDR_(15), 0, QSPI_RETRIEVED},
+ {QSPI_RBDR_(16), 0, QSPI_RETRIEVED},
+ {QSPI_RBDR_(17), 0, QSPI_RETRIEVED},
+ {QSPI_RBDR_(18), 0, QSPI_RETRIEVED},
+ {QSPI_RBDR_(19), 0, QSPI_RETRIEVED},
+ {QSPI_RBDR_(20), 0, QSPI_RETRIEVED},
+ {QSPI_RBDR_(21), 0, QSPI_RETRIEVED},
+ {QSPI_RBDR_(22), 0, QSPI_RETRIEVED},
+ {QSPI_RBDR_(23), 0, QSPI_RETRIEVED},
+ {QSPI_RBDR_(24), 0, QSPI_RETRIEVED},
+ {QSPI_RBDR_(25), 0, QSPI_RETRIEVED},
+ {QSPI_RBDR_(26), 0, QSPI_RETRIEVED},
+ {QSPI_RBDR_(27), 0, QSPI_RETRIEVED},
+ {QSPI_RBDR_(28), 0, QSPI_RETRIEVED},
+ {QSPI_RBDR_(29), 0, QSPI_RETRIEVED},
+ {QSPI_RBDR_(30), 0, QSPI_RETRIEVED},
+ {QSPI_RBDR_(31), 0, QSPI_RETRIEVED},
+ {QSPI_LUTKEY, QSPI_LUTKEY_VALUE, QSPI_PREDEFINED},
+ {QSPI_LCKCR, QSPI_LCKER_UNLOCK, QSPI_PREDEFINED},
+ {QSPI_LUT(0), 0, QSPI_RETRIEVED},
+ {QSPI_LUT(1), 0, QSPI_RETRIEVED},
+ {QSPI_LUT(2), 0, QSPI_RETRIEVED},
+ {QSPI_LUT(3), 0, QSPI_RETRIEVED},
+ {QSPI_LUT(4), 0, QSPI_RETRIEVED},
+ {QSPI_LUT(5), 0, QSPI_RETRIEVED},
+ {QSPI_LUT(6), 0, QSPI_RETRIEVED},
+ {QSPI_LUT(7), 0, QSPI_RETRIEVED},
+ {QSPI_LUT(8), 0, QSPI_RETRIEVED},
+ {QSPI_LUT(9), 0, QSPI_RETRIEVED},
+ {QSPI_LUT(10), 0, QSPI_RETRIEVED},
+ {QSPI_LUT(11), 0, QSPI_RETRIEVED},
+ {QSPI_LUT(12), 0, QSPI_RETRIEVED},
+ {QSPI_LUT(13), 0, QSPI_RETRIEVED},
+ {QSPI_LUT(14), 0, QSPI_RETRIEVED},
+ {QSPI_LUT(15), 0, QSPI_RETRIEVED},
+ {QSPI_LUT(16), 0, QSPI_RETRIEVED},
+ {QSPI_LUT(17), 0, QSPI_RETRIEVED},
+ {QSPI_LUT(18), 0, QSPI_RETRIEVED},
+ {QSPI_LUT(19), 0, QSPI_RETRIEVED},
+ {QSPI_LUT(20), 0, QSPI_RETRIEVED},
+ {QSPI_LUT(21), 0, QSPI_RETRIEVED},
+ {QSPI_LUT(22), 0, QSPI_RETRIEVED},
+ {QSPI_LUT(23), 0, QSPI_RETRIEVED},
+ {QSPI_LUT(24), 0, QSPI_RETRIEVED},
+ {QSPI_LUT(25), 0, QSPI_RETRIEVED},
+ {QSPI_LUT(26), 0, QSPI_RETRIEVED},
+ {QSPI_LUT(27), 0, QSPI_RETRIEVED},
+ {QSPI_LUT(28), 0, QSPI_RETRIEVED},
+ {QSPI_LUT(29), 0, QSPI_RETRIEVED},
+ {QSPI_LUT(30), 0, QSPI_RETRIEVED},
+ {QSPI_LUT(31), 0, QSPI_RETRIEVED},
+ {QSPI_LUT(32), 0, QSPI_RETRIEVED},
+ {QSPI_LUT(33), 0, QSPI_RETRIEVED},
+ {QSPI_LUT(34), 0, QSPI_RETRIEVED},
+ {QSPI_LUT(35), 0, QSPI_RETRIEVED},
+ {QSPI_LUT(36), 0, QSPI_RETRIEVED},
+ {QSPI_LUT(37), 0, QSPI_RETRIEVED},
+ {QSPI_LUT(38), 0, QSPI_RETRIEVED},
+ {QSPI_LUT(39), 0, QSPI_RETRIEVED},
+ {QSPI_LUT(40), 0, QSPI_RETRIEVED},
+ {QSPI_LUT(41), 0, QSPI_RETRIEVED},
+ {QSPI_LUT(42), 0, QSPI_RETRIEVED},
+ {QSPI_LUT(43), 0, QSPI_RETRIEVED},
+ {QSPI_LUT(44), 0, QSPI_RETRIEVED},
+ {QSPI_LUT(45), 0, QSPI_RETRIEVED},
+ {QSPI_LUT(46), 0, QSPI_RETRIEVED},
+ {QSPI_LUT(47), 0, QSPI_RETRIEVED},
+ {QSPI_LUT(48), 0, QSPI_RETRIEVED},
+ {QSPI_LUT(49), 0, QSPI_RETRIEVED},
+ {QSPI_LUT(50), 0, QSPI_RETRIEVED},
+ {QSPI_LUT(51), 0, QSPI_RETRIEVED},
+ {QSPI_LUT(52), 0, QSPI_RETRIEVED},
+ {QSPI_LUT(53), 0, QSPI_RETRIEVED},
+ {QSPI_LUT(54), 0, QSPI_RETRIEVED},
+ {QSPI_LUT(55), 0, QSPI_RETRIEVED},
+ {QSPI_LUT(56), 0, QSPI_RETRIEVED},
+ {QSPI_LUT(57), 0, QSPI_RETRIEVED},
+ {QSPI_LUT(58), 0, QSPI_RETRIEVED},
+ {QSPI_LUT(59), 0, QSPI_RETRIEVED},
+ {QSPI_LUT(60), 0, QSPI_RETRIEVED},
+ {QSPI_LUT(61), 0, QSPI_RETRIEVED},
+ {QSPI_LUT(62), 0, QSPI_RETRIEVED},
+ {QSPI_LUT(63), 0, QSPI_RETRIEVED},
+ {QSPI_LUTKEY, QSPI_LUTKEY_VALUE, QSPI_PREDEFINED},
+ {QSPI_LCKCR, QSPI_LCKER_LOCK, QSPI_PREDEFINED},
+ {QSPI_MCR, 0, QSPI_RETRIEVED},
+};
+static unsigned int *ocram_saved_in_ddr;
+static void __iomem *ocram_base;
+static void __iomem *console_base;
+static void __iomem *qspi_base;
+static unsigned int ocram_size;
static void __iomem *ccm_base;
static void __iomem *suspend_ocram_base;
static void (*imx6_suspend_in_ocram_fn)(void __iomem *ocram_vbase);
+struct regmap *romcp;
/*
* suspend ocram space layout:
@@ -96,6 +304,8 @@ struct imx6_pm_socdata {
const char *pl310_compat;
const u32 mmdc_io_num;
const u32 *mmdc_io_offset;
+ const u32 mmdc_num;
+ const u32 *mmdc_offset;
};
static const u32 imx6q_mmdc_io_offset[] __initconst = {
@@ -110,6 +320,18 @@ static const u32 imx6q_mmdc_io_offset[] __initconst = {
0x74c, /* GPR_ADDS */
};
+static const u32 imx6q_mmdc_io_lpddr2_offset[] __initconst = {
+ 0x5ac, 0x5b4, 0x528, 0x520, /* DQM0 ~ DQM3 */
+ 0x514, 0x510, 0x5bc, 0x5c4, /* DQM4 ~ DQM7 */
+ 0x784, 0x788, 0x794, 0x79c, /* GPR_B0DS ~ GPR_B3DS */
+ 0x7a0, 0x7a4, 0x7a8, 0x748, /* GPR_B4DS ~ GPR_B7DS */
+ 0x56c, 0x578, 0x588, 0x594, /* CAS, RAS, SDCLK_0, SDCLK_1 */
+ 0x5a8, 0x5b0, 0x524, 0x51c, /* SDQS0 ~ SDQS3 */
+ 0x518, 0x50c, 0x5b8, 0x5c0, /* SDQS4 ~ SDQS7 */
+ 0x59c, 0x5a0, 0x750, 0x774, /* SODT0, SODT1, MODE_CTL, MODE */
+ 0x74c, 0x590, 0x598, 0x57c, /* GRP_ADDS, SDCKE0, SDCKE1, RESET */
+};
+
static const u32 imx6dl_mmdc_io_offset[] __initconst = {
0x470, 0x474, 0x478, 0x47c, /* DQM0 ~ DQM3 */
0x480, 0x484, 0x488, 0x48c, /* DQM4 ~ DQM7 */
@@ -130,6 +352,27 @@ static const u32 imx6sl_mmdc_io_offset[] __initconst = {
0x330, 0x334, 0x320, /* SDCKE0, SDCKE1, RESET */
};
+static const u32 imx6sx_mmdc_io_lpddr2_offset[] __initconst = {
+ 0x2ec, 0x2f0, 0x2f4, 0x2f8, /* DQM0 ~ DQM3 */
+ 0x300, 0x2fc, 0x32c, 0x5f4, /* CAS, RAS, SDCLK_0, GPR_ADDS */
+ 0x60c, 0x610, 0x61c, 0x620, /* GPR_B0DS ~ GPR_B3DS */
+ 0x310, 0x314, 0x5f8, 0x608, /* SODT0, SODT1, MODE_CTL, MODE */
+ 0x330, 0x334, 0x338, 0x33c, /* SDQS0 ~ SDQS3 */
+ 0x324, 0x328, 0x340, /* DRAM_SDCKE0 ~ 1, DRAM_RESET */
+};
+
+static const u32 imx6sx_mmdc_lpddr2_offset[] __initconst = {
+ 0x01c, 0x85c, 0x800, 0x890,
+ 0x8b8, 0x81c, 0x820, 0x824,
+ 0x828, 0x82c, 0x830, 0x834,
+ 0x838, 0x848, 0x850, 0x8c0,
+ 0x83c, 0x840, 0x8b8, 0x00c,
+ 0x004, 0x010, 0x014, 0x018,
+ 0x02c, 0x030, 0x038, 0x008,
+ 0x040, 0x000, 0x020, 0x818,
+ 0x800, 0x004, 0x01c,
+};
+
static const u32 imx6sx_mmdc_io_offset[] __initconst = {
0x2ec, 0x2f0, 0x2f4, 0x2f8, /* DQM0 ~ DQM3 */
0x60c, 0x610, 0x61c, 0x620, /* GPR_B0DS ~ GPR_B3DS */
@@ -138,6 +381,16 @@ static const u32 imx6sx_mmdc_io_offset[] __initconst = {
0x330, 0x334, 0x338, 0x33c, /* SDQS0 ~ SDQS3 */
};
+static const u32 imx6sx_mmdc_offset[] __initconst = {
+ 0x800, 0x80c, 0x810, 0x83c,
+ 0x840, 0x848, 0x850, 0x81c,
+ 0x820, 0x824, 0x828, 0x8b8,
+ 0x004, 0x008, 0x00c, 0x010,
+ 0x014, 0x018, 0x01c, 0x02c,
+ 0x030, 0x040, 0x000, 0x01c,
+ 0x020, 0x818, 0x01c,
+};
+
static const u32 imx6ul_mmdc_io_offset[] __initconst = {
0x244, 0x248, 0x24c, 0x250, /* DQM0, DQM1, RAS, CAS */
0x27c, 0x498, 0x4a4, 0x490, /* SDCLK0, GPR_B0DS-B1DS, GPR_ADDS */
@@ -145,6 +398,53 @@ static const u32 imx6ul_mmdc_io_offset[] __initconst = {
0x494, 0x4b0, /* MODE_CTL, MODE, */
};
+static const u32 imx6ul_mmdc_offset[] __initconst = {
+ 0x01c, 0x800, 0x80c, 0x83c,
+ 0x848, 0x850, 0x81c, 0x820,
+ 0x82c, 0x830, 0x8c0, 0x8b8,
+ 0x004, 0x008, 0x00c, 0x010,
+ 0x014, 0x018, 0x01c, 0x02c,
+ 0x030, 0x040, 0x000, 0x01c,
+ 0x020, 0x818, 0x01c,
+};
+
+static const u32 imx6ul_mmdc_io_lpddr2_offset[] __initconst = {
+ 0x244, 0x248, 0x24c, 0x250, /* DQM0, DQM1, RAS, CAS */
+ 0x27c, 0x498, 0x4a4, 0x490, /* SDCLK0, GPR_B0DS-B1DS, GPR_ADDS */
+ 0x280, 0x284, 0x260, 0x264, /* SDQS0~1, SODT0, SODT1 */
+ 0x494, 0x4b0, 0x274, 0x278, /* MODE_CTL, MODE, SDCKE0, SDCKE1 */
+ 0x288, /* DRAM_RESET */
+};
+
+static const u32 imx6ul_mmdc_lpddr2_offset[] __initconst = {
+ 0x01c, 0x85c, 0x800, 0x890,
+ 0x8b8, 0x81c, 0x820, 0x82c,
+ 0x830, 0x83c, 0x848, 0x850,
+ 0x8c0, 0x8b8, 0x004, 0x008,
+ 0x00c, 0x010, 0x038, 0x014,
+ 0x018, 0x01c, 0x02c, 0x030,
+ 0x040, 0x000, 0x020, 0x818,
+ 0x800, 0x004, 0x01c,
+};
+
+static const u32 imx6sll_mmdc_io_offset[] __initconst = {
+ 0x294, 0x298, 0x29c, 0x2a0, /* DQM0 ~ DQM3 */
+ 0x544, 0x54c, 0x554, 0x558, /* GPR_B0DS ~ GPR_B3DS */
+ 0x530, 0x540, 0x2ac, 0x52c, /* MODE_CTL, MODE, SDCLK_0, GPR_ADDDS */
+ 0x2a4, 0x2a8, /* SDCKE0, SDCKE1*/
+};
+
+static const u32 imx6sll_mmdc_lpddr3_offset[] __initconst = {
+ 0x01c, 0x85c, 0x800, 0x890,
+ 0x8b8, 0x81c, 0x820, 0x82c,
+ 0x830, 0x83c, 0x848, 0x850,
+ 0x8c0, 0x8b8, 0x004, 0x008,
+ 0x00c, 0x010, 0x038, 0x014,
+ 0x018, 0x01c, 0x02c, 0x030,
+ 0x040, 0x000, 0x020, 0x818,
+ 0x800, 0x004, 0x01c,
+};
+
static const struct imx6_pm_socdata imx6q_pm_data __initconst = {
.mmdc_compat = "fsl,imx6q-mmdc",
.src_compat = "fsl,imx6q-src",
@@ -153,6 +453,19 @@ static const struct imx6_pm_socdata imx6q_pm_data __initconst = {
.pl310_compat = "arm,pl310-cache",
.mmdc_io_num = ARRAY_SIZE(imx6q_mmdc_io_offset),
.mmdc_io_offset = imx6q_mmdc_io_offset,
+ .mmdc_num = 0,
+ .mmdc_offset = NULL,
+};
+
+static const struct imx6_pm_socdata imx6q_lpddr2_pm_data __initconst = {
+ .mmdc_compat = "fsl,imx6q-mmdc",
+ .src_compat = "fsl,imx6q-src",
+ .iomuxc_compat = "fsl,imx6q-iomuxc",
+ .gpc_compat = "fsl,imx6q-gpc",
+ .mmdc_io_num = ARRAY_SIZE(imx6q_mmdc_io_lpddr2_offset),
+ .mmdc_io_offset = imx6q_mmdc_io_lpddr2_offset,
+ .mmdc_num = 0,
+ .mmdc_offset = NULL,
};
static const struct imx6_pm_socdata imx6dl_pm_data __initconst = {
@@ -163,6 +476,8 @@ static const struct imx6_pm_socdata imx6dl_pm_data __initconst = {
.pl310_compat = "arm,pl310-cache",
.mmdc_io_num = ARRAY_SIZE(imx6dl_mmdc_io_offset),
.mmdc_io_offset = imx6dl_mmdc_io_offset,
+ .mmdc_num = 0,
+ .mmdc_offset = NULL,
};
static const struct imx6_pm_socdata imx6sl_pm_data __initconst = {
@@ -173,6 +488,8 @@ static const struct imx6_pm_socdata imx6sl_pm_data __initconst = {
.pl310_compat = "arm,pl310-cache",
.mmdc_io_num = ARRAY_SIZE(imx6sl_mmdc_io_offset),
.mmdc_io_offset = imx6sl_mmdc_io_offset,
+ .mmdc_num = 0,
+ .mmdc_offset = NULL,
};
static const struct imx6_pm_socdata imx6sx_pm_data __initconst = {
@@ -183,6 +500,19 @@ static const struct imx6_pm_socdata imx6sx_pm_data __initconst = {
.pl310_compat = "arm,pl310-cache",
.mmdc_io_num = ARRAY_SIZE(imx6sx_mmdc_io_offset),
.mmdc_io_offset = imx6sx_mmdc_io_offset,
+ .mmdc_num = ARRAY_SIZE(imx6sx_mmdc_offset),
+ .mmdc_offset = imx6sx_mmdc_offset,
+};
+
+static const struct imx6_pm_socdata imx6sx_lpddr2_pm_data __initconst = {
+ .mmdc_compat = "fsl,imx6sx-mmdc",
+ .src_compat = "fsl,imx6sx-src",
+ .iomuxc_compat = "fsl,imx6sx-iomuxc",
+ .gpc_compat = "fsl,imx6sx-gpc",
+ .mmdc_io_num = ARRAY_SIZE(imx6sx_mmdc_io_lpddr2_offset),
+ .mmdc_io_offset = imx6sx_mmdc_io_lpddr2_offset,
+ .mmdc_num = ARRAY_SIZE(imx6sx_mmdc_lpddr2_offset),
+ .mmdc_offset = imx6sx_mmdc_lpddr2_offset,
};
static const struct imx6_pm_socdata imx6ul_pm_data __initconst = {
@@ -193,6 +523,61 @@ static const struct imx6_pm_socdata imx6ul_pm_data __initconst = {
.pl310_compat = NULL,
.mmdc_io_num = ARRAY_SIZE(imx6ul_mmdc_io_offset),
.mmdc_io_offset = imx6ul_mmdc_io_offset,
+ .mmdc_num = ARRAY_SIZE(imx6ul_mmdc_offset),
+ .mmdc_offset = imx6ul_mmdc_offset,
+};
+
+static const struct imx6_pm_socdata imx6ul_lpddr2_pm_data __initconst = {
+ .mmdc_compat = "fsl,imx6ul-mmdc",
+ .src_compat = "fsl,imx6ul-src",
+ .iomuxc_compat = "fsl,imx6ul-iomuxc",
+ .gpc_compat = "fsl,imx6ul-gpc",
+ .mmdc_io_num = ARRAY_SIZE(imx6ul_mmdc_io_lpddr2_offset),
+ .mmdc_io_offset = imx6ul_mmdc_io_lpddr2_offset,
+ .mmdc_num = ARRAY_SIZE(imx6ul_mmdc_lpddr2_offset),
+ .mmdc_offset = imx6ul_mmdc_lpddr2_offset,
+};
+
+static const struct imx6_pm_socdata imx6sll_pm_data __initconst = {
+ .mmdc_compat = "fsl,imx6sll-mmdc",
+ .src_compat = "fsl,imx6sll-src",
+ .iomuxc_compat = "fsl,imx6sll-iomuxc",
+ .gpc_compat = "fsl,imx6sll-gpc",
+ .mmdc_io_num = ARRAY_SIZE(imx6sll_mmdc_io_offset),
+ .mmdc_io_offset = imx6sll_mmdc_io_offset,
+ .mmdc_num = ARRAY_SIZE(imx6sll_mmdc_lpddr3_offset),
+ .mmdc_offset = imx6sll_mmdc_lpddr3_offset,
+};
+
+static struct map_desc iram_tlb_io_desc __initdata = {
+ /* .virtual and .pfn are run-time assigned */
+ .length = SZ_1M,
+ .type = MT_MEMORY_RWX_NONCACHED,
+};
+
+/*
+ * AIPS1 and AIPS2 is not used, because it will trigger a BUG_ON if
+ * lowlevel debug and earlyprintk are configured.
+ *
+ * it is because there is a vm conflict because UART1 is mapped early if
+ * AIPS1 is mapped using 1M size.
+ *
+ * Thus no use AIPS1 and AIPS2 to avoid kernel BUG_ON.
+ */
+static struct map_desc imx6_pm_io_desc[] __initdata = {
+ imx_map_entry(MX6Q, MMDC_P0, MT_DEVICE),
+ imx_map_entry(MX6Q, MMDC_P1, MT_DEVICE),
+ imx_map_entry(MX6Q, SRC, MT_DEVICE),
+ imx_map_entry(MX6Q, IOMUXC, MT_DEVICE),
+ imx_map_entry(MX6Q, CCM, MT_DEVICE),
+ imx_map_entry(MX6Q, ANATOP, MT_DEVICE),
+ imx_map_entry(MX6Q, GPC, MT_DEVICE),
+ imx_map_entry(MX6Q, L2, MT_DEVICE),
+};
+
+static const char * const low_power_ocram_match[] __initconst = {
+ "fsl,lpm-sram",
+ NULL
};
/*
@@ -207,14 +592,19 @@ struct imx6_cpu_pm_info {
phys_addr_t resume_addr; /* The physical resume address for asm code */
u32 ddr_type;
u32 pm_info_size; /* Size of pm_info. */
- struct imx6_pm_base mmdc_base;
+ struct imx6_pm_base mmdc0_base;
+ struct imx6_pm_base mmdc1_base;
struct imx6_pm_base src_base;
struct imx6_pm_base iomuxc_base;
struct imx6_pm_base ccm_base;
struct imx6_pm_base gpc_base;
struct imx6_pm_base l2_base;
+ struct imx6_pm_base anatop_base;
+ u32 ttbr1; /* Store TTBR1 */
u32 mmdc_io_num; /* Number of MMDC IOs which need saved/restored. */
- u32 mmdc_io_val[MX6_MAX_MMDC_IO_NUM][2]; /* To save offset and value */
+ u32 mmdc_io_val[MX6_MAX_MMDC_IO_NUM][3]; /* To save offset, value, low power settings */
+ u32 mmdc_num; /* Number of MMDC registers which need saved/restored. */
+ u32 mmdc_val[MX6_MAX_MMDC_NUM][2];
} __aligned(8);
void imx6_set_int_mem_clk_lpm(bool enable)
@@ -293,11 +683,18 @@ int imx6_set_lpm(enum mxc_cpu_pwr_mode mode)
val |= 0x2 << BP_CLPCR_LPM;
val &= ~BM_CLPCR_VSTBY;
val &= ~BM_CLPCR_SBYOS;
- if (cpu_is_imx6sl())
+ if (cpu_is_imx6sl() || cpu_is_imx6sx() || cpu_is_imx6sll())
val |= BM_CLPCR_BYPASS_PMIC_READY;
if (cpu_is_imx6sl() || cpu_is_imx6sx() || cpu_is_imx6ul() ||
- cpu_is_imx6ull())
+ cpu_is_imx6ull() || cpu_is_imx6sll())
val |= BM_CLPCR_BYP_MMDC_CH0_LPM_HS;
+ else if (cpu_is_imx6q() &&
+ imx_mmdc_get_ddr_type() == IMX_DDR_TYPE_LPDDR2 &&
+ imx_mmdc_get_lpddr2_2ch_mode() == IMX_LPDDR2_2CH_MODE) {
+ /* keep handshake enabled for lpddr2 2ch-mode */
+ val &= ~BM_CLPCR_BYP_MMDC_CH0_LPM_HS;
+ val &= ~BM_CLPCR_BYP_MMDC_CH1_LPM_HS;
+ }
else
val |= BM_CLPCR_BYP_MMDC_CH1_LPM_HS;
break;
@@ -311,11 +708,18 @@ int imx6_set_lpm(enum mxc_cpu_pwr_mode mode)
val |= 0x3 << BP_CLPCR_STBY_COUNT;
val |= BM_CLPCR_VSTBY;
val |= BM_CLPCR_SBYOS;
- if (cpu_is_imx6sl() || cpu_is_imx6sx())
+ if (cpu_is_imx6sl() || cpu_is_imx6sx() || cpu_is_imx6sll())
val |= BM_CLPCR_BYPASS_PMIC_READY;
if (cpu_is_imx6sl() || cpu_is_imx6sx() || cpu_is_imx6ul() ||
- cpu_is_imx6ull())
+ cpu_is_imx6ull() || cpu_is_imx6sll())
val |= BM_CLPCR_BYP_MMDC_CH0_LPM_HS;
+ else if (cpu_is_imx6q() &&
+ imx_mmdc_get_ddr_type() == IMX_DDR_TYPE_LPDDR2 &&
+ imx_mmdc_get_lpddr2_2ch_mode() == IMX_LPDDR2_2CH_MODE) {
+ /* keep handshake enabled for lpddr2 2ch-mode */
+ val &= ~BM_CLPCR_BYP_MMDC_CH0_LPM_HS;
+ val &= ~BM_CLPCR_BYP_MMDC_CH1_LPM_HS;
+ }
else
val |= BM_CLPCR_BYP_MMDC_CH1_LPM_HS;
break;
@@ -337,15 +741,27 @@ int imx6_set_lpm(enum mxc_cpu_pwr_mode mode)
*
* Note that IRQ #32 is GIC SPI #0.
*/
- imx_gpc_hwirq_unmask(0);
+ if (mode != WAIT_CLOCKED)
+ imx_gpc_hwirq_unmask(0);
writel_relaxed(val, ccm_base + CLPCR);
- imx_gpc_hwirq_mask(0);
+ if (mode != WAIT_CLOCKED)
+ imx_gpc_hwirq_mask(0);
return 0;
}
+#define MX6Q_SUSPEND_PARAM \
+ ((0 << PSCI_0_2_POWER_STATE_ID_SHIFT) | \
+ (1 << PSCI_0_2_POWER_STATE_AFFL_SHIFT) | \
+ (PSCI_POWER_STATE_TYPE_POWER_DOWN << PSCI_0_2_POWER_STATE_TYPE_SHIFT))
+
static int imx6q_suspend_finish(unsigned long val)
{
+ if (psci_ops.cpu_suspend) {
+ return psci_ops.cpu_suspend(MX6Q_SUSPEND_PARAM,
+ __pa(cpu_resume));
+ }
+
if (!imx6_suspend_in_ocram_fn) {
cpu_do_idle();
} else {
@@ -364,19 +780,104 @@ static int imx6q_suspend_finish(unsigned long val)
return 0;
}
+static void imx6_console_save(unsigned int *regs)
+{
+ if (!console_base)
+ return;
+
+ regs[0] = readl_relaxed(console_base + UART_UCR1);
+ regs[1] = readl_relaxed(console_base + UART_UCR2);
+ regs[2] = readl_relaxed(console_base + UART_UCR3);
+ regs[3] = readl_relaxed(console_base + UART_UCR4);
+ regs[4] = readl_relaxed(console_base + UART_UFCR);
+ regs[5] = readl_relaxed(console_base + UART_UESC);
+ regs[6] = readl_relaxed(console_base + UART_UTIM);
+ regs[7] = readl_relaxed(console_base + UART_UBIR);
+ regs[8] = readl_relaxed(console_base + UART_UBMR);
+ regs[9] = readl_relaxed(console_base + UART_UTS);
+}
+
+static void imx6_console_restore(unsigned int *regs)
+{
+ if (!console_base)
+ return;
+
+ writel_relaxed(regs[4], console_base + UART_UFCR);
+ writel_relaxed(regs[5], console_base + UART_UESC);
+ writel_relaxed(regs[6], console_base + UART_UTIM);
+ writel_relaxed(regs[7], console_base + UART_UBIR);
+ writel_relaxed(regs[8], console_base + UART_UBMR);
+ writel_relaxed(regs[9], console_base + UART_UTS);
+ writel_relaxed(regs[0], console_base + UART_UCR1);
+ writel_relaxed(regs[1] | 0x1, console_base + UART_UCR2);
+ writel_relaxed(regs[2], console_base + UART_UCR3);
+ writel_relaxed(regs[3], console_base + UART_UCR4);
+}
+
+static void imx6_qspi_save(struct qspi_regs *pregs, int reg_num)
+{
+ int i;
+
+ if (!qspi_base)
+ return;
+
+ for (i = 0; i < reg_num; i++) {
+ if (QSPI_RETRIEVED == pregs[i].valuetype)
+ pregs[i].value = readl_relaxed(qspi_base +
+ pregs[i].offset);
+ }
+}
+
+static void imx6_qspi_restore(struct qspi_regs *pregs, int reg_num)
+{
+ int i;
+
+ if (!qspi_base)
+ return;
+
+ for (i = 0; i < reg_num; i++)
+ writel_relaxed(pregs[i].value, qspi_base + pregs[i].offset);
+}
+
static int imx6q_pm_enter(suspend_state_t state)
{
+ unsigned int console_saved_reg[10] = {0};
+ static unsigned int ccm_ccgr4, ccm_ccgr6;
+
+#ifdef CONFIG_SOC_IMX6SX
+ if (imx_src_is_m4_enabled()) {
+ if (imx_gpc_is_m4_sleeping() && imx_mu_is_m4_in_low_freq()) {
+ imx_gpc_hold_m4_in_sleep();
+ imx_mu_enable_m4_irqs_in_gic(true);
+ } else {
+ pr_info("M4 is busy, enter WAIT mode instead of STOP!\n");
+ imx6_set_lpm(WAIT_UNCLOCKED);
+ imx6_set_int_mem_clk_lpm(true);
+ imx_gpc_pre_suspend(false);
+ /* Zzz ... */
+ cpu_do_idle();
+ imx_gpc_post_resume();
+ imx6_set_lpm(WAIT_CLOCKED);
+
+ return 0;
+ }
+ }
+#endif
switch (state) {
case PM_SUSPEND_STANDBY:
imx6_set_lpm(STOP_POWER_ON);
imx6_set_int_mem_clk_lpm(true);
imx_gpc_pre_suspend(false);
+#ifdef CONFIG_SOC_IMX6SL
if (cpu_is_imx6sl())
imx6sl_set_wait_clk(true);
+#endif
/* Zzz ... */
cpu_do_idle();
+#ifdef CONFIG_SOC_IMX6SL
if (cpu_is_imx6sl())
imx6sl_set_wait_clk(false);
+#endif
imx_gpc_post_resume();
imx6_set_lpm(WAIT_CLOCKED);
break;
@@ -392,8 +893,50 @@ static int imx6q_pm_enter(suspend_state_t state)
imx6_enable_rbc(true);
imx_gpc_pre_suspend(true);
imx_anatop_pre_suspend();
+ if ((cpu_is_imx6ull() || cpu_is_imx6sll()) &&
+ imx_gpc_is_mf_mix_off())
+ imx6_console_save(console_saved_reg);
+ if (cpu_is_imx6sx() && imx_gpc_is_mf_mix_off()) {
+ ccm_ccgr4 = readl_relaxed(ccm_base + CCGR4);
+ ccm_ccgr6 = readl_relaxed(ccm_base + CCGR6);
+ /*
+ * i.MX6SX RDC needs PCIe and eim clk to be enabled
+ * if Mega/Fast off, it is better to check cpu type
+ * and whether Mega/Fast is off in this suspend flow,
+ * but we need to add cpu type check for 3 places which
+ * will increase code size, so here we just do it
+ * for all cases, as when STOP mode is entered, CCM
+ * hardware will gate all clocks, so it will NOT impact
+ * any function or power.
+ */
+ writel_relaxed(ccm_ccgr4 | (0x3 << 0), ccm_base +
+ CCGR4);
+ writel_relaxed(ccm_ccgr6 | (0x3 << 10), ccm_base +
+ CCGR6);
+ memcpy(ocram_saved_in_ddr, ocram_base, ocram_size);
+ imx6_console_save(console_saved_reg);
+ if (imx_src_is_m4_enabled())
+ imx6_qspi_save(qspi_regs_imx6sx,
+ sizeof(qspi_regs_imx6sx) /
+ sizeof(struct qspi_regs));
+ }
+
/* Zzz ... */
cpu_suspend(0, imx6q_suspend_finish);
+
+ if (cpu_is_imx6sx() && imx_gpc_is_mf_mix_off()) {
+ writel_relaxed(ccm_ccgr4, ccm_base + CCGR4);
+ writel_relaxed(ccm_ccgr6, ccm_base + CCGR6);
+ memcpy(ocram_base, ocram_saved_in_ddr, ocram_size);
+ imx6_console_restore(console_saved_reg);
+ if (imx_src_is_m4_enabled())
+ imx6_qspi_restore(qspi_regs_imx6sx,
+ sizeof(qspi_regs_imx6sx) /
+ sizeof(struct qspi_regs));
+ }
+ if ((cpu_is_imx6ull() || cpu_is_imx6sll()) &&
+ imx_gpc_is_mf_mix_off())
+ imx6_console_restore(console_saved_reg);
if (cpu_is_imx6q() || cpu_is_imx6dl())
imx_smp_prepare();
imx_anatop_post_resume();
@@ -407,6 +950,13 @@ static int imx6q_pm_enter(suspend_state_t state)
return -EINVAL;
}
+#ifdef CONFIG_SOC_IMX6SX
+ if (imx_src_is_m4_enabled()) {
+ imx_mu_enable_m4_irqs_in_gic(false);
+ imx_gpc_release_m4_in_sleep();
+ }
+#endif
+
return 0;
}
@@ -420,44 +970,114 @@ static const struct platform_suspend_ops imx6q_pm_ops = {
.valid = imx6q_pm_valid,
};
-static int __init imx6_pm_get_base(struct imx6_pm_base *base,
- const char *compat)
+static int __init imx6_dt_find_lpsram(unsigned long node, const char *uname,
+ int depth, void *data)
{
- struct device_node *node;
- struct resource res;
- int ret = 0;
+ unsigned long lpram_addr;
+ const __be32 *prop = of_get_flat_dt_prop(node, "reg", NULL);
+
+ if (of_flat_dt_match(node, low_power_ocram_match)) {
+ if (!prop)
+ return -EINVAL;
+
+ lpram_addr = be32_to_cpup(prop);
+
+ /* We need to create a 1M page table entry. */
+ iram_tlb_io_desc.virtual = IMX_IO_P2V(lpram_addr & 0xFFF00000);
+ iram_tlb_io_desc.pfn = __phys_to_pfn(lpram_addr & 0xFFF00000);
+ iram_tlb_phys_addr = lpram_addr;
+ iram_tlb_base_addr = IMX_IO_P2V(lpram_addr);
- node = of_find_compatible_node(NULL, NULL, compat);
- if (!node) {
- ret = -ENODEV;
- goto out;
+ iotable_init(&iram_tlb_io_desc, 1);
}
- ret = of_address_to_resource(node, 0, &res);
- if (ret)
- goto put_node;
+ return 0;
+}
- base->pbase = res.start;
- base->vbase = ioremap(res.start, resource_size(&res));
- if (!base->vbase)
- ret = -ENOMEM;
+void __init imx6_pm_map_io(void)
+{
+ unsigned long i;
-put_node:
- of_node_put(node);
-out:
- return ret;
+ iotable_init(imx6_pm_io_desc, ARRAY_SIZE(imx6_pm_io_desc));
+
+ /*
+ * Get the address of IRAM or OCRAM to be used by the low
+ * power code from the device tree.
+ */
+ WARN_ON(of_scan_flat_dt(imx6_dt_find_lpsram, NULL));
+
+ /*
+ * We moved suspend/resume and lowpower idle to TEE,
+ * But busfreq now still in Linux, this table is still needed
+ * If we later decide to move busfreq to TEE, we could drop this.
+ */
+ /* Return if no IRAM space is allocated for suspend/resume code. */
+ if (!iram_tlb_base_addr) {
+ pr_warn("No IRAM/OCRAM memory allocated for suspend/resume \
+ code. Please ensure device tree has an entry for \
+ fsl,lpm-sram.\n");
+ return;
+ }
+
+ /* Set all entries to 0. */
+ memset((void *)iram_tlb_base_addr, 0, MX6Q_IRAM_TLB_SIZE);
+
+ /*
+ * Make sure the IRAM virtual address has a mapping in the IRAM
+ * page table.
+ *
+ * Only use the top 11 bits [31-20] when storing the physical
+ * address in the page table as only these bits are required
+ * for 1M mapping.
+ */
+ i = ((iram_tlb_base_addr >> 20) << 2) / 4;
+ *((unsigned long *)iram_tlb_base_addr + i) =
+ (iram_tlb_phys_addr & 0xFFF00000) | TT_ATTRIB_NON_CACHEABLE_1M;
+
+ /*
+ * Make sure the AIPS1 virtual address has a mapping in the
+ * IRAM page table.
+ */
+ i = ((IMX_IO_P2V(MX6Q_AIPS1_BASE_ADDR) >> 20) << 2) / 4;
+ *((unsigned long *)iram_tlb_base_addr + i) =
+ (MX6Q_AIPS1_BASE_ADDR & 0xFFF00000) |
+ TT_ATTRIB_NON_CACHEABLE_1M;
+
+ /*
+ * Make sure the AIPS2 virtual address has a mapping in the
+ * IRAM page table.
+ */
+ i = ((IMX_IO_P2V(MX6Q_AIPS2_BASE_ADDR) >> 20) << 2) / 4;
+ *((unsigned long *)iram_tlb_base_addr + i) =
+ (MX6Q_AIPS2_BASE_ADDR & 0xFFF00000) |
+ TT_ATTRIB_NON_CACHEABLE_1M;
+
+ /*
+ * Make sure the AIPS3 virtual address has a mapping
+ * in the IRAM page table.
+ */
+ i = ((IMX_IO_P2V(MX6Q_AIPS3_BASE_ADDR) >> 20) << 2) / 4;
+ *((unsigned long *)iram_tlb_base_addr + i) =
+ (MX6Q_AIPS3_BASE_ADDR & 0xFFF00000) |
+ TT_ATTRIB_NON_CACHEABLE_1M;
+
+ /*
+ * Make sure the L2 controller virtual address has a mapping
+ * in the IRAM page table.
+ */
+ i = ((IMX_IO_P2V(MX6Q_L2_BASE_ADDR) >> 20) << 2) / 4;
+ *((unsigned long *)iram_tlb_base_addr + i) =
+ (MX6Q_L2_BASE_ADDR & 0xFFF00000) | TT_ATTRIB_NON_CACHEABLE_1M;
}
static int __init imx6q_suspend_init(const struct imx6_pm_socdata *socdata)
{
- phys_addr_t ocram_pbase;
struct device_node *node;
- struct platform_device *pdev;
struct imx6_cpu_pm_info *pm_info;
- struct gen_pool *ocram_pool;
- unsigned long ocram_base;
+ unsigned long iram_paddr;
int i, ret = 0;
const u32 *mmdc_offset_array;
+ const u32 *mmdc_io_offset_array;
suspend_set_ops(&imx6q_pm_ops);
@@ -466,41 +1086,30 @@ static int __init imx6q_suspend_init(const struct imx6_pm_socdata *socdata)
return -EINVAL;
}
- node = of_find_compatible_node(NULL, NULL, "mmio-sram");
- if (!node) {
- pr_warn("%s: failed to find ocram node!\n", __func__);
- return -ENODEV;
+ if (psci_ops.cpu_suspend) {
+ /* TODO: seems not needed */
+ /* of_node_put(node); */
+ return ret;
}
- pdev = of_find_device_by_node(node);
- if (!pdev) {
- pr_warn("%s: failed to find ocram device!\n", __func__);
- ret = -ENODEV;
- goto put_node;
- }
-
- ocram_pool = gen_pool_get(&pdev->dev, NULL);
- if (!ocram_pool) {
- pr_warn("%s: ocram pool unavailable!\n", __func__);
- ret = -ENODEV;
- goto put_node;
- }
-
- ocram_base = gen_pool_alloc(ocram_pool, MX6Q_SUSPEND_OCRAM_SIZE);
- if (!ocram_base) {
- pr_warn("%s: unable to alloc ocram!\n", __func__);
- ret = -ENOMEM;
- goto put_node;
- }
+ /*
+ * 16KB is allocated for IRAM TLB, but only up 8k is for kernel TLB,
+ * The lower 8K is not used, so use the lower 8K for IRAM code and
+ * pm_info.
+ *
+ */
+ iram_paddr = iram_tlb_phys_addr + MX6_SUSPEND_IRAM_ADDR_OFFSET;
- ocram_pbase = gen_pool_virt_to_phys(ocram_pool, ocram_base);
+ /* Make sure iram_paddr is 8 byte aligned. */
+ if ((uintptr_t)(iram_paddr) & (FNCPY_ALIGN - 1))
+ iram_paddr += FNCPY_ALIGN - iram_paddr % (FNCPY_ALIGN);
- suspend_ocram_base = __arm_ioremap_exec(ocram_pbase,
- MX6Q_SUSPEND_OCRAM_SIZE, false);
+ /* Get the virtual address of the suspend code. */
+ suspend_ocram_base = (void *)IMX_IO_P2V(iram_paddr);
memset(suspend_ocram_base, 0, sizeof(*pm_info));
pm_info = suspend_ocram_base;
- pm_info->pbase = ocram_pbase;
+ pm_info->pbase = iram_paddr;
pm_info->resume_addr = __pa_symbol(v7_cpu_resume);
pm_info->pm_info_size = sizeof(*pm_info);
@@ -508,53 +1117,120 @@ static int __init imx6q_suspend_init(const struct imx6_pm_socdata *socdata)
* ccm physical address is not used by asm code currently,
* so get ccm virtual address directly.
*/
- pm_info->ccm_base.vbase = ccm_base;
+ pm_info->ccm_base.pbase = MX6Q_CCM_BASE_ADDR;
+ pm_info->ccm_base.vbase = (void __iomem *)
+ IMX_IO_P2V(MX6Q_CCM_BASE_ADDR);
- ret = imx6_pm_get_base(&pm_info->mmdc_base, socdata->mmdc_compat);
- if (ret) {
- pr_warn("%s: failed to get mmdc base %d!\n", __func__, ret);
- goto put_node;
- }
+ pm_info->mmdc0_base.pbase = MX6Q_MMDC_P0_BASE_ADDR;
+ pm_info->mmdc0_base.vbase = (void __iomem *)
+ IMX_IO_P2V(MX6Q_MMDC_P0_BASE_ADDR);
- ret = imx6_pm_get_base(&pm_info->src_base, socdata->src_compat);
- if (ret) {
- pr_warn("%s: failed to get src base %d!\n", __func__, ret);
- goto src_map_failed;
- }
+ pm_info->mmdc1_base.pbase = MX6Q_MMDC_P1_BASE_ADDR;
+ pm_info->mmdc1_base.vbase = (void __iomem *)
+ IMX_IO_P2V(MX6Q_MMDC_P1_BASE_ADDR);
- ret = imx6_pm_get_base(&pm_info->iomuxc_base, socdata->iomuxc_compat);
- if (ret) {
- pr_warn("%s: failed to get iomuxc base %d!\n", __func__, ret);
- goto iomuxc_map_failed;
- }
+ pm_info->src_base.pbase = MX6Q_SRC_BASE_ADDR;
+ pm_info->src_base.vbase = (void __iomem *)
+ IMX_IO_P2V(MX6Q_SRC_BASE_ADDR);
- ret = imx6_pm_get_base(&pm_info->gpc_base, socdata->gpc_compat);
- if (ret) {
- pr_warn("%s: failed to get gpc base %d!\n", __func__, ret);
- goto gpc_map_failed;
- }
+ pm_info->iomuxc_base.pbase = MX6Q_IOMUXC_BASE_ADDR;
+ pm_info->iomuxc_base.vbase = (void __iomem *)
+ IMX_IO_P2V(MX6Q_IOMUXC_BASE_ADDR);
- if (socdata->pl310_compat) {
- ret = imx6_pm_get_base(&pm_info->l2_base, socdata->pl310_compat);
- if (ret) {
- pr_warn("%s: failed to get pl310-cache base %d!\n",
- __func__, ret);
- goto pl310_cache_map_failed;
- }
- }
+ pm_info->gpc_base.pbase = MX6Q_GPC_BASE_ADDR;
+ pm_info->gpc_base.vbase = (void __iomem *)
+ IMX_IO_P2V(MX6Q_GPC_BASE_ADDR);
+
+ pm_info->l2_base.pbase = MX6Q_L2_BASE_ADDR;
+ pm_info->l2_base.vbase = (void __iomem *)
+ IMX_IO_P2V(MX6Q_L2_BASE_ADDR);
+
+ pm_info->anatop_base.pbase = MX6Q_ANATOP_BASE_ADDR;
+ pm_info->anatop_base.vbase = (void __iomem *)
+ IMX_IO_P2V(MX6Q_ANATOP_BASE_ADDR);
pm_info->ddr_type = imx_mmdc_get_ddr_type();
pm_info->mmdc_io_num = socdata->mmdc_io_num;
- mmdc_offset_array = socdata->mmdc_io_offset;
+ mmdc_io_offset_array = socdata->mmdc_io_offset;
+ pm_info->mmdc_num = socdata->mmdc_num;
+ mmdc_offset_array = socdata->mmdc_offset;
for (i = 0; i < pm_info->mmdc_io_num; i++) {
pm_info->mmdc_io_val[i][0] =
- mmdc_offset_array[i];
+ mmdc_io_offset_array[i];
pm_info->mmdc_io_val[i][1] =
readl_relaxed(pm_info->iomuxc_base.vbase +
+ mmdc_io_offset_array[i]);
+ pm_info->mmdc_io_val[i][2] = 0;
+ }
+
+ /* i.MX6SLL has no DRAM RESET pin */
+ if (cpu_is_imx6sll()) {
+ pm_info->mmdc_io_val[pm_info->mmdc_io_num - 2][2] = 0x1000;
+ pm_info->mmdc_io_val[pm_info->mmdc_io_num - 1][2] = 0x1000;
+ } else {
+ if (pm_info->ddr_type == IMX_DDR_TYPE_LPDDR2) {
+ /* for LPDDR2, CKE0/1 and RESET pin need special setting */
+ pm_info->mmdc_io_val[pm_info->mmdc_io_num - 3][2] = 0x1000;
+ pm_info->mmdc_io_val[pm_info->mmdc_io_num - 2][2] = 0x1000;
+ pm_info->mmdc_io_val[pm_info->mmdc_io_num - 1][2] = 0x80000;
+ }
+ }
+
+ /* initialize MMDC settings */
+ for (i = 0; i < pm_info->mmdc_num; i++) {
+ pm_info->mmdc_val[i][0] =
+ mmdc_offset_array[i];
+ pm_info->mmdc_val[i][1] =
+ readl_relaxed(pm_info->mmdc0_base.vbase +
mmdc_offset_array[i]);
}
+ if (cpu_is_imx6sll() && pm_info->ddr_type == IMX_MMDC_DDR_TYPE_LPDDR3) {
+ pm_info->mmdc_val[0][1] = 0x8000;
+ pm_info->mmdc_val[2][1] = 0xa1390003;
+ pm_info->mmdc_val[3][1] = 0x400000;
+ pm_info->mmdc_val[4][1] = 0x800;
+ pm_info->mmdc_val[13][1] = 0x800;
+ pm_info->mmdc_val[14][1] = 0x20052;
+ pm_info->mmdc_val[20][1] = 0x201718;
+ pm_info->mmdc_val[21][1] = 0x8000;
+ pm_info->mmdc_val[28][1] = 0xa1310003;
+ }
+
+ /* need to overwrite the value for some mmdc registers */
+ if ((cpu_is_imx6sx() || cpu_is_imx6ul() || cpu_is_imx6ull()) &&
+ pm_info->ddr_type != IMX_DDR_TYPE_LPDDR2) {
+ pm_info->mmdc_val[20][1] = (pm_info->mmdc_val[20][1]
+ & 0xffff0000) | 0x0202;
+ pm_info->mmdc_val[23][1] = 0x8033;
+ }
+
+ if (cpu_is_imx6sx() &&
+ pm_info->ddr_type == IMX_DDR_TYPE_LPDDR2) {
+ pm_info->mmdc_val[0][1] = 0x8000;
+ pm_info->mmdc_val[2][1] = 0xa1390003;
+ pm_info->mmdc_val[3][1] = 0x380000;
+ pm_info->mmdc_val[4][1] = 0x800;
+ pm_info->mmdc_val[18][1] = 0x800;
+ pm_info->mmdc_val[20][1] = 0x20024;
+ pm_info->mmdc_val[23][1] = 0x1748;
+ pm_info->mmdc_val[32][1] = 0xa1310003;
+ }
+
+ if ((cpu_is_imx6ul() || cpu_is_imx6ull()) &&
+ pm_info->ddr_type == IMX_DDR_TYPE_LPDDR2) {
+ pm_info->mmdc_val[0][1] = 0x8000;
+ pm_info->mmdc_val[2][1] = 0xa1390003;
+ pm_info->mmdc_val[3][1] = 0x470000;
+ pm_info->mmdc_val[4][1] = 0x800;
+ pm_info->mmdc_val[13][1] = 0x800;
+ pm_info->mmdc_val[14][1] = 0x20012;
+ pm_info->mmdc_val[20][1] = 0x1748;
+ pm_info->mmdc_val[21][1] = 0x8000;
+ pm_info->mmdc_val[28][1] = 0xa1310003;
+ }
+
imx6_suspend_in_ocram_fn = fncpy(
suspend_ocram_base + sizeof(*pm_info),
&imx6_suspend,
@@ -562,14 +1238,6 @@ static int __init imx6q_suspend_init(const struct imx6_pm_socdata *socdata)
goto put_node;
-pl310_cache_map_failed:
- iounmap(pm_info->gpc_base.vbase);
-gpc_map_failed:
- iounmap(pm_info->iomuxc_base.vbase);
-iomuxc_map_failed:
- iounmap(pm_info->src_base.vbase);
-src_map_failed:
- iounmap(pm_info->mmdc_base.vbase);
put_node:
of_node_put(node);
@@ -649,7 +1317,10 @@ void __init imx6_pm_ccm_init(const char *ccm_compat)
void __init imx6q_pm_init(void)
{
- imx6_pm_common_init(&imx6q_pm_data);
+ if (imx_mmdc_get_ddr_type() == IMX_DDR_TYPE_LPDDR2)
+ imx6_pm_common_init(&imx6q_lpddr2_pm_data);
+ else
+ imx6_pm_common_init(&imx6q_pm_data);
}
void __init imx6dl_pm_init(void)
@@ -659,15 +1330,96 @@ void __init imx6dl_pm_init(void)
void __init imx6sl_pm_init(void)
{
+ struct device_node *np;
+ struct regmap *gpr;
+
+ if (cpu_is_imx6sll()) {
+ imx6_pm_common_init(&imx6sll_pm_data);
+ np = of_find_node_by_path(
+ "/soc/aips-bus@02000000/spba-bus@02000000/serial@02020000");
+ if (np)
+ console_base = of_iomap(np, 0);
+ /* i.MX6SLL has bus auto clock gating function */
+ gpr = syscon_regmap_lookup_by_compatible("fsl,imx6q-iomuxc-gpr");
+ if (!IS_ERR(gpr))
+ regmap_update_bits(gpr, IOMUXC_GPR5,
+ IOMUXC_GPR5_CLOCK_AFCG_X_BYPASS_MASK, 0);
+ return;
+ }
+
imx6_pm_common_init(&imx6sl_pm_data);
}
void __init imx6sx_pm_init(void)
{
- imx6_pm_common_init(&imx6sx_pm_data);
+ struct device_node *np;
+ struct resource res;
+
+ if (imx_mmdc_get_ddr_type() == IMX_DDR_TYPE_LPDDR2)
+ imx6_pm_common_init(&imx6sx_lpddr2_pm_data);
+ else
+ imx6_pm_common_init(&imx6sx_pm_data);
+ if (imx_get_soc_revision() < IMX_CHIP_REVISION_1_2) {
+ /*
+ * As there is a 16K OCRAM(start from 0x8f8000)
+ * dedicated for low power function on i.MX6SX,
+ * but ROM did NOT do the ocram address change
+ * accordingly, so we need to add a data patch
+ * to workaround this issue, otherwise, system
+ * will fail to resume from DSM mode. TO1.2 fixes
+ * this issue.
+ */
+ romcp = syscon_regmap_lookup_by_compatible(
+ "fsl,imx6sx-romcp");
+ if (IS_ERR(romcp)) {
+ pr_err("failed to find fsl,imx6sx-romcp regmap\n");
+ return;
+ }
+ regmap_write(romcp, ROMC_ROMPATCH0D, iram_tlb_phys_addr);
+ regmap_update_bits(romcp, ROMC_ROMPATCHCNTL,
+ BM_ROMPATCHCNTL_0D, BM_ROMPATCHCNTL_0D);
+ regmap_update_bits(romcp, ROMC_ROMPATCHENL,
+ BM_ROMPATCHENL_0D, BM_ROMPATCHENL_0D);
+ regmap_write(romcp, ROMC_ROMPATCH0A,
+ ROM_ADDR_FOR_INTERNAL_RAM_BASE);
+ regmap_update_bits(romcp, ROMC_ROMPATCHCNTL,
+ BM_ROMPATCHCNTL_DIS, ~BM_ROMPATCHCNTL_DIS);
+ }
+
+ np = of_find_compatible_node(NULL, NULL, "fsl,mega-fast-sram");
+ ocram_base = of_iomap(np, 0);
+ WARN_ON(!ocram_base);
+ WARN_ON(of_address_to_resource(np, 0, &res));
+ ocram_size = resource_size(&res);
+ ocram_saved_in_ddr = kzalloc(ocram_size, GFP_KERNEL);
+ WARN_ON(!ocram_saved_in_ddr);
+
+ np = of_find_node_by_path(
+ "/soc/aips-bus@02000000/spba-bus@02000000/serial@02020000");
+ if (np)
+ console_base = of_iomap(np, 0);
+ if (imx_src_is_m4_enabled()) {
+ np = of_find_compatible_node(NULL, NULL,
+ "fsl,imx6sx-qspi-m4-restore");
+ if (np)
+ qspi_base = of_iomap(np, 0);
+ WARN_ON(!qspi_base);
+ }
}
void __init imx6ul_pm_init(void)
{
- imx6_pm_common_init(&imx6ul_pm_data);
+ struct device_node *np;
+
+ if (imx_mmdc_get_ddr_type() == IMX_DDR_TYPE_LPDDR2)
+ imx6_pm_common_init(&imx6ul_lpddr2_pm_data);
+ else
+ imx6_pm_common_init(&imx6ul_pm_data);
+
+ if (cpu_is_imx6ull()) {
+ np = of_find_node_by_path(
+ "/soc/aips-bus@02000000/spba-bus@02000000/serial@02020000");
+ if (np)
+ console_base = of_iomap(np, 0);
+ }
}
diff --git a/arch/arm/mach-imx/pm-imx7.c b/arch/arm/mach-imx/pm-imx7.c
new file mode 100644
index 000000000000..e9f4d86f21aa
--- /dev/null
+++ b/arch/arm/mach-imx/pm-imx7.c
@@ -0,0 +1,1227 @@
+/*
+ * Copyright (C) 2015 Freescale Semiconductor, Inc.
+ *
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/busfreq-imx.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/of_fdt.h>
+#include <linux/of_irq.h>
+#include <linux/psci.h>
+#include <linux/slab.h>
+#include <linux/suspend.h>
+#include <linux/genalloc.h>
+#include <linux/mfd/syscon.h>
+#include <linux/mfd/syscon/imx7-iomuxc-gpr.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_fdt.h>
+#include <linux/of_platform.h>
+#include <linux/regmap.h>
+#include <linux/suspend.h>
+#include <asm/cacheflush.h>
+#include <asm/fncpy.h>
+#include <asm/mach/map.h>
+#include <asm/proc-fns.h>
+#include <asm/suspend.h>
+#include <asm/tlb.h>
+
+#include <uapi/linux/psci.h>
+
+#include "common.h"
+#include "hardware.h"
+#include "cpuidle.h"
+
+#define MX7_SUSPEND_OCRAM_SIZE 0x1000
+#define MX7_MAX_DDRC_NUM 32
+#define MX7_MAX_DDRC_PHY_NUM 16
+
+#define MX7_SUSPEND_IRAM_ADDR_OFFSET 0
+#define READ_DATA_FROM_HARDWARE 0
+
+#define UART_UCR1 0x80
+#define UART_UCR2 0x84
+#define UART_UCR3 0x88
+#define UART_UCR4 0x8c
+#define UART_UFCR 0x90
+#define UART_UESC 0x9c
+#define UART_UTIM 0xa0
+#define UART_UBIR 0xa4
+#define UART_UBMR 0xa8
+#define UART_UBRC 0xac
+#define UART_UTS 0xb4
+
+#define MAX_IOMUXC_GPR 23
+#define MAX_UART_IO 4
+#define MAX_CCM_LPCG 167
+#define MAX_GPT 3
+#define MAX_GPIO_ROW 7
+#define MAX_GPIO_COL 8
+
+#define UART_RX_IO 0x128
+#define UART_RX_PAD 0x398
+#define UART_TX_IO 0x12c
+#define UART_TX_PAD 0x39c
+
+#define GPT_CR 0x0
+#define GPT_PR 0x4
+#define GPT_IR 0xc
+
+#define CCM_LPCG_START 0x4040
+#define CCM_LPCG_STEP 0x10
+#define CCM_EIM_LPCG 0x4160
+#define CCM_PXP_LPCG 0x44c0
+#define CCM_PCIE_LPCG 0x4600
+
+#define BM_CCM_ROOT_POST_PODF 0x3f
+#define BM_CCM_ROOT_PRE_PODF 0x70000
+#define BM_CCM_ROOT_MUX 0x7000000
+#define BM_CCM_ROOT_ENABLE 0x10000000
+
+#define BM_SYS_COUNTER_CNTCR_FCR1 0x200
+#define BM_SYS_COUNTER_CNTCR_FCR0 0x100
+
+#define PFD_A_OFFSET 0xc0
+#define PFD_B_OFFSET 0xd0
+
+#define PLL_ARM_OFFSET 0x60
+#define PLL_DDR_OFFSET 0x70
+#define PLL_DDR_SS_OFFSET 0x80
+#define PLL_DDR_NUM_OFFSET 0x90
+#define PLL_DDR_DENOM_OFFSET 0xa0
+#define PLL_480_OFFSET 0xb0
+#define PLL_ENET_OFFSET 0xe0
+#define PLL_AUDIO_OFFSET 0xf0
+#define PLL_AUDIO_SS_OFFSET 0x100
+#define PLL_AUDIO_NUM_OFFSET 0x110
+#define PLL_AUDIO_DENOM_OFFSET 0x120
+#define PLL_VIDEO_OFFSET 0x130
+#define PLL_VIDEO_SS_OFFSET 0x140
+#define PLL_VIDEO_NUM_OFFSET 0x150
+#define PLL_VIDEO_DENOM_OFFSET 0x160
+
+#define REG_SET 0x4
+#define REG_CLR 0x8
+
+#define GPIO_DR 0x0
+#define GPIO_GDIR 0x4
+#define GPIO_ICR1 0xc
+#define GPIO_ICR2 0x10
+#define GPIO_IMR 0x14
+#define GPIO_EDGE 0x1c
+
+#define M4RCR 0x0C
+#define M4_SP_OFF 0x00
+#define M4_PC_OFF 0x04
+#define M4_RCR_HALT 0xAB
+#define M4_RCR_GO 0xAA
+#define M4_OCRAMS_RESERVED_SIZE 0xc
+
+extern unsigned long iram_tlb_base_addr;
+extern unsigned long iram_tlb_phys_addr;
+
+static unsigned int *ocram_saved_in_ddr;
+static void __iomem *ocram_base;
+static unsigned int ocram_size;
+static unsigned int *lpm_ocram_saved_in_ddr;
+static void __iomem *lpm_ocram_base;
+
+static unsigned int *lpm_m4tcm_saved_in_ddr;
+static void __iomem *lpm_m4tcm_base;
+static void __iomem *m4_bootrom_base;
+
+static unsigned int lpm_ocram_size;
+static void __iomem *ccm_base;
+static void __iomem *lpsr_base;
+static void __iomem *console_base;
+static void __iomem *suspend_ocram_base;
+static void __iomem *iomuxc_base;
+static void __iomem *gpt1_base;
+static void __iomem *system_counter_ctrl_base;
+static void __iomem *system_counter_cmp_base;
+static void __iomem *gpio1_base;
+static void (*imx7_suspend_in_ocram_fn)(void __iomem *ocram_vbase);
+struct imx7_cpu_pm_info *pm_info;
+static bool lpsr_enabled;
+static u32 iomuxc_gpr[MAX_IOMUXC_GPR];
+static u32 uart1_io[MAX_UART_IO];
+static u32 ccm_lpcg[MAX_CCM_LPCG];
+static u32 ccm_root[][2] = {
+ {0x8000, 0}, {0x8080, 0}, {0x8100, 0}, {0x8800, 0},
+ {0x8880, 0}, {0x8900, 0}, {0x8980, 0}, {0x9000, 0},
+ {0x9800, 0}, {0x9880, 0}, {0xa000, 0}, {0xa080, 0},
+ {0xa100, 0}, {0xa180, 0}, {0xa200, 0}, {0xa280, 0},
+ {0xa300, 0}, {0xa380, 0}, {0xa400, 0}, {0xa480, 0},
+ {0xa500, 0}, {0xa580, 0}, {0xa600, 0}, {0xa680, 0},
+ {0xa700, 0}, {0xa780, 0}, {0xa800, 0}, {0xa880, 0},
+ {0xa900, 0}, {0xa980, 0}, {0xaa00, 0}, {0xaa80, 0},
+ {0xab00, 0}, {0xab80, 0}, {0xac00, 0}, {0xac80, 0},
+ {0xad00, 0}, {0xad80, 0}, {0xae00, 0}, {0xae80, 0},
+ {0xaf00, 0}, {0xaf80, 0}, {0xb000, 0}, {0xb080, 0},
+ {0xb100, 0}, {0xb180, 0}, {0xb200, 0}, {0xb280, 0},
+ {0xb300, 0}, {0xb380, 0}, {0xb400, 0}, {0xb480, 0},
+ {0xb500, 0}, {0xb580, 0}, {0xb600, 0}, {0xb680, 0},
+ {0xb700, 0}, {0xb780, 0}, {0xb800, 0}, {0xb880, 0},
+ {0xb900, 0}, {0xb980, 0}, {0xba00, 0}, {0xba80, 0},
+ {0xbb00, 0}, {0xbb80, 0}, {0xbc00, 0}, {0xbc80, 0},
+ {0xbd00, 0}, {0xbd80, 0}, {0xbe00, 0},
+};
+static u32 pfd_a, pfd_b;
+static u32 pll[15];
+static u32 gpt1_regs[MAX_GPT];
+static u32 sys_ctrl_reg, sys_cmp_reg;
+static u32 gpio_reg[MAX_GPIO_ROW][MAX_GPIO_COL];
+/*
+ * suspend ocram space layout:
+ * ======================== high address ======================
+ * .
+ * .
+ * .
+ * ^
+ * ^
+ * ^
+ * imx7_suspend code
+ * PM_INFO structure(imx7_cpu_pm_info)
+ * ======================== low address =======================
+ */
+
+struct imx7_pm_base {
+ phys_addr_t pbase;
+ void __iomem *vbase;
+};
+
+struct imx7_pm_socdata {
+ u32 ddr_type;
+ const char *ddrc_compat;
+ const char *src_compat;
+ const char *iomuxc_compat;
+ const char *gpc_compat;
+ const u32 ddrc_num;
+ const u32 (*ddrc_offset)[2];
+ const u32 ddrc_phy_num;
+ const u32 (*ddrc_phy_offset)[2];
+};
+
+static const u32 imx7d_ddrc_lpddr3_setting[][2] __initconst = {
+ { 0x0, READ_DATA_FROM_HARDWARE },
+ { 0x1a0, READ_DATA_FROM_HARDWARE },
+ { 0x1a4, READ_DATA_FROM_HARDWARE },
+ { 0x1a8, READ_DATA_FROM_HARDWARE },
+ { 0x64, READ_DATA_FROM_HARDWARE },
+ { 0xd0, READ_DATA_FROM_HARDWARE },
+ { 0xdc, READ_DATA_FROM_HARDWARE },
+ { 0xe0, READ_DATA_FROM_HARDWARE },
+ { 0xe4, READ_DATA_FROM_HARDWARE },
+ { 0xf4, READ_DATA_FROM_HARDWARE },
+ { 0x100, READ_DATA_FROM_HARDWARE },
+ { 0x104, READ_DATA_FROM_HARDWARE },
+ { 0x108, READ_DATA_FROM_HARDWARE },
+ { 0x10c, READ_DATA_FROM_HARDWARE },
+ { 0x110, READ_DATA_FROM_HARDWARE },
+ { 0x114, READ_DATA_FROM_HARDWARE },
+ { 0x118, READ_DATA_FROM_HARDWARE },
+ { 0x120, READ_DATA_FROM_HARDWARE },
+ { 0x11c, READ_DATA_FROM_HARDWARE },
+ { 0x180, READ_DATA_FROM_HARDWARE },
+ { 0x184, READ_DATA_FROM_HARDWARE },
+ { 0x190, READ_DATA_FROM_HARDWARE },
+ { 0x194, READ_DATA_FROM_HARDWARE },
+ { 0x200, READ_DATA_FROM_HARDWARE },
+ { 0x204, READ_DATA_FROM_HARDWARE },
+ { 0x210, READ_DATA_FROM_HARDWARE },
+ { 0x214, READ_DATA_FROM_HARDWARE },
+ { 0x218, READ_DATA_FROM_HARDWARE },
+ { 0x240, READ_DATA_FROM_HARDWARE },
+ { 0x244, READ_DATA_FROM_HARDWARE },
+};
+
+static const u32 imx7d_ddrc_phy_lpddr3_setting[][2] __initconst = {
+ { 0x0, READ_DATA_FROM_HARDWARE },
+ { 0x4, READ_DATA_FROM_HARDWARE },
+ { 0x8, READ_DATA_FROM_HARDWARE },
+ { 0x10, READ_DATA_FROM_HARDWARE },
+ { 0xb0, READ_DATA_FROM_HARDWARE },
+ { 0x1c, READ_DATA_FROM_HARDWARE },
+ { 0x9c, READ_DATA_FROM_HARDWARE },
+ { 0x7c, READ_DATA_FROM_HARDWARE },
+ { 0x80, READ_DATA_FROM_HARDWARE },
+ { 0x84, READ_DATA_FROM_HARDWARE },
+ { 0x88, READ_DATA_FROM_HARDWARE },
+ { 0x6c, READ_DATA_FROM_HARDWARE },
+ { 0x20, READ_DATA_FROM_HARDWARE },
+ { 0x30, READ_DATA_FROM_HARDWARE },
+ { 0x50, 0x01000008 },
+ { 0x50, 0x00000008 },
+ { 0xc0, 0x0e487304 },
+ { 0xc0, 0x0e4c7304 },
+ { 0xc0, 0x0e4c7306 },
+ { 0xc0, 0x0e487304 },
+};
+
+static const u32 imx7d_ddrc_ddr3_setting[][2] __initconst = {
+ { 0x0, READ_DATA_FROM_HARDWARE },
+ { 0x1a0, READ_DATA_FROM_HARDWARE },
+ { 0x1a4, READ_DATA_FROM_HARDWARE },
+ { 0x1a8, READ_DATA_FROM_HARDWARE },
+ { 0x64, READ_DATA_FROM_HARDWARE },
+ { 0x490, READ_DATA_FROM_HARDWARE },
+ { 0xd0, READ_DATA_FROM_HARDWARE },
+ { 0xd4, READ_DATA_FROM_HARDWARE },
+ { 0xdc, READ_DATA_FROM_HARDWARE },
+ { 0xe0, READ_DATA_FROM_HARDWARE },
+ { 0xe4, READ_DATA_FROM_HARDWARE },
+ { 0xf4, READ_DATA_FROM_HARDWARE },
+ { 0x100, READ_DATA_FROM_HARDWARE },
+ { 0x104, READ_DATA_FROM_HARDWARE },
+ { 0x108, READ_DATA_FROM_HARDWARE },
+ { 0x10c, READ_DATA_FROM_HARDWARE },
+ { 0x110, READ_DATA_FROM_HARDWARE },
+ { 0x114, READ_DATA_FROM_HARDWARE },
+ { 0x120, READ_DATA_FROM_HARDWARE },
+ { 0x180, READ_DATA_FROM_HARDWARE },
+ { 0x190, READ_DATA_FROM_HARDWARE },
+ { 0x194, READ_DATA_FROM_HARDWARE },
+ { 0x200, READ_DATA_FROM_HARDWARE },
+ { 0x204, READ_DATA_FROM_HARDWARE },
+ { 0x210, READ_DATA_FROM_HARDWARE },
+ { 0x214, READ_DATA_FROM_HARDWARE },
+ { 0x218, READ_DATA_FROM_HARDWARE },
+ { 0x240, READ_DATA_FROM_HARDWARE },
+ { 0x244, READ_DATA_FROM_HARDWARE },
+};
+
+static const u32 imx7d_ddrc_phy_ddr3_setting[][2] __initconst = {
+ { 0x0, READ_DATA_FROM_HARDWARE },
+ { 0x4, READ_DATA_FROM_HARDWARE },
+ { 0x10, READ_DATA_FROM_HARDWARE },
+ { 0xb0, READ_DATA_FROM_HARDWARE },
+ { 0x9c, READ_DATA_FROM_HARDWARE },
+ { 0x7c, READ_DATA_FROM_HARDWARE },
+ { 0x80, READ_DATA_FROM_HARDWARE },
+ { 0x84, READ_DATA_FROM_HARDWARE },
+ { 0x88, READ_DATA_FROM_HARDWARE },
+ { 0x6c, READ_DATA_FROM_HARDWARE },
+ { 0x20, READ_DATA_FROM_HARDWARE },
+ { 0x30, READ_DATA_FROM_HARDWARE },
+ { 0x50, 0x01000010 },
+ { 0x50, 0x00000010 },
+ { 0xc0, 0x0e407304 },
+ { 0xc0, 0x0e447304 },
+ { 0xc0, 0x0e447306 },
+ { 0xc0, 0x0e407304 },
+};
+
+static const struct imx7_pm_socdata imx7d_pm_data_lpddr3 __initconst = {
+ .ddrc_compat = "fsl,imx7d-ddrc",
+ .src_compat = "fsl,imx7d-src",
+ .iomuxc_compat = "fsl,imx7d-iomuxc",
+ .gpc_compat = "fsl,imx7d-gpc",
+ .ddrc_num = ARRAY_SIZE(imx7d_ddrc_lpddr3_setting),
+ .ddrc_offset = imx7d_ddrc_lpddr3_setting,
+ .ddrc_phy_num = ARRAY_SIZE(imx7d_ddrc_phy_lpddr3_setting),
+ .ddrc_phy_offset = imx7d_ddrc_phy_lpddr3_setting,
+};
+
+static const struct imx7_pm_socdata imx7d_pm_data_ddr3 __initconst = {
+ .ddrc_compat = "fsl,imx7d-ddrc",
+ .src_compat = "fsl,imx7d-src",
+ .iomuxc_compat = "fsl,imx7d-iomuxc",
+ .gpc_compat = "fsl,imx7d-gpc",
+ .ddrc_num = ARRAY_SIZE(imx7d_ddrc_ddr3_setting),
+ .ddrc_offset = imx7d_ddrc_ddr3_setting,
+ .ddrc_phy_num = ARRAY_SIZE(imx7d_ddrc_phy_ddr3_setting),
+ .ddrc_phy_offset = imx7d_ddrc_phy_ddr3_setting,
+};
+
+/*
+ * This structure is for passing necessary data for low level ocram
+ * suspend code(arch/arm/mach-imx/suspend-imx7.S), if this struct
+ * definition is changed, the offset definition in
+ * arch/arm/mach-imx/suspend-imx7.S must be also changed accordingly,
+ * otherwise, the suspend to ocram function will be broken!
+ */
+struct imx7_cpu_pm_info {
+ u32 m4_reserve0;
+ u32 m4_reserve1;
+ u32 m4_reserve2;
+ phys_addr_t pbase; /* The physical address of pm_info. */
+ phys_addr_t resume_addr; /* The physical resume address for asm code */
+ u32 ddr_type;
+ u32 pm_info_size; /* Size of pm_info. */
+ struct imx7_pm_base ddrc_base;
+ struct imx7_pm_base ddrc_phy_base;
+ struct imx7_pm_base src_base;
+ struct imx7_pm_base iomuxc_gpr_base;
+ struct imx7_pm_base ccm_base;
+ struct imx7_pm_base gpc_base;
+ struct imx7_pm_base snvs_base;
+ struct imx7_pm_base anatop_base;
+ struct imx7_pm_base lpsr_base;
+ struct imx7_pm_base gic_base;
+ u32 ttbr1; /* Store TTBR1 */
+ u32 ddrc_num; /* Number of DDRC which need saved/restored. */
+ u32 ddrc_val[MX7_MAX_DDRC_NUM][2]; /* To save offset and value */
+ u32 ddrc_phy_num; /* Number of DDRC which need saved/restored. */
+ u32 ddrc_phy_val[MX7_MAX_DDRC_NUM][2]; /* To save offset and value */
+} __aligned(8);
+
+static struct map_desc imx7_pm_io_desc[] __initdata = {
+ imx_map_entry(MX7D, AIPS1, MT_DEVICE),
+ imx_map_entry(MX7D, AIPS2, MT_DEVICE),
+ imx_map_entry(MX7D, AIPS3, MT_DEVICE),
+};
+
+static const char * const low_power_ocram_match[] __initconst = {
+ "fsl,lpm-sram",
+ NULL
+};
+
+static void imx7_gpio_save(void)
+{
+ u32 i;
+
+ for (i = 0; i < 7; i++) {
+ gpio_reg[i][0] = readl_relaxed(gpio1_base +
+ (i << 16) + GPIO_DR);
+ gpio_reg[i][1] = readl_relaxed(gpio1_base +
+ (i << 16) + GPIO_GDIR);
+ gpio_reg[i][3] = readl_relaxed(gpio1_base +
+ (i << 16) + GPIO_ICR1);
+ gpio_reg[i][4] = readl_relaxed(gpio1_base +
+ (i << 16) + GPIO_ICR2);
+ gpio_reg[i][5] = readl_relaxed(gpio1_base +
+ (i << 16) + GPIO_IMR);
+ gpio_reg[i][7] = readl_relaxed(gpio1_base +
+ (i << 16) + GPIO_EDGE);
+ }
+}
+
+static void imx7_gpio_restore(void)
+{
+ u32 i, val;
+
+ for (i = 0; i < 7; i++) {
+ writel_relaxed(gpio_reg[i][1], gpio1_base +
+ (i << 16) + GPIO_GDIR);
+ writel_relaxed(gpio_reg[i][3], gpio1_base +
+ (i << 16) + GPIO_ICR1);
+ writel_relaxed(gpio_reg[i][4], gpio1_base +
+ (i << 16) + GPIO_ICR2);
+ writel_relaxed(gpio_reg[i][5], gpio1_base +
+ (i << 16) + GPIO_IMR);
+ writel_relaxed(gpio_reg[i][7], gpio1_base +
+ (i << 16) + GPIO_EDGE);
+ /* only restore output gpio value */
+ val = readl_relaxed(gpio1_base + (i << 16) + GPIO_DR) |
+ (gpio_reg[i][0] & gpio_reg[i][1]);
+ writel_relaxed(val, gpio1_base + (i << 16) + GPIO_DR);
+ }
+}
+
+static void imx7_ccm_save(void)
+{
+ u32 i;
+
+ for (i = 0; i < MAX_CCM_LPCG; i++)
+ ccm_lpcg[i] = readl_relaxed(pm_info->ccm_base.vbase +
+ i * CCM_LPCG_STEP + CCM_LPCG_START);
+ pfd_a = readl_relaxed(pm_info->anatop_base.vbase + PFD_A_OFFSET);
+ pfd_b = readl_relaxed(pm_info->anatop_base.vbase + PFD_B_OFFSET);
+
+ pll[0] = readl_relaxed(pm_info->anatop_base.vbase +
+ PLL_ARM_OFFSET);
+ pll[1] = readl_relaxed(pm_info->anatop_base.vbase +
+ PLL_DDR_OFFSET);
+ pll[2] = readl_relaxed(pm_info->anatop_base.vbase +
+ PLL_DDR_SS_OFFSET);
+ pll[3] = readl_relaxed(pm_info->anatop_base.vbase +
+ PLL_DDR_NUM_OFFSET);
+ pll[4] = readl_relaxed(pm_info->anatop_base.vbase +
+ PLL_DDR_DENOM_OFFSET);
+ pll[5] = readl_relaxed(pm_info->anatop_base.vbase +
+ PLL_480_OFFSET);
+ pll[6] = readl_relaxed(pm_info->anatop_base.vbase +
+ PLL_ENET_OFFSET);
+ pll[7] = readl_relaxed(pm_info->anatop_base.vbase +
+ PLL_AUDIO_OFFSET);
+ pll[8] = readl_relaxed(pm_info->anatop_base.vbase +
+ PLL_AUDIO_SS_OFFSET);
+ pll[9] = readl_relaxed(pm_info->anatop_base.vbase +
+ PLL_AUDIO_NUM_OFFSET);
+ pll[10] = readl_relaxed(pm_info->anatop_base.vbase +
+ PLL_AUDIO_DENOM_OFFSET);
+ pll[11] = readl_relaxed(pm_info->anatop_base.vbase +
+ PLL_VIDEO_OFFSET);
+ pll[12] = readl_relaxed(pm_info->anatop_base.vbase +
+ PLL_VIDEO_SS_OFFSET);
+ pll[13] = readl_relaxed(pm_info->anatop_base.vbase +
+ PLL_VIDEO_NUM_OFFSET);
+ pll[14] = readl_relaxed(pm_info->anatop_base.vbase +
+ PLL_VIDEO_DENOM_OFFSET);
+
+ /* enable all PLLs/PFDs for saving CCM root */
+ writel_relaxed(0x1c000070, pm_info->anatop_base.vbase +
+ PLL_480_OFFSET + 0x8);
+ writel_relaxed(0x80808080, pm_info->anatop_base.vbase +
+ PFD_A_OFFSET + 0x8);
+ writel_relaxed(0x80808080, pm_info->anatop_base.vbase +
+ PFD_B_OFFSET + 0x8);
+ writel_relaxed(0x1fc0, pm_info->anatop_base.vbase +
+ PLL_ENET_OFFSET + 0x4);
+ writel_relaxed(0x12000, pm_info->anatop_base.vbase +
+ PLL_AUDIO_OFFSET);
+ writel_relaxed(0x12000, pm_info->anatop_base.vbase +
+ PLL_VIDEO_OFFSET);
+
+ for (i = 0; i < sizeof(ccm_root) / 8; i++)
+ ccm_root[i][1] = readl_relaxed(
+ pm_info->ccm_base.vbase + ccm_root[i][0]);
+}
+
+static void imx7_ccm_restore(void)
+{
+ u32 i, val;
+
+ /* enable all PLLs/PFDs for restoring CCM root */
+ writel_relaxed(0x1c000070, pm_info->anatop_base.vbase +
+ PLL_480_OFFSET + REG_CLR);
+ writel_relaxed(0x80808080, pm_info->anatop_base.vbase +
+ PFD_A_OFFSET + REG_CLR);
+ writel_relaxed(0x80808080, pm_info->anatop_base.vbase +
+ PFD_B_OFFSET + REG_CLR);
+ writel_relaxed(0x1fc0, pm_info->anatop_base.vbase +
+ PLL_ENET_OFFSET + REG_SET);
+ writel_relaxed(0x12000, pm_info->anatop_base.vbase +
+ PLL_AUDIO_OFFSET);
+ writel_relaxed(0x12000, pm_info->anatop_base.vbase +
+ PLL_VIDEO_OFFSET);
+
+ for (i = 0; i < sizeof(ccm_root) / 8; i++) {
+ val = readl_relaxed(pm_info->ccm_base.vbase + ccm_root[i][0]);
+ /* restore post podf */
+ val &= ~BM_CCM_ROOT_POST_PODF;
+ val |= ccm_root[i][1] & BM_CCM_ROOT_POST_PODF;
+ writel_relaxed(val, pm_info->ccm_base.vbase + ccm_root[i][0]);
+ /* resotre pre podf */
+ val &= ~BM_CCM_ROOT_PRE_PODF;
+ val |= ccm_root[i][1] & BM_CCM_ROOT_PRE_PODF;
+ writel_relaxed(val, pm_info->ccm_base.vbase + ccm_root[i][0]);
+ /* restore mux */
+ val &= ~BM_CCM_ROOT_MUX;
+ val |= ccm_root[i][1] & BM_CCM_ROOT_MUX;
+ writel_relaxed(val, pm_info->ccm_base.vbase + ccm_root[i][0]);
+ /* restore enable */
+ val &= ~BM_CCM_ROOT_ENABLE;
+ val |= ccm_root[i][1] & BM_CCM_ROOT_ENABLE;
+ writel_relaxed(val, pm_info->ccm_base.vbase + ccm_root[i][0]);
+ }
+
+ /* restore PLLs */
+ writel_relaxed(pll[0], pm_info->anatop_base.vbase +
+ PLL_ARM_OFFSET);
+ writel_relaxed(pll[1], pm_info->anatop_base.vbase +
+ PLL_DDR_OFFSET);
+ writel_relaxed(pll[2], pm_info->anatop_base.vbase +
+ PLL_DDR_SS_OFFSET);
+ writel_relaxed(pll[3], pm_info->anatop_base.vbase +
+ PLL_DDR_NUM_OFFSET);
+ writel_relaxed(pll[4], pm_info->anatop_base.vbase +
+ PLL_DDR_DENOM_OFFSET);
+ writel_relaxed(pll[5], pm_info->anatop_base.vbase +
+ PLL_480_OFFSET);
+ writel_relaxed(pll[6], pm_info->anatop_base.vbase +
+ PLL_ENET_OFFSET);
+ writel_relaxed(pll[7], pm_info->anatop_base.vbase +
+ PLL_AUDIO_OFFSET);
+ writel_relaxed(pll[8], pm_info->anatop_base.vbase +
+ PLL_AUDIO_SS_OFFSET);
+ writel_relaxed(pll[9], pm_info->anatop_base.vbase +
+ PLL_AUDIO_NUM_OFFSET);
+ writel_relaxed(pll[10], pm_info->anatop_base.vbase +
+ PLL_AUDIO_DENOM_OFFSET);
+ writel_relaxed(pll[11], pm_info->anatop_base.vbase +
+ PLL_VIDEO_OFFSET);
+ writel_relaxed(pll[12], pm_info->anatop_base.vbase +
+ PLL_VIDEO_SS_OFFSET);
+ writel_relaxed(pll[13], pm_info->anatop_base.vbase +
+ PLL_VIDEO_NUM_OFFSET);
+ writel_relaxed(pll[14], pm_info->anatop_base.vbase +
+ PLL_VIDEO_DENOM_OFFSET);
+
+ for (i = 0; i < MAX_CCM_LPCG; i++)
+ writel_relaxed(ccm_lpcg[i], pm_info->ccm_base.vbase +
+ i * CCM_LPCG_STEP + CCM_LPCG_START);
+ /* restore PFDs */
+ writel_relaxed(pfd_a & 0x80808080,
+ pm_info->anatop_base.vbase + PFD_A_OFFSET + REG_SET);
+ writel_relaxed(pfd_a, pm_info->anatop_base.vbase + PFD_A_OFFSET);
+
+ writel_relaxed(pfd_b & 0x80808080,
+ pm_info->anatop_base.vbase + PFD_B_OFFSET + REG_SET);
+ writel_relaxed(pfd_b, pm_info->anatop_base.vbase + PFD_B_OFFSET);
+}
+
+static void imx7_sys_counter_save(void)
+{
+ sys_ctrl_reg = readl_relaxed(system_counter_ctrl_base);
+ sys_cmp_reg = readl_relaxed(system_counter_cmp_base);
+}
+
+static void imx7_sys_counter_restore(void)
+{
+ writel_relaxed(sys_ctrl_reg, system_counter_ctrl_base);
+ writel_relaxed(sys_cmp_reg, system_counter_cmp_base);
+}
+
+static void imx7_gpt_save(void)
+{
+ gpt1_regs[0] = readl_relaxed(gpt1_base + GPT_CR);
+ gpt1_regs[1] = readl_relaxed(gpt1_base + GPT_PR);
+ gpt1_regs[2] = readl_relaxed(gpt1_base + GPT_IR);
+}
+
+static void imx7_gpt_restore(void)
+{
+ writel_relaxed(gpt1_regs[0], gpt1_base + GPT_CR);
+ writel_relaxed(gpt1_regs[1], gpt1_base + GPT_PR);
+ writel_relaxed(gpt1_regs[2], gpt1_base + GPT_IR);
+}
+
+static void imx7_iomuxc_gpr_save(void)
+{
+ u32 i;
+
+ for (i = 0; i < MAX_IOMUXC_GPR; i++)
+ iomuxc_gpr[i] = readl_relaxed(
+ pm_info->iomuxc_gpr_base.vbase + i * 4);
+}
+
+static void imx7_iomuxc_gpr_restore(void)
+{
+ u32 i;
+
+ for (i = 0; i < MAX_IOMUXC_GPR; i++)
+ writel_relaxed(iomuxc_gpr[i],
+ pm_info->iomuxc_gpr_base.vbase + i * 4);
+}
+
+static void imx7_console_save(unsigned int *regs)
+{
+ if (!console_base)
+ return;
+
+ regs[0] = readl_relaxed(console_base + UART_UCR1);
+ regs[1] = readl_relaxed(console_base + UART_UCR2);
+ regs[2] = readl_relaxed(console_base + UART_UCR3);
+ regs[3] = readl_relaxed(console_base + UART_UCR4);
+ regs[4] = readl_relaxed(console_base + UART_UFCR);
+ regs[5] = readl_relaxed(console_base + UART_UESC);
+ regs[6] = readl_relaxed(console_base + UART_UTIM);
+ regs[7] = readl_relaxed(console_base + UART_UBIR);
+ regs[8] = readl_relaxed(console_base + UART_UBMR);
+ regs[9] = readl_relaxed(console_base + UART_UTS);
+}
+
+static void imx7_console_io_save(void)
+{
+ /* save uart1 io, driver resume is too late */
+ uart1_io[0] = readl_relaxed(iomuxc_base + UART_RX_IO);
+ uart1_io[1] = readl_relaxed(iomuxc_base + UART_RX_PAD);
+ uart1_io[2] = readl_relaxed(iomuxc_base + UART_TX_IO);
+ uart1_io[3] = readl_relaxed(iomuxc_base + UART_TX_PAD);
+}
+
+static void imx7_console_restore(unsigned int *regs)
+{
+ if (!console_base)
+ return;
+
+ writel_relaxed(regs[4], console_base + UART_UFCR);
+ writel_relaxed(regs[5], console_base + UART_UESC);
+ writel_relaxed(regs[6], console_base + UART_UTIM);
+ writel_relaxed(regs[7], console_base + UART_UBIR);
+ writel_relaxed(regs[8], console_base + UART_UBMR);
+ writel_relaxed(regs[9], console_base + UART_UTS);
+ writel_relaxed(regs[0], console_base + UART_UCR1);
+ writel_relaxed(regs[1] | 0x1, console_base + UART_UCR2);
+ writel_relaxed(regs[2], console_base + UART_UCR3);
+ writel_relaxed(regs[3], console_base + UART_UCR4);
+}
+
+static void imx7_console_io_restore(void)
+{
+ /* restore uart1 io */
+ writel_relaxed(uart1_io[0], iomuxc_base + UART_RX_IO);
+ writel_relaxed(uart1_io[1], iomuxc_base + UART_RX_PAD);
+ writel_relaxed(uart1_io[2], iomuxc_base + UART_TX_IO);
+ writel_relaxed(uart1_io[3], iomuxc_base + UART_TX_PAD);
+}
+
+#define MX7D_SUSPEND_POWERDWN_PARAM \
+ ((0 << PSCI_0_2_POWER_STATE_ID_SHIFT) | \
+ (1 << PSCI_0_2_POWER_STATE_AFFL_SHIFT) | \
+ (PSCI_POWER_STATE_TYPE_POWER_DOWN << PSCI_0_2_POWER_STATE_TYPE_SHIFT))
+
+#define MX7D_SUSPEND_STANDBY_PARAM \
+ ((0 << PSCI_0_2_POWER_STATE_ID_SHIFT) | \
+ (1 << PSCI_0_2_POWER_STATE_AFFL_SHIFT) | \
+ (PSCI_POWER_STATE_TYPE_STANDBY << PSCI_0_2_POWER_STATE_TYPE_SHIFT))
+
+static int imx7_suspend_finish(unsigned long val)
+{
+ u32 state;
+
+ if (val == 0)
+ state = MX7D_SUSPEND_POWERDWN_PARAM;
+ else
+ state = MX7D_SUSPEND_STANDBY_PARAM;
+
+ if (psci_ops.cpu_suspend) {
+ return psci_ops.cpu_suspend(state, __pa(cpu_resume));
+ }
+
+ if (!imx7_suspend_in_ocram_fn) {
+ cpu_do_idle();
+ } else {
+ /*
+ * call low level suspend function in ocram,
+ * as we need to float DDR IO.
+ */
+ local_flush_tlb_all();
+ imx7_suspend_in_ocram_fn(suspend_ocram_base);
+ }
+
+ return 0;
+}
+
+static void imx7_pm_set_lpsr_resume_addr(unsigned long addr)
+{
+ writel_relaxed(addr, pm_info->lpsr_base.vbase);
+}
+
+static int imx7_pm_is_resume_from_lpsr(void)
+{
+ return readl_relaxed(lpsr_base);
+}
+
+static int imx7_pm_enter(suspend_state_t state)
+{
+ unsigned int console_saved_reg[10] = {0};
+ u32 val;
+
+ if (!iram_tlb_base_addr) {
+ pr_warn("No IRAM/OCRAM memory allocated for suspend/resume \
+ code. Please ensure device tree has an entry for \
+ fsl,lpm-sram.\n");
+ return -EINVAL;
+ }
+
+ /*
+ * arm_arch_timer driver requires system counter to be
+ * a clock source with CLOCK_SOURCE_SUSPEND_NONSTOP flag
+ * set, which means hardware system counter needs to keep
+ * running during suspend, as the base clock for system
+ * counter is 24MHz which will be disabled in STOP mode,
+ * so we need to switch system counter's clock to alternate
+ * (lower) clock, it is based on 32K, from block guide, there
+ * is no special flow needs to be followed, system counter
+ * hardware will handle the clock transition.
+ */
+ val = readl_relaxed(system_counter_ctrl_base);
+ val &= ~BM_SYS_COUNTER_CNTCR_FCR0;
+ val |= BM_SYS_COUNTER_CNTCR_FCR1;
+ writel_relaxed(val, system_counter_ctrl_base);
+
+ switch (state) {
+ case PM_SUSPEND_STANDBY:
+ imx_anatop_pre_suspend();
+ imx_gpcv2_pre_suspend(false);
+
+ /* Zzz ... */
+ if (psci_ops.cpu_suspend)
+ cpu_suspend(1, imx7_suspend_finish);
+ else
+ imx7_suspend_in_ocram_fn(suspend_ocram_base);
+
+ imx_anatop_post_resume();
+ imx_gpcv2_post_resume();
+ break;
+ case PM_SUSPEND_MEM:
+ imx_anatop_pre_suspend();
+ imx_gpcv2_pre_suspend(true);
+ if (imx_gpcv2_is_mf_mix_off()) {
+ /*
+ * per design requirement, EXSC for PCIe/EIM/PXP
+ * will need clock to recover RDC setting on
+ * resume, so enable PCIe/EIM LPCG for RDC
+ * recovery when M/F mix off
+ */
+ writel_relaxed(0x3, pm_info->ccm_base.vbase +
+ CCM_EIM_LPCG);
+ writel_relaxed(0x3, pm_info->ccm_base.vbase +
+ CCM_PXP_LPCG);
+ writel_relaxed(0x3, pm_info->ccm_base.vbase +
+ CCM_PCIE_LPCG);
+ /* stop m4 if mix will also be shutdown */
+ if (imx_src_is_m4_enabled() && imx_mu_is_m4_in_stop()) {
+ writel(M4_RCR_HALT,
+ pm_info->src_base.vbase + M4RCR);
+ imx_gpcv2_enable_wakeup_for_m4();
+ }
+ imx7_console_save(console_saved_reg);
+ memcpy(ocram_saved_in_ddr, ocram_base, ocram_size);
+ if (lpsr_enabled) {
+ imx7_pm_set_lpsr_resume_addr(pm_info->resume_addr);
+ imx7_console_io_save();
+ memcpy(lpm_ocram_saved_in_ddr, lpm_ocram_base,
+ lpm_ocram_size);
+ imx7_iomuxc_gpr_save();
+ imx7_ccm_save();
+ imx7_gpt_save();
+ imx7_sys_counter_save();
+ imx7_gpio_save();
+ }
+ }
+
+ /* Zzz ... */
+ cpu_suspend(0, imx7_suspend_finish);
+
+ if (imx7_pm_is_resume_from_lpsr()) {
+ imx7_console_io_restore();
+ memcpy(lpm_ocram_base, lpm_ocram_saved_in_ddr,
+ lpm_ocram_size);
+ imx7_iomuxc_gpr_restore();
+ imx7_ccm_restore();
+ imx7_gpt_restore();
+ imx7_sys_counter_restore();
+ imx7_gpio_restore();
+ imx7d_enable_rcosc();
+ }
+ if (imx_gpcv2_is_mf_mix_off() ||
+ imx7_pm_is_resume_from_lpsr()) {
+ writel_relaxed(0x0, pm_info->ccm_base.vbase +
+ CCM_EIM_LPCG);
+ writel_relaxed(0x0, pm_info->ccm_base.vbase +
+ CCM_PXP_LPCG);
+ writel_relaxed(0x0, pm_info->ccm_base.vbase +
+ CCM_PCIE_LPCG);
+ memcpy(ocram_base, ocram_saved_in_ddr, ocram_size);
+ imx7_console_restore(console_saved_reg);
+ if (imx_src_is_m4_enabled() && imx_mu_is_m4_in_stop()) {
+ imx_gpcv2_disable_wakeup_for_m4();
+ /* restore M4 image */
+ memcpy(lpm_m4tcm_base,
+ lpm_m4tcm_saved_in_ddr, SZ_32K);
+ /* kick m4 to enable */
+ writel(M4_RCR_GO,
+ pm_info->src_base.vbase + M4RCR);
+ /* offset high bus count for m4 image */
+ request_bus_freq(BUS_FREQ_HIGH);
+ /* restore M4 to run mode */
+ imx_mu_set_m4_run_mode();
+ /* gpc wakeup */
+ }
+ }
+ /* clear LPSR resume address */
+ imx7_pm_set_lpsr_resume_addr(0);
+ imx_anatop_post_resume();
+ imx_gpcv2_post_resume();
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ /* restore system counter's clock to base clock */
+ val = readl_relaxed(system_counter_ctrl_base);
+ val &= ~BM_SYS_COUNTER_CNTCR_FCR1;
+ val |= BM_SYS_COUNTER_CNTCR_FCR0;
+ writel_relaxed(val, system_counter_ctrl_base);
+
+ return 0;
+}
+
+static int imx7_pm_valid(suspend_state_t state)
+{
+ return state == PM_SUSPEND_STANDBY || state == PM_SUSPEND_MEM;
+}
+
+static const struct platform_suspend_ops imx7_pm_ops = {
+ .enter = imx7_pm_enter,
+ .valid = imx7_pm_valid,
+};
+
+void __init imx7_pm_set_ccm_base(void __iomem *base)
+{
+ ccm_base = base;
+}
+
+static struct map_desc iram_tlb_io_desc __initdata = {
+ /* .virtual and .pfn are run-time assigned */
+ .length = SZ_1M,
+ .type = MT_MEMORY_RWX_NONCACHED,
+};
+
+static int __init imx7_dt_find_lpsram(unsigned long node, const char *uname,
+ int depth, void *data)
+{
+ unsigned long lpram_addr;
+ const __be32 *prop = of_get_flat_dt_prop(node, "reg", NULL);
+
+ if (of_flat_dt_match(node, low_power_ocram_match)) {
+ if (!prop)
+ return -EINVAL;
+
+ lpram_addr = be32_to_cpup(prop);
+
+ /* We need to create a 1M page table entry. */
+ iram_tlb_io_desc.virtual = IMX_IO_P2V(lpram_addr & 0xFFF00000);
+ iram_tlb_io_desc.pfn = __phys_to_pfn(lpram_addr & 0xFFF00000);
+ iram_tlb_phys_addr = lpram_addr;
+ iram_tlb_base_addr = IMX_IO_P2V(lpram_addr);
+ iotable_init(&iram_tlb_io_desc, 1);
+ }
+
+ return 0;
+}
+
+void __init imx7_pm_map_io(void)
+{
+ unsigned long i, j;
+
+ iotable_init(imx7_pm_io_desc, ARRAY_SIZE(imx7_pm_io_desc));
+ /*
+ * Get the address of IRAM or OCRAM to be used by the low
+ * power code from the device tree.
+ */
+ WARN_ON(of_scan_flat_dt(imx7_dt_find_lpsram, NULL));
+
+ /* Return if no IRAM space is allocated for suspend/resume code. */
+ if (!iram_tlb_base_addr) {
+ pr_warn("No valid ocram available for suspend/resume!\n");
+ return;
+ }
+
+ /* TODO: Handle M4 in TEE? */
+ /* Set all entries to 0 except first 3 words reserved for M4. */
+ memset((void *)(iram_tlb_base_addr + M4_OCRAMS_RESERVED_SIZE),
+ 0, MX7_IRAM_TLB_SIZE - M4_OCRAMS_RESERVED_SIZE);
+
+ /*
+ * Make sure the IRAM virtual address has a mapping in the IRAM
+ * page table.
+ *
+ * Only use the top 12 bits [31-20] when storing the physical
+ * address in the page table as only these bits are required
+ * for 1M mapping.
+ */
+ j = ((iram_tlb_base_addr >> 20) << 2) / 4;
+ *((unsigned long *)iram_tlb_base_addr + j) =
+ (iram_tlb_phys_addr & 0xFFF00000) | TT_ATTRIB_NON_CACHEABLE_1M;
+
+ /*
+ * Make sure the AIPS1 virtual address has a mapping in the
+ * IRAM page table.
+ */
+ for (i = 0; i < 4; i++) {
+ j = ((IMX_IO_P2V(MX7D_AIPS1_BASE_ADDR + i * 0x100000) >> 20) << 2) / 4;
+ *((unsigned long *)iram_tlb_base_addr + j) =
+ ((MX7D_AIPS1_BASE_ADDR + i * 0x100000) & 0xFFF00000) |
+ TT_ATTRIB_NON_CACHEABLE_1M;
+ }
+
+ /*
+ * Make sure the AIPS2 virtual address has a mapping in the
+ * IRAM page table.
+ */
+ for (i = 0; i < 4; i++) {
+ j = ((IMX_IO_P2V(MX7D_AIPS2_BASE_ADDR + i * 0x100000) >> 20) << 2) / 4;
+ *((unsigned long *)iram_tlb_base_addr + j) =
+ ((MX7D_AIPS2_BASE_ADDR + i * 0x100000) & 0xFFF00000) |
+ TT_ATTRIB_NON_CACHEABLE_1M;
+ }
+
+ /*
+ * Make sure the AIPS3 virtual address has a mapping
+ * in the IRAM page table.
+ */
+ for (i = 0; i < 4; i++) {
+ j = ((IMX_IO_P2V(MX7D_AIPS3_BASE_ADDR + i * 0x100000) >> 20) << 2) / 4;
+ *((unsigned long *)iram_tlb_base_addr + j) =
+ ((MX7D_AIPS3_BASE_ADDR + i * 0x100000) & 0xFFF00000) |
+ TT_ATTRIB_NON_CACHEABLE_1M;
+ }
+
+ /*
+ * Make sure the GIC virtual address has a mapping in the
+ * IRAM page table.
+ */
+ j = ((IMX_IO_P2V(MX7D_GIC_BASE_ADDR) >> 20) << 2) / 4;
+ *((unsigned long *)iram_tlb_base_addr + j) =
+ (MX7D_GIC_BASE_ADDR & 0xFFF00000) | TT_ATTRIB_NON_CACHEABLE_1M;
+}
+
+static int __init imx7_suspend_init(const struct imx7_pm_socdata *socdata)
+{
+ struct device_node *node;
+ int i, ret = 0;
+ const u32 (*ddrc_offset_array)[2];
+ const u32 (*ddrc_phy_offset_array)[2];
+ unsigned long iram_paddr;
+
+ suspend_set_ops(&imx7_pm_ops);
+
+ if (!socdata) {
+ pr_warn("%s: invalid argument!\n", __func__);
+ return -EINVAL;
+ }
+
+ /*
+ * 16KB is allocated for IRAM TLB, but only up 8k is for kernel TLB,
+ * The lower 8K is not used, so use the lower 8K for IRAM code and
+ * pm_info.
+ *
+ */
+ iram_paddr = iram_tlb_phys_addr + MX7_SUSPEND_IRAM_ADDR_OFFSET;
+
+ /* Make sure iram_paddr is 8 byte aligned. */
+ if ((uintptr_t)(iram_paddr) & (FNCPY_ALIGN - 1))
+ iram_paddr += FNCPY_ALIGN - iram_paddr % (FNCPY_ALIGN);
+
+ /* Get the virtual address of the suspend code. */
+ suspend_ocram_base = (void *)IMX_IO_P2V(iram_paddr);
+
+ if (psci_ops.cpu_suspend) {
+ pm_info = kmalloc(sizeof(*pm_info), GFP_KERNEL);
+ if (!pm_info)
+ return -ENOMEM;
+ } else {
+ pm_info = suspend_ocram_base;
+ }
+ /* pbase points to iram_paddr. */
+ pm_info->pbase = iram_paddr;
+ pm_info->resume_addr = virt_to_phys(ca7_cpu_resume);
+ pm_info->pm_info_size = sizeof(*pm_info);
+
+ /*
+ * ccm physical address is not used by asm code currently,
+ * so get ccm virtual address directly, as we already have
+ * it from ccm driver.
+ */
+ pm_info->ccm_base.pbase = MX7D_CCM_BASE_ADDR;
+ pm_info->ccm_base.vbase = (void __iomem *)
+ IMX_IO_P2V(MX7D_CCM_BASE_ADDR);
+
+ pm_info->ddrc_base.pbase = MX7D_DDRC_BASE_ADDR;
+ pm_info->ddrc_base.vbase = (void __iomem *)
+ IMX_IO_P2V(MX7D_DDRC_BASE_ADDR);
+
+ pm_info->ddrc_phy_base.pbase = MX7D_DDRC_PHY_BASE_ADDR;
+ pm_info->ddrc_phy_base.vbase = (void __iomem *)
+ IMX_IO_P2V(MX7D_DDRC_PHY_BASE_ADDR);
+
+ pm_info->src_base.pbase = MX7D_SRC_BASE_ADDR;
+ pm_info->src_base.vbase = (void __iomem *)
+ IMX_IO_P2V(MX7D_SRC_BASE_ADDR);
+
+ pm_info->iomuxc_gpr_base.pbase = MX7D_IOMUXC_GPR_BASE_ADDR;
+ pm_info->iomuxc_gpr_base.vbase = (void __iomem *)
+ IMX_IO_P2V(MX7D_IOMUXC_GPR_BASE_ADDR);
+
+ pm_info->gpc_base.pbase = MX7D_GPC_BASE_ADDR;
+ pm_info->gpc_base.vbase = (void __iomem *)
+ IMX_IO_P2V(MX7D_GPC_BASE_ADDR);
+
+ pm_info->anatop_base.pbase = MX7D_ANATOP_BASE_ADDR;
+ pm_info->anatop_base.vbase = (void __iomem *)
+ IMX_IO_P2V(MX7D_ANATOP_BASE_ADDR);
+
+ pm_info->snvs_base.pbase = MX7D_SNVS_BASE_ADDR;
+ pm_info->snvs_base.vbase = (void __iomem *)
+ IMX_IO_P2V(MX7D_SNVS_BASE_ADDR);
+
+ pm_info->lpsr_base.pbase = MX7D_LPSR_BASE_ADDR;
+ lpsr_base = pm_info->lpsr_base.vbase = (void __iomem *)
+ IMX_IO_P2V(MX7D_LPSR_BASE_ADDR);
+
+ pm_info->gic_base.pbase = MX7D_GIC_BASE_ADDR;
+ pm_info->gic_base.vbase = (void __iomem *)
+ IMX_IO_P2V(MX7D_GIC_BASE_ADDR);
+
+ pm_info->ddrc_num = socdata->ddrc_num;
+ ddrc_offset_array = socdata->ddrc_offset;
+ pm_info->ddrc_phy_num = socdata->ddrc_phy_num;
+ ddrc_phy_offset_array = socdata->ddrc_phy_offset;
+
+ /* initialize DDRC settings */
+ for (i = 0; i < pm_info->ddrc_num; i++) {
+ pm_info->ddrc_val[i][0] = ddrc_offset_array[i][0];
+ if (ddrc_offset_array[i][1] == READ_DATA_FROM_HARDWARE)
+ pm_info->ddrc_val[i][1] =
+ readl_relaxed(pm_info->ddrc_base.vbase +
+ ddrc_offset_array[i][0]);
+ else
+ pm_info->ddrc_val[i][1] = ddrc_offset_array[i][1];
+
+ if (pm_info->ddrc_val[i][0] == 0xd0)
+ pm_info->ddrc_val[i][1] |= 0xc0000000;
+ }
+
+ /* initialize DDRC PHY settings */
+ for (i = 0; i < pm_info->ddrc_phy_num; i++) {
+ pm_info->ddrc_phy_val[i][0] =
+ ddrc_phy_offset_array[i][0];
+ if (ddrc_phy_offset_array[i][1] == READ_DATA_FROM_HARDWARE)
+ pm_info->ddrc_phy_val[i][1] =
+ readl_relaxed(pm_info->ddrc_phy_base.vbase +
+ ddrc_phy_offset_array[i][0]);
+ else
+ pm_info->ddrc_phy_val[i][1] =
+ ddrc_phy_offset_array[i][1];
+ }
+
+ if (psci_ops.cpu_suspend)
+ goto put_node;
+
+ imx7_suspend_in_ocram_fn = fncpy(
+ suspend_ocram_base + sizeof(*pm_info),
+ &imx7_suspend,
+ MX7_SUSPEND_OCRAM_SIZE - sizeof(*pm_info));
+
+ goto put_node;
+
+put_node:
+ of_node_put(node);
+
+ return ret;
+}
+
+static void __init imx7_pm_common_init(const struct imx7_pm_socdata
+ *socdata)
+{
+ int ret;
+ struct regmap *gpr;
+
+ if (IS_ENABLED(CONFIG_SUSPEND)) {
+ ret = imx7_suspend_init(socdata);
+ if (ret)
+ pr_warn("%s: No DDR LPM support with suspend %d!\n",
+ __func__, ret);
+ }
+
+ /*
+ * Force IOMUXC irq pending, so that the interrupt to GPC can be
+ * used to deassert dsm_request signal when the signal gets
+ * asserted unexpectedly.
+ */
+ gpr = syscon_regmap_lookup_by_compatible("fsl,imx7d-iomuxc-gpr");
+ if (!IS_ERR(gpr))
+ regmap_update_bits(gpr, IOMUXC_GPR1, IMX7D_GPR1_IRQ_MASK,
+ IMX7D_GPR1_IRQ_MASK);
+}
+
+void __init imx7d_pm_init(void)
+{
+ struct device_node *np;
+ struct resource res;
+ if (imx_src_is_m4_enabled()) {
+ /* map the 32K of M4 TCM */
+ np = of_find_node_by_path(
+ "/tcml@007f8000");
+ if (np)
+ lpm_m4tcm_base = of_iomap(np, 0);
+ WARN_ON(!lpm_m4tcm_base);
+
+ /* map the m4 bootrom from dtb */
+ np = of_find_node_by_path(
+ "/soc/sram@00180000");
+ if (np)
+ m4_bootrom_base = of_iomap(np, 0);
+ WARN_ON(!m4_bootrom_base);
+
+ lpm_m4tcm_saved_in_ddr = kzalloc(SZ_32K, GFP_KERNEL);
+ WARN_ON(!lpm_m4tcm_saved_in_ddr);
+
+ /* save M4 Image to DDR */
+ memcpy(lpm_m4tcm_saved_in_ddr, lpm_m4tcm_base, SZ_32K);
+ }
+ np = of_find_compatible_node(NULL, NULL, "fsl,lpm-sram");
+ if (of_get_property(np, "fsl,enable-lpsr", NULL))
+ lpsr_enabled = true;
+
+ if (psci_ops.cpu_suspend)
+ lpsr_enabled = false;
+
+ if (lpsr_enabled) {
+ pr_info("LPSR mode enabled, DSM will go into LPSR mode!\n");
+ lpm_ocram_base = of_iomap(np, 0);
+ WARN_ON(!lpm_ocram_base);
+ WARN_ON(of_address_to_resource(np, 0, &res));
+ lpm_ocram_size = resource_size(&res);
+ lpm_ocram_saved_in_ddr = kzalloc(lpm_ocram_size, GFP_KERNEL);
+ WARN_ON(!lpm_ocram_saved_in_ddr);
+
+ np = of_find_node_by_path(
+ "/soc/aips-bus@30000000/iomuxc@30330000");
+ if (np)
+ iomuxc_base = of_iomap(np, 0);
+ WARN_ON(!iomuxc_base);
+
+ np = of_find_node_by_path(
+ "/soc/aips-bus@30000000/gpt@302d0000");
+ if (np)
+ gpt1_base = of_iomap(np, 0);
+ WARN_ON(!gpt1_base);
+
+ np = of_find_node_by_path(
+ "/soc/aips-bus@30400000/system-counter-cmp@306b0000");
+ if (np)
+ system_counter_cmp_base = of_iomap(np, 0);
+ WARN_ON(!system_counter_cmp_base);
+
+ np = of_find_node_by_path(
+ "/soc/aips-bus@30000000/gpio@30200000");
+ if (np)
+ gpio1_base = of_iomap(np, 0);
+ WARN_ON(!gpio1_base);
+ }
+
+ np = of_find_node_by_path(
+ "/soc/aips-bus@30400000/system-counter-ctrl@306c0000");
+ if (np)
+ system_counter_ctrl_base = of_iomap(np, 0);
+ WARN_ON(!system_counter_ctrl_base);
+
+ if (imx_ddrc_get_ddr_type() == IMX_DDR_TYPE_LPDDR3
+ || imx_ddrc_get_ddr_type() == IMX_DDR_TYPE_LPDDR2)
+ imx7_pm_common_init(&imx7d_pm_data_lpddr3);
+ else if (imx_ddrc_get_ddr_type() == IMX_DDR_TYPE_DDR3)
+ imx7_pm_common_init(&imx7d_pm_data_ddr3);
+
+ np = of_find_compatible_node(NULL, NULL, "fsl,mega-fast-sram");
+ ocram_base = of_iomap(np, 0);
+ WARN_ON(!ocram_base);
+ WARN_ON(of_address_to_resource(np, 0, &res));
+ ocram_size = resource_size(&res);
+ ocram_saved_in_ddr = kzalloc(ocram_size, GFP_KERNEL);
+ WARN_ON(!ocram_saved_in_ddr);
+
+ np = of_find_node_by_path(
+ "/soc/aips-bus@30800000/serial@30860000");
+ if (np)
+ console_base = of_iomap(np, 0);
+
+ /* clear LPSR resume address first */
+ imx7_pm_set_lpsr_resume_addr(0);
+}
diff --git a/arch/arm/mach-imx/pm-imx7ulp.c b/arch/arm/mach-imx/pm-imx7ulp.c
new file mode 100644
index 000000000000..238d36cd7d24
--- /dev/null
+++ b/arch/arm/mach-imx/pm-imx7ulp.c
@@ -0,0 +1,826 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017-2018 NXP
+ *
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/delay.h>
+#include <linux/console.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/genalloc.h>
+#include <linux/mfd/syscon.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_fdt.h>
+#include <linux/of_irq.h>
+#include <linux/psci.h>
+#include <linux/of_platform.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+#include <linux/suspend.h>
+#include <asm/cacheflush.h>
+#include <asm/fncpy.h>
+#include <asm/mach/map.h>
+#include <asm/proc-fns.h>
+#include <asm/suspend.h>
+#include <asm/tlb.h>
+
+#include <uapi/linux/psci.h>
+
+#include "common.h"
+#include "hardware.h"
+
+#define MU_SR 0x60
+
+#define PMPROT 0x8
+#define PMCTRL 0x10
+#define PMSTAT 0x18
+#define SRS 0x20
+#define RPC 0x24
+#define SSRS 0x28
+#define SRIE 0x2c
+#define SRIF 0x30
+#define CSRE 0x34
+#define MR 0x40
+
+#define PMC_HSRUN 0x4
+#define PMC_RUN 0x8
+#define PMC_VLPR 0xc
+#define PMC_STOP 0x10
+#define PMC_VLPS 0x14
+#define PMC_LLS 0x18
+#define PMC_VLLS 0x1c
+#define PMC_STATUS 0x20
+#define PMC_CTRL 0x24
+#define PMC_SRAMCTRL_0 0x28
+#define PMC_SRAMCTRL_1 0x2c
+#define PMC_SRAMCTRL_2 0x30
+
+#define BM_PMPROT_AHSRUN (1 << 7)
+#define BM_PMPROT_AVLP (1 << 5)
+#define BM_PMPROT_ALLS (1 << 3)
+#define BM_PMPROT_AVLLS (1 << 1)
+
+#define BM_PMCTRL_STOPA (1 << 24)
+#define BM_PMCTRL_PSTOPO (3 << 16)
+#define BM_PMCTRL_RUNM (3 << 8)
+#define BM_PMCTRL_STOPM (7 << 0)
+
+#define BM_VLPS_RBBEN (1 << 28)
+
+#define BM_CTRL_LDOEN (1 << 31)
+#define BM_CTRL_LDOOKDIS (1 << 30)
+
+#define BM_VLLS_MON1P2HVDHP (1 << 5)
+#define BM_VLLS_MON1P2LVDHP (1 << 4)
+
+#define BP_PMCTRL_STOPM 0
+#define BP_PMCTRL_PSTOPO 16
+
+#define MX7ULP_MAX_MMDC_IO_NUM 64
+#define MX7ULP_MAX_MMDC_NUM 50
+#define MX7ULP_MAX_IOMUX_NUM 116
+#define MX7ULP_MAX_SELECT_INPUT_NUM 78
+
+#define IOMUX_START 0x0
+#define SELECT_INPUT_START 0x200
+
+#define TPM_SC 0x10
+#define TPM_MOD 0x18
+#define TPM_C0SC 0x20
+#define TPM_C0V 0x24
+
+#define PCC2_ENABLE_PCS_FIRC ((1 << 30) | (3 << 24))
+#define PCC2_ENABLE (1 << 30)
+
+#define LPUART_BAUD 0x10
+#define LPUART_CTRL 0x18
+#define LPUART_FIFO 0x28
+#define LPUART_WATER 0x2c
+
+#define GPIO_PDOR 0x0
+#define GPIO_PDDR 0x14
+
+#define PTC2_LPUART4_TX_OFFSET 0x8
+#define PTC3_LPUART4_RX_OFFSET 0xc
+#define PTC2_LPUART4_TX_INPUT_OFFSET 0x248
+#define PTC3_LPUART4_RX_INPUT_OFFSET 0x24c
+#define LPUART4_MUX_VALUE (4 << 8)
+#define LPUART4_INPUT_VALUE (1)
+
+#define MU_B_SR_NMIC (1 << 3)
+
+#define DGO_GPR3 0x60
+#define DGO_GPR4 0x64
+
+#define ADDR_1M_MASK 0xFFF00000
+
+static void __iomem *smc1_base;
+static void __iomem *pmc0_base;
+static void __iomem *pmc1_base;
+static void __iomem *tpm5_base;
+static void __iomem *lpuart4_base;
+static void __iomem *iomuxc1_base;
+static void __iomem *pcc2_base;
+static void __iomem *pcc3_base;
+static void __iomem *mu_base;
+static void __iomem *scg1_base;
+static void __iomem *gpio_base[4];
+static void __iomem *suspend_ocram_base;
+static void (*imx7ulp_suspend_in_ocram_fn)(void __iomem *sram_base);
+
+static u32 tpm5_regs[4];
+static u32 lpuart4_regs[4];
+static u32 pcc2_regs[24][2] = {
+ {0x20, 0}, {0x3c, 0}, {0x40, 0}, {0x6c, 0},
+ {0x84, 0}, {0x90, 0}, {0x94, 0}, {0x98, 0},
+ {0x9c, 0}, {0xa4, 0}, {0xa8, 0}, {0xac, 0},
+ {0xb0, 0}, {0xb4, 0}, {0xb8, 0}, {0xc4, 0},
+ {0xcc, 0}, {0xd0, 0}, {0xd4, 0}, {0xd8, 0},
+ {0xdc, 0}, {0xe0, 0}, {0xf4, 0}, {0x10c, 0},
+};
+
+static u32 pcc3_regs[16][2] = {
+ {0x84, 0}, {0x88, 0}, {0x90, 0}, {0x94, 0},
+ {0x98, 0}, {0x9c, 0}, {0xa0, 0}, {0xa4, 0},
+ {0xa8, 0}, {0xac, 0}, {0xb8, 0}, {0xbc, 0},
+ {0xc0, 0}, {0xc4, 0}, {0x140, 0}, {0x144, 0},
+};
+
+static u32 scg1_offset[17] = {
+ 0x14, 0x30, 0x40, 0x304,
+ 0x500, 0x504, 0x508, 0x50c,
+ 0x510, 0x514, 0x600, 0x604,
+ 0x608, 0x60c, 0x610, 0x614,
+ 0x104,
+};
+
+extern unsigned long iram_tlb_base_addr;
+extern unsigned long iram_tlb_phys_addr;
+
+/*
+ * suspend ocram space layout:
+ * ======================== high address ======================
+ * .
+ * .
+ * .
+ * ^
+ * ^
+ * ^
+ * imx7ulp_suspend code
+ * PM_INFO structure(imx7ulp_cpu_pm_info)
+ * ======================== low address =======================
+ */
+struct imx7ulp_pm_socdata {
+ u32 ddr_type;
+ const char *mmdc_compat;
+ const u32 mmdc_io_num;
+ const u32 *mmdc_io_offset;
+ const u32 mmdc_num;
+ const u32 *mmdc_offset;
+};
+
+static const u32 imx7ulp_mmdc_io_lpddr3_offset[] __initconst = {
+ 0x0, 0x4, 0x8, 0xc,
+ 0x10, 0x14, 0x18, 0x1c,
+ 0x20, 0x24, 0x28, 0x2c,
+ 0x30, 0x34, 0x38, 0x3c,
+ 0x40, 0x44, 0x48, 0x4c,
+ 0x50, 0x54, 0x58, 0x5c,
+ 0x60, 0x64, 0x68, 0x6c,
+ 0x70, 0x74, 0x78, 0x7c,
+ 0x80, 0x84, 0x88, 0x8c,
+ 0x90, 0x94, 0x98, 0x9c,
+ 0xa0, 0xa4, 0xa8, 0xac,
+ 0xb0, 0xb4, 0xb8, 0xbc,
+ 0xc0, 0xc4, 0xc8, 0xcc,
+ 0xd0, 0xd4, 0xd8, 0xdc,
+ 0xe8, 0xf8, 0xfc, 0x120,
+ 0x124,
+};
+
+static const u32 imx7ulp_mmdc_lpddr3_offset[] __initconst = {
+ 0x01c, 0x800, 0x85c, 0x890,
+ 0x848, 0x850, 0x81c, 0x820,
+ 0x824, 0x828, 0x82c, 0x830,
+ 0x834, 0x838, 0x8c0, 0x8b8,
+ 0x004, 0x00c, 0x010, 0x038,
+ 0x014, 0x018, 0x02c, 0x030,
+ 0x040, 0x000, 0x01c, 0x01c,
+ 0x01c, 0x01c, 0x01c, 0x01c,
+ 0x01c, 0x01c, 0x01c, 0x01c,
+ 0x01c, 0x01c, 0x83c, 0x020,
+ 0x800, 0x004, 0x404, 0x01c,
+};
+
+static const u32 imx7ulp_lpddr3_script[] __initconst = {
+ 0x00008000, 0xA1390003, 0x0D3900A0, 0x00400000,
+ 0x40404040, 0x40404040, 0x33333333, 0x33333333,
+ 0x33333333, 0x33333333, 0xf3333333, 0xf3333333,
+ 0xf3333333, 0xf3333333, 0x24922492, 0x00000800,
+ 0x00020052, 0x292C42F3, 0x00100A22, 0x00120556,
+ 0x00C700DB, 0x00211718, 0x0F9F26D2, 0x009F0E10,
+ 0x0000003F, 0xC3190000, 0x00008050, 0x00008058,
+ 0x003F8030, 0x003F8038, 0xFF0A8030, 0xFF0A8038,
+ 0x04028030, 0x04028038, 0x83018030, 0x83018038,
+ 0x01038030, 0x01038038, 0x20000000, 0x00001800,
+ 0xA1310000, 0x00020052, 0x00011006, 0x00000000,
+};
+
+static const struct imx7ulp_pm_socdata imx7ulp_lpddr3_pm_data __initconst = {
+ .mmdc_compat = "fsl,imx7ulp-mmdc",
+ .mmdc_io_num = ARRAY_SIZE(imx7ulp_mmdc_io_lpddr3_offset),
+ .mmdc_io_offset = imx7ulp_mmdc_io_lpddr3_offset,
+ .mmdc_num = ARRAY_SIZE(imx7ulp_mmdc_lpddr3_offset),
+ .mmdc_offset = imx7ulp_mmdc_lpddr3_offset,
+};
+
+/*
+ * This structure is for passing necessary data for low level ocram
+ * suspend code(arch/arm/mach-imx/suspend-imx7ulp.S), if this struct
+ * definition is changed, the offset definition in
+ * arch/arm/mach-imx/suspend-imx7ulp.S must be also changed accordingly,
+ * otherwise, the suspend to sram function will be broken!
+ */
+struct imx7ulp_cpu_pm_info {
+ u32 m4_reserve0;
+ u32 m4_reserve1;
+ u32 m4_reserve2;
+ phys_addr_t pbase; /* The physical address of pm_info. */
+ phys_addr_t resume_addr; /* The physical resume address for asm code */
+ u32 pm_info_size; /* Size of pm_info. */
+ void __iomem *sim_base;
+ void __iomem *scg1_base;
+ void __iomem *mmdc_base;
+ void __iomem *mmdc_io_base;
+ void __iomem *smc1_base;
+ u32 scg1[17];
+ u32 ttbr1; /* Store TTBR1 */
+ u32 gpio[4][2];
+ u32 iomux_num; /* Number of IOs which need saved/restored. */
+ u32 iomux_val[MX7ULP_MAX_IOMUX_NUM]; /* To save value */
+ u32 select_input_num; /* Number of select input which need saved/restored. */
+ u32 select_input_val[MX7ULP_MAX_SELECT_INPUT_NUM]; /* To save value */
+ u32 mmdc_io_num; /* Number of MMDC IOs which need saved/restored. */
+ u32 mmdc_io_val[MX7ULP_MAX_MMDC_IO_NUM][2]; /* To save offset and value */
+ u32 mmdc_num; /* Number of MMDC registers which need saved/restored. */
+ u32 mmdc_val[MX7ULP_MAX_MMDC_NUM][2];
+} __aligned(8);
+
+static struct imx7ulp_cpu_pm_info *pm_info;
+static void __iomem *aips1_base;
+static void __iomem *aips2_base;
+static void __iomem *aips3_base;
+static void __iomem *aips4_base;
+static void __iomem *aips5_base;
+
+static const char * const low_power_ocram_match[] __initconst = {
+ "fsl,lpm-sram",
+ NULL
+};
+
+static void imx7ulp_gpio_save(void)
+{
+ int i;
+
+ for (i = 0; i < 4; i++) {
+ pm_info->gpio[i][0] = readl_relaxed(gpio_base[i] + GPIO_PDOR);
+ pm_info->gpio[i][1] = readl_relaxed(gpio_base[i] + GPIO_PDDR);
+ }
+}
+
+static void imx7ulp_scg1_save(void)
+{
+ int i;
+
+ for (i = 0; i < 17; i++)
+ pm_info->scg1[i] = readl_relaxed(scg1_base + scg1_offset[i]);
+}
+
+static void imx7ulp_pcc3_save(void)
+{
+ int i;
+
+ for (i = 0; i < 16; i++)
+ pcc3_regs[i][1] = readl_relaxed(pcc3_base + pcc3_regs[i][0]);
+}
+
+static void imx7ulp_pcc3_restore(void)
+{
+ int i;
+
+ for (i = 0; i < 16; i++)
+ writel_relaxed(pcc3_regs[i][1], pcc3_base + pcc3_regs[i][0]);
+}
+
+static void imx7ulp_pcc2_save(void)
+{
+ int i;
+
+ for (i = 0; i < 24; i++)
+ pcc2_regs[i][1] = readl_relaxed(pcc2_base + pcc2_regs[i][0]);
+}
+
+static void imx7ulp_pcc2_restore(void)
+{
+ int i;
+
+ for (i = 0; i < 24; i++)
+ writel_relaxed(pcc2_regs[i][1], pcc2_base + pcc2_regs[i][0]);
+}
+
+static inline void imx7ulp_iomuxc_save(void)
+{
+ int i;
+
+ pm_info->iomux_num = MX7ULP_MAX_IOMUX_NUM;
+ pm_info->select_input_num = MX7ULP_MAX_SELECT_INPUT_NUM;
+
+ for (i = 0; i < pm_info->iomux_num; i++)
+ pm_info->iomux_val[i] =
+ readl_relaxed(iomuxc1_base +
+ IOMUX_START + i * 0x4);
+ for (i = 0; i < pm_info->select_input_num; i++)
+ pm_info->select_input_val[i] =
+ readl_relaxed(iomuxc1_base +
+ SELECT_INPUT_START + i * 0x4);
+}
+
+static void imx7ulp_lpuart_save(void)
+{
+ lpuart4_regs[0] = readl_relaxed(lpuart4_base + LPUART_BAUD);
+ lpuart4_regs[1] = readl_relaxed(lpuart4_base + LPUART_FIFO);
+ lpuart4_regs[2] = readl_relaxed(lpuart4_base + LPUART_WATER);
+ lpuart4_regs[3] = readl_relaxed(lpuart4_base + LPUART_CTRL);
+}
+
+static void imx7ulp_lpuart_restore(void)
+{
+ writel_relaxed(LPUART4_MUX_VALUE,
+ iomuxc1_base + PTC2_LPUART4_TX_OFFSET);
+ writel_relaxed(LPUART4_MUX_VALUE,
+ iomuxc1_base + PTC3_LPUART4_RX_OFFSET);
+ writel_relaxed(LPUART4_INPUT_VALUE,
+ iomuxc1_base + PTC2_LPUART4_TX_INPUT_OFFSET);
+ writel_relaxed(LPUART4_INPUT_VALUE,
+ iomuxc1_base + PTC3_LPUART4_RX_INPUT_OFFSET);
+
+ writel_relaxed(lpuart4_regs[0], lpuart4_base + LPUART_BAUD);
+ writel_relaxed(lpuart4_regs[1], lpuart4_base + LPUART_FIFO);
+ writel_relaxed(lpuart4_regs[2], lpuart4_base + LPUART_WATER);
+ writel_relaxed(lpuart4_regs[3], lpuart4_base + LPUART_CTRL);
+}
+
+static void imx7ulp_tpm_save(void)
+{
+ tpm5_regs[0] = readl_relaxed(tpm5_base + TPM_SC);
+ tpm5_regs[1] = readl_relaxed(tpm5_base + TPM_MOD);
+ tpm5_regs[2] = readl_relaxed(tpm5_base + TPM_C0SC);
+ tpm5_regs[3] = readl_relaxed(tpm5_base + TPM_C0V);
+}
+
+static void imx7ulp_tpm_restore(void)
+{
+ writel_relaxed(tpm5_regs[0], tpm5_base + TPM_SC);
+ writel_relaxed(tpm5_regs[1], tpm5_base + TPM_MOD);
+ writel_relaxed(tpm5_regs[2], tpm5_base + TPM_C0SC);
+ writel_relaxed(tpm5_regs[3], tpm5_base + TPM_C0V);
+}
+
+static void imx7ulp_set_dgo(u32 val)
+{
+ writel_relaxed(val, pm_info->sim_base + DGO_GPR3);
+ writel_relaxed(val, pm_info->sim_base + DGO_GPR4);
+}
+
+int imx7ulp_set_lpm(enum imx7ulp_cpu_pwr_mode mode)
+{
+ u32 val1 = BM_PMPROT_AHSRUN | BM_PMPROT_AVLP | BM_PMPROT_AVLLS;
+ u32 val2 = readl_relaxed(smc1_base + PMCTRL);
+ u32 val3 = readl_relaxed(pmc0_base + PMC_CTRL);
+
+ val2 &= ~(BM_PMCTRL_RUNM |
+ BM_PMCTRL_STOPM | BM_PMCTRL_PSTOPO);
+ val3 |= BM_CTRL_LDOOKDIS;
+
+ switch (mode) {
+ case RUN:
+ /* system/bus clock enabled */
+ val2 |= 0x3 << BP_PMCTRL_PSTOPO;
+ break;
+ case WAIT:
+ /* system clock disabled, bus clock enabled */
+ val2 |= 0x2 << BP_PMCTRL_PSTOPO;
+ break;
+ case STOP:
+ /* system/bus clock disabled */
+ val2 |= 0x1 << BP_PMCTRL_PSTOPO;
+ break;
+ case VLPS:
+ val2 |= 0x2 << BP_PMCTRL_STOPM;
+ break;
+ case VLLS:
+ val2 |= 0x4 << BP_PMCTRL_STOPM;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ writel_relaxed(val1, smc1_base + PMPROT);
+ writel_relaxed(val2, smc1_base + PMCTRL);
+ writel_relaxed(val3, pmc0_base + PMC_CTRL);
+
+ return 0;
+}
+
+#define MX7ULP_SUSPEND_POWERDWN_PARAM \
+ ((0 << PSCI_0_2_POWER_STATE_ID_SHIFT) | \
+ (1 << PSCI_0_2_POWER_STATE_AFFL_SHIFT) | \
+ (PSCI_POWER_STATE_TYPE_POWER_DOWN << PSCI_0_2_POWER_STATE_TYPE_SHIFT))
+
+#define MX7ULP_SUSPEND_STANDBY_PARAM \
+ ((0 << PSCI_0_2_POWER_STATE_ID_SHIFT) | \
+ (1 << PSCI_0_2_POWER_STATE_AFFL_SHIFT) | \
+ (PSCI_POWER_STATE_TYPE_STANDBY << PSCI_0_2_POWER_STATE_TYPE_SHIFT))
+
+static int imx7ulp_suspend_finish(unsigned long val)
+{
+ u32 state;
+
+ if (val == 0)
+ state = MX7ULP_SUSPEND_POWERDWN_PARAM;
+ else
+ state = MX7ULP_SUSPEND_STANDBY_PARAM;
+
+ if (psci_ops.cpu_suspend) {
+ return psci_ops.cpu_suspend(state, __pa(cpu_resume));
+ }
+
+ imx7ulp_suspend_in_ocram_fn(suspend_ocram_base);
+
+ return 0;
+}
+
+static int imx7ulp_pm_enter(suspend_state_t state)
+{
+ switch (state) {
+ case PM_SUSPEND_STANDBY:
+ if (psci_ops.cpu_suspend) {
+ /* Zzz ... */
+ cpu_suspend(1, imx7ulp_suspend_finish);
+ } else {
+ imx7ulp_set_lpm(VLPS);
+ writel_relaxed(
+ readl_relaxed(pmc1_base + PMC_VLPS) | BM_VLPS_RBBEN,
+ pmc1_base + PMC_VLPS);
+
+ /* Zzz ... */
+ cpu_suspend(0, imx7ulp_suspend_finish);
+
+ writel_relaxed(
+ readl_relaxed(pmc1_base + PMC_VLPS) & ~BM_VLPS_RBBEN,
+ pmc1_base + PMC_VLPS);
+ imx7ulp_set_lpm(RUN);
+ }
+ break;
+ case PM_SUSPEND_MEM:
+ if (psci_ops.cpu_suspend) {
+ /* Zzz ... */
+ cpu_suspend(0, imx7ulp_suspend_finish);
+ } else {
+ imx7ulp_gpio_save();
+ imx7ulp_scg1_save();
+ imx7ulp_pcc2_save();
+ imx7ulp_pcc3_save();
+ imx7ulp_tpm_save();
+ if (!console_suspend_enabled)
+ imx7ulp_lpuart_save();
+ imx7ulp_iomuxc_save();
+ imx7ulp_set_lpm(VLLS);
+
+ /* Zzz ... */
+ cpu_suspend(0, imx7ulp_suspend_finish);
+
+ imx7ulp_pcc2_restore();
+ imx7ulp_pcc3_restore();
+ if (!console_suspend_enabled)
+ imx7ulp_lpuart_restore();
+ imx7ulp_set_dgo(0);
+ imx7ulp_tpm_restore();
+ imx7ulp_set_lpm(RUN);
+ }
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+/* Put CA7 into VLLS mode before M4 power off CA7 */
+void imx7ulp_poweroff(void)
+{
+ imx7ulp_set_lpm(VLLS);
+ cpu_suspend(0, imx7ulp_suspend_finish);
+}
+
+static int imx7ulp_pm_valid(suspend_state_t state)
+{
+ return (state == PM_SUSPEND_STANDBY || state == PM_SUSPEND_MEM);
+}
+
+static const struct platform_suspend_ops imx7ulp_pm_ops = {
+ .enter = imx7ulp_pm_enter,
+ .valid = imx7ulp_pm_valid,
+};
+
+static int __init imx7ulp_suspend_init(void)
+{
+ int ret = 0;
+
+ suspend_set_ops(&imx7ulp_pm_ops);
+
+ return ret;
+}
+
+static struct map_desc iram_tlb_io_desc __initdata = {
+ /* .virtual and .pfn are run-time assigned */
+ .length = SZ_1M,
+ .type = MT_MEMORY_RWX_NONCACHED,
+};
+
+static int __init imx7ulp_dt_find_lpsram(unsigned long node, const char *uname,
+ int depth, void *data)
+{
+ unsigned long lpram_addr;
+ const __be32 *prop = of_get_flat_dt_prop(node, "reg", NULL);
+
+ if (of_flat_dt_match(node, low_power_ocram_match)) {
+ if (!prop)
+ return -EINVAL;
+
+ lpram_addr = be32_to_cpup(prop);
+
+ /* We need to create a 1M page table entry. */
+ iram_tlb_io_desc.virtual =
+ IMX_IO_P2V(lpram_addr & ADDR_1M_MASK);
+ iram_tlb_io_desc.pfn = __phys_to_pfn(lpram_addr & ADDR_1M_MASK);
+ iram_tlb_phys_addr = lpram_addr;
+ iram_tlb_base_addr = IMX_IO_P2V(lpram_addr);
+ iotable_init(&iram_tlb_io_desc, 1);
+ }
+
+ return 0;
+}
+
+void __init imx7ulp_pm_map_io(void)
+{
+ /*
+ * Get the address of IRAM or OCRAM to be used by the low
+ * power code from the device tree.
+ */
+ WARN_ON(of_scan_flat_dt(imx7ulp_dt_find_lpsram, NULL));
+
+ /* Return if no IRAM space is allocated for suspend/resume code. */
+ if (!iram_tlb_base_addr) {
+ pr_warn("No valid ocram available for suspend/resume!\n");
+ return;
+ }
+}
+
+void __init imx7ulp_pm_common_init(const struct imx7ulp_pm_socdata
+ *socdata)
+{
+ struct device_node *np;
+ unsigned long sram_paddr = 0;
+ const u32 *mmdc_offset_array;
+ const u32 *mmdc_io_offset_array;
+ unsigned long i, j;
+ int ret;
+
+ if (psci_ops.cpu_suspend) {
+ aips1_base = ioremap(MX7ULP_AIPS1_BASE_ADDR, SZ_1M);
+ aips2_base = ioremap(MX7ULP_AIPS2_BASE_ADDR, SZ_1M);
+ aips3_base = ioremap(MX7ULP_AIPS3_BASE_ADDR, SZ_1M);
+ aips4_base = ioremap(MX7ULP_AIPS4_BASE_ADDR, SZ_1M);
+ aips5_base = ioremap(MX7ULP_AIPS5_BASE_ADDR, SZ_1M);
+ } else {
+ /* Set all entries to 0 except first 3 words reserved for M4. */
+ memset((void *)iram_tlb_base_addr, 0, MX7ULP_IRAM_TLB_SIZE);
+
+ /*
+ * Make sure the IRAM virtual address has a mapping in the IRAM
+ * page table.
+ *
+ * Only use the top 12 bits [31-20] when storing the physical
+ * address in the page table as only these bits are required
+ * for 1M mapping.
+ */
+ j = ((iram_tlb_base_addr >> 20) << 2) / 4;
+ *((unsigned long *)iram_tlb_base_addr + j) =
+ (iram_tlb_phys_addr & ADDR_1M_MASK) |
+ TT_ATTRIB_NON_CACHEABLE_1M;
+ /*
+ * Make sure the AIPS1 virtual address has a mapping in the
+ * IRAM page table.
+ */
+ aips1_base = ioremap(MX7ULP_AIPS1_BASE_ADDR, SZ_1M);
+ j = (((u32)aips1_base >> 20) << 2) / 4;
+ *((unsigned long *)iram_tlb_base_addr + j) =
+ ((MX7ULP_AIPS1_BASE_ADDR) & ADDR_1M_MASK) |
+ TT_ATTRIB_NON_CACHEABLE_1M;
+ /*
+ * Make sure the AIPS2 virtual address has a mapping in the
+ * IRAM page table.
+ */
+ aips2_base = ioremap(MX7ULP_AIPS2_BASE_ADDR, SZ_1M);
+ j = (((u32)aips2_base >> 20) << 2) / 4;
+ *((unsigned long *)iram_tlb_base_addr + j) =
+ ((MX7ULP_AIPS2_BASE_ADDR) & ADDR_1M_MASK) |
+ TT_ATTRIB_NON_CACHEABLE_1M;
+ /*
+ * Make sure the AIPS3 virtual address has a mapping in the
+ * IRAM page table.
+ */
+ aips3_base = ioremap(MX7ULP_AIPS3_BASE_ADDR, SZ_1M);
+ j = (((u32)aips3_base >> 20) << 2) / 4;
+ *((unsigned long *)iram_tlb_base_addr + j) =
+ ((MX7ULP_AIPS3_BASE_ADDR) & ADDR_1M_MASK) |
+ TT_ATTRIB_NON_CACHEABLE_1M;
+ /*
+ * Make sure the AIPS4 virtual address has a mapping in the
+ * IRAM page table.
+ */
+ aips4_base = ioremap(MX7ULP_AIPS4_BASE_ADDR, SZ_1M);
+ j = (((u32)aips4_base >> 20) << 2) / 4;
+ *((unsigned long *)iram_tlb_base_addr + j) =
+ ((MX7ULP_AIPS4_BASE_ADDR) & ADDR_1M_MASK) |
+ TT_ATTRIB_NON_CACHEABLE_1M;
+ /*
+ * Make sure the AIPS5 virtual address has a mapping in the
+ * IRAM page table.
+ */
+ aips5_base = ioremap(MX7ULP_AIPS5_BASE_ADDR, SZ_1M);
+ j = (((u32)aips5_base >> 20) << 2) / 4;
+ *((unsigned long *)iram_tlb_base_addr + j) =
+ ((MX7ULP_AIPS5_BASE_ADDR) & ADDR_1M_MASK) |
+ TT_ATTRIB_NON_CACHEABLE_1M;
+ }
+
+ np = of_find_compatible_node(NULL, NULL, "fsl,imx7ulp-smc1");
+ smc1_base = of_iomap(np, 0);
+ WARN_ON(!smc1_base);
+
+ np = of_find_compatible_node(NULL, NULL, "fsl,imx7ulp-pmc0");
+ pmc0_base = of_iomap(np, 0);
+ WARN_ON(!pmc0_base);
+
+ np = of_find_compatible_node(NULL, NULL, "fsl,imx7ulp-pmc1");
+ pmc1_base = of_iomap(np, 0);
+ WARN_ON(!pmc1_base);
+
+ np = of_find_compatible_node(NULL, NULL, "fsl,imx7ulp-tpm");
+ tpm5_base = of_iomap(np, 0);
+ WARN_ON(!tpm5_base);
+
+ np = of_find_compatible_node(NULL, NULL, "fsl,imx7ulp-lpuart");
+ lpuart4_base = of_iomap(np, 0);
+ WARN_ON(!lpuart4_base);
+
+ np = of_find_compatible_node(NULL, NULL, "fsl,imx7ulp-pcc2");
+ pcc2_base = of_iomap(np, 0);
+ WARN_ON(!pcc2_base);
+
+ np = of_find_compatible_node(NULL, NULL, "fsl,imx7ulp-pcc3");
+ pcc3_base = of_iomap(np, 0);
+ WARN_ON(!pcc3_base);
+
+ np = of_find_compatible_node(NULL, NULL, "fsl,imx7ulp-iomuxc-1");
+ iomuxc1_base = of_iomap(np, 0);
+ WARN_ON(!iomuxc1_base);
+
+ np = of_find_compatible_node(NULL, NULL, "fsl,imx7ulp-scg1");
+ scg1_base = of_iomap(np, 0);
+ WARN_ON(!scg1_base);
+
+ np = NULL;
+ for (i = 0; i < 4; i++) {
+ np = of_find_compatible_node(np, NULL, "fsl,vf610-gpio");
+ gpio_base[i] = of_iomap(np, 1);
+ WARN_ON(!gpio_base[i]);
+ }
+
+ if (psci_ops.cpu_suspend) {
+ pm_info = kzalloc(SZ_16K, GFP_KERNEL);
+ if (!pm_info)
+ panic("pm info allocation failed\n");
+ } else {
+ /*
+ * 16KB is allocated for IRAM TLB, but only up 8k is for kernel TLB,
+ * The lower 8K is not used, so use the lower 8K for IRAM code and
+ * pm_info.
+ *
+ */
+ sram_paddr = iram_tlb_phys_addr;
+
+ /* Make sure sram_paddr is 8 byte aligned. */
+ if ((uintptr_t)(sram_paddr) & (FNCPY_ALIGN - 1))
+ sram_paddr += FNCPY_ALIGN - sram_paddr % (FNCPY_ALIGN);
+
+ /* Get the virtual address of the suspend code. */
+ suspend_ocram_base = (void *)IMX_IO_P2V(sram_paddr);
+
+ pm_info = suspend_ocram_base;
+ }
+ pm_info->pbase = sram_paddr;
+ pm_info->resume_addr = virt_to_phys(imx7ulp_cpu_resume);
+ pm_info->pm_info_size = sizeof(*pm_info);
+
+ pm_info->scg1_base = aips2_base +
+ (MX7ULP_SCG1_BASE_ADDR & ~ADDR_1M_MASK);
+ pm_info->smc1_base = aips3_base +
+ (MX7ULP_SMC1_BASE_ADDR & ~ADDR_1M_MASK);
+ pm_info->mmdc_base = aips4_base +
+ (MX7ULP_MMDC_BASE_ADDR & ~ADDR_1M_MASK);
+ pm_info->mmdc_io_base = aips4_base +
+ (MX7ULP_MMDC_IO_BASE_ADDR & ~ADDR_1M_MASK);
+ pm_info->sim_base = aips5_base +
+ (MX7ULP_SIM_BASE_ADDR & ~ADDR_1M_MASK);
+
+ pm_info->mmdc_io_num = socdata->mmdc_io_num;
+ mmdc_io_offset_array = socdata->mmdc_io_offset;
+ pm_info->mmdc_num = socdata->mmdc_num;
+ mmdc_offset_array = socdata->mmdc_offset;
+
+ for (i = 0; i < pm_info->mmdc_io_num; i++) {
+ pm_info->mmdc_io_val[i][0] =
+ mmdc_io_offset_array[i];
+ pm_info->mmdc_io_val[i][1] =
+ readl_relaxed(pm_info->mmdc_io_base +
+ mmdc_io_offset_array[i]);
+ }
+
+ /* initialize MMDC settings */
+ for (i = 0; i < pm_info->mmdc_num; i++)
+ pm_info->mmdc_val[i][0] =
+ mmdc_offset_array[i];
+
+ for (i = 0; i < pm_info->mmdc_num; i++)
+ pm_info->mmdc_val[i][1] = imx7ulp_lpddr3_script[i];
+
+ if (!psci_ops.cpu_suspend) {
+ imx7ulp_suspend_in_ocram_fn = fncpy(
+ suspend_ocram_base + sizeof(*pm_info),
+ &imx7ulp_suspend,
+ MX7ULP_SUSPEND_OCRAM_SIZE - sizeof(*pm_info));
+ }
+
+ if (IS_ENABLED(CONFIG_SUSPEND)) {
+ ret = imx7ulp_suspend_init();
+ if (ret)
+ pr_warn("%s: No DDR LPM support with suspend %d!\n",
+ __func__, ret);
+ }
+}
+
+void __init imx7ulp_pm_init(void)
+{
+ imx7ulp_pm_common_init(&imx7ulp_lpddr3_pm_data);
+ imx7ulp_set_lpm(RUN);
+}
+
+static irqreturn_t imx7ulp_nmi_isr(int irq, void *param)
+{
+ writel_relaxed(readl_relaxed(mu_base + MU_SR) | MU_B_SR_NMIC,
+ mu_base + MU_SR);
+ pm_system_wakeup();
+
+ return IRQ_HANDLED;
+}
+
+void imx7ulp_enable_nmi(void)
+{
+ struct device_node *np;
+ int irq, ret;
+
+ np = of_find_compatible_node(NULL, NULL, "fsl,imx7ulp-nmi");
+ mu_base = of_iomap(np, 0);
+ WARN_ON(!mu_base);
+ irq = of_irq_get(np, 0);
+ ret = request_irq(irq, imx7ulp_nmi_isr,
+ IRQF_NO_SUSPEND, "imx7ulp-nmi", NULL);
+ if (ret) {
+ pr_err("%s: register interrupt %d failed, rc %d\n",
+ __func__, irq, ret);
+ return;
+ }
+}
diff --git a/arch/arm/mach-imx/pm-rpmsg.c b/arch/arm/mach-imx/pm-rpmsg.c
new file mode 100644
index 000000000000..e760379cdf85
--- /dev/null
+++ b/arch/arm/mach-imx/pm-rpmsg.c
@@ -0,0 +1,354 @@
+/*
+ * Copyright 2017-2018 NXP
+ *
+ * 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/err.h>
+#include <linux/slab.h>
+#include <linux/imx_rpmsg.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/pm_qos.h>
+#include <linux/reboot.h>
+#include <linux/rpmsg.h>
+#include <linux/uaccess.h>
+#include <linux/virtio.h>
+#include "common.h"
+
+#define RPMSG_TIMEOUT 1000
+
+#define PM_RPMSG_TYPE 0
+#define HEATBEAT_RPMSG_TYPE 2
+
+enum pm_rpmsg_cmd {
+ PM_RPMSG_MODE,
+ PM_RPMSG_HEART_BEAT,
+ PM_RPMSG_HEART_BEAT_OFF,
+};
+
+enum pm_rpmsg_power_mode {
+ PM_RPMSG_HSRUN,
+ PM_RPMSG_RUN,
+ PM_RPMSG_VLPR,
+ PM_RPMSG_WAIT,
+ PM_RPMSG_VLPS,
+ PM_RPMSG_VLLS,
+ PM_RPMSG_REBOOT,
+ PM_RPMSG_SHUTDOWN,
+};
+
+struct pm_rpmsg_info {
+ struct rpmsg_device *rpdev;
+ struct device *dev;
+ struct pm_rpmsg_data *msg;
+ struct pm_qos_request pm_qos_req;
+ struct notifier_block restart_handler;
+ struct completion cmd_complete;
+ bool first_flag;
+ struct mutex lock;
+};
+
+static struct pm_rpmsg_info pm_rpmsg;
+
+static struct delayed_work heart_beat_work;
+
+static bool heartbeat_off;
+
+struct pm_rpmsg_data {
+ struct imx_rpmsg_head header;
+ u8 data;
+} __attribute__ ((packed));
+
+static int pm_send_message(struct pm_rpmsg_data *msg,
+ struct pm_rpmsg_info *info, bool ack)
+{
+ int err;
+
+ if (!info->rpdev) {
+ dev_dbg(info->dev,
+ "rpmsg channel not ready, m4 image ready?\n");
+ return -EINVAL;
+ }
+
+ mutex_lock(&info->lock);
+ pm_qos_add_request(&info->pm_qos_req,
+ PM_QOS_CPU_DMA_LATENCY, 0);
+
+ reinit_completion(&info->cmd_complete);
+
+ err = rpmsg_send(info->rpdev->ept, (void *)msg,
+ sizeof(struct pm_rpmsg_data));
+
+ if (err) {
+ dev_err(&info->rpdev->dev, "rpmsg_send failed: %d\n", err);
+ goto err_out;
+ }
+
+ if (ack) {
+ err = wait_for_completion_timeout(&info->cmd_complete,
+ msecs_to_jiffies(RPMSG_TIMEOUT));
+ if (!err) {
+ dev_err(&info->rpdev->dev, "rpmsg_send timeout!\n");
+ err = -ETIMEDOUT;
+ goto err_out;
+ }
+
+ if (info->msg->data != 0) {
+ dev_err(&info->rpdev->dev, "rpmsg not ack %d!\n",
+ info->msg->data);
+ err = -EINVAL;
+ goto err_out;
+ }
+
+ err = 0;
+ }
+
+err_out:
+ pm_qos_remove_request(&info->pm_qos_req);
+ mutex_unlock(&info->lock);
+
+ return err;
+}
+
+static int pm_vlls_notify_m4(bool enter)
+{
+ struct pm_rpmsg_data msg;
+
+ msg.header.cate = IMX_RMPSG_LIFECYCLE;
+ msg.header.major = IMX_RMPSG_MAJOR;
+ msg.header.minor = IMX_RMPSG_MINOR;
+ msg.header.type = PM_RPMSG_TYPE;
+ msg.header.cmd = PM_RPMSG_MODE;
+ msg.data = enter ? PM_RPMSG_VLLS : PM_RPMSG_RUN;
+
+ return pm_send_message(&msg, &pm_rpmsg, true);
+}
+
+void pm_shutdown_notify_m4(void)
+{
+ struct pm_rpmsg_data msg;
+
+ msg.header.cate = IMX_RMPSG_LIFECYCLE;
+ msg.header.major = IMX_RMPSG_MAJOR;
+ msg.header.minor = IMX_RMPSG_MINOR;
+ msg.header.type = PM_RPMSG_TYPE;
+ msg.header.cmd = PM_RPMSG_MODE;
+ msg.data = PM_RPMSG_SHUTDOWN;
+ /* No ACK from M4 */
+ pm_send_message(&msg, &pm_rpmsg, false);
+
+ imx7ulp_poweroff();
+}
+
+void pm_reboot_notify_m4(void)
+{
+ struct pm_rpmsg_data msg;
+
+ msg.header.cate = IMX_RMPSG_LIFECYCLE;
+ msg.header.major = IMX_RMPSG_MAJOR;
+ msg.header.minor = IMX_RMPSG_MINOR;
+ msg.header.type = PM_RPMSG_TYPE;
+ msg.header.cmd = PM_RPMSG_MODE;
+ msg.data = PM_RPMSG_REBOOT;
+
+ pm_send_message(&msg, &pm_rpmsg, true);
+
+}
+
+void pm_heartbeat_off_notify_m4(bool enter)
+{
+ struct pm_rpmsg_data msg;
+
+ msg.header.cate = IMX_RMPSG_LIFECYCLE;
+ msg.header.major = IMX_RMPSG_MAJOR;
+ msg.header.minor = IMX_RMPSG_MINOR;
+ msg.header.type = PM_RPMSG_TYPE;
+ msg.header.cmd = PM_RPMSG_HEART_BEAT_OFF;
+ msg.data = enter ? 0 : 1;
+
+ pm_send_message(&msg, &pm_rpmsg, true);
+}
+
+static void pm_heart_beat_work_handler(struct work_struct *work)
+{
+ struct pm_rpmsg_data msg;
+
+ /* Notify M4 side A7 in RUN mode at boot time */
+ if (pm_rpmsg.first_flag) {
+ pm_vlls_notify_m4(false);
+
+ pm_heartbeat_off_notify_m4(heartbeat_off);
+
+ pm_rpmsg.first_flag = false;
+ }
+
+ if (!heartbeat_off) {
+ msg.header.cate = IMX_RMPSG_LIFECYCLE;
+ msg.header.major = IMX_RMPSG_MAJOR;
+ msg.header.minor = IMX_RMPSG_MINOR;
+ msg.header.type = HEATBEAT_RPMSG_TYPE;
+ msg.header.cmd = PM_RPMSG_HEART_BEAT;
+ msg.data = 0;
+ pm_send_message(&msg, &pm_rpmsg, false);
+
+ schedule_delayed_work(&heart_beat_work,
+ msecs_to_jiffies(30000));
+ }
+}
+
+static void pm_poweroff_rpmsg(void)
+{
+ pm_shutdown_notify_m4();
+ pr_emerg("Unable to poweroff system\n");
+}
+
+static int pm_restart_handler(struct notifier_block *this, unsigned long mode,
+ void *cmd)
+{
+ pm_reboot_notify_m4();
+
+ return NOTIFY_DONE;
+}
+
+static int pm_rpmsg_probe(struct rpmsg_device *rpdev)
+{
+ int ret;
+
+ pm_rpmsg.rpdev = rpdev;
+
+ dev_info(&rpdev->dev, "new channel: 0x%x -> 0x%x!\n",
+ rpdev->src, rpdev->dst);
+
+ init_completion(&pm_rpmsg.cmd_complete);
+ mutex_init(&pm_rpmsg.lock);
+
+ INIT_DELAYED_WORK(&heart_beat_work,
+ pm_heart_beat_work_handler);
+
+ pm_rpmsg.first_flag = true;
+ schedule_delayed_work(&heart_beat_work, 0);
+
+ pm_rpmsg.restart_handler.notifier_call = pm_restart_handler;
+ pm_rpmsg.restart_handler.priority = 128;
+ ret = register_restart_handler(&pm_rpmsg.restart_handler);
+ if (ret)
+ dev_err(&rpdev->dev, "cannot register restart handler\n");
+
+ pm_power_off = pm_poweroff_rpmsg;
+
+ return 0;
+}
+
+static int pm_rpmsg_cb(struct rpmsg_device *rpdev, void *data, int len,
+ void *priv, u32 src)
+{
+ struct pm_rpmsg_data *msg = (struct pm_rpmsg_data *)data;
+
+ pm_rpmsg.msg = msg;
+
+ complete(&pm_rpmsg.cmd_complete);
+
+ return 0;
+}
+
+static void pm_rpmsg_remove(struct rpmsg_device *rpdev)
+{
+ dev_info(&rpdev->dev, "pm rpmsg driver is removed\n");
+}
+
+static struct rpmsg_device_id pm_rpmsg_id_table[] = {
+ { .name = "rpmsg-life-cycle-channel" },
+ { },
+};
+
+static struct rpmsg_driver pm_rpmsg_driver = {
+ .drv.name = "pm_rpmsg",
+ .drv.owner = THIS_MODULE,
+ .id_table = pm_rpmsg_id_table,
+ .probe = pm_rpmsg_probe,
+ .callback = pm_rpmsg_cb,
+ .remove = pm_rpmsg_remove,
+};
+
+#ifdef CONFIG_PM_SLEEP
+static int pm_heartbeat_suspend(struct device *dev)
+{
+ int err;
+
+ err = pm_vlls_notify_m4(true);
+ if (err)
+ return err;
+
+ cancel_delayed_work_sync(&heart_beat_work);
+
+ return 0;
+}
+
+static int pm_heartbeat_resume(struct device *dev)
+{
+ int err;
+
+ err = pm_vlls_notify_m4(false);
+ if (err)
+ return err;
+
+ schedule_delayed_work(&heart_beat_work,
+ msecs_to_jiffies(10000));
+
+ return 0;
+}
+#endif
+
+static int pm_heartbeat_probe(struct platform_device *pdev)
+{
+ platform_set_drvdata(pdev, &pm_rpmsg);
+
+ return register_rpmsg_driver(&pm_rpmsg_driver);
+}
+
+static const struct of_device_id pm_heartbeat_id[] = {
+ {"fsl,heartbeat-rpmsg",},
+ {},
+};
+MODULE_DEVICE_TABLE(of, pm_heartbeat_id);
+
+static const struct dev_pm_ops pm_heartbeat_ops = {
+ SET_LATE_SYSTEM_SLEEP_PM_OPS(pm_heartbeat_suspend,
+ pm_heartbeat_resume)
+};
+
+static struct platform_driver pm_heartbeat_driver = {
+ .driver = {
+ .name = "heartbeat-rpmsg",
+ .owner = THIS_MODULE,
+ .of_match_table = pm_heartbeat_id,
+ .pm = &pm_heartbeat_ops,
+ },
+ .probe = pm_heartbeat_probe,
+};
+
+static int __init setup_heartbeat(char *str)
+{
+ heartbeat_off = true;
+
+ return 1;
+};
+__setup("heartbeat_off", setup_heartbeat);
+
+module_platform_driver(pm_heartbeat_driver);
+
+MODULE_DESCRIPTION("Freescale PM rpmsg driver");
+MODULE_AUTHOR("Anson Huang <Anson.Huang@nxp.com>");
+MODULE_LICENSE("GPL");
diff --git a/arch/arm/mach-imx/smc_sip.h b/arch/arm/mach-imx/smc_sip.h
new file mode 100644
index 000000000000..30c854be7d74
--- /dev/null
+++ b/arch/arm/mach-imx/smc_sip.h
@@ -0,0 +1,36 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright 2018 NXP
+ */
+/*
+ * 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 __SMC_SIP_H__
+#define __SMC_SIP_H__
+
+#include <linux/arm-smccc.h>
+
+/*
+ * Macro definition building the OPTEE SMC Code function
+ * for a Fast Call, SIP operation
+ */
+#define OPTEE_SMC_FAST_CALL_SIP_VAL(func_num) \
+ ARM_SMCCC_CALL_VAL( \
+ ARM_SMCCC_FAST_CALL, \
+ ARM_SMCCC_SMC_32, \
+ ARM_SMCCC_OWNER_SIP, \
+ (func_num))
+
+
+/*
+ * Definition of the i.MX SMC SIP Operations
+ * Operation value must be aligned with i.MX OPTEE
+ * SIP definitions
+ */
+/* Busfreq operation */
+#define IMX_SIP_BUSFREQ_CHANGE 6
+
+#endif /* __SMC_SIP_H__ */
+
diff --git a/arch/arm/mach-imx/smp_wfe.S b/arch/arm/mach-imx/smp_wfe.S
new file mode 100644
index 000000000000..08894bb39c4d
--- /dev/null
+++ b/arch/arm/mach-imx/smp_wfe.S
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2015 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/linkage.h>
+#include <asm/smp_scu.h>
+#include "hardware.h"
+
+ .macro disable_l1_dcache
+
+ /*
+ * Flush all data from the L1 data cache before disabling
+ * SCTLR.C bit.
+ */
+ push {r0 - r10, lr}
+ ldr r7, =v7_flush_dcache_all
+ mov lr, pc
+ mov pc, r7
+ pop {r0 - r10, lr}
+
+ /* disable d-cache */
+ mrc p15, 0, r7, c1, c0, 0
+ bic r7, r7, #(1 << 2)
+ mcr p15, 0, r7, c1, c0, 0
+ dsb
+ isb
+
+ push {r0 - r10, lr}
+ ldr r7, =v7_flush_dcache_all
+ mov lr, pc
+ mov pc, r7
+ pop {r0 - r10, lr}
+
+ .endm
+
+#ifdef CONFIG_SMP
+ .align 3
+
+ENTRY(imx7_smp_wfe)
+ push {r4 - r11, lr}
+
+ dsb
+ isb
+
+ disable_l1_dcache
+
+ isb
+
+ /* Turn off SMP bit. */
+ mrc p15, 0, r8, c1, c0, 1
+ bic r8, r8, #0x40
+ mcr p15, 0, r8, c1, c0, 1
+
+ isb
+ /* Set flag of entering WFE. */
+ mov r7, #0xff
+ lsl r7, r7, r0
+ mov r6, #SCU_PM_DORMANT
+ lsl r6, r6, r0
+ ldr r8, [r1, #0x4]
+ bic r8, r8, r7
+ orr r6, r6, r8
+ str r6, [r1, #0x4]
+
+go_back_wfe:
+ wfe
+
+ /* Offset 0x0 stores busfeq done flag */
+ ldr r6, [r1]
+ cmp r6, #1
+ beq go_back_wfe
+
+ /* Turn ON SMP bit. */
+ mrc p15, 0, r8, c1, c0, 1
+ orr r8, r8, #0x40
+ mcr p15, 0, r8, c1, c0, 1
+
+ isb
+ /* Enable L1 data cache. */
+ mrc p15, 0, r8, c1, c0, 0
+ orr r8, r8, #0x4
+ mcr p15, 0, r8, c1, c0, 0
+ isb
+
+ /* Set flag of exiting WFE. */
+ mov r7, #0xff
+ lsl r7, r7, r0
+ mov r6, #SCU_PM_NORMAL
+ lsl r6, r6, r0
+ ldr r8, [r1, #0x4]
+ bic r8, r8, r7
+ orr r6, r6, r8
+ str r6, [r1, #0x4]
+
+ /* Pop all saved registers. */
+ pop {r4 - r11, lr}
+ mov pc, lr
+ .ltorg
+ENDPROC(imx7_smp_wfe)
+#endif
diff --git a/arch/arm/mach-imx/smp_wfe_imx6.S b/arch/arm/mach-imx/smp_wfe_imx6.S
new file mode 100644
index 000000000000..7695d891bafd
--- /dev/null
+++ b/arch/arm/mach-imx/smp_wfe_imx6.S
@@ -0,0 +1,186 @@
+/*
+ * Copyright (C) 2015 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <linux/linkage.h>
+#include <asm/smp_scu.h>
+#include "hardware.h"
+
+#ifdef CONFIG_SMP
+.extern imx_scu_base
+#endif
+
+.globl wfe_smp_freq_change_start
+.globl wfe_smp_freq_change_end
+
+#ifdef CONFIG_SMP
+
+ .align 3
+
+ .macro disable_l1_dcache
+
+ /*
+ * Flush all data from the L1 data cache before disabling
+ * SCTLR.C bit.
+ */
+ push {r0 - r11, lr}
+
+ ldr r7, =v7_flush_kern_cache_all
+ mov lr, pc
+ mov pc, r7
+ pop {r0 - r11, lr}
+
+ /* disable d-cache */
+ mrc p15, 0, r6, c1, c0, 0
+ bic r6, r6, #0x4
+ mcr p15, 0, r6, c1, c0, 0
+ dsb
+ isb
+
+ push {r0 - r11, lr}
+
+ ldr r7, =v7_flush_kern_cache_all
+ mov lr, pc
+ mov pc, r7
+ pop {r0 - r11, lr}
+
+ .endm
+
+ENTRY(wfe_smp_freq_change)
+wfe_smp_freq_change_start:
+ push {r4 - r11, lr}
+
+ mov r6, r0
+ mov r7, r1
+
+ dsb
+ isb
+
+ disable_l1_dcache
+
+ isb
+
+ /* Turn off SMP bit. */
+ mrc p15, 0, r8, c1, c0, 1
+ bic r8, r8, #0x40
+ mcr p15, 0, r8, c1, c0, 1
+
+ isb
+
+ /* Inform the SCU we are going to enter WFE. */
+ push {r0 - r11, lr}
+
+ ldr r0,=imx_scu_base
+ ldr r0, [r0]
+ mov r1, #SCU_PM_DORMANT
+ ldr r3, =scu_power_mode
+ mov lr, pc
+ mov pc, r3
+
+ pop {r0 - r11, lr}
+
+go_back_wfe:
+ wfe
+
+ ldr r3, [r7]
+ cmp r3, #1
+ beq go_back_wfe
+
+ /* Turn ON SMP bit. */
+ mrc p15, 0, r8, c1, c0, 1
+ orr r8, r8, #0x40
+ mcr p15, 0, r8, c1, c0, 1
+
+ isb
+ /* Enable L1 data cache. */
+ mrc p15, 0, r8, c1, c0, 0
+ orr r8, r8, #0x4
+ mcr p15, 0, r8, c1, c0, 0
+ isb
+
+ /* Inform the SCU we have exited WFE. */
+ push {r0 - r11, lr}
+
+ ldr r0,=imx_scu_base
+ ldr r0, [r0]
+ mov r1, #SCU_PM_NORMAL
+ ldr r3, =scu_power_mode
+ mov lr, pc
+ mov pc, r3
+
+ pop {r0 - r11, lr}
+
+ /* Pop all saved registers. */
+ pop {r4 - r11, lr}
+ mov pc, lr
+ .ltorg
+wfe_smp_freq_change_end:
+ENDPROC(wfe_smp_freq_change)
+
+#ifdef CONFIG_OPTEE
+/**
+ * @brief Switch CPU in WFE mode while bus frequency change
+ * on-going
+ *
+ * @param[in] r0 CPU in WFE Status
+ * @param[in] r1 Bus frequency change status
+ */
+
+.globl imx_smp_wfe_optee_end
+
+ENTRY(imx_smp_wfe_optee)
+ push {r4-r11, lr}
+
+ dsb
+ isb
+
+ disable_l1_dcache
+ isb
+
+ /* Set flag CPU entering WFE. */
+ mov r4, #1
+ str r4, [r0]
+
+ dsb
+ isb
+
+1:
+ wfe
+
+ /* Check if busfreq is done, else loop */
+ ldr r4, [r1]
+ cmp r4, #1
+ beq 1b
+
+ /* Enable L1 data cache. */
+ mrc p15, 0, r4, c1, c0, 0
+ orr r4, r4, #0x4
+ mcr p15, 0, r4, c1, c0, 0
+ isb
+
+ /* Set flag CPU exiting WFE. */
+ mov r4, #0
+ str r4, [r0]
+
+ /* Pop all saved registers. */
+ pop {r4-r11, lr}
+ mov pc, lr
+ .ltorg
+imx_smp_wfe_optee_end:
+ENDPROC(imx_smp_wfe_optee)
+#endif
+#endif
diff --git a/arch/arm/mach-imx/src.c b/arch/arm/mach-imx/src.c
index 495d85d0fe7e..e410998fac93 100644
--- a/arch/arm/mach-imx/src.c
+++ b/arch/arm/mach-imx/src.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2011 Freescale Semiconductor, Inc.
+ * Copyright 2011-2015 Freescale Semiconductor, Inc.
* Copyright 2011 Linaro Ltd.
*
* The code contained herein is licensed under the GNU General Public
@@ -18,6 +18,7 @@
#include <linux/smp.h>
#include <asm/smp_plat.h>
#include "common.h"
+#include "hardware.h"
#define SRC_SCR 0x000
#define SRC_GPR1 0x020
@@ -29,9 +30,18 @@
#define BP_SRC_SCR_SW_IPU2_RST 12
#define BP_SRC_SCR_CORE1_RST 14
#define BP_SRC_SCR_CORE1_ENABLE 22
+/* below is for i.MX7D */
+#define SRC_GPR1_V2 0x074
+#define SRC_A7RCR0 0x004
+#define SRC_A7RCR1 0x008
+#define SRC_M4RCR 0x00C
+
+#define BP_SRC_A7RCR0_A7_CORE_RESET0 0
+#define BP_SRC_A7RCR1_A7_CORE1_ENABLE 1
static void __iomem *src_base;
-static DEFINE_SPINLOCK(scr_lock);
+static DEFINE_SPINLOCK(src_lock);
+static bool m4_is_enabled;
static const int sw_reset_bits[5] = {
BP_SRC_SCR_SW_GPU_RST,
@@ -41,6 +51,11 @@ static const int sw_reset_bits[5] = {
BP_SRC_SCR_SW_IPU2_RST
};
+bool imx_src_is_m4_enabled(void)
+{
+ return m4_is_enabled;
+}
+
static int imx_src_reset_module(struct reset_controller_dev *rcdev,
unsigned long sw_reset_idx)
{
@@ -57,11 +72,11 @@ static int imx_src_reset_module(struct reset_controller_dev *rcdev,
bit = 1 << sw_reset_bits[sw_reset_idx];
- spin_lock_irqsave(&scr_lock, flags);
+ spin_lock_irqsave(&src_lock, flags);
val = readl_relaxed(src_base + SRC_SCR);
val |= bit;
writel_relaxed(val, src_base + SRC_SCR);
- spin_unlock_irqrestore(&scr_lock, flags);
+ spin_unlock_irqrestore(&src_lock, flags);
timeout = jiffies + msecs_to_jiffies(1000);
while (readl(src_base + SRC_SCR) & bit) {
@@ -87,32 +102,59 @@ void imx_enable_cpu(int cpu, bool enable)
u32 mask, val;
cpu = cpu_logical_map(cpu);
- mask = 1 << (BP_SRC_SCR_CORE1_ENABLE + cpu - 1);
- spin_lock(&scr_lock);
- val = readl_relaxed(src_base + SRC_SCR);
- val = enable ? val | mask : val & ~mask;
- val |= 1 << (BP_SRC_SCR_CORE1_RST + cpu - 1);
- writel_relaxed(val, src_base + SRC_SCR);
- spin_unlock(&scr_lock);
+ spin_lock(&src_lock);
+ if (cpu_is_imx7d()) {
+ /* enable core */
+ if (enable)
+ imx_gpcv2_set_core1_pdn_pup_by_software(false);
+
+ mask = 1 << (BP_SRC_A7RCR1_A7_CORE1_ENABLE + cpu - 1);
+ val = readl_relaxed(src_base + SRC_A7RCR1);
+ val = enable ? val | mask : val & ~mask;
+ writel_relaxed(val, src_base + SRC_A7RCR1);
+ } else {
+ mask = 1 << (BP_SRC_SCR_CORE1_ENABLE + cpu - 1);
+ val = readl_relaxed(src_base + SRC_SCR);
+ val = enable ? val | mask : val & ~mask;
+ val |= 1 << (BP_SRC_SCR_CORE1_RST + cpu - 1);
+ writel_relaxed(val, src_base + SRC_SCR);
+ }
+ spin_unlock(&src_lock);
}
void imx_set_cpu_jump(int cpu, void *jump_addr)
{
+ spin_lock(&src_lock);
cpu = cpu_logical_map(cpu);
- writel_relaxed(__pa_symbol(jump_addr),
- src_base + SRC_GPR1 + cpu * 8);
+ if (cpu_is_imx7d())
+ writel_relaxed(__pa_symbol(jump_addr),
+ src_base + SRC_GPR1_V2 + cpu * 8);
+ else
+ writel_relaxed(__pa_symbol(jump_addr),
+ src_base + SRC_GPR1 + cpu * 8);
+ spin_unlock(&src_lock);
}
u32 imx_get_cpu_arg(int cpu)
{
cpu = cpu_logical_map(cpu);
- return readl_relaxed(src_base + SRC_GPR1 + cpu * 8 + 4);
+ if (cpu_is_imx7d())
+ return readl_relaxed(src_base + SRC_GPR1_V2
+ + cpu * 8 + 4);
+ else
+ return readl_relaxed(src_base + SRC_GPR1
+ + cpu * 8 + 4);
}
void imx_set_cpu_arg(int cpu, u32 arg)
{
cpu = cpu_logical_map(cpu);
- writel_relaxed(arg, src_base + SRC_GPR1 + cpu * 8 + 4);
+ if (cpu_is_imx7d())
+ writel_relaxed(arg, src_base + SRC_GPR1_V2
+ + cpu * 8 + 4);
+ else
+ writel_relaxed(arg, src_base + SRC_GPR1
+ + cpu * 8 + 4);
}
void __init imx_src_init(void)
@@ -126,6 +168,15 @@ void __init imx_src_init(void)
src_base = of_iomap(np, 0);
WARN_ON(!src_base);
+ if (cpu_is_imx7d()) {
+ val = readl_relaxed(src_base + SRC_M4RCR);
+ if (((val & BIT(3)) == BIT(3)) && !(val & BIT(0)))
+ m4_is_enabled = true;
+ else
+ m4_is_enabled = false;
+ return;
+ }
+
imx_reset_controller.of_node = np;
if (IS_ENABLED(CONFIG_RESET_CONTROLLER))
reset_controller_register(&imx_reset_controller);
@@ -134,9 +185,17 @@ void __init imx_src_init(void)
* force warm reset sources to generate cold reset
* for a more reliable restart
*/
- spin_lock(&scr_lock);
+ spin_lock(&src_lock);
val = readl_relaxed(src_base + SRC_SCR);
+
+ /* bit 4 is m4c_non_sclr_rst on i.MX6SX */
+ if (cpu_is_imx6sx() && ((val &
+ (1 << BP_SRC_SCR_SW_OPEN_VG_RST)) == 0))
+ m4_is_enabled = true;
+ else
+ m4_is_enabled = false;
+
val &= ~(1 << BP_SRC_SCR_WARM_RESET_ENABLE);
writel_relaxed(val, src_base + SRC_SCR);
- spin_unlock(&scr_lock);
+ spin_unlock(&src_lock);
}
diff --git a/arch/arm/mach-imx/suspend-imx6.S b/arch/arm/mach-imx/suspend-imx6.S
index 76ee2ceec8d5..b8ad48fc85a9 100644
--- a/arch/arm/mach-imx/suspend-imx6.S
+++ b/arch/arm/mach-imx/suspend-imx6.S
@@ -1,5 +1,5 @@
/*
- * Copyright 2014 Freescale Semiconductor, Inc.
+ * Copyright 2014-2015 Freescale Semiconductor, Inc.
*
* The code contained herein is licensed under the GNU General Public
* License. You may obtain a copy of the GNU General Public License
@@ -47,23 +47,32 @@
#define PM_INFO_RESUME_ADDR_OFFSET 0x4
#define PM_INFO_DDR_TYPE_OFFSET 0x8
#define PM_INFO_PM_INFO_SIZE_OFFSET 0xC
-#define PM_INFO_MX6Q_MMDC_P_OFFSET 0x10
-#define PM_INFO_MX6Q_MMDC_V_OFFSET 0x14
-#define PM_INFO_MX6Q_SRC_P_OFFSET 0x18
-#define PM_INFO_MX6Q_SRC_V_OFFSET 0x1C
-#define PM_INFO_MX6Q_IOMUXC_P_OFFSET 0x20
-#define PM_INFO_MX6Q_IOMUXC_V_OFFSET 0x24
-#define PM_INFO_MX6Q_CCM_P_OFFSET 0x28
-#define PM_INFO_MX6Q_CCM_V_OFFSET 0x2C
-#define PM_INFO_MX6Q_GPC_P_OFFSET 0x30
-#define PM_INFO_MX6Q_GPC_V_OFFSET 0x34
-#define PM_INFO_MX6Q_L2_P_OFFSET 0x38
-#define PM_INFO_MX6Q_L2_V_OFFSET 0x3C
-#define PM_INFO_MMDC_IO_NUM_OFFSET 0x40
-#define PM_INFO_MMDC_IO_VAL_OFFSET 0x44
+#define PM_INFO_MX6Q_MMDC0_P_OFFSET 0x10
+#define PM_INFO_MX6Q_MMDC0_V_OFFSET 0x14
+#define PM_INFO_MX6Q_MMDC1_P_OFFSET 0x18
+#define PM_INFO_MX6Q_MMDC1_V_OFFSET 0x1C
+#define PM_INFO_MX6Q_SRC_P_OFFSET 0x20
+#define PM_INFO_MX6Q_SRC_V_OFFSET 0x24
+#define PM_INFO_MX6Q_IOMUXC_P_OFFSET 0x28
+#define PM_INFO_MX6Q_IOMUXC_V_OFFSET 0x2C
+#define PM_INFO_MX6Q_CCM_P_OFFSET 0x30
+#define PM_INFO_MX6Q_CCM_V_OFFSET 0x34
+#define PM_INFO_MX6Q_GPC_P_OFFSET 0x38
+#define PM_INFO_MX6Q_GPC_V_OFFSET 0x3C
+#define PM_INFO_MX6Q_L2_P_OFFSET 0x40
+#define PM_INFO_MX6Q_L2_V_OFFSET 0x44
+#define PM_INFO_MX6Q_ANATOP_P_OFFSET 0x48
+#define PM_INFO_MX6Q_ANATOP_V_OFFSET 0x4C
+#define PM_INFO_MX6Q_TTBR1_V_OFFSET 0x50
+#define PM_INFO_MMDC_IO_NUM_OFFSET 0x54
+#define PM_INFO_MMDC_IO_VAL_OFFSET 0x58
+/* below offsets depends on MX6_MAX_MMDC_IO_NUM(36) definition */
+#define PM_INFO_MMDC_NUM_OFFSET 0x208
+#define PM_INFO_MMDC_VAL_OFFSET 0x20C
#define MX6Q_SRC_GPR1 0x20
#define MX6Q_SRC_GPR2 0x24
+#define MX6Q_MMDC_MISC 0x18
#define MX6Q_MMDC_MAPSR 0x404
#define MX6Q_MMDC_MPDGCTRL0 0x83c
#define MX6Q_GPC_IMR1 0x08
@@ -71,9 +80,49 @@
#define MX6Q_GPC_IMR3 0x10
#define MX6Q_GPC_IMR4 0x14
#define MX6Q_CCM_CCR 0x0
+#define MX6Q_ANATOP_CORE 0x140
.align 3
+ /* Check if the cpu is cortex-a7 */
+ .macro is_cortex_a7
+
+ /* Read the primary cpu number is MPIDR */
+ mrc p15, 0, r5, c0, c0, 0
+ ldr r6, =0xfff0
+ and r5, r5, r6
+ ldr r6, =0xc070
+ cmp r5, r6
+
+ .endm
+
+ .macro disable_l1_cache
+
+ /*
+ * Flush all data from the L1 data cache before disabling
+ * SCTLR.C bit.
+ */
+ push {r0 - r10, lr}
+ ldr r7, =v7_flush_dcache_all
+ mov lr, pc
+ mov pc, r7
+ pop {r0 - r10, lr}
+
+ /* disable d-cache */
+ mrc p15, 0, r7, c1, c0, 0
+ bic r7, r7, #(1 << 2)
+ mcr p15, 0, r7, c1, c0, 0
+ dsb
+ isb
+
+ push {r0 -r10, lr}
+ ldr r7, = v7_flush_dcache_all
+ mov lr, pc
+ mov pc , r7
+ pop {r0 -r10, lr}
+
+ .endm
+
.macro sync_l2_cache
/* sync L2 cache to drain L2's buffers to DRAM. */
@@ -92,29 +141,8 @@
.endm
- .macro resume_mmdc
-
- /* restore MMDC IO */
- cmp r5, #0x0
- ldreq r11, [r0, #PM_INFO_MX6Q_IOMUXC_V_OFFSET]
- ldrne r11, [r0, #PM_INFO_MX6Q_IOMUXC_P_OFFSET]
-
- ldr r6, [r0, #PM_INFO_MMDC_IO_NUM_OFFSET]
- ldr r7, =PM_INFO_MMDC_IO_VAL_OFFSET
- add r7, r7, r0
-1:
- ldr r8, [r7], #0x4
- ldr r9, [r7], #0x4
- str r9, [r11, r8]
- subs r6, r6, #0x1
- bne 1b
-
- cmp r5, #0x0
- ldreq r11, [r0, #PM_INFO_MX6Q_MMDC_V_OFFSET]
- ldrne r11, [r0, #PM_INFO_MX6Q_MMDC_P_OFFSET]
-
- cmp r3, #IMX_DDR_TYPE_LPDDR2
- bne 4f
+ /* r11 must be MMDC base address */
+ .macro reset_read_fifo
/* reset read FIFO, RST_RD_FIFO */
ldr r7, =MX6Q_MMDC_MPDGCTRL0
@@ -134,23 +162,294 @@
ldr r6, [r11, r7]
ands r6, r6, #(1 << 31)
bne 3b
+
+ /* check if lppdr2 2 channel mode is enabled */
+ ldr r7, =MX6Q_MMDC_MISC
+ ldr r6, [r11, r7]
+ ands r6, r6, #(1 << 2)
+ beq 6f
+
+ ldr r7, =MX6Q_MMDC_MPDGCTRL0
+ ldr r6, [r12, r7]
+ orr r6, r6, #(1 << 31)
+ str r6, [r12, r7]
4:
+ ldr r6, [r12, r7]
+ ands r6, r6, #(1 << 31)
+ bne 4b
+
+ ldr r6, [r12, r7]
+ orr r6, r6, #(1 << 31)
+ str r6, [r12, r7]
+5:
+ ldr r6, [r12, r7]
+ ands r6, r6, #(1 << 31)
+ bne 5b
+
+6:
+ .endm
+
+ /* r11 must be MMDC base address */
+ .macro mmdc_out_and_auto_self_refresh
+
/* let DDR out of self-refresh */
ldr r7, [r11, #MX6Q_MMDC_MAPSR]
bic r7, r7, #(1 << 21)
str r7, [r11, #MX6Q_MMDC_MAPSR]
-5:
+7:
ldr r7, [r11, #MX6Q_MMDC_MAPSR]
ands r7, r7, #(1 << 25)
- bne 5b
+ bne 7b
/* enable DDR auto power saving */
ldr r7, [r11, #MX6Q_MMDC_MAPSR]
bic r7, r7, #0x1
str r7, [r11, #MX6Q_MMDC_MAPSR]
+ /* check if lppdr2 2 channel mode is enabled */
+ ldr r7, =MX6Q_MMDC_MISC
+ ldr r6, [r11, r7]
+ ands r6, r6, #(1 << 2)
+ beq 9f
+
+ ldr r7, [r12, #MX6Q_MMDC_MAPSR]
+ bic r7, r7, #(1 << 21)
+ str r7, [r12, #MX6Q_MMDC_MAPSR]
+8:
+ ldr r7, [r12, #MX6Q_MMDC_MAPSR]
+ ands r7, r7, #(1 << 25)
+ bne 8b
+
+ ldr r7, [r12, #MX6Q_MMDC_MAPSR]
+ bic r7, r7, #0x1
+ str r7, [r12, #MX6Q_MMDC_MAPSR]
+9:
+ .endm
+
+ /* r10 must be iomuxc base address */
+ .macro resume_iomuxc_gpr
+
+ add r10, r10, #0x4000
+ /* IOMUXC GPR DRAM_RESET_BYPASS */
+ ldr r4, [r10, #0x8]
+ bic r4, r4, #(0x1 << 27)
+ str r4, [r10, #0x8]
+ /* IOMUXC GPR DRAM_CKE_BYPASS */
+ ldr r4, [r10, #0x8]
+ bic r4, r4, #(0x1 << 31)
+ str r4, [r10, #0x8]
+
+ .endm
+
+ .macro resume_io
+
+ /* restore MMDC IO */
+ cmp r5, #0x0
+ ldreq r10, [r0, #PM_INFO_MX6Q_IOMUXC_V_OFFSET]
+ ldrne r10, [r0, #PM_INFO_MX6Q_IOMUXC_P_OFFSET]
+
+ ldr r6, [r0, #PM_INFO_MMDC_IO_NUM_OFFSET]
+ ldr r7, =PM_INFO_MMDC_IO_VAL_OFFSET
+ add r7, r7, r0
+10:
+ ldr r8, [r7], #0x4
+ ldr r9, [r7], #0x8
+ str r9, [r10, r8]
+ subs r6, r6, #0x1
+ bne 10b
+
+ cmp r5, #0x0
+ /* Here only MMDC0 is set */
+ ldreq r11, [r0, #PM_INFO_MX6Q_MMDC0_V_OFFSET]
+ ldrne r11, [r0, #PM_INFO_MX6Q_MMDC0_P_OFFSET]
+ ldreq r12, [r0, #PM_INFO_MX6Q_MMDC1_V_OFFSET]
+ ldrne r12, [r0, #PM_INFO_MX6Q_MMDC1_P_OFFSET]
+
+ reset_read_fifo
+ mmdc_out_and_auto_self_refresh
+
+ .endm
+
+ .macro resume_mmdc_io
+
+ cmp r5, #0x0
+ ldreq r10, [r0, #PM_INFO_MX6Q_IOMUXC_V_OFFSET]
+ ldrne r10, [r0, #PM_INFO_MX6Q_IOMUXC_P_OFFSET]
+ ldreq r11, [r0, #PM_INFO_MX6Q_MMDC0_V_OFFSET]
+ ldrne r11, [r0, #PM_INFO_MX6Q_MMDC0_P_OFFSET]
+
+ /* resume mmdc iomuxc settings */
+ ldr r6, [r0, #PM_INFO_MMDC_IO_NUM_OFFSET]
+ ldr r7, =PM_INFO_MMDC_IO_VAL_OFFSET
+ add r7, r7, r0
+11:
+ ldr r8, [r7], #0x4
+ ldr r9, [r7], #0x8
+ str r9, [r10, r8]
+ subs r6, r6, #0x1
+ bne 11b
+
+ /* check whether we need to restore MMDC */
+ cmp r5, #0x0
+ beq 12f
+
+ /* check whether last suspend is with M/F mix off */
+ ldr r9, [r0, #PM_INFO_MX6Q_GPC_P_OFFSET]
+ ldr r6, [r9, #0x220]
+ cmp r6, #0x0
+ bne 13f
+12:
+ resume_iomuxc_gpr
+ reset_read_fifo
+
+ b 17f
+13:
+ /* restore MMDC settings */
+ ldr r6, [r0, #PM_INFO_MMDC_NUM_OFFSET]
+ ldr r7, =PM_INFO_MMDC_VAL_OFFSET
+ add r7, r7, r0
+14:
+ ldr r8, [r7], #0x4
+ ldr r9, [r7], #0x4
+ str r9, [r11, r8]
+ subs r6, r6, #0x1
+ bne 14b
+
+ /* let DDR enter self-refresh */
+ ldr r7, [r11, #MX6Q_MMDC_MAPSR]
+ orr r7, r7, #(1 << 20)
+ str r7, [r11, #MX6Q_MMDC_MAPSR]
+15:
+ ldr r7, [r11, #MX6Q_MMDC_MAPSR]
+ ands r7, r7, #(1 << 24)
+ beq 15b
+
+ resume_iomuxc_gpr
+ reset_read_fifo
+
+ /* let DDR out of self-refresh */
+ ldr r7, [r11, #MX6Q_MMDC_MAPSR]
+ bic r7, r7, #(1 << 20)
+ str r7, [r11, #MX6Q_MMDC_MAPSR]
+16:
+ ldr r7, [r11, #MX6Q_MMDC_MAPSR]
+ ands r7, r7, #(1 << 24)
+ bne 16b
+
+ /* kick off MMDC */
+ ldr r4, =0x0
+ str r4, [r11, #0x1c]
+
+17:
+ mmdc_out_and_auto_self_refresh
+
+ .endm
+
+ .macro store_ttbr1
+
+ /* Store TTBR1 to pm_info->ttbr1 */
+ mrc p15, 0, r7, c2, c0, 1
+ str r7, [r0, #PM_INFO_MX6Q_TTBR1_V_OFFSET]
+
+ /* Disable Branch Prediction, Z bit in SCTLR. */
+ mrc p15, 0, r6, c1, c0, 0
+ bic r6, r6, #0x800
+ mcr p15, 0, r6, c1, c0, 0
+
+ /* Flush the BTAC. */
+ ldr r6, =0x0
+ mcr p15, 0, r6, c7, c1, 6
+
+ ldr r6, =iram_tlb_phys_addr
+ ldr r6, [r6]
+ dsb
+ isb
+
+ /* Store the IRAM table in TTBR1 */
+ mcr p15, 0, r6, c2, c0, 1
+ /* Read TTBCR and set PD0=1, N = 1 */
+ mrc p15, 0, r6, c2, c0, 2
+ orr r6, r6, #0x11
+ mcr p15, 0, r6, c2, c0, 2
+
+ dsb
+ isb
+
+ /* flush the TLB */
+ ldr r6, =0x0
+ mcr p15, 0, r6, c8, c3, 0
+
+ /* Disable L1 data cache. */
+ mrc p15, 0, r6, c1, c0, 0
+ bic r6, r6, #0x4
+ mcr p15, 0, r6, c1, c0, 0
+
+ dsb
+ isb
+
+ is_cortex_a7
+ beq 17f
+
+#ifdef CONFIG_CACHE_L2X0
+ ldr r8, [r0, #PM_INFO_MX6Q_L2_V_OFFSET]
+ mov r6, #0x0
+ str r6, [r8, #0x100]
+
+ dsb
+ isb
+#endif
+17:
.endm
+ .macro restore_ttbr1
+
+ is_cortex_a7
+ beq 18f
+
+#ifdef CONFIG_CACHE_L2X0
+ /* Enable L2. */
+ ldr r8, [r0, #PM_INFO_MX6Q_L2_V_OFFSET]
+ ldr r7, =0x1
+ str r7, [r8, #0x100]
+#endif
+
+18:
+ /* Enable L1 data cache. */
+ mrc p15, 0, r6, c1, c0, 0
+ orr r6, r6, #0x4
+ mcr p15, 0, r6, c1, c0, 0
+
+ dsb
+ isb
+
+ /* Restore TTBCR */
+ /* Read TTBCR and set PD0=0, N = 0 */
+ mrc p15, 0, r6, c2, c0, 2
+ bic r6, r6, #0x11
+ mcr p15, 0, r6, c2, c0, 2
+ dsb
+ isb
+
+ /* flush the TLB */
+ ldr r6, =0x0
+ mcr p15, 0, r6, c8, c3, 0
+
+ /* Enable Branch Prediction, Z bit in SCTLR. */
+ mrc p15, 0, r6, c1, c0, 0
+ orr r6, r6, #0x800
+ mcr p15, 0, r6, c1, c0, 0
+
+ /* Flush the Branch Target Address Cache (BTAC) */
+ ldr r6, =0x0
+ mcr p15, 0, r6, c7, c1, 6
+
+ /* Restore TTBR1, get the origin ttbr1 from pm info */
+ ldr r7, [r0, #PM_INFO_MX6Q_TTBR1_V_OFFSET]
+ mcr p15, 0, r7, c2, c0, 1
+
+ .endm
+
+
ENTRY(imx6_suspend)
ldr r1, [r0, #PM_INFO_PBASE_OFFSET]
ldr r2, [r0, #PM_INFO_RESUME_ADDR_OFFSET]
@@ -185,10 +484,25 @@ ENTRY(imx6_suspend)
str r9, [r11, #MX6Q_SRC_GPR1]
str r1, [r11, #MX6Q_SRC_GPR2]
+ /*
+ * Check if the cpu is Cortex-A7, for Cortex-A7
+ * the cache implementation is not the same as
+ * Cortex-A9, so the cache maintenance operation
+ * is different.
+ */
+ is_cortex_a7
+ beq a7_dache_flush
+
/* need to sync L2 cache before DSM. */
sync_l2_cache
-
- ldr r11, [r0, #PM_INFO_MX6Q_MMDC_V_OFFSET]
+ b ttbr_store
+a7_dache_flush:
+ disable_l1_cache
+ttbr_store:
+ store_ttbr1
+
+ ldr r11, [r0, #PM_INFO_MX6Q_MMDC0_V_OFFSET]
+ ldr r12, [r0, #PM_INFO_MX6Q_MMDC1_V_OFFSET]
/*
* put DDR explicitly into self-refresh and
* disable automatic power savings.
@@ -207,31 +521,59 @@ poll_dvfs_set:
ands r7, r7, #(1 << 25)
beq poll_dvfs_set
+ /* check if lppdr2 2 channel mode is enabled */
+ ldr r7, =MX6Q_MMDC_MISC
+ ldr r6, [r11, r7]
+ ands r6, r6, #(1 << 2)
+ beq skip_self_refresh_ch1
+
+ ldr r7, [r12, #MX6Q_MMDC_MAPSR]
+ orr r7, r7, #0x1
+ str r7, [r12, #MX6Q_MMDC_MAPSR]
+
+ ldr r7, [r12, #MX6Q_MMDC_MAPSR]
+ orr r7, r7, #(1 << 21)
+ str r7, [r12, #MX6Q_MMDC_MAPSR]
+
+poll_dvfs_set_ch1:
+ ldr r7, [r12, #MX6Q_MMDC_MAPSR]
+ ands r7, r7, #(1 << 25)
+ beq poll_dvfs_set_ch1
+
+skip_self_refresh_ch1:
+ /* use r11 to store the IO address */
ldr r11, [r0, #PM_INFO_MX6Q_IOMUXC_V_OFFSET]
- ldr r6, =0x0
- ldr r7, [r0, #PM_INFO_MMDC_IO_NUM_OFFSET]
+ ldr r6, [r0, #PM_INFO_MMDC_IO_NUM_OFFSET]
ldr r8, =PM_INFO_MMDC_IO_VAL_OFFSET
add r8, r8, r0
- /* LPDDR2's last 3 IOs need special setting */
- cmp r3, #IMX_DDR_TYPE_LPDDR2
- subeq r7, r7, #0x3
set_mmdc_io_lpm:
- ldr r9, [r8], #0x8
- str r6, [r11, r9]
- subs r7, r7, #0x1
+ ldr r7, [r8], #0x8
+ ldr r9, [r8], #0x4
+ str r9, [r11, r7]
+ subs r6, r6, #0x1
bne set_mmdc_io_lpm
- cmp r3, #IMX_DDR_TYPE_LPDDR2
- bne set_mmdc_io_lpm_done
- ldr r6, =0x1000
- ldr r9, [r8], #0x8
- str r6, [r11, r9]
- ldr r9, [r8], #0x8
- str r6, [r11, r9]
- ldr r6, =0x80000
- ldr r9, [r8]
- str r6, [r11, r9]
-set_mmdc_io_lpm_done:
+ /* check whether it supports Mega/Fast off */
+ ldr r6, [r0, #PM_INFO_MMDC_NUM_OFFSET]
+ cmp r6, #0x0
+ beq set_mmdc_lpm_done
+
+ /* IOMUXC GPR DRAM_RESET */
+ add r11, r11, #0x4000
+ ldr r6, [r11, #0x8]
+ orr r6, r6, #(0x1 << 28)
+ str r6, [r11, #0x8]
+
+ /* IOMUXC GPR DRAM_RESET_BYPASS */
+ ldr r6, [r11, #0x8]
+ orr r6, r6, #(0x1 << 27)
+ str r6, [r11, #0x8]
+
+ /* IOMUXC GPR DRAM_CKE_BYPASS */
+ ldr r6, [r11, #0x8]
+ orr r6, r6, #(0x1 << 31)
+ str r6, [r11, #0x8]
+set_mmdc_lpm_done:
/*
* mask all GPC interrupts before
@@ -291,6 +633,27 @@ rbc_loop:
subs r6, r6, #0x1
bne rbc_loop
+ /*
+ * ERR005852 Analog: Transition from Deep Sleep Mode to
+ * LDO Bypass Mode may cause the slow response of the
+ * VDDARM_CAP output.
+ *
+ * Software workaround:
+ * if internal ldo(VDDARM) bypassed, switch to analog bypass
+ * mode (0x1E), prio to entering DSM, and then, revert to the
+ * normal bypass mode, when exiting from DSM.
+ */
+ ldr r11, [r0, #PM_INFO_MX6Q_ANATOP_V_OFFSET]
+ ldr r10, [r11, #MX6Q_ANATOP_CORE]
+ and r10, r10, #0x1f
+ cmp r10, #0x1f
+ bne ldo_check_done1
+ldo_analog_bypass:
+ ldr r10, [r11, #MX6Q_ANATOP_CORE]
+ bic r10, r10, #0x1f
+ orr r10, r10, #0x1e
+ str r10, [r11, #MX6Q_ANATOP_CORE]
+ldo_check_done1:
/* Zzz, enter stop mode */
wfi
nop
@@ -303,8 +666,28 @@ rbc_loop:
* wakeup source, system should auto
* resume, we need to restore MMDC IO first
*/
+ /* restore it with 0x1f if use ldo bypass mode.*/
+ ldr r10, [r11, #MX6Q_ANATOP_CORE]
+ and r10, r10, #0x1f
+ cmp r10, #0x1e
+ bne ldo_check_done2
+ldo_bypass_restore:
+ ldr r10, [r11, #MX6Q_ANATOP_CORE]
+ orr r10, r10, #0x1f
+ str r10, [r11, #MX6Q_ANATOP_CORE]
+ldo_check_done2:
mov r5, #0x0
- resume_mmdc
+ /* check whether it supports Mega/Fast off */
+ ldr r6, [r0, #PM_INFO_MMDC_NUM_OFFSET]
+ cmp r6, #0x0
+ beq only_resume_io
+ resume_mmdc_io
+ b resume_mmdc_done
+only_resume_io:
+ resume_io
+resume_mmdc_done:
+
+ restore_ttbr1
/* return to suspend finish */
ret lr
@@ -319,6 +702,16 @@ resume:
mcr p15, 0, r6, c1, c0, 0
isb
+ /* restore it with 0x1f if use ldo bypass mode.*/
+ ldr r11, [r0, #PM_INFO_MX6Q_ANATOP_P_OFFSET]
+ ldr r7, [r11, #MX6Q_ANATOP_CORE]
+ and r7, r7, #0x1f
+ cmp r7, #0x1e
+ bne ldo_check_done3
+ ldr r7, [r11, #MX6Q_ANATOP_CORE]
+ orr r7, r7, #0x1f
+ str r7, [r11, #MX6Q_ANATOP_CORE]
+ldo_check_done3:
/* get physical resume address from pm_info. */
ldr lr, [r0, #PM_INFO_RESUME_ADDR_OFFSET]
/* clear core0's entry and parameter */
@@ -329,7 +722,16 @@ resume:
ldr r3, [r0, #PM_INFO_DDR_TYPE_OFFSET]
mov r5, #0x1
- resume_mmdc
+ /* check whether it supports Mega/Fast off */
+ ldr r6, [r0, #PM_INFO_MMDC_NUM_OFFSET]
+ cmp r6, #0x0
+ beq dsm_only_resume_io
+ resume_mmdc_io
+ b dsm_resume_mmdc_done
+dsm_only_resume_io:
+ ldr r3, [r0, #PM_INFO_DDR_TYPE_OFFSET]
+ resume_io
+dsm_resume_mmdc_done:
ret lr
ENDPROC(imx6_suspend)
@@ -342,8 +744,11 @@ ENDPROC(imx6_suspend)
ENTRY(v7_cpu_resume)
bl v7_invalidate_l1
+ is_cortex_a7
+ beq done
#ifdef CONFIG_CACHE_L2X0
bl l2c310_early_resume
#endif
+done:
b cpu_resume
ENDPROC(v7_cpu_resume)
diff --git a/arch/arm/mach-imx/suspend-imx7.S b/arch/arm/mach-imx/suspend-imx7.S
new file mode 100644
index 000000000000..5f4e31152a69
--- /dev/null
+++ b/arch/arm/mach-imx/suspend-imx7.S
@@ -0,0 +1,714 @@
+/*
+ * Copyright (C) 2015 Freescale Semiconductor, Inc.
+ *
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/linkage.h>
+#include <asm/asm-offsets.h>
+#include "hardware.h"
+
+/*
+ * ==================== low level suspend ====================
+ *
+ * Better to follow below rules to use ARM registers:
+ * r0: pm_info structure address;
+ * r1 ~ r4: for saving pm_info members;
+ * r5 ~ r10: free registers;
+ * r11: io base address.
+ *
+ * suspend ocram space layout:
+ * ======================== high address ======================
+ * .
+ * .
+ * .
+ * ^
+ * ^
+ * ^
+ * imx7_suspend code
+ * PM_INFO structure(imx7_cpu_pm_info)
+ * ======================== low address =======================
+ */
+
+/*
+ * Below offsets are based on struct imx7_cpu_pm_info
+ * which defined in arch/arm/mach-imx/pm-imx7.c, this
+ * structure contains necessary pm info for low level
+ * suspend related code.
+ */
+#define PM_INFO_M4_RESERVE0_OFFSET 0x0
+#define PM_INFO_M4_RESERVE1_OFFSET 0x4
+#define PM_INFO_M4_RESERVE2_OFFSET 0x8
+#define PM_INFO_PBASE_OFFSET 0xc
+#define PM_INFO_RESUME_ADDR_OFFSET 0x10
+#define PM_INFO_DDR_TYPE_OFFSET 0x14
+#define PM_INFO_PM_INFO_SIZE_OFFSET 0x18
+#define PM_INFO_MX7_DDRC_P_OFFSET 0x1c
+#define PM_INFO_MX7_DDRC_V_OFFSET 0x20
+#define PM_INFO_MX7_DDRC_PHY_P_OFFSET 0x24
+#define PM_INFO_MX7_DDRC_PHY_V_OFFSET 0x28
+#define PM_INFO_MX7_SRC_P_OFFSET 0x2c
+#define PM_INFO_MX7_SRC_V_OFFSET 0x30
+#define PM_INFO_MX7_IOMUXC_GPR_P_OFFSET 0x34
+#define PM_INFO_MX7_IOMUXC_GPR_V_OFFSET 0x38
+#define PM_INFO_MX7_CCM_P_OFFSET 0x3c
+#define PM_INFO_MX7_CCM_V_OFFSET 0x40
+#define PM_INFO_MX7_GPC_P_OFFSET 0x44
+#define PM_INFO_MX7_GPC_V_OFFSET 0x48
+#define PM_INFO_MX7_SNVS_P_OFFSET 0x4c
+#define PM_INFO_MX7_SNVS_V_OFFSET 0x50
+#define PM_INFO_MX7_ANATOP_P_OFFSET 0x54
+#define PM_INFO_MX7_ANATOP_V_OFFSET 0x58
+#define PM_INFO_MX7_LPSR_P_OFFSET 0x5c
+#define PM_INFO_MX7_LPSR_V_OFFSET 0x60
+#define PM_INFO_MX7_GIC_DIST_P_OFFSET 0x64
+#define PM_INFO_MX7_GIC_DIST_V_OFFSET 0x68
+#define PM_INFO_MX7_TTBR1_V_OFFSET 0x6c
+#define PM_INFO_DDRC_REG_NUM_OFFSET 0x70
+#define PM_INFO_DDRC_REG_OFFSET 0x74
+#define PM_INFO_DDRC_VALUE_OFFSET 0x78
+#define PM_INFO_DDRC_PHY_REG_NUM_OFFSET 0x174
+#define PM_INFO_DDRC_PHY_REG_OFFSET 0x178
+#define PM_INFO_DDRC_PHY_VALUE_OFFSET 0x17c
+
+#define MX7_SRC_GPR1 0x74
+#define MX7_SRC_GPR2 0x78
+#define GPC_PGC_C0 0x800
+#define GPC_PGC_FM 0xa00
+#define ANADIG_SNVS_MISC_CTRL 0x380
+#define ANADIG_SNVS_MISC_CTRL_SET 0x384
+#define ANADIG_SNVS_MISC_CTRL_CLR 0x388
+#define ANADIG_DIGPROG 0x800
+#define DDRC_STAT 0x4
+#define DDRC_PWRCTL 0x30
+#define DDRC_PSTAT 0x3fc
+#define DDRC_PCTRL_0 0x490
+#define DDRC_DFIMISC 0x1b0
+#define DDRC_SWCTL 0x320
+#define DDRC_SWSTAT 0x324
+#define DDRPHY_LP_CON0 0x18
+
+#define CCM_SNVS_LPCG 0x250
+#define MX7D_GPC_IMR1 0x30
+#define MX7D_GPC_IMR2 0x34
+#define MX7D_GPC_IMR3 0x38
+#define MX7D_GPC_IMR4 0x3c
+
+ .align 3
+
+ .macro disable_l1_dcache
+
+ /*
+ * Flush all data from the L1 data cache before disabling
+ * SCTLR.C bit.
+ */
+ push {r0 - r10, lr}
+ ldr r7, =v7_flush_dcache_all
+ mov lr, pc
+ mov pc, r7
+ pop {r0 - r10, lr}
+
+ /* disable d-cache */
+ mrc p15, 0, r7, c1, c0, 0
+ bic r7, r7, #(1 << 2)
+ mcr p15, 0, r7, c1, c0, 0
+ dsb
+ isb
+
+ push {r0 - r10, lr}
+ ldr r7, =v7_flush_dcache_all
+ mov lr, pc
+ mov pc, r7
+ pop {r0 - r10, lr}
+
+ .endm
+
+ .macro store_ttbr1
+
+ /* Store TTBR1 to pm_info->ttbr1 */
+ mrc p15, 0, r7, c2, c0, 1
+ str r7, [r0, #PM_INFO_MX7_TTBR1_V_OFFSET]
+
+ /* Disable Branch Prediction, Z bit in SCTLR. */
+ mrc p15, 0, r6, c1, c0, 0
+ bic r6, r6, #0x800
+ mcr p15, 0, r6, c1, c0, 0
+
+ /* Flush the BTAC. */
+ ldr r6, =0x0
+ mcr p15, 0, r6, c7, c1, 6
+
+ ldr r6, =iram_tlb_phys_addr
+ ldr r6, [r6]
+ dsb
+ isb
+
+ /* Store the IRAM table in TTBR1 */
+ mcr p15, 0, r6, c2, c0, 1
+ /* Read TTBCR and set PD0=1, N = 1 */
+ mrc p15, 0, r6, c2, c0, 2
+ orr r6, r6, #0x11
+ mcr p15, 0, r6, c2, c0, 2
+
+ dsb
+ isb
+
+ /* flush the TLB */
+ ldr r6, =0x0
+ mcr p15, 0, r6, c8, c3, 0
+
+ .endm
+
+ .macro restore_ttbr1
+
+ /* Enable L1 data cache. */
+ mrc p15, 0, r6, c1, c0, 0
+ orr r6, r6, #0x4
+ mcr p15, 0, r6, c1, c0, 0
+
+ dsb
+ isb
+
+ /* Restore TTBCR */
+ /* Read TTBCR and set PD0=0, N = 0 */
+ mrc p15, 0, r6, c2, c0, 2
+ bic r6, r6, #0x11
+ mcr p15, 0, r6, c2, c0, 2
+ dsb
+ isb
+
+ /* flush the TLB */
+ ldr r6, =0x0
+ mcr p15, 0, r6, c8, c3, 0
+
+ /* Enable Branch Prediction, Z bit in SCTLR. */
+ mrc p15, 0, r6, c1, c0, 0
+ orr r6, r6, #0x800
+ mcr p15, 0, r6, c1, c0, 0
+
+ /* Flush the Branch Target Address Cache (BTAC) */
+ ldr r6, =0x0
+ mcr p15, 0, r6, c7, c1, 6
+
+ /* Restore TTBR1, get the origin ttbr1 from pm info */
+ ldr r7, [r0, #PM_INFO_MX7_TTBR1_V_OFFSET]
+ mcr p15, 0, r7, c2, c0, 1
+
+ .endm
+
+ .macro ddrc_enter_self_refresh
+
+ ldr r11, [r0, #PM_INFO_MX7_DDRC_V_OFFSET]
+
+ /* let DDR out of self-refresh */
+ ldr r7, =0x0
+ str r7, [r11, #DDRC_PWRCTL]
+
+ /* wait rw port_busy clear */
+ ldr r6, =(0x1 << 16)
+ orr r6, r6, #0x1
+1:
+ ldr r7, [r11, #DDRC_PSTAT]
+ ands r7, r7, r6
+ bne 1b
+
+ /* enter self-refresh bit 5 */
+ ldr r7, =(0x1 << 5)
+ str r7, [r11, #DDRC_PWRCTL]
+
+ /* wait until self-refresh mode entered */
+2:
+ ldr r7, [r11, #DDRC_STAT]
+ and r7, r7, #0x3
+ cmp r7, #0x3
+ bne 2b
+3:
+ ldr r7, [r11, #DDRC_STAT]
+ ands r7, r7, #0x20
+ beq 3b
+
+ /* disable dram clk */
+ ldr r7, [r11, #DDRC_PWRCTL]
+ orr r7, r7, #(1 << 3)
+ str r7, [r11, #DDRC_PWRCTL]
+
+ .endm
+
+ .macro ddrc_exit_self_refresh
+
+ cmp r5, #0x0
+ ldreq r11, [r0, #PM_INFO_MX7_DDRC_V_OFFSET]
+ ldrne r11, [r0, #PM_INFO_MX7_DDRC_P_OFFSET]
+
+ /* let DDR out of self-refresh */
+ ldr r7, =0x0
+ str r7, [r11, #DDRC_PWRCTL]
+
+ /* wait until self-refresh mode entered */
+4:
+ ldr r7, [r11, #DDRC_STAT]
+ and r7, r7, #0x3
+ cmp r7, #0x3
+ beq 4b
+
+ /* enable auto self-refresh */
+ ldr r7, [r11, #DDRC_PWRCTL]
+ orr r7, r7, #(1 << 0)
+ str r7, [r11, #DDRC_PWRCTL]
+
+ .endm
+
+ .macro wait_delay
+5:
+ subs r6, r6, #0x1
+ bne 5b
+
+ .endm
+
+ .macro ddr_enter_retention
+
+ ldr r11, [r0, #PM_INFO_MX7_DDRC_V_OFFSET]
+
+ /* let DDR out of self-refresh */
+ ldr r7, =0x0
+ str r7, [r11, #DDRC_PCTRL_0]
+
+ /* wait rw port_busy clear */
+ ldr r6, =(0x1 << 16)
+ orr r6, r6, #0x1
+6:
+ ldr r7, [r11, #DDRC_PSTAT]
+ ands r7, r7, r6
+ bne 6b
+
+ ldr r11, [r0, #PM_INFO_MX7_DDRC_V_OFFSET]
+ /* enter self-refresh bit 5 */
+ ldr r7, =(0x1 << 5)
+ str r7, [r11, #DDRC_PWRCTL]
+
+ /* wait until self-refresh mode entered */
+7:
+ ldr r7, [r11, #DDRC_STAT]
+ and r7, r7, #0x3
+ cmp r7, #0x3
+ bne 7b
+8:
+ ldr r7, [r11, #DDRC_STAT]
+ ands r7, r7, #0x20
+ beq 8b
+
+ /* disable dram clk */
+ ldr r7, =(0x1 << 5)
+ orr r7, r7, #(1 << 3)
+ str r7, [r11, #DDRC_PWRCTL]
+
+ ldr r11, [r0, #PM_INFO_MX7_ANATOP_V_OFFSET]
+ ldr r7, [r11, #ANADIG_DIGPROG]
+ and r7, r7, #0xff
+ cmp r7, #0x11
+ bne 10f
+
+ /* TO 1.1 */
+ ldr r11, [r0, #PM_INFO_MX7_IOMUXC_GPR_V_OFFSET]
+ ldr r7, =0x38000000
+ str r7, [r11]
+
+ /* LPSR mode need to use TO1.0 flow as IOMUX lost power */
+ ldr r10, [r0, #PM_INFO_MX7_LPSR_V_OFFSET]
+ ldr r7, [r10]
+ cmp r7, #0x0
+ beq 11f
+10:
+ /* reset ddr_phy */
+ ldr r11, [r0, #PM_INFO_MX7_ANATOP_V_OFFSET]
+ ldr r7, =0x0
+ str r7, [r11, #ANADIG_SNVS_MISC_CTRL]
+
+ /* delay 7 us */
+ ldr r6, =6000
+ wait_delay
+
+ ldr r11, [r0, #PM_INFO_MX7_SRC_V_OFFSET]
+ ldr r6, =0x1000
+ ldr r7, [r11, r6]
+ orr r7, r7, #0x1
+ str r7, [r11, r6]
+11:
+ /* turn off ddr power */
+ ldr r11, [r0, #PM_INFO_MX7_ANATOP_V_OFFSET]
+ ldr r7, =(0x1 << 29)
+ str r7, [r11, #ANADIG_SNVS_MISC_CTRL_SET]
+
+ ldr r11, [r0, #PM_INFO_MX7_SRC_V_OFFSET]
+ ldr r6, =0x1000
+ ldr r7, [r11, r6]
+ orr r7, r7, #0x1
+ str r7, [r11, r6]
+
+ .endm
+
+ .macro ddr_exit_retention
+
+ cmp r5, #0x0
+ ldreq r1, [r0, #PM_INFO_MX7_ANATOP_V_OFFSET]
+ ldrne r1, [r0, #PM_INFO_MX7_ANATOP_P_OFFSET]
+ ldreq r2, [r0, #PM_INFO_MX7_SRC_V_OFFSET]
+ ldrne r2, [r0, #PM_INFO_MX7_SRC_P_OFFSET]
+ ldreq r3, [r0, #PM_INFO_MX7_DDRC_V_OFFSET]
+ ldrne r3, [r0, #PM_INFO_MX7_DDRC_P_OFFSET]
+ ldreq r4, [r0, #PM_INFO_MX7_DDRC_PHY_V_OFFSET]
+ ldrne r4, [r0, #PM_INFO_MX7_DDRC_PHY_P_OFFSET]
+ ldreq r10, [r0, #PM_INFO_MX7_CCM_V_OFFSET]
+ ldrne r10, [r0, #PM_INFO_MX7_CCM_P_OFFSET]
+ ldreq r11, [r0, #PM_INFO_MX7_IOMUXC_GPR_V_OFFSET]
+ ldrne r11, [r0, #PM_INFO_MX7_IOMUXC_GPR_P_OFFSET]
+
+ /* turn on ddr power */
+ ldr r7, =(0x1 << 29)
+ str r7, [r1, #ANADIG_SNVS_MISC_CTRL_CLR]
+
+ ldr r6, =50
+ wait_delay
+
+ /* clear ddr_phy reset */
+ ldr r6, =0x1000
+ ldr r7, [r2, r6]
+ orr r7, r7, #0x3
+ str r7, [r2, r6]
+ ldr r7, [r2, r6]
+ bic r7, r7, #0x1
+ str r7, [r2, r6]
+13:
+ ldr r6, [r0, #PM_INFO_DDRC_REG_NUM_OFFSET]
+ ldr r7, =PM_INFO_DDRC_REG_OFFSET
+ add r7, r7, r0
+14:
+ ldr r8, [r7], #0x4
+ ldr r9, [r7], #0x4
+ str r9, [r3, r8]
+ subs r6, r6, #0x1
+ bne 14b
+ ldr r7, =0x20
+ str r7, [r3, #DDRC_PWRCTL]
+ ldr r7, =0x0
+ str r7, [r3, #DDRC_DFIMISC]
+
+ /* do PHY, clear ddr_phy reset */
+ ldr r6, =0x1000
+ ldr r7, [r2, r6]
+ bic r7, r7, #0x2
+ str r7, [r2, r6]
+
+ ldr r7, [r1, #ANADIG_DIGPROG]
+ and r7, r7, #0xff
+ cmp r7, #0x11
+ bne 12f
+
+ /*
+ * TKT262940:
+ * System hang when press RST for DDR PAD is
+ * in retention mode, fixed on TO1.1
+ */
+ ldr r7, [r11]
+ bic r7, r7, #(1 << 27)
+ str r7, [r11]
+ ldr r7, [r11]
+ bic r7, r7, #(1 << 29)
+ str r7, [r11]
+12:
+ ldr r7, =(0x1 << 30)
+ str r7, [r1, #ANADIG_SNVS_MISC_CTRL_SET]
+
+ /* need to delay ~5mS */
+ ldr r6, =0x100000
+ wait_delay
+
+ ldr r6, [r0, #PM_INFO_DDRC_PHY_REG_NUM_OFFSET]
+ ldr r7, =PM_INFO_DDRC_PHY_REG_OFFSET
+ add r7, r7, r0
+
+15:
+ ldr r8, [r7], #0x4
+ ldr r9, [r7], #0x4
+ str r9, [r4, r8]
+ subs r6, r6, #0x1
+ bne 15b
+
+ ldr r7, =0x0
+ add r9, r10, #0x4000
+ str r7, [r9, #0x130]
+
+ ldr r7, =0x170
+ orr r7, r7, #0x8
+ str r7, [r11, #0x20]
+
+ ldr r7, =0x2
+ add r9, r10, #0x4000
+ str r7, [r9, #0x130]
+
+ ldr r7, =0xf
+ str r7, [r4, #DDRPHY_LP_CON0]
+
+ /* wait until self-refresh mode entered */
+16:
+ ldr r7, [r3, #DDRC_STAT]
+ and r7, r7, #0x3
+ cmp r7, #0x3
+ bne 16b
+ ldr r7, =0x0
+ str r7, [r3, #DDRC_SWCTL]
+ ldr r7, =0x1
+ str r7, [r3, #DDRC_DFIMISC]
+ ldr r7, =0x1
+ str r7, [r3, #DDRC_SWCTL]
+17:
+ ldr r7, [r3, #DDRC_SWSTAT]
+ and r7, r7, #0x1
+ cmp r7, #0x1
+ bne 17b
+18:
+ ldr r7, [r3, #DDRC_STAT]
+ and r7, r7, #0x20
+ cmp r7, #0x20
+ bne 18b
+
+ /* let DDR out of self-refresh */
+ ldr r7, =0x0
+ str r7, [r3, #DDRC_PWRCTL]
+19:
+ ldr r7, [r3, #DDRC_STAT]
+ and r7, r7, #0x30
+ cmp r7, #0x0
+ bne 19b
+
+20:
+ ldr r7, [r3, #DDRC_STAT]
+ and r7, r7, #0x3
+ cmp r7, #0x1
+ bne 20b
+
+ /* enable port */
+ ldr r7, =0x1
+ str r7, [r3, #DDRC_PCTRL_0]
+
+ /* enable auto self-refresh */
+ ldr r7, [r3, #DDRC_PWRCTL]
+ orr r7, r7, #(1 << 0)
+ str r7, [r3, #DDRC_PWRCTL]
+
+ .endm
+
+ENTRY(imx7_suspend)
+ push {r4-r12}
+
+ /* make sure SNVS clk is enabled */
+ ldr r11, [r0, #PM_INFO_MX7_CCM_V_OFFSET]
+ add r11, r11, #0x4000
+ ldr r7, =0x3
+ str r7, [r11, #CCM_SNVS_LPCG]
+
+ /* check whether it is a standby mode */
+ ldr r11, [r0, #PM_INFO_MX7_GPC_V_OFFSET]
+ ldr r7, [r11, #GPC_PGC_C0]
+ cmp r7, #0
+ beq ddr_only_self_refresh
+
+ /*
+ * The value of r0 is mapped the same in origin table and IRAM table,
+ * thus no need to care r0 here.
+ */
+ ldr r1, [r0, #PM_INFO_PBASE_OFFSET]
+ ldr r2, [r0, #PM_INFO_RESUME_ADDR_OFFSET]
+ ldr r3, [r0, #PM_INFO_DDR_TYPE_OFFSET]
+ ldr r4, [r0, #PM_INFO_PM_INFO_SIZE_OFFSET]
+
+ /*
+ * counting the resume address in iram
+ * to set it in SRC register.
+ */
+ ldr r6, =imx7_suspend
+ ldr r7, =resume
+ sub r7, r7, r6
+ add r8, r1, r4
+ add r9, r8, r7
+
+ ldr r11, [r0, #PM_INFO_MX7_SRC_V_OFFSET]
+ /* store physical resume addr and pm_info address. */
+ str r9, [r11, #MX7_SRC_GPR1]
+ str r1, [r11, #MX7_SRC_GPR2]
+
+ disable_l1_dcache
+
+ store_ttbr1
+
+ ldr r11, [r0, #PM_INFO_MX7_GPC_V_OFFSET]
+ ldr r7, [r11, #GPC_PGC_FM]
+ cmp r7, #0
+ beq ddr_only_self_refresh
+
+ ddr_enter_retention
+ /* enter LPSR mode if resume addr is valid */
+ ldr r11, [r0, #PM_INFO_MX7_LPSR_V_OFFSET]
+ ldr r7, [r11]
+ cmp r7, #0x0
+ beq ddr_retention_enter_out
+
+ /* disable STOP mode before entering LPSR */
+ ldr r11, [r0, #PM_INFO_MX7_GPC_V_OFFSET]
+ ldr r7, [r11]
+ bic r7, #0xf
+ str r7, [r11]
+
+ /* shut down vddsoc to enter lpsr mode */
+ ldr r11, [r0, #PM_INFO_MX7_SNVS_V_OFFSET]
+ ldr r7, [r11, #0x38]
+ orr r7, r7, #0x60
+ str r7, [r11, #0x38]
+wait_shutdown:
+ wfi
+ nop
+ nop
+ nop
+ nop
+ b wait_shutdown
+
+ddr_only_self_refresh:
+ ddrc_enter_self_refresh
+ b wfi
+ddr_retention_enter_out:
+
+ ldr r11, [r0, #PM_INFO_MX7_GIC_DIST_V_OFFSET]
+ ldr r7, =0x0
+ ldr r8, =0x1000
+ str r7, [r11, r8]
+
+ ldr r11, [r0, #PM_INFO_MX7_GPC_V_OFFSET]
+ ldr r4, [r11, #MX7D_GPC_IMR1]
+ ldr r5, [r11, #MX7D_GPC_IMR2]
+ ldr r6, [r11, #MX7D_GPC_IMR3]
+ ldr r7, [r11, #MX7D_GPC_IMR4]
+
+ ldr r8, =0xffffffff
+ str r8, [r11, #MX7D_GPC_IMR1]
+ str r8, [r11, #MX7D_GPC_IMR2]
+ str r8, [r11, #MX7D_GPC_IMR3]
+ str r8, [r11, #MX7D_GPC_IMR4]
+
+ /*
+ * enable the RBC bypass counter here
+ * to hold off the interrupts. RBC counter
+ * = 8 (240us). With this setting, the latency
+ * from wakeup interrupt to ARM power up
+ * is ~250uS.
+ */
+ ldr r8, [r11, #0x14]
+ bic r8, r8, #(0x3f << 24)
+ orr r8, r8, #(0x8 << 24)
+ str r8, [r11, #0x14]
+
+ /* enable the counter. */
+ ldr r8, [r11, #0x14]
+ orr r8, r8, #(0x1 << 30)
+ str r8, [r11, #0x14]
+
+ /* unmask all the GPC interrupts. */
+ str r4, [r11, #MX7D_GPC_IMR1]
+ str r5, [r11, #MX7D_GPC_IMR2]
+ str r6, [r11, #MX7D_GPC_IMR3]
+ str r7, [r11, #MX7D_GPC_IMR4]
+
+ /*
+ * now delay for a short while (3usec)
+ * ARM is at 1GHz at this point
+ * so a short loop should be enough.
+ * this delay is required to ensure that
+ * the RBC counter can start counting in
+ * case an interrupt is already pending
+ * or in case an interrupt arrives just
+ * as ARM is about to assert DSM_request.
+ */
+ ldr r7, =2000
+rbc_loop:
+ subs r7, r7, #0x1
+ bne rbc_loop
+wfi:
+ /* Zzz, enter stop mode */
+ wfi
+ nop
+ nop
+ nop
+ nop
+
+ mov r5, #0x0
+
+ ldr r11, [r0, #PM_INFO_MX7_GPC_V_OFFSET]
+ ldr r7, [r11, #GPC_PGC_FM]
+ cmp r7, #0
+ beq wfi_ddr_self_refresh_out
+
+ ddr_exit_retention
+ b wfi_ddr_retention_out
+wfi_ddr_self_refresh_out:
+ ddrc_exit_self_refresh
+wfi_ddr_retention_out:
+
+ /* check whether it is a standby mode */
+ ldr r11, [r0, #PM_INFO_MX7_GPC_V_OFFSET]
+ ldr r7, [r11, #GPC_PGC_C0]
+ cmp r7, #0
+ beq standby_out
+
+ ldr r11, [r0, #PM_INFO_MX7_GIC_DIST_V_OFFSET]
+ ldr r7, =0x1
+ ldr r8, =0x1000
+ str r7, [r11, r8]
+
+ restore_ttbr1
+standby_out:
+ pop {r4-r12}
+ /* return to suspend finish */
+ mov pc, lr
+
+resume:
+ /* invalidate L1 I-cache first */
+ mov r6, #0x0
+ mcr p15, 0, r6, c7, c5, 0
+ mcr p15, 0, r6, c7, c5, 6
+ /* enable the Icache and branch prediction */
+ mov r6, #0x1800
+ mcr p15, 0, r6, c1, c0, 0
+ isb
+
+ /* get physical resume address from pm_info. */
+ ldr lr, [r0, #PM_INFO_RESUME_ADDR_OFFSET]
+ /* clear core0's entry and parameter */
+ ldr r11, [r0, #PM_INFO_MX7_SRC_P_OFFSET]
+ mov r7, #0x0
+ str r7, [r11, #MX7_SRC_GPR1]
+ str r7, [r11, #MX7_SRC_GPR2]
+
+ mov r5, #0x1
+
+ ldr r11, [r0, #PM_INFO_MX7_GPC_P_OFFSET]
+ ldr r7, [r11, #GPC_PGC_FM]
+ cmp r7, #0
+ beq dsm_ddr_self_refresh_out
+
+ ddr_exit_retention
+ b dsm_ddr_retention_out
+dsm_ddr_self_refresh_out:
+ ddrc_exit_self_refresh
+dsm_ddr_retention_out:
+
+ mov pc, lr
+ENDPROC(imx7_suspend)
+
+ENTRY(ca7_cpu_resume)
+ bl v7_invalidate_l1
+ b cpu_resume
+ENDPROC(ca7_cpu_resume)
diff --git a/arch/arm/mach-imx/suspend-imx7ulp.S b/arch/arm/mach-imx/suspend-imx7ulp.S
new file mode 100644
index 000000000000..bd45e460f75f
--- /dev/null
+++ b/arch/arm/mach-imx/suspend-imx7ulp.S
@@ -0,0 +1,625 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017 NXP
+ *
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/linkage.h>
+#include <asm/asm-offsets.h>
+#include "hardware.h"
+
+/*
+ * ==================== low level suspend ====================
+ *
+ * Better to follow below rules to use ARM registers:
+ * r0: pm_info structure address;
+ *
+ * suspend ocram space layout:
+ * ======================== high address ======================
+ * .
+ * .
+ * .
+ * ^
+ * ^
+ * ^
+ * imx7ulp_suspend code
+ * PM_INFO structure(imx7ulp_cpu_pm_info)
+ * ======================== low address =======================
+ */
+
+/*
+ * Below offsets are based on struct imx7ulp_cpu_pm_info
+ * which defined in arch/arm/mach-imx/pm-imx7ulp.c, this
+ * structure contains necessary pm info for low level
+ * suspend related code.
+ */
+#define PM_INFO_M4_RESERVE0_OFFSET 0x0
+#define PM_INFO_M4_RESERVE1_OFFSET 0x4
+#define PM_INFO_M4_RESERVE2_OFFSET 0x8
+#define PM_INFO_PBASE_OFFSET 0xc
+#define PM_INFO_RESUME_ADDR_OFFSET 0x10
+#define PM_INFO_PM_INFO_SIZE_OFFSET 0x14
+#define PM_INFO_PM_INFO_SIM_VBASE_OFFSET 0x18
+#define PM_INFO_PM_INFO_SCG1_VBASE_OFFSET 0x1c
+#define PM_INFO_PM_INFO_MMDC_VBASE_OFFSET 0x20
+#define PM_INFO_PM_INFO_MMDC_IO_VBASE_OFFSET 0x24
+#define PM_INFO_PM_INFO_SMC1_VBASE_OFFSET 0x28
+#define PM_INFO_PM_INFO_SCG1_VAL_OFFSET 0x2c
+#define PM_INFO_MX7ULP_TTBR1_V_OFFSET 0x70
+#define PM_INFO_MX7ULP_GPIO_REG_OFFSET 0x74
+#define PM_INFO_IOMUX_NUM_OFFSET 0x94
+#define PM_INFO_IOMUX_VAL_OFFSET 0x98
+#define PM_INFO_SELECT_INPUT_NUM_OFFSET 0x268
+#define PM_INFO_SELECT_INPUT_VAL_OFFSET 0x26c
+#define PM_INFO_MMDC_IO_NUM_OFFSET 0x3a4
+#define PM_INFO_MMDC_IO_VAL_OFFSET 0x3a8
+/* below offsets depends on MX7ULP_MAX_MMDC_IO_NUM(36) definition */
+#define PM_INFO_MMDC_NUM_OFFSET 0x5a8
+#define PM_INFO_MMDC_VAL_OFFSET 0x5ac
+
+#define DGO_CTRL0 0x50
+#define DGO_GPR3 0x60
+#define DGO_GPR4 0x64
+
+#define MX7ULP_MMDC_MISC 0x18
+#define MX7ULP_MMDC_MAPSR 0x404
+#define MX7ULP_MMDC_MPDGCTRL0 0x83c
+
+#define SCG_RCCR 0x14
+#define SCG_DDRCCR 0x30
+#define SCG_NICCCR 0x40
+#define SCG_FIRCDIV 0x304
+#define SCG_APLLCSR 0x500
+#define SCG_APLLDIV 0x504
+#define SCG_APLLCFG 0x508
+#define SCG_APLLPFD 0x50c
+#define SCG_APLLNUM 0x510
+#define SCG_APLLDENOM 0x514
+#define SCG_SPLLCSR 0x600
+#define SCG_SPLLDIV 0x604
+#define SCG_SPLLCFG 0x608
+#define SCG_SPLLPFD 0x60c
+#define SCG_SPLLNUM 0x610
+#define SCG_SPLLDENOM 0x614
+#define SCG_SOSCDIV 0x104
+
+#define PMC1_CTRL 0x24
+
+#define GPIO_PDOR 0x0
+#define GPIO_PDDR 0x14
+#define GPIO_PORT_NUM 0x4
+#define GPIO_PORT_OFFSET 0x40
+
+#define PMCTRL 0x10
+
+#define IOMUX_OFFSET 0x0
+#define SELECT_INPUT_OFFSET 0x200
+
+ .align 3
+
+ .macro store_ttbr1
+
+ /* Store TTBR1 to pm_info->ttbr1 */
+ mrc p15, 0, r7, c2, c0, 1
+ str r7, [r0, #PM_INFO_MX7ULP_TTBR1_V_OFFSET]
+
+ /* Disable Branch Prediction, Z bit in SCTLR. */
+ mrc p15, 0, r6, c1, c0, 0
+ bic r6, r6, #0x800
+ mcr p15, 0, r6, c1, c0, 0
+
+ /* Flush the BTAC. */
+ ldr r6, =0x0
+ mcr p15, 0, r6, c7, c1, 6
+
+ ldr r6, =iram_tlb_phys_addr
+ ldr r6, [r6]
+ dsb
+ isb
+
+ /* Store the IRAM table in TTBR1 */
+ mcr p15, 0, r6, c2, c0, 1
+ /* Read TTBCR and set PD0=1, N = 1 */
+ mrc p15, 0, r6, c2, c0, 2
+ orr r6, r6, #0x11
+ mcr p15, 0, r6, c2, c0, 2
+
+ dsb
+ isb
+
+ /* flush the TLB */
+ ldr r6, =0x0
+ mcr p15, 0, r6, c8, c3, 0
+
+ .endm
+
+ .macro restore_ttbr1
+
+ /* Enable L1 data cache. */
+ mrc p15, 0, r6, c1, c0, 0
+ orr r6, r6, #0x4
+ mcr p15, 0, r6, c1, c0, 0
+
+ dsb
+ isb
+
+ /* Restore TTBCR */
+ /* Read TTBCR and set PD0=0, N = 0 */
+ mrc p15, 0, r6, c2, c0, 2
+ bic r6, r6, #0x11
+ mcr p15, 0, r6, c2, c0, 2
+ dsb
+ isb
+
+ /* flush the TLB */
+ ldr r6, =0x0
+ mcr p15, 0, r6, c8, c3, 0
+
+ /* Enable Branch Prediction, Z bit in SCTLR. */
+ mrc p15, 0, r6, c1, c0, 0
+ orr r6, r6, #0x800
+ mcr p15, 0, r6, c1, c0, 0
+
+ /* Flush the Branch Target Address Cache (BTAC) */
+ ldr r6, =0x0
+ mcr p15, 0, r6, c7, c1, 6
+
+ /* Restore TTBR1, get the origin ttbr1 from pm info */
+ ldr r7, [r0, #PM_INFO_MX7ULP_TTBR1_V_OFFSET]
+ mcr p15, 0, r7, c2, c0, 1
+
+ .endm
+
+ .macro disable_l1_dcache
+
+ /*
+ * Flush all data from the L1 data cache before disabling
+ * SCTLR.C bit.
+ */
+ push {r0 - r10, lr}
+ ldr r7, =v7_flush_dcache_all
+ mov lr, pc
+ mov pc, r7
+ pop {r0 - r10, lr}
+
+ /* disable d-cache */
+ mrc p15, 0, r7, c1, c0, 0
+ bic r7, r7, #(1 << 2)
+ mcr p15, 0, r7, c1, c0, 0
+ dsb
+ isb
+
+ push {r0 - r10, lr}
+ ldr r7, =v7_flush_dcache_all
+ mov lr, pc
+ mov pc, r7
+ pop {r0 - r10, lr}
+
+ .endm
+
+ .macro restore_mmdc_settings
+
+ ldr r10, =MX7ULP_MMDC_IO_BASE_ADDR
+ ldr r11, =MX7ULP_MMDC_BASE_ADDR
+
+ /* resume mmdc iomuxc settings */
+ ldr r6, [r0, #PM_INFO_MMDC_IO_NUM_OFFSET]
+ ldr r7, =PM_INFO_MMDC_IO_VAL_OFFSET
+ add r7, r7, r0
+11:
+ ldr r8, [r7], #0x4
+ ldr r9, [r7], #0x4
+ str r9, [r10, r8]
+ subs r6, r6, #0x1
+ bne 11b
+
+ /* restore MMDC settings */
+ ldr r6, [r0, #PM_INFO_MMDC_NUM_OFFSET]
+ ldr r7, =PM_INFO_MMDC_VAL_OFFSET
+ add r7, r7, r0
+1:
+ ldr r8, [r7], #0x4
+ ldr r9, [r7], #0x4
+ str r9, [r11, r8]
+ subs r6, r6, #0x1
+ bne 1b
+
+ /* let DDR enter self-refresh */
+ ldr r7, [r11, #MX7ULP_MMDC_MAPSR]
+ orr r7, r7, #(1 << 20)
+ str r7, [r11, #MX7ULP_MMDC_MAPSR]
+2:
+ ldr r7, [r11, #MX7ULP_MMDC_MAPSR]
+ ands r7, r7, #(1 << 24)
+ beq 2b
+
+ /* let DDR out of self-refresh */
+ ldr r7, [r11, #MX7ULP_MMDC_MAPSR]
+ bic r7, r7, #(1 << 20)
+ str r7, [r11, #MX7ULP_MMDC_MAPSR]
+3:
+ ldr r7, [r11, #MX7ULP_MMDC_MAPSR]
+ ands r7, r7, #(1 << 24)
+ bne 3b
+
+ /* kick off MMDC */
+ ldr r4, =0x0
+ str r4, [r11, #0x1c]
+
+ /* let DDR out of self-refresh */
+ ldr r7, [r11, #MX7ULP_MMDC_MAPSR]
+ bic r7, r7, #(1 << 20)
+ str r7, [r11, #MX7ULP_MMDC_MAPSR]
+4:
+ ldr r7, [r11, #MX7ULP_MMDC_MAPSR]
+ ands r7, r7, #(1 << 24)
+ bne 4b
+
+ /* enable DDR auto power saving */
+ ldr r7, [r11, #MX7ULP_MMDC_MAPSR]
+ bic r7, r7, #0x1
+ str r7, [r11, #MX7ULP_MMDC_MAPSR]
+
+ .endm
+
+ENTRY(imx7ulp_suspend)
+ push {r4-r12}
+
+ /*
+ * The value of r0 is mapped the same in origin table and IRAM table,
+ * thus no need to care r0 here.
+ */
+ ldr r1, [r0, #PM_INFO_PBASE_OFFSET]
+ ldr r2, [r0, #PM_INFO_RESUME_ADDR_OFFSET]
+ ldr r3, [r0, #PM_INFO_PM_INFO_SIZE_OFFSET]
+
+ /*
+ * counting the resume address in iram
+ * to set it in SRC register.
+ */
+ ldr r6, =imx7ulp_suspend
+ ldr r7, =resume
+ sub r7, r7, r6
+ add r8, r1, r3
+ add r9, r8, r7
+
+ ldr r11, [r0, #PM_INFO_PM_INFO_SIM_VBASE_OFFSET]
+ /* store physical resume addr and pm_info address. */
+ str r9, [r11, #DGO_GPR3]
+ str r1, [r11, #DGO_GPR4]
+ ldr r7, [r11, #DGO_CTRL0]
+ orr r7, r7, #0xc
+ str r7, [r11, #DGO_CTRL0]
+wait_dgo:
+ ldr r7, [r11, #DGO_CTRL0]
+ and r7, r7, #0x18000
+ cmp r7, #0x18000
+ bne wait_dgo
+
+ ldr r7, [r11, #DGO_CTRL0]
+ orr r7, r7, #0x18000
+ bic r7, r7, #0xc
+ str r7, [r11, #DGO_CTRL0]
+
+ disable_l1_dcache
+
+ store_ttbr1
+
+ ldr r11, [r0, #PM_INFO_PM_INFO_MMDC_VBASE_OFFSET]
+
+ /*
+ * put DDR explicitly into self-refresh and
+ * disable automatic power savings.
+ */
+ ldr r7, [r11, #MX7ULP_MMDC_MAPSR]
+ orr r7, r7, #0x1
+ str r7, [r11, #MX7ULP_MMDC_MAPSR]
+
+ /* make the DDR explicitly enter self-refresh. */
+ ldr r7, [r11, #MX7ULP_MMDC_MAPSR]
+ orr r7, r7, #(1 << 20)
+ str r7, [r11, #MX7ULP_MMDC_MAPSR]
+
+poll_dvfs_set:
+ ldr r7, [r11, #MX7ULP_MMDC_MAPSR]
+ ands r7, r7, #(1 << 24)
+ beq poll_dvfs_set
+
+ /* put mmdc io into lpm */
+ ldr r11, [r0, #PM_INFO_PM_INFO_MMDC_IO_VBASE_OFFSET]
+ ldr r10, [r0, #PM_INFO_MMDC_IO_NUM_OFFSET]
+ ldr r7, =PM_INFO_MMDC_IO_VAL_OFFSET
+ add r7, r7, r0
+mmdc_io_lpm:
+ ldr r8, [r7], #0x8
+ mov r9, #0x0
+ str r9, [r11, r8]
+ subs r10, r10, #0x1
+ bne mmdc_io_lpm
+
+ /* switch NIC clock to FIRC */
+ ldr r10, [r0, #PM_INFO_PM_INFO_SCG1_VBASE_OFFSET]
+ ldr r7, [r10, #SCG_NICCCR]
+ bic r7, #(1 << 28)
+ str r7, [r10, #SCG_NICCCR]
+
+ /* switch RUN clock to FIRC */
+ ldr r7, [r10, #SCG_RCCR]
+ bic r7, #(0xf << 24)
+ orr r7, #(0x3 << 24)
+ str r7, [r10, #SCG_RCCR]
+
+ /* turn off SPLL and SPFD */
+ ldr r7, [r10, #SCG_SPLLPFD]
+ mov r8, r7
+ orr r7, r7, #(0x1 << 31)
+ orr r7, r7, #(0x1 << 23)
+ orr r7, r7, #(0x1 << 15)
+ orr r7, r7, #(0x1 << 7)
+ str r7, [r10, #SCG_SPLLPFD]
+
+ ldr r7, [r10, #SCG_SPLLCSR]
+ bic r7, r7, #0x1
+ str r7, [r10, #SCG_SPLLCSR]
+
+ /* turn off APLL and APFD */
+ ldr r7, [r10, #SCG_APLLPFD]
+ mov r9, r7
+ orr r7, r7, #(0x1 << 31)
+ orr r7, r7, #(0x1 << 23)
+ orr r7, r7, #(0x1 << 15)
+ orr r7, r7, #(0x1 << 7)
+ str r7, [r10, #SCG_APLLPFD]
+
+ ldr r7, [r10, #SCG_APLLCSR]
+ bic r7, r7, #0x1
+ str r7, [r10, #SCG_APLLCSR]
+
+ /* Zzz, enter stop mode */
+ wfi
+ nop
+ nop
+ nop
+ nop
+
+ /* clear core0's entry and parameter */
+ ldr r10, [r0, #PM_INFO_PM_INFO_SIM_VBASE_OFFSET]
+ mov r7, #0x0
+ str r7, [r10, #DGO_GPR3]
+ str r7, [r10, #DGO_GPR4]
+
+ /* enable SPLL and SPFD */
+ ldr r10, [r0, #PM_INFO_PM_INFO_SCG1_VBASE_OFFSET]
+ ldr r7, [r10, #SCG_SPLLCSR]
+ orr r7, r7, #1
+ str r7, [r10, #SCG_SPLLCSR]
+wait_spll:
+ ldr r7, [r10, #SCG_SPLLCSR]
+ ands r7, r7, #(1 << 24)
+ beq wait_spll
+
+ str r8, [r10, #SCG_SPLLPFD]
+ /* switch RUN clock to SPLL */
+ ldr r7, [r10, #SCG_RCCR]
+ bic r7, #(0xf << 24)
+ orr r7, #(0x6 << 24)
+ str r7, [r10, #SCG_RCCR]
+
+ /* enable APLL and APFD */
+ ldr r7, [r10, #SCG_APLLCSR]
+ orr r7, r7, #1
+ str r7, [r10, #SCG_APLLCSR]
+wait_apll:
+ ldr r7, [r10, #SCG_APLLCSR]
+ ands r7, r7, #(1 << 24)
+ beq wait_apll
+
+ str r9, [r10, #SCG_APLLPFD]
+
+ /* switch NIC clock to DDR */
+ ldr r7, [r10, #SCG_NICCCR]
+ orr r7, #(1 << 28)
+ str r7, [r10, #SCG_NICCCR]
+
+ /* let mmdc io out of lpm */
+ ldr r11, [r0, #PM_INFO_PM_INFO_MMDC_IO_VBASE_OFFSET]
+ ldr r10, [r0, #PM_INFO_MMDC_IO_NUM_OFFSET]
+ ldr r7, =PM_INFO_MMDC_IO_VAL_OFFSET
+ add r7, r7, r0
+mmdc_io_exit_lpm:
+ ldr r8, [r7], #0x4
+ ldr r9, [r7], #0x4
+ str r9, [r11, r8]
+ subs r10, r10, #0x1
+ bne mmdc_io_exit_lpm
+
+ /* let DDR out of self-refresh */
+ ldr r11, [r0, #PM_INFO_PM_INFO_MMDC_VBASE_OFFSET]
+ ldr r7, [r11, #MX7ULP_MMDC_MAPSR]
+ bic r7, r7, #(1 << 20)
+ str r7, [r11, #MX7ULP_MMDC_MAPSR]
+poll_dvfs_clear:
+ ldr r7, [r11, #MX7ULP_MMDC_MAPSR]
+ ands r7, r7, #(1 << 24)
+ bne poll_dvfs_clear
+
+ /* enable DDR auto power saving */
+ ldr r7, [r11, #MX7ULP_MMDC_MAPSR]
+ bic r7, r7, #0x1
+ str r7, [r11, #MX7ULP_MMDC_MAPSR]
+
+ restore_ttbr1
+ pop {r4-r12}
+ /* return to suspend finish */
+ mov pc, lr
+
+resume:
+ /* invalidate L1 I-cache first */
+ mov r6, #0x0
+ mcr p15, 0, r6, c7, c5, 0
+ mcr p15, 0, r6, c7, c5, 6
+ /* enable the Icache and branch prediction */
+ mov r6, #0x1800
+ mcr p15, 0, r6, c1, c0, 0
+ isb
+
+ ldr r6, =MX7ULP_SIM_BASE_ADDR
+ ldr r0, [r6, #DGO_GPR4]
+ /* get physical resume address from pm_info. */
+ ldr lr, [r0, #PM_INFO_RESUME_ADDR_OFFSET]
+
+ ldr r11, =MX7ULP_SCG1_BASE_ADDR
+ /* enable spll and pfd0 */
+ ldr r5, =PM_INFO_PM_INFO_SCG1_VAL_OFFSET
+ add r6, r5, #48
+ ldr r7, [r0, r6]
+ str r7, [r11, #SCG_SPLLCFG]
+
+ add r6, r5, #56
+ ldr r7, [r0, r6]
+ str r7, [r11, #SCG_SPLLNUM]
+
+ add r6, r5, #60
+ ldr r7, [r0, r6]
+ str r7, [r11, #SCG_SPLLDENOM]
+
+ add r6, r5, #40
+ ldr r7, [r0, r6]
+ str r7, [r11, #SCG_SPLLCSR]
+5:
+ ldr r7, [r11, #SCG_SPLLCSR]
+ ands r7, r7, #0x1000000
+ beq 5b
+
+ add r6, r5, #44
+ ldr r7, [r0, r6]
+ str r7, [r11, #SCG_SPLLDIV]
+
+ add r6, r5, #52
+ ldr r7, [r0, r6]
+ str r7, [r11, #SCG_SPLLPFD]
+
+ add r6, r5, #0
+ ldr r7, [r0, r6]
+ str r7, [r11, #SCG_RCCR]
+
+ /* enable apll and pfd0 */
+ add r6, r5, #24
+ ldr r7, [r0, r6]
+ str r7, [r11, #SCG_APLLCFG]
+
+ add r6, r5, #32
+ ldr r7, [r0, r6]
+ str r7, [r11, #SCG_APLLNUM]
+
+ add r6, r5, #36
+ ldr r7, [r0, r6]
+ str r7, [r11, #SCG_APLLDENOM]
+
+ add r6, r5, #16
+ ldr r7, [r0, r6]
+ str r7, [r11, #SCG_APLLCSR]
+6:
+ ldr r7, [r11, #SCG_APLLCSR]
+ ands r7, r7, #0x1000000
+ beq 6b
+
+ add r6, r5, #20
+ ldr r7, [r0, r6]
+ str r7, [r11, #SCG_APLLDIV]
+
+ add r6, r5, #28
+ ldr r7, [r0, r6]
+ str r7, [r11, #SCG_APLLPFD]
+
+ /* set ddr ccr */
+ add r6, r5, #4
+ ldr r7, [r0, r6]
+ str r7, [r11, #SCG_DDRCCR]
+
+ /* set nic sel */
+ add r6, r5, #8
+ ldr r7, [r0, r6]
+ str r7, [r11, #SCG_NICCCR]
+
+ /* set firc div2 to get 48MHz */
+ add r6, r5, #12
+ ldr r7, [r0, r6]
+ str r7, [r11, #SCG_FIRCDIV]
+
+ /* restore system OSC div */
+ add r6, r5, #64
+ ldr r7, [r0, r6]
+ str r7, [r11, #SCG_SOSCDIV]
+
+ /* enable mmdc clock in pcc3 */
+ ldr r11, =MX7ULP_PCC3_BASE_ADDR
+ ldr r7, [r11, #0xac]
+ orr r7, r7, #(1 << 30)
+ str r7, [r11, #0xac]
+
+ /* enable GPIO clock in pcc2 */
+ ldr r11, =MX7ULP_PCC2_BASE_ADDR
+ ldr r7, [r11, #0x3c]
+ orr r7, r7, #(1 << 30)
+ str r7, [r11, #0x3c]
+
+ /* restore gpio settings */
+ ldr r10, =MX7ULP_GPIOC_BASE_ADDR
+ ldr r7, =PM_INFO_MX7ULP_GPIO_REG_OFFSET
+ add r7, r7, r0
+ ldr r6, =GPIO_PORT_NUM
+12:
+ ldr r9, [r7], #0x4
+ str r9, [r10, #GPIO_PDOR]
+ ldr r9, [r7], #0x4
+ str r9, [r10, #GPIO_PDDR]
+ add r10, r10, #GPIO_PORT_OFFSET
+ subs r6, r6, #0x1
+ bne 12b
+
+ /* restore iomuxc settings */
+ ldr r10, =MX7ULP_IOMUXC1_BASE_ADDR
+ add r10, r10, #IOMUX_OFFSET
+ ldr r6, [r0, #PM_INFO_IOMUX_NUM_OFFSET]
+ ldr r7, =PM_INFO_IOMUX_VAL_OFFSET
+ add r7, r7, r0
+13:
+ ldr r9, [r7], #0x4
+ str r9, [r10], #0x4
+ subs r6, r6, #0x1
+ bne 13b
+
+ /* restore select input settings */
+ ldr r10, =MX7ULP_IOMUXC1_BASE_ADDR
+ add r10, r10, #SELECT_INPUT_OFFSET
+ ldr r6, [r0, #PM_INFO_SELECT_INPUT_NUM_OFFSET]
+ ldr r7, =PM_INFO_SELECT_INPUT_VAL_OFFSET
+ add r7, r7, r0
+14:
+ ldr r9, [r7], #0x4
+ str r9, [r10], #0x4
+ subs r6, r6, #0x1
+ bne 14b
+
+ /* isoack */
+ ldr r6, =MX7ULP_PMC1_BASE_ADDR
+ ldr r7, [r6, #PMC1_CTRL]
+ orr r7, r7, #(1 << 14)
+ str r7, [r6, #PMC1_CTRL]
+
+ restore_mmdc_settings
+
+ mov pc, lr
+ENDPROC(imx7ulp_suspend)
+
+ENTRY(imx7ulp_cpu_resume)
+ bl v7_invalidate_l1
+ b cpu_resume
+ENDPROC(imx7ulp_cpu_resume)
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
index 50e0b45a22db..95dc7300b2ac 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -719,7 +719,7 @@ config ARM_VIRT_EXT
details.
config SWP_EMULATE
- bool "Emulate SWP/SWPB instructions" if !SMP
+ bool "Emulate SWP/SWPB instructions"
depends on CPU_V7
default y if SMP
select HAVE_PROC_CPU if PROC_FS
diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c
index 808efbb89b88..6bd9c658a8c6 100644
--- a/arch/arm/mm/cache-l2x0.c
+++ b/arch/arm/mm/cache-l2x0.c
@@ -50,7 +50,6 @@ struct l2c_init_data {
static void __iomem *l2x0_base;
static const struct l2c_init_data *l2x0_data;
-static DEFINE_RAW_SPINLOCK(l2x0_lock);
static u32 l2x0_way_mask; /* Bitmask of active ways */
static u32 l2x0_size;
static unsigned long sync_reg_offset = L2X0_CACHE_SYNC;
@@ -60,6 +59,102 @@ struct l2x0_regs l2x0_saved_regs;
static bool l2x0_bresp_disable;
static bool l2x0_flz_disable;
+#ifdef CONFIG_OPTEE
+
+#ifndef CONFIG_SMP
+/*
+ * Redefine the arch_writelock/unlock functions not present
+ * in NO SMP mode
+ */
+#define arch_write_lock(lock) raw_spin_lock(lock)
+#define arch_write_unlock(lock) raw_spin_unlock(lock)
+#endif
+
+struct l2x0_mutex {
+ arch_rwlock_t *mutex;
+ arch_rwlock_t nomutex;
+};
+
+static struct l2x0_mutex l2x0_lock;
+
+
+#define l2x0_spin_lock(lock, flags) \
+ do { \
+ flags = local_lock(lock); \
+ } while (0)
+
+#define l2x0_spin_unlock(lock, flags) local_unlock(lock, flags)
+
+#define l2x0_spin_lock_init(lock) spinlock_init(lock)
+
+
+static void spinlock_init(struct l2x0_mutex *spinlock)
+{
+ spinlock->mutex = NULL;
+#ifdef CONFIG_SMP
+ spinlock->nomutex.lock = 0;
+#endif
+}
+
+static unsigned long local_lock(struct l2x0_mutex *spinlock)
+{
+ unsigned long flags;
+ arch_rwlock_t *lock = spinlock->mutex;
+
+ if (!lock)
+ lock = &spinlock->nomutex;
+
+ local_irq_save(flags);
+ preempt_disable();
+ arch_write_lock(lock);
+
+ return flags;
+}
+
+static void local_unlock(struct l2x0_mutex *spinlock, unsigned long flags)
+{
+ arch_rwlock_t *lock = spinlock->mutex;
+
+ if (!lock)
+ lock = &spinlock->nomutex;
+
+ arch_write_unlock(lock);
+ local_irq_restore(flags);
+ preempt_enable();
+}
+
+static int l2c_set_mutex(void *mutex)
+{
+ unsigned long flags;
+
+ if (l2x0_lock.mutex != NULL)
+ return -EINVAL;
+
+ /* Ensure the no mutex is released */
+ l2x0_spin_lock(&l2x0_lock, flags);
+ l2x0_lock.mutex = mutex;
+
+ arch_write_unlock(&l2x0_lock.nomutex);
+ local_irq_restore(flags);
+ preempt_enable();
+
+ return 0;
+}
+
+#else
+static DEFINE_RAW_SPINLOCK(l2x0_lock);
+
+#define l2x0_spin_lock(lock, flags) raw_spin_lock_irqsave(lock, flags)
+#define l2x0_spin_unlock(lock, flags) raw_spin_unlock_irqrestore(lock, flags)
+
+#define l2x0_spin_lock_init(lock)
+static int l2c_set_mutex(void *mutex)
+{
+ return -EINVAL;
+}
+
+#endif
+
/*
* Common code for all cache controllers.
*/
@@ -287,17 +382,15 @@ static void l2c220_op_way(void __iomem *base, unsigned reg)
{
unsigned long flags;
- raw_spin_lock_irqsave(&l2x0_lock, flags);
+ l2x0_spin_lock(&l2x0_lock, flags);
__l2c_op_way(base + reg);
__l2c220_cache_sync(base);
- raw_spin_unlock_irqrestore(&l2x0_lock, flags);
+ l2x0_spin_unlock(&l2x0_lock, flags);
}
static unsigned long l2c220_op_pa_range(void __iomem *reg, unsigned long start,
unsigned long end, unsigned long flags)
{
- raw_spinlock_t *lock = &l2x0_lock;
-
while (start < end) {
unsigned long blk_end = start + min(end - start, 4096UL);
@@ -308,8 +401,8 @@ static unsigned long l2c220_op_pa_range(void __iomem *reg, unsigned long start,
}
if (blk_end < end) {
- raw_spin_unlock_irqrestore(lock, flags);
- raw_spin_lock_irqsave(lock, flags);
+ l2x0_spin_unlock(&l2x0_lock, flags);
+ l2x0_spin_lock(&l2x0_lock, flags);
}
}
@@ -321,7 +414,7 @@ static void l2c220_inv_range(unsigned long start, unsigned long end)
void __iomem *base = l2x0_base;
unsigned long flags;
- raw_spin_lock_irqsave(&l2x0_lock, flags);
+ l2x0_spin_lock(&l2x0_lock, flags);
if ((start | end) & (CACHE_LINE_SIZE - 1)) {
if (start & (CACHE_LINE_SIZE - 1)) {
start &= ~(CACHE_LINE_SIZE - 1);
@@ -340,7 +433,7 @@ static void l2c220_inv_range(unsigned long start, unsigned long end)
start, end, flags);
l2c_wait_mask(base + L2X0_INV_LINE_PA, 1);
__l2c220_cache_sync(base);
- raw_spin_unlock_irqrestore(&l2x0_lock, flags);
+ l2x0_spin_unlock(&l2x0_lock, flags);
}
static void l2c220_clean_range(unsigned long start, unsigned long end)
@@ -354,12 +447,12 @@ static void l2c220_clean_range(unsigned long start, unsigned long end)
return;
}
- raw_spin_lock_irqsave(&l2x0_lock, flags);
+ l2x0_spin_lock(&l2x0_lock, flags);
flags = l2c220_op_pa_range(base + L2X0_CLEAN_LINE_PA,
start, end, flags);
l2c_wait_mask(base + L2X0_CLEAN_INV_LINE_PA, 1);
__l2c220_cache_sync(base);
- raw_spin_unlock_irqrestore(&l2x0_lock, flags);
+ l2x0_spin_unlock(&l2x0_lock, flags);
}
static void l2c220_flush_range(unsigned long start, unsigned long end)
@@ -373,12 +466,12 @@ static void l2c220_flush_range(unsigned long start, unsigned long end)
return;
}
- raw_spin_lock_irqsave(&l2x0_lock, flags);
+ l2x0_spin_lock(&l2x0_lock, flags);
flags = l2c220_op_pa_range(base + L2X0_CLEAN_INV_LINE_PA,
start, end, flags);
l2c_wait_mask(base + L2X0_CLEAN_INV_LINE_PA, 1);
__l2c220_cache_sync(base);
- raw_spin_unlock_irqrestore(&l2x0_lock, flags);
+ l2x0_spin_unlock(&l2x0_lock, flags);
}
static void l2c220_flush_all(void)
@@ -390,9 +483,9 @@ static void l2c220_sync(void)
{
unsigned long flags;
- raw_spin_lock_irqsave(&l2x0_lock, flags);
+ l2x0_spin_lock(&l2x0_lock, flags);
__l2c220_cache_sync(l2x0_base);
- raw_spin_unlock_irqrestore(&l2x0_lock, flags);
+ l2x0_spin_unlock(&l2x0_lock, flags);
}
static void l2c220_enable(void __iomem *base, unsigned num_lock)
@@ -484,7 +577,7 @@ static void l2c310_inv_range_erratum(unsigned long start, unsigned long end)
unsigned long flags;
/* Erratum 588369 for both clean+invalidate operations */
- raw_spin_lock_irqsave(&l2x0_lock, flags);
+ l2x0_spin_lock(&l2x0_lock, flags);
l2c_set_debug(base, 0x03);
if (start & (CACHE_LINE_SIZE - 1)) {
@@ -501,7 +594,7 @@ static void l2c310_inv_range_erratum(unsigned long start, unsigned long end)
}
l2c_set_debug(base, 0x00);
- raw_spin_unlock_irqrestore(&l2x0_lock, flags);
+ l2x0_spin_unlock(&l2x0_lock, flags);
}
__l2c210_op_pa_range(base + L2X0_INV_LINE_PA, start, end);
@@ -510,11 +603,10 @@ static void l2c310_inv_range_erratum(unsigned long start, unsigned long end)
static void l2c310_flush_range_erratum(unsigned long start, unsigned long end)
{
- raw_spinlock_t *lock = &l2x0_lock;
unsigned long flags;
void __iomem *base = l2x0_base;
- raw_spin_lock_irqsave(lock, flags);
+ l2x0_spin_lock(&l2x0_lock, flags);
while (start < end) {
unsigned long blk_end = start + min(end - start, 4096UL);
@@ -527,11 +619,11 @@ static void l2c310_flush_range_erratum(unsigned long start, unsigned long end)
l2c_set_debug(base, 0x00);
if (blk_end < end) {
- raw_spin_unlock_irqrestore(lock, flags);
- raw_spin_lock_irqsave(lock, flags);
+ l2x0_spin_unlock(&l2x0_lock, flags);
+ l2x0_spin_lock(&l2x0_lock, flags);
}
}
- raw_spin_unlock_irqrestore(lock, flags);
+ l2x0_spin_unlock(&l2x0_lock, flags);
__l2c210_cache_sync(base);
}
@@ -540,12 +632,12 @@ static void l2c310_flush_all_erratum(void)
void __iomem *base = l2x0_base;
unsigned long flags;
- raw_spin_lock_irqsave(&l2x0_lock, flags);
+ l2x0_spin_lock(&l2x0_lock, flags);
l2c_set_debug(base, 0x03);
__l2c_op_way(base + L2X0_CLEAN_INV_WAY);
l2c_set_debug(base, 0x00);
__l2c210_cache_sync(base);
- raw_spin_unlock_irqrestore(&l2x0_lock, flags);
+ l2x0_spin_unlock(&l2x0_lock, flags);
}
static void __init l2c310_save(void __iomem *base)
@@ -871,6 +963,10 @@ static int __init __l2c_init(const struct l2c_init_data *data,
fns.sync = NULL;
}
+#ifdef CONFIG_OPTEE
+ fns.set_mutex = l2c_set_mutex;
+#endif
+
/*
* Check if l2x0 controller is already enabled. If we are booting
* in non-secure mode accessing the below registers will fault.
@@ -879,6 +975,11 @@ static int __init __l2c_init(const struct l2c_init_data *data,
l2x0_saved_regs.aux_ctrl = aux;
data->enable(l2x0_base, data->num_lock);
+ } else {
+ pr_info("%s cache controller enabled try to unlock\n",
+ data->type);
+
+ data->unlock(l2x0_base, data->num_lock);
}
outer_cache = fns;
@@ -1395,10 +1496,10 @@ static void aurora_pa_range(unsigned long start, unsigned long end,
while (start < end) {
range_end = aurora_range_end(start, end);
- raw_spin_lock_irqsave(&l2x0_lock, flags);
+ l2x0_spin_lock(&l2x0_lock, flags);
writel_relaxed(start, base + AURORA_RANGE_BASE_ADDR_REG);
writel_relaxed(range_end - CACHE_LINE_SIZE, base + offset);
- raw_spin_unlock_irqrestore(&l2x0_lock, flags);
+ l2x0_spin_unlock(&l2x0_lock, flags);
writel_relaxed(0, base + AURORA_SYNC_REG);
start = range_end;
@@ -1433,9 +1534,9 @@ static void aurora_flush_all(void)
unsigned long flags;
/* clean all ways */
- raw_spin_lock_irqsave(&l2x0_lock, flags);
+ l2x0_spin_lock(&l2x0_lock, flags);
__l2c_op_way(base + L2X0_CLEAN_INV_WAY);
- raw_spin_unlock_irqrestore(&l2x0_lock, flags);
+ l2x0_spin_unlock(&l2x0_lock, flags);
writel_relaxed(0, base + AURORA_SYNC_REG);
}
@@ -1450,12 +1551,12 @@ static void aurora_disable(void)
void __iomem *base = l2x0_base;
unsigned long flags;
- raw_spin_lock_irqsave(&l2x0_lock, flags);
+ l2x0_spin_lock(&l2x0_lock, flags);
__l2c_op_way(base + L2X0_CLEAN_INV_WAY);
writel_relaxed(0, base + AURORA_SYNC_REG);
l2c_write_sec(0, base, L2X0_CTRL);
dsb(st);
- raw_spin_unlock_irqrestore(&l2x0_lock, flags);
+ l2x0_spin_unlock(&l2x0_lock, flags);
}
static void aurora_save(void __iomem *base)
@@ -1812,6 +1913,8 @@ int __init l2x0_of_init(u32 aux_val, u32 aux_mask)
else
cache_id = readl_relaxed(l2x0_base + L2X0_CACHE_ID);
+ l2x0_spin_lock_init(&l2x0_lock);
+
return __l2c_init(data, aux_val, aux_mask, cache_id, nosync);
}
#endif
diff --git a/arch/arm/mm/cache-v7.S b/arch/arm/mm/cache-v7.S
index 50a70edbc863..4aca71c8fc34 100644
--- a/arch/arm/mm/cache-v7.S
+++ b/arch/arm/mm/cache-v7.S
@@ -162,6 +162,9 @@ loop2:
skip:
add r10, r10, #2 @ increment cache number
cmp r3, r10
+#ifdef CONFIG_ARM_ERRATA_814220
+ dsb
+#endif
bgt flush_levels
finished:
mov r10, #0 @ switch back to cache level 0
diff --git a/arch/arm/mm/proc-syms.c b/arch/arm/mm/proc-syms.c
index 054b491ff764..872b1ff7ff11 100644
--- a/arch/arm/mm/proc-syms.c
+++ b/arch/arm/mm/proc-syms.c
@@ -14,6 +14,7 @@
#include <asm/proc-fns.h>
#include <asm/tlbflush.h>
#include <asm/page.h>
+#include "dma.h"
#ifndef MULTI_CPU
EXPORT_SYMBOL(cpu_dcache_clean_area);
@@ -30,6 +31,9 @@ EXPORT_SYMBOL(__cpuc_flush_user_all);
EXPORT_SYMBOL(__cpuc_flush_user_range);
EXPORT_SYMBOL(__cpuc_coherent_kern_range);
EXPORT_SYMBOL(__cpuc_flush_dcache_area);
+EXPORT_SYMBOL(__glue(_CACHE,_dma_map_area));
+EXPORT_SYMBOL(__glue(_CACHE,_dma_unmap_area));
+EXPORT_SYMBOL(__glue(_CACHE,_dma_flush_range));
#else
EXPORT_SYMBOL(cpu_cache);
#endif
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index e296ae3e20f4..5b0dbfcf317b 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -801,6 +801,7 @@ config FORCE_MAX_ZONEORDER
int
default "14" if (ARM64_64K_PAGES && TRANSPARENT_HUGEPAGE)
default "12" if (ARM64_16K_PAGES && TRANSPARENT_HUGEPAGE)
+ default "14" if (ARCH_FSL_IMX8QM || ARCH_FSL_IMX8QXP || ARCH_FSL_IMX8MQ || ARCH_FSL_IMX8QP)
default "11"
help
The kernel memory allocator divides physically contiguous memory
diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms
index 456d21542250..2d944087e10a 100644
--- a/arch/arm64/Kconfig.platforms
+++ b/arch/arm64/Kconfig.platforms
@@ -266,4 +266,64 @@ config ARCH_ZYNQMP
help
This enables support for Xilinx ZynqMP Family
+config ARCH_FSL_IMX8QM
+ bool "Freescale i.MX8QM SOC"
+ select PINCTRL
+ select PINCTRL_IMX
+ select PINCTRL_IMX8QM
+ select PM
+ select SOC_BUS
+ select GPIO_MXC_PAD_WAKEUP
+ help
+ This enables support for Freescale i.MX8QM SOC.
+
+config ARCH_FSL_IMX8QP
+ bool "Freescale i.MX8QP SOC"
+ select PINCTRL
+ select PINCTRL_IMX
+ select PINCTRL_IMX8QM
+ select PM
+ select SOC_BUS
+ select GPIO_MXC_PAD_WAKEUP
+ help
+ This enables support for Freescale i.MX8QP SOC.
+
+
+config ARCH_FSL_IMX8QXP
+ bool "Freescale i.MX8QXP SOC"
+ select PINCTRL
+ select PINCTRL_IMX
+ select PINCTRL_IMX8QXP
+ select PM
+ select SOC_BUS
+ select GPIO_MXC_PAD_WAKEUP
+ help
+ This enables support for Freescale i.MX8QXP SOC.
+
+config ARCH_FSL_IMX8MQ
+ bool "Freescale i.MX8MQ SOC"
+ select ARCH_MXC
+ select SERIAL_IMX
+ select PINCTRL
+ select PINCTRL_IMX
+ select PINCTRL_IMX8MQ
+ select PM
+ select SOC_BUS
+ select KEYBOARD_SNVS_PWRKEY
+ help
+ This enables support for Freescale i.MX8MQ SOC.
+
+config ARCH_FSL_IMX8MM
+ bool "Freescale i.MX8MM SOC"
+ select ARCH_MXC
+ select SERIAL_IMX
+ select PINCTRL
+ select PINCTRL_IMX
+ select PINCTRL_IMX8MM
+ select PM
+ select SOC_BUS
+ select KEYBOARD_SNVS_PWRKEY
+ help
+ This enables support for Freescale i.MX8MM SOC.
+
endmenu
diff --git a/arch/arm64/boot/dts/freescale/Makefile b/arch/arm64/boot/dts/freescale/Makefile
index dc02e82aba7c..da7ede2f5744 100644
--- a/arch/arm64/boot/dts/freescale/Makefile
+++ b/arch/arm64/boot/dts/freescale/Makefile
@@ -14,6 +14,123 @@ dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls2080a-simu.dtb
dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls2088a-qds.dtb
dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls2088a-rdb.dtb
+dtb-$(CONFIG_ARCH_FSL_IMX8QM) += fsl-imx8qm-lpddr4-arm2.dtb \
+ fsl-imx8qm-lpddr4-arm2-dom0.dtb \
+ fsl-imx8qm-lpddr4-arm2-domu.dtb \
+ fsl-imx8qm-ddr4-arm2.dtb \
+ fsl-imx8qm-ddr4-arm2-hdmi.dtb \
+ fsl-imx8qm-lpddr4-arm2_ca53.dtb \
+ fsl-imx8qm-lpddr4-arm2_ca72.dtb \
+ fsl-imx8qm-mek.dtb \
+ fsl-imx8qm-mek-rpmsg.dtb \
+ fsl-imx8qm-mek-dsp.dtb \
+ fsl-imx8qm-mek-ov5640.dtb \
+ fsl-imx8qm-mek_ca53.dtb \
+ fsl-imx8qm-mek_ca72.dtb \
+ fsl-imx8qm-mek-hdmi.dtb \
+ fsl-imx8qm-mek-hdmi-in.dtb \
+ fsl-imx8qm-mek-dsi-rm67191.dtb \
+ fsl-imx8qm-mek-enet2-tja1100.dtb \
+ fsl-imx8qm-mek-jdi-wuxga-lvds1-panel.dtb \
+ fsl-imx8qm-mek-dom0.dtb \
+ fsl-imx8qm-mek-dom0-dpu2.dtb \
+ fsl-imx8qm-mek-domu.dtb \
+ fsl-imx8qm-mek-domu-car.dtb \
+ fsl-imx8qm-mek-domu-dpu1.dtb \
+ fsl-imx8qm-mek-domu-dpu1-hdmi.dtb \
+ fsl-imx8qm-mek-root.dtb \
+ fsl-imx8qm-mek-inmate.dtb \
+ fsl-imx8qm-lpddr4-arm2-dp.dtb \
+ fsl-imx8qm-lpddr4-arm2-hdmi.dtb \
+ fsl-imx8qm-lpddr4-arm2-hdmi-in.dtb \
+ fsl-imx8qm-lpddr4-arm2-8cam.dtb \
+ fsl-imx8qm-lpddr4-arm2-it6263-dual-channel.dtb \
+ fsl-imx8qm-lpddr4-arm2-jdi-wuxga-lvds1-panel.dtb \
+ fsl-imx8qm-lpddr4-arm2-lpspi.dtb \
+ fsl-imx8qm-lpddr4-arm2-lpspi-slave.dtb \
+ fsl-imx8qm-lpddr4-arm2-spdif.dtb \
+ fsl-imx8qm-lpddr4-arm2-mqs.dtb \
+ fsl-imx8qm-lpddr4-arm2-usb3.dtb \
+ fsl-imx8qm-lpddr4-arm2-dsi-rm67191.dtb \
+ fsl-imx8qm-lpddr4-arm2-enet2-tja1100.dtb \
+ fsl-imx8qm-lpddr4-arm2-hsic.dtb \
+ fsl-imx8dm-lpddr4-arm2.dtb \
+ fsl-imx8qp-lpddr4-arm2.dtb \
+ fsl-imx8qm-lpddr4-arm2-dp-dig-pll.dtb
+dtb-$(CONFIG_ARCH_FSL_IMX8QXP) += fsl-imx8qxp-lpddr4-arm2.dtb \
+ fsl-imx8qxp-mek.dtb \
+ fsl-imx8qxp-mek-rpmsg.dtb \
+ fsl-imx8qxp-mek-dsp.dtb \
+ fsl-imx8qxp-mek-dom0.dtb \
+ fsl-imx8qxp-mek-ov5640.dtb \
+ fsl-imx8qxp-mek-ov5640-rpmsg.dtb \
+ fsl-imx8qxp-mek-enet2.dtb \
+ fsl-imx8qxp-mek-enet2-tja1100.dtb \
+ fsl-imx8qxp-mek-dsi-rm67191.dtb \
+ fsl-imx8qxp-mek-a0.dtb \
+ fsl-imx8qxp-mek-lcdif.dtb \
+ fsl-imx8qxp-mek-it6263-lvds0-dual-channel.dtb \
+ fsl-imx8qxp-mek-it6263-lvds1-dual-channel.dtb \
+ fsl-imx8qxp-mek-jdi-wuxga-lvds0-panel.dtb \
+ fsl-imx8qxp-mek-jdi-wuxga-lvds1-panel.dtb \
+ fsl-imx8qxp-mek-root.dtb \
+ fsl-imx8qxp-mek-inmate.dtb \
+ fsl-imx8qxp-lpddr4-arm2-enet2.dtb \
+ fsl-imx8qxp-lpddr4-arm2-enet2-tja1100.dtb \
+ fsl-imx8qxp-lpddr4-arm2-gpmi-nand.dtb \
+ fsl-imx8qxp-lpddr4-arm2-lpspi.dtb \
+ fsl-imx8qxp-lpddr4-arm2-lpspi-slave.dtb \
+ fsl-imx8qxp-lpddr4-arm2-spdif.dtb \
+ fsl-imx8qxp-lpddr4-arm2-mlb.dtb \
+ fsl-imx8qxp-lpddr4-arm2-mqs.dtb \
+ fsl-imx8qxp-lpddr4-arm2-wm8962.dtb \
+ fsl-imx8qxp-lpddr4-arm2-dsp.dtb \
+ fsl-imx8qxp-lpddr4-arm2-dsi-rm67191.dtb \
+ fsl-imx8qxp-lpddr4-arm2-a0.dtb \
+ fsl-imx8qxp-17x17-val.dtb \
+ fsl-imx8qxp-ddr3l-val.dtb \
+ fsl-imx8dx-17x17-val.dtb \
+ fsl-imx8dx-lpddr4-arm2.dtb \
+ fsl-imx8dxp-lpddr4-arm2.dtb
+dtb-$(CONFIG_ARCH_FSL_IMX8MQ) += fsl-imx8mq-ddr3l-arm2.dtb \
+ fsl-imx8mq-ddr4-arm2.dtb \
+ fsl-imx8mq-ddr4-arm2-gpmi-nand.dtb \
+ fsl-imx8mq-evk.dtb \
+ fsl-imx8mq-evk-b3.dtb \
+ fsl-imx8mq-evk-m4.dtb \
+ fsl-imx8mq-evk-pcie1-m2.dtb \
+ fsl-imx8mq-evk-lcdif-adv7535.dtb \
+ fsl-imx8mq-evk-lcdif-adv7535-b3.dtb \
+ fsl-imx8mq-evk-mipi-csi2.dtb \
+ fsl-imx8mq-evk-pdm.dtb \
+ fsl-imx8mq-evk-dcss-adv7535.dtb \
+ fsl-imx8mq-evk-dcss-adv7535-b3.dtb \
+ fsl-imx8mq-evk-dcss-rm67191.dtb \
+ fsl-imx8mq-evk-dcss-rm67191-b3.dtb \
+ fsl-imx8mq-evk-dual-display.dtb \
+ fsl-imx8mq-evk-dual-display-b3.dtb \
+ fsl-imx8mq-evk-ak4497.dtb \
+ fsl-imx8mq-evk-audio-tdm.dtb \
+ fsl-imx8mq-evk-drm.dtb \
+ fsl-imx8mq-evk-root.dtb \
+ fsl-imx8mq-evk-inmate.dtb \
+ fsl-imx8mq-evk-dp.dtb \
+ fsl-imx8mq-evk-edp.dtb
+dtb-$(CONFIG_ARCH_FSL_IMX8MM) += fsl-imx8mm-evk.dtb \
+ fsl-imx8mm-evk-ak4497.dtb \
+ fsl-imx8mm-evk-m4.dtb \
+ fsl-imx8mm-evk-ak5558.dtb \
+ fsl-imx8mm-evk-audio-tdm.dtb \
+ fsl-imx8mm-ddr3l-val.dtb \
+ fsl-imx8mm-ddr4-evk.dtb \
+ fsl-imx8mm-ddr4-val.dtb \
+ fsl-imx8mm-evk-rm67191.dtb \
+ fsl-imx8mm-evk-root.dtb \
+ fsl-imx8mm-evk-inmate.dtb \
+ fsl-imx8mm-evk-revb.dtb \
+ fsl-imx8mm-evk-revb-rm67191.dtb \
+ fsl-imx8mm-ddr4-evk-rm67191.dtb \
+ fsl-imx8mm-ddr4-qca9377-evk.dtb
always := $(dtb-y)
subdir-y := $(dts-dirs)
clean-files := *.dtb
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8-ca35.dtsi b/arch/arm64/boot/dts/freescale/fsl-imx8-ca35.dtsi
new file mode 100644
index 000000000000..2a2f155027c6
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8-ca35.dtsi
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017 NXP
+ *
+ * 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 <dt-bindings/clock/imx8qxp-clock.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+/{
+ cpus {
+ #address-cells = <2>;
+ #size-cells = <0>;
+
+ /* We have 1 clusters having 4 Cortex-A35 cores */
+ A35_0: cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a35";
+ reg = <0x0 0x0>;
+ enable-method = "psci";
+ next-level-cache = <&A35_L2>;
+ };
+
+ A35_1: cpu@1 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a35";
+ reg = <0x0 0x1>;
+ enable-method = "psci";
+ next-level-cache = <&A35_L2>;
+ };
+
+ A35_2: cpu@2 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a35";
+ reg = <0x0 0x2>;
+ enable-method = "psci";
+ next-level-cache = <&A35_L2>;
+ };
+
+ A35_3: cpu@3 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a35";
+ reg = <0x0 0x3>;
+ enable-method = "psci";
+ next-level-cache = <&A35_L2>;
+ };
+
+ A35_L2: l2-cache0 {
+ compatible = "cache";
+ };
+ };
+
+ pmu {
+ compatible = "arm,armv8-pmuv3";
+ interrupts = <GIC_PPI 7
+ (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_HIGH)>;
+ interrupt-affinity = <&A35_0>, <&A35_1>, <&A35_2>, <&A35_3>;
+ };
+
+ psci {
+ compatible = "arm,psci-1.0";
+ method = "smc";
+ cpu_suspend = <0xc4000001>;
+ cpu_off = <0xc4000002>;
+ cpu_on = <0xc4000003>;
+ };
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8-ca53.dtsi b/arch/arm64/boot/dts/freescale/fsl-imx8-ca53.dtsi
new file mode 100644
index 000000000000..7f24d09b3ad7
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8-ca53.dtsi
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017 NXP
+ *
+ * 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 <dt-bindings/interrupt-controller/arm-gic.h>
+
+/{
+ cpus {
+ #address-cells = <2>;
+ #size-cells = <0>;
+
+ idle-states {
+ entry-method = "psci";
+
+ CPU_SLEEP: cpu-sleep {
+ compatible = "arm,idle-state";
+ arm,psci-suspend-param = <0x0000000>;
+ entry-latency-us = <700>;
+ exit-latency-us = <250>;
+ min-residency-us = <1000>;
+ };
+
+ CLUSTER_SLEEP: cluster-sleep {
+ compatible = "arm,idle-state";
+ arm,psci-suspend-param = <0x1000000>;
+ entry-latency-us = <1000>;
+ exit-latency-us = <700>;
+ min-residency-us = <2700>;
+ wakeup-latency-us = <1500>;
+ };
+ };
+
+ /* We have 1 clusters having 4 Cortex-A53 cores */
+ A53_0: cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a53";
+ reg = <0x0 0x0>;
+ enable-method = "psci";
+ next-level-cache = <&A53_L2>;
+ cpu-idle-states = <&CPU_SLEEP>;
+ };
+
+ A53_1: cpu@1 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a53";
+ reg = <0x0 0x1>;
+ enable-method = "psci";
+ next-level-cache = <&A53_L2>;
+ cpu-idle-states = <&CPU_SLEEP>;
+ };
+
+ A53_2: cpu@2 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a53";
+ reg = <0x0 0x2>;
+ enable-method = "psci";
+ next-level-cache = <&A53_L2>;
+ cpu-idle-states = <&CPU_SLEEP>;
+ };
+
+ A53_3: cpu@3 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a53";
+ reg = <0x0 0x3>;
+ enable-method = "psci";
+ next-level-cache = <&A53_L2>;
+ cpu-idle-states = <&CPU_SLEEP>;
+ };
+
+ A53_L2: l2-cache0 {
+ compatible = "cache";
+ };
+ };
+
+ psci {
+ compatible = "arm,psci-1.0";
+ method = "smc";
+ cpu_suspend = <0xc4000001>;
+ cpu_off = <0xc4000002>;
+ cpu_on = <0xc4000003>;
+ };
+
+ pmu {
+ compatible = "arm,armv8-pmuv3";
+ interrupts = <GIC_PPI 7
+ (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_HIGH)>;
+ interrupt-affinity = <&A53_0>, <&A53_1>, <&A53_2>, <&A53_3>;
+ };
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8-ca72.dtsi b/arch/arm64/boot/dts/freescale/fsl-imx8-ca72.dtsi
new file mode 100644
index 000000000000..944c16002cbf
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8-ca72.dtsi
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017 NXP
+ *
+ * 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 <dt-bindings/interrupt-controller/arm-gic.h>
+/ {
+ cpus {
+ #address-cells = <2>;
+ #size-cells = <0>;
+
+ idle-states {
+ entry-method = "psci";
+
+ CPU_SLEEP: cpu-sleep {
+ compatible = "arm,idle-state";
+ arm,psci-suspend-param = <0x0000000>;
+ entry-latency-us = <700>;
+ exit-latency-us = <250>;
+ min-residency-us = <1000>;
+ };
+
+ CLUSTER_SLEEP: cluster-sleep {
+ compatible = "arm,idle-state";
+ arm,psci-suspend-param = <0x1000000>;
+ entry-latency-us = <1000>;
+ exit-latency-us = <700>;
+ min-residency-us = <2700>;
+ wakeup-latency-us = <1500>;
+ };
+ };
+
+ /* We have 2nd clusters having 2 Cortex-A72 cores */
+ A72_0: cpu@100 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a72","arm,armv8";
+ reg = <0x0 0x100>;
+ enable-method = "psci";
+ next-level-cache = <&A72_L2>;
+ cpu-idle-states = <&CPU_SLEEP>;
+ };
+
+ A72_1: cpu@101 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a72","arm,armv8";
+ reg = <0x0 0x101>;
+ enable-method = "psci";
+ next-level-cache = <&A72_L2>;
+ cpu-idle-states = <&CPU_SLEEP>;
+ };
+
+ A72_L2: l2-cache1 {
+ compatible = "cache";
+ };
+ };
+
+ pmu {
+ compatible = "arm,armv8-pmuv3";
+ interrupts = <GIC_PPI 7
+ (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_HIGH)>;
+ interrupt-affinity = <&A72_0>, <&A72_1>;
+ };
+
+ psci {
+ compatible = "arm,psci-1.0";
+ method = "smc";
+ cpu_suspend = <0xc4000001>;
+ cpu_off = <0xc4000002>;
+ cpu_on = <0xc4000003>;
+ };
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8dm-lpddr4-arm2.dts b/arch/arm64/boot/dts/freescale/fsl-imx8dm-lpddr4-arm2.dts
new file mode 100644
index 000000000000..412525fcf1b0
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8dm-lpddr4-arm2.dts
@@ -0,0 +1,109 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2018 NXP
+ *
+ * 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.
+ */
+
+/dts-v1/;
+
+#include "fsl-imx8dm.dtsi"
+
+#include "fsl-imx8q-arm2.dtsi"
+
+/ {
+ model = "Freescale i.MX8DM ARM2";
+ compatible = "fsl,imx8dm-arm2", "fsl,imx8dm", "fsl,imx8qm";
+};
+
+&gpu_3d1 {
+ status = "disabled";
+};
+
+&mipi_dsi_phy2 {
+ status = "disabled";
+};
+
+&mipi_dsi2 {
+ status = "disabled";
+};
+
+&mipi_dsi_bridge2 {
+ status = "disabled";
+};
+
+&display{
+ ports = <&dpu1_disp0>, <&dpu1_disp1>;
+};
+
+&prg10 {
+ status = "disabled";
+};
+
+&prg11 {
+ status = "disabled";
+};
+
+&prg12 {
+ status = "disabled";
+};
+
+&prg13 {
+ status = "disabled";
+};
+
+&prg14 {
+ status = "disabled";
+};
+
+&prg15 {
+ status = "disabled";
+};
+
+&prg16 {
+ status = "disabled";
+};
+
+&prg17 {
+ status = "disabled";
+};
+
+&prg18 {
+ status = "disabled";
+};
+
+&dpr3_channel1 {
+ status = "disabled";
+};
+
+&dpr3_channel2 {
+ status = "disabled";
+};
+
+&dpr3_channel3 {
+ status = "disabled";
+};
+
+&dpr4_channel1 {
+ status = "disabled";
+};
+
+&dpr4_channel2 {
+ status = "disabled";
+};
+
+&dpr4_channel3 {
+ status = "disabled";
+};
+
+&dpu2 {
+ status = "disabled";
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8dm.dtsi b/arch/arm64/boot/dts/freescale/fsl-imx8dm.dtsi
new file mode 100644
index 000000000000..eae337eb6422
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8dm.dtsi
@@ -0,0 +1,42 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2018 NXP
+ *
+ * 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 "fsl-imx8qm.dtsi"
+
+/ {
+ model = "Freescale i.MX8DM";
+ compatible = "fsl, imx8dm", "fsl,imx8qm";
+
+};
+
+&A53_0 {
+ device_type = "";
+};
+
+&A53_1 {
+ device_type = "";
+};
+
+&A53_2 {
+ device_type = "";
+};
+
+&A53_3 {
+ device_type = "";
+};
+
+&A53_L2 {
+ compatible = "";
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8dx-17x17-val.dts b/arch/arm64/boot/dts/freescale/fsl-imx8dx-17x17-val.dts
new file mode 100644
index 000000000000..f792ccb4e570
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8dx-17x17-val.dts
@@ -0,0 +1,26 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2019 NXP
+ *
+ * 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.
+ */
+
+/dts-v1/;
+
+#include "fsl-imx8dx.dtsi"
+
+#include "fsl-imx8x-17x17-val.dtsi"
+
+/ {
+ model = "Freescale i.MX8DX 17x17 Validation board";
+ compatible = "fsl,imx8dx-17x17-val", "fsl,imx8dx", "fsl,imx8qxp";
+};
+
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8dx-lpddr4-arm2.dts b/arch/arm64/boot/dts/freescale/fsl-imx8dx-lpddr4-arm2.dts
new file mode 100644
index 000000000000..23d0714087f1
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8dx-lpddr4-arm2.dts
@@ -0,0 +1,26 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2018 NXP
+ *
+ * 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.
+ */
+
+/dts-v1/;
+
+#include "fsl-imx8dx.dtsi"
+
+#include "fsl-imx8x-arm2.dtsi"
+
+/ {
+ model = "Freescale i.MX8DX ARM2";
+ compatible = "fsl,imx8dx-arm2", "fsl,imx8dx", "fsl,imx8qxp";
+};
+
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8dx.dtsi b/arch/arm64/boot/dts/freescale/fsl-imx8dx.dtsi
new file mode 100644
index 000000000000..e4ef0d0154a8
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8dx.dtsi
@@ -0,0 +1,3581 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017-2018 NXP
+ *
+ * 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 <dt-bindings/interrupt-controller/arm-gic.h>
+#include "fsl-imx8-ca35.dtsi"
+#include <dt-bindings/soc/imx_rsrc.h>
+#include <dt-bindings/soc/imx8_hsio.h>
+#include <dt-bindings/soc/imx8_pd.h>
+#include <dt-bindings/clock/imx8qxp-clock.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/pinctrl/pads-imx8qxp.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/thermal/thermal.h>
+
+/ {
+ model = "Freescale i.MX8DX";
+ compatible = "fsl,imx8dx", "fsl,imx8qxp";
+ interrupt-parent = <&gic>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ pmu {
+ interrupt-affinity = <&A35_0>, <&A35_1>;
+ };
+
+ aliases {
+ csi0 = &mipi_csi_0;
+ dpu0 = &dpu1;
+ ethernet0 = &fec1;
+ ethernet1 = &fec2;
+ dsi_phy0 = &mipi_dsi_phy1;
+ dsi_phy1 = &mipi_dsi_phy2;
+ mipi_dsi0 = &mipi_dsi1;
+ mipi_dsi1 = &mipi_dsi2;
+ ldb0 = &ldb1;
+ ldb1 = &ldb2;
+ isi0 = &isi_0;
+ isi1 = &isi_1;
+ isi2 = &isi_2;
+ isi3 = &isi_3;
+ isi4 = &isi_4;
+ isi5 = &isi_5;
+ isi6 = &isi_6;
+ isi7 = &isi_7;
+ serial0 = &lpuart0;
+ serial1 = &lpuart1;
+ serial2 = &lpuart2;
+ serial3 = &lpuart3;
+ mmc0 = &usdhc1;
+ mmc1 = &usdhc2;
+ mmc2 = &usdhc3;
+ can0 = &flexcan1;
+ can1 = &flexcan2;
+ can2 = &flexcan3;
+ i2c1 = &i2c_rpbus_1;
+ i2c5 = &i2c_rpbus_5;
+ i2c12 = &i2c_rpbus_12;
+ i2c13 = &i2c_rpbus_13;
+ i2c14 = &i2c_rpbus_14;
+ i2c15 = &i2c_rpbus_15;
+ };
+
+ cpus {
+ idle-states {
+ entry-method = "psci";
+
+ CPU_SLEEP: cpu-sleep {
+ compatible = "arm,idle-state";
+ arm,psci-suspend-param = <0x10000>;
+ local-timer-stop;
+ entry-latency-us = <500>;
+ exit-latency-us = <500>;
+ min-residency-us = <5000>;
+ };
+
+ CLUSTER_SLEEP: cluster-sleep {
+ compatible = "arm,idle-state";
+ arm,psci-suspend-param = <0x10033>;
+ local-timer-stop;
+ entry-latency-us = <500>;
+ exit-latency-us = <2300>;
+ min-residency-us = <14000>;
+ };
+ };
+ };
+
+ memory@80000000 {
+ device_type = "memory";
+ reg = <0x00000000 0x80000000 0 0x40000000>;
+ /* DRAM space - 1, size : 1 GB DRAM */
+ };
+
+ reserved-memory {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ /*
+ * reserved-memory layout
+ * 0x8800_0000 ~ 0x8FFF_FFFF is reserved for M4
+ * Shouldn't be used at A core and Linux side.
+ *
+ */
+ decoder_boot: decoder_boot@0x84000000 {
+ no-map;
+ reg = <0 0x84000000 0 0x2000000>;
+ };
+ encoder_boot: encoder_boot@0x86000000 {
+ no-map;
+ reg = <0 0x86000000 0 0x200000>;
+ };
+ rpmsg_reserved: rpmsg@0x90000000 {
+ no-map;
+ reg = <0 0x90000000 0 0x400000>;
+ };
+ rpmsg_dma_reserved:rpmsg_dma@0x90400000 {
+ compatible = "shared-dma-pool";
+ no-map;
+ reg = <0 0x90400000 0 0x1C00000>;
+ };
+ decoder_rpc: decoder_rpc@0x92000000 {
+ no-map;
+ reg = <0 0x92000000 0 0x200000>;
+ };
+ encoder_rpc: encoder_rpc@0x92200000 {
+ no-map;
+ reg = <0 0x92200000 0 0x200000>;
+ };
+ dsp_reserved: dsp@0x92400000 {
+ no-map;
+ reg = <0 0x92400000 0 0x2000000>;
+ };
+ encoder_reserved: encoder_reserved@0x94400000 {
+ no-map;
+ reg = <0 0x94400000 0 0x800000>;
+ };
+ /* global autoconfigured region for contiguous allocations */
+ linux,cma {
+ compatible = "shared-dma-pool";
+ reusable;
+ size = <0 0x3c000000>;
+ alloc-ranges = <0 0x96000000 0 0x3c000000>;
+ linux,cma-default;
+ };
+ };
+
+ gic: interrupt-controller@51a00000 {
+ compatible = "arm,gic-v3";
+ reg = <0x0 0x51a00000 0 0x10000>, /* GIC Dist */
+ <0x0 0x51b00000 0 0xC0000>; /* GICR (RD_base + SGI_base) */
+ #interrupt-cells = <3>;
+ interrupt-controller;
+ interrupts = <GIC_PPI 9
+ (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_HIGH)>;
+ interrupt-parent = <&gic>;
+ };
+
+ mu: mu@5d1c0000 {
+ compatible = "fsl,imx8-mu";
+ reg = <0x0 0x5d1c0000 0x0 0x10000>;
+ interrupts = <GIC_SPI 177 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-parent = <&gic>;
+ fsl,scu_ap_mu_id = <0>;
+ status = "okay";
+ };
+
+ mu13: mu13@5d280000 {
+ compatible = "fsl,imx8-mu-dsp";
+ reg = <0x0 0x5d280000 0x0 0x10000>;
+ interrupts = <GIC_SPI 192 IRQ_TYPE_LEVEL_HIGH>;
+ fsl,dsp_ap_mu_id = <13>;
+ status = "okay";
+ };
+
+ mu_m4: mu_m4@37440000 {
+ compatible = "fsl,imx8-mu0-vpu-m4";
+ reg = <0x0 0x37440000 0x0 0x10000>;
+ interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>;
+ fsl,vpu_ap_mu_id = <15>;
+ status = "okay";
+ };
+
+ mu_m0: mu_m0@2d000000 {
+ compatible = "fsl,imx8-mu0-vpu-m0";
+ reg = <0x0 0x2d000000 0x0 0x20000>;
+ interrupts = <GIC_SPI 469 IRQ_TYPE_LEVEL_HIGH>;
+ fsl,vpu_ap_mu_id = <16>;
+ status = "okay";
+ };
+
+ mu1_m0: mu1_m0@2d020000 {
+ compatible = "fsl,imx8-mu1-vpu-m0";
+ reg = <0x0 0x2d020000 0x0 0x20000>;
+ interrupts = <GIC_SPI 470 IRQ_TYPE_LEVEL_HIGH>;
+ fsl,vpu_ap_mu_id = <17>;
+ status = "okay";
+ };
+ clk: clk {
+ compatible = "fsl,imx8qxp-clk";
+ #clock-cells = <1>;
+ };
+
+ iomuxc: iomuxc {
+ compatible = "fsl,imx8qxp-iomuxc";
+ };
+
+ rtc: rtc {
+ compatible = "fsl,imx-sc-rtc";
+ };
+
+ timer {
+ compatible = "arm,armv8-timer";
+ interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>, /* Physical Secure */
+ <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>, /* Physical Non-Secure */
+ <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>, /* Virtual */
+ <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>; /* Hypervisor */
+ clock-frequency = <8000000>;
+ interrupt-parent = <&gic>;
+ };
+
+ imx8qx-pm {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_lsio: PD_LSIO {
+ compatible = "nxp,imx8-pd";
+ reg = <SC_R_NONE>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_lsio_pwm0: PD_LSIO_PWM_0 {
+ reg = <SC_R_PWM_0>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_lsio>;
+ };
+ pd_lsio_pwm1: PD_LSIO_PWM_1 {
+ reg = <SC_R_PWM_1>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_lsio>;
+ };
+ pd_lsio_pwm2: PD_LSIO_PWM_2 {
+ reg = <SC_R_PWM_2>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_lsio>;
+ };
+ pd_lsio_pwm3: PD_LSIO_PWM_3 {
+ reg = <SC_R_PWM_3>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_lsio>;
+ };
+ pd_lsio_pwm4: PD_LSIO_PWM_4 {
+ reg = <SC_R_PWM_4>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_lsio>;
+ };
+ pd_lsio_pwm5: PD_LSIO_PWM_5 {
+ reg = <SC_R_PWM_5>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_lsio>;
+ };
+ pd_lsio_pwm6: PD_LSIO_PWM_6 {
+ reg = <SC_R_PWM_6>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_lsio>;
+ };
+ pd_lsio_pwm7: PD_LSIO_PWM_7 {
+ reg = <SC_R_PWM_7>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_lsio>;
+ };
+ pd_lsio_kpp: PD_LSIO_KPP {
+ reg = <SC_R_KPP>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_lsio>;
+ };
+ pd_lsio_gpio0: PD_LSIO_GPIO_0 {
+ reg = <SC_R_GPIO_0>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_lsio>;
+ };
+ pd_lsio_gpio1: PD_LSIO_GPIO_1 {
+ reg = <SC_R_GPIO_1>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_lsio>;
+ };
+ pd_lsio_gpio2: PD_LSIO_GPIO_2 {
+ reg = <SC_R_GPIO_2>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_lsio>;
+ };
+ pd_lsio_gpio3: PD_LSIO_GPIO_3 {
+ reg = <SC_R_GPIO_3>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_lsio>;
+ };
+ pd_lsio_gpio4: PD_LSIO_GPIO_4 {
+ reg = <SC_R_GPIO_4>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_lsio>;
+ };
+ pd_lsio_gpio5: PD_LSIO_GPIO_5{
+ reg = <SC_R_GPIO_5>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_lsio>;
+ };
+ pd_lsio_gpio6:PD_LSIO_GPIO_6 {
+ reg = <SC_R_GPIO_6>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_lsio>;
+ };
+ pd_lsio_gpio7: PD_LSIO_GPIO_7 {
+ reg = <SC_R_GPIO_7>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_lsio>;
+ };
+ pd_lsio_gpt0: PD_LSIO_GPT_0 {
+ reg = <SC_R_GPT_0>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_lsio>;
+ };
+ pd_lsio_gpt1: PD_LSIO_GPT_1 {
+ reg = <SC_R_GPT_1>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_lsio>;
+ };
+ pd_lsio_gpt2: PD_LSIO_GPT_2 {
+ reg = <SC_R_GPT_2>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_lsio>;
+ };
+ pd_lsio_gpt3: PD_LSIO_GPT_3 {
+ reg = <SC_R_GPT_3>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_lsio>;
+ };
+ pd_lsio_gpt4: PD_LSIO_GPT_4 {
+ reg = <SC_R_GPT_4>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_lsio>;
+ };
+ pd_lsio_flexspi0: PD_LSIO_FSPI_0 {
+ reg = <SC_R_FSPI_0>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_lsio>;
+ };
+ pd_lsio_flexspi1: PD_LSIO_FSPI_1{
+ reg = <SC_R_FSPI_1>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_lsio>;
+ };
+ pd_lsio_mu5a: PD_LSIO_MU5A {
+ reg = <SC_R_MU_5A>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_lsio>;
+ };
+ };
+
+ pd_conn: PD_CONN {
+ compatible = "nxp,imx8-pd";
+ reg = <SC_R_NONE>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_conn_usbotg0: PD_CONN_USB_0 {
+ reg = <SC_R_USB_0>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_conn>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ wakeup-irq = <267>;
+
+ pd_conn_usbotg0_phy: PD_CONN_USB_0_PHY {
+ reg = <SC_R_USB_0_PHY>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_conn_usbotg0>;
+ wakeup-irq = <267>;
+ };
+
+ };
+ pd_conn_usbotg1: PD_CONN_USB_1 {
+ reg = <SC_R_USB_1>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_conn>;
+ };
+ pd_conn_usb2: PD_CONN_USB_2 {
+ reg = <SC_R_USB_2>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ power-domains = <&pd_conn>;
+ wakeup-irq = <271>;
+
+ pd_conn_usb2_phy: PD_CONN_USB_2_PHY {
+ reg = <SC_R_USB_2_PHY>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_conn_usb2>;
+ wakeup-irq = <271>;
+ };
+
+ };
+ pd_conn_sdch0: PD_CONN_SDHC_0 {
+ reg = <SC_R_SDHC_0>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_conn>;
+ };
+ pd_conn_sdch1: PD_CONN_SDHC_1 {
+ reg = <SC_R_SDHC_1>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_conn>;
+ };
+ pd_conn_sdch2: PD_CONN_SDHC_2 {
+ reg = <SC_R_SDHC_2>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_conn>;
+ };
+ pd_conn_enet0: PD_CONN_ENET_0 {
+ reg = <SC_R_ENET_0>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_conn>;
+ wakeup-irq = <258>;
+ };
+ pd_conn_enet1: PD_CONN_ENET_1 {
+ reg = <SC_R_ENET_1>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_conn>;
+ fsl,wakeup_irq = <262>;
+ };
+ pd_conn_nand: PD_CONN_NAND {
+ reg = <SC_R_NAND>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_conn>;
+ };
+ pd_conn_mlb0: PD_CONN_MLB_0 {
+ reg = <SC_R_MLB_0>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_conn>;
+ };
+ pd_conn_edma_ch0: PD_CONN_DMA_4_CH0 {
+ reg = <SC_R_DMA_4_CH0>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_conn>;
+ };
+ pd_conn_edma_ch1: PD_CONN_DMA_4_CH1 {
+ reg = <SC_R_DMA_4_CH1>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_conn>;
+ };
+ pd_conn_edma_ch2: PD_CONN_DMA_4_CH2 {
+ reg = <SC_R_DMA_4_CH2>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_conn>;
+ };
+ pd_conn_edma_ch3: PD_CONN_DMA_4_CH3 {
+ reg = <SC_R_DMA_4_CH3>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_conn>;
+ };
+ pd_conn_edma_ch4: PD_CONN_DMA_4_CH4 {
+ reg = <SC_R_DMA_4_CH4>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_conn>;
+ };
+ };
+
+ pd_audio: PD_AUDIO {
+ compatible = "nxp,imx8-pd";
+ reg = <SC_R_NONE>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_audio_pll0: PD_AUD_AUDIO_PLL_0 {
+ reg = <SC_R_AUDIO_PLL_0>;
+ power-domains =<&pd_audio>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_audio_pll1: PD_AUD_AUDIO_PLL_1 {
+ reg = <SC_R_AUDIO_PLL_1>;
+ power-domains =<&pd_audio_pll0>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_audio_clk0: PD_AUD_AUDIO_CLK_0 {
+ reg = <SC_R_AUDIO_CLK_0>;
+ power-domains =<&pd_audio_pll1>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_audio_clk1: PD_AUD_AUDIO_CLK_1 {
+ reg = <SC_R_AUDIO_CLK_1>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_audio_clk0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_dma0_chan0: PD_ASRC_0_RXA {
+ reg = <SC_R_DMA_0_CH0>;
+ power-domains =<&pd_audio_clk1>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_dma0_chan1: PD_ASRC_0_RXB {
+ reg = <SC_R_DMA_0_CH1>;
+ power-domains =<&pd_dma0_chan0>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_dma0_chan2: PD_ASRC_0_RXC {
+ reg = <SC_R_DMA_0_CH2>;
+ power-domains =<&pd_dma0_chan1>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_dma0_chan3: PD_ASRC_0_TXA {
+ reg = <SC_R_DMA_0_CH3>;
+ power-domains =<&pd_dma0_chan2>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_dma0_chan4: PD_ASRC_0_TXB {
+ reg = <SC_R_DMA_0_CH4>;
+ power-domains =<&pd_dma0_chan3>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_dma0_chan5: PD_ASRC_0_TXC {
+ reg = <SC_R_DMA_0_CH5>;
+ power-domains =<&pd_dma0_chan4>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_asrc0:PD_AUD_ASRC_0 {
+ reg = <SC_R_ASRC_0>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_dma0_chan5>;
+ };
+ };
+ };
+ };
+ };
+ };
+ };
+
+ pd_dma1_chan0: PD_ASRC_1_RXA {
+ reg = <SC_R_DMA_1_CH0>;
+ power-domains =<&pd_audio_clk1>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_dma1_chan1: PD_ASRC_1_RXB {
+ reg = <SC_R_DMA_1_CH1>;
+ power-domains =<&pd_dma1_chan0>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_dma1_chan2: PD_ASRC_1_RXC {
+ reg = <SC_R_DMA_1_CH2>;
+ power-domains =<&pd_dma1_chan1>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_dma1_chan3: PD_ASRC_1_TXA {
+ reg = <SC_R_DMA_1_CH3>;
+ power-domains =<&pd_dma1_chan2>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_dma1_chan4: PD_ASRC_1_TXB {
+ reg = <SC_R_DMA_1_CH4>;
+ power-domains =<&pd_dma1_chan3>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_dma1_chan5: PD_ASRC_1_TXC {
+ reg = <SC_R_DMA_1_CH5>;
+ power-domains =<&pd_dma1_chan4>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_asrc1: PD_AUD_ASRC_1 {
+ reg = <SC_R_ASRC_1>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_dma1_chan5>;
+
+ };
+ };
+ };
+ };
+ };
+ };
+ };
+ pd_dma0_chan6: PD_ESAI_0_RX {
+ reg = <SC_R_DMA_0_CH6>;
+ power-domains =<&pd_audio_clk1>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_dma0_chan7: PD_ESAI_0_TX {
+ reg = <SC_R_DMA_0_CH7>;
+ power-domains =<&pd_dma0_chan6>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_esai0: PD_AUD_ESAI_0 {
+ reg = <SC_R_ESAI_0>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_dma0_chan7>;
+ };
+ };
+ };
+ pd_dma0_chan8: PD_SPDIF_0_RX {
+ reg = <SC_R_DMA_0_CH8>;
+ power-domains =<&pd_audio_clk1>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_dma0_chan9: PD_SPDIF_0_TX {
+ reg = <SC_R_DMA_0_CH9>;
+ power-domains =<&pd_dma0_chan8>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_spdif0: PD_AUD_SPDIF_0 {
+ reg = <SC_R_SPDIF_0>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_dma0_chan9>;
+
+ };
+ };
+ };
+ pd_dma0_chan12: PD_SAI_0_RX {
+ reg = <SC_R_DMA_0_CH12>;
+ power-domains =<&pd_audio_clk1>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_dma0_chan13: PD_SAI_0_TX {
+ reg = <SC_R_DMA_0_CH13>;
+ power-domains =<&pd_dma0_chan12>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_sai0:PD_AUD_SAI_0 {
+ reg = <SC_R_SAI_0>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_dma0_chan13>;
+ };
+ };
+
+ };
+ pd_dma0_chan14: PD_SAI_1_RX {
+ reg = <SC_R_DMA_0_CH14>;
+ power-domains =<&pd_audio_clk1>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_dma0_chan15: PD_SAI_1_TX {
+ reg = <SC_R_DMA_0_CH15>;
+ power-domains =<&pd_dma0_chan14>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_sai1: PD_AUD_SAI_1 {
+ reg = <SC_R_SAI_1>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_dma0_chan15>;
+ };
+ };
+ };
+ pd_dma0_chan16: PD_SAI_2_RX {
+ reg = <SC_R_DMA_0_CH16>;
+ power-domains =<&pd_audio_clk1>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pd_sai2: PD_AUD_SAI_2 {
+ reg = <SC_R_SAI_2>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_dma0_chan16>;
+ };
+ };
+ pd_dma0_chan17: PD_SAI_3_RX {
+ reg = <SC_R_DMA_0_CH17>;
+ power-domains =<&pd_audio_clk1>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_sai3: PD_AUD_SAI_3 {
+ reg = <SC_R_SAI_3>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_dma0_chan17>;
+ };
+ };
+ pd_dma1_chan8: PD_SAI_4_RX {
+ reg = <SC_R_DMA_1_CH8>;
+ power-domains =<&pd_audio_clk1>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_dma1_chan9: PD_SAI_4_TX {
+ reg = <SC_R_DMA_1_CH9>;
+ power-domains =<&pd_dma1_chan8>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_sai4: PD_AUD_SAI_4 {
+ reg = <SC_R_SAI_4>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_dma1_chan9>;
+
+ };
+ };
+ };
+ pd_dma1_chan10: PD_SAI_5_TX {
+ reg = <SC_R_DMA_1_CH10>;
+ power-domains =<&pd_audio_clk1>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pd_sai5: PD_AUD_SAI_5 {
+ reg = <SC_R_SAI_5>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_dma1_chan10>;
+ };
+ };
+ pd_gpt5: PD_AUD_GPT_5 {
+ reg = <SC_R_GPT_5>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_audio_clk1>;
+ };
+ pd_gpt6: PD_AUD_GPT_6 {
+ reg = <SC_R_GPT_6>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_audio_clk1>;
+ };
+ pd_gpt7: PD_AUD_GPT_7 {
+ reg = <SC_R_GPT_7>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_audio_clk1>;
+ };
+ pd_gpt8: PD_AUD_GPT_8 {
+ reg = <SC_R_GPT_8>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_audio_clk1>;
+ };
+ pd_gpt9: PD_AUD_GPT_9 {
+ reg = <SC_R_GPT_9>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_audio_clk1>;
+ };
+ pd_gpt10: PD_AUD_GPT_10 {
+ reg = <SC_R_GPT_10>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_audio_clk1>;
+ };
+ pd_amix: PD_AUD_AMIX {
+ reg = <SC_R_AMIX>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_audio_clk1>;
+ };
+ pd_mqs0: PD_AUD_MQS_0 {
+ reg = <SC_R_MQS_0>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_audio_clk1>;
+ };
+ pd_mclk_out0: PD_AUD_MCLK_OUT_0 {
+ reg = <SC_R_MCLK_OUT_0>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_audio_clk1>;
+ };
+ pd_mclk_out1: PD_AUD_MCLK_OUT_1 {
+ reg = <SC_R_MCLK_OUT_1>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_audio_clk1>;
+ };
+ };
+ };
+ };
+ };
+
+ pd_dsp_mu_A: PD_DSP_MU_A {
+ reg = <SC_R_MU_13A>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_audio>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_dsp_mu_B: PD_DSP_MU_B {
+ reg = <SC_R_MU_13B>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_dsp_mu_A>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_dsp_ram: PD_AUD_OCRAM {
+ reg = <SC_R_DSP_RAM>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_dsp_mu_B>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pd_dsp: PD_AUD_DSP {
+ reg = <SC_R_DSP>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_dsp_ram>;
+ };
+ };
+ };
+ };
+ };
+
+ pd_dma: PD_DMA {
+ compatible = "nxp,imx8-pd";
+ reg = <SC_R_NONE>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_dma_elcdif_pll: PD_DMA_ELCDIF_PLL {
+ reg = <SC_R_ELCDIF_PLL>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_dma>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_dma_lcd0: PD_DMA_LCD_0 {
+ reg = <SC_R_LCD_0>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_dma_elcdif_pll>;
+ };
+ };
+ pd_dma_flexcan0: PD_DMA_CAN_0 {
+ reg = <SC_R_CAN_0>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_dma>;
+ wakeup-irq = <235>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_dma_flexcan1: PD_DMA_CAN_1 {
+ reg = <SC_R_CAN_1>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_dma_flexcan0>;
+ wakeup-irq = <236>;
+ };
+
+ pd_dma_flexcan2: PD_DMA_CAN_2 {
+ reg = <SC_R_CAN_2>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_dma_flexcan0>;
+ wakeup-irq = <237>;
+ };
+ };
+
+ pd_dma_ftm0: PD_DMA_FTM_0 {
+ reg = <SC_R_FTM_0>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_dma>;
+ };
+ pd_dma_ftm1: PD_DMA_FTM_1 {
+ reg = <SC_R_FTM_1>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_dma>;
+ };
+ pd_dma_adc0: PD_DMA_ADC_0 {
+ reg = <SC_R_ADC_0>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_dma>;
+ };
+ pd_dma_lpi2c0: PD_DMA_I2C_0 {
+ reg = <SC_R_I2C_0>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_dma>;
+ };
+ pd_dma_lpi2c1: PD_DMA_I2C_1 {
+ reg = <SC_R_I2C_1>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_dma>;
+ };
+ pd_dma_lpi2c2:PD_DMA_I2C_2 {
+ reg = <SC_R_I2C_2>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_dma>;
+ };
+ pd_dma_lpi2c3: PD_DMA_I2C_3 {
+ reg = <SC_R_I2C_3>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_dma>;
+ };
+ pd_dma_lpuart0: PD_DMA_UART0 {
+ reg = <SC_R_UART_0>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_dma>;
+ wakeup-irq = <345>;
+ };
+ pd_dma_lpuart1: PD_DMA_UART1 {
+ reg = <SC_R_UART_1>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_dma>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ wakeup-irq = <346>;
+
+ pd_dma2_chan10: PD_UART1_RX {
+ reg = <SC_R_DMA_2_CH10>;
+ power-domains =<&pd_dma_lpuart1>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_dma2_chan11: PD_UART1_TX {
+ reg = <SC_R_DMA_2_CH11>;
+ power-domains =<&pd_dma2_chan10>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ };
+ };
+ pd_dma_lpuart2: PD_DMA_UART2 {
+ reg = <SC_R_UART_2>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_dma>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ wakeup-irq = <347>;
+
+ pd_dma2_chan12: PD_UART2_RX {
+ reg = <SC_R_DMA_2_CH12>;
+ power-domains =<&pd_dma_lpuart2>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_dma2_chan13: PD_UART2_TX {
+ reg = <SC_R_DMA_2_CH13>;
+ power-domains =<&pd_dma2_chan12>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ };
+ };
+ pd_dma_lpuart3: PD_DMA_UART3 {
+ reg = <SC_R_UART_3>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_dma>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ wakeup-irq = <348>;
+
+ pd_dma3_chan14: PD_UART3_RX {
+ reg = <SC_R_DMA_2_CH14>;
+ power-domains =<&pd_dma_lpuart3>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_dma3_chan15: PD_UART3_TX {
+ reg = <SC_R_DMA_2_CH15>;
+ power-domains =<&pd_dma3_chan14>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ };
+ };
+ pd_dma_lpspi0: PD_DMA_SPI_0 {
+ reg = <SC_R_SPI_0>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_dma>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ wakeup-irq = <336>;
+
+ pd_dma2_chan0: PD_LPSPI0_RX {
+ reg = <SC_R_DMA_2_CH0>;
+ power-domains =<&pd_dma_lpspi0>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_dma2_chan1: PD_LPSPI0_TX {
+ reg = <SC_R_DMA_2_CH1>;
+ power-domains =<&pd_dma2_chan0>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ };
+ };
+ pd_dma_lpspi1: PD_DMA_SPI_1 {
+ reg = <SC_R_SPI_1>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_dma>;
+ };
+ pd_dma_lpspi2: PD_DMA_SPI_2 {
+ reg = <SC_R_SPI_2>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_dma>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ wakeup-irq = <338>;
+
+ pd_dma2_chan4: PD_LPSPI2_RX {
+ reg = <SC_R_DMA_2_CH4>;
+ power-domains =<&pd_dma_lpspi2>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_dma2_chan5: PD_LPSPI2_TX {
+ reg = <SC_R_DMA_2_CH5>;
+ power-domains =<&pd_dma2_chan4>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ };
+ };
+ pd_dma_lpspi3: PD_DMA_SPI_3 {
+ reg = <SC_R_SPI_3>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_dma>;
+ };
+ pd_dma_pwm0: PD_DMA_PWM_0 {
+ reg = <SC_R_LCD_0_PWM_0>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_dma>;
+ };
+ };
+
+ pd_gpu: gpu-power-domain {
+ compatible = "nxp,imx8-pd";
+ reg = <SC_R_NONE>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_gpu0: gpu0 {
+ name = "gpu0";
+ reg = <SC_R_GPU_0_PID0>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_gpu>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ };
+
+ pd_vpu: vpu-power-domain {
+ compatible = "nxp,imx8-pd";
+ reg = <SC_R_VPU>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_vpu_mu_enc: VPU_ENC_MU {
+ reg = <SC_R_VPU_MU_1>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_vpu>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_vpu_enc: VPU_ENC {
+ reg = <SC_R_VPU_ENC_0>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_vpu_mu_enc>;
+ };
+ };
+
+ pd_vpu_mu_dec: VPU_DEC_MU {
+ reg = <SC_R_VPU_MU_0>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_vpu>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_vpu_dec: VPU_DEC {
+ reg = <SC_R_VPU_DEC_0>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_vpu_mu_dec>;
+ };
+ };
+ };
+
+ pd_hsio: hsio-power-domain {
+ compatible = "nxp,imx8-pd";
+ reg = <SC_R_NONE>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_hsio_gpio: PD_HSIO_GPIO {
+ reg = <SC_R_HSIO_GPIO>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_hsio>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_serdes1: PD_HSIO_SERDES_1 {
+ reg = <SC_R_SERDES_1>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_hsio_gpio>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_pcie: PD_HSIO_PCIE_B {
+ reg = <SC_R_PCIE_B>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_serdes1>;
+ };
+ };
+ };
+ };
+
+ pd_cm40: PD_CM40 {
+ compatible = "nxp,imx8-pd";
+ reg = <SC_R_NONE>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_cm40_i2c: PD_CM40_I2C {
+ reg = <SC_R_M4_0_I2C>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_cm40>;
+ };
+
+ pd_cm40_intmux: PD_CM40_INTMUX {
+ reg = <SC_R_M4_0_INTMUX>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_cm40>;
+ };
+ };
+
+
+ pd_dc0: PD_DC_0 {
+ compatible = "nxp,imx8-pd";
+ reg = <SC_R_DC_0>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_dc0_pll0: PD_DC_0_PLL_0{
+ reg = <SC_R_DC_0_PLL_0>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_dc0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_dc0_pll1: PD_DC_0_PLL_1{
+ reg = <SC_R_DC_0_PLL_1>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_dc0_pll0>;
+ };
+ };
+ pd_mipi_dsi0: PD_MIPI_0_DSI {
+ reg = <SC_R_MIPI_0>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_dc0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_mipi_dsi_0_lvds: PD_LVDS0 {
+ reg = <SC_R_LVDS_0>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_mipi_dsi0>;
+ };
+
+ pd_mipi_dsi_0_aux_lvds: PD_AUX_LVDS0 {
+ reg = <SC_R_LVDS_0>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_mipi_dsi0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_mipi_dsi_1_dual_lvds: PD_DUAL_LVDS1 {
+ reg = <SC_R_LVDS_1>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_mipi_dsi_0_aux_lvds>;
+ };
+ };
+
+ pd_mipi_dsi_0_i2c0: PD_MIPI_0_DSI_I2C0 {
+ reg = <SC_R_MIPI_0_I2C_0>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_mipi_dsi0>;
+ };
+ pd_mipi_dsi_0_i2c1: PD_MIPI_0_DSI_I2C1 {
+ reg = <SC_R_MIPI_0_I2C_1>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_mipi_dsi0>;
+ };
+ pd_mipi_0_pwm0: PD_MIPI_0_DSI_PWM0 {
+ reg = <SC_R_MIPI_0_PWM_0>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_mipi_dsi0>;
+ };
+ };
+
+ pd_mipi_dsi1: PD_MIPI_1_DSI {
+ reg = <SC_R_MIPI_1>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_dc0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_mipi_dsi_1_lvds: PD_LVDS1 {
+ reg = <SC_R_LVDS_1>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_mipi_dsi1>;
+ };
+
+ pd_mipi_dsi_1_aux_lvds: PD_AUX_LVDS1 {
+ reg = <SC_R_LVDS_1>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_mipi_dsi1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_mipi_dsi_0_dual_lvds: PD_DUAL_LVDS0 {
+ reg = <SC_R_LVDS_0>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_mipi_dsi_1_aux_lvds>;
+ };
+ };
+
+ pd_mipi_dsi_1_i2c0: PD_MIPI_1_DSI_I2C0 {
+ reg = <SC_R_MIPI_1_I2C_0>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_mipi_dsi1>;
+ };
+ pd_mipi_dsi_1_i2c1: PD_MIPI_1_DSI_I2C1 {
+ reg = <SC_R_MIPI_1_I2C_1>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_mipi_dsi1>;
+ };
+ pd_mipi_1_pwm0: PD_MIPI_1_DSI_PWM0 {
+ reg = <SC_R_MIPI_1_PWM_0>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_mipi_dsi1>;
+ };
+ };
+ };
+
+ pd_isi_ch0: PD_IMAGING {
+ compatible = "nxp,imx8-pd";
+ reg = <SC_R_ISI_CH0>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_mipi_csi: PD_MIPI_CSI0 {
+ reg = <SC_R_CSI_0>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ power-domains =<&pd_isi_ch0>;
+
+ pd_mipi_csi_i2c0: PD_MIPI_CSI0_I2C0 {
+ reg = <SC_R_CSI_0_I2C_0>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_mipi_csi>;
+ };
+
+ pd_mipi_csi_pwm0: PD_MIPI_CSI0_PWM {
+ name = "mipi_csi0_pwm";
+ reg = <SC_R_CSI_0_PWM_0>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_mipi_csi>;
+ };
+ };
+
+ pd_parallel_csi: PD_PARALLEL_CSI {
+ reg = <SC_R_PI_0>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ power-domains =<&pd_isi_ch0>;
+
+ pd_parallel_csi_i2c0: PD_PARALLEL_CSI_I2C {
+ name = "parallel_csi_i2c";
+ reg = <SC_R_PI_0_I2C_0>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_parallel_csi>;
+ };
+
+ pd_parallel_csi_pwm0: PD_PARALLEL_CSI_PWM {
+ name = "parallel_csi_pwm";
+ reg = <SC_R_PI_0_PWM_0>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_parallel_csi>;
+ };
+
+ pd_parallel_csi_pll: PD_PARALLEL_CSI_PLL {
+ name = "parallel_csi_pll";
+ reg = <SC_R_PI_0_PLL>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_parallel_csi>;
+ };
+ };
+
+ pd_isi_ch1: PD_IMAGING_PDMA1 {
+ reg = <SC_R_ISI_CH1>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_isi_ch0>;
+ };
+
+ pd_isi_ch2: PD_IMAGING_PDMA2 {
+ reg = <SC_R_ISI_CH2>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_isi_ch0>;
+ };
+
+ pd_isi_ch3: PD_IMAGING_PDMA3 {
+ reg = <SC_R_ISI_CH3>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_isi_ch0>;
+ };
+
+ pd_isi_ch4: PD_IMAGING_PDMA4 {
+ reg = <SC_R_ISI_CH4>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_isi_ch0>;
+ };
+
+ pd_isi_ch5: PD_IMAGING_PDMA5 {
+ reg = <SC_R_ISI_CH5>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_isi_ch0>;
+ };
+
+ pd_isi_ch6: PD_IMAGING_PDMA6 {
+ reg = <SC_R_ISI_CH6>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_isi_ch0>;
+ };
+
+ pd_isi_ch7: PD_IMAGING_PDMA7 {
+ reg = <SC_R_ISI_CH7>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_isi_ch0>;
+ };
+
+ pd_jpeg_dec_mp: PD_JPEG_DEC_MP{
+ reg = <SC_R_MJPEG_DEC_MP>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_isi_ch0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_jpgdec: PD_IMAGING_JPEG_DEC {
+ reg = <SC_R_MJPEG_DEC_S0>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_jpeg_dec_mp>;
+ };
+ };
+
+ pd_jpeg_enc_mp: PD_JPEG_ENC_MP{
+ reg = <SC_R_MJPEG_ENC_MP>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_isi_ch0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_jpgenc: PD_IMAGING_JPEG_ENC {
+ reg = <SC_R_MJPEG_ENC_S0>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_jpeg_enc_mp>;
+ };
+ };
+ };
+ pd_caam: PD_CAAM {
+ compatible = "nxp,imx8-pd";
+ reg = <SC_R_NONE>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_caam_jr1: PD_CAAM_JR1 {
+ reg = <SC_R_CAAM_JR1>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_caam>;
+ };
+ pd_caam_jr2: PD_CAAM_JR2 {
+ reg = <SC_R_CAAM_JR2>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_caam>;
+ };
+ pd_caam_jr3: PD_CAAM_JR3 {
+ reg = <SC_R_CAAM_JR3>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_caam>;
+ };
+ };
+ };
+
+ tsens: thermal-sensor {
+ compatible = "nxp,imx8qxp-sc-tsens";
+ /* number of the temp sensor on the chip */
+ tsens-num = <2>;
+ #thermal-sensor-cells = <1>;
+ };
+
+ thermal_zones: thermal-zones {
+ /* cpu thermal */
+ cpu-thermal0 {
+ polling-delay-passive = <250>;
+ polling-delay = <2000>;
+ /*the slope and offset of the temp sensor */
+ thermal-sensors = <&tsens 0>;
+ trips {
+ cpu_alert0: trip0 {
+ temperature = <107000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+ cpu_crit0: trip1 {
+ temperature = <127000>;
+ hysteresis = <2000>;
+ type = "critical";
+ };
+ };
+ cooling-maps {
+ map0 {
+ trip = <&cpu_alert0>;
+ cooling-device =
+ <&A35_0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
+ };
+
+ drc-thermal0 {
+ polling-delay-passive = <250>;
+ polling-delay = <2000>;
+ thermal-sensors = <&tsens 1>;
+ status = "disabled";
+ trips {
+ drc_alert0: trip0 {
+ temperature = <107000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+ drc_crit0: trip1 {
+ temperature = <127000>;
+ hysteresis = <2000>;
+ type = "critical";
+ };
+ };
+ };
+ };
+
+ irqsteer_csi: irqsteer@58220000 {
+ compatible = "nxp,imx-irqsteer";
+ reg = <0x0 0x58220000 0x0 0x1000>;
+ interrupts = <GIC_SPI 320 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-controller;
+ interrupt-parent = <&gic>;
+ #interrupt-cells = <2>;
+ clocks = <&clk IMX8QXP_CLK_DUMMY>;
+ clock-names = "ipg";
+ power-domains = <&pd_mipi_csi>;
+ };
+
+ i2c0_csi0: i2c@58226000 {
+ compatible = "fsl,imx8qm-lpi2c";
+ reg = <0x0 0x58226000 0x0 0x1000>;
+ interrupts = <8 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-parent = <&irqsteer_csi>;
+ clocks = <&clk IMX8QXP_CSI0_I2C0_CLK>,
+ <&clk IMX8QXP_CSI0_I2C0_IPG_CLK>;
+ clock-names = "per", "ipg";
+ assigned-clocks = <&clk IMX8QXP_CSI0_I2C0_CLK>;
+ assigned-clock-rates = <24000000>;
+ power-domains = <&pd_mipi_csi_i2c0>;
+ status = "disabled";
+ };
+
+ intmux_cm40: intmux@37400000 {
+ compatible = "nxp,imx-intmux";
+ reg = <0x0 0x37400000 0x0 0x1000>;
+ interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>,
+ <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>;
+ interrupt-controller;
+ interrupt-parent = <&gic>;
+ #interrupt-cells = <2>;
+ clocks = <&clk IMX8QXP_CM40_IPG_CLK>;
+ clock-names = "ipg";
+ power-domains = <&pd_cm40_intmux>;
+ status = "disabled";
+ };
+
+ i2c0_cm40: i2c@37230000 {
+ compatible = "fsl,imx8qm-lpi2c";
+ reg = <0x0 0x37230000 0x0 0x1000>;
+ interrupts = <9 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-parent = <&intmux_cm40>;
+ clocks = <&clk IMX8QXP_CM40_I2C_CLK>,
+ <&clk IMX8QXP_CM40_I2C_IPG_CLK>;
+ clock-names = "per", "ipg";
+ assigned-clocks = <&clk IMX8QXP_CM40_I2C_CLK>;
+ assigned-clock-rates = <24000000>;
+ power-domains = <&pd_cm40_i2c>;
+ status = "disabled";
+ };
+
+ dpu_intsteer: dpu_intsteer@56000000 {
+ compatible = "fsl,imx8qxp-dpu-intsteer", "syscon";
+ reg = <0x0 0x56000000 0x0 0x10000>;
+ };
+
+ pixel_combiner: pixel-combiner@56020000 {
+ compatible = "fsl,imx8qxp-pixel-combiner";
+ reg = <0x0 0x56020000 0x0 0x10000>;
+ power-domains = <&pd_dc0>;
+ status = "disabled";
+ };
+
+ prg1: prg@56040000 {
+ compatible = "fsl,imx8qxp-prg", "fsl,imx8qm-prg";
+ reg = <0x0 0x56040000 0x0 0x10000>;
+ clocks = <&clk IMX8QXP_DC0_PRG0_APB_CLK>,
+ <&clk IMX8QXP_DC0_PRG0_RTRAM_CLK>;
+ clock-names = "apb", "rtram";
+ power-domains = <&pd_dc0>;
+ status = "disabled";
+ };
+
+ prg2: prg@56050000 {
+ compatible = "fsl,imx8qxp-prg", "fsl,imx8qm-prg";
+ reg = <0x0 0x56050000 0x0 0x10000>;
+ clocks = <&clk IMX8QXP_DC0_PRG1_APB_CLK>,
+ <&clk IMX8QXP_DC0_PRG1_RTRAM_CLK>;
+ clock-names = "apb", "rtram";
+ power-domains = <&pd_dc0>;
+ status = "disabled";
+ };
+
+ prg3: prg@56060000 {
+ compatible = "fsl,imx8qxp-prg", "fsl,imx8qm-prg";
+ reg = <0x0 0x56060000 0x0 0x10000>;
+ clocks = <&clk IMX8QXP_DC0_PRG2_APB_CLK>,
+ <&clk IMX8QXP_DC0_PRG2_RTRAM_CLK>;
+ clock-names = "apb", "rtram";
+ power-domains = <&pd_dc0>;
+ status = "disabled";
+ };
+
+ prg4: prg@56070000 {
+ compatible = "fsl,imx8qxp-prg", "fsl,imx8qm-prg";
+ reg = <0x0 0x56070000 0x0 0x10000>;
+ clocks = <&clk IMX8QXP_DC0_PRG3_APB_CLK>,
+ <&clk IMX8QXP_DC0_PRG3_RTRAM_CLK>;
+ clock-names = "apb", "rtram";
+ power-domains = <&pd_dc0>;
+ status = "disabled";
+ };
+
+ prg5: prg@56080000 {
+ compatible = "fsl,imx8qxp-prg", "fsl,imx8qm-prg";
+ reg = <0x0 0x56080000 0x0 0x10000>;
+ clocks = <&clk IMX8QXP_DC0_PRG4_APB_CLK>,
+ <&clk IMX8QXP_DC0_PRG4_RTRAM_CLK>;
+ clock-names = "apb", "rtram";
+ power-domains = <&pd_dc0>;
+ status = "disabled";
+ };
+
+ prg6: prg@56090000 {
+ compatible = "fsl,imx8qxp-prg", "fsl,imx8qm-prg";
+ reg = <0x0 0x56090000 0x0 0x10000>;
+ clocks = <&clk IMX8QXP_DC0_PRG5_APB_CLK>,
+ <&clk IMX8QXP_DC0_PRG5_RTRAM_CLK>;
+ clock-names = "apb", "rtram";
+ power-domains = <&pd_dc0>;
+ status = "disabled";
+ };
+
+ prg7: prg@560a0000 {
+ compatible = "fsl,imx8qxp-prg", "fsl,imx8qm-prg";
+ reg = <0x0 0x560a0000 0x0 0x10000>;
+ clocks = <&clk IMX8QXP_DC0_PRG6_APB_CLK>,
+ <&clk IMX8QXP_DC0_PRG6_RTRAM_CLK>;
+ clock-names = "apb", "rtram";
+ power-domains = <&pd_dc0>;
+ status = "disabled";
+ };
+
+ prg8: prg@560b0000 {
+ compatible = "fsl,imx8qxp-prg", "fsl,imx8qm-prg";
+ reg = <0x0 0x560b0000 0x0 0x10000>;
+ clocks = <&clk IMX8QXP_DC0_PRG7_APB_CLK>,
+ <&clk IMX8QXP_DC0_PRG7_RTRAM_CLK>;
+ clock-names = "apb", "rtram";
+ power-domains = <&pd_dc0>;
+ status = "disabled";
+ };
+
+ prg9: prg@560c0000 {
+ compatible = "fsl,imx8qxp-prg", "fsl,imx8qm-prg";
+ reg = <0x0 0x560c0000 0x0 0x10000>;
+ clocks = <&clk IMX8QXP_DC0_PRG8_APB_CLK>,
+ <&clk IMX8QXP_DC0_PRG8_RTRAM_CLK>;
+ clock-names = "apb", "rtram";
+ power-domains = <&pd_dc0>;
+ status = "disabled";
+ };
+
+ dpr1_channel1: dpr-channel@560d0000 {
+ compatible = "fsl,imx8qxp-dpr-channel",
+ "fsl,imx8qm-dpr-channel";
+ reg = <0x0 0x560d0000 0x0 0x10000>;
+ fsl,sc-resource = <SC_R_DC_0_BLIT0>;
+ fsl,prgs = <&prg1>;
+ clocks = <&clk IMX8QXP_DC0_DPR0_APB_CLK>,
+ <&clk IMX8QXP_DC0_DPR0_B_CLK>,
+ <&clk IMX8QXP_DC0_RTRAM0_CLK>;
+ clock-names = "apb", "b", "rtram";
+ power-domains = <&pd_dc0>;
+ status = "disabled";
+ };
+
+ dpr1_channel2: dpr-channel@560e0000 {
+ compatible = "fsl,imx8qxp-dpr-channel",
+ "fsl,imx8qm-dpr-channel";
+ reg = <0x0 0x560e0000 0x0 0x10000>;
+ fsl,sc-resource = <SC_R_DC_0_BLIT1>;
+ fsl,prgs = <&prg2>, <&prg1>;
+ clocks = <&clk IMX8QXP_DC0_DPR0_APB_CLK>,
+ <&clk IMX8QXP_DC0_DPR0_B_CLK>,
+ <&clk IMX8QXP_DC0_RTRAM0_CLK>;
+ clock-names = "apb", "b", "rtram";
+ power-domains = <&pd_dc0>;
+ status = "disabled";
+ };
+
+ dpr1_channel3: dpr-channel@560f0000 {
+ compatible = "fsl,imx8qxp-dpr-channel",
+ "fsl,imx8qm-dpr-channel";
+ reg = <0x0 0x560f0000 0x0 0x10000>;
+ fsl,sc-resource = <SC_R_DC_0_FRAC0>;
+ fsl,prgs = <&prg3>;
+ clocks = <&clk IMX8QXP_DC0_DPR0_APB_CLK>,
+ <&clk IMX8QXP_DC0_DPR0_B_CLK>,
+ <&clk IMX8QXP_DC0_RTRAM0_CLK>;
+ clock-names = "apb", "b", "rtram";
+ power-domains = <&pd_dc0>;
+ status = "disabled";
+ };
+
+ dpr2_channel1: dpr-channel@56100000 {
+ compatible = "fsl,imx8qxp-dpr-channel",
+ "fsl,imx8qm-dpr-channel";
+ reg = <0x0 0x56100000 0x0 0x10000>;
+ fsl,sc-resource = <SC_R_DC_0_VIDEO0>;
+ fsl,prgs = <&prg4>, <&prg5>;
+ clocks = <&clk IMX8QXP_DC0_DPR1_APB_CLK>,
+ <&clk IMX8QXP_DC0_DPR1_B_CLK>,
+ <&clk IMX8QXP_DC0_RTRAM1_CLK>;
+ clock-names = "apb", "b", "rtram";
+ power-domains = <&pd_dc0>;
+ status = "disabled";
+ };
+
+ dpr2_channel2: dpr-channel@56110000 {
+ compatible = "fsl,imx8qxp-dpr-channel",
+ "fsl,imx8qm-dpr-channel";
+ reg = <0x0 0x56110000 0x0 0x10000>;
+ fsl,sc-resource = <SC_R_DC_0_VIDEO1>;
+ fsl,prgs = <&prg6>, <&prg7>;
+ clocks = <&clk IMX8QXP_DC0_DPR1_APB_CLK>,
+ <&clk IMX8QXP_DC0_DPR1_B_CLK>,
+ <&clk IMX8QXP_DC0_RTRAM1_CLK>;
+ clock-names = "apb", "b", "rtram";
+ power-domains = <&pd_dc0>;
+ status = "disabled";
+ };
+
+ dpr2_channel3: dpr-channel@56120000 {
+ compatible = "fsl,imx8qxp-dpr-channel",
+ "fsl,imx8qm-dpr-channel";
+ reg = <0x0 0x56120000 0x0 0x10000>;
+ fsl,sc-resource = <SC_R_DC_0_WARP>;
+ fsl,prgs = <&prg8>, <&prg9>;
+ clocks = <&clk IMX8QXP_DC0_DPR1_APB_CLK>,
+ <&clk IMX8QXP_DC0_DPR1_B_CLK>,
+ <&clk IMX8QXP_DC0_RTRAM1_CLK>;
+ clock-names = "apb", "b", "rtram";
+ power-domains = <&pd_dc0>;
+ status = "disabled";
+ };
+
+ dpu1: dpu@56180000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx8qxp-dpu", "fsl,imx8qm-dpu";
+ reg = <0x0 0x56180000 0x0 0x40000>;
+ intsteer = <&dpu_intsteer>;
+ interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 47 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 50 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "irq_common",
+ "irq_stream0a",
+ "irq_stream0b", /* to M4? */
+ "irq_stream1a",
+ "irq_stream1b", /* to M4? */
+ "irq_reserved0",
+ "irq_reserved1",
+ "irq_blit",
+ "irq_dpr0",
+ "irq_dpr1";
+ clocks = <&clk IMX8QXP_DC0_PLL0_CLK>,
+ <&clk IMX8QXP_DC0_PLL1_CLK>,
+ <&clk IMX8QXP_DC0_DISP0_CLK>,
+ <&clk IMX8QXP_DC0_DISP1_CLK>;
+ clock-names = "pll0", "pll1", "disp0", "disp1";
+ power-domains = <&pd_dc0_pll1>;
+ fsl,dpr-channels = <&dpr1_channel1>, <&dpr1_channel2>,
+ <&dpr1_channel3>, <&dpr2_channel1>,
+ <&dpr2_channel2>, <&dpr2_channel3>;
+ fsl,pixel-combiner = <&pixel_combiner>;
+ status = "disabled";
+
+ dpu_disp0: port@0 {
+ reg = <0>;
+
+ dpu_disp0_lvds0_ch0: lvds0-endpoint {
+ remote-endpoint = <&ldb1_ch0>;
+ };
+
+ dpu_disp0_lvds0_ch1: lvds1-endpoint {
+ remote-endpoint = <&ldb1_ch1>;
+ };
+
+ dpu_disp0_mipi_dsi: mipi-dsi-endpoint {
+ remote-endpoint = <&mipi_dsi1_in>;
+ };
+ };
+
+ dpu_disp1: port@1 {
+ reg = <1>;
+
+ dpu_disp1_lvds1_ch0: lvds0-endpoint {
+ remote-endpoint = <&ldb2_ch0>;
+ };
+
+ dpu_disp1_lvds1_ch1: lvds1-endpoint {
+ remote-endpoint = <&ldb2_ch1>;
+ };
+
+ dpu_disp1_mipi_dsi: mipi-dsi-endpoint {
+ remote-endpoint = <&mipi_dsi2_in>;
+ };
+ };
+ };
+
+ irqsteer_mipi_lvds0: irqsteer@56220000 {
+ compatible = "nxp,imx-irqsteer";
+ reg = <0x0 0x56220000 0x0 0x1000>;
+ interrupts = <GIC_SPI 59 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-controller;
+ interrupt-parent = <&gic>;
+ #interrupt-cells = <2>;
+ clocks = <&clk IMX8QXP_MIPI0_LIS_IPG_CLK>;
+ clock-names = "ipg";
+ power-domains = <&pd_mipi_dsi0>;
+ };
+
+ adma_lcdif: lcdif@5a180000 {
+ compatible = "fsl,imx8qxp-lcdif", "fsl,imx28-lcdif";
+ reg = <0x0 0x5a180000 0x0 0x10000>;
+ clocks = <&clk IMX8QXP_LCD_CLK>,
+ <&clk IMX8QXP_LCD_PXL_CLK>,
+ <&clk IMX8QXP_LCD_IPG_CLK>;
+ clock-names = "pix", "disp_axi", "axi";
+ assigned-clocks = <&clk IMX8QXP_LCD_SEL>,
+ <&clk IMX8QXP_LCD_PXL_SEL>,
+ <&clk IMX8QXP_ELCDIF_PLL_DIV>;
+ assigned-clock-parents = <&clk IMX8QXP_ELCDIF_PLL>,
+ <&clk IMX8QXP_LCD_PXL_BYPASS_DIV>;
+ assigned-clock-rates = <0>, <24000000>, <804000000>;
+ interrupts = <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>;
+ power-domains = <&pd_dma_lcd0>;
+ status = "disabled";
+ };
+
+ pwm_adma_lcdif: pwm@5a190000 {
+ compatible = "fsl,imx8qxp-pwm", "fsl,imx27-pwm";
+ reg = <0x0 0x5a190000 0 0x1000>;
+ clocks = <&clk IMX8QXP_PWM_IPG_CLK>,
+ <&clk IMX8QXP_PWM_CLK>;
+ clock-names = "ipg", "per";
+ assigned-clocks = <&clk IMX8QXP_PWM_CLK>;
+ assigned-clock-rates = <24000000>;
+ #pwm-cells = <2>;
+ power-domains = <&pd_dma_pwm0>;
+ status = "disabled";
+ };
+
+ mipi_dsi_csr1: csr@56221000 {
+ compatible = "fsl,imx8qxp-mipi-dsi-csr", "syscon";
+ reg = <0x0 0x56221000 0x0 0x1000>;
+ };
+
+ mipi_dsi_phy1: dsi_phy@56228300 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "mixel,imx8qxp-mipi-dsi-phy";
+ reg = <0x0 0x56228300 0x0 0x100>;
+ #phy-cells = <0>;
+ status = "disabled";
+ };
+
+ mipi_dsi_bridge1: mipi_dsi_bridge@56228000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "nwl,mipi-dsi";
+ reg = <0x0 0x56228000 0x0 0x300>;
+ interrupts = <16 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-parent = <&irqsteer_mipi_lvds0>;
+ clocks =
+ <&clk IMX8QXP_MIPI0_DSI_PHY_CLK>,
+ <&clk IMX8QXP_MIPI0_DSI_TX_ESC_CLK>,
+ <&clk IMX8QXP_MIPI0_DSI_RX_ESC_CLK>;
+ clock-names = "phy_ref", "tx_esc", "rx_esc";
+ assigned-clocks =
+ <&clk IMX8QXP_MIPI0_DSI_PHY_SEL>,
+ <&clk IMX8QXP_MIPI0_DSI_TX_ESC_SEL>,
+ <&clk IMX8QXP_MIPI0_DSI_RX_ESC_SEL>,
+ <&clk IMX8QXP_MIPI0_DSI_TX_ESC_CLK>,
+ <&clk IMX8QXP_MIPI0_DSI_RX_ESC_CLK>;
+ assigned-clock-rates = <0>, <0>, <0>, <18000000>, <72000000>;
+ assigned-clock-parents =
+ <&clk IMX8QXP_MIPI0_DSI_PLL_DIV2_CLK>,
+ <&clk IMX8QXP_MIPI0_DSI_PLL_DIV2_CLK>,
+ <&clk IMX8QXP_MIPI0_DSI_PLL_DIV2_CLK>;
+ power-domains = <&pd_mipi_dsi0>;
+ phys = <&mipi_dsi_phy1>;
+ phy-names = "dphy";
+ status = "disabled";
+
+ port@0 {
+ mipi_dsi_bridge1_in: endpoint {
+ remote-endpoint = <&mipi_dsi1_out>;
+ };
+ };
+ };
+
+ mipi_dsi1: mipi_dsi@56228000 {
+ compatible = "fsl,imx8qxp-mipi-dsi";
+ clocks =
+ <&clk IMX8QXP_MIPI0_PIXEL_CLK>,
+ <&clk IMX8QXP_MIPI0_BYPASS_CLK>,
+ <&clk IMX8QXP_MIPI0_DSI_PHY_CLK>;
+ clock-names = "pixel", "bypass", "phy_ref";
+ power-domains = <&pd_mipi_dsi0>;
+ csr = <&mipi_dsi_csr1>;
+ phys = <&mipi_dsi_phy1>;
+ phy-names = "dphy";
+ status = "disabled";
+
+ port@0 {
+ mipi_dsi1_in: endpoint {
+ remote-endpoint = <&dpu_disp0_mipi_dsi>;
+ };
+ };
+
+ port@1 {
+ mipi_dsi1_out: endpoint {
+ remote-endpoint = <&mipi_dsi_bridge1_in>;
+ };
+ };
+ };
+
+ lvds_region1: lvds_region@56220000 {
+ compatible = "fsl,imx8qxp-lvds-region", "syscon";
+ reg = <0x0 0x56220000 0x0 0x10000>;
+ };
+
+ ldb1_phy: ldb_phy@56221000 {
+ compatible = "mixel,lvds-combo-phy";
+ reg = <0x0 0x56221000 0x0 0x100>, <0x0 0x56228000 0x0 0x1000>;
+ #phy-cells = <0>;
+ clocks = <&clk IMX8QXP_MIPI0_LVDS_PHY_CLK>;
+ clock-names = "phy";
+ status = "disabled";
+ };
+
+ ldb1: ldb@562210e0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx8qxp-ldb";
+ clocks = <&clk IMX8QXP_MIPI0_LVDS_PIXEL_CLK>,
+ <&clk IMX8QXP_MIPI0_LVDS_BYPASS_CLK>,
+ <&clk IMX8QXP_MIPI1_LVDS_PIXEL_CLK>,
+ <&clk IMX8QXP_MIPI1_LVDS_BYPASS_CLK>;
+ clock-names = "pixel", "bypass", "aux_pixel", "aux_bypass";
+ power-domains = <&pd_mipi_dsi_0_lvds>;
+ gpr = <&lvds_region1>;
+ aux-gpr = <&lvds_region2>;
+ status = "disabled";
+
+ lvds-channel@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0>;
+ phys = <&ldb1_phy>, <&ldb2_phy>;
+ phy-names = "ldb_phy", "aux_ldb_phy";
+ status = "disabled";
+
+ port@0 {
+ reg = <0>;
+
+ ldb1_ch0: endpoint {
+ remote-endpoint = <&dpu_disp0_lvds0_ch0>;
+ };
+ };
+ };
+
+ lvds-channel@1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <1>;
+ phys = <&ldb1_phy>;
+ phy-names = "ldb_phy";
+ status = "disabled";
+
+ port@0 {
+ reg = <0>;
+
+ ldb1_ch1: endpoint {
+ remote-endpoint = <&dpu_disp0_lvds0_ch1>;
+ };
+ };
+ };
+ };
+
+ pwm_mipi_lvds0: pwm@56224000 {
+ compatible = "fsl,imx8qxp-pwm", "fsl,imx27-pwm";
+ reg = <0x0 0x56224000 0 0x1000>;
+ clocks = <&clk IMX8QXP_MIPI0_PWM_IPG_CLK>,
+ <&clk IMX8QXP_MIPI0_PWM_CLK>,
+ <&clk IMX8QXP_MIPI0_PWM_32K_CLK>;
+ clock-names = "ipg", "per", "32k";
+ assigned-clocks = <&clk IMX8QXP_MIPI0_PWM_CLK>;
+ assigned-clock-rates = <24000000>;
+ #pwm-cells = <2>;
+ power-domains = <&pd_mipi_0_pwm0>;
+ status = "disabled";
+ };
+
+ i2c0_mipi_lvds0: i2c@56226000 {
+ compatible = "fsl,imx8qxp-lpi2c", "fsl,imx8qm-lpi2c";
+ reg = <0x0 0x56226000 0x0 0x1000>;
+ interrupts = <8 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-parent = <&irqsteer_mipi_lvds0>;
+ clocks = <&clk IMX8QXP_MIPI0_I2C0_CLK>,
+ <&clk IMX8QXP_MIPI0_I2C0_IPG_CLK>;
+ clock-names = "per", "ipg";
+ assigned-clocks = <&clk IMX8QXP_MIPI0_I2C0_DIV>;
+ assigned-clock-rates = <24000000>;
+ power-domains = <&pd_mipi_dsi_0_i2c0>;
+ status = "disabled";
+ };
+
+ irqsteer_mipi_lvds1: irqsteer@56240000 {
+ compatible = "nxp,imx-irqsteer";
+ reg = <0x0 0x56240000 0x0 0x1000>;
+ interrupts = <GIC_SPI 60 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-controller;
+ interrupt-parent = <&gic>;
+ #interrupt-cells = <2>;
+ clocks = <&clk IMX8QXP_MIPI1_LIS_IPG_CLK>;
+ clock-names = "ipg";
+ power-domains = <&pd_mipi_dsi1>;
+ };
+
+ mipi_dsi_csr2: csr@56241000 {
+ compatible = "fsl,imx8qxp-mipi-dsi-csr", "syscon";
+ reg = <0x0 0x56241000 0x0 0x1000>;
+ };
+
+ mipi_dsi_phy2: dsi_phy@56248300 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "mixel,imx8qxp-mipi-dsi-phy";
+ reg = <0x0 0x56248300 0x0 0x100>;
+ #phy-cells = <0>;
+ status = "disabled";
+ };
+
+ mipi_dsi_bridge2: mipi_dsi_bridge@56248000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "nwl,mipi-dsi";
+ reg = <0x0 0x56248000 0x0 0x300>;
+ interrupts = <16 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-parent = <&irqsteer_mipi_lvds1>;
+ clocks =
+ <&clk IMX8QXP_MIPI1_DSI_PHY_CLK>,
+ <&clk IMX8QXP_MIPI1_DSI_TX_ESC_CLK>,
+ <&clk IMX8QXP_MIPI1_DSI_RX_ESC_CLK>;
+ clock-names = "phy_ref", "tx_esc", "rx_esc";
+ assigned-clocks =
+ <&clk IMX8QXP_MIPI1_DSI_PHY_SEL>,
+ <&clk IMX8QXP_MIPI1_DSI_TX_ESC_SEL>,
+ <&clk IMX8QXP_MIPI1_DSI_RX_ESC_SEL>,
+ <&clk IMX8QXP_MIPI1_DSI_TX_ESC_CLK>,
+ <&clk IMX8QXP_MIPI1_DSI_RX_ESC_CLK>;
+ assigned-clock-rates = <0>, <0>, <0>, <18000000>, <72000000>;
+ assigned-clock-parents =
+ <&clk IMX8QXP_MIPI1_DSI_PLL_DIV2_CLK>,
+ <&clk IMX8QXP_MIPI1_DSI_PLL_DIV2_CLK>,
+ <&clk IMX8QXP_MIPI1_DSI_PLL_DIV2_CLK>;
+ power-domains = <&pd_mipi_dsi1>;
+ phys = <&mipi_dsi_phy2>;
+ phy-names = "dphy";
+ status = "disabled";
+
+ port@0 {
+ mipi_dsi_bridge2_in: endpoint {
+ remote-endpoint = <&mipi_dsi2_out>;
+ };
+ };
+ };
+
+ mipi_dsi2: mipi_dsi@56248000 {
+ compatible = "fsl,imx8qxp-mipi-dsi";
+ clocks =
+ <&clk IMX8QXP_MIPI1_PIXEL_CLK>,
+ <&clk IMX8QXP_MIPI1_BYPASS_CLK>,
+ <&clk IMX8QXP_MIPI1_DSI_PHY_CLK>;
+ clock-names = "pixel", "bypass", "phy_ref";
+ power-domains = <&pd_mipi_dsi1>;
+ csr = <&mipi_dsi_csr2>;
+ phys = <&mipi_dsi_phy2>;
+ phy-names = "dphy";
+ status = "disabled";
+
+ port@0 {
+ mipi_dsi2_in: endpoint {
+ remote-endpoint = <&dpu_disp1_mipi_dsi>;
+ };
+ };
+
+ port@1 {
+ mipi_dsi2_out: endpoint {
+ remote-endpoint = <&mipi_dsi_bridge2_in>;
+ };
+ };
+ };
+
+ lvds_region2: lvds_region@56240000 {
+ compatible = "fsl,imx8qxp-lvds-region", "syscon";
+ reg = <0x0 0x56240000 0x0 0x10000>;
+ };
+
+ ldb2_phy: ldb_phy@56241000 {
+ compatible = "mixel,lvds-combo-phy";
+ reg = <0x0 0x56241000 0x0 0x100>, <0x0 0x56248000 0x0 0x1000>;
+ #phy-cells = <0>;
+ clocks = <&clk IMX8QXP_MIPI1_LVDS_PHY_CLK>;
+ clock-names = "phy";
+ status = "disabled";
+ };
+
+ ldb2: ldb@562410e0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx8qxp-ldb";
+ clocks = <&clk IMX8QXP_MIPI1_LVDS_PIXEL_CLK>,
+ <&clk IMX8QXP_MIPI1_LVDS_BYPASS_CLK>,
+ <&clk IMX8QXP_MIPI0_LVDS_PIXEL_CLK>,
+ <&clk IMX8QXP_MIPI0_LVDS_BYPASS_CLK>;
+ clock-names = "pixel", "bypass", "aux_pixel", "aux_bypass";
+ power-domains = <&pd_mipi_dsi_1_lvds>;
+ gpr = <&lvds_region2>;
+ aux-gpr = <&lvds_region1>;
+ status = "disabled";
+
+ lvds-channel@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0>;
+ phys = <&ldb2_phy>, <&ldb1_phy>;
+ phy-names = "ldb_phy", "aux_ldb_phy";
+ status = "disabled";
+
+ port@0 {
+ reg = <0>;
+
+ ldb2_ch0: endpoint {
+ remote-endpoint = <&dpu_disp1_lvds1_ch0>;
+ };
+ };
+ };
+
+ lvds-channel@1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <1>;
+ phys = <&ldb2_phy>;
+ phy-names = "ldb_phy";
+ status = "disabled";
+
+ port@0 {
+ reg = <0>;
+
+ ldb2_ch1: endpoint {
+ remote-endpoint = <&dpu_disp1_lvds1_ch1>;
+ };
+ };
+ };
+ };
+
+ cameradev: camera {
+ compatible = "fsl,mxc-md", "simple-bus";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ isi_0: isi@58100000 {
+ compatible = "fsl,imx8-isi";
+ reg = <0x0 0x58100000 0x0 0x10000>;
+ interrupts = <0 297 0>;
+ interface = <2 0 2>; /* <Input MIPI_VCx Output>
+ Input: 0-DC0, 1-DC1, 2-MIPI CSI0, 3-MIPI CSI1, 4-HDMI, 5-MEM
+ VCx: 0-VC0, 1-VC1, 2-VC2, 3-VC3, MIPI CSI only
+ Output: 0-DC0, 1-DC1, 2-MEM */
+ clocks = <&clk IMX8QXP_IMG_PDMA_0_CLK>;
+ clock-names = "per";
+ assigned-clocks = <&clk IMX8QXP_IMG_PDMA_0_CLK>;
+ assigned-clock-rates = <600000000>;
+ power-domains =<&pd_isi_ch0>;
+ status = "disabled";
+ };
+
+ isi_1: isi@58110000 {
+ compatible = "fsl,imx8-isi";
+ reg = <0x0 0x58110000 0x0 0x10000>;
+ interrupts = <0 298 0>;
+ interface = <2 1 2>;
+ clocks = <&clk IMX8QXP_IMG_PDMA_1_CLK>;
+ clock-names = "per";
+ assigned-clocks = <&clk IMX8QXP_IMG_PDMA_1_CLK>;
+ assigned-clock-rates = <600000000>;
+ power-domains =<&pd_isi_ch1>;
+ status = "disabled";
+ };
+
+ isi_2: isi@58120000 {
+ compatible = "fsl,imx8-isi";
+ reg = <0x0 0x58120000 0x0 0x10000>;
+ interrupts = <0 299 0>;
+ interface = <2 2 2>;
+ clocks = <&clk IMX8QXP_IMG_PDMA_2_CLK>;
+ clock-names = "per";
+ assigned-clocks = <&clk IMX8QXP_IMG_PDMA_2_CLK>;
+ assigned-clock-rates = <600000000>;
+ power-domains =<&pd_isi_ch2>;
+ status = "disabled";
+ };
+
+ isi_3: isi@58130000 {
+ compatible = "fsl,imx8-isi";
+ reg = <0x0 0x58130000 0x0 0x10000>;
+ interrupts = <0 300 0>;
+ interface = <2 3 2>;
+ clocks = <&clk IMX8QXP_IMG_PDMA_3_CLK>;
+ clock-names = "per";
+ assigned-clocks = <&clk IMX8QXP_IMG_PDMA_3_CLK>;
+ assigned-clock-rates = <600000000>;
+ power-domains =<&pd_isi_ch3>;
+ status = "disabled";
+ };
+
+ isi_4: isi@58140000 {
+ compatible = "fsl,imx8-isi";
+ reg = <0x0 0x58140000 0x0 0x10000>;
+ interrupts = <0 301 0>;
+ interface = <3 0 2>;
+ clocks = <&clk IMX8QXP_IMG_PDMA_4_CLK>;
+ clock-names = "per";
+ assigned-clocks = <&clk IMX8QXP_IMG_PDMA_4_CLK>;
+ assigned-clock-rates = <600000000>;
+ power-domains =<&pd_isi_ch4>;
+ status = "disabled";
+ };
+
+ isi_5: isi@58150000 {
+ compatible = "fsl,imx8-isi";
+ reg = <0x0 0x58150000 0x0 0x10000>;
+ interrupts = <0 302 0>;
+ interface = <3 1 2>;
+ clocks = <&clk IMX8QXP_IMG_PDMA_5_CLK>;
+ clock-names = "per";
+ assigned-clocks = <&clk IMX8QXP_IMG_PDMA_5_CLK>;
+ assigned-clock-rates = <600000000>;
+ power-domains =<&pd_isi_ch5>;
+ status = "disabled";
+ };
+
+ isi_6: isi@58160000 {
+ compatible = "fsl,imx8-isi";
+ reg = <0x0 0x58160000 0x0 0x10000>;
+ interrupts = <0 303 0>;
+ interface = <3 2 2>;
+ clocks = <&clk IMX8QXP_IMG_PDMA_6_CLK>;
+ clock-names = "per";
+ assigned-clocks = <&clk IMX8QXP_IMG_PDMA_6_CLK>;
+ assigned-clock-rates = <600000000>;
+ power-domains =<&pd_isi_ch6>;
+ status = "disabled";
+ };
+
+ isi_7: isi@58170000 {
+ compatible = "fsl,imx8-isi";
+ reg = <0x0 0x58170000 0x0 0x10000>;
+ interrupts = <0 304 0>;
+ interface = <3 3 2>;
+ clocks = <&clk IMX8QXP_IMG_PDMA_7_CLK>;
+ clock-names = "per";
+ assigned-clocks = <&clk IMX8QXP_IMG_PDMA_7_CLK>;
+ assigned-clock-rates = <600000000>;
+ power-domains =<&pd_isi_ch7>;
+ status = "disabled";
+ };
+
+ mipi_csi_0: csi@58227000 {
+ compatible = "fsl,mxc-mipi-csi2";
+ reg = <0x0 0x58227000 0x0 0x1000>, /* CSI0 Controler base addr */
+ <0x0 0x58221000 0x0 0x1000>; /* CSI0 Subsystem CSR base addr */
+ interrupts = <10 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-parent = <&irqsteer_csi>;
+ clocks = <&clk IMX8QXP_CLK_DUMMY>,
+ <&clk IMX8QXP_CSI0_CORE_CLK>,
+ <&clk IMX8QXP_CSI0_ESC_CLK>,
+ <&clk IMX8QXP_IMG_PXL_LINK_CSI0_CLK>;
+ clock-names = "clk_apb", "clk_core", "clk_esc", "clk_pxl";
+ assigned-clocks = <&clk IMX8QXP_CSI0_CORE_CLK>,
+ <&clk IMX8QXP_CSI0_ESC_CLK>;
+ assigned-clock-rates = <360000000>, <72000000>;
+ power-domains = <&pd_mipi_csi>;
+ status = "disabled";
+ };
+
+ parallel_csi: pcsi@58261000 {
+ compatible = "fsl,mxc-parallel-csi";
+ reg = <0x0 0x58261000 0x0 0x1000>;
+ clocks = <&clk IMX8QXP_PARALLEL_CSI_PIXEL_CLK>,
+ <&clk IMX8QXP_PARALLEL_CSI_IPG_CLK>,
+ <&clk IMX8QXP_PARALLEL_CSI_CLK_SEL>,
+ <&clk IMX8QXP_PARALLEL_CSI_PER_CLK_DIV>,
+ <&clk IMX8QXP_PARALLEL_CSI_CLK_DPLL>;
+ clock-names = "pixel", "ipg", "sel", "div", "dpll";
+ assigned-clocks = <&clk IMX8QXP_PARALLEL_CSI_CLK_SEL>,
+ <&clk IMX8QXP_PARALLEL_CSI_PER_CLK_DIV>;
+ assigned-clock-parents = <&clk IMX8QXP_PARALLEL_CSI_CLK_DPLL>;
+ assigned-clock-rates = <0>, <160000000>; /* 160MHz */
+ power-domains = <&pd_parallel_csi>;
+ status = "disabled";
+ };
+
+ jpegdec: jpegdec@58400000 {
+ compatible = "fsl,imx8-jpgdec";
+ reg = <0x0 0x58400000 0x0 0x00040020 >;
+ interrupts = <GIC_SPI 309 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8QXP_IMG_JPEG_DEC_IPG_CLK >,
+ <&clk IMX8QXP_IMG_JPEG_DEC_CLK >;
+ clock-names = "ipg", "per";
+ assigned-clocks = <&clk IMX8QXP_IMG_JPEG_DEC_IPG_CLK >,
+ <&clk IMX8QXP_IMG_JPEG_DEC_CLK >;
+ assigned-clock-rates = <200000000>;
+ power-domains =<&pd_jpgdec>;
+ status = "okay";
+ };
+
+ jpegenc: jpegenc@58450000 {
+ compatible = "fsl,imx8-jpgenc";
+ reg = <0x0 0x58450000 0x0 0x00240020 >;
+ interrupts = <GIC_SPI 305 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8QXP_IMG_JPEG_ENC_IPG_CLK >,
+ <&clk IMX8QXP_IMG_JPEG_ENC_CLK >;
+ clock-names = "ipg", "per";
+ assigned-clocks = <&clk IMX8QXP_IMG_JPEG_ENC_IPG_CLK >,
+ <&clk IMX8QXP_IMG_JPEG_ENC_CLK >;
+ assigned-clock-rates = <200000000>;
+ power-domains =<&pd_jpgenc>;
+ status = "okay";
+ };
+ };
+
+ i2c_rpbus_1: i2c-rpbus-1 {
+ compatible = "fsl,i2c-rpbus";
+ status = "disabled";
+ };
+
+ i2c_rpbus_5: i2c-rpbus-5 {
+ compatible = "fsl,i2c-rpbus";
+ status = "disabled";
+ };
+
+ i2c_rpbus_12: i2c-rpbus-12 {
+ compatible = "fsl,i2c-rpbus";
+ status = "disabled";
+ };
+
+ i2c_rpbus_13: i2c-rpbus-13 {
+ compatible = "fsl,i2c-rpbus";
+ status = "disabled";
+ };
+
+ i2c_rpbus_14: i2c-rpbus-14 {
+ compatible = "fsl,i2c-rpbus";
+ status = "disabled";
+ };
+
+ i2c_rpbus_15: i2c-rpbus-15 {
+ compatible = "fsl,i2c-rpbus";
+ status = "disabled";
+ };
+
+ pwm_mipi_lvds1: pwm@56244000 {
+ compatible = "fsl,imx8qxp-pwm", "fsl,imx27-pwm";
+ reg = <0x0 0x56244000 0 0x1000>;
+ clocks = <&clk IMX8QXP_MIPI1_PWM_IPG_CLK>,
+ <&clk IMX8QXP_MIPI1_PWM_CLK>,
+ <&clk IMX8QXP_MIPI1_PWM_32K_CLK>;
+ clock-names = "ipg", "per", "32k";
+ assigned-clocks = <&clk IMX8QXP_MIPI1_PWM_CLK>;
+ assigned-clock-rates = <24000000>;
+ #pwm-cells = <2>;
+ power-domains = <&pd_mipi_1_pwm0>;
+ status = "disabled";
+ };
+
+ i2c0_mipi_lvds1: i2c@56246000 {
+ compatible = "fsl,imx8qxp-lpi2c", "fsl,imx8qm-lpi2c";
+ reg = <0x0 0x56246000 0x0 0x1000>;
+ interrupts = <8 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-parent = <&irqsteer_mipi_lvds1>;
+ clocks = <&clk IMX8QXP_MIPI1_I2C0_CLK>,
+ <&clk IMX8QXP_MIPI1_I2C0_IPG_CLK>;
+ clock-names = "per", "ipg";
+ assigned-clocks = <&clk IMX8QXP_MIPI1_I2C0_DIV>;
+ assigned-clock-rates = <24000000>;
+ power-domains = <&pd_mipi_dsi_1_i2c0>;
+ status = "disabled";
+ };
+
+ adc0: adc@5a880000 {
+ compatible = "fsl,imx8qxp-adc";
+ reg = <0x0 0x5a880000 0x0 0x10000>;
+ interrupts = <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-parent = <&gic>;
+ clocks = <&clk IMX8QXP_ADC0_CLK>,
+ <&clk IMX8QXP_ADC0_IPG_CLK>;
+ clock-names = "per", "ipg";
+ assigned-clocks = <&clk IMX8QXP_ADC0_CLK>;
+ assigned-clock-rates = <24000000>;
+ power-domains = <&pd_dma_adc0>;
+ status = "disabled";
+ };
+
+ i2c0: i2c@5a800000 {
+ compatible = "fsl,imx8qm-lpi2c", "fsl,imx7ulp-lpi2c";
+ reg = <0x0 0x5a800000 0x0 0x4000>;
+ interrupts = <GIC_SPI 220 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-parent = <&gic>;
+ clocks = <&clk IMX8QXP_I2C0_CLK>,
+ <&clk IMX8QXP_I2C0_IPG_CLK>;
+ clock-names = "per", "ipg";
+ assigned-clocks = <&clk IMX8QXP_I2C0_CLK>;
+ assigned-clock-rates = <24000000>;
+ power-domains = <&pd_dma_lpi2c0>;
+ status = "disabled";
+ };
+
+ i2c1: i2c@5a810000 {
+ compatible = "fsl,imx8qm-lpi2c", "fsl,imx7ulp-lpi2c";
+ reg = <0x0 0x5a810000 0x0 0x4000>;
+ interrupts = <GIC_SPI 221 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-parent = <&gic>;
+ clocks = <&clk IMX8QXP_I2C1_CLK>,
+ <&clk IMX8QXP_I2C1_IPG_CLK>;
+ clock-names = "per", "ipg";
+ assigned-clocks = <&clk IMX8QXP_I2C1_CLK>;
+ assigned-clock-rates = <24000000>;
+ power-domains = <&pd_dma_lpi2c1>;
+ status = "disabled";
+ };
+
+ i2c2: i2c@5a820000 {
+ compatible = "fsl,imx8qm-lpi2c", "fsl,imx7ulp-lpi2c";
+ reg = <0x0 0x5a820000 0x0 0x4000>;
+ interrupts = <GIC_SPI 222 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-parent = <&gic>;
+ clocks = <&clk IMX8QXP_I2C2_CLK>,
+ <&clk IMX8QXP_I2C2_IPG_CLK>;
+ clock-names = "per", "ipg";
+ assigned-clocks = <&clk IMX8QXP_I2C2_CLK>;
+ assigned-clock-rates = <24000000>;
+ power-domains = <&pd_dma_lpi2c2>;
+ status = "disabled";
+ };
+
+ i2c3: i2c@5a830000 {
+ compatible = "fsl,imx8qm-lpi2c", "fsl,imx7ulp-lpi2c";
+ reg = <0x0 0x5a830000 0x0 0x4000>;
+ interrupts = <GIC_SPI 223 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-parent = <&gic>;
+ clocks = <&clk IMX8QXP_I2C3_CLK>,
+ <&clk IMX8QXP_I2C3_IPG_CLK>;
+ clock-names = "per", "ipg";
+ assigned-clocks = <&clk IMX8QXP_I2C3_CLK>;
+ assigned-clock-rates = <24000000>;
+ power-domains = <&pd_dma_lpi2c3>;
+ status = "disabled";
+ };
+
+ usbmisc1: usbmisc@5b0d0200 {
+ #index-cells = <1>;
+ compatible = "fsl,imx7d-usbmisc", "fsl,imx6q-usbmisc";
+ reg = <0x0 0x5b0d0200 0x0 0x200>;
+ };
+
+ usbphy1: usbphy@0x5b100000 {
+ compatible = "fsl,imx8qm-usbphy", "fsl,imx7ulp-usbphy", "fsl,imx6ul-usbphy", "fsl,imx23-usbphy";
+ reg = <0x0 0x5b100000 0x0 0x1000>;
+ clocks = <&clk IMX8QXP_USB2_PHY_IPG_CLK>;
+ power-domains = <&pd_conn_usbotg0_phy>;
+ };
+
+ usbotg1: usb@5b0d0000 {
+ compatible = "fsl,imx8qm-usb", "fsl,imx27-usb";
+ reg = <0x0 0x5b0d0000 0x0 0x200>;
+ interrupt-parent = <&wu>;
+ interrupts = <GIC_SPI 267 IRQ_TYPE_LEVEL_HIGH>;
+ fsl,usbphy = <&usbphy1>;
+ fsl,usbmisc = <&usbmisc1 0>;
+ clocks = <&clk IMX8QXP_USB2_OH_AHB_CLK>;
+ ahb-burst-config = <0x0>;
+ tx-burst-size-dword = <0x10>;
+ rx-burst-size-dword = <0x10>;
+ #stream-id-cells = <1>;
+ power-domains = <&pd_conn_usbotg0>;
+ status = "disabled";
+ };
+
+ flexcan1: can@5a8d0000 {
+ compatible = "fsl,imx8qxp-flexcan", "fsl,imx8qm-flexcan";
+ reg = <0x0 0x5a8d0000 0x0 0x10000>;
+ interrupts = <GIC_SPI 235 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-parent = <&wu>;
+ clocks = <&clk IMX8QXP_CAN0_IPG_CLK>,
+ <&clk IMX8QXP_CAN0_CLK>;
+ clock-names = "ipg", "per";
+ assigned-clocks = <&clk IMX8QXP_CAN0_CLK>;
+ assigned-clock-rates = <40000000>;
+ power-domains = <&pd_dma_flexcan0>;
+ /* SLSlice[4] */
+ clk-src = <0>;
+ status = "disabled";
+ };
+
+ flexcan2: can@5a8e0000 {
+ compatible = "fsl,imx8qxp-flexcan", "fsl,imx8qm-flexcan";
+ reg = <0x0 0x5a8e0000 0x0 0x10000>;
+ interrupts = <GIC_SPI 236 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-parent = <&wu>;
+ /* CAN0 clock and PD is shared among all CAN instances */
+ clocks = <&clk IMX8QXP_CAN0_IPG_CLK>,
+ <&clk IMX8QXP_CAN0_CLK>;
+ clock-names = "ipg", "per";
+ assigned-clocks = <&clk IMX8QXP_CAN0_CLK>;
+ assigned-clock-rates = <40000000>;
+ power-domains = <&pd_dma_flexcan1>;
+ /* SLSlice[4] */
+ clk-src = <0>;
+ status = "disabled";
+ };
+
+ flexcan3: can@5a8f0000 {
+ compatible = "fsl,imx8qxp-flexcan", "fsl,imx8qm-flexcan";
+ reg = <0x0 0x5a8f0000 0x0 0x10000>;
+ interrupts = <GIC_SPI 237 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-parent = <&wu>;
+ /* CAN0 clock and PD is shared among all CAN instances */
+ clocks = <&clk IMX8QXP_CAN0_IPG_CLK>,
+ <&clk IMX8QXP_CAN0_CLK>;
+ clock-names = "ipg", "per";
+ assigned-clocks = <&clk IMX8QXP_CAN0_CLK>;
+ assigned-clock-rates = <40000000>;
+ power-domains = <&pd_dma_flexcan2>;
+ /* SLSlice[4] */
+ clk-src = <0>;
+ status = "disabled";
+ };
+
+ dma_apbh: dma-apbh@5b810000 {
+ compatible = "fsl,imx28-dma-apbh";
+ reg = <0x0 0x5b810000 0x0 0x2000>;
+ interrupts = <GIC_SPI 274 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 274 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 274 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 274 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "gpmi0", "gpmi1", "gpmi2", "gpmi3";
+ #dma-cells = <1>;
+ dma-channels = <4>;
+ clocks = <&clk IMX8QXP_APBHDMA_CLK>;
+ power-domains = <&pd_conn_nand>;
+ };
+
+ gpmi: gpmi-nand@5b812000{
+ compatible = "fsl,imx8qxp-gpmi-nand";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x0 0x5b812000 0x0 0x2000>, <0x0 0x5b814000 0x0 0x2000>;
+ reg-names = "gpmi-nand", "bch";
+ interrupts = <GIC_SPI 272 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "bch";
+ clocks = <&clk IMX8QXP_GPMI_BCH_IO_CLK>,
+ <&clk IMX8QXP_GPMI_APB_CLK>,
+ <&clk IMX8QXP_GPMI_BCH_CLK>,
+ <&clk IMX8QXP_GPMI_APB_BCH_CLK>;
+ clock-names = "gpmi_io", "gpmi_apb", "gpmi_bch", "gpmi_apb_bch";
+ dmas = <&dma_apbh 0>;
+ dma-names = "rx-tx";
+ power-domains = <&pd_conn_nand>;
+ assigned-clocks = <&clk IMX8QXP_GPMI_BCH_IO_CLK>;
+ assigned-clock-rates = <50000000>;
+ status = "disabled";
+ };
+
+ usbphynop1: usbphynop1 {
+ compatible = "usb-nop-xceiv";
+ clocks = <&clk IMX8QXP_USB3_PHY_CLK>;
+ clock-names = "main_clk";
+ power-domains = <&pd_conn_usb2_phy>;
+ };
+
+ usbotg3: usb3@5b110000 {
+ compatible = "Cadence,usb3";
+ reg = <0x0 0x5B110000 0x0 0x10000>,
+ <0x0 0x5B130000 0x0 0x10000>,
+ <0x0 0x5B140000 0x0 0x10000>,
+ <0x0 0x5B160000 0x0 0x40000>,
+ <0x0 0x5B120000 0x0 0x10000>;
+ interrupt-parent = <&wu>;
+ interrupts = <GIC_SPI 271 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8QXP_USB3_LPM_CLK>,
+ <&clk IMX8QXP_USB3_BUS_CLK>,
+ <&clk IMX8QXP_USB3_ACLK>,
+ <&clk IMX8QXP_USB3_IPG_CLK>,
+ <&clk IMX8QXP_USB3_CORE_PCLK>;
+ clock-names = "usb3_lpm_clk", "usb3_bus_clk", "usb3_aclk",
+ "usb3_ipg_clk", "usb3_core_pclk";
+ power-domains = <&pd_conn_usb2>;
+ cdns3,usbphy = <&usbphynop1>;
+ status = "disabled";
+ };
+
+ wu: wu {
+ compatible = "fsl,imx8-wu";
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ interrupt-parent = <&gic>;
+ };
+
+ gpio0: gpio@5d080000 {
+ compatible = "fsl,imx8qm-gpio", "fsl,imx35-gpio";
+ reg = <0x0 0x5d080000 0x0 0x10000>;
+ interrupts = <GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ power-domains = <&pd_lsio_gpio0>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio1: gpio@5d090000 {
+ compatible = "fsl,imx8qm-gpio", "fsl,imx35-gpio";
+ reg = <0x0 0x5d090000 0x0 0x10000>;
+ interrupts = <GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ power-domains = <&pd_lsio_gpio1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio2: gpio@5d0a0000 {
+ compatible = "fsl,imx8qm-gpio", "fsl,imx35-gpio";
+ reg = <0x0 0x5d0a0000 0x0 0x10000>;
+ interrupts = <GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ power-domains = <&pd_lsio_gpio2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio3: gpio@5d0b0000 {
+ compatible = "fsl,imx8qm-gpio", "fsl,imx35-gpio";
+ reg = <0x0 0x5d0b0000 0x0 0x10000>;
+ interrupts = <GIC_SPI 139 IRQ_TYPE_LEVEL_HIGH>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ power-domains = <&pd_lsio_gpio3>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio4: gpio@5d0c0000 {
+ compatible = "fsl,imx8qm-gpio", "fsl,imx35-gpio";
+ reg = <0x0 0x5d0c0000 0x0 0x10000>;
+ interrupts = <GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ power-domains = <&pd_lsio_gpio4>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio5: gpio@5d0d0000 {
+ compatible = "fsl,imx8qm-gpio", "fsl,imx35-gpio";
+ reg = <0x0 0x5d0d0000 0x0 0x10000>;
+ interrupts = <GIC_SPI 141 IRQ_TYPE_LEVEL_HIGH>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ power-domains = <&pd_lsio_gpio5>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio6: gpio@5d0e0000 {
+ compatible = "fsl,imx8qm-gpio", "fsl,imx35-gpio";
+ reg = <0x0 0x5d0e0000 0x0 0x10000>;
+ interrupts = <GIC_SPI 142 IRQ_TYPE_LEVEL_HIGH>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ power-domains = <&pd_lsio_gpio6>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio7: gpio@5d0f0000 {
+ compatible = "fsl,imx8qm-gpio", "fsl,imx35-gpio";
+ reg = <0x0 0x5d0f0000 0x0 0x10000>;
+ interrupts = <GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ power-domains = <&pd_lsio_gpio7>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio0_mipi_csi0: gpio@58222000 {
+ compatible = "fsl,imx8qm-gpio", "fsl,imx35-gpio";
+ reg = <0x0 0x58222000 0x0 0x1000>;
+ interrupts = <0 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-parent = <&irqsteer_csi>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ power-domains = <&pd_mipi_csi>;
+ };
+
+ gpu_3d0: gpu@53100000 {
+ compatible = "fsl,imx8-gpu";
+ reg = <0x0 0x53100000 0 0x40000>;
+ interrupts = <GIC_SPI 64 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8QXP_GPU0_CORE_CLK>, <&clk IMX8QXP_GPU0_SHADER_CLK>;
+ clock-names = "core", "shader";
+ assigned-clocks = <&clk IMX8QXP_GPU0_CORE_CLK>, <&clk IMX8QXP_GPU0_SHADER_CLK>;
+ assigned-clock-rates = <700000000>, <850000000>;
+ power-domains = <&pd_gpu0>;
+ status = "disabled";
+ };
+
+ imx8_gpu_ss: imx8_gpu_ss {
+ compatible = "fsl,imx8qxp-gpu", "fsl,imx8-gpu-ss";
+ cores = <&gpu_3d0>;
+ reg = <0x0 0x80000000 0x0 0x80000000>, <0x0 0x0 0x0 0x10000000>;
+ reg-names = "phys_baseaddr", "contiguous_mem";
+ status = "disabled";
+ };
+
+ ddr_pmu0: ddr_pmu@5c020000 {
+ compatible = "fsl,imx8-ddr-pmu";
+ reg = <0x0 0x5c020000 0x0 0x10000>;
+ interrupt-parent = <&gic>;
+ interrupts = <GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ lpspi0: lpspi@5a000000 {
+ compatible = "fsl,imx7ulp-spi";
+ reg = <0x0 0x5a000000 0x0 0x10000>;
+ interrupts = <GIC_SPI 216 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-parent = <&gic>;
+ clocks = <&clk IMX8QXP_SPI0_CLK>,
+ <&clk IMX8QXP_SPI0_IPG_CLK>;
+ clock-names = "per", "ipg";
+ assigned-clocks = <&clk IMX8QXP_SPI0_CLK>;
+ assigned-clock-rates = <20000000>;
+ power-domains = <&pd_dma2_chan1>;
+ dma-names = "tx","rx";
+ dmas = <&edma2 1 0 0>, <&edma2 0 0 1>;
+ status = "disabled";
+ };
+
+ lpspi2: lpspi@5a020000 {
+ compatible = "fsl,imx7ulp-spi";
+ reg = <0x0 0x5a020000 0x0 0x10000>;
+ interrupts = <GIC_SPI 218 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-parent = <&gic>;
+ clocks = <&clk IMX8QXP_SPI2_CLK>,
+ <&clk IMX8QXP_SPI2_IPG_CLK>;
+ clock-names = "per", "ipg";
+ assigned-clocks = <&clk IMX8QXP_SPI2_CLK>;
+ assigned-clock-rates = <20000000>;
+ power-domains = <&pd_dma2_chan5>;
+ dma-names = "tx","rx";
+ dmas = <&edma2 5 0 0>, <&edma2 4 0 1>;
+ status = "disabled";
+ };
+
+ lpuart0: serial@5a060000 {
+ compatible = "fsl,imx8qm-lpuart";
+ reg = <0x0 0x5a060000 0x0 0x1000>;
+ interrupts = <GIC_SPI 345 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-parent = <&wu>;
+ clocks = <&clk IMX8QXP_UART0_CLK>,
+ <&clk IMX8QXP_UART0_IPG_CLK>;
+ clock-names = "per", "ipg";
+ assigned-clocks = <&clk IMX8QXP_UART0_CLK>;
+ assigned-clock-rates = <80000000>;
+ power-domains = <&pd_dma_lpuart0>;
+ status = "disabled";
+ };
+
+ lpuart1: serial@5a070000 {
+ compatible = "fsl,imx8qm-lpuart";
+ reg = <0x0 0x5a070000 0x0 0x1000>;
+ interrupts = <GIC_SPI 346 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-parent = <&wu>;
+ clocks = <&clk IMX8QXP_UART1_CLK>,
+ <&clk IMX8QXP_UART1_IPG_CLK>;
+ clock-names = "per", "ipg";
+ assigned-clocks = <&clk IMX8QXP_UART1_CLK>;
+ assigned-clock-rates = <80000000>;
+ power-domains = <&pd_dma2_chan11>;
+ dma-names = "tx","rx";
+ dmas = <&edma2 11 0 0>,
+ <&edma2 10 0 1>;
+ status = "disabled";
+ };
+
+ lpuart2: serial@5a080000 {
+ compatible = "fsl,imx8qm-lpuart";
+ reg = <0x0 0x5a080000 0x0 0x1000>;
+ interrupts = <GIC_SPI 347 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-parent = <&wu>;
+ clocks = <&clk IMX8QXP_UART2_CLK>,
+ <&clk IMX8QXP_UART2_IPG_CLK>;
+ clock-names = "per", "ipg";
+ assigned-clocks = <&clk IMX8QXP_UART2_CLK>;
+ assigned-clock-rates = <80000000>;
+ power-domains = <&pd_dma2_chan13>;
+ dma-names = "tx","rx";
+ dmas = <&edma2 13 0 0>,
+ <&edma2 12 0 1>;
+ status = "disabled";
+ };
+
+ lpuart3: serial@5a090000 {
+ compatible = "fsl,imx8qm-lpuart";
+ reg = <0x0 0x5a090000 0x0 0x1000>;
+ interrupts = <GIC_SPI 348 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-parent = <&wu>;
+ clocks = <&clk IMX8QXP_UART3_CLK>,
+ <&clk IMX8QXP_UART3_IPG_CLK>;
+ clock-names = "per", "ipg";
+ assigned-clocks = <&clk IMX8QXP_UART3_CLK>;
+ assigned-clock-rates = <80000000>;
+ power-domains = <&pd_dma3_chan15>;
+ dma-names = "tx","rx";
+ dmas = <&edma2 15 0 0>,
+ <&edma2 14 0 1>;
+ status = "disabled";
+ };
+
+ edma2: dma-controller@5a1f0000 {
+ compatible = "fsl,imx8qm-edma";
+ reg = <0x0 0x5a200000 0x0 0x10000>, /* channel0 LPSPI0 rx */
+ <0x0 0x5a210000 0x0 0x10000>, /* channel1 LPSPI0 tx */
+ <0x0 0x5a220000 0x0 0x10000>, /* channel2 LPSPI1 rx */
+ <0x0 0x5a230000 0x0 0x10000>, /* channel3 LPSPI1 tx */
+ <0x0 0x5a240000 0x0 0x10000>, /* channel4 LPSPI2 rx */
+ <0x0 0x5a250000 0x0 0x10000>, /* channel5 LPSPI2 tx */
+ <0x0 0x5a260000 0x0 0x10000>, /* channel6 LPSPI3 rx */
+ <0x0 0x5a270000 0x0 0x10000>, /* channel7 LPSPI3 tx */
+ <0x0 0x5a280000 0x0 0x10000>, /* channel8 UART0 rx */
+ <0x0 0x5a290000 0x0 0x10000>, /* channel9 UART0 tx */
+ <0x0 0x5a2a0000 0x0 0x10000>, /* channel10 UART1 rx */
+ <0x0 0x5a2b0000 0x0 0x10000>, /* channel11 UART1 tx */
+ <0x0 0x5a2c0000 0x0 0x10000>, /* channel12 UART2 rx */
+ <0x0 0x5a2d0000 0x0 0x10000>, /* channel13 UART2 tx */
+ <0x0 0x5a2e0000 0x0 0x10000>, /* channel14 UART3 rx */
+ <0x0 0x5a2f0000 0x0 0x10000>; /* channel15 UART3 tx */
+ #dma-cells = <3>;
+ dma-channels = <16>;
+ interrupts = <GIC_SPI 416 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 417 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 418 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 419 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 420 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 421 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 422 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 423 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 434 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 435 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 436 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 437 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 438 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 439 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 440 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 441 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "edma2-chan0-rx", "edma2-chan1-tx",
+ "edma2-chan2-rx", "edma2-chan3-tx",
+ "edma2-chan4-rx", "edma2-chan5-tx",
+ "edma2-chan6-rx", "edma2-chan7-tx",
+ "edma2-chan8-rx", "edma2-chan9-tx",
+ "edma2-chan10-rx", "edma2-chan11-tx",
+ "edma2-chan12-rx", "edma2-chan13-tx",
+ "edma2-chan14-rx", "edma2-chan15-tx";
+ status = "okay";
+ };
+
+ edma0: dma-controller@591F0000 {
+ compatible = "fsl,imx8qm-edma";
+ reg = <0x0 0x59200000 0x0 0x10000>, /* asrc0 */
+ <0x0 0x59210000 0x0 0x10000>,
+ <0x0 0x59220000 0x0 0x10000>,
+ <0x0 0x59230000 0x0 0x10000>,
+ <0x0 0x59240000 0x0 0x10000>,
+ <0x0 0x59250000 0x0 0x10000>,
+ <0x0 0x59260000 0x0 0x10000>, /* esai0 rx */
+ <0x0 0x59270000 0x0 0x10000>, /* esai0 tx */
+ <0x0 0x59280000 0x0 0x10000>, /* spdif0 rx */
+ <0x0 0x59290000 0x0 0x10000>, /* spdif0 tx */
+ <0x0 0x592c0000 0x0 0x10000>, /* sai0 rx */
+ <0x0 0x592d0000 0x0 0x10000>, /* sai0 tx */
+ <0x0 0x592e0000 0x0 0x10000>, /* sai1 rx */
+ <0x0 0x592f0000 0x0 0x10000>, /* sai1 tx */
+ <0x0 0x59350000 0x0 0x10000>,
+ <0x0 0x59370000 0x0 0x10000>;
+ #dma-cells = <3>;
+ shared-interrupt;
+ dma-channels = <16>;
+ interrupts = <GIC_SPI 374 IRQ_TYPE_LEVEL_HIGH>, /* asrc 0 */
+ <GIC_SPI 375 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 376 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 377 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 378 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 379 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 410 IRQ_TYPE_LEVEL_HIGH>, /* esai0 */
+ <GIC_SPI 410 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 457 IRQ_TYPE_LEVEL_HIGH>, /* spdif0 */
+ <GIC_SPI 459 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 315 IRQ_TYPE_LEVEL_HIGH>, /* sai0 */
+ <GIC_SPI 315 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 317 IRQ_TYPE_LEVEL_HIGH>, /* sai1 */
+ <GIC_SPI 317 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 391 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 393 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "edma0-chan0-rx", "edma0-chan1-rx", /* asrc0 */
+ "edma0-chan2-rx", "edma0-chan3-tx",
+ "edma0-chan4-tx", "edma0-chan5-tx",
+ "edma0-chan6-rx", "edma0-chan7-tx", /* esai0 */
+ "edma0-chan8-rx", "edma0-chan9-tx", /* spdif0 */
+ "edma0-chan12-rx", "edma0-chan13-tx", /* sai0 */
+ "edma0-chan14-rx", "edma0-chan15-tx", /* sai1 */
+ "edma0-chan21-tx", /* gpt5 */
+ "edma0-chan23-rx"; /* gpt7 */
+ status = "okay";
+ };
+
+ edma1: dma-controller@599F0000 {
+ compatible = "fsl,imx8qm-edma";
+ reg = <0x0 0x59A00000 0x0 0x10000>, /* asrc1 */
+ <0x0 0x59A10000 0x0 0x10000>,
+ <0x0 0x59A20000 0x0 0x10000>,
+ <0x0 0x59A30000 0x0 0x10000>,
+ <0x0 0x59A40000 0x0 0x10000>,
+ <0x0 0x59A50000 0x0 0x10000>,
+ <0x0 0x59A80000 0x0 0x10000>, /* sai4 rx */
+ <0x0 0x59A90000 0x0 0x10000>, /* sai4 tx */
+ <0x0 0x59AA0000 0x0 0x10000>; /* sai5 tx */
+ #dma-cells = <3>;
+ shared-interrupt;
+ dma-channels = <9>;
+ interrupts = <GIC_SPI 382 IRQ_TYPE_LEVEL_HIGH>, /* asrc 1 */
+ <GIC_SPI 383 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 384 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 385 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 386 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 387 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 330 IRQ_TYPE_LEVEL_HIGH>, /* sai4 */
+ <GIC_SPI 330 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 332 IRQ_TYPE_LEVEL_HIGH>; /* sai5 */
+ interrupt-names = "edma1-chan0-rx", "edma1-chan1-rx", /* asrc1 */
+ "edma1-chan2-rx", "edma1-chan3-tx",
+ "edma1-chan4-tx", "edma1-chan5-tx",
+ "edma1-chan8-rx", "edma1-chan9-tx", /* sai4 */
+ "edma1-chan10-tx"; /* sai5 */
+ status = "okay";
+ };
+
+ acm: acm@59e00000 {
+ compatible = "nxp,imx8qm-acm";
+ reg = <0x0 0x59e00000 0x0 0x1D0000>;
+ status = "disabled";
+ };
+
+ sai0: sai@59040000 {
+ compatible = "fsl,imx8qm-sai";
+ reg = <0x0 0x59040000 0x0 0x10000>;
+ interrupts = <GIC_SPI 314 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8QXP_AUD_SAI_0_IPG>,
+ <&clk IMX8QXP_CLK_DUMMY>,
+ <&clk IMX8QXP_AUD_SAI_0_MCLK>,
+ <&clk IMX8QXP_CLK_DUMMY>,
+ <&clk IMX8QXP_CLK_DUMMY>;
+ clock-names = "bus", "mclk0", "mclk1", "mclk2", "mclk3";
+ dma-names = "rx", "tx";
+ dmas = <&edma0 12 0 1>, <&edma0 13 0 0>;
+ status = "disabled";
+ power-domains = <&pd_sai0>;
+ };
+
+ sai1: sai@59050000 {
+ compatible = "fsl,imx8qm-sai";
+ reg = <0x0 0x59050000 0x0 0x10000>;
+ interrupts = <GIC_SPI 316 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8QXP_AUD_SAI_1_IPG>,
+ <&clk IMX8QXP_CLK_DUMMY>,
+ <&clk IMX8QXP_AUD_SAI_1_MCLK>,
+ <&clk IMX8QXP_CLK_DUMMY>,
+ <&clk IMX8QXP_CLK_DUMMY>;
+ clock-names = "bus", "mclk0", "mclk1", "mclk2", "mclk3";
+ dma-names = "rx", "tx";
+ dmas = <&edma0 14 0 1>, <&edma0 15 0 0>;
+ status = "disabled";
+ power-domains = <&pd_sai1>;
+ };
+
+ sai2: sai@59060000 {
+ compatible = "fsl,imx8qm-sai";
+ reg = <0x0 0x59060000 0x0 0x10000>;
+ interrupts = <GIC_SPI 318 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8QXP_AUD_SAI_2_IPG>,
+ <&clk IMX8QXP_CLK_DUMMY>,
+ <&clk IMX8QXP_AUD_SAI_2_MCLK>,
+ <&clk IMX8QXP_CLK_DUMMY>,
+ <&clk IMX8QXP_CLK_DUMMY>;
+ clock-names = "bus", "mclk0", "mclk1", "mclk2", "mclk3";
+ dma-names = "rx";
+ dmas = <&edma0 16 0 1>;
+ status = "disabled";
+ power-domains = <&pd_sai2>;
+ };
+
+ sai3: sai@59070000 {
+ compatible = "fsl,imx8qm-sai";
+ reg = <0x0 0x59070000 0x0 0x10000>;
+ interrupts = <GIC_SPI 323 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8QXP_AUD_SAI_3_IPG>,
+ <&clk IMX8QXP_CLK_DUMMY>,
+ <&clk IMX8QXP_AUD_SAI_3_MCLK>,
+ <&clk IMX8QXP_CLK_DUMMY>,
+ <&clk IMX8QXP_CLK_DUMMY>;
+ clock-names = "bus", "mclk0", "mclk1", "mclk2", "mclk3";
+ dma-names = "rx";
+ dmas = <&edma0 17 0 1>;
+ status = "disabled";
+ power-domains = <&pd_sai3>;
+ };
+
+ sai4: sai@59820000 {
+ compatible = "fsl,imx8qm-sai";
+ reg = <0x0 0x59820000 0x0 0x10000>;
+ interrupts = <GIC_SPI 329 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8QXP_AUD_SAI_4_IPG>,
+ <&clk IMX8QXP_CLK_DUMMY>,
+ <&clk IMX8QXP_AUD_SAI_4_MCLK>,
+ <&clk IMX8QXP_CLK_DUMMY>,
+ <&clk IMX8QXP_CLK_DUMMY>;
+ dmas = <&edma1 8 0 1>, <&edma1 9 0 0>;
+ clock-names = "bus", "mclk0", "mclk1", "mclk2", "mclk3";
+ dma-names = "rx", "tx";
+ status = "disabled";
+ power-domains = <&pd_sai4>;
+ };
+
+ sai5: sai@59830000 {
+ compatible = "fsl,imx8qm-sai";
+ reg = <0x0 0x59830000 0x0 0x10000>;
+ interrupts = <GIC_SPI 331 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8QXP_AUD_SAI_5_IPG>,
+ <&clk IMX8QXP_CLK_DUMMY>,
+ <&clk IMX8QXP_AUD_SAI_5_MCLK>,
+ <&clk IMX8QXP_CLK_DUMMY>,
+ <&clk IMX8QXP_CLK_DUMMY>;
+ clock-names = "bus", "mclk0", "mclk1", "mclk2", "mclk3";
+ dma-names = "tx";
+ dmas = <&edma1 10 0 0>;
+ status = "disabled";
+ power-domains = <&pd_sai5>;
+ };
+
+ amix: amix@59840000 {
+ compatible = "fsl,imx8qm-amix";
+ reg = <0x0 0x59840000 0x0 0x10000>;
+ clocks = <&clk IMX8QXP_AUD_AMIX_IPG>;
+ clock-names = "ipg";
+ power-domains = <&pd_amix>;
+ status = "disabled";
+ };
+
+ asrc0: asrc@59000000 {
+ compatible = "fsl,imx8qm-asrc0";
+ reg = <0x0 0x59000000 0x0 0x10000>;
+ interrupts = <GIC_SPI 372 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 373 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8QXP_AUD_ASRC_0_IPG>,
+ <&clk IMX8QXP_CLK_DUMMY>,
+ <&clk IMX8QXP_AUD_ACM_AUD_PLL_CLK0_CLK>,
+ <&clk IMX8QXP_AUD_ACM_AUD_PLL_CLK1_CLK>,
+ <&clk IMX8QXP_ACM_AUD_CLK0_SEL>,
+ <&clk IMX8QXP_ACM_AUD_CLK1_SEL>,
+ <&clk IMX8QXP_CLK_DUMMY>,
+ <&clk IMX8QXP_CLK_DUMMY>,
+ <&clk IMX8QXP_CLK_DUMMY>,
+ <&clk IMX8QXP_CLK_DUMMY>,
+ <&clk IMX8QXP_CLK_DUMMY>,
+ <&clk IMX8QXP_CLK_DUMMY>,
+ <&clk IMX8QXP_CLK_DUMMY>,
+ <&clk IMX8QXP_CLK_DUMMY>,
+ <&clk IMX8QXP_CLK_DUMMY>,
+ <&clk IMX8QXP_CLK_DUMMY>,
+ <&clk IMX8QXP_CLK_DUMMY>,
+ <&clk IMX8QXP_CLK_DUMMY>,
+ <&clk IMX8QXP_CLK_DUMMY>;
+ clock-names = "ipg", "mem",
+ "asrck_0", "asrck_1", "asrck_2", "asrck_3",
+ "asrck_4", "asrck_5", "asrck_6", "asrck_7",
+ "asrck_8", "asrck_9", "asrck_a", "asrck_b",
+ "asrck_c", "asrck_d", "asrck_e", "asrck_f",
+ "spba";
+ dmas = <&edma0 0 0 0>, <&edma0 1 0 0>, <&edma0 2 0 0>,
+ <&edma0 3 0 1>, <&edma0 4 0 1>, <&edma0 5 0 1>;
+ dma-names = "rxa", "rxb", "rxc",
+ "txa", "txb", "txc";
+ fsl,asrc-rate = <8000>;
+ fsl,asrc-width = <16>;
+ power-domains = <&pd_asrc0>;
+ status = "disabled";
+ };
+
+ asrc1: asrc@59800000 {
+ compatible = "fsl,imx8qm-asrc1";
+ reg = <0x0 0x59800000 0x0 0x10000>;
+ interrupts = <GIC_SPI 380 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 381 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8QXP_AUD_ASRC_1_IPG>,
+ <&clk IMX8QXP_CLK_DUMMY>,
+ <&clk IMX8QXP_AUD_ACM_AUD_PLL_CLK0_CLK>,
+ <&clk IMX8QXP_AUD_ACM_AUD_PLL_CLK1_CLK>,
+ <&clk IMX8QXP_ACM_AUD_CLK0_SEL>,
+ <&clk IMX8QXP_ACM_AUD_CLK1_SEL>,
+ <&clk IMX8QXP_CLK_DUMMY>,
+ <&clk IMX8QXP_CLK_DUMMY>,
+ <&clk IMX8QXP_CLK_DUMMY>,
+ <&clk IMX8QXP_CLK_DUMMY>,
+ <&clk IMX8QXP_CLK_DUMMY>,
+ <&clk IMX8QXP_CLK_DUMMY>,
+ <&clk IMX8QXP_CLK_DUMMY>,
+ <&clk IMX8QXP_CLK_DUMMY>,
+ <&clk IMX8QXP_CLK_DUMMY>,
+ <&clk IMX8QXP_CLK_DUMMY>,
+ <&clk IMX8QXP_CLK_DUMMY>,
+ <&clk IMX8QXP_CLK_DUMMY>,
+ <&clk IMX8QXP_CLK_DUMMY>;
+ clock-names = "ipg", "mem",
+ "asrck_0", "asrck_1", "asrck_2", "asrck_3",
+ "asrck_4", "asrck_5", "asrck_6", "asrck_7",
+ "asrck_8", "asrck_9", "asrck_a", "asrck_b",
+ "asrck_c", "asrck_d", "asrck_e", "asrck_f",
+ "spba";
+ dmas = <&edma1 0 0 0>, <&edma1 1 0 0>, <&edma1 2 0 0>,
+ <&edma1 3 0 1>, <&edma1 4 0 1>, <&edma1 5 0 1>;
+ dma-names = "rxa", "rxb", "rxc",
+ "txa", "txb", "txc";
+ fsl,asrc-rate = <8000>;
+ fsl,asrc-width = <16>;
+ power-domains = <&pd_asrc1>;
+ status = "disabled";
+ };
+
+ mqs: mqs@59850000 {
+ compatible = "fsl,imx8qm-mqs";
+ reg = <0x0 0x59850000 0x0 0x10000>;
+ clocks = <&clk IMX8QXP_AUD_MQS_IPG>,
+ <&clk IMX8QXP_AUD_MQS_HMCLK>;
+ clock-names = "core", "mclk";
+ power-domains = <&pd_mqs0>;
+ status = "disabled";
+ };
+
+ usdhc1: usdhc@5b010000 {
+ compatible = "fsl,imx8qm-usdhc", "fsl,imx6sl-usdhc";
+ interrupt-parent = <&gic>;
+ interrupts = <GIC_SPI 232 IRQ_TYPE_LEVEL_HIGH>;
+ reg = <0x0 0x5b010000 0x0 0x10000>;
+ clocks = <&clk IMX8QXP_SDHC0_IPG_CLK>,
+ <&clk IMX8QXP_SDHC0_CLK>,
+ <&clk IMX8QXP_CLK_DUMMY>;
+ clock-names = "ipg", "per", "ahb";
+ assigned-clocks = <&clk IMX8QXP_SDHC0_SEL>, <&clk IMX8QXP_SDHC0_DIV>;
+ assigned-clock-parents = <&clk IMX8QXP_CONN_PLL1_CLK>;
+ assigned-clock-rates = <0>, <400000000>;
+ power-domains = <&pd_conn_sdch0>;
+ fsl,tuning-start-tap = <20>;
+ fsl,tuning-step= <2>;
+ status = "disabled";
+ };
+
+ usdhc2: usdhc@5b020000 {
+ compatible = "fsl,imx8qm-usdhc", "fsl,imx6sl-usdhc";
+ interrupt-parent = <&gic>;
+ interrupts = <GIC_SPI 233 IRQ_TYPE_LEVEL_HIGH>;
+ reg = <0x0 0x5b020000 0x0 0x10000>;
+ clocks = <&clk IMX8QXP_SDHC1_IPG_CLK>,
+ <&clk IMX8QXP_SDHC1_CLK>,
+ <&clk IMX8QXP_CLK_DUMMY>;
+ clock-names = "ipg", "per", "ahb";
+ assigned-clocks = <&clk IMX8QXP_SDHC1_SEL>, <&clk IMX8QXP_SDHC1_DIV>;
+ assigned-clock-parents = <&clk IMX8QXP_CONN_PLL1_CLK>;
+ assigned-clock-rates = <0>, <200000000>;
+ power-domains = <&pd_conn_sdch1>;
+ fsl,tuning-start-tap = <20>;
+ fsl,tuning-step= <2>;
+ status = "disabled";
+ };
+
+ usdhc3: usdhc@5b030000 {
+ compatible = "fsl,imx8qm-usdhc", "fsl,imx6sl-usdhc";
+ interrupt-parent = <&gic>;
+ interrupts = <GIC_SPI 234 IRQ_TYPE_LEVEL_HIGH>;
+ reg = <0x0 0x5b030000 0x0 0x10000>;
+ clocks = <&clk IMX8QXP_SDHC2_IPG_CLK>,
+ <&clk IMX8QXP_SDHC2_CLK>,
+ <&clk IMX8QXP_CLK_DUMMY>;
+ clock-names = "ipg", "per", "ahb";
+ assigned-clocks = <&clk IMX8QXP_SDHC2_SEL>, <&clk IMX8QXP_SDHC2_DIV>;
+ assigned-clock-parents = <&clk IMX8QXP_CONN_PLL1_CLK>;
+ assigned-clock-rates = <0>, <200000000>;
+ power-domains = <&pd_conn_sdch2>;
+ status = "disabled";
+ };
+
+ fec1: ethernet@5b040000 {
+ compatible = "fsl,imx8qm-fec";
+ reg = <0x0 0x5b040000 0x0 0x10000>;
+ interrupt-parent = <&wu>;
+ interrupts = <GIC_SPI 258 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 256 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 257 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 259 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8QXP_ENET0_IPG_CLK>, <&clk IMX8QXP_ENET0_AHB_CLK>, <&clk IMX8QXP_ENET0_RGMII_TX_CLK>,
+ <&clk IMX8QXP_ENET0_PTP_CLK>, <&clk IMX8QXP_ENET0_TX_CLK>;
+ clock-names = "ipg", "ahb", "enet_clk_ref", "ptp", "enet_2x_txclk";
+ assigned-clocks = <&clk IMX8QXP_ENET0_ROOT_DIV>,
+ <&clk IMX8QXP_ENET0_REF_DIV>;
+ assigned-clock-rates = <250000000>, <125000000>;
+ fsl,num-tx-queues=<3>;
+ fsl,num-rx-queues=<3>;
+ fsl,wakeup_irq = <0>;
+ power-domains = <&pd_conn_enet0>;
+ status = "disabled";
+ };
+
+ fec2: ethernet@5b050000 {
+ compatible = "fsl,imx8qm-fec";
+ reg = <0x0 0x5b050000 0x0 0x10000>;
+ interrupt-parent = <&wu>;
+ interrupts = <GIC_SPI 262 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 260 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 261 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 263 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8QXP_ENET1_IPG_CLK>, <&clk IMX8QXP_ENET1_AHB_CLK>, <&clk IMX8QXP_ENET1_RGMII_TX_CLK>,
+ <&clk IMX8QXP_ENET1_PTP_CLK>, <&clk IMX8QXP_ENET1_TX_CLK>;
+ clock-names = "ipg", "ahb", "enet_clk_ref", "ptp", "enet_2x_txclk";
+ assigned-clocks = <&clk IMX8QXP_ENET1_ROOT_DIV>,
+ <&clk IMX8QXP_ENET1_REF_DIV>;
+ assigned-clock-rates = <250000000>, <125000000>;
+ fsl,num-tx-queues=<3>;
+ fsl,num-rx-queues=<3>;
+ fsl,wakeup_irq = <0>;
+ power-domains = <&pd_conn_enet1>;
+ status = "disabled";
+ };
+
+ mlb: mlb@5B060000 {
+ compatible = "fsl,imx6q-mlb150";
+ reg = <0x0 0x5B060000 0x0 0x10000>;
+ interrupt-parent = <&gic>;
+ interrupts = <0 265 IRQ_TYPE_LEVEL_HIGH>,
+ <0 266 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8QXP_MLB_CLK>,
+ <&clk IMX8QXP_MLB_HCLK>,
+ <&clk IMX8QXP_MLB_IPG_CLK>;
+ clock-names = "mlb", "hclk", "ipg";
+ assigned-clocks = <&clk IMX8QXP_MLB_CLK>,
+ <&clk IMX8QXP_MLB_HCLK>,
+ <&clk IMX8QXP_MLB_IPG_CLK>;
+ assigned-clock-rates = <333333333>, <333333333>, <83333333>;
+ power-domains = <&pd_conn_mlb0>;
+ status = "disabled";
+ };
+
+ gpt0: gpt0@5d140000 {
+ compatible = "fsl,imx8qxp-gpt";
+ reg = <0x0 0x5d140000 0x0 0x4000>;
+ interrupts = <GIC_SPI 80 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8QXP_CLK_DUMMY>, <&clk IMX8QXP_GPT_3M>;
+ clock-names = "ipg", "per";
+ power-domains = <&pd_lsio_gpt0>;
+ };
+
+ dsp: dsp@596e8000 {
+ compatible = "fsl,imx8qxp-dsp";
+ reserved-region = <&dsp_reserved>;
+ reg = <0x0 0x596e8000 0x0 0x88000>;
+ clocks = <&clk IMX8QXP_AUD_DSP_IPG>,
+ <&clk IMX8QXP_AUD_OCRAM_IPG>,
+ <&clk IMX8QXP_AUD_DSP_CORE_CLK>;
+ clock-names = "ipg", "ocram", "core";
+ fsl,dsp-firmware = "imx/dsp/hifi4.bin";
+ power-domains = <&pd_dsp>;
+ };
+
+ esai0: esai@59010000 {
+ compatible = "fsl,imx8qm-esai";
+ reg = <0x0 0x59010000 0x0 0x10000>;
+ interrupts = <GIC_SPI 409 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8QXP_AUD_ESAI_0_IPG>,
+ <&clk IMX8QXP_AUD_ESAI_0_EXTAL_IPG>,
+ <&clk IMX8QXP_AUD_ESAI_0_IPG>,
+ <&clk IMX8QXP_CLK_DUMMY>;
+ clock-names = "core", "extal", "fsys", "spba";
+ dmas = <&edma0 6 0 1>, <&edma0 7 0 0>;
+ dma-names = "rx", "tx";
+ power-domains = <&pd_esai0>;
+ status = "disabled";
+ };
+
+ spdif0: spdif@59020000 {
+ compatible = "fsl,imx8qm-spdif";
+ reg = <0x0 0x59020000 0x0 0x10000>;
+ interrupts = <GIC_SPI 456 IRQ_TYPE_LEVEL_HIGH>, /* rx */
+ <GIC_SPI 458 IRQ_TYPE_LEVEL_HIGH>; /* tx */
+ clocks = <&clk IMX8QXP_AUD_SPDIF_0_GCLKW>, /* core */
+ <&clk IMX8QXP_CLK_DUMMY>, /* rxtx0 */
+ <&clk IMX8QXP_AUD_SPDIF_0_TX_CLK>, /* rxtx1 */
+ <&clk IMX8QXP_CLK_DUMMY>, /* rxtx2 */
+ <&clk IMX8QXP_CLK_DUMMY>, /* rxtx3 */
+ <&clk IMX8QXP_CLK_DUMMY>, /* rxtx4 */
+ <&clk IMX8QXP_IPG_AUD_CLK_ROOT>, /* rxtx5 */
+ <&clk IMX8QXP_CLK_DUMMY>, /* rxtx6 */
+ <&clk IMX8QXP_CLK_DUMMY>, /* rxtx7 */
+ <&clk IMX8QXP_CLK_DUMMY>; /* spba */
+ clock-names = "core", "rxtx0",
+ "rxtx1", "rxtx2",
+ "rxtx3", "rxtx4",
+ "rxtx5", "rxtx6",
+ "rxtx7", "spba";
+ dmas = <&edma0 8 0 5>, <&edma0 9 0 4>;
+ dma-names = "rx", "tx";
+ power-domains = <&pd_spdif0>;
+ status = "disabled";
+ };
+
+ flexspi0: flexspi@05d120000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx8qxp-flexspi";
+ reg = <0x0 0x5d120000 0x0 0x10000>, <0x0 0x08000000 0x0 0x10000000>;
+ reg-names = "FlexSPI", "FlexSPI-memory";
+ interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8QXP_LSIO_FSPI0_CLK>;
+ assigned-clock-rates = <29000000>;
+ clock-names = "fspi";
+ power-domains = <&pd_lsio_flexspi0>;
+ status = "disabled";
+ };
+
+ display-subsystem {
+ compatible = "fsl,imx-display-subsystem";
+ ports = <&dpu_disp0>, <&dpu_disp1>;
+ };
+
+ dma_cap: dma_cap {
+ compatible = "dma-capability";
+ only-dma-mask32 = <1>;
+ };
+
+ hsio: hsio@5f080000 {
+ compatible = "fsl,imx8qm-hsio", "syscon";
+ reg = <0x0 0x5f080000 0x0 0xF0000>; /* lpcg, csr, msic, gpio */
+ };
+
+ ocotp: ocotp {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,imx8qxp-ocotp", "syscon";
+ };
+
+ pcieb: pcie@0x5f010000 {
+ /*
+ * pcieb phyx1 lane1 in default, adjust it refer to the
+ * exact hw design.
+ */
+ compatible = "fsl,imx8qxp-pcie","snps,dw-pcie";
+ reg = <0x0 0x5f010000 0x0 0x10000>, /* Controller reg*/
+ <0x0 0x7ff00000 0x0 0x80000>; /* PCI cfg space */
+ reg-names = "dbi", "config";
+ reserved-region = <&rpmsg_reserved>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ device_type = "pci";
+ ranges = <0x81000000 0 0x00000000 0x0 0x7ff80000 0 0x00010000 /* downstream I/O */
+ 0x82000000 0 0x70000000 0x0 0x70000000 0 0x0ff00000>; /* non-prefetchable memory */
+ num-lanes = <1>;
+
+ #interrupt-cells = <1>;
+ interrupts = <GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 104 IRQ_TYPE_LEVEL_HIGH>; /* eDMA */
+ interrupt-names = "msi";
+
+ /*
+ * Set these clocks in default, then clocks should be
+ * refined for exact hw design of imx8 pcie.
+ */
+ clocks = <&clk IMX8QXP_HSIO_PCIE_MSTR_AXI_CLK>,
+ <&clk IMX8QXP_HSIO_PCIE_SLV_AXI_CLK>,
+ <&clk IMX8QXP_HSIO_PHY_X1_PCLK>,
+ <&clk IMX8QXP_HSIO_PCIE_X1_PER_CLK>,
+ <&clk IMX8QXP_HSIO_PCIE_DBI_AXI_CLK>;
+ clock-names = "pcie", "pcie_bus", "pcie_phy", "pcie_per", "pcie_inbound_axi";
+
+ interrupt-map-mask = <0 0 0 0x7>;
+ interrupt-map = <0 0 0 1 &gic 0 105 4>,
+ <0 0 0 2 &gic 0 106 4>,
+ <0 0 0 3 &gic 0 107 4>,
+ <0 0 0 4 &gic 0 108 4>;
+ power-domains = <&pd_pcie>;
+ fsl,max-link-speed = <3>;
+ hsio-cfg = <PCIEAX2PCIEBX1>;
+ hsio = <&hsio>;
+ ctrl-id = <1>; /* pcieb */
+ cpu-base-addr = <0x80000000>;
+ status = "disabled";
+ };
+
+ imx_ion {
+ compatible = "fsl,mxc-ion";
+ fsl,heap-id = <0>;
+ };
+
+ vpu: vpu@2c000000 {
+ compatible = "nxp,imx8qm-vpu", "nxp,imx8qxp-vpu";
+ reg = <0x0 0x2c000000 0x0 0x1000000>;
+ reg-names = "vpu_regs";
+ interrupts = <0 464 0x4>, /* encoder irq */
+ <0 465 0x4>, /* encoder fiq */
+ <0 466 0x4>, /* decoder irq */
+ <0 467 0x4>, /* decoder fiq */
+ <0 468 0x4>; /* decoder sif */
+ interrupt-names = "enc_irq", "enc_fiq", "dec_irq", "dec_fiq", "dec_sif";
+ clocks = <&clk IMX8QXP_VPU_DEC_CLK>;
+ clock-names = "vpu_clk";
+ assigned-clocks = <&clk IMX8QXP_VPU_DEC_CLK>;
+ power-domains = <&pd_vpu_dec>;
+ status = "disabled";
+ };
+
+ vpu_decoder: vpu_decoder@2c000000 {
+ compatible = "nxp,imx8qm-b0-vpudec", "nxp,imx8qxp-b0-vpudec";
+ boot-region = <&decoder_boot>;
+ rpc-region = <&decoder_rpc>;
+ reg = <0x0 0x2c000000 0x0 0x1000000>;
+ reg-names = "vpu_regs";
+ power-domains = <&pd_vpu_dec>;
+ reg-csr = <0x2d040000>;
+ status = "disabled";
+ };
+
+ vpu_encoder: vpu_encoder@2d000000 {
+ compatible = "nxp,imx8qxp-b0-vpuenc";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ boot-region = <&encoder_boot>;
+ rpc-region = <&encoder_rpc>;
+ reserved-region = <&encoder_reserved>;
+ reg = <0x0 0x2d000000 0x0 0x1000000>, /*VPU Encoder*/
+ <0x0 0x2c000000 0x0 0x2000000>; /*VPU*/
+ reg-names = "vpu_regs";
+ power-domains = <&pd_vpu_enc>;
+ reg-rpc-system = <0x40000000>;
+
+ resolution-max = <1920 1080>;
+ fps-max = <120>;
+ status = "disabled";
+
+ core0@1020000 {
+ compatible = "fsl,imx8-mu1-vpu-m0";
+ reg = <0x1020000 0x20000>;
+ reg-csr = <0x1050000 0x10000>;
+ interrupts = <GIC_SPI 470 IRQ_TYPE_LEVEL_HIGH>;
+ fsl,vpu_ap_mu_id = <17>;
+ fw-buf-size = <0x200000>;
+ rpc-buf-size = <0x80000>;
+ print-buf-size = <0x80000>;
+ };
+ };
+ imx_rpmsg: imx_rpmsg {
+ compatible = "fsl,rpmsg-bus", "simple-bus";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ mu_rpmsg: mu_rpmsg@5d200000 {
+ compatible = "fsl,imx6sx-mu";
+ reg = <0x0 0x5d200000 0x0 0x10000>;
+ interrupts = <GIC_SPI 184 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8QXP_LSIO_MU5A_IPG_CLK>;
+ clock-names = "ipg";
+ power-domains = <&pd_lsio_mu5a>;
+ };
+
+ rpmsg: rpmsg{
+ compatible = "fsl,imx8qxp-rpmsg";
+ status = "disabled";
+ mub-partition = <3>;
+ power-domains = <&pd_lsio_mu5a>;
+ memory-region = <&rpmsg_dma_reserved>;
+ };
+ };
+
+ crypto: caam@0x31400000 {
+ compatible = "fsl,sec-v4.0";
+ reg = <0 0x31400000 0 0x400000>;
+ interrupts = <GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 0 0x31400000 0x400000>;
+ fsl,first-jr-index = <2>;
+ fsl,sec-era = <9>;
+
+ sec_jr1: jr1@0x20000 {
+ compatible = "fsl,sec-v4.0-job-ring";
+ reg = <0x20000 0x1000>;
+ interrupts = <GIC_SPI 452 IRQ_TYPE_LEVEL_HIGH>;
+ power-domains = <&pd_caam_jr1>;
+ status = "disabled";
+ };
+
+ sec_jr2: jr2@30000 {
+ compatible = "fsl,sec-v4.0-job-ring";
+ reg = <0x30000 0x1000>;
+ interrupts = <GIC_SPI 453 IRQ_TYPE_LEVEL_HIGH>;
+ power-domains = <&pd_caam_jr2>;
+ status = "okay";
+ };
+
+ sec_jr3: jr3@40000 {
+ compatible = "fsl,sec-v4.0-job-ring";
+ reg = <0x40000 0x1000>;
+ interrupts = <GIC_SPI 454 IRQ_TYPE_LEVEL_HIGH>;
+ power-domains = <&pd_caam_jr3>;
+ status = "okay";
+ };
+ };
+
+ caam_sm: caam-sm@31800000 {
+ compatible = "fsl,imx6q-caam-sm";
+ reg = <0 0x31800000 0 0x10000>;
+ };
+
+ sc_pwrkey: sc-powerkey {
+ compatible = "fsl,imx8-pwrkey";
+ linux,keycode = <KEY_POWER>;
+ wakeup-source;
+ };
+
+ wdog: wdog {
+ compatible = "fsl,imx8-wdt";
+ };
+};
+
+&A35_0 {
+ operating-points = <
+ /* kHz uV*/
+ /* voltage is maintained by SCFW, so no need here */
+ 1200000 0
+ 900000 0
+ >;
+ clocks = <&clk IMX8QXP_A35_DIV>;
+ clock-latency = <61036>;
+ #cooling-cells = <2>;
+};
+
+/delete-node/ &A35_2;
+/delete-node/ &A35_3;
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8dxp-lpddr4-arm2.dts b/arch/arm64/boot/dts/freescale/fsl-imx8dxp-lpddr4-arm2.dts
new file mode 100644
index 000000000000..c8b9e57f10d0
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8dxp-lpddr4-arm2.dts
@@ -0,0 +1,35 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2018 NXP
+ *
+ * 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.
+ */
+
+/dts-v1/;
+
+#include "fsl-imx8dxp.dtsi"
+
+#include "fsl-imx8x-arm2.dtsi"
+
+/ {
+ model = "Freescale i.MX8DXP ARM2";
+ compatible = "fsl,imx8dxp-arm2", "fsl,imx8dxp", "fsl,imx8qxp";
+};
+
+&usbotg3 {
+ dr_mode = "otg";
+ extcon = <&typec_ptn5150>;
+ status = "okay";
+};
+
+&vpu_decoder {
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8dxp.dtsi b/arch/arm64/boot/dts/freescale/fsl-imx8dxp.dtsi
new file mode 100644
index 000000000000..81fe228c3335
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8dxp.dtsi
@@ -0,0 +1,39 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2018 NXP
+ *
+ * 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 "fsl-imx8dx.dtsi"
+
+/ {
+ model = "Freescale i.MX8DXP";
+ compatible = "fsl,imx8dxp", "fsl,imx8qxp";
+
+ vpu_decoder: vpu_decoder@2c000000 {
+ compatible = "nxp,imx8qm-b0-vpudec", "nxp,imx8qxp-b0-vpudec";
+ boot-region = <&decoder_boot>;
+ rpc-region = <&decoder_rpc>;
+ reg = <0x0 0x2c000000 0x0 0x1000000>;
+ reg-names = "vpu_regs";
+ clocks = <&clk IMX8QXP_VPU_DEC_CLK>;
+ clock-names = "vpu_clk";
+ assigned-clocks = <&clk IMX8QXP_VPU_DEC_CLK>;
+ power-domains = <&pd_vpu_dec>;
+ status = "disabled";
+ };
+};
+
+&gpu_3d0 {
+ assigned-clock-rates = <700000000>, <850000000>;
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8mm-ddr3l-val.dts b/arch/arm64/boot/dts/freescale/fsl-imx8mm-ddr3l-val.dts
new file mode 100644
index 000000000000..86d7c58fe81d
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8mm-ddr3l-val.dts
@@ -0,0 +1,418 @@
+// SPDX-License-Identifier: GPL-2.0+
+ /*
+ * Copyright 2018 NXP
+ */
+
+/dts-v1/;
+
+#include "fsl-imx8mm.dtsi"
+
+/ {
+ model = "FSL i.MX8MM DDR3L Validation board";
+ compatible = "fsl,imx8mm-val", "fsl,imx8mm";
+
+ chosen {
+ bootargs = "console=ttymxc1,115200 earlycon=ec_imx6q,0x30890000,115200";
+ stdout-path = &uart2;
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ reg_usdhc2_vmmc: regulator-usdhc2 {
+ compatible = "regulator-fixed";
+ regulator-name = "VSD_3V3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&gpio2 19 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+ };
+
+ busfreq {
+ status = "disabled";
+ };
+};
+
+&iomuxc {
+ pinctrl-names = "default";
+
+ imx8mm-val {
+ pinctrl_ecspi1: ecspi1grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_ECSPI1_SCLK_ECSPI1_SCLK 0x82
+ MX8MM_IOMUXC_ECSPI1_MOSI_ECSPI1_MOSI 0x82
+ MX8MM_IOMUXC_ECSPI1_MISO_ECSPI1_MISO 0x82
+ >;
+ };
+
+ pinctrl_ecspi1_cs: ecspi1cs {
+ fsl,pins = <
+ MX8MM_IOMUXC_ECSPI1_SS0_GPIO5_IO9 0x40000
+ >;
+ };
+
+ pinctrl_fec1: fec1grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_ENET_MDC_ENET1_MDC 0x3
+ MX8MM_IOMUXC_ENET_MDIO_ENET1_MDIO 0x23
+ MX8MM_IOMUXC_ENET_TD2_ENET1_TX_CLK 0x4000001f
+ MX8MM_IOMUXC_ENET_TD1_ENET1_RGMII_TD1 0x56
+ MX8MM_IOMUXC_ENET_TD0_ENET1_RGMII_TD0 0x56
+ MX8MM_IOMUXC_ENET_RD1_ENET1_RGMII_RD1 0x56
+ MX8MM_IOMUXC_ENET_RD0_ENET1_RGMII_RD0 0x56
+ MX8MM_IOMUXC_ENET_RXC_ENET1_RX_ER 0x56
+ MX8MM_IOMUXC_ENET_RX_CTL_ENET1_RGMII_RX_CTL 0x56
+ MX8MM_IOMUXC_ENET_TX_CTL_ENET1_RGMII_TX_CTL 0x56
+ >;
+ };
+
+ pinctrl_i2c1: i2c1grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_I2C1_SCL_I2C1_SCL 0x400001c3
+ MX8MM_IOMUXC_I2C1_SDA_I2C1_SDA 0x400001c3
+ >;
+ };
+
+ pinctrl_i2c2: i2c2grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_I2C2_SCL_I2C2_SCL 0x400001c3
+ MX8MM_IOMUXC_I2C2_SDA_I2C2_SDA 0x400001c3
+ >;
+ };
+
+ pinctrl_i2c3: i2c3grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_I2C3_SCL_I2C3_SCL 0x400001c3
+ MX8MM_IOMUXC_I2C3_SDA_I2C3_SDA 0x400001c3
+ >;
+ };
+
+ pinctrl_uart2: uart2grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_UART2_RXD_UART2_DCE_RX 0x140
+ MX8MM_IOMUXC_UART2_TXD_UART2_DCE_TX 0x140
+ >;
+ };
+
+ pinctrl_usdhc2_gpio: usdhc2grpgpio {
+ fsl,pins = <
+ MX8MM_IOMUXC_SD2_RESET_B_GPIO2_IO19 0x41
+ >;
+ };
+
+ pinctrl_usdhc2: usdhc2grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK 0x190
+ MX8MM_IOMUXC_SD2_CMD_USDHC2_CMD 0x1d0
+ MX8MM_IOMUXC_SD2_DATA0_USDHC2_DATA0 0x1d0
+ MX8MM_IOMUXC_SD2_DATA1_USDHC2_DATA1 0x1d0
+ MX8MM_IOMUXC_SD2_DATA2_USDHC2_DATA2 0x1d0
+ MX8MM_IOMUXC_SD2_DATA3_USDHC2_DATA3 0x1d0
+ MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0x1d0
+ >;
+ };
+
+ pinctrl_usdhc2_100mhz: usdhc2grp100mhz {
+ fsl,pins = <
+ MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK 0x194
+ MX8MM_IOMUXC_SD2_CMD_USDHC2_CMD 0x1d4
+ MX8MM_IOMUXC_SD2_DATA0_USDHC2_DATA0 0x1d4
+ MX8MM_IOMUXC_SD2_DATA1_USDHC2_DATA1 0x1d4
+ MX8MM_IOMUXC_SD2_DATA2_USDHC2_DATA2 0x1d4
+ MX8MM_IOMUXC_SD2_DATA3_USDHC2_DATA3 0x1d4
+ MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0x1d0
+ >;
+ };
+
+ pinctrl_usdhc2_200mhz: usdhc2grp200mhz {
+ fsl,pins = <
+ MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK 0x196
+ MX8MM_IOMUXC_SD2_CMD_USDHC2_CMD 0x1d6
+ MX8MM_IOMUXC_SD2_DATA0_USDHC2_DATA0 0x1d6
+ MX8MM_IOMUXC_SD2_DATA1_USDHC2_DATA1 0x1d6
+ MX8MM_IOMUXC_SD2_DATA2_USDHC2_DATA2 0x1d6
+ MX8MM_IOMUXC_SD2_DATA3_USDHC2_DATA3 0x1d6
+ MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0x1d0
+ >;
+ };
+
+ pinctrl_gpmi_nand_1: gpmi-nand-1 {
+ fsl,pins = <
+ MX8MM_IOMUXC_NAND_ALE_RAWNAND_ALE 0x00000096
+ MX8MM_IOMUXC_NAND_CE0_B_RAWNAND_CE0_B 0x00000096
+ MX8MM_IOMUXC_NAND_CLE_RAWNAND_CLE 0x00000096
+ MX8MM_IOMUXC_NAND_DATA00_RAWNAND_DATA00 0x00000096
+ MX8MM_IOMUXC_NAND_DATA01_RAWNAND_DATA01 0x00000096
+ MX8MM_IOMUXC_NAND_DATA02_RAWNAND_DATA02 0x00000096
+ MX8MM_IOMUXC_NAND_DATA03_RAWNAND_DATA03 0x00000096
+ MX8MM_IOMUXC_NAND_DATA04_RAWNAND_DATA04 0x00000096
+ MX8MM_IOMUXC_NAND_DATA05_RAWNAND_DATA05 0x00000096
+ MX8MM_IOMUXC_NAND_DATA06_RAWNAND_DATA06 0x00000096
+ MX8MM_IOMUXC_NAND_DATA07_RAWNAND_DATA07 0x00000096
+ MX8MM_IOMUXC_NAND_RE_B_RAWNAND_RE_B 0x00000096
+ MX8MM_IOMUXC_NAND_READY_B_RAWNAND_READY_B 0x00000056
+ MX8MM_IOMUXC_NAND_WE_B_RAWNAND_WE_B 0x00000096
+ MX8MM_IOMUXC_NAND_WP_B_RAWNAND_WP_B 0x00000096
+ >;
+ };
+ };
+};
+
+&ecspi1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ fsl,spi-num-chipselects = <1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ecspi1 &pinctrl_ecspi1_cs>;
+ cs-gpios = <&gpio5 9 GPIO_ACTIVE_LOW>;
+ status = "okay";
+
+ flash: m25p80@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "gd25q16", "jedec,spi-nor";
+ spi-max-frequency = <20000000>;
+ reg = <0>;
+ };
+};
+
+&i2c1 {
+ clock-frequency = <400000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c1>;
+ status = "okay";
+
+ pmic: bd71837@4b {
+ reg = <0x4b>;
+ compatible = "rohm,bd71837";
+
+ gpo {
+ rohm,drv = <0x0C>; /* 0b0000_1100 all gpos with cmos output mode */
+ };
+
+ regulators {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ bd71837,pmic-buck2-uses-i2c-dvs;
+ bd71837,pmic-buck2-dvs-voltage = <1000000>, <900000>, <0>; /* VDD_ARM: Run-Idle */
+
+ buck1_reg: regulator@0 {
+ reg = <0>;
+ regulator-compatible = "buck1";
+ regulator-min-microvolt = <700000>;
+ regulator-max-microvolt = <1300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ regulator-ramp-delay = <1250>;
+ };
+
+ buck2_reg: regulator@1 {
+ reg = <1>;
+ regulator-compatible = "buck2";
+ regulator-min-microvolt = <700000>;
+ regulator-max-microvolt = <1300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ regulator-ramp-delay = <1250>;
+ };
+
+ buck3_reg: regulator@2 {
+ reg = <2>;
+ regulator-compatible = "buck3";
+ regulator-min-microvolt = <700000>;
+ regulator-max-microvolt = <1300000>;
+ };
+
+ buck4_reg: regulator@3 {
+ reg = <3>;
+ regulator-compatible = "buck4";
+ regulator-min-microvolt = <700000>;
+ regulator-max-microvolt = <1300000>;
+ };
+
+ buck5_reg: regulator@4 {
+ reg = <4>;
+ regulator-compatible = "buck5";
+ regulator-min-microvolt = <700000>;
+ regulator-max-microvolt = <1350000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ buck6_reg: regulator@5 {
+ reg = <5>;
+ regulator-compatible = "buck6";
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ buck7_reg: regulator@6 {
+ reg = <6>;
+ regulator-compatible = "buck7";
+ regulator-min-microvolt = <1605000>;
+ regulator-max-microvolt = <1995000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ buck8_reg: regulator@7 {
+ reg = <7>;
+ regulator-compatible = "buck8";
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1400000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ ldo1_reg: regulator@8 {
+ reg = <8>;
+ regulator-compatible = "ldo1";
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ ldo2_reg: regulator@9 {
+ reg = <9>;
+ regulator-compatible = "ldo2";
+ regulator-min-microvolt = <900000>;
+ regulator-max-microvolt = <900000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ ldo3_reg: regulator@10 {
+ reg = <10>;
+ regulator-compatible = "ldo3";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ ldo4_reg: regulator@11 {
+ reg = <11>;
+ regulator-compatible = "ldo4";
+ regulator-min-microvolt = <900000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ ldo5_reg: regulator@12 {
+ reg = <12>;
+ regulator-compatible = "ldo5";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ ldo6_reg: regulator@13 {
+ reg = <13>;
+ regulator-compatible = "ldo6";
+ regulator-min-microvolt = <900000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ ldo7_reg: regulator@14 {
+ reg = <14>;
+ regulator-compatible = "ldo7";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ };
+ };
+ };
+};
+
+&i2c2 {
+ clock-frequency = <400000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c2>;
+ status = "okay";
+};
+
+&i2c3 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c3>;
+ status = "okay";
+};
+
+&mu {
+ status = "okay";
+};
+
+&rpmsg{
+ /*
+ * 64K for one rpmsg instance:
+ * --0xb8000000~0xb800ffff: pingpong
+ */
+ vdev-nums = <1>;
+ reg = <0x0 0xb8000000 0x0 0x10000>;
+ status = "okay";
+};
+
+&fec1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_fec1>;
+ phy-mode = "rmii";
+ phy-handle = <&ethphy0>;
+ fsl,magic-packet;
+ status = "okay";
+
+ mdio {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ethphy0: ethernet-phy@0 {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <0>;
+ };
+ };
+};
+
+&uart2 { /* console */
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart2>;
+ status = "okay";
+};
+
+&usbotg1 {
+ dr_mode = "host";
+ status = "okay";
+};
+
+&usbotg2 {
+ dr_mode = "peripheral";
+ status = "okay";
+};
+
+&usdhc2 {
+ pinctrl-names = "default", "state_100mhz", "state_200mhz";
+ pinctrl-0 = <&pinctrl_usdhc2>, <&pinctrl_usdhc2_gpio>;
+ pinctrl-1 = <&pinctrl_usdhc2_100mhz>, <&pinctrl_usdhc2_gpio>;
+ pinctrl-2 = <&pinctrl_usdhc2_200mhz>, <&pinctrl_usdhc2_gpio>;
+ bus-width = <4>;
+ non-removable;
+ vmmc-supply = <&reg_usdhc2_vmmc>;
+ status = "okay";
+};
+
+&gpmi {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpmi_nand_1>;
+ status = "okay";
+ nand-on-flash-bbt;
+};
+
+&A53_0 {
+ arm-supply = <&buck2_reg>;
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8mm-ddr4-evk-rm67191.dts b/arch/arm64/boot/dts/freescale/fsl-imx8mm-ddr4-evk-rm67191.dts
new file mode 100644
index 000000000000..ff599ffaec4a
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8mm-ddr4-evk-rm67191.dts
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2018 NXP
+ *
+ * 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 "fsl-imx8mm-ddr4-evk.dts"
+
+&adv_bridge {
+ status = "disabled";
+};
+
+&mipi_dsi {
+ panel@0 {
+ compatible = "raydium,rm67191";
+ reg = <0>;
+ pinctrl-0 = <&pinctrl_mipi_dsi_en>;
+ reset-gpio = <&gpio1 8 GPIO_ACTIVE_HIGH>;
+ dsi-lanes = <4>;
+ video-mode = <2>; /* 0: burst mode
+ * 1: non-burst mode with sync event
+ * 2: non-burst mode with sync pulse
+ */
+ panel-width-mm = <68>;
+ panel-height-mm = <121>;
+ status = "okay";
+ };
+};
+
+&i2c2 {
+ synaptics_dsx_ts@20 {
+ compatible = "synaptics_dsx";
+ reg = <0x20>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c2_synaptics_dsx_io>;
+ interrupt-parent = <&gpio1>;
+ interrupts = <9 IRQ_TYPE_LEVEL_LOW>;
+ synaptics,diagonal-rotation;
+ status = "okay";
+ };
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8mm-ddr4-evk.dts b/arch/arm64/boot/dts/freescale/fsl-imx8mm-ddr4-evk.dts
new file mode 100644
index 000000000000..618caf8baf6c
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8mm-ddr4-evk.dts
@@ -0,0 +1,113 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2018 NXP
+ */
+
+/dts-v1/;
+
+#include "fsl-imx8mm-evk.dts"
+
+/ {
+ model = "FSL i.MX8MM DDR4 EVK with CYW43455 WIFI/BT board";
+
+ leds {
+ pinctrl-0 = <&pinctrl_gpio_led_2>;
+
+ status {
+ gpios = <&gpio3 4 GPIO_ACTIVE_LOW>;
+ };
+ };
+
+ usdhc1_pwrseq: usdhc1_pwrseq {
+ compatible = "mmc-pwrseq-simple";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usdhc1_gpio>;
+ reset-gpios = <&gpio2 10 GPIO_ACTIVE_LOW>;
+ };
+};
+
+&iomuxc {
+ imx8mm-evk {
+ pinctrl_gpmi_nand_1: gpmi-nand-1 {
+ fsl,pins = <
+ MX8MM_IOMUXC_NAND_ALE_RAWNAND_ALE 0x00000096
+ MX8MM_IOMUXC_NAND_CE0_B_RAWNAND_CE0_B 0x00000096
+ MX8MM_IOMUXC_NAND_CE1_B_RAWNAND_CE1_B 0x00000096
+ MX8MM_IOMUXC_NAND_CLE_RAWNAND_CLE 0x00000096
+ MX8MM_IOMUXC_NAND_DATA00_RAWNAND_DATA00 0x00000096
+ MX8MM_IOMUXC_NAND_DATA01_RAWNAND_DATA01 0x00000096
+ MX8MM_IOMUXC_NAND_DATA02_RAWNAND_DATA02 0x00000096
+ MX8MM_IOMUXC_NAND_DATA03_RAWNAND_DATA03 0x00000096
+ MX8MM_IOMUXC_NAND_DATA04_RAWNAND_DATA04 0x00000096
+ MX8MM_IOMUXC_NAND_DATA05_RAWNAND_DATA05 0x00000096
+ MX8MM_IOMUXC_NAND_DATA06_RAWNAND_DATA06 0x00000096
+ MX8MM_IOMUXC_NAND_DATA07_RAWNAND_DATA07 0x00000096
+ MX8MM_IOMUXC_NAND_RE_B_RAWNAND_RE_B 0x00000096
+ MX8MM_IOMUXC_NAND_READY_B_RAWNAND_READY_B 0x00000056
+ MX8MM_IOMUXC_NAND_WE_B_RAWNAND_WE_B 0x00000096
+ MX8MM_IOMUXC_NAND_WP_B_RAWNAND_WP_B 0x00000096
+ >;
+ };
+
+ pinctrl_gpio_led_2: gpioled2grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_NAND_CE3_B_GPIO3_IO4 0x19
+ >;
+ };
+
+ pinctrl_wlan: wlangrp {
+ fsl,pins = <
+ MX8MM_IOMUXC_GPIO1_IO00_ANAMIX_REF_CLK_32K 0x141
+ MX8MM_IOMUXC_SD1_DATA7_GPIO2_IO9 0x111
+ >;
+ };
+ };
+};
+
+&gpmi {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpmi_nand_1>;
+ status = "okay";
+ nand-on-flash-bbt;
+};
+
+&reg_sd1_vmmc {
+ status = "disabled";
+};
+
+&usdhc1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-0 = <&pinctrl_usdhc1>, <&pinctrl_wlan>;
+ pinctrl-1 = <&pinctrl_usdhc1_100mhz>, <&pinctrl_wlan>;
+ pinctrl-2 = <&pinctrl_usdhc1_200mhz>, <&pinctrl_wlan>;
+ cap-power-off-card;
+ /delete-property/ vmmc-supply;
+ mmc-pwrseq = <&usdhc1_pwrseq>;
+
+ brcmf: bcrmf@1 {
+ reg = <1>;
+ compatible = "brcm,bcm4329-fmac";
+ interrupt-parent = <&gpio2>;
+ interrupts = <9 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "host-wake";
+ };
+};
+
+&usdhc3 {
+ status = "disabled";
+};
+
+&flexspi {
+ status = "disabled";
+};
+
+/*
+ * External OSC is used as PCIe REFCLK on RevC board.
+ * DDR4 board is same to the RevB board, configure
+ * PCIe REFCLK to internal PLL.
+ */
+&pcie0{
+ ext_osc = <0>;
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8mm-ddr4-qca9377-evk.dts b/arch/arm64/boot/dts/freescale/fsl-imx8mm-ddr4-qca9377-evk.dts
new file mode 100644
index 000000000000..e1339640d56b
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8mm-ddr4-qca9377-evk.dts
@@ -0,0 +1,33 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2018 NXP
+ */
+
+/dts-v1/;
+
+#include "fsl-imx8mm-ddr4-evk.dts"
+
+/ {
+ model = "FSL i.MX8MM DDR4 EVK with QCA9377-3 WIFI/BT board";
+};
+
+&reg_sd1_vmmc {
+ status = "okay";
+};
+
+&usdhc1 {
+ pinctrl-0 = <&pinctrl_usdhc1>, <&pinctrl_usdhc1_gpio>;
+ pinctrl-1 = <&pinctrl_usdhc1_100mhz>, <&pinctrl_usdhc1_gpio>;
+ pinctrl-2 = <&pinctrl_usdhc1_200mhz>, <&pinctrl_usdhc1_gpio>;
+ vmmc-supply = <&reg_sd1_vmmc>;
+ /delete-property/ mmc-pwrseq;
+ /delete-property/ cap-power-off-card;
+
+ brcmf: bcrmf@1 {
+ status = "disabled";
+ };
+};
+
+&usdhc1_pwrseq {
+ status = "disabled";
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8mm-ddr4-val.dts b/arch/arm64/boot/dts/freescale/fsl-imx8mm-ddr4-val.dts
new file mode 100644
index 000000000000..797f21d166fb
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8mm-ddr4-val.dts
@@ -0,0 +1,541 @@
+/*
+ * Copyright 2018 NXP
+ *
+ * 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.
+ */
+
+/dts-v1/;
+
+#include "fsl-imx8mm.dtsi"
+
+/ {
+ model = "FSL i.MX8MM DDR4 validation board";
+ compatible = "fsl,imx8mm-val", "fsl,imx8mm";
+
+ chosen {
+ bootargs = "console=ttymxc1,115200 earlycon=ec_imx6q,0x30890000,115200";
+ stdout-path = &uart2;
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ reg_usdhc2_vmmc: regulator-usdhc2 {
+ compatible = "regulator-fixed";
+ regulator-name = "VSD_3V3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&gpio2 19 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+ };
+
+ busfreq {
+ status = "disabled";
+ };
+};
+
+&iomuxc {
+ pinctrl-names = "default";
+
+ imx8mm-val {
+ pinctrl_fec1: fec1grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_ENET_MDC_ENET1_MDC 0x3
+ MX8MM_IOMUXC_ENET_MDIO_ENET1_MDIO 0x3
+ MX8MM_IOMUXC_ENET_TD3_ENET1_RGMII_TD3 0x1f
+ MX8MM_IOMUXC_ENET_TD2_ENET1_RGMII_TD2 0x1f
+ MX8MM_IOMUXC_ENET_TD1_ENET1_RGMII_TD1 0x1f
+ MX8MM_IOMUXC_ENET_TD0_ENET1_RGMII_TD0 0x1f
+ MX8MM_IOMUXC_ENET_RD3_ENET1_RGMII_RD3 0x91
+ MX8MM_IOMUXC_ENET_RD2_ENET1_RGMII_RD2 0x91
+ MX8MM_IOMUXC_ENET_RD1_ENET1_RGMII_RD1 0x91
+ MX8MM_IOMUXC_ENET_RD0_ENET1_RGMII_RD0 0x91
+ MX8MM_IOMUXC_ENET_TXC_ENET1_RGMII_TXC 0x1f
+ MX8MM_IOMUXC_ENET_RXC_ENET1_RGMII_RXC 0x91
+ MX8MM_IOMUXC_ENET_RX_CTL_ENET1_RGMII_RX_CTL 0x91
+ MX8MM_IOMUXC_ENET_TX_CTL_ENET1_RGMII_TX_CTL 0x1f
+ MX8MM_IOMUXC_SAI2_RXC_GPIO4_IO22 0x19
+ >;
+ };
+
+ pinctrl_flexspi0: flexspi0grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_NAND_ALE_QSPI_A_SCLK 0x1c2
+ MX8MM_IOMUXC_NAND_CE0_B_QSPI_A_SS0_B 0x82
+ MX8MM_IOMUXC_NAND_DATA00_QSPI_A_DATA0 0x82
+ MX8MM_IOMUXC_NAND_DATA01_QSPI_A_DATA1 0x82
+ MX8MM_IOMUXC_NAND_DATA02_QSPI_A_DATA2 0x82
+ MX8MM_IOMUXC_NAND_DATA03_QSPI_A_DATA3 0x82
+ >;
+ };
+
+ pinctrl_i2c1: i2c1grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_I2C1_SCL_I2C1_SCL 0x400001c3
+ MX8MM_IOMUXC_I2C1_SDA_I2C1_SDA 0x400001c3
+ >;
+ };
+
+ pinctrl_i2c2: i2c2grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_I2C2_SCL_I2C2_SCL 0x400001c3
+ MX8MM_IOMUXC_I2C2_SDA_I2C2_SDA 0x400001c3
+ >;
+ };
+
+ pinctrl_i2c3: i2c3grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_I2C3_SCL_I2C3_SCL 0x400001c3
+ MX8MM_IOMUXC_I2C3_SDA_I2C3_SDA 0x400001c3
+ >;
+ };
+
+ pinctrl_pmic: pmicirq {
+ fsl,pins = <
+ MX8MM_IOMUXC_GPIO1_IO03_GPIO1_IO3 0x41
+ >;
+ };
+
+ pinctrl_typec1: typec1grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_SD1_STROBE_GPIO2_IO11 0x159
+ >;
+ };
+
+ pinctrl_typec2: typec2grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_SD2_CD_B_GPIO2_IO12 0x159
+ >;
+ };
+
+ pinctrl_uart2: uart2grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_UART2_RXD_UART2_DCE_RX 0x140
+ MX8MM_IOMUXC_UART2_TXD_UART2_DCE_TX 0x140
+ >;
+ };
+
+ pinctrl_usdhc2_gpio: usdhc2grpgpio {
+ fsl,pins = <
+ MX8MM_IOMUXC_SD2_RESET_B_GPIO2_IO19 0x41
+ >;
+ };
+
+ pinctrl_usdhc2: usdhc2grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK 0x190
+ MX8MM_IOMUXC_SD2_CMD_USDHC2_CMD 0x1d0
+ MX8MM_IOMUXC_SD2_DATA0_USDHC2_DATA0 0x1d0
+ MX8MM_IOMUXC_SD2_DATA1_USDHC2_DATA1 0x1d0
+ MX8MM_IOMUXC_SD2_DATA2_USDHC2_DATA2 0x1d0
+ MX8MM_IOMUXC_SD2_DATA3_USDHC2_DATA3 0x1d0
+ MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0x1d0
+ >;
+ };
+
+ pinctrl_usdhc2_100mhz: usdhc2grp100mhz {
+ fsl,pins = <
+ MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK 0x194
+ MX8MM_IOMUXC_SD2_CMD_USDHC2_CMD 0x1d4
+ MX8MM_IOMUXC_SD2_DATA0_USDHC2_DATA0 0x1d4
+ MX8MM_IOMUXC_SD2_DATA1_USDHC2_DATA1 0x1d4
+ MX8MM_IOMUXC_SD2_DATA2_USDHC2_DATA2 0x1d4
+ MX8MM_IOMUXC_SD2_DATA3_USDHC2_DATA3 0x1d4
+ MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0x1d0
+ >;
+ };
+
+ pinctrl_usdhc2_200mhz: usdhc2grp200mhz {
+ fsl,pins = <
+ MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK 0x196
+ MX8MM_IOMUXC_SD2_CMD_USDHC2_CMD 0x1d6
+ MX8MM_IOMUXC_SD2_DATA0_USDHC2_DATA0 0x1d6
+ MX8MM_IOMUXC_SD2_DATA1_USDHC2_DATA1 0x1d6
+ MX8MM_IOMUXC_SD2_DATA2_USDHC2_DATA2 0x1d6
+ MX8MM_IOMUXC_SD2_DATA3_USDHC2_DATA3 0x1d6
+ MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0x1d0
+ >;
+ };
+
+ pinctrl_usdhc3: usdhc3grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_NAND_WE_B_USDHC3_CLK 0x190
+ MX8MM_IOMUXC_NAND_WP_B_USDHC3_CMD 0x1d0
+ MX8MM_IOMUXC_NAND_DATA04_USDHC3_DATA0 0x1d0
+ MX8MM_IOMUXC_NAND_DATA05_USDHC3_DATA1 0x1d0
+ MX8MM_IOMUXC_NAND_DATA06_USDHC3_DATA2 0x1d0
+ MX8MM_IOMUXC_NAND_DATA07_USDHC3_DATA3 0x1d0
+ MX8MM_IOMUXC_NAND_RE_B_USDHC3_DATA4 0x1d0
+ MX8MM_IOMUXC_NAND_CE2_B_USDHC3_DATA5 0x1d0
+ MX8MM_IOMUXC_NAND_CE3_B_USDHC3_DATA6 0x1d0
+ MX8MM_IOMUXC_NAND_CLE_USDHC3_DATA7 0x1d0
+ MX8MM_IOMUXC_NAND_CE1_B_USDHC3_STROBE 0x190
+ >;
+ };
+
+ pinctrl_usdhc3_100mhz: usdhc3grp100mhz {
+ fsl,pins = <
+ MX8MM_IOMUXC_NAND_WE_B_USDHC3_CLK 0x194
+ MX8MM_IOMUXC_NAND_WP_B_USDHC3_CMD 0x1d4
+ MX8MM_IOMUXC_NAND_DATA04_USDHC3_DATA0 0x1d4
+ MX8MM_IOMUXC_NAND_DATA05_USDHC3_DATA1 0x1d4
+ MX8MM_IOMUXC_NAND_DATA06_USDHC3_DATA2 0x1d4
+ MX8MM_IOMUXC_NAND_DATA07_USDHC3_DATA3 0x1d4
+ MX8MM_IOMUXC_NAND_RE_B_USDHC3_DATA4 0x1d4
+ MX8MM_IOMUXC_NAND_CE2_B_USDHC3_DATA5 0x1d4
+ MX8MM_IOMUXC_NAND_CE3_B_USDHC3_DATA6 0x1d4
+ MX8MM_IOMUXC_NAND_CLE_USDHC3_DATA7 0x1d4
+ MX8MM_IOMUXC_NAND_CE1_B_USDHC3_STROBE 0x194
+ >;
+ };
+
+ pinctrl_usdhc3_200mhz: usdhc3grp200mhz {
+ fsl,pins = <
+ MX8MM_IOMUXC_NAND_WE_B_USDHC3_CLK 0x196
+ MX8MM_IOMUXC_NAND_WP_B_USDHC3_CMD 0x1d6
+ MX8MM_IOMUXC_NAND_DATA04_USDHC3_DATA0 0x1d6
+ MX8MM_IOMUXC_NAND_DATA05_USDHC3_DATA1 0x1d6
+ MX8MM_IOMUXC_NAND_DATA06_USDHC3_DATA2 0x1d6
+ MX8MM_IOMUXC_NAND_DATA07_USDHC3_DATA3 0x1d6
+ MX8MM_IOMUXC_NAND_RE_B_USDHC3_DATA4 0x1d6
+ MX8MM_IOMUXC_NAND_CE2_B_USDHC3_DATA5 0x1d6
+ MX8MM_IOMUXC_NAND_CE3_B_USDHC3_DATA6 0x1d6
+ MX8MM_IOMUXC_NAND_CLE_USDHC3_DATA7 0x1d6
+ MX8MM_IOMUXC_NAND_CE1_B_USDHC3_STROBE 0x196
+ >;
+ };
+
+ pinctrl_wdog: wdoggrp {
+ fsl,pins = <
+ MX8MM_IOMUXC_GPIO1_IO02_WDOG1_WDOG_B 0xc6
+ >;
+ };
+ };
+};
+
+&flexspi {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_flexspi0>;
+ status = "okay";
+
+ flash0: mt25qu256aba@0 {
+ reg = <0>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "micron,mt25qu256aba";
+ spi-max-frequency = <29000000>;
+ spi-nor,ddr-quad-read-dummy = <8>;
+ };
+};
+
+&i2c1 {
+ clock-frequency = <400000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c1>;
+ status = "okay";
+
+ pmic: bd71837@4b {
+ reg = <0x4b>;
+ compatible = "rohm,bd71837";
+ /* PMIC BD71837 PMIC_nINT GPIO1_IO3 */
+ pinctrl-0 = <&pinctrl_pmic>;
+ gpio_intr = <&gpio1 3 GPIO_ACTIVE_LOW>;
+
+ gpo {
+ rohm,drv = <0x0C>; /* 0b0000_1100 all gpos with cmos output mode */
+ };
+
+ regulators {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ bd71837,pmic-buck2-uses-i2c-dvs;
+ bd71837,pmic-buck2-dvs-voltage = <1000000>, <900000>, <0>; /* VDD_ARM: Run-Idle */
+
+ buck1_reg: regulator@0 {
+ reg = <0>;
+ regulator-compatible = "buck1";
+ regulator-min-microvolt = <700000>;
+ regulator-max-microvolt = <1300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ regulator-ramp-delay = <1250>;
+ };
+
+ buck2_reg: regulator@1 {
+ reg = <1>;
+ regulator-compatible = "buck2";
+ regulator-min-microvolt = <700000>;
+ regulator-max-microvolt = <1300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ regulator-ramp-delay = <1250>;
+ };
+
+ buck3_reg: regulator@2 {
+ reg = <2>;
+ regulator-compatible = "buck3";
+ regulator-min-microvolt = <700000>;
+ regulator-max-microvolt = <1300000>;
+ };
+
+ buck4_reg: regulator@3 {
+ reg = <3>;
+ regulator-compatible = "buck4";
+ regulator-min-microvolt = <700000>;
+ regulator-max-microvolt = <1300000>;
+ };
+
+ buck5_reg: regulator@4 {
+ reg = <4>;
+ regulator-compatible = "buck5";
+ regulator-min-microvolt = <700000>;
+ regulator-max-microvolt = <1350000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ buck6_reg: regulator@5 {
+ reg = <5>;
+ regulator-compatible = "buck6";
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ buck7_reg: regulator@6 {
+ reg = <6>;
+ regulator-compatible = "buck7";
+ regulator-min-microvolt = <1605000>;
+ regulator-max-microvolt = <1995000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ buck8_reg: regulator@7 {
+ reg = <7>;
+ regulator-compatible = "buck8";
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1400000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ ldo1_reg: regulator@8 {
+ reg = <8>;
+ regulator-compatible = "ldo1";
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ ldo2_reg: regulator@9 {
+ reg = <9>;
+ regulator-compatible = "ldo2";
+ regulator-min-microvolt = <900000>;
+ regulator-max-microvolt = <900000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ ldo3_reg: regulator@10 {
+ reg = <10>;
+ regulator-compatible = "ldo3";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ ldo4_reg: regulator@11 {
+ reg = <11>;
+ regulator-compatible = "ldo4";
+ regulator-min-microvolt = <900000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ ldo5_reg: regulator@12 {
+ reg = <12>;
+ regulator-compatible = "ldo5";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ ldo6_reg: regulator@13 {
+ reg = <13>;
+ regulator-compatible = "ldo6";
+ regulator-min-microvolt = <900000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ ldo7_reg: regulator@14 {
+ reg = <14>;
+ regulator-compatible = "ldo7";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ };
+ };
+ };
+};
+
+&i2c2 {
+ clock-frequency = <400000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c2>;
+ status = "okay";
+
+ typec1_ptn5110: tcpci@50 {
+ compatible = "usb,tcpci";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_typec1>;
+ reg = <0x50>;
+ interrupt-parent = <&gpio2>;
+ interrupts = <11 8>;
+ src-pdos = <0x380190c8>;
+ snk-pdos = <0x380190c8>;
+ /* Only can sink 5V for safe */
+ max-snk-mv = <5000>;
+ max-snk-ma = <3000>;
+ op-snk-mw = <10000>;
+ max-snk-mw = <15000>;
+ port-type = "drp";
+ default-role = "sink";
+ status = "okay";
+ };
+
+ typec2_ptn5110: tcpci@52 {
+ compatible = "usb,tcpci";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_typec2>;
+ reg = <0x52>;
+ interrupt-parent = <&gpio2>;
+ interrupts = <12 8>;
+ src-pdos = <0x380190c8>;
+ snk-pdos = <0x380190c8>;
+ /* Only can sink 5V for safe */
+ max-snk-mv = <5000>;
+ max-snk-ma = <3000>;
+ op-snk-mw = <10000>;
+ max-snk-mw = <15000>;
+ port-type = "drp";
+ default-role = "sink";
+ status = "disabled";
+ };
+};
+
+&i2c3 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c3>;
+ status = "okay";
+
+ pca6416: gpio@20 {
+ compatible = "ti,tca6416";
+ reg = <0x20>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+};
+
+&mu {
+ status = "okay";
+};
+
+&rpmsg{
+ /*
+ * 64K for one rpmsg instance:
+ * --0xb8000000~0xb800ffff: pingpong
+ */
+ vdev-nums = <1>;
+ reg = <0x0 0xb8000000 0x0 0x10000>;
+ status = "okay";
+};
+
+&fec1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_fec1>;
+ phy-mode = "rgmii-id";
+ phy-handle = <&ethphy0>;
+ fsl,magic-packet;
+ status = "okay";
+
+ mdio {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ethphy0: ethernet-phy@0 {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <0>;
+ at803x,led-act-blind-workaround;
+ at803x,eee-okay;
+ at803x,vddio-1p8v;
+ };
+ };
+};
+
+&uart2 { /* console */
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart2>;
+ status = "okay";
+};
+
+&usbotg1 {
+ dr_mode = "otg";
+ extcon = <0>, <&typec1_ptn5110>;
+ status = "okay";
+};
+
+&usbotg2 {
+ dr_mode = "otg";
+ extcon = <0>, <&typec2_ptn5110>;
+ status = "disabled";
+};
+
+&usdhc2 {
+ pinctrl-names = "default", "state_100mhz", "state_200mhz";
+ pinctrl-0 = <&pinctrl_usdhc2>, <&pinctrl_usdhc2_gpio>;
+ pinctrl-1 = <&pinctrl_usdhc2_100mhz>, <&pinctrl_usdhc2_gpio>;
+ pinctrl-2 = <&pinctrl_usdhc2_200mhz>, <&pinctrl_usdhc2_gpio>;
+ bus-width = <4>;
+ non-removable;
+ vmmc-supply = <&reg_usdhc2_vmmc>;
+ 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>;
+ non-removable;
+ status = "okay";
+};
+
+&wdog1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_wdog>;
+ fsl,ext-reset-output;
+ status = "okay";
+};
+
+&A53_0 {
+ arm-supply = <&buck2_reg>;
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8mm-evk-ak4497.dts b/arch/arm64/boot/dts/freescale/fsl-imx8mm-evk-ak4497.dts
new file mode 100644
index 000000000000..438856d84d64
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8mm-evk-ak4497.dts
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2018 NXP
+ *
+ * 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 "fsl-imx8mm-evk.dts"
+
+/ {
+ sound-ak4458 {
+ status = "disabled";
+ };
+
+ sound-ak4497 {
+ status = "okay";
+ };
+};
+
+&iomuxc {
+ imx8mm-evk {
+ pinctrl_sai1_pcm: sai1grp_pcm {
+ fsl,pins = <
+ MX8MM_IOMUXC_SAI1_MCLK_SAI1_MCLK 0xd6
+ MX8MM_IOMUXC_SAI1_TXFS_SAI1_TX_SYNC 0xd6
+ MX8MM_IOMUXC_SAI1_RXD7_SAI1_TX_SYNC 0xd6
+ MX8MM_IOMUXC_SAI1_TXC_SAI1_TX_BCLK 0xd6
+ MX8MM_IOMUXC_SAI1_TXD0_SAI1_TX_DATA0 0xd6
+ MX8MM_IOMUXC_SAI1_TXD1_SAI1_TX_DATA1 0xd6
+ MX8MM_IOMUXC_SAI1_TXD2_SAI1_TX_DATA2 0xd6
+ MX8MM_IOMUXC_SAI1_TXD3_SAI1_TX_DATA3 0xd6
+ MX8MM_IOMUXC_SAI1_TXD4_SAI1_TX_DATA4 0xd6
+ MX8MM_IOMUXC_SAI1_TXD5_SAI1_TX_DATA5 0xd6
+ MX8MM_IOMUXC_SAI1_TXD6_SAI1_TX_DATA6 0xd6
+ MX8MM_IOMUXC_SAI1_TXD7_SAI1_TX_DATA7 0xd6
+ >;
+ };
+
+ pinctrl_sai1_dsd: sai1grp_dsd {
+ fsl,pins = <
+ MX8MM_IOMUXC_SAI1_MCLK_SAI1_MCLK 0xd6
+ MX8MM_IOMUXC_SAI1_TXFS_SAI1_TX_SYNC 0xd6
+ MX8MM_IOMUXC_SAI1_RXD7_SAI1_TX_DATA4 0xd6
+ MX8MM_IOMUXC_SAI1_TXC_SAI1_TX_BCLK 0xd6
+ MX8MM_IOMUXC_SAI1_TXD0_SAI1_TX_DATA0 0xd6
+ MX8MM_IOMUXC_SAI1_TXD1_SAI1_TX_DATA1 0xd6
+ MX8MM_IOMUXC_SAI1_TXD2_SAI1_TX_DATA2 0xd6
+ MX8MM_IOMUXC_SAI1_TXD3_SAI1_TX_DATA3 0xd6
+ MX8MM_IOMUXC_SAI1_TXD4_SAI1_TX_DATA4 0xd6
+ MX8MM_IOMUXC_SAI1_TXD5_SAI1_TX_DATA5 0xd6
+ MX8MM_IOMUXC_SAI1_TXD6_SAI1_TX_DATA6 0xd6
+ MX8MM_IOMUXC_SAI1_TXD7_SAI1_TX_DATA7 0xd6
+ >;
+ };
+ };
+};
+
+&sai1 {
+ pinctrl-names = "default", "dsd";
+ pinctrl-0 = <&pinctrl_sai1_pcm>;
+ pinctrl-1 = <&pinctrl_sai1_dsd>;
+ assigned-clocks = <&clk IMX8MM_CLK_SAI1_SRC>,
+ <&clk IMX8MM_CLK_SAI1_DIV>;
+ assigned-clock-parents = <&clk IMX8MM_AUDIO_PLL2_OUT>;
+ assigned-clock-rates = <0>, <22579200>;
+ fsl,sai-multi-lane;
+ fsl,dataline,dsd = <0 0xff 0x11>;
+ dmas = <&sdma2 0 26 0>, <&sdma2 1 26 0>;
+ status = "okay";
+};
+
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8mm-evk-ak5558.dts b/arch/arm64/boot/dts/freescale/fsl-imx8mm-evk-ak5558.dts
new file mode 100644
index 000000000000..0268b09a2755
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8mm-evk-ak5558.dts
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2017 NXP
+ *
+ * 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 "fsl-imx8mm-evk.dts"
+
+/ {
+ sound-ak5558 {
+ status = "okay";
+ };
+ sound-micfil {
+ status = "disabled";
+ };
+};
+
+&micfil {
+ status = "disabled";
+};
+
+&sai5 {
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8mm-evk-audio-tdm.dts b/arch/arm64/boot/dts/freescale/fsl-imx8mm-evk-audio-tdm.dts
new file mode 100644
index 000000000000..fc1826bb90cd
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8mm-evk-audio-tdm.dts
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2018 NXP
+ *
+ * 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 "fsl-imx8mm-evk-ak5558.dts"
+
+/ {
+ sound-ak4458 {
+ fsl,tdm;
+ };
+
+ sound-ak5558 {
+ fsl,tdm;
+ };
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8mm-evk-inmate.dts b/arch/arm64/boot/dts/freescale/fsl-imx8mm-evk-inmate.dts
new file mode 100644
index 000000000000..2d20584b540e
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8mm-evk-inmate.dts
@@ -0,0 +1,224 @@
+/*
+ * Copyright 2019 NXP
+ *
+ * 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.
+ */
+
+/dts-v1/;
+
+#include "fsl-imx8mm.dtsi"
+
+/ {
+ model = "Freescale i.MX8MM EVK";
+ compatible = "fsl,imx8mm-evk", "fsl,imx8mm";
+ interrupt-parent = <&gic>;
+
+ timer {
+ compatible = "arm,armv8-timer";
+ interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>, /* Physical Secure */
+ <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>, /* Physical Non-Secure */
+ <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>, /* Virtual */
+ <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>; /* Hypervisor */
+ clock-frequency = <8333333>;
+ };
+
+ clocks {
+ clk_dummy: clock@7 {
+ compatible = "fixed-clock";
+ reg = <7>;
+ #clock-cells = <0>;
+ clock-frequency = <0>;
+ clock-output-names = "clk_dummy";
+ };
+
+ /* The clocks are configured by 1st OS */
+ clk_200m: clock@8 {
+ compatible = "fixed-clock";
+ reg = <8>;
+ #clock-cells = <0>;
+ clock-frequency = <200000000>;
+ clock-output-names = "200m";
+ };
+ clk_266m: clock@9 {
+ compatible = "fixed-clock";
+ reg = <9>;
+ #clock-cells = <0>;
+ clock-frequency = <266000000>;
+ clock-output-names = "266m";
+ };
+ clk_80m: clock@10 {
+ compatible = "fixed-clock";
+ reg = <10>;
+ #clock-cells = <0>;
+ clock-frequency = <80000000>;
+ clock-output-names = "80m";
+ };
+ };
+
+ display-subsystem {
+ /delete-property/ compatible;
+ };
+
+ pci@bb800000 {
+ compatible = "pci-host-ecam-generic";
+ device_type = "pci";
+ bus-range = <0 0>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ #interrupt-cells = <1>;
+ interrupt-map-mask = <0 0 0 7>;
+ interrupt-map = <0 0 0 1 &gic GIC_SPI 76 IRQ_TYPE_EDGE_RISING>;
+ reg = <0x0 0xbb800000 0x0 0x100000>;
+ ranges = <0x02000000 0x00 0x10000000 0x0 0x10000000 0x00 0x10000>;
+ };
+};
+
+/delete-node/ &{/memory@40000000};
+/delete-node/ &{/reserved-memory};
+/delete-node/ &{/busfreq};
+/delete-node/ &ddr_pmu0;
+
+&hsio_pd {
+ status = "disabled";
+};
+
+&pcie0_pd {
+ status = "disabled";
+};
+
+&usb_otg1_pd {
+ status = "disabled";
+};
+
+&usb_otg2_pd {
+ status = "disabled";
+};
+
+&gpumix_pd {
+ status = "disabled";
+};
+
+&vpumix_pd {
+ status = "disabled";
+};
+
+&vpu_g1_pd {
+ status = "disabled";
+};
+
+&vpu_g2_pd {
+ status = "disabled";
+};
+
+&vpu_h1_pd {
+ status = "disabled";
+};
+
+&dispmix_pd {
+ status = "disabled";
+};
+
+&mipi_pd {
+ status = "disabled";
+};
+
+&gpio1 {
+ status = "disabled";
+};
+&gpio2 {
+ status = "disabled";
+};
+&gpio3 {
+ status = "disabled";
+};
+&gpio4 {
+ status = "disabled";
+};
+&gpio5 {
+ status = "disabled";
+};
+
+/delete-node/ &tmu;
+/delete-node/ &{/thermal-zones};
+/delete-node/ &iomuxc;
+
+&gpr {
+ /delete-property/ compatible;
+};
+
+/delete-node/ &anatop;
+/delete-node/ &snvs;
+
+&clk {
+ /delete-property/ compatible;
+};
+
+&src {
+ /delete-property/ compatible;
+};
+
+/delete-node/ &system_counter;
+
+/delete-node/ &imx_rpmsg;
+/delete-node/ &ocotp;
+
+&dispmix_gpr {
+ /delete-property/ compatible;
+};
+
+&sdma1 {
+ status = "disabled";
+};
+
+&sdma2 {
+ status = "disabled";
+};
+
+&sdma3 {
+ status = "disabled";
+};
+
+/delete-node/ &{/imx_ion};
+/delete-node/ &pcie0;
+/delete-node/ &crypto;
+/delete-node/ &caam_sm;
+/delete-node/ &caam_snvs;
+/delete-node/ &irq_sec_vio;
+
+/delete-node/ &{/cpus/cpu@0};
+/delete-node/ &{/cpus/cpu@1};
+/delete-node/ &{/pmu};
+
+&gic {
+ reg = <0x0 0x38800000 0 0x10000>, /* GIC Dist */
+ <0x0 0x38880000 0 0xC0000>; /* GICR (RD_base + SGI_base) */
+};
+
+&uart4 {
+ clocks = <&osc_24m>,
+ <&osc_24m>;
+ clock-names = "ipg", "per";
+ /delete-property/ dmas;
+ /delete-property/ dmas-names;
+ status = "okay";
+};
+
+&usdhc3 {
+ clocks = <&clk_dummy>,
+ <&clk_266m>,
+ <&clk_200m>;
+ /delete-property/assigned-clocks;
+ /delete-property/assigned-clock-rates;
+ clock-names = "ipg", "ahb", "per";
+ bus-width = <8>;
+ non-removable;
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8mm-evk-m4.dts b/arch/arm64/boot/dts/freescale/fsl-imx8mm-evk-m4.dts
new file mode 100644
index 000000000000..52bf4db5b0a1
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8mm-evk-m4.dts
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2018 NXP
+ *
+ * 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 "fsl-imx8mm-evk.dts"
+
+/ {
+ reserved-memory {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ m4_reserved: m4@0x80000000 {
+ no-map;
+ reg = <0 0x80000000 0 0x1000000>;
+ };
+
+ };
+
+ rpmsg_i2s: rpmsg-i2s {
+ compatible = "fsl,imx8mq-rpmsg-i2s";
+ /* the audio device index in m4 domain */
+ fsl,audioindex = <0> ;
+ fsl,dma-buffer-size = <0x6000000>;
+ fsl,enable-lpa;
+ status = "okay";
+ };
+
+ sound-rpmsg {
+ compatible = "fsl,imx-audio-rpmsg";
+ model = "ak4497-audio";
+ cpu-dai = <&rpmsg_i2s>;
+ rpmsg-out;
+ };
+
+};
+
+/*
+ * ATTENTION: M4 may use IPs like below
+ * ECSPI0/ECSPI2, GPIO1/GPIO5, GPT1, I2C3, I2S3, WDOG1, UART4, PWM3, SDMA1
+ */
+
+&i2c3 {
+ status = "disabled";
+};
+
+&rpmsg{
+ /*
+ * 64K for one rpmsg instance:
+ * --0xb8000000~0xb800ffff: pingpong
+ */
+ vdev-nums = <1>;
+ reg = <0x0 0xb8000000 0x0 0x10000>;
+ status = "okay";
+};
+
+&sdma1{
+ status = "disabled";
+};
+
+&uart4 {
+ status = "disabled";
+};
+
+&sdma3 {
+ status = "disabled";
+};
+
+&sai1 {
+ status = "disabled";
+};
+
+&flexspi {
+ status = "disabled";
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8mm-evk-revb-rm67191.dts b/arch/arm64/boot/dts/freescale/fsl-imx8mm-evk-revb-rm67191.dts
new file mode 100644
index 000000000000..02c2c0430a14
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8mm-evk-revb-rm67191.dts
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2018 NXP
+ *
+ * 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 "fsl-imx8mm-evk-revb.dts"
+
+&adv_bridge {
+ status = "disabled";
+};
+
+&mipi_dsi {
+ panel@0 {
+ compatible = "raydium,rm67191";
+ reg = <0>;
+ pinctrl-0 = <&pinctrl_mipi_dsi_en>;
+ reset-gpio = <&gpio1 8 GPIO_ACTIVE_HIGH>;
+ dsi-lanes = <4>;
+ video-mode = <2>; /* 0: burst mode
+ * 1: non-burst mode with sync event
+ * 2: non-burst mode with sync pulse
+ */
+ panel-width-mm = <68>;
+ panel-height-mm = <121>;
+ status = "okay";
+ };
+};
+
+&i2c2 {
+ synaptics_dsx_ts@20 {
+ compatible = "synaptics_dsx";
+ reg = <0x20>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c2_synaptics_dsx_io>;
+ interrupt-parent = <&gpio1>;
+ interrupts = <9 IRQ_TYPE_LEVEL_LOW>;
+ synaptics,diagonal-rotation;
+ status = "okay";
+ };
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8mm-evk-revb.dts b/arch/arm64/boot/dts/freescale/fsl-imx8mm-evk-revb.dts
new file mode 100644
index 000000000000..c2f89aa7002c
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8mm-evk-revb.dts
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2018 NXP
+ *
+ * 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.
+ */
+
+/dts-v1/;
+
+#include "fsl-imx8mm-evk.dts"
+
+/ {
+ model = "FSL i.MX8MM EVK RevB board";
+};
+
+/*
+ * External OSC is used as PCIe REFCLK on RevC board.
+ * Use the -revb.dts file to distiguish the different
+ * HW design.
+ */
+&pcie0{
+ ext_osc = <0>;
+ status = "okay";
+};
+
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8mm-evk-rm67191.dts b/arch/arm64/boot/dts/freescale/fsl-imx8mm-evk-rm67191.dts
new file mode 100644
index 000000000000..d7c17e33ffdf
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8mm-evk-rm67191.dts
@@ -0,0 +1,35 @@
+#include "fsl-imx8mm-evk.dts"
+
+&adv_bridge {
+ status = "disabled";
+};
+
+&mipi_dsi {
+ panel@0 {
+ compatible = "raydium,rm67191";
+ reg = <0>;
+ pinctrl-0 = <&pinctrl_mipi_dsi_en>;
+ reset-gpio = <&gpio1 8 GPIO_ACTIVE_HIGH>;
+ dsi-lanes = <4>;
+ video-mode = <2>; /* 0: burst mode
+ * 1: non-burst mode with sync event
+ * 2: non-burst mode with sync pulse
+ */
+ panel-width-mm = <68>;
+ panel-height-mm = <121>;
+ status = "okay";
+ };
+};
+
+&i2c2 {
+ synaptics_dsx_ts@20 {
+ compatible = "synaptics_dsx";
+ reg = <0x20>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c2_synaptics_dsx_io>;
+ interrupt-parent = <&gpio1>;
+ interrupts = <9 IRQ_TYPE_LEVEL_LOW>;
+ synaptics,diagonal-rotation;
+ status = "okay";
+ };
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8mm-evk-root.dts b/arch/arm64/boot/dts/freescale/fsl-imx8mm-evk-root.dts
new file mode 100644
index 000000000000..7486510df83a
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8mm-evk-root.dts
@@ -0,0 +1,113 @@
+/*
+ * Copyright 2018 NXP
+ *
+ * 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 "fsl-imx8mm-evk.dts"
+
+/ {
+ interrupt-parent = <&gic>;
+};
+
+/delete-node/ &gpc;
+
+&CPU_SLEEP {
+ /* We are not using GPC for now, need set 0 to avoid hang */
+ /delete-property/ compatible;
+ /*arm,psci-suspend-param = <0x0>;*/
+};
+
+&clk {
+ init-on-array = <IMX8MM_CLK_AHB_CG IMX8MM_CLK_DRAM_CORE
+ IMX8MM_CLK_NOC_CG IMX8MM_CLK_NOC_APB_CG
+ IMX8MM_CLK_USB_BUS_CG
+ IMX8MM_CLK_MAIN_AXI_CG IMX8MM_CLK_AUDIO_AHB_CG
+ IMX8MM_CLK_DRAM_APB_DIV IMX8MM_CLK_A53_DIV
+ IMX8MM_ARM_PLL_OUT IMX8MM_CLK_DISP_AXI_CG
+ IMX8MM_CLK_DISP_APB_CG
+ IMX8MM_CLK_NAND_USDHC_BUS_CG
+ IMX8MM_CLK_USDHC3_ROOT
+ IMX8MM_CLK_UART4_ROOT>;
+};
+
+&iomuxc {
+ imx8mq-evk {
+ /*
+ * Used for the 2nd Linux.
+ * TODO: M4 may use these pins.
+ */
+ pinctrl_uart4: uart4grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_UART4_RXD_UART4_DCE_RX 0x140
+ MX8MM_IOMUXC_UART4_TXD_UART4_DCE_TX 0x140
+ >;
+ };
+
+ };
+};
+
+&{/busfreq} {
+ /* Disable busfreq, to avoid 1st Linux busfreq crash other inmates */
+ status = "disabled";
+};
+
+&{/reserved-memory} {
+
+ ivshmem_reserved: ivshmem@0xbbb00000 {
+ no-map;
+ reg = <0 0xbbb00000 0x0 0x00100000>;
+ };
+
+ ivshmem2_reserved: ivshmem2@0xbba00000 {
+ no-map;
+ reg = <0 0xbba00000 0x0 0x00100000>;
+ };
+
+ pci_reserved: pci@0xbb800000 {
+ no-map;
+ reg = <0 0xbb800000 0x0 0x00200000>;
+ };
+
+ loader_reserved: loader@0xbb700000 {
+ no-map;
+ reg = <0 0xbb700000 0x0 0x00100000>;
+ };
+
+ jh_reserved: jh@0xb7c00000 {
+ no-map;
+ reg = <0 0xb7c00000 0x0 0x00400000>;
+ };
+
+ /* 512MB */
+ inmate_reserved: inmate@0x93c00000 {
+ no-map;
+ reg = <0 0x93c00000 0x0 0x24000000>;
+ };
+};
+
+&uart2 {
+ /* uart2 is used by the 2nd OS, so configure pin and clk */
+ pinctrl-0 = <&pinctrl_uart2>, <&pinctrl_uart4>;
+ assigned-clocks = <&clk IMX8MM_CLK_UART4_SRC>;
+ assigned-clock-parents = <&clk IMX8MM_CLK_24M>;
+};
+
+&usdhc3 {
+ status = "disabled";
+};
+
+&usdhc2 {
+ /* sdhc3 is used by 2nd linux, configure the pin */
+ pinctrl-0 = <&pinctrl_usdhc3>, <&pinctrl_usdhc2>, <&pinctrl_usdhc2_gpio>;
+ pinctrl-1 = <&pinctrl_usdhc3>, <&pinctrl_usdhc2_100mhz>, <&pinctrl_usdhc2_gpio>;
+ pinctrl-2 = <&pinctrl_usdhc3>, <&pinctrl_usdhc2_200mhz>, <&pinctrl_usdhc2_gpio>;
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8mm-evk.dts b/arch/arm64/boot/dts/freescale/fsl-imx8mm-evk.dts
new file mode 100755
index 000000000000..57de82ec4e76
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8mm-evk.dts
@@ -0,0 +1,1045 @@
+/*
+ * Copyright 2018 NXP
+ *
+ * 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.
+ */
+
+/dts-v1/;
+
+#include "fsl-imx8mm.dtsi"
+
+/ {
+ model = "FSL i.MX8MM EVK board";
+ compatible = "fsl,imx8mm-evk", "fsl,imx8mm";
+
+ chosen {
+ bootargs = "console=ttymxc1,115200 earlycon=ec_imx6q,0x30890000,115200";
+ stdout-path = &uart2;
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpio_led>;
+
+ status {
+ label = "status";
+ gpios = <&gpio3 16 0>;
+ default-state = "on";
+ };
+ };
+
+ modem_reset: modem-reset {
+ compatible = "gpio-reset";
+ reset-gpios = <&gpio2 6 GPIO_ACTIVE_LOW>;
+ reset-delay-us = <2000>;
+ reset-post-delay-ms = <40>;
+ #reset-cells = <0>;
+ };
+
+ ir_recv: ir-receiver {
+ compatible = "gpio-ir-receiver";
+ gpios = <&gpio1 13 GPIO_ACTIVE_LOW>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ir_recv>;
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ reg_sd1_vmmc: sd1_regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "WLAN_EN";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&gpio2 10 GPIO_ACTIVE_HIGH>;
+ off-on-delay = <20000>;
+ startup-delay-us = <100>;
+ enable-active-high;
+ };
+
+ reg_usdhc2_vmmc: regulator-usdhc2 {
+ compatible = "regulator-fixed";
+ regulator-name = "VSD_3V3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&gpio2 19 GPIO_ACTIVE_HIGH>;
+ off-on-delay = <20000>;
+ enable-active-high;
+ };
+
+ reg_audio_board: regulator-audio-board {
+ compatible = "regulator-fixed";
+ regulator-name = "EXT_PWREN";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ enable-active-high;
+ startup-delay-us = <300000>;
+ gpio = <&pca6416 1 GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ wm8524: wm8524 {
+ compatible = "wlf,wm8524";
+ clocks = <&clk IMX8MM_CLK_SAI3_ROOT>;
+ clock-names = "mclk";
+ wlf,mute-gpios = <&gpio5 21 GPIO_ACTIVE_LOW>;
+ };
+
+ sound-wm8524 {
+ compatible = "fsl,imx-audio-wm8524";
+ model = "wm8524-audio";
+ audio-cpu = <&sai3>;
+ audio-codec = <&wm8524>;
+ audio-routing =
+ "Line Out Jack", "LINEVOUTL",
+ "Line Out Jack", "LINEVOUTR";
+ };
+
+ sound-ak4458 {
+ compatible = "fsl,imx-audio-ak4458";
+ model = "ak4458-audio";
+ audio-cpu = <&sai1>;
+ audio-codec = <&ak4458_1>, <&ak4458_2>;
+ ak4458,pdn-gpio = <&pca6416 4 GPIO_ACTIVE_HIGH>;
+ };
+
+ sound-ak5558 {
+ compatible = "fsl,imx-audio-ak5558";
+ model = "ak5558-audio";
+ audio-cpu = <&sai5>;
+ audio-codec = <&ak5558>;
+ status = "disabled";
+ };
+
+ sound-ak4497 {
+ compatible = "fsl,imx-audio-ak4497";
+ model = "ak4497-audio";
+ audio-cpu = <&sai1>;
+ audio-codec = <&ak4497>;
+ status = "disabled";
+ };
+
+ sound-spdif {
+ compatible = "fsl,imx-audio-spdif";
+ model = "imx-spdif";
+ spdif-controller = <&spdif1>;
+ spdif-out;
+ spdif-in;
+ };
+
+ sound-micfil {
+ compatible = "fsl,imx-audio-micfil";
+ model = "imx-audio-micfil";
+ cpu-dai = <&micfil>;
+ };
+};
+
+&clk {
+ assigned-clocks = <&clk IMX8MM_AUDIO_PLL1>, <&clk IMX8MM_AUDIO_PLL2>;
+ assigned-clock-rates = <786432000>, <722534400>;
+};
+
+&iomuxc {
+ pinctrl-names = "default";
+
+ imx8mm-evk {
+ pinctrl_csi_pwn: csi_pwn_grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_GPIO1_IO07_GPIO1_IO7 0x19
+ >;
+ };
+
+ pinctrl_ir_recv: ir_recv {
+ fsl,pins = <
+ MX8MM_IOMUXC_GPIO1_IO13_GPIO1_IO13 0x14f
+ >;
+ };
+
+ pinctrl_csi_rst: csi_rst_grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_GPIO1_IO06_GPIO1_IO6 0x19
+ MX8MM_IOMUXC_GPIO1_IO14_CCMSRCGPCMIX_CLKO1 0x59
+ >;
+ };
+
+ pinctrl_mipi_dsi_en: mipi_dsi_en {
+ fsl,pins = <
+ MX8MM_IOMUXC_GPIO1_IO08_GPIO1_IO8 0x16
+ >;
+ };
+
+ pinctrl_i2c2_synaptics_dsx_io: synaptics_dsx_iogrp {
+ fsl,pins = <
+ MX8MM_IOMUXC_GPIO1_IO09_GPIO1_IO9 0x19 /* Touch int */
+ >;
+ };
+
+ pinctrl_fec1: fec1grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_ENET_MDC_ENET1_MDC 0x3
+ MX8MM_IOMUXC_ENET_MDIO_ENET1_MDIO 0x3
+ MX8MM_IOMUXC_ENET_TD3_ENET1_RGMII_TD3 0x1f
+ MX8MM_IOMUXC_ENET_TD2_ENET1_RGMII_TD2 0x1f
+ MX8MM_IOMUXC_ENET_TD1_ENET1_RGMII_TD1 0x1f
+ MX8MM_IOMUXC_ENET_TD0_ENET1_RGMII_TD0 0x1f
+ MX8MM_IOMUXC_ENET_RD3_ENET1_RGMII_RD3 0x91
+ MX8MM_IOMUXC_ENET_RD2_ENET1_RGMII_RD2 0x91
+ MX8MM_IOMUXC_ENET_RD1_ENET1_RGMII_RD1 0x91
+ MX8MM_IOMUXC_ENET_RD0_ENET1_RGMII_RD0 0x91
+ MX8MM_IOMUXC_ENET_TXC_ENET1_RGMII_TXC 0x1f
+ MX8MM_IOMUXC_ENET_RXC_ENET1_RGMII_RXC 0x91
+ MX8MM_IOMUXC_ENET_RX_CTL_ENET1_RGMII_RX_CTL 0x91
+ MX8MM_IOMUXC_ENET_TX_CTL_ENET1_RGMII_TX_CTL 0x1f
+ MX8MM_IOMUXC_SAI2_RXC_GPIO4_IO22 0x19
+ >;
+ };
+
+ pinctrl_flexspi0: flexspi0grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_NAND_ALE_QSPI_A_SCLK 0x1c2
+ MX8MM_IOMUXC_NAND_CE0_B_QSPI_A_SS0_B 0x82
+ MX8MM_IOMUXC_NAND_DATA00_QSPI_A_DATA0 0x82
+ MX8MM_IOMUXC_NAND_DATA01_QSPI_A_DATA1 0x82
+ MX8MM_IOMUXC_NAND_DATA02_QSPI_A_DATA2 0x82
+ MX8MM_IOMUXC_NAND_DATA03_QSPI_A_DATA3 0x82
+ >;
+ };
+
+ pinctrl_gpio_led: gpioledgrp {
+ fsl,pins = <
+ MX8MM_IOMUXC_NAND_READY_B_GPIO3_IO16 0x19
+ >;
+ };
+
+ pinctrl_i2c1: i2c1grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_I2C1_SCL_I2C1_SCL 0x400001c3
+ MX8MM_IOMUXC_I2C1_SDA_I2C1_SDA 0x400001c3
+ >;
+ };
+
+ pinctrl_i2c2: i2c2grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_I2C2_SCL_I2C2_SCL 0x400001c3
+ MX8MM_IOMUXC_I2C2_SDA_I2C2_SDA 0x400001c3
+ >;
+ };
+
+ pinctrl_i2c3: i2c3grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_I2C3_SCL_I2C3_SCL 0x400001c3
+ MX8MM_IOMUXC_I2C3_SDA_I2C3_SDA 0x400001c3
+ >;
+ };
+
+ pinctrl_pcie0: pcie0grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_I2C4_SCL_PCIE1_CLKREQ_B 0x61 /* open drain, pull up */
+ MX8MM_IOMUXC_GPIO1_IO05_GPIO1_IO5 0x41
+ MX8MM_IOMUXC_SAI2_RXFS_GPIO4_IO21 0x41
+ >;
+ };
+
+ pinctrl_pmic: pmicirq {
+ fsl,pins = <
+ MX8MM_IOMUXC_GPIO1_IO03_GPIO1_IO3 0x41
+ >;
+ };
+
+ pinctrl_typec1: typec1grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_SD1_STROBE_GPIO2_IO11 0x159
+ >;
+ };
+
+ pinctrl_typec2: typec2grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_SD2_CD_B_GPIO2_IO12 0x159
+ >;
+ };
+
+ pinctrl_sai1: sai1grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_SAI1_MCLK_SAI1_MCLK 0xd6
+ MX8MM_IOMUXC_SAI1_TXFS_SAI1_TX_SYNC 0xd6
+ MX8MM_IOMUXC_SAI1_RXD7_SAI1_TX_SYNC 0xd6
+ MX8MM_IOMUXC_SAI1_TXC_SAI1_TX_BCLK 0xd6
+ MX8MM_IOMUXC_SAI1_TXD0_SAI1_TX_DATA0 0xd6
+ MX8MM_IOMUXC_SAI1_TXD1_SAI1_TX_DATA1 0xd6
+ MX8MM_IOMUXC_SAI1_TXD2_SAI1_TX_DATA2 0xd6
+ MX8MM_IOMUXC_SAI1_TXD3_SAI1_TX_DATA3 0xd6
+ MX8MM_IOMUXC_SAI1_TXD4_SAI1_TX_DATA4 0xd6
+ MX8MM_IOMUXC_SAI1_TXD5_SAI1_TX_DATA5 0xd6
+ MX8MM_IOMUXC_SAI1_TXD6_SAI1_TX_DATA6 0xd6
+ MX8MM_IOMUXC_SAI1_TXD7_SAI1_TX_DATA7 0xd6
+ >;
+ };
+
+ pinctrl_sai1_dsd: sai1grp_dsd {
+ fsl,pins = <
+ MX8MM_IOMUXC_SAI1_MCLK_SAI1_MCLK 0xd6
+ MX8MM_IOMUXC_SAI1_TXFS_SAI1_TX_SYNC 0xd6
+ MX8MM_IOMUXC_SAI1_RXD7_SAI1_TX_DATA4 0xd6
+ MX8MM_IOMUXC_SAI1_TXC_SAI1_TX_BCLK 0xd6
+ MX8MM_IOMUXC_SAI1_TXD0_SAI1_TX_DATA0 0xd6
+ MX8MM_IOMUXC_SAI1_TXD1_SAI1_TX_DATA1 0xd6
+ MX8MM_IOMUXC_SAI1_TXD2_SAI1_TX_DATA2 0xd6
+ MX8MM_IOMUXC_SAI1_TXD3_SAI1_TX_DATA3 0xd6
+ MX8MM_IOMUXC_SAI1_TXD4_SAI1_TX_DATA4 0xd6
+ MX8MM_IOMUXC_SAI1_TXD5_SAI1_TX_DATA5 0xd6
+ MX8MM_IOMUXC_SAI1_TXD6_SAI1_TX_DATA6 0xd6
+ MX8MM_IOMUXC_SAI1_TXD7_SAI1_TX_DATA7 0xd6
+ >;
+ };
+
+ pinctrl_sai3: sai3grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_SAI3_TXFS_SAI3_TX_SYNC 0xd6
+ MX8MM_IOMUXC_SAI3_TXC_SAI3_TX_BCLK 0xd6
+ MX8MM_IOMUXC_SAI3_MCLK_SAI3_MCLK 0xd6
+ MX8MM_IOMUXC_SAI3_TXD_SAI3_TX_DATA0 0xd6
+ MX8MM_IOMUXC_I2C4_SDA_GPIO5_IO21 0xd6
+ >;
+ };
+
+ pinctrl_sai5: sai5grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_SAI5_MCLK_SAI5_MCLK 0xd6
+ MX8MM_IOMUXC_SAI5_RXC_SAI5_RX_BCLK 0xd6
+ MX8MM_IOMUXC_SAI5_RXFS_SAI5_RX_SYNC 0xd6
+ MX8MM_IOMUXC_SAI5_RXD0_SAI5_RX_DATA0 0xd6
+ MX8MM_IOMUXC_SAI5_RXD1_SAI5_RX_DATA1 0xd6
+ MX8MM_IOMUXC_SAI5_RXD2_SAI5_RX_DATA2 0xd6
+ MX8MM_IOMUXC_SAI5_RXD3_SAI5_RX_DATA3 0xd6
+ >;
+ };
+
+ pinctrl_pdm: pdmgrp {
+ fsl,pins = <
+ MX8MM_IOMUXC_SAI5_MCLK_SAI5_MCLK 0xd6
+ MX8MM_IOMUXC_SAI5_RXC_PDM_CLK 0xd6
+ MX8MM_IOMUXC_SAI5_RXFS_SAI5_RX_SYNC 0xd6
+ MX8MM_IOMUXC_SAI5_RXD0_PDM_DATA0 0xd6
+ MX8MM_IOMUXC_SAI5_RXD1_PDM_DATA1 0xd6
+ MX8MM_IOMUXC_SAI5_RXD2_PDM_DATA2 0xd6
+ MX8MM_IOMUXC_SAI5_RXD3_PDM_DATA3 0xd6
+ >;
+ };
+
+ pinctrl_spdif1: spdif1grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_SPDIF_TX_SPDIF1_OUT 0xd6
+ MX8MM_IOMUXC_SPDIF_RX_SPDIF1_IN 0xd6
+ >;
+ };
+
+ pinctrl_uart1: uart1grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_UART1_RXD_UART1_DCE_RX 0x140
+ MX8MM_IOMUXC_UART1_TXD_UART1_DCE_TX 0x140
+ MX8MM_IOMUXC_UART3_RXD_UART1_DCE_CTS_B 0x140
+ MX8MM_IOMUXC_UART3_TXD_UART1_DCE_RTS_B 0x140
+ MX8MM_IOMUXC_SD1_DATA4_GPIO2_IO6 0x19
+ >;
+ };
+
+ pinctrl_uart2: uart2grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_UART2_RXD_UART2_DCE_RX 0x140
+ MX8MM_IOMUXC_UART2_TXD_UART2_DCE_TX 0x140
+ >;
+ };
+
+ pinctrl_uart3: uart3grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_ECSPI1_SCLK_UART3_DCE_RX 0x140
+ MX8MM_IOMUXC_ECSPI1_MOSI_UART3_DCE_TX 0x140
+ MX8MM_IOMUXC_ECSPI1_SS0_UART3_DCE_RTS_B 0x140
+ MX8MM_IOMUXC_ECSPI1_MISO_UART3_DCE_CTS_B 0x140
+ >;
+ };
+
+ pinctrl_usdhc1_gpio: usdhc1grpgpio {
+ fsl,pins = <
+ MX8MM_IOMUXC_SD1_RESET_B_GPIO2_IO10 0x41
+ >;
+ };
+
+ pinctrl_usdhc1: usdhc1grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_SD1_CLK_USDHC1_CLK 0x190
+ MX8MM_IOMUXC_SD1_CMD_USDHC1_CMD 0x1d0
+ MX8MM_IOMUXC_SD1_DATA0_USDHC1_DATA0 0x1d0
+ MX8MM_IOMUXC_SD1_DATA1_USDHC1_DATA1 0x1d0
+ MX8MM_IOMUXC_SD1_DATA2_USDHC1_DATA2 0x1d0
+ MX8MM_IOMUXC_SD1_DATA3_USDHC1_DATA3 0x1d0
+ >;
+ };
+
+ pinctrl_usdhc1_100mhz: usdhc1grp100mhz {
+ fsl,pins = <
+ MX8MM_IOMUXC_SD1_CLK_USDHC1_CLK 0x194
+ MX8MM_IOMUXC_SD1_CMD_USDHC1_CMD 0x1d4
+ MX8MM_IOMUXC_SD1_DATA0_USDHC1_DATA0 0x1d4
+ MX8MM_IOMUXC_SD1_DATA1_USDHC1_DATA1 0x1d4
+ MX8MM_IOMUXC_SD1_DATA2_USDHC1_DATA2 0x1d4
+ MX8MM_IOMUXC_SD1_DATA3_USDHC1_DATA3 0x1d4
+ >;
+ };
+
+ pinctrl_usdhc1_200mhz: usdhc1grp200mhz {
+ fsl,pins = <
+ MX8MM_IOMUXC_SD1_CLK_USDHC1_CLK 0x196
+ MX8MM_IOMUXC_SD1_CMD_USDHC1_CMD 0x1d6
+ MX8MM_IOMUXC_SD1_DATA0_USDHC1_DATA0 0x1d6
+ MX8MM_IOMUXC_SD1_DATA1_USDHC1_DATA1 0x1d6
+ MX8MM_IOMUXC_SD1_DATA2_USDHC1_DATA2 0x1d6
+ MX8MM_IOMUXC_SD1_DATA3_USDHC1_DATA3 0x1d6
+ >;
+ };
+
+ pinctrl_usdhc2_gpio: usdhc2grpgpio {
+ fsl,pins = <
+ MX8MM_IOMUXC_GPIO1_IO15_GPIO1_IO15 0x1c4
+ MX8MM_IOMUXC_SD2_RESET_B_GPIO2_IO19 0x41
+ >;
+ };
+
+ pinctrl_usdhc2: usdhc2grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK 0x190
+ MX8MM_IOMUXC_SD2_CMD_USDHC2_CMD 0x1d0
+ MX8MM_IOMUXC_SD2_DATA0_USDHC2_DATA0 0x1d0
+ MX8MM_IOMUXC_SD2_DATA1_USDHC2_DATA1 0x1d0
+ MX8MM_IOMUXC_SD2_DATA2_USDHC2_DATA2 0x1d0
+ MX8MM_IOMUXC_SD2_DATA3_USDHC2_DATA3 0x1d0
+ MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0x1d0
+ >;
+ };
+
+ pinctrl_usdhc2_100mhz: usdhc2grp100mhz {
+ fsl,pins = <
+ MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK 0x194
+ MX8MM_IOMUXC_SD2_CMD_USDHC2_CMD 0x1d4
+ MX8MM_IOMUXC_SD2_DATA0_USDHC2_DATA0 0x1d4
+ MX8MM_IOMUXC_SD2_DATA1_USDHC2_DATA1 0x1d4
+ MX8MM_IOMUXC_SD2_DATA2_USDHC2_DATA2 0x1d4
+ MX8MM_IOMUXC_SD2_DATA3_USDHC2_DATA3 0x1d4
+ MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0x1d0
+ >;
+ };
+
+ pinctrl_usdhc2_200mhz: usdhc2grp200mhz {
+ fsl,pins = <
+ MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK 0x196
+ MX8MM_IOMUXC_SD2_CMD_USDHC2_CMD 0x1d6
+ MX8MM_IOMUXC_SD2_DATA0_USDHC2_DATA0 0x1d6
+ MX8MM_IOMUXC_SD2_DATA1_USDHC2_DATA1 0x1d6
+ MX8MM_IOMUXC_SD2_DATA2_USDHC2_DATA2 0x1d6
+ MX8MM_IOMUXC_SD2_DATA3_USDHC2_DATA3 0x1d6
+ MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0x1d0
+ >;
+ };
+
+ pinctrl_usdhc3: usdhc3grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_NAND_WE_B_USDHC3_CLK 0x190
+ MX8MM_IOMUXC_NAND_WP_B_USDHC3_CMD 0x1d0
+ MX8MM_IOMUXC_NAND_DATA04_USDHC3_DATA0 0x1d0
+ MX8MM_IOMUXC_NAND_DATA05_USDHC3_DATA1 0x1d0
+ MX8MM_IOMUXC_NAND_DATA06_USDHC3_DATA2 0x1d0
+ MX8MM_IOMUXC_NAND_DATA07_USDHC3_DATA3 0x1d0
+ MX8MM_IOMUXC_NAND_RE_B_USDHC3_DATA4 0x1d0
+ MX8MM_IOMUXC_NAND_CE2_B_USDHC3_DATA5 0x1d0
+ MX8MM_IOMUXC_NAND_CE3_B_USDHC3_DATA6 0x1d0
+ MX8MM_IOMUXC_NAND_CLE_USDHC3_DATA7 0x1d0
+ MX8MM_IOMUXC_NAND_CE1_B_USDHC3_STROBE 0x190
+ >;
+ };
+
+ pinctrl_usdhc3_100mhz: usdhc3grp100mhz {
+ fsl,pins = <
+ MX8MM_IOMUXC_NAND_WE_B_USDHC3_CLK 0x194
+ MX8MM_IOMUXC_NAND_WP_B_USDHC3_CMD 0x1d4
+ MX8MM_IOMUXC_NAND_DATA04_USDHC3_DATA0 0x1d4
+ MX8MM_IOMUXC_NAND_DATA05_USDHC3_DATA1 0x1d4
+ MX8MM_IOMUXC_NAND_DATA06_USDHC3_DATA2 0x1d4
+ MX8MM_IOMUXC_NAND_DATA07_USDHC3_DATA3 0x1d4
+ MX8MM_IOMUXC_NAND_RE_B_USDHC3_DATA4 0x1d4
+ MX8MM_IOMUXC_NAND_CE2_B_USDHC3_DATA5 0x1d4
+ MX8MM_IOMUXC_NAND_CE3_B_USDHC3_DATA6 0x1d4
+ MX8MM_IOMUXC_NAND_CLE_USDHC3_DATA7 0x1d4
+ MX8MM_IOMUXC_NAND_CE1_B_USDHC3_STROBE 0x194
+ >;
+ };
+
+ pinctrl_usdhc3_200mhz: usdhc3grp200mhz {
+ fsl,pins = <
+ MX8MM_IOMUXC_NAND_WE_B_USDHC3_CLK 0x196
+ MX8MM_IOMUXC_NAND_WP_B_USDHC3_CMD 0x1d6
+ MX8MM_IOMUXC_NAND_DATA04_USDHC3_DATA0 0x1d6
+ MX8MM_IOMUXC_NAND_DATA05_USDHC3_DATA1 0x1d6
+ MX8MM_IOMUXC_NAND_DATA06_USDHC3_DATA2 0x1d6
+ MX8MM_IOMUXC_NAND_DATA07_USDHC3_DATA3 0x1d6
+ MX8MM_IOMUXC_NAND_RE_B_USDHC3_DATA4 0x1d6
+ MX8MM_IOMUXC_NAND_CE2_B_USDHC3_DATA5 0x1d6
+ MX8MM_IOMUXC_NAND_CE3_B_USDHC3_DATA6 0x1d6
+ MX8MM_IOMUXC_NAND_CLE_USDHC3_DATA7 0x1d6
+ MX8MM_IOMUXC_NAND_CE1_B_USDHC3_STROBE 0x196
+ >;
+ };
+
+ pinctrl_wdog: wdoggrp {
+ fsl,pins = <
+ MX8MM_IOMUXC_GPIO1_IO02_WDOG1_WDOG_B 0xc6
+ >;
+ };
+ };
+};
+
+&csi1_bridge {
+ fsl,mipi-mode;
+ status = "okay";
+ port {
+ csi1_ep: endpoint {
+ remote-endpoint = <&csi1_mipi_ep>;
+ };
+ };
+};
+
+&flexspi {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_flexspi0>;
+ status = "okay";
+
+ flash0: mt25qu256aba@0 {
+ reg = <0>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "micron,mt25qu256aba";
+ spi-max-frequency = <80000000>;
+ spi-nor,ddr-quad-read-dummy = <6>;
+ };
+};
+
+&i2c1 {
+ clock-frequency = <400000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c1>;
+ status = "okay";
+
+ pmic: bd71837@4b {
+ reg = <0x4b>;
+ compatible = "rohm,bd71840", "rohm,bd71837";
+ /* PMIC BD71837 PMIC_nINT GPIO1_IO3 */
+ pinctrl-0 = <&pinctrl_pmic>;
+ gpio_intr = <&gpio1 3 GPIO_ACTIVE_LOW>;
+
+ gpo {
+ rohm,drv = <0x0C>; /* 0b0000_1100 all gpos with cmos output mode */
+ };
+
+ regulators {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ bd71837,pmic-buck2-uses-i2c-dvs;
+ bd71837,pmic-buck2-dvs-voltage = <1000000>, <900000>, <0>; /* VDD_ARM: Run-Idle */
+
+ buck1_reg: regulator@0 {
+ reg = <0>;
+ regulator-compatible = "buck1";
+ regulator-min-microvolt = <700000>;
+ regulator-max-microvolt = <1300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ regulator-ramp-delay = <1250>;
+ };
+
+ buck2_reg: regulator@1 {
+ reg = <1>;
+ regulator-compatible = "buck2";
+ regulator-min-microvolt = <700000>;
+ regulator-max-microvolt = <1300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ regulator-ramp-delay = <1250>;
+ };
+
+ buck3_reg: regulator@2 {
+ reg = <2>;
+ regulator-compatible = "buck3";
+ regulator-min-microvolt = <700000>;
+ regulator-max-microvolt = <1300000>;
+ };
+
+ buck4_reg: regulator@3 {
+ reg = <3>;
+ regulator-compatible = "buck4";
+ regulator-min-microvolt = <700000>;
+ regulator-max-microvolt = <1300000>;
+ };
+
+ buck5_reg: regulator@4 {
+ reg = <4>;
+ regulator-compatible = "buck5";
+ regulator-min-microvolt = <700000>;
+ regulator-max-microvolt = <1350000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ buck6_reg: regulator@5 {
+ reg = <5>;
+ regulator-compatible = "buck6";
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ buck7_reg: regulator@6 {
+ reg = <6>;
+ regulator-compatible = "buck7";
+ regulator-min-microvolt = <1605000>;
+ regulator-max-microvolt = <1995000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ buck8_reg: regulator@7 {
+ reg = <7>;
+ regulator-compatible = "buck8";
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1400000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ ldo1_reg: regulator@8 {
+ reg = <8>;
+ regulator-compatible = "ldo1";
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ ldo2_reg: regulator@9 {
+ reg = <9>;
+ regulator-compatible = "ldo2";
+ regulator-min-microvolt = <900000>;
+ regulator-max-microvolt = <900000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ ldo3_reg: regulator@10 {
+ reg = <10>;
+ regulator-compatible = "ldo3";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ ldo4_reg: regulator@11 {
+ reg = <11>;
+ regulator-compatible = "ldo4";
+ regulator-min-microvolt = <900000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ ldo6_reg: regulator@13 {
+ reg = <13>;
+ regulator-compatible = "ldo6";
+ regulator-min-microvolt = <900000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+ };
+ };
+};
+
+&i2c2 {
+ clock-frequency = <400000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c2>;
+ status = "okay";
+
+ adv_bridge: adv7535@3d {
+ compatible = "adi,adv7533";
+ reg = <0x3d>;
+ adi,addr-cec = <0x3b>;
+ adi,dsi-lanes = <4>;
+ status = "okay";
+
+ port {
+ adv7535_from_dsim: endpoint {
+ remote-endpoint = <&dsim_to_adv7535>;
+ };
+ };
+ };
+
+ typec1_ptn5110: tcpci@50 {
+ compatible = "usb,tcpci";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_typec1>;
+ reg = <0x50>;
+ interrupt-parent = <&gpio2>;
+ interrupts = <11 8>;
+ src-pdos = <0x380190c8>;
+ snk-pdos = <0x380190c8>;
+ /* Only can sink 5V for safe */
+ max-snk-mv = <5000>;
+ max-snk-ma = <3000>;
+ op-snk-mw = <10000>;
+ max-snk-mw = <15000>;
+ port-type = "drp";
+ default-role = "sink";
+ status = "okay";
+ };
+
+ typec2_ptn5110: tcpci@52 {
+ compatible = "usb,tcpci";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_typec2>;
+ reg = <0x52>;
+ interrupt-parent = <&gpio2>;
+ interrupts = <12 8>;
+ src-pdos = <0x380190c8>;
+ snk-pdos = <0x380190c8>;
+ /* Only can sink 5V for safe */
+ max-snk-mv = <5000>;
+ max-snk-ma = <3000>;
+ op-snk-mw = <10000>;
+ max-snk-mw = <15000>;
+ port-type = "drp";
+ default-role = "sink";
+ status = "okay";
+ };
+};
+
+
+&mipi_csi_1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "okay";
+ port {
+ mipi1_sensor_ep: endpoint1 {
+ remote-endpoint = <&ov5640_mipi1_ep>;
+ data-lanes = <2>;
+ csis-hs-settle = <13>;
+ csis-clk-settle = <2>;
+ csis-wclk;
+ };
+
+ csi1_mipi_ep: endpoint2 {
+ remote-endpoint = <&csi1_ep>;
+ };
+ };
+};
+
+&i2c3 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c3>;
+ status = "okay";
+
+ pca6416: gpio@20 {
+ compatible = "ti,tca6416";
+ reg = <0x20>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ ak4458_1: ak4458@10 {
+ compatible = "asahi-kasei,ak4458";
+ reg = <0x10>;
+ AVDD-supply = <&reg_audio_board>;
+ DVDD-supply = <&reg_audio_board>;
+ };
+
+ ak4458_2: ak4458@12 {
+ compatible = "asahi-kasei,ak4458";
+ reg = <0x12>;
+ AVDD-supply = <&reg_audio_board>;
+ DVDD-supply = <&reg_audio_board>;
+ };
+
+ ak5558: ak5558@13 {
+ compatible = "asahi-kasei,ak5558";
+ reg = <0x13>;
+ ak5558,pdn-gpio = <&pca6416 3 GPIO_ACTIVE_HIGH>;
+ AVDD-supply = <&reg_audio_board>;
+ DVDD-supply = <&reg_audio_board>;
+ };
+
+ ak4497: ak4497@11 {
+ compatible = "asahi-kasei,ak4497";
+ reg = <0x11>;
+ ak4497,pdn-gpio = <&pca6416 5 GPIO_ACTIVE_HIGH>;
+ AVDD-supply = <&reg_audio_board>;
+ DVDD-supply = <&reg_audio_board>;
+ };
+
+ ov5640_mipi: ov5640_mipi@3c {
+ compatible = "ovti,ov5640_mipi";
+ reg = <0x3c>;
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_csi_pwn>, <&pinctrl_csi_rst>;
+ clocks = <&clk IMX8MM_CLK_CLKO1_DIV>;
+ clock-names = "csi_mclk";
+ assigned-clocks = <&clk IMX8MM_CLK_CLKO1_SRC>,
+ <&clk IMX8MM_CLK_CLKO1_DIV>;
+ assigned-clock-parents = <&clk IMX8MM_CLK_24M>;
+ assigned-clock-rates = <0>, <24000000>;
+ csi_id = <0>;
+ pwn-gpios = <&gpio1 7 GPIO_ACTIVE_HIGH>;
+ mclk = <24000000>;
+ mclk_source = <0>;
+ port {
+ ov5640_mipi1_ep: endpoint {
+ remote-endpoint = <&mipi1_sensor_ep>;
+ };
+ };
+ };
+};
+
+&lcdif {
+ status = "okay";
+};
+
+&mipi_dsi {
+ status = "okay";
+
+ port@1 {
+ dsim_to_adv7535: endpoint {
+ remote-endpoint = <&adv7535_from_dsim>;
+ };
+ };
+};
+
+&mu {
+ status = "okay";
+};
+
+&sai1 {
+ pinctrl-names = "default", "dsd";
+ pinctrl-0 = <&pinctrl_sai1>;
+ pinctrl-1 = <&pinctrl_sai1_dsd>;
+ assigned-clocks = <&clk IMX8MM_CLK_SAI1_SRC>,
+ <&clk IMX8MM_CLK_SAI1_DIV>;
+ assigned-clock-parents = <&clk IMX8MM_AUDIO_PLL1_OUT>;
+ assigned-clock-rates = <0>, <49152000>;
+ clocks = <&clk IMX8MM_CLK_SAI1_IPG>, <&clk IMX8MM_CLK_DUMMY>,
+ <&clk IMX8MM_CLK_SAI1_ROOT>, <&clk IMX8MM_CLK_DUMMY>,
+ <&clk IMX8MM_CLK_DUMMY>, <&clk IMX8MM_AUDIO_PLL1_OUT>,
+ <&clk IMX8MM_AUDIO_PLL2_OUT>;
+ clock-names = "bus", "mclk0", "mclk1", "mclk2", "mclk3", "pll8k", "pll11k";
+ fsl,sai-multi-lane;
+ fsl,dataline,dsd = <0 0xff 0xff 2 0xff 0x11>;
+ dmas = <&sdma2 0 26 0>, <&sdma2 1 26 0>;
+ status = "okay";
+};
+
+&sai3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_sai3>;
+ assigned-clocks = <&clk IMX8MM_CLK_SAI3_SRC>,
+ <&clk IMX8MM_CLK_SAI3_DIV>;
+ assigned-clock-parents = <&clk IMX8MM_AUDIO_PLL1_OUT>;
+ assigned-clock-rates = <0>, <24576000>;
+ status = "okay";
+};
+
+&sai5 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_sai5>;
+ assigned-clocks = <&clk IMX8MM_CLK_SAI5_SRC>,
+ <&clk IMX8MM_CLK_SAI5_DIV>;
+ assigned-clock-parents = <&clk IMX8MM_AUDIO_PLL1_OUT>;
+ assigned-clock-rates = <0>, <49152000>;
+ clocks = <&clk IMX8MM_CLK_SAI5_IPG>, <&clk IMX8MM_CLK_DUMMY>,
+ <&clk IMX8MM_CLK_SAI5_ROOT>, <&clk IMX8MM_CLK_DUMMY>,
+ <&clk IMX8MM_CLK_DUMMY>, <&clk IMX8MM_AUDIO_PLL1_OUT>,
+ <&clk IMX8MM_AUDIO_PLL2_OUT>;
+ clock-names = "bus", "mclk0", "mclk1", "mclk2", "mclk3", "pll8k", "pll11k";
+ fsl,sai-asynchronous;
+ status = "disabled";
+};
+
+&spdif1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_spdif1>;
+ assigned-clocks = <&clk IMX8MM_CLK_SPDIF1_SRC>,
+ <&clk IMX8MM_CLK_SPDIF1_DIV>;
+ assigned-clock-parents = <&clk IMX8MM_AUDIO_PLL1_OUT>;
+ assigned-clock-rates = <0>, <24576000>;
+ clocks = <&clk IMX8MM_CLK_AUDIO_AHB_DIV>, <&clk IMX8MM_CLK_24M>,
+ <&clk IMX8MM_CLK_SPDIF1_DIV>, <&clk IMX8MM_CLK_DUMMY>,
+ <&clk IMX8MM_CLK_DUMMY>, <&clk IMX8MM_CLK_DUMMY>,
+ <&clk IMX8MM_CLK_AUDIO_AHB_DIV>, <&clk IMX8MM_CLK_DUMMY>,
+ <&clk IMX8MM_CLK_DUMMY>, <&clk IMX8MM_CLK_DUMMY>,
+ <&clk IMX8MM_AUDIO_PLL1_OUT>, <&clk IMX8MM_AUDIO_PLL2_OUT>;
+ clock-names = "core", "rxtx0", "rxtx1", "rxtx2", "rxtx3",
+ "rxtx4", "rxtx5", "rxtx6", "rxtx7", "spba", "pll8k", "pll11k";
+ status = "okay";
+};
+
+&fec1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_fec1>;
+ phy-mode = "rgmii-id";
+ phy-handle = <&ethphy0>;
+ fsl,magic-packet;
+ status = "okay";
+
+ mdio {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ethphy0: ethernet-phy@0 {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <0>;
+ at803x,led-act-blind-workaround;
+ at803x,eee-okay;
+ at803x,vddio-1p8v;
+ };
+ };
+};
+
+&pcie0{
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pcie0>;
+ disable-gpio = <&gpio1 5 GPIO_ACTIVE_LOW>;
+ reset-gpio = <&gpio4 21 GPIO_ACTIVE_LOW>;
+ ext_osc = <1>;
+ status = "okay";
+};
+
+&uart1 { /* BT */
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart1>;
+ assigned-clocks = <&clk IMX8MM_CLK_UART1_SRC>;
+ assigned-clock-parents = <&clk IMX8MM_SYS_PLL1_80M>;
+ fsl,uart-has-rtscts;
+ resets = <&modem_reset>;
+ status = "okay";
+};
+
+&uart2 { /* console */
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart2>;
+ status = "okay";
+};
+
+&uart3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart3>;
+ assigned-clocks = <&clk IMX8MM_CLK_UART3_SRC>;
+ assigned-clock-parents = <&clk IMX8MM_SYS_PLL1_80M>;
+ fsl,uart-has-rtscts;
+ status = "okay";
+};
+
+&usbotg1 {
+ dr_mode = "otg";
+ extcon = <0>, <&typec1_ptn5110>;
+ picophy,pre-emp-curr-control = <3>;
+ picophy,dc-vol-level-adjust = <7>;
+ status = "okay";
+};
+
+&usbotg2 {
+ dr_mode = "otg";
+ extcon = <0>, <&typec2_ptn5110>;
+ picophy,pre-emp-curr-control = <3>;
+ picophy,dc-vol-level-adjust = <7>;
+ status = "disabled";
+};
+
+&usdhc1 {
+ pinctrl-names = "default", "state_100mhz", "state_200mhz";
+ pinctrl-0 = <&pinctrl_usdhc1>, <&pinctrl_usdhc1_gpio>;
+ pinctrl-1 = <&pinctrl_usdhc1_100mhz>, <&pinctrl_usdhc1_gpio>;
+ pinctrl-2 = <&pinctrl_usdhc1_200mhz>, <&pinctrl_usdhc1_gpio>;
+ bus-width = <4>;
+ vmmc-supply = <&reg_sd1_vmmc>;
+ pm-ignore-notify;
+ keep-power-in-suspend;
+ non-removable;
+ status = "okay";
+};
+
+&usdhc2 {
+ pinctrl-names = "default", "state_100mhz", "state_200mhz";
+ pinctrl-0 = <&pinctrl_usdhc2>, <&pinctrl_usdhc2_gpio>;
+ pinctrl-1 = <&pinctrl_usdhc2_100mhz>, <&pinctrl_usdhc2_gpio>;
+ pinctrl-2 = <&pinctrl_usdhc2_200mhz>, <&pinctrl_usdhc2_gpio>;
+ cd-gpios = <&gpio1 15 GPIO_ACTIVE_LOW>;
+ bus-width = <4>;
+ vmmc-supply = <&reg_usdhc2_vmmc>;
+ 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>;
+ non-removable;
+ status = "okay";
+};
+
+&wdog1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_wdog>;
+ fsl,ext-reset-output;
+ status = "okay";
+};
+
+&A53_0 {
+ arm-supply = <&buck2_reg>;
+};
+
+&gpu {
+ status = "okay";
+};
+
+&vpu_g1 {
+ status = "okay";
+};
+
+&vpu_g2 {
+ status = "okay";
+};
+
+&vpu_h1 {
+ status = "okay";
+};
+
+&micfil {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pdm>;
+ assigned-clocks = <&clk IMX8MM_CLK_PDM_SRC>, <&clk IMX8MM_CLK_PDM_DIV>;
+ assigned-clock-parents = <&clk IMX8MM_AUDIO_PLL1_OUT>;
+ assigned-clock-rates = <0>, <196608000>;
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8mm.dtsi b/arch/arm64/boot/dts/freescale/fsl-imx8mm.dtsi
new file mode 100644
index 000000000000..e200219ea8bb
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8mm.dtsi
@@ -0,0 +1,1293 @@
+/*
+ * Copyright 2017-2019 NXP
+ *
+ * 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 "fsl-imx8-ca53.dtsi"
+#include <dt-bindings/clock/imx8mm-clock.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/pinctrl/pins-imx8mm.h>
+#include <dt-bindings/thermal/thermal.h>
+
+/ {
+ compatible = "fsl,imx8mm";
+ interrupt-parent = <&gpc>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ aliases {
+ ethernet0 = &fec1;
+ i2c0 = &i2c1;
+ i2c1 = &i2c2;
+ i2c2 = &i2c3;
+ i2c3 = &i2c4;
+ serial0 = &uart1;
+ serial1 = &uart2;
+ serial2 = &uart3;
+ serial3 = &uart4;
+ spi0 = &ecspi1;
+ spi1 = &ecspi2;
+ spi2 = &ecspi3;
+ mmc0 = &usdhc1;
+ mmc1 = &usdhc2;
+ mmc2 = &usdhc3;
+ gpio0 = &gpio1;
+ gpio1 = &gpio2;
+ gpio2 = &gpio3;
+ gpio3 = &gpio4;
+ gpio4 = &gpio5;
+ };
+
+ cpus {
+ idle-states {
+ entry-method = "psci";
+
+ CPU_SLEEP: cpu-sleep {
+ compatible = "arm,idle-state";
+ arm,psci-suspend-param = <0x0010033>;
+ local-timer-stop;
+ entry-latency-us = <1000>;
+ exit-latency-us = <700>;
+ min-residency-us = <2700>;
+ wakeup-latency-us = <1500>;
+ };
+ };
+ };
+
+ memory@40000000 {
+ device_type = "memory";
+ reg = <0x0 0x40000000 0 0x80000000>;
+ };
+
+ reserved-memory {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ /* global autoconfigured region for contiguous allocations */
+ linux,cma {
+ compatible = "shared-dma-pool";
+ reusable;
+ size = <0 0x28000000>;
+ alloc-ranges = <0 0x40000000 0 0x60000000>;
+ linux,cma-default;
+ };
+
+ rpmsg_reserved: rpmsg@0xb8000000 {
+ no-map;
+ reg = <0 0xb8000000 0 0x400000>;
+ };
+ };
+
+ gic: interrupt-controller@38800000 {
+ compatible = "arm,gic-v3";
+ reg = <0x0 0x38800000 0 0x10000>, /* GIC Dist */
+ <0x0 0x38880000 0 0xC0000>; /* GICR (RD_base + SGI_base) */
+ #interrupt-cells = <3>;
+ interrupt-controller;
+ interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-parent = <&gic>;
+ };
+
+ timer {
+ compatible = "arm,armv8-timer";
+ interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>, /* Physical Secure */
+ <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>, /* Physical Non-Secure */
+ <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>, /* Virtual */
+ <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>; /* Hypervisor */
+ clock-frequency = <8000000>;
+ arm,no-tick-in-suspend;
+ interrupt-parent = <&gic>;
+ };
+
+ pmu {
+ interrupt-parent = <&gic>;
+ };
+
+ busfreq { /* BUSFREQ */
+ compatible = "fsl,imx_busfreq";
+ clocks = <&clk IMX8MM_DRAM_PLL_OUT>, <&clk IMX8MM_CLK_DRAM_ALT_SRC>,
+ <&clk IMX8MM_CLK_DRAM_APB_SRC>, <&clk IMX8MM_CLK_DRAM_APB_PRE_DIV>,
+ <&clk IMX8MM_CLK_DRAM_CORE>, <&clk IMX8MM_CLK_DRAM_ALT_ROOT>,
+ <&clk IMX8MM_SYS_PLL1_40M>, <&clk IMX8MM_SYS_PLL1_100M>,
+ <&clk IMX8MM_SYS_PLL2_333M>, <&clk IMX8MM_CLK_NOC_DIV>,
+ <&clk IMX8MM_CLK_AHB_DIV>, <&clk IMX8MM_CLK_MAIN_AXI_SRC>,
+ <&clk IMX8MM_CLK_24M>, <&clk IMX8MM_SYS_PLL1_800M>;
+ clock-names = "dram_pll", "dram_alt_src", "dram_apb_src", "dram_apb_pre_div",
+ "dram_core", "dram_alt_root", "sys_pll1_40m", "sys_pll1_100m",
+ "sys_pll2_333m", "noc_div", "ahb_div", "main_axi_src", "osc_24m",
+ "sys_pll1_800m";
+ interrupts = <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-name = "irq_busfreq_0", "irq_busfreq_1", "irq_busfreq_2", "irq_busfreq_3";
+ };
+
+ ddr_pmu0: ddr_pmu@3d800000 {
+ compatible = "fsl,imx8m-ddr-pmu", "fsl,imx8-ddr-pmu";
+ reg = <0x0 0x3d800000 0x0 0x400000>;
+ interrupts = <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ clocks {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ osc_32k: clock@0 {
+ compatible = "fixed-clock";
+ reg = <0>;
+ #clock-cells = <0>;
+ clock-frequency = <32768>;
+ clock-output-names = "osc_32k";
+ };
+
+ osc_24m: clock@1 {
+ compatible = "fixed-clock";
+ reg = <1>;
+ #clock-cells = <0>;
+ clock-frequency = <24000000>;
+ clock-output-names = "osc_24m";
+ };
+
+ clk_ext1: clock@2 {
+ compatible = "fixed-clock";
+ reg = <3>;
+ #clock-cells = <0>;
+ clock-frequency = <133000000>;
+ clock-output-names = "clk_ext1";
+ };
+
+ clk_ext2: clock@3 {
+ compatible = "fixed-clock";
+ reg = <4>;
+ #clock-cells = <0>;
+ clock-frequency = <133000000>;
+ clock-output-names = "clk_ext2";
+ };
+
+ clk_ext3: clock@4 {
+ compatible = "fixed-clock";
+ reg = <5>;
+ #clock-cells = <0>;
+ clock-frequency = <133000000>;
+ clock-output-names = "clk_ext3";
+ };
+
+ clk_ext4: clock@5 {
+ compatible = "fixed-clock";
+ reg = <6>;
+ #clock-cells = <0>;
+ clock-frequency= <133000000>;
+ clock-output-names = "clk_ext4";
+ };
+ };
+
+ power-domains {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ /* HSIOMIX */
+ hsio_pd: power-domain@0 {
+ compatible = "fsl,imx8mm-pm-domain";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ domain-id = <0>;
+ #power-domain-cells = <0>;
+ domain-name = "HSIO_PD";
+ clocks = <&clk IMX8MM_CLK_USB1_CTRL_ROOT>,
+ <&clk IMX8MM_CLK_SIM_HSIO>;
+
+ pcie0_pd: power-domain@1 {
+ domain-id = <1>;
+ #power-domain-cells = <0>;
+ domain-name = "PCIE0_PD";
+ clocks = <&clk IMX8MM_CLK_PCIE1_ROOT>;
+ };
+
+ usb_otg1_pd: power-domain@2 {
+ domain-id = <2>;
+ #power-domain-cells = <0>;
+ domain-name = "USB_OTG1_PD";
+ };
+
+ usb_otg2_pd: power-domain@3 {
+ domain-id = <3>;
+ #power-domain-cells = <0>;
+ domain-name = "USB_OTG2_PD";
+ };
+ };
+
+ /* GPU2D&3D */
+ gpumix_pd: power-domain@4 {
+ compatible = "fsl,imx8mm-pm-domain";
+ domain-id = <4>;
+ #power-domain-cells = <0>;
+ domain-name = "GPUMIX_PD";
+ clocks = <&clk IMX8MM_CLK_GPU_BUS_ROOT>,
+ <&clk IMX8MM_CLK_GPU2D_ROOT>,
+ <&clk IMX8MM_CLK_GPU3D_ROOT>,
+ <&clk IMX8MM_CLK_GPU_AHB_DIV>;
+ };
+
+ vpumix_pd: power-domain@5 {
+ compatible = "fsl,imx8mm-pm-domain";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ domain-id = <5>;
+ #power-domain-cells = <0>;
+ domain-name = "VPUMIX_PD";
+ clocks = <&clk IMX8MM_CLK_VPU_DEC_ROOT>;
+
+ vpu_g1_pd: power-domain@6 {
+ domain-id = <6>;
+ #power-domain-cells = <0>;
+ domain-name = "VPU_G1_PD";
+ clocks = <&clk IMX8MM_CLK_VPU_G1_ROOT>;
+ };
+
+ vpu_g2_pd: power-domain@7 {
+ domain-id = <7>;
+ #power-domain-cells = <0>;
+ domain-name = "VPU_G2_PD";
+ clocks = <&clk IMX8MM_CLK_VPU_G2_ROOT>;
+ };
+
+ vpu_h1_pd: power-domain@8 {
+ domain-id = <8>;
+ #power-domain-cells = <0>;
+ domain-name = "VPU_H1_PD";
+ clocks = <&clk IMX8MM_CLK_VPU_H1_ROOT>;
+ };
+ };
+
+ dispmix_pd: power-domain@9 {
+ compatible = "fsl,imx8mm-pm-domain";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ domain-id = <9>;
+ #power-domain-cells = <0>;
+ domain-name = "DISPMIX_PD";
+ clocks = <&clk IMX8MM_CLK_DISP_ROOT>;
+
+ mipi_pd: power-domain@10 {
+ domain-id = <10>;
+ #power-domain-cells = <0>;
+ domain-name = "MIPI_PD";
+ };
+ };
+ };
+
+ csi1_bridge: csi1_bridge@32e20000 {
+ compatible = "fsl,imx8mm-csi", "fsl,imx8mq-csi", "fsl,imx6s-csi";
+ reg = <0x0 0x32e20000 0x0 0x10000>;
+ interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8MM_CLK_DISP_AXI_ROOT>,
+ <&clk IMX8MM_CLK_CSI1_ROOT>,
+ <&clk IMX8MM_CLK_DISP_APB_ROOT>;
+ clock-names = "disp-axi", "csi_mclk", "disp_dcic";
+ power-domains = <&dispmix_pd>;
+ status = "disabled";
+ };
+
+ mipi_csi_1: mipi_csi@32e30000 {
+ compatible = "fsl,imx8mm-mipi-csi";
+ reg = <0x0 0x32e30000 0x0 0x1000>;
+ interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
+ clock-frequency = <333000000>;
+ clocks = <&clk IMX8MM_CLK_CSI1_CORE_DIV>,
+ <&clk IMX8MM_CLK_CSI1_PHY_REF_DIV>,
+ <&clk IMX8MM_CLK_DISP_AXI_ROOT>,
+ <&clk IMX8MM_CLK_DISP_APB_ROOT>;
+ clock-names = "mipi_clk", "phy_clk", "disp_axi", "disp_apb";
+ bus-width = <4>;
+ csi-gpr = <&dispmix_gpr>;
+ power-domains = <&mipi_pd>;
+ status = "disabled";
+ };
+
+ gpio1: gpio@30200000 {
+ compatible = "fsl,imx8mm-gpio", "fsl,imx35-gpio";
+ reg = <0x0 0x30200000 0x0 0x10000>;
+ interrupts = <GIC_SPI 64 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio2: gpio@30210000 {
+ compatible = "fsl,imx8mm-gpio", "fsl,imx35-gpio";
+ reg = <0x0 0x30210000 0x0 0x10000>;
+ interrupts = <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio3: gpio@30220000 {
+ compatible = "fsl,imx8mm-gpio", "fsl,imx35-gpio";
+ reg = <0x0 0x30220000 0x0 0x10000>;
+ interrupts = <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio4: gpio@30230000 {
+ compatible = "fsl,imx8mm-gpio", "fsl,imx35-gpio";
+ reg = <0x0 0x30230000 0x0 0x10000>;
+ interrupts = <GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio5: gpio@30240000 {
+ compatible = "fsl,imx8mm-gpio", "fsl,imx35-gpio";
+ reg = <0x0 0x30240000 0x0 0x10000>;
+ interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ tmu: tmu@0x30260000 {
+ compatible = "fsl,imx8mm-tmu";
+ reg = <0x0 0x30260000 0x0 0x10000>;
+ clocks = <&clk IMX8MM_CLK_TMU_ROOT>;
+ interrupt = <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>;
+ #thermal-sensor-cells = <0>;
+ };
+
+ thermal-zones {
+ /* cpu thermal */
+ cpu-thermal {
+ polling-delay-passive = <250>;
+ polling-delay = <2000>;
+ thermal-sensors = <&tmu>;
+ trips {
+ cpu_alert0: trip0 {
+ temperature = <85000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+
+ cpu_crit0: trip1 {
+ temperature = <95000>;
+ hysteresis = <2000>;
+ type = "critical";
+ };
+ };
+
+ cooling-maps {
+ map0 {
+ trip = <&cpu_alert0>;
+ cooling-device =
+ <&A53_0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
+ };
+ };
+
+ iomuxc: pinctrl@30330000 {
+ compatible = "fsl,imx8mm-iomuxc";
+ reg = <0x0 0x30330000 0x0 0x10000>;
+ };
+
+ gpr: iomuxc-gpr@30340000 {
+ compatible = "fsl,imx8mm-iomuxc-gpr", "fsl,imx7d-iomuxc-gpr", "syscon";
+ reg = <0x0 0x30340000 0x0 0x10000>;
+ };
+
+ anatop: anatop@30360000 {
+ compatible = "fsl,imx8mm-anatop", "syscon", "simple-bus";
+ reg = <0x0 0x30360000 0x0 0x10000>;
+ };
+
+ snvs: snvs@30370000 {
+ compatible = "fsl,sec-v4.0-mon","syscon", "simple-mfd";
+ reg = <0x0 0x30370000 0x0 0x10000>;
+
+ snvs_rtc: snvs-rtc-lp{
+ compatible = "fsl,sec-v4.0-mon-rtc-lp";
+ regmap =<&snvs>;
+ offset = <0x34>;
+ interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ snvs_pwrkey: snvs-powerkey {
+ compatible = "fsl,sec-v4.0-pwrkey";
+ regmap = <&snvs>;
+ interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>;
+ linux,keycode = <KEY_POWER>;
+ wakeup-source;
+ };
+ };
+
+ clk: clock-controller@30380000 {
+ compatible = "fsl,imx8mm-ccm";
+ reg = <0x0 0x30380000 0x0 0x10000>;
+ #clock-cells = <1>;
+ clocks = <&osc_32k>, <&osc_24m>, <&clk_ext1>, <&clk_ext2>,
+ <&clk_ext3>, <&clk_ext4>;
+ clock-names = "osc_32k", "osc_24m", "clk_ext1", "clk_ext2",
+ "clk_ext3", "clk_ext4";
+ };
+
+ src: src@30390000 {
+ compatible = "fsl,imx8mm-src", "fsl,imx8mq-src", "syscon";
+ reg = <0x0 0x30390000 0x0 0x10000>;
+ interrupts = <GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH>;
+ #reset-cells = <1>;
+ };
+
+ gpc: gpc@303a0000 {
+ compatible = "fsl,imx8mm-gpc", "fsl,imx8mq-gpc", "syscon";
+ reg = <0x0 0x303a0000 0x0 0x10000>;
+ interrupt-controller;
+ interrupts = <GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH>;
+ #interrupt-cells = <3>;
+ interrupt-parent = <&gic>;
+ };
+
+ system_counter: timer@306a0000 {
+ compatible = "nxp,sysctr-timer";
+ reg = <0x0 0x306a0000 0x0 0x10000>, /* system-counter-rd base */
+ <0x0 0x306b0000 0x0 0x10000>, /* system-counter-cmp base */
+ <0x0 0x306c0000 0x0 0x10000>; /* system-counter-ctrl base */
+ clock-frequency = <8000000>;
+ interrupts = <GIC_SPI 47 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ uart1: serial@30860000 {
+ compatible = "fsl,imx8mm-uart",
+ "fsl,imx6q-uart", "fsl,imx21-uart";
+ reg = <0x0 0x30860000 0x0 0x10000>;
+ interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8MM_CLK_UART1_ROOT>,
+ <&clk IMX8MM_CLK_UART1_ROOT>;
+ clock-names = "ipg", "per";
+ dmas = <&sdma1 22 4 0>, <&sdma1 23 4 0>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ uart3: serial@30880000 {
+ compatible = "fsl,imx8mm-uart",
+ "fsl,imx6q-uart", "fsl,imx21-uart";
+ reg = <0x0 0x30880000 0x0 0x10000>;
+ interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8MM_CLK_UART3_ROOT>,
+ <&clk IMX8MM_CLK_UART3_ROOT>;
+ clock-names = "ipg", "per";
+ dmas = <&sdma1 26 4 0>, <&sdma1 27 4 0>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ uart2: serial@30890000 {
+ compatible = "fsl,imx8mm-uart",
+ "fsl,imx6q-uart", "fsl,imx21-uart";
+ reg = <0x0 0x30890000 0x0 0x10000>;
+ interrupts = <GIC_SPI 27 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8MM_CLK_UART2_ROOT>,
+ <&clk IMX8MM_CLK_UART2_ROOT>;
+ clock-names = "ipg", "per";
+ status = "disabled";
+ };
+
+ i2c1: i2c@30a20000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx8mm-i2c", "fsl,imx21-i2c";
+ reg = <0x0 0x30a20000 0x0 0x10000>;
+ interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8MM_CLK_I2C1_ROOT>;
+ status = "disabled";
+ };
+
+ i2c2: i2c@30a30000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx8mm-i2c", "fsl,imx21-i2c";
+ reg = <0x0 0x30a30000 0x0 0x10000>;
+ interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8MM_CLK_I2C2_ROOT>;
+ status = "disabled";
+ };
+
+ i2c3: i2c@30a40000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx8mm-i2c", "fsl,imx21-i2c";
+ reg = <0x0 0x30a40000 0x0 0x10000>;
+ interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8MM_CLK_I2C3_ROOT>;
+ status = "disabled";
+ };
+
+ i2c4: i2c@30a50000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx8mm-i2c", "fsl,imx21-i2c";
+ reg = <0x0 0x30a50000 0x0 0x10000>;
+ interrupts = <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8MM_CLK_I2C4_ROOT>;
+ status = "disabled";
+ };
+
+ uart4: serial@30a60000 {
+ compatible = "fsl,imx8mq-uart",
+ "fsl,imx6q-uart", "fsl,imx21-uart";
+ reg = <0x0 0x30a60000 0x0 0x10000>;
+ interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8MM_CLK_UART4_ROOT>,
+ <&clk IMX8MM_CLK_UART4_ROOT>;
+ clock-names = "ipg", "per";
+ dmas = <&sdma1 28 4 0>, <&sdma1 29 4 0>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+
+ imx_rpmsg: imx_rpmsg {
+ compatible = "fsl,rpmsg-bus", "simple-bus";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ mu: mu@30aa0000 {
+ compatible = "fsl,imx8mq-mu", "fsl,imx6sx-mu";
+ reg = <0x0 0x30aa0000 0x0 0x10000>;
+ interrupts = <GIC_SPI 88 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8MM_CLK_MU_ROOT>;
+ clock-names = "mu";
+ status = "disabled";
+ };
+
+ rpmsg: rpmsg{
+ compatible = "fsl,imx8mq-rpmsg";
+ status = "disabled";
+ };
+ };
+
+ ocotp: ocotp-ctrl@30350000 {
+ compatible = "fsl,imx8mq-ocotp", "fsl,imx7d-ocotp", "syscon";
+ reg = <0 0x30350000 0 0x10000>;
+ clocks = <&clk IMX8MM_CLK_OCOTP_ROOT>;
+ /* For nvmem subnodes */
+ #address-cells = <1>;
+ #size-cells = <1>;
+ };
+
+ dispmix_gpr: display-gpr@32e28000 {
+ compatible = "fsl, imx8mm-iomuxc-gpr", "syscon";
+ reg = <0x0 0x32e28000 0x0 0x100>;
+ };
+
+ usbotg1: usb@32e40000 {
+ compatible = "fsl,imx8mm-usb", "fsl,imx7d-usb", "fsl,imx27-usb";
+ reg = <0x0 0x32e40000 0x0 0x200>;
+ interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8MM_CLK_USB1_CTRL_ROOT>;
+ clock-names = "usb1_ctrl_root_clk";
+ assigned-clocks = <&clk IMX8MM_CLK_USB_BUS_SRC>,
+ <&clk IMX8MM_CLK_USB_CORE_REF_SRC>;
+ assigned-clock-parents = <&clk IMX8MM_SYS_PLL2_500M>,
+ <&clk IMX8MM_SYS_PLL1_100M>;
+ fsl,usbphy = <&usbphynop1>;
+ fsl,usbmisc = <&usbmisc1 0>;
+ power-domains = <&usb_otg1_pd>;
+ status = "disabled";
+ };
+
+ usbphynop1: usbphynop1 {
+ compatible = "usb-nop-xceiv";
+ clocks = <&clk IMX8MM_CLK_USB_PHY_REF_SRC>;
+ assigned-clocks = <&clk IMX8MM_CLK_USB_PHY_REF_SRC>;
+ assigned-clock-parents = <&clk IMX8MM_SYS_PLL1_100M>;
+ clock-names = "main_clk";
+ };
+
+ usbmisc1: usbmisc@32e40200 {
+ #index-cells = <1>;
+ compatible = "fsl,imx7d-usbmisc", "fsl,imx6q-usbmisc";
+ reg = <0x0 0x32e40200 0x0 0x200>;
+ };
+
+ usbotg2: usb@32e50000 {
+ compatible = "fsl,imx8mm-usb", "fsl,imx7d-usb", "fsl,imx27-usb";
+ reg = <0x0 0x32e50000 0x0 0x200>;
+ interrupts = <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8MM_CLK_USB1_CTRL_ROOT>;
+ clock-names = "usb1_ctrl_root_clk";
+ assigned-clocks = <&clk IMX8MM_CLK_USB_BUS_SRC>,
+ <&clk IMX8MM_CLK_USB_CORE_REF_SRC>;
+ assigned-clock-parents = <&clk IMX8MM_SYS_PLL2_500M>,
+ <&clk IMX8MM_SYS_PLL1_100M>;
+ fsl,usbphy = <&usbphynop2>;
+ fsl,usbmisc = <&usbmisc2 0>;
+ power-domains = <&usb_otg2_pd>;
+ status = "disabled";
+ };
+
+ usbphynop2: usbphynop2 {
+ compatible = "usb-nop-xceiv";
+ clocks = <&clk IMX8MM_CLK_USB_PHY_REF_SRC>;
+ assigned-clocks = <&clk IMX8MM_CLK_USB_PHY_REF_SRC>;
+ assigned-clock-parents = <&clk IMX8MM_SYS_PLL1_100M>;
+ clock-names = "main_clk";
+ };
+
+ usbmisc2: usbmisc@32e50200 {
+ #index-cells = <1>;
+ compatible = "fsl,imx7d-usbmisc", "fsl,imx6q-usbmisc";
+ reg = <0x0 0x32e50200 0x0 0x200>;
+ };
+
+ usdhc1: mmc@30b40000 {
+ compatible = "fsl,imx8mq-usdhc", "fsl,imx8qm-usdhc";
+ reg = <0x0 0x30b40000 0x0 0x10000>;
+ interrupts = <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8MM_CLK_DUMMY>,
+ <&clk IMX8MM_CLK_NAND_USDHC_BUS_DIV>,
+ <&clk IMX8MM_CLK_USDHC1_ROOT>;
+ clock-names = "ipg", "ahb", "per";
+ assigned-clocks = <&clk IMX8MM_CLK_USDHC1_DIV>;
+ assigned-clock-rates = <400000000>;
+ fsl,tuning-start-tap = <20>;
+ fsl,tuning-step= <2>;
+ bus-width = <4>;
+ status = "disabled";
+ };
+
+ usdhc2: mmc@30b50000 {
+ compatible = "fsl,imx8mq-usdhc", "fsl,imx8qm-usdhc";
+ reg = <0x0 0x30b50000 0x0 0x10000>;
+ interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8MM_CLK_DUMMY>,
+ <&clk IMX8MM_CLK_NAND_USDHC_BUS_DIV>,
+ <&clk IMX8MM_CLK_USDHC2_ROOT>;
+ clock-names = "ipg", "ahb", "per";
+ fsl,tuning-start-tap = <20>;
+ fsl,tuning-step= <2>;
+ bus-width = <4>;
+ status = "disabled";
+ };
+
+ usdhc3: mmc@30b60000 {
+ compatible = "fsl,imx8mq-usdhc", "fsl,imx8qm-usdhc";
+ reg = <0x0 0x30b60000 0x0 0x10000>;
+ interrupts = <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8MM_CLK_DUMMY>,
+ <&clk IMX8MM_CLK_NAND_USDHC_BUS_DIV>,
+ <&clk IMX8MM_CLK_USDHC3_ROOT>;
+ clock-names = "ipg", "ahb", "per";
+ assigned-clocks = <&clk IMX8MM_CLK_USDHC3_ROOT>;
+ assigned-clock-rates = <400000000>;
+ fsl,tuning-start-tap = <20>;
+ fsl,tuning-step= <2>;
+ bus-width = <4>;
+ status = "disabled";
+ };
+
+ sai1: sai@30010000 {
+ compatible = "fsl,imx8mq-sai",
+ "fsl,imx6sx-sai";
+ reg = <0x0 0x30010000 0x0 0x10000>;
+ interrupts = <GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8MM_CLK_SAI1_IPG>,
+ <&clk IMX8MM_CLK_DUMMY>,
+ <&clk IMX8MM_CLK_SAI1_ROOT>,
+ <&clk IMX8MM_CLK_DUMMY>, <&clk IMX8MM_CLK_DUMMY>;
+ clock-names = "bus", "mclk0", "mclk1", "mclk2", "mclk3";
+ dmas = <&sdma2 0 2 0>, <&sdma2 1 2 0>;
+ dma-names = "rx", "tx";
+ fsl,dataline = <0 0xff 0xff>;
+ status = "disabled";
+ };
+
+ sai2: sai@30020000 {
+ compatible = "fsl,imx8mq-sai",
+ "fsl,imx6sx-sai";
+ reg = <0x0 0x30020000 0x0 0x10000>;
+ interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8MM_CLK_SAI2_IPG>,
+ <&clk IMX8MM_CLK_DUMMY>,
+ <&clk IMX8MM_CLK_SAI2_ROOT>,
+ <&clk IMX8MM_CLK_DUMMY>, <&clk IMX8MM_CLK_DUMMY>;
+ clock-names = "bus", "mclk0", "mclk1", "mclk2", "mclk3";
+ dmas = <&sdma2 2 2 0>, <&sdma2 3 2 0>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ sai3: sai@30030000 {
+ compatible = "fsl,imx8mm-sai", "fsl,imx8mq-sai", "fsl,imx6sx-sai";
+ reg = <0x0 0x30030000 0x0 0x10000>;
+ interrupts = <GIC_SPI 50 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8MM_CLK_SAI3_IPG>,
+ <&clk IMX8MM_CLK_DUMMY>,
+ <&clk IMX8MM_CLK_SAI3_ROOT>,
+ <&clk IMX8MM_CLK_DUMMY>, <&clk IMX8MM_CLK_DUMMY>;
+ clock-names = "bus", "mclk0", "mclk1", "mclk2", "mclk3";
+ dmas = <&sdma2 4 2 0>, <&sdma2 5 2 0>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ sai5: sai@30050000 {
+ compatible = "fsl,imx8mm-sai", "fsl,imx8mq-sai", "fsl,imx6sx-sai";
+ reg = <0x0 0x30050000 0x0 0x10000>;
+ interrupts = <GIC_SPI 90 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8MM_CLK_SAI5_IPG>,
+ <&clk IMX8MM_CLK_DUMMY>,
+ <&clk IMX8MM_CLK_SAI5_ROOT>,
+ <&clk IMX8MM_CLK_DUMMY>, <&clk IMX8MM_CLK_DUMMY>;
+ clock-names = "bus", "mclk0", "mclk1", "mclk2", "mclk3";
+ dmas = <&sdma2 8 2 0>, <&sdma2 9 2 0>;
+ dma-names = "rx", "tx";
+ fsl,shared-interrupt;
+ fsl,dataline = <0 0xf 0xf>;
+ status = "disabled";
+ };
+
+ sai6: sai@30060000 {
+ compatible = "fsl,imx8mq-sai",
+ "fsl,imx6sx-sai";
+ reg = <0x0 0x30060000 0x0 0x10000>;
+ interrupts = <GIC_SPI 90 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8MM_CLK_SAI6_IPG>,
+ <&clk IMX8MM_CLK_DUMMY>,
+ <&clk IMX8MM_CLK_SAI6_ROOT>,
+ <&clk IMX8MM_CLK_DUMMY>, <&clk IMX8MM_CLK_DUMMY>;
+ clock-names = "bus", "mclk0", "mclk1", "mclk2", "mclk3";
+ dmas = <&sdma2 10 2 0>, <&sdma2 11 2 0>;
+ dma-names = "rx", "tx";
+ fsl,shared-interrupt;
+ status = "disabled";
+ };
+
+ micfil: micfil@30080000 {
+ compatible = "fsl,imx8mm-micfil";
+ reg = <0x0 0x30080000 0x0 0x10000>;
+ interrupts = <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8MM_CLK_PDM_IPG>,
+ <&clk IMX8MM_CLK_PDM_ROOT>,
+ <&clk IMX8MM_AUDIO_PLL1_OUT>,
+ <&clk IMX8MM_AUDIO_PLL2_OUT>,
+ <&clk IMX8MM_CLK_EXT3>;
+ clock-names = "ipg_clk", "ipg_clk_app",
+ "pll8k", "pll11k", "clkext3";
+ dmas = <&sdma2 24 26 0x80000000>;
+ dma-names = "rx";
+ status = "disabled";
+ };
+
+ spdif1: spdif@30090000 {
+ compatible = "fsl,imx8mm-spdif";
+ reg = <0x0 0x30090000 0x0 0x10000>;
+ interrupts = <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8MM_CLK_AUDIO_AHB_DIV>, /* core */
+ <&clk IMX8MM_CLK_24M>, /* rxtx0 */
+ <&clk IMX8MM_CLK_SPDIF1_DIV>, /* rxtx1 */
+ <&clk IMX8MM_CLK_DUMMY>, /* rxtx2 */
+ <&clk IMX8MM_CLK_DUMMY>, /* rxtx3 */
+ <&clk IMX8MM_CLK_DUMMY>, /* rxtx4 */
+ <&clk IMX8MM_CLK_AUDIO_AHB_DIV>, /* rxtx5 */
+ <&clk IMX8MM_CLK_DUMMY>, /* rxtx6 */
+ <&clk IMX8MM_CLK_DUMMY>, /* rxtx7 */
+ <&clk IMX8MM_CLK_DUMMY>; /* spba */
+ clock-names = "core", "rxtx0",
+ "rxtx1", "rxtx2",
+ "rxtx3", "rxtx4",
+ "rxtx5", "rxtx6",
+ "rxtx7", "spba";
+ dmas = <&sdma2 28 18 0>, <&sdma2 29 18 0>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ sdma1: dma-controller@30bd0000 {
+ compatible = "fsl,imx8mm-sdma", "fsl,imx8mq-sdma", "fsl,imx7d-sdma";
+ reg = <0x0 0x30bd0000 0x0 0x10000>;
+ interrupts = <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8MM_CLK_SDMA1_ROOT>,
+ <&clk IMX8MM_CLK_SDMA1_ROOT>;
+ clock-names = "ipg", "ahb";
+ #dma-cells = <3>;
+ fsl,sdma-ram-script-name = "imx/sdma/sdma-imx7d.bin";
+ status = "okay";
+ };
+
+ sdma2: dma-controller@302c0000 {
+ compatible = "fsl,imx8mm-sdma", "fsl,imx8mq-sdma", "fsl,imx7d-sdma";
+ reg = <0x0 0x302c0000 0x0 0x10000>;
+ interrupts = <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8MM_CLK_SDMA2_ROOT>,
+ <&clk IMX8MM_CLK_SDMA2_ROOT>;
+ clock-names = "ipg", "ahb";
+ #dma-cells = <3>;
+ fsl,sdma-ram-script-name = "imx/sdma/sdma-imx7d.bin";
+ fsl,ratio-1-1;
+ status = "okay";
+ };
+
+ sdma3: dma-controller@302b0000 {
+ compatible = "fsl,imx8mm-sdma", "fsl,imx8mq-sdma", "fsl,imx7d-sdma";
+ reg = <0x0 0x302b0000 0x0 0x10000>;
+ interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8MM_CLK_SDMA3_ROOT>,
+ <&clk IMX8MM_CLK_SDMA3_ROOT>;
+ clock-names = "ipg", "ahb";
+ #dma-cells = <3>;
+ fsl,sdma-ram-script-name = "imx/sdma/sdma-imx7d.bin";
+ fsl,ratio-1-1;
+ status = "okay";
+ };
+
+ wdog1: wdog@30280000 {
+ compatible = "fsl,imx21-wdt";
+ reg = <0 0x30280000 0 0x10000>;
+ interrupts = <GIC_SPI 78 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8MM_CLK_WDOG1_ROOT>;
+ status = "disabled";
+ };
+
+ wdog2: wdog@30290000 {
+ compatible = "fsl,imx21-wdt";
+ reg = <0 0x30290000 0 0x10000>;
+ interrupts = <GIC_SPI 79 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8MM_CLK_WDOG2_ROOT>;
+ status = "disabled";
+ };
+
+ wdog3: wdog@302a0000 {
+ compatible = "fsl,imx21-wdt";
+ reg = <0 0x302a0000 0 0x10000>;
+ interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8MM_CLK_WDOG3_ROOT>;
+ status = "disabled";
+ };
+
+ flexspi: flexspi@30bb0000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx8mm-flexspi";
+ reg = <0 0x30bb0000 0 0x10000>, <0 0x08000000 0 0x10000000>;
+ reg-names = "FlexSPI", "FlexSPI-memory";
+ interrupts = <GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8MM_CLK_QSPI_ROOT>;
+ clock-names = "fspi";
+ assigned-clock-rates = <80000000>;
+ assigned-clocks = <&clk IMX8MM_CLK_QSPI_SRC>;
+ assigned-clock-parents = <&clk IMX8MM_SYS_PLL1_800M>;
+ status = "disabled";
+ };
+
+ ecspi1: ecspi@30820000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx8mm-ecspi", "fsl,imx51-ecspi";
+ reg = <0x0 0x30820000 0x0 0x10000>;
+ interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8MM_CLK_ECSPI1_ROOT>,
+ <&clk IMX8MM_CLK_ECSPI1_ROOT>;
+ clock-names = "ipg", "per";
+ dmas = <&sdma1 0 7 1>, <&sdma1 1 7 2>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ ecspi2: ecspi@30830000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx8mm-ecspi", "fsl,imx51-ecspi";
+ reg = <0x0 0x30830000 0x0 0x10000>;
+ interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8MM_CLK_ECSPI2_ROOT>,
+ <&clk IMX8MM_CLK_ECSPI2_ROOT>;
+ clock-names = "ipg", "per";
+ dmas = <&sdma1 2 7 1>, <&sdma1 3 7 2>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ ecspi3: ecspi@30840000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx8mm-ecspi", "fsl,imx51-ecspi";
+ reg = <0x0 0x30840000 0x0 0x10000>;
+ interrupts = <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8MM_CLK_ECSPI3_ROOT>,
+ <&clk IMX8MM_CLK_ECSPI3_ROOT>;
+ clock-names = "ipg", "per";
+ dmas = <&sdma1 4 7 1>, <&sdma1 5 7 2>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ fec1: ethernet@30be0000 {
+ compatible = "fsl,imx8mm-fec", "fsl,imx8mq-fec", "fsl,imx6sx-fec";
+ reg = <0x0 0x30be0000 0x0 0x10000>;
+ interrupts = <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8MM_CLK_ENET1_ROOT>,
+ <&clk IMX8MM_CLK_ENET1_ROOT>,
+ <&clk IMX8MM_CLK_ENET_TIMER_DIV>,
+ <&clk IMX8MM_CLK_ENET_REF_DIV>,
+ <&clk IMX8MM_CLK_ENET_PHY_REF_DIV>;
+ clock-names = "ipg", "ahb", "ptp",
+ "enet_clk_ref", "enet_out";
+ assigned-clocks = <&clk IMX8MM_CLK_ENET_AXI_SRC>,
+ <&clk IMX8MM_CLK_ENET_TIMER_SRC>,
+ <&clk IMX8MM_CLK_ENET_REF_SRC>,
+ <&clk IMX8MM_CLK_ENET_TIMER_DIV>;
+ assigned-clock-parents = <&clk IMX8MM_SYS_PLL1_266M>,
+ <&clk IMX8MM_SYS_PLL2_100M>,
+ <&clk IMX8MM_SYS_PLL2_125M>;
+ assigned-clock-rates = <0>, <0>, <125000000>, <100000000>;
+ stop-mode = <&gpr 0x10 3>;
+ fsl,num-tx-queues=<3>;
+ fsl,num-rx-queues=<3>;
+ fsl,wakeup_irq = <2>;
+ status = "disabled";
+ };
+
+ dma_cap: dma_cap {
+ compatible = "dma-capability";
+ only-dma-mask32 = <1>;
+ };
+
+ imx_ion {
+ compatible = "fsl,mxc-ion";
+ fsl,heap-id = <0>;
+ };
+
+ lcdif: lcdif@32E00000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx8mm-lcdif";
+ reg = <0x0 0x32e00000 0x0 0x10000>;
+ clocks = <&clk IMX8MM_CLK_LCDIF_PIXEL_DIV>,
+ <&clk IMX8MM_CLK_DISP_AXI_ROOT>,
+ <&clk IMX8MM_CLK_DISP_APB_ROOT>;
+ clock-names = "pix", "disp-axi", "disp-apb";
+ assigned-clocks = <&clk IMX8MM_CLK_LCDIF_PIXEL_SRC>,
+ <&clk IMX8MM_CLK_DISP_AXI_SRC>,
+ <&clk IMX8MM_CLK_DISP_APB_SRC>;
+ assigned-clock-parents = <&clk IMX8MM_VIDEO_PLL1_OUT>,
+ <&clk IMX8MM_SYS_PLL2_1000M>,
+ <&clk IMX8MM_SYS_PLL1_800M>;
+ assigned-clock-rate = <594000000>, <500000000>, <200000000>;
+ interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>;
+ lcdif-gpr = <&dispmix_gpr>;
+ power-domains = <&dispmix_pd>;
+ status = "disabled";
+
+ lcdif_disp0: port@0 {
+ reg = <0>;
+
+ lcdif_to_dsim: endpoint {
+ remote-endpoint = <&dsim_from_lcdif>;
+ };
+ };
+ };
+
+ mipi_dsi: mipi_dsi@32E10000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx8mm-mipi-dsim";
+ reg = <0x0 0x32e10000 0x0 0x400>;
+ clocks = <&clk IMX8MM_CLK_DSI_CORE_DIV>,
+ <&clk IMX8MM_CLK_DSI_PHY_REF_DIV>;
+ clock-names = "cfg", "pll-ref";
+ assigned-clocks = <&clk IMX8MM_CLK_DSI_CORE_SRC>,
+ <&clk IMX8MM_CLK_DSI_PHY_REF_SRC>;
+ assigned-clock-parents = <&clk IMX8MM_SYS_PLL1_266M>,
+ <&clk IMX8MM_VIDEO_PLL1_OUT>;
+ assigned-clock-rates = <266000000>, <594000000>;
+ interrupts = <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>;
+ dsi-gpr = <&dispmix_gpr>;
+ power-domains = <&mipi_pd>;
+ status = "disabled";
+
+ port@0 {
+ dsim_from_lcdif: endpoint {
+ remote-endpoint = <&lcdif_to_dsim>;
+ };
+ };
+ };
+
+ display-subsystem {
+ compatible = "fsl,imx-display-subsystem";
+ ports = <&lcdif_disp0>;
+ };
+
+ pcie0: pcie@0x33800000 {
+ compatible = "fsl,imx8mm-pcie", "snps,dw-pcie";
+ reg = <0x0 0x33800000 0x0 0x400000>, <0x0 0x32f00000 0x0 0x10000>,
+ <0x0 0x1ff00000 0x0 0x80000>;
+ reg-names = "dbi", "phy", "config";
+ reserved-region = <&rpmsg_reserved>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ device_type = "pci";
+ ranges = <0x81000000 0 0x00000000 0x0 0x1ff80000 0 0x00010000 /* downstream I/O 64KB */
+ 0x82000000 0 0x18000000 0x0 0x18000000 0 0x07f00000>; /* non-prefetchable memory */
+ num-lanes = <1>;
+ interrupts = <GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 127 IRQ_TYPE_LEVEL_HIGH>; /* eDMA */
+ interrupt-names = "msi";
+ #interrupt-cells = <1>;
+ interrupt-map-mask = <0 0 0 0x7>;
+ interrupt-map = <0 0 0 1 &gic GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>,
+ <0 0 0 2 &gic GIC_SPI 124 IRQ_TYPE_LEVEL_HIGH>,
+ <0 0 0 3 &gic GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>,
+ <0 0 0 4 &gic GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8MM_CLK_PCIE1_ROOT>,
+ <&clk IMX8MM_CLK_PCIE1_AUX_CG>,
+ <&clk IMX8MM_CLK_PCIE1_PHY_CG>;
+ clock-names = "pcie", "pcie_bus", "pcie_phy";
+ fsl,max-link-speed = <2>;
+ ctrl-id = <0>;
+ power-domains = <&pcie0_pd>;
+ status = "disabled";
+ };
+
+ pwm1: pwm@30660000 {
+ compatible = "fsl,imx8mm-pwm", "fsl,imx27-pwm";
+ reg = <0x0 0x30660000 0x0 0x10000>;
+ interrupts = <GIC_SPI 81 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8MM_CLK_PWM1_ROOT>,
+ <&clk IMX8MM_CLK_PWM1_ROOT>;
+ clock-names = "ipg", "per";
+ #pwm-cells = <2>;
+ status = "disabled";
+ };
+
+ pwm2: pwm@30670000 {
+ compatible = "fsl,imx8mm-pwm", "fsl,imx27-pwm";
+ reg = <0x0 0x30670000 0x0 0x10000>;
+ interrupts = <GIC_SPI 82 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8MM_CLK_PWM2_ROOT>,
+ <&clk IMX8MM_CLK_PWM2_ROOT>;
+ clock-names = "ipg", "per";
+ #pwm-cells = <2>;
+ status = "disabled";
+ };
+
+ pwm3: pwm@30680000 {
+ compatible = "fsl,imx8mm-pwm", "fsl,imx27-pwm";
+ reg = <0x0 0x30680000 0x0 0x10000>;
+ interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8MM_CLK_PWM3_ROOT>,
+ <&clk IMX8MM_CLK_PWM3_ROOT>;
+ clock-names = "ipg", "per";
+ #pwm-cells = <2>;
+ status = "disabled";
+ };
+
+ pwm4: pwm@30690000 {
+ compatible = "fsl,imx8mm-pwm", "fsl,imx27-pwm";
+ reg = <0x0 0x30690000 0x0 0x10000>;
+ interrupts = <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8MM_CLK_PWM4_ROOT>,
+ <&clk IMX8MM_CLK_PWM4_ROOT>;
+ clock-names = "ipg", "per";
+ #pwm-cells = <2>;
+ status = "disabled";
+ };
+
+ vpu_h1: vpu_h1@38320000 {
+ compatible = "nxp,imx8mm-hantro-h1";
+ reg = <0x0 0x38320000 0x0 0x10000>;
+ reg-names = "regs_hantro_h1";
+ interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "irq_hantro_h1";
+ clocks = <&clk IMX8MM_CLK_VPU_H1_ROOT>, <&clk IMX8MM_CLK_VPU_DEC_ROOT>;
+ clock-names = "clk_hantro_h1", "clk_hantro_h1_bus";
+ assigned-clocks = <&clk IMX8MM_CLK_VPU_H1_SRC>,<&clk IMX8MM_CLK_VPU_BUS_SRC>;
+ assigned-clock-parents = <&clk IMX8MM_VPU_PLL_OUT>, <&clk IMX8MM_SYS_PLL1_800M>;
+ assigned-clock-rates = <600000000>, <800000000>;
+ power-domains = <&vpu_h1_pd>;
+ status = "disabled";
+ };
+
+ vpu_g1: vpu_g1@38300000 {
+ compatible = "nxp,imx8mm-hantro";
+ reg = <0x0 0x38300000 0x0 0x100000>;
+ reg-names = "regs_hantro";
+ interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "irq_hantro";
+ clocks = <&clk IMX8MM_CLK_VPU_G1_ROOT>, <&clk IMX8MM_CLK_VPU_DEC_ROOT>;
+ clock-names = "clk_hantro", "clk_hantro_bus";
+ assigned-clocks = <&clk IMX8MM_CLK_VPU_G1_SRC>, <&clk IMX8MM_CLK_VPU_BUS_SRC>;
+ assigned-clock-parents = <&clk IMX8MM_VPU_PLL_OUT>, <&clk IMX8MM_SYS_PLL1_800M>;
+ assigned-clock-rates = <600000000>, <800000000>;
+ power-domains = <&vpu_g1_pd>;
+ status = "disabled";
+ };
+
+ vpu_g2: vpu_g2@38310000 {
+ compatible = "nxp,imx8mm-hantro";
+ reg = <0x0 0x38310000 0x0 0x100000>;
+ reg-names = "regs_hantro";
+ interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "irq_hantro";
+ clocks = <&clk IMX8MM_CLK_VPU_G2_ROOT>, <&clk IMX8MM_CLK_VPU_DEC_ROOT>;
+ clock-names = "clk_hantro", "clk_hantro_bus";
+ assigned-clocks = <&clk IMX8MM_CLK_VPU_G2_SRC>, <&clk IMX8MM_CLK_VPU_BUS_SRC>;
+ assigned-clock-parents = <&clk IMX8MM_VPU_PLL_OUT>, <&clk IMX8MM_SYS_PLL1_800M>;
+ assigned-clock-rates = <600000000>, <800000000>;
+ power-domains = <&vpu_g2_pd>;
+ status = "disabled";
+ };
+
+ gpu: gpu@38000000 {
+ compatible ="fsl,imx8mm-gpu", "fsl,imx6q-gpu";
+ reg = <0x0 0x38000000 0x0 0x8000>, <0x0 0x38008000 0x0 0x8000>,
+ <0x0 0x40000000 0x0 0x80000000>, <0x0 0x0 0x0 0x8000000>;
+ reg-names = "iobase_3d", "iobase_2d",
+ "phys_baseaddr", "contiguous_mem";
+ interrupts = <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "irq_3d", "irq_2d";
+ clocks = <&clk IMX8MM_CLK_GPU3D_ROOT>,
+ <&clk IMX8MM_CLK_DUMMY>,
+ <&clk IMX8MM_CLK_GPU_BUS_ROOT>,
+ <&clk IMX8MM_CLK_GPU_AHB_DIV>,
+ <&clk IMX8MM_CLK_GPU2D_ROOT>,
+ <&clk IMX8MM_CLK_GPU_BUS_ROOT>,
+ <&clk IMX8MM_CLK_GPU_AHB_DIV>;
+ clock-names = "gpu3d_clk", "gpu3d_shader_clk",
+ "gpu3d_axi_clk", "gpu3d_ahb_clk",
+ "gpu2d_clk", "gpu2d_axi_clk",
+ "gpu2d_ahb_clk";
+
+ assigned-clocks = <&clk IMX8MM_CLK_GPU3D_SRC>, <&clk IMX8MM_CLK_GPU2D_SRC>, <&clk IMX8MM_CLK_GPU_AXI_SRC>, <&clk IMX8MM_CLK_GPU_AHB_SRC>,<&clk IMX8MM_GPU_PLL_OUT>, <&clk IMX8MM_CLK_GPU_AHB_DIV>;
+ assigned-clock-parents = <&clk IMX8MM_GPU_PLL_OUT>,<&clk IMX8MM_GPU_PLL_OUT>, <&clk IMX8MM_SYS_PLL1_800M>, <&clk IMX8MM_SYS_PLL1_800M>;
+ assigned-clock-rates = <0>, <0>, <0>,<0>,<1000000000>, <400000000>;
+
+ power-domains = <&gpumix_pd>;
+
+ status = "disabled";
+ };
+
+ crypto: caam@30900000 {
+ compatible = "fsl,sec-v4.0";
+ #address-cells = <0x1>;
+ #size-cells = <0x1>;
+ reg = <0 0x30900000 0 0x40000>;
+ ranges = <0 0 0x30900000 0x40000>;
+ interrupts = <GIC_SPI 91 IRQ_TYPE_LEVEL_HIGH>;
+
+ sec_jr0: jr0@1000 {
+ compatible = "fsl,sec-v4.0-job-ring";
+ reg = <0x1000 0x1000>;
+ interrupts = <GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ sec_jr1: jr1@2000 {
+ compatible = "fsl,sec-v4.0-job-ring";
+ reg = <0x2000 0x1000>;
+ interrupts = <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ sec_jr2: jr2@3000 {
+ compatible = "fsl,sec-v4.0-job-ring";
+ reg = <0x3000 0x1000>;
+ interrupts = <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>;
+ };
+ };
+
+ caam_sm: caam-sm@00100000 {
+ compatible = "fsl,imx6q-caam-sm";
+ reg = <0 0x00100000 0 0x8000>;
+ };
+
+ caam_snvs: caam-snvs@30370000 {
+ compatible = "fsl,imx6q-caam-snvs";
+ reg = <0 0x30370000 0 0x10000>;
+ };
+
+ irq_sec_vio: caam_secvio {
+ compatible = "fsl,imx7d-caam-secvio", "fsl,imx6q-caam-secvio";
+ interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
+ jtag-tamper = "disabled";
+ watchdog-tamper = "enabled";
+ internal-boot-tamper = "enabled";
+ external-pin-tamper = "disabled";
+ };
+
+ dma_apbh: dma-apbh@33000000 {
+ compatible = "fsl,imx7d-dma-apbh", "fsl,imx28-dma-apbh";
+ reg = <0 0x33000000 0 0x2000>;
+ interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "gpmi0", "gpmi1", "gpmi2", "gpmi3";
+ #dma-cells = <1>;
+ dma-channels = <4>;
+ clocks = <&clk IMX8MM_CLK_NAND_USDHC_BUS_RAWNAND_CLK>;
+ };
+
+ gpmi: gpmi-nand@33002000{
+ compatible = "fsl,imx7d-gpmi-nand";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0 0x33002000 0 0x2000>, <0 0x33004000 0 0x4000>;
+ reg-names = "gpmi-nand", "bch";
+ interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "bch";
+ clocks = <&clk IMX8MM_CLK_NAND_ROOT>,
+ <&clk IMX8MM_CLK_NAND_USDHC_BUS_RAWNAND_CLK>;
+ clock-names = "gpmi_io", "gpmi_bch_apb";
+ dmas = <&dma_apbh 0>;
+ dma-names = "rx-tx";
+ status = "disabled";
+ };
+};
+
+&A53_0 {
+ operating-points = <
+ /* kHz uV */
+ 1800000 1000000
+ 1600000 950000
+ 1200000 850000
+ >;
+ clocks = <&clk IMX8MM_CLK_A53_DIV>, <&clk IMX8MM_CLK_A53_SRC>,
+ <&clk IMX8MM_ARM_PLL>, <&clk IMX8MM_ARM_PLL_OUT>,
+ <&clk IMX8MM_SYS_PLL1_800M>;
+ clock-names = "a53", "arm_a53_src", "arm_pll",
+ "arm_pll_out", "sys1_pll_800m";
+ clock-latency = <61036>;
+ #cooling-cells = <2>;
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8mq-ddr3l-arm2.dts b/arch/arm64/boot/dts/freescale/fsl-imx8mq-ddr3l-arm2.dts
new file mode 100644
index 000000000000..2f9f6c660a65
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8mq-ddr3l-arm2.dts
@@ -0,0 +1,371 @@
+/*
+ * Copyright 2017 NXP
+ *
+ * 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.
+ */
+
+/dts-v1/;
+
+#include "fsl-imx8mq.dtsi"
+
+/ {
+ model = "Freescale i.MX8MQ DDR3L ARM2";
+ compatible = "fsl,imx8mq-evk", "fsl,imx8mq";
+
+ chosen {
+ bootargs = "console=ttymxc0,115200 earlycon=ec_imx6q,0x30860000,115200";
+ stdout-path = &uart1;
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ reg_usdhc2_vmmc: usdhc2_vmmc {
+ compatible = "regulator-fixed";
+ regulator-name = "VSD_3V3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&gpio2 19 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+ };
+
+ busfreq {
+ status = "disabled";
+ };
+};
+
+&iomuxc {
+ pinctrl-names = "default";
+
+ imx8mq-arm2 {
+ pinctrl_fec1: fec1grp {
+ fsl,pins = <
+ MX8MQ_IOMUXC_ENET_MDC_ENET1_MDC 0x3
+ MX8MQ_IOMUXC_ENET_MDIO_ENET1_MDIO 0x23
+ MX8MQ_IOMUXC_ENET_TD2_ENET1_TX_CLK 0x4000001f
+ MX8MQ_IOMUXC_ENET_TD1_ENET1_RGMII_TD1 0x56
+ MX8MQ_IOMUXC_ENET_TD0_ENET1_RGMII_TD0 0x56
+ MX8MQ_IOMUXC_ENET_RD1_ENET1_RGMII_RD1 0x56
+ MX8MQ_IOMUXC_ENET_RD0_ENET1_RGMII_RD0 0x56
+ MX8MQ_IOMUXC_ENET_RXC_ENET1_RX_ER 0x56
+ MX8MQ_IOMUXC_ENET_RX_CTL_ENET1_RGMII_RX_CTL 0x56
+ MX8MQ_IOMUXC_ENET_TX_CTL_ENET1_RGMII_TX_CTL 0x56
+ >;
+ };
+
+ pinctrl_i2c1: i2c1grp {
+ fsl,pins = <
+ MX8MQ_IOMUXC_I2C1_SCL_I2C1_SCL 0x4000007f
+ MX8MQ_IOMUXC_I2C1_SDA_I2C1_SDA 0x4000007f
+ >;
+ };
+
+ pinctrl_i2c2: i2c2grp {
+ fsl,pins = <
+ MX8MQ_IOMUXC_I2C2_SCL_I2C2_SCL 0x4000007f
+ MX8MQ_IOMUXC_I2C2_SDA_I2C2_SDA 0x4000007f
+ >;
+ };
+
+
+ pinctrl_qspi: qspigrp {
+ fsl,pins = <
+ MX8MQ_IOMUXC_NAND_ALE_QSPI_A_SCLK 0x82
+ MX8MQ_IOMUXC_NAND_CLE_QSPI_B_SCLK 0x82
+ MX8MQ_IOMUXC_NAND_CE0_B_QSPI_A_SS0_B 0x82
+ MX8MQ_IOMUXC_NAND_CE2_B_QSPI_B_SS0_B 0x82
+ MX8MQ_IOMUXC_NAND_DATA00_QSPI_A_DATA0 0x82
+ MX8MQ_IOMUXC_NAND_DATA01_QSPI_A_DATA1 0x82
+ MX8MQ_IOMUXC_NAND_DATA02_QSPI_A_DATA2 0x82
+ MX8MQ_IOMUXC_NAND_DATA03_QSPI_A_DATA3 0x82
+ MX8MQ_IOMUXC_NAND_DATA04_QSPI_B_DATA0 0x82
+ MX8MQ_IOMUXC_NAND_DATA05_QSPI_B_DATA1 0x82
+ MX8MQ_IOMUXC_NAND_DATA06_QSPI_B_DATA2 0x82
+ MX8MQ_IOMUXC_NAND_DATA07_QSPI_B_DATA3 0x82
+
+ >;
+ };
+
+ pinctrl_uart1: uart1grp {
+ fsl,pins = <
+ MX8MQ_IOMUXC_UART1_RXD_UART1_DCE_RX 0x79
+ MX8MQ_IOMUXC_UART1_TXD_UART1_DCE_TX 0x79
+ >;
+ };
+
+ pinctrl_usdhc1: usdhc1grp {
+ fsl,pins = <
+ MX8MQ_IOMUXC_SD1_CLK_USDHC1_CLK 0x83
+ MX8MQ_IOMUXC_SD1_CMD_USDHC1_CMD 0xc3
+ MX8MQ_IOMUXC_SD1_DATA0_USDHC1_DATA0 0xc3
+ MX8MQ_IOMUXC_SD1_DATA1_USDHC1_DATA1 0xc3
+ MX8MQ_IOMUXC_SD1_DATA2_USDHC1_DATA2 0xc3
+ MX8MQ_IOMUXC_SD1_DATA3_USDHC1_DATA3 0xc3
+ MX8MQ_IOMUXC_SD1_DATA4_USDHC1_DATA4 0xc3
+ MX8MQ_IOMUXC_SD1_DATA5_USDHC1_DATA5 0xc3
+ MX8MQ_IOMUXC_SD1_DATA6_USDHC1_DATA6 0xc3
+ MX8MQ_IOMUXC_SD1_DATA7_USDHC1_DATA7 0xc3
+ MX8MQ_IOMUXC_SD1_STROBE_USDHC1_STROBE 0x83
+ MX8MQ_IOMUXC_SD1_RESET_B_USDHC1_RESET_B 0xc1
+ >;
+ };
+
+ pinctrl_usdhc1_100mhz: usdhc1grp100mhz {
+ fsl,pins = <
+ MX8MQ_IOMUXC_SD1_CLK_USDHC1_CLK 0x8d
+ MX8MQ_IOMUXC_SD1_CMD_USDHC1_CMD 0xcd
+ MX8MQ_IOMUXC_SD1_DATA0_USDHC1_DATA0 0xcd
+ MX8MQ_IOMUXC_SD1_DATA1_USDHC1_DATA1 0xcd
+ MX8MQ_IOMUXC_SD1_DATA2_USDHC1_DATA2 0xcd
+ MX8MQ_IOMUXC_SD1_DATA3_USDHC1_DATA3 0xcd
+ MX8MQ_IOMUXC_SD1_DATA4_USDHC1_DATA4 0xcd
+ MX8MQ_IOMUXC_SD1_DATA5_USDHC1_DATA5 0xcd
+ MX8MQ_IOMUXC_SD1_DATA6_USDHC1_DATA6 0xcd
+ MX8MQ_IOMUXC_SD1_DATA7_USDHC1_DATA7 0xcd
+ MX8MQ_IOMUXC_SD1_STROBE_USDHC1_STROBE 0x8d
+ MX8MQ_IOMUXC_SD1_RESET_B_USDHC1_RESET_B 0xc1
+ >;
+ };
+
+ pinctrl_usdhc1_200mhz: usdhc1grp200mhz {
+ fsl,pins = <
+ MX8MQ_IOMUXC_SD1_CLK_USDHC1_CLK 0x9f
+ MX8MQ_IOMUXC_SD1_CMD_USDHC1_CMD 0xdf
+ MX8MQ_IOMUXC_SD1_DATA0_USDHC1_DATA0 0xdf
+ MX8MQ_IOMUXC_SD1_DATA1_USDHC1_DATA1 0xdf
+ MX8MQ_IOMUXC_SD1_DATA2_USDHC1_DATA2 0xdf
+ MX8MQ_IOMUXC_SD1_DATA3_USDHC1_DATA3 0xdf
+ MX8MQ_IOMUXC_SD1_DATA4_USDHC1_DATA4 0xdf
+ MX8MQ_IOMUXC_SD1_DATA5_USDHC1_DATA5 0xdf
+ MX8MQ_IOMUXC_SD1_DATA6_USDHC1_DATA6 0xdf
+ MX8MQ_IOMUXC_SD1_DATA7_USDHC1_DATA7 0xdf
+ MX8MQ_IOMUXC_SD1_STROBE_USDHC1_STROBE 0x9f
+ MX8MQ_IOMUXC_SD1_RESET_B_USDHC1_RESET_B 0xc1
+ >;
+ };
+
+ pinctrl_usdhc2_gpio: usdhc2grpgpio {
+ fsl,pins = <
+ MX8MQ_IOMUXC_SD2_CD_B_GPIO2_IO12 0x41
+ MX8MQ_IOMUXC_SD2_RESET_B_GPIO2_IO19 0x41
+ >;
+ };
+
+ pinctrl_usdhc2: usdhc2grp {
+ fsl,pins = <
+ MX8MQ_IOMUXC_SD2_CLK_USDHC2_CLK 0x83
+ MX8MQ_IOMUXC_SD2_CMD_USDHC2_CMD 0xc3
+ MX8MQ_IOMUXC_SD2_DATA0_USDHC2_DATA0 0xc3
+ MX8MQ_IOMUXC_SD2_DATA1_USDHC2_DATA1 0xc3
+ MX8MQ_IOMUXC_SD2_DATA2_USDHC2_DATA2 0xc3
+ MX8MQ_IOMUXC_SD2_DATA3_USDHC2_DATA3 0xc3
+ MX8MQ_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0xc1
+ >;
+ };
+
+ pinctrl_usdhc2_100mhz: usdhc2grp100mhz {
+ fsl,pins = <
+ MX8MQ_IOMUXC_SD2_CLK_USDHC2_CLK 0x8d
+ MX8MQ_IOMUXC_SD2_CMD_USDHC2_CMD 0xcd
+ MX8MQ_IOMUXC_SD2_DATA0_USDHC2_DATA0 0xcd
+ MX8MQ_IOMUXC_SD2_DATA1_USDHC2_DATA1 0xcd
+ MX8MQ_IOMUXC_SD2_DATA2_USDHC2_DATA2 0xcd
+ MX8MQ_IOMUXC_SD2_DATA3_USDHC2_DATA3 0xcd
+ MX8MQ_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0xc1
+ >;
+ };
+
+ pinctrl_usdhc2_200mhz: usdhc2grp200mhz {
+ fsl,pins = <
+ MX8MQ_IOMUXC_SD2_CLK_USDHC2_CLK 0x9f
+ MX8MQ_IOMUXC_SD2_CMD_USDHC2_CMD 0xdf
+ MX8MQ_IOMUXC_SD2_DATA0_USDHC2_DATA0 0xdf
+ MX8MQ_IOMUXC_SD2_DATA1_USDHC2_DATA1 0xdf
+ MX8MQ_IOMUXC_SD2_DATA2_USDHC2_DATA2 0xdf
+ MX8MQ_IOMUXC_SD2_DATA3_USDHC2_DATA3 0xdf
+ MX8MQ_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0xc1
+ >;
+ };
+
+ };
+};
+
+&fec1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_fec1>;
+ phy-mode = "rmii";
+ phy-handle = <&ethphy0>;
+ fsl,magic-packet;
+ assigned-clock-parents = <&clk IMX8MQ_SYS1_PLL_266M>,
+ <&clk IMX8MQ_SYS2_PLL_100M>,
+ <&clk IMX8MQ_SYS2_PLL_50M>;
+ assigned-clock-rates = <0>, <0>, <50000000>, <100000000>;
+ status = "okay";
+
+ mdio {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ethphy0: ethernet-phy@0 {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <3>;
+ };
+ };
+};
+
+&i2c1 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c1>;
+ status = "okay";
+
+ pmic: pfuze100@08 {
+ compatible = "fsl,pfuze100";
+ reg = <0x08>;
+
+ regulators {
+ sw1a_reg: sw1ab {
+ regulator-min-microvolt = <300000>;
+ regulator-max-microvolt = <1875000>;
+ regulator-always-on;
+ };
+
+ sw1c_reg: sw1c {
+ regulator-min-microvolt = <300000>;
+ regulator-max-microvolt = <1875000>;
+ regulator-always-on;
+ };
+
+ sw2_reg: sw2 {
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ sw3a_reg: sw3ab {
+ regulator-min-microvolt = <400000>;
+ regulator-max-microvolt = <1975000>;
+ regulator-always-on;
+ };
+
+ sw4_reg: sw4 {
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ swbst_reg: swbst {
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5150000>;
+ };
+
+ snvs_reg: vsnvs {
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-always-on;
+ };
+
+ vref_reg: vrefddr {
+ regulator-always-on;
+ };
+
+ vgen1_reg: vgen1 {
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1550000>;
+ };
+
+ vgen2_reg: vgen2 {
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1550000>;
+ regulator-always-on;
+ };
+
+ vgen3_reg: vgen3 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ vgen4_reg: vgen4 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ vgen5_reg: vgen5 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ vgen6_reg: vgen6 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ };
+ };
+ };
+};
+
+&i2c2 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c2>;
+ status = "okay";
+};
+
+&uart1 { /* console */
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart1>;
+ assigned-clocks = <&clk IMX8MQ_CLK_UART1>;
+ assigned-clock-parents = <&clk IMX8MQ_CLK_25M>;
+ status = "okay";
+};
+
+&usdhc1 {
+ pinctrl-names = "default", "state_100mhz", "state_200mhz";
+ pinctrl-0 = <&pinctrl_usdhc1>;
+ pinctrl-1 = <&pinctrl_usdhc1_100mhz>;
+ pinctrl-2 = <&pinctrl_usdhc1_200mhz>;
+ bus-width = <8>;
+ non-removable;
+ status = "okay";
+};
+
+&usdhc2 {
+ pinctrl-names = "default", "state_100mhz", "state_200mhz";
+ pinctrl-0 = <&pinctrl_usdhc2>, <&pinctrl_usdhc2_gpio>;
+ pinctrl-1 = <&pinctrl_usdhc2_100mhz>, <&pinctrl_usdhc2_gpio>;
+ pinctrl-2 = <&pinctrl_usdhc2_200mhz>, <&pinctrl_usdhc2_gpio>;
+ bus-width = <4>;
+ cd-gpios = <&gpio2 12 GPIO_ACTIVE_LOW>;
+ vmmc-supply = <&reg_usdhc2_vmmc>;
+ status = "okay";
+};
+
+&dcss {
+ status = "okay";
+
+ disp-dev = "hdmi_disp";
+};
+
+&hdmi {
+ compatible = "fsl,imx8mq-dp";
+
+ dp-lane-mapping = <0x4e>;
+ dp-link-rate = <0x14>;
+ dp-num-lanes = <0x4>;
+
+ status = "okay";
+};
+
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8mq-ddr4-arm2-gpmi-nand.dts b/arch/arm64/boot/dts/freescale/fsl-imx8mq-ddr4-arm2-gpmi-nand.dts
new file mode 100644
index 000000000000..bc6c8b7c2ce1
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8mq-ddr4-arm2-gpmi-nand.dts
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2017 NXP
+ *
+ *
+ * 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.
+ */
+
+#include "fsl-imx8mq-ddr4-arm2.dts"
+
+&iomuxc {
+ imx8mq-arm2 {
+ pinctrl_gpmi_nand_1: gpmi-nand-1 {
+ fsl,pins = <
+ MX8MQ_IOMUXC_NAND_ALE_RAWNAND_ALE 0x00000096
+ MX8MQ_IOMUXC_NAND_CE0_B_RAWNAND_CE0_B 0x00000096
+ MX8MQ_IOMUXC_NAND_CLE_RAWNAND_CLE 0x00000096
+ MX8MQ_IOMUXC_NAND_DATA00_RAWNAND_DATA00 0x00000096
+ MX8MQ_IOMUXC_NAND_DATA01_RAWNAND_DATA01 0x00000096
+ MX8MQ_IOMUXC_NAND_DATA02_RAWNAND_DATA02 0x00000096
+ MX8MQ_IOMUXC_NAND_DATA03_RAWNAND_DATA03 0x00000096
+ MX8MQ_IOMUXC_NAND_DATA04_RAWNAND_DATA04 0x00000096
+ MX8MQ_IOMUXC_NAND_DATA05_RAWNAND_DATA05 0x00000096
+ MX8MQ_IOMUXC_NAND_DATA06_RAWNAND_DATA06 0x00000096
+ MX8MQ_IOMUXC_NAND_DATA07_RAWNAND_DATA07 0x00000096
+ MX8MQ_IOMUXC_NAND_RE_B_RAWNAND_RE_B 0x00000096
+ MX8MQ_IOMUXC_NAND_READY_B_RAWNAND_READY_B 0x00000056
+ MX8MQ_IOMUXC_NAND_WE_B_RAWNAND_WE_B 0x00000096
+ MX8MQ_IOMUXC_NAND_WP_B_RAWNAND_WP_B 0x00000096
+ >;
+ };
+ };
+};
+
+&gpmi {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpmi_nand_1>;
+ status = "okay";
+ nand-on-flash-bbt;
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8mq-ddr4-arm2.dts b/arch/arm64/boot/dts/freescale/fsl-imx8mq-ddr4-arm2.dts
new file mode 100644
index 000000000000..9679a76599fa
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8mq-ddr4-arm2.dts
@@ -0,0 +1,363 @@
+/*
+ * Copyright 2017 NXP
+ *
+ * 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.
+ */
+
+/dts-v1/;
+
+#include "fsl-imx8mq.dtsi"
+
+/ {
+ model = "Freescale i.MX8MQ DDR4 ARM2";
+ compatible = "fsl,imx8mq-evk", "fsl,imx8mq";
+
+ chosen {
+ bootargs = "console=ttymxc0,115200 earlycon=ec_imx6q,0x30860000,115200";
+ stdout-path = &uart1;
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ reg_usdhc2_vmmc: usdhc2_vmmc {
+ compatible = "regulator-fixed";
+ regulator-name = "VSD_3V3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&gpio2 19 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+ };
+
+ busfreq {
+ status = "disabled";
+ };
+};
+
+&iomuxc {
+ pinctrl-names = "default";
+
+ imx8mq-arm2 {
+ pinctrl_fec1: fec1grp {
+ fsl,pins = <
+ MX8MQ_IOMUXC_ENET_MDC_ENET1_MDC 0x3
+ MX8MQ_IOMUXC_ENET_MDIO_ENET1_MDIO 0x23
+ MX8MQ_IOMUXC_ENET_TD3_ENET1_RGMII_TD3 0x1f
+ MX8MQ_IOMUXC_ENET_TD2_ENET1_RGMII_TD2 0x1f
+ MX8MQ_IOMUXC_ENET_TD1_ENET1_RGMII_TD1 0x1f
+ MX8MQ_IOMUXC_ENET_TD0_ENET1_RGMII_TD0 0x1f
+ MX8MQ_IOMUXC_ENET_RD3_ENET1_RGMII_RD3 0x91
+ MX8MQ_IOMUXC_ENET_RD2_ENET1_RGMII_RD2 0x91
+ MX8MQ_IOMUXC_ENET_RD1_ENET1_RGMII_RD1 0x91
+ MX8MQ_IOMUXC_ENET_RD0_ENET1_RGMII_RD0 0x91
+ MX8MQ_IOMUXC_ENET_TXC_ENET1_RGMII_TXC 0x1f
+ MX8MQ_IOMUXC_ENET_RXC_ENET1_RGMII_RXC 0x91
+ MX8MQ_IOMUXC_ENET_RX_CTL_ENET1_RGMII_RX_CTL 0x91
+ MX8MQ_IOMUXC_ENET_TX_CTL_ENET1_RGMII_TX_CTL 0x1f
+ MX8MQ_IOMUXC_GPIO1_IO09_GPIO1_IO9 0x19
+ >;
+ };
+
+ pinctrl_i2c1: i2c1grp {
+ fsl,pins = <
+ MX8MQ_IOMUXC_I2C1_SCL_I2C1_SCL 0x4000007f
+ MX8MQ_IOMUXC_I2C1_SDA_I2C1_SDA 0x4000007f
+ >;
+ };
+
+ pinctrl_i2c2: i2c2grp {
+ fsl,pins = <
+ MX8MQ_IOMUXC_I2C2_SCL_I2C2_SCL 0x4000007f
+ MX8MQ_IOMUXC_I2C2_SDA_I2C2_SDA 0x4000007f
+ >;
+ };
+
+ pinctrl_uart1: uart1grp {
+ fsl,pins = <
+ MX8MQ_IOMUXC_UART1_RXD_UART1_DCE_RX 0x79
+ MX8MQ_IOMUXC_UART1_TXD_UART1_DCE_TX 0x79
+ >;
+ };
+
+ pinctrl_usdhc1: usdhc1grp {
+ fsl,pins = <
+ MX8MQ_IOMUXC_SD1_CLK_USDHC1_CLK 0x83
+ MX8MQ_IOMUXC_SD1_CMD_USDHC1_CMD 0xc3
+ MX8MQ_IOMUXC_SD1_DATA0_USDHC1_DATA0 0xc3
+ MX8MQ_IOMUXC_SD1_DATA1_USDHC1_DATA1 0xc3
+ MX8MQ_IOMUXC_SD1_DATA2_USDHC1_DATA2 0xc3
+ MX8MQ_IOMUXC_SD1_DATA3_USDHC1_DATA3 0xc3
+ MX8MQ_IOMUXC_SD1_DATA4_USDHC1_DATA4 0xc3
+ MX8MQ_IOMUXC_SD1_DATA5_USDHC1_DATA5 0xc3
+ MX8MQ_IOMUXC_SD1_DATA6_USDHC1_DATA6 0xc3
+ MX8MQ_IOMUXC_SD1_DATA7_USDHC1_DATA7 0xc3
+ MX8MQ_IOMUXC_SD1_STROBE_USDHC1_STROBE 0x83
+ MX8MQ_IOMUXC_SD1_RESET_B_USDHC1_RESET_B 0xc1
+ >;
+ };
+
+ pinctrl_usdhc1_100mhz: usdhc1grp100mhz {
+ fsl,pins = <
+ MX8MQ_IOMUXC_SD1_CLK_USDHC1_CLK 0x8d
+ MX8MQ_IOMUXC_SD1_CMD_USDHC1_CMD 0xcd
+ MX8MQ_IOMUXC_SD1_DATA0_USDHC1_DATA0 0xcd
+ MX8MQ_IOMUXC_SD1_DATA1_USDHC1_DATA1 0xcd
+ MX8MQ_IOMUXC_SD1_DATA2_USDHC1_DATA2 0xcd
+ MX8MQ_IOMUXC_SD1_DATA3_USDHC1_DATA3 0xcd
+ MX8MQ_IOMUXC_SD1_DATA4_USDHC1_DATA4 0xcd
+ MX8MQ_IOMUXC_SD1_DATA5_USDHC1_DATA5 0xcd
+ MX8MQ_IOMUXC_SD1_DATA6_USDHC1_DATA6 0xcd
+ MX8MQ_IOMUXC_SD1_DATA7_USDHC1_DATA7 0xcd
+ MX8MQ_IOMUXC_SD1_STROBE_USDHC1_STROBE 0x8d
+ MX8MQ_IOMUXC_SD1_RESET_B_USDHC1_RESET_B 0xc1
+ >;
+ };
+
+ pinctrl_usdhc1_200mhz: usdhc1grp200mhz {
+ fsl,pins = <
+ MX8MQ_IOMUXC_SD1_CLK_USDHC1_CLK 0x9f
+ MX8MQ_IOMUXC_SD1_CMD_USDHC1_CMD 0xdf
+ MX8MQ_IOMUXC_SD1_DATA0_USDHC1_DATA0 0xdf
+ MX8MQ_IOMUXC_SD1_DATA1_USDHC1_DATA1 0xdf
+ MX8MQ_IOMUXC_SD1_DATA2_USDHC1_DATA2 0xdf
+ MX8MQ_IOMUXC_SD1_DATA3_USDHC1_DATA3 0xdf
+ MX8MQ_IOMUXC_SD1_DATA4_USDHC1_DATA4 0xdf
+ MX8MQ_IOMUXC_SD1_DATA5_USDHC1_DATA5 0xdf
+ MX8MQ_IOMUXC_SD1_DATA6_USDHC1_DATA6 0xdf
+ MX8MQ_IOMUXC_SD1_DATA7_USDHC1_DATA7 0xdf
+ MX8MQ_IOMUXC_SD1_STROBE_USDHC1_STROBE 0x9f
+ MX8MQ_IOMUXC_SD1_RESET_B_USDHC1_RESET_B 0xc1
+ >;
+ };
+
+ pinctrl_usdhc2_gpio: usdhc2grpgpio {
+ fsl,pins = <
+ MX8MQ_IOMUXC_SD2_CD_B_GPIO2_IO12 0x41
+ MX8MQ_IOMUXC_SD2_RESET_B_GPIO2_IO19 0x41
+ >;
+ };
+
+ pinctrl_usdhc2: usdhc2grp {
+ fsl,pins = <
+ MX8MQ_IOMUXC_SD2_CLK_USDHC2_CLK 0x83
+ MX8MQ_IOMUXC_SD2_CMD_USDHC2_CMD 0xc3
+ MX8MQ_IOMUXC_SD2_DATA0_USDHC2_DATA0 0xc3
+ MX8MQ_IOMUXC_SD2_DATA1_USDHC2_DATA1 0xc3
+ MX8MQ_IOMUXC_SD2_DATA2_USDHC2_DATA2 0xc3
+ MX8MQ_IOMUXC_SD2_DATA3_USDHC2_DATA3 0xc3
+ MX8MQ_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0xc1
+ >;
+ };
+
+ pinctrl_usdhc2_100mhz: usdhc2grp100mhz {
+ fsl,pins = <
+ MX8MQ_IOMUXC_SD2_CLK_USDHC2_CLK 0x8d
+ MX8MQ_IOMUXC_SD2_CMD_USDHC2_CMD 0xcd
+ MX8MQ_IOMUXC_SD2_DATA0_USDHC2_DATA0 0xcd
+ MX8MQ_IOMUXC_SD2_DATA1_USDHC2_DATA1 0xcd
+ MX8MQ_IOMUXC_SD2_DATA2_USDHC2_DATA2 0xcd
+ MX8MQ_IOMUXC_SD2_DATA3_USDHC2_DATA3 0xcd
+ MX8MQ_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0xc1
+ >;
+ };
+
+ pinctrl_usdhc2_200mhz: usdhc2grp200mhz {
+ fsl,pins = <
+ MX8MQ_IOMUXC_SD2_CLK_USDHC2_CLK 0x9f
+ MX8MQ_IOMUXC_SD2_CMD_USDHC2_CMD 0xdf
+ MX8MQ_IOMUXC_SD2_DATA0_USDHC2_DATA0 0xdf
+ MX8MQ_IOMUXC_SD2_DATA1_USDHC2_DATA1 0xdf
+ MX8MQ_IOMUXC_SD2_DATA2_USDHC2_DATA2 0xdf
+ MX8MQ_IOMUXC_SD2_DATA3_USDHC2_DATA3 0xdf
+ MX8MQ_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0xc1
+ >;
+ };
+
+ pinctrl_wdog: wdoggrp {
+ fsl,pins = <
+ MX8MQ_IOMUXC_GPIO1_IO02_WDOG1_WDOG_B 0xc6
+ >;
+ };
+ };
+};
+
+&fec1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_fec1>;
+ phy-mode = "rgmii-id";
+ phy-handle = <&ethphy0>;
+ fsl,magic-packet;
+ status = "okay";
+
+ mdio {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ethphy0: ethernet-phy@0 {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <0>;
+ at803x,led-act-blind-workaround;
+ at803x,eee-disabled;
+ };
+ };
+};
+
+&i2c1 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c1>;
+ status = "okay";
+
+ pmic: pfuze100@08 {
+ compatible = "fsl,pfuze100";
+ reg = <0x08>;
+
+ regulators {
+ sw1a_reg: sw1ab {
+ regulator-min-microvolt = <300000>;
+ regulator-max-microvolt = <1875000>;
+ regulator-always-on;
+ };
+
+ sw1c_reg: sw1c {
+ regulator-min-microvolt = <300000>;
+ regulator-max-microvolt = <1875000>;
+ regulator-always-on;
+ };
+
+ sw2_reg: sw2 {
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ sw3a_reg: sw3ab {
+ regulator-min-microvolt = <400000>;
+ regulator-max-microvolt = <1975000>;
+ regulator-always-on;
+ };
+
+ sw4_reg: sw4 {
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ swbst_reg: swbst {
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5150000>;
+ };
+
+ snvs_reg: vsnvs {
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-always-on;
+ };
+
+ vref_reg: vrefddr {
+ regulator-always-on;
+ };
+
+ vgen1_reg: vgen1 {
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1550000>;
+ };
+
+ vgen2_reg: vgen2 {
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1550000>;
+ regulator-always-on;
+ };
+
+ vgen3_reg: vgen3 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ vgen4_reg: vgen4 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ vgen5_reg: vgen5 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ vgen6_reg: vgen6 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ };
+ };
+ };
+};
+
+&i2c2 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c2>;
+ status = "okay";
+};
+
+&uart1 { /* console */
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart1>;
+ assigned-clocks = <&clk IMX8MQ_CLK_UART1>;
+ assigned-clock-parents = <&clk IMX8MQ_CLK_25M>;
+ status = "okay";
+};
+
+&usdhc1 {
+ pinctrl-names = "default", "state_100mhz", "state_200mhz";
+ pinctrl-0 = <&pinctrl_usdhc1>;
+ pinctrl-1 = <&pinctrl_usdhc1_100mhz>;
+ pinctrl-2 = <&pinctrl_usdhc1_200mhz>;
+ bus-width = <8>;
+ non-removable;
+ status = "okay";
+};
+
+&usdhc2 {
+ pinctrl-names = "default", "state_100mhz", "state_200mhz";
+ pinctrl-0 = <&pinctrl_usdhc2>, <&pinctrl_usdhc2_gpio>;
+ pinctrl-1 = <&pinctrl_usdhc2_100mhz>, <&pinctrl_usdhc2_gpio>;
+ pinctrl-2 = <&pinctrl_usdhc2_200mhz>, <&pinctrl_usdhc2_gpio>;
+ bus-width = <4>;
+ cd-gpios = <&gpio2 12 GPIO_ACTIVE_HIGH>;
+ vmmc-supply = <&reg_usdhc2_vmmc>;
+ status = "okay";
+};
+
+&usb3_phy0 {
+ status = "okay";
+};
+
+&usb3_0 {
+ status = "okay";
+};
+
+&usb_dwc3_0 {
+ status = "okay";
+ dr_mode = "peripheral";
+};
+
+&wdog1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_wdog>;
+ fsl,ext-reset-output;
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8mq-evk-ak4497.dts b/arch/arm64/boot/dts/freescale/fsl-imx8mq-evk-ak4497.dts
new file mode 100644
index 000000000000..b761d4c949e2
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8mq-evk-ak4497.dts
@@ -0,0 +1,95 @@
+/*
+ * Copyright 2017 NXP
+ *
+ * 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 "fsl-imx8mq-evk.dts"
+
+/ {
+ sound-ak4458 {
+ status = "disabled";
+ };
+
+ sound-ak4497 {
+ status = "okay";
+ };
+};
+
+&iomuxc {
+
+ imx8mq-evk {
+ pinctrl_sai1_pcm: sai1grp_pcm {
+ fsl,pins = <
+ MX8MQ_IOMUXC_SAI1_MCLK_SAI1_MCLK 0xd6
+ MX8MQ_IOMUXC_SAI1_TXFS_SAI1_TX_SYNC 0xd6
+ MX8MQ_IOMUXC_SAI1_RXD7_SAI1_TX_SYNC 0xd6
+ MX8MQ_IOMUXC_SAI1_TXC_SAI1_TX_BCLK 0xd6
+ MX8MQ_IOMUXC_SAI1_TXD0_SAI1_TX_DATA0 0xd6
+ MX8MQ_IOMUXC_SAI1_TXD1_SAI1_TX_DATA1 0xd6
+ MX8MQ_IOMUXC_SAI1_TXD2_SAI1_TX_DATA2 0xd6
+ MX8MQ_IOMUXC_SAI1_TXD3_SAI1_TX_DATA3 0xd6
+ MX8MQ_IOMUXC_SAI1_TXD4_SAI1_TX_DATA4 0xd6
+ MX8MQ_IOMUXC_SAI1_TXD5_SAI1_TX_DATA5 0xd6
+ MX8MQ_IOMUXC_SAI1_TXD6_SAI1_TX_DATA6 0xd6
+ MX8MQ_IOMUXC_SAI1_TXD7_SAI1_TX_DATA7 0xd6
+ >;
+ };
+
+ pinctrl_sai1_dsd: sai1grp_dsd {
+ fsl,pins = <
+ MX8MQ_IOMUXC_SAI1_MCLK_SAI1_MCLK 0xd6
+ MX8MQ_IOMUXC_SAI1_TXFS_SAI1_TX_SYNC 0xd6
+ MX8MQ_IOMUXC_SAI1_RXD7_SAI1_TX_DATA4 0xd6
+ MX8MQ_IOMUXC_SAI1_TXC_SAI1_TX_BCLK 0xd6
+ MX8MQ_IOMUXC_SAI1_TXD0_SAI1_TX_DATA0 0xd6
+ MX8MQ_IOMUXC_SAI1_TXD1_SAI1_TX_DATA1 0xd6
+ MX8MQ_IOMUXC_SAI1_TXD2_SAI1_TX_DATA2 0xd6
+ MX8MQ_IOMUXC_SAI1_TXD3_SAI1_TX_DATA3 0xd6
+ MX8MQ_IOMUXC_SAI1_TXD4_SAI1_TX_DATA4 0xd6
+ MX8MQ_IOMUXC_SAI1_TXD5_SAI1_TX_DATA5 0xd6
+ MX8MQ_IOMUXC_SAI1_TXD6_SAI1_TX_DATA6 0xd6
+ MX8MQ_IOMUXC_SAI1_TXD7_SAI1_TX_DATA7 0xd6
+ >;
+ };
+
+ pinctrl_sai1_dsd512: sai1grp_dsd512 {
+ fsl,pins = <
+ MX8MQ_IOMUXC_SAI1_MCLK_SAI1_TX_BCLK 0xd6
+ MX8MQ_IOMUXC_SAI1_TXFS_SAI1_TX_SYNC 0xd6
+ MX8MQ_IOMUXC_SAI1_RXD7_SAI1_TX_DATA4 0xd6
+ MX8MQ_IOMUXC_SAI1_TXC_SAI1_TX_BCLK 0xd6
+ MX8MQ_IOMUXC_SAI1_TXD0_SAI1_TX_DATA0 0xd6
+ MX8MQ_IOMUXC_SAI1_TXD1_SAI1_TX_DATA1 0xd6
+ MX8MQ_IOMUXC_SAI1_TXD2_SAI1_TX_DATA2 0xd6
+ MX8MQ_IOMUXC_SAI1_TXD3_SAI1_TX_DATA3 0xd6
+ MX8MQ_IOMUXC_SAI1_TXD4_SAI1_TX_DATA4 0xd6
+ MX8MQ_IOMUXC_SAI1_TXD5_SAI1_TX_DATA5 0xd6
+ MX8MQ_IOMUXC_SAI1_TXD6_SAI1_TX_DATA6 0xd6
+ MX8MQ_IOMUXC_SAI1_TXD7_SAI1_TX_DATA7 0xd6
+ >;
+ };
+ };
+};
+
+&sai1 {
+ pinctrl-names = "default", "dsd", "dsd512";
+ pinctrl-0 = <&pinctrl_sai1_pcm>;
+ pinctrl-1 = <&pinctrl_sai1_dsd>;
+ pinctrl-2 = <&pinctrl_sai1_dsd512>;
+ assigned-clocks = <&clk IMX8MQ_CLK_SAI1>;
+ assigned-clock-parents = <&clk IMX8MQ_AUDIO_PLL2_OUT>;
+ assigned-clock-rates = <45158400>;
+ fsl,sai-multi-lane;
+ fsl,dataline,dsd = <0 0xff 0x11>;
+ dmas = <&sdma2 8 26 0>, <&sdma2 9 26 0>;
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8mq-evk-audio-tdm.dts b/arch/arm64/boot/dts/freescale/fsl-imx8mq-evk-audio-tdm.dts
new file mode 100644
index 000000000000..752114f6a064
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8mq-evk-audio-tdm.dts
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2017 NXP
+ *
+ * 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 "fsl-imx8mq-evk.dts"
+
+/ {
+ sound-ak4458 {
+ fsl,tdm;
+ };
+
+ sound-ak5558 {
+ fsl,tdm;
+ };
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8mq-evk-b3.dts b/arch/arm64/boot/dts/freescale/fsl-imx8mq-evk-b3.dts
new file mode 100644
index 000000000000..da8e86582573
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8mq-evk-b3.dts
@@ -0,0 +1,99 @@
+/*
+ * Copyright 2018 NXP
+ *
+ * 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 "fsl-imx8mq-evk.dts"
+
+/delete-node/ &ov5640_mipi;
+/delete-node/ &ov5640_mipi2;
+/delete-node/ &synaptics_dsx_ts;
+/delete-node/ &adv_bridge;
+
+&i2c1 {
+ ov5640_mipi: ov5640_mipi@1c {
+ compatible = "ovti,ov5640_mipi";
+ reg = <0x1c>;
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_csi1_pwn>, <&pinctrl_csi_rst>;
+ clocks = <&clk IMX8MQ_CLK_CLKO2>;
+ clock-names = "csi_mclk";
+ assigned-clocks = <&clk IMX8MQ_CLK_CLKO2>;
+ assigned-clock-parents = <&clk IMX8MQ_SYS2_PLL_200M>;
+ assigned-clock-rates = <20000000>;
+ csi_id = <0>;
+ pwn-gpios = <&gpio1 3 GPIO_ACTIVE_HIGH>;
+ mclk = <20000000>;
+ mclk_source = <0>;
+ port {
+ ov5640_mipi1_ep: endpoint {
+ remote-endpoint = <&mipi1_sensor_ep>;
+ };
+ };
+ };
+
+ ov5640_mipi2: ov5640_mipi2@2c {
+ compatible = "ovti,ov5640_mipi";
+ reg = <0x2c>;
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_csi2_pwn>;
+ clocks = <&clk IMX8MQ_CLK_CLKO2>;
+ clock-names = "csi_mclk";
+ assigned-clocks = <&clk IMX8MQ_CLK_CLKO2>;
+ assigned-clock-parents = <&clk IMX8MQ_SYS2_PLL_200M>;
+ assigned-clock-rates = <20000000>;
+ csi_id = <1>;
+ pwn-gpios = <&gpio1 5 GPIO_ACTIVE_HIGH>;
+ mclk = <20000000>;
+ mclk_source = <0>;
+ port {
+ ov5640_mipi2_ep: endpoint {
+ remote-endpoint = <&mipi2_sensor_ep>;
+ };
+ };
+ };
+
+ synaptics_dsx_ts: synaptics_dsx_ts@20 {
+ compatible = "synaptics_dsx";
+ reg = <0x20>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c1_dsi_ts_int>;
+ interrupt-parent = <&gpio5>;
+ interrupts = <7 IRQ_TYPE_LEVEL_LOW>;
+ synaptics,diagonal-rotation;
+ status = "disabled";
+ };
+
+ adv_bridge: adv7535@3d {
+ compatible = "adi,adv7533";
+ reg = <0x3d>;
+ adi,addr-cec = <0x3b>;
+ adi,dsi-lanes = <4>;
+ pinctrl-0 = <&pinctrl_i2c1_dsi_ts_int>;
+ interrupt-parent = <&gpio5>;
+ interrupts = <7 IRQ_TYPE_LEVEL_LOW>;
+
+ status = "disabled";
+
+ port {
+ adv7535_in: endpoint {
+ remote-endpoint = <&mipi_dsi_bridge_adv>;
+ };
+ };
+ };
+};
+
+&i2c2 {
+ status = "disabled";
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8mq-evk-dcss-adv7535-b3.dts b/arch/arm64/boot/dts/freescale/fsl-imx8mq-evk-dcss-adv7535-b3.dts
new file mode 100644
index 000000000000..ca1655dbf8de
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8mq-evk-dcss-adv7535-b3.dts
@@ -0,0 +1,16 @@
+/*
+ * Copyright 2018 NXP
+ *
+ * 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 "fsl-imx8mq-evk-b3.dts"
+#include "fsl-imx8mq-evk-dcss-adv7535.dtsi"
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8mq-evk-dcss-adv7535.dts b/arch/arm64/boot/dts/freescale/fsl-imx8mq-evk-dcss-adv7535.dts
new file mode 100644
index 000000000000..3bd1381a834a
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8mq-evk-dcss-adv7535.dts
@@ -0,0 +1,16 @@
+/*
+ * Copyright 2017-2018 NXP
+ *
+ * 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 "fsl-imx8mq-evk.dts"
+#include "fsl-imx8mq-evk-dcss-adv7535.dtsi"
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8mq-evk-dcss-adv7535.dtsi b/arch/arm64/boot/dts/freescale/fsl-imx8mq-evk-dcss-adv7535.dtsi
new file mode 100644
index 000000000000..5c8dd0154398
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8mq-evk-dcss-adv7535.dtsi
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2018 NXP
+ *
+ * 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.
+ */
+
+/ {
+ sound-hdmi {
+ status = "disabled";
+ };
+};
+
+&hdmi {
+ status = "disabled";
+};
+
+&dcss {
+ status = "okay";
+ disp-dev = "mipi_disp";
+
+ clocks = <&clk IMX8MQ_CLK_DISP_APB_ROOT>,
+ <&clk IMX8MQ_CLK_DISP_AXI_ROOT>,
+ <&clk IMX8MQ_CLK_DISP_RTRM_ROOT>,
+ <&clk IMX8MQ_CLK_DC_PIXEL>,
+ <&clk IMX8MQ_CLK_DISP_DTRC>,
+ <&clk IMX8MQ_VIDEO_PLL1>,
+ <&clk IMX8MQ_CLK_27M>,
+ <&clk IMX8MQ_CLK_25M>;
+ clock-names = "apb", "axi", "rtrm", "pix", "dtrc",
+ "pll", "pll_src1", "pll_src2";
+ assigned-clocks = <&clk IMX8MQ_CLK_DC_PIXEL>,
+ <&clk IMX8MQ_CLK_DISP_AXI>,
+ <&clk IMX8MQ_CLK_DISP_RTRM>;
+ assigned-clock-parents = <&clk IMX8MQ_VIDEO_PLL1_OUT>,
+ <&clk IMX8MQ_SYS1_PLL_800M>,
+ <&clk IMX8MQ_SYS1_PLL_800M>;
+ assigned-clock-rates = <594000000>,
+ <800000000>,
+ <400000000>;
+
+ dcss_disp0: port@0 {
+ reg = <0>;
+
+ dcss_disp0_mipi_dsi: mipi_dsi {
+ remote-endpoint = <&mipi_dsi_in>;
+ };
+ };
+};
+
+&mipi_dsi_phy {
+ status = "okay";
+};
+
+&mipi_dsi {
+ status = "okay";
+
+ port@1 {
+ mipi_dsi_in: endpoint {
+ remote-endpoint = <&dcss_disp0_mipi_dsi>;
+ };
+ };
+
+};
+
+&mipi_dsi_bridge {
+ status = "okay";
+};
+
+&adv_bridge {
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8mq-evk-dcss-rm67191-b3.dts b/arch/arm64/boot/dts/freescale/fsl-imx8mq-evk-dcss-rm67191-b3.dts
new file mode 100644
index 000000000000..af47a22e9982
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8mq-evk-dcss-rm67191-b3.dts
@@ -0,0 +1,16 @@
+/*
+ * Copyright 2018 NXP
+ *
+ * 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 "fsl-imx8mq-evk-b3.dts"
+#include "fsl-imx8mq-evk-dcss-rm67191.dtsi"
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8mq-evk-dcss-rm67191.dts b/arch/arm64/boot/dts/freescale/fsl-imx8mq-evk-dcss-rm67191.dts
new file mode 100644
index 000000000000..02467af735f5
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8mq-evk-dcss-rm67191.dts
@@ -0,0 +1,16 @@
+/*
+ * Copyright 2017-2018 NXP
+ *
+ * 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 "fsl-imx8mq-evk.dts"
+#include "fsl-imx8mq-evk-dcss-rm67191.dtsi"
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8mq-evk-dcss-rm67191.dtsi b/arch/arm64/boot/dts/freescale/fsl-imx8mq-evk-dcss-rm67191.dtsi
new file mode 100644
index 000000000000..7d124d3d3e30
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8mq-evk-dcss-rm67191.dtsi
@@ -0,0 +1,131 @@
+/*
+ * Copyright 2018 NXP
+ *
+ * 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.
+ */
+
+/ {
+ sound-hdmi {
+ status = "disabled";
+ };
+};
+
+&hdmi {
+ status = "disabled";
+};
+
+&dcss {
+ status = "okay";
+ disp-dev = "mipi_disp";
+
+ clocks = <&clk IMX8MQ_CLK_DISP_APB_ROOT>,
+ <&clk IMX8MQ_CLK_DISP_AXI_ROOT>,
+ <&clk IMX8MQ_CLK_DISP_RTRM_ROOT>,
+ <&clk IMX8MQ_CLK_DC_PIXEL>,
+ <&clk IMX8MQ_CLK_DISP_DTRC>,
+ <&clk IMX8MQ_VIDEO_PLL1>,
+ <&clk IMX8MQ_CLK_27M>,
+ <&clk IMX8MQ_CLK_25M>;
+ clock-names = "apb", "axi", "rtrm", "pix", "dtrc", "pll",
+ "pll_src1", "pll_src2";
+
+ assigned-clocks = <&clk IMX8MQ_CLK_DC_PIXEL>,
+ <&clk IMX8MQ_CLK_DISP_AXI>,
+ <&clk IMX8MQ_CLK_DISP_RTRM>;
+ assigned-clock-parents = <&clk IMX8MQ_VIDEO_PLL1_OUT>,
+ <&clk IMX8MQ_SYS1_PLL_800M>,
+ <&clk IMX8MQ_SYS1_PLL_800M>;
+ assigned-clock-rates = <600000000>,
+ <800000000>,
+ <400000000>;
+
+ dcss_disp0: port@0 {
+ reg = <0>;
+
+ dcss_disp0_mipi_dsi: mipi_dsi {
+ remote-endpoint = <&mipi_dsi_in>;
+ };
+ };
+};
+
+&mipi_dsi_phy {
+ status = "okay";
+};
+
+&mipi_dsi {
+ status = "okay";
+
+ port@1 {
+ mipi_dsi_in: endpoint {
+ remote-endpoint = <&dcss_disp0_mipi_dsi>;
+ };
+ };
+
+};
+
+&mipi_dsi_bridge {
+ status = "okay";
+
+ panel@0 {
+ compatible = "raydium,rm67191";
+ reg = <0>;
+ pinctrl-0 = <&pinctrl_mipi_dsi_en>;
+ reset-gpio = <&gpio5 6 GPIO_ACTIVE_HIGH>;
+ dsi-lanes = <4>;
+ panel-width-mm = <68>;
+ panel-height-mm = <121>;
+
+ display-timings {
+ timing {
+ clock-frequency = <132000000>;
+ hactive = <1080>;
+ vactive = <1920>;
+ hfront-porch = <20>;
+ hsync-len = <2>;
+ hback-porch = <34>;
+ vfront-porch = <10>;
+ vsync-len = <5>;
+ vback-porch = <4>;
+ hsync-active = <0>;
+ vsync-active = <0>;
+ de-active = <0>;
+ pixelclk-active = <0>;
+ };
+ };
+
+ port {
+ panel1_in: endpoint {
+ remote-endpoint = <&mipi_dsi_bridge_out>;
+ };
+ };
+ };
+
+ port@2 {
+ mipi_dsi_bridge_out: endpoint {
+ remote-endpoint = <&panel1_in>;
+ };
+ };
+};
+
+&iomuxc {
+ imx8mq-evk {
+ pinctrl_mipi_dsi_en: mipi_dsi_en {
+ fsl,pins = <
+ MX8MQ_IOMUXC_ECSPI1_SCLK_GPIO5_IO6 0x16
+ >;
+ };
+
+ };
+};
+
+&synaptics_dsx_ts {
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8mq-evk-dp.dts b/arch/arm64/boot/dts/freescale/fsl-imx8mq-evk-dp.dts
new file mode 100644
index 000000000000..5b50ef5148a3
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8mq-evk-dp.dts
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2017 NXP
+ *
+ * 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 "fsl-imx8mq-evk.dts"
+
+&hdmi {
+ compatible = "fsl,imx8mq-dp";
+
+ dp-lane-mapping = <0xc6>;
+ dp-link-rate = <0x14>;
+ dp-num-lanes = <0x4>;
+
+ status = "okay";
+};
+
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8mq-evk-drm.dts b/arch/arm64/boot/dts/freescale/fsl-imx8mq-evk-drm.dts
new file mode 100644
index 000000000000..a695afbf9469
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8mq-evk-drm.dts
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2017 NXP
+ *
+ * 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 "fsl-imx8mq-evk.dts"
+
+&resmem {
+ display_region: imx_ion@1 {
+ compatible = "imx-ion-pool";
+ reg = <0x0 0xe6000000 0 0x18000000>;
+ };
+
+ vpu_region: imx_ion@2 {
+ compatible = "imx-ion-pool";
+ reg = <0x0 0xe4000000 0 0x02000000>;
+ };
+};
+
+&imx_ion {
+ compatible = "fsl,mxc-ion", "linux,ion";
+
+ ion-display-region {
+ compatible = "fsl,display-heap", "linux,ion-heap-unmapped";
+ memory-region = <&display_region>;
+ };
+
+ ion-vpu-region {
+ compatible = "fsl,vpu-heap", "linux,ion-heap-unmapped";
+ memory-region = <&vpu_region>;
+ };
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8mq-evk-dual-display-b3.dts b/arch/arm64/boot/dts/freescale/fsl-imx8mq-evk-dual-display-b3.dts
new file mode 100644
index 000000000000..b0c7df737dd9
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8mq-evk-dual-display-b3.dts
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2018 NXP
+ *
+ * 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 "fsl-imx8mq-evk-lcdif-adv7535-b3.dts"
+
+/ {
+ display-subsystem {
+ status = "okay";
+ };
+
+ sound-hdmi {
+ status = "okay";
+ };
+};
+
+&irqsteer_dcss {
+ status = "okay";
+};
+
+&dcss {
+ status = "okay";
+};
+
+&hdmi {
+ status = "okay";
+};
+
+&lcdif {
+ status = "okay";
+ max-res = <1280>, <720>;
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8mq-evk-dual-display.dts b/arch/arm64/boot/dts/freescale/fsl-imx8mq-evk-dual-display.dts
new file mode 100644
index 000000000000..21616e6c8619
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8mq-evk-dual-display.dts
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2017 NXP
+ *
+ * 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 "fsl-imx8mq-evk-lcdif-adv7535.dts"
+
+/ {
+ display-subsystem {
+ status = "okay";
+ };
+
+ sound-hdmi {
+ status = "okay";
+ };
+};
+
+&irqsteer_dcss {
+ status = "okay";
+};
+
+&dcss {
+ status = "okay";
+};
+
+&hdmi {
+ status = "okay";
+};
+
+&lcdif {
+ status = "okay";
+ max-res = <1280>, <720>;
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8mq-evk-edp.dts b/arch/arm64/boot/dts/freescale/fsl-imx8mq-evk-edp.dts
new file mode 100644
index 000000000000..5f8ea76166bb
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8mq-evk-edp.dts
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2017 NXP
+ *
+ * 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 "fsl-imx8mq-evk.dts"
+
+&hdmi {
+ compatible = "fsl,imx8mq-dp";
+ lane_mapping = <0xc6>;
+ fsl,edp;
+ edp_link_rate = <0x6>;
+ edp_num_lanes = <0x4>;
+ status = "okay";
+};
+
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8mq-evk-inmate.dts b/arch/arm64/boot/dts/freescale/fsl-imx8mq-evk-inmate.dts
new file mode 100644
index 000000000000..135a90498fa7
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8mq-evk-inmate.dts
@@ -0,0 +1,207 @@
+/*
+ * Copyright 2018 NXP
+ *
+ * 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.
+ */
+
+/dts-v1/;
+
+#include "fsl-imx8mq.dtsi"
+
+/ {
+ model = "Freescale i.MX8MQ EVK";
+ compatible = "fsl,imx8mq-evk", "fsl,imx8mq";
+ interrupt-parent = <&gic>;
+
+ timer {
+ compatible = "arm,armv8-timer";
+ interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>, /* Physical Secure */
+ <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>, /* Physical Non-Secure */
+ <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>, /* Virtual */
+ <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>; /* Hypervisor */
+ clock-frequency = <8333333>;
+ };
+
+ clocks {
+ clk_dummy: clock@7 {
+ compatible = "fixed-clock";
+ reg = <7>;
+ #clock-cells = <0>;
+ clock-frequency = <0>;
+ clock-output-names = "clk_dummy";
+ };
+
+ /* The clocks are configured by 1st OS */
+ clk_400m: clock@8 {
+ compatible = "fixed-clock";
+ reg = <8>;
+ #clock-cells = <0>;
+ clock-frequency = <400000000>;
+ clock-output-names = "400m";
+ };
+ clk_266m: clock@9 {
+ compatible = "fixed-clock";
+ reg = <9>;
+ #clock-cells = <0>;
+ clock-frequency = <266000000>;
+ clock-output-names = "266m";
+ };
+ clk_80m: clock@10 {
+ compatible = "fixed-clock";
+ reg = <10>;
+ #clock-cells = <0>;
+ clock-frequency = <80000000>;
+ clock-output-names = "80m";
+ };
+ };
+
+ display-subsystem {
+ /delete-property/ compatible;
+ };
+
+ pci@bfb00000 {
+ compatible = "pci-host-ecam-generic";
+ device_type = "pci";
+ bus-range = <0 0>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ #interrupt-cells = <1>;
+ interrupt-map-mask = <0 0 0 7>;
+ interrupt-map = <0 0 0 1 &gic GIC_SPI 109 IRQ_TYPE_EDGE_RISING>;
+ reg = <0x0 0xbfb00000 0x0 0x100000>;
+ ranges = <0x02000000 0x00 0x10000000 0x0 0x10000000 0x00 0x10000>;
+ };
+};
+
+/delete-node/ &{/memory@40000000};
+
+&clk {
+ /delete-property/ compatible;
+};
+
+/delete-node/ &{/cpus/cpu@0};
+/delete-node/ &{/cpus/cpu@1};
+/delete-node/ &{/pmu};
+
+/delete-node/ &{/busfreq};
+
+/delete-node/ &resmem;
+
+&mipi_pd {
+ status = "disabled";
+};
+
+&pcie0_pd {
+ status = "disabled";
+};
+
+&usb_otg1_pd {
+ status = "disabled";
+};
+
+&usb_otg2_pd {
+ status = "disabled";
+};
+
+&gpu_pd {
+ status = "disabled";
+};
+
+&vpu_pd {
+ status = "disabled";
+};
+
+&mipi_csi1_pd {
+ status = "disabled";
+};
+
+&mipi_csi2_pd {
+ status = "disabled";
+};
+
+&pcie1_pd {
+ status = "disabled";
+};
+
+&gpio1 {
+ status = "disabled";
+};
+&gpio2 {
+ status = "disabled";
+};
+&gpio3 {
+ status = "disabled";
+};
+&gpio4 {
+ status = "disabled";
+};
+&gpio5 {
+ status = "disabled";
+};
+
+/delete-node/ &tmu;
+/delete-node/ &{/thermal-zones};
+
+/delete-node/ &irqsteer_dcss;
+/delete-node/ &ocotp;
+/delete-node/ &snvs;
+
+&src {
+ /delete-property/ compatible;
+};
+
+&dcss {
+ /delete-property/ interrupt-parent;
+};
+
+/delete-node/ &gpc;
+/delete-node/ &system_counter;
+/delete-node/ &imx_ion;
+/delete-node/ &pcie0;
+/delete-node/ &pcie1;
+/delete-node/ &vpu;
+/delete-node/ &ddr_pmu0;
+/delete-node/ &imx_rpmsg;
+/delete-node/ &crypto;
+/delete-node/ &caam_sm;
+/delete-node/ &caam_snvs;
+/delete-node/ &irq_sec_vio;
+/delete-node/ &dma_apbh;
+/delete-node/ &gpmi;
+
+&gic {
+ reg = <0x0 0x38800000 0 0x10000>, /* GIC Dist */
+ <0x0 0x38880000 0 0xC0000>; /* GICR (RD_base + SGI_base) */
+};
+
+
+/delete-node/ &iomuxc;
+
+&uart2 {
+ clocks = <&osc_25m>,
+ <&osc_25m>;
+ clock-names = "ipg", "per";
+ /delete-property/ dmas;
+ /delete-property/ dmas-names;
+ status = "okay";
+};
+
+&usdhc1 {
+ clocks = <&clk_dummy>,
+ <&clk_266m>,
+ <&clk_400m>;
+ /delete-property/assigned-clocks;
+ /delete-property/assigned-clock-rates;
+ clock-names = "ipg", "ahb", "per";
+ bus-width = <8>;
+ non-removable;
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8mq-evk-lcdif-adv7535-b3.dts b/arch/arm64/boot/dts/freescale/fsl-imx8mq-evk-lcdif-adv7535-b3.dts
new file mode 100644
index 000000000000..00f881834182
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8mq-evk-lcdif-adv7535-b3.dts
@@ -0,0 +1,16 @@
+/*
+ * Copyright 2018 NXP
+ *
+ * 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 "fsl-imx8mq-evk-b3.dts"
+#include "fsl-imx8mq-evk-lcdif-adv7535.dtsi"
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8mq-evk-lcdif-adv7535.dts b/arch/arm64/boot/dts/freescale/fsl-imx8mq-evk-lcdif-adv7535.dts
new file mode 100644
index 000000000000..e02b6a9f742d
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8mq-evk-lcdif-adv7535.dts
@@ -0,0 +1,16 @@
+/*
+ * Copyright 2017-2018 NXP
+ *
+ * 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 "fsl-imx8mq-evk.dts"
+#include "fsl-imx8mq-evk-lcdif-adv7535.dtsi"
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8mq-evk-lcdif-adv7535.dtsi b/arch/arm64/boot/dts/freescale/fsl-imx8mq-evk-lcdif-adv7535.dtsi
new file mode 100644
index 000000000000..c93885da4d55
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8mq-evk-lcdif-adv7535.dtsi
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2018 NXP
+ *
+ * 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.
+ */
+
+/ {
+ display-subsystem {
+ status = "disabled";
+ };
+
+ sound-hdmi {
+ status = "disabled";
+ };
+};
+
+&irqsteer_dcss {
+ status = "disabled";
+};
+
+&dcss {
+ status = "disabled";
+};
+
+&hdmi {
+ status = "disabled";
+};
+
+&lcdif {
+ status = "okay";
+ max-res = <1280>, <720>;
+
+ port@0 {
+ lcdif_mipi_dsi: mipi-dsi-endpoint {
+ remote-endpoint = <&mipi_dsi_in>;
+ };
+ };
+};
+
+&mipi_dsi_phy {
+ status = "okay";
+};
+
+&mipi_dsi {
+ status = "okay";
+ as_bridge;
+ sync-pol = <1>;
+ pwr-delay = <10>;
+
+ port@1 {
+ mipi_dsi_in: endpoint {
+ remote-endpoint = <&lcdif_mipi_dsi>;
+ };
+ };
+};
+
+&mipi_dsi_bridge {
+ status = "okay";
+};
+
+&adv_bridge {
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8mq-evk-lcdif-rm67191-b3.dts b/arch/arm64/boot/dts/freescale/fsl-imx8mq-evk-lcdif-rm67191-b3.dts
new file mode 100644
index 000000000000..41146082c64f
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8mq-evk-lcdif-rm67191-b3.dts
@@ -0,0 +1,16 @@
+/*
+ * Copyright 2018 NXP
+ *
+ * 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 "fsl-imx8mq-evk-b3.dts"
+#include "fsl-imx8mq-evk-lcdif-rm67191.dtsi"
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8mq-evk-lcdif-rm67191.dts b/arch/arm64/boot/dts/freescale/fsl-imx8mq-evk-lcdif-rm67191.dts
new file mode 100644
index 000000000000..d2c38003b60e
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8mq-evk-lcdif-rm67191.dts
@@ -0,0 +1,16 @@
+/*
+ * Copyright 2017-2018 NXP
+ *
+ * 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 "fsl-imx8mq-evk.dts"
+#include "fsl-imx8mq-evk-lcdif-rm67191.dtsi"
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8mq-evk-lcdif-rm67191.dtsi b/arch/arm64/boot/dts/freescale/fsl-imx8mq-evk-lcdif-rm67191.dtsi
new file mode 100644
index 000000000000..3688aa04cd6d
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8mq-evk-lcdif-rm67191.dtsi
@@ -0,0 +1,101 @@
+/*
+ * Copyright 2018 NXP
+ *
+ * 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.
+ */
+
+/ {
+ display-subsystem {
+ status = "disabled";
+ };
+
+ sound-hdmi {
+ status = "disabled";
+ };
+};
+
+&irqsteer_dcss {
+ status = "disabled";
+};
+
+&dcss {
+ status = "disabled";
+};
+
+&hdmi {
+ status = "disabled";
+};
+
+&lcdif {
+ status = "okay";
+ max-res = <1080>, <1920>;
+
+ port@0 {
+ lcdif_mipi_dsi: mipi-dsi-endpoint {
+ remote-endpoint = <&mipi_dsi_in>;
+ };
+ };
+};
+
+&mipi_dsi_phy {
+ status = "okay";
+};
+
+&mipi_dsi {
+ status = "okay";
+ as_bridge;
+ sync-pol = <1>;
+
+ port@1 {
+ mipi_dsi_in: endpoint {
+ remote-endpoint = <&lcdif_mipi_dsi>;
+ };
+ };
+};
+
+&mipi_dsi_bridge {
+ status = "okay";
+
+ panel@0 {
+ compatible = "raydium,rm67191";
+ reg = <0>;
+ pinctrl-0 = <&pinctrl_mipi_dsi_en>;
+ reset-gpio = <&gpio5 6 GPIO_ACTIVE_HIGH>;
+ dsi-lanes = <4>;
+ panel-width-mm = <68>;
+ panel-height-mm = <121>;
+ port {
+ panel1_in: endpoint {
+ remote-endpoint = <&mipi_dsi_bridge_out>;
+ };
+ };
+ };
+
+ port@2 {
+ mipi_dsi_bridge_out: endpoint {
+ remote-endpoint = <&panel1_in>;
+ };
+ };
+};
+
+&iomuxc {
+ imx8mq-evk {
+ pinctrl_mipi_dsi_en: mipi_dsi_en {
+ fsl,pins = <
+ MX8MQ_IOMUXC_ECSPI1_SCLK_GPIO5_IO6 0x16
+ >;
+ };
+ };
+};
+
+&synaptics_dsx_ts {
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8mq-evk-m4.dts b/arch/arm64/boot/dts/freescale/fsl-imx8mq-evk-m4.dts
new file mode 100644
index 000000000000..c0099e3f431b
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8mq-evk-m4.dts
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2017 NXP
+ *
+ * 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 "fsl-imx8mq-evk.dts"
+
+/ {
+ reserved-memory {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ m4_reserved: m4@0x80000000 {
+ no-map;
+ reg = <0 0x80000000 0 0x1000000>;
+ };
+
+ };
+};
+
+&gpt1 {
+ status = "disabled";
+};
+
+&i2c2 {
+ status = "disabled";
+};
+
+&pwm4 {
+ status = "disabled";
+};
+
+&rpmsg{
+ /*
+ * 64K for one rpmsg instance:
+ * --0xb8000000~0xb800ffff: pingpong
+ */
+ vdev-nums = <1>;
+ reg = <0x0 0xb8000000 0x0 0x10000>;
+ status = "okay";
+};
+
+&tmu {
+ status = "disabled";
+};
+
+&uart2 {
+ status = "disabled";
+};
+
+&wdog3{
+ status = "disabled";
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8mq-evk-mipi-csi2.dts b/arch/arm64/boot/dts/freescale/fsl-imx8mq-evk-mipi-csi2.dts
new file mode 100644
index 000000000000..7e4a672708bb
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8mq-evk-mipi-csi2.dts
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2017 NXP
+ *
+ * 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 "fsl-imx8mq-evk.dts"
+
+&ov5640_mipi {
+ status = "disabled";
+};
+
+&ov5640_mipi2 {
+ status = "okay";
+};
+
+&csi1_bridge {
+ status = "disabled";
+};
+
+&csi2_bridge {
+ status = "okay";
+};
+
+&mipi_csi_1 {
+ status = "disabled";
+};
+&mipi_csi_2 {
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8mq-evk-pcie1-m2.dts b/arch/arm64/boot/dts/freescale/fsl-imx8mq-evk-pcie1-m2.dts
new file mode 100644
index 000000000000..6b0147673ec7
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8mq-evk-pcie1-m2.dts
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2017 NXP
+ *
+ * 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.
+ */
+
+/*
+ * NOTE:
+ * 1. The DTS file only support i.MX8MQ EVK RevB1/B2 board PCIe M.2 Murata
+ * 1CQ (Qca6174) WIFI & BT.
+ * EVK RevB1 rework:
+ * WIFI rework: fly line from R1436 (near to M.2) to R1459
+ * BT rework: ensure R1446,R1447,R1448,R1449 installed on board
+ * EVK RevB2 rework: no rework
+ *
+ * 2. If need to support i.MX8MQ EVK RevA0/A1 board PCIe M.2 Murata 1CQ
+ * (Qca6174) WIFI & BT, some board rework requirement:
+ * EVK RevA0 rework:
+ * WIFI rework: install R1436 for wlreg_on
+ * EVK RevA0 rework:
+ * WIFI rework: install R1436 for wlreg_on
+ * BT rework: fly line from M.2 pin54 to R1437
+ * Also, below DTS change requirement:
+ * / {
+ * regulators {
+ * epdev_on: fixedregulator@100 {
+ * compatible = "regulator-fixed";
+ * regulator-min-microvolt = <3300000>;
+ * regulator-max-microvolt = <3300000>;
+ * regulator-name = "epdev_on";
+ * gpio = <&gpio2 19 GPIO_ACTIVE_HIGH>;
+ * enable-active-high;
+ * };
+ * };
+ * };
+ *
+ * &iomuxc {
+ * imx8mq-evk {
+ * pinctrl_epdev_on: epdevongrp {
+ * fsl,pins = <
+ * MX8MQ_IOMUXC_SD2_RESET_B_GPIO2_IO19 0x16
+ * >;
+ * };
+ * };
+ * };
+ *
+ * &pcie1{
+ * pinctrl-names = "default";
+ * pinctrl-0 = <&pinctrl_pcie1 &pinctrl_epdev_on>;
+ * epdev_on-supply = <&epdev_on>;
+ * };
+ *
+ * &usdhc2 {
+ * status = "disabled";
+ * };
+ *
+ *
+ * 3. When wifi driver switch to QCA CLD from ATH10K, there have two known issues:
+ * - QCA CLD driver only support ONE instance.
+ * - QCA CLD driver don't support PCIe MSI feature.
+ * So here it has to disable pcie0 port.
+ */
+
+#include "fsl-imx8mq-evk.dts"
+
+/ {
+ modem_reset: modem-reset {
+ reset-gpios = <&gpio3 5 GPIO_ACTIVE_HIGH>;
+ };
+};
+
+&pcie0{
+ status = "disabled";
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8mq-evk-pdm.dts b/arch/arm64/boot/dts/freescale/fsl-imx8mq-evk-pdm.dts
new file mode 100644
index 000000000000..24e9c6bd416c
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8mq-evk-pdm.dts
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017 NXP
+ *
+ * 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 "fsl-imx8mq-evk.dts"
+
+/ {
+ sound-pdm {
+ compatible = "fsl,imx-pdm-mic";
+ model = "imx-pdm-audio";
+ audio-cpu = <&sai3>;
+ decimation = <64>;
+ status = "okay";
+ };
+};
+
+&iomuxc {
+ imx8mq-evk {
+ pinctrl_sai3: sai3grp {
+ fsl,pins = <
+ MX8MQ_IOMUXC_SAI3_RXC_SAI3_RX_BCLK 0xd6
+ MX8MQ_IOMUXC_SAI3_RXD_SAI3_RX_DATA0 0xd6
+ >;
+ };
+ };
+};
+
+&sai3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_sai3>;
+ assigned-clocks = <&clk IMX8MQ_CLK_SAI3>;
+ assigned-clock-parents = <&clk IMX8MQ_AUDIO_PLL1_OUT>;
+ assigned-clock-rates = <24576000>;
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8mq-evk-root.dts b/arch/arm64/boot/dts/freescale/fsl-imx8mq-evk-root.dts
new file mode 100644
index 000000000000..5e1d6688b139
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8mq-evk-root.dts
@@ -0,0 +1,110 @@
+/*
+ * Copyright 2018 NXP
+ *
+ * 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 "fsl-imx8mq-evk.dts"
+
+/ {
+ interrupt-parent = <&gic>;
+};
+
+/delete-node/ &gpc;
+
+&CPU_SLEEP {
+ /* We are not using GPC for now, need set 0 to avoid hang */
+ arm,psci-suspend-param = <0x0>;
+};
+
+&clk {
+ init-on-array = <IMX8MQ_CLK_DRAM_CORE IMX8MQ_CLK_AHB
+ IMX8MQ_CLK_NOC IMX8MQ_CLK_NOC_APB
+ IMX8MQ_CLK_USB_BUS
+ IMX8MQ_CLK_MAIN_AXI IMX8MQ_CLK_A53_CG
+ IMX8MQ_CLK_AUDIO_AHB IMX8MQ_CLK_TMU_ROOT
+ IMX8MQ_CLK_DRAM_APB
+ IMX8MQ_CLK_UART2_ROOT
+ IMX8MQ_CLK_UART2
+ IMX8MQ_CLK_NAND_USDHC_BUS>;
+};
+
+&iomuxc {
+ imx8mq-evk {
+ /*
+ * Used for the 2nd Linux.
+ * TODO: M4 may use these pins.
+ */
+ pinctrl_uart2: uart2grp {
+ fsl,pins = <
+ MX8MQ_IOMUXC_UART2_RXD_UART2_DCE_RX 0x49
+ MX8MQ_IOMUXC_UART2_TXD_UART2_DCE_TX 0x49
+ >;
+ };
+ };
+};
+
+&{/busfreq} {
+ /* Disable busfreq, to avoid 1st Linux busfreq crash other inmates */
+ status = "disabled";
+};
+
+&resmem {
+ jh_reserved: jh@0xfdc00000 {
+ no-map;
+ reg = <0 0xfdc00000 0x0 0x400000>;
+ };
+
+ inmate_reserved: inmate@0xc0000000 {
+ no-map;
+ reg = <0 0xc0000000 0x0 0x3dc00000>;
+ };
+
+ loader_reserved: loader@0xbff00000 {
+ no-map;
+ reg = <0 0xbff00000 0x0 0x00100000>;
+ };
+
+ ivshmem_reserved: ivshmem@0xbfe00000 {
+ no-map;
+ reg = <0 0xbfe00000 0x0 0x00100000>;
+ };
+
+ ivshmem2_reserved: ivshmem2@0xbfd00000 {
+ no-map;
+ reg = <0 0xbfd00000 0x0 0x00100000>;
+ };
+
+ pci_reserved: pci@0xbfc00000 {
+ no-map;
+ reg = <0 0xbfb00000 0x0 0x00200000>;
+ };
+};
+
+&uart1 {
+ /* uart2 is used by the 2nd OS, so configure pin and clk */
+ pinctrl-0 = <&pinctrl_uart1>, <&pinctrl_uart2>;
+ assigned-clocks = <&clk IMX8MQ_CLK_UART1>,
+ <&clk IMX8MQ_CLK_UART2>;
+ assigned-clock-parents = <&clk IMX8MQ_CLK_25M>,
+ <&clk IMX8MQ_CLK_25M>;
+};
+
+&usdhc1 {
+ status = "disabled";
+};
+
+&usdhc2 {
+ /* sdhc1 is used by 2nd linux, configure the pin */
+ pinctrl-0 = <&pinctrl_usdhc1>, <&pinctrl_usdhc2>, <&pinctrl_usdhc2_gpio>;
+ pinctrl-1 = <&pinctrl_usdhc1>, <&pinctrl_usdhc2_100mhz>, <&pinctrl_usdhc2_gpio>;
+ pinctrl-2 = <&pinctrl_usdhc1>, <&pinctrl_usdhc2_200mhz>, <&pinctrl_usdhc2_gpio>;
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8mq-evk.dts b/arch/arm64/boot/dts/freescale/fsl-imx8mq-evk.dts
new file mode 100644
index 000000000000..f7079946cc64
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8mq-evk.dts
@@ -0,0 +1,1017 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017 NXP
+ *
+ * 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.
+ */
+
+/dts-v1/;
+
+#include "fsl-imx8mq.dtsi"
+
+/ {
+ model = "Freescale i.MX8MQ EVK";
+ compatible = "fsl,imx8mq-evk", "fsl,imx8mq";
+
+ chosen {
+ bootargs = "console=ttymxc0,115200 earlycon=ec_imx6q,0x30860000,115200";
+ stdout-path = &uart1;
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ reg_usdhc2_vmmc: usdhc2_vmmc {
+ compatible = "regulator-fixed";
+ regulator-name = "VSD_3V3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&gpio2 19 GPIO_ACTIVE_HIGH>;
+ off-on-delay = <20000>;
+ enable-active-high;
+ };
+
+ reg_gpio_dvfs: regulator-gpio {
+ compatible = "regulator-gpio";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_dvfs>;
+ regulator-min-microvolt = <900000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-name = "gpio_dvfs";
+ regulator-type = "voltage";
+ gpios = <&gpio1 13 GPIO_ACTIVE_HIGH>;
+ states = <900000 0x1 1000000 0x0>;
+ };
+ };
+
+ ir_recv: ir-receiver {
+ compatible = "gpio-ir-receiver";
+ gpios = <&gpio1 12 GPIO_ACTIVE_LOW>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ir_recv>;
+ };
+
+ brcmfmac: brcmfmac {
+ compatible = "cypress,brcmfmac";
+ pinctrl-names = "init", "idle", "default";
+ pinctrl-0 = <&pinctrl_wlan_init>;
+ pinctrl-1 = <&pinctrl_wlan_init>;
+ pinctrl-2 = <&pinctrl_wlan>;
+ };
+
+ modem_reset: modem-reset {
+ compatible = "gpio-reset";
+ reset-gpios = <&gpio3 5 GPIO_ACTIVE_LOW>;
+ reset-delay-us = <2000>;
+ reset-post-delay-ms = <40>;
+ #reset-cells = <0>;
+ };
+
+ wm8524: wm8524 {
+ compatible = "wlf,wm8524";
+ clocks = <&clk IMX8MQ_CLK_SAI2_ROOT>;
+ clock-names = "mclk";
+ wlf,mute-gpios = <&gpio1 8 GPIO_ACTIVE_LOW>;
+ };
+
+ sound-wm8524 {
+ compatible = "fsl,imx-audio-wm8524";
+ model = "wm8524-audio";
+ audio-cpu = <&sai2>;
+ audio-codec = <&wm8524>;
+ audio-routing =
+ "Line Out Jack", "LINEVOUTL",
+ "Line Out Jack", "LINEVOUTR";
+ };
+
+ sound-hdmi {
+ compatible = "fsl,imx8mq-evk-cdnhdmi",
+ "fsl,imx-audio-cdnhdmi";
+ model = "imx-audio-hdmi";
+ audio-cpu = <&sai4>;
+ protocol = <1>;
+ hdmi-out;
+ constraint-rate = <44100>,
+ <88200>,
+ <176400>,
+ <32000>,
+ <48000>,
+ <96000>,
+ <192000>;
+ };
+
+ sound-spdif {
+ compatible = "fsl,imx-audio-spdif";
+ model = "imx-spdif";
+ spdif-controller = <&spdif1>;
+ spdif-out;
+ spdif-in;
+ };
+
+ sound-hdmi-arc {
+ compatible = "fsl,imx-audio-spdif";
+ model = "imx-hdmi-arc";
+ spdif-controller = <&spdif2>;
+ spdif-in;
+ };
+
+ sound-ak4458 {
+ compatible = "fsl,imx-audio-ak4458-mq";
+ model = "ak4458-audio";
+ audio-cpu = <&sai1>;
+ audio-codec = <&ak4458_1>, <&ak4458_2>;
+ ak4458,pdn-gpio = <&gpio3 18 GPIO_ACTIVE_HIGH>;
+ };
+
+ sound-ak5558 {
+ compatible = "fsl,imx-audio-ak5558-mq";
+ model = "ak5558-audio";
+ audio-cpu = <&sai5>;
+ audio-codec = <&ak5558>;
+ };
+
+ sound-ak4497 {
+ compatible = "fsl,imx-audio-ak4497-mq";
+ model = "ak4497-audio";
+ audio-cpu = <&sai1>;
+ audio-codec = <&ak4497>;
+ status = "disabled";
+ };
+};
+
+&clk {
+ assigned-clocks = <&clk IMX8MQ_AUDIO_PLL1>, <&clk IMX8MQ_AUDIO_PLL2>;
+ assigned-clock-rates = <786432000>, <722534400>;
+};
+
+&iomuxc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_hog>;
+
+ imx8mq-evk {
+ pinctrl_hog: hoggrp {
+ fsl,pins = <
+ MX8MQ_IOMUXC_NAND_READY_B_GPIO3_IO16 0x19
+ MX8MQ_IOMUXC_NAND_WE_B_GPIO3_IO17 0x19
+ MX8MQ_IOMUXC_NAND_WP_B_GPIO3_IO18 0x19
+ >;
+ };
+
+ pinctrl_ir_recv: ir_recv {
+ fsl,pins = <
+ MX8MQ_IOMUXC_GPIO1_IO12_GPIO1_IO12 0x4f
+ >;
+ };
+
+ pinctrl_csi1_pwn: csi1_pwn_grp {
+ fsl,pins = <
+ MX8MQ_IOMUXC_GPIO1_IO03_GPIO1_IO3 0x19
+ >;
+ };
+ pinctrl_csi2_pwn: csi2_pwn_grp {
+ fsl,pins = <
+ MX8MQ_IOMUXC_GPIO1_IO05_GPIO1_IO5 0x19
+ >;
+ };
+
+ pinctrl_csi_rst: csi_rst_grp {
+ fsl,pins = <
+ MX8MQ_IOMUXC_GPIO1_IO06_GPIO1_IO6 0x19
+ MX8MQ_IOMUXC_GPIO1_IO15_CCMSRCGPCMIX_CLKO2 0x59
+ >;
+ };
+
+ pinctrl_fec1: fec1grp {
+ fsl,pins = <
+ MX8MQ_IOMUXC_ENET_MDC_ENET1_MDC 0x3
+ MX8MQ_IOMUXC_ENET_MDIO_ENET1_MDIO 0x23
+ MX8MQ_IOMUXC_ENET_TD3_ENET1_RGMII_TD3 0x1f
+ MX8MQ_IOMUXC_ENET_TD2_ENET1_RGMII_TD2 0x1f
+ MX8MQ_IOMUXC_ENET_TD1_ENET1_RGMII_TD1 0x1f
+ MX8MQ_IOMUXC_ENET_TD0_ENET1_RGMII_TD0 0x1f
+ MX8MQ_IOMUXC_ENET_RD3_ENET1_RGMII_RD3 0x91
+ MX8MQ_IOMUXC_ENET_RD2_ENET1_RGMII_RD2 0x91
+ MX8MQ_IOMUXC_ENET_RD1_ENET1_RGMII_RD1 0x91
+ MX8MQ_IOMUXC_ENET_RD0_ENET1_RGMII_RD0 0x91
+ MX8MQ_IOMUXC_ENET_TXC_ENET1_RGMII_TXC 0x1f
+ MX8MQ_IOMUXC_ENET_RXC_ENET1_RGMII_RXC 0x91
+ MX8MQ_IOMUXC_ENET_RX_CTL_ENET1_RGMII_RX_CTL 0x91
+ MX8MQ_IOMUXC_ENET_TX_CTL_ENET1_RGMII_TX_CTL 0x1f
+ MX8MQ_IOMUXC_GPIO1_IO09_GPIO1_IO9 0x19
+ >;
+ };
+
+ pinctrl_i2c1: i2c1grp {
+ fsl,pins = <
+ MX8MQ_IOMUXC_I2C1_SCL_I2C1_SCL 0x4000007f
+ MX8MQ_IOMUXC_I2C1_SDA_I2C1_SDA 0x4000007f
+ >;
+ };
+
+ pinctrl_i2c2: i2c2grp {
+ fsl,pins = <
+ MX8MQ_IOMUXC_I2C2_SCL_I2C2_SCL 0x40000067
+ MX8MQ_IOMUXC_I2C2_SDA_I2C2_SDA 0x40000067
+ >;
+ };
+
+ pinctrl_i2c3: i2c3grp {
+ fsl,pins = <
+ MX8MQ_IOMUXC_I2C3_SCL_I2C3_SCL 0x40000067
+ MX8MQ_IOMUXC_I2C3_SDA_I2C3_SDA 0x40000067
+ >;
+ };
+
+ pinctrl_pcie0: pcie0grp {
+ fsl,pins = <
+ MX8MQ_IOMUXC_I2C4_SCL_PCIE1_CLKREQ_B 0x76 /* open drain, pull up */
+ MX8MQ_IOMUXC_UART4_TXD_GPIO5_IO29 0x16
+ MX8MQ_IOMUXC_UART4_RXD_GPIO5_IO28 0x16
+ >;
+ };
+
+ pinctrl_pcie1: pcie1grp {
+ fsl,pins = <
+ MX8MQ_IOMUXC_I2C4_SDA_PCIE2_CLKREQ_B 0x76 /* open drain, pull up */
+ MX8MQ_IOMUXC_ECSPI2_SCLK_GPIO5_IO10 0x16
+ MX8MQ_IOMUXC_ECSPI2_MISO_GPIO5_IO12 0x16
+ >;
+ };
+
+ pinctrl_dvfs: dvfsgrp {
+ fsl,pins = <
+ MX8MQ_IOMUXC_GPIO1_IO13_GPIO1_IO13 0x16
+ >;
+ };
+
+ pinctrl_typec: typecgrp {
+ fsl,pins = <
+ MX8MQ_IOMUXC_NAND_RE_B_GPIO3_IO15 0x16
+ MX8MQ_IOMUXC_NAND_CE2_B_GPIO3_IO3 0x17059
+ >;
+ };
+
+ pinctrl_qspi: qspigrp {
+ fsl,pins = <
+ MX8MQ_IOMUXC_NAND_ALE_QSPI_A_SCLK 0x82
+ MX8MQ_IOMUXC_NAND_CE0_B_QSPI_A_SS0_B 0x82
+ MX8MQ_IOMUXC_NAND_DATA00_QSPI_A_DATA0 0x82
+ MX8MQ_IOMUXC_NAND_DATA01_QSPI_A_DATA1 0x82
+ MX8MQ_IOMUXC_NAND_DATA02_QSPI_A_DATA2 0x82
+ MX8MQ_IOMUXC_NAND_DATA03_QSPI_A_DATA3 0x82
+
+ >;
+ };
+
+ pinctrl_uart1: uart1grp {
+ fsl,pins = <
+ MX8MQ_IOMUXC_UART1_RXD_UART1_DCE_RX 0x49
+ MX8MQ_IOMUXC_UART1_TXD_UART1_DCE_TX 0x49
+ >;
+ };
+
+ pinctrl_uart3: uart3grp {
+ fsl,pins = <
+ MX8MQ_IOMUXC_UART3_TXD_UART3_DCE_TX 0x49
+ MX8MQ_IOMUXC_UART3_RXD_UART3_DCE_RX 0x49
+ MX8MQ_IOMUXC_ECSPI1_MISO_UART3_DCE_CTS_B 0x49
+ MX8MQ_IOMUXC_ECSPI1_SS0_UART3_DCE_RTS_B 0x49
+ MX8MQ_IOMUXC_NAND_CLE_GPIO3_IO5 0x19
+ >;
+ };
+
+ pinctrl_usdhc1: usdhc1grp {
+ fsl,pins = <
+ MX8MQ_IOMUXC_SD1_CLK_USDHC1_CLK 0x83
+ MX8MQ_IOMUXC_SD1_CMD_USDHC1_CMD 0xc3
+ MX8MQ_IOMUXC_SD1_DATA0_USDHC1_DATA0 0xc3
+ MX8MQ_IOMUXC_SD1_DATA1_USDHC1_DATA1 0xc3
+ MX8MQ_IOMUXC_SD1_DATA2_USDHC1_DATA2 0xc3
+ MX8MQ_IOMUXC_SD1_DATA3_USDHC1_DATA3 0xc3
+ MX8MQ_IOMUXC_SD1_DATA4_USDHC1_DATA4 0xc3
+ MX8MQ_IOMUXC_SD1_DATA5_USDHC1_DATA5 0xc3
+ MX8MQ_IOMUXC_SD1_DATA6_USDHC1_DATA6 0xc3
+ MX8MQ_IOMUXC_SD1_DATA7_USDHC1_DATA7 0xc3
+ MX8MQ_IOMUXC_SD1_STROBE_USDHC1_STROBE 0x83
+ MX8MQ_IOMUXC_SD1_RESET_B_USDHC1_RESET_B 0xc1
+ >;
+ };
+
+ pinctrl_usdhc1_100mhz: usdhc1grp100mhz {
+ fsl,pins = <
+ MX8MQ_IOMUXC_SD1_CLK_USDHC1_CLK 0x8d
+ MX8MQ_IOMUXC_SD1_CMD_USDHC1_CMD 0xcd
+ MX8MQ_IOMUXC_SD1_DATA0_USDHC1_DATA0 0xcd
+ MX8MQ_IOMUXC_SD1_DATA1_USDHC1_DATA1 0xcd
+ MX8MQ_IOMUXC_SD1_DATA2_USDHC1_DATA2 0xcd
+ MX8MQ_IOMUXC_SD1_DATA3_USDHC1_DATA3 0xcd
+ MX8MQ_IOMUXC_SD1_DATA4_USDHC1_DATA4 0xcd
+ MX8MQ_IOMUXC_SD1_DATA5_USDHC1_DATA5 0xcd
+ MX8MQ_IOMUXC_SD1_DATA6_USDHC1_DATA6 0xcd
+ MX8MQ_IOMUXC_SD1_DATA7_USDHC1_DATA7 0xcd
+ MX8MQ_IOMUXC_SD1_STROBE_USDHC1_STROBE 0x8d
+ MX8MQ_IOMUXC_SD1_RESET_B_USDHC1_RESET_B 0xc1
+ >;
+ };
+
+ pinctrl_usdhc1_200mhz: usdhc1grp200mhz {
+ fsl,pins = <
+ MX8MQ_IOMUXC_SD1_CLK_USDHC1_CLK 0x9f
+ MX8MQ_IOMUXC_SD1_CMD_USDHC1_CMD 0xdf
+ MX8MQ_IOMUXC_SD1_DATA0_USDHC1_DATA0 0xdf
+ MX8MQ_IOMUXC_SD1_DATA1_USDHC1_DATA1 0xdf
+ MX8MQ_IOMUXC_SD1_DATA2_USDHC1_DATA2 0xdf
+ MX8MQ_IOMUXC_SD1_DATA3_USDHC1_DATA3 0xdf
+ MX8MQ_IOMUXC_SD1_DATA4_USDHC1_DATA4 0xdf
+ MX8MQ_IOMUXC_SD1_DATA5_USDHC1_DATA5 0xdf
+ MX8MQ_IOMUXC_SD1_DATA6_USDHC1_DATA6 0xdf
+ MX8MQ_IOMUXC_SD1_DATA7_USDHC1_DATA7 0xdf
+ MX8MQ_IOMUXC_SD1_STROBE_USDHC1_STROBE 0x9f
+ MX8MQ_IOMUXC_SD1_RESET_B_USDHC1_RESET_B 0xc1
+ >;
+ };
+
+ pinctrl_usdhc2_gpio: usdhc2grpgpio {
+ fsl,pins = <
+ MX8MQ_IOMUXC_SD2_CD_B_GPIO2_IO12 0x41
+ MX8MQ_IOMUXC_SD2_RESET_B_GPIO2_IO19 0x41
+ >;
+ };
+
+ pinctrl_usdhc2: usdhc2grp {
+ fsl,pins = <
+ MX8MQ_IOMUXC_SD2_CLK_USDHC2_CLK 0x83
+ MX8MQ_IOMUXC_SD2_CMD_USDHC2_CMD 0xc3
+ MX8MQ_IOMUXC_SD2_DATA0_USDHC2_DATA0 0xc3
+ MX8MQ_IOMUXC_SD2_DATA1_USDHC2_DATA1 0xc3
+ MX8MQ_IOMUXC_SD2_DATA2_USDHC2_DATA2 0xc3
+ MX8MQ_IOMUXC_SD2_DATA3_USDHC2_DATA3 0xc3
+ MX8MQ_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0xc1
+ >;
+ };
+
+ pinctrl_usdhc2_100mhz: usdhc2grp100mhz {
+ fsl,pins = <
+ MX8MQ_IOMUXC_SD2_CLK_USDHC2_CLK 0x8d
+ MX8MQ_IOMUXC_SD2_CMD_USDHC2_CMD 0xcd
+ MX8MQ_IOMUXC_SD2_DATA0_USDHC2_DATA0 0xcd
+ MX8MQ_IOMUXC_SD2_DATA1_USDHC2_DATA1 0xcd
+ MX8MQ_IOMUXC_SD2_DATA2_USDHC2_DATA2 0xcd
+ MX8MQ_IOMUXC_SD2_DATA3_USDHC2_DATA3 0xcd
+ MX8MQ_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0xc1
+ >;
+ };
+
+ pinctrl_usdhc2_200mhz: usdhc2grp200mhz {
+ fsl,pins = <
+ MX8MQ_IOMUXC_SD2_CLK_USDHC2_CLK 0x9f
+ MX8MQ_IOMUXC_SD2_CMD_USDHC2_CMD 0xdf
+ MX8MQ_IOMUXC_SD2_DATA0_USDHC2_DATA0 0xdf
+ MX8MQ_IOMUXC_SD2_DATA1_USDHC2_DATA1 0xdf
+ MX8MQ_IOMUXC_SD2_DATA2_USDHC2_DATA2 0xdf
+ MX8MQ_IOMUXC_SD2_DATA3_USDHC2_DATA3 0xdf
+ MX8MQ_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0xc1
+ >;
+ };
+
+ pinctrl_sai1_pcm: sai1grp_pcm {
+ fsl,pins = <
+ MX8MQ_IOMUXC_SAI1_MCLK_SAI1_MCLK 0xd6
+ MX8MQ_IOMUXC_SAI1_TXFS_SAI1_TX_SYNC 0xd6
+ MX8MQ_IOMUXC_SAI1_RXD7_SAI1_TX_SYNC 0xd6
+ MX8MQ_IOMUXC_SAI1_TXC_SAI1_TX_BCLK 0xd6
+ MX8MQ_IOMUXC_SAI1_TXD0_SAI1_TX_DATA0 0xd6
+ MX8MQ_IOMUXC_SAI1_TXD1_SAI1_TX_DATA1 0xd6
+ MX8MQ_IOMUXC_SAI1_TXD2_SAI1_TX_DATA2 0xd6
+ MX8MQ_IOMUXC_SAI1_TXD3_SAI1_TX_DATA3 0xd6
+ MX8MQ_IOMUXC_SAI1_TXD4_SAI1_TX_DATA4 0xd6
+ MX8MQ_IOMUXC_SAI1_TXD5_SAI1_TX_DATA5 0xd6
+ MX8MQ_IOMUXC_SAI1_TXD6_SAI1_TX_DATA6 0xd6
+ MX8MQ_IOMUXC_SAI1_TXD7_SAI1_TX_DATA7 0xd6
+ >;
+ };
+
+ pinctrl_sai1_pcm_b2m: sai1grp_pcm_b2m {
+ fsl,pins = <
+ MX8MQ_IOMUXC_SAI1_MCLK_SAI1_TX_BCLK 0xd6
+ MX8MQ_IOMUXC_SAI1_TXFS_SAI1_TX_SYNC 0xd6
+ MX8MQ_IOMUXC_SAI1_RXD7_SAI1_TX_SYNC 0xd6
+ MX8MQ_IOMUXC_SAI1_TXC_SAI1_TX_BCLK 0xd6
+ MX8MQ_IOMUXC_SAI1_TXD0_SAI1_TX_DATA0 0xd6
+ MX8MQ_IOMUXC_SAI1_TXD1_SAI1_TX_DATA1 0xd6
+ MX8MQ_IOMUXC_SAI1_TXD2_SAI1_TX_DATA2 0xd6
+ MX8MQ_IOMUXC_SAI1_TXD3_SAI1_TX_DATA3 0xd6
+ MX8MQ_IOMUXC_SAI1_TXD4_SAI1_TX_DATA4 0xd6
+ MX8MQ_IOMUXC_SAI1_TXD5_SAI1_TX_DATA5 0xd6
+ MX8MQ_IOMUXC_SAI1_TXD6_SAI1_TX_DATA6 0xd6
+ MX8MQ_IOMUXC_SAI1_TXD7_SAI1_TX_DATA7 0xd6
+ >;
+ };
+
+ pinctrl_sai1_dsd: sai1grp_dsd {
+ fsl,pins = <
+ MX8MQ_IOMUXC_SAI1_MCLK_SAI1_MCLK 0xd6
+ MX8MQ_IOMUXC_SAI1_TXFS_SAI1_TX_SYNC 0xd6
+ MX8MQ_IOMUXC_SAI1_RXD7_SAI1_TX_DATA4 0xd6
+ MX8MQ_IOMUXC_SAI1_TXC_SAI1_TX_BCLK 0xd6
+ MX8MQ_IOMUXC_SAI1_TXD0_SAI1_TX_DATA0 0xd6
+ MX8MQ_IOMUXC_SAI1_TXD1_SAI1_TX_DATA1 0xd6
+ MX8MQ_IOMUXC_SAI1_TXD2_SAI1_TX_DATA2 0xd6
+ MX8MQ_IOMUXC_SAI1_TXD3_SAI1_TX_DATA3 0xd6
+ MX8MQ_IOMUXC_SAI1_TXD4_SAI1_TX_DATA4 0xd6
+ MX8MQ_IOMUXC_SAI1_TXD5_SAI1_TX_DATA5 0xd6
+ MX8MQ_IOMUXC_SAI1_TXD6_SAI1_TX_DATA6 0xd6
+ MX8MQ_IOMUXC_SAI1_TXD7_SAI1_TX_DATA7 0xd6
+ >;
+ };
+
+ pinctrl_sai2: sai2grp {
+ fsl,pins = <
+ MX8MQ_IOMUXC_SAI2_TXFS_SAI2_TX_SYNC 0xd6
+ MX8MQ_IOMUXC_SAI2_TXC_SAI2_TX_BCLK 0xd6
+ MX8MQ_IOMUXC_SAI2_MCLK_SAI2_MCLK 0xd6
+ MX8MQ_IOMUXC_SAI2_TXD0_SAI2_TX_DATA0 0xd6
+ MX8MQ_IOMUXC_GPIO1_IO08_GPIO1_IO8 0xd6
+ >;
+ };
+
+ pinctrl_sai5: sai5grp {
+ fsl,pins = <
+ MX8MQ_IOMUXC_SAI5_MCLK_SAI5_MCLK 0xd6
+ MX8MQ_IOMUXC_SAI5_RXC_SAI5_RX_BCLK 0xd6
+ MX8MQ_IOMUXC_SAI5_RXFS_SAI5_RX_SYNC 0xd6
+ MX8MQ_IOMUXC_SAI5_RXD0_SAI5_RX_DATA0 0xd6
+ MX8MQ_IOMUXC_SAI5_RXD1_SAI5_RX_DATA1 0xd6
+ MX8MQ_IOMUXC_SAI5_RXD2_SAI5_RX_DATA2 0xd6
+ MX8MQ_IOMUXC_SAI5_RXD3_SAI5_RX_DATA3 0xd6
+ >;
+ };
+
+ pinctrl_spdif1: spdif1grp {
+ fsl,pins = <
+ MX8MQ_IOMUXC_SPDIF_TX_SPDIF1_OUT 0xd6
+ MX8MQ_IOMUXC_SPDIF_RX_SPDIF1_IN 0xd6
+ >;
+ };
+
+ pinctrl_wdog: wdoggrp {
+ fsl,pins = <
+ MX8MQ_IOMUXC_GPIO1_IO02_WDOG1_WDOG_B 0xc6
+ >;
+ };
+
+ pinctrl_wlan: wlangrp {
+ fsl,pins = <
+ MX8MQ_IOMUXC_GPIO1_IO00_ANAMIX_REF_CLK_32K 0x16
+ >;
+ };
+
+ pinctrl_wlan_init: wlan_initgrp {
+ fsl,pins = <
+ MX8MQ_IOMUXC_GPIO1_IO00_GPIO1_IO0 0x16
+ >;
+ };
+
+ pinctrl_i2c1_dsi_ts_int: dsi_ts_int {
+ fsl,pins = <
+ MX8MQ_IOMUXC_ECSPI1_MOSI_GPIO5_IO7 0x19
+ >;
+ };
+ };
+};
+
+&fec1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_fec1>;
+ phy-mode = "rgmii-id";
+ phy-handle = <&ethphy0>;
+ fsl,magic-packet;
+ status = "okay";
+
+ mdio {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ethphy0: ethernet-phy@0 {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <0>;
+ at803x,led-act-blind-workaround;
+ at803x,eee-disabled;
+ };
+ };
+};
+
+&i2c1 {
+ clock-frequency = <400000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c1>;
+ status = "okay";
+
+ pmic: pfuze100@08 {
+ compatible = "fsl,pfuze100";
+ reg = <0x08>;
+
+ regulators {
+ sw1a_reg: sw1ab {
+ regulator-min-microvolt = <300000>;
+ regulator-max-microvolt = <1875000>;
+ };
+
+ sw1c_reg: sw1c {
+ regulator-min-microvolt = <300000>;
+ regulator-max-microvolt = <1875000>;
+ };
+
+ sw2_reg: sw2 {
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ sw3a_reg: sw3ab {
+ regulator-min-microvolt = <400000>;
+ regulator-max-microvolt = <1975000>;
+ regulator-always-on;
+ };
+
+ sw4_reg: sw4 {
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ swbst_reg: swbst {
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5150000>;
+ };
+
+ snvs_reg: vsnvs {
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-always-on;
+ };
+
+ vref_reg: vrefddr {
+ regulator-always-on;
+ };
+
+ vgen1_reg: vgen1 {
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1550000>;
+ };
+
+ vgen2_reg: vgen2 {
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1550000>;
+ regulator-always-on;
+ };
+
+ vgen3_reg: vgen3 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ vgen4_reg: vgen4 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ vgen5_reg: vgen5 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ vgen6_reg: vgen6 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ };
+ };
+ };
+
+ typec_ptn5100: ptn5110@50 {
+ compatible = "usb,tcpci";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_typec>;
+ reg = <0x50>;
+ interrupt-parent = <&gpio3>;
+ interrupts = <3 8>;
+ ss-sel-gpios = <&gpio3 15 GPIO_ACTIVE_HIGH>;
+ src-pdos = <0x380190c8>;
+ snk-pdos = <0x380190c8 0x3802d0c8>;
+ max-snk-mv = <9000>;
+ max-snk-ma = <2000>;
+ op-snk-mw = <9000>;
+ max-snk-mw = <18000>;
+ port-type = "drp";
+ default-role = "sink";
+ };
+
+ ov5640_mipi2: ov5640_mipi2@3c {
+ compatible = "ovti,ov5640_mipi";
+ reg = <0x3c>;
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_csi2_pwn>, <&pinctrl_csi_rst>;
+ clocks = <&clk IMX8MQ_CLK_CLKO2>;
+ clock-names = "csi_mclk";
+ assigned-clocks = <&clk IMX8MQ_CLK_CLKO2>;
+ assigned-clock-parents = <&clk IMX8MQ_SYS2_PLL_200M>;
+ assigned-clock-rates = <20000000>;
+ csi_id = <1>;
+ pwn-gpios = <&gpio1 5 GPIO_ACTIVE_HIGH>;
+ mclk = <20000000>;
+ mclk_source = <0>;
+ port {
+ ov5640_mipi2_ep: endpoint {
+ remote-endpoint = <&mipi2_sensor_ep>;
+ };
+ };
+ };
+
+};
+
+&i2c2 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c2>;
+ status = "okay";
+
+ ov5640_mipi: ov5640_mipi@3c {
+ compatible = "ovti,ov5640_mipi";
+ reg = <0x3c>;
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_csi1_pwn>;
+ clocks = <&clk IMX8MQ_CLK_CLKO2>;
+ clock-names = "csi_mclk";
+ assigned-clocks = <&clk IMX8MQ_CLK_CLKO2>;
+ assigned-clock-parents = <&clk IMX8MQ_SYS2_PLL_200M>;
+ assigned-clock-rates = <20000000>;
+ csi_id = <0>;
+ pwn-gpios = <&gpio1 3 GPIO_ACTIVE_HIGH>;
+ mclk = <20000000>;
+ mclk_source = <0>;
+ port {
+ ov5640_mipi1_ep: endpoint {
+ remote-endpoint = <&mipi1_sensor_ep>;
+ };
+ };
+ };
+};
+
+&i2c3 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c3>;
+ status = "okay";
+
+ ak4458_1: ak4458@10 {
+ compatible = "asahi-kasei,ak4458";
+ reg = <0x10>;
+ };
+
+ ak4458_2: ak4458@12 {
+ compatible = "asahi-kasei,ak4458";
+ reg = <0x12>;
+ };
+
+ ak5558: ak5558@13 {
+ compatible = "asahi-kasei,ak5558";
+ reg = <0x13>;
+ ak5558,pdn-gpio = <&gpio3 17 GPIO_ACTIVE_HIGH>;
+ };
+
+ ak4497: ak4497@11 {
+ compatible = "asahi-kasei,ak4497";
+ reg = <0x11>;
+ ak4497,pdn-gpio = <&gpio3 16 GPIO_ACTIVE_HIGH>;
+ };
+
+ synaptics_dsx_ts: synaptics_dsx_ts@20 {
+ compatible = "synaptics_dsx";
+ reg = <0x20>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c1_dsi_ts_int>;
+ interrupt-parent = <&gpio5>;
+ interrupts = <7 IRQ_TYPE_LEVEL_LOW>;
+ synaptics,diagonal-rotation;
+ status = "disabled";
+ };
+
+ adv_bridge: adv7535@3d {
+ compatible = "adi,adv7533";
+ reg = <0x3d>;
+ adi,addr-cec = <0x3b>;
+ adi,dsi-lanes = <4>;
+ pinctrl-0 = <&pinctrl_i2c1_dsi_ts_int>;
+ interrupt-parent = <&gpio5>;
+ interrupts = <7 IRQ_TYPE_LEVEL_LOW>;
+
+ status = "disabled";
+
+ port {
+ adv7535_in: endpoint {
+ remote-endpoint = <&mipi_dsi_bridge_adv>;
+ };
+ };
+ };
+};
+
+&pcie0{
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pcie0>;
+ disable-gpio = <&gpio5 29 GPIO_ACTIVE_LOW>;
+ reset-gpio = <&gpio5 28 GPIO_ACTIVE_LOW>;
+ ext_osc = <1>;
+ hard-wired = <1>;
+ status = "okay";
+};
+
+&pcie1{
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pcie1>;
+ disable-gpio = <&gpio5 10 GPIO_ACTIVE_LOW>;
+ reset-gpio = <&gpio5 12 GPIO_ACTIVE_LOW>;
+ ext_osc = <1>;
+ status = "okay";
+};
+
+&uart1 { /* console */
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart1>;
+ assigned-clocks = <&clk IMX8MQ_CLK_UART1>;
+ assigned-clock-parents = <&clk IMX8MQ_CLK_25M>;
+ status = "okay";
+};
+
+&qspi {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_qspi>;
+ status = "okay";
+
+ flash0: n25q256a@0 {
+ reg = <0>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "micron,n25q256a";
+ spi-max-frequency = <29000000>;
+ spi-nor,ddr-quad-read-dummy = <6>;
+ };
+};
+
+&uart3 { /* BT */
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart3>;
+ assigned-clocks = <&clk IMX8MQ_CLK_UART3>;
+ assigned-clock-parents = <&clk IMX8MQ_SYS1_PLL_80M>;
+ fsl,uart-has-rtscts;
+ resets = <&modem_reset>;
+ status = "okay";
+};
+
+&usdhc1 {
+ pinctrl-names = "default", "state_100mhz", "state_200mhz";
+ pinctrl-0 = <&pinctrl_usdhc1>;
+ pinctrl-1 = <&pinctrl_usdhc1_100mhz>;
+ pinctrl-2 = <&pinctrl_usdhc1_200mhz>;
+ bus-width = <8>;
+ non-removable;
+ status = "okay";
+};
+
+&usdhc2 {
+ pinctrl-names = "default", "state_100mhz", "state_200mhz";
+ pinctrl-0 = <&pinctrl_usdhc2>, <&pinctrl_usdhc2_gpio>;
+ pinctrl-1 = <&pinctrl_usdhc2_100mhz>, <&pinctrl_usdhc2_gpio>;
+ pinctrl-2 = <&pinctrl_usdhc2_200mhz>, <&pinctrl_usdhc2_gpio>;
+ bus-width = <4>;
+ cd-gpios = <&gpio2 12 GPIO_ACTIVE_LOW>;
+ vmmc-supply = <&reg_usdhc2_vmmc>;
+ status = "okay";
+};
+
+&usb3_phy0 {
+ status = "okay";
+};
+
+&usb3_0 {
+ status = "okay";
+};
+
+&usb_dwc3_0 {
+ status = "okay";
+ extcon = <&typec_ptn5100>;
+ dr_mode = "otg";
+ hnp-disable;
+ srp-disable;
+ adp-disable;
+};
+
+&usb3_phy1 {
+ status = "okay";
+};
+
+&usb3_1 {
+ status = "okay";
+};
+
+&usb_dwc3_1 {
+ status = "okay";
+ dr_mode = "host";
+};
+
+&sai1 {
+ pinctrl-names = "default", "pcm_b2m", "dsd";
+ pinctrl-0 = <&pinctrl_sai1_pcm>;
+ pinctrl-1 = <&pinctrl_sai1_pcm_b2m>;
+ pinctrl-2 = <&pinctrl_sai1_dsd>;
+ assigned-clocks = <&clk IMX8MQ_CLK_SAI1>;
+ assigned-clock-parents = <&clk IMX8MQ_AUDIO_PLL1_OUT>;
+ assigned-clock-rates = <49152000>;
+ clocks = <&clk IMX8MQ_CLK_SAI1_IPG>, <&clk IMX8MQ_CLK_DUMMY>,
+ <&clk IMX8MQ_CLK_SAI1_ROOT>, <&clk IMX8MQ_CLK_DUMMY>,
+ <&clk IMX8MQ_CLK_DUMMY>, <&clk IMX8MQ_AUDIO_PLL1_OUT>,
+ <&clk IMX8MQ_AUDIO_PLL2_OUT>;
+ clock-names = "bus", "mclk0", "mclk1", "mclk2", "mclk3", "pll8k", "pll11k";
+ fsl,sai-multi-lane;
+ fsl,dataline,dsd = <0 0xff 0xff 2 0xff 0x11>;
+ dmas = <&sdma2 8 26 0>, <&sdma2 9 26 0>;
+ status = "okay";
+};
+
+&sai2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_sai2>;
+ assigned-clocks = <&clk IMX8MQ_CLK_SAI2>;
+ assigned-clock-parents = <&clk IMX8MQ_AUDIO_PLL1_OUT>;
+ assigned-clock-rates = <24576000>;
+ status = "okay";
+};
+
+&sai4 {
+ assigned-clocks = <&clk IMX8MQ_CLK_SAI4>;
+ assigned-clock-parents = <&clk IMX8MQ_AUDIO_PLL1_OUT>;
+ assigned-clock-rates = <24576000>;
+ clocks = <&clk IMX8MQ_CLK_SAI4_IPG>, <&clk IMX8MQ_CLK_DUMMY>,
+ <&clk IMX8MQ_CLK_SAI4_ROOT>, <&clk IMX8MQ_CLK_DUMMY>,
+ <&clk IMX8MQ_CLK_DUMMY>, <&clk IMX8MQ_AUDIO_PLL1_OUT>,
+ <&clk IMX8MQ_AUDIO_PLL2_OUT>;
+ clock-names = "bus", "mclk0", "mclk1", "mclk2", "mclk3", "pll8k", "pll11k";
+ status = "okay";
+};
+
+&sai5 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_sai5>;
+ assigned-clocks = <&clk IMX8MQ_CLK_SAI5>;
+ assigned-clock-parents = <&clk IMX8MQ_AUDIO_PLL1_OUT>;
+ assigned-clock-rates = <49152000>;
+ clocks = <&clk IMX8MQ_CLK_SAI5_IPG>, <&clk IMX8MQ_CLK_DUMMY>,
+ <&clk IMX8MQ_CLK_SAI5_ROOT>, <&clk IMX8MQ_CLK_DUMMY>,
+ <&clk IMX8MQ_CLK_DUMMY>, <&clk IMX8MQ_AUDIO_PLL1_OUT>,
+ <&clk IMX8MQ_AUDIO_PLL2_OUT>;
+ clock-names = "bus", "mclk0", "mclk1", "mclk2", "mclk3", "pll8k", "pll11k";
+ fsl,sai-asynchronous;
+ status = "okay";
+};
+
+&spdif1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_spdif1>;
+ assigned-clocks = <&clk IMX8MQ_CLK_SPDIF1>;
+ assigned-clock-parents = <&clk IMX8MQ_AUDIO_PLL1_OUT>;
+ assigned-clock-rates = <24576000>;
+ status = "okay";
+};
+
+&spdif2 {
+ assigned-clocks = <&clk IMX8MQ_CLK_SPDIF2>;
+ assigned-clock-parents = <&clk IMX8MQ_AUDIO_PLL1_OUT>;
+ assigned-clock-rates = <24576000>;
+ status = "okay";
+};
+
+&gpu_pd {
+ power-supply = <&sw1a_reg>;
+};
+
+&vpu_pd {
+ power-supply = <&sw1c_reg>;
+};
+
+&gpu {
+ status = "okay";
+};
+
+&vpu {
+ status = "okay";
+};
+
+&wdog1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_wdog>;
+ fsl,ext-reset-output;
+ status = "okay";
+};
+
+&mu {
+ status = "okay";
+};
+
+&A53_0 {
+ operating-points = <
+ /* kHz uV */
+ 1500000 1000000
+ 1300000 1000000
+ 1000000 900000
+ 800000 900000
+ >;
+ dc-supply = <&reg_gpio_dvfs>;
+};
+
+&dcss {
+ status = "okay";
+
+ disp-dev = "hdmi_disp";
+};
+
+&hdmi {
+ status = "okay";
+};
+
+&csi1_bridge {
+ fsl,mipi-mode;
+ fsl,two-8bit-sensor-mode;
+ status = "okay";
+
+ port {
+ csi1_ep: endpoint {
+ remote-endpoint = <&csi1_mipi_ep>;
+ };
+ };
+};
+
+&csi2_bridge {
+ fsl,mipi-mode;
+ fsl,two-8bit-sensor-mode;
+ status = "okay";
+
+ port {
+ csi2_ep: endpoint {
+ remote-endpoint = <&csi2_mipi_ep>;
+ };
+ };
+};
+
+&mipi_csi_1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "okay";
+ port {
+ mipi1_sensor_ep: endpoint1 {
+ remote-endpoint = <&ov5640_mipi1_ep>;
+ data-lanes = <1 2>;
+ };
+
+ csi1_mipi_ep: endpoint2 {
+ remote-endpoint = <&csi1_ep>;
+ };
+ };
+};
+
+&mipi_csi_2 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "okay";
+ port {
+ mipi2_sensor_ep: endpoint1 {
+ remote-endpoint = <&ov5640_mipi2_ep>;
+ data-lanes = <1 2>;
+ };
+
+ csi2_mipi_ep: endpoint2 {
+ remote-endpoint = <&csi2_ep>;
+ };
+ };
+};
+
+&mipi_dsi_bridge {
+ port@1 {
+ mipi_dsi_bridge_adv: endpoint {
+ remote-endpoint = <&adv7535_in>;
+ };
+ };
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8mq.dtsi b/arch/arm64/boot/dts/freescale/fsl-imx8mq.dtsi
new file mode 100755
index 000000000000..669f71201532
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8mq.dtsi
@@ -0,0 +1,1466 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017-2018 NXP
+ *
+ * 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 "fsl-imx8-ca53.dtsi"
+#include <dt-bindings/clock/imx8mq-clock.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/pinctrl/pins-imx8mq.h>
+#include <dt-bindings/thermal/thermal.h>
+
+/ {
+ compatible = "fsl,imx8mq";
+ interrupt-parent = <&gpc>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ aliases {
+ csi0 = &mipi_csi_1;
+ csi1 = &mipi_csi_2;
+ ethernet0 = &fec1;
+ serial0 = &uart1;
+ serial1 = &uart2;
+ serial2 = &uart3;
+ serial3 = &uart4;
+ spi0 = &ecspi1;
+ spi1 = &ecspi2;
+ spi2 = &ecspi3;
+ mmc0 = &usdhc1;
+ mmc1 = &usdhc2;
+ gpio0 = &gpio1;
+ gpio1 = &gpio2;
+ gpio2 = &gpio3;
+ gpio3 = &gpio4;
+ gpio4 = &gpio5;
+ dsi_phy0 = &mipi_dsi_phy;
+ mipi_dsi0 = &mipi_dsi;
+ };
+
+ cpus {
+ idle-states {
+ entry-method = "psci";
+
+ CPU_SLEEP: cpu-sleep {
+ compatible = "arm,idle-state";
+ arm,psci-suspend-param = <0x0010033>;
+ local-timer-stop;
+ entry-latency-us = <1000>;
+ exit-latency-us = <700>;
+ min-residency-us = <2700>;
+ wakeup-latency-us = <1500>;
+ };
+ };
+ };
+
+ memory@40000000 {
+ device_type = "memory";
+ reg = <0x00000000 0x40000000 0 0xc0000000>;
+ };
+
+ resmem: reserved-memory {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ /* global autoconfigured region for contiguous allocations */
+ linux,cma {
+ compatible = "shared-dma-pool";
+ reusable;
+ size = <0 0x3c000000>;
+ alloc-ranges = <0 0x40000000 0 0x40000000>;
+ linux,cma-default;
+ };
+
+ rpmsg_reserved: rpmsg@0xb8000000 {
+ no-map;
+ reg = <0 0xb8000000 0 0x400000>;
+ };
+ };
+
+ gic: interrupt-controller@38800000 {
+ compatible = "arm,gic-v3";
+ reg = <0x0 0x38800000 0 0x10000>, /* GIC Dist */
+ <0x0 0x38880000 0 0xC0000>, /* GICR (RD_base + SGI_base) */
+ <0x0 0x30340000 0x0 0x10000>; /* IOMUXC_GPR */
+ #interrupt-cells = <3>;
+ interrupt-controller;
+ interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-parent = <&gic>;
+ };
+
+ timer {
+ compatible = "arm,armv8-timer";
+ interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>, /* Physical Secure */
+ <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>, /* Physical Non-Secure */
+ <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>, /* Virtual */
+ <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>; /* Hypervisor */
+ clock-frequency = <8333333>;
+ interrupt-parent = <&gic>;
+ arm,no-tick-in-suspend;
+ };
+
+ pmu {
+ interrupt-parent = <&gic>;
+ };
+
+ busfreq { /* BUSFREQ */
+ compatible = "fsl,imx_busfreq";
+ clocks = <&clk IMX8MQ_DRAM_PLL_OUT>, <&clk IMX8MQ_CLK_DRAM_ALT>,
+ <&clk IMX8MQ_CLK_DRAM_APB>, <&clk IMX8MQ_CLK_DRAM_APB>,
+ <&clk IMX8MQ_CLK_DRAM_CORE>, <&clk IMX8MQ_CLK_DRAM_ALT_ROOT>,
+ <&clk IMX8MQ_SYS1_PLL_40M>, <&clk IMX8MQ_SYS1_PLL_400M>,
+ <&clk IMX8MQ_SYS1_PLL_100M>, <&clk IMX8MQ_SYS1_PLL_800M>,
+ <&clk IMX8MQ_CLK_NOC>, <&clk IMX8MQ_CLK_MAIN_AXI>,
+ <&clk IMX8MQ_CLK_AHB>, <&clk IMX8MQ_CLK_25M>,
+ <&clk IMX8MQ_SYS2_PLL_333M>, <&clk IMX8MQ_SYS1_PLL_133M>;
+ clock-names = "dram_pll", "dram_alt_src", "dram_apb_src", "dram_apb_pre_div",
+ "dram_core", "dram_alt_root", "sys1_pll_40m", "sys1_pll_400m",
+ "sys1_pll_100m", "sys1_pll_800m", "noc_div", "main_axi_src",
+ "ahb_div", "osc_25m", "sys2_pll_333m", "sys1_pll_133m";
+ interrupts = <GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 111 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-name = "irq_busfreq_0", "irq_busfreq_1", "irq_busfreq_2", "irq_busfreq_3";
+ };
+
+ clocks {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ckil: clock@0 {
+ compatible = "fixed-clock";
+ reg = <0>;
+ #clock-cells = <0>;
+ clock-frequency = <32768>;
+ clock-output-names = "ckil";
+ };
+
+ osc_25m: clock@1 {
+ compatible = "fixed-clock";
+ reg = <1>;
+ #clock-cells = <0>;
+ clock-frequency = <25000000>;
+ clock-output-names = "osc_25m";
+ };
+
+ osc_27m: clock@2 {
+ compatible = "fixed-clock";
+ reg = <2>;
+ #clock-cells = <0>;
+ clock-frequency = <27000000>;
+ clock-output-names = "osc_27m";
+ };
+
+ clk_ext1: clock@3 {
+ compatible = "fixed-clock";
+ reg = <3>;
+ #clock-cells = <0>;
+ clock-frequency = <133000000>;
+ clock-output-names = "clk_ext1";
+ };
+
+ clk_ext2: clock@4 {
+ compatible = "fixed-clock";
+ reg = <4>;
+ #clock-cells = <0>;
+ clock-frequency = <133000000>;
+ clock-output-names = "clk_ext2";
+ };
+
+ clk_ext3: clock@5 {
+ compatible = "fixed-clock";
+ reg = <5>;
+ #clock-cells = <0>;
+ clock-frequency = <133000000>;
+ clock-output-names = "clk_ext3";
+ };
+
+ clk_ext4: clock@6 {
+ compatible = "fixed-clock";
+ reg = <6>;
+ #clock-cells = <0>;
+ clock-frequency= <133000000>;
+ clock-output-names = "clk_ext4";
+ };
+ };
+
+ mipi_pd: gpc_power_domain@0 {
+ compatible = "fsl,imx8mq-pm-domain";
+ #power-domain-cells = <0>;
+ domain-id = <0>;
+ domain-name = "MIPI_PD";
+ };
+
+ pcie0_pd: gpc_power_domain@1 {
+ compatible = "fsl,imx8mq-pm-domain";
+ #power-domain-cells = <0>;
+ domain-id = <1>;
+ domain-name = "PCIE0_PD";
+ };
+
+ usb_otg1_pd: gpc_power_domain@2 {
+ compatible = "fsl,imx8mq-pm-domain";
+ #power-domain-cells = <0>;
+ domain-id = <2>;
+ domain-name = "USB_OTG1_PD";
+ };
+
+ usb_otg2_pd: gpc_power_domain@3 {
+ compatible = "fsl,imx8mq-pm-domain";
+ #power-domain-cells = <0>;
+ domain-id = <3>;
+ domain-name = "USB_OTG2_PD";
+ };
+
+ gpu_pd: gpc_power_domain@4 {
+ compatible = "fsl,imx8mq-pm-domain";
+ #power-domain-cells = <0>;
+ domain-id = <4>;
+ domain-name = "GPU_PD";
+ clocks = <&clk IMX8MQ_CLK_GPU_AXI>, <&clk IMX8MQ_CLK_GPU_SHADER_DIV>,
+ <&clk IMX8MQ_CLK_GPU_ROOT>, <&clk IMX8MQ_CLK_GPU_AHB>;
+ };
+
+ vpu_pd: gpc_power_domain@5 {
+ compatible = "fsl,imx8mq-pm-domain";
+ #power-domain-cells = <0>;
+ domain-id = <5>;
+ domain-name = "VPU_PD";
+ clocks = <&clk IMX8MQ_CLK_VPU_G1_ROOT>, <&clk IMX8MQ_CLK_VPU_G2_ROOT>,
+ <&clk IMX8MQ_CLK_VPU_DEC_ROOT>;
+ };
+
+ mipi_csi1_pd: gpc_power_domain@8 {
+ compatible = "fsl,imx8mq-pm-domain";
+ #power-domain-cells = <0>;
+ domain-id = <8>;
+ domain-name = "MIPI_CSI1_PD";
+ };
+
+ mipi_csi2_pd: gpc_power_domain@9 {
+ compatible = "fsl,imx8mq-pm-domain";
+ #power-domain-cells = <0>;
+ domain-id = <9>;
+ domain-name = "MIPI_CSI2_PD";
+ };
+
+ pcie1_pd: gpc_power_domain@10 {
+ compatible = "fsl,imx8mq-pm-domain";
+ #power-domain-cells = <0>;
+ domain-id = <10>;
+ domain-name = "PCIE1_PD";
+ };
+
+ pwm1: pwm@30660000 {
+ compatible = "fsl,imx8mq-pwm", "fsl,imx27-pwm";
+ reg = <0x0 0x30660000 0x0 0x10000>;
+ interrupts = <GIC_SPI 81 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8MQ_CLK_PWM1_ROOT>,
+ <&clk IMX8MQ_CLK_PWM1_ROOT>;
+ clock-names = "ipg", "per";
+ #pwm-cells = <2>;
+ status = "disabled";
+ };
+
+ pwm2: pwm@30670000 {
+ compatible = "fsl,imx8mq-pwm", "fsl,imx27-pwm";
+ reg = <0x0 0x30670000 0x0 0x10000>;
+ interrupts = <GIC_SPI 82 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8MQ_CLK_PWM2_ROOT>,
+ <&clk IMX8MQ_CLK_PWM2_ROOT>;
+ clock-names = "ipg", "per";
+ #pwm-cells = <2>;
+ status = "disabled";
+ };
+
+ pwm3: pwm@30680000 {
+ compatible = "fsl,imx8mq-pwm", "fsl,imx27-pwm";
+ reg = <0x0 0x30680000 0x0 0x10000>;
+ interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8MQ_CLK_PWM3_ROOT>,
+ <&clk IMX8MQ_CLK_PWM3_ROOT>;
+ clock-names = "ipg", "per";
+ #pwm-cells = <2>;
+ status = "disabled";
+ };
+
+ pwm4: pwm@30690000 {
+ compatible = "fsl,imx8mq-pwm", "fsl,imx27-pwm";
+ reg = <0x0 0x30690000 0x0 0x10000>;
+ interrupts = <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8MQ_CLK_PWM4_ROOT>,
+ <&clk IMX8MQ_CLK_PWM4_ROOT>;
+ clock-names = "ipg", "per";
+ #pwm-cells = <2>;
+ status = "disabled";
+ };
+
+ gpio1: gpio@30200000 {
+ compatible = "fsl,imx8mq-gpio", "fsl,imx35-gpio";
+ reg = <0x0 0x30200000 0x0 0x10000>;
+ interrupts = <GIC_SPI 64 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio2: gpio@30210000 {
+ compatible = "fsl,imx8mq-gpio", "fsl,imx35-gpio";
+ reg = <0x0 0x30210000 0x0 0x10000>;
+ interrupts = <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio3: gpio@30220000 {
+ compatible = "fsl,imx8mq-gpio", "fsl,imx35-gpio";
+ reg = <0x0 0x30220000 0x0 0x10000>;
+ interrupts = <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio4: gpio@30230000 {
+ compatible = "fsl,imx8mq-gpio", "fsl,imx35-gpio";
+ reg = <0x0 0x30230000 0x0 0x10000>;
+ interrupts = <GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio5: gpio@30240000 {
+ compatible = "fsl,imx8mq-gpio", "fsl,imx35-gpio";
+ reg = <0x0 0x30240000 0x0 0x10000>;
+ interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ tmu: tmu@30260000 {
+ compatible = "fsl,imx8mq-tmu";
+ reg = <0x0 0x30260000 0x0 0x10000>;
+ interrupt = <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>;
+ little-endian;
+ fsl,tmu-range = <0xb0000 0xa0026 0x80048 0x70061>;
+ fsl,tmu-calibration = <0x00000000 0x00000023
+ 0x00000001 0x00000029
+ 0x00000002 0x0000002f
+ 0x00000003 0x00000035
+ 0x00000004 0x0000003d
+ 0x00000005 0x00000043
+ 0x00000006 0x0000004b
+ 0x00000007 0x00000051
+ 0x00000008 0x00000057
+ 0x00000009 0x0000005f
+ 0x0000000a 0x00000067
+ 0x0000000b 0x0000006f
+
+ 0x00010000 0x0000001b
+ 0x00010001 0x00000023
+ 0x00010002 0x0000002b
+ 0x00010003 0x00000033
+ 0x00010004 0x0000003b
+ 0x00010005 0x00000043
+ 0x00010006 0x0000004b
+ 0x00010007 0x00000055
+ 0x00010008 0x0000005d
+ 0x00010009 0x00000067
+ 0x0001000a 0x00000070
+
+ 0x00020000 0x00000017
+ 0x00020001 0x00000023
+ 0x00020002 0x0000002d
+ 0x00020003 0x00000037
+ 0x00020004 0x00000041
+ 0x00020005 0x0000004b
+ 0x00020006 0x00000057
+ 0x00020007 0x00000063
+ 0x00020008 0x0000006f
+
+ 0x00030000 0x00000015
+ 0x00030001 0x00000021
+ 0x00030002 0x0000002d
+ 0x00030003 0x00000039
+ 0x00030004 0x00000045
+ 0x00030005 0x00000053
+ 0x00030006 0x0000005f
+ 0x00030007 0x00000071>;
+ #thermal-sensor-cells = <0>;
+ };
+
+ thermal-zones {
+ /* cpu thermal */
+ cpu-thermal {
+ polling-delay-passive = <250>;
+ polling-delay = <2000>;
+ thermal-sensors = <&tmu>;
+ trips {
+ cpu_alert0: trip0 {
+ temperature = <85000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+ cpu_crit0: trip1 {
+ temperature = <95000>;
+ hysteresis = <2000>;
+ type = "critical";
+ };
+ };
+
+ cooling-maps {
+ map0 {
+ trip = <&cpu_alert0>;
+ cooling-device =
+ <&A53_0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
+ };
+ };
+
+ gpt1: gpt@302d0000 {
+ compatible = "fsl,imx8mq-gpt", "fsl,imx7d-gpt";
+ reg = <0x0 0x302d0000 0x0 0x10000>;
+ interrupts = <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8MQ_CLK_GPT1_ROOT>,
+ <&clk IMX8MQ_CLK_GPT1_ROOT>,
+ <&clk IMX8MQ_GPT_3M_CLK>;
+ clock-names = "ipg", "per", "osc_per";
+ status = "disabled";
+ };
+
+ irqsteer_dcss: irqsteer@32e2d000 {
+ compatible = "nxp,imx-irqsteer";
+ reg = <0x0 0x32e2d000 0x0 0x1000>;
+ interrupts = <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ nxp,irqsteer_chans = <2>;
+ nxp,endian = <1>; /* MSB */
+ clocks = <&clk IMX8MQ_CLK_DISP_APB_ROOT>;
+ clock-names = "ipg";
+ };
+
+ csi1_bridge: csi1_bridge@30a90000 {
+ compatible = "fsl,imx8mq-csi", "fsl,imx6s-csi";
+ reg = <0x0 0x30a90000 0x0 0x10000>;
+ interrupts = <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8MQ_CLK_DUMMY>,
+ <&clk IMX8MQ_CLK_CSI1_ROOT>,
+ <&clk IMX8MQ_CLK_DUMMY>;
+ clock-names = "disp-axi", "csi_mclk", "disp_dcic";
+ status = "disabled";
+ };
+
+ csi2_bridge: csi2_bridge@30b80000 {
+ compatible = "fsl,imx8mq-csi", "fsl,imx6s-csi";
+ reg = <0x0 0x30b80000 0x0 0x10000>;
+ interrupts = <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8MQ_CLK_DUMMY>,
+ <&clk IMX8MQ_CLK_CSI2_ROOT>,
+ <&clk IMX8MQ_CLK_DUMMY>;
+ clock-names = "disp-axi", "csi_mclk", "disp_dcic";
+ status = "disabled";
+ };
+
+ mipi_csi_1: mipi_csi1@30a70000 {
+ compatible = "fsl,mxc-mipi-csi2_yav";
+ reg = <0x0 0x30a70000 0x0 0x1000>; /* MIPI CSI1 Controller base addr */
+ interrupts = <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8MQ_CLK_DUMMY>,
+ <&clk IMX8MQ_CLK_CSI1_CORE>,
+ <&clk IMX8MQ_CLK_CSI1_ESC>,
+ <&clk IMX8MQ_CLK_CSI1_PHY_REF>;
+ clock-names = "clk_apb", "clk_core", "clk_esc", "clk_pxl";
+ assigned-clocks = <&clk IMX8MQ_CLK_CSI1_CORE>,
+ <&clk IMX8MQ_CLK_CSI1_PHY_REF>,
+ <&clk IMX8MQ_CLK_CSI1_ESC>;
+ assigned-clock-rates = <133000000>, <100000000>, <66000000>;
+ power-domains = <&mipi_csi1_pd>;
+ csis-phy-reset = <&src 0x4c 7>;
+ phy-gpr = <&gpr 0x88>;
+ status = "disabled";
+ };
+
+ mipi_csi_2: mipi_csi2@30b60000 {
+ compatible = "fsl,mxc-mipi-csi2_yav";
+ reg = <0x0 0x30b60000 0x0 0x1000>; /* MIPI CSI2 Controller base addr */
+ interrupts = <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8MQ_CLK_DUMMY>,
+ <&clk IMX8MQ_CLK_CSI2_CORE>,
+ <&clk IMX8MQ_CLK_CSI2_ESC>,
+ <&clk IMX8MQ_CLK_CSI2_PHY_REF>;
+ clock-names = "clk_apb", "clk_core", "clk_esc", "clk_pxl";
+ assigned-clocks = <&clk IMX8MQ_CLK_CSI2_CORE>,
+ <&clk IMX8MQ_CLK_CSI2_PHY_REF>,
+ <&clk IMX8MQ_CLK_CSI2_ESC>;
+ assigned-clock-rates = <133000000>, <100000000>, <66000000>;
+ power-domains = <&mipi_csi2_pd>;
+ csis-phy-reset = <&src 0x50 7>;
+ phy-gpr = <&gpr 0xa4>;
+ status = "disabled";
+ };
+
+ dcss: dcss@0x32e00000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "nxp,imx8mq-dcss";
+ reg = <0x0 0x32e00000 0x0 0x30000>;
+ interrupts = <3 IRQ_TYPE_LEVEL_HIGH>,
+ <4 IRQ_TYPE_LEVEL_HIGH>,
+ <5 IRQ_TYPE_LEVEL_HIGH>,
+ <6 IRQ_TYPE_LEVEL_HIGH>,
+ <8 IRQ_TYPE_LEVEL_HIGH>,
+ <9 IRQ_TYPE_EDGE_RISING>,
+ <16 IRQ_TYPE_LEVEL_HIGH>,
+ <17 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "dpr_dc_ch0",
+ "dpr_dc_ch1",
+ "dpr_dc_ch2",
+ "ctx_ld",
+ "ctxld_kick",
+ "dtg_prg1",
+ "dtrc_ch1",
+ "dtrc_ch2";
+ interrupt-parent = <&irqsteer_dcss>;
+ clocks = <&clk IMX8MQ_CLK_DISP_APB_ROOT>,
+ <&clk IMX8MQ_CLK_DISP_AXI_ROOT>,
+ <&clk IMX8MQ_CLK_DISP_RTRM_ROOT>,
+ <&clk IMX8MQ_VIDEO2_PLL_OUT>,
+ <&clk IMX8MQ_CLK_DISP_DTRC>,
+ <&clk IMX8MQ_VIDEO2_PLL1_REF_SEL>,
+ <&clk IMX8MQ_CLK_PHY_27MHZ>;
+ clock-names = "apb", "axi", "rtrm", "pix",
+ "dtrc", "pll", "pll_src1";
+ assigned-clocks = <&clk IMX8MQ_CLK_DC_PIXEL>,
+ <&clk IMX8MQ_CLK_DISP_AXI>,
+ <&clk IMX8MQ_CLK_DISP_RTRM>,
+ <&clk IMX8MQ_VIDEO2_PLL1_REF_SEL>;
+ assigned-clock-parents = <&clk IMX8MQ_VIDEO_PLL1_OUT>,
+ <&clk IMX8MQ_SYS1_PLL_800M>,
+ <&clk IMX8MQ_SYS1_PLL_800M>,
+ <&clk IMX8MQ_CLK_27M>;
+ assigned-clock-rates = <594000000>,
+ <800000000>,
+ <400000000>;
+ status = "disabled";
+
+ dcss_disp0: port@0 {
+ reg = <0>;
+
+ dcss_disp0_hdmi: hdmi-endpoint {
+ remote-endpoint = <&hdmi_disp>;
+ };
+ };
+ };
+
+ hdmi: hdmi@32c00000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx8mq-hdmi";
+ reg = <0x0 0x32c00000 0x0 0x100000>, /* HDP registers */
+ <0x0 0x32e40000 0x0 0x40000>, /* HDP SEC register */
+ <0x0 0x32e2f000 0x0 0x10>; /* RESET register */
+ interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "plug_in", "plug_out";
+ fsl,cec;
+ status = "disabled";
+
+ port@0 {
+ reg = <0>;
+ hdmi_disp: endpoint {
+ remote-endpoint = <&dcss_disp0_hdmi>;
+ };
+ };
+ };
+
+ lcdif: lcdif@30320000 {
+ compatible = "fsl,imx8mq-lcdif", "fsl,imx28-lcdif";
+ reg = <0x0 0x30320000 0x0 0x10000>;
+ clocks = <&clk IMX8MQ_CLK_LCDIF_PIXEL>,
+ <&clk IMX8MQ_VIDEO_PLL1>,
+ <&clk IMX8MQ_CLK_27M>,
+ <&clk IMX8MQ_CLK_25M>;
+ clock-names = "pix", "video_pll", "osc_27", "osc_25";
+ assigned-clocks = <&clk IMX8MQ_CLK_LCDIF_PIXEL>;
+ assigned-clock-parents = <&clk IMX8MQ_VIDEO_PLL1_OUT>;
+ assigned-clock-rate = <594000000>;
+ interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
+
+ display-subsystem {
+ compatible = "fsl,imx-display-subsystem";
+ ports = <&dcss_disp0>;
+ };
+
+ mipi_dsi_phy: dsi_phy@30A00300 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "mixel,imx8mq-mipi-dsi-phy";
+ reg = <0x0 0x30A00300 0x0 0x100>;
+ #phy-cells = <0>;
+ status = "disabled";
+ };
+
+ mipi_dsi_bridge: mipi_dsi_bridge@30A00000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "nwl,mipi-dsi";
+ reg = <0x0 0x30A00000 0x0 0x400>;
+ interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8MQ_CLK_DSI_PHY_REF>,
+ <&clk IMX8MQ_CLK_DSI_AHB>,
+ <&clk IMX8MQ_CLK_DSI_IPG_DIV>;
+ clock-names = "phy_ref", "rx_esc", "tx_esc";
+ assigned-clocks = <&clk IMX8MQ_CLK_DSI_AHB>;
+ assigned-clock-parents = <&clk IMX8MQ_SYS1_PLL_80M>;
+ assigned-clock-rates = <80000000>;
+ phys = <&mipi_dsi_phy>;
+ phy-names = "dphy";
+ no_clk_reset;
+ status = "disabled";
+
+ port@0 {
+ mipi_dsi_bridge_in: endpoint {
+ remote-endpoint = <&mipi_dsi_out>;
+ };
+ };
+ };
+
+ mipi_dsi: mipi_dsi@30A00000 {
+ compatible = "fsl,imx8mq-mipi-dsi_drm";
+ clocks = <&clk IMX8MQ_CLK_DSI_CORE>,
+ <&clk IMX8MQ_CLK_DSI_PHY_REF>;
+ clock-names = "core", "phy_ref";
+ assigned-clocks = <&clk IMX8MQ_CLK_DSI_PHY_REF>,
+ <&clk IMX8MQ_CLK_DSI_CORE>;
+ assigned-clock-parents = <&clk IMX8MQ_VIDEO_PLL1_OUT>,
+ <&clk IMX8MQ_SYS1_PLL_266M>;
+ assigned-clock-rates = <594000000>, <266000000>;
+ power-domains = <&mipi_pd>;
+ src = <&src>;
+ mux-sel = <&gpr>;
+ phys = <&mipi_dsi_phy>;
+ phy-names = "dphy";
+ no_clk_reset;
+ status = "disabled";
+
+ port@0 {
+ mipi_dsi_out: endpoint {
+ remote-endpoint = <&mipi_dsi_bridge_in>;
+ };
+ };
+ };
+
+ iomuxc: iomuxc@30330000 {
+ compatible = "fsl,imx8mq-iomuxc";
+ reg = <0x0 0x30330000 0x0 0x10000>;
+ };
+
+ gpr: iomuxc-gpr@30340000 {
+ compatible = "fsl,imx8mq-iomuxc-gpr", "fsl,imx7d-iomuxc-gpr", "syscon";
+ reg = <0x0 0x30340000 0x0 0x10000>;
+ };
+
+ ocotp: ocotp-ctrl@30350000 {
+ compatible = "fsl,imx8mq-ocotp", "fsl,imx7d-ocotp", "syscon";
+ reg = <0 0x30350000 0 0x10000>;
+ clocks = <&clk IMX8MQ_CLK_OCOTP_ROOT>;
+ /* For nvmem subnodes */
+ #address-cells = <1>;
+ #size-cells = <1>;
+ };
+
+ anatop: anatop@30360000 {
+ compatible = "fsl,imx8mq-anatop", "fsl,imx6q-anatop",
+ "syscon", "simple-bus";
+ reg = <0x0 0x30360000 0x0 0x10000>;
+ interrupts = <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ snvs: snvs@30370000 {
+ compatible = "fsl,sec-v4.0-mon","syscon", "simple-mfd";
+ reg = <0x0 0x30370000 0x0 0x10000>;
+
+ snvs_rtc: snvs-rtc-lp{
+ compatible = "fsl,sec-v4.0-mon-rtc-lp";
+ regmap =<&snvs>;
+ offset = <0x34>;
+ interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ snvs_pwrkey: snvs-powerkey {
+ compatible = "fsl,sec-v4.0-pwrkey";
+ regmap = <&snvs>;
+ interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>;
+ linux,keycode = <KEY_POWER>;
+ wakeup-source;
+ };
+ };
+
+ clk: ccm@30380000 {
+ compatible = "fsl,imx8mq-ccm";
+ reg = <0x0 0x30380000 0x0 0x10000>;
+ interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
+ #clock-cells = <1>;
+ clocks = <&ckil>, <&osc_25m>, <&osc_27m>, <&clk_ext1>, <&clk_ext2>,
+ <&clk_ext3>, <&clk_ext4>;
+ clock-names = "ckil", "osc_25m", "osc_27m", "clk_ext1", "clk_ext2",
+ "clk_ext3", "clk_ext4";
+ };
+
+ src: src@30390000 {
+ compatible = "fsl,imx8mq-src", "fsl,imx51-src", "syscon";
+ reg = <0x0 0x30390000 0x0 0x10000>;
+ interrupts = <GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH>;
+ #reset-cells = <1>;
+ };
+
+ gpc: gpc@303a0000 {
+ compatible = "fsl,imx8mq-gpc", "fsl,imx7d-gpc", "syscon";
+ reg = <0x0 0x303a0000 0x0 0x10000>;
+ interrupt-controller;
+ interrupts = <GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH>;
+ #interrupt-cells = <3>;
+ interrupt-parent = <&gic>;
+ };
+
+ system_counter: system-counter@3036a0000 {
+ compatible = "nxp,sysctr-timer";
+ reg = <0x0 0x306a0000 0x0 0x10000>, /* system-counter-rd base */
+ <0x0 0x306b0000 0x0 0x10000>, /* system-counter-cmp base */
+ <0x0 0x306c0000 0x0 0x10000>; /* system-counter-ctrl base */
+ clock-frequency = <8333333>;
+ interrupts = <GIC_SPI 47 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ spdif1: spdif@30810000 {
+ compatible = "fsl,imx8mq-spdif", "fsl,imx35-spdif";
+ reg = <0x0 0x30810000 0x0 0x10000>;
+ interrupts = <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8MQ_CLK_IPG_ROOT>, /* core */
+ <&clk IMX8MQ_CLK_25M>, /* rxtx0 */
+ <&clk IMX8MQ_CLK_SPDIF1>, /* rxtx1 */
+ <&clk IMX8MQ_CLK_DUMMY>, /* rxtx2 */
+ <&clk IMX8MQ_CLK_DUMMY>, /* rxtx3 */
+ <&clk IMX8MQ_CLK_DUMMY>, /* rxtx4 */
+ <&clk IMX8MQ_CLK_IPG_ROOT>, /* rxtx5 */
+ <&clk IMX8MQ_CLK_DUMMY>, /* rxtx6 */
+ <&clk IMX8MQ_CLK_DUMMY>, /* rxtx7 */
+ <&clk IMX8MQ_CLK_DUMMY>; /* spba */
+ clock-names = "core", "rxtx0",
+ "rxtx1", "rxtx2",
+ "rxtx3", "rxtx4",
+ "rxtx5", "rxtx6",
+ "rxtx7", "spba";
+ dmas = <&sdma1 8 18 0>, <&sdma1 9 18 0>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ ecspi1: ecspi@30820000 {
+ compatible = "fsl,imx6ul-ecspi", "fsl,imx51-ecspi";
+ reg = <0x0 0x30820000 0x0 0x10000>;
+ interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8MQ_CLK_ECSPI1_ROOT>,
+ <&clk IMX8MQ_CLK_ECSPI1_ROOT>;
+ clock-names = "ipg", "per";
+ status = "disabled";
+ };
+
+ ecspi1: ecspi@30820000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx8mq-ecspi", "fsl,imx51-ecspi";
+ reg = <0x0 0x30820000 0x0 0x10000>;
+ interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8MQ_CLK_ECSPI1_ROOT>,
+ <&clk IMX8MQ_CLK_ECSPI1_ROOT>;
+ clock-names = "ipg", "per";
+ status = "disabled";
+ };
+
+ ecspi2: ecspi@30830000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx8mq-ecspi", "fsl,imx51-ecspi";
+ reg = <0x0 0x30830000 0x0 0x10000>;
+ interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8MQ_CLK_ECSPI2_ROOT>,
+ <&clk IMX8MQ_CLK_ECSPI2_ROOT>;
+ clock-names = "ipg", "per";
+ status = "disabled";
+ };
+
+ ecspi3: ecspi@30840000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx8mq-ecspi", "fsl,imx51-ecspi";
+ reg = <0x0 0x30840000 0x0 0x10000>;
+ interrupts = <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8MQ_CLK_ECSPI3_ROOT>,
+ <&clk IMX8MQ_CLK_ECSPI3_ROOT>;
+ clock-names = "ipg", "per";
+ status = "disabled";
+ };
+
+ uart1: serial@30860000 {
+ compatible = "fsl,imx8mq-uart",
+ "fsl,imx6q-uart", "fsl,imx21-uart";
+ reg = <0x0 0x30860000 0x0 0x10000>;
+ interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8MQ_CLK_UART1_ROOT>,
+ <&clk IMX8MQ_CLK_UART1_ROOT>;
+ clock-names = "ipg", "per";
+ status = "disabled";
+ };
+
+ uart3: serial@30880000 {
+ compatible = "fsl,imx8mq-uart",
+ "fsl,imx6q-uart", "fsl,imx21-uart";
+ reg = <0x0 0x30880000 0x0 0x10000>;
+ interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8MQ_CLK_UART3_ROOT>,
+ <&clk IMX8MQ_CLK_UART3_ROOT>;
+ clock-names = "ipg", "per";
+ dmas = <&sdma1 26 4 0>, <&sdma1 27 4 0>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ uart2: serial@30890000 {
+ compatible = "fsl,imx8mq-uart",
+ "fsl,imx6q-uart", "fsl,imx21-uart";
+ reg = <0x0 0x30890000 0x0 0x10000>;
+ interrupts = <GIC_SPI 27 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8MQ_CLK_UART2_ROOT>,
+ <&clk IMX8MQ_CLK_UART2_ROOT>;
+ clock-names = "ipg", "per";
+ dmas = <&sdma1 24 4 0>, <&sdma1 25 4 0>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ spdif2: spdif@308a0000 {
+ compatible = "fsl,imx8mq-spdif", "fsl,imx35-spdif";
+ reg = <0x0 0x308a0000 0x0 0x10000>;
+ interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8MQ_CLK_IPG_ROOT>, /* core */
+ <&clk IMX8MQ_CLK_25M>, /* rxtx0 */
+ <&clk IMX8MQ_CLK_SPDIF2>, /* rxtx1 */
+ <&clk IMX8MQ_CLK_DUMMY>, /* rxtx2 */
+ <&clk IMX8MQ_CLK_DUMMY>, /* rxtx3 */
+ <&clk IMX8MQ_CLK_DUMMY>, /* rxtx4 */
+ <&clk IMX8MQ_CLK_IPG_ROOT>, /* rxtx5 */
+ <&clk IMX8MQ_CLK_DUMMY>, /* rxtx6 */
+ <&clk IMX8MQ_CLK_DUMMY>, /* rxtx7 */
+ <&clk IMX8MQ_CLK_DUMMY>; /* spba */
+ clock-names = "core", "rxtx0",
+ "rxtx1", "rxtx2",
+ "rxtx3", "rxtx4",
+ "rxtx5", "rxtx6",
+ "rxtx7", "spba";
+ dmas = <&sdma1 16 18 0>, <&sdma1 17 18 0>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ uart4: serial@30a60000 {
+ compatible = "fsl,imx8mq-uart",
+ "fsl,imx6q-uart", "fsl,imx21-uart";
+ reg = <0x0 0x30a60000 0x0 0x10000>;
+ interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8MQ_CLK_UART4_ROOT>,
+ <&clk IMX8MQ_CLK_UART4_ROOT>;
+ clock-names = "ipg", "per";
+ dmas = <&sdma1 28 4 0>, <&sdma1 29 4 0>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ mu: mu@30aa0000 {
+ compatible = "fsl,imx8mq-mu", "fsl,imx6sx-mu";
+ reg = <0x0 0x30aa0000 0x0 0x10000>;
+ interrupts = <GIC_SPI 88 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8MQ_CLK_MU_ROOT>;
+ clock-names = "mu";
+ status = "disabled";
+ };
+
+ usb3_phy0: phy@381f0040 {
+ compatible = "fsl,imx8mq-usb-phy";
+ #phy-cells = <1>;
+ reg = <0x0 0x381f0040 0x0 0x40>;
+ clocks = <&clk IMX8MQ_CLK_USB1_PHY_ROOT>;
+ clock-names = "usb_phy_root_clk";
+ assigned-clocks = <&clk IMX8MQ_CLK_USB_PHY_REF>;
+ assigned-clock-parents = <&clk IMX8MQ_SYS1_PLL_100M>;
+ assigned-clock-rates = <100000000>;
+ status = "disabled";
+ };
+
+ usb3_0: usb@38100000 {
+ compatible = "fsl, imx8mq-dwc3";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+ clocks = <&clk IMX8MQ_CLK_USB1_CTRL_ROOT>;
+ clock-names = "usb1_ctrl_root_clk";
+ assigned-clocks = <&clk IMX8MQ_CLK_USB_BUS>,
+ <&clk IMX8MQ_CLK_USB_CORE_REF>;
+ assigned-clock-parents = <&clk IMX8MQ_SYS2_PLL_500M>,
+ <&clk IMX8MQ_SYS1_PLL_100M>;
+ assigned-clock-rates = <500000000>, <100000000>;
+ status = "disabled";
+
+ usb_dwc3_0: dwc3 {
+ compatible = "snps,dwc3";
+ reg = <0x0 0x38100000 0x0 0x10000>;
+ interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>;
+ phys = <&usb3_phy0 0>, <&usb3_phy0 1>;
+ phy-names = "usb2-phy", "usb3-phy";
+ power-domains = <&usb_otg1_pd>;
+ snps,power-down-scale = <2>;
+ usb3-resume-missing-cas;
+ usb3-lpm-capable;
+ snps,has-lpm-erratum;
+ snps,lpm-nyet-threshold = <0xf>;
+ status = "disabled";
+ };
+ };
+
+ usb3_phy1: phy@382f0040 {
+ compatible = "fsl,imx8mq-usb-phy";
+ #phy-cells = <1>;
+ reg = <0x0 0x382f0040 0x0 0x40>;
+ clocks = <&clk IMX8MQ_CLK_USB2_PHY_ROOT>;
+ clock-names = "usb_phy_root_clk";
+ assigned-clocks = <&clk IMX8MQ_CLK_USB_PHY_REF>;
+ assigned-clock-parents = <&clk IMX8MQ_SYS1_PLL_100M>;
+ assigned-clock-rates = <100000000>;
+ status = "disabled";
+ };
+
+ usb3_1: usb@38200000 {
+ compatible = "fsl, imx8mq-dwc3";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+ clocks = <&clk IMX8MQ_CLK_USB2_CTRL_ROOT>;
+ clock-names = "usb2_ctrl_root_clk";
+ assigned-clocks = <&clk IMX8MQ_CLK_USB_BUS>,
+ <&clk IMX8MQ_CLK_USB_CORE_REF>;
+ assigned-clock-parents = <&clk IMX8MQ_SYS2_PLL_500M>,
+ <&clk IMX8MQ_SYS1_PLL_100M>;
+ assigned-clock-rates = <500000000>, <100000000>;
+ status = "disabled";
+
+ usb_dwc3_1: dwc3 {
+ compatible = "snps,dwc3";
+ reg = <0x0 0x38200000 0x0 0x10000>;
+ interrupts = <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>;
+ phys = <&usb3_phy1 0>, <&usb3_phy1 1>;
+ phy-names = "usb2-phy", "usb3-phy";
+ power-domains = <&usb_otg2_pd>;
+ snps,power-down-scale = <2>;
+ usb3-resume-missing-cas;
+ usb3-lpm-capable;
+ status = "disabled";
+ };
+ };
+
+ usdhc1: usdhc@30b40000 {
+ compatible = "fsl,imx8mq-usdhc", "fsl,imx7d-usdhc";
+ reg = <0x0 0x30b40000 0x0 0x10000>;
+ interrupts = <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8MQ_CLK_DUMMY>,
+ <&clk IMX8MQ_CLK_NAND_USDHC_BUS>,
+ <&clk IMX8MQ_CLK_USDHC1_ROOT>;
+ clock-names = "ipg", "ahb", "per";
+ assigned-clocks = <&clk IMX8MQ_CLK_USDHC1>;
+ assigned-clock-rates = <400000000>;
+ fsl,tuning-start-tap = <20>;
+ fsl,tuning-step = <2>;
+ fsl,strobe-dll-delay-target = <5>;
+ bus-width = <4>;
+ status = "disabled";
+ };
+
+ usdhc2: usdhc@30b50000 {
+ compatible = "fsl,imx8mq-usdhc", "fsl,imx7d-usdhc";
+ reg = <0x0 0x30b50000 0x0 0x10000>;
+ interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8MQ_CLK_DUMMY>,
+ <&clk IMX8MQ_CLK_NAND_USDHC_BUS>,
+ <&clk IMX8MQ_CLK_USDHC2_ROOT>;
+ clock-names = "ipg", "ahb", "per";
+ fsl,tuning-start-tap = <20>;
+ fsl,tuning-step = <2>;
+ bus-width = <4>;
+ status = "disabled";
+ };
+
+ sai1: sai@30010000 {
+ compatible = "fsl,imx8mq-sai",
+ "fsl,imx6sx-sai";
+ reg = <0x0 0x30010000 0x0 0x10000>;
+ interrupts = <GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8MQ_CLK_SAI1_IPG>,
+ <&clk IMX8MQ_CLK_DUMMY>,
+ <&clk IMX8MQ_CLK_SAI1_ROOT>,
+ <&clk IMX8MQ_CLK_DUMMY>, <&clk IMX8MQ_CLK_DUMMY>;
+ clock-names = "bus", "mclk0", "mclk1", "mclk2", "mclk3";
+ dmas = <&sdma2 8 2 0>, <&sdma2 9 2 0>;
+ dma-names = "rx", "tx";
+ fsl,dataline = <0 0xff 0xff>;
+ status = "disabled";
+ };
+
+ sai6: sai@30030000 {
+ compatible = "fsl,imx8mq-sai",
+ "fsl,imx6sx-sai";
+ reg = <0x0 0x30030000 0x0 0x10000>;
+ interrupts = <GIC_SPI 90 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8MQ_CLK_SAI6_IPG>,
+ <&clk IMX8MQ_CLK_DUMMY>,
+ <&clk IMX8MQ_CLK_SAI6_ROOT>,
+ <&clk IMX8MQ_CLK_DUMMY>, <&clk IMX8MQ_CLK_DUMMY>;
+ clock-names = "bus", "mclk0", "mclk1", "mclk2", "mclk3";
+ dmas = <&sdma2 4 24 0>, <&sdma2 5 24 0>;
+ dma-names = "rx", "tx";
+ fsl,shared-interrupt;
+ status = "disabled";
+ };
+
+ sai5: sai@30040000 {
+ compatible = "fsl,imx8mq-sai",
+ "fsl,imx6sx-sai";
+ reg = <0x0 0x30040000 0x0 0x10000>;
+ interrupts = <GIC_SPI 90 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8MQ_CLK_SAI5_IPG>,
+ <&clk IMX8MQ_CLK_DUMMY>,
+ <&clk IMX8MQ_CLK_SAI5_ROOT>,
+ <&clk IMX8MQ_CLK_DUMMY>, <&clk IMX8MQ_CLK_DUMMY>;
+ clock-names = "bus", "mclk0", "mclk1", "mclk2", "mclk3";
+ dmas = <&sdma2 2 24 0>, <&sdma2 3 24 0>;
+ dma-names = "rx", "tx";
+ fsl,shared-interrupt;
+ fsl,dataline = <0 0xf 0xf>;
+ status = "disabled";
+ };
+
+ sai4: sai@30050000 {
+ compatible = "fsl,imx8mq-sai",
+ "fsl,imx6sx-sai";
+ reg = <0x0 0x30050000 0x0 0x10000>;
+ interrupts = <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8MQ_CLK_SAI4_IPG>,
+ <&clk IMX8MQ_CLK_DUMMY>,
+ <&clk IMX8MQ_CLK_SAI4_ROOT>,
+ <&clk IMX8MQ_CLK_DUMMY>, <&clk IMX8MQ_CLK_DUMMY>;
+ clock-names = "bus", "mclk0", "mclk1", "mclk2", "mclk3";
+ dmas = <&sdma2 0 24 0>, <&sdma2 1 24 0>;
+ dma-names = "rx", "tx";
+ fsl,dataline = <0 0x0 0xf>;
+ status = "disabled";
+ };
+
+ sai2: sai@308b0000 {
+ compatible = "fsl,imx8mq-sai",
+ "fsl,imx6sx-sai";
+ reg = <0x0 0x308b0000 0x0 0x10000>;
+ interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8MQ_CLK_SAI2_IPG>,
+ <&clk IMX8MQ_CLK_DUMMY>,
+ <&clk IMX8MQ_CLK_SAI2_ROOT>,
+ <&clk IMX8MQ_CLK_DUMMY>, <&clk IMX8MQ_CLK_DUMMY>;
+ clock-names = "bus", "mclk0", "mclk1", "mclk2", "mclk3";
+ dmas = <&sdma1 10 24 0>, <&sdma1 11 24 0>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ sai3: sai@308c0000 {
+ compatible = "fsl,imx8mq-sai",
+ "fsl,imx6sx-sai";
+ reg = <0x0 0x308c0000 0x0 0x10000>;
+ interrupts = <GIC_SPI 50 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8MQ_CLK_SAI3_IPG>,
+ <&clk IMX8MQ_CLK_DUMMY>,
+ <&clk IMX8MQ_CLK_SAI3_ROOT>,
+ <&clk IMX8MQ_CLK_DUMMY>, <&clk IMX8MQ_CLK_DUMMY>;
+ clock-names = "bus", "mclk0", "mclk1", "mclk2", "mclk3";
+ dmas = <&sdma1 12 24 0>, <&sdma1 13 24 0>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ sdma1: sdma@30bd0000 {
+ compatible = "fsl,imx8mq-sdma", "fsl,imx7d-sdma";
+ reg = <0x0 0x30bd0000 0x0 0x10000>;
+ interrupts = <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8MQ_CLK_SDMA1_ROOT>,
+ <&clk IMX8MQ_CLK_SDMA1_ROOT>;
+ clock-names = "ipg", "ahb";
+ #dma-cells = <3>;
+ fsl,sdma-ram-script-name = "imx/sdma/sdma-imx7d.bin";
+ status = "okay";
+ };
+
+ sdma2: sdma@302c0000 {
+ compatible = "fsl,imx8mq-sdma", "fsl,imx7d-sdma";
+ reg = <0x0 0x302c0000 0x0 0x10000>;
+ interrupts = <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8MQ_CLK_SDMA2_ROOT>,
+ <&clk IMX8MQ_CLK_SDMA2_ROOT>;
+ clock-names = "ipg", "ahb";
+ #dma-cells = <3>;
+ fsl,sdma-ram-script-name = "imx/sdma/sdma-imx7d.bin";
+ fsl,ratio-1-1;
+ status = "okay";
+ };
+
+ fec1: ethernet@30be0000 {
+ compatible = "fsl,imx8mq-fec", "fsl,imx6sx-fec";
+ reg = <0x0 0x30be0000 0x0 0x10000>;
+ interrupts = <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8MQ_CLK_ENET1_ROOT>,
+ <&clk IMX8MQ_CLK_ENET1_ROOT>,
+ <&clk IMX8MQ_CLK_ENET_TIMER>,
+ <&clk IMX8MQ_CLK_ENET_REF>,
+ <&clk IMX8MQ_CLK_ENET_PHY_REF>;
+ clock-names = "ipg", "ahb", "ptp",
+ "enet_clk_ref", "enet_out";
+ assigned-clocks = <&clk IMX8MQ_CLK_ENET_AXI>,
+ <&clk IMX8MQ_CLK_ENET_TIMER>,
+ <&clk IMX8MQ_CLK_ENET_REF>,
+ <&clk IMX8MQ_CLK_ENET_TIMER>;
+ assigned-clock-parents = <&clk IMX8MQ_SYS1_PLL_266M>,
+ <&clk IMX8MQ_SYS2_PLL_100M>,
+ <&clk IMX8MQ_SYS2_PLL_125M>;
+ assigned-clock-rates = <0>, <0>, <125000000>, <100000000>;
+ stop-mode = <&gpr 0x10 3>;
+ fsl,num-tx-queues=<3>;
+ fsl,num-rx-queues=<3>;
+ fsl,wakeup_irq = <2>;
+ status = "disabled";
+ };
+
+ gpu: gpu@38000000 {
+ compatible = "fsl,imx8mq-gpu", "fsl,imx6q-gpu";
+ reg = <0x0 0x38000000 0 0x40000>, <0x0 0x40000000 0x0 0xC0000000>, <0x0 0x0 0x0 0x10000000>;
+ reg-names = "iobase_3d", "phys_baseaddr", "contiguous_mem";
+ interrupts = <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "irq_3d";
+ clocks = <&clk IMX8MQ_CLK_GPU_ROOT>, <&clk IMX8MQ_CLK_GPU_SHADER_DIV>, <&clk IMX8MQ_CLK_GPU_AXI>, <&clk IMX8MQ_CLK_GPU_AHB>;
+ clock-names = "gpu3d_clk", "gpu3d_shader_clk", "gpu3d_axi_clk", "gpu3d_ahb_clk";
+ assigned-clocks = <&clk IMX8MQ_CLK_GPU_CORE_SRC>, <&clk IMX8MQ_CLK_GPU_SHADER_SRC>, <&clk IMX8MQ_CLK_GPU_AXI>, <&clk IMX8MQ_CLK_GPU_AHB>;
+ assigned-clock-parents = <&clk IMX8MQ_GPU_PLL_OUT>, <&clk IMX8MQ_GPU_PLL_OUT>, <&clk IMX8MQ_GPU_PLL_OUT>, <&clk IMX8MQ_GPU_PLL_OUT>;
+ assigned-clock-rates = <800000000>, <800000000>, <800000000>, <800000000>;
+ power-domains = <&gpu_pd>;
+ status = "disabled";
+ };
+
+ imx_ion: imx_ion {
+ compatible = "fsl,mxc-ion";
+ fsl,heap-id = <0>;
+ };
+
+ i2c1: i2c@30a20000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx21-i2c";
+ reg = <0x0 0x30a20000 0x0 0x10000>;
+ interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8MQ_CLK_I2C1_ROOT>;
+ status = "disabled";
+ };
+
+ i2c2: i2c@30a30000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx21-i2c";
+ reg = <0x0 0x30a30000 0x0 0x10000>;
+ interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8MQ_CLK_I2C2_ROOT>;
+ status = "disabled";
+ };
+
+ i2c3: i2c@30a40000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx21-i2c";
+ reg = <0x0 0x30a40000 0x0 0x10000>;
+ interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8MQ_CLK_I2C3_ROOT>;
+ status = "disabled";
+ };
+
+ i2c4: i2c@30a50000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx21-i2c";
+ reg = <0x0 0x30a50000 0x0 0x10000>;
+ interrupts = <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8MQ_CLK_I2C4_ROOT>;
+ status = "disabled";
+ };
+
+ vpu: vpu@38300000 {
+ compatible = "nxp,imx8mq-hantro";
+ reg = <0x0 0x38300000 0x0 0x200000>;
+ reg-names = "regs_hantro";
+ interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "irq_hantro_g1", "irq_hantro_g2";
+ clocks = <&clk IMX8MQ_CLK_VPU_G1_ROOT>, <&clk IMX8MQ_CLK_VPU_G2_ROOT>, <&clk IMX8MQ_CLK_VPU_DEC_ROOT>;
+ clock-names = "clk_hantro_g1", "clk_hantro_g2", "clk_hantro_bus";
+ assigned-clocks = <&clk IMX8MQ_CLK_VPU_G1>, <&clk IMX8MQ_CLK_VPU_G2>, <&clk IMX8MQ_CLK_VPU_BUS>;
+ assigned-clock-parents = <&clk IMX8MQ_VPU_PLL_OUT>, <&clk IMX8MQ_VPU_PLL_OUT>, <&clk IMX8MQ_SYS1_PLL_800M>;
+ assigned-clock-rates = <600000000>, <600000000>, <800000000>;
+ power-domains = <&vpu_pd>;
+ regulator-supply = <&sw1c_reg>;
+ status = "disabled";
+ };
+
+ wdog1: wdog@30280000 {
+ compatible = "fsl,imx21-wdt";
+ reg = <0 0x30280000 0 0x10000>;
+ interrupts = <GIC_SPI 78 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8MQ_CLK_WDOG1_ROOT>;
+ status = "disabled";
+ };
+
+ wdog2: wdog@30290000 {
+ compatible = "fsl,imx21-wdt";
+ reg = <0 0x30290000 0 0x10000>;
+ interrupts = <GIC_SPI 79 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8MQ_CLK_WDOG2_ROOT>;
+ status = "disabled";
+ };
+
+ wdog3: wdog@302a0000 {
+ compatible = "fsl,imx21-wdt";
+ reg = <0 0x302a0000 0 0x10000>;
+ interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8MQ_CLK_WDOG3_ROOT>;
+ status = "disabled";
+ };
+
+ dma_cap: dma_cap {
+ compatible = "dma-capability";
+ only-dma-mask32 = <1>;
+ };
+
+ qspi: qspi@30bb0000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx7d-qspi";
+ reg = <0 0x30bb0000 0 0x10000>, <0 0x08000000 0 0x10000000>;
+ reg-names = "QuadSPI", "QuadSPI-memory";
+ interrupts = <GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8MQ_CLK_QSPI_ROOT>,
+ <&clk IMX8MQ_CLK_QSPI_ROOT>;
+ clock-names = "qspi_en", "qspi";
+ status = "disabled";
+ };
+
+ pcie0: pcie@0x33800000 {
+ compatible = "fsl,imx8mq-pcie", "snps,dw-pcie";
+ reg = <0x0 0x33800000 0x0 0x400000>, <0x0 0x1ff00000 0x0 0x80000>;
+ reg-names = "dbi", "config";
+ reserved-region = <&rpmsg_reserved>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ device_type = "pci";
+ ranges = <0x81000000 0 0x00000000 0x0 0x1ff80000 0 0x00010000 /* downstream I/O 64KB */
+ 0x82000000 0 0x18000000 0x0 0x18000000 0 0x07f00000>; /* non-prefetchable memory */
+ num-lanes = <1>;
+ interrupts = <GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 127 IRQ_TYPE_LEVEL_HIGH>; /* eDMA */
+ interrupt-names = "msi";
+ #interrupt-cells = <1>;
+ interrupt-map-mask = <0 0 0 0x7>;
+ interrupt-map = <0 0 0 1 &gic GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>,
+ <0 0 0 2 &gic GIC_SPI 124 IRQ_TYPE_LEVEL_HIGH>,
+ <0 0 0 3 &gic GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>,
+ <0 0 0 4 &gic GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8MQ_CLK_PCIE1_ROOT>,
+ <&clk IMX8MQ_CLK_PCIE1_AUX>,
+ <&clk IMX8MQ_CLK_PCIE1_PHY>;
+ clock-names = "pcie", "pcie_bus", "pcie_phy";
+ fsl,max-link-speed = <2>;
+ ctrl-id = <0>;
+ power-domains = <&pcie0_pd>;
+ status = "disabled";
+ };
+
+ pcie1: pcie@0x33c00000 {
+ compatible = "fsl,imx8mq-pcie", "snps,dw-pcie";
+ reg = <0x0 0x33c00000 0x0 0x400000>, <0x0 0x27f00000 0x0 0x80000>;
+ reg-names = "dbi", "config";
+ reserved-region = <&rpmsg_reserved>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ device_type = "pci";
+ ranges = <0x81000000 0 0x00000000 0x0 0x27f80000 0 0x00010000 /* downstream I/O 64KB */
+ 0x82000000 0 0x20000000 0x0 0x20000000 0 0x07f00000>; /* non-prefetchable memory */
+ num-lanes = <1>;
+ interrupts = <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 80 IRQ_TYPE_LEVEL_HIGH>; /* eDMA */
+ interrupt-names = "msi";
+ #interrupt-cells = <1>;
+ interrupt-map-mask = <0 0 0 0x7>;
+ interrupt-map = <0 0 0 1 &gic GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>,
+ <0 0 0 2 &gic GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>,
+ <0 0 0 3 &gic GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH>,
+ <0 0 0 4 &gic GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8MQ_CLK_PCIE2_ROOT>,
+ <&clk IMX8MQ_CLK_PCIE2_AUX>,
+ <&clk IMX8MQ_CLK_PCIE2_PHY>;
+ clock-names = "pcie", "pcie_bus", "pcie_phy";
+ fsl,max-link-speed = <2>;
+ ctrl-id = <1>;
+ power-domains = <&pcie1_pd>;
+ status = "disabled";
+ };
+
+ ddr_pmu0: ddr_pmu@3d800000 {
+ compatible = "fsl,imx8-ddr-pmu";
+ reg = <0x0 0x3d800000 0x0 0x400000>;
+ interrupts = <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ imx_rpmsg: imx_rpmsg {
+ compatible = "fsl,rpmsg-bus", "simple-bus";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ rpmsg: rpmsg{
+ compatible = "fsl,imx8mq-rpmsg";
+ status = "disabled";
+ };
+ };
+
+ crypto: caam@30900000 {
+ compatible = "fsl,sec-v4.0";
+ #address-cells = <0x1>;
+ #size-cells = <0x1>;
+ reg = <0 0x30900000 0 0x40000>;
+ ranges = <0 0 0x30900000 0x40000>;
+ interrupts = <GIC_SPI 91 IRQ_TYPE_LEVEL_HIGH>;
+
+ sec_jr0: jr0@1000 {
+ compatible = "fsl,sec-v4.0-job-ring";
+ reg = <0x1000 0x1000>;
+ interrupts = <GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ sec_jr1: jr1@2000 {
+ compatible = "fsl,sec-v4.0-job-ring";
+ reg = <0x2000 0x1000>;
+ interrupts = <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ sec_jr2: jr2@3000 {
+ compatible = "fsl,sec-v4.0-job-ring";
+ reg = <0x3000 0x1000>;
+ interrupts = <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>;
+ };
+ };
+
+ caam_sm: caam-sm@00100000 {
+ compatible = "fsl,imx6q-caam-sm";
+ reg = <0 0x00100000 0 0x8000>;
+ };
+
+ caam_snvs: caam-snvs@30370000 {
+ compatible = "fsl,imx6q-caam-snvs";
+ reg = <0 0x30370000 0 0x10000>;
+ };
+
+ irq_sec_vio: caam_secvio {
+ compatible = "fsl,imx7d-caam-secvio", "fsl,imx6q-caam-secvio";
+ interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
+ jtag-tamper = "disabled";
+ watchdog-tamper = "enabled";
+ internal-boot-tamper = "enabled";
+ external-pin-tamper = "disabled";
+ };
+
+ dma_apbh: dma-apbh@33000000 {
+ compatible = "fsl,imx7d-dma-apbh", "fsl,imx28-dma-apbh";
+ reg = <0 0x33000000 0 0x2000>;
+ interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "gpmi0", "gpmi1", "gpmi2", "gpmi3";
+ #dma-cells = <1>;
+ dma-channels = <4>;
+ clocks = <&clk IMX8MQ_CLK_NAND_USDHC_BUS_RAWNAND_CLK>;
+ };
+
+ gpmi: gpmi-nand@33002000{
+ compatible = "fsl,imx7d-gpmi-nand";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0 0x33002000 0 0x2000>, <0 0x33004000 0 0x4000>;
+ reg-names = "gpmi-nand", "bch";
+ interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "bch";
+ clocks = <&clk IMX8MQ_CLK_RAWNAND_ROOT>,
+ <&clk IMX8MQ_CLK_NAND_USDHC_BUS_RAWNAND_CLK>;
+ clock-names = "gpmi_io", "gpmi_bch_apb";
+ dmas = <&dma_apbh 0>;
+ dma-names = "rx-tx";
+ status = "disabled";
+ };
+};
+
+&A53_0 {
+ operating-points = <
+ /* kHz uV */
+ 1000000 900000
+ 800000 900000
+ >;
+ clocks = <&clk IMX8MQ_CLK_A53_DIV>, <&clk IMX8MQ_CLK_A53_SRC>,
+ <&clk IMX8MQ_ARM_PLL>, <&clk IMX8MQ_ARM_PLL_OUT>,
+ <&clk IMX8MQ_SYS1_PLL_800M>;
+ clock-names = "a53", "arm_a53_src", "arm_pll",
+ "arm_pll_out", "sys1_pll_800m";
+ clock-latency = <61036>;
+ #cooling-cells = <2>;
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8q-arm2.dtsi b/arch/arm64/boot/dts/freescale/fsl-imx8q-arm2.dtsi
new file mode 100644
index 000000000000..6415398f9545
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8q-arm2.dtsi
@@ -0,0 +1,1320 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2017~2018 NXP
+ *
+ * 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.
+ */
+
+/ {
+ chosen {
+ bootargs = "console=ttyLP0,115200 earlycon=lpuart32,0x5a060000,115200";
+ stdout-path = &lpuart0;
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpio_leds>;
+ user {
+ label = "heartbeat";
+ gpios = <&gpio2 15 0>;
+ default-state = "on";
+ linux,default-trigger = "heartbeat";
+ };
+ };
+
+ modem_reset: modem-reset {
+ compatible = "gpio-reset";
+ reset-gpios = <&pca9557_b 7 GPIO_ACTIVE_LOW>;
+ reset-delay-us = <2000>;
+ reset-post-delay-ms = <40>;
+ #reset-cells = <0>;
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ reg_audio: regulator@0 {
+ compatible = "regulator-fixed";
+ reg = <2>;
+ regulator-name = "cs42888_supply";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ reg_can_en: regulator-can-gen {
+ compatible = "regulator-fixed";
+ regulator-name = "can-en";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&pca9557_b 5 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ reg_can_stby: regulator-can-stby {
+ compatible = "regulator-fixed";
+ regulator-name = "can-stby";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&pca9557_b 4 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ vin-supply = <&reg_can_en>;
+ };
+
+ reg_fec2_supply: fec2_nvcc {
+ compatible = "regulator-fixed";
+ regulator-name = "fec2_nvcc";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ gpio = <&max7322 0 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ reg_usdhc2_vmmc: usdhc2_vmmc {
+ compatible = "regulator-fixed";
+ regulator-name = "sw-3p3-sd1";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&gpio4 7 GPIO_ACTIVE_HIGH>;
+ off-on-delay = <3000>;
+ enable-active-high;
+ };
+ };
+
+ sound-cs42888 {
+ compatible = "fsl,imx8qm-sabreauto-cs42888",
+ "fsl,imx-audio-cs42888";
+ model = "imx-cs42888";
+ esai-controller = <&esai0>;
+ audio-codec = <&codec>;
+ asrc-controller = <&asrc0>;
+ };
+
+ sound-amix-sai {
+ compatible = "fsl,imx-audio-amix";
+ model = "amix-audio-sai";
+ dais = <&sai6>, <&sai7>;
+ amix-controller = <&amix>;
+ };
+
+ lvds_backlight0: lvds_backlight@0 {
+ compatible = "pwm-backlight";
+ pwms = <&lvds0_pwm 0 100000 0>;
+
+ brightness-levels = < 0 1 2 3 4 5 6 7 8 9
+ 10 11 12 13 14 15 16 17 18 19
+ 20 21 22 23 24 25 26 27 28 29
+ 30 31 32 33 34 35 36 37 38 39
+ 40 41 42 43 44 45 46 47 48 49
+ 50 51 52 53 54 55 56 57 58 59
+ 60 61 62 63 64 65 66 67 68 69
+ 70 71 72 73 74 75 76 77 78 79
+ 80 81 82 83 84 85 86 87 88 89
+ 90 91 92 93 94 95 96 97 98 99
+ 100>;
+ default-brightness-level = <80>;
+ };
+
+ lvds_backlight1: lvds_backlight@1 {
+ compatible = "pwm-backlight";
+ pwms = <&lvds1_pwm 0 100000 0>;
+
+ brightness-levels = < 0 1 2 3 4 5 6 7 8 9
+ 10 11 12 13 14 15 16 17 18 19
+ 20 21 22 23 24 25 26 27 28 29
+ 30 31 32 33 34 35 36 37 38 39
+ 40 41 42 43 44 45 46 47 48 49
+ 50 51 52 53 54 55 56 57 58 59
+ 60 61 62 63 64 65 66 67 68 69
+ 70 71 72 73 74 75 76 77 78 79
+ 80 81 82 83 84 85 86 87 88 89
+ 90 91 92 93 94 95 96 97 98 99
+ 100>;
+ default-brightness-level = <80>;
+ };
+};
+
+&acm {
+ status = "okay";
+};
+
+&amix {
+ status = "okay";
+};
+
+&asrc0 {
+ assigned-clocks = <&clk IMX8QM_AUD_PLL0_DIV>,
+ <&clk IMX8QM_AUD_ACM_AUD_PLL_CLK0_DIV>,
+ <&clk IMX8QM_AUD_ACM_AUD_REC_CLK0_DIV>;
+ assigned-clock-rates = <786432000>, <49152000>, <24576000>;
+ fsl,asrc-rate = <48000>;
+ status = "okay";
+};
+
+&asrc1 {
+ fsl,asrc-rate = <48000>;
+ assigned-clocks = <&clk IMX8QM_AUD_PLL0_DIV>,
+ <&clk IMX8QM_AUD_ACM_AUD_PLL_CLK0_DIV>,
+ <&clk IMX8QM_AUD_ACM_AUD_REC_CLK0_DIV>;
+ assigned-clock-rates = <786432000>, <49152000>, <24576000>;
+ status = "okay";
+};
+
+&esai0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_esai0>;
+ assigned-clocks = <&clk IMX8QM_ACM_ESAI0_MCLK_SEL>,
+ <&clk IMX8QM_AUD_PLL0_DIV>,
+ <&clk IMX8QM_AUD_ACM_AUD_PLL_CLK0_DIV>,
+ <&clk IMX8QM_AUD_ACM_AUD_REC_CLK0_DIV>,
+ <&clk IMX8QM_AUD_ESAI_0_EXTAL_IPG>;
+ assigned-clock-parents = <&clk IMX8QM_AUD_ACM_AUD_PLL_CLK0_CLK>;
+ assigned-clock-rates = <0>, <786432000>, <49152000>, <24576000>, <49152000>;
+ status = "okay";
+};
+
+&sai_hdmi_tx {
+ assigned-clocks =<&clk IMX8QM_ACM_HDMI_TX_SAI0_MCLK_SEL>,
+ <&clk IMX8QM_AUD_PLL0_DIV>,
+ <&clk IMX8QM_AUD_ACM_AUD_PLL_CLK0_DIV>,
+ <&clk IMX8QM_AUD_ACM_AUD_REC_CLK0_DIV>,
+ <&clk IMX8QM_AUD_SAI_HDMITX0_MCLK>;
+ assigned-clock-parents = <&clk IMX8QM_AUD_ACM_AUD_PLL_CLK0_CLK>;
+ assigned-clock-rates = <0>, <786432000>, <49152000>, <24576000>, <49152000>;
+ fsl,sai-asynchronous;
+ status = "okay";
+};
+
+&sai6 {
+ assigned-clocks = <&clk IMX8QM_ACM_SAI6_MCLK_SEL>,
+ <&clk IMX8QM_AUD_PLL1_DIV>,
+ <&clk IMX8QM_AUD_ACM_AUD_PLL_CLK1_DIV>,
+ <&clk IMX8QM_AUD_ACM_AUD_REC_CLK1_DIV>,
+ <&clk IMX8QM_AUD_SAI_6_MCLK>;
+ assigned-clock-parents = <&clk IMX8QM_AUD_ACM_AUD_PLL_CLK1_CLK>;
+ assigned-clock-rates = <0>, <786432000>, <98304000>, <24576000>, <98304000>;
+ fsl,sai-asynchronous;
+ fsl,txm-rxs;
+ status = "okay";
+};
+
+&sai7 {
+ assigned-clocks = <&clk IMX8QM_ACM_SAI7_MCLK_SEL>,
+ <&clk IMX8QM_AUD_PLL1_DIV>,
+ <&clk IMX8QM_AUD_ACM_AUD_PLL_CLK1_DIV>,
+ <&clk IMX8QM_AUD_ACM_AUD_REC_CLK1_DIV>,
+ <&clk IMX8QM_AUD_SAI_7_MCLK>;
+ assigned-clock-parents = <&clk IMX8QM_AUD_ACM_AUD_PLL_CLK1_CLK>;
+ assigned-clock-rates = <0>, <786432000>, <98304000>, <24576000>, <98304000>;
+ fsl,sai-asynchronous;
+ fsl,txm-rxs;
+ status = "okay";
+};
+
+&iomuxc {
+ imx8qm-arm2 {
+
+ pinctrl_esai0: esai0grp {
+ fsl,pins = <
+ SC_P_ESAI0_FSR_AUD_ESAI0_FSR 0xc6000040
+ SC_P_ESAI0_FST_AUD_ESAI0_FST 0xc6000040
+ SC_P_ESAI0_SCKR_AUD_ESAI0_SCKR 0xc6000040
+ SC_P_ESAI0_SCKT_AUD_ESAI0_SCKT 0xc6000040
+ SC_P_ESAI0_TX0_AUD_ESAI0_TX0 0xc6000040
+ SC_P_ESAI0_TX1_AUD_ESAI0_TX1 0xc6000040
+ SC_P_ESAI0_TX2_RX3_AUD_ESAI0_TX2_RX3 0xc6000040
+ SC_P_ESAI0_TX3_RX2_AUD_ESAI0_TX3_RX2 0xc6000040
+ SC_P_ESAI0_TX4_RX1_AUD_ESAI0_TX4_RX1 0xc6000040
+ SC_P_ESAI0_TX5_RX0_AUD_ESAI0_TX5_RX0 0xc6000040
+ SC_P_MCLK_OUT0_AUD_ACM_MCLK_OUT0 0xc6000040
+ >;
+ };
+
+ pinctrl_fec1: fec1grp {
+ fsl,pins = <
+ SC_P_COMP_CTL_GPIO_1V8_3V3_ENET_ENETB_PAD 0x000014a0
+ SC_P_ENET0_MDC_CONN_ENET0_MDC 0x06000020
+ SC_P_ENET0_MDIO_CONN_ENET0_MDIO 0x06000020
+ SC_P_ENET0_RGMII_TX_CTL_CONN_ENET0_RGMII_TX_CTL 0x00000060
+ SC_P_ENET0_RGMII_TXC_CONN_ENET0_RGMII_TXC 0x00000060
+ SC_P_ENET0_RGMII_TXD0_CONN_ENET0_RGMII_TXD0 0x00000060
+ SC_P_ENET0_RGMII_TXD1_CONN_ENET0_RGMII_TXD1 0x00000060
+ SC_P_ENET0_RGMII_TXD2_CONN_ENET0_RGMII_TXD2 0x00000060
+ SC_P_ENET0_RGMII_TXD3_CONN_ENET0_RGMII_TXD3 0x00000060
+ SC_P_ENET0_RGMII_RXC_CONN_ENET0_RGMII_RXC 0x00000060
+ SC_P_ENET0_RGMII_RX_CTL_CONN_ENET0_RGMII_RX_CTL 0x00000060
+ SC_P_ENET0_RGMII_RXD0_CONN_ENET0_RGMII_RXD0 0x00000060
+ SC_P_ENET0_RGMII_RXD1_CONN_ENET0_RGMII_RXD1 0x00000060
+ SC_P_ENET0_RGMII_RXD2_CONN_ENET0_RGMII_RXD2 0x00000060
+ SC_P_ENET0_RGMII_RXD3_CONN_ENET0_RGMII_RXD3 0x00000060
+ >;
+ };
+
+ pinctrl_fec2: fec2grp {
+ fsl,pins = <
+ SC_P_COMP_CTL_GPIO_1V8_3V3_ENET_ENETA_PAD 0x000014a0
+ SC_P_ENET1_MDC_CONN_ENET1_MDC 0x06000020
+ SC_P_ENET1_MDIO_CONN_ENET1_MDIO 0x06000020
+ SC_P_ENET1_RGMII_TX_CTL_CONN_ENET1_RGMII_TX_CTL 0x00000060
+ SC_P_ENET1_RGMII_TXC_CONN_ENET1_RGMII_TXC 0x00000060
+ SC_P_ENET1_RGMII_TXD0_CONN_ENET1_RGMII_TXD0 0x00000060
+ SC_P_ENET1_RGMII_TXD1_CONN_ENET1_RGMII_TXD1 0x00000060
+ SC_P_ENET1_RGMII_TXD2_CONN_ENET1_RGMII_TXD2 0x00000060
+ SC_P_ENET1_RGMII_TXD3_CONN_ENET1_RGMII_TXD3 0x00000060
+ SC_P_ENET1_RGMII_RXC_CONN_ENET1_RGMII_RXC 0x00000060
+ SC_P_ENET1_RGMII_RX_CTL_CONN_ENET1_RGMII_RX_CTL 0x00000060
+ SC_P_ENET1_RGMII_RXD0_CONN_ENET1_RGMII_RXD0 0x00000060
+ SC_P_ENET1_RGMII_RXD1_CONN_ENET1_RGMII_RXD1 0x00000060
+ SC_P_ENET1_RGMII_RXD2_CONN_ENET1_RGMII_RXD2 0x00000060
+ SC_P_ENET1_RGMII_RXD3_CONN_ENET1_RGMII_RXD3 0x00000060
+ >;
+ };
+
+ pinctrl_lvds0_lpi2c1: lvds0lpi2c1grp {
+ fsl,pins = <
+ SC_P_LVDS0_I2C1_SCL_LVDS0_I2C1_SCL 0xc600004c
+ SC_P_LVDS0_I2C1_SDA_LVDS0_I2C1_SDA 0xc600004c
+ >;
+ };
+
+ pinctrl_lvds1_lpi2c1: lvds1lpi2c1grp {
+ fsl,pins = <
+ SC_P_LVDS1_I2C1_SCL_LVDS1_I2C1_SCL 0xc600004c
+ SC_P_LVDS1_I2C1_SDA_LVDS1_I2C1_SDA 0xc600004c
+ >;
+ };
+
+ pinctrl_hdmi_lpi2c0: hdmilpi2c0grp {
+ fsl,pins = <
+ SC_P_HDMI_TX0_TS_SCL_HDMI_TX0_I2C0_SCL 0xc600004c
+ SC_P_HDMI_TX0_TS_SDA_HDMI_TX0_I2C0_SDA 0xc600004c
+ >;
+ };
+
+ pinctrl_mipi0_lpi2c0: mipi0_lpi2c0grp {
+ fsl,pins = <
+ SC_P_MIPI_DSI0_I2C0_SCL_MIPI_DSI0_I2C0_SCL 0xc600004c
+ SC_P_MIPI_DSI0_I2C0_SDA_MIPI_DSI0_I2C0_SDA 0xc600004c
+ >;
+ };
+
+ pinctrl_mipi1_lpi2c0: mipi1_lpi2c0grp {
+ fsl,pins = <
+ SC_P_MIPI_DSI1_I2C0_SCL_MIPI_DSI1_I2C0_SCL 0xc600004c
+ SC_P_MIPI_DSI1_I2C0_SDA_MIPI_DSI1_I2C0_SDA 0xc600004c
+ >;
+ };
+
+ pinctrl_mipi_dsi_0_1_en: mipi_dsi_0_1_en {
+ fsl,pins = <
+ SC_P_LVDS0_I2C0_SDA_LSIO_GPIO1_IO07 0x00000021
+ >;
+ };
+
+ pinctrl_lpi2c0: lpi2c0grp {
+ fsl,pins = <
+ SC_P_HDMI_TX0_TS_SCL_DMA_I2C0_SCL 0xc600004c
+ SC_P_HDMI_TX0_TS_SDA_DMA_I2C0_SDA 0xc600004c
+ >;
+ };
+
+ pinctrl_lpi2c1: lpi2c1grp {
+ fsl,pins = <
+ SC_P_GPT0_CLK_DMA_I2C1_SCL 0xc600004c
+ SC_P_GPT0_CAPTURE_DMA_I2C1_SDA 0xc600004c
+ >;
+ };
+
+ pinctrl_lpi2c2: lpi2c2grp {
+ fsl,pins = <
+ SC_P_GPT1_CLK_DMA_I2C2_SCL 0xc600004c
+ SC_P_GPT1_CAPTURE_DMA_I2C2_SDA 0xc600004c
+ >;
+ };
+
+ pinctrl_lpuart0: lpuart0grp {
+ fsl,pins = <
+ SC_P_UART0_RX_DMA_UART0_RX 0x06000020
+ SC_P_UART0_TX_DMA_UART0_TX 0x06000020
+ >;
+ };
+
+ pinctrl_lpuart1: lpuart1grp {
+ fsl,pins = <
+ SC_P_UART1_RX_DMA_UART1_RX 0x06000020
+ SC_P_UART1_TX_DMA_UART1_TX 0x06000020
+ SC_P_UART1_CTS_B_DMA_UART1_CTS_B 0x06000020
+ SC_P_UART1_RTS_B_DMA_UART1_RTS_B 0x06000020
+ >;
+ };
+
+ pinctrl_lpuart3: lpuart3grp {
+ fsl,pins = <
+ SC_P_M41_GPIO0_00_DMA_UART3_RX 0x06000020
+ SC_P_M41_GPIO0_01_DMA_UART3_TX 0x06000020
+ >;
+ };
+
+ pinctrl_mlb: mlbgrp {
+ fsl,pins = <
+ SC_P_MLB_SIG_CONN_MLB_SIG 0x21
+ SC_P_MLB_CLK_CONN_MLB_CLK 0x21
+ SC_P_MLB_DATA_CONN_MLB_DATA 0x21
+ >;
+ };
+
+ pinctrl_isl29023: isl29023grp {
+ fsl,pins = <
+ SC_P_ADC_IN2_LSIO_GPIO3_IO20 0x00000021
+ >;
+ };
+
+ pinctrl_usdhc1: usdhc1grp {
+ fsl,pins = <
+ SC_P_EMMC0_CLK_CONN_EMMC0_CLK 0x06000041
+ SC_P_EMMC0_CMD_CONN_EMMC0_CMD 0x00000021
+ SC_P_EMMC0_DATA0_CONN_EMMC0_DATA0 0x00000021
+ SC_P_EMMC0_DATA1_CONN_EMMC0_DATA1 0x00000021
+ SC_P_EMMC0_DATA2_CONN_EMMC0_DATA2 0x00000021
+ SC_P_EMMC0_DATA3_CONN_EMMC0_DATA3 0x00000021
+ SC_P_EMMC0_DATA4_CONN_EMMC0_DATA4 0x00000021
+ SC_P_EMMC0_DATA5_CONN_EMMC0_DATA5 0x00000021
+ SC_P_EMMC0_DATA6_CONN_EMMC0_DATA6 0x00000021
+ SC_P_EMMC0_DATA7_CONN_EMMC0_DATA7 0x00000021
+ SC_P_EMMC0_STROBE_CONN_EMMC0_STROBE 0x00000041
+ SC_P_EMMC0_RESET_B_CONN_EMMC0_RESET_B 0x00000021
+ >;
+ };
+
+ pinctrl_usdhc1_100mhz: usdhc1grp100mhz {
+ fsl,pins = <
+ SC_P_EMMC0_CLK_CONN_EMMC0_CLK 0x06000040
+ SC_P_EMMC0_CMD_CONN_EMMC0_CMD 0x00000020
+ SC_P_EMMC0_DATA0_CONN_EMMC0_DATA0 0x00000020
+ SC_P_EMMC0_DATA1_CONN_EMMC0_DATA1 0x00000020
+ SC_P_EMMC0_DATA2_CONN_EMMC0_DATA2 0x00000020
+ SC_P_EMMC0_DATA3_CONN_EMMC0_DATA3 0x00000020
+ SC_P_EMMC0_DATA4_CONN_EMMC0_DATA4 0x00000020
+ SC_P_EMMC0_DATA5_CONN_EMMC0_DATA5 0x00000020
+ SC_P_EMMC0_DATA6_CONN_EMMC0_DATA6 0x00000020
+ SC_P_EMMC0_DATA7_CONN_EMMC0_DATA7 0x00000020
+ SC_P_EMMC0_STROBE_CONN_EMMC0_STROBE 0x00000040
+ SC_P_EMMC0_RESET_B_CONN_EMMC0_RESET_B 0x00000020
+ >;
+ };
+
+ pinctrl_usdhc1_200mhz: usdhc1grp200mhz {
+ fsl,pins = <
+ SC_P_EMMC0_CLK_CONN_EMMC0_CLK 0x06000040
+ SC_P_EMMC0_CMD_CONN_EMMC0_CMD 0x00000020
+ SC_P_EMMC0_DATA0_CONN_EMMC0_DATA0 0x00000020
+ SC_P_EMMC0_DATA1_CONN_EMMC0_DATA1 0x00000020
+ SC_P_EMMC0_DATA2_CONN_EMMC0_DATA2 0x00000020
+ SC_P_EMMC0_DATA3_CONN_EMMC0_DATA3 0x00000020
+ SC_P_EMMC0_DATA4_CONN_EMMC0_DATA4 0x00000020
+ SC_P_EMMC0_DATA5_CONN_EMMC0_DATA5 0x00000020
+ SC_P_EMMC0_DATA6_CONN_EMMC0_DATA6 0x00000020
+ SC_P_EMMC0_DATA7_CONN_EMMC0_DATA7 0x00000020
+ SC_P_EMMC0_STROBE_CONN_EMMC0_STROBE 0x00000040
+ SC_P_EMMC0_RESET_B_CONN_EMMC0_RESET_B 0x00000020
+ >;
+ };
+
+ pinctrl_usdhc2_gpio: usdhc2grpgpio {
+ fsl,pins = <
+ SC_P_USDHC1_DATA6_LSIO_GPIO5_IO21 0x00000021
+ SC_P_USDHC1_DATA7_LSIO_GPIO5_IO22 0x00000021
+ SC_P_USDHC1_RESET_B_LSIO_GPIO4_IO07 0x00000021
+ >;
+ };
+
+ pinctrl_usdhc2: usdhc2grp {
+ fsl,pins = <
+ SC_P_USDHC1_CLK_CONN_USDHC1_CLK 0x06000041
+ SC_P_USDHC1_CMD_CONN_USDHC1_CMD 0x00000021
+ SC_P_USDHC1_DATA0_CONN_USDHC1_DATA0 0x00000021
+ SC_P_USDHC1_DATA1_CONN_USDHC1_DATA1 0x00000021
+ SC_P_USDHC1_DATA2_CONN_USDHC1_DATA2 0x00000021
+ SC_P_USDHC1_DATA3_CONN_USDHC1_DATA3 0x00000021
+ SC_P_USDHC1_VSELECT_CONN_USDHC1_VSELECT 0x00000021
+ >;
+ };
+
+ pinctrl_usdhc2_100mhz: usdhc2grp100mhz {
+ fsl,pins = <
+ SC_P_USDHC1_CLK_CONN_USDHC1_CLK 0x06000040
+ SC_P_USDHC1_CMD_CONN_USDHC1_CMD 0x00000020
+ SC_P_USDHC1_DATA0_CONN_USDHC1_DATA0 0x00000020
+ SC_P_USDHC1_DATA1_CONN_USDHC1_DATA1 0x00000020
+ SC_P_USDHC1_DATA2_CONN_USDHC1_DATA2 0x00000020
+ SC_P_USDHC1_DATA3_CONN_USDHC1_DATA3 0x00000020
+ SC_P_USDHC1_VSELECT_CONN_USDHC1_VSELECT 0x00000020
+ >;
+ };
+
+ pinctrl_usdhc2_200mhz: usdhc2grp200mhz {
+ fsl,pins = <
+ SC_P_USDHC1_CLK_CONN_USDHC1_CLK 0x06000040
+ SC_P_USDHC1_CMD_CONN_USDHC1_CMD 0x00000020
+ SC_P_USDHC1_DATA0_CONN_USDHC1_DATA0 0x00000020
+ SC_P_USDHC1_DATA1_CONN_USDHC1_DATA1 0x00000020
+ SC_P_USDHC1_DATA2_CONN_USDHC1_DATA2 0x00000020
+ SC_P_USDHC1_DATA3_CONN_USDHC1_DATA3 0x00000020
+ SC_P_USDHC1_VSELECT_CONN_USDHC1_VSELECT 0x00000020
+ >;
+ };
+
+ pinctrl_flexcan1: flexcan0grp {
+ fsl,pins = <
+ SC_P_FLEXCAN0_TX_DMA_FLEXCAN0_TX 0x21
+ SC_P_FLEXCAN0_RX_DMA_FLEXCAN0_RX 0x21
+ >;
+ };
+
+ pinctrl_flexcan2: flexcan1grp {
+ fsl,pins = <
+ SC_P_FLEXCAN1_TX_DMA_FLEXCAN1_TX 0x21
+ SC_P_FLEXCAN1_RX_DMA_FLEXCAN1_RX 0x21
+ >;
+ };
+
+ pinctrl_flexcan3: flexcan2grp {
+ fsl,pins = <
+ SC_P_FLEXCAN2_TX_DMA_FLEXCAN2_TX 0x21
+ SC_P_FLEXCAN2_RX_DMA_FLEXCAN2_RX 0x21
+ >;
+ };
+
+ pinctrl_flexspi0: flexspi0grp {
+ fsl,pins = <
+ SC_P_QSPI0A_DATA0_LSIO_QSPI0A_DATA0 0x06000021
+ SC_P_QSPI0A_DATA1_LSIO_QSPI0A_DATA1 0x06000021
+ SC_P_QSPI0A_DATA2_LSIO_QSPI0A_DATA2 0x06000021
+ SC_P_QSPI0A_DATA3_LSIO_QSPI0A_DATA3 0x06000021
+ SC_P_QSPI0A_DQS_LSIO_QSPI0A_DQS 0x06000021
+ SC_P_QSPI0A_SS0_B_LSIO_QSPI0A_SS0_B 0x06000021
+ SC_P_QSPI0A_SS1_B_LSIO_QSPI0A_SS1_B 0x06000021
+ SC_P_QSPI0A_SCLK_LSIO_QSPI0A_SCLK 0x06000021
+ SC_P_QSPI0B_SCLK_LSIO_QSPI0B_SCLK 0x06000021
+ SC_P_QSPI0B_DATA0_LSIO_QSPI0B_DATA0 0x06000021
+ SC_P_QSPI0B_DATA1_LSIO_QSPI0B_DATA1 0x06000021
+ SC_P_QSPI0B_DATA2_LSIO_QSPI0B_DATA2 0x06000021
+ SC_P_QSPI0B_DATA3_LSIO_QSPI0B_DATA3 0x06000021
+ SC_P_QSPI0B_DQS_LSIO_QSPI0B_DQS 0x06000021
+ SC_P_QSPI0B_SS0_B_LSIO_QSPI0B_SS0_B 0x06000021
+ SC_P_QSPI0B_SS1_B_LSIO_QSPI0B_SS1_B 0x06000021
+ >;
+ };
+
+ pinctrl_gpio_leds: gpioledsgrp {
+ fsl,pins = <
+ SC_P_SPDIF0_TX_LSIO_GPIO2_IO15 0x00000021
+ >;
+ };
+
+ pinctrl_pciea: pcieagrp{
+ fsl,pins = <
+ SC_P_PCIE_CTRL0_CLKREQ_B_LSIO_GPIO4_IO27 0x06000021
+ SC_P_PCIE_CTRL0_WAKE_B_LSIO_GPIO4_IO28 0x04000021
+ SC_P_PCIE_CTRL0_PERST_B_LSIO_GPIO4_IO29 0x06000021
+ >;
+ };
+
+ pinctrl_pcieb: pciebgrp{
+ fsl,pins = <
+ SC_P_PCIE_CTRL1_CLKREQ_B_LSIO_GPIO4_IO30 0x06000021
+ SC_P_PCIE_CTRL1_WAKE_B_LSIO_GPIO4_IO31 0x04000021
+ SC_P_PCIE_CTRL1_PERST_B_LSIO_GPIO5_IO00 0x06000021
+ >;
+ };
+
+ pinctrl_usbotg1: usbotg1 {
+ fsl,pins = <
+ SC_P_USB_SS3_TC0_CONN_USB_OTG1_PWR 0x00000021
+ >;
+ };
+
+ pinctrl_lvds0_pwm0: lvds0pwm0grp {
+ fsl,pins = <
+ SC_P_LVDS0_GPIO00_LVDS0_PWM0_OUT 0x00000020
+ >;
+ };
+
+ pinctrl_lvds1_pwm0: lvds1pwm0grp {
+ fsl,pins = <
+ SC_P_LVDS1_GPIO00_LVDS1_PWM0_OUT 0x00000020
+ >;
+ };
+
+ pinctrl_mipi_csi0_gpio: mipicsi0gpiogrp{
+ fsl,pins = <
+ SC_P_MIPI_CSI0_GPIO0_00_MIPI_CSI0_GPIO0_IO00 0x00000021
+ SC_P_MIPI_CSI0_GPIO0_01_MIPI_CSI0_GPIO0_IO01 0x00000021
+ >;
+ };
+
+ pinctrl_mipi_csi1_gpio: mipicsi1gpiogrp{
+ fsl,pins = <
+ SC_P_MIPI_CSI1_GPIO0_00_MIPI_CSI1_GPIO0_IO00 0x00000021
+ SC_P_MIPI_CSI1_GPIO0_01_MIPI_CSI1_GPIO0_IO01 0x00000021
+ >;
+ };
+ };
+};
+
+&gpio2 {
+ status = "okay";
+};
+
+&gpio5 {
+ status = "okay";
+};
+
+&usdhc1 {
+ pinctrl-names = "default", "state_100mhz", "state_200mhz";
+ pinctrl-0 = <&pinctrl_usdhc1>;
+ pinctrl-1 = <&pinctrl_usdhc1_100mhz>;
+ pinctrl-2 = <&pinctrl_usdhc1_200mhz>;
+ bus-width = <8>;
+ non-removable;
+ status = "okay";
+};
+
+&usdhc2 {
+ pinctrl-names = "default", "state_100mhz", "state_200mhz";
+ pinctrl-0 = <&pinctrl_usdhc2>, <&pinctrl_usdhc2_gpio>;
+ pinctrl-1 = <&pinctrl_usdhc2_100mhz>, <&pinctrl_usdhc2_gpio>;
+ pinctrl-2 = <&pinctrl_usdhc2_200mhz>, <&pinctrl_usdhc2_gpio>;
+ bus-width = <4>;
+ cd-gpios = <&gpio5 22 GPIO_ACTIVE_LOW>;
+ wp-gpios = <&gpio5 21 GPIO_ACTIVE_HIGH>;
+ vmmc-supply = <&reg_usdhc2_vmmc>;
+ status = "okay";
+};
+
+&usbotg1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usbotg1>;
+ srp-disable;
+ hnp-disable;
+ adp-disable;
+ power-polarity-active-high;
+ disable-over-current;
+ status = "okay";
+};
+
+&usbotg3 {
+ dr_mode = "host";
+ status = "okay";
+};
+
+&fec1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_fec1>;
+ phy-mode = "rgmii-txid";
+ phy-handle = <&ethphy0>;
+ fsl,magic-packet;
+ fsl,rgmii_rxc_dly;
+ status = "okay";
+
+ mdio {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ethphy0: ethernet-phy@0 {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <0>;
+ at803x,eee-disabled;
+ at803x,vddio-1p8v;
+ };
+
+ ethphy1: ethernet-phy@1 {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <1>;
+ at803x,eee-disabled;
+ at803x,vddio-1p8v;
+ status = "disabled";
+ };
+ };
+};
+
+&fec2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_fec2>;
+ phy-mode = "rgmii-txid";
+ phy-handle = <&ethphy1>;
+ phy-supply = <&reg_fec2_supply>;
+ fsl,magic-packet;
+ fsl,rgmii_rxc_dly;
+ status = "okay";
+};
+
+&flexcan1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_flexcan1>;
+ xceiver-supply = <&reg_can_stby>;
+ status = "okay";
+};
+
+&flexcan2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_flexcan2>;
+ xceiver-supply = <&reg_can_stby>;
+ status = "okay";
+};
+
+&flexcan3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_flexcan3>;
+ xceiver-supply = <&reg_can_stby>;
+ status = "okay";
+};
+
+&flexspi0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_flexspi0>;
+ status = "okay";
+
+ flash0: mt35xu512aba@0 {
+ reg = <0>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "micron,mt35xu512aba";
+ spi-max-frequency = <133000000>;
+ spi-nor,ddr-quad-read-dummy = <8>;
+ };
+};
+
+&gpio0_mipi_csi0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_mipi_csi0_gpio>;
+ status = "okay";
+};
+
+&gpio0_mipi_csi1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_mipi_csi1_gpio>;
+ status = "okay";
+};
+
+&i2c0_mipi_csi0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ clock-frequency = <100000>;
+ status = "okay";
+
+ max9286_mipi@6A {
+ compatible = "maxim,max9286_mipi";
+ reg = <0x6A>;
+ clocks = <&clk IMX8QM_CLK_DUMMY>;
+ clock-names = "capture_mclk";
+ mclk = <27000000>;
+ mclk_source = <0>;
+ pwn-gpios = <&gpio0_mipi_csi0 0 GPIO_ACTIVE_HIGH>;
+ virtual-channel;
+ port {
+ max9286_0_ep: endpoint {
+ remote-endpoint = <&mipi_csi0_ep>;
+ data-lanes = <1 2 3 4>;
+ };
+ };
+ };
+};
+
+&i2c0_mipi_csi1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ clock-frequency = <100000>;
+ status = "disabled";
+
+ max9286_mipi@6A {
+ compatible = "maxim,max9286_mipi";
+ reg = <0x6A>;
+ clocks = <&clk IMX8QM_CLK_DUMMY>;
+ clock-names = "capture_mclk";
+ mclk = <27000000>;
+ mclk_source = <0>;
+ pwn-gpios = <&gpio0_mipi_csi1 0 GPIO_ACTIVE_HIGH>;
+ virtual-channel;
+ port {
+ max9286_1_ep: endpoint {
+ remote-endpoint = <&mipi_csi1_ep>;
+ data-lanes = <1 2 3 4>;
+ };
+ };
+ };
+};
+
+&i2c0_hdmi {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_hdmi_lpi2c0>;
+ clock-frequency = <100000>;
+ status = "disabled";
+};
+
+&i2c0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lpi2c0>;
+ clock-frequency = <100000>;
+ status = "okay";
+
+ codec: cs42888@48 {
+ compatible = "cirrus,cs42888";
+ reg = <0x48>;
+ clocks = <&clk IMX8QM_AUD_MCLKOUT0>;
+ clock-names = "mclk";
+ VA-supply = <&reg_audio>;
+ VD-supply = <&reg_audio>;
+ VLS-supply = <&reg_audio>;
+ VLC-supply = <&reg_audio>;
+ reset-gpio = <&pca9557_a 2 1>;
+ power-domains = <&pd_mclk_out0>;
+ };
+};
+
+&i2c1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lpi2c1>;
+ status = "okay";
+
+ pca9557_a: gpio@18 {
+ compatible = "nxp,pca9557";
+ reg = <0x18>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ pca9557_b: gpio@19 {
+ compatible = "nxp,pca9557";
+ reg = <0x19>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ pca9557_c: gpio@1b {
+ compatible = "nxp,pca9557";
+ reg = <0x1b>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ pca9557_d: gpio@1f {
+ compatible = "nxp,pca9557";
+ reg = <0x1f>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ fxas2100x@20 {
+ compatible = "fsl,fxas2100x";
+ reg = <0x20>;
+ };
+
+ fxos8700@1d {
+ compatible = "fsl,fxos8700";
+ reg = <0x1d>;
+ };
+
+ isl29023@44 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_isl29023>;
+ compatible = "fsl,isl29023";
+ reg = <0x44>;
+ rext = <499>;
+ interrupt-parent = <&gpio3>;
+ interrupts = <20 2>;
+ };
+
+ mpl3115@60 {
+ compatible = "fsl,mpl3115";
+ reg = <0x60>;
+ };
+};
+
+&i2c2 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lpi2c2>;
+ status = "okay";
+
+ max7322: gpio@68 {
+ compatible = "maxim,max7322";
+ reg = <0x68>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+};
+
+&pd_dma_lpuart0 {
+ debug_console;
+};
+
+&lpuart0 { /* console */
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lpuart0>;
+ status = "okay";
+};
+
+&lpuart1 { /* BT */
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lpuart1>;
+ resets = <&modem_reset>;
+ status = "okay";
+};
+
+&lpuart3 { /* GPS */
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lpuart3>;
+ status = "okay";
+};
+
+&mipi_csi_0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ virtual-channel;
+ status = "okay";
+
+ /* Camera 0 MIPI CSI-2 (CSIS0) */
+ port@0 {
+ reg = <0>;
+ mipi_csi0_ep: endpoint {
+ remote-endpoint = <&max9286_0_ep>;
+ data-lanes = <1 2 3 4>;
+ };
+ };
+};
+
+&mipi_csi_1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ virtual-channel;
+ status = "disabled";
+
+ /* Camera 0 MIPI CSI-2 (CSIS1) */
+ port@1 {
+ reg = <1>;
+ mipi_csi1_ep: endpoint {
+ remote-endpoint = <&max9286_1_ep>;
+ data-lanes = <1 2 3 4>;
+ };
+ };
+};
+
+&mlb {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_mlb>;
+ pinctrl-assert-gpios = <&pca9557_d 2 GPIO_ACTIVE_LOW>;
+ status = "okay";
+};
+
+&isi_0 {
+ status = "okay";
+};
+
+&isi_1 {
+ status = "okay";
+};
+
+&isi_2 {
+ status = "okay";
+};
+
+&isi_3 {
+ status = "okay";
+};
+
+&gpu_3d0 {
+ status = "okay";
+};
+
+&gpu_3d1 {
+ status = "okay";
+};
+
+&imx8_gpu_ss {
+ status = "okay";
+};
+
+&pixel_combiner1 {
+ status = "okay";
+};
+
+&prg1 {
+ status = "okay";
+};
+
+&prg2 {
+ status = "okay";
+};
+
+&prg3 {
+ status = "okay";
+};
+
+&prg4 {
+ status = "okay";
+};
+
+&prg5 {
+ status = "okay";
+};
+
+&prg6 {
+ status = "okay";
+};
+
+&prg7 {
+ status = "okay";
+};
+
+&prg8 {
+ status = "okay";
+};
+
+&prg9 {
+ status = "okay";
+};
+
+&dpr1_channel1 {
+ status = "okay";
+};
+
+&dpr1_channel2 {
+ status = "okay";
+};
+
+&dpr1_channel3 {
+ status = "okay";
+};
+
+&dpr2_channel1 {
+ status = "okay";
+};
+
+&dpr2_channel2 {
+ status = "okay";
+};
+
+&dpr2_channel3 {
+ status = "okay";
+};
+
+&dpu1 {
+ status = "okay";
+};
+
+&pixel_combiner2 {
+ status = "okay";
+};
+
+&prg10 {
+ status = "okay";
+};
+
+&prg11 {
+ status = "okay";
+};
+
+&prg12 {
+ status = "okay";
+};
+
+&prg13 {
+ status = "okay";
+};
+
+&prg14 {
+ status = "okay";
+};
+
+&prg15 {
+ status = "okay";
+};
+
+&prg16 {
+ status = "okay";
+};
+
+&prg17 {
+ status = "okay";
+};
+
+&prg18 {
+ status = "okay";
+};
+
+&dpr3_channel1 {
+ status = "okay";
+};
+
+&dpr3_channel2 {
+ status = "okay";
+};
+
+&dpr3_channel3 {
+ status = "okay";
+};
+
+&dpr4_channel1 {
+ status = "okay";
+};
+
+&dpr4_channel2 {
+ status = "okay";
+};
+
+&dpr4_channel3 {
+ status = "okay";
+};
+
+&dpu2 {
+ status = "okay";
+};
+
+&pciea{
+ ext_osc = <1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pciea>;
+ reset-gpio = <&gpio4 29 GPIO_ACTIVE_LOW>;
+ clkreq-gpio = <&gpio4 27 GPIO_ACTIVE_LOW>;
+ status = "okay";
+};
+
+&pcieb{
+ ext_osc = <1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pcieb>;
+ reset-gpio = <&gpio5 0 GPIO_ACTIVE_LOW>;
+ clkreq-gpio = <&gpio4 1 GPIO_ACTIVE_LOW>;
+ status = "okay";
+};
+
+&intmux_cm40 {
+ status = "okay";
+};
+
+&rpmsg{
+ /*
+ * 64K for one rpmsg instance:
+ */
+ vdev-nums = <1>;
+ reg = <0x0 0x90000000 0x0 0x10000>;
+ status = "okay";
+};
+
+&intmux_cm41 {
+ status = "okay";
+};
+
+&rpmsg1{
+ /*
+ * 64K for one rpmsg instance:
+ */
+ vdev-nums = <1>;
+ reg = <0x0 0x90100000 0x0 0x10000>;
+ status = "okay";
+};
+
+&lvds0_pwm {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lvds0_pwm0>;
+ status = "okay";
+};
+
+&lvds1_pwm {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lvds1_pwm0>;
+ status = "okay";
+};
+
+&ldb1_phy {
+ status = "okay";
+};
+
+&ldb1 {
+ status = "okay";
+
+ lvds-channel@0 {
+ fsl,data-mapping = "jeida";
+ fsl,data-width = <24>;
+ status = "okay";
+
+ port@1 {
+ reg = <1>;
+
+ lvds0_out: endpoint {
+ remote-endpoint = <&it6263_0_in>;
+ };
+ };
+ };
+};
+
+&i2c1_lvds0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lvds0_lpi2c1>;
+ clock-frequency = <100000>;
+ status = "okay";
+
+ lvds-to-hdmi-bridge@4c {
+ compatible = "ite,it6263";
+ reg = <0x4c>;
+
+ port {
+ it6263_0_in: endpoint {
+ clock-lanes = <3>;
+ data-lanes = <0 1 2 4>;
+ remote-endpoint = <&lvds0_out>;
+ };
+ };
+ };
+};
+
+&ldb2_phy {
+ status = "okay";
+};
+
+&ldb2 {
+ status = "okay";
+
+ lvds-channel@0 {
+ fsl,data-mapping = "jeida";
+ fsl,data-width = <24>;
+ status = "okay";
+
+ port@1 {
+ reg = <1>;
+
+ lvds1_out: endpoint {
+ remote-endpoint = <&it6263_1_in>;
+ };
+ };
+ };
+};
+
+&i2c1_lvds1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lvds1_lpi2c1>;
+ clock-frequency = <100000>;
+ status = "okay";
+
+ lvds-to-hdmi-bridge@4c {
+ compatible = "ite,it6263";
+ reg = <0x4c>;
+
+ port {
+ it6263_1_in: endpoint {
+ clock-lanes = <3>;
+ data-lanes = <0 1 2 4>;
+ remote-endpoint = <&lvds1_out>;
+ };
+ };
+ };
+};
+
+&mipi_dsi_phy1 {
+ status = "okay";
+};
+
+&mipi_dsi1 {
+ status = "okay";
+};
+
+&mipi_dsi_bridge1 {
+ status = "okay";
+
+ port@1 {
+ mipi_dsi_bridge1_adv: endpoint {
+ remote-endpoint = <&adv7535_1_in>;
+ };
+ };
+};
+
+&i2c0_mipi_dsi0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_mipi0_lpi2c0>;
+ clock-frequency = <100000>;
+ status = "okay";
+
+ adv_bridge1: adv7535@3d {
+ compatible = "adi,adv7535", "adi,adv7533";
+ reg = <0x3d>;
+ adi,dsi-lanes = <4>;
+ adi,dsi-channel = <1>;
+ status = "okay";
+
+ port {
+ adv7535_1_in: endpoint {
+ remote-endpoint = <&mipi_dsi_bridge1_adv>;
+ };
+ };
+ };
+};
+
+&mipi_dsi_phy2 {
+ status = "okay";
+};
+
+&mipi_dsi2 {
+ status = "okay";
+};
+
+&mipi_dsi_bridge2 {
+ status = "okay";
+
+ port@1 {
+ mipi_dsi_bridge2_adv: endpoint {
+ remote-endpoint = <&adv7535_2_in>;
+ };
+ };
+};
+
+&i2c0_mipi_dsi1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_mipi1_lpi2c0>;
+ clock-frequency = <100000>;
+ status = "okay";
+
+ adv_bridge2: adv7535@3d {
+ compatible = "adi,adv7535", "adi,adv7533";
+ reg = <0x3d>;
+ adi,dsi-lanes = <4>;
+ adi,dsi-channel = <1>;
+ status = "okay";
+
+ port {
+ adv7535_2_in: endpoint {
+ remote-endpoint = <&mipi_dsi_bridge2_adv>;
+ };
+ };
+ };
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8qm-ddr4-arm2-hdmi.dts b/arch/arm64/boot/dts/freescale/fsl-imx8qm-ddr4-arm2-hdmi.dts
new file mode 100644
index 000000000000..6d1e5c69e4e2
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8qm-ddr4-arm2-hdmi.dts
@@ -0,0 +1,103 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2017-2018 NXP
+ *
+ * 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.
+ */
+/*
+ * HDMI only dts, disable ldb display.
+ */
+
+#include "fsl-imx8qm-ddr4-arm2.dts"
+
+/ {
+ sound-hdmi-tx {
+ compatible = "fsl,imx-audio-cdnhdmi";
+ model = "imx-audio-hdmi-tx";
+ audio-cpu = <&sai_hdmi_tx>;
+ constraint-rate = <48000>;
+ protocol = <1>;
+ hdmi-out;
+ };
+
+ sound-amix-sai {
+ status = "disabled";
+ };
+
+ sound-hdmi-arc {
+ compatible = "fsl,imx-audio-spdif";
+ model = "imx-hdmi-arc";
+ spdif-controller = <&spdif1>;
+ spdif-in;
+ spdif-out;
+ };
+};
+
+&ldb1_phy {
+ status = "disabled";
+};
+
+&ldb1 {
+ status = "disabled";
+};
+
+&i2c1_lvds0 {
+ status = "disabled";
+};
+
+&hdmi {
+ compatible = "fsl,imx8qm-hdmi";
+ assigned-clocks = <&clk IMX8QM_HDMI_PXL_SEL>,
+ <&clk IMX8QM_HDMI_PXL_LINK_SEL>,
+ <&clk IMX8QM_HDMI_PXL_MUX_SEL>;
+ assigned-clock-parents = <&clk IMX8QM_HDMI_AV_PLL_CLK>,
+ <&clk IMX8QM_HDMI_AV_PLL_CLK>,
+ <&clk IMX8QM_HDMI_AV_PLL_CLK>;
+ fsl,cec;
+ status = "okay";
+};
+
+&amix {
+ status = "disabled";
+};
+
+&sai6 {
+ status = "disabled";
+};
+
+&sai7 {
+ status = "disabled";
+};
+
+&sai_hdmi_tx {
+ assigned-clocks =<&clk IMX8QM_ACM_HDMI_TX_SAI0_MCLK_SEL>,
+ <&clk IMX8QM_AUD_PLL1_DIV>,
+ <&clk IMX8QM_AUD_ACM_AUD_PLL_CLK1_DIV>,
+ <&clk IMX8QM_AUD_ACM_AUD_REC_CLK1_DIV>,
+ <&clk IMX8QM_AUD_SAI_HDMITX0_MCLK>;
+ assigned-clock-parents = <&clk IMX8QM_AUD_ACM_AUD_PLL_CLK1_CLK>;
+ assigned-clock-rates = <0>, <768000000>, <768000000>, <768000000>, <768000000>;
+ fsl,sai-asynchronous;
+ status = "okay";
+};
+
+&sai_hdmi_rx {
+ fsl,sai-asynchronous;
+ status = "okay";
+};
+
+&spdif1 {
+ assigned-clocks =<&clk IMX8QM_AUD_PLL0_DIV>,
+ <&clk IMX8QM_AUD_ACM_AUD_PLL_CLK0_DIV>,
+ <&clk IMX8QM_AUD_ACM_AUD_REC_CLK0_DIV>;
+ assigned-clock-rates = <786432000>, <49152000>, <12288000>;
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8qm-ddr4-arm2.dts b/arch/arm64/boot/dts/freescale/fsl-imx8qm-ddr4-arm2.dts
new file mode 100644
index 000000000000..5a8487e26923
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8qm-ddr4-arm2.dts
@@ -0,0 +1,1300 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2017-2018 NXP
+ *
+ * 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.
+ */
+
+/dts-v1/;
+
+#include "fsl-imx8qm.dtsi"
+
+/ {
+ model = "Freescale i.MX8QM DDR4 ARM2";
+ compatible = "fsl,imx8qm-arm2", "fsl,imx8qm";
+
+ bcmdhd_wlan_0: bcmdhd_wlan@0 {
+ compatible = "android,bcmdhd_wlan";
+ bcmdhd_fw = "/lib/firmware/bcm/1FD_BCM89359/fw_bcmdhd.bin";
+ bcmdhd_nv = "/lib/firmware/bcm/1FD_BCM89359/bcmdhd.cal";
+ };
+
+ chosen {
+ bootargs = "console=ttyLP0,115200 earlycon=lpuart32,0x5a060000,115200";
+ stdout-path = &lpuart0;
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpio_leds>;
+ user {
+ label = "heartbeat";
+ gpios = <&gpio2 15 0>;
+ default-state = "on";
+ linux,default-trigger = "heartbeat";
+ };
+ };
+
+ modem_reset: modem-reset {
+ compatible = "gpio-reset";
+ reset-gpios = <&pca9557_b 7 GPIO_ACTIVE_LOW>;
+ reset-delay-us = <2000>;
+ reset-post-delay-ms = <40>;
+ #reset-cells = <0>;
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ reg_audio: regulator@0 {
+ compatible = "regulator-fixed";
+ reg = <2>;
+ regulator-name = "cs42888_supply";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ reg_can_en: regulator-can-gen {
+ compatible = "regulator-fixed";
+ regulator-name = "can-en";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&pca9557_b 5 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ reg_can_stby: regulator-can-stby {
+ compatible = "regulator-fixed";
+ regulator-name = "can-stby";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&pca9557_b 4 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ vin-supply = <&reg_can_en>;
+ };
+
+ reg_fec2_supply: fec2_nvcc {
+ compatible = "regulator-fixed";
+ regulator-name = "fec2_nvcc";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ gpio = <&max7322 0 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ reg_usdhc2_vmmc: usdhc2_vmmc {
+ compatible = "regulator-fixed";
+ regulator-name = "sw-3p3-sd1";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&gpio4 7 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ epdev_on: fixedregulator@100 {
+ compatible = "regulator-fixed";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-name = "epdev_on";
+ gpio = <&pca9557_b 3 0>;
+ enable-active-high;
+ };
+ };
+
+ sound-cs42888 {
+ compatible = "fsl,imx8qm-sabreauto-cs42888",
+ "fsl,imx-audio-cs42888";
+ model = "imx-cs42888";
+ esai-controller = <&esai0>;
+ audio-codec = <&codec>;
+ asrc-controller = <&asrc0>;
+ };
+
+ sound-amix-sai {
+ compatible = "fsl,imx-audio-amix";
+ model = "amix-audio-sai";
+ dais = <&sai6>, <&sai7>;
+ amix-controller = <&amix>;
+ };
+
+ lvds_backlight0: lvds_backlight@0 {
+ compatible = "pwm-backlight";
+ pwms = <&lvds0_pwm 0 100000 0>;
+
+ brightness-levels = < 0 1 2 3 4 5 6 7 8 9
+ 10 11 12 13 14 15 16 17 18 19
+ 20 21 22 23 24 25 26 27 28 29
+ 30 31 32 33 34 35 36 37 38 39
+ 40 41 42 43 44 45 46 47 48 49
+ 50 51 52 53 54 55 56 57 58 59
+ 60 61 62 63 64 65 66 67 68 69
+ 70 71 72 73 74 75 76 77 78 79
+ 80 81 82 83 84 85 86 87 88 89
+ 90 91 92 93 94 95 96 97 98 99
+ 100>;
+ default-brightness-level = <80>;
+ };
+
+ lvds_backlight1: lvds_backlight@1 {
+ compatible = "pwm-backlight";
+ pwms = <&lvds1_pwm 0 100000 0>;
+
+ brightness-levels = < 0 1 2 3 4 5 6 7 8 9
+ 10 11 12 13 14 15 16 17 18 19
+ 20 21 22 23 24 25 26 27 28 29
+ 30 31 32 33 34 35 36 37 38 39
+ 40 41 42 43 44 45 46 47 48 49
+ 50 51 52 53 54 55 56 57 58 59
+ 60 61 62 63 64 65 66 67 68 69
+ 70 71 72 73 74 75 76 77 78 79
+ 80 81 82 83 84 85 86 87 88 89
+ 90 91 92 93 94 95 96 97 98 99
+ 100>;
+ default-brightness-level = <80>;
+ };
+};
+
+&acm {
+ status = "okay";
+};
+
+&amix {
+ status = "okay";
+};
+
+&asrc0 {
+ assigned-clocks = <&clk IMX8QM_AUD_PLL0_DIV>,
+ <&clk IMX8QM_AUD_ACM_AUD_PLL_CLK0_DIV>,
+ <&clk IMX8QM_AUD_ACM_AUD_REC_CLK0_DIV>;
+ assigned-clock-rates = <786432000>, <49152000>, <24576000>;
+ fsl,asrc-rate = <48000>;
+ status = "okay";
+};
+
+&asrc1 {
+ fsl,asrc-rate = <48000>;
+ assigned-clocks = <&clk IMX8QM_AUD_PLL0_DIV>,
+ <&clk IMX8QM_AUD_ACM_AUD_PLL_CLK0_DIV>,
+ <&clk IMX8QM_AUD_ACM_AUD_REC_CLK0_DIV>;
+ assigned-clock-rates = <786432000>, <49152000>, <24576000>;
+ status = "okay";
+};
+
+&esai0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_esai0>;
+ assigned-clocks = <&clk IMX8QM_ACM_ESAI0_MCLK_SEL>,
+ <&clk IMX8QM_AUD_PLL0_DIV>,
+ <&clk IMX8QM_AUD_ACM_AUD_PLL_CLK0_DIV>,
+ <&clk IMX8QM_AUD_ACM_AUD_REC_CLK0_DIV>,
+ <&clk IMX8QM_AUD_ESAI_0_EXTAL_IPG>;
+ assigned-clock-parents = <&clk IMX8QM_AUD_ACM_AUD_PLL_CLK0_CLK>;
+ assigned-clock-rates = <0>, <786432000>, <49152000>, <24576000>, <49152000>;
+ status = "okay";
+};
+
+&sai_hdmi_tx {
+ assigned-clocks =<&clk IMX8QM_ACM_HDMI_TX_SAI0_MCLK_SEL>,
+ <&clk IMX8QM_AUD_PLL0_DIV>,
+ <&clk IMX8QM_AUD_ACM_AUD_PLL_CLK0_DIV>,
+ <&clk IMX8QM_AUD_ACM_AUD_REC_CLK0_DIV>,
+ <&clk IMX8QM_AUD_SAI_HDMITX0_MCLK>;
+ assigned-clock-parents = <&clk IMX8QM_AUD_ACM_AUD_PLL_CLK0_CLK>;
+ assigned-clock-rates = <0>, <786432000>, <49152000>, <24576000>, <49152000>;
+ fsl,sai-asynchronous;
+ status = "okay";
+};
+
+&sai6 {
+ assigned-clocks = <&clk IMX8QM_ACM_SAI6_MCLK_SEL>,
+ <&clk IMX8QM_AUD_PLL1_DIV>,
+ <&clk IMX8QM_AUD_ACM_AUD_PLL_CLK1_DIV>,
+ <&clk IMX8QM_AUD_ACM_AUD_REC_CLK1_DIV>,
+ <&clk IMX8QM_AUD_SAI_6_MCLK>;
+ assigned-clock-parents = <&clk IMX8QM_AUD_ACM_AUD_PLL_CLK1_CLK>;
+ assigned-clock-rates = <0>, <786432000>, <98304000>, <24576000>, <98304000>;
+ fsl,sai-asynchronous;
+ fsl,txm-rxs;
+ status = "okay";
+};
+
+&sai7 {
+ assigned-clocks = <&clk IMX8QM_ACM_SAI7_MCLK_SEL>,
+ <&clk IMX8QM_AUD_PLL1_DIV>,
+ <&clk IMX8QM_AUD_ACM_AUD_PLL_CLK1_DIV>,
+ <&clk IMX8QM_AUD_ACM_AUD_REC_CLK1_DIV>,
+ <&clk IMX8QM_AUD_SAI_7_MCLK>;
+ assigned-clock-parents = <&clk IMX8QM_AUD_ACM_AUD_PLL_CLK1_CLK>;
+ assigned-clock-rates = <0>, <786432000>, <98304000>, <24576000>, <98304000>;
+ fsl,sai-asynchronous;
+ fsl,txm-rxs;
+ status = "okay";
+};
+
+&iomuxc {
+ imx8qm-arm2 {
+
+ pinctrl_esai0: esai0grp {
+ fsl,pins = <
+ SC_P_ESAI0_FSR_AUD_ESAI0_FSR 0xc6000040
+ SC_P_ESAI0_FST_AUD_ESAI0_FST 0xc6000040
+ SC_P_ESAI0_SCKR_AUD_ESAI0_SCKR 0xc6000040
+ SC_P_ESAI0_SCKT_AUD_ESAI0_SCKT 0xc6000040
+ SC_P_ESAI0_TX0_AUD_ESAI0_TX0 0xc6000040
+ SC_P_ESAI0_TX1_AUD_ESAI0_TX1 0xc6000040
+ SC_P_ESAI0_TX2_RX3_AUD_ESAI0_TX2_RX3 0xc6000040
+ SC_P_ESAI0_TX3_RX2_AUD_ESAI0_TX3_RX2 0xc6000040
+ SC_P_ESAI0_TX4_RX1_AUD_ESAI0_TX4_RX1 0xc6000040
+ SC_P_ESAI0_TX5_RX0_AUD_ESAI0_TX5_RX0 0xc6000040
+ SC_P_MCLK_OUT0_AUD_ACM_MCLK_OUT0 0xc6000040
+ >;
+ };
+
+ pinctrl_fec1: fec1grp {
+ fsl,pins = <
+ SC_P_COMP_CTL_GPIO_1V8_3V3_ENET_ENETB_PAD 0x000014a0
+ SC_P_ENET0_MDC_CONN_ENET0_MDC 0x06000020
+ SC_P_ENET0_MDIO_CONN_ENET0_MDIO 0x06000020
+ SC_P_ENET0_RGMII_TX_CTL_CONN_ENET0_RGMII_TX_CTL 0x00000060
+ SC_P_ENET0_RGMII_TXC_CONN_ENET0_RGMII_TXC 0x00000060
+ SC_P_ENET0_RGMII_TXD0_CONN_ENET0_RGMII_TXD0 0x00000060
+ SC_P_ENET0_RGMII_TXD1_CONN_ENET0_RGMII_TXD1 0x00000060
+ SC_P_ENET0_RGMII_TXD2_CONN_ENET0_RGMII_TXD2 0x00000060
+ SC_P_ENET0_RGMII_TXD3_CONN_ENET0_RGMII_TXD3 0x00000060
+ SC_P_ENET0_RGMII_RXC_CONN_ENET0_RGMII_RXC 0x00000060
+ SC_P_ENET0_RGMII_RX_CTL_CONN_ENET0_RGMII_RX_CTL 0x00000060
+ SC_P_ENET0_RGMII_RXD0_CONN_ENET0_RGMII_RXD0 0x00000060
+ SC_P_ENET0_RGMII_RXD1_CONN_ENET0_RGMII_RXD1 0x00000060
+ SC_P_ENET0_RGMII_RXD2_CONN_ENET0_RGMII_RXD2 0x00000060
+ SC_P_ENET0_RGMII_RXD3_CONN_ENET0_RGMII_RXD3 0x00000060
+ >;
+ };
+
+ pinctrl_fec2: fec2grp {
+ fsl,pins = <
+ SC_P_COMP_CTL_GPIO_1V8_3V3_ENET_ENETA_PAD 0x000014a0
+ SC_P_ENET1_MDC_CONN_ENET1_MDC 0x06000020
+ SC_P_ENET1_MDIO_CONN_ENET1_MDIO 0x06000020
+ SC_P_ENET1_RGMII_TX_CTL_CONN_ENET1_RGMII_TX_CTL 0x00000060
+ SC_P_ENET1_RGMII_TXC_CONN_ENET1_RGMII_TXC 0x00000060
+ SC_P_ENET1_RGMII_TXD0_CONN_ENET1_RGMII_TXD0 0x00000060
+ SC_P_ENET1_RGMII_TXD1_CONN_ENET1_RGMII_TXD1 0x00000060
+ SC_P_ENET1_RGMII_TXD2_CONN_ENET1_RGMII_TXD2 0x00000060
+ SC_P_ENET1_RGMII_TXD3_CONN_ENET1_RGMII_TXD3 0x00000060
+ SC_P_ENET1_RGMII_RXC_CONN_ENET1_RGMII_RXC 0x00000060
+ SC_P_ENET1_RGMII_RX_CTL_CONN_ENET1_RGMII_RX_CTL 0x00000060
+ SC_P_ENET1_RGMII_RXD0_CONN_ENET1_RGMII_RXD0 0x00000060
+ SC_P_ENET1_RGMII_RXD1_CONN_ENET1_RGMII_RXD1 0x00000060
+ SC_P_ENET1_RGMII_RXD2_CONN_ENET1_RGMII_RXD2 0x00000060
+ SC_P_ENET1_RGMII_RXD3_CONN_ENET1_RGMII_RXD3 0x00000060
+ >;
+ };
+
+ pinctrl_lvds0_lpi2c1: lvds0lpi2c1grp {
+ fsl,pins = <
+ SC_P_LVDS0_I2C1_SCL_LVDS0_I2C1_SCL 0xc600004c
+ SC_P_LVDS0_I2C1_SDA_LVDS0_I2C1_SDA 0xc600004c
+ >;
+ };
+
+ pinctrl_lvds1_lpi2c1: lvds1lpi2c1grp {
+ fsl,pins = <
+ SC_P_LVDS1_I2C1_SCL_LVDS1_I2C1_SCL 0xc600004c
+ SC_P_LVDS1_I2C1_SDA_LVDS1_I2C1_SDA 0xc600004c
+ >;
+ };
+
+ pinctrl_hdmi_lpi2c0: hdmilpi2c0grp {
+ fsl,pins = <
+ SC_P_HDMI_TX0_TS_SCL_HDMI_TX0_I2C0_SCL 0xc600004c
+ SC_P_HDMI_TX0_TS_SDA_HDMI_TX0_I2C0_SDA 0xc600004c
+ >;
+ };
+
+ pinctrl_mipi0_lpi2c0: mipi0_lpi2c0grp {
+ fsl,pins = <
+ SC_P_MIPI_DSI0_I2C0_SCL_MIPI_DSI0_I2C0_SCL 0xc600004c
+ SC_P_MIPI_DSI0_I2C0_SDA_MIPI_DSI0_I2C0_SDA 0xc600004c
+ >;
+ };
+
+ pinctrl_mipi1_lpi2c0: mipi1_lpi2c0grp {
+ fsl,pins = <
+ SC_P_MIPI_DSI1_I2C0_SCL_MIPI_DSI1_I2C0_SCL 0xc600004c
+ SC_P_MIPI_DSI1_I2C0_SDA_MIPI_DSI1_I2C0_SDA 0xc600004c
+ >;
+ };
+
+ pinctrl_mipi_dsi_0_1_en: mipi_dsi_0_1_en {
+ fsl,pins = <
+ SC_P_LVDS0_I2C0_SDA_LSIO_GPIO1_IO07 0x00000021
+ >;
+ };
+
+ pinctrl_lpi2c0: lpi2c0grp {
+ fsl,pins = <
+ SC_P_HDMI_TX0_TS_SCL_DMA_I2C0_SCL 0xc600004c
+ SC_P_HDMI_TX0_TS_SDA_DMA_I2C0_SDA 0xc600004c
+ >;
+ };
+
+ pinctrl_lpi2c1: lpi2c1grp {
+ fsl,pins = <
+ SC_P_GPT0_CLK_DMA_I2C1_SCL 0xc600004c
+ SC_P_GPT0_CAPTURE_DMA_I2C1_SDA 0xc600004c
+ >;
+ };
+
+ pinctrl_lpi2c2: lpi2c2grp {
+ fsl,pins = <
+ SC_P_GPT1_CLK_DMA_I2C2_SCL 0xc600004c
+ SC_P_GPT1_CAPTURE_DMA_I2C2_SDA 0xc600004c
+ >;
+ };
+
+ pinctrl_lpuart0: lpuart0grp {
+ fsl,pins = <
+ SC_P_UART0_RX_DMA_UART0_RX 0x06000020
+ SC_P_UART0_TX_DMA_UART0_TX 0x06000020
+ >;
+ };
+
+ pinctrl_lpuart1: lpuart1grp {
+ fsl,pins = <
+ SC_P_UART1_RX_DMA_UART1_RX 0x06000020
+ SC_P_UART1_TX_DMA_UART1_TX 0x06000020
+ SC_P_UART1_CTS_B_DMA_UART1_CTS_B 0x06000020
+ SC_P_UART1_RTS_B_DMA_UART1_RTS_B 0x06000020
+ >;
+ };
+
+ pinctrl_lpuart3: lpuart3grp {
+ fsl,pins = <
+ SC_P_M41_GPIO0_00_DMA_UART3_RX 0x06000020
+ SC_P_M41_GPIO0_01_DMA_UART3_TX 0x06000020
+ >;
+ };
+
+ pinctrl_mlb: mlbgrp {
+ fsl,pins = <
+ SC_P_MLB_SIG_CONN_MLB_SIG 0x21
+ SC_P_MLB_CLK_CONN_MLB_CLK 0x21
+ SC_P_MLB_DATA_CONN_MLB_DATA 0x21
+ >;
+ };
+
+ pinctrl_isl29023: isl29023grp {
+ fsl,pins = <
+ SC_P_ADC_IN2_LSIO_GPIO3_IO20 0x00000021
+ >;
+ };
+
+ pinctrl_usdhc3_gpio: usdhc3grpgpio {
+ fsl,pins = <
+ SC_P_USDHC2_RESET_B_CONN_USDHC2_RESET_B 0x00000021
+ >;
+ };
+
+ pinctrl_usdhc3: usdhc3grp {
+ fsl,pins = <
+ SC_P_USDHC2_CLK_CONN_USDHC2_CLK 0x06000041
+ SC_P_USDHC2_CMD_CONN_USDHC2_CMD 0x00000021
+ SC_P_USDHC2_DATA0_CONN_USDHC2_DATA0 0x00000021
+ SC_P_USDHC2_DATA1_CONN_USDHC2_DATA1 0x00000021
+ SC_P_USDHC2_DATA2_CONN_USDHC2_DATA2 0x00000021
+ SC_P_USDHC2_DATA3_CONN_USDHC2_DATA3 0x00000021
+ SC_P_USDHC2_VSELECT_CONN_USDHC2_VSELECT 0x00000021
+ /* WP */
+ SC_P_USDHC2_WP_LSIO_GPIO4_IO11 0x00000021
+ /* CD */
+ SC_P_USDHC2_CD_B_LSIO_GPIO4_IO12 0x00000021
+ >;
+ };
+
+ pinctrl_usdhc3_100mhz: usdhc3grp100mhz {
+ fsl,pins = <
+ SC_P_USDHC2_CLK_CONN_USDHC2_CLK 0x06000040
+ SC_P_USDHC2_CMD_CONN_USDHC2_CMD 0x00000020
+ SC_P_USDHC2_DATA0_CONN_USDHC2_DATA0 0x00000020
+ SC_P_USDHC2_DATA1_CONN_USDHC2_DATA1 0x00000020
+ SC_P_USDHC2_DATA2_CONN_USDHC2_DATA2 0x00000020
+ SC_P_USDHC2_DATA3_CONN_USDHC2_DATA3 0x00000020
+ SC_P_USDHC2_VSELECT_CONN_USDHC2_VSELECT 0x00000020
+ /* WP */
+ SC_P_USDHC2_WP_LSIO_GPIO4_IO11 0x00000020
+ /* CD */
+ SC_P_USDHC2_CD_B_LSIO_GPIO4_IO12 0x00000020
+ >;
+ };
+
+ pinctrl_usdhc3_200mhz: usdhc3grp200mhz {
+ fsl,pins = <
+ SC_P_USDHC2_CLK_CONN_USDHC2_CLK 0x06000040
+ SC_P_USDHC2_CMD_CONN_USDHC2_CMD 0x00000020
+ SC_P_USDHC2_DATA0_CONN_USDHC2_DATA0 0x00000020
+ SC_P_USDHC2_DATA1_CONN_USDHC2_DATA1 0x00000020
+ SC_P_USDHC2_DATA2_CONN_USDHC2_DATA2 0x00000020
+ SC_P_USDHC2_DATA3_CONN_USDHC2_DATA3 0x00000020
+ SC_P_USDHC2_VSELECT_CONN_USDHC2_VSELECT 0x00000020
+ /* WP */
+ SC_P_USDHC2_WP_LSIO_GPIO4_IO11 0x00000020
+ /* CD */
+ SC_P_USDHC2_CD_B_LSIO_GPIO4_IO12 0x00000020
+ >;
+ };
+
+ pinctrl_flexcan1: flexcan0grp {
+ fsl,pins = <
+ SC_P_FLEXCAN0_TX_DMA_FLEXCAN0_TX 0x21
+ SC_P_FLEXCAN0_RX_DMA_FLEXCAN0_RX 0x21
+ >;
+ };
+
+ pinctrl_flexcan2: flexcan1grp {
+ fsl,pins = <
+ SC_P_FLEXCAN1_TX_DMA_FLEXCAN1_TX 0x21
+ SC_P_FLEXCAN1_RX_DMA_FLEXCAN1_RX 0x21
+ >;
+ };
+
+ pinctrl_flexcan3: flexcan2grp {
+ fsl,pins = <
+ SC_P_FLEXCAN2_TX_DMA_FLEXCAN2_TX 0x21
+ SC_P_FLEXCAN2_RX_DMA_FLEXCAN2_RX 0x21
+ >;
+ };
+
+ pinctrl_flexspi0: flexspi0grp {
+ fsl,pins = <
+ SC_P_QSPI0A_DATA0_LSIO_QSPI0A_DATA0 0x06000021
+ SC_P_QSPI0A_DATA1_LSIO_QSPI0A_DATA1 0x06000021
+ SC_P_QSPI0A_DATA2_LSIO_QSPI0A_DATA2 0x06000021
+ SC_P_QSPI0A_DATA3_LSIO_QSPI0A_DATA3 0x06000021
+ SC_P_QSPI0A_DQS_LSIO_QSPI0A_DQS 0x06000021
+ SC_P_QSPI0A_SS0_B_LSIO_QSPI0A_SS0_B 0x06000021
+ SC_P_QSPI0A_SS1_B_LSIO_QSPI0A_SS1_B 0x06000021
+ SC_P_QSPI0A_SCLK_LSIO_QSPI0A_SCLK 0x06000021
+ SC_P_QSPI0B_SCLK_LSIO_QSPI0B_SCLK 0x06000021
+ SC_P_QSPI0B_DATA0_LSIO_QSPI0B_DATA0 0x06000021
+ SC_P_QSPI0B_DATA1_LSIO_QSPI0B_DATA1 0x06000021
+ SC_P_QSPI0B_DATA2_LSIO_QSPI0B_DATA2 0x06000021
+ SC_P_QSPI0B_DATA3_LSIO_QSPI0B_DATA3 0x06000021
+ SC_P_QSPI0B_DQS_LSIO_QSPI0B_DQS 0x06000021
+ SC_P_QSPI0B_SS0_B_LSIO_QSPI0B_SS0_B 0x06000021
+ SC_P_QSPI0B_SS1_B_LSIO_QSPI0B_SS1_B 0x06000021
+ >;
+ };
+
+ pinctrl_gpio_leds: gpioledsgrp {
+ fsl,pins = <
+ SC_P_SPDIF0_TX_LSIO_GPIO2_IO15 0x00000021
+ >;
+ };
+
+ pinctrl_pciea: pcieagrp{
+ fsl,pins = <
+ SC_P_PCIE_CTRL0_CLKREQ_B_LSIO_GPIO4_IO27 0x06000021
+ SC_P_PCIE_CTRL0_WAKE_B_LSIO_GPIO4_IO28 0x04000021
+ SC_P_PCIE_CTRL0_PERST_B_LSIO_GPIO4_IO29 0x06000021
+ >;
+ };
+
+ pinctrl_pcieb: pciebgrp{
+ fsl,pins = <
+ SC_P_PCIE_CTRL1_CLKREQ_B_LSIO_GPIO4_IO30 0x06000021
+ SC_P_PCIE_CTRL1_WAKE_B_LSIO_GPIO4_IO31 0x04000021
+ SC_P_PCIE_CTRL1_PERST_B_LSIO_GPIO5_IO00 0x06000021
+ >;
+ };
+
+ pinctrl_usbotg1: usbotg1 {
+ fsl,pins = <
+ SC_P_USB_SS3_TC0_CONN_USB_OTG1_PWR 0x00000021
+ >;
+ };
+
+ pinctrl_lvds0_pwm0: lvds0pwm0grp {
+ fsl,pins = <
+ SC_P_LVDS0_GPIO00_LVDS0_PWM0_OUT 0x00000020
+ >;
+ };
+
+ pinctrl_lvds1_pwm0: lvds1pwm0grp {
+ fsl,pins = <
+ SC_P_LVDS1_GPIO00_LVDS1_PWM0_OUT 0x00000020
+ >;
+ };
+
+ pinctrl_mipi_csi0_gpio: mipicsi0gpiogrp{
+ fsl,pins = <
+ SC_P_MIPI_CSI0_GPIO0_00_MIPI_CSI0_GPIO0_IO00 0x00000021
+ SC_P_MIPI_CSI0_GPIO0_01_MIPI_CSI0_GPIO0_IO01 0x00000021
+ >;
+ };
+
+ pinctrl_mipi_csi1_gpio: mipicsi1gpiogrp{
+ fsl,pins = <
+ SC_P_MIPI_CSI1_GPIO0_00_MIPI_CSI1_GPIO0_IO00 0x00000021
+ SC_P_MIPI_CSI1_GPIO0_01_MIPI_CSI1_GPIO0_IO01 0x00000021
+ >;
+ };
+ };
+};
+
+&gpio2 {
+ status = "okay";
+};
+
+&gpio5 {
+ status = "okay";
+};
+
+&usdhc3 {
+ pinctrl-names = "default", "state_100mhz", "state_200mhz";
+ pinctrl-0 = <&pinctrl_usdhc3>,<&pinctrl_usdhc3_gpio>;
+ pinctrl-1 = <&pinctrl_usdhc3_100mhz>,<&pinctrl_usdhc3_gpio>;
+ pinctrl-2 = <&pinctrl_usdhc3_200mhz>,<&pinctrl_usdhc3_gpio>;
+ bus-width = <4>;
+ cd-gpios = <&gpio4 12 GPIO_ACTIVE_LOW>;
+ wp-gpios = <&gpio4 11 GPIO_ACTIVE_HIGH>;
+ no-1-8-v;
+ status = "okay";
+
+};
+
+&usbotg1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usbotg1>;
+ srp-disable;
+ hnp-disable;
+ adp-disable;
+ power-polarity-active-high;
+ disable-over-current;
+ status = "okay";
+};
+
+&usbotg3 {
+ dr_mode = "host";
+ status = "okay";
+};
+
+&fec1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_fec1>;
+ phy-mode = "rgmii-txid";
+ phy-handle = <&ethphy0>;
+ fsl,magic-packet;
+ fsl,rgmii_rxc_dly;
+ status = "okay";
+
+ mdio {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ethphy0: ethernet-phy@0 {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <0>;
+ at803x,eee-disabled;
+ at803x,vddio-1p8v;
+ };
+
+ ethphy1: ethernet-phy@1 {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <1>;
+ at803x,eee-disabled;
+ at803x,vddio-1p8v;
+ status = "disabled";
+ };
+ };
+};
+
+&fec2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_fec2>;
+ phy-mode = "rgmii-txid";
+ phy-handle = <&ethphy1>;
+ phy-supply = <&reg_fec2_supply>;
+ fsl,magic-packet;
+ fsl,rgmii_rxc_dly;
+ status = "okay";
+};
+
+&flexcan1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_flexcan1>;
+ xceiver-supply = <&reg_can_stby>;
+ status = "okay";
+};
+
+&flexcan2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_flexcan2>;
+ xceiver-supply = <&reg_can_stby>;
+ status = "okay";
+};
+
+&flexcan3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_flexcan3>;
+ xceiver-supply = <&reg_can_stby>;
+ status = "okay";
+};
+
+&flexspi0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_flexspi0>;
+ status = "okay";
+
+ flash0: mt35xu512aba@0 {
+ reg = <0>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "micron,mt35xu512aba";
+ spi-max-frequency = <133000000>;
+ spi-nor,ddr-quad-read-dummy = <8>;
+ };
+};
+
+&gpio0_mipi_csi0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_mipi_csi0_gpio>;
+ status = "okay";
+};
+
+&gpio0_mipi_csi1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_mipi_csi1_gpio>;
+ status = "okay";
+};
+
+&i2c0_mipi_csi0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ clock-frequency = <100000>;
+ status = "okay";
+
+ max9286_mipi@6A {
+ compatible = "maxim,max9286_mipi";
+ reg = <0x6A>;
+ clocks = <&clk IMX8QM_CLK_DUMMY>;
+ clock-names = "capture_mclk";
+ mclk = <27000000>;
+ mclk_source = <0>;
+ pwn-gpios = <&gpio0_mipi_csi0 0 GPIO_ACTIVE_HIGH>;
+ virtual-channel;
+ port {
+ max9286_0_ep: endpoint {
+ remote-endpoint = <&mipi_csi0_ep>;
+ data-lanes = <1 2 3 4>;
+ };
+ };
+ };
+};
+
+&i2c0_mipi_csi1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ clock-frequency = <100000>;
+ status = "disabled";
+
+ max9286_mipi@6A {
+ compatible = "maxim,max9286_mipi";
+ reg = <0x6A>;
+ clocks = <&clk IMX8QM_CLK_DUMMY>;
+ clock-names = "capture_mclk";
+ mclk = <27000000>;
+ mclk_source = <0>;
+ pwn-gpios = <&gpio0_mipi_csi1 0 GPIO_ACTIVE_HIGH>;
+ virtual-channel;
+ port {
+ max9286_1_ep: endpoint {
+ remote-endpoint = <&mipi_csi1_ep>;
+ data-lanes = <1 2 3 4>;
+ };
+ };
+ };
+};
+
+&i2c0_hdmi {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_hdmi_lpi2c0>;
+ clock-frequency = <100000>;
+ status = "disabled";
+};
+
+&i2c0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lpi2c0>;
+ clock-frequency = <100000>;
+ status = "okay";
+
+ codec: cs42888@48 {
+ compatible = "cirrus,cs42888";
+ reg = <0x48>;
+ clocks = <&clk IMX8QM_AUD_MCLKOUT0>;
+ clock-names = "mclk";
+ VA-supply = <&reg_audio>;
+ VD-supply = <&reg_audio>;
+ VLS-supply = <&reg_audio>;
+ VLC-supply = <&reg_audio>;
+ reset-gpio = <&pca9557_a 2 1>;
+ power-domains = <&pd_mclk_out0>;
+ };
+};
+
+&i2c1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lpi2c1>;
+ status = "okay";
+
+ pca9557_a: gpio@18 {
+ compatible = "nxp,pca9557";
+ reg = <0x18>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ pca9557_b: gpio@19 {
+ compatible = "nxp,pca9557";
+ reg = <0x19>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ pca9557_c: gpio@1b {
+ compatible = "nxp,pca9557";
+ reg = <0x1b>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ pca9557_d: gpio@1f {
+ compatible = "nxp,pca9557";
+ reg = <0x1f>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ fxas2100x@20 {
+ compatible = "fsl,fxas2100x";
+ reg = <0x20>;
+ };
+
+ fxos8700@1d {
+ compatible = "fsl,fxos8700";
+ reg = <0x1d>;
+ };
+
+ isl29023@44 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_isl29023>;
+ compatible = "fsl,isl29023";
+ reg = <0x44>;
+ rext = <499>;
+ interrupt-parent = <&gpio3>;
+ interrupts = <20 2>;
+ };
+
+ mpl3115@60 {
+ compatible = "fsl,mpl3115";
+ reg = <0x60>;
+ };
+};
+
+&i2c2 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lpi2c2>;
+ status = "okay";
+
+ max7322: gpio@68 {
+ compatible = "maxim,max7322";
+ reg = <0x68>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+};
+
+&pd_dma_lpuart0 {
+ debug_console;
+};
+
+&lpuart0 { /* console */
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lpuart0>;
+ status = "okay";
+};
+
+&lpuart1 { /* BT */
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lpuart1>;
+ resets = <&modem_reset>;
+ status = "disabled";
+};
+
+&lpuart3 { /* GPS */
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lpuart3>;
+ status = "disabled";
+};
+
+&mipi_csi_0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ virtual-channel;
+ status = "okay";
+
+ /* Camera 0 MIPI CSI-2 (CSIS0) */
+ port@0 {
+ reg = <0>;
+ mipi_csi0_ep: endpoint {
+ remote-endpoint = <&max9286_0_ep>;
+ data-lanes = <1 2 3 4>;
+ };
+ };
+};
+
+&mipi_csi_1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ virtual-channel;
+ status = "disabled";
+
+ /* Camera 0 MIPI CSI-2 (CSIS1) */
+ port@1 {
+ reg = <1>;
+ mipi_csi1_ep: endpoint {
+ remote-endpoint = <&max9286_1_ep>;
+ data-lanes = <1 2 3 4>;
+ };
+ };
+};
+
+&mlb {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_mlb>;
+ pinctrl-assert-gpios = <&pca9557_d 2 GPIO_ACTIVE_LOW>;
+ status = "okay";
+};
+
+&isi_0 {
+ status = "okay";
+};
+
+&isi_1 {
+ status = "okay";
+};
+
+&isi_2 {
+ status = "okay";
+};
+
+&isi_3 {
+ status = "okay";
+};
+
+&gpu_3d0 {
+ status = "okay";
+};
+
+&gpu_3d1 {
+ status = "okay";
+};
+
+&imx8_gpu_ss {
+ status = "okay";
+};
+
+&pixel_combiner1 {
+ status = "okay";
+};
+
+&prg1 {
+ status = "okay";
+};
+
+&prg2 {
+ status = "okay";
+};
+
+&prg3 {
+ status = "okay";
+};
+
+&prg4 {
+ status = "okay";
+};
+
+&prg5 {
+ status = "okay";
+};
+
+&prg6 {
+ status = "okay";
+};
+
+&prg7 {
+ status = "okay";
+};
+
+&prg8 {
+ status = "okay";
+};
+
+&prg9 {
+ status = "okay";
+};
+
+&dpr1_channel1 {
+ status = "okay";
+};
+
+&dpr1_channel2 {
+ status = "okay";
+};
+
+&dpr1_channel3 {
+ status = "okay";
+};
+
+&dpr2_channel1 {
+ status = "okay";
+};
+
+&dpr2_channel2 {
+ status = "okay";
+};
+
+&dpr2_channel3 {
+ status = "okay";
+};
+
+&dpu1 {
+ status = "okay";
+};
+
+&pixel_combiner2 {
+ status = "okay";
+};
+
+&prg10 {
+ status = "okay";
+};
+
+&prg11 {
+ status = "okay";
+};
+
+&prg12 {
+ status = "okay";
+};
+
+&prg13 {
+ status = "okay";
+};
+
+&prg14 {
+ status = "okay";
+};
+
+&prg15 {
+ status = "okay";
+};
+
+&prg16 {
+ status = "okay";
+};
+
+&prg17 {
+ status = "okay";
+};
+
+&prg18 {
+ status = "okay";
+};
+
+&dpr3_channel1 {
+ status = "okay";
+};
+
+&dpr3_channel2 {
+ status = "okay";
+};
+
+&dpr3_channel3 {
+ status = "okay";
+};
+
+&dpr4_channel1 {
+ status = "okay";
+};
+
+&dpr4_channel2 {
+ status = "okay";
+};
+
+&dpr4_channel3 {
+ status = "okay";
+};
+
+&dpu2 {
+ status = "okay";
+};
+
+&pciea{
+ ext_osc = <1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pciea>;
+ reset-gpio = <&gpio4 29 GPIO_ACTIVE_LOW>;
+ clkreq-gpio = <&gpio4 27 GPIO_ACTIVE_LOW>;
+ status = "disabled";
+};
+
+&pcieb{
+ ext_osc = <1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pcieb>;
+ reset-gpio = <&gpio5 0 GPIO_ACTIVE_LOW>;
+ clkreq-gpio = <&gpio4 1 GPIO_ACTIVE_LOW>;
+ status = "disabled";
+};
+
+&intmux_cm40 {
+ status = "okay";
+};
+
+&rpmsg{
+ /*
+ * 64K for one rpmsg instance:
+ */
+ vdev-nums = <1>;
+ reg = <0x0 0x90000000 0x0 0x10000>;
+ status = "okay";
+};
+
+&intmux_cm41 {
+ status = "okay";
+};
+
+&rpmsg1{
+ /*
+ * 64K for one rpmsg instance:
+ */
+ vdev-nums = <1>;
+ reg = <0x0 0x90100000 0x0 0x10000>;
+ status = "okay";
+};
+
+&lvds0_pwm {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lvds0_pwm0>;
+ status = "okay";
+};
+
+&lvds1_pwm {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lvds1_pwm0>;
+ status = "okay";
+};
+
+&ldb1_phy {
+ status = "okay";
+};
+
+&ldb1 {
+ status = "okay";
+
+ lvds-channel@0 {
+ fsl,data-mapping = "jeida";
+ fsl,data-width = <24>;
+ status = "okay";
+
+ port@1 {
+ reg = <1>;
+
+ lvds0_out: endpoint {
+ remote-endpoint = <&it6263_0_in>;
+ };
+ };
+ };
+};
+
+&i2c1_lvds0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lvds0_lpi2c1>;
+ clock-frequency = <100000>;
+ status = "okay";
+
+ lvds-to-hdmi-bridge@4c {
+ compatible = "ite,it6263";
+ reg = <0x4c>;
+
+ port {
+ it6263_0_in: endpoint {
+ clock-lanes = <3>;
+ data-lanes = <0 1 2 4>;
+ remote-endpoint = <&lvds0_out>;
+ };
+ };
+ };
+};
+
+&ldb2_phy {
+ status = "okay";
+};
+
+&ldb2 {
+ status = "okay";
+
+ lvds-channel@0 {
+ fsl,data-mapping = "jeida";
+ fsl,data-width = <24>;
+ status = "okay";
+
+ port@1 {
+ reg = <1>;
+
+ lvds1_out: endpoint {
+ remote-endpoint = <&it6263_1_in>;
+ };
+ };
+ };
+};
+
+&i2c1_lvds1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lvds1_lpi2c1>;
+ clock-frequency = <100000>;
+ status = "okay";
+
+ lvds-to-hdmi-bridge@4c {
+ compatible = "ite,it6263";
+ reg = <0x4c>;
+
+ port {
+ it6263_1_in: endpoint {
+ clock-lanes = <3>;
+ data-lanes = <0 1 2 4>;
+ remote-endpoint = <&lvds1_out>;
+ };
+ };
+ };
+};
+
+&mipi_dsi_phy1 {
+ status = "okay";
+};
+
+&mipi_dsi1 {
+ status = "okay";
+};
+
+&mipi_dsi_bridge1 {
+ status = "okay";
+
+ port@1 {
+ mipi_dsi_bridge1_adv: endpoint {
+ remote-endpoint = <&adv7535_1_in>;
+ };
+ };
+};
+
+&i2c0_mipi_dsi0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_mipi0_lpi2c0>;
+ clock-frequency = <100000>;
+ status = "okay";
+
+ adv_bridge1: adv7535@3d {
+ compatible = "adi,adv7535", "adi,adv7533";
+ reg = <0x3d>;
+ adi,dsi-lanes = <4>;
+ adi,dsi-channel = <1>;
+ status = "okay";
+
+ port {
+ adv7535_1_in: endpoint {
+ remote-endpoint = <&mipi_dsi_bridge1_adv>;
+ };
+ };
+ };
+};
+
+&mipi_dsi_phy2 {
+ status = "okay";
+};
+
+&mipi_dsi2 {
+ status = "okay";
+};
+
+&mipi_dsi_bridge2 {
+ status = "okay";
+
+ port@1 {
+ mipi_dsi_bridge2_adv: endpoint {
+ remote-endpoint = <&adv7535_2_in>;
+ };
+ };
+};
+
+&i2c0_mipi_dsi1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_mipi1_lpi2c0>;
+ clock-frequency = <100000>;
+ status = "okay";
+
+ adv_bridge2: adv7535@3d {
+ compatible = "adi,adv7535", "adi,adv7533";
+ reg = <0x3d>;
+ adi,dsi-lanes = <4>;
+ adi,dsi-channel = <1>;
+ status = "okay";
+
+ port {
+ adv7535_2_in: endpoint {
+ remote-endpoint = <&mipi_dsi_bridge2_adv>;
+ };
+ };
+ };
+};
+
+&vpu_decoder {
+ core_type = <2>;
+ status = "okay";
+};
+
+&vpu_encoder {
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8qm-device.dtsi b/arch/arm64/boot/dts/freescale/fsl-imx8qm-device.dtsi
new file mode 100644
index 000000000000..8fc95161d511
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8qm-device.dtsi
@@ -0,0 +1,4414 @@
+/*
+ * Copyright 2018 NXP
+ *
+ * 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.
+ */
+
+ imx8qm-pm {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_dc0: PD_DC_0 {
+ compatible = "nxp,imx8-pd";
+ reg = <SC_R_DC_0>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_dc0_pll0: PD_DC_0_PLL_0{
+ reg = <SC_R_DC_0_PLL_0>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_dc0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_dc0_pll1: PD_DC_0_PLL_1{
+ reg = <SC_R_DC_0_PLL_1>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_dc0_pll0>;
+ };
+ };
+
+ pd_mipi0: PD_MIPI_0_DSI {
+ reg = <SC_R_MIPI_0>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_dc0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_mipi0_i2c0: PD_MIPI_0_DSI_I2C0 {
+ reg = <SC_R_MIPI_0_I2C_0>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_mipi0>;
+ };
+
+ pd_mipi0_i2c1: PD_MIPI_0_DSI_I2C1 {
+ reg = <SC_R_MIPI_0_I2C_1>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_mipi0>;
+ };
+
+ pd_mipi0_pwm: PD_MIPI_0_DSI_PWM0 {
+ reg = <SC_R_MIPI_0_PWM_0>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_mipi0>;
+ };
+ };
+
+ pd_lvds0: PD_LVDS0 {
+ reg = <SC_R_LVDS_0>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_dc0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_lvds0_i2c0: PD_LVDS0_I2C0 {
+ reg = <SC_R_LVDS_0_I2C_0>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_lvds0>;
+ };
+
+ pd_lvds0_pwm: PD_LVDS0_PWM {
+ reg = <SC_R_LVDS_0_PWM_0>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_lvds0>;
+ };
+ };
+
+ pd_hdmi: PD_HDMI {
+ reg = <SC_R_HDMI>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_dc0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_hdmi_pll0: PD_HDMI_PLL_0{
+ reg = <SC_R_HDMI_PLL_0>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_hdmi>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_hdmi_pll1: PD_HDMI_PLL_1{
+ reg = <SC_R_HDMI_PLL_1>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_hdmi_pll0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_hdmi_i2c0: PD_HDMI_I2C_0 {
+ reg = <SC_R_HDMI_I2C_0>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_hdmi_pll1>;
+ };
+
+ pd_hdmi_i2s: PD_HDMI_I2S {
+ reg = <SC_R_HDMI_I2S>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_hdmi_pll1>;
+ };
+ };
+ };
+
+ };
+
+ };
+
+ pd_dc1: PD_DC_1 {
+ compatible = "nxp,imx8-pd";
+ reg = <SC_R_DC_1>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_dc1_pll0: PD_DC_1_PLL_0{
+ reg = <SC_R_DC_1_PLL_0>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_dc1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_dc1_pll1: PD_DC_1_PLL_1{
+ reg = <SC_R_DC_1_PLL_1>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_dc1_pll0>;
+ };
+ };
+
+ pd_mipi1: PD_MIPI_1_DSI {
+ reg = <SC_R_MIPI_1>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_dc1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_mipi1_i2c0: PD_MIPI_1_DSI_I2C0 {
+ reg = <SC_R_MIPI_1_I2C_0>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_mipi1>;
+ };
+
+ pd_mipi1_i2c1: PD_MIPI_1_DSI_I2C1 {
+ reg = <SC_R_MIPI_1_I2C_1>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_mipi1>;
+ };
+
+ pd_mipi1_pwm: PD_MIPI_1_DSI_PWM {
+ reg = <SC_R_MIPI_1_PWM_0>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_mipi1>;
+ };
+ };
+
+ pd_lvds1: PD_LVDS1 {
+ reg = <SC_R_LVDS_1>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_dc1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_lvds1_i2c0: PD_LVDS1_I2C0 {
+ reg = <SC_R_LVDS_1_I2C_0>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_lvds1>;
+ };
+
+ pd_lvds1_pwm: PD_LVDS1_PWM {
+ reg = <SC_R_LVDS_1_PWM_0>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_lvds1>;
+ };
+ };
+ };
+
+ pd_lsio: PD_LSIO {
+ compatible = "nxp,imx8-pd";
+ reg = <SC_R_NONE>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_lsio_pwm0: PD_LSIO_PWM_0 {
+ reg = <SC_R_PWM_0>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_lsio>;
+ };
+ pd_lsio_pwm1: PD_LSIO_PWM_1 {
+ reg = <SC_R_PWM_1>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_lsio>;
+ };
+ pd_lsio_pwm2: PD_LSIO_PWM_2 {
+ reg = <SC_R_PWM_2>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_lsio>;
+ };
+ pd_lsio_pwm3: PD_LSIO_PWM_3 {
+ reg = <SC_R_PWM_3>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_lsio>;
+ };
+ pd_lsio_pwm4: PD_LSIO_PWM_4 {
+ reg = <SC_R_PWM_4>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_lsio>;
+ };
+ pd_lsio_pwm5: PD_LSIO_PWM_5 {
+ reg = <SC_R_PWM_5>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_lsio>;
+ };
+ pd_lsio_pwm6: PD_LSIO_PWM_6 {
+ reg = <SC_R_PWM_6>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_lsio>;
+ };
+ pd_lsio_pwm7: PD_LSIO_PWM_7 {
+ reg = <SC_R_PWM_7>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_lsio>;
+ };
+ pd_lsio_kpp: PD_LSIO_KPP {
+ reg = <SC_R_KPP>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_lsio>;
+ };
+ pd_lsio_gpio0: PD_LSIO_GPIO_0 {
+ reg = <SC_R_GPIO_0>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_lsio>;
+ };
+ pd_lsio_gpio1: PD_LSIO_GPIO_1 {
+ reg = <SC_R_GPIO_1>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_lsio>;
+ };
+ pd_lsio_gpio2: PD_LSIO_GPIO_2 {
+ reg = <SC_R_GPIO_2>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_lsio>;
+ };
+ pd_lsio_gpio3: PD_LSIO_GPIO_3 {
+ reg = <SC_R_GPIO_3>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_lsio>;
+ };
+ pd_lsio_gpio4: PD_LSIO_GPIO_4 {
+ reg = <SC_R_GPIO_4>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_lsio>;
+ };
+ pd_lsio_gpio5: PD_LSIO_GPIO_5{
+ reg = <SC_R_GPIO_5>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_lsio>;
+ };
+ pd_lsio_gpio6:PD_LSIO_GPIO_6 {
+ reg = <SC_R_GPIO_6>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_lsio>;
+ };
+ pd_lsio_gpio7: PD_LSIO_GPIO_7 {
+ reg = <SC_R_GPIO_7>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_lsio>;
+ };
+ pd_lsio_gpt0: PD_LSIO_GPT_0 {
+ reg = <SC_R_GPT_0>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_lsio>;
+ };
+ pd_lsio_gpt1: PD_LSIO_GPT_1 {
+ reg = <SC_R_GPT_1>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_lsio>;
+ };
+ pd_lsio_gpt2: PD_LSIO_GPT_2 {
+ reg = <SC_R_GPT_2>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_lsio>;
+ };
+ pd_lsio_gpt3: PD_LSIO_GPT_3 {
+ reg = <SC_R_GPT_3>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_lsio>;
+ };
+ pd_lsio_gpt4: PD_LSIO_GPT_4 {
+ reg = <SC_R_GPT_4>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_lsio>;
+ };
+ pd_lsio_flexspi0: PD_LSIO_FSPI_0 {
+ reg = <SC_R_FSPI_0>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_lsio>;
+ };
+ pd_lsio_flexspi1: PD_LSIO_FSPI_1{
+ reg = <SC_R_FSPI_1>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_lsio>;
+ };
+ pd_lsio_mu5a: PD_LSIO_MU5A {
+ reg = <SC_R_MU_5A>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_lsio>;
+ };
+ pd_lsio_mu6a: PD_LSIO_MU6A {
+ reg = <SC_R_MU_6A>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_lsio>;
+ };
+ };
+
+ pd_conn: PD_CONN {
+ compatible = "nxp,imx8-pd";
+ reg = <SC_R_NONE>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_conn_usbotg0: PD_CONN_USB_0 {
+ reg = <SC_R_USB_0>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_conn>;
+ wakeup-irq = <267>;
+ };
+
+ pd_conn_usbotg0_phy: PD_CONN_USB_0_PHY {
+ reg = <SC_R_USB_0_PHY>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_conn>;
+ wakeup-irq = <267>;
+ };
+
+ pd_conn_usbh1: PD_CONN_USB_1 {
+ reg = <SC_R_USB_1>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_conn>;
+ wakeup-irq = <268>;
+ };
+
+ pd_conn_usb2: PD_CONN_USB_2 {
+ reg = <SC_R_USB_2>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ power-domains = <&pd_conn>;
+ wakeup-irq = <271>;
+
+ pd_conn_usb2_phy: PD_CONN_USB_2_PHY {
+ reg = <SC_R_USB_2_PHY>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_conn_usb2>;
+ wakeup-irq = <271>;
+ };
+ };
+ pd_conn_sdch0: PD_CONN_SDHC_0 {
+ reg = <SC_R_SDHC_0>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_conn>;
+ };
+ pd_conn_sdch1: PD_CONN_SDHC_1 {
+ reg = <SC_R_SDHC_1>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_conn>;
+ };
+ pd_conn_sdch2: PD_CONN_SDHC_2 {
+ reg = <SC_R_SDHC_2>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_conn>;
+ };
+ pd_conn_enet0: PD_CONN_ENET_0 {
+ reg = <SC_R_ENET_0>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_conn>;
+ wakeup-irq = <258>;
+ };
+ pd_conn_enet1: PD_CONN_ENET_1 {
+ reg = <SC_R_ENET_1>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_conn>;
+ fsl,wakeup_irq = <262>;
+ };
+ pd_conn_nand: PD_CONN_NAND {
+ reg = <SC_R_NAND>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_conn>;
+ };
+ pd_conn_mlb0: PD_CONN_MLB_0 {
+ reg = <SC_R_MLB_0>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_conn>;
+ };
+ pd_conn_edma_ch0: PD_CONN_DMA_4_CH0 {
+ reg = <SC_R_DMA_4_CH0>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_conn>;
+ };
+ pd_conn_edma_ch1: PD_CONN_DMA_4_CH1 {
+ reg = <SC_R_DMA_4_CH1>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_conn>;
+ };
+ pd_conn_edma_ch2: PD_CONN_DMA_4_CH2 {
+ reg = <SC_R_DMA_4_CH2>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_conn>;
+ };
+ pd_conn_edma_ch3: PD_CONN_DMA_4_CH3 {
+ reg = <SC_R_DMA_4_CH3>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_conn>;
+ };
+ pd_conn_edma_ch4: PD_CONN_DMA_4_CH4 {
+ reg = <SC_R_DMA_4_CH4>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_conn>;
+ };
+ };
+
+ pd_hsio: PD_HSIO {
+ compatible = "nxp,imx8-pd";
+ reg = <SC_R_NONE>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_hsio_gpio: PD_HSIO_GPIO {
+ reg = <SC_R_HSIO_GPIO>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_hsio>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_serdes0: PD_HSIO_SERDES_0 {
+ reg = <SC_R_SERDES_0>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_hsio_gpio>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_pcie0: PD_HSIO_PCIE_A {
+ reg = <SC_R_PCIE_A>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_serdes0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_pcie1: PD_HSIO_PCIE_B {
+ reg = <SC_R_PCIE_B>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_pcie0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_serdes1: PD_HSIO_SERDES_1 {
+ reg = <SC_R_SERDES_1>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_pcie1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_sata0: PD_HSIO_SATA_0 {
+ reg = <SC_R_SATA_0>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_serdes1>;
+ };
+ };
+ };
+ };
+ };
+ };
+ };
+
+ pd_audio: PD_AUDIO {
+ compatible = "nxp,imx8-pd";
+ reg = <SC_R_NONE>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_audio_pll0: PD_AUD_AUDIO_PLL_0 {
+ reg = <SC_R_AUDIO_PLL_0>;
+ power-domains =<&pd_audio>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_audio_pll1: PD_AUD_AUDIO_PLL_1 {
+ reg = <SC_R_AUDIO_PLL_1>;
+ power-domains =<&pd_audio_pll0>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_audio_clk0: PD_AUD_AUDIO_CLK_0 {
+ reg = <SC_R_AUDIO_CLK_0>;
+ power-domains =<&pd_audio_pll1>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_audio_clk1: PD_AUD_AUDIO_CLK_1 {
+ reg = <SC_R_AUDIO_CLK_1>;
+ power-domains =<&pd_audio_clk0>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_dma2_chan0: PD_ASRC_0_RXA {
+ reg = <SC_R_DMA_2_CH0>;
+ power-domains =<&pd_audio_clk1>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_dma2_chan1: PD_ASRC_0_RXB {
+ reg = <SC_R_DMA_2_CH1>;
+ power-domains =<&pd_dma2_chan0>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_dma2_chan2: PD_ASRC_0_RXC {
+ reg = <SC_R_DMA_2_CH2>;
+ power-domains =<&pd_dma2_chan1>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_dma2_chan3: PD_ASRC_0_TXA {
+ reg = <SC_R_DMA_2_CH3>;
+ power-domains =<&pd_dma2_chan2>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_dma2_chan4: PD_ASRC_0_TXB {
+ reg = <SC_R_DMA_2_CH4>;
+ power-domains =<&pd_dma2_chan3>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_dma2_chan5: PD_ASRC_0_TXC {
+ reg = <SC_R_DMA_2_CH5>;
+ power-domains =<&pd_dma2_chan4>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_asrc0:PD_AUD_ASRC_0 {
+ reg = <SC_R_ASRC_0>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_dma2_chan5>;
+ };
+ };
+ };
+ };
+ };
+ };
+ };
+
+ pd_dma3_chan0: PD_ASRC_1_RXA {
+ reg = <SC_R_DMA_3_CH0>;
+ power-domains =<&pd_audio_clk1>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_dma3_chan1: PD_ASRC_1_RXB {
+ reg = <SC_R_DMA_3_CH1>;
+ power-domains =<&pd_dma3_chan0>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_dma3_chan2: PD_ASRC_1_RXC {
+ reg = <SC_R_DMA_3_CH2>;
+ power-domains =<&pd_dma3_chan1>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_dma3_chan3: PD_ASRC_1_TXA {
+ reg = <SC_R_DMA_3_CH3>;
+ power-domains =<&pd_dma3_chan2>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_dma3_chan4: PD_ASRC_1_TXB {
+ reg = <SC_R_DMA_3_CH4>;
+ power-domains =<&pd_dma3_chan3>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_dma3_chan5: PD_ASRC_1_TXC {
+ reg = <SC_R_DMA_3_CH5>;
+ power-domains =<&pd_dma3_chan4>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_asrc1: PD_AUD_ASRC_1 {
+ reg = <SC_R_ASRC_1>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_dma3_chan5>;
+
+ };
+ };
+ };
+ };
+ };
+ };
+ };
+ pd_dma2_chan6: PD_ESAI_0_RX {
+ reg = <SC_R_DMA_2_CH6>;
+ power-domains =<&pd_audio_clk1>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_dma2_chan7: PD_ESAI_0_TX {
+ reg = <SC_R_DMA_2_CH7>;
+ power-domains =<&pd_dma2_chan6>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_esai0: PD_AUD_ESAI_0 {
+ reg = <SC_R_ESAI_0>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_dma2_chan7>;
+ };
+ };
+ };
+
+ pd_dma3_chan6: PD_ESAI_1_RX {
+ reg = <SC_R_DMA_3_CH6>;
+ power-domains =<&pd_audio_clk1>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_dma3_chan7: PD_ESAI_1_TX {
+ reg = <SC_R_DMA_3_CH7>;
+ power-domains =<&pd_dma3_chan6>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_esai1: PD_AUD_ESAI_1 {
+ reg = <SC_R_ESAI_1>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_dma3_chan7>;
+ };
+ };
+ };
+ pd_dma2_chan8: PD_SPDIF_0_RX {
+ reg = <SC_R_DMA_2_CH8>;
+ power-domains =<&pd_audio_clk1>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_dma2_chan9: PD_SPDIF_0_TX {
+ reg = <SC_R_DMA_2_CH9>;
+ power-domains =<&pd_dma2_chan8>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_spdif0: PD_AUD_SPDIF_0 {
+ reg = <SC_R_SPDIF_0>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_dma2_chan9>;
+
+ };
+ };
+ };
+ pd_dma2_chan10: PD_SPDIF_1_RX {
+ reg = <SC_R_DMA_2_CH10>;
+ power-domains =<&pd_audio_clk1>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_dma2_chan11: PD_SPDIF_1_TX {
+ reg = <SC_R_DMA_2_CH11>;
+ power-domains =<&pd_dma2_chan10>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_spdif1: PD_AUD_SPDIF_1 {
+ reg = <SC_R_SPDIF_1>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_dma2_chan11>;
+
+ };
+ };
+ };
+ pd_dma2_chan12: PD_SAI_0_RX {
+ reg = <SC_R_DMA_2_CH12>;
+ power-domains =<&pd_audio_clk1>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_dma2_chan13: PD_SAI_0_TX {
+ reg = <SC_R_DMA_2_CH13>;
+ power-domains =<&pd_dma2_chan12>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_sai0:PD_AUD_SAI_0 {
+ reg = <SC_R_SAI_0>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_dma2_chan13>;
+ };
+ };
+
+ };
+ pd_dma2_chan14: PD_SAI_1_RX {
+ reg = <SC_R_DMA_2_CH14>;
+ power-domains =<&pd_audio_clk1>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_dma2_chan15: PD_SAI_1_TX {
+ reg = <SC_R_DMA_2_CH15>;
+ power-domains =<&pd_dma2_chan14>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_sai1: PD_AUD_SAI_1 {
+ reg = <SC_R_SAI_1>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_dma2_chan15>;
+ };
+ };
+ };
+ pd_dma2_chan16: PD_SAI_2_RX {
+ reg = <SC_R_DMA_2_CH16>;
+ power-domains =<&pd_audio_clk1>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pd_sai2: PD_AUD_SAI_2 {
+ reg = <SC_R_SAI_2>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_dma2_chan16>;
+ };
+ };
+ pd_dma2_chan17: PD_SAI_3_RX {
+ reg = <SC_R_DMA_2_CH17>;
+ power-domains =<&pd_audio_clk1>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_sai3: PD_AUD_SAI_3 {
+ reg = <SC_R_SAI_3>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_dma2_chan17>;
+ };
+ };
+ pd_dma2_chan18: PD_SAI_4_RX {
+ reg = <SC_R_DMA_2_CH18>;
+ power-domains =<&pd_audio_clk1>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_sai4: PD_AUD_SAI_4 {
+ reg = <SC_R_SAI_4>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_dma2_chan18>;
+ };
+ };
+ pd_dma2_chan19: PD_SAI_5_RX {
+ reg = <SC_R_DMA_2_CH19>;
+ power-domains =<&pd_audio_clk1>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_sai5: PD_AUD_SAI_5 {
+ reg = <SC_R_SAI_5>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_dma2_chan19>;
+ };
+ };
+ pd_dma3_chan8: PD_SAI_6_RX {
+ reg = <SC_R_DMA_3_CH8>;
+ power-domains =<&pd_audio_clk1>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_dma3_chan9: PD_SAI_6_TX {
+ reg = <SC_R_DMA_3_CH9>;
+ power-domains =<&pd_dma3_chan8>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_sai6: PD_AUD_SAI_6 {
+ reg = <SC_R_SAI_6>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_dma3_chan9>;
+
+ };
+ };
+ };
+ pd_dma3_chan10: PD_SAI_7_TX {
+ reg = <SC_R_DMA_3_CH10>;
+ power-domains =<&pd_audio_clk1>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pd_sai7: PD_AUD_SAI_7 {
+ reg = <SC_R_SAI_7>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_dma3_chan10>;
+ };
+ };
+ pd_gpt5: PD_AUD_GPT_5 {
+ reg = <SC_R_GPT_5>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_audio_clk1>;
+ };
+ pd_gpt6: PD_AUD_GPT_6 {
+ reg = <SC_R_GPT_6>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_audio_clk1>;
+ };
+ pd_gpt7: PD_AUD_GPT_7 {
+ reg = <SC_R_GPT_7>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_audio_clk1>;
+ };
+ pd_gpt8: PD_AUD_GPT_8 {
+ reg = <SC_R_GPT_8>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_audio_clk1>;
+ };
+ pd_gpt9: PD_AUD_GPT_9 {
+ reg = <SC_R_GPT_9>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_audio_clk1>;
+ };
+ pd_gpt10: PD_AUD_GPT_10 {
+ reg = <SC_R_GPT_10>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_audio_clk1>;
+ };
+ pd_amix: PD_AUD_AMIX {
+ reg = <SC_R_AMIX>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_audio_clk1>;
+ };
+ pd_mqs0: PD_AUD_MQS_0 {
+ reg = <SC_R_MQS_0>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_audio_clk1>;
+ };
+ pd_mclk_out0: PD_AUD_MCLK_OUT_0 {
+ reg = <SC_R_MCLK_OUT_0>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_audio_clk1>;
+ };
+ pd_mclk_out1: PD_AUD_MCLK_OUT_1 {
+ reg = <SC_R_MCLK_OUT_1>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_audio_clk1>;
+ };
+ };
+ };
+ };
+ };
+
+ pd_dsp_irqsteer: PD_DSP_MU_A {
+ reg = <SC_R_IRQSTR_DSP>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_audio>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_dsp_mu_A: PD_DSP_MU_A {
+ reg = <SC_R_MU_13A>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_dsp_irqsteer>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_dsp_mu_B: PD_DSP_MU_B {
+ reg = <SC_R_MU_13B>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_dsp_mu_A>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_dsp_ram: PD_AUD_OCRAM {
+ reg = <SC_R_DSP_RAM>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_dsp_mu_B>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pd_dsp: PD_AUD_DSP {
+ reg = <SC_R_DSP>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_dsp_ram>;
+ };
+ };
+ };
+ };
+ };
+ };
+
+ pd_dma: PD_DMA {
+ compatible = "nxp,imx8-pd";
+ reg = <SC_R_NONE>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_dma_flexcan0: PD_DMA_CAN_0 {
+ reg = <SC_R_CAN_0>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_dma>;
+ wakeup-irq = <235>;
+ };
+ pd_dma_flexcan1: PD_DMA_CAN_1 {
+ reg = <SC_R_CAN_1>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_dma>;
+ wakeup-irq = <236>;
+ };
+ pd_dma_flexcan2: PD_DMA_CAN_2 {
+ reg = <SC_R_CAN_2>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_dma>;
+ wakeup-irq = <237>;
+ };
+ pd_dma_ftm0: PD_DMA_FTM_0 {
+ reg = <SC_R_FTM_0>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_dma>;
+ };
+ pd_dma_ftm1: PD_DMA_FTM_1 {
+ reg = <SC_R_FTM_1>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_dma>;
+ };
+ pd_dma_adc0: PD_DMA_ADC_0 {
+ reg = <SC_R_ADC_0>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_dma>;
+ };
+ pd_dma_adc1: PD_DMA_ADC_1 {
+ reg = <SC_R_ADC_1>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_dma>;
+ };
+ pd_dma_lpi2c0: PD_DMA_I2C_0 {
+ reg = <SC_R_I2C_0>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_dma>;
+ };
+ pd_dma_lpi2c1: PD_DMA_I2C_1 {
+ reg = <SC_R_I2C_1>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_dma>;
+ };
+ pd_dma_lpi2c2:PD_DMA_I2C_2 {
+ reg = <SC_R_I2C_2>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_dma>;
+ };
+ pd_dma_lpi2c3: PD_DMA_I2C_3 {
+ reg = <SC_R_I2C_3>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_dma>;
+ };
+ pd_dma_lpi2c4: PD_DMA_I2C_4 {
+ reg = <SC_R_I2C_4>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_dma>;
+ };
+ pd_dma_lpuart0: PD_DMA_UART0 {
+ reg = <SC_R_UART_0>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_dma>;
+ wakeup-irq = <345>;
+ };
+ pd_dma_lpuart1: PD_DMA_UART1 {
+ reg = <SC_R_UART_1>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_dma>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ wakeup-irq = <346>;
+
+ pd_dma0_chan14: PD_UART1_RX {
+ reg = <SC_R_DMA_0_CH14>;
+ power-domains =<&pd_dma_lpuart1>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_dma0_chan15: PD_UART1_TX {
+ reg = <SC_R_DMA_0_CH15>;
+ power-domains =<&pd_dma0_chan14>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ };
+ };
+ pd_dma_lpuart2: PD_DMA_UART2 {
+ reg = <SC_R_UART_2>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_dma>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ wakeup-irq = <347>;
+
+ pd_dma0_chan16: PD_UART2_RX {
+ reg = <SC_R_DMA_0_CH16>;
+ power-domains =<&pd_dma_lpuart2>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_dma0_chan17: PD_UART2_TX {
+ reg = <SC_R_DMA_0_CH17>;
+ power-domains =<&pd_dma0_chan16>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ };
+ };
+ pd_dma_lpuart3: PD_DMA_UART3 {
+ reg = <SC_R_UART_3>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_dma>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ wakeup-irq = <348>;
+
+ pd_dma0_chan18: PD_UART3_RX {
+ reg = <SC_R_DMA_0_CH18>;
+ power-domains =<&pd_dma_lpuart3>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_dma0_chan19: PD_UART3_TX {
+ reg = <SC_R_DMA_0_CH19>;
+ power-domains =<&pd_dma0_chan18>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ };
+ };
+ pd_dma_lpuart4: PD_DMA_UART4 {
+ reg = <SC_R_UART_4>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_dma>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ wakeup-irq = <349>;
+
+ pd_dma0_chan20: PD_UART4_RX {
+ reg = <SC_R_DMA_0_CH20>;
+ power-domains =<&pd_dma_lpuart4>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_dma0_chan21: PD_UART4_TX {
+ reg = <SC_R_DMA_0_CH21>;
+ power-domains =<&pd_dma0_chan20>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ };
+ };
+ pd_dma_lpspi0: PD_DMA_SPI_0 {
+ reg = <SC_R_SPI_0>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_dma>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_dma0_chan0: PD_LPSPI0_RX {
+ reg = <SC_R_DMA_0_CH0>;
+ power-domains =<&pd_dma_lpspi0>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_dma0_chan1: PD_LPSPI0_TX {
+ reg = <SC_R_DMA_0_CH1>;
+ power-domains =<&pd_dma0_chan0>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ };
+ };
+ pd_dma_lpspi1: PD_DMA_SPI_1 {
+ reg = <SC_R_SPI_1>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_dma>;
+ };
+ pd_dma_lpspi2: PD_DMA_SPI_2 {
+ reg = <SC_R_SPI_2>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_dma>;
+ };
+ pd_dma_lpspi3: PD_DMA_SPI_3 {
+ reg = <SC_R_SPI_3>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_dma>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_dma0_chan6: PD_LPSPI3_RX {
+ reg = <SC_R_DMA_0_CH6>;
+ power-domains =<&pd_dma_lpspi3>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_dma0_chan7: PD_LPSPI3_TX {
+ reg = <SC_R_DMA_0_CH7>;
+ power-domains =<&pd_dma0_chan6>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ };
+ };
+ pd_dma_emvsim0: PD_DMA_EMVSIM_0 {
+ reg = <SC_R_EMVSIM_0>;
+ power-domains = <&pd_dma>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_ldo1_sim: LDO1_SIM {
+ reg = <SC_R_BOARD_R2>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_dma_emvsim0>;
+ };
+ };
+ pd_dma_emvsim1: PD_DMA_EMVSIM_1 {
+ reg = <SC_R_EMVSIM_1>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_dma>;
+ };
+ };
+ pd_gpu: PD_GPU {
+ compatible = "nxp,imx8-pd";
+ reg = <SC_R_NONE>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_gpu0: PD_GPU0 {
+ reg = <SC_R_GPU_0_PID0>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_gpu>;
+ };
+ pd_gpu1: PD_GPU1 {
+ reg = <SC_R_GPU_1_PID0>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_gpu>;
+ };
+ };
+
+ pd_vpu: vpu-power-domain {
+ compatible = "nxp,imx8-pd";
+ reg = <SC_R_VPU>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_vpu_mu1_enc: VPU_ENC_MU1 {
+ reg = <SC_R_VPU_MU_2>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_vpu>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_vpu_enc1: VPU_ENC1 {
+ reg = <SC_R_VPU_ENC_1>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_vpu_mu1_enc>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_vpu_mu_enc: VPU_ENC_MU {
+ reg = <SC_R_VPU_MU_1>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_vpu_enc1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_vpu_enc: VPU_ENC {
+ reg = <SC_R_VPU_ENC_0>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_vpu_mu_enc>;
+ };
+ };
+ };
+ };
+
+ pd_vpu_mu_dec: VPU_DEC_MU {
+ reg = <SC_R_VPU_MU_0>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_vpu>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_vpu_dec: VPU_DEC {
+ reg = <SC_R_VPU_DEC_0>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_vpu_mu_dec>;
+ };
+ };
+ };
+
+
+ pd_isi_ch0: PD_IMAGING {
+ compatible = "nxp,imx8-pd";
+ reg = <SC_R_ISI_CH0>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_csi0: PD_MIPI_CSI0 {
+ reg = <SC_R_CSI_0>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_isi_ch0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_csi0_i2c0: PD_MIPI_CSI0_I2C0 {
+ reg = <SC_R_CSI_0_I2C_0>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_csi0>;
+ };
+
+ pd_csi0_pwm: PD_MIPI_CSI0_PWM {
+ reg = <SC_R_CSI_0_PWM_0>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_csi0>;
+ };
+ };
+
+ pd_csi1: PD_MIPI_CSI1 {
+ reg = <SC_R_CSI_1>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_isi_ch0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_csi1_i2c0: PD_MIPI_CSI1_I2C0 {
+ reg = <SC_R_CSI_1_I2C_0>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_csi1>;
+ };
+
+ pd_csi1_pwm: PD_MIPI_CSI1_PWM {
+ reg = <SC_R_CSI_1_PWM_0>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_csi1>;
+ };
+ };
+
+ pd_hdmi_rx: PD_HDMI_RX {
+ reg = <SC_R_HDMI_RX>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_isi_ch0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_hdmi_rx_bypass: PD_HDMI_RX_BYPASS {
+ reg = <SC_R_HDMI_RX_BYPASS>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_hdmi_rx>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_hdmi_rx_i2c0: PD_HDMI_RX_I2C {
+ reg = <SC_R_HDMI_RX_I2C_0>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_hdmi_rx_bypass>;
+ };
+
+ pd_hdmi_rx_pwm0: PD_HDMI_RX_PWM {
+ reg = <SC_R_HDMI_RX_PWM_0>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_hdmi_rx_bypass>;
+ };
+ };
+ };
+
+ pd_isi_ch1: PD_IMAGING_PDMA1 {
+ reg = <SC_R_ISI_CH1>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_isi_ch0>;
+ };
+
+ pd_isi_ch2: PD_IMAGING_PDMA2 {
+ reg = <SC_R_ISI_CH2>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_isi_ch0>;
+ };
+
+ pd_isi_ch3: PD_IMAGING_PDMA3 {
+ reg = <SC_R_ISI_CH3>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_isi_ch0>;
+ };
+
+ pd_isi_ch4: PD_IMAGING_PDMA4 {
+ reg = <SC_R_ISI_CH4>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_isi_ch0>;
+ };
+
+ pd_isi_ch5: PD_IMAGING_PDMA5 {
+ reg = <SC_R_ISI_CH5>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_isi_ch0>;
+ };
+
+ pd_isi_ch6: PD_IMAGING_PDMA6 {
+ reg = <SC_R_ISI_CH6>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_isi_ch0>;
+ };
+
+ pd_isi_ch7: PD_IMAGING_PDMA7 {
+ reg = <SC_R_ISI_CH7>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_isi_ch0>;
+ };
+
+ pd_jpeg_dec_mp: PD_JPEG_DEC_MP {
+ reg = <SC_R_MJPEG_DEC_MP>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_isi_ch0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_jpgdec: PD_IMAGING_JPEG_DEC {
+ reg = <SC_R_MJPEG_DEC_S0>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_jpeg_dec_mp>;
+ };
+ };
+
+ pd_jpeg_enc_mp: PD_JPEG_ENC_MP {
+ reg = <SC_R_MJPEG_ENC_MP>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_isi_ch0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_jpgenc: PD_IMAGING_JPEG_ENC {
+ reg = <SC_R_MJPEG_ENC_S0>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_jpeg_enc_mp>;
+ };
+ };
+ };
+
+ pd_cm40: PD_CM40 {
+ compatible = "nxp,imx8-pd";
+ reg = <SC_R_NONE>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_cm40_i2c: PD_CM40_I2C {
+ reg = <SC_R_M4_0_I2C>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_cm40>;
+ };
+
+ pd_cm40_intmux: PD_CM40_INTMUX {
+ reg = <SC_R_M4_0_INTMUX>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_cm40>;
+ };
+ };
+
+ pd_cm41: PD_CM41 {
+ compatible = "nxp,imx8-pd";
+ reg = <SC_R_NONE>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_cm41_intmux: PD_CM41_INTMUX {
+ reg = <SC_R_M4_1_INTMUX>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_cm41>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ early_power_on;
+
+ pd_cm41_i2c: PD_CM41_I2C {
+ reg = <SC_R_M4_1_I2C>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_cm41_intmux>;
+ };
+ };
+ };
+
+ pd_caam: PD_CAAM {
+ compatible = "nxp,imx8-pd";
+ reg = <SC_R_NONE>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_caam_jr1: PD_CAAM_JR1 {
+ reg = <SC_R_CAAM_JR1>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_caam>;
+ };
+ pd_caam_jr2: PD_CAAM_JR2 {
+ reg = <SC_R_CAAM_JR2>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_caam>;
+ };
+ pd_caam_jr3: PD_CAAM_JR3 {
+ reg = <SC_R_CAAM_JR3>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_caam>;
+ };
+ };
+ };
+
+ tsens: thermal-sensor {
+ compatible = "nxp,imx8qm-sc-tsens";
+ /* number of the temp sensor on the chip */
+ tsens-num = <5>;
+ #thermal-sensor-cells = <1>;
+ };
+
+ thermal_zones: thermal-zones {
+ /* cpu thermal */
+ cpu-thermal0 {
+ polling-delay-passive = <250>;
+ polling-delay = <2000>;
+ /*the slope and offset of the temp sensor */
+ thermal-sensors = <&tsens 0>;
+ trips {
+ cpu_alert0: trip0 {
+ temperature = <107000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+ cpu_crit0: trip1 {
+ temperature = <127000>;
+ hysteresis = <2000>;
+ type = "critical";
+ };
+ };
+ cooling-maps {
+ map0 {
+ trip = <&cpu_alert0>;
+ cooling-device =
+ <&A53_0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
+ };
+
+ cpu-thermal1 {
+ polling-delay-passive = <250>;
+ polling-delay = <2000>;
+ thermal-sensors = <&tsens 1>;
+ trips {
+ cpu_alert1: trip0 {
+ temperature = <107000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+ cpu_crit1: trip1 {
+ temperature = <127000>;
+ hysteresis = <2000>;
+ type = "critical";
+ };
+ };
+ cooling-maps {
+ map0 {
+ trip = <&cpu_alert1>;
+ cooling-device =
+ <&A72_0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
+ };
+
+ gpu-thermal0 {
+ polling-delay-passive = <250>;
+ polling-delay = <2000>;
+ thermal-sensors = <&tsens 2>;
+ trips {
+ gpu_alert0: trip0 {
+ temperature = <107000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+ gpu_crit0: trip1 {
+ temperature = <127000>;
+ hysteresis = <2000>;
+ type = "critical";
+ };
+ };
+ };
+
+ gpu-thermal1 {
+ polling-delay-passive = <250>;
+ polling-delay = <2000>;
+ thermal-sensors = <&tsens 3>;
+ trips {
+ gpu_alert1: trip0 {
+ temperature = <107000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+ gpu_crit1: trip1 {
+ temperature = <127000>;
+ hysteresis = <2000>;
+ type = "critical";
+ };
+ };
+ };
+
+ drc-thermal0 {
+ polling-delay-passive = <250>;
+ polling-delay = <2000>;
+ thermal-sensors = <&tsens 4>;
+ trips {
+ drc_alert0: trip0 {
+ temperature = <107000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+ drc_crit0: trip1 {
+ temperature = <127000>;
+ hysteresis = <2000>;
+ type = "critical";
+ };
+ };
+ };
+ };
+
+ rtc: rtc {
+ compatible = "fsl,imx-sc-rtc";
+ };
+
+ dpu1_intsteer: dpu_intsteer@56000000 {
+ compatible = "fsl,imx8qm-dpu-intsteer", "syscon";
+ reg = <0x0 0x56000000 0x0 0x10000>;
+ };
+
+ pixel_combiner1: pixel-combiner@56020000 {
+ compatible = "fsl,imx8qm-pixel-combiner";
+ reg = <0x0 0x56020000 0x0 0x10000>;
+ power-domains = <&pd_dc0>;
+ status = "disabled";
+ };
+
+ prg1: prg@56040000 {
+ compatible = "fsl,imx8qm-prg";
+ reg = <0x0 0x56040000 0x0 0x10000>;
+ clocks = <&clk IMX8QM_DC0_PRG0_APB_CLK>,
+ <&clk IMX8QM_DC0_PRG0_RTRAM_CLK>;
+ clock-names = "apb", "rtram";
+ power-domains = <&pd_dc0>;
+ status = "disabled";
+ };
+
+ prg2: prg@56050000 {
+ compatible = "fsl,imx8qm-prg";
+ reg = <0x0 0x56050000 0x0 0x10000>;
+ clocks = <&clk IMX8QM_DC0_PRG1_APB_CLK>,
+ <&clk IMX8QM_DC0_PRG1_RTRAM_CLK>;
+ clock-names = "apb", "rtram";
+ power-domains = <&pd_dc0>;
+ status = "disabled";
+ };
+
+ prg3: prg@56060000 {
+ compatible = "fsl,imx8qm-prg";
+ reg = <0x0 0x56060000 0x0 0x10000>;
+ clocks = <&clk IMX8QM_DC0_PRG2_APB_CLK>,
+ <&clk IMX8QM_DC0_PRG2_RTRAM_CLK>;
+ clock-names = "apb", "rtram";
+ power-domains = <&pd_dc0>;
+ status = "disabled";
+ };
+
+ prg4: prg@56070000 {
+ compatible = "fsl,imx8qm-prg";
+ reg = <0x0 0x56070000 0x0 0x10000>;
+ clocks = <&clk IMX8QM_DC0_PRG3_APB_CLK>,
+ <&clk IMX8QM_DC0_PRG3_RTRAM_CLK>;
+ clock-names = "apb", "rtram";
+ power-domains = <&pd_dc0>;
+ status = "disabled";
+ };
+
+ prg5: prg@56080000 {
+ compatible = "fsl,imx8qm-prg";
+ reg = <0x0 0x56080000 0x0 0x10000>;
+ clocks = <&clk IMX8QM_DC0_PRG4_APB_CLK>,
+ <&clk IMX8QM_DC0_PRG4_RTRAM_CLK>;
+ clock-names = "apb", "rtram";
+ power-domains = <&pd_dc0>;
+ status = "disabled";
+ };
+
+ prg6: prg@56090000 {
+ compatible = "fsl,imx8qm-prg";
+ reg = <0x0 0x56090000 0x0 0x10000>;
+ clocks = <&clk IMX8QM_DC0_PRG5_APB_CLK>,
+ <&clk IMX8QM_DC0_PRG5_RTRAM_CLK>;
+ clock-names = "apb", "rtram";
+ power-domains = <&pd_dc0>;
+ status = "disabled";
+ };
+
+ prg7: prg@560a0000 {
+ compatible = "fsl,imx8qm-prg";
+ reg = <0x0 0x560a0000 0x0 0x10000>;
+ clocks = <&clk IMX8QM_DC0_PRG6_APB_CLK>,
+ <&clk IMX8QM_DC0_PRG6_RTRAM_CLK>;
+ clock-names = "apb", "rtram";
+ power-domains = <&pd_dc0>;
+ status = "disabled";
+ };
+
+ prg8: prg@560b0000 {
+ compatible = "fsl,imx8qm-prg";
+ reg = <0x0 0x560b0000 0x0 0x10000>;
+ clocks = <&clk IMX8QM_DC0_PRG7_APB_CLK>,
+ <&clk IMX8QM_DC0_PRG7_RTRAM_CLK>;
+ clock-names = "apb", "rtram";
+ power-domains = <&pd_dc0>;
+ status = "disabled";
+ };
+
+ prg9: prg@560c0000 {
+ compatible = "fsl,imx8qm-prg";
+ reg = <0x0 0x560c0000 0x0 0x10000>;
+ clocks = <&clk IMX8QM_DC0_PRG8_APB_CLK>,
+ <&clk IMX8QM_DC0_PRG8_RTRAM_CLK>;
+ clock-names = "apb", "rtram";
+ power-domains = <&pd_dc0>;
+ status = "disabled";
+ };
+
+ dpr1_channel1: dpr-channel@560d0000 {
+ compatible = "fsl,imx8qm-dpr-channel";
+ reg = <0x0 0x560d0000 0x0 0x10000>;
+ fsl,sc-resource = <SC_R_DC_0_BLIT0>;
+ fsl,prgs = <&prg1>;
+ clocks = <&clk IMX8QM_DC0_DPR0_APB_CLK>,
+ <&clk IMX8QM_DC0_DPR0_B_CLK>,
+ <&clk IMX8QM_DC0_RTRAM0_CLK>;
+ clock-names = "apb", "b", "rtram";
+ power-domains = <&pd_dc0>;
+ status = "disabled";
+ };
+
+ dpr1_channel2: dpr-channel@560e0000 {
+ compatible = "fsl,imx8qm-dpr-channel";
+ reg = <0x0 0x560e0000 0x0 0x10000>;
+ fsl,sc-resource = <SC_R_DC_0_BLIT1>;
+ fsl,prgs = <&prg2>, <&prg1>;
+ clocks = <&clk IMX8QM_DC0_DPR0_APB_CLK>,
+ <&clk IMX8QM_DC0_DPR0_B_CLK>,
+ <&clk IMX8QM_DC0_RTRAM0_CLK>;
+ clock-names = "apb", "b", "rtram";
+ power-domains = <&pd_dc0>;
+ status = "disabled";
+ };
+
+ dpr1_channel3: dpr-channel@560f0000 {
+ compatible = "fsl,imx8qm-dpr-channel";
+ reg = <0x0 0x560f0000 0x0 0x10000>;
+ fsl,sc-resource = <SC_R_DC_0_FRAC0>;
+ fsl,prgs = <&prg3>;
+ clocks = <&clk IMX8QM_DC0_DPR0_APB_CLK>,
+ <&clk IMX8QM_DC0_DPR0_B_CLK>,
+ <&clk IMX8QM_DC0_RTRAM0_CLK>;
+ clock-names = "apb", "b", "rtram";
+ power-domains = <&pd_dc0>;
+ status = "disabled";
+ };
+
+ dpr2_channel1: dpr-channel@56100000 {
+ compatible = "fsl,imx8qm-dpr-channel";
+ reg = <0x0 0x56100000 0x0 0x10000>;
+ fsl,sc-resource = <SC_R_DC_0_VIDEO0>;
+ fsl,prgs = <&prg4>, <&prg5>;
+ clocks = <&clk IMX8QM_DC0_DPR1_APB_CLK>,
+ <&clk IMX8QM_DC0_DPR1_B_CLK>,
+ <&clk IMX8QM_DC0_RTRAM1_CLK>;
+ clock-names = "apb", "b", "rtram";
+ power-domains = <&pd_dc0>;
+ status = "disabled";
+ };
+
+ dpr2_channel2: dpr-channel@56110000 {
+ compatible = "fsl,imx8qm-dpr-channel";
+ reg = <0x0 0x56110000 0x0 0x10000>;
+ fsl,sc-resource = <SC_R_DC_0_VIDEO1>;
+ fsl,prgs = <&prg6>, <&prg7>;
+ clocks = <&clk IMX8QM_DC0_DPR1_APB_CLK>,
+ <&clk IMX8QM_DC0_DPR1_B_CLK>,
+ <&clk IMX8QM_DC0_RTRAM1_CLK>;
+ clock-names = "apb", "b", "rtram";
+ power-domains = <&pd_dc0>;
+ status = "disabled";
+ };
+
+ dpr2_channel3: dpr-channel@56120000 {
+ compatible = "fsl,imx8qm-dpr-channel";
+ reg = <0x0 0x56120000 0x0 0x10000>;
+ fsl,sc-resource = <SC_R_DC_0_WARP>;
+ fsl,prgs = <&prg8>, <&prg9>;
+ clocks = <&clk IMX8QM_DC0_DPR1_APB_CLK>,
+ <&clk IMX8QM_DC0_DPR1_B_CLK>,
+ <&clk IMX8QM_DC0_RTRAM1_CLK>;
+ clock-names = "apb", "b", "rtram";
+ power-domains = <&pd_dc0>;
+ status = "disabled";
+ };
+
+ dpu1: dpu@56180000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx8qm-dpu";
+ reg = <0x0 0x56180000 0x0 0x40000>;
+ intsteer = <&dpu1_intsteer>;
+ interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 47 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 50 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "irq_common",
+ "irq_stream0a",
+ "irq_stream0b", /* to M4? */
+ "irq_stream1a",
+ "irq_stream1b", /* to M4? */
+ "irq_reserved0",
+ "irq_reserved1",
+ "irq_blit",
+ "irq_dpr0",
+ "irq_dpr1";
+ clocks = <&clk IMX8QM_DC0_PLL0_CLK>,
+ <&clk IMX8QM_DC0_PLL1_CLK>,
+ <&clk IMX8QM_DC0_BYPASS_0_DIV>,
+ <&clk IMX8QM_DC0_DISP0_SEL>,
+ <&clk IMX8QM_DC0_DISP1_SEL>,
+ <&clk IMX8QM_DC0_DISP0_CLK>,
+ <&clk IMX8QM_DC0_DISP1_CLK>;
+ clock-names = "pll0", "pll1", "bypass0",
+ "disp0_sel", "disp1_sel", "disp0", "disp1";
+ power-domains = <&pd_dc0_pll1>;
+ fsl,dpr-channels = <&dpr1_channel1>, <&dpr1_channel2>,
+ <&dpr1_channel3>, <&dpr2_channel1>,
+ <&dpr2_channel2>, <&dpr2_channel3>;
+ fsl,pixel-combiner = <&pixel_combiner1>;
+ status = "disabled";
+
+ dpu1_disp0: port@0 {
+ reg = <0>;
+
+ dpu1_disp0_hdmi: hdmi-endpoint {
+ remote-endpoint = <&hdmi_disp>;
+ };
+
+ dpu1_disp0_mipi_dsi: mipi-dsi-endpoint {
+ remote-endpoint = <&mipi_dsi1_in>;
+ };
+ };
+
+ dpu1_disp1: port@1 {
+ reg = <1>;
+
+ dpu1_disp1_lvds0: lvds0-endpoint {
+ remote-endpoint = <&ldb1_lvds0>;
+ };
+
+ dpu1_disp1_lvds1: lvds1-endpoint {
+ remote-endpoint = <&ldb1_lvds1>;
+ };
+ };
+ };
+
+ hdmi:hdmi@56268000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x0 0x56268000 0x0 0x100000>, /* HDP Controller */
+ <0x0 0x56261000 0x0 0x1000>; /* HDP SubSystem CSR */
+ interrupts = <10 IRQ_TYPE_LEVEL_HIGH>,
+ <13 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "plug_in", "plug_out";
+ interrupt-parent = <&irqsteer_hdmi>;
+ status = "disabled";
+ clocks = <&clk IMX8QM_HDMI_DIG_PLL_CLK>,
+ <&clk IMX8QM_HDMI_AV_PLL_CLK>,
+ <&clk IMX8QM_HDMI_IPG_CLK>,
+ <&clk IMX8QM_HDMI_HDP_CORE_CLK>,
+ <&clk IMX8QM_HDMI_PXL_CLK>,
+ <&clk IMX8QM_HDMI_PXL_MUX_CLK>,
+ <&clk IMX8QM_HDMI_PXL_LINK_CLK>,
+ <&clk IMX8QM_HDMI_HDP_CLK>,
+ <&clk IMX8QM_HDMI_HDP_PHY_CLK>,
+ <&clk IMX8QM_HDMI_APB_CLK>,
+ <&clk IMX8QM_HDMI_LIS_IPG_CLK>,
+ <&clk IMX8QM_HDMI_MSI_HCLK>,
+ <&clk IMX8QM_HDMI_PXL_LPCG_CLK>,
+ <&clk IMX8QM_HDMI_PXL_EVEN_CLK>,
+ <&clk IMX8QM_HDMI_PXL_DBL_CLK>,
+ <&clk IMX8QM_HDMI_VIF_CLK>,
+ <&clk IMX8QM_HDMI_APB_MUX_CSR_CLK>,
+ <&clk IMX8QM_HDMI_APB_MUX_CTRL_CLK>,
+ <&clk IMX8QM_HDMI_I2S_CLK>,
+ <&clk IMX8QM_HDMI_I2S_BYPASS_CLK>;
+ clock-names = "dig_pll", "av_pll", "clk_ipg",
+ "clk_core", "clk_pxl", "clk_pxl_mux",
+ "clk_pxl_link", "clk_hdp", "clk_phy",
+ "clk_apb", "clk_lis","clk_msi",
+ "clk_lpcg", "clk_even","clk_dbl",
+ "clk_vif", "clk_apb_csr","clk_apb_ctrl",
+ "clk_i2s", "clk_i2s_bypass";
+ power-domains = <&pd_hdmi_i2s>;
+
+ port@0 {
+ reg = <0>;
+ hdmi_disp: endpoint {
+ remote-endpoint = <&dpu1_disp0_hdmi>;
+ };
+ };
+ };
+
+ irqsteer_dsi0: irqsteer@56220000 {
+ compatible = "nxp,imx-irqsteer";
+ reg = <0x0 0x56220000 0x0 0x1000>;
+ interrupts = <GIC_SPI 59 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-controller;
+ interrupt-parent = <&gic>;
+ #interrupt-cells = <2>;
+ clocks = <&clk IMX8QM_MIPI0_LIS_IPG_CLK>;
+ clock-names = "ipg";
+ power-domains = <&pd_mipi0>;
+ };
+
+ i2c0_mipi_dsi0: i2c@56226000 {
+ compatible = "fsl,imx8qm-lpi2c";
+ reg = <0x0 0x56226000 0x0 0x1000>;
+ interrupts = <8 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-parent = <&irqsteer_dsi0>;
+ clocks = <&clk IMX8QM_MIPI0_I2C0_CLK>,
+ <&clk IMX8QM_MIPI0_I2C0_IPG_CLK>;
+ clock-names = "per", "ipg";
+ assigned-clocks = <&clk IMX8QM_MIPI0_I2C0_CLK>;
+ assigned-clock-rates = <24000000>;
+ power-domains = <&pd_mipi0_i2c0>;
+ status = "disabled";
+ };
+
+ mipi_dsi_csr1: csr@56221000 {
+ compatible = "fsl,imx8qm-mipi-dsi-csr", "syscon";
+ reg = <0x0 0x56221000 0x0 0x1000>;
+ };
+
+ mipi_dsi_phy1: dsi_phy@56228300 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "mixel,imx8qm-mipi-dsi-phy";
+ reg = <0x0 0x56228300 0x0 0x100>;
+ power-domains = <&pd_mipi0>;
+ #phy-cells = <0>;
+ status = "disabled";
+ };
+
+ mipi_dsi1: mipi_dsi@56228000 {
+ compatible = "fsl,imx8qm-mipi-dsi";
+ clocks =
+ <&clk IMX8QM_MIPI0_PXL_CLK>,
+ <&clk IMX8QM_MIPI0_BYPASS_CLK>,
+ <&clk IMX8QM_MIPI0_DSI_PHY_CLK>;
+ clock-names = "pixel", "bypass", "phy_ref";
+ power-domains = <&pd_mipi0>;
+ csr = <&mipi_dsi_csr1>;
+ phys = <&mipi_dsi_phy1>;
+ phy-names = "dphy";
+ pwr-delay = <100>;
+ status = "disabled";
+
+ port@0 {
+ mipi_dsi1_in: endpoint {
+ remote-endpoint = <&dpu1_disp0_mipi_dsi>;
+ };
+ };
+
+ port@1 {
+ mipi_dsi1_out: endpoint {
+ remote-endpoint = <&mipi_dsi_bridge1_in>;
+ };
+ };
+ };
+
+ mipi_dsi_bridge1: mipi_dsi_bridge@56228000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "nwl,mipi-dsi";
+ reg = <0x0 0x56228000 0x0 0x300>;
+ interrupts = <16 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-parent = <&irqsteer_dsi0>;
+ clocks =
+ <&clk IMX8QM_MIPI0_BYPASS_CLK>,
+ <&clk IMX8QM_MIPI0_DSI_TX_ESC_CLK>,
+ <&clk IMX8QM_MIPI0_DSI_RX_ESC_CLK>;
+ clock-names = "phy_ref", "tx_esc", "rx_esc";
+ assigned-clocks = <&clk IMX8QM_MIPI0_DSI_TX_ESC_DIV>,
+ <&clk IMX8QM_MIPI0_DSI_RX_ESC_DIV>;
+ assigned-clock-rates = <18000000>, <72000000>;
+ power-domains = <&pd_mipi0>;
+ phys = <&mipi_dsi_phy1>;
+ phy-names = "dphy";
+ status = "disabled";
+
+ port@0 {
+ mipi_dsi_bridge1_in: endpoint {
+ remote-endpoint = <&mipi_dsi1_out>;
+ };
+ };
+ };
+
+ lvds_region1: lvds_region@56240000 {
+ compatible = "fsl,imx8qm-lvds-region", "syscon";
+ reg = <0x0 0x56240000 0x0 0x10000>;
+ };
+
+ ldb1_phy: ldb_phy@56241000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "mixel,lvds-phy";
+ reg = <0x0 0x56241000 0x0 0x100>;
+ clocks = <&clk IMX8QM_LVDS0_PHY_CLK>;
+ clock-names = "phy";
+ power-domains = <&pd_lvds0>;
+ status = "disabled";
+
+ ldb1_phy1: port@0 {
+ reg = <0>;
+ #phy-cells = <0>;
+ };
+
+ ldb1_phy2: port@1 {
+ reg = <1>;
+ #phy-cells = <0>;
+ };
+ };
+
+ ldb1: ldb@562410e0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx8qm-ldb";
+ clocks = <&clk IMX8QM_LVDS0_PIXEL_CLK>,
+ <&clk IMX8QM_LVDS0_BYPASS_CLK>;
+ clock-names = "pixel", "bypass";
+ power-domains = <&pd_lvds0>;
+ gpr = <&lvds_region1>;
+ status = "disabled";
+
+ lvds-channel@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0>;
+ phys = <&ldb1_phy1>;
+ phy-names = "ldb_phy";
+ status = "disabled";
+
+ port@0 {
+ reg = <0>;
+
+ ldb1_lvds0: endpoint {
+ remote-endpoint = <&dpu1_disp1_lvds0>;
+ };
+ };
+ };
+
+ lvds-channel@1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <1>;
+ phys = <&ldb1_phy2>;
+ phy-names = "ldb_phy";
+ status = "disabled";
+
+ port@0 {
+ reg = <0>;
+
+ ldb1_lvds1: endpoint {
+ remote-endpoint = <&dpu1_disp1_lvds1>;
+ };
+ };
+ };
+ };
+
+ lvds0_pwm: pwm@56244000 {
+ compatible = "fsl,imx8qm-pwm", "fsl,imx27-pwm";
+ reg = <0x0 0x56244000 0 0x1000>;
+ clocks = <&clk IMX8QM_LVDS0_PWM0_IPG_CLK>,
+ <&clk IMX8QM_LVDS0_PWM0_CLK>;
+ clock-names = "ipg", "per";
+ assigned-clocks = <&clk IMX8QM_LVDS0_PWM0_CLK>;
+ assigned-clock-rates = <24000000>;
+ #pwm-cells = <2>;
+ power-domains = <&pd_lvds0_pwm>;
+ status = "disabled";
+ };
+
+ dpu2_intsteer: dpu_intsteer@57000000 {
+ compatible = "fsl,imx8qm-dpu-intsteer", "syscon";
+ reg = <0x0 0x57000000 0x0 0x10000>;
+ };
+
+ pixel_combiner2: pixel-combiner@57020000 {
+ compatible = "fsl,imx8qm-pixel-combiner";
+ reg = <0x0 0x57020000 0x0 0x10000>;
+ power-domains = <&pd_dc1>;
+ status = "disabled";
+ };
+
+ prg10: prg@57040000 {
+ compatible = "fsl,imx8qm-prg";
+ reg = <0x0 0x57040000 0x0 0x10000>;
+ clocks = <&clk IMX8QM_DC1_PRG0_APB_CLK>,
+ <&clk IMX8QM_DC1_PRG0_RTRAM_CLK>;
+ clock-names = "apb", "rtram";
+ power-domains = <&pd_dc1>;
+ status = "disabled";
+ };
+
+ prg11: prg@57050000 {
+ compatible = "fsl,imx8qm-prg";
+ reg = <0x0 0x57050000 0x0 0x10000>;
+ clocks = <&clk IMX8QM_DC1_PRG1_APB_CLK>,
+ <&clk IMX8QM_DC1_PRG1_RTRAM_CLK>;
+ clock-names = "apb", "rtram";
+ power-domains = <&pd_dc1>;
+ status = "disabled";
+ };
+
+ prg12: prg@57060000 {
+ compatible = "fsl,imx8qm-prg";
+ reg = <0x0 0x57060000 0x0 0x10000>;
+ clocks = <&clk IMX8QM_DC1_PRG2_APB_CLK>,
+ <&clk IMX8QM_DC1_PRG2_RTRAM_CLK>;
+ clock-names = "apb", "rtram";
+ power-domains = <&pd_dc1>;
+ status = "disabled";
+ };
+
+ prg13: prg@57070000 {
+ compatible = "fsl,imx8qm-prg";
+ reg = <0x0 0x57070000 0x0 0x10000>;
+ clocks = <&clk IMX8QM_DC1_PRG3_APB_CLK>,
+ <&clk IMX8QM_DC1_PRG3_RTRAM_CLK>;
+ clock-names = "apb", "rtram";
+ power-domains = <&pd_dc1>;
+ status = "disabled";
+ };
+
+ prg14: prg@57080000 {
+ compatible = "fsl,imx8qm-prg";
+ reg = <0x0 0x57080000 0x0 0x10000>;
+ clocks = <&clk IMX8QM_DC1_PRG4_APB_CLK>,
+ <&clk IMX8QM_DC1_PRG4_RTRAM_CLK>;
+ clock-names = "apb", "rtram";
+ power-domains = <&pd_dc1>;
+ status = "disabled";
+ };
+
+ prg15: prg@57090000 {
+ compatible = "fsl,imx8qm-prg";
+ reg = <0x0 0x57090000 0x0 0x10000>;
+ clocks = <&clk IMX8QM_DC1_PRG5_APB_CLK>,
+ <&clk IMX8QM_DC1_PRG5_RTRAM_CLK>;
+ clock-names = "apb", "rtram";
+ power-domains = <&pd_dc1>;
+ status = "disabled";
+ };
+
+ prg16: prg@570a0000 {
+ compatible = "fsl,imx8qm-prg";
+ reg = <0x0 0x570a0000 0x0 0x10000>;
+ clocks = <&clk IMX8QM_DC1_PRG6_APB_CLK>,
+ <&clk IMX8QM_DC1_PRG6_RTRAM_CLK>;
+ clock-names = "apb", "rtram";
+ power-domains = <&pd_dc1>;
+ status = "disabled";
+ };
+
+ prg17: prg@570b0000 {
+ compatible = "fsl,imx8qm-prg";
+ reg = <0x0 0x570b0000 0x0 0x10000>;
+ clocks = <&clk IMX8QM_DC1_PRG7_APB_CLK>,
+ <&clk IMX8QM_DC1_PRG7_RTRAM_CLK>;
+ clock-names = "apb", "rtram";
+ power-domains = <&pd_dc1>;
+ status = "disabled";
+ };
+
+ prg18: prg@570c0000 {
+ compatible = "fsl,imx8qm-prg";
+ reg = <0x0 0x570c0000 0x0 0x10000>;
+ clocks = <&clk IMX8QM_DC1_PRG8_APB_CLK>,
+ <&clk IMX8QM_DC1_PRG8_RTRAM_CLK>;
+ clock-names = "apb", "rtram";
+ power-domains = <&pd_dc1>;
+ status = "disabled";
+ };
+
+ dpr3_channel1: dpr-channel@570d0000 {
+ compatible = "fsl,imx8qm-dpr-channel";
+ reg = <0x0 0x570d0000 0x0 0x10000>;
+ fsl,sc-resource = <SC_R_DC_1_BLIT0>;
+ fsl,prgs = <&prg10>;
+ clocks = <&clk IMX8QM_DC1_DPR0_APB_CLK>,
+ <&clk IMX8QM_DC1_DPR0_B_CLK>,
+ <&clk IMX8QM_DC1_RTRAM0_CLK>;
+ clock-names = "apb", "b", "rtram";
+ power-domains = <&pd_dc1>;
+ status = "disabled";
+ };
+
+ dpr3_channel2: dpr-channel@570e0000 {
+ compatible = "fsl,imx8qm-dpr-channel";
+ reg = <0x0 0x570e0000 0x0 0x10000>;
+ fsl,sc-resource = <SC_R_DC_1_BLIT1>;
+ fsl,prgs = <&prg11>, <&prg10>;
+ clocks = <&clk IMX8QM_DC1_DPR0_APB_CLK>,
+ <&clk IMX8QM_DC1_DPR0_B_CLK>,
+ <&clk IMX8QM_DC1_RTRAM0_CLK>;
+ clock-names = "apb", "b", "rtram";
+ power-domains = <&pd_dc1>;
+ status = "disabled";
+ };
+
+ dpr3_channel3: dpr-channel@570f0000 {
+ compatible = "fsl,imx8qm-dpr-channel";
+ reg = <0x0 0x570f0000 0x0 0x10000>;
+ fsl,sc-resource = <SC_R_DC_1_FRAC0>;
+ fsl,prgs = <&prg12>;
+ clocks = <&clk IMX8QM_DC1_DPR0_APB_CLK>,
+ <&clk IMX8QM_DC1_DPR0_B_CLK>,
+ <&clk IMX8QM_DC1_RTRAM0_CLK>;
+ clock-names = "apb", "b", "rtram";
+ power-domains = <&pd_dc1>;
+ status = "disabled";
+ };
+
+ dpr4_channel1: dpr-channel@57100000 {
+ compatible = "fsl,imx8qm-dpr-channel";
+ reg = <0x0 0x57100000 0x0 0x10000>;
+ fsl,sc-resource = <SC_R_DC_1_VIDEO0>;
+ fsl,prgs = <&prg13>, <&prg14>;
+ clocks = <&clk IMX8QM_DC1_DPR1_APB_CLK>,
+ <&clk IMX8QM_DC1_DPR1_B_CLK>,
+ <&clk IMX8QM_DC1_RTRAM1_CLK>;
+ clock-names = "apb", "b", "rtram";
+ power-domains = <&pd_dc1>;
+ status = "disabled";
+ };
+
+ dpr4_channel2: dpr-channel@57110000 {
+ compatible = "fsl,imx8qm-dpr-channel";
+ reg = <0x0 0x57110000 0x0 0x10000>;
+ fsl,sc-resource = <SC_R_DC_1_VIDEO1>;
+ fsl,prgs = <&prg15>, <&prg16>;
+ clocks = <&clk IMX8QM_DC1_DPR1_APB_CLK>,
+ <&clk IMX8QM_DC1_DPR1_B_CLK>,
+ <&clk IMX8QM_DC1_RTRAM1_CLK>;
+ clock-names = "apb", "b", "rtram";
+ power-domains = <&pd_dc1>;
+ status = "disabled";
+ };
+
+ dpr4_channel3: dpr-channel@56712000 {
+ compatible = "fsl,imx8qm-dpr-channel";
+ reg = <0x0 0x57120000 0x0 0x10000>;
+ fsl,sc-resource = <SC_R_DC_1_WARP>;
+ fsl,prgs = <&prg17>, <&prg18>;
+ clocks = <&clk IMX8QM_DC1_DPR1_APB_CLK>,
+ <&clk IMX8QM_DC1_DPR1_B_CLK>,
+ <&clk IMX8QM_DC1_RTRAM1_CLK>;
+ clock-names = "apb", "b", "rtram";
+ power-domains = <&pd_dc1>;
+ status = "disabled";
+ };
+
+ dpu2: dpu@57180000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx8qm-dpu";
+ reg = <0x0 0x57180000 0x0 0x40000>;
+ intsteer = <&dpu2_intsteer>;
+ interrupts = <GIC_SPI 152 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 153 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 154 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 155 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 156 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 157 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 158 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 159 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 162 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 163 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "irq_common",
+ "irq_stream0a",
+ "irq_stream0b", /* to M4? */
+ "irq_stream1a",
+ "irq_stream1b", /* to M4? */
+ "irq_reserved0",
+ "irq_reserved1",
+ "irq_blit",
+ "irq_dpr0",
+ "irq_dpr1";
+ clocks = <&clk IMX8QM_DC1_PLL0_CLK>,
+ <&clk IMX8QM_DC1_PLL1_CLK>,
+ <&clk IMX8QM_DC1_BYPASS_0_DIV>,
+ <&clk IMX8QM_DC1_DISP0_SEL>,
+ <&clk IMX8QM_DC1_DISP1_SEL>,
+ <&clk IMX8QM_DC1_DISP0_CLK>,
+ <&clk IMX8QM_DC1_DISP1_CLK>;
+ clock-names = "pll0", "pll1", "bypass0",
+ "disp0_sel", "disp1_sel", "disp0", "disp1";
+ power-domains = <&pd_dc1_pll1>;
+ fsl,dpr-channels = <&dpr3_channel1>, <&dpr3_channel2>,
+ <&dpr3_channel3>, <&dpr4_channel1>,
+ <&dpr4_channel2>, <&dpr4_channel3>;
+ fsl,pixel-combiner = <&pixel_combiner2>;
+ status = "disabled";
+
+ dpu2_disp0: port@0 {
+ reg = <0>;
+
+ dpu2_disp0_mipi_dsi: mipi-dsi-endpoint {
+ remote-endpoint = <&mipi_dsi2_in>;
+ };
+ };
+
+ dpu2_disp1: port@1 {
+ reg = <1>;
+
+ dpu2_disp1_lvds0: lvds0-endpoint {
+ remote-endpoint = <&ldb2_lvds0>;
+ };
+
+ dpu2_disp1_lvds1: lvds1-endpoint {
+ remote-endpoint = <&ldb2_lvds1>;
+ };
+ };
+ };
+
+ irqsteer_dsi1: irqsteer@57220000 {
+ compatible = "nxp,imx-irqsteer";
+ reg = <0x0 0x57220000 0x0 0x1000>;
+ interrupts = <GIC_SPI 60 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-controller;
+ interrupt-parent = <&gic>;
+ #interrupt-cells = <2>;
+ clocks = <&clk IMX8QM_MIPI1_LIS_IPG_CLK>;
+ clock-names = "ipg";
+ power-domains = <&pd_mipi1>;
+ };
+
+ i2c0_mipi_dsi1: i2c@57226000 {
+ compatible = "fsl,imx8qm-lpi2c";
+ reg = <0x0 0x57226000 0x0 0x1000>;
+ interrupts = <8 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-parent = <&irqsteer_dsi1>;
+ clocks = <&clk IMX8QM_MIPI1_I2C0_CLK>,
+ <&clk IMX8QM_MIPI1_I2C0_IPG_CLK>;
+ clock-names = "per", "ipg";
+ assigned-clocks = <&clk IMX8QM_MIPI1_I2C0_CLK>;
+ assigned-clock-rates = <24000000>;
+ power-domains = <&pd_mipi1_i2c0>;
+ status = "disabled";
+ };
+
+ mipi_dsi_csr2: csr@57221000 {
+ compatible = "fsl,imx8qm-mipi-dsi-csr", "syscon";
+ reg = <0x0 0x57221000 0x0 0x1000>;
+ };
+
+ mipi_dsi_phy2: mipi_phy@57228300 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "mixel,imx8qm-mipi-dsi-phy";
+ reg = <0x0 0x57228300 0x0 0x100>;
+ power-domains = <&pd_mipi1>;
+ #phy-cells = <0>;
+ status = "disabled";
+ };
+
+ mipi_dsi2: mipi_dsi@57228000 {
+ compatible = "fsl,imx8qm-mipi-dsi";
+ clocks =
+ <&clk IMX8QM_MIPI1_PXL_CLK>,
+ <&clk IMX8QM_MIPI1_BYPASS_CLK>,
+ <&clk IMX8QM_MIPI1_DSI_PHY_CLK>;
+ clock-names = "pixel", "bypass", "phy_ref";
+ power-domains = <&pd_mipi1>;
+ csr = <&mipi_dsi_csr2>;
+ phys = <&mipi_dsi_phy2>;
+ phy-names = "dphy";
+ pwr-delay = <100>;
+ status = "disabled";
+
+ port@0 {
+ mipi_dsi2_in: endpoint {
+ remote-endpoint = <&dpu2_disp0_mipi_dsi>;
+ };
+ };
+
+ port@1 {
+ mipi_dsi2_out: endpoint {
+ remote-endpoint = <&mipi_dsi_bridge2_in>;
+ };
+ };
+ };
+
+ mipi_dsi_bridge2: mipi_dsi_bridge@57228000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "nwl,mipi-dsi";
+ reg = <0x0 0x57228000 0x0 0x300>;
+ interrupts = <16 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-parent = <&irqsteer_dsi1>;
+ clocks =
+ <&clk IMX8QM_MIPI1_BYPASS_CLK>,
+ <&clk IMX8QM_MIPI1_DSI_TX_ESC_CLK>,
+ <&clk IMX8QM_MIPI1_DSI_RX_ESC_CLK>;
+ clock-names = "phy_ref", "tx_esc", "rx_esc";
+ assigned-clocks = <&clk IMX8QM_MIPI1_DSI_TX_ESC_DIV>,
+ <&clk IMX8QM_MIPI1_DSI_RX_ESC_DIV>;
+ assigned-clock-rates = <18000000>, <72000000>;
+ power-domains = <&pd_mipi1>;
+ phys = <&mipi_dsi_phy2>;
+ phy-names = "dphy";
+ status = "disabled";
+
+ port@0 {
+ mipi_dsi_bridge2_in: endpoint {
+ remote-endpoint = <&mipi_dsi2_out>;
+ };
+ };
+ };
+
+ lvds_region2: lvds_region@57240000 {
+ compatible = "fsl,imx8qm-lvds-region", "syscon";
+ reg = <0x0 0x57240000 0x0 0x10000>;
+ };
+
+ ldb2_phy: ldb_phy@57241000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "mixel,lvds-phy";
+ reg = <0x0 0x57241000 0x0 0x100>;
+ clocks = <&clk IMX8QM_LVDS1_PHY_CLK>;
+ clock-names = "phy";
+ power-domains = <&pd_lvds1>;
+ status = "disabled";
+
+ ldb2_phy1: port@0 {
+ reg = <0>;
+ #phy-cells = <0>;
+ };
+
+ ldb2_phy2: port@1 {
+ reg = <1>;
+ #phy-cells = <0>;
+ };
+ };
+
+ ldb2: ldb@572410e0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx8qm-ldb";
+ clocks = <&clk IMX8QM_LVDS1_PIXEL_CLK>,
+ <&clk IMX8QM_LVDS1_BYPASS_CLK>;
+ clock-names = "pixel", "bypass";
+ power-domains = <&pd_lvds1>;
+ gpr = <&lvds_region2>;
+ status = "disabled";
+
+ lvds-channel@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0>;
+ phys = <&ldb2_phy1>;
+ phy-names = "ldb_phy";
+ status = "disabled";
+
+ port@0 {
+ reg = <0>;
+
+ ldb2_lvds0: endpoint {
+ remote-endpoint = <&dpu2_disp1_lvds0>;
+ };
+ };
+ };
+
+ lvds-channel@1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <1>;
+ phys = <&ldb2_phy2>;
+ phy-names = "ldb_phy";
+ status = "disabled";
+
+ port@0 {
+ reg = <0>;
+
+ ldb2_lvds1: endpoint {
+ remote-endpoint = <&dpu2_disp1_lvds1>;
+ };
+ };
+ };
+ };
+
+ lvds1_pwm: pwm@57244000 {
+ compatible = "fsl,imx8qm-pwm", "fsl,imx27-pwm";
+ reg = <0x0 0x57244000 0 0x1000>;
+ clocks = <&clk IMX8QM_LVDS1_PWM0_IPG_CLK>,
+ <&clk IMX8QM_LVDS1_PWM0_CLK>;
+ clock-names = "ipg", "per";
+ assigned-clocks = <&clk IMX8QM_LVDS1_PWM0_CLK>;
+ assigned-clock-rates = <24000000>;
+ #pwm-cells = <2>;
+ power-domains = <&pd_lvds1_pwm>;
+ status = "disabled";
+ };
+
+ camera: camera {
+ compatible = "fsl,mxc-md", "simple-bus";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ isi_0: isi@58100000 {
+ compatible = "fsl,imx8-isi";
+ reg = <0x0 0x58100000 0x0 0x10000>;
+ interrupts = <0 297 0>;
+ interface = <2 0 2>; /* <Input MIPI_VCx Output>
+ Input: 0-DC0, 1-DC1, 2-MIPI CSI0, 3-MIPI CSI1, 4-HDMI, 5-MEM
+ VCx: 0-VC0, 1-VC1, 2-VC2, 3-VC3, MIPI CSI only
+ Output: 0-DC0, 1-DC1, 2-MEM */
+ clocks = <&clk IMX8QM_IMG_PDMA_0_CLK>;
+ clock-names = "per";
+ assigned-clocks = <&clk IMX8QM_IMG_PDMA_0_CLK>;
+ assigned-clock-rates = <600000000>;
+ power-domains =<&pd_isi_ch0>;
+ status = "disabled";
+ };
+
+ isi_1: isi@58110000 {
+ compatible = "fsl,imx8-isi";
+ reg = <0x0 0x58110000 0x0 0x10000>;
+ interrupts = <0 298 0>;
+ interface = <2 1 2>;
+ clocks = <&clk IMX8QM_IMG_PDMA_1_CLK>;
+ clock-names = "per";
+ assigned-clocks = <&clk IMX8QM_IMG_PDMA_1_CLK>;
+ assigned-clock-rates = <600000000>;
+ power-domains =<&pd_isi_ch1>;
+ status = "disabled";
+ };
+
+ isi_2: isi@58120000 {
+ compatible = "fsl,imx8-isi";
+ reg = <0x0 0x58120000 0x0 0x10000>;
+ interrupts = <0 299 0>;
+ interface = <2 2 2>;
+ clocks = <&clk IMX8QM_IMG_PDMA_2_CLK>;
+ clock-names = "per";
+ assigned-clocks = <&clk IMX8QM_IMG_PDMA_2_CLK>;
+ assigned-clock-rates = <600000000>;
+ power-domains =<&pd_isi_ch2>;
+ status = "disabled";
+ };
+
+ isi_3: isi@58130000 {
+ compatible = "fsl,imx8-isi";
+ reg = <0x0 0x58130000 0x0 0x10000>;
+ interrupts = <0 300 0>;
+ interface = <2 3 2>;
+ clocks = <&clk IMX8QM_IMG_PDMA_3_CLK>;
+ clock-names = "per";
+ assigned-clocks = <&clk IMX8QM_IMG_PDMA_3_CLK>;
+ assigned-clock-rates = <600000000>;
+ power-domains =<&pd_isi_ch3>;
+ status = "disabled";
+ };
+
+ isi_4: isi@58140000 {
+ compatible = "fsl,imx8-isi";
+ reg = <0x0 0x58140000 0x0 0x10000>;
+ interrupts = <0 301 0>;
+ interface = <3 0 2>;
+ clocks = <&clk IMX8QM_IMG_PDMA_4_CLK>;
+ clock-names = "per";
+ assigned-clocks = <&clk IMX8QM_IMG_PDMA_4_CLK>;
+ assigned-clock-rates = <600000000>;
+ power-domains =<&pd_isi_ch4>;
+ status = "disabled";
+ };
+
+ isi_5: isi@58150000 {
+ compatible = "fsl,imx8-isi";
+ reg = <0x0 0x58150000 0x0 0x10000>;
+ interrupts = <0 302 0>;
+ interface = <3 1 2>;
+ clocks = <&clk IMX8QM_IMG_PDMA_5_CLK>;
+ clock-names = "per";
+ assigned-clocks = <&clk IMX8QM_IMG_PDMA_5_CLK>;
+ assigned-clock-rates = <600000000>;
+ power-domains =<&pd_isi_ch5>;
+ status = "disabled";
+ };
+
+ isi_6: isi@58160000 {
+ compatible = "fsl,imx8-isi";
+ reg = <0x0 0x58160000 0x0 0x10000>;
+ interrupts = <0 303 0>;
+ interface = <3 2 2>;
+ clocks = <&clk IMX8QM_IMG_PDMA_6_CLK>;
+ clock-names = "per";
+ assigned-clocks = <&clk IMX8QM_IMG_PDMA_6_CLK>;
+ assigned-clock-rates = <600000000>;
+ power-domains =<&pd_isi_ch6>;
+ status = "disabled";
+ };
+
+ isi_7: isi@58170000 {
+ compatible = "fsl,imx8-isi";
+ reg = <0x0 0x58170000 0x0 0x10000>;
+ interrupts = <0 304 0>;
+ interface = <3 3 2>;
+ clocks = <&clk IMX8QM_IMG_PDMA_7_CLK>;
+ clock-names = "per";
+ assigned-clocks = <&clk IMX8QM_IMG_PDMA_7_CLK>;
+ assigned-clock-rates = <600000000>;
+ power-domains =<&pd_isi_ch7>;
+ status = "disabled";
+ };
+
+ mipi_csi_0: csi@58227000 {
+ compatible = "fsl,mxc-mipi-csi2";
+ reg = <0x0 0x58227000 0x0 0x1000>, /* CSI0 Controler base addr */
+ <0x0 0x58221000 0x0 0x1000>; /* CSI0 Subsystem CSR base addr */
+ interrupts = <10 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-parent = <&irqsteer_csi0>;
+ clocks = <&clk IMX8QM_CLK_DUMMY>,
+ <&clk IMX8QM_CSI0_CORE_CLK>,
+ <&clk IMX8QM_CSI0_ESC_CLK>,
+ <&clk IMX8QM_IMG_PXL_LINK_CSI0_CLK>;
+ clock-names = "clk_apb", "clk_core", "clk_esc", "clk_pxl";
+ assigned-clocks = <&clk IMX8QM_CSI0_CORE_CLK>,
+ <&clk IMX8QM_CSI0_ESC_CLK>;
+ assigned-clock-rates = <360000000>, <72000000>;
+ power-domains = <&pd_csi0>;
+ status = "disabled";
+ };
+
+ mipi_csi_1: csi@58247000 {
+ compatible = "fsl,mxc-mipi-csi2";
+ reg = <0x0 0x58247000 0x0 0x1000>, /* CSI1 Controler base addr */
+ <0x0 0x58241000 0x0 0x1000>; /* CSI1 Subsystem CSR base addr */
+ interrupts = <10 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-parent = <&irqsteer_csi1>;
+ clocks = <&clk IMX8QM_CLK_DUMMY>,
+ <&clk IMX8QM_CSI1_CORE_CLK>,
+ <&clk IMX8QM_CSI1_ESC_CLK>,
+ <&clk IMX8QM_IMG_PXL_LINK_CSI1_CLK>;
+ clock-names = "clk_apb", "clk_core", "clk_esc", "clk_pxl";
+ assigned-clocks = <&clk IMX8QM_CSI1_CORE_CLK>,
+ <&clk IMX8QM_CSI1_ESC_CLK>;
+ assigned-clock-rates = <360000000>, <72000000>;
+ power-domains = <&pd_csi1>;
+ status = "disabled";
+ };
+
+ hdmi_rx: hdmi_rx@58268000 {
+ compatible = "fsl,imx-hdmi-rx";
+ reg = <0x0 0x58268000 0x0 0x10000>, /* HDP Controller */
+ <0x0 0x58261000 0x0 0x1000>; /* HDP SubSystem CSR */
+ interrupts = <10 IRQ_TYPE_LEVEL_HIGH>,
+ <13 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "plug_in", "plug_out";
+
+ interrupt-parent = <&irqsteer_hdmi_rx>;
+ clocks = <&clk IMX8QM_HDMI_RX_HD_REF_CLK>,
+ <&clk IMX8QM_HDMI_RX_HD_CORE_CLK>,
+ <&clk IMX8QM_HDMI_RX_PXL_CLK>,
+ <&clk IMX8QM_HDMI_RX_SINK_PCLK>,
+ <&clk IMX8QM_HDMI_RX_SINK_SCLK>,
+ <&clk IMX8QM_HDMI_RX_PXL_ENC_CLK>,
+ <&clk IMX8QM_HDMI_RX_I2S_CLK>,
+ <&clk IMX8QM_HDMI_RX_SPDIF_CLK>,
+ <&clk IMX8QM_IMG_PXL_LINK_HDMI_IN_CLK>;
+ clock-names = "ref_clk", "core_clk", "pxl_clk",
+ "pclk", "sclk", "enc_clk",
+ "i2s_clk", "spdif_clk",
+ "pxl_link_clk";
+ power-domains = <&pd_hdmi_rx_bypass>;
+ status = "disabled";
+ };
+
+ jpegdec: jpegdec@58400000 {
+ compatible = "fsl,imx8-jpgdec";
+ reg = <0x0 0x58400000 0x0 0x00040020 >;
+ interrupts = <GIC_SPI 309 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8QM_IMG_JPEG_DEC_IPG_CLK >,
+ <&clk IMX8QM_IMG_JPEG_DEC_CLK >;
+ clock-names = "ipg", "per";
+ assigned-clocks = <&clk IMX8QM_IMG_JPEG_DEC_IPG_CLK >,
+ <&clk IMX8QM_IMG_JPEG_DEC_CLK >;
+ assigned-clock-rates = <200000000>;
+ power-domains =<&pd_jpgdec>;
+ };
+
+ jpegenc: jpegenc@58450000 {
+ compatible = "fsl,imx8-jpgenc";
+ reg = <0x0 0x58450000 0x0 0x00240020 >;
+ interrupts = <GIC_SPI 305 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8QM_IMG_JPEG_ENC_IPG_CLK >,
+ <&clk IMX8QM_IMG_JPEG_ENC_CLK >;
+ clock-names = "ipg", "per";
+ assigned-clocks = <&clk IMX8QM_IMG_JPEG_ENC_IPG_CLK >,
+ <&clk IMX8QM_IMG_JPEG_ENC_CLK >;
+ assigned-clock-rates = <200000000>;
+ power-domains =<&pd_jpgenc>;
+ };
+ };
+
+ adc0: adc@5a880000 {
+ compatible = "fsl,imx8qxp-adc";
+ reg = <0x0 0x5a880000 0x0 0x10000>;
+ interrupts = <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-parent = <&gic>;
+ clocks = <&clk IMX8QM_ADC0_CLK>,
+ <&clk IMX8QM_ADC0_IPG_CLK>;
+ clock-names = "per", "ipg";
+ assigned-clocks = <&clk IMX8QM_ADC0_CLK>;
+ assigned-clock-rates = <24000000>;
+ power-domains = <&pd_dma_adc0>;
+ status = "disabled";
+ };
+
+ adc1: adc@5a890000 {
+ compatible = "fsl,imx8qxp-adc";
+ reg = <0x0 0x5a890000 0x0 0x10000>;
+ interrupts = <GIC_SPI 241 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-parent = <&gic>;
+ clocks = <&clk IMX8QM_ADC1_CLK>,
+ <&clk IMX8QM_ADC1_IPG_CLK>;
+ clock-names = "per", "ipg";
+ assigned-clocks = <&clk IMX8QM_ADC1_CLK>;
+ assigned-clock-rates = <24000000>;
+ power-domains = <&pd_dma_adc1>;
+ status = "disabled";
+ };
+
+ i2c0: i2c@5a800000 {
+ compatible = "fsl,imx8qm-lpi2c", "fsl,imx7ulp-lpi2c";
+ reg = <0x0 0x5a800000 0x0 0x4000>;
+ interrupts = <GIC_SPI 220 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-parent = <&gic>;
+ clocks = <&clk IMX8QM_I2C0_CLK>,
+ <&clk IMX8QM_I2C0_IPG_CLK>;
+ clock-names = "per", "ipg";
+ assigned-clocks = <&clk IMX8QM_I2C0_CLK>;
+ assigned-clock-rates = <24000000>;
+ power-domains = <&pd_dma_lpi2c0>;
+ status = "disabled";
+ };
+
+ i2c1: i2c@5a810000 {
+ compatible = "fsl,imx8qm-lpi2c", "fsl,imx7ulp-lpi2c";
+ reg = <0x0 0x5a810000 0x0 0x4000>;
+ interrupts = <GIC_SPI 221 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-parent = <&gic>;
+ clocks = <&clk IMX8QM_I2C1_CLK>,
+ <&clk IMX8QM_I2C1_IPG_CLK>;
+ clock-names = "per", "ipg";
+ assigned-clocks = <&clk IMX8QM_I2C1_CLK>;
+ assigned-clock-rates = <24000000>;
+ power-domains = <&pd_dma_lpi2c1>;
+ status = "disabled";
+ };
+
+ i2c2: i2c@5a820000 {
+ compatible = "fsl,imx8qm-lpi2c", "fsl,imx7ulp-lpi2c";
+ reg = <0x0 0x5a820000 0x0 0x4000>;
+ interrupts = <GIC_SPI 222 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-parent = <&gic>;
+ clocks = <&clk IMX8QM_I2C2_CLK>,
+ <&clk IMX8QM_I2C2_IPG_CLK>;
+ clock-names = "per", "ipg";
+ assigned-clocks = <&clk IMX8QM_I2C2_CLK>;
+ assigned-clock-rates = <24000000>;
+ power-domains = <&pd_dma_lpi2c2>;
+ status = "disabled";
+ };
+
+ i2c3: i2c@5a830000 {
+ compatible = "fsl,imx8qm-lpi2c", "fsl,imx7ulp-lpi2c";
+ reg = <0x0 0x5a830000 0x0 0x4000>;
+ interrupts = <GIC_SPI 223 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-parent = <&gic>;
+ clocks = <&clk IMX8QM_I2C3_CLK>,
+ <&clk IMX8QM_I2C3_IPG_CLK>;
+ clock-names = "per", "ipg";
+ assigned-clocks = <&clk IMX8QM_I2C3_CLK>;
+ assigned-clock-rates = <24000000>;
+ power-domains = <&pd_dma_lpi2c3>;
+ status = "disabled";
+ };
+
+ i2c4: i2c@5a840000 {
+ compatible = "fsl,imx8qm-lpi2c", "fsl,imx7ulp-lpi2c";
+ reg = <0x0 0x5a840000 0x0 0x4000>;
+ interrupts = <GIC_SPI 224 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-parent = <&gic>;
+ clocks = <&clk IMX8QM_I2C4_CLK>,
+ <&clk IMX8QM_I2C4_IPG_CLK>;
+ clock-names = "per", "ipg";
+ assigned-clocks = <&clk IMX8QM_I2C4_CLK>;
+ assigned-clock-rates = <24000000>;
+ power-domains = <&pd_dma_lpi2c4>;
+ status = "disabled";
+ };
+
+ i2c0_cm40: i2c@37230000 {
+ compatible = "fsl,imx8qm-lpi2c";
+ reg = <0x0 0x37230000 0x0 0x1000>;
+ interrupts = <9 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-parent = <&intmux_cm40>;
+ clocks = <&clk IMX8QM_CM40_I2C_CLK>,
+ <&clk IMX8QM_CM40_I2C_IPG_CLK>;
+ clock-names = "per", "ipg";
+ assigned-clocks = <&clk IMX8QM_CM40_I2C_CLK>;
+ assigned-clock-rates = <24000000>;
+ power-domains = <&pd_cm40_i2c>;
+ status = "disabled";
+ };
+
+ i2c0_cm41: i2c@3b230000 {
+ compatible = "fsl,imx8qm-lpi2c";
+ reg = <0x0 0x3b230000 0x0 0x1000>;
+ interrupts = <9 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-parent = <&intmux_cm41>;
+ clocks = <&clk IMX8QM_CM41_I2C_CLK>,
+ <&clk IMX8QM_CM41_I2C_IPG_CLK>;
+ clock-names = "per", "ipg";
+ assigned-clocks = <&clk IMX8QM_CM41_I2C_CLK>;
+ assigned-clock-rates = <24000000>;
+ power-domains = <&pd_cm41_i2c>;
+ status = "disabled";
+ };
+
+ irqsteer_hdmi: irqsteer@56260000 {
+ compatible = "nxp,imx-irqsteer";
+ reg = <0x0 0x56260000 0x0 0x1000>;
+ interrupts = <GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-controller;
+ interrupt-parent = <&gic>;
+ #interrupt-cells = <2>;
+ clocks = <&clk IMX8QM_HDMI_LIS_IPG_CLK>;
+ clock-names = "ipg";
+ assigned-clocks = <&clk IMX8QM_HDMI_DIG_PLL_CLK>,
+ <&clk IMX8QM_HDMI_LIS_IPG_CLK>;
+ assigned-clock-rates = <800000000>, <100000000>;
+ power-domains = <&pd_hdmi>;
+ status = "disabled";
+ };
+
+ irqsteer_hdmi_rx: irqsteer@58260000 {
+ compatible = "nxp,imx-irqsteer";
+ reg = <0x0 0x58260000 0x0 0x1000>;
+ interrupts = <GIC_SPI 322 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ clocks = <&clk IMX8QM_HDMI_RX_IPG_CLK>;
+ clock-names = "ipg";
+ power-domains = <&pd_hdmi_rx>;
+ };
+
+
+ i2c0_hdmi: i2c@56266000 {
+ compatible = "fsl,imx8qm-lpi2c";
+ reg = <0x0 0x56266000 0x0 0x1000>;
+ interrupts = <8 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-parent = <&irqsteer_hdmi>;
+ clocks = <&clk IMX8QM_HDMI_I2C0_CLK>,
+ <&clk IMX8QM_HDMI_I2C_IPG_CLK>;
+ clock-names = "per", "ipg";
+ assigned-clocks = <&clk IMX8QM_HDMI_I2C0_CLK>;
+ assigned-clock-rates = <24000000>;
+ power-domains = <&pd_hdmi_i2c0>;
+ status = "disabled";
+ };
+
+ irqsteer_lvds0: irqsteer@562400000 {
+ compatible = "nxp,imx-irqsteer";
+ reg = <0x0 0x56240000 0x0 0x1000>;
+ interrupts = <GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-controller;
+ interrupt-parent = <&gic>;
+ #interrupt-cells = <2>;
+ clocks = <&clk IMX8QM_LVDS0_LIS_IPG_CLK>;
+ clock-names = "ipg";
+ power-domains = <&pd_lvds0>;
+ };
+
+ flexcan1: can@5a8d0000 {
+ compatible = "fsl,imx8qm-flexcan", "fsl,imx6q-flexcan";
+ reg = <0x0 0x5a8d0000 0x0 0x10000>;
+ interrupts = <GIC_SPI 235 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-parent = <&wu>;
+ clocks = <&clk IMX8QM_CAN0_IPG_CLK>,
+ <&clk IMX8QM_CAN0_CLK>;
+ clock-names = "ipg", "per";
+ assigned-clocks = <&clk IMX8QM_CAN0_CLK>;
+ assigned-clock-rates = <40000000>;
+ power-domains = <&pd_dma_flexcan0>;
+ status = "disabled";
+ };
+
+ flexcan2: can@5a8e0000 {
+ compatible = "fsl,imx8qm-flexcan", "fsl,imx6q-flexcan";
+ reg = <0x0 0x5a8e0000 0x0 0x10000>;
+ interrupts = <GIC_SPI 236 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-parent = <&wu>;
+ clocks = <&clk IMX8QM_CAN1_IPG_CLK>,
+ <&clk IMX8QM_CAN1_CLK>;
+ clock-names = "ipg", "per";
+ assigned-clocks = <&clk IMX8QM_CAN1_CLK>;
+ assigned-clock-rates = <40000000>;
+ power-domains = <&pd_dma_flexcan1>;
+ status = "disabled";
+ };
+
+ flexcan3: can@5a8f0000 {
+ compatible = "fsl,imx8qm-flexcan", "fsl,imx6q-flexcan";
+ reg = <0x0 0x5a8f0000 0x0 0x10000>;
+ interrupts = <GIC_SPI 237 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-parent = <&wu>;
+ clocks = <&clk IMX8QM_CAN2_IPG_CLK>,
+ <&clk IMX8QM_CAN2_CLK>;
+ clock-names = "ipg", "per";
+ assigned-clocks = <&clk IMX8QM_CAN2_CLK>;
+ assigned-clock-rates = <40000000>;
+ power-domains = <&pd_dma_flexcan2>;
+ status = "disabled";
+ };
+
+ i2c1_lvds0: i2c@56247000 {
+ compatible = "fsl,imx8qm-lpi2c";
+ reg = <0x0 0x56247000 0x0 0x1000>;
+ interrupts = <9 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-parent = <&irqsteer_lvds0>;
+ clocks = <&clk IMX8QM_LVDS0_I2C0_CLK>,
+ <&clk IMX8QM_LVDS0_I2C0_IPG_CLK>;
+ clock-names = "per", "ipg";
+ assigned-clocks = <&clk IMX8QM_LVDS0_I2C0_CLK>;
+ assigned-clock-rates = <24000000>;
+ power-domains = <&pd_lvds0_i2c0>;
+ status = "disabled";
+ };
+
+ irqsteer_lvds1: irqsteer@572400000 {
+ compatible = "nxp,imx-irqsteer";
+ reg = <0x0 0x57240000 0x0 0x1000>;
+ interrupts = <GIC_SPI 58 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-controller;
+ interrupt-parent = <&gic>;
+ #interrupt-cells = <2>;
+ clocks = <&clk IMX8QM_LVDS1_LIS_IPG_CLK>;
+ clock-names = "ipg";
+ power-domains = <&pd_lvds1>;
+ };
+
+ i2c1_lvds1: i2c@57247000 {
+ compatible = "fsl,imx8qm-lpi2c";
+ reg = <0x0 0x57247000 0x0 0x1000>;
+ interrupts = <9 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-parent = <&irqsteer_lvds1>;
+ clocks = <&clk IMX8QM_LVDS1_I2C0_CLK>,
+ <&clk IMX8QM_LVDS1_I2C0_IPG_CLK>;
+ clock-names = "per", "ipg";
+ assigned-clocks = <&clk IMX8QM_LVDS1_I2C0_CLK>;
+ assigned-clock-rates = <24000000>;
+ power-domains = <&pd_lvds1_i2c0>;
+ status = "disabled";
+ };
+
+ irqsteer_csi0: irqsteer@58220000 {
+ compatible = "nxp,imx-irqsteer";
+ reg = <0x0 0x58220000 0x0 0x1000>;
+ interrupts = <GIC_SPI 320 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-controller;
+ interrupt-parent = <&gic>;
+ #interrupt-cells = <2>;
+ clocks = <&clk IMX8QM_CLK_DUMMY>;
+ clock-names = "ipg";
+ power-domains = <&pd_csi0>;
+ };
+
+ i2c0_mipi_csi0: i2c@58226000 {
+ compatible = "fsl,imx8qm-lpi2c";
+ reg = <0x0 0x58226000 0x0 0x1000>;
+ interrupts = <8 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-parent = <&irqsteer_csi0>;
+ clocks = <&clk IMX8QM_CSI0_I2C0_CLK>,
+ <&clk IMX8QM_CSI0_I2C0_IPG_CLK>;
+ clock-names = "per", "ipg";
+ assigned-clocks = <&clk IMX8QM_CSI0_I2C0_CLK>;
+ assigned-clock-rates = <24000000>;
+ power-domains = <&pd_csi0_i2c0>;
+ status = "disabled";
+ };
+
+ irqsteer_csi1: irqsteer@582400000 {
+ compatible = "nxp,imx-irqsteer";
+ reg = <0x0 0x58240000 0x0 0x1000>;
+ interrupts = <GIC_SPI 321 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-controller;
+ interrupt-parent = <&gic>;
+ #interrupt-cells = <2>;
+ clocks = <&clk IMX8QM_CLK_DUMMY>;
+ clock-names = "ipg";
+ power-domains = <&pd_csi1>;
+ };
+
+ i2c0_mipi_csi1: i2c@58246000 {
+ compatible = "fsl,imx8qm-lpi2c";
+ reg = <0x0 0x58246000 0x0 0x1000>;
+ interrupts = <8 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-parent = <&irqsteer_csi1>;
+ clocks = <&clk IMX8QM_CSI1_I2C0_CLK>,
+ <&clk IMX8QM_CSI1_I2C0_IPG_CLK>;
+ clock-names = "per", "ipg";
+ assigned-clocks = <&clk IMX8QM_CSI1_I2C0_CLK>;
+ assigned-clock-rates = <24000000>;
+ power-domains = <&pd_csi1_i2c0>;
+ status = "disabled";
+ };
+
+ lpspi0: lpspi@5a000000 {
+ compatible = "fsl,imx7ulp-spi";
+ reg = <0x0 0x5a000000 0x0 0x10000>;
+ interrupts = <GIC_SPI 216 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-parent = <&gic>;
+ clocks = <&clk IMX8QM_SPI0_CLK>,
+ <&clk IMX8QM_SPI0_IPG_CLK>;
+ clock-names = "per", "ipg";
+ assigned-clocks = <&clk IMX8QM_SPI0_CLK>;
+ assigned-clock-rates = <20000000>;
+ power-domains = <&pd_dma0_chan1>;
+ dma-names = "tx","rx";
+ dmas = <&edma0 1 0 0>, <&edma0 0 0 1>;
+ status = "disabled";
+ };
+
+ lpspi3: lpspi@5a030000 {
+ compatible = "fsl,imx7ulp-spi";
+ reg = <0x0 0x5a030000 0x0 0x10000>;
+ interrupts = <GIC_SPI 219 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-parent = <&gic>;
+ clocks = <&clk IMX8QM_SPI3_CLK>,
+ <&clk IMX8QM_SPI3_IPG_CLK>;
+ clock-names = "per", "ipg";
+ assigned-clocks = <&clk IMX8QM_SPI3_CLK>;
+ assigned-clock-rates = <60000000>;
+ power-domains = <&pd_dma0_chan7>;
+ dma-names = "tx","rx";
+ dmas = <&edma0 7 0 0>, <&edma0 6 0 1>;
+ status = "disabled";
+ };
+
+ lpuart0: serial@5a060000 {
+ compatible = "fsl,imx8qm-lpuart";
+ reg = <0x0 0x5a060000 0x0 0x1000>;
+ interrupts = <GIC_SPI 345 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-parent = <&wu>;
+ clocks = <&clk IMX8QM_UART0_CLK>,
+ <&clk IMX8QM_UART0_IPG_CLK>;
+ clock-names = "per", "ipg";
+ assigned-clocks = <&clk IMX8QM_UART0_CLK>;
+ assigned-clock-rates = <80000000>;
+ power-domains = <&pd_dma_lpuart0>;
+ status = "disabled";
+ };
+
+ lpuart1: serial@5a070000 {
+ compatible = "fsl,imx8qm-lpuart";
+ reg = <0x0 0x5a070000 0x0 0x1000>;
+ interrupts = <GIC_SPI 346 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-parent = <&wu>;
+ clocks = <&clk IMX8QM_UART1_CLK>,
+ <&clk IMX8QM_UART1_IPG_CLK>;
+ clock-names = "per", "ipg";
+ assigned-clocks = <&clk IMX8QM_UART1_CLK>;
+ assigned-clock-rates = <80000000>;
+ power-domains = <&pd_dma0_chan15>;
+ dma-names = "tx","rx";
+ dmas = <&edma0 15 0 0>,
+ <&edma0 14 0 1>;
+ status = "disabled";
+ };
+
+ lpuart2: serial@5a080000 {
+ compatible = "fsl,imx8qm-lpuart";
+ reg = <0x0 0x5a080000 0x0 0x1000>;
+ interrupts = <GIC_SPI 347 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-parent = <&wu>;
+ clocks = <&clk IMX8QM_UART2_CLK>,
+ <&clk IMX8QM_UART2_IPG_CLK>;
+ clock-names = "per", "ipg";
+ assigned-clocks = <&clk IMX8QM_UART2_CLK>;
+ assigned-clock-rates = <80000000>;
+ power-domains = <&pd_dma0_chan17>;
+ dma-names = "tx","rx";
+ dmas = <&edma0 17 0 0>,
+ <&edma0 16 0 1>;
+ status = "disabled";
+ };
+
+ lpuart3: serial@5a090000 {
+ compatible = "fsl,imx8qm-lpuart";
+ reg = <0x0 0x5a090000 0x0 0x1000>;
+ interrupts = <GIC_SPI 348 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-parent = <&wu>;
+ clocks = <&clk IMX8QM_UART3_CLK>,
+ <&clk IMX8QM_UART3_IPG_CLK>;
+ clock-names = "per", "ipg";
+ assigned-clocks = <&clk IMX8QM_UART3_CLK>;
+ assigned-clock-rates = <80000000>;
+ power-domains = <&pd_dma0_chan19>;
+ dma-names = "tx","rx";
+ dmas = <&edma0 19 0 0>,
+ <&edma0 18 0 1>;
+ status = "disabled";
+ };
+
+ lpuart4: serial@5a0a0000 {
+ compatible = "fsl,imx8qm-lpuart";
+ reg = <0x0 0x5a0a0000 0x0 0x1000>;
+ interrupts = <GIC_SPI 349 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-parent = <&wu>;
+ clocks = <&clk IMX8QM_UART4_CLK>,
+ <&clk IMX8QM_UART4_IPG_CLK>;
+ clock-names = "per", "ipg";
+ assigned-clocks = <&clk IMX8QM_UART4_CLK>;
+ assigned-clock-rates = <80000000>;
+ power-domains = <&pd_dma0_chan21>;
+ dma-names = "tx","rx";
+ dmas = <&edma0 21 0 0>,
+ <&edma0 20 0 1>;
+ status = "disabled";
+ };
+
+ ftmpwm0: ftmpwm@0x05a8a0000 {
+ compatible = "fsl,vf610-ftm-pwm";
+ reg = <0 0x5A8A0000 0 0x1000>;
+ #pwm-cells = <3>;
+ clock-names = "ftm_sys", "ftm_ext",
+ "ftm_fix", "ftm_cnt_clk_en", "ipg";
+ clocks = <&clk IMX8QM_FTM0_CLK>,
+ <&clk IMX8QM_CLK_DUMMY>,
+ <&clk IMX8QM_FTM0_CLK>,
+ <&clk IMX8QM_CLK_DUMMY>,
+ <&clk IMX8QM_FTM0_IPG_CLK>;
+ assigned-clocks = <&clk IMX8QM_FTM0_CLK>;
+ assigned-clock-rates = <8000000>;
+ power-domains = <&pd_dma_ftm0>;
+ ftm-has-pwmen-bits;
+ status = "disabled";
+ };
+
+ ftmpwm1: ftmpwm@0x05a8b0000 {
+ compatible = "fsl,vf610-ftm-pwm";
+ reg = <0 0x5A8B0000 0 0x1000>;
+ #pwm-cells = <3>;
+ clock-names = "ftm_sys", "ftm_ext",
+ "ftm_fix", "ftm_cnt_clk_en", "ipg";
+ clocks = <&clk IMX8QM_FTM1_CLK>,
+ <&clk IMX8QM_CLK_DUMMY>,
+ <&clk IMX8QM_FTM1_CLK>,
+ <&clk IMX8QM_CLK_DUMMY>,
+ <&clk IMX8QM_FTM0_IPG_CLK>;
+ assigned-clocks = <&clk IMX8QM_FTM1_CLK>;
+ assigned-clock-rates = <8000000>;
+ power-domains = <&pd_dma_ftm1>;
+ ftm-has-pwmen-bits;
+ status = "disabled";
+ };
+
+ emvsim0: sim0@5a0d0000 {
+ compatible = "fsl,imx8-emvsim";
+ reg = <0x0 0x5a0d0000 0x0 0x10000>;
+ interrupts = <GIC_SPI 230 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8QM_EMVSIM0_CLK>,
+ <&clk IMX8QM_EMVSIM0_IPG_CLK>;
+ clock-names = "sim", "ipg";
+ power-domains = <&pd_ldo1_sim>;
+ status = "disabled";
+ };
+
+ edma0: dma-controller@5a1f0000 {
+ compatible = "fsl,imx8qm-edma";
+ reg = <0x0 0x5a200000 0x0 0x10000>, /* channel0 LPSPI0 rx */
+ <0x0 0x5a210000 0x0 0x10000>, /* channel1 LPSPI0 tx */
+ <0x0 0x5a260000 0x0 0x10000>, /* channel6 LPSPI3 rx */
+ <0x0 0x5a270000 0x0 0x10000>, /* channel7 LPSPI3 tx */
+ <0x0 0x5a2c0000 0x0 0x10000>, /* channel12 UART0 rx */
+ <0x0 0x5a2d0000 0x0 0x10000>, /* channel13 UART0 tx */
+ <0x0 0x5a2e0000 0x0 0x10000>, /* channel14 UART1 rx */
+ <0x0 0x5a2f0000 0x0 0x10000>, /* channel15 UART1 tx */
+ <0x0 0x5a300000 0x0 0x10000>, /* channel16 UART2 rx */
+ <0x0 0x5a310000 0x0 0x10000>, /* channel17 UART2 tx */
+ <0x0 0x5a320000 0x0 0x10000>, /* channel18 UART3 rx */
+ <0x0 0x5a330000 0x0 0x10000>, /* channel19 UART3 tx */
+ <0x0 0x5a340000 0x0 0x10000>, /* channel20 UART4 rx */
+ <0x0 0x5a350000 0x0 0x10000>; /* channel21 UART4 tx */
+ #dma-cells = <3>;
+ dma-channels = <14>;
+ interrupts = <GIC_SPI 416 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 417 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 422 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 423 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 434 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 435 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 436 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 437 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 438 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 439 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 440 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 441 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 442 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 443 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "edma0-chan0-rx", "edma0-chan1-tx",
+ "edma0-chan6-rx", "edma0-chan7-tx",
+ "edma0-chan12-rx", "edma0-chan13-tx",
+ "edma0-chan14-rx", "edma0-chan15-tx",
+ "edma0-chan16-rx", "edma0-chan17-tx",
+ "edma0-chan18-rx", "edma0-chan19-tx",
+ "edma0-chan20-rx", "edma0-chan21-tx";
+ status = "okay";
+ };
+
+ edma2: dma-controller@591F0000 {
+ compatible = "fsl,imx8qm-adma";
+ reg = <0x0 0x59200000 0x0 0x10000>, /* asrc0 */
+ <0x0 0x59210000 0x0 0x10000>,
+ <0x0 0x59220000 0x0 0x10000>,
+ <0x0 0x59230000 0x0 0x10000>,
+ <0x0 0x59240000 0x0 0x10000>,
+ <0x0 0x59250000 0x0 0x10000>,
+ <0x0 0x59260000 0x0 0x10000>, /* esai0 rx */
+ <0x0 0x59270000 0x0 0x10000>, /* esai0 tx */
+ <0x0 0x59280000 0x0 0x10000>, /* spdif0 rx */
+ <0x0 0x59290000 0x0 0x10000>, /* spdif0 tx */
+ <0x0 0x592A0000 0x0 0x10000>, /* spdif1 rx */
+ <0x0 0x592B0000 0x0 0x10000>, /* spdif1 tx */
+ <0x0 0x592c0000 0x0 0x10000>, /* sai0 rx */
+ <0x0 0x592d0000 0x0 0x10000>, /* sai0 tx */
+ <0x0 0x592e0000 0x0 0x10000>, /* sai1 rx */
+ <0x0 0x592f0000 0x0 0x10000>, /* sai1 tx */
+ <0x0 0x59320000 0x0 0x10000>, /* sai4 rx */
+ <0x0 0x59330000 0x0 0x10000>; /* sai5 tx */
+ #dma-cells = <3>;
+ shared-interrupt;
+ dma-channels = <18>;
+ interrupts = <GIC_SPI 374 IRQ_TYPE_LEVEL_HIGH>, /* asrc0 */
+ <GIC_SPI 375 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 376 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 377 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 378 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 379 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 410 IRQ_TYPE_LEVEL_HIGH>, /* esai0 */
+ <GIC_SPI 410 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 457 IRQ_TYPE_LEVEL_HIGH>, /* spdif0 */
+ <GIC_SPI 459 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 461 IRQ_TYPE_LEVEL_HIGH>, /* spdif1 */
+ <GIC_SPI 463 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 315 IRQ_TYPE_LEVEL_HIGH>, /* sai0 */
+ <GIC_SPI 315 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 317 IRQ_TYPE_LEVEL_HIGH>, /* sai1 */
+ <GIC_SPI 317 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 326 IRQ_TYPE_LEVEL_HIGH>, /* sai4 */
+ <GIC_SPI 328 IRQ_TYPE_LEVEL_HIGH>; /* sai5 */
+ interrupt-names = "edma2-chan0-rx", "edma2-chan1-rx", /* asrc0 */
+ "edma2-chan2-rx", "edma2-chan3-tx",
+ "edma2-chan4-tx", "edma2-chan5-tx",
+ "edma2-chan6-rx", "edma2-chan7-tx", /* esai0 */
+ "edma2-chan8-rx", "edma2-chan9-tx", /* spdif0 */
+ "edma2-chan10-rx", "edma2-chan11-tx", /* spdif1 */
+ "edma2-chan12-rx", "edma2-chan13-tx", /* sai0 */
+ "edma2-chan14-rx", "edma2-chan15-tx", /* sai1 */
+ "edma2-chan18-rx", "edma2-chan19-tx"; /* sai4, sai5 */
+ status = "okay";
+ };
+
+ edma3: dma-controller@599F0000 {
+ compatible = "fsl,imx8qm-adma";
+ reg = <0x0 0x59A00000 0x0 0x10000>, /* asrc1 */
+ <0x0 0x59A10000 0x0 0x10000>,
+ <0x0 0x59A20000 0x0 0x10000>,
+ <0x0 0x59A30000 0x0 0x10000>,
+ <0x0 0x59A40000 0x0 0x10000>,
+ <0x0 0x59A50000 0x0 0x10000>,
+ <0x0 0x59A80000 0x0 0x10000>, /* sai6 rx */
+ <0x0 0x59A90000 0x0 0x10000>, /* sai6 tx */
+ <0x0 0x59AA0000 0x0 0x10000>; /* sai7 tx */
+ #dma-cells = <3>;
+ shared-interrupt;
+ dma-channels = <9>;
+ interrupts = <GIC_SPI 382 IRQ_TYPE_LEVEL_HIGH>, /* asrc1 */
+ <GIC_SPI 383 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 384 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 385 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 386 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 387 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 330 IRQ_TYPE_LEVEL_HIGH>, /* sai6 */
+ <GIC_SPI 330 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 332 IRQ_TYPE_LEVEL_HIGH>; /* sai7 */
+ interrupt-names = "edma3-chan0-rx", "edma3-chan1-rx", /* asrc1 */
+ "edma3-chan2-rx", "edma3-chan3-tx",
+ "edma3-chan4-tx", "edma3-chan5-tx",
+ "edma3-chan8-rx", "edma3-chan9-tx", /* sai6 */
+ "edma3-chan10-tx"; /* sai7 */
+ status = "okay";
+ };
+
+ wu: wu {
+ compatible = "fsl,imx8-wu";
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ interrupt-parent = <&gic>;
+ };
+
+ gpio0: gpio@5d080000 {
+ compatible = "fsl,imx8qm-gpio", "fsl,imx35-gpio";
+ reg = <0x0 0x5d080000 0x0 0x10000>;
+ interrupts = <GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ power-domains = <&pd_lsio_gpio0>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio1: gpio@5d090000 {
+ compatible = "fsl,imx8qm-gpio", "fsl,imx35-gpio";
+ reg = <0x0 0x5d090000 0x0 0x10000>;
+ interrupts = <GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ power-domains = <&pd_lsio_gpio1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio2: gpio@5d0a0000 {
+ compatible = "fsl,imx8qm-gpio", "fsl,imx35-gpio";
+ reg = <0x0 0x5d0a0000 0x0 0x10000>;
+ interrupts = <GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ power-domains = <&pd_lsio_gpio2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio3: gpio@5d0b0000 {
+ compatible = "fsl,imx8qm-gpio", "fsl,imx35-gpio";
+ reg = <0x0 0x5d0b0000 0x0 0x10000>;
+ interrupts = <GIC_SPI 139 IRQ_TYPE_LEVEL_HIGH>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ power-domains = <&pd_lsio_gpio3>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio4: gpio@5d0c0000 {
+ compatible = "fsl,imx8qm-gpio", "fsl,imx35-gpio";
+ reg = <0x0 0x5d0c0000 0x0 0x10000>;
+ interrupts = <GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ power-domains = <&pd_lsio_gpio4>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio5: gpio@5d0d0000 {
+ compatible = "fsl,imx8qm-gpio", "fsl,imx35-gpio";
+ reg = <0x0 0x5d0d0000 0x0 0x10000>;
+ interrupts = <GIC_SPI 141 IRQ_TYPE_LEVEL_HIGH>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ power-domains = <&pd_lsio_gpio5>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio6: gpio@5d0e0000 {
+ compatible = "fsl,imx8qm-gpio", "fsl,imx35-gpio";
+ reg = <0x0 0x5d0e0000 0x0 0x10000>;
+ interrupts = <GIC_SPI 142 IRQ_TYPE_LEVEL_HIGH>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ power-domains = <&pd_lsio_gpio6>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio7: gpio@5d0f0000 {
+ compatible = "fsl,imx8qm-gpio", "fsl,imx35-gpio";
+ reg = <0x0 0x5d0f0000 0x0 0x10000>;
+ interrupts = <GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ power-domains = <&pd_lsio_gpio7>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio0_mipi_csi0: gpio@58222000 {
+ compatible = "fsl,imx8qm-gpio", "fsl,imx35-gpio";
+ reg = <0x0 0x58222000 0x0 0x1000>;
+ interrupts = <0 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-parent = <&irqsteer_csi0>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ power-domains = <&pd_csi0>;
+ status = "disabled";
+ };
+
+ gpio0_mipi_csi1: gpio@58242000 {
+ compatible = "fsl,imx8qm-gpio", "fsl,imx35-gpio";
+ reg = <0x0 0x58242000 0x0 0x1000>;
+ interrupts = <0 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-parent = <&irqsteer_csi1>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ power-domains = <&pd_csi1>;
+ status = "disabled";
+ };
+
+ gpt0: gpt0@5d140000 {
+ compatible = "fsl,imx8qm-gpt";
+ reg = <0x0 0x5d140000 0x0 0x4000>;
+ interrupts = <GIC_SPI 80 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8QM_GPT0_CLK>, <&clk IMX8QM_GPT_3M>;
+ clock-names = "ipg", "per";
+ power-domains = <&pd_lsio_gpt0>;
+ };
+
+ pwm0: pwm@5d000000 {
+ compatible = "fsl,imx8qm-pwm", "fsl,imx27-pwm";
+ reg = <0x0 0x5d000000 0 0x10000>;
+ clocks = <&clk IMX8QM_PWM0_HF_CLK>,
+ <&clk IMX8QM_PWM0_HF_CLK>;
+ clock-names = "ipg", "per";
+ assigned-clocks = <&clk IMX8QM_PWM0_HF_CLK>;
+ assigned-clock-rates = <24000000>;
+ #pwm-cells = <2>;
+ status = "disabled";
+ };
+
+
+ pwm1: pwm@5d010000 {
+ compatible = "fsl,imx8qm-pwm", "fsl,imx27-pwm";
+ reg = <0x0 0x5d010000 0 0x10000>;
+ clocks = <&clk IMX8QM_PWM1_HF_CLK>,
+ <&clk IMX8QM_PWM1_HF_CLK>;
+ clock-names = "ipg", "per";
+ assigned-clocks = <&clk IMX8QM_PWM1_HF_CLK>;
+ assigned-clock-rates = <24000000>;
+ #pwm-cells = <2>;
+ status = "disabled";
+ };
+
+ pwm2: pwm@5d020000 {
+ compatible = "fsl,imx8qm-pwm", "fsl,imx27-pwm";
+ reg = <0x0 0x5d020000 0 0x10000>;
+ clocks = <&clk IMX8QM_PWM2_HF_CLK>,
+ <&clk IMX8QM_PWM2_HF_CLK>;
+ clock-names = "ipg", "per";
+ assigned-clocks = <&clk IMX8QM_PWM2_HF_CLK>;
+ assigned-clock-rates = <24000000>;
+ #pwm-cells = <2>;
+ status = "disabled";
+ };
+
+ pwm3: pwm@5d030000 {
+ compatible = "fsl,imx8qm-pwm", "fsl,imx27-pwm";
+ reg = <0x0 0x5d030000 0 0x10000>;
+ clocks = <&clk IMX8QM_PWM3_HF_CLK>,
+ <&clk IMX8QM_PWM3_HF_CLK>;
+ clock-names = "ipg", "per";
+ assigned-clocks = <&clk IMX8QM_PWM3_HF_CLK>;
+ assigned-clock-rates = <24000000>;
+ #pwm-cells = <2>;
+ status = "disabled";
+ };
+
+ pwm4: pwm@5d040000 {
+ compatible = "fsl,imx8qm-pwm", "fsl,imx27-pwm";
+ reg = <0x0 0x5d040000 0 0x10000>;
+ clocks = <&clk IMX8QM_PWM4_HF_CLK>,
+ <&clk IMX8QM_PWM4_HF_CLK>;
+ clock-names = "ipg", "per";
+ assigned-clocks = <&clk IMX8QM_PWM4_HF_CLK>;
+ assigned-clock-rates = <24000000>;
+ #pwm-cells = <2>;
+ status = "disabled";
+ };
+
+ pwm5: pwm@5d050000 {
+ compatible = "fsl,imx8qm-pwm", "fsl,imx27-pwm";
+ reg = <0x0 0x5d050000 0 0x10000>;
+ clocks = <&clk IMX8QM_PWM5_HF_CLK>,
+ <&clk IMX8QM_PWM5_HF_CLK>;
+ clock-names = "ipg", "per";
+ assigned-clocks = <&clk IMX8QM_PWM5_HF_CLK>;
+ assigned-clock-rates = <24000000>;
+ #pwm-cells = <2>;
+ status = "disabled";
+ };
+
+ pwm6: pwm@5d060000 {
+ compatible = "fsl,imx8qm-pwm", "fsl,imx27-pwm";
+ reg = <0x0 0x5d060000 0 0x10000>;
+ clocks = <&clk IMX8QM_PWM6_HF_CLK>,
+ <&clk IMX8QM_PWM6_HF_CLK>;
+ clock-names = "ipg", "per";
+ assigned-clocks = <&clk IMX8QM_PWM6_HF_CLK>;
+ assigned-clock-rates = <24000000>;
+ #pwm-cells = <2>;
+ status = "disabled";
+ };
+
+ pwm7: pwm@5d070000 {
+ compatible = "fsl,imx8qm-pwm", "fsl,imx27-pwm";
+ reg = <0x0 0x5d070000 0 0x10000>;
+ clocks = <&clk IMX8QM_PWM7_HF_CLK>,
+ <&clk IMX8QM_PWM7_HF_CLK>;
+ clock-names = "ipg", "per";
+ assigned-clocks = <&clk IMX8QM_PWM7_HF_CLK>;
+ assigned-clock-rates = <24000000>;
+ #pwm-cells = <2>;
+ status = "disabled";
+ };
+
+
+ gpu_3d0: gpu@53100000 {
+ compatible = "fsl,imx8-gpu";
+ reg = <0x0 0x53100000 0 0x40000>;
+ interrupts = <GIC_SPI 64 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8QM_GPU0_CORE_CLK>, <&clk IMX8QM_GPU0_SHADER_CLK>;
+ clock-names = "core", "shader";
+ assigned-clocks = <&clk IMX8QM_GPU0_CORE_CLK>, <&clk IMX8QM_GPU0_SHADER_CLK>;
+ assigned-clock-rates = <800000000>, <1000000000>;
+ fsl,sc_gpu_pid = <SC_R_GPU_0_PID0>;
+ power-domains = <&pd_gpu0>;
+ status = "disabled";
+ };
+
+ gpu_3d1: gpu@54100000 {
+ compatible = "fsl,imx8-gpu";
+ reg = <0x0 0x54100000 0x0 0x40000>;
+ interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8QM_GPU1_CORE_CLK>, <&clk IMX8QM_GPU1_SHADER_CLK>;
+ clock-names = "core", "shader";
+ assigned-clocks = <&clk IMX8QM_GPU1_CORE_CLK>, <&clk IMX8QM_GPU1_SHADER_CLK>;
+ assigned-clock-rates = <800000000>, <1000000000>;
+ fsl,sc_gpu_pid = <SC_R_GPU_1_PID0>;
+ power-domains = <&pd_gpu1>;
+ status = "disabled";
+ };
+
+ imx8_gpu_ss: imx8_gpu_ss {
+ compatible = "fsl,imx8qm-gpu", "fsl,imx8-gpu-ss";
+ cores = <&gpu_3d0>, <&gpu_3d1>;
+ reg = <0x0 0x80000000 0x0 0x80000000>, <0x0 0x0 0x0 0x10000000>;
+ reg-names = "phys_baseaddr", "contiguous_mem";
+ depth-compression = <0>;
+ status = "disabled";
+ };
+
+ mlb: mlb@5B060000 {
+ compatible = "fsl,imx6q-mlb150";
+ reg = <0x0 0x5B060000 0x0 0x10000>;
+ interrupt-parent = <&gic>;
+ interrupts = <0 265 IRQ_TYPE_LEVEL_HIGH>,
+ <0 266 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8QM_MLB_CLK>,
+ <&clk IMX8QM_MLB_HCLK>,
+ <&clk IMX8QM_MLB_IPG_CLK>;
+ clock-names = "mlb", "hclk", "ipg";
+ assigned-clocks = <&clk IMX8QM_MLB_CLK>,
+ <&clk IMX8QM_MLB_HCLK>,
+ <&clk IMX8QM_MLB_IPG_CLK>;
+ assigned-clock-rates = <333333333>, <333333333>, <83333333>;
+ power-domains = <&pd_conn_mlb0>;
+ status = "disabled";
+ };
+
+ usdhc1: usdhc@5b010000 {
+ compatible = "fsl,imx8qm-usdhc", "fsl,imx6sl-usdhc";
+ interrupt-parent = <&gic>;
+ interrupts = <GIC_SPI 232 IRQ_TYPE_LEVEL_HIGH>;
+ reg = <0x0 0x5b010000 0x0 0x10000>;
+ clocks = <&clk IMX8QM_SDHC0_IPG_CLK>,
+ <&clk IMX8QM_SDHC0_CLK>,
+ <&clk IMX8QM_CLK_DUMMY>;
+ clock-names = "ipg", "per", "ahb";
+ assigned-clocks = <&clk IMX8QM_SDHC0_DIV>;
+ assigned-clock-rates = <400000000>;
+ power-domains = <&pd_conn_sdch0>;
+ fsl,tuning-start-tap = <20>;
+ fsl,tuning-step= <2>;
+ iommus = <&smmu 0x11 0x7f80>;
+ status = "disabled";
+ };
+
+ usdhc2: usdhc@5b020000 {
+ compatible = "fsl,imx8qm-usdhc", "fsl,imx6sl-usdhc";
+ interrupt-parent = <&gic>;
+ interrupts = <GIC_SPI 233 IRQ_TYPE_LEVEL_HIGH>;
+ reg = <0x0 0x5b020000 0x0 0x10000>;
+ clocks = <&clk IMX8QM_SDHC1_IPG_CLK>,
+ <&clk IMX8QM_SDHC1_CLK>,
+ <&clk IMX8QM_CLK_DUMMY>;
+ clock-names = "ipg", "per", "ahb";
+ assigned-clocks = <&clk IMX8QM_SDHC1_DIV>;
+ assigned-clock-rates = <200000000>;
+ power-domains = <&pd_conn_sdch1>;
+ fsl,tuning-start-tap = <20>;
+ fsl,tuning-step= <2>;
+ iommus = <&smmu 0x11 0x7f80>;
+ status = "disabled";
+ };
+
+ usdhc3: usdhc@5b030000 {
+ compatible = "fsl,imx8qm-usdhc", "fsl,imx6sl-usdhc";
+ interrupt-parent = <&gic>;
+ interrupts = <GIC_SPI 234 IRQ_TYPE_LEVEL_HIGH>;
+ reg = <0x0 0x5b030000 0x0 0x10000>;
+ clocks = <&clk IMX8QM_SDHC2_IPG_CLK>,
+ <&clk IMX8QM_SDHC2_CLK>,
+ <&clk IMX8QM_CLK_DUMMY>;
+ clock-names = "ipg", "per", "ahb";
+ assigned-clocks = <&clk IMX8QM_SDHC2_DIV>;
+ assigned-clock-rates = <200000000>;
+ power-domains = <&pd_conn_sdch2>;
+ iommus = <&smmu 0x11 0x7f80>;
+ status = "disabled";
+ };
+
+ fec1: ethernet@5b040000 {
+ compatible = "fsl,imx8qm-fec";
+ reg = <0x0 0x5b040000 0x0 0x10000>;
+ interrupt-parent = <&wu>;
+ interrupts = <GIC_SPI 258 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 256 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 257 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 259 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8QM_ENET0_IPG_CLK>, <&clk IMX8QM_ENET0_AHB_CLK>, <&clk IMX8QM_ENET0_RGMII_TX_CLK>,
+ <&clk IMX8QM_ENET0_PTP_CLK>, <&clk IMX8QM_ENET0_TX_CLK>;
+ clock-names = "ipg", "ahb", "enet_clk_ref", "ptp", "enet_2x_txclk";
+ assigned-clocks = <&clk IMX8QM_ENET0_ROOT_DIV>,
+ <&clk IMX8QM_ENET0_REF_DIV>;
+ assigned-clock-rates = <250000000>, <125000000>;
+ fsl,num-tx-queues=<3>;
+ fsl,num-rx-queues=<3>;
+ fsl,wakeup_irq = <0>;
+ power-domains = <&pd_conn_enet0>;
+ iommus = <&smmu 0x12 0x7f80>;
+ status = "disabled";
+ };
+
+ fec2: ethernet@5b050000 {
+ compatible = "fsl,imx8qm-fec";
+ reg = <0x0 0x5b050000 0x0 0x10000>;
+ interrupt-parent = <&wu>;
+ interrupts = <GIC_SPI 262 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 260 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 261 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 263 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8QM_ENET1_IPG_CLK>, <&clk IMX8QM_ENET1_AHB_CLK>, <&clk IMX8QM_ENET1_RGMII_TX_CLK>,
+ <&clk IMX8QM_ENET1_PTP_CLK>, <&clk IMX8QM_ENET1_TX_CLK>;
+ clock-names = "ipg", "ahb", "enet_clk_ref", "ptp", "enet_2x_txclk";
+ assigned-clocks = <&clk IMX8QM_ENET1_ROOT_DIV>,
+ <&clk IMX8QM_ENET1_REF_DIV>;
+ assigned-clock-rates = <250000000>, <125000000>;
+ fsl,num-tx-queues=<3>;
+ fsl,num-rx-queues=<3>;
+ fsl,wakeup_irq = <0>;
+ power-domains = <&pd_conn_enet1>;
+ iommus = <&smmu 0x12 0x7f80>;
+ status = "disabled";
+ };
+
+ usbmisc1: usbmisc@5b0d0200 {
+ #index-cells = <1>;
+ compatible = "fsl,imx7ulp-usbmisc", "fsl,imx6q-usbmisc";
+ reg = <0x0 0x5b0d0200 0x0 0x200>;
+ };
+
+ usbmisc2: usbmisc@5b0e0200 {
+ #index-cells = <1>;
+ compatible = "fsl,imx7ulp-usbmisc", "fsl,imx6q-usbmisc";
+ reg = <0x0 0x5b0e0200 0x0 0x200>;
+ };
+
+ usbphy1: usbphy@0x5b100000 {
+ compatible = "fsl,imx8qm-usbphy", "fsl,imx7ulp-usbphy", "fsl,imx6ul-usbphy", "fsl,imx23-usbphy";
+ reg = <0x0 0x5b100000 0x0 0x1000>;
+ clocks = <&clk IMX8QM_USB2_PHY_IPG_CLK>;
+ power-domains = <&pd_conn_usbotg0_phy>;
+ };
+
+ usbphynop1: usbphynop1 {
+ compatible = "usb-nop-xceiv";
+ clocks = <&clk IMX8QM_USB3_PHY_CLK>;
+ clock-names = "main_clk";
+ power-domains = <&pd_conn_usb2_phy>;
+ };
+
+ usbphynop2: usbphynop2 {
+ compatible = "usb-nop-xceiv";
+ clocks = <&clk IMX8QM_USB2_PHY_IPG_CLK>;
+ clock-names = "main_clk";
+ power-domains = <&pd_conn_usbotg0_phy>;
+ };
+
+ usbotg1: usb@5b0d0000 {
+ compatible = "fsl,imx8qm-usb", "fsl,imx27-usb";
+ reg = <0x0 0x5b0d0000 0x0 0x200>;
+ interrupt-parent = <&wu>;
+ interrupts = <GIC_SPI 267 IRQ_TYPE_LEVEL_HIGH>;
+ fsl,usbphy = <&usbphy1>;
+ fsl,usbmisc = <&usbmisc1 0>;
+ clocks = <&clk IMX8QM_USB2_OH_AHB_CLK>;
+ ahb-burst-config = <0x0>;
+ tx-burst-size-dword = <0x10>;
+ rx-burst-size-dword = <0x10>;
+ #stream-id-cells = <1>;
+ power-domains = <&pd_conn_usbotg0>;
+ status = "disabled";
+ };
+
+ usbh1: usb@5b0e0000 {
+ compatible = "fsl,imx8qm-usb", "fsl,imx27-usb";
+ reg = <0x0 0x5b0e0000 0x0 0x200>;
+ interrupt-parent = <&wu>;
+ interrupts = <GIC_SPI 268 IRQ_TYPE_LEVEL_HIGH>;
+ phy_type = "hsic";
+ dr_mode = "host";
+ fsl,usbphy = <&usbphynop2>;
+ fsl,usbmisc = <&usbmisc2 0>;
+ clocks = <&clk IMX8QM_USB2_OH_AHB_CLK>;
+ ahb-burst-config = <0x0>;
+ tx-burst-size-dword = <0x10>;
+ rx-burst-size-dword = <0x10>;
+ #stream-id-cells = <1>;
+ power-domains = <&pd_conn_usbh1>;
+ status = "disabled";
+ };
+
+ usbotg3: usb3@5b110000 {
+ compatible = "Cadence,usb3";
+ reg = <0x0 0x5B110000 0x0 0x10000>,
+ <0x0 0x5B130000 0x0 0x10000>,
+ <0x0 0x5B140000 0x0 0x10000>,
+ <0x0 0x5B160000 0x0 0x40000>,
+ <0x0 0x5B120000 0x0 0x10000>;
+ interrupt-parent = <&wu>;
+ interrupts = <GIC_SPI 271 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8QM_USB3_LPM_CLK>,
+ <&clk IMX8QM_USB3_BUS_CLK>,
+ <&clk IMX8QM_USB3_ACLK>,
+ <&clk IMX8QM_USB3_IPG_CLK>,
+ <&clk IMX8QM_USB3_CORE_PCLK>;
+ clock-names = "usb3_lpm_clk", "usb3_bus_clk", "usb3_aclk",
+ "usb3_ipg_clk", "usb3_core_pclk";
+ power-domains = <&pd_conn_usb2>;
+ cdns3,usbphy = <&usbphynop1>;
+ status = "disabled";
+ };
+
+ ddr_pmu0: ddr_pmu@5c020000 {
+ compatible = "fsl,imx8-ddr-pmu";
+ reg = <0x0 0x5c020000 0x0 0x10000>;
+ interrupt-parent = <&gic>;
+ interrupts = <GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ ddr_pmu1: ddr_pmu@5c120000 {
+ compatible = "fsl,imx8-ddr-pmu";
+ reg = <0x0 0x5c120000 0x0 0x10000>;
+ interrupt-parent = <&gic>;
+ interrupts = <GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ vpu: vpu@2c000000 {
+ compatible = "nxp,imx8qm-vpu", "nxp,imx8x-vpu";
+ reg = <0x0 0x2c000000 0x0 0x1000000>;
+ reg-names = "iobase_vpu";
+ interrupts = <0 464 0x4>;
+ interrupt-names = "irq_vpu";
+ clocks = <&clk IMX8QM_VPU_DDR_CLK>,
+ <&clk IMX8QM_VPU_SYS_CLK>,
+ <&clk IMX8QM_VPU_XUVI_CLK>,
+ <&clk IMX8QM_VPU_UART_CLK>;
+ clock-names = "clk_vpu_ddr", "clk_vpu_sys",
+ "clk_vpu_xuvi", "clk_vpu_uart";
+ assigned-clocks = <&clk IMX8QM_VPU_DDR_CLK>,
+ <&clk IMX8QM_VPU_SYS_CLK>,
+ <&clk IMX8QM_VPU_XUVI_CLK>,
+ <&clk IMX8QM_VPU_UART_CLK>;
+ assigned-clock-rates = <800000000>, <600000000>,
+ <600000000>, <80000000>;
+ power-domains = <&pd_vpu_dec>;
+ status = "disabled";
+ };
+
+ acm: acm@59e00000 {
+ compatible = "nxp,imx8qm-acm";
+ reg = <0x0 0x59e00000 0x0 0x1D0000>;
+ status = "disabled";
+ };
+
+ dsp: dsp@556e8000 {
+ compatible = "fsl,imx8qm-dsp";
+ reserved-region = <&dsp_reserved>;
+ reg = <0x0 0x556e8000 0x0 0x88000>;
+ clocks = <&clk IMX8QM_AUD_DSP_IPG>,
+ <&clk IMX8QM_AUD_OCRAM_IPG>,
+ <&clk IMX8QM_AUD_DSP_CORE_CLK>;
+ clock-names = "ipg", "ocram", "core";
+ fsl,dsp-firmware = "imx/dsp/hifi4.bin";
+ fixup-offset = <0x4000000>;
+ power-domains = <&pd_dsp>;
+ };
+
+ esai0: esai@59010000 {
+ compatible = "fsl,imx8qm-esai";
+ reg = <0x0 0x59010000 0x0 0x10000>;
+ interrupts = <GIC_SPI 409 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8QM_AUD_ESAI_0_IPG>,
+ <&clk IMX8QM_AUD_ESAI_0_EXTAL_IPG>,
+ <&clk IMX8QM_AUD_ESAI_0_IPG>,
+ <&clk IMX8QM_CLK_DUMMY>;
+ clock-names = "core", "extal", "fsys", "spba";
+ dmas = <&edma2 6 0 1>, <&edma2 7 0 0>;
+ dma-names = "rx", "tx";
+ power-domains = <&pd_esai0>;
+ status = "disabled";
+ };
+
+ spdif0: spdif@59020000 {
+ compatible = "fsl,imx8qm-spdif";
+ reg = <0x0 0x59020000 0x0 0x10000>;
+ interrupts = <GIC_SPI 456 IRQ_TYPE_LEVEL_HIGH>, /* rx */
+ <GIC_SPI 458 IRQ_TYPE_LEVEL_HIGH>; /* tx */
+ clocks = <&clk IMX8QM_AUD_SPDIF_0_GCLKW>, /* core */
+ <&clk IMX8QM_CLK_DUMMY>, /* rxtx0 */
+ <&clk IMX8QM_AUD_SPDIF_0_TX_CLK>, /* rxtx1 */
+ <&clk IMX8QM_CLK_DUMMY>, /* rxtx2 */
+ <&clk IMX8QM_CLK_DUMMY>, /* rxtx3 */
+ <&clk IMX8QM_CLK_DUMMY>, /* rxtx4 */
+ <&clk IMX8QM_IPG_AUD_CLK_ROOT>, /* rxtx5 */
+ <&clk IMX8QM_CLK_DUMMY>, /* rxtx6 */
+ <&clk IMX8QM_CLK_DUMMY>, /* rxtx7 */
+ <&clk IMX8QM_CLK_DUMMY>; /* spba */
+ clock-names = "core", "rxtx0",
+ "rxtx1", "rxtx2",
+ "rxtx3", "rxtx4",
+ "rxtx5", "rxtx6",
+ "rxtx7", "spba";
+ dmas = <&edma2 8 0 5>, <&edma2 9 0 4>;
+ dma-names = "rx", "tx";
+ power-domains = <&pd_spdif0>;
+ status = "disabled";
+ };
+
+ spdif1: spdif@59030000 {
+ compatible = "fsl,imx8qm-spdif";
+ reg = <0x0 0x59030000 0x0 0x10000>;
+ interrupts = <GIC_SPI 460 IRQ_TYPE_LEVEL_HIGH>, /* rx */
+ <GIC_SPI 462 IRQ_TYPE_LEVEL_HIGH>; /* tx */
+ clocks = <&clk IMX8QM_AUD_SPDIF_1_GCLKW>, /* core */
+ <&clk IMX8QM_CLK_DUMMY>, /* rxtx0 */
+ <&clk IMX8QM_AUD_SPDIF_1_TX_CLK>, /* rxtx1 */
+ <&clk IMX8QM_CLK_DUMMY>, /* rxtx2 */
+ <&clk IMX8QM_CLK_DUMMY>, /* rxtx3 */
+ <&clk IMX8QM_CLK_DUMMY>, /* rxtx4 */
+ <&clk IMX8QM_IPG_AUD_CLK_ROOT>, /* rxtx5 */
+ <&clk IMX8QM_CLK_DUMMY>, /* rxtx6 */
+ <&clk IMX8QM_CLK_DUMMY>, /* rxtx7 */
+ <&clk IMX8QM_CLK_DUMMY>; /* spba */
+ clock-names = "core", "rxtx0",
+ "rxtx1", "rxtx2",
+ "rxtx3", "rxtx4",
+ "rxtx5", "rxtx6",
+ "rxtx7", "spba";
+ dmas = <&edma2 10 0 5>, <&edma2 11 0 4>;
+ dma-names = "rx", "tx";
+ power-domains = <&pd_spdif1>;
+ status = "disabled";
+ };
+
+ sai1: sai@59050000 {
+ compatible = "fsl,imx8qm-sai";
+ reg = <0x0 0x59050000 0x0 0x10000>;
+ interrupts = <GIC_SPI 316 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8QM_AUD_SAI_1_IPG>,
+ <&clk IMX8QM_CLK_DUMMY>,
+ <&clk IMX8QM_AUD_SAI_1_MCLK>,
+ <&clk IMX8QM_CLK_DUMMY>,
+ <&clk IMX8QM_CLK_DUMMY>;
+ clock-names = "bus", "mclk0", "mclk1", "mclk2", "mclk3";
+ dma-names = "rx", "tx";
+ dmas = <&edma2 14 0 1>, <&edma2 15 0 0>;
+ status = "disabled";
+ power-domains = <&pd_sai1>;
+ };
+
+
+ sai0: sai@59040000 {
+ compatible = "fsl,imx8qm-sai";
+ reg = <0x0 0x59040000 0x0 0x10000>;
+ interrupts = <GIC_SPI 314 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8QM_AUD_SAI_0_IPG>,
+ <&clk IMX8QM_CLK_DUMMY>,
+ <&clk IMX8QM_AUD_SAI_0_MCLK>,
+ <&clk IMX8QM_CLK_DUMMY>,
+ <&clk IMX8QM_CLK_DUMMY>;
+ clock-names = "bus", "mclk0", "mclk1", "mclk2", "mclk3";
+ dma-names = "rx", "tx";
+ dmas = <&edma2 12 0 1>, <&edma2 13 0 0>;
+ status = "disabled";
+ power-domains = <&pd_sai0>;
+ };
+
+ sai2: sai@59060000 {
+ compatible = "fsl,imx8qm-sai";
+ reg = <0x0 0x59060000 0x0 0x10000>;
+ interrupts = <GIC_SPI 318 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8QM_AUD_SAI_2_IPG>,
+ <&clk IMX8QM_CLK_DUMMY>,
+ <&clk IMX8QM_AUD_SAI_2_MCLK>,
+ <&clk IMX8QM_CLK_DUMMY>,
+ <&clk IMX8QM_CLK_DUMMY>;
+ clock-names = "bus", "mclk0", "mclk1", "mclk2", "mclk3";
+ dma-names = "rx";
+ dmas = <&edma2 16 0 1>;
+ status = "disabled";
+ power-domains = <&pd_sai2>;
+ };
+
+ sai3: sai@59070000 {
+ compatible = "fsl,imx8qm-sai";
+ reg = <0x0 0x59070000 0x0 0x10000>;
+ interrupts = <GIC_SPI 323 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8QM_AUD_SAI_3_IPG>,
+ <&clk IMX8QM_CLK_DUMMY>,
+ <&clk IMX8QM_AUD_SAI_3_MCLK>,
+ <&clk IMX8QM_CLK_DUMMY>,
+ <&clk IMX8QM_CLK_DUMMY>;
+ clock-names = "bus", "mclk0", "mclk1", "mclk2", "mclk3";
+ dma-names = "rx";
+ dmas = <&edma2 17 0 1>;
+ status = "disabled";
+ power-domains = <&pd_sai3>;
+ };
+
+ sai_hdmi_rx: sai@59080000 {
+ compatible = "fsl,imx8qm-sai";
+ reg = <0x0 0x59080000 0x0 0x10000>;
+ interrupts = <GIC_SPI 325 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8QM_AUD_SAI_HDMIRX0_IPG>,
+ <&clk IMX8QM_CLK_DUMMY>,
+ <&clk IMX8QM_AUD_SAI_HDMIRX0_MCLK>,
+ <&clk IMX8QM_CLK_DUMMY>,
+ <&clk IMX8QM_CLK_DUMMY>;
+ clock-names = "bus", "mclk0", "mclk1", "mclk2", "mclk3";
+ dma-names = "rx";
+ dmas = <&edma2 18 0 1>;
+ fsl,dataline = <0 0xf 0x0>;
+ status = "disabled";
+ power-domains = <&pd_sai4>;
+ };
+
+ sai_hdmi_tx: sai@59090000 {
+ compatible = "fsl,imx8qm-sai";
+ reg = <0x0 0x59090000 0x0 0x10000>;
+ interrupts = <GIC_SPI 327 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8QM_AUD_SAI_HDMITX0_IPG>,
+ <&clk IMX8QM_CLK_DUMMY>,
+ <&clk IMX8QM_AUD_SAI_HDMITX0_MCLK>,
+ <&clk IMX8QM_CLK_DUMMY>,
+ <&clk IMX8QM_CLK_DUMMY>;
+ clock-names = "bus", "mclk0", "mclk1", "mclk2", "mclk3";
+ dma-names = "tx";
+ dmas = <&edma2 19 0 0>;
+ fsl,dataline = <0 0x0 0xf>;
+ status = "disabled";
+ power-domains = <&pd_sai5>;
+ };
+
+ esai1: esai@59810000 {
+ compatible = "fsl,imx8qm-esai";
+ reg = <0x0 0x59810000 0x0 0x10000>;
+ interrupts = <GIC_SPI 411 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8QM_AUD_ESAI_1_IPG>,
+ <&clk IMX8QM_AUD_ESAI_1_EXTAL_IPG>,
+ <&clk IMX8QM_AUD_ESAI_1_IPG>,
+ <&clk IMX8QM_CLK_DUMMY>;
+ clock-names = "core", "extal", "fsys", "spba";
+ dmas = <&edma3 6 0 1>, <&edma3 7 0 0>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ power-domains = <&pd_esai1>;
+ };
+
+ sai6: sai@59820000 {
+ compatible = "fsl,imx8qm-sai";
+ reg = <0x0 0x59820000 0x0 0x10000>;
+ interrupts = <GIC_SPI 329 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8QM_AUD_SAI_6_IPG>,
+ <&clk IMX8QM_CLK_DUMMY>,
+ <&clk IMX8QM_AUD_SAI_6_MCLK>,
+ <&clk IMX8QM_CLK_DUMMY>,
+ <&clk IMX8QM_CLK_DUMMY>;
+ clock-names = "bus", "mclk0", "mclk1", "mclk2", "mclk3";
+ dma-names = "rx", "tx";
+ dmas = <&edma3 8 0 1>, <&edma3 9 0 0>;
+ status = "disabled";
+ power-domains = <&pd_sai6>;
+ };
+
+ sai7: sai@59830000 {
+ compatible = "fsl,imx8qm-sai";
+ reg = <0x0 0x59830000 0x0 0x10000>;
+ interrupts = <GIC_SPI 331 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8QM_AUD_SAI_7_IPG>,
+ <&clk IMX8QM_CLK_DUMMY>,
+ <&clk IMX8QM_AUD_SAI_7_MCLK>,
+ <&clk IMX8QM_CLK_DUMMY>,
+ <&clk IMX8QM_CLK_DUMMY>;
+ clock-names = "bus", "mclk0", "mclk1", "mclk2", "mclk3";
+ dma-names = "tx";
+ dmas = <&edma3 10 0 0>;
+ status = "disabled";
+ power-domains = <&pd_sai7>;
+ };
+
+ amix: amix@59840000 {
+ compatible = "fsl,imx8qm-amix";
+ reg = <0x0 0x59840000 0x0 0x10000>;
+ clocks = <&clk IMX8QM_AUD_AMIX_IPG>;
+ clock-names = "ipg";
+ power-domains = <&pd_amix>;
+ status = "disabled";
+ };
+
+ asrc0: asrc@59000000 {
+ compatible = "fsl,imx8qm-asrc0";
+ reg = <0x0 0x59000000 0x0 0x10000>;
+ interrupts = <GIC_SPI 372 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 373 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8QM_AUD_ASRC_0_IPG>,
+ <&clk IMX8QM_AUD_ASRC_0_MEM>,
+ <&clk IMX8QM_AUD_ACM_AUD_PLL_CLK0_CLK>,
+ <&clk IMX8QM_AUD_ACM_AUD_PLL_CLK1_CLK>,
+ <&clk IMX8QM_ACM_AUD_CLK0_SEL>,
+ <&clk IMX8QM_ACM_AUD_CLK1_SEL>,
+ <&clk IMX8QM_CLK_DUMMY>,
+ <&clk IMX8QM_CLK_DUMMY>,
+ <&clk IMX8QM_CLK_DUMMY>,
+ <&clk IMX8QM_CLK_DUMMY>,
+ <&clk IMX8QM_CLK_DUMMY>,
+ <&clk IMX8QM_CLK_DUMMY>,
+ <&clk IMX8QM_CLK_DUMMY>,
+ <&clk IMX8QM_CLK_DUMMY>,
+ <&clk IMX8QM_CLK_DUMMY>,
+ <&clk IMX8QM_CLK_DUMMY>,
+ <&clk IMX8QM_CLK_DUMMY>,
+ <&clk IMX8QM_CLK_DUMMY>,
+ <&clk IMX8QM_CLK_DUMMY>;
+ clock-names = "ipg", "mem",
+ "asrck_0", "asrck_1", "asrck_2", "asrck_3",
+ "asrck_4", "asrck_5", "asrck_6", "asrck_7",
+ "asrck_8", "asrck_9", "asrck_a", "asrck_b",
+ "asrck_c", "asrck_d", "asrck_e", "asrck_f",
+ "spba";
+ dmas = <&edma2 0 0 0>, <&edma2 1 0 0>, <&edma2 2 0 0>,
+ <&edma2 3 0 1>, <&edma2 4 0 1>, <&edma2 5 0 1>;
+ dma-names = "rxa", "rxb", "rxc",
+ "txa", "txb", "txc";
+ fsl,asrc-rate = <8000>;
+ fsl,asrc-width = <16>;
+ power-domains = <&pd_asrc0>;
+ status = "disabled";
+ };
+
+ asrc1: asrc@59800000 {
+ compatible = "fsl,imx8qm-asrc1";
+ reg = <0x0 0x59800000 0x0 0x10000>;
+ interrupts = <GIC_SPI 380 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 381 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8QM_AUD_ASRC_1_IPG>,
+ <&clk IMX8QM_AUD_ASRC_1_MEM>,
+ <&clk IMX8QM_AUD_ACM_AUD_PLL_CLK0_CLK>,
+ <&clk IMX8QM_AUD_ACM_AUD_PLL_CLK1_CLK>,
+ <&clk IMX8QM_ACM_AUD_CLK0_SEL>,
+ <&clk IMX8QM_ACM_AUD_CLK1_SEL>,
+ <&clk IMX8QM_CLK_DUMMY>,
+ <&clk IMX8QM_CLK_DUMMY>,
+ <&clk IMX8QM_CLK_DUMMY>,
+ <&clk IMX8QM_CLK_DUMMY>,
+ <&clk IMX8QM_CLK_DUMMY>,
+ <&clk IMX8QM_CLK_DUMMY>,
+ <&clk IMX8QM_CLK_DUMMY>,
+ <&clk IMX8QM_CLK_DUMMY>,
+ <&clk IMX8QM_CLK_DUMMY>,
+ <&clk IMX8QM_CLK_DUMMY>,
+ <&clk IMX8QM_CLK_DUMMY>,
+ <&clk IMX8QM_CLK_DUMMY>,
+ <&clk IMX8QM_CLK_DUMMY>;
+ clock-names = "ipg", "mem",
+ "asrck_0", "asrck_1", "asrck_2", "asrck_3",
+ "asrck_4", "asrck_5", "asrck_6", "asrck_7",
+ "asrck_8", "asrck_9", "asrck_a", "asrck_b",
+ "asrck_c", "asrck_d", "asrck_e", "asrck_f",
+ "spba";
+ dmas = <&edma3 0 0 0>, <&edma3 1 0 0>, <&edma3 2 0 0>,
+ <&edma3 3 0 1>, <&edma3 4 0 1>, <&edma3 5 0 1>;
+ dma-names = "rxa", "rxb", "rxc",
+ "txa", "txb", "txc";
+ fsl,asrc-rate = <8000>;
+ fsl,asrc-width = <16>;
+ power-domains = <&pd_asrc1>;
+ status = "disabled";
+ };
+
+ mqs: mqs@59850000 {
+ compatible = "fsl,imx8qm-mqs";
+ reg = <0x0 0x59850000 0x0 0x10000>;
+ clocks = <&clk IMX8QM_AUD_MQS_IPG>,
+ <&clk IMX8QM_AUD_MQS_HMCLK>;
+ clock-names = "core", "mclk";
+ power-domains = <&pd_mqs0>;
+ status = "disabled";
+ };
+
+ flexspi0: flexspi@05d120000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx8qm-flexspi";
+ reg = <0x0 0x5d120000 0x0 0x10000>,
+ <0x0 0x08000000 0x0 0x19ffffff>;
+ reg-names = "FlexSPI", "FlexSPI-memory";
+ interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8QM_FSPI0_CLK>;
+ assigned-clock-rates = <29000000>;
+ power-domains = <&pd_lsio_flexspi0>;
+ clock-names = "fspi";
+ status = "disabled";
+ };
+
+ display: display-subsystem {
+ compatible = "fsl,imx-display-subsystem";
+ ports = <&dpu1_disp0>, <&dpu1_disp1>,
+ <&dpu2_disp0>, <&dpu2_disp1>;
+ };
+
+ dma_cap: dma_cap {
+ compatible = "dma-capability";
+ only-dma-mask32 = <1>;
+ };
+
+ hsio: hsio@5f080000 {
+ compatible = "fsl,imx8qm-hsio", "syscon";
+ reg = <0x0 0x5f080000 0x0 0xF0000>; /* lpcg, csr, msic, gpio */
+ };
+
+ ocotp: ocotp {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,imx8qm-ocotp", "syscon";
+ };
+
+ pciea: pcie@0x5f000000 {
+ compatible = "fsl,imx8qm-pcie","snps,dw-pcie";
+ reg = <0x0 0x5f000000 0x0 0x10000>, /* Controller reg */
+ <0x0 0x6ff00000 0x0 0x80000>; /* PCI cfg space */
+ reg-names = "dbi", "config";
+ reserved-region = <&rpmsg_reserved>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ device_type = "pci";
+ ranges = <0x81000000 0 0x00000000 0x0 0x6ff80000 0 0x00010000 /* downstream I/O */
+ 0x82000000 0 0x60000000 0x0 0x60000000 0 0x0ff00000>; /* non-prefetchable memory */
+ num-lanes = <1>;
+
+ #interrupt-cells = <1>;
+ interrupts = <GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>; /* eDMA */
+ interrupt-names = "msi";
+
+ /*
+ * Set these clocks in default, then clocks should be
+ * refined for exact hw design of imx8 pcie.
+ */
+ clocks = <&clk IMX8QM_HSIO_PCIE_A_MSTR_AXI_CLK>,
+ <&clk IMX8QM_HSIO_PCIE_A_SLV_AXI_CLK>,
+ <&clk IMX8QM_HSIO_PHY_X2_PCLK_0>,
+ <&clk IMX8QM_HSIO_PCIE_X2_PER_CLK>,
+ <&clk IMX8QM_HSIO_PCIE_A_DBI_AXI_CLK>;
+ clock-names = "pcie", "pcie_bus", "pcie_phy", "pcie_per", "pcie_inbound_axi";
+
+ interrupt-map-mask = <0 0 0 0x7>;
+ interrupt-map = <0 0 0 1 &gic 0 73 4>,
+ <0 0 0 2 &gic 0 74 4>,
+ <0 0 0 3 &gic 0 75 4>,
+ <0 0 0 4 &gic 0 76 4>;
+ power-domains = <&pd_pcie1>;
+ fsl,max-link-speed = <3>;
+ hsio-cfg = <PCIEAX1PCIEBX1SATA>;
+ hsio = <&hsio>;
+ ctrl-id = <0>; /* pciea */
+ cpu-base-addr = <0x40000000>;
+ status = "disabled";
+ };
+
+ pcieb: pcie@0x5f010000 {
+ compatible = "fsl,imx8qm-pcie","snps,dw-pcie";
+ reg = <0x0 0x5f010000 0x0 0x10000>, /* Controller reg */
+ <0x0 0x7ff00000 0x0 0x80000>; /* PCI cfg space */
+ reg-names = "dbi", "config";
+ reserved-region = <&rpmsg_reserved>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ device_type = "pci";
+ ranges = <0x81000000 0 0x00000000 0x0 0x7ff80000 0 0x00010000 /* downstream I/O */
+ 0x82000000 0 0x70000000 0x0 0x70000000 0 0x0ff00000>; /* non-prefetchable memory */
+ num-lanes = <1>;
+
+ #interrupt-cells = <1>;
+ interrupts = <GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 104 IRQ_TYPE_LEVEL_HIGH>; /* eDMA */
+ interrupt-names = "msi";
+
+ /*
+ * Set these clocks in default, then clocks should be
+ * refined for exact hw design of imx8 pcie.
+ */
+ clocks = <&clk IMX8QM_HSIO_PCIE_B_MSTR_AXI_CLK>,
+ <&clk IMX8QM_HSIO_PCIE_B_SLV_AXI_CLK>,
+ <&clk IMX8QM_HSIO_PHY_X2_PCLK_1>,
+ <&clk IMX8QM_HSIO_PCIE_X1_PER_CLK>,
+ <&clk IMX8QM_HSIO_PCIE_B_DBI_AXI_CLK>;
+ clock-names = "pcie", "pcie_bus", "pcie_phy", "pcie_per", "pcie_inbound_axi";
+
+ interrupt-map-mask = <0 0 0 0x7>;
+ interrupt-map = <0 0 0 1 &gic 0 105 4>,
+ <0 0 0 2 &gic 0 106 4>,
+ <0 0 0 3 &gic 0 107 4>,
+ <0 0 0 4 &gic 0 108 4>;
+ power-domains = <&pd_pcie1>;
+ fsl,max-link-speed = <3>;
+ hsio-cfg = <PCIEAX1PCIEBX1SATA>;
+ hsio = <&hsio>;
+ ctrl-id = <1>; /* pcieb */
+ cpu-base-addr = <0x80000000>;
+ status = "disabled";
+ };
+
+ sata: sata@5f020000 {
+ compatible = "fsl,imx8qm-ahci";
+ reg = <0x0 0x5f020000 0x0 0x10000>, /* Controller reg */
+ <0x0 0x5f1a0000 0x0 0x10000>; /* PHY reg */
+ reg-names = "ctl", "phy";
+ interrupts = <GIC_SPI 88 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8QM_HSIO_SATA_CLK>,
+ <&clk IMX8QM_HSIO_PHY_X1_PCLK>,
+ <&clk IMX8QM_HSIO_SATA_EPCS_TX_CLK>,
+ <&clk IMX8QM_HSIO_SATA_EPCS_RX_CLK>,
+ <&clk IMX8QM_HSIO_PHY_X2_PCLK_0>,
+ <&clk IMX8QM_HSIO_PHY_X2_PCLK_1>,
+ <&clk IMX8QM_HSIO_PHY_X1_APB_CLK>;
+ clock-names = "sata", "sata_ref", "epcs_tx", "epcs_rx",
+ "phy_pclk0", "phy_pclk1", "phy_apbclk";
+ hsio = <&hsio>;
+ power-domains = <&pd_sata0>;
+ iommus = <&smmu 0x13 0x7f80>;
+ status = "disabled";
+ };
+
+ intmux_cm40: intmux@37400000 {
+ compatible = "nxp,imx-intmux";
+ reg = <0x0 0x37400000 0x0 0x1000>;
+ interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>,
+ <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>;
+ interrupt-controller;
+ interrupt-parent = <&gic>;
+ #interrupt-cells = <2>;
+ clocks = <&clk IMX8QM_CM40_IPG_CLK>;
+ clock-names = "ipg";
+ power-domains = <&pd_cm40_intmux>;
+ status = "disabled";
+ };
+
+ intmux_cm41: intmux@3b400000 {
+ compatible = "nxp,imx-intmux";
+ reg = <0x0 0x3b400000 0x0 0x1000>;
+ interrupts = <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 27 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-controller;
+ interrupt-parent = <&gic>;
+ #interrupt-cells = <2>;
+ clocks = <&clk IMX8QM_CM41_IPG_CLK>;
+ clock-names = "ipg";
+ power-domains = <&pd_cm41_intmux>;
+ status = "disabled";
+ };
+
+ imx_rpmsg: imx_rpmsg {
+ compatible = "fsl,rpmsg-bus", "simple-bus";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ mu_rpmsg: mu_rpmsg@5d200000 {
+ compatible = "fsl,imx6sx-mu";
+ reg = <0x0 0x5d200000 0x0 0x10000>;
+ interrupts = <GIC_SPI 184 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8QM_LSIO_MU5A_IPG_CLK>;
+ clock-names = "ipg";
+ power-domains = <&pd_lsio_mu5a>;
+ status = "okay";
+ };
+
+ rpmsg: rpmsg {
+ compatible = "fsl,imx8qm-rpmsg";
+ power-domains = <&pd_lsio_mu5a>;
+ mub-partition = <3>;
+ memory-region = <&rpmsg_dma_reserved>;
+ status = "disabled";
+ };
+
+ mu_rpmsg1: mu_rpmsg1@5d210000 {
+ compatible = "fsl,imx-mu-rpmsg1";
+ reg = <0x0 0x5d210000 0x0 0x10000>;
+ interrupts = <GIC_SPI 185 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8QM_LSIO_MU6A_IPG_CLK>;
+ clock-names = "ipg";
+ power-domains = <&pd_lsio_mu6a>;
+ status = "okay";
+ };
+
+ rpmsg1: rpmsg1{
+ compatible = "fsl,imx8qm-rpmsg";
+ multi-core-id = <1>;
+ mub-partition = <4>;
+ power-domains = <&pd_lsio_mu6a>;
+ memory-region = <&rpmsg_dma_reserved>;
+ status = "disabled";
+ };
+ };
+
+ crypto: caam@0x31400000 {
+ compatible = "fsl,sec-v4.0";
+ reg = <0 0x31400000 0 0x400000>;
+ interrupts = <GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 0 0x31400000 0x400000>;
+ fsl,first-jr-index = <2>;
+ fsl,sec-era = <9>;
+
+ sec_jr1: jr1@0x20000 {
+ compatible = "fsl,sec-v4.0-job-ring";
+ reg = <0x20000 0x1000>;
+ interrupts = <GIC_SPI 452 IRQ_TYPE_LEVEL_HIGH>;
+ power-domains = <&pd_caam_jr1>;
+ status = "disabled";
+ };
+
+ sec_jr2: jr2@30000 {
+ compatible = "fsl,sec-v4.0-job-ring";
+ reg = <0x30000 0x1000>;
+ interrupts = <GIC_SPI 453 IRQ_TYPE_LEVEL_HIGH>;
+ power-domains = <&pd_caam_jr2>;
+ status = "okay";
+ };
+
+ sec_jr3: jr3@40000 {
+ compatible = "fsl,sec-v4.0-job-ring";
+ reg = <0x40000 0x1000>;
+ interrupts = <GIC_SPI 454 IRQ_TYPE_LEVEL_HIGH>;
+ power-domains = <&pd_caam_jr3>;
+ status = "okay";
+ };
+ };
+
+ caam_sm: caam-sm@31800000 {
+ compatible = "fsl,imx6q-caam-sm";
+ reg = <0 0x31800000 0 0x10000>;
+ };
+
+ i2c_rpbus_0: i2c-rpbus-0 {
+ compatible = "fsl,i2c-rpbus";
+ status = "disabled";
+ };
+
+ i2c_rpbus_1: i2c-rpbus-1 {
+ compatible = "fsl,i2c-rpbus";
+ status = "disabled";
+ };
+
+ sc_pwrkey: sc-powerkey {
+ compatible = "fsl,imx8-pwrkey";
+ linux,keycode = <KEY_POWER>;
+ wakeup-source;
+ };
+
+ wdog: wdog {
+ compatible = "fsl,imx8-wdt";
+ };
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8qm-enet2-tja1100.dtsi b/arch/arm64/boot/dts/freescale/fsl-imx8qm-enet2-tja1100.dtsi
new file mode 100644
index 000000000000..410954296779
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8qm-enet2-tja1100.dtsi
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2018 NXP
+ *
+ * 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.
+ */
+
+/* fec1 cannot attach to ethphy0 since the PHY address
+ * conflict with ethphy2. So eth0 should not work.
+ * There still enable fec1 to share the MDIO bus for fec2 due
+ * to board limitation.
+ */
+&fec1 {
+ /* PHY address should rework to 2 */
+ phy-handle = <&ethphy2>;
+
+ mdio {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ethphy0: ethernet-phy@0 {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <0>;
+ tja110x,refclk_in;
+ /delete-property/ at803x,eee-disabled;
+ /delete-property/ at803x,vddio-1p8v;
+ };
+
+ ethphy2: ethernet-phy@2 {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <2>;
+ at803x,eee-disabled;
+ at803x,vddio-1p8v;
+ };
+ };
+};
+
+&fec2 {
+ pinctrl-0 = <&pinctrl_fec2_rmii>;
+ clocks = <&clk IMX8QM_ENET1_IPG_CLK>,
+ <&clk IMX8QM_ENET1_AHB_CLK>,
+ <&clk IMX8QM_ENET1_REF_50MHZ_CLK>,
+ <&clk IMX8QM_ENET1_PTP_CLK>,
+ <&clk IMX8QM_ENET1_TX_CLK>;
+ phy-mode = "rmii";
+ phy-handle = <&ethphy0>;
+ /delete-property/ phy-supply;
+};
+
+&iomuxc {
+ imx8qm-mek {
+ pinctrl_fec2_rmii: fec2rmiigrp {
+ fsl,pins = <
+ SC_P_ENET1_RGMII_TXC_CONN_ENET1_RCLK50M_OUT 0x06000020
+ SC_P_ENET1_RGMII_RXD0_CONN_ENET1_RGMII_RXD0 0x06000020
+ SC_P_ENET1_RGMII_RXD1_CONN_ENET1_RGMII_RXD1 0x06000020
+ SC_P_ENET1_RGMII_RXD2_CONN_ENET1_RMII_RX_ER 0x06000020
+ SC_P_ENET1_RGMII_RX_CTL_CONN_ENET1_RGMII_RX_CTL 0x06000020
+ SC_P_ENET1_RGMII_TXD0_CONN_ENET1_RGMII_TXD0 0x06000020
+ SC_P_ENET1_RGMII_TXD1_CONN_ENET1_RGMII_TXD1 0x06000020
+ SC_P_ENET1_RGMII_TX_CTL_CONN_ENET1_RGMII_TX_CTL 0x06000020
+ >;
+ };
+ };
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8qm-lpddr4-arm2-8cam.dts b/arch/arm64/boot/dts/freescale/fsl-imx8qm-lpddr4-arm2-8cam.dts
new file mode 100644
index 000000000000..64c530e4ba1f
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8qm-lpddr4-arm2-8cam.dts
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2017 NXP
+ *
+ * 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.
+ */
+/*
+ * MIPI CSI-2 eight cameras dts,
+ * One MIPI CSI-2 controller connected four cameras
+ * The first four cameras have enabled in mipi_csi_0.
+ * Enable the last four cameras in mipi_csi_1 here.
+ */
+
+#include "fsl-imx8qm-lpddr4-arm2.dts"
+
+&mipi_csi_1 {
+ status = "okay";
+};
+
+&i2c0_mipi_csi1 {
+ status = "okay";
+};
+
+&isi_4 {
+ status = "okay";
+};
+
+&isi_5 {
+ status = "okay";
+};
+
+&isi_6 {
+ status = "okay";
+};
+
+&isi_7 {
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8qm-lpddr4-arm2-dom0.dts b/arch/arm64/boot/dts/freescale/fsl-imx8qm-lpddr4-arm2-dom0.dts
new file mode 100644
index 000000000000..cb009a4b76a8
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8qm-lpddr4-arm2-dom0.dts
@@ -0,0 +1,331 @@
+/*
+ * Copyright 2018 NXP
+ *
+ * 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 "fsl-imx8qm-lpddr4-arm2.dts"
+#include "fsl-imx8qm-xen.dtsi"
+
+/ {
+ chosen {
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ /* Could be updated by U-Boot */
+ module@0 {
+ bootargs = "earlycon=xen console=hvc0 loglevel=8 root=/dev/mmcblk1p2 rw rootwait";
+ compatible = "xen,linux-zimage", "xen,multiboot-module";
+ reg = <0x00000000 0x80a00000 0x00000000 0xf93a00>;
+ };
+ };
+
+ domu {
+ /*
+ * There are 5 MUs, 0A is used by Dom0, 1A is used
+ * by ATF, so for DomU, 2A/3A/4A could be used.
+ * SC_R_MU_0A
+ * SC_R_MU_1A
+ * SC_R_MU_2A
+ * SC_R_MU_3A
+ * SC_R_MU_4A
+ * The rsrcs and pads will be configured by uboot scu_rm cmd
+ */
+ #address-cells = <1>;
+ #size-cells = <0>;
+ doma {
+ compatible = "xen,domu";
+ /*
+ * The name entry in VM configuration file
+ * needs to be same as here.
+ */
+ domain_name = "DomU";
+ /*
+ * The reg property will be updated by U-Boot to
+ * reflect the partition id.
+ */
+ reg = <0>;
+ init_on_rsrcs = <
+ SC_R_MU_2A
+ >;
+ rsrcs = <
+ SC_R_GPU_1_PID0
+ SC_R_GPU_1_PID1
+ SC_R_GPU_1_PID2
+ SC_R_GPU_1_PID3
+ SC_R_LVDS_1
+ SC_R_LVDS_1_I2C_0
+ SC_R_LVDS_1_PWM_0
+ SC_R_DC_1
+ SC_R_DC_1_BLIT0
+ SC_R_DC_1_BLIT1
+ SC_R_DC_1_BLIT2
+ SC_R_DC_1_BLIT_OUT
+ SC_R_UNUSED9
+ SC_R_UNUSED10
+ SC_R_DC_1_WARP
+ SC_R_UNUSED11
+ SC_R_UNUSED12
+ SC_R_DC_1_VIDEO0
+ SC_R_DC_1_VIDEO1
+ SC_R_DC_1_FRAC0
+ SC_R_UNUSED13
+ SC_R_DC_1_PLL_0
+ SC_R_DC_1_PLL_1
+ SC_R_MIPI_1
+ SC_R_MIPI_1_I2C_0
+ SC_R_MIPI_1_I2C_1
+ SC_R_MIPI_1_PWM_0
+ SC_R_HDMI
+ SC_R_HDMI_I2C_0
+ SC_R_SDHC_0
+ SC_R_USB_0
+ SC_R_USB_0_PHY
+ SC_R_UART_1
+ SC_R_DMA_0_CH14
+ SC_R_DMA_0_CH15
+ SC_R_MU_2A
+ >;
+ pads = <
+ /* i2c1_lvds1 */
+ SC_P_LVDS1_I2C1_SCL
+ SC_P_LVDS1_I2C1_SDA
+ /* emmc */
+ SC_P_EMMC0_CLK
+ SC_P_EMMC0_CMD
+ SC_P_EMMC0_DATA0
+ SC_P_EMMC0_DATA1
+ SC_P_EMMC0_DATA2
+ SC_P_EMMC0_DATA3
+ SC_P_EMMC0_DATA4
+ SC_P_EMMC0_DATA5
+ SC_P_EMMC0_DATA6
+ SC_P_EMMC0_DATA7
+ SC_P_EMMC0_STROBE
+ SC_P_EMMC0_RESET_B
+ /* usb otg */
+ SC_P_USB_SS3_TC0
+ /* uart1 */
+ SC_P_UART1_RX
+ SC_P_UART1_TX
+ SC_P_UART1_CTS_B
+ SC_P_UART1_RTS_B
+ SC_P_QSPI1A_DQS
+ >;
+ };
+ };
+
+ reserved-memory {
+ /* global autoconfigured region for contiguous allocations */
+ linux,cma {
+ compatible = "shared-dma-pool";
+ reusable;
+ size = <0 0x28000000>;
+ alloc-ranges = <0 0xd0000000 0 0x28000000>;
+ linux,cma-default;
+ };
+ };
+
+ display-subsystem {
+ compatible = "fsl,imx-display-subsystem";
+ ports = <&dpu1_disp0>, <&dpu1_disp1>;
+ };
+
+ /* Passthrough to domu */
+ mu2: mu@5d1d0000 {
+ compatible = "fsl,imx8-mu";
+ reg = <0x0 0x5d1d0000 0x0 0x10000>;
+ interrupts = <GIC_SPI 178 IRQ_TYPE_LEVEL_HIGH>;
+ fsl,scu_ap_mu_id = <0>;
+ xen,passthrough;
+ status = "disabled";
+ };
+
+};
+
+&usbotg1_lpcg {
+ xen,passthrough;
+};
+
+&sdhc1_lpcg {
+ xen,passthrough;
+};
+
+&lpuart1 {
+ xen,passthrough;
+};
+
+&lpuart1_lpcg {
+ xen,passthrough;
+};
+
+&di_lvds1_lpcg {
+ xen,passthrough;
+};
+
+&dc_1_lpcg {
+ xen,passthrough;
+};
+
+&edma01 {
+ #stream-id-cells = <1>;
+ xen,passthrough;
+ fsl,sc_rsrc_id = <SC_R_DMA_0_CH14>,
+ <SC_R_DMA_0_CH15>;
+};
+
+/* SMMU */
+&smmu {
+ mmu-masters = <&dpu2 0x13>, <&gpu_3d1 0x15>,
+ <&usdhc1 0x12>, <&usbotg1 0x11>,
+ <&edma01 0x10>;
+};
+
+&lvds_region2 {
+ xen,passthrough;
+};
+
+&irqsteer_lvds1 {
+ xen,passthrough;
+};
+
+&i2c1_lvds1 {
+ xen,passthrough;
+};
+
+&ldb2_phy {
+ xen,passthrough;
+};
+
+&ldb2 {
+ xen,passthrough;
+};
+
+&crypto {
+ /* Met CAAM failure on A0, disable it first */
+ status = "disabled";
+};
+
+&dpu2_intsteer {
+ xen,passthrough;
+};
+
+&dpu2 {
+ xen,passthrough;
+ #stream-id-cells = <1>;
+ iommus = <&smmu>;
+};
+
+&prg10 {
+ xen,passthrough;
+};
+
+&prg11 {
+ xen,passthrough;
+};
+
+&prg12 {
+ xen,passthrough;
+};
+
+&prg13 {
+ xen,passthrough;
+};
+
+&prg14 {
+ xen,passthrough;
+};
+
+&prg15 {
+ xen,passthrough;
+};
+
+&prg16 {
+ xen,passthrough;
+};
+
+&prg17 {
+ xen,passthrough;
+};
+
+&prg18 {
+ xen,passthrough;
+};
+
+&dpr3_channel1 {
+ xen,passthrough;
+};
+
+&dpr3_channel2 {
+ xen,passthrough;
+};
+
+&dpr3_channel3 {
+ xen,passthrough;
+};
+
+&dpr4_channel1 {
+ xen,passthrough;
+};
+
+&dpr4_channel2 {
+ xen,passthrough;
+};
+
+&dpr4_channel3 {
+ xen,passthrough;
+};
+
+/* GPU */
+&pd_gpu1 {
+ xen,passthrough;
+};
+
+&gpu_3d1 {
+ xen,passthrough;
+ #stream-id-cells = <1>;
+ iommus = <&smmu>;
+};
+
+&imx8_gpu_ss {
+ cores = <&gpu_3d0>;
+ /delete-property/ reg;
+ /delete-property/ reg-names;
+};
+
+&sata {
+ status = "disabled";
+};
+
+&usdhc1 {
+ xen,passthrough;
+ #stream-id-cells = <1>;
+ iommus = <&smmu>;
+};
+
+&usbotg1 {
+ /* Hack reg */
+ reg = <0x0 0x5b0d0000 0x0 0x1000>;
+ xen,passthrough;
+ #stream-id-cells = <1>;
+ iommus = <&smmu>;
+};
+
+&usbmisc1 {
+ /* Hack */
+ /delete-property/ reg;
+ status = "disabled";
+};
+
+&usbphy1 {
+ reg = <0x0 0x5b100000 0x0 0x1000>;
+ xen,passthrough;
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8qm-lpddr4-arm2-domu.dts b/arch/arm64/boot/dts/freescale/fsl-imx8qm-lpddr4-arm2-domu.dts
new file mode 100644
index 000000000000..13ecc444bca9
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8qm-lpddr4-arm2-domu.dts
@@ -0,0 +1,630 @@
+/*
+ * Copyright 2018 NXP
+ *
+ * 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.
+ */
+
+/dts-v1/;
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/clock/imx8qm-clock.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/soc/imx_rsrc.h>
+#include <dt-bindings/soc/imx8_hsio.h>
+#include <dt-bindings/soc/imx8_pd.h>
+#include <dt-bindings/pinctrl/pads-imx8qm.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/thermal/thermal.h>
+
+/ {
+ model = "Freescale i.MX8QM DOMU";
+ compatible = "fsl,imx8qm-lpddr4", "fsl,imx8qm", "xen,xenvm-4.10", "xen,xenvm";
+ interrupt-parent = <&gic>;
+ #address-cells = <0x2>;
+ #size-cells = <0x2>;
+
+ /delete-node/ aliases;
+
+ aliases {
+ mmc0 = &usdhc1;
+ dpu1 = &dpu2;
+ ldb1 = &ldb2;
+ serial1 = &lpuart1;
+ };
+
+ cpus {
+ #address-cells = <0x2>;
+ #size-cells = <0x0>;
+
+ cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,armv8";
+ enable-method = "psci";
+ reg = <0x0 0x0>;
+ };
+
+ cpu@1 {
+ device_type = "cpu";
+ compatible = "arm,armv8";
+ enable-method = "psci";
+ reg = <0x0 0x1>;
+ };
+ };
+
+ psci {
+ compatible = "arm,psci-1.0";
+ method = "hvc";
+ };
+
+ memory@80000000 {
+ device_type = "memory";
+ /* Will be updated by U-Boot or XEN TOOL */
+ reg = <0x00000000 0x40000000 0 0x40000000>;
+ };
+
+ gic: interrupt-controller@3001000 {
+ compatible = "arm,gic-v3";
+ #interrupt-cells = <3>;
+ #address-cells = <0x0>;
+ interrupt-controller;
+ redistributor-stride = <0x20000>;
+ #redistributor-regions = <0x1>;
+ reg = <0x0 0x3001000 0 0x10000>, /* GIC Dist */
+ <0x0 0x3020000 0 0x1000000>; /* GICR */
+ interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_HIGH)>;
+ interrupt-parent = <&gic>;
+ };
+
+ timer {
+ compatible = "arm,armv8-timer";
+ interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>;
+ interrupt-parent = <&gic>;
+ clock-frequency = <8000000>;
+ };
+
+ hypervisor {
+ compatible = "xen,xen-4.11", "xen,xen";
+ reg = <0x0 0x38000000 0x0 0x1000000>;
+ interrupts = <GIC_PPI 15 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>;
+ interrupt-parent = <&gic>;
+ };
+
+ passthrough {
+ compatible = "simple-bus";
+ ranges;
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ firmware {
+ android {
+ compatible = "android,firmware";
+ fstab {
+ compatible = "android,fstab";
+ vendor {
+ compatible = "android,vendor";
+ /* emmc node which used if androidboot.storage_type=emmc */
+ dev_emmc = "/dev/block/platform/passthrough/15b010000.usdhc/by-name/vendor";
+ type = "ext4";
+ mnt_flags = "ro,barrier=1,inode_readahead_blks=8";
+ fsmgr_flags = "wait,slotselect,avb";
+ };
+ };
+
+ vbmeta {
+ /*we need use FirstStageMountVBootV2 if we enable avb*/
+ compatible = "android,vbmeta";
+ /*parts means the partition witch can be mount in first stage*/
+ parts = "vbmeta,boot,system,vendor";
+ };
+ };
+ };
+
+
+ clk: clk {
+ compatible = "fsl,imx8qm-clk";
+ #clock-cells = <1>;
+ fsl,lpcg_base_offset = <0x00000001 0x00000000>;
+ };
+
+ iomuxc: iomuxc {
+ compatible = "fsl,imx8qm-iomuxc";
+ };
+
+ #include "fsl-imx8qm-device.dtsi"
+
+ mu2: mu@15d1d0000 {
+ compatible = "fsl,imx8-mu";
+ reg = <0x1 0x5d1d0000 0x0 0x10000>;
+ interrupts = <GIC_SPI 178 IRQ_TYPE_LEVEL_HIGH>;
+ fsl,scu_ap_mu_id = <0>;
+ status = "okay";
+ };
+
+ usb_lpcg {
+ reg = <0x1 0x5b270000 0x0 0x10000>;
+ };
+
+ edma01: dma-controller1@5a1f0000 {
+ compatible = "fsl,imx8qm-edma";
+ reg = <0x1 0x5a2e0000 0x0 0x10000>, /* channel14 UART1 rx */
+ <0x1 0x5a2f0000 0x0 0x10000>; /* channel15 UART1 tx */
+ #dma-cells = <3>;
+ dma-channels = <2>;
+ interrupts = <GIC_SPI 436 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 437 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "edma0-chan14-rx", "edma0-chan15-tx";
+ status = "okay";
+ };
+ };
+};
+
+/delete-node/ &tsens;
+/delete-node/ &thermal_zones;
+/delete-node/ &rtc;
+
+&display {
+ ports = <&dpu2_disp0>, <&dpu2_disp1>;
+};
+
+&dpu2_intsteer {
+ reg = <0x1 0x57000000 0x0 0x10000>;
+ status = "okay";
+};
+
+&prg10 {
+ reg = <0x1 0x57040000 0x0 0x10000>;
+ status = "okay";
+};
+
+&prg11 {
+ reg = <0x1 0x57050000 0x0 0x10000>;
+ status = "okay";
+};
+
+&prg12 {
+ reg = <0x1 0x57060000 0x0 0x10000>;
+ status = "okay";
+};
+
+&prg13 {
+ reg = <0x1 0x57070000 0x0 0x10000>;
+ status = "okay";
+};
+
+&prg14 {
+ reg = <0x1 0x57080000 0x0 0x10000>;
+ status = "okay";
+};
+
+&prg15 {
+ reg = <0x1 0x57090000 0x0 0x10000>;
+ status = "okay";
+};
+
+&prg16 {
+ reg = <0x1 0x570a0000 0x0 0x10000>;
+ status = "okay";
+};
+
+&prg17 {
+ reg = <0x1 0x570b0000 0x0 0x10000>;
+ status = "okay";
+};
+
+&prg18 {
+ reg = <0x1 0x570c0000 0x0 0x10000>;
+ status = "okay";
+};
+
+&dpr3_channel1 {
+ reg = <0x1 0x570d0000 0x0 0x10000>;
+ status = "okay";
+};
+
+&dpr3_channel2 {
+ reg = <0x1 0x570e0000 0x0 0x10000>;
+ status = "okay";
+};
+
+&dpr3_channel3 {
+ reg = <0x1 0x570f0000 0x0 0x10000>;
+ status = "okay";
+};
+
+&dpr4_channel1 {
+ reg = <0x1 0x57100000 0x0 0x10000>;
+ status = "okay";
+};
+
+&dpr4_channel2 {
+ reg = <0x1 0x57110000 0x0 0x10000>;
+ status = "okay";
+};
+
+&dpr4_channel3 {
+ reg = <0x1 0x57120000 0x0 0x10000>;
+ status = "okay";
+};
+
+&dpu2 {
+ reg = <0x1 0x57180000 0x0 0x40000>;
+ status = "okay";
+
+ dpu2_disp0: port@0 {
+ dpu2_disp0_mipi_dsi: mipi-dsi-endpoint {
+ /delete-property/ remote-endpoint;
+ };
+ };
+ dpu2_disp1: port@1 {
+ reg = <1>;
+
+ dpu2_disp1_lvds0: lvds0-endpoint {
+ remote-endpoint = <&ldb2_lvds0>;
+ };
+
+ dpu2_disp1_lvds1: lvds1-endpoint {
+ remote-endpoint = <&ldb2_lvds1>;
+ };
+ };
+};
+
+/delete-node/ &hdmi;
+/delete-node/ &irqsteer_dsi0;
+/delete-node/ &i2c0_mipi_dsi0;
+/delete-node/ &mipi_dsi_csr1;
+/delete-node/ &mipi_dsi_phy1;
+/delete-node/ &mipi_dsi1;
+/delete-node/ &mipi_dsi_bridge1;
+
+&lvds_region2 {
+ reg = <0x1 0x57240000 0x0 0x10000>;
+ status = "okay";
+};
+
+&ldb2_phy {
+ reg = <0x1 0x57241000 0x0 0x100>;
+ status = "okay";
+};
+
+&ldb2 {
+ status = "okay";
+
+ lvds-channel@0 {
+ fsl,data-mapping = "jeida";
+ fsl,data-width = <24>;
+ status = "okay";
+
+ port@1 {
+ reg = <1>;
+
+ lvds1_out: endpoint {
+ remote-endpoint = <&it6263_1_in>;
+ };
+ };
+ };
+};
+
+/delete-node/ &lvds0_pwm;
+/delete-node/ &dpu1_intsteer;
+/delete-node/ &prg1;
+/delete-node/ &prg2;
+/delete-node/ &prg3;
+/delete-node/ &prg4;
+/delete-node/ &prg5;
+/delete-node/ &prg6;
+/delete-node/ &prg7;
+/delete-node/ &prg8;
+/delete-node/ &prg9;
+/delete-node/ &dpr1_channel1;
+/delete-node/ &dpr1_channel2;
+/delete-node/ &dpr1_channel3;
+/delete-node/ &dpr2_channel1;
+/delete-node/ &dpr2_channel2;
+/delete-node/ &dpr2_channel3;
+/delete-node/ &dpu1;
+/delete-node/ &dsp;
+/delete-node/ &irqsteer_dsi1;
+/delete-node/ &i2c0_mipi_dsi1;
+/delete-node/ &mipi_dsi_csr2;
+/delete-node/ &mipi_dsi_phy2;
+/delete-node/ &mipi_dsi2;
+/delete-node/ &mipi_dsi_bridge2;
+/delete-node/ &lvds_region1;
+/delete-node/ &ldb1_phy;
+/delete-node/ &ldb1;
+/delete-node/ &lvds1_pwm;
+/delete-node/ &camera;
+/delete-node/ &adc0;
+/delete-node/ &adc1;
+/delete-node/ &i2c0;
+/delete-node/ &i2c1;
+/delete-node/ &i2c2;
+/delete-node/ &i2c3;
+/delete-node/ &i2c4;
+/delete-node/ &i2c0_cm40;
+/delete-node/ &i2c0_cm41;
+/delete-node/ &irqsteer_hdmi;
+/delete-node/ &i2c0_hdmi;
+
+&irqsteer_lvds1 {
+ reg = <0x1 0x57240000 0x0 0x1000>;
+ /delete-property/ interrupt-parent;
+ status = "okay";
+};
+
+/delete-node/ &flexcan1;
+/delete-node/ &flexcan2;
+/delete-node/ &flexcan3;
+
+&i2c1_lvds1 {
+ reg = <0x1 0x57247000 0x0 0x1000>;
+ status = "okay";
+};
+
+/delete-node/ &irqsteer_lvds0;
+/delete-node/ &i2c1_lvds0;
+/delete-node/ &irqsteer_csi0;
+/delete-node/ &i2c0_mipi_csi0;
+/delete-node/ &irqsteer_csi1;
+/delete-node/ &i2c0_mipi_csi1;
+/delete-node/ &lpspi0;
+/delete-node/ &lpspi3;
+/delete-node/ &lpuart0;
+
+&lpuart1 {
+ /delete-property/ interrupt-parent;
+ reg = <0x1 0x5a070000 0 0x1000>;
+ dmas = <&edma01 15 0 0>, <&edma01 14 0 1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lpuart1>;
+ status = "okay";
+};
+
+/delete-node/ &lpuart2;
+/delete-node/ &lpuart3;
+/delete-node/ &lpuart4;
+/delete-node/ &emvsim0;
+/delete-node/ &edma0;
+/delete-node/ &edma2;
+/delete-node/ &edma3;
+/delete-node/ &gpio0;
+/delete-node/ &gpio1;
+/delete-node/ &gpio2;
+/delete-node/ &gpio3;
+/delete-node/ &gpio4;
+/delete-node/ &gpio5;
+/delete-node/ &gpio6;
+/delete-node/ &gpio7;
+/delete-node/ &gpio0_mipi_csi0;
+/delete-node/ &gpio0_mipi_csi1;
+/delete-node/ &gpt0;
+/delete-node/ &pwm0;
+/delete-node/ &pwm1;
+/delete-node/ &pwm2;
+/delete-node/ &pwm3;
+/delete-node/ &pwm4;
+/delete-node/ &pwm5;
+/delete-node/ &pwm6;
+/delete-node/ &pwm7;
+
+&gpu_3d1 {
+ reg = <0x0 0x24100000 0 0x40000>;
+ status = "okay";
+};
+
+/delete-node/ &gpu_3d0;
+
+&imx8_gpu_ss {
+ /* xen guests have 3GB of low RAM @ 1GB */
+ reg = <0x0 0x40000000 0x0 0xc0000000>;
+ reg-names = "phys_baseaddr";
+ cores = <&gpu_3d1>;
+ status = "okay";
+};
+
+/delete-node/ &mlb;
+
+&usdhc1 {
+ compatible = "fsl,imx8qm-usdhc", "fsl,imx6sl-usdhc";
+ /*interrupt-parent = <&gic>;*/
+ /delete-property/ interrupt-parent;
+ reg = <0x1 0x5b010000 0x0 0x10000>;
+};
+
+/delete-node/ &usdhc2;
+/delete-node/ &usdhc3;
+/delete-node/ &fec1;
+/delete-node/ &fec2;
+
+&usbmisc1 {
+ reg = <0x1 0x5b0d0200 0x0 0x200>;
+};
+
+/delete-node/ &usbmisc2;
+
+&usbphy1 {
+ reg = <0x1 0x5b100000 0x0 0x200>;
+};
+
+/delete-node/ &usbh1;
+/delete-node/ &usbotg3;
+/delete-node/ &usbphynop1;
+/delete-node/ &usbphynop2;
+
+&usbotg1 {
+ reg = <0x1 0x5b0d0000 0x0 0x200>;
+ /delete-property/ interrupt-parent;
+};
+
+/delete-node/ &ddr_pmu0;
+/delete-node/ &ddr_pmu1;
+/delete-node/ &vpu;
+/delete-node/ &acm;
+/delete-node/ &esai0;
+/delete-node/ &esai1;
+/delete-node/ &spdif0;
+/delete-node/ &spdif1;
+/delete-node/ &sai1;
+/delete-node/ &sai0;
+/delete-node/ &sai2;
+/delete-node/ &sai3;
+/delete-node/ &sai_hdmi_rx;
+/delete-node/ &sai_hdmi_tx;
+/delete-node/ &sai6;
+/delete-node/ &sai7;
+/delete-node/ &amix;
+/delete-node/ &asrc0;
+/delete-node/ &asrc1;
+/delete-node/ &mqs;
+/delete-node/ &flexspi0;
+
+&dma_cap {
+ compatible = "dma-capability";
+ only-dma-mask32 = <1>;
+};
+
+/delete-node/ &hsio;
+/delete-node/ &ocotp;
+/delete-node/ &pciea;
+/delete-node/ &pcieb;
+/delete-node/ &sata;
+
+/delete-node/ &intmux_cm40;
+/delete-node/ &intmux_cm41;
+/delete-node/ &imx_rpmsg;
+/delete-node/ &crypto;
+/delete-node/ &caam_sm;
+/delete-node/ &sc_pwrkey;
+/delete-node/ &wdog;
+/delete-node/ &wu;
+
+&iomuxc {
+ imx8qm-mek {
+ pinctrl_usdhc1: usdhc1grp {
+ fsl,pins = <
+ SC_P_EMMC0_CLK_CONN_EMMC0_CLK 0x06000041
+ SC_P_EMMC0_CMD_CONN_EMMC0_CMD 0x00000021
+ SC_P_EMMC0_DATA0_CONN_EMMC0_DATA0 0x00000021
+ SC_P_EMMC0_DATA1_CONN_EMMC0_DATA1 0x00000021
+ SC_P_EMMC0_DATA2_CONN_EMMC0_DATA2 0x00000021
+ SC_P_EMMC0_DATA3_CONN_EMMC0_DATA3 0x00000021
+ SC_P_EMMC0_DATA4_CONN_EMMC0_DATA4 0x00000021
+ SC_P_EMMC0_DATA5_CONN_EMMC0_DATA5 0x00000021
+ SC_P_EMMC0_DATA6_CONN_EMMC0_DATA6 0x00000021
+ SC_P_EMMC0_DATA7_CONN_EMMC0_DATA7 0x00000021
+ SC_P_EMMC0_STROBE_CONN_EMMC0_STROBE 0x06000041
+ SC_P_EMMC0_RESET_B_CONN_EMMC0_RESET_B 0x00000021
+ >;
+ };
+
+ pinctrl_usdhc1_100mhz: usdhc1grp100mhz {
+ fsl,pins = <
+ SC_P_EMMC0_CLK_CONN_EMMC0_CLK 0x06000040
+ SC_P_EMMC0_CMD_CONN_EMMC0_CMD 0x00000020
+ SC_P_EMMC0_DATA0_CONN_EMMC0_DATA0 0x00000020
+ SC_P_EMMC0_DATA1_CONN_EMMC0_DATA1 0x00000020
+ SC_P_EMMC0_DATA2_CONN_EMMC0_DATA2 0x00000020
+ SC_P_EMMC0_DATA3_CONN_EMMC0_DATA3 0x00000020
+ SC_P_EMMC0_DATA4_CONN_EMMC0_DATA4 0x00000020
+ SC_P_EMMC0_DATA5_CONN_EMMC0_DATA5 0x00000020
+ SC_P_EMMC0_DATA6_CONN_EMMC0_DATA6 0x00000020
+ SC_P_EMMC0_DATA7_CONN_EMMC0_DATA7 0x00000020
+ SC_P_EMMC0_STROBE_CONN_EMMC0_STROBE 0x06000040
+ SC_P_EMMC0_RESET_B_CONN_EMMC0_RESET_B 0x00000020
+ >;
+ };
+
+ pinctrl_usdhc1_200mhz: usdhc1grp200mhz {
+ fsl,pins = <
+ SC_P_EMMC0_CLK_CONN_EMMC0_CLK 0x06000040
+ SC_P_EMMC0_CMD_CONN_EMMC0_CMD 0x00000020
+ SC_P_EMMC0_DATA0_CONN_EMMC0_DATA0 0x00000020
+ SC_P_EMMC0_DATA1_CONN_EMMC0_DATA1 0x00000020
+ SC_P_EMMC0_DATA2_CONN_EMMC0_DATA2 0x00000020
+ SC_P_EMMC0_DATA3_CONN_EMMC0_DATA3 0x00000020
+ SC_P_EMMC0_DATA4_CONN_EMMC0_DATA4 0x00000020
+ SC_P_EMMC0_DATA5_CONN_EMMC0_DATA5 0x00000020
+ SC_P_EMMC0_DATA6_CONN_EMMC0_DATA6 0x00000020
+ SC_P_EMMC0_DATA7_CONN_EMMC0_DATA7 0x00000020
+ SC_P_EMMC0_STROBE_CONN_EMMC0_STROBE 0x06000040
+ SC_P_EMMC0_RESET_B_CONN_EMMC0_RESET_B 0x00000020
+ >;
+ };
+
+ pinctrl_usbotg1: usbotg1 {
+ fsl,pins = <
+ SC_P_USB_SS3_TC0_CONN_USB_OTG1_PWR 0x00000021
+ >;
+ };
+
+ pinctrl_lvds1_lpi2c1: lvds1lpi2c1grp {
+ fsl,pins = <
+ SC_P_LVDS1_I2C1_SCL_LVDS1_I2C1_SCL 0xc600004c
+ SC_P_LVDS1_I2C1_SDA_LVDS1_I2C1_SDA 0xc600004c
+ >;
+ };
+
+ pinctrl_lpuart1: lpuart1grp {
+ fsl,pins = <
+ SC_P_UART1_RX_DMA_UART1_RX 0x06000020
+ SC_P_UART1_TX_DMA_UART1_TX 0x06000020
+ SC_P_UART1_CTS_B_DMA_UART1_CTS_B 0x06000020
+ SC_P_UART1_RTS_B_DMA_UART1_RTS_B 0x06000020
+ SC_P_QSPI1A_DQS_LSIO_GPIO4_IO22 0x00000021
+ >;
+ };
+ };
+};
+
+&usdhc1 {
+ /delete-property/ iommus;
+ pinctrl-names = "default", "state_100mhz", "state_200mhz";
+ pinctrl-0 = <&pinctrl_usdhc1>;
+ pinctrl-1 = <&pinctrl_usdhc1_100mhz>;
+ pinctrl-2 = <&pinctrl_usdhc1_200mhz>;
+ bus-width = <8>;
+ non-removable;
+ status = "okay";
+};
+
+&usbotg1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usbotg1>;
+ srp-disable;
+ hnp-disable;
+ adp-disable;
+ power-polarity-active-high;
+ disable-over-current;
+ status = "okay";
+};
+
+&i2c1_lvds1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lvds1_lpi2c1>;
+ clock-frequency = <100000>;
+ status = "okay";
+
+ lvds-to-hdmi-bridge@4c {
+ compatible = "ite,it6263";
+ reg = <0x4c>;
+
+ port {
+ it6263_1_in: endpoint {
+ clock-lanes = <3>;
+ data-lanes = <0 1 2 4>;
+ remote-endpoint = <&lvds1_out>;
+ };
+ };
+ };
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8qm-lpddr4-arm2-dp-dig-pll.dts b/arch/arm64/boot/dts/freescale/fsl-imx8qm-lpddr4-arm2-dp-dig-pll.dts
new file mode 100644
index 000000000000..46600260dd41
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8qm-lpddr4-arm2-dp-dig-pll.dts
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2018 NXP
+ *
+ * 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.
+ */
+/*
+ * HDMI only dts, disable ldb display.
+ */
+
+#include "fsl-imx8qm-lpddr4-arm2.dts"
+
+/ {
+ sound-hdmi {
+ compatible = "fsl,imx-audio-cdnhdmi";
+ model = "imx-audio-dp";
+ audio-cpu = <&sai_hdmi_tx>;
+ protocol = <1>;
+ hdmi-out;
+ };
+};
+
+&ldb1_phy {
+ status = "disabled";
+};
+
+&ldb1 {
+ status = "disabled";
+};
+
+&i2c1_lvds0 {
+ status = "disabled";
+};
+
+&hdmi {
+ compatible = "fsl,imx8qm-dp";
+ fsl,use_digpll_pclock;
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8qm-lpddr4-arm2-dp.dts b/arch/arm64/boot/dts/freescale/fsl-imx8qm-lpddr4-arm2-dp.dts
new file mode 100644
index 000000000000..c9083f7a89bb
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8qm-lpddr4-arm2-dp.dts
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2017-2018 NXP
+ *
+ * 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.
+ */
+/*
+ * HDMI only dts, disable ldb display.
+ */
+
+#include "fsl-imx8qm-lpddr4-arm2.dts"
+
+/ {
+ sound-hdmi {
+ compatible = "fsl,imx-audio-cdnhdmi";
+ model = "imx-audio-dp";
+ audio-cpu = <&sai_hdmi_tx>;
+ protocol = <1>;
+ hdmi-out;
+ };
+};
+
+&ldb1_phy {
+ status = "disabled";
+};
+
+&ldb1 {
+ status = "disabled";
+};
+
+&i2c1_lvds0 {
+ status = "disabled";
+};
+
+&irqsteer_hdmi {
+ status = "okay";
+};
+
+&hdmi {
+ compatible = "fsl,imx8qm-dp";
+ assigned-clocks = <&clk IMX8QM_HDMI_PXL_SEL>,
+ <&clk IMX8QM_HDMI_PXL_LINK_SEL>,
+ <&clk IMX8QM_HDMI_PXL_MUX_SEL>;
+ assigned-clock-parents = <&clk IMX8QM_HDMI_AV_PLL_CLK>,
+ <&clk IMX8QM_HDMI_AV_PLL_CLK>,
+ <&clk IMX8QM_HDMI_AV_PLL_CLK>;
+
+ dp-lane-mapping = <0x1b>;
+ dp-link-rate = <0x14>;
+ dp-num-lanes = <0x4>;
+
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8qm-lpddr4-arm2-dsi-rm67191.dts b/arch/arm64/boot/dts/freescale/fsl-imx8qm-lpddr4-arm2-dsi-rm67191.dts
new file mode 100644
index 000000000000..788ff2cff108
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8qm-lpddr4-arm2-dsi-rm67191.dts
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2017 NXP
+ *
+ * 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 "fsl-imx8qm-lpddr4-arm2.dts"
+
+&mipi_dsi_bridge1 {
+ status = "okay";
+
+ panel@0 {
+ compatible = "raydium,rm67191";
+ reg = <0>;
+ pinctrl-0 = <&pinctrl_mipi_dsi_0_1_en>;
+ reset-gpio = <&gpio1 7 GPIO_ACTIVE_HIGH>;
+ dsi-lanes = <4>;
+ panel-width-mm = <68>;
+ panel-height-mm = <121>;
+ port {
+ panel1_in: endpoint {
+ remote-endpoint = <&mipi_bridge1_out>;
+ };
+ };
+ };
+
+ port@2 {
+ mipi_bridge1_out: endpoint {
+ remote-endpoint = <&panel1_in>;
+ };
+ };
+};
+
+&mipi_dsi_bridge2 {
+ status = "okay";
+
+ panel@0 {
+ compatible = "raydium,rm67191";
+ reg = <0>;
+ pinctrl-0 = <&pinctrl_mipi_dsi_0_1_en>;
+ reset-gpio = <&gpio1 7 GPIO_ACTIVE_HIGH>;
+ dsi-lanes = <4>;
+ panel-width-mm = <68>;
+ panel-height-mm = <121>;
+ port {
+ panel2_in: endpoint {
+ remote-endpoint = <&mipi_bridge2_out>;
+ };
+ };
+ };
+
+ port@2 {
+ mipi_bridge2_out: endpoint {
+ remote-endpoint = <&panel2_in>;
+ };
+ };
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8qm-lpddr4-arm2-enet2-tja1100.dts b/arch/arm64/boot/dts/freescale/fsl-imx8qm-lpddr4-arm2-enet2-tja1100.dts
new file mode 100644
index 000000000000..42daa8aedb74
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8qm-lpddr4-arm2-enet2-tja1100.dts
@@ -0,0 +1,16 @@
+/*
+ * Copyright 2018 NXP
+ *
+ * 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 "fsl-imx8qm-lpddr4-arm2.dts"
+#include "fsl-imx8qm-enet2-tja1100.dtsi"
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8qm-lpddr4-arm2-hdmi-in.dts b/arch/arm64/boot/dts/freescale/fsl-imx8qm-lpddr4-arm2-hdmi-in.dts
new file mode 100644
index 000000000000..2f60845773c2
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8qm-lpddr4-arm2-hdmi-in.dts
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2018 NXP
+ *
+ * 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.
+ */
+/*
+ * HDMI only dts, disable ldb display.
+ */
+
+#include "fsl-imx8qm-lpddr4-arm2-hdmi.dts"
+
+/ {
+ sound-hdmi-rx {
+ compatible = "fsl,imx-audio-cdnhdmi";
+ model = "imx-audio-hdmi-rx";
+ audio-cpu = <&sai_hdmi_rx>;
+ protocol = <1>;
+ hdmi-in;
+ };
+};
+
+/* HDMI RX */
+&isi_0 {
+ status = "disabled";
+};
+
+&isi_1 {
+ interface = <4 0 2>; /* <Input MIPI_VCx Output>
+ Input: 0-DC0, 1-DC1, 2-MIPI CSI0, 3-MIPI CSI1, 4-HDMI, 5-MEM
+ VCx: 0-VC0, 1-VC1, 2-VC2, 3-VC3, MIPI CSI only
+ Output: 0-DC0, 1-DC1, 2-MEM */
+ status = "okay";
+};
+
+&isi_2 {
+ status = "okay";
+ fsl,chain_buf;
+};
+
+&isi_3 {
+ status = "disabled";
+};
+
+
+&mipi_csi_0 {
+ status = "disabled";
+};
+
+&i2c0_mipi_csi0 {
+ status = "disabled";
+};
+
+&hdmi_rx {
+ fsl,cec;
+ assigned-clocks = <&clk IMX8QM_HDMI_RX_HD_REF_SEL>,
+ <&clk IMX8QM_HDMI_RX_PXL_SEL>,
+ <&clk IMX8QM_HDMI_RX_HD_REF_DIV>;
+ assigned-clock-parents = <&clk IMX8QM_HDMI_RX_DIG_PLL_CLK>,
+ <&clk IMX8QM_HDMI_RX_BYPASS_CLK>;
+ assigned-clock-rates = <0>, <0>, <400000000>;
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8qm-lpddr4-arm2-hdmi.dts b/arch/arm64/boot/dts/freescale/fsl-imx8qm-lpddr4-arm2-hdmi.dts
new file mode 100644
index 000000000000..7cc8944fac60
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8qm-lpddr4-arm2-hdmi.dts
@@ -0,0 +1,107 @@
+/*
+ * Copyright 2017-2018 NXP
+ *
+ * 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.
+ */
+/*
+ * HDMI only dts, disable ldb display.
+ */
+
+#include "fsl-imx8qm-lpddr4-arm2.dts"
+
+/ {
+ sound-hdmi-tx {
+ compatible = "fsl,imx-audio-cdnhdmi";
+ model = "imx-audio-hdmi-tx";
+ audio-cpu = <&sai_hdmi_tx>;
+ constraint-rate = <48000>;
+ protocol = <1>;
+ hdmi-out;
+ };
+
+ sound-amix-sai {
+ status = "disabled";
+ };
+
+ sound-hdmi-arc {
+ compatible = "fsl,imx-audio-spdif";
+ model = "imx-hdmi-arc";
+ spdif-controller = <&spdif1>;
+ spdif-in;
+ spdif-out;
+ };
+};
+
+&ldb1_phy {
+ status = "disabled";
+};
+
+&ldb1 {
+ status = "disabled";
+};
+
+&i2c1_lvds0 {
+ status = "disabled";
+};
+
+&irqsteer_hdmi {
+ status = "okay";
+};
+
+&hdmi {
+ compatible = "fsl,imx8qm-hdmi";
+ assigned-clocks = <&clk IMX8QM_HDMI_PXL_SEL>,
+ <&clk IMX8QM_HDMI_PXL_LINK_SEL>,
+ <&clk IMX8QM_HDMI_PXL_MUX_SEL>;
+ assigned-clock-parents = <&clk IMX8QM_HDMI_AV_PLL_CLK>,
+ <&clk IMX8QM_HDMI_AV_PLL_CLK>,
+ <&clk IMX8QM_HDMI_AV_PLL_CLK>;
+ fsl,no_edid;
+ status = "okay";
+};
+
+&amix {
+ status = "disabled";
+};
+
+&sai6 {
+ status = "disabled";
+};
+
+&sai7 {
+ status = "disabled";
+};
+
+&sai_hdmi_tx {
+ assigned-clocks =<&clk IMX8QM_ACM_HDMI_TX_SAI0_MCLK_SEL>,
+ <&clk IMX8QM_AUD_PLL1_DIV>,
+ <&clk IMX8QM_AUD_ACM_AUD_PLL_CLK1_DIV>,
+ <&clk IMX8QM_AUD_ACM_AUD_REC_CLK1_DIV>,
+ <&clk IMX8QM_AUD_SAI_HDMITX0_MCLK>;
+ assigned-clock-parents = <&clk IMX8QM_AUD_ACM_AUD_PLL_CLK1_CLK>;
+ assigned-clock-rates = <0>, <768000000>, <768000000>, <768000000>, <768000000>;
+ fsl,sai-asynchronous;
+ status = "okay";
+};
+
+&sai_hdmi_rx {
+ fsl,sai-asynchronous;
+ status = "okay";
+};
+
+&spdif1 {
+ assigned-clocks =<&clk IMX8QM_AUD_PLL0_DIV>,
+ <&clk IMX8QM_AUD_ACM_AUD_PLL_CLK0_DIV>,
+ <&clk IMX8QM_AUD_ACM_AUD_REC_CLK0_DIV>;
+ assigned-clock-rates = <786432000>, <49152000>, <12288000>;
+ status = "okay";
+};
+
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8qm-lpddr4-arm2-hsic.dts b/arch/arm64/boot/dts/freescale/fsl-imx8qm-lpddr4-arm2-hsic.dts
new file mode 100644
index 000000000000..42adaf9b6c5c
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8qm-lpddr4-arm2-hsic.dts
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2017 NXP
+ *
+ * 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.
+ */
+
+/* This dts is only for verify USB HSIC function at i.MX8 Debug Board */
+
+#include "fsl-imx8qm-lpddr4-arm2.dts"
+
+/ {
+ imx8qm-pm {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_usbh1: PD_USBH1 {
+ compatible = "nxp,imx8-pd";
+ reg = <SC_R_NONE>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_usbh1_io: usbh1_io {
+ reg = <SC_R_BOARD_R2>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_usbh1>;
+ };
+ };
+ };
+};
+
+&iomuxc {
+ imx8qm-arm2 {
+ pinctrl_usb_hsic_idle: usbh1_1 {
+ fsl,pins = <
+ SC_P_USB_HSIC0_DATA_CONN_USB_HSIC0_DATA 0xc60000c5
+ SC_P_USB_HSIC0_STROBE_CONN_USB_HSIC0_STROBE 0xc60000c5
+ >;
+ };
+
+ pinctrl_usb_hsic_active: usbh1_2 {
+ fsl,pins = <
+ SC_P_USB_HSIC0_STROBE_CONN_USB_HSIC0_STROBE 0xc60000d5
+ >;
+ };
+ };
+};
+
+&usbotg1 {
+ ci-disable-lpm;
+};
+
+/*
+ * Due to USB HSIC uses the same AHB and 480M with USBOTG1,
+ * the usbotg1 must be enabled for usbh1 usage.
+ */
+&usbh1 {
+ pinctrl-names = "idle", "active";
+ pinctrl-0 = <&pinctrl_usb_hsic_idle>;
+ pinctrl-1 = <&pinctrl_usb_hsic_active>;
+ power-domains = <&pd_usbh1_io>;
+ srp-disable;
+ hnp-disable;
+ adp-disable;
+ disable-over-current;
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8qm-lpddr4-arm2-it6263-dual-channel.dts b/arch/arm64/boot/dts/freescale/fsl-imx8qm-lpddr4-arm2-it6263-dual-channel.dts
new file mode 100644
index 000000000000..2e9572b4d33b
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8qm-lpddr4-arm2-it6263-dual-channel.dts
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2017 NXP
+ *
+ * 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 "fsl-imx8qm-lpddr4-arm2.dts"
+
+&ldb1 {
+ fsl,dual-channel;
+};
+
+&i2c1_lvds0 {
+ lvds-to-hdmi-bridge@4c {
+ split-mode;
+ };
+};
+
+&ldb2 {
+ fsl,dual-channel;
+};
+
+&i2c1_lvds1 {
+ lvds-to-hdmi-bridge@4c {
+ split-mode;
+ };
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8qm-lpddr4-arm2-jdi-wuxga-lvds1-panel.dts b/arch/arm64/boot/dts/freescale/fsl-imx8qm-lpddr4-arm2-jdi-wuxga-lvds1-panel.dts
new file mode 100644
index 000000000000..39bbdad2d6f1
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8qm-lpddr4-arm2-jdi-wuxga-lvds1-panel.dts
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2017 NXP
+ *
+ * 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 "fsl-imx8qm-lpddr4-arm2.dts"
+
+/ {
+ lvds1_panel {
+ compatible = "jdi,tx26d202vm0bwa";
+ backlight = <&lvds_backlight1>;
+
+ port {
+ panel_lvds1_in: endpoint {
+ remote-endpoint = <&lvds1_out>;
+ };
+ };
+ };
+};
+
+&ldb1_phy {
+ status = "disabled";
+};
+
+&ldb1 {
+ status = "disabled";
+};
+
+&i2c1_lvds0 {
+ lvds-to-hdmi-bridge@4c {
+ status = "disabled";
+ };
+};
+
+&i2c1_lvds1 {
+ lvds-to-hdmi-bridge@4c {
+ status = "disabled";
+ };
+};
+
+&ldb2_phy {
+ status = "okay";
+};
+
+&ldb2 {
+ status = "okay";
+ fsl,dual-channel;
+
+ lvds-channel@0 {
+ fsl,data-mapping = "spwg";
+ fsl,data-width = <24>;
+ status = "okay";
+
+ port@1 {
+ reg = <1>;
+
+ lvds1_out: endpoint {
+ remote-endpoint = <&panel_lvds1_in>;
+ };
+ };
+ };
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8qm-lpddr4-arm2-lpspi-slave.dts b/arch/arm64/boot/dts/freescale/fsl-imx8qm-lpddr4-arm2-lpspi-slave.dts
new file mode 100644
index 000000000000..c38b3970bb8d
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8qm-lpddr4-arm2-lpspi-slave.dts
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2018 NXP
+ *
+ * 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 "fsl-imx8qm-lpddr4-arm2-lpspi.dts"
+
+/delete-node/&spidev0;
+
+&pinctrl_lpspi3 {
+ fsl,pins = <
+ SC_P_SPI3_SCK_DMA_SPI3_SCK 0x0600004c
+ SC_P_SPI3_SDO_DMA_SPI3_SDO 0x0600004c
+ SC_P_SPI3_SDI_DMA_SPI3_SDI 0x0600004c
+ SC_P_SPI3_CS0_DMA_SPI3_CS0 0x0600004c
+ >;
+};
+
+&lpspi3 {
+ pinctrl-0 = <&pinctrl_lpspi3>;
+ /delete-property/ cs-gpios;
+ spi-slave;
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8qm-lpddr4-arm2-lpspi.dts b/arch/arm64/boot/dts/freescale/fsl-imx8qm-lpddr4-arm2-lpspi.dts
new file mode 100644
index 000000000000..844bdda456d4
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8qm-lpddr4-arm2-lpspi.dts
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2017 NXP
+ *
+ * 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 "fsl-imx8qm-lpddr4-arm2.dts"
+
+&iomuxc {
+
+ imx8qm-arm2 {
+
+ pinctrl_lpspi0: lpspi0grp {
+ fsl,pins = <
+ SC_P_SPI0_SCK_DMA_SPI0_SCK 0x0600004c
+ SC_P_SPI0_SDO_DMA_SPI0_SDO 0x0600004c
+ SC_P_SPI0_SDI_DMA_SPI0_SDI 0x0600004c
+ >;
+ };
+
+ pinctrl_lpspi0_cs: lpspi0cs {
+ fsl,pins = <
+ SC_P_SPI0_CS0_LSIO_GPIO3_IO05 0x21
+ >;
+ };
+
+ pinctrl_lpspi3: lpspi3grp {
+ fsl,pins = <
+ SC_P_SPI3_SCK_DMA_SPI3_SCK 0x0600004c
+ SC_P_SPI3_SDO_DMA_SPI3_SDO 0x0600004c
+ SC_P_SPI3_SDI_DMA_SPI3_SDI 0x0600004c
+ SC_P_SPI3_CS0_DMA_SPI3_CS0 0x0600004c
+ >;
+ };
+
+ };
+};
+
+&lpspi0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ fsl,spi-num-chipselects = <1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lpspi0 &pinctrl_lpspi0_cs>;
+ cs-gpios = <&gpio3 5 GPIO_ACTIVE_LOW>;
+ status = "okay";
+
+ flash: at45db041e@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "atmel,at45", "atmel,dataflash";
+ spi-max-frequency = <5000000>;
+ reg = <0>;
+ };
+};
+
+&lpspi3 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ fsl,spi-num-chipselects = <1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lpspi3>;
+ status = "okay";
+
+ spidev0: spi@0 {
+ reg = <0>;
+ compatible = "rohm,dh2228fv";
+ spi-max-frequency = <30000000>;
+ };
+
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8qm-lpddr4-arm2-mqs.dts b/arch/arm64/boot/dts/freescale/fsl-imx8qm-lpddr4-arm2-mqs.dts
new file mode 100644
index 000000000000..64d0bb2f77ec
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8qm-lpddr4-arm2-mqs.dts
@@ -0,0 +1,198 @@
+/*
+ * Copyright 2017 NXP
+ *
+ * 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 "fsl-imx8qm-lpddr4-arm2.dts"
+
+/ {
+
+ leds {
+ status = "disabled";
+ };
+
+ regulators {
+
+ reg_spdif_en: regulator-spdif-en {
+ compatible = "regulator-fixed";
+ regulator-name = "spdif-en";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&pca9557_d 0 GPIO_ACTIVE_HIGH>;
+ regulator-always-on;
+ enable-active-high;
+ };
+
+ reg_wm8962: regulator-wm8962 {
+ compatible = "regulator-fixed";
+ regulator-name = "wm8962-supply";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&gpio4 12 GPIO_ACTIVE_HIGH>;
+ regulator-always-on;
+ enable-active-high;
+ };
+
+ reg_bb2: regulator-bb2 {
+ compatible = "regulator-fixed";
+ regulator-name = "bb2-supply";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&gpio1 13 GPIO_ACTIVE_HIGH>;
+ regulator-always-on;
+ enable-active-high;
+ };
+ };
+
+ sound-cs42888 {
+ status = "disabled";
+ };
+
+ sound-spdif {
+ compatible = "fsl,imx-audio-spdif";
+ model = "imx-spdif";
+ spdif-controller = <&spdif0>;
+ spdif-in;
+ spdif-out;
+ status = "disabled";
+ };
+
+ sound-mqs {
+ compatible = "fsl,imx8qm-lpddr4-arm2-mqs",
+ "fsl,imx-audio-mqs";
+ model = "mqs-audio";
+ cpu-dai = <&sai1>;
+ audio-codec = <&mqs>;
+ asrc-controller = <&asrc1>;
+ };
+
+ sound-wm8962 {
+ compatible = "fsl,imx6q-sabresd-wm8962",
+ "fsl,imx-audio-wm8962";
+ model = "wm8962-audio";
+ cpu-dai = <&sai0>;
+ audio-codec = <&wm8962>;
+ audio-routing =
+ "Headphone Jack", "HPOUTL",
+ "Headphone Jack", "HPOUTR",
+ "Ext Spk", "SPKOUTL",
+ "Ext Spk", "SPKOUTR",
+ "AMIC", "MICBIAS",
+ "IN3R", "AMIC",
+ "DMIC", "MICBIAS",
+ "DMICDAT", "DMIC",
+ "CPU-Playback", "ASRC-Playback",
+ "Playback", "CPU-Playback",
+ "ASRC-Capture", "CPU-Capture",
+ "CPU-Capture", "Capture";
+ hp-det-gpios = <&gpio5 26 1>;
+ mic-det-gpios = <&gpio5 27 1>;
+ codec-master;
+ };
+};
+
+&esai0 {
+ status = "disabled";
+};
+
+&iomuxc {
+
+ imx8qm-arm2 {
+
+ pinctrl_spdif0: spdif0grp {
+ fsl,pins = <
+ SC_P_SPDIF0_TX_AUD_SPDIF0_TX 0xc6000040
+ SC_P_SPDIF0_RX_AUD_SPDIF0_RX 0xc6000040
+ >;
+ };
+
+ pinctrl_mqs: mqsgrp {
+ fsl,pins = <
+ SC_P_SPDIF0_TX_AUD_MQS_L 0xc6000061
+ SC_P_SPDIF0_RX_AUD_MQS_R 0xc6000061
+ >;
+ };
+
+ pinctrl_sai0: sai0grp {
+ fsl,pins = <
+ SC_P_SAI1_RXC_AUD_SAI0_TXD 0xc6000060
+ SC_P_SAI1_RXFS_AUD_SAI0_RXD 0xc6000040
+ SC_P_SAI1_TXC_AUD_SAI0_TXC 0xc6000040
+ SC_P_SPI2_CS1_AUD_SAI0_TXFS 0xc6000040
+
+ SC_P_USDHC2_CD_B_LSIO_GPIO4_IO12 0xc6000040
+ SC_P_USDHC2_DATA0_LSIO_GPIO5_IO26 0xc6000040
+ SC_P_USDHC2_DATA1_LSIO_GPIO5_IO27 0xc6000040
+ SC_P_LVDS1_I2C0_SDA_LSIO_GPIO1_IO13 0xc6000040
+ SC_P_MCLK_OUT0_AUD_ACM_MCLK_OUT0 0xc6000040
+ >;
+ };
+ };
+};
+
+&i2c0 {
+
+ wm8962: wm8962@1a {
+ compatible = "wlf,wm8962";
+ reg = <0x1a>;
+ clocks = <&clk IMX8QM_AUD_MCLKOUT0>;
+ DCVDD-supply = <&reg_wm8962>;
+ DBVDD-supply = <&reg_wm8962>;
+ AVDD-supply = <&reg_wm8962>;
+ CPVDD-supply = <&reg_wm8962>;
+ MICVDD-supply = <&reg_wm8962>;
+ PLLVDD-supply = <&reg_wm8962>;
+ SPKVDD1-supply = <&reg_wm8962>;
+ SPKVDD2-supply = <&reg_wm8962>;
+ gpio-cfg = <
+ 0x0000 /* 0:Default */
+ 0x0000 /* 1:Default */
+ 0x0013 /* 2:FN_DMICCLK */
+ 0x0000 /* 3:Default */
+ 0x8014 /* 4:FN_DMICCDAT */
+ 0x0000 /* 5:Default */
+ >;
+ amic-mono;
+ power-domains = <&pd_mclk_out0>;
+ };
+};
+
+
+&mqs {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_mqs>;
+ status = "okay";
+};
+
+&spdif0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_spdif0>;
+ status = "disabled";
+};
+
+&sai1 {
+ assigned-clocks =<&clk IMX8QM_AUD_PLL0_DIV>,
+ <&clk IMX8QM_AUD_ACM_AUD_PLL_CLK0_DIV>,
+ <&clk IMX8QM_AUD_ACM_AUD_REC_CLK0_DIV>;
+ assigned-clock-rates = <786432000>, <49152000>, <24576000>;
+ status = "okay";
+};
+
+&sai0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_sai0>;
+ assigned-clocks =<&clk IMX8QM_AUD_PLL0_DIV>,
+ <&clk IMX8QM_AUD_ACM_AUD_PLL_CLK0_DIV>,
+ <&clk IMX8QM_AUD_ACM_AUD_REC_CLK0_DIV>;
+ assigned-clock-rates = <786432000>, <49152000>, <24576000>;
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8qm-lpddr4-arm2-spdif.dts b/arch/arm64/boot/dts/freescale/fsl-imx8qm-lpddr4-arm2-spdif.dts
new file mode 100644
index 000000000000..8125de8f0579
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8qm-lpddr4-arm2-spdif.dts
@@ -0,0 +1,205 @@
+/*
+ * Copyright 2017 NXP
+ *
+ * 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 "fsl-imx8qm-lpddr4-arm2.dts"
+
+/ {
+
+ leds {
+ status = "disabled";
+ };
+
+ regulators {
+
+ reg_spdif_en: regulator-spdif-en {
+ compatible = "regulator-fixed";
+ regulator-name = "spdif-en";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&pca9557_d 0 GPIO_ACTIVE_HIGH>;
+ regulator-always-on;
+ enable-active-high;
+ };
+
+ reg_wm8962: regulator-wm8962 {
+ compatible = "regulator-fixed";
+ regulator-name = "wm8962-supply";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&gpio4 12 GPIO_ACTIVE_HIGH>;
+ regulator-always-on;
+ enable-active-high;
+ };
+
+ reg_bb2: regulator-bb2 {
+ compatible = "regulator-fixed";
+ regulator-name = "bb2-supply";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&gpio1 13 GPIO_ACTIVE_HIGH>;
+ regulator-always-on;
+ enable-active-high;
+ };
+ };
+
+ sound-cs42888 {
+ status = "disabled";
+ };
+
+ sound-spdif {
+ compatible = "fsl,imx-audio-spdif";
+ model = "imx-spdif";
+ spdif-controller = <&spdif0>;
+ spdif-in;
+ spdif-out;
+ };
+
+ sound-mqs {
+ compatible = "fsl,imx8qm-lpddr4-arm2-mqs",
+ "fsl,imx-audio-mqs";
+ model = "mqs-audio";
+ cpu-dai = <&sai1>;
+ audio-codec = <&mqs>;
+ status = "disabled";
+ };
+
+ sound-wm8962 {
+ compatible = "fsl,imx6q-sabresd-wm8962",
+ "fsl,imx-audio-wm8962";
+ model = "wm8962-audio";
+ cpu-dai = <&sai0>;
+ audio-codec = <&wm8962>;
+ audio-routing =
+ "Headphone Jack", "HPOUTL",
+ "Headphone Jack", "HPOUTR",
+ "Ext Spk", "SPKOUTL",
+ "Ext Spk", "SPKOUTR",
+ "AMIC", "MICBIAS",
+ "IN3R", "AMIC",
+ "DMIC", "MICBIAS",
+ "DMICDAT", "DMIC",
+ "CPU-Playback", "ASRC-Playback",
+ "Playback", "CPU-Playback",
+ "ASRC-Capture", "CPU-Capture",
+ "CPU-Capture", "Capture";
+ hp-det-gpios = <&gpio5 26 1>;
+ mic-det-gpios = <&gpio5 27 1>;
+ codec-master;
+ };
+};
+
+&esai0 {
+ status = "disabled";
+};
+
+&iomuxc {
+
+ imx8qm-arm2 {
+
+ pinctrl_spdif0: spdif0grp {
+ fsl,pins = <
+ SC_P_SPDIF0_TX_AUD_SPDIF0_TX 0xc6000040
+ SC_P_SPDIF0_RX_AUD_SPDIF0_RX 0xc6000040
+ >;
+ };
+
+ pinctrl_mqs: mqsgrp {
+ fsl,pins = <
+ SC_P_SPDIF0_TX_AUD_MQS_L 0xc6000061
+ SC_P_SPDIF0_RX_AUD_MQS_R 0xc6000061
+ >;
+ };
+
+ pinctrl_sai0: sai0grp {
+ fsl,pins = <
+ SC_P_SAI1_RXC_AUD_SAI0_TXD 0xc6000060
+ SC_P_SAI1_RXFS_AUD_SAI0_RXD 0xc6000040
+ SC_P_SAI1_TXC_AUD_SAI0_TXC 0xc6000040
+ SC_P_SPI2_CS1_AUD_SAI0_TXFS 0xc6000040
+
+ SC_P_USDHC2_CD_B_LSIO_GPIO4_IO12 0xc6000040
+ SC_P_USDHC2_DATA0_LSIO_GPIO5_IO26 0xc6000040
+ SC_P_USDHC2_DATA1_LSIO_GPIO5_IO27 0xc6000040
+ SC_P_LVDS1_I2C0_SDA_LSIO_GPIO1_IO13 0xc6000040
+ SC_P_MCLK_OUT0_AUD_ACM_MCLK_OUT0 0xc6000040
+ >;
+ };
+ };
+};
+
+&esai0 {
+ status = "disabled";
+};
+
+&i2c0 {
+
+ wm8962: wm8962@1a {
+ compatible = "wlf,wm8962";
+ reg = <0x1a>;
+ clocks = <&clk IMX8QM_AUD_MCLKOUT0>;
+ DCVDD-supply = <&reg_wm8962>;
+ DBVDD-supply = <&reg_wm8962>;
+ AVDD-supply = <&reg_wm8962>;
+ CPVDD-supply = <&reg_wm8962>;
+ MICVDD-supply = <&reg_wm8962>;
+ PLLVDD-supply = <&reg_wm8962>;
+ SPKVDD1-supply = <&reg_wm8962>;
+ SPKVDD2-supply = <&reg_wm8962>;
+ gpio-cfg = <
+ 0x0000 /* 0:Default */
+ 0x0000 /* 1:Default */
+ 0x0013 /* 2:FN_DMICCLK */
+ 0x0000 /* 3:Default */
+ 0x8014 /* 4:FN_DMICCDAT */
+ 0x0000 /* 5:Default */
+ >;
+ amic-mono;
+ power-domains = <&pd_mclk_out0>;
+ };
+};
+
+
+&mqs {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_mqs>;
+ status = "disabled";
+};
+
+&spdif0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_spdif0>;
+ assigned-clocks =<&clk IMX8QM_AUD_PLL0_DIV>,
+ <&clk IMX8QM_AUD_ACM_AUD_PLL_CLK0_DIV>,
+ <&clk IMX8QM_AUD_ACM_AUD_REC_CLK0_DIV>;
+ assigned-clock-rates = <786432000>, <49152000>, <24576000>;
+ status = "okay";
+};
+
+&sai1 {
+ assigned-clocks =<&clk IMX8QM_AUD_PLL0_DIV>,
+ <&clk IMX8QM_AUD_ACM_AUD_PLL_CLK0_DIV>,
+ <&clk IMX8QM_AUD_ACM_AUD_REC_CLK0_DIV>;
+ assigned-clock-rates = <786432000>, <49152000>, <24576000>;
+ status = "okay";
+};
+
+&sai0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_sai0>;
+ assigned-clocks =<&clk IMX8QM_AUD_PLL0_DIV>,
+ <&clk IMX8QM_AUD_ACM_AUD_PLL_CLK0_DIV>,
+ <&clk IMX8QM_AUD_ACM_AUD_REC_CLK0_DIV>;
+ assigned-clock-rates = <786432000>, <49152000>, <24576000>;
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8qm-lpddr4-arm2-usb3.dts b/arch/arm64/boot/dts/freescale/fsl-imx8qm-lpddr4-arm2-usb3.dts
new file mode 100644
index 000000000000..24f110d17cad
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8qm-lpddr4-arm2-usb3.dts
@@ -0,0 +1,113 @@
+/*
+ * Copyright 2017 NXP
+ *
+ * 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.
+ */
+
+/* This dts is only for verify USB3 Type-C Connector */
+
+#include "fsl-imx8qm-lpddr4-arm2.dts"
+
+/ {
+ imx8qm-pm {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_ptn5150: PD_PTN5150 {
+ compatible = "nxp,imx8-pd";
+ reg = <SC_R_NONE>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_ptn5150_io: ptn5150_io {
+ reg = <SC_R_BOARD_R0>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_ptn5150>;
+ };
+ };
+ };
+};
+
+
+
+&iomuxc {
+ imx8qm-arm2 {
+ pinctrl_lpi2c1: lpi2c1grp {
+ fsl,pins = <
+ SC_P_USB_SS3_TC1_DMA_I2C1_SCL 0xc600004c
+ SC_P_USB_SS3_TC3_DMA_I2C1_SDA 0xc600004c
+ >;
+ };
+
+ pinctrl_ptn5150: ptn5150 {
+ fsl,pins = <
+ SC_P_SIM0_CLK_LSIO_GPIO0_IO00 0x00000021
+ >;
+ };
+ };
+};
+
+&usbotg3 {
+ dr_mode = "otg";
+ extcon = <&typec_ptn5150>;
+ status = "okay";
+};
+
+&i2c1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lpi2c1>;
+ status = "okay";
+
+ typec_ptn5150: typec@3d {
+ compatible = "nxp,ptn5150";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ptn5150>;
+ reg = <0x3d>;
+ power-domains = <&pd_ptn5150_io>;
+ connect-gpios = <&gpio0 0 GPIO_ACTIVE_HIGH>;
+ };
+
+ pca9557_a: gpio@18 {
+ status = "disabled";
+ };
+
+ pca9557_b: gpio@19 {
+ status = "disabled";
+ };
+
+ pca9557_c: gpio@1b {
+ status = "disabled";
+ };
+
+ pca9557_d: gpio@1f {
+ status = "disabled";
+ };
+
+ fxas2100x@20 {
+ status = "disabled";
+ };
+
+ fxos8700@1d {
+ status = "disabled";
+ };
+
+ isl29023@44 {
+ status = "disabled";
+ };
+
+ mpl3115@60 {
+ status = "disabled";
+ };
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8qm-lpddr4-arm2.dts b/arch/arm64/boot/dts/freescale/fsl-imx8qm-lpddr4-arm2.dts
new file mode 100644
index 000000000000..329e7953c659
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8qm-lpddr4-arm2.dts
@@ -0,0 +1,34 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2017~2018 NXP
+ *
+ * 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.
+ */
+
+/dts-v1/;
+
+#include "fsl-imx8qm.dtsi"
+#include "fsl-imx8q-arm2.dtsi"
+
+/ {
+ model = "Freescale i.MX8QM LPDDR4 ARM2";
+ compatible = "fsl,imx8qm-lpddr4-arm2", "fsl,imx8qm";
+};
+
+&vpu_decoder {
+ core_type = <2>;
+ status = "okay";
+};
+
+&vpu_encoder {
+ status = "okay";
+};
+
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8qm-lpddr4-arm2_ca53.dts b/arch/arm64/boot/dts/freescale/fsl-imx8qm-lpddr4-arm2_ca53.dts
new file mode 100644
index 000000000000..9c42d98899b0
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8qm-lpddr4-arm2_ca53.dts
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017 NXP
+ *
+ * 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 "fsl-imx8qm-lpddr4-arm2.dts"
+
+&A72_0 {
+ device_type = "";
+};
+
+&A72_1 {
+ device_type = "";
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8qm-lpddr4-arm2_ca72.dts b/arch/arm64/boot/dts/freescale/fsl-imx8qm-lpddr4-arm2_ca72.dts
new file mode 100644
index 000000000000..55e2e8c51637
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8qm-lpddr4-arm2_ca72.dts
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017 NXP
+ *
+ * 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 "fsl-imx8qm-lpddr4-arm2.dts"
+
+&A53_0 {
+ device_type = "";
+};
+
+&A53_1 {
+ device_type = "";
+};
+
+&A53_2 {
+ device_type = "";
+};
+
+&A53_3 {
+ device_type = "";
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8qm-mek-dom0-dpu2.dts b/arch/arm64/boot/dts/freescale/fsl-imx8qm-mek-dom0-dpu2.dts
new file mode 100644
index 000000000000..492c453db02c
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8qm-mek-dom0-dpu2.dts
@@ -0,0 +1,784 @@
+/*
+ * Copyright 2018 NXP
+ *
+ * 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.
+ */
+
+/dts-v1/;
+
+/memreserve/ 0x84000000 0x4000000;
+/memreserve/ 0x90000000 0x400000;
+/memreserve/ 0x90400000 0x2000000;
+/memreserve/ 0x92400000 0x2000000;
+/memreserve/ 0x94400000 0x1800000;
+
+#include "fsl-imx8qm-mek.dtsi"
+#include "fsl-imx8qm-xen.dtsi"
+
+/ {
+ model = "Freescale i.MX8QM MEK DOM0";
+ compatible = "fsl,imx8qm-mek", "fsl,imx8qm";
+
+ chosen {
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ /* Could be updated by U-Boot */
+ module@0 {
+ bootargs = "earlycon=xen console=hvc0 loglevel=8 root=/dev/mmcblk1p2 rw rootwait";
+ compatible = "xen,linux-zimage", "xen,multiboot-module";
+ reg = <0x00000000 0x80a00000 0x00000000 0xf93a00>;
+ };
+ };
+
+ domu {
+ /*
+ * There are 5 MUs, 0A is used by Dom0, 1A is used
+ * by ATF, so for DomU, 2A/3A/4A could be used.
+ * SC_R_MU_0A
+ * SC_R_MU_1A
+ * SC_R_MU_2A
+ * SC_R_MU_3A
+ * SC_R_MU_4A
+ * The rsrcs and pads will be configured by uboot scu_rm cmd
+ */
+ #address-cells = <1>;
+ #size-cells = <0>;
+ doma {
+ compatible = "xen,domu";
+ /*
+ * The name entry in VM configuration file
+ * needs to be same as here.
+ */
+ domain_name = "DomU";
+ /*
+ * The reg property will be updated by U-Boot to
+ * reflect the partition id.
+ */
+ reg = <0>;
+ init_on_rsrcs = <
+ SC_R_MU_2A
+ >;
+ rsrcs = <
+ SC_R_MU_6A
+ SC_R_GPU_0_PID0
+ SC_R_GPU_0_PID1
+ SC_R_GPU_0_PID2
+ SC_R_GPU_0_PID3
+ SC_R_LVDS_0
+ SC_R_LVDS_0_I2C_0
+ SC_R_LVDS_0_PWM_0
+ SC_R_DC_0
+ SC_R_DC_0_BLIT0
+ SC_R_DC_0_BLIT1
+ SC_R_DC_0_BLIT2
+ SC_R_DC_0_BLIT_OUT
+ SC_R_UNUSED9
+ SC_R_UNUSED10
+ SC_R_DC_0_WARP
+ SC_R_UNUSED11
+ SC_R_UNUSED12
+ SC_R_DC_0_VIDEO0
+ SC_R_DC_0_VIDEO1
+ SC_R_DC_0_FRAC0
+ SC_R_UNUSED13
+ SC_R_DC_0_PLL_0
+ SC_R_DC_0_PLL_1
+ SC_R_MIPI_0
+ SC_R_MIPI_0_I2C_0
+ SC_R_MIPI_0_I2C_1
+ SC_R_MIPI_0_PWM_0
+ SC_R_HDMI
+ SC_R_HDMI_PLL_0
+ SC_R_HDMI_PLL_1
+ SC_R_HDMI_I2C_0
+ SC_R_HDMI_I2S
+ SC_R_HDMI_RX
+ SC_R_SDHC_0
+ SC_R_USB_0
+ SC_R_USB_0_PHY
+ SC_R_UART_1
+ SC_R_DMA_0_CH14
+ SC_R_DMA_0_CH15
+ SC_R_MU_2A
+ /* pcie */
+ SC_R_PCIE_B
+ SC_R_PCIE_A
+ SC_R_SERDES_0
+ SC_R_HSIO_GPIO
+ /*vpu*/
+ SC_R_VPU
+ SC_R_VPU_PID0
+ SC_R_VPU_PID1
+ SC_R_VPU_PID2
+ SC_R_VPU_PID3
+ SC_R_VPU_PID4
+ SC_R_VPU_PID5
+ SC_R_VPU_PID6
+ SC_R_VPU_PID7
+ SC_R_VPU_DEC_0
+ SC_R_VPU_ENC_0
+ SC_R_VPU_ENC_1
+ SC_R_VPU_TS_0
+ SC_R_VPU_MU_0
+ SC_R_VPU_MU_1
+ SC_R_VPU_MU_2
+ SC_R_VPU_MU_3
+ /* crypto */
+ SC_R_CAAM_JR2
+ SC_R_CAAM_JR2_OUT
+ SC_R_CAAM_JR3
+ SC_R_CAAM_JR3_OUT
+ /* Camera */
+ SC_R_ISI_CH0
+ SC_R_ISI_CH1
+ SC_R_ISI_CH2
+ SC_R_ISI_CH3
+ SC_R_MIPI_0
+ SC_R_MIPI_0_PWM_0
+ SC_R_MIPI_0_I2C_0
+ SC_R_MIPI_0_I2C_1
+ SC_R_CSI_0
+ SC_R_CSI_0_PWM_0
+ SC_R_CSI_0_I2C_0
+ /* usbotg3 */
+ SC_R_USB_2
+ SC_R_USB_2_PHY
+ >;
+ pads = <
+ /* i2c1_lvds1 */
+ SC_P_LVDS1_I2C1_SCL
+ SC_P_LVDS1_I2C1_SDA
+ /* emmc */
+ SC_P_EMMC0_CLK
+ SC_P_EMMC0_CMD
+ SC_P_EMMC0_DATA0
+ SC_P_EMMC0_DATA1
+ SC_P_EMMC0_DATA2
+ SC_P_EMMC0_DATA3
+ SC_P_EMMC0_DATA4
+ SC_P_EMMC0_DATA5
+ SC_P_EMMC0_DATA6
+ SC_P_EMMC0_DATA7
+ SC_P_EMMC0_STROBE
+ SC_P_EMMC0_RESET_B
+ /* usb otg */
+ SC_P_USB_SS3_TC0
+ /* uart1 */
+ SC_P_UART1_RX
+ SC_P_UART1_TX
+ SC_P_UART1_CTS_B
+ SC_P_UART1_RTS_B
+ SC_P_QSPI1A_DQS
+ /* pciea */
+ SC_P_PCIE_CTRL0_CLKREQ_B
+ SC_P_PCIE_CTRL0_WAKE_B
+ SC_P_PCIE_CTRL0_PERST_B
+ SC_P_LVDS1_I2C0_SDA
+ SC_P_USDHC2_RESET_B
+ /*usbotgs typec */
+ SC_P_QSPI1A_SS0_B
+ SC_P_USB_SS3_TC3
+ SC_P_QSPI1A_DATA0
+ /* isl29023 */
+ SC_P_USDHC2_WP
+
+ >;
+ gpios = <&gpio1 13 GPIO_ACTIVE_LOW>,
+ <&gpio1 27 GPIO_ACTIVE_LOW>,
+ <&gpio4 6 GPIO_ACTIVE_LOW>,
+ <&gpio4 9 GPIO_ACTIVE_LOW>,
+ <&gpio4 11 GPIO_ACTIVE_HIGH>,
+ <&gpio4 19 GPIO_ACTIVE_HIGH>,
+ <&gpio4 26 GPIO_ACTIVE_HIGH>,
+ <&gpio4 27 GPIO_ACTIVE_LOW>,
+ <&gpio4 29 GPIO_ACTIVE_LOW>;
+ };
+ };
+
+ reserved-memory {
+ /* global autoconfigured region for contiguous allocations */
+ linux,cma {
+ compatible = "shared-dma-pool";
+ reusable;
+ size = <0 0x28000000>;
+ alloc-ranges = <0 0xa0000000 0 0x40000000>;
+ linux,cma-default;
+ };
+ };
+
+ display-subsystem {
+ compatible = "fsl,imx-display-subsystem";
+ ports = <&dpu2_disp0>, <&dpu2_disp1>;
+ };
+
+ /* Passthrough to domu */
+ mu2: mu@5d1d0000 {
+ compatible = "fsl,imx8-mu";
+ reg = <0x0 0x5d1d0000 0x0 0x10000>;
+ interrupts = <GIC_SPI 178 IRQ_TYPE_LEVEL_HIGH>;
+ fsl,scu_ap_mu_id = <0>;
+ xen,passthrough;
+ status = "disabled";
+ };
+
+ cm41: cm41@1 {
+ fsl,sc_rsrc_id = <SC_R_M4_1_PID0>,
+ <SC_R_M4_1_PID1>,
+ <SC_R_M4_1_PID2>,
+ <SC_R_M4_1_PID3>,
+ <SC_R_M4_1_PID4>;
+ #stream-id-cells = <1>;
+ iommus = <&smmu>;
+ xen,passthrough;
+ };
+
+ irqsteer_cm41: irqsteer_cm41@0x51080000 {
+ reg = <0x0 0x51080000 0x0 0x10000>;
+ xen,passthrough;
+ };
+
+ mu_rpmsg1_b: mu_rpmsg1_b@0x5d2a0000 {
+ reg = <0x0 0x5d2a0000 0x0 0x10000>;
+ xen,passthrough;
+ };
+
+ decoder_boot_mem: decoder_boot_mem@0x84000000 {
+ xen,passthrough;
+ reg = <0 0x84000000 0 0x2000000>;
+ };
+
+ encoder_boot_mem: encoder_boot_mem@0x86000000 {
+ xen,passthrough;
+ reg = <0 0x86000000 0 0x2000000>;
+ };
+
+ rpmsg_reserved_mem: rpmsg_reserved_mem@90000000 {
+ reg = <0x0 0x90000000 0x0 0x400000>;
+ xen,passthrough;
+ };
+
+ decoder_rpc_mem: decoder_rpc_mem@0x90400000 {
+ xen,passthrough;
+ reg = <0 0x90400000 0 0x1000000>;
+ };
+
+ encoder_rpc_mem: encoder_rpc_mem@0x91400000 {
+ xen,passthrough;
+ reg = <0 0x91400000 0 0x1000000>;
+ };
+ encoder_reserved_mem: encoder_reserved_mem@0x94400000 {
+ xen,passthrough;
+ reg = <0 0x94400000 0 0x800000>;
+ };
+
+ decoder_str_mem: str_mem@0x94400000 {
+ xen,passthrough;
+ reg = <0 0x94400000 0 0x1800000>;
+ };
+
+ gpio4_dummy: gpio4_dummy@0{
+ /* Passthrough gpio4 interrupt to DomU */
+ interrupts = <GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>;
+ xen,passthrough;
+ };
+};
+
+&mu_rpmsg1 {
+ xen,passthrough;
+};
+
+&rpmsg1 {
+ /* Let xen not create mapping form dom0 */
+ /delete-property/ reg;
+ status = "disabled";
+};
+
+&mu_6_lpcg {
+ xen,passthrough;
+};
+
+&mu_6_lpcg_b {
+ xen,passthrough;
+};
+
+&mu_7_lpcg_b {
+ xen,passthrough;
+};
+
+&usbotg1_lpcg {
+ xen,passthrough;
+};
+
+&sdhc1_lpcg {
+ xen,passthrough;
+};
+
+&lpuart1 {
+ xen,passthrough;
+};
+
+&lpuart1_lpcg {
+ xen,passthrough;
+};
+
+/*
+ * DomU CM41 use this, but DomU OS not need this,
+ * because smmu is enabled for CM41, so need to
+ *create the lpuart2 mapping in SMMU
+ */
+&lpuart2 {
+ xen,passthrough;
+};
+
+&lpuart2_lpcg {
+ xen,passthrough;
+};
+
+&di_lvds0_lpcg {
+ xen,passthrough;
+};
+
+&dc_0_lpcg {
+ xen,passthrough;
+};
+
+&edma01 {
+ #stream-id-cells = <1>;
+ xen,passthrough;
+ fsl,sc_rsrc_id = <SC_R_DMA_0_CH14>,
+ <SC_R_DMA_0_CH15>;
+};
+
+/*
+ * SMMU, for simplity, we put all all the resources needs to programmed
+ * for VPU under vpu_decoder node, then in cfg file only add vpu_decoder
+ * in dt_dev is enough.
+ */
+&smmu {
+ mmu-masters = <&dpu1 0x13>, <&gpu_3d0 0x15>,
+ <&usdhc1 0x12>, <&usbotg1 0x11>,
+ <&edma01 0x10>, <&cm41 0x09>, <&pciea 0x08>,
+ <&vpu_decoder 0x7>, <&crypto 0x6>, <&isi_0 0x5>,
+ <&usbotg3 0x4>, <&hdmi 0x3>;
+};
+
+&lvds_region1 {
+ xen,passthrough;
+};
+
+&irqsteer_lvds0 {
+ xen,passthrough;
+};
+
+&i2c1_lvds0 {
+ xen,passthrough;
+};
+
+&ldb1_phy {
+ xen,passthrough;
+};
+
+&ldb1 {
+ xen,passthrough;
+};
+
+&dpu1_intsteer {
+ xen,passthrough;
+};
+
+&dpu1 {
+ xen,passthrough;
+ #stream-id-cells = <1>;
+ iommus = <&smmu>;
+};
+
+&pixel_combiner1 {
+ xen,passthrough;
+};
+
+&prg1 {
+ xen,passthrough;
+};
+
+&prg2 {
+ xen,passthrough;
+};
+
+&prg3 {
+ xen,passthrough;
+};
+
+&prg4 {
+ xen,passthrough;
+};
+
+&prg5 {
+ xen,passthrough;
+};
+
+&prg6 {
+ xen,passthrough;
+};
+
+&prg7 {
+ xen,passthrough;
+};
+
+&prg8 {
+ xen,passthrough;
+};
+
+&prg9 {
+ xen,passthrough;
+};
+
+&dpr1_channel1 {
+ xen,passthrough;
+};
+
+&dpr1_channel2 {
+ xen,passthrough;
+};
+
+&dpr1_channel3 {
+ xen,passthrough;
+};
+
+&dpr2_channel1 {
+ xen,passthrough;
+};
+
+&dpr2_channel2 {
+ xen,passthrough;
+};
+
+&dpr2_channel3 {
+ xen,passthrough;
+};
+
+/* GPU */
+&pd_gpu0 {
+ xen,passthrough;
+};
+
+&gpu_3d0 {
+ xen,passthrough;
+ #stream-id-cells = <1>;
+ iommus = <&smmu>;
+};
+
+&imx8_gpu_ss {
+ cores = <&gpu_3d1>;
+ /delete-property/ reg;
+ /delete-property/ reg-names;
+};
+
+&sata {
+ status = "disabled";
+};
+
+&usdhc1 {
+ xen,passthrough;
+ #stream-id-cells = <1>;
+ iommus = <&smmu>;
+};
+
+&usbotg1 {
+ /* Hack reg */
+ reg = <0x0 0x5b0d0000 0x0 0x1000>;
+ xen,passthrough;
+ #stream-id-cells = <1>;
+ iommus = <&smmu>;
+};
+
+&usbmisc1 {
+ /* Hack */
+ /delete-property/ reg;
+ status = "disabled";
+};
+
+&usbphy1 {
+ reg = <0x0 0x5b100000 0x0 0x1000>;
+ xen,passthrough;
+};
+
+&hsio {
+ xen,passthrough;
+};
+
+&hsio_pcie_x2_lpcg {
+ xen,passthrough;
+};
+
+&hsio_phy_x2_lpcg {
+ xen,passthrough;
+};
+
+&hsio_pcie_x2_crr2_lpcg {
+ xen,passthrough;
+};
+
+&hsio_pcie_x1_lpcg {
+ xen,passthrough;
+};
+
+&pciea {
+ #stream-id-cells = <1>;
+ iommus = <&smmu>;
+ xen,passthrough;
+ fsl,sc_rsrc_id = <SC_R_PCIE_A>;
+};
+
+&pcieb {
+ xen,passthrough;
+};
+
+&gpio1 {
+ xen,shared;
+};
+
+&gpt0 {
+ /delete-property/ interrupts;
+ status = "disabled";
+};
+
+&gpio4 {
+ /*
+ * Use GPT0 interrupt for hack
+ * This could be removed when interrupt sharing be supported.
+ */
+ interrupts = <GIC_SPI 80 IRQ_TYPE_LEVEL_HIGH>;
+ xen,domu-irq;
+ xen,shared;
+};
+
+&dsp {
+ xen,passthrough;
+};
+
+&mu_m0 {
+ xen,passthrough;
+};
+
+&mu1_m0 {
+ xen,passthrough;
+};
+
+&mu2_m0 {
+ xen,passthrough;
+};
+
+&vpu_decoder {
+ #stream-id-cells = <1>;
+ iommus = <&smmu>;
+ xen,passthrough;
+ fsl,sc_rsrc_id = <SC_R_VPU>,
+ <SC_R_VPU_PID0>,
+ <SC_R_VPU_PID1>,
+ <SC_R_VPU_PID2>,
+ <SC_R_VPU_PID3>,
+ <SC_R_VPU_PID4>,
+ <SC_R_VPU_PID5>,
+ <SC_R_VPU_PID6>,
+ <SC_R_VPU_PID7>,
+ <SC_R_VPU_DEC_0>,
+ <SC_R_VPU_ENC_0>,
+ <SC_R_VPU_ENC_1>,
+ <SC_R_VPU_TS_0>,
+ <SC_R_VPU_MU_0>,
+ <SC_R_VPU_MU_1>,
+ <SC_R_VPU_MU_2>,
+ <SC_R_VPU_MU_3>;
+};
+
+&vpu_decoder_csr {
+ xen,passthrough;
+};
+
+&vpu_encoder {
+ iommus = <&smmu>;
+ #stream-id-cells = <1>;
+ xen,passthrough;
+};
+
+&crypto {
+ xen,passthrough;
+ iommus = <&smmu>;
+ #stream-id-cells = <1>;
+ /* JR1 is not used by Linux */
+ fsl,sc_rsrc_id = <SC_R_CAAM_JR2>, <SC_R_CAAM_JR2_OUT>,
+ <SC_R_CAAM_JR3>, <SC_R_CAAM_JR3_OUT>;
+};
+
+&sec_jr2 {
+ xen,passthrough;
+};
+
+&sec_jr3 {
+ xen,passthrough;
+};
+
+&caam_sm {
+ xen,passthrough;
+};
+
+&i2c0 {
+ isl29023@44 {
+ xen,passthrough;
+ };
+
+ fxos8700@1e {
+ xen,passthrough;
+ };
+
+ fxas2100x@20 {
+ xen,passthrough;
+ };
+
+ mpl3115@60 {
+ xen,passthrough;
+ };
+
+ typec_ptn5110: typec@50 {
+ xen,passthrough;
+ };
+};
+
+/* Camera */
+&img_pdma_0_lpcg {
+ xen,passthrough;
+};
+
+&img_pdma_1_lpcg {
+ xen,passthrough;
+};
+
+&img_pdma_2_lpcg {
+ xen,passthrough;
+};
+
+&img_pdma_3_lpcg {
+ xen,passthrough;
+};
+
+&mipi_csi_0_lpcg {
+ xen,passthrough;
+};
+
+&img_pxl_link_csi0_lpcg {
+ xen,passthrough;
+};
+
+&gpio0_mipi_csi0 {
+ xen,passthrough;
+};
+
+&irqsteer_csi0 {
+ xen,passthrough;
+};
+
+&isi_0 {
+ xen,passthrough;
+ #stream-id-cells = <1>;
+ iommus = <&smmu>;
+ fsl,sc_rsrc_id = <SC_R_ISI_CH0>,
+ <SC_R_ISI_CH1>,
+ <SC_R_ISI_CH2>,
+ <SC_R_ISI_CH3>;
+};
+
+&isi_1 {
+ xen,passthrough;
+};
+
+&isi_2 {
+ xen,passthrough;
+};
+
+&isi_3 {
+ xen,passthrough;
+};
+
+&mipi_csi_0 {
+ xen,passthrough;
+};
+
+&i2c0_mipi_csi0 {
+ xen,passthrough;
+};
+
+&isi_4 {
+ status = "okay";
+};
+
+&isi_5 {
+ status = "okay";
+};
+
+&isi_6 {
+ status = "okay";
+};
+
+&isi_7 {
+ status = "okay";
+};
+
+&mipi_csi_1 {
+ status = "okay";
+};
+
+&i2c0_mipi_csi1 {
+ status = "okay";
+};
+
+&usbotg3_lpcg {
+ xen,passthrough;
+};
+
+&usbotg3 {
+ xen,passthrough;
+ #stream-id-cells = <1>;
+ iommus = <&smmu>;
+};
+
+/* hdmi */
+&hdmi {
+ xen,passthrough;
+ #stream-id-cells = <1>;
+ iommus = <&smmu>;
+ fsl,sc_rsrc_id = <SC_R_HDMI>,
+ <SC_R_HDMI_RX>;
+};
+
+&hdmi_rx {
+ xen,passthrough;
+};
+
+&irqsteer_hdmi {
+ xen,passthrough;
+};
+
+&irqsteer_hdmi_rx {
+ xen,passthrough;
+};
+
+&i2c0_hdmi {
+ xen,passthrough;
+};
+
+&sai_hdmi_rx {
+ xen,passthrough;
+};
+
+&sai_hdmi_tx {
+ xen,passthrough;
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8qm-mek-dom0.dts b/arch/arm64/boot/dts/freescale/fsl-imx8qm-mek-dom0.dts
new file mode 100644
index 000000000000..d23e7d0df165
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8qm-mek-dom0.dts
@@ -0,0 +1,929 @@
+/*
+ * Copyright 2018-2019 NXP
+ *
+ * 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.
+ */
+
+/dts-v1/;
+
+/memreserve/ 0x84000000 0x2000000;
+/memreserve/ 0x86000000 0x400000;
+/memreserve/ 0x90000000 0x400000;
+/memreserve/ 0x90400000 0x1C00000;
+/memreserve/ 0x92000000 0x200000;
+/memreserve/ 0x92400000 0x2000000;
+
+#include "fsl-imx8qm-mek.dtsi"
+#include "fsl-imx8qm-xen.dtsi"
+
+/ {
+ model = "Freescale i.MX8QM MEK DOM0";
+ compatible = "fsl,imx8qm-mek", "fsl,imx8qm";
+
+ chosen {
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ /* Could be updated by U-Boot */
+ module@0 {
+ bootargs = "earlycon=xen console=hvc0 loglevel=8 root=/dev/mmcblk1p2 rw rootwait";
+ compatible = "xen,linux-zimage", "xen,multiboot-module";
+ reg = <0x00000000 0x80a00000 0x00000000 0xf93a00>;
+ };
+ };
+
+ domu {
+ /*
+ * There are 5 MUs, 0A is used by Dom0, 1A is used
+ * by ATF, so for DomU, 2A/3A/4A could be used.
+ * SC_R_MU_0A
+ * SC_R_MU_1A
+ * SC_R_MU_2A
+ * SC_R_MU_3A
+ * SC_R_MU_4A
+ * The rsrcs and pads will be configured by uboot scu_rm cmd
+ */
+ #address-cells = <1>;
+ #size-cells = <0>;
+ doma {
+ compatible = "xen,domu";
+ /*
+ * The name entry in VM configuration file
+ * needs to be same as here.
+ */
+ domain_name = "DomU";
+ /*
+ * The reg property will be updated by U-Boot to
+ * reflect the partition id.
+ */
+ reg = <0>;
+ init_on_rsrcs = <
+ SC_R_MU_2A
+ >;
+ /* Resources that will be transferred between
+ * M41 and AP, when support android auto.
+ */
+ rsrcs-m41-ap = <
+ SC_R_CSI_0
+ SC_R_CSI_0_PWM_0
+ SC_R_CSI_0_I2C_0
+ SC_R_LVDS_1
+ SC_R_LVDS_1_I2C_0
+ SC_R_LVDS_1_PWM_0
+ SC_R_DC_1
+ SC_R_DC_1_BLIT0
+ SC_R_DC_1_BLIT1
+ SC_R_DC_1_BLIT2
+ SC_R_DC_1_BLIT_OUT
+ SC_R_DC_1_WARP
+ SC_R_DC_1_VIDEO0
+ SC_R_DC_1_VIDEO1
+ SC_R_DC_1_FRAC0
+ SC_R_DC_1_PLL_0
+ SC_R_DC_1_PLL_1
+ SC_R_ISI_CH0
+ >;
+ rsrcs = <
+ SC_R_MU_6A
+ SC_R_GPU_1_PID0
+ SC_R_GPU_1_PID1
+ SC_R_GPU_1_PID2
+ SC_R_GPU_1_PID3
+ SC_R_LVDS_1
+ SC_R_LVDS_1_I2C_0
+ SC_R_LVDS_1_PWM_0
+ SC_R_DC_1
+ SC_R_DC_1_BLIT0
+ SC_R_DC_1_BLIT1
+ SC_R_DC_1_BLIT2
+ SC_R_DC_1_BLIT_OUT
+ SC_R_DC_1_WARP
+ SC_R_DC_1_VIDEO0
+ SC_R_DC_1_VIDEO1
+ SC_R_DC_1_FRAC0
+ SC_R_DC_1_PLL_0
+ SC_R_DC_1_PLL_1
+ SC_R_MIPI_1
+ SC_R_MIPI_1_I2C_0
+ SC_R_MIPI_1_I2C_1
+ SC_R_MIPI_1_PWM_0
+ SC_R_SDHC_0
+ SC_R_USB_0
+ SC_R_USB_0_PHY
+ SC_R_UART_1
+ SC_R_DMA_0_CH14
+ SC_R_DMA_0_CH15
+ SC_R_MU_2A
+ /* pcie */
+ SC_R_PCIE_B
+ SC_R_PCIE_A
+ SC_R_SERDES_0
+ SC_R_HSIO_GPIO
+ /*vpu*/
+ SC_R_VPU
+ SC_R_VPU_PID0
+ SC_R_VPU_PID1
+ SC_R_VPU_PID2
+ SC_R_VPU_PID3
+ SC_R_VPU_PID4
+ SC_R_VPU_PID5
+ SC_R_VPU_PID6
+ SC_R_VPU_PID7
+ SC_R_VPU_DEC_0
+ SC_R_VPU_ENC_0
+ SC_R_VPU_ENC_1
+ SC_R_VPU_TS_0
+ SC_R_VPU_MU_0
+ SC_R_VPU_MU_1
+ SC_R_VPU_MU_2
+ SC_R_VPU_MU_3
+ /* crypto */
+ SC_R_CAAM_JR2
+ SC_R_CAAM_JR2_OUT
+ SC_R_CAAM_JR3
+ SC_R_CAAM_JR3_OUT
+ /* Camera */
+ SC_R_ISI_CH0
+ SC_R_ISI_CH1
+ SC_R_ISI_CH2
+ SC_R_ISI_CH3
+ SC_R_MIPI_0
+ SC_R_MIPI_0_PWM_0
+ SC_R_MIPI_0_I2C_0
+ SC_R_MIPI_0_I2C_1
+ SC_R_CSI_0
+ SC_R_CSI_0_PWM_0
+ SC_R_CSI_0_I2C_0
+ /* usbotg3 */
+ SC_R_USB_2
+ SC_R_USB_2_PHY
+ /* SAI0 */
+ SC_R_DMA_2_CH12
+ SC_R_DMA_2_CH13
+ SC_R_SAI_0
+ /* ESAI0 */
+ SC_R_DMA_2_CH6
+ SC_R_DMA_2_CH7
+ SC_R_ESAI_0
+ /* ASRC0 */
+ SC_R_DMA_2_CH0
+ SC_R_DMA_2_CH1
+ SC_R_DMA_2_CH2
+ SC_R_DMA_2_CH3
+ SC_R_DMA_2_CH4
+ SC_R_DMA_2_CH5
+ SC_R_ASRC_0
+ SC_R_AUDIO_CLK_1
+ SC_R_AUDIO_CLK_0
+ SC_R_AUDIO_PLL_1
+ SC_R_AUDIO_PLL_0
+
+ SC_R_MCLK_OUT_0
+ SC_R_MCLK_OUT_1
+
+ /* HIFI DSP */
+ SC_R_DSP
+ SC_R_DSP_RAM
+ >;
+ /* Pads that will be transferred between M41 and AP */
+ pads-m41-ap = <
+ SC_P_MIPI_CSI0_GPIO0_00
+ SC_P_MIPI_CSI0_GPIO0_01
+ SC_P_LVDS1_I2C1_SCL
+ SC_P_LVDS1_I2C1_SDA
+ >;
+ pads = <
+ /* i2c1_lvds1 */
+ SC_P_LVDS1_I2C1_SCL
+ SC_P_LVDS1_I2C1_SDA
+ /* emmc */
+ SC_P_EMMC0_CLK
+ SC_P_EMMC0_CMD
+ SC_P_EMMC0_DATA0
+ SC_P_EMMC0_DATA1
+ SC_P_EMMC0_DATA2
+ SC_P_EMMC0_DATA3
+ SC_P_EMMC0_DATA4
+ SC_P_EMMC0_DATA5
+ SC_P_EMMC0_DATA6
+ SC_P_EMMC0_DATA7
+ SC_P_EMMC0_STROBE
+ SC_P_EMMC0_RESET_B
+ /* usb otg */
+ SC_P_USB_SS3_TC0
+ /* uart1 */
+ SC_P_UART1_RX
+ SC_P_UART1_TX
+ SC_P_UART1_CTS_B
+ SC_P_UART1_RTS_B
+ SC_P_QSPI1A_DQS
+ /* pciea */
+ SC_P_PCIE_CTRL0_CLKREQ_B
+ SC_P_PCIE_CTRL0_WAKE_B
+ SC_P_PCIE_CTRL0_PERST_B
+ SC_P_LVDS1_I2C0_SDA
+ SC_P_USDHC2_RESET_B
+ /*usbotgs typec */
+ SC_P_QSPI1A_SS0_B
+ SC_P_USB_SS3_TC3
+ SC_P_QSPI1A_DATA0
+ /* isl29023 */
+ SC_P_USDHC2_WP
+ SC_P_MIPI_CSI0_GPIO0_00
+ SC_P_MIPI_CSI0_GPIO0_01
+
+ /* SAI0 */
+ SC_P_SPI0_CS1
+ SC_P_SPI2_CS1
+ SC_P_SAI1_RXFS
+ SC_P_SAI1_RXC
+
+ /* ESAI0 */
+ SC_P_ESAI0_FSR
+ SC_P_ESAI0_FST
+ SC_P_ESAI0_SCKR
+ SC_P_ESAI0_SCKT
+ SC_P_ESAI0_TX0
+ SC_P_ESAI0_TX1
+ SC_P_ESAI0_TX2_RX3
+ SC_P_ESAI0_TX3_RX2
+ SC_P_ESAI0_TX4_RX1
+ SC_P_ESAI0_TX5_RX0
+
+ /* lvds pwm */
+ SC_P_LVDS1_GPIO00
+ >;
+
+ gpios = <&gpio1 13 GPIO_ACTIVE_LOW>,
+ <&gpio1 27 GPIO_ACTIVE_LOW>,
+ <&gpio1 28 GPIO_ACTIVE_LOW>,
+ <&gpio4 6 GPIO_ACTIVE_LOW>,
+ <&gpio4 9 GPIO_ACTIVE_LOW>,
+ <&gpio4 11 GPIO_ACTIVE_HIGH>,
+ <&gpio4 19 GPIO_ACTIVE_HIGH>,
+ <&gpio4 22 GPIO_ACTIVE_LOW>,
+ <&gpio4 26 GPIO_ACTIVE_HIGH>,
+ <&gpio4 25 GPIO_ACTIVE_HIGH>,
+ <&gpio4 27 GPIO_ACTIVE_LOW>,
+ <&gpio4 29 GPIO_ACTIVE_LOW>;
+ };
+ };
+
+ reserved-memory {
+ /* global autoconfigured region for contiguous allocations */
+ linux,cma {
+ compatible = "shared-dma-pool";
+ reusable;
+ size = <0 0x28000000>;
+ alloc-ranges = <0 0xa0000000 0 0x40000000>;
+ linux,cma-default;
+ };
+ };
+
+ display-subsystem {
+ compatible = "fsl,imx-display-subsystem";
+ ports = <&dpu1_disp0>, <&dpu1_disp1>;
+ };
+
+ /* Passthrough to domu */
+ mu2: mu@5d1d0000 {
+ compatible = "fsl,imx8-mu";
+ reg = <0x0 0x5d1d0000 0x0 0x10000>;
+ interrupts = <GIC_SPI 178 IRQ_TYPE_LEVEL_HIGH>;
+ fsl,scu_ap_mu_id = <0>;
+ xen,passthrough;
+ status = "disabled";
+ };
+
+ irqsteer_cm41: irqsteer_cm41@0x51080000 {
+ reg = <0x0 0x51080000 0x0 0x10000>;
+ xen,passthrough;
+ };
+
+ mu_rpmsg1_b: mu_rpmsg1_b@0x5d2a0000 {
+ reg = <0x0 0x5d2a0000 0x0 0x10000>;
+ xen,passthrough;
+ };
+
+ dsp_mu_b: dsp_mu_b@0x5d310000 {
+ reg = <0x0 0x5d310000 0x0 0x10000>;
+ xen,passthrough;
+ };
+
+ decoder_boot_mem: decoder_boot_mem@0x84000000 {
+ xen,passthrough;
+ reg = <0 0x84000000 0 0x2000000>;
+ };
+
+ encoder_boot_mem: encoder_boot_mem@0x86000000 {
+ xen,passthrough;
+ reg = <0 0x86000000 0 0x400000>;
+ };
+
+ rpmsg_reserved_mem: rpmsg_reserved_mem@90000000 {
+ xen,passthrough;
+ reg = <0x0 0x90000000 0x0 0x400000>;
+ };
+
+ rpmsg_dma_mem: rpmsg_dma_mem@90400000 {
+ xen,passthrough;
+ reg = <0x0 0x90400000 0x0 0x1c00000>;
+ };
+
+ decoder_rpc_mem: decoder_rpc_mem@0x92000000 {
+ xen,passthrough;
+ reg = <0 0x92000000 0 0x200000>;
+ };
+
+ encoder_rpc_mem: encoder_rpc_mem@0x92200000 {
+ xen,passthrough;
+ reg = <0 0x92200000 0 0x200000>;
+ };
+
+ dsp_reserved_mem: dsp@0x92400000 {
+ xen,passthrough;
+ reg = <0 0x92400000 0 0x2000000>;
+ };
+ encoder_reserved_mem: encoder_reserved_mem@0x94400000 {
+ xen,passthrough;
+ reg = <0 0x94400000 0 0x800000>;
+ };
+
+ /* This piece memory is used by M41, M40 is not covered */
+ m41_mem: m41_mem@0x94400000 {
+ xen,passthrough;
+ reg = <0 0x88800000 0 0x7800000>;
+ };
+
+ gpio4_dummy: gpio4_dummy@0{
+ /* Passthrough gpio4 interrupt to DomU */
+ interrupts = <GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>;
+ xen,passthrough;
+ };
+
+ /* Interrupt 33 is not used, use it virtual PL031 */
+ rtc0: rtc@23000000 {
+ interrupts = <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>;
+ xen,passthrough;
+ };
+};
+
+&mu_rpmsg1 {
+ xen,passthrough;
+};
+
+&rpmsg1 {
+ /* Let xen not create mapping form dom0 */
+ /delete-property/ reg;
+ status = "disabled";
+};
+
+&rpmsg {
+ /delete-property/ reg;
+ status = "disabled";
+};
+
+&mu_6_lpcg {
+ xen,passthrough;
+};
+
+&mu_6_lpcg_b {
+ xen,passthrough;
+};
+
+&mu_7_lpcg_b {
+ xen,passthrough;
+};
+
+&usbotg1_lpcg {
+ xen,passthrough;
+};
+
+&sdhc1_lpcg {
+ xen,passthrough;
+};
+
+&lpuart1 {
+ xen,passthrough;
+};
+
+&lpuart1_lpcg {
+ xen,passthrough;
+};
+
+/*
+ * DomU CM41 use this, but DomU OS not need this,
+ * because smmu is enabled for CM41, so need to
+ *create the lpuart2 mapping in SMMU
+ */
+&lpuart2 {
+ xen,passthrough;
+};
+
+&lpuart2_lpcg {
+ xen,passthrough;
+};
+
+&di_lvds1_lpcg {
+ xen,passthrough;
+};
+
+&dc_1_lpcg {
+ xen,passthrough;
+};
+
+&edma01 {
+ #stream-id-cells = <1>;
+ xen,passthrough;
+};
+
+&edma20 {
+ #stream-id-cells = <1>;
+ xen,passthrough;
+ /* Put edma20 and edma21 resource here */
+ fsl,sc_rsrc_id = <SC_R_DMA_2_CH0>,
+ <SC_R_DMA_2_CH1>,
+ <SC_R_DMA_2_CH2>,
+ <SC_R_DMA_2_CH3>,
+ <SC_R_DMA_2_CH4>,
+ <SC_R_DMA_2_CH5>,
+ <SC_R_DMA_2_CH6>,
+ <SC_R_DMA_2_CH7>,
+ <SC_R_DMA_2_CH12>,
+ <SC_R_DMA_2_CH13>;
+};
+
+&edma21 {
+ xen,passthrough;
+};
+
+&edma24 {
+ xen,passthrough;
+};
+
+/*
+ * SMMU, for simplity, we put all all the resources needs to programmed
+ * for VPU under vpu_decoder node, then in cfg file only add vpu_decoder
+ * in dt_dev is enough.
+ */
+&smmu {
+ mmu-masters = <&dpu2 0x13>, <&gpu_3d1 0x15>, <&edma20 0x14>,
+ <&usdhc1 0x12>, <&usbotg1 0x11>,
+ <&edma01 0x10>, <&pciea 0x08>,
+ <&vpu_decoder 0x7>, <&crypto 0x6>, <&isi_0 0x5>,
+ <&usbotg3 0x4>, <&dsp 0x3>;
+};
+
+&lvds_region2 {
+ xen,passthrough;
+};
+
+&irqsteer_lvds1 {
+ xen,passthrough;
+};
+
+&i2c1_lvds1 {
+ xen,passthrough;
+};
+
+&ldb2_phy {
+ xen,passthrough;
+};
+
+&ldb2 {
+ xen,passthrough;
+};
+
+&dpu2_intsteer {
+ xen,passthrough;
+};
+
+&dpu2 {
+ xen,passthrough;
+ #stream-id-cells = <1>;
+ iommus = <&smmu>;
+};
+
+&pixel_combiner2 {
+ xen,passthrough;
+};
+
+&prg10 {
+ xen,passthrough;
+};
+
+&prg11 {
+ xen,passthrough;
+};
+
+&prg12 {
+ xen,passthrough;
+};
+
+&prg13 {
+ xen,passthrough;
+};
+
+&prg14 {
+ xen,passthrough;
+};
+
+&prg15 {
+ xen,passthrough;
+};
+
+&prg16 {
+ xen,passthrough;
+};
+
+&prg17 {
+ xen,passthrough;
+};
+
+&prg18 {
+ xen,passthrough;
+};
+
+&dpr3_channel1 {
+ xen,passthrough;
+};
+
+&dpr3_channel2 {
+ xen,passthrough;
+};
+
+&dpr3_channel3 {
+ xen,passthrough;
+};
+
+&dpr4_channel1 {
+ xen,passthrough;
+};
+
+&dpr4_channel2 {
+ xen,passthrough;
+};
+
+&dpr4_channel3 {
+ xen,passthrough;
+};
+
+/* GPU */
+&pd_gpu1 {
+ xen,passthrough;
+};
+
+&gpu_3d1 {
+ xen,passthrough;
+ #stream-id-cells = <1>;
+ iommus = <&smmu>;
+};
+
+&imx8_gpu_ss {
+ cores = <&gpu_3d0>;
+ reg = <0x0 0xa0000000 0x0 0x40000000>, <0x0 0x0 0x0 0x10000000>;
+ reg-names = "phys_baseaddr", "contiguous_mem";
+};
+
+&sata {
+ status = "disabled";
+};
+
+&usdhc1 {
+ xen,passthrough;
+ #stream-id-cells = <1>;
+ iommus = <&smmu>;
+};
+
+&usbotg1 {
+ /* Hack reg */
+ reg = <0x0 0x5b0d0000 0x0 0x1000>;
+ xen,passthrough;
+ #stream-id-cells = <1>;
+ iommus = <&smmu>;
+};
+
+&usbmisc1 {
+ /* Hack */
+ /delete-property/ reg;
+ status = "disabled";
+};
+
+&usbphy1 {
+ reg = <0x0 0x5b100000 0x0 0x1000>;
+ xen,passthrough;
+};
+
+&hsio {
+ xen,passthrough;
+};
+
+&hsio_pcie_x2_lpcg {
+ xen,passthrough;
+};
+
+&hsio_phy_x2_lpcg {
+ xen,passthrough;
+};
+
+&hsio_pcie_x2_crr2_lpcg {
+ xen,passthrough;
+};
+
+&hsio_pcie_x1_lpcg {
+ xen,passthrough;
+};
+
+&pciea {
+ #stream-id-cells = <1>;
+ iommus = <&smmu>;
+ xen,passthrough;
+ fsl,sc_rsrc_id = <SC_R_PCIE_A>;
+};
+
+&pcieb {
+ xen,passthrough;
+};
+
+&gpio1 {
+ xen,shared;
+};
+
+&gpt0 {
+ /delete-property/ interrupts;
+ status = "disabled";
+};
+
+&gpio4 {
+ /*
+ * Use GPT0 interrupt for hack
+ * This could be removed when interrupt sharing be supported.
+ */
+ interrupts = <GIC_SPI 80 IRQ_TYPE_LEVEL_HIGH>;
+ xen,domu-irq;
+ xen,shared;
+};
+
+&dsp {
+ xen,passthrough;
+ #stream-id-cells = <1>;
+ iommus = <&smmu>;
+};
+
+&mu13 {
+ xen,passthrough;
+};
+
+&mu_m0 {
+ xen,passthrough;
+};
+
+&mu1_m0 {
+ xen,passthrough;
+};
+
+&mu2_m0 {
+ xen,passthrough;
+};
+
+&vpu_decoder {
+ #stream-id-cells = <1>;
+ iommus = <&smmu>;
+ xen,passthrough;
+ fsl,sc_rsrc_id = <SC_R_VPU_PID0>,
+ <SC_R_VPU_PID1>,
+ <SC_R_VPU_PID2>,
+ <SC_R_VPU_PID3>,
+ <SC_R_VPU_PID4>,
+ <SC_R_VPU_PID5>,
+ <SC_R_VPU_PID6>,
+ <SC_R_VPU_PID7>,
+ <SC_R_VPU_DEC_0>,
+ <SC_R_VPU_ENC_0>,
+ <SC_R_VPU_ENC_1>,
+ <SC_R_VPU_TS_0>;
+};
+
+&vpu_decoder_csr {
+ xen,passthrough;
+};
+
+&vpu_encoder {
+ iommus = <&smmu>;
+ #stream-id-cells = <1>;
+ xen,passthrough;
+};
+
+&{/vpu_encoder@2d000000/core0@1020000} {
+ xen,passthrough;
+};
+
+&{/vpu_encoder@2d000000/core1@1040000} {
+ xen,passthrough;
+};
+
+&crypto {
+ xen,passthrough;
+ iommus = <&smmu>;
+ #stream-id-cells = <1>;
+ /* JR1 is not used by Linux */
+ fsl,sc_rsrc_id = <SC_R_CAAM_JR2>, <SC_R_CAAM_JR2_OUT>,
+ <SC_R_CAAM_JR3>, <SC_R_CAAM_JR3_OUT>;
+};
+
+&sec_jr2 {
+ xen,passthrough;
+};
+
+&sec_jr3 {
+ xen,passthrough;
+};
+
+&caam_sm {
+ xen,passthrough;
+};
+
+&i2c0 {
+ isl29023@44 {
+ xen,passthrough;
+ };
+
+ fxos8700@1e {
+ xen,passthrough;
+ };
+
+ fxas2100x@20 {
+ xen,passthrough;
+ };
+
+ mpl3115@60 {
+ xen,passthrough;
+ };
+
+ typec_ptn5110: typec@50 {
+ xen,passthrough;
+ };
+};
+
+/* Camera */
+&img_pdma_0_lpcg {
+ xen,passthrough;
+};
+
+&img_pdma_1_lpcg {
+ xen,passthrough;
+};
+
+&img_pdma_2_lpcg {
+ xen,passthrough;
+};
+
+&img_pdma_3_lpcg {
+ xen,passthrough;
+};
+
+&mipi_csi_0_lpcg {
+ xen,passthrough;
+};
+
+&img_pxl_link_csi0_lpcg {
+ xen,passthrough;
+};
+
+&gpio0_mipi_csi0 {
+ xen,passthrough;
+};
+
+&irqsteer_csi0 {
+ xen,passthrough;
+};
+
+&isi_0 {
+ xen,passthrough;
+ #stream-id-cells = <1>;
+ iommus = <&smmu>;
+ fsl,sc_rsrc_id = <SC_R_ISI_CH0>,
+ <SC_R_ISI_CH1>,
+ <SC_R_ISI_CH2>,
+ <SC_R_ISI_CH3>;
+};
+
+&isi_1 {
+ xen,passthrough;
+};
+
+&isi_2 {
+ xen,passthrough;
+};
+
+&isi_3 {
+ xen,passthrough;
+};
+
+&mipi_csi_0 {
+ xen,passthrough;
+};
+
+&i2c0_mipi_csi0 {
+ xen,passthrough;
+};
+
+&isi_4 {
+ status = "okay";
+};
+
+&isi_5 {
+ status = "okay";
+};
+
+&isi_6 {
+ status = "okay";
+};
+
+&isi_7 {
+ status = "okay";
+};
+
+&mipi_csi_1 {
+ status = "okay";
+};
+
+&i2c0_mipi_csi1 {
+ status = "okay";
+};
+
+&usbotg3_lpcg {
+ xen,passthrough;
+};
+
+&usbotg3 {
+ xen,passthrough;
+ #stream-id-cells = <1>;
+ iommus = <&smmu>;
+};
+
+/delete-node/ &{/sound-cs42888};
+
+&acm {
+ xen,passthrough;
+};
+
+&sai0 {
+ xen,passthrough;
+};
+
+&aud_sai_0_lpcg {
+ xen,passthrough;
+};
+
+&esai0 {
+ xen,passthrough;
+};
+
+&asrc0 {
+ xen,passthrough;
+};
+
+&aud_asrc_0_lpcg {
+ xen,passthrough;
+};
+
+&aud_esai_0_lpcg {
+ xen,passthrough;
+};
+
+&aud_pll_clk0_lpcg {
+ xen,passthrough;
+};
+
+&aud_pll_clk1_lpcg {
+ xen,passthrough;
+};
+
+&aud_mclkout0_lpcg {
+ xen,passthrough;
+};
+
+&aud_mclkout1_lpcg {
+ xen,passthrough;
+};
+
+&aud_rec_clk0_lpcg {
+ xen,passthrough;
+};
+
+&aud_rec_clk1_lpcg {
+ xen,passthrough;
+};
+
+&lvds1_pwm {
+ xen,passthrough;
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8qm-mek-domu-car.dts b/arch/arm64/boot/dts/freescale/fsl-imx8qm-mek-domu-car.dts
new file mode 100644
index 000000000000..e552a103e6ab
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8qm-mek-domu-car.dts
@@ -0,0 +1,747 @@
+/*
+ * Copyright 2018-2019 NXP
+ *
+ * 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 "fsl-imx8qm-mek-domu.dts"
+
+/* Android Auto use bootargs */
+/delete-node/ &{/reserved-memory/linux,cma};
+
+/ {
+ /*
+ trusty {
+ compatible = "android,trusty-smc-v1";
+ ranges;
+ #address-cells = <2>;
+ #size-cells = <2>;
+ trusty-virtio {
+ compatible = "android,trusty-virtio-v1";
+ };
+ };
+ trusty_ipi: interrupt-controller@0 {
+ compatible = "android,CustomIPI";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+ */
+
+ bt_rfkill {
+ compatible = "fsl,mxc_bt_rfkill";
+ bt-power-gpios = <&gpio4 22 GPIO_ACTIVE_LOW>;
+ status ="okay";
+ };
+
+ sound-xtor {
+ compatible = "fsl,imx-audio-xtor";
+ model = "xtor-audio";
+ cpu-dai = <&sai0>;
+ status = "okay";
+ };
+};
+
+/* Android auto use RPMSG to handle I2C */
+/delete-node/ &xen_i2c1;
+/delete-node/ &i2c1_lvds1;
+/delete-node/ &camera;
+/delete-node/ &dpu2_intsteer;
+/delete-node/ &prg10;
+/delete-node/ &prg11;
+/delete-node/ &prg12;
+/delete-node/ &prg13;
+/delete-node/ &prg14;
+/delete-node/ &prg15;
+/delete-node/ &prg16;
+/delete-node/ &prg17;
+/delete-node/ &prg18;
+/delete-node/ &dpr3_channel1;
+/delete-node/ &dpr3_channel2;
+/delete-node/ &dpr3_channel3;
+/delete-node/ &dpr4_channel1;
+/delete-node/ &dpr4_channel2;
+/delete-node/ &dpr4_channel3;
+/delete-node/ &dpu2;
+/delete-node/ &pixel_combiner2;
+
+/delete-node/ &lvds_region2;
+/delete-node/ &ldb2_phy;
+/delete-node/ &ldb2;
+/delete-node/ &lvds1_pwm;
+/delete-node/ &irqsteer_lvds1;
+
+/delete-node/ &irqsteer_csi0;
+/delete-node/ &i2c0_mipi_csi0;
+/delete-node/ &gpio0_mipi_csi0;
+
+&iomuxc {
+ imx8qm-mek {
+ pinctrl_mipi_csi0_en_rst: mipi_csi0_en_rst {
+ fsl,pins = <
+ SC_P_MIPI_CSI0_GPIO0_00_LSIO_GPIO1_IO27 0x00000021
+ SC_P_MIPI_CSI0_GPIO0_01_LSIO_GPIO1_IO28 0x00000021
+ >;
+ };
+
+ pinctrl_sai0: sai0grp {
+ fsl,pins = <
+ SC_P_SPI0_CS1_AUD_SAI0_TXC 0x0600004c
+ SC_P_SPI2_CS1_AUD_SAI0_TXFS 0x0600004c
+ SC_P_SAI1_RXFS_AUD_SAI0_RXD 0x0600004c
+ SC_P_SAI1_RXC_AUD_SAI0_TXD 0x0600006c
+ >;
+ };
+ };
+};
+
+&sai0 {
+ assigned-clocks = <&clk IMX8QM_AUD_PLL0_DIV>,
+ <&clk IMX8QM_AUD_ACM_AUD_PLL_CLK0_DIV>,
+ <&clk IMX8QM_AUD_ACM_AUD_REC_CLK0_DIV>,
+ <&clk IMX8QM_AUD_SAI_0_MCLK>;
+ assigned-clock-rates = <786432000>, <49152000>, <12288000>, <49152000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_sai0>;
+ status = "okay";
+};
+
+&i2c_rpbus_1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "okay";
+
+ cs42888: cs42888@48 {
+ compatible = "cirrus,cs42888";
+ reg = <0x48>;
+ clocks = <&clk IMX8QM_AUD_MCLKOUT0>;
+ clock-names = "mclk";
+ VA-supply = <&reg_audio>;
+ VD-supply = <&reg_audio>;
+ VLS-supply = <&reg_audio>;
+ VLC-supply = <&reg_audio>;
+ reset-gpio = <&gpio4 25 1>;
+ power-domains = <&pd_mclk_out0>;
+ assigned-clocks = <&clk IMX8QM_AUD_PLL0_DIV>,
+ <&clk IMX8QM_AUD_ACM_AUD_PLL_CLK0_DIV>,
+ <&clk IMX8QM_AUD_ACM_AUD_REC_CLK0_DIV>,
+ <&clk IMX8QM_AUD_MCLKOUT0>;
+ assigned-clock-rates = <786432000>, <49152000>, <12288000>, <12288000>;
+ fsl,txs-rxm;
+ status = "okay";
+ };
+};
+
+&vehicle_core {
+ status = "okay";
+};
+
+&vehicle_rpmsg_m4 {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ status = "okay";
+ ranges;
+
+ clk_post: clk1 {
+ compatible = "fsl,imx8qm-post-clk";
+ #clock-cells = <1>;
+ };
+
+ dpu2_intsteer: dpu_intsteer@57000000 {
+ compatible = "fsl,imx8qm-dpu-intsteer", "syscon";
+ reg = <0x0 0x57000000 0x0 0x10000>;
+ };
+
+ pixel_combiner2: pixel-combiner@57020000 {
+ compatible = "fsl,imx8qm-pixel-combiner";
+ reg = <0x0 0x57020000 0x0 0x10000>;
+ power-domains = <&pd_dc1>;
+ status = "okay";
+ };
+
+ prg10: prg@57040000 {
+ compatible = "fsl,imx8qm-prg";
+ reg = <0x0 0x57040000 0x0 0x10000>;
+ clocks = <&clk_post IMX8QM_DC1_PRG0_APB_CLK>,
+ <&clk_post IMX8QM_DC1_PRG0_RTRAM_CLK>;
+ clock-names = "apb", "rtram";
+ power-domains = <&pd_dc1>;
+ status = "okay";
+ };
+
+ prg11: prg@57050000 {
+ compatible = "fsl,imx8qm-prg";
+ reg = <0x0 0x57050000 0x0 0x10000>;
+ clocks = <&clk_post IMX8QM_DC1_PRG1_APB_CLK>,
+ <&clk_post IMX8QM_DC1_PRG1_RTRAM_CLK>;
+ clock-names = "apb", "rtram";
+ power-domains = <&pd_dc1>;
+ status = "okay";
+ };
+
+ prg12: prg@57060000 {
+ compatible = "fsl,imx8qm-prg";
+ reg = <0x0 0x57060000 0x0 0x10000>;
+ clocks = <&clk_post IMX8QM_DC1_PRG2_APB_CLK>,
+ <&clk_post IMX8QM_DC1_PRG2_RTRAM_CLK>;
+ clock-names = "apb", "rtram";
+ power-domains = <&pd_dc1>;
+ status = "okay";
+ };
+
+ prg13: prg@57070000 {
+ compatible = "fsl,imx8qm-prg";
+ reg = <0x0 0x57070000 0x0 0x10000>;
+ clocks = <&clk_post IMX8QM_DC1_PRG3_APB_CLK>,
+ <&clk_post IMX8QM_DC1_PRG3_RTRAM_CLK>;
+ clock-names = "apb", "rtram";
+ power-domains = <&pd_dc1>;
+ status = "okay";
+ };
+
+ prg14: prg@57080000 {
+ compatible = "fsl,imx8qm-prg";
+ reg = <0x0 0x57080000 0x0 0x10000>;
+ clocks = <&clk_post IMX8QM_DC1_PRG4_APB_CLK>,
+ <&clk_post IMX8QM_DC1_PRG4_RTRAM_CLK>;
+ clock-names = "apb", "rtram";
+ power-domains = <&pd_dc1>;
+ status = "okay";
+ };
+
+ prg15: prg@57090000 {
+ compatible = "fsl,imx8qm-prg";
+ reg = <0x0 0x57090000 0x0 0x10000>;
+ clocks = <&clk_post IMX8QM_DC1_PRG5_APB_CLK>,
+ <&clk_post IMX8QM_DC1_PRG5_RTRAM_CLK>;
+ clock-names = "apb", "rtram";
+ power-domains = <&pd_dc1>;
+ status = "okay";
+ };
+
+ prg16: prg@570a0000 {
+ compatible = "fsl,imx8qm-prg";
+ reg = <0x0 0x570a0000 0x0 0x10000>;
+ clocks = <&clk_post IMX8QM_DC1_PRG6_APB_CLK>,
+ <&clk_post IMX8QM_DC1_PRG6_RTRAM_CLK>;
+ clock-names = "apb", "rtram";
+ power-domains = <&pd_dc1>;
+ status = "okay";
+ };
+
+
+ prg17: prg@570b0000 {
+ compatible = "fsl,imx8qm-prg";
+ reg = <0x0 0x570b0000 0x0 0x10000>;
+ clocks = <&clk_post IMX8QM_DC1_PRG7_APB_CLK>,
+ <&clk_post IMX8QM_DC1_PRG7_RTRAM_CLK>;
+ clock-names = "apb", "rtram";
+ power-domains = <&pd_dc1>;
+ status = "okay";
+ };
+
+ prg18: prg@570c0000 {
+ compatible = "fsl,imx8qm-prg";
+ reg = <0x0 0x570c0000 0x0 0x10000>;
+ clocks = <&clk_post IMX8QM_DC1_PRG8_APB_CLK>,
+ <&clk_post IMX8QM_DC1_PRG8_RTRAM_CLK>;
+ clock-names = "apb", "rtram";
+ power-domains = <&pd_dc1>;
+ status = "okay";
+ };
+
+ dpr3_channel1: dpr-channel@570d0000 {
+ compatible = "fsl,imx8qm-dpr-channel";
+ reg = <0x0 0x570d0000 0x0 0x10000>;
+ fsl,sc-resource = <SC_R_DC_1_BLIT0>;
+ fsl,prgs = <&prg10>;
+ clocks = <&clk_post IMX8QM_DC1_DPR0_APB_CLK>,
+ <&clk_post IMX8QM_DC1_DPR0_B_CLK>,
+ <&clk_post IMX8QM_DC1_RTRAM0_CLK>;
+ clock-names = "apb", "b", "rtram";
+ power-domains = <&pd_dc1>;
+ status = "okay";
+ };
+
+ dpr3_channel2: dpr-channel@570e0000 {
+ compatible = "fsl,imx8qm-dpr-channel";
+ reg = <0x0 0x570e0000 0x0 0x10000>;
+ fsl,sc-resource = <SC_R_DC_1_BLIT1>;
+ fsl,prgs = <&prg11>, <&prg10>;
+ clocks = <&clk_post IMX8QM_DC1_DPR0_APB_CLK>,
+ <&clk_post IMX8QM_DC1_DPR0_B_CLK>,
+ <&clk_post IMX8QM_DC1_RTRAM0_CLK>;
+ clock-names = "apb", "b", "rtram";
+ power-domains = <&pd_dc1>;
+ status = "okay";
+ };
+
+ dpr3_channel3: dpr-channel@570f0000 {
+ compatible = "fsl,imx8qm-dpr-channel";
+ reg = <0x0 0x570f0000 0x0 0x10000>;
+ fsl,sc-resource = <SC_R_DC_1_FRAC0>;
+ fsl,prgs = <&prg12>;
+ clocks = <&clk_post IMX8QM_DC1_DPR0_APB_CLK>,
+ <&clk_post IMX8QM_DC1_DPR0_B_CLK>,
+ <&clk_post IMX8QM_DC1_RTRAM0_CLK>;
+ clock-names = "apb", "b", "rtram";
+ power-domains = <&pd_dc1>;
+ status = "okay";
+ };
+
+ dpr4_channel1: dpr-channel@57100000 {
+ compatible = "fsl,imx8qm-dpr-channel";
+ reg = <0x0 0x57100000 0x0 0x10000>;
+ fsl,sc-resource = <SC_R_DC_1_VIDEO0>;
+ fsl,prgs = <&prg13>, <&prg14>;
+ clocks = <&clk_post IMX8QM_DC1_DPR1_APB_CLK>,
+ <&clk_post IMX8QM_DC1_DPR1_B_CLK>,
+ <&clk_post IMX8QM_DC1_RTRAM1_CLK>;
+ clock-names = "apb", "b", "rtram";
+ power-domains = <&pd_dc1>;
+ status = "okay";
+ };
+
+ dpr4_channel2: dpr-channel@57110000 {
+ compatible = "fsl,imx8qm-dpr-channel";
+ reg = <0x0 0x57110000 0x0 0x10000>;
+ fsl,sc-resource = <SC_R_DC_1_VIDEO1>;
+ fsl,prgs = <&prg15>, <&prg16>;
+ clocks = <&clk_post IMX8QM_DC1_DPR1_APB_CLK>,
+ <&clk_post IMX8QM_DC1_DPR1_B_CLK>,
+ <&clk_post IMX8QM_DC1_RTRAM1_CLK>;
+ clock-names = "apb", "b", "rtram";
+ power-domains = <&pd_dc1>;
+ status = "okay";
+ };
+
+ dpr4_channel3: dpr-channel@56712000 {
+ compatible = "fsl,imx8qm-dpr-channel";
+ reg = <0x0 0x57120000 0x0 0x10000>;
+ fsl,sc-resource = <SC_R_DC_1_WARP>;
+ fsl,prgs = <&prg17>, <&prg18>;
+ clocks = <&clk_post IMX8QM_DC1_DPR1_APB_CLK>,
+ <&clk_post IMX8QM_DC1_DPR1_B_CLK>,
+ <&clk_post IMX8QM_DC1_RTRAM1_CLK>;
+ clock-names = "apb", "b", "rtram";
+ power-domains = <&pd_dc1>;
+ status = "okay";
+ };
+
+ dpu2: dpu@57180000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx8qm-dpu";
+ reg = <0x0 0x57180000 0x0 0x40000>;
+ intsteer = <&dpu2_intsteer>;
+ interrupts = <GIC_SPI 152 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 153 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 154 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 155 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 156 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 157 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 158 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 159 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 162 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 163 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "irq_common",
+ "irq_stream0a",
+ "irq_stream0b", /* to M4? */
+ "irq_stream1a",
+ "irq_stream1b", /* to M4? */
+ "irq_reserved0",
+ "irq_reserved1",
+ "irq_blit",
+ "irq_dpr0",
+ "irq_dpr1";
+ clocks = <&clk_post IMX8QM_DC1_PLL0_CLK>,
+ <&clk_post IMX8QM_DC1_PLL1_CLK>,
+ <&clk_post IMX8QM_DC1_BYPASS_0_DIV>,
+ <&clk_post IMX8QM_DC1_DISP0_SEL>,
+ <&clk_post IMX8QM_DC1_DISP1_SEL>,
+ <&clk_post IMX8QM_DC1_DISP0_CLK>,
+ <&clk_post IMX8QM_DC1_DISP1_CLK>;
+ clock-names = "pll0", "pll1", "bypass0",
+ "disp0_sel", "disp1_sel", "disp0", "disp1";
+ power-domains = <&pd_dc1_pll1>;
+ fsl,dpr-channels = <&dpr3_channel1>, <&dpr3_channel2>,
+ <&dpr3_channel3>, <&dpr4_channel1>,
+ <&dpr4_channel2>, <&dpr4_channel3>;
+ fsl,pixel-combiner = <&pixel_combiner2>;
+ status = "okay";
+
+ dpu2_disp0: port@0 {
+ reg = <0>;
+
+ dpu2_disp0_mipi_dsi: mipi-dsi-endpoint {
+ /delete-property/ remote-endpoint;
+ };
+ };
+
+ dpu2_disp1: port@1 {
+ reg = <1>;
+
+ dpu2_disp1_lvds0: lvds0-endpoint {
+ remote-endpoint = <&ldb2_lvds0>;
+ };
+
+ dpu2_disp1_lvds1: lvds1-endpoint {
+ remote-endpoint = <&ldb2_lvds1>;
+ };
+ };
+ };
+
+ irqsteer_dsi1: irqsteer@57220000 {
+ compatible = "nxp,imx-irqsteer";
+ reg = <0x0 0x57220000 0x0 0x1000>;
+ interrupts = <GIC_SPI 60 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-controller;
+ interrupt-parent = <&gic>;
+ #interrupt-cells = <2>;
+ clocks = <&clk IMX8QM_MIPI1_LIS_IPG_CLK>;
+ clock-names = "ipg";
+ power-domains = <&pd_mipi1>;
+ };
+
+ mipi_dsi_csr2: csr@57221000 {
+ compatible = "fsl,imx8qm-mipi-dsi-csr", "syscon";
+ reg = <0x0 0x57221000 0x0 0x1000>;
+ };
+
+ mipi_dsi_phy2: mipi_phy@57228300 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "mixel,imx8qm-mipi-dsi-phy";
+ reg = <0x0 0x57228300 0x0 0x100>;
+ power-domains = <&pd_mipi1>;
+ #phy-cells = <0>;
+ status = "disabled";
+ };
+
+ lvds_region2: lvds_region@57240000 {
+ compatible = "fsl,imx8qm-lvds-region", "syscon";
+ reg = <0x0 0x57240000 0x0 0x10000>;
+ };
+
+ ldb2_phy: ldb_phy@57241000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "mixel,lvds-phy";
+ reg = <0x0 0x57241000 0x0 0x100>;
+ clocks = <&clk_post IMX8QM_LVDS1_PHY_CLK>;
+ clock-names = "phy";
+ power-domains = <&pd_lvds1>;
+ status = "okay";
+
+ ldb2_phy1: port@0 {
+ reg = <0>;
+ #phy-cells = <0>;
+ };
+
+ ldb2_phy2: port@1 {
+ reg = <1>;
+ #phy-cells = <0>;
+ };
+ };
+
+ ldb2: ldb@572410e0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx8qm-ldb";
+ clocks = <&clk_post IMX8QM_LVDS1_PIXEL_CLK>,
+ <&clk_post IMX8QM_LVDS1_BYPASS_CLK>;
+ clock-names = "pixel", "bypass";
+ power-domains = <&pd_lvds1>;
+ gpr = <&lvds_region2>;
+ status = "okay";
+
+ lvds-channel@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0>;
+ phys = <&ldb2_phy1>;
+ phy-names = "ldb_phy";
+ fsl,data-mapping = "jeida";
+ fsl,data-width = <24>;
+ status = "okay";
+
+ port@0 {
+ reg = <0>;
+
+ ldb2_lvds0: endpoint {
+ remote-endpoint = <&dpu2_disp1_lvds0>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+
+ lvds1_out: endpoint {
+ remote-endpoint = <&it6263_1_in>;
+ };
+ };
+ };
+
+ lvds-channel@1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <1>;
+ phys = <&ldb2_phy2>;
+ phy-names = "ldb_phy";
+ status = "disabled";
+
+ port@0 {
+ reg = <0>;
+
+ ldb2_lvds1: endpoint {
+ remote-endpoint = <&dpu2_disp1_lvds1>;
+ };
+ };
+ };
+ };
+
+ lvds1_pwm: pwm@57244000 {
+ compatible = "fsl,imx8qm-pwm", "fsl,imx27-pwm";
+ reg = <0x0 0x57244000 0 0x1000>;
+ clocks = <&clk_post IMX8QM_LVDS1_PWM0_IPG_CLK>,
+ <&clk_post IMX8QM_LVDS1_PWM0_CLK>;
+ clock-names = "ipg", "per";
+ assigned-clocks = <&clk_post IMX8QM_LVDS1_PWM0_CLK>;
+ assigned-clock-rates = <24000000>;
+ #pwm-cells = <2>;
+ power-domains = <&pd_lvds1_pwm>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lvds1_pwm0>;
+ status = "okay";
+ };
+
+ irqsteer_lvds1: irqsteer@572400000 {
+ compatible = "nxp,imx-irqsteer";
+ reg = <0x0 0x57240000 0x0 0x1000>;
+ interrupts = <GIC_SPI 58 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-controller;
+ interrupt-parent = <&gic>;
+ #interrupt-cells = <2>;
+ clocks = <&clk_post IMX8QM_LVDS1_LIS_IPG_CLK>;
+ clock-names = "ipg";
+ power-domains = <&pd_lvds1>;
+ };
+
+ irqsteer_csi0: irqsteer@58220000 {
+ compatible = "nxp,imx-irqsteer";
+ reg = <0x0 0x58220000 0x0 0x1000>;
+ interrupts = <GIC_SPI 320 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-controller;
+ interrupt-parent = <&gic>;
+ #interrupt-cells = <2>;
+ clocks = <&clk IMX8QM_CLK_DUMMY>;
+ clock-names = "ipg";
+ power-domains = <&pd_csi0>;
+ };
+
+ i2c0_mipi_csi0: i2c@58226000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx8qm-lpi2c";
+ reg = <0x0 0x58226000 0x0 0x1000>;
+ interrupts = <8 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-parent = <&irqsteer_csi0>;
+ clocks = <&clk_post IMX8QM_CSI0_I2C0_CLK>,
+ <&clk_post IMX8QM_CSI0_I2C0_IPG_CLK>;
+ clock-names = "per", "ipg";
+ assigned-clocks = <&clk_post IMX8QM_CSI0_I2C0_CLK>;
+ assigned-clock-rates = <24000000>;
+ power-domains = <&pd_csi0_i2c0>;
+ pinctrl-names = "default";
+ status = "okay";
+ clock-frequency = <1000000>;
+ /*pinctrl-0 = <&pinctrl_mipi_csi0_en>;*/
+ max9286_mipi@6A {
+ compatible = "maxim,max9286_mipi";
+ reg = <0x6A>;
+ clocks = <&clk IMX8QM_CLK_DUMMY>;
+ clock-names = "capture_mclk";
+ mclk = <27000000>;
+ mclk_source = <0>;
+ pwn-gpios = <&gpio1 27 GPIO_ACTIVE_HIGH>;
+ virtual-channel;
+ port {
+ max9286_0_ep: endpoint {
+ remote-endpoint = <&mipi_csi0_ep>;
+ data-lanes = <1 2 3 4>;
+ };
+ };
+ };
+ };
+
+ gpio0_mipi_csi0: gpio@58222000 {
+ compatible = "fsl,imx8qm-gpio", "fsl,imx35-gpio";
+ reg = <0x0 0x58222000 0x0 0x1000>;
+ interrupts = <0 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-parent = <&irqsteer_csi0>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ power-domains = <&pd_csi0>;
+ status = "disabled";
+ };
+
+ irqsteer_csi1: irqsteer@582400000 {
+ compatible = "nxp,imx-irqsteer";
+ reg = <0x0 0x58240000 0x0 0x1000>;
+ interrupts = <GIC_SPI 321 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-controller;
+ interrupt-parent = <&gic>;
+ #interrupt-cells = <2>;
+ clocks = <&clk IMX8QM_CLK_DUMMY>;
+ clock-names = "ipg";
+ power-domains = <&pd_csi1>;
+ };
+
+ gpio0_mipi_csi1: gpio@58242000 {
+ compatible = "fsl,imx8qm-gpio", "fsl,imx35-gpio";
+ reg = <0x0 0x58242000 0x0 0x1000>;
+ interrupts = <0 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-parent = <&irqsteer_csi1>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ power-domains = <&pd_csi1>;
+ status = "disabled";
+ };
+
+ i2c1_lvds1: i2c@57247000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx8qm-lpi2c";
+ reg = <0x0 0x57247000 0x0 0x1000>;
+ interrupts = <9 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-parent = <&irqsteer_lvds1>;
+ clocks = <&clk_post IMX8QM_LVDS1_I2C0_CLK>,
+ <&clk_post IMX8QM_LVDS1_I2C0_IPG_CLK>;
+ clock-names = "per", "ipg";
+ assigned-clocks = <&clk_post IMX8QM_LVDS1_I2C0_CLK>;
+ assigned-clock-rates = <24000000>;
+ power-domains = <&pd_lvds1_i2c0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lvds1_lpi2c1>;
+ clock-frequency = <400000>;
+ status = "okay";
+ lvds-to-hdmi-bridge@4c {
+ compatible = "ite,it6263";
+ reg = <0x4c>;
+ port {
+ it6263_1_in: endpoint {
+ clock-lanes = <3>;
+ data-lanes = <0 1 2 4>;
+ remote-endpoint = <&lvds1_out>;
+ };
+ };
+ };
+ };
+
+ camera: camera {
+ compatible = "fsl,mxc-md";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ isi_0: isi@58100000 {
+ compatible = "fsl,imx8-isi";
+ reg = <0x0 0x58100000 0x0 0x10000>;
+ interrupts = <0 297 0>;
+ interface = <2 0 2>; /* <Input MIPI_VCx Output>
+ Input: 0-DC0, 1-DC1, 2-MIPI CSI0, 3-MIPI CSI1, 4-HDMI, 5-MEM
+ VCx: 0-VC0, 1-VC1, 2-VC2, 3-VC3, MIPI CSI only
+ Output: 0-DC0, 1-DC1, 2-MEM */
+ clocks = <&clk IMX8QM_IMG_PDMA_0_CLK>;
+ clock-names = "per";
+ assigned-clocks = <&clk IMX8QM_IMG_PDMA_0_CLK>;
+ assigned-clock-rates = <600000000>;
+ power-domains =<&pd_isi_ch0>;
+ low_latency;
+ status = "okay";
+ };
+
+ isi_1: isi@58110000 {
+ compatible = "fsl,imx8-isi";
+ reg = <0x0 0x58110000 0x0 0x10000>;
+ interrupts = <0 298 0>;
+ interface = <2 1 2>;
+ clocks = <&clk IMX8QM_IMG_PDMA_1_CLK>;
+ clock-names = "per";
+ assigned-clocks = <&clk IMX8QM_IMG_PDMA_1_CLK>;
+ assigned-clock-rates = <600000000>;
+ power-domains =<&pd_isi_ch1>;
+ low_latency;
+ status = "okay";
+ };
+
+ isi_2: isi@58120000 {
+ compatible = "fsl,imx8-isi";
+ reg = <0x0 0x58120000 0x0 0x10000>;
+ interrupts = <0 299 0>;
+ interface = <2 2 2>;
+ clocks = <&clk IMX8QM_IMG_PDMA_2_CLK>;
+ clock-names = "per";
+ assigned-clocks = <&clk IMX8QM_IMG_PDMA_2_CLK>;
+ assigned-clock-rates = <600000000>;
+ power-domains =<&pd_isi_ch2>;
+ low_latency;
+ status = "okay";
+ };
+
+ isi_3: isi@58130000 {
+ compatible = "fsl,imx8-isi";
+ reg = <0x0 0x58130000 0x0 0x10000>;
+ interrupts = <0 300 0>;
+ interface = <2 3 2>;
+ clocks = <&clk IMX8QM_IMG_PDMA_3_CLK>;
+ clock-names = "per";
+ assigned-clocks = <&clk IMX8QM_IMG_PDMA_3_CLK>;
+ assigned-clock-rates = <600000000>;
+ power-domains =<&pd_isi_ch3>;
+ low_latency;
+ status = "okay";
+ };
+
+ mipi_csi_0: csi@58227000 {
+ compatible = "fsl,mxc-mipi-csi2";
+ reg = <0x0 0x58227000 0x0 0x1000>, /* CSI0 Controler base addr */
+ <0x0 0x58221000 0x0 0x1000>; /* CSI0 Subsystem CSR base addr */
+ interrupts = <10 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-parent = <&irqsteer_csi0>;
+ clocks = <&clk IMX8QM_CLK_DUMMY>,
+ <&clk_post IMX8QM_CSI0_CORE_CLK>,
+ <&clk_post IMX8QM_CSI0_ESC_CLK>,
+ <&clk IMX8QM_IMG_PXL_LINK_CSI0_CLK>;
+ clock-names = "clk_apb", "clk_core", "clk_esc", "clk_pxl";
+ assigned-clocks = <&clk_post IMX8QM_CSI0_CORE_CLK>,
+ <&clk_post IMX8QM_CSI0_ESC_CLK>;
+ assigned-clock-rates = <360000000>, <72000000>;
+ power-domains = <&pd_csi0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ virtual-channel;
+ status = "okay";
+
+ /* Camera 0 MIPI CSI-2 (CSIS0) */
+ port@0 {
+ reg = <0>;
+ mipi_csi0_ep: endpoint {
+ remote-endpoint = <&max9286_0_ep>;
+ data-lanes = <1 2 3 4>;
+ };
+ };
+ };
+ };
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8qm-mek-domu-dpu1-hdmi.dts b/arch/arm64/boot/dts/freescale/fsl-imx8qm-mek-domu-dpu1-hdmi.dts
new file mode 100644
index 000000000000..74641490a692
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8qm-mek-domu-dpu1-hdmi.dts
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2018 NXP
+ *
+ * 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 "fsl-imx8qm-mek-domu-dpu1.dts"
+
+/ {
+ /* Sound not enabled */
+};
+
+&ldb1_phy {
+ status = "okay";
+};
+
+&ldb1 {
+ status = "okay";
+};
+
+&i2c1_lvds0 {
+ status = "okay";
+};
+
+&hdmi {
+ compatible = "fsl,imx8qm-hdmi";
+ assigned-clocks = <&clk IMX8QM_HDMI_PXL_SEL>,
+ <&clk IMX8QM_HDMI_PXL_LINK_SEL>,
+ <&clk IMX8QM_HDMI_PXL_MUX_SEL>;
+ assigned-clock-parents = <&clk IMX8QM_HDMI_AV_PLL_CLK>,
+ <&clk IMX8QM_HDMI_AV_PLL_CLK>,
+ <&clk IMX8QM_HDMI_AV_PLL_CLK>;
+ fsl,cec;
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8qm-mek-domu-dpu1.dts b/arch/arm64/boot/dts/freescale/fsl-imx8qm-mek-domu-dpu1.dts
new file mode 100644
index 000000000000..cc866abd07db
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8qm-mek-domu-dpu1.dts
@@ -0,0 +1,991 @@
+/*
+ * Copyright 2018 NXP
+ *
+ * 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.
+ */
+
+/dts-v1/;
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/clock/imx8qm-clock.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/soc/imx_rsrc.h>
+#include <dt-bindings/soc/imx8_hsio.h>
+#include <dt-bindings/soc/imx8_pd.h>
+#include <dt-bindings/pinctrl/pads-imx8qm.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/thermal/thermal.h>
+
+/ {
+ model = "Freescale i.MX8QM DOMU";
+ compatible = "fsl,imx8qm-mek", "fsl,imx8qm", "xen,xenvm-4.10", "xen,xenvm";
+ interrupt-parent = <&gic>;
+ #address-cells = <0x2>;
+ #size-cells = <0x2>;
+
+ /delete-node/ aliases;
+
+ aliases {
+ mmc0 = &usdhc1;
+ dpu0 = &dpu1;
+ ldb0 = &ldb1;
+ serial1 = &lpuart1;
+ isi0 = &isi_0;
+ isi1 = &isi_1;
+ isi2 = &isi_2;
+ isi3 = &isi_3;
+ csi0 = &mipi_csi_0;
+ };
+
+ cpus {
+ #address-cells = <0x2>;
+ #size-cells = <0x0>;
+
+ cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,armv8";
+ enable-method = "psci";
+ reg = <0x0 0x0>;
+ };
+
+ cpu@1 {
+ device_type = "cpu";
+ compatible = "arm,armv8";
+ enable-method = "psci";
+ reg = <0x0 0x1>;
+ };
+ };
+
+ psci {
+ compatible = "arm,psci-1.0";
+ method = "hvc";
+ };
+
+ memory@80000000 {
+ device_type = "memory";
+ /* Will be updated by U-Boot or XEN TOOL */
+ reg = <0x00000000 0x80000000 0 0x80000000>;
+ };
+
+ /*
+ * The reserved memory will be used when using U-Boot loading android
+ * image. For booting kernel using xl tool, pass args:
+ * cma=960M@2400M-3584M
+ * For the rpmsg_reserved area, need xl tool to create for non-android.
+ */
+ reserved-memory {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+ passthrough;
+
+ /*
+ * reserved-memory layout
+ * 0x8800_0000 ~ 0x8FFF_FFFF is reserved for M4
+ * Shouldn't be used at A core and Linux side.
+ *
+ */
+
+ decoder_boot: decoder_boot@0x84000000 {
+ no-map;
+ reg = <0 0x84000000 0 0x2000000>;
+ };
+ encoder_boot: encoder_boot@0x86000000 {
+ no-map;
+ reg = <0 0x86000000 0 0x400000>;
+ };
+ /*
+ * CM40 rpmsg memory is still for Dom0, the domu.cfg
+ * not map 0x90000000 - 0x90100000 to DomU.
+ */
+ rpmsg_reserved: rpmsg@0x90000000 {
+ no-map;
+ reg = <0 0x90000000 0 0x400000>;
+ };
+ rpmsg_dma_reserved:rpmsg_dma@0x90400000 {
+ compatible = "shared-dma-pool";
+ no-map;
+ reg = <0 0x90400000 0 0x1C00000>;
+ };
+ decoder_rpc: decoder_rpc@0x92000000 {
+ no-map;
+ reg = <0 0x92000000 0 0x200000>;
+ };
+ encoder_rpc: encoder_rpc@0x92200000 {
+ no-map;
+ reg = <0 0x92200000 0 0x200000>;
+ };
+
+ encoder_reserved: encoder_reserved@0x94400000 {
+ no-map;
+ reg = <0 0x94400000 0 0x800000>;
+ };
+
+ /* global autoconfigured region for contiguous allocations */
+ linux,cma {
+ compatible = "shared-dma-pool";
+ reusable;
+ size = <0 0x3c000000>;
+ alloc-ranges = <0 0x96000000 0 0x3c000000>;
+ linux,cma-default;
+ };
+ };
+
+ gic: interrupt-controller@3001000 {
+ compatible = "arm,gic-v3";
+ #interrupt-cells = <3>;
+ #address-cells = <0x0>;
+ interrupt-controller;
+ redistributor-stride = <0x20000>;
+ #redistributor-regions = <0x1>;
+ reg = <0x0 0x3001000 0 0x10000>, /* GIC Dist */
+ <0x0 0x3020000 0 0x1000000>; /* GICR */
+ interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_HIGH)>;
+ interrupt-parent = <&gic>;
+ linux,phandle = <0xfde8>;
+ phandle = <0xfde8>;
+ };
+
+ timer {
+ compatible = "arm,armv8-timer";
+ interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>;
+ interrupt-parent = <&gic>;
+ clock-frequency = <8000000>;
+ };
+
+ hypervisor {
+ compatible = "xen,xen-4.11", "xen,xen";
+ reg = <0x0 0x38000000 0x0 0x1000000>;
+ interrupts = <GIC_PPI 15 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>;
+ interrupt-parent = <&gic>;
+ };
+
+ passthrough {
+ compatible = "simple-bus";
+ ranges;
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ firmware {
+ android {
+ compatible = "android,firmware";
+ fstab {
+ compatible = "android,fstab";
+ vendor {
+ compatible = "android,vendor";
+ /* emmc node which used if androidboot.storage_type=emmc */
+ dev_emmc = "/dev/block/platform/passthrough/5b010000.usdhc/by-name/vendor";
+ type = "ext4";
+ mnt_flags = "ro,barrier=1,inode_readahead_blks=8";
+ fsmgr_flags = "wait,slotselect,avb";
+ };
+ };
+
+ vbmeta {
+ /*we need use FirstStageMountVBootV2 if we enable avb*/
+ compatible = "android,vbmeta";
+ /*parts means the partition witch can be mount in first stage*/
+ parts = "vbmeta,boot,system,vendor";
+ };
+ };
+ };
+
+ mu_m0: mu_m0@2d000000 {
+ compatible = "fsl,imx8-mu0-vpu-m0";
+ reg = <0x0 0x2d000000 0x0 0x20000>;
+ interrupts = <GIC_SPI 472 IRQ_TYPE_LEVEL_HIGH>;
+ fsl,vpu_ap_mu_id = <16>;
+ status = "okay";
+ };
+
+ mu1_m0: mu1_m0@2d020000 {
+ compatible = "fsl,imx8-mu1-vpu-m0";
+ reg = <0x0 0x2d020000 0x0 0x20000>;
+ interrupts = <GIC_SPI 473 IRQ_TYPE_LEVEL_HIGH>;
+ fsl,vpu_ap_mu_id = <17>;
+ status = "okay";
+ };
+ mu2_m0: mu2_m0@2d040000 {
+ compatible = "fsl,imx8-mu2-vpu-m0";
+ reg = <0x0 0x2d040000 0x0 0x20000>;
+ interrupts = <GIC_SPI 474 IRQ_TYPE_LEVEL_HIGH>;
+ fsl,vpu_ap_mu_id = <18>;
+ status = "okay";
+ };
+
+ vpu_decoder: vpu_decoder@2c000000 {
+ compatible = "nxp,imx8qm-b0-vpudec", "nxp,imx8qxp-b0-vpudec";
+ boot-region = <&decoder_boot>;
+ rpc-region = <&decoder_rpc>;
+ reg = <0x0 0x2c000000 0x0 0x1000000>;
+ reg-names = "vpu_regs";
+ reg-csr = <0x2d080000>;
+ power-domains = <&pd_vpu_dec>;
+ status = "disabled";
+ };
+
+ vpu_encoder: vpu_encoder@2d000000 {
+ compatible = "nxp,imx8qm-b0-vpuenc";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ boot-region = <&encoder_boot>;
+ rpc-region = <&encoder_rpc>;
+ reserved-region = <&encoder_reserved>;
+ reg = <0x0 0x2d000000 0x0 0x1000000>, /*VPU Encoder*/
+ <0x0 0x2c000000 0x0 0x2000000>; /*VPU*/
+ reg-names = "vpu_regs";
+ power-domains = <&pd_vpu_enc>;
+ reg-rpc-system = <0x40000000>;
+
+ resolution-max = <1920 1080>;
+ fps-max = <120>;
+ status = "disabled";
+
+ core0@1020000 {
+ compatible = "fsl,imx8-mu1-vpu-m0";
+ reg = <0x1020000 0x20000>;
+ reg-csr = <0x1090000 0x10000>;
+ interrupts = <GIC_SPI 473 IRQ_TYPE_LEVEL_HIGH>;
+ fsl,vpu_ap_mu_id = <17>;
+ fw-buf-size = <0x200000>;
+ rpc-buf-size = <0x80000>;
+ print-buf-size = <0x80000>;
+ };
+ core1@1040000 {
+ compatible = "fsl,imx8-mu2-vpu-m0";
+ reg = <0x1040000 0x20000>;
+ reg-csr = <0x10a0000 0x10000>;
+ interrupts = <GIC_SPI 474 IRQ_TYPE_LEVEL_HIGH>;
+ fsl,vpu_ap_mu_id = <18>;
+ fw-buf-size = <0x200000>;
+ rpc-buf-size = <0x80000>;
+ print-buf-size = <0x80000>;
+ };
+ };
+
+ clk: clk {
+ compatible = "fsl,imx8qm-clk";
+ #clock-cells = <1>;
+ fsl,lpcg_base_offset = <0x00000000 0x00000000>;
+ };
+
+ iomuxc: iomuxc {
+ compatible = "fsl,imx8qm-iomuxc";
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ epdev_on: fixedregulator@100 {
+ compatible = "regulator-fixed";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-name = "epdev_on";
+ gpio = <&gpio4 9 0>;
+ enable-active-high;
+ };
+ };
+
+ #include "fsl-imx8qm-device.dtsi"
+
+ mu2: mu@5d1d0000 {
+ compatible = "fsl,imx8-mu";
+ reg = <0x0 0x5d1d0000 0x0 0x10000>;
+ interrupts = <GIC_SPI 178 IRQ_TYPE_LEVEL_HIGH>;
+ fsl,scu_ap_mu_id = <0>;
+ status = "okay";
+ };
+
+ usb_lpcg {
+ reg = <0x0 0x5b270000 0x0 0x10000>;
+ };
+
+ edma01: dma-controller1@5a1f0000 {
+ compatible = "fsl,imx8qm-edma";
+ reg = <0x0 0x5a2e0000 0x0 0x10000>, /* channel14 UART1 rx */
+ <0x0 0x5a2f0000 0x0 0x10000>; /* channel15 UART1 tx */
+ #dma-cells = <3>;
+ dma-channels = <2>;
+ interrupts = <GIC_SPI 436 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 437 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "edma0-chan14-rx", "edma0-chan15-tx";
+ status = "okay";
+ };
+
+ xen_i2c0: xen_i2c@0 {
+ compatible = "xen,i2c";
+ be-adapter = "5a800000.i2c";
+ status = "okay";
+ };
+ };
+};
+
+/delete-node/ &tsens;
+/delete-node/ &thermal_zones;
+/delete-node/ &rtc;
+
+&display {
+ ports = <&dpu1_disp0>, <&dpu1_disp1>;
+};
+
+&dpu1_intsteer {
+ status = "okay";
+};
+
+&prg1 {
+ status = "okay";
+};
+
+&prg2 {
+ status = "okay";
+};
+
+&prg3 {
+ status = "okay";
+};
+
+&prg4 {
+ status = "okay";
+};
+
+&prg5 {
+ status = "okay";
+};
+
+&prg6 {
+ status = "okay";
+};
+
+&prg7 {
+ status = "okay";
+};
+
+&prg8 {
+ status = "okay";
+};
+
+&prg9 {
+ status = "okay";
+};
+
+&dpr1_channel1 {
+ status = "okay";
+};
+
+&dpr1_channel2 {
+ status = "okay";
+};
+
+&dpr1_channel3 {
+ status = "okay";
+};
+
+&dpr2_channel1 {
+ status = "okay";
+};
+
+&dpr2_channel2 {
+ status = "okay";
+};
+
+&dpr2_channel3 {
+ status = "okay";
+};
+
+&dpu1 {
+ status = "okay";
+};
+
+&pixel_combiner1 {
+ status = "okay";
+};
+
+&hdmi {
+ status = "disabled";
+};
+
+/*/delete-node/ &irqsteer_dsi0;*/
+/*/delete-node/ &i2c0_mipi_dsi0;*/
+/*/delete-node/ &mipi_dsi_csr1;*/
+/*/delete-node/ &mipi_dsi_phy1;*/
+/*/delete-node/ &mipi_dsi1;*/
+/*/delete-node/ &mipi_dsi_bridge1;*/
+
+&lvds_region1 {
+ status = "okay";
+};
+
+&ldb1_phy {
+ status = "okay";
+};
+
+&ldb1 {
+ status = "okay";
+
+ lvds-channel@0 {
+ fsl,data-mapping = "jeida";
+ fsl,data-width = <24>;
+ status = "okay";
+
+ port@1 {
+ reg = <1>;
+
+ lvds0_out: endpoint {
+ remote-endpoint = <&it6263_0_in>;
+ };
+ };
+ };
+};
+
+/delete-node/ &dpu2_intsteer;
+/delete-node/ &prg10;
+/delete-node/ &prg11;
+/delete-node/ &prg12;
+/delete-node/ &prg13;
+/delete-node/ &prg14;
+/delete-node/ &prg15;
+/delete-node/ &prg16;
+/delete-node/ &prg17;
+/delete-node/ &prg18;
+/delete-node/ &dpr3_channel1;
+/delete-node/ &dpr3_channel2;
+/delete-node/ &dpr3_channel3;
+/delete-node/ &dpr4_channel1;
+/delete-node/ &dpr4_channel2;
+/delete-node/ &dpr4_channel3;
+/delete-node/ &dpu2;
+/delete-node/ &pixel_combiner2;
+/delete-node/ &dsp;
+/delete-node/ &irqsteer_dsi1;
+/delete-node/ &i2c0_mipi_dsi1;
+/delete-node/ &mipi_dsi_csr2;
+/delete-node/ &mipi_dsi_phy2;
+/delete-node/ &mipi_dsi2;
+/delete-node/ &mipi_dsi_bridge2;
+/delete-node/ &lvds_region2;
+/delete-node/ &ldb2_phy;
+/delete-node/ &ldb2;
+/delete-node/ &lvds1_pwm;
+/*/delete-node/ &camera;*/
+/delete-node/ &adc0;
+/delete-node/ &adc1;
+/delete-node/ &i2c0;
+/delete-node/ &i2c1;
+/delete-node/ &i2c2;
+/delete-node/ &i2c3;
+/delete-node/ &i2c4;
+/delete-node/ &i2c0_cm40;
+/delete-node/ &i2c0_cm41;
+&irqsteer_hdmi {
+ status = "okay";
+};
+/*/delete-node/ &i2c0_hdmi;*/
+&irqsteer_hdmi_rx {
+ status = "okay";
+};
+/delete-node/ &irqsteer_lvds1;
+/delete-node/ &flexcan1;
+/delete-node/ &flexcan2;
+/delete-node/ &flexcan3;
+/delete-node/ &i2c1_lvds1;
+&irqsteer_lvds0 {
+ /delete-property/ interrupt-parent;
+ status = "okay";
+};
+
+&i2c1_lvds0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lvds0_lpi2c1>;
+ clock-frequency = <100000>;
+ status = "okay";
+
+ lvds-to-hdmi-bridge@4c {
+ compatible = "ite,it6263";
+ reg = <0x4c>;
+
+ port {
+ it6263_0_in: endpoint {
+ clock-lanes = <3>;
+ data-lanes = <0 1 2 4>;
+ remote-endpoint = <&lvds0_out>;
+ };
+ };
+ };
+};
+
+&lvds0_pwm {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lvds0_pwm0>;
+ status = "okay";
+};
+
+/*/delete-node/ &irqsteer_csi0;*/
+/*/delete-node/ &i2c0_mipi_csi0;*/
+/delete-node/ &irqsteer_csi1;
+/delete-node/ &i2c0_mipi_csi1;
+/delete-node/ &lpspi0;
+/delete-node/ &lpspi3;
+/delete-node/ &lpuart0;
+
+&lpuart1 {
+ /delete-property/ interrupt-parent;
+ reg = <0x0 0x5a070000 0 0x1000>;
+ dmas = <&edma01 15 0 0>, <&edma01 14 0 1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lpuart1>;
+ status = "okay";
+};
+
+/delete-node/ &lpuart2;
+/delete-node/ &lpuart3;
+/delete-node/ &lpuart4;
+/delete-node/ &emvsim0;
+/delete-node/ &edma0;
+/delete-node/ &edma2;
+/delete-node/ &edma3;
+&gpio0 {
+ /delete-property/ power-domains;
+ status = "disabled";
+};
+&gpio1 {
+ /delete-property/ power-domains;
+ status = "okay";
+};
+&gpio2 {
+ /delete-property/ power-domains;
+ status = "disabled";
+};
+&gpio3 {
+ /delete-property/ power-domains;
+ status = "disabled";
+};
+&gpio4 {
+ /delete-property/ power-domains;
+ status = "okay";
+};
+&gpio5 {
+ /delete-property/ power-domains;
+ status = "disabled";
+};
+&gpio6 {
+ /delete-property/ power-domains;
+ status = "disabled";
+};
+&gpio7 {
+ /delete-property/ power-domains;
+ status = "disabled";
+};
+
+/*/delete-node/ &gpio0_mipi_csi0;*/
+/delete-node/ &gpio0_mipi_csi1;
+/delete-node/ &gpt0;
+/delete-node/ &pwm0;
+/delete-node/ &pwm1;
+/delete-node/ &pwm2;
+/delete-node/ &pwm3;
+/delete-node/ &pwm4;
+/delete-node/ &pwm5;
+/delete-node/ &pwm6;
+/delete-node/ &pwm7;
+
+&gpu_3d0 {
+ status = "okay";
+};
+
+/delete-node/ &gpu_3d1;
+
+&imx8_gpu_ss {
+ /* xen guests have 2GB of low RAM @ 2GB */
+ reg = <0x0 0x80000000 0x0 0x80000000>;
+ reg-names = "phys_baseaddr";
+ cores = <&gpu_3d0>;
+ status = "okay";
+};
+
+/delete-node/ &mlb;
+
+&usdhc1 {
+ compatible = "fsl,imx8qm-usdhc", "fsl,imx6sl-usdhc";
+ /*interrupt-parent = <&gic>;*/
+ /delete-property/ interrupt-parent;
+ reg = <0x0 0x5b010000 0x0 0x10000>;
+};
+
+/delete-node/ &usdhc2;
+/delete-node/ &usdhc3;
+/delete-node/ &fec1;
+/delete-node/ &fec2;
+
+&usbmisc1 {
+ reg = <0x0 0x5b0d0200 0x0 0x200>;
+};
+
+&usbmisc2 {
+ status = "okay";
+};
+
+&usbphy1 {
+ reg = <0x0 0x5b100000 0x0 0x200>;
+};
+
+/delete-node/ &usbh1;
+
+&usbotg3 {
+ /delete-property/ interrupt-parent;
+ dr_mode = "otg";
+ extcon = <&typec_ptn5110>;
+ status = "okay";
+};
+
+&usbphynop1 {
+ status = "okay";
+};
+
+/delete-node/ &usbphynop2;
+
+&usbotg1 {
+ reg = <0x0 0x5b0d0000 0x0 0x200>;
+ /delete-property/ interrupt-parent;
+};
+
+/delete-node/ &ddr_pmu0;
+/delete-node/ &ddr_pmu1;
+/delete-node/ &vpu;
+/delete-node/ &acm;
+/delete-node/ &esai0;
+/delete-node/ &esai1;
+/delete-node/ &spdif0;
+/delete-node/ &spdif1;
+/delete-node/ &sai1;
+/delete-node/ &sai0;
+/delete-node/ &sai2;
+/delete-node/ &sai3;
+/delete-node/ &sai_hdmi_rx;
+/delete-node/ &sai_hdmi_tx;
+/delete-node/ &sai6;
+/delete-node/ &sai7;
+/delete-node/ &amix;
+/delete-node/ &asrc0;
+/delete-node/ &asrc1;
+/delete-node/ &mqs;
+/delete-node/ &flexspi0;
+
+&dma_cap {
+ compatible = "dma-capability";
+ only-dma-mask32 = <1>;
+};
+
+/delete-node/ &ocotp;
+&pciea {
+ ext_osc = <1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pciea>;
+ disable-gpio = <&gpio1 13 GPIO_ACTIVE_LOW>;
+ reset-gpio = <&gpio4 29 GPIO_ACTIVE_LOW>;
+ clkreq-gpio = <&gpio4 27 GPIO_ACTIVE_LOW>;
+ epdev_on-supply = <&epdev_on>;
+ status = "okay";
+};
+/delete-node/ &pcieb;
+/delete-node/ &sata;
+
+/delete-node/ &intmux_cm40;
+/delete-node/ &intmux_cm41;
+
+&rpmsg1{
+ /*
+ * 64K for one rpmsg instance:
+ */
+ vdev-nums = <2>;
+ reg = <0x0 0x90100000 0x0 0x20000>;
+ status = "okay";
+};
+
+&mu_rpmsg1 {
+ reg = <0x0 0x5d210000 0x0 0x10000>;
+};
+
+/*/delete-node/ &crypto;*/
+/*/delete-node/ &caam_sm;*/
+/*/delete-node/ &sc_pwrkey;*/
+/delete-node/ &wdog;
+/delete-node/ &wu;
+
+&iomuxc {
+ imx8qm-mek {
+ pinctrl_usdhc1: usdhc1grp {
+ fsl,pins = <
+ SC_P_EMMC0_CLK_CONN_EMMC0_CLK 0x06000041
+ SC_P_EMMC0_CMD_CONN_EMMC0_CMD 0x00000021
+ SC_P_EMMC0_DATA0_CONN_EMMC0_DATA0 0x00000021
+ SC_P_EMMC0_DATA1_CONN_EMMC0_DATA1 0x00000021
+ SC_P_EMMC0_DATA2_CONN_EMMC0_DATA2 0x00000021
+ SC_P_EMMC0_DATA3_CONN_EMMC0_DATA3 0x00000021
+ SC_P_EMMC0_DATA4_CONN_EMMC0_DATA4 0x00000021
+ SC_P_EMMC0_DATA5_CONN_EMMC0_DATA5 0x00000021
+ SC_P_EMMC0_DATA6_CONN_EMMC0_DATA6 0x00000021
+ SC_P_EMMC0_DATA7_CONN_EMMC0_DATA7 0x00000021
+ SC_P_EMMC0_STROBE_CONN_EMMC0_STROBE 0x06000041
+ SC_P_EMMC0_RESET_B_CONN_EMMC0_RESET_B 0x00000021
+ >;
+ };
+
+ pinctrl_usdhc1_100mhz: usdhc1grp100mhz {
+ fsl,pins = <
+ SC_P_EMMC0_CLK_CONN_EMMC0_CLK 0x06000040
+ SC_P_EMMC0_CMD_CONN_EMMC0_CMD 0x00000020
+ SC_P_EMMC0_DATA0_CONN_EMMC0_DATA0 0x00000020
+ SC_P_EMMC0_DATA1_CONN_EMMC0_DATA1 0x00000020
+ SC_P_EMMC0_DATA2_CONN_EMMC0_DATA2 0x00000020
+ SC_P_EMMC0_DATA3_CONN_EMMC0_DATA3 0x00000020
+ SC_P_EMMC0_DATA4_CONN_EMMC0_DATA4 0x00000020
+ SC_P_EMMC0_DATA5_CONN_EMMC0_DATA5 0x00000020
+ SC_P_EMMC0_DATA6_CONN_EMMC0_DATA6 0x00000020
+ SC_P_EMMC0_DATA7_CONN_EMMC0_DATA7 0x00000020
+ SC_P_EMMC0_STROBE_CONN_EMMC0_STROBE 0x06000040
+ SC_P_EMMC0_RESET_B_CONN_EMMC0_RESET_B 0x00000020
+ >;
+ };
+
+ pinctrl_usdhc1_200mhz: usdhc1grp200mhz {
+ fsl,pins = <
+ SC_P_EMMC0_CLK_CONN_EMMC0_CLK 0x06000040
+ SC_P_EMMC0_CMD_CONN_EMMC0_CMD 0x00000020
+ SC_P_EMMC0_DATA0_CONN_EMMC0_DATA0 0x00000020
+ SC_P_EMMC0_DATA1_CONN_EMMC0_DATA1 0x00000020
+ SC_P_EMMC0_DATA2_CONN_EMMC0_DATA2 0x00000020
+ SC_P_EMMC0_DATA3_CONN_EMMC0_DATA3 0x00000020
+ SC_P_EMMC0_DATA4_CONN_EMMC0_DATA4 0x00000020
+ SC_P_EMMC0_DATA5_CONN_EMMC0_DATA5 0x00000020
+ SC_P_EMMC0_DATA6_CONN_EMMC0_DATA6 0x00000020
+ SC_P_EMMC0_DATA7_CONN_EMMC0_DATA7 0x00000020
+ SC_P_EMMC0_STROBE_CONN_EMMC0_STROBE 0x06000040
+ SC_P_EMMC0_RESET_B_CONN_EMMC0_RESET_B 0x00000020
+ >;
+ };
+
+ pinctrl_usbotg1: usbotg1 {
+ fsl,pins = <
+ SC_P_USB_SS3_TC0_CONN_USB_OTG1_PWR 0x00000021
+ >;
+ };
+
+ pinctrl_lvds0_lpi2c1: lvds0lpi2c1grp {
+ fsl,pins = <
+ SC_P_LVDS0_I2C1_SCL_LVDS0_I2C1_SCL 0xc600004c
+ SC_P_LVDS0_I2C1_SDA_LVDS0_I2C1_SDA 0xc600004c
+ >;
+ };
+
+ pinctrl_lpuart1: lpuart1grp {
+ fsl,pins = <
+ SC_P_UART1_RX_DMA_UART1_RX 0x06000020
+ SC_P_UART1_TX_DMA_UART1_TX 0x06000020
+ SC_P_UART1_CTS_B_DMA_UART1_CTS_B 0x06000020
+ SC_P_UART1_RTS_B_DMA_UART1_RTS_B 0x06000020
+ SC_P_QSPI1A_DQS_LSIO_GPIO4_IO22 0x00000021
+ >;
+ };
+
+ pinctrl_pciea: pcieagrp{
+ fsl,pins = <
+ SC_P_PCIE_CTRL0_CLKREQ_B_LSIO_GPIO4_IO27 0x06000021
+ SC_P_PCIE_CTRL0_WAKE_B_LSIO_GPIO4_IO28 0x04000021
+ SC_P_PCIE_CTRL0_PERST_B_LSIO_GPIO4_IO29 0x06000021
+ SC_P_LVDS1_I2C0_SDA_LSIO_GPIO1_IO13 0x06000000
+ SC_P_USDHC2_RESET_B_LSIO_GPIO4_IO09 0x06000021
+ >;
+ };
+
+ pinctrl_typec: typecgrp {
+ fsl,pins = <
+ SC_P_QSPI1A_SS0_B_LSIO_GPIO4_IO19 0x60
+ SC_P_USB_SS3_TC3_LSIO_GPIO4_IO06 0x60
+ SC_P_QSPI1A_DATA0_LSIO_GPIO4_IO26 0x00000021
+ >;
+ };
+
+ pinctrl_isl29023: isl29023grp {
+ fsl,pins = <
+ SC_P_USDHC2_WP_LSIO_GPIO4_IO11 0x00000021
+ >;
+ };
+
+ pinctrl_lvds0_pwm0: lvds0pwm0grp {
+ fsl,pins = <
+ SC_P_LVDS0_GPIO00_LVDS0_PWM0_OUT 0x00000020
+ >;
+ };
+ };
+};
+
+&usdhc1 {
+ /delete-property/ iommus;
+ pinctrl-names = "default", "state_100mhz", "state_200mhz";
+ pinctrl-0 = <&pinctrl_usdhc1>;
+ pinctrl-1 = <&pinctrl_usdhc1_100mhz>;
+ pinctrl-2 = <&pinctrl_usdhc1_200mhz>;
+ bus-width = <8>;
+ non-removable;
+ status = "okay";
+};
+
+&usbotg1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usbotg1>;
+ srp-disable;
+ hnp-disable;
+ adp-disable;
+ power-polarity-active-high;
+ disable-over-current;
+ status = "okay";
+};
+
+&vpu_decoder {
+ core_type = <2>;
+ status = "okay";
+};
+
+&vpu_encoder {
+ status = "okay";
+};
+
+&xen_i2c0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clock-frequency = <100000>;
+ status = "okay";
+
+ isl29023@44 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_isl29023>;
+ compatible = "fsl,isl29023";
+ reg = <0x44>;
+ rext = <499>;
+ interrupt-parent = <&gpio4>;
+ interrupts = <11 2>;
+ };
+
+ fxos8700@1e {
+ compatible = "fsl,fxos8700";
+ reg = <0x1e>;
+ interrupt-open-drain;
+ };
+
+ fxas2100x@20 {
+ compatible = "fsl,fxas2100x";
+ reg = <0x20>;
+ interrupt-open-drain;
+ };
+
+ mpl3115@60 {
+ compatible = "fsl,mpl3115";
+ reg = <0x60>;
+ interrupt-open-drain;
+ };
+
+ typec_ptn5110: typec@50 {
+ compatible = "usb,tcpci";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_typec>;
+ reg = <0x51>;
+ interrupt-parent = <&gpio4>;
+ interrupts = <26 IRQ_TYPE_LEVEL_LOW>;
+ ss-sel-gpios = <&gpio4 6 GPIO_ACTIVE_LOW>;
+ reset-gpios = <&gpio4 19 GPIO_ACTIVE_HIGH>;
+ src-pdos = <0x380190c8 0x3803c0c8>;
+ port-type = "drp";
+ sink-disable;
+ default-role = "source";
+ status = "okay";
+ };
+};
+
+/* Camera */
+/delete-node/ &isi_4;
+/delete-node/ &isi_5;
+/delete-node/ &isi_6;
+/delete-node/ &isi_7;
+/delete-node/ &mipi_csi_1;
+/delete-node/ &jpegdec;
+/delete-node/ &jpegenc;
+
+&gpio0_mipi_csi0 {
+ status = "okay";
+};
+
+&irqsteer_csi0 {
+ status = "okay";
+};
+
+&isi_0 {
+ status = "okay";
+};
+
+&isi_1 {
+ status = "okay";
+};
+
+&isi_2 {
+ status = "okay";
+};
+
+&isi_3 {
+ status = "okay";
+};
+
+&mipi_csi_0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ virtual-channel;
+ status = "okay";
+
+ /* Camera 0 MIPI CSI-2 (CSIS0) */
+ port@0 {
+ reg = <0>;
+ mipi_csi0_ep: endpoint {
+ remote-endpoint = <&max9286_0_ep>;
+ data-lanes = <1 2 3 4>;
+ };
+ };
+};
+
+&i2c0_mipi_csi0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ clock-frequency = <100000>;
+ status = "okay";
+
+
+ max9286_mipi@6A {
+ compatible = "maxim,max9286_mipi";
+ reg = <0x6A>;
+ clocks = <&clk IMX8QM_CLK_DUMMY>;
+ clock-names = "capture_mclk";
+ mclk = <27000000>;
+ mclk_source = <0>;
+ pwn-gpios = <&gpio1 27 GPIO_ACTIVE_HIGH>;
+ virtual-channel;
+ port {
+ max9286_0_ep: endpoint {
+ remote-endpoint = <&mipi_csi0_ep>;
+ data-lanes = <1 2 3 4>;
+ };
+ };
+ };
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8qm-mek-domu-hdmi.dts b/arch/arm64/boot/dts/freescale/fsl-imx8qm-mek-domu-hdmi.dts
new file mode 100644
index 000000000000..af28b24b77ec
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8qm-mek-domu-hdmi.dts
@@ -0,0 +1,98 @@
+/*
+ * Copyright 2018 NXP
+ *
+ * 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 "fsl-imx8qm-mek-domu.dts"
+
+/*
+ * Currently we disable the audio part, since audio in domu not ready.
+ * This file is reused from fsl-imx8qm-mek-hdmi.dts.
+ */
+
+/ {
+ passthrough {
+ /*
+ sound-hdmi-tx {
+ compatible = "fsl,imx-audio-cdnhdmi";
+ model = "imx-audio-hdmi-tx";
+ audio-cpu = <&sai_hdmi_tx>;
+ constraint-rate = <48000>;
+ protocol = <1>;
+ hdmi-out;
+ };
+
+ sound-amix-sai {
+ status = "disabled";
+ };
+
+ sound-hdmi-arc {
+ compatible = "fsl,imx-audio-spdif";
+ model = "imx-hdmi-arc";
+ spdif-controller = <&spdif1>;
+ spdif-in;
+ spdif-out;
+ };
+ */
+ };
+};
+
+&hdmi {
+ compatible = "fsl,imx8qm-hdmi";
+ assigned-clocks = <&clk IMX8QM_HDMI_PXL_SEL>,
+ <&clk IMX8QM_HDMI_PXL_LINK_SEL>,
+ <&clk IMX8QM_HDMI_PXL_MUX_SEL>;
+ assigned-clock-parents = <&clk IMX8QM_HDMI_AV_PLL_CLK>,
+ <&clk IMX8QM_HDMI_AV_PLL_CLK>,
+ <&clk IMX8QM_HDMI_AV_PLL_CLK>;
+ fsl,cec;
+ status = "okay";
+};
+
+/*
+&amix {
+ status = "disabled";
+};
+
+&sai6 {
+ status = "disabled";
+};
+
+&sai7 {
+ status = "disabled";
+};
+
+&sai_hdmi_tx {
+ assigned-clocks =<&clk IMX8QM_ACM_HDMI_TX_SAI0_MCLK_SEL>,
+ <&clk IMX8QM_AUD_PLL1_DIV>,
+ <&clk IMX8QM_AUD_ACM_AUD_PLL_CLK1_DIV>,
+ <&clk IMX8QM_AUD_ACM_AUD_REC_CLK1_DIV>,
+ <&clk IMX8QM_AUD_SAI_HDMITX0_MCLK>;
+ assigned-clock-parents = <&clk IMX8QM_AUD_ACM_AUD_PLL_CLK1_CLK>;
+ assigned-clock-rates = <0>, <768000000>, <768000000>, <768000000>, <768000000>;
+ fsl,sai-asynchronous;
+ status = "okay";
+};
+
+&sai_hdmi_rx {
+ fsl,sai-asynchronous;
+ status = "okay";
+};
+
+&spdif1 {
+ assigned-clocks =<&clk IMX8QM_AUD_PLL0_DIV>,
+ <&clk IMX8QM_AUD_ACM_AUD_PLL_CLK0_DIV>,
+ <&clk IMX8QM_AUD_ACM_AUD_REC_CLK0_DIV>;
+ assigned-clock-rates = <786432000>, <49152000>, <12288000>;
+ status = "okay";
+};
+*/
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8qm-mek-domu.dts b/arch/arm64/boot/dts/freescale/fsl-imx8qm-mek-domu.dts
new file mode 100644
index 000000000000..08bc1e05a235
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8qm-mek-domu.dts
@@ -0,0 +1,1269 @@
+/*
+ * Copyright 2018-2019 NXP
+ *
+ * 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.
+ */
+
+/dts-v1/;
+
+/*
+ * At current stage, M41 is not ready to communicate with XEN, so we
+ * we need a way to tell XEN uboot is running or linux is running.
+ * XEN will check the contents of this area.
+ * So reserve a page at the beginning of GUEST_RAM0_BASE to avoid Linux
+ * touch this area.
+ */
+/memreserve/ 0x80000000 0x1000;
+
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/clock/imx8qm-clock.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/soc/imx_rsrc.h>
+#include <dt-bindings/soc/imx8_hsio.h>
+#include <dt-bindings/soc/imx8_pd.h>
+#include <dt-bindings/pinctrl/pads-imx8qm.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/thermal/thermal.h>
+
+/ {
+ model = "Freescale i.MX8QM DOMU";
+ compatible = "fsl,imx8qm-mek", "fsl,imx8qm", "xen,xenvm-4.10", "xen,xenvm";
+ interrupt-parent = <&gic>;
+ #address-cells = <0x2>;
+ #size-cells = <0x2>;
+
+ /delete-node/ aliases;
+
+ aliases {
+ mmc0 = &usdhc1;
+ dpu1 = &dpu2;
+ ldb1 = &ldb2;
+ serial1 = &lpuart1;
+ isi0 = &isi_0;
+ isi1 = &isi_1;
+ isi2 = &isi_2;
+ isi3 = &isi_3;
+ csi0 = &mipi_csi_0;
+ i2c1 = &i2c_rpbus_1;
+ };
+
+ cpus {
+ #address-cells = <0x2>;
+ #size-cells = <0x0>;
+
+ cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,armv8";
+ enable-method = "psci";
+ reg = <0x0 0x0>;
+ };
+
+ cpu@1 {
+ device_type = "cpu";
+ compatible = "arm,armv8";
+ enable-method = "psci";
+ reg = <0x0 0x1>;
+ };
+
+ cpu@2 {
+ device_type = "cpu";
+ compatible = "arm,armv8";
+ enable-method = "psci";
+ reg = <0x0 0x2>;
+ };
+
+ cpu@3 {
+ device_type = "cpu";
+ compatible = "arm,armv8";
+ enable-method = "psci";
+ reg = <0x0 0x3>;
+ };
+ };
+
+ psci {
+ compatible = "arm,psci-1.0";
+ method = "hvc";
+ };
+
+ memory@80000000 {
+ device_type = "memory";
+ /* Will be updated by U-Boot or XEN TOOL */
+ reg = <0x00000000 0x80000000 0 0x80000000>;
+ };
+
+ /*
+ * The reserved memory will be used when using U-Boot loading android
+ * image. For booting kernel using xl tool, pass args:
+ * cma=960M@2400M-3584M
+ * For the rpmsg_reserved area, need xl tool to create for non-android.
+ */
+ reserved-memory {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+ passthrough;
+
+ /*
+ * reserved-memory layout
+ * 0x8800_0000 ~ 0x8FFF_FFFF is reserved for M4
+ * Shouldn't be used at A core and Linux side.
+ *
+ */
+
+ decoder_boot: decoder_boot@0x84000000 {
+ no-map;
+ reg = <0 0x84000000 0 0x2000000>;
+ };
+ encoder_boot: encoder_boot@0x86000000 {
+ no-map;
+ reg = <0 0x86000000 0 0x400000>;
+ };
+ /*
+ * CM40 rpmsg memory is still for Dom0, the domu.cfg
+ * not map 0x90000000 - 0x90100000 to DomU.
+ */
+ rpmsg_reserved: rpmsg@0x90000000 {
+ no-map;
+ reg = <0 0x90000000 0 0x400000>;
+ };
+ rpmsg_dma_reserved:rpmsg_dma@0x90400000 {
+ compatible = "shared-dma-pool";
+ no-map;
+ reg = <0 0x90400000 0 0x1C00000>;
+ };
+ decoder_rpc: decoder_rpc@0x92000000 {
+ no-map;
+ reg = <0 0x92000000 0 0x200000>;
+ };
+ encoder_rpc: encoder_rpc@0x92200000 {
+ no-map;
+ reg = <0 0x92200000 0 0x200000>;
+ };
+ dsp_reserved: dsp@0x92400000 {
+ no-map;
+ reg = <0 0x92400000 0 0x2000000>;
+ };
+ encoder_reserved: encoder_reserved@0x94400000 {
+ no-map;
+ reg = <0 0x94400000 0 0x800000>;
+ };
+
+ /* global autoconfigured region for contiguous allocations */
+ linux,cma {
+ compatible = "shared-dma-pool";
+ reusable;
+ size = <0 0x3c000000>;
+ alloc-ranges = <0 0x96000000 0 0x3c000000>;
+ linux,cma-default;
+ };
+ };
+
+ gic: interrupt-controller@3001000 {
+ compatible = "arm,gic-v3";
+ #interrupt-cells = <3>;
+ #address-cells = <0x0>;
+ interrupt-controller;
+ redistributor-stride = <0x20000>;
+ #redistributor-regions = <0x1>;
+ reg = <0x0 0x3001000 0 0x10000>, /* GIC Dist */
+ <0x0 0x3020000 0 0x1000000>; /* GICR */
+ interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_HIGH)>;
+ interrupt-parent = <&gic>;
+ linux,phandle = <0xfde8>;
+ phandle = <0xfde8>;
+ };
+
+ timer {
+ compatible = "arm,armv8-timer";
+ interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>;
+ interrupt-parent = <&gic>;
+ clock-frequency = <8000000>;
+ };
+
+ hypervisor {
+ compatible = "xen,xen-4.11", "xen,xen";
+ reg = <0x0 0x38000000 0x0 0x1000000>;
+ interrupts = <GIC_PPI 15 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>;
+ interrupt-parent = <&gic>;
+ };
+
+ clocks {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ clk0: clock@0 {
+ compatible = "fixed-clock";
+ reg = <0>;
+ #clock-cells = <0>;
+ clock-frequency = <24000000>;
+ };
+ };
+
+ rtc0: rtc@23000000 {
+ compatible = "arm,pl031", "arm,primecell";
+ reg = <0x0 0x23000000 0x0 0x1000>;
+ interrupts = <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk0>;
+ clock-names = "apb_pclk";
+ };
+
+ lvds_backlight1: lvds_backlight@1 {
+ compatible = "pwm-backlight";
+ pwms = <&lvds1_pwm 0 100000 0>;
+
+ brightness-levels = < 0 1 2 3 4 5 6 7 8 9
+ 10 11 12 13 14 15 16 17 18 19
+ 20 21 22 23 24 25 26 27 28 29
+ 30 31 32 33 34 35 36 37 38 39
+ 40 41 42 43 44 45 46 47 48 49
+ 50 51 52 53 54 55 56 57 58 59
+ 60 61 62 63 64 65 66 67 68 69
+ 70 71 72 73 74 75 76 77 78 79
+ 80 81 82 83 84 85 86 87 88 89
+ 90 91 92 93 94 95 96 97 98 99
+ 100>;
+ default-brightness-level = <80>;
+ };
+
+ passthrough {
+ compatible = "simple-bus";
+ ranges;
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ firmware {
+ android {
+ compatible = "android,firmware";
+ fstab {
+ compatible = "android,fstab";
+ vendor {
+ compatible = "android,vendor";
+ /* emmc node which used if androidboot.storage_type=emmc */
+ dev_emmc = "/dev/block/platform/passthrough/5b010000.usdhc/by-name/vendor";
+ type = "ext4";
+ mnt_flags = "ro,barrier=1,inode_readahead_blks=8";
+ fsmgr_flags = "wait,slotselect,avb";
+ };
+ };
+
+ vbmeta {
+ /*we need use FirstStageMountVBootV2 if we enable avb*/
+ compatible = "android,vbmeta";
+ /*parts means the partition witch can be mount in first stage*/
+ parts = "vbmeta,boot,system,vendor";
+ };
+ };
+ };
+
+ mu_m0: mu_m0@2d000000 {
+ compatible = "fsl,imx8-mu0-vpu-m0";
+ reg = <0x0 0x2d000000 0x0 0x20000>;
+ interrupts = <GIC_SPI 472 IRQ_TYPE_LEVEL_HIGH>;
+ fsl,vpu_ap_mu_id = <16>;
+ status = "okay";
+ };
+
+ mu1_m0: mu1_m0@2d020000 {
+ compatible = "fsl,imx8-mu1-vpu-m0";
+ reg = <0x0 0x2d020000 0x0 0x20000>;
+ interrupts = <GIC_SPI 473 IRQ_TYPE_LEVEL_HIGH>;
+ fsl,vpu_ap_mu_id = <17>;
+ status = "okay";
+ };
+ mu2_m0: mu2_m0@2d040000 {
+ compatible = "fsl,imx8-mu2-vpu-m0";
+ reg = <0x0 0x2d040000 0x0 0x20000>;
+ interrupts = <GIC_SPI 474 IRQ_TYPE_LEVEL_HIGH>;
+ fsl,vpu_ap_mu_id = <18>;
+ status = "okay";
+ };
+
+ mu13: mu13@5d280000 {
+ compatible = "fsl,imx8-mu-dsp";
+ reg = <0x0 0x5d280000 0x0 0x10000>;
+ interrupts = <GIC_SPI 192 IRQ_TYPE_LEVEL_HIGH>;
+ fsl,dsp_ap_mu_id = <13>;
+ status = "okay";
+ };
+
+
+ vpu_decoder: vpu_decoder@2c000000 {
+ compatible = "nxp,imx8qm-b0-vpudec", "nxp,imx8qxp-b0-vpudec";
+ boot-region = <&decoder_boot>;
+ rpc-region = <&decoder_rpc>;
+ reg = <0x0 0x2c000000 0x0 0x1000000>;
+ reg-names = "vpu_regs";
+ reg-csr = <0x2d080000>;
+ power-domains = <&pd_vpu_dec>;
+ status = "disabled";
+ };
+
+ vpu_encoder: vpu_encoder@2d000000 {
+ compatible = "nxp,imx8qm-b0-vpuenc";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ boot-region = <&encoder_boot>;
+ rpc-region = <&encoder_rpc>;
+ reserved-region = <&encoder_reserved>;
+ reg = <0x0 0x2d000000 0x0 0x1000000>, /*VPU Encoder*/
+ <0x0 0x2c000000 0x0 0x2000000>; /*VPU*/
+ reg-names = "vpu_regs";
+ power-domains = <&pd_vpu_enc>;
+ reg-rpc-system = <0x40000000>;
+
+ resolution-max = <1920 1080>;
+ fps-max = <120>;
+ status = "disabled";
+
+ core0@1020000 {
+ compatible = "fsl,imx8-mu1-vpu-m0";
+ reg = <0x1020000 0x20000>;
+ reg-csr = <0x1090000 0x10000>;
+ interrupts = <GIC_SPI 473 IRQ_TYPE_LEVEL_HIGH>;
+ fsl,vpu_ap_mu_id = <17>;
+ fw-buf-size = <0x200000>;
+ rpc-buf-size = <0x80000>;
+ print-buf-size = <0x80000>;
+ };
+ core1@1040000 {
+ compatible = "fsl,imx8-mu2-vpu-m0";
+ reg = <0x1040000 0x20000>;
+ reg-csr = <0x10a0000 0x10000>;
+ interrupts = <GIC_SPI 474 IRQ_TYPE_LEVEL_HIGH>;
+ fsl,vpu_ap_mu_id = <18>;
+ fw-buf-size = <0x200000>;
+ rpc-buf-size = <0x80000>;
+ print-buf-size = <0x80000>;
+ };
+ };
+
+ clk: clk {
+ compatible = "fsl,imx8qm-clk";
+ #clock-cells = <1>;
+ fsl,lpcg_base_offset = <0x00000000 0x00000000>;
+ };
+
+ iomuxc: iomuxc {
+ compatible = "fsl,imx8qm-iomuxc";
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ epdev_on: fixedregulator@100 {
+ compatible = "regulator-fixed";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-name = "epdev_on";
+ gpio = <&gpio4 9 0>;
+ enable-active-high;
+ };
+
+ reg_audio: fixedregulator@2 {
+ compatible = "regulator-fixed";
+ reg = <2>;
+ regulator-name = "cs42888_supply";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+ };
+
+ #include "fsl-imx8qm-device.dtsi"
+
+ mu2: mu@5d1d0000 {
+ compatible = "fsl,imx8-mu";
+ reg = <0x0 0x5d1d0000 0x0 0x10000>;
+ interrupts = <GIC_SPI 178 IRQ_TYPE_LEVEL_HIGH>;
+ fsl,scu_ap_mu_id = <0>;
+ status = "okay";
+ };
+
+ usb_lpcg {
+ reg = <0x0 0x5b270000 0x0 0x10000>;
+ };
+
+ edma01: dma-controller1@5a1f0000 {
+ compatible = "fsl,imx8qm-edma";
+ reg = <0x0 0x5a2e0000 0x0 0x10000>, /* channel14 UART1 rx */
+ <0x0 0x5a2f0000 0x0 0x10000>; /* channel15 UART1 tx */
+ #dma-cells = <3>;
+ dma-channels = <2>;
+ interrupts = <GIC_SPI 436 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 437 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "edma0-chan14-rx", "edma0-chan15-tx";
+ status = "okay";
+ };
+
+ edma20: dma-controller@591f0000 {
+ compatible = "fsl,imx8qm-adma";
+ reg = <0x0 0x59200000 0x0 0x10000>, /* asrc0 */
+ <0x0 0x59210000 0x0 0x10000>,
+ <0x0 0x59220000 0x0 0x10000>,
+ <0x0 0x59230000 0x0 0x10000>,
+ <0x0 0x59240000 0x0 0x10000>,
+ <0x0 0x59250000 0x0 0x10000>;
+ #dma-cells = <3>;
+ shared-interrupt;
+ dma-channels = <6>;
+ interrupts = <GIC_SPI 374 IRQ_TYPE_LEVEL_HIGH>, /* asrc0 */
+ <GIC_SPI 375 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 376 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 377 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 378 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 379 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "edma2-chan0-rx", "edma2-chan1-rx", /* asrc0 */
+ "edma2-chan2-rx", "edma2-chan3-tx",
+ "edma2-chan4-tx", "edma2-chan5-tx";
+ status = "okay";
+ };
+
+ edma21: dma-controller@0x59260000 {
+ compatible = "fsl,imx8qm-adma";
+ reg = <0x0 0x59260000 0x0 0x10000>, /* esai0 rx */
+ <0x0 0x59270000 0x0 0x10000>; /* esai0 tx */
+ #dma-cells = <3>;
+ shared-interrupt;
+ dma-channels = <2>;
+ interrupts = <GIC_SPI 410 IRQ_TYPE_LEVEL_HIGH>, /* esai0 */
+ <GIC_SPI 410 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "edma2-chan6-rx", "edma2-chan7-tx"; /* esai0 */
+ status = "okay";
+ };
+
+ edma24: dma-controller@0x592c0000 {
+ compatible = "fsl,imx8qm-adma";
+ reg = <0x0 0x592c0000 0x0 0x10000>, /* sai0 rx */
+ <0x0 0x592d0000 0x0 0x10000>; /* sai0 tx */
+ #dma-cells = <3>;
+ shared-interrupt;
+ dma-channels = <2>;
+ interrupts = <GIC_SPI 315 IRQ_TYPE_LEVEL_HIGH>, /* sai0 */
+ <GIC_SPI 315 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "edma2-chan12-rx", "edma2-chan13-tx"; /* sai0 */
+ fsl,sc_rsrc_id = <SC_R_DMA_2_CH12>,
+ <SC_R_DMA_2_CH13>;
+ status = "okay";
+ };
+
+ sound-cs42888 {
+ compatible = "fsl,imx8qm-sabreauto-cs42888",
+ "fsl,imx-audio-cs42888";
+ model = "imx-cs42888";
+ esai-controller = <&esai0>;
+ audio-codec = <&cs42888>;
+ asrc-controller = <&asrc0>;
+ status = "okay";
+ };
+
+ xen_i2c0: xen_i2c@0 {
+ compatible = "xen,i2c";
+ be-adapter = "5a800000.i2c";
+ status = "okay";
+ };
+
+ xen_i2c1: xen_i2c@1 {
+ compatible = "xen,i2c";
+ be-adapter = "3b230000.i2c";
+ status = "okay";
+ };
+ };
+
+ /*
+ * vehicle core driver device node which open power domain dc by default
+ */
+ vehicle_core: vehicle_core {
+ compatible = "nxp,imx-vehicle";
+ status = "disabled";
+ };
+
+ /*
+ * vehicle M4 driver which can get info from MCU.
+ */
+ vehicle_rpmsg_m4: vehicle_rpmsg_m4 {
+ compatible = "nxp,imx-vehicle-m4";
+ status = "disabled";
+ };
+};
+
+/delete-node/ &tsens;
+/delete-node/ &thermal_zones;
+/delete-node/ &rtc;
+
+&display {
+ ports = <&dpu2_disp0>, <&dpu2_disp1>;
+};
+
+&dpu2_intsteer {
+ reg = <0x0 0x57000000 0x0 0x10000>;
+ status = "okay";
+};
+
+&prg10 {
+ reg = <0x0 0x57040000 0x0 0x10000>;
+ status = "okay";
+};
+
+&prg11 {
+ reg = <0x0 0x57050000 0x0 0x10000>;
+ status = "okay";
+};
+
+&prg12 {
+ reg = <0x0 0x57060000 0x0 0x10000>;
+ status = "okay";
+};
+
+&prg13 {
+ reg = <0x0 0x57070000 0x0 0x10000>;
+ status = "okay";
+};
+
+&prg14 {
+ reg = <0x0 0x57080000 0x0 0x10000>;
+ status = "okay";
+};
+
+&prg15 {
+ reg = <0x0 0x57090000 0x0 0x10000>;
+ status = "okay";
+};
+
+&prg16 {
+ reg = <0x0 0x570a0000 0x0 0x10000>;
+ status = "okay";
+};
+
+&prg17 {
+ reg = <0x0 0x570b0000 0x0 0x10000>;
+ status = "okay";
+};
+
+&prg18 {
+ reg = <0x0 0x570c0000 0x0 0x10000>;
+ status = "okay";
+};
+
+&dpr3_channel1 {
+ reg = <0x0 0x570d0000 0x0 0x10000>;
+ status = "okay";
+};
+
+&dpr3_channel2 {
+ reg = <0x0 0x570e0000 0x0 0x10000>;
+ status = "okay";
+};
+
+&dpr3_channel3 {
+ reg = <0x0 0x570f0000 0x0 0x10000>;
+ status = "okay";
+};
+
+&dpr4_channel1 {
+ reg = <0x0 0x57100000 0x0 0x10000>;
+ status = "okay";
+};
+
+&dpr4_channel2 {
+ reg = <0x0 0x57110000 0x0 0x10000>;
+ status = "okay";
+};
+
+&dpr4_channel3 {
+ reg = <0x0 0x57120000 0x0 0x10000>;
+ status = "okay";
+};
+
+&dpu2 {
+ reg = <0x0 0x57180000 0x0 0x40000>;
+ status = "okay";
+
+ dpu2_disp0: port@0 {
+ dpu2_disp0_mipi_dsi: mipi-dsi-endpoint {
+ /delete-property/ remote-endpoint;
+ };
+ };
+ dpu2_disp1: port@1 {
+ reg = <1>;
+
+ dpu2_disp1_lvds0: lvds0-endpoint {
+ remote-endpoint = <&ldb2_lvds0>;
+ };
+
+ dpu2_disp1_lvds1: lvds1-endpoint {
+ remote-endpoint = <&ldb2_lvds1>;
+ };
+ };
+};
+
+&pixel_combiner2 {
+ status = "okay";
+};
+
+/delete-node/ &hdmi;
+/delete-node/ &hdmi_rx;
+/delete-node/ &irqsteer_dsi0;
+/delete-node/ &i2c0_mipi_dsi0;
+/delete-node/ &mipi_dsi_csr1;
+/delete-node/ &mipi_dsi_phy1;
+/delete-node/ &mipi_dsi1;
+/delete-node/ &mipi_dsi_bridge1;
+
+&lvds_region2 {
+ reg = <0x0 0x57240000 0x0 0x10000>;
+ status = "okay";
+};
+
+&ldb2_phy {
+ reg = <0x0 0x57241000 0x0 0x100>;
+ status = "okay";
+};
+
+&ldb2 {
+ status = "okay";
+
+ lvds-channel@0 {
+ fsl,data-mapping = "jeida";
+ fsl,data-width = <24>;
+ status = "okay";
+
+ port@1 {
+ reg = <1>;
+
+ lvds1_out: endpoint {
+ remote-endpoint = <&it6263_1_in>;
+ };
+ };
+ };
+};
+
+/delete-node/ &lvds0_pwm;
+/delete-node/ &dpu1_intsteer;
+/delete-node/ &prg1;
+/delete-node/ &prg2;
+/delete-node/ &prg3;
+/delete-node/ &prg4;
+/delete-node/ &prg5;
+/delete-node/ &prg6;
+/delete-node/ &prg7;
+/delete-node/ &prg8;
+/delete-node/ &prg9;
+/delete-node/ &dpr1_channel1;
+/delete-node/ &dpr1_channel2;
+/delete-node/ &dpr1_channel3;
+/delete-node/ &dpr2_channel1;
+/delete-node/ &dpr2_channel2;
+/delete-node/ &dpr2_channel3;
+/delete-node/ &dpu1;
+/delete-node/ &pixel_combiner1;
+
+&dsp {
+ status = "okay";
+};
+
+/delete-node/ &irqsteer_dsi1;
+/delete-node/ &i2c0_mipi_dsi1;
+/delete-node/ &mipi_dsi_csr2;
+/delete-node/ &mipi_dsi_phy2;
+/delete-node/ &mipi_dsi2;
+/delete-node/ &mipi_dsi_bridge2;
+/delete-node/ &lvds_region1;
+/delete-node/ &ldb1_phy;
+/delete-node/ &ldb1;
+/*/delete-node/ &camera;*/
+/delete-node/ &adc0;
+/delete-node/ &adc1;
+/delete-node/ &i2c0;
+/delete-node/ &i2c1;
+/delete-node/ &i2c2;
+/delete-node/ &i2c3;
+/delete-node/ &i2c4;
+/delete-node/ &i2c0_cm40;
+/delete-node/ &i2c0_cm41;
+/delete-node/ &irqsteer_hdmi;
+/delete-node/ &irqsteer_hdmi_rx;
+/delete-node/ &i2c0_hdmi;
+
+&irqsteer_lvds1 {
+ reg = <0x0 0x57240000 0x0 0x1000>;
+ /delete-property/ interrupt-parent;
+ status = "okay";
+};
+
+/delete-node/ &flexcan1;
+/delete-node/ &flexcan2;
+/delete-node/ &flexcan3;
+
+&i2c1_lvds1 {
+ reg = <0x0 0x57247000 0x0 0x1000>;
+ status = "okay";
+};
+
+/delete-node/ &irqsteer_lvds0;
+/delete-node/ &i2c1_lvds0;
+/*/delete-node/ &irqsteer_csi0;*/
+/*/delete-node/ &i2c0_mipi_csi0;*/
+/delete-node/ &irqsteer_csi1;
+/delete-node/ &i2c0_mipi_csi1;
+/delete-node/ &lpspi0;
+/delete-node/ &lpspi3;
+/delete-node/ &lpuart0;
+
+&lpuart1 {
+ /delete-property/ interrupt-parent;
+ reg = <0x0 0x5a070000 0 0x1000>;
+ dmas = <&edma01 15 0 0>, <&edma01 14 0 1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lpuart1>;
+ status = "okay";
+};
+
+/delete-node/ &lpuart2;
+/delete-node/ &lpuart3;
+/delete-node/ &lpuart4;
+/delete-node/ &emvsim0;
+/delete-node/ &edma0;
+/delete-node/ &edma2;
+/delete-node/ &edma3;
+&gpio0 {
+ /delete-property/ power-domains;
+ status = "disabled";
+};
+&gpio1 {
+ /delete-property/ power-domains;
+ status = "okay";
+};
+&gpio2 {
+ /delete-property/ power-domains;
+ status = "disabled";
+};
+&gpio3 {
+ /delete-property/ power-domains;
+ status = "disabled";
+};
+&gpio4 {
+ /delete-property/ power-domains;
+ status = "okay";
+};
+&gpio5 {
+ /delete-property/ power-domains;
+ status = "disabled";
+};
+&gpio6 {
+ /delete-property/ power-domains;
+ status = "disabled";
+};
+&gpio7 {
+ /delete-property/ power-domains;
+ status = "disabled";
+};
+
+/*/delete-node/ &gpio0_mipi_csi0;*/
+/delete-node/ &gpio0_mipi_csi1;
+/delete-node/ &gpt0;
+/delete-node/ &pwm0;
+/delete-node/ &pwm1;
+/delete-node/ &pwm2;
+/delete-node/ &pwm3;
+/delete-node/ &pwm4;
+/delete-node/ &pwm5;
+/delete-node/ &pwm6;
+/delete-node/ &pwm7;
+
+&gpu_3d1 {
+ reg = <0x0 0x54100000 0 0x40000>;
+ status = "okay";
+};
+
+/delete-node/ &gpu_3d0;
+
+&imx8_gpu_ss {
+ /* xen guests have 2GB of low RAM @ 2GB */
+ reg = <0x0 0x80000000 0x0 0x80000000>, <0x0 0x0 0x0 0x10000000>;
+ reg-names = "phys_baseaddr", "contiguous_mem";
+ cores = <&gpu_3d1>;
+ status = "okay";
+};
+
+/delete-node/ &mlb;
+
+&usdhc1 {
+ compatible = "fsl,imx8qm-usdhc", "fsl,imx6sl-usdhc";
+ /*interrupt-parent = <&gic>;*/
+ /delete-property/ interrupt-parent;
+ reg = <0x0 0x5b010000 0x0 0x10000>;
+};
+
+/delete-node/ &usdhc2;
+/delete-node/ &usdhc3;
+/delete-node/ &fec1;
+/delete-node/ &fec2;
+
+&usbmisc1 {
+ reg = <0x0 0x5b0d0200 0x0 0x200>;
+};
+
+&usbmisc2 {
+ status = "okay";
+};
+
+&usbphy1 {
+ reg = <0x0 0x5b100000 0x0 0x200>;
+};
+
+/delete-node/ &usbh1;
+
+&usbotg3 {
+ /delete-property/ interrupt-parent;
+ dr_mode = "otg";
+ extcon = <&typec_ptn5110>;
+ status = "okay";
+};
+
+&usbphynop1 {
+ status = "okay";
+};
+
+/delete-node/ &usbphynop2;
+
+&usbotg1 {
+ reg = <0x0 0x5b0d0000 0x0 0x200>;
+ /delete-property/ interrupt-parent;
+};
+
+/delete-node/ &ddr_pmu0;
+/delete-node/ &ddr_pmu1;
+/delete-node/ &vpu;
+
+&acm {
+ status = "okay";
+};
+
+&esai0 {
+ compatible = "fsl,imx8qm-esai";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_esai0>;
+ dmas = <&edma21 6 0 1>, <&edma21 7 0 0>;
+ assigned-clocks = <&clk IMX8QM_ACM_ESAI0_MCLK_SEL>,
+ <&clk IMX8QM_AUD_PLL0_DIV>,
+ <&clk IMX8QM_AUD_ACM_AUD_PLL_CLK0_DIV>,
+ <&clk IMX8QM_AUD_ACM_AUD_REC_CLK0_DIV>,
+ <&clk IMX8QM_AUD_ESAI_0_EXTAL_IPG>;
+ assigned-clock-parents = <&clk IMX8QM_AUD_ACM_AUD_PLL_CLK0_CLK>;
+ assigned-clock-rates = <0>, <786432000>, <49152000>, <12288000>, <49152000>;
+ status = "okay";
+};
+
+/delete-node/ &esai1;
+/delete-node/ &spdif0;
+/delete-node/ &spdif1;
+/delete-node/ &sai1;
+&sai0 {
+ dmas = <&edma24 12 0 1>, <&edma24 13 0 0>;
+};
+/delete-node/ &sai2;
+/delete-node/ &sai3;
+/delete-node/ &sai_hdmi_rx;
+/delete-node/ &sai_hdmi_tx;
+/delete-node/ &sai6;
+/delete-node/ &sai7;
+/delete-node/ &amix;
+
+&asrc0 {
+ dmas = <&edma20 0 0 0>, <&edma20 1 0 0>, <&edma20 2 0 0>,
+ <&edma20 3 0 1>, <&edma20 4 0 1>, <&edma20 5 0 1>;
+ fsl,asrc-rate = <48000>;
+ status = "okay";
+};
+
+/delete-node/ &asrc1;
+/delete-node/ &mqs;
+/delete-node/ &flexspi0;
+
+&dma_cap {
+ compatible = "dma-capability";
+ only-dma-mask32 = <1>;
+};
+
+/delete-node/ &ocotp;
+&pciea {
+ ext_osc = <1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pciea>;
+ disable-gpio = <&gpio1 13 GPIO_ACTIVE_LOW>;
+ reset-gpio = <&gpio4 29 GPIO_ACTIVE_LOW>;
+ clkreq-gpio = <&gpio4 27 GPIO_ACTIVE_LOW>;
+ epdev_on-supply = <&epdev_on>;
+ status = "okay";
+};
+/delete-node/ &pcieb;
+/delete-node/ &sata;
+
+/delete-node/ &intmux_cm40;
+/delete-node/ &intmux_cm41;
+
+&rpmsg1{
+ /*
+ * 64K for one rpmsg instance:
+ */
+ vdev-nums = <2>;
+ reg = <0x0 0x90100000 0x0 0x20000>;
+ status = "okay";
+};
+
+&mu_rpmsg1 {
+ reg = <0x0 0x5d210000 0x0 0x10000>;
+};
+
+/*/delete-node/ &crypto;*/
+/*/delete-node/ &caam_sm;*/
+/*/delete-node/ &sc_pwrkey;*/
+/delete-node/ &wdog;
+/delete-node/ &wu;
+
+&iomuxc {
+ imx8qm-mek {
+ pinctrl_usdhc1: usdhc1grp {
+ fsl,pins = <
+ SC_P_EMMC0_CLK_CONN_EMMC0_CLK 0x06000041
+ SC_P_EMMC0_CMD_CONN_EMMC0_CMD 0x00000021
+ SC_P_EMMC0_DATA0_CONN_EMMC0_DATA0 0x00000021
+ SC_P_EMMC0_DATA1_CONN_EMMC0_DATA1 0x00000021
+ SC_P_EMMC0_DATA2_CONN_EMMC0_DATA2 0x00000021
+ SC_P_EMMC0_DATA3_CONN_EMMC0_DATA3 0x00000021
+ SC_P_EMMC0_DATA4_CONN_EMMC0_DATA4 0x00000021
+ SC_P_EMMC0_DATA5_CONN_EMMC0_DATA5 0x00000021
+ SC_P_EMMC0_DATA6_CONN_EMMC0_DATA6 0x00000021
+ SC_P_EMMC0_DATA7_CONN_EMMC0_DATA7 0x00000021
+ SC_P_EMMC0_STROBE_CONN_EMMC0_STROBE 0x06000041
+ SC_P_EMMC0_RESET_B_CONN_EMMC0_RESET_B 0x00000021
+ >;
+ };
+
+ pinctrl_usdhc1_100mhz: usdhc1grp100mhz {
+ fsl,pins = <
+ SC_P_EMMC0_CLK_CONN_EMMC0_CLK 0x06000040
+ SC_P_EMMC0_CMD_CONN_EMMC0_CMD 0x00000020
+ SC_P_EMMC0_DATA0_CONN_EMMC0_DATA0 0x00000020
+ SC_P_EMMC0_DATA1_CONN_EMMC0_DATA1 0x00000020
+ SC_P_EMMC0_DATA2_CONN_EMMC0_DATA2 0x00000020
+ SC_P_EMMC0_DATA3_CONN_EMMC0_DATA3 0x00000020
+ SC_P_EMMC0_DATA4_CONN_EMMC0_DATA4 0x00000020
+ SC_P_EMMC0_DATA5_CONN_EMMC0_DATA5 0x00000020
+ SC_P_EMMC0_DATA6_CONN_EMMC0_DATA6 0x00000020
+ SC_P_EMMC0_DATA7_CONN_EMMC0_DATA7 0x00000020
+ SC_P_EMMC0_STROBE_CONN_EMMC0_STROBE 0x06000040
+ SC_P_EMMC0_RESET_B_CONN_EMMC0_RESET_B 0x00000020
+ >;
+ };
+
+ pinctrl_usdhc1_200mhz: usdhc1grp200mhz {
+ fsl,pins = <
+ SC_P_EMMC0_CLK_CONN_EMMC0_CLK 0x06000040
+ SC_P_EMMC0_CMD_CONN_EMMC0_CMD 0x00000020
+ SC_P_EMMC0_DATA0_CONN_EMMC0_DATA0 0x00000020
+ SC_P_EMMC0_DATA1_CONN_EMMC0_DATA1 0x00000020
+ SC_P_EMMC0_DATA2_CONN_EMMC0_DATA2 0x00000020
+ SC_P_EMMC0_DATA3_CONN_EMMC0_DATA3 0x00000020
+ SC_P_EMMC0_DATA4_CONN_EMMC0_DATA4 0x00000020
+ SC_P_EMMC0_DATA5_CONN_EMMC0_DATA5 0x00000020
+ SC_P_EMMC0_DATA6_CONN_EMMC0_DATA6 0x00000020
+ SC_P_EMMC0_DATA7_CONN_EMMC0_DATA7 0x00000020
+ SC_P_EMMC0_STROBE_CONN_EMMC0_STROBE 0x06000040
+ SC_P_EMMC0_RESET_B_CONN_EMMC0_RESET_B 0x00000020
+ >;
+ };
+
+ pinctrl_usbotg1: usbotg1 {
+ fsl,pins = <
+ SC_P_USB_SS3_TC0_CONN_USB_OTG1_PWR 0x00000021
+ >;
+ };
+
+ pinctrl_lvds1_lpi2c1: lvds1lpi2c1grp {
+ fsl,pins = <
+ SC_P_LVDS1_I2C1_SCL_LVDS1_I2C1_SCL 0xc600004c
+ SC_P_LVDS1_I2C1_SDA_LVDS1_I2C1_SDA 0xc600004c
+ >;
+ };
+
+ pinctrl_lvds1_pwm0: lvds1pwm0grp {
+ fsl,pins = <
+ SC_P_LVDS1_GPIO00_LVDS1_PWM0_OUT 0x00000020
+ >;
+ };
+
+ pinctrl_lpuart1: lpuart1grp {
+ fsl,pins = <
+ SC_P_UART1_RX_DMA_UART1_RX 0x06000020
+ SC_P_UART1_TX_DMA_UART1_TX 0x06000020
+ SC_P_UART1_CTS_B_DMA_UART1_CTS_B 0x06000020
+ SC_P_UART1_RTS_B_DMA_UART1_RTS_B 0x06000020
+ SC_P_QSPI1A_DQS_LSIO_GPIO4_IO22 0x00000021
+ >;
+ };
+
+ pinctrl_pciea: pcieagrp{
+ fsl,pins = <
+ SC_P_PCIE_CTRL0_CLKREQ_B_LSIO_GPIO4_IO27 0x06000021
+ SC_P_PCIE_CTRL0_WAKE_B_LSIO_GPIO4_IO28 0x04000021
+ SC_P_PCIE_CTRL0_PERST_B_LSIO_GPIO4_IO29 0x06000021
+ SC_P_LVDS1_I2C0_SDA_LSIO_GPIO1_IO13 0x06000000
+ SC_P_USDHC2_RESET_B_LSIO_GPIO4_IO09 0x06000021
+ >;
+ };
+
+ pinctrl_typec: typecgrp {
+ fsl,pins = <
+ SC_P_QSPI1A_SS0_B_LSIO_GPIO4_IO19 0x60
+ SC_P_USB_SS3_TC3_LSIO_GPIO4_IO06 0x60
+ SC_P_QSPI1A_DATA0_LSIO_GPIO4_IO26 0x00000021
+ >;
+ };
+
+ pinctrl_isl29023: isl29023grp {
+ fsl,pins = <
+ SC_P_USDHC2_WP_LSIO_GPIO4_IO11 0x00000021
+ >;
+ };
+
+ pinctrl_esai0: esai0grp {
+ fsl,pins = <
+ SC_P_ESAI0_FSR_AUD_ESAI0_FSR 0xc6000040
+ SC_P_ESAI0_FST_AUD_ESAI0_FST 0xc6000040
+ SC_P_ESAI0_SCKR_AUD_ESAI0_SCKR 0xc6000040
+ SC_P_ESAI0_SCKT_AUD_ESAI0_SCKT 0xc6000040
+ SC_P_ESAI0_TX0_AUD_ESAI0_TX0 0xc6000040
+ SC_P_ESAI0_TX1_AUD_ESAI0_TX1 0xc6000040
+ SC_P_ESAI0_TX2_RX3_AUD_ESAI0_TX2_RX3 0xc6000040
+ SC_P_ESAI0_TX3_RX2_AUD_ESAI0_TX3_RX2 0xc6000040
+ SC_P_ESAI0_TX4_RX1_AUD_ESAI0_TX4_RX1 0xc6000040
+ SC_P_ESAI0_TX5_RX0_AUD_ESAI0_TX5_RX0 0xc6000040
+ >;
+ };
+ };
+};
+
+&usdhc1 {
+ /delete-property/ iommus;
+ pinctrl-names = "default", "state_100mhz", "state_200mhz";
+ pinctrl-0 = <&pinctrl_usdhc1>;
+ pinctrl-1 = <&pinctrl_usdhc1_100mhz>;
+ pinctrl-2 = <&pinctrl_usdhc1_200mhz>;
+ bus-width = <8>;
+ non-removable;
+ status = "okay";
+};
+
+&usbotg1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usbotg1>;
+ srp-disable;
+ hnp-disable;
+ adp-disable;
+ power-polarity-active-high;
+ disable-over-current;
+ status = "okay";
+};
+
+&i2c1_lvds1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lvds1_lpi2c1>;
+ clock-frequency = <100000>;
+ status = "okay";
+
+ lvds-to-hdmi-bridge@4c {
+ compatible = "ite,it6263";
+ reg = <0x4c>;
+
+ port {
+ it6263_1_in: endpoint {
+ clock-lanes = <3>;
+ data-lanes = <0 1 2 4>;
+ remote-endpoint = <&lvds1_out>;
+ };
+ };
+ };
+};
+
+&vpu_decoder {
+ core_type = <2>;
+ status = "okay";
+};
+
+&vpu_encoder {
+ status = "okay";
+};
+
+&xen_i2c0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clock-frequency = <100000>;
+ status = "okay";
+
+ isl29023@44 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_isl29023>;
+ compatible = "fsl,isl29023";
+ reg = <0x44>;
+ rext = <499>;
+ interrupt-parent = <&gpio4>;
+ interrupts = <11 2>;
+ };
+
+ fxos8700@1e {
+ compatible = "fsl,fxos8700";
+ reg = <0x1e>;
+ interrupt-open-drain;
+ };
+
+ fxas2100x@20 {
+ compatible = "fsl,fxas2100x";
+ reg = <0x20>;
+ interrupt-open-drain;
+ };
+
+ mpl3115@60 {
+ compatible = "fsl,mpl3115";
+ reg = <0x60>;
+ interrupt-open-drain;
+ };
+
+ typec_ptn5110: typec@50 {
+ compatible = "usb,tcpci";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_typec>;
+ reg = <0x51>;
+ interrupt-parent = <&gpio4>;
+ interrupts = <26 IRQ_TYPE_LEVEL_LOW>;
+ ss-sel-gpios = <&gpio4 6 GPIO_ACTIVE_LOW>;
+ reset-gpios = <&gpio4 19 GPIO_ACTIVE_HIGH>;
+ src-pdos = <0x380190c8 0x3803c0c8>;
+ port-type = "drp";
+ sink-disable;
+ default-role = "source";
+ status = "okay";
+ };
+};
+
+&xen_i2c1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clock-frequency = <100000>;
+ status = "okay";
+
+ cs42888: cs42888@48 {
+ compatible = "cirrus,cs42888";
+ reg = <0x48>;
+ clocks = <&clk IMX8QM_AUD_MCLKOUT0>;
+ clock-names = "mclk";
+ VA-supply = <&reg_audio>;
+ VD-supply = <&reg_audio>;
+ VLS-supply = <&reg_audio>;
+ VLC-supply = <&reg_audio>;
+ reset-gpio = <&gpio4 25 1>;
+ power-domains = <&pd_mclk_out0>;
+ assigned-clocks = <&clk IMX8QM_AUD_PLL0_DIV>,
+ <&clk IMX8QM_AUD_ACM_AUD_PLL_CLK0_DIV>,
+ <&clk IMX8QM_AUD_ACM_AUD_REC_CLK0_DIV>,
+ <&clk IMX8QM_AUD_MCLKOUT0>;
+ assigned-clock-rates = <786432000>, <49152000>, <12288000>, <12288000>;
+ status = "okay";
+ };
+};
+
+/* Camera */
+/delete-node/ &isi_4;
+/delete-node/ &isi_5;
+/delete-node/ &isi_6;
+/delete-node/ &isi_7;
+/delete-node/ &mipi_csi_1;
+/delete-node/ &jpegdec;
+/delete-node/ &jpegenc;
+
+&gpio0_mipi_csi0 {
+ status = "okay";
+};
+
+&irqsteer_csi0 {
+ status = "okay";
+};
+
+&isi_0 {
+ status = "okay";
+};
+
+&isi_1 {
+ status = "okay";
+};
+
+&isi_2 {
+ status = "okay";
+};
+
+&isi_3 {
+ status = "okay";
+};
+
+&mipi_csi_0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ virtual-channel;
+ status = "okay";
+
+ /* Camera 0 MIPI CSI-2 (CSIS0) */
+ port@0 {
+ reg = <0>;
+ mipi_csi0_ep: endpoint {
+ remote-endpoint = <&max9286_0_ep>;
+ data-lanes = <1 2 3 4>;
+ };
+ };
+};
+
+&i2c0_mipi_csi0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ clock-frequency = <100000>;
+ status = "okay";
+
+
+ max9286_mipi@6A {
+ compatible = "maxim,max9286_mipi";
+ reg = <0x6A>;
+ clocks = <&clk IMX8QM_CLK_DUMMY>;
+ clock-names = "capture_mclk";
+ mclk = <27000000>;
+ mclk_source = <0>;
+ pwn-gpios = <&gpio1 27 GPIO_ACTIVE_HIGH>;
+ virtual-channel;
+ port {
+ max9286_0_ep: endpoint {
+ remote-endpoint = <&mipi_csi0_ep>;
+ data-lanes = <1 2 3 4>;
+ };
+ };
+ };
+};
+
+&lvds1_pwm {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lvds1_pwm0>;
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8qm-mek-dsi-rm67191.dts b/arch/arm64/boot/dts/freescale/fsl-imx8qm-mek-dsi-rm67191.dts
new file mode 100644
index 000000000000..4ce6121f1437
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8qm-mek-dsi-rm67191.dts
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2017 NXP
+ *
+ * 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 "fsl-imx8qm-mek.dts"
+
+&mipi_dsi_bridge1 {
+ status = "okay";
+
+ panel@0 {
+ compatible = "raydium,rm67191";
+ reg = <0>;
+ pinctrl-0 = <&pinctrl_mipi_dsi_0_1_en>;
+ reset-gpio = <&gpio1 7 GPIO_ACTIVE_HIGH>;
+ dsi-lanes = <4>;
+ panel-width-mm = <68>;
+ panel-height-mm = <121>;
+ port {
+ panel1_in: endpoint {
+ remote-endpoint = <&mipi_bridge1_out>;
+ };
+ };
+ };
+
+ port@2 {
+ mipi_bridge1_out: endpoint {
+ remote-endpoint = <&panel1_in>;
+ };
+ };
+};
+
+&mipi_dsi_bridge2 {
+ status = "okay";
+
+ panel@0 {
+ compatible = "raydium,rm67191";
+ reg = <0>;
+ pinctrl-0 = <&pinctrl_mipi_dsi_0_1_en>;
+ reset-gpio = <&gpio1 7 GPIO_ACTIVE_HIGH>;
+ dsi-lanes = <4>;
+ panel-width-mm = <68>;
+ panel-height-mm = <121>;
+ port {
+ panel2_in: endpoint {
+ remote-endpoint = <&mipi_bridge2_out>;
+ };
+ };
+ };
+
+ port@2 {
+ mipi_bridge2_out: endpoint {
+ remote-endpoint = <&panel2_in>;
+ };
+ };
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8qm-mek-dsp.dts b/arch/arm64/boot/dts/freescale/fsl-imx8qm-mek-dsp.dts
new file mode 100644
index 000000000000..3588fe8c16b4
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8qm-mek-dsp.dts
@@ -0,0 +1,198 @@
+// SPDX-License-Identifier: GPL-2.0+
+// Copyright NXP 2018
+
+#include "fsl-imx8qm-mek.dts"
+
+/ {
+ sound-cs42888 {
+ status = "disabled";
+ };
+
+ sound {
+ status = "disabled";
+ };
+
+ dspaudio: dspaudio {
+ compatible = "fsl,dsp-audio";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_esai0>;
+ clocks = <&clk IMX8QM_AUD_ESAI_0_IPG>,
+ <&clk IMX8QM_AUD_ESAI_0_EXTAL_IPG>,
+ <&clk IMX8QM_AUD_ASRC_0_IPG>,
+ <&clk IMX8QM_AUD_ASRC_0_MEM>,
+ <&clk IMX8QM_AUD_ACM_AUD_PLL_CLK0_CLK>,
+ <&clk IMX8QM_AUD_ACM_AUD_PLL_CLK1_CLK>,
+ <&clk IMX8QM_ACM_AUD_CLK0_SEL>,
+ <&clk IMX8QM_ACM_AUD_CLK1_SEL>;
+
+ clock-names = "bus", "mclk", "ipg", "mem",
+ "asrck_0", "asrck_1", "asrck_2", "asrck_3";
+ assigned-clocks = <&clk IMX8QM_ACM_ESAI0_MCLK_SEL>,
+ <&clk IMX8QM_AUD_PLL0_DIV>,
+ <&clk IMX8QM_AUD_ACM_AUD_PLL_CLK0_DIV>,
+ <&clk IMX8QM_AUD_ACM_AUD_REC_CLK0_DIV>,
+ <&clk IMX8QM_AUD_ESAI_0_EXTAL_IPG>;
+ assigned-clock-parents = <&clk IMX8QM_AUD_ACM_AUD_PLL_CLK0_CLK>;
+ assigned-clock-rates = <0>, <786432000>, <49152000>, <24576000>, <49152000>;
+ power-domains = <&pd_esai0>;
+ status = "okay";
+ };
+
+ sound-dsp {
+ compatible = "fsl,imx-dsp-audio";
+ model = "dsp-audio";
+ cpu-dai = <&dspaudio>;
+ audio-codec = <&cs42888>;
+ audio-platform = <&dsp>;
+ };
+};
+
+&edma2 {
+ compatible = "fsl,imx8qm-edma";
+ reg = <0x0 0x59280000 0x0 0x10000>, /* spdif0 rx */
+ <0x0 0x59290000 0x0 0x10000>, /* spdif0 tx */
+ <0x0 0x592c0000 0x0 0x10000>, /* sai0 rx */
+ <0x0 0x592d0000 0x0 0x10000>, /* sai0 tx */
+ <0x0 0x592e0000 0x0 0x10000>, /* sai1 rx */
+ <0x0 0x592f0000 0x0 0x10000>, /* sai1 tx */
+ <0x0 0x59320000 0x0 0x10000>, /* sai4 rx */
+ <0x0 0x59330000 0x0 0x10000>; /* sai5 tx */
+ #dma-cells = <3>;
+ shared-interrupt;
+ dma-channels = <8>;
+ interrupts = <GIC_SPI 457 IRQ_TYPE_LEVEL_HIGH>, /* spdif0 */
+ <GIC_SPI 459 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 315 IRQ_TYPE_LEVEL_HIGH>, /* sai0 */
+ <GIC_SPI 315 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 317 IRQ_TYPE_LEVEL_HIGH>, /* sai1 */
+ <GIC_SPI 317 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 326 IRQ_TYPE_LEVEL_HIGH>,/* sai4 */
+ <GIC_SPI 328 IRQ_TYPE_LEVEL_HIGH>;/* sai5 */
+ interrupt-names = "edma2-chan8-rx", "edma0-chan9-tx", /* spdif0 */
+ "edma2-chan12-rx", "edma2-chan13-tx", /* sai0 */
+ "edma2-chan14-rx", "edma2-chan15-tx", /* sai1 */
+ "edma2-chan18-tx", "edma2-chan19-rx"; /* sai4, sai5 */
+ status = "okay";
+};
+
+&dsp {
+ compatible = "fsl,imx8qm-dsp";
+ reserved-region = <&dsp_reserved>;
+ reg = <0x0 0x556e8000 0x0 0x88000>;
+ clocks = <&clk IMX8QM_AUD_ESAI_0_IPG>,
+ <&clk IMX8QM_AUD_ESAI_0_EXTAL_IPG>,
+ <&clk IMX8QM_AUD_ASRC_0_IPG>,
+ <&clk IMX8QM_AUD_ASRC_0_MEM>,
+ <&clk IMX8QM_AUD_ACM_AUD_PLL_CLK0_CLK>,
+ <&clk IMX8QM_AUD_ACM_AUD_PLL_CLK1_CLK>,
+ <&clk IMX8QM_ACM_AUD_CLK0_SEL>,
+ <&clk IMX8QM_ACM_AUD_CLK1_SEL>;
+ clock-names = "esai_ipg", "esai_mclk", "asrc_ipg", "asrc_mem",
+ "asrck_0", "asrck_1", "asrck_2", "asrck_3";
+ assigned-clocks = <&clk IMX8QM_ACM_ESAI0_MCLK_SEL>,
+ <&clk IMX8QM_AUD_PLL0_DIV>,
+ <&clk IMX8QM_AUD_ACM_AUD_PLL_CLK0_DIV>,
+ <&clk IMX8QM_AUD_ACM_AUD_REC_CLK0_DIV>,
+ <&clk IMX8QM_AUD_ESAI_0_EXTAL_IPG>;
+ assigned-clock-parents = <&clk IMX8QM_AUD_ACM_AUD_PLL_CLK0_CLK>;
+ assigned-clock-rates = <0>, <786432000>, <49152000>, <24576000>, <49152000>;
+ fsl,dsp-firmware = "imx/dsp/hifi4.bin";
+ fixup-offset = <0x4000000>;
+ power-domains = <&pd_dsp>;
+};
+
+/delete-node/ &pd_dma2_chan6;
+/delete-node/ &pd_dsp_irqsteer;
+
+&pd_asrc0 {
+ reg = <SC_R_ASRC_0>;
+ power-domains =<&pd_dma2_chan5>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_dma2_chan6: PD_ESAI_0_RX {
+ reg = <SC_R_DMA_2_CH6>;
+ power-domains =<&pd_asrc0>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_dma2_chan7: PD_ESAI_0_TX {
+ reg = <SC_R_DMA_2_CH7>;
+ power-domains =<&pd_dma2_chan6>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_esai0: PD_AUD_ESAI_0 {
+ reg = <SC_R_ESAI_0>;
+ power-domains =<&pd_dma2_chan7>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_dsp_irqsteer: PD_DSP_IRQSTEER {
+ reg = <SC_R_IRQSTR_DSP>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_esai0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_dsp_mu_A: PD_DSP_MU_A {
+ reg = <SC_R_MU_13A>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_dsp_irqsteer>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_dsp_mu_B: PD_DSP_MU_B {
+ reg = <SC_R_MU_13B>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_dsp_mu_A>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_dsp_ram: PD_AUD_OCRAM {
+ reg = <SC_R_DSP_RAM>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_dsp_mu_B>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pd_dsp: PD_AUD_DSP {
+ reg = <SC_R_DSP>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_dsp_ram>;
+ };
+ };
+ };
+ };
+ };
+ };
+ };
+ };
+};
+
+&esai0 {
+ status = "disabled";
+};
+
+&asrc0 {
+ status = "disabled";
+};
+
+&sai1 {
+ status = "disabled";
+};
+
+&wm8960 {
+ status = "disabled";
+};
+
+&cs42888 {
+ assigned-clocks = <&clk IMX8QM_AUD_PLL0_DIV>,
+ <&clk IMX8QM_AUD_ACM_AUD_PLL_CLK0_DIV>,
+ <&clk IMX8QM_AUD_ACM_AUD_REC_CLK0_DIV>,
+ <&clk IMX8QM_AUD_MCLKOUT0>;
+ assigned-clock-rates = <786432000>, <49152000>, <24576000>, <24576000>;
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8qm-mek-enet2-tja1100.dts b/arch/arm64/boot/dts/freescale/fsl-imx8qm-mek-enet2-tja1100.dts
new file mode 100644
index 000000000000..817bb62df06a
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8qm-mek-enet2-tja1100.dts
@@ -0,0 +1,16 @@
+/*
+ * Copyright 2018 NXP
+ *
+ * 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 "fsl-imx8qm-mek.dts"
+#include "fsl-imx8qm-enet2-tja1100.dtsi"
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8qm-mek-hdmi-in.dts b/arch/arm64/boot/dts/freescale/fsl-imx8qm-mek-hdmi-in.dts
new file mode 100644
index 000000000000..788680861dae
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8qm-mek-hdmi-in.dts
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2018 NXP
+ *
+ * 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.
+ */
+/*
+ * HDMI IN only dts.
+ */
+
+#include "fsl-imx8qm-mek-hdmi.dts"
+
+/ {
+ sound-hdmi-rx {
+ compatible = "fsl,imx-audio-cdnhdmi";
+ model = "imx-audio-hdmi-rx";
+ audio-cpu = <&sai_hdmi_rx>;
+ protocol = <1>;
+ hdmi-in;
+ };
+};
+
+/* HDMI RX */
+&isi_2 {
+ interface = <4 0 2>; /* <Input MIPI_VCx Output>
+ Input: 0-DC0, 1-DC1, 2-MIPI CSI0, 3-MIPI CSI1, 4-HDMI, 5-MEM
+ VCx: 0-VC0, 1-VC1, 2-VC2, 3-VC3, MIPI CSI only
+ Output: 0-DC0, 1-DC1, 2-MEM */
+ status = "okay";
+};
+
+&isi_3 {
+ /* For HDMI RX 4K chain buf */
+ interface = <4 0 2>;
+ status = "okay";
+};
+
+&mipi_csi_0 {
+ status = "disabled";
+};
+
+&i2c0_mipi_csi0 {
+ status = "disabled";
+};
+
+&hdmi_rx {
+ fsl,cec;
+ assigned-clocks = <&clk IMX8QM_HDMI_RX_HD_REF_SEL>,
+ <&clk IMX8QM_HDMI_RX_PXL_SEL>,
+ <&clk IMX8QM_HDMI_RX_HD_REF_DIV>;
+ assigned-clock-parents = <&clk IMX8QM_HDMI_RX_DIG_PLL_CLK>,
+ <&clk IMX8QM_HDMI_RX_BYPASS_CLK>;
+ assigned-clock-rates = <0>, <0>, <400000000>;
+ status = "okay";
+};
+
+&sai_hdmi_rx {
+ fsl,sai-asynchronous;
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8qm-mek-hdmi.dts b/arch/arm64/boot/dts/freescale/fsl-imx8qm-mek-hdmi.dts
new file mode 100644
index 000000000000..59532f47b2cd
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8qm-mek-hdmi.dts
@@ -0,0 +1,88 @@
+/*
+ * Copyright 2017-2018 NXP
+ *
+ * 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.
+ */
+/*
+ * HDMI only dts, disable ldb display.
+ */
+
+#include "fsl-imx8qm-mek.dts"
+
+/ {
+ sound-hdmi-tx {
+ compatible = "fsl,imx-audio-cdnhdmi";
+ model = "imx-audio-hdmi-tx";
+ audio-cpu = <&sai_hdmi_tx>;
+ protocol = <1>;
+ hdmi-out;
+ };
+
+ sound-amix-sai {
+ status = "disabled";
+ };
+
+ sound-hdmi-arc {
+ compatible = "fsl,imx-audio-spdif";
+ model = "imx-hdmi-arc";
+ spdif-controller = <&spdif1>;
+ spdif-in;
+ spdif-out;
+ };
+};
+
+&ldb1_phy {
+ status = "disabled";
+};
+
+&ldb1 {
+ status = "disabled";
+};
+
+&i2c1_lvds0 {
+ status = "disabled";
+};
+
+&irqsteer_hdmi {
+ status = "okay";
+};
+
+&hdmi {
+ compatible = "fsl,imx8qm-hdmi";
+ assigned-clocks = <&clk IMX8QM_HDMI_PXL_SEL>,
+ <&clk IMX8QM_HDMI_PXL_LINK_SEL>,
+ <&clk IMX8QM_HDMI_PXL_MUX_SEL>;
+ assigned-clock-parents = <&clk IMX8QM_HDMI_AV_PLL_CLK>,
+ <&clk IMX8QM_HDMI_AV_PLL_CLK>,
+ <&clk IMX8QM_HDMI_AV_PLL_CLK>;
+ fsl,cec;
+ status = "okay";
+};
+
+&sai_hdmi_tx {
+ assigned-clocks =<&clk IMX8QM_ACM_HDMI_TX_SAI0_MCLK_SEL>,
+ <&clk IMX8QM_AUD_PLL0_DIV>,
+ <&clk IMX8QM_AUD_ACM_AUD_PLL_CLK0_DIV>,
+ <&clk IMX8QM_AUD_ACM_AUD_REC_CLK0_DIV>,
+ <&clk IMX8QM_AUD_SAI_HDMITX0_MCLK>;
+ assigned-clock-parents = <&clk IMX8QM_AUD_ACM_AUD_PLL_CLK0_CLK>;
+ assigned-clock-rates = <0>, <786432000>, <49152000>, <12288000>, <49152000>;
+ fsl,sai-asynchronous;
+ status = "okay";
+};
+
+&spdif1 {
+ assigned-clocks =<&clk IMX8QM_AUD_PLL0_DIV>,
+ <&clk IMX8QM_AUD_ACM_AUD_PLL_CLK0_DIV>,
+ <&clk IMX8QM_AUD_ACM_AUD_REC_CLK0_DIV>;
+ assigned-clock-rates = <786432000>, <49152000>, <12288000>;
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8qm-mek-inmate.dts b/arch/arm64/boot/dts/freescale/fsl-imx8qm-mek-inmate.dts
new file mode 100644
index 000000000000..6026e002490b
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8qm-mek-inmate.dts
@@ -0,0 +1,287 @@
+/*
+ * Copyright 2018 NXP
+ *
+ * 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.
+ */
+
+/dts-v1/;
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include "fsl-imx8-ca53.dtsi"
+#include <dt-bindings/soc/imx_rsrc.h>
+#include <dt-bindings/soc/imx8_hsio.h>
+#include <dt-bindings/soc/imx8_pd.h>
+#include <dt-bindings/clock/imx8qm-clock.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/pinctrl/pads-imx8qm.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/thermal/thermal.h>
+
+/ {
+ model = "Freescale i.MX8QM MEK";
+ compatible = "fsl,imx8qm-mek", "fsl,imx8qm";
+ interrupt-parent = <&gic>;
+ #address-cells = <0x2>;
+ #size-cells = <0x2>;
+
+ aliases {
+ mmc0 = &usdhc1;
+ serial2 = &lpuart2;
+ };
+
+ cpus {
+ #address-cells = <0x2>;
+ #size-cells = <0x0>;
+
+ cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,armv8";
+ enable-method = "psci";
+ reg = <0x0 0x2>;
+ /delete-property/ cpu-idle-states;
+ };
+
+ cpu@1 {
+ device_type = "cpu";
+ compatible = "arm,armv8";
+ enable-method = "psci";
+ reg = <0x0 0x3>;
+ /delete-property/ cpu-idle-states;
+ };
+ };
+
+ psci {
+ compatible = "arm,psci-1.0";
+ method = "smc";
+ };
+
+ timer {
+ compatible = "arm,armv8-timer";
+ interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>, /* Physical Secure */
+ <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>, /* Physical Non-Secure */
+ <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>, /* Virtual */
+ <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>; /* Hypervisor */
+ clock-frequency = <8333333>;
+ };
+
+ clk: clk {
+ compatible = "fsl,imx8qm-clk";
+ #clock-cells = <1>;
+ };
+
+ iomuxc: iomuxc {
+ compatible = "fsl,imx8qm-iomuxc";
+ };
+
+ gic: interrupt-controller@51a00000 {
+ compatible = "arm,gic-v3";
+ reg = <0x0 0x51a00000 0 0x10000>, /* GIC Dist */
+ <0x0 0x51b00000 0 0xC0000>; /* GICR (RD_base + SGI_base) */
+ #interrupt-cells = <3>;
+ interrupt-controller;
+ interrupts = <GIC_PPI 9
+ (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_HIGH)>;
+ interrupt-parent = <&gic>;
+ };
+
+ imx8qx-pm {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_conn: PD_CONN {
+ compatible = "nxp,imx8-pd";
+ reg = <SC_R_NONE>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_conn_sdch0: PD_CONN_SDHC_0 {
+ reg = <SC_R_SDHC_0>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_conn>;
+ };
+ };
+
+ pd_dma: PD_DMA {
+ compatible = "nxp,imx8-pd";
+ reg = <SC_R_NONE>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_dma_lpuart2: PD_DMA_UART2 {
+ reg = <SC_R_UART_2>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_dma>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ wakeup-irq = <347>;
+
+ pd_dma0_chan16: PD_UART2_RX {
+ reg = <SC_R_DMA_0_CH16>;
+ power-domains =<&pd_dma_lpuart2>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_dma0_chan17: PD_UART2_TX {
+ reg = <SC_R_DMA_0_CH17>;
+ power-domains =<&pd_dma0_chan16>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ };
+ };
+ };
+ };
+
+ mu2: mu@5d1d0000 {
+ compatible = "fsl,imx8-mu";
+ reg = <0x0 0x5d1d0000 0x0 0x10000>;
+ interrupts = <GIC_SPI 178 IRQ_TYPE_LEVEL_HIGH>;
+ fsl,scu_ap_mu_id = <0>;
+ status = "okay";
+ };
+
+ pci@fd700000 {
+ compatible = "pci-host-ecam-generic";
+ device_type = "pci";
+ bus-range = <0 0>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ #interrupt-cells = <1>;
+ interrupt-map-mask = <0 0 0 7>;
+ interrupt-map = <0 0 0 1 &gic GIC_SPI 90 IRQ_TYPE_EDGE_RISING>;
+ reg = <0x0 0xfd700000 0x0 0x100000>;
+ ranges = <0x02000000 0x00 0x10000000 0x0 0x10000000 0x00 0x10000>;
+ };
+
+ usdhc1: usdhc@5b010000 {
+ compatible = "fsl,imx8qm-usdhc", "fsl,imx6sl-usdhc";
+ interrupt-parent = <&gic>;
+ interrupts = <GIC_SPI 232 IRQ_TYPE_LEVEL_HIGH>;
+ reg = <0x0 0x5b010000 0x0 0x10000>;
+ clocks = <&clk IMX8QM_SDHC0_IPG_CLK>,
+ <&clk IMX8QM_SDHC0_CLK>,
+ <&clk IMX8QM_CLK_DUMMY>;
+ clock-names = "ipg", "per", "ahb";
+ assigned-clocks = <&clk IMX8QM_SDHC0_DIV>;
+ assigned-clock-rates = <400000000>;
+ power-domains = <&pd_conn_sdch0>;
+ fsl,tuning-start-tap = <20>;
+ fsl,tuning-step= <2>;
+ /*iommus = <&smmu 0x11 0x7f80>;*/
+ status = "disabled";
+ };
+
+ /* For early console */
+ lpuart0: serial@5a060000 {
+ compatible = "fsl,imx8qm-lpuart";
+ reg = <0x0 0x5a060000 0x0 0x1000>;
+ };
+
+ lpuart2: serial@5a080000 {
+ compatible = "fsl,imx8qm-lpuart";
+ reg = <0x0 0x5a080000 0x0 0x1000>;
+ interrupts = <GIC_SPI 347 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-parent = <&gic>;
+ clocks = <&clk IMX8QM_UART2_CLK>,
+ <&clk IMX8QM_UART2_IPG_CLK>;
+ clock-names = "per", "ipg";
+ assigned-clocks = <&clk IMX8QM_UART2_CLK>;
+ assigned-clock-rates = <80000000>;
+ power-domains = <&pd_dma0_chan17>;
+ /*
+ * dma-names = "tx","rx";
+ * dmas = <&edma0 17 0 0>,
+ * <&edma0 16 0 1>;
+ */
+ status = "disabled";
+ };
+};
+
+&iomuxc {
+ imx8qxp-mek {
+ pinctrl_lpuart2: lpuart2grp {
+ fsl,pins = <
+ SC_P_UART0_RTS_B_DMA_UART2_RX 0x06000020
+ SC_P_UART0_CTS_B_DMA_UART2_TX 0x06000020
+ >;
+ };
+
+ pinctrl_usdhc1: usdhc1grp {
+ fsl,pins = <
+ SC_P_EMMC0_CLK_CONN_EMMC0_CLK 0x06000041
+ SC_P_EMMC0_CMD_CONN_EMMC0_CMD 0x00000021
+ SC_P_EMMC0_DATA0_CONN_EMMC0_DATA0 0x00000021
+ SC_P_EMMC0_DATA1_CONN_EMMC0_DATA1 0x00000021
+ SC_P_EMMC0_DATA2_CONN_EMMC0_DATA2 0x00000021
+ SC_P_EMMC0_DATA3_CONN_EMMC0_DATA3 0x00000021
+ SC_P_EMMC0_DATA4_CONN_EMMC0_DATA4 0x00000021
+ SC_P_EMMC0_DATA5_CONN_EMMC0_DATA5 0x00000021
+ SC_P_EMMC0_DATA6_CONN_EMMC0_DATA6 0x00000021
+ SC_P_EMMC0_DATA7_CONN_EMMC0_DATA7 0x00000021
+ SC_P_EMMC0_STROBE_CONN_EMMC0_STROBE 0x00000041
+ SC_P_EMMC0_RESET_B_CONN_EMMC0_RESET_B 0x00000021
+ >;
+ };
+
+ pinctrl_usdhc1_100mhz: usdhc1grp100mhz {
+ fsl,pins = <
+ SC_P_EMMC0_CLK_CONN_EMMC0_CLK 0x06000040
+ SC_P_EMMC0_CMD_CONN_EMMC0_CMD 0x00000020
+ SC_P_EMMC0_DATA0_CONN_EMMC0_DATA0 0x00000020
+ SC_P_EMMC0_DATA1_CONN_EMMC0_DATA1 0x00000020
+ SC_P_EMMC0_DATA2_CONN_EMMC0_DATA2 0x00000020
+ SC_P_EMMC0_DATA3_CONN_EMMC0_DATA3 0x00000020
+ SC_P_EMMC0_DATA4_CONN_EMMC0_DATA4 0x00000020
+ SC_P_EMMC0_DATA5_CONN_EMMC0_DATA5 0x00000020
+ SC_P_EMMC0_DATA6_CONN_EMMC0_DATA6 0x00000020
+ SC_P_EMMC0_DATA7_CONN_EMMC0_DATA7 0x00000020
+ SC_P_EMMC0_STROBE_CONN_EMMC0_STROBE 0x00000040
+ SC_P_EMMC0_RESET_B_CONN_EMMC0_RESET_B 0x00000020
+ >;
+ };
+
+ pinctrl_usdhc1_200mhz: usdhc1grp200mhz {
+ fsl,pins = <
+ SC_P_EMMC0_CLK_CONN_EMMC0_CLK 0x06000040
+ SC_P_EMMC0_CMD_CONN_EMMC0_CMD 0x00000020
+ SC_P_EMMC0_DATA0_CONN_EMMC0_DATA0 0x00000020
+ SC_P_EMMC0_DATA1_CONN_EMMC0_DATA1 0x00000020
+ SC_P_EMMC0_DATA2_CONN_EMMC0_DATA2 0x00000020
+ SC_P_EMMC0_DATA3_CONN_EMMC0_DATA3 0x00000020
+ SC_P_EMMC0_DATA4_CONN_EMMC0_DATA4 0x00000020
+ SC_P_EMMC0_DATA5_CONN_EMMC0_DATA5 0x00000020
+ SC_P_EMMC0_DATA6_CONN_EMMC0_DATA6 0x00000020
+ SC_P_EMMC0_DATA7_CONN_EMMC0_DATA7 0x00000020
+ SC_P_EMMC0_STROBE_CONN_EMMC0_STROBE 0x00000040
+ SC_P_EMMC0_RESET_B_CONN_EMMC0_RESET_B 0x00000020
+ >;
+ };
+ };
+};
+
+&lpuart2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lpuart2>;
+ status = "okay";
+};
+
+&usdhc1 {
+ pinctrl-names = "default", "state_100mhz", "state_200mhz";
+ pinctrl-0 = <&pinctrl_usdhc1>;
+ pinctrl-1 = <&pinctrl_usdhc1_100mhz>;
+ pinctrl-2 = <&pinctrl_usdhc1_200mhz>;
+ bus-width = <8>;
+ non-removable;
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8qm-mek-jdi-wuxga-lvds1-panel.dts b/arch/arm64/boot/dts/freescale/fsl-imx8qm-mek-jdi-wuxga-lvds1-panel.dts
new file mode 100644
index 000000000000..8c4d450c775a
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8qm-mek-jdi-wuxga-lvds1-panel.dts
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2017 NXP
+ *
+ * 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 "fsl-imx8qm-mek.dts"
+
+/ {
+ lvds1_panel {
+ compatible = "jdi,tx26d202vm0bwa";
+ backlight = <&lvds_backlight1>;
+
+ port {
+ panel_lvds1_in: endpoint {
+ remote-endpoint = <&lvds1_out>;
+ };
+ };
+ };
+};
+
+&ldb1_phy {
+ status = "disabled";
+};
+
+&ldb1 {
+ status = "disabled";
+};
+
+&i2c1_lvds0 {
+ lvds-to-hdmi-bridge@4c {
+ status = "disabled";
+ };
+};
+
+&i2c1_lvds1 {
+ lvds-to-hdmi-bridge@4c {
+ status = "disabled";
+ };
+};
+
+&ldb2_phy {
+ status = "okay";
+};
+
+&ldb2 {
+ status = "okay";
+ fsl,dual-channel;
+
+ lvds-channel@0 {
+ fsl,data-mapping = "spwg";
+ fsl,data-width = <24>;
+ status = "okay";
+
+ port@1 {
+ reg = <1>;
+
+ lvds1_out: endpoint {
+ remote-endpoint = <&panel_lvds1_in>;
+ };
+ };
+ };
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8qm-mek-ov5640.dts b/arch/arm64/boot/dts/freescale/fsl-imx8qm-mek-ov5640.dts
new file mode 100644
index 000000000000..fb6ed45254f0
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8qm-mek-ov5640.dts
@@ -0,0 +1,153 @@
+/*
+ * Copyright 2018 NXP
+ *
+ * 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 "fsl-imx8qm-mek.dts"
+
+&iomuxc {
+ imx8qm-mek {
+ pinctrl_mipi_csi0: mipicsi0grp{
+ fsl,pins = <
+ SC_P_MIPI_CSI0_MCLK_OUT_MIPI_CSI0_ACM_MCLK_OUT 0xC0000041
+ SC_P_MIPI_CSI0_GPIO0_00_LSIO_GPIO1_IO27 0x00000021
+ SC_P_MIPI_CSI0_GPIO0_01_LSIO_GPIO1_IO28 0x00000021
+ >;
+ };
+
+ pinctrl_mipi_csi1: mipicsi1grp{
+ fsl,pins = <
+ SC_P_MIPI_CSI1_MCLK_OUT_MIPI_CSI1_ACM_MCLK_OUT 0xC0000041
+ SC_P_MIPI_CSI1_GPIO0_00_LSIO_GPIO1_IO30 0x00000021
+ SC_P_MIPI_CSI1_GPIO0_01_LSIO_GPIO1_IO31 0x00000021
+ >;
+ };
+ };
+};
+
+&isi_0 {
+ status = "okay";
+};
+
+&isi_4 {
+ status = "okay";
+};
+
+&isi_1 {
+ status = "disabled";
+};
+
+&isi_2 {
+ status = "disabled";
+};
+
+&isi_3 {
+ status = "disabled";
+};
+
+&isi_5 {
+ status = "disabled";
+};
+
+&isi_6 {
+ status = "disabled";
+};
+
+&isi_7 {
+ status = "disabled";
+};
+
+&i2c0_mipi_csi0 {
+ clock-frequency = <100000>;
+ status = "okay";
+
+ ov5640_mipi: ov5640_mipi@3c {
+ compatible = "ovti,ov5640_mipi_v3";
+ reg = <0x3c>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_mipi_csi0>;
+ clocks = <&clk IMX8QM_24MHZ>;
+ clock-names = "csi_mclk";
+ csi_id = <0>;
+ pwn-gpios = <&gpio1 28 GPIO_ACTIVE_LOW>;
+ rst-gpios = <&gpio1 27 GPIO_ACTIVE_HIGH>;
+ mclk = <24000000>;
+ mclk_source = <0>;
+ mipi_csi;
+ status = "okay";
+ port {
+ ov5640_mipi_ep: endpoint {
+ remote-endpoint = <&mipi_csi0_ep>;
+ };
+ };
+ };
+
+ max9286_mipi@6A {
+ status = "disabled";
+ };
+};
+
+&i2c0_mipi_csi1 {
+ clock-frequency = <100000>;
+ status = "okay";
+
+ ov5640_mipi@3c {
+ compatible = "ovti,ov5640_mipi_v3";
+ reg = <0x3c>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_mipi_csi1>;
+ clocks = <&clk IMX8QM_24MHZ>;
+ clock-names = "csi_mclk";
+ csi_id = <1>;
+ pwn-gpios = <&gpio1 31 GPIO_ACTIVE_LOW>;
+ rst-gpios = <&gpio1 30 GPIO_ACTIVE_HIGH>;
+ mclk = <24000000>;
+ mclk_source = <0>;
+ mipi_csi;
+ status = "okay";
+ port {
+ ov5640_mipi_ep_1: endpoint {
+ remote-endpoint = <&mipi_csi1_ep>;
+ };
+ };
+ };
+
+ max9286_mipi@6A {
+ status = "disabled";
+ };
+};
+
+&mipi_csi_0 {
+ /delete-property/virtual-channel;
+ status = "okay";
+
+ port@0 {
+ reg = <0>;
+ mipi_csi0_ep: endpoint {
+ remote-endpoint = <&ov5640_mipi_ep>;
+ data-lanes = <1 2>;
+ };
+ };
+};
+
+&mipi_csi_1 {
+ /delete-property/virtual-channel;
+ status = "okay";
+
+ port@1 {
+ reg = <1>;
+ mipi_csi1_ep: endpoint {
+ remote-endpoint = <&ov5640_mipi_ep_1>;
+ data-lanes = <1 2>;
+ };
+ };
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8qm-mek-root.dts b/arch/arm64/boot/dts/freescale/fsl-imx8qm-mek-root.dts
new file mode 100644
index 000000000000..542d83459d09
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8qm-mek-root.dts
@@ -0,0 +1,119 @@
+/*
+ * Copyright 2018 NXP
+ *
+ * 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 "fsl-imx8qm-mek.dts"
+
+/ {
+ domu {
+ /*
+ * There are 5 MUs, 0A is used by root cell, 1A is used
+ * by ATF, so for non-root cell, 2A/3A/4A could be used.
+ * SC_R_MU_0A
+ * SC_R_MU_1A
+ * SC_R_MU_2A
+ * SC_R_MU_3A
+ * SC_R_MU_4A
+ * The rsrcs and pads will be configured by uboot scu_rm cmd
+ */
+ #address-cells = <1>;
+ #size-cells = <0>;
+ doma {
+ /*
+ * This is not for domu, this is just reuse
+ * the method for jailhouse inmate non root cell
+ * Linux.
+ */
+ compatible = "xen,domu";
+ /*
+ * The reg property will be updated by U-Boot to
+ * reflect the partition id.
+ */
+ reg = <0>;
+ init_on_rsrcs = <
+ SC_R_MU_2A
+ >;
+ rsrcs = <
+ SC_R_SDHC_0
+ SC_R_DMA_0_CH16
+ SC_R_DMA_0_CH17
+ SC_R_UART_2
+ SC_R_MU_2A
+ >;
+ pads = <
+ /* emmc */
+ SC_P_EMMC0_CLK
+ SC_P_EMMC0_CMD
+ SC_P_EMMC0_DATA0
+ SC_P_EMMC0_DATA1
+ SC_P_EMMC0_DATA2
+ SC_P_EMMC0_DATA3
+ SC_P_EMMC0_DATA4
+ SC_P_EMMC0_DATA5
+ SC_P_EMMC0_DATA6
+ SC_P_EMMC0_DATA7
+ SC_P_EMMC0_STROBE
+ SC_P_EMMC0_RESET_B
+ /* lpuart2 */
+ SC_P_UART0_RTS_B
+ SC_P_UART0_CTS_B
+ >;
+ };
+ };
+
+};
+
+&{/reserved-memory} {
+
+ jh_reserved: jh@0xfdc00000 {
+ no-map;
+ reg = <0x0 0xfdc00000 0x0 0x400000>;
+ };
+
+ loader_reserved: loader@0xfdb00000 {
+ no-map;
+ reg = <0x0 0xfdb00000 0x0 0x00100000>;
+ };
+
+ ivshmem_reserved: ivshmem@0xfd900000 {
+ no-map;
+ reg = <0x0 0xfd900000 0x0 0x00200000>;
+ };
+
+ pci_reserved: pci@0xfd700000 {
+ no-map;
+ reg = <0x0 0xfd700000 0x0 0x00200000>;
+ };
+
+ /* Decrease if no need such big memory */
+ inmate_reserved: inmate@0xdf7000000 {
+ no-map;
+ reg = <0x0 0xdf700000 0x0 0x1e000000>;
+ };
+};
+
+&smmu {
+ /* Jailhouse hypervisor will initialize SMMU and use it. */
+ status = "disabled";
+};
+
+&usdhc1 {
+ /* Let U-Boot program SID */
+ iommus = <&smmu 0x10 0x7f80>;
+ /delete-property/ compatible;
+};
+
+&lpuart2 {
+ /* Let inmate linux use this for console */
+ status = "disabled";
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8qm-mek-rpmsg.dts b/arch/arm64/boot/dts/freescale/fsl-imx8qm-mek-rpmsg.dts
new file mode 100644
index 000000000000..fdcd408b6dba
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8qm-mek-rpmsg.dts
@@ -0,0 +1,17 @@
+/*
+ * Copyright 2019 NXP
+ *
+ * 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.
+ */
+
+/dts-v1/;
+
+#include "fsl-imx8qm-mek-rpmsg.dtsi"
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8qm-mek-rpmsg.dtsi b/arch/arm64/boot/dts/freescale/fsl-imx8qm-mek-rpmsg.dtsi
new file mode 100644
index 000000000000..c35ca212d5f7
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8qm-mek-rpmsg.dtsi
@@ -0,0 +1,109 @@
+/*
+ * Copyright 2019 NXP
+ *
+ * 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 "fsl-imx8qm-mek.dtsi"
+
+/delete-node/ &i2c0_cm41;
+
+&i2c_rpbus_1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "okay";
+
+ pca6416: gpio@20 {
+ compatible = "ti,tca6416";
+ reg = <0x20>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ cs42888: cs42888@48 {
+ compatible = "cirrus,cs42888";
+ reg = <0x48>;
+ clocks = <&clk IMX8QM_AUD_MCLKOUT0>;
+ clock-names = "mclk";
+ VA-supply = <&reg_audio>;
+ VD-supply = <&reg_audio>;
+ VLS-supply = <&reg_audio>;
+ VLC-supply = <&reg_audio>;
+ reset-gpio = <&gpio4 25 1>;
+ power-domains = <&pd_mclk_out0>;
+ assigned-clocks = <&clk IMX8QM_AUD_PLL0_DIV>,
+ <&clk IMX8QM_AUD_ACM_AUD_PLL_CLK0_DIV>,
+ <&clk IMX8QM_AUD_ACM_AUD_REC_CLK0_DIV>,
+ <&clk IMX8QM_AUD_MCLKOUT0>;
+ assigned-clock-rates = <786432000>, <49152000>, <12288000>, <12288000>;
+ fsl,txs-rxm;
+ status = "okay";
+ };
+};
+
+&rpmsg{
+ /*
+ * 64K for one rpmsg instance:
+ */
+ vdev-nums = <2>;
+ reg = <0x0 0x90000000 0x0 0x20000>;
+ status = "okay";
+};
+
+&rpmsg1{
+ /*
+ * 64K for one rpmsg instance, using 2 instance
+ * 0x90110000 - 0x9011FFFF: audio
+ */
+ vdev-nums = <2>;
+ reg = <0x0 0x90100000 0x0 0x20000>;
+ status = "okay";
+};
+
+&reg_can01_en {
+ status = "disabled";
+};
+
+&reg_can2_en {
+ status = "disabled";
+};
+
+&reg_can01_stby {
+ status = "disabled";
+};
+
+&reg_can2_stby {
+ status = "disabled";
+};
+
+&intmux_cm41 {
+ status = "disabled";
+};
+
+&intmux_cm40 {
+ status = "disabled";
+};
+
+&flexcan1 {
+ status = "disabled";
+};
+
+&flexcan2 {
+ status = "disabled";
+};
+
+&flexcan3 {
+ status = "disabled";
+};
+
+&flexspi0 {
+ status = "disabled";
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8qm-mek.dts b/arch/arm64/boot/dts/freescale/fsl-imx8qm-mek.dts
new file mode 100644
index 000000000000..c7e3d6a2deaf
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8qm-mek.dts
@@ -0,0 +1,17 @@
+/*
+ * Copyright 2017-2018 NXP
+ *
+ * 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.
+ */
+
+/dts-v1/;
+
+#include "fsl-imx8qm-mek.dtsi"
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8qm-mek.dtsi b/arch/arm64/boot/dts/freescale/fsl-imx8qm-mek.dtsi
new file mode 100644
index 000000000000..2f832826340a
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8qm-mek.dtsi
@@ -0,0 +1,1522 @@
+/*
+ * Copyright 2017-2018 NXP
+ *
+ * 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 "fsl-imx8qm.dtsi"
+
+/ {
+ model = "Freescale i.MX8QM MEK";
+ compatible = "fsl,imx8qm-mek", "fsl,imx8qm";
+
+ chosen {
+ bootargs = "console=ttyLP0,115200 earlycon=lpuart32,0x5a060000,115200";
+ stdout-path = &lpuart0;
+ };
+
+ brcmfmac: brcmfmac {
+ compatible = "cypress,brcmfmac";
+ pinctrl-names = "init", "idle", "default";
+ pinctrl-0 = <&pinctrl_wifi_init>;
+ pinctrl-1 = <&pinctrl_wifi_init>;
+ pinctrl-2 = <&pinctrl_wifi>;
+ };
+
+ modem_reset: modem-reset {
+ compatible = "gpio-reset";
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&pinctrl_modem_reset>;
+ pinctrl-1 = <&pinctrl_modem_reset_sleep>;
+ reset-gpios = <&gpio4 22 GPIO_ACTIVE_LOW>;
+ reset-delay-us = <2000>;
+ reset-post-delay-ms = <40>;
+ #reset-cells = <0>;
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ reg_can01_en: regulator-can01-gen {
+ compatible = "regulator-fixed";
+ regulator-name = "can01-en";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&pca6416 3 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ reg_can2_en: regulator-can2-gen {
+ compatible = "regulator-fixed";
+ regulator-name = "can2-en";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&pca6416 4 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ reg_can01_stby: regulator-can01-stby {
+ compatible = "regulator-fixed";
+ regulator-name = "can01-stby";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&pca6416 5 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ vin-supply = <&reg_can01_en>;
+ };
+
+ reg_can2_stby: regulator-can2-stby {
+ compatible = "regulator-fixed";
+ regulator-name = "can2-stby";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&pca6416 6 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ vin-supply = <&reg_can2_en>;
+ };
+
+ reg_fec2_supply: fec2_nvcc {
+ compatible = "regulator-fixed";
+ regulator-name = "fec2_nvcc";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ gpio = <&max7322 0 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ epdev_on: fixedregulator@100 {
+ compatible = "regulator-fixed";
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&pinctrl_wlreg_on>;
+ pinctrl-1 = <&pinctrl_wlreg_on_sleep>;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-name = "epdev_on";
+ gpio = <&gpio1 13 0>;
+ enable-active-high;
+ };
+
+ reg_usdhc2_vmmc: usdhc2_vmmc {
+ compatible = "regulator-fixed";
+ regulator-name = "sw-3p3-sd1";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&gpio4 7 GPIO_ACTIVE_HIGH>;
+ off-on-delay = <4800>;
+ enable-active-high;
+ };
+
+ reg_audio: fixedregulator@2 {
+ compatible = "regulator-fixed";
+ reg = <2>;
+ regulator-name = "cs42888_supply";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ reg_vref_1v8: adc_vref_1v8 {
+ compatible = "regulator-fixed";
+ regulator-name = "vref_1v8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+ };
+
+ sound: sound {
+ compatible = "fsl,imx7d-evk-wm8960",
+ "fsl,imx-audio-wm8960";
+ model = "wm8960-audio";
+ cpu-dai = <&sai1>;
+ audio-codec = <&wm8960>;
+ codec-master;
+ /*
+ * hp-det = <hp-det-pin hp-det-polarity>;
+ * hp-det-pin: JD1 JD2 or JD3
+ * hp-det-polarity = 0: hp detect high for headphone
+ * hp-det-polarity = 1: hp detect high for speaker
+ */
+ hp-det = <2 0>;
+ hp-det-gpios = <&gpio0 31 0>;
+ mic-det-gpios = <&gpio0 31 0>;
+ audio-routing =
+ "Headphone Jack", "HP_L",
+ "Headphone Jack", "HP_R",
+ "Ext Spk", "SPK_LP",
+ "Ext Spk", "SPK_LN",
+ "Ext Spk", "SPK_RP",
+ "Ext Spk", "SPK_RN",
+ "LINPUT2", "Mic Jack",
+ "LINPUT3", "Mic Jack",
+ "RINPUT1", "Main MIC",
+ "RINPUT2", "Main MIC",
+ "Mic Jack", "MICB",
+ "Main MIC", "MICB",
+ "CPU-Playback", "ASRC-Playback",
+ "Playback", "CPU-Playback",
+ "ASRC-Capture", "CPU-Capture",
+ "CPU-Capture", "Capture";
+ };
+
+ sound-cs42888 {
+ compatible = "fsl,imx8qm-sabreauto-cs42888",
+ "fsl,imx-audio-cs42888";
+ model = "imx-cs42888";
+ esai-controller = <&esai0>;
+ audio-codec = <&cs42888>;
+ asrc-controller = <&asrc0>;
+ status = "okay";
+ };
+
+ sound-amix-sai {
+ compatible = "fsl,imx-audio-amix";
+ model = "amix-audio-sai";
+ dais = <&sai6>, <&sai7>;
+ amix-controller = <&amix>;
+ };
+
+ lvds_backlight0: lvds_backlight@0 {
+ compatible = "pwm-backlight";
+ pwms = <&lvds0_pwm 0 100000 0>;
+
+ brightness-levels = < 0 1 2 3 4 5 6 7 8 9
+ 10 11 12 13 14 15 16 17 18 19
+ 20 21 22 23 24 25 26 27 28 29
+ 30 31 32 33 34 35 36 37 38 39
+ 40 41 42 43 44 45 46 47 48 49
+ 50 51 52 53 54 55 56 57 58 59
+ 60 61 62 63 64 65 66 67 68 69
+ 70 71 72 73 74 75 76 77 78 79
+ 80 81 82 83 84 85 86 87 88 89
+ 90 91 92 93 94 95 96 97 98 99
+ 100>;
+ default-brightness-level = <80>;
+ };
+
+ lvds_backlight1: lvds_backlight@1 {
+ compatible = "pwm-backlight";
+ pwms = <&lvds1_pwm 0 100000 0>;
+
+ brightness-levels = < 0 1 2 3 4 5 6 7 8 9
+ 10 11 12 13 14 15 16 17 18 19
+ 20 21 22 23 24 25 26 27 28 29
+ 30 31 32 33 34 35 36 37 38 39
+ 40 41 42 43 44 45 46 47 48 49
+ 50 51 52 53 54 55 56 57 58 59
+ 60 61 62 63 64 65 66 67 68 69
+ 70 71 72 73 74 75 76 77 78 79
+ 80 81 82 83 84 85 86 87 88 89
+ 90 91 92 93 94 95 96 97 98 99
+ 100>;
+ default-brightness-level = <80>;
+ };
+};
+
+&acm {
+ status = "okay";
+};
+
+&amix {
+ status = "okay";
+};
+
+&sai6 {
+ assigned-clocks = <&clk IMX8QM_ACM_SAI6_MCLK_SEL>,
+ <&clk IMX8QM_AUD_PLL1_DIV>,
+ <&clk IMX8QM_AUD_ACM_AUD_PLL_CLK1_DIV>,
+ <&clk IMX8QM_AUD_ACM_AUD_REC_CLK1_DIV>,
+ <&clk IMX8QM_AUD_SAI_6_MCLK>;
+ assigned-clock-parents = <&clk IMX8QM_AUD_ACM_AUD_PLL_CLK1_CLK>;
+ assigned-clock-rates = <0>, <786432000>, <98304000>, <12288000>, <98304000>;
+ fsl,sai-asynchronous;
+ fsl,txm-rxs;
+ status = "okay";
+};
+
+&sai7 {
+ assigned-clocks = <&clk IMX8QM_ACM_SAI7_MCLK_SEL>,
+ <&clk IMX8QM_AUD_PLL1_DIV>,
+ <&clk IMX8QM_AUD_ACM_AUD_PLL_CLK1_DIV>,
+ <&clk IMX8QM_AUD_ACM_AUD_REC_CLK1_DIV>,
+ <&clk IMX8QM_AUD_SAI_7_MCLK>;
+ assigned-clock-parents = <&clk IMX8QM_AUD_ACM_AUD_PLL_CLK1_CLK>;
+ assigned-clock-rates = <0>, <786432000>, <98304000>, <12288000>, <98304000>;
+ fsl,sai-asynchronous;
+ fsl,txm-rxs;
+ status = "okay";
+};
+
+&iomuxc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_hog>;
+
+ imx8qm-mek {
+ pinctrl_hog: hoggrp {
+ fsl,pins = <
+ SC_P_MCLK_OUT0_AUD_ACM_MCLK_OUT0 0x0600004c
+ SC_P_QSPI1A_DATA1_LSIO_GPIO4_IO25 0x0600004c
+ SC_P_SCU_GPIO0_03_LSIO_GPIO0_IO31 0x0600004c
+ >;
+ };
+
+ pinctrl_adc0: adc0grp {
+ fsl,pins = <
+ SC_P_ADC_IN0_DMA_ADC0_IN0 0xc0000060
+ >;
+ };
+
+ pinctrl_cm41_i2c0: cm41i2c0grp {
+ fsl,pins = <
+ SC_P_M41_I2C0_SCL_M41_I2C0_SCL 0x0600004c
+ SC_P_M41_I2C0_SDA_M41_I2C0_SDA 0x0600004c
+ >;
+ };
+
+ pinctrl_esai0: esai0grp {
+ fsl,pins = <
+ SC_P_ESAI0_FSR_AUD_ESAI0_FSR 0xc6000040
+ SC_P_ESAI0_FST_AUD_ESAI0_FST 0xc6000040
+ SC_P_ESAI0_SCKR_AUD_ESAI0_SCKR 0xc6000040
+ SC_P_ESAI0_SCKT_AUD_ESAI0_SCKT 0xc6000040
+ SC_P_ESAI0_TX0_AUD_ESAI0_TX0 0xc6000040
+ SC_P_ESAI0_TX1_AUD_ESAI0_TX1 0xc6000040
+ SC_P_ESAI0_TX2_RX3_AUD_ESAI0_TX2_RX3 0xc6000040
+ SC_P_ESAI0_TX3_RX2_AUD_ESAI0_TX3_RX2 0xc6000040
+ SC_P_ESAI0_TX4_RX1_AUD_ESAI0_TX4_RX1 0xc6000040
+ SC_P_ESAI0_TX5_RX0_AUD_ESAI0_TX5_RX0 0xc6000040
+ >;
+ };
+
+ pinctrl_fec1: fec1grp {
+ fsl,pins = <
+ SC_P_COMP_CTL_GPIO_1V8_3V3_ENET_ENETB_PAD 0x000014a0
+ SC_P_ENET0_MDC_CONN_ENET0_MDC 0x06000020
+ SC_P_ENET0_MDIO_CONN_ENET0_MDIO 0x06000020
+ SC_P_ENET0_RGMII_TX_CTL_CONN_ENET0_RGMII_TX_CTL 0x00000061
+ SC_P_ENET0_RGMII_TXC_CONN_ENET0_RGMII_TXC 0x00000061
+ SC_P_ENET0_RGMII_TXD0_CONN_ENET0_RGMII_TXD0 0x00000061
+ SC_P_ENET0_RGMII_TXD1_CONN_ENET0_RGMII_TXD1 0x00000061
+ SC_P_ENET0_RGMII_TXD2_CONN_ENET0_RGMII_TXD2 0x00000061
+ SC_P_ENET0_RGMII_TXD3_CONN_ENET0_RGMII_TXD3 0x00000061
+ SC_P_ENET0_RGMII_RXC_CONN_ENET0_RGMII_RXC 0x00000061
+ SC_P_ENET0_RGMII_RX_CTL_CONN_ENET0_RGMII_RX_CTL 0x00000061
+ SC_P_ENET0_RGMII_RXD0_CONN_ENET0_RGMII_RXD0 0x00000061
+ SC_P_ENET0_RGMII_RXD1_CONN_ENET0_RGMII_RXD1 0x00000061
+ SC_P_ENET0_RGMII_RXD2_CONN_ENET0_RGMII_RXD2 0x00000061
+ SC_P_ENET0_RGMII_RXD3_CONN_ENET0_RGMII_RXD3 0x00000061
+ >;
+ };
+
+ pinctrl_fec2: fec2grp {
+ fsl,pins = <
+ SC_P_COMP_CTL_GPIO_1V8_3V3_ENET_ENETA_PAD 0x000014a0
+ SC_P_ENET1_RGMII_TX_CTL_CONN_ENET1_RGMII_TX_CTL 0x00000060
+ SC_P_ENET1_RGMII_TXC_CONN_ENET1_RGMII_TXC 0x00000060
+ SC_P_ENET1_RGMII_TXD0_CONN_ENET1_RGMII_TXD0 0x00000060
+ SC_P_ENET1_RGMII_TXD1_CONN_ENET1_RGMII_TXD1 0x00000060
+ SC_P_ENET1_RGMII_TXD2_CONN_ENET1_RGMII_TXD2 0x00000060
+ SC_P_ENET1_RGMII_TXD3_CONN_ENET1_RGMII_TXD3 0x00000060
+ SC_P_ENET1_RGMII_RXC_CONN_ENET1_RGMII_RXC 0x00000060
+ SC_P_ENET1_RGMII_RX_CTL_CONN_ENET1_RGMII_RX_CTL 0x00000060
+ SC_P_ENET1_RGMII_RXD0_CONN_ENET1_RGMII_RXD0 0x00000060
+ SC_P_ENET1_RGMII_RXD1_CONN_ENET1_RGMII_RXD1 0x00000060
+ SC_P_ENET1_RGMII_RXD2_CONN_ENET1_RGMII_RXD2 0x00000060
+ SC_P_ENET1_RGMII_RXD3_CONN_ENET1_RGMII_RXD3 0x00000060
+ >;
+ };
+
+ pinctrl_flexspi0: flexspi0grp {
+ fsl,pins = <
+ SC_P_QSPI0A_DATA0_LSIO_QSPI0A_DATA0 0x06000021
+ SC_P_QSPI0A_DATA1_LSIO_QSPI0A_DATA1 0x06000021
+ SC_P_QSPI0A_DATA2_LSIO_QSPI0A_DATA2 0x06000021
+ SC_P_QSPI0A_DATA3_LSIO_QSPI0A_DATA3 0x06000021
+ SC_P_QSPI0A_DQS_LSIO_QSPI0A_DQS 0x06000021
+ SC_P_QSPI0A_SS0_B_LSIO_QSPI0A_SS0_B 0x06000021
+ SC_P_QSPI0A_SS1_B_LSIO_QSPI0A_SS1_B 0x06000021
+ SC_P_QSPI0A_SCLK_LSIO_QSPI0A_SCLK 0x06000021
+ SC_P_QSPI0B_SCLK_LSIO_QSPI0B_SCLK 0x06000021
+ SC_P_QSPI0B_DATA0_LSIO_QSPI0B_DATA0 0x06000021
+ SC_P_QSPI0B_DATA1_LSIO_QSPI0B_DATA1 0x06000021
+ SC_P_QSPI0B_DATA2_LSIO_QSPI0B_DATA2 0x06000021
+ SC_P_QSPI0B_DATA3_LSIO_QSPI0B_DATA3 0x06000021
+ SC_P_QSPI0B_DQS_LSIO_QSPI0B_DQS 0x06000021
+ SC_P_QSPI0B_SS0_B_LSIO_QSPI0B_SS0_B 0x06000021
+ SC_P_QSPI0B_SS1_B_LSIO_QSPI0B_SS1_B 0x06000021
+ >;
+ };
+
+ pinctrl_flexcan1: flexcan0grp {
+ fsl,pins = <
+ SC_P_FLEXCAN0_TX_DMA_FLEXCAN0_TX 0x21
+ SC_P_FLEXCAN0_RX_DMA_FLEXCAN0_RX 0x21
+ >;
+ };
+
+ pinctrl_flexcan2: flexcan1grp {
+ fsl,pins = <
+ SC_P_FLEXCAN1_TX_DMA_FLEXCAN1_TX 0x21
+ SC_P_FLEXCAN1_RX_DMA_FLEXCAN1_RX 0x21
+ >;
+ };
+
+ pinctrl_flexcan3: flexcan2grp {
+ fsl,pins = <
+ SC_P_FLEXCAN2_TX_DMA_FLEXCAN2_TX 0x21
+ SC_P_FLEXCAN2_RX_DMA_FLEXCAN2_RX 0x21
+ >;
+ };
+
+ pinctrl_lpuart0: lpuart0grp {
+ fsl,pins = <
+ SC_P_UART0_RX_DMA_UART0_RX 0x06000020
+ SC_P_UART0_TX_DMA_UART0_TX 0x06000020
+ >;
+ };
+
+ pinctrl_lpuart1: lpuart1grp {
+ fsl,pins = <
+ SC_P_UART1_RX_DMA_UART1_RX 0x06000020
+ SC_P_UART1_TX_DMA_UART1_TX 0x06000020
+ SC_P_UART1_CTS_B_DMA_UART1_CTS_B 0x06000020
+ SC_P_UART1_RTS_B_DMA_UART1_RTS_B 0x06000020
+ >;
+ };
+
+ pinctrl_lpuart2: lpuart2grp {
+ fsl,pins = <
+ SC_P_UART0_RTS_B_DMA_UART2_RX 0x06000020
+ SC_P_UART0_CTS_B_DMA_UART2_TX 0x06000020
+ >;
+ };
+
+ pinctrl_lpuart3: lpuart3grp {
+ fsl,pins = <
+ SC_P_M41_GPIO0_00_DMA_UART3_RX 0x06000020
+ SC_P_M41_GPIO0_01_DMA_UART3_TX 0x06000020
+ >;
+ };
+
+ pinctrl_mlb: mlbgrp {
+ fsl,pins = <
+ SC_P_MLB_SIG_CONN_MLB_SIG 0x21
+ SC_P_MLB_CLK_CONN_MLB_CLK 0x21
+ SC_P_MLB_DATA_CONN_MLB_DATA 0x21
+ >;
+ };
+
+ pinctrl_modem_reset: modemresetgrp {
+ fsl,pins = <
+ SC_P_QSPI1A_DQS_LSIO_GPIO4_IO22 0x06000021
+ >;
+ };
+
+ pinctrl_modem_reset_sleep: modemreset_sleepgrp {
+ fsl,pins = <
+ SC_P_QSPI1A_DQS_LSIO_GPIO4_IO22 0x07800021
+ >;
+ };
+
+ pinctrl_sai1: sai1grp {
+ fsl,pins = <
+ SC_P_SAI1_RXD_AUD_SAI1_RXD 0x06000040
+ SC_P_SAI1_RXC_AUD_SAI1_RXC 0x06000040
+ SC_P_SAI1_RXFS_AUD_SAI1_RXFS 0x06000040
+ SC_P_SAI1_TXD_AUD_SAI1_TXD 0x06000060
+ SC_P_SAI1_TXC_AUD_SAI1_TXC 0x06000040
+ >;
+ };
+
+ pinctrl_i2c0: i2c0grp {
+ fsl,pins = <
+ SC_P_HDMI_TX0_TS_SCL_DMA_I2C0_SCL 0x06000021
+ SC_P_HDMI_TX0_TS_SDA_DMA_I2C0_SDA 0x06000021
+ >;
+ };
+
+ pinctrl_isl29023: isl29023grp {
+ fsl,pins = <
+ SC_P_USDHC2_WP_LSIO_GPIO4_IO11 0x00000021
+ >;
+ };
+
+ pinctrl_i2c1: i2c1grp {
+ fsl,pins = <
+ SC_P_GPT0_CLK_DMA_I2C1_SCL 0x0600004c
+ SC_P_GPT0_CAPTURE_DMA_I2C1_SDA 0x0600004c
+ >;
+ };
+
+ pinctrl_pciea: pcieagrp{
+ fsl,pins = <
+ SC_P_PCIE_CTRL0_CLKREQ_B_LSIO_GPIO4_IO27 0x06000021
+ SC_P_PCIE_CTRL0_WAKE_B_LSIO_GPIO4_IO28 0x04000021
+ SC_P_PCIE_CTRL0_PERST_B_LSIO_GPIO4_IO29 0x06000021
+ SC_P_USDHC2_RESET_B_LSIO_GPIO4_IO09 0x06000021
+ >;
+ };
+
+ pinctrl_sim0: sim0grp {
+ fsl,pins = <
+ SC_P_SIM0_CLK_DMA_SIM0_CLK 0x21
+ SC_P_SIM0_IO_DMA_SIM0_IO 0x21
+ SC_P_SIM0_PD_DMA_SIM0_PD 0x21
+ SC_P_SIM0_POWER_EN_DMA_SIM0_POWER_EN 0x21
+ SC_P_SIM0_RST_DMA_SIM0_RST 0x21
+ >;
+ };
+
+ pinctrl_typec: typecgrp {
+ fsl,pins = <
+ SC_P_QSPI1A_SS0_B_LSIO_GPIO4_IO19 0x60
+ SC_P_USB_SS3_TC3_LSIO_GPIO4_IO06 0x60
+ SC_P_QSPI1A_DATA0_LSIO_GPIO4_IO26 0x00000021
+ >;
+ };
+
+ pinctrl_usbotg1: usbotg1 {
+ fsl,pins = <
+ SC_P_USB_SS3_TC0_CONN_USB_OTG1_PWR 0x00000021
+ >;
+ };
+
+ pinctrl_usdhc1: usdhc1grp {
+ fsl,pins = <
+ SC_P_EMMC0_CLK_CONN_EMMC0_CLK 0x06000041
+ SC_P_EMMC0_CMD_CONN_EMMC0_CMD 0x00000021
+ SC_P_EMMC0_DATA0_CONN_EMMC0_DATA0 0x00000021
+ SC_P_EMMC0_DATA1_CONN_EMMC0_DATA1 0x00000021
+ SC_P_EMMC0_DATA2_CONN_EMMC0_DATA2 0x00000021
+ SC_P_EMMC0_DATA3_CONN_EMMC0_DATA3 0x00000021
+ SC_P_EMMC0_DATA4_CONN_EMMC0_DATA4 0x00000021
+ SC_P_EMMC0_DATA5_CONN_EMMC0_DATA5 0x00000021
+ SC_P_EMMC0_DATA6_CONN_EMMC0_DATA6 0x00000021
+ SC_P_EMMC0_DATA7_CONN_EMMC0_DATA7 0x00000021
+ SC_P_EMMC0_STROBE_CONN_EMMC0_STROBE 0x00000041
+ SC_P_EMMC0_RESET_B_CONN_EMMC0_RESET_B 0x00000021
+ >;
+ };
+
+ pinctrl_usdhc1_100mhz: usdhc1grp100mhz {
+ fsl,pins = <
+ SC_P_EMMC0_CLK_CONN_EMMC0_CLK 0x06000040
+ SC_P_EMMC0_CMD_CONN_EMMC0_CMD 0x00000020
+ SC_P_EMMC0_DATA0_CONN_EMMC0_DATA0 0x00000020
+ SC_P_EMMC0_DATA1_CONN_EMMC0_DATA1 0x00000020
+ SC_P_EMMC0_DATA2_CONN_EMMC0_DATA2 0x00000020
+ SC_P_EMMC0_DATA3_CONN_EMMC0_DATA3 0x00000020
+ SC_P_EMMC0_DATA4_CONN_EMMC0_DATA4 0x00000020
+ SC_P_EMMC0_DATA5_CONN_EMMC0_DATA5 0x00000020
+ SC_P_EMMC0_DATA6_CONN_EMMC0_DATA6 0x00000020
+ SC_P_EMMC0_DATA7_CONN_EMMC0_DATA7 0x00000020
+ SC_P_EMMC0_STROBE_CONN_EMMC0_STROBE 0x00000040
+ SC_P_EMMC0_RESET_B_CONN_EMMC0_RESET_B 0x00000020
+ >;
+ };
+
+ pinctrl_usdhc1_200mhz: usdhc1grp200mhz {
+ fsl,pins = <
+ SC_P_EMMC0_CLK_CONN_EMMC0_CLK 0x06000040
+ SC_P_EMMC0_CMD_CONN_EMMC0_CMD 0x00000020
+ SC_P_EMMC0_DATA0_CONN_EMMC0_DATA0 0x00000020
+ SC_P_EMMC0_DATA1_CONN_EMMC0_DATA1 0x00000020
+ SC_P_EMMC0_DATA2_CONN_EMMC0_DATA2 0x00000020
+ SC_P_EMMC0_DATA3_CONN_EMMC0_DATA3 0x00000020
+ SC_P_EMMC0_DATA4_CONN_EMMC0_DATA4 0x00000020
+ SC_P_EMMC0_DATA5_CONN_EMMC0_DATA5 0x00000020
+ SC_P_EMMC0_DATA6_CONN_EMMC0_DATA6 0x00000020
+ SC_P_EMMC0_DATA7_CONN_EMMC0_DATA7 0x00000020
+ SC_P_EMMC0_STROBE_CONN_EMMC0_STROBE 0x00000040
+ SC_P_EMMC0_RESET_B_CONN_EMMC0_RESET_B 0x00000020
+ >;
+ };
+
+ pinctrl_usdhc2_gpio: usdhc2grpgpio {
+ fsl,pins = <
+ SC_P_USDHC1_DATA6_LSIO_GPIO5_IO21 0x00000021
+ SC_P_USDHC1_DATA7_LSIO_GPIO5_IO22 0x00000021
+ SC_P_USDHC1_RESET_B_LSIO_GPIO4_IO07 0x00000021
+ >;
+ };
+
+ pinctrl_usdhc2: usdhc2grp {
+ fsl,pins = <
+ SC_P_USDHC1_CLK_CONN_USDHC1_CLK 0x06000041
+ SC_P_USDHC1_CMD_CONN_USDHC1_CMD 0x00000021
+ SC_P_USDHC1_DATA0_CONN_USDHC1_DATA0 0x00000021
+ SC_P_USDHC1_DATA1_CONN_USDHC1_DATA1 0x00000021
+ SC_P_USDHC1_DATA2_CONN_USDHC1_DATA2 0x00000021
+ SC_P_USDHC1_DATA3_CONN_USDHC1_DATA3 0x00000021
+ SC_P_USDHC1_VSELECT_CONN_USDHC1_VSELECT 0x00000021
+ >;
+ };
+
+ pinctrl_usdhc2_100mhz: usdhc2grp100mhz {
+ fsl,pins = <
+ SC_P_USDHC1_CLK_CONN_USDHC1_CLK 0x06000040
+ SC_P_USDHC1_CMD_CONN_USDHC1_CMD 0x00000020
+ SC_P_USDHC1_DATA0_CONN_USDHC1_DATA0 0x00000020
+ SC_P_USDHC1_DATA1_CONN_USDHC1_DATA1 0x00000020
+ SC_P_USDHC1_DATA2_CONN_USDHC1_DATA2 0x00000020
+ SC_P_USDHC1_DATA3_CONN_USDHC1_DATA3 0x00000020
+ SC_P_USDHC1_VSELECT_CONN_USDHC1_VSELECT 0x00000020
+ >;
+ };
+
+ pinctrl_usdhc2_200mhz: usdhc2grp200mhz {
+ fsl,pins = <
+ SC_P_USDHC1_CLK_CONN_USDHC1_CLK 0x06000040
+ SC_P_USDHC1_CMD_CONN_USDHC1_CMD 0x00000020
+ SC_P_USDHC1_DATA0_CONN_USDHC1_DATA0 0x00000020
+ SC_P_USDHC1_DATA1_CONN_USDHC1_DATA1 0x00000020
+ SC_P_USDHC1_DATA2_CONN_USDHC1_DATA2 0x00000020
+ SC_P_USDHC1_DATA3_CONN_USDHC1_DATA3 0x00000020
+ SC_P_USDHC1_VSELECT_CONN_USDHC1_VSELECT 0x00000020
+ >;
+ };
+ pinctrl_lvds0_lpi2c1: lvds0lpi2c1grp {
+ fsl,pins = <
+ SC_P_LVDS0_I2C1_SCL_LVDS0_I2C1_SCL 0xc600004c
+ SC_P_LVDS0_I2C1_SDA_LVDS0_I2C1_SDA 0xc600004c
+ >;
+ };
+
+ pinctrl_lvds1_lpi2c1: lvds1lpi2c1grp {
+ fsl,pins = <
+ SC_P_LVDS1_I2C1_SCL_LVDS1_I2C1_SCL 0xc600004c
+ SC_P_LVDS1_I2C1_SDA_LVDS1_I2C1_SDA 0xc600004c
+ >;
+ };
+
+ pinctrl_lvds0_pwm0: lvds0pwm0grp {
+ fsl,pins = <
+ SC_P_LVDS0_GPIO00_LVDS0_PWM0_OUT 0x00000020
+ >;
+ };
+
+ pinctrl_lvds1_pwm0: lvds1pwm0grp {
+ fsl,pins = <
+ SC_P_LVDS1_GPIO00_LVDS1_PWM0_OUT 0x00000020
+ >;
+ };
+
+ pinctrl_mipi0_lpi2c0: mipi0_lpi2c0grp {
+ fsl,pins = <
+ SC_P_MIPI_DSI0_I2C0_SCL_MIPI_DSI0_I2C0_SCL 0xc600004c
+ SC_P_MIPI_DSI0_I2C0_SDA_MIPI_DSI0_I2C0_SDA 0xc600004c
+ SC_P_MIPI_DSI0_GPIO0_01_LSIO_GPIO1_IO19 0x00000020
+ >;
+ };
+
+ pinctrl_mipi1_lpi2c0: mipi1_lpi2c0grp {
+ fsl,pins = <
+ SC_P_MIPI_DSI1_I2C0_SCL_MIPI_DSI1_I2C0_SCL 0xc600004c
+ SC_P_MIPI_DSI1_I2C0_SDA_MIPI_DSI1_I2C0_SDA 0xc600004c
+ SC_P_MIPI_DSI1_GPIO0_01_LSIO_GPIO1_IO23 0x00000020
+ >;
+ };
+
+ pinctrl_mipi_dsi_0_1_en: mipi_dsi_0_1_en {
+ fsl,pins = <
+ SC_P_LVDS0_I2C0_SDA_LSIO_GPIO1_IO07 0x00000021
+ >;
+ };
+
+ pinctrl_mipi_csi0_en_rst: mipi_csi0_en_rst {
+ fsl,pins = <
+ SC_P_MIPI_CSI0_GPIO0_00_LSIO_GPIO1_IO27 0x00000021
+ SC_P_MIPI_CSI0_GPIO0_01_LSIO_GPIO1_IO28 0x00000021
+ >;
+ };
+
+ pinctrl_mipi_csi1_en_rst: mipi_csi1_en_rst {
+ fsl,pins = <
+ SC_P_MIPI_CSI1_GPIO0_00_LSIO_GPIO1_IO30 0x00000021
+ SC_P_MIPI_CSI1_GPIO0_01_LSIO_GPIO1_IO31 0x00000021
+ >;
+ };
+
+ pinctrl_wifi: wifigrp{
+ fsl,pins = <
+ SC_P_SCU_GPIO0_07_SCU_DSC_RTC_CLOCK_OUTPUT_32K 0x20
+ >;
+ };
+
+ pinctrl_wifi_init: wifi_initgrp{
+ fsl,pins = <
+ SC_P_SCU_GPIO0_07_LSIO_GPIO1_IO03 0x20
+ >;
+ };
+
+ pinctrl_wlreg_on: wlregongrp{
+ fsl,pins = <
+ SC_P_LVDS1_I2C0_SDA_LSIO_GPIO1_IO13 0x06000000
+ >;
+ };
+
+ pinctrl_wlreg_on_sleep: wlregon_sleepgrp{
+ fsl,pins = <
+ SC_P_LVDS1_I2C0_SDA_LSIO_GPIO1_IO13 0x07800000
+ >;
+ };
+ };
+};
+
+&adc0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_adc0>;
+ vref-supply = <&reg_vref_1v8>;
+ status = "okay";
+};
+
+&asrc0 {
+ fsl,asrc-rate = <48000>;
+ status = "okay";
+};
+
+&esai0 {
+ compatible = "fsl,imx8qm-esai";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_esai0>;
+ assigned-clocks = <&clk IMX8QM_ACM_ESAI0_MCLK_SEL>,
+ <&clk IMX8QM_AUD_PLL0_DIV>,
+ <&clk IMX8QM_AUD_ACM_AUD_PLL_CLK0_DIV>,
+ <&clk IMX8QM_AUD_ACM_AUD_REC_CLK0_DIV>,
+ <&clk IMX8QM_AUD_ESAI_0_EXTAL_IPG>;
+ assigned-clock-parents = <&clk IMX8QM_AUD_ACM_AUD_PLL_CLK0_CLK>;
+ assigned-clock-rates = <0>, <786432000>, <49152000>, <12288000>, <49152000>;
+ fsl,txm-rxs;
+ status = "okay";
+};
+
+&emvsim0 {
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&pinctrl_sim0>;
+ pinctrl-1 = <&pinctrl_sim0>;
+ status = "okay";
+};
+&sai1 {
+ assigned-clocks = <&clk IMX8QM_AUD_PLL0_DIV>,
+ <&clk IMX8QM_AUD_ACM_AUD_PLL_CLK0_DIV>,
+ <&clk IMX8QM_AUD_ACM_AUD_REC_CLK0_DIV>,
+ <&clk IMX8QM_AUD_SAI_1_MCLK>;
+ assigned-clock-rates = <786432000>, <49152000>, <12288000>, <49152000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_sai1>;
+ status = "okay";
+};
+
+&usbotg1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usbotg1>;
+ srp-disable;
+ hnp-disable;
+ adp-disable;
+ power-polarity-active-high;
+ disable-over-current;
+ status = "okay";
+};
+
+&usbotg3 {
+ dr_mode = "otg";
+ extcon = <&typec_ptn5110>;
+ status = "okay";
+};
+
+&usdhc1 {
+ pinctrl-names = "default", "state_100mhz", "state_200mhz";
+ pinctrl-0 = <&pinctrl_usdhc1>;
+ pinctrl-1 = <&pinctrl_usdhc1_100mhz>;
+ pinctrl-2 = <&pinctrl_usdhc1_200mhz>;
+ bus-width = <8>;
+ non-removable;
+ status = "okay";
+};
+
+&usdhc2 {
+ pinctrl-names = "default", "state_100mhz", "state_200mhz";
+ pinctrl-0 = <&pinctrl_usdhc2>, <&pinctrl_usdhc2_gpio>;
+ pinctrl-1 = <&pinctrl_usdhc2_100mhz>, <&pinctrl_usdhc2_gpio>;
+ pinctrl-2 = <&pinctrl_usdhc2_200mhz>, <&pinctrl_usdhc2_gpio>;
+ bus-width = <4>;
+ cd-gpios = <&gpio5 22 GPIO_ACTIVE_LOW>;
+ wp-gpios = <&gpio5 21 GPIO_ACTIVE_HIGH>;
+ vmmc-supply = <&reg_usdhc2_vmmc>;
+ status = "okay";
+};
+
+&fec1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_fec1>;
+ phy-mode = "rgmii-txid";
+ phy-handle = <&ethphy0>;
+ fsl,magic-packet;
+ fsl,rgmii_rxc_dly;
+ status = "okay";
+
+ mdio {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ethphy0: ethernet-phy@0 {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <0>;
+ at803x,eee-disabled;
+ at803x,vddio-1p8v;
+ };
+
+ ethphy1: ethernet-phy@1 {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <1>;
+ at803x,eee-disabled;
+ at803x,vddio-1p8v;
+ };
+ };
+};
+
+&flexspi0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_flexspi0>;
+ status = "okay";
+
+ flash0: mt35xu512aba@0 {
+ reg = <0>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "micron,mt35xu512aba";
+ spi-max-frequency = <133000000>;
+ spi-nor,ddr-quad-read-dummy = <8>;
+ };
+};
+
+&flexcan1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_flexcan1>;
+ xceiver-supply = <&reg_can01_stby>;
+ status = "okay";
+};
+
+&flexcan2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_flexcan2>;
+ xceiver-supply = <&reg_can01_stby>;
+ status = "okay";
+};
+
+&flexcan3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_flexcan3>;
+ xceiver-supply = <&reg_can2_stby>;
+ status = "okay";
+};
+
+&i2c0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c0>;
+ status = "okay";
+
+ isl29023@44 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_isl29023>;
+ compatible = "fsl,isl29023";
+ reg = <0x44>;
+ rext = <499>;
+ interrupt-parent = <&gpio4>;
+ interrupts = <11 2>;
+ };
+
+ fxos8700@1e {
+ compatible = "fsl,fxos8700";
+ reg = <0x1e>;
+ interrupt-open-drain;
+ };
+
+ fxas2100x@20 {
+ compatible = "fsl,fxas2100x";
+ reg = <0x20>;
+ interrupt-open-drain;
+ };
+
+ max7322: gpio@68 {
+ compatible = "maxim,max7322";
+ reg = <0x68>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ mpl3115@60 {
+ compatible = "fsl,mpl3115";
+ reg = <0x60>;
+ interrupt-open-drain;
+ };
+
+ typec_ptn5110: typec@50 {
+ compatible = "usb,tcpci";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_typec>;
+ reg = <0x51>;
+ interrupt-parent = <&gpio4>;
+ interrupts = <26 IRQ_TYPE_LEVEL_LOW>;
+ ss-sel-gpios = <&gpio4 6 GPIO_ACTIVE_LOW>;
+ reset-gpios = <&gpio4 19 GPIO_ACTIVE_HIGH>;
+ src-pdos = <0x380190c8 0x3803c0c8>;
+ port-type = "drp";
+ sink-disable;
+ default-role = "source";
+ status = "okay";
+ };
+};
+
+&i2c1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c1>;
+ status = "okay";
+
+ wm8960: wm8960@1a {
+ compatible = "wlf,wm8960";
+ reg = <0x1a>;
+ clocks = <&clk IMX8QM_AUD_MCLKOUT0>;
+ clock-names = "mclk";
+ wlf,shared-lrclk;
+ power-domains = <&pd_mclk_out0>;
+ assigned-clocks = <&clk IMX8QM_AUD_PLL0_DIV>,
+ <&clk IMX8QM_AUD_ACM_AUD_PLL_CLK0_DIV>,
+ <&clk IMX8QM_AUD_ACM_AUD_REC_CLK0_DIV>,
+ <&clk IMX8QM_AUD_MCLKOUT0>;
+ assigned-clock-rates = <786432000>, <49152000>, <12288000>, <12288000>;
+ };
+};
+
+&i2c0_cm41 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_cm41_i2c0>;
+ status = "okay";
+
+ pca6416: gpio@20 {
+ compatible = "ti,tca6416";
+ reg = <0x20>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ cs42888: cs42888@48 {
+ compatible = "cirrus,cs42888";
+ reg = <0x48>;
+ clocks = <&clk IMX8QM_AUD_MCLKOUT0>;
+ clock-names = "mclk";
+ VA-supply = <&reg_audio>;
+ VD-supply = <&reg_audio>;
+ VLS-supply = <&reg_audio>;
+ VLC-supply = <&reg_audio>;
+ reset-gpio = <&gpio4 25 1>;
+ power-domains = <&pd_mclk_out0>;
+ assigned-clocks = <&clk IMX8QM_AUD_PLL0_DIV>,
+ <&clk IMX8QM_AUD_ACM_AUD_PLL_CLK0_DIV>,
+ <&clk IMX8QM_AUD_ACM_AUD_REC_CLK0_DIV>,
+ <&clk IMX8QM_AUD_MCLKOUT0>;
+ assigned-clock-rates = <786432000>, <49152000>, <12288000>, <12288000>;
+ fsl,txs-rxm;
+ status = "okay";
+ };
+};
+
+&fec2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_fec2>;
+ phy-mode = "rgmii-txid";
+ phy-handle = <&ethphy1>;
+ phy-supply = <&reg_fec2_supply>;
+ fsl,magic-packet;
+ fsl,rgmii_rxc_dly;
+ status = "okay";
+};
+
+&pd_dma_lpuart0 {
+ debug_console;
+};
+
+&lpuart0 { /* console */
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lpuart0>;
+ status = "okay";
+};
+
+&lpuart1 { /* BT */
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lpuart1>;
+ resets = <&modem_reset>;
+ status = "okay";
+};
+
+&lpuart2 { /* Dbg console */
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lpuart2>;
+ status = "disabled";
+};
+
+&lpuart3 { /* MKbus */
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lpuart3>;
+ status = "okay";
+};
+
+&gpu_3d0 {
+ status = "okay";
+};
+
+&gpu_3d1 {
+ status = "okay";
+};
+
+&imx8_gpu_ss {
+ status = "okay";
+};
+
+&pixel_combiner1 {
+ status = "okay";
+};
+
+&prg1 {
+ status = "okay";
+};
+
+&prg2 {
+ status = "okay";
+};
+
+&prg3 {
+ status = "okay";
+};
+
+&prg4 {
+ status = "okay";
+};
+
+&prg5 {
+ status = "okay";
+};
+
+&prg6 {
+ status = "okay";
+};
+
+&prg7 {
+ status = "okay";
+};
+
+&prg8 {
+ status = "okay";
+};
+
+&prg9 {
+ status = "okay";
+};
+
+&dpr1_channel1 {
+ status = "okay";
+};
+
+&dpr1_channel2 {
+ status = "okay";
+};
+
+&dpr1_channel3 {
+ status = "okay";
+};
+
+&dpr2_channel1 {
+ status = "okay";
+};
+
+&dpr2_channel2 {
+ status = "okay";
+};
+
+&dpr2_channel3 {
+ status = "okay";
+};
+
+&dpu1 {
+ status = "okay";
+};
+
+&pixel_combiner2 {
+ status = "okay";
+};
+
+&prg10 {
+ status = "okay";
+};
+
+&prg11 {
+ status = "okay";
+};
+
+&prg12 {
+ status = "okay";
+};
+
+&prg13 {
+ status = "okay";
+};
+
+&prg14 {
+ status = "okay";
+};
+
+&prg15 {
+ status = "okay";
+};
+
+&prg16 {
+ status = "okay";
+};
+
+&prg17 {
+ status = "okay";
+};
+
+&prg18 {
+ status = "okay";
+};
+
+&dpr3_channel1 {
+ status = "okay";
+};
+
+&dpr3_channel2 {
+ status = "okay";
+};
+
+&dpr3_channel3 {
+ status = "okay";
+};
+
+&dpr4_channel1 {
+ status = "okay";
+};
+
+&dpr4_channel2 {
+ status = "okay";
+};
+
+&dpr4_channel3 {
+ status = "okay";
+};
+
+&dpu2 {
+ status = "okay";
+};
+
+&pciea{
+ ext_osc = <1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pciea>;
+ disable-gpio = <&gpio4 9 GPIO_ACTIVE_LOW>;
+ reset-gpio = <&gpio4 29 GPIO_ACTIVE_LOW>;
+ clkreq-gpio = <&gpio4 27 GPIO_ACTIVE_LOW>;
+ epdev_on-supply = <&epdev_on>;
+ status = "okay";
+};
+
+&pd_cm40_intmux {
+ early_power_on;
+};
+
+&intmux_cm40 {
+ status = "okay";
+};
+
+&pd_cm41_intmux {
+ early_power_on;
+};
+
+&intmux_cm41 {
+ status = "okay";
+};
+
+&mipi_csi_0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ virtual-channel;
+ status = "okay";
+
+ /* Camera 0 MIPI CSI-2 (CSIS0) */
+ port@0 {
+ reg = <0>;
+ mipi_csi0_ep: endpoint {
+ remote-endpoint = <&max9286_0_ep>;
+ data-lanes = <1 2 3 4>;
+ };
+ };
+};
+
+&mipi_csi_1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ virtual-channel;
+ status = "okay";
+
+ /* Camera 0 MIPI CSI-2 (CSIS1) */
+ port@1 {
+ reg = <1>;
+ mipi_csi1_ep: endpoint {
+ remote-endpoint = <&max9286_1_ep>;
+ data-lanes = <1 2 3 4>;
+ };
+ };
+};
+
+&mlb {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_mlb>;
+ status = "okay";
+};
+
+&gpio1 {
+ status = "okay";
+};
+
+&i2c0_mipi_csi0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clock-frequency = <100000>;
+ status = "okay";
+
+ max9286_mipi@6A {
+ compatible = "maxim,max9286_mipi";
+ reg = <0x6A>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_mipi_csi0_en_rst>;
+ clocks = <&clk IMX8QM_CLK_DUMMY>;
+ clock-names = "capture_mclk";
+ mclk = <27000000>;
+ mclk_source = <0>;
+ pwn-gpios = <&gpio1 27 GPIO_ACTIVE_HIGH>;
+ virtual-channel;
+ port {
+ max9286_0_ep: endpoint {
+ remote-endpoint = <&mipi_csi0_ep>;
+ data-lanes = <1 2 3 4>;
+ };
+ };
+ };
+};
+
+&i2c0_mipi_csi1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clock-frequency = <100000>;
+ status = "okay";
+
+ max9286_mipi@6A {
+ compatible = "maxim,max9286_mipi";
+ reg = <0x6A>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_mipi_csi1_en_rst>;
+ clocks = <&clk IMX8QM_CLK_DUMMY>;
+ clock-names = "capture_mclk";
+ mclk = <27000000>;
+ mclk_source = <0>;
+ pwn-gpios = <&gpio1 30 GPIO_ACTIVE_HIGH>;
+ virtual-channel;
+ port {
+ max9286_1_ep: endpoint {
+ remote-endpoint = <&mipi_csi1_ep>;
+ data-lanes = <1 2 3 4>;
+ };
+ };
+ };
+};
+
+&isi_0 {
+ status = "okay";
+};
+
+&isi_1 {
+ status = "okay";
+};
+
+&isi_2 {
+ status = "okay";
+};
+
+&isi_3 {
+ status = "okay";
+};
+
+&isi_4 {
+ status = "okay";
+};
+
+&isi_5 {
+ status = "okay";
+};
+
+&isi_6 {
+ status = "okay";
+};
+
+&isi_7 {
+ status = "okay";
+};
+
+&sata {
+ pinctrl-0 = <&pinctrl_pciea>;
+ clkreq-gpio = <&gpio4 27 GPIO_ACTIVE_LOW>;
+ status = "okay";
+};
+
+&ldb1_phy {
+ status = "okay";
+};
+
+&ldb1 {
+ status = "okay";
+
+ lvds-channel@0 {
+ fsl,data-mapping = "jeida";
+ fsl,data-width = <24>;
+ status = "okay";
+
+ port@1 {
+ reg = <1>;
+
+ lvds0_out: endpoint {
+ remote-endpoint = <&it6263_0_in>;
+ };
+ };
+ };
+};
+
+&i2c1_lvds0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lvds0_lpi2c1>;
+ clock-frequency = <100000>;
+ status = "okay";
+
+ lvds-to-hdmi-bridge@4c {
+ compatible = "ite,it6263";
+ reg = <0x4c>;
+
+ port {
+ it6263_0_in: endpoint {
+ clock-lanes = <3>;
+ data-lanes = <0 1 2 4>;
+ remote-endpoint = <&lvds0_out>;
+ };
+ };
+ };
+};
+
+&ldb2_phy {
+ status = "okay";
+};
+
+&ldb2 {
+ status = "okay";
+
+ lvds-channel@0 {
+ fsl,data-mapping = "jeida";
+ fsl,data-width = <24>;
+ status = "okay";
+
+ port@1 {
+ reg = <1>;
+
+ lvds1_out: endpoint {
+ remote-endpoint = <&it6263_1_in>;
+ };
+ };
+ };
+};
+
+&i2c1_lvds1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lvds1_lpi2c1>;
+ clock-frequency = <100000>;
+ status = "okay";
+
+ lvds-to-hdmi-bridge@4c {
+ compatible = "ite,it6263";
+ reg = <0x4c>;
+
+ port {
+ it6263_1_in: endpoint {
+ clock-lanes = <3>;
+ data-lanes = <0 1 2 4>;
+ remote-endpoint = <&lvds1_out>;
+ };
+ };
+ };
+};
+
+&i2c0_mipi_dsi0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_mipi0_lpi2c0>;
+ clock-frequency = <100000>;
+ status = "okay";
+
+ adv_bridge1: adv7535@3d {
+ compatible = "adi,adv7535", "adi,adv7533";
+ reg = <0x3d>;
+ adi,dsi-lanes = <4>;
+ adi,dsi-channel = <1>;
+ interrupt-parent = <&gpio1>;
+ interrupts = <19 IRQ_TYPE_LEVEL_LOW>;
+ status = "okay";
+
+ port {
+ adv7535_1_in: endpoint {
+ remote-endpoint = <&mipi_dsi_bridge1_adv>;
+ };
+ };
+ };
+};
+
+&mipi_dsi_phy1 {
+ status = "okay";
+};
+
+&mipi_dsi1 {
+ pwr-delay = <10>;
+ status = "okay";
+};
+
+&mipi_dsi_bridge1 {
+ status = "okay";
+
+ port@1 {
+ mipi_dsi_bridge1_adv: endpoint {
+ remote-endpoint = <&adv7535_1_in>;
+ };
+ };
+};
+
+&i2c0_mipi_dsi1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_mipi1_lpi2c0>;
+ clock-frequency = <100000>;
+ status = "okay";
+
+ adv_bridge2: adv7535@3d {
+ compatible = "adi,adv7535", "adi,adv7533";
+ reg = <0x3d>;
+ adi,dsi-lanes = <4>;
+ adi,dsi-channel = <1>;
+ interrupt-parent = <&gpio1>;
+ interrupts = <23 IRQ_TYPE_LEVEL_LOW>;
+ status = "okay";
+
+ port {
+ adv7535_2_in: endpoint {
+ remote-endpoint = <&mipi_dsi_bridge2_adv>;
+ };
+ };
+ };
+};
+
+&mipi_dsi_phy2 {
+ status = "okay";
+};
+
+&mipi_dsi2 {
+ pwr-delay = <10>;
+ status = "okay";
+};
+
+&mipi_dsi_bridge2 {
+ status = "okay";
+
+ port@1 {
+ mipi_dsi_bridge2_adv: endpoint {
+ remote-endpoint = <&adv7535_2_in>;
+ };
+ };
+};
+
+&lvds0_pwm {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lvds0_pwm0>;
+ status = "okay";
+};
+
+&lvds1_pwm {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lvds1_pwm0>;
+ status = "okay";
+};
+
+&tsens {
+ tsens-num = <6>;
+};
+
+&thermal_zones {
+ pmic-thermal0 {
+ polling-delay-passive = <250>;
+ polling-delay = <2000>;
+ thermal-sensors = <&tsens 5>;
+ trips {
+ pmic_alert0: trip0 {
+ temperature = <110000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+ pmic_crit0: trip1 {
+ temperature = <125000>;
+ hysteresis = <2000>;
+ type = "critical";
+ };
+ };
+ cooling-maps {
+ map0 {
+ trip = <&pmic_alert0>;
+ cooling-device =
+ <&A53_0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ map1 {
+ trip = <&pmic_alert0>;
+ cooling-device =
+ <&A72_0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
+ };
+};
+
+&vpu_decoder {
+ core_type = <2>;
+ status = "okay";
+};
+
+&vpu_encoder {
+ status = "okay";
+};
+
+
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8qm-mek_ca53.dts b/arch/arm64/boot/dts/freescale/fsl-imx8qm-mek_ca53.dts
new file mode 100644
index 000000000000..5c8c4f499948
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8qm-mek_ca53.dts
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2017 NXP
+ *
+ * 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 "fsl-imx8qm-mek.dts"
+
+&A72_0 {
+ device_type = "";
+};
+
+&A72_1 {
+ device_type = "";
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8qm-mek_ca72.dts b/arch/arm64/boot/dts/freescale/fsl-imx8qm-mek_ca72.dts
new file mode 100644
index 000000000000..fa2ff24c51ce
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8qm-mek_ca72.dts
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2017 NXP
+ *
+ * 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 "fsl-imx8qm-mek.dts"
+
+&A53_0 {
+ device_type = "";
+};
+
+&A53_1 {
+ device_type = "";
+};
+
+&A53_2 {
+ device_type = "";
+};
+
+&A53_3 {
+ device_type = "";
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8qm-xen.dtsi b/arch/arm64/boot/dts/freescale/fsl-imx8qm-xen.dtsi
new file mode 100644
index 000000000000..5b11bb8337b8
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8qm-xen.dtsi
@@ -0,0 +1,576 @@
+/*
+ * Copyright 2018 NXP
+ *
+ * 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.
+ */
+
+/*
+ * This dtsi is used by dom0 mainly for passthrough devices to domu.
+ */
+/ {
+ /delete-node/ thermal-zones;
+
+ /delete-node/ wu;
+
+ /*
+ * This is just to avoid renaming all other edma0 nodes, so choose
+ * edma0a and edma0d here.
+ */
+ edma0a: dma-controller0@5a200000 {
+ compatible = "fsl,imx8qm-edma";
+ reg = <0x0 0x5a200000 0x0 0x10000>, /* channel0 LPSPI0 rx */
+ <0x0 0x5a210000 0x0 0x10000>; /* channel1 LPSPI0 tx */
+ #dma-cells = <3>;
+ dma-channels = <2>;
+ interrupts = <GIC_SPI 416 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 417 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "edma0-chan0-rx", "edma0-chan1-tx";
+ fsl,sc_rsrc_id = <SC_R_DMA_0_CH0>,
+ <SC_R_DMA_0_CH1>;
+ status = "okay";
+ };
+
+ edma0d: dma-controller0@5a260000 {
+ compatible = "fsl,imx8qm-edma";
+ reg = <0x0 0x5a260000 0x0 0x10000>, /* channel6 LPSPI3 rx */
+ <0x0 0x5a270000 0x0 0x10000>; /* channel7 LPSPI3 tx */
+ #dma-cells = <3>;
+ dma-channels = <2>;
+ interrupts = <GIC_SPI 422 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 423 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "edma0-chan6-rx", "edma0-chan7-tx";
+ fsl,sc_rsrc_id = <SC_R_DMA_0_CH6>,
+ <SC_R_DMA_0_CH7>;
+ status = "okay";
+ };
+
+ edma00: dma-controller0@5a2c0000 {
+ compatible = "fsl,imx8qm-edma";
+ reg = <0x0 0x5a2c0000 0x0 0x10000>, /* channel12 UART0 rx */
+ <0x0 0x5a2d0000 0x0 0x10000>; /* channel13 UART0 tx */
+ #dma-cells = <3>;
+ dma-channels = <2>;
+ interrupts = <GIC_SPI 434 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 435 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "edma0-chan12-rx", "edma0-chan13-tx";
+ fsl,sc_rsrc_id = <SC_R_DMA_0_CH12>,
+ <SC_R_DMA_0_CH13>;
+ status = "okay";
+ };
+
+ edma01: dma-controller1@5a2e0000 {
+ compatible = "fsl,imx8qm-edma";
+ reg = <0x0 0x5a2e0000 0x0 0x10000>, /* channel14 UART1 rx */
+ <0x0 0x5a2f0000 0x0 0x10000>; /* channel15 UART1 tx */
+ #dma-cells = <3>;
+ dma-channels = <2>;
+ interrupts = <GIC_SPI 436 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 437 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "edma0-chan14-rx", "edma0-chan15-tx";
+ fsl,sc_rsrc_id = <SC_R_DMA_0_CH14>,
+ <SC_R_DMA_0_CH15>;
+ status = "okay";
+ };
+
+ edma02: dma-controller2@5a300000 {
+ compatible = "fsl,imx8qm-edma";
+ reg = <0x0 0x5a300000 0x0 0x10000>, /* channel16 UART2 rx */
+ <0x0 0x5a310000 0x0 0x10000>; /* channel17 UART2 tx */
+ #dma-cells = <3>;
+ dma-channels = <2>;
+ interrupts = <GIC_SPI 438 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 439 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "edma0-chan16-rx", "edma0-chan17-tx";
+ fsl,sc_rsrc_id = <SC_R_DMA_0_CH16>,
+ <SC_R_DMA_0_CH17>;
+ status = "okay";
+ };
+
+ edma03: dma-controller3@5a320000 {
+ compatible = "fsl,imx8qm-edma";
+ reg = <0x0 0x5a320000 0x0 0x10000>, /* channel18 UART3 rx */
+ <0x0 0x5a330000 0x0 0x10000>; /* channel19 UART3 tx */
+ #dma-cells = <3>;
+ dma-channels = <2>;
+ interrupts = <GIC_SPI 440 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 441 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "edma0-chan18-rx", "edma0-chan19-tx";
+ fsl,sc_rsrc_id = <SC_R_DMA_0_CH18>,
+ <SC_R_DMA_0_CH19>;
+ status = "okay";
+ };
+
+ edma04: dma-controller4@5a340000 {
+ compatible = "fsl,imx8qm-edma";
+ reg = <0x0 0x5a340000 0x0 0x10000>, /* channel20 UART4 rx */
+ <0x0 0x5a350000 0x0 0x10000>; /* channel21 UART4 tx */
+ #dma-cells = <3>;
+ dma-channels = <2>;
+ interrupts = <GIC_SPI 442 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 443 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "edma0-chan20-rx", "edma0-chan21-tx";
+ fsl,sc_rsrc_id = <SC_R_DMA_0_CH20>,
+ <SC_R_DMA_0_CH21>;
+ status = "okay";
+ };
+
+ edma20: dma-controller@59200000 {
+ compatible = "fsl,imx8qm-adma";
+ reg = <0x0 0x59200000 0x0 0x10000>, /* asrc0 */
+ <0x0 0x59210000 0x0 0x10000>,
+ <0x0 0x59220000 0x0 0x10000>,
+ <0x0 0x59230000 0x0 0x10000>,
+ <0x0 0x59240000 0x0 0x10000>,
+ <0x0 0x59250000 0x0 0x10000>;
+ #dma-cells = <3>;
+ shared-interrupt;
+ dma-channels = <6>;
+ interrupts = <GIC_SPI 374 IRQ_TYPE_LEVEL_HIGH>, /* asrc0 */
+ <GIC_SPI 375 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 376 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 377 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 378 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 379 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "edma2-chan0-rx", "edma2-chan1-rx", /* asrc0 */
+ "edma2-chan2-rx", "edma2-chan3-tx",
+ "edma2-chan4-tx", "edma2-chan5-tx";
+ fsl,sc_rsrc_id = <SC_R_DMA_2_CH0>,
+ <SC_R_DMA_2_CH1>,
+ <SC_R_DMA_2_CH2>,
+ <SC_R_DMA_2_CH3>,
+ <SC_R_DMA_2_CH4>,
+ <SC_R_DMA_2_CH5>;
+ status = "okay";
+ };
+
+ edma21: dma-controller@0x59260000 {
+ compatible = "fsl,imx8qm-adma";
+ reg = <0x0 0x59260000 0x0 0x10000>, /* esai0 rx */
+ <0x0 0x59270000 0x0 0x10000>; /* esai0 tx */
+ #dma-cells = <3>;
+ shared-interrupt;
+ dma-channels = <2>;
+ interrupts = <GIC_SPI 410 IRQ_TYPE_LEVEL_HIGH>, /* esai0 */
+ <GIC_SPI 410 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "edma2-chan6-rx", "edma2-chan7-tx"; /* esai0 */
+ fsl,sc_rsrc_id = <SC_R_DMA_2_CH6>,
+ <SC_R_DMA_2_CH7>;
+ status = "okay";
+ };
+
+ edma22: dma-controller@0x59280000 {
+ compatible = "fsl,imx8qm-adma";
+ reg = <0x0 0x59280000 0x0 0x10000>, /* spdif0 rx */
+ <0x0 0x59290000 0x0 0x10000>; /* spdif0 tx */
+ #dma-cells = <3>;
+ shared-interrupt;
+ dma-channels = <2>;
+ interrupts = <GIC_SPI 457 IRQ_TYPE_LEVEL_HIGH>, /* spdif0 */
+ <GIC_SPI 459 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "edma2-chan8-rx", "edma2-chan9-tx"; /* spdif0 */
+ fsl,sc_rsrc_id = <SC_R_DMA_2_CH8>,
+ <SC_R_DMA_2_CH9>;
+ status = "okay";
+ };
+
+ edma23: dma-controller@0x592a0000 {
+ compatible = "fsl,imx8qm-adma";
+ reg = <0x0 0x592A0000 0x0 0x10000>, /* spdif1 rx */
+ <0x0 0x592B0000 0x0 0x10000>; /* spdif1 tx */
+ #dma-cells = <3>;
+ shared-interrupt;
+ dma-channels = <2>;
+ interrupts = <GIC_SPI 461 IRQ_TYPE_LEVEL_HIGH>, /* spdif1 */
+ <GIC_SPI 463 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "edma2-chan10-rx", "edma2-chan11-tx"; /* spdif1 */
+ fsl,sc_rsrc_id = <SC_R_DMA_2_CH10>,
+ <SC_R_DMA_2_CH11>;
+ status = "okay";
+ };
+
+ edma24: dma-controller@0x592c0000 {
+ compatible = "fsl,imx8qm-adma";
+ reg = <0x0 0x592c0000 0x0 0x10000>, /* sai0 rx */
+ <0x0 0x592d0000 0x0 0x10000>; /* sai0 tx */
+ #dma-cells = <3>;
+ shared-interrupt;
+ dma-channels = <2>;
+ interrupts = <GIC_SPI 315 IRQ_TYPE_LEVEL_HIGH>, /* sai0 */
+ <GIC_SPI 315 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "edma2-chan12-rx", "edma2-chan13-tx"; /* sai0 */
+ fsl,sc_rsrc_id = <SC_R_DMA_2_CH12>,
+ <SC_R_DMA_2_CH13>;
+ status = "okay";
+ };
+
+ edma25: dma-controller@0x592e0000 {
+ compatible = "fsl,imx8qm-adma";
+ reg = <0x0 0x592e0000 0x0 0x10000>, /* sai1 rx */
+ <0x0 0x592f0000 0x0 0x10000>; /* sai1 tx */
+ #dma-cells = <3>;
+ shared-interrupt;
+ dma-channels = <2>;
+ interrupts = <GIC_SPI 317 IRQ_TYPE_LEVEL_HIGH>, /* sai1 */
+ <GIC_SPI 317 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "edma2-chan14-rx", "edma2-chan15-tx"; /* sai1 */
+ fsl,sc_rsrc_id = <SC_R_DMA_2_CH14>,
+ <SC_R_DMA_2_CH15>;
+ status = "okay";
+ };
+
+ edma26: dma-controller@0x59320000 {
+ compatible = "fsl,imx8qm-adma";
+ reg = <0x0 0x59320000 0x0 0x10000>, /* sai4 rx */
+ <0x0 0x59330000 0x0 0x10000>; /* sai5 tx */
+ #dma-cells = <3>;
+ shared-interrupt;
+ dma-channels = <2>;
+ interrupts = <GIC_SPI 326 IRQ_TYPE_LEVEL_HIGH>, /* sai4 */
+ <GIC_SPI 328 IRQ_TYPE_LEVEL_HIGH>; /* sai5 */
+ interrupt-names = "edma2-chan18-rx", "edma2-chan19-tx"; /* sai1 */
+ fsl,sc_rsrc_id = <SC_R_DMA_2_CH18>,
+ <SC_R_DMA_2_CH19>;
+ status = "okay";
+ };
+
+ usbotg1_lpcg: usbotg1_lpcg@5b270000 {
+ compatible = "fsl,imx8qm-usbotg1-lpcg";
+ reg = <0x0 0x5b270000 0x0 0x10000>;
+ };
+
+ usbotg3_lpcg: usbotg3_lpcg@5b280000 {
+ reg = <0x0 0x5b280000 0x0 0x1000>;
+ };
+
+ sdhc1_lpcg: sdhc1_lpcg@5b200000 {
+ compatible = "fsl,imx8qm-lpuart-lpcg";
+ reg = <0x0 0x5b200000 0x0 0x10000>;
+ };
+
+ lpuart1_lpcg: lpcg@5a470000 {
+ compatible = "fsl,imx8qm-lpuart-lpcg";
+ reg = <0x0 0x5a470000 0x0 0x10000>;
+ };
+
+ lpuart2_lpcg: lpcg@5a480000 {
+ compatible = "fsl,imx8qm-lpuart-lpcg";
+ reg = <0x0 0x5a480000 0x0 0x10000>;
+ };
+
+ di_lvds0_lpcg: lpcg@56243000 {
+ compatible = "fsl,imx8qm-di-lvds0-lpcg";
+ reg = <0x0 0x56243000 0x0 0x1000>;
+ };
+
+ di_lvds1_lpcg: lpcg@57243000 {
+ compatible = "fsl,imx8qm-di-lvds1-lpcg";
+ reg = <0x0 0x57243000 0x0 0x1000>;
+ };
+
+ dc_0_lpcg: lpcg@56010000 {
+ compatible = "fsl,imx8qm-dc0-lpcg";
+ reg = <0x0 0x56010000 0x0 0x10000>;
+ };
+
+ dc_1_lpcg: lpcg@57010000 {
+ compatible = "fsl,imx8qm-dc1-lpcg";
+ reg = <0x0 0x57010000 0x0 0x10000>;
+ };
+
+ mu_5_lpcg: lpcg@5d600000 {
+ compatible = "fsl,imx8qm-mu-lpcg";
+ reg = <0x0 0x5d600000 0x0 0x10000>;
+ };
+
+ mu_6_lpcg: lpcg@5d610000 {
+ compatible = "fsl,imx8qm-mu-lpcg";
+ reg = <0x0 0x5d610000 0x0 0x10000>;
+ };
+
+ mu_5_lpcg_b: lpcg@5d690000 {
+ compatible = "fsl,imx8qm-mu-lpcg";
+ reg = <0x0 0x5d690000 0x0 0x10000>;
+ };
+
+ mu_6_lpcg_b: lpcg@5d6a0000 {
+ compatible = "fsl,imx8qm-mu-lpcg";
+ reg = <0x0 0x5d6a0000 0x0 0x10000>;
+ };
+
+ mu_7_lpcg_b: lpcg@5d6b0000 {
+ compatible = "fsl,imx8qm-mu-lpcg";
+ reg = <0x0 0x5d6b0000 0x0 0x10000>;
+ };
+
+ hsio_pcie_x2_lpcg: hsio_pcie_x2_lpcg@5f050000 {
+ reg = <0x0 0x5f050000 0x0 0x10000>;
+ };
+
+ hsio_pcie_x1_lpcg: hsio_pcie_x1_lpcg@5f060000 {
+ reg = <0x0 0x5f060000 0x0 0x10000>;
+ };
+
+ hsio_phy_x2_lpcg: hsio_phy_x2_lpcg@5f080000 {
+ reg = <0x0 0x5f080000 0x0 0x10000>;
+ };
+
+ hsio_pcie_x2_crr2_lpcg: hsio_phy_x2_lpcg@5f0c0000 {
+ reg = <0x0 0x5f0c0000 0x0 0x10000>;
+ };
+
+ mipi_csi_0_lpcg: mipi_csi_0_lpcg@58223000 {
+ reg = <0x0 0x58223000 0x0 0x1000>;
+ };
+
+ img_pxl_link_csi0_lpcg: img_pxl_link_csi0_lpcg@58580000 {
+ reg = <0x0 0x58580000 0x0 0x1000>;
+ };
+
+ img_pdma_0_lpcg: img_pdma_0_lpcg@58500000 {
+ reg = <0x0 0x58500000 0x0 0x1000>;
+ };
+
+ img_pdma_1_lpcg: img_pdma_1_lpcg@58510000 {
+ reg = <0x0 0x58510000 0x0 0x1000>;
+ };
+
+ img_pdma_2_lpcg: img_pdma_2_lpcg@58520000 {
+ reg = <0x0 0x58520000 0x0 0x1000>;
+ };
+
+ img_pdma_3_lpcg: img_pdma_3_lpcg@58530000 {
+ reg = <0x0 0x58530000 0x0 0x1000>;
+ };
+
+ vpu_decoder_csr: vpu_decoder_csr@0x2d080000 {
+ reg = <0x0 0x2d080000 0x0 0x1000>;
+ };
+
+ /* hdmi */
+ di_hdmi_lpcg: di_hdmi_lpcg@0x56263000 {
+ reg = <0x0 0x56263000 0x0 0x1000>;
+ };
+
+ rx_hdmi_lpcg: rx_hdmi_lpcg@0x58263000 {
+ reg = <0x0 0x58263000 0x0 0x1000>;
+ };
+
+ img_pxl_link_hdmi_lpcg: img_pxl_link_hdmi_lpcg@0x585a0000 {
+ reg = <0x0 0x585a0000 0x0 0x1000>;
+ };
+
+ aud_hdmi_rx_sai_0_lpcg: aud_hdmi_rx_sai_0_lpcg@0x59480000 {
+ reg = <0x0 0x59480000 0x0 0x1000>;
+ };
+
+ aud_hdmi_tx_sai_0_lpcg: aud_hdmi_tx_sai_0_lpcg@0x59490000 {
+ reg = <0x0 0x59490000 0x0 0x1000>;
+ };
+
+ aud_asrc_0_lpcg: aud_asrc_0_lpcg@0x59400000 {
+ reg = <0x0 0x59400000 0x0 0x1000>;
+ };
+
+ aud_esai_0_lpcg: aud_esai_0_lpcg@0x59410000 {
+ reg = <0x0 0x59410000 0x0 0x1000>;
+ };
+
+ aud_pll_clk0_lpcg: aud_pll_clk0_lpcg {
+ reg = <0x0 0x59d20000 0x0 0x1000>;
+ };
+
+ aud_pll_clk1_lpcg: aud_pll_clk1_lpcg {
+ reg = <0x0 0x59d30000 0x0 0x1000>;
+ };
+
+ aud_mclkout0_lpcg: aud_mclkout0_lpcg {
+ reg = <0x0 0x59d50000 0x0 0x1000>;
+ };
+
+ aud_mclkout1_lpcg: aud_mclkout1_lpcg {
+ reg = <0x0 0x59d60000 0x0 0x1000>;
+ };
+
+ aud_rec_clk0_lpcg: aud_rec_clk0_lpcg {
+ reg = <0x0 0x59d00000 0x0 0x1000>;
+ };
+
+ aud_rec_clk1_lpcg: aud_rec_clk1_lpcg {
+ reg = <0x0 0x59d10000 0x0 0x1000>;
+ };
+
+ aud_dsp_lpcg: aud_dsp_lpcg {
+ reg = <0x0 0x59580000 0x0 0x1000>;
+ };
+ aud_ocram_lpcg: aud_ocram_lpcg {
+ reg = <0x0 0x59590000 0x0 0x1000>;
+ };
+
+ aud_sai_0_lpcg: aud_sai_0_lpcg {
+ reg = <0x0 0x59440000 0x0 0x1000>;
+ };
+};
+
+/delete-node/ &edma0;
+/delete-node/ &edma2;
+
+&mu {
+ interrupt-parent = <&gic>;
+};
+
+&flexcan1 {
+ interrupt-parent = <&gic>;
+};
+
+&flexcan2 {
+ interrupt-parent = <&gic>;
+};
+
+&flexcan3 {
+ interrupt-parent = <&gic>;
+};
+
+&lpspi0 {
+ interrupt-parent = <&gic>;
+ dmas = <&edma0a 1 0 0>, <&edma0a 0 0 1>;
+};
+
+&lpspi3 {
+ interrupt-parent = <&gic>;
+ dmas = <&edma0d 7 0 0>, <&edma0d 6 0 1>;
+};
+
+&lpuart0 {
+ interrupt-parent = <&gic>;
+};
+
+&lpuart1 {
+ interrupt-parent = <&gic>;
+ dmas = <&edma01 15 0 0>, <&edma01 14 0 1>;
+};
+
+&lpuart2 {
+ interrupt-parent = <&gic>;
+ dmas = <&edma02 17 0 0>, <&edma02 16 0 1>;
+};
+
+&lpuart3 {
+ interrupt-parent = <&gic>;
+ dmas = <&edma03 19 0 0>, <&edma03 18 0 1>;
+};
+
+&lpuart4 {
+ interrupt-parent = <&gic>;
+ dmas = <&edma04 21 0 0>, <&edma04 20 0 1>;
+};
+
+&usdhc1 {
+ /delete-property/ iommus;
+};
+
+&usdhc2 {
+ /delete-property/ iommus;
+};
+
+&usdhc3 {
+ /delete-property/ iommus;
+};
+
+&fec1 {
+ interrupt-parent = <&gic>;
+ /delete-property/ iommus;
+};
+
+&fec2 {
+ interrupt-parent = <&gic>;
+ /delete-property/ iommus;
+};
+
+&sata {
+ /delete-property/ iommus;
+};
+
+&usbotg1 {
+ interrupt-parent = <&gic>;
+};
+
+&usbh1 {
+ interrupt-parent = <&gic>;
+};
+
+&usbotg3 {
+ interrupt-parent = <&gic>;
+};
+
+&smmu {
+ /* xen only supports legacy bindings for now */
+ #iommu-cells = <0>;
+};
+
+&dpu1 {
+ fsl,sc_rsrc_id = <SC_R_DC_0_BLIT0>,
+ <SC_R_DC_0_BLIT1>,
+ <SC_R_DC_0_BLIT2>,
+ <SC_R_DC_0_BLIT_OUT>,
+ <SC_R_DC_0_WARP>,
+ <SC_R_DC_0_VIDEO0>,
+ <SC_R_DC_0_VIDEO1>,
+ <SC_R_DC_0_FRAC0>,
+ <SC_R_DC_0>;
+};
+
+&dpu2 {
+ fsl,sc_rsrc_id = <SC_R_DC_1_BLIT0>,
+ <SC_R_DC_1_BLIT1>,
+ <SC_R_DC_1_BLIT2>,
+ <SC_R_DC_1_BLIT_OUT>,
+ <SC_R_DC_1_WARP>,
+ <SC_R_DC_1_VIDEO0>,
+ <SC_R_DC_1_VIDEO1>,
+ <SC_R_DC_1_FRAC0>,
+ <SC_R_DC_1>;
+};
+
+&esai0 {
+ dmas = <&edma21 6 0 1>, <&edma21 7 0 0>;
+};
+
+&spdif0 {
+ dmas = <&edma22 8 0 5>, <&edma22 9 0 4>;
+};
+
+&spdif1 {
+ dmas = <&edma23 10 0 5>, <&edma23 11 0 4>;
+};
+
+&sai0 {
+ dmas = <&edma24 12 0 1>, <&edma24 13 0 0>;
+};
+
+&sai1 {
+ dmas = <&edma25 14 0 1>, <&edma25 15 0 0>;
+};
+
+/delete-node/ &sai2;
+/delete-node/ &sai3;
+
+&sai_hdmi_rx {
+ dmas = <&edma26 18 0 1>;
+};
+
+&sai_hdmi_tx {
+ dmas = <&edma26 19 0 0>;
+};
+
+&asrc0 {
+ dmas = <&edma20 0 0 0>, <&edma20 1 0 0>, <&edma20 2 0 0>,
+ <&edma20 3 0 1>, <&edma20 4 0 1>, <&edma20 5 0 1>;
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8qm.dtsi b/arch/arm64/boot/dts/freescale/fsl-imx8qm.dtsi
new file mode 100644
index 000000000000..6bfa324c9f31
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8qm.dtsi
@@ -0,0 +1,355 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017-2018 NXP
+ *
+ * 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 <dt-bindings/interrupt-controller/arm-gic.h>
+#include "fsl-imx8-ca53.dtsi"
+#include "fsl-imx8-ca72.dtsi"
+#include <dt-bindings/clock/imx8qm-clock.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/soc/imx_rsrc.h>
+#include <dt-bindings/soc/imx8_hsio.h>
+#include <dt-bindings/soc/imx8_pd.h>
+#include <dt-bindings/pinctrl/pads-imx8qm.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/thermal/thermal.h>
+
+/ {
+ compatible = "fsl,imx8qm";
+ interrupt-parent = <&gic>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ aliases {
+ csi0 = &mipi_csi_0;
+ csi1 = &mipi_csi_1;
+ dpu0 = &dpu1;
+ dpu1 = &dpu2;
+ ethernet0 = &fec1;
+ ethernet1 = &fec2;
+ dsi_phy0 = &mipi_dsi_phy1;
+ dsi_phy1 = &mipi_dsi_phy2;
+ mipi_dsi0 = &mipi_dsi1;
+ mipi_dsi1 = &mipi_dsi2;
+ ldb0 = &ldb1;
+ ldb1 = &ldb2;
+ isi0 = &isi_0;
+ isi1 = &isi_1;
+ isi2 = &isi_2;
+ isi3 = &isi_3;
+ isi4 = &isi_4;
+ isi5 = &isi_5;
+ isi6 = &isi_6;
+ isi7 = &isi_7;
+ serial0 = &lpuart0;
+ serial1 = &lpuart1;
+ serial2 = &lpuart2;
+ serial3 = &lpuart3;
+ serial4 = &lpuart4;
+ mmc0 = &usdhc1;
+ mmc1 = &usdhc2;
+ mmc2 = &usdhc3;
+ usbphy0 = &usbphy1;
+ can0 = &flexcan1;
+ can1 = &flexcan2;
+ can2 = &flexcan3;
+ i2c0 = &i2c_rpbus_0;
+ i2c1 = &i2c_rpbus_1;
+ };
+
+ memory@80000000 {
+ device_type = "memory";
+ reg = <0x00000000 0x80000000 0 0x40000000>;
+ /* DRAM space - 1, size : 1 GB DRAM */
+ };
+
+ reserved-memory {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ /*
+ * reserved-memory layout
+ * 0x8800_0000 ~ 0x8FFF_FFFF is reserved for M4
+ * Shouldn't be used at A core and Linux side.
+ *
+ */
+
+ decoder_boot: decoder_boot@0x84000000 {
+ no-map;
+ reg = <0 0x84000000 0 0x2000000>;
+ };
+ encoder_boot: encoder_boot@0x86000000 {
+ no-map;
+ reg = <0 0x86000000 0 0x400000>;
+ };
+ rpmsg_reserved: rpmsg@0x90000000 {
+ no-map;
+ reg = <0 0x90000000 0 0x400000>;
+ };
+ rpmsg_dma_reserved:rpmsg_dma@0x90400000 {
+ compatible = "shared-dma-pool";
+ no-map;
+ reg = <0 0x90400000 0 0x1C00000>;
+ };
+ decoder_rpc: decoder_rpc@0x92000000 {
+ no-map;
+ reg = <0 0x92000000 0 0x200000>;
+ };
+ encoder_rpc: encoder_rpc@0x92200000 {
+ no-map;
+ reg = <0 0x92200000 0 0x200000>;
+ };
+ dsp_reserved: dsp@0x92400000 {
+ no-map;
+ reg = <0 0x92400000 0 0x2000000>;
+ };
+ encoder_reserved: encoder_reserved@0x94400000 {
+ no-map;
+ reg = <0 0x94400000 0 0x800000>;
+ };
+
+ /* global autoconfigured region for contiguous allocations */
+ linux,cma {
+ compatible = "shared-dma-pool";
+ reusable;
+ size = <0 0x3c000000>;
+ alloc-ranges = <0 0x96000000 0 0x3c000000>;
+ linux,cma-default;
+ };
+
+ };
+
+ gic: interrupt-controller@51a00000 {
+ compatible = "arm,gic-v3";
+ reg = <0x0 0x51a00000 0 0x10000>, /* GIC Dist */
+ <0x0 0x51b00000 0 0xC0000>, /* GICR */
+ <0x0 0x52000000 0 0x2000>, /* GICC */
+ <0x0 0x52010000 0 0x1000>, /* GICH */
+ <0x0 0x52020000 0 0x20000>; /* GICV */
+ #interrupt-cells = <3>;
+ interrupt-controller;
+ interrupts = <GIC_PPI 9
+ (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_HIGH)>;
+ interrupt-parent = <&gic>;
+ };
+
+ mu: mu@5d1c0000 {
+ compatible = "fsl,imx8-mu";
+ reg = <0x0 0x5d1c0000 0x0 0x10000>;
+ interrupts = <GIC_SPI 177 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-parent = <&gic>;
+ fsl,scu_ap_mu_id = <0>;
+ status = "okay";
+ };
+
+ mu13: mu13@5d280000 {
+ compatible = "fsl,imx8-mu-dsp";
+ reg = <0x0 0x5d280000 0x0 0x10000>;
+ interrupts = <GIC_SPI 192 IRQ_TYPE_LEVEL_HIGH>;
+ fsl,dsp_ap_mu_id = <13>;
+ status = "okay";
+ };
+
+ mu_m0: mu_m0@2d000000 {
+ compatible = "fsl,imx8-mu0-vpu-m0";
+ reg = <0x0 0x2d000000 0x0 0x20000>;
+ interrupts = <GIC_SPI 472 IRQ_TYPE_LEVEL_HIGH>;
+ fsl,vpu_ap_mu_id = <16>;
+ status = "okay";
+ };
+
+ mu1_m0: mu1_m0@2d020000 {
+ compatible = "fsl,imx8-mu1-vpu-m0";
+ reg = <0x0 0x2d020000 0x0 0x20000>;
+ interrupts = <GIC_SPI 473 IRQ_TYPE_LEVEL_HIGH>;
+ fsl,vpu_ap_mu_id = <17>;
+ status = "okay";
+ };
+
+ mu2_m0: mu2_m0@2d040000 {
+ compatible = "fsl,imx8-mu2-vpu-m0";
+ reg = <0x0 0x2d040000 0x0 0x20000>;
+ interrupts = <GIC_SPI 474 IRQ_TYPE_LEVEL_HIGH>;
+ fsl,vpu_ap_mu_id = <18>;
+ status = "okay";
+ };
+
+ vpu_decoder: vpu_decoder@2c000000 {
+ compatible = "nxp,imx8qm-b0-vpudec", "nxp,imx8qxp-b0-vpudec";
+ boot-region = <&decoder_boot>;
+ rpc-region = <&decoder_rpc>;
+ reg = <0x0 0x2c000000 0x0 0x1000000>;
+ reg-names = "vpu_regs";
+ reg-csr = <0x2d080000>;
+ power-domains = <&pd_vpu_dec>;
+ status = "disabled";
+ };
+
+ vpu_encoder: vpu_encoder@2d000000 {
+ compatible = "nxp,imx8qm-b0-vpuenc";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ boot-region = <&encoder_boot>;
+ rpc-region = <&encoder_rpc>;
+ reserved-region = <&encoder_reserved>;
+ reg = <0x0 0x2d000000 0x0 0x1000000>, /*VPU Encoder*/
+ <0x0 0x2c000000 0x0 0x2000000>; /*VPU*/
+ reg-names = "vpu_regs";
+ power-domains = <&pd_vpu_enc>;
+ reg-rpc-system = <0x40000000>;
+
+ resolution-max = <1920 1080>;
+ fps-max = <120>;
+ status = "disabled";
+
+ core0@1020000 {
+ compatible = "fsl,imx8-mu1-vpu-m0";
+ reg = <0x1020000 0x20000>;
+ reg-csr = <0x1090000 0x10000>;
+ interrupts = <GIC_SPI 473 IRQ_TYPE_LEVEL_HIGH>;
+ fsl,vpu_ap_mu_id = <17>;
+ fw-buf-size = <0x200000>;
+ rpc-buf-size = <0x80000>;
+ print-buf-size = <0x80000>;
+ };
+ core1@1040000 {
+ compatible = "fsl,imx8-mu2-vpu-m0";
+ reg = <0x1040000 0x20000>;
+ reg-csr = <0x10a0000 0x10000>;
+ interrupts = <GIC_SPI 474 IRQ_TYPE_LEVEL_HIGH>;
+ fsl,vpu_ap_mu_id = <18>;
+ fw-buf-size = <0x200000>;
+ rpc-buf-size = <0x80000>;
+ print-buf-size = <0x80000>;
+ };
+ };
+
+ clk: clk {
+ compatible = "fsl,imx8qm-clk";
+ #clock-cells = <1>;
+ };
+
+ iomuxc: iomuxc {
+ compatible = "fsl,imx8qm-iomuxc";
+ };
+
+ timer {
+ compatible = "arm,armv8-timer";
+ interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>, /* Physical Secure */
+ <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>, /* Physical Non-Secure */
+ <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>, /* Virtual */
+ <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>; /* Hypervisor */
+ clock-frequency = <8000000>;
+ interrupt-parent = <&gic>;
+ };
+
+ smmu: iommu@51400000 {
+ compatible = "arm,mmu-500";
+ interrupt-parent = <&gic>;
+ reg = <0 0x51400000 0 0x40000>;
+ #global-interrupts = <1>;
+ #iommu-cells = <2>;
+ interrupts = <0 32 4>,
+ <0 32 4>, <0 32 4>, <0 32 4>, <0 32 4>,
+ <0 32 4>, <0 32 4>, <0 32 4>, <0 32 4>,
+ <0 32 4>, <0 32 4>, <0 32 4>, <0 32 4>,
+ <0 32 4>, <0 32 4>, <0 32 4>, <0 32 4>,
+ <0 32 4>, <0 32 4>, <0 32 4>, <0 32 4>,
+ <0 32 4>, <0 32 4>, <0 32 4>, <0 32 4>,
+ <0 32 4>, <0 32 4>, <0 32 4>, <0 32 4>,
+ <0 32 4>, <0 32 4>, <0 32 4>, <0 32 4>;
+ };
+
+ cci: cci@52090000 {
+ compatible = "arm,cci-400";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0 0x52090000 0 0x1000>;
+ ranges = <0 0 0x52090000 0x10000>;
+
+ pmu@9000 {
+ compatible = "arm,cci-400-pmu,r1",
+ "arm,cci-400-pmu";
+ reg = <0x9000 0x4000>;
+ interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-parent = <&gic>;
+ };
+ };
+
+ #include "fsl-imx8qm-device.dtsi"
+};
+
+&A53_0 {
+ operating-points = <
+ /* kHz uV */
+ /* voltage is maintained by SCFW, so no need here */
+ 1200000 0
+ 1104000 0
+ 900000 0
+ 600000 0
+ >;
+ clocks = <&clk IMX8QM_A53_DIV>;
+ clock-latency = <61036>;
+ #cooling-cells = <2>;
+ /delete-property/ cpu-idle-states;
+};
+
+&A72_0 {
+ operating-points = <
+ /* kHz uV */
+ /* voltage is maintained by SCFW, so no need here */
+ 1596000 0
+ 1296000 0
+ 1056000 0
+ 600000 0
+ >;
+ clocks = <&clk IMX8QM_A72_DIV>;
+ clock-latency = <61036>;
+ #cooling-cells = <2>;
+ /delete-property/ cpu-idle-states;
+};
+
+
+&imx8_gpu_ss {/*<freq-kHz vol-uV>*/
+ operating-points = <
+/*overdrive*/ 800000 0 /*The first tuple is for core clock frequency*/
+ 1000000 0 /*The second tuple is for shader clock frequency*/
+/*nominal*/ 650000 0
+ 700000 0
+/*underdrive*/ 400000 0 /*core/shader clock share the same frequency on underdrive mode*/
+ >;
+};
+
+&A53_1 {
+ /delete-property/ cpu-idle-states;
+};
+
+&A53_2 {
+ /delete-property/ cpu-idle-states;
+};
+
+&A53_3 {
+ /delete-property/ cpu-idle-states;
+};
+
+&A72_1 {
+ /delete-property/ cpu-idle-states;
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8qp-lpddr4-arm2.dts b/arch/arm64/boot/dts/freescale/fsl-imx8qp-lpddr4-arm2.dts
new file mode 100644
index 000000000000..969869097ed5
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8qp-lpddr4-arm2.dts
@@ -0,0 +1,25 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2018 NXP
+ *
+ * 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.
+ */
+
+/dts-v1/;
+
+#include "fsl-imx8qp.dtsi"
+
+#include "fsl-imx8q-arm2.dtsi"
+
+/ {
+ model = "Freescale i.MX8QP ARM2";
+ compatible = "fsl,imx8qp-arm2", "fsl,imx8qp", "fsl,imx8qm";
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8qp.dtsi b/arch/arm64/boot/dts/freescale/fsl-imx8qp.dtsi
new file mode 100644
index 000000000000..97793d66ef23
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8qp.dtsi
@@ -0,0 +1,43 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2018 NXP
+ *
+ * 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 "fsl-imx8qm.dtsi"
+
+/ {
+ model = "Freescale i.MX8QP";
+ compatible = "fsl,imx8qp", "fsl,imx8qm";
+
+ pmu {
+ interrupt-affinity = <&A72_0>;
+ };
+};
+
+/delete-node/ &A72_1;
+
+&gpu_3d0 {
+ assigned-clock-rates = <625000000>, <625000000>;
+};
+
+&gpu_3d1 {
+ assigned-clock-rates = <625000000>, <625000000>;
+};
+
+&imx8_gpu_ss {/*<freq-kHz vol-uV>*/
+ operating-points = <
+ /*nominal*/ 625000 0
+ 625000 0
+/*underdrive*/ 400000 0 /*core/shader clock share the same frequency on underdrive mode*/
+ >;
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8qxp-17x17-val.dts b/arch/arm64/boot/dts/freescale/fsl-imx8qxp-17x17-val.dts
new file mode 100644
index 000000000000..dda882ed4e8a
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8qxp-17x17-val.dts
@@ -0,0 +1,26 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2019 NXP
+ *
+ * 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.
+ */
+
+/dts-v1/;
+
+#include "fsl-imx8qxp.dtsi"
+
+#include "fsl-imx8x-17x17-val.dtsi"
+
+/ {
+ model = "Freescale i.MX8QXP 17x17 Validation board";
+ compatible = "fsl,imx8qxp-17x17-val", "fsl,imx8qxp";
+};
+
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8qxp-ddr3l-val.dts b/arch/arm64/boot/dts/freescale/fsl-imx8qxp-ddr3l-val.dts
new file mode 100644
index 000000000000..3e52899599a0
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8qxp-ddr3l-val.dts
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2018 NXP
+ *
+ * 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 "fsl-imx8qxp-lpddr4-arm2.dts"
+
+/ {
+ model = "Freescale i.MX8QXP DDR3L VALIDATION";
+ compatible = "fsl,imx8qxp-ddr3l-val", "fsl,imx8qxp";
+
+ reserved-memory {
+ linux,cma {
+ compatible = "shared-dma-pool";
+ reusable;
+ size = <0 0x14000000>;
+ alloc-ranges = <0 0x96000000 0 0x14000000>;
+ linux,cma-default;
+ };
+ };
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8qxp-enet2-tja1100.dtsi b/arch/arm64/boot/dts/freescale/fsl-imx8qxp-enet2-tja1100.dtsi
new file mode 100644
index 000000000000..b664c6f8a215
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8qxp-enet2-tja1100.dtsi
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2018 NXP
+ *
+ * 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.
+ */
+
+&fec1 {
+ status = "disabled";
+};
+
+&fec2 {
+ pinctrl-0 = <&pinctrl_fec2_rmii>;
+ clocks = <&clk IMX8QXP_ENET1_IPG_CLK>,
+ <&clk IMX8QXP_ENET1_AHB_CLK>,
+ <&clk IMX8QXP_ENET1_REF_50MHZ_CLK>,
+ <&clk IMX8QXP_ENET1_PTP_CLK>,
+ <&clk IMX8QXP_ENET1_TX_CLK>;
+ phy-mode = "rmii";
+ phy-handle = <&ethphy2>;
+ /delete-property/ phy-supply;
+
+ mdio {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ethphy2: ethernet-phy@5 {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <5>;
+ tja110x,refclk_in;
+ };
+ };
+};
+
+&iomuxc {
+ imx8qxp-mek {
+ pinctrl_fec2_rmii: fec2rmiigrp {
+ fsl,pins = <
+ SC_P_ENET0_MDC_CONN_ENET1_MDC 0x06000020
+ SC_P_ENET0_MDIO_CONN_ENET1_MDIO 0x06000020
+ SC_P_ESAI0_FSR_CONN_ENET1_RCLK50M_OUT 0x06000020
+ SC_P_SPDIF0_RX_CONN_ENET1_RGMII_RXD0 0x06000020
+ SC_P_ESAI0_TX3_RX2_CONN_ENET1_RGMII_RXD1 0x06000020
+ SC_P_ESAI0_TX2_RX3_CONN_ENET1_RMII_RX_ER 0x06000020
+ SC_P_SPDIF0_TX_CONN_ENET1_RGMII_RX_CTL 0x06000020
+ SC_P_ESAI0_TX4_RX1_CONN_ENET1_RGMII_TXD0 0x06000020
+ SC_P_ESAI0_TX5_RX0_CONN_ENET1_RGMII_TXD1 0x06000020
+ SC_P_ESAI0_SCKR_CONN_ENET1_RGMII_TX_CTL 0x06000020
+ >;
+ };
+ };
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8qxp-lpddr4-arm2-a0.dts b/arch/arm64/boot/dts/freescale/fsl-imx8qxp-lpddr4-arm2-a0.dts
new file mode 100644
index 000000000000..264ae77ddbb7
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8qxp-lpddr4-arm2-a0.dts
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2018 NXP
+ *
+ * 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 "fsl-imx8qxp-lpddr4-arm2.dts"
+
+&vpu_encoder {
+ status = "disabled";
+};
+
+&vpu_decoder {
+ status = "disabled";
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8qxp-lpddr4-arm2-dsi-rm67191.dts b/arch/arm64/boot/dts/freescale/fsl-imx8qxp-lpddr4-arm2-dsi-rm67191.dts
new file mode 100644
index 000000000000..414cd3231f32
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8qxp-lpddr4-arm2-dsi-rm67191.dts
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2017 NXP
+ *
+ * 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 "fsl-imx8qxp-lpddr4-arm2.dts"
+
+&mipi_dsi_bridge1 {
+ status = "okay";
+
+ panel@0 {
+ compatible = "raydium,rm67191";
+ reg = <0>;
+ dsi-lanes = <4>;
+ panel-width-mm = <68>;
+ panel-height-mm = <121>;
+ port {
+ panel1_in: endpoint {
+ remote-endpoint = <&mipi_bridge1_out>;
+ };
+ };
+ };
+
+ port@2 {
+ mipi_bridge1_out: endpoint {
+ remote-endpoint = <&panel1_in>;
+ };
+ };
+};
+
+&mipi_dsi_bridge2 {
+ status = "okay";
+
+ panel@0 {
+ compatible = "raydium,rm67191";
+ reg = <0>;
+ dsi-lanes = <4>;
+ panel-width-mm = <68>;
+ panel-height-mm = <121>;
+ port {
+ panel2_in: endpoint {
+ remote-endpoint = <&mipi_bridge2_out>;
+ };
+ };
+ };
+
+ port@2 {
+ mipi_bridge2_out: endpoint {
+ remote-endpoint = <&panel2_in>;
+ };
+ };
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8qxp-lpddr4-arm2-dsp.dts b/arch/arm64/boot/dts/freescale/fsl-imx8qxp-lpddr4-arm2-dsp.dts
new file mode 100644
index 000000000000..0a10ac35627c
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8qxp-lpddr4-arm2-dsp.dts
@@ -0,0 +1,112 @@
+// SPDX-License-Identifier: (GPL-2.0+
+// Copyright 2017 NXP
+
+#include "fsl-imx8qxp-lpddr4-arm2.dts"
+
+/ {
+ sound-cs42888 {
+ status = "disabled";
+ };
+
+ dspaudio: dspaudio {
+ compatible = "fsl,dsp-audio";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_esai0>;
+ clocks = <&clk IMX8QXP_AUD_ESAI_0_IPG>,
+ <&clk IMX8QXP_AUD_ESAI_0_EXTAL_IPG>,
+ <&clk IMX8QXP_AUD_ASRC_0_IPG>,
+ <&clk IMX8QXP_CLK_DUMMY>,
+ <&clk IMX8QXP_AUD_ACM_AUD_PLL_CLK0_CLK>,
+ <&clk IMX8QXP_AUD_ACM_AUD_PLL_CLK1_CLK>,
+ <&clk IMX8QXP_ACM_AUD_CLK0_SEL>,
+ <&clk IMX8QXP_ACM_AUD_CLK1_SEL>;
+ clock-names = "bus", "mclk", "ipg", "mem",
+ "asrck_0", "asrck_1", "asrck_2", "asrck_3";
+ assigned-clocks = <&clk IMX8QXP_ACM_ESAI0_MCLK_SEL>,
+ <&clk IMX8QXP_AUD_PLL0_DIV>,
+ <&clk IMX8QXP_AUD_ACM_AUD_PLL_CLK0_DIV>,
+ <&clk IMX8QXP_AUD_ACM_AUD_REC_CLK0_DIV>,
+ <&clk IMX8QXP_AUD_ESAI_0_EXTAL_IPG>;
+ assigned-clock-parents = <&clk IMX8QXP_AUD_ACM_AUD_PLL_CLK0_CLK>;
+ assigned-clock-rates = <0>, <786432000>, <49152000>, <24576000>, <49152000>;
+ power-domains = <&pd_esai0>;
+ status = "okay";
+ };
+
+ sound-dsp {
+ compatible = "fsl,imx-dsp-audio";
+ model = "dsp-audio";
+ cpu-dai = <&dspaudio>;
+ audio-codec = <&codec>;
+ audio-platform = <&dsp>;
+ };
+};
+
+&edma0 {
+ compatible = "fsl,imx8qm-edma";
+ reg = <0x0 0x59280000 0x0 0x10000>, /* spdif0 rx */
+ <0x0 0x59290000 0x0 0x10000>, /* spdif0 tx */
+ <0x0 0x592c0000 0x0 0x10000>, /* sai0 rx */
+ <0x0 0x592d0000 0x0 0x10000>, /* sai0 tx */
+ <0x0 0x592e0000 0x0 0x10000>, /* sai1 rx */
+ <0x0 0x592f0000 0x0 0x10000>, /* sai1 tx */
+ <0x0 0x59350000 0x0 0x10000>,
+ <0x0 0x59370000 0x0 0x10000>;
+ #dma-cells = <3>;
+ shared-interrupt;
+ dma-channels = <8>;
+ interrupts = <GIC_SPI 457 IRQ_TYPE_LEVEL_HIGH>, /* spdif0 */
+ <GIC_SPI 459 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 315 IRQ_TYPE_LEVEL_HIGH>, /* sai0 */
+ <GIC_SPI 315 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 317 IRQ_TYPE_LEVEL_HIGH>, /* sai1 */
+ <GIC_SPI 317 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 391 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 393 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "edma0-chan8-rx", "edma0-chan9-tx", /* spdif0 */
+ "edma0-chan12-rx", "edma0-chan13-tx", /* sai0 */
+ "edma0-chan14-rx", "edma0-chan15-tx", /* sai1 */
+ "edma0-chan21-tx", /* gpt5 */
+ "edma0-chan23-rx"; /* gpt7 */
+ status = "okay";
+};
+
+/delete-node/ &pd_dma0_chan6;
+
+&pd_asrc0 {
+ reg = <SC_R_ASRC_0>;
+ power-domains =<&pd_dma0_chan5>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_dma0_chan6: PD_ESAI_0_RX {
+ reg = <SC_R_DMA_0_CH6>;
+ power-domains =<&pd_asrc0>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_dma0_chan7: PD_ESAI_0_TX {
+ reg = <SC_R_DMA_0_CH7>;
+ power-domains =<&pd_dma0_chan6>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_esai0: PD_AUD_ESAI_0 {
+ reg = <SC_R_ESAI_0>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_dma0_chan7>;
+ };
+ };
+ };
+};
+
+&esai0 {
+ status = "disabled";
+};
+
+&asrc0 {
+ status = "disabled";
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8qxp-lpddr4-arm2-enet2-tja1100.dts b/arch/arm64/boot/dts/freescale/fsl-imx8qxp-lpddr4-arm2-enet2-tja1100.dts
new file mode 100644
index 000000000000..f45a85a736d3
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8qxp-lpddr4-arm2-enet2-tja1100.dts
@@ -0,0 +1,16 @@
+/*
+ * Copyright 2018 NXP
+ *
+ * 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 "fsl-imx8qxp-lpddr4-arm2-enet2.dts"
+#include "fsl-imx8qxp-enet2-tja1100.dtsi"
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8qxp-lpddr4-arm2-enet2.dts b/arch/arm64/boot/dts/freescale/fsl-imx8qxp-lpddr4-arm2-enet2.dts
new file mode 100644
index 000000000000..7a7c67ff68f7
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8qxp-lpddr4-arm2-enet2.dts
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2017 NXP
+ *
+ * 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 "fsl-imx8qxp-lpddr4-arm2.dts"
+
+&esai0 {
+ status = "disabled";
+};
+
+&fec2 {
+ status = "okay";
+};
+
+&ethphy1 {
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8qxp-lpddr4-arm2-gpmi-nand.dts b/arch/arm64/boot/dts/freescale/fsl-imx8qxp-lpddr4-arm2-gpmi-nand.dts
new file mode 100644
index 000000000000..d1165640116b
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8qxp-lpddr4-arm2-gpmi-nand.dts
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2017 NXP
+ *
+ *
+ * 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.
+ */
+
+#include "fsl-imx8qxp-lpddr4-arm2.dts"
+
+&iomuxc {
+ imx8qxp-zebu {
+ pinctrl_gpmi_nand_1: gpmi-nand-1 {
+ fsl,pins = <
+ SC_P_EMMC0_CLK_CONN_NAND_READY_B 0x0e00004c
+ SC_P_EMMC0_DATA0_CONN_NAND_DATA00 0x0e00004c
+ SC_P_EMMC0_DATA1_CONN_NAND_DATA01 0x0e00004c
+ SC_P_EMMC0_DATA2_CONN_NAND_DATA02 0x0e00004c
+ SC_P_EMMC0_DATA3_CONN_NAND_DATA03 0x0e00004c
+ SC_P_EMMC0_DATA4_CONN_NAND_DATA04 0x0e00004c
+ SC_P_EMMC0_DATA5_CONN_NAND_DATA05 0x0e00004c
+ SC_P_EMMC0_DATA6_CONN_NAND_DATA06 0x0e00004c
+ SC_P_EMMC0_DATA7_CONN_NAND_DATA07 0x0e00004c
+ SC_P_EMMC0_STROBE_CONN_NAND_CLE 0x0e00004c
+ SC_P_EMMC0_RESET_B_CONN_NAND_WP_B 0x0e00004c
+
+ SC_P_USDHC1_DATA0_CONN_NAND_CE1_B 0x0e00004c
+ SC_P_USDHC1_DATA2_CONN_NAND_WE_B 0x0e00004c
+ SC_P_USDHC1_DATA3_CONN_NAND_ALE 0x0e00004c
+ SC_P_USDHC1_CMD_CONN_NAND_CE0_B 0x0e00004c
+
+ /* i.MX8QXP NAND use nand_re_dqs_pins */
+ SC_P_USDHC1_CD_B_CONN_NAND_DQS 0x0e00004c
+ SC_P_USDHC1_VSELECT_CONN_NAND_RE_B 0x0e00004c
+
+ >;
+ };
+ };
+};
+
+&gpmi {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpmi_nand_1>;
+ status = "okay";
+ nand-on-flash-bbt;
+};
+
+/* Disabled the usdhc1/usdhc2 since pin conflict */
+&usdhc1 {
+ status = "disabled";
+};
+
+&usdhc2 {
+ status = "disabled";
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8qxp-lpddr4-arm2-lpspi-slave.dts b/arch/arm64/boot/dts/freescale/fsl-imx8qxp-lpddr4-arm2-lpspi-slave.dts
new file mode 100644
index 000000000000..8c2661370de4
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8qxp-lpddr4-arm2-lpspi-slave.dts
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2017-2018 NXP
+ *
+ * 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 "fsl-imx8qxp-lpddr4-arm2-lpspi.dts"
+
+/delete-node/&spidev0;
+
+&pinctrl_lpspi2 {
+ fsl,pins = <
+ SC_P_SPI2_SCK_ADMA_SPI2_SCK 0x0600004c
+ SC_P_SPI2_SDO_ADMA_SPI2_SDO 0x0600004c
+ SC_P_SPI2_SDI_ADMA_SPI2_SDI 0x0600004c
+ SC_P_SPI2_CS0_ADMA_SPI2_CS0 0x0600004c
+ >;
+};
+
+&lpspi2 {
+ pinctrl-0 = <&pinctrl_lpspi2>;
+ /delete-property/ cs-gpios;
+ spi-slave;
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8qxp-lpddr4-arm2-lpspi.dts b/arch/arm64/boot/dts/freescale/fsl-imx8qxp-lpddr4-arm2-lpspi.dts
new file mode 100644
index 000000000000..2fb0ea0a413d
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8qxp-lpddr4-arm2-lpspi.dts
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2017-2018 NXP
+ *
+ * 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 "fsl-imx8qxp-lpddr4-arm2.dts"
+
+&iomuxc {
+
+ imx8qxp-arm2 {
+
+ pinctrl_lpspi0: lpspi0grp {
+ fsl,pins = <
+ SC_P_SPI0_SCK_ADMA_SPI0_SCK 0x0600004c
+ SC_P_SPI0_SDO_ADMA_SPI0_SDO 0x0600004c
+ SC_P_SPI0_SDI_ADMA_SPI0_SDI 0x0600004c
+ >;
+ };
+
+ pinctrl_lpspi0_cs: lpspi0cs {
+ fsl,pins = <
+ SC_P_SPI0_CS0_LSIO_GPIO1_IO08 0x21
+ >;
+ };
+
+ pinctrl_lpspi2: lpspi2grp {
+ fsl,pins = <
+ SC_P_SPI2_SCK_ADMA_SPI2_SCK 0x0600004c
+ SC_P_SPI2_SDO_ADMA_SPI2_SDO 0x0600004c
+ SC_P_SPI2_SDI_ADMA_SPI2_SDI 0x0600004c
+ SC_P_SPI2_CS0_ADMA_SPI2_CS0 0x0600004c
+ >;
+ };
+ };
+};
+
+&lpspi0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ fsl,spi-num-chipselects = <1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lpspi0 &pinctrl_lpspi0_cs>;
+ cs-gpios = <&gpio1 8 GPIO_ACTIVE_LOW>;
+ status = "okay";
+
+ flash: at45db041e@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "atmel,at45", "atmel,dataflash";
+ spi-max-frequency = <5000000>;
+ reg = <0>;
+ };
+};
+
+&lpspi2 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ fsl,spi-num-chipselects = <1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lpspi2>;
+ status = "okay";
+
+ spidev0: spi@0 {
+ reg = <0>;
+ compatible = "rohm,dh2228fv";
+ spi-max-frequency = <10000000>;
+ };
+
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8qxp-lpddr4-arm2-mlb.dts b/arch/arm64/boot/dts/freescale/fsl-imx8qxp-lpddr4-arm2-mlb.dts
new file mode 100644
index 000000000000..14d164f21c5f
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8qxp-lpddr4-arm2-mlb.dts
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2017 NXP
+ *
+ * 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 "fsl-imx8qxp-lpddr4-arm2.dts"
+
+&esai0 {
+ status = "disabled";
+};
+
+&mlb {
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8qxp-lpddr4-arm2-mqs.dts b/arch/arm64/boot/dts/freescale/fsl-imx8qxp-lpddr4-arm2-mqs.dts
new file mode 100644
index 000000000000..17abb9bc5b67
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8qxp-lpddr4-arm2-mqs.dts
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2017 NXP
+ *
+ * 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 "fsl-imx8qxp-lpddr4-arm2.dts"
+
+/ {
+ sound-cs42888 {
+ status = "disabled";
+ };
+
+ sound-mqs {
+ compatible = "fsl,imx8qxp-lpddr4-arm2-mqs",
+ "fsl,imx-audio-mqs";
+ model = "mqs-audio";
+ cpu-dai = <&sai1>;
+ audio-codec = <&mqs>;
+ asrc-controller = <&asrc1>;
+ };
+};
+
+&esai0 {
+ status = "disabled";
+};
+
+&iomuxc {
+
+ imx8qxp-arm2 {
+ pinctrl_mqs: mqsgrp {
+ fsl,pins = <
+ SC_P_SPDIF0_TX_ADMA_MQS_L 0xc6000061
+ SC_P_SPDIF0_RX_ADMA_MQS_R 0xc6000061
+ >;
+ };
+ };
+};
+
+&mqs {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_mqs>;
+ status = "okay";
+};
+
+&sai1 {
+ assigned-clocks = <&clk IMX8QXP_AUD_PLL0_DIV>,
+ <&clk IMX8QXP_AUD_ACM_AUD_PLL_CLK0_DIV>,
+ <&clk IMX8QXP_AUD_ACM_AUD_REC_CLK0_DIV>;
+ assigned-clock-rates = <786432000>, <49152000>, <24576000>;
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8qxp-lpddr4-arm2-spdif.dts b/arch/arm64/boot/dts/freescale/fsl-imx8qxp-lpddr4-arm2-spdif.dts
new file mode 100644
index 000000000000..c6622623101b
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8qxp-lpddr4-arm2-spdif.dts
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2017 NXP
+ *
+ * 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 "fsl-imx8qxp-lpddr4-arm2.dts"
+
+/ {
+
+ sound-cs42888 {
+ status = "disabled";
+ };
+
+ sound-spdif {
+ compatible = "fsl,imx-audio-spdif";
+ model = "imx-spdif";
+ spdif-controller = <&spdif0>;
+ spdif-in;
+ spdif-out;
+ };
+};
+
+&iomuxc {
+
+ imx8qxp-arm2 {
+
+ pinctrl_spdif0: spdif0grp {
+ fsl,pins = <
+ SC_P_SPDIF0_TX_ADMA_SPDIF0_TX 0xc6000040
+ SC_P_SPDIF0_RX_ADMA_SPDIF0_RX 0xc6000040
+ >;
+ };
+
+ };
+};
+
+&esai0 {
+ status = "disabled";
+};
+
+&spdif0 {
+ compatible = "fsl,imx8qm-spdif";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_spdif0>;
+ assigned-clocks = <&clk IMX8QXP_AUD_PLL0_DIV>,
+ <&clk IMX8QXP_AUD_ACM_AUD_PLL_CLK0_DIV>,
+ <&clk IMX8QXP_AUD_ACM_AUD_REC_CLK0_DIV>;
+ assigned-clock-rates = <786432000>, <49152000>, <24576000>;
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8qxp-lpddr4-arm2-wm8962.dts b/arch/arm64/boot/dts/freescale/fsl-imx8qxp-lpddr4-arm2-wm8962.dts
new file mode 100644
index 000000000000..8f39af831aef
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8qxp-lpddr4-arm2-wm8962.dts
@@ -0,0 +1,113 @@
+/*
+ * Copyright 2017 NXP
+ *
+ * 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 "fsl-imx8qxp-lpddr4-arm2.dts"
+
+/ {
+ regulators {
+ reg_wm8962: regulator-wm8962 {
+ compatible = "regulator-fixed";
+ regulator-name = "wm8962-supply";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&gpio1 1 GPIO_ACTIVE_HIGH>;
+ regulator-always-on;
+ enable-active-high;
+ };
+ };
+
+ sound-cs42888 {
+ status = "disabled";
+ };
+
+ sound-wm8962 {
+ compatible = "fsl,imx6q-sabresd-wm8962",
+ "fsl,imx-audio-wm8962";
+ model = "wm8962-audio";
+ cpu-dai = <&sai0>;
+ audio-codec = <&wm8962>;
+ audio-routing =
+ "Headphone Jack", "HPOUTL",
+ "Headphone Jack", "HPOUTR",
+ "Ext Spk", "SPKOUTL",
+ "Ext Spk", "SPKOUTR",
+ "AMIC", "MICBIAS",
+ "IN3R", "AMIC",
+ "DMIC", "MICBIAS",
+ "DMICDAT", "DMIC",
+ "Playback", "CPU-Playback",
+ "CPU-Capture", "Capture";
+ codec-master;
+ hp-det-gpios = <&gpio1 2 1>;
+ mic-det-gpios = <&gpio1 3 1>;
+ };
+};
+
+&esai0 {
+ status = "disabled";
+};
+
+&iomuxc {
+ imx8qxp-lpddr4-arm2 {
+ pinctrl_sai0: sai0grp {
+ fsl,pins = <
+ SC_P_SAI0_TXFS_ADMA_SAI0_TXFS 0xc6000040
+ SC_P_SAI0_TXC_ADMA_SAI0_TXC 0xc6000040
+ SC_P_SAI0_TXD_ADMA_SAI0_TXD 0xc6000060
+ SC_P_SAI0_RXD_ADMA_SAI0_RXD 0xc6000040
+ SC_P_SPI2_SDO_LSIO_GPIO1_IO01 0xc6000040
+ SC_P_SPI2_SDI_LSIO_GPIO1_IO02 0xc6000040
+ SC_P_SPI2_SCK_LSIO_GPIO1_IO03 0xc6000040
+ SC_P_MCLK_OUT0_ADMA_ACM_MCLK_OUT0 0xc6000040
+ >;
+ };
+ };
+};
+
+&i2c0_csi0 {
+
+ wm8962: wm8962@1a {
+ compatible = "wlf,wm8962";
+ reg = <0x1a>;
+ clocks = <&clk IMX8QXP_AUD_MCLKOUT0>;
+ DCVDD-supply = <&reg_wm8962>;
+ DBVDD-supply = <&reg_wm8962>;
+ AVDD-supply = <&reg_wm8962>;
+ CPVDD-supply = <&reg_wm8962>;
+ MICVDD-supply = <&reg_wm8962>;
+ PLLVDD-supply = <&reg_wm8962>;
+ SPKVDD1-supply = <&reg_wm8962>;
+ SPKVDD2-supply = <&reg_wm8962>;
+ gpio-cfg = <
+ 0x0000 /* 0:Default */
+ 0x0000 /* 1:Default */
+ 0x0013 /* 2:FN_DMICCLK */
+ 0x0000 /* 3:Default */
+ 0x8014 /* 4:FN_DMICCDAT */
+ 0x0000 /* 5:Default */
+ >;
+ amic-mono;
+ power-domains = <&pd_mclk_out0>;
+ };
+};
+
+&sai0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_sai0>;
+ assigned-clocks = <&clk IMX8QXP_AUD_PLL0_DIV>,
+ <&clk IMX8QXP_AUD_ACM_AUD_PLL_CLK0_DIV>,
+ <&clk IMX8QXP_AUD_ACM_AUD_REC_CLK0_DIV>;
+ assigned-clock-rates = <786432000>, <49152000>, <24576000>;
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8qxp-lpddr4-arm2.dts b/arch/arm64/boot/dts/freescale/fsl-imx8qxp-lpddr4-arm2.dts
new file mode 100644
index 000000000000..0c77adee9e59
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8qxp-lpddr4-arm2.dts
@@ -0,0 +1,35 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2017~2018 NXP
+ *
+ * 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.
+ */
+
+/dts-v1/;
+
+#include "fsl-imx8qxp.dtsi"
+#include "fsl-imx8x-arm2.dtsi"
+
+/ {
+ model = "Freescale i.MX8QXP LPDDR4 ARM2";
+ compatible = "fsl,imx8qxp-lpddr4-arm2", "fsl,imx8qxp";
+};
+
+&usbotg3 {
+ dr_mode = "otg";
+ extcon = <&typec_ptn5150>;
+ status = "okay";
+};
+
+&vpu_decoder {
+ core_type = <1>;
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8qxp-mek-a0.dts b/arch/arm64/boot/dts/freescale/fsl-imx8qxp-mek-a0.dts
new file mode 100755
index 000000000000..c64dda8215f7
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8qxp-mek-a0.dts
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2018 NXP
+ *
+ * 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 "fsl-imx8qxp-mek.dts"
+
+&vpu_encoder {
+ status = "disabled";
+};
+
+&vpu_decoder {
+ status = "disabled";
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8qxp-mek-dom0.dts b/arch/arm64/boot/dts/freescale/fsl-imx8qxp-mek-dom0.dts
new file mode 100644
index 000000000000..623b30113dc5
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8qxp-mek-dom0.dts
@@ -0,0 +1,90 @@
+/*
+ * Copyright 2017-2018 NXP
+ *
+ * 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.
+ */
+
+/dts-v1/;
+
+/memreserve/ 0x84000000 0x2200000;
+/memreserve/ 0x90000000 0x400000;
+/memreserve/ 0x90400000 0x400000;
+/memreserve/ 0x92400000 0x2000000;
+
+#include "fsl-imx8qxp-mek.dtsi"
+#include "fsl-imx8qxp-xen.dtsi"
+
+/ {
+ chosen {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ module@0 {
+ bootargs = "earlycon=xen console=hvc0 root=/dev/mmcblk1p2 rootwait rw";
+ compatible = "xen,linux-zimage", "xen,multiboot-module";
+ /* The size will be override by uboot command */
+ reg = <0x00000000 0x80a00000 0x00000000 0xf93a00>;
+ };
+
+ };
+
+ reserved-memory {
+ /* global autoconfigured region for contiguous allocations */
+ linux,cma {
+ compatible = "shared-dma-pool";
+ reusable;
+ size = <0 0x3c000000>;
+ alloc-ranges = <0 0xa0000000 0 0x40000000>;
+ linux,cma-default;
+ };
+ };
+
+ /*
+ * Dom0 memory is from 0x90000000, so add reg to make sure
+ * the memory is mapped as device, because they are used
+ * for vpu boot code.
+ */
+ decoder_boot_mem: decoder_boot_mem@0x84000000 {
+ reg = <0 0x84000000 0 0x2000000>;
+ };
+
+ encoder_boot_mem: encoder_boot_mem@0x86000000 {
+ reg = <0 0x86000000 0 0x200000>;
+ };
+
+ rpmsg_reserved_mem: rpmsg_reserved_mem@90000000 {
+ reg = <0x0 0x90000000 0x0 0x400000>;
+ };
+
+ decoder_rpc_mem: decoder_rpc_mem@0x92000000 {
+ reg = <0 0x92000000 0 0x200000>;
+ };
+
+ encoder_rpc_mem: encoder_rpc_mem@0x92200000 {
+ reg = <0 0x92200000 0 0x200000>;
+ };
+
+ dsp_reserved_mem: dsp_reserved_mem@0x92400000 {
+ reg = <0 0x92400000 0 0x2000000>;
+ };
+ encoder_reserved_mem: encoder_reserved_mem@0x94400000 {
+ reg = <0 0x94400000 0 0x800000>;
+ };
+
+ rtc0: rtc@23000000 {
+ interrupts = <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>;
+ xen,passthrough;
+ };
+};
+
+&imx8_gpu_ss {
+ /delete-property/ reg;
+ /delete-property/ reg-names;
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8qxp-mek-dsi-rm67191.dts b/arch/arm64/boot/dts/freescale/fsl-imx8qxp-mek-dsi-rm67191.dts
new file mode 100644
index 000000000000..a5debdc6ff7e
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8qxp-mek-dsi-rm67191.dts
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2017 NXP
+ *
+ * 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 "fsl-imx8qxp-mek.dts"
+
+&mipi_dsi_bridge1 {
+ status = "okay";
+
+ panel@0 {
+ compatible = "raydium,rm67191";
+ reg = <0>;
+ reset-gpio = <&pca9557_a 6 GPIO_ACTIVE_HIGH>;
+ dsi-lanes = <4>;
+ panel-width-mm = <68>;
+ panel-height-mm = <121>;
+ port {
+ panel1_in: endpoint {
+ remote-endpoint = <&mipi_bridge1_out>;
+ };
+ };
+ };
+
+ port@2 {
+ mipi_bridge1_out: endpoint {
+ remote-endpoint = <&panel1_in>;
+ };
+ };
+};
+
+&mipi_dsi_bridge2 {
+ status = "okay";
+
+ panel@0 {
+ compatible = "raydium,rm67191";
+ reg = <0>;
+ reset-gpio = <&pca9557_b 7 GPIO_ACTIVE_HIGH>;
+ dsi-lanes = <4>;
+ panel-width-mm = <68>;
+ panel-height-mm = <121>;
+ port {
+ panel2_in: endpoint {
+ remote-endpoint = <&mipi_bridge2_out>;
+ };
+ };
+ };
+
+ port@2 {
+ mipi_bridge2_out: endpoint {
+ remote-endpoint = <&panel2_in>;
+ };
+ };
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8qxp-mek-dsp.dts b/arch/arm64/boot/dts/freescale/fsl-imx8qxp-mek-dsp.dts
new file mode 100644
index 000000000000..70c0fbdd8171
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8qxp-mek-dsp.dts
@@ -0,0 +1,171 @@
+// SPDX-License-Identifier: GPL-2.0+
+// Copyright NXP 2018
+
+#include "fsl-imx8qxp-mek.dts"
+
+/ {
+ sound-cs42888 {
+ status = "disabled";
+ };
+
+ sound {
+ status = "disabled";
+ };
+
+ dspaudio: dspaudio {
+ compatible = "fsl,dsp-audio";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_esai0>;
+ status = "okay";
+ };
+
+ sound-dsp {
+ compatible = "fsl,imx-dsp-audio";
+ model = "dsp-audio";
+ cpu-dai = <&dspaudio>;
+ audio-codec = <&cs42888>;
+ audio-platform = <&dsp>;
+ };
+};
+
+&edma0 {
+ compatible = "fsl,imx8qm-edma";
+ reg = <0x0 0x59280000 0x0 0x10000>, /* spdif0 rx */
+ <0x0 0x59290000 0x0 0x10000>, /* spdif0 tx */
+ <0x0 0x592c0000 0x0 0x10000>, /* sai0 rx */
+ <0x0 0x592d0000 0x0 0x10000>, /* sai0 tx */
+ <0x0 0x592e0000 0x0 0x10000>, /* sai1 rx */
+ <0x0 0x592f0000 0x0 0x10000>, /* sai1 tx */
+ <0x0 0x59350000 0x0 0x10000>,
+ <0x0 0x59370000 0x0 0x10000>;
+ #dma-cells = <3>;
+ shared-interrupt;
+ dma-channels = <8>;
+ interrupts = <GIC_SPI 457 IRQ_TYPE_LEVEL_HIGH>, /* spdif0 */
+ <GIC_SPI 459 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 315 IRQ_TYPE_LEVEL_HIGH>, /* sai0 */
+ <GIC_SPI 315 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 317 IRQ_TYPE_LEVEL_HIGH>, /* sai1 */
+ <GIC_SPI 317 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 391 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 393 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "edma0-chan8-rx", "edma0-chan9-tx", /* spdif0 */
+ "edma0-chan12-rx", "edma0-chan13-tx", /* sai0 */
+ "edma0-chan14-rx", "edma0-chan15-tx", /* sai1 */
+ "edma0-chan21-tx", /* gpt5 */
+ "edma0-chan23-rx"; /* gpt7 */
+ status = "okay";
+};
+
+&dsp {
+ compatible = "fsl,imx8qxp-dsp";
+ reserved-region = <&dsp_reserved>;
+ reg = <0x0 0x596e8000 0x0 0x88000>;
+ clocks = <&clk IMX8QXP_AUD_ESAI_0_IPG>,
+ <&clk IMX8QXP_AUD_ESAI_0_EXTAL_IPG>,
+ <&clk IMX8QXP_AUD_ASRC_0_IPG>,
+ <&clk IMX8QXP_CLK_DUMMY>,
+ <&clk IMX8QXP_AUD_ACM_AUD_PLL_CLK0_CLK>,
+ <&clk IMX8QXP_AUD_ACM_AUD_PLL_CLK1_CLK>,
+ <&clk IMX8QXP_ACM_AUD_CLK0_SEL>,
+ <&clk IMX8QXP_ACM_AUD_CLK1_SEL>;
+ clock-names = "esai_ipg", "esai_mclk", "asrc_ipg", "asrc_mem",
+ "asrck_0", "asrck_1", "asrck_2", "asrck_3";
+ assigned-clocks = <&clk IMX8QXP_ACM_ESAI0_MCLK_SEL>,
+ <&clk IMX8QXP_AUD_PLL0_DIV>,
+ <&clk IMX8QXP_AUD_ACM_AUD_PLL_CLK0_DIV>,
+ <&clk IMX8QXP_AUD_ACM_AUD_REC_CLK0_DIV>,
+ <&clk IMX8QXP_AUD_ESAI_0_EXTAL_IPG>;
+ assigned-clock-parents = <&clk IMX8QXP_AUD_ACM_AUD_PLL_CLK0_CLK>;
+ assigned-clock-rates = <0>, <786432000>, <49152000>, <24576000>, <49152000>;
+ fsl,dsp-firmware = "imx/dsp/hifi4.bin";
+ power-domains = <&pd_dsp>;
+};
+
+/delete-node/ &pd_dma0_chan6;
+/delete-node/ &pd_dsp_mu_A;
+
+&pd_asrc0 {
+ reg = <SC_R_ASRC_0>;
+ power-domains =<&pd_dma0_chan5>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_dma0_chan6: PD_ESAI_0_RX {
+ reg = <SC_R_DMA_0_CH6>;
+ power-domains =<&pd_asrc0>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_dma0_chan7: PD_ESAI_0_TX {
+ reg = <SC_R_DMA_0_CH7>;
+ power-domains =<&pd_dma0_chan6>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_esai0: PD_AUD_ESAI_0 {
+ reg = <SC_R_ESAI_0>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_dma0_chan7>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_dsp_mu_A: PD_DSP_MU_A {
+ reg = <SC_R_MU_13A>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_esai0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_dsp_mu_B: PD_DSP_MU_B {
+ reg = <SC_R_MU_13B>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_dsp_mu_A>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_dsp_ram: PD_AUD_OCRAM {
+ reg = <SC_R_DSP_RAM>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_dsp_mu_B>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pd_dsp: PD_AUD_DSP {
+ reg = <SC_R_DSP>;
+ #power-domain-cells = <0>;
+ power-domains =<&pd_dsp_ram>;
+ };
+ };
+ };
+ };
+ };
+ };
+ };
+};
+
+&esai0 {
+ status = "disabled";
+};
+
+&asrc0 {
+ status = "disabled";
+};
+
+&sai1 {
+ status = "disabled";
+};
+
+&wm8960 {
+ status = "disabled";
+};
+
+&cs42888 {
+ assigned-clocks = <&clk IMX8QXP_AUD_PLL0_DIV>,
+ <&clk IMX8QXP_AUD_ACM_AUD_PLL_CLK0_DIV>,
+ <&clk IMX8QXP_AUD_ACM_AUD_REC_CLK0_DIV>,
+ <&clk IMX8QXP_AUD_MCLKOUT0>;
+ assigned-clock-rates = <786432000>, <49152000>, <24576000>, <12288000>;
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8qxp-mek-enet2-tja1100.dts b/arch/arm64/boot/dts/freescale/fsl-imx8qxp-mek-enet2-tja1100.dts
new file mode 100644
index 000000000000..d9b3842502f1
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8qxp-mek-enet2-tja1100.dts
@@ -0,0 +1,16 @@
+/*
+ * Copyright 2018 NXP
+ *
+ * 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 "fsl-imx8qxp-mek-enet2.dts"
+#include "fsl-imx8qxp-enet2-tja1100.dtsi"
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8qxp-mek-enet2.dts b/arch/arm64/boot/dts/freescale/fsl-imx8qxp-mek-enet2.dts
new file mode 100644
index 000000000000..184df3f14ad1
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8qxp-mek-enet2.dts
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2017 NXP
+ *
+ * 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 "fsl-imx8qxp-mek.dts"
+
+&esai0 {
+ status = "disabled";
+};
+
+&fec2 {
+ status = "okay";
+};
+
+&ethphy1 {
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8qxp-mek-inmate.dts b/arch/arm64/boot/dts/freescale/fsl-imx8qxp-mek-inmate.dts
new file mode 100644
index 000000000000..0d9613a3aa88
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8qxp-mek-inmate.dts
@@ -0,0 +1,294 @@
+/*
+ * Copyright 2018 NXP
+ *
+ * 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.
+ */
+
+/dts-v1/;
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include "fsl-imx8-ca35.dtsi"
+#include <dt-bindings/soc/imx_rsrc.h>
+#include <dt-bindings/soc/imx8_hsio.h>
+#include <dt-bindings/soc/imx8_pd.h>
+#include <dt-bindings/clock/imx8qxp-clock.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/pinctrl/pads-imx8qxp.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/thermal/thermal.h>
+
+/ {
+ model = "Freescale i.MX8QXP MEK";
+ compatible = "fsl,imx8qxp-mek", "fsl,imx8qxp";
+ interrupt-parent = <&gic>;
+ #address-cells = <0x2>;
+ #size-cells = <0x2>;
+
+ aliases {
+ mmc0 = &usdhc1;
+ serial2 = &lpuart2;
+ };
+
+ cpus {
+ #address-cells = <0x2>;
+ #size-cells = <0x0>;
+
+ cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,armv8";
+ enable-method = "psci";
+ reg = <0x0 0x2>;
+ /delete-property/ cpu-idle-states;
+ };
+
+ cpu@1 {
+ device_type = "cpu";
+ compatible = "arm,armv8";
+ enable-method = "psci";
+ reg = <0x0 0x3>;
+ /delete-property/ cpu-idle-states;
+ };
+
+ cpu@2 {
+ /delete-property/ cpu-idle-states;
+ };
+
+ cpu@3 {
+ /delete-property/ cpu-idle-states;
+ };
+ };
+
+ psci {
+ compatible = "arm,psci-1.0";
+ method = "smc";
+ };
+
+ timer {
+ compatible = "arm,armv8-timer";
+ interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>, /* Physical Secure */
+ <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>, /* Physical Non-Secure */
+ <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>, /* Virtual */
+ <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>; /* Hypervisor */
+ clock-frequency = <8333333>;
+ };
+
+ clk: clk {
+ compatible = "fsl,imx8qxp-clk";
+ #clock-cells = <1>;
+ };
+
+ iomuxc: iomuxc {
+ compatible = "fsl,imx8qxp-iomuxc";
+ };
+
+ gic: interrupt-controller@51a00000 {
+ compatible = "arm,gic-v3";
+ reg = <0x0 0x51a00000 0 0x10000>, /* GIC Dist */
+ <0x0 0x51b00000 0 0xC0000>; /* GICR (RD_base + SGI_base) */
+ #interrupt-cells = <3>;
+ interrupt-controller;
+ interrupts = <GIC_PPI 9
+ (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_HIGH)>;
+ interrupt-parent = <&gic>;
+ };
+
+ imx8qx-pm {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_conn: PD_CONN {
+ compatible = "nxp,imx8-pd";
+ reg = <SC_R_NONE>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_conn_sdch0: PD_CONN_SDHC_0 {
+ reg = <SC_R_SDHC_0>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_conn>;
+ };
+ };
+
+ pd_dma: PD_DMA {
+ compatible = "nxp,imx8-pd";
+ reg = <SC_R_NONE>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_dma_lpuart2: PD_DMA_UART2 {
+ reg = <SC_R_UART_2>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_dma>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ /*wakeup-irq = <227>;*/
+
+ pd_dma2_chan12: PD_UART2_RX {
+ reg = <SC_R_DMA_2_CH12>;
+ power-domains =<&pd_dma_lpuart2>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_dma2_chan13: PD_UART2_TX {
+ reg = <SC_R_DMA_2_CH13>;
+ power-domains =<&pd_dma2_chan12>;
+ #power-domain-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ };
+ };
+ };
+ };
+
+ mu2: mu@5d1d0000 {
+ compatible = "fsl,imx8-mu";
+ reg = <0x0 0x5d1d0000 0x0 0x10000>;
+ interrupts = <GIC_SPI 178 IRQ_TYPE_LEVEL_HIGH>;
+ fsl,scu_ap_mu_id = <0>;
+ status = "okay";
+ };
+
+ pci@fd700000 {
+ compatible = "pci-host-ecam-generic";
+ device_type = "pci";
+ bus-range = <0 0>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ #interrupt-cells = <1>;
+ interrupt-map-mask = <0 0 0 7>;
+ interrupt-map = <0 0 0 1 &gic GIC_SPI 90 IRQ_TYPE_EDGE_RISING>;
+ reg = <0x0 0xfd700000 0x0 0x100000>;
+ ranges = <0x02000000 0x00 0x10000000 0x0 0x10000000 0x00 0x10000>;
+ };
+
+ usdhc1: usdhc@5b010000 {
+ compatible = "fsl,imx8qm-usdhc", "fsl,imx6sl-usdhc";
+ interrupt-parent = <&gic>;
+ interrupts = <GIC_SPI 232 IRQ_TYPE_LEVEL_HIGH>;
+ reg = <0x0 0x5b010000 0x0 0x10000>;
+ clocks = <&clk IMX8QXP_SDHC0_IPG_CLK>,
+ <&clk IMX8QXP_SDHC0_CLK>,
+ <&clk IMX8QXP_CLK_DUMMY>;
+ clock-names = "ipg", "per", "ahb";
+ assigned-clocks = <&clk IMX8QXP_SDHC0_SEL>, <&clk IMX8QXP_SDHC0_DIV>;
+ assigned-clock-parents = <&clk IMX8QXP_CONN_PLL0_CLK>;
+ assigned-clock-rates = <0>, <400000000>;
+ power-domains = <&pd_conn_sdch0>;
+ fsl,tuning-start-tap = <20>;
+ fsl,tuning-step= <2>;
+ status = "disabled";
+ };
+
+
+ /* For early console */
+ lpuart0: serial@5a060000 {
+ compatible = "fsl,imx8qm-lpuart";
+ reg = <0x0 0x5a060000 0x0 0x1000>;
+ };
+
+ lpuart2: serial@5a080000 {
+ compatible = "fsl,imx8qm-lpuart";
+ reg = <0x0 0x5a080000 0x0 0x1000>;
+ interrupts = <GIC_SPI 227 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-parent = <&gic>;
+ clocks = <&clk IMX8QXP_UART2_CLK>,
+ <&clk IMX8QXP_UART2_IPG_CLK>;
+ clock-names = "per", "ipg";
+ assigned-clocks = <&clk IMX8QXP_UART2_CLK>;
+ assigned-clock-rates = <80000000>;
+ power-domains = <&pd_dma2_chan13>;
+ /*
+ * dma-names = "tx","rx";
+ * dmas = <&edma2 13 0 0>,
+ * <&edma2 12 0 1>;
+ */
+ status = "disabled";
+ };
+
+};
+
+&iomuxc {
+ imx8qxp-mek {
+ pinctrl_lpuart2: lpuart2grp {
+ fsl,pins = <
+ SC_P_UART2_TX_ADMA_UART2_TX 0x06000020
+ SC_P_UART2_RX_ADMA_UART2_RX 0x06000020
+ >;
+ };
+
+ pinctrl_usdhc1: usdhc1grp {
+ fsl,pins = <
+ SC_P_EMMC0_CLK_CONN_EMMC0_CLK 0x06000041
+ SC_P_EMMC0_CMD_CONN_EMMC0_CMD 0x00000021
+ SC_P_EMMC0_DATA0_CONN_EMMC0_DATA0 0x00000021
+ SC_P_EMMC0_DATA1_CONN_EMMC0_DATA1 0x00000021
+ SC_P_EMMC0_DATA2_CONN_EMMC0_DATA2 0x00000021
+ SC_P_EMMC0_DATA3_CONN_EMMC0_DATA3 0x00000021
+ SC_P_EMMC0_DATA4_CONN_EMMC0_DATA4 0x00000021
+ SC_P_EMMC0_DATA5_CONN_EMMC0_DATA5 0x00000021
+ SC_P_EMMC0_DATA6_CONN_EMMC0_DATA6 0x00000021
+ SC_P_EMMC0_DATA7_CONN_EMMC0_DATA7 0x00000021
+ SC_P_EMMC0_STROBE_CONN_EMMC0_STROBE 0x00000041
+ >;
+ };
+
+ pinctrl_usdhc1_100mhz: usdhc1grp100mhz {
+ fsl,pins = <
+ SC_P_EMMC0_CLK_CONN_EMMC0_CLK 0x06000040
+ SC_P_EMMC0_CMD_CONN_EMMC0_CMD 0x00000020
+ SC_P_EMMC0_DATA0_CONN_EMMC0_DATA0 0x00000020
+ SC_P_EMMC0_DATA1_CONN_EMMC0_DATA1 0x00000020
+ SC_P_EMMC0_DATA2_CONN_EMMC0_DATA2 0x00000020
+ SC_P_EMMC0_DATA3_CONN_EMMC0_DATA3 0x00000020
+ SC_P_EMMC0_DATA4_CONN_EMMC0_DATA4 0x00000020
+ SC_P_EMMC0_DATA5_CONN_EMMC0_DATA5 0x00000020
+ SC_P_EMMC0_DATA6_CONN_EMMC0_DATA6 0x00000020
+ SC_P_EMMC0_DATA7_CONN_EMMC0_DATA7 0x00000020
+ SC_P_EMMC0_STROBE_CONN_EMMC0_STROBE 0x00000040
+ >;
+ };
+
+ pinctrl_usdhc1_200mhz: usdhc1grp200mhz {
+ fsl,pins = <
+ SC_P_EMMC0_CLK_CONN_EMMC0_CLK 0x06000040
+ SC_P_EMMC0_CMD_CONN_EMMC0_CMD 0x00000020
+ SC_P_EMMC0_DATA0_CONN_EMMC0_DATA0 0x00000020
+ SC_P_EMMC0_DATA1_CONN_EMMC0_DATA1 0x00000020
+ SC_P_EMMC0_DATA2_CONN_EMMC0_DATA2 0x00000020
+ SC_P_EMMC0_DATA3_CONN_EMMC0_DATA3 0x00000020
+ SC_P_EMMC0_DATA4_CONN_EMMC0_DATA4 0x00000020
+ SC_P_EMMC0_DATA5_CONN_EMMC0_DATA5 0x00000020
+ SC_P_EMMC0_DATA6_CONN_EMMC0_DATA6 0x00000020
+ SC_P_EMMC0_DATA7_CONN_EMMC0_DATA7 0x00000020
+ SC_P_EMMC0_STROBE_CONN_EMMC0_STROBE 0x00000040
+ >;
+ };
+ };
+};
+
+&lpuart2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lpuart2>;
+ status = "okay";
+};
+
+&usdhc1 {
+ pinctrl-names = "default", "state_100mhz", "state_200mhz";
+ pinctrl-0 = <&pinctrl_usdhc1>;
+ pinctrl-1 = <&pinctrl_usdhc1_100mhz>;
+ pinctrl-2 = <&pinctrl_usdhc1_200mhz>;
+ bus-width = <8>;
+ non-removable;
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8qxp-mek-it6263-lvds0-dual-channel.dts b/arch/arm64/boot/dts/freescale/fsl-imx8qxp-mek-it6263-lvds0-dual-channel.dts
new file mode 100755
index 000000000000..aa6d7b27cf1b
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8qxp-mek-it6263-lvds0-dual-channel.dts
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2018 NXP
+ *
+ * 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 "fsl-imx8qxp-mek.dts"
+
+&i2c0_mipi_lvds0 {
+ lvds-to-hdmi-bridge@4c {
+ split-mode;
+ };
+};
+
+&ldb1 {
+ fsl,dual-channel;
+ power-domains = <&pd_mipi_dsi_0_dual_lvds>;
+};
+
+&ldb2 {
+ status = "disabled";
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8qxp-mek-it6263-lvds1-dual-channel.dts b/arch/arm64/boot/dts/freescale/fsl-imx8qxp-mek-it6263-lvds1-dual-channel.dts
new file mode 100755
index 000000000000..14328ef010fb
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8qxp-mek-it6263-lvds1-dual-channel.dts
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2018 NXP
+ *
+ * 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 "fsl-imx8qxp-mek.dts"
+
+&i2c0_mipi_lvds1 {
+ lvds-to-hdmi-bridge@4c {
+ split-mode;
+ };
+};
+
+&ldb1 {
+ status = "disabled";
+};
+
+&ldb2 {
+ fsl,dual-channel;
+ power-domains = <&pd_mipi_dsi_1_dual_lvds>;
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8qxp-mek-jdi-wuxga-lvds0-panel.dts b/arch/arm64/boot/dts/freescale/fsl-imx8qxp-mek-jdi-wuxga-lvds0-panel.dts
new file mode 100644
index 000000000000..f855f66e94e5
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8qxp-mek-jdi-wuxga-lvds0-panel.dts
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2018 NXP
+ *
+ * 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 "fsl-imx8qxp-mek.dts"
+
+/ {
+ lvds0_panel {
+ compatible = "jdi,tx26d202vm0bwa";
+ backlight = <&lvds_backlight1>;
+
+ port {
+ panel_lvds0_in: endpoint {
+ remote-endpoint = <&lvds0_out>;
+ };
+ };
+ };
+};
+
+&ldb1 {
+ fsl,dual-channel;
+ power-domains = <&pd_mipi_dsi_0_dual_lvds>;
+
+ lvds-channel@0 {
+ fsl,data-mapping = "spwg";
+ fsl,data-width = <24>;
+
+ port@1 {
+ reg = <1>;
+
+ lvds0_out: endpoint {
+ remote-endpoint = <&panel_lvds0_in>;
+ };
+ };
+ };
+};
+
+&ldb2 {
+ status = "disabled";
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8qxp-mek-jdi-wuxga-lvds1-panel.dts b/arch/arm64/boot/dts/freescale/fsl-imx8qxp-mek-jdi-wuxga-lvds1-panel.dts
new file mode 100644
index 000000000000..b23fb2b6fa3d
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8qxp-mek-jdi-wuxga-lvds1-panel.dts
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2018 NXP
+ *
+ * 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 "fsl-imx8qxp-mek.dts"
+
+/ {
+ lvds1_panel {
+ compatible = "jdi,tx26d202vm0bwa";
+ backlight = <&lvds_backlight0>;
+
+ port {
+ panel_lvds1_in: endpoint {
+ remote-endpoint = <&lvds1_out>;
+ };
+ };
+ };
+};
+
+&ldb2 {
+ fsl,dual-channel;
+ power-domains = <&pd_mipi_dsi_1_dual_lvds>;
+
+ lvds-channel@0 {
+ fsl,data-mapping = "spwg";
+ fsl,data-width = <24>;
+
+ port@1 {
+ reg = <1>;
+
+ lvds1_out: endpoint {
+ remote-endpoint = <&panel_lvds1_in>;
+ };
+ };
+ };
+};
+
+&ldb1 {
+ status = "disabled";
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8qxp-mek-lcdif.dts b/arch/arm64/boot/dts/freescale/fsl-imx8qxp-mek-lcdif.dts
new file mode 100644
index 000000000000..e884a771b76e
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8qxp-mek-lcdif.dts
@@ -0,0 +1,97 @@
+/*
+ * Copyright 2018 NXP
+ *
+ * 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 "fsl-imx8qxp-mek.dts"
+
+/ {
+ display-subsystem {
+ status = "disabled";
+ };
+
+ panel {
+ compatible = "sii,43wvf1g";
+ backlight = <&lcdif_backlight>;
+
+ port {
+ panel_in: endpoint {
+ remote-endpoint = <&adapter_out>;
+ };
+ };
+ };
+
+ seiko_adapter: seiko-adapter {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "nxp,seiko-43wvfig";
+ bus_mode = <18>;
+
+ port@0 {
+ reg = <0>;
+ adapter_in: endpoint {
+ remote-endpoint = <&lcdif_out>;
+ };
+ };
+ port@1 {
+ reg = <1>;
+ adapter_out: endpoint {
+ remote-endpoint = <&panel_in>;
+ };
+ };
+ };
+
+};
+
+&iomuxc {
+ imx8qxp-mek {
+ pinctrl_hog: hoggrp {
+ fsl,pins = <
+ SC_P_COMP_CTL_GPIO_1V8_3V3_GPIORHB_PAD 0x000514a0
+ >;
+ };
+ };
+};
+
+&esai0 {
+ status = "disabled";
+};
+
+&sai1 {
+ status = "disabled";
+};
+
+&lpuart1 {
+ status = "disabled";
+};
+
+&lcdif_backlight {
+ status = "okay";
+};
+
+&adma_lcdif {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lcdif>;
+ status = "okay";
+
+ port@0 {
+ lcdif_out: lcdif-endpoint {
+ remote-endpoint = <&adapter_in>;
+ };
+ };
+};
+
+&pwm_adma_lcdif {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lcdif_pwm>;
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8qxp-mek-lvds0-it6263.dtsi b/arch/arm64/boot/dts/freescale/fsl-imx8qxp-mek-lvds0-it6263.dtsi
new file mode 100644
index 000000000000..acd6a388cce0
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8qxp-mek-lvds0-it6263.dtsi
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2017 NXP
+ *
+ * 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.
+ */
+
+&ldb1_phy {
+ status = "okay";
+};
+
+&ldb1 {
+ status = "okay";
+
+ lvds-channel@0 {
+ fsl,data-mapping = "jeida";
+ fsl,data-width = <24>;
+ status = "okay";
+
+ port@1 {
+ reg = <1>;
+
+ lvds0_out: endpoint {
+ remote-endpoint = <&it6263_0_in>;
+ };
+ };
+ };
+};
+
+&i2c0_mipi_lvds0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c0_mipi_lvds0>;
+ clock-frequency = <100000>;
+ status = "okay";
+
+ lvds-to-hdmi-bridge@4c {
+ compatible = "ite,it6263";
+ reg = <0x4c>;
+ reset-gpios = <&pca9557_a 6 GPIO_ACTIVE_LOW>;
+
+ port {
+ it6263_0_in: endpoint {
+ clock-lanes = <4>;
+ data-lanes = <0 1 2 3>;
+ remote-endpoint = <&lvds0_out>;
+ };
+ };
+ };
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8qxp-mek-lvds1-it6263.dtsi b/arch/arm64/boot/dts/freescale/fsl-imx8qxp-mek-lvds1-it6263.dtsi
new file mode 100644
index 000000000000..c3088ea63fab
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8qxp-mek-lvds1-it6263.dtsi
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2017 NXP
+ *
+ * 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.
+ */
+
+&ldb2_phy {
+ status = "okay";
+};
+
+&ldb2 {
+ status = "okay";
+
+ lvds-channel@0 {
+ fsl,data-mapping = "jeida";
+ fsl,data-width = <24>;
+ status = "okay";
+
+ port@1 {
+ reg = <1>;
+
+ lvds1_out: endpoint {
+ remote-endpoint = <&it6263_1_in>;
+ };
+ };
+ };
+};
+
+&i2c0_mipi_lvds1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c0_mipi_lvds1>;
+ clock-frequency = <100000>;
+ status = "okay";
+
+ lvds-to-hdmi-bridge@4c {
+ compatible = "ite,it6263";
+ reg = <0x4c>;
+ reset-gpios = <&pca9557_b 7 GPIO_ACTIVE_LOW>;
+
+ port {
+ it6263_1_in: endpoint {
+ clock-lanes = <4>;
+ data-lanes = <0 1 2 3>;
+ remote-endpoint = <&lvds1_out>;
+ };
+ };
+ };
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8qxp-mek-ov5640-rpmsg.dts b/arch/arm64/boot/dts/freescale/fsl-imx8qxp-mek-ov5640-rpmsg.dts
new file mode 100644
index 000000000000..0294a85466de
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8qxp-mek-ov5640-rpmsg.dts
@@ -0,0 +1,24 @@
+#include "fsl-imx8qxp-mek-rpmsg.dts"
+#include "fsl-imx8qxp-mek-ov5640.dtsi"
+
+&i2c_rpbus_5 {
+ ov5640: ov5640@3c {
+ compatible = "ovti,ov5640_v3";
+ reg = <0x3c>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_parallel_csi>;
+ clocks = <&clk IMX8QXP_PARALLEL_CSI_MISC0_CLK>;
+ clock-names = "csi_mclk";
+ pwn-gpios = <&gpio3 2 GPIO_ACTIVE_LOW>;
+ rst-gpios = <&gpio3 3 GPIO_ACTIVE_HIGH>;
+ csi_id = <0>;
+ mclk = <24000000>;
+ mclk_source = <0>;
+ status = "okay";
+ port {
+ ov5640_ep: endpoint {
+ remote-endpoint = <&parallel_csi_ep>;
+ };
+ };
+ };
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8qxp-mek-ov5640.dts b/arch/arm64/boot/dts/freescale/fsl-imx8qxp-mek-ov5640.dts
new file mode 100644
index 000000000000..e8d0f1c150ca
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8qxp-mek-ov5640.dts
@@ -0,0 +1,24 @@
+#include "fsl-imx8qxp-mek.dts"
+#include "fsl-imx8qxp-mek-ov5640.dtsi"
+
+&i2c0_cm40 {
+ ov5640: ov5640@3c {
+ compatible = "ovti,ov5640_v3";
+ reg = <0x3c>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_parallel_csi>;
+ clocks = <&clk IMX8QXP_PARALLEL_CSI_MISC0_CLK>;
+ clock-names = "csi_mclk";
+ pwn-gpios = <&gpio3 2 GPIO_ACTIVE_LOW>;
+ rst-gpios = <&gpio3 3 GPIO_ACTIVE_HIGH>;
+ csi_id = <0>;
+ mclk = <24000000>;
+ mclk_source = <0>;
+ status = "okay";
+ port {
+ ov5640_ep: endpoint {
+ remote-endpoint = <&parallel_csi_ep>;
+ };
+ };
+ };
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8qxp-mek-ov5640.dtsi b/arch/arm64/boot/dts/freescale/fsl-imx8qxp-mek-ov5640.dtsi
new file mode 100644
index 000000000000..dacf622289a8
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8qxp-mek-ov5640.dtsi
@@ -0,0 +1,126 @@
+&iomuxc {
+ imx8qxp-mek {
+ pinctrl_mipi_csi0: mipicsi0grp{
+ fsl,pins = <
+ SC_P_MIPI_CSI0_MCLK_OUT_MIPI_CSI0_ACM_MCLK_OUT 0xC0000041
+ SC_P_MIPI_CSI0_GPIO0_01_LSIO_GPIO3_IO07 0xC0000041
+ SC_P_MIPI_CSI0_GPIO0_00_LSIO_GPIO3_IO08 0xC0000041
+ >;
+ };
+
+ pinctrl_parallel_csi: parallelcsigrp {
+ fsl,pins = <
+ SC_P_CSI_D00_CI_PI_D02 0xC0000041
+ SC_P_CSI_D01_CI_PI_D03 0xC0000041
+ SC_P_CSI_D02_CI_PI_D04 0xC0000041
+ SC_P_CSI_D03_CI_PI_D05 0xC0000041
+ SC_P_CSI_D04_CI_PI_D06 0xC0000041
+ SC_P_CSI_D05_CI_PI_D07 0xC0000041
+ SC_P_CSI_D06_CI_PI_D08 0xC0000041
+ SC_P_CSI_D07_CI_PI_D09 0xC0000041
+
+ SC_P_CSI_MCLK_CI_PI_MCLK 0xC0000041
+ SC_P_CSI_PCLK_CI_PI_PCLK 0xC0000041
+ SC_P_CSI_HSYNC_CI_PI_HSYNC 0xC0000041
+ SC_P_CSI_VSYNC_CI_PI_VSYNC 0xC0000041
+ SC_P_CSI_EN_LSIO_GPIO3_IO02 0xC0000041
+ SC_P_CSI_RESET_LSIO_GPIO3_IO03 0xC0000041
+ >;
+ };
+ };
+};
+
+&isi_0 {
+ interface = <6 0 2>; /* INPUT: 6-PARALLEL CSI */
+ parallel_csi;
+ status = "okay";
+};
+
+&cameradev {
+ parallel_csi;
+ status = "okay";
+};
+
+&parallel_csi {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "okay";
+ port@0 {
+ reg = <0>;
+ parallel_csi_ep: endpoint {
+ remote-endpoint = <&ov5640_ep>;
+ };
+ };
+};
+
+&isi_2 {
+ interface = <2 0 2>;
+ status = "okay";
+};
+
+&isi_1 {
+ status = "disabled";
+};
+
+&isi_3 {
+ status = "disabled";
+};
+
+&isi_4 {
+ status = "disabled";
+};
+
+&isi_5 {
+ status = "disabled";
+};
+
+&isi_6 {
+ status = "disabled";
+};
+
+&isi_7 {
+ status = "disabled";
+};
+
+&i2c0_csi0 {
+ clock-frequency = <100000>;
+ status = "okay";
+
+ ov5640_mipi: ov5640_mipi@3c {
+ compatible = "ovti,ov5640_mipi_v3";
+ reg = <0x3c>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_mipi_csi0>;
+ clocks = <&clk IMX8QXP_24MHZ>;
+ clock-names = "csi_mclk";
+ csi_id = <0>;
+ pwn-gpios = <&gpio3 7 GPIO_ACTIVE_LOW>;
+ rst-gpios = <&gpio3 8 GPIO_ACTIVE_HIGH>;
+ mclk = <24000000>;
+ mclk_source = <0>;
+ mipi_csi;
+ status = "okay";
+ port {
+ ov5640_mipi_ep: endpoint {
+ remote-endpoint = <&mipi_csi0_ep>;
+ };
+ };
+ };
+
+ max9286_mipi@6A {
+ status = "disabled";
+ };
+};
+
+&mipi_csi_0 {
+ /delete-property/virtual-channel;
+ status = "okay";
+
+ port@0 {
+ reg = <0>;
+ mipi_csi0_ep: endpoint {
+ remote-endpoint = <&ov5640_mipi_ep>;
+ data-lanes = <1 2>;
+ };
+ };
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8qxp-mek-root.dts b/arch/arm64/boot/dts/freescale/fsl-imx8qxp-mek-root.dts
new file mode 100644
index 000000000000..4c5aac65f60d
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8qxp-mek-root.dts
@@ -0,0 +1,111 @@
+/*
+ * Copyright 2018 NXP
+ *
+ * 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 "fsl-imx8qxp-mek.dts"
+
+/ {
+ domu {
+ /*
+ * There are 5 MUs, 0A is used by root cell, 1A is used
+ * by ATF, so for non-root cell, 2A/3A/4A could be used.
+ * SC_R_MU_0A
+ * SC_R_MU_1A
+ * SC_R_MU_2A
+ * SC_R_MU_3A
+ * SC_R_MU_4A
+ * The rsrcs and pads will be configured by uboot scu_rm cmd
+ */
+ #address-cells = <1>;
+ #size-cells = <0>;
+ doma {
+ /*
+ * This is not for domu, this is just reuse
+ * the method for jailhouse inmate non root cell
+ * Linux.
+ */
+ compatible = "xen,domu";
+ /*
+ * The reg property will be updated by U-Boot to
+ * reflect the partition id.
+ */
+ reg = <0>;
+ init_on_rsrcs = <
+ SC_R_MU_2A
+ >;
+ rsrcs = <
+ SC_R_SDHC_0
+ SC_R_DMA_2_CH12
+ SC_R_DMA_2_CH13
+ SC_R_UART_2
+ SC_R_MU_2A
+ >;
+ pads = <
+ /* emmc */
+ SC_P_EMMC0_CLK
+ SC_P_EMMC0_CMD
+ SC_P_EMMC0_DATA0
+ SC_P_EMMC0_DATA1
+ SC_P_EMMC0_DATA2
+ SC_P_EMMC0_DATA3
+ SC_P_EMMC0_DATA4
+ SC_P_EMMC0_DATA5
+ SC_P_EMMC0_DATA6
+ SC_P_EMMC0_DATA7
+ SC_P_EMMC0_STROBE
+ /* lpuart2 */
+ SC_P_UART2_TX
+ SC_P_UART2_RX
+ >;
+ };
+ };
+
+};
+
+&{/reserved-memory} {
+
+ jh_reserved: jh@0xfdc00000 {
+ no-map;
+ reg = <0x0 0xfdc00000 0x0 0x400000>;
+ };
+
+ loader_reserved: loader@0xfdb00000 {
+ no-map;
+ reg = <0x0 0xfdb00000 0x0 0x00100000>;
+ };
+
+ ivshmem_reserved: ivshmem@0xfd900000 {
+ no-map;
+ reg = <0x0 0xfd900000 0x0 0x00200000>;
+ };
+
+ pci_reserved: pci@0xfd700000 {
+ no-map;
+ reg = <0x0 0xfd700000 0x0 0x00200000>;
+ };
+
+ /* Decrease if no need such big memory */
+ inmate_reserved: inmate@0xdf7000000 {
+ no-map;
+ reg = <0x0 0xdf700000 0x0 0x1e000000>;
+ };
+};
+
+&usdhc1 {
+ /delete-property/ compatible;
+};
+
+&lpuart2 {
+ /* Let inmate linux use this for console */
+ status = "disabled";
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8qxp-mek-rpmsg.dts b/arch/arm64/boot/dts/freescale/fsl-imx8qxp-mek-rpmsg.dts
new file mode 100644
index 000000000000..858827eee055
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8qxp-mek-rpmsg.dts
@@ -0,0 +1,17 @@
+/*
+ * Copyright 2019 NXP
+ *
+ * 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.
+ */
+
+/dts-v1/;
+
+#include "fsl-imx8qxp-mek-rpmsg.dtsi"
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8qxp-mek-rpmsg.dtsi b/arch/arm64/boot/dts/freescale/fsl-imx8qxp-mek-rpmsg.dtsi
new file mode 100755
index 000000000000..19ba5c627ba2
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8qxp-mek-rpmsg.dtsi
@@ -0,0 +1,212 @@
+/*
+ * Copyright 2019 NXP
+ *
+ * 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 "fsl-imx8qxp-mek.dtsi"
+
+/delete-node/ &i2c0_cm40;
+/delete-node/ &i2c1;
+
+&i2c_rpbus_1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "okay";
+
+ typec_ptn5110: typec@50 {
+ compatible = "usb,tcpci";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_typec>;
+ reg = <0x50>;
+ interrupt-parent = <&gpio1>;
+ interrupts = <3 IRQ_TYPE_LEVEL_LOW>;
+ ss-sel-gpios = <&gpio5 9 GPIO_ACTIVE_LOW>;
+ reset-gpios = <&pca9557_a 7 GPIO_ACTIVE_HIGH>;
+ src-pdos = <0x380190c8 0x3803c0c8>;
+ port-type = "drp";
+ sink-disable;
+ default-role = "source";
+ status = "okay";
+ };
+};
+
+&i2c_rpbus_5 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "okay";
+
+ wm8960: wm8960@1a {
+ compatible = "wlf,wm8960";
+ reg = <0x1a>;
+ clocks = <&clk IMX8QXP_AUD_MCLKOUT0>;
+ clock-names = "mclk";
+ wlf,shared-lrclk;
+ power-domains = <&pd_mclk_out0>;
+ assigned-clocks = <&clk IMX8QXP_AUD_PLL0_DIV>,
+ <&clk IMX8QXP_AUD_ACM_AUD_PLL_CLK0_DIV>,
+ <&clk IMX8QXP_AUD_ACM_AUD_REC_CLK0_DIV>,
+ <&clk IMX8QXP_AUD_MCLKOUT0>;
+ assigned-clock-rates = <786432000>, <49152000>, <12288000>, <12288000>;
+ };
+
+ pca6416: gpio@20 {
+ compatible = "ti,tca6416";
+ reg = <0x20>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ cs42888: cs42888@48 {
+ compatible = "cirrus,cs42888";
+ reg = <0x48>;
+ clocks = <&clk IMX8QXP_AUD_MCLKOUT0>;
+ clock-names = "mclk";
+ VA-supply = <&reg_audio>;
+ VD-supply = <&reg_audio>;
+ VLS-supply = <&reg_audio>;
+ VLC-supply = <&reg_audio>;
+ reset-gpio = <&pca9557_b 1 1>;
+ power-domains = <&pd_mclk_out0>;
+ assigned-clocks = <&clk IMX8QXP_AUD_PLL0_DIV>,
+ <&clk IMX8QXP_AUD_ACM_AUD_PLL_CLK0_DIV>,
+ <&clk IMX8QXP_AUD_ACM_AUD_REC_CLK0_DIV>,
+ <&clk IMX8QXP_AUD_MCLKOUT0>;
+ assigned-clock-rates = <786432000>, <49152000>, <12288000>, <12288000>;
+ fsl,txs-rxm;
+ status = "okay";
+ };
+
+ ov5640: ov5640@3c {
+ compatible = "ovti,ov5640_v3";
+ reg = <0x3c>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_parallel_csi>;
+ clocks = <&clk IMX8QXP_PARALLEL_CSI_MISC0_CLK>;
+ clock-names = "csi_mclk";
+ pwn-gpios = <&gpio3 2 GPIO_ACTIVE_LOW>;
+ rst-gpios = <&gpio3 3 GPIO_ACTIVE_HIGH>;
+ csi_id = <0>;
+ mclk = <24000000>;
+ mclk_source = <0>;
+ status = "okay";
+ port {
+ ov5640_ep: endpoint {
+ remote-endpoint = <&parallel_csi_ep>;
+ };
+ };
+ };
+
+};
+
+&i2c_rpbus_12 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "okay";
+
+ max7322: gpio@68 {
+ compatible = "maxim,max7322";
+ reg = <0x68>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+};
+
+&i2c_rpbus_14 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "okay";
+
+ fxos8700@1e {
+ compatible = "fsl,fxos8700";
+ reg = <0x1e>;
+ interrupt-open-drain;
+ };
+
+ fxas2100x@21 {
+ compatible = "fsl,fxas2100x";
+ reg = <0x21>;
+ interrupt-open-drain;
+ };
+
+ mpl3115@60 {
+ compatible = "fsl,mpl3115";
+ reg = <0x60>;
+ interrupt-open-drain;
+ };
+};
+
+&i2c_rpbus_15 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "okay";
+
+ pca9557_a: gpio@1a {
+ compatible = "nxp,pca9557";
+ reg = <0x1a>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ pca9557_b: gpio@1d {
+ compatible = "nxp,pca9557";
+ reg = <0x1d>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ isl29023@44 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_isl29023>;
+ compatible = "fsl,isl29023";
+ reg = <0x44>;
+ rext = <499>;
+ interrupt-parent = <&gpio1>;
+ interrupts = <2 2>;
+ };
+};
+
+&rpmsg{
+ /*
+ * 64K for one rpmsg instance:
+ */
+ vdev-nums = <2>;
+ reg = <0x0 0x90000000 0x0 0x20000>;
+ status = "okay";
+};
+
+&reg_can_en {
+ status = "disabled";
+};
+
+&reg_can_stby {
+ status = "disabled";
+};
+
+&intmux_cm40 {
+ status = "disabled";
+};
+
+&flexcan1 {
+ status = "disabled";
+};
+
+&flexcan2 {
+ status = "disabled";
+};
+
+&flexspi0 {
+ status = "disabled";
+};
+
+&lpuart3 {
+ status = "disabled";
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8qxp-mek.dts b/arch/arm64/boot/dts/freescale/fsl-imx8qxp-mek.dts
new file mode 100644
index 000000000000..3e717323efc3
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8qxp-mek.dts
@@ -0,0 +1,17 @@
+/*
+ * Copyright 2017-2018 NXP
+ *
+ * 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.
+ */
+
+/dts-v1/;
+
+#include "fsl-imx8qxp-mek.dtsi"
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8qxp-mek.dtsi b/arch/arm64/boot/dts/freescale/fsl-imx8qxp-mek.dtsi
new file mode 100755
index 000000000000..eaa7da4b0758
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8qxp-mek.dtsi
@@ -0,0 +1,1397 @@
+/*
+ * Copyright 2017-2018 NXP
+ *
+ * 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 "fsl-imx8qxp.dtsi"
+
+/ {
+ model = "Freescale i.MX8QXP MEK";
+ compatible = "fsl,imx8qxp-mek", "fsl,imx8qxp";
+
+ chosen {
+ bootargs = "console=ttyLP0,115200 earlycon=lpuart32,0x5a060000,115200";
+ stdout-path = &lpuart0;
+ };
+
+ brcmfmac: brcmfmac {
+ compatible = "cypress,brcmfmac";
+ pinctrl-names = "init", "idle", "default";
+ pinctrl-0 = <&pinctrl_wifi_init>;
+ pinctrl-1 = <&pinctrl_wifi_init>;
+ pinctrl-2 = <&pinctrl_wifi>;
+ };
+
+ modem_reset: modem-reset {
+ compatible = "gpio-reset";
+ reset-gpios = <&pca9557_a 1 GPIO_ACTIVE_LOW>;
+ reset-delay-us = <2000>;
+ reset-post-delay-ms = <40>;
+ #reset-cells = <0>;
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ reg_can_en: regulator-can-gen {
+ compatible = "regulator-fixed";
+ regulator-name = "can-en";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&pca6416 3 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ reg_can_stby: regulator-can-stby {
+ compatible = "regulator-fixed";
+ regulator-name = "can-stby";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&pca6416 5 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ vin-supply = <&reg_can_en>;
+ };
+
+ reg_fec2_supply: fec2_nvcc {
+ compatible = "regulator-fixed";
+ regulator-name = "fec2_nvcc";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ gpio = <&max7322 0 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ reg_usdhc2_vmmc: usdhc2_vmmc {
+ compatible = "regulator-fixed";
+ regulator-name = "SD1_SPWR";
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ gpio = <&gpio4 19 GPIO_ACTIVE_HIGH>;
+ off-on-delay = <3480>;
+ enable-active-high;
+ };
+
+ epdev_on: fixedregulator@100 {
+ compatible = "regulator-fixed";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-name = "epdev_on";
+ gpio = <&pca9557_a 0 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ reg_usb_otg1_vbus: regulator@0 {
+ compatible = "regulator-fixed";
+ reg = <0>;
+ regulator-name = "usb_otg1_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&pca9557_b 2 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ reg_audio: fixedregulator@2 {
+ compatible = "regulator-fixed";
+ reg = <2>;
+ regulator-name = "cs42888_supply";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+ };
+
+ sound: sound {
+ compatible = "fsl,imx7d-evk-wm8960",
+ "fsl,imx-audio-wm8960";
+ model = "wm8960-audio";
+ cpu-dai = <&sai1>;
+ audio-codec = <&wm8960>;
+ codec-master;
+ /*
+ * hp-det = <hp-det-pin hp-det-polarity>;
+ * hp-det-pin: JD1 JD2 or JD3
+ * hp-det-polarity = 0: hp detect high for headphone
+ * hp-det-polarity = 1: hp detect high for speaker
+ */
+ hp-det = <2 0>;
+ hp-det-gpios = <&gpio1 0 0>;
+ mic-det-gpios = <&gpio1 0 0>;
+ audio-routing =
+ "Headphone Jack", "HP_L",
+ "Headphone Jack", "HP_R",
+ "Ext Spk", "SPK_LP",
+ "Ext Spk", "SPK_LN",
+ "Ext Spk", "SPK_RP",
+ "Ext Spk", "SPK_RN",
+ "LINPUT2", "Mic Jack",
+ "LINPUT3", "Mic Jack",
+ "RINPUT1", "Main MIC",
+ "RINPUT2", "Main MIC",
+ "Mic Jack", "MICB",
+ "Main MIC", "MICB",
+ "CPU-Playback", "ASRC-Playback",
+ "Playback", "CPU-Playback",
+ "ASRC-Capture", "CPU-Capture",
+ "CPU-Capture", "Capture";
+ };
+
+ sound-amix-sai {
+ compatible = "fsl,imx-audio-amix";
+ model = "amix-audio-sai";
+ dais = <&sai4>, <&sai5>;
+ amix-controller = <&amix>;
+ };
+
+ sound-cs42888 {
+ compatible = "fsl,imx8qm-sabreauto-cs42888",
+ "fsl,imx-audio-cs42888";
+ model = "imx-cs42888";
+ esai-controller = <&esai0>;
+ audio-codec = <&cs42888>;
+ asrc-controller = <&asrc0>;
+ status = "okay";
+ };
+
+ lvds_backlight0: lvds_backlight@0 {
+ compatible = "pwm-backlight";
+ pwms = <&pwm_mipi_lvds0 0 100000 0>;
+
+ brightness-levels = < 0 1 2 3 4 5 6 7 8 9
+ 10 11 12 13 14 15 16 17 18 19
+ 20 21 22 23 24 25 26 27 28 29
+ 30 31 32 33 34 35 36 37 38 39
+ 40 41 42 43 44 45 46 47 48 49
+ 50 51 52 53 54 55 56 57 58 59
+ 60 61 62 63 64 65 66 67 68 69
+ 70 71 72 73 74 75 76 77 78 79
+ 80 81 82 83 84 85 86 87 88 89
+ 90 91 92 93 94 95 96 97 98 99
+ 100>;
+ default-brightness-level = <80>;
+ };
+
+ lvds_backlight1: lvds_backlight@1 {
+ compatible = "pwm-backlight";
+ pwms = <&pwm_mipi_lvds1 0 100000 0>;
+
+ brightness-levels = < 0 1 2 3 4 5 6 7 8 9
+ 10 11 12 13 14 15 16 17 18 19
+ 20 21 22 23 24 25 26 27 28 29
+ 30 31 32 33 34 35 36 37 38 39
+ 40 41 42 43 44 45 46 47 48 49
+ 50 51 52 53 54 55 56 57 58 59
+ 60 61 62 63 64 65 66 67 68 69
+ 70 71 72 73 74 75 76 77 78 79
+ 80 81 82 83 84 85 86 87 88 89
+ 90 91 92 93 94 95 96 97 98 99
+ 100>;
+ default-brightness-level = <80>;
+ };
+
+ lcdif_backlight: lcdif_backlight {
+ compatible = "pwm-backlight";
+ pwms = <&pwm_adma_lcdif 0 100000 0>;
+
+ brightness-levels = <0 4 8 16 32 64 128 255>;
+ default-brightness-level = <6>;
+ status = "disabled";
+ };
+
+};
+
+&acm {
+ status = "okay";
+};
+
+&amix {
+ status = "okay";
+};
+
+&asrc0 {
+ fsl,asrc-rate = <48000>;
+ status = "okay";
+};
+
+&esai0 {
+ compatible = "fsl,imx8qm-esai";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_esai0>;
+ assigned-clocks = <&clk IMX8QXP_ACM_ESAI0_MCLK_SEL>,
+ <&clk IMX8QXP_AUD_PLL0_DIV>,
+ <&clk IMX8QXP_AUD_ACM_AUD_PLL_CLK0_DIV>,
+ <&clk IMX8QXP_AUD_ACM_AUD_REC_CLK0_DIV>,
+ <&clk IMX8QXP_AUD_ESAI_0_EXTAL_IPG>;
+ assigned-clock-parents = <&clk IMX8QXP_AUD_ACM_AUD_PLL_CLK0_CLK>;
+ assigned-clock-rates = <0>, <786432000>, <49152000>, <12288000>, <49152000>;
+ fsl,txm-rxs;
+ status = "okay";
+};
+
+&sai4 {
+ assigned-clocks = <&clk IMX8QXP_ACM_SAI4_MCLK_SEL>,
+ <&clk IMX8QXP_AUD_PLL1_DIV>,
+ <&clk IMX8QXP_AUD_ACM_AUD_PLL_CLK1_DIV>,
+ <&clk IMX8QXP_AUD_ACM_AUD_REC_CLK1_DIV>,
+ <&clk IMX8QXP_AUD_SAI_4_MCLK>;
+ assigned-clock-parents = <&clk IMX8QXP_AUD_ACM_AUD_PLL_CLK1_CLK>;
+ assigned-clock-rates = <0>, <786432000>, <98304000>, <12288000>, <98304000>;
+ fsl,sai-asynchronous;
+ fsl,txm-rxs;
+ status = "okay";
+};
+
+&sai5 {
+ assigned-clocks = <&clk IMX8QXP_ACM_SAI5_MCLK_SEL>,
+ <&clk IMX8QXP_AUD_PLL1_DIV>,
+ <&clk IMX8QXP_AUD_ACM_AUD_PLL_CLK1_DIV>,
+ <&clk IMX8QXP_AUD_ACM_AUD_REC_CLK1_DIV>,
+ <&clk IMX8QXP_AUD_SAI_5_MCLK>;
+ assigned-clock-parents = <&clk IMX8QXP_AUD_ACM_AUD_PLL_CLK1_CLK>;
+ assigned-clock-rates = <0>, <786432000>, <98304000>, <12288000>, <98304000>;
+ fsl,sai-asynchronous;
+ fsl,txm-rxs;
+ status = "okay";
+};
+
+&iomuxc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_hog>;
+
+ imx8qxp-mek {
+ pinctrl_hog: hoggrp {
+ fsl,pins = <
+ SC_P_MCLK_OUT0_ADMA_ACM_MCLK_OUT0 0x0600004c
+ SC_P_COMP_CTL_GPIO_1V8_3V3_GPIORHB_PAD 0x000514a0
+ >;
+ };
+
+ pinctrl_csi0_lpi2c0: csi0lpi2c0grp {
+ fsl,pins = <
+ SC_P_MIPI_CSI0_I2C0_SCL_MIPI_CSI0_I2C0_SCL 0xc2000020
+ SC_P_MIPI_CSI0_I2C0_SDA_MIPI_CSI0_I2C0_SDA 0xc2000020
+ >;
+ };
+
+ pinctrl_esai0: esai0grp {
+ fsl,pins = <
+ SC_P_ESAI0_FSR_ADMA_ESAI0_FSR 0xc6000040
+ SC_P_ESAI0_FST_ADMA_ESAI0_FST 0xc6000040
+ SC_P_ESAI0_SCKR_ADMA_ESAI0_SCKR 0xc6000040
+ SC_P_ESAI0_SCKT_ADMA_ESAI0_SCKT 0xc6000040
+ SC_P_ESAI0_TX0_ADMA_ESAI0_TX0 0xc6000040
+ SC_P_ESAI0_TX1_ADMA_ESAI0_TX1 0xc6000040
+ SC_P_ESAI0_TX2_RX3_ADMA_ESAI0_TX2_RX3 0xc6000040
+ SC_P_ESAI0_TX3_RX2_ADMA_ESAI0_TX3_RX2 0xc6000040
+ SC_P_ESAI0_TX4_RX1_ADMA_ESAI0_TX4_RX1 0xc6000040
+ SC_P_ESAI0_TX5_RX0_ADMA_ESAI0_TX5_RX0 0xc6000040
+ >;
+ };
+
+ pinctrl_lpuart0: lpuart0grp {
+ fsl,pins = <
+ SC_P_UART0_RX_ADMA_UART0_RX 0x06000020
+ SC_P_UART0_TX_ADMA_UART0_TX 0x06000020
+ >;
+ };
+
+ pinctrl_lpuart1: lpuart1grp {
+ fsl,pins = <
+ SC_P_UART1_TX_ADMA_UART1_TX 0x06000020
+ SC_P_UART1_RX_ADMA_UART1_RX 0x06000020
+ SC_P_UART1_RTS_B_ADMA_UART1_RTS_B 0x06000020
+ SC_P_UART1_CTS_B_ADMA_UART1_CTS_B 0x06000020
+ >;
+ };
+
+ pinctrl_lpuart2: lpuart2grp {
+ fsl,pins = <
+ SC_P_UART2_TX_ADMA_UART2_TX 0x06000020
+ SC_P_UART2_RX_ADMA_UART2_RX 0x06000020
+ >;
+ };
+
+ pinctrl_lpuart3: lpuart3grp {
+ fsl,pins = <
+ SC_P_FLEXCAN2_TX_ADMA_UART3_TX 0x06000020
+ SC_P_FLEXCAN2_RX_ADMA_UART3_RX 0x06000020
+ >;
+ };
+
+ pinctrl_fec1: fec1grp {
+ fsl,pins = <
+ SC_P_COMP_CTL_GPIO_1V8_3V3_ENET_ENETB0_PAD 0x000014a0
+ SC_P_COMP_CTL_GPIO_1V8_3V3_ENET_ENETB1_PAD 0x000014a0
+ SC_P_ENET0_MDC_CONN_ENET0_MDC 0x06000020
+ SC_P_ENET0_MDIO_CONN_ENET0_MDIO 0x06000020
+ SC_P_ENET0_RGMII_TX_CTL_CONN_ENET0_RGMII_TX_CTL 0x00000061
+ SC_P_ENET0_RGMII_TXC_CONN_ENET0_RGMII_TXC 0x00000061
+ SC_P_ENET0_RGMII_TXD0_CONN_ENET0_RGMII_TXD0 0x00000061
+ SC_P_ENET0_RGMII_TXD1_CONN_ENET0_RGMII_TXD1 0x00000061
+ SC_P_ENET0_RGMII_TXD2_CONN_ENET0_RGMII_TXD2 0x00000061
+ SC_P_ENET0_RGMII_TXD3_CONN_ENET0_RGMII_TXD3 0x00000061
+ SC_P_ENET0_RGMII_RXC_CONN_ENET0_RGMII_RXC 0x00000061
+ SC_P_ENET0_RGMII_RX_CTL_CONN_ENET0_RGMII_RX_CTL 0x00000061
+ SC_P_ENET0_RGMII_RXD0_CONN_ENET0_RGMII_RXD0 0x00000061
+ SC_P_ENET0_RGMII_RXD1_CONN_ENET0_RGMII_RXD1 0x00000061
+ SC_P_ENET0_RGMII_RXD2_CONN_ENET0_RGMII_RXD2 0x00000061
+ SC_P_ENET0_RGMII_RXD3_CONN_ENET0_RGMII_RXD3 0x00000061
+ >;
+ };
+
+ pinctrl_fec2: fec2grp {
+ fsl,pins = <
+ SC_P_ESAI0_SCKR_CONN_ENET1_RGMII_TX_CTL 0x00000060
+ SC_P_ESAI0_FSR_CONN_ENET1_RGMII_TXC 0x00000060
+ SC_P_ESAI0_TX4_RX1_CONN_ENET1_RGMII_TXD0 0x00000060
+ SC_P_ESAI0_TX5_RX0_CONN_ENET1_RGMII_TXD1 0x00000060
+ SC_P_ESAI0_FST_CONN_ENET1_RGMII_TXD2 0x00000060
+ SC_P_ESAI0_SCKT_CONN_ENET1_RGMII_TXD3 0x00000060
+ SC_P_ESAI0_TX0_CONN_ENET1_RGMII_RXC 0x00000060
+ SC_P_SPDIF0_TX_CONN_ENET1_RGMII_RX_CTL 0x00000060
+ SC_P_SPDIF0_RX_CONN_ENET1_RGMII_RXD0 0x00000060
+ SC_P_ESAI0_TX3_RX2_CONN_ENET1_RGMII_RXD1 0x00000060
+ SC_P_ESAI0_TX2_RX3_CONN_ENET1_RGMII_RXD2 0x00000060
+ SC_P_ESAI0_TX1_CONN_ENET1_RGMII_RXD3 0x00000060
+ >;
+ };
+
+ pinctrl_flexcan1: flexcan0grp {
+ fsl,pins = <
+ SC_P_FLEXCAN0_TX_ADMA_FLEXCAN0_TX 0x21
+ SC_P_FLEXCAN0_RX_ADMA_FLEXCAN0_RX 0x21
+ >;
+ };
+
+ pinctrl_flexcan2: flexcan1grp {
+ fsl,pins = <
+ SC_P_FLEXCAN1_TX_ADMA_FLEXCAN1_TX 0x21
+ SC_P_FLEXCAN1_RX_ADMA_FLEXCAN1_RX 0x21
+ >;
+ };
+
+ pinctrl_lcdif: lcdif_grp {
+ fsl,pins = <
+ SC_P_ESAI0_FSR_ADMA_LCDIF_D00 0x00000060
+ SC_P_ESAI0_FST_ADMA_LCDIF_D01 0x00000060
+ SC_P_ESAI0_SCKR_ADMA_LCDIF_D02 0x00000060
+ SC_P_ESAI0_SCKT_ADMA_LCDIF_D03 0x00000060
+ SC_P_ESAI0_TX0_ADMA_LCDIF_D04 0x00000060
+ SC_P_ESAI0_TX1_ADMA_LCDIF_D05 0x00000060
+ SC_P_ESAI0_TX2_RX3_ADMA_LCDIF_D06 0x00000060
+ SC_P_ESAI0_TX3_RX2_ADMA_LCDIF_D07 0x00000060
+ SC_P_ESAI0_TX4_RX1_ADMA_LCDIF_D08 0x00000060
+ SC_P_ESAI0_TX5_RX0_ADMA_LCDIF_D09 0x00000060
+ SC_P_SPDIF0_RX_ADMA_LCDIF_D10 0x00000060
+ SC_P_SPDIF0_TX_ADMA_LCDIF_D11 0x00000060
+ SC_P_SPDIF0_EXT_CLK_ADMA_LCDIF_D12 0x00000060
+ SC_P_SPI3_SCK_ADMA_LCDIF_D13 0x00000060
+ SC_P_SPI3_SDO_ADMA_LCDIF_D14 0x00000060
+ SC_P_SPI3_SDI_ADMA_LCDIF_D15 0x00000060
+ SC_P_UART1_RTS_B_ADMA_LCDIF_D16 0x00000060
+ SC_P_UART1_CTS_B_ADMA_LCDIF_D17 0x00000060
+ SC_P_SAI0_TXD_ADMA_LCDIF_D18 0x00000060
+ SC_P_SAI0_TXC_ADMA_LCDIF_D19 0x00000060
+ SC_P_SAI0_RXD_ADMA_LCDIF_D20 0x00000060
+ SC_P_SAI1_RXD_ADMA_LCDIF_D21 0x00000060
+ SC_P_SAI1_RXC_ADMA_LCDIF_D22 0x00000060
+ SC_P_SAI1_RXFS_ADMA_LCDIF_D23 0x00000060
+ SC_P_SPI3_CS0_ADMA_LCDIF_HSYNC 0x00000060
+ SC_P_SPI3_CS1_ADMA_LCDIF_RESET 0x00000060
+ SC_P_MCLK_IN1_ADMA_LCDIF_EN 0x00000060
+ SC_P_MCLK_IN0_ADMA_LCDIF_VSYNC 0x00000060
+ SC_P_MCLK_OUT0_ADMA_LCDIF_CLK 0x00000060
+ >;
+ };
+
+ pinctrl_lcdif_pwm: lcdif_pwm_grp {
+ fsl,pins = <
+ SC_P_SPI0_CS1_ADMA_LCD_PWM0_OUT 0x00000060
+ >;
+ };
+
+ pinctrl_flexspi0: flexspi0grp {
+ fsl,pins = <
+ SC_P_QSPI0A_DATA0_LSIO_QSPI0A_DATA0 0x06000021
+ SC_P_QSPI0A_DATA1_LSIO_QSPI0A_DATA1 0x06000021
+ SC_P_QSPI0A_DATA2_LSIO_QSPI0A_DATA2 0x06000021
+ SC_P_QSPI0A_DATA3_LSIO_QSPI0A_DATA3 0x06000021
+ SC_P_QSPI0A_DQS_LSIO_QSPI0A_DQS 0x06000021
+ SC_P_QSPI0A_SS0_B_LSIO_QSPI0A_SS0_B 0x06000021
+ SC_P_QSPI0A_SS1_B_LSIO_QSPI0A_SS1_B 0x06000021
+ SC_P_QSPI0A_SCLK_LSIO_QSPI0A_SCLK 0x06000021
+ SC_P_QSPI0B_SCLK_LSIO_QSPI0B_SCLK 0x06000021
+ SC_P_QSPI0B_DATA0_LSIO_QSPI0B_DATA0 0x06000021
+ SC_P_QSPI0B_DATA1_LSIO_QSPI0B_DATA1 0x06000021
+ SC_P_QSPI0B_DATA2_LSIO_QSPI0B_DATA2 0x06000021
+ SC_P_QSPI0B_DATA3_LSIO_QSPI0B_DATA3 0x06000021
+ SC_P_QSPI0B_DQS_LSIO_QSPI0B_DQS 0x06000021
+ SC_P_QSPI0B_SS0_B_LSIO_QSPI0B_SS0_B 0x06000021
+ SC_P_QSPI0B_SS1_B_LSIO_QSPI0B_SS1_B 0x06000021
+ >;
+ };
+
+ pinctrl_cm40_i2c: cm40i2cgrp {
+ fsl,pins = <
+ SC_P_ADC_IN1_M40_I2C0_SDA 0x0600004c
+ SC_P_ADC_IN0_M40_I2C0_SCL 0x0600004c
+ >;
+ };
+
+ pinctrl_ioexp_rst: ioexp_rst_grp {
+ fsl,pins = <
+ SC_P_SPI2_SDO_LSIO_GPIO1_IO01 0x06000021
+ >;
+ };
+
+ pinctrl_ioexp_rst_sleep: ioexp_rst_sleep_grp {
+ fsl,pins = <
+ SC_P_SPI2_SDO_LSIO_GPIO1_IO01 0x07800021
+ >;
+ };
+
+ pinctrl_pwm_mipi_lvds0: mipi_lvds0_pwm_grp {
+ fsl,pins = <
+ SC_P_MIPI_DSI0_GPIO0_00_MIPI_DSI0_PWM0_OUT 0x00000020
+ >;
+ };
+
+ pinctrl_i2c0_mipi_lvds0: mipi_lvds0_i2c0_grp {
+ fsl,pins = <
+ SC_P_MIPI_DSI0_I2C0_SCL_MIPI_DSI0_I2C0_SCL 0xc6000020
+ SC_P_MIPI_DSI0_I2C0_SDA_MIPI_DSI0_I2C0_SDA 0xc6000020
+ SC_P_MIPI_DSI0_GPIO0_01_LSIO_GPIO1_IO28 0x00000020
+ >;
+ };
+
+ pinctrl_pwm_mipi_lvds1: mipi_lvds1_pwm_grp {
+ fsl,pins = <
+ SC_P_MIPI_DSI1_GPIO0_00_MIPI_DSI1_PWM0_OUT 0x00000020
+ >;
+ };
+
+ pinctrl_i2c0_mipi_lvds1: mipi_lvds1_i2c0_grp {
+ fsl,pins = <
+ SC_P_MIPI_DSI1_I2C0_SCL_MIPI_DSI1_I2C0_SCL 0xc6000020
+ SC_P_MIPI_DSI1_I2C0_SDA_MIPI_DSI1_I2C0_SDA 0xc6000020
+ SC_P_MIPI_DSI1_GPIO0_01_LSIO_GPIO2_IO00 0x00000020
+ >;
+ };
+
+ pinctrl_isl29023: isl29023grp {
+ fsl,pins = <
+ SC_P_SPI2_SDI_LSIO_GPIO1_IO02 0x00000021
+ >;
+ };
+
+ pinctrl_lpi2c1: lpi1cgrp {
+ fsl,pins = <
+ SC_P_USB_SS3_TC1_ADMA_I2C1_SCL 0x06000021
+ SC_P_USB_SS3_TC3_ADMA_I2C1_SDA 0x06000021
+ >;
+ };
+
+ pinctrl_sai1: sai1grp {
+ fsl,pins = <
+ SC_P_SAI1_RXD_ADMA_SAI1_RXD 0x06000040
+ SC_P_SAI1_RXC_ADMA_SAI1_TXC 0x06000040
+ SC_P_SAI1_RXFS_ADMA_SAI1_TXFS 0x06000040
+ SC_P_SPI0_CS1_ADMA_SAI1_TXD 0x06000060
+ SC_P_SPI2_CS0_LSIO_GPIO1_IO00 0x06000040
+ >;
+ };
+
+ pinctrl_usdhc1: usdhc1grp {
+ fsl,pins = <
+ SC_P_EMMC0_CLK_CONN_EMMC0_CLK 0x06000041
+ SC_P_EMMC0_CMD_CONN_EMMC0_CMD 0x00000021
+ SC_P_EMMC0_DATA0_CONN_EMMC0_DATA0 0x00000021
+ SC_P_EMMC0_DATA1_CONN_EMMC0_DATA1 0x00000021
+ SC_P_EMMC0_DATA2_CONN_EMMC0_DATA2 0x00000021
+ SC_P_EMMC0_DATA3_CONN_EMMC0_DATA3 0x00000021
+ SC_P_EMMC0_DATA4_CONN_EMMC0_DATA4 0x00000021
+ SC_P_EMMC0_DATA5_CONN_EMMC0_DATA5 0x00000021
+ SC_P_EMMC0_DATA6_CONN_EMMC0_DATA6 0x00000021
+ SC_P_EMMC0_DATA7_CONN_EMMC0_DATA7 0x00000021
+ SC_P_EMMC0_STROBE_CONN_EMMC0_STROBE 0x00000041
+ >;
+ };
+
+ pinctrl_typec: typecgrp {
+ fsl,pins = <
+ SC_P_ENET0_REFCLK_125M_25M_LSIO_GPIO5_IO09 0x60
+ SC_P_SPI2_SCK_LSIO_GPIO1_IO03 0x06000021
+ >;
+ };
+
+ pinctrl_usdhc1_100mhz: usdhc1grp100mhz {
+ fsl,pins = <
+ SC_P_EMMC0_CLK_CONN_EMMC0_CLK 0x06000041
+ SC_P_EMMC0_CMD_CONN_EMMC0_CMD 0x00000021
+ SC_P_EMMC0_DATA0_CONN_EMMC0_DATA0 0x00000021
+ SC_P_EMMC0_DATA1_CONN_EMMC0_DATA1 0x00000021
+ SC_P_EMMC0_DATA2_CONN_EMMC0_DATA2 0x00000021
+ SC_P_EMMC0_DATA3_CONN_EMMC0_DATA3 0x00000021
+ SC_P_EMMC0_DATA4_CONN_EMMC0_DATA4 0x00000021
+ SC_P_EMMC0_DATA5_CONN_EMMC0_DATA5 0x00000021
+ SC_P_EMMC0_DATA6_CONN_EMMC0_DATA6 0x00000021
+ SC_P_EMMC0_DATA7_CONN_EMMC0_DATA7 0x00000021
+ SC_P_EMMC0_STROBE_CONN_EMMC0_STROBE 0x00000041
+ >;
+ };
+
+ pinctrl_usdhc1_200mhz: usdhc1grp200mhz {
+ fsl,pins = <
+ SC_P_EMMC0_CLK_CONN_EMMC0_CLK 0x06000041
+ SC_P_EMMC0_CMD_CONN_EMMC0_CMD 0x00000021
+ SC_P_EMMC0_DATA0_CONN_EMMC0_DATA0 0x00000021
+ SC_P_EMMC0_DATA1_CONN_EMMC0_DATA1 0x00000021
+ SC_P_EMMC0_DATA2_CONN_EMMC0_DATA2 0x00000021
+ SC_P_EMMC0_DATA3_CONN_EMMC0_DATA3 0x00000021
+ SC_P_EMMC0_DATA4_CONN_EMMC0_DATA4 0x00000021
+ SC_P_EMMC0_DATA5_CONN_EMMC0_DATA5 0x00000021
+ SC_P_EMMC0_DATA6_CONN_EMMC0_DATA6 0x00000021
+ SC_P_EMMC0_DATA7_CONN_EMMC0_DATA7 0x00000021
+ SC_P_EMMC0_STROBE_CONN_EMMC0_STROBE 0x00000041
+ >;
+ };
+
+ pinctrl_usdhc2_gpio: usdhc2gpiogrp {
+ fsl,pins = <
+ SC_P_USDHC1_RESET_B_LSIO_GPIO4_IO19 0x00000021
+ SC_P_USDHC1_WP_LSIO_GPIO4_IO21 0x00000021
+ SC_P_USDHC1_CD_B_LSIO_GPIO4_IO22 0x00000021
+ >;
+ };
+
+ pinctrl_usdhc2: usdhc2grp {
+ fsl,pins = <
+ SC_P_USDHC1_CLK_CONN_USDHC1_CLK 0x06000041
+ SC_P_USDHC1_CMD_CONN_USDHC1_CMD 0x00000021
+ SC_P_USDHC1_DATA0_CONN_USDHC1_DATA0 0x00000021
+ SC_P_USDHC1_DATA1_CONN_USDHC1_DATA1 0x00000021
+ SC_P_USDHC1_DATA2_CONN_USDHC1_DATA2 0x00000021
+ SC_P_USDHC1_DATA3_CONN_USDHC1_DATA3 0x00000021
+ SC_P_USDHC1_VSELECT_CONN_USDHC1_VSELECT 0x00000021
+ >;
+ };
+
+ pinctrl_usdhc2_100mhz: usdhc2grp100mhz {
+ fsl,pins = <
+ SC_P_USDHC1_CLK_CONN_USDHC1_CLK 0x06000041
+ SC_P_USDHC1_CMD_CONN_USDHC1_CMD 0x00000021
+ SC_P_USDHC1_DATA0_CONN_USDHC1_DATA0 0x00000021
+ SC_P_USDHC1_DATA1_CONN_USDHC1_DATA1 0x00000021
+ SC_P_USDHC1_DATA2_CONN_USDHC1_DATA2 0x00000021
+ SC_P_USDHC1_DATA3_CONN_USDHC1_DATA3 0x00000021
+ SC_P_USDHC1_VSELECT_CONN_USDHC1_VSELECT 0x00000021
+ >;
+ };
+
+ pinctrl_usdhc2_200mhz: usdhc2grp200mhz {
+ fsl,pins = <
+ SC_P_USDHC1_CLK_CONN_USDHC1_CLK 0x06000041
+ SC_P_USDHC1_CMD_CONN_USDHC1_CMD 0x00000021
+ SC_P_USDHC1_DATA0_CONN_USDHC1_DATA0 0x00000021
+ SC_P_USDHC1_DATA1_CONN_USDHC1_DATA1 0x00000021
+ SC_P_USDHC1_DATA2_CONN_USDHC1_DATA2 0x00000021
+ SC_P_USDHC1_DATA3_CONN_USDHC1_DATA3 0x00000021
+ SC_P_USDHC1_VSELECT_CONN_USDHC1_VSELECT 0x00000021
+ >;
+ };
+
+ pinctrl_pcieb: pcieagrp{
+ fsl,pins = <
+ SC_P_PCIE_CTRL0_PERST_B_LSIO_GPIO4_IO00 0x06000021
+ SC_P_PCIE_CTRL0_CLKREQ_B_LSIO_GPIO4_IO01 0x06000021
+ SC_P_PCIE_CTRL0_WAKE_B_LSIO_GPIO4_IO02 0x04000021
+ >;
+ };
+
+ pinctrl_mipi_csi0_gpio: mipicsi0gpiogrp{
+ fsl,pins = <
+ SC_P_MIPI_CSI0_GPIO0_00_MIPI_CSI0_GPIO0_IO00 0x00000021
+ SC_P_MIPI_CSI0_GPIO0_01_MIPI_CSI0_GPIO0_IO01 0x00000021
+ >;
+ };
+
+ pinctrl_gpio3: gpio3grp{
+ fsl,pins = <
+ SC_P_MIPI_CSI0_GPIO0_01_LSIO_GPIO3_IO07 0xC0000041
+ SC_P_MIPI_CSI0_GPIO0_00_LSIO_GPIO3_IO08 0xC0000041
+ >;
+ };
+
+ pinctrl_wifi: wifigrp{
+ fsl,pins = <
+ SC_P_SCU_BOOT_MODE3_SCU_DSC_RTC_CLOCK_OUTPUT_32K 0x20
+ >;
+ };
+
+ pinctrl_wifi_init: wifi_initgrp{
+ fsl,pins = <
+ SC_P_SCU_BOOT_MODE3_SCU_DSC_BOOT_MODE3 0x20
+ >;
+ };
+
+ pinctrl_parallel_csi: parallelcsigrp {
+ fsl,pins = <
+ SC_P_CSI_D00_CI_PI_D02 0xC0000041
+ SC_P_CSI_D01_CI_PI_D03 0xC0000041
+ SC_P_CSI_D02_CI_PI_D04 0xC0000041
+ SC_P_CSI_D03_CI_PI_D05 0xC0000041
+ SC_P_CSI_D04_CI_PI_D06 0xC0000041
+ SC_P_CSI_D05_CI_PI_D07 0xC0000041
+ SC_P_CSI_D06_CI_PI_D08 0xC0000041
+ SC_P_CSI_D07_CI_PI_D09 0xC0000041
+
+ SC_P_CSI_MCLK_CI_PI_MCLK 0xC0000041
+ SC_P_CSI_PCLK_CI_PI_PCLK 0xC0000041
+ SC_P_CSI_HSYNC_CI_PI_HSYNC 0xC0000041
+ SC_P_CSI_VSYNC_CI_PI_VSYNC 0xC0000041
+ SC_P_CSI_EN_LSIO_GPIO3_IO02 0xC0000041
+ SC_P_CSI_RESET_LSIO_GPIO3_IO03 0xC0000041
+ >;
+ };
+ };
+};
+
+&pd_dma_lpuart0 {
+ debug_console;
+};
+
+&lpuart0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lpuart0>;
+ status = "okay";
+};
+
+&lpuart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lpuart1>;
+ resets = <&modem_reset>;
+ status = "okay";
+};
+
+&lpuart2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lpuart2>;
+ status = "okay";
+};
+
+&lpuart3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lpuart3>;
+ status = "okay";
+};
+
+&fec1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_fec1>;
+ phy-mode = "rgmii-txid";
+ phy-handle = <&ethphy0>;
+ fsl,magic-packet;
+ fsl,rgmii_rxc_dly;
+ status = "okay";
+
+ mdio {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ethphy0: ethernet-phy@0 {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <0>;
+ at803x,eee-disabled;
+ at803x,vddio-1p8v;
+ };
+
+ ethphy1: ethernet-phy@1 {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <1>;
+ at803x,eee-disabled;
+ at803x,vddio-1p8v;
+ status = "disabled";
+ };
+ };
+};
+
+&fec2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_fec2>;
+ phy-mode = "rgmii-txid";
+ phy-handle = <&ethphy1>;
+ phy-supply = <&reg_fec2_supply>;
+ fsl,magic-packet;
+ fsl,rgmii_rxc_dly;
+ status = "disabled";
+};
+
+&flexcan1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_flexcan1>;
+ xceiver-supply = <&reg_can_stby>;
+ status = "okay";
+};
+
+&flexcan2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_flexcan2>;
+ xceiver-supply = <&reg_can_stby>;
+ status = "okay";
+};
+
+&flexspi0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_flexspi0>;
+ status = "okay";
+
+ flash0: mt35xu512aba@0 {
+ reg = <0>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "micron,mt35xu512aba";
+ spi-max-frequency = <133000000>;
+ spi-nor,ddr-quad-read-dummy = <8>;
+ };
+};
+
+&pd_cm40_intmux {
+ early_power_on;
+};
+
+&intmux_cm40 {
+ status = "okay";
+};
+
+&i2c0_cm40 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_cm40_i2c>;
+ status = "okay";
+
+ wm8960: wm8960@1a {
+ compatible = "wlf,wm8960";
+ reg = <0x1a>;
+ clocks = <&clk IMX8QXP_AUD_MCLKOUT0>;
+ clock-names = "mclk";
+ wlf,shared-lrclk;
+ power-domains = <&pd_mclk_out0>;
+ assigned-clocks = <&clk IMX8QXP_AUD_PLL0_DIV>,
+ <&clk IMX8QXP_AUD_ACM_AUD_PLL_CLK0_DIV>,
+ <&clk IMX8QXP_AUD_ACM_AUD_REC_CLK0_DIV>,
+ <&clk IMX8QXP_AUD_MCLKOUT0>;
+ assigned-clock-rates = <786432000>, <49152000>, <12288000>, <12288000>;
+ };
+
+ pca6416: gpio@20 {
+ compatible = "ti,tca6416";
+ reg = <0x20>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ cs42888: cs42888@48 {
+ compatible = "cirrus,cs42888";
+ reg = <0x48>;
+ clocks = <&clk IMX8QXP_AUD_MCLKOUT0>;
+ clock-names = "mclk";
+ VA-supply = <&reg_audio>;
+ VD-supply = <&reg_audio>;
+ VLS-supply = <&reg_audio>;
+ VLC-supply = <&reg_audio>;
+ reset-gpio = <&pca9557_b 1 1>;
+ power-domains = <&pd_mclk_out0>;
+ assigned-clocks = <&clk IMX8QXP_AUD_PLL0_DIV>,
+ <&clk IMX8QXP_AUD_ACM_AUD_PLL_CLK0_DIV>,
+ <&clk IMX8QXP_AUD_ACM_AUD_REC_CLK0_DIV>,
+ <&clk IMX8QXP_AUD_MCLKOUT0>;
+ assigned-clock-rates = <786432000>, <49152000>, <12288000>, <12288000>;
+ fsl,txs-rxm;
+ status = "okay";
+ };
+
+ ov5640: ov5640@3c {
+ compatible = "ovti,ov5640_v3";
+ reg = <0x3c>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_parallel_csi>;
+ clocks = <&clk IMX8QXP_PARALLEL_CSI_MISC0_CLK>;
+ clock-names = "csi_mclk";
+ pwn-gpios = <&gpio3 2 GPIO_ACTIVE_LOW>;
+ rst-gpios = <&gpio3 3 GPIO_ACTIVE_HIGH>;
+ csi_id = <0>;
+ mclk = <24000000>;
+ mclk_source = <0>;
+ status = "okay";
+ port {
+ ov5640_ep: endpoint {
+ remote-endpoint = <&parallel_csi_ep>;
+ };
+ };
+ };
+};
+
+&i2c1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clock-frequency = <100000>;
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&pinctrl_lpi2c1 &pinctrl_ioexp_rst>;
+ pinctrl-1 = <&pinctrl_lpi2c1 &pinctrl_ioexp_rst_sleep>;
+ pinctrl-assert-gpios = <&gpio1 1 GPIO_ACTIVE_HIGH>;
+ status = "okay";
+
+ pca9646@71 {
+ compatible = "nxp,pca9646";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x71>;
+
+ i2c@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0>;
+
+ max7322: gpio@68 {
+ compatible = "maxim,max7322";
+ reg = <0x68>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+ };
+
+ i2c@1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <1>;
+ };
+
+ i2c@2 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <2>;
+
+ fxos8700@1e {
+ compatible = "fsl,fxos8700";
+ reg = <0x1e>;
+ interrupt-open-drain;
+ };
+
+ fxas2100x@21 {
+ compatible = "fsl,fxas2100x";
+ reg = <0x21>;
+ interrupt-open-drain;
+ };
+
+ mpl3115@60 {
+ compatible = "fsl,mpl3115";
+ reg = <0x60>;
+ interrupt-open-drain;
+ };
+ };
+
+ i2c@3 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <3>;
+
+ pca9557_a: gpio@1a {
+ compatible = "nxp,pca9557";
+ reg = <0x1a>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ pca9557_b: gpio@1d {
+ compatible = "nxp,pca9557";
+ reg = <0x1d>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ isl29023@44 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_isl29023>;
+ compatible = "fsl,isl29023";
+ reg = <0x44>;
+ rext = <499>;
+ interrupt-parent = <&gpio1>;
+ interrupts = <2 2>;
+ };
+ };
+ };
+
+ typec_ptn5110: typec@50 {
+ compatible = "usb,tcpci";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_typec>;
+ reg = <0x50>;
+ interrupt-parent = <&gpio1>;
+ interrupts = <3 IRQ_TYPE_LEVEL_LOW>;
+ ss-sel-gpios = <&gpio5 9 GPIO_ACTIVE_LOW>;
+ reset-gpios = <&pca9557_a 7 GPIO_ACTIVE_HIGH>;
+ src-pdos = <0x380190c8 0x3803c0c8>;
+ port-type = "drp";
+ sink-disable;
+ default-role = "source";
+ status = "okay";
+ };
+};
+
+&sai1 {
+ assigned-clocks = <&clk IMX8QXP_AUD_PLL0_DIV>,
+ <&clk IMX8QXP_AUD_ACM_AUD_PLL_CLK0_DIV>,
+ <&clk IMX8QXP_AUD_ACM_AUD_REC_CLK0_DIV>,
+ <&clk IMX8QXP_AUD_SAI_1_MCLK>;
+ assigned-clock-rates = <786432000>, <49152000>, <12288000>, <49152000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_sai1>;
+ status = "okay";
+};
+
+&usbotg1 {
+ vbus-supply = <&reg_usb_otg1_vbus>;
+ srp-disable;
+ hnp-disable;
+ adp-disable;
+ power-polarity-active-high;
+ disable-over-current;
+ status = "okay";
+};
+
+&usbotg3 {
+ dr_mode = "otg";
+ extcon = <&typec_ptn5110>;
+ status = "okay";
+};
+
+&usbphy1 {
+ fsl,tx-d-cal = <114>;
+};
+
+&usdhc1 {
+ pinctrl-names = "default", "state_100mhz", "state_200mhz";
+ pinctrl-0 = <&pinctrl_usdhc1>;
+ pinctrl-1 = <&pinctrl_usdhc1_100mhz>;
+ pinctrl-2 = <&pinctrl_usdhc1_200mhz>;
+ bus-width = <8>;
+ non-removable;
+ status = "okay";
+};
+
+&usdhc2 {
+ pinctrl-names = "default", "state_100mhz", "state_200mhz";
+ pinctrl-0 = <&pinctrl_usdhc2>, <&pinctrl_usdhc2_gpio>;
+ pinctrl-1 = <&pinctrl_usdhc2_100mhz>, <&pinctrl_usdhc2_gpio>;
+ pinctrl-2 = <&pinctrl_usdhc2_200mhz>, <&pinctrl_usdhc2_gpio>;
+ bus-width = <4>;
+ cd-gpios = <&gpio4 22 GPIO_ACTIVE_LOW>;
+ wp-gpios = <&gpio4 21 GPIO_ACTIVE_HIGH>;
+ vmmc-supply = <&reg_usdhc2_vmmc>;
+ status = "okay";
+};
+
+&pcieb{
+ ext_osc = <1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pcieb>;
+ clkreq-gpio = <&gpio4 1 GPIO_ACTIVE_LOW>;
+ disable-gpio = <&pca9557_a 2 GPIO_ACTIVE_LOW>;
+ reset-gpio = <&gpio4 0 GPIO_ACTIVE_LOW>;
+ epdev_on-supply = <&epdev_on>;
+ status = "okay";
+};
+
+&pixel_combiner {
+ status = "okay";
+};
+
+&prg1 {
+ status = "okay";
+};
+
+&prg2 {
+ status = "okay";
+};
+
+&prg3 {
+ status = "okay";
+};
+
+&prg4 {
+ status = "okay";
+};
+
+&prg5 {
+ status = "okay";
+};
+
+&prg6 {
+ status = "okay";
+};
+
+&prg7 {
+ status = "okay";
+};
+
+&prg8 {
+ status = "okay";
+};
+
+&prg9 {
+ status = "okay";
+};
+
+&dpr1_channel1 {
+ status = "okay";
+};
+
+&dpr1_channel2 {
+ status = "okay";
+};
+
+&dpr1_channel3 {
+ status = "okay";
+};
+
+&dpr2_channel1 {
+ status = "okay";
+};
+
+&dpr2_channel2 {
+ status = "okay";
+};
+
+&dpr2_channel3 {
+ status = "okay";
+};
+
+&dpu1 {
+ status = "okay";
+};
+
+&gpu_3d0 {
+ status = "okay";
+};
+
+&imx8_gpu_ss {
+ status = "okay";
+};
+
+&mipi_csi_0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ virtual-channel;
+ status = "okay";
+
+ /* Camera 0 MIPI CSI-2 (CSIS0) */
+ port@0 {
+ reg = <0>;
+ mipi_csi0_ep: endpoint {
+ remote-endpoint = <&max9286_0_ep>;
+ data-lanes = <1 2 3 4>;
+ };
+ };
+};
+
+&cameradev {
+ parallel_csi;
+ status = "okay";
+};
+
+&parallel_csi {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "okay";
+ port@0 {
+ reg = <0>;
+ parallel_csi_ep: endpoint {
+ remote-endpoint = <&ov5640_ep>;
+ };
+ };
+};
+
+&isi_0 {
+ status = "okay";
+};
+
+&isi_1 {
+ status = "okay";
+};
+
+&isi_2 {
+ status = "okay";
+};
+
+&isi_3 {
+ status = "okay";
+};
+
+&isi_4 {
+ interface = <6 0 2>; /* INPUT: 6-PARALLEL CSI */
+ parallel_csi;
+ status = "okay";
+};
+
+&gpio3 {
+ pinctrl-name = "default";
+ pinctrl-0 = <&pinctrl_gpio3>;
+};
+
+&i2c0_csi0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_csi0_lpi2c0>;
+ clock-frequency = <100000>;
+ status = "okay";
+
+ max9286_mipi@6A {
+ compatible = "maxim,max9286_mipi";
+ reg = <0x6A>;
+ clocks = <&clk IMX8QXP_CLK_DUMMY>;
+ clock-names = "capture_mclk";
+ mclk = <27000000>;
+ mclk_source = <0>;
+ pwn-gpios = <&gpio3 7 GPIO_ACTIVE_HIGH>;
+ virtual-channel;
+ status = "okay";
+ port {
+ max9286_0_ep: endpoint {
+ remote-endpoint = <&mipi_csi0_ep>;
+ data-lanes = <1 2 3 4>;
+ };
+ };
+ };
+};
+
+&vpu {
+ status = "disabled";
+};
+
+&vpu_decoder {
+ core_type = <1>;
+ status = "okay";
+};
+
+&vpu_encoder {
+ status = "okay";
+};
+
+&pwm_mipi_lvds0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pwm_mipi_lvds0>;
+ status = "okay";
+};
+
+/* DSI/LVDS port 0 */
+&i2c0_mipi_lvds0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c0_mipi_lvds0>;
+ clock-frequency = <100000>;
+ status = "okay";
+
+ lvds-to-hdmi-bridge@4c {
+ compatible = "ite,it6263";
+ reg = <0x4c>;
+ reset-gpios = <&pca9557_a 6 GPIO_ACTIVE_LOW>;
+
+ port {
+ it6263_0_in: endpoint {
+ clock-lanes = <4>;
+ data-lanes = <0 1 2 3>;
+ remote-endpoint = <&lvds0_out>;
+ };
+ };
+ };
+
+ adv_bridge1: adv7535@3d {
+ compatible = "adi,adv7535", "adi,adv7533";
+ reg = <0x3d>;
+ adi,dsi-lanes = <4>;
+ adi,dsi-channel = <1>;
+ interrupt-parent = <&gpio1>;
+ interrupts = <28 IRQ_TYPE_LEVEL_LOW>;
+ status = "okay";
+
+ port {
+ adv7535_1_in: endpoint {
+ remote-endpoint = <&mipi_dsi_bridge1_out>;
+ };
+ };
+ };
+
+};
+
+&ldb1_phy {
+ status = "okay";
+};
+
+&ldb1 {
+ status = "okay";
+
+ lvds-channel@0 {
+ fsl,data-mapping = "jeida";
+ fsl,data-width = <24>;
+ status = "okay";
+
+ port@1 {
+ reg = <1>;
+
+ lvds0_out: endpoint {
+ remote-endpoint = <&it6263_0_in>;
+ };
+ };
+ };
+};
+
+&mipi_dsi_phy1 {
+ status = "okay";
+};
+
+&mipi_dsi1 {
+ pwr-delay = <10>;
+ status = "okay";
+};
+
+&mipi_dsi_bridge1 {
+ status = "okay";
+
+ port@1 {
+ mipi_dsi_bridge1_out: endpoint {
+ remote-endpoint = <&adv7535_1_in>;
+ };
+ };
+};
+
+&pwm_mipi_lvds1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pwm_mipi_lvds1>;
+ status = "okay";
+};
+
+/* DSI/LVDS port 1 */
+&i2c0_mipi_lvds1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c0_mipi_lvds1>;
+ clock-frequency = <100000>;
+ status = "okay";
+
+ lvds-to-hdmi-bridge@4c {
+ compatible = "ite,it6263";
+ reg = <0x4c>;
+ reset-gpios = <&pca9557_b 7 GPIO_ACTIVE_LOW>;
+
+ port {
+ it6263_1_in: endpoint {
+ clock-lanes = <4>;
+ data-lanes = <0 1 2 3>;
+ remote-endpoint = <&lvds1_out>;
+ };
+ };
+ };
+
+ adv_bridge2: adv7535@3d {
+ compatible = "adi,adv7535", "adi,adv7533";
+ reg = <0x3d>;
+ adi,dsi-lanes = <4>;
+ adi,dsi-channel = <1>;
+ interrupt-parent = <&gpio2>;
+ interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+ status = "okay";
+
+ port {
+ adv7535_2_in: endpoint {
+ remote-endpoint = <&mipi_dsi_bridge2_out>;
+ };
+ };
+ };
+};
+
+&ldb2_phy {
+ status = "okay";
+};
+
+&ldb2 {
+ status = "okay";
+
+ lvds-channel@0 {
+ fsl,data-mapping = "jeida";
+ fsl,data-width = <24>;
+ status = "okay";
+
+ port@1 {
+ reg = <1>;
+
+ lvds1_out: endpoint {
+ remote-endpoint = <&it6263_1_in>;
+ };
+ };
+ };
+};
+
+&mipi_dsi_phy2 {
+ status = "okay";
+};
+
+&mipi_dsi2 {
+ pwr-delay = <10>;
+ status = "okay";
+};
+
+&mipi_dsi_bridge2 {
+ status = "okay";
+
+ port@1 {
+ mipi_dsi_bridge2_out: endpoint {
+ remote-endpoint = <&adv7535_2_in>;
+ };
+ };
+};
+
+&tsens {
+ tsens-num = <3>;
+};
+
+&thermal_zones {
+ pmic-thermal0 {
+ polling-delay-passive = <250>;
+ polling-delay = <2000>;
+ thermal-sensors = <&tsens 2>;
+ trips {
+ pmic_alert0: trip0 {
+ temperature = <110000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+ pmic_crit0: trip1 {
+ temperature = <125000>;
+ hysteresis = <2000>;
+ type = "critical";
+ };
+ };
+ cooling-maps {
+ map0 {
+ trip = <&pmic_alert0>;
+ cooling-device =
+ <&A35_0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
+ };
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8qxp-xen.dtsi b/arch/arm64/boot/dts/freescale/fsl-imx8qxp-xen.dtsi
new file mode 100644
index 000000000000..2d600d0700c0
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8qxp-xen.dtsi
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2018 NXP
+ *
+ * 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.
+ */
+
+/ {
+ /delete-node/ wu;
+};
+
+&usbotg1 {
+ interrupt-parent = <&gic>;
+};
+
+&flexcan1 {
+ interrupt-parent = <&gic>;
+};
+
+&flexcan2 {
+ interrupt-parent = <&gic>;
+};
+
+&flexcan3 {
+ interrupt-parent = <&gic>;
+};
+
+&usbotg3 {
+ interrupt-parent = <&gic>;
+};
+
+&lpuart0 {
+ interrupt-parent = <&gic>;
+};
+
+&lpuart1 {
+ interrupt-parent = <&gic>;
+};
+
+&lpuart2 {
+ interrupt-parent = <&gic>;
+};
+
+&lpuart3 {
+ interrupt-parent = <&gic>;
+};
+
+&fec1 {
+ interrupt-parent = <&gic>;
+};
+
+&fec2 {
+ interrupt-parent = <&gic>;
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8qxp.dtsi b/arch/arm64/boot/dts/freescale/fsl-imx8qxp.dtsi
new file mode 100644
index 000000000000..b3c7ed38cec6
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8qxp.dtsi
@@ -0,0 +1,51 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2018 NXP
+ *
+ * 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 "fsl-imx8dxp.dtsi"
+
+/ {
+ model = "Freescale i.MX8QXP";
+ compatible = "fsl,imx8qxp";
+
+ cpus {
+ A35_2: cpu@2 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a35";
+ reg = <0x0 0x2>;
+ enable-method = "psci";
+ next-level-cache = <&A35_L2>;
+ };
+
+ A35_3: cpu@3 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a35";
+ reg = <0x0 0x3>;
+ enable-method = "psci";
+ next-level-cache = <&A35_L2>;
+ };
+ };
+
+ pmu {
+ interrupt-affinity = <&A35_0>, <&A35_1>, <&A35_2>, <&A35_3>;
+ };
+};
+
+&A35_2 {
+ device_type = "cpu";
+};
+
+&A35_3 {
+ device_type = "cpu";
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8x-17x17-val.dtsi b/arch/arm64/boot/dts/freescale/fsl-imx8x-17x17-val.dtsi
new file mode 100644
index 000000000000..ac38be4998a6
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8x-17x17-val.dtsi
@@ -0,0 +1,155 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2019 NXP
+ *
+ * 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 "fsl-imx8x-arm2.dtsi"
+
+/ {
+ reserved-memory {
+ linux,cma {
+ compatible = "shared-dma-pool";
+ reusable;
+ size = <0 0x14000000>;
+ alloc-ranges = <0 0x96000000 0 0x14000000>;
+ linux,cma-default;
+ };
+ };
+
+ regulators {
+ epdev_on: fixedregulator@100 {
+ compatible = "regulator-fixed";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-name = "epdev_on";
+ gpio = <&pca9557_a 0 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+ };
+};
+
+&iomuxc {
+ imx8qxp-lpddr4-arm2 {
+ pinctrl_flexspi0: flexspi0grp {
+ fsl,pins = <
+ SC_P_QSPI0A_DATA0_LSIO_QSPI0A_DATA0 0x06000021
+ SC_P_QSPI0A_DATA1_LSIO_QSPI0A_DATA1 0x06000021
+ SC_P_QSPI0A_DATA2_LSIO_QSPI0A_DATA2 0x06000021
+ SC_P_QSPI0A_DATA3_LSIO_QSPI0A_DATA3 0x06000021
+ SC_P_QSPI0A_SS0_B_LSIO_QSPI0A_SS0_B 0x06000021
+ SC_P_QSPI0A_SCLK_LSIO_QSPI0A_SCLK 0x06000021
+ >;
+ };
+ };
+};
+
+&i2c1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lpi2c1>;
+ status = "okay";
+
+ /delete-node/ gpio@68;
+ /delete-node/ typec@3d;
+
+ pca9557_a: gpio@18 {
+ compatible = "nxp,pca9557";
+ reg = <0x18>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ pca9557_b: gpio@19 {
+ compatible = "nxp,pca9557";
+ reg = <0x19>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+};
+
+&i2c2 {
+ status = "disabled";
+};
+
+&i2c3 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lpi2c3>;
+ status = "okay";
+
+ /delete-node/ gpio@18;
+ /delete-node/ gpio@19;
+
+ max7322: gpio@68 {
+ compatible = "maxim,max7322";
+ reg = <0x68>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+};
+
+&i2c0_csi0 {
+ status = "disabled";
+};
+
+&mipi_csi_0 {
+ status = "disabled";
+};
+
+&gpio0_mipi_csi0 {
+ status = "disabled";
+};
+
+&pcieb{
+ ext_osc = <1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pcieb>;
+ clkreq-gpio = <&gpio4 1 GPIO_ACTIVE_LOW>;
+ disable-gpio = <&pca9557_a 5 GPIO_ACTIVE_LOW>;
+ reset-gpio = <&gpio4 0 GPIO_ACTIVE_LOW>;
+ epdev_on-supply = <&epdev_on>;
+ status = "okay";
+};
+
+&usdhc2 {
+ status = "disabled";
+};
+
+&flexspi0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_flexspi0>;
+ status = "okay";
+
+ /delete-node/ mt35xu512aba@0;
+
+ flash0: mt25qu512abb@0 {
+ reg = <0>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "micron,mt25qu512abb";
+ spi-max-frequency = <29000000>;
+ };
+};
+
+&adc0 {
+ status = "disabled";
+};
+
+&usbotg1 {
+ /delete-property/ pinctrl-names;
+ /delete-property/ pinctrl-0;
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8x-arm2.dtsi b/arch/arm64/boot/dts/freescale/fsl-imx8x-arm2.dtsi
new file mode 100644
index 000000000000..9ff873574130
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8x-arm2.dtsi
@@ -0,0 +1,1013 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2017~2018 NXP
+ *
+ * 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.
+ */
+
+/ {
+ chosen {
+ bootargs = "console=ttyLP0,115200 earlycon=lpuart32,0x5a060000,115200";
+ stdout-path = &lpuart0;
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ reg_usdhc2_vmmc: usdhc2_vmmc {
+ compatible = "regulator-fixed";
+ regulator-name = "SD1_SPWR";
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ gpio = <&gpio4 19 GPIO_ACTIVE_HIGH>;
+ off-on-delay = <2720>;
+ enable-active-high;
+ };
+
+ reg_can_en: regulator-can-gen {
+ compatible = "regulator-fixed";
+ regulator-name = "can-en";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&pca9557_b 5 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ reg_can_stby: regulator-can-stby {
+ compatible = "regulator-fixed";
+ regulator-name = "can-stby";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&pca9557_b 4 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ vin-supply = <&reg_can_en>;
+ };
+
+ reg_audio: fixedregulator@0 {
+ compatible = "regulator-fixed";
+ reg = <2>;
+ regulator-name = "cs42888_supply";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ reg_baseboard: fixedregulator@1 {
+ compatible = "regulator-fixed";
+ reg = <2>;
+ regulator-name = "baseboard_supply";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ gpio = <&gpio5 9 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ reg_fec2_supply: fec2_nvcc {
+ compatible = "regulator-fixed";
+ regulator-name = "fec2_nvcc";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ gpio = <&max7322 0 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ reg_adc_vref_1v8: adc_vref_1v8 {
+ compatible = "regulator-fixed";
+ regulator-name = "vref_1v8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+ };
+
+ sound-cs42888 {
+ compatible = "fsl,imx8qm-sabreauto-cs42888",
+ "fsl,imx-audio-cs42888";
+ model = "imx-cs42888";
+ esai-controller = <&esai0>;
+ audio-codec = <&codec>;
+ asrc-controller = <&asrc0>;
+ status = "okay";
+ };
+
+ sound-amix-sai {
+ compatible = "fsl,imx-audio-amix";
+ model = "amix-audio-sai";
+ dais = <&sai4>, <&sai5>;
+ amix-controller = <&amix>;
+ };
+};
+
+&acm {
+ status = "okay";
+};
+
+&adc0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_adc0>;
+ vref-supply = <&reg_adc_vref_1v8>;
+ status = "okay";
+};
+
+&amix {
+ status = "okay";
+};
+
+&asrc0 {
+ fsl,asrc-rate = <48000>;
+ status = "okay";
+};
+
+&asrc1 {
+ fsl,asrc-rate = <48000>;
+ status = "okay";
+};
+
+&esai0 {
+ compatible = "fsl,imx8qm-esai";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_esai0>;
+ assigned-clocks = <&clk IMX8QXP_ACM_ESAI0_MCLK_SEL>,
+ <&clk IMX8QXP_AUD_PLL0_DIV>,
+ <&clk IMX8QXP_AUD_ACM_AUD_PLL_CLK0_DIV>,
+ <&clk IMX8QXP_AUD_ACM_AUD_REC_CLK0_DIV>,
+ <&clk IMX8QXP_AUD_ESAI_0_EXTAL_IPG>;
+ assigned-clock-parents = <&clk IMX8QXP_AUD_ACM_AUD_PLL_CLK0_CLK>;
+ assigned-clock-rates = <0>, <786432000>, <49152000>, <24576000>, <49152000>;
+ status = "okay";
+};
+
+&sai4 {
+ assigned-clocks = <&clk IMX8QXP_ACM_SAI4_MCLK_SEL>,
+ <&clk IMX8QXP_AUD_PLL1_DIV>,
+ <&clk IMX8QXP_AUD_ACM_AUD_PLL_CLK1_DIV>,
+ <&clk IMX8QXP_AUD_ACM_AUD_REC_CLK1_DIV>,
+ <&clk IMX8QXP_AUD_SAI_4_MCLK>;
+ assigned-clock-parents = <&clk IMX8QXP_AUD_ACM_AUD_PLL_CLK1_CLK>;
+ assigned-clock-rates = <0>, <786432000>, <98304000>, <24576000>, <98304000>;
+ fsl,sai-asynchronous;
+ fsl,txm-rxs;
+ status = "okay";
+};
+
+&sai5 {
+ assigned-clocks = <&clk IMX8QXP_ACM_SAI5_MCLK_SEL>,
+ <&clk IMX8QXP_AUD_PLL1_DIV>,
+ <&clk IMX8QXP_AUD_ACM_AUD_PLL_CLK1_DIV>,
+ <&clk IMX8QXP_AUD_ACM_AUD_REC_CLK1_DIV>,
+ <&clk IMX8QXP_AUD_SAI_5_MCLK>;
+ assigned-clock-parents = <&clk IMX8QXP_AUD_ACM_AUD_PLL_CLK1_CLK>;
+ assigned-clock-rates = <0>, <786432000>, <98304000>, <24576000>, <98304000>;
+ fsl,sai-asynchronous;
+ fsl,txm-rxs;
+ status = "okay";
+};
+
+&iomuxc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_hog>;
+ imx8qxp-lpddr4-arm2 {
+ pinctrl_hog: hoggrp {
+ fsl,pins = <
+ SC_P_ENET0_REFCLK_125M_25M_LSIO_GPIO5_IO09 0xc600004c
+ SC_P_COMP_CTL_GPIO_1V8_3V3_GPIORHB_PAD 0x000514a0
+ >;
+ };
+
+ pinctrl_adc0: adc0grp {
+ fsl,pins = <
+ SC_P_ADC_IN0_ADMA_ADC_IN0 0x60
+ SC_P_ADC_IN1_ADMA_ADC_IN1 0x60
+ >;
+ };
+
+ pinctrl_csi0_lpi2c0: csi0lpi2c0grp {
+ fsl,pins = <
+ SC_P_MIPI_CSI0_I2C0_SCL_MIPI_CSI0_I2C0_SCL 0xc2000020
+ SC_P_MIPI_CSI0_I2C0_SDA_MIPI_CSI0_I2C0_SDA 0xc2000020
+ >;
+ };
+
+ pinctrl_esai0: esai0grp {
+ fsl,pins = <
+ SC_P_ESAI0_FSR_ADMA_ESAI0_FSR 0xc6000040
+ SC_P_ESAI0_FST_ADMA_ESAI0_FST 0xc6000040
+ SC_P_ESAI0_SCKR_ADMA_ESAI0_SCKR 0xc6000040
+ SC_P_ESAI0_SCKT_ADMA_ESAI0_SCKT 0xc6000040
+ SC_P_ESAI0_TX0_ADMA_ESAI0_TX0 0xc6000040
+ SC_P_ESAI0_TX1_ADMA_ESAI0_TX1 0xc6000040
+ SC_P_ESAI0_TX2_RX3_ADMA_ESAI0_TX2_RX3 0xc6000040
+ SC_P_ESAI0_TX3_RX2_ADMA_ESAI0_TX3_RX2 0xc6000040
+ SC_P_ESAI0_TX4_RX1_ADMA_ESAI0_TX4_RX1 0xc6000040
+ SC_P_ESAI0_TX5_RX0_ADMA_ESAI0_TX5_RX0 0xc6000040
+ SC_P_MCLK_OUT0_ADMA_ACM_MCLK_OUT0 0xc6000040
+ >;
+ };
+
+ pinctrl_fec1: fec1grp {
+ fsl,pins = <
+ SC_P_COMP_CTL_GPIO_1V8_3V3_ENET_ENETB0_PAD 0x000014a0
+ SC_P_COMP_CTL_GPIO_1V8_3V3_ENET_ENETB1_PAD 0x000014a0
+ SC_P_ENET0_MDC_CONN_ENET0_MDC 0x06000020
+ SC_P_ENET0_MDIO_CONN_ENET0_MDIO 0x06000020
+ SC_P_ENET0_RGMII_TX_CTL_CONN_ENET0_RGMII_TX_CTL 0x00000060
+ SC_P_ENET0_RGMII_TXC_CONN_ENET0_RGMII_TXC 0x00000060
+ SC_P_ENET0_RGMII_TXD0_CONN_ENET0_RGMII_TXD0 0x00000060
+ SC_P_ENET0_RGMII_TXD1_CONN_ENET0_RGMII_TXD1 0x00000060
+ SC_P_ENET0_RGMII_TXD2_CONN_ENET0_RGMII_TXD2 0x00000060
+ SC_P_ENET0_RGMII_TXD3_CONN_ENET0_RGMII_TXD3 0x00000060
+ SC_P_ENET0_RGMII_RXC_CONN_ENET0_RGMII_RXC 0x00000060
+ SC_P_ENET0_RGMII_RX_CTL_CONN_ENET0_RGMII_RX_CTL 0x00000060
+ SC_P_ENET0_RGMII_RXD0_CONN_ENET0_RGMII_RXD0 0x00000060
+ SC_P_ENET0_RGMII_RXD1_CONN_ENET0_RGMII_RXD1 0x00000060
+ SC_P_ENET0_RGMII_RXD2_CONN_ENET0_RGMII_RXD2 0x00000060
+ SC_P_ENET0_RGMII_RXD3_CONN_ENET0_RGMII_RXD3 0x00000060
+ >;
+ };
+
+ pinctrl_fec2: fec2grp {
+ fsl,pins = <
+ SC_P_ESAI0_SCKR_CONN_ENET1_RGMII_TX_CTL 0x00000060
+ SC_P_ESAI0_FSR_CONN_ENET1_RGMII_TXC 0x00000060
+ SC_P_ESAI0_TX4_RX1_CONN_ENET1_RGMII_TXD0 0x00000060
+ SC_P_ESAI0_TX5_RX0_CONN_ENET1_RGMII_TXD1 0x00000060
+ SC_P_ESAI0_FST_CONN_ENET1_RGMII_TXD2 0x00000060
+ SC_P_ESAI0_SCKT_CONN_ENET1_RGMII_TXD3 0x00000060
+ SC_P_ESAI0_TX0_CONN_ENET1_RGMII_RXC 0x00000060
+ SC_P_SPDIF0_TX_CONN_ENET1_RGMII_RX_CTL 0x00000060
+ SC_P_SPDIF0_RX_CONN_ENET1_RGMII_RXD0 0x00000060
+ SC_P_ESAI0_TX3_RX2_CONN_ENET1_RGMII_RXD1 0x00000060
+ SC_P_ESAI0_TX2_RX3_CONN_ENET1_RGMII_RXD2 0x00000060
+ SC_P_ESAI0_TX1_CONN_ENET1_RGMII_RXD3 0x00000060
+ >;
+ };
+
+ pinctrl_flexcan1: flexcan0grp {
+ fsl,pins = <
+ SC_P_FLEXCAN0_TX_ADMA_FLEXCAN0_TX 0x21
+ SC_P_FLEXCAN0_RX_ADMA_FLEXCAN0_RX 0x21
+ >;
+ };
+
+ pinctrl_flexcan2: flexcan1grp {
+ fsl,pins = <
+ SC_P_FLEXCAN1_TX_ADMA_FLEXCAN1_TX 0x21
+ SC_P_FLEXCAN1_RX_ADMA_FLEXCAN1_RX 0x21
+ >;
+ };
+
+ pinctrl_flexcan3: flexcan2grp {
+ fsl,pins = <
+ SC_P_FLEXCAN2_TX_ADMA_FLEXCAN2_TX 0x21
+ SC_P_FLEXCAN2_RX_ADMA_FLEXCAN2_RX 0x21
+ >;
+ };
+
+ pinctrl_i2c0_mipi_lvds0: mipi_lvds0_i2c0_grp {
+ fsl,pins = <
+ SC_P_MIPI_DSI0_I2C0_SCL_MIPI_DSI0_I2C0_SCL 0xc6000020
+ SC_P_MIPI_DSI0_I2C0_SDA_MIPI_DSI0_I2C0_SDA 0xc6000020
+ >;
+ };
+
+ pinctrl_i2c0_mipi_lvds1: mipi_lvds1_i2c0_grp {
+ fsl,pins = <
+ SC_P_MIPI_DSI1_I2C0_SCL_MIPI_DSI1_I2C0_SCL 0xc6000020
+ SC_P_MIPI_DSI1_I2C0_SDA_MIPI_DSI1_I2C0_SDA 0xc6000020
+ >;
+ };
+
+ pinctrl_ptn5150: ptn5150 {
+ fsl,pins = <
+ SC_P_SPI0_CS1_LSIO_GPIO1_IO07 0x00000021
+ >;
+ };
+
+ pinctrl_flexspi0: flexspi0grp {
+ fsl,pins = <
+ SC_P_QSPI0A_DATA0_LSIO_QSPI0A_DATA0 0x06000021
+ SC_P_QSPI0A_DATA1_LSIO_QSPI0A_DATA1 0x06000021
+ SC_P_QSPI0A_DATA2_LSIO_QSPI0A_DATA2 0x06000021
+ SC_P_QSPI0A_DATA3_LSIO_QSPI0A_DATA3 0x06000021
+ SC_P_QSPI0A_DQS_LSIO_QSPI0A_DQS 0x06000021
+ SC_P_QSPI0A_SS0_B_LSIO_QSPI0A_SS0_B 0x06000021
+ SC_P_QSPI0A_SS1_B_LSIO_QSPI0A_SS1_B 0x06000021
+ SC_P_QSPI0A_SCLK_LSIO_QSPI0A_SCLK 0x06000021
+ SC_P_QSPI0B_SCLK_LSIO_QSPI0B_SCLK 0x06000021
+ SC_P_QSPI0B_DATA0_LSIO_QSPI0B_DATA0 0x06000021
+ SC_P_QSPI0B_DATA1_LSIO_QSPI0B_DATA1 0x06000021
+ SC_P_QSPI0B_DATA2_LSIO_QSPI0B_DATA2 0x06000021
+ SC_P_QSPI0B_DATA3_LSIO_QSPI0B_DATA3 0x06000021
+ SC_P_QSPI0B_DQS_LSIO_QSPI0B_DQS 0x06000021
+ SC_P_QSPI0B_SS0_B_LSIO_QSPI0B_SS0_B 0x06000021
+ SC_P_QSPI0B_SS1_B_LSIO_QSPI0B_SS1_B 0x06000021
+ >;
+ };
+
+ pinctrl_lpi2c1: lpi1cgrp {
+ fsl,pins = <
+ SC_P_USB_SS3_TC1_ADMA_I2C1_SCL 0x06000021
+ SC_P_USB_SS3_TC3_ADMA_I2C1_SDA 0x06000021
+ >;
+ };
+
+ pinctrl_lpi2c3: lpi2cgrp {
+ fsl,pins = <
+ SC_P_SPI3_CS1_ADMA_I2C3_SCL 0x06000020
+ SC_P_MCLK_IN1_ADMA_I2C3_SDA 0x06000020
+ >;
+ };
+
+ pinctrl_lpuart0: lpuart0grp {
+ fsl,pins = <
+ SC_P_UART0_RX_ADMA_UART0_RX 0x0600002c
+ SC_P_UART0_TX_ADMA_UART0_TX 0x0600002c
+ >;
+ };
+
+ pinctrl_lpuart1: lpuart1grp {
+ fsl,pins = <
+ SC_P_UART1_TX_ADMA_UART1_TX 0x0600002c
+ SC_P_UART1_RX_ADMA_UART1_RX 0x0600002c
+ SC_P_UART1_RTS_B_ADMA_UART1_RTS_B 0x0600002c
+ SC_P_UART1_CTS_B_ADMA_UART1_CTS_B 0x0600002c
+ >;
+ };
+
+ pinctrl_lpuart3: lpuart3grp {
+ fsl,pins = <
+ SC_P_FLEXCAN2_RX_ADMA_UART3_RX 0x0600002c
+ SC_P_FLEXCAN2_TX_ADMA_UART3_TX 0x0600002c
+ >;
+ };
+
+ pinctrl_mlb: mlbgrp {
+ fsl,pins = <
+ SC_P_ESAI0_SCKT_CONN_MLB_SIG 0x21
+ SC_P_ESAI0_FST_CONN_MLB_CLK 0x21
+ SC_P_ESAI0_TX0_CONN_MLB_DATA 0x21
+ >;
+ };
+
+ pinctrl_usdhc1: usdhc1grp {
+ fsl,pins = <
+ SC_P_EMMC0_CLK_CONN_EMMC0_CLK 0x06000041
+ SC_P_EMMC0_CMD_CONN_EMMC0_CMD 0x00000021
+ SC_P_EMMC0_DATA0_CONN_EMMC0_DATA0 0x00000021
+ SC_P_EMMC0_DATA1_CONN_EMMC0_DATA1 0x00000021
+ SC_P_EMMC0_DATA2_CONN_EMMC0_DATA2 0x00000021
+ SC_P_EMMC0_DATA3_CONN_EMMC0_DATA3 0x00000021
+ SC_P_EMMC0_DATA4_CONN_EMMC0_DATA4 0x00000021
+ SC_P_EMMC0_DATA5_CONN_EMMC0_DATA5 0x00000021
+ SC_P_EMMC0_DATA6_CONN_EMMC0_DATA6 0x00000021
+ SC_P_EMMC0_DATA7_CONN_EMMC0_DATA7 0x00000021
+ SC_P_EMMC0_STROBE_CONN_EMMC0_STROBE 0x00000041
+ SC_P_EMMC0_RESET_B_CONN_EMMC0_RESET_B 0x00000021
+ >;
+ };
+
+ pinctrl_usdhc1_100mhz: usdhc1grp100mhz {
+ fsl,pins = <
+ SC_P_EMMC0_CLK_CONN_EMMC0_CLK 0x06000040
+ SC_P_EMMC0_CMD_CONN_EMMC0_CMD 0x00000020
+ SC_P_EMMC0_DATA0_CONN_EMMC0_DATA0 0x00000020
+ SC_P_EMMC0_DATA1_CONN_EMMC0_DATA1 0x00000020
+ SC_P_EMMC0_DATA2_CONN_EMMC0_DATA2 0x00000020
+ SC_P_EMMC0_DATA3_CONN_EMMC0_DATA3 0x00000020
+ SC_P_EMMC0_DATA4_CONN_EMMC0_DATA4 0x00000020
+ SC_P_EMMC0_DATA5_CONN_EMMC0_DATA5 0x00000020
+ SC_P_EMMC0_DATA6_CONN_EMMC0_DATA6 0x00000020
+ SC_P_EMMC0_DATA7_CONN_EMMC0_DATA7 0x00000020
+ SC_P_EMMC0_STROBE_CONN_EMMC0_STROBE 0x00000040
+ SC_P_EMMC0_RESET_B_CONN_EMMC0_RESET_B 0x00000020
+ >;
+ };
+
+ pinctrl_usdhc1_200mhz: usdhc1grp200mhz {
+ fsl,pins = <
+ SC_P_EMMC0_CLK_CONN_EMMC0_CLK 0x06000040
+ SC_P_EMMC0_CMD_CONN_EMMC0_CMD 0x00000020
+ SC_P_EMMC0_DATA0_CONN_EMMC0_DATA0 0x00000020
+ SC_P_EMMC0_DATA1_CONN_EMMC0_DATA1 0x00000020
+ SC_P_EMMC0_DATA2_CONN_EMMC0_DATA2 0x00000020
+ SC_P_EMMC0_DATA3_CONN_EMMC0_DATA3 0x00000020
+ SC_P_EMMC0_DATA4_CONN_EMMC0_DATA4 0x00000020
+ SC_P_EMMC0_DATA5_CONN_EMMC0_DATA5 0x00000020
+ SC_P_EMMC0_DATA6_CONN_EMMC0_DATA6 0x00000020
+ SC_P_EMMC0_DATA7_CONN_EMMC0_DATA7 0x00000020
+ SC_P_EMMC0_STROBE_CONN_EMMC0_STROBE 0x00000040
+ SC_P_EMMC0_RESET_B_CONN_EMMC0_RESET_B 0x00000020
+ >;
+ };
+
+ pinctrl_usdhc2_gpio: usdhc2gpiogrp {
+ fsl,pins = <
+ SC_P_USDHC1_RESET_B_LSIO_GPIO4_IO19 0x00000021
+ SC_P_USDHC1_WP_LSIO_GPIO4_IO21 0x00000021
+ SC_P_USDHC1_CD_B_LSIO_GPIO4_IO22 0x00000021
+ >;
+ };
+
+ pinctrl_usdhc2: usdhc2grp {
+ fsl,pins = <
+ SC_P_USDHC1_CLK_CONN_USDHC1_CLK 0x06000041
+ SC_P_USDHC1_CMD_CONN_USDHC1_CMD 0x00000021
+ SC_P_USDHC1_DATA0_CONN_USDHC1_DATA0 0x00000021
+ SC_P_USDHC1_DATA1_CONN_USDHC1_DATA1 0x00000021
+ SC_P_USDHC1_DATA2_CONN_USDHC1_DATA2 0x00000021
+ SC_P_USDHC1_DATA3_CONN_USDHC1_DATA3 0x00000021
+ SC_P_USDHC1_VSELECT_CONN_USDHC1_VSELECT 0x00000021
+ >;
+ };
+
+ pinctrl_usdhc2_100mhz: usdhc2grp100mhz {
+ fsl,pins = <
+ SC_P_USDHC1_CLK_CONN_USDHC1_CLK 0x06000040
+ SC_P_USDHC1_CMD_CONN_USDHC1_CMD 0x00000020
+ SC_P_USDHC1_DATA0_CONN_USDHC1_DATA0 0x00000020
+ SC_P_USDHC1_DATA1_CONN_USDHC1_DATA1 0x00000020
+ SC_P_USDHC1_DATA2_CONN_USDHC1_DATA2 0x00000020
+ SC_P_USDHC1_DATA3_CONN_USDHC1_DATA3 0x00000020
+ SC_P_USDHC1_VSELECT_CONN_USDHC1_VSELECT 0x00000020
+ >;
+ };
+
+ pinctrl_usdhc2_200mhz: usdhc2grp200mhz {
+ fsl,pins = <
+ SC_P_USDHC1_CLK_CONN_USDHC1_CLK 0x06000040
+ SC_P_USDHC1_CMD_CONN_USDHC1_CMD 0x00000020
+ SC_P_USDHC1_DATA0_CONN_USDHC1_DATA0 0x00000020
+ SC_P_USDHC1_DATA1_CONN_USDHC1_DATA1 0x00000020
+ SC_P_USDHC1_DATA2_CONN_USDHC1_DATA2 0x00000020
+ SC_P_USDHC1_DATA3_CONN_USDHC1_DATA3 0x00000020
+ SC_P_USDHC1_VSELECT_CONN_USDHC1_VSELECT 0x00000020
+ >;
+ };
+
+ pinctrl_pcieb: pciebgrp{
+ fsl,pins = <
+ SC_P_PCIE_CTRL0_PERST_B_LSIO_GPIO4_IO00 0x06000021
+ SC_P_PCIE_CTRL0_CLKREQ_B_LSIO_GPIO4_IO01 0x06000021
+ SC_P_PCIE_CTRL0_WAKE_B_LSIO_GPIO4_IO02 0x04000021
+ >;
+ };
+
+ pinctrl_usbotg1: usbotg1 {
+ fsl,pins = <
+ SC_P_USB_SS3_TC0_CONN_USB_OTG1_PWR 0x00000021
+ >;
+ };
+
+ pinctrl_mipi_csi0_gpio: mipicsi0gpiogrp{
+ fsl,pins = <
+ SC_P_MIPI_CSI0_GPIO0_00_MIPI_CSI0_GPIO0_IO00 0x00000021
+ SC_P_MIPI_CSI0_GPIO0_01_MIPI_CSI0_GPIO0_IO01 0x00000021
+ >;
+ };
+ };
+};
+
+&fec1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_fec1>;
+ phy-mode = "rgmii-txid";
+ phy-handle = <&ethphy0>;
+ fsl,magic-packet;
+ fsl,rgmii_rxc_dly;
+ status = "okay";
+
+ mdio {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ethphy0: ethernet-phy@0 {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <0>;
+ at803x,eee-disabled;
+ at803x,vddio-1p8v;
+ };
+
+ ethphy1: ethernet-phy@1 {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <1>;
+ at803x,eee-disabled;
+ at803x,vddio-1p8v;
+ status = "disabled";
+ };
+ };
+};
+
+&fec2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_fec2>;
+ phy-mode = "rgmii-txid";
+ phy-handle = <&ethphy1>;
+ phy-supply = <&reg_fec2_supply>;
+ fsl,magic-packet;
+ fsl,rgmii_rxc_dly;
+ status = "disabled";
+};
+
+&flexcan1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_flexcan1>;
+ xceiver-supply = <&reg_can_stby>;
+ status = "okay";
+};
+
+&flexcan2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_flexcan2>;
+ xceiver-supply = <&reg_can_stby>;
+ status = "okay";
+};
+
+&flexcan3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_flexcan3>;
+ xceiver-supply = <&reg_can_stby>;
+ status = "okay";
+};
+
+&mipi_csi_0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ virtual-channel;
+ status = "okay";
+
+ /* Camera 0 MIPI CSI-2 (CSIS0) */
+ port@0 {
+ reg = <0>;
+ mipi_csi0_ep: endpoint {
+ remote-endpoint = <&max9286_0_ep>;
+ data-lanes = <1 2 3 4>;
+ };
+ };
+};
+
+&gpio0_mipi_csi0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_mipi_csi0_gpio>;
+};
+
+&isi_0 {
+ status = "okay";
+};
+
+&isi_1 {
+ status = "okay";
+};
+
+&isi_2 {
+ status = "okay";
+};
+
+&isi_3 {
+ status = "okay";
+};
+
+&flexspi0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_flexspi0>;
+ status = "okay";
+
+ flash0: mt35xu512aba@0 {
+ reg = <0>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "micron,mt35xu512aba";
+ spi-max-frequency = <133000000>;
+ spi-nor,ddr-quad-read-dummy = <8>;
+ };
+};
+
+&i2c0_csi0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_csi0_lpi2c0>;
+ clock-frequency = <100000>;
+ status = "okay";
+
+ codec: cs42888@48 {
+ compatible = "cirrus,cs42888";
+ reg = <0x48>;
+ clocks = <&clk IMX8QXP_AUD_MCLKOUT0>;
+ clock-names = "mclk";
+ VA-supply = <&reg_audio>;
+ VD-supply = <&reg_audio>;
+ VLS-supply = <&reg_audio>;
+ VLC-supply = <&reg_audio>;
+ reset-gpio = <&pca9557_a 2 1>;
+ power-domains = <&pd_mclk_out0>;
+ status = "okay";
+ };
+
+ max9286_mipi@6A {
+ compatible = "maxim,max9286_mipi";
+ reg = <0x6A>;
+ clocks = <&clk IMX8QXP_CLK_DUMMY>;
+ clock-names = "capture_mclk";
+ mclk = <27000000>;
+ mclk_source = <0>;
+ pwn-gpios = <&gpio0_mipi_csi0 0 GPIO_ACTIVE_HIGH>;
+ virtual-channel;
+ status = "okay";
+ port {
+ max9286_0_ep: endpoint {
+ remote-endpoint = <&mipi_csi0_ep>;
+ data-lanes = <1 2 3 4>;
+ };
+ };
+ };
+};
+
+&i2c1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lpi2c1>;
+ status = "okay";
+
+ max7322: gpio@68 {
+ compatible = "maxim,max7322";
+ reg = <0x68>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ typec_ptn5150: typec@3d {
+ compatible = "nxp,ptn5150";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ptn5150>;
+ reg = <0x3d>;
+ connect-gpios = <&gpio1 7 GPIO_ACTIVE_HIGH>;
+ };
+};
+
+&i2c3 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lpi2c3>;
+ status = "okay";
+
+ pca9557_a: gpio@18 {
+ compatible = "nxp,pca9557";
+ reg = <0x18>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ pca9557_b: gpio@19 {
+ compatible = "nxp,pca9557";
+ reg = <0x19>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+};
+
+&pd_dma_lpuart0 {
+ debug_console;
+};
+
+&lpuart0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lpuart0>;
+ status = "okay";
+};
+
+&lpuart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lpuart1>;
+ status = "okay";
+};
+
+&lpuart3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lpuart3>;
+ status = "disabled";
+};
+
+&mlb {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_mlb>;
+ status = "disabled";
+};
+
+&usdhc1 {
+ pinctrl-names = "default", "state_100mhz", "state_200mhz";
+ pinctrl-0 = <&pinctrl_usdhc1>;
+ pinctrl-1 = <&pinctrl_usdhc1_100mhz>;
+ pinctrl-2 = <&pinctrl_usdhc1_200mhz>;
+ bus-width = <8>;
+ non-removable;
+ status = "okay";
+};
+
+&usdhc2 {
+ pinctrl-names = "default", "state_100mhz", "state_200mhz";
+ pinctrl-0 = <&pinctrl_usdhc2>, <&pinctrl_usdhc2_gpio>;
+ pinctrl-1 = <&pinctrl_usdhc2_100mhz>, <&pinctrl_usdhc2_gpio>;
+ pinctrl-2 = <&pinctrl_usdhc2_200mhz>, <&pinctrl_usdhc2_gpio>;
+ bus-width = <4>;
+ cd-gpios = <&gpio4 22 GPIO_ACTIVE_LOW>;
+ wp-gpios = <&gpio4 21 GPIO_ACTIVE_HIGH>;
+ vmmc-supply = <&reg_usdhc2_vmmc>;
+ status = "okay";
+};
+
+&gpu_3d0 {
+ status = "okay";
+};
+
+&imx8_gpu_ss {
+ status = "okay";
+};
+
+&usbotg1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usbotg1>;
+ srp-disable;
+ hnp-disable;
+ adp-disable;
+ power-polarity-active-high;
+ disable-over-current;
+ status = "okay";
+};
+
+&pixel_combiner {
+ status = "okay";
+};
+
+&prg1 {
+ status = "okay";
+};
+
+&prg2 {
+ status = "okay";
+};
+
+&prg3 {
+ status = "okay";
+};
+
+&prg4 {
+ status = "okay";
+};
+
+&prg5 {
+ status = "okay";
+};
+
+&prg6 {
+ status = "okay";
+};
+
+&prg7 {
+ status = "okay";
+};
+
+&prg8 {
+ status = "okay";
+};
+
+&prg9 {
+ status = "okay";
+};
+
+&dpr1_channel1 {
+ status = "okay";
+};
+
+&dpr1_channel2 {
+ status = "okay";
+};
+
+&dpr1_channel3 {
+ status = "okay";
+};
+
+&dpr2_channel1 {
+ status = "okay";
+};
+
+&dpr2_channel2 {
+ status = "okay";
+};
+
+&dpr2_channel3 {
+ status = "okay";
+};
+
+&dpu1 {
+ status = "okay";
+};
+
+&pcieb{
+ ext_osc = <1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pcieb>;
+ reset-gpio = <&gpio4 0 GPIO_ACTIVE_LOW>;
+ clkreq-gpio = <&gpio4 1 GPIO_ACTIVE_LOW>;
+ status = "okay";
+};
+
+&intmux_cm40 {
+ status = "okay";
+};
+
+&rpmsg{
+ /*
+ * 64K for one rpmsg instance:
+ */
+ vdev-nums = <1>;
+ reg = <0x0 0x90000000 0x0 0x10000>;
+ status = "okay";
+};
+
+&ldb1_phy {
+ status = "okay";
+};
+
+&ldb1 {
+ status = "okay";
+
+ lvds-channel@0 {
+ fsl,data-mapping = "jeida";
+ fsl,data-width = <24>;
+ status = "okay";
+
+ port@1 {
+ reg = <1>;
+
+ lvds0_out: endpoint {
+ remote-endpoint = <&it6263_0_in>;
+ };
+ };
+ };
+};
+
+&i2c0_mipi_lvds0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c0_mipi_lvds0>;
+ clock-frequency = <100000>;
+ status = "okay";
+
+ lvds-to-hdmi-bridge@4c {
+ compatible = "ite,it6263";
+ reg = <0x4c>;
+
+ port {
+ it6263_0_in: endpoint {
+ clock-lanes = <3>;
+ data-lanes = <0 1 2 4>;
+ remote-endpoint = <&lvds0_out>;
+ };
+ };
+ };
+};
+
+&ldb2_phy {
+ status = "okay";
+};
+
+&ldb2 {
+ status = "okay";
+
+ lvds-channel@0 {
+ fsl,data-mapping = "jeida";
+ fsl,data-width = <24>;
+ status = "okay";
+
+ port@1 {
+ reg = <1>;
+
+ lvds1_out: endpoint {
+ remote-endpoint = <&it6263_1_in>;
+ };
+ };
+ };
+};
+
+&i2c0_mipi_lvds1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c0_mipi_lvds1>;
+ clock-frequency = <100000>;
+ status = "okay";
+
+ lvds-to-hdmi-bridge@4c {
+ compatible = "ite,it6263";
+ reg = <0x4c>;
+
+ port {
+ it6263_1_in: endpoint {
+ clock-lanes = <3>;
+ data-lanes = <0 1 2 4>;
+ remote-endpoint = <&lvds1_out>;
+ };
+ };
+ };
+};
+
+&mipi_dsi_phy1 {
+ status = "okay";
+};
+
+&mipi_dsi1 {
+ status = "okay";
+};
+
+&mipi_dsi_bridge1 {
+ status = "okay";
+
+ port@1 {
+ mipi_dsi_bridge1_out: endpoint {
+ remote-endpoint = <&adv7535_1_in>;
+ };
+ };
+};
+
+&i2c0_mipi_lvds0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c0_mipi_lvds0>;
+ clock-frequency = <100000>;
+ status = "okay";
+
+ adv_bridge1: adv7535@3d {
+ compatible = "adi,adv7535", "adi,adv7533";
+ reg = <0x3d>;
+ adi,dsi-lanes = <4>;
+ adi,dsi-channel = <1>;
+ status = "okay";
+
+ port {
+ adv7535_1_in: endpoint {
+ remote-endpoint = <&mipi_dsi_bridge1_out>;
+ };
+ };
+ };
+};
+
+&mipi_dsi_phy2 {
+ status = "okay";
+};
+
+&mipi_dsi2 {
+ status = "okay";
+};
+
+&mipi_dsi_bridge2 {
+ status = "okay";
+
+ port@1 {
+ mipi_dsi_bridge2_out: endpoint {
+ remote-endpoint = <&adv7535_2_in>;
+ };
+ };
+};
+
+&i2c0_mipi_lvds1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c0_mipi_lvds1>;
+ clock-frequency = <100000>;
+ status = "okay";
+
+ adv_bridge2: adv7535@3d {
+ compatible = "adi,adv7535", "adi,adv7533";
+ reg = <0x3d>;
+ adi,dsi-lanes = <4>;
+ adi,dsi-channel = <1>;
+ status = "okay";
+
+ port {
+ adv7535_2_in: endpoint {
+ remote-endpoint = <&mipi_dsi_bridge2_out>;
+ };
+ };
+};
+ };
+
+&vpu_encoder {
+ status = "okay";
+};
diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index b05796578e7a..9c3d9ea7c035 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -22,9 +22,12 @@ CONFIG_CPUSETS=y
CONFIG_CGROUP_DEVICE=y
CONFIG_CGROUP_CPUACCT=y
CONFIG_CGROUP_PERF=y
+CONFIG_NAMESPACES=y
CONFIG_USER_NS=y
CONFIG_SCHED_AUTOGROUP=y
+CONFIG_RELAY=y
CONFIG_BLK_DEV_INITRD=y
+CONFIG_EXPERT=y
CONFIG_KALLSYMS_ALL=y
# CONFIG_COMPAT_BRK is not set
CONFIG_PROFILING=y
@@ -61,21 +64,24 @@ CONFIG_ARCH_VEXPRESS=y
CONFIG_ARCH_XGENE=y
CONFIG_ARCH_ZX=y
CONFIG_ARCH_ZYNQMP=y
+CONFIG_ARCH_FSL_IMX8QM=y
+CONFIG_ARCH_FSL_IMX8QP=y
+CONFIG_ARCH_FSL_IMX8QXP=y
+CONFIG_ARCH_FSL_IMX8MQ=y
+CONFIG_ARCH_FSL_IMX8MM=y
CONFIG_PCI=y
CONFIG_HOTPLUG_PCI_PCIE=y
CONFIG_PCI_IOV=y
CONFIG_HOTPLUG_PCI=y
CONFIG_HOTPLUG_PCI_ACPI=y
-CONFIG_PCI_LAYERSCAPE=y
+CONFIG_PCI_IMX6=y
CONFIG_PCI_HISI=y
-CONFIG_PCIE_QCOM=y
CONFIG_PCIE_KIRIN=y
-CONFIG_PCIE_ARMADA_8K=y
CONFIG_PCI_AARDVARK=y
CONFIG_PCIE_RCAR=y
-CONFIG_PCIE_ROCKCHIP=m
CONFIG_PCI_HOST_GENERIC=y
CONFIG_PCI_XGENE=y
+CONFIG_PCIE_ROCKCHIP=m
CONFIG_ARM64_VA_BITS_48=y
CONFIG_SCHED_MC=y
CONFIG_NUMA=y
@@ -89,12 +95,22 @@ CONFIG_CRASH_DUMP=y
CONFIG_XEN=y
# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
CONFIG_COMPAT=y
-CONFIG_HIBERNATION=y
+CONFIG_PM_DEBUG=y
+CONFIG_PM_TEST_SUSPEND=y
CONFIG_WQ_POWER_EFFICIENT_DEFAULT=y
CONFIG_ARM_CPUIDLE=y
CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_STAT=y
+CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
+CONFIG_CPU_FREQ_GOV_POWERSAVE=y
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
+CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y
+CONFIG_CPU_FREQ_GOV_INTERACTIVE=y
CONFIG_CPUFREQ_DT=y
CONFIG_ARM_BIG_LITTLE_CPUFREQ=y
+CONFIG_ARM_IMX8_CPUFREQ=y
+CONFIG_ARM_IMX8MQ_CPUFREQ=y
CONFIG_ARM_SCPI_CPUFREQ=y
CONFIG_ACPI_CPPC_CPUFREQ=m
CONFIG_NET=y
@@ -105,7 +121,10 @@ CONFIG_IP_MULTICAST=y
CONFIG_IP_PNP=y
CONFIG_IP_PNP_DHCP=y
CONFIG_IP_PNP_BOOTP=y
-CONFIG_IPV6=m
+CONFIG_INET6_XFRM_MODE_TRANSPORT=m
+CONFIG_INET6_XFRM_MODE_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_BEET=m
+CONFIG_IPV6_SIT=m
CONFIG_NETFILTER=y
CONFIG_NF_CONNTRACK=m
CONFIG_NF_CONNTRACK_EVENTS=y
@@ -132,35 +151,65 @@ CONFIG_BRIDGE_VLAN_FILTERING=y
CONFIG_VLAN_8021Q=m
CONFIG_VLAN_8021Q_GVRP=y
CONFIG_VLAN_8021Q_MVRP=y
+CONFIG_LLC2=y
CONFIG_BPF_JIT=y
-CONFIG_BT=m
-CONFIG_BT_HIDP=m
+CONFIG_CAN=y
+CONFIG_CAN_FLEXCAN=y
+CONFIG_BT=y
+CONFIG_BT_RFCOMM=y
+CONFIG_BT_RFCOMM_TTY=y
+CONFIG_BT_BNEP=y
+CONFIG_BT_BNEP_MC_FILTER=y
+CONFIG_BT_BNEP_PROTO_FILTER=y
+CONFIG_BT_HIDP=y
# CONFIG_BT_HS is not set
# CONFIG_BT_LE is not set
CONFIG_BT_LEDS=y
-# CONFIG_BT_DEBUGFS is not set
-CONFIG_BT_HCIUART=m
-CONFIG_BT_HCIUART_LL=y
-CONFIG_CFG80211=m
-CONFIG_MAC80211=m
+CONFIG_BT_HCIUART=y
+CONFIG_BT_HCIUART_BCSP=y
+CONFIG_BT_HCIUART_ATH3K=y
+CONFIG_BT_HCIUART_3WIRE=y
+CONFIG_BT_HCIUART_BCM=y
+CONFIG_BT_HCIUART_QCA=y
+CONFIG_BT_HCIVHCI=y
+CONFIG_CFG80211=y
+CONFIG_NL80211_TESTMODE=y
+CONFIG_CFG80211_INTERNAL_REGDB=y
+CONFIG_CFG80211_WEXT=y
+CONFIG_MAC80211=y
CONFIG_MAC80211_LEDS=y
-CONFIG_RFKILL=m
CONFIG_NET_9P=y
CONFIG_NET_9P_VIRTIO=y
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
CONFIG_DEVTMPFS=y
CONFIG_DEVTMPFS_MOUNT=y
CONFIG_DMA_CMA=y
+CONFIG_CMA_SIZE_MBYTES=320
+CONFIG_ARM_CCI400_PMU=y
+CONFIG_ARM_CCI5xx_PMU=y
CONFIG_MTD=y
+CONFIG_MTD_CMDLINE_PARTS=y
CONFIG_MTD_BLOCK=y
+CONFIG_MTD_RAM=y
+CONFIG_MTD_DATAFLASH=y
CONFIG_MTD_M25P80=y
+CONFIG_MTD_SLRAM=y
CONFIG_MTD_NAND=y
CONFIG_MTD_NAND_DENALI_DT=y
+CONFIG_MTD_NAND_GPMI_NAND=y
CONFIG_MTD_SPI_NOR=y
+# CONFIG_MTD_SPI_NOR_USE_4K_SECTORS is not set
+CONFIG_SPI_FSL_QUADSPI=y
+CONFIG_SPI_FSL_FLEXSPI=y
+CONFIG_MTD_UBI=y
+CONFIG_OF_OVERLAY=y
CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_NBD=m
+CONFIG_XEN_BLKDEV_BACKEND=y
CONFIG_VIRTIO_BLK=y
CONFIG_BLK_DEV_NVME=m
+CONFIG_SENSORS_FXOS8700=y
+CONFIG_SENSORS_FXAS2100X=y
CONFIG_SRAM=y
CONFIG_EEPROM_AT25=m
# CONFIG_SCSI_PROC_FS is not set
@@ -171,6 +220,7 @@ CONFIG_SCSI_HISI_SAS_PCI=y
CONFIG_ATA=y
CONFIG_SATA_AHCI=y
CONFIG_SATA_AHCI_PLATFORM=y
+CONFIG_AHCI_IMX=y
CONFIG_AHCI_CEVA=y
CONFIG_AHCI_MVEBU=y
CONFIG_AHCI_XGENE=y
@@ -202,10 +252,11 @@ CONFIG_SMC91X=y
CONFIG_SMSC911X=y
CONFIG_STMMAC_ETH=m
CONFIG_MDIO_BUS_MUX_MMIOREG=y
-CONFIG_AT803X_PHY=m
+CONFIG_AT803X_PHY=y
CONFIG_MARVELL_PHY=m
CONFIG_MESON_GXL_PHY=m
CONFIG_MICREL_PHY=y
+CONFIG_NXP_TJA110X_PHY=y
CONFIG_REALTEK_PHY=m
CONFIG_ROCKCHIP_PHY=y
CONFIG_USB_PEGASUS=m
@@ -218,16 +269,27 @@ CONFIG_USB_NET_SMSC75XX=m
CONFIG_USB_NET_SMSC95XX=m
CONFIG_USB_NET_PLUSB=m
CONFIG_USB_NET_MCS7830=m
+# CONFIG_WLAN_VENDOR_ATH is not set
CONFIG_BRCMFMAC=m
-CONFIG_WL18XX=m
-CONFIG_WLCORE_SDIO=m
+CONFIG_BRCMFMAC_PCIE=y
+CONFIG_HOSTAP=y
+CONFIG_RTL_CARDS=m
+# CONFIG_WLAN_VENDOR_TI is not set
+CONFIG_XEN_NETDEV_BACKEND=m
+CONFIG_IVSHMEM_NET=y
+CONFIG_INPUT_POLLDEV=y
CONFIG_INPUT_EVDEV=y
CONFIG_KEYBOARD_ADC=m
-CONFIG_KEYBOARD_CROS_EC=y
CONFIG_KEYBOARD_GPIO=y
+CONFIG_KEYBOARD_IMX_SC_PWRKEY=y
+CONFIG_KEYBOARD_CROS_EC=y
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_I2C=y
CONFIG_INPUT_MISC=y
CONFIG_INPUT_PM8941_PWRKEY=y
CONFIG_INPUT_HISI_POWERKEY=y
+CONFIG_INPUT_MPL3115=y
+CONFIG_INPUT_ISL29023=y
# CONFIG_SERIO_SERPORT is not set
CONFIG_SERIO_AMBAKMI=y
CONFIG_LEGACY_PTY_COUNT=16
@@ -247,6 +309,7 @@ CONFIG_SERIAL_MESON_CONSOLE=y
CONFIG_SERIAL_SAMSUNG=y
CONFIG_SERIAL_SAMSUNG_CONSOLE=y
CONFIG_SERIAL_TEGRA=y
+CONFIG_SERIAL_IMX_CONSOLE=y
CONFIG_SERIAL_SH_SCI=y
CONFIG_SERIAL_SH_SCI_NR_UARTS=11
CONFIG_SERIAL_SH_SCI_CONSOLE=y
@@ -254,16 +317,18 @@ CONFIG_SERIAL_MSM=y
CONFIG_SERIAL_MSM_CONSOLE=y
CONFIG_SERIAL_XILINX_PS_UART=y
CONFIG_SERIAL_XILINX_PS_UART_CONSOLE=y
+CONFIG_SERIAL_FSL_LPUART=y
+CONFIG_SERIAL_FSL_LPUART_CONSOLE=y
CONFIG_SERIAL_MVEBU_UART=y
CONFIG_SERIAL_DEV_BUS=y
CONFIG_SERIAL_DEV_CTRL_TTYPORT=y
CONFIG_VIRTIO_CONSOLE=y
CONFIG_I2C_CHARDEV=y
-CONFIG_I2C_MUX=y
CONFIG_I2C_MUX_PCA954x=y
CONFIG_I2C_BCM2835=m
CONFIG_I2C_DESIGNWARE_PLATFORM=y
CONFIG_I2C_IMX=y
+CONFIG_I2C_IMX_LPI2C=y
CONFIG_I2C_MESON=y
CONFIG_I2C_MV64XXX=y
CONFIG_I2C_PXA=y
@@ -274,31 +339,40 @@ CONFIG_I2C_TEGRA=y
CONFIG_I2C_UNIPHIER_F=y
CONFIG_I2C_RCAR=y
CONFIG_I2C_CROS_EC_TUNNEL=y
+CONFIG_XEN_I2C_BACKEND=y
+CONFIG_I2C_RPBUS=y
CONFIG_SPI=y
-CONFIG_SPI_MESON_SPICC=m
-CONFIG_SPI_MESON_SPIFC=m
CONFIG_SPI_BCM2835=m
CONFIG_SPI_BCM2835AUX=m
+CONFIG_SPI_FSL_LPSPI=y
+CONFIG_SPI_IMX=y
+CONFIG_SPI_MESON_SPICC=m
+CONFIG_SPI_MESON_SPIFC=m
CONFIG_SPI_ORION=y
CONFIG_SPI_PL022=y
-CONFIG_SPI_QUP=y
CONFIG_SPI_ROCKCHIP=y
+CONFIG_SPI_QUP=y
CONFIG_SPI_S3C64XX=y
-CONFIG_SPI_SPIDEV=m
+CONFIG_SPI_SPIDEV=y
+CONFIG_SPI_SLAVE=y
+CONFIG_SPI_SLAVE_TIME=y
+CONFIG_SPI_SLAVE_SYSTEM_CONTROL=y
CONFIG_SPMI=y
-CONFIG_PINCTRL_IPQ8074=y
CONFIG_PINCTRL_SINGLE=y
CONFIG_PINCTRL_MAX77620=y
+CONFIG_PINCTRL_IPQ8074=y
CONFIG_PINCTRL_MSM8916=y
CONFIG_PINCTRL_MSM8994=y
CONFIG_PINCTRL_MSM8996=y
CONFIG_PINCTRL_QDF2XXX=y
CONFIG_PINCTRL_QCOM_SPMI_PMIC=y
+CONFIG_GPIO_SYSFS=y
CONFIG_GPIO_DWAPB=y
CONFIG_GPIO_PL061=y
CONFIG_GPIO_RCAR=y
CONFIG_GPIO_XGENE=y
CONFIG_GPIO_XGENE_SB=y
+CONFIG_GPIO_MAX732X=y
CONFIG_GPIO_PCA953X=y
CONFIG_GPIO_PCA953X_IRQ=y
CONFIG_GPIO_MAX77620=y
@@ -312,14 +386,21 @@ CONFIG_BATTERY_BQ27XXX=y
CONFIG_SENSORS_ARM_SCPI=y
CONFIG_SENSORS_LM90=m
CONFIG_SENSORS_INA2XX=m
+# CONFIG_MXC_MMA8451 is not set
+CONFIG_THERMAL_WRITABLE_TRIPS=y
CONFIG_THERMAL_GOV_POWER_ALLOCATOR=y
CONFIG_CPU_THERMAL=y
CONFIG_THERMAL_EMULATION=y
-CONFIG_BRCMSTB_THERMAL=m
-CONFIG_EXYNOS_THERMAL=y
+CONFIG_IMX8M_THERMAL=y
+CONFIG_IMX8MM_THERMAL=y
+CONFIG_IMX_SC_THERMAL=y
+CONFIG_DEVICE_THERMAL=y
CONFIG_ROCKCHIP_THERMAL=m
+CONFIG_EXYNOS_THERMAL=y
CONFIG_WATCHDOG=y
CONFIG_S3C2410_WATCHDOG=y
+CONFIG_IMX2_WDT=y
+CONFIG_IMX8_WDT=y
CONFIG_MESON_GXBB_WATCHDOG=m
CONFIG_MESON_WATCHDOG=m
CONFIG_RENESAS_WDT=y
@@ -336,37 +417,51 @@ CONFIG_MFD_MAX77620=y
CONFIG_MFD_SPMI_PMIC=y
CONFIG_MFD_RK808=y
CONFIG_MFD_SEC_CORE=y
+CONFIG_MFD_BD71837=y
+CONFIG_REGULATOR_FIXED_VOLTAGE=y
CONFIG_REGULATOR_AXP20X=y
CONFIG_REGULATOR_FAN53555=y
-CONFIG_REGULATOR_FIXED_VOLTAGE=y
CONFIG_REGULATOR_GPIO=y
CONFIG_REGULATOR_HI6421V530=y
CONFIG_REGULATOR_HI655X=y
CONFIG_REGULATOR_MAX77620=y
+CONFIG_REGULATOR_PFUZE100=y
CONFIG_REGULATOR_PWM=y
CONFIG_REGULATOR_QCOM_SMD_RPM=y
CONFIG_REGULATOR_QCOM_SPMI=y
CONFIG_REGULATOR_RK808=y
CONFIG_REGULATOR_S2MPS11=y
-CONFIG_MEDIA_SUPPORT=m
+CONFIG_REGULATOR_BD71837=y
+CONFIG_RC_CORE=y
+CONFIG_RC_DEVICES=y
+CONFIG_IR_GPIO_CIR=y
+CONFIG_MEDIA_SUPPORT=y
CONFIG_MEDIA_CAMERA_SUPPORT=y
CONFIG_MEDIA_ANALOG_TV_SUPPORT=y
CONFIG_MEDIA_DIGITAL_TV_SUPPORT=y
+CONFIG_MEDIA_CEC_SUPPORT=y
CONFIG_MEDIA_CONTROLLER=y
-CONFIG_MEDIA_RC_SUPPORT=y
-CONFIG_RC_CORE=m
-CONFIG_RC_DEVICES=y
-CONFIG_RC_DECODERS=y
-CONFIG_IR_MESON=m
CONFIG_VIDEO_V4L2_SUBDEV_API=y
# CONFIG_DVB_NET is not set
+CONFIG_MEDIA_USB_SUPPORT=y
+CONFIG_USB_VIDEO_CLASS=m
+CONFIG_V4L_PLATFORM_DRIVERS=y
+CONFIG_VIDEO_MXC_CAPTURE=y
+CONFIG_VIDEO_MX8_CAPTURE=y
+CONFIG_GMSL_MAX9286=y
+CONFIG_VIDEO_MXC_CSI_CAMERA=y
+CONFIG_MXC_MIPI_CSI=y
+CONFIG_MXC_CAMERA_OV5640_MIPI_V2=y
CONFIG_V4L_MEM2MEM_DRIVERS=y
CONFIG_VIDEO_SAMSUNG_S5P_JPEG=m
CONFIG_VIDEO_SAMSUNG_S5P_MFC=m
CONFIG_VIDEO_SAMSUNG_EXYNOS_GSC=m
CONFIG_VIDEO_RENESAS_FCP=m
CONFIG_VIDEO_RENESAS_VSP1=m
-CONFIG_DRM=m
+CONFIG_IMX_DPU_CORE=y
+CONFIG_IMX_DCSS_CORE=y
+CONFIG_IMX_LCDIF_CORE=y
+CONFIG_DRM=y
CONFIG_DRM_NOUVEAU=m
CONFIG_DRM_EXYNOS=m
CONFIG_DRM_EXYNOS5433_DECON=y
@@ -384,16 +479,32 @@ CONFIG_ROCKCHIP_INNO_HDMI=y
CONFIG_DRM_RCAR_DU=m
CONFIG_DRM_RCAR_LVDS=y
CONFIG_DRM_RCAR_VSP=y
+CONFIG_DRM_MSM=m
CONFIG_DRM_TEGRA=m
-CONFIG_DRM_PANEL_SIMPLE=m
-CONFIG_DRM_I2C_ADV7511=m
+CONFIG_DRM_PANEL_SIMPLE=y
+CONFIG_DRM_PANEL_SEIKO_43WVF1G=y
+CONFIG_DRM_PANEL_RAYDIUM_RM67191=y
+CONFIG_DRM_NXP_SEIKO_43WVFIG=y
+CONFIG_DRM_I2C_ADV7511=y
+CONFIG_DRM_ITE_IT6263=y
+CONFIG_DRM_IMX_PARALLEL_DISPLAY=y
+CONFIG_DRM_IMX_TVE=y
+CONFIG_DRM_IMX_LDB=y
+CONFIG_DRM_IMX_HDMI=y
+CONFIG_DRM_IMX_NWL_DSI=y
+CONFIG_DRM_IMX_SEC_DSIM=y
+CONFIG_DRM_IMX_HDP=y
+CONFIG_IMX_HDP_CEC=y
CONFIG_DRM_VC4=m
CONFIG_DRM_HISI_KIRIN=m
+CONFIG_DRM_MXSFB=y
CONFIG_DRM_MESON=m
-CONFIG_FB=y
+CONFIG_FB_IMX64=y
+CONFIG_FB_IMX64_DEBUG=y
CONFIG_FB_ARMCLCD=y
+CONFIG_FB_MXC_DISP_FRAMEWORK=y
CONFIG_BACKLIGHT_GENERIC=m
-CONFIG_BACKLIGHT_PWM=m
+CONFIG_BACKLIGHT_PWM=y
CONFIG_BACKLIGHT_LP855X=m
CONFIG_FRAMEBUFFER_CONSOLE=y
CONFIG_LOGO=y
@@ -401,14 +512,44 @@ CONFIG_LOGO=y
# CONFIG_LOGO_LINUX_VGA16 is not set
CONFIG_SOUND=y
CONFIG_SND=y
+CONFIG_SND_USB_AUDIO=m
CONFIG_SND_SOC=y
CONFIG_SND_BCM2835_SOC_I2S=m
+CONFIG_SND_SOC_FSL_ACM=y
+CONFIG_SND_IMX_SOC=y
+CONFIG_SND_SOC_IMX_AK4458=y
+CONFIG_SND_SOC_IMX_AK5558=y
+CONFIG_SND_SOC_IMX_AK4497=y
+CONFIG_SND_SOC_IMX_WM8960=y
+CONFIG_SND_SOC_IMX_WM8524=y
+CONFIG_SND_SOC_IMX_CS42888=y
+CONFIG_SND_SOC_IMX_WM8962=y
+CONFIG_SND_SOC_IMX_MICFIL=y
+CONFIG_SND_SOC_IMX_RPMSG=y
+CONFIG_SND_SOC_IMX_MQS=y
+CONFIG_SND_SOC_IMX_SPDIF=y
+CONFIG_SND_SOC_IMX_AMIX=y
+CONFIG_SND_SOC_IMX_CDNHDMI=y
+CONFIG_SND_SOC_IMX_DSP=y
CONFIG_SND_SOC_SAMSUNG=y
-CONFIG_SND_SOC_RCAR=m
-CONFIG_SND_SOC_AK4613=m
+CONFIG_SND_SOC_RCAR=y
+CONFIG_SND_SOC_AK4613=y
CONFIG_SND_SIMPLE_CARD=y
+CONFIG_HID_A4TECH=y
+CONFIG_HID_APPLE=y
+CONFIG_HID_BELKIN=y
+CONFIG_HID_CHERRY=y
+CONFIG_HID_CHICONY=y
+CONFIG_HID_CYPRESS=y
+CONFIG_HID_EZKEY=y
+CONFIG_HID_KENSINGTON=y
+CONFIG_HID_LOGITECH=y
+CONFIG_HID_MICROSOFT=y
+CONFIG_HID_MONTEREY=y
+CONFIG_HID_MULTITOUCH=y
CONFIG_USB=y
CONFIG_USB_OTG=y
+CONFIG_USB_OTG_WHITELIST=y
CONFIG_USB_XHCI_HCD=y
CONFIG_USB_XHCI_TEGRA=y
CONFIG_USB_EHCI_HCD=y
@@ -418,7 +559,9 @@ CONFIG_USB_EHCI_HCD_PLATFORM=y
CONFIG_USB_OHCI_HCD=y
CONFIG_USB_OHCI_EXYNOS=y
CONFIG_USB_OHCI_HCD_PLATFORM=y
+CONFIG_USB_HCD_TEST_MODE=y
CONFIG_USB_RENESAS_USBHS=m
+CONFIG_USB_ACM=m
CONFIG_USB_STORAGE=y
CONFIG_USB_DWC3=y
CONFIG_USB_DWC2=y
@@ -426,13 +569,46 @@ CONFIG_USB_CHIPIDEA=y
CONFIG_USB_CHIPIDEA_UDC=y
CONFIG_USB_CHIPIDEA_HOST=y
CONFIG_USB_ISP1760=y
+CONFIG_USB_ISP1760_HOST_ROLE=y
+CONFIG_USB_CDNS3=y
+CONFIG_USB_CDNS3_GADGET=y
+CONFIG_USB_CDNS3_HOST=y
+CONFIG_USB_TEST=m
+CONFIG_USB_EHSET_TEST_FIXTURE=y
CONFIG_USB_HSIC_USB3503=y
CONFIG_NOP_USB_XCEIV=y
-CONFIG_USB_MSM_OTG=y
+CONFIG_USB_GPIO_VBUS=y
CONFIG_USB_QCOM_8X16_PHY=y
+CONFIG_USB_MXS_PHY=y
CONFIG_USB_ULPI=y
CONFIG_USB_GADGET=y
CONFIG_USB_RENESAS_USBHS_UDC=m
+CONFIG_USB_CONFIGFS=y
+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_FSL_UTP=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_USB_AUDIO=m
+CONFIG_GADGET_UAC1=y
+CONFIG_USB_ETH=m
+CONFIG_USB_ETH_EEM=y
+CONFIG_USB_G_NCM=m
+CONFIG_USB_MASS_STORAGE=m
+CONFIG_USB_G_SERIAL=m
+CONFIG_USB_CDC_COMPOSITE=m
CONFIG_MMC=y
CONFIG_MMC_BLOCK_MINORS=32
CONFIG_MMC_ARMMMCI=y
@@ -442,6 +618,7 @@ CONFIG_MMC_SDHCI_PLTFM=y
CONFIG_MMC_SDHCI_OF_ARASAN=y
CONFIG_MMC_SDHCI_OF_ESDHC=y
CONFIG_MMC_SDHCI_CADENCE=y
+CONFIG_MMC_SDHCI_ESDHC_IMX=y
CONFIG_MMC_SDHCI_TEGRA=y
CONFIG_MMC_MESON_GX=y
CONFIG_MMC_SDHCI_MSM=y
@@ -454,6 +631,9 @@ CONFIG_MMC_DW_ROCKCHIP=y
CONFIG_MMC_SUNXI=y
CONFIG_MMC_BCM2835=y
CONFIG_MMC_SDHCI_XENON=y
+CONFIG_MXC_MLB150=y
+CONFIG_MXC_SIM=y
+CONFIG_MXC_EMVSIM=y
CONFIG_NEW_LEDS=y
CONFIG_LEDS_CLASS=y
CONFIG_LEDS_GPIO=y
@@ -471,26 +651,36 @@ CONFIG_RTC_DRV_DS3232=y
CONFIG_RTC_DRV_EFI=y
CONFIG_RTC_DRV_S3C=y
CONFIG_RTC_DRV_PL031=y
-CONFIG_RTC_DRV_SUN6I=y
CONFIG_RTC_DRV_TEGRA=y
+CONFIG_RTC_DRV_SNVS=y
+CONFIG_RTC_DRV_IMX_SC=y
CONFIG_RTC_DRV_XGENE=y
CONFIG_DMADEVICES=y
CONFIG_DMA_BCM2835=m
+CONFIG_FSL_EDMA_V3=y
+CONFIG_IMX_SDMA=y
CONFIG_K3_DMA=y
CONFIG_MV_XOR_V2=y
+CONFIG_MXS_DMA=y
CONFIG_PL330_DMA=y
CONFIG_TEGRA20_APB_DMA=y
CONFIG_QCOM_BAM_DMA=y
CONFIG_QCOM_HIDMA_MGMT=y
CONFIG_QCOM_HIDMA=y
CONFIG_RCAR_DMAC=y
-CONFIG_VFIO=y
-CONFIG_VFIO_PCI=y
+CONFIG_UIO=y
+CONFIG_UIO_PCI_GENERIC=y
CONFIG_VIRTIO_PCI=y
CONFIG_VIRTIO_BALLOON=y
CONFIG_VIRTIO_MMIO=y
CONFIG_XEN_GNTDEV=y
CONFIG_XEN_GRANT_DEV_ALLOC=y
+CONFIG_STAGING=y
+CONFIG_ION=y
+CONFIG_ION_SYSTEM_HEAP=y
+CONFIG_ION_CMA_HEAP=y
+CONFIG_TYPEC_TCPM=y
+CONFIG_TYPEC_TCPCI=y
CONFIG_COMMON_CLK_RK808=y
CONFIG_COMMON_CLK_SCPI=y
CONFIG_COMMON_CLK_CS2000_CP=y
@@ -505,6 +695,7 @@ CONFIG_MSM_GCC_8994=y
CONFIG_MSM_MMCC_8996=y
CONFIG_HWSPINLOCK=y
CONFIG_HWSPINLOCK_QCOM=y
+CONFIG_CLKSRC_IMX_SYS_CNT=y
CONFIG_ARM_MHU=y
CONFIG_PLATFORM_MHU=y
CONFIG_BCM2835_MBOX=y
@@ -512,8 +703,10 @@ CONFIG_HI6220_MBOX=y
CONFIG_ROCKCHIP_IOMMU=y
CONFIG_ARM_SMMU=y
CONFIG_ARM_SMMU_V3=y
+CONFIG_RPMSG=y
CONFIG_RPMSG_QCOM_SMD=y
CONFIG_RASPBERRYPI_POWER=y
+CONFIG_ARCH_MXC_ARM64=y
CONFIG_QCOM_SMEM=y
CONFIG_QCOM_SMD_RPM=y
CONFIG_QCOM_SMP2P=y
@@ -522,27 +715,33 @@ CONFIG_ROCKCHIP_PM_DOMAINS=y
CONFIG_ARCH_TEGRA_132_SOC=y
CONFIG_ARCH_TEGRA_210_SOC=y
CONFIG_ARCH_TEGRA_186_SOC=y
-CONFIG_EXTCON_USB_GPIO=y
+CONFIG_EXTCON_PTN5150=y
CONFIG_IIO=y
CONFIG_EXYNOS_ADC=y
+CONFIG_IMX8QXP_ADC=y
CONFIG_ROCKCHIP_SARADC=m
CONFIG_PWM=y
CONFIG_PWM_BCM2835=m
CONFIG_PWM_CROS_EC=m
+CONFIG_PWM_FSL_FTM=y
+CONFIG_PWM_IMX=y
CONFIG_PWM_MESON=m
CONFIG_PWM_ROCKCHIP=y
CONFIG_PWM_SAMSUNG=y
CONFIG_PWM_TEGRA=m
-CONFIG_PHY_RCAR_GEN3_USB2=y
-CONFIG_PHY_HI6220_USB=y
+CONFIG_PHY_XGENE=y
CONFIG_PHY_SUN4I_USB=y
-CONFIG_PHY_ROCKCHIP_INNO_USB2=y
+CONFIG_PHY_HI6220_USB=y
+CONFIG_PHY_RCAR_GEN3_USB2=y
CONFIG_PHY_ROCKCHIP_EMMC=y
+CONFIG_PHY_ROCKCHIP_INNO_USB2=y
CONFIG_PHY_ROCKCHIP_PCIE=m
-CONFIG_PHY_XGENE=y
CONFIG_PHY_TEGRA_XUSB=y
CONFIG_QCOM_L2_PMU=y
CONFIG_QCOM_L3_PMU=y
+CONFIG_IMX8_DDR_PERF=y
+CONFIG_NVMEM_IMX_OCOTP=y
+CONFIG_NVMEM_IMX_SCU_OCOTP=y
CONFIG_TEE=y
CONFIG_OPTEE=y
CONFIG_ARM_SCPI_PROTOCOL=y
@@ -566,8 +765,9 @@ CONFIG_CUSE=m
CONFIG_OVERLAY_FS=m
CONFIG_VFAT_FS=y
CONFIG_HUGETLBFS=y
-CONFIG_CONFIGFS_FS=y
CONFIG_EFIVAR_FS=y
+CONFIG_JFFS2_FS=y
+CONFIG_UBIFS_FS=y
CONFIG_SQUASHFS=y
CONFIG_NFS_FS=y
CONFIG_NFS_V4=y
@@ -580,30 +780,49 @@ CONFIG_NLS_ISO8859_1=y
CONFIG_VIRTUALIZATION=y
CONFIG_KVM=y
CONFIG_PRINTK_TIME=y
-CONFIG_DEBUG_INFO=y
CONFIG_DEBUG_FS=y
CONFIG_MAGIC_SYSRQ=y
-CONFIG_DEBUG_KERNEL=y
-CONFIG_LOCKUP_DETECTOR=y
# CONFIG_SCHED_DEBUG is not set
# CONFIG_DEBUG_PREEMPT is not set
# CONFIG_FTRACE is not set
CONFIG_MEMTEST=y
CONFIG_SECURITY=y
+CONFIG_CRYPTO_TEST=m
+CONFIG_CRYPTO_CHACHA20POLY1305=y
CONFIG_CRYPTO_ECHAINIV=y
+CONFIG_CRYPTO_CBC=y
+CONFIG_CRYPTO_CTS=y
+CONFIG_CRYPTO_LRW=y
+CONFIG_CRYPTO_XTS=y
+CONFIG_CRYPTO_MD4=y
+CONFIG_CRYPTO_MD5=y
+CONFIG_CRYPTO_RMD128=y
+CONFIG_CRYPTO_RMD160=y
+CONFIG_CRYPTO_RMD256=y
+CONFIG_CRYPTO_RMD320=y
+CONFIG_CRYPTO_SHA512=y
+CONFIG_CRYPTO_SHA3=y
+CONFIG_CRYPTO_TGR192=y
+CONFIG_CRYPTO_WP512=y
+CONFIG_CRYPTO_BLOWFISH=y
+CONFIG_CRYPTO_CAMELLIA=y
+CONFIG_CRYPTO_CAST5=y
+CONFIG_CRYPTO_CAST6=y
+CONFIG_CRYPTO_SERPENT=y
+CONFIG_CRYPTO_TWOFISH=y
CONFIG_CRYPTO_ANSI_CPRNG=y
+CONFIG_CRYPTO_DEV_FSL_CAAM=y
+CONFIG_CRYPTO_DEV_FSL_CAAM_SM=y
+CONFIG_CRYPTO_DEV_FSL_CAAM_SM_TEST=y
+CONFIG_CRYPTO_DEV_FSL_CAAM_SECVIO=y
CONFIG_ARM64_CRYPTO=y
-CONFIG_CRYPTO_SHA256_ARM64=m
CONFIG_CRYPTO_SHA512_ARM64=m
CONFIG_CRYPTO_SHA1_ARM64_CE=y
CONFIG_CRYPTO_SHA2_ARM64_CE=y
CONFIG_CRYPTO_GHASH_ARM64_CE=y
CONFIG_CRYPTO_CRCT10DIF_ARM64_CE=m
CONFIG_CRYPTO_CRC32_ARM64_CE=m
-CONFIG_CRYPTO_AES_ARM64=m
-CONFIG_CRYPTO_AES_ARM64_CE=m
CONFIG_CRYPTO_AES_ARM64_CE_CCM=y
CONFIG_CRYPTO_AES_ARM64_CE_BLK=y
-CONFIG_CRYPTO_AES_ARM64_NEON_BLK=m
CONFIG_CRYPTO_CHACHA20_NEON=m
CONFIG_CRYPTO_AES_ARM64_BS=m
diff --git a/arch/arm64/include/asm/tlbflush.h b/arch/arm64/include/asm/tlbflush.h
index 9e82dd79c7db..8c72efcb638e 100644
--- a/arch/arm64/include/asm/tlbflush.h
+++ b/arch/arm64/include/asm/tlbflush.h
@@ -24,6 +24,7 @@
#include <linux/sched.h>
#include <asm/cputype.h>
#include <asm/mmu.h>
+#include <soc/imx8/soc.h>
/*
* Raw TLBI operations.
@@ -120,8 +121,12 @@ static inline void flush_tlb_mm(struct mm_struct *mm)
unsigned long asid = ASID(mm) << 48;
dsb(ishst);
- __tlbi(aside1is, asid);
- __tlbi_user(aside1is, asid);
+ if (TKT340553_SW_WORKAROUND && ASID(mm) >> 11) {
+ __tlbi(vmalle1is);
+ } else {
+ __tlbi(aside1is, asid);
+ __tlbi_user(aside1is, asid);
+ }
dsb(ish);
}
@@ -131,8 +136,12 @@ static inline void flush_tlb_page(struct vm_area_struct *vma,
unsigned long addr = uaddr >> 12 | (ASID(vma->vm_mm) << 48);
dsb(ishst);
- __tlbi(vale1is, addr);
- __tlbi_user(vale1is, addr);
+ if (TKT340553_SW_WORKAROUND && (uaddr >> 36 || (ASID(vma->vm_mm) >> 12))) {
+ __tlbi(vmalle1is);
+ } else {
+ __tlbi(vale1is, addr);
+ __tlbi_user(vale1is, addr);
+ }
dsb(ish);
}
@@ -148,6 +157,7 @@ static inline void __flush_tlb_range(struct vm_area_struct *vma,
{
unsigned long asid = ASID(vma->vm_mm) << 48;
unsigned long addr;
+ unsigned long mask = (1 << 20) - 1;
if ((end - start) > MAX_TLB_RANGE) {
flush_tlb_mm(vma->vm_mm);
@@ -156,10 +166,14 @@ static inline void __flush_tlb_range(struct vm_area_struct *vma,
start = asid | (start >> 12);
end = asid | (end >> 12);
+ mask <<= 24;
+
dsb(ishst);
for (addr = start; addr < end; addr += 1 << (PAGE_SHIFT - 12)) {
- if (last_level) {
+ if (TKT340553_SW_WORKAROUND && (addr & mask || (ASID(vma->vm_mm) >> 12))) {
+ __tlbi(vmalle1is);
+ } else if (last_level) {
__tlbi(vale1is, addr);
__tlbi_user(vale1is, addr);
} else {
@@ -189,8 +203,12 @@ static inline void flush_tlb_kernel_range(unsigned long start, unsigned long end
end >>= 12;
dsb(ishst);
- for (addr = start; addr < end; addr += 1 << (PAGE_SHIFT - 12))
- __tlbi(vaae1is, addr);
+ for (addr = start; addr < end; addr += 1 << (PAGE_SHIFT - 12)) {
+ if (TKT340553_SW_WORKAROUND && addr >> 24)
+ __tlbi(vmalle1is);
+ else
+ __tlbi(vaae1is, addr);
+ }
dsb(ish);
isb();
}
@@ -204,8 +222,13 @@ static inline void __flush_tlb_pgtable(struct mm_struct *mm,
{
unsigned long addr = uaddr >> 12 | (ASID(mm) << 48);
- __tlbi(vae1is, addr);
- __tlbi_user(vae1is, addr);
+ if (TKT340553_SW_WORKAROUND && (uaddr >> 36 || (ASID(mm) >> 12))) {
+ __tlbi(vmalle1is);
+ } else {
+ __tlbi(vae1is, addr);
+ __tlbi_user(vae1is, addr);
+ }
+
dsb(ish);
}
diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c
index 56c110844c01..34b5a64dfd75 100644
--- a/arch/arm64/mm/dma-mapping.c
+++ b/arch/arm64/mm/dma-mapping.c
@@ -29,9 +29,14 @@
#include <linux/vmalloc.h>
#include <linux/swiotlb.h>
#include <linux/pci.h>
+#include <linux/of.h>
#include <asm/cacheflush.h>
+EXPORT_SYMBOL(__dma_map_area);
+EXPORT_SYMBOL(__dma_unmap_area);
+EXPORT_SYMBOL(__dma_flush_area);
+
static int swiotlb __ro_after_init;
static pgprot_t __get_dma_pgprot(unsigned long attrs, pgprot_t prot,
@@ -369,7 +374,23 @@ static int __swiotlb_dma_mapping_error(struct device *hwdev, dma_addr_t addr)
return 0;
}
-static const struct dma_map_ops swiotlb_dma_ops = {
+/*
+ * Some 64bit SoCs only support up to 32bit dma capability.
+ * Do quirk set here.
+ */
+static int __swiotlb_dma_supported_quirk(struct device *hwdev, u64 mask)
+{
+ if (mask > DMA_BIT_MASK(32)) {
+ pr_err("Can't support > 32 bit dma.\n");
+ return 0;
+ }
+
+ if (swiotlb)
+ return swiotlb_dma_supported(hwdev, mask);
+ return 1;
+}
+
+static struct dma_map_ops swiotlb_dma_ops = {
.alloc = __dma_alloc,
.free = __dma_free,
.mmap = __swiotlb_mmap,
@@ -863,7 +884,7 @@ static void __iommu_unmap_sg_attrs(struct device *dev,
iommu_dma_unmap_sg(dev, sgl, nelems, dir, attrs);
}
-static const struct dma_map_ops iommu_dma_ops = {
+static struct dma_map_ops iommu_dma_ops = {
.alloc = __iommu_alloc_attrs,
.free = __iommu_free_attrs,
.mmap = __iommu_mmap_attrs,
@@ -923,6 +944,15 @@ void arch_teardown_dma_ops(struct device *dev)
dev->dma_ops = NULL;
}
+static int iommu_dma_supported_quirk(struct device *dev, u64 mask)
+{
+ if (mask > DMA_BIT_MASK(32)) {
+ pr_err("Can't support > 32 bit dma.\n");
+ return 0;
+ }
+
+ return 1;
+}
#else
static void __iommu_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
@@ -934,6 +964,9 @@ static void __iommu_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
const struct iommu_ops *iommu, bool coherent)
{
+ u32 mask32;
+ struct device_node *np;
+
if (!dev->dma_ops)
dev->dma_ops = &swiotlb_dma_ops;
@@ -946,4 +979,16 @@ void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
dev->dma_ops = xen_dma_ops;
}
#endif
+
+ np = of_find_compatible_node(NULL, NULL, "dma-capability");
+ if (np == NULL)
+ return;
+ if (of_property_read_u32(np, "only-dma-mask32", &mask32))
+ mask32 = 0;
+ if (mask32) {
+ swiotlb_dma_ops.dma_supported = __swiotlb_dma_supported_quirk;
+#ifdef CONFIG_IOMMU_DMA
+ iommu_dma_ops.dma_supported = iommu_dma_supported_quirk;
+#endif
+ }
}
diff --git a/block/blk-core.c b/block/blk-core.c
index 4e04c79aa2c2..57d32555f191 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -1930,7 +1930,7 @@ out_unlock:
return BLK_QC_T_NONE;
}
-static void handle_bad_sector(struct bio *bio)
+static void handle_bad_sector(struct bio *bio, sector_t maxsector)
{
char b[BDEVNAME_SIZE];
@@ -1938,7 +1938,7 @@ static void handle_bad_sector(struct bio *bio)
printk(KERN_INFO "%s: rw=%d, want=%Lu, limit=%Lu\n",
bio_devname(bio, b), bio->bi_opf,
(unsigned long long)bio_end_sector(bio),
- (long long)get_capacity(bio->bi_disk));
+ (long long)maxsector);
}
#ifdef CONFIG_FAIL_MAKE_REQUEST
@@ -1976,67 +1976,74 @@ static inline bool should_fail_request(struct hd_struct *part,
#endif /* CONFIG_FAIL_MAKE_REQUEST */
+static inline bool bio_check_ro(struct bio *bio, struct hd_struct *part)
+{
+ if (part->policy && op_is_write(bio_op(bio))) {
+ char b[BDEVNAME_SIZE];
+
+ printk(KERN_ERR
+ "generic_make_request: Trying to write "
+ "to read-only block-device %s (partno %d)\n",
+ bio_devname(bio, b), part->partno);
+ return true;
+ }
+
+ return false;
+}
+
+/*
+ * Check whether this bio extends beyond the end of the device or partition.
+ * This may well happen - the kernel calls bread() without checking the size of
+ * the device, e.g., when mounting a file system.
+ */
+static inline int bio_check_eod(struct bio *bio, sector_t maxsector)
+{
+ unsigned int nr_sectors = bio_sectors(bio);
+
+ if (nr_sectors && maxsector &&
+ (nr_sectors > maxsector ||
+ bio->bi_iter.bi_sector > maxsector - nr_sectors)) {
+ handle_bad_sector(bio, maxsector);
+ return -EIO;
+ }
+ return 0;
+}
+
/*
* Remap block n of partition p to block n+start(p) of the disk.
*/
static inline int blk_partition_remap(struct bio *bio)
{
struct hd_struct *p;
- int ret = 0;
+ int ret = -EIO;
+
+ rcu_read_lock();
+ p = __disk_get_part(bio->bi_disk, bio->bi_partno);
+ if (unlikely(!p))
+ goto out;
+ if (unlikely(should_fail_request(p, bio->bi_iter.bi_size)))
+ goto out;
+ if (unlikely(bio_check_ro(bio, p)))
+ goto out;
/*
* Zone reset does not include bi_size so bio_sectors() is always 0.
* Include a test for the reset op code and perform the remap if needed.
*/
- if (!bio->bi_partno ||
- (!bio_sectors(bio) && bio_op(bio) != REQ_OP_ZONE_RESET))
- return 0;
-
- rcu_read_lock();
- p = __disk_get_part(bio->bi_disk, bio->bi_partno);
- if (likely(p && !should_fail_request(p, bio->bi_iter.bi_size))) {
+ if (bio_sectors(bio) || bio_op(bio) == REQ_OP_ZONE_RESET) {
+ if (bio_check_eod(bio, part_nr_sects_read(p)))
+ goto out;
bio->bi_iter.bi_sector += p->start_sect;
bio->bi_partno = 0;
trace_block_bio_remap(bio->bi_disk->queue, bio, part_devt(p),
- bio->bi_iter.bi_sector - p->start_sect);
- } else {
- printk("%s: fail for partition %d\n", __func__, bio->bi_partno);
- ret = -EIO;
+ bio->bi_iter.bi_sector - p->start_sect);
}
+ ret = 0;
+out:
rcu_read_unlock();
-
return ret;
}
-/*
- * Check whether this bio extends beyond the end of the device.
- */
-static inline int bio_check_eod(struct bio *bio, unsigned int nr_sectors)
-{
- sector_t maxsector;
-
- if (!nr_sectors)
- return 0;
-
- /* Test device or partition size, when known. */
- maxsector = get_capacity(bio->bi_disk);
- if (maxsector) {
- sector_t sector = bio->bi_iter.bi_sector;
-
- if (maxsector < nr_sectors || maxsector - nr_sectors < sector) {
- /*
- * This may well happen - the kernel calls bread()
- * without checking the size of the device, e.g., when
- * mounting a device.
- */
- handle_bad_sector(bio);
- return 1;
- }
- }
-
- return 0;
-}
-
static noinline_for_stack bool
generic_make_request_checks(struct bio *bio)
{
@@ -2047,9 +2054,6 @@ generic_make_request_checks(struct bio *bio)
might_sleep();
- if (bio_check_eod(bio, nr_sectors))
- goto end_io;
-
q = bio->bi_disk->queue;
if (unlikely(!q)) {
printk(KERN_ERR
@@ -2063,18 +2067,21 @@ generic_make_request_checks(struct bio *bio)
* For a REQ_NOWAIT based request, return -EOPNOTSUPP
* if queue is not a request based queue.
*/
-
if ((bio->bi_opf & REQ_NOWAIT) && !queue_is_rq_based(q))
goto not_supported;
if (should_fail_request(&bio->bi_disk->part0, bio->bi_iter.bi_size))
goto end_io;
- if (blk_partition_remap(bio))
- goto end_io;
-
- if (bio_check_eod(bio, nr_sectors))
- goto end_io;
+ if (bio->bi_partno) {
+ if (unlikely(blk_partition_remap(bio)))
+ goto end_io;
+ } else {
+ if (unlikely(bio_check_ro(bio, &bio->bi_disk->part0)))
+ goto end_io;
+ if (unlikely(bio_check_eod(bio, get_capacity(bio->bi_disk))))
+ goto end_io;
+ }
/*
* Filter flush bio's early so that make_request based
@@ -2259,6 +2266,40 @@ out:
EXPORT_SYMBOL(generic_make_request);
/**
+ * direct_make_request - hand a buffer directly to its device driver for I/O
+ * @bio: The bio describing the location in memory and on the device.
+ *
+ * This function behaves like generic_make_request(), but does not protect
+ * against recursion. Must only be used if the called driver is known
+ * to not call generic_make_request (or direct_make_request) again from
+ * its make_request function. (Calling direct_make_request again from
+ * a workqueue is perfectly fine as that doesn't recurse).
+ */
+blk_qc_t direct_make_request(struct bio *bio)
+{
+ struct request_queue *q = bio->bi_disk->queue;
+ bool nowait = bio->bi_opf & REQ_NOWAIT;
+ blk_qc_t ret;
+
+ if (!generic_make_request_checks(bio))
+ return BLK_QC_T_NONE;
+
+ if (unlikely(blk_queue_enter(q, nowait))) {
+ if (nowait && !blk_queue_dying(q))
+ bio->bi_status = BLK_STS_AGAIN;
+ else
+ bio->bi_status = BLK_STS_IOERR;
+ bio_endio(bio);
+ return BLK_QC_T_NONE;
+ }
+
+ ret = q->make_request_fn(q, bio);
+ blk_queue_exit(q);
+ return ret;
+}
+EXPORT_SYMBOL_GPL(direct_make_request);
+
+/**
* submit_bio - submit a bio to the block device layer for I/O
* @bio: The &struct bio which describes the I/O
*
@@ -2302,6 +2343,17 @@ blk_qc_t submit_bio(struct bio *bio)
}
EXPORT_SYMBOL(submit_bio);
+bool blk_poll(struct request_queue *q, blk_qc_t cookie)
+{
+ if (!q->poll_fn || !blk_qc_t_valid(cookie))
+ return false;
+
+ if (current->plug)
+ blk_flush_plug_list(current->plug, false);
+ return q->poll_fn(q, cookie);
+}
+EXPORT_SYMBOL_GPL(blk_poll);
+
/**
* blk_cloned_rq_check_limits - Helper function to check a cloned request
* for new the queue limits
@@ -2712,6 +2764,27 @@ struct request *blk_fetch_request(struct request_queue *q)
}
EXPORT_SYMBOL(blk_fetch_request);
+/*
+ * Steal bios from a request and add them to a bio list.
+ * The request must not have been partially completed before.
+ */
+void blk_steal_bios(struct bio_list *list, struct request *rq)
+{
+ if (rq->bio) {
+ if (list->tail)
+ list->tail->bi_next = rq->bio;
+ else
+ list->head = rq->bio;
+ list->tail = rq->biotail;
+
+ rq->bio = NULL;
+ rq->biotail = NULL;
+ }
+
+ rq->__data_len = 0;
+}
+EXPORT_SYMBOL_GPL(blk_steal_bios);
+
/**
* blk_update_request - Special helper function for request stacking drivers
* @req: the request being processed
diff --git a/block/blk-lib.c b/block/blk-lib.c
index 0bdc77888dc5..d1b9dd03da25 100644
--- a/block/blk-lib.c
+++ b/block/blk-lib.c
@@ -37,6 +37,9 @@ int __blkdev_issue_discard(struct block_device *bdev, sector_t sector,
if (!q)
return -ENXIO;
+ if (bdev_read_only(bdev))
+ return -EPERM;
+
if (flags & BLKDEV_DISCARD_SECURE) {
if (!blk_queue_secure_erase(q))
return -EOPNOTSUPP;
@@ -172,6 +175,9 @@ static int __blkdev_issue_write_same(struct block_device *bdev, sector_t sector,
if (!q)
return -ENXIO;
+ if (bdev_read_only(bdev))
+ return -EPERM;
+
bs_mask = (bdev_logical_block_size(bdev) >> 9) - 1;
if ((sector | nr_sects) & bs_mask)
return -EINVAL;
@@ -249,6 +255,9 @@ static int __blkdev_issue_write_zeroes(struct block_device *bdev,
if (!q)
return -ENXIO;
+ if (bdev_read_only(bdev))
+ return -EPERM;
+
/* Ensure that max_write_zeroes_sectors doesn't overflow bi_size */
max_write_zeroes_sectors = bdev_write_zeroes_sectors(bdev);
@@ -303,6 +312,9 @@ static int __blkdev_issue_zero_pages(struct block_device *bdev,
if (!q)
return -ENXIO;
+ if (bdev_read_only(bdev))
+ return -EPERM;
+
while (nr_sects != 0) {
bio = next_bio(bio, __blkdev_sectors_to_bio_pages(nr_sects),
gfp_mask);
diff --git a/block/blk-map.c b/block/blk-map.c
index e31be14da8ea..dcfb489a0c8d 100644
--- a/block/blk-map.c
+++ b/block/blk-map.c
@@ -206,6 +206,12 @@ int blk_rq_unmap_user(struct bio *bio)
}
EXPORT_SYMBOL(blk_rq_unmap_user);
+#ifdef CONFIG_AHCI_IMX
+extern void *sg_io_buffer_hack;
+#else
+#define sg_io_buffer_hack NULL
+#endif
+
/**
* blk_rq_map_kern - map kernel data to a request, for passthrough requests
* @q: request queue where request should be inserted
@@ -233,7 +239,14 @@ int blk_rq_map_kern(struct request_queue *q, struct request *rq, void *kbuf,
if (!len || !kbuf)
return -EINVAL;
- do_copy = !blk_rq_aligned(q, addr, len) || object_is_on_stack(kbuf);
+#ifdef CONFIG_AHCI_IMX
+ if (kbuf == sg_io_buffer_hack)
+ do_copy = 0;
+ else
+#endif
+ do_copy = !blk_rq_aligned(q, addr, len)
+ || object_is_on_stack(kbuf);
+
if (do_copy)
bio = bio_copy_kern(q, kbuf, len, gfp_mask, reading);
else
diff --git a/block/blk-mq-sysfs.c b/block/blk-mq-sysfs.c
index c97fafa1b206..de209d60a662 100644
--- a/block/blk-mq-sysfs.c
+++ b/block/blk-mq-sysfs.c
@@ -253,7 +253,7 @@ static int blk_mq_register_hctx(struct blk_mq_hw_ctx *hctx)
return ret;
}
-static void __blk_mq_unregister_dev(struct device *dev, struct request_queue *q)
+void blk_mq_unregister_dev(struct device *dev, struct request_queue *q)
{
struct blk_mq_hw_ctx *hctx;
int i;
@@ -270,13 +270,6 @@ static void __blk_mq_unregister_dev(struct device *dev, struct request_queue *q)
q->mq_sysfs_init_done = false;
}
-void blk_mq_unregister_dev(struct device *dev, struct request_queue *q)
-{
- mutex_lock(&q->sysfs_lock);
- __blk_mq_unregister_dev(dev, q);
- mutex_unlock(&q->sysfs_lock);
-}
-
void blk_mq_hctx_kobj_init(struct blk_mq_hw_ctx *hctx)
{
kobject_init(&hctx->kobj, &blk_mq_hw_ktype);
diff --git a/block/blk-mq.c b/block/blk-mq.c
index eac444804736..3875729f31c5 100644
--- a/block/blk-mq.c
+++ b/block/blk-mq.c
@@ -37,6 +37,7 @@
#include "blk-wbt.h"
#include "blk-mq-sched.h"
+static bool blk_mq_poll(struct request_queue *q, blk_qc_t cookie);
static void blk_mq_poll_stats_start(struct request_queue *q);
static void blk_mq_poll_stats_fn(struct blk_stat_callback *cb);
@@ -2449,6 +2450,8 @@ struct request_queue *blk_mq_init_allocated_queue(struct blk_mq_tag_set *set,
spin_lock_init(&q->requeue_lock);
blk_queue_make_request(q, blk_mq_make_request);
+ if (q->mq_ops->poll)
+ q->poll_fn = blk_mq_poll;
/*
* Do this after blk_queue_make_request() overrides it...
@@ -2926,20 +2929,14 @@ static bool __blk_mq_poll(struct blk_mq_hw_ctx *hctx, struct request *rq)
return false;
}
-bool blk_mq_poll(struct request_queue *q, blk_qc_t cookie)
+static bool blk_mq_poll(struct request_queue *q, blk_qc_t cookie)
{
struct blk_mq_hw_ctx *hctx;
- struct blk_plug *plug;
struct request *rq;
- if (!q->mq_ops || !q->mq_ops->poll || !blk_qc_t_valid(cookie) ||
- !test_bit(QUEUE_FLAG_POLL, &q->queue_flags))
+ if (!test_bit(QUEUE_FLAG_POLL, &q->queue_flags))
return false;
- plug = current->plug;
- if (plug)
- blk_flush_plug_list(plug, false);
-
hctx = q->queue_hw_ctx[blk_qc_t_to_queue_num(cookie)];
if (!blk_qc_t_is_internal(cookie))
rq = blk_mq_tag_to_rq(hctx->tags, blk_qc_t_to_tag(cookie));
@@ -2957,7 +2954,6 @@ bool blk_mq_poll(struct request_queue *q, blk_qc_t cookie)
return __blk_mq_poll(hctx, rq);
}
-EXPORT_SYMBOL_GPL(blk_mq_poll);
static int __init blk_mq_init(void)
{
diff --git a/block/blk-sysfs.c b/block/blk-sysfs.c
index 9caf96c2c108..dfc391df0ffe 100644
--- a/block/blk-sysfs.c
+++ b/block/blk-sysfs.c
@@ -859,6 +859,10 @@ struct kobj_type blk_queue_ktype = {
.release = blk_release_queue,
};
+/**
+ * blk_register_queue - register a block layer queue with sysfs
+ * @disk: Disk of which the request queue should be registered with sysfs.
+ */
int blk_register_queue(struct gendisk *disk)
{
int ret;
@@ -915,11 +919,12 @@ int blk_register_queue(struct gendisk *disk)
if (q->request_fn || (q->mq_ops && q->elevator)) {
ret = elv_register_queue(q);
if (ret) {
+ mutex_unlock(&q->sysfs_lock);
kobject_uevent(&q->kobj, KOBJ_REMOVE);
kobject_del(&q->kobj);
blk_trace_remove_sysfs(dev);
kobject_put(&dev->kobj);
- goto unlock;
+ return ret;
}
}
ret = 0;
@@ -927,7 +932,15 @@ unlock:
mutex_unlock(&q->sysfs_lock);
return ret;
}
+EXPORT_SYMBOL_GPL(blk_register_queue);
+/**
+ * blk_unregister_queue - counterpart of blk_register_queue()
+ * @disk: Disk of which the request queue should be unregistered from sysfs.
+ *
+ * Note: the caller is responsible for guaranteeing that this function is called
+ * after blk_register_queue() has finished.
+ */
void blk_unregister_queue(struct gendisk *disk)
{
struct request_queue *q = disk->queue;
@@ -935,21 +948,39 @@ void blk_unregister_queue(struct gendisk *disk)
if (WARN_ON(!q))
return;
- mutex_lock(&q->sysfs_lock);
- queue_flag_clear_unlocked(QUEUE_FLAG_REGISTERED, q);
- mutex_unlock(&q->sysfs_lock);
+ /* Return early if disk->queue was never registered. */
+ if (!test_bit(QUEUE_FLAG_REGISTERED, &q->queue_flags))
+ return;
- wbt_exit(q);
+ /*
+ * Since sysfs_remove_dir() prevents adding new directory entries
+ * before removal of existing entries starts, protect against
+ * concurrent elv_iosched_store() calls.
+ */
+ mutex_lock(&q->sysfs_lock);
+ spin_lock_irq(q->queue_lock);
+ queue_flag_clear(QUEUE_FLAG_REGISTERED, q);
+ spin_unlock_irq(q->queue_lock);
+ /*
+ * Remove the sysfs attributes before unregistering the queue data
+ * structures that can be modified through sysfs.
+ */
if (q->mq_ops)
blk_mq_unregister_dev(disk_to_dev(disk), q);
-
- if (q->request_fn || (q->mq_ops && q->elevator))
- elv_unregister_queue(q);
+ mutex_unlock(&q->sysfs_lock);
kobject_uevent(&q->kobj, KOBJ_REMOVE);
kobject_del(&q->kobj);
blk_trace_remove_sysfs(disk_to_dev(disk));
+
+ wbt_exit(q);
+
+ mutex_lock(&q->sysfs_lock);
+ if (q->request_fn || (q->mq_ops && q->elevator))
+ elv_unregister_queue(q);
+ mutex_unlock(&q->sysfs_lock);
+
kobject_put(&disk_to_dev(disk)->kobj);
}
diff --git a/block/blk-throttle.c b/block/blk-throttle.c
index a8cd7b3d9647..80862cf4734a 100644
--- a/block/blk-throttle.c
+++ b/block/blk-throttle.c
@@ -1512,10 +1512,20 @@ static struct cftype throtl_legacy_files[] = {
.seq_show = blkg_print_stat_bytes,
},
{
+ .name = "throttle.io_service_bytes_recursive",
+ .private = (unsigned long)&blkcg_policy_throtl,
+ .seq_show = blkg_print_stat_bytes_recursive,
+ },
+ {
.name = "throttle.io_serviced",
.private = (unsigned long)&blkcg_policy_throtl,
.seq_show = blkg_print_stat_ios,
},
+ {
+ .name = "throttle.io_serviced_recursive",
+ .private = (unsigned long)&blkcg_policy_throtl,
+ .seq_show = blkg_print_stat_ios_recursive,
+ },
{ } /* terminate */
};
diff --git a/block/blk.h b/block/blk.h
index b2c287c2c6a3..521ea46b6e96 100644
--- a/block/blk.h
+++ b/block/blk.h
@@ -204,6 +204,9 @@ static inline void elv_deactivate_rq(struct request_queue *q, struct request *rq
e->type->ops.sq.elevator_deactivate_req_fn(q, rq);
}
+int elv_register_queue(struct request_queue *q);
+void elv_unregister_queue(struct request_queue *q);
+
struct hd_struct *__disk_get_part(struct gendisk *disk, int partno);
#ifdef CONFIG_FAIL_IO_TIMEOUT
diff --git a/block/elevator.c b/block/elevator.c
index 8320d97240be..d39315efd510 100644
--- a/block/elevator.c
+++ b/block/elevator.c
@@ -859,6 +859,8 @@ int elv_register_queue(struct request_queue *q)
struct elevator_queue *e = q->elevator;
int error;
+ lockdep_assert_held(&q->sysfs_lock);
+
error = kobject_add(&e->kobj, &q->kobj, "%s", "iosched");
if (!error) {
struct elv_fs_entry *attr = e->type->elevator_attrs;
@@ -876,10 +878,11 @@ int elv_register_queue(struct request_queue *q)
}
return error;
}
-EXPORT_SYMBOL(elv_register_queue);
void elv_unregister_queue(struct request_queue *q)
{
+ lockdep_assert_held(&q->sysfs_lock);
+
if (q) {
struct elevator_queue *e = q->elevator;
@@ -890,7 +893,6 @@ void elv_unregister_queue(struct request_queue *q)
wbt_enable_default(q);
}
}
-EXPORT_SYMBOL(elv_unregister_queue);
int elv_register(struct elevator_type *e)
{
@@ -957,6 +959,8 @@ static int elevator_switch_mq(struct request_queue *q,
{
int ret;
+ lockdep_assert_held(&q->sysfs_lock);
+
blk_mq_freeze_queue(q);
if (q->elevator) {
@@ -1000,6 +1004,8 @@ static int elevator_switch(struct request_queue *q, struct elevator_type *new_e)
bool old_registered = false;
int err;
+ lockdep_assert_held(&q->sysfs_lock);
+
if (q->mq_ops)
return elevator_switch_mq(q, new_e);
diff --git a/block/genhd.c b/block/genhd.c
index 449ef56bba70..e3dff72f78ed 100644
--- a/block/genhd.c
+++ b/block/genhd.c
@@ -597,6 +597,11 @@ static void register_disk(struct device *parent, struct gendisk *disk)
*/
pm_runtime_set_memalloc_noio(ddev, true);
+ if (disk->flags & GENHD_FL_HIDDEN) {
+ dev_set_uevent_suppress(ddev, 0);
+ return;
+ }
+
disk->part0.holder_dir = kobject_create_and_add("holders", &ddev->kobj);
disk->slave_dir = kobject_create_and_add("slaves", &ddev->kobj);
@@ -628,21 +633,27 @@ exit:
while ((part = disk_part_iter_next(&piter)))
kobject_uevent(&part_to_dev(part)->kobj, KOBJ_ADD);
disk_part_iter_exit(&piter);
+
+ err = sysfs_create_link(&ddev->kobj,
+ &disk->queue->backing_dev_info->dev->kobj,
+ "bdi");
+ WARN_ON(err);
}
/**
- * device_add_disk - add partitioning information to kernel list
+ * __device_add_disk - add disk information to kernel list
* @parent: parent device for the disk
* @disk: per-device partitioning information
+ * @register_queue: register the queue if set to true
*
* This function registers the partitioning information in @disk
* with the kernel.
*
* FIXME: error handling
*/
-void device_add_disk(struct device *parent, struct gendisk *disk)
+static void __device_add_disk(struct device *parent, struct gendisk *disk,
+ bool register_queue)
{
- struct backing_dev_info *bdi;
dev_t devt;
int retval;
@@ -651,7 +662,8 @@ void device_add_disk(struct device *parent, struct gendisk *disk)
* parameters make sense.
*/
WARN_ON(disk->minors && !(disk->major || disk->first_minor));
- WARN_ON(!disk->minors && !(disk->flags & GENHD_FL_EXT_DEVT));
+ WARN_ON(!disk->minors &&
+ !(disk->flags & (GENHD_FL_EXT_DEVT | GENHD_FL_HIDDEN)));
disk->flags |= GENHD_FL_UP;
@@ -660,24 +672,29 @@ void device_add_disk(struct device *parent, struct gendisk *disk)
WARN_ON(1);
return;
}
- disk_to_dev(disk)->devt = devt;
-
- /* ->major and ->first_minor aren't supposed to be
- * dereferenced from here on, but set them just in case.
- */
disk->major = MAJOR(devt);
disk->first_minor = MINOR(devt);
disk_alloc_events(disk);
- /* Register BDI before referencing it from bdev */
- bdi = disk->queue->backing_dev_info;
- bdi_register_owner(bdi, disk_to_dev(disk));
-
- blk_register_region(disk_devt(disk), disk->minors, NULL,
- exact_match, exact_lock, disk);
+ if (disk->flags & GENHD_FL_HIDDEN) {
+ /*
+ * Don't let hidden disks show up in /proc/partitions,
+ * and don't bother scanning for partitions either.
+ */
+ disk->flags |= GENHD_FL_SUPPRESS_PARTITION_INFO;
+ disk->flags |= GENHD_FL_NO_PART_SCAN;
+ } else {
+ /* Register BDI before referencing it from bdev */
+ disk_to_dev(disk)->devt = devt;
+ bdi_register_owner(disk->queue->backing_dev_info,
+ disk_to_dev(disk));
+ blk_register_region(disk_devt(disk), disk->minors, NULL,
+ exact_match, exact_lock, disk);
+ }
register_disk(parent, disk);
- blk_register_queue(disk);
+ if (register_queue)
+ blk_register_queue(disk);
/*
* Take an extra ref on queue which will be put on disk_release()
@@ -685,15 +702,22 @@ void device_add_disk(struct device *parent, struct gendisk *disk)
*/
WARN_ON_ONCE(!blk_get_queue(disk->queue));
- retval = sysfs_create_link(&disk_to_dev(disk)->kobj, &bdi->dev->kobj,
- "bdi");
- WARN_ON(retval);
-
disk_add_events(disk);
blk_integrity_add(disk);
}
+
+void device_add_disk(struct device *parent, struct gendisk *disk)
+{
+ __device_add_disk(parent, disk, true);
+}
EXPORT_SYMBOL(device_add_disk);
+void device_add_disk_no_queue_reg(struct device *parent, struct gendisk *disk)
+{
+ __device_add_disk(parent, disk, false);
+}
+EXPORT_SYMBOL(device_add_disk_no_queue_reg);
+
void del_gendisk(struct gendisk *disk)
{
struct disk_part_iter piter;
@@ -717,24 +741,28 @@ void del_gendisk(struct gendisk *disk)
set_capacity(disk, 0);
disk->flags &= ~GENHD_FL_UP;
- sysfs_remove_link(&disk_to_dev(disk)->kobj, "bdi");
+ if (!(disk->flags & GENHD_FL_HIDDEN))
+ sysfs_remove_link(&disk_to_dev(disk)->kobj, "bdi");
if (disk->queue) {
/*
* Unregister bdi before releasing device numbers (as they can
* get reused and we'd get clashes in sysfs).
*/
- bdi_unregister(disk->queue->backing_dev_info);
+ if (!(disk->flags & GENHD_FL_HIDDEN))
+ bdi_unregister(disk->queue->backing_dev_info);
blk_unregister_queue(disk);
} else {
WARN_ON(1);
}
- blk_unregister_region(disk_devt(disk), disk->minors);
+
+ if (!(disk->flags & GENHD_FL_HIDDEN)) {
+ blk_unregister_region(disk_devt(disk), disk->minors);
+ kobject_put(disk->part0.holder_dir);
+ kobject_put(disk->slave_dir);
+ }
part_stat_set_all(&disk->part0, 0);
disk->part0.stamp = 0;
-
- kobject_put(disk->part0.holder_dir);
- kobject_put(disk->slave_dir);
if (!sysfs_deprecated)
sysfs_remove_link(block_depr, dev_name(disk_to_dev(disk)));
pm_runtime_set_memalloc_noio(disk_to_dev(disk), false);
@@ -797,6 +825,10 @@ struct gendisk *get_gendisk(dev_t devt, int *partno)
spin_unlock_bh(&ext_devt_lock);
}
+ if (unlikely(disk->flags & GENHD_FL_HIDDEN)) {
+ put_disk(disk);
+ disk = NULL;
+ }
return disk;
}
EXPORT_SYMBOL(get_gendisk);
@@ -1040,6 +1072,15 @@ static ssize_t disk_removable_show(struct device *dev,
(disk->flags & GENHD_FL_REMOVABLE ? 1 : 0));
}
+static ssize_t disk_hidden_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct gendisk *disk = dev_to_disk(dev);
+
+ return sprintf(buf, "%d\n",
+ (disk->flags & GENHD_FL_HIDDEN ? 1 : 0));
+}
+
static ssize_t disk_ro_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
@@ -1077,6 +1118,7 @@ static ssize_t disk_discard_alignment_show(struct device *dev,
static DEVICE_ATTR(range, S_IRUGO, disk_range_show, NULL);
static DEVICE_ATTR(ext_range, S_IRUGO, disk_ext_range_show, NULL);
static DEVICE_ATTR(removable, S_IRUGO, disk_removable_show, NULL);
+static DEVICE_ATTR(hidden, S_IRUGO, disk_hidden_show, NULL);
static DEVICE_ATTR(ro, S_IRUGO, disk_ro_show, NULL);
static DEVICE_ATTR(size, S_IRUGO, part_size_show, NULL);
static DEVICE_ATTR(alignment_offset, S_IRUGO, disk_alignment_offset_show, NULL);
@@ -1101,6 +1143,7 @@ static struct attribute *disk_attrs[] = {
&dev_attr_range.attr,
&dev_attr_ext_range.attr,
&dev_attr_removable.attr,
+ &dev_attr_hidden.attr,
&dev_attr_ro.attr,
&dev_attr_size.attr,
&dev_attr_alignment_offset.attr,
diff --git a/block/scsi_ioctl.c b/block/scsi_ioctl.c
index 7440de44dd85..6ed73c02a04d 100644
--- a/block/scsi_ioctl.c
+++ b/block/scsi_ioctl.c
@@ -253,6 +253,12 @@ static int blk_fill_sghdr_rq(struct request_queue *q, struct request *rq,
return 0;
}
+#ifdef CONFIG_AHCI_IMX
+extern void *sg_io_buffer_hack;
+#else
+#define sg_io_buffer_hack NULL
+#endif
+
static int blk_complete_sghdr_rq(struct request *rq, struct sg_io_hdr *hdr,
struct bio *bio)
{
@@ -282,7 +288,12 @@ static int blk_complete_sghdr_rq(struct request *rq, struct sg_io_hdr *hdr,
ret = -EFAULT;
}
- r = blk_rq_unmap_user(bio);
+ if (sg_io_buffer_hack && !hdr->iovec_count)
+ r = copy_to_user(hdr->dxferp, sg_io_buffer_hack,
+ hdr->dxfer_len);
+ else
+ r = blk_rq_unmap_user(bio);
+
if (!ret)
ret = r;
@@ -306,6 +317,9 @@ static int sg_io(struct request_queue *q, struct gendisk *bd_disk,
if (hdr->dxfer_len > (queue_max_hw_sectors(q) << 9))
return -EIO;
+ if (sg_io_buffer_hack && hdr->dxfer_len > 0x10000)
+ return -EIO;
+
if (hdr->dxfer_len)
switch (hdr->dxfer_direction) {
default:
@@ -353,9 +367,14 @@ static int sg_io(struct request_queue *q, struct gendisk *bd_disk,
ret = blk_rq_map_user_iov(q, rq, NULL, &i, GFP_KERNEL);
kfree(iov);
- } else if (hdr->dxfer_len)
- ret = blk_rq_map_user(q, rq, NULL, hdr->dxferp, hdr->dxfer_len,
- GFP_KERNEL);
+ } else if (hdr->dxfer_len) {
+ if (sg_io_buffer_hack)
+ ret = blk_rq_map_kern(q, rq, sg_io_buffer_hack,
+ hdr->dxfer_len, GFP_KERNEL);
+ else
+ ret = blk_rq_map_user(q, rq, NULL, hdr->dxferp,
+ hdr->dxfer_len, GFP_KERNEL);
+ }
if (ret)
goto out_free_cdb;
diff --git a/crypto/ccm.c b/crypto/ccm.c
index 8104c564dd31..a5138a3594f7 100644
--- a/crypto/ccm.c
+++ b/crypto/ccm.c
@@ -46,7 +46,18 @@ struct crypto_rfc4309_req_ctx {
struct crypto_ccm_req_priv_ctx {
u8 odata[16];
u8 idata[16];
- u8 auth_tag[16];
+
+ /*
+ * We need to force auth_tag to be on its own cacheline.
+ *
+ * We put it on its cacheline with the macro ____cacheline_aligned.
+ * The next fields must be on another cacheline so we add a dummy field
+ * which is located on another cacheline to enforce that.
+ */
+ u8 auth_tag[16] ____cacheline_aligned;
+
+ u8 dummy_align_auth_tag ____cacheline_aligned;
+
u32 flags;
struct scatterlist src[3];
struct scatterlist dst[3];
diff --git a/crypto/ecc.c b/crypto/ecc.c
index 65ee29dda063..0c1698774714 100644
--- a/crypto/ecc.c
+++ b/crypto/ecc.c
@@ -515,7 +515,7 @@ static void vli_mmod_fast_256(u64 *result, const u64 *product,
static bool vli_mmod_fast(u64 *result, u64 *product,
const u64 *curve_prime, unsigned int ndigits)
{
- u64 tmp[2 * ndigits];
+ u64 tmp[2 * ECC_MAX_DIGITS];
switch (ndigits) {
case 3:
@@ -536,7 +536,7 @@ static bool vli_mmod_fast(u64 *result, u64 *product,
static void vli_mod_mult_fast(u64 *result, const u64 *left, const u64 *right,
const u64 *curve_prime, unsigned int ndigits)
{
- u64 product[2 * ndigits];
+ u64 product[2 * ECC_MAX_DIGITS];
vli_mult(product, left, right, ndigits);
vli_mmod_fast(result, product, curve_prime, ndigits);
@@ -546,7 +546,7 @@ static void vli_mod_mult_fast(u64 *result, const u64 *left, const u64 *right,
static void vli_mod_square_fast(u64 *result, const u64 *left,
const u64 *curve_prime, unsigned int ndigits)
{
- u64 product[2 * ndigits];
+ u64 product[2 * ECC_MAX_DIGITS];
vli_square(product, left, ndigits);
vli_mmod_fast(result, product, curve_prime, ndigits);
@@ -560,8 +560,8 @@ static void vli_mod_square_fast(u64 *result, const u64 *left,
static void vli_mod_inv(u64 *result, const u64 *input, const u64 *mod,
unsigned int ndigits)
{
- u64 a[ndigits], b[ndigits];
- u64 u[ndigits], v[ndigits];
+ u64 a[ECC_MAX_DIGITS], b[ECC_MAX_DIGITS];
+ u64 u[ECC_MAX_DIGITS], v[ECC_MAX_DIGITS];
u64 carry;
int cmp_result;
@@ -649,8 +649,8 @@ static void ecc_point_double_jacobian(u64 *x1, u64 *y1, u64 *z1,
u64 *curve_prime, unsigned int ndigits)
{
/* t1 = x, t2 = y, t3 = z */
- u64 t4[ndigits];
- u64 t5[ndigits];
+ u64 t4[ECC_MAX_DIGITS];
+ u64 t5[ECC_MAX_DIGITS];
if (vli_is_zero(z1, ndigits))
return;
@@ -711,7 +711,7 @@ static void ecc_point_double_jacobian(u64 *x1, u64 *y1, u64 *z1,
static void apply_z(u64 *x1, u64 *y1, u64 *z, u64 *curve_prime,
unsigned int ndigits)
{
- u64 t1[ndigits];
+ u64 t1[ECC_MAX_DIGITS];
vli_mod_square_fast(t1, z, curve_prime, ndigits); /* z^2 */
vli_mod_mult_fast(x1, x1, t1, curve_prime, ndigits); /* x1 * z^2 */
@@ -724,7 +724,7 @@ static void xycz_initial_double(u64 *x1, u64 *y1, u64 *x2, u64 *y2,
u64 *p_initial_z, u64 *curve_prime,
unsigned int ndigits)
{
- u64 z[ndigits];
+ u64 z[ECC_MAX_DIGITS];
vli_set(x2, x1, ndigits);
vli_set(y2, y1, ndigits);
@@ -750,7 +750,7 @@ static void xycz_add(u64 *x1, u64 *y1, u64 *x2, u64 *y2, u64 *curve_prime,
unsigned int ndigits)
{
/* t1 = X1, t2 = Y1, t3 = X2, t4 = Y2 */
- u64 t5[ndigits];
+ u64 t5[ECC_MAX_DIGITS];
/* t5 = x2 - x1 */
vli_mod_sub(t5, x2, x1, curve_prime, ndigits);
@@ -791,9 +791,9 @@ static void xycz_add_c(u64 *x1, u64 *y1, u64 *x2, u64 *y2, u64 *curve_prime,
unsigned int ndigits)
{
/* t1 = X1, t2 = Y1, t3 = X2, t4 = Y2 */
- u64 t5[ndigits];
- u64 t6[ndigits];
- u64 t7[ndigits];
+ u64 t5[ECC_MAX_DIGITS];
+ u64 t6[ECC_MAX_DIGITS];
+ u64 t7[ECC_MAX_DIGITS];
/* t5 = x2 - x1 */
vli_mod_sub(t5, x2, x1, curve_prime, ndigits);
@@ -846,9 +846,9 @@ static void ecc_point_mult(struct ecc_point *result,
unsigned int ndigits)
{
/* R0 and R1 */
- u64 rx[2][ndigits];
- u64 ry[2][ndigits];
- u64 z[ndigits];
+ u64 rx[2][ECC_MAX_DIGITS];
+ u64 ry[2][ECC_MAX_DIGITS];
+ u64 z[ECC_MAX_DIGITS];
int i, nb;
int num_bits = vli_num_bits(scalar, ndigits);
@@ -957,13 +957,13 @@ int ecc_is_key_valid(unsigned int curve_id, unsigned int ndigits,
int ecc_gen_privkey(unsigned int curve_id, unsigned int ndigits, u64 *privkey)
{
const struct ecc_curve *curve = ecc_get_curve(curve_id);
- u64 priv[ndigits];
+ u64 priv[ECC_MAX_DIGITS];
unsigned int nbytes = ndigits << ECC_DIGITS_TO_BYTES_SHIFT;
unsigned int nbits = vli_num_bits(curve->n, ndigits);
int err;
/* Check that N is included in Table 1 of FIPS 186-4, section 6.1.1 */
- if (nbits < 160)
+ if (nbits < 160 || ndigits > ARRAY_SIZE(priv))
return -EINVAL;
/*
@@ -999,10 +999,10 @@ int ecc_make_pub_key(unsigned int curve_id, unsigned int ndigits,
{
int ret = 0;
struct ecc_point *pk;
- u64 priv[ndigits];
+ u64 priv[ECC_MAX_DIGITS];
const struct ecc_curve *curve = ecc_get_curve(curve_id);
- if (!private_key || !curve) {
+ if (!private_key || !curve || ndigits > ARRAY_SIZE(priv)) {
ret = -EINVAL;
goto out;
}
@@ -1030,18 +1030,49 @@ out:
return ret;
}
+/* SP800-56A section 5.6.2.3.4 partial verification: ephemeral keys only */
+static int ecc_is_pubkey_valid_partial(const struct ecc_curve *curve,
+ struct ecc_point *pk)
+{
+ u64 yy[ECC_MAX_DIGITS], xxx[ECC_MAX_DIGITS], w[ECC_MAX_DIGITS];
+
+ /* Check 1: Verify key is not the zero point. */
+ if (ecc_point_is_zero(pk))
+ return -EINVAL;
+
+ /* Check 2: Verify key is in the range [1, p-1]. */
+ if (vli_cmp(curve->p, pk->x, pk->ndigits) != 1)
+ return -EINVAL;
+ if (vli_cmp(curve->p, pk->y, pk->ndigits) != 1)
+ return -EINVAL;
+
+ /* Check 3: Verify that y^2 == (x^3 + a·x + b) mod p */
+ vli_mod_square_fast(yy, pk->y, curve->p, pk->ndigits); /* y^2 */
+ vli_mod_square_fast(xxx, pk->x, curve->p, pk->ndigits); /* x^2 */
+ vli_mod_mult_fast(xxx, xxx, pk->x, curve->p, pk->ndigits); /* x^3 */
+ vli_mod_mult_fast(w, curve->a, pk->x, curve->p, pk->ndigits); /* a·x */
+ vli_mod_add(w, w, curve->b, curve->p, pk->ndigits); /* a·x + b */
+ vli_mod_add(w, w, xxx, curve->p, pk->ndigits); /* x^3 + a·x + b */
+ if (vli_cmp(yy, w, pk->ndigits) != 0) /* Equation */
+ return -EINVAL;
+
+ return 0;
+
+}
+
int crypto_ecdh_shared_secret(unsigned int curve_id, unsigned int ndigits,
const u64 *private_key, const u64 *public_key,
u64 *secret)
{
int ret = 0;
struct ecc_point *product, *pk;
- u64 priv[ndigits];
- u64 rand_z[ndigits];
+ u64 priv[ECC_MAX_DIGITS];
+ u64 rand_z[ECC_MAX_DIGITS];
unsigned int nbytes;
const struct ecc_curve *curve = ecc_get_curve(curve_id);
- if (!private_key || !public_key || !curve) {
+ if (!private_key || !public_key || !curve ||
+ ndigits > ARRAY_SIZE(priv) || ndigits > ARRAY_SIZE(rand_z)) {
ret = -EINVAL;
goto out;
}
@@ -1056,16 +1087,20 @@ int crypto_ecdh_shared_secret(unsigned int curve_id, unsigned int ndigits,
goto out;
}
+ ecc_swap_digits(public_key, pk->x, ndigits);
+ ecc_swap_digits(&public_key[ndigits], pk->y, ndigits);
+ ret = ecc_is_pubkey_valid_partial(curve, pk);
+ if (ret)
+ goto err_alloc_product;
+
+ ecc_swap_digits(private_key, priv, ndigits);
+
product = ecc_alloc_point(ndigits);
if (!product) {
ret = -ENOMEM;
goto err_alloc_product;
}
- ecc_swap_digits(public_key, pk->x, ndigits);
- ecc_swap_digits(&public_key[ndigits], pk->y, ndigits);
- ecc_swap_digits(private_key, priv, ndigits);
-
ecc_point_mult(product, pk, priv, rand_z, curve->p, ndigits);
ecc_swap_digits(product->x, secret, ndigits);
diff --git a/crypto/ecc.h b/crypto/ecc.h
index e4fd4492c765..f75a86baa3bd 100644
--- a/crypto/ecc.h
+++ b/crypto/ecc.h
@@ -26,7 +26,9 @@
#ifndef _CRYPTO_ECC_H
#define _CRYPTO_ECC_H
-#define ECC_MAX_DIGITS 4 /* 256 */
+#define ECC_CURVE_NIST_P192_DIGITS 3
+#define ECC_CURVE_NIST_P256_DIGITS 4
+#define ECC_MAX_DIGITS ECC_CURVE_NIST_P256_DIGITS
#define ECC_DIGITS_TO_BYTES_SHIFT 3
diff --git a/crypto/ecc_curve_defs.h b/crypto/ecc_curve_defs.h
index b80f45da829c..336ab1805639 100644
--- a/crypto/ecc_curve_defs.h
+++ b/crypto/ecc_curve_defs.h
@@ -13,9 +13,11 @@ struct ecc_curve {
struct ecc_point g;
u64 *p;
u64 *n;
+ u64 *a;
+ u64 *b;
};
-/* NIST P-192 */
+/* NIST P-192: a = p - 3 */
static u64 nist_p192_g_x[] = { 0xF4FF0AFD82FF1012ull, 0x7CBF20EB43A18800ull,
0x188DA80EB03090F6ull };
static u64 nist_p192_g_y[] = { 0x73F977A11E794811ull, 0x631011ED6B24CDD5ull,
@@ -24,6 +26,10 @@ static u64 nist_p192_p[] = { 0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFFFFFFFFFEull,
0xFFFFFFFFFFFFFFFFull };
static u64 nist_p192_n[] = { 0x146BC9B1B4D22831ull, 0xFFFFFFFF99DEF836ull,
0xFFFFFFFFFFFFFFFFull };
+static u64 nist_p192_a[] = { 0xFFFFFFFFFFFFFFFCull, 0xFFFFFFFFFFFFFFFEull,
+ 0xFFFFFFFFFFFFFFFFull };
+static u64 nist_p192_b[] = { 0xFEB8DEECC146B9B1ull, 0x0FA7E9AB72243049ull,
+ 0x64210519E59C80E7ull };
static struct ecc_curve nist_p192 = {
.name = "nist_192",
.g = {
@@ -32,10 +38,12 @@ static struct ecc_curve nist_p192 = {
.ndigits = 3,
},
.p = nist_p192_p,
- .n = nist_p192_n
+ .n = nist_p192_n,
+ .a = nist_p192_a,
+ .b = nist_p192_b
};
-/* NIST P-256 */
+/* NIST P-256: a = p - 3 */
static u64 nist_p256_g_x[] = { 0xF4A13945D898C296ull, 0x77037D812DEB33A0ull,
0xF8BCE6E563A440F2ull, 0x6B17D1F2E12C4247ull };
static u64 nist_p256_g_y[] = { 0xCBB6406837BF51F5ull, 0x2BCE33576B315ECEull,
@@ -44,6 +52,10 @@ static u64 nist_p256_p[] = { 0xFFFFFFFFFFFFFFFFull, 0x00000000FFFFFFFFull,
0x0000000000000000ull, 0xFFFFFFFF00000001ull };
static u64 nist_p256_n[] = { 0xF3B9CAC2FC632551ull, 0xBCE6FAADA7179E84ull,
0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFF00000000ull };
+static u64 nist_p256_a[] = { 0xFFFFFFFFFFFFFFFCull, 0x00000000FFFFFFFFull,
+ 0x0000000000000000ull, 0xFFFFFFFF00000001ull };
+static u64 nist_p256_b[] = { 0x3BCE3C3E27D2604Bull, 0x651D06B0CC53B0F6ull,
+ 0xB3EBBD55769886BCull, 0x5AC635D8AA3A93E7ull };
static struct ecc_curve nist_p256 = {
.name = "nist_256",
.g = {
@@ -52,7 +64,9 @@ static struct ecc_curve nist_p256 = {
.ndigits = 4,
},
.p = nist_p256_p,
- .n = nist_p256_n
+ .n = nist_p256_n,
+ .a = nist_p256_a,
+ .b = nist_p256_b
};
#endif
diff --git a/crypto/ecdh.c b/crypto/ecdh.c
index 4271fc77d261..6a07d1005b6e 100644
--- a/crypto/ecdh.c
+++ b/crypto/ecdh.c
@@ -30,8 +30,8 @@ static inline struct ecdh_ctx *ecdh_get_ctx(struct crypto_kpp *tfm)
static unsigned int ecdh_supported_curve(unsigned int curve_id)
{
switch (curve_id) {
- case ECC_CURVE_NIST_P192: return 3;
- case ECC_CURVE_NIST_P256: return 4;
+ case ECC_CURVE_NIST_P192: return ECC_CURVE_NIST_P192_DIGITS;
+ case ECC_CURVE_NIST_P256: return ECC_CURVE_NIST_P256_DIGITS;
default: return 0;
}
}
diff --git a/crypto/gcm.c b/crypto/gcm.c
index 45b34a1144b8..2be938e5486e 100644
--- a/crypto/gcm.c
+++ b/crypto/gcm.c
@@ -66,7 +66,18 @@ struct crypto_gcm_ghash_ctx {
struct crypto_gcm_req_priv_ctx {
u8 iv[16];
- u8 auth_tag[16];
+
+ /*
+ * We need to force auth_tag to be on its own cacheline.
+ *
+ * We put it on its cacheline with the macro ____cacheline_aligned.
+ * The next fields must be on another cacheline so we add a dummy field
+ * which is located on another cacheline to enforce that.
+ */
+ u8 auth_tag[16] ____cacheline_aligned;
+
+ u8 dummy_align_auth_tag ____cacheline_aligned;
+
u8 iauth_tag[16];
struct scatterlist src[3];
struct scatterlist dst[3];
@@ -119,7 +130,7 @@ static int crypto_gcm_setkey(struct crypto_aead *aead, const u8 *key,
be128 hash;
u8 iv[16];
- struct crypto_gcm_setkey_result result;
+ struct crypto_gcm_setkey_result result ____cacheline_aligned;
struct scatterlist sg[1];
struct skcipher_request req;
diff --git a/crypto/tcrypt.c b/crypto/tcrypt.c
index f7affe7cf0b4..f7890aff8d1a 100644
--- a/crypto/tcrypt.c
+++ b/crypto/tcrypt.c
@@ -75,8 +75,7 @@ static char *check[] = {
"cast6", "arc4", "michael_mic", "deflate", "crc32c", "tea", "xtea",
"khazad", "wp512", "wp384", "wp256", "tnepres", "xeta", "fcrypt",
"camellia", "seed", "salsa20", "rmd128", "rmd160", "rmd256", "rmd320",
- "lzo", "cts", "zlib", "sha3-224", "sha3-256", "sha3-384", "sha3-512",
- NULL
+ "lzo", "cts", "sha3-224", "sha3-256", "sha3-384", "sha3-512", NULL
};
struct tcrypt_result {
@@ -1244,10 +1243,6 @@ static int do_test(const char *alg, u32 type, u32 mask, int m)
ret += tcrypt_test("ecb(seed)");
break;
- case 44:
- ret += tcrypt_test("zlib");
- break;
-
case 45:
ret += tcrypt_test("rfc4309(ccm(aes))");
break;
@@ -1316,10 +1311,6 @@ static int do_test(const char *alg, u32 type, u32 mask, int m)
ret += tcrypt_test("vmac(aes)");
break;
- case 110:
- ret += tcrypt_test("hmac(crc32)");
- break;
-
case 111:
ret += tcrypt_test("hmac(sha3-224)");
break;
diff --git a/crypto/testmgr.c b/crypto/testmgr.c
index d91278c01ea8..549469fc73b9 100644
--- a/crypto/testmgr.c
+++ b/crypto/testmgr.c
@@ -46,6 +46,8 @@ MODULE_PARM_DESC(notests, "disable crypto self-tests");
/* a perfect nop */
int alg_test(const char *driver, const char *alg, u32 type, u32 mask)
{
+ printk_once(KERN_INFO "alg: self-tests disabled by "
+ "CONFIG_CRYPTO_MANAGER_DISABLE_TESTS\n");
return 0;
}
diff --git a/crypto/testmgr.h b/crypto/testmgr.h
index 12835f072614..d9b6fc18ab73 100644
--- a/crypto/testmgr.h
+++ b/crypto/testmgr.h
@@ -24,8 +24,6 @@
#ifndef _CRYPTO_TESTMGR_H
#define _CRYPTO_TESTMGR_H
-#include <linux/netlink.h>
-
#define MAX_DIGEST_SIZE 64
#define MAX_TAP 8
diff --git a/drivers/Kconfig b/drivers/Kconfig
index 1d7af3c2ff27..0e86f585a95e 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -103,6 +103,8 @@ source "drivers/mmc/Kconfig"
source "drivers/memstick/Kconfig"
+source "drivers/mxc/Kconfig"
+
source "drivers/leds/Kconfig"
source "drivers/accessibility/Kconfig"
diff --git a/drivers/Makefile b/drivers/Makefile
index 5f5ccdbad21a..77fbc52a2b48 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -130,6 +130,7 @@ obj-$(CONFIG_EISA) += eisa/
obj-$(CONFIG_CPU_FREQ) += cpufreq/
obj-$(CONFIG_CPU_IDLE) += cpuidle/
obj-y += mmc/
+obj-y += mxc/
obj-$(CONFIG_MEMSTICK) += memstick/
obj-$(CONFIG_NEW_LEDS) += leds/
obj-$(CONFIG_INFINIBAND) += infiniband/
diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig
index 229a5ccd6b73..1887b5b31e6b 100644
--- a/drivers/ata/Kconfig
+++ b/drivers/ata/Kconfig
@@ -138,7 +138,7 @@ config AHCI_ST
config AHCI_IMX
tristate "Freescale i.MX AHCI SATA support"
- depends on MFD_SYSCON && (ARCH_MXC || COMPILE_TEST)
+ depends on MFD_SYSCON && (ARCH_MXC || ARCH_FSL_IMX8QM || COMPILE_TEST)
depends on (HWMON && (THERMAL || !THERMAL_OF)) || !HWMON
help
This option enables support for the Freescale i.MX SoC's
diff --git a/drivers/ata/ahci_imx.c b/drivers/ata/ahci_imx.c
index 787567e840bd..96892576aeae 100644
--- a/drivers/ata/ahci_imx.c
+++ b/drivers/ata/ahci_imx.c
@@ -22,6 +22,8 @@
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/ahci_platform.h>
+#include <linux/gpio.h>
+#include <linux/of_gpio.h>
#include <linux/of_device.h>
#include <linux/mfd/syscon.h>
#include <linux/mfd/syscon/imx6q-iomuxc-gpr.h>
@@ -53,11 +55,82 @@ enum {
/* Clock Reset Register */
IMX_CLOCK_RESET = 0x7f3f,
IMX_CLOCK_RESET_RESET = 1 << 0,
+ /* IMX8QM HSIO AHCI definitions */
+ IMX8QM_SATA_PHY_REG03_RX_IMPED_RATIO = 0x03,
+ IMX8QM_SATA_PHY_REG09_TX_IMPED_RATIO = 0x09,
+ IMX8QM_SATA_PHY_REG10_TX_POST_CURSOR_RATIO = 0x0a,
+ IMX8QM_SATA_PHY_GEN1_TX_POST_CURSOR_RATIO = 0x15,
+ IMX8QM_SATA_PHY_IMPED_RATIO_85OHM = 0x6c,
+ IMX8QM_SATA_PHY_REG22_TX_POST_CURSOR_RATIO = 0x16,
+ IMX8QM_SATA_PHY_GEN2_TX_POST_CURSOR_RATIO = 0x00,
+ IMX8QM_SATA_PHY_REG24_TX_AMP_RATIO_MARGIN0 = 0x18,
+ IMX8QM_SATA_PHY_TX_AMP_RATIO_MARGIN0 = 0x64,
+ IMX8QM_SATA_PHY_REG25_TX_AMP_RATIO_MARGIN1 = 0x19,
+ IMX8QM_SATA_PHY_TX_AMP_RATIO_MARGIN1 = 0x70,
+ IMX8QM_SATA_PHY_REG26_TX_AMP_RATIO_MARGIN2 = 0x1a,
+ IMX8QM_SATA_PHY_TX_AMP_RATIO_MARGIN2 = 0x69,
+ IMX8QM_SATA_PHY_REG48_PMA_STATUS = 0x30,
+ IMX8QM_SATA_PHY_REG48_PMA_RDY = BIT(7),
+ IMX8QM_SATA_PHY_REG128_UPDATE_SETTING = 0x80,
+ IMX8QM_SATA_PHY_UPDATE_SETTING = 0x01,
+ IMX8QM_LPCG_PHYX2_OFFSET = 0x00000,
+ IMX8QM_CSR_PHYX2_OFFSET = 0x90000,
+ IMX8QM_CSR_PHYX1_OFFSET = 0xa0000,
+ IMX8QM_CSR_PHYX_STTS0_OFFSET = 0x4,
+ IMX8QM_CSR_PCIEA_OFFSET = 0xb0000,
+ IMX8QM_CSR_PCIEB_OFFSET = 0xc0000,
+ IMX8QM_CSR_SATA_OFFSET = 0xd0000,
+ IMX8QM_CSR_PCIE_CTRL2_OFFSET = 0x8,
+ IMX8QM_CSR_MISC_OFFSET = 0xe0000,
+ /* IMX8QM SATA specific control registers */
+ IMX8QM_SATA_PPCFG_OFFSET = 0xa8,
+ IMX8QM_SATA_PPCFG_FORCE_PHY_RDY = BIT(20),
+ IMX8QM_SATA_PPCFG_BIST_PATTERN_MASK = 0x7 << 21,
+ IMX8QM_SATA_PPCFG_BIST_PATTERN_OFFSET = 21,
+ IMX8QM_SATA_PPCFG_BIST_PATTERN_EN = BIT(24),
+ IMX8QM_SATA_PPCFG_BIST_PATTERN_NOALIGNS = BIT(26),
+ IMX8QM_SATA_PP2CFG_OFFSET = 0xac,
+ IMX8QM_SATA_PP2CFG_COMINIT_NEGATE_MIN = 0x28 << 24,
+ IMX8QM_SATA_PP2CFG_COMINT_BURST_GAP = 0x18 << 16,
+ IMX8QM_SATA_PP2CFG_COMINT_BURST_GAP_MAX = 0x2b << 8,
+ IMX8QM_SATA_PP2CFG_COMINT_BURST_GAP_MIN = 0x1b << 0,
+ IMX8QM_SATA_PP3CFG_OFFSET = 0xb0,
+ IMX8QM_SATA_PP3CFG_COMWAKE_NEGATE_MIN = 0x0e << 24,
+ IMX8QM_SATA_PP3CFG_COMWAKE_BURST_GAP = 0x08 << 16,
+ IMX8QM_SATA_PP3CFG_COMWAKE_BURST_GAP_MAX = 0x0f << 8,
+ IMX8QM_SATA_PP3CFG_COMWAKE_BURST_GAP_MIN = 0x01 << 0,
+
+ IMX8QM_LPCG_PHYX2_PCLK0_MASK = (0x3 << 16),
+ IMX8QM_LPCG_PHYX2_PCLK1_MASK = (0x3 << 20),
+ IMX8QM_PHY_APB_RSTN_0 = BIT(0),
+ IMX8QM_PHY_MODE_SATA = BIT(19),
+ IMX8QM_PHY_MODE_MASK = (0xf << 17),
+ IMX8QM_PHY_PIPE_RSTN_0 = BIT(24),
+ IMX8QM_PHY_PIPE_RSTN_OVERRIDE_0 = BIT(25),
+ IMX8QM_PHY_PIPE_RSTN_1 = BIT(26),
+ IMX8QM_PHY_PIPE_RSTN_OVERRIDE_1 = BIT(27),
+ IMX8QM_STTS0_LANE0_TX_PLL_LOCK = BIT(4),
+ IMX8QM_MISC_IOB_RXENA = BIT(0),
+ IMX8QM_MISC_IOB_TXENA = BIT(1),
+ IMX8QM_MISC_PHYX1_EPCS_SEL = BIT(12),
+ IMX8QM_MISC_CLKREQN_OUT_OVERRIDE_1 = BIT(24),
+ IMX8QM_MISC_CLKREQN_OUT_OVERRIDE_0 = BIT(25),
+ IMX8QM_MISC_CLKREQN_IN_OVERRIDE_1 = BIT(28),
+ IMX8QM_MISC_CLKREQN_IN_OVERRIDE_0 = BIT(29),
+ IMX8QM_SATA_CTRL_RESET_N = BIT(12),
+ IMX8QM_SATA_CTRL_EPCS_PHYRESET_N = BIT(7),
+ IMX8QM_SATA_CTRL_EPCS_TXDEEMP_SEL = BIT(6),
+ IMX8QM_SATA_CTRL_EPCS_TXDEEMP = BIT(5),
+ IMX8QM_CTRL_BUTTON_RST_N = BIT(21),
+ IMX8QM_CTRL_POWER_UP_RST_N = BIT(23),
+ IMX8QM_CTRL_LTSSM_ENABLE = BIT(4),
};
enum ahci_imx_type {
AHCI_IMX53,
AHCI_IMX6Q,
+ AHCI_IMX6QP,
+ AHCI_IMX8QM,
};
struct imx_ahci_priv {
@@ -66,16 +139,31 @@ struct imx_ahci_priv {
struct clk *sata_clk;
struct clk *sata_ref_clk;
struct clk *ahb_clk;
+ struct clk *epcs_tx_clk;
+ struct clk *epcs_rx_clk;
+ struct clk *phy_apbclk;
+ struct clk *phy_pclk0;
+ struct clk *phy_pclk1;
+ void __iomem *phy_base;
+ int clkreq_gpio;
struct regmap *gpr;
bool no_device;
bool first_time;
u32 phy_params;
+ u32 imped_ratio;
+ u32 ext_osc;
};
+void *sg_io_buffer_hack;
+
static int ahci_imx_hotplug;
module_param_named(hotplug, ahci_imx_hotplug, int, 0644);
MODULE_PARM_DESC(hotplug, "AHCI IMX hot-plug support (0=Don't support, 1=support)");
+static int bist_enable;
+module_param_named(bist, bist_enable, int, 0644);
+MODULE_PARM_DESC(bist, "AHCI IMX bist mode enable(1 = enable)");
+
static void ahci_imx_host_stop(struct ata_host *host);
static int imx_phy_crbit_assert(void __iomem *mmio, u32 bit, bool assert)
@@ -391,6 +479,273 @@ static struct attribute *fsl_sata_ahci_attrs[] = {
};
ATTRIBUTE_GROUPS(fsl_sata_ahci);
+static int imx8_sata_enable(struct ahci_host_priv *hpriv)
+{
+ u32 val, reg;
+ int i, ret;
+ struct imx_ahci_priv *imxpriv = hpriv->plat_data;
+ struct device *dev = &imxpriv->ahci_pdev->dev;
+
+ /* configure the hsio for sata */
+ ret = clk_prepare_enable(imxpriv->phy_pclk0);
+ if (ret < 0) {
+ dev_err(dev, "can't enable phy pclk0.\n");
+ return ret;
+ }
+ ret = clk_prepare_enable(imxpriv->phy_pclk1);
+ if (ret < 0) {
+ dev_err(dev, "can't enable phy pclk1.\n");
+ goto disable_phy_pclk0;
+ }
+ ret = clk_prepare_enable(imxpriv->epcs_tx_clk);
+ if (ret < 0) {
+ dev_err(dev, "can't enable epcs tx clk.\n");
+ goto disable_phy_pclk1;
+ }
+ ret = clk_prepare_enable(imxpriv->epcs_rx_clk);
+ if (ret < 0) {
+ dev_err(dev, "can't enable epcs rx clk.\n");
+ goto disable_epcs_tx_clk;
+ }
+ ret = clk_prepare_enable(imxpriv->phy_apbclk);
+ if (ret < 0) {
+ dev_err(dev, "can't enable phy pclk1.\n");
+ goto disable_epcs_rx_clk;
+ }
+ /* Configure PHYx2 PIPE_RSTN */
+ regmap_read(imxpriv->gpr, IMX8QM_CSR_PCIEA_OFFSET
+ + IMX8QM_CSR_PCIE_CTRL2_OFFSET, &val);
+ if ((val & IMX8QM_CTRL_LTSSM_ENABLE) == 0) {
+ /* PCIEA of HSIO is down too */
+ regmap_update_bits(imxpriv->gpr,
+ IMX8QM_CSR_PHYX2_OFFSET,
+ IMX8QM_PHY_PIPE_RSTN_0
+ | IMX8QM_PHY_PIPE_RSTN_OVERRIDE_0,
+ IMX8QM_PHY_PIPE_RSTN_0
+ | IMX8QM_PHY_PIPE_RSTN_OVERRIDE_0);
+ }
+ regmap_read(imxpriv->gpr, IMX8QM_CSR_PCIEB_OFFSET
+ + IMX8QM_CSR_PCIE_CTRL2_OFFSET, &reg);
+ if ((reg & IMX8QM_CTRL_LTSSM_ENABLE) == 0) {
+ /* PCIEB of HSIO is down */
+ regmap_update_bits(imxpriv->gpr,
+ IMX8QM_CSR_PHYX2_OFFSET,
+ IMX8QM_PHY_PIPE_RSTN_1
+ | IMX8QM_PHY_PIPE_RSTN_OVERRIDE_1,
+ IMX8QM_PHY_PIPE_RSTN_1
+ | IMX8QM_PHY_PIPE_RSTN_OVERRIDE_1);
+ }
+ if (((reg | val) & IMX8QM_CTRL_LTSSM_ENABLE) == 0) {
+ /* Both PCIA and PCIEB of HSIO is down */
+ regmap_update_bits(imxpriv->gpr,
+ IMX8QM_LPCG_PHYX2_OFFSET,
+ IMX8QM_LPCG_PHYX2_PCLK0_MASK
+ | IMX8QM_LPCG_PHYX2_PCLK1_MASK,
+ 0);
+ }
+
+ /* set PWR_RST and BT_RST of csr_pciea */
+ val = IMX8QM_CSR_PCIEA_OFFSET + IMX8QM_CSR_PCIE_CTRL2_OFFSET;
+ regmap_update_bits(imxpriv->gpr,
+ val,
+ IMX8QM_CTRL_BUTTON_RST_N,
+ IMX8QM_CTRL_BUTTON_RST_N);
+ regmap_update_bits(imxpriv->gpr,
+ val,
+ IMX8QM_CTRL_POWER_UP_RST_N,
+ IMX8QM_CTRL_POWER_UP_RST_N);
+
+ /* PHYX1_MODE to SATA */
+ regmap_update_bits(imxpriv->gpr,
+ IMX8QM_CSR_PHYX1_OFFSET,
+ IMX8QM_PHY_MODE_MASK,
+ IMX8QM_PHY_MODE_SATA);
+
+ if (imxpriv->ext_osc) {
+ dev_info(dev, "external osc is used.\n");
+ /*
+ * bit0 rx ena 1, bit1 tx ena 0
+ * bit12 PHY_X1_EPCS_SEL 1.
+ */
+ regmap_update_bits(imxpriv->gpr,
+ IMX8QM_CSR_MISC_OFFSET,
+ IMX8QM_MISC_IOB_RXENA,
+ IMX8QM_MISC_IOB_RXENA);
+ regmap_update_bits(imxpriv->gpr,
+ IMX8QM_CSR_MISC_OFFSET,
+ IMX8QM_MISC_IOB_TXENA,
+ 0);
+ } else {
+ dev_info(dev, "internal pll is used.\n");
+ regmap_update_bits(imxpriv->gpr,
+ IMX8QM_CSR_MISC_OFFSET,
+ IMX8QM_MISC_IOB_RXENA,
+ 0);
+ regmap_update_bits(imxpriv->gpr,
+ IMX8QM_CSR_MISC_OFFSET,
+ IMX8QM_MISC_IOB_TXENA,
+ IMX8QM_MISC_IOB_TXENA);
+
+ }
+ regmap_update_bits(imxpriv->gpr,
+ IMX8QM_CSR_MISC_OFFSET,
+ IMX8QM_MISC_PHYX1_EPCS_SEL,
+ IMX8QM_MISC_PHYX1_EPCS_SEL);
+ /*
+ * It is possible, for PCIe and SATA are sharing
+ * the same clock source, HPLL or external oscillator.
+ * When PCIe is in low power modes (L1.X or L2 etc),
+ * the clock source can be turned off. In this case,
+ * if this clock source is required to be toggling by
+ * SATA, then SATA functions will be abnormal.
+ */
+ regmap_update_bits(imxpriv->gpr,
+ IMX8QM_CSR_MISC_OFFSET,
+ IMX8QM_MISC_CLKREQN_OUT_OVERRIDE_1
+ | IMX8QM_MISC_CLKREQN_OUT_OVERRIDE_0
+ | IMX8QM_MISC_CLKREQN_IN_OVERRIDE_1
+ | IMX8QM_MISC_CLKREQN_IN_OVERRIDE_0,
+ IMX8QM_MISC_CLKREQN_OUT_OVERRIDE_1
+ | IMX8QM_MISC_CLKREQN_OUT_OVERRIDE_0
+ | IMX8QM_MISC_CLKREQN_IN_OVERRIDE_1
+ | IMX8QM_MISC_CLKREQN_IN_OVERRIDE_0);
+
+ /* clear PHY RST, then set it */
+ regmap_update_bits(imxpriv->gpr,
+ IMX8QM_CSR_SATA_OFFSET,
+ IMX8QM_SATA_CTRL_EPCS_PHYRESET_N,
+ 0);
+
+ regmap_update_bits(imxpriv->gpr,
+ IMX8QM_CSR_SATA_OFFSET,
+ IMX8QM_SATA_CTRL_EPCS_PHYRESET_N,
+ IMX8QM_SATA_CTRL_EPCS_PHYRESET_N);
+ regmap_update_bits(imxpriv->gpr,
+ IMX8QM_CSR_SATA_OFFSET,
+ IMX8QM_SATA_CTRL_EPCS_TXDEEMP,
+ IMX8QM_SATA_CTRL_EPCS_TXDEEMP);
+ regmap_update_bits(imxpriv->gpr,
+ IMX8QM_CSR_SATA_OFFSET,
+ IMX8QM_SATA_CTRL_EPCS_TXDEEMP_SEL,
+ IMX8QM_SATA_CTRL_EPCS_TXDEEMP_SEL);
+
+ /* CTRL RST: SET -> delay 1 us -> CLEAR -> SET */
+ regmap_update_bits(imxpriv->gpr,
+ IMX8QM_CSR_SATA_OFFSET,
+ IMX8QM_SATA_CTRL_RESET_N,
+ IMX8QM_SATA_CTRL_RESET_N);
+ udelay(1);
+ regmap_update_bits(imxpriv->gpr,
+ IMX8QM_CSR_SATA_OFFSET,
+ IMX8QM_SATA_CTRL_RESET_N,
+ 0);
+ regmap_update_bits(imxpriv->gpr,
+ IMX8QM_CSR_SATA_OFFSET,
+ IMX8QM_SATA_CTRL_RESET_N,
+ IMX8QM_SATA_CTRL_RESET_N);
+
+ /* APB reset */
+ regmap_update_bits(imxpriv->gpr,
+ IMX8QM_CSR_PHYX1_OFFSET,
+ IMX8QM_PHY_APB_RSTN_0,
+ IMX8QM_PHY_APB_RSTN_0);
+
+ for (i = 0; i < 100; i++) {
+ reg = IMX8QM_CSR_PHYX1_OFFSET
+ + IMX8QM_CSR_PHYX_STTS0_OFFSET;
+ regmap_read(imxpriv->gpr, reg, &val);
+ val &= IMX8QM_STTS0_LANE0_TX_PLL_LOCK;
+ if (val == IMX8QM_STTS0_LANE0_TX_PLL_LOCK)
+ break;
+ udelay(1);
+ }
+
+ if (val != IMX8QM_STTS0_LANE0_TX_PLL_LOCK) {
+ dev_err(dev, "TX PLL of the PHY is not locked\n");
+ ret = -ENODEV;
+ } else {
+ for (i = 0; i < 1000; i++) {
+ reg = readb(imxpriv->phy_base +
+ IMX8QM_SATA_PHY_REG48_PMA_STATUS);
+ if (reg & IMX8QM_SATA_PHY_REG48_PMA_RDY)
+ break;
+ udelay(10);
+ }
+ if ((reg & IMX8QM_SATA_PHY_REG48_PMA_RDY) == 0) {
+ dev_err(dev, "Calibration is NOT finished.\n");
+ ret = -ENODEV;
+ goto err_out;
+ }
+
+ writeb(imxpriv->imped_ratio, imxpriv->phy_base
+ + IMX8QM_SATA_PHY_REG03_RX_IMPED_RATIO);
+ writeb(imxpriv->imped_ratio, imxpriv->phy_base
+ + IMX8QM_SATA_PHY_REG09_TX_IMPED_RATIO);
+ reg = readb(imxpriv->phy_base
+ + IMX8QM_SATA_PHY_REG03_RX_IMPED_RATIO);
+ if (unlikely(reg != imxpriv->imped_ratio))
+ dev_info(dev, "Can't set PHY RX impedance ratio.\n");
+ reg = readb(imxpriv->phy_base
+ + IMX8QM_SATA_PHY_REG09_TX_IMPED_RATIO);
+ if (unlikely(reg != imxpriv->imped_ratio))
+ dev_info(dev, "Can't set PHY TX impedance ratio.\n");
+
+ /* Configure the tx_amplitude to pass the tests. */
+ writeb(IMX8QM_SATA_PHY_TX_AMP_RATIO_MARGIN0, imxpriv->phy_base +
+ IMX8QM_SATA_PHY_REG24_TX_AMP_RATIO_MARGIN0);
+ writeb(IMX8QM_SATA_PHY_TX_AMP_RATIO_MARGIN1, imxpriv->phy_base +
+ IMX8QM_SATA_PHY_REG25_TX_AMP_RATIO_MARGIN1);
+ writeb(IMX8QM_SATA_PHY_TX_AMP_RATIO_MARGIN2, imxpriv->phy_base +
+ IMX8QM_SATA_PHY_REG26_TX_AMP_RATIO_MARGIN2);
+
+ /* Adjust the OOB COMINIT/COMWAKE to pass the tests. */
+ writeb(IMX8QM_SATA_PHY_GEN1_TX_POST_CURSOR_RATIO,
+ imxpriv->phy_base +
+ IMX8QM_SATA_PHY_REG10_TX_POST_CURSOR_RATIO);
+ writeb(IMX8QM_SATA_PHY_GEN2_TX_POST_CURSOR_RATIO,
+ imxpriv->phy_base +
+ IMX8QM_SATA_PHY_REG22_TX_POST_CURSOR_RATIO);
+
+ writeb(IMX8QM_SATA_PHY_UPDATE_SETTING, imxpriv->phy_base +
+ IMX8QM_SATA_PHY_REG128_UPDATE_SETTING);
+
+ reg = IMX8QM_SATA_PP2CFG_COMINIT_NEGATE_MIN |
+ IMX8QM_SATA_PP2CFG_COMINT_BURST_GAP |
+ IMX8QM_SATA_PP2CFG_COMINT_BURST_GAP_MAX |
+ IMX8QM_SATA_PP2CFG_COMINT_BURST_GAP_MIN;
+ writel(reg, hpriv->mmio + IMX8QM_SATA_PP2CFG_OFFSET);
+ reg = IMX8QM_SATA_PP3CFG_COMWAKE_NEGATE_MIN |
+ IMX8QM_SATA_PP3CFG_COMWAKE_BURST_GAP |
+ IMX8QM_SATA_PP3CFG_COMWAKE_BURST_GAP_MAX |
+ IMX8QM_SATA_PP3CFG_COMWAKE_BURST_GAP_MIN;
+ writel(reg, hpriv->mmio + IMX8QM_SATA_PP3CFG_OFFSET);
+
+ usleep_range(50, 100);
+
+ /*
+ * To reduce the power consumption, gate off
+ * the PHY clks
+ */
+ clk_disable_unprepare(imxpriv->phy_apbclk);
+ clk_disable_unprepare(imxpriv->phy_pclk1);
+ clk_disable_unprepare(imxpriv->phy_pclk0);
+ return ret;
+ }
+
+err_out:
+ clk_disable_unprepare(imxpriv->phy_apbclk);
+disable_epcs_rx_clk:
+ clk_disable_unprepare(imxpriv->epcs_rx_clk);
+disable_epcs_tx_clk:
+ clk_disable_unprepare(imxpriv->epcs_tx_clk);
+disable_phy_pclk1:
+ clk_disable_unprepare(imxpriv->phy_pclk1);
+disable_phy_pclk0:
+ clk_disable_unprepare(imxpriv->phy_pclk0);
+
+ return ret;
+}
+
static int imx_sata_enable(struct ahci_host_priv *hpriv)
{
struct imx_ahci_priv *imxpriv = hpriv->plat_data;
@@ -408,7 +763,7 @@ static int imx_sata_enable(struct ahci_host_priv *hpriv)
if (ret < 0)
goto disable_regulator;
- if (imxpriv->type == AHCI_IMX6Q) {
+ if (imxpriv->type == AHCI_IMX6Q || imxpriv->type == AHCI_IMX6QP) {
/*
* set PHY Paremeters, two steps to configure the GPR13,
* one write for rest of parameters, mask of first write
@@ -432,12 +787,28 @@ static int imx_sata_enable(struct ahci_host_priv *hpriv)
IMX6Q_GPR13_SATA_MPLL_CLK_EN);
usleep_range(100, 200);
+ }
+
+ if (imxpriv->type == AHCI_IMX6Q) {
ret = imx_sata_phy_reset(hpriv);
- if (ret) {
- dev_err(dev, "failed to reset phy: %d\n", ret);
- goto disable_clk;
- }
+ } else if (imxpriv->type == AHCI_IMX6QP) {
+ /* 6qp adds the sata reset mechanism, use it for 6qp sata */
+ regmap_update_bits(imxpriv->gpr, IOMUXC_GPR5,
+ BIT(10), 0);
+
+ regmap_update_bits(imxpriv->gpr, IOMUXC_GPR5,
+ BIT(11), 0);
+ udelay(50);
+ regmap_update_bits(imxpriv->gpr, IOMUXC_GPR5,
+ BIT(11), BIT(11));
+ } else if (imxpriv->type == AHCI_IMX8QM) {
+ ret = imx8_sata_enable(hpriv);
+ }
+
+ if (ret) {
+ dev_err(dev, "failed to reset phy: %d\n", ret);
+ goto disable_clk;
}
usleep_range(1000, 2000);
@@ -459,12 +830,20 @@ static void imx_sata_disable(struct ahci_host_priv *hpriv)
if (imxpriv->no_device)
return;
- if (imxpriv->type == AHCI_IMX6Q) {
+ if (imxpriv->type == AHCI_IMX6QP)
+ regmap_update_bits(imxpriv->gpr, IOMUXC_GPR5,
+ BIT(10), BIT(10));
+
+ if (imxpriv->type == AHCI_IMX6Q || imxpriv->type == AHCI_IMX6QP) {
regmap_update_bits(imxpriv->gpr, IOMUXC_GPR13,
IMX6Q_GPR13_SATA_MPLL_CLK_EN,
!IMX6Q_GPR13_SATA_MPLL_CLK_EN);
}
+ if (imxpriv->type == AHCI_IMX8QM) {
+ clk_disable_unprepare(imxpriv->epcs_rx_clk);
+ clk_disable_unprepare(imxpriv->epcs_tx_clk);
+ }
clk_disable_unprepare(imxpriv->sata_ref_clk);
ahci_platform_disable_regulators(hpriv);
@@ -481,7 +860,8 @@ static void ahci_imx_error_handler(struct ata_port *ap)
ahci_error_handler(ap);
- if (!(imxpriv->first_time) || ahci_imx_hotplug)
+ if (!(imxpriv->first_time) || ahci_imx_hotplug
+ || (imxpriv->type == AHCI_IMX8QM))
return;
imxpriv->first_time = false;
@@ -513,7 +893,7 @@ static int ahci_imx_softreset(struct ata_link *link, unsigned int *class,
if (imxpriv->type == AHCI_IMX53)
ret = ahci_pmp_retry_srst_ops.softreset(link, class, deadline);
- else if (imxpriv->type == AHCI_IMX6Q)
+ else
ret = ahci_ops.softreset(link, class, deadline);
return ret;
@@ -536,6 +916,8 @@ static const struct ata_port_info ahci_imx_port_info = {
static const struct of_device_id imx_ahci_of_match[] = {
{ .compatible = "fsl,imx53-ahci", .data = (void *)AHCI_IMX53 },
{ .compatible = "fsl,imx6q-ahci", .data = (void *)AHCI_IMX6Q },
+ { .compatible = "fsl,imx6qp-ahci", .data = (void *)AHCI_IMX6QP },
+ { .compatible = "fsl,imx8qm-ahci", .data = (void *)AHCI_IMX8QM },
{},
};
MODULE_DEVICE_TABLE(of, imx_ahci_of_match);
@@ -703,6 +1085,194 @@ static struct scsi_host_template ahci_platform_sht = {
AHCI_SHT(DRV_NAME),
};
+static int imx8_sata_probe(struct device *dev, struct imx_ahci_priv *imxpriv)
+{
+ int ret;
+ struct resource *phy_res;
+ struct platform_device *pdev = imxpriv->ahci_pdev;
+ struct device_node *np = dev->of_node;
+
+ if (of_property_read_u32(np, "ext_osc", &imxpriv->ext_osc) < 0) {
+ dev_info(dev, "ext_osc is not specified.\n");
+ /* Use the external osc as ref clk defaultly. */
+ imxpriv->ext_osc = 1;
+ }
+
+ if (of_property_read_u32(np, "fsl,phy-imp", &imxpriv->imped_ratio)) {
+ /*
+ * Regarding to the differnet Hw designs,
+ * Set the impedance ratio to 0x6c when 85OHM is used.
+ * Keep it to default value 0x80, when 100OHM is used.
+ */
+ dev_info(dev, "phy impedance ratio is not specified.\n");
+ imxpriv->imped_ratio = IMX8QM_SATA_PHY_IMPED_RATIO_85OHM;
+ }
+ phy_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "phy");
+ if (phy_res) {
+ imxpriv->phy_base = devm_ioremap(dev, phy_res->start,
+ resource_size(phy_res));
+ if (!imxpriv->phy_base) {
+ dev_err(dev, "error with ioremap\n");
+ return -ENOMEM;
+ }
+ } else {
+ dev_err(dev, "missing *phy* reg region.\n");
+ return -ENOMEM;
+ }
+ imxpriv->gpr =
+ syscon_regmap_lookup_by_phandle(np, "hsio");
+ if (IS_ERR(imxpriv->gpr)) {
+ dev_err(dev, "unable to find gpr registers\n");
+ return PTR_ERR(imxpriv->gpr);
+ }
+ imxpriv->epcs_tx_clk = devm_clk_get(dev, "epcs_tx");
+ if (IS_ERR(imxpriv->epcs_tx_clk)) {
+ dev_err(dev, "can't get sata_epcs tx clock.\n");
+ return PTR_ERR(imxpriv->epcs_tx_clk);
+ }
+
+ imxpriv->epcs_rx_clk = devm_clk_get(dev, "epcs_rx");
+ if (IS_ERR(imxpriv->epcs_rx_clk)) {
+ dev_err(dev, "can't get sata_epcs rx clock.\n");
+ return PTR_ERR(imxpriv->epcs_rx_clk);
+ }
+
+ imxpriv->phy_pclk0 = devm_clk_get(dev, "phy_pclk0");
+ if (IS_ERR(imxpriv->phy_pclk0)) {
+ dev_err(dev, "can't get sata_phy_pclk0 clock.\n");
+ return PTR_ERR(imxpriv->phy_pclk0);
+ }
+
+ imxpriv->phy_pclk1 = devm_clk_get(dev, "phy_pclk1");
+ if (IS_ERR(imxpriv->phy_pclk1)) {
+ dev_err(dev, "can't get sata_phy_pclk1 clock.\n");
+ return PTR_ERR(imxpriv->phy_pclk1);
+ }
+
+ imxpriv->phy_apbclk = devm_clk_get(dev, "phy_apbclk");
+ if (IS_ERR(imxpriv->phy_apbclk)) {
+ dev_err(dev, "can't get sata_phy_apbclk clock.\n");
+ return PTR_ERR(imxpriv->phy_apbclk);
+ }
+
+ /* Fetch GPIO, then enable the external OSC */
+ imxpriv->clkreq_gpio = of_get_named_gpio(np, "clkreq-gpio", 0);
+ if (gpio_is_valid(imxpriv->clkreq_gpio)) {
+ ret = devm_gpio_request_one(dev, imxpriv->clkreq_gpio,
+ GPIOF_OUT_INIT_LOW,
+ "SATA CLKREQ");
+ if (ret == -EBUSY) {
+ dev_info(dev, "clkreq had been initialized.\n");
+ } else if (ret) {
+ dev_err(dev, "%d unable to get clkreq.\n", ret);
+ return ret;
+ }
+ } else if (imxpriv->clkreq_gpio == -EPROBE_DEFER) {
+ return imxpriv->clkreq_gpio;
+ }
+
+ return 0;
+}
+
+static ssize_t imx_ahci_bist_pattern_info(struct device *dev,
+ struct device_attribute *devattr, char *buf)
+{
+ u32 bist_pattern;
+ struct ahci_host_priv *hpriv = dev_get_drvdata(dev);
+
+ bist_pattern = readl(hpriv->mmio + IMX8QM_SATA_PPCFG_OFFSET);
+ bist_pattern = bist_pattern & IMX8QM_SATA_PPCFG_BIST_PATTERN_MASK;
+ bist_pattern = bist_pattern >> IMX8QM_SATA_PPCFG_BIST_PATTERN_OFFSET;
+ return sprintf(buf, "imx-ahci-bist-pattern %s%s%s%s.\n",
+ (BIT(0) << bist_pattern) & BIT(0) ? "LBP " : "",
+ (BIT(0) << bist_pattern) & BIT(1) ? "LFTP " : "",
+ (BIT(0) << bist_pattern) & BIT(2) ? "MFTP " : "",
+ (BIT(0) << bist_pattern) & BIT(3) ? "HFTP " : "");
+}
+
+static ssize_t imx_ahci_bist_pattern(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ int ret;
+ u32 bist_pattern, val, timeout;
+ struct ahci_host_priv *hpriv = dev_get_drvdata(dev);
+
+ ret = sscanf(buf, "%x\n", &bist_pattern);
+ if (ret != 1)
+ return -EINVAL;
+ if ((bist_pattern > 3)) {
+ dev_err(dev, "LBP 0, LFTP 1, MFTP 2, HFTP 3.\n");
+ return -1;
+ }
+ dev_info(dev, "Try to enable %s%s%s%s pattern.\n",
+ (BIT(0) << bist_pattern) & BIT(0) ? "LBP " : "",
+ (BIT(0) << bist_pattern) & BIT(1) ? "LFTP " : "",
+ (BIT(0) << bist_pattern) & BIT(2) ? "MFTP " : "",
+ (BIT(0) << bist_pattern) & BIT(3) ? "HFTP " : "");
+
+ dev_info(dev, "Clear BIST enable.\n");
+ val = readl(hpriv->mmio + IMX8QM_SATA_PPCFG_OFFSET);
+ writel(val & (~IMX8QM_SATA_PPCFG_BIST_PATTERN_EN),
+ hpriv->mmio + IMX8QM_SATA_PPCFG_OFFSET);
+
+ /* put device into listen mode, first set PxSCTL.DET to 0 */
+ dev_info(dev, "Turn off device detection.\n");
+ val = readl(hpriv->mmio + 0x100 + PORT_SCR_CTL);
+ writel(val & ~0xf, hpriv->mmio + 0x100 + PORT_SCR_CTL);
+
+ dev_info(dev, "Force phy ready, then wait.\n");
+ val = readl(hpriv->mmio + IMX8QM_SATA_PPCFG_OFFSET);
+ writel(val | IMX8QM_SATA_PPCFG_FORCE_PHY_RDY,
+ hpriv->mmio + IMX8QM_SATA_PPCFG_OFFSET);
+
+ timeout = 1000;
+ do {
+ val = readl(hpriv->mmio + 0x100 + PORT_SCR_STAT);
+ if ((val & 0xf) > 1)
+ break;
+ mdelay(1);
+ } while (--timeout);
+ if (timeout == 0)
+ dev_info(dev, "Error, wait for phy ready timeout.\n");
+ else
+ dev_info(dev, "Get phy ready, and Gen%d mode is set.\n",
+ (val & 0xF0) >> 4);
+
+ /* clear SError */
+ dev_info(dev, "Clear error reg.\n");
+ val = readl(hpriv->mmio + 0x100 + PORT_SCR_ERR);
+ writel(val, hpriv->mmio + 0x100 + PORT_SCR_ERR);
+
+ dev_info(dev, "Select BIST pattern.\n");
+ val = readl(hpriv->mmio + IMX8QM_SATA_PPCFG_OFFSET);
+ val &= (~IMX8QM_SATA_PPCFG_BIST_PATTERN_MASK);
+ val |= (bist_pattern << IMX8QM_SATA_PPCFG_BIST_PATTERN_OFFSET);
+ writel(val, hpriv->mmio + IMX8QM_SATA_PPCFG_OFFSET);
+
+ dev_info(dev, "Set no aligns in BIST pattern.\n");
+ val = readl(hpriv->mmio + IMX8QM_SATA_PPCFG_OFFSET);
+ writel(val | IMX8QM_SATA_PPCFG_BIST_PATTERN_NOALIGNS,
+ hpriv->mmio + IMX8QM_SATA_PPCFG_OFFSET);
+
+ dev_info(dev, "BIST enable.\n");
+ val = readl(hpriv->mmio + IMX8QM_SATA_PPCFG_OFFSET);
+ writel(val | IMX8QM_SATA_PPCFG_BIST_PATTERN_EN,
+ hpriv->mmio + IMX8QM_SATA_PPCFG_OFFSET);
+
+ return count;
+}
+
+static DEVICE_ATTR(ahci_bist_pattern, 0644, imx_ahci_bist_pattern_info,
+ imx_ahci_bist_pattern);
+
+static struct attribute *imx_ahci_attrs[] = {
+ &dev_attr_ahci_bist_pattern.attr,
+ NULL
+};
+
+static struct attribute_group imx_ahci_attrgroup = {
+ .attrs = imx_ahci_attrs,
+};
static int imx_ahci_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
@@ -737,13 +1307,7 @@ static int imx_ahci_probe(struct platform_device *pdev)
return PTR_ERR(imxpriv->sata_ref_clk);
}
- imxpriv->ahb_clk = devm_clk_get(dev, "ahb");
- if (IS_ERR(imxpriv->ahb_clk)) {
- dev_err(dev, "can't get ahb clock.\n");
- return PTR_ERR(imxpriv->ahb_clk);
- }
-
- if (imxpriv->type == AHCI_IMX6Q) {
+ if (imxpriv->type == AHCI_IMX6Q || imxpriv->type == AHCI_IMX6QP) {
u32 reg_value;
imxpriv->gpr = syscon_regmap_lookup_by_compatible(
@@ -762,6 +1326,10 @@ static int imx_ahci_probe(struct platform_device *pdev)
IMX6Q_GPR13_SATA_RX_DPLL_MODE_2P_4F |
IMX6Q_GPR13_SATA_SPD_MODE_3P0G |
reg_value;
+ } else if (imxpriv->type == AHCI_IMX8QM) {
+ ret = imx8_sata_probe(dev, imxpriv);
+ if (ret)
+ return ret;
}
hpriv = ahci_platform_get_resources(pdev);
@@ -815,15 +1383,62 @@ static int imx_ahci_probe(struct platform_device *pdev)
writel(reg_val, hpriv->mmio + HOST_PORTS_IMPL);
}
- reg_val = clk_get_rate(imxpriv->ahb_clk) / 1000;
- writel(reg_val, hpriv->mmio + IMX_TIMER1MS);
+ imxpriv->ahb_clk = devm_clk_get(dev, "ahb");
+ if (IS_ERR(imxpriv->ahb_clk)) {
+ dev_info(dev, "no ahb clock.\n");
+ } else {
+ /*
+ * AHB clock is only used to configure the vendor specified
+ * TIMER1MS register. Set it if the AHB clock is defined.
+ */
+ reg_val = clk_get_rate(imxpriv->ahb_clk) / 1000;
+ writel(reg_val, hpriv->mmio + IMX_TIMER1MS);
+ }
- ret = ahci_platform_init_host(pdev, hpriv, &ahci_imx_port_info,
- &ahci_platform_sht);
- if (ret)
- goto disable_sata;
+ /*
+ * Due to IP bug on the Synopsis 3.00 SATA version,
+ * which is present on mx6q, and not on mx53,
+ * we should use sg_tablesize = 1 for reliable operation
+ */
+ if (imxpriv->type == AHCI_IMX6Q || imxpriv->type == AHCI_IMX6QP) {
+ dma_addr_t dma;
+
+ ahci_platform_sht.sg_tablesize = 1;
+
+ sg_io_buffer_hack = dma_alloc_coherent(NULL, 0x10000,
+ &dma, GFP_KERNEL);
+ if (!sg_io_buffer_hack) {
+ ret = -ENOMEM;
+ goto disable_sata;
+ }
+ }
- return 0;
+ if (imxpriv->type == AHCI_IMX8QM && bist_enable) {
+ dev_info(dev, "AHCI SATA compliance test patterns.\n");
+ ret = clk_prepare_enable(imxpriv->phy_pclk0);
+ if (ret < 0)
+ dev_err(dev, "can't enable phy pclk0.\n");
+ ret = clk_prepare_enable(imxpriv->phy_pclk1);
+ if (ret < 0)
+ dev_err(dev, "can't enable phy pclk1.\n");
+ ret = clk_prepare_enable(imxpriv->phy_apbclk);
+ if (ret < 0)
+ dev_err(dev, "can't get sata_phy_apbclk clock.\n");
+
+ dev_set_drvdata(dev, hpriv);
+ ret = sysfs_create_group(&pdev->dev.kobj, &imx_ahci_attrgroup);
+ if (ret)
+ ret = -EINVAL;
+ dev_info(dev, "Register AHCI SATA BIST sysfile callback.\n");
+ } else {
+
+ ret = ahci_platform_init_host(pdev, hpriv, &ahci_imx_port_info,
+ &ahci_platform_sht);
+ if (ret)
+ goto disable_sata;
+ }
+
+ return ret;
disable_sata:
imx_sata_disable(hpriv);
diff --git a/drivers/base/Kconfig b/drivers/base/Kconfig
index 49fd50fccd48..a9fd66b3d81a 100644
--- a/drivers/base/Kconfig
+++ b/drivers/base/Kconfig
@@ -153,6 +153,7 @@ config FW_LOADER_USER_HELPER
config FW_LOADER_USER_HELPER_FALLBACK
bool "Fallback user-helper invocation for firmware loading"
depends on FW_LOADER
+ default y
select FW_LOADER_USER_HELPER
help
This option enables / disables the invocation of user-helper
diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c
index 4b57cf5bc81d..49c5b71dc849 100644
--- a/drivers/base/firmware_class.c
+++ b/drivers/base/firmware_class.c
@@ -1217,7 +1217,7 @@ _request_firmware(const struct firmware **firmware_p, const char *name,
ret = fw_get_filesystem_firmware(device, fw->priv);
if (ret) {
if (!(opt_flags & FW_OPT_NO_WARN))
- dev_warn(device,
+ dev_dbg(device,
"Direct firmware load for %s failed with error %d\n",
name, ret);
if (opt_flags & FW_OPT_USERHELPER) {
diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c
index e811f2414889..07a32f29d4e0 100644
--- a/drivers/base/power/domain.c
+++ b/drivers/base/power/domain.c
@@ -247,6 +247,9 @@ static int _genpd_power_on(struct generic_pm_domain *genpd, bool timed)
if (!genpd->power_on)
return 0;
+ pr_debug("%s: Power-%s (idle state %d timed %s)\n", genpd->name, "on",
+ state_idx, timed ? "true" : "false");
+
if (!timed)
return genpd->power_on(genpd);
@@ -277,6 +280,9 @@ static int _genpd_power_off(struct generic_pm_domain *genpd, bool timed)
if (!genpd->power_off)
return 0;
+ pr_debug("%s: Power-%s (idle state %d timed %s)\n", genpd->name, "off",
+ state_idx, timed ? "true" : "false");
+
if (!timed)
return genpd->power_off(genpd);
@@ -367,6 +373,13 @@ static int genpd_power_off(struct generic_pm_domain *genpd, bool one_dev_on,
if (genpd->gov && genpd->gov->power_down_ok) {
if (!genpd->gov->power_down_ok(&genpd->domain))
return -EAGAIN;
+ } else {
+ /*
+ * if no valid state idx specified by governor, we use
+ * the default state_idx 0 to enter in case the domain
+ * has multi low power states.
+ */
+ genpd->state_idx = 0;
}
/* Default to shallowest state. */
@@ -379,6 +392,10 @@ static int genpd_power_off(struct generic_pm_domain *genpd, bool one_dev_on,
if (atomic_read(&genpd->sd_count) > 0)
return -EBUSY;
+ if (!genpd->device_count)
+ /* Choose the deepest state if no devices using this domain */
+ genpd->state_idx = genpd->state_count - 1;
+
/*
* If sd_count > 0 at this point, one of the subdomains hasn't
* managed to call genpd_power_on() for the master yet after
@@ -799,7 +816,20 @@ static void genpd_sync_power_off(struct generic_pm_domain *genpd, bool use_lock,
{
struct gpd_link *link;
- if (!genpd_status_on(genpd) || genpd_is_always_on(genpd))
+ /*
+ * Give the power domain a chance to switch to the deepest state in
+ * case it's already off but in an intermediate low power state.
+ * Due to power domain is alway off, so no need to check device wakeup
+ * here anymore
+ */
+
+ genpd->state_idx_saved = genpd->state_idx;
+
+ if (genpd_is_always_on(genpd))
+ return;
+
+ if (!genpd_status_on(genpd) &&
+ genpd->state_idx == (genpd->state_count - 1))
return;
if (genpd->suspended_count != genpd->device_count
@@ -811,6 +841,9 @@ static void genpd_sync_power_off(struct generic_pm_domain *genpd, bool use_lock,
if (_genpd_power_off(genpd, false))
return;
+ if (genpd->status == GPD_STATE_POWER_OFF)
+ return;
+
genpd->status = GPD_STATE_POWER_OFF;
list_for_each_entry(link, &genpd->slave_links, slave_node) {
@@ -858,6 +891,8 @@ static void genpd_sync_power_on(struct generic_pm_domain *genpd, bool use_lock,
_genpd_power_on(genpd, false);
+ /* restore save power domain state after resume */
+ genpd->state_idx = genpd->state_idx_saved;
genpd->status = GPD_STATE_ACTIVE;
}
@@ -1911,7 +1946,7 @@ EXPORT_SYMBOL_GPL(of_genpd_del_provider);
* Returns a valid pointer to struct generic_pm_domain on success or ERR_PTR()
* on failure.
*/
-static struct generic_pm_domain *genpd_get_from_provider(
+struct generic_pm_domain *genpd_get_from_provider(
struct of_phandle_args *genpdspec)
{
struct generic_pm_domain *genpd = ERR_PTR(-ENOENT);
@@ -1934,6 +1969,7 @@ static struct generic_pm_domain *genpd_get_from_provider(
return genpd;
}
+EXPORT_SYMBOL_GPL(genpd_get_from_provider);
/**
* of_genpd_add_device() - Add a device to an I/O PM domain
diff --git a/drivers/base/regmap/regmap-mmio.c b/drivers/base/regmap/regmap-mmio.c
index 5189fd6182f6..400a297d2490 100644
--- a/drivers/base/regmap/regmap-mmio.c
+++ b/drivers/base/regmap/regmap-mmio.c
@@ -305,19 +305,15 @@ static struct regmap_mmio_context *regmap_mmio_gen_context(struct device *dev,
goto err_free;
}
- if (clk_id == NULL)
- return ctx;
-
ctx->clk = clk_get(dev, clk_id);
- if (IS_ERR(ctx->clk)) {
- ret = PTR_ERR(ctx->clk);
- goto err_free;
- }
-
- ret = clk_prepare(ctx->clk);
- if (ret < 0) {
- clk_put(ctx->clk);
- goto err_free;
+ if (!IS_ERR(ctx->clk)) {
+ ret = clk_prepare(ctx->clk);
+ if (ret < 0) {
+ clk_put(ctx->clk);
+ goto err_free;
+ }
+ } else {
+ ctx->clk = NULL;
}
return ctx;
diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c
index 94944d063b37..c5e172093c8c 100644
--- a/drivers/block/pktcdvd.c
+++ b/drivers/block/pktcdvd.c
@@ -1122,7 +1122,7 @@ static int pkt_start_recovery(struct packet_data *pkt)
pkt->sector = new_sector;
bio_reset(pkt->bio);
- bio_set_set(pkt->bio, pd->bdev);
+ bio_set_dev(pkt->bio, pd->bdev);
bio_set_op_attrs(pkt->bio, REQ_OP_WRITE, 0);
pkt->bio->bi_iter.bi_sector = new_sector;
pkt->bio->bi_iter.bi_size = pkt->frames * CD_FRAMESIZE;
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
index 88316f86cc95..6f7601356048 100644
--- a/drivers/char/Kconfig
+++ b/drivers/char/Kconfig
@@ -94,6 +94,21 @@ config BFIN_OTP_WRITE_ENABLE
If unsure, say N.
+config FSL_OTP
+ tristate "Freescale On-Chip OTP Memory Support"
+ depends on HAS_IOMEM && OF
+ help
+ If you say Y here, you will get support for a character device
+ interface into the One Time Programmable memory pages that are
+ stored on the some Freescale i.MX processors. This will not get
+ you access to the secure memory pages however. You will need to
+ write your own secure code and reader for that.
+
+ To compile this driver as a module, choose M here: the module
+ will be called fsl_otp.
+
+ If unsure, it is safe to say Y.
+
config PRINTER
tristate "Parallel printer support"
depends on PARPORT
@@ -588,5 +603,6 @@ config TILE_SROM
source "drivers/char/xillybus/Kconfig"
+source "drivers/char/imx_amp/Kconfig"
endmenu
diff --git a/drivers/char/Makefile b/drivers/char/Makefile
index 7dc3abe66464..e02181144a95 100644
--- a/drivers/char/Makefile
+++ b/drivers/char/Makefile
@@ -15,6 +15,7 @@ obj-$(CONFIG_UV_MMTIMER) += uv_mmtimer.o
obj-$(CONFIG_IBM_BSR) += bsr.o
obj-$(CONFIG_SGI_MBCS) += mbcs.o
obj-$(CONFIG_BFIN_OTP) += bfin-otp.o
+obj-$(CONFIG_FSL_OTP) += fsl_otp.o
obj-$(CONFIG_PRINTER) += lp.o
@@ -60,3 +61,4 @@ js-rtc-y = rtc.o
obj-$(CONFIG_TILE_SROM) += tile-srom.o
obj-$(CONFIG_XILLYBUS) += xillybus/
obj-$(CONFIG_POWERNV_OP_PANEL) += powernv-op-panel.o
+obj-$(CONFIG_HAVE_IMX_AMP) += imx_amp/
diff --git a/drivers/char/fsl_otp.c b/drivers/char/fsl_otp.c
new file mode 100644
index 000000000000..ebeb0fc0907d
--- /dev/null
+++ b/drivers/char/fsl_otp.c
@@ -0,0 +1,738 @@
+/*
+ * Freescale On-Chip OTP driver
+ *
+ * Copyright (C) 2010-2016 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2017 NXP
+ *
+ * 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/delay.h>
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/kobject.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/sysfs.h>
+
+#define HW_OCOTP_CTRL 0x00000000
+#define HW_OCOTP_CTRL_SET 0x00000004
+#define BP_OCOTP_CTRL_WR_UNLOCK 16
+#define BM_OCOTP_CTRL_WR_UNLOCK 0xFFFF0000
+#define BM_OCOTP_CTRL_RELOAD_SHADOWS 0x00000400
+#define BM_OCOTP_CTRL_ERROR 0x00000200
+#define BM_OCOTP_CTRL_BUSY 0x00000100
+#define BP_OCOTP_CTRL_ADDR 0
+#define BM_OCOTP_CTRL_ADDR 0x0000007F
+#define BM_OCOTP_CTRL_ADDR_MX7D 0x0000000F
+#define BP_OCOTP_CTRL_ADDR_MX7ULP 0
+#define BM_OCOTP_CTRL_ADDR_MX7ULP 0x000000FF
+
+#define HW_OCOTP_TIMING 0x00000010
+#define BP_OCOTP_TIMING_STROBE_READ 16
+#define BM_OCOTP_TIMING_STROBE_READ 0x003F0000
+#define BP_OCOTP_TIMING_RELAX 12
+#define BM_OCOTP_TIMING_RELAX 0x0000F000
+#define BP_OCOTP_TIMING_STROBE_PROG 0
+#define BM_OCOTP_TIMING_STROBE_PROG 0x00000FFF
+
+#define BP_TIMING_FSOURCE 12
+#define BM_TIMING_FSOURCE 0x0007F000
+#define BV_TIMING_FSOURCE_NS 1001
+#define BP_TIMING_PROG 0
+#define BM_TIMING_PROG 0x00000FFF
+#define BV_TIMING_PROG_US 10
+
+#define HW_OCOTP_DATA 0x00000020
+
+#define HW_OCOTP_DATA0_MX7D 0x00000020
+#define HW_OCOTP_DATA1_MX7D 0x00000030
+#define HW_OCOTP_DATA2_MX7D 0x00000040
+#define HW_OCOTP_DATA3_MX7D 0x00000050
+
+#define HW_OCOTP_PDN_ULP 0x00000010
+#define HW_OCOTP_OUT_STATUS_ULP 0x00000090
+#define HW_OCOTP_OUT_STATUS_CLR_ULP 0x00000098
+
+#define BM_OUT_STATUS_DED_RELOAD_ULP (1 << 20)
+#define BM_OUT_STATUS_SEC_RELOAD_ULP (1 << 19)
+#define BM_OUT_STATUS_PROGFAIL (1 << 12)
+#define BM_OUT_STATUS_LOCKED (1 << 11)
+#define BM_OUT_STATUS_DED_ULP (1 << 10)
+
+#define HW_OCOTP_CUST_N(n) (0x00000400 + (n) * 0x10)
+#define BF(value, field) (((value) << BP_##field) & BM_##field)
+
+#define DEF_RELAX 20 /* > 16.5ns */
+
+#define BANK8(a, b, c, d, e, f, g, h) { \
+ "HW_OCOTP_"#a, "HW_OCOTP_"#b, "HW_OCOTP_"#c, "HW_OCOTP_"#d, \
+ "HW_OCOTP_"#e, "HW_OCOTP_"#f, "HW_OCOTP_"#g, "HW_OCOTP_"#h, \
+}
+
+#define BANK4(a, b, c, d) { \
+ "HW_OCOTP_"#a, "HW_OCOTP_"#b, "HW_OCOTP_"#c, "HW_OCOTP_"#d, \
+}
+
+static const char *imx6q_otp_desc[16][8] = {
+ BANK8(LOCK, CFG0, CFG1, CFG2, CFG3, CFG4, CFG5, CFG6),
+ BANK8(MEM0, MEM1, MEM2, MEM3, MEM4, ANA0, ANA1, ANA2),
+ BANK8(OTPMK0, OTPMK1, OTPMK2, OTPMK3, OTPMK4, OTPMK5, OTPMK6, OTPMK7),
+ BANK8(SRK0, SRK1, SRK2, SRK3, SRK4, SRK5, SRK6, SRK7),
+ BANK8(RESP0, HSJC_RESP1, MAC0, MAC1, HDCP_KSV0, HDCP_KSV1, GP1, GP2),
+ BANK8(DTCP_KEY0, DTCP_KEY1, DTCP_KEY2, DTCP_KEY3, DTCP_KEY4, MISC_CONF, FIELD_RETURN, SRK_REVOKE),
+ BANK8(HDCP_KEY0, HDCP_KEY1, HDCP_KEY2, HDCP_KEY3, HDCP_KEY4, HDCP_KEY5, HDCP_KEY6, HDCP_KEY7),
+ BANK8(HDCP_KEY8, HDCP_KEY9, HDCP_KEY10, HDCP_KEY11, HDCP_KEY12, HDCP_KEY13, HDCP_KEY14, HDCP_KEY15),
+ BANK8(HDCP_KEY16, HDCP_KEY17, HDCP_KEY18, HDCP_KEY19, HDCP_KEY20, HDCP_KEY21, HDCP_KEY22, HDCP_KEY23),
+ BANK8(HDCP_KEY24, HDCP_KEY25, HDCP_KEY26, HDCP_KEY27, HDCP_KEY28, HDCP_KEY29, HDCP_KEY30, HDCP_KEY31),
+ BANK8(HDCP_KEY32, HDCP_KEY33, HDCP_KEY34, HDCP_KEY35, HDCP_KEY36, HDCP_KEY37, HDCP_KEY38, HDCP_KEY39),
+ BANK8(HDCP_KEY40, HDCP_KEY41, HDCP_KEY42, HDCP_KEY43, HDCP_KEY44, HDCP_KEY45, HDCP_KEY46, HDCP_KEY47),
+ BANK8(HDCP_KEY48, HDCP_KEY49, HDCP_KEY50, HDCP_KEY51, HDCP_KEY52, HDCP_KEY53, HDCP_KEY54, HDCP_KEY55),
+ BANK8(HDCP_KEY56, HDCP_KEY57, HDCP_KEY58, HDCP_KEY59, HDCP_KEY60, HDCP_KEY61, HDCP_KEY62, HDCP_KEY63),
+ BANK8(HDCP_KEY64, HDCP_KEY65, HDCP_KEY66, HDCP_KEY67, HDCP_KEY68, HDCP_KEY69, HDCP_KEY70, HDCP_KEY71),
+ BANK8(CRC0, CRC1, CRC2, CRC3, CRC4, CRC5, CRC6, CRC7),
+};
+
+static const char *imx6sl_otp_desc[][8] = {
+ BANK8(LOCK, CFG0, CFG1, CFG2, CFG3, CFG4, CFG5, CFG6),
+ BANK8(MEM0, MEM1, MEM2, MEM3, MEM4, ANA0, ANA1, ANA2),
+ BANK8(OTPMK0, OTPMK1, OTPMK2, OTPMK3, OTPMK4, OTPMK5, OTPMK6, OTPMK7),
+ BANK8(SRK0, SRK1, SRK2, SRK3, SRK4, SRK5, SRK6, SRK7),
+ BANK8(SJC_RESP0, SJC_RESP1, MAC0, MAC1, CRC0, CRC1, GP1, GP2),
+ BANK8(SW_GP0, SW_GP1, SW_GP2, SW_GP3, SW_GP4, MISC_CONF, FIELD_RETURN, SRK_REVOKE),
+ BANK8(GP_LO0, GP_LO1, GP_LO2, GP_LO3, GP_LO4, GP_LO5, GP_LO6, GP_LO7),
+ BANK8(GP_HI0, GP_HI1, GP_HI2, GP_HI3, GP_HI4, GP_HI5, GP_HI6, GP_HI7),
+};
+
+static const char *imx6sll_otp_desc[][8] = {
+ BANK8(LOCK, CFG0, CFG1, CFG2, CFG3, CFG4, CFG5, CFG6),
+ BANK8(MEM0, MEM1, MEM2, MEM3, MEM4, ANA0, ANA1, USB),
+ BANK8(OTPMK0, OTPMK1, OTPMK2, OTPMK3, OTPMK4, OTPMK5, OTPMK6, OTPMK7),
+ BANK8(SRK0, SRK1, SRK2, SRK3, SRK4, SRK5, SRK6, SRK7),
+ BANK8(SJC_RESP0, SJC_RESP1, MAC0, MAC1, MAC2, CRC0, GP1, GP2),
+ BANK8(SW_GP0, SW_GP1, SW_GP2, SW_GP3, SW_GP4, MISC_CONF, FIELD_RETURN, SRK_REVOKE),
+ BANK8(ROM_PATCH0, ROM_PATCH1, ROM_PATCH2, ROM_PATCH3, ROM_PATCH4, ROM_PATCH5, ROM_PATCH6, ROM_PATCH7),
+ BANK8(GP30, GP31, GP32, GP33, GP40, GP41, GP42, GP43),
+};
+
+static const char *imx6ul_otp_desc[][8] = {
+ BANK8(LOCK, CFG0, CFG1, CFG2, CFG3, CFG4, CFG5, CFG6),
+ BANK8(MEM0, MEM1, MEM2, MEM3, MEM4, ANA0, ANA1, ANA2),
+ BANK8(OTPMK0, OTPMK1, OTPMK2, OTPMK3, OTPMK4, OTPMK5, OTPMK6, OTPMK7),
+ BANK8(SRK0, SRK1, SRK2, SRK3, SRK4, SRK5, SRK6, SRK7),
+ BANK8(SJC_RESP0, SJC_RESP1, MAC0, MAC1, MAC2, CRC, GP1, GP2),
+ BANK8(SW_GP0, SW_GP1, SW_GP2, SW_GP3, SW_GP4, MISC_CONF, FIELD_RETURN, SRK_REVOKE),
+ BANK8(ROM_PATCH0, ROM_PATCH1, ROM_PATCH2, ROM_PATCH3, ROM_PATCH4, ROM_PATCH5, ROM_PATCH6, ROM_PATCH7),
+ BANK8(ROM_PATCH8, ROM_PATCH9, ROM_PATCH10, ROM_PATCH11, ROM_PATCH12, ROM_PATCH13, ROM_PATCH14, ROM_PATCH15),
+ BANK8(GP30, GP31, GP32, GP33, GP34, GP35, GP36, GP37),
+ BANK8(GP38, GP39, GP310, GP311, GP312, GP313, GP314, GP315),
+ BANK8(GP40, GP41, GP42, GP43, GP44, GP45, GP46, GP47),
+ BANK8(GP48, GP49, GP410, GP411, GP412, GP413, GP414, GP415),
+ BANK8(GP50, GP51, GP52, GP53, GP54, GP55, GP56, GP57),
+ BANK8(GP58, GP59, GP510, GP511, GP512, GP513, GP514, GP515),
+ BANK8(GP60, GP61, GP62, GP63, GP64, GP65, GP66, GP67),
+ BANK8(GP70, GP71, GP72, GP73, GP80, GP81, GP82, GP83),
+};
+
+static const char *imx6ull_otp_desc[][8] = {
+ BANK8(LOCK, CFG0, CFG1, CFG2, CFG3, CFG4, CFG5, CFG6),
+ BANK8(MEM0, MEM1, MEM2, MEM3, MEM4, ANA0, ANA1, ANA2),
+ BANK8(OTPMK0, OTPMK1, OTPMK2, OTPMK3, OTPMK4, OTPMK5, OTPMK6, OTPMK7),
+ BANK8(SRK0, SRK1, SRK2, SRK3, SRK4, SRK5, SRK6, SRK7),
+ BANK8(SJC_RESP0, SJC_RESP1, MAC0, MAC1, MAC2, CRC, GP1, GP2),
+ BANK8(SW_GP0, SW_GP1, SW_GP2, SW_GP3, SW_GP4, MISC_CONF, FIELD_RETURN, SRK_REVOKE),
+ BANK8(ROM_PATCH0, ROM_PATCH1, ROM_PATCH2, ROM_PATCH3, ROM_PATCH4, ROM_PATCH5, ROM_PATCH6, ROM_PATCH7),
+ BANK8(GP30, GP31, GP32, GP33, GP40, GP41, GP42, GP43),
+};
+
+static const char *imx7d_otp_desc[][4] = {
+ BANK4(LOCK, TESTER0, TESTER1, TESTER2),
+ BANK4(TESTER3, TESTER4, TESTER5, BOOT_CFG0),
+ BANK4(BOOT_CFG1, BOOT_CFG2, BOOT_CFG3, BOOT_CFG4),
+ BANK4(MEM_TRIM0, MEM_TRIM1, ANA0, ANA1),
+ BANK4(OTPMK0, OTPMK1, OTPMK2, OTPMK3),
+ BANK4(OTPMK4, OTPMK5, OTPMK6, OTPMK7),
+ BANK4(SRK0, SRK1, SRK2, SRK3),
+ BANK4(SRK4, SRK5, SRK6, SRK7),
+ BANK4(SJC_RESP0, SJC_RESP1, USB_ID, FIELD_RETURN),
+ BANK4(MAC_ADDR0, MAC_ADDR1, MAC_ADDR2, SRK_REVOKE),
+ BANK4(MAU_KEY0, MAU_KEY1, MAU_KEY2, MAU_KEY3),
+ BANK4(MAU_KEY4, MAU_KEY5, MAU_KEY6, MAU_KEY7),
+ BANK4(ROM_PATCH0, ROM_PATCH1, ROM_PATCH2, ROM_PATCH3),
+ BANK4(ROM_PATCH4, ROM_PATCH5, ROM_PATCH6, ROM_PATCH7),
+ BANK4(GP10, GP11, GP20, GP21),
+ BANK4(CRC_GP10, CRC_GP11, CRC_GP20, CRC_GP21),
+};
+
+static const char *imx7ulp_otp_desc[][8] = {
+ BANK8(TESTER0, TESTER1, TESTER2, TESTER3, TESTER4, TESTER5, TESTER6, TESTER7),
+ BANK8(LOCK0, LOCK1, LOCK2, CFG0, CFG1, CFG2, CFG3, CFG4),
+ BANK8(BOOT0, BOOT1, BOOT2, BOOT3, BOOT4, BOOT5, BOOT6, BOOT7),
+ BANK8(MEM0, MEM1, MEM2, MEM3, ANA0, ANA1, ANA2, ANA3),
+ BANK8(OTPMK0, OTPMK1, OTPMK2, OTPMK3, OTPMK4, OTPMK5, OTPMK6, OTPMK7),
+ BANK8(A7_SRK0, A7_SRK1, A7_SRK2, A7_SRK3, A7_SRK4, A7_SRK5, A7_SRK6, A7_SRK7),
+ BANK8(M4_SRK0, M4_SRK1, M4_SRK2, M4_SRK3, M4_SRK4, M4_SRK5, M4_SRK6, M4_SRK7),
+ BANK8(SJC_RESP0, SJC_RESP1, GP0, GP1, GP2, GP3, GP4, GP5),
+ BANK8(MAU_KEY0, MAU_KEY1, MAU_KEY2, MAU_KEY3, MAU_KEY4, MAU_KEY5, MAU_KEY6, MAU_KEY7),
+ BANK8(TESTER10, TESTER11, TESTER12, TESTER13, TESTER14, TESTER15, FIELD_RETURN, SRK_REVOKE),
+ BANK8(PMU0, PMU1, PMU2, PMU3, PMU4, PMU5, PMU6, PMU7),
+ BANK8(A7_PATCH0, A7_PATCH1, A7_PATCH2, A7_PATCH3, A7_PATCH4, A7_PATCH5, A7_PATCH6, A7_PATCH7),
+ BANK8(A7_PATCH10, A7_PATCH11, A7_PATCH12, A7_PATCH13, A7_PATCH14, A7_PATCH15, A7_PATCH16, A7_PATCH17),
+ BANK8(A7_PATCH20, A7_PATCH21, A7_PATCH22, A7_PATCH23, A7_PATCH24, A7_PATCH25, A7_PATCH26, A7_PATCH27),
+ BANK8(A7_PATCH30, A7_PATCH31, A7_PATCH32, A7_PATCH33, A7_PATCH34, A7_PATCH35, A7_PATCH36, A7_PATCH37),
+ BANK8(GP10, GP11, GP12, GP13, GP14, GP15, GP16, GP17),
+ BANK8(GP20, GP21, GP22, GP23, GP24, GP25, GP26, GP27),
+ BANK8(GP30, GP31, GP32, GP33, GP34, GP35, GP36, GP37),
+ BANK8(GP40, GP41, GP42, GP43, GP44, GP45, GP46, GP47),
+ BANK8(GP50, GP51, GP52, GP53, GP54, GP55, GP56, GP57),
+ BANK8(M4_PATCH0, M4_PATCH1, M4_PATCH2, M4_PATCH3, M4_PATCH4, M4_PATCH5, M4_PATCH6, M4_PATCH7),
+ BANK8(M4_PATCH10, M4_PATCH11, M4_PATCH12, M4_PATCH13, M4_PATCH14, M4_PATCH15, M4_PATCH16, M4_PATCH17),
+ BANK8(M4_PATCH20, M4_PATCH21, M4_PATCH22, M4_PATCH23, M4_PATCH24, M4_PATCH25, M4_PATCH26, M4_PATCH27),
+ BANK8(M4_PATCH30, M4_PATCH31, M4_PATCH32, M4_PATCH33, M4_PATCH34, M4_PATCH35, M4_PATCH36, M4_PATCH37),
+ BANK8(GP60, GP61, GP62, GP63, GP64, GP65, GP66, GP67),
+ BANK8(GP70, GP71, GP72, GP73, GP74, GP75, GP76, GP77),
+ BANK8(GP80, GP81, GP82, GP83, GP84, GP85, GP86, GP87),
+ BANK8(GP90, GP91, GP92, GP93, GP94, GP95, GP96, GP97),
+ BANK8(TRIM0, TRIM1, TRIM2, TRIM3, TRIM4, TRIM5, TRIM6, TRIM7),
+ BANK8(OTFAD_KEY0, OTFAD_KEY1, OTFAD_KEY2, OTFAD_KEY3, OTFAD_CFG0, OTFAD_CFG1, OTFAD_CFG2, OTFAD_CFG3),
+ BANK8(CRC0, CRC1, CRC2, CRC3, CRC4, CRC5, CRC6, CRC7),
+};
+
+static DEFINE_MUTEX(otp_mutex);
+static void __iomem *otp_base;
+static struct clk *otp_clk;
+struct kobject *otp_kobj;
+struct kobj_attribute *otp_kattr;
+struct attribute_group *otp_attr_group;
+
+enum fsl_otp_devtype {
+ FSL_OTP_MX6Q,
+ FSL_OTP_MX6DL,
+ FSL_OTP_MX6SX,
+ FSL_OTP_MX6SL,
+ FSL_OTP_MX6SLL,
+ FSL_OTP_MX6UL,
+ FSL_OTP_MX6ULL,
+ FSL_OTP_MX7D,
+ FSL_OTP_MX7ULP,
+};
+
+struct fsl_otp_devtype_data {
+ enum fsl_otp_devtype devtype;
+ const char **bank_desc;
+ int fuse_nums;
+ void (*set_otp_timing)(void);
+};
+
+static struct fsl_otp_devtype_data *fsl_otp;
+
+/*
+ * fsl_otp_bank_physical and fsl_otp_word_physical are used to
+ * find the physical index of the word. Only used for calculating
+ * offset of the word, means only effective when reading fuse.
+ * Do not use the two functions for prog fuse. Always use the word
+ * index from fuse map to prog the fuse.
+ *
+ * Take i.MX6UL for example:
+ * there are holes between bank 5 and bank 6. The hole is 0x100 bytes.
+ * To bank 15, word 7, the word index is 15 * 8 + 7. The physical word
+ * index is 15 * 8 + 0x100 / 0x10 + 7, 0x100 contains 16 words.
+ * So use 15 * 8 + 7 to prog the fuse. And when reading, account the hole
+ * using offset 0x400 + (15 * 8 + 0x100 / 0x10 + 7) * 0x10.
+ *
+ * There is a hole in shadow registers address map of size 0x100
+ * between bank 5 and bank 6 on iMX6QP, iMX6DQ, iMX6SDL, iMX6SX and iMX6UL.
+ * Bank 5 ends at 0x6F0 and Bank 6 starts at 0x800. When reading the fuses,
+ * account for this hole in address space.
+ *
+ * Similar hole exists between bank 14 and bank 15 of size 0x80
+ * on iMX6QP, iMX6DQ, iMX6SDL, i.MX6SLL and iMX6SX.
+ * Note: iMX6SL has only 0-7 banks and there is no hole.
+ * Note: iMX6UL doesn't have this one.
+ *
+ * To i.MX6SLL, there are 9 banks. bank 7 and bank8 only contain 4 words
+ * each. Other banks contains 8 words.
+ */
+static u32 fsl_otp_bank_physical(struct fsl_otp_devtype_data *d, int bank)
+{
+ u32 phy_bank;
+
+ if ((bank == 0) || (d->devtype == FSL_OTP_MX6SL) ||
+ (d->devtype == FSL_OTP_MX7D) || (d->devtype == FSL_OTP_MX7ULP))
+ phy_bank = bank;
+ else if ((d->devtype == FSL_OTP_MX6UL) ||
+ (d->devtype == FSL_OTP_MX6ULL) ||
+ (d->devtype == FSL_OTP_MX6SLL)) {
+ if (bank >= 6)
+ phy_bank = fsl_otp_bank_physical(d, 5) + bank - 3;
+ else
+ phy_bank = bank;
+ } else {
+ if (bank >= 15)
+ phy_bank = fsl_otp_bank_physical(d, 14) + bank - 13;
+ else if (bank >= 6)
+ phy_bank = fsl_otp_bank_physical(d, 5) + bank - 3;
+ else
+ phy_bank = bank;
+ }
+
+ return phy_bank;
+}
+
+static u32 fsl_otp_word_physical(struct fsl_otp_devtype_data *d, int index)
+{
+ u32 phy_bank_off;
+ u32 word_off, bank_off;
+ u32 words_per_bank;
+
+ if (d->devtype == FSL_OTP_MX7D)
+ words_per_bank = 4;
+ else
+ words_per_bank = 8;
+
+ bank_off = index / words_per_bank;
+ word_off = index % words_per_bank;
+ phy_bank_off = fsl_otp_bank_physical(d, bank_off);
+
+ return phy_bank_off * words_per_bank + word_off;
+}
+
+static void imx6_set_otp_timing(void)
+{
+ unsigned long clk_rate = 0;
+ unsigned long strobe_read, relex, strobe_prog;
+ u32 timing = 0;
+
+ clk_rate = clk_get_rate(otp_clk);
+
+ /* do optimization for too many zeros */
+ relex = clk_rate / (1000000000 / DEF_RELAX) - 1;
+ strobe_prog = clk_rate / (1000000000 / 10000) + 2 * (DEF_RELAX + 1) - 1;
+ strobe_read = clk_rate / (1000000000 / 40) + 2 * (DEF_RELAX + 1) - 1;
+
+ timing = BF(relex, OCOTP_TIMING_RELAX);
+ timing |= BF(strobe_read, OCOTP_TIMING_STROBE_READ);
+ timing |= BF(strobe_prog, OCOTP_TIMING_STROBE_PROG);
+
+ __raw_writel(timing, otp_base + HW_OCOTP_TIMING);
+}
+
+static void imx7_set_otp_timing(void)
+{
+ unsigned long clk_rate;
+ u32 fsource, prog;
+ u32 timing = 0;
+ u32 reg;
+
+ clk_rate = clk_get_rate(otp_clk);
+
+ fsource = DIV_ROUND_UP((clk_rate / 1000) * BV_TIMING_FSOURCE_NS,
+ 1000000) + 1;
+ prog = DIV_ROUND_CLOSEST(clk_rate * BV_TIMING_PROG_US, 1000000) + 1;
+ timing = BF(fsource, TIMING_FSOURCE) | BF(prog, TIMING_PROG);
+ reg = __raw_readl(otp_base + HW_OCOTP_TIMING);
+ reg &= ~(BM_TIMING_FSOURCE | BM_TIMING_PROG);
+ reg |= timing;
+ __raw_writel(reg, otp_base + HW_OCOTP_TIMING);
+}
+
+static void imx7ulp_set_otp_timing(void)
+{
+ /* No need to setup timing for ULP */
+}
+
+static struct fsl_otp_devtype_data imx6q_data = {
+ .devtype = FSL_OTP_MX6Q,
+ .bank_desc = (const char **)imx6q_otp_desc,
+ .fuse_nums = 16 * 8,
+ .set_otp_timing = imx6_set_otp_timing,
+};
+
+static struct fsl_otp_devtype_data imx6sl_data = {
+ .devtype = FSL_OTP_MX6SL,
+ .bank_desc = (const char **)imx6sl_otp_desc,
+ .fuse_nums = 8 * 8,
+ .set_otp_timing = imx6_set_otp_timing,
+};
+
+static struct fsl_otp_devtype_data imx6sll_data = {
+ .devtype = FSL_OTP_MX6SLL,
+ .bank_desc = (const char **)imx6sll_otp_desc,
+ /* Bank 7 and Bank 8 are 4 words each */
+ .fuse_nums = 8 * 8,
+ .set_otp_timing = imx6_set_otp_timing,
+};
+
+static struct fsl_otp_devtype_data imx6ul_data = {
+ .devtype = FSL_OTP_MX6UL,
+ .bank_desc = (const char **)imx6ul_otp_desc,
+ .fuse_nums = 16 * 8,
+ .set_otp_timing = imx6_set_otp_timing,
+};
+
+static struct fsl_otp_devtype_data imx6ull_data = {
+ .devtype = FSL_OTP_MX6ULL,
+ .bank_desc = (const char **)imx6ull_otp_desc,
+ /* Bank 7 and Bank 8 are 4 words each */
+ .fuse_nums = 8 * 8,
+ .set_otp_timing = imx6_set_otp_timing,
+};
+
+static struct fsl_otp_devtype_data imx7d_data = {
+ .devtype = FSL_OTP_MX7D,
+ .bank_desc = (const char **)imx7d_otp_desc,
+ .fuse_nums = 16 * 4,
+ .set_otp_timing = imx7_set_otp_timing,
+};
+
+static struct fsl_otp_devtype_data imx7ulp_data = {
+ .devtype = FSL_OTP_MX7ULP,
+ .bank_desc = (const char **)imx7ulp_otp_desc,
+ .fuse_nums = 31 * 8,
+ .set_otp_timing = imx7ulp_set_otp_timing,
+};
+
+static int otp_wait_busy(u32 flags)
+{
+ int count;
+ u32 c;
+
+ for (count = 10000; count >= 0; count--) {
+ c = __raw_readl(otp_base + HW_OCOTP_CTRL);
+ if (!(c & (BM_OCOTP_CTRL_BUSY | BM_OCOTP_CTRL_ERROR | flags)))
+ break;
+ cpu_relax();
+ }
+
+ if (count < 0)
+ return -ETIMEDOUT;
+
+ return 0;
+}
+
+static ssize_t fsl_otp_show(struct kobject *kobj, struct kobj_attribute *attr,
+ char *buf)
+{
+ unsigned int index = attr - otp_kattr;
+ unsigned int phy_index;
+ u32 value = 0;
+ int ret;
+
+ if (!fsl_otp)
+ return -ENODEV;
+
+ ret = clk_prepare_enable(otp_clk);
+ if (ret)
+ return -ENODEV;
+
+ mutex_lock(&otp_mutex);
+
+ phy_index = fsl_otp_word_physical(fsl_otp, index);
+ fsl_otp->set_otp_timing();
+ ret = otp_wait_busy(0);
+ if (ret)
+ goto out;
+
+ if (fsl_otp->devtype == FSL_OTP_MX7ULP) {
+ value = __raw_readl(otp_base + HW_OCOTP_OUT_STATUS_ULP);
+ if (value & BM_OUT_STATUS_DED_ULP) {
+ __raw_writel(BM_OUT_STATUS_DED_ULP, otp_base + HW_OCOTP_OUT_STATUS_CLR_ULP);
+ goto out;
+ }
+ }
+
+ value = __raw_readl(otp_base + HW_OCOTP_CUST_N(phy_index));
+
+ if (fsl_otp->devtype == FSL_OTP_MX7ULP) {
+ __raw_writel(1, otp_base + HW_OCOTP_PDN_ULP);
+ }
+
+out:
+ mutex_unlock(&otp_mutex);
+ clk_disable_unprepare(otp_clk);
+ return ret ? 0 : sprintf(buf, "0x%x\n", value);
+}
+
+static int imx6_otp_write_bits(int addr, u32 data, u32 magic)
+{
+ u32 c; /* for control register */
+
+ /* init the control register */
+ c = __raw_readl(otp_base + HW_OCOTP_CTRL);
+ c &= ~BM_OCOTP_CTRL_ADDR;
+ c |= BF(addr, OCOTP_CTRL_ADDR);
+ c |= BF(magic, OCOTP_CTRL_WR_UNLOCK);
+ __raw_writel(c, otp_base + HW_OCOTP_CTRL);
+
+ /* init the data register */
+ __raw_writel(data, otp_base + HW_OCOTP_DATA);
+ otp_wait_busy(0);
+
+ mdelay(2); /* Write Postamble */
+
+ return 0;
+}
+
+static int imx7ulp_otp_write_bits(int addr, u32 data, u32 magic)
+{
+ u32 c; /* for control register */
+
+ /* init the control register */
+ c = __raw_readl(otp_base + HW_OCOTP_CTRL);
+ c &= ~BM_OCOTP_CTRL_ADDR_MX7ULP;
+ c |= BF(addr, OCOTP_CTRL_ADDR_MX7ULP);
+ c |= BF(magic, OCOTP_CTRL_WR_UNLOCK);
+ __raw_writel(c, otp_base + HW_OCOTP_CTRL);
+
+ /* init the data register */
+ __raw_writel(data, otp_base + HW_OCOTP_DATA);
+ otp_wait_busy(0);
+
+ mdelay(2); /* Write Postamble */
+
+ return 0;
+}
+
+static int imx7_otp_write_bits(int addr, u32 data, u32 magic)
+{
+ u32 c; /* for control register */
+
+ /* init the control register */
+ c = __raw_readl(otp_base + HW_OCOTP_CTRL);
+ c &= ~BM_OCOTP_CTRL_ADDR_MX7D;
+ /* convert to bank address */
+ c |= BF((addr >> 2), OCOTP_CTRL_ADDR);
+ c |= BF(magic, OCOTP_CTRL_WR_UNLOCK);
+ __raw_writel(c, otp_base + HW_OCOTP_CTRL);
+
+ /* init the data register */
+ switch (addr & 0x3) {
+ case 0:
+ __raw_writel(0, otp_base + HW_OCOTP_DATA1_MX7D);
+ __raw_writel(0, otp_base + HW_OCOTP_DATA2_MX7D);
+ __raw_writel(0, otp_base + HW_OCOTP_DATA3_MX7D);
+ __raw_writel(data, otp_base + HW_OCOTP_DATA0_MX7D);
+ break;
+ case 1:
+ __raw_writel(data, otp_base + HW_OCOTP_DATA1_MX7D);
+ __raw_writel(0, otp_base + HW_OCOTP_DATA2_MX7D);
+ __raw_writel(0, otp_base + HW_OCOTP_DATA3_MX7D);
+ __raw_writel(0, otp_base + HW_OCOTP_DATA0_MX7D);
+ break;
+ case 2:
+ __raw_writel(0, otp_base + HW_OCOTP_DATA1_MX7D);
+ __raw_writel(data, otp_base + HW_OCOTP_DATA2_MX7D);
+ __raw_writel(0, otp_base + HW_OCOTP_DATA3_MX7D);
+ __raw_writel(0, otp_base + HW_OCOTP_DATA0_MX7D);
+ break;
+ case 3:
+ __raw_writel(0, otp_base + HW_OCOTP_DATA1_MX7D);
+ __raw_writel(0, otp_base + HW_OCOTP_DATA2_MX7D);
+ __raw_writel(data, otp_base + HW_OCOTP_DATA3_MX7D);
+ __raw_writel(0, otp_base + HW_OCOTP_DATA0_MX7D);
+ break;
+ }
+ __raw_writel(data, otp_base + HW_OCOTP_DATA);
+ otp_wait_busy(0);
+
+ mdelay(2); /* Write Postamble */
+
+ return 0;
+
+}
+
+static ssize_t fsl_otp_store(struct kobject *kobj, struct kobj_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned int index = attr - otp_kattr;
+ unsigned int phy_index;
+ unsigned long value;
+ unsigned long tmp;
+ int ret;
+
+ if (!fsl_otp)
+ return -ENODEV;
+
+ ret = kstrtoul(buf, 16, &value);
+ if (ret < 0)
+ return -EINVAL;
+
+ ret = clk_prepare_enable(otp_clk);
+ if (ret)
+ return -ENODEV;
+
+ mutex_lock(&otp_mutex);
+
+ phy_index = fsl_otp_word_physical(fsl_otp, index);
+ if ((fsl_otp->devtype == FSL_OTP_MX7ULP) && (phy_index > 15)) {
+ fsl_otp->set_otp_timing();
+ ret = otp_wait_busy(0);
+ if (ret)
+ goto out;
+
+ tmp = __raw_readl(otp_base + HW_OCOTP_OUT_STATUS_ULP);
+ if (tmp & BM_OUT_STATUS_DED_ULP) {
+ __raw_writel(BM_OUT_STATUS_DED_ULP, otp_base + HW_OCOTP_OUT_STATUS_CLR_ULP);
+ goto out;
+ }
+
+ tmp = __raw_readl(otp_base + HW_OCOTP_CUST_N(phy_index));
+
+ __raw_writel(1, otp_base + HW_OCOTP_PDN_ULP);
+
+ if (tmp != 0) {
+ ret = -EPERM;
+ goto out;
+ }
+ }
+
+ fsl_otp->set_otp_timing();
+ ret = otp_wait_busy(0);
+ if (ret)
+ goto out;
+
+ if (fsl_otp->devtype == FSL_OTP_MX7D)
+ imx7_otp_write_bits(index, value, 0x3e77);
+ else if (fsl_otp->devtype == FSL_OTP_MX7ULP)
+ imx7ulp_otp_write_bits(index, value, 0x3e77);
+ else
+ imx6_otp_write_bits(index, value, 0x3e77);
+
+ if (fsl_otp->devtype == FSL_OTP_MX7ULP) {
+ value = __raw_readl(otp_base + HW_OCOTP_OUT_STATUS_ULP);
+ if (value & (BM_OUT_STATUS_LOCKED | BM_OUT_STATUS_PROGFAIL))
+ printk("ulp prog fail\n");
+
+ otp_wait_busy(0);
+ }
+
+ /* Reload all the shadow registers */
+ __raw_writel(BM_OCOTP_CTRL_RELOAD_SHADOWS,
+ otp_base + HW_OCOTP_CTRL_SET);
+ udelay(1);
+ otp_wait_busy(BM_OCOTP_CTRL_RELOAD_SHADOWS);
+
+ if (fsl_otp->devtype == FSL_OTP_MX7ULP) {
+ __raw_writel(1, otp_base + HW_OCOTP_PDN_ULP);
+ }
+
+out:
+ mutex_unlock(&otp_mutex);
+ clk_disable_unprepare(otp_clk);
+ return ret ? ret : count;
+}
+
+static const struct of_device_id fsl_otp_dt_ids[] = {
+ { .compatible = "fsl,imx6q-ocotp", .data = (void *)&imx6q_data, },
+ { .compatible = "fsl,imx6sl-ocotp", .data = (void *)&imx6sl_data, },
+ { .compatible = "fsl,imx6sll-ocotp", .data = (void *)&imx6sll_data, },
+ { .compatible = "fsl,imx6ul-ocotp", .data = (void *)&imx6ul_data, },
+ { .compatible = "fsl,imx6ull-ocotp", .data = (void *)&imx6ull_data, },
+ { .compatible = "fsl,imx7d-ocotp", .data = (void *)&imx7d_data, },
+ { .compatible = "fsl,imx7ulp-ocotp", .data = (void *)&imx7ulp_data, },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, fsl_otp_dt_ids);
+
+static int fsl_otp_probe(struct platform_device *pdev)
+{
+ struct resource *res;
+ struct attribute **attrs;
+ const char **desc;
+ int i, num;
+ int ret;
+ const struct of_device_id *of_id =
+ of_match_device(fsl_otp_dt_ids, &pdev->dev);
+
+ fsl_otp = (struct fsl_otp_devtype_data *)of_id->data;
+ if (!fsl_otp) {
+ dev_err(&pdev->dev, "No driver data provided!\n");
+ return -ENODEV;
+ }
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ otp_base = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(otp_base)) {
+ ret = PTR_ERR(otp_base);
+ dev_err(&pdev->dev, "failed to ioremap resource: %d\n", ret);
+ return ret;
+ }
+
+ otp_clk = devm_clk_get(&pdev->dev, NULL);
+ if (IS_ERR(otp_clk)) {
+ ret = PTR_ERR(otp_clk);
+ dev_err(&pdev->dev, "failed to get clock: %d\n", ret);
+ return ret;
+ }
+
+ desc = fsl_otp->bank_desc;
+ num = fsl_otp->fuse_nums;
+
+ /* The last one is NULL, which is used to detect the end */
+ attrs = devm_kzalloc(&pdev->dev, (num + 1) * sizeof(*attrs),
+ GFP_KERNEL);
+ otp_kattr = devm_kzalloc(&pdev->dev, num * sizeof(*otp_kattr),
+ GFP_KERNEL);
+ otp_attr_group = devm_kzalloc(&pdev->dev, sizeof(*otp_attr_group),
+ GFP_KERNEL);
+ if (!attrs || !otp_kattr || !otp_attr_group)
+ return -ENOMEM;
+
+ for (i = 0; i < num; i++) {
+ sysfs_attr_init(&otp_kattr[i].attr);
+ otp_kattr[i].attr.name = desc[i];
+ otp_kattr[i].attr.mode = 0600;
+ otp_kattr[i].show = fsl_otp_show;
+ otp_kattr[i].store = fsl_otp_store;
+ attrs[i] = &otp_kattr[i].attr;
+ }
+ otp_attr_group->attrs = attrs;
+
+ otp_kobj = kobject_create_and_add("fsl_otp", NULL);
+ if (!otp_kobj) {
+ dev_err(&pdev->dev, "failed to add kobject\n");
+ return -ENOMEM;
+ }
+
+ ret = sysfs_create_group(otp_kobj, otp_attr_group);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to create sysfs group: %d\n", ret);
+ kobject_put(otp_kobj);
+ return ret;
+ }
+
+ mutex_init(&otp_mutex);
+
+ return 0;
+}
+
+static int fsl_otp_remove(struct platform_device *pdev)
+{
+ sysfs_remove_group(otp_kobj, otp_attr_group);
+ kobject_put(otp_kobj);
+
+ return 0;
+}
+
+static struct platform_driver fsl_otp_driver = {
+ .driver = {
+ .name = "imx-ocotp",
+ .owner = THIS_MODULE,
+ .of_match_table = fsl_otp_dt_ids,
+ },
+ .probe = fsl_otp_probe,
+ .remove = fsl_otp_remove,
+};
+module_platform_driver(fsl_otp_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Huang Shijie <b32955@freescale.com>");
+MODULE_DESCRIPTION("Freescale i.MX OCOTP driver");
diff --git a/drivers/char/hw_random/Kconfig b/drivers/char/hw_random/Kconfig
index 95a031e9eced..54f3ece8a779 100644
--- a/drivers/char/hw_random/Kconfig
+++ b/drivers/char/hw_random/Kconfig
@@ -267,6 +267,18 @@ config HW_RANDOM_IMX_RNGC
If unsure, say Y.
+config HW_RANDOM_IMX_RNG
+ tristate "Freescale RNG B/C Random Number Generator"
+ depends on HW_RANDOM && ARCH_MXC && HAVE_IMX_RNG
+ ---help---
+ This driver provides kernel-side support for the Random Number
+ Generator (RNGBB and RNGC) hardware found on Freescale i.MX processors.
+
+ To compile this driver as a module, choose M here: the
+ module will be called fsl-rngc.
+
+ If unsure, say Y.
+
config HW_RANDOM_NOMADIK
tristate "ST-Ericsson Nomadik Random Number Generator support"
depends on ARCH_NOMADIK
diff --git a/drivers/char/hw_random/Makefile b/drivers/char/hw_random/Makefile
index f3728d008fff..2addfa7f26c3 100644
--- a/drivers/char/hw_random/Makefile
+++ b/drivers/char/hw_random/Makefile
@@ -22,6 +22,7 @@ obj-$(CONFIG_HW_RANDOM_VIRTIO) += virtio-rng.o
obj-$(CONFIG_HW_RANDOM_TX4939) += tx4939-rng.o
obj-$(CONFIG_HW_RANDOM_MXC_RNGA) += mxc-rnga.o
obj-$(CONFIG_HW_RANDOM_IMX_RNGC) += imx-rngc.o
+obj-$(CONFIG_HW_RANDOM_IMX_RNG) += imx-rng.o
obj-$(CONFIG_HW_RANDOM_OCTEON) += octeon-rng.o
obj-$(CONFIG_HW_RANDOM_NOMADIK) += nomadik-rng.o
obj-$(CONFIG_HW_RANDOM_PSERIES) += pseries-rng.o
diff --git a/drivers/char/hw_random/imx-rng.c b/drivers/char/hw_random/imx-rng.c
new file mode 100644
index 000000000000..df9c13f7d325
--- /dev/null
+++ b/drivers/char/hw_random/imx-rng.c
@@ -0,0 +1,440 @@
+/*
+ * RNG driver for Freescale RNG B/C
+ *
+ * Copyright (C) 2008-2015 Freescale Semiconductor, Inc.
+ */
+
+/*
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/*
+ * Hardware driver for the Intel/AMD/VIA Random Number Generators (RNG)
+ * (c) Copyright 2003 Red Hat Inc <jgarzik@redhat.com>
+ *
+ * derived from
+ *
+ * Hardware driver for the AMD 768 Random Number Generator (RNG)
+ * (c) Copyright 2001 Red Hat Inc <alan@redhat.com>
+ *
+ * derived from
+ *
+ * Hardware driver for Intel i810 Random Number Generator (RNG)
+ * Copyright 2000,2001 Jeff Garzik <jgarzik@pobox.com>
+ * Copyright 2000,2001 Philipp Rumpf <prumpf@mandrakesoft.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.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+#include <linux/of_address.h>
+#include <linux/interrupt.h>
+#include <linux/hw_random.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+
+#define MODULE_NAME "imx-rng"
+
+#define RNGC_VERSION_MAJOR3 3
+
+#define RNGC_VERSION_ID 0x0000
+#define RNGC_COMMAND 0x0004
+#define RNGC_CONTROL 0x0008
+#define RNGC_STATUS 0x000C
+#define RNGC_ERROR 0x0010
+#define RNGC_FIFO 0x0014
+#define RNGC_VERIF_CTRL 0x0020
+#define RNGC_OSC_CTRL_COUNT 0x0028
+#define RNGC_OSC_COUNT 0x002C
+#define RNGC_OSC_COUNT_STATUS 0x0030
+
+#define RNGC_VERID_ZEROS_MASK 0x0f000000
+#define RNGC_VERID_RNG_TYPE_MASK 0xf0000000
+#define RNGC_VERID_RNG_TYPE_SHIFT 28
+#define RNGC_VERID_CHIP_VERSION_MASK 0x00ff0000
+#define RNGC_VERID_CHIP_VERSION_SHIFT 16
+#define RNGC_VERID_VERSION_MAJOR_MASK 0x0000ff00
+#define RNGC_VERID_VERSION_MAJOR_SHIFT 8
+#define RNGC_VERID_VERSION_MINOR_MASK 0x000000ff
+#define RNGC_VERID_VERSION_MINOR_SHIFT 0
+
+#define RNGC_CMD_ZEROS_MASK 0xffffff8c
+#define RNGC_CMD_SW_RST 0x00000040
+#define RNGC_CMD_CLR_ERR 0x00000020
+#define RNGC_CMD_CLR_INT 0x00000010
+#define RNGC_CMD_SEED 0x00000002
+#define RNGC_CMD_SELF_TEST 0x00000001
+
+#define RNGC_CTRL_ZEROS_MASK 0xfffffc8c
+#define RNGC_CTRL_CTL_ACC 0x00000200
+#define RNGC_CTRL_VERIF_MODE 0x00000100
+#define RNGC_CTRL_MASK_ERROR 0x00000040
+
+#define RNGC_CTRL_MASK_DONE 0x00000020
+#define RNGC_CTRL_AUTO_SEED 0x00000010
+#define RNGC_CTRL_FIFO_UFLOW_MASK 0x00000003
+#define RNGC_CTRL_FIFO_UFLOW_SHIFT 0
+
+#define RNGC_CTRL_FIFO_UFLOW_ZEROS_ERROR 0
+#define RNGC_CTRL_FIFO_UFLOW_ZEROS_ERROR2 1
+#define RNGC_CTRL_FIFO_UFLOW_BUS_XFR 2
+#define RNGC_CTRL_FIFO_UFLOW_ZEROS_INTR 3
+
+#define RNGC_STATUS_ST_PF_MASK 0x00c00000
+#define RNGC_STATUS_ST_PF_SHIFT 22
+#define RNGC_STATUS_ST_PF_TRNG 0x00800000
+#define RNGC_STATUS_ST_PF_PRNG 0x00400000
+#define RNGC_STATUS_ERROR 0x00010000
+#define RNGC_STATUS_FIFO_SIZE_MASK 0x0000f000
+#define RNGC_STATUS_FIFO_SIZE_SHIFT 12
+#define RNGC_STATUS_FIFO_LEVEL_MASK 0x00000f00
+#define RNGC_STATUS_FIFO_LEVEL_SHIFT 8
+#define RNGC_STATUS_NEXT_SEED_DONE 0x00000040
+#define RNGC_STATUS_SEED_DONE 0x00000020
+#define RNGC_STATUS_ST_DONE 0x00000010
+#define RNGC_STATUS_RESEED 0x00000008
+#define RNGC_STATUS_SLEEP 0x00000004
+#define RNGC_STATUS_BUSY 0x00000002
+#define RNGC_STATUS_SEC_STATE 0x00000001
+
+#define RNGC_ERROR_STATUS_ZEROS_MASK 0xffffffc0
+#define RNGC_ERROR_STATUS_BAD_KEY 0x00000040
+#define RNGC_ERROR_STATUS_RAND_ERR 0x00000020
+#define RNGC_ERROR_STATUS_FIFO_ERR 0x00000010
+#define RNGC_ERROR_STATUS_STAT_ERR 0x00000008
+#define RNGC_ERROR_STATUS_ST_ERR 0x00000004
+#define RNGC_ERROR_STATUS_OSC_ERR 0x00000002
+#define RNGC_ERROR_STATUS_LFSR_ERR 0x00000001
+
+#define RNG_ADDR_RANGE 0x34
+
+static DECLARE_COMPLETION(rng_self_testing);
+static DECLARE_COMPLETION(rng_seed_done);
+
+static struct platform_device *imx_rng_dev;
+
+struct imx_rng_priv_data {
+ void __iomem *reg_base;
+};
+
+int irq_rng;
+
+static int imx_rng_data_present(struct hwrng *rng, int wait)
+{
+ int level;
+ struct imx_rng_priv_data *prv = (struct imx_rng_priv_data *)rng->priv;
+
+ /* how many random numbers are in FIFO? [0-16] */
+ level = (readl(prv->reg_base + RNGC_STATUS) &
+ RNGC_STATUS_FIFO_LEVEL_MASK) >> RNGC_STATUS_FIFO_LEVEL_SHIFT;
+
+ return level > 0 ? 1 : 0;
+}
+
+static int imx_rng_data_read(struct hwrng *rng, u32 *data)
+{
+ int err;
+ struct imx_rng_priv_data *prv = (struct imx_rng_priv_data *)rng->priv;
+
+ /* retrieve a random number from FIFO */
+ *data = readl(prv->reg_base + RNGC_FIFO);
+
+ /* is there some error while reading this random number? */
+ err = readl(prv->reg_base + RNGC_STATUS) & RNGC_STATUS_ERROR;
+
+ /* if error happened doesn't return random number */
+ return err ? 0 : 4;
+}
+
+static irqreturn_t imx_rng_irq(int irq, void *dev)
+{
+ int handled = 0;
+ struct imx_rng_priv_data *prv = (struct imx_rng_priv_data *)dev;
+
+ /* is the seed creation done? */
+ if (readl(prv->reg_base + RNGC_STATUS) & RNGC_STATUS_SEED_DONE) {
+ complete(&rng_seed_done);
+ writel(RNGC_CMD_CLR_INT | RNGC_CMD_CLR_ERR,
+ prv->reg_base + RNGC_COMMAND);
+ handled = 1;
+ }
+
+ /* is the self test done? */
+ if (readl(prv->reg_base + RNGC_STATUS) & RNGC_STATUS_ST_DONE) {
+ complete(&rng_self_testing);
+ writel(RNGC_CMD_CLR_INT | RNGC_CMD_CLR_ERR,
+ prv->reg_base + RNGC_COMMAND);
+ handled = 1;
+ }
+
+ /* is there any error? */
+ if (readl(prv->reg_base + RNGC_STATUS) & RNGC_STATUS_ERROR) {
+ /* clear interrupt */
+ writel(RNGC_CMD_CLR_INT | RNGC_CMD_CLR_ERR,
+ prv->reg_base + RNGC_COMMAND);
+ handled = 1;
+ }
+
+ return handled;
+}
+
+static int imx_rng_init(struct hwrng *rng)
+{
+ int err;
+ struct imx_rng_priv_data *prv = (struct imx_rng_priv_data *)rng->priv;
+ u32 cmd, ctrl, osc;
+
+ reinit_completion(&rng_self_testing);
+ reinit_completion(&rng_seed_done);
+
+ err = readl(prv->reg_base + RNGC_STATUS) & RNGC_STATUS_ERROR;
+ if (err) {
+ /* is this a bad keys error ? */
+ if (readl(prv->reg_base + RNGC_ERROR) &
+ RNGC_ERROR_STATUS_BAD_KEY) {
+ dev_err(&imx_rng_dev->dev, "Can't start, Bad Keys.\n");
+ return -EIO;
+ }
+ }
+
+ /* mask all interrupts, will be unmasked soon */
+ ctrl = readl(prv->reg_base + RNGC_CONTROL);
+ writel(ctrl | RNGC_CTRL_MASK_DONE | RNGC_CTRL_MASK_ERROR,
+ prv->reg_base + RNGC_CONTROL);
+
+ /* verify if oscillator is working */
+ osc = readl(prv->reg_base + RNGC_ERROR);
+ if (osc & RNGC_ERROR_STATUS_OSC_ERR) {
+ dev_err(&imx_rng_dev->dev, "RNGC Oscillator is dead!\n");
+ return -EIO;
+ }
+
+ err = request_irq(irq_rng, imx_rng_irq,
+ 0, "imx-rng", (void *)rng->priv);
+ if (err) {
+ dev_err(&imx_rng_dev->dev, "Can't get interrupt working.\n");
+ return -EIO;
+ }
+
+ /* do self test, repeat until get success */
+ do {
+ /* clear error */
+ cmd = readl(prv->reg_base + RNGC_COMMAND);
+ writel(cmd | RNGC_CMD_CLR_ERR, prv->reg_base + RNGC_COMMAND);
+
+ /* unmask all interrupt */
+ ctrl = readl(prv->reg_base + RNGC_CONTROL);
+ writel(ctrl & ~(RNGC_CTRL_MASK_DONE | RNGC_CTRL_MASK_ERROR),
+ prv->reg_base + RNGC_CONTROL);
+
+ /* run self test */
+ cmd = readl(prv->reg_base + RNGC_COMMAND);
+ writel(cmd | RNGC_CMD_SELF_TEST,
+ prv->reg_base + RNGC_COMMAND);
+
+ wait_for_completion(&rng_self_testing);
+
+ } while (readl(prv->reg_base + RNGC_ERROR) &
+ RNGC_ERROR_STATUS_ST_ERR);
+
+ /* clear interrupt. Is it really necessary here? */
+ writel(RNGC_CMD_CLR_INT | RNGC_CMD_CLR_ERR,
+ prv->reg_base + RNGC_COMMAND);
+
+ /* create seed, repeat while there is some statistical error */
+ do {
+ /* clear error */
+ cmd = readl(prv->reg_base + RNGC_COMMAND);
+ writel(cmd | RNGC_CMD_CLR_ERR, prv->reg_base + RNGC_COMMAND);
+
+ /* seed creation */
+ cmd = readl(prv->reg_base + RNGC_COMMAND);
+ writel(cmd | RNGC_CMD_SEED, prv->reg_base + RNGC_COMMAND);
+
+ wait_for_completion(&rng_seed_done);
+
+ } while (readl(prv->reg_base + RNGC_ERROR) &
+ RNGC_ERROR_STATUS_STAT_ERR);
+
+ err = readl(prv->reg_base + RNGC_ERROR) &
+ (RNGC_ERROR_STATUS_STAT_ERR |
+ RNGC_ERROR_STATUS_RAND_ERR |
+ RNGC_ERROR_STATUS_FIFO_ERR |
+ RNGC_ERROR_STATUS_ST_ERR |
+ RNGC_ERROR_STATUS_OSC_ERR |
+ RNGC_ERROR_STATUS_LFSR_ERR);
+
+ if (err) {
+ dev_err(&imx_rng_dev->dev, "iMX RNG appears inoperable.\n");
+ return -EIO;
+ }
+
+ return 0;
+}
+
+static struct hwrng imx_rng = {
+ .name = "imx-rng",
+ .init = imx_rng_init,
+ .data_present = imx_rng_data_present,
+ .data_read = imx_rng_data_read
+};
+
+static int __init imx_rng_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct device_node *np = dev->of_node;
+ struct clk *clk;
+ struct imx_rng_priv_data *priv;
+ int err = -ENODEV;
+
+ if (imx_rng_dev)
+ return -EBUSY;
+
+ /* Enable the clock */
+ clk = of_clk_get(np, 0);
+ if (IS_ERR(clk)) {
+ dev_err(dev, "Can not get clock.\n");
+ return PTR_ERR(clk);
+ }
+ clk_enable(clk);
+
+ /* Allocate private data memory */
+ priv = kzalloc(sizeof(struct imx_rng_priv_data), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ imx_rng.priv = (unsigned long)priv;
+ dev_set_drvdata(dev, priv);
+
+ /* ioremap that register space */
+ priv->reg_base = of_iomap(np, 0);
+ if (!priv->reg_base) {
+ kfree(priv);
+ dev_err(dev, "Failed to remap register space.\n");
+ return -ENODEV;
+ }
+
+ irq_rng = platform_get_irq(pdev, 0);
+
+ err = hwrng_register(&imx_rng);
+ if (err) {
+ iounmap(priv->reg_base);
+ kfree(priv);
+ dev_err(dev, "failed to register hwrng (%d)\n", err);
+ return err;
+ }
+
+ imx_rng_dev = pdev;
+ dev_info(dev, "iMX RNG Registered.\n");
+
+ return 0;
+}
+
+static int __exit imx_rng_remove(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct device_node *np = dev->of_node;
+ struct clk *clk;
+ struct imx_rng_priv_data *priv = dev_get_drvdata(dev);
+
+ /* Disable the clock */
+ clk = of_clk_get(np, 0);
+
+ if (IS_ERR(clk))
+ dev_err(dev, "Can not get clock.\n");
+ else
+ clk_disable(clk);
+
+ hwrng_unregister(&imx_rng);
+
+ iounmap(priv->reg_base);
+
+ kfree(priv);
+
+ return 0;
+}
+
+static int imx_rng_suspend(struct platform_device *pdev, pm_message_t state)
+{
+#ifdef CONFIG_PM
+ struct device *dev = &pdev->dev;
+ struct device_node *np = dev->of_node;
+ struct clk *clk = of_clk_get(np, 0);
+
+ if (IS_ERR(clk)) {
+ dev_err(&pdev->dev, "Can not get rng_clk\n");
+ return PTR_ERR(clk);
+ }
+
+ clk_disable(clk);
+#endif
+
+ return 0;
+}
+
+static int imx_rng_resume(struct platform_device *pdev)
+{
+#ifdef CONFIG_PM
+ struct device *dev = &pdev->dev;
+ struct device_node *np = dev->of_node;
+ struct clk *clk = of_clk_get(np, 0);
+
+ if (IS_ERR(clk)) {
+ dev_err(&pdev->dev, "Can not get rng_clk\n");
+ return PTR_ERR(clk);
+ }
+
+ clk_enable(clk);
+#endif
+
+ return 0;
+}
+
+static struct of_device_id imx_rng_dt_ids[] = {
+ { .compatible = "imx-rng",},
+ { .compatible = "fsl,imx-rng",},
+ { .compatible = "fsl,imx6sl-rng",},
+ { },
+};
+
+MODULE_DEVICE_TABLE(of, imx_rng_dt_ids);
+
+static struct platform_driver imx_rng_driver = {
+ .driver = {
+ .name = MODULE_NAME,
+ .owner = THIS_MODULE,
+ .of_match_table = imx_rng_dt_ids,
+ },
+ .remove = __exit_p(imx_rng_remove),
+ .suspend = imx_rng_suspend,
+ .resume = imx_rng_resume,
+};
+
+static int __init mod_init(void)
+{
+ return platform_driver_probe(&imx_rng_driver, imx_rng_probe);
+}
+
+static void __exit mod_exit(void)
+{
+ platform_driver_unregister(&imx_rng_driver);
+}
+
+module_init(mod_init);
+module_exit(mod_exit);
+
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("H/W RNG(B/C) driver for i.MX");
+MODULE_LICENSE("GPL");
diff --git a/drivers/char/imx_amp/Kconfig b/drivers/char/imx_amp/Kconfig
new file mode 100644
index 000000000000..1f892f8daccb
--- /dev/null
+++ b/drivers/char/imx_amp/Kconfig
@@ -0,0 +1,9 @@
+#
+# imx mcc
+#
+
+config IMX_SEMA4
+ bool "IMX SEMA4 driver"
+ depends on SOC_IMX6SX
+ help
+ Support for IMX SEMA4 driver, most people should say N here.
diff --git a/drivers/char/imx_amp/Makefile b/drivers/char/imx_amp/Makefile
new file mode 100644
index 000000000000..4e7a91691b39
--- /dev/null
+++ b/drivers/char/imx_amp/Makefile
@@ -0,0 +1,5 @@
+#
+# Makefile for imx mcc
+#
+#
+obj-$(CONFIG_IMX_SEMA4) += imx_sema4.o
diff --git a/drivers/char/imx_amp/imx_sema4.c b/drivers/char/imx_amp/imx_sema4.c
new file mode 100644
index 000000000000..412202f11cbb
--- /dev/null
+++ b/drivers/char/imx_amp/imx_sema4.c
@@ -0,0 +1,413 @@
+/*
+ * Copyright (C) 2014 Freescale Semiconductor, Inc.
+ */
+
+/*
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/err.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/wait.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/imx_sema4.h>
+
+static struct imx_sema4_mutex_device *imx6_sema4;
+
+/*!
+ * \brief mutex create function.
+ *
+ * This function allocates imx_sema4_mutex structure and returns a handle
+ * to it. The mutex to be created is identified by SEMA4 device number and mutex
+ * (gate) number. The handle is used to reference the created mutex in calls to
+ * other imx_sema4_mutex API functions. This function is to be called only
+ * once for each mutex.
+ *
+ * \param[in] dev_num SEMA4 device (module) number.
+ * \param[in] mutex_num Mutex (gate) number.
+ *
+ * \return NULL (Failure.)
+ * \return imx_sema4_mutex (Success.)
+ */
+struct imx_sema4_mutex *
+imx_sema4_mutex_create(u32 dev_num, u32 mutex_num)
+{
+ struct imx_sema4_mutex *mutex_ptr = NULL;
+
+ if (mutex_num >= SEMA4_NUM_GATES || dev_num >= SEMA4_NUM_DEVICES)
+ goto out;
+
+ if (imx6_sema4->cpine_val & (1 < mutex_num)) {
+ pr_err("Error: requiring a allocated sema4.\n");
+ pr_err("mutex_num %d cpine_val 0x%08x.\n",
+ mutex_num, imx6_sema4->cpine_val);
+ }
+ mutex_ptr = kzalloc(sizeof(*mutex_ptr), GFP_KERNEL);
+ if (!mutex_ptr)
+ goto out;
+ imx6_sema4->mutex_ptr[mutex_num] = mutex_ptr;
+ imx6_sema4->alloced |= 1 < mutex_num;
+ imx6_sema4->cpine_val |= idx_sema4[mutex_num];
+ writew(imx6_sema4->cpine_val, imx6_sema4->ioaddr + SEMA4_CP0INE);
+
+ mutex_ptr->valid = CORE_MUTEX_VALID;
+ mutex_ptr->gate_num = mutex_num;
+ init_waitqueue_head(&mutex_ptr->wait_q);
+
+out:
+ return mutex_ptr;
+}
+EXPORT_SYMBOL(imx_sema4_mutex_create);
+
+/*!
+ * \brief mutex destroy function.
+ *
+ * This function destroys a mutex.
+ *
+ * \param[in] mutex_ptr Pointer to mutex structure.
+ *
+ * \return MQX_COMPONENT_DOES_NOT_EXIST (mutex component not installed.)
+ * \return MQX_INVALID_PARAMETER (Wrong input parameter.)
+ * \return COREMUTEX_OK (Success.)
+ *
+ */
+int imx_sema4_mutex_destroy(struct imx_sema4_mutex *mutex_ptr)
+{
+ u32 mutex_num;
+
+ if ((mutex_ptr == NULL) || (mutex_ptr->valid != CORE_MUTEX_VALID))
+ return -EINVAL;
+
+ mutex_num = mutex_ptr->gate_num;
+ if ((imx6_sema4->cpine_val & idx_sema4[mutex_num]) == 0) {
+ pr_err("Error: trying to destroy a un-allocated sema4.\n");
+ pr_err("mutex_num %d cpine_val 0x%08x.\n",
+ mutex_num, imx6_sema4->cpine_val);
+ }
+ imx6_sema4->mutex_ptr[mutex_num] = NULL;
+ imx6_sema4->alloced &= ~(1 << mutex_num);
+ imx6_sema4->cpine_val &= ~(idx_sema4[mutex_num]);
+ writew(imx6_sema4->cpine_val, imx6_sema4->ioaddr + SEMA4_CP0INE);
+
+ kfree(mutex_ptr);
+
+ return 0;
+}
+EXPORT_SYMBOL(imx_sema4_mutex_destroy);
+
+/*!
+ * \brief Lock the mutex, shouldn't be interruted by INT.
+ *
+ * This function attempts to lock a mutex. If the mutex is already locked
+ * by another task the function return -EBUSY, and tell invoker wait until
+ * it is possible to lock the mutex.
+ *
+ * \param[in] mutex_ptr Pointer to mutex structure.
+ *
+ * \return MQX_INVALID_POINTER (Wrong pointer to the mutex structure provided.)
+ * \return COREMUTEX_OK (mutex successfully locked.)
+ *
+ * \see imx_sema4_mutex_unlock
+ */
+int _imx_sema4_mutex_lock(struct imx_sema4_mutex *mutex_ptr)
+{
+ int ret = 0, i = 0;
+
+ if ((mutex_ptr == NULL) || (mutex_ptr->valid != CORE_MUTEX_VALID))
+ return -EINVAL;
+
+ i = mutex_ptr->gate_num;
+ mutex_ptr->gate_val = readb(imx6_sema4->ioaddr + i);
+ mutex_ptr->gate_val &= SEMA4_GATE_MASK;
+ /* Check to see if this core already own it */
+ if (mutex_ptr->gate_val == SEMA4_A9_LOCK) {
+ /* return -EBUSY, invoker should be in sleep, and re-lock ag */
+ pr_err("%s -> %s %d already locked, wait! num %d val %d.\n",
+ __FILE__, __func__, __LINE__,
+ i, mutex_ptr->gate_val);
+ ret = -EBUSY;
+ goto out;
+ } else {
+ /* try to lock the mutex */
+ mutex_ptr->gate_val = readb(imx6_sema4->ioaddr + i);
+ mutex_ptr->gate_val &= (~SEMA4_GATE_MASK);
+ mutex_ptr->gate_val |= SEMA4_A9_LOCK;
+ writeb(mutex_ptr->gate_val, imx6_sema4->ioaddr + i);
+ mutex_ptr->gate_val = readb(imx6_sema4->ioaddr + i);
+ mutex_ptr->gate_val &= SEMA4_GATE_MASK;
+ /* double check the mutex is locked, otherwise, return -EBUSY */
+ if (mutex_ptr->gate_val != SEMA4_A9_LOCK) {
+ pr_debug("wait-locked num %d val %d.\n",
+ i, mutex_ptr->gate_val);
+ ret = -EBUSY;
+ }
+ }
+out:
+ return ret;
+}
+
+/* !
+ * \brief Try to lock the core mutex.
+ *
+ * This function attempts to lock a mutex. If the mutex is successfully locked
+ * for the calling task, SEMA4_A9_LOCK is returned. If the mutex is already
+ * locked by another task, the function does not block but rather returns
+ * negative immediately.
+ *
+ * \param[in] mutex_ptr Pointer to core_mutex structure.
+ *
+ * \return SEMA4_A9_LOCK (mutex successfully locked.)
+ * \return negative (mutex not locked.)
+ *
+ */
+int imx_sema4_mutex_trylock(struct imx_sema4_mutex *mutex_ptr)
+{
+ int ret = 0;
+
+ ret = _imx_sema4_mutex_lock(mutex_ptr);
+ if (ret == 0)
+ return SEMA4_A9_LOCK;
+ else
+ return ret;
+}
+EXPORT_SYMBOL(imx_sema4_mutex_trylock);
+
+/*!
+ * \brief Invoke _imx_sema4_mutex_lock to lock the mutex.
+ *
+ * This function attempts to lock a mutex. If the mutex is already locked
+ * by another task the function, sleep itself and schedule out.
+ * Wait until it is possible to lock the mutex.
+ *
+ * Invoker should add its own wait queue into the wait queue header of the
+ * required semaphore, set TASK_INTERRUPTIBLE and sleep on itself by
+ * schedule() when the lock is failed. Re-try to lock the semaphore when
+ * it is woke up by the sema4 isr.
+ *
+ * \param[in] mutex_ptr Pointer to mutex structure.
+ *
+ * \return SEMA4_A9_LOCK (mutex successfully locked.)
+ *
+ * \see imx_sema4_mutex_unlock
+ */
+int imx_sema4_mutex_lock(struct imx_sema4_mutex *mutex_ptr)
+{
+ int ret = 0;
+ unsigned long flags;
+
+ spin_lock_irqsave(&imx6_sema4->lock, flags);
+ ret = _imx_sema4_mutex_lock(mutex_ptr);
+ spin_unlock_irqrestore(&imx6_sema4->lock, flags);
+ while (-EBUSY == ret) {
+ spin_lock_irqsave(&imx6_sema4->lock, flags);
+ ret = _imx_sema4_mutex_lock(mutex_ptr);
+ spin_unlock_irqrestore(&imx6_sema4->lock, flags);
+ if (ret == 0)
+ break;
+ }
+
+ return ret;
+}
+EXPORT_SYMBOL(imx_sema4_mutex_lock);
+
+/*!
+ * \brief Unlock the mutex.
+ *
+ * This function unlocks the specified mutex.
+ *
+ * \param[in] mutex_ptr Pointer to mutex structure.
+ *
+ * \return -EINVAL (Wrong pointer to the mutex structure provided.)
+ * \return -EINVAL (This mutex has not been locked by this core.)
+ * \return 0 (mutex successfully unlocked.)
+ *
+ * \see imx_sema4_mutex_lock
+ */
+int imx_sema4_mutex_unlock(struct imx_sema4_mutex *mutex_ptr)
+{
+ int ret = 0, i = 0;
+
+ if ((mutex_ptr == NULL) || (mutex_ptr->valid != CORE_MUTEX_VALID))
+ return -EINVAL;
+
+ i = mutex_ptr->gate_num;
+ mutex_ptr->gate_val = readb(imx6_sema4->ioaddr + i);
+ mutex_ptr->gate_val &= SEMA4_GATE_MASK;
+ /* make sure it is locked by this core */
+ if (mutex_ptr->gate_val != SEMA4_A9_LOCK) {
+ pr_err("%d Trying to unlock an unlock mutex.\n", __LINE__);
+ ret = -EINVAL;
+ goto out;
+ }
+ /* unlock it */
+ mutex_ptr->gate_val = readb(imx6_sema4->ioaddr + i);
+ mutex_ptr->gate_val &= (~SEMA4_GATE_MASK);
+ writeb(mutex_ptr->gate_val | SEMA4_UNLOCK, imx6_sema4->ioaddr + i);
+ mutex_ptr->gate_val = readb(imx6_sema4->ioaddr + i);
+ mutex_ptr->gate_val &= SEMA4_GATE_MASK;
+ /* make sure it is locked by this core */
+ if (mutex_ptr->gate_val == SEMA4_A9_LOCK)
+ pr_err("%d ERROR, failed to unlock the mutex.\n", __LINE__);
+
+out:
+ return ret;
+}
+EXPORT_SYMBOL(imx_sema4_mutex_unlock);
+
+/*
+ * isr used by SEMA4, wake up the sleep tasks if there are the tasks waiting
+ * for locking semaphore.
+ * FIXME the bits order of the gatn, cpnie, cpnntf are not exact identified yet!
+ */
+static irqreturn_t imx_sema4_isr(int irq, void *dev_id)
+{
+ int i;
+ struct imx_sema4_mutex *mutex_ptr;
+ unsigned int mask;
+ struct imx_sema4_mutex_device *imx6_sema4 = dev_id;
+
+ imx6_sema4->cpntf_val = readw(imx6_sema4->ioaddr + SEMA4_CP0NTF);
+ for (i = 0; i < SEMA4_NUM_GATES; i++) {
+ mask = idx_sema4[i];
+ if ((imx6_sema4->cpntf_val) & mask) {
+ mutex_ptr = imx6_sema4->mutex_ptr[i];
+ /*
+ * An interrupt is pending on this mutex, the only way
+ * to clear it is to lock it (either by this core or
+ * another).
+ */
+ mutex_ptr->gate_val = readb(imx6_sema4->ioaddr + i);
+ mutex_ptr->gate_val &= (~SEMA4_GATE_MASK);
+ mutex_ptr->gate_val |= SEMA4_A9_LOCK;
+ writeb(mutex_ptr->gate_val, imx6_sema4->ioaddr + i);
+ mutex_ptr->gate_val = readb(imx6_sema4->ioaddr + i);
+ mutex_ptr->gate_val &= SEMA4_GATE_MASK;
+ if (mutex_ptr->gate_val == SEMA4_A9_LOCK) {
+ /*
+ * wake up the wait queue, whatever there
+ * are wait task or not.
+ * NOTE: check gate is locted or not in
+ * sema4_lock func by wait task.
+ */
+ mutex_ptr->gate_val =
+ readb(imx6_sema4->ioaddr + i);
+ mutex_ptr->gate_val &= (~SEMA4_GATE_MASK);
+ mutex_ptr->gate_val |= SEMA4_UNLOCK;
+
+ writeb(mutex_ptr->gate_val,
+ imx6_sema4->ioaddr + i);
+ wake_up(&mutex_ptr->wait_q);
+ } else {
+ pr_debug("can't lock gate%d %s retry!\n", i,
+ mutex_ptr->gate_val ?
+ "locked by m4" : "");
+ }
+ }
+ }
+
+ return IRQ_HANDLED;
+}
+
+static const struct of_device_id imx_sema4_dt_ids[] = {
+ { .compatible = "fsl,imx6sx-sema4", },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, imx_sema4_dt_ids);
+
+static int imx_sema4_probe(struct platform_device *pdev)
+{
+ struct resource *res;
+ int ret;
+
+ imx6_sema4 = devm_kzalloc(&pdev->dev, sizeof(*imx6_sema4), GFP_KERNEL);
+ if (!imx6_sema4)
+ return -ENOMEM;
+
+ imx6_sema4->dev = &pdev->dev;
+ imx6_sema4->cpine_val = 0;
+ spin_lock_init(&imx6_sema4->lock);
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (IS_ERR(res)) {
+ dev_err(&pdev->dev, "unable to get imx sema4 resource 0\n");
+ ret = -ENODEV;
+ goto err;
+ }
+
+ imx6_sema4->ioaddr = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(imx6_sema4->ioaddr)) {
+ ret = PTR_ERR(imx6_sema4->ioaddr);
+ goto err;
+ }
+
+ imx6_sema4->irq = platform_get_irq(pdev, 0);
+ if (!imx6_sema4->irq) {
+ dev_err(&pdev->dev, "failed to get irq\n");
+ ret = -ENODEV;
+ goto err;
+ }
+
+ ret = devm_request_irq(&pdev->dev, imx6_sema4->irq, imx_sema4_isr,
+ IRQF_SHARED, "imx6sx-sema4", imx6_sema4);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to request imx sema4 irq\n");
+ ret = -ENODEV;
+ goto err;
+ }
+
+ platform_set_drvdata(pdev, imx6_sema4);
+
+err:
+ return ret;
+}
+
+static int imx_sema4_remove(struct platform_device *pdev)
+{
+ return 0;
+}
+
+static struct platform_driver imx_sema4_driver = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "imx-sema4",
+ .of_match_table = imx_sema4_dt_ids,
+ },
+ .probe = imx_sema4_probe,
+ .remove = imx_sema4_remove,
+};
+
+static int __init imx_sema4_init(void)
+{
+ int ret;
+
+ ret = platform_driver_register(&imx_sema4_driver);
+ if (ret)
+ pr_err("Unable to initialize sema4 driver\n");
+ else
+ pr_info("imx sema4 driver is registered.\n");
+
+ return ret;
+}
+
+static void __exit imx_sema4_exit(void)
+{
+ pr_info("imx sema4 driver is unregistered.\n");
+ platform_driver_unregister(&imx_sema4_driver);
+}
+
+module_exit(imx_sema4_exit);
+module_init(imx_sema4_init);
+
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("IMX SEMA4 driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index 8ca03d9d693b..f1e68a0119f3 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -64,6 +64,7 @@ obj-$(CONFIG_H8300) += h8300/
obj-$(CONFIG_ARCH_HISI) += hisilicon/
obj-y += imgtec/
obj-$(CONFIG_ARCH_MXC) += imx/
+obj-$(CONFIG_ARCH_MXC_ARM64) += imx/
obj-$(CONFIG_MACH_INGENIC) += ingenic/
obj-$(CONFIG_ARCH_K3) += keystone/
obj-$(CONFIG_ARCH_KEYSTONE) += keystone/
diff --git a/drivers/clk/clk-divider.c b/drivers/clk/clk-divider.c
index b49942b9fe50..cce882269b6e 100644
--- a/drivers/clk/clk-divider.c
+++ b/drivers/clk/clk-divider.c
@@ -122,6 +122,9 @@ unsigned long divider_recalc_rate(struct clk_hw *hw, unsigned long parent_rate,
{
unsigned int div;
+ if (flags & CLK_DIVIDER_ZERO_GATE && !val)
+ return 0;
+
div = _get_div(table, val, flags, width);
if (!div) {
WARN(!(flags & CLK_DIVIDER_ALLOW_ZERO),
@@ -140,8 +143,13 @@ static unsigned long clk_divider_recalc_rate(struct clk_hw *hw,
struct clk_divider *divider = to_clk_divider(hw);
unsigned int val;
- val = clk_readl(divider->reg) >> divider->shift;
- val &= div_mask(divider->width);
+ if ((divider->flags & CLK_DIVIDER_ZERO_GATE) &&
+ !clk_hw_is_enabled(hw)) {
+ val = divider->cached_val;
+ } else {
+ val = clk_readl(divider->reg) >> divider->shift;
+ val &= div_mask(divider->width);
+ }
return divider_recalc_rate(hw, parent_rate, val, divider->table,
divider->flags, divider->width);
@@ -393,6 +401,12 @@ static int clk_divider_set_rate(struct clk_hw *hw, unsigned long rate,
if (value < 0)
return value;
+ if ((divider->flags & CLK_DIVIDER_ZERO_GATE) &&
+ !clk_hw_is_enabled(hw)) {
+ divider->cached_val = value;
+ return 0;
+ }
+
if (divider->lock)
spin_lock_irqsave(divider->lock, flags);
else
@@ -415,10 +429,85 @@ static int clk_divider_set_rate(struct clk_hw *hw, unsigned long rate,
return 0;
}
+static int clk_divider_enable(struct clk_hw *hw)
+{
+ struct clk_divider *divider = to_clk_divider(hw);
+ unsigned long flags = 0;
+ u32 val;
+
+ if (!(divider->flags & CLK_DIVIDER_ZERO_GATE))
+ return 0;
+
+ if (!divider->cached_val) {
+ pr_err("%s: no valid preset rate\n", clk_hw_get_name(hw));
+ return -EINVAL;
+ }
+
+ if (divider->lock)
+ spin_lock_irqsave(divider->lock, flags);
+ else
+ __acquire(divider->lock);
+
+ /* restore div val */
+ val = clk_readl(divider->reg);
+ val |= divider->cached_val << divider->shift;
+ clk_writel(val, divider->reg);
+
+ if (divider->lock)
+ spin_unlock_irqrestore(divider->lock, flags);
+ else
+ __release(divider->lock);
+
+ return 0;
+}
+
+static void clk_divider_disable(struct clk_hw *hw)
+{
+ struct clk_divider *divider = to_clk_divider(hw);
+ unsigned long flags = 0;
+ u32 val;
+
+ if (!(divider->flags & CLK_DIVIDER_ZERO_GATE))
+ return;
+
+ if (divider->lock)
+ spin_lock_irqsave(divider->lock, flags);
+ else
+ __acquire(divider->lock);
+
+ /* store the current div val */
+ val = clk_readl(divider->reg) >> divider->shift;
+ val &= div_mask(divider->width);
+ divider->cached_val = val;
+ clk_writel(0, divider->reg);
+
+ if (divider->lock)
+ spin_unlock_irqrestore(divider->lock, flags);
+ else
+ __release(divider->lock);
+}
+
+static int clk_divider_is_enabled(struct clk_hw *hw)
+{
+ struct clk_divider *divider = to_clk_divider(hw);
+ u32 val;
+
+ if (!(divider->flags & CLK_DIVIDER_ZERO_GATE))
+ return __clk_get_enable_count(hw->clk);
+
+ val = clk_readl(divider->reg) >> divider->shift;
+ val &= div_mask(divider->width);
+
+ return val ? 1 : 0;
+}
+
const struct clk_ops clk_divider_ops = {
.recalc_rate = clk_divider_recalc_rate,
.round_rate = clk_divider_round_rate,
.set_rate = clk_divider_set_rate,
+ .enable = clk_divider_enable,
+ .disable = clk_divider_disable,
+ .is_enabled = clk_divider_is_enabled,
};
EXPORT_SYMBOL_GPL(clk_divider_ops);
@@ -437,6 +526,7 @@ static struct clk_hw *_register_divider(struct device *dev, const char *name,
struct clk_divider *div;
struct clk_hw *hw;
struct clk_init_data init;
+ u32 val;
int ret;
if (clk_divider_flags & CLK_DIVIDER_HIWORD_MASK) {
@@ -469,6 +559,12 @@ static struct clk_hw *_register_divider(struct device *dev, const char *name,
div->hw.init = &init;
div->table = table;
+ if (div->flags & CLK_DIVIDER_ZERO_GATE) {
+ val = clk_readl(reg) >> shift;
+ val &= div_mask(width);
+ div->cached_val = val;
+ }
+
/* register the clock */
hw = &div->hw;
ret = clk_hw_register(dev, hw);
diff --git a/drivers/clk/clk-fractional-divider.c b/drivers/clk/clk-fractional-divider.c
index 083daa293280..5bad0767e03a 100644
--- a/drivers/clk/clk-fractional-divider.c
+++ b/drivers/clk/clk-fractional-divider.c
@@ -40,6 +40,11 @@ static unsigned long clk_fd_recalc_rate(struct clk_hw *hw,
m = (val & fd->mmask) >> fd->mshift;
n = (val & fd->nmask) >> fd->nshift;
+ if (fd->flags & CLK_FRAC_DIVIDER_ZERO_BASED) {
+ m++;
+ n++;
+ }
+
if (!n || !m)
return parent_rate;
@@ -103,6 +108,11 @@ static int clk_fd_set_rate(struct clk_hw *hw, unsigned long rate,
GENMASK(fd->mwidth - 1, 0), GENMASK(fd->nwidth - 1, 0),
&m, &n);
+ if (fd->flags & CLK_FRAC_DIVIDER_ZERO_BASED) {
+ m--;
+ n--;
+ }
+
if (fd->lock)
spin_lock_irqsave(fd->lock, flags);
else
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index a3f52f678211..134996ffff8e 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -1800,7 +1800,8 @@ static int clk_core_set_parent(struct clk_core *core, struct clk_core *parent)
/* prevent racing with updates to the clock topology */
clk_prepare_lock();
- if (core->parent == parent)
+ if ((core->parent == parent) &&
+ !(core->flags & CLK_SET_PARENT_NOCACHE))
goto out;
/* verify ops for for multi-parent clks */
@@ -2490,6 +2491,19 @@ static int __clk_core_init(struct clk_core *core)
}
/*
+ * optional platform-specific magic
+ *
+ * The .init callback is not used by any of the basic clock types, but
+ * exists for weird hardware that must perform initialization magic.
+ * Please consider other ways of solving initialization problems before
+ * using this callback, as its use is discouraged.
+ */
+ if (core->ops->init)
+ core->ops->init(core->hw);
+
+ kref_init(&core->ref);
+
+ /*
* walk the list of orphan clocks and reparent any that newly finds a
* parent.
*/
@@ -2511,18 +2525,6 @@ static int __clk_core_init(struct clk_core *core)
}
}
- /*
- * optional platform-specific magic
- *
- * The .init callback is not used by any of the basic clock types, but
- * exists for weird hardware that must perform initialization magic.
- * Please consider other ways of solving initialization problems before
- * using this callback, as its use is discouraged.
- */
- if (core->ops->init)
- core->ops->init(core->hw);
-
- kref_init(&core->ref);
out:
clk_prepare_unlock();
diff --git a/drivers/clk/imx/Makefile b/drivers/clk/imx/Makefile
index f91f2b2e11cd..46fa0da9a3bf 100644
--- a/drivers/clk/imx/Makefile
+++ b/drivers/clk/imx/Makefile
@@ -1,6 +1,6 @@
# SPDX-License-Identifier: GPL-2.0
-obj-y += \
+obj-$(CONFIG_ARM) += \
clk.o \
clk-busy.o \
clk-cpu.o \
@@ -11,7 +11,10 @@ obj-y += \
clk-pllv1.o \
clk-pllv2.o \
clk-pllv3.o \
- clk-pfd.o
+ clk-pfd.o \
+ clk-pllv4.o \
+ clk-pllv5.o \
+ clk-pfdv2.o
obj-$(CONFIG_SOC_IMX1) += clk-imx1.o
obj-$(CONFIG_SOC_IMX21) += clk-imx21.o
@@ -22,7 +25,16 @@ obj-$(CONFIG_SOC_IMX35) += clk-imx35.o
obj-$(CONFIG_SOC_IMX5) += clk-imx51-imx53.o
obj-$(CONFIG_SOC_IMX6Q) += clk-imx6q.o
obj-$(CONFIG_SOC_IMX6SL) += clk-imx6sl.o
+obj-$(CONFIG_SOC_IMX6SLL) += clk-imx6sll.o
obj-$(CONFIG_SOC_IMX6SX) += clk-imx6sx.o
obj-$(CONFIG_SOC_IMX6UL) += clk-imx6ul.o
obj-$(CONFIG_SOC_IMX7D) += clk-imx7d.o
+obj-$(CONFIG_SOC_IMX7ULP) += clk-imx7ulp.o clk-composite-7ulp.o
obj-$(CONFIG_SOC_VF610) += clk-vf610.o
+#
+# IMX Clock specific Makefile
+#
+obj-$(CONFIG_ARCH_FSL_IMX8QM) += clk.o clk-imx8qm.o clk-imx8.o clk-divider-scu.o clk-gate-scu.o clk-mux-scu.o
+obj-$(CONFIG_ARCH_FSL_IMX8QXP) += clk.o clk-imx8qxp.o clk-imx8.o clk-divider-scu.o clk-gate-scu.o clk-mux-scu.o
+obj-$(CONFIG_ARCH_FSL_IMX8MQ) += clk.o clk-imx8mq.o clk-frac-pll.o clk-sccg-pll.o clk-gate2.o clk-composite-8m.o
+obj-$(CONFIG_ARCH_FSL_IMX8MM) += clk.o clk-imx8mm.o clk-intpll.o clk-gate2.o clk-cpu.o
diff --git a/drivers/clk/imx/clk-busy.c b/drivers/clk/imx/clk-busy.c
index 097625c5715c..03ad540f0991 100644
--- a/drivers/clk/imx/clk-busy.c
+++ b/drivers/clk/imx/clk-busy.c
@@ -101,7 +101,7 @@ struct clk *imx_clk_busy_divider(const char *name, const char *parent_name,
init.name = name;
init.ops = &clk_busy_divider_ops;
- init.flags = CLK_SET_RATE_PARENT;
+ init.flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE;
init.parent_names = &parent_name;
init.num_parents = 1;
diff --git a/drivers/clk/imx/clk-composite-7ulp.c b/drivers/clk/imx/clk-composite-7ulp.c
new file mode 100644
index 000000000000..8b6597801409
--- /dev/null
+++ b/drivers/clk/imx/clk-composite-7ulp.c
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017 NXP
+ *
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+#include <linux/errno.h>
+#include <linux/slab.h>
+#include <linux/clk-provider.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+
+#include "clk.h"
+
+#define PCG_PCS_SHIFT 24
+#define PCG_PCS_MASK 0x7
+#define PCG_CGC_SHIFT 30
+#define PCG_FRAC_SHIFT 3
+#define PCG_FRAC_WIDTH 1
+#define PCG_FRAC_MASK BIT(3)
+#define PCG_PCD_SHIFT 0
+#define PCG_PCD_WIDTH 3
+#define PCG_PCD_MASK 0x7
+
+#define PCG_PREDIV_SHIFT 16
+#define PCG_PREDIV_WIDTH 3
+#define PCG_PREDIV_MAX 8
+
+#define PCG_DIV_SHIFT 0
+#define PCG_DIV_WIDTH 6
+#define PCG_DIV_MAX 64
+
+#define clk_div_mask(width) ((1 << (width)) - 1)
+
+struct clk *imx7ulp_clk_composite(const char *name, const char **parent_names,
+ int num_parents, bool mux_present,
+ bool rate_present, bool gate_present,
+ void __iomem *reg)
+{
+ struct clk_hw *mux_hw = NULL, *fd_hw = NULL, *gate_hw = NULL;
+ struct clk_fractional_divider *fd = NULL;
+ struct clk_gate *gate = NULL;
+ struct clk_mux *mux = NULL;
+ struct clk *clk;
+
+ if (mux_present) {
+ mux = kzalloc(sizeof(*mux), GFP_KERNEL);
+ if (!mux)
+ return ERR_PTR(-ENOMEM);
+ mux_hw = &mux->hw;
+ mux->reg = reg;
+ mux->shift = PCG_PCS_SHIFT;
+ mux->mask = PCG_PCS_MASK;
+ }
+
+ if (rate_present) {
+ fd = kzalloc(sizeof(*fd), GFP_KERNEL);
+ if (!fd) {
+ kfree(mux);
+ return ERR_PTR(-ENOMEM);
+ }
+ fd_hw = &fd->hw;
+ fd->reg = reg;
+ fd->mshift = PCG_FRAC_SHIFT;
+ fd->mwidth = PCG_FRAC_WIDTH;
+ fd->mmask = PCG_FRAC_MASK;
+ fd->nshift = PCG_PCD_SHIFT;
+ fd->nwidth = PCG_PCD_WIDTH;
+ fd->nmask = PCG_PCD_MASK;
+ fd->flags = CLK_FRAC_DIVIDER_ZERO_BASED;
+ }
+
+ if (gate_present) {
+ gate = kzalloc(sizeof(*gate), GFP_KERNEL);
+ if (!gate) {
+ kfree(mux);
+ kfree(fd);
+ return ERR_PTR(-ENOMEM);
+ }
+ gate_hw = &gate->hw;
+ gate->reg = reg;
+ gate->bit_idx = PCG_CGC_SHIFT;
+ }
+
+ clk = clk_register_composite(NULL, name, parent_names, num_parents,
+ mux_hw, &clk_mux_ops, fd_hw,
+ &clk_fractional_divider_ops, gate_hw,
+ &clk_gate_ops, CLK_SET_RATE_GATE |
+ CLK_SET_PARENT_GATE);
+ if (IS_ERR(clk)) {
+ kfree(mux);
+ kfree(fd);
+ kfree(gate);
+ }
+
+ return clk;
+}
+
diff --git a/drivers/clk/imx/clk-composite-8m.c b/drivers/clk/imx/clk-composite-8m.c
new file mode 100644
index 000000000000..076e5e28fe24
--- /dev/null
+++ b/drivers/clk/imx/clk-composite-8m.c
@@ -0,0 +1,186 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2018 NXP
+ */
+
+#include <linux/errno.h>
+#include <linux/slab.h>
+#include <linux/clk-provider.h>
+#include <linux/clk.h>
+
+#define clk_div_mask(width) ((1 << (width)) - 1)
+
+#include "clk.h"
+
+#define PCG_PREDIV_SHIFT 16
+#define PCG_PREDIV_WIDTH 3
+#define PCG_PREDIV_MAX 8
+
+#define PCG_DIV_SHIFT 0
+#define PCG_DIV_WIDTH 6
+#define PCG_DIV_MAX 64
+
+#define PCG_PCS_SHIFT 24
+#define PCG_PCS_MASK 0x7
+
+#define PCG_CGC_SHIFT 28
+
+static unsigned long imx8m_clk_composite_divider_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ struct clk_divider *divider = to_clk_divider(hw);
+ unsigned long prediv_rate;
+ unsigned int prediv_value;
+ unsigned int div_value;
+
+ prediv_value = clk_readl(divider->reg) >> divider->shift;
+ prediv_value &= clk_div_mask(divider->width);
+
+ prediv_rate = divider_recalc_rate(hw, parent_rate, prediv_value,
+ NULL, divider->flags,
+ divider->width);
+
+ div_value = clk_readl(divider->reg) >> PCG_DIV_SHIFT;
+ div_value &= clk_div_mask(PCG_DIV_WIDTH);
+
+ return divider_recalc_rate(hw, prediv_rate, div_value, NULL,
+ divider->flags, PCG_DIV_WIDTH);
+}
+
+static int imx8m_clk_composite_compute_dividers(unsigned long rate,
+ unsigned long parent_rate,
+ int *prediv, int *postdiv)
+{
+ int div1, div2;
+ int error = INT_MAX;
+ int ret = -EINVAL;
+
+ /* default values */
+ *prediv = 1;
+ *postdiv = 1;
+
+ for (div1 = 1; div1 <= PCG_PREDIV_MAX; div1++) {
+ for (div2 = 1; div2 <= PCG_DIV_MAX; div2++) {
+ int new_error = ((parent_rate / div1) / div2) - rate;
+
+ if (abs(new_error) < abs(error)) {
+ *prediv = div1;
+ *postdiv = div2;
+ error = new_error;
+ ret = 0;
+ }
+ }
+ }
+ return ret;
+}
+
+static long imx8m_clk_composite_divider_round_rate(struct clk_hw *hw,
+ unsigned long rate,
+ unsigned long *prate)
+{
+ int prediv_value;
+ int div_value;
+
+ imx8m_clk_composite_compute_dividers(rate, *prate,
+ &prediv_value, &div_value);
+
+ rate = DIV_ROUND_UP(*prate, prediv_value);
+ rate = DIV_ROUND_UP(rate, div_value);
+
+ return rate;
+}
+
+static int imx8m_clk_composite_divider_set_rate(struct clk_hw *hw,
+ unsigned long rate,
+ unsigned long parent_rate)
+{
+ struct clk_divider *divider = to_clk_divider(hw);
+ unsigned long flags = 0;
+ int prediv_value;
+ int div_value;
+ int ret = 0;
+ u32 val;
+
+ ret = imx8m_clk_composite_compute_dividers(rate, parent_rate,
+ &prediv_value, &div_value);
+ if (ret)
+ return -EINVAL;
+
+ spin_lock_irqsave(divider->lock, flags);
+
+ val = clk_readl(divider->reg);
+ val &= ~((clk_div_mask(divider->width) << divider->shift) |
+ (clk_div_mask(PCG_DIV_WIDTH) << PCG_DIV_SHIFT));
+
+ val |= (u32)(prediv_value - 1) << divider->shift;
+ val |= (u32)(div_value - 1) << PCG_DIV_SHIFT;
+ clk_writel(val, divider->reg);
+
+ spin_unlock_irqrestore(divider->lock, flags);
+
+ return ret;
+}
+
+static const struct clk_ops imx8m_clk_composite_divider_ops = {
+ .recalc_rate = imx8m_clk_composite_divider_recalc_rate,
+ .round_rate = imx8m_clk_composite_divider_round_rate,
+ .set_rate = imx8m_clk_composite_divider_set_rate,
+};
+
+struct clk *imx8m_clk_composite_flags(const char *name,
+ const char **parent_names,
+ int num_parents, void __iomem *reg,
+ unsigned long flags)
+{
+ struct clk_hw *mux_hw = NULL, *div_hw = NULL, *gate_hw = NULL;
+ struct clk_divider *div = NULL;
+ struct clk_gate *gate = NULL;
+ struct clk_mux *mux = NULL;
+ struct clk *clk = ERR_PTR(-ENOMEM);
+
+ mux = kzalloc(sizeof(*mux), GFP_KERNEL);
+ if (!mux)
+ goto fail;
+
+ mux_hw = &mux->hw;
+ mux->reg = reg;
+ mux->shift = PCG_PCS_SHIFT;
+ mux->mask = PCG_PCS_MASK;
+
+ div = kzalloc(sizeof(*div), GFP_KERNEL);
+ if (!div)
+ goto fail;
+
+ div_hw = &div->hw;
+ div->reg = reg;
+ div->shift = PCG_PREDIV_SHIFT;
+ div->width = PCG_PREDIV_WIDTH;
+ div->lock = &imx_ccm_lock;
+ div->flags = CLK_DIVIDER_ROUND_CLOSEST;
+
+ gate = kzalloc(sizeof(*gate), GFP_KERNEL);
+ if (!gate)
+ goto fail;
+
+ gate_hw = &gate->hw;
+ gate->reg = reg;
+ gate->bit_idx = PCG_CGC_SHIFT;
+
+ if (imx_src_is_m4_enabled())
+ flags |= CLK_IGNORE_UNUSED;
+
+ clk = clk_register_composite(NULL, name, parent_names, num_parents,
+ mux_hw, &clk_mux_ops, div_hw,
+ &imx8m_clk_composite_divider_ops,
+ gate_hw, &clk_gate_ops, flags);
+ if (IS_ERR(clk))
+ goto fail;
+
+ return clk;
+
+fail:
+ kfree(gate);
+ kfree(div);
+ kfree(mux);
+ return clk;
+}
diff --git a/drivers/clk/imx/clk-divider-scu.c b/drivers/clk/imx/clk-divider-scu.c
new file mode 100644
index 000000000000..b8ad05050ec0
--- /dev/null
+++ b/drivers/clk/imx/clk-divider-scu.c
@@ -0,0 +1,250 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017 NXP
+ *
+ * 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/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/jiffies.h>
+#include <linux/slab.h>
+#include <soc/imx8/sc/sci.h>
+
+#include "clk-imx8.h"
+
+struct clk_divider_scu {
+ struct clk_divider div;
+ sc_rsrc_t rsrc_id;
+ sc_pm_clk_t clk_type;
+};
+
+struct clk_divider3_scu {
+ struct clk_divider div;
+ sc_rsrc_t rsrc_id;
+ sc_ctrl_t gpr_id;
+};
+
+static inline struct clk_divider3_scu *to_clk_divider3_scu(struct clk_hw *hw)
+{
+ struct clk_divider *div = container_of(hw, struct clk_divider, hw);
+
+ return container_of(div, struct clk_divider3_scu, div);
+}
+
+static inline struct clk_divider_scu *to_clk_divider_scu(struct clk_hw *hw)
+{
+ struct clk_divider *div = container_of(hw, struct clk_divider, hw);
+
+ return container_of(div, struct clk_divider_scu, div);
+}
+
+static unsigned long clk_divider_scu_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ struct clk_divider_scu *clk = to_clk_divider_scu(hw);
+ sc_err_t sci_err;
+ sc_pm_clock_rate_t rate = 0;
+
+ if (!ccm_ipc_handle)
+ return 0;
+
+ sci_err = sc_pm_get_clock_rate(ccm_ipc_handle, clk->rsrc_id,
+ clk->clk_type, &rate);
+
+ return sci_err ? 0 : rate;
+}
+
+static long clk_divider_scu_round_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long *prate)
+{
+ /* TODO */
+ *prate = rate;
+
+ return rate;
+}
+
+static int clk_divider_scu_set_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long parent_rate)
+{
+ struct clk_divider_scu *clk = to_clk_divider_scu(hw);
+ sc_err_t sci_err;
+
+ if (!ccm_ipc_handle) {
+ return -EAGAIN;
+ }
+
+ sci_err = sc_pm_set_clock_rate(ccm_ipc_handle, clk->rsrc_id,
+ clk->clk_type, (sc_pm_clock_rate_t *)&rate);
+
+ return sci_err ? -EINVAL : 0;
+}
+
+static struct clk_ops clk_divider_scu_ops = {
+ .recalc_rate = clk_divider_scu_recalc_rate,
+ .round_rate = clk_divider_scu_round_rate,
+ .set_rate = clk_divider_scu_set_rate,
+};
+
+struct clk *imx_clk_divider_scu(const char *name,
+ sc_rsrc_t rsrc_id, sc_pm_clk_t clk_type)
+{
+ struct clk_divider_scu *div_clk;
+ struct clk *clk;
+ struct clk_init_data init;
+
+ if (!imx8_clk_is_resource_owned(rsrc_id)) {
+ pr_debug("skip clk %s rsrc %d not owned\n", name, rsrc_id);
+ return ERR_PTR(-ENODEV);
+ }
+
+ div_clk = kzalloc(sizeof(*div_clk), GFP_KERNEL);
+ if (!div_clk)
+ return ERR_PTR(-ENOMEM);
+
+ div_clk->rsrc_id = rsrc_id;
+ div_clk->clk_type = clk_type;
+
+ init.name = name;
+ init.ops = &clk_divider_scu_ops;
+ init.flags = CLK_GET_RATE_NOCACHE;
+ init.num_parents = 0;
+ div_clk->div.hw.init = &init;
+
+ clk = clk_register(NULL, &div_clk->div.hw);
+ if (IS_ERR(clk))
+ kfree(div_clk);
+
+ return clk;
+}
+
+struct clk *imx_clk_divider2_scu(const char *name, const char *parent_name,
+ sc_rsrc_t rsrc_id, sc_pm_clk_t clk_type)
+{
+ struct clk_divider_scu *div_clk;
+ struct clk *clk;
+ struct clk_init_data init;
+
+ if (!imx8_clk_is_resource_owned(rsrc_id)) {
+ pr_debug("skip clk %s rsrc %d not owned\n", name, rsrc_id);
+ return ERR_PTR(-ENODEV);
+ }
+
+ div_clk = kzalloc(sizeof(*div_clk), GFP_KERNEL);
+ if (!div_clk)
+ return ERR_PTR(-ENOMEM);
+
+ div_clk->rsrc_id = rsrc_id;
+ div_clk->clk_type = clk_type;
+
+ init.name = name;
+ init.ops = &clk_divider_scu_ops;
+ init.flags = CLK_GET_RATE_NOCACHE;
+ init.parent_names = parent_name ? &parent_name : NULL;
+ init.num_parents = parent_name ? 1 : 0;
+ div_clk->div.hw.init = &init;
+
+ clk = clk_register(NULL, &div_clk->div.hw);
+ if (IS_ERR(clk))
+ kfree(div_clk);
+
+ return clk;
+}
+
+static unsigned long clk_divider3_scu_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ struct clk_divider3_scu *clk = to_clk_divider3_scu(hw);
+ uint32_t val;
+ sc_err_t sci_err;
+ sc_pm_clock_rate_t rate = 0;
+
+ if (!ccm_ipc_handle)
+ return 0;
+
+ sci_err = sc_misc_get_control(ccm_ipc_handle, clk->rsrc_id,
+ clk->gpr_id, &val);
+
+ rate = (val) ? parent_rate / 2 : parent_rate;
+
+ return sci_err ? 0 : rate;
+}
+
+static long clk_divider3_scu_round_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long *prate)
+{
+ if (rate < *prate)
+ rate = *prate / 2;
+ else
+ rate = *prate;
+
+ return rate;
+}
+
+static int clk_divider3_scu_set_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long parent_rate)
+{
+ struct clk_divider3_scu *clk = to_clk_divider3_scu(hw);
+ uint32_t val;
+ sc_err_t sci_err;
+
+ if (!ccm_ipc_handle) {
+ return -EAGAIN;
+ }
+
+ val = (rate < parent_rate) ? 1 : 0;
+ sci_err = sc_misc_set_control(ccm_ipc_handle, clk->rsrc_id,
+ clk->gpr_id, val);
+
+ return sci_err ? -EINVAL : 0;
+}
+
+static struct clk_ops clk_divider3_scu_ops = {
+ .recalc_rate = clk_divider3_scu_recalc_rate,
+ .round_rate = clk_divider3_scu_round_rate,
+ .set_rate = clk_divider3_scu_set_rate,
+};
+
+struct clk *imx_clk_divider3_scu(const char *name, const char *parent_name,
+ sc_rsrc_t rsrc_id, sc_ctrl_t gpr_id)
+{
+ struct clk_divider3_scu *div;
+ struct clk *clk;
+ struct clk_init_data init;
+
+ if (!imx8_clk_is_resource_owned(rsrc_id)) {
+ pr_debug("skip clk %s rsrc %d not owned\n", name, rsrc_id);
+ return ERR_PTR(-ENODEV);
+ }
+
+ div = kzalloc(sizeof(struct clk_divider3_scu), GFP_KERNEL);
+ if (!div)
+ return ERR_PTR(-ENOMEM);
+
+ div->rsrc_id = rsrc_id;
+ div->gpr_id = gpr_id;
+
+ init.name = name;
+ init.ops = &clk_divider3_scu_ops;
+ init.flags = 0;
+ init.parent_names = parent_name ? &parent_name : NULL;
+ init.num_parents = parent_name ? 1 : 0;
+
+ div->div.hw.init = &init;
+
+ clk = clk_register(NULL, &div->div.hw);
+ if (IS_ERR(clk))
+ kfree(div);
+
+ return clk;
+}
diff --git a/drivers/clk/imx/clk-frac-pll.c b/drivers/clk/imx/clk-frac-pll.c
new file mode 100644
index 000000000000..7c2614cbb8f7
--- /dev/null
+++ b/drivers/clk/imx/clk-frac-pll.c
@@ -0,0 +1,230 @@
+/*
+ * Copyright 2017 NXP.
+ *
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <linux/jiffies.h>
+
+#include "clk.h"
+
+#define PLL_CFG0 0x0
+#define PLL_CFG1 0x4
+
+#define PLL_LOCK_STATUS (0x1 << 31)
+#define PLL_CLKE 21
+#define PLL_PD 19
+#define PLL_BYPASS 14
+#define PLL_NEWDIV_VAL (1 << 12)
+#define PLL_NEWDIV_ACK (1 << 11)
+#define PLL_FRAC_DIV_MASK 0xffffff
+#define PLL_INT_DIV_MASK 0x7f
+#define PLL_FRAC_DENOM 0x1000000
+
+struct clk_frac_pll {
+ struct clk_hw hw;
+ void __iomem *base;
+};
+
+#define to_clk_frac_pll(_hw) container_of(_hw, struct clk_frac_pll, hw)
+
+static int clk_wait_lock(struct clk_frac_pll *pll)
+{
+ unsigned long timeout = jiffies + msecs_to_jiffies(10);
+
+ /* Wait for PLL to lock */
+ do {
+ if (readl_relaxed(pll->base) & PLL_LOCK_STATUS)
+ break;
+ if (time_after(jiffies, timeout))
+ break;
+ } while (1);
+
+ return readl_relaxed(pll->base) & PLL_LOCK_STATUS ? 0 : -ETIMEDOUT;
+}
+
+static int clk_wait_ack(struct clk_frac_pll *pll)
+{
+ unsigned long timeout = jiffies + msecs_to_jiffies(50);
+
+ /* return directly if the pll is in powerdown or bypass */
+ if (readl_relaxed(pll->base) & ((1 << PLL_PD) | (1 << PLL_BYPASS)))
+ return 0;
+
+ /* Wait for the pll's divfi and divff is reloaded */
+ do {
+ if (readl_relaxed(pll->base) & PLL_NEWDIV_ACK)
+ break;
+ if (time_after(jiffies, timeout))
+ break;
+ } while (1);
+
+ return readl_relaxed(pll->base) & PLL_NEWDIV_ACK ? 0 : ETIMEDOUT;
+}
+
+static int clk_pll_prepare(struct clk_hw *hw)
+{
+ struct clk_frac_pll *pll = to_clk_frac_pll(hw);
+ u32 val;
+
+ val = readl_relaxed(pll->base + PLL_CFG0);
+ val &= ~(1 << PLL_PD);
+ writel_relaxed(val, pll->base + PLL_CFG0);
+
+ return clk_wait_lock(pll);
+}
+
+static void clk_pll_unprepare(struct clk_hw *hw)
+{
+ struct clk_frac_pll *pll = to_clk_frac_pll(hw);
+ u32 val;
+
+ val = readl_relaxed(pll->base + PLL_CFG0);
+ val |= (1 << PLL_PD);
+ writel_relaxed(val, pll->base + PLL_CFG0);
+}
+
+static int clk_pll_is_prepared(struct clk_hw *hw)
+{
+ struct clk_frac_pll *pll = to_clk_frac_pll(hw);
+ u32 val;
+
+ val = readl_relaxed(pll->base + PLL_CFG0);
+ return (val & (1 << PLL_PD)) ? 0 : 1;
+}
+
+static unsigned long clk_pll_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ struct clk_frac_pll *pll = to_clk_frac_pll(hw);
+ u32 val, divff, divfi, divq;
+ u64 temp64;
+
+ val = readl_relaxed(pll->base + PLL_CFG0);
+ divq = ((val & 0x1f) + 1) * 2;
+ val = readl_relaxed(pll->base + PLL_CFG1);
+ divff = (val >> 7) & PLL_FRAC_DIV_MASK;
+ divfi = (val & PLL_INT_DIV_MASK);
+
+ temp64 = (u64)parent_rate * 8;
+ temp64 *= divff;
+ do_div(temp64, PLL_FRAC_DENOM);
+ temp64 /= divq;
+
+ return parent_rate * 8 * (divfi + 1) / divq + (unsigned long)temp64;
+}
+
+static long clk_pll_round_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long *prate)
+{
+ u32 divff, divfi;
+ u64 temp64;
+ unsigned long parent_rate = *prate;
+
+ parent_rate *= 8;
+ rate *= 2;
+ divfi = rate / parent_rate;
+ temp64 = (u64)(rate - divfi * parent_rate);
+ temp64 *= PLL_FRAC_DENOM;
+ do_div(temp64, parent_rate);
+ divff = temp64;
+
+ temp64 = (u64)parent_rate;
+ temp64 *= divff;
+ do_div(temp64, PLL_FRAC_DENOM);
+
+ return (parent_rate * divfi + (unsigned long)temp64) / 2;
+}
+
+/*
+ * To simplify the clock calculation, we can keep the
+ * 'PLL_OUTPUT_VAL' to zero(means the PLL output
+ * will be dividered by 2. So the PLL output can use
+ * below formula:
+ * pllout = parent_rate * 8 / 2 * DIVF_VAL;
+ * where DIVF_VAL = 1 + DIVFI + DIVFF / 2^24.
+ */
+static int clk_pll_set_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long parent_rate)
+{
+ struct clk_frac_pll *pll = to_clk_frac_pll(hw);
+ u32 val, divfi, divff;
+ u64 temp64;
+ int ret;
+
+ parent_rate *= 8;
+ rate *= 2;
+ divfi = rate / parent_rate;
+ temp64 = (u64) (rate - divfi * parent_rate);
+ temp64 *= PLL_FRAC_DENOM;
+ do_div(temp64, parent_rate);
+ divff = temp64;
+
+ val = readl_relaxed(pll->base + PLL_CFG1);
+ val &= ~((PLL_FRAC_DIV_MASK << 7) | (PLL_INT_DIV_MASK));
+ val |= ((divff << 7) | (divfi - 1));
+ writel_relaxed(val, pll->base + PLL_CFG1);
+
+ val = readl_relaxed(pll->base + PLL_CFG0);
+ val &= ~0x1f;
+ writel_relaxed(val, pll->base + PLL_CFG0);
+
+ /* Set the NEV_DIV_VAL to reload the DIVFI and DIVFF */
+ val = readl_relaxed(pll->base + PLL_CFG0);
+ val |= PLL_NEWDIV_VAL;
+ writel_relaxed(val, pll->base + PLL_CFG0);
+
+ ret = clk_wait_ack(pll);
+
+ /* clear the NEV_DIV_VAL */
+ val = readl_relaxed(pll->base + PLL_CFG0);
+ val &= ~PLL_NEWDIV_VAL;
+ writel_relaxed(val, pll->base + PLL_CFG0);
+
+ return ret;
+}
+
+static const struct clk_ops clk_frac_pll_ops = {
+ .prepare = clk_pll_prepare,
+ .unprepare = clk_pll_unprepare,
+ .is_prepared = clk_pll_is_prepared,
+ .recalc_rate = clk_pll_recalc_rate,
+ .round_rate = clk_pll_round_rate,
+ .set_rate = clk_pll_set_rate,
+};
+
+struct clk *imx_clk_frac_pll(const char *name, const char *parent_name,
+ void __iomem *base)
+{
+ struct clk_frac_pll *pll;
+ struct clk *clk;
+ struct clk_init_data init;
+
+ pll = kzalloc(sizeof(*pll), GFP_KERNEL);
+ if (!pll)
+ return ERR_PTR(-ENOMEM);
+
+ pll->base = base;
+ init.name = name;
+ init.ops = &clk_frac_pll_ops;
+ init.flags = 0;
+ init.parent_names = &parent_name;
+ init.num_parents = 1;
+
+ pll->hw.init = &init;
+
+ clk = clk_register(NULL, &pll->hw);
+ if (IS_ERR(clk))
+ kfree(pll);
+
+ return clk;
+}
diff --git a/drivers/clk/imx/clk-gate-scu.c b/drivers/clk/imx/clk-gate-scu.c
new file mode 100644
index 000000000000..abcda5f9a952
--- /dev/null
+++ b/drivers/clk/imx/clk-gate-scu.c
@@ -0,0 +1,448 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017-2018 NXP
+ *
+ * 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/clk-provider.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/pm_domain.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <soc/imx8/sc/sci.h>
+
+#include "clk-imx8.h"
+
+/*
+ * DOC: basic gatable clock which can gate and ungate it's ouput
+ *
+ * Traits of this clock:
+ * prepare - clk_(un)prepare only ensures parent is (un)prepared
+ * enable - clk_enable and clk_disable are functional & control gating
+ * rate - inherits rate from parent. No clk_set_rate support
+ * parent - fixed parent. No clk_set_parent support
+ */
+
+#define CLK_GATE_SCU_HW_SW_EN (BIT(0) | BIT(1))
+#define CLK_GATE_SCU_SW_EN BIT(1)
+
+struct clk_gate_scu {
+ struct clk_hw hw;
+ void __iomem *reg;
+ u8 bit_idx;
+ bool hw_gate;
+ u8 flags;
+ spinlock_t *lock;
+ sc_rsrc_t rsrc_id;
+ sc_pm_clk_t clk_type;
+};
+
+struct clk_gate2_scu {
+ struct clk_hw hw;
+ void __iomem *reg;
+ u8 bit_idx;
+ u8 flags;
+ spinlock_t *lock;
+ char *pd_name;
+ struct generic_pm_domain *pd;
+};
+
+struct clk_gate3_scu {
+ struct clk_hw hw;
+ spinlock_t *lock;
+ sc_rsrc_t rsrc_id;
+ sc_ctrl_t gpr_id;
+ bool invert;
+};
+
+#define to_clk_gate_scu(_hw) container_of(_hw, struct clk_gate_scu, hw)
+#define to_clk_gate2_scu(_hw) container_of(_hw, struct clk_gate2_scu, hw)
+#define to_clk_gate3_scu(_hw) container_of(_hw, struct clk_gate3_scu, hw)
+
+/* Write to the LPCG bits. */
+static int clk_gate_scu_enable(struct clk_hw *hw)
+{
+ struct clk_gate_scu *gate = to_clk_gate_scu(hw);
+ u32 reg;
+
+ if (!ccm_ipc_handle)
+ return -1;
+
+ if (gate->reg) {
+ reg = readl(gate->reg);
+ if (gate->hw_gate)
+ reg |= (CLK_GATE_SCU_HW_SW_EN << gate->bit_idx);
+ else
+ reg |= (CLK_GATE_SCU_SW_EN << gate->bit_idx);
+ writel(reg, gate->reg);
+ }
+
+ return 0;
+}
+
+/* Write to the LPCG bits. */
+static void clk_gate_scu_disable(struct clk_hw *hw)
+{
+ struct clk_gate_scu *gate = to_clk_gate_scu(hw);
+ u32 reg;
+
+ if (!ccm_ipc_handle)
+ return;
+
+ if (gate->reg) {
+ reg = readl(gate->reg);
+ if (gate->hw_gate)
+ reg &= ~(CLK_GATE_SCU_HW_SW_EN << gate->bit_idx);
+ else
+ reg &= ~(CLK_GATE_SCU_SW_EN << gate->bit_idx);
+ writel(reg, gate->reg);
+ }
+}
+
+static int clk_gate_scu_prepare(struct clk_hw *hw)
+{
+ struct clk_gate_scu *gate = to_clk_gate_scu(hw);
+ sc_err_t sci_err = SC_ERR_NONE;
+
+ if (!ccm_ipc_handle)
+ return -1;
+
+ /* Enable the clock at the DSC slice level */
+ sci_err = sc_pm_clock_enable(ccm_ipc_handle, gate->rsrc_id,
+ gate->clk_type, true, gate->hw_gate);
+
+ if (sci_err != SC_ERR_NONE)
+ return -EINVAL;
+
+ return 0;
+}
+
+static void clk_gate_scu_unprepare(struct clk_hw *hw)
+{
+ struct clk_gate_scu *gate = to_clk_gate_scu(hw);
+ sc_err_t sci_err;
+
+ if (!ccm_ipc_handle)
+ return;
+
+ sci_err = sc_pm_clock_enable(ccm_ipc_handle, gate->rsrc_id,
+ gate->clk_type, false, false);
+ if (sci_err)
+ pr_err("clk gate scu unprepare clk fail!\n");
+}
+
+static unsigned long clk_gate_scu_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ struct clk_gate_scu *clk = to_clk_gate_scu(hw);
+ sc_err_t sci_err;
+ sc_pm_clock_rate_t rate = 0;
+
+ if (!ccm_ipc_handle)
+ return 0;
+
+ sci_err = sc_pm_get_clock_rate(ccm_ipc_handle, clk->rsrc_id,
+ clk->clk_type, &rate);
+
+ return sci_err ? 0 : rate;
+}
+
+static struct clk_ops clk_gate_scu_ops = {
+ .prepare = clk_gate_scu_prepare,
+ .unprepare = clk_gate_scu_unprepare,
+ .enable = clk_gate_scu_enable,
+ .disable = clk_gate_scu_disable,
+ .recalc_rate = clk_gate_scu_recalc_rate,
+};
+
+struct clk *clk_register_gate_scu(struct device *dev, const char *name,
+ const char *parent_name, unsigned long flags,
+ u8 clk_gate_scu_flags, spinlock_t *lock,
+ sc_rsrc_t rsrc_id, sc_pm_clk_t clk_type,
+ void __iomem *reg, u8 bit_idx, bool hw_gate)
+{
+ struct clk_gate_scu *gate;
+ struct clk *clk;
+ struct clk_init_data init;
+
+ if (!imx8_clk_is_resource_owned(rsrc_id)) {
+ pr_debug("skip clk %s rsrc %d not owned\n", name, rsrc_id);
+ return ERR_PTR(-ENODEV);
+ }
+
+ gate = kzalloc(sizeof(struct clk_gate_scu), GFP_KERNEL);
+ if (!gate)
+ return ERR_PTR(-ENOMEM);
+
+ /* struct clk_gate_scu assignments */
+ gate->flags = clk_gate_scu_flags;
+ gate->lock = lock;
+ gate->rsrc_id = rsrc_id;
+ gate->clk_type = clk_type;
+ if (reg != NULL)
+ gate->reg = ioremap((phys_addr_t)reg, SZ_64K);
+ else
+ gate->reg = NULL;
+ gate->bit_idx = bit_idx;
+ gate->hw_gate = hw_gate;
+
+ init.name = name;
+ init.ops = &clk_gate_scu_ops;
+ init.flags = flags;
+ init.parent_names = parent_name ? &parent_name : NULL;
+ init.num_parents = parent_name ? 1 : 0;
+
+ gate->hw.init = &init;
+
+ clk = clk_register(dev, &gate->hw);
+ if (IS_ERR(clk)) {
+ iounmap(gate->reg);
+ kfree(gate);
+ }
+
+ return clk;
+}
+
+/* Get the power domain associated with the clock from the device tree. */
+static void populate_gate_pd(struct clk_gate2_scu *clk)
+{
+ struct device_node *np;
+ struct of_phandle_args pd_args;
+
+ np = of_find_node_by_name(NULL, clk->pd_name);
+ if (np) {
+ pd_args.np = np;
+ pd_args.args_count = 0;
+ clk->pd = genpd_get_from_provider(&pd_args);
+ if (IS_ERR(clk->pd))
+ pr_warn("%s: failed to get pd\n", __func__);
+ }
+}
+
+/* Write to the LPCG bits. */
+static int clk_gate2_scu_enable(struct clk_hw *hw)
+{
+ struct clk_gate2_scu *gate = to_clk_gate2_scu(hw);
+ u32 reg;
+
+ if (!ccm_ipc_handle)
+ return -1;
+
+ if (gate->pd == NULL && gate->pd_name)
+ populate_gate_pd(gate);
+
+ if (IS_ERR_OR_NULL(gate->pd))
+ return -1;
+
+ if (gate->pd->status != GPD_STATE_ACTIVE)
+ return -1;
+
+ if (gate->reg) {
+ reg = readl(gate->reg);
+ reg |= (0x2 << gate->bit_idx);
+ writel(reg, gate->reg);
+ }
+
+ return 0;
+}
+
+/* Write to the LPCG bits. */
+static void clk_gate2_scu_disable(struct clk_hw *hw)
+{
+ struct clk_gate2_scu *gate = to_clk_gate2_scu(hw);
+ u32 reg;
+
+ if (!ccm_ipc_handle)
+ return;
+
+ if (gate->pd == NULL && gate->pd_name)
+ populate_gate_pd(gate);
+
+ if (IS_ERR_OR_NULL(gate->pd))
+ return;
+
+ if (gate->pd->status != GPD_STATE_ACTIVE)
+ return;
+
+ if (gate->reg) {
+ reg = readl(gate->reg);
+ reg &= ~(0x2 << gate->bit_idx);
+ writel(reg, gate->reg);
+ }
+}
+
+static int clk_gate2_scu_is_enabled(struct clk_hw *hw)
+{
+ struct clk_gate2_scu *gate = to_clk_gate2_scu(hw);
+ u32 val;
+
+ if (gate->pd == NULL && gate->pd_name)
+ populate_gate_pd(gate);
+
+ if (IS_ERR_OR_NULL(gate->pd))
+ return 0;
+
+ if (gate->pd->status != GPD_STATE_ACTIVE)
+ return 0;
+
+ if (gate->reg) {
+ val = readl(gate->reg);
+
+ if (((val >> gate->bit_idx) & 2) == 2)
+ return 1;
+ }
+ return 0;
+}
+
+
+static struct clk_ops clk_gate2_scu_ops = {
+ .enable = clk_gate2_scu_enable,
+ .disable = clk_gate2_scu_disable,
+ .is_enabled = clk_gate2_scu_is_enabled,
+};
+
+struct clk *clk_register_gate2_scu(struct device *dev, const char *name,
+ const char *parent_name, unsigned long flags,
+ void __iomem *reg, u8 bit_idx,
+ u8 clk_gate_flags, spinlock_t *lock, const char *pd_name)
+{
+ struct clk_gate2_scu *gate;
+ struct clk *clk;
+ struct clk_init_data init;
+
+ gate = kzalloc(sizeof(struct clk_gate2_scu), GFP_KERNEL);
+ if (!gate)
+ return ERR_PTR(-ENOMEM);
+
+ /* struct clk_gate_scu assignments */
+ gate->flags = clk_gate_flags;
+ gate->lock = lock;
+ if (reg != NULL)
+ gate->reg = ioremap((phys_addr_t)reg, SZ_64K);
+ else
+ gate->reg = NULL;
+ gate->bit_idx = bit_idx;
+ gate->pd = NULL;
+ gate->pd_name = NULL;
+ if (pd_name) {
+ gate->pd_name = kzalloc(strlen(pd_name) + 1, GFP_KERNEL);
+ strcpy(gate->pd_name, pd_name);
+ }
+
+ init.name = name;
+ init.ops = &clk_gate2_scu_ops;
+ init.flags = flags;
+ init.parent_names = parent_name ? &parent_name : NULL;
+ init.num_parents = parent_name ? 1 : 0;
+
+ gate->hw.init = &init;
+
+ clk = clk_register(dev, &gate->hw);
+ if (IS_ERR(clk)) {
+ iounmap(gate->reg);
+ kfree(gate->pd_name);
+ kfree(gate);
+ }
+
+ return clk;
+}
+
+static int clk_gate3_scu_prepare(struct clk_hw *hw)
+{
+ struct clk_gate3_scu *gate = to_clk_gate3_scu(hw);
+ uint32_t val;
+
+ if (!ccm_ipc_handle)
+ return -1;
+
+ val = (gate->invert) ? 0 : 1;
+
+ return sc_misc_set_control(ccm_ipc_handle,
+ gate->rsrc_id, gate->gpr_id, val);
+}
+
+/* Write to the LPCG bits. */
+static void clk_gate3_scu_unprepare(struct clk_hw *hw)
+{
+ struct clk_gate3_scu *gate = to_clk_gate3_scu(hw);
+ uint32_t val;
+
+ if (!ccm_ipc_handle)
+ return;
+
+ val = (gate->invert) ? 1 : 0;
+ sc_misc_set_control(ccm_ipc_handle, gate->rsrc_id, gate->gpr_id, val);
+}
+
+static int clk_gate3_scu_is_prepared(struct clk_hw *hw)
+{
+ struct clk_gate3_scu *gate = to_clk_gate3_scu(hw);
+ uint32_t val;
+
+ if (!ccm_ipc_handle)
+ return -1;
+
+ sc_misc_get_control(ccm_ipc_handle, gate->rsrc_id, gate->gpr_id, &val);
+ val &= 1;
+
+ if (gate->invert)
+ return 1 - val;
+
+ return val;
+}
+
+static struct clk_ops clk_gate3_scu_ops = {
+ .prepare = clk_gate3_scu_prepare,
+ .unprepare = clk_gate3_scu_unprepare,
+ .is_prepared = clk_gate3_scu_is_prepared,
+};
+
+struct clk *clk_register_gate3_scu(struct device *dev, const char *name,
+ const char *parent_name, spinlock_t *lock,
+ sc_rsrc_t rsrc_id, sc_ctrl_t gpr_id, bool invert_flag)
+{
+ struct clk_gate3_scu *gate;
+ struct clk *clk;
+ struct clk_init_data init;
+
+ if (!imx8_clk_is_resource_owned(rsrc_id)) {
+ pr_debug("skip clk %s rsrc %d not owned\n", name, rsrc_id);
+ return ERR_PTR(-ENODEV);
+ }
+
+ gate = kzalloc(sizeof(struct clk_gate_scu), GFP_KERNEL);
+ if (!gate)
+ return ERR_PTR(-ENOMEM);
+
+ /* struct clk_gate_scu assignments */
+ gate->lock = lock;
+ gate->rsrc_id = rsrc_id;
+ gate->gpr_id = gpr_id;
+ gate->invert = invert_flag;
+
+ init.name = name;
+ init.ops = &clk_gate3_scu_ops;
+ init.flags = 0;
+ init.parent_names = parent_name ? &parent_name : NULL;
+ init.num_parents = parent_name ? 1 : 0;
+
+ gate->hw.init = &init;
+
+ clk = clk_register(dev, &gate->hw);
+ if (IS_ERR(clk))
+ kfree(gate);
+
+ return clk;
+}
diff --git a/drivers/clk/imx/clk-gate2.c b/drivers/clk/imx/clk-gate2.c
index db44a198a0d9..b9bd5938d44a 100644
--- a/drivers/clk/imx/clk-gate2.c
+++ b/drivers/clk/imx/clk-gate2.c
@@ -1,6 +1,7 @@
/*
* Copyright (C) 2010-2011 Canonical Ltd <jeremy.kerr@canonical.com>
* Copyright (C) 2011-2012 Mike Turquette, Linaro Ltd <mturquette@linaro.org>
+ * Copyright (C) 2014-2015 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
@@ -10,11 +11,13 @@
*/
#include <linux/clk-provider.h>
+#include <linux/imx_sema4.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/io.h>
#include <linux/err.h>
#include <linux/string.h>
+#include <soc/imx/src.h>
#include "clk.h"
/**
@@ -38,11 +41,56 @@ struct clk_gate2 {
};
#define to_clk_gate2(_hw) container_of(_hw, struct clk_gate2, hw)
+#define CCM_CCGR_FULL_ENABLE 0x3
+
+static void clk_gate2_do_hardware(struct clk_gate2 *gate, bool enable)
+{
+ u32 reg;
+
+ reg = readl(gate->reg);
+ if (enable)
+ reg |= CCM_CCGR_FULL_ENABLE << gate->bit_idx;
+ else
+ reg &= ~(CCM_CCGR_FULL_ENABLE << gate->bit_idx);
+ writel(reg, gate->reg);
+}
+
+static void clk_gate2_do_shared_clks(struct clk_hw *hw, bool enable)
+{
+ struct clk_gate2 *gate = to_clk_gate2(hw);
+
+ if (imx_src_is_m4_enabled() && clk_on_imx6sx()) {
+#ifdef CONFIG_SOC_IMX6SX
+ if (!amp_power_mutex || !shared_mem) {
+ if (enable)
+ clk_gate2_do_hardware(gate, enable);
+ return;
+ }
+
+ imx_sema4_mutex_lock(amp_power_mutex);
+ if (shared_mem->ca9_valid != SHARED_MEM_MAGIC_NUMBER ||
+ shared_mem->cm4_valid != SHARED_MEM_MAGIC_NUMBER) {
+ imx_sema4_mutex_unlock(amp_power_mutex);
+ return;
+ }
+
+ if (!imx_update_shared_mem(hw, enable)) {
+ imx_sema4_mutex_unlock(amp_power_mutex);
+ return;
+ }
+
+ clk_gate2_do_hardware(gate, enable);
+
+ imx_sema4_mutex_unlock(amp_power_mutex);
+#endif
+ } else {
+ clk_gate2_do_hardware(gate, enable);
+ }
+}
static int clk_gate2_enable(struct clk_hw *hw)
{
struct clk_gate2 *gate = to_clk_gate2(hw);
- u32 reg;
unsigned long flags = 0;
spin_lock_irqsave(gate->lock, flags);
@@ -50,11 +98,7 @@ static int clk_gate2_enable(struct clk_hw *hw)
if (gate->share_count && (*gate->share_count)++ > 0)
goto out;
- reg = readl(gate->reg);
- reg &= ~(3 << gate->bit_idx);
- reg |= gate->cgr_val << gate->bit_idx;
- writel(reg, gate->reg);
-
+ clk_gate2_do_shared_clks(hw, true);
out:
spin_unlock_irqrestore(gate->lock, flags);
@@ -64,7 +108,6 @@ out:
static void clk_gate2_disable(struct clk_hw *hw)
{
struct clk_gate2 *gate = to_clk_gate2(hw);
- u32 reg;
unsigned long flags = 0;
spin_lock_irqsave(gate->lock, flags);
@@ -76,10 +119,7 @@ static void clk_gate2_disable(struct clk_hw *hw)
goto out;
}
- reg = readl(gate->reg);
- reg &= ~(3 << gate->bit_idx);
- writel(reg, gate->reg);
-
+ clk_gate2_do_shared_clks(hw, false);
out:
spin_unlock_irqrestore(gate->lock, flags);
}
@@ -105,15 +145,11 @@ 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);
- }
+ if (!gate->share_count || *gate->share_count == 0)
+ clk_gate2_do_shared_clks(hw, false);
spin_unlock_irqrestore(gate->lock, flags);
}
diff --git a/drivers/clk/imx/clk-imx6q.c b/drivers/clk/imx/clk-imx6q.c
index 8eb93eb2f857..19cd0bfd0fc2 100644
--- a/drivers/clk/imx/clk-imx6q.c
+++ b/drivers/clk/imx/clk-imx6q.c
@@ -1,6 +1,7 @@
/*
- * Copyright 2011-2013 Freescale Semiconductor, Inc.
+ * Copyright (C) 2011-2016 Freescale Semiconductor, Inc.
* Copyright 2011 Linaro Ltd.
+ * Copyright 2017 NXP.
*
* The code contained herein is licensed under the GNU General Public
* License. You may obtain a copy of the GNU General Public License
@@ -31,7 +32,8 @@ static const char *periph_clk2_sels[] = { "pll3_usb_otg", "osc", "osc", "dummy",
static const char *periph2_clk2_sels[] = { "pll3_usb_otg", "pll2_bus", };
static const char *periph_sels[] = { "periph_pre", "periph_clk2", };
static const char *periph2_sels[] = { "periph2_pre", "periph2_clk2", };
-static const char *axi_sels[] = { "periph", "pll2_pfd2_396m", "periph", "pll3_pfd1_540m", };
+static const char *axi_alt_sels[] = { "pll2_pfd2_396m", "pll3_pfd1_540m", };
+static const char *axi_sels[] = { "periph", "axi_alt_sel", };
static const char *audio_sels[] = { "pll4_audio_div", "pll3_pfd2_508m", "pll3_pfd3_454m", "pll3_usb_otg", };
static const char *gpu_axi_sels[] = { "axi", "ahb", };
static const char *pre_axi_sels[] = { "axi", "ahb", };
@@ -41,15 +43,17 @@ static const char *gpu3d_core_sels[] = { "mmdc_ch0_axi", "pll3_usb_otg", "pll2_p
static const char *gpu3d_shader_sels[] = { "mmdc_ch0_axi", "pll3_usb_otg", "pll2_pfd1_594m", "pll3_pfd0_720m", };
static const char *ipu_sels[] = { "mmdc_ch0_axi", "pll2_pfd2_396m", "pll3_120m", "pll3_pfd1_540m", };
static const char *ldb_di_sels[] = { "pll5_video_div", "pll2_pfd0_352m", "pll2_pfd2_396m", "mmdc_ch1_axi", "pll3_usb_otg", };
+static const char *ldb_di0_div_sels[] = { "ldb_di0_div_3_5", "ldb_di0_div_7", };
+static const char *ldb_di1_div_sels[] = { "ldb_di1_div_3_5", "ldb_di1_div_7", };
static const char *ipu_di_pre_sels[] = { "mmdc_ch0_axi", "pll3_usb_otg", "pll5_video_div", "pll2_pfd0_352m", "pll2_pfd2_396m", "pll3_pfd1_540m", };
static const char *ipu1_di0_sels[] = { "ipu1_di0_pre", "dummy", "dummy", "ldb_di0", "ldb_di1", };
static const char *ipu1_di1_sels[] = { "ipu1_di1_pre", "dummy", "dummy", "ldb_di0", "ldb_di1", };
static const char *ipu2_di0_sels[] = { "ipu2_di0_pre", "dummy", "dummy", "ldb_di0", "ldb_di1", };
static const char *ipu2_di1_sels[] = { "ipu2_di1_pre", "dummy", "dummy", "ldb_di0", "ldb_di1", };
-static const char *ipu1_di0_sels_2[] = { "ipu1_di0_pre", "dummy", "dummy", "ldb_di0_podf", "ldb_di1_podf", };
-static const char *ipu1_di1_sels_2[] = { "ipu1_di1_pre", "dummy", "dummy", "ldb_di0_podf", "ldb_di1_podf", };
-static const char *ipu2_di0_sels_2[] = { "ipu2_di0_pre", "dummy", "dummy", "ldb_di0_podf", "ldb_di1_podf", };
-static const char *ipu2_di1_sels_2[] = { "ipu2_di1_pre", "dummy", "dummy", "ldb_di0_podf", "ldb_di1_podf", };
+static const char *ipu1_di0_sels_2[] = { "ipu1_di0_pre", "dummy", "dummy", "ldb_di0_div_sel", "ldb_di1_div_sel", };
+static const char *ipu1_di1_sels_2[] = { "ipu1_di1_pre", "dummy", "dummy", "ldb_di0_div_sel", "ldb_di1_div_sel", };
+static const char *ipu2_di0_sels_2[] = { "ipu2_di0_pre", "dummy", "dummy", "ldb_di0_div_sel", "ldb_di1_div_sel", };
+static const char *ipu2_di1_sels_2[] = { "ipu2_di1_pre", "dummy", "dummy", "ldb_di0_div_sel", "ldb_di1_div_sel", };
static const char *hsi_tx_sels[] = { "pll3_120m", "pll2_pfd2_396m", };
static const char *pcie_axi_sels[] = { "axi", "ahb", };
static const char *ssi_sels[] = { "pll3_pfd2_508m", "pll3_pfd3_454m", "pll4_audio_div", };
@@ -95,11 +99,14 @@ static const char *pll7_bypass_sels[] = { "pll7", "pll7_bypass_src", };
static struct clk *clk[IMX6QDL_CLK_END];
static struct clk_onecell_data clk_data;
+static void __iomem *ccm_base;
static unsigned int const clks_init_on[] __initconst = {
IMX6QDL_CLK_MMDC_CH0_AXI,
IMX6QDL_CLK_ROM,
IMX6QDL_CLK_ARM,
+ IMX6QDL_CLK_OCRAM,
+ IMX6QDL_CLK_AXI,
};
static struct clk_div_table clk_enet_ref_table[] = {
@@ -234,6 +241,12 @@ static void of_assigned_ldb_sels(struct device_node *node,
#define CCM_CCDR 0x04
#define CCM_CCSR 0x0c
#define CCM_CS2CDR 0x2c
+#define CCM_CSCDR3 0x3c
+#define CCM_CCGR0 0x68
+#define CCM_CCGR3 0x74
+
+#define ANATOP_PLL3_PFD 0xf0
+
#define CCDR_MMDC_CH1_MASK BIT(16)
#define CCSR_PLL3_SW_CLK_SEL BIT(0)
@@ -241,6 +254,10 @@ static void of_assigned_ldb_sels(struct device_node *node,
#define CS2CDR_LDB_DI0_CLK_SEL_SHIFT 9
#define CS2CDR_LDB_DI1_CLK_SEL_SHIFT 12
+#define OCOTP_CFG3 0x440
+#define OCOTP_CFG3_SPEED_SHIFT 16
+#define OCOTP_CFG3_SPEED_1P2GHZ 0x3
+
static void __init imx6q_mmdc_ch1_mask_handshake(void __iomem *ccm_base)
{
unsigned int reg;
@@ -388,6 +405,62 @@ static void init_ldb_clks(struct device_node *np, void __iomem *ccm_base)
#define PFD2_CLKGATE BIT(23)
#define PFD3_CLKGATE BIT(31)
+/*
+ * workaround for ERR010579, when switching the clock source of IPU clock
+ * root in CCM. even setting CCGR3[CG0]=0x0 to gate off clock before
+ * switching, IPU may hang due to no IPU clock from CCM.
+ */
+static void __init init_ipu_clk(void __iomem *anatop_base)
+{
+ u32 val, origin_podf;
+
+ /* gate off the IPU1_IPU clock */
+ val = readl_relaxed(ccm_base + CCM_CCGR3);
+ val &= ~0x3;
+ writel_relaxed(val, ccm_base + CCM_CCGR3);
+
+ /* gate off IPU DCIC1/2 clocks */
+ val = readl_relaxed(ccm_base + CCM_CCGR0);
+ val &= ~(0xf << 24);
+ writel_relaxed(val, ccm_base + CCM_CCGR0);
+
+ /* set IPU_PODF to 3'b000 */
+ val = readl_relaxed(ccm_base + CCM_CSCDR3);
+ origin_podf = val & (0x7 << 11);
+ val &= ~(0x7 << 11);
+ writel_relaxed(val, ccm_base + CCM_CSCDR3);
+
+ /* disable PLL3_PFD1 */
+ val = readl_relaxed(anatop_base + ANATOP_PLL3_PFD);
+ val &= ~(0x1 << 15);
+ writel_relaxed(val, anatop_base + ANATOP_PLL3_PFD);
+
+ /* switch IPU_SEL clock to PLL3_PFD1 */
+ val = readl_relaxed(ccm_base + CCM_CSCDR3);
+ val |= (0x3 << 9);
+ writel_relaxed(val, ccm_base + CCM_CSCDR3);
+
+ /* restore the IPU PODF*/
+ val = readl_relaxed(ccm_base + CCM_CSCDR3);
+ val |= origin_podf;
+ writel_relaxed(val, ccm_base + CCM_CSCDR3);
+
+ /* enable PLL3_PFD1 */
+ val = readl_relaxed(anatop_base + ANATOP_PLL3_PFD);
+ val |= (0x1 << 15);
+ writel_relaxed(val, anatop_base + ANATOP_PLL3_PFD);
+
+ /* enable IPU1_IPU clock */
+ val = readl_relaxed(ccm_base + CCM_CCGR3);
+ val |= 0x3;
+ writel_relaxed(val, ccm_base + CCM_CCGR3);
+
+ /* enable IPU DCIC1/2 clock */
+ val = readl_relaxed(ccm_base + CCM_CCGR0);
+ val |= (0xf << 24);
+ writel_relaxed(val, ccm_base + CCM_CCGR0);
+}
+
static void disable_anatop_clocks(void __iomem *anatop_base)
{
unsigned int reg;
@@ -418,7 +491,7 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
struct device_node *np;
void __iomem *anatop_base, *base;
int i;
- int ret;
+ u32 val;
clk[IMX6QDL_CLK_DUMMY] = imx_clk_fixed("dummy", 0);
clk[IMX6QDL_CLK_CKIL] = imx_obtain_fixed_clock("ckil", 0);
@@ -450,7 +523,7 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
/* type name parent_name base div_mask */
clk[IMX6QDL_CLK_PLL1] = imx_clk_pllv3(IMX_PLLV3_SYS, "pll1", "osc", base + 0x00, 0x7f);
- clk[IMX6QDL_CLK_PLL2] = imx_clk_pllv3(IMX_PLLV3_GENERIC, "pll2", "osc", base + 0x30, 0x1);
+ clk[IMX6QDL_CLK_PLL2] = imx_clk_pllv3(IMX_PLLV3_PLL2, "pll2", "osc", base + 0x30, 0x1);
clk[IMX6QDL_CLK_PLL3] = imx_clk_pllv3(IMX_PLLV3_USB, "pll3", "osc", base + 0x10, 0x3);
clk[IMX6QDL_CLK_PLL4] = imx_clk_pllv3(IMX_PLLV3_AV, "pll4", "osc", base + 0x70, 0x7f);
clk[IMX6QDL_CLK_PLL5] = imx_clk_pllv3(IMX_PLLV3_AV, "pll5", "osc", base + 0xa0, 0x7f);
@@ -474,7 +547,7 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
clk_set_parent(clk[IMX6QDL_PLL6_BYPASS], clk[IMX6QDL_CLK_PLL6]);
clk_set_parent(clk[IMX6QDL_PLL7_BYPASS], clk[IMX6QDL_CLK_PLL7]);
- clk[IMX6QDL_CLK_PLL1_SYS] = imx_clk_gate("pll1_sys", "pll1_bypass", base + 0x00, 13);
+ clk[IMX6QDL_CLK_PLL1_SYS] = imx_clk_fixed_factor("pll1_sys", "pll1_bypass", 1, 1);
clk[IMX6QDL_CLK_PLL2_BUS] = imx_clk_gate("pll2_bus", "pll2_bypass", base + 0x30, 13);
clk[IMX6QDL_CLK_PLL3_USB_OTG] = imx_clk_gate("pll3_usb_otg", "pll3_bypass", base + 0x10, 13);
clk[IMX6QDL_CLK_PLL4_AUDIO] = imx_clk_gate("pll4_audio", "pll4_bypass", base + 0x70, 13);
@@ -549,23 +622,25 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
clk[IMX6QDL_CLK_GPU3D_AXI] = imx_clk_fixed_factor("gpu3d_axi", "mmdc_ch0_axi_podf", 1, 1);
}
- clk[IMX6QDL_CLK_PLL4_POST_DIV] = clk_register_divider_table(NULL, "pll4_post_div", "pll4_audio", CLK_SET_RATE_PARENT, base + 0x70, 19, 2, 0, post_div_table, &imx_ccm_lock);
- clk[IMX6QDL_CLK_PLL4_AUDIO_DIV] = clk_register_divider(NULL, "pll4_audio_div", "pll4_post_div", CLK_SET_RATE_PARENT, base + 0x170, 15, 1, 0, &imx_ccm_lock);
- clk[IMX6QDL_CLK_PLL5_POST_DIV] = clk_register_divider_table(NULL, "pll5_post_div", "pll5_video", CLK_SET_RATE_PARENT, base + 0xa0, 19, 2, 0, post_div_table, &imx_ccm_lock);
- clk[IMX6QDL_CLK_PLL5_VIDEO_DIV] = clk_register_divider_table(NULL, "pll5_video_div", "pll5_post_div", CLK_SET_RATE_PARENT, base + 0x170, 30, 2, 0, video_div_table, &imx_ccm_lock);
+ clk[IMX6QDL_CLK_PLL4_POST_DIV] = clk_register_divider_table(NULL, "pll4_post_div", "pll4_audio", CLK_SET_RATE_PARENT | CLK_SET_RATE_GATE, base + 0x70, 19, 2, 0, post_div_table, &imx_ccm_lock);
+ clk[IMX6QDL_CLK_PLL4_AUDIO_DIV] = clk_register_divider(NULL, "pll4_audio_div", "pll4_post_div", CLK_SET_RATE_PARENT | CLK_SET_RATE_GATE, base + 0x170, 15, 1, 0, &imx_ccm_lock);
+ clk[IMX6QDL_CLK_PLL5_POST_DIV] = clk_register_divider_table(NULL, "pll5_post_div", "pll5_video", CLK_SET_RATE_PARENT | CLK_SET_RATE_GATE, base + 0xa0, 19, 2, 0, post_div_table, &imx_ccm_lock);
+ clk[IMX6QDL_CLK_PLL5_VIDEO_DIV] = clk_register_divider_table(NULL, "pll5_video_div", "pll5_post_div", CLK_SET_RATE_PARENT | CLK_SET_RATE_GATE, base + 0x170, 30, 2, 0, video_div_table, &imx_ccm_lock);
np = ccm_node;
base = of_iomap(np, 0);
+ ccm_base = base;
WARN_ON(!base);
/* name reg shift width parent_names num_parents */
clk[IMX6QDL_CLK_STEP] = imx_clk_mux("step", base + 0xc, 8, 1, step_sels, ARRAY_SIZE(step_sels));
- clk[IMX6QDL_CLK_PLL1_SW] = imx_clk_mux("pll1_sw", base + 0xc, 2, 1, pll1_sw_sels, ARRAY_SIZE(pll1_sw_sels));
- clk[IMX6QDL_CLK_PERIPH_PRE] = imx_clk_mux("periph_pre", base + 0x18, 18, 2, periph_pre_sels, ARRAY_SIZE(periph_pre_sels));
+ clk[IMX6QDL_CLK_PLL1_SW] = imx_clk_mux_glitchless("pll1_sw", base + 0xc, 2, 1, pll1_sw_sels, ARRAY_SIZE(pll1_sw_sels));
+ clk[IMX6QDL_CLK_PERIPH_PRE] = imx_clk_mux_bus("periph_pre", base + 0x18, 18, 2, periph_pre_sels, ARRAY_SIZE(periph_pre_sels));
clk[IMX6QDL_CLK_PERIPH2_PRE] = imx_clk_mux("periph2_pre", base + 0x18, 21, 2, periph_pre_sels, ARRAY_SIZE(periph_pre_sels));
- clk[IMX6QDL_CLK_PERIPH_CLK2_SEL] = imx_clk_mux("periph_clk2_sel", base + 0x18, 12, 2, periph_clk2_sels, ARRAY_SIZE(periph_clk2_sels));
+ clk[IMX6QDL_CLK_PERIPH_CLK2_SEL] = imx_clk_mux_bus("periph_clk2_sel", base + 0x18, 12, 2, periph_clk2_sels, ARRAY_SIZE(periph_clk2_sels));
clk[IMX6QDL_CLK_PERIPH2_CLK2_SEL] = imx_clk_mux("periph2_clk2_sel", base + 0x18, 20, 1, periph2_clk2_sels, ARRAY_SIZE(periph2_clk2_sels));
- clk[IMX6QDL_CLK_AXI_SEL] = imx_clk_mux("axi_sel", base + 0x14, 6, 2, axi_sels, ARRAY_SIZE(axi_sels));
+ clk[IMX6QDL_CLK_AXI_ALT_SEL] = imx_clk_mux("axi_alt_sel", base + 0x14, 7, 1, axi_alt_sels, ARRAY_SIZE(axi_alt_sels));
+ clk[IMX6QDL_CLK_AXI_SEL] = imx_clk_mux_glitchless("axi_sel", base + 0x14, 6, 1, axi_sels, ARRAY_SIZE(axi_sels));
clk[IMX6QDL_CLK_ESAI_SEL] = imx_clk_mux("esai_sel", base + 0x20, 19, 2, audio_sels, ARRAY_SIZE(audio_sels));
clk[IMX6QDL_CLK_ASRC_SEL] = imx_clk_mux("asrc_sel", base + 0x30, 7, 2, audio_sels, ARRAY_SIZE(audio_sels));
clk[IMX6QDL_CLK_SPDIF_SEL] = imx_clk_mux("spdif_sel", base + 0x30, 20, 2, audio_sels, ARRAY_SIZE(audio_sels));
@@ -592,14 +667,13 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
clk[IMX6QDL_CLK_IPU1_SEL] = imx_clk_mux("ipu1_sel", base + 0x3c, 9, 2, ipu_sels, ARRAY_SIZE(ipu_sels));
clk[IMX6QDL_CLK_IPU2_SEL] = imx_clk_mux("ipu2_sel", base + 0x3c, 14, 2, ipu_sels, ARRAY_SIZE(ipu_sels));
- disable_anatop_clocks(anatop_base);
-
- imx6q_mmdc_ch1_mask_handshake(base);
-
if (clk_on_imx6qp()) {
clk[IMX6QDL_CLK_LDB_DI0_SEL] = imx_clk_mux_flags("ldb_di0_sel", base + 0x2c, 9, 3, ldb_di_sels, ARRAY_SIZE(ldb_di_sels), CLK_SET_RATE_PARENT);
clk[IMX6QDL_CLK_LDB_DI1_SEL] = imx_clk_mux_flags("ldb_di1_sel", base + 0x2c, 12, 3, ldb_di_sels, ARRAY_SIZE(ldb_di_sels), CLK_SET_RATE_PARENT);
} else {
+ disable_anatop_clocks(anatop_base);
+
+ imx6q_mmdc_ch1_mask_handshake(base);
/*
* The LDB_DI0/1_SEL muxes are registered read-only due to a hardware
* bug. Set the muxes to the requested values before registering the
@@ -610,6 +684,8 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
clk[IMX6QDL_CLK_LDB_DI0_SEL] = imx_clk_mux_ldb("ldb_di0_sel", base + 0x2c, 9, 3, ldb_di_sels, ARRAY_SIZE(ldb_di_sels));
clk[IMX6QDL_CLK_LDB_DI1_SEL] = imx_clk_mux_ldb("ldb_di1_sel", base + 0x2c, 12, 3, ldb_di_sels, ARRAY_SIZE(ldb_di_sels));
}
+ clk[IMX6QDL_CLK_LDB_DI0_DIV_SEL] = imx_clk_mux_flags("ldb_di0_div_sel", base + 0x20, 10, 1, ldb_di0_div_sels, ARRAY_SIZE(ldb_di0_div_sels), CLK_SET_RATE_PARENT);
+ clk[IMX6QDL_CLK_LDB_DI1_DIV_SEL] = imx_clk_mux_flags("ldb_di1_div_sel", base + 0x20, 11, 1, ldb_di1_div_sels, ARRAY_SIZE(ldb_di1_div_sels), CLK_SET_RATE_PARENT);
clk[IMX6QDL_CLK_IPU1_DI0_PRE_SEL] = imx_clk_mux_flags("ipu1_di0_pre_sel", base + 0x34, 6, 3, ipu_di_pre_sels, ARRAY_SIZE(ipu_di_pre_sels), CLK_SET_RATE_PARENT);
clk[IMX6QDL_CLK_IPU1_DI1_PRE_SEL] = imx_clk_mux_flags("ipu1_di1_pre_sel", base + 0x34, 15, 3, ipu_di_pre_sels, ARRAY_SIZE(ipu_di_pre_sels), CLK_SET_RATE_PARENT);
clk[IMX6QDL_CLK_IPU2_DI0_PRE_SEL] = imx_clk_mux_flags("ipu2_di0_pre_sel", base + 0x38, 6, 3, ipu_di_pre_sels, ARRAY_SIZE(ipu_di_pre_sels), CLK_SET_RATE_PARENT);
@@ -675,6 +751,8 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
clk[IMX6QDL_CLK_UART_SERIAL_PODF] = imx_clk_divider("uart_serial_podf", "uart_sel", base + 0x24, 0, 6);
clk[IMX6QDL_CLK_LDB_DI0_DIV_3_5] = imx_clk_fixed_factor("ldb_di0_div_3_5", "ldb_di0", 2, 7);
clk[IMX6QDL_CLK_LDB_DI1_DIV_3_5] = imx_clk_fixed_factor("ldb_di1_div_3_5", "ldb_di1", 2, 7);
+ clk[IMX6QDL_CLK_LDB_DI0_DIV_7] = imx_clk_fixed_factor("ldb_di0_div_7", "ldb_di0", 1, 7);
+ clk[IMX6QDL_CLK_LDB_DI1_DIV_7] = imx_clk_fixed_factor("ldb_di1_div_7", "ldb_di1", 1, 7);
} else {
clk[IMX6QDL_CLK_ECSPI_ROOT] = imx_clk_divider("ecspi_root", "pll3_60m", base + 0x38, 19, 6);
clk[IMX6QDL_CLK_CAN_ROOT] = imx_clk_divider("can_root", "pll3_60m", base + 0x20, 2, 6);
@@ -682,6 +760,8 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
clk[IMX6QDL_CLK_UART_SERIAL_PODF] = imx_clk_divider("uart_serial_podf", "pll3_80m", base + 0x24, 0, 6);
clk[IMX6QDL_CLK_LDB_DI0_DIV_3_5] = imx_clk_fixed_factor("ldb_di0_div_3_5", "ldb_di0_sel", 2, 7);
clk[IMX6QDL_CLK_LDB_DI1_DIV_3_5] = imx_clk_fixed_factor("ldb_di1_div_3_5", "ldb_di1_sel", 2, 7);
+ clk[IMX6QDL_CLK_LDB_DI0_DIV_7] = imx_clk_fixed_factor("ldb_di0_div_7", "ldb_di0_sel", 1, 7);
+ clk[IMX6QDL_CLK_LDB_DI1_DIV_7] = imx_clk_fixed_factor("ldb_di1_div_7", "ldb_di1_sel", 1, 7);
}
if (clk_on_imx6dl())
clk[IMX6QDL_CLK_MLB_PODF] = imx_clk_divider("mlb_podf", "mlb_sel", base + 0x18, 23, 3);
@@ -748,6 +828,8 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
clk[IMX6QDL_CLK_CAN1_SERIAL] = imx_clk_gate2("can1_serial", "can_root", base + 0x68, 16);
clk[IMX6QDL_CLK_CAN2_IPG] = imx_clk_gate2("can2_ipg", "ipg", base + 0x68, 18);
clk[IMX6QDL_CLK_CAN2_SERIAL] = imx_clk_gate2("can2_serial", "can_root", base + 0x68, 20);
+ clk[IMX6QDL_CLK_DCIC1] = imx_clk_gate2("dcic1", "ipu1_podf", base + 0x68, 24);
+ clk[IMX6QDL_CLK_DCIC2] = imx_clk_gate2("dcic2", "ipu2_podf", base + 0x68, 26);
clk[IMX6QDL_CLK_ECSPI1] = imx_clk_gate2("ecspi1", "ecspi_root", base + 0x6c, 0);
clk[IMX6QDL_CLK_ECSPI2] = imx_clk_gate2("ecspi2", "ecspi_root", base + 0x6c, 2);
clk[IMX6QDL_CLK_ECSPI3] = imx_clk_gate2("ecspi3", "ecspi_root", base + 0x6c, 4);
@@ -765,7 +847,7 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
clk[IMX6QDL_CLK_GPU2D_CORE] = imx_clk_gate2("gpu2d_core", "gpu2d_core_podf", base + 0x6c, 24);
clk[IMX6QDL_CLK_GPU3D_CORE] = imx_clk_gate2("gpu3d_core", "gpu3d_core_podf", base + 0x6c, 26);
clk[IMX6QDL_CLK_HDMI_IAHB] = imx_clk_gate2("hdmi_iahb", "ahb", base + 0x70, 0);
- clk[IMX6QDL_CLK_HDMI_ISFR] = imx_clk_gate2("hdmi_isfr", "mipi_core_cfg", base + 0x70, 4);
+ clk[IMX6QDL_CLK_HDMI_ISFR] = imx_clk_gate2("hdmi_isfr", "pll3_pfd1_540m", base + 0x70, 4);
clk[IMX6QDL_CLK_I2C1] = imx_clk_gate2("i2c1", "ipg_per", base + 0x70, 6);
clk[IMX6QDL_CLK_I2C2] = imx_clk_gate2("i2c2", "ipg_per", base + 0x70, 8);
clk[IMX6QDL_CLK_I2C3] = imx_clk_gate2("i2c3", "ipg_per", base + 0x70, 10);
@@ -858,11 +940,27 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
clk_data.clk_num = ARRAY_SIZE(clk);
of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
+ clk_register_clkdev(clk[IMX6QDL_CLK_GPT_IPG], "ipg", "imx-gpt.0");
+ clk_register_clkdev(clk[IMX6QDL_CLK_GPT_IPG_PER], "per", "imx-gpt.0");
+ clk_register_clkdev(clk[IMX6QDL_CLK_GPT_3M], "gpt_3m", "imx-gpt.0");
clk_register_clkdev(clk[IMX6QDL_CLK_ENET_REF], "enet_ref", NULL);
clk_set_rate(clk[IMX6QDL_CLK_PLL3_PFD1_540M], 540000000);
- if (clk_on_imx6dl())
+ if (clk_on_imx6dl()) {
+ init_ipu_clk(anatop_base);
clk_set_parent(clk[IMX6QDL_CLK_IPU1_SEL], clk[IMX6QDL_CLK_PLL3_PFD1_540M]);
+ clk_set_parent(clk[IMX6QDL_CLK_AXI_ALT_SEL], clk[IMX6QDL_CLK_PLL3_PFD1_540M]);
+ clk_set_parent(clk[IMX6QDL_CLK_AXI_SEL], clk[IMX6QDL_CLK_AXI_ALT_SEL]);
+ /* set epdc/pxp axi clock to 200Mhz */
+ clk_set_parent(clk[IMX6QDL_CLK_IPU2_SEL], clk[IMX6QDL_CLK_PLL2_PFD2_396M]);
+ clk_set_rate(clk[IMX6QDL_CLK_IPU2], 200000000);
+ } else {
+ /* set eim_slow to 132Mhz for i.MX6Q */
+ if (clk_on_imx6q())
+ clk_set_rate(clk[IMX6QDL_CLK_EIM_SLOW], 132000000);
+ clk_set_parent(clk[IMX6QDL_CLK_IPU1_SEL], clk[IMX6QDL_CLK_MMDC_CH0_AXI]);
+ clk_set_parent(clk[IMX6QDL_CLK_IPU2_SEL], clk[IMX6QDL_CLK_MMDC_CH0_AXI]);
+ }
clk_set_parent(clk[IMX6QDL_CLK_IPU1_DI0_PRE_SEL], clk[IMX6QDL_CLK_PLL5_VIDEO_DIV]);
clk_set_parent(clk[IMX6QDL_CLK_IPU1_DI1_PRE_SEL], clk[IMX6QDL_CLK_PLL5_VIDEO_DIV]);
@@ -873,6 +971,7 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
clk_set_parent(clk[IMX6QDL_CLK_IPU2_DI0_SEL], clk[IMX6QDL_CLK_IPU2_DI0_PRE]);
clk_set_parent(clk[IMX6QDL_CLK_IPU2_DI1_SEL], clk[IMX6QDL_CLK_IPU2_DI1_PRE]);
+
/*
* The gpmi needs 100MHz frequency in the EDO/Sync mode,
* We can not get the 100MHz from the pll2_pfd0_352m.
@@ -880,30 +979,93 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
*/
clk_set_parent(clk[IMX6QDL_CLK_ENFC_SEL], clk[IMX6QDL_CLK_PLL2_PFD2_396M]);
- for (i = 0; i < ARRAY_SIZE(clks_init_on); i++)
- clk_prepare_enable(clk[clks_init_on[i]]);
-
- if (IS_ENABLED(CONFIG_USB_MXS_PHY)) {
- clk_prepare_enable(clk[IMX6QDL_CLK_USBPHY1_GATE]);
- clk_prepare_enable(clk[IMX6QDL_CLK_USBPHY2_GATE]);
+ /* gpu clock initilazation */
+ /*
+ * On mx6dl, 2d core clock sources(sel, podf) is from 3d
+ * shader core clock, but 3d shader clock multiplexer of
+ * mx6dl is different. For instance the equivalent of
+ * pll2_pfd_594M on mx6q is pll2_pfd_528M on mx6dl.
+ * Make a note here.
+ */
+ if (clk_on_imx6dl()) {
+ clk_set_parent(clk[IMX6QDL_CLK_GPU3D_SHADER_SEL], clk[IMX6QDL_CLK_PLL2_PFD1_594M]);
+ imx_clk_set_rate(clk[IMX6QDL_CLK_GPU3D_SHADER], 528000000);
+ /* for mx6dl, change gpu3d_core parent to 594_PFD*/
+ clk_set_parent(clk[IMX6QDL_CLK_GPU3D_CORE_SEL], clk[IMX6QDL_CLK_PLL2_PFD1_594M]);
+ imx_clk_set_rate(clk[IMX6QDL_CLK_GPU3D_CORE], 528000000);
+ } else if (clk_on_imx6q()) {
+ if (imx_get_soc_revision() >= IMX_CHIP_REVISION_2_0) {
+ clk_set_parent(clk[IMX6QDL_CLK_GPU3D_SHADER_SEL], clk[IMX6QDL_CLK_PLL3_PFD0_720M]);
+ imx_clk_set_rate(clk[IMX6QDL_CLK_GPU3D_SHADER], 720000000);
+ clk_set_parent(clk[IMX6QDL_CLK_GPU3D_CORE_SEL], clk[IMX6QDL_CLK_PLL2_PFD1_594M]);
+ imx_clk_set_rate(clk[IMX6QDL_CLK_GPU3D_CORE], 594000000);
+ clk_set_parent(clk[IMX6QDL_CLK_GPU2D_CORE_SEL], clk[IMX6QDL_CLK_PLL3_PFD0_720M]);
+ imx_clk_set_rate(clk[IMX6QDL_CLK_GPU2D_CORE], 720000000);
+ } else {
+ clk_set_parent(clk[IMX6QDL_CLK_GPU3D_SHADER_SEL], clk[IMX6QDL_CLK_PLL2_PFD1_594M]);
+ imx_clk_set_rate(clk[IMX6QDL_CLK_GPU3D_SHADER], 594000000);
+ clk_set_parent(clk[IMX6QDL_CLK_GPU3D_CORE_SEL], clk[IMX6QDL_CLK_MMDC_CH0_AXI]);
+ imx_clk_set_rate(clk[IMX6QDL_CLK_GPU3D_CORE], 528000000);
+ clk_set_parent(clk[IMX6QDL_CLK_GPU2D_CORE_SEL], clk[IMX6QDL_CLK_PLL3_USB_OTG]);
+ imx_clk_set_rate(clk[IMX6QDL_CLK_GPU2D_CORE], 480000000);
+ }
}
/*
* Let's initially set up CLKO with OSC24M, since this configuration
* is widely used by imx6q board designs to clock audio codec.
*/
- ret = clk_set_parent(clk[IMX6QDL_CLK_CKO2_SEL], clk[IMX6QDL_CLK_OSC]);
- if (!ret)
- ret = clk_set_parent(clk[IMX6QDL_CLK_CKO], clk[IMX6QDL_CLK_CKO2]);
- if (ret)
- pr_warn("failed to set up CLKO: %d\n", ret);
+ imx_clk_set_parent(clk[IMX6QDL_CLK_CKO2_SEL], clk[IMX6QDL_CLK_OSC]);
+ imx_clk_set_parent(clk[IMX6QDL_CLK_CKO], clk[IMX6QDL_CLK_CKO2]);
/* Audio-related clocks configuration */
clk_set_parent(clk[IMX6QDL_CLK_SPDIF_SEL], clk[IMX6QDL_CLK_PLL3_PFD3_454M]);
/* All existing boards with PCIe use LVDS1 */
- if (IS_ENABLED(CONFIG_PCI_IMX6))
+ if (IS_ENABLED(CONFIG_PCI_IMX6)) {
clk_set_parent(clk[IMX6QDL_CLK_LVDS1_SEL], clk[IMX6QDL_CLK_SATA_REF_100M]);
+ np = of_find_compatible_node(NULL, NULL, "snps,dw-pcie");
+ /* external oscillator is used or not. */
+ if (of_property_read_u32(np, "ext_osc", &val) < 0)
+ val = 0;
+ /*
+ * imx6qp sabresd revb board has the external osc used by pcie
+ * - pll6 should be set bypass mode later in driver.
+ * - lvds_clk1 should be selected as pll6 bypass src, set here.
+ */
+ if (clk_on_imx6qp() && val == 1)
+ clk_set_parent(clk[IMX6QDL_PLL6_BYPASS_SRC], clk[IMX6QDL_CLK_LVDS1_IN]);
+ }
+
+ /*
+ * Enable clocks only after both parent and rate are all initialized
+ * as needed
+ */
+ for (i = 0; i < ARRAY_SIZE(clks_init_on); i++)
+ imx_clk_prepare_enable(clk[clks_init_on[i]]);
+
+ if (IS_ENABLED(CONFIG_USB_MXS_PHY)) {
+ imx_clk_prepare_enable(clk[IMX6QDL_CLK_USBPHY1_GATE]);
+ imx_clk_prepare_enable(clk[IMX6QDL_CLK_USBPHY2_GATE]);
+ }
+
+ /*Set enet_ref clock to 125M to supply for RGMII tx_clk */
+ clk_set_rate(clk[IMX6QDL_CLK_ENET_REF], 125000000);
+
+#ifdef CONFIG_MX6_VPU_352M
+ /*
+ * If VPU 352M is enabled, then PLL2_PDF2 need to be
+ * set to 352M, cpufreq will be disabled as VDDSOC/PU
+ * need to be at highest voltage, scaling cpu freq is
+ * not saving any power, and busfreq will be also disabled
+ * as the PLL2_PFD2 is not at default freq, in a word,
+ * all modules that sourceing clk from PLL2_PFD2 will
+ * be impacted.
+ */
+ imx_clk_set_rate(clk[IMX6QDL_CLK_PLL2_PFD2_396M], 352000000);
+ clk_set_parent(clk[IMX6QDL_CLK_VPU_AXI_SEL], clk[IMX6QDL_CLK_PLL2_PFD2_396M]);
+ pr_info("VPU 352M is enabled!\n");
+#endif
/*
* Initialize the GPU clock muxes, so that the maximum specified clock
@@ -924,5 +1086,35 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
}
imx_register_uart_clocks(uart_clks);
+
+ /*
+ * for i.MX6QP with speeding grading set to 1.2GHz,
+ * VPU should run at 396MHz.
+ */
+ if (clk_on_imx6q() && imx_get_soc_revision() >= IMX_CHIP_REVISION_2_0) {
+ np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-ocotp");
+ WARN_ON(!np);
+
+ base = of_iomap(np, 0);
+ WARN_ON(!base);
+
+ /*
+ * SPEED_GRADING[1:0] defines the max speed of ARM:
+ * 2b'11: 1200000000Hz;
+ * 2b'10: 996000000Hz;
+ * 2b'01: 852000000Hz; -- i.MX6Q Only, exclusive with 996MHz.
+ * 2b'00: 792000000Hz;
+ * We need to set the max speed of ARM according to fuse map.
+ */
+ val = readl_relaxed(base + OCOTP_CFG3);
+ val >>= OCOTP_CFG3_SPEED_SHIFT;
+ val &= 0x3;
+ if (val == OCOTP_CFG3_SPEED_1P2GHZ) {
+ imx_clk_set_parent(clk[IMX6QDL_CLK_VPU_AXI_SEL], clk[IMX6QDL_CLK_PLL2_PFD2_396M]);
+ imx_clk_set_rate(clk[IMX6QDL_CLK_VPU_AXI_PODF], 396000000);
+ pr_info("VPU frequency set to 396MHz!\n");
+ }
+ iounmap(base);
+ }
}
CLK_OF_DECLARE(imx6q, "fsl,imx6q-ccm", imx6q_clocks_init);
diff --git a/drivers/clk/imx/clk-imx6sl.c b/drivers/clk/imx/clk-imx6sl.c
index c264a744fae8..d0667b561e96 100644
--- a/drivers/clk/imx/clk-imx6sl.c
+++ b/drivers/clk/imx/clk-imx6sl.c
@@ -7,6 +7,7 @@
*
*/
+#include <linux/busfreq-imx.h>
#include <linux/clk.h>
#include <linux/clkdev.h>
#include <linux/err.h>
@@ -17,9 +18,9 @@
#include "clk.h"
-#define CCDR 0x4
-#define BM_CCM_CCDR_MMDC_CH0_MASK (1 << 17)
#define CCSR 0xc
+#define CCDR 0x04
+#define CCDR_CH0_HS_BYP 17
#define BM_CCSR_PLL1_SW_CLK_SEL (1 << 2)
#define CACRR 0x10
#define CDHIPR 0x48
@@ -57,7 +58,7 @@ static const char *lcdif_pix_sels[] = { "pll2_bus", "pll3_usb_otg", "pll5_video_
static const char *epdc_pix_sels[] = { "pll2_bus", "pll3_usb_otg", "pll5_video_div", "pll2_pfd0", "pll2_pfd1", "pll3_pfd1", };
static const char *audio_sels[] = { "pll4_audio_div", "pll3_pfd2", "pll3_pfd3", "pll3_usb_otg", };
static const char *ecspi_sels[] = { "pll3_60m", "osc", };
-static const char *uart_sels[] = { "pll3_80m", "osc", };
+static const char *uart_sels[] = { "pll3_80m", "uart_osc_4m", };
static const char *lvds_sels[] = {
"pll1_sys", "pll2_bus", "pll2_pfd0", "pll2_pfd1", "pll2_pfd2", "dummy", "pll4_audio", "pll5_video",
"dummy", "enet_ref", "dummy", "dummy", "pll3_usb_otg", "pll7_usb_host", "pll3_pfd0", "pll3_pfd1",
@@ -145,46 +146,39 @@ static int imx6sl_get_arm_divider_for_wait(void)
}
}
-static void imx6sl_enable_pll_arm(bool enable)
-{
- static u32 saved_pll_arm;
- u32 val;
-
- if (enable) {
- saved_pll_arm = val = readl_relaxed(anatop_base + PLL_ARM);
- val |= BM_PLL_ARM_ENABLE;
- val &= ~BM_PLL_ARM_POWERDOWN;
- writel_relaxed(val, anatop_base + PLL_ARM);
- while (!(__raw_readl(anatop_base + PLL_ARM) & BM_PLL_ARM_LOCK))
- ;
- } else {
- writel_relaxed(saved_pll_arm, anatop_base + PLL_ARM);
- }
-}
-
void imx6sl_set_wait_clk(bool enter)
{
static unsigned long saved_arm_div;
+ u32 val;
int arm_div_for_wait = imx6sl_get_arm_divider_for_wait();
-
- /*
- * According to hardware design, arm podf change need
- * PLL1 clock enabled.
- */
- if (arm_div_for_wait == ARM_WAIT_DIV_396M)
- imx6sl_enable_pll_arm(true);
+ int mode = get_bus_freq_mode();
if (enter) {
- saved_arm_div = readl_relaxed(ccm_base + CACRR);
- writel_relaxed(arm_div_for_wait, ccm_base + CACRR);
+ /*
+ * If in this mode, the IPG clock is at 12MHz, we can
+ * only run ARM at a max 28.8MHz, so we need to run
+ * from the 24MHz OSC, as there is no way to get
+ * 28.8MHz, when ARM is sourced from PLl1.
+ */
+ if (mode == BUS_FREQ_LOW) {
+ val = readl_relaxed(ccm_base + CCSR);
+ val |= BM_CCSR_PLL1_SW_CLK_SEL;
+ writel_relaxed(val, ccm_base + CCSR);
+ } else {
+ saved_arm_div = readl_relaxed(ccm_base + CACRR);
+ writel_relaxed(arm_div_for_wait, ccm_base + CACRR);
+ }
} else {
- writel_relaxed(saved_arm_div, ccm_base + CACRR);
+ if (mode == BUS_FREQ_LOW) {
+ val = readl_relaxed(ccm_base + CCSR);
+ val &= ~BM_CCSR_PLL1_SW_CLK_SEL;
+ writel_relaxed(val, ccm_base + CCSR);
+ } else {
+ writel_relaxed(saved_arm_div, ccm_base + CACRR);
+ }
}
while (__raw_readl(ccm_base + CDHIPR) & BM_CDHIPR_ARM_PODF_BUSY)
;
-
- if (arm_div_for_wait == ARM_WAIT_DIV_396M)
- imx6sl_enable_pll_arm(false);
}
static struct clk ** const uart_clks[] __initconst = {
@@ -197,7 +191,7 @@ static void __init imx6sl_clocks_init(struct device_node *ccm_node)
{
struct device_node *np;
void __iomem *base;
- int i;
+ int i, reg;
int ret;
clks[IMX6SL_CLK_DUMMY] = imx_clk_fixed("dummy", 0);
@@ -229,7 +223,7 @@ static void __init imx6sl_clocks_init(struct device_node *ccm_node)
clks[IMX6SL_CLK_PLL7] = imx_clk_pllv3(IMX_PLLV3_USB, "pll7", "osc", base + 0x20, 0x3);
clks[IMX6SL_PLL1_BYPASS] = imx_clk_mux_flags("pll1_bypass", base + 0x00, 16, 1, pll1_bypass_sels, ARRAY_SIZE(pll1_bypass_sels), CLK_SET_RATE_PARENT);
- clks[IMX6SL_PLL2_BYPASS] = imx_clk_mux_flags("pll2_bypass", base + 0x30, 16, 1, pll2_bypass_sels, ARRAY_SIZE(pll2_bypass_sels), CLK_SET_RATE_PARENT);
+ clks[IMX6SL_PLL2_BYPASS] = imx_clk_mux_flags_bus("pll2_bypass", base + 0x30, 16, 1, pll2_bypass_sels, ARRAY_SIZE(pll2_bypass_sels), CLK_SET_RATE_PARENT);
clks[IMX6SL_PLL3_BYPASS] = imx_clk_mux_flags("pll3_bypass", base + 0x10, 16, 1, pll3_bypass_sels, ARRAY_SIZE(pll3_bypass_sels), CLK_SET_RATE_PARENT);
clks[IMX6SL_PLL4_BYPASS] = imx_clk_mux_flags("pll4_bypass", base + 0x70, 16, 1, pll4_bypass_sels, ARRAY_SIZE(pll4_bypass_sels), CLK_SET_RATE_PARENT);
clks[IMX6SL_PLL5_BYPASS] = imx_clk_mux_flags("pll5_bypass", base + 0xa0, 16, 1, pll5_bypass_sels, ARRAY_SIZE(pll5_bypass_sels), CLK_SET_RATE_PARENT);
@@ -245,7 +239,7 @@ static void __init imx6sl_clocks_init(struct device_node *ccm_node)
clk_set_parent(clks[IMX6SL_PLL6_BYPASS], clks[IMX6SL_CLK_PLL6]);
clk_set_parent(clks[IMX6SL_PLL7_BYPASS], clks[IMX6SL_CLK_PLL7]);
- clks[IMX6SL_CLK_PLL1_SYS] = imx_clk_gate("pll1_sys", "pll1_bypass", base + 0x00, 13);
+ clks[IMX6SL_CLK_PLL1_SYS] = imx_clk_fixed_factor("pll1_sys", "pll1_bypass", 1, 1);
clks[IMX6SL_CLK_PLL2_BUS] = imx_clk_gate("pll2_bus", "pll2_bypass", base + 0x30, 13);
clks[IMX6SL_CLK_PLL3_USB_OTG] = imx_clk_gate("pll3_usb_otg", "pll3_bypass", base + 0x10, 13);
clks[IMX6SL_CLK_PLL4_AUDIO] = imx_clk_gate("pll4_audio", "pll4_bypass", base + 0x70, 13);
@@ -273,7 +267,7 @@ static void __init imx6sl_clocks_init(struct device_node *ccm_node)
clks[IMX6SL_CLK_PLL4_POST_DIV] = clk_register_divider_table(NULL, "pll4_post_div", "pll4_audio", CLK_SET_RATE_PARENT, base + 0x70, 19, 2, 0, post_div_table, &imx_ccm_lock);
clks[IMX6SL_CLK_PLL4_AUDIO_DIV] = clk_register_divider(NULL, "pll4_audio_div", "pll4_post_div", CLK_SET_RATE_PARENT, base + 0x170, 15, 1, 0, &imx_ccm_lock);
clks[IMX6SL_CLK_PLL5_POST_DIV] = clk_register_divider_table(NULL, "pll5_post_div", "pll5_video", CLK_SET_RATE_PARENT, base + 0xa0, 19, 2, 0, post_div_table, &imx_ccm_lock);
- clks[IMX6SL_CLK_PLL5_VIDEO_DIV] = clk_register_divider_table(NULL, "pll5_video_div", "pll5_post_div", CLK_SET_RATE_PARENT, base + 0x170, 30, 2, 0, video_div_table, &imx_ccm_lock);
+ clks[IMX6SL_CLK_PLL5_VIDEO_DIV] = clk_register_divider_table(NULL, "pll5_video_div", "pll5_post_div", CLK_SET_RATE_PARENT | CLK_SET_RATE_GATE, base + 0x170, 30, 2, 0, video_div_table, &imx_ccm_lock);
clks[IMX6SL_CLK_ENET_REF] = clk_register_divider_table(NULL, "enet_ref", "pll6_enet", 0, base + 0xe0, 0, 2, 0, clk_enet_ref_table, &imx_ccm_lock);
/* name parent_name reg idx */
@@ -290,6 +284,7 @@ static void __init imx6sl_clocks_init(struct device_node *ccm_node)
clks[IMX6SL_CLK_PLL3_120M] = imx_clk_fixed_factor("pll3_120m", "pll3_usb_otg", 1, 4);
clks[IMX6SL_CLK_PLL3_80M] = imx_clk_fixed_factor("pll3_80m", "pll3_usb_otg", 1, 6);
clks[IMX6SL_CLK_PLL3_60M] = imx_clk_fixed_factor("pll3_60m", "pll3_usb_otg", 1, 8);
+ clks[IMX6SL_CLK_UART_OSC_4M] = imx_clk_fixed_factor("uart_osc_4m", "osc", 1, 6);
np = ccm_node;
base = of_iomap(np, 0);
@@ -298,13 +293,13 @@ static void __init imx6sl_clocks_init(struct device_node *ccm_node)
/* name reg shift width parent_names num_parents */
clks[IMX6SL_CLK_STEP] = imx_clk_mux("step", base + 0xc, 8, 1, step_sels, ARRAY_SIZE(step_sels));
- clks[IMX6SL_CLK_PLL1_SW] = imx_clk_mux("pll1_sw", base + 0xc, 2, 1, pll1_sw_sels, ARRAY_SIZE(pll1_sw_sels));
+ clks[IMX6SL_CLK_PLL1_SW] = imx_clk_mux_glitchless("pll1_sw", base + 0xc, 2, 1, pll1_sw_sels, ARRAY_SIZE(pll1_sw_sels));
clks[IMX6SL_CLK_OCRAM_ALT_SEL] = imx_clk_mux("ocram_alt_sel", base + 0x14, 7, 1, ocram_alt_sels, ARRAY_SIZE(ocram_alt_sels));
clks[IMX6SL_CLK_OCRAM_SEL] = imx_clk_mux("ocram_sel", base + 0x14, 6, 1, ocram_sels, ARRAY_SIZE(ocram_sels));
- clks[IMX6SL_CLK_PRE_PERIPH2_SEL] = imx_clk_mux("pre_periph2_sel", base + 0x18, 21, 2, pre_periph_sels, ARRAY_SIZE(pre_periph_sels));
- clks[IMX6SL_CLK_PRE_PERIPH_SEL] = imx_clk_mux("pre_periph_sel", base + 0x18, 18, 2, pre_periph_sels, ARRAY_SIZE(pre_periph_sels));
- clks[IMX6SL_CLK_PERIPH2_CLK2_SEL] = imx_clk_mux("periph2_clk2_sel", base + 0x18, 20, 1, periph2_clk2_sels, ARRAY_SIZE(periph2_clk2_sels));
- clks[IMX6SL_CLK_PERIPH_CLK2_SEL] = imx_clk_mux("periph_clk2_sel", base + 0x18, 12, 2, periph_clk2_sels, ARRAY_SIZE(periph_clk2_sels));
+ clks[IMX6SL_CLK_PRE_PERIPH2_SEL] = imx_clk_mux_bus("pre_periph2_sel", base + 0x18, 21, 2, pre_periph_sels, ARRAY_SIZE(pre_periph_sels));
+ clks[IMX6SL_CLK_PRE_PERIPH_SEL] = imx_clk_mux_bus("pre_periph_sel", base + 0x18, 18, 2, pre_periph_sels, ARRAY_SIZE(pre_periph_sels));
+ clks[IMX6SL_CLK_PERIPH2_CLK2_SEL] = imx_clk_mux_bus("periph2_clk2_sel", base + 0x18, 20, 1, periph2_clk2_sels, ARRAY_SIZE(periph2_clk2_sels));
+ clks[IMX6SL_CLK_PERIPH_CLK2_SEL] = imx_clk_mux_bus("periph_clk2_sel", base + 0x18, 12, 2, periph_clk2_sels, ARRAY_SIZE(periph_clk2_sels));
clks[IMX6SL_CLK_CSI_SEL] = imx_clk_mux("csi_sel", base + 0x3c, 9, 2, csi_sels, ARRAY_SIZE(csi_sels));
clks[IMX6SL_CLK_LCDIF_AXI_SEL] = imx_clk_mux("lcdif_axi_sel", base + 0x3c, 14, 2, lcdif_axi_sels, ARRAY_SIZE(lcdif_axi_sels));
clks[IMX6SL_CLK_USDHC1_SEL] = imx_clk_fixup_mux("usdhc1_sel", base + 0x1c, 16, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels), imx_cscmr1_fixup);
@@ -319,8 +314,8 @@ static void __init imx6sl_clocks_init(struct device_node *ccm_node)
clks[IMX6SL_CLK_EPDC_AXI_SEL] = imx_clk_mux("epdc_axi_sel", base + 0x34, 15, 3, epdc_axi_sels, ARRAY_SIZE(epdc_axi_sels));
clks[IMX6SL_CLK_GPU2D_OVG_SEL] = imx_clk_mux("gpu2d_ovg_sel", base + 0x18, 4, 2, gpu2d_ovg_sels, ARRAY_SIZE(gpu2d_ovg_sels));
clks[IMX6SL_CLK_GPU2D_SEL] = imx_clk_mux("gpu2d_sel", base + 0x18, 8, 2, gpu2d_sels, ARRAY_SIZE(gpu2d_sels));
- clks[IMX6SL_CLK_LCDIF_PIX_SEL] = imx_clk_mux("lcdif_pix_sel", base + 0x38, 6, 3, lcdif_pix_sels, ARRAY_SIZE(lcdif_pix_sels));
- clks[IMX6SL_CLK_EPDC_PIX_SEL] = imx_clk_mux("epdc_pix_sel", base + 0x38, 15, 3, epdc_pix_sels, ARRAY_SIZE(epdc_pix_sels));
+ clks[IMX6SL_CLK_LCDIF_PIX_SEL] = imx_clk_mux_flags("lcdif_pix_sel", base + 0x38, 6, 3, lcdif_pix_sels, ARRAY_SIZE(lcdif_pix_sels), CLK_SET_RATE_PARENT);
+ clks[IMX6SL_CLK_EPDC_PIX_SEL] = imx_clk_mux_flags("epdc_pix_sel", base + 0x38, 15, 3, epdc_pix_sels, ARRAY_SIZE(epdc_pix_sels), CLK_SET_RATE_PARENT);
clks[IMX6SL_CLK_SPDIF0_SEL] = imx_clk_mux("spdif0_sel", base + 0x30, 20, 2, audio_sels, ARRAY_SIZE(audio_sels));
clks[IMX6SL_CLK_SPDIF1_SEL] = imx_clk_mux("spdif1_sel", base + 0x30, 7, 2, audio_sels, ARRAY_SIZE(audio_sels));
clks[IMX6SL_CLK_EXTERN_AUDIO_SEL] = imx_clk_mux("extern_audio_sel", base + 0x20, 19, 2, audio_sels, ARRAY_SIZE(audio_sels));
@@ -332,7 +327,7 @@ static void __init imx6sl_clocks_init(struct device_node *ccm_node)
clks[IMX6SL_CLK_PERIPH2] = imx_clk_busy_mux("periph2", base + 0x14, 26, 1, base + 0x48, 3, periph2_sels, ARRAY_SIZE(periph2_sels));
/* name parent_name reg shift width */
- clks[IMX6SL_CLK_OCRAM_PODF] = imx_clk_divider("ocram_podf", "ocram_sel", base + 0x14, 16, 3);
+ clks[IMX6SL_CLK_OCRAM_PODF] = imx_clk_busy_divider("ocram_podf", "ocram_sel", base + 0x14, 16, 3, base + 0x48, 0);
clks[IMX6SL_CLK_PERIPH_CLK2_PODF] = imx_clk_divider("periph_clk2_podf", "periph_clk2_sel", base + 0x14, 27, 3);
clks[IMX6SL_CLK_PERIPH2_CLK2_PODF] = imx_clk_divider("periph2_clk2_podf", "periph2_clk2_sel", base + 0x14, 0, 3);
clks[IMX6SL_CLK_IPG] = imx_clk_divider("ipg", "ahb", base + 0x14, 8, 2);
@@ -416,16 +411,17 @@ static void __init imx6sl_clocks_init(struct device_node *ccm_node)
clks[IMX6SL_CLK_USDHC3] = imx_clk_gate2("usdhc3", "usdhc3_podf", base + 0x80, 6);
clks[IMX6SL_CLK_USDHC4] = imx_clk_gate2("usdhc4", "usdhc4_podf", base + 0x80, 8);
- /* Ensure the MMDC CH0 handshake is bypassed */
- writel_relaxed(readl_relaxed(base + CCDR) |
- BM_CCM_CCDR_MMDC_CH0_MASK, base + CCDR);
-
imx_check_clocks(clks, ARRAY_SIZE(clks));
clk_data.clks = clks;
clk_data.clk_num = ARRAY_SIZE(clks);
of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
+ /* Ensure the CH0 handshake is bypassed */
+ reg = readl_relaxed(base + CCDR);
+ reg |= 1 << CCDR_CH0_HS_BYP;
+ writel_relaxed(reg, base + CCDR);
+
/* Ensure the AHB clk is at 132MHz. */
ret = clk_set_rate(clks[IMX6SL_CLK_AHB], 132000000);
if (ret)
@@ -447,6 +443,8 @@ static void __init imx6sl_clocks_init(struct device_node *ccm_node)
/* Audio-related clocks configuration */
clk_set_parent(clks[IMX6SL_CLK_SPDIF0_SEL], clks[IMX6SL_CLK_PLL3_PFD3]);
+ /* Initialize Video PLLs to valid frequency (650MHz). */
+ imx_clk_set_rate(clks[IMX6SL_CLK_PLL5_VIDEO_DIV], 650000000);
/* set PLL5 video as lcdif pix parent clock */
clk_set_parent(clks[IMX6SL_CLK_LCDIF_PIX_SEL],
clks[IMX6SL_CLK_PLL5_VIDEO_DIV]);
@@ -454,6 +452,18 @@ static void __init imx6sl_clocks_init(struct device_node *ccm_node)
clk_set_parent(clks[IMX6SL_CLK_LCDIF_AXI_SEL],
clks[IMX6SL_CLK_PLL2_PFD2]);
+ /* Configure EPDC clocks */
+ clk_set_parent(clks[IMX6SL_CLK_EPDC_PIX_SEL],
+ clks[IMX6SL_CLK_PLL5_VIDEO_DIV]);
+ clk_set_parent(clks[IMX6SL_CLK_EPDC_AXI_SEL],
+ clks[IMX6SL_CLK_PLL2_PFD2]);
+ clk_set_rate(clks[IMX6SL_CLK_EPDC_AXI], 200000000);
+
+ /* Set the UART parent if needed */
+ if (uart_from_osc)
+ imx_clk_set_parent(clks[IMX6SL_CLK_UART_SEL], clks[IMX6SL_CLK_UART_OSC_4M]);
+
imx_register_uart_clocks(uart_clks);
+
}
CLK_OF_DECLARE(imx6sl, "fsl,imx6sl-ccm", imx6sl_clocks_init);
diff --git a/drivers/clk/imx/clk-imx6sll.c b/drivers/clk/imx/clk-imx6sll.c
new file mode 100644
index 000000000000..ff6aaf4143ef
--- /dev/null
+++ b/drivers/clk/imx/clk-imx6sll.c
@@ -0,0 +1,380 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017 NXP.
+ *
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <dt-bindings/clock/imx6sll-clock.h>
+#include <linux/clk.h>
+#include <linux/clkdev.h>
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/types.h>
+
+#include "clk.h"
+
+#define BM_CCM_CCDR_MMDC_CH0_MASK (0x2 << 16)
+#define CCDR 0x4
+
+static const char *pll_bypass_src_sels[] = { "osc", "dummy", };
+static const char *pll1_bypass_sels[] = { "pll1", "pll1_bypass_src", };
+static const char *pll2_bypass_sels[] = { "pll2", "pll2_bypass_src", };
+static const char *pll3_bypass_sels[] = { "pll3", "pll3_bypass_src", };
+static const char *pll4_bypass_sels[] = { "pll4", "pll4_bypass_src", };
+static const char *pll5_bypass_sels[] = { "pll5", "pll5_bypass_src", };
+static const char *pll6_bypass_sels[] = { "pll6", "pll6_bypass_src", };
+static const char *pll7_bypass_sels[] = { "pll7", "pll7_bypass_src", };
+static const char *step_sels[] = { "osc", "pll2_pfd2_396m", };
+static const char *pll1_sw_sels[] = { "pll1_sys", "step", };
+static const char *axi_alt_sels[] = { "pll2_pfd2_396m", "pll3_pfd1_540m", };
+static const char *axi_sels[] = {"periph", "axi_alt_sel", };
+static const char *periph_pre_sels[] = { "pll2_bus", "pll2_pfd2_396m", "pll2_pfd0_352m", "pll2_198m", };
+static const char *periph2_pre_sels[] = { "pll2_bus", "pll2_pfd2_396m", "pll2_pfd0_352m", "pll4_audio_div", };
+static const char *periph_clk2_sels[] = { "pll3_usb_otg", "osc", "osc", };
+static const char *periph2_clk2_sels[] = { "pll3_usb_otg", "osc", };
+static const char *periph_sels[] = { "periph_pre", "periph_clk2", };
+static const char *periph2_sels[] = { "periph2_pre", "periph2_clk2", };
+static const char *usdhc_sels[] = { "pll2_pfd2_396m", "pll2_pfd0_352m", };
+static const char *ssi_sels[] = {"pll3_pfd2_508m", "pll3_pfd3_454m", "pll4_audio_div", "dummy",};
+static const char *spdif_sels[] = { "pll4_audio_div", "pll3_pfd2_508m", "pll5_video_div", "pll3_usb_otg", };
+static const char *ldb_di0_div_sels[] = { "ldb_di0_div_3_5", "ldb_di0_div_7", };
+static const char *ldb_di1_div_sels[] = { "ldb_di1_div_3_5", "ldb_di1_div_7", };
+static const char *ldb_di0_sels[] = { "pll5_video_div", "pll2_pfd0_352m", "pll2_pfd2_396m", "pll2_pfd3_594m", "pll2_pfd1_594m", "pll3_pfd3_454m", };
+static const char *ldb_di1_sels[] = { "pll3_usb_otg", "pll2_pfd0_352m", "pll2_pfd2_396m", "pll2_bus", "pll3_pfd3_454m", "pll3_pfd2_508m", };
+static const char *lcdif_pre_sels[] = { "pll2_bus", "pll3_pfd3_454m", "pll5_video_div", "pll2_pfd0_352m", "pll2_pfd1_594m", "pll3_pfd1_540m", };
+static const char *ecspi_sels[] = { "pll3_60m", "osc", };
+static const char *uart_sels[] = { "pll3_80m", "osc", };
+static const char *perclk_sels[] = { "ipg", "osc", };
+static const char *lcdif_sels[] = { "lcdif_podf", "ipp_di0", "ipp_di1", "ldb_di0", "ldb_di1", };
+
+static const char *epdc_pre_sels[] = { "pll2_bus", "pll3_usb_otg", "pll5_video_div", "pll2_pfd0_352m", "pll2_pfd2_396m", "pll3_pfd2_508m", };
+static const char *epdc_sels[] = { "epdc_podf", "ipp_di0", "ipp_di1", "ldb_di0", "ldb_di1", };
+
+static struct clk *clks[IMX6SLL_CLK_END];
+static struct clk_onecell_data clk_data;
+
+static int const clks_init_on[] __initconst = {
+ IMX6SLL_CLK_AIPSTZ1, IMX6SLL_CLK_AIPSTZ2,
+ IMX6SLL_CLK_OCRAM, IMX6SLL_CLK_ARM, IMX6SLL_CLK_ROM,
+ IMX6SLL_CLK_MMDC_P0_FAST, IMX6SLL_CLK_MMDC_P0_IPG,
+};
+
+static struct clk_div_table post_div_table[] = {
+ { .val = 2, .div = 1, },
+ { .val = 1, .div = 2, },
+ { .val = 0, .div = 4, },
+ { }
+};
+
+static struct clk_div_table video_div_table[] = {
+ { .val = 0, .div = 1, },
+ { .val = 1, .div = 2, },
+ { .val = 2, .div = 1, },
+ { .val = 3, .div = 4, },
+ { }
+};
+
+static u32 share_count_audio;
+static u32 share_count_ssi1;
+static u32 share_count_ssi2;
+static u32 share_count_ssi3;
+
+static void __init imx6sll_clocks_init(struct device_node *ccm_node)
+{
+ struct device_node *np;
+ void __iomem *base;
+ int i;
+
+ clks[IMX6SLL_CLK_DUMMY] = imx_clk_fixed("dummy", 0);
+
+ clks[IMX6SLL_CLK_CKIL] = of_clk_get_by_name(ccm_node, "ckil");
+ clks[IMX6SLL_CLK_OSC] = of_clk_get_by_name(ccm_node, "osc");
+
+ /* ipp_di clock is external input */
+ clks[IMX6SLL_CLK_IPP_DI0] = of_clk_get_by_name(ccm_node, "ipp_di0");
+ clks[IMX6SLL_CLK_IPP_DI1] = of_clk_get_by_name(ccm_node, "ipp_di1");
+
+ np = of_find_compatible_node(NULL, NULL, "fsl,imx6sll-anatop");
+ base = of_iomap(np, 0);
+ WARN_ON(!base);
+
+ clks[IMX6SLL_PLL1_BYPASS_SRC] = imx_clk_mux("pll1_bypass_src", base + 0x00, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
+ clks[IMX6SLL_PLL2_BYPASS_SRC] = imx_clk_mux("pll2_bypass_src", base + 0x30, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
+ clks[IMX6SLL_PLL3_BYPASS_SRC] = imx_clk_mux("pll3_bypass_src", base + 0x10, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
+ clks[IMX6SLL_PLL4_BYPASS_SRC] = imx_clk_mux("pll4_bypass_src", base + 0x70, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
+ clks[IMX6SLL_PLL5_BYPASS_SRC] = imx_clk_mux("pll5_bypass_src", base + 0xa0, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
+ clks[IMX6SLL_PLL6_BYPASS_SRC] = imx_clk_mux("pll6_bypass_src", base + 0xe0, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
+ clks[IMX6SLL_PLL7_BYPASS_SRC] = imx_clk_mux("pll7_bypass_src", base + 0x20, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
+
+ clks[IMX6SLL_CLK_PLL1] = imx_clk_pllv3(IMX_PLLV3_SYS, "pll1", "pll1_bypass_src", base + 0x00, 0x7f);
+ clks[IMX6SLL_CLK_PLL2] = imx_clk_pllv3(IMX_PLLV3_GENERIC, "pll2", "pll2_bypass_src", base + 0x30, 0x1);
+ clks[IMX6SLL_CLK_PLL3] = imx_clk_pllv3(IMX_PLLV3_USB, "pll3", "pll3_bypass_src", base + 0x10, 0x3);
+ clks[IMX6SLL_CLK_PLL4] = imx_clk_pllv3(IMX_PLLV3_AV, "pll4", "pll4_bypass_src", base + 0x70, 0x7f);
+ clks[IMX6SLL_CLK_PLL5] = imx_clk_pllv3(IMX_PLLV3_AV, "pll5", "pll5_bypass_src", base + 0xa0, 0x7f);
+ clks[IMX6SLL_CLK_PLL6] = imx_clk_pllv3(IMX_PLLV3_ENET, "pll6", "pll6_bypass_src", base + 0xe0, 0x3);
+ clks[IMX6SLL_CLK_PLL7] = imx_clk_pllv3(IMX_PLLV3_USB, "pll7", "pll7_bypass_src", base + 0x20, 0x3);
+
+ clks[IMX6SLL_PLL1_BYPASS] = imx_clk_mux_flags("pll1_bypass", base + 0x00, 16, 1, pll1_bypass_sels, ARRAY_SIZE(pll1_bypass_sels), CLK_SET_RATE_PARENT);
+ clks[IMX6SLL_PLL2_BYPASS] = imx_clk_mux_flags("pll2_bypass", base + 0x30, 16, 1, pll2_bypass_sels, ARRAY_SIZE(pll2_bypass_sels), CLK_SET_RATE_PARENT);
+ clks[IMX6SLL_PLL3_BYPASS] = imx_clk_mux_flags("pll3_bypass", base + 0x10, 16, 1, pll3_bypass_sels, ARRAY_SIZE(pll3_bypass_sels), CLK_SET_RATE_PARENT);
+ clks[IMX6SLL_PLL4_BYPASS] = imx_clk_mux_flags("pll4_bypass", base + 0x70, 16, 1, pll4_bypass_sels, ARRAY_SIZE(pll4_bypass_sels), CLK_SET_RATE_PARENT);
+ clks[IMX6SLL_PLL5_BYPASS] = imx_clk_mux_flags("pll5_bypass", base + 0xa0, 16, 1, pll5_bypass_sels, ARRAY_SIZE(pll5_bypass_sels), CLK_SET_RATE_PARENT);
+ clks[IMX6SLL_PLL6_BYPASS] = imx_clk_mux_flags("pll6_bypass", base + 0xe0, 16, 1, pll6_bypass_sels, ARRAY_SIZE(pll6_bypass_sels), CLK_SET_RATE_PARENT);
+ clks[IMX6SLL_PLL7_BYPASS] = imx_clk_mux_flags("pll7_bypass", base + 0x20, 16, 1, pll7_bypass_sels, ARRAY_SIZE(pll7_bypass_sels), CLK_SET_RATE_PARENT);
+
+ /* Do not bypass PLLs initially */
+ clk_set_parent(clks[IMX6SLL_PLL1_BYPASS], clks[IMX6SLL_CLK_PLL1]);
+ clk_set_parent(clks[IMX6SLL_PLL2_BYPASS], clks[IMX6SLL_CLK_PLL2]);
+ clk_set_parent(clks[IMX6SLL_PLL3_BYPASS], clks[IMX6SLL_CLK_PLL3]);
+ clk_set_parent(clks[IMX6SLL_PLL4_BYPASS], clks[IMX6SLL_CLK_PLL4]);
+ clk_set_parent(clks[IMX6SLL_PLL5_BYPASS], clks[IMX6SLL_CLK_PLL5]);
+ clk_set_parent(clks[IMX6SLL_PLL6_BYPASS], clks[IMX6SLL_CLK_PLL6]);
+ clk_set_parent(clks[IMX6SLL_PLL7_BYPASS], clks[IMX6SLL_CLK_PLL7]);
+
+ clks[IMX6SLL_CLK_PLL1_SYS] = imx_clk_fixed_factor("pll1_sys", "pll1_bypass", 1, 1);
+ clks[IMX6SLL_CLK_PLL2_BUS] = imx_clk_gate("pll2_bus", "pll2_bypass", base + 0x30, 13);
+ clks[IMX6SLL_CLK_PLL3_USB_OTG] = imx_clk_gate("pll3_usb_otg", "pll3_bypass", base + 0x10, 13);
+ clks[IMX6SLL_CLK_PLL4_AUDIO] = imx_clk_gate("pll4_audio", "pll4_bypass", base + 0x70, 13);
+ clks[IMX6SLL_CLK_PLL5_VIDEO] = imx_clk_gate("pll5_video", "pll5_bypass", base + 0xa0, 13);
+ clks[IMX6SLL_CLK_PLL6_ENET] = imx_clk_gate("pll6_enet", "pll6_bypass", base + 0xe0, 13);
+ clks[IMX6SLL_CLK_PLL7_USB_HOST] = imx_clk_gate("pll7_usb_host", "pll7_bypass", base + 0x20, 13);
+
+ /*
+ * Bit 20 is the reserved and read-only bit, we do this only for:
+ * - Do nothing for usbphy clk_enable/disable
+ * - Keep refcount when do usbphy clk_enable/disable, in that case,
+ * the clk framework many need to enable/disable usbphy's parent
+ */
+ clks[IMX6SLL_CLK_USBPHY1] = imx_clk_gate("usbphy1", "pll3_usb_otg", base + 0x10, 20);
+ clks[IMX6SLL_CLK_USBPHY2] = imx_clk_gate("usbphy2", "pll7_usb_host", base + 0x20, 20);
+
+ /*
+ * usbphy*_gate needs to be on after system boots up, and software
+ * never needs to control it anymore.
+ */
+ clks[IMX6SLL_CLK_USBPHY1_GATE] = imx_clk_gate("usbphy1_gate", "dummy", base + 0x10, 6);
+ clks[IMX6SLL_CLK_USBPHY2_GATE] = imx_clk_gate("usbphy2_gate", "dummy", base + 0x20, 6);
+
+ /* name parent_name reg idx */
+ clks[IMX6SLL_CLK_PLL2_PFD0] = imx_clk_pfd("pll2_pfd0_352m", "pll2_bus", base + 0x100, 0);
+ clks[IMX6SLL_CLK_PLL2_PFD1] = imx_clk_pfd("pll2_pfd1_594m", "pll2_bus", base + 0x100, 1);
+ clks[IMX6SLL_CLK_PLL2_PFD2] = imx_clk_pfd("pll2_pfd2_396m", "pll2_bus", base + 0x100, 2);
+ clks[IMX6SLL_CLK_PLL2_PFD3] = imx_clk_pfd("pll2_pfd3_594m", "pll2_bus", base + 0x100, 3);
+ clks[IMX6SLL_CLK_PLL3_PFD0] = imx_clk_pfd("pll3_pfd0_720m", "pll3_usb_otg", base + 0xf0, 0);
+ clks[IMX6SLL_CLK_PLL3_PFD1] = imx_clk_pfd("pll3_pfd1_540m", "pll3_usb_otg", base + 0xf0, 1);
+ clks[IMX6SLL_CLK_PLL3_PFD2] = imx_clk_pfd("pll3_pfd2_508m", "pll3_usb_otg", base + 0xf0, 2);
+ clks[IMX6SLL_CLK_PLL3_PFD3] = imx_clk_pfd("pll3_pfd3_454m", "pll3_usb_otg", base + 0xf0, 3);
+
+ clks[IMX6SLL_CLK_PLL4_POST_DIV] = clk_register_divider_table(NULL, "pll4_post_div", "pll4_audio",
+ CLK_SET_RATE_PARENT | CLK_SET_RATE_GATE, base + 0x70, 19, 2, 0, post_div_table, &imx_ccm_lock);
+ clks[IMX6SLL_CLK_PLL4_AUDIO_DIV] = clk_register_divider(NULL, "pll4_audio_div", "pll4_post_div",
+ CLK_SET_RATE_PARENT | CLK_SET_RATE_GATE, base + 0x170, 15, 1, 0, &imx_ccm_lock);
+ clks[IMX6SLL_CLK_PLL5_POST_DIV] = clk_register_divider_table(NULL, "pll5_post_div", "pll5_video",
+ CLK_SET_RATE_PARENT | CLK_SET_RATE_GATE, base + 0xa0, 19, 2, 0, post_div_table, &imx_ccm_lock);
+ clks[IMX6SLL_CLK_PLL5_VIDEO_DIV] = clk_register_divider_table(NULL, "pll5_video_div", "pll5_post_div",
+ CLK_SET_RATE_PARENT | CLK_SET_RATE_GATE, base + 0x170, 30, 2, 0, video_div_table, &imx_ccm_lock);
+
+ /* name parent_name mult div */
+ clks[IMX6SLL_CLK_PLL2_198M] = imx_clk_fixed_factor("pll2_198m", "pll2_pfd2_396m", 1, 2);
+ clks[IMX6SLL_CLK_PLL3_120M] = imx_clk_fixed_factor("pll3_120m", "pll3_usb_otg", 1, 4);
+ clks[IMX6SLL_CLK_PLL3_80M] = imx_clk_fixed_factor("pll3_80m", "pll3_usb_otg", 1, 6);
+ clks[IMX6SLL_CLK_PLL3_60M] = imx_clk_fixed_factor("pll3_60m", "pll3_usb_otg", 1, 8);
+ clks[IMX6SLL_CLK_GPT_3M] = imx_clk_fixed_factor("gpt_3m", "osc", 1, 8);
+
+ np = ccm_node;
+ base = of_iomap(np, 0);
+ WARN_ON(!base);
+
+ clks[IMX6SLL_CLK_STEP] = imx_clk_mux("step", base + 0x0c, 8, 1, step_sels, ARRAY_SIZE(step_sels));
+ clks[IMX6SLL_CLK_PLL1_SW] = imx_clk_mux_glitchless("pll1_sw", base + 0x0c, 2, 1, pll1_sw_sels, ARRAY_SIZE(pll1_sw_sels));
+ clks[IMX6SLL_CLK_AXI_ALT_SEL] = imx_clk_mux("axi_alt_sel", base + 0x14, 7, 1, axi_alt_sels, ARRAY_SIZE(axi_alt_sels));
+ clks[IMX6SLL_CLK_AXI_SEL] = imx_clk_mux_flags("axi_sel", base + 0x14, 6, 1, axi_sels, ARRAY_SIZE(axi_sels), 0);
+ clks[IMX6SLL_CLK_PERIPH_PRE] = imx_clk_mux_bus("periph_pre", base + 0x18, 18, 2, periph_pre_sels, ARRAY_SIZE(periph_pre_sels));
+ clks[IMX6SLL_CLK_PERIPH2_PRE] = imx_clk_mux_bus("periph2_pre", base + 0x18, 21, 2, periph2_pre_sels, ARRAY_SIZE(periph2_pre_sels));
+ clks[IMX6SLL_CLK_PERIPH_CLK2_SEL] = imx_clk_mux_bus("periph_clk2_sel", base + 0x18, 12, 2, periph_clk2_sels, ARRAY_SIZE(periph_clk2_sels));
+ clks[IMX6SLL_CLK_PERIPH2_CLK2_SEL] = imx_clk_mux_bus("periph2_clk2_sel", base + 0x18, 20, 1, periph2_clk2_sels, ARRAY_SIZE(periph2_clk2_sels));
+ clks[IMX6SLL_CLK_USDHC2_SEL] = imx_clk_mux("usdhc2_sel", base + 0x1c, 17, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels));
+ clks[IMX6SLL_CLK_USDHC1_SEL] = imx_clk_mux("usdhc1_sel", base + 0x1c, 16, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels));
+ clks[IMX6SLL_CLK_USDHC3_SEL] = imx_clk_mux("usdhc3_sel", base + 0x1c, 18, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels));
+ clks[IMX6SLL_CLK_SSI1_SEL] = imx_clk_mux("ssi1_sel", base + 0x1c, 10, 2, ssi_sels, ARRAY_SIZE(ssi_sels));
+ clks[IMX6SLL_CLK_SSI2_SEL] = imx_clk_mux("ssi2_sel", base + 0x1c, 12, 2, ssi_sels, ARRAY_SIZE(ssi_sels));
+ clks[IMX6SLL_CLK_SSI3_SEL] = imx_clk_mux("ssi3_sel", base + 0x1c, 14, 2, ssi_sels, ARRAY_SIZE(ssi_sels));
+ clks[IMX6SLL_CLK_PERCLK_SEL] = imx_clk_mux("perclk_sel", base + 0x1c, 6, 1, perclk_sels, ARRAY_SIZE(perclk_sels));
+ clks[IMX6SLL_CLK_UART_SEL] = imx_clk_mux("uart_sel", base + 0x24, 6, 1, uart_sels, ARRAY_SIZE(uart_sels));
+ clks[IMX6SLL_CLK_SPDIF_SEL] = imx_clk_mux("spdif_sel", base + 0x30, 20, 2, spdif_sels, ARRAY_SIZE(spdif_sels));
+ clks[IMX6SLL_CLK_EXTERN_AUDIO_SEL] = imx_clk_mux("extern_audio_sel", base + 0x30, 7, 2, spdif_sels, ARRAY_SIZE(spdif_sels));
+ clks[IMX6SLL_CLK_EPDC_PRE_SEL] = imx_clk_mux("epdc_pre_sel", base + 0x34, 15, 3, epdc_pre_sels, ARRAY_SIZE(epdc_pre_sels));
+ clks[IMX6SLL_CLK_EPDC_SEL] = imx_clk_mux("epdc_sel", base + 0x34, 9, 3, epdc_sels, ARRAY_SIZE(epdc_sels));
+ clks[IMX6SLL_CLK_ECSPI_SEL] = imx_clk_mux("ecspi_sel", base + 0x38, 18, 1, ecspi_sels, ARRAY_SIZE(ecspi_sels));
+ clks[IMX6SLL_CLK_LCDIF_PRE_SEL] = imx_clk_mux("lcdif_pre_sel", base + 0x38, 15, 3, lcdif_pre_sels, ARRAY_SIZE(lcdif_pre_sels));
+ clks[IMX6SLL_CLK_LCDIF_SEL] = imx_clk_mux("lcdif_sel", base + 0x38, 9, 3, lcdif_sels, ARRAY_SIZE(lcdif_sels));
+
+ clks[IMX6SLL_CLK_PERIPH] = imx_clk_busy_mux("periph", base + 0x14, 25, 1, base + 0x48, 5, periph_sels, ARRAY_SIZE(periph_sels));
+ clks[IMX6SLL_CLK_PERIPH2] = imx_clk_busy_mux("periph2", base + 0x14, 26, 1, base + 0x48, 3, periph2_sels, ARRAY_SIZE(periph2_sels));
+
+ clks[IMX6SLL_CLK_PERIPH_CLK2] = imx_clk_divider("periph_clk2", "periph_clk2_sel", base + 0x14, 27, 3);
+ clks[IMX6SLL_CLK_PERIPH2_CLK2] = imx_clk_divider("periph2_clk2", "periph2_clk2_sel", base + 0x14, 0, 3);
+ clks[IMX6SLL_CLK_IPG] = imx_clk_divider("ipg", "ahb", base + 0x14, 8, 2);
+ clks[IMX6SLL_CLK_LCDIF_PODF] = imx_clk_divider("lcdif_podf", "lcdif_pred", base + 0x18, 23, 3);
+ clks[IMX6SLL_CLK_PERCLK] = imx_clk_divider("perclk", "perclk_sel", base + 0x1c, 0, 6);
+ clks[IMX6SLL_CLK_USDHC3_PODF] = imx_clk_divider("usdhc3_podf", "usdhc3_sel", base + 0x24, 19, 3);
+ clks[IMX6SLL_CLK_USDHC2_PODF] = imx_clk_divider("usdhc2_podf", "usdhc2_sel", base + 0x24, 16, 3);
+ clks[IMX6SLL_CLK_USDHC1_PODF] = imx_clk_divider("usdhc1_podf", "usdhc1_sel", base + 0x24, 11, 3);
+ clks[IMX6SLL_CLK_UART_PODF] = imx_clk_divider("uart_podf", "uart_sel", base + 0x24, 0, 6);
+ clks[IMX6SLL_CLK_SSI3_PRED] = imx_clk_divider("ssi3_pred", "ssi3_sel", base + 0x28, 22, 3);
+ clks[IMX6SLL_CLK_SSI3_PODF] = imx_clk_divider("ssi3_podf", "ssi3_pred", base + 0x28, 16, 6);
+ clks[IMX6SLL_CLK_SSI1_PRED] = imx_clk_divider("ssi1_pred", "ssi1_sel", base + 0x28, 6, 3);
+ clks[IMX6SLL_CLK_SSI1_PODF] = imx_clk_divider("ssi1_podf", "ssi1_pred", base + 0x28, 0, 6);
+ clks[IMX6SLL_CLK_SSI2_PRED] = imx_clk_divider("ssi2_pred", "ssi2_sel", base + 0x2c, 6, 3);
+ clks[IMX6SLL_CLK_SSI2_PODF] = imx_clk_divider("ssi2_podf", "ssi2_pred", base + 0x2c, 0, 6);
+ clks[IMX6SLL_CLK_SPDIF_PRED] = imx_clk_divider("spdif_pred", "spdif_sel", base + 0x30, 25, 3);
+ clks[IMX6SLL_CLK_SPDIF_PODF] = imx_clk_divider("spdif_podf", "spdif_pred", base + 0x30, 22, 3);
+ clks[IMX6SLL_CLK_EXTERN_AUDIO_PRED] = imx_clk_divider("extern_audio_pred", "extern_audio_sel", base + 0x30, 12, 3);
+ clks[IMX6SLL_CLK_EXTERN_AUDIO_PODF] = imx_clk_divider("extern_audio_podf", "extern_audio_pred", base + 0x30, 9, 3);
+ clks[IMX6SLL_CLK_EPDC_PODF] = imx_clk_divider("epdc_podf", "epdc_pre_sel", base + 0x34, 12, 3);
+ clks[IMX6SLL_CLK_ECSPI_PODF] = imx_clk_divider("ecspi_podf", "ecspi_sel", base + 0x38, 19, 6);
+ clks[IMX6SLL_CLK_LCDIF_PRED] = imx_clk_divider("lcdif_pred", "lcdif_pre_sel", base + 0x38, 12, 3);
+
+ clks[IMX6SLL_CLK_ARM] = imx_clk_busy_divider("arm", "pll1_sw", base + 0x10, 0, 3, base + 0x48, 16);
+ clks[IMX6SLL_CLK_MMDC_PODF] = imx_clk_busy_divider("mmdc_podf", "periph2", base + 0x14, 3, 3, base + 0x48, 2);
+ clks[IMX6SLL_CLK_AXI_PODF] = imx_clk_busy_divider("axi", "axi_sel", base + 0x14, 16, 3, base + 0x48, 0);
+ clks[IMX6SLL_CLK_AHB] = imx_clk_busy_divider("ahb", "periph", base + 0x14, 10, 3, base + 0x48, 1);
+
+ clks[IMX6SLL_CLK_LDB_DI0_DIV_3_5] = imx_clk_fixed_factor("ldb_di0_div_3_5", "ldb_di0_sel", 2, 7);
+ clks[IMX6SLL_CLK_LDB_DI0_DIV_7] = imx_clk_fixed_factor("ldb_di0_div_7", "ldb_di0_sel", 1, 7);
+ clks[IMX6SLL_CLK_LDB_DI1_DIV_3_5] = imx_clk_fixed_factor("ldb_di1_div_3_5", "ldb_di1_sel", 2, 7);
+ clks[IMX6SLL_CLK_LDB_DI1_DIV_7] = imx_clk_fixed_factor("ldb_di1_div_7", "ldb_di1_sel", 1, 7);
+
+ clks[IMX6SLL_CLK_LDB_DI0_SEL] = imx_clk_mux("ldb_di0_sel", base + 0x2c, 9, 3, ldb_di0_sels, ARRAY_SIZE(ldb_di0_sels));
+ clks[IMX6SLL_CLK_LDB_DI1_SEL] = imx_clk_mux("ldb_di1_sel", base + 0x1c, 7, 3, ldb_di1_sels, ARRAY_SIZE(ldb_di1_sels));
+ clks[IMX6SLL_CLK_LDB_DI0_DIV_SEL] = imx_clk_mux("ldb_di0_div_sel", base + 0x20, 10, 1, ldb_di0_div_sels, ARRAY_SIZE(ldb_di0_div_sels));
+ clks[IMX6SLL_CLK_LDB_DI1_DIV_SEL] = imx_clk_mux("ldb_di1_div_sel", base + 0x20, 10, 1, ldb_di1_div_sels, ARRAY_SIZE(ldb_di1_div_sels));
+
+ /* CCGR0 */
+ clks[IMX6SLL_CLK_AIPSTZ1] = imx_clk_gate2("aips_tz1", "ahb", base + 0x68, 0);
+ clks[IMX6SLL_CLK_AIPSTZ2] = imx_clk_gate2("aips_tz2", "ahb", base + 0x68, 2);
+ clks[IMX6SLL_CLK_DCP] = imx_clk_gate2("dcp", "ahb", base + 0x68, 10);
+ clks[IMX6SLL_CLK_UART2_IPG] = imx_clk_gate2("uart2_ipg", "ipg", base + 0x68, 28);
+ clks[IMX6SLL_CLK_UART2_SERIAL] = imx_clk_gate2("uart2_serial", "uart_podf", base + 0x68, 28);
+
+ /* CCGR1 */
+ clks[IMX6SLL_CLK_ECSPI1] = imx_clk_gate2("ecspi1", "ecspi_podf", base + 0x6c, 0);
+ clks[IMX6SLL_CLK_ECSPI2] = imx_clk_gate2("ecspi2", "ecspi_podf", base + 0x6c, 2);
+ clks[IMX6SLL_CLK_ECSPI3] = imx_clk_gate2("ecspi3", "ecspi_podf", base + 0x6c, 4);
+ clks[IMX6SLL_CLK_ECSPI4] = imx_clk_gate2("ecspi4", "ecspi_podf", base + 0x6c, 6);
+ clks[IMX6SLL_CLK_UART3_IPG] = imx_clk_gate2("uart3_ipg", "ipg", base + 0x6c, 10);
+ clks[IMX6SLL_CLK_UART3_SERIAL] = imx_clk_gate2("uart3_serial", "uart_podf", base + 0x6c, 10);
+ clks[IMX6SLL_CLK_EPIT1] = imx_clk_gate2("epit1", "perclk", base + 0x6c, 12);
+ clks[IMX6SLL_CLK_EPIT2] = imx_clk_gate2("epit2", "perclk", base + 0x6c, 14);
+ clks[IMX6SLL_CLK_GPT_BUS] = imx_clk_gate2("gpt1_bus", "perclk", base + 0x6c, 20);
+ clks[IMX6SLL_CLK_GPT_SERIAL] = imx_clk_gate2("gpt1_serial", "perclk", base + 0x6c, 22);
+ clks[IMX6SLL_CLK_UART4_IPG] = imx_clk_gate2("uart4_ipg", "ipg", base + 0x6c, 24);
+ clks[IMX6SLL_CLK_UART4_SERIAL] = imx_clk_gate2("uart4_serail", "uart_podf", base + 0x6c, 24);
+
+ /* CCGR2 */
+ clks[IMX6SLL_CLK_CSI] = imx_clk_gate2("csi", "axi", base + 0x70, 2);
+ clks[IMX6SLL_CLK_I2C1] = imx_clk_gate2("i2c1", "perclk", base + 0x70, 6);
+ clks[IMX6SLL_CLK_I2C2] = imx_clk_gate2("i2c2", "perclk", base + 0x70, 8);
+ clks[IMX6SLL_CLK_I2C3] = imx_clk_gate2("i2c3", "perclk", base + 0x70, 10);
+ clks[IMX6SLL_CLK_OCOTP] = imx_clk_gate2("ocotp", "ipg", base + 0x70, 12);
+ clks[IMX6SLL_CLK_LCDIF_APB] = imx_clk_gate2("lcdif_apb", "axi", base + 0x70, 28);
+ clks[IMX6SLL_CLK_PXP] = imx_clk_gate2("pxp", "axi", base + 0x70, 30);
+
+ /* CCGR3 */
+ clks[IMX6SLL_CLK_UART5_IPG] = imx_clk_gate2("uart5_ipg", "ipg", base + 0x74, 2);
+ clks[IMX6SLL_CLK_UART5_SERIAL] = imx_clk_gate2("uart5_serial", "uart_podf", base + 0x74, 2);
+ clks[IMX6SLL_CLK_EPDC_AXI] = imx_clk_gate2("epdc_aclk", "axi", base + 0x74, 4);
+ clks[IMX6SLL_CLK_EPDC_PIX] = imx_clk_gate2("epdc_pix", "epdc_podf", base + 0x74, 4);
+ clks[IMX6SLL_CLK_LCDIF_PIX] = imx_clk_gate2("lcdif_pix", "lcdif_podf", base + 0x74, 10);
+ clks[IMX6SLL_CLK_WDOG1] = imx_clk_gate2("wdog1", "ipg", base + 0x74, 16);
+ clks[IMX6SLL_CLK_MMDC_P0_FAST] = imx_clk_gate("mmdc_p0_fast", "mmdc_podf", base + 0x74, 20);
+ clks[IMX6SLL_CLK_MMDC_P0_IPG] = imx_clk_gate2("mmdc_p0_ipg", "ipg", base + 0x74, 24);
+ clks[IMX6SLL_CLK_OCRAM] = imx_clk_gate("ocram", "ahb", base + 0x74, 28);
+
+ /* CCGR4 */
+ clks[IMX6SLL_CLK_PWM1] = imx_clk_gate2("pwm1", "perclk", base + 0x78, 16);
+ clks[IMX6SLL_CLK_PWM2] = imx_clk_gate2("pwm2", "perclk", base + 0x78, 18);
+ clks[IMX6SLL_CLK_PWM3] = imx_clk_gate2("pwm3", "perclk", base + 0x78, 20);
+ clks[IMX6SLL_CLK_PWM4] = imx_clk_gate2("pwm4", "perclk", base + 0x78, 22);
+
+ /* CCGR5 */
+ clks[IMX6SLL_CLK_ROM] = imx_clk_gate2("rom", "ahb", base + 0x7c, 0);
+ clks[IMX6SLL_CLK_SDMA] = imx_clk_gate2("sdma", "ahb", base + 0x7c, 6);
+ clks[IMX6SLL_CLK_WDOG2] = imx_clk_gate2("wdog2", "ipg", base + 0x7c, 10);
+ clks[IMX6SLL_CLK_SPBA] = imx_clk_gate2("spba", "ipg", base + 0x7c, 12);
+ clks[IMX6SLL_CLK_EXTERN_AUDIO] = imx_clk_gate2_shared("extern_audio", "extern_audio_podf", base + 0x7c, 14, &share_count_audio);
+ clks[IMX6SLL_CLK_SPDIF] = imx_clk_gate2_shared("spdif", "spdif_podf", base + 0x7c, 14, &share_count_audio);
+ clks[IMX6SLL_CLK_SPDIF_GCLK] = imx_clk_gate2_shared("spdif_gclk", "ipg", base + 0x7c, 14, &share_count_audio);
+ clks[IMX6SLL_CLK_SSI1] = imx_clk_gate2_shared("ssi1", "ssi1_podf", base + 0x7c, 18, &share_count_ssi1);
+ clks[IMX6SLL_CLK_SSI1_IPG] = imx_clk_gate2_shared("ssi1_ipg", "ipg", base + 0x7c, 18, &share_count_ssi1);
+ clks[IMX6SLL_CLK_SSI2] = imx_clk_gate2_shared("ssi2", "ssi2_podf", base + 0x7c, 20, &share_count_ssi2);
+ clks[IMX6SLL_CLK_SSI2_IPG] = imx_clk_gate2_shared("ssi2_ipg", "ipg", base + 0x7c, 20, &share_count_ssi2);
+ clks[IMX6SLL_CLK_SSI3] = imx_clk_gate2_shared("ssi3", "ssi3_podf", base + 0x7c, 22, &share_count_ssi3);
+ clks[IMX6SLL_CLK_SSI3_IPG] = imx_clk_gate2_shared("ssi3_ipg", "ipg", base + 0x7c, 22, &share_count_ssi3);
+ clks[IMX6SLL_CLK_UART1_IPG] = imx_clk_gate2("uart1_ipg", "ipg", base + 0x7c, 24);
+ clks[IMX6SLL_CLK_UART1_SERIAL] = imx_clk_gate2("uart1_serial", "uart_podf", base + 0x7c, 24);
+
+ /* CCGR6 */
+ clks[IMX6SLL_CLK_USBOH3] = imx_clk_gate2("usboh3", "ipg", base + 0x80, 0);
+ clks[IMX6SLL_CLK_USDHC1] = imx_clk_gate2("usdhc1", "usdhc1_podf", base + 0x80, 2);
+ clks[IMX6SLL_CLK_USDHC2] = imx_clk_gate2("usdhc2", "usdhc2_podf", base + 0x80, 4);
+ clks[IMX6SLL_CLK_USDHC3] = imx_clk_gate2("usdhc3", "usdhc3_podf", base + 0x80, 6);
+
+ /* mask handshake of mmdc */
+ writel_relaxed(BM_CCM_CCDR_MMDC_CH0_MASK, base + CCDR);
+
+ for (i = 0; i < ARRAY_SIZE(clks); i++)
+ if (IS_ERR(clks[i]))
+ pr_err("i.MX6SLL clk %d: register failed with %ld\n", i, PTR_ERR(clks[i]));
+
+ clk_data.clks = clks;
+ clk_data.clk_num = ARRAY_SIZE(clks);
+ of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
+
+ /* set perclk to from OSC */
+ clk_set_parent(clks[IMX6SLL_CLK_PERCLK_SEL], clks[IMX6SLL_CLK_OSC]);
+
+ /* Set the UART parent if needed */
+ if (uart_from_osc)
+ imx_clk_set_parent(clks[IMX6SLL_CLK_UART_SEL], clks[IMX6SLL_CLK_OSC]);
+ else
+ imx_clk_set_parent(clks[IMX6SLL_CLK_UART_SEL], clks[IMX6SLL_CLK_PLL3_80M]);
+
+ for (i = 0; i < ARRAY_SIZE(clks_init_on); i++)
+ clk_prepare_enable(clks[clks_init_on[i]]);
+
+ if (IS_ENABLED(CONFIG_USB_MXS_PHY)) {
+ clk_prepare_enable(clks[IMX6SLL_CLK_USBPHY1_GATE]);
+ clk_prepare_enable(clks[IMX6SLL_CLK_USBPHY2_GATE]);
+ }
+
+ /* Lower the AHB clock rate before changing the clock source. */
+ imx_clk_set_rate(clks[IMX6SLL_CLK_AHB], 99000000);
+
+ /* Change periph_pre clock to pll2_bus to adjust AXI rate to 264MHz */
+ imx_clk_set_parent(clks[IMX6SLL_CLK_PERIPH_CLK2_SEL], clks[IMX6SLL_CLK_PLL3_USB_OTG]);
+ imx_clk_set_parent(clks[IMX6SLL_CLK_PERIPH], clks[IMX6SLL_CLK_PERIPH_CLK2]);
+ imx_clk_set_parent(clks[IMX6SLL_CLK_PERIPH_PRE], clks[IMX6SLL_CLK_PLL2_BUS]);
+ imx_clk_set_parent(clks[IMX6SLL_CLK_PERIPH], clks[IMX6SLL_CLK_PERIPH_PRE]);
+
+ imx_clk_set_rate(clks[IMX6SLL_CLK_AHB], 132000000);
+
+ /* Configure EPDC clocks */
+ imx_clk_set_rate(clks[IMX6SLL_CLK_PLL3_PFD2], 320000000);
+ clk_set_parent(clks[IMX6SLL_CLK_EPDC_PRE_SEL],
+ clks[IMX6SLL_CLK_PLL3_PFD2]);
+
+}
+
+CLK_OF_DECLARE(imx6sll, "fsl,imx6sll-ccm", imx6sll_clocks_init);
+
diff --git a/drivers/clk/imx/clk-imx6sx.c b/drivers/clk/imx/clk-imx6sx.c
index e6d389e333d7..a8efbde257d8 100644
--- a/drivers/clk/imx/clk-imx6sx.c
+++ b/drivers/clk/imx/clk-imx6sx.c
@@ -1,5 +1,6 @@
/*
- * Copyright (C) 2014 Freescale Semiconductor, Inc.
+ * Copyright (C) 2014-2016 Freescale Semiconductor, Inc.
+ * Copyright 2017 NXP
*
* The code contained herein is licensed under the GNU General Public
* License. You may obtain a copy of the GNU General Public License
@@ -13,15 +14,19 @@
#include <linux/clk.h>
#include <linux/clkdev.h>
#include <linux/err.h>
+#include <linux/imx_sema4.h>
#include <linux/init.h>
#include <linux/io.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_irq.h>
#include <linux/types.h>
+#include <soc/imx/gpc.h>
+#include <soc/imx/src.h>
#include "clk.h"
+#define CCM_CCGR_OFFSET(index) (index * 2)
#define CCDR 0x4
#define BM_CCM_CCDR_MMDC_CH0_MASK (0x2 << 16)
@@ -80,7 +85,7 @@ static const char *lvds_sels[] = {
"arm", "pll1_sys", "dummy", "dummy", "dummy", "dummy", "dummy", "pll5_video_div",
"dummy", "dummy", "pcie_ref_125m", "dummy", "usbphy1", "usbphy2",
};
-static const char *pll_bypass_src_sels[] = { "osc", "lvds1_in", };
+static const char *pll_bypass_src_sels[] = { "osc", "lvds1_in", "lvds2_in", "dummy", };
static const char *pll1_bypass_sels[] = { "pll1", "pll1_bypass_src", };
static const char *pll2_bypass_sels[] = { "pll2", "pll2_bypass_src", };
static const char *pll3_bypass_sels[] = { "pll3", "pll3_bypass_src", };
@@ -91,18 +96,19 @@ static const char *pll7_bypass_sels[] = { "pll7", "pll7_bypass_src", };
static struct clk *clks[IMX6SX_CLK_CLK_END];
static struct clk_onecell_data clk_data;
+struct imx_sema4_mutex *amp_power_mutex;
+
+static int clks_shared[MAX_SHARED_CLK_NUMBER];
+
+struct imx_shared_mem *shared_mem;
+static unsigned int shared_mem_paddr, shared_mem_size;
static int const clks_init_on[] __initconst = {
IMX6SX_CLK_AIPS_TZ1, IMX6SX_CLK_AIPS_TZ2, IMX6SX_CLK_AIPS_TZ3,
IMX6SX_CLK_IPMUX1, IMX6SX_CLK_IPMUX2, IMX6SX_CLK_IPMUX3,
IMX6SX_CLK_WAKEUP, IMX6SX_CLK_MMDC_P0_FAST, IMX6SX_CLK_MMDC_P0_IPG,
IMX6SX_CLK_ROM, IMX6SX_CLK_ARM, IMX6SX_CLK_IPG, IMX6SX_CLK_OCRAM,
- IMX6SX_CLK_PER2_MAIN, IMX6SX_CLK_PERCLK, IMX6SX_CLK_M4,
- IMX6SX_CLK_QSPI1, IMX6SX_CLK_QSPI2, IMX6SX_CLK_UART_IPG,
- IMX6SX_CLK_UART_SERIAL, IMX6SX_CLK_I2C3, IMX6SX_CLK_ECSPI5,
- IMX6SX_CLK_CAN1_IPG, IMX6SX_CLK_CAN1_SERIAL, IMX6SX_CLK_CAN2_IPG,
- IMX6SX_CLK_CAN2_SERIAL, IMX6SX_CLK_CANFD, IMX6SX_CLK_EPIT1,
- IMX6SX_CLK_EPIT2,
+ IMX6SX_CLK_PER2_MAIN, IMX6SX_CLK_PERCLK, IMX6SX_CLK_TZASC1,
};
static const struct clk_div_table clk_enet_ref_table[] = {
@@ -143,6 +149,38 @@ static struct clk ** const uart_clks[] __initconst = {
NULL
};
+/*
+ * As IMX6SX_CLK_M4_PRE_SEL is NOT a glitchless MUX, so when
+ * M4 is trying to change its clk parent, need to ask A9 to
+ * help do it, and M4 must be hold in wfi. To avoid glitch
+ * occur, need to gate M4 clk first before switching its parent.
+ */
+void imx6sx_set_m4_highfreq(bool high_freq)
+{
+ static struct clk *m4_high_freq_sel;
+
+ imx_gpc_hold_m4_in_sleep();
+
+ clk_disable_unprepare(clks[IMX6SX_CLK_M4]);
+ imx_clk_set_parent(clks[IMX6SX_CLK_M4_SEL],
+ clks[IMX6SX_CLK_LDB_DI0]);
+
+ if (high_freq) {
+ imx_clk_set_parent(clks[IMX6SX_CLK_M4_PRE_SEL],
+ m4_high_freq_sel);
+ } else {
+ m4_high_freq_sel = clk_get_parent(clks[IMX6SX_CLK_M4_PRE_SEL]);
+ imx_clk_set_parent(clks[IMX6SX_CLK_M4_PRE_SEL],
+ clks[IMX6SX_CLK_OSC]);
+ }
+
+ imx_clk_set_parent(clks[IMX6SX_CLK_M4_SEL],
+ clks[IMX6SX_CLK_M4_PRE_SEL]);
+ clk_prepare_enable(clks[IMX6SX_CLK_M4]);
+
+ imx_gpc_release_m4_in_sleep();
+}
+
static void __init imx6sx_clocks_init(struct device_node *ccm_node)
{
struct device_node *np;
@@ -160,6 +198,7 @@ static void __init imx6sx_clocks_init(struct device_node *ccm_node)
/* Clock source from external clock via CLK1 PAD */
clks[IMX6SX_CLK_ANACLK1] = imx_obtain_fixed_clock("anaclk1", 0);
+ clks[IMX6SX_CLK_ANACLK2] = imx_obtain_fixed_clock("anaclk2", 0);
np = of_find_compatible_node(NULL, NULL, "fsl,imx6sx-anatop");
base = of_iomap(np, 0);
@@ -175,7 +214,7 @@ static void __init imx6sx_clocks_init(struct device_node *ccm_node)
/* type name parent_name base div_mask */
clks[IMX6SX_CLK_PLL1] = imx_clk_pllv3(IMX_PLLV3_SYS, "pll1", "osc", base + 0x00, 0x7f);
- clks[IMX6SX_CLK_PLL2] = imx_clk_pllv3(IMX_PLLV3_GENERIC, "pll2", "osc", base + 0x30, 0x1);
+ clks[IMX6SX_CLK_PLL2] = imx_clk_pllv3(IMX_PLLV3_PLL2, "pll2", "osc", base + 0x30, 0x1);
clks[IMX6SX_CLK_PLL3] = imx_clk_pllv3(IMX_PLLV3_USB, "pll3", "osc", base + 0x10, 0x3);
clks[IMX6SX_CLK_PLL4] = imx_clk_pllv3(IMX_PLLV3_AV, "pll4", "osc", base + 0x70, 0x7f);
clks[IMX6SX_CLK_PLL5] = imx_clk_pllv3(IMX_PLLV3_AV, "pll5", "osc", base + 0xa0, 0x7f);
@@ -191,15 +230,15 @@ static void __init imx6sx_clocks_init(struct device_node *ccm_node)
clks[IMX6SX_PLL7_BYPASS] = imx_clk_mux_flags("pll7_bypass", base + 0x20, 16, 1, pll7_bypass_sels, ARRAY_SIZE(pll7_bypass_sels), CLK_SET_RATE_PARENT);
/* Do not bypass PLLs initially */
- clk_set_parent(clks[IMX6SX_PLL1_BYPASS], clks[IMX6SX_CLK_PLL1]);
- clk_set_parent(clks[IMX6SX_PLL2_BYPASS], clks[IMX6SX_CLK_PLL2]);
- clk_set_parent(clks[IMX6SX_PLL3_BYPASS], clks[IMX6SX_CLK_PLL3]);
- clk_set_parent(clks[IMX6SX_PLL4_BYPASS], clks[IMX6SX_CLK_PLL4]);
- clk_set_parent(clks[IMX6SX_PLL5_BYPASS], clks[IMX6SX_CLK_PLL5]);
- clk_set_parent(clks[IMX6SX_PLL6_BYPASS], clks[IMX6SX_CLK_PLL6]);
- clk_set_parent(clks[IMX6SX_PLL7_BYPASS], clks[IMX6SX_CLK_PLL7]);
-
- clks[IMX6SX_CLK_PLL1_SYS] = imx_clk_gate("pll1_sys", "pll1_bypass", base + 0x00, 13);
+ imx_clk_set_parent(clks[IMX6SX_PLL1_BYPASS], clks[IMX6SX_CLK_PLL1]);
+ imx_clk_set_parent(clks[IMX6SX_PLL2_BYPASS], clks[IMX6SX_CLK_PLL2]);
+ imx_clk_set_parent(clks[IMX6SX_PLL3_BYPASS], clks[IMX6SX_CLK_PLL3]);
+ imx_clk_set_parent(clks[IMX6SX_PLL4_BYPASS], clks[IMX6SX_CLK_PLL4]);
+ imx_clk_set_parent(clks[IMX6SX_PLL5_BYPASS], clks[IMX6SX_CLK_PLL5]);
+ imx_clk_set_parent(clks[IMX6SX_PLL6_BYPASS], clks[IMX6SX_CLK_PLL6]);
+ imx_clk_set_parent(clks[IMX6SX_PLL7_BYPASS], clks[IMX6SX_CLK_PLL7]);
+
+ clks[IMX6SX_CLK_PLL1_SYS] = imx_clk_fixed_factor("pll1_sys", "pll1_bypass", 1, 1);
clks[IMX6SX_CLK_PLL2_BUS] = imx_clk_gate("pll2_bus", "pll2_bypass", base + 0x30, 13);
clks[IMX6SX_CLK_PLL3_USB_OTG] = imx_clk_gate("pll3_usb_otg", "pll3_bypass", base + 0x10, 13);
clks[IMX6SX_CLK_PLL4_AUDIO] = imx_clk_gate("pll4_audio", "pll4_bypass", base + 0x70, 13);
@@ -228,7 +267,9 @@ static void __init imx6sx_clocks_init(struct device_node *ccm_node)
clks[IMX6SX_CLK_PCIE_REF_125M] = imx_clk_gate("pcie_ref_125m", "pcie_ref", base + 0xe0, 19);
clks[IMX6SX_CLK_LVDS1_OUT] = imx_clk_gate_exclusive("lvds1_out", "lvds1_sel", base + 0x160, 10, BIT(12));
+ clks[IMX6SX_CLK_LVDS2_OUT] = imx_clk_gate_exclusive("lvds2_out", "lvds2_sel", base + 0x160, 11, BIT(13));
clks[IMX6SX_CLK_LVDS1_IN] = imx_clk_gate_exclusive("lvds1_in", "anaclk1", base + 0x160, 12, BIT(10));
+ clks[IMX6SX_CLK_LVDS2_IN] = imx_clk_gate_exclusive("lvds2_in", "anaclk2", base + 0x160, 13, BIT(11));
clks[IMX6SX_CLK_ENET_REF] = clk_register_divider_table(NULL, "enet_ref", "pll6_enet", 0,
base + 0xe0, 0, 2, 0, clk_enet_ref_table,
@@ -270,6 +311,7 @@ static void __init imx6sx_clocks_init(struct device_node *ccm_node)
/* name reg shift width parent_names num_parents */
clks[IMX6SX_CLK_LVDS1_SEL] = imx_clk_mux("lvds1_sel", base + 0x160, 0, 5, lvds_sels, ARRAY_SIZE(lvds_sels));
+ clks[IMX6SX_CLK_LVDS2_SEL] = imx_clk_mux("lvds2_sel", base + 0x160, 5, 5, lvds_sels, ARRAY_SIZE(lvds_sels));
np = ccm_node;
base = of_iomap(np, 0);
@@ -277,12 +319,12 @@ static void __init imx6sx_clocks_init(struct device_node *ccm_node)
/* name reg shift width parent_names num_parents */
clks[IMX6SX_CLK_STEP] = imx_clk_mux("step", base + 0xc, 8, 1, step_sels, ARRAY_SIZE(step_sels));
- clks[IMX6SX_CLK_PLL1_SW] = imx_clk_mux("pll1_sw", base + 0xc, 2, 1, pll1_sw_sels, ARRAY_SIZE(pll1_sw_sels));
+ clks[IMX6SX_CLK_PLL1_SW] = imx_clk_mux_glitchless("pll1_sw", base + 0xc, 2, 1, pll1_sw_sels, ARRAY_SIZE(pll1_sw_sels));
clks[IMX6SX_CLK_OCRAM_SEL] = imx_clk_mux("ocram_sel", base + 0x14, 6, 2, ocram_sels, ARRAY_SIZE(ocram_sels));
- clks[IMX6SX_CLK_PERIPH_PRE] = imx_clk_mux("periph_pre", base + 0x18, 18, 2, periph_pre_sels, ARRAY_SIZE(periph_pre_sels));
- clks[IMX6SX_CLK_PERIPH2_PRE] = imx_clk_mux("periph2_pre", base + 0x18, 21, 2, periph2_pre_sels, ARRAY_SIZE(periph2_pre_sels));
- clks[IMX6SX_CLK_PERIPH_CLK2_SEL] = imx_clk_mux("periph_clk2_sel", base + 0x18, 12, 2, periph_clk2_sels, ARRAY_SIZE(periph_clk2_sels));
- clks[IMX6SX_CLK_PERIPH2_CLK2_SEL] = imx_clk_mux("periph2_clk2_sel", base + 0x18, 20, 1, periph2_clk2_sels, ARRAY_SIZE(periph2_clk2_sels));
+ clks[IMX6SX_CLK_PERIPH_PRE] = imx_clk_mux_bus("periph_pre", base + 0x18, 18, 2, periph_pre_sels, ARRAY_SIZE(periph_pre_sels));
+ clks[IMX6SX_CLK_PERIPH2_PRE] = imx_clk_mux_bus("periph2_pre", base + 0x18, 21, 2, periph2_pre_sels, ARRAY_SIZE(periph2_pre_sels));
+ clks[IMX6SX_CLK_PERIPH_CLK2_SEL] = imx_clk_mux_bus("periph_clk2_sel", base + 0x18, 12, 2, periph_clk2_sels, ARRAY_SIZE(periph_clk2_sels));
+ clks[IMX6SX_CLK_PERIPH2_CLK2_SEL] = imx_clk_mux_bus("periph2_clk2_sel", base + 0x18, 20, 1, periph2_clk2_sels, ARRAY_SIZE(periph2_clk2_sels));
clks[IMX6SX_CLK_PCIE_AXI_SEL] = imx_clk_mux("pcie_axi_sel", base + 0x18, 10, 1, pcie_axi_sels, ARRAY_SIZE(pcie_axi_sels));
clks[IMX6SX_CLK_GPU_AXI_SEL] = imx_clk_mux("gpu_axi_sel", base + 0x18, 8, 2, gpu_axi_sels, ARRAY_SIZE(gpu_axi_sels));
clks[IMX6SX_CLK_GPU_CORE_SEL] = imx_clk_mux("gpu_core_sel", base + 0x18, 4, 2, gpu_core_sels, ARRAY_SIZE(gpu_core_sels));
@@ -294,13 +336,13 @@ static void __init imx6sx_clocks_init(struct device_node *ccm_node)
clks[IMX6SX_CLK_SSI3_SEL] = imx_clk_mux("ssi3_sel", base + 0x1c, 14, 2, ssi_sels, ARRAY_SIZE(ssi_sels));
clks[IMX6SX_CLK_SSI2_SEL] = imx_clk_mux("ssi2_sel", base + 0x1c, 12, 2, ssi_sels, ARRAY_SIZE(ssi_sels));
clks[IMX6SX_CLK_SSI1_SEL] = imx_clk_mux("ssi1_sel", base + 0x1c, 10, 2, ssi_sels, ARRAY_SIZE(ssi_sels));
- clks[IMX6SX_CLK_QSPI1_SEL] = imx_clk_mux_flags("qspi1_sel", base + 0x1c, 7, 3, qspi1_sels, ARRAY_SIZE(qspi1_sels), CLK_SET_RATE_PARENT);
+ clks[IMX6SX_CLK_QSPI1_SEL] = imx_clk_mux("qspi1_sel", base + 0x1c, 7, 3, qspi1_sels, ARRAY_SIZE(qspi1_sels));
clks[IMX6SX_CLK_PERCLK_SEL] = imx_clk_mux("perclk_sel", base + 0x1c, 6, 1, perclk_sels, ARRAY_SIZE(perclk_sels));
clks[IMX6SX_CLK_VID_SEL] = imx_clk_mux("vid_sel", base + 0x20, 21, 3, vid_sels, ARRAY_SIZE(vid_sels));
clks[IMX6SX_CLK_ESAI_SEL] = imx_clk_mux("esai_sel", base + 0x20, 19, 2, audio_sels, ARRAY_SIZE(audio_sels));
clks[IMX6SX_CLK_CAN_SEL] = imx_clk_mux("can_sel", base + 0x20, 8, 2, can_sels, ARRAY_SIZE(can_sels));
clks[IMX6SX_CLK_UART_SEL] = imx_clk_mux("uart_sel", base + 0x24, 6, 1, uart_sels, ARRAY_SIZE(uart_sels));
- clks[IMX6SX_CLK_QSPI2_SEL] = imx_clk_mux_flags("qspi2_sel", base + 0x2c, 15, 3, qspi2_sels, ARRAY_SIZE(qspi2_sels), CLK_SET_RATE_PARENT);
+ clks[IMX6SX_CLK_QSPI2_SEL] = imx_clk_mux("qspi2_sel", base + 0x2c, 15, 3, qspi2_sels, ARRAY_SIZE(qspi2_sels));
clks[IMX6SX_CLK_SPDIF_SEL] = imx_clk_mux("spdif_sel", base + 0x30, 20, 2, audio_sels, ARRAY_SIZE(audio_sels));
clks[IMX6SX_CLK_AUDIO_SEL] = imx_clk_mux("audio_sel", base + 0x30, 7, 2, audio_sels, ARRAY_SIZE(audio_sels));
clks[IMX6SX_CLK_ENET_PRE_SEL] = imx_clk_mux("enet_pre_sel", base + 0x34, 15, 3, enet_pre_sels, ARRAY_SIZE(enet_pre_sels));
@@ -494,79 +536,196 @@ static void __init imx6sx_clocks_init(struct device_node *ccm_node)
clks[IMX6SX_CLK_CKO1] = imx_clk_gate("cko1", "cko1_podf", base + 0x60, 7);
clks[IMX6SX_CLK_CKO2] = imx_clk_gate("cko2", "cko2_podf", base + 0x60, 24);
+ /* get those shared clk nodes if M4 is active */
+ if (imx_src_is_m4_enabled()) {
+ u32 num;
+
+ of_property_read_u32(np, "fsl,shared-clks-number", &num);
+ if (num > MAX_SHARED_CLK_NUMBER)
+ pr_err("clk: shared clk nodes exceed the max number!\n");
+ of_property_read_u32_array(np, "fsl,shared-clks-index",
+ clks_shared, num);
+ if (of_property_read_u32(np, "fsl,shared-mem-addr",
+ &shared_mem_paddr))
+ pr_err("clk: fsl,shared-mem-addr NOT found!\n");
+ if (of_property_read_u32(np, "fsl,shared-mem-size",
+ &shared_mem_size))
+ pr_err("clk: fsl,shared-mem-size NOT found!\n");
+ }
+
/* mask handshake of mmdc */
writel_relaxed(BM_CCM_CCDR_MMDC_CH0_MASK, base + CCDR);
imx_check_clocks(clks, ARRAY_SIZE(clks));
+ /*
+ * QSPI2/GPMI_IO share the same clock source but with the
+ * different gate, need explicitely gate the QSPI2 & GPMI_IO
+ * during the clock init phase according to the SOC design.
+ */
+ if (!imx_src_is_m4_enabled()) {
+ writel_relaxed(readl_relaxed(base + 0x78) &
+ ~(3 << CCM_CCGR_OFFSET(5)), base + 0x78);
+ writel_relaxed(readl_relaxed(base + 0x78) &
+ ~(3 << CCM_CCGR_OFFSET(14)), base + 0x78);
+ }
+
clk_data.clks = clks;
clk_data.clk_num = ARRAY_SIZE(clks);
of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
- for (i = 0; i < ARRAY_SIZE(clks_init_on); i++)
- clk_prepare_enable(clks[clks_init_on[i]]);
+ /*
+ * As some of the modules need to access ocotp in MSL,
+ * need to make sure ocotp clk(CCM_CCGR2_CG6) is enabled
+ * during MSL, as on i.MX6SX, accessing OCOTP registers
+ * needs its clk on, it will be disabled by clk late
+ * init and managed by ocotp driver.
+ */
+ writel_relaxed(readl_relaxed(base + 0x70) | 1 << 12, base + 0x70);
+
+ /* maintain M4 usecount */
+ if (imx_src_is_m4_enabled())
+ imx_clk_prepare_enable(clks[IMX6SX_CLK_M4]);
+
+ /* set perclk to from OSC */
+ imx_clk_set_parent(clks[IMX6SX_CLK_PERCLK_SEL], clks[IMX6SX_CLK_OSC]);
if (IS_ENABLED(CONFIG_USB_MXS_PHY)) {
- clk_prepare_enable(clks[IMX6SX_CLK_USBPHY1_GATE]);
- clk_prepare_enable(clks[IMX6SX_CLK_USBPHY2_GATE]);
+ imx_clk_prepare_enable(clks[IMX6SX_CLK_USBPHY1_GATE]);
+ imx_clk_prepare_enable(clks[IMX6SX_CLK_USBPHY2_GATE]);
}
/* Set the default 132MHz for EIM module */
- clk_set_parent(clks[IMX6SX_CLK_EIM_SLOW_SEL], clks[IMX6SX_CLK_PLL2_PFD2]);
- clk_set_rate(clks[IMX6SX_CLK_EIM_SLOW], 132000000);
+ imx_clk_set_parent(clks[IMX6SX_CLK_EIM_SLOW_SEL], clks[IMX6SX_CLK_PLL2_PFD2]);
+ imx_clk_set_rate(clks[IMX6SX_CLK_EIM_SLOW], 132000000);
/* set parent clock for LCDIF1 pixel clock */
- clk_set_parent(clks[IMX6SX_CLK_LCDIF1_PRE_SEL], clks[IMX6SX_CLK_PLL5_VIDEO_DIV]);
- clk_set_parent(clks[IMX6SX_CLK_LCDIF1_SEL], clks[IMX6SX_CLK_LCDIF1_PODF]);
+ imx_clk_set_parent(clks[IMX6SX_CLK_LCDIF1_PRE_SEL], clks[IMX6SX_CLK_PLL5_VIDEO_DIV]);
+ imx_clk_set_parent(clks[IMX6SX_CLK_LCDIF1_SEL], clks[IMX6SX_CLK_LCDIF1_PODF]);
+
+ /* set parent clock for LCDIF2 */
+ imx_clk_set_parent(clks[IMX6SX_CLK_LCDIF2_SEL], clks[IMX6SX_CLK_LDB_DI0]);
/* Set the parent clks of PCIe lvds1 and pcie_axi to be pcie ref, axi */
- if (clk_set_parent(clks[IMX6SX_CLK_LVDS1_SEL], clks[IMX6SX_CLK_PCIE_REF_125M]))
- pr_err("Failed to set pcie bus parent clk.\n");
- if (clk_set_parent(clks[IMX6SX_CLK_PCIE_AXI_SEL], clks[IMX6SX_CLK_AXI]))
- pr_err("Failed to set pcie parent clk.\n");
+ imx_clk_set_parent(clks[IMX6SX_CLK_LVDS1_SEL], clks[IMX6SX_CLK_PCIE_REF_125M]);
+ imx_clk_set_parent(clks[IMX6SX_CLK_PCIE_AXI_SEL], clks[IMX6SX_CLK_AXI]);
/*
* Init enet system AHB clock, set to 200MHz
* pll2_pfd2_396m-> ENET_PODF-> ENET_AHB
*/
- clk_set_parent(clks[IMX6SX_CLK_ENET_PRE_SEL], clks[IMX6SX_CLK_PLL2_PFD2]);
- clk_set_parent(clks[IMX6SX_CLK_ENET_SEL], clks[IMX6SX_CLK_ENET_PODF]);
- clk_set_rate(clks[IMX6SX_CLK_ENET_PODF], 200000000);
- clk_set_rate(clks[IMX6SX_CLK_ENET_REF], 125000000);
- clk_set_rate(clks[IMX6SX_CLK_ENET2_REF], 125000000);
+ imx_clk_set_parent(clks[IMX6SX_CLK_ENET_PRE_SEL], clks[IMX6SX_CLK_PLL2_PFD2]);
+ imx_clk_set_parent(clks[IMX6SX_CLK_ENET_SEL], clks[IMX6SX_CLK_ENET_PODF]);
+ imx_clk_set_rate(clks[IMX6SX_CLK_ENET_PODF], 200000000);
+ imx_clk_set_rate(clks[IMX6SX_CLK_ENET_REF], 125000000);
+ imx_clk_set_rate(clks[IMX6SX_CLK_ENET2_REF], 125000000);
/* Audio clocks */
- clk_set_rate(clks[IMX6SX_CLK_PLL4_AUDIO_DIV], 393216000);
+ imx_clk_set_rate(clks[IMX6SX_CLK_PLL4_AUDIO_DIV], 393216000);
- clk_set_parent(clks[IMX6SX_CLK_SPDIF_SEL], clks[IMX6SX_CLK_PLL4_AUDIO_DIV]);
- clk_set_rate(clks[IMX6SX_CLK_SPDIF_PODF], 98304000);
+ imx_clk_set_parent(clks[IMX6SX_CLK_SPDIF_SEL], clks[IMX6SX_CLK_PLL4_AUDIO_DIV]);
+ imx_clk_set_rate(clks[IMX6SX_CLK_SPDIF_PODF], 24576000);
- clk_set_parent(clks[IMX6SX_CLK_AUDIO_SEL], clks[IMX6SX_CLK_PLL3_USB_OTG]);
- clk_set_rate(clks[IMX6SX_CLK_AUDIO_PODF], 24000000);
+ imx_clk_set_parent(clks[IMX6SX_CLK_AUDIO_SEL], clks[IMX6SX_CLK_PLL3_USB_OTG]);
+ imx_clk_set_rate(clks[IMX6SX_CLK_AUDIO_PODF], 24000000);
- clk_set_parent(clks[IMX6SX_CLK_SSI1_SEL], clks[IMX6SX_CLK_PLL4_AUDIO_DIV]);
- clk_set_parent(clks[IMX6SX_CLK_SSI2_SEL], clks[IMX6SX_CLK_PLL4_AUDIO_DIV]);
- clk_set_parent(clks[IMX6SX_CLK_SSI3_SEL], clks[IMX6SX_CLK_PLL4_AUDIO_DIV]);
- clk_set_rate(clks[IMX6SX_CLK_SSI1_PODF], 24576000);
- clk_set_rate(clks[IMX6SX_CLK_SSI2_PODF], 24576000);
- clk_set_rate(clks[IMX6SX_CLK_SSI3_PODF], 24576000);
+ imx_clk_set_parent(clks[IMX6SX_CLK_SSI1_SEL], clks[IMX6SX_CLK_PLL4_AUDIO_DIV]);
+ imx_clk_set_parent(clks[IMX6SX_CLK_SSI2_SEL], clks[IMX6SX_CLK_PLL4_AUDIO_DIV]);
+ imx_clk_set_parent(clks[IMX6SX_CLK_SSI3_SEL], clks[IMX6SX_CLK_PLL4_AUDIO_DIV]);
+ imx_clk_set_rate(clks[IMX6SX_CLK_SSI1_PODF], 24576000);
+ imx_clk_set_rate(clks[IMX6SX_CLK_SSI2_PODF], 24576000);
+ imx_clk_set_rate(clks[IMX6SX_CLK_SSI3_PODF], 24576000);
- clk_set_parent(clks[IMX6SX_CLK_ESAI_SEL], clks[IMX6SX_CLK_PLL4_AUDIO_DIV]);
- clk_set_rate(clks[IMX6SX_CLK_ESAI_PODF], 24576000);
+ imx_clk_set_parent(clks[IMX6SX_CLK_ESAI_SEL], clks[IMX6SX_CLK_PLL4_AUDIO_DIV]);
+ imx_clk_set_rate(clks[IMX6SX_CLK_ESAI_PODF], 24576000);
- /* Set parent clock for vadc */
- clk_set_parent(clks[IMX6SX_CLK_VID_SEL], clks[IMX6SX_CLK_PLL3_USB_OTG]);
+ /* Set the UART parent if needed. */
+ if (uart_from_osc)
+ clk_set_parent(clks[IMX6SX_CLK_UART_SEL], clks[IMX6SX_CLK_OSC]);
+ else
+ clk_set_parent(clks[IMX6SX_CLK_UART_SEL], clks[IMX6SX_CLK_PLL3_80M]);
- /* default parent of can_sel clock is invalid, manually set it here */
- clk_set_parent(clks[IMX6SX_CLK_CAN_SEL], clks[IMX6SX_CLK_PLL3_60M]);
+ /* Set parent clock for vadc */
+ imx_clk_set_parent(clks[IMX6SX_CLK_VID_SEL], clks[IMX6SX_CLK_PLL3_USB_OTG]);
/* Update gpu clock from default 528M to 720M */
- clk_set_parent(clks[IMX6SX_CLK_GPU_CORE_SEL], clks[IMX6SX_CLK_PLL3_PFD0]);
- clk_set_parent(clks[IMX6SX_CLK_GPU_AXI_SEL], clks[IMX6SX_CLK_PLL3_PFD0]);
+ imx_clk_set_parent(clks[IMX6SX_CLK_GPU_CORE_SEL], clks[IMX6SX_CLK_PLL3_PFD0]);
+ imx_clk_set_parent(clks[IMX6SX_CLK_GPU_AXI_SEL], clks[IMX6SX_CLK_PLL3_PFD0]);
- clk_set_parent(clks[IMX6SX_CLK_QSPI1_SEL], clks[IMX6SX_CLK_PLL2_BUS]);
- clk_set_parent(clks[IMX6SX_CLK_QSPI2_SEL], clks[IMX6SX_CLK_PLL2_BUS]);
+ imx_clk_set_parent(clks[IMX6SX_CLK_QSPI1_SEL], clks[IMX6SX_CLK_PLL2_BUS]);
+ imx_clk_set_parent(clks[IMX6SX_CLK_QSPI2_SEL], clks[IMX6SX_CLK_PLL2_BUS]);
+ /* Set the UART parent if needed. */
+ if (uart_from_osc)
+ imx_clk_set_parent(clks[IMX6SX_CLK_UART_SEL], clks[IMX6SX_CLK_OSC]);
+
+ if (!imx_src_is_m4_enabled())
+ /* default parent of can_sel clock is invalid, manually set it here */
+ imx_clk_set_parent(clks[IMX6SX_CLK_CAN_SEL], clks[IMX6SX_CLK_PLL3_60M]);
+
+ for (i = 0; i < ARRAY_SIZE(clks_init_on); i++)
+ imx_clk_prepare_enable(clks[clks_init_on[i]]);
imx_register_uart_clocks(uart_clks);
}
CLK_OF_DECLARE(imx6sx, "fsl,imx6sx-ccm", imx6sx_clocks_init);
+
+int imx_update_shared_mem(struct clk_hw *hw, bool enable)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(clks_shared); i++) {
+ if (shared_mem->imx_clk[i].self == hw->clk)
+ break;
+ }
+
+ if (i >= ARRAY_SIZE(clks_shared))
+ return 1;
+
+ /* update ca9 clk status in shared memory */
+ if (enable)
+ shared_mem->imx_clk[i].ca9_enabled = 1;
+ else
+ shared_mem->imx_clk[i].ca9_enabled = 0;
+
+ if (shared_mem->imx_clk[i].cm4_enabled == 0)
+ return 1;
+
+ return 0;
+}
+
+static int __init imx_amp_power_init(void)
+{
+ int i;
+ void __iomem *shared_mem_base;
+
+ if (!(imx_src_is_m4_enabled() && clk_on_imx6sx()))
+ return 0;
+
+ amp_power_mutex = imx_sema4_mutex_create(0, MCC_POWER_SHMEM_NUMBER);
+
+ shared_mem_base = ioremap_nocache(shared_mem_paddr, shared_mem_size);
+
+ if (!amp_power_mutex) {
+ pr_err("Failed to create sema4 mutex!\n");
+ return 0;
+ }
+
+ shared_mem = (struct imx_shared_mem *)shared_mem_base;
+
+ for (i = 0; i < ARRAY_SIZE(clks_shared); i++) {
+ shared_mem->imx_clk[i].self = clks[clks_shared[i]];
+ shared_mem->imx_clk[i].ca9_enabled = 1;
+ pr_debug("%d: name %s, addr 0x%x\n", i,
+ __clk_get_name(shared_mem->imx_clk[i].self),
+ (u32)&(shared_mem->imx_clk[i]));
+ }
+ /* enable amp power management */
+ shared_mem->ca9_valid = SHARED_MEM_MAGIC_NUMBER;
+
+ pr_info("A9-M4 sema4 num %d, A9-M4 magic number 0x%x - 0x%x.\n",
+ amp_power_mutex->gate_num, shared_mem->ca9_valid,
+ shared_mem->cm4_valid);
+
+ return 0;
+}
+late_initcall(imx_amp_power_init);
diff --git a/drivers/clk/imx/clk-imx6ul.c b/drivers/clk/imx/clk-imx6ul.c
index 5cc5ff1b4e1f..4f614c5c57c9 100644
--- a/drivers/clk/imx/clk-imx6ul.c
+++ b/drivers/clk/imx/clk-imx6ul.c
@@ -1,5 +1,6 @@
/*
- * Copyright (C) 2015 Freescale Semiconductor, Inc.
+ * Copyright (C) 2015-2016 Freescale Semiconductor, Inc.
+ * Copyright 2017 NXP.
*
* The code contained herein is licensed under the GNU General Public
* License. You may obtain a copy of the GNU General Public License
@@ -115,7 +116,8 @@ static inline int clk_on_imx6ul(void)
static inline int clk_on_imx6ull(void)
{
- return of_machine_is_compatible("fsl,imx6ull");
+ return of_machine_is_compatible("fsl,imx6ull") ||
+ of_machine_is_compatible("fsl,imx6ulz");
}
static void __init imx6ul_clocks_init(struct device_node *ccm_node)
@@ -147,7 +149,7 @@ static void __init imx6ul_clocks_init(struct device_node *ccm_node)
clks[IMX6UL_PLL7_BYPASS_SRC] = imx_clk_mux("pll7_bypass_src", base + 0x20, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
clks[IMX6UL_CLK_PLL1] = imx_clk_pllv3(IMX_PLLV3_SYS, "pll1", "osc", base + 0x00, 0x7f);
- clks[IMX6UL_CLK_PLL2] = imx_clk_pllv3(IMX_PLLV3_GENERIC, "pll2", "osc", base + 0x30, 0x1);
+ clks[IMX6UL_CLK_PLL2] = imx_clk_pllv3(IMX_PLLV3_PLL2, "pll2", "osc", base + 0x30, 0x1);
clks[IMX6UL_CLK_PLL3] = imx_clk_pllv3(IMX_PLLV3_USB, "pll3", "osc", base + 0x10, 0x3);
clks[IMX6UL_CLK_PLL4] = imx_clk_pllv3(IMX_PLLV3_AV, "pll4", "osc", base + 0x70, 0x7f);
clks[IMX6UL_CLK_PLL5] = imx_clk_pllv3(IMX_PLLV3_AV, "pll5", "osc", base + 0xa0, 0x7f);
@@ -161,7 +163,6 @@ static void __init imx6ul_clocks_init(struct device_node *ccm_node)
clks[IMX6UL_PLL5_BYPASS] = imx_clk_mux_flags("pll5_bypass", base + 0xa0, 16, 1, pll5_bypass_sels, ARRAY_SIZE(pll5_bypass_sels), CLK_SET_RATE_PARENT);
clks[IMX6UL_PLL6_BYPASS] = imx_clk_mux_flags("pll6_bypass", base + 0xe0, 16, 1, pll6_bypass_sels, ARRAY_SIZE(pll6_bypass_sels), CLK_SET_RATE_PARENT);
clks[IMX6UL_PLL7_BYPASS] = imx_clk_mux_flags("pll7_bypass", base + 0x20, 16, 1, pll7_bypass_sels, ARRAY_SIZE(pll7_bypass_sels), CLK_SET_RATE_PARENT);
- clks[IMX6UL_CLK_CSI_SEL] = imx_clk_mux_flags("csi_sel", base + 0x3c, 9, 2, csi_sels, ARRAY_SIZE(csi_sels), CLK_SET_RATE_PARENT);
/* Do not bypass PLLs initially */
clk_set_parent(clks[IMX6UL_PLL1_BYPASS], clks[IMX6UL_CLK_PLL1]);
@@ -236,13 +237,13 @@ static void __init imx6ul_clocks_init(struct device_node *ccm_node)
clks[IMX6UL_CA7_SECONDARY_SEL] = imx_clk_mux("ca7_secondary_sel", base + 0xc, 3, 1, ca7_secondary_sels, ARRAY_SIZE(ca7_secondary_sels));
clks[IMX6UL_CLK_STEP] = imx_clk_mux("step", base + 0x0c, 8, 1, step_sels, ARRAY_SIZE(step_sels));
- clks[IMX6UL_CLK_PLL1_SW] = imx_clk_mux_flags("pll1_sw", base + 0x0c, 2, 1, pll1_sw_sels, ARRAY_SIZE(pll1_sw_sels), 0);
+ clks[IMX6UL_CLK_PLL1_SW] = imx_clk_mux_glitchless("pll1_sw", base + 0x0c, 2, 1, pll1_sw_sels, ARRAY_SIZE(pll1_sw_sels));
clks[IMX6UL_CLK_AXI_ALT_SEL] = imx_clk_mux("axi_alt_sel", base + 0x14, 7, 1, axi_alt_sels, ARRAY_SIZE(axi_alt_sels));
clks[IMX6UL_CLK_AXI_SEL] = imx_clk_mux_flags("axi_sel", base + 0x14, 6, 1, axi_sels, ARRAY_SIZE(axi_sels), 0);
- clks[IMX6UL_CLK_PERIPH_PRE] = imx_clk_mux("periph_pre", base + 0x18, 18, 2, periph_pre_sels, ARRAY_SIZE(periph_pre_sels));
- clks[IMX6UL_CLK_PERIPH2_PRE] = imx_clk_mux("periph2_pre", base + 0x18, 21, 2, periph2_pre_sels, ARRAY_SIZE(periph2_pre_sels));
- clks[IMX6UL_CLK_PERIPH_CLK2_SEL] = imx_clk_mux("periph_clk2_sel", base + 0x18, 12, 2, periph_clk2_sels, ARRAY_SIZE(periph_clk2_sels));
- clks[IMX6UL_CLK_PERIPH2_CLK2_SEL] = imx_clk_mux("periph2_clk2_sel", base + 0x18, 20, 1, periph2_clk2_sels, ARRAY_SIZE(periph2_clk2_sels));
+ clks[IMX6UL_CLK_PERIPH_PRE] = imx_clk_mux_bus("periph_pre", base + 0x18, 18, 2, periph_pre_sels, ARRAY_SIZE(periph_pre_sels));
+ clks[IMX6UL_CLK_PERIPH2_PRE] = imx_clk_mux_bus("periph2_pre", base + 0x18, 21, 2, periph2_pre_sels, ARRAY_SIZE(periph2_pre_sels));
+ clks[IMX6UL_CLK_PERIPH_CLK2_SEL] = imx_clk_mux_bus("periph_clk2_sel", base + 0x18, 12, 2, periph_clk2_sels, ARRAY_SIZE(periph_clk2_sels));
+ clks[IMX6UL_CLK_PERIPH2_CLK2_SEL] = imx_clk_mux_bus("periph2_clk2_sel", base + 0x18, 20, 1, periph2_clk2_sels, ARRAY_SIZE(periph2_clk2_sels));
clks[IMX6UL_CLK_EIM_SLOW_SEL] = imx_clk_mux("eim_slow_sel", base + 0x1c, 29, 2, eim_slow_sels, ARRAY_SIZE(eim_slow_sels));
clks[IMX6UL_CLK_GPMI_SEL] = imx_clk_mux("gpmi_sel", base + 0x1c, 19, 1, gpmi_sels, ARRAY_SIZE(gpmi_sels));
clks[IMX6UL_CLK_BCH_SEL] = imx_clk_mux("bch_sel", base + 0x1c, 18, 1, bch_sels, ARRAY_SIZE(bch_sels));
@@ -270,6 +271,7 @@ static void __init imx6ul_clocks_init(struct device_node *ccm_node)
clks[IMX6UL_CLK_ECSPI_SEL] = imx_clk_mux("ecspi_sel", base + 0x38, 18, 1, ecspi_sels, ARRAY_SIZE(ecspi_sels));
clks[IMX6UL_CLK_LCDIF_PRE_SEL] = imx_clk_mux("lcdif_pre_sel", base + 0x38, 15, 3, lcdif_pre_sels, ARRAY_SIZE(lcdif_pre_sels));
clks[IMX6UL_CLK_LCDIF_SEL] = imx_clk_mux("lcdif_sel", base + 0x38, 9, 3, lcdif_sels, ARRAY_SIZE(lcdif_sels));
+ clks[IMX6UL_CLK_CSI_SEL] = imx_clk_mux_flags("csi_sel", base + 0x3c, 9, 2, csi_sels, ARRAY_SIZE(csi_sels), CLK_SET_RATE_PARENT);
clks[IMX6UL_CLK_LDB_DI0_DIV_SEL] = imx_clk_mux("ldb_di0", base + 0x20, 10, 1, ldb_di0_div_sels, ARRAY_SIZE(ldb_di0_div_sels));
clks[IMX6UL_CLK_LDB_DI1_DIV_SEL] = imx_clk_mux("ldb_di1", base + 0x20, 11, 1, ldb_di1_div_sels, ARRAY_SIZE(ldb_di1_div_sels));
@@ -309,7 +311,10 @@ static void __init imx6ul_clocks_init(struct device_node *ccm_node)
clks[IMX6UL_CLK_SAI2_PODF] = imx_clk_divider("sai2_podf", "sai2_pred", base + 0x2c, 0, 6);
clks[IMX6UL_CLK_SPDIF_PRED] = imx_clk_divider("spdif_pred", "spdif_sel", base + 0x30, 25, 3);
clks[IMX6UL_CLK_SPDIF_PODF] = imx_clk_divider("spdif_podf", "spdif_pred", base + 0x30, 22, 3);
- clks[IMX6UL_CLK_SIM_PODF] = imx_clk_divider("sim_podf", "sim_pre_sel", base + 0x34, 12, 3);
+ if (clk_on_imx6ul())
+ clks[IMX6UL_CLK_SIM_PODF] = imx_clk_divider("sim_podf", "sim_pre_sel", base + 0x34, 12, 3);
+ else
+ clks[IMX6ULL_CLK_EPDC_PODF] = imx_clk_divider("epdc_podf", "epdc_pre_sel", base + 0x34, 12, 3);
clks[IMX6UL_CLK_ECSPI_PODF] = imx_clk_divider("ecspi_podf", "ecspi_sel", base + 0x38, 19, 6);
clks[IMX6UL_CLK_LCDIF_PRED] = imx_clk_divider("lcdif_pred", "lcdif_pre_sel", base + 0x38, 12, 3);
clks[IMX6UL_CLK_CSI_PODF] = imx_clk_divider("csi_podf", "csi_sel", base + 0x3c, 11, 3);
@@ -473,9 +478,16 @@ static void __init imx6ul_clocks_init(struct device_node *ccm_node)
/* set perclk to from OSC */
clk_set_parent(clks[IMX6UL_CLK_PERCLK_SEL], clks[IMX6UL_CLK_OSC]);
+ /* Set the UART parent if needed */
+ if (uart_from_osc)
+ imx_clk_set_parent(clks[IMX6UL_CLK_UART_SEL], clks[IMX6UL_CLK_OSC]);
+ else
+ imx_clk_set_parent(clks[IMX6UL_CLK_UART_SEL], clks[IMX6UL_CLK_PLL3_80M]);
+
clk_set_rate(clks[IMX6UL_CLK_ENET_REF], 50000000);
clk_set_rate(clks[IMX6UL_CLK_ENET2_REF], 50000000);
clk_set_rate(clks[IMX6UL_CLK_CSI], 24000000);
+ clk_set_rate(clks[IMX6UL_CLK_PLL3_PFD2], 320000000);
/* keep all the clks on just for bringup */
for (i = 0; i < ARRAY_SIZE(clks_init_on); i++)
@@ -496,6 +508,17 @@ static void __init imx6ul_clocks_init(struct device_node *ccm_node)
clk_set_parent(clks[IMX6ULL_CLK_EPDC_PRE_SEL], clks[IMX6UL_CLK_PLL3_PFD2]);
clk_set_parent(clks[IMX6UL_CLK_ENFC_SEL], clks[IMX6UL_CLK_PLL2_PFD2]);
+
+ /* Lower the AHB clock rate before changing the clock source. */
+ imx_clk_set_rate(clks[IMX6UL_CLK_AHB], 99000000);
+
+ /* Change periph_pre clock to pll2_bus to adjust AXI rate to 264MHz */
+ imx_clk_set_parent(clks[IMX6UL_CLK_PERIPH_CLK2_SEL], clks[IMX6UL_CLK_PLL3_USB_OTG]);
+ imx_clk_set_parent(clks[IMX6UL_CLK_PERIPH], clks[IMX6UL_CLK_PERIPH_CLK2]);
+ imx_clk_set_parent(clks[IMX6UL_CLK_PERIPH_PRE], clks[IMX6UL_CLK_PLL2_BUS]);
+ imx_clk_set_parent(clks[IMX6UL_CLK_PERIPH], clks[IMX6UL_CLK_PERIPH_PRE]);
+
+ imx_clk_set_rate(clks[IMX6UL_CLK_AHB], 132000000);
}
CLK_OF_DECLARE(imx6ul, "fsl,imx6ul-ccm", imx6ul_clocks_init);
diff --git a/drivers/clk/imx/clk-imx7d.c b/drivers/clk/imx/clk-imx7d.c
index 0ac9b30c8b90..de71c4a02a91 100644
--- a/drivers/clk/imx/clk-imx7d.c
+++ b/drivers/clk/imx/clk-imx7d.c
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2014-2015 Freescale Semiconductor, Inc.
+ * Copyright 2017 NXP.
*
* The code contained herein is licensed under the GNU General Public
* License. You may obtain a copy of the GNU General Public License
@@ -19,6 +20,7 @@
#include <linux/of_address.h>
#include <linux/of_irq.h>
#include <linux/types.h>
+#include <soc/imx/src.h>
#include "clk.h"
@@ -26,6 +28,9 @@ static u32 share_count_sai1;
static u32 share_count_sai2;
static u32 share_count_sai3;
static u32 share_count_nand;
+static u32 share_count_pxp;
+static u32 share_count_enet1;
+static u32 share_count_enet2;
static const struct clk_div_table test_div_table[] = {
{ .val = 3, .div = 1, },
@@ -51,25 +56,20 @@ static const char *arm_a7_sel[] = { "osc", "pll_arm_main_clk",
static const char *arm_m4_sel[] = { "osc", "pll_sys_main_240m_clk",
"pll_enet_250m_clk", "pll_sys_pfd2_270m_clk",
- "pll_dram_533m_clk", "pll_audio_post_div", "pll_video_main_clk",
- "pll_usb_main_clk", };
-
-static const char *arm_m0_sel[] = { "osc", "pll_sys_main_120m_clk",
- "pll_enet_125m_clk", "pll_sys_pfd2_135m_clk",
- "pll_dram_533m_clk", "pll_audio_post_div", "pll_video_main_clk",
+ "pll_dram_533m_clk", "pll_audio_post_div", "pll_video_post_div",
"pll_usb_main_clk", };
static const char *axi_sel[] = { "osc", "pll_sys_pfd1_332m_clk",
"pll_dram_533m_clk", "pll_enet_250m_clk", "pll_sys_pfd5_clk",
- "pll_audio_post_div", "pll_video_main_clk", "pll_sys_pfd7_clk", };
+ "pll_audio_post_div", "pll_video_post_div", "pll_sys_pfd7_clk", };
static const char *disp_axi_sel[] = { "osc", "pll_sys_pfd1_332m_clk",
"pll_dram_533m_clk", "pll_enet_250m_clk", "pll_sys_pfd6_clk",
- "pll_sys_pfd7_clk", "pll_audio_post_div", "pll_video_main_clk", };
+ "pll_sys_pfd7_clk", "pll_audio_post_div", "pll_video_post_div", };
static const char *enet_axi_sel[] = { "osc", "pll_sys_pfd2_270m_clk",
"pll_dram_533m_clk", "pll_enet_250m_clk",
- "pll_sys_main_240m_clk", "pll_audio_post_div", "pll_video_main_clk",
+ "pll_sys_main_240m_clk", "pll_audio_post_div", "pll_video_post_div",
"pll_sys_pfd4_clk", };
static const char *nand_usdhc_bus_sel[] = { "osc", "pll_sys_pfd2_270m_clk",
@@ -79,8 +79,8 @@ static const char *nand_usdhc_bus_sel[] = { "osc", "pll_sys_pfd2_270m_clk",
static const char *ahb_channel_sel[] = { "osc", "pll_sys_pfd2_270m_clk",
"pll_dram_533m_clk", "pll_sys_pfd0_392m_clk",
- "pll_enet_125m_clk", "pll_usb_main_clk", "pll_audio_post_div",
- "pll_video_main_clk", };
+ "pll_enet_250m_clk", "pll_usb_main_clk", "pll_audio_post_div",
+ "pll_video_post_div", };
static const char *dram_phym_sel[] = { "pll_dram_main_clk",
"dram_phym_alt_clk", };
@@ -91,7 +91,7 @@ static const char *dram_sel[] = { "pll_dram_main_clk",
static const char *dram_phym_alt_sel[] = { "osc", "pll_dram_533m_clk",
"pll_sys_main_clk", "pll_enet_500m_clk",
"pll_usb_main_clk", "pll_sys_pfd7_clk", "pll_audio_post_div",
- "pll_video_main_clk", };
+ "pll_video_post_div", };
static const char *dram_alt_sel[] = { "osc", "pll_dram_533m_clk",
"pll_sys_main_clk", "pll_enet_500m_clk",
@@ -113,62 +113,62 @@ static const char *pcie_phy_sel[] = { "osc", "pll_enet_100m_clk",
static const char *epdc_pixel_sel[] = { "osc", "pll_sys_pfd1_332m_clk",
"pll_dram_533m_clk", "pll_sys_main_clk", "pll_sys_pfd5_clk",
- "pll_sys_pfd6_clk", "pll_sys_pfd7_clk", "pll_video_main_clk", };
+ "pll_sys_pfd6_clk", "pll_sys_pfd7_clk", "pll_video_post_div", };
static const char *lcdif_pixel_sel[] = { "osc", "pll_sys_pfd5_clk",
"pll_dram_533m_clk", "ext_clk_3", "pll_sys_pfd4_clk",
- "pll_sys_pfd2_270m_clk", "pll_video_main_clk",
+ "pll_sys_pfd2_270m_clk", "pll_video_post_div",
"pll_usb_main_clk", };
static const char *mipi_dsi_sel[] = { "osc", "pll_sys_pfd5_clk",
"pll_sys_pfd3_clk", "pll_sys_main_clk", "pll_sys_pfd0_196m_clk",
- "pll_dram_533m_clk", "pll_video_main_clk", "pll_audio_post_div", };
+ "pll_dram_533m_clk", "pll_video_post_div", "pll_audio_post_div", };
static const char *mipi_csi_sel[] = { "osc", "pll_sys_pfd4_clk",
"pll_sys_pfd3_clk", "pll_sys_main_clk", "pll_sys_pfd0_196m_clk",
- "pll_dram_533m_clk", "pll_video_main_clk", "pll_audio_post_div", };
+ "pll_dram_533m_clk", "pll_video_post_div", "pll_audio_post_div", };
static const char *mipi_dphy_sel[] = { "osc", "pll_sys_main_120m_clk",
"pll_dram_533m_clk", "pll_sys_pfd5_clk", "ref_1m_clk", "ext_clk_2",
- "pll_video_main_clk", "ext_clk_3", };
+ "pll_video_post_div", "ext_clk_3", };
static const char *sai1_sel[] = { "osc", "pll_sys_pfd2_135m_clk",
- "pll_audio_post_div", "pll_dram_533m_clk", "pll_video_main_clk",
+ "pll_audio_post_div", "pll_dram_533m_clk", "pll_video_post_div",
"pll_sys_pfd4_clk", "pll_enet_125m_clk", "ext_clk_2", };
static const char *sai2_sel[] = { "osc", "pll_sys_pfd2_135m_clk",
- "pll_audio_post_div", "pll_dram_533m_clk", "pll_video_main_clk",
+ "pll_audio_post_div", "pll_dram_533m_clk", "pll_video_post_div",
"pll_sys_pfd4_clk", "pll_enet_125m_clk", "ext_clk_2", };
static const char *sai3_sel[] = { "osc", "pll_sys_pfd2_135m_clk",
- "pll_audio_post_div", "pll_dram_533m_clk", "pll_video_main_clk",
+ "pll_audio_post_div", "pll_dram_533m_clk", "pll_video_post_div",
"pll_sys_pfd4_clk", "pll_enet_125m_clk", "ext_clk_3", };
static const char *spdif_sel[] = { "osc", "pll_sys_pfd2_135m_clk",
- "pll_audio_post_div", "pll_dram_533m_clk", "pll_video_main_clk",
+ "pll_audio_post_div", "pll_dram_533m_clk", "pll_video_post_div",
"pll_sys_pfd4_clk", "pll_enet_125m_clk", "ext_3_clk", };
static const char *enet1_ref_sel[] = { "osc", "pll_enet_125m_clk",
"pll_enet_50m_clk", "pll_enet_25m_clk",
- "pll_sys_main_120m_clk", "pll_audio_post_div", "pll_video_main_clk",
+ "pll_sys_main_120m_clk", "pll_audio_post_div", "pll_video_post_div",
"ext_clk_4", };
static const char *enet1_time_sel[] = { "osc", "pll_enet_100m_clk",
"pll_audio_post_div", "ext_clk_1", "ext_clk_2", "ext_clk_3",
- "ext_clk_4", "pll_video_main_clk", };
+ "ext_clk_4", "pll_video_post_div", };
static const char *enet2_ref_sel[] = { "osc", "pll_enet_125m_clk",
"pll_enet_50m_clk", "pll_enet_25m_clk",
- "pll_sys_main_120m_clk", "pll_audio_post_div", "pll_video_main_clk",
+ "pll_sys_main_120m_clk", "pll_audio_post_div", "pll_video_post_div",
"ext_clk_4", };
static const char *enet2_time_sel[] = { "osc", "pll_enet_100m_clk",
"pll_audio_post_div", "ext_clk_1", "ext_clk_2", "ext_clk_3",
- "ext_clk_4", "pll_video_main_clk", };
+ "ext_clk_4", "pll_video_post_div", };
static const char *enet_phy_ref_sel[] = { "osc", "pll_enet_25m_clk",
"pll_enet_50m_clk", "pll_enet_125m_clk",
- "pll_dram_533m_clk", "pll_audio_post_div", "pll_video_main_clk",
+ "pll_dram_533m_clk", "pll_audio_post_div", "pll_video_post_div",
"pll_sys_pfd3_clk", };
static const char *eim_sel[] = { "osc", "pll_sys_pfd2_135m_clk",
@@ -179,7 +179,7 @@ static const char *eim_sel[] = { "osc", "pll_sys_pfd2_135m_clk",
static const char *nand_sel[] = { "osc", "pll_sys_main_clk",
"pll_dram_533m_clk", "pll_sys_pfd0_392m_clk", "pll_sys_pfd3_clk",
"pll_enet_500m_clk", "pll_enet_250m_clk",
- "pll_video_main_clk", };
+ "pll_video_post_div", };
static const char *qspi_sel[] = { "osc", "pll_sys_pfd4_clk",
"pll_dram_533m_clk", "pll_enet_500m_clk", "pll_sys_pfd3_clk",
@@ -209,22 +209,22 @@ static const char *can2_sel[] = { "osc", "pll_sys_main_120m_clk",
static const char *i2c1_sel[] = { "osc", "pll_sys_main_120m_clk",
"pll_enet_50m_clk", "pll_dram_533m_clk",
- "pll_audio_post_div", "pll_video_main_clk", "pll_usb_main_clk",
+ "pll_audio_post_div", "pll_video_post_div", "pll_usb_main_clk",
"pll_sys_pfd2_135m_clk", };
static const char *i2c2_sel[] = { "osc", "pll_sys_main_120m_clk",
"pll_enet_50m_clk", "pll_dram_533m_clk",
- "pll_audio_post_div", "pll_video_main_clk", "pll_usb_main_clk",
+ "pll_audio_post_div", "pll_video_post_div", "pll_usb_main_clk",
"pll_sys_pfd2_135m_clk", };
static const char *i2c3_sel[] = { "osc", "pll_sys_main_120m_clk",
"pll_enet_50m_clk", "pll_dram_533m_clk",
- "pll_audio_post_div", "pll_video_main_clk", "pll_usb_main_clk",
+ "pll_audio_post_div", "pll_video_post_div", "pll_usb_main_clk",
"pll_sys_pfd2_135m_clk", };
static const char *i2c4_sel[] = { "osc", "pll_sys_main_120m_clk",
"pll_enet_50m_clk", "pll_dram_533m_clk",
- "pll_audio_post_div", "pll_video_main_clk", "pll_usb_main_clk",
+ "pll_audio_post_div", "pll_video_post_div", "pll_usb_main_clk",
"pll_sys_pfd2_135m_clk", };
static const char *uart1_sel[] = { "osc", "pll_sys_main_240m_clk",
@@ -284,27 +284,27 @@ static const char *ecspi4_sel[] = { "osc", "pll_sys_main_240m_clk",
static const char *pwm1_sel[] = { "osc", "pll_enet_100m_clk",
"pll_sys_main_120m_clk", "pll_enet_40m_clk", "pll_audio_post_div",
- "ext_clk_1", "ref_1m_clk", "pll_video_main_clk", };
+ "ext_clk_1", "ref_1m_clk", "pll_video_post_div", };
static const char *pwm2_sel[] = { "osc", "pll_enet_100m_clk",
"pll_sys_main_120m_clk", "pll_enet_40m_clk", "pll_audio_post_div",
- "ext_clk_1", "ref_1m_clk", "pll_video_main_clk", };
+ "ext_clk_1", "ref_1m_clk", "pll_video_post_div", };
static const char *pwm3_sel[] = { "osc", "pll_enet_100m_clk",
"pll_sys_main_120m_clk", "pll_enet_40m_clk", "pll_audio_post_div",
- "ext_clk_2", "ref_1m_clk", "pll_video_main_clk", };
+ "ext_clk_2", "ref_1m_clk", "pll_video_post_div", };
static const char *pwm4_sel[] = { "osc", "pll_enet_100m_clk",
"pll_sys_main_120m_clk", "pll_enet_40m_clk", "pll_audio_post_div",
- "ext_clk_2", "ref_1m_clk", "pll_video_main_clk", };
+ "ext_clk_2", "ref_1m_clk", "pll_video_post_div", };
static const char *flextimer1_sel[] = { "osc", "pll_enet_100m_clk",
"pll_sys_main_120m_clk", "pll_enet_40m_clk", "pll_audio_post_div",
- "ext_clk_3", "ref_1m_clk", "pll_video_main_clk", };
+ "ext_clk_3", "ref_1m_clk", "pll_video_post_div", };
static const char *flextimer2_sel[] = { "osc", "pll_enet_100m_clk",
"pll_sys_main_120m_clk", "pll_enet_40m_clk", "pll_audio_post_div",
- "ext_clk_3", "ref_1m_clk", "pll_video_main_clk", };
+ "ext_clk_3", "ref_1m_clk", "pll_video_post_div", };
static const char *sim1_sel[] = { "osc", "pll_sys_pfd2_135m_clk",
"pll_sys_main_120m_clk", "pll_dram_533m_clk",
@@ -313,23 +313,23 @@ static const char *sim1_sel[] = { "osc", "pll_sys_pfd2_135m_clk",
static const char *sim2_sel[] = { "osc", "pll_sys_pfd2_135m_clk",
"pll_sys_main_120m_clk", "pll_dram_533m_clk",
- "pll_usb_main_clk", "pll_video_main_clk", "pll_enet_125m_clk",
+ "pll_usb_main_clk", "pll_video_post_div", "pll_enet_125m_clk",
"pll_sys_pfd7_clk", };
static const char *gpt1_sel[] = { "osc", "pll_enet_100m_clk",
- "pll_sys_pfd0_392m_clk", "pll_enet_40m_clk", "pll_video_main_clk",
+ "pll_sys_pfd0_392m_clk", "pll_enet_40m_clk", "pll_video_post_div",
"ref_1m_clk", "pll_audio_post_div", "ext_clk_1", };
static const char *gpt2_sel[] = { "osc", "pll_enet_100m_clk",
- "pll_sys_pfd0_392m_clk", "pll_enet_40m_clk", "pll_video_main_clk",
+ "pll_sys_pfd0_392m_clk", "pll_enet_40m_clk", "pll_video_post_div",
"ref_1m_clk", "pll_audio_post_div", "ext_clk_2", };
static const char *gpt3_sel[] = { "osc", "pll_enet_100m_clk",
- "pll_sys_pfd0_392m_clk", "pll_enet_40m_clk", "pll_video_main_clk",
+ "pll_sys_pfd0_392m_clk", "pll_enet_40m_clk", "pll_video_post_div",
"ref_1m_clk", "pll_audio_post_div", "ext_clk_3", };
static const char *gpt4_sel[] = { "osc", "pll_enet_100m_clk",
- "pll_sys_pfd0_392m_clk", "pll_enet_40m_clk", "pll_video_main_clk",
+ "pll_sys_pfd0_392m_clk", "pll_enet_40m_clk", "pll_video_post_div",
"ref_1m_clk", "pll_audio_post_div", "ext_clk_4", };
static const char *trace_sel[] = { "osc", "pll_sys_pfd2_135m_clk",
@@ -344,12 +344,12 @@ static const char *wdog_sel[] = { "osc", "pll_sys_pfd2_135m_clk",
static const char *csi_mclk_sel[] = { "osc", "pll_sys_pfd2_135m_clk",
"pll_sys_main_120m_clk", "pll_dram_533m_clk",
- "pll_enet_125m_clk", "pll_audio_post_div", "pll_video_main_clk",
+ "pll_enet_125m_clk", "pll_audio_post_div", "pll_video_post_div",
"pll_usb_main_clk", };
static const char *audio_mclk_sel[] = { "osc", "pll_sys_pfd2_135m_clk",
"pll_sys_main_120m_clk", "pll_dram_533m_clk",
- "pll_enet_125m_clk", "pll_audio_post_div", "pll_video_main_clk",
+ "pll_enet_125m_clk", "pll_audio_post_div", "pll_video_post_div",
"pll_usb_main_clk", };
static const char *wrclk_sel[] = { "osc", "pll_enet_40m_clk",
@@ -363,13 +363,13 @@ static const char *clko1_sel[] = { "osc", "pll_sys_main_clk",
static const char *clko2_sel[] = { "osc", "pll_sys_main_240m_clk",
"pll_sys_pfd0_392m_clk", "pll_sys_pfd1_166m_clk", "pll_sys_pfd4_clk",
- "pll_audio_post_div", "pll_video_main_clk", "ckil", };
+ "pll_audio_post_div", "pll_video_post_div", "ckil", };
static const char *lvds1_sel[] = { "pll_arm_main_clk",
"pll_sys_main_clk", "pll_sys_pfd0_392m_clk", "pll_sys_pfd1_332m_clk",
"pll_sys_pfd2_270m_clk", "pll_sys_pfd3_clk", "pll_sys_pfd4_clk",
"pll_sys_pfd5_clk", "pll_sys_pfd6_clk", "pll_sys_pfd7_clk",
- "pll_audio_post_div", "pll_video_main_clk", "pll_enet_500m_clk",
+ "pll_audio_post_div", "pll_video_post_div", "pll_enet_500m_clk",
"pll_enet_250m_clk", "pll_enet_125m_clk", "pll_enet_100m_clk",
"pll_enet_50m_clk", "pll_enet_40m_clk", "pll_enet_25m_clk",
"pll_dram_main_clk", };
@@ -384,7 +384,7 @@ static const char *pll_video_bypass_sel[] = { "pll_video_main", "pll_video_main_
static int const clks_init_on[] __initconst = {
IMX7D_ARM_A7_ROOT_CLK, IMX7D_MAIN_AXI_ROOT_CLK,
- IMX7D_PLL_SYS_MAIN_480M_CLK, IMX7D_NAND_USDHC_BUS_ROOT_CLK,
+ IMX7D_PLL_SYS_MAIN_480M_CLK,
IMX7D_DRAM_PHYM_ROOT_CLK, IMX7D_DRAM_ROOT_CLK,
IMX7D_DRAM_PHYM_ALT_ROOT_CLK, IMX7D_DRAM_ALT_ROOT_CLK,
IMX7D_AHB_CHANNEL_ROOT_CLK, IMX7D_IPG_ROOT_CLK,
@@ -428,8 +428,8 @@ static void __init imx7d_clocks_init(struct device_node *ccm_node)
clks[IMX7D_PLL_DRAM_MAIN] = imx_clk_pllv3(IMX_PLLV3_DDR_IMX7, "pll_dram_main", "osc", base + 0x70, 0x7f);
clks[IMX7D_PLL_SYS_MAIN] = imx_clk_pllv3(IMX_PLLV3_GENERIC, "pll_sys_main", "osc", base + 0xb0, 0x1);
clks[IMX7D_PLL_ENET_MAIN] = imx_clk_pllv3(IMX_PLLV3_ENET_IMX7, "pll_enet_main", "osc", base + 0xe0, 0x0);
- clks[IMX7D_PLL_AUDIO_MAIN] = imx_clk_pllv3(IMX_PLLV3_AV, "pll_audio_main", "osc", base + 0xf0, 0x7f);
- clks[IMX7D_PLL_VIDEO_MAIN] = imx_clk_pllv3(IMX_PLLV3_AV, "pll_video_main", "osc", base + 0x130, 0x7f);
+ clks[IMX7D_PLL_AUDIO_MAIN] = imx_clk_pllv3(IMX_PLLV3_AV_IMX7, "pll_audio_main", "osc", base + 0xf0, 0x7f);
+ clks[IMX7D_PLL_VIDEO_MAIN] = imx_clk_pllv3(IMX_PLLV3_AV_IMX7, "pll_video_main", "osc", base + 0x130, 0x7f);
clks[IMX7D_PLL_ARM_MAIN_BYPASS] = imx_clk_mux_flags("pll_arm_main_bypass", base + 0x60, 16, 1, pll_arm_bypass_sel, ARRAY_SIZE(pll_arm_bypass_sel), CLK_SET_RATE_PARENT);
clks[IMX7D_PLL_DRAM_MAIN_BYPASS] = imx_clk_mux_flags("pll_dram_main_bypass", base + 0x70, 16, 1, pll_dram_bypass_sel, ARRAY_SIZE(pll_dram_bypass_sel), CLK_SET_RATE_PARENT);
@@ -438,23 +438,22 @@ static void __init imx7d_clocks_init(struct device_node *ccm_node)
clks[IMX7D_PLL_AUDIO_MAIN_BYPASS] = imx_clk_mux_flags("pll_audio_main_bypass", base + 0xf0, 16, 1, pll_audio_bypass_sel, ARRAY_SIZE(pll_audio_bypass_sel), CLK_SET_RATE_PARENT);
clks[IMX7D_PLL_VIDEO_MAIN_BYPASS] = imx_clk_mux_flags("pll_video_main_bypass", base + 0x130, 16, 1, pll_video_bypass_sel, ARRAY_SIZE(pll_video_bypass_sel), CLK_SET_RATE_PARENT);
- clk_set_parent(clks[IMX7D_PLL_ARM_MAIN_BYPASS], clks[IMX7D_PLL_ARM_MAIN]);
- clk_set_parent(clks[IMX7D_PLL_DRAM_MAIN_BYPASS], clks[IMX7D_PLL_DRAM_MAIN]);
- clk_set_parent(clks[IMX7D_PLL_SYS_MAIN_BYPASS], clks[IMX7D_PLL_SYS_MAIN]);
- clk_set_parent(clks[IMX7D_PLL_ENET_MAIN_BYPASS], clks[IMX7D_PLL_ENET_MAIN]);
- clk_set_parent(clks[IMX7D_PLL_AUDIO_MAIN_BYPASS], clks[IMX7D_PLL_AUDIO_MAIN]);
- clk_set_parent(clks[IMX7D_PLL_VIDEO_MAIN_BYPASS], clks[IMX7D_PLL_VIDEO_MAIN]);
-
clks[IMX7D_PLL_ARM_MAIN_CLK] = imx_clk_gate("pll_arm_main_clk", "pll_arm_main_bypass", base + 0x60, 13);
- clks[IMX7D_PLL_DRAM_MAIN_CLK] = imx_clk_gate("pll_dram_main_clk", "pll_dram_main_bypass", base + 0x70, 13);
+ clks[IMX7D_PLL_DRAM_MAIN_CLK] = imx_clk_gate("pll_dram_main_clk", "pll_dram_test_div", base + 0x70, 13);
clks[IMX7D_PLL_SYS_MAIN_CLK] = imx_clk_gate("pll_sys_main_clk", "pll_sys_main_bypass", base + 0xb0, 13);
- clks[IMX7D_PLL_AUDIO_MAIN_CLK] = imx_clk_gate("pll_audio_main_clk", "pll_audio_main_bypass", base + 0xf0, 13);
- clks[IMX7D_PLL_VIDEO_MAIN_CLK] = imx_clk_gate("pll_video_main_clk", "pll_video_main_bypass", base + 0x130, 13);
+ clks[IMX7D_PLL_AUDIO_MAIN_CLK] = imx_clk_gate("pll_audio_main_clk", "pll_audio_test_div", base + 0xf0, 13);
+ clks[IMX7D_PLL_VIDEO_MAIN_CLK] = imx_clk_gate("pll_video_main_clk", "pll_video_test_div", base + 0x130, 13);
- clks[IMX7D_PLL_AUDIO_TEST_DIV] = clk_register_divider_table(NULL, "pll_audio_test_div", "pll_audio_main_clk",
+ clks[IMX7D_PLL_DRAM_TEST_DIV] = clk_register_divider_table(NULL, "pll_dram_test_div", "pll_dram_main_bypass",
+ CLK_SET_RATE_PARENT | CLK_SET_RATE_GATE, base + 0x70, 21, 2, 0, test_div_table, &imx_ccm_lock);
+ clks[IMX7D_PLL_AUDIO_TEST_DIV] = clk_register_divider_table(NULL, "pll_audio_test_div", "pll_audio_main_bypass",
CLK_SET_RATE_PARENT | CLK_SET_RATE_GATE, base + 0xf0, 19, 2, 0, test_div_table, &imx_ccm_lock);
- clks[IMX7D_PLL_AUDIO_POST_DIV] = clk_register_divider_table(NULL, "pll_audio_post_div", "pll_audio_test_div",
+ clks[IMX7D_PLL_AUDIO_POST_DIV] = clk_register_divider_table(NULL, "pll_audio_post_div", "pll_audio_main_clk",
CLK_SET_RATE_PARENT | CLK_SET_RATE_GATE, base + 0xf0, 22, 2, 0, post_div_table, &imx_ccm_lock);
+ clks[IMX7D_PLL_VIDEO_TEST_DIV] = clk_register_divider_table(NULL, "pll_video_test_div", "pll_video_main_bypass",
+ CLK_SET_RATE_PARENT | CLK_SET_RATE_GATE, base + 0x130, 19, 2, 0, test_div_table, &imx_ccm_lock);
+ clks[IMX7D_PLL_VIDEO_POST_DIV] = clk_register_divider_table(NULL, "pll_video_post_div", "pll_video_main_clk",
+ CLK_SET_RATE_PARENT | CLK_SET_RATE_GATE, base + 0x130, 22, 2, 0, post_div_table, &imx_ccm_lock);
clks[IMX7D_PLL_SYS_PFD0_392M_CLK] = imx_clk_pfd("pll_sys_pfd0_392m_clk", "pll_sys_main_clk", base + 0xc0, 0);
clks[IMX7D_PLL_SYS_PFD1_332M_CLK] = imx_clk_pfd("pll_sys_pfd1_332m_clk", "pll_sys_main_clk", base + 0xc0, 1);
@@ -510,7 +509,6 @@ static void __init imx7d_clocks_init(struct device_node *ccm_node)
clks[IMX7D_ARM_A7_ROOT_SRC] = imx_clk_mux2("arm_a7_src", base + 0x8000, 24, 3, arm_a7_sel, ARRAY_SIZE(arm_a7_sel));
clks[IMX7D_ARM_M4_ROOT_SRC] = imx_clk_mux2("arm_m4_src", base + 0x8080, 24, 3, arm_m4_sel, ARRAY_SIZE(arm_m4_sel));
- clks[IMX7D_ARM_M0_ROOT_SRC] = imx_clk_mux2("arm_m0_src", base + 0x8100, 24, 3, arm_m0_sel, ARRAY_SIZE(arm_m0_sel));
clks[IMX7D_MAIN_AXI_ROOT_SRC] = imx_clk_mux2("axi_src", base + 0x8800, 24, 3, axi_sel, ARRAY_SIZE(axi_sel));
clks[IMX7D_DISP_AXI_ROOT_SRC] = imx_clk_mux2("disp_axi_src", base + 0x8880, 24, 3, disp_axi_sel, ARRAY_SIZE(disp_axi_sel));
clks[IMX7D_ENET_AXI_ROOT_SRC] = imx_clk_mux2("enet_axi_src", base + 0x8900, 24, 3, enet_axi_sel, ARRAY_SIZE(enet_axi_sel));
@@ -524,7 +522,7 @@ static void __init imx7d_clocks_init(struct device_node *ccm_node)
clks[IMX7D_PCIE_CTRL_ROOT_SRC] = imx_clk_mux2("pcie_ctrl_src", base + 0xa180, 24, 3, pcie_ctrl_sel, ARRAY_SIZE(pcie_ctrl_sel));
clks[IMX7D_PCIE_PHY_ROOT_SRC] = imx_clk_mux2("pcie_phy_src", base + 0xa200, 24, 3, pcie_phy_sel, ARRAY_SIZE(pcie_phy_sel));
clks[IMX7D_EPDC_PIXEL_ROOT_SRC] = imx_clk_mux2("epdc_pixel_src", base + 0xa280, 24, 3, epdc_pixel_sel, ARRAY_SIZE(epdc_pixel_sel));
- clks[IMX7D_LCDIF_PIXEL_ROOT_SRC] = imx_clk_mux2("lcdif_pixel_src", base + 0xa300, 24, 3, lcdif_pixel_sel, ARRAY_SIZE(lcdif_pixel_sel));
+ clks[IMX7D_LCDIF_PIXEL_ROOT_SRC] = imx_clk_mux_flags("lcdif_pixel_src", base + 0xa300, 24, 3, lcdif_pixel_sel, ARRAY_SIZE(lcdif_pixel_sel), CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE);
clks[IMX7D_MIPI_DSI_ROOT_SRC] = imx_clk_mux2("mipi_dsi_src", base + 0xa380, 24, 3, mipi_dsi_sel, ARRAY_SIZE(mipi_dsi_sel));
clks[IMX7D_MIPI_CSI_ROOT_SRC] = imx_clk_mux2("mipi_csi_src", base + 0xa400, 24, 3, mipi_csi_sel, ARRAY_SIZE(mipi_csi_sel));
clks[IMX7D_MIPI_DPHY_ROOT_SRC] = imx_clk_mux2("mipi_dphy_src", base + 0xa480, 24, 3, mipi_dphy_sel, ARRAY_SIZE(mipi_dphy_sel));
@@ -582,7 +580,6 @@ static void __init imx7d_clocks_init(struct device_node *ccm_node)
clks[IMX7D_ARM_A7_ROOT_CG] = imx_clk_gate3("arm_a7_cg", "arm_a7_src", base + 0x8000, 28);
clks[IMX7D_ARM_M4_ROOT_CG] = imx_clk_gate3("arm_m4_cg", "arm_m4_src", base + 0x8080, 28);
- clks[IMX7D_ARM_M0_ROOT_CG] = imx_clk_gate3("arm_m0_cg", "arm_m0_src", base + 0x8100, 28);
clks[IMX7D_MAIN_AXI_ROOT_CG] = imx_clk_gate3("axi_cg", "axi_src", base + 0x8800, 28);
clks[IMX7D_DISP_AXI_ROOT_CG] = imx_clk_gate3("disp_axi_cg", "disp_axi_src", base + 0x8880, 28);
clks[IMX7D_ENET_AXI_ROOT_CG] = imx_clk_gate3("enet_axi_cg", "enet_axi_src", base + 0x8900, 28);
@@ -719,14 +716,13 @@ static void __init imx7d_clocks_init(struct device_node *ccm_node)
clks[IMX7D_CLKO1_ROOT_PRE_DIV] = imx_clk_divider2("clko1_pre_div", "clko1_cg", base + 0xbd80, 16, 3);
clks[IMX7D_CLKO2_ROOT_PRE_DIV] = imx_clk_divider2("clko2_pre_div", "clko2_cg", base + 0xbe00, 16, 3);
- clks[IMX7D_ARM_A7_ROOT_DIV] = imx_clk_divider2("arm_a7_div", "arm_a7_cg", base + 0x8000, 0, 3);
+ clks[IMX7D_ARM_A7_ROOT_DIV] = imx_clk_divider_flags("arm_a7_div", "arm_a7_cg", base + 0x8000, 0, 3, CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE);
clks[IMX7D_ARM_M4_ROOT_DIV] = imx_clk_divider2("arm_m4_div", "arm_m4_cg", base + 0x8080, 0, 3);
- clks[IMX7D_ARM_M0_ROOT_DIV] = imx_clk_divider2("arm_m0_div", "arm_m0_cg", base + 0x8100, 0, 3);
- clks[IMX7D_MAIN_AXI_ROOT_DIV] = imx_clk_divider2("axi_post_div", "axi_pre_div", base + 0x8800, 0, 6);
+ clks[IMX7D_MAIN_AXI_ROOT_DIV] = imx_clk_divider_flags("axi_post_div", "axi_pre_div", base + 0x8800, 0, 6, CLK_OPS_PARENT_ENABLE);
clks[IMX7D_DISP_AXI_ROOT_DIV] = imx_clk_divider2("disp_axi_post_div", "disp_axi_pre_div", base + 0x8880, 0, 6);
clks[IMX7D_ENET_AXI_ROOT_DIV] = imx_clk_divider2("enet_axi_post_div", "enet_axi_pre_div", base + 0x8900, 0, 6);
clks[IMX7D_NAND_USDHC_BUS_ROOT_CLK] = imx_clk_divider2("nand_usdhc_root_clk", "nand_usdhc_pre_div", base + 0x8980, 0, 6);
- clks[IMX7D_AHB_CHANNEL_ROOT_DIV] = imx_clk_divider2("ahb_root_clk", "ahb_pre_div", base + 0x9000, 0, 6);
+ clks[IMX7D_AHB_CHANNEL_ROOT_CLK] = imx_clk_divider_flags("ahb_root_clk", "ahb_pre_div", base + 0x9000, 0, 6, CLK_OPS_PARENT_ENABLE);
clks[IMX7D_IPG_ROOT_CLK] = imx_clk_divider2("ipg_root_clk", "ahb_root_clk", base + 0x9080, 0, 2);
clks[IMX7D_DRAM_ROOT_DIV] = imx_clk_divider2("dram_post_div", "dram_cg", base + 0x9880, 0, 3);
clks[IMX7D_DRAM_PHYM_ALT_ROOT_DIV] = imx_clk_divider2("dram_phym_alt_post_div", "dram_phym_alt_pre_div", base + 0xa000, 0, 3);
@@ -738,7 +734,7 @@ static void __init imx7d_clocks_init(struct device_node *ccm_node)
clks[IMX7D_LCDIF_PIXEL_ROOT_DIV] = imx_clk_divider2("lcdif_pixel_post_div", "lcdif_pixel_pre_div", base + 0xa300, 0, 6);
clks[IMX7D_MIPI_DSI_ROOT_DIV] = imx_clk_divider2("mipi_dsi_post_div", "mipi_dsi_pre_div", base + 0xa380, 0, 6);
clks[IMX7D_MIPI_CSI_ROOT_DIV] = imx_clk_divider2("mipi_csi_post_div", "mipi_csi_pre_div", base + 0xa400, 0, 6);
- clks[IMX7D_MIPI_DPHY_ROOT_DIV] = imx_clk_divider2("mipi_dphy_post_div", "mipi_csi_dphy_div", base + 0xa480, 0, 6);
+ clks[IMX7D_MIPI_DPHY_ROOT_DIV] = imx_clk_divider2("mipi_dphy_post_div", "mipi_dphy_pre_div", base + 0xa480, 0, 6);
clks[IMX7D_SAI1_ROOT_DIV] = imx_clk_divider2("sai1_post_div", "sai1_pre_div", base + 0xa500, 0, 6);
clks[IMX7D_SAI2_ROOT_DIV] = imx_clk_divider2("sai2_post_div", "sai2_pre_div", base + 0xa580, 0, 6);
clks[IMX7D_SAI3_ROOT_DIV] = imx_clk_divider2("sai3_post_div", "sai3_pre_div", base + 0xa600, 0, 6);
@@ -791,20 +787,22 @@ static void __init imx7d_clocks_init(struct device_node *ccm_node)
clks[IMX7D_CLKO1_ROOT_DIV] = imx_clk_divider2("clko1_post_div", "clko1_pre_div", base + 0xbd80, 0, 6);
clks[IMX7D_CLKO2_ROOT_DIV] = imx_clk_divider2("clko2_post_div", "clko2_pre_div", base + 0xbe00, 0, 6);
- clks[IMX7D_ARM_A7_ROOT_CLK] = imx_clk_gate4("arm_a7_root_clk", "arm_a7_div", base + 0x4000, 0);
+ clks[IMX7D_ARM_A7_ROOT_CLK] = imx_clk_gate2_flags("arm_a7_root_clk", "arm_a7_div", base + 0x4000, 0, CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE);
clks[IMX7D_ARM_M4_ROOT_CLK] = imx_clk_gate4("arm_m4_root_clk", "arm_m4_div", base + 0x4010, 0);
- clks[IMX7D_ARM_M0_ROOT_CLK] = imx_clk_gate4("arm_m0_root_clk", "arm_m0_div", base + 0x4020, 0);
clks[IMX7D_MAIN_AXI_ROOT_CLK] = imx_clk_gate4("main_axi_root_clk", "axi_post_div", base + 0x4040, 0);
clks[IMX7D_DISP_AXI_ROOT_CLK] = imx_clk_gate4("disp_axi_root_clk", "disp_axi_post_div", base + 0x4050, 0);
clks[IMX7D_ENET_AXI_ROOT_CLK] = imx_clk_gate4("enet_axi_root_clk", "enet_axi_post_div", base + 0x4060, 0);
clks[IMX7D_OCRAM_CLK] = imx_clk_gate4("ocram_clk", "main_axi_root_clk", base + 0x4110, 0);
clks[IMX7D_OCRAM_S_CLK] = imx_clk_gate4("ocram_s_clk", "ahb_root_clk", base + 0x4120, 0);
+ clks[IMX7D_CAAM_CLK] = imx_clk_gate4("caam_clk", "ipg_root_clk", base + 0x4240, 0);
clks[IMX7D_DRAM_ROOT_CLK] = imx_clk_gate4("dram_root_clk", "dram_post_div", base + 0x4130, 0);
clks[IMX7D_DRAM_PHYM_ROOT_CLK] = imx_clk_gate4("dram_phym_root_clk", "dram_phym_cg", base + 0x4130, 0);
clks[IMX7D_DRAM_PHYM_ALT_ROOT_CLK] = imx_clk_gate4("dram_phym_alt_root_clk", "dram_phym_alt_post_div", base + 0x4130, 0);
clks[IMX7D_DRAM_ALT_ROOT_CLK] = imx_clk_gate4("dram_alt_root_clk", "dram_alt_post_div", base + 0x4130, 0);
clks[IMX7D_OCOTP_CLK] = imx_clk_gate4("ocotp_clk", "ipg_root_clk", base + 0x4230, 0);
- clks[IMX7D_USB_HSIC_ROOT_CLK] = imx_clk_gate4("usb_hsic_root_clk", "usb_hsic_post_div", base + 0x4420, 0);
+ clks[IMX7D_MU_ROOT_CLK] = imx_clk_gate2("mu_root_clk", "ipg_root_clk", base + 0x4270, 0);
+ clks[IMX7D_SEMA4_HS_ROOT_CLK] = imx_clk_gate4("sema4_hs_root_clk", "ipg_root_clk", base + 0x4280, 0);
+ clks[IMX7D_USB_HSIC_ROOT_CLK] = imx_clk_gate4("usb_hsic_root_clk", "usb_hsic_post_div", base + 0x4690, 0);
clks[IMX7D_SDMA_CORE_CLK] = imx_clk_gate4("sdma_root_clk", "ahb_root_clk", base + 0x4480, 0);
clks[IMX7D_PCIE_CTRL_ROOT_CLK] = imx_clk_gate4("pcie_ctrl_root_clk", "pcie_ctrl_post_div", base + 0x4600, 0);
clks[IMX7D_PCIE_PHY_ROOT_CLK] = imx_clk_gate4("pcie_phy_root_clk", "pcie_phy_post_div", base + 0x4600, 0);
@@ -813,6 +811,10 @@ static void __init imx7d_clocks_init(struct device_node *ccm_node)
clks[IMX7D_MIPI_DSI_ROOT_CLK] = imx_clk_gate4("mipi_dsi_root_clk", "mipi_dsi_post_div", base + 0x4650, 0);
clks[IMX7D_MIPI_CSI_ROOT_CLK] = imx_clk_gate4("mipi_csi_root_clk", "mipi_csi_post_div", base + 0x4640, 0);
clks[IMX7D_MIPI_DPHY_ROOT_CLK] = imx_clk_gate4("mipi_dphy_root_clk", "mipi_dphy_post_div", base + 0x4660, 0);
+ clks[IMX7D_ENET1_IPG_ROOT_CLK] = imx_clk_gate2_shared2("enet1_ipg_root_clk", "enet_axi_post_div", base + 0x4700, 0, &share_count_enet1);
+ clks[IMX7D_ENET1_TIME_ROOT_CLK] = imx_clk_gate2_shared2("enet1_time_root_clk", "enet1_time_post_div", base + 0x4700, 0, &share_count_enet1);
+ clks[IMX7D_ENET2_IPG_ROOT_CLK] = imx_clk_gate2_shared2("enet2_ipg_root_clk", "enet_axi_post_div", base + 0x4710, 0, &share_count_enet2);
+ clks[IMX7D_ENET2_TIME_ROOT_CLK] = imx_clk_gate2_shared2("enet2_time_root_clk", "enet2_time_post_div", base + 0x4710, 0, &share_count_enet2);
clks[IMX7D_SAI1_ROOT_CLK] = imx_clk_gate2_shared2("sai1_root_clk", "sai1_post_div", base + 0x48c0, 0, &share_count_sai1);
clks[IMX7D_SAI1_IPG_CLK] = imx_clk_gate2_shared2("sai1_ipg_clk", "ipg_root_clk", base + 0x48c0, 0, &share_count_sai1);
clks[IMX7D_SAI2_ROOT_CLK] = imx_clk_gate2_shared2("sai2_root_clk", "sai2_post_div", base + 0x48d0, 0, &share_count_sai2);
@@ -820,11 +822,6 @@ static void __init imx7d_clocks_init(struct device_node *ccm_node)
clks[IMX7D_SAI3_ROOT_CLK] = imx_clk_gate2_shared2("sai3_root_clk", "sai3_post_div", base + 0x48e0, 0, &share_count_sai3);
clks[IMX7D_SAI3_IPG_CLK] = imx_clk_gate2_shared2("sai3_ipg_clk", "ipg_root_clk", base + 0x48e0, 0, &share_count_sai3);
clks[IMX7D_SPDIF_ROOT_CLK] = imx_clk_gate4("spdif_root_clk", "spdif_post_div", base + 0x44d0, 0);
- clks[IMX7D_ENET1_REF_ROOT_CLK] = imx_clk_gate4("enet1_ref_root_clk", "enet1_ref_post_div", base + 0x44e0, 0);
- clks[IMX7D_ENET1_TIME_ROOT_CLK] = imx_clk_gate4("enet1_time_root_clk", "enet1_time_post_div", base + 0x44f0, 0);
- clks[IMX7D_ENET2_REF_ROOT_CLK] = imx_clk_gate4("enet2_ref_root_clk", "enet2_ref_post_div", base + 0x4500, 0);
- clks[IMX7D_ENET2_TIME_ROOT_CLK] = imx_clk_gate4("enet2_time_root_clk", "enet2_time_post_div", base + 0x4510, 0);
- clks[IMX7D_ENET_PHY_REF_ROOT_CLK] = imx_clk_gate4("enet_phy_ref_root_clk", "enet_phy_ref_post_div", base + 0x4520, 0);
clks[IMX7D_EIM_ROOT_CLK] = imx_clk_gate4("eim_root_clk", "eim_post_div", base + 0x4160, 0);
clks[IMX7D_NAND_RAWNAND_CLK] = imx_clk_gate2_shared2("nand_rawnand_clk", "nand_root_clk", base + 0x4140, 0, &share_count_nand);
clks[IMX7D_NAND_USDHC_BUS_RAWNAND_CLK] = imx_clk_gate2_shared2("nand_usdhc_rawnand_clk", "nand_usdhc_root_clk", base + 0x4140, 0, &share_count_nand);
@@ -869,7 +866,12 @@ static void __init imx7d_clocks_init(struct device_node *ccm_node)
clks[IMX7D_CSI_MCLK_ROOT_CLK] = imx_clk_gate4("csi_mclk_root_clk", "csi_mclk_post_div", base + 0x4490, 0);
clks[IMX7D_AUDIO_MCLK_ROOT_CLK] = imx_clk_gate4("audio_mclk_root_clk", "audio_mclk_post_div", base + 0x4790, 0);
clks[IMX7D_WRCLK_ROOT_CLK] = imx_clk_gate4("wrclk_root_clk", "wrclk_post_div", base + 0x47a0, 0);
+ clks[IMX7D_USB_CTRL_CLK] = imx_clk_gate4("usb_ctrl_clk", "ahb_root_clk", base + 0x4680, 0);
+ clks[IMX7D_USB_PHY1_CLK] = imx_clk_gate4("usb_phy1_clk", "pll_usb1_main_clk", base + 0x46a0, 0);
+ clks[IMX7D_USB_PHY2_CLK] = imx_clk_gate4("usb_phy2_clk", "pll_usb_main_clk", base + 0x46b0, 0);
clks[IMX7D_ADC_ROOT_CLK] = imx_clk_gate4("adc_root_clk", "ipg_root_clk", base + 0x4200, 0);
+ clks[IMX7D_PXP_IPG_CLK] = imx_clk_gate2_shared2("pxp_ipg_clk", "ipg_root_clk", base + 0x44c0, 0, &share_count_pxp);
+ clks[IMX7D_PXP_AXI_CLK] = imx_clk_gate2_shared2("pxp_axi_clk", "main_axi_root_clk", base + 0x44c0, 0, &share_count_pxp);
clks[IMX7D_GPT_3M_CLK] = imx_clk_fixed_factor("gpt_3m", "osc", 1, 8);
@@ -888,13 +890,43 @@ static void __init imx7d_clocks_init(struct device_node *ccm_node)
for (i = 0; i < ARRAY_SIZE(clks_init_on); i++)
clk_prepare_enable(clks[clks_init_on[i]]);
+ if (imx_src_is_m4_enabled()) {
+ imx_clk_set_parent(clks[IMX7D_ARM_M4_ROOT_SRC], clks[IMX7D_PLL_SYS_MAIN_240M_CLK]);
+ imx_clk_prepare_enable(clks[IMX7D_ARM_M4_ROOT_CLK]);
+ }
+
+ imx_clk_set_parent(clks[IMX7D_PLL_ARM_MAIN_BYPASS], clks[IMX7D_PLL_ARM_MAIN]);
+ imx_clk_set_parent(clks[IMX7D_PLL_DRAM_MAIN_BYPASS], clks[IMX7D_PLL_DRAM_MAIN]);
+ imx_clk_set_parent(clks[IMX7D_PLL_SYS_MAIN_BYPASS], clks[IMX7D_PLL_SYS_MAIN]);
+ imx_clk_set_parent(clks[IMX7D_PLL_ENET_MAIN_BYPASS], clks[IMX7D_PLL_ENET_MAIN]);
+ imx_clk_set_parent(clks[IMX7D_PLL_AUDIO_MAIN_BYPASS], clks[IMX7D_PLL_AUDIO_MAIN]);
+ imx_clk_set_parent(clks[IMX7D_PLL_VIDEO_MAIN_BYPASS], clks[IMX7D_PLL_VIDEO_MAIN]);
+
/* use old gpt clk setting, gpt1 root clk must be twice as gpt counter freq */
- clk_set_parent(clks[IMX7D_GPT1_ROOT_SRC], clks[IMX7D_OSC_24M_CLK]);
+ imx_clk_set_parent(clks[IMX7D_GPT1_ROOT_SRC], clks[IMX7D_OSC_24M_CLK]);
- /* set uart module clock's parent clock source that must be great then 80MHz */
- clk_set_parent(clks[IMX7D_UART1_ROOT_SRC], clks[IMX7D_OSC_24M_CLK]);
+ /* Set clock rate for USBPHY, the USB_PLL at CCM is from USBOTG2 */
+ clks[IMX7D_USB1_MAIN_480M_CLK] = imx_clk_fixed_factor("pll_usb1_main_clk", "osc", 20, 1);
+ clks[IMX7D_USB_MAIN_480M_CLK] = imx_clk_fixed_factor("pll_usb_main_clk", "osc", 20, 1);
- imx_register_uart_clocks(uart_clks);
+ /* set parent of EPDC pixel clock */
+ imx_clk_set_parent(clks[IMX7D_EPDC_PIXEL_ROOT_SRC], clks[IMX7D_PLL_SYS_MAIN_CLK]);
+ /* set lcdif pixel root clock source to get the required 33Mhz clock */
+ imx_clk_set_parent(clks[IMX7D_LCDIF_PIXEL_ROOT_SRC], clks[IMX7D_PLL_VIDEO_POST_DIV]);
+
+ imx_clk_set_parent(clks[IMX7D_MIPI_CSI_ROOT_SRC], clks[IMX7D_PLL_SYS_PFD3_CLK]);
+
+ /* set parent of SIM1 root clock */
+ imx_clk_set_parent(clks[IMX7D_SIM1_ROOT_SRC], clks[IMX7D_PLL_SYS_MAIN_120M_CLK]);
+
+ imx_clk_set_parent(clks[IMX7D_UART3_ROOT_SRC], clks[IMX7D_PLL_SYS_MAIN_240M_CLK]);
+ imx_clk_set_rate(clks[IMX7D_UART3_ROOT_DIV], 80000000);
+ imx_clk_set_parent(clks[IMX7D_UART5_ROOT_SRC], clks[IMX7D_PLL_SYS_MAIN_240M_CLK]);
+ imx_clk_set_rate(clks[IMX7D_UART5_ROOT_DIV], 80000000);
+ imx_clk_set_parent(clks[IMX7D_UART6_ROOT_SRC], clks[IMX7D_PLL_SYS_MAIN_240M_CLK]);
+ imx_clk_set_rate(clks[IMX7D_UART6_ROOT_DIV], 80000000);
+
+ imx_register_uart_clocks(uart_clks);
}
CLK_OF_DECLARE(imx7d, "fsl,imx7d-ccm", imx7d_clocks_init);
diff --git a/drivers/clk/imx/clk-imx7ulp.c b/drivers/clk/imx/clk-imx7ulp.c
new file mode 100644
index 000000000000..67b5d1ae01f8
--- /dev/null
+++ b/drivers/clk/imx/clk-imx7ulp.c
@@ -0,0 +1,322 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017-2018 NXP.
+ *
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <dt-bindings/clock/imx7ulp-clock.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+
+#include "clk.h"
+
+static const char *pll_pre_sels[] = { "sosc", "firc", };
+static const char *spll_pfd_sels[] = { "spll_pfd0", "spll_pfd1", "spll_pfd2", "spll_pfd3", };
+static const char *spll_sels[] = { "spll", "spll_pfd_sel", };
+static const char *apll_pfd_sels[] = { "apll_pfd0", "apll_pfd1", "apll_pfd2", "apll_pfd3", };
+static const char *apll_sels[] = { "apll", "apll_pfd_sel", };
+static const char *sys_sels[] = { "dummy", "sosc", "sirc", "firc", "rosc", "apll_sel", "spll_sel", "upll", };
+static const char *arm_sels[] = { "core_div", "dummy", "dummy", "hsrun_core", };
+static const char *ddr_sels[] = { "apll_pfd_sel", "upll", };
+static const char *nic_sels[] = { "firc", "ddr_div", };
+static const char *periph_plat_sels[] = { "dummy", "nic1_bus", "nic1_div", "ddr_div", "apll_pfd2", "apll_pfd1", "apll_pfd0", "upll", };
+static const char *periph_bus_sels[] = { "dummy", "sosc_bus_clk", "dummy", "firc_bus_clk", "rosc", "nic1_bus", "nic1_div", "spll_bus_clk", };
+static struct clk *clks[IMX7ULP_CLK_END];
+static struct clk_onecell_data clk_data;
+
+static const char *cm4_pll_pre_sels[] = { "cm4_sosc", "cm4_firc", };
+static const char *cm4_spll_pfd_sels[] = { "cm4_spll_pfd0", "cm4_spll_pfd1", "cm4_spll_pfd2", "cm4_spll_pfd3", };
+static const char *cm4_spll_sels[] = { "cm4_spll_vco", "cm4_spll_pfd_sel", };
+static const char *cm4_apll_pfd_sels[] = { "cm4_apll_pfd0", "cm4_apll_pfd1", "cm4_apll_pfd2", "cm4_apll_pfd3", };
+static const char *cm4_apll_sels[] = { "cm4_apll_vco_post_div2", "cm4_apll_pfd_sel", };
+static const char *cm4_sys_sels[] = { "cm4_dummy", "cm4_sosc", "cm4_sirc", "cm4_firc", "cm4_rosc", "cm4_apll_sel", "cm4_spll_sel", "cm4_dummy", };
+static const char *cm4_periph_bus_sels[] = { "cm4_dummy", "cm4_sosc", "cm4_sirc", "cm4_firc", "cm4_rosc", "cm4_bus_div", "cm4_spll_pfd2", "cm4_apll_pfd0_pre_div", };
+static const char *scg0_clkout_sels[] = { "dummy", "cm4_sosc", "cm4_sirc", "cm4_firc", "cm4_rosc", "cm4_apll_sel", "cm4_spll_sel", "dummy"};
+
+static struct clk *clks_cm4[IMX7ULP_CM4_CLK_END];
+static struct clk_onecell_data clk_data_cm4;
+
+
+static int const clks_init_on[] __initconst = {
+ IMX7ULP_CLK_BUS_DIV,
+ IMX7ULP_CLK_ARM,
+ IMX7ULP_CLK_NIC0_DIV,
+ IMX7ULP_CLK_NIC1_DIV,
+ IMX7ULP_CLK_NIC1_BUS_DIV,
+ IMX7ULP_CLK_MMDC,
+};
+
+/* used by sosc/sirc/firc/ddr/spll/apll dividers */
+static const struct clk_div_table ulp_div_table[] = {
+ { .val = 1, .div = 1, },
+ { .val = 2, .div = 2, },
+ { .val = 3, .div = 4, },
+ { .val = 4, .div = 8, },
+ { .val = 5, .div = 16, },
+ { .val = 6, .div = 32, },
+ { .val = 7, .div = 64, },
+ { }
+};
+
+static void __init imx7ulp_clocks_init(struct device_node *scg_node)
+{
+ struct device_node *np;
+ void __iomem *base;
+ void __iomem *smc_base;
+ int i;
+
+ clks[IMX7ULP_CLK_DUMMY] = imx_clk_fixed("dummy", 0);
+
+ clks[IMX7ULP_CLK_ROSC] = of_clk_get_by_name(scg_node, "rosc");
+ clks[IMX7ULP_CLK_SOSC] = of_clk_get_by_name(scg_node, "sosc");
+ clks[IMX7ULP_CLK_SIRC] = of_clk_get_by_name(scg_node, "sirc");
+ clks[IMX7ULP_CLK_FIRC] = of_clk_get_by_name(scg_node, "firc");
+ clks[IMX7ULP_CLK_MIPI_PLL] = of_clk_get_by_name(scg_node, "mpll");
+ clks[IMX7ULP_CLK_UPLL] = of_clk_get_by_name(scg_node, "upll");
+
+ np = of_find_compatible_node(NULL, NULL, "fsl,imx7ulp-smc1");
+ smc_base = of_iomap(np, 0);
+ WARN_ON(!smc_base);
+
+ np = scg_node;
+ base = of_iomap(np, 0);
+ WARN_ON(!base);
+
+ clks[IMX7ULP_CLK_SPLL_PRE_SEL] = imx_clk_mux("spll_pre_sel", base + 0x608, 0, 1, pll_pre_sels, ARRAY_SIZE(pll_pre_sels));
+ clks[IMX7ULP_CLK_APLL_PRE_SEL] = imx_clk_mux("apll_pre_sel", base + 0x508, 0, 1, pll_pre_sels, ARRAY_SIZE(pll_pre_sels));
+ /* name parent_name reg shift width */
+ clks[IMX7ULP_CLK_SPLL_PRE_DIV] = imx_clk_divider("spll_pre_div", "spll_pre_sel", base + 0x608, 8, 3);
+ clks[IMX7ULP_CLK_APLL_PRE_DIV] = imx_clk_divider("apll_pre_div", "apll_pre_sel", base + 0x508, 8, 3);
+ /* name parent_name base*/
+ clks[IMX7ULP_CLK_SPLL] = imx_clk_pllv4("spll", "spll_pre_div", base + 0x600);
+ clks[IMX7ULP_CLK_APLL] = imx_clk_pllv4("apll", "apll_pre_div", base + 0x500);
+
+ /* SPLL PFDs */
+ clks[IMX7ULP_CLK_SPLL_PFD0] = imx_clk_pfdv2("spll_pfd0", "spll", base + 0x60C, 0);
+ clks[IMX7ULP_CLK_SPLL_PFD1] = imx_clk_pfdv2("spll_pfd1", "spll", base + 0x60C, 1);
+ clks[IMX7ULP_CLK_SPLL_PFD2] = imx_clk_pfdv2("spll_pfd2", "spll", base + 0x60C, 2);
+ clks[IMX7ULP_CLK_SPLL_PFD3] = imx_clk_pfdv2("spll_pfd3", "spll", base + 0x60C, 3);
+ /* APLL PFDs */
+ clks[IMX7ULP_CLK_APLL_PFD0] = imx_clk_pfdv2("apll_pfd0", "apll", base + 0x50C, 0);
+ clks[IMX7ULP_CLK_APLL_PFD1] = imx_clk_pfdv2("apll_pfd1", "apll", base + 0x50C, 1);
+ clks[IMX7ULP_CLK_APLL_PFD2] = imx_clk_pfdv2("apll_pfd2", "apll", base + 0x50C, 2);
+ clks[IMX7ULP_CLK_APLL_PFD3] = imx_clk_pfdv2("apll_pfd3", "apll", base + 0x50C, 3);
+
+ clks[IMX7ULP_CLK_SPLL_PFD_SEL] = imx_clk_mux("spll_pfd_sel", base + 0x608, 14, 2, spll_pfd_sels, ARRAY_SIZE(spll_pfd_sels));
+ clks[IMX7ULP_CLK_APLL_PFD_SEL] = imx_clk_mux("apll_pfd_sel", base + 0x508, 14, 2, apll_pfd_sels, ARRAY_SIZE(apll_pfd_sels));
+
+ clks[IMX7ULP_CLK_SPLL_SEL] = imx_clk_mux("spll_sel", base + 0x608, 1, 1, spll_sels, ARRAY_SIZE(spll_sels));
+ clks[IMX7ULP_CLK_APLL_SEL] = imx_clk_mux("apll_sel", base + 0x508, 1, 1, apll_sels, ARRAY_SIZE(apll_sels));
+
+ clks[IMX7ULP_CLK_SPLL_BUS_CLK] = clk_register_divider_table(NULL, "spll_bus_clk", "spll_sel", CLK_SET_RATE_GATE, base + 0x604, 8, 3,
+ CLK_DIVIDER_READ_ONLY | CLK_DIVIDER_ZERO_GATE, ulp_div_table, &imx_ccm_lock);
+
+ /* sys/ddr/nic select different clock source requires that clock to be enabled first */
+ clks[IMX7ULP_CLK_SYS_SEL] = imx_clk_mux2("sys_sel", base + 0x14, 24, 4, sys_sels, ARRAY_SIZE(sys_sels));
+ clks[IMX7ULP_CLK_HSRUN_SYS_SEL] = imx_clk_mux2("hsrun_sys_sel", base + 0x1c, 24, 4, sys_sels, ARRAY_SIZE(sys_sels));
+ clks[IMX7ULP_CLK_DDR_SEL] = imx_clk_mux2("ddr_sel", base + 0x30, 24, 1, ddr_sels, ARRAY_SIZE(ddr_sels));
+ clks[IMX7ULP_CLK_NIC_SEL] = imx_clk_mux2("nic_sel", base + 0x40, 28, 1, nic_sels, ARRAY_SIZE(nic_sels));
+
+ clks[IMX7ULP_CLK_CORE_DIV] = imx_clk_divider_flags("core_div", "sys_sel", base + 0x14, 16, 4, CLK_SET_RATE_PARENT);
+ clks[IMX7ULP_CLK_HSRUN_CORE] = imx_clk_divider_flags("hsrun_core", "hsrun_sys_sel", base + 0x1c, 16, 4, CLK_SET_RATE_PARENT);
+
+ clks[IMX7ULP_CLK_PLAT_DIV] = imx_clk_divider("plat_div", "core_div", base + 0x14, 12, 4);
+ /* Fake mux */
+ clks[IMX7ULP_CLK_ARM] = imx_clk_mux_glitchless("arm", smc_base + 0x10, 8, 2, arm_sels, ARRAY_SIZE(arm_sels));
+
+ clks[IMX7ULP_CLK_DDR_DIV] = clk_register_divider_table(NULL, "ddr_div", "ddr_sel", CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, base + 0x30, 0, 3,
+ CLK_DIVIDER_ZERO_GATE, ulp_div_table, &imx_ccm_lock);
+
+ clks[IMX7ULP_CLK_NIC0_DIV] = imx_clk_divider_flags("nic0_div", "nic_sel", base + 0x40, 24, 4, CLK_SET_RATE_PARENT);
+ clks[IMX7ULP_CLK_NIC1_DIV] = imx_clk_divider_flags("nic1_div", "nic0_div", base + 0x40, 16, 4, CLK_SET_RATE_PARENT);
+ clks[IMX7ULP_CLK_NIC1_BUS_DIV] = imx_clk_divider_flags("nic1_bus", "nic0_div", base + 0x40, 4, 4, CLK_SET_RATE_PARENT);
+
+ clks[IMX7ULP_CLK_GPU_DIV] = imx_clk_divider("gpu_div", "nic0_div", base + 0x40, 20, 4);
+
+ clks[IMX7ULP_CLK_SOSC_BUS_CLK] = clk_register_divider_table(NULL, "sosc_bus_clk", "sosc", 0, base + 0x104, 8, 3,
+ CLK_DIVIDER_READ_ONLY | CLK_DIVIDER_ZERO_GATE, ulp_div_table, &imx_ccm_lock);
+ clks[IMX7ULP_CLK_FIRC_BUS_CLK] = clk_register_divider_table(NULL, "firc_bus_clk", "firc", 0, base + 0x304, 8, 3,
+ CLK_DIVIDER_READ_ONLY | CLK_DIVIDER_ZERO_GATE, ulp_div_table, &imx_ccm_lock);
+
+ /* PCC2 */
+ np = of_find_compatible_node(NULL, NULL, "fsl,imx7ulp-pcc2");
+ base = of_iomap(np, 0);
+ WARN_ON(!base);
+
+ clks[IMX7ULP_CLK_DMA1] = imx_clk_gate("dma1", "nic1_bus", base + 0x20, 30);
+ clks[IMX7ULP_CLK_RGPIO2P1] = imx_clk_gate("rgpio2p1", "nic1_bus", base + 0x3c, 30);
+ clks[IMX7ULP_CLK_DMA_MUX1] = imx_clk_gate("dma_mux1", "nic1_bus", base + 0x84, 30);
+ clks[IMX7ULP_CLK_CAAM] = imx_clk_gate("caam", "nic1_div", base + 0x90, 30);
+ clks[IMX7ULP_CLK_LPTPM4] = imx7ulp_clk_composite("lptpm4", periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, false, true, base + 0x94);
+ clks[IMX7ULP_CLK_LPTPM5] = imx7ulp_clk_composite("lptmp5", periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, false, true, base + 0x98);
+ clks[IMX7ULP_CLK_LPIT1] = imx7ulp_clk_composite("lpit1", periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, false, true, base + 0x9C);
+ clks[IMX7ULP_CLK_LPSPI2] = imx7ulp_clk_composite("lpspi2", periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, false, true, base + 0xA4);
+ clks[IMX7ULP_CLK_LPSPI3] = imx7ulp_clk_composite("lpspi3", periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, false, true, base + 0xA8);
+ clks[IMX7ULP_CLK_LPI2C4] = imx7ulp_clk_composite("lpi2c4", periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, false, true, base + 0xAC);
+ clks[IMX7ULP_CLK_LPI2C5] = imx7ulp_clk_composite("lpi2c5", periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, false, true, base + 0xB0);
+ clks[IMX7ULP_CLK_LPUART4] = imx7ulp_clk_composite("lpuart4", periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, false, true, base + 0xB4);
+ clks[IMX7ULP_CLK_LPUART5] = imx7ulp_clk_composite("lpuart5", periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, false, true, base + 0xB8);
+ clks[IMX7ULP_CLK_FLEXIO1] = imx7ulp_clk_composite("flexio", periph_bus_sels, ARRAY_SIZE(periph_plat_sels), true, false, true, base + 0xC4);
+ clks[IMX7ULP_CLK_USB0] = imx7ulp_clk_composite("usb0", periph_plat_sels, ARRAY_SIZE(periph_plat_sels), true, true, true, base + 0xCC);
+ clks[IMX7ULP_CLK_USB1] = imx7ulp_clk_composite("usb1", periph_plat_sels, ARRAY_SIZE(periph_plat_sels), true, true, true, base + 0xD0);
+ clks[IMX7ULP_CLK_USB_PHY] = imx_clk_gate("usb_phy", "nic1_bus", base + 0xD4, 30);
+ clks[IMX7ULP_CLK_USDHC0] = imx7ulp_clk_composite("usdhc0", periph_plat_sels, ARRAY_SIZE(periph_plat_sels), true, true, true, base + 0xDC);
+ clks[IMX7ULP_CLK_USDHC1] = imx7ulp_clk_composite("usdhc1", periph_plat_sels, ARRAY_SIZE(periph_plat_sels), true, true, true, base + 0xE0);
+ clks[IMX7ULP_CLK_WDG1] = imx7ulp_clk_composite("wdg1", periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, true, true, base + 0xF4);
+ clks[IMX7ULP_CLK_WDG2] = imx7ulp_clk_composite("wdg2", periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, true, true, base + 0x10C);
+
+ /* PCC3 */
+ np = of_find_compatible_node(NULL, NULL, "fsl,imx7ulp-pcc3");
+ base = of_iomap(np, 0);
+ WARN_ON(!base);
+
+ clks[IMX7ULP_CLK_LPTPM6] = imx7ulp_clk_composite("lptpm6", periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, false, true, base + 0x84);
+ clks[IMX7ULP_CLK_LPTPM7] = imx7ulp_clk_composite("lptpm7", periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, false, true, base + 0x88);
+ clks[IMX7ULP_CLK_LPI2C6] = imx7ulp_clk_composite("lpi2c6", periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, false, true, base + 0x90);
+ clks[IMX7ULP_CLK_LPI2C7] = imx7ulp_clk_composite("lpi2c7", periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, false, true, base + 0x94);
+ clks[IMX7ULP_CLK_LPUART6] = imx7ulp_clk_composite("lpuart6", periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, false, true, base + 0x98);
+ clks[IMX7ULP_CLK_LPUART7] = imx7ulp_clk_composite("lpuart7", periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, false, true, base + 0x9C);
+ clks[IMX7ULP_CLK_VIU] = imx_clk_gate("viu", "nic1_div", base + 0xA0, 30);
+ clks[IMX7ULP_CLK_DSI] = imx7ulp_clk_composite("dsi", periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, true, true, base + 0xA4);
+ clks[IMX7ULP_CLK_LCDIF] = imx7ulp_clk_composite("lcdif", periph_plat_sels, ARRAY_SIZE(periph_plat_sels), true, true, true, base + 0xA8);
+ clks[IMX7ULP_CLK_MMDC] = imx_clk_gate("mmdc", "nic1_div", base + 0xAC, 30);
+ clks[IMX7ULP_CLK_GPU3D] = imx7ulp_clk_composite("gpu3d", periph_plat_sels, ARRAY_SIZE(periph_plat_sels), true, false, true, base + 0x140);
+ clks[IMX7ULP_CLK_PCTLC] = imx_clk_gate("pctlc", "nic1_bus", base + 0xb8, 30);
+ clks[IMX7ULP_CLK_PCTLD] = imx_clk_gate("pctld", "nic1_bus", base + 0xbc, 30);
+ clks[IMX7ULP_CLK_PCTLE] = imx_clk_gate("pctle", "nic1_bus", base + 0xc0, 30);
+ clks[IMX7ULP_CLK_PCTLF] = imx_clk_gate("pctlf", "nic1_bus", base + 0xc4, 30);
+ clks[IMX7ULP_CLK_GPU2D] = imx7ulp_clk_composite("gpu2d", periph_plat_sels, ARRAY_SIZE(periph_plat_sels), true, false, true, base + 0x144);
+
+ imx_check_clocks(clks, ARRAY_SIZE(clks));
+
+ clk_data.clks = clks;
+ clk_data.clk_num = ARRAY_SIZE(clks);
+ of_clk_add_provider(scg_node, of_clk_src_onecell_get, &clk_data);
+
+ for (i = 0; i < ARRAY_SIZE(clks_init_on); i++)
+ imx_clk_prepare_enable(clks[clks_init_on[i]]);
+ imx_clk_set_parent(clks[IMX7ULP_CLK_GPU2D], clks[IMX7ULP_CLK_APLL_PFD2]);
+ imx_clk_set_parent(clks[IMX7ULP_CLK_GPU3D], clks[IMX7ULP_CLK_APLL_PFD2]);
+
+ imx_clk_set_rate(clks[IMX7ULP_CLK_APLL_PFD2], 400000000);
+
+ /* setting the rate for emmc/sd usage */
+ imx_clk_set_rate(clks[IMX7ULP_CLK_APLL_PFD1], 352800000);
+
+ pr_info("i.MX7ULP clock tree init done.\n");
+}
+
+CLK_OF_DECLARE(imx7ulp, "fsl,imx7ulp-scg1", imx7ulp_clocks_init);
+
+static struct clk_div_table apll_pfd0_div_table[] = {
+ { .val = 1, .div = 1, },
+ { .val = 0, .div = 2, },
+ { /* sentinel */ }
+};
+
+static u32 share_count_sai0;
+static u32 share_count_sai1;
+
+static void __init imx7ulp_cm4_clocks_init(struct device_node *scg_node)
+{
+ struct device_node *np, *np_sim;
+ void __iomem *base;
+ void __iomem *base_sim;
+
+ clks_cm4[IMX7ULP_CM4_CLK_DUMMY] = imx_clk_fixed("cm4_dummy", 0);
+
+ clks_cm4[IMX7ULP_CM4_CLK_ROSC] = of_clk_get_by_name(scg_node, "cm4_rosc");
+ clks_cm4[IMX7ULP_CM4_CLK_SOSC] = of_clk_get_by_name(scg_node, "cm4_sosc");
+ clks_cm4[IMX7ULP_CM4_CLK_SIRC] = of_clk_get_by_name(scg_node, "cm4_sirc");
+ clks_cm4[IMX7ULP_CM4_CLK_FIRC] = of_clk_get_by_name(scg_node, "cm4_firc");
+
+ np = scg_node;
+ base = of_iomap(np, 0);
+ WARN_ON(!base);
+
+ np_sim = of_find_compatible_node(NULL, NULL, "fsl,imx7ulp-sim");
+ base_sim = of_iomap(np_sim, 0);
+ WARN_ON(!base_sim);
+
+ clks_cm4[IMX7ULP_CM4_CLK_SPLL_VCO_PRE_SEL] = imx_clk_mux("cm4_spll_vco_pre_sel", base + 0x608, 0, 1, cm4_pll_pre_sels, ARRAY_SIZE(cm4_pll_pre_sels));
+ clks_cm4[IMX7ULP_CM4_CLK_APLL_VCO_PRE_SEL] = imx_clk_mux("cm4_apll_vco_pre_sel", base + 0x508, 0, 1, cm4_pll_pre_sels, ARRAY_SIZE(cm4_pll_pre_sels));
+ /* name parent_name reg shift width */
+ clks_cm4[IMX7ULP_CM4_CLK_SPLL_VCO_PRE_DIV] = imx_clk_divider("cm4_spll_vco_pre_div", "cm4_spll_vco_pre_sel", base + 0x608, 8, 3);
+ clks_cm4[IMX7ULP_CM4_CLK_APLL_VCO_PRE_DIV] = imx_clk_divider("cm4_apll_vco_pre_div", "cm4_apll_vco_pre_sel", base + 0x508, 8, 3);
+ /* name parent_name base*/
+ clks_cm4[IMX7ULP_CM4_CLK_SPLL_VCO] = imx_clk_pllv5("cm4_spll_vco", "cm4_spll_vco_pre_div", base + 0x600);
+ clks_cm4[IMX7ULP_CM4_CLK_APLL_VCO] = imx_clk_pllv4("cm4_apll_vco", "cm4_apll_vco_pre_div", base + 0x500);
+
+ clks_cm4[IMX7ULP_CM4_CLK_APLL_VCO_POST_DIV1] = imx_clk_divider("cm4_apll_vco_post_div1", "cm4_apll_vco", base + 0x508, 24, 4);
+ clks_cm4[IMX7ULP_CM4_CLK_APLL_VCO_POST_DIV2] = imx_clk_divider("cm4_apll_vco_post_div2", "cm4_apll_vco_post_div1", base + 0x508, 28, 4);
+
+ /* SPLL PFDs */
+ clks_cm4[IMX7ULP_CM4_CLK_SPLL_PFD0] = imx_clk_pfdv2("cm4_spll_pfd0", "cm4_spll_vco", base + 0x60C, 0);
+ clks_cm4[IMX7ULP_CM4_CLK_SPLL_PFD1] = imx_clk_pfdv2("cm4_spll_pfd1", "cm4_spll_vco", base + 0x60C, 1);
+ clks_cm4[IMX7ULP_CM4_CLK_SPLL_PFD2] = imx_clk_pfdv2("cm4_spll_pfd2", "cm4_spll_vco", base + 0x60C, 2);
+ clks_cm4[IMX7ULP_CM4_CLK_SPLL_PFD3] = imx_clk_pfdv2("cm4_spll_pfd3", "cm4_spll_vco", base + 0x60C, 3);
+ /* APLL PFDs */
+ clks_cm4[IMX7ULP_CM4_CLK_APLL_PFD0] = imx_clk_pfdv2("cm4_apll_pfd0", "cm4_apll_vco", base + 0x50C, 0);
+ clks_cm4[IMX7ULP_CM4_CLK_APLL_PFD1] = imx_clk_pfdv2("cm4_apll_pfd1", "cm4_apll_vco", base + 0x50C, 1);
+ clks_cm4[IMX7ULP_CM4_CLK_APLL_PFD2] = imx_clk_pfdv2("cm4_apll_pfd2", "cm4_apll_vco", base + 0x50C, 2);
+ clks_cm4[IMX7ULP_CM4_CLK_APLL_PFD3] = imx_clk_pfdv2("cm4_apll_pfd3", "cm4_apll_vco", base + 0x50C, 3);
+
+ clks_cm4[IMX7ULP_CM4_CLK_APLL_PFD0_PRE_DIV] = clk_register_divider_table(NULL, "cm4_apll_pfd0_pre_div", "cm4_apll_pfd0", CLK_SET_RATE_PARENT | CLK_SET_RATE_GATE, base_sim + 0x2c, 5, 1, 0, apll_pfd0_div_table, &imx_ccm_lock);
+
+ clks_cm4[IMX7ULP_CM4_CLK_SPLL_PFD_SEL] = imx_clk_mux("cm4_spll_pfd_sel", base + 0x608, 14, 2, cm4_spll_pfd_sels, ARRAY_SIZE(cm4_spll_pfd_sels));
+ clks_cm4[IMX7ULP_CM4_CLK_APLL_PFD_SEL] = imx_clk_mux("cm4_apll_pfd_sel", base + 0x508, 14, 2, cm4_apll_pfd_sels, ARRAY_SIZE(cm4_apll_pfd_sels));
+
+ clks_cm4[IMX7ULP_CM4_CLK_SPLL_SEL] = imx_clk_mux("cm4_spll_sel", base + 0x608, 1, 1, cm4_spll_sels, ARRAY_SIZE(cm4_spll_sels));
+ clks_cm4[IMX7ULP_CM4_CLK_APLL_SEL] = imx_clk_mux("cm4_apll_sel", base + 0x508, 1, 1, cm4_apll_sels, ARRAY_SIZE(cm4_apll_sels));
+
+ clks_cm4[IMX7ULP_CM4_CLK_SYS_SEL] = imx_clk_mux("cm4_sys_sel", base + 0x14, 24, 4, cm4_sys_sels, ARRAY_SIZE(cm4_sys_sels));
+
+ clks_cm4[IMX7ULP_CM4_CLK_CORE_DIV] = imx_clk_divider("cm4_core_div", "cm4_sys_sel", base + 0x14, 16, 4);
+ clks_cm4[IMX7ULP_CM4_CLK_PLAT_DIV] = imx_clk_divider("cm4_plat_div", "cm4_core_div", base + 0x14, 12, 4);
+ clks_cm4[IMX7ULP_CM4_CLK_BUS_DIV] = imx_clk_divider("cm4_bus_div", "cm4_core_div", base + 0x14, 4, 4);
+ clks_cm4[IMX7ULP_CM4_CLK_SLOW_DIV] = imx_clk_divider("cm4_slow_div", "cm4_core_div", base + 0x14, 0, 4);
+
+ clks_cm4[IMX7ULP_CLK_SCG0_CLKOUT] = imx_clk_mux("scg0_clkout", base + 0x20, 24, 4, scg0_clkout_sels, ARRAY_SIZE(scg0_clkout_sels));
+
+ /* PCG0 */
+ np = of_find_compatible_node(NULL, NULL, "fsl,imx7ulp-pcc0");
+ base = of_iomap(np, 0);
+ WARN_ON(!base);
+
+ clks_cm4[IMX7ULP_CM4_CLK_SAI0_SEL] = imx_clk_mux("cm4_sai0_sel", base + 0xDC, 24, 3, cm4_periph_bus_sels, ARRAY_SIZE(cm4_periph_bus_sels));
+ clks_cm4[IMX7ULP_CM4_CLK_SAI0_DIV] = imx_clk_divider("cm4_sai0_div", "cm4_sai0_sel", base + 0xDC, 0, 8);
+ clks_cm4[IMX7ULP_CM4_CLK_SAI0_ROOT] = imx_clk_gate2_shared("cm4_sai0_root", "cm4_sai0_div", base + 0xDC, 30, &share_count_sai0);
+ clks_cm4[IMX7ULP_CM4_CLK_SAI0_IPG] = imx_clk_gate2_shared("cm4_sai0_ipg", "cm4_bus_div", base + 0xDC, 30, &share_count_sai0);
+
+ /* PCG1 */
+ np = of_find_compatible_node(NULL, NULL, "fsl,imx7ulp-pcc1");
+ base = of_iomap(np, 0);
+ WARN_ON(!base);
+
+
+ clks_cm4[IMX7ULP_CM4_CLK_SAI1_SEL] = imx_clk_mux("cm4_sai1_sel", base + 0xA8, 24, 3, cm4_periph_bus_sels, ARRAY_SIZE(cm4_periph_bus_sels));
+ clks_cm4[IMX7ULP_CM4_CLK_SAI1_DIV] = imx_clk_divider("cm4_sai1_div", "cm4_sai1_sel", base + 0xA8, 0, 8);
+ clks_cm4[IMX7ULP_CM4_CLK_SAI1_ROOT] = imx_clk_gate2_shared("cm4_sai1_root", "cm4_sai1_div", base + 0xA8, 30, &share_count_sai1);
+ clks_cm4[IMX7ULP_CM4_CLK_SAI1_IPG] = imx_clk_gate2_shared("cm4_sai1_ipg", "cm4_bus_div", base + 0xA8, 30, &share_count_sai1);
+
+ imx_check_clocks(clks_cm4, ARRAY_SIZE(clks_cm4));
+
+ clk_data_cm4.clks = clks_cm4;
+ clk_data_cm4.clk_num = ARRAY_SIZE(clks_cm4);
+ of_clk_add_provider(scg_node, of_clk_src_onecell_get, &clk_data_cm4);
+
+ imx_clk_prepare_enable(clks_cm4[IMX7ULP_CM4_CLK_SYS_SEL]);
+
+ pr_info("i.MX7ULP cm4 clock tree init.\n");
+}
+CLK_OF_DECLARE(imx7ulp_cm4, "fsl,imx7ulp-scg0", imx7ulp_cm4_clocks_init);
diff --git a/drivers/clk/imx/clk-imx8.c b/drivers/clk/imx/clk-imx8.c
new file mode 100644
index 000000000000..fb5896a09b79
--- /dev/null
+++ b/drivers/clk/imx/clk-imx8.c
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017 NXP
+ *
+ * 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/errno.h>
+#include <soc/imx8/sc/sci.h>
+
+#include "clk-imx8.h"
+
+sc_ipc_t ccm_ipc_handle;
+
+int imx8_clk_mu_init(void)
+{
+ uint32_t mu_id;
+ sc_err_t sciErr;
+
+ printk("MU and Power domains initialized\n");
+
+ sciErr = sc_ipc_getMuID(&mu_id);
+ if (sciErr != SC_ERR_NONE) {
+ pr_info("Cannot obtain MU ID\n");
+ return -EPROBE_DEFER;
+ }
+
+ sciErr = sc_ipc_open(&ccm_ipc_handle, mu_id);
+
+ if (sciErr != SC_ERR_NONE) {
+ pr_info("Cannot open MU channel to SCU\n");
+ return -EPROBE_DEFER;
+ }
+
+ return 0;
+}
+
+bool imx8_clk_is_resource_owned(sc_rsrc_t rsrc)
+{
+ /*
+ * A-core resources are special. SCFW reports they are not "owned" by
+ * current partition but linux can still adjust them for cpufreq.
+ *
+ * So force this to return false when running as a VM guest and always
+ * true otherwise.
+ */
+ if (rsrc == SC_R_A53 || rsrc == SC_R_A72 || rsrc == SC_R_A35) {
+ if (xen_domain() && !xen_initial_domain())
+ return false;
+ return true;
+ }
+
+ if (!ccm_ipc_handle) {
+ pr_warn("%s: no ipc handle!\n", __func__);
+ /* should have handled -EPROBE_DEFER from clk_mu_init earlier. */
+ return false;
+ }
+
+ return sc_rm_is_resource_owned(ccm_ipc_handle, rsrc);
+}
diff --git a/drivers/clk/imx/clk-imx8.h b/drivers/clk/imx/clk-imx8.h
new file mode 100644
index 000000000000..db1b577423fc
--- /dev/null
+++ b/drivers/clk/imx/clk-imx8.h
@@ -0,0 +1,131 @@
+#ifndef __IMX8_CLK_H
+#define __IMX8_CLK_H
+
+#include <linux/spinlock.h>
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <soc/imx8/sc/sci.h>
+
+extern spinlock_t imx_ccm_lock;
+extern sc_ipc_t ccm_ipc_handle;
+
+int imx8_clk_mu_init(void);
+bool imx8_clk_is_resource_owned(sc_rsrc_t rsrc);
+
+struct clk *imx_clk_divider_scu(const char *name,
+ sc_rsrc_t rsrc_id, sc_pm_clk_t clk_type);
+
+struct clk *imx_clk_divider2_scu(const char *name, const char *parent_name,
+ sc_rsrc_t rsrc_id, sc_pm_clk_t clk_type);
+
+struct clk *imx_clk_divider3_scu(const char *name, const char *parent_name,
+ sc_rsrc_t rsrc_id, sc_ctrl_t gpr_id);
+
+struct clk *clk_register_gate_scu(struct device *dev, const char *name,
+ const char *parent_name, unsigned long flags,
+ u8 clk_gate_scu_flags, spinlock_t *lock,
+ sc_rsrc_t rsrc_id, sc_pm_clk_t clk_type,
+ void __iomem *reg, u8 bit_idx, bool hw_gate);
+
+struct clk *clk_register_gate2_scu(struct device *dev, const char *name,
+ const char *parent_name, unsigned long flags,
+ void __iomem *reg, u8 bit_idx,
+ u8 clk_gate_flags, spinlock_t *lock, const char *pd_name);
+
+struct clk *clk_register_mux_scu(struct device *dev, const char *name,
+ const char **parent_names, u8 num_parents, unsigned long flags,
+ void __iomem *reg, u8 shift, u8 width,
+ u8 clk_mux_flags, spinlock_t *lock,
+ const char *pd_name);
+
+struct clk *clk_register_gate3_scu(struct device *dev, const char *name,
+ const char *parent_name, spinlock_t *lock,
+ sc_rsrc_t rsrc_id, sc_ctrl_t gpr_id, bool invert_flag);
+
+struct clk *clk_register_mux_gpr_scu(struct device *dev, const char *name,
+ const char **parents, int num_parents, spinlock_t *lock,
+ sc_rsrc_t rsrc_id, sc_ctrl_t gpr_id);
+
+struct clk *clk_register_mux2_scu(struct device *dev, const char *name,
+ const char **parents, int num_parents, unsigned long flags,
+ sc_rsrc_t rsrc_id, sc_pm_clk_t clk_type);
+
+static inline struct clk *imx_clk_fixed(const char *name, int rate)
+{
+ return clk_register_fixed_rate(NULL, name, NULL, 0, rate);
+}
+
+static inline struct clk *imx_clk_gate_scu(const char *name, const char *parent,
+ sc_rsrc_t rsrc_id, sc_pm_clk_t clk_type,
+ void __iomem *reg, u8 bit_idx, bool hw_gate)
+{
+ return clk_register_gate_scu(NULL, name, parent,
+ CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE, 0,
+ &imx_ccm_lock, rsrc_id, clk_type, reg,
+ bit_idx, hw_gate);
+}
+
+static inline struct clk *imx_clk_gate2_scu(const char *name, const char *parent,
+ void __iomem *reg, u8 bit_idx, const char *pd_name)
+{
+ return clk_register_gate2_scu(NULL, name, parent, 0, reg,
+ bit_idx, 0, &imx_ccm_lock, pd_name);
+}
+
+static inline struct clk *imx_clk_gate3_scu(const char *name, const char *parent,
+ sc_rsrc_t rsrc_id, sc_ctrl_t gpr_id, bool invert_flag)
+{
+ return clk_register_gate3_scu(NULL, name, parent,
+ &imx_ccm_lock, rsrc_id, gpr_id, invert_flag);
+}
+
+static inline struct clk *imx_clk_mux_gpr_scu(const char *name, const char **parents,
+ int num_parents, sc_rsrc_t rsrc_id, sc_ctrl_t gpr_id)
+{
+ return clk_register_mux_gpr_scu(NULL, name, parents, num_parents,
+ &imx_ccm_lock, rsrc_id, gpr_id);
+}
+
+static inline struct clk *imx_clk_mux2_scu(const char *name,
+ const char **parents, int num_parents, sc_rsrc_t rsrc_id,
+ sc_pm_clk_t clk_type)
+{
+ return clk_register_mux2_scu(NULL, name, parents, num_parents,
+ CLK_SET_RATE_NO_REPARENT, rsrc_id,
+ clk_type);
+}
+
+static inline void imx_clk_set_rate(struct clk *clk, unsigned long rate)
+{
+ int ret = clk_set_rate(clk, rate);
+
+ if (ret)
+ pr_err("failed to set rate of clk %s to %ld: %d\n",
+ __clk_get_name(clk), rate, ret);
+}
+
+static inline struct clk *imx_clk_gate(const char *name, const char *parent,
+ void __iomem *reg, u8 shift)
+{
+ return clk_register_gate(NULL, name, parent, CLK_SET_RATE_PARENT, reg,
+ shift, 0, &imx_ccm_lock);
+}
+
+static inline struct clk *imx_clk_fixed_factor(const char *name,
+ const char *parent, unsigned int mult, unsigned int div)
+{
+ return clk_register_fixed_factor(NULL, name, parent,
+ CLK_SET_RATE_PARENT, mult, div);
+}
+
+static inline struct clk *imx_clk_mux_scu(const char *name, void __iomem *reg,
+ u8 shift, u8 width, const char **parents, int num_parents, const char *pd_name)
+{
+ return clk_register_mux_scu(NULL, name, parents, num_parents,
+ CLK_SET_RATE_NO_REPARENT | CLK_SET_PARENT_NOCACHE,
+ reg, shift,
+ width, 0, &imx_ccm_lock, pd_name);
+}
+
+
+#endif
diff --git a/drivers/clk/imx/clk-imx8mm.c b/drivers/clk/imx/clk-imx8mm.c
new file mode 100644
index 000000000000..5709bfce578c
--- /dev/null
+++ b/drivers/clk/imx/clk-imx8mm.c
@@ -0,0 +1,988 @@
+/*
+ * Copyright 2017-2019 NXP.
+ *
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <dt-bindings/clock/imx8mm-clock.h>
+#include <linux/clk.h>
+#include <linux/clkdev.h>
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/types.h>
+#include <soc/imx8/soc.h>
+
+#include "clk.h"
+
+static u32 share_count_sai1;
+static u32 share_count_sai2;
+static u32 share_count_sai3;
+static u32 share_count_sai4;
+static u32 share_count_sai5;
+static u32 share_count_sai6;
+static u32 share_count_dcss;
+static u32 share_count_pdm;
+static u32 share_count_nand;
+
+/* IDs of PLLs available on i.MX8 Mini */
+enum {
+ ARM_PLL,
+ GPU_PLL,
+ VPU_PLL,
+ SYS_PLL1,
+ SYS_PLL2,
+ SYS_PLL3,
+ DRAM_PLL,
+ AUDIO_PLL1,
+ AUDIO_PLL2,
+ VIDEO_PLL2,
+ NR_PLLS,
+};
+
+#define PLL_1416X_RATE(_rate, _m, _p, _s) \
+ { \
+ .rate = (_rate), \
+ .mdiv = (_m), \
+ .pdiv = (_p), \
+ .sdiv = (_s), \
+ }
+
+#define PLL_1443X_RATE(_rate, _m, _p, _s, _k) \
+ { \
+ .rate = (_rate), \
+ .mdiv = (_m), \
+ .pdiv = (_p), \
+ .sdiv = (_s), \
+ .kdiv = (_k), \
+ }
+
+static const struct imx_int_pll_rate_table imx8mm_intpll_tbl[] = {
+ PLL_1416X_RATE(1800000000U, 225, 3, 0),
+ PLL_1416X_RATE(1600000000U, 200, 3, 0),
+ PLL_1416X_RATE(1200000000U, 300, 3, 1),
+ PLL_1416X_RATE(1000000000U, 250, 3, 1),
+ PLL_1416X_RATE(800000000U, 200, 3, 1),
+ PLL_1416X_RATE(750000000U, 250, 2, 2),
+ PLL_1416X_RATE(700000000U, 350, 3, 2),
+ PLL_1416X_RATE(600000000U, 300, 3, 2),
+};
+
+static const struct imx_int_pll_rate_table imx8mm_audiopll_tbl[] = {
+ PLL_1443X_RATE(786432000U, 262, 2, 2, 9437),
+ PLL_1443X_RATE(722534400U, 361, 3, 2, 17511),
+};
+
+static const struct imx_int_pll_rate_table imx8mm_videopll_tbl[] = {
+ PLL_1443X_RATE(650000000U, 325, 3, 2, 0),
+ PLL_1443X_RATE(594000000U, 198, 2, 2, 0),
+};
+
+static const struct imx_int_pll_rate_table imx8mm_drampll_tbl[] = {
+ PLL_1443X_RATE(650000000U, 325, 3, 2, 0),
+};
+
+static struct imx_int_pll_clk imx8mm_audio_pll __initdata = {
+ .type = PLL_1443X,
+ .rate_table = imx8mm_audiopll_tbl,
+};
+
+static struct imx_int_pll_clk imx8mm_video_pll __initdata = {
+ .type = PLL_1443X,
+ .rate_table = imx8mm_videopll_tbl,
+};
+
+static struct imx_int_pll_clk imx8mm_dram_pll __initdata = {
+ .type = PLL_1443X,
+ .rate_table = imx8mm_drampll_tbl,
+};
+
+static struct imx_int_pll_clk imx8mm_arm_pll __initdata = {
+ .type = PLL_1416X,
+ .rate_table = imx8mm_intpll_tbl,
+};
+
+static struct imx_int_pll_clk imx8mm_gpu_pll __initdata = {
+ .type = PLL_1416X,
+ .rate_table = imx8mm_intpll_tbl,
+};
+
+static struct imx_int_pll_clk imx8mm_vpu_pll __initdata = {
+ .type = PLL_1416X,
+ .rate_table = imx8mm_intpll_tbl,
+};
+
+static struct imx_int_pll_clk imx8mm_sys_pll __initdata = {
+ .type = PLL_1416X,
+ .rate_table = imx8mm_intpll_tbl,
+};
+
+static const char *pll_ref_sels[] = { "osc_24m", "dummy", "dummy", "dummy", };
+static const char *audio_pll1_bypass_sels[] = {"audio_pll1", "audio_pll1_ref_sel", };
+static const char *audio_pll2_bypass_sels[] = {"audio_pll2", "audio_pll2_ref_sel", };
+static const char *video_pll1_bypass_sels[] = {"video_pll1", "video_pll1_ref_sel", };
+static const char *dram_pll_bypass_sels[] = {"dram_pll", "dram_pll_ref_sel", };
+static const char *gpu_pll_bypass_sels[] = {"gpu_pll", "gpu_pll_ref_sel", };
+static const char *vpu_pll_bypass_sels[] = {"vpu_pll", "vpu_pll_ref_sel", };
+static const char *arm_pll_bypass_sels[] = {"arm_pll", "arm_pll_ref_sel", };
+static const char *sys_pll1_bypass_sels[] = {"sys_pll1", "sys_pll1_ref_sel", };
+static const char *sys_pll2_bypass_sels[] = {"sys_pll2", "sys_pll2_ref_sel", };
+static const char *sys_pll3_bypass_sels[] = {"sys_pll3", "sys_pll3_ref_sel", };
+
+/* CCM ROOT */
+static const char *imx8mm_a53_sels[] = {"osc_24m", "arm_pll_out", "sys_pll2_500m", "sys_pll2_1000m",
+ "sys_pll1_800m", "sys_pll1_400m", "audio_pll1_out", "sys_pll3_out", };
+
+static const char *imx8mm_m4_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll2_250m", "sys_pll1_266m",
+ "sys_pll1_800m", "audio_pll1_out", "video_pll1_out", "sys_pll3_out", };
+
+static const char *imx8mm_vpu_sels[] = {"osc_24m", "arm_pll_out", "sys_pll2_500m", "sys_pll2_1000m",
+ "sys_pll1_800m", "sys_pll1_400m", "audio_pll1_out", "vpu_pll_out", };
+
+static const char *imx8mm_gpu3d_sels[] = {"osc_24m", "gpu_pll_out", "sys_pll1_800m", "sys_pll3_out",
+ "sys_pll2_1000m", "audio_pll1_out", "video_pll1_out", "audio_pll2_out", };
+
+static const char *imx8mm_gpu2d_sels[] = {"osc_24m", "gpu_pll_out", "sys_pll1_800m", "sys_pll3_out",
+ "sys_pll2_1000m", "audio_pll1_out", "video_pll1_out", "audio_pll2_out", };
+
+static const char *imx8mm_main_axi_sels[] = {"osc_24m", "sys_pll2_333m", "sys_pll1_800m", "sys_pll2_250m",
+ "sys_pll2_1000m", "audio_pll1_out", "video_pll1_out", "sys_pll1_100m",};
+
+static const char *imx8mm_enet_axi_sels[] = {"osc_24m", "sys_pll1_266m", "sys_pll1_800m", "sys_pll2_250m",
+ "sys_pll2_200m", "audio_pll1_out", "video_pll1_out", "sys_pll3_out", };
+
+static const char *imx8mm_nand_usdhc_sels[] = {"osc_24m", "sys_pll1_266m", "sys_pll1_800m", "sys_pll2_200m",
+ "sys_pll1_133m", "sys_pll3_out", "sys_pll2_250m", "audio_pll1_out", };
+
+static const char *imx8mm_vpu_bus_sels[] = {"osc_24m", "sys_pll1_800m", "vpu_pll_out", "audio_pll2_out",
+ "sys_pll3_out", "sys_pll2_1000m", "sys_pll2_200m", "sys_pll1_100m", };
+
+static const char *imx8mm_disp_axi_sels[] = {"osc_24m", "sys_pll2_1000m", "sys_pll1_800m", "sys_pll3_out",
+ "sys_pll1_40m", "audio_pll2_out", "clk_ext1", "clk_ext4", };
+
+static const char *imx8mm_disp_apb_sels[] = {"osc_24m", "sys_pll2_125m", "sys_pll1_800m", "sys_pll3_out",
+ "sys1_pll_40m", "audio_pll2_out", "clk_ext1", "clk_ext3", };
+
+static const char *imx8mm_disp_rtrm_sels[] = {"osc_24m", "sys_pll1_800m", "sys_pll2_200m", "sys_pll2_1000m",
+ "audio_pll1_out", "video_pll1_out", "clk_ext2", "clk_ext3", };
+
+static const char *imx8mm_usb_bus_sels[] = {"osc_24m", "sys_pll2_500m", "sys_pll1_800m", "sys_pll2_100m",
+ "sys_pll2_200m", "clk_ext2", "clk_ext4", "audio_pll2_out", };
+
+static const char *imx8mm_gpu_axi_sels[] = {"osc_24m", "sys_pll1_800m", "gpu_pll_out", "sys_pll3_out", "sys_pll2_1000m",
+ "audio_pll1_out", "video_pll1_out", "audio_pll2_out", };
+
+static const char *imx8mm_gpu_ahb_sels[] = {"osc_24m", "sys_pll1_800m", "gpu_pll_out", "sys_pll3_out", "sys_pll2_1000m",
+ "audio_pll1_out", "video_pll1_out", "audio_pll2_out", };
+
+static const char *imx8mm_noc_sels[] = {"osc_24m", "sys_pll1_800m", "sys_pll3_out", "sys_pll2_1000m", "sys_pll2_500m",
+ "audio_pll1_out", "video_pll1_out", "audio_pll2_out", };
+
+static const char *imx8mm_noc_apb_sels[] = {"osc_24m", "sys_pll1_400m", "sys_pll3_out", "sys_pll2_333m", "sys_pll2_200m",
+ "sys_pll1_800m", "audio_pll1_out", "video_pll1_out", };
+
+static const char *imx8mm_ahb_sels[] = {"osc_24m", "sys_pll1_133m", "sys_pll1_800m", "sys_pll1_400m",
+ "sys_pll2_125m", "sys_pll3_out", "audio_pll1_out", "video_pll1_out", };
+
+static const char *imx8mm_audio_ahb_sels[] = {"osc_24m", "sys_pll2_500m", "sys_pll1_800m", "sys_pll2_1000m",
+ "sys_pll2_166m", "sys_pll3_out", "audio_pll1_out", "video_pll1_out", };
+
+static const char *imx8mm_dram_alt_sels[] = {"osc_24m", "sys_pll1_800m", "sys_pll1_100m", "sys_pll2_500m",
+ "sys_pll2_1000m", "sys_pll3_out", "audio_pll1_out", "sys_pll1_266m", };
+
+static const char *imx8mm_dram_apb_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll1_40m", "sys_pll1_160m",
+ "sys_pll1_800m", "sys_pll3_out", "sys_pll2_250m", "audio_pll2_out", };
+
+static const char *imx8mm_vpu_g1_sels[] = {"osc_24m", "vpu_pll_out", "sys_pll1_800m", "sys_pll2_1000m",
+ "sys_pll1_100m", "sys_pll2_125m", "sys_pll3_out", "audio_pll1_out", };
+
+static const char *imx8mm_vpu_g2_sels[] = {"osc_24m", "vpu_pll_out", "sys_pll1_800m", "sys_pll2_1000m",
+ "sys_pll1_100m", "sys_pll2_125m", "sys_pll3_out", "audio_pll1_out", };
+
+static const char *imx8mm_disp_dtrc_sels[] = {"osc_24m", "video_pll2_out", "sys_pll1_800m", "sys_pll2_1000m",
+ "sys_pll1_160m", "video_pll1_out", "sys_pll3_out", "audio_pll2_out", };
+
+static const char *imx8mm_disp_dc8000_sels[] = {"osc_24m", "video_pll2_out", "sys_pll1_800m", "sys_pll2_1000m",
+ "sys_pll1_160m", "video_pll1_out", "sys_pll3_out", "audio_pll2_out", };
+
+static const char *imx8mm_pcie1_ctrl_sels[] = {"osc_24m", "sys_pll2_250m", "sys_pll2_200m", "sys_pll1_266m",
+ "sys_pll1_800m", "sys_pll2_500m", "sys_pll2_333m", "sys_pll3_out", };
+
+static const char *imx8mm_pcie1_phy_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll2_500m", "clk_ext1", "clk_ext2",
+ "clk_ext3", "clk_ext4", "sys_pll1_400m", };
+
+static const char *imx8mm_pcie1_aux_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll2_50m", "sys_pll3_out",
+ "sys_pll2_100m", "sys_pll1_80m", "sys_pll1_160m", "sys_pll1_200m", };
+
+static const char *imx8mm_dc_pixel_sels[] = {"osc_24m", "video_pll1_out", "audio_pll2_out", "audio_pll1_out",
+ "sys_pll1_800m", "sys_pll2_1000m", "sys_pll3_out", "clk_ext4", };
+
+static const char *imx8mm_lcdif_pixel_sels[] = {"osc_24m", "video_pll1_out", "audio_pll2_out", "audio_pll1_out",
+ "sys_pll1_800m", "sys_pll2_1000m", "sys_pll3_out", "clk_ext4", };
+
+static const char *imx8mm_sai1_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", "video_pll1_out",
+ "sys_pll1_133m", "osc_hdmi", "clk_ext1", "clk_ext2", };
+
+static const char *imx8mm_sai2_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", "video_pll1_out",
+ "sys_pll1_133m", "osc_hdmi", "clk_ext2", "clk_ext3", };
+
+static const char *imx8mm_sai3_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", "video_pll1_out",
+ "sys_pll1_133m", "osc_hdmi", "clk_ext3", "clk_ext4", };
+
+static const char *imx8mm_sai4_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", "video_pll1_out",
+ "sys_pll1_133m", "osc_hdmi", "clk_ext1", "clk_ext2", };
+
+static const char *imx8mm_sai5_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", "video_pll1_out",
+ "sys_pll1_133m", "osc_hdmi", "clk_ext2", "clk_ext3", };
+
+static const char *imx8mm_sai6_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", "video_pll1_out",
+ "sys_pll1_133m", "osc_hdmi", "clk_ext3", "clk_ext4", };
+
+static const char *imx8mm_spdif1_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", "video_pll1_out",
+ "sys_pll1_133m", "osc_hdmi", "clk_ext2", "clk_ext3", };
+
+static const char *imx8mm_spdif2_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", "video_pll1_out",
+ "sys_pll1_133m", "osc_hdmi", "clk_ext3", "clk_ext4", };
+
+static const char *imx8mm_enet_ref_sels[] = {"osc_24m", "sys_pll2_125m", "sys_pll2_50m", "sys_pll2_100m",
+ "sys_pll1_160m", "audio_pll1_out", "video_pll1_out", "clk_ext4", };
+
+static const char *imx8mm_enet_timer_sels[] = {"osc_24m", "sys_pll2_100m", "audio_pll1_out", "clk_ext1", "clk_ext2",
+ "clk_ext3", "clk_ext4", "video_pll1_out", };
+
+static const char *imx8mm_enet_phy_sels[] = {"osc_24m", "sys_pll2_50m", "sys_pll2_125m", "sys_pll2_200m",
+ "sys_pll2_500m", "video_pll1_out", "audio_pll2_out", };
+
+static const char *imx8mm_nand_sels[] = {"osc_24m", "sys_pll2_500m", "audio_pll1_out", "sys_pll1_400m",
+ "audio_pll2_out", "sys_pll3_out", "sys_pll2_250m", "video_pll1_out", };
+
+static const char *imx8mm_qspi_sels[] = {"osc_24m", "sys1_pll_400m", "sys_pll1_800m", "sys2_pll_500m",
+ "audio_pll2_out", "sys1_pll_266m", "sys3_pll2_out", "sys1_pll_100m", };
+
+static const char *imx8mm_usdhc1_sels[] = {"osc_24m", "sys_pll1_400m", "sys_pll1_800m", "sys_pll2_500m",
+ "sys_pll3_out", "sys_pll1_266m", "audio_pll2_out", "sys_pll1_100m", };
+
+static const char *imx8mm_usdhc2_sels[] = {"osc_24m", "sys_pll1_400m", "sys_pll1_800m", "sys_pll2_500m",
+ "sys_pll3_out", "sys_pll1_266m", "audio_pll2_out", "sys_pll1_100m", };
+
+static const char *imx8mm_i2c1_sels[] = {"osc_24m", "sys_pll1_160m", "sys_pll2_50m", "sys_pll3_out", "audio_pll1_out",
+ "video_pll1_out", "audio_pll2_out", "sys_pll1_133m", };
+
+static const char *imx8mm_i2c2_sels[] = {"osc_24m", "sys_pll1_160m", "sys_pll2_50m", "sys_pll3_out", "audio_pll1_out",
+ "video_pll1_out", "audio_pll2_out", "sys_pll1_133m", };
+
+static const char *imx8mm_i2c3_sels[] = {"osc_24m", "sys_pll1_160m", "sys_pll2_50m", "sys_pll3_out", "audio_pll1_out",
+ "video_pll1_out", "audio_pll2_out", "sys_pll1_133m", };
+
+static const char *imx8mm_i2c4_sels[] = {"osc_24m", "sys_pll1_160m", "sys_pll2_50m", "sys_pll3_out", "audio_pll1_out",
+ "video_pll1_out", "audio_pll2_out", "sys_pll1_133m", };
+
+static const char *imx8mm_uart1_sels[] = {"osc_24m", "sys_pll1_80m", "sys_pll2_200m", "sys_pll2_100m",
+ "sys_pll3_out", "clk_ext2", "clk_ext4", "audio_pll2_out", };
+
+static const char *imx8mm_uart2_sels[] = {"osc_24m", "sys_pll1_80m", "sys_pll2_200m", "sys_pll2_100m",
+ "sys_pll3_out", "clk_ext2", "clk_ext3", "audio_pll2_out", };
+
+static const char *imx8mm_uart3_sels[] = {"osc_24m", "sys_pll1_80m", "sys_pll2_200m", "sys_pll2_100m",
+ "sys_pll3_out", "clk_ext2", "clk_ext4", "audio_pll2_out", };
+
+static const char *imx8mm_uart4_sels[] = {"osc_24m", "sys_pll1_80m", "sys_pll2_200m", "sys_pll2_100m",
+ "sys_pll3_out", "clk_ext2", "clk_ext3", "audio_pll2_out", };
+
+static const char *imx8mm_usb_core_sels[] = {"osc_24m", "sys_pll1_100m", "sys_pll1_40m", "sys_pll2_100m",
+ "sys_pll2_200m", "clk_ext2", "clk_ext3", "audio_pll2_out", };
+
+static const char *imx8mm_usb_phy_sels[] = {"osc_24m", "sys_pll1_100m", "sys_pll1_40m", "sys_pll2_100m",
+ "sys_pll2_200m", "clk_ext2", "clk_ext3", "audio_pll2_out", };
+
+static const char *imx8mm_ecspi1_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll1_40m", "sys_pll1_160m",
+ "sys_pll1_800m", "sys_pll3_out", "sys_pll2_250m", "audio_pll2_out", };
+
+static const char *imx8mm_ecspi2_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll1_40m", "sys_pll1_160m",
+ "sys_pll1_800m", "sys_pll3_out", "sys_pll2_250m", "audio_pll2_out", };
+
+static const char *imx8mm_pwm1_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_160m", "sys_pll1_40m",
+ "sys_pll3_out", "clk_ext1", "sys_pll1_80m", "video_pll1_out", };
+
+static const char *imx8mm_pwm2_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_160m", "sys_pll1_40m",
+ "sys_pll3_out", "clk_ext1", "sys_pll1_80m", "video_pll1_out", };
+
+static const char *imx8mm_pwm3_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_160m", "sys_pll1_40m",
+ "sys3_pll2_out", "clk_ext2", "sys_pll1_80m", "video_pll1_out", };
+
+static const char *imx8mm_pwm4_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_160m", "sys_pll1_40m",
+ "sys_pll3_out", "clk_ext2", "sys_pll1_80m", "video_pll1_out", };
+
+static const char *imx8mm_gpt1_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_400m", "sys_pll1_40m",
+ "video_pll1_out", "sys_pll1_800m", "audio_pll1_out", "clk_ext1" };
+
+static const char *imx8mm_wdog_sels[] = {"osc_24m", "sys_pll1_133m", "sys_pll1_160m", "vpu_pll_out",
+ "sys_pll2_125m", "sys_pll3_out", "sys_pll1_80m", "sys_pll2_166m", };
+
+static const char *imx8mm_wrclk_sels[] = {"osc_24m", "sys_pll1_40m", "vpu_pll_out", "sys_pll3_out", "sys_pll2_200m",
+ "sys_pll1_266m", "sys_pll2_500m", "sys_pll1_100m", };
+
+static const char *imx8mm_dsi_core_sels[] = {"osc_24m", "sys_pll1_266m", "sys_pll2_250m", "sys_pll1_800m",
+ "sys_pll2_1000m", "sys_pll3_out", "audio_pll2_out", "video_pll1_out", };
+
+static const char *imx8mm_dsi_phy_sels[] = {"osc_24m", "sys_pll2_125m", "sys_pll2_100m", "sys_pll1_800m",
+ "sys_pll2_1000m", "clk_ext2", "audio_pll2_out", "video_pll1_out", };
+
+static const char *imx8mm_dsi_dbi_sels[] = {"osc_24m", "sys_pll1_266m", "sys_pll2_100m", "sys_pll1_800m",
+ "sys_pll2_1000m", "sys_pll3_out", "audio_pll2_out", "video_pll1_out", };
+
+static const char *imx8mm_usdhc3_sels[] = {"osc_24m", "sys_pll1_400m", "sys_pll1_800m", "sys_pll2_500m",
+ "sys_pll3_out", "sys_pll1_266m", "audio_pll2_clk", "sys_pll1_100m", };
+
+static const char *imx8mm_csi1_core_sels[] = {"osc_24m", "sys_pll1_266m", "sys_pll2_250m", "sys_pll1_800m",
+ "sys_pll2_1000m", "sys_pll3_out", "audio_pll2_out", "video_pll1_out", };
+
+static const char *imx8mm_csi1_phy_sels[] = {"osc_24m", "sys_pll2_333m", "sys_pll2_100m", "sys_pll1_800m",
+ "sys_pll2_1000m", "clk_ext2", "audio_pll2_out", "video_pll1_out", };
+
+static const char *imx8mm_csi1_esc_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_80m", "sys_pll1_800m",
+ "sys_pll2_1000m", "sys_pll3_out", "clk_ext3", "audio_pll2_out", };
+
+static const char *imx8mm_csi2_core_sels[] = {"osc_24m", "sys_pll1_266m", "sys_pll2_250m", "sys_pll1_800m",
+ "sys_pll2_1000m", "sys_pll3_out", "audio_pll2_out", "video_pll1_out", };
+
+static const char *imx8mm_csi2_phy_sels[] = {"osc_24m", "sys_pll2_333m", "sys_pll2_100m", "sys_pll1_800m",
+ "sys_pll2_1000m", "clk_ext2", "audio_pll2_out", "video_pll1_out", };
+
+static const char *imx8mm_csi2_esc_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_80m", "sys_pll1_800m",
+ "sys_pll2_1000m", "sys_pll3_out", "clk_ext3", "audio_pll2_out", };
+
+static const char *imx8mm_pcie2_ctrl_sels[] = {"osc_24m", "sys_pll2_250m", "sys_pll2_200m", "sys_pll1_266m",
+ "sys_pll1_800m", "sys_pll2_500m", "sys_pll2_333m", "sys_pll3_out", };
+
+static const char *imx8mm_pcie2_phy_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll2_500m", "clk_ext1",
+ "clk_ext2", "clk_ext3", "clk_ext4", "sys_pll1_400m", };
+
+static const char *imx8mm_pcie2_aux_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll2_50m", "sys_pll3_out",
+ "sys_pll2_100m", "sys_pll1_80m", "sys_pll1_160m", "sys_pll1_200m", };
+
+static const char *imx8mm_ecspi3_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll1_40m", "sys_pll1_160m",
+ "sys_pll1_800m", "sys_pll3_out", "sys_pll2_250m", "audio_pll2_out", };
+
+static const char *imx8mm_pdm_sels[] = {"osc_24m", "sys_pll2_100m", "audio_pll1_out", "sys_pll1_800m",
+ "sys_pll2_1000m", "sys_pll3_out", "clk_ext3", "audio_pll2_out", };
+
+static const char *imx8mm_vpu_h1_sels[] = {"osc_24m", "vpu_pll_out", "sys_pll1_800m", "sys_pll2_1000m",
+ "audio_pll2_clk", "sys_pll2_125m", "sys_pll3_clk", "audio_pll1_out", };
+
+static const char *imx8mm_dram_core_sels[] = {"dram_pll_out", "dram_alt_root", };
+
+static struct clk *clks[IMX8MM_CLK_END];
+static struct clk_onecell_data clk_data;
+
+static int const clks_init_on[] __initconst = {
+ IMX8MM_CLK_AHB_CG, IMX8MM_CLK_DRAM_CORE,
+ IMX8MM_CLK_NOC_CG, IMX8MM_CLK_NOC_APB_CG,
+ IMX8MM_CLK_USB_BUS_CG,
+ IMX8MM_CLK_MAIN_AXI_CG, IMX8MM_CLK_AUDIO_AHB_CG,
+ IMX8MM_CLK_DRAM_APB_DIV, IMX8MM_CLK_A53_DIV,
+ IMX8MM_ARM_PLL_OUT, IMX8MM_CLK_DISP_AXI_CG,
+ IMX8MM_CLK_DISP_APB_CG,
+};
+
+static struct clk ** const uart_clks[] __initconst = {
+ &clks[IMX8MM_CLK_UART1_ROOT],
+ &clks[IMX8MM_CLK_UART2_ROOT],
+ &clks[IMX8MM_CLK_UART3_ROOT],
+ &clks[IMX8MM_CLK_UART4_ROOT],
+ NULL
+};
+
+static const char *imx8mm_clko1_sels[] = {"osc_24m", "sys_pll1_800m", "osc_27m", "sys_pll1_200m", "audio_pll2_clk",
+ "vpu_pll", "sys_pll1_80m", };
+
+static int __init imx_clk_init_on(struct device_node *np,
+ struct clk * const clks[])
+{
+ u32 *array;
+ int i, ret, elems;
+
+ elems = of_property_count_u32_elems(np, "init-on-array");
+ if (elems < 0)
+ return elems;
+ array = kcalloc(elems, sizeof(elems), GFP_KERNEL);
+ if (IS_ERR_OR_NULL(array))
+ return PTR_ERR(array);
+
+ ret = of_property_read_u32_array(np, "init-on-array", array, elems);
+ if (ret)
+ return ret;
+
+ for (i = 0; i < elems; i++) {
+ ret = clk_prepare_enable(clks[array[i]]);
+ if (ret)
+ pr_err("clk_prepare_enable failed %d\n", array[i]);
+ }
+
+ return 0;
+}
+
+static void __init imx8mm_clocks_init(struct device_node *ccm_node)
+{
+ struct device_node *np;
+ void __iomem *base;
+ int i;
+
+ check_m4_enabled();
+
+ clks[IMX8MM_CLK_DUMMY] = imx_clk_fixed("dummy", 0);
+ clks[IMX8MM_CLK_24M] = of_clk_get_by_name(ccm_node, "osc_24m");
+ clks[IMX8MM_CLK_32K] = of_clk_get_by_name(ccm_node, "osc_32k"); /* Check more */
+ clks[IMX8MM_CLK_EXT1] = of_clk_get_by_name(ccm_node, "clk_ext1");
+ clks[IMX8MM_CLK_EXT2] = of_clk_get_by_name(ccm_node, "clk_ext2");
+ clks[IMX8MM_CLK_EXT3] = of_clk_get_by_name(ccm_node, "clk_ext3");
+ clks[IMX8MM_CLK_EXT4] = of_clk_get_by_name(ccm_node, "clk_ext4");
+
+ np = of_find_compatible_node(NULL, NULL, "fsl,imx8mm-anatop");
+ base = of_iomap(np, 0);
+ WARN_ON(!base);
+
+ clks[IMX8MM_AUDIO_PLL1_REF_SEL] = imx_clk_mux("audio_pll1_ref_sel", base + 0x0, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+ clks[IMX8MM_AUDIO_PLL2_REF_SEL] = imx_clk_mux("audio_pll2_ref_sel", base + 0x14, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+ clks[IMX8MM_VIDEO_PLL1_REF_SEL] = imx_clk_mux("video_pll1_ref_sel", base + 0x28, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+ clks[IMX8MM_DRAM_PLL_REF_SEL] = imx_clk_mux("dram_pll_ref_sel", base + 0x50, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+ clks[IMX8MM_GPU_PLL_REF_SEL] = imx_clk_mux("gpu_pll_ref_sel", base + 0x64, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+ clks[IMX8MM_VPU_PLL_REF_SEL] = imx_clk_mux("vpu_pll_ref_sel", base + 0x74, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+ clks[IMX8MM_ARM_PLL_REF_SEL] = imx_clk_mux("arm_pll_ref_sel", base + 0x84, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+ clks[IMX8MM_SYS_PLL1_REF_SEL] = imx_clk_mux("sys_pll1_ref_sel", base + 0x94, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+ clks[IMX8MM_SYS_PLL2_REF_SEL] = imx_clk_mux("sys_pll2_ref_sel", base + 0x104, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+ clks[IMX8MM_SYS_PLL3_REF_SEL] = imx_clk_mux("sys_pll3_ref_sel", base + 0x114, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+
+ clks[IMX8MM_AUDIO_PLL1] = imx_clk_int_pll("audio_pll1", "audio_pll1_ref_sel", base, &imx8mm_audio_pll);
+ clks[IMX8MM_AUDIO_PLL2] = imx_clk_int_pll("audio_pll2", "audio_pll2_ref_sel", base + 0x14, &imx8mm_audio_pll);
+ clks[IMX8MM_VIDEO_PLL1] = imx_clk_int_pll("video_pll1", "video_pll1_ref_sel", base + 0x28, &imx8mm_video_pll);
+ clks[IMX8MM_DRAM_PLL] = imx_clk_int_pll("dram_pll", "dram_pll_ref_sel", base + 0x50, &imx8mm_dram_pll);
+ clks[IMX8MM_GPU_PLL] = imx_clk_int_pll("gpu_pll", "gpu_pll_ref_sel", base + 0x64, &imx8mm_gpu_pll);
+ clks[IMX8MM_VPU_PLL] = imx_clk_int_pll("vpu_pll", "vpu_pll_ref_sel", base + 0x74, &imx8mm_vpu_pll);
+ clks[IMX8MM_ARM_PLL] = imx_clk_int_pll("arm_pll", "arm_pll_ref_sel", base + 0x84, &imx8mm_arm_pll);
+ clks[IMX8MM_SYS_PLL1] = imx_clk_int_pll("sys_pll1", "sys_pll1_ref_sel", base + 0x94, &imx8mm_sys_pll);
+ clks[IMX8MM_SYS_PLL2] = imx_clk_int_pll("sys_pll2", "sys_pll2_ref_sel", base + 0x104, &imx8mm_sys_pll);
+ clks[IMX8MM_SYS_PLL3] = imx_clk_int_pll("sys_pll3", "sys_pll3_ref_sel", base + 0x114, &imx8mm_sys_pll);
+
+ /* PLL bypass out */
+ clks[IMX8MM_AUDIO_PLL1_BYPASS] = imx_clk_mux_flags("audio_pll1_bypass", base, 4, 1, audio_pll1_bypass_sels, ARRAY_SIZE(audio_pll1_bypass_sels), CLK_SET_RATE_PARENT);
+ clks[IMX8MM_AUDIO_PLL2_BYPASS] = imx_clk_mux_flags("audio_pll2_bypass", base + 0x14, 4, 1, audio_pll2_bypass_sels, ARRAY_SIZE(audio_pll2_bypass_sels), CLK_SET_RATE_PARENT);
+ clks[IMX8MM_VIDEO_PLL1_BYPASS] = imx_clk_mux_flags("video_pll1_bypass", base + 0x28, 4, 1, video_pll1_bypass_sels, ARRAY_SIZE(video_pll1_bypass_sels), CLK_SET_RATE_PARENT);
+ clks[IMX8MM_DRAM_PLL_BYPASS] = imx_clk_mux_flags("dram_pll_bypass", base + 0x50, 4, 1, dram_pll_bypass_sels, ARRAY_SIZE(dram_pll_bypass_sels), CLK_SET_RATE_PARENT);
+ clks[IMX8MM_GPU_PLL_BYPASS] = imx_clk_mux_flags("gpu_pll_bypass", base + 0x64, 4, 1, gpu_pll_bypass_sels, ARRAY_SIZE(gpu_pll_bypass_sels), CLK_SET_RATE_PARENT);
+ clks[IMX8MM_VPU_PLL_BYPASS] = imx_clk_mux_flags("vpu_pll_bypass", base + 0x74, 4, 1, vpu_pll_bypass_sels, ARRAY_SIZE(vpu_pll_bypass_sels), CLK_SET_RATE_PARENT);
+ clks[IMX8MM_ARM_PLL_BYPASS] = imx_clk_mux_flags("arm_pll_bypass", base + 0x84, 4, 1, arm_pll_bypass_sels, ARRAY_SIZE(arm_pll_bypass_sels), CLK_SET_RATE_PARENT);
+ clks[IMX8MM_SYS_PLL1_BYPASS] = imx_clk_mux_flags("sys_pll1_bypass", base + 0x94, 4, 1, sys_pll1_bypass_sels, ARRAY_SIZE(sys_pll1_bypass_sels), CLK_SET_RATE_PARENT);
+ clks[IMX8MM_SYS_PLL2_BYPASS] = imx_clk_mux_flags("sys_pll2_bypass", base + 0x104, 4, 1, sys_pll2_bypass_sels, ARRAY_SIZE(sys_pll2_bypass_sels), CLK_SET_RATE_PARENT);
+ clks[IMX8MM_SYS_PLL3_BYPASS] = imx_clk_mux_flags("sys_pll3_bypass", base + 0x114, 4, 1, sys_pll3_bypass_sels, ARRAY_SIZE(sys_pll3_bypass_sels), CLK_SET_RATE_PARENT);
+
+ /* unbypass all the plls */
+ clk_set_parent(clks[IMX8MM_AUDIO_PLL1_BYPASS], clks[IMX8MM_AUDIO_PLL1]);
+ clk_set_parent(clks[IMX8MM_AUDIO_PLL2_BYPASS], clks[IMX8MM_AUDIO_PLL2]);
+ clk_set_parent(clks[IMX8MM_VIDEO_PLL1_BYPASS], clks[IMX8MM_VIDEO_PLL1]);
+ clk_set_parent(clks[IMX8MM_DRAM_PLL_BYPASS], clks[IMX8MM_DRAM_PLL]);
+ clk_set_parent(clks[IMX8MM_GPU_PLL_BYPASS], clks[IMX8MM_GPU_PLL]);
+ clk_set_parent(clks[IMX8MM_VPU_PLL_BYPASS], clks[IMX8MM_VPU_PLL]);
+ clk_set_parent(clks[IMX8MM_ARM_PLL_BYPASS], clks[IMX8MM_ARM_PLL]);
+ clk_set_parent(clks[IMX8MM_SYS_PLL1_BYPASS], clks[IMX8MM_SYS_PLL1]);
+ clk_set_parent(clks[IMX8MM_SYS_PLL2_BYPASS], clks[IMX8MM_SYS_PLL2]);
+ clk_set_parent(clks[IMX8MM_SYS_PLL3_BYPASS], clks[IMX8MM_SYS_PLL3]);
+
+ /* PLL out gate */
+ clks[IMX8MM_AUDIO_PLL1_OUT] = imx_clk_gate("audio_pll1_out", "audio_pll1_bypass", base, 13);
+ clks[IMX8MM_AUDIO_PLL2_OUT] = imx_clk_gate("audio_pll2_out", "audio_pll2_bypass", base + 0x14, 13);
+ clks[IMX8MM_VIDEO_PLL1_OUT] = imx_clk_gate("video_pll1_out", "video_pll1_bypass", base + 0x28, 13);
+ clks[IMX8MM_DRAM_PLL_OUT] = imx_clk_gate("dram_pll_out", "dram_pll_bypass", base + 0x50, 13);
+ clks[IMX8MM_GPU_PLL_OUT] = imx_clk_gate("gpu_pll_out", "gpu_pll_bypass", base + 0x64, 13);
+ clks[IMX8MM_VPU_PLL_OUT] = imx_clk_gate("vpu_pll_out", "vpu_pll_bypass", base + 0x74, 13);
+ clks[IMX8MM_ARM_PLL_OUT] = imx_clk_gate("arm_pll_out", "arm_pll_bypass", base + 0x84, 13);
+ clks[IMX8MM_SYS_PLL1_OUT] = imx_clk_gate("sys_pll1_out", "sys_pll1_bypass", base + 0x94, 13);
+ clks[IMX8MM_SYS_PLL2_OUT] = imx_clk_gate("sys_pll2_out", "sys_pll2_bypass", base + 0x104, 13);
+ clks[IMX8MM_SYS_PLL3_OUT] = imx_clk_gate("sys_pll3_out", "sys_pll3_bypass", base + 0x114, 13);
+
+ /* SYS PLL fixed output */
+ clks[IMX8MM_SYS_PLL1_40M] = imx_clk_fixed_factor("sys_pll1_40m", "sys_pll1_out", 1, 20);
+ clks[IMX8MM_SYS_PLL1_80M] = imx_clk_fixed_factor("sys_pll1_80m", "sys_pll1_out", 1, 10);
+ clks[IMX8MM_SYS_PLL1_100M] = imx_clk_fixed_factor("sys_pll1_100m", "sys_pll1_out", 1, 8);
+ clks[IMX8MM_SYS_PLL1_133M] = imx_clk_fixed_factor("sys_pll1_133m", "sys_pll1_out", 1, 6);
+ clks[IMX8MM_SYS_PLL1_160M] = imx_clk_fixed_factor("sys_pll1_160m", "sys_pll1_out", 1, 5);
+ clks[IMX8MM_SYS_PLL1_200M] = imx_clk_fixed_factor("sys_pll1_200m", "sys_pll1_out", 1, 4);
+ clks[IMX8MM_SYS_PLL1_266M] = imx_clk_fixed_factor("sys_pll1_266m", "sys_pll1_out", 1, 3);
+ clks[IMX8MM_SYS_PLL1_400M] = imx_clk_fixed_factor("sys_pll1_400m", "sys_pll1_out", 1, 2);
+ clks[IMX8MM_SYS_PLL1_800M] = imx_clk_fixed_factor("sys_pll1_800m", "sys_pll1_out", 1, 1);
+
+ clks[IMX8MM_SYS_PLL2_50M] = imx_clk_fixed_factor("sys_pll2_50m", "sys_pll2_out", 1, 20);
+ clks[IMX8MM_SYS_PLL2_100M] = imx_clk_fixed_factor("sys_pll2_100m", "sys_pll2_out", 1, 10);
+ clks[IMX8MM_SYS_PLL2_125M] = imx_clk_fixed_factor("sys_pll2_125m", "sys_pll2_out", 1, 8);
+ clks[IMX8MM_SYS_PLL2_166M] = imx_clk_fixed_factor("sys_pll2_166m", "sys_pll2_out", 1, 6);
+ clks[IMX8MM_SYS_PLL2_200M] = imx_clk_fixed_factor("sys_pll2_200m", "sys_pll2_out", 1, 5);
+ clks[IMX8MM_SYS_PLL2_250M] = imx_clk_fixed_factor("sys_pll2_250m", "sys_pll2_out", 1, 4);
+ clks[IMX8MM_SYS_PLL2_333M] = imx_clk_fixed_factor("sys_pll2_333m", "sys_pll2_out", 1, 3);
+ clks[IMX8MM_SYS_PLL2_500M] = imx_clk_fixed_factor("sys_pll2_500m", "sys_pll2_out", 1, 2);
+ clks[IMX8MM_SYS_PLL2_1000M] = imx_clk_fixed_factor("sys_pll2_1000m", "sys_pll2_out", 1, 1);
+
+ np = ccm_node;
+ base = of_iomap(np, 0);
+ WARN_ON(!base);
+
+ /* Core Slice */
+ clks[IMX8MM_CLK_A53_SRC] = imx_clk_mux2("arm_a53_src", base + 0x8000, 24, 3, imx8mm_a53_sels, ARRAY_SIZE(imx8mm_a53_sels));
+ clks[IMX8MM_CLK_M4_SRC] = imx_clk_mux2("arm_m4_src", base + 0x8080, 24, 3, imx8mm_m4_sels, ARRAY_SIZE(imx8mm_m4_sels));
+ clks[IMX8MM_CLK_VPU_SRC] = imx_clk_mux2("vpu_src", base + 0x8100, 24, 3, imx8mm_vpu_sels, ARRAY_SIZE(imx8mm_vpu_sels));
+ clks[IMX8MM_CLK_GPU3D_SRC] = imx_clk_mux2("gpu3d_src", base + 0x8180, 24, 3, imx8mm_gpu3d_sels, ARRAY_SIZE(imx8mm_gpu3d_sels));
+ clks[IMX8MM_CLK_GPU2D_SRC] = imx_clk_mux2("gpu2d_src", base + 0x8200, 24, 3, imx8mm_gpu2d_sels, ARRAY_SIZE(imx8mm_gpu2d_sels));
+ clks[IMX8MM_CLK_A53_CG] = imx_clk_gate3("arm_a53_cg", "arm_a53_src", base + 0x8000, 28);
+ clks[IMX8MM_CLK_M4_CG] = imx_clk_gate3("arm_m4_cg", "arm_m4_src", base + 0x8080, 28);
+ clks[IMX8MM_CLK_VPU_CG] = imx_clk_gate3("vpu_cg", "vpu_src", base + 0x8100, 28);
+ clks[IMX8MM_CLK_GPU3D_CG] = imx_clk_gate3("gpu3d_cg", "gpu3d_src", base + 0x8180, 28);
+ clks[IMX8MM_CLK_GPU2D_CG] = imx_clk_gate3("gpu2d_cg", "gpu2d_src", base + 0x8200, 28);
+
+ clks[IMX8MM_CLK_A53_DIV] = imx_clk_divider2("arm_a53_div", "arm_a53_cg", base + 0x8000, 0, 3);
+ clks[IMX8MM_CLK_M4_DIV] = imx_clk_divider2("arm_m4_div", "arm_m4_cg", base + 0x8080, 0, 3);
+ clks[IMX8MM_CLK_VPU_DIV] = imx_clk_divider2("vpu_div", "vpu_cg", base + 0x8100, 0, 3);
+ clks[IMX8MM_CLK_GPU3D_DIV] = imx_clk_divider2("gpu3d_div", "gpu3d_cg", base + 0x8180, 0, 3);
+ clks[IMX8MM_CLK_GPU2D_DIV] = imx_clk_divider2("gpu2d_div", "gpu2d_cg", base + 0x8200, 0, 3);
+
+ /* BUS */
+ clks[IMX8MM_CLK_MAIN_AXI_SRC] = imx_clk_mux2("main_axi_src", base + 0x8800, 24, 3, imx8mm_main_axi_sels, ARRAY_SIZE(imx8mm_main_axi_sels));
+ clks[IMX8MM_CLK_ENET_AXI_SRC] = imx_clk_mux2("enet_axi_src", base + 0x8880, 24, 3, imx8mm_enet_axi_sels, ARRAY_SIZE(imx8mm_enet_axi_sels));
+ clks[IMX8MM_CLK_NAND_USDHC_BUS_SRC] = imx_clk_mux2("nand_usdhc_bus_src", base + 0x8900, 24, 3, imx8mm_nand_usdhc_sels, ARRAY_SIZE(imx8mm_nand_usdhc_sels));
+ clks[IMX8MM_CLK_VPU_BUS_SRC] = imx_clk_mux2("vpu_bus_src", base + 0x8980, 24, 3, imx8mm_vpu_bus_sels, ARRAY_SIZE(imx8mm_vpu_bus_sels));
+ clks[IMX8MM_CLK_DISP_AXI_SRC] = imx_clk_mux2("disp_axi_src", base + 0x8a00, 24, 3, imx8mm_disp_axi_sels, ARRAY_SIZE(imx8mm_disp_axi_sels));
+ clks[IMX8MM_CLK_DISP_APB_SRC] = imx_clk_mux2("disp_apb_src", base + 0x8a80, 24, 3, imx8mm_disp_apb_sels, ARRAY_SIZE(imx8mm_disp_apb_sels));
+ clks[IMX8MM_CLK_DISP_RTRM_SRC] = imx_clk_mux2("disp_rtrm_src", base + 0x8b00, 24, 3, imx8mm_disp_rtrm_sels, ARRAY_SIZE(imx8mm_disp_rtrm_sels));
+ clks[IMX8MM_CLK_USB_BUS_SRC] = imx_clk_mux2("usb_bus_src", base + 0x8b80, 24, 3, imx8mm_usb_bus_sels, ARRAY_SIZE(imx8mm_usb_bus_sels));
+ clks[IMX8MM_CLK_GPU_AXI_SRC] = imx_clk_mux2("gpu_axi_src", base + 0x8c00, 24, 3, imx8mm_gpu_axi_sels, ARRAY_SIZE(imx8mm_gpu_axi_sels));
+ clks[IMX8MM_CLK_GPU_AHB_SRC] = imx_clk_mux2("gpu_ahb_src", base + 0x8c80, 24, 3, imx8mm_gpu_ahb_sels, ARRAY_SIZE(imx8mm_gpu_ahb_sels));
+ clks[IMX8MM_CLK_NOC_SRC] = imx_clk_mux2("noc_src", base + 0x8d00, 24, 3, imx8mm_noc_sels, ARRAY_SIZE(imx8mm_noc_sels));
+ clks[IMX8MM_CLK_NOC_APB_SRC] = imx_clk_mux2("noc_apb_src", base + 0x8d80, 24, 3, imx8mm_noc_apb_sels, ARRAY_SIZE(imx8mm_noc_apb_sels));
+
+ clks[IMX8MM_CLK_MAIN_AXI_CG] = imx_clk_gate3("main_axi_cg", "main_axi_src", base + 0x8800, 28);
+ clks[IMX8MM_CLK_ENET_AXI_CG] = imx_clk_gate3("enet_axi_cg", "enet_axi_src", base + 0x8880, 28);
+ clks[IMX8MM_CLK_NAND_USDHC_BUS_CG] = imx_clk_gate3("nand_usdhc_bus_cg", "nand_usdhc_bus_src", base + 0x8900, 28);
+ clks[IMX8MM_CLK_VPU_BUS_CG] = imx_clk_gate3("vpu_bus_cg", "vpu_bus_src", base + 0x8980, 28);
+ clks[IMX8MM_CLK_DISP_AXI_CG] = imx_clk_gate3("disp_axi_cg", "disp_axi_src", base + 0x8a00, 28);
+ clks[IMX8MM_CLK_DISP_APB_CG] = imx_clk_gate3("disp_apb_cg", "disp_apb_src", base + 0x8a80, 28);
+ clks[IMX8MM_CLK_DISP_RTRM_CG] = imx_clk_gate3("disp_rtrm_cg", "disp_rtrm_src", base + 0x8b00, 28);
+ clks[IMX8MM_CLK_USB_BUS_CG] = imx_clk_gate3("usb_bus_cg", "usb_bus_src", base + 0x8b80, 28);
+ clks[IMX8MM_CLK_GPU_AXI_CG] = imx_clk_gate3("gpu_axi_cg", "gpu_axi_src", base + 0x8c00, 28);
+ clks[IMX8MM_CLK_GPU_AHB_CG] = imx_clk_gate3("gpu_ahb_cg", "gpu_ahb_src", base + 0x8c80, 28);
+ clks[IMX8MM_CLK_NOC_CG] = imx_clk_gate3("noc_cg", "noc_src", base + 0x8d00, 28);
+ clks[IMX8MM_CLK_NOC_APB_CG] = imx_clk_gate3("noc_apb_cg", "noc_apb_src", base + 0x8d80, 28);
+
+ clks[IMX8MM_CLK_MAIN_AXI_PRE_DIV] = imx_clk_divider2("main_axi_pre_div", "main_axi_cg", base + 0x8800, 16, 3);
+ clks[IMX8MM_CLK_ENET_AXI_PRE_DIV] = imx_clk_divider2("enet_axi_pre_div", "enet_axi_cg", base + 0x8880, 16, 3);
+ clks[IMX8MM_CLK_NAND_USDHC_BUS_PRE_DIV] = imx_clk_divider2("nand_usdhc_bus_pre_div", "nand_usdhc_bus_cg", base + 0x8900, 16, 3);
+ clks[IMX8MM_CLK_VPU_BUS_PRE_DIV] = imx_clk_divider2("vpu_bus_pre_div", "vpu_bus_cg", base + 0x8980, 16, 3);
+ clks[IMX8MM_CLK_DISP_AXI_PRE_DIV] = imx_clk_divider2("disp_axi_pre_div", "disp_axi_cg", base + 0x8a00, 16, 3);
+ clks[IMX8MM_CLK_DISP_APB_PRE_DIV] = imx_clk_divider2("disp_apb_pre_div", "disp_apb_cg", base + 0x8a80, 16, 3);
+ clks[IMX8MM_CLK_DISP_RTRM_PRE_DIV] = imx_clk_divider2("disp_rtrm_pre_div", "disp_rtrm_cg", base + 0x8b00, 16, 3);
+ clks[IMX8MM_CLK_USB_BUS_PRE_DIV] = imx_clk_divider2("usb_bus_pre_div", "usb_bus_cg", base + 0x8b80, 16, 3);
+ clks[IMX8MM_CLK_GPU_AXI_PRE_DIV] = imx_clk_divider2("gpu_axi_pre_div", "gpu_axi_cg", base + 0x8c00, 16, 3);
+ clks[IMX8MM_CLK_GPU_AHB_PRE_DIV] = imx_clk_divider2("gpu_ahb_pre_div", "gpu_ahb_cg", base + 0x8c80, 16, 3);
+ clks[IMX8MM_CLK_NOC_PRE_DIV] = imx_clk_divider2("noc_pre_div", "noc_cg", base + 0x8d00, 16, 3);
+ clks[IMX8MM_CLK_NOC_APB_PRE_DIV] = imx_clk_divider2("noc_apb_pre_div", "noc_apb_cg", base + 0x8d80, 16, 3);
+
+ clks[IMX8MM_CLK_MAIN_AXI_DIV] = imx_clk_divider2("main_axi_div", "main_axi_pre_div", base + 0x8800, 0, 6);
+ clks[IMX8MM_CLK_ENET_AXI_DIV] = imx_clk_divider2("enet_axi_div", "enet_axi_pre_div", base + 0x8880, 0, 6);
+ clks[IMX8MM_CLK_NAND_USDHC_BUS_DIV] = imx_clk_divider2("nand_usdhc_bus_div", "nand_usdhc_bus_pre_div", base + 0x8900, 0, 6);
+ clks[IMX8MM_CLK_VPU_BUS_DIV] = imx_clk_divider2("vpu_bus_div", "vpu_bus_pre_div", base + 0x8980, 0, 6);
+ clks[IMX8MM_CLK_DISP_AXI_DIV] = imx_clk_divider2("disp_axi_div", "disp_axi_pre_div", base + 0x8a00, 0, 6);
+ clks[IMX8MM_CLK_DISP_APB_DIV] = imx_clk_divider2("disp_apb_div", "disp_apb_pre_div", base + 0x8a80, 0, 6);
+ clks[IMX8MM_CLK_DISP_RTRM_DIV] = imx_clk_divider2("disp_rtrm_div", "disp_rtrm_pre_div", base + 0x8b00, 0, 6);
+ clks[IMX8MM_CLK_USB_BUS_DIV] = imx_clk_divider2("usb_bus_div", "usb_bus_pre_div", base + 0x8b80, 0, 6);
+ clks[IMX8MM_CLK_GPU_AXI_DIV] = imx_clk_divider2("gpu_axi_div", "gpu_axi_pre_div", base + 0x8c00, 0, 6);
+ clks[IMX8MM_CLK_GPU_AHB_DIV] = imx_clk_divider2("gpu_ahb_div", "gpu_ahb_pre_div", base + 0x8c80, 0, 6);
+ clks[IMX8MM_CLK_NOC_DIV] = imx_clk_divider2("noc_div", "noc_pre_div", base + 0x8d00, 0, 6);
+ clks[IMX8MM_CLK_NOC_APB_DIV] = imx_clk_divider2("noc_apb_div", "noc_apb_pre_div", base + 0x8d80, 0, 6);
+
+ /* AHB */
+ clks[IMX8MM_CLK_AHB_SRC] = imx_clk_mux2("ahb_src", base + 0x9000, 24, 3, imx8mm_ahb_sels, ARRAY_SIZE(imx8mm_ahb_sels));
+ clks[IMX8MM_CLK_AUDIO_AHB_SRC] = imx_clk_mux2("audio_ahb_src", base + 0x9100, 24, 3, imx8mm_audio_ahb_sels, ARRAY_SIZE(imx8mm_audio_ahb_sels));
+ clks[IMX8MM_CLK_AHB_CG] = imx_clk_gate3("ahb_cg", "ahb_src", base + 0x9000, 28);
+ clks[IMX8MM_CLK_AUDIO_AHB_CG] = imx_clk_gate3("audio_ahb_cg", "audio_ahb_src", base + 0x9100, 28);
+ clks[IMX8MM_CLK_AHB_PRE_DIV] = imx_clk_divider2("ahb_pre_div", "ahb_cg", base + 0x9000, 16, 3);
+ clks[IMX8MM_CLK_AUDIO_AHB_PRE_DIV] = imx_clk_divider2("audio_ahb_pre_div", "audio_ahb_cg", base + 0x9100, 16, 3);
+ clks[IMX8MM_CLK_AHB_DIV] = imx_clk_divider_flags("ahb_div", "ahb_pre_div", base + 0x9000, 0, 6, CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE);
+ clks[IMX8MM_CLK_AUDIO_AHB_DIV] = imx_clk_divider2("audio_ahb_div", "audio_ahb_pre_div", base + 0x9100, 0, 6);
+
+ /* IPG */
+ clks[IMX8MM_CLK_IPG_ROOT] = imx_clk_divider2("ipg_root", "ahb_div", base + 0x9080, 0, 1);
+ clks[IMX8MM_CLK_IPG_AUDIO_ROOT] = imx_clk_divider2("ipg_audio_root", "audio_ahb_div", base + 0x9180, 0, 1);
+
+ /* IP */
+ clks[IMX8MM_CLK_DRAM_ALT_SRC] = imx_clk_mux2("dram_alt_src", base + 0xa000, 24, 3, imx8mm_dram_alt_sels, ARRAY_SIZE(imx8mm_dram_alt_sels));
+ clks[IMX8MM_CLK_DRAM_APB_SRC] = imx_clk_mux2("dram_apb_src", base + 0xa080, 24, 3, imx8mm_dram_apb_sels, ARRAY_SIZE(imx8mm_dram_apb_sels));
+ clks[IMX8MM_CLK_VPU_G1_SRC] = imx_clk_mux2("vpu_g1_src", base + 0xa100, 24, 3, imx8mm_vpu_g1_sels, ARRAY_SIZE(imx8mm_vpu_g1_sels));
+ clks[IMX8MM_CLK_VPU_G2_SRC] = imx_clk_mux2("vpu_g2_src", base + 0xa180, 24, 3, imx8mm_vpu_g2_sels, ARRAY_SIZE(imx8mm_vpu_g2_sels));
+ clks[IMX8MM_CLK_DISP_DTRC_SRC] = imx_clk_mux2("disp_dtrc_src", base + 0xa200, 24, 3, imx8mm_disp_dtrc_sels, ARRAY_SIZE(imx8mm_disp_dtrc_sels));
+ clks[IMX8MM_CLK_DISP_DC8000_SRC] = imx_clk_mux2("disp_dc8000_src", base + 0xa280, 24, 3, imx8mm_disp_dc8000_sels, ARRAY_SIZE(imx8mm_disp_dc8000_sels));
+ clks[IMX8MM_CLK_PCIE1_CTRL_SRC] = imx_clk_mux2("pcie1_ctrl_src", base + 0xa300, 24, 3, imx8mm_pcie1_ctrl_sels, ARRAY_SIZE(imx8mm_pcie1_ctrl_sels));
+ clks[IMX8MM_CLK_PCIE1_PHY_SRC] = imx_clk_mux2("pcie1_phy_src", base + 0xa380, 24, 3, imx8mm_pcie1_phy_sels, ARRAY_SIZE(imx8mm_pcie1_phy_sels));
+ clks[IMX8MM_CLK_PCIE1_AUX_SRC] = imx_clk_mux2("pcie1_aux_src", base + 0xa400, 24, 3, imx8mm_pcie1_aux_sels, ARRAY_SIZE(imx8mm_pcie1_aux_sels));
+ clks[IMX8MM_CLK_DC_PIXEL_SRC] = imx_clk_mux2("dc_pixel_src", base + 0xa480, 24, 3, imx8mm_dc_pixel_sels, ARRAY_SIZE(imx8mm_dc_pixel_sels));
+ clks[IMX8MM_CLK_LCDIF_PIXEL_SRC] = imx_clk_mux2("lcdif_pixel_src", base + 0xa500, 24, 3, imx8mm_lcdif_pixel_sels, ARRAY_SIZE(imx8mm_lcdif_pixel_sels));
+ clks[IMX8MM_CLK_SAI1_SRC] = imx_clk_mux2("sai1_src", base + 0xa580, 24, 3, imx8mm_sai1_sels, ARRAY_SIZE(imx8mm_sai1_sels));
+ clks[IMX8MM_CLK_SAI2_SRC] = imx_clk_mux2("sai2_src", base + 0xa600, 24, 3, imx8mm_sai2_sels, ARRAY_SIZE(imx8mm_sai2_sels));
+ clks[IMX8MM_CLK_SAI3_SRC] = imx_clk_mux2("sai3_src", base + 0xa680, 24, 3, imx8mm_sai3_sels, ARRAY_SIZE(imx8mm_sai3_sels));
+ clks[IMX8MM_CLK_SAI4_SRC] = imx_clk_mux2("sai4_src", base + 0xa700, 24, 3, imx8mm_sai4_sels, ARRAY_SIZE(imx8mm_sai4_sels));
+ clks[IMX8MM_CLK_SAI5_SRC] = imx_clk_mux2("sai5_src", base + 0xa780, 24, 3, imx8mm_sai5_sels, ARRAY_SIZE(imx8mm_sai5_sels));
+ clks[IMX8MM_CLK_SAI6_SRC] = imx_clk_mux2("sai6_src", base + 0xa800, 24, 3, imx8mm_sai6_sels, ARRAY_SIZE(imx8mm_sai6_sels));
+ clks[IMX8MM_CLK_SPDIF1_SRC] = imx_clk_mux2("spdif1_src", base + 0xa880, 24, 3, imx8mm_spdif1_sels, ARRAY_SIZE(imx8mm_spdif1_sels));
+ clks[IMX8MM_CLK_SPDIF2_SRC] = imx_clk_mux2("spdif2_src", base + 0xa900, 24, 3, imx8mm_spdif2_sels, ARRAY_SIZE(imx8mm_spdif2_sels));
+ clks[IMX8MM_CLK_ENET_REF_SRC] = imx_clk_mux2("enet_ref_src", base + 0xa980, 24, 3, imx8mm_enet_ref_sels, ARRAY_SIZE(imx8mm_enet_ref_sels));
+ clks[IMX8MM_CLK_ENET_TIMER_SRC] = imx_clk_mux2("enet_timer_src", base + 0xaa00, 24, 3, imx8mm_enet_timer_sels, ARRAY_SIZE(imx8mm_enet_timer_sels));
+ clks[IMX8MM_CLK_ENET_PHY_REF_SRC] = imx_clk_mux2("enet_phy_src", base + 0xaa80, 24, 3, imx8mm_enet_phy_sels, ARRAY_SIZE(imx8mm_enet_phy_sels));
+ clks[IMX8MM_CLK_NAND_SRC] = imx_clk_mux2("nand_src", base + 0xab00, 24, 3, imx8mm_nand_sels, ARRAY_SIZE(imx8mm_nand_sels));
+ clks[IMX8MM_CLK_QSPI_SRC] = imx_clk_mux2("qspi_src", base + 0xab80, 24, 3, imx8mm_qspi_sels, ARRAY_SIZE(imx8mm_qspi_sels));
+ clks[IMX8MM_CLK_USDHC1_SRC] = imx_clk_mux2("usdhc1_src", base + 0xac00, 24, 3, imx8mm_usdhc1_sels, ARRAY_SIZE(imx8mm_usdhc1_sels));
+ clks[IMX8MM_CLK_USDHC2_SRC] = imx_clk_mux2("usdhc2_src", base + 0xac80, 24, 3, imx8mm_usdhc2_sels, ARRAY_SIZE(imx8mm_usdhc2_sels));
+ clks[IMX8MM_CLK_I2C1_SRC] = imx_clk_mux2("i2c1_src", base + 0xad00, 24, 3, imx8mm_i2c1_sels, ARRAY_SIZE(imx8mm_i2c1_sels));
+ clks[IMX8MM_CLK_I2C2_SRC] = imx_clk_mux2("i2c2_src", base + 0xad80, 24, 3, imx8mm_i2c2_sels, ARRAY_SIZE(imx8mm_i2c2_sels));
+ clks[IMX8MM_CLK_I2C3_SRC] = imx_clk_mux2("i2c3_src", base + 0xae00, 24, 3, imx8mm_i2c3_sels, ARRAY_SIZE(imx8mm_i2c3_sels));
+ clks[IMX8MM_CLK_I2C4_SRC] = imx_clk_mux2("i2c4_src", base + 0xae80, 24, 3, imx8mm_i2c4_sels, ARRAY_SIZE(imx8mm_i2c4_sels));
+ clks[IMX8MM_CLK_UART1_SRC] = imx_clk_mux2("uart1_src", base + 0xaf00, 24, 3, imx8mm_uart1_sels, ARRAY_SIZE(imx8mm_uart1_sels));
+ clks[IMX8MM_CLK_UART2_SRC] = imx_clk_mux2("uart2_src", base + 0xaf80, 24, 3, imx8mm_uart2_sels, ARRAY_SIZE(imx8mm_uart2_sels));
+ clks[IMX8MM_CLK_UART3_SRC] = imx_clk_mux2("uart3_src", base + 0xb000, 24, 3, imx8mm_uart3_sels, ARRAY_SIZE(imx8mm_uart3_sels));
+ clks[IMX8MM_CLK_UART4_SRC] = imx_clk_mux2("uart4_src", base + 0xb080, 24, 3, imx8mm_uart4_sels, ARRAY_SIZE(imx8mm_uart4_sels));
+ clks[IMX8MM_CLK_USB_CORE_REF_SRC] = imx_clk_mux2("usb_core_ref_src", base + 0xb100, 24, 3, imx8mm_usb_core_sels, ARRAY_SIZE(imx8mm_usb_core_sels));
+ clks[IMX8MM_CLK_USB_PHY_REF_SRC] = imx_clk_mux2("usb_phy_ref_src", base + 0xb180, 24, 3, imx8mm_usb_phy_sels, ARRAY_SIZE(imx8mm_usb_phy_sels));
+ clks[IMX8MM_CLK_ECSPI1_SRC] = imx_clk_mux2("ecspi1_src", base + 0xb280, 24, 3, imx8mm_ecspi1_sels, ARRAY_SIZE(imx8mm_ecspi1_sels));
+ clks[IMX8MM_CLK_ECSPI2_SRC] = imx_clk_mux2("ecspi2_src", base + 0xb300, 24, 3, imx8mm_ecspi2_sels, ARRAY_SIZE(imx8mm_ecspi2_sels));
+ clks[IMX8MM_CLK_PWM1_SRC] = imx_clk_mux2("pwm1_src", base + 0xb380, 24, 3, imx8mm_pwm1_sels, ARRAY_SIZE(imx8mm_pwm1_sels));
+ clks[IMX8MM_CLK_PWM2_SRC] = imx_clk_mux2("pwm2_src", base + 0xb400, 24, 3, imx8mm_pwm2_sels, ARRAY_SIZE(imx8mm_pwm2_sels));
+ clks[IMX8MM_CLK_PWM3_SRC] = imx_clk_mux2("pwm3_src", base + 0xb480, 24, 3, imx8mm_pwm3_sels, ARRAY_SIZE(imx8mm_pwm3_sels));
+ clks[IMX8MM_CLK_PWM4_SRC] = imx_clk_mux2("pwm4_src", base + 0xb500, 24, 3, imx8mm_pwm4_sels, ARRAY_SIZE(imx8mm_pwm4_sels));
+ clks[IMX8MM_CLK_GPT1_SRC] = imx_clk_mux2("gpt1_src", base + 0xb580, 24, 3, imx8mm_gpt1_sels, ARRAY_SIZE(imx8mm_gpt1_sels));
+ clks[IMX8MM_CLK_WDOG_SRC] = imx_clk_mux2("wdog_src", base + 0xb900, 24, 3, imx8mm_wdog_sels, ARRAY_SIZE(imx8mm_wdog_sels));
+ clks[IMX8MM_CLK_WRCLK_SRC] = imx_clk_mux2("wrclk_src", base + 0xb980, 24, 3, imx8mm_wrclk_sels, ARRAY_SIZE(imx8mm_wrclk_sels));
+ clks[IMX8MM_CLK_CLKO1_SRC] = imx_clk_mux2("clko1_src", base + 0xba00, 24, 3, imx8mm_clko1_sels, ARRAY_SIZE(imx8mm_clko1_sels));
+ clks[IMX8MM_CLK_DSI_CORE_SRC] = imx_clk_mux2("dsi_core_src", base + 0xbb00, 24, 3, imx8mm_dsi_core_sels, ARRAY_SIZE(imx8mm_dsi_core_sels));
+ clks[IMX8MM_CLK_DSI_PHY_REF_SRC] = imx_clk_mux2("dsi_phy_ref_src", base + 0xbb80, 24, 3, imx8mm_dsi_phy_sels, ARRAY_SIZE(imx8mm_dsi_phy_sels));
+ clks[IMX8MM_CLK_DSI_DBI_SRC] = imx_clk_mux2("dsi_dbi_src", base + 0xbc00, 24, 3, imx8mm_dsi_dbi_sels, ARRAY_SIZE(imx8mm_dsi_dbi_sels));
+ clks[IMX8MM_CLK_USDHC3_SRC] = imx_clk_mux2("usdhc3_src", base + 0xbc80, 24, 3, imx8mm_usdhc3_sels, ARRAY_SIZE(imx8mm_usdhc3_sels));
+ clks[IMX8MM_CLK_CSI1_CORE_SRC] = imx_clk_mux2("csi1_core_src", base + 0xbd00, 24, 3, imx8mm_csi1_core_sels, ARRAY_SIZE(imx8mm_csi1_core_sels));
+ clks[IMX8MM_CLK_CSI1_PHY_REF_SRC] = imx_clk_mux2("csi1_phy_ref_src", base + 0xbd80, 24, 3, imx8mm_csi1_phy_sels, ARRAY_SIZE(imx8mm_csi1_phy_sels));
+ clks[IMX8MM_CLK_CSI1_ESC_SRC] = imx_clk_mux2("csi1_esc_src", base + 0xbe00, 24, 3, imx8mm_csi1_esc_sels, ARRAY_SIZE(imx8mm_csi1_esc_sels));
+ clks[IMX8MM_CLK_CSI2_CORE_SRC] = imx_clk_mux2("csi2_core_src", base + 0xbe80, 24, 3, imx8mm_csi2_core_sels, ARRAY_SIZE(imx8mm_csi2_core_sels));
+ clks[IMX8MM_CLK_CSI2_PHY_REF_SRC] = imx_clk_mux2("csi2_phy_ref_src", base + 0xbf00, 24, 3, imx8mm_csi2_phy_sels, ARRAY_SIZE(imx8mm_csi2_phy_sels));
+ clks[IMX8MM_CLK_CSI2_ESC_SRC] = imx_clk_mux2("csi2_esc_src", base + 0xbf80, 24, 3, imx8mm_csi2_esc_sels, ARRAY_SIZE(imx8mm_csi2_esc_sels));
+ clks[IMX8MM_CLK_PCIE2_CTRL_SRC] = imx_clk_mux2("pcie2_ctrl_src", base + 0xc000, 24, 3, imx8mm_pcie2_ctrl_sels, ARRAY_SIZE(imx8mm_pcie2_ctrl_sels));
+ clks[IMX8MM_CLK_PCIE2_PHY_SRC] = imx_clk_mux2("pcie2_phy_src", base + 0xc080, 24, 3, imx8mm_pcie2_phy_sels, ARRAY_SIZE(imx8mm_pcie2_phy_sels));
+ clks[IMX8MM_CLK_PCIE2_AUX_SRC] = imx_clk_mux2("pcie2_aux_src", base + 0xc100, 24, 3, imx8mm_pcie2_aux_sels, ARRAY_SIZE(imx8mm_pcie2_aux_sels));
+ clks[IMX8MM_CLK_ECSPI3_SRC] = imx_clk_mux2("ecspi3_src", base + 0xc180, 24, 3, imx8mm_ecspi3_sels, ARRAY_SIZE(imx8mm_ecspi3_sels));
+ clks[IMX8MM_CLK_PDM_SRC] = imx_clk_mux2("pdm_src", base + 0xc200, 24, 3, imx8mm_pdm_sels, ARRAY_SIZE(imx8mm_pdm_sels));
+ clks[IMX8MM_CLK_VPU_H1_SRC] = imx_clk_mux2("vpu_h1_src", base + 0xc280, 24, 3, imx8mm_vpu_h1_sels, ARRAY_SIZE(imx8mm_vpu_h1_sels));
+
+ clks[IMX8MM_CLK_DRAM_ALT_CG] = imx_clk_gate3("dram_alt_cg", "dram_alt_src", base + 0xa000, 28);
+ clks[IMX8MM_CLK_DRAM_APB_CG] = imx_clk_gate3("dram_apb_cg", "dram_apb_src", base + 0xa080, 28);
+ clks[IMX8MM_CLK_VPU_G1_CG] = imx_clk_gate3("vpu_g1_cg", "vpu_g1_src", base + 0xa100, 28);
+ clks[IMX8MM_CLK_VPU_G2_CG] = imx_clk_gate3("vpu_g2_cg", "vpu_g2_src", base + 0xa180, 28);
+ clks[IMX8MM_CLK_DISP_DTRC_CG] = imx_clk_gate3("disp_dtrc_cg", "disp_dtrc_src", base + 0xa200, 28);
+ clks[IMX8MM_CLK_DISP_DC8000_CG] = imx_clk_gate3("disp_dc8000_cg", "disp_dc8000_src", base + 0xa280, 28);
+ clks[IMX8MM_CLK_PCIE1_CTRL_CG] = imx_clk_gate3("pcie1_ctrl_cg", "pcie1_ctrl_src", base + 0xa300, 28);
+ clks[IMX8MM_CLK_PCIE1_PHY_CG] = imx_clk_gate3("pcie1_phy_cg", "pcie1_phy_src", base + 0xa380, 28);
+ clks[IMX8MM_CLK_PCIE1_AUX_CG] = imx_clk_gate3("pcie1_aux_cg", "pcie1_aux_src", base + 0xa400, 28);
+ clks[IMX8MM_CLK_DC_PIXEL_CG] = imx_clk_gate3("dc_pixel_cg", "dc_pixel_src", base + 0xa480, 28);
+ clks[IMX8MM_CLK_LCDIF_PIXEL_CG] = imx_clk_gate3("lcdif_pixel_cg", "lcdif_pixel_src", base + 0xa500, 28);
+ clks[IMX8MM_CLK_SAI1_CG] = imx_clk_gate3("sai1_cg", "sai1_src", base + 0xa580, 28);
+ clks[IMX8MM_CLK_SAI2_CG] = imx_clk_gate3("sai2_cg", "sai2_src", base + 0xa600, 28);
+ clks[IMX8MM_CLK_SAI3_CG] = imx_clk_gate3("sai3_cg", "sai3_src", base + 0xa680, 28);
+ clks[IMX8MM_CLK_SAI4_CG] = imx_clk_gate3("sai4_cg", "sai4_src", base + 0xa700, 28);
+ clks[IMX8MM_CLK_SAI5_CG] = imx_clk_gate3("sai5_cg", "sai5_src", base + 0xa780, 28);
+ clks[IMX8MM_CLK_SAI6_CG] = imx_clk_gate3("sai6_cg", "sai6_src", base + 0xa800, 28);
+ clks[IMX8MM_CLK_SPDIF1_CG] = imx_clk_gate3("spdif1_cg", "spdif1_src", base + 0xa880, 28);
+ clks[IMX8MM_CLK_SPDIF2_CG] = imx_clk_gate3("spdif2_cg", "spdif2_src", base + 0xa900, 28);
+ clks[IMX8MM_CLK_ENET_REF_CG] = imx_clk_gate3("enet_ref_cg", "enet_ref_src", base + 0xa980, 28);
+ clks[IMX8MM_CLK_ENET_TIMER_CG] = imx_clk_gate3("enet_timer_cg", "enet_timer_src", base + 0xaa00, 28);
+ clks[IMX8MM_CLK_ENET_PHY_REF_CG] = imx_clk_gate3("enet_phy_cg", "enet_phy_src", base + 0xaa80, 28);
+ clks[IMX8MM_CLK_NAND_CG] = imx_clk_gate3("nand_cg", "nand_src", base + 0xab00, 28);
+ clks[IMX8MM_CLK_QSPI_CG] = imx_clk_gate3("qspi_cg", "qspi_src", base + 0xab80, 28);
+ clks[IMX8MM_CLK_USDHC1_CG] = imx_clk_gate3("usdhc1_cg", "usdhc1_src", base + 0xac00, 28);
+ clks[IMX8MM_CLK_USDHC2_CG] = imx_clk_gate3("usdhc2_cg", "usdhc2_src", base + 0xac80, 28);
+ clks[IMX8MM_CLK_I2C1_CG] = imx_clk_gate3("i2c1_cg", "i2c1_src", base + 0xad00, 28);
+ clks[IMX8MM_CLK_I2C2_CG] = imx_clk_gate3("i2c2_cg", "i2c2_src", base + 0xad80, 28);
+ clks[IMX8MM_CLK_I2C3_CG] = imx_clk_gate3("i2c3_cg", "i2c3_src", base + 0xae00, 28);
+ clks[IMX8MM_CLK_I2C4_CG] = imx_clk_gate3("i2c4_cg", "i2c4_src", base + 0xae80, 28);
+ clks[IMX8MM_CLK_UART1_CG] = imx_clk_gate3("uart1_cg", "uart1_src", base + 0xaf00, 28);
+ clks[IMX8MM_CLK_UART2_CG] = imx_clk_gate3("uart2_cg", "uart2_src", base + 0xaf80, 28);
+ clks[IMX8MM_CLK_UART3_CG] = imx_clk_gate3("uart3_cg", "uart3_src", base + 0xb000, 28);
+ clks[IMX8MM_CLK_UART4_CG] = imx_clk_gate3("uart4_cg", "uart4_src", base + 0xb080, 28);
+ clks[IMX8MM_CLK_USB_CORE_REF_CG] = imx_clk_gate3("usb_core_ref_cg", "usb_core_ref_src", base + 0xb100, 28);
+ clks[IMX8MM_CLK_USB_PHY_REF_CG] = imx_clk_gate3("usb_phy_ref_cg", "usb_phy_ref_src", base + 0xb180, 28);
+ clks[IMX8MM_CLK_ECSPI1_CG] = imx_clk_gate3("ecspi1_cg", "ecspi1_src", base + 0xb280, 28);
+ clks[IMX8MM_CLK_ECSPI2_CG] = imx_clk_gate3("ecspi2_cg", "ecspi2_src", base + 0xb300, 28);
+ clks[IMX8MM_CLK_PWM1_CG] = imx_clk_gate3("pwm1_cg", "pwm1_src", base + 0xb380, 28);
+ clks[IMX8MM_CLK_PWM2_CG] = imx_clk_gate3("pwm2_cg", "pwm2_src", base + 0xb400, 28);
+ clks[IMX8MM_CLK_PWM3_CG] = imx_clk_gate3("pwm3_cg", "pwm3_src", base + 0xb480, 28);
+ clks[IMX8MM_CLK_PWM4_CG] = imx_clk_gate3("pwm4_cg", "pwm4_src", base + 0xb500, 28);
+ clks[IMX8MM_CLK_GPT1_CG] = imx_clk_gate3("gpt1_cg", "gpt1_src", base + 0xb580, 28);
+ clks[IMX8MM_CLK_WDOG_CG] = imx_clk_gate3("wdog_cg", "wdog_src", base + 0xb900, 28);
+ clks[IMX8MM_CLK_WRCLK_CG] = imx_clk_gate3("wrclk_cg", "wrclk_src", base + 0xb980, 28);
+ clks[IMX8MM_CLK_CLKO1_CG] = imx_clk_gate3("clko1_cg", "clko1_src", base + 0xba00, 28);
+ clks[IMX8MM_CLK_DSI_CORE_CG] = imx_clk_gate3("dsi_core_cg", "dsi_core_src", base + 0xbb00, 28);
+ clks[IMX8MM_CLK_DSI_PHY_REF_CG] = imx_clk_gate3("dsi_phy_ref_cg", "dsi_phy_ref_src", base + 0xbb80, 28);
+ clks[IMX8MM_CLK_DSI_DBI_CG] = imx_clk_gate3("dsi_dbi_cg", "dsi_dbi_src", base + 0xbc00, 28);
+ clks[IMX8MM_CLK_USDHC3_CG] = imx_clk_gate3("usdhc3_cg", "usdhc3_src", base + 0xbc80, 28);
+ clks[IMX8MM_CLK_CSI1_CORE_CG] = imx_clk_gate3("csi1_core_cg", "csi1_core_src", base + 0xbd00, 28);
+ clks[IMX8MM_CLK_CSI1_PHY_REF_CG] = imx_clk_gate3("csi1_phy_ref_cg", "csi1_phy_ref_src", base + 0xbd80, 28);
+ clks[IMX8MM_CLK_CSI1_ESC_CG] = imx_clk_gate3("csi1_esc_cg", "csi1_esc_src", base + 0xbe00, 28);
+ clks[IMX8MM_CLK_CSI2_CORE_CG] = imx_clk_gate3("csi2_core_cg", "csi2_core_src", base + 0xbe80, 28);
+ clks[IMX8MM_CLK_CSI2_PHY_REF_CG] = imx_clk_gate3("csi2_phy_ref_cg", "csi2_phy_ref_src", base + 0xbf00, 28);
+ clks[IMX8MM_CLK_CSI2_ESC_CG] = imx_clk_gate3("csi2_esc_cg", "csi2_esc_src", base + 0xbf80, 28);
+ clks[IMX8MM_CLK_PCIE2_CTRL_CG] = imx_clk_gate3("pcie2_ctrl_cg", "pcie2_ctrl_src", base + 0xc000, 28);
+ clks[IMX8MM_CLK_PCIE2_PHY_CG] = imx_clk_gate3("pcie2_phy_cg", "pcie2_phy_src", base + 0xc080, 28);
+ clks[IMX8MM_CLK_PCIE2_AUX_CG] = imx_clk_gate3("pcie2_aux_cg", "pcie2_aux_src", base + 0xc100, 28);
+ clks[IMX8MM_CLK_ECSPI3_CG] = imx_clk_gate3("ecspi3_cg", "ecspi3_src", base + 0xc180, 28);
+ clks[IMX8MM_CLK_PDM_CG] = imx_clk_gate3("pdm_cg", "pdm_src", base + 0xc200, 28);
+ clks[IMX8MM_CLK_VPU_H1_CG] = imx_clk_gate3("vpu_h1_cg", "vpu_h1_src", base + 0xc280, 28);
+
+ clks[IMX8MM_CLK_DRAM_ALT_PRE_DIV] = imx_clk_divider2("dram_alt_pre_div", "dram_alt_cg", base + 0xa000, 16, 3);
+ clks[IMX8MM_CLK_DRAM_APB_PRE_DIV] = imx_clk_divider2("dram_apb_pre_div", "dram_apb_cg", base + 0xa080, 16, 3);
+ clks[IMX8MM_CLK_VPU_G1_PRE_DIV] = imx_clk_divider2("vpu_g1_pre_div", "vpu_g1_cg", base + 0xa100, 16, 3);
+ clks[IMX8MM_CLK_VPU_G2_PRE_DIV] = imx_clk_divider2("vpu_g2_pre_div", "vpu_g2_cg", base + 0xa180, 16, 3);
+ clks[IMX8MM_CLK_DISP_DTRC_PRE_DIV] = imx_clk_divider2("disp_dtrc_pre_div", "disp_dtrc_cg", base + 0xa200, 16, 3);
+ clks[IMX8MM_CLK_DISP_DC8000_PRE_DIV] = imx_clk_divider2("disp_dc8000_pre_div", "disp_dc8000_cg", base + 0xa280, 16, 3);
+ clks[IMX8MM_CLK_PCIE1_CTRL_PRE_DIV] = imx_clk_divider2("pcie1_ctrl_pre_div", "pcie1_ctrl_cg", base + 0xa300, 16, 3);
+ clks[IMX8MM_CLK_PCIE1_PHY_PRE_DIV] = imx_clk_divider2("pcie1_phy_pre_div", "pcie1_phy_cg", base + 0xa380, 16, 3);
+ clks[IMX8MM_CLK_PCIE1_AUX_PRE_DIV] = imx_clk_divider2("pcie1_aux_pre_div", "pcie1_aux_cg", base + 0xa400, 16, 3);
+ clks[IMX8MM_CLK_DC_PIXEL_PRE_DIV] = imx_clk_divider2("dc_pixel_pre_div", "dc_pixel_cg", base + 0xa480, 16, 3);
+ clks[IMX8MM_CLK_LCDIF_PIXEL_PRE_DIV] = imx_clk_divider2("lcdif_pixel_pre_div", "lcdif_pixel_cg", base + 0xa500, 16, 3);
+ clks[IMX8MM_CLK_SAI1_PRE_DIV] = imx_clk_divider2("sai1_pre_div", "sai1_cg", base + 0xa580, 16, 3);
+ clks[IMX8MM_CLK_SAI2_PRE_DIV] = imx_clk_divider2("sai2_pre_div", "sai2_cg", base + 0xa600, 16, 3);
+ clks[IMX8MM_CLK_SAI3_PRE_DIV] = imx_clk_divider2("sai3_pre_div", "sai3_cg", base + 0xa680, 16, 3);
+ clks[IMX8MM_CLK_SAI4_PRE_DIV] = imx_clk_divider2("sai4_pre_div", "sai4_cg", base + 0xa700, 16, 3);
+ clks[IMX8MM_CLK_SAI5_PRE_DIV] = imx_clk_divider2("sai5_pre_div", "sai5_cg", base + 0xa780, 16, 3);
+ clks[IMX8MM_CLK_SAI6_PRE_DIV] = imx_clk_divider2("sai6_pre_div", "sai6_cg", base + 0xa800, 16, 3);
+ clks[IMX8MM_CLK_SPDIF1_PRE_DIV] = imx_clk_divider2("spdif1_pre_div", "spdif1_cg", base + 0xa880, 16, 3);
+ clks[IMX8MM_CLK_SPDIF2_PRE_DIV] = imx_clk_divider2("spdif2_pre_div", "spdif2_cg", base + 0xa900, 16, 3);
+ clks[IMX8MM_CLK_ENET_REF_PRE_DIV] = imx_clk_divider2("enet_ref_pre_div", "enet_ref_cg", base + 0xa980, 16, 3);
+ clks[IMX8MM_CLK_ENET_TIMER_PRE_DIV] = imx_clk_divider2("enet_timer_pre_div", "enet_timer_cg", base + 0xaa00, 16, 3);
+ clks[IMX8MM_CLK_ENET_PHY_REF_PRE_DIV] = imx_clk_divider2("enet_phy_pre_div", "enet_phy_cg", base + 0xaa80, 16, 3);
+ clks[IMX8MM_CLK_NAND_PRE_DIV] = imx_clk_divider2("nand_pre_div", "nand_cg", base + 0xab00, 16, 3);
+ clks[IMX8MM_CLK_QSPI_PRE_DIV] = imx_clk_divider2("qspi_pre_div", "qspi_cg", base + 0xab80, 16, 3);
+ clks[IMX8MM_CLK_USDHC1_PRE_DIV] = imx_clk_divider2("usdhc1_pre_div", "usdhc1_cg", base + 0xac00, 16, 3);
+ clks[IMX8MM_CLK_USDHC2_PRE_DIV] = imx_clk_divider2("usdhc2_pre_div", "usdhc2_cg", base + 0xac80, 16, 3);
+ clks[IMX8MM_CLK_I2C1_PRE_DIV] = imx_clk_divider2("i2c1_pre_div", "i2c1_cg", base + 0xad00, 16, 3);
+ clks[IMX8MM_CLK_I2C2_PRE_DIV] = imx_clk_divider2("i2c2_pre_div", "i2c2_cg", base + 0xad80, 16, 3);
+ clks[IMX8MM_CLK_I2C3_PRE_DIV] = imx_clk_divider2("i2c3_pre_div", "i2c3_cg", base + 0xae00, 16, 3);
+ clks[IMX8MM_CLK_I2C4_PRE_DIV] = imx_clk_divider2("i2c4_pre_div", "i2c4_cg", base + 0xae80, 16, 3);
+ clks[IMX8MM_CLK_UART1_PRE_DIV] = imx_clk_divider2("uart1_pre_div", "uart1_cg", base + 0xaf00, 16, 3);
+ clks[IMX8MM_CLK_UART2_PRE_DIV] = imx_clk_divider2("uart2_pre_div", "uart2_cg", base + 0xaf80, 16, 3);
+ clks[IMX8MM_CLK_UART3_PRE_DIV] = imx_clk_divider2("uart3_pre_div", "uart3_cg", base + 0xb000, 16, 3);
+ clks[IMX8MM_CLK_UART4_PRE_DIV] = imx_clk_divider2("uart4_pre_div", "uart4_cg", base + 0xb080, 16, 3);
+ clks[IMX8MM_CLK_USB_CORE_REF_PRE_DIV] = imx_clk_divider2("usb_core_ref_pre_div", "usb_core_ref_cg", base + 0xb100, 16, 3);
+ clks[IMX8MM_CLK_USB_PHY_REF_PRE_DIV] = imx_clk_divider2("usb_phy_ref_pre_div", "usb_phy_ref_cg", base + 0xb180, 16, 3);
+ clks[IMX8MM_CLK_ECSPI1_PRE_DIV] = imx_clk_divider2("ecspi1_pre_div", "ecspi1_cg", base + 0xb280, 16, 3);
+ clks[IMX8MM_CLK_ECSPI2_PRE_DIV] = imx_clk_divider2("ecspi2_pre_div", "ecspi2_cg", base + 0xb300, 16, 3);
+ clks[IMX8MM_CLK_PWM1_PRE_DIV] = imx_clk_divider2("pwm1_pre_div", "pwm1_cg", base + 0xb380, 16, 3);
+ clks[IMX8MM_CLK_PWM2_PRE_DIV] = imx_clk_divider2("pwm2_pre_div", "pwm2_cg", base + 0xb400, 16, 3);
+ clks[IMX8MM_CLK_PWM3_PRE_DIV] = imx_clk_divider2("pwm3_pre_div", "pwm3_cg", base + 0xb480, 16, 3);
+ clks[IMX8MM_CLK_PWM4_PRE_DIV] = imx_clk_divider2("pwm4_pre_div", "pwm4_cg", base + 0xb500, 16, 3);
+ clks[IMX8MM_CLK_GPT1_PRE_DIV] = imx_clk_divider2("gpt1_pre_div", "gpt1_cg", base + 0xb580, 16, 3);
+ clks[IMX8MM_CLK_WDOG_PRE_DIV] = imx_clk_divider2("wdog_pre_div", "wdog_cg", base + 0xb900, 16, 3);
+ clks[IMX8MM_CLK_WRCLK_PRE_DIV] = imx_clk_divider2("wrclk_pre_div", "wrclk_cg", base + 0xb980, 16, 3);
+ clks[IMX8MM_CLK_CLKO1_PRE_DIV] = imx_clk_divider2("clko1_pre_div", "clko1_cg", base + 0xba00, 16, 3);
+ clks[IMX8MM_CLK_DSI_CORE_PRE_DIV] = imx_clk_divider2("dsi_core_pre_div", "dsi_core_cg", base + 0xbb00, 16, 3);
+ clks[IMX8MM_CLK_DSI_PHY_REF_PRE_DIV] = imx_clk_divider2("dsi_phy_ref_pre_div", "dsi_phy_ref_cg", base + 0xbb80, 16, 3);
+ clks[IMX8MM_CLK_DSI_DBI_PRE_DIV] = imx_clk_divider2("dsi_dbi_pre_div", "dsi_dbi_cg", base + 0xbc00, 16, 3);
+ clks[IMX8MM_CLK_USDHC3_PRE_DIV] = imx_clk_divider2("usdhc3_pre_div", "usdhc3_cg", base + 0xbc80, 16, 3);
+ clks[IMX8MM_CLK_CSI1_CORE_PRE_DIV] = imx_clk_divider2("csi1_core_pre_div", "csi1_core_cg", base + 0xbd00, 16, 3);
+ clks[IMX8MM_CLK_CSI1_PHY_REF_PRE_DIV] = imx_clk_divider2("csi1_phy_ref_pre_div", "csi1_phy_ref_cg", base + 0xbd80, 16, 3);
+ clks[IMX8MM_CLK_CSI1_ESC_PRE_DIV] = imx_clk_divider2("csi1_esc_pre_div", "csi1_esc_cg", base + 0xbe00, 16, 3);
+ clks[IMX8MM_CLK_CSI2_CORE_PRE_DIV] = imx_clk_divider2("csi2_core_pre_div", "csi2_core_cg", base + 0xbe80, 16, 3);
+ clks[IMX8MM_CLK_CSI2_PHY_REF_PRE_DIV] = imx_clk_divider2("csi2_phy_ref_pre_div", "csi2_phy_ref_cg", base + 0xbf00, 16, 3);
+ clks[IMX8MM_CLK_CSI2_ESC_PRE_DIV] = imx_clk_divider2("csi2_esc_pre_div", "csi2_esc_cg", base + 0xbf80, 16, 3);
+ clks[IMX8MM_CLK_PCIE2_CTRL_PRE_DIV] = imx_clk_divider2("pcie2_ctrl_pre_div", "pcie2_ctrl_cg", base + 0xc000, 16, 3);
+ clks[IMX8MM_CLK_PCIE2_PHY_PRE_DIV] = imx_clk_divider2("pcie2_phy_pre_div", "pcie2_phy_cg", base + 0xc080, 16, 3);
+ clks[IMX8MM_CLK_PCIE2_AUX_PRE_DIV] = imx_clk_divider2("pcie2_aux_pre_div", "pcie2_aux_cg", base + 0xc100, 16, 3);
+ clks[IMX8MM_CLK_ECSPI3_PRE_DIV] = imx_clk_divider2("ecspi3_pre_div", "ecspi3_cg", base + 0xc180, 16, 3);
+ clks[IMX8MM_CLK_PDM_PRE_DIV] = imx_clk_divider2("pdm_pre_div", "pdm_cg", base + 0xc200, 16, 3);
+ clks[IMX8MM_CLK_VPU_H1_PRE_DIV] = imx_clk_divider2("vpu_h1_pre_div", "vpu_h1_cg", base + 0xc280, 16, 3);
+
+ clks[IMX8MM_CLK_DRAM_ALT_DIV] = imx_clk_divider2("dram_alt_div", "dram_alt_pre_div", base + 0xa000, 0, 6);
+ clks[IMX8MM_CLK_DRAM_APB_DIV] = imx_clk_divider2("dram_apb_div", "dram_apb_pre_div", base + 0xa080, 0, 6);
+ clks[IMX8MM_CLK_VPU_G1_DIV] = imx_clk_divider2("vpu_g1_div", "vpu_g1_pre_div", base + 0xa100, 0, 6);
+ clks[IMX8MM_CLK_VPU_G2_DIV] = imx_clk_divider2("vpu_g2_div", "vpu_g2_pre_div", base + 0xa180, 0, 6);
+ clks[IMX8MM_CLK_DISP_DTRC_DIV] = imx_clk_divider2("disp_dtrc_div", "disp_dtrc_pre_div", base + 0xa200, 0, 6);
+ clks[IMX8MM_CLK_DISP_DC8000_DIV] = imx_clk_divider2("disp_dc8000_div", "disp_dc8000_pre_div", base + 0xa280, 0, 6);
+ clks[IMX8MM_CLK_PCIE1_CTRL_DIV] = imx_clk_divider2("pcie1_ctrl_div", "pcie1_ctrl_pre_div", base + 0xa300, 0, 6);
+ clks[IMX8MM_CLK_PCIE1_PHY_DIV] = imx_clk_divider2("pcie1_phy_div", "pcie1_phy_pre_div", base + 0xa380, 0, 6);
+ clks[IMX8MM_CLK_PCIE1_AUX_DIV] = imx_clk_divider2("pcie1_aux_div", "pcie1_aux_pre_div", base + 0xa400, 0, 6);
+ clks[IMX8MM_CLK_DC_PIXEL_DIV] = imx_clk_divider2("dc_pixel_div", "dc_pixel_pre_div", base + 0xa480, 0, 6);
+ clks[IMX8MM_CLK_LCDIF_PIXEL_DIV] = imx_clk_divider2("lcdif_pixel_div", "lcdif_pixel_pre_div", base + 0xa500, 0, 6);
+ clks[IMX8MM_CLK_SAI1_DIV] = imx_clk_divider2("sai1_div", "sai1_pre_div", base + 0xa580, 0, 6);
+ clks[IMX8MM_CLK_SAI2_DIV] = imx_clk_divider2("sai2_div", "sai2_pre_div", base + 0xa600, 0, 6);
+ clks[IMX8MM_CLK_SAI3_DIV] = imx_clk_divider2("sai3_div", "sai3_pre_div", base + 0xa680, 0, 6);
+ clks[IMX8MM_CLK_SAI4_DIV] = imx_clk_divider2("sai4_div", "sai4_pre_div", base + 0xa700, 0, 6);
+ clks[IMX8MM_CLK_SAI5_DIV] = imx_clk_divider2("sai5_div", "sai5_pre_div", base + 0xa780, 0, 6);
+ clks[IMX8MM_CLK_SAI6_DIV] = imx_clk_divider2("sai6_div", "sai6_pre_div", base + 0xa800, 0, 6);
+ clks[IMX8MM_CLK_SPDIF1_DIV] = imx_clk_divider2("spdif1_div", "spdif1_pre_div", base + 0xa880, 0, 6);
+ clks[IMX8MM_CLK_SPDIF2_DIV] = imx_clk_divider2("spdif2_div", "spdif2_pre_div", base + 0xa900, 0, 6);
+ clks[IMX8MM_CLK_ENET_REF_DIV] = imx_clk_divider2("enet_ref_div", "enet_ref_pre_div", base + 0xa980, 0, 6);
+ clks[IMX8MM_CLK_ENET_TIMER_DIV] = imx_clk_divider2("enet_timer_div", "enet_timer_pre_div", base + 0xaa00, 0, 6);
+ clks[IMX8MM_CLK_ENET_PHY_REF_DIV] = imx_clk_divider2("enet_phy_div", "enet_phy_pre_div", base + 0xaa80, 0, 6);
+ clks[IMX8MM_CLK_NAND_DIV] = imx_clk_divider2("nand_div", "nand_pre_div", base + 0xab00, 0, 6);
+ clks[IMX8MM_CLK_QSPI_DIV] = imx_clk_divider2("qspi_div", "qspi_pre_div", base + 0xab80, 0, 6);
+ clks[IMX8MM_CLK_USDHC1_DIV] = imx_clk_divider2("usdhc1_div", "usdhc1_pre_div", base + 0xac00, 0, 6);
+ clks[IMX8MM_CLK_USDHC2_DIV] = imx_clk_divider2("usdhc2_div", "usdhc2_pre_div", base + 0xac80, 0, 6);
+ clks[IMX8MM_CLK_I2C1_DIV] = imx_clk_divider2("i2c1_div", "i2c1_pre_div", base + 0xad00, 0, 6);
+ clks[IMX8MM_CLK_I2C2_DIV] = imx_clk_divider2("i2c2_div", "i2c2_pre_div", base + 0xad80, 0, 6);
+ clks[IMX8MM_CLK_I2C3_DIV] = imx_clk_divider2("i2c3_div", "i2c3_pre_div", base + 0xae00, 0, 6);
+ clks[IMX8MM_CLK_I2C4_DIV] = imx_clk_divider2("i2c4_div", "i2c4_pre_div", base + 0xae80, 0, 6);
+ clks[IMX8MM_CLK_UART1_DIV] = imx_clk_divider2("uart1_div", "uart1_pre_div", base + 0xaf00, 0, 6);
+ clks[IMX8MM_CLK_UART2_DIV] = imx_clk_divider2("uart2_div", "uart2_pre_div", base + 0xaf80, 0, 6);
+ clks[IMX8MM_CLK_UART3_DIV] = imx_clk_divider2("uart3_div", "uart3_pre_div", base + 0xb000, 0, 6);
+ clks[IMX8MM_CLK_UART4_DIV] = imx_clk_divider2("uart4_div", "uart4_pre_div", base + 0xb080, 0, 6);
+ clks[IMX8MM_CLK_USB_CORE_REF_DIV] = imx_clk_divider2("usb_core_ref_div", "usb_core_ref_pre_div", base + 0xb100, 0, 6);
+ clks[IMX8MM_CLK_USB_PHY_REF_DIV] = imx_clk_divider2("usb_phy_ref_div", "usb_phy_ref_pre_div", base + 0xb180, 0, 6);
+ clks[IMX8MM_CLK_ECSPI1_DIV] = imx_clk_divider2("ecspi1_div", "ecspi1_pre_div", base + 0xb280, 0, 6);
+ clks[IMX8MM_CLK_ECSPI2_DIV] = imx_clk_divider2("ecspi2_div", "ecspi2_pre_div", base + 0xb300, 0, 6);
+ clks[IMX8MM_CLK_PWM1_DIV] = imx_clk_divider2("pwm1_div", "pwm1_pre_div", base + 0xb380, 0, 6);
+ clks[IMX8MM_CLK_PWM2_DIV] = imx_clk_divider2("pwm2_div", "pwm2_pre_div", base + 0xb400, 0, 6);
+ clks[IMX8MM_CLK_PWM3_DIV] = imx_clk_divider2("pwm3_div", "pwm3_pre_div", base + 0xb480, 0, 6);
+ clks[IMX8MM_CLK_PWM4_DIV] = imx_clk_divider2("pwm4_div", "pwm4_pre_div", base + 0xb500, 0, 6);
+ clks[IMX8MM_CLK_GPT1_DIV] = imx_clk_divider2("gpt1_div", "gpt1_pre_div", base + 0xb580, 0, 6);
+ clks[IMX8MM_CLK_WDOG_DIV] = imx_clk_divider2("wdog_div", "wdog_pre_div", base + 0xb900, 0, 6);
+ clks[IMX8MM_CLK_WRCLK_DIV] = imx_clk_divider2("wrclk_div", "wrclk_pre_div", base + 0xb980, 0, 6);
+ clks[IMX8MM_CLK_CLKO1_DIV] = imx_clk_divider2("clko1_div", "clko1_pre_div", base + 0xba00, 0, 6);
+ clks[IMX8MM_CLK_DSI_CORE_DIV] = imx_clk_divider2("dsi_core_div", "dsi_core_pre_div", base + 0xbb00, 0, 6);
+ clks[IMX8MM_CLK_DSI_PHY_REF_DIV] = imx_clk_divider2("dsi_phy_ref_div", "dsi_phy_ref_pre_div", base + 0xbb80, 0, 6);
+ clks[IMX8MM_CLK_DSI_DBI_DIV] = imx_clk_divider2("dsi_dbi_div", "dsi_dbi_pre_div", base + 0xbc00, 0, 6);
+ clks[IMX8MM_CLK_USDHC3_DIV] = imx_clk_divider2("usdhc3_div", "usdhc3_pre_div", base + 0xbc80, 0, 6);
+ clks[IMX8MM_CLK_CSI1_CORE_DIV] = imx_clk_divider2("csi1_core_div", "csi1_core_pre_div", base + 0xbd00, 0, 6);
+ clks[IMX8MM_CLK_CSI1_PHY_REF_DIV] = imx_clk_divider2("csi1_phy_ref_div", "csi1_phy_ref_pre_div", base + 0xbd80, 0, 6);
+ clks[IMX8MM_CLK_CSI1_ESC_DIV] = imx_clk_divider2("csi1_esc_div", "csi1_esc_pre_div", base + 0xbe00, 0, 6);
+ clks[IMX8MM_CLK_CSI2_CORE_DIV] = imx_clk_divider2("csi2_core_div", "csi2_core_pre_div", base + 0xbe80, 0, 6);
+ clks[IMX8MM_CLK_CSI2_PHY_REF_DIV] = imx_clk_divider2("csi2_phy_ref_div", "csi2_phy_ref_pre_div", base + 0xbf00, 0, 6);
+ clks[IMX8MM_CLK_CSI2_ESC_DIV] = imx_clk_divider2("csi2_esc_div", "csi2_esc_pre_div", base + 0xbf80, 0, 6);
+ clks[IMX8MM_CLK_PCIE2_CTRL_DIV] = imx_clk_divider2("pcie2_ctrl_div", "pcie2_ctrl_pre_div", base + 0xc000, 0, 6);
+ clks[IMX8MM_CLK_PCIE2_PHY_DIV] = imx_clk_divider2("pcie2_phy_div", "pcie2_phy_pre_div", base + 0xc080, 0, 6);
+ clks[IMX8MM_CLK_PCIE2_AUX_DIV] = imx_clk_divider2("pcie2_aux_div", "pcie2_aux_pre_div", base + 0xc100, 0, 6);
+ clks[IMX8MM_CLK_ECSPI3_DIV] = imx_clk_divider2("ecspi3_div", "ecspi3_pre_div", base + 0xc180, 0, 6);
+ clks[IMX8MM_CLK_PDM_DIV] = imx_clk_divider2("pdm_div", "pdm_pre_div", base + 0xc200, 0, 6);
+ clks[IMX8MM_CLK_VPU_H1_DIV] = imx_clk_divider2("vpu_h1_div", "vpu_h1_pre_div", base + 0xc280, 0, 6);
+
+ /* CCGR */
+ clks[IMX8MM_CLK_ECSPI1_ROOT] = imx_clk_gate4("ecspi1_root_clk", "ecspi1_div", base + 0x4070, 0);
+ clks[IMX8MM_CLK_ECSPI2_ROOT] = imx_clk_gate4("ecspi2_root_clk", "ecspi2_div", base + 0x4080, 0);
+ clks[IMX8MM_CLK_ECSPI3_ROOT] = imx_clk_gate4("ecspi3_root_clk", "ecspi3_div", base + 0x4090, 0);
+ clks[IMX8MM_CLK_ENET1_ROOT] = imx_clk_gate4("enet1_root_clk", "enet_axi_div", base + 0x40a0, 0);
+ clks[IMX8MM_CLK_GPT1_ROOT] = imx_clk_gate4("gpt1_root_clk", "gpt1_div", base + 0x4100, 0);
+ clks[IMX8MM_CLK_I2C1_ROOT] = imx_clk_gate4("i2c1_root_clk", "i2c1_div", base + 0x4170, 0);
+ clks[IMX8MM_CLK_I2C2_ROOT] = imx_clk_gate4("i2c2_root_clk", "i2c2_div", base + 0x4180, 0);
+ clks[IMX8MM_CLK_I2C3_ROOT] = imx_clk_gate4("i2c3_root_clk", "i2c3_div", base + 0x4190, 0);
+ clks[IMX8MM_CLK_I2C4_ROOT] = imx_clk_gate4("i2c4_root_clk", "i2c4_div", base + 0x41a0, 0);
+ clks[IMX8MM_CLK_MU_ROOT] = imx_clk_gate4("mu_root_clk", "ipg_root", base + 0x4210, 0);
+ clks[IMX8MM_CLK_OCOTP_ROOT] = imx_clk_gate4("ocotp_root_clk", "ipg_root", base + 0x4220, 0);
+ clks[IMX8MM_CLK_PCIE1_ROOT] = imx_clk_gate4("pcie1_root_clk", "pcie1_ctrl_div", base + 0x4250, 0);
+ clks[IMX8MM_CLK_PWM1_ROOT] = imx_clk_gate4("pwm1_root_clk", "pwm1_div", base + 0x4280, 0);
+ clks[IMX8MM_CLK_PWM2_ROOT] = imx_clk_gate4("pwm2_root_clk", "pwm2_div", base + 0x4290, 0);
+ clks[IMX8MM_CLK_PWM3_ROOT] = imx_clk_gate4("pwm3_root_clk", "pwm3_div", base + 0x42a0, 0);
+ clks[IMX8MM_CLK_PWM4_ROOT] = imx_clk_gate4("pwm4_root_clk", "pwm4_div", base + 0x42b0, 0);
+ clks[IMX8MM_CLK_QSPI_ROOT] = imx_clk_gate4("qspi_root_clk", "qspi_div", base + 0x42f0, 0);
+ clks[IMX8MM_CLK_NAND_ROOT] = imx_clk_gate2_shared2("nand_root_clk", "nand_div", base + 0x4300, 0, &share_count_nand);
+ clks[IMX8MM_CLK_NAND_USDHC_BUS_RAWNAND_CLK] = imx_clk_gate2_shared2("nand_usdhc_rawnand_clk", "nand_usdhc_bus_div", base + 0x4300, 0, &share_count_nand);
+ clks[IMX8MM_CLK_SAI1_ROOT] = imx_clk_gate2_shared2("sai1_root_clk", "sai1_div", base + 0x4330, 0, &share_count_sai1);
+ clks[IMX8MM_CLK_SAI1_IPG] = imx_clk_gate2_shared2("sai1_ipg_clk", "ipg_audio_root", base + 0x4330, 0, &share_count_sai1);
+ clks[IMX8MM_CLK_SAI2_ROOT] = imx_clk_gate2_shared2("sai2_root_clk", "sai2_div", base + 0x4340, 0, &share_count_sai2);
+ clks[IMX8MM_CLK_SAI2_IPG] = imx_clk_gate2_shared2("sai2_ipg_clk", "ipg_audio_root", base + 0x4340, 0, &share_count_sai2);
+ clks[IMX8MM_CLK_SAI3_ROOT] = imx_clk_gate2_shared2("sai3_root_clk", "sai3_div", base + 0x4350, 0, &share_count_sai3);
+ clks[IMX8MM_CLK_SAI3_IPG] = imx_clk_gate2_shared2("sai3_ipg_clk", "ipg_audio_root", base + 0x4350, 0, &share_count_sai3);
+ clks[IMX8MM_CLK_SAI4_ROOT] = imx_clk_gate2_shared2("sai4_root_clk", "sai4_div", base + 0x4360, 0, &share_count_sai4);
+ clks[IMX8MM_CLK_SAI4_IPG] = imx_clk_gate2_shared2("sai4_ipg_clk", "ipg_audio_root", base + 0x4360, 0, &share_count_sai4);
+ clks[IMX8MM_CLK_SAI5_ROOT] = imx_clk_gate2_shared2("sai5_root_clk", "sai5_div", base + 0x4370, 0, &share_count_sai5);
+ clks[IMX8MM_CLK_SAI5_IPG] = imx_clk_gate2_shared2("sai5_ipg_clk", "ipg_audio_root", base + 0x4370, 0, &share_count_sai5);
+ clks[IMX8MM_CLK_SAI6_ROOT] = imx_clk_gate2_shared2("sai6_root_clk", "sai6_div", base + 0x4380, 0, &share_count_sai6);
+ clks[IMX8MM_CLK_SAI6_IPG] = imx_clk_gate2_shared2("sai6_ipg_clk", "ipg_audio_root", base + 0x4380, 0, &share_count_sai6);
+ clks[IMX8MM_CLK_SIM_HSIO] = imx_clk_gate4("sim_hsio_clk", "usb_bus_div", base + 0x4450, 0);
+ clks[IMX8MM_CLK_UART1_ROOT] = imx_clk_gate4("uart1_root_clk", "uart1_div", base + 0x4490, 0);
+ clks[IMX8MM_CLK_UART2_ROOT] = imx_clk_gate4("uart2_root_clk", "uart2_div", base + 0x44a0, 0);
+ clks[IMX8MM_CLK_UART3_ROOT] = imx_clk_gate4("uart3_root_clk", "uart3_div", base + 0x44b0, 0);
+ clks[IMX8MM_CLK_UART4_ROOT] = imx_clk_gate4("uart4_root_clk", "uart4_div", base + 0x44c0, 0);
+ clks[IMX8MM_CLK_USB1_CTRL_ROOT] = imx_clk_gate4("usb1_ctrl_root_clk", "usb_core_ref_div", base + 0x44d0, 0);
+ clks[IMX8MM_CLK_GPU3D_ROOT] = imx_clk_gate4("gpu3d_root_clk", "gpu3d_div", base + 0x44f0, 0);
+ clks[IMX8MM_CLK_USDHC1_ROOT] = imx_clk_gate4("usdhc1_root_clk", "usdhc1_div", base + 0x4510, 0);
+ clks[IMX8MM_CLK_USDHC2_ROOT] = imx_clk_gate4("usdhc2_root_clk", "usdhc2_div", base + 0x4520, 0);
+ clks[IMX8MM_CLK_WDOG1_ROOT] = imx_clk_gate4("wdog1_root_clk", "wdog_div", base + 0x4530, 0);
+ clks[IMX8MM_CLK_WDOG2_ROOT] = imx_clk_gate4("wdog2_root_clk", "wdog_div", base + 0x4540, 0);
+ clks[IMX8MM_CLK_WDOG3_ROOT] = imx_clk_gate4("wdog3_root_clk", "wdog_div", base + 0x4550, 0);
+ clks[IMX8MM_CLK_VPU_G1_ROOT] = imx_clk_gate4("vpu_g1_root_clk", "vpu_g1_div", base + 0x4560, 0);
+ clks[IMX8MM_CLK_GPU_BUS_ROOT] = imx_clk_gate4("gpu_root_clk", "gpu_axi_div", base + 0x4570, 0);
+ clks[IMX8MM_CLK_VPU_H1_ROOT] = imx_clk_gate4("vpu_h1_root_clk", "vpu_h1_div", base + 0x4590, 0);
+ clks[IMX8MM_CLK_VPU_G2_ROOT] = imx_clk_gate4("vpu_g2_root_clk", "vpu_g2_div", base + 0x45a0, 0);
+ clks[IMX8MM_CLK_PDM_ROOT] = imx_clk_gate2_shared2("pdm_root_clk", "pdm_div", base + 0x45b0, 0, &share_count_pdm);
+ clks[IMX8MM_CLK_PDM_IPG] = imx_clk_gate2_shared2("pdm_ipg_clk", "ipg_audio_root", base + 0x45b0, 0, &share_count_pdm);
+ clks[IMX8MM_CLK_DISP_ROOT] = imx_clk_gate2_shared2("disp_root_clk", "disp_dc8000_div", base + 0x45d0, 0, &share_count_dcss);
+ clks[IMX8MM_CLK_DISP_AXI_ROOT] = imx_clk_gate2_shared2("disp_axi_root_clk", "disp_axi_div", base + 0x45d0, 0, &share_count_dcss);
+ clks[IMX8MM_CLK_DISP_APB_ROOT] = imx_clk_gate2_shared2("disp_apb_root_clk", "disp_apb_div", base + 0x45d0, 0, &share_count_dcss);
+ clks[IMX8MM_CLK_DISP_RTRM_ROOT] = imx_clk_gate2_shared2("disp_rtrm_root_clk", "disp_rtrm_div", base + 0x45d0, 0, &share_count_dcss);
+ clks[IMX8MM_CLK_USDHC3_ROOT] = imx_clk_gate4("usdhc3_root_clk", "usdhc3_div", base + 0x45e0, 0);
+ clks[IMX8MM_CLK_TMU_ROOT] = imx_clk_gate4("tmu_root_clk", "ipg_root", base + 0x4620, 0);
+ clks[IMX8MM_CLK_VPU_DEC_ROOT] = imx_clk_gate4("vpu_dec_root_clk", "vpu_bus_div", base + 0x4630, 0);
+ clks[IMX8MM_CLK_SDMA1_ROOT] = imx_clk_gate4("sdma1_clk", "ipg_root", base + 0x43a0, 0);
+ clks[IMX8MM_CLK_SDMA2_ROOT] = imx_clk_gate4("sdma2_clk", "ipg_audio_root", base + 0x43b0, 0);
+ clks[IMX8MM_CLK_SDMA3_ROOT] = imx_clk_gate4("sdma3_clk", "ipg_audio_root", base + 0x45f0, 0);
+ clks[IMX8MM_CLK_GPU2D_ROOT] = imx_clk_gate4("gpu2d_root_clk", "gpu2d_div", base + 0x4660, 0);
+ clks[IMX8MM_CLK_CSI1_ROOT] = imx_clk_gate4("csi1_root_clk", "csi1_core_div", base + 0x4650, 0);
+
+ clks[IMX8MM_CLK_GPT_3M] = imx_clk_fixed_factor("gpt_3m", "osc_24m", 1, 8);
+
+ clks[IMX8MM_CLK_DRAM_ALT_ROOT] = imx_clk_fixed_factor("dram_alt_root", "dram_alt_div", 1, 4);
+ clks[IMX8MM_CLK_DRAM_CORE] = imx_clk_mux2("dram_core_clk", base + 0x9800, 24, 1, imx8mm_dram_core_sels, ARRAY_SIZE(imx8mm_dram_core_sels));
+
+ clks[IMX8MM_CLK_ARM] = imx_clk_cpu("arm", "arm_a53_div",
+ clks[IMX8MM_CLK_A53_DIV],
+ clks[IMX8MM_CLK_A53_SRC],
+ clks[IMX8MM_ARM_PLL_OUT],
+ clks[IMX8MM_CLK_24M]);
+
+ for (i = 0; i < IMX8MM_CLK_END; i++)
+ if (IS_ERR(clks[i]))
+ pr_err("i.MX8mm clk %u register failed with %ld\n",
+ i, PTR_ERR(clks[i]));
+
+ clk_data.clks = clks;
+ clk_data.clk_num = ARRAY_SIZE(clks);
+ of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
+
+ if (imx_clk_init_on(ccm_node, clks)) {
+ for (i = 0; i < ARRAY_SIZE(clks_init_on); i++)
+ clk_prepare_enable(clks[clks_init_on[i]]);
+ }
+
+ clk_set_parent(clks[IMX8MM_CLK_AUDIO_AHB_SRC], clks[IMX8MM_SYS_PLL1_800M]);
+ clk_set_rate(clks[IMX8MM_CLK_AUDIO_AHB_DIV], 400000000);
+ clk_set_rate(clks[IMX8MM_CLK_IPG_AUDIO_ROOT], 400000000);
+
+ /* increase NOC clock to design target */
+ clk_set_rate(clks[IMX8MM_SYS_PLL3], 750000000);
+ clk_set_rate(clks[IMX8MM_VIDEO_PLL1], 594000000);
+ clk_set_parent(clks[IMX8MM_CLK_NOC_SRC], clks[IMX8MM_SYS_PLL3_OUT]);
+ clk_set_parent(clks[IMX8MM_CLK_PCIE1_CTRL_SRC], clks[IMX8MM_SYS_PLL2_250M]);
+ clk_set_parent(clks[IMX8MM_CLK_PCIE1_PHY_SRC], clks[IMX8MM_SYS_PLL2_100M]);
+
+ clk_set_parent(clks[IMX8MM_CLK_CSI1_CORE_SRC], clks[IMX8MM_SYS_PLL2_1000M]);
+ clk_set_parent(clks[IMX8MM_CLK_CSI1_PHY_REF_SRC], clks[IMX8MM_SYS_PLL2_1000M]);
+ clk_set_parent(clks[IMX8MM_CLK_CSI1_ESC_SRC], clks[IMX8MM_SYS_PLL1_800M]);
+
+ writel_relaxed(0x2, base + 0x45d0);
+ clk_set_parent(clks[IMX8MM_CLK_DISP_AXI_SRC], clks[IMX8MM_SYS_PLL2_1000M]);
+ clk_set_rate(clks[IMX8MM_CLK_DISP_AXI_PRE_DIV], 500000000);
+ clk_set_parent(clks[IMX8MM_CLK_DISP_APB_SRC], clks[IMX8MM_SYS_PLL1_800M]);
+ clk_set_rate(clks[IMX8MM_CLK_DISP_APB_PRE_DIV], 200000000);
+
+ imx_register_uart_clocks(uart_clks);
+
+ pr_info("i.MX8MM clock driver init done\n");
+}
+
+CLK_OF_DECLARE(imx8mm, "fsl,imx8mm-ccm", imx8mm_clocks_init);
diff --git a/drivers/clk/imx/clk-imx8mq.c b/drivers/clk/imx/clk-imx8mq.c
new file mode 100644
index 000000000000..8ab58946c379
--- /dev/null
+++ b/drivers/clk/imx/clk-imx8mq.c
@@ -0,0 +1,629 @@
+/*
+ * Copyright 2017-2018 NXP.
+ *
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <dt-bindings/clock/imx8mq-clock.h>
+#include <linux/clk.h>
+#include <linux/clkdev.h>
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/types.h>
+#include <soc/imx8/soc.h>
+
+#include "clk.h"
+
+static u32 share_count_sai1;
+static u32 share_count_sai2;
+static u32 share_count_sai3;
+static u32 share_count_sai4;
+static u32 share_count_sai5;
+static u32 share_count_sai6;
+static u32 share_count_dcss;
+static u32 share_count_nand;
+
+static struct clk *clks[IMX8MQ_CLK_END];
+
+static const char *pll_ref_sels[] = { "osc_25m", "osc_27m", "phy_27m", "dummy", };
+static const char *arm_pll_bypass_sels[] = {"arm_pll", "arm_pll_ref_sel", };
+static const char *gpu_pll_bypass_sels[] = {"gpu_pll", "gpu_pll_ref_sel", };
+static const char *vpu_pll_bypass_sels[] = {"vpu_pll", "vpu_pll_ref_sel", };
+static const char *audio_pll1_bypass_sels[] = {"audio_pll1", "audio_pll1_ref_sel", };
+static const char *audio_pll2_bypass_sels[] = {"audio_pll2", "audio_pll2_ref_sel", };
+static const char *video_pll1_bypass_sels[] = {"video_pll1", "video_pll1_ref_sel", };
+
+static const char *sys1_pll_out_sels[] = {"sys1_pll1_ref_sel", };
+static const char *sys2_pll_out_sels[] = {"sys1_pll1_ref_sel", "sys2_pll1_ref_sel", };
+static const char *sys3_pll_out_sels[] = {"sys3_pll1_ref_sel", "sys2_pll1_ref_sel", };
+static const char *dram_pll_out_sels[] = {"dram_pll1_ref_sel", };
+static const char *video2_pll_out_sels[] = {"video2_pll1_ref_sel", };
+/* CCM ROOT */
+static const char *imx8mq_a53_sels[] = {"osc_25m", "arm_pll_out", "sys2_pll_500m", "sys2_pll_1000m",
+ "sys1_pll_800m", "sys1_pll_400m", "audio_pll1_out", "sys3_pll2_out", };
+
+static const char *imx8mq_vpu_sels[] = {"osc_25m", "arm_pll_out", "sys2_pll_500m", "sys2_pll_1000m",
+ "sys1_pll_800m", "sys1_pll_400m", "audio_pll1_out", "vpu_pll_out", };
+
+static const char *imx8mq_gpu_core_sels[] = {"osc_25m", "gpu_pll_out", "sys1_pll_800m", "sys3_pll2_out",
+ "sys2_pll_1000m", "audio_pll1_out", "video_pll1_out", "audio_pll2_out", };
+
+static const char *imx8mq_gpu_shader_sels[] = {"osc_25m", "gpu_pll_out", "sys1_pll_800m", "sys3_pll2_out",
+ "sys2_pll_1000m", "audio_pll1_out", "video_pll1_out", "audio_pll2_out", };
+
+static const char *imx8mq_main_axi_sels[] = {"osc_25m", "sys2_pll_333m", "sys1_pll_800m", "sys2_pll_250m",
+ "sys2_pll_1000m", "audio_pll1_out", "video_pll1_out", "sys1_pll_100m",};
+
+static const char *imx8mq_enet_axi_sels[] = {"osc_25m", "sys1_pll_266m", "sys1_pll_800m", "sys2_pll_250m",
+ "sys2_pll_200m", "audio_pll1_out", "video_pll1_out", "sys3_pll2_out", };
+
+static const char *imx8mq_nand_usdhc_sels[] = {"osc_25m", "sys1_pll_266m", "sys1_pll_800m", "sys2_pll_200m",
+ "sys1_pll_133m", "sys3_pll2_out", "sys2_pll_250m", "audio_pll1_out", };
+
+static const char *imx8mq_vpu_bus_sels[] = {"osc_25m", "sys1_pll_800m", "vpu_pll_out", "audio_pll2_out", "sys3_pll2_out", "sys2_pll_1000m", "sys2_pll_200m", "sys1_pll_100m", };
+
+static const char *imx8mq_disp_axi_sels[] = {"osc_25m", "sys2_pll_125m", "sys1_pll_800m", "sys3_pll2_out", "sys1_pll_400m", "audio_pll2_out", "clk_ext1", "clk_ext4", };
+
+static const char *imx8mq_disp_apb_sels[] = {"osc_25m", "sys2_pll_125m", "sys1_pll_800m", "sys3_pll2_out",
+ "sys1_pll_40m", "audio_pll2_out", "clk_ext1", "clk_ext3", };
+
+static const char *imx8mq_disp_rtrm_sels[] = {"osc_25m", "sys1_pll_800m", "sys2_pll_200m", "sys1_pll_400m",
+ "audio_pll1_out", "video_pll1_out", "clk_ext2", "clk_ext3", };
+
+static const char *imx8mq_usb_bus_sels[] = {"osc_25m", "sys2_pll_500m", "sys1_pll_800m", "sys2_pll_100m",
+ "sys2_pll_200m", "clk_ext2", "clk_ext4", "audio_pll2_out", };
+
+static const char *imx8mq_gpu_axi_sels[] = {"osc_25m", "sys1_pll_800m", "gpu_pll_out", "sys3_pll2_out", "sys2_pll_1000m",
+ "audio_pll1_out", "video_pll1_out", "audio_pll2_out", };
+
+static const char *imx8mq_gpu_ahb_sels[] = {"osc_25m", "sys1_pll_800m", "gpu_pll_out", "sys3_pll2_out", "sys2_pll_1000m",
+ "audio_pll1_out", "video_pll1_out", "audio_pll2_out", };
+
+static const char *imx8mq_noc_sels[] = {"osc_25m", "sys1_pll_800m", "sys3_pll2_out", "sys2_pll_1000m", "sys2_pll_500m",
+ "audio_pll1_out", "video_pll1_out", "audio_pll2_out", };
+
+static const char *imx8mq_noc_apb_sels[] = {"osc_25m", "sys1_pll_400m", "sys3_pll2_out", "sys2_pll_333m", "sys2_pll_200m",
+ "sys1_pll_800m", "audio_pll1_out", "video_pll1_out", };
+
+static const char *imx8mq_ahb_sels[] = {"osc_25m", "sys1_pll_133m", "sys1_pll_800m", "sys1_pll_400m",
+ "sys2_pll_125m", "sys3_pll2_out", "audio_pll1_out", "video_pll1_out", };
+
+static const char *imx8mq_audio_ahb_sels[] = {"osc_25m", "sys2_pll_500m", "sys1_pll_800m", "sys2_pll_1000m",
+ "sys2_pll_166m", "sys3_pll2_out", "audio_pll1_out", "video_pll1_out", };
+
+static const char *imx8mq_dsi_ahb_sels[] = {"osc_25m", "sys2_pll_100m", "sys1_pll_80m", "sys1_pll_800m",
+ "sys2_pll_1000m", "sys3_pll2_out", "clk_ext3", "audio_pll2_out"};
+
+static const char *imx8mq_dram_alt_sels[] = {"osc_25m", "sys1_pll_800m", "sys1_pll_100m", "sys2_pll_500m",
+ "sys2_pll_250m", "sys1_pll_400m", "audio_pll1_out", "sys1_pll_266m", };
+
+static const char *imx8mq_dram_apb_sels[] = {"osc_25m", "sys2_pll_200m", "sys1_pll_40m", "sys1_pll_160m",
+ "sys1_pll_800m", "sys3_pll2_out", "sys2_pll_250m", "audio_pll2_out", };
+
+static const char *imx8mq_vpu_g1_sels[] = {"osc_25m", "vpu_pll_out", "sys1_pll_800m", "sys2_pll_1000m", "sys1_pll_100m", "sys2_pll_125m", "sys3_pll2_out", "audio_pll1_out", };
+
+static const char *imx8mq_vpu_g2_sels[] = {"osc_25m", "vpu_pll_out", "sys1_pll_800m", "sys2_pll_1000m", "sys1_pll_100m", "sys2_pll_125m", "sys3_pll2_out", "audio_pll1_out", };
+
+static const char *imx8mq_disp_dtrc_sels[] = {"osc_25m", "vpu_pll_out", "sys1_pll_800m", "sys2_pll_1000m", "sys1_pll_160m", "sys2_pll_100m", "sys3_pll2_out", "audio_pll2_out", };
+
+static const char *imx8mq_disp_dc8000_sels[] = {"osc_25m", "vpu_pll_out", "sys1_pll_800m", "sys2_pll_1000m", "sys1_pll_160m", "sys2_pll_100m", "sys3_pll2_out", "audio_pll2_out", };
+
+static const char *imx8mq_pcie1_ctrl_sels[] = {"osc_25m", "sys2_pll_250m", "sys2_pll_200m", "sys1_pll_266m",
+ "sys1_pll_800m", "sys2_pll_500m", "sys2_pll_250m", "sys3_pll2_out", };
+
+static const char *imx8mq_pcie1_phy_sels[] = {"osc_25m", "sys2_pll_100m", "sys2_pll_500m", "clk_ext1", "clk_ext2",
+ "clk_ext3", "clk_ext4", };
+
+static const char *imx8mq_pcie1_aux_sels[] = {"osc_25m", "sys2_pll_200m", "sys2_pll_500m", "sys3_pll2_out",
+ "sys2_pll_100m", "sys1_pll_80m", "sys1_pll_160m", "sys1_pll_200m", };
+
+static const char *imx8mq_dc_pixel_sels[] = {"osc_25m", "video_pll1_out", "audio_pll2_out", "audio_pll1_out", "sys1_pll_800m", "sys2_pll_1000m", "sys3_pll2_out", "clk_ext4", };
+
+static const char *imx8mq_lcdif_pixel_sels[] = {"osc_25m", "video_pll1_out", "audio_pll2_out", "audio_pll1_out", "sys1_pll_800m", "sys2_pll_1000m", "sys3_pll2_out", "clk_ext4", };
+
+static const char *imx8mq_sai1_sels[] = {"osc_25m", "audio_pll1_out", "audio_pll2_out", "video_pll1_out", "sys1_pll_133m", "osc_27m", "clk_ext1", "clk_ext2", };
+
+static const char *imx8mq_sai2_sels[] = {"osc_25m", "audio_pll1_out", "audio_pll2_out", "video_pll1_out", "sys1_pll_133m", "osc_27m", "clk_ext2", "clk_ext3", };
+
+static const char *imx8mq_sai3_sels[] = {"osc_25m", "audio_pll1_out", "audio_pll2_out", "video_pll1_out", "sys1_pll_133m", "osc_27m", "clk_ext3", "clk_ext4", };
+
+static const char *imx8mq_sai4_sels[] = {"osc_25m", "audio_pll1_out", "audio_pll2_out", "video_pll1_out", "sys1_pll_133m", "osc_27m", "clk_ext1", "clk_ext2", };
+
+static const char *imx8mq_sai5_sels[] = {"osc_25m", "audio_pll1_out", "audio_pll2_out", "video_pll1_out", "sys1_pll_133m", "osc_27m", "clk_ext2", "clk_ext3", };
+
+static const char *imx8mq_sai6_sels[] = {"osc_25m", "audio_pll1_out", "audio_pll2_out", "video_pll1_out", "sys1_pll_133m", "osc_27m", "clk_ext3", "clk_ext4", };
+
+static const char *imx8mq_spdif1_sels[] = {"osc_25m", "audio_pll1_out", "audio_pll2_out", "video_pll1_out", "sys1_pll_133m", "osc_27m", "clk_ext2", "clk_ext3", };
+
+static const char *imx8mq_spdif2_sels[] = {"osc_25m", "audio_pll1_out", "audio_pll2_out", "video_pll1_out", "sys1_pll_133m", "osc_27m", "clk_ext3", "clk_ext4", };
+
+static const char *imx8mq_enet_ref_sels[] = {"osc_25m", "sys2_pll_125m", "sys2_pll_500m", "sys2_pll_100m",
+ "sys1_pll_160m", "audio_pll1_out", "video_pll1_out", "clk_ext4", };
+
+static const char *imx8mq_enet_timer_sels[] = {"osc_25m", "sys2_pll_100m", "audio_pll1_out", "clk_ext1", "clk_ext2",
+ "clk_ext3", "clk_ext4", "video_pll1_out", };
+
+static const char *imx8mq_enet_phy_sels[] = {"osc_25m", "sys2_pll_50m", "sys2_pll_125m", "sys2_pll_500m",
+ "audio_pll1_out", "video_pll1_out", "audio_pll2_out", };
+
+static const char *imx8mq_nand_sels[] = {"osc_25m", "sys2_pll_500m", "audio_pll1_out", "sys1_pll_400m",
+ "audio_pll2_out", "sys3_pll2_out", "sys2_pll_250m", "video_pll1_out", };
+
+static const char *imx8mq_qspi_sels[] = {"osc_25m", "sys1_pll_400m", "sys1_pll_800m", "sys2_pll_500m",
+ "audio_pll2_out", "sys1_pll_266m", "sys3_pll2_out", "sys1_pll_100m", };
+
+static const char *imx8mq_usdhc1_sels[] = {"osc_25m", "sys1_pll_400m", "sys1_pll_800m", "sys2_pll_500m",
+ "audio_pll2_out", "sys1_pll_266m", "sys3_pll2_out", "sys1_pll_100m", };
+
+static const char *imx8mq_usdhc2_sels[] = {"osc_25m", "sys1_pll_400m", "sys1_pll_800m", "sys2_pll_500m",
+ "audio_pll2_out", "sys1_pll_266m", "sys3_pll2_out", "sys1_pll_100m", };
+
+static const char *imx8mq_i2c1_sels[] = {"osc_25m", "sys1_pll_160m", "sys2_pll_50m", "sys3_pll2_out", "audio_pll1_out",
+ "video_pll1_out", "audio_pll2_out", "sys1_pll_133m", };
+
+static const char *imx8mq_i2c2_sels[] = {"osc_25m", "sys1_pll_160m", "sys2_pll_50m", "sys3_pll2_out", "audio_pll1_out",
+ "video_pll1_out", "audio_pll2_out", "sys1_pll_133m", };
+
+static const char *imx8mq_i2c3_sels[] = {"osc_25m", "sys1_pll_160m", "sys2_pll_50m", "sys3_pll2_out", "audio_pll1_out",
+ "video_pll1_out", "audio_pll2_out", "sys1_pll_133m", };
+
+static const char *imx8mq_i2c4_sels[] = {"osc_25m", "sys1_pll_160m", "sys2_pll_50m", "sys3_pll2_out", "audio_pll1_out",
+ "video_pll1_out", "audio_pll2_out", "sys1_pll_133m", };
+
+static const char *imx8mq_uart1_sels[] = {"osc_25m", "sys1_pll_80m", "sys2_pll_200m", "sys2_pll_100m",
+ "sys3_pll2_out", "clk_ext2", "clk_ext4", "audio_pll2_out", };
+
+static const char *imx8mq_uart2_sels[] = {"osc_25m", "sys1_pll_80m", "sys2_pll_200m", "sys2_pll_100m",
+ "sys3_pll2_out", "clk_ext2", "clk_ext3", "audio_pll2_out", };
+
+static const char *imx8mq_uart3_sels[] = {"osc_25m", "sys1_pll_80m", "sys2_pll_200m", "sys2_pll_100m",
+ "sys3_pll2_out", "clk_ext2", "clk_ext4", "audio_pll2_out", };
+
+static const char *imx8mq_uart4_sels[] = {"osc_25m", "sys1_pll_80m", "sys2_pll_200m", "sys2_pll_100m",
+ "sys3_pll2_out", "clk_ext2", "clk_ext3", "audio_pll2_out", };
+
+static const char *imx8mq_usb_core_sels[] = {"osc_25m", "sys1_pll_100m", "sys1_pll_40m", "sys2_pll_100m",
+ "sys2_pll_200m", "clk_ext2", "clk_ext3", "audio_pll2_out", };
+
+static const char *imx8mq_usb_phy_sels[] = {"osc_25m", "sys1_pll_100m", "sys1_pll_40m", "sys2_pll_100m",
+ "sys2_pll_200m", "clk_ext2", "clk_ext3", "audio_pll2_out", };
+
+static const char *imx8mq_ecspi1_sels[] = {"osc_25m", "sys2_pll_200m", "sys1_pll_40m", "sys1_pll_160m",
+ "sys1_pll_800m", "sys3_pll2_out", "sys2_pll_250m", "audio_pll2_out", };
+
+static const char *imx8mq_ecspi2_sels[] = {"osc_25m", "sys2_pll_200m", "sys1_pll_40m", "sys1_pll_160m",
+ "sys1_pll_800m", "sys3_pll2_out", "sys2_pll_250m", "audio_pll2_out", };
+
+static const char *imx8mq_pwm1_sels[] = {"osc_25m", "sys2_pll_100m", "sys1_pll_160m", "sys1_pll_40m",
+ "sys3_pll2_out", "clk_ext1", "sys1_pll_80m", "video_pll1_out", };
+
+static const char *imx8mq_pwm2_sels[] = {"osc_25m", "sys2_pll_100m", "sys1_pll_160m", "sys1_pll_40m",
+ "sys3_pll2_out", "clk_ext1", "sys1_pll_80m", "video_pll1_out", };
+
+static const char *imx8mq_pwm3_sels[] = {"osc_25m", "sys2_pll_100m", "sys1_pll_160m", "sys1_pll_40m",
+ "sys3_pll2_out", "clk_ext2", "sys1_pll_80m", "video_pll1_out", };
+
+static const char *imx8mq_pwm4_sels[] = {"osc_25m", "sys2_pll_100m", "sys1_pll_160m", "sys1_pll_40m",
+ "sys3_pll2_out", "clk_ext2", "sys1_pll_80m", "video_pll1_out", };
+
+static const char *imx8mq_gpt1_sels[] = {"osc_25m", "sys2_pll_100m", "sys1_pll_400m", "sys1_pll_40m",
+ "sys1_pll_80m", "audio_pll1_out", "clk_ext1", };
+
+static const char *imx8mq_wdog_sels[] = {"osc_25m", "sys1_pll_133m", "sys1_pll_160m", "vpu_pll_out",
+ "sys2_pll_125m", "sys3_pll2_out", "sys1_pll_80m", "sys2_pll_166m", };
+
+static const char *imx8mq_wrclk_sels[] = {"osc_25m", "sys1_pll_40m", "vpu_pll_out", "sys3_pll2_out", "sys2_pll_200m",
+ "sys1_pll_266m", "sys2_pll_500m", "sys1_pll_100m", };
+
+static const char *imx8mq_dsi_core_sels[] = {"osc_25m", "sys1_pll_266m", "sys2_pll_250m", "sys1_pll_800m",
+ "sys2_pll_1000m", "sys3_pll2_out", "audio_pll2_out", "video_pll1_out", };
+
+static const char *imx8mq_dsi_phy_sels[] = {"osc_25m", "sys2_pll_125m", "sys2_pll_100m", "sys1_pll_800m",
+ "sys2_pll_1000m", "clk_ext2", "audio_pll2_out", "video_pll1_out", };
+
+static const char *imx8mq_dsi_dbi_sels[] = {"osc_25m", "sys1_pll_266m", "sys2_pll_100m", "sys1_pll_800m",
+ "sys2_pll_1000m", "sys3_pll2_out", "audio_pll2_out", "video_pll1_out", };
+
+static const char *imx8mq_dsi_esc_sels[] = {"osc_25m", "sys2_pll_100m", "sys1_pll_80m", "sys1_pll_800m",
+ "sys2_pll_1000m", "sys3_pll2_out", "clk_ext3", "audio_pll2_out", };
+
+static const char *imx8mq_csi1_core_sels[] = {"osc_25m", "sys1_pll_266m", "sys2_pll_250m", "sys1_pll_800m",
+ "sys2_pll_1000m", "sys3_pll2_out", "audio_pll2_out", "video_pll1_out", };
+
+static const char *imx8mq_csi1_phy_sels[] = {"osc_25m", "sys2_pll_125m", "sys2_pll_100m", "sys1_pll_800m",
+ "sys2_pll_1000m", "clk_ext2", "audio_pll2_out", "video_pll1_out", };
+
+static const char *imx8mq_csi1_esc_sels[] = {"osc_25m", "sys2_pll_100m", "sys1_pll_80m", "sys1_pll_800m",
+ "sys2_pll_1000m", "sys3_pll2_out", "clk_ext3", "audio_pll2_out", };
+
+static const char *imx8mq_csi2_core_sels[] = {"osc_25m", "sys1_pll_266m", "sys2_pll_250m", "sys1_pll_800m",
+ "sys2_pll_1000m", "sys3_pll2_out", "audio_pll2_out", "video_pll1_out", };
+
+static const char *imx8mq_csi2_phy_sels[] = {"osc_25m", "sys2_pll_125m", "sys2_pll_100m", "sys1_pll_800m",
+ "sys2_pll_1000m", "clk_ext2", "audio_pll2_out", "video_pll1_out", };
+
+static const char *imx8mq_csi2_esc_sels[] = {"osc_25m", "sys2_pll_100m", "sys1_pll_80m", "sys1_pll_800m",
+ "sys2_pll_1000m", "sys3_pll2_out", "clk_ext3", "audio_pll2_out", };
+
+static const char *imx8mq_pcie2_ctrl_sels[] = {"osc_25m", "sys2_pll_250m", "sys2_pll_200m", "sys1_pll_266m",
+ "sys1_pll_800m", "sys2_pll_500m", "sys2_pll_333m", "sys3_pll2_out", };
+
+static const char *imx8mq_pcie2_phy_sels[] = {"osc_25m", "sys2_pll_100m", "sys2_pll_500m", "clk_ext1",
+ "clk_ext2", "clk_ext3", "clk_ext4", "sys1_pll_400m", };
+
+static const char *imx8mq_pcie2_aux_sels[] = {"osc_25m", "sys2_pll_200m", "sys2_pll_50m", "sys3_pll2_out",
+ "sys2_pll_100m", "sys1_pll_80m", "sys1_pll_160m", "sys1_pll_200m", };
+
+static const char *imx8mq_ecspi3_sels[] = {"osc_25m", "sys2_pll_200m", "sys1_pll_40m", "sys1_pll_160m",
+ "sys1_pll_800m", "sys3_pll2_out", "sys2_pll_250m", "audio_pll2_out", };
+static const char *imx8mq_dram_core_sels[] = {"dram_pll_out", "dram_alt_root", };
+
+static const char *imx8mq_clko2_sels[] = {"osc_25m", "sys2_pll_200m", "sys1_pll_400m", "sys2_pll_166m", "audio_pll1_out",
+ "video_pll1_out", "ckil", };
+
+static int const clks_init_on[] __initconst = {
+ IMX8MQ_CLK_DRAM_CORE, IMX8MQ_CLK_AHB,
+ IMX8MQ_CLK_NOC, IMX8MQ_CLK_NOC_APB,
+ IMX8MQ_CLK_USB_BUS,
+ IMX8MQ_CLK_MAIN_AXI, IMX8MQ_CLK_A53_CG,
+ IMX8MQ_CLK_TMU_ROOT,
+ IMX8MQ_CLK_DRAM_APB, IMX8MQ_DRAM_PLL_OUT,
+};
+
+static struct clk ** const uart_clks[] __initconst = {
+ &clks[IMX8MQ_CLK_UART1_ROOT],
+ &clks[IMX8MQ_CLK_UART2_ROOT],
+ &clks[IMX8MQ_CLK_UART3_ROOT],
+ &clks[IMX8MQ_CLK_UART4_ROOT],
+ NULL
+};
+
+static struct clk_onecell_data clk_data;
+
+static int __init imx_clk_init_on(struct device_node *np,
+ struct clk * const clks[])
+{
+ u32 *array;
+ int i, ret, elems;
+
+ elems = of_property_count_u32_elems(np, "init-on-array");
+ if (elems < 0)
+ return elems;
+ array = kzalloc(elems * sizeof(elems), GFP_KERNEL);
+ if (IS_ERR_OR_NULL(array))
+ return PTR_ERR(array);
+
+ ret = of_property_read_u32_array(np, "init-on-array", array, elems);
+ if (ret)
+ return ret;
+
+ for (i = 0; i < elems; i++) {
+ ret = clk_prepare_enable(clks[array[i]]);
+ if (ret)
+ pr_err("clk_prepare_enable failed %d\n", array[i]);
+ }
+
+ return 0;
+}
+
+static void __init imx8mq_clocks_init(struct device_node *ccm_node)
+{
+ struct device_node *np;
+ void __iomem *base;
+ int i;
+
+ check_m4_enabled();
+
+ clks[IMX8MQ_CLK_DUMMY] = imx_clk_fixed("dummy", 0);
+ clks[IMX8MQ_CLK_32K] = of_clk_get_by_name(ccm_node, "ckil");
+ clks[IMX8MQ_CLK_25M] = of_clk_get_by_name(ccm_node, "osc_25m");
+ clks[IMX8MQ_CLK_27M] = of_clk_get_by_name(ccm_node, "osc_27m");
+ clks[IMX8MQ_CLK_EXT1] = of_clk_get_by_name(ccm_node, "clk_ext1");
+ clks[IMX8MQ_CLK_EXT2] = of_clk_get_by_name(ccm_node, "clk_ext2");
+ clks[IMX8MQ_CLK_EXT3] = of_clk_get_by_name(ccm_node, "clk_ext3");
+ clks[IMX8MQ_CLK_EXT4] = of_clk_get_by_name(ccm_node, "clk_ext4");
+ clks[IMX8MQ_CLK_PHY_27MHZ] = imx_clk_fixed("phy_27m", 27000000);
+
+ np = of_find_compatible_node(NULL, NULL, "fsl,imx8mq-anatop");
+ base = of_iomap(np, 0);
+ WARN_ON(!base);
+
+ clks[IMX8MQ_ARM_PLL_REF_SEL] = imx_clk_mux("arm_pll_ref_sel", base + 0x28, 16, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+ clks[IMX8MQ_GPU_PLL_REF_SEL] = imx_clk_mux("gpu_pll_ref_sel", base + 0x18, 16, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+ clks[IMX8MQ_VPU_PLL_REF_SEL] = imx_clk_mux("vpu_pll_ref_sel", base + 0x20, 16, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+ clks[IMX8MQ_AUDIO_PLL1_REF_SEL] = imx_clk_mux("audio_pll1_ref_sel", base + 0x0, 16, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+ clks[IMX8MQ_AUDIO_PLL2_REF_SEL] = imx_clk_mux("audio_pll2_ref_sel", base + 0x8, 16, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+ clks[IMX8MQ_VIDEO_PLL1_REF_SEL] = imx_clk_mux("video_pll1_ref_sel", base + 0x10, 16, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+ clks[IMX8MQ_SYS1_PLL1_REF_SEL] = imx_clk_mux("sys1_pll1_ref_sel", base + 0x30, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+ clks[IMX8MQ_SYS2_PLL1_REF_SEL] = imx_clk_mux("sys2_pll1_ref_sel", base + 0x3c, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+ clks[IMX8MQ_SYS3_PLL1_REF_SEL] = imx_clk_mux("sys3_pll1_ref_sel", base + 0x48, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+ clks[IMX8MQ_DRAM_PLL1_REF_SEL] = imx_clk_mux("dram_pll1_ref_sel", base + 0x60, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+ clks[IMX8MQ_VIDEO2_PLL1_REF_SEL] = imx_clk_mux("video2_pll1_ref_sel", base + 0x54, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+
+ clks[IMX8MQ_ARM_PLL_REF_DIV] = imx_clk_divider("arm_pll_ref_div", "arm_pll_ref_sel", base + 0x28, 5, 6);
+ clks[IMX8MQ_GPU_PLL_REF_DIV] = imx_clk_divider("gpu_pll_ref_div", "gpu_pll_ref_sel", base + 0x18, 5, 6);
+ clks[IMX8MQ_VPU_PLL_REF_DIV] = imx_clk_divider("vpu_pll_ref_div", "vpu_pll_ref_sel", base + 0x20, 5, 6);
+ clks[IMX8MQ_AUDIO_PLL1_REF_DIV] = imx_clk_divider("audio_pll1_ref_div", "audio_pll1_ref_sel", base + 0x0, 5, 6);
+ clks[IMX8MQ_AUDIO_PLL2_REF_DIV] = imx_clk_divider("audio_pll2_ref_div", "audio_pll2_ref_sel", base + 0x8, 5, 6);
+ clks[IMX8MQ_VIDEO_PLL1_REF_DIV] = imx_clk_divider("video_pll1_ref_div", "video_pll1_ref_sel", base + 0x10, 5, 6);
+
+ clks[IMX8MQ_ARM_PLL] = imx_clk_frac_pll("arm_pll", "arm_pll_ref_div", base + 0x28);
+ clks[IMX8MQ_GPU_PLL] = imx_clk_frac_pll("gpu_pll", "gpu_pll_ref_div", base + 0x18);
+ clks[IMX8MQ_VPU_PLL] = imx_clk_frac_pll("vpu_pll", "vpu_pll_ref_div", base + 0x20);
+ clks[IMX8MQ_AUDIO_PLL1] = imx_clk_frac_pll("audio_pll1", "audio_pll1_ref_div", base + 0x0);
+ clks[IMX8MQ_AUDIO_PLL2] = imx_clk_frac_pll("audio_pll2", "audio_pll2_ref_div", base + 0x8);
+ clks[IMX8MQ_VIDEO_PLL1] = imx_clk_frac_pll("video_pll1", "video_pll1_ref_div", base + 0x10);
+
+ /* PLL bypass out */
+ clks[IMX8MQ_ARM_PLL_BYPASS] = imx_clk_mux("arm_pll_bypass", base + 0x28, 14, 1, arm_pll_bypass_sels, ARRAY_SIZE(arm_pll_bypass_sels));
+ clks[IMX8MQ_GPU_PLL_BYPASS] = imx_clk_mux("gpu_pll_bypass", base + 0x18, 14, 1, gpu_pll_bypass_sels, ARRAY_SIZE(gpu_pll_bypass_sels));
+ clks[IMX8MQ_VPU_PLL_BYPASS] = imx_clk_mux("vpu_pll_bypass", base + 0x20, 14, 1, vpu_pll_bypass_sels, ARRAY_SIZE(vpu_pll_bypass_sels));
+ clks[IMX8MQ_AUDIO_PLL1_BYPASS] = imx_clk_mux("audio_pll1_bypass", base + 0x0, 14, 1, audio_pll1_bypass_sels, ARRAY_SIZE(audio_pll1_bypass_sels));
+ clks[IMX8MQ_AUDIO_PLL2_BYPASS] = imx_clk_mux("audio_pll2_bypass", base + 0x8, 14, 1, audio_pll2_bypass_sels, ARRAY_SIZE(audio_pll2_bypass_sels));
+ clks[IMX8MQ_VIDEO_PLL1_BYPASS] = imx_clk_mux("video_pll1_bypass", base + 0x10, 14, 1, video_pll1_bypass_sels, ARRAY_SIZE(video_pll1_bypass_sels));
+
+ /* unbypass all the plls */
+ clk_set_parent(clks[IMX8MQ_GPU_PLL_BYPASS], clks[IMX8MQ_GPU_PLL]);
+ clk_set_parent(clks[IMX8MQ_VPU_PLL_BYPASS], clks[IMX8MQ_VPU_PLL]);
+ clk_set_parent(clks[IMX8MQ_AUDIO_PLL1_BYPASS], clks[IMX8MQ_AUDIO_PLL1]);
+ clk_set_parent(clks[IMX8MQ_AUDIO_PLL2_BYPASS], clks[IMX8MQ_AUDIO_PLL2]);
+ clk_set_parent(clks[IMX8MQ_VIDEO_PLL1_BYPASS], clks[IMX8MQ_VIDEO_PLL1]);
+
+ /* PLL OUT GATE */
+ clks[IMX8MQ_ARM_PLL_OUT] = imx_clk_gate("arm_pll_out", "arm_pll_bypass", base + 0x28, 21);
+ clks[IMX8MQ_GPU_PLL_OUT] = imx_clk_gate("gpu_pll_out", "gpu_pll_bypass", base + 0x18, 21);
+ clks[IMX8MQ_VPU_PLL_OUT] = imx_clk_gate("vpu_pll_out", "vpu_pll_bypass", base + 0x20, 21);
+ clks[IMX8MQ_AUDIO_PLL1_OUT] = imx_clk_gate("audio_pll1_out", "audio_pll1_bypass", base + 0x0, 21);
+ clks[IMX8MQ_AUDIO_PLL2_OUT] = imx_clk_gate("audio_pll2_out", "audio_pll2_bypass", base + 0x8, 21);
+ clks[IMX8MQ_VIDEO_PLL1_OUT] = imx_clk_gate("video_pll1_out", "video_pll1_bypass", base + 0x10, 21);
+
+ clks[IMX8MQ_SYS1_PLL_OUT] = imx_clk_sccg_pll("sys1_pll_out", sys1_pll_out_sels, ARRAY_SIZE(sys1_pll_out_sels), 0, 0, 0, base + 0x30, CLK_IS_CRITICAL);
+ clks[IMX8MQ_SYS2_PLL_OUT] = imx_clk_sccg_pll("sys2_pll_out", sys2_pll_out_sels, ARRAY_SIZE(sys2_pll_out_sels), 0, 0, 1, base + 0x3c, CLK_IS_CRITICAL);
+ clks[IMX8MQ_SYS3_PLL_OUT] = imx_clk_sccg_pll("sys3_pll_out", sys3_pll_out_sels, ARRAY_SIZE(sys3_pll_out_sels), 0, 0, 1, base + 0x48, CLK_IS_CRITICAL);
+ clks[IMX8MQ_DRAM_PLL_OUT] = imx_clk_sccg_pll("dram_pll_out", dram_pll_out_sels, ARRAY_SIZE(dram_pll_out_sels), 0, 0, 0, base + 0x60, CLK_IS_CRITICAL);
+ clks[IMX8MQ_VIDEO2_PLL_OUT] = imx_clk_sccg_pll("video2_pll_out", video2_pll_out_sels, ARRAY_SIZE(video2_pll_out_sels), 0, 0, 0, base + 0x54, 0);
+
+ /* SYS PLL fixed output */
+ clks[IMX8MQ_SYS1_PLL_40M] = imx_clk_fixed_factor("sys1_pll_40m", "sys1_pll_out", 1, 20);
+ clks[IMX8MQ_SYS1_PLL_80M] = imx_clk_fixed_factor("sys1_pll_80m", "sys1_pll_out", 1, 10);
+ clks[IMX8MQ_SYS1_PLL_100M] = imx_clk_fixed_factor("sys1_pll_100m", "sys1_pll_out", 1, 8);
+ clks[IMX8MQ_SYS1_PLL_133M] = imx_clk_fixed_factor("sys1_pll_133m", "sys1_pll_out", 1, 6);
+ clks[IMX8MQ_SYS1_PLL_160M] = imx_clk_fixed_factor("sys1_pll_160m", "sys1_pll_out", 1, 5);
+ clks[IMX8MQ_SYS1_PLL_200M] = imx_clk_fixed_factor("sys1_pll_200m", "sys1_pll_out", 1, 4);
+ clks[IMX8MQ_SYS1_PLL_266M] = imx_clk_fixed_factor("sys1_pll_266m", "sys1_pll_out", 1, 3);
+ clks[IMX8MQ_SYS1_PLL_400M] = imx_clk_fixed_factor("sys1_pll_400m", "sys1_pll_out", 1, 2);
+ clks[IMX8MQ_SYS1_PLL_800M] = imx_clk_fixed_factor("sys1_pll_800m", "sys1_pll_out", 1, 1);
+
+ clks[IMX8MQ_SYS2_PLL_50M] = imx_clk_fixed_factor("sys2_pll_50m", "sys2_pll_out", 1, 20);
+ clks[IMX8MQ_SYS2_PLL_100M] = imx_clk_fixed_factor("sys2_pll_100m", "sys2_pll_out", 1, 10);
+ clks[IMX8MQ_SYS2_PLL_125M] = imx_clk_fixed_factor("sys2_pll_125m", "sys2_pll_out", 1, 8);
+ clks[IMX8MQ_SYS2_PLL_166M] = imx_clk_fixed_factor("sys2_pll_166m", "sys2_pll_out", 1, 6);
+ clks[IMX8MQ_SYS2_PLL_200M] = imx_clk_fixed_factor("sys2_pll_200m", "sys2_pll_out", 1, 5);
+ clks[IMX8MQ_SYS2_PLL_250M] = imx_clk_fixed_factor("sys2_pll_250m", "sys2_pll_out", 1, 4);
+ clks[IMX8MQ_SYS2_PLL_333M] = imx_clk_fixed_factor("sys2_pll_333m", "sys2_pll_out", 1, 3);
+ clks[IMX8MQ_SYS2_PLL_500M] = imx_clk_fixed_factor("sys2_pll_500m", "sys2_pll_out", 1, 2);
+ clks[IMX8MQ_SYS2_PLL_1000M] = imx_clk_fixed_factor("sys2_pll_1000m", "sys2_pll_out", 1, 1);
+
+ np = ccm_node;
+ base = of_iomap(np, 0);
+ WARN_ON(!base);
+ /* CORE */
+ clks[IMX8MQ_CLK_A53_SRC] = imx_clk_mux2("arm_a53_src", base + 0x8000, 24, 3, imx8mq_a53_sels, ARRAY_SIZE(imx8mq_a53_sels));
+ clks[IMX8MQ_CLK_VPU_SRC] = imx_clk_mux2("vpu_src", base + 0x8100, 24, 3, imx8mq_vpu_sels, ARRAY_SIZE(imx8mq_vpu_sels));
+ clks[IMX8MQ_CLK_GPU_CORE_SRC] = imx_clk_mux2("gpu_core_src", base + 0x8180, 24, 3, imx8mq_gpu_core_sels, ARRAY_SIZE(imx8mq_gpu_core_sels));
+ clks[IMX8MQ_CLK_GPU_SHADER_SRC] = imx_clk_mux2("gpu_shader_src", base + 0x8200, 24, 3, imx8mq_gpu_shader_sels, ARRAY_SIZE(imx8mq_gpu_shader_sels));
+ clks[IMX8MQ_CLK_A53_CG] = imx_clk_gate3("arm_a53_cg", "arm_a53_src", base + 0x8000, 28);
+ clks[IMX8MQ_CLK_VPU_CG] = imx_clk_gate3("vpu_cg", "vpu_src", base + 0x8100, 28);
+ clks[IMX8MQ_CLK_GPU_CORE_CG] = imx_clk_gate3("gpu_core_cg", "gpu_core_src", base + 0x8180, 28);
+ clks[IMX8MQ_CLK_GPU_SHADER_CG] = imx_clk_gate3("gpu_shader_cg", "gpu_shader_src", base + 0x8200, 28);
+
+ clks[IMX8MQ_CLK_A53_DIV] = imx_clk_divider2("arm_a53_div", "arm_a53_cg", base + 0x8000, 0, 3);
+ clks[IMX8MQ_CLK_VPU_DIV] = imx_clk_divider2("vpu_div", "vpu_cg", base + 0x8100, 0, 3);
+ clks[IMX8MQ_CLK_GPU_CORE_DIV] = imx_clk_divider2("gpu_core_div", "gpu_core_cg", base + 0x8180, 0, 3);
+ clks[IMX8MQ_CLK_GPU_SHADER_DIV] = imx_clk_divider2("gpu_shader_div", "gpu_shader_cg", base + 0x8200, 0, 3);
+
+ /* BUS */
+
+ clks[IMX8MQ_CLK_MAIN_AXI] = imx8m_clk_composite_critical("main_axi", imx8mq_main_axi_sels, base + 0x8800);
+ clks[IMX8MQ_CLK_ENET_AXI] = imx8m_clk_composite("enet_axi", imx8mq_enet_axi_sels, base + 0x8880);
+ clks[IMX8MQ_CLK_NAND_USDHC_BUS] = imx8m_clk_composite("nand_usdhc_bus", imx8mq_nand_usdhc_sels, base + 0x8900);
+ clks[IMX8MQ_CLK_VPU_BUS] = imx8m_clk_composite("vpu_bus", imx8mq_vpu_bus_sels, base + 0x8980);
+ clks[IMX8MQ_CLK_DISP_AXI] = imx8m_clk_composite("disp_axi", imx8mq_disp_axi_sels, base + 0x8a00);
+ clks[IMX8MQ_CLK_DISP_APB] = imx8m_clk_composite("disp_apb", imx8mq_disp_apb_sels, base + 0x8a80);
+ clks[IMX8MQ_CLK_DISP_RTRM] = imx8m_clk_composite("disp_rtrm", imx8mq_disp_rtrm_sels, base + 0x8b00);
+ clks[IMX8MQ_CLK_USB_BUS] = imx8m_clk_composite("usb_bus", imx8mq_usb_bus_sels, base + 0x8b80);
+ clks[IMX8MQ_CLK_GPU_AXI] = imx8m_clk_composite("gpu_axi", imx8mq_gpu_axi_sels, base + 0x8c00);
+ clks[IMX8MQ_CLK_GPU_AHB] = imx8m_clk_composite("gpu_ahb", imx8mq_gpu_ahb_sels, base + 0x8c80);
+ clks[IMX8MQ_CLK_NOC] = imx8m_clk_composite_critical("noc", imx8mq_noc_sels, base + 0x8d00);
+ clks[IMX8MQ_CLK_NOC_APB] = imx8m_clk_composite_critical("noc_apb", imx8mq_noc_apb_sels, base + 0x8d80);
+
+ /* AHB */
+ clks[IMX8MQ_CLK_AHB] = imx8m_clk_composite("ahb", imx8mq_ahb_sels, base + 0x9000);
+ clks[IMX8MQ_CLK_AUDIO_AHB] = imx8m_clk_composite("audio_ahb", imx8mq_audio_ahb_sels, base + 0x9100);
+
+ /* IPG */
+ clks[IMX8MQ_CLK_IPG_ROOT] = imx_clk_divider2("ipg_root", "ahb", base + 0x9080, 0, 1);
+ clks[IMX8MQ_CLK_IPG_AUDIO_ROOT] = imx_clk_divider2("ipg_audio_root", "audio_ahb", base + 0x9180, 0, 1);
+ clks[IMX8MQ_CLK_DSI_IPG_DIV] = imx_clk_divider2("dsi_ipg_div", "dsi_ahb", base + 0x9280, 0, 6);
+
+ clks[IMX8MQ_CLK_DRAM_CORE] = imx_clk_mux2("dram_core_clk", base + 0x9800, 24, 1, imx8mq_dram_core_sels, ARRAY_SIZE(imx8mq_dram_core_sels));
+ /* IP */
+ clks[IMX8MQ_CLK_DRAM_ALT] = imx8m_clk_composite("dram_alt", imx8mq_dram_alt_sels, base + 0xa000);
+ clks[IMX8MQ_CLK_DRAM_APB] = imx8m_clk_composite("dram_apb", imx8mq_dram_apb_sels, base + 0xa080);
+ clks[IMX8MQ_CLK_VPU_G1] = imx8m_clk_composite("vpu_g1", imx8mq_vpu_g1_sels, base + 0xa100);
+ clks[IMX8MQ_CLK_VPU_G2] = imx8m_clk_composite("vpu_g2", imx8mq_vpu_g2_sels, base + 0xa180);
+ clks[IMX8MQ_CLK_DISP_DTRC] = imx8m_clk_composite("disp_dtrc", imx8mq_disp_dtrc_sels, base + 0xa200);
+ clks[IMX8MQ_CLK_DISP_DC8000] = imx8m_clk_composite("disp_dc8000", imx8mq_disp_dc8000_sels, base + 0xa280);
+ clks[IMX8MQ_CLK_PCIE1_CTRL] = imx8m_clk_composite("pcie1_ctrl", imx8mq_pcie1_ctrl_sels, base + 0xa300);
+ clks[IMX8MQ_CLK_PCIE1_PHY] = imx8m_clk_composite("pcie1_phy", imx8mq_pcie1_phy_sels, base + 0xa380);
+ clks[IMX8MQ_CLK_PCIE1_AUX] = imx8m_clk_composite("pcie1_aux", imx8mq_pcie1_aux_sels, base + 0xa400);
+ clks[IMX8MQ_CLK_DC_PIXEL] = imx8m_clk_composite("dc_pixel", imx8mq_dc_pixel_sels, base + 0xa480);
+ clks[IMX8MQ_CLK_LCDIF_PIXEL] = imx8m_clk_composite("lcdif_pixel", imx8mq_lcdif_pixel_sels, base + 0xa500);
+ clks[IMX8MQ_CLK_SAI1] = imx8m_clk_composite("sai1", imx8mq_sai1_sels, base + 0xa580);
+ clks[IMX8MQ_CLK_SAI2] = imx8m_clk_composite("sai2", imx8mq_sai2_sels, base + 0xa600);
+ clks[IMX8MQ_CLK_SAI3] = imx8m_clk_composite("sai3", imx8mq_sai3_sels, base + 0xa680);
+ clks[IMX8MQ_CLK_SAI4] = imx8m_clk_composite("sai4", imx8mq_sai4_sels, base + 0xa700);
+ clks[IMX8MQ_CLK_SAI5] = imx8m_clk_composite("sai5", imx8mq_sai5_sels, base + 0xa780);
+ clks[IMX8MQ_CLK_SAI6] = imx8m_clk_composite("sai6", imx8mq_sai6_sels, base + 0xa800);
+ clks[IMX8MQ_CLK_SPDIF1] = imx8m_clk_composite("spdif1", imx8mq_spdif1_sels, base + 0xa880);
+ clks[IMX8MQ_CLK_SPDIF2] = imx8m_clk_composite("spdif2", imx8mq_spdif2_sels, base + 0xa900);
+ clks[IMX8MQ_CLK_ENET_REF] = imx8m_clk_composite("enet_ref", imx8mq_enet_ref_sels, base + 0xa980);
+ clks[IMX8MQ_CLK_ENET_TIMER] = imx8m_clk_composite("enet_timer", imx8mq_enet_timer_sels, base + 0xaa00);
+ clks[IMX8MQ_CLK_ENET_PHY_REF] = imx8m_clk_composite("enet_phy", imx8mq_enet_phy_sels, base + 0xaa80);
+ clks[IMX8MQ_CLK_NAND] = imx8m_clk_composite("nand", imx8mq_nand_sels, base + 0xab00);
+ clks[IMX8MQ_CLK_QSPI] = imx8m_clk_composite("qspi", imx8mq_qspi_sels, base + 0xab80);
+ clks[IMX8MQ_CLK_USDHC1] = imx8m_clk_composite("usdhc1", imx8mq_usdhc1_sels, base + 0xac00);
+ clks[IMX8MQ_CLK_USDHC2] = imx8m_clk_composite("usdhc2", imx8mq_usdhc2_sels, base + 0xac80);
+ clks[IMX8MQ_CLK_I2C1] = imx8m_clk_composite("i2c1", imx8mq_i2c1_sels, base + 0xad00);
+ clks[IMX8MQ_CLK_I2C2] = imx8m_clk_composite("i2c2", imx8mq_i2c2_sels, base + 0xad80);
+ clks[IMX8MQ_CLK_I2C3] = imx8m_clk_composite("i2c3", imx8mq_i2c3_sels, base + 0xae00);
+ clks[IMX8MQ_CLK_I2C4] = imx8m_clk_composite("i2c4", imx8mq_i2c4_sels, base + 0xae80);
+ clks[IMX8MQ_CLK_UART1] = imx8m_clk_composite("uart1", imx8mq_uart1_sels, base + 0xaf00);
+ clks[IMX8MQ_CLK_UART2] = imx8m_clk_composite("uart2", imx8mq_uart2_sels, base + 0xaf80);
+ clks[IMX8MQ_CLK_UART3] = imx8m_clk_composite("uart3", imx8mq_uart3_sels, base + 0xb000);
+ clks[IMX8MQ_CLK_UART4] = imx8m_clk_composite("uart4", imx8mq_uart4_sels, base + 0xb080);
+ clks[IMX8MQ_CLK_USB_CORE_REF] = imx8m_clk_composite("usb_core_ref", imx8mq_usb_core_sels, base + 0xb100);
+ clks[IMX8MQ_CLK_USB_PHY_REF] = imx8m_clk_composite("usb_phy_ref", imx8mq_usb_phy_sels, base + 0xb180);
+ clks[IMX8MQ_CLK_ECSPI1] = imx8m_clk_composite("ecspi1", imx8mq_ecspi1_sels, base + 0xb280);
+ clks[IMX8MQ_CLK_ECSPI2] = imx8m_clk_composite("ecspi2", imx8mq_ecspi2_sels, base + 0xb300);
+ clks[IMX8MQ_CLK_PWM1] = imx8m_clk_composite("pwm1", imx8mq_pwm1_sels, base + 0xb380);
+ clks[IMX8MQ_CLK_PWM2] = imx8m_clk_composite("pwm2", imx8mq_pwm2_sels, base + 0xb400);
+ clks[IMX8MQ_CLK_PWM3] = imx8m_clk_composite("pwm3", imx8mq_pwm3_sels, base + 0xb480);
+ clks[IMX8MQ_CLK_PWM4] = imx8m_clk_composite("pwm4", imx8mq_pwm4_sels, base + 0xb500);
+ clks[IMX8MQ_CLK_GPT1] = imx8m_clk_composite("gpt1", imx8mq_gpt1_sels, base + 0xb580);
+ clks[IMX8MQ_CLK_WDOG] = imx8m_clk_composite("wdog", imx8mq_wdog_sels, base + 0xb900);
+ clks[IMX8MQ_CLK_WRCLK] = imx8m_clk_composite("wrclk", imx8mq_wrclk_sels, base + 0xb980);
+ clks[IMX8MQ_CLK_CLKO2] = imx8m_clk_composite("clko2", imx8mq_clko2_sels, base + 0xba80);
+ clks[IMX8MQ_CLK_DSI_CORE] = imx8m_clk_composite("dsi_core", imx8mq_dsi_core_sels, base + 0xbb00);
+ clks[IMX8MQ_CLK_DSI_PHY_REF] = imx8m_clk_composite("dsi_phy_ref", imx8mq_dsi_phy_sels, base + 0xbb80);
+ clks[IMX8MQ_CLK_DSI_DBI] = imx8m_clk_composite("dsi_dbi", imx8mq_dsi_dbi_sels, base + 0xbc00);
+ clks[IMX8MQ_CLK_DSI_ESC] = imx8m_clk_composite("dsi_esc", imx8mq_dsi_esc_sels, base + 0xbc80);
+ clks[IMX8MQ_CLK_DSI_AHB] = imx8m_clk_composite("dsi_ahb", imx8mq_dsi_ahb_sels, base + 0x9200);
+ clks[IMX8MQ_CLK_CSI1_CORE] = imx8m_clk_composite("csi1_core", imx8mq_csi1_core_sels, base + 0xbd00);
+ clks[IMX8MQ_CLK_CSI1_PHY_REF] = imx8m_clk_composite("csi1_phy_ref", imx8mq_csi1_phy_sels, base + 0xbd80);
+ clks[IMX8MQ_CLK_CSI1_ESC] = imx8m_clk_composite("csi1_esc", imx8mq_csi1_esc_sels, base + 0xbe00);
+ clks[IMX8MQ_CLK_CSI2_CORE] = imx8m_clk_composite("csi2_core", imx8mq_csi2_core_sels, base + 0xbe80);
+ clks[IMX8MQ_CLK_CSI2_PHY_REF] = imx8m_clk_composite("csi2_phy_ref", imx8mq_csi2_phy_sels, base + 0xbf00);
+ clks[IMX8MQ_CLK_CSI2_ESC] = imx8m_clk_composite("csi2_esc", imx8mq_csi2_esc_sels, base + 0xbf80);
+ clks[IMX8MQ_CLK_PCIE2_CTRL] = imx8m_clk_composite("pcie2_ctrl", imx8mq_pcie2_ctrl_sels, base + 0xc000);
+ clks[IMX8MQ_CLK_PCIE2_PHY] = imx8m_clk_composite("pcie2_phy", imx8mq_pcie2_phy_sels, base + 0xc080);
+ clks[IMX8MQ_CLK_PCIE2_AUX] = imx8m_clk_composite("pcie2_aux", imx8mq_pcie2_aux_sels, base + 0xc100);
+ clks[IMX8MQ_CLK_ECSPI3] = imx8m_clk_composite("ecspi3", imx8mq_ecspi3_sels, base + 0xc180);
+
+ /*FIXME, the doc is not ready now */
+ clks[IMX8MQ_CLK_ECSPI1_ROOT] = imx_clk_gate4("ecspi1_root_clk", "ecspi1", base + 0x4070, 0);
+ clks[IMX8MQ_CLK_ECSPI2_ROOT] = imx_clk_gate4("ecspi2_root_clk", "ecspi2", base + 0x4080, 0);
+ clks[IMX8MQ_CLK_ECSPI3_ROOT] = imx_clk_gate4("ecspi3_root_clk", "ecspi3", base + 0x4090, 0);
+ clks[IMX8MQ_CLK_ENET1_ROOT] = imx_clk_gate4("enet1_root_clk", "enet_axi", base + 0x40a0, 0);
+ clks[IMX8MQ_CLK_GPT1_ROOT] = imx_clk_gate4("gpt1_root_clk", "gpt1", base + 0x4100, 0);
+ clks[IMX8MQ_CLK_I2C1_ROOT] = imx_clk_gate4("i2c1_root_clk", "i2c1", base + 0x4170, 0);
+ clks[IMX8MQ_CLK_I2C2_ROOT] = imx_clk_gate4("i2c2_root_clk", "i2c2", base + 0x4180, 0);
+ clks[IMX8MQ_CLK_I2C3_ROOT] = imx_clk_gate4("i2c3_root_clk", "i2c3", base + 0x4190, 0);
+ clks[IMX8MQ_CLK_I2C4_ROOT] = imx_clk_gate4("i2c4_root_clk", "i2c4", base + 0x41a0, 0);
+ clks[IMX8MQ_CLK_MU_ROOT] = imx_clk_gate4("mu_root_clk", "ipg_root", base + 0x4210, 0);
+ clks[IMX8MQ_CLK_OCOTP_ROOT] = imx_clk_gate4("ocotp_root_clk", "ipg_root", base + 0x4220, 0);
+ clks[IMX8MQ_CLK_PCIE1_ROOT] = imx_clk_gate4("pcie1_root_clk", "pcie1_ctrl", base + 0x4250, 0);
+ clks[IMX8MQ_CLK_PCIE2_ROOT] = imx_clk_gate4("pcie2_root_clk", "pcie2_ctrl", base + 0x4640, 0);
+ clks[IMX8MQ_CLK_PWM1_ROOT] = imx_clk_gate4("pwm1_root_clk", "pwm1", base + 0x4280, 0);
+ clks[IMX8MQ_CLK_PWM2_ROOT] = imx_clk_gate4("pwm2_root_clk", "pwm2", base + 0x4290, 0);
+ clks[IMX8MQ_CLK_PWM3_ROOT] = imx_clk_gate4("pwm3_root_clk", "pwm3", base + 0x42a0, 0);
+ clks[IMX8MQ_CLK_PWM4_ROOT] = imx_clk_gate4("pwm4_root_clk", "pwm4", base + 0x42b0, 0);
+ clks[IMX8MQ_CLK_QSPI_ROOT] = imx_clk_gate4("qspi_root_clk", "qspi", base + 0x42f0, 0);
+ clks[IMX8MQ_CLK_RAWNAND_ROOT] = imx_clk_gate2_shared2("nand_root_clk", "nand", base + 0x4300, 0, &share_count_nand);
+ clks[IMX8MQ_CLK_NAND_USDHC_BUS_RAWNAND_CLK] = imx_clk_gate2_shared2("nand_usdhc_rawnand_clk", "nand_usdhc_bus", base + 0x4300, 0, &share_count_nand);
+ clks[IMX8MQ_CLK_SAI1_ROOT] = imx_clk_gate2_shared2("sai1_root_clk", "sai1", base + 0x4330, 0, &share_count_sai1);
+ clks[IMX8MQ_CLK_SAI1_IPG] = imx_clk_gate2_shared2("sai1_ipg_clk", "ipg_audio_root", base + 0x4330, 0, &share_count_sai1);
+ clks[IMX8MQ_CLK_SAI2_ROOT] = imx_clk_gate2_shared2("sai2_root_clk", "sai2", base + 0x4340, 0, &share_count_sai2);
+ clks[IMX8MQ_CLK_SAI2_IPG] = imx_clk_gate2_shared2("sai2_ipg_clk", "ipg_root", base + 0x4340, 0, &share_count_sai2);
+ clks[IMX8MQ_CLK_SAI3_ROOT] = imx_clk_gate2_shared2("sai3_root_clk", "sai3", base + 0x4350, 0, &share_count_sai3);
+ clks[IMX8MQ_CLK_SAI3_IPG] = imx_clk_gate2_shared2("sai3_ipg_clk", "ipg_root", base + 0x4350, 0, &share_count_sai3);
+ clks[IMX8MQ_CLK_SAI4_ROOT] = imx_clk_gate2_shared2("sai4_root_clk", "sai4", base + 0x4360, 0, &share_count_sai4);
+ clks[IMX8MQ_CLK_SAI4_IPG] = imx_clk_gate2_shared2("sai4_ipg_clk", "ipg_audio_root", base + 0x4360, 0, &share_count_sai4);
+ clks[IMX8MQ_CLK_SAI5_ROOT] = imx_clk_gate2_shared2("sai5_root_clk", "sai5", base + 0x4370, 0, &share_count_sai5);
+ clks[IMX8MQ_CLK_SAI5_IPG] = imx_clk_gate2_shared2("sai5_ipg_clk", "ipg_audio_root", base + 0x4370, 0, &share_count_sai5);
+ clks[IMX8MQ_CLK_SAI6_ROOT] = imx_clk_gate2_shared2("sai6_root_clk", "sai6", base + 0x4380, 0, &share_count_sai6);
+ clks[IMX8MQ_CLK_SAI6_IPG] = imx_clk_gate2_shared2("sai6_ipg_clk", "ipg_audio_root", base + 0x4380, 0, &share_count_sai6);
+ clks[IMX8MQ_CLK_UART1_ROOT] = imx_clk_gate4("uart1_root_clk", "uart1", base + 0x4490, 0);
+ clks[IMX8MQ_CLK_UART2_ROOT] = imx_clk_gate4("uart2_root_clk", "uart2", base + 0x44a0, 0);
+ clks[IMX8MQ_CLK_UART3_ROOT] = imx_clk_gate4("uart3_root_clk", "uart3", base + 0x44b0, 0);
+ clks[IMX8MQ_CLK_UART4_ROOT] = imx_clk_gate4("uart4_root_clk", "uart4", base + 0x44c0, 0);
+ clks[IMX8MQ_CLK_USB1_CTRL_ROOT] = imx_clk_gate4("usb1_ctrl_root_clk", "usb_core_ref", base + 0x44d0, 0);
+ clks[IMX8MQ_CLK_USB2_CTRL_ROOT] = imx_clk_gate4("usb2_ctrl_root_clk", "usb_core_ref", base + 0x44e0, 0);
+ clks[IMX8MQ_CLK_USB1_PHY_ROOT] = imx_clk_gate4("usb1_phy_root_clk", "usb_phy_ref", base + 0x44f0, 0);
+ clks[IMX8MQ_CLK_USB2_PHY_ROOT] = imx_clk_gate4("usb2_phy_root_clk", "usb_phy_ref", base + 0x4500, 0);
+ clks[IMX8MQ_CLK_USDHC1_ROOT] = imx_clk_gate4("usdhc1_root_clk", "usdhc1", base + 0x4510, 0);
+ clks[IMX8MQ_CLK_USDHC2_ROOT] = imx_clk_gate4("usdhc2_root_clk", "usdhc2", base + 0x4520, 0);
+ clks[IMX8MQ_CLK_WDOG1_ROOT] = imx_clk_gate4("wdog1_root_clk", "wdog", base + 0x4530, 0);
+ clks[IMX8MQ_CLK_WDOG2_ROOT] = imx_clk_gate4("wdog2_root_clk", "wdog", base + 0x4540, 0);
+ clks[IMX8MQ_CLK_WDOG3_ROOT] = imx_clk_gate4("wdog3_root_clk", "wdog", base + 0x4550, 0);
+ clks[IMX8MQ_CLK_VPU_G1_ROOT] = imx_clk_gate2_flags("vpu_g1_root_clk", "vpu_g1", base + 0x4560, 0, CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE);
+ clks[IMX8MQ_CLK_GPU_ROOT] = imx_clk_gate4("gpu_root_clk", "gpu_core_div", base + 0x4570, 0);
+ clks[IMX8MQ_CLK_VPU_G2_ROOT] = imx_clk_gate2_flags("vpu_g2_root_clk", "vpu_g2", base + 0x45a0, 0, CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE);
+ clks[IMX8MQ_CLK_DISP_ROOT] = imx_clk_gate2_shared2("disp_root_clk", "disp_dc8000", base + 0x45d0, 0, &share_count_dcss);
+ clks[IMX8MQ_CLK_DISP_AXI_ROOT] = imx_clk_gate2_shared2("disp_axi_root_clk", "disp_axi", base + 0x45d0, 0, &share_count_dcss);
+ clks[IMX8MQ_CLK_DISP_APB_ROOT] = imx_clk_gate2_shared2("disp_apb_root_clk", "disp_apb", base + 0x45d0, 0, &share_count_dcss);
+ clks[IMX8MQ_CLK_DISP_RTRM_ROOT] = imx_clk_gate2_shared2("disp_rtrm_root_clk", "disp_rtrm", base + 0x45d0, 0, &share_count_dcss);
+ clks[IMX8MQ_CLK_TMU_ROOT] = imx_clk_gate4("tmu_root_clk", "ipg_root", base + 0x4620, 0);
+ clks[IMX8MQ_CLK_VPU_DEC_ROOT] = imx_clk_gate2_flags("vpu_dec_root_clk", "vpu_bus", base + 0x4630, 0, CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE);
+ clks[IMX8MQ_CLK_CSI1_ROOT] = imx_clk_gate4("csi1_root_clk", "csi1_core", base + 0x4650, 0);
+ clks[IMX8MQ_CLK_CSI2_ROOT] = imx_clk_gate4("csi2_root_clk", "csi2_core", base + 0x4660, 0);
+ clks[IMX8MQ_CLK_SDMA1_ROOT] = imx_clk_gate4("sdma1_clk", "ipg_root", base + 0x43a0, 0);
+ clks[IMX8MQ_CLK_SDMA2_ROOT] = imx_clk_gate4("sdma2_clk", "ipg_audio_root", base + 0x43b0, 0);
+
+ clks[IMX8MQ_GPT_3M_CLK] = imx_clk_fixed_factor("gpt_3m", "osc_25m", 1, 8);
+ clks[IMX8MQ_CLK_DRAM_ALT_ROOT] = imx_clk_fixed_factor("dram_alt_root", "dram_alt", 1, 4);
+
+ for (i = 0; i < IMX8MQ_CLK_END; i++)
+ if (IS_ERR(clks[i]))
+ pr_err("i.MX8mq clk %u register failed with %ld\n",
+ i, PTR_ERR(clks[i]));
+
+ clk_data.clks = clks;
+ clk_data.clk_num = ARRAY_SIZE(clks);
+ of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
+
+ /* enable all the clocks just for bringup */
+ if (imx_clk_init_on(ccm_node, clks)) {
+ for (i = 0; i < ARRAY_SIZE(clks_init_on); i++)
+ clk_prepare_enable(clks[clks_init_on[i]]);
+ }
+
+ clk_set_parent(clks[IMX8MQ_CLK_AHB], clks[IMX8MQ_SYS1_PLL_133M]);
+ clk_set_parent(clks[IMX8MQ_CLK_NAND_USDHC_BUS], clks[IMX8MQ_SYS1_PLL_266M]);
+ clk_set_parent(clks[IMX8MQ_CLK_AUDIO_AHB], clks[IMX8MQ_SYS2_PLL_500M]);
+
+ /* config video_pll1 clock */
+ clk_set_parent(clks[IMX8MQ_VIDEO_PLL1_REF_SEL], clks[IMX8MQ_CLK_27M]);
+ clk_set_rate(clks[IMX8MQ_VIDEO_PLL1], 593999999);
+
+ /* increase NOC clock to achieve best DDR access performance */
+ clk_set_rate(clks[IMX8MQ_CLK_NOC], clk_get_rate(clks[IMX8MQ_SYS1_PLL_800M]));
+
+ /* set pcie root's parent clk source */
+ clk_set_parent(clks[IMX8MQ_CLK_PCIE1_CTRL], clks[IMX8MQ_SYS2_PLL_250M]);
+ clk_set_parent(clks[IMX8MQ_CLK_PCIE1_PHY], clks[IMX8MQ_SYS2_PLL_100M]);
+ clk_set_parent(clks[IMX8MQ_CLK_PCIE2_CTRL], clks[IMX8MQ_SYS2_PLL_250M]);
+ clk_set_parent(clks[IMX8MQ_CLK_PCIE2_PHY], clks[IMX8MQ_SYS2_PLL_100M]);
+
+ clk_set_parent(clks[IMX8MQ_CLK_CSI1_CORE], clks[IMX8MQ_SYS1_PLL_266M]);
+ clk_set_parent(clks[IMX8MQ_CLK_CSI1_PHY_REF], clks[IMX8MQ_SYS2_PLL_1000M]);
+ clk_set_parent(clks[IMX8MQ_CLK_CSI1_ESC], clks[IMX8MQ_SYS1_PLL_800M]);
+ clk_set_parent(clks[IMX8MQ_CLK_CSI2_CORE], clks[IMX8MQ_SYS1_PLL_266M]);
+ clk_set_parent(clks[IMX8MQ_CLK_CSI2_PHY_REF], clks[IMX8MQ_SYS2_PLL_1000M]);
+ clk_set_parent(clks[IMX8MQ_CLK_CSI2_ESC], clks[IMX8MQ_SYS1_PLL_800M]);
+
+ imx_register_uart_clocks(uart_clks);
+
+ pr_info("i.MX8MQ clock driver init done\n");
+}
+
+CLK_OF_DECLARE(imx8mq, "fsl,imx8mq-ccm", imx8mq_clocks_init);
diff --git a/drivers/clk/imx/clk-imx8qm.c b/drivers/clk/imx/clk-imx8qm.c
new file mode 100644
index 000000000000..3685b85df7e1
--- /dev/null
+++ b/drivers/clk/imx/clk-imx8qm.c
@@ -0,0 +1,954 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017-2018 NXP
+ *
+ * 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 <dt-bindings/clock/imx8qm-clock.h>
+#include <dt-bindings/soc/imx8_pd.h>
+#include <linux/clk.h>
+#include <linux/clkdev.h>
+#include <linux/clk-provider.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/platform_device.h>
+#include <linux/pm_domain.h>
+#include <linux/types.h>
+
+#include <soc/imx8/imx8qm/lpcg.h>
+#include <soc/imx8/sc/sci.h>
+
+#include "clk-imx8.h"
+
+#define STR_VALUE(arg) #arg
+#define FUNCTION_NAME(name) STR_VALUE(name)
+
+static const char *aud_clk_sels[] = {
+ "aud_acm_aud_rec_clk0_clk",
+ "aud_acm_aud_rec_clk1_clk",
+ "mlb_clk",
+ "hdmi_rx_mclk",
+ "ext_aud_mclk0",
+ "ext_aud_mclk1",
+ "esai0_rx_clk",
+ "esai0_rx_hf_clk",
+ "esai0_tx_clk",
+ "esai0_tx_hf_clk",
+ "esai1_rx_clk",
+ "esai1_rx_hf_clk",
+ "esai1_tx_clk",
+ "esai1_tx_hf_clk",
+ "spdif0_rx",
+ "spdif1_rx",
+ "sai0_rx_bclk",
+ "sai0_tx_bclk",
+ "sai1_rx_bclk",
+ "sai1_tx_bclk",
+ "sai2_rx_bclk",
+ "sai3_rx_bclk",
+ "hdmi_rx_sai0_rx_bclk",
+};
+
+static const char *mclk_out_sels[] = {
+ "aud_acm_aud_rec_clk0_clk",
+ "aud_acm_aud_rec_clk1_clk",
+ "mlb_clk",
+ "hdmi_rx_mclk",
+ "spdif0_rx",
+ "spdif1_rx",
+ "hdmi_rx_sai0_rx_bclk",
+ "sai6_rx_bclk",
+};
+
+static const char *sai_mclk_sels[] = {
+ "aud_acm_aud_pll_clk0_clk",
+ "aud_acm_aud_pll_clk1_clk",
+ "acm_aud_clk0_clk",
+ "acm_aud_clk1_clk",
+};
+
+static const char *asrc_mux_clk_sels[] = {
+ "hdmi_rx_sai0_rx_bclk",
+ "hdmi_tx_sai0_tx_bclk",
+ "dummy",
+ "mlb_clk",
+};
+
+static const char *esai_mclk_sels[] = {
+ "aud_acm_aud_pll_clk0_clk",
+ "aud_acm_aud_pll_clk1_clk",
+ "acm_aud_clk0_clk",
+ "acm_aud_clk1_clk",
+};
+
+static const char *spdif_mclk_sels[] = {
+ "aud_acm_aud_pll_clk0_clk",
+ "aud_acm_aud_pll_clk1_clk",
+ "acm_aud_clk0_clk",
+ "acm_aud_clk1_clk",
+};
+
+static const char *mqs_mclk_sels[] = {
+ "aud_acm_aud_pll_clk0_clk",
+ "aud_acm_aud_pll_clk1_clk",
+ "acm_aud_clk0_clk",
+ "acm_aud_clk1_clk",
+};
+
+static const char *dc0_sels[] = {
+ "dummy",
+ "dummy",
+ "dc0_pll0_clk",
+ "dc0_pll1_clk",
+ "dc0_bypass0_div",
+};
+
+static const char *dc1_sels[] = {
+ "dummy",
+ "dummy",
+ "dc1_pll0_clk",
+ "dc1_pll1_clk",
+ "dc1_bypass0_div",
+};
+
+static const char *hdmi_sels[] = {
+ "dummy",
+ "hdmi_dig_pll_clk",
+ "dummy",
+ "dummy",
+ "hdmi_av_pll_clk",
+};
+
+static const char *hdmi_rx_sels[] = {
+ "dummy",
+ "hdmi_rx_dig_pll_clk",
+ "dummy",
+ "dummy",
+ "hdmi_rx_bypass_clk",
+};
+
+
+static struct clk *clks[IMX8QM_CLK_END];
+static struct clk_onecell_data clk_data;
+
+static const char *enet_sels[] = {"enet_25MHz", "enet_125MHz",};
+static const char *enet0_rmii_tx_sels[] = {"enet0_ref_div", "dummy",};
+static const char *enet1_rmii_tx_sels[] = {"enet1_ref_div", "dummy",};
+
+#define LPCG_ADDR(arg) ((void __iomem *)(base_lpcg + arg))
+
+static int imx8qm_clk_probe(struct platform_device *pdev)
+{
+ struct device_node *ccm_node = pdev->dev.of_node;
+ struct device_node *np_acm;
+ void __iomem *base_acm;
+ u64 base_lpcg = 0;
+ int i, ret;
+
+ ret = imx8_clk_mu_init();
+ if (ret)
+ return ret;
+
+ pr_info("***** imx8qm_clocks_init *****\n");
+
+ /* Parse lpcg_base_offset for virtualization cases */
+ ret = of_property_read_u64(ccm_node, "fsl,lpcg_base_offset", &base_lpcg);
+ if (ret && ret != -EINVAL) {
+ dev_err(&pdev->dev, "failed to parse fsl,lpcg_base_offset: %d\n", ret);
+ return ret;
+ }
+
+ clks[IMX8QM_CLK_DUMMY] = imx_clk_fixed("dummy", 0);
+
+ /* ARM core */
+ clks[IMX8QM_A53_DIV] = imx_clk_divider_scu("a53_div", SC_R_A53, SC_PM_CLK_CPU);
+ clks[IMX8QM_A72_DIV] = imx_clk_divider_scu("a72_div", SC_R_A72, SC_PM_CLK_CPU);
+
+ /* User Defined PLLs dividers */
+ clks[IMX8QM_AUD_PLL0_DIV] = imx_clk_divider_scu("audio_pll0_div", SC_R_AUDIO_PLL_0, SC_PM_CLK_PLL);
+ clks[IMX8QM_AUD_PLL1_DIV] = imx_clk_divider_scu("audio_pll1_div", SC_R_AUDIO_PLL_1, SC_PM_CLK_PLL);
+ clks[IMX8QM_DC0_PLL0_DIV] = imx_clk_divider_scu("dc0_pll0_div", SC_R_DC_0_PLL_0, SC_PM_CLK_PLL);
+ clks[IMX8QM_DC0_PLL1_DIV] = imx_clk_divider_scu("dc0_pll1_div", SC_R_DC_0_PLL_1, SC_PM_CLK_PLL);
+ clks[IMX8QM_DC1_PLL0_DIV] = imx_clk_divider_scu("dc1_pll0_div", SC_R_DC_1_PLL_0, SC_PM_CLK_PLL);
+ clks[IMX8QM_DC1_PLL1_DIV] = imx_clk_divider_scu("dc1_pll1_div", SC_R_DC_1_PLL_1, SC_PM_CLK_PLL);
+ clks[IMX8QM_HDMI_AV_PLL_DIV] = imx_clk_divider_scu("hdmi_av_pll_div", SC_R_HDMI_PLL_1, SC_PM_CLK_PLL);
+ clks[IMX8QM_HDMI_DIG_PLL_DIV] = imx_clk_divider_scu("hdmi_dig_pll_div", SC_R_HDMI_PLL_0, SC_PM_CLK_PLL);
+
+ /* User Defined PLLs clocks*/
+ clks[IMX8QM_AUD_PLL0] = imx_clk_gate_scu("audio_pll0_clk", "audio_pll0_div", SC_R_AUDIO_PLL_0, SC_PM_CLK_PLL, NULL, 0, 0);
+ clks[IMX8QM_AUD_PLL1] = imx_clk_gate_scu("audio_pll1_clk", "audio_pll1_div", SC_R_AUDIO_PLL_1, SC_PM_CLK_PLL, NULL, 0, 0);
+ clks[IMX8QM_DC0_PLL0_CLK] = imx_clk_gate_scu("dc0_pll0_clk", "dc0_pll0_div", SC_R_DC_0_PLL_0, SC_PM_CLK_PLL, NULL, 0, 0);
+ clks[IMX8QM_DC0_PLL1_CLK] = imx_clk_gate_scu("dc0_pll1_clk", "dc0_pll1_div", SC_R_DC_0_PLL_1, SC_PM_CLK_PLL, NULL, 0, 0);
+ clks[IMX8QM_DC1_PLL0_CLK] = imx_clk_gate_scu("dc1_pll0_clk", "dc1_pll0_div", SC_R_DC_1_PLL_0, SC_PM_CLK_PLL, NULL, 0, 0);
+ clks[IMX8QM_DC1_PLL1_CLK] = imx_clk_gate_scu("dc1_pll1_clk", "dc1_pll1_div", SC_R_DC_1_PLL_1, SC_PM_CLK_PLL, NULL, 0, 0);
+ clks[IMX8QM_HDMI_AV_PLL_CLK] = imx_clk_gate_scu("hdmi_av_pll_clk", "hdmi_av_pll_div", SC_R_HDMI_PLL_1, SC_PM_CLK_PLL, NULL, 0, 0);
+ clks[IMX8QM_HDMI_DIG_PLL_CLK] = imx_clk_gate_scu("hdmi_dig_pll_clk", "hdmi_dig_pll_div", SC_R_HDMI_PLL_0, SC_PM_CLK_PLL, NULL, 0, 0);
+
+ /* DMA SS */
+ clks[IMX8QM_UART0_DIV] = imx_clk_divider_scu("uart0_div", SC_R_UART_0, SC_PM_CLK_PER);
+ clks[IMX8QM_UART1_DIV] = imx_clk_divider_scu("uart1_div", SC_R_UART_1, SC_PM_CLK_PER);
+ clks[IMX8QM_UART2_DIV] = imx_clk_divider_scu("uart2_div", SC_R_UART_2, SC_PM_CLK_PER);
+ clks[IMX8QM_UART3_DIV] = imx_clk_divider_scu("uart3_div", SC_R_UART_3, SC_PM_CLK_PER);
+ clks[IMX8QM_UART4_DIV] = imx_clk_divider_scu("uart4_div", SC_R_UART_4, SC_PM_CLK_PER);
+ clks[IMX8QM_SPI0_DIV] = imx_clk_divider_scu("spi0_div", SC_R_SPI_0, SC_PM_CLK_PER);
+ clks[IMX8QM_SPI1_DIV] = imx_clk_divider_scu("spi1_div", SC_R_SPI_1, SC_PM_CLK_PER);
+ clks[IMX8QM_SPI2_DIV] = imx_clk_divider_scu("spi2_div", SC_R_SPI_2, SC_PM_CLK_PER);
+ clks[IMX8QM_SPI3_DIV] = imx_clk_divider_scu("spi3_div", SC_R_SPI_3, SC_PM_CLK_PER);
+ clks[IMX8QM_EMVSIM0_DIV] = imx_clk_divider_scu("emvsim0_div", SC_R_EMVSIM_0, SC_PM_CLK_PER);
+ clks[IMX8QM_EMVSIM1_DIV] = imx_clk_divider_scu("emvsim1_div", SC_R_EMVSIM_1, SC_PM_CLK_PER);
+ clks[IMX8QM_CAN0_DIV] = imx_clk_divider_scu("can0_div", SC_R_CAN_0, SC_PM_CLK_PER);
+ clks[IMX8QM_CAN1_DIV] = imx_clk_divider_scu("can1_div", SC_R_CAN_1, SC_PM_CLK_PER);
+ clks[IMX8QM_CAN2_DIV] = imx_clk_divider_scu("can2_div", SC_R_CAN_2, SC_PM_CLK_PER);
+ clks[IMX8QM_I2C0_DIV] = imx_clk_divider_scu("i2c0_div", SC_R_I2C_0, SC_PM_CLK_PER);
+ clks[IMX8QM_I2C1_DIV] = imx_clk_divider_scu("i2c1_div", SC_R_I2C_1, SC_PM_CLK_PER);
+ clks[IMX8QM_I2C2_DIV] = imx_clk_divider_scu("i2c2_div", SC_R_I2C_2, SC_PM_CLK_PER);
+ clks[IMX8QM_I2C3_DIV] = imx_clk_divider_scu("i2c3_div", SC_R_I2C_3, SC_PM_CLK_PER);
+ clks[IMX8QM_I2C4_DIV] = imx_clk_divider_scu("i2c4_div", SC_R_I2C_4, SC_PM_CLK_PER);
+ clks[IMX8QM_FTM0_DIV] = imx_clk_divider_scu("ftm0_div", SC_R_FTM_0, SC_PM_CLK_PER);
+ clks[IMX8QM_FTM1_DIV] = imx_clk_divider_scu("ftm1_div", SC_R_FTM_1, SC_PM_CLK_PER);
+ clks[IMX8QM_ADC0_DIV] = imx_clk_divider_scu("adc0_div", SC_R_ADC_0, SC_PM_CLK_PER);
+ clks[IMX8QM_ADC1_DIV] = imx_clk_divider_scu("adc1_div", SC_R_ADC_1, SC_PM_CLK_PER);
+
+ /* LSIO SS */
+ clks[IMX8QM_PWM0_DIV] = imx_clk_divider_scu("pwm_0_div", SC_R_PWM_0, SC_PM_CLK_PER);
+ clks[IMX8QM_PWM1_DIV] = imx_clk_divider_scu("pwm_1_div", SC_R_PWM_1, SC_PM_CLK_PER);
+ clks[IMX8QM_PWM2_DIV] = imx_clk_divider_scu("pwm_2_div", SC_R_PWM_2, SC_PM_CLK_PER);
+ clks[IMX8QM_PWM3_DIV] = imx_clk_divider_scu("pwm_3_div", SC_R_PWM_3, SC_PM_CLK_PER);
+ clks[IMX8QM_PWM4_DIV] = imx_clk_divider_scu("pwm_4_div", SC_R_PWM_4, SC_PM_CLK_PER);
+ clks[IMX8QM_PWM5_DIV] = imx_clk_divider_scu("pwm_5_div", SC_R_PWM_5, SC_PM_CLK_PER);
+ clks[IMX8QM_PWM6_DIV] = imx_clk_divider_scu("pwm_6_div", SC_R_PWM_6, SC_PM_CLK_PER);
+ clks[IMX8QM_PWM7_DIV] = imx_clk_divider_scu("pwm_7_div", SC_R_PWM_7, SC_PM_CLK_PER);
+ clks[IMX8QM_FSPI0_DIV] = imx_clk_divider_scu("fspi_0_div", SC_R_FSPI_0, SC_PM_CLK_PER);
+ clks[IMX8QM_FSPI1_DIV] = imx_clk_divider_scu("fspi_1_div", SC_R_FSPI_1, SC_PM_CLK_PER);
+ clks[IMX8QM_GPT0_DIV] = imx_clk_divider_scu("gpt_0_div", SC_R_GPT_0, SC_PM_CLK_PER);
+ clks[IMX8QM_GPT1_DIV] = imx_clk_divider_scu("gpt_1_div", SC_R_GPT_1, SC_PM_CLK_PER);
+ clks[IMX8QM_GPT2_DIV] = imx_clk_divider_scu("gpt_2_div", SC_R_GPT_2, SC_PM_CLK_PER);
+ clks[IMX8QM_GPT3_DIV] = imx_clk_divider_scu("gpt_3_div", SC_R_GPT_3, SC_PM_CLK_PER);
+ clks[IMX8QM_GPT4_DIV] = imx_clk_divider_scu("gpt_4_div", SC_R_GPT_4, SC_PM_CLK_PER);
+
+ /* lvds subsystem */
+ clks[IMX8QM_LVDS0_BYPASS_CLK] = imx_clk_divider_scu("lvds0_bypass_clk", SC_R_LVDS_0, SC_PM_CLK_BYPASS);
+ clks[IMX8QM_LVDS0_PIXEL_DIV] = imx_clk_divider_scu("lvds0_pixel_div", SC_R_LVDS_0, SC_PM_CLK_PER);
+ clks[IMX8QM_LVDS0_I2C0_DIV] = imx_clk_divider_scu("lvds0_i2c0_div", SC_R_LVDS_0_I2C_0, SC_PM_CLK_PER);
+ clks[IMX8QM_LVDS0_I2C1_DIV] = imx_clk_divider_scu("lvds0_i2c1_div", SC_R_LVDS_0_I2C_1, SC_PM_CLK_PER);
+ clks[IMX8QM_LVDS0_PWM0_DIV] = imx_clk_divider_scu("lvds0_pwm0_div", SC_R_LVDS_0_PWM_0, SC_PM_CLK_PER);
+ clks[IMX8QM_LVDS0_PHY_DIV] = imx_clk_divider_scu("lvds0_phy_div", SC_R_LVDS_0, SC_PM_CLK_PHY);
+ clks[IMX8QM_LVDS1_BYPASS_CLK] = imx_clk_divider_scu("lvds1_bypass_clk", SC_R_LVDS_1, SC_PM_CLK_BYPASS);
+ clks[IMX8QM_LVDS1_PIXEL_DIV] = imx_clk_divider_scu("lvds1_pixel_div", SC_R_LVDS_1, SC_PM_CLK_PER);
+ clks[IMX8QM_LVDS1_I2C0_DIV] = imx_clk_divider_scu("lvds1_i2c0_div", SC_R_LVDS_1_I2C_0, SC_PM_CLK_PER);
+ clks[IMX8QM_LVDS1_I2C1_DIV] = imx_clk_divider_scu("lvds1_i2c1_div", SC_R_LVDS_1_I2C_1, SC_PM_CLK_PER);
+ clks[IMX8QM_LVDS1_PWM0_DIV] = imx_clk_divider_scu("lvds1_pwm0_div", SC_R_LVDS_1_PWM_0, SC_PM_CLK_PER);
+ clks[IMX8QM_LVDS1_PHY_DIV] = imx_clk_divider_scu("lvds1_phy_div", SC_R_LVDS_1, SC_PM_CLK_PHY);
+
+ /* vpu/zpu subsystem */
+ clks[IMX8QM_VPU_DDR_DIV] = imx_clk_divider_scu("vpu_ddr_div", SC_R_VPU, SC_PM_CLK_SLV_BUS);
+ clks[IMX8QM_VPU_SYS_DIV] = imx_clk_divider_scu("vpu_sys_div", SC_R_VPU, SC_PM_CLK_MST_BUS);
+ clks[IMX8QM_VPU_XUVI_DIV] = imx_clk_divider_scu("vpu_xuvi_div", SC_R_VPU, SC_PM_CLK_PER);
+ clks[IMX8QM_VPU_UART_DIV] = imx_clk_divider_scu("vpu_uart_div", SC_R_VPU_UART, SC_PM_CLK_PER);
+ clks[IMX8QM_VPU_CORE_DIV] = imx_clk_divider_scu("vpu_core_div", SC_R_VPUCORE, SC_PM_CLK_PER);
+
+ /* gpu */
+ clks[IMX8QM_GPU0_CORE_DIV] = imx_clk_divider_scu("gpu_core0_div", SC_R_GPU_0_PID0, SC_PM_CLK_PER);
+ clks[IMX8QM_GPU0_SHADER_DIV] = imx_clk_divider_scu("gpu_shader0_div", SC_R_GPU_0_PID0, SC_PM_CLK_MISC);
+ clks[IMX8QM_GPU1_CORE_DIV] = imx_clk_divider_scu("gpu_core1_div", SC_R_GPU_1_PID0, SC_PM_CLK_PER);
+ clks[IMX8QM_GPU1_SHADER_DIV] = imx_clk_divider_scu("gpu_shader1_div", SC_R_GPU_1_PID0, SC_PM_CLK_MISC);
+
+ /* Connectivity */
+ clks[IMX8QM_SDHC0_DIV] = imx_clk_divider_scu("sdhc0_div", SC_R_SDHC_0, SC_PM_CLK_PER);
+ clks[IMX8QM_SDHC1_DIV] = imx_clk_divider_scu("sdhc1_div", SC_R_SDHC_1, SC_PM_CLK_PER);
+ clks[IMX8QM_SDHC2_DIV] = imx_clk_divider_scu("sdhc2_div", SC_R_SDHC_2, SC_PM_CLK_PER);
+ clks[IMX8QM_ENET0_ROOT_DIV] = imx_clk_divider_scu("enet0_root_div", SC_R_ENET_0, SC_PM_CLK_PER);
+ clks[IMX8QM_ENET0_REF_DIV] = imx_clk_divider3_scu("enet0_ref_div", "enet0_root_clk", SC_R_ENET_0, SC_C_CLKDIV);
+ clks[IMX8QM_ENET1_REF_DIV] = imx_clk_divider3_scu("enet1_ref_div", "enet1_root_clk", SC_R_ENET_1, SC_C_CLKDIV);
+ clks[IMX8QM_ENET0_BYPASS_DIV] = imx_clk_divider_scu("enet0_bypass_div", SC_R_ENET_0, SC_PM_CLK_BYPASS);
+ clks[IMX8QM_ENET0_RGMII_DIV] = imx_clk_divider_scu("enet0_rgmii_div", SC_R_ENET_0, SC_PM_CLK_MISC0);
+ clks[IMX8QM_ENET1_ROOT_DIV] = imx_clk_divider_scu("enet1_root_div", SC_R_ENET_1, SC_PM_CLK_PER);
+ clks[IMX8QM_ENET1_BYPASS_DIV] = imx_clk_divider_scu("enet1_bypass_div", SC_R_ENET_1, SC_PM_CLK_BYPASS);
+ clks[IMX8QM_ENET1_RGMII_DIV] = imx_clk_divider_scu("enet1_rgmii_div", SC_R_ENET_1, SC_PM_CLK_MISC0);
+ clks[IMX8QM_GPMI_BCH_IO_DIV] = imx_clk_divider_scu("gpmi_io_div", SC_R_NAND, SC_PM_CLK_MST_BUS);
+ clks[IMX8QM_GPMI_BCH_DIV] = imx_clk_divider_scu("gpmi_bch_div", SC_R_NAND, SC_PM_CLK_PER);
+ clks[IMX8QM_USB3_ACLK_DIV] = imx_clk_divider_scu("usb3_aclk_div", SC_R_USB_2, SC_PM_CLK_PER);
+ clks[IMX8QM_USB3_BUS_DIV] = imx_clk_divider_scu("usb3_bus_div", SC_R_USB_2, SC_PM_CLK_MST_BUS);
+ clks[IMX8QM_USB3_LPM_DIV] = imx_clk_divider_scu("usb3_lpm_div", SC_R_USB_2, SC_PM_CLK_MISC);
+
+ /* Audio */
+ clks[IMX8QM_AUD_ACM_AUD_PLL_CLK0_DIV] = imx_clk_divider2_scu("aud_acm_aud_pll_clk0_div", "audio_pll0_clk", SC_R_AUDIO_PLL_0, SC_PM_CLK_MISC0);
+ clks[IMX8QM_AUD_ACM_AUD_PLL_CLK1_DIV] = imx_clk_divider2_scu("aud_acm_aud_pll_clk1_div", "audio_pll1_clk", SC_R_AUDIO_PLL_1, SC_PM_CLK_MISC0);
+ clks[IMX8QM_AUD_ACM_AUD_REC_CLK0_DIV] = imx_clk_divider2_scu("aud_acm_aud_rec_clk0_div", "audio_pll0_clk", SC_R_AUDIO_PLL_0, SC_PM_CLK_MISC1);
+ clks[IMX8QM_AUD_ACM_AUD_REC_CLK1_DIV] = imx_clk_divider2_scu("aud_acm_aud_rec_clk1_div", "audio_pll1_clk", SC_R_AUDIO_PLL_1, SC_PM_CLK_MISC1);
+
+ /* MIPI CSI */
+ clks[IMX8QM_CSI0_I2C0_DIV] = imx_clk_divider_scu("mipi_csi0_i2c0_div", SC_R_CSI_0_I2C_0, SC_PM_CLK_PER);
+ clks[IMX8QM_CSI0_PWM0_DIV] = imx_clk_divider_scu("mipi_csi0_pwm0_div", SC_R_CSI_0_PWM_0, SC_PM_CLK_PER);
+ clks[IMX8QM_CSI0_CORE_DIV] = imx_clk_divider_scu("mipi_csi0_core_div", SC_R_CSI_0, SC_PM_CLK_PER);
+ clks[IMX8QM_CSI0_ESC_DIV] = imx_clk_divider_scu("mipi_csi0_esc_div", SC_R_CSI_0, SC_PM_CLK_MISC);
+ clks[IMX8QM_CSI1_I2C0_DIV] = imx_clk_divider_scu("mipi_csi1_i2c0_div", SC_R_CSI_1_I2C_0, SC_PM_CLK_PER);
+ clks[IMX8QM_CSI1_PWM0_DIV] = imx_clk_divider_scu("mipi_csi1_pwm0_div", SC_R_CSI_1_PWM_0, SC_PM_CLK_PER);
+ clks[IMX8QM_CSI1_CORE_DIV] = imx_clk_divider_scu("mipi_csi1_core_div", SC_R_CSI_1, SC_PM_CLK_PER);
+ clks[IMX8QM_CSI1_ESC_DIV] = imx_clk_divider_scu("mipi_csi1_esc_div", SC_R_CSI_1, SC_PM_CLK_MISC);
+
+ /* RX-HDMI */
+ clks[IMX8QM_HDMI_RX_I2S_BYPASS_CLK] = imx_clk_divider_scu("hdmi_rx_i2s_bypass_clk", SC_R_HDMI_RX_BYPASS, SC_PM_CLK_MISC0);
+ clks[IMX8QM_HDMI_RX_SPDIF_BYPASS_CLK] = imx_clk_divider_scu("hdmi_rx_spdif_bypass_clk", SC_R_HDMI_RX_BYPASS, SC_PM_CLK_MISC1);
+ clks[IMX8QM_HDMI_RX_BYPASS_CLK] = imx_clk_divider_scu("hdmi_rx_bypass_clk", SC_R_HDMI_RX_BYPASS, SC_PM_CLK_MISC2);
+ clks[IMX8QM_HDMI_RX_I2C0_DIV] = imx_clk_divider_scu("hdmi_rx_i2c0_div", SC_R_HDMI_RX_I2C_0, SC_PM_CLK_MISC2);
+ clks[IMX8QM_HDMI_RX_SPDIF_DIV] = imx_clk_divider_scu("hdmi_rx_spdif_div", SC_R_HDMI_RX, SC_PM_CLK_MISC0);
+ clks[IMX8QM_HDMI_RX_HD_REF_SEL] = imx_clk_mux2_scu("hdmi_rx_hd_ref_sel", hdmi_rx_sels, ARRAY_SIZE(hdmi_rx_sels), SC_R_HDMI_RX, SC_PM_CLK_MISC1);
+ clks[IMX8QM_HDMI_RX_HD_REF_DIV] = imx_clk_divider2_scu("hdmi_rx_hd_ref_div", "hdmi_rx_hd_ref_sel", SC_R_HDMI_RX, SC_PM_CLK_MISC1);
+ clks[IMX8QM_HDMI_RX_HD_CORE_SEL] = imx_clk_mux2_scu("hdmi_rx_hd_core_sel", hdmi_rx_sels, ARRAY_SIZE(hdmi_rx_sels), SC_R_HDMI_RX, SC_PM_CLK_MISC2);
+ clks[IMX8QM_HDMI_RX_HD_CORE_DIV] = imx_clk_divider2_scu("hdmi_rx_hd_core_div", "hdmi_rx_hd_core_sel", SC_R_HDMI_RX, SC_PM_CLK_MISC2);
+ clks[IMX8QM_HDMI_RX_PXL_SEL] = imx_clk_mux2_scu("hdmi_rx_pxl_sel", hdmi_rx_sels, ARRAY_SIZE(hdmi_rx_sels), SC_R_HDMI_RX, SC_PM_CLK_MISC3);
+ clks[IMX8QM_HDMI_RX_PXL_DIV] = imx_clk_divider2_scu("hdmi_rx_pxl_div", "hdmi_rx_pxl_sel", SC_R_HDMI_RX, SC_PM_CLK_MISC3);
+ clks[IMX8QM_HDMI_RX_I2S_DIV] = imx_clk_divider_scu("hdmi_rx_i2s_div", SC_R_HDMI_RX, SC_PM_CLK_MISC4);
+ clks[IMX8QM_HDMI_RX_PWM_DIV] = imx_clk_divider_scu("hdmi_rx_pwm_div", SC_R_HDMI_RX_PWM_0, SC_PM_CLK_MISC2);
+
+ /* DC SS */
+ clks[IMX8QM_DC0_DISP0_SEL] = imx_clk_mux2_scu("dc0_disp0_sel", dc0_sels, ARRAY_SIZE(dc0_sels), SC_R_DC_0, SC_PM_CLK_MISC0);
+ clks[IMX8QM_DC0_DISP0_DIV] = imx_clk_divider2_scu("dc0_disp0_div", "dc0_disp0_sel", SC_R_DC_0, SC_PM_CLK_MISC0);
+ clks[IMX8QM_DC0_DISP1_SEL] = imx_clk_mux2_scu("dc0_disp1_sel", dc0_sels, ARRAY_SIZE(dc0_sels), SC_R_DC_0, SC_PM_CLK_MISC1);
+ clks[IMX8QM_DC0_DISP1_DIV] = imx_clk_divider2_scu("dc0_disp1_div", "dc0_disp1_sel", SC_R_DC_0, SC_PM_CLK_MISC1);
+ clks[IMX8QM_DC0_BYPASS_0_DIV] = imx_clk_divider_scu("dc0_bypass0_div", SC_R_DC_0_VIDEO0, SC_PM_CLK_MISC);
+ clks[IMX8QM_DC0_BYPASS_1_DIV] = imx_clk_divider_scu("dc0_bypass1_div", SC_R_DC_0_VIDEO1, SC_PM_CLK_MISC);
+ clks[IMX8QM_DC1_DISP0_SEL] = imx_clk_mux2_scu("dc1_disp0_sel", dc1_sels, ARRAY_SIZE(dc1_sels), SC_R_DC_1, SC_PM_CLK_MISC0);
+ clks[IMX8QM_DC1_DISP0_DIV] = imx_clk_divider2_scu("dc1_disp0_div", "dc1_disp0_sel", SC_R_DC_1, SC_PM_CLK_MISC0);
+ clks[IMX8QM_DC1_DISP1_SEL] = imx_clk_mux2_scu("dc1_disp1_sel", dc1_sels, ARRAY_SIZE(dc1_sels), SC_R_DC_1, SC_PM_CLK_MISC1);
+ clks[IMX8QM_DC1_DISP1_DIV] = imx_clk_divider2_scu("dc1_disp1_div", "dc1_disp1_sel", SC_R_DC_1, SC_PM_CLK_MISC1);
+ clks[IMX8QM_DC1_BYPASS_0_DIV] = imx_clk_divider_scu("dc1_bypass0_div", SC_R_DC_1_VIDEO0, SC_PM_CLK_BYPASS);
+ clks[IMX8QM_DC1_BYPASS_1_DIV] = imx_clk_divider_scu("dc1_bypass1_div", SC_R_DC_1_VIDEO1, SC_PM_CLK_BYPASS);
+
+ /* HDMI SS */
+ clks[IMX8QM_HDMI_IPG_DIV] = imx_clk_divider_scu("hdmi_ipg_div", SC_R_HDMI, SC_PM_CLK_MISC);
+ clks[IMX8QM_HDMI_I2S_BYPASS_CLK] = imx_clk_divider_scu("hdmi_i2s_bypass_clk", SC_R_HDMI_I2S, SC_PM_CLK_BYPASS);
+ clks[IMX8QM_HDMI_I2C0_DIV] = imx_clk_divider_scu("hdmi_i2c0_div", SC_R_HDMI_I2C_0, SC_PM_CLK_MISC2);
+ clks[IMX8QM_HDMI_PXL_SEL] = imx_clk_mux2_scu("hdmi_pxl_sel", hdmi_sels, ARRAY_SIZE(hdmi_sels), SC_R_HDMI, SC_PM_CLK_MISC3);
+ clks[IMX8QM_HDMI_PXL_DIV] = imx_clk_divider2_scu("hdmi_pxl_div", "hdmi_pxl_sel", SC_R_HDMI, SC_PM_CLK_MISC3);
+ clks[IMX8QM_HDMI_PXL_LINK_SEL] = imx_clk_mux2_scu("hdmi_pxl_link_sel", hdmi_sels, ARRAY_SIZE(hdmi_sels), SC_R_HDMI, SC_PM_CLK_MISC1);
+ clks[IMX8QM_HDMI_PXL_LINK_DIV] = imx_clk_divider2_scu("hdmi_pxl_link_div", "hdmi_pxl_link_sel", SC_R_HDMI, SC_PM_CLK_MISC1);
+ clks[IMX8QM_HDMI_PXL_MUX_SEL] = imx_clk_mux2_scu("hdmi_pxl_mux_sel", hdmi_sels, ARRAY_SIZE(hdmi_sels), SC_R_HDMI, SC_PM_CLK_MISC0);
+ clks[IMX8QM_HDMI_PXL_MUX_DIV] = imx_clk_divider2_scu("hdmi_pxl_mux_div", "hdmi_pxl_mux_sel", SC_R_HDMI, SC_PM_CLK_MISC0);
+ clks[IMX8QM_HDMI_I2S_DIV] = imx_clk_divider_scu("hdmi_i2s_div", SC_R_HDMI_I2S, SC_PM_CLK_MISC0);
+ clks[IMX8QM_HDMI_HDP_CORE_DIV] = imx_clk_divider_scu("hdmi_core_div", SC_R_HDMI, SC_PM_CLK_MISC2);
+
+ /* MIPI -DI SS */
+ clks[IMX8QM_MIPI0_BYPASS_CLK] = imx_clk_divider_scu("mipi0_bypass_clk", SC_R_MIPI_0, SC_PM_CLK_BYPASS);
+ clks[IMX8QM_MIPI0_PWM0_DIV] = imx_clk_divider_scu("mipi0_pwm0_div", SC_R_MIPI_0_PWM_0, SC_PM_CLK_PER);
+ clks[IMX8QM_MIPI0_DSI_TX_ESC_DIV] = imx_clk_divider_scu("mipi0_dsi_tx_esc_div", SC_R_MIPI_0, SC_PM_CLK_MST_BUS);
+ clks[IMX8QM_MIPI0_DSI_RX_ESC_DIV] = imx_clk_divider_scu("mipi0_dsi_rx_esc_div", SC_R_MIPI_0, SC_PM_CLK_SLV_BUS);
+ clks[IMX8QM_MIPI0_DSI_PHY_DIV] = imx_clk_divider_scu("mipi0_dsi_phy_div", SC_R_MIPI_0, SC_PM_CLK_PHY);
+ clks[IMX8QM_MIPI0_PXL_DIV] = imx_clk_divider_scu("mipi0_pxl_div", SC_R_MIPI_0, SC_PM_CLK_PER);
+ clks[IMX8QM_MIPI1_BYPASS_CLK] = imx_clk_divider_scu("mipi1_bypass_clk", SC_R_MIPI_1, SC_PM_CLK_BYPASS);
+ clks[IMX8QM_MIPI1_PWM0_DIV] = imx_clk_divider_scu("mipi1_pwm0_div", SC_R_MIPI_1_PWM_0, SC_PM_CLK_PER);
+ clks[IMX8QM_MIPI1_DSI_TX_ESC_DIV] = imx_clk_divider_scu("mipi1_dsi_tx_esc_div", SC_R_MIPI_1, SC_PM_CLK_MST_BUS);
+ clks[IMX8QM_MIPI1_DSI_RX_ESC_DIV] = imx_clk_divider_scu("mipi1_dsi_rx_esc_div", SC_R_MIPI_1, SC_PM_CLK_SLV_BUS);
+ clks[IMX8QM_MIPI1_DSI_PHY_DIV] = imx_clk_divider_scu("mipi1_dsi_phy_div", SC_R_MIPI_1, SC_PM_CLK_PHY);
+ clks[IMX8QM_MIPI1_PXL_DIV] = imx_clk_divider_scu("mipi1_pxl_div", SC_R_MIPI_1, SC_PM_CLK_PER);
+
+ /* Fixed clocks. */
+ clks[IMX8QM_IPG_DMA_CLK_ROOT] = imx_clk_fixed("ipg_dma_clk_root", SC_120MHZ);
+ clks[IMX8QM_IPG_AUD_CLK_ROOT] = imx_clk_fixed("ipg_aud_clk_root", SC_175MHZ);
+ clks[IMX8QM_AXI_CONN_CLK_ROOT] = imx_clk_fixed("axi_conn_clk_root", SC_333MHZ);
+ clks[IMX8QM_AHB_CONN_CLK_ROOT] = imx_clk_fixed("ahb_conn_clk_root", SC_166MHZ);
+ clks[IMX8QM_IPG_CONN_CLK_ROOT] = imx_clk_fixed("ipg_conn_clk_root", SC_83MHZ);
+ clks[IMX8QM_IPG_MIPI_CSI_CLK_ROOT] = imx_clk_fixed("ipg_mipi_csi_clk_root", SC_120MHZ);
+ clks[IMX8QM_DC_AXI_EXT_CLK] = imx_clk_fixed("axi_ext_dc_clk_root", SC_800MHZ);
+ clks[IMX8QM_DC_AXI_INT_CLK] = imx_clk_fixed("axi_int_dc_clk_root", SC_400MHZ);
+ clks[IMX8QM_DC_CFG_CLK] = imx_clk_fixed("cfg_dc_clk_root", SC_100MHZ);
+ clks[IMX8QM_LVDS_IPG_CLK] = imx_clk_fixed("ipg_lvds_clk_root", SC_24MHZ);
+ clks[IMX8QM_IMG_AXI_CLK] = imx_clk_fixed("axi_img_clk_root", SC_400MHZ);
+ clks[IMX8QM_IMG_IPG_CLK] = imx_clk_fixed("ipg_img_clk_root", SC_200MHZ);
+ clks[IMX8QM_IMG_PXL_CLK] = imx_clk_fixed("pxl_img_clk_root", SC_600MHZ);
+ clks[IMX8QM_HSIO_AXI_CLK] = imx_clk_fixed("axi_hsio_clk_root", SC_400MHZ);
+ clks[IMX8QM_HSIO_PER_CLK] = imx_clk_fixed("per_hsio_clk_root", SC_133MHZ);
+ clks[IMX8QM_HDMI_RX_IPG_CLK] = imx_clk_fixed("ipg_hdmi_rx_clk_root", SC_200MHZ);
+ clks[IMX8QM_HDMI_RX_DIG_PLL_CLK] = imx_clk_fixed("hdmi_rx_dig_pll_clk", SC_800MHZ);
+ clks[IMX8QM_ENET_25MHZ_CLK] = imx_clk_fixed("enet_25MHz", SC_25MHZ);
+ clks[IMX8QM_ENET_125MHZ_CLK] = imx_clk_fixed("enet_125MHz", SC_125MHZ);
+ clks[IMX8QM_LSIO_BUS_CLK] = imx_clk_fixed("lsio_bus_clk_root", SC_100MHZ);
+ clks[IMX8QM_LSIO_MEM_CLK] = imx_clk_fixed("lsio_mem_clk_root", SC_200MHZ);
+ clks[IMX8QM_24MHZ] = imx_clk_fixed("xtal_24MHz", 24000000);
+ clks[IMX8QM_GPT_3M] = imx_clk_fixed("gpt_3m", 3000000);
+ clks[IMX8QM_32KHZ] = imx_clk_fixed("xtal_32KHz", 32768);
+ clks[IMX8QM_MIPI0_CLK_ROOT] = imx_clk_fixed("mipi0_clk_root", SC_120MHZ);
+ clks[IMX8QM_MIPI1_CLK_ROOT] = imx_clk_fixed("mipi1_clk_root", SC_120MHZ);
+
+ /* Conectivity */
+ clks[IMX8QM_SDHC0_IPG_CLK] = imx_clk_gate2_scu("sdhc0_ipg_clk", "ipg_conn_clk_root", LPCG_ADDR(USDHC_0_LPCG), 16, FUNCTION_NAME(PD_CONN_SDHC_0));
+ clks[IMX8QM_SDHC1_IPG_CLK] = imx_clk_gate2_scu("sdhc1_ipg_clk", "ipg_conn_clk_root", LPCG_ADDR(USDHC_1_LPCG), 16, FUNCTION_NAME(PD_CONN_SDHC_1));
+ clks[IMX8QM_SDHC2_IPG_CLK] = imx_clk_gate2_scu("sdhc2_ipg_clk", "ipg_conn_clk_root", LPCG_ADDR(USDHC_2_LPCG), 16, FUNCTION_NAME(PD_CONN_SDHC_2));
+ clks[IMX8QM_SDHC0_CLK] = imx_clk_gate_scu("sdhc0_clk", "sdhc0_div", SC_R_SDHC_0, SC_PM_CLK_PER, LPCG_ADDR(USDHC_0_LPCG), 0, 0);
+ clks[IMX8QM_SDHC1_CLK] = imx_clk_gate_scu("sdhc1_clk", "sdhc1_div", SC_R_SDHC_1, SC_PM_CLK_PER, LPCG_ADDR(USDHC_1_LPCG), 0, 0);
+ clks[IMX8QM_SDHC2_CLK] = imx_clk_gate_scu("sdhc2_clk", "sdhc2_div", SC_R_SDHC_2, SC_PM_CLK_PER, LPCG_ADDR(USDHC_2_LPCG), 0, 0);
+ clks[IMX8QM_ENET0_AHB_CLK] = imx_clk_gate2_scu("enet0_ahb_clk", "axi_conn_clk_root", LPCG_ADDR(ENET_0_LPCG), 8, FUNCTION_NAME(PD_CONN_ENET_0));
+ clks[IMX8QM_ENET0_IPG_S_CLK] = imx_clk_gate2_scu("enet0_ipg_s_clk", "ipg_conn_clk_root", LPCG_ADDR(ENET_0_LPCG), 20, FUNCTION_NAME(PD_CONN_ENET_0));
+ clks[IMX8QM_ENET0_IPG_CLK] = imx_clk_gate2_scu("enet0_ipg_clk", "enet0_ipg_s_clk", LPCG_ADDR(ENET_0_LPCG), 16, FUNCTION_NAME(PD_CONN_ENET_0));
+ clks[IMX8QM_ENET1_AHB_CLK] = imx_clk_gate2_scu("enet1_ahb_clk", "axi_conn_clk_root", LPCG_ADDR(ENET_1_LPCG), 8, FUNCTION_NAME(PD_CONN_ENET_1));
+ clks[IMX8QM_ENET1_IPG_S_CLK] = imx_clk_gate2_scu("enet1_ipg_s_clk", "ipg_conn_clk_root", LPCG_ADDR(ENET_1_LPCG), 20, FUNCTION_NAME(PD_CONN_ENET_1));
+ clks[IMX8QM_ENET1_IPG_CLK] = imx_clk_gate2_scu("enet1_ipg_clk", "enet1_ipg_s_clk", LPCG_ADDR(ENET_1_LPCG), 16, FUNCTION_NAME(PD_CONN_ENET_1));
+ clks[IMX8QM_ENET0_ROOT_CLK] = imx_clk_gate_scu("enet0_root_clk", "enet0_root_div", SC_R_ENET_0, SC_PM_CLK_PER, NULL, 0, 0);
+ clks[IMX8QM_ENET1_ROOT_CLK] = imx_clk_gate_scu("enet1_root_clk", "enet1_root_div", SC_R_ENET_1, SC_PM_CLK_PER, NULL, 0, 0);
+ clks[IMX8QM_ENET0_TX_CLK] = imx_clk_gate2_scu("enet0_tx_2x_clk", "enet0_root_clk", LPCG_ADDR(ENET_0_LPCG), 4, FUNCTION_NAME(PD_CONN_ENET_0));
+ clks[IMX8QM_ENET1_TX_CLK] = imx_clk_gate2_scu("enet1_tx_2x_clk", "enet1_root_clk", LPCG_ADDR(ENET_1_LPCG), 4, FUNCTION_NAME(PD_CONN_ENET_1));
+ clks[IMX8QM_ENET0_PTP_CLK] = imx_clk_gate2_scu("enet0_ptp_clk", "enet0_root_clk", LPCG_ADDR(ENET_0_LPCG), 0, FUNCTION_NAME(PD_CONN_ENET_0));
+ clks[IMX8QM_ENET1_PTP_CLK] = imx_clk_gate2_scu("enet1_ptp_clk", "enet1_root_clk", LPCG_ADDR(ENET_1_LPCG), 0, FUNCTION_NAME(PD_CONN_ENET_1));
+ clks[IMX8QM_ENET0_REF_25MHZ_125MHZ_SEL] = imx_clk_mux_gpr_scu("enet0_ref_25_125_sel", enet_sels, ARRAY_SIZE(enet_sels), SC_R_ENET_0, SC_C_SEL_125);
+ clks[IMX8QM_ENET1_REF_25MHZ_125MHZ_SEL] = imx_clk_mux_gpr_scu("enet1_ref_25_125_sel", enet_sels, ARRAY_SIZE(enet_sels), SC_R_ENET_1, SC_C_SEL_125);
+ clks[IMX8QM_ENET0_RMII_TX_SEL] = imx_clk_mux_gpr_scu("enet0_rmii_tx_sel", enet0_rmii_tx_sels, ARRAY_SIZE(enet0_rmii_tx_sels), SC_R_ENET_0, SC_C_TXCLK);
+ clks[IMX8QM_ENET1_RMII_TX_SEL] = imx_clk_mux_gpr_scu("enet1_rmii_tx_sel", enet1_rmii_tx_sels, ARRAY_SIZE(enet1_rmii_tx_sels), SC_R_ENET_1, SC_C_TXCLK);
+ clks[IMX8QM_ENET0_RGMII_TX_CLK] = imx_clk_gate2_scu("enet0_rgmii_tx_clk", "enet0_rmii_tx_sel", LPCG_ADDR(ENET_0_LPCG), 12, FUNCTION_NAME(PD_CONN_ENET_0));
+ clks[IMX8QM_ENET1_RGMII_TX_CLK] = imx_clk_gate2_scu("enet1_rgmii_tx_clk", "enet1_rmii_tx_sel", LPCG_ADDR(ENET_1_LPCG), 12, FUNCTION_NAME(PD_CONN_ENET_1));
+ clks[IMX8QM_ENET0_RMII_RX_CLK] = imx_clk_gate2_scu("enet0_rgmii_rx_clk", "enet0_rgmii_div", LPCG_ADDR(ENET_0_LPCG + 0x4), 0, FUNCTION_NAME(PD_CONN_ENET_0));
+ clks[IMX8QM_ENET1_RMII_RX_CLK] = imx_clk_gate2_scu("enet1_rgmii_rx_clk", "enet1_rgmii_div", LPCG_ADDR(ENET_1_LPCG + 0x4), 0, FUNCTION_NAME(PD_CONN_ENET_1));
+ clks[IMX8QM_ENET0_REF_25MHZ_125MHZ_CLK] = imx_clk_gate3_scu("enet0_ref_25_125_clk", "enet0_ref_25_125_sel", SC_R_ENET_0, SC_C_DISABLE_125, true);
+ clks[IMX8QM_ENET1_REF_25MHZ_125MHZ_CLK] = imx_clk_gate3_scu("enet1_ref_25_125_clk", "enet1_ref_25_125_sel", SC_R_ENET_1, SC_C_DISABLE_125, true);
+ clks[IMX8QM_ENET0_REF_50MHZ_CLK] = imx_clk_gate3_scu("enet0_ref_50_clk", NULL, SC_R_ENET_0, SC_C_DISABLE_50, true);
+ clks[IMX8QM_ENET1_REF_50MHZ_CLK] = imx_clk_gate3_scu("enet1_ref_50_clk", NULL, SC_R_ENET_1, SC_C_DISABLE_50, true);
+ clks[IMX8QM_GPMI_APB_CLK] = imx_clk_gate2_scu("gpmi_apb_clk", "axi_conn_clk_root", LPCG_ADDR(NAND_LPCG), 16, FUNCTION_NAME(PD_CONN_NAND));
+ clks[IMX8QM_GPMI_APB_BCH_CLK] = imx_clk_gate2_scu("gpmi_apb_bch_clk", "axi_conn_clk_root", LPCG_ADDR(NAND_LPCG), 20, FUNCTION_NAME(PD_CONN_NAND));
+ clks[IMX8QM_GPMI_BCH_IO_CLK] = imx_clk_gate_scu("gpmi_io_clk", "gpmi_io_div", SC_R_NAND, SC_PM_CLK_MST_BUS, LPCG_ADDR(NAND_LPCG), 4, 0);
+ clks[IMX8QM_GPMI_BCH_CLK] = imx_clk_gate_scu("gpmi_bch_clk", "gpmi_bch_div", SC_R_NAND, SC_PM_CLK_PER, LPCG_ADDR(NAND_LPCG), 0, 0);
+ clks[IMX8QM_APBHDMA_CLK] = imx_clk_gate2_scu("gpmi_clk", "axi_conn_clk_root", LPCG_ADDR(NAND_LPCG + 0x4), 16, FUNCTION_NAME(PD_CONN_NAND));
+ clks[IMX8QM_USB2_OH_AHB_CLK] = imx_clk_gate2_scu("usboh3", "ahb_conn_clk_root", LPCG_ADDR(USB_2_LPCG), 24, FUNCTION_NAME(PD_CONN_USB_0));
+ clks[IMX8QM_USB2_OH_IPG_S_CLK] = imx_clk_gate2_scu("usboh3_ipg_s", "ipg_conn_clk_root", LPCG_ADDR(USB_2_LPCG), 16, FUNCTION_NAME(PD_CONN_USB_0));
+ clks[IMX8QM_USB2_OH_IPG_S_PL301_CLK] = imx_clk_gate2_scu("usboh3_ipg_pl301_s", "ipg_conn_clk_root", LPCG_ADDR(USB_2_LPCG), 20, FUNCTION_NAME(PD_CONN_USB_0));
+ clks[IMX8QM_USB2_PHY_IPG_CLK] = imx_clk_gate2_scu("usboh3_phy_clk", "ipg_conn_clk_root", LPCG_ADDR(USB_2_LPCG), 28, FUNCTION_NAME(PD_CONN_USB_0));
+ clks[IMX8QM_USB3_IPG_CLK] = imx_clk_gate2_scu("usb3_ipg_clk", "ipg_conn_clk_root", LPCG_ADDR(USB_3_LPCG), 16, FUNCTION_NAME(PD_CONN_USB_2));
+ clks[IMX8QM_USB3_CORE_PCLK] = imx_clk_gate2_scu("usb3_core_clk", "ipg_conn_clk_root", LPCG_ADDR(USB_3_LPCG), 20, FUNCTION_NAME(PD_CONN_USB_2));
+ clks[IMX8QM_USB3_PHY_CLK] = imx_clk_gate2_scu("usb3_phy_clk", "usb3_ipg_clk", LPCG_ADDR(USB_3_LPCG), 24, FUNCTION_NAME(PD_CONN_USB_2_PHY));
+ clks[IMX8QM_USB3_ACLK] = imx_clk_gate_scu("usb3_aclk", "usb3_aclk_div", SC_R_USB_2, SC_PM_CLK_PER, LPCG_ADDR(USB_3_LPCG), 28, 0);
+ clks[IMX8QM_USB3_BUS_CLK] = imx_clk_gate_scu("usb3_bus_clk", "usb3_bus_div", SC_R_USB_2, SC_PM_CLK_MST_BUS, LPCG_ADDR(USB_3_LPCG), 0, 0);
+ clks[IMX8QM_USB3_LPM_CLK] = imx_clk_gate_scu("usb3_lpm_clk", "usb3_lpm_div", SC_R_USB_2, SC_PM_CLK_MISC, LPCG_ADDR(USB_3_LPCG), 4, 0);
+ clks[IMX8QM_EDMA_CLK] = imx_clk_gate2_scu("edma_clk", "axi_conn_clk_root", LPCG_ADDR(EDMA_LPCG), 0, FUNCTION_NAME(PD_CONN_DMA_4_CH0));
+ clks[IMX8QM_EDMA_IPG_CLK] = imx_clk_gate2_scu("edma_ipg_clk", "ipg_conn_clk_root", LPCG_ADDR(EDMA_LPCG), 16, FUNCTION_NAME(PD_CONN_DMA_4_CH0));
+ clks[IMX8QM_MLB_HCLK] = imx_clk_gate2_scu("mlb_hclk", "axi_conn_clk_root", LPCG_ADDR(MLB_LPCG), 20, FUNCTION_NAME(PD_CONN_MLB_0));
+ clks[IMX8QM_MLB_CLK] = imx_clk_gate2_scu("mlb_clk", "mlb_hclk", LPCG_ADDR(MLB_LPCG), 0, FUNCTION_NAME(PD_CONN_MLB_0));
+ clks[IMX8QM_MLB_IPG_CLK] = imx_clk_gate2_scu("mlb_ipg_clk", "ipg_conn_clk_root", LPCG_ADDR(MLB_LPCG), 16, FUNCTION_NAME(PD_CONN_MLB_0));
+
+ /* DMA */
+ clks[IMX8QM_UART0_IPG_CLK] = imx_clk_gate2_scu("uart0_ipg_clk", "ipg_dma_clk_root", LPCG_ADDR(LPUART_0_LPCG), 16, FUNCTION_NAME(PD_DMA_UART0));
+ clks[IMX8QM_UART1_IPG_CLK] = imx_clk_gate2_scu("uart1_ipg_clk", "ipg_dma_clk_root", LPCG_ADDR(LPUART_1_LPCG), 16, FUNCTION_NAME(PD_DMA_UART1));
+ clks[IMX8QM_UART2_IPG_CLK] = imx_clk_gate2_scu("uart2_ipg_clk", "ipg_dma_clk_root", LPCG_ADDR(LPUART_2_LPCG), 16, FUNCTION_NAME(PD_DMA_UART2));
+ clks[IMX8QM_UART3_IPG_CLK] = imx_clk_gate2_scu("uart3_ipg_clk", "ipg_dma_clk_root", LPCG_ADDR(LPUART_3_LPCG), 16, FUNCTION_NAME(PD_DMA_UART3));
+ clks[IMX8QM_UART4_IPG_CLK] = imx_clk_gate2_scu("uart4_ipg_clk", "ipg_dma_clk_root", LPCG_ADDR(LPUART_4_LPCG), 16, FUNCTION_NAME(PD_DMA_UART4));
+ clks[IMX8QM_UART0_CLK] = imx_clk_gate_scu("uart0_clk", "uart0_div", SC_R_UART_0, SC_PM_CLK_PER, LPCG_ADDR(LPUART_0_LPCG), 0, 0);
+ clks[IMX8QM_UART1_CLK] = imx_clk_gate_scu("uart1_clk", "uart1_div", SC_R_UART_1, SC_PM_CLK_PER, LPCG_ADDR(LPUART_1_LPCG), 0, 0);
+ clks[IMX8QM_UART2_CLK] = imx_clk_gate_scu("uart2_clk", "uart2_div", SC_R_UART_2, SC_PM_CLK_PER, LPCG_ADDR(LPUART_2_LPCG), 0, 0);
+ clks[IMX8QM_UART3_CLK] = imx_clk_gate_scu("uart3_clk", "uart3_div", SC_R_UART_3, SC_PM_CLK_PER, LPCG_ADDR(LPUART_3_LPCG), 0, 0);
+ clks[IMX8QM_UART4_CLK] = imx_clk_gate_scu("uart4_clk", "uart4_div", SC_R_UART_4, SC_PM_CLK_PER, LPCG_ADDR(LPUART_4_LPCG), 0, 0);
+ clks[IMX8QM_SPI0_IPG_CLK] = imx_clk_gate2_scu("spi0_ipg_clk", "ipg_dma_clk_root", LPCG_ADDR(LPSPI_0_LPCG), 16, FUNCTION_NAME(PD_DMA_SPI_0));
+ clks[IMX8QM_SPI1_IPG_CLK] = imx_clk_gate2_scu("spi1_ipg_clk", "ipg_dma_clk_root", LPCG_ADDR(LPSPI_1_LPCG), 16, FUNCTION_NAME(PD_DMA_SPI_1));
+ clks[IMX8QM_SPI2_IPG_CLK] = imx_clk_gate2_scu("spi2_ipg_clk", "ipg_dma_clk_root", LPCG_ADDR(LPSPI_2_LPCG), 16, FUNCTION_NAME(PD_DMA_SPI_2));
+ clks[IMX8QM_SPI3_IPG_CLK] = imx_clk_gate2_scu("spi3_ipg_clk", "ipg_dma_clk_root", LPCG_ADDR(LPSPI_3_LPCG), 16, FUNCTION_NAME(PD_DMA_SPI_3));
+ clks[IMX8QM_SPI0_CLK] = imx_clk_gate_scu("spi0_clk", "spi0_div", SC_R_SPI_0, SC_PM_CLK_PER, LPCG_ADDR(LPSPI_0_LPCG), 0, 0);
+ clks[IMX8QM_SPI1_CLK] = imx_clk_gate_scu("spi1_clk", "spi1_div", SC_R_SPI_1, SC_PM_CLK_PER, LPCG_ADDR(LPSPI_1_LPCG), 0, 0);
+ clks[IMX8QM_SPI2_CLK] = imx_clk_gate_scu("spi2_clk", "spi2_div", SC_R_SPI_2, SC_PM_CLK_PER, LPCG_ADDR(LPSPI_2_LPCG), 0, 0);
+ clks[IMX8QM_SPI3_CLK] = imx_clk_gate_scu("spi3_clk", "spi3_div", SC_R_SPI_3, SC_PM_CLK_PER, LPCG_ADDR(LPSPI_3_LPCG), 0, 0);
+ clks[IMX8QM_EMVSIM0_IPG_CLK] = imx_clk_gate2_scu("emvsim0_ipg_clk", "ipg_dma_clk_root", LPCG_ADDR(EMVSIM_0_LPCG), 16, FUNCTION_NAME(PD_DMA_EMVSIM_0));
+ clks[IMX8QM_EMVSIM1_IPG_CLK] = imx_clk_gate2_scu("emvsim1_ipg_clk", "ipg_dma_clk_root", LPCG_ADDR(EMVSIM_1_LPCG), 16, FUNCTION_NAME(PD_DMA_EMVSIM_1));
+ clks[IMX8QM_EMVSIM0_CLK] = imx_clk_gate_scu("emvsim0_clk", "emvsim0_div", SC_R_EMVSIM_0, SC_PM_CLK_PER, LPCG_ADDR(EMVSIM_0_LPCG), 0, 0);
+ clks[IMX8QM_EMVSIM1_CLK] = imx_clk_gate_scu("emvsim1_clk", "emvsim1_div", SC_R_EMVSIM_0, SC_PM_CLK_PER, LPCG_ADDR(EMVSIM_1_LPCG), 0, 0);
+ clks[IMX8QM_CAN0_IPG_CHI_CLK] = imx_clk_gate2_scu("can0_ipg_chi_clk", "ipg_dma_clk_root", LPCG_ADDR(FLEX_CAN_0_LPCG), 20, FUNCTION_NAME(PD_DMA_CAN_0));
+ clks[IMX8QM_CAN0_IPG_CLK] = imx_clk_gate2_scu("can0_ipg_clk", "can0_ipg_chi_clk", LPCG_ADDR(FLEX_CAN_0_LPCG), 16, FUNCTION_NAME(PD_DMA_CAN_0));
+ clks[IMX8QM_CAN1_IPG_CHI_CLK] = imx_clk_gate2_scu("can1_ipg_chi_clk", "ipg_dma_clk_root", LPCG_ADDR(FLEX_CAN_1_LPCG), 20, FUNCTION_NAME(PD_DMA_CAN_1));
+ clks[IMX8QM_CAN1_IPG_CLK] = imx_clk_gate2_scu("can1_ipg_clk", "can1_ipg_chi_clk", LPCG_ADDR(FLEX_CAN_1_LPCG), 16, FUNCTION_NAME(PD_DMA_CAN_1));
+ clks[IMX8QM_CAN2_IPG_CHI_CLK] = imx_clk_gate2_scu("can2_ipg_chi_clk", "ipg_dma_clk_root", LPCG_ADDR(FLEX_CAN_2_LPCG), 20, FUNCTION_NAME(PD_DMA_CAN_2));
+ clks[IMX8QM_CAN2_IPG_CLK] = imx_clk_gate2_scu("can2_ipg_clk", "can2_ipg_chi_clk", LPCG_ADDR(FLEX_CAN_2_LPCG), 16, FUNCTION_NAME(PD_DMA_CAN_2));
+ clks[IMX8QM_CAN0_CLK] = imx_clk_gate_scu("can0_clk", "can0_div", SC_R_CAN_0, SC_PM_CLK_PER, LPCG_ADDR(FLEX_CAN_0_LPCG), 0, 0);
+ clks[IMX8QM_CAN1_CLK] = imx_clk_gate_scu("can1_clk", "can1_div", SC_R_CAN_1, SC_PM_CLK_PER, LPCG_ADDR(FLEX_CAN_1_LPCG), 0, 0);
+ clks[IMX8QM_CAN2_CLK] = imx_clk_gate_scu("can2_clk", "can2_div", SC_R_CAN_2, SC_PM_CLK_PER, LPCG_ADDR(FLEX_CAN_2_LPCG), 0, 0);
+ clks[IMX8QM_I2C0_IPG_CLK] = imx_clk_gate2_scu("i2c0_ipg_clk", "ipg_dma_clk_root", LPCG_ADDR(LPI2C_0_LPCG), 16, FUNCTION_NAME(PD_DMA_I2C_0));
+ clks[IMX8QM_I2C1_IPG_CLK] = imx_clk_gate2_scu("i2c1_ipg_clk", "ipg_dma_clk_root", LPCG_ADDR(LPI2C_1_LPCG), 16, FUNCTION_NAME(PD_DMA_I2C_1));
+ clks[IMX8QM_I2C2_IPG_CLK] = imx_clk_gate2_scu("i2c2_ipg_clk", "ipg_dma_clk_root", LPCG_ADDR(LPI2C_2_LPCG), 16, FUNCTION_NAME(PD_DMA_I2C_2));
+ clks[IMX8QM_I2C3_IPG_CLK] = imx_clk_gate2_scu("i2c3_ipg_clk", "ipg_dma_clk_root", LPCG_ADDR(LPI2C_3_LPCG), 16, FUNCTION_NAME(PD_DMA_I2C_3));
+ clks[IMX8QM_I2C4_IPG_CLK] = imx_clk_gate2_scu("i2c4_ipg_clk", "ipg_dma_clk_root", LPCG_ADDR(LPI2C_4_LPCG), 16, FUNCTION_NAME(PD_DMA_I2C_4));
+ clks[IMX8QM_I2C0_CLK] = imx_clk_gate_scu("i2c0_clk", "i2c0_div", SC_R_I2C_0, SC_PM_CLK_PER, LPCG_ADDR(LPI2C_0_LPCG), 0, 0);
+ clks[IMX8QM_I2C1_CLK] = imx_clk_gate_scu("i2c1_clk", "i2c1_div", SC_R_I2C_1, SC_PM_CLK_PER, LPCG_ADDR(LPI2C_1_LPCG), 0, 0);
+ clks[IMX8QM_I2C2_CLK] = imx_clk_gate_scu("i2c2_clk", "i2c2_div", SC_R_I2C_2, SC_PM_CLK_PER, LPCG_ADDR(LPI2C_2_LPCG), 0, 0);
+ clks[IMX8QM_I2C3_CLK] = imx_clk_gate_scu("i2c3_clk", "i2c3_div", SC_R_I2C_3, SC_PM_CLK_PER, LPCG_ADDR(LPI2C_3_LPCG), 0, 0);
+ clks[IMX8QM_I2C4_CLK] = imx_clk_gate_scu("i2c4_clk", "i2c4_div", SC_R_I2C_4, SC_PM_CLK_PER, LPCG_ADDR(LPI2C_4_LPCG), 0, 0);
+ clks[IMX8QM_FTM0_IPG_CLK] = imx_clk_gate2_scu("ftm0_ipg_clk", "ipg_dma_clk_root", LPCG_ADDR(FTM_0_LPCG), 16, FUNCTION_NAME(PD_DMA_FTM_0));
+ clks[IMX8QM_FTM1_IPG_CLK] = imx_clk_gate2_scu("ftm1_ipg_clk", "ipg_dma_clk_root", LPCG_ADDR(FTM_1_LPCG), 16, FUNCTION_NAME(PD_DMA_FTM_1));
+ clks[IMX8QM_FTM0_CLK] = imx_clk_gate_scu("ftm0_clk", "ftm0_div", SC_R_FTM_0, SC_PM_CLK_PER, LPCG_ADDR(FTM_0_LPCG), 0, 0);
+ clks[IMX8QM_FTM1_CLK] = imx_clk_gate_scu("ftm1_clk", "ftm1_div", SC_R_FTM_1, SC_PM_CLK_PER, LPCG_ADDR(FTM_1_LPCG), 0, 0);
+ clks[IMX8QM_ADC0_IPG_CLK] = imx_clk_gate2_scu("adc0_ipg_clk", "ipg_dma_clk_root", LPCG_ADDR(ADC_0_LPCG), 16, FUNCTION_NAME(PD_DMA_ADC_0));
+ clks[IMX8QM_ADC1_IPG_CLK] = imx_clk_gate2_scu("adc1_ipg_clk", "ipg_dma_clk_root", LPCG_ADDR(ADC_1_LPCG), 16, FUNCTION_NAME(PD_DMA_ADC_1));
+ clks[IMX8QM_ADC0_CLK] = imx_clk_gate_scu("adc0_clk", "adc0_div", SC_R_ADC_0, SC_PM_CLK_PER, LPCG_ADDR(ADC_0_LPCG), 0, 0);
+ clks[IMX8QM_ADC1_CLK] = imx_clk_gate_scu("adc1_clk", "adc1_div", SC_R_ADC_1, SC_PM_CLK_PER, LPCG_ADDR(ADC_1_LPCG), 0, 0);
+
+ /* LSIO SS */
+ clks[IMX8QM_PWM0_IPG_S_CLK] = imx_clk_gate_scu("pwm_0_ipg_s_clk", "pwm_0_div", SC_R_PWM_0, SC_PM_CLK_PER, LPCG_ADDR(PWM_0_LPCG), 0x10, 0);
+ clks[IMX8QM_PWM0_IPG_SLV_CLK] = imx_clk_gate_scu("pwm_0_ipg_slv_clk", "pwm_0_ipg_s_clk", SC_R_PWM_0, SC_PM_CLK_PER, LPCG_ADDR(PWM_0_LPCG), 0x14, 0);
+ clks[IMX8QM_PWM0_IPG_MSTR_CLK] = imx_clk_gate2_scu("pwm_0_ipg_mstr_clk", "lsio_bus_clk_root", LPCG_ADDR(PWM_0_LPCG), 0x18, FUNCTION_NAME(PD_LSIO_PWM_0));
+ clks[IMX8QM_PWM0_HF_CLK] = imx_clk_gate_scu("pwm_0_hf_clk", "pwm_0_ipg_slv_clk", SC_R_PWM_0, SC_PM_CLK_PER, LPCG_ADDR(PWM_0_LPCG), 4, 0);
+ clks[IMX8QM_PWM0_CLK] = imx_clk_gate_scu("pwm_0_clk", "pwm_0_ipg_slv_clk", SC_R_PWM_0, SC_PM_CLK_PER, LPCG_ADDR(PWM_0_LPCG), 0, 0);
+ clks[IMX8QM_PWM1_IPG_S_CLK] = imx_clk_gate_scu("pwm_1_ipg_s_clk", "pwm_1_div", SC_R_PWM_1, SC_PM_CLK_PER, LPCG_ADDR(PWM_1_LPCG), 0x10, 0);
+ clks[IMX8QM_PWM1_IPG_SLV_CLK] = imx_clk_gate_scu("pwm_1_ipg_slv_clk", "pwm_1_ipg_s_clk", SC_R_PWM_1, SC_PM_CLK_PER, LPCG_ADDR(PWM_1_LPCG), 0x14, 0);
+ clks[IMX8QM_PWM1_IPG_MSTR_CLK] = imx_clk_gate2_scu("pwm_1_ipg_mstr_clk", "lsio_bus_clk_root", LPCG_ADDR(PWM_1_LPCG), 0x18, FUNCTION_NAME(PD_LSIO_PWM_1));
+ clks[IMX8QM_PWM1_HF_CLK] = imx_clk_gate_scu("pwm_1_hf_clk", "pwm_1_ipg_slv_clk", SC_R_PWM_1, SC_PM_CLK_PER, LPCG_ADDR(PWM_1_LPCG), 4, 0);
+ clks[IMX8QM_PWM1_CLK] = imx_clk_gate_scu("pwm_1_clk", "pwm_1_ipg_slv_clk", SC_R_PWM_1, SC_PM_CLK_PER, LPCG_ADDR(PWM_1_LPCG), 0, 0);
+ clks[IMX8QM_PWM2_IPG_S_CLK] = imx_clk_gate_scu("pwm_2_ipg_s_clk", "pwm_2_div", SC_R_PWM_2, SC_PM_CLK_PER, LPCG_ADDR(PWM_2_LPCG), 0x10, 0);
+ clks[IMX8QM_PWM2_IPG_SLV_CLK] = imx_clk_gate_scu("pwm_2_ipg_slv_clk", "pwm_2_ipg_s_clk", SC_R_PWM_2, SC_PM_CLK_PER, LPCG_ADDR(PWM_2_LPCG), 0x14, 0);
+ clks[IMX8QM_PWM2_IPG_MSTR_CLK] = imx_clk_gate2_scu("pwm_2_ipg_mstr_clk", "lsio_bus_clk_root", LPCG_ADDR(PWM_2_LPCG), 0x18, FUNCTION_NAME(PD_LSIO_PWM_2));
+ clks[IMX8QM_PWM2_HF_CLK] = imx_clk_gate_scu("pwm_2_hf_clk", "pwm_2_ipg_slv_clk", SC_R_PWM_2, SC_PM_CLK_PER, LPCG_ADDR(PWM_2_LPCG), 4, 0);
+ clks[IMX8QM_PWM2_CLK] = imx_clk_gate_scu("pwm_2_clk", "pwm_2_ipg_slv_clk", SC_R_PWM_2, SC_PM_CLK_PER, LPCG_ADDR(PWM_2_LPCG), 0, 0);
+ clks[IMX8QM_PWM3_IPG_S_CLK] = imx_clk_gate_scu("pwm_3_ipg_s_clk", "pwm_3_div", SC_R_PWM_3, SC_PM_CLK_PER, LPCG_ADDR(PWM_3_LPCG), 0x10, 0);
+ clks[IMX8QM_PWM3_IPG_SLV_CLK] = imx_clk_gate_scu("pwm_3_ipg_slv_clk", "pwm_3_ipg_s_clk", SC_R_PWM_3, SC_PM_CLK_PER, LPCG_ADDR(PWM_3_LPCG), 0x14, 0);
+ clks[IMX8QM_PWM3_IPG_MSTR_CLK] = imx_clk_gate2_scu("pwm_3_ipg_mstr_clk", "lsio_bus_clk_root", LPCG_ADDR(PWM_3_LPCG), 0x18, FUNCTION_NAME(PD_LSIO_PWM_3));
+ clks[IMX8QM_PWM3_HF_CLK] = imx_clk_gate_scu("pwm_3_hf_clk", "pwm_3_ipg_slv_clk", SC_R_PWM_3, SC_PM_CLK_PER, LPCG_ADDR(PWM_3_LPCG), 4, 0);
+ clks[IMX8QM_PWM3_CLK] = imx_clk_gate_scu("pwm_3_clk", "pwm_3_ipg_slv_clk", SC_R_PWM_3, SC_PM_CLK_PER, LPCG_ADDR(PWM_3_LPCG), 0, 0);
+ clks[IMX8QM_PWM4_IPG_S_CLK] = imx_clk_gate_scu("pwm_4_ipg_s_clk", "pwm_4_div", SC_R_PWM_4, SC_PM_CLK_PER, LPCG_ADDR(PWM_4_LPCG), 0x10, 0);
+ clks[IMX8QM_PWM4_IPG_SLV_CLK] = imx_clk_gate_scu("pwm_4_ipg_slv_clk", "pwm_4_ipg_s_clk", SC_R_PWM_4, SC_PM_CLK_PER, LPCG_ADDR(PWM_4_LPCG), 0x14, 0);
+ clks[IMX8QM_PWM4_IPG_MSTR_CLK] = imx_clk_gate2_scu("pwm_4_ipg_mstr_clk", "lsio_bus_clk_root", LPCG_ADDR(PWM_4_LPCG), 0x18, FUNCTION_NAME(PD_LSIO_PWM_4));
+ clks[IMX8QM_PWM4_HF_CLK] = imx_clk_gate_scu("pwm_4_hf_clk", "pwm_4_ipg_slv_clk", SC_R_PWM_4, SC_PM_CLK_PER, LPCG_ADDR(PWM_4_LPCG), 4, 0);
+ clks[IMX8QM_PWM4_CLK] = imx_clk_gate_scu("pwm_4_clk", "pwm_4_ipg_slv_clk", SC_R_PWM_4, SC_PM_CLK_PER, LPCG_ADDR(PWM_4_LPCG), 0, 0);
+ clks[IMX8QM_PWM5_IPG_S_CLK] = imx_clk_gate_scu("pwm_5_ipg_s_clk", "pwm_5_div", SC_R_PWM_5, SC_PM_CLK_PER, LPCG_ADDR(PWM_5_LPCG), 0x10, 0);
+ clks[IMX8QM_PWM5_IPG_SLV_CLK] = imx_clk_gate_scu("pwm_5_ipg_slv_clk", "pwm_5_ipg_s_clk", SC_R_PWM_5, SC_PM_CLK_PER, LPCG_ADDR(PWM_5_LPCG), 0x14, 0);
+ clks[IMX8QM_PWM5_IPG_MSTR_CLK] = imx_clk_gate2_scu("pwm_5_ipg_mstr_clk", "lsio_bus_clk_root", LPCG_ADDR(PWM_5_LPCG), 0x18, FUNCTION_NAME(PD_LSIO_PWM_5));
+ clks[IMX8QM_PWM5_HF_CLK] = imx_clk_gate_scu("pwm_5_hf_clk", "pwm_5_ipg_slv_clk", SC_R_PWM_5, SC_PM_CLK_PER, LPCG_ADDR(PWM_5_LPCG), 4, 0);
+ clks[IMX8QM_PWM5_CLK] = imx_clk_gate_scu("pwm_5_clk", "pwm_5_ipg_slv_clk", SC_R_PWM_5, SC_PM_CLK_PER, LPCG_ADDR(PWM_5_LPCG), 0, 0);
+ clks[IMX8QM_PWM6_IPG_S_CLK] = imx_clk_gate_scu("pwm_6_ipg_s_clk", "pwm_6_div", SC_R_PWM_6, SC_PM_CLK_PER, LPCG_ADDR(PWM_6_LPCG), 0x10, 0);
+ clks[IMX8QM_PWM6_IPG_SLV_CLK] = imx_clk_gate_scu("pwm_6_ipg_slv_clk", "pwm_6_ipg_s_clk", SC_R_PWM_6, SC_PM_CLK_PER, LPCG_ADDR(PWM_6_LPCG), 0x14, 0);
+ clks[IMX8QM_PWM6_IPG_MSTR_CLK] = imx_clk_gate2_scu("pwm_6_ipg_mstr_clk", "lsio_bus_clk_root", LPCG_ADDR(PWM_6_LPCG), 0x18, FUNCTION_NAME(PD_LSIO_PWM_6));
+ clks[IMX8QM_PWM6_HF_CLK] = imx_clk_gate_scu("pwm_6_hf_clk", "pwm_6_ipg_slv_clk", SC_R_PWM_6, SC_PM_CLK_PER, LPCG_ADDR(PWM_6_LPCG), 4, 0);
+ clks[IMX8QM_PWM6_CLK] = imx_clk_gate_scu("pwm_6_clk", "pwm_6_ipg_slv_clk", SC_R_PWM_6, SC_PM_CLK_PER, LPCG_ADDR(PWM_6_LPCG), 0, 0);
+ clks[IMX8QM_PWM7_IPG_S_CLK] = imx_clk_gate_scu("pwm_7_ipg_s_clk", "pwm_7_div", SC_R_PWM_7, SC_PM_CLK_PER, LPCG_ADDR(PWM_7_LPCG), 0x10, 0);
+ clks[IMX8QM_PWM7_IPG_SLV_CLK] = imx_clk_gate_scu("pwm_7_ipg_slv_clk", "pwm_7_ipg_s_clk", SC_R_PWM_7, SC_PM_CLK_PER, LPCG_ADDR(PWM_7_LPCG), 0x14, 0);
+ clks[IMX8QM_PWM7_IPG_MSTR_CLK] = imx_clk_gate2_scu("pwm_7_ipg_mstr_clk", "lsio_bus_clk_root", LPCG_ADDR(PWM_7_LPCG), 0x18, FUNCTION_NAME(PD_LSIO_PWM_7));
+ clks[IMX8QM_PWM7_HF_CLK] = imx_clk_gate_scu("pwm_7_hf_clk", "pwm_7_ipg_slv_clk", SC_R_PWM_7, SC_PM_CLK_PER, LPCG_ADDR(PWM_7_LPCG), 4, 0);
+ clks[IMX8QM_PWM7_CLK] = imx_clk_gate_scu("pwm_7_clk", "pwm_7_ipg_slv_clk", SC_R_PWM_7, SC_PM_CLK_PER, LPCG_ADDR(PWM_7_LPCG), 0, 0);
+ clks[IMX8QM_GPT0_IPG_S_CLK] = imx_clk_gate_scu("gpt_0_ipg_s_clk", "gpt_0_div", SC_R_GPT_0, SC_PM_CLK_PER, LPCG_ADDR(GPT_0_LPCG), 0x10, 0);
+ clks[IMX8QM_GPT0_IPG_SLV_CLK] = imx_clk_gate_scu("gpt_0_ipg_slv_clk", "gpt_0_ipg_s_clk", SC_R_GPT_0, SC_PM_CLK_PER, LPCG_ADDR(GPT_0_LPCG), 0x14, 0);
+ clks[IMX8QM_GPT0_CLK] = imx_clk_gate_scu("gpt_0_clk", "gpt_0_ipg_slv_clk", SC_R_GPT_0, SC_PM_CLK_PER, LPCG_ADDR(GPT_0_LPCG), 0, 0);
+ clks[IMX8QM_GPT0_IPG_MSTR_CLK] = imx_clk_gate2_scu("gpt_0_ipg_mstr_clk", "lsio_bus_clk_root", LPCG_ADDR(GPT_0_LPCG), 0x18, FUNCTION_NAME(PD_LSIO_GPT_0));
+ clks[IMX8QM_GPT0_HF_CLK] = imx_clk_gate_scu("gpt_0_hf_clk", "gpt_0_ipg_slv_clk", SC_R_GPT_0, SC_PM_CLK_PER, LPCG_ADDR(GPT_0_LPCG), 4, 0);
+ clks[IMX8QM_GPT1_IPG_S_CLK] = imx_clk_gate_scu("gpt_1_ipg_s_clk", "gpt_1_div", SC_R_GPT_1, SC_PM_CLK_PER, LPCG_ADDR(GPT_1_LPCG), 0x10, 0);
+ clks[IMX8QM_GPT1_IPG_SLV_CLK] = imx_clk_gate_scu("gpt_1_ipg_slv_clk", "gpt_1_ipg_s_clk", SC_R_GPT_1, SC_PM_CLK_PER, LPCG_ADDR(GPT_1_LPCG), 0x14, 0);
+ clks[IMX8QM_GPT1_CLK] = imx_clk_gate_scu("gpt_1_clk", "gpt_1_ipg_slv_clk", SC_R_GPT_1, SC_PM_CLK_PER, LPCG_ADDR(GPT_1_LPCG), 0, 0);
+ clks[IMX8QM_GPT1_HF_CLK] = imx_clk_gate_scu("gpt_1_hf_clk", "gpt_1_ipg_slv_clk", SC_R_GPT_1, SC_PM_CLK_PER, LPCG_ADDR(GPT_1_LPCG), 4, 0);
+ clks[IMX8QM_GPT1_IPG_MSTR_CLK] = imx_clk_gate2_scu("gpt_1_ipg_mstr_clk", "lsio_bus_clk_root", LPCG_ADDR(GPT_1_LPCG), 0x18, FUNCTION_NAME(PD_LSIO_GPT_1));
+ clks[IMX8QM_GPT2_IPG_S_CLK] = imx_clk_gate_scu("gpt_2_ipg_s_clk", "gpt_2_div", SC_R_GPT_2, SC_PM_CLK_PER, LPCG_ADDR(GPT_2_LPCG), 0x10, 0);
+ clks[IMX8QM_GPT2_IPG_SLV_CLK] = imx_clk_gate_scu("gpt_2_ipg_slv_clk", "gpt_2_ipg_s_clk", SC_R_GPT_2, SC_PM_CLK_PER, LPCG_ADDR(GPT_2_LPCG), 0x14, 0);
+ clks[IMX8QM_GPT2_CLK] = imx_clk_gate_scu("gpt_2_clk", "gpt_2_ipg_slv_clk", SC_R_GPT_2, SC_PM_CLK_PER, LPCG_ADDR(GPT_2_LPCG), 0, 0);
+ clks[IMX8QM_GPT2_HF_CLK] = imx_clk_gate_scu("gpt_2_hf_clk", "gpt_2_ipg_slv_clk", SC_R_GPT_2, SC_PM_CLK_PER, LPCG_ADDR(GPT_2_LPCG), 4, 0);
+ clks[IMX8QM_GPT2_IPG_MSTR_CLK] = imx_clk_gate2_scu("gpt_2_ipg_mstr_clk", "lsio_bus_clk_root", LPCG_ADDR(GPT_2_LPCG), 0x18, FUNCTION_NAME(PD_LSIO_GPT_2));
+ clks[IMX8QM_GPT3_IPG_S_CLK] = imx_clk_gate_scu("gpt_3_ipg_s_clk", "gpt_3_div", SC_R_GPT_3, SC_PM_CLK_PER, LPCG_ADDR(GPT_3_LPCG), 0x10, 0);
+ clks[IMX8QM_GPT3_IPG_SLV_CLK] = imx_clk_gate_scu("gpt_3_ipg_slv_clk", "gpt_3_ipg_s_clk", SC_R_GPT_3, SC_PM_CLK_PER, LPCG_ADDR(GPT_3_LPCG), 0x14, 0);
+ clks[IMX8QM_GPT3_CLK] = imx_clk_gate_scu("gpt_3_clk", "gpt_3_ipg_slv_clk", SC_R_GPT_3, SC_PM_CLK_PER, LPCG_ADDR(GPT_3_LPCG), 0, 0);
+ clks[IMX8QM_GPT3_HF_CLK] = imx_clk_gate_scu("gpt_3_hf_clk", "gpt_3_ipg_slv_clk", SC_R_GPT_3, SC_PM_CLK_PER, LPCG_ADDR(GPT_3_LPCG), 4, 0);
+ clks[IMX8QM_GPT3_IPG_MSTR_CLK] = imx_clk_gate2_scu("gpt_3_ipg_mstr_clk", "lsio_bus_clk_root", LPCG_ADDR(GPT_3_LPCG), 0x18, FUNCTION_NAME(PD_LSIO_GPT_3));
+ clks[IMX8QM_GPT4_IPG_S_CLK] = imx_clk_gate_scu("gpt_4_ipg_s_clk", "gpt_4_div", SC_R_GPT_4, SC_PM_CLK_PER, LPCG_ADDR(GPT_4_LPCG), 0x10, 0);
+ clks[IMX8QM_GPT4_IPG_SLV_CLK] = imx_clk_gate_scu("gpt_4_ipg_slv_clk", "gpt_4_ipg_s_clk", SC_R_GPT_4, SC_PM_CLK_PER, LPCG_ADDR(GPT_4_LPCG), 0x14, 0);
+ clks[IMX8QM_GPT4_CLK] = imx_clk_gate_scu("gpt_4_clk", "gpt_4_ipg_slv_clk", SC_R_GPT_4, SC_PM_CLK_PER, LPCG_ADDR(GPT_4_LPCG), 0, 0);
+ clks[IMX8QM_GPT4_HF_CLK] = imx_clk_gate_scu("gpt_4_hf_clk", "gpt_4_ipg_slv_clk", SC_R_GPT_4, SC_PM_CLK_PER, LPCG_ADDR(GPT_4_LPCG), 4, 0);
+ clks[IMX8QM_GPT4_IPG_MSTR_CLK] = imx_clk_gate2_scu("gpt_4_ipg_mstr_clk", "lsio_bus_clk_root", LPCG_ADDR(GPT_4_LPCG), 0x18, FUNCTION_NAME(PD_LSIO_GPT_4));
+ clks[IMX8QM_FSPI0_HCLK] = imx_clk_gate2_scu("fspi0_hclk_clk", "lsio_mem_clk_root", LPCG_ADDR(FSPI_0_LPCG), 0x10, FUNCTION_NAME(PD_LSIO_FSPI_0));
+ clks[IMX8QM_FSPI0_IPG_S_CLK] = imx_clk_gate2_scu("fspi0_ipg_s_clk", "lsio_bus_clk_root", LPCG_ADDR(FSPI_0_LPCG), 0x18, FUNCTION_NAME(PD_LSIO_FSPI_0));
+ clks[IMX8QM_FSPI0_IPG_CLK] = imx_clk_gate2_scu("fspi0_ipg_clk", "fspi0_ipg_s_clk", LPCG_ADDR(FSPI_0_LPCG), 0x14, FUNCTION_NAME(PD_LSIO_FSPI_0));
+ clks[IMX8QM_FSPI0_CLK] = imx_clk_gate_scu("fspi_0_clk", "fspi_0_div", SC_R_FSPI_0, SC_PM_CLK_PER, LPCG_ADDR(FSPI_0_LPCG), 0, 0);
+ clks[IMX8QM_FSPI1_HCLK] = imx_clk_gate2_scu("fspi1_hclk_clk", "lsio_mem_clk_root", LPCG_ADDR(FSPI_1_LPCG), 0x10, FUNCTION_NAME(PD_LSIO_FSPI_1));
+ clks[IMX8QM_FSPI1_IPG_S_CLK] = imx_clk_gate2_scu("fspi1_ipg_s_clk", "lsio_bus_clk_root", LPCG_ADDR(FSPI_1_LPCG), 0x18, FUNCTION_NAME(PD_LSIO_FSPI_1));
+ clks[IMX8QM_FSPI1_IPG_CLK] = imx_clk_gate2_scu("fspi1_ipg_clk", "fspi1_ipg_s_clk", LPCG_ADDR(FSPI_1_LPCG), 0x14, FUNCTION_NAME(PD_LSIO_FSPI_1));
+ clks[IMX8QM_FSPI1_CLK] = imx_clk_gate_scu("fspi_1_clk", "fspi_1_div", SC_R_FSPI_1, SC_PM_CLK_PER, LPCG_ADDR(FSPI_1_LPCG), 0, 0);
+
+ clks[IMX8QM_LSIO_MU5A_IPG_S_CLK] = imx_clk_gate2_scu("mu5_a_ipg_s_clk", "lsio_bus_clk_root", LPCG_ADDR(MU_5A_LPCG), 0x10, FUNCTION_NAME(PD_LSIO_MU5A));
+ clks[IMX8QM_LSIO_MU5A_IPG_CLK] = imx_clk_gate2_scu("mu5_a_ipg_clk", "mu5_a_ipg_s_clk", LPCG_ADDR(MU_5A_LPCG), 0x0, FUNCTION_NAME(PD_LSIO_MU5A));
+ clks[IMX8QM_LSIO_MU6A_IPG_S_CLK] = imx_clk_gate2_scu("mu6_a_ipg_s_clk", "lsio_bus_clk_root", LPCG_ADDR(MU_6A_LPCG), 0x10, FUNCTION_NAME(PD_LSIO_MU6A));
+ clks[IMX8QM_LSIO_MU6A_IPG_CLK] = imx_clk_gate2_scu("mu6_a_ipg_clk", "mu6_a_ipg_s_clk", LPCG_ADDR(MU_6A_LPCG), 0x0, FUNCTION_NAME(PD_LSIO_MU6A));
+ /* Audio */
+ clks[IMX8QM_AUD_ACM_AUD_PLL_CLK0_CLK] = imx_clk_gate_scu("aud_acm_aud_pll_clk0_clk", "aud_acm_aud_pll_clk0_div", SC_R_AUDIO_PLL_0, SC_PM_CLK_MISC0, LPCG_ADDR(AUD_PLL_CLK0_LPCG), 0, 0);
+ clks[IMX8QM_AUD_ACM_AUD_PLL_CLK1_CLK] = imx_clk_gate_scu("aud_acm_aud_pll_clk1_clk", "aud_acm_aud_pll_clk1_div", SC_R_AUDIO_PLL_1, SC_PM_CLK_MISC0, LPCG_ADDR(AUD_PLL_CLK1_LPCG), 0, 0);
+ clks[IMX8QM_AUD_ACM_AUD_REC_CLK0_CLK] = imx_clk_gate_scu("aud_acm_aud_rec_clk0_clk", "aud_acm_aud_rec_clk0_div", SC_R_AUDIO_PLL_0, SC_PM_CLK_MISC1, LPCG_ADDR(AUD_REC_CLK0_LPCG), 0, 0);
+ clks[IMX8QM_AUD_ACM_AUD_REC_CLK1_CLK] = imx_clk_gate_scu("aud_acm_aud_rec_clk1_clk", "aud_acm_aud_rec_clk1_div", SC_R_AUDIO_PLL_1, SC_PM_CLK_MISC1, LPCG_ADDR(AUD_REC_CLK1_LPCG), 0, 0);
+
+ clks[IMX8QM_HDMI_RX_MCLK] = imx_clk_fixed("hdmi_rx_mclk", 0);
+ clks[IMX8QM_EXT_AUD_MCLK0] = imx_clk_fixed("ext_aud_mclk0", 0);
+ clks[IMX8QM_EXT_AUD_MCLK1] = imx_clk_fixed("ext_aud_mclk1", 0);
+ clks[IMX8QM_ESAI0_RX_CLK] = imx_clk_fixed("esai0_rx_clk", 0);
+ clks[IMX8QM_ESAI0_RX_HF_CLK] = imx_clk_fixed("esai0_rx_hf_clk", 0);
+ clks[IMX8QM_ESAI0_TX_CLK] = imx_clk_fixed("esai0_tx_clk", 0);
+ clks[IMX8QM_ESAI0_TX_HF_CLK] = imx_clk_fixed("esai0_tx_hf_clk", 0);
+ clks[IMX8QM_ESAI1_RX_CLK] = imx_clk_fixed("esai1_rx_clk", 0);
+ clks[IMX8QM_ESAI1_RX_HF_CLK] = imx_clk_fixed("esai1_rx_hf_clk", 0);
+ clks[IMX8QM_ESAI1_TX_CLK] = imx_clk_fixed("esai1_tx_clk", 0);
+ clks[IMX8QM_ESAI1_TX_HF_CLK] = imx_clk_fixed("esai1_tx_hf_clk", 0);
+ clks[IMX8QM_SPDIF0_RX] = imx_clk_fixed("spdif0_rx", 0);
+ clks[IMX8QM_SPDIF1_RX] = imx_clk_fixed("spdif1_rx", 0);
+ clks[IMX8QM_SAI0_RX_BCLK] = imx_clk_fixed("sai0_rx_bclk", 0);
+ clks[IMX8QM_SAI0_TX_BCLK] = imx_clk_fixed("sai0_tx_bclk", 0);
+ clks[IMX8QM_SAI1_RX_BCLK] = imx_clk_fixed("sai1_rx_bclk", 0);
+ clks[IMX8QM_SAI1_TX_BCLK] = imx_clk_fixed("sai1_tx_bclk", 0);
+ clks[IMX8QM_SAI2_RX_BCLK] = imx_clk_fixed("sai2_rx_bclk", 0);
+ clks[IMX8QM_SAI3_RX_BCLK] = imx_clk_fixed("sai3_rx_bclk", 0);
+ clks[IMX8QM_HDMI_RX_SAI0_RX_BCLK] = imx_clk_fixed("hdmi_rx_sai0_rx_bclk", 0);
+ clks[IMX8QM_SAI6_RX_BCLK] = imx_clk_fixed("sai6_rx_bclk", 0);
+ clks[IMX8QM_HDMI_TX_SAI0_TX_BCLK] = imx_clk_fixed("hdmi_tx_sai0_tx_bclk", 0);
+ clks[IMX8QM_CM40_IPG_CLK] = imx_clk_fixed("ipg_cm40_clk_root", SC_132MHZ);
+ clks[IMX8QM_CM41_IPG_CLK] = imx_clk_fixed("ipg_cm41_clk_root", SC_132MHZ);
+
+ np_acm = of_find_compatible_node(NULL, NULL, "nxp,imx8qm-acm");
+ if (np_acm) {
+ base_acm = of_iomap(np_acm, 0);
+ WARN_ON(!base_acm);
+
+ clks[IMX8QM_ACM_AUD_CLK0_SEL] = imx_clk_mux_scu("acm_aud_clk0_sel", base_acm + 0x00000, 0, 5, aud_clk_sels, ARRAY_SIZE(aud_clk_sels), FUNCTION_NAME(PD_AUDIO));
+ clks[IMX8QM_ACM_AUD_CLK0_CLK] = imx_clk_gate_scu("acm_aud_clk0_clk", "acm_aud_clk0_sel", SC_R_AUDIO_CLK_0, SC_PM_CLK_SLV_BUS, NULL, 0, 0);
+
+ clks[IMX8QM_ACM_AUD_CLK1_SEL] = imx_clk_mux_scu("acm_aud_clk1_sel", base_acm + 0x10000, 0, 5, aud_clk_sels, ARRAY_SIZE(aud_clk_sels), FUNCTION_NAME(PD_AUDIO));
+ clks[IMX8QM_ACM_AUD_CLK1_CLK] = imx_clk_gate_scu("acm_aud_clk1_clk", "acm_aud_clk1_sel", SC_R_AUDIO_CLK_1, SC_PM_CLK_SLV_BUS, NULL, 0, 0);
+ clks[IMX8QM_ACM_MCLKOUT0_SEL] = imx_clk_mux_scu("acm_mclkout0_sel", base_acm + 0x20000, 0, 3, mclk_out_sels, ARRAY_SIZE(mclk_out_sels), FUNCTION_NAME(PD_AUDIO));
+ clks[IMX8QM_ACM_MCLKOUT1_SEL] = imx_clk_mux_scu("acm_mclkout1_sel", base_acm + 0x30000, 0, 3, mclk_out_sels, ARRAY_SIZE(mclk_out_sels), FUNCTION_NAME(PD_AUDIO));
+ clks[IMX8QM_ACM_SAI0_MCLK_SEL] = imx_clk_mux_scu("acm_sai0_mclk_sel", base_acm + 0xE0000, 0, 2, sai_mclk_sels, ARRAY_SIZE(sai_mclk_sels), FUNCTION_NAME(PD_AUD_SAI_0));
+ clks[IMX8QM_ACM_SAI1_MCLK_SEL] = imx_clk_mux_scu("acm_sai1_mclk_sel", base_acm + 0xF0000, 0, 2, sai_mclk_sels, ARRAY_SIZE(sai_mclk_sels), FUNCTION_NAME(PD_AUD_SAI_1));
+ clks[IMX8QM_ACM_SAI2_MCLK_SEL] = imx_clk_mux_scu("acm_sai2_mclk_sel", base_acm + 0x100000, 0, 2, sai_mclk_sels, ARRAY_SIZE(sai_mclk_sels), FUNCTION_NAME(PD_AUD_SAI_2));
+ clks[IMX8QM_ACM_SAI3_MCLK_SEL] = imx_clk_mux_scu("acm_sai3_mclk_sel", base_acm + 0x110000, 0, 2, sai_mclk_sels, ARRAY_SIZE(sai_mclk_sels), FUNCTION_NAME(PD_AUD_SAI_3));
+ clks[IMX8QM_ACM_HDMI_RX_SAI0_MCLK_SEL] = imx_clk_mux_scu("acm_hdmi_rx_sai0_mclk_sel", base_acm + 0x120000, 0, 2, sai_mclk_sels, ARRAY_SIZE(sai_mclk_sels), FUNCTION_NAME(PD_AUD_SAI_4));
+ clks[IMX8QM_ACM_HDMI_TX_SAI0_MCLK_SEL] = imx_clk_mux_scu("acm_hdmi_tx_sai0_mclk_sel", base_acm + 0x130000, 0, 2, sai_mclk_sels, ARRAY_SIZE(sai_mclk_sels), FUNCTION_NAME(PD_AUD_SAI_5));
+ clks[IMX8QM_ACM_SAI6_MCLK_SEL] = imx_clk_mux_scu("acm_sai6_mclk_sel", base_acm + 0x140000, 0, 2, sai_mclk_sels, ARRAY_SIZE(sai_mclk_sels), FUNCTION_NAME(PD_AUD_SAI_6));
+ clks[IMX8QM_ACM_SAI7_MCLK_SEL] = imx_clk_mux_scu("acm_sai7_mclk_sel", base_acm + 0x150000, 0, 2, sai_mclk_sels, ARRAY_SIZE(sai_mclk_sels), FUNCTION_NAME(PD_AUD_SAI_7));
+ clks[IMX8QM_ACM_SPDIF0_TX_CLK_SEL] = imx_clk_mux_scu("acm_spdif0_mclk_sel", base_acm + 0x1A0000, 0, 2, spdif_mclk_sels, ARRAY_SIZE(spdif_mclk_sels), FUNCTION_NAME(PD_AUD_SPDIF_0));
+ clks[IMX8QM_ACM_SPDIF1_TX_CLK_SEL] = imx_clk_mux_scu("acm_spdif1_mclk_sel", base_acm + 0x1B0000, 0, 2, spdif_mclk_sels, ARRAY_SIZE(spdif_mclk_sels), FUNCTION_NAME(PD_AUD_SPDIF_1));
+ clks[IMX8QM_ACM_MQS_TX_CLK_SEL] = imx_clk_mux_scu("acm_mqs_mclk_sel", base_acm + 0x1C0000, 0, 2, mqs_mclk_sels, ARRAY_SIZE(mqs_mclk_sels), FUNCTION_NAME(PD_AUD_MQS_0));
+ clks[IMX8QM_ACM_ASRC0_MUX_CLK_SEL] = imx_clk_mux_scu("acm_asrc0_mclk_sel", base_acm + 0x40000, 0, 2, asrc_mux_clk_sels, ARRAY_SIZE(asrc_mux_clk_sels), FUNCTION_NAME(PD_AUD_ASRC_0));
+ clks[IMX8QM_ACM_ASRC1_MUX_CLK_SEL] = imx_clk_mux_scu("acm_asrc1_mclk_sel", base_acm + 0x50000, 0, 2, asrc_mux_clk_sels, ARRAY_SIZE(asrc_mux_clk_sels), FUNCTION_NAME(PD_AUD_ASRC_1));
+ clks[IMX8QM_ACM_ESAI0_MCLK_SEL] = imx_clk_mux_scu("acm_esai0_mclk_sel", base_acm + 0x60000, 0, 2, esai_mclk_sels, ARRAY_SIZE(esai_mclk_sels), FUNCTION_NAME(PD_AUD_ESAI_0));
+ clks[IMX8QM_ACM_ESAI1_MCLK_SEL] = imx_clk_mux_scu("acm_esai1_mclk_sel", base_acm + 0x70000, 0, 2, esai_mclk_sels, ARRAY_SIZE(esai_mclk_sels), FUNCTION_NAME(PD_AUD_ESAI_1));
+ } else
+ printk("clk-imx8qm: missing acm node, skipping\n");
+
+ clks[IMX8QM_AUD_AMIX_IPG] = imx_clk_gate2_scu("aud_amix_ipg_clk", "ipg_aud_clk_root", LPCG_ADDR(AUD_AMIX_LPCG), 0, FUNCTION_NAME(PD_AUD_AMIX));
+ clks[IMX8QM_AUD_ESAI_0_IPG] = imx_clk_gate2_scu("aud_esai0_ipg_clk", "ipg_aud_clk_root", LPCG_ADDR(AUD_ESAI_0_LPCG), 0, FUNCTION_NAME(PD_AUD_ESAI_0));
+ clks[IMX8QM_AUD_ESAI_1_IPG] = imx_clk_gate2_scu("aud_esai1_ipg_clk", "ipg_aud_clk_root", LPCG_ADDR(AUD_ESAI_1_LPCG), 0, FUNCTION_NAME(PD_AUD_ESAI_1));
+ clks[IMX8QM_AUD_ESAI_0_EXTAL_IPG] = imx_clk_gate2_scu("aud_esai0_extal_ipg_clk", "acm_esai0_mclk_sel", LPCG_ADDR(AUD_ESAI_0_LPCG), 16, FUNCTION_NAME(PD_AUD_ESAI_0));
+ clks[IMX8QM_AUD_ESAI_1_EXTAL_IPG] = imx_clk_gate2_scu("aud_esai1_extal_ipg_clk", "acm_esai1_mclk_sel", LPCG_ADDR(AUD_ESAI_1_LPCG), 16, FUNCTION_NAME(PD_AUD_ESAI_1));
+ clks[IMX8QM_AUD_SAI_0_IPG_S] = imx_clk_gate2_scu("aud_sai0_ipg_s_clk", "ipg_aud_clk_root", LPCG_ADDR(AUD_SAI_0_LPCG), 8, FUNCTION_NAME(PD_AUD_SAI_0));
+ clks[IMX8QM_AUD_SAI_0_IPG] = imx_clk_gate2_scu("aud_sai0_ipg_clk", "aud_sai0_ipg_s_clk", LPCG_ADDR(AUD_SAI_0_LPCG), 0, FUNCTION_NAME(PD_AUD_SAI_0));
+ clks[IMX8QM_AUD_SAI_0_MCLK] = imx_clk_gate2_scu("aud_sai0_mclk_clk", "acm_sai0_mclk_sel", LPCG_ADDR(AUD_SAI_0_LPCG), 16, FUNCTION_NAME(PD_AUD_SAI_0));
+ clks[IMX8QM_AUD_SAI_1_IPG_S] = imx_clk_gate2_scu("aud_sai1_ipg_s_clk", "ipg_aud_clk_root", LPCG_ADDR(AUD_SAI_1_LPCG), 8, FUNCTION_NAME(PD_AUD_SAI_1));
+ clks[IMX8QM_AUD_SAI_1_IPG] = imx_clk_gate2_scu("aud_sai1_ipg_clk", "aud_sai1_ipg_s_clk", LPCG_ADDR(AUD_SAI_1_LPCG), 0, FUNCTION_NAME(PD_AUD_SAI_1));
+ clks[IMX8QM_AUD_SAI_1_MCLK] = imx_clk_gate2_scu("aud_sai1_mclk_clk", "acm_sai1_mclk_sel", LPCG_ADDR(AUD_SAI_1_LPCG), 16, FUNCTION_NAME(PD_AUD_SAI_1));
+ clks[IMX8QM_AUD_SAI_2_IPG_S] = imx_clk_gate2_scu("aud_sai2_ipg_s_clk", "ipg_aud_clk_root", LPCG_ADDR(AUD_SAI_2_LPCG), 8, FUNCTION_NAME(PD_AUD_SAI_2));
+ clks[IMX8QM_AUD_SAI_2_IPG] = imx_clk_gate2_scu("aud_sai2_ipg_clk", "aud_sai2_ipg_s_clk", LPCG_ADDR(AUD_SAI_2_LPCG), 0, FUNCTION_NAME(PD_AUD_SAI_2));
+ clks[IMX8QM_AUD_SAI_2_MCLK] = imx_clk_gate2_scu("aud_sai2_mclk_clk", "acm_sai2_mclk_sel", LPCG_ADDR(AUD_SAI_2_LPCG), 16, FUNCTION_NAME(PD_AUD_SAI_2));
+ clks[IMX8QM_AUD_SAI_3_IPG_S] = imx_clk_gate2_scu("aud_sai3_ipg_s_clk", "ipg_aud_clk_root", LPCG_ADDR(AUD_SAI_3_LPCG), 8, FUNCTION_NAME(PD_AUD_SAI_3));
+ clks[IMX8QM_AUD_SAI_3_IPG] = imx_clk_gate2_scu("aud_sai3_ipg_clk", "aud_sai3_ipg_s_clk", LPCG_ADDR(AUD_SAI_3_LPCG), 0, FUNCTION_NAME(PD_AUD_SAI_3));
+ clks[IMX8QM_AUD_SAI_3_MCLK] = imx_clk_gate2_scu("aud_sai3_mclk_clk", "acm_sai3_mclk_sel", LPCG_ADDR(AUD_SAI_3_LPCG), 16, FUNCTION_NAME(PD_AUD_SAI_3));
+ clks[IMX8QM_AUD_SAI_6_IPG_S] = imx_clk_gate2_scu("aud_sai6_ipg_s_clk", "ipg_aud_clk_root", LPCG_ADDR(AUD_SAI_6_LPCG), 8, FUNCTION_NAME(PD_AUD_SAI_6));
+ clks[IMX8QM_AUD_SAI_6_IPG] = imx_clk_gate2_scu("aud_sai6_ipg_clk", "aud_sai6_ipg_s_clk", LPCG_ADDR(AUD_SAI_6_LPCG), 0, FUNCTION_NAME(PD_AUD_SAI_6));
+ clks[IMX8QM_AUD_SAI_6_MCLK] = imx_clk_gate2_scu("aud_sai6_mclk_clk", "acm_sai6_mclk_sel", LPCG_ADDR(AUD_SAI_6_LPCG), 16, FUNCTION_NAME(PD_AUD_SAI_6));
+ clks[IMX8QM_AUD_SAI_7_IPG_S] = imx_clk_gate2_scu("aud_sai7_ipg_s_clk", "ipg_aud_clk_root", LPCG_ADDR(AUD_SAI_7_LPCG), 8, FUNCTION_NAME(PD_AUD_SAI_7));
+ clks[IMX8QM_AUD_SAI_7_IPG] = imx_clk_gate2_scu("aud_sai7_ipg_clk", "aud_sai7_ipg_s_clk", LPCG_ADDR(AUD_SAI_7_LPCG), 0, FUNCTION_NAME(PD_AUD_SAI_7));
+ clks[IMX8QM_AUD_SAI_7_MCLK] = imx_clk_gate2_scu("aud_sai7_mclk_clk", "acm_sai7_mclk_sel", LPCG_ADDR(AUD_SAI_7_LPCG), 16, FUNCTION_NAME(PD_AUD_SAI_7));
+ clks[IMX8QM_AUD_SAI_HDMIRX0_IPG_S] = imx_clk_gate2_scu("aud_sai_hdmirx0_ipg_s_clk", "ipg_aud_clk_root", LPCG_ADDR(AUD_HDMI_RX_SAI_0_LPCG), 8, FUNCTION_NAME(PD_AUD_SAI_4));
+ clks[IMX8QM_AUD_SAI_HDMIRX0_IPG] = imx_clk_gate2_scu("aud_sai_hdmirx0_ipg_clk", "aud_sai_hdmirx0_ipg_s_clk", LPCG_ADDR(AUD_HDMI_RX_SAI_0_LPCG), 0, FUNCTION_NAME(PD_AUD_SAI_4));
+ clks[IMX8QM_AUD_SAI_HDMIRX0_MCLK] = imx_clk_gate2_scu("aud_sai_hdmirx0_mclk_clk", "acm_hdmi_rx_sai0_mclk_sel", LPCG_ADDR(AUD_HDMI_RX_SAI_0_LPCG), 16, FUNCTION_NAME(PD_AUD_SAI_4));
+ clks[IMX8QM_AUD_SAI_HDMITX0_IPG_S] = imx_clk_gate2_scu("aud_sai_hdmitx0_ipg_s_clk", "ipg_aud_clk_root", LPCG_ADDR(AUD_HDMI_TX_SAI_0_LPCG), 8, FUNCTION_NAME(PD_AUD_SAI_5));
+ clks[IMX8QM_AUD_SAI_HDMITX0_IPG] = imx_clk_gate2_scu("aud_sai_hdmitx0_ipg_clk", "aud_sai_hdmitx0_ipg_s_clk", LPCG_ADDR(AUD_HDMI_TX_SAI_0_LPCG), 0, FUNCTION_NAME(PD_AUD_SAI_5));
+ clks[IMX8QM_AUD_SAI_HDMITX0_MCLK] = imx_clk_gate2_scu("aud_sai_hdmitx0_mclk_clk", "acm_hdmi_tx_sai0_mclk_sel", LPCG_ADDR(AUD_HDMI_TX_SAI_0_LPCG), 16, FUNCTION_NAME(PD_AUD_SAI_5));
+ clks[IMX8QM_AUD_MQS_IPG] = imx_clk_gate2_scu("aud_mqs_ipg", "ipg_aud_clk_root", LPCG_ADDR(AUD_MQS_LPCG), 0, FUNCTION_NAME(PD_AUD_MQS_0));
+ clks[IMX8QM_AUD_MQS_HMCLK] = imx_clk_gate2_scu("aud_mqs_hm_clk", "acm_mqs_mclk_sel", LPCG_ADDR(AUD_MQS_LPCG), 16, FUNCTION_NAME(PD_AUD_MQS_0));
+ clks[IMX8QM_AUD_GPT5_IPG_S] = imx_clk_gate2_scu("aud_gpt5_ipg", "ipg_aud_clk_root", LPCG_ADDR(AUD_GPT_5_LPCG), 0, FUNCTION_NAME(PD_AUD_GPT_5));
+ clks[IMX8QM_AUD_GPT5_24M_CLK] = imx_clk_gate2_scu("aud_gpt5_24MHz", "xtal_24MHz", LPCG_ADDR(AUD_GPT_5_LPCG), 20, FUNCTION_NAME(PD_AUD_GPT_5));
+ clks[IMX8QM_AUD_GPT6_IPG_S] = imx_clk_gate2_scu("aud_gpt6_ipg", "ipg_aud_clk_root", LPCG_ADDR(AUD_GPT_6_LPCG), 0, FUNCTION_NAME(PD_AUD_GPT_6));
+ clks[IMX8QM_AUD_GPT6_24M_CLK] = imx_clk_gate2_scu("aud_gpt6_24MHz", "xtal_24MHz", LPCG_ADDR(AUD_GPT_6_LPCG), 20, FUNCTION_NAME(PD_AUD_GPT_6));
+ clks[IMX8QM_AUD_GPT7_IPG_S] = imx_clk_gate2_scu("aud_gpt7_ipg", "ipg_aud_clk_root", LPCG_ADDR(AUD_GPT_7_LPCG), 0, FUNCTION_NAME(PD_AUD_GPT_7));
+ clks[IMX8QM_AUD_GPT7_24M_CLK] = imx_clk_gate2_scu("aud_gpt7_24MHz", "xtal_24MHz", LPCG_ADDR(AUD_GPT_7_LPCG), 20, FUNCTION_NAME(PD_AUD_GPT_7));
+ clks[IMX8QM_AUD_GPT8_IPG_S] = imx_clk_gate2_scu("aud_gpt8_ipg", "ipg_aud_clk_root", LPCG_ADDR(AUD_GPT_8_LPCG), 0, FUNCTION_NAME(PD_AUD_GPT_8));
+ clks[IMX8QM_AUD_GPT8_24M_CLK] = imx_clk_gate2_scu("aud_gpt8_24MHz", "xtal_24MHz", LPCG_ADDR(AUD_GPT_8_LPCG), 20, FUNCTION_NAME(PD_AUD_GPT_8));
+ clks[IMX8QM_AUD_GPT9_IPG_S] = imx_clk_gate2_scu("aud_gpt9_ipg", "ipg_aud_clk_root", LPCG_ADDR(AUD_GPT_9_LPCG), 0, FUNCTION_NAME(PD_AUD_GPT_9));
+ clks[IMX8QM_AUD_GPT9_24M_CLK] = imx_clk_gate2_scu("aud_gpt9_24MHz", "xtal_24MHz", LPCG_ADDR(AUD_GPT_9_LPCG), 20, FUNCTION_NAME(PD_AUD_GPT_9));
+ clks[IMX8QM_AUD_GPT10_IPG_S] = imx_clk_gate2_scu("aud_gpt10_ipg", "ipg_aud_clk_root", LPCG_ADDR(AUD_GPT_10_LPCG), 0, FUNCTION_NAME(PD_AUD_GPT_9));
+ clks[IMX8QM_AUD_GPT10_24M_CLK] = imx_clk_gate2_scu("aud_gpt10_24MHz", "xtal_24MHz", LPCG_ADDR(AUD_GPT_10_LPCG), 20, FUNCTION_NAME(PD_AUD_GPT_9));
+ clks[IMX8QM_AUD_MCLKOUT0] = imx_clk_gate2_scu("aud_mclkout0", "acm_mclkout0_sel", LPCG_ADDR(AUD_MCLKOUT0_LPCG), 0, FUNCTION_NAME(PD_AUDIO));
+ clks[IMX8QM_AUD_MCLKOUT1] = imx_clk_gate2_scu("aud_mclkout1", "acm_mclkout1_sel", LPCG_ADDR(AUD_MCLKOUT1_LPCG), 0, FUNCTION_NAME(PD_AUDIO));
+ clks[IMX8QM_AUD_SPDIF_0_IPG_S] = imx_clk_gate2_scu("spdif0_ipg_s", "ipg_aud_clk_root", LPCG_ADDR(AUD_SPDIF_0_LPCG), 0, FUNCTION_NAME(PD_AUD_SPDIF_0));
+ clks[IMX8QM_AUD_SPDIF_0_GCLKW] = imx_clk_gate2_scu("spdif0_gclkw", "spdif0_ipg_s", LPCG_ADDR(AUD_SPDIF_0_LPCG), 16, FUNCTION_NAME(PD_AUD_SPDIF_0));
+ clks[IMX8QM_AUD_SPDIF_0_TX_CLK] = imx_clk_gate2_scu("spdif0_tx_clk", "acm_spdif0_mclk_sel", LPCG_ADDR(AUD_SPDIF_0_LPCG), 20, FUNCTION_NAME(PD_AUD_SPDIF_0));
+ clks[IMX8QM_AUD_SPDIF_1_IPG_S] = imx_clk_gate2_scu("spdif1_ipg_s", "ipg_aud_clk_root", LPCG_ADDR(AUD_SPDIF_1_LPCG), 0, FUNCTION_NAME(PD_AUD_SPDIF_1));
+ clks[IMX8QM_AUD_SPDIF_1_GCLKW] = imx_clk_gate2_scu("spdif1_gclkw", "spdif1_ipg_s", LPCG_ADDR(AUD_SPDIF_1_LPCG), 16, FUNCTION_NAME(PD_AUD_SPDIF_1));
+ clks[IMX8QM_AUD_SPDIF_1_TX_CLK] = imx_clk_gate2_scu("spdif1_tx_clk", "acm_spdif1_mclk_sel", LPCG_ADDR(AUD_SPDIF_1_LPCG), 20, FUNCTION_NAME(PD_AUD_SPDIF_1));
+ clks[IMX8QM_AUD_ASRC_0_IPG] = imx_clk_gate2_scu("aud_asrc0_ipg", "ipg_aud_clk_root", LPCG_ADDR(AUD_ASRC_0_LPCG), 0, FUNCTION_NAME(PD_AUD_ASRC_0));
+ clks[IMX8QM_AUD_ASRC_0_MEM] = imx_clk_gate2_scu("aud_asrc0_mem", "ipg_aud_clk_root", LPCG_ADDR(AUD_ASRC_0_LPCG), 8, FUNCTION_NAME(PD_AUD_ASRC_0));
+ clks[IMX8QM_AUD_ASRC_1_IPG] = imx_clk_gate2_scu("aud_asrc1_ipg", "ipg_aud_clk_root", LPCG_ADDR(AUD_ASRC_1_LPCG), 0, FUNCTION_NAME(PD_AUD_ASRC_1));
+ clks[IMX8QM_AUD_ASRC_1_MEM] = imx_clk_gate2_scu("aud_asrc1_mem", "ipg_aud_clk_root", LPCG_ADDR(AUD_ASRC_1_LPCG), 8, FUNCTION_NAME(PD_AUD_ASRC_1));
+ clks[IMX8QM_ACM_ASRC0_MUX_CLK_CLK] = imx_clk_gate_scu("aud_asrc0_mux_clk", "acm_asrc0_mclk_sel", SC_R_ASRC_0, SC_PM_CLK_PER, NULL, 0, 0);
+ clks[IMX8QM_ACM_ASRC1_MUX_CLK_CLK] = imx_clk_gate_scu("aud_asrc1_mux_clk", "acm_asrc1_mclk_sel", SC_R_ASRC_1, SC_PM_CLK_PER, NULL, 0, 0);
+
+ /* DSP */
+ clks[IMX8QM_AUD_DSP_ADB_ACLK] = imx_clk_gate2_scu("aud_dsp_adb_aclk", "ipg_aud_clk_root", LPCG_ADDR(AUD_DSP_LPCG), 16, FUNCTION_NAME(PD_AUD_DSP));
+ clks[IMX8QM_AUD_DSP_IPG] = imx_clk_gate2_scu("aud_dsp_ipg", "ipg_aud_clk_root", LPCG_ADDR(AUD_DSP_LPCG), 20, FUNCTION_NAME(PD_AUD_DSP));
+ clks[IMX8QM_AUD_DSP_CORE_CLK] = imx_clk_gate2_scu("aud_dsp_core_clk", "ipg_aud_clk_root", LPCG_ADDR(AUD_DSP_LPCG), 28, FUNCTION_NAME(PD_AUD_DSP));
+ clks[IMX8QM_AUD_OCRAM_IPG] = imx_clk_gate2_scu("aud_ocram_ipg", "ipg_aud_clk_root", LPCG_ADDR(AUD_OCRAM_LPCG), 16, FUNCTION_NAME(PD_AUD_OCRAM));
+
+ /* MIPI CSI */
+ clks[IMX8QM_CSI0_I2C0_IPG_CLK] = imx_clk_gate2_scu("mipi_csi0_i2c0_ipg_s", "ipg_mipi_csi_clk_root", LPCG_ADDR(MIPI_CSI_0_LPCG + 0x14), 16, FUNCTION_NAME(PD_MIPI_CSI0_I2C0));
+ clks[IMX8QM_CSI0_I2C0_CLK] = imx_clk_gate_scu("mipi_csi0_i2c0_clk", "mipi_csi0_i2c0_div", SC_R_CSI_0_I2C_0, SC_PM_CLK_PER, LPCG_ADDR(MIPI_CSI_0_LPCG + 0x14), 0, 0);
+ clks[IMX8QM_CSI0_PWM0_IPG_CLK] = imx_clk_gate2_scu("mipi_csi0_pwm0_ipg_s", "ipg_mipi_csi_clk_root", LPCG_ADDR(MIPI_CSI_0_LPCG + 0x10), 16, FUNCTION_NAME(PD_MIPI_CSI0_PWM));
+ clks[IMX8QM_CSI0_PWM0_CLK] = imx_clk_gate_scu("mipi_csi0_pwm0_clk", "mipi_csi0_pwm0_div", SC_R_CSI_0_PWM_0, SC_PM_CLK_PER, LPCG_ADDR(MIPI_CSI_0_LPCG + 0x10), 0, 0);
+ clks[IMX8QM_CSI0_CORE_CLK] = imx_clk_gate_scu("mipi_csi0_core_clk", "mipi_csi0_core_div", SC_R_CSI_0, SC_PM_CLK_PER, LPCG_ADDR(MIPI_CSI_0_LPCG + 0x18), 16, 0);
+ clks[IMX8QM_CSI0_ESC_CLK] = imx_clk_gate_scu("mipi_csi0_esc_clk", "mipi_csi0_esc_div", SC_R_CSI_0, SC_PM_CLK_MISC, LPCG_ADDR(MIPI_CSI_0_LPCG + 0x1C), 16, 0);
+ clks[IMX8QM_CSI1_I2C0_IPG_CLK] = imx_clk_gate2_scu("mipi_csi1_i2c0_ipg_s", "ipg_mipi_csi_clk_root", LPCG_ADDR(MIPI_CSI_1_LPCG + 0x14), 16, FUNCTION_NAME(PD_MIPI_CSI1_I2C0));
+ clks[IMX8QM_CSI1_I2C0_CLK] = imx_clk_gate_scu("mipi_csi1_i2c0_clk", "mipi_csi1_i2c0_div", SC_R_CSI_1_I2C_0, SC_PM_CLK_PER, LPCG_ADDR(MIPI_CSI_1_LPCG + 0x14), 0, 0);
+ clks[IMX8QM_CSI1_PWM0_IPG_CLK] = imx_clk_gate2_scu("mipi_csi1_pwm0_ipg_s", "ipg_mipi_csi_clk_root", LPCG_ADDR(MIPI_CSI_1_LPCG + 0x10), 16, FUNCTION_NAME(PD_MIPI_CSI0_PWM));
+ clks[IMX8QM_CSI1_PWM0_CLK] = imx_clk_gate_scu("mipi_csi1_pwm0_clk", "mipi_csi1_pwm0_div", SC_R_CSI_1_PWM_0, SC_PM_CLK_PER, LPCG_ADDR(MIPI_CSI_1_LPCG + 0x10), 0, 0);
+ clks[IMX8QM_CSI1_CORE_CLK] = imx_clk_gate_scu("mipi_csi1_core_clk", "mipi_csi1_core_div", SC_R_CSI_1, SC_PM_CLK_PER, LPCG_ADDR(MIPI_CSI_1_LPCG + 0x18), 16, 0);
+ clks[IMX8QM_CSI1_ESC_CLK] = imx_clk_gate_scu("mipi_csi1_esc_clk", "mipi_csi1_esc_div", SC_R_CSI_1, SC_PM_CLK_MISC, LPCG_ADDR(MIPI_CSI_1_LPCG + 0x1C), 16, 0);
+
+ /* RX-HDMI */
+ clks[IMX8QM_HDMI_RX_GPIO_IPG_S_CLK] = imx_clk_gate2_scu("hdmi_rx_gpio_ipg_s_clk", "ipg_hdmi_rx_clk_root", LPCG_ADDR(RX_HDMI_LPCG), 0, FUNCTION_NAME(PD_HDMI_RX));
+ clks[IMX8QM_HDMI_RX_PWM_IPG_S_CLK] = imx_clk_gate2_scu("hdmi_rx_pwm_ipg_s_clk", "ipg_hdmi_rx_clk_root", LPCG_ADDR(RX_HDMI_LPCG + 0x8), 0, FUNCTION_NAME(PD_HDMI_RX));
+ clks[IMX8QM_HDMI_RX_PWM_IPG_CLK] = imx_clk_gate2_scu("hdmi_rx_pwm_ipg_clk", "hdmi_rx_pwm_ipg_s_clk", LPCG_ADDR(RX_HDMI_LPCG + 0x4), 0, FUNCTION_NAME(PD_HDMI_RX));
+ clks[IMX8QM_HDMI_RX_I2C_IPG_S_CLK] = imx_clk_gate2_scu("hdmi_rx_i2c_ipg_s_clk", "ipg_hdmi_rx_clk_root", LPCG_ADDR(RX_HDMI_LPCG + 0x1C), 0, FUNCTION_NAME(PD_HDMI_RX_I2C));
+ clks[IMX8QM_HDMI_RX_I2C_IPG_CLK] = imx_clk_gate2_scu("hdmi_rx_i2c_ipg_clk", "hdmi_rx_i2c_ipg_s_clk", LPCG_ADDR(RX_HDMI_LPCG + 0x18), 0, FUNCTION_NAME(PD_HDMI_RX_I2C));
+ clks[IMX8QM_HDMI_RX_I2C_DIV_CLK] = imx_clk_gate2_scu("hdmi_rx_i2c0_div_clk", "hdmi_rx_i2c0_div", LPCG_ADDR(RX_HDMI_LPCG + 0x14), 0, FUNCTION_NAME(PD_HDMI_RX_I2C));
+ clks[IMX8QM_HDMI_RX_I2C0_CLK] = imx_clk_gate_scu("hdmi_rx_i2c0_clk", "hdmi_rx_i2c0_div_clk", SC_R_HDMI_RX_I2C_0, SC_PM_CLK_MISC2, LPCG_ADDR(RX_HDMI_LPCG + 0x10), 0, 0);
+ clks[IMX8QM_HDMI_RX_SPDIF_CLK] = imx_clk_gate_scu("hdmi_rx_spdif_clk", "hdmi_rx_spdif_bypass_clk", SC_R_HDMI_RX, SC_PM_CLK_MISC0, NULL, 0, 0);
+ clks[IMX8QM_HDMI_RX_HD_REF_CLK] = imx_clk_gate_scu("hdmi_rx_hd_ref_clk", "hdmi_rx_hd_ref_div", SC_R_HDMI_RX, SC_PM_CLK_MISC1, NULL, 0, 0);
+ clks[IMX8QM_HDMI_RX_HD_CORE_CLK] = imx_clk_gate_scu("hdmi_rx_hd_core_clk", "hdmi_rx_hd_core_div", SC_R_HDMI_RX, SC_PM_CLK_MISC2, LPCG_ADDR(RX_HDMI_LPCG + 0x28), 0, 0);
+ clks[IMX8QM_HDMI_RX_PXL_CLK] = imx_clk_gate_scu("hdmi_rx_pxl_clk", "hdmi_rx_pxl_div", SC_R_HDMI_RX, SC_PM_CLK_MISC3, LPCG_ADDR(RX_HDMI_LPCG + 0x2C), 0, 0);
+ clks[IMX8QM_HDMI_RX_I2S_CLK] = imx_clk_gate_scu("hdmi_rx_i2s_clk", "hdmi_rx_i2s_bypass_clk", SC_R_HDMI_RX, SC_PM_CLK_MISC4, NULL, 0, 0);
+ clks[IMX8QM_HDMI_RX_PWM_CLK] = imx_clk_gate_scu("hdmi_rx_pwm_clk", "hdmi_rx_pwm_div", SC_R_HDMI_RX_PWM_0, SC_PM_CLK_MISC2, LPCG_ADDR(RX_HDMI_LPCG + 0xC), 0, 0);
+ clks[IMX8QM_HDMI_RX_SINK_PCLK] = imx_clk_gate2_scu("hdmi_rx_sink_pclk", "ipg_hdmi_rx_clk_root", LPCG_ADDR(RX_HDMI_LPCG + 0x20), 0, FUNCTION_NAME(PD_HDMI_RX_BYPASS));
+ clks[IMX8QM_HDMI_RX_SINK_SCLK] = imx_clk_gate2_scu("hdmi_rx_sink_sclk", "ipg_hdmi_rx_clk_root", LPCG_ADDR(RX_HDMI_LPCG + 0x24), 0, FUNCTION_NAME(PD_HDMI_RX_BYPASS));
+ clks[IMX8QM_HDMI_RX_PXL_ENC_CLK] = imx_clk_gate2_scu("hdmi_rx_sink_enc_clk", "hdmi_rx_pxl_clk", LPCG_ADDR(RX_HDMI_LPCG + 0x30), 0, FUNCTION_NAME(PD_HDMI_RX_BYPASS));
+
+ /* MIPI-DI */
+ clks[IMX8QM_MIPI0_LIS_IPG_CLK] = imx_clk_gate2_scu("mipi0_lis_ipg_clk", "mipi0_clk_root", LPCG_ADDR(MIPI_DSI_0_LPCG + 0x0), 0, FUNCTION_NAME(PD_MIPI_0_DSI));
+ clks[IMX8QM_MIPI0_I2C0_DIV] = imx_clk_divider_scu("mipi0_i2c0_div", SC_R_MIPI_0_I2C_0, SC_PM_CLK_MISC2);
+ clks[IMX8QM_MIPI0_I2C0_CLK] = imx_clk_gate_scu("mipi0_i2c0_clk", "mipi0_i2c0_div", SC_R_MIPI_0_I2C_0, SC_PM_CLK_MISC2, LPCG_ADDR(MIPI_DSI_0_LPCG + 0x1c), 0, 0);
+ clks[IMX8QM_MIPI0_I2C0_IPG_S_CLK] = imx_clk_gate2_scu("mipi0_i2c0_ipg_s", "mipi0_clk_root", LPCG_ADDR(MIPI_DSI_0_LPCG + 0x18), 0, FUNCTION_NAME(PD_MIPI_0_DSI_I2C0));
+ clks[IMX8QM_MIPI0_I2C0_IPG_CLK] = imx_clk_gate2_scu("mipi0_i2c0_ipg", "mipi0_i2c0_ipg_s", LPCG_ADDR(MIPI_DSI_0_LPCG + 0x14), 0, FUNCTION_NAME(PD_MIPI_0_DSI_I2C0));
+ clks[IMX8QM_MIPI0_I2C1_DIV] = imx_clk_divider_scu("mipi0_i2c1_div", SC_R_MIPI_0_I2C_1, SC_PM_CLK_MISC2);
+ clks[IMX8QM_MIPI0_I2C1_CLK] = imx_clk_gate_scu("mipi0_i2c1_clk", "mipi0_i2c1_div", SC_R_MIPI_0_I2C_1, SC_PM_CLK_MISC2, LPCG_ADDR(MIPI_DSI_0_LPCG + 0x2C), 0, 0);
+ clks[IMX8QM_MIPI0_I2C1_IPG_S_CLK] = imx_clk_gate2_scu("mipi0_i2c1_ipg_s", "mipi0_clk_root", LPCG_ADDR(MIPI_DSI_0_LPCG + 0x28), 0, FUNCTION_NAME(PD_MIPI_0_DSI_I2C1));
+ clks[IMX8QM_MIPI0_I2C1_IPG_CLK] = imx_clk_gate2_scu("mipi0_i2c1_ipg", "mipi0_i2c1_ipg_s", LPCG_ADDR(MIPI_DSI_0_LPCG + 0x24), 0, FUNCTION_NAME(PD_MIPI_0_DSI_I2C1));
+ clks[IMX8QM_MIPI0_PWM0_CLK] = imx_clk_gate_scu("mipi0_pwm0_clk", "mipi0_pwm0_div", SC_R_MIPI_0_PWM_0, SC_PM_CLK_PER, NULL, 0, 0);
+ clks[IMX8QM_MIPI0_DSI_TX_ESC_CLK] = imx_clk_gate_scu("mipi0_dsi_tx_esc_clk", "mipi0_dsi_tx_esc_div", SC_R_MIPI_0, SC_PM_CLK_MST_BUS, NULL, 0, 0);
+ clks[IMX8QM_MIPI0_DSI_RX_ESC_CLK] = imx_clk_gate_scu("mipi0_dsi_rx_esc_clk", "mipi0_dsi_rx_esc_div", SC_R_MIPI_0, SC_PM_CLK_SLV_BUS, NULL, 0, 0);
+ clks[IMX8QM_MIPI0_DSI_PHY_CLK] = imx_clk_gate_scu("mipi0_dsi_phy_clk", "mipi0_dsi_phy_div", SC_R_MIPI_0, SC_PM_CLK_PHY, NULL, 0, 0);
+ clks[IMX8QM_MIPI0_PXL_CLK] = imx_clk_gate_scu("mipi0_pxl_clk", "mipi0_pxl_div", SC_R_MIPI_0, SC_PM_CLK_PER, NULL, 0, 0);
+
+ clks[IMX8QM_MIPI1_LIS_IPG_CLK] = imx_clk_gate2_scu("mipi1_lis_ipg_clk", "mipi1_clk_root", LPCG_ADDR(MIPI_DSI_1_LPCG + 0x0), 0, FUNCTION_NAME(PD_MIPI_1_DSI));
+
+ clks[IMX8QM_MIPI1_I2C0_DIV] = imx_clk_divider_scu("mipi1_i2c0_div", SC_R_MIPI_1_I2C_0, SC_PM_CLK_MISC2);
+ clks[IMX8QM_MIPI1_I2C0_CLK] = imx_clk_gate_scu("mipi1_i2c0_clk", "mipi1_i2c0_div", SC_R_MIPI_1_I2C_0, SC_PM_CLK_MISC2, LPCG_ADDR(MIPI_DSI_1_LPCG + 0x1c), 0, 0);
+ clks[IMX8QM_MIPI1_I2C0_IPG_S_CLK] = imx_clk_gate2_scu("mipi1_i2c0_ipg_s", "mipi1_clk_root", LPCG_ADDR(MIPI_DSI_1_LPCG + 0x18), 0, FUNCTION_NAME(PD_MIPI_1_DSI_I2C0));
+ clks[IMX8QM_MIPI1_I2C0_IPG_CLK] = imx_clk_gate2_scu("mipi1_i2c0_ipg", "mipi1_i2c0_ipg_s", LPCG_ADDR(MIPI_DSI_1_LPCG + 0x14), 0, FUNCTION_NAME(PD_MIPI_1_DSI_I2C0));
+ clks[IMX8QM_MIPI1_I2C1_DIV] = imx_clk_divider_scu("mipi1_i2c1_div", SC_R_MIPI_1_I2C_1, SC_PM_CLK_MISC2);
+ clks[IMX8QM_MIPI1_I2C1_CLK] = imx_clk_gate_scu("mipi1_i2c1_clk", "mipi1_i2c1_div", SC_R_MIPI_1_I2C_1, SC_PM_CLK_MISC2, LPCG_ADDR(MIPI_DSI_1_LPCG + 0x2C), 0, 0);
+ clks[IMX8QM_MIPI1_I2C1_IPG_S_CLK] = imx_clk_gate2_scu("mipi1_i2c1_ipg_s", "mipi1_clk_root", LPCG_ADDR(MIPI_DSI_1_LPCG + 0x28), 0, FUNCTION_NAME(PD_MIPI_1_DSI_I2C1));
+ clks[IMX8QM_MIPI1_I2C1_IPG_CLK] = imx_clk_gate2_scu("mipi1_i2c1_ipg", "mipi1_i2c1_ipg_s", LPCG_ADDR(MIPI_DSI_1_LPCG + 0x24), 0, FUNCTION_NAME(PD_MIPI_1_DSI_I2C1));
+ clks[IMX8QM_MIPI1_PWM0_CLK] = imx_clk_gate_scu("mipi1_pwm0_clk", "mipi1_pwm0_div", SC_R_MIPI_1_PWM_0, SC_PM_CLK_PER, NULL, 0, 0);
+ clks[IMX8QM_MIPI1_DSI_TX_ESC_CLK] = imx_clk_gate_scu("mipi1_dsi_tx_esc_clk", "mipi1_dsi_tx_esc_div", SC_R_MIPI_1, SC_PM_CLK_MST_BUS, NULL, 0, 0);
+ clks[IMX8QM_MIPI1_DSI_RX_ESC_CLK] = imx_clk_gate_scu("mipi1_dsi_rx_esc_clk", "mipi1_dsi_rx_esc_div", SC_R_MIPI_1, SC_PM_CLK_SLV_BUS, NULL, 0, 0);
+ clks[IMX8QM_MIPI1_DSI_PHY_CLK] = imx_clk_gate_scu("mipi1_dsi_phy_clk", "mipi1_dsi_phy_div", SC_R_MIPI_1, SC_PM_CLK_PHY, NULL, 0, 0);
+ clks[IMX8QM_MIPI1_PXL_CLK] = imx_clk_gate_scu("mipi1_pxl_clk", "mipi1_pxl_div", SC_R_MIPI_1, SC_PM_CLK_PER, NULL, 0, 0);
+
+ /* Display controller */
+ /* DC0 */
+ clks[IMX8QM_DC0_DISP0_CLK] = imx_clk_gate_scu("dc0_disp0_clk", "dc0_disp0_div", SC_R_DC_0, SC_PM_CLK_MISC0, LPCG_ADDR(DC_0_LPCG), 0, 0);
+ clks[IMX8QM_DC0_DISP1_CLK] = imx_clk_gate_scu("dc0_disp1_clk", "dc0_disp1_div", SC_R_DC_0, SC_PM_CLK_MISC1, LPCG_ADDR(DC_0_LPCG), 4, 0);
+ clks[IMX8QM_DC0_PRG0_RTRAM_CLK] = imx_clk_gate2_scu("dc0_prg0_rtram_clk", "axi_int_dc_clk_root", LPCG_ADDR(DC_0_LPCG + 0x20), 0, FUNCTION_NAME(PD_DC_0));
+ clks[IMX8QM_DC0_PRG0_APB_CLK] = imx_clk_gate2_scu("dc0_prg0_apb_clk", "cfg_dc_clk_root", LPCG_ADDR(DC_0_LPCG + 0x20), 16, FUNCTION_NAME(PD_DC_0));
+ clks[IMX8QM_DC0_PRG1_RTRAM_CLK] = imx_clk_gate2_scu("dc0_prg1_rtram_clk", "axi_int_dc_clk_root", LPCG_ADDR(DC_0_LPCG + 0x24), 0, FUNCTION_NAME(PD_DC_0));
+ clks[IMX8QM_DC0_PRG1_APB_CLK] = imx_clk_gate2_scu("dc0_prg1_apb_clk", "cfg_dc_clk_root", LPCG_ADDR(DC_0_LPCG + 0x24), 16, FUNCTION_NAME(PD_DC_0));
+ clks[IMX8QM_DC0_PRG2_RTRAM_CLK] = imx_clk_gate2_scu("dc0_prg2_rtram_clk", "axi_int_dc_clk_root", LPCG_ADDR(DC_0_LPCG + 0x28), 0, FUNCTION_NAME(PD_DC_0));
+ clks[IMX8QM_DC0_PRG2_APB_CLK] = imx_clk_gate2_scu("dc0_prg2_apb_clk", "cfg_dc_clk_root", LPCG_ADDR(DC_0_LPCG + 0x28), 16, FUNCTION_NAME(PD_DC_0));
+ clks[IMX8QM_DC0_PRG3_RTRAM_CLK] = imx_clk_gate2_scu("dc0_prg3_rtram_clk", "axi_int_dc_clk_root", LPCG_ADDR(DC_0_LPCG + 0x34), 0, FUNCTION_NAME(PD_DC_0));
+ clks[IMX8QM_DC0_PRG3_APB_CLK] = imx_clk_gate2_scu("dc0_prg3_apb_clk", "cfg_dc_clk_root", LPCG_ADDR(DC_0_LPCG + 0x34), 16, FUNCTION_NAME(PD_DC_0));
+ clks[IMX8QM_DC0_PRG4_RTRAM_CLK] = imx_clk_gate2_scu("dc0_prg4_rtram_clk", "axi_int_dc_clk_root", LPCG_ADDR(DC_0_LPCG + 0x38), 0, FUNCTION_NAME(PD_DC_0));
+ clks[IMX8QM_DC0_PRG4_APB_CLK] = imx_clk_gate2_scu("dc0_prg4_apb_clk", "cfg_dc_clk_root", LPCG_ADDR(DC_0_LPCG + 0x38), 16, FUNCTION_NAME(PD_DC_0));
+ clks[IMX8QM_DC0_PRG5_RTRAM_CLK] = imx_clk_gate2_scu("dc0_prg5_rtram_clk", "axi_int_dc_clk_root", LPCG_ADDR(DC_0_LPCG + 0x3c), 0, FUNCTION_NAME(PD_DC_0));
+ clks[IMX8QM_DC0_PRG5_APB_CLK] = imx_clk_gate2_scu("dc0_prg5_apb_clk", "cfg_dc_clk_root", LPCG_ADDR(DC_0_LPCG + 0x3c), 16, FUNCTION_NAME(PD_DC_0));
+ clks[IMX8QM_DC0_PRG6_RTRAM_CLK] = imx_clk_gate2_scu("dc0_prg6_rtram_clk", "axi_int_dc_clk_root", LPCG_ADDR(DC_0_LPCG + 0x40), 0, FUNCTION_NAME(PD_DC_0));
+ clks[IMX8QM_DC0_PRG6_APB_CLK] = imx_clk_gate2_scu("dc0_prg6_apb_clk", "cfg_dc_clk_root", LPCG_ADDR(DC_0_LPCG + 0x40), 16, FUNCTION_NAME(PD_DC_0));
+ clks[IMX8QM_DC0_PRG7_RTRAM_CLK] = imx_clk_gate2_scu("dc0_prg7_rtram_clk", "axi_int_dc_clk_root", LPCG_ADDR(DC_0_LPCG + 0x44), 0, FUNCTION_NAME(PD_DC_0));
+ clks[IMX8QM_DC0_PRG7_APB_CLK] = imx_clk_gate2_scu("dc0_prg7_apb_clk", "cfg_dc_clk_root", LPCG_ADDR(DC_0_LPCG + 0x44), 16, FUNCTION_NAME(PD_DC_0));
+ clks[IMX8QM_DC0_PRG8_RTRAM_CLK] = imx_clk_gate2_scu("dc0_prg8_rtram_clk", "axi_int_dc_clk_root", LPCG_ADDR(DC_0_LPCG + 0x48), 0, FUNCTION_NAME(PD_DC_0));
+ clks[IMX8QM_DC0_PRG8_APB_CLK] = imx_clk_gate2_scu("dc0_prg8_apb_clk", "cfg_dc_clk_root", LPCG_ADDR(DC_0_LPCG + 0x48), 16, FUNCTION_NAME(PD_DC_0));
+ clks[IMX8QM_DC0_DPR0_APB_CLK] = imx_clk_gate2_scu("dc0_dpr0_apb_clk", "cfg_dc_clk_root", LPCG_ADDR(DC_0_LPCG + 0x18), 16, FUNCTION_NAME(PD_DC_0));
+ clks[IMX8QM_DC0_DPR0_B_CLK] = imx_clk_gate2_scu("dc0_dpr0_b_clk", "axi_ext_dc_clk_root", LPCG_ADDR(DC_0_LPCG + 0x18), 20, FUNCTION_NAME(PD_DC_0));
+ clks[IMX8QM_DC0_DPR1_APB_CLK] = imx_clk_gate2_scu("dc0_dpr1_apb_clk", "cfg_dc_clk_root", LPCG_ADDR(DC_0_LPCG + 0x2c), 16, FUNCTION_NAME(PD_DC_0));
+ clks[IMX8QM_DC0_DPR1_B_CLK] = imx_clk_gate2_scu("dc0_dpr1_b_clk", "axi_ext_dc_clk_root", LPCG_ADDR(DC_0_LPCG + 0x2c), 20, FUNCTION_NAME(PD_DC_0));
+ clks[IMX8QM_DC0_RTRAM0_CLK] = imx_clk_gate2_scu("dc0_rtrm0_clk", "axi_int_dc_clk_root", LPCG_ADDR(DC_0_LPCG + 0x1C), 0, FUNCTION_NAME(PD_DC_0));
+ clks[IMX8QM_DC0_RTRAM1_CLK] = imx_clk_gate2_scu("dc0_rtrm1_clk", "axi_int_dc_clk_root", LPCG_ADDR(DC_0_LPCG + 0x30), 0, FUNCTION_NAME(PD_DC_0));
+ /* DC1 */
+ clks[IMX8QM_DC1_DISP0_CLK] = imx_clk_gate_scu("dc1_disp0_clk", "dc1_disp0_div", SC_R_DC_1, SC_PM_CLK_MISC0, LPCG_ADDR(DC_1_LPCG), 0, 0);
+ clks[IMX8QM_DC1_DISP1_CLK] = imx_clk_gate_scu("dc1_disp1_clk", "dc1_disp1_div", SC_R_DC_1, SC_PM_CLK_MISC1, LPCG_ADDR(DC_1_LPCG), 4, 0);
+ clks[IMX8QM_DC1_PRG0_RTRAM_CLK] = imx_clk_gate2_scu("dc1_prg0_rtram_clk", "axi_int_dc_clk_root", LPCG_ADDR(DC_1_LPCG + 0x20), 0, FUNCTION_NAME(PD_DC_1));
+ clks[IMX8QM_DC1_PRG0_APB_CLK] = imx_clk_gate2_scu("dc1_prg0_apb_clk", "cfg_dc_clk_root", LPCG_ADDR(DC_1_LPCG + 0x20), 16, FUNCTION_NAME(PD_DC_1));
+ clks[IMX8QM_DC1_PRG1_RTRAM_CLK] = imx_clk_gate2_scu("dc1_prg1_rtram_clk", "axi_int_dc_clk_root", LPCG_ADDR(DC_1_LPCG + 0x24), 0, FUNCTION_NAME(PD_DC_1));
+ clks[IMX8QM_DC1_PRG1_APB_CLK] = imx_clk_gate2_scu("dc1_prg1_apb_clk", "cfg_dc_clk_root", LPCG_ADDR(DC_1_LPCG + 0x24), 16, FUNCTION_NAME(PD_DC_1));
+ clks[IMX8QM_DC1_PRG2_RTRAM_CLK] = imx_clk_gate2_scu("dc1_prg2_rtram_clk", "axi_int_dc_clk_root", LPCG_ADDR(DC_1_LPCG + 0x28), 0, FUNCTION_NAME(PD_DC_1));
+ clks[IMX8QM_DC1_PRG2_APB_CLK] = imx_clk_gate2_scu("dc1_prg2_apb_clk", "cfg_dc_clk_root", LPCG_ADDR(DC_1_LPCG + 0x28), 16, FUNCTION_NAME(PD_DC_1));
+ clks[IMX8QM_DC1_PRG3_RTRAM_CLK] = imx_clk_gate2_scu("dc1_prg3_rtram_clk", "axi_int_dc_clk_root", LPCG_ADDR(DC_1_LPCG + 0x34), 0, FUNCTION_NAME(PD_DC_1));
+ clks[IMX8QM_DC1_PRG3_APB_CLK] = imx_clk_gate2_scu("dc1_prg3_apb_clk", "cfg_dc_clk_root", LPCG_ADDR(DC_1_LPCG + 0x34), 16, FUNCTION_NAME(PD_DC_1));
+ clks[IMX8QM_DC1_PRG4_RTRAM_CLK] = imx_clk_gate2_scu("dc1_prg4_rtram_clk", "axi_int_dc_clk_root", LPCG_ADDR(DC_1_LPCG + 0x38), 0, FUNCTION_NAME(PD_DC_1));
+ clks[IMX8QM_DC1_PRG4_APB_CLK] = imx_clk_gate2_scu("dc1_prg4_apb_clk", "cfg_dc_clk_root", LPCG_ADDR(DC_1_LPCG + 0x38), 16, FUNCTION_NAME(PD_DC_1));
+ clks[IMX8QM_DC1_PRG5_RTRAM_CLK] = imx_clk_gate2_scu("dc1_prg5_rtram_clk", "axi_int_dc_clk_root", LPCG_ADDR(DC_1_LPCG + 0x3c), 0, FUNCTION_NAME(PD_DC_1));
+ clks[IMX8QM_DC1_PRG5_APB_CLK] = imx_clk_gate2_scu("dc1_prg5_apb_clk", "cfg_dc_clk_root", LPCG_ADDR(DC_1_LPCG + 0x3c), 16, FUNCTION_NAME(PD_DC_1));
+ clks[IMX8QM_DC1_PRG6_RTRAM_CLK] = imx_clk_gate2_scu("dc1_prg6_rtram_clk", "axi_int_dc_clk_root", LPCG_ADDR(DC_1_LPCG + 0x40), 0, FUNCTION_NAME(PD_DC_1));
+ clks[IMX8QM_DC1_PRG6_APB_CLK] = imx_clk_gate2_scu("dc1_prg6_apb_clk", "cfg_dc_clk_root", LPCG_ADDR(DC_1_LPCG + 0x40), 16, FUNCTION_NAME(PD_DC_1));
+ clks[IMX8QM_DC1_PRG7_RTRAM_CLK] = imx_clk_gate2_scu("dc1_prg7_rtram_clk", "axi_int_dc_clk_root", LPCG_ADDR(DC_1_LPCG + 0x44), 0, FUNCTION_NAME(PD_DC_1));
+ clks[IMX8QM_DC1_PRG7_APB_CLK] = imx_clk_gate2_scu("dc1_prg7_apb_clk", "cfg_dc_clk_root", LPCG_ADDR(DC_1_LPCG + 0x44), 16, FUNCTION_NAME(PD_DC_1));
+ clks[IMX8QM_DC1_PRG8_RTRAM_CLK] = imx_clk_gate2_scu("dc1_prg8_rtram_clk", "axi_int_dc_clk_root", LPCG_ADDR(DC_1_LPCG + 0x48), 0, FUNCTION_NAME(PD_DC_1));
+ clks[IMX8QM_DC1_PRG8_APB_CLK] = imx_clk_gate2_scu("dc1_prg8_apb_clk", "cfg_dc_clk_root", LPCG_ADDR(DC_1_LPCG + 0x48), 16, FUNCTION_NAME(PD_DC_1));
+ clks[IMX8QM_DC1_DPR0_APB_CLK] = imx_clk_gate2_scu("dc1_dpr0_apb_clk", "cfg_dc_clk_root", LPCG_ADDR(DC_1_LPCG + 0x18), 16, FUNCTION_NAME(PD_DC_1));
+ clks[IMX8QM_DC1_DPR0_B_CLK] = imx_clk_gate2_scu("dc1_dpr0_b_clk", "axi_ext_dc_clk_root", LPCG_ADDR(DC_1_LPCG + 0x18), 20, FUNCTION_NAME(PD_DC_1));
+ clks[IMX8QM_DC1_DPR1_APB_CLK] = imx_clk_gate2_scu("dc1_dpr1_apb_clk", "cfg_dc_clk_root", LPCG_ADDR(DC_1_LPCG + 0x2c), 16, FUNCTION_NAME(PD_DC_1));
+ clks[IMX8QM_DC1_DPR1_B_CLK] = imx_clk_gate2_scu("dc1_dpr1_b_clk", "axi_ext_dc_clk_root", LPCG_ADDR(DC_1_LPCG + 0x2c), 20, FUNCTION_NAME(PD_DC_1));
+ clks[IMX8QM_DC1_RTRAM0_CLK] = imx_clk_gate2_scu("dc1_rtrm0_clk", "axi_int_dc_clk_root", LPCG_ADDR(DC_1_LPCG + 0x1C), 0, FUNCTION_NAME(PD_DC_1));
+ clks[IMX8QM_DC1_RTRAM1_CLK] = imx_clk_gate2_scu("dc1_rtrm1_clk", "axi_int_dc_clk_root", LPCG_ADDR(DC_1_LPCG + 0x30), 0, FUNCTION_NAME(PD_DC_1));
+
+ /* HDMI SS */
+ clks[IMX8QM_HDMI_IPG_CLK] = imx_clk_gate_scu("ipg_hdmi_clk_root", "hdmi_ipg_div", SC_R_HDMI, SC_PM_CLK_MISC, NULL, 0, 0);
+ clks[IMX8QM_HDMI_I2C0_CLK] = imx_clk_gate_scu("hdmi_i2c0_clk", "hdmi_i2c0_div", SC_R_HDMI_I2C_0, SC_PM_CLK_MISC2, LPCG_ADDR(DI_HDMI_LPCG), 0, 0);
+ clks[IMX8QM_HDMI_PXL_MUX_CLK] = imx_clk_gate_scu("hdmi_pxl_mux_clk", "hdmi_pxl_mux_div", SC_R_HDMI, SC_PM_CLK_MISC0, NULL, 0, 0);
+ clks[IMX8QM_HDMI_PXL_LINK_CLK] = imx_clk_gate_scu("hdmi_pxl_link_clk", "hdmi_pxl_link_div", SC_R_HDMI, SC_PM_CLK_MISC1, NULL, 0, 0);
+ clks[IMX8QM_HDMI_HDP_CORE_CLK] = imx_clk_gate_scu("hdmi_hdp_core_clk", "hdmi_core_div", SC_R_HDMI, SC_PM_CLK_MISC2, NULL, 0, 0);
+ clks[IMX8QM_HDMI_PXL_CLK] = imx_clk_gate_scu("hdmi_pxl_clk", "hdmi_pxl_div", SC_R_HDMI, SC_PM_CLK_MISC3, NULL, 0, 0);
+ clks[IMX8QM_HDMI_I2S_CLK] = imx_clk_gate_scu("hdmi_i2s_clk", "hdmi_i2s_div", SC_R_HDMI_I2S, SC_PM_CLK_MISC0, LPCG_ADDR(DI_HDMI_LPCG + 0xC), 0, 0);
+ clks[IMX8QM_HDMI_I2C_IPG_CLK] = imx_clk_gate2_scu("hdmi_i2c_ipg_clk", "ipg_hdmi_clk_root", LPCG_ADDR(DI_HDMI_LPCG), 16, FUNCTION_NAME(PD_HDMI_I2C_0));
+ clks[IMX8QM_HDMI_PWM_IPG_CLK] = imx_clk_gate2_scu("hdmi_pwm_ipg_clk", "ipg_hdmi_clk_root", LPCG_ADDR(DI_HDMI_LPCG + 0x8), 16, FUNCTION_NAME(PD_HDMI_PWM_0));
+ clks[IMX8QM_HDMI_GPIO_IPG_CLK] = imx_clk_gate2_scu("hdmi_gpio_ipg_clk", "ipg_hdmi_clk_root", LPCG_ADDR(DI_HDMI_LPCG + 0x10), 16, FUNCTION_NAME(PD_HDMI_GPIO_0));
+ clks[IMX8QM_HDMI_LIS_IPG_CLK] = imx_clk_gate2_scu("hdmi_lis_ipg_clk", "ipg_hdmi_clk_root", LPCG_ADDR(DI_HDMI_LPCG + 0x4), 16, FUNCTION_NAME(PD_HDMI));
+ clks[IMX8QM_HDMI_MSI_HCLK] = imx_clk_gate2_scu("hdmi_msi_hclk_clk", "ipg_hdmi_clk_root", LPCG_ADDR(DI_HDMI_LPCG + 0x14), 0, FUNCTION_NAME(PD_HDMI));
+ clks[IMX8QM_HDMI_PXL_LPCG_CLK] = imx_clk_gate2_scu("hdmi_pxl_lpcg_clk", "dummy", LPCG_ADDR(DI_HDMI_LPCG + 0x18), 0, FUNCTION_NAME(PD_HDMI));
+ clks[IMX8QM_HDMI_PXL_EVEN_CLK] = imx_clk_gate2_scu("hdmi_pxl_even_clk", "hdmi_pxl_lpcg_clk", NULL, 0, FUNCTION_NAME(PD_HDMI));
+ clks[IMX8QM_HDMI_HDP_CLK] = imx_clk_gate2_scu("hdmi_pxl_odd_clk", "hdmi_pxl_lpcg_clk", NULL, 0, FUNCTION_NAME(PD_HDMI));
+ clks[IMX8QM_HDMI_PXL_DBL_CLK] = imx_clk_gate2_scu("hdmi_pxl_dbl_clk", "hdmi_pxl_lpcg_clk", NULL, 0, FUNCTION_NAME(PD_HDMI));
+ clks[IMX8QM_HDMI_VIF_CLK] = imx_clk_gate2_scu("hdmi_vif_clk", "hdmi_pxl_mux_clk", LPCG_ADDR(DI_HDMI_LPCG + 0x1C), 0, FUNCTION_NAME(PD_HDMI));
+ clks[IMX8QM_HDMI_APB_CLK] = imx_clk_gate2_scu("hdmi_apb_clk", "ipg_hdmi_clk_root", LPCG_ADDR(DI_HDMI_LPCG + 0x28), 16, FUNCTION_NAME(PD_HDMI));
+ clks[IMX8QM_HDMI_APB_MUX_CSR_CLK] = imx_clk_gate2_scu("hdmi_apb_mux_csr_clk", "hdmi_apb_clk", LPCG_ADDR(DI_HDMI_LPCG + 0x20), 16, FUNCTION_NAME(PD_HDMI));
+ clks[IMX8QM_HDMI_APB_MUX_CTRL_CLK] = imx_clk_gate2_scu("hdmi_apb_mux_ctrl_clk", "hdmi_apb_clk", LPCG_ADDR(DI_HDMI_LPCG + 0x24), 16, FUNCTION_NAME(PD_HDMI));
+ clks[IMX8QM_HDMI_HDP_PHY_CLK] = imx_clk_gate2_scu("hdmi_pclk", "ipg_hdmi_clk_root", LPCG_ADDR(DI_HDMI_LPCG + 0x1C), 16, FUNCTION_NAME(PD_HDMI));
+
+ /* lvds subsystem */
+ clks[IMX8QM_LVDS0_PIXEL_CLK] = imx_clk_gate_scu("lvds0_pixel_clk", "lvds0_pixel_div", SC_R_LVDS_0, SC_PM_CLK_PER, NULL, 0, 0);
+ clks[IMX8QM_LVDS0_I2C0_CLK] = imx_clk_gate_scu("lvds0_i2c0_clk", "lvds0_i2c0_div", SC_R_LVDS_0_I2C_0, SC_PM_CLK_PER, LPCG_ADDR(DI_LVDS_0_LPCG + 0x10), 0, 0);
+ clks[IMX8QM_LVDS0_I2C1_CLK] = imx_clk_gate_scu("lvds0_i2c1_clk", "lvds0_i2c1_div", SC_R_LVDS_0_I2C_1, SC_PM_CLK_PER, LPCG_ADDR(DI_LVDS_0_LPCG + 0x14), 0, 0);
+ clks[IMX8QM_LVDS0_PWM0_CLK] = imx_clk_gate_scu("lvds0_pwm0_clk", "lvds0_pwm0_div", SC_R_LVDS_0_PWM_0, SC_PM_CLK_PER, LPCG_ADDR(DI_LVDS_0_LPCG + 0x0C), 0, 0);
+ clks[IMX8QM_LVDS0_PHY_CLK] = imx_clk_gate_scu("lvds0_phy_clk", "lvds0_phy_div", SC_R_LVDS_0, SC_PM_CLK_PHY, NULL, 0, 0);
+ clks[IMX8QM_LVDS0_I2C0_IPG_CLK] = imx_clk_gate2_scu("lvds0_i2c0_ipg_clk", "ipg_lvds_clk_root", LPCG_ADDR(DI_LVDS_0_LPCG + 0x10), 16, FUNCTION_NAME(PD_LVDS0_I2C0));
+ clks[IMX8QM_LVDS0_I2C1_IPG_CLK] = imx_clk_gate2_scu("lvds0_i2c1_ipg_clk", "ipg_lvds_clk_root", LPCG_ADDR(DI_LVDS_0_LPCG + 0x14), 16, FUNCTION_NAME(PD_LVDS0_I2C1));
+ clks[IMX8QM_LVDS0_PWM0_IPG_CLK] = imx_clk_gate2_scu("lvds0_pwm0_ipg_clk", "ipg_lvds_clk_root", LPCG_ADDR(DI_LVDS_0_LPCG + 0x0C), 16, FUNCTION_NAME(PD_LVDS0_PWM));
+ clks[IMX8QM_LVDS0_GPIO_IPG_CLK] = imx_clk_gate2_scu("lvds0_gpio_ipg_clk", "ipg_lvds_clk_root", LPCG_ADDR(DI_LVDS_0_LPCG + 0x08), 16, FUNCTION_NAME(PD_LVDS0_GPIO));
+ clks[IMX8QM_LVDS0_LIS_IPG_CLK] = imx_clk_gate2_scu("lvds0_lis_ipg_clk", "ipg_lvds_clk_root", LPCG_ADDR(DI_LVDS_0_LPCG + 0x0), 16, FUNCTION_NAME(PD_LVDS0));
+
+ clks[IMX8QM_LVDS1_PIXEL_CLK] = imx_clk_gate_scu("lvds1_pixel_clk", "lvds1_pixel_div", SC_R_LVDS_1, SC_PM_CLK_PER, NULL, 0, 0);
+ clks[IMX8QM_LVDS1_I2C0_CLK] = imx_clk_gate_scu("lvds1_i2c0_clk", "lvds1_i2c0_div", SC_R_LVDS_1_I2C_0, SC_PM_CLK_PER, LPCG_ADDR(DI_LVDS_1_LPCG + 0x10), 0, 0);
+ clks[IMX8QM_LVDS1_I2C1_CLK] = imx_clk_gate_scu("lvds1_i2c1_clk", "lvds1_i2c1_div", SC_R_LVDS_1_I2C_1, SC_PM_CLK_PER, LPCG_ADDR(DI_LVDS_1_LPCG + 0x14), 0, 0);
+ clks[IMX8QM_LVDS1_PWM0_CLK] = imx_clk_gate_scu("lvds1_pwm0_clk", "lvds1_pwm0_div", SC_R_LVDS_1_PWM_0, SC_PM_CLK_PER, LPCG_ADDR(DI_LVDS_1_LPCG + 0x0C), 0, 0);
+ clks[IMX8QM_LVDS1_PHY_CLK] = imx_clk_gate_scu("lvds1_phy_clk", "lvds1_phy_div", SC_R_LVDS_1, SC_PM_CLK_PHY, NULL, 0, 0);
+ clks[IMX8QM_LVDS1_I2C0_IPG_CLK] = imx_clk_gate2_scu("lvds1_i2c0_ipg_clk", "ipg_lvds_clk_root", LPCG_ADDR(DI_LVDS_1_LPCG + 0x10), 16, FUNCTION_NAME(PD_LVDS1_I2C0));
+ clks[IMX8QM_LVDS1_I2C1_IPG_CLK] = imx_clk_gate2_scu("lvds1_i2c1_ipg_clk", "ipg_lvds_clk_root", LPCG_ADDR(DI_LVDS_1_LPCG + 0x14), 16, FUNCTION_NAME(PD_LVDS1_I2C1));
+ clks[IMX8QM_LVDS1_PWM0_IPG_CLK] = imx_clk_gate2_scu("lvds1_pwm0_ipg_clk", "ipg_lvds_clk_root", LPCG_ADDR(DI_LVDS_1_LPCG + 0x0C), 16, FUNCTION_NAME(PD_LVDS1_PWM));
+ clks[IMX8QM_LVDS1_GPIO_IPG_CLK] = imx_clk_gate2_scu("lvds1_gpio_ipg_clk", "ipg_lvds_clk_root", LPCG_ADDR(DI_LVDS_1_LPCG + 0x08), 16, FUNCTION_NAME(PD_LVDS1_GPIO));
+ clks[IMX8QM_LVDS1_LIS_IPG_CLK] = imx_clk_gate2_scu("lvds1_lis_ipg_clk", "ipg_lvds_clk_root", LPCG_ADDR(DI_LVDS_1_LPCG + 0x0), 16, FUNCTION_NAME(PD_LVDS1));
+
+ /* vpu/zpu subsystem */
+ clks[IMX8QM_VPU_DDR_CLK] = imx_clk_gate_scu("vpu_ddr_clk", "vpu_ddr_div", SC_R_VPU, SC_PM_CLK_SLV_BUS, NULL, 0, 0);
+ clks[IMX8QM_VPU_SYS_CLK] = imx_clk_gate_scu("vpu_sys_clk", "vpu_sys_div", SC_R_VPU, SC_PM_CLK_MST_BUS, NULL, 0, 0);
+ clks[IMX8QM_VPU_XUVI_CLK] = imx_clk_gate_scu("vpu_xuvi_clk", "vpu_xuvi_div", SC_R_VPU, SC_PM_CLK_PER, NULL, 0, 0);
+ clks[IMX8QM_VPU_UART_CLK] = imx_clk_gate_scu("vpu_uart_clk", "vpu_uart_div", SC_R_VPU_UART, SC_PM_CLK_PER, NULL, 0, 0);
+ clks[IMX8QM_VPU_CORE_CLK] = imx_clk_gate_scu("vpu_core_clk", "vpu_core_div", SC_R_VPUCORE, SC_PM_CLK_PER, NULL, 0, 0);
+
+ /* gpu */
+ clks[IMX8QM_GPU0_CORE_CLK] = imx_clk_gate_scu("gpu_core0_clk", "gpu_core0_div", SC_R_GPU_0_PID0, SC_PM_CLK_PER, NULL, 0, 0);
+ clks[IMX8QM_GPU0_SHADER_CLK] = imx_clk_gate_scu("gpu_shader0_clk", "gpu_shader0_div", SC_R_GPU_0_PID0, SC_PM_CLK_MISC, NULL, 0, 0);
+ clks[IMX8QM_GPU1_CORE_CLK] = imx_clk_gate_scu("gpu_core1_clk", "gpu_core1_div", SC_R_GPU_1_PID0, SC_PM_CLK_PER, NULL, 0, 0);
+ clks[IMX8QM_GPU1_SHADER_CLK] = imx_clk_gate_scu("gpu_shader1_clk", "gpu_shader1_div", SC_R_GPU_1_PID0, SC_PM_CLK_MISC, NULL, 0, 0);
+
+ /* Imaging SS */
+ clks[IMX8QM_IMG_JPEG_ENC_IPG_CLK] = imx_clk_gate2_scu("img_jpeg_enc_ipg_clk", "ipg_img_clk_root", LPCG_ADDR(IMG_JPEG_ENC_LPCG), 16, FUNCTION_NAME(PD_IMAGING_JPEG_ENC));
+ clks[IMX8QM_IMG_JPEG_ENC_CLK] = imx_clk_gate2_scu("img_jpeg_enc_clk", "img_jpeg_enc_ipg_clk", LPCG_ADDR(IMG_JPEG_ENC_LPCG), 0, FUNCTION_NAME(PD_IMAGING_JPEG_ENC));
+ clks[IMX8QM_IMG_JPEG_DEC_IPG_CLK] = imx_clk_gate2_scu("img_jpeg_dec_ipg_clk", "ipg_img_clk_root", LPCG_ADDR(IMG_JPEG_DEC_LPCG), 16, FUNCTION_NAME(PD_IMAGING_JPEG_DEC));
+ clks[IMX8QM_IMG_JPEG_DEC_CLK] = imx_clk_gate2_scu("img_jpeg_dec_clk", "img_jpeg_dec_ipg_clk", LPCG_ADDR(IMG_JPEG_DEC_LPCG), 0, FUNCTION_NAME(PD_IMAGING_JPEG_DEC));
+ clks[IMX8QM_IMG_PXL_LINK_DC0_CLK] = imx_clk_gate2_scu("img_pxl_link_dc0_clk", "pxl_img_clk_root", LPCG_ADDR(IMG_PXL_LINK_DC0_LPCG), 0, FUNCTION_NAME(PD_IMAGING));
+ clks[IMX8QM_IMG_PXL_LINK_DC1_CLK] = imx_clk_gate2_scu("img_pxl_link_dc1_clk", "pxl_img_clk_root", LPCG_ADDR(IMG_PXL_LINK_DC1_LPCG), 0, FUNCTION_NAME(PD_IMAGING));
+ clks[IMX8QM_IMG_PXL_LINK_CSI0_CLK] = imx_clk_gate2_scu("img_pxl_link_csi0_clk", "pxl_img_clk_root", LPCG_ADDR(IMG_PXL_LINK_CSI0_LPCG), 0, FUNCTION_NAME(PD_IMAGING));
+ clks[IMX8QM_IMG_PXL_LINK_CSI1_CLK] = imx_clk_gate2_scu("img_pxl_link_csi1_clk", "pxl_img_clk_root", LPCG_ADDR(IMG_PXL_LINK_CSI1_LPCG), 0, FUNCTION_NAME(PD_IMAGING));
+ clks[IMX8QM_IMG_PXL_LINK_HDMI_IN_CLK] = imx_clk_gate2_scu("img_pxl_link_hdmi_in_clk", "pxl_img_clk_root", LPCG_ADDR(IMG_PXL_LINK_HDMI_LPCG), 0, FUNCTION_NAME(PD_HDMI_RX));
+ clks[IMX8QM_IMG_PDMA_0_CLK] = imx_clk_gate2_scu("img_pdma0_clk", "pxl_img_clk_root", LPCG_ADDR(IMG_PDMA_0_LPCG), 0, FUNCTION_NAME(PD_IMAGING_PDMA0));
+ clks[IMX8QM_IMG_PDMA_1_CLK] = imx_clk_gate2_scu("img_pdma1_clk", "pxl_img_clk_root", LPCG_ADDR(IMG_PDMA_1_LPCG), 0, FUNCTION_NAME(PD_IMAGING_PDMA1));
+ clks[IMX8QM_IMG_PDMA_2_CLK] = imx_clk_gate2_scu("img_pdma2_clk", "pxl_img_clk_root", LPCG_ADDR(IMG_PDMA_2_LPCG), 0, FUNCTION_NAME(PD_IMAGING_PDMA2));
+ clks[IMX8QM_IMG_PDMA_3_CLK] = imx_clk_gate2_scu("img_pdma3_clk", "pxl_img_clk_root", LPCG_ADDR(IMG_PDMA_3_LPCG), 0, FUNCTION_NAME(PD_IMAGING_PDMA3));
+ clks[IMX8QM_IMG_PDMA_4_CLK] = imx_clk_gate2_scu("img_pdma4_clk", "pxl_img_clk_root", LPCG_ADDR(IMG_PDMA_4_LPCG), 0, FUNCTION_NAME(PD_IMAGING_PDMA4));
+ clks[IMX8QM_IMG_PDMA_5_CLK] = imx_clk_gate2_scu("img_pdma5_clk", "pxl_img_clk_root", LPCG_ADDR(IMG_PDMA_5_LPCG), 0, FUNCTION_NAME(PD_IMAGING_PDMA5));
+ clks[IMX8QM_IMG_PDMA_6_CLK] = imx_clk_gate2_scu("img_pdma6_clk", "pxl_img_clk_root", LPCG_ADDR(IMG_PDMA_6_LPCG), 0, FUNCTION_NAME(PD_IMAGING_PDMA6));
+ clks[IMX8QM_IMG_PDMA_7_CLK] = imx_clk_gate2_scu("img_pdma7_clk", "pxl_img_clk_root", LPCG_ADDR(IMG_PDMA_7_LPCG), 0, FUNCTION_NAME(PD_IMAGING_PDMA7));
+
+ /* HSIO */
+ clks[IMX8QM_HSIO_PCIE_A_MSTR_AXI_CLK] = imx_clk_gate2_scu("hsio_pcieA_mstr_axi_clk", "axi_hsio_clk_root", LPCG_ADDR(HSIO_PCIE_X2_LPCG), 16, FUNCTION_NAME(PD_HSIO_PCIE_A));
+ clks[IMX8QM_HSIO_PCIE_A_SLV_AXI_CLK] = imx_clk_gate2_scu("hsio_pcieA_slv_axi_clk", "axi_hsio_clk_root", LPCG_ADDR(HSIO_PCIE_X2_LPCG), 20, FUNCTION_NAME(PD_HSIO_PCIE_A));
+ clks[IMX8QM_HSIO_PCIE_A_DBI_AXI_CLK] = imx_clk_gate2_scu("hsio_pcieA_dbi_axi_clk", "axi_hsio_clk_root", LPCG_ADDR(HSIO_PCIE_X2_LPCG), 24, FUNCTION_NAME(PD_HSIO_PCIE_A));
+ clks[IMX8QM_HSIO_PCIE_B_MSTR_AXI_CLK] = imx_clk_gate2_scu("hsio_pcieB_mstr_axi_clk", "axi_hsio_clk_root", LPCG_ADDR(HSIO_PCIE_X1_LPCG), 16, FUNCTION_NAME(PD_HSIO_PCIE_B));
+ clks[IMX8QM_HSIO_PCIE_B_SLV_AXI_CLK] = imx_clk_gate2_scu("hsio_pcieB_slv_axi_clk", "axi_hsio_clk_root", LPCG_ADDR(HSIO_PCIE_X1_LPCG), 20, FUNCTION_NAME(PD_HSIO_PCIE_B));
+ clks[IMX8QM_HSIO_PCIE_B_DBI_AXI_CLK] = imx_clk_gate2_scu("hsio_pcieB_dbi_axi_clk", "axi_hsio_clk_root", LPCG_ADDR(HSIO_PCIE_X1_LPCG), 24, FUNCTION_NAME(PD_HSIO_PCIE_B));
+ clks[IMX8QM_HSIO_PCIE_X1_PER_CLK] = imx_clk_gate2_scu("hsio_pcie_x1_per_clk", "per_hsio_clk_root", LPCG_ADDR(HSIO_PCIE_X1_CRR3_LPCG), 16, FUNCTION_NAME(PD_HSIO_PCIE_B));
+ clks[IMX8QM_HSIO_PCIE_X2_PER_CLK] = imx_clk_gate2_scu("hsio_pcie_x2_per_clk", "per_hsio_clk_root", LPCG_ADDR(HSIO_PCIE_X2_CRR2_LPCG), 16, FUNCTION_NAME(PD_HSIO_PCIE_A));
+ clks[IMX8QM_HSIO_SATA_PER_CLK] = imx_clk_gate2_scu("hsio_sata_per_clk", "per_hsio_clk_root", LPCG_ADDR(HSIO_SATA_CRR4_LPCG), 16, FUNCTION_NAME(PD_HSIO_SATA_0));
+ clks[IMX8QM_HSIO_PHY_X1_PER_CLK] = imx_clk_gate2_scu("hsio_phy_x1_per_clk", "per_hsio_clk_root", LPCG_ADDR(HSIO_PHY_X1_CRR1_LPCG), 16, FUNCTION_NAME(PD_HSIO_SATA_0));
+ clks[IMX8QM_HSIO_PHY_X2_PER_CLK] = imx_clk_gate2_scu("hsio_phy_x2_per_clk", "per_hsio_clk_root", LPCG_ADDR(HSIO_PHY_X2_CRR0_LPCG), 16, FUNCTION_NAME(PD_HSIO_PCIE_A));
+ clks[IMX8QM_HSIO_MISC_PER_CLK] = imx_clk_gate2_scu("hsio_misc_per_clk", "per_hsio_clk_root", LPCG_ADDR(HSIO_MISC_LPCG), 16, FUNCTION_NAME(PD_HSIO));
+ clks[IMX8QM_HSIO_PHY_X1_APB_CLK] = imx_clk_gate2_scu("hsio_phy_x1_apb_clk", "per_hsio_clk_root", LPCG_ADDR(HSIO_PHY_X1_LPCG), 16, FUNCTION_NAME(PD_HSIO_SATA_0));
+ clks[IMX8QM_HSIO_PHY_X2_APB_0_CLK] = imx_clk_gate2_scu("hsio_phy_x2_apb_0_clk", "per_hsio_clk_root", LPCG_ADDR(HSIO_PHY_X2_LPCG), 16, FUNCTION_NAME(PD_HSIO_PCIE_A));
+ clks[IMX8QM_HSIO_PHY_X2_APB_1_CLK] = imx_clk_gate2_scu("hsio_phy_x2_apb_1_clk", "per_hsio_clk_root", LPCG_ADDR(HSIO_PHY_X2_LPCG), 20, FUNCTION_NAME(PD_HSIO_PCIE_A));
+ clks[IMX8QM_HSIO_SATA_CLK] = imx_clk_gate2_scu("hsio_sata_clk", "axi_hsio_clk_root", LPCG_ADDR(HSIO_SATA_LPCG), 16, FUNCTION_NAME(PD_HSIO_SATA_0));
+ clks[IMX8QM_HSIO_GPIO_CLK] = imx_clk_gate2_scu("hsio_gpio_clk", "per_hsio_clk_root", LPCG_ADDR(HSIO_GPIO_LPCG), 16, FUNCTION_NAME(PD_HSIO_PCIE_A));
+ clks[IMX8QM_HSIO_PHY_X1_PCLK] = imx_clk_gate2_scu("hsio_phy_x1_pclk", "dummy", LPCG_ADDR(HSIO_PHY_X1_LPCG), 0, FUNCTION_NAME(PD_HSIO_SATA_0));
+ clks[IMX8QM_HSIO_PHY_X2_PCLK_0] = imx_clk_gate2_scu("hsio_phy_x2_pclk_0", "dummy", LPCG_ADDR(HSIO_PHY_X2_LPCG), 0, FUNCTION_NAME(PD_HSIO_PCIE_A));
+ clks[IMX8QM_HSIO_PHY_X2_PCLK_1] = imx_clk_gate2_scu("hsio_phy_x2_pclk_1", "dummy", LPCG_ADDR(HSIO_PHY_X2_LPCG), 4, FUNCTION_NAME(PD_HSIO_PCIE_B));
+ clks[IMX8QM_HSIO_SATA_EPCS_RX_CLK] = imx_clk_gate2_scu("hsio_sata_epcs_rx_clk", "dummy", LPCG_ADDR(HSIO_PHY_X1_LPCG), 8, FUNCTION_NAME(PD_HSIO_SATA_0));
+ clks[IMX8QM_HSIO_SATA_EPCS_TX_CLK] = imx_clk_gate2_scu("hsio_sata_epcs_tx_clk", "dummy", LPCG_ADDR(HSIO_PHY_X1_LPCG), 4, FUNCTION_NAME(PD_HSIO_SATA_0));
+
+ /* CM40 */
+ clks[IMX8QM_CM40_I2C_DIV] = imx_clk_divider_scu("cm40_i2c_div", SC_R_M4_0_I2C, SC_PM_CLK_PER);
+ clks[IMX8QM_CM40_I2C_CLK] = imx_clk_gate_scu("cm40_i2c_clk", "cm40_i2c_div", SC_R_M4_0_I2C, SC_PM_CLK_PER, (void __iomem *)(CM40_I2C_LPCG), 0, 0);
+ clks[IMX8QM_CM40_I2C_IPG_CLK] = imx_clk_gate2_scu("cm40_i2c_ipg_clk", "ipg_cm40_clk_root", (void __iomem *)(CM40_I2C_LPCG), 16, FUNCTION_NAME(PD_CM40_I2C));
+
+ /* CM41 */
+ clks[IMX8QM_CM41_I2C_DIV] = imx_clk_divider_scu("cm41_i2c_div", SC_R_M4_1_I2C, SC_PM_CLK_PER);
+ clks[IMX8QM_CM41_I2C_CLK] = imx_clk_gate_scu("cm41_i2c_clk", "cm41_i2c_div", SC_R_M4_1_I2C, SC_PM_CLK_PER, (void __iomem *)(CM41_I2C_LPCG), 0, 0);
+ clks[IMX8QM_CM41_I2C_IPG_CLK] = imx_clk_gate2_scu("cm41_i2c_ipg_clk", "ipg_cm41_clk_root", (void __iomem *)(CM41_I2C_LPCG), 16, FUNCTION_NAME(PD_CM41_I2C));
+
+ for (i = 0; i < ARRAY_SIZE(clks); i++)
+ if (IS_ERR(clks[i]) && PTR_ERR(clks[i]) != -ENODEV)
+ pr_err("i.MX8QM clk %d: register failed with %ld\n",
+ i, PTR_ERR(clks[i]));
+
+ clk_data.clks = clks;
+ clk_data.clk_num = ARRAY_SIZE(clks);
+ of_clk_add_provider(ccm_node, of_clk_src_onecell_get, &clk_data);
+
+ return 0;
+}
+
+static const struct of_device_id imx8qm_match[] = {
+ { .compatible = "fsl,imx8qm-clk", },
+ { /* sentinel value */ }
+};
+
+static struct platform_driver imx8qm_clk_driver = {
+ .driver = {
+ .name = "imx8qm-clk",
+ .of_match_table = imx8qm_match,
+ },
+ .probe = imx8qm_clk_probe,
+};
+
+static int __init imx8qm_clk_init(void)
+{
+ return platform_driver_register(&imx8qm_clk_driver);
+}
+core_initcall(imx8qm_clk_init);
diff --git a/drivers/clk/imx/clk-imx8qxp.c b/drivers/clk/imx/clk-imx8qxp.c
new file mode 100644
index 000000000000..424c706a5481
--- /dev/null
+++ b/drivers/clk/imx/clk-imx8qxp.c
@@ -0,0 +1,739 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017-2018 NXP
+ *
+ * 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 <dt-bindings/clock/imx8qxp-clock.h>
+#include <dt-bindings/soc/imx8_pd.h>
+#include <linux/clk.h>
+#include <linux/clkdev.h>
+#include <linux/clk-provider.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/types.h>
+#include <linux/platform_device.h>
+#include <linux/pm_domain.h>
+
+#include <soc/imx8/imx8qxp/lpcg.h>
+#include <soc/imx8/sc/sci.h>
+#include "clk-imx8.h"
+
+#define STR_VALUE(arg) #arg
+#define FUNCTION_NAME(name) STR_VALUE(name)
+
+static const char *aud_clk_sels[] = {
+ "aud_acm_aud_rec_clk0_clk",
+ "aud_acm_aud_rec_clk1_clk",
+ "ext_aud_mclk0",
+ "ext_aud_mclk1",
+ "esai0_rx_clk",
+ "esai0_rx_hf_clk",
+ "esai0_tx_clk",
+ "esai0_tx_hf_clk",
+ "spdif0_rx",
+ "sai0_rx_bclk",
+ "sai0_tx_bclk",
+ "sai1_rx_bclk",
+ "sai1_tx_bclk",
+ "sai2_rx_bclk",
+ "sai3_rx_bclk",
+};
+
+static const char *mclk_out_sels[] = {
+ "aud_acm_aud_rec_clk0_clk",
+ "aud_acm_aud_rec_clk1_clk",
+ "dummy",
+ "dummy",
+ "spdif0_rx",
+ "dummy",
+ "dummy",
+ "sai4_rx_bclk",
+};
+
+static const char *sai_mclk_sels[] = {
+ "aud_acm_aud_pll_clk0_clk",
+ "aud_acm_aud_pll_clk1_clk",
+ "acm_aud_clk0_clk",
+ "acm_aud_clk1_clk",
+};
+
+static const char *esai_mclk_sels[] = {
+ "aud_acm_aud_pll_clk0_clk",
+ "aud_acm_aud_pll_clk1_clk",
+ "acm_aud_clk0_clk",
+ "acm_aud_clk1_clk",
+};
+
+static const char *spdif_mclk_sels[] = {
+ "aud_acm_aud_pll_clk0_clk",
+ "aud_acm_aud_pll_clk1_clk",
+ "acm_aud_clk0_clk",
+ "acm_aud_clk1_clk",
+};
+
+static const char *mqs_mclk_sels[] = {
+ "aud_acm_aud_pll_clk0_clk",
+ "aud_acm_aud_pll_clk1_clk",
+ "acm_aud_clk0_clk",
+ "acm_aud_clk1_clk",
+};
+
+static const char *mipi0_sels[] = {
+ "dummy",
+ "mipi0_pll_clk",
+ "mipi0_pll_div2_clk",
+ "dummy",
+ "mipi0_lvds_bypass_clk",
+};
+
+static const char *mipi1_sels[] = {
+ "dummy",
+ "mipi1_pll_clk",
+ "mipi1_pll_div2_clk",
+ "dummy",
+ "mipi1_lvds_bypass_clk",
+};
+
+static const char *sdhc0_sels[] = {
+ "dummy",
+ "conn_pll0_clk",
+ "conn_pll1_clk",
+ "dummy",
+ "dummy",
+};
+
+static const char *sdhc1_sels[] = {
+ "dummy",
+ "conn_pll0_clk",
+ "conn_pll1_clk",
+ "dummy",
+ "dummy",
+};
+
+static const char *sdhc2_sels[] = {
+ "dummy",
+ "conn_pll0_clk",
+ "conn_pll1_clk",
+ "dummy",
+ "dummy",
+};
+
+static const char *pll0_sels[] = {
+ "dummy",
+ "parallel_pll_clk",
+ "dummy",
+ "dummy",
+ "dummy",
+};
+
+static const char *lcd_pxl_sels[] = {
+ "dummy",
+ "dummy",
+ "dummy",
+ "dummy",
+ "lcd_pxl_bypass_div",
+};
+
+static const char *lcd_sels[] = {
+ "dummy",
+ "dummy",
+ "dummy",
+ "dummy",
+ "elcdif_pll",
+};
+
+static struct clk *clks[IMX8QXP_CLK_END];
+static struct clk_onecell_data clk_data;
+
+static const char *enet_sels[] = { "enet_25MHz", "enet_125MHz", };
+static const char *enet0_rmii_tx_sels[] = { "enet0_ref_div", "dummy", };
+static const char *enet1_rmii_tx_sels[] = { "enet1_ref_div", "dummy", };
+
+static int imx8qxp_clk_probe(struct platform_device *pdev)
+{
+ struct device_node *ccm_node = pdev->dev.of_node;
+ struct device_node *np_acm;
+ void __iomem *base_acm;
+ int i, ret;
+
+ ret = imx8_clk_mu_init();
+ if (ret)
+ return ret;
+
+ pr_info("***** imx8qxp_clocks_init *****\n");
+
+ /* Fixed clocks */
+ clks[IMX8QXP_CLK_DUMMY] = imx_clk_fixed("dummy", 0);
+ clks[IMX8QXP_24MHZ] = imx_clk_fixed("xtal_24MHz", SC_24MHZ);
+ clks[IMX8QXP_GPT_3M] = imx_clk_fixed("gpt_3m", 3000000);
+ clks[IMX8QXP_32KHZ] = imx_clk_fixed("xtal_32KHz", SC_32KHZ);
+
+ /* ARM core */
+ clks[IMX8QXP_A35_DIV] = imx_clk_divider_scu("a35_div", SC_R_A35, SC_PM_CLK_CPU);
+
+ /* User Defined PLLs dividers */
+ clks[IMX8QXP_AUD_PLL0_DIV] = imx_clk_divider_scu("audio_pll0_div", SC_R_AUDIO_PLL_0, SC_PM_CLK_PLL);
+ clks[IMX8QXP_AUD_PLL1_DIV] = imx_clk_divider_scu("audio_pll1_div", SC_R_AUDIO_PLL_1, SC_PM_CLK_PLL);
+ clks[IMX8QXP_ELCDIF_PLL_DIV] = imx_clk_divider_scu("elcdif_pll_div", SC_R_ELCDIF_PLL, SC_PM_CLK_PLL);
+
+ /* User Defined PLLs clocks */
+ clks[IMX8QXP_AUD_PLL0] = imx_clk_gate_scu("audio_pll0_clk", "audio_pll0_div", SC_R_AUDIO_PLL_0, SC_PM_CLK_PLL, NULL, 0, 0);
+ clks[IMX8QXP_AUD_PLL1] = imx_clk_gate_scu("audio_pll1_clk", "audio_pll1_div", SC_R_AUDIO_PLL_1, SC_PM_CLK_PLL, NULL, 0, 0);
+ clks[IMX8QXP_ELCDIF_PLL] = imx_clk_gate_scu("elcdif_pll", "elcdif_pll_div", SC_R_ELCDIF_PLL, SC_PM_CLK_PLL, NULL, 0, 0);
+
+ clks[IMX8QXP_IPG_DMA_CLK_ROOT] = imx_clk_fixed("ipg_dma_clk_root", SC_120MHZ);
+ clks[IMX8QXP_IPG_AUD_CLK_ROOT] = imx_clk_fixed("ipg_aud_clk_root", SC_150MHZ);
+ clks[IMX8QXP_AXI_CONN_CLK_ROOT] = imx_clk_fixed("axi_conn_clk_root", SC_333MHZ);
+ clks[IMX8QXP_AHB_CONN_CLK_ROOT] = imx_clk_fixed("ahb_conn_clk_root", SC_166MHZ);
+ clks[IMX8QXP_IPG_CONN_CLK_ROOT] = imx_clk_fixed("ipg_conn_clk_root", SC_83MHZ);
+ clks[IMX8QXP_DC_AXI_EXT_CLK] = imx_clk_fixed("axi_ext_dc_clk_root", SC_800MHZ);
+ clks[IMX8QXP_DC_AXI_INT_CLK] = imx_clk_fixed("axi_int_dc_clk_root", SC_400MHZ);
+ clks[IMX8QXP_DC_CFG_CLK] = imx_clk_fixed("cfg_dc_clk_root", SC_100MHZ);
+ clks[IMX8QXP_MIPI_IPG_CLK] = imx_clk_fixed("ipg_mipi_clk_root", SC_120MHZ);
+ clks[IMX8QXP_IMG_AXI_CLK] = imx_clk_fixed("axi_img_clk_root", SC_400MHZ);
+ clks[IMX8QXP_IMG_IPG_CLK] = imx_clk_fixed("ipg_img_clk_root", SC_200MHZ);
+ clks[IMX8QXP_IMG_PXL_CLK] = imx_clk_fixed("pxl_img_clk_root", SC_600MHZ);
+ clks[IMX8QXP_HSIO_AXI_CLK] = imx_clk_fixed("axi_hsio_clk_root", SC_400MHZ);
+ clks[IMX8QXP_HSIO_PER_CLK] = imx_clk_fixed("per_hsio_clk_root", SC_133MHZ);
+ clks[IMX8QXP_CM40_IPG_CLK] = imx_clk_fixed("ipg_cm40_clk_root", SC_132MHZ);
+ clks[IMX8QXP_MIPI0_DSI_PLL_CLK] = imx_clk_fixed("mipi0_pll_clk", SC_864MHZ);
+ clks[IMX8QXP_MIPI0_DSI_PLL_DIV2_CLK] = imx_clk_fixed("mipi0_pll_div2_clk", SC_432MHZ);
+ clks[IMX8QXP_MIPI1_DSI_PLL_CLK] = imx_clk_fixed("mipi1_pll_clk", SC_864MHZ);
+ clks[IMX8QXP_MIPI1_DSI_PLL_DIV2_CLK] = imx_clk_fixed("mipi1_pll_div2_clk", SC_432MHZ);
+ clks[IMX8QXP_CONN_PLL0_CLK] = imx_clk_fixed("conn_pll0_clk", SC_792MHZ);
+ clks[IMX8QXP_CONN_PLL1_CLK] = imx_clk_fixed("conn_pll1_clk", SC_1000MHZ);
+
+ clks[IMX8QXP_UART0_DIV] = imx_clk_divider_scu("uart0_div", SC_R_UART_0, SC_PM_CLK_PER);
+ clks[IMX8QXP_UART0_IPG_CLK] = imx_clk_gate2_scu("uart0_ipg_clk", "ipg_dma_clk_root", (void __iomem *)(LPUART_0_LPCG), 16, FUNCTION_NAME(PD_DMA_UART0));
+ clks[IMX8QXP_UART0_CLK] = imx_clk_gate_scu("uart0_clk", "uart0_div", SC_R_UART_0, SC_PM_CLK_PER, (void __iomem *)(LPUART_0_LPCG), 0, 0);
+
+ clks[IMX8QXP_GPU0_CORE_DIV] = imx_clk_divider_scu("gpu_core0_div", SC_R_GPU_0_PID0, SC_PM_CLK_PER);
+ clks[IMX8QXP_GPU0_SHADER_DIV] = imx_clk_divider_scu("gpu_shader0_div", SC_R_GPU_0_PID0, SC_PM_CLK_MISC);
+ clks[IMX8QXP_GPU0_CORE_CLK] = imx_clk_gate_scu("gpu_core0_clk", "gpu_core0_div", SC_R_GPU_0_PID0, SC_PM_CLK_PER, NULL, 0, 0);
+ clks[IMX8QXP_GPU0_SHADER_CLK] = imx_clk_gate_scu("gpu_shader0_clk", "gpu_shader0_div", SC_R_GPU_0_PID0, SC_PM_CLK_MISC, NULL, 0, 0);
+
+ /* LSIO SS */
+ clks[IMX8QXP_LSIO_MEM_CLK] = imx_clk_fixed("lsio_mem_clk_root", SC_100MHZ);
+ clks[IMX8QXP_LSIO_BUS_CLK] = imx_clk_fixed("lsio_bus_clk_root", SC_200MHZ);
+
+ clks[IMX8QXP_LSIO_PWM0_DIV] = imx_clk_divider_scu("pwm_0_div", SC_R_PWM_0, SC_PM_CLK_PER);
+ clks[IMX8QXP_LSIO_PWM0_IPG_S_CLK] = imx_clk_gate_scu("pwm_0_ipg_s_clk", "pwm_0_div", SC_R_PWM_0, SC_PM_CLK_PER, (void __iomem *)(PWM_0_LPCG), 0x10, 0);
+ clks[IMX8QXP_LSIO_PWM0_IPG_SLV_CLK] = imx_clk_gate_scu("pwm_0_ipg_slv_clk", "pwm_0_ipg_s_clk", SC_R_PWM_0, SC_PM_CLK_PER, (void __iomem *)(PWM_0_LPCG), 0x14, 0);
+ clks[IMX8QXP_LSIO_PWM0_IPG_MSTR_CLK] = imx_clk_gate2_scu("pwm_0_ipg_mstr_clk", "lsio_bus_clk_root", (void __iomem *)(PWM_0_LPCG), 0x18, FUNCTION_NAME(PD_LSIO_PWM_0));
+ clks[IMX8QXP_LSIO_PWM0_HF_CLK] = imx_clk_gate_scu("pwm_0_hf_clk", "pwm_0_ipg_slv_clk", SC_R_PWM_0, SC_PM_CLK_PER, (void __iomem *)(PWM_0_LPCG), 4, 0);
+ clks[IMX8QXP_LSIO_PWM0_CLK] = imx_clk_gate_scu("pwm_0_clk", "pwm_0_ipg_slv_clk", SC_R_PWM_0, SC_PM_CLK_PER, (void __iomem *)(PWM_0_LPCG), 0, 0);
+ clks[IMX8QXP_LSIO_PWM1_DIV] = imx_clk_divider_scu("pwm_1_div", SC_R_PWM_1, SC_PM_CLK_PER);
+ clks[IMX8QXP_LSIO_PWM1_IPG_S_CLK] = imx_clk_gate_scu("pwm_1_ipg_s_clk", "pwm_1_div", SC_R_PWM_1, SC_PM_CLK_PER, (void __iomem *)(PWM_1_LPCG), 0x10, 0);
+ clks[IMX8QXP_LSIO_PWM1_IPG_SLV_CLK] = imx_clk_gate_scu("pwm_1_ipg_slv_clk", "pwm_1_ipg_s_clk", SC_R_PWM_1, SC_PM_CLK_PER, (void __iomem *)(PWM_1_LPCG), 0x14, 0);
+ clks[IMX8QXP_LSIO_PWM1_IPG_MSTR_CLK] = imx_clk_gate2_scu("pwm_1_ipg_mstr_clk", "lsio_bus_clk_root", (void __iomem *)(PWM_1_LPCG), 0x18, FUNCTION_NAME(PD_LSIO_PWM_1));
+ clks[IMX8QXP_LSIO_PWM1_HF_CLK] = imx_clk_gate_scu("pwm_1_hf_clk", "pwm_1_ipg_slv_clk", SC_R_PWM_1, SC_PM_CLK_PER, (void __iomem *)(PWM_1_LPCG), 4, 0);
+ clks[IMX8QXP_LSIO_PWM1_CLK] = imx_clk_gate_scu("pwm_1_clk", "pwm_1_ipg_slv_clk", SC_R_PWM_1, SC_PM_CLK_PER, (void __iomem *)(PWM_1_LPCG), 0, 0);
+ clks[IMX8QXP_LSIO_PWM2_DIV] = imx_clk_divider_scu("pwm_2_div", SC_R_PWM_2, SC_PM_CLK_PER);
+ clks[IMX8QXP_LSIO_PWM2_IPG_S_CLK] = imx_clk_gate_scu("pwm_2_ipg_s_clk", "pwm_2_div", SC_R_PWM_2, SC_PM_CLK_PER, (void __iomem *)(PWM_2_LPCG), 0x10, 0);
+ clks[IMX8QXP_LSIO_PWM2_IPG_SLV_CLK] = imx_clk_gate_scu("pwm_2_ipg_slv_clk", "pwm_2_ipg_s_clk", SC_R_PWM_2, SC_PM_CLK_PER, (void __iomem *)(PWM_2_LPCG), 0x14, 0);
+ clks[IMX8QXP_LSIO_PWM2_IPG_MSTR_CLK] = imx_clk_gate2_scu("pwm_2_ipg_mstr_clk", "lsio_bus_clk_root", (void __iomem *)(PWM_2_LPCG), 0x18, FUNCTION_NAME(PD_LSIO_PWM_2));
+ clks[IMX8QXP_LSIO_PWM2_HF_CLK] = imx_clk_gate_scu("pwm_2_hf_clk", "pwm_2_ipg_slv_clk", SC_R_PWM_2, SC_PM_CLK_PER, (void __iomem *)(PWM_2_LPCG), 4, 0);
+ clks[IMX8QXP_LSIO_PWM2_CLK] = imx_clk_gate_scu("pwm_2_clk", "pwm_2_ipg_slv_clk", SC_R_PWM_2, SC_PM_CLK_PER, (void __iomem *)(PWM_2_LPCG), 0, 0);
+ clks[IMX8QXP_LSIO_PWM3_DIV] = imx_clk_divider_scu("pwm_3_div", SC_R_PWM_3, SC_PM_CLK_PER);
+ clks[IMX8QXP_LSIO_PWM3_IPG_S_CLK] = imx_clk_gate_scu("pwm_3_ipg_s_clk", "pwm_3_div", SC_R_PWM_3, SC_PM_CLK_PER, (void __iomem *)(PWM_3_LPCG), 0x10, 0);
+ clks[IMX8QXP_LSIO_PWM3_IPG_SLV_CLK] = imx_clk_gate_scu("pwm_3_ipg_slv_clk", "pwm_3_ipg_s_clk", SC_R_PWM_3, SC_PM_CLK_PER, (void __iomem *)(PWM_3_LPCG), 0x14, 0);
+ clks[IMX8QXP_LSIO_PWM3_IPG_MSTR_CLK] = imx_clk_gate2_scu("pwm_3_ipg_mstr_clk", "lsio_bus_clk_root", (void __iomem *)(PWM_3_LPCG), 0x18, FUNCTION_NAME(PD_LSIO_PWM_3));
+ clks[IMX8QXP_LSIO_PWM3_HF_CLK] = imx_clk_gate_scu("pwm_3_hf_clk", "pwm_3_ipg_slv_clk", SC_R_PWM_3, SC_PM_CLK_PER, (void __iomem *)(PWM_3_LPCG), 4, 0);
+ clks[IMX8QXP_LSIO_PWM3_CLK] = imx_clk_gate_scu("pwm_3_clk", "pwm_3_ipg_slv_clk", SC_R_PWM_3, SC_PM_CLK_PER, (void __iomem *)(PWM_3_LPCG), 0, 0);
+ clks[IMX8QXP_LSIO_PWM4_DIV] = imx_clk_divider_scu("pwm_4_div", SC_R_PWM_4, SC_PM_CLK_PER);
+ clks[IMX8QXP_LSIO_PWM4_IPG_S_CLK] = imx_clk_gate_scu("pwm_4_ipg_s_clk", "pwm_4_div", SC_R_PWM_4, SC_PM_CLK_PER, (void __iomem *)(PWM_4_LPCG), 0x10, 0);
+ clks[IMX8QXP_LSIO_PWM4_IPG_SLV_CLK] = imx_clk_gate_scu("pwm_4_ipg_slv_clk", "pwm_4_ipg_s_clk", SC_R_PWM_4, SC_PM_CLK_PER, (void __iomem *)(PWM_4_LPCG), 0x14, 0);
+ clks[IMX8QXP_LSIO_PWM4_IPG_MSTR_CLK] = imx_clk_gate2_scu("pwm_4_ipg_mstr_clk", "lsio_bus_clk_root", (void __iomem *)(PWM_4_LPCG), 0x18, FUNCTION_NAME(PD_LSIO_PWM_4));
+ clks[IMX8QXP_LSIO_PWM4_HF_CLK] = imx_clk_gate_scu("pwm_4_hf_clk", "pwm_4_ipg_slv_clk", SC_R_PWM_4, SC_PM_CLK_PER, (void __iomem *)(PWM_4_LPCG), 4, 0);
+ clks[IMX8QXP_LSIO_PWM4_CLK] = imx_clk_gate_scu("pwm_4_clk", "pwm_4_ipg_slv_clk", SC_R_PWM_4, SC_PM_CLK_PER, (void __iomem *)(PWM_4_LPCG), 0, 0);
+ clks[IMX8QXP_LSIO_PWM5_DIV] = imx_clk_divider_scu("pwm_5_div", SC_R_PWM_5, SC_PM_CLK_PER);
+ clks[IMX8QXP_LSIO_PWM5_IPG_S_CLK] = imx_clk_gate_scu("pwm_5_ipg_s_clk", "pwm_5_div", SC_R_PWM_5, SC_PM_CLK_PER, (void __iomem *)(PWM_5_LPCG), 0x10, 0);
+ clks[IMX8QXP_LSIO_PWM5_IPG_SLV_CLK] = imx_clk_gate_scu("pwm_5_ipg_slv_clk", "pwm_5_ipg_s_clk", SC_R_PWM_5, SC_PM_CLK_PER, (void __iomem *)(PWM_5_LPCG), 0x14, 0);
+ clks[IMX8QXP_LSIO_PWM5_IPG_MSTR_CLK] = imx_clk_gate2_scu("pwm_5_ipg_mstr_clk", "lsio_bus_clk_root", (void __iomem *)(PWM_5_LPCG), 0x18, FUNCTION_NAME(PD_LSIO_PWM_5));
+ clks[IMX8QXP_LSIO_PWM5_HF_CLK] = imx_clk_gate_scu("pwm_5_hf_clk", "pwm_5_ipg_slv_clk", SC_R_PWM_5, SC_PM_CLK_PER, (void __iomem *)(PWM_5_LPCG), 4, 0);
+ clks[IMX8QXP_LSIO_PWM5_CLK] = imx_clk_gate_scu("pwm_5_clk", "pwm_5_ipg_slv_clk", SC_R_PWM_5, SC_PM_CLK_PER, (void __iomem *)(PWM_5_LPCG), 0, 0);
+ clks[IMX8QXP_LSIO_PWM6_DIV] = imx_clk_divider_scu("pwm_6_div", SC_R_PWM_6, SC_PM_CLK_PER);
+ clks[IMX8QXP_LSIO_PWM6_IPG_S_CLK] = imx_clk_gate_scu("pwm_6_ipg_s_clk", "pwm_6_div", SC_R_PWM_6, SC_PM_CLK_PER, (void __iomem *)(PWM_6_LPCG), 0x10, 0);
+ clks[IMX8QXP_LSIO_PWM6_IPG_SLV_CLK] = imx_clk_gate_scu("pwm_6_ipg_slv_clk", "pwm_6_ipg_s_clk", SC_R_PWM_6, SC_PM_CLK_PER, (void __iomem *)(PWM_6_LPCG), 0x14, 0);
+ clks[IMX8QXP_LSIO_PWM6_IPG_MSTR_CLK] = imx_clk_gate2_scu("pwm_6_ipg_mstr_clk", "lsio_bus_clk_root", (void __iomem *)(PWM_6_LPCG), 0x18, FUNCTION_NAME(PD_LSIO_PWM_6));
+ clks[IMX8QXP_LSIO_PWM6_HF_CLK] = imx_clk_gate_scu("pwm_6_hf_clk", "pwm_6_ipg_slv_clk", SC_R_PWM_6, SC_PM_CLK_PER, (void __iomem *)(PWM_6_LPCG), 4, 0);
+ clks[IMX8QXP_LSIO_PWM6_CLK] = imx_clk_gate_scu("pwm_6_clk", "pwm_6_ipg_slv_clk", SC_R_PWM_6, SC_PM_CLK_PER, (void __iomem *)(PWM_6_LPCG), 0, 0);
+ clks[IMX8QXP_LSIO_PWM7_DIV] = imx_clk_divider_scu("pwm_7_div", SC_R_PWM_7, SC_PM_CLK_PER);
+ clks[IMX8QXP_LSIO_PWM7_IPG_S_CLK] = imx_clk_gate_scu("pwm_7_ipg_s_clk", "pwm_7_div", SC_R_PWM_7, SC_PM_CLK_PER, (void __iomem *)(PWM_7_LPCG), 0x10, 0);
+ clks[IMX8QXP_LSIO_PWM7_IPG_SLV_CLK] = imx_clk_gate_scu("pwm_7_ipg_slv_clk", "pwm_7_ipg_s_clk", SC_R_PWM_7, SC_PM_CLK_PER, (void __iomem *)(PWM_7_LPCG), 0x14, 0);
+ clks[IMX8QXP_LSIO_PWM7_IPG_MSTR_CLK] = imx_clk_gate2_scu("pwm_7_ipg_mstr_clk", "lsio_bus_clk_root", (void __iomem *)(PWM_7_LPCG), 0x18, FUNCTION_NAME(PD_LSIO_PWM_7));
+ clks[IMX8QXP_LSIO_PWM7_HF_CLK] = imx_clk_gate_scu("pwm_7_hf_clk", "pwm_7_ipg_slv_clk", SC_R_PWM_7, SC_PM_CLK_PER, (void __iomem *)(PWM_7_LPCG), 4, 0);
+ clks[IMX8QXP_LSIO_PWM7_CLK] = imx_clk_gate_scu("pwm_7_clk", "pwm_7_ipg_slv_clk", SC_R_PWM_7, SC_PM_CLK_PER, (void __iomem *)(PWM_7_LPCG), 0, 0);
+ clks[IMX8QXP_LSIO_GPT0_DIV] = imx_clk_divider_scu("gpt_0_div", SC_R_GPT_4, SC_PM_CLK_PER);
+ clks[IMX8QXP_LSIO_GPT0_IPG_S_CLK] = imx_clk_gate_scu("gpt_0_ipg_s_clk", "gpt_0_div", SC_R_GPT_0, SC_PM_CLK_PER, (void __iomem *)(GPT_0_LPCG), 0x10, 0);
+ clks[IMX8QXP_LSIO_GPT0_IPG_SLV_CLK] = imx_clk_gate_scu("gpt_0_ipg_slv_clk", "gpt_0_ipg_s_clk", SC_R_GPT_0, SC_PM_CLK_PER, (void __iomem *)(GPT_0_LPCG), 0x14, 0);
+ clks[IMX8QXP_LSIO_GPT0_CLK] = imx_clk_gate_scu("gpt_0_clk", "gpt_0_ipg_slv_clk", SC_R_GPT_0, SC_PM_CLK_PER, (void __iomem *)(GPT_0_LPCG), 0, 0);
+ clks[IMX8QXP_LSIO_GPT0_IPG_MSTR_CLK] = imx_clk_gate2_scu("gpt_0_ipg_mstr_clk", "lsio_bus_clk_root", (void __iomem *)(GPT_0_LPCG), 0x18, FUNCTION_NAME(PD_LSIO_GPT_0));
+ clks[IMX8QXP_LSIO_GPT0_HF_CLK] = imx_clk_gate_scu("gpt_0_hf_clk", "gpt_0_ipg_slv_clk", SC_R_GPT_0, SC_PM_CLK_PER, (void __iomem *)(GPT_0_LPCG), 4, 0);
+ clks[IMX8QXP_LSIO_GPT1_DIV] = imx_clk_divider_scu("gpt_1_div", SC_R_GPT_4, SC_PM_CLK_PER);
+ clks[IMX8QXP_LSIO_GPT1_IPG_S_CLK] = imx_clk_gate_scu("gpt_1_ipg_s_clk", "gpt_1_div", SC_R_GPT_1, SC_PM_CLK_PER, (void __iomem *)(GPT_1_LPCG), 0x10, 0);
+ clks[IMX8QXP_LSIO_GPT1_IPG_SLV_CLK] = imx_clk_gate_scu("gpt_1_ipg_slv_clk", "gpt_1_ipg_s_clk", SC_R_GPT_1, SC_PM_CLK_PER, (void __iomem *)(GPT_1_LPCG), 0x14, 0);
+ clks[IMX8QXP_LSIO_GPT1_CLK] = imx_clk_gate_scu("gpt_1_clk", "gpt_1_ipg_slv_clk", SC_R_GPT_1, SC_PM_CLK_PER, (void __iomem *)(GPT_1_LPCG), 0, 0);
+ clks[IMX8QXP_LSIO_GPT1_HF_CLK] = imx_clk_gate_scu("gpt_1_hf_clk", "gpt_1_ipg_slv_clk", SC_R_GPT_1, SC_PM_CLK_PER, (void __iomem *)(GPT_1_LPCG), 4, 0);
+ clks[IMX8QXP_LSIO_GPT1_IPG_MSTR_CLK] = imx_clk_gate2_scu("gpt_1_ipg_mstr_clk", "lsio_bus_clk_root", (void __iomem *)(GPT_1_LPCG), 0x18, FUNCTION_NAME(PD_LSIO_GPT_1));
+ clks[IMX8QXP_LSIO_GPT2_DIV] = imx_clk_divider_scu("gpt_2_div", SC_R_GPT_4, SC_PM_CLK_PER);
+ clks[IMX8QXP_LSIO_GPT2_IPG_S_CLK] = imx_clk_gate_scu("gpt_2_ipg_s_clk", "gpt_2_div", SC_R_GPT_2, SC_PM_CLK_PER, (void __iomem *)(GPT_2_LPCG), 0x10, 0);
+ clks[IMX8QXP_LSIO_GPT2_IPG_SLV_CLK] = imx_clk_gate_scu("gpt_2_ipg_slv_clk", "gpt_2_ipg_s_clk", SC_R_GPT_2, SC_PM_CLK_PER, (void __iomem *)(GPT_2_LPCG), 0x14, 0);
+ clks[IMX8QXP_LSIO_GPT2_CLK] = imx_clk_gate_scu("gpt_2_clk", "gpt_2_ipg_slv_clk", SC_R_GPT_2, SC_PM_CLK_PER, (void __iomem *)(GPT_2_LPCG), 0, 0);
+ clks[IMX8QXP_LSIO_GPT2_HF_CLK] = imx_clk_gate_scu("gpt_2_hf_clk", "gpt_2_ipg_slv_clk", SC_R_GPT_2, SC_PM_CLK_PER, (void __iomem *)(GPT_2_LPCG), 4, 0);
+ clks[IMX8QXP_LSIO_GPT2_IPG_MSTR_CLK] = imx_clk_gate2_scu("gpt_2_ipg_mstr_clk", "lsio_bus_clk_root", (void __iomem *)(GPT_2_LPCG), 0x18, FUNCTION_NAME(PD_LSIO_GPT_2));
+ clks[IMX8QXP_LSIO_GPT3_DIV] = imx_clk_divider_scu("gpt_3_div", SC_R_GPT_4, SC_PM_CLK_PER);
+ clks[IMX8QXP_LSIO_GPT3_IPG_S_CLK] = imx_clk_gate_scu("gpt_3_ipg_s_clk", "gpt_3_div", SC_R_GPT_3, SC_PM_CLK_PER, (void __iomem *)(GPT_3_LPCG), 0x10, 0);
+ clks[IMX8QXP_LSIO_GPT3_IPG_SLV_CLK] = imx_clk_gate_scu("gpt_3_ipg_slv_clk", "gpt_3_ipg_s_clk", SC_R_GPT_3, SC_PM_CLK_PER, (void __iomem *)(GPT_3_LPCG), 0x14, 0);
+ clks[IMX8QXP_LSIO_GPT3_CLK] = imx_clk_gate_scu("gpt_3_clk", "gpt_3_ipg_slv_clk", SC_R_GPT_3, SC_PM_CLK_PER, (void __iomem *)(GPT_3_LPCG), 0, 0);
+ clks[IMX8QXP_LSIO_GPT3_HF_CLK] = imx_clk_gate_scu("gpt_3_hf_clk", "gpt_3_ipg_slv_clk", SC_R_GPT_3, SC_PM_CLK_PER, (void __iomem *)(GPT_3_LPCG), 4, 0);
+ clks[IMX8QXP_LSIO_GPT3_IPG_MSTR_CLK] = imx_clk_gate2_scu("gpt_3_ipg_mstr_clk", "lsio_bus_clk_root", (void __iomem *)(GPT_3_LPCG), 0x18, FUNCTION_NAME(PD_LSIO_GPT_3));
+ clks[IMX8QXP_LSIO_GPT4_DIV] = imx_clk_divider_scu("gpt_4_div", SC_R_GPT_4, SC_PM_CLK_PER);
+ clks[IMX8QXP_LSIO_GPT4_IPG_S_CLK] = imx_clk_gate_scu("gpt_4_ipg_s_clk", "gpt_4_div", SC_R_GPT_4, SC_PM_CLK_PER, (void __iomem *)(GPT_4_LPCG), 0x10, 0);
+ clks[IMX8QXP_LSIO_GPT4_IPG_SLV_CLK] = imx_clk_gate_scu("gpt_4_ipg_slv_clk", "gpt_4_ipg_s_clk", SC_R_GPT_4, SC_PM_CLK_PER, (void __iomem *)(GPT_4_LPCG), 0x14, 0);
+ clks[IMX8QXP_LSIO_GPT4_CLK] = imx_clk_gate_scu("gpt_4_clk", "gpt_4_ipg_slv_clk", SC_R_GPT_4, SC_PM_CLK_PER, (void __iomem *)(GPT_4_LPCG), 0, 0);
+ clks[IMX8QXP_LSIO_GPT4_HF_CLK] = imx_clk_gate_scu("gpt_4_hf_clk", "gpt_4_ipg_slv_clk", SC_R_GPT_4, SC_PM_CLK_PER, (void __iomem *)(GPT_4_LPCG), 4, 0);
+ clks[IMX8QXP_LSIO_GPT4_IPG_MSTR_CLK] = imx_clk_gate2_scu("gpt_4_ipg_mstr_clk", "lsio_bus_clk_root", (void __iomem *)(GPT_4_LPCG), 0x18, FUNCTION_NAME(PD_LSIO_GPT_4));
+ clks[IMX8QXP_LSIO_FSPI0_DIV] = imx_clk_divider_scu("fspi_0_div", SC_R_FSPI_0, SC_PM_CLK_PER);
+ clks[IMX8QXP_LSIO_FSPI0_HCLK] = imx_clk_gate2_scu("fspi0_hclk_clk", "lsio_mem_clk_root", (void __iomem *)(FSPI_0_LPCG), 0x10, FUNCTION_NAME(PD_LSIO_FSPI_0));
+ clks[IMX8QXP_LSIO_FSPI0_IPG_S_CLK] = imx_clk_gate2_scu("fspi0_ipg_s_clk", "lsio_bus_clk_root", (void __iomem *)(FSPI_0_LPCG), 0x18, FUNCTION_NAME(PD_LSIO_FSPI_0));
+ clks[IMX8QXP_LSIO_FSPI0_IPG_CLK] = imx_clk_gate2_scu("fspi0_ipg_clk", "fspi0_ipg_s_clk", (void __iomem *)(FSPI_0_LPCG), 0x14, FUNCTION_NAME(PD_LSIO_FSPI_0));
+ clks[IMX8QXP_LSIO_FSPI0_CLK] = imx_clk_gate_scu("fspi_0_clk", "fspi_0_div", SC_R_FSPI_0, SC_PM_CLK_PER, (void __iomem *)(FSPI_0_LPCG), 0, 0);
+ clks[IMX8QXP_LSIO_FSPI1_DIV] = imx_clk_divider_scu("fspi_1_div", SC_R_FSPI_1, SC_PM_CLK_PER);
+ clks[IMX8QXP_LSIO_FSPI1_HCLK] = imx_clk_gate2_scu("fspi1_hclk_clk", "lsio_mem_clk_root", (void __iomem *)(FSPI_1_LPCG), 0x10, FUNCTION_NAME(PD_LSIO_FSPI_1));
+ clks[IMX8QXP_LSIO_FSPI1_IPG_S_CLK] = imx_clk_gate2_scu("fspi1_ipg_s_clk", "lsio_bus_clk_root", (void __iomem *)(FSPI_1_LPCG), 0x18, FUNCTION_NAME(PD_LSIO_FSPI_1));
+ clks[IMX8QXP_LSIO_FSPI1_IPG_CLK] = imx_clk_gate2_scu("fspi1_ipg_clk", "fspi1_ipg_s_clk", (void __iomem *)(FSPI_1_LPCG), 0x14, FUNCTION_NAME(PD_LSIO_FSPI_1));
+ clks[IMX8QXP_LSIO_FSPI1_CLK] = imx_clk_gate_scu("fspi_1_clk", "fspi_1_div", SC_R_FSPI_1, SC_PM_CLK_PER, (void __iomem *)(FSPI_1_LPCG), 0, 0);
+ clks[IMX8QXP_LSIO_MU5A_IPG_S_CLK] = imx_clk_gate2_scu("mu5_a_ipg_s_clk", "lsio_bus_clk_root", (void __iomem *)(MU_5A_LPCG), 0x10, FUNCTION_NAME(PD_LSIO_MU5A));
+ clks[IMX8QXP_LSIO_MU5A_IPG_CLK] = imx_clk_gate2_scu("mu5_a_ipg_clk", "mu5_a_ipg_s_clk", (void __iomem *)(MU_5A_LPCG), 0x0, FUNCTION_NAME(PD_LSIO_MU5A));
+ /* ADMA SS */
+ clks[IMX8QXP_UART1_IPG_CLK] = imx_clk_gate2_scu("uart1_ipg_clk", "ipg_dma_clk_root", (void __iomem *)(LPUART_1_LPCG), 16, FUNCTION_NAME(PD_DMA_UART1));
+ clks[IMX8QXP_UART2_IPG_CLK] = imx_clk_gate2_scu("uart2_ipg_clk", "ipg_dma_clk_root", (void __iomem *)(LPUART_2_LPCG), 16, FUNCTION_NAME(PD_DMA_UART2));
+ clks[IMX8QXP_UART3_IPG_CLK] = imx_clk_gate2_scu("uart3_ipg_clk", "ipg_dma_clk_root", (void __iomem *)(LPUART_3_LPCG), 16, FUNCTION_NAME(PD_DMA_UART3));
+ clks[IMX8QXP_UART1_DIV] = imx_clk_divider_scu("uart1_div", SC_R_UART_1, SC_PM_CLK_PER);
+ clks[IMX8QXP_UART2_DIV] = imx_clk_divider_scu("uart2_div", SC_R_UART_2, SC_PM_CLK_PER);
+ clks[IMX8QXP_UART3_DIV] = imx_clk_divider_scu("uart3_div", SC_R_UART_3, SC_PM_CLK_PER);
+ clks[IMX8QXP_UART1_CLK] = imx_clk_gate_scu("uart1_clk", "uart1_div", SC_R_UART_1, SC_PM_CLK_PER, (void __iomem *)(LPUART_1_LPCG), 0, 0);
+ clks[IMX8QXP_UART2_CLK] = imx_clk_gate_scu("uart2_clk", "uart2_div", SC_R_UART_2, SC_PM_CLK_PER, (void __iomem *)(LPUART_2_LPCG), 0, 0);
+ clks[IMX8QXP_UART3_CLK] = imx_clk_gate_scu("uart3_clk", "uart3_div", SC_R_UART_3, SC_PM_CLK_PER, (void __iomem *)(LPUART_3_LPCG), 0, 0);
+ clks[IMX8QXP_SPI0_IPG_CLK] = imx_clk_gate2_scu("spi0_ipg_clk", "ipg_dma_clk_root", (void __iomem *)(LPSPI_0_LPCG), 16, FUNCTION_NAME(PD_DMA_SPI_0));
+ clks[IMX8QXP_SPI1_IPG_CLK] = imx_clk_gate2_scu("spi1_ipg_clk", "ipg_dma_clk_root", (void __iomem *)(LPSPI_1_LPCG), 16, FUNCTION_NAME(PD_DMA_SPI_1));
+ clks[IMX8QXP_SPI2_IPG_CLK] = imx_clk_gate2_scu("spi2_ipg_clk", "ipg_dma_clk_root", (void __iomem *)(LPSPI_2_LPCG), 16, FUNCTION_NAME(PD_DMA_SPI_2));
+ clks[IMX8QXP_SPI3_IPG_CLK] = imx_clk_gate2_scu("spi3_ipg_clk", "ipg_dma_clk_root", (void __iomem *)(LPSPI_3_LPCG), 16, FUNCTION_NAME(PD_DMA_SPI_3));
+ clks[IMX8QXP_SPI0_DIV] = imx_clk_divider_scu("spi0_div", SC_R_SPI_0, SC_PM_CLK_PER);
+ clks[IMX8QXP_SPI1_DIV] = imx_clk_divider_scu("spi1_div", SC_R_SPI_1, SC_PM_CLK_PER);
+ clks[IMX8QXP_SPI2_DIV] = imx_clk_divider_scu("spi2_div", SC_R_SPI_2, SC_PM_CLK_PER);
+ clks[IMX8QXP_SPI3_DIV] = imx_clk_divider_scu("spi3_div", SC_R_SPI_3, SC_PM_CLK_PER);
+ clks[IMX8QXP_SPI0_CLK] = imx_clk_gate_scu("spi0_clk", "spi0_div", SC_R_SPI_0, SC_PM_CLK_PER, (void __iomem *)(LPSPI_0_LPCG), 0, 0);
+ clks[IMX8QXP_SPI1_CLK] = imx_clk_gate_scu("spi1_clk", "spi1_div", SC_R_SPI_1, SC_PM_CLK_PER, (void __iomem *)(LPSPI_1_LPCG), 0, 0);
+ clks[IMX8QXP_SPI2_CLK] = imx_clk_gate_scu("spi2_clk", "spi2_div", SC_R_SPI_2, SC_PM_CLK_PER, (void __iomem *)(LPSPI_2_LPCG), 0, 0);
+ clks[IMX8QXP_SPI3_CLK] = imx_clk_gate_scu("spi3_clk", "spi3_div", SC_R_SPI_3, SC_PM_CLK_PER, (void __iomem *)(LPSPI_3_LPCG), 0, 0);
+ clks[IMX8QXP_CAN0_IPG_CHI_CLK] = imx_clk_gate2_scu("can0_ipg_chi_clk", "ipg_dma_clk_root", (void __iomem *)(FLEX_CAN_0_LPCG), 20, FUNCTION_NAME(PD_DMA_CAN_0));
+ clks[IMX8QXP_CAN0_IPG_CLK] = imx_clk_gate2_scu("can0_ipg_clk", "can0_ipg_chi_clk", (void __iomem *)(FLEX_CAN_0_LPCG), 16, FUNCTION_NAME(PD_DMA_CAN_0));
+ clks[IMX8QXP_CAN1_IPG_CHI_CLK] = imx_clk_gate2_scu("can1_ipg_chi_clk", "ipg_dma_clk_root", (void __iomem *)(FLEX_CAN_1_LPCG), 20, FUNCTION_NAME(PD_DMA_CAN_1));
+ clks[IMX8QXP_CAN1_IPG_CLK] = imx_clk_gate2_scu("can1_ipg_clk", "can1_ipg_chi_clk", (void __iomem *)(FLEX_CAN_1_LPCG), 16, FUNCTION_NAME(PD_DMA_CAN_1));
+ clks[IMX8QXP_CAN2_IPG_CHI_CLK] = imx_clk_gate2_scu("can2_ipg_chi_clk", "ipg_dma_clk_root", (void __iomem *)(FLEX_CAN_2_LPCG), 20, FUNCTION_NAME(PD_DMA_CAN_2));
+ clks[IMX8QXP_CAN2_IPG_CLK] = imx_clk_gate2_scu("can2_ipg_clk", "can2_ipg_chi_clk", (void __iomem *)(FLEX_CAN_2_LPCG), 16, FUNCTION_NAME(PD_DMA_CAN_2));
+ clks[IMX8QXP_CAN0_DIV] = imx_clk_divider_scu("can0_div", SC_R_CAN_0, SC_PM_CLK_PER);
+ clks[IMX8QXP_CAN1_DIV] = imx_clk_divider_scu("can1_div", SC_R_CAN_1, SC_PM_CLK_PER);
+ clks[IMX8QXP_CAN2_DIV] = imx_clk_divider_scu("can2_div", SC_R_CAN_2, SC_PM_CLK_PER);
+ clks[IMX8QXP_CAN0_CLK] = imx_clk_gate_scu("can0_clk", "can0_div", SC_R_CAN_0, SC_PM_CLK_PER, (void __iomem *)(FLEX_CAN_0_LPCG), 0, 0);
+ clks[IMX8QXP_CAN1_CLK] = imx_clk_gate_scu("can1_clk", "can1_div", SC_R_CAN_1, SC_PM_CLK_PER, (void __iomem *)(FLEX_CAN_1_LPCG), 0, 0);
+ clks[IMX8QXP_CAN2_CLK] = imx_clk_gate_scu("can2_clk", "can2_div", SC_R_CAN_2, SC_PM_CLK_PER, (void __iomem *)(FLEX_CAN_2_LPCG), 0, 0);
+ clks[IMX8QXP_I2C0_IPG_CLK] = imx_clk_gate2_scu("i2c0_ipg_clk", "ipg_dma_clk_root", (void __iomem *)(LPI2C_0_LPCG), 16, FUNCTION_NAME(PD_DMA_I2C_0));
+ clks[IMX8QXP_I2C1_IPG_CLK] = imx_clk_gate2_scu("i2c1_ipg_clk", "ipg_dma_clk_root", (void __iomem *)(LPI2C_1_LPCG), 16, FUNCTION_NAME(PD_DMA_I2C_1));
+ clks[IMX8QXP_I2C2_IPG_CLK] = imx_clk_gate2_scu("i2c2_ipg_clk", "ipg_dma_clk_root", (void __iomem *)(LPI2C_2_LPCG), 16, FUNCTION_NAME(PD_DMA_I2C_2));
+ clks[IMX8QXP_I2C3_IPG_CLK] = imx_clk_gate2_scu("i2c3_ipg_clk", "ipg_dma_clk_root", (void __iomem *)(LPI2C_3_LPCG), 16, FUNCTION_NAME(PD_DMA_I2C_3));
+ clks[IMX8QXP_I2C0_DIV] = imx_clk_divider_scu("i2c0_div", SC_R_I2C_0, SC_PM_CLK_PER);
+ clks[IMX8QXP_I2C1_DIV] = imx_clk_divider_scu("i2c1_div", SC_R_I2C_1, SC_PM_CLK_PER);
+ clks[IMX8QXP_I2C2_DIV] = imx_clk_divider_scu("i2c2_div", SC_R_I2C_2, SC_PM_CLK_PER);
+ clks[IMX8QXP_I2C3_DIV] = imx_clk_divider_scu("i2c3_div", SC_R_I2C_3, SC_PM_CLK_PER);
+ clks[IMX8QXP_I2C0_CLK] = imx_clk_gate_scu("i2c0_clk", "i2c0_div", SC_R_I2C_0, SC_PM_CLK_PER, (void __iomem *)(LPI2C_0_LPCG), 0, 0);
+ clks[IMX8QXP_I2C1_CLK] = imx_clk_gate_scu("i2c1_clk", "i2c1_div", SC_R_I2C_1, SC_PM_CLK_PER, (void __iomem *)(LPI2C_1_LPCG), 0, 0);
+ clks[IMX8QXP_I2C2_CLK] = imx_clk_gate_scu("i2c2_clk", "i2c2_div", SC_R_I2C_2, SC_PM_CLK_PER, (void __iomem *)(LPI2C_2_LPCG), 0, 0);
+ clks[IMX8QXP_I2C3_CLK] = imx_clk_gate_scu("i2c3_clk", "i2c3_div", SC_R_I2C_3, SC_PM_CLK_PER, (void __iomem *)(LPI2C_3_LPCG), 0, 0);
+ clks[IMX8QXP_FTM0_IPG_CLK] = imx_clk_gate2_scu("ftm0_ipg_clk", "ipg_dma_clk_root", (void __iomem *)(FTM_0_LPCG), 16, FUNCTION_NAME(PD_DMA_FTM_0));
+ clks[IMX8QXP_FTM1_IPG_CLK] = imx_clk_gate2_scu("ftm1_ipg_clk", "ipg_dma_clk_root", (void __iomem *)(FTM_1_LPCG), 16, FUNCTION_NAME(PD_DMA_FTM_1));
+ clks[IMX8QXP_FTM0_DIV] = imx_clk_divider_scu("ftm0_div", SC_R_FTM_0, SC_PM_CLK_PER);
+ clks[IMX8QXP_FTM1_DIV] = imx_clk_divider_scu("ftm1_div", SC_R_FTM_1, SC_PM_CLK_PER);
+ clks[IMX8QXP_FTM0_CLK] = imx_clk_gate_scu("ftm0_clk", "ftm0_div", SC_R_FTM_0, SC_PM_CLK_PER, (void __iomem *)(FTM_0_LPCG), 0, 0);
+ clks[IMX8QXP_FTM1_CLK] = imx_clk_gate_scu("ftm1_clk", "ftm1_div", SC_R_FTM_1, SC_PM_CLK_PER, (void __iomem *)(FTM_1_LPCG), 0, 0);
+ clks[IMX8QXP_ADC0_IPG_CLK] = imx_clk_gate2_scu("adc0_ipg_clk", "ipg_dma_clk_root", (void __iomem *)(ADC_0_LPCG), 16, FUNCTION_NAME(PD_DMA_ADC_0));
+ clks[IMX8QXP_ADC0_DIV] = imx_clk_divider_scu("adc0_div", SC_R_ADC_0, SC_PM_CLK_PER);
+ clks[IMX8QXP_ADC0_CLK] = imx_clk_gate_scu("adc0_clk", "adc0_div", SC_R_ADC_0, SC_PM_CLK_PER, (void __iomem *)(ADC_0_LPCG), 0, 0);
+ clks[IMX8QXP_PWM_IPG_CLK] = imx_clk_gate2_scu("pwm_ipg_clk", "ipg_dma_clk_root", (void __iomem *)(PWM_LPCG), 16, FUNCTION_NAME(PD_DMA_PWM_0));
+ clks[IMX8QXP_PWM_DIV] = imx_clk_divider_scu("pwm_div", SC_R_LCD_0_PWM_0, SC_PM_CLK_PER);
+ clks[IMX8QXP_PWM_CLK] = imx_clk_gate_scu("pwm_clk", "pwm_div", SC_R_LCD_0_PWM_0, SC_PM_CLK_PER, (void __iomem *)(PWM_LPCG), 0, 0);
+ clks[IMX8QXP_LCD_IPG_CLK] = imx_clk_gate2_scu("lcd_ipg_clk", "ipg_dma_clk_root", (void __iomem *)(LCD_LPCG), 16, FUNCTION_NAME(PD_DMA_LCD_0));
+
+ clks[IMX8QXP_LCD_PXL_BYPASS_DIV] = imx_clk_divider_scu("lcd_pxl_bypass_div", SC_R_LCD_0, SC_PM_CLK_BYPASS);
+ clks[IMX8QXP_LCD_PXL_SEL] = imx_clk_mux2_scu("lcd_pxl_sel", lcd_pxl_sels, ARRAY_SIZE(lcd_pxl_sels), SC_R_LCD_0, SC_PM_CLK_MISC0);
+ clks[IMX8QXP_LCD_PXL_DIV] = imx_clk_divider2_scu("lcd_pxl_div", "lcd_pxl_sel", SC_R_LCD_0, SC_PM_CLK_MISC0);
+ clks[IMX8QXP_LCD_PXL_CLK] = imx_clk_gate_scu("lcd_pxl_clk", "lcd_pxl_div", SC_R_LCD_0, SC_PM_CLK_MISC0, NULL, 0, 0);
+ clks[IMX8QXP_LCD_SEL] = imx_clk_mux2_scu("lcd_sel", lcd_sels, ARRAY_SIZE(lcd_sels), SC_R_LCD_0, SC_PM_CLK_PER);
+ clks[IMX8QXP_LCD_DIV] = imx_clk_divider2_scu("lcd_div", "lcd_sel", SC_R_LCD_0, SC_PM_CLK_PER);
+ clks[IMX8QXP_LCD_CLK] = imx_clk_gate_scu("lcd_clk", "lcd_div", SC_R_LCD_0, SC_PM_CLK_PER, (void __iomem *)(LCD_LPCG), 0, 0);
+
+ /* Connectivity */
+ clks[IMX8QXP_SDHC0_IPG_CLK] = imx_clk_gate2_scu("sdhc0_ipg_clk", "ipg_conn_clk_root", (void __iomem *)(USDHC_0_LPCG), 16, FUNCTION_NAME(PD_CONN_SDHC_0));
+ clks[IMX8QXP_SDHC1_IPG_CLK] = imx_clk_gate2_scu("sdhc1_ipg_clk", "ipg_conn_clk_root", (void __iomem *)(USDHC_1_LPCG), 16, FUNCTION_NAME(PD_CONN_SDHC_1));
+ clks[IMX8QXP_SDHC2_IPG_CLK] = imx_clk_gate2_scu("sdhc2_ipg_clk", "ipg_conn_clk_root", (void __iomem *)(USDHC_2_LPCG), 16, FUNCTION_NAME(PD_CONN_SDHC_2));
+ clks[IMX8QXP_SDHC0_SEL] = imx_clk_mux2_scu("sdhc0_sel", sdhc0_sels, ARRAY_SIZE(sdhc0_sels), SC_R_SDHC_0, SC_PM_CLK_PER);
+ clks[IMX8QXP_SDHC1_SEL] = imx_clk_mux2_scu("sdhc1_sel", sdhc1_sels, ARRAY_SIZE(sdhc1_sels), SC_R_SDHC_1, SC_PM_CLK_PER);
+ clks[IMX8QXP_SDHC2_SEL] = imx_clk_mux2_scu("sdhc2_sel", sdhc2_sels, ARRAY_SIZE(sdhc2_sels), SC_R_SDHC_2, SC_PM_CLK_PER);
+ clks[IMX8QXP_SDHC0_DIV] = imx_clk_divider2_scu("sdhc0_div", "sdhc0_sel", SC_R_SDHC_0, SC_PM_CLK_PER);
+ clks[IMX8QXP_SDHC1_DIV] = imx_clk_divider2_scu("sdhc1_div", "sdhc1_sel", SC_R_SDHC_1, SC_PM_CLK_PER);
+ clks[IMX8QXP_SDHC2_DIV] = imx_clk_divider2_scu("sdhc2_div", "sdhc2_sel", SC_R_SDHC_2, SC_PM_CLK_PER);
+ clks[IMX8QXP_SDHC0_CLK] = imx_clk_gate_scu("sdhc0_clk", "sdhc0_div", SC_R_SDHC_0, SC_PM_CLK_PER, (void __iomem *)(USDHC_0_LPCG), 0, 0);
+ clks[IMX8QXP_SDHC1_CLK] = imx_clk_gate_scu("sdhc1_clk", "sdhc1_div", SC_R_SDHC_1, SC_PM_CLK_PER, (void __iomem *)(USDHC_1_LPCG), 0, 0);
+ clks[IMX8QXP_SDHC2_CLK] = imx_clk_gate_scu("sdhc2_clk", "sdhc2_div", SC_R_SDHC_2, SC_PM_CLK_PER, (void __iomem *)(USDHC_2_LPCG), 0, 0);
+ clks[IMX8QXP_ENET0_ROOT_DIV] = imx_clk_divider_scu("enet0_root_div", SC_R_ENET_0, SC_PM_CLK_PER);
+ clks[IMX8QXP_ENET0_REF_DIV] = imx_clk_divider3_scu("enet0_ref_div", "enet0_root_clk", SC_R_ENET_0, SC_C_CLKDIV);
+ clks[IMX8QXP_ENET1_REF_DIV] = imx_clk_divider3_scu("enet1_ref_div", "enet1_root_clk", SC_R_ENET_1, SC_C_CLKDIV);
+ clks[IMX8QXP_ENET0_BYPASS_DIV] = imx_clk_divider_scu("enet0_bypass_div", SC_R_ENET_0, SC_PM_CLK_BYPASS);
+ clks[IMX8QXP_ENET0_RGMII_DIV] = imx_clk_divider_scu("enet0_rgmii_div", SC_R_ENET_0, SC_PM_CLK_MISC0);
+ clks[IMX8QXP_ENET1_ROOT_DIV] = imx_clk_divider_scu("enet1_root_div", SC_R_ENET_1, SC_PM_CLK_PER);
+ clks[IMX8QXP_ENET1_BYPASS_DIV] = imx_clk_divider_scu("enet1_bypass_div", SC_R_ENET_1, SC_PM_CLK_BYPASS);
+ clks[IMX8QXP_ENET1_RGMII_DIV] = imx_clk_divider_scu("enet1_rgmii_div", SC_R_ENET_1, SC_PM_CLK_MISC0);
+ clks[IMX8QXP_ENET0_AHB_CLK] = imx_clk_gate2_scu("enet0_ahb_clk", "axi_conn_clk_root", (void __iomem *)(ENET_0_LPCG), 8, FUNCTION_NAME(PD_CONN_ENET_0));
+ clks[IMX8QXP_ENET0_IPG_S_CLK] = imx_clk_gate2_scu("enet0_ipg_s_clk", "ipg_conn_clk_root", (void __iomem *)(ENET_0_LPCG), 20, FUNCTION_NAME(PD_CONN_ENET_0));
+ clks[IMX8QXP_ENET0_IPG_CLK] = imx_clk_gate2_scu("enet0_ipg_clk", "enet0_ipg_s_clk", (void __iomem *)(ENET_0_LPCG), 16, FUNCTION_NAME(PD_CONN_ENET_0));
+ clks[IMX8QXP_ENET1_AHB_CLK] = imx_clk_gate2_scu("enet1_ahb_clk", "axi_conn_clk_root", (void __iomem *)(ENET_1_LPCG), 8, FUNCTION_NAME(PD_CONN_ENET_1));
+ clks[IMX8QXP_ENET1_IPG_S_CLK] = imx_clk_gate2_scu("enet1_ipg_s_clk", "ipg_conn_clk_root", (void __iomem *)(ENET_1_LPCG), 20, FUNCTION_NAME(PD_CONN_ENET_1));
+ clks[IMX8QXP_ENET1_IPG_CLK] = imx_clk_gate2_scu("enet1_ipg_clk", "enet1_ipg_s_clk", (void __iomem *)(ENET_1_LPCG), 16, FUNCTION_NAME(PD_CONN_ENET_1));
+ clks[IMX8QXP_ENET0_ROOT_CLK] = imx_clk_gate_scu("enet0_root_clk", "enet0_root_div", SC_R_ENET_0, SC_PM_CLK_PER, NULL, 0, 0);
+ clks[IMX8QXP_ENET1_ROOT_CLK] = imx_clk_gate_scu("enet1_root_clk", "enet1_root_div", SC_R_ENET_1, SC_PM_CLK_PER, NULL, 0, 0);
+ clks[IMX8QXP_ENET0_TX_CLK] = imx_clk_gate2_scu("enet0_tx_2x_clk", "enet0_root_clk", (void __iomem *)(ENET_0_LPCG), 4, FUNCTION_NAME(PD_CONN_ENET_0));
+ clks[IMX8QXP_ENET1_TX_CLK] = imx_clk_gate2_scu("enet1_tx_2x_clk", "enet1_root_clk", (void __iomem *)(ENET_1_LPCG), 4, FUNCTION_NAME(PD_CONN_ENET_1));
+ clks[IMX8QXP_ENET0_PTP_CLK] = imx_clk_gate2_scu("enet0_ptp_clk", "enet0_root_clk", (void __iomem *)(ENET_0_LPCG), 0, FUNCTION_NAME(PD_CONN_ENET_0));
+ clks[IMX8QXP_ENET1_PTP_CLK] = imx_clk_gate2_scu("enet1_ptp_clk", "enet1_root_clk", (void __iomem *)(ENET_1_LPCG), 0, FUNCTION_NAME(PD_CONN_ENET_1));
+ clks[IMX8QXP_ENET0_REF_25MHZ_125MHZ_SEL] = imx_clk_mux_gpr_scu("enet0_ref_25_125_sel", enet_sels, ARRAY_SIZE(enet_sels), SC_R_ENET_0, SC_C_SEL_125);
+ clks[IMX8QXP_ENET1_REF_25MHZ_125MHZ_SEL] = imx_clk_mux_gpr_scu("enet1_ref_25_125_sel", enet_sels, ARRAY_SIZE(enet_sels), SC_R_ENET_1, SC_C_SEL_125);
+ clks[IMX8QXP_ENET0_RMII_TX_SEL] = imx_clk_mux_gpr_scu("enet0_rmii_tx_sel", enet0_rmii_tx_sels, ARRAY_SIZE(enet0_rmii_tx_sels), SC_R_ENET_0, SC_C_TXCLK);
+ clks[IMX8QXP_ENET1_RMII_TX_SEL] = imx_clk_mux_gpr_scu("enet1_rmii_tx_sel", enet1_rmii_tx_sels, ARRAY_SIZE(enet1_rmii_tx_sels), SC_R_ENET_1, SC_C_TXCLK);
+ clks[IMX8QXP_ENET0_RGMII_TX_CLK] = imx_clk_gate2_scu("enet0_rgmii_tx_clk", "enet0_rmii_tx_sel", (void __iomem *)(ENET_0_LPCG), 12, FUNCTION_NAME(PD_CONN_ENET_0));
+ clks[IMX8QXP_ENET1_RGMII_TX_CLK] = imx_clk_gate2_scu("enet1_rgmii_tx_clk", "enet1_rmii_tx_sel", (void __iomem *)(ENET_1_LPCG), 12, FUNCTION_NAME(PD_CONN_ENET_1));
+ clks[IMX8QXP_ENET0_RMII_RX_CLK] = imx_clk_gate2_scu("enet0_rgmii_rx_clk", "enet0_rgmii_div", (void __iomem *)(ENET_0_LPCG + 0x4), 0, FUNCTION_NAME(PD_CONN_ENET_0));
+ clks[IMX8QXP_ENET1_RMII_RX_CLK] = imx_clk_gate2_scu("enet1_rgmii_rx_clk", "enet1_rgmii_div", (void __iomem *)(ENET_1_LPCG + 0x4), 0, FUNCTION_NAME(PD_CONN_ENET_1));
+ clks[IMX8QXP_ENET0_REF_25MHZ_125MHZ_CLK] = imx_clk_gate3_scu("enet0_ref_25_125_clk", "enet0_ref_25_125_sel", SC_R_ENET_0, SC_C_DISABLE_125, true);
+ clks[IMX8QXP_ENET1_REF_25MHZ_125MHZ_CLK] = imx_clk_gate3_scu("enet1_ref_25_125_clk", "enet1_ref_25_125_sel", SC_R_ENET_1, SC_C_DISABLE_125, true);
+ clks[IMX8QXP_ENET0_REF_50MHZ_CLK] = imx_clk_gate3_scu("enet0_ref_50_clk", NULL, SC_R_ENET_0, SC_C_DISABLE_50, true);
+ clks[IMX8QXP_ENET1_REF_50MHZ_CLK] = imx_clk_gate3_scu("enet1_ref_50_clk", NULL, SC_R_ENET_1, SC_C_DISABLE_50, true);
+ clks[IMX8QXP_GPMI_BCH_IO_DIV] = imx_clk_divider_scu("gpmi_io_div", SC_R_NAND, SC_PM_CLK_MST_BUS);
+ clks[IMX8QXP_GPMI_BCH_DIV] = imx_clk_divider_scu("gpmi_bch_div", SC_R_NAND, SC_PM_CLK_PER);
+ clks[IMX8QXP_GPMI_APB_CLK] = imx_clk_gate2_scu("gpmi_apb_clk", "axi_conn_clk_root", (void __iomem *)(NAND_LPCG), 16, FUNCTION_NAME(PD_CONN_NAND));
+ clks[IMX8QXP_GPMI_APB_BCH_CLK] = imx_clk_gate2_scu("gpmi_apb_bch_clk", "axi_conn_clk_root", (void __iomem *)(NAND_LPCG), 20, FUNCTION_NAME(PD_CONN_NAND));
+ clks[IMX8QXP_GPMI_BCH_IO_CLK] = imx_clk_gate_scu("gpmi_io_clk", "gpmi_io_div", SC_R_NAND, SC_PM_CLK_MST_BUS, (void __iomem *)(NAND_LPCG), 4, 0);
+ clks[IMX8QXP_GPMI_BCH_CLK] = imx_clk_gate_scu("gpmi_bch_clk", "gpmi_bch_div", SC_R_NAND, SC_PM_CLK_PER, (void __iomem *)(NAND_LPCG), 0, 0);
+ clks[IMX8QXP_APBHDMA_CLK] = imx_clk_gate2_scu("gpmi_clk", "axi_conn_clk_root", (void __iomem *)(NAND_LPCG + 0x4), 16, FUNCTION_NAME(PD_CONN_NAND));
+ clks[IMX8QXP_USB3_ACLK_DIV] = imx_clk_divider_scu("usb3_aclk_div", SC_R_USB_2, SC_PM_CLK_PER);
+ clks[IMX8QXP_USB3_BUS_DIV] = imx_clk_divider_scu("usb3_bus_div", SC_R_USB_2, SC_PM_CLK_MST_BUS);
+ clks[IMX8QXP_USB3_LPM_DIV] = imx_clk_divider_scu("usb3_lpm_div", SC_R_USB_2, SC_PM_CLK_MISC);
+ clks[IMX8QXP_USB2_OH_AHB_CLK] = imx_clk_gate2_scu("usboh3", "ahb_conn_clk_root", (void __iomem *)(USB_2_LPCG), 24, FUNCTION_NAME(PD_CONN_USB_0));
+ clks[IMX8QXP_USB2_OH_IPG_S_CLK] = imx_clk_gate2_scu("usboh3_ipg_s", "ipg_conn_clk_root", (void __iomem *)(USB_2_LPCG), 16, FUNCTION_NAME(PD_CONN_USB_0));
+ clks[IMX8QXP_USB2_OH_IPG_S_PL301_CLK] = imx_clk_gate2_scu("usboh3_ipg_pl301_s", "ipg_conn_clk_root", (void __iomem *)(USB_2_LPCG), 20, FUNCTION_NAME(PD_CONN_USB_0));
+ clks[IMX8QXP_USB2_PHY_IPG_CLK] = imx_clk_gate2_scu("usboh3_phy_clk", "ipg_conn_clk_root", (void __iomem *)(USB_2_LPCG), 28, FUNCTION_NAME(PD_CONN_USB_0));
+ clks[IMX8QXP_USB3_IPG_CLK] = imx_clk_gate2_scu("usb3_ipg_clk", "ipg_conn_clk_root", (void __iomem *)(USB_3_LPCG), 16, FUNCTION_NAME(PD_CONN_USB_2));
+ clks[IMX8QXP_USB3_CORE_PCLK] = imx_clk_gate2_scu("usb3_core_clk", "ipg_conn_clk_root", (void __iomem *)(USB_3_LPCG), 20, FUNCTION_NAME(PD_CONN_USB_2));
+ clks[IMX8QXP_USB3_PHY_CLK] = imx_clk_gate2_scu("usb3_phy_clk", "usb3_ipg_clk", (void __iomem *)(USB_3_LPCG), 24, FUNCTION_NAME(PD_CONN_USB_2_PHY));
+ clks[IMX8QXP_USB3_ACLK] = imx_clk_gate_scu("usb3_aclk", "usb3_aclk_div", SC_R_USB_2, SC_PM_CLK_PER, (void __iomem *)(USB_3_LPCG), 28, 0);
+ clks[IMX8QXP_USB3_BUS_CLK] = imx_clk_gate_scu("usb3_bus_clk", "usb3_bus_div", SC_R_USB_2, SC_PM_CLK_MST_BUS, (void __iomem *)(USB_3_LPCG), 0, 0);
+ clks[IMX8QXP_USB3_LPM_CLK] = imx_clk_gate_scu("usb3_lpm_clk", "usb3_lpm_div", SC_R_USB_2, SC_PM_CLK_MISC, (void __iomem *)(USB_3_LPCG), 4, 0);
+ clks[IMX8QXP_EDMA_CLK] = imx_clk_gate2_scu("edma_clk", "axi_conn_clk_root", (void __iomem *)(EDMA_LPCG), 0, FUNCTION_NAME(PD_CONN_DMA_4_CH0));
+ clks[IMX8QXP_EDMA_IPG_CLK] = imx_clk_gate2_scu("edma_ipg_clk", "ipg_conn_clk_root", (void __iomem *)(EDMA_LPCG), 16, FUNCTION_NAME(PD_CONN_DMA_4_CH0));
+ clks[IMX8QXP_MLB_HCLK] = imx_clk_gate2_scu("mlb_hclk", "axi_conn_clk_root", (void __iomem *)(MLB_LPCG), 20, FUNCTION_NAME(PD_CONN_MLB_0));
+ clks[IMX8QXP_MLB_CLK] = imx_clk_gate2_scu("mlb_clk", "mlb_hclk", (void __iomem *)(MLB_LPCG), 0, FUNCTION_NAME(PD_CONN_MLB_0));
+ clks[IMX8QXP_MLB_IPG_CLK] = imx_clk_gate2_scu("mlb_ipg_clk", "ipg_conn_clk_root", (void __iomem *)(MLB_LPCG), 16, FUNCTION_NAME(PD_CONN_MLB_0));
+
+ /* Display controller - DC0 SS */
+ clks[IMX8QXP_DC0_PLL0_DIV] = imx_clk_divider_scu("dc0_pll0_div", SC_R_DC_0_PLL_0, SC_PM_CLK_PLL);
+ clks[IMX8QXP_DC0_PLL1_DIV] = imx_clk_divider_scu("dc0_pll1_div", SC_R_DC_0_PLL_1, SC_PM_CLK_PLL);
+ clks[IMX8QXP_DC0_PLL0_CLK] = imx_clk_gate_scu("dc0_pll0_clk", "dc0_pll0_div", SC_R_DC_0_PLL_0, SC_PM_CLK_PLL, NULL, 0, 0);
+ clks[IMX8QXP_DC0_PLL1_CLK] = imx_clk_gate_scu("dc0_pll1_clk", "dc0_pll1_div", SC_R_DC_0_PLL_1, SC_PM_CLK_PLL, NULL, 0, 0);
+ clks[IMX8QXP_DC0_DISP0_DIV] = imx_clk_divider_scu("dc0_disp0_div", SC_R_DC_0, SC_PM_CLK_MISC0);
+ clks[IMX8QXP_DC0_DISP1_DIV] = imx_clk_divider_scu("dc0_disp1_div", SC_R_DC_0, SC_PM_CLK_MISC1);
+ clks[IMX8QXP_DC0_DISP0_CLK] = imx_clk_gate_scu("dc0_disp0_clk", "dc0_disp0_div", SC_R_DC_0, SC_PM_CLK_MISC0, (void __iomem *)(DC_0_LPCG), 0, 0);
+ clks[IMX8QXP_DC0_DISP1_CLK] = imx_clk_gate_scu("dc0_disp1_clk", "dc0_disp1_div", SC_R_DC_0, SC_PM_CLK_MISC1, (void __iomem *)(DC_0_LPCG), 4, 0);
+ clks[IMX8QXP_DC0_BYPASS_0_DIV] = imx_clk_divider_scu("dc0_bypass0_div", SC_R_DC_0_VIDEO0, SC_PM_CLK_BYPASS);
+ clks[IMX8QXP_DC0_BYPASS_1_DIV] = imx_clk_divider_scu("dc0_bypass1_div", SC_R_DC_0_VIDEO1, SC_PM_CLK_BYPASS);
+ clks[IMX8QXP_DC0_PRG0_RTRAM_CLK] = imx_clk_gate2_scu("dc0_prg0_rtram_clk", "axi_int_dc_clk_root", (void __iomem *)(DC_0_LPCG + 0x20), 0, FUNCTION_NAME(PD_DC_0));
+ clks[IMX8QXP_DC0_PRG0_APB_CLK] = imx_clk_gate2_scu("dc0_prg0_apb_clk", "cfg_dc_clk_root", (void __iomem *)(DC_0_LPCG + 0x20), 16, FUNCTION_NAME(PD_DC_0));
+ clks[IMX8QXP_DC0_PRG1_RTRAM_CLK] = imx_clk_gate2_scu("dc0_prg1_rtram_clk", "axi_int_dc_clk_root", (void __iomem *)(DC_0_LPCG + 0x24), 0, FUNCTION_NAME(PD_DC_0));
+ clks[IMX8QXP_DC0_PRG1_APB_CLK] = imx_clk_gate2_scu("dc0_prg1_apb_clk", "cfg_dc_clk_root", (void __iomem *)(DC_0_LPCG + 0x24), 16, FUNCTION_NAME(PD_DC_0));
+ clks[IMX8QXP_DC0_PRG2_RTRAM_CLK] = imx_clk_gate2_scu("dc0_prg2_rtram_clk", "axi_int_dc_clk_root", (void __iomem *)(DC_0_LPCG + 0x28), 0, FUNCTION_NAME(PD_DC_0));
+ clks[IMX8QXP_DC0_PRG2_APB_CLK] = imx_clk_gate2_scu("dc0_prg2_apb_clk", "cfg_dc_clk_root", (void __iomem *)(DC_0_LPCG + 0x28), 16, FUNCTION_NAME(PD_DC_0));
+ clks[IMX8QXP_DC0_PRG3_RTRAM_CLK] = imx_clk_gate2_scu("dc0_prg3_rtram_clk", "axi_int_dc_clk_root", (void __iomem *)(DC_0_LPCG + 0x34), 0, FUNCTION_NAME(PD_DC_0));
+ clks[IMX8QXP_DC0_PRG3_APB_CLK] = imx_clk_gate2_scu("dc0_prg3_apb_clk", "cfg_dc_clk_root", (void __iomem *)(DC_0_LPCG + 0x34), 16, FUNCTION_NAME(PD_DC_0));
+ clks[IMX8QXP_DC0_PRG4_RTRAM_CLK] = imx_clk_gate2_scu("dc0_prg4_rtram_clk", "axi_int_dc_clk_root", (void __iomem *)(DC_0_LPCG + 0x38), 0, FUNCTION_NAME(PD_DC_0));
+ clks[IMX8QXP_DC0_PRG4_APB_CLK] = imx_clk_gate2_scu("dc0_prg4_apb_clk", "cfg_dc_clk_root", (void __iomem *)(DC_0_LPCG + 0x38), 16, FUNCTION_NAME(PD_DC_0));
+ clks[IMX8QXP_DC0_PRG5_RTRAM_CLK] = imx_clk_gate2_scu("dc0_prg5_rtram_clk", "axi_int_dc_clk_root", (void __iomem *)(DC_0_LPCG + 0x3c), 0, FUNCTION_NAME(PD_DC_0));
+ clks[IMX8QXP_DC0_PRG5_APB_CLK] = imx_clk_gate2_scu("dc0_prg5_apb_clk", "cfg_dc_clk_root", (void __iomem *)(DC_0_LPCG + 0x3c), 16, FUNCTION_NAME(PD_DC_0));
+ clks[IMX8QXP_DC0_PRG6_RTRAM_CLK] = imx_clk_gate2_scu("dc0_prg6_rtram_clk", "axi_int_dc_clk_root", (void __iomem *)(DC_0_LPCG + 0x40), 0, FUNCTION_NAME(PD_DC_0));
+ clks[IMX8QXP_DC0_PRG6_APB_CLK] = imx_clk_gate2_scu("dc0_prg6_apb_clk", "cfg_dc_clk_root", (void __iomem *)(DC_0_LPCG + 0x40), 16, FUNCTION_NAME(PD_DC_0));
+ clks[IMX8QXP_DC0_PRG7_RTRAM_CLK] = imx_clk_gate2_scu("dc0_prg7_rtram_clk", "axi_int_dc_clk_root", (void __iomem *)(DC_0_LPCG + 0x44), 0, FUNCTION_NAME(PD_DC_0));
+ clks[IMX8QXP_DC0_PRG7_APB_CLK] = imx_clk_gate2_scu("dc0_prg7_apb_clk", "cfg_dc_clk_root", (void __iomem *)(DC_0_LPCG + 0x44), 16, FUNCTION_NAME(PD_DC_0));
+ clks[IMX8QXP_DC0_PRG8_RTRAM_CLK] = imx_clk_gate2_scu("dc0_prg8_rtram_clk", "axi_int_dc_clk_root", (void __iomem *)(DC_0_LPCG + 0x48), 0, FUNCTION_NAME(PD_DC_0));
+ clks[IMX8QXP_DC0_PRG8_APB_CLK] = imx_clk_gate2_scu("dc0_prg8_apb_clk", "cfg_dc_clk_root", (void __iomem *)(DC_0_LPCG + 0x48), 16, FUNCTION_NAME(PD_DC_0));
+ clks[IMX8QXP_DC0_DPR0_APB_CLK] = imx_clk_gate2_scu("dc0_dpr0_apb_clk", "cfg_dc_clk_root", (void __iomem *)(DC_0_LPCG + 0x18), 16, FUNCTION_NAME(PD_DC_0));
+ clks[IMX8QXP_DC0_DPR0_B_CLK] = imx_clk_gate2_scu("dc0_dpr0_b_clk", "axi_ext_dc_clk_root", (void __iomem *)(DC_0_LPCG + 0x18), 20, FUNCTION_NAME(PD_DC_0));
+ clks[IMX8QXP_DC0_RTRAM0_CLK] = imx_clk_gate2_scu("dc0_rtrm0_clk", "axi_int_dc_clk_root", (void __iomem *)(DC_0_LPCG + 0x1C), 0, FUNCTION_NAME(PD_DC_0));
+ clks[IMX8QXP_DC0_DPR1_APB_CLK] = imx_clk_gate2_scu("dc0_dpr1_apb_clk", "cfg_dc_clk_root", (void __iomem *)(DC_0_LPCG + 0x2C), 16, FUNCTION_NAME(PD_DC_0));
+ clks[IMX8QXP_DC0_DPR1_B_CLK] = imx_clk_gate2_scu("dc0_dpr1_b_clk", "axi_ext_dc_clk_root", (void __iomem *)(DC_0_LPCG + 0x2C), 20, FUNCTION_NAME(PD_DC_0));
+ clks[IMX8QXP_DC0_RTRAM1_CLK] = imx_clk_gate2_scu("dc0_rtrm1_clk", "axi_int_dc_clk_root", (void __iomem *)(DC_0_LPCG + 0x30), 0, FUNCTION_NAME(PD_DC_0));
+
+ /* Display interface - MIPI-LVDS SS */
+ clks[IMX8QXP_MIPI0_BYPASS_CLK] = imx_clk_divider_scu("mipi0_bypass_clk", SC_R_MIPI_0, SC_PM_CLK_BYPASS);
+ clks[IMX8QXP_MIPI0_PIXEL_DIV] = imx_clk_divider_scu("mipi0_pixel_div", SC_R_MIPI_0, SC_PM_CLK_PER);
+ clks[IMX8QXP_MIPI0_PIXEL_CLK] = imx_clk_gate_scu("mipi0_pixel_clk", "mipi0_pixel_div", SC_R_MIPI_0, SC_PM_CLK_PER, NULL, 0, 0);
+ clks[IMX8QXP_MIPI0_LVDS_PIXEL_DIV] = imx_clk_divider_scu("mipi0_lvds_pixel_div", SC_R_LVDS_0, SC_PM_CLK_MISC2);
+ clks[IMX8QXP_MIPI0_LVDS_PIXEL_CLK] = imx_clk_gate_scu("mipi0_lvds_pixel_clk", "mipi0_lvds_pixel_div", SC_R_LVDS_0, SC_PM_CLK_MISC2, NULL, 0, 0);
+ clks[IMX8QXP_MIPI0_LVDS_BYPASS_CLK] = imx_clk_divider_scu("mipi0_lvds_bypass_clk", SC_R_LVDS_0, SC_PM_CLK_BYPASS);
+ clks[IMX8QXP_MIPI0_LVDS_PHY_DIV] = imx_clk_divider_scu("mipi0_lvds_phy_div", SC_R_LVDS_0, SC_PM_CLK_MISC3);
+ clks[IMX8QXP_MIPI0_LVDS_PHY_CLK] = imx_clk_gate_scu("mipi0_lvds_phy_clk", "mipi0_lvds_phy_div", SC_R_LVDS_0, SC_PM_CLK_MISC3, NULL, 0, 0);
+ clks[IMX8QXP_MIPI0_DSI_TX_ESC_SEL] = imx_clk_mux2_scu("mipi0_dsi_tx_esc_sel", mipi0_sels, ARRAY_SIZE(mipi0_sels), SC_R_MIPI_0, SC_PM_CLK_MST_BUS);
+ clks[IMX8QXP_MIPI0_DSI_TX_ESC_DIV] = imx_clk_divider2_scu("mipi0_dsi_tx_esc_div", "mipi0_dsi_tx_esc_sel", SC_R_MIPI_0, SC_PM_CLK_MST_BUS);
+ clks[IMX8QXP_MIPI0_DSI_TX_ESC_CLK] = imx_clk_gate_scu("mipi0_dsi_tx_esc_clk", "mipi0_dsi_tx_esc_div", SC_R_MIPI_0, SC_PM_CLK_MST_BUS, NULL, 0, 0);
+ clks[IMX8QXP_MIPI0_DSI_RX_ESC_SEL] = imx_clk_mux2_scu("mipi0_dsi_rx_esc_sel", mipi0_sels, ARRAY_SIZE(mipi0_sels), SC_R_MIPI_0, SC_PM_CLK_SLV_BUS);
+ clks[IMX8QXP_MIPI0_DSI_RX_ESC_DIV] = imx_clk_divider2_scu("mipi0_dsi_rx_esc_div", "mipi0_dsi_rx_esc_sel", SC_R_MIPI_0, SC_PM_CLK_SLV_BUS);
+ clks[IMX8QXP_MIPI0_DSI_RX_ESC_CLK] = imx_clk_gate_scu("mipi0_dsi_rx_esc_clk", "mipi0_dsi_rx_esc_div", SC_R_MIPI_0, SC_PM_CLK_SLV_BUS, NULL, 0, 0);
+ clks[IMX8QXP_MIPI0_DSI_PHY_SEL] = imx_clk_mux2_scu("mipi0_dsi_phy_sel", mipi0_sels, ARRAY_SIZE(mipi0_sels), SC_R_MIPI_0, SC_PM_CLK_PHY);
+ clks[IMX8QXP_MIPI0_DSI_PHY_DIV] = imx_clk_divider2_scu("mipi0_dsi_phy_div", "mipi0_dsi_phy_sel", SC_R_MIPI_0, SC_PM_CLK_PHY);
+ clks[IMX8QXP_MIPI0_DSI_PHY_CLK] = imx_clk_gate_scu("mipi0_dsi_phy_clk", "mipi0_dsi_phy_div", SC_R_MIPI_0, SC_PM_CLK_PHY, NULL, 0, 0);
+ clks[IMX8QXP_MIPI0_I2C0_DIV] = imx_clk_divider_scu("mipi0_i2c0_div", SC_R_MIPI_0_I2C_0, SC_PM_CLK_MISC2);
+ clks[IMX8QXP_MIPI0_I2C1_DIV] = imx_clk_divider_scu("mipi0_i2c1_div", SC_R_MIPI_0_I2C_1, SC_PM_CLK_MISC2);
+ clks[IMX8QXP_MIPI0_I2C0_CLK] = imx_clk_gate_scu("mipi0_i2c0_clk", "mipi0_i2c0_div", SC_R_MIPI_0_I2C_0, SC_PM_CLK_MISC2, (void __iomem *)(DI_MIPI0_LPCG + 0x10), 0, 0);
+ clks[IMX8QXP_MIPI0_I2C1_CLK] = imx_clk_gate_scu("mipi0_i2c1_clk", "mipi0_i2c1_div", SC_R_MIPI_0_I2C_1, SC_PM_CLK_MISC2, (void __iomem *)(DI_MIPI0_LPCG + 0x14), 0, 0);
+ clks[IMX8QXP_MIPI0_I2C0_IPG_CLK] = imx_clk_gate2_scu("mipi0_i2c0_ipg_clk", "ipg_mipi_clk_root", (void __iomem *)(DI_MIPI0_LPCG + 0x10), 16, FUNCTION_NAME(PD_MIPI_0_DSI_I2C0));
+ clks[IMX8QXP_MIPI0_I2C1_IPG_CLK] = imx_clk_gate2_scu("mipi0_i2c1_ipg_clk", "ipg_mipi_clk_root", (void __iomem *)(DI_MIPI0_LPCG + 0x14), 16, FUNCTION_NAME(PD_MIPI_0_DSI_I2C1));
+ clks[IMX8QXP_MIPI0_PWM_IPG_CLK] = imx_clk_gate2_scu("mipi0_pwm_ipg_clk", "ipg_mipi_clk_root", (void __iomem *)(DI_MIPI0_LPCG + 0xC), 16, FUNCTION_NAME(PD_MIPI_0_DSI_PWM0));
+ clks[IMX8QXP_MIPI0_PWM_32K_CLK] = imx_clk_gate2_scu("mipi0_pwm_32K_clk", "xtal_32KHz", (void __iomem *)(DI_MIPI0_LPCG + 0xC), 4, FUNCTION_NAME(PD_MIPI_0_DSI_PWM0));
+ clks[IMX8QXP_MIPI0_PWM_DIV] = imx_clk_divider_scu("mipi0_pwm_div", SC_R_MIPI_0_PWM_0, SC_PM_CLK_PER);
+ clks[IMX8QXP_MIPI0_PWM_CLK] = imx_clk_gate_scu("mipi0_pwm_clk", "mipi0_pwm_div", SC_R_MIPI_0_PWM_0, SC_PM_CLK_PER, (void __iomem *)(DI_MIPI0_LPCG + 0xC), 0, 0);
+ clks[IMX8QXP_MIPI0_GPIO_IPG_CLK] = imx_clk_gate2_scu("mipi0_gpio_ipg_clk", "ipg_mipi_clk_root", (void __iomem *)(DI_MIPI0_LPCG + 0x8), 16, FUNCTION_NAME(PD_MIPI_0_GPIO_0));
+ clks[IMX8QXP_MIPI0_LIS_IPG_CLK] = imx_clk_gate2_scu("mipi0_lis_ipg_clk", "ipg_mipi_clk_root", (void __iomem *)(DI_MIPI0_LPCG + 0x0), 16, FUNCTION_NAME(PD_MIPI_0_DSI));
+ clks[IMX8QXP_MIPI1_BYPASS_CLK] = imx_clk_divider_scu("mipi1_bypass_clk", SC_R_MIPI_1, SC_PM_CLK_BYPASS);
+ clks[IMX8QXP_MIPI1_PIXEL_DIV] = imx_clk_divider_scu("mipi1_pixel_div", SC_R_MIPI_1, SC_PM_CLK_PER);
+ clks[IMX8QXP_MIPI1_PIXEL_CLK] = imx_clk_gate_scu("mipi1_pixel_clk", "mipi1_pixel_div", SC_R_MIPI_1, SC_PM_CLK_PER, NULL, 0, 0);
+ clks[IMX8QXP_MIPI1_LVDS_PIXEL_DIV] = imx_clk_divider_scu("mipi1_lvds_pixel_div", SC_R_LVDS_1, SC_PM_CLK_MISC2);
+ clks[IMX8QXP_MIPI1_LVDS_PIXEL_CLK] = imx_clk_gate_scu("mipi1_lvds_pixel_clk", "mipi1_lvds_pixel_div", SC_R_LVDS_1, SC_PM_CLK_MISC2, NULL, 0, 0);
+ clks[IMX8QXP_MIPI1_LVDS_BYPASS_CLK] = imx_clk_divider_scu("mipi1_lvds_bypass_clk", SC_R_LVDS_1, SC_PM_CLK_BYPASS);
+ clks[IMX8QXP_MIPI1_LVDS_PHY_DIV] = imx_clk_divider_scu("mipi1_lvds_phy_div", SC_R_LVDS_1, SC_PM_CLK_MISC3);
+ clks[IMX8QXP_MIPI1_LVDS_PHY_CLK] = imx_clk_gate_scu("mipi1_lvds_phy_clk", "mipi1_lvds_phy_div", SC_R_LVDS_1, SC_PM_CLK_MISC3, NULL, 0, 0);
+ clks[IMX8QXP_MIPI1_DSI_TX_ESC_SEL] = imx_clk_mux2_scu("mipi1_dsi_tx_esc_sel", mipi1_sels, ARRAY_SIZE(mipi1_sels), SC_R_MIPI_1, SC_PM_CLK_MST_BUS);
+ clks[IMX8QXP_MIPI1_DSI_TX_ESC_DIV] = imx_clk_divider2_scu("mipi1_dsi_tx_esc_div", "mipi1_dsi_tx_esc_sel", SC_R_MIPI_1, SC_PM_CLK_MST_BUS);
+ clks[IMX8QXP_MIPI1_DSI_TX_ESC_CLK] = imx_clk_gate_scu("mipi1_dsi_tx_esc_clk", "mipi1_dsi_tx_esc_div", SC_R_MIPI_1, SC_PM_CLK_MST_BUS, NULL, 0, 0);
+ clks[IMX8QXP_MIPI1_DSI_RX_ESC_SEL] = imx_clk_mux2_scu("mipi1_dsi_rx_esc_sel", mipi1_sels, ARRAY_SIZE(mipi1_sels), SC_R_MIPI_1, SC_PM_CLK_SLV_BUS);
+ clks[IMX8QXP_MIPI1_DSI_RX_ESC_DIV] = imx_clk_divider2_scu("mipi1_dsi_rx_esc_div", "mipi1_dsi_rx_esc_sel", SC_R_MIPI_1, SC_PM_CLK_SLV_BUS);
+ clks[IMX8QXP_MIPI1_DSI_RX_ESC_CLK] = imx_clk_gate_scu("mipi1_dsi_rx_esc_clk", "mipi1_dsi_rx_esc_div", SC_R_MIPI_1, SC_PM_CLK_SLV_BUS, NULL, 0, 0);
+ clks[IMX8QXP_MIPI1_DSI_PHY_SEL] = imx_clk_mux2_scu("mipi1_dsi_phy_sel", mipi1_sels, ARRAY_SIZE(mipi1_sels), SC_R_MIPI_1, SC_PM_CLK_PHY);
+ clks[IMX8QXP_MIPI1_DSI_PHY_DIV] = imx_clk_divider2_scu("mipi1_dsi_phy_div", "mipi1_dsi_phy_sel", SC_R_MIPI_1, SC_PM_CLK_PHY);
+ clks[IMX8QXP_MIPI1_DSI_PHY_CLK] = imx_clk_gate_scu("mipi1_dsi_phy_clk", "mipi1_dsi_phy_div", SC_R_MIPI_1, SC_PM_CLK_PHY, NULL, 0, 0);
+
+ clks[IMX8QXP_MIPI1_I2C0_DIV] = imx_clk_divider_scu("mipi1_i2c0_div", SC_R_MIPI_1_I2C_0, SC_PM_CLK_MISC2);
+ clks[IMX8QXP_MIPI1_I2C1_DIV] = imx_clk_divider_scu("mipi1_i2c1_div", SC_R_MIPI_1_I2C_1, SC_PM_CLK_MISC2);
+ clks[IMX8QXP_MIPI1_I2C0_CLK] = imx_clk_gate_scu("mipi1_i2c0_clk", "mipi1_i2c0_div", SC_R_MIPI_1_I2C_0, SC_PM_CLK_MISC2, (void __iomem *)(DI_MIPI1_LPCG + 0x10), 0, 0);
+ clks[IMX8QXP_MIPI1_I2C1_CLK] = imx_clk_gate_scu("mipi1_i2c1_clk", "mipi1_i2c1_div", SC_R_MIPI_1_I2C_1, SC_PM_CLK_MISC2, (void __iomem *)(DI_MIPI1_LPCG + 0x14), 0, 0);
+ clks[IMX8QXP_MIPI1_I2C0_IPG_CLK] = imx_clk_gate2_scu("mipi1_i2c0_ipg_clk", "ipg_mipi_clk_root", (void __iomem *)(DI_MIPI1_LPCG + 0x10), 16, FUNCTION_NAME(PD_MIPI_1_DSI_I2C0));
+ clks[IMX8QXP_MIPI1_I2C1_IPG_CLK] = imx_clk_gate2_scu("mipi1_i2c1_ipg_clk", "ipg_mipi_clk_root", (void __iomem *)(DI_MIPI1_LPCG + 0x14), 16, FUNCTION_NAME(PD_MIPI_1_DSI_I2C1));
+ clks[IMX8QXP_MIPI1_PWM_IPG_CLK] = imx_clk_gate2_scu("mipi1_pwm_ipg_clk", "ipg_mipi_clk_root", (void __iomem *)(DI_MIPI1_LPCG + 0xC), 16, FUNCTION_NAME(PD_MIPI_1_DSI_PWM0));
+ clks[IMX8QXP_MIPI1_PWM_32K_CLK] = imx_clk_gate2_scu("mipi1_pwm_32K_clk", "xtal_32KHz", (void __iomem *)(DI_MIPI1_LPCG + 0xC), 4, FUNCTION_NAME(PD_MIPI_1_DSI_PWM0));
+ clks[IMX8QXP_MIPI1_PWM_DIV] = imx_clk_divider_scu("mipi1_pwm_div", SC_R_MIPI_1_PWM_0, SC_PM_CLK_PER);
+ clks[IMX8QXP_MIPI1_PWM_CLK] = imx_clk_gate_scu("mipi1_pwm_clk", "mipi1_pwm_div", SC_R_MIPI_1_PWM_0, SC_PM_CLK_PER, (void __iomem *)(DI_MIPI1_LPCG + 0xC), 0, 0);
+ clks[IMX8QXP_MIPI1_GPIO_IPG_CLK] = imx_clk_gate2_scu("mipi1_gpio_ipg_clk", "ipg_mipi_clk_root", (void __iomem *)(DI_MIPI1_LPCG + 0x8), 16, FUNCTION_NAME(PD_MIPI_1_GPIO_0));
+ clks[IMX8QXP_MIPI1_LIS_IPG_CLK] = imx_clk_gate2_scu("mipi1_lis_ipg_clk", "ipg_mipi_clk_root", (void __iomem *)(DI_MIPI1_LPCG + 0x0), 16, FUNCTION_NAME(PD_MIPI_1_DSI));
+
+ /* Imaging SS */
+ clks[IMX8QXP_IMG_JPEG_ENC_IPG_CLK] = imx_clk_gate2_scu("img_jpeg_enc_ipg_clk", "ipg_img_clk_root", (void __iomem *)(IMG_JPEG_ENC_LPCG), 16, FUNCTION_NAME(PD_IMAGING_JPEG_ENC));
+ clks[IMX8QXP_IMG_JPEG_ENC_CLK] = imx_clk_gate2_scu("img_jpeg_enc_clk", "img_jpeg_enc_ipg_clk", (void __iomem *)(IMG_JPEG_ENC_LPCG), 0, FUNCTION_NAME(PD_IMAGING_JPEG_ENC));
+ clks[IMX8QXP_IMG_JPEG_DEC_IPG_CLK] = imx_clk_gate2_scu("img_jpeg_dec_ipg_clk", "ipg_img_clk_root", (void __iomem *)(IMG_JPEG_DEC_LPCG), 16, FUNCTION_NAME(PD_IMAGING_JPEG_DEC));
+ clks[IMX8QXP_IMG_JPEG_DEC_CLK] = imx_clk_gate2_scu("img_jpeg_dec_clk", "img_jpeg_dec_ipg_clk", (void __iomem *)(IMG_JPEG_DEC_LPCG), 0, FUNCTION_NAME(PD_IMAGING_JPEG_DEC));
+ clks[IMX8QXP_IMG_PXL_LINK_DC0_CLK] = imx_clk_gate2_scu("img_pxl_link_dc0_clk", "pxl_img_clk_root", (void __iomem *)(IMG_PXL_LINK_DC0_LPCG), 0, FUNCTION_NAME(PD_IMAGING));
+ clks[IMX8QXP_IMG_PXL_LINK_DC1_CLK] = imx_clk_gate2_scu("img_pxl_link_dc1_clk", "pxl_img_clk_root", (void __iomem *)(IMG_PXL_LINK_DC1_LPCG), 0, FUNCTION_NAME(PD_IMAGING));
+ clks[IMX8QXP_IMG_PXL_LINK_CSI0_CLK] = imx_clk_gate2_scu("img_pxl_link_csi0_clk", "pxl_img_clk_root", (void __iomem *)(IMG_PXL_LINK_CSI0_LPCG), 0, FUNCTION_NAME(PD_IMAGING));
+ clks[IMX8QXP_IMG_PXL_LINK_CSI1_CLK] = imx_clk_gate2_scu("img_pxl_link_csi1_clk", "pxl_img_clk_root", (void __iomem *)(IMG_PXL_LINK_CSI1_LPCG), 0, FUNCTION_NAME(PD_IMAGING));
+ clks[IMX8QXP_IMG_PXL_LINK_HDMI_IN_CLK] = imx_clk_gate2_scu("img_pxl_link_hdmi_in_clk", "pxl_img_clk_root", (void __iomem *)(IMG_PXL_LINK_HDMI_LPCG), 0, FUNCTION_NAME(PD_HDMI_RX));
+ clks[IMX8QXP_IMG_PDMA_0_CLK] = imx_clk_gate2_scu("img_pdma0_clk", "pxl_img_clk_root", (void __iomem *)(IMG_PDMA_0_LPCG), 0, FUNCTION_NAME(PD_IMAGING_PDMA0));
+ clks[IMX8QXP_IMG_PDMA_1_CLK] = imx_clk_gate2_scu("img_pdma1_clk", "pxl_img_clk_root", (void __iomem *)(IMG_PDMA_1_LPCG), 0, FUNCTION_NAME(PD_IMAGING_PDMA1));
+ clks[IMX8QXP_IMG_PDMA_2_CLK] = imx_clk_gate2_scu("img_pdma2_clk", "pxl_img_clk_root", (void __iomem *)(IMG_PDMA_2_LPCG), 0, FUNCTION_NAME(PD_IMAGING_PDMA2));
+ clks[IMX8QXP_IMG_PDMA_3_CLK] = imx_clk_gate2_scu("img_pdma3_clk", "pxl_img_clk_root", (void __iomem *)(IMG_PDMA_3_LPCG), 0, FUNCTION_NAME(PD_IMAGING_PDMA3));
+ clks[IMX8QXP_IMG_PDMA_4_CLK] = imx_clk_gate2_scu("img_pdma4_clk", "pxl_img_clk_root", (void __iomem *)(IMG_PDMA_4_LPCG), 0, FUNCTION_NAME(PD_IMAGING_PDMA4));
+ clks[IMX8QXP_IMG_PDMA_5_CLK] = imx_clk_gate2_scu("img_pdma5_clk", "pxl_img_clk_root", (void __iomem *)(IMG_PDMA_5_LPCG), 0, FUNCTION_NAME(PD_IMAGING_PDMA5));
+ clks[IMX8QXP_IMG_PDMA_6_CLK] = imx_clk_gate2_scu("img_pdma6_clk", "pxl_img_clk_root", (void __iomem *)(IMG_PDMA_6_LPCG), 0, FUNCTION_NAME(PD_IMAGING_PDMA6));
+ clks[IMX8QXP_IMG_PDMA_7_CLK] = imx_clk_gate2_scu("img_pdma7_clk", "pxl_img_clk_root", (void __iomem *)(IMG_PDMA_7_LPCG), 0, FUNCTION_NAME(PD_IMAGING_PDMA7));
+
+ /* MIPI CSI SS */
+ clks[IMX8QXP_CSI0_I2C0_DIV] = imx_clk_divider_scu("mipi_csi0_i2c0_div", SC_R_CSI_0_I2C_0, SC_PM_CLK_PER);
+ clks[IMX8QXP_CSI0_PWM0_DIV] = imx_clk_divider_scu("mipi_csi0_pwm0_div", SC_R_CSI_0_PWM_0, SC_PM_CLK_PER);
+ clks[IMX8QXP_CSI0_CORE_DIV] = imx_clk_divider_scu("mipi_csi0_core_div", SC_R_CSI_0, SC_PM_CLK_PER);
+ clks[IMX8QXP_CSI0_ESC_DIV] = imx_clk_divider_scu("mipi_csi0_esc_div", SC_R_CSI_0, SC_PM_CLK_MISC);
+ clks[IMX8QXP_CSI0_I2C0_IPG_CLK] = imx_clk_gate2_scu("mipi_csi0_i2c0_ipg_s", "ipg_mipi_csi_clk_root", (void __iomem *)(MIPI_CSI_0_LPCG + 0x14), 16, FUNCTION_NAME(PD_MIPI_CSI0_I2C0));
+ clks[IMX8QXP_CSI0_I2C0_CLK] = imx_clk_gate_scu("mipi_csi0_i2c0_clk", "mipi_csi0_i2c0_div", SC_R_CSI_0_I2C_0, SC_PM_CLK_PER, (void __iomem *)(MIPI_CSI_0_LPCG + 0x14), 0, 0);
+ clks[IMX8QXP_CSI0_PWM0_IPG_CLK] = imx_clk_gate2_scu("mipi_csi0_pwm0_ipg_s", "ipg_mipi_csi_clk_root", (void __iomem *)(MIPI_CSI_0_LPCG + 0x10), 16, FUNCTION_NAME(PD_MIPI_CSI0_PWM));
+ clks[IMX8QXP_CSI0_PWM0_CLK] = imx_clk_gate_scu("mipi_csi0_pwm0_clk", "mipi_csi0_pwm0_div", SC_R_CSI_0_PWM_0, SC_PM_CLK_PER, (void __iomem *)(MIPI_CSI_0_LPCG + 0x10), 0, 0);
+ clks[IMX8QXP_CSI0_CORE_CLK] = imx_clk_gate_scu("mipi_csi0_core_clk", "mipi_csi0_core_div", SC_R_CSI_0, SC_PM_CLK_PER, (void __iomem *)(MIPI_CSI_0_LPCG + 0x18), 16, 0);
+ clks[IMX8QXP_CSI0_ESC_CLK] = imx_clk_gate_scu("mipi_csi0_esc_clk", "mipi_csi0_esc_div", SC_R_CSI_0, SC_PM_CLK_MISC, (void __iomem *)(MIPI_CSI_0_LPCG + 0x1C), 16, 0);
+
+ /* Parallel CSI */
+ clks[IMX8QXP_PARALLEL_CSI_CLK_DPLL] = imx_clk_divider_scu("parallel_pll_clk", SC_R_PI_0_PLL, SC_PM_CLK_PLL);
+ clks[IMX8QXP_PARALLEL_CSI_CLK_SEL] = imx_clk_mux2_scu("pll0_sel", pll0_sels, ARRAY_SIZE(pll0_sels), SC_R_PI_0, SC_PM_CLK_PER);
+ clks[IMX8QXP_PARALLEL_CSI_PER_CLK_DIV] = imx_clk_divider2_scu("parallel_per_clk", "pll0_sel", SC_R_PI_0, SC_PM_CLK_PER);
+ clks[IMX8QXP_PARALLEL_CSI_MCLK_DIV] = imx_clk_divider_scu("parallel_csi_mclk_div", SC_R_PI_0, SC_PM_CLK_MISC0);
+ clks[IMX8QXP_PARALLEL_CSI_PIXEL_CLK] = imx_clk_gate_scu("parallel_pixel_clk", "parallel_per_clk", SC_R_PI_0, SC_PM_CLK_PER, (void __iomem *)(PARALLEL_CSI_LPCG + 0x18), 0, 0);
+ clks[IMX8QXP_PARALLEL_CSI_IPG_CLK] = imx_clk_gate_scu("parallel_ipg_clk", "parallel_per_clk", SC_R_PI_0, SC_PM_CLK_PER, (void __iomem *)(PARALLEL_CSI_LPCG + 0x4), 16, 0);
+ clks[IMX8QXP_PARALLEL_CSI_MISC0_CLK] = imx_clk_gate_scu("parallel_csi_mclk", "parallel_csi_mclk_div", SC_R_PI_0, SC_PM_CLK_MISC0, (void __iomem *)(PARALLEL_CSI_LPCG + 0x1C), 0, 0);
+
+
+ /* HSIO SS */
+ clks[IMX8QXP_HSIO_PCIE_MSTR_AXI_CLK] = imx_clk_gate2_scu("hsio_pcie_mstr_axi_clk", "axi_hsio_clk_root", (void __iomem *)(HSIO_PCIE_X1_LPCG), 16, FUNCTION_NAME(PD_HSIO_PCIE_B));
+ clks[IMX8QXP_HSIO_PCIE_SLV_AXI_CLK] = imx_clk_gate2_scu("hsio_pcie_slv_axi_clk", "axi_hsio_clk_root", (void __iomem *)(HSIO_PCIE_X1_LPCG), 20, FUNCTION_NAME(PD_HSIO_PCIE_B));
+ clks[IMX8QXP_HSIO_PCIE_DBI_AXI_CLK] = imx_clk_gate2_scu("hsio_pcie_dbi_axi_clk", "axi_hsio_clk_root", (void __iomem *)(HSIO_PCIE_X1_LPCG), 24, FUNCTION_NAME(PD_HSIO_PCIE_B));
+ clks[IMX8QXP_HSIO_PCIE_X1_PER_CLK] = imx_clk_gate2_scu("hsio_pcie_x1_per_clk", "per_hsio_clk_root", (void __iomem *)(HSIO_PCIE_X1_CRR3_LPCG), 16, FUNCTION_NAME(PD_HSIO_PCIE_B));
+ clks[IMX8QXP_HSIO_PHY_X1_PER_CLK] = imx_clk_gate2_scu("hsio_phy_x1_per_clk", "per_hsio_clk_root", (void __iomem *)(HSIO_PHY_X1_CRR1_LPCG), 16, FUNCTION_NAME(PD_HSIO_PCIE_B));
+ clks[IMX8QXP_HSIO_MISC_PER_CLK] = imx_clk_gate2_scu("hsio_misc_per_clk", "per_hsio_clk_root", (void __iomem *)(HSIO_MISC_LPCG), 16, FUNCTION_NAME(PD_HSIO));
+ clks[IMX8QXP_HSIO_PHY_X1_APB_CLK] = imx_clk_gate2_scu("hsio_phy_x1_apb_clk", "per_hsio_clk_root", (void __iomem *)(HSIO_PHY_X1_LPCG), 16, FUNCTION_NAME(PD_HSIO_PCIE_B));
+ clks[IMX8QXP_HSIO_GPIO_CLK] = imx_clk_gate2_scu("hsio_gpio_clk", "per_hsio_clk_root", (void __iomem *)(HSIO_GPIO_LPCG), 16, FUNCTION_NAME(PD_HSIO_PCIE_B));
+ clks[IMX8QXP_HSIO_PHY_X1_PCLK] = imx_clk_gate2_scu("hsio_phy_x1_pclk", "dummy", (void __iomem *)(HSIO_PHY_X1_LPCG), 0, FUNCTION_NAME(PD_HSIO_PCIE_B));
+
+ /* CM40 */
+ clks[IMX8QXP_CM40_I2C_DIV] = imx_clk_divider_scu("cm40_i2c_div", SC_R_M4_0_I2C, SC_PM_CLK_PER);
+ clks[IMX8QXP_CM40_I2C_CLK] = imx_clk_gate_scu("cm40_i2c_clk", "cm40_i2c_div", SC_R_M4_0_I2C, SC_PM_CLK_PER, (void __iomem *)(CM40_I2C_LPCG), 0, 0);
+ clks[IMX8QXP_CM40_I2C_IPG_CLK] = imx_clk_gate2_scu("cm40_i2c_ipg_clk", "ipg_cm40_clk_root", (void __iomem *)(CM40_I2C_LPCG), 16, FUNCTION_NAME(PD_CM40_I2C));
+
+ /* Audio */
+ clks[IMX8QXP_AUD_ACM_AUD_PLL_CLK0_DIV] = imx_clk_divider2_scu("aud_acm_aud_pll_clk0_div", "audio_pll0_clk", SC_R_AUDIO_PLL_0, SC_PM_CLK_MISC0);
+ clks[IMX8QXP_AUD_ACM_AUD_PLL_CLK1_DIV] = imx_clk_divider2_scu("aud_acm_aud_pll_clk1_div", "audio_pll1_clk", SC_R_AUDIO_PLL_1, SC_PM_CLK_MISC0);
+ clks[IMX8QXP_AUD_ACM_AUD_REC_CLK0_DIV] = imx_clk_divider2_scu("aud_acm_aud_rec_clk0_div", "audio_pll0_clk", SC_R_AUDIO_PLL_0, SC_PM_CLK_MISC1);
+ clks[IMX8QXP_AUD_ACM_AUD_REC_CLK1_DIV] = imx_clk_divider2_scu("aud_acm_aud_rec_clk1_div", "audio_pll1_clk", SC_R_AUDIO_PLL_1, SC_PM_CLK_MISC1);
+ clks[IMX8QXP_AUD_ACM_AUD_PLL_CLK0_CLK] = imx_clk_gate_scu("aud_acm_aud_pll_clk0_clk", "aud_acm_aud_pll_clk0_div", SC_R_AUDIO_PLL_0, SC_PM_CLK_MISC0, (void __iomem *)(AUD_PLL_CLK0_LPCG), 0, 0);
+ clks[IMX8QXP_AUD_ACM_AUD_PLL_CLK1_CLK] = imx_clk_gate_scu("aud_acm_aud_pll_clk1_clk", "aud_acm_aud_pll_clk1_div", SC_R_AUDIO_PLL_1, SC_PM_CLK_MISC0, (void __iomem *)(AUD_PLL_CLK1_LPCG), 0, 0);
+ clks[IMX8QXP_AUD_ACM_AUD_REC_CLK0_CLK] = imx_clk_gate_scu("aud_acm_aud_rec_clk0_clk", "aud_acm_aud_rec_clk0_div", SC_R_AUDIO_PLL_0, SC_PM_CLK_MISC1, (void __iomem *)(AUD_REC_CLK0_LPCG), 0, 0);
+ clks[IMX8QXP_AUD_ACM_AUD_REC_CLK1_CLK] = imx_clk_gate_scu("aud_acm_aud_rec_clk1_clk", "aud_acm_aud_rec_clk1_div", SC_R_AUDIO_PLL_1, SC_PM_CLK_MISC1, (void __iomem *)(AUD_REC_CLK1_LPCG), 0, 0);
+
+ /* VPU */
+ clks[IMX8QXP_VPU_ENC_CLK] = imx_clk_gate_scu("vpu_enc_clk", "dummy", SC_R_VPU_ENC_0, SC_PM_CLK_PER, NULL, 0, 0);
+ clks[IMX8QXP_VPU_DEC_CLK] = imx_clk_gate_scu("vpu_dec_clk", "dummy", SC_R_VPU_DEC_0, SC_PM_CLK_PER, NULL, 0, 0);
+
+ np_acm = of_find_compatible_node(NULL, NULL, "nxp,imx8qm-acm");
+ if (np_acm) {
+ base_acm = of_iomap(np_acm, 0);
+ WARN_ON(!base_acm);
+
+ clks[IMX8QXP_EXT_AUD_MCLK0] = imx_clk_fixed("ext_aud_mclk0", 0);
+ clks[IMX8QXP_EXT_AUD_MCLK1] = imx_clk_fixed("ext_aud_mclk1", 0);
+ clks[IMX8QXP_ESAI0_RX_CLK] = imx_clk_fixed("esai0_rx_clk", 0);
+ clks[IMX8QXP_ESAI0_RX_HF_CLK] = imx_clk_fixed("esai0_rx_hf_clk", 0);
+ clks[IMX8QXP_ESAI0_TX_CLK] = imx_clk_fixed("esai0_tx_clk", 0);
+ clks[IMX8QXP_ESAI0_TX_HF_CLK] = imx_clk_fixed("esai0_tx_hf_clk", 0);
+ clks[IMX8QXP_SPDIF0_RX] = imx_clk_fixed("spdif0_rx", 0);
+ clks[IMX8QXP_SAI0_RX_BCLK] = imx_clk_fixed("sai0_rx_bclk", 0);
+ clks[IMX8QXP_SAI0_TX_BCLK] = imx_clk_fixed("sai0_tx_bclk", 0);
+ clks[IMX8QXP_SAI1_RX_BCLK] = imx_clk_fixed("sai1_rx_bclk", 0);
+ clks[IMX8QXP_SAI1_TX_BCLK] = imx_clk_fixed("sai1_tx_bclk", 0);
+ clks[IMX8QXP_SAI2_RX_BCLK] = imx_clk_fixed("sai2_rx_bclk", 0);
+ clks[IMX8QXP_SAI3_RX_BCLK] = imx_clk_fixed("sai3_rx_bclk", 0);
+ clks[IMX8QXP_SAI4_RX_BCLK] = imx_clk_fixed("sai4_rx_bclk", 0);
+
+ clks[IMX8QXP_ACM_AUD_CLK0_SEL] = imx_clk_mux_scu("acm_aud_clk0_sel", base_acm+0x000000, 0, 5, aud_clk_sels, ARRAY_SIZE(aud_clk_sels), FUNCTION_NAME(PD_AUD_AUDIO_CLK_0));
+ clks[IMX8QXP_ACM_AUD_CLK0_CLK] = imx_clk_gate_scu("acm_aud_clk0_clk", "acm_aud_clk0_sel", SC_R_AUDIO_CLK_0, SC_PM_CLK_SLV_BUS, NULL, 0, 0);
+ clks[IMX8QXP_ACM_AUD_CLK1_SEL] = imx_clk_mux_scu("acm_aud_clk1_sel", base_acm+0x010000, 0, 5, aud_clk_sels, ARRAY_SIZE(aud_clk_sels), FUNCTION_NAME(PD_AUD_AUDIO_CLK_1));
+ clks[IMX8QXP_ACM_AUD_CLK1_CLK] = imx_clk_gate_scu("acm_aud_clk1_clk", "acm_aud_clk1_sel", SC_R_AUDIO_CLK_1, SC_PM_CLK_SLV_BUS, NULL, 0, 0);
+ clks[IMX8QXP_ACM_MCLKOUT0_SEL] = imx_clk_mux_scu("acm_mclkout0_sel", base_acm+0x020000, 0, 3, mclk_out_sels, ARRAY_SIZE(mclk_out_sels), FUNCTION_NAME(PD_AUD_MCLK_OUT_0));
+ clks[IMX8QXP_ACM_MCLKOUT1_SEL] = imx_clk_mux_scu("acm_mclkout1_sel", base_acm+0x030000, 0, 3, mclk_out_sels, ARRAY_SIZE(mclk_out_sels), FUNCTION_NAME(PD_AUD_MCLK_OUT_1));
+ clks[IMX8QXP_ACM_ASRC0_MUX_CLK_SEL] = imx_clk_mux_scu("acm_asrc0_mclk_sel", base_acm+0x040000, 0, 2, NULL, 0, FUNCTION_NAME(PD_AUD_ASRC_0));
+ clks[IMX8QXP_ACM_ASRC0_MUX_CLK_CLK] = imx_clk_gate_scu("aud_asrc0_mux_clk", "acm_asrc0_mclk_sel", SC_R_ASRC_0, SC_PM_CLK_PER, NULL, 0, 0);
+ clks[IMX8QXP_ACM_ASRC1_MUX_CLK_SEL] = imx_clk_mux_scu("acm_asrc1_mclk_sel", base_acm+0x050000, 0, 2, NULL, 0, FUNCTION_NAME(PD_AUD_ASRC_1));
+ clks[IMX8QXP_ACM_ASRC1_MUX_CLK_CLK] = imx_clk_gate_scu("aud_asrc1_mux_clk", "acm_asrc1_mclk_sel", SC_R_ASRC_1, SC_PM_CLK_PER, NULL, 0, 0);
+ clks[IMX8QXP_ACM_ESAI0_MCLK_SEL] = imx_clk_mux_scu("acm_esai0_mclk_sel", base_acm+0x060000, 0, 2, esai_mclk_sels, ARRAY_SIZE(esai_mclk_sels), FUNCTION_NAME(PD_AUD_ESAI_0));
+ clks[IMX8QXP_ACM_SAI0_MCLK_SEL] = imx_clk_mux_scu("acm_sai0_mclk_sel", base_acm+0x0E0000, 0, 2, sai_mclk_sels, ARRAY_SIZE(sai_mclk_sels), FUNCTION_NAME(PD_AUD_SAI_0));
+ clks[IMX8QXP_ACM_SAI1_MCLK_SEL] = imx_clk_mux_scu("acm_sai1_mclk_sel", base_acm+0x0F0000, 0, 2, sai_mclk_sels, ARRAY_SIZE(sai_mclk_sels), FUNCTION_NAME(PD_AUD_SAI_1));
+ clks[IMX8QXP_ACM_SAI2_MCLK_SEL] = imx_clk_mux_scu("acm_sai2_mclk_sel", base_acm+0x100000, 0, 2, sai_mclk_sels, ARRAY_SIZE(sai_mclk_sels), FUNCTION_NAME(PD_AUD_SAI_2));
+ clks[IMX8QXP_ACM_SAI3_MCLK_SEL] = imx_clk_mux_scu("acm_sai3_mclk_sel", base_acm+0x110000, 0, 2, sai_mclk_sels, ARRAY_SIZE(sai_mclk_sels), FUNCTION_NAME(PD_AUD_SAI_3));
+ clks[IMX8QXP_ACM_SAI4_MCLK_SEL] = imx_clk_mux_scu("acm_sai4_mclk_sel", base_acm+0x140000, 0, 2, sai_mclk_sels, ARRAY_SIZE(sai_mclk_sels), FUNCTION_NAME(PD_AUD_SAI_4));
+ clks[IMX8QXP_ACM_SAI5_MCLK_SEL] = imx_clk_mux_scu("acm_sai5_mclk_sel", base_acm+0x150000, 0, 2, sai_mclk_sels, ARRAY_SIZE(sai_mclk_sels), FUNCTION_NAME(PD_AUD_SAI_5));
+ clks[IMX8QXP_ACM_SPDIF0_TX_CLK_SEL] = imx_clk_mux_scu("acm_spdif0_mclk_sel", base_acm+0x1A0000, 0, 2, spdif_mclk_sels, ARRAY_SIZE(spdif_mclk_sels), FUNCTION_NAME(PD_AUD_SPDIF_0));
+ clks[IMX8QXP_ACM_MQS_TX_CLK_SEL] = imx_clk_mux_scu("acm_mqs_mclk_sel", base_acm+0x1C0000, 0, 2, mqs_mclk_sels, ARRAY_SIZE(mqs_mclk_sels), FUNCTION_NAME(PD_AUD_MQS_0));
+
+ clks[IMX8QXP_AUD_AMIX_IPG] = imx_clk_gate2_scu("aud_amix_ipg_clk", "ipg_aud_clk_root", (void __iomem *)(AUD_AMIX_LPCG), 0, FUNCTION_NAME(PD_AUD_AMIX));
+ clks[IMX8QXP_AUD_ESAI_0_IPG] = imx_clk_gate2_scu("aud_esai0_ipg_clk", "ipg_aud_clk_root", (void __iomem *)(AUD_ESAI_0_LPCG), 16, FUNCTION_NAME(PD_AUD_ESAI_0));
+ clks[IMX8QXP_AUD_ESAI_0_EXTAL_IPG] = imx_clk_gate2_scu("aud_esai0_extal_clk", "acm_esai0_mclk_sel", (void __iomem *)(AUD_ESAI_0_LPCG), 0, FUNCTION_NAME(PD_AUD_ESAI_0));
+ clks[IMX8QXP_AUD_SAI_0_IPG] = imx_clk_gate2_scu("aud_sai0_ipg_clk", "ipg_aud_clk_root", (void __iomem *)(AUD_SAI_0_LPCG), 16, FUNCTION_NAME(PD_AUD_SAI_0));
+ clks[IMX8QXP_AUD_SAI_0_MCLK] = imx_clk_gate2_scu("aud_sai0_mclk_clk", "acm_sai0_mclk_sel", (void __iomem *)(AUD_SAI_0_LPCG), 0, FUNCTION_NAME(PD_AUD_SAI_0));
+ clks[IMX8QXP_AUD_SAI_1_IPG] = imx_clk_gate2_scu("aud_sai1_ipg_clk", "ipg_aud_clk_root", (void __iomem *)(AUD_SAI_1_LPCG), 16, FUNCTION_NAME(PD_AUD_SAI_1));
+ clks[IMX8QXP_AUD_SAI_1_MCLK] = imx_clk_gate2_scu("aud_sai1_mclk_clk", "acm_sai1_mclk_sel", (void __iomem *)(AUD_SAI_1_LPCG), 0, FUNCTION_NAME(PD_AUD_SAI_1));
+ clks[IMX8QXP_AUD_SAI_2_IPG] = imx_clk_gate2_scu("aud_sai2_ipg_clk", "ipg_aud_clk_root", (void __iomem *)(AUD_SAI_2_LPCG), 16, FUNCTION_NAME(PD_AUD_SAI_2));
+ clks[IMX8QXP_AUD_SAI_2_MCLK] = imx_clk_gate2_scu("aud_sai2_mclk_clk", "acm_sai2_mclk_sel", (void __iomem *)(AUD_SAI_2_LPCG), 0, FUNCTION_NAME(PD_AUD_SAI_2));
+ clks[IMX8QXP_AUD_SAI_3_IPG] = imx_clk_gate2_scu("aud_sai3_ipg_clk", "ipg_aud_clk_root", (void __iomem *)(AUD_SAI_3_LPCG), 16, FUNCTION_NAME(PD_AUD_SAI_3));
+ clks[IMX8QXP_AUD_SAI_3_MCLK] = imx_clk_gate2_scu("aud_sai3_mclk_clk", "acm_sai3_mclk_sel", (void __iomem *)(AUD_SAI_3_LPCG), 0, FUNCTION_NAME(PD_AUD_SAI_3));
+ clks[IMX8QXP_AUD_SAI_4_IPG] = imx_clk_gate2_scu("aud_sai4_ipg_clk", "ipg_aud_clk_root", (void __iomem *)(AUD_SAI_4_LPCG), 16, FUNCTION_NAME(PD_AUD_SAI_4));
+ clks[IMX8QXP_AUD_SAI_4_MCLK] = imx_clk_gate2_scu("aud_sai4_mclk_clk", "acm_sai4_mclk_sel", (void __iomem *)(AUD_SAI_4_LPCG), 0, FUNCTION_NAME(PD_AUD_SAI_4));
+ clks[IMX8QXP_AUD_SAI_5_IPG] = imx_clk_gate2_scu("aud_sai5_ipg_clk", "ipg_aud_clk_root", (void __iomem *)(AUD_SAI_5_LPCG), 16, FUNCTION_NAME(PD_AUD_SAI_5));
+ clks[IMX8QXP_AUD_SAI_5_MCLK] = imx_clk_gate2_scu("aud_sai5_mclk_clk", "acm_sai5_mclk_sel", (void __iomem *)(AUD_SAI_5_LPCG), 0, FUNCTION_NAME(PD_AUD_SAI_5));
+ clks[IMX8QXP_AUD_MQS_IPG] = imx_clk_gate2_scu("aud_mqs_ipg", "ipg_aud_clk_root", (void __iomem *)(AUD_MQS_LPCG), 16, FUNCTION_NAME(PD_AUD_MQS_0));
+ clks[IMX8QXP_AUD_MQS_HMCLK] = imx_clk_gate2_scu("aud_mqs_hm_clk", "acm_mqs_mclk_sel", (void __iomem *)(AUD_MQS_LPCG), 0, FUNCTION_NAME(PD_AUD_MQS_0));
+ clks[IMX8QXP_AUD_GPT5_IPG] = imx_clk_gate2_scu("aud_gpt5_ipg", "ipg_aud_clk_root", (void __iomem *)(AUD_GPT_5_LPCG), 16, FUNCTION_NAME(PD_AUD_GPT_5));
+ clks[IMX8QXP_AUD_GPT5_CLKIN] = imx_clk_gate2_scu("aud_gpt5_clkin", "ipg_aud_clk_root", (void __iomem *)(AUD_GPT_5_LPCG), 0, FUNCTION_NAME(PD_AUD_GPT_5));
+ clks[IMX8QXP_AUD_GPT6_IPG] = imx_clk_gate2_scu("aud_gpt6_ipg", "ipg_aud_clk_root", (void __iomem *)(AUD_GPT_6_LPCG), 16, FUNCTION_NAME(PD_AUD_GPT_6));
+ clks[IMX8QXP_AUD_GPT6_CLKIN] = imx_clk_gate2_scu("aud_gpt6_clkin", "ipg_aud_clk_root", (void __iomem *)(AUD_GPT_6_LPCG), 0, FUNCTION_NAME(PD_AUD_GPT_6));
+ clks[IMX8QXP_AUD_GPT7_IPG] = imx_clk_gate2_scu("aud_gpt7_ipg", "ipg_aud_clk_root", (void __iomem *)(AUD_GPT_7_LPCG), 16, FUNCTION_NAME(PD_AUD_GPT_7));
+ clks[IMX8QXP_AUD_GPT7_CLKIN] = imx_clk_gate2_scu("aud_gpt7_clkin", "ipg_aud_clk_root", (void __iomem *)(AUD_GPT_7_LPCG), 0, FUNCTION_NAME(PD_AUD_GPT_7));
+ clks[IMX8QXP_AUD_GPT8_IPG] = imx_clk_gate2_scu("aud_gpt8_ipg", "ipg_aud_clk_root", (void __iomem *)(AUD_GPT_8_LPCG), 16, FUNCTION_NAME(PD_AUD_GPT_8));
+ clks[IMX8QXP_AUD_GPT8_CLKIN] = imx_clk_gate2_scu("aud_gpt8_clkin", "ipg_aud_clk_root", (void __iomem *)(AUD_GPT_8_LPCG), 0, FUNCTION_NAME(PD_AUD_GPT_8));
+ clks[IMX8QXP_AUD_GPT9_IPG] = imx_clk_gate2_scu("aud_gpt9_ipg", "ipg_aud_clk_root", (void __iomem *)(AUD_GPT_9_LPCG), 16, FUNCTION_NAME(PD_AUD_GPT_9));
+ clks[IMX8QXP_AUD_GPT9_CLKIN] = imx_clk_gate2_scu("aud_gpt9_clkin", "ipg_aud_clk_root", (void __iomem *)(AUD_GPT_9_LPCG), 0, FUNCTION_NAME(PD_AUD_GPT_9));
+ clks[IMX8QXP_AUD_GPT10_IPG] = imx_clk_gate2_scu("aud_gpt10_ipg", "ipg_aud_clk_root", (void __iomem *)(AUD_GPT_10_LPCG), 16, FUNCTION_NAME(PD_AUD_GPT_10));
+ clks[IMX8QXP_AUD_GPT10_CLKIN] = imx_clk_gate2_scu("aud_gpt10_clkin", "ipg_aud_clk_root", (void __iomem *)(AUD_GPT_10_LPCG), 0, FUNCTION_NAME(PD_AUD_GPT_10));
+ clks[IMX8QXP_AUD_MCLKOUT0] = imx_clk_gate2_scu("aud_mclkout0", "acm_mclkout0_sel", (void __iomem *)(AUD_MCLKOUT0_LPCG), 0, FUNCTION_NAME(PD_AUD_MCLK_OUT_0));
+ clks[IMX8QXP_AUD_MCLKOUT1] = imx_clk_gate2_scu("aud_mclkout1", "acm_mclkout1_sel", (void __iomem *)(AUD_MCLKOUT1_LPCG), 0, FUNCTION_NAME(PD_AUD_MCLK_OUT_1));
+ clks[IMX8QXP_AUD_SPDIF_0_GCLKW] = imx_clk_gate2_scu("spdif0_gclkw", "ipg_aud_clk_root", (void __iomem *)(AUD_SPDIF_0_LPCG), 16, FUNCTION_NAME(PD_AUD_SPDIF_0));
+ clks[IMX8QXP_AUD_SPDIF_0_TX_CLK] = imx_clk_gate2_scu("spdif0_tx_clk", "acm_spdif0_mclk_sel", (void __iomem *)(AUD_SPDIF_0_LPCG), 0, FUNCTION_NAME(PD_AUD_SPDIF_0));
+ clks[IMX8QXP_AUD_ASRC_0_IPG] = imx_clk_gate2_scu("aud_asrc0_ipg", "ipg_aud_clk_root", (void __iomem *)(AUD_ASRC_0_LPCG), 16, FUNCTION_NAME(PD_AUD_ASRC_0));
+ clks[IMX8QXP_AUD_ASRC_1_IPG] = imx_clk_gate2_scu("aud_asrc1_ipg", "ipg_aud_clk_root", (void __iomem *)(AUD_ASRC_1_LPCG), 16, FUNCTION_NAME(PD_AUD_ASRC_1));
+ clks[IMX8QXP_AUD_DSP_ADB_ACLK] = imx_clk_gate2_scu("aud_dsp_adb_aclk", "ipg_aud_clk_root", (void __iomem *)(AUD_DSP_LPCG), 16, FUNCTION_NAME(PD_AUD_DSP));
+ clks[IMX8QXP_AUD_DSP_IPG] = imx_clk_gate2_scu("aud_dsp_ipg", "ipg_aud_clk_root", (void __iomem *)(AUD_DSP_LPCG), 20, FUNCTION_NAME(PD_AUD_DSP));
+ clks[IMX8QXP_AUD_DSP_CORE_CLK] = imx_clk_gate2_scu("aud_dsp_core_clk", "ipg_aud_clk_root", (void __iomem *)(AUD_DSP_LPCG), 28, FUNCTION_NAME(PD_AUD_DSP));
+ clks[IMX8QXP_AUD_OCRAM_IPG] = imx_clk_gate2_scu("aud_ocram_ipg", "ipg_aud_clk_root", (void __iomem *)(AUD_OCRAM_LPCG), 16, FUNCTION_NAME(PD_AUD_OCRAM));
+ };
+
+ for (i = 0; i < ARRAY_SIZE(clks); i++)
+ if (IS_ERR(clks[i]) && PTR_ERR(clks[i]) != -ENODEV)
+ pr_err("i.MX8QXP clk %d: register failed with %ld\n",
+ i, PTR_ERR(clks[i]));
+
+ clk_data.clks = clks;
+ clk_data.clk_num = ARRAY_SIZE(clks);
+ of_clk_add_provider(ccm_node, of_clk_src_onecell_get, &clk_data);
+
+ return 0;
+}
+
+static const struct of_device_id imx8qxp_match[] = {
+ { .compatible = "fsl,imx8qxp-clk", },
+ { /* sentinel value */ }
+};
+
+static struct platform_driver imx8qxp_clk_driver = {
+ .driver = {
+ .name = "imx8qxp-clk",
+ .of_match_table = imx8qxp_match,
+ },
+ .probe = imx8qxp_clk_probe,
+};
+
+static int __init imx8qxp_clk_init(void)
+{
+ return platform_driver_register(&imx8qxp_clk_driver);
+}
+core_initcall(imx8qxp_clk_init);
diff --git a/drivers/clk/imx/clk-intpll.c b/drivers/clk/imx/clk-intpll.c
new file mode 100644
index 000000000000..4c8e0685b8ba
--- /dev/null
+++ b/drivers/clk/imx/clk-intpll.c
@@ -0,0 +1,430 @@
+/*
+ * Copyright 2017-2018 NXP.
+ *
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/bitops.h>
+#include <linux/clk-provider.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <linux/jiffies.h>
+
+#include "clk.h"
+
+#define GNRL_CTL 0x0
+#define DIV_CTL 0x4
+#define LOCK_STATUS BIT(31)
+#define LOCK_SEL_MASK BIT(29)
+#define CLKE_MASK BIT(11)
+#define RST_MASK BIT(9)
+#define BYPASS_MASK BIT(4)
+#define MDIV_SHIFT 12
+#define MDIV_MASK GENMASK(21, 12)
+#define PDIV_SHIFT 4
+#define PDIV_MASK GENMASK(9, 4)
+#define SDIV_SHIFT 0
+#define SDIV_MASK GENMASK(2, 0)
+#define KDIV_SHIFT 0
+#define KDIV_MASK GENMASK(15, 0)
+
+struct clk_int_pll {
+ struct clk_hw hw;
+ void __iomem *base;
+ enum imx_int_pll_type type;
+ struct imx_int_pll_rate_table *rate_table;
+ int rate_count;
+};
+
+#define to_clk_int_pll(_hw) container_of(_hw, struct clk_int_pll, hw)
+
+static const struct imx_int_pll_rate_table *imx_get_pll_settings(
+ struct clk_int_pll *pll, unsigned long rate)
+{
+ const struct imx_int_pll_rate_table *rate_table = pll->rate_table;
+ int i;
+
+ for (i = 0; i < pll->rate_count; i++) {
+ if (rate == rate_table[i].rate)
+ return &rate_table[i];
+ }
+
+ return NULL;
+}
+
+static long clk_int_pll_round_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long *prate)
+{
+ struct clk_int_pll *pll = to_clk_int_pll(hw);
+ const struct imx_int_pll_rate_table *rate_table = pll->rate_table;
+ int i;
+
+ /* Assumming rate_table is in descending order */
+ for (i = 0; i < pll->rate_count; i++) {
+ if (rate >= rate_table[i].rate)
+ return rate_table[i].rate;
+ }
+ /* return minimum supported value */
+ return rate_table[i - 1].rate;
+}
+
+static unsigned long clk_int_pll1416x_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ struct clk_int_pll *pll = to_clk_int_pll(hw);
+ u32 mdiv, pdiv, sdiv, pll_gnrl, pll_div;
+ u64 fvco = parent_rate;
+
+ pll_gnrl = readl_relaxed(pll->base);
+ pll_div = readl_relaxed(pll->base + 4);
+ mdiv = (pll_div & MDIV_MASK) >> MDIV_SHIFT;
+ pdiv = (pll_div & PDIV_MASK) >> PDIV_SHIFT;
+ sdiv = (pll_div & SDIV_MASK) >> SDIV_SHIFT;
+
+ fvco *= mdiv;
+ do_div(fvco, pdiv << sdiv);
+
+ return (unsigned long)fvco;
+}
+
+static unsigned long clk_int_pll1443x_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ struct clk_int_pll *pll = to_clk_int_pll(hw);
+ const struct imx_int_pll_rate_table *rate_table = pll->rate_table;
+ u32 mdiv, pdiv, sdiv, pll_gnrl, pll_div_ctl0, pll_div_ctl1;
+ short int kdiv;
+ u64 fvco = parent_rate;
+ long rate = 0;
+ int i;
+
+ pll_gnrl = readl_relaxed(pll->base);
+ pll_div_ctl0 = readl_relaxed(pll->base + 4);
+ pll_div_ctl1 = readl_relaxed(pll->base + 8);
+ mdiv = (pll_div_ctl0 & MDIV_MASK) >> MDIV_SHIFT;
+ pdiv = (pll_div_ctl0 & PDIV_MASK) >> PDIV_SHIFT;
+ sdiv = (pll_div_ctl0 & SDIV_MASK) >> SDIV_SHIFT;
+ kdiv = pll_div_ctl1 & KDIV_MASK;
+
+ /*
+ * Sometimes, the recalculated rate has deviation due to
+ * the frac part. So find the accurate pll rate from the table
+ * first, if no match rate in the table, use the rate calculated
+ * from the equation below.
+ */
+ for (i = 0; i < pll->rate_count; i++) {
+ if (rate_table[i].pdiv == pdiv && rate_table[i].mdiv == mdiv &&
+ rate_table[i].sdiv == sdiv && rate_table[i].kdiv == kdiv)
+ rate = rate_table[i].rate;
+ }
+
+ /* fvco = (m * 65536 + k) * Fin / (p * 65536) */
+ fvco *= (mdiv * 65536 + kdiv);
+ pdiv *= 65536;
+
+ do_div(fvco, pdiv << sdiv);
+
+ return rate ? (unsigned long) rate : (unsigned long)fvco;
+}
+
+static inline bool clk_int_pll1416x_mp_change(const struct imx_int_pll_rate_table *rate,
+ u32 pll_div)
+{
+ u32 old_mdiv, old_pdiv;
+
+ old_mdiv = (pll_div >> MDIV_SHIFT) & MDIV_MASK;
+ old_pdiv = (pll_div >> PDIV_SHIFT) & PDIV_MASK;
+
+ return (rate->mdiv != old_mdiv || rate->pdiv != old_pdiv);
+}
+
+static inline bool clk_int_pll1443x_mpk_change(const struct imx_int_pll_rate_table *rate,
+ u32 pll_div_ctl0, u32 pll_div_ctl1)
+{
+ u32 old_mdiv, old_pdiv, old_kdiv;
+
+ old_mdiv = (pll_div_ctl0 >> MDIV_SHIFT) & MDIV_MASK;
+ old_pdiv = (pll_div_ctl0 >> PDIV_SHIFT) & PDIV_MASK;
+ old_kdiv = (pll_div_ctl1 >> KDIV_SHIFT) & KDIV_MASK;
+
+ return (rate->mdiv != old_mdiv || rate->pdiv != old_pdiv ||
+ rate->kdiv != old_kdiv);
+}
+
+static inline bool clk_int_pll1443x_mp_change(const struct imx_int_pll_rate_table *rate,
+ u32 pll_div_ctl0, u32 pll_div_ctl1)
+{
+ u32 old_mdiv, old_pdiv, old_kdiv;
+
+ old_mdiv = (pll_div_ctl0 >> MDIV_SHIFT) & MDIV_MASK;
+ old_pdiv = (pll_div_ctl0 >> PDIV_SHIFT) & PDIV_MASK;
+ old_kdiv = (pll_div_ctl1 >> KDIV_SHIFT) & KDIV_MASK;
+
+ return (rate->mdiv != old_mdiv || rate->pdiv != old_pdiv ||
+ rate->kdiv != old_kdiv);
+}
+
+static int clk_int_pll_wait_lock(struct clk_int_pll *pll)
+{
+ unsigned long timeout = jiffies + msecs_to_jiffies(10);
+
+ /* Wait for PLL to lock */
+ do {
+ if (readl_relaxed(pll->base) & LOCK_STATUS)
+ break;
+ if (time_after(jiffies, timeout))
+ break;
+ } while (1);
+
+ return readl_relaxed(pll->base) & LOCK_STATUS ? 0 : -ETIMEDOUT;
+}
+
+static int clk_int_pll1416x_set_rate(struct clk_hw *hw, unsigned long drate,
+ unsigned long prate)
+{
+ struct clk_int_pll *pll = to_clk_int_pll(hw);
+ const struct imx_int_pll_rate_table *rate;
+ u32 tmp, div_val;
+ int ret;
+
+ rate = imx_get_pll_settings(pll, drate);
+ if (!rate) {
+ pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
+ drate, clk_hw_get_name(hw));
+ return -EINVAL;
+ }
+
+ tmp = readl_relaxed(pll->base + 4);
+
+ if (!clk_int_pll1416x_mp_change(rate, tmp)) {
+ tmp &= ~(SDIV_MASK) << SDIV_SHIFT;
+ tmp |= rate->sdiv << SDIV_SHIFT;
+ writel_relaxed(tmp, pll->base + 4);
+
+ return 0;
+ }
+
+ /* Bypass clock and set lock to pll output lock */
+ tmp = readl_relaxed(pll->base);
+ tmp |= LOCK_SEL_MASK;
+ writel_relaxed(tmp, pll->base);
+
+ /* Enable RST */
+ tmp &= ~RST_MASK;
+ writel_relaxed(tmp, pll->base);
+
+ div_val = (rate->mdiv << MDIV_SHIFT) | (rate->pdiv << PDIV_SHIFT) |
+ (rate->sdiv << SDIV_SHIFT);
+ writel_relaxed(div_val, pll->base + 0x4);
+
+ /*
+ * According to SPEC, t3 - t2 need to be greater than
+ * 1us and 1/FREF, respectively.
+ * FREF is FIN / Prediv, the prediv is [1, 63], so choose
+ * 3us.
+ */
+ udelay(3);
+
+ /* Disable RST */
+ tmp |= RST_MASK;
+ writel_relaxed(tmp, pll->base);
+
+ /* Wait Lock */
+ ret = clk_int_pll_wait_lock(pll);
+ if (ret)
+ return ret;
+
+ /* Bypass */
+ tmp &= ~BYPASS_MASK;
+ writel_relaxed(tmp, pll->base);
+
+ return 0;
+}
+
+static int clk_int_pll1443x_set_rate(struct clk_hw *hw, unsigned long drate,
+ unsigned long prate)
+{
+ struct clk_int_pll *pll = to_clk_int_pll(hw);
+ const struct imx_int_pll_rate_table *rate;
+ u32 tmp, div_val;
+ int ret;
+
+ rate = imx_get_pll_settings(pll, drate);
+ if (!rate) {
+ pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
+ drate, clk_hw_get_name(hw));
+ return -EINVAL;
+ }
+
+ tmp = readl_relaxed(pll->base + 4);
+ div_val = readl_relaxed(pll->base + 8);
+
+ if (!clk_int_pll1443x_mpk_change(rate, tmp, div_val)) {
+ tmp &= ~(SDIV_MASK) << SDIV_SHIFT;
+ tmp |= rate->sdiv << SDIV_SHIFT;
+ writel_relaxed(tmp, pll->base + 4);
+
+ return 0;
+ }
+
+ /* Enable RST */
+ tmp = readl_relaxed(pll->base);
+ tmp &= ~RST_MASK;
+ writel_relaxed(tmp, pll->base);
+
+ div_val = (rate->mdiv << MDIV_SHIFT) | (rate->pdiv << PDIV_SHIFT) |
+ (rate->sdiv << SDIV_SHIFT);
+ writel_relaxed(div_val, pll->base + 0x4);
+ writel_relaxed(rate->kdiv << KDIV_SHIFT, pll->base + 0x8);
+
+ /*
+ * According to SPEC, t3 - t2 need to be greater than
+ * 1us and 1/FREF, respectively.
+ * FREF is FIN / Prediv, the prediv is [1, 63], so choose
+ * 3us.
+ */
+ udelay(3);
+
+ /* Disable RST */
+ tmp |= RST_MASK;
+ writel_relaxed(tmp, pll->base);
+
+ /* Wait Lock*/
+ ret = clk_int_pll_wait_lock(pll);
+ if (ret)
+ return ret;
+
+ /* Bypass */
+ tmp &= ~BYPASS_MASK;
+ writel_relaxed(tmp, pll->base);
+
+ return 0;
+}
+
+static int clk_int_pll_prepare(struct clk_hw *hw)
+{
+ struct clk_int_pll *pll = to_clk_int_pll(hw);
+ u32 val;
+
+ /*
+ * RESETB = 1 from 0, PLL starts its normal
+ * operation after lock time
+ */
+ val = readl_relaxed(pll->base + GNRL_CTL);
+ val |= RST_MASK;
+ writel_relaxed(val, pll->base + GNRL_CTL);
+
+ return clk_int_pll_wait_lock(pll);
+}
+
+static int clk_int_pll_is_prepared(struct clk_hw *hw)
+{
+ struct clk_int_pll *pll = to_clk_int_pll(hw);
+ u32 val;
+
+ val = readl_relaxed(pll->base + GNRL_CTL);
+
+ return (val & RST_MASK) ? 1 : 0;
+}
+
+static void clk_int_pll_unprepare(struct clk_hw *hw)
+{
+ struct clk_int_pll *pll = to_clk_int_pll(hw);
+ u32 val;
+
+ /*
+ * Set RST to 0, power down mode is enabled and
+ * every digital block is reset
+ */
+ val = readl_relaxed(pll->base + GNRL_CTL);
+ val &= ~RST_MASK;
+ writel_relaxed(val, pll->base + GNRL_CTL);
+}
+
+static const struct clk_ops clk_pll1416x_ops = {
+ .prepare = clk_int_pll_prepare,
+ .unprepare = clk_int_pll_unprepare,
+ .is_prepared = clk_int_pll_is_prepared,
+ .recalc_rate = clk_int_pll1416x_recalc_rate,
+ .round_rate = clk_int_pll_round_rate,
+ .set_rate = clk_int_pll1416x_set_rate,
+};
+
+static const struct clk_ops clk_pll1416x_min_ops = {
+ .recalc_rate = clk_int_pll1416x_recalc_rate,
+};
+
+static const struct clk_ops clk_pll1443x_ops = {
+ .prepare = clk_int_pll_prepare,
+ .unprepare = clk_int_pll_unprepare,
+ .is_prepared = clk_int_pll_is_prepared,
+ .recalc_rate = clk_int_pll1443x_recalc_rate,
+ .round_rate = clk_int_pll_round_rate,
+ .set_rate = clk_int_pll1443x_set_rate,
+};
+
+struct clk *imx_clk_int_pll(const char *name, const char *parent_name,
+ void __iomem *base,
+ const struct imx_int_pll_clk *pll_clk)
+{
+ struct clk_int_pll *pll;
+ struct clk *clk;
+ struct clk_init_data init;
+ int len;
+
+ pll = kzalloc(sizeof(*pll), GFP_KERNEL);
+ if (!pll)
+ return ERR_PTR(-ENOMEM);
+
+ init.name = name;
+ init.flags = pll_clk->flags;
+ init.parent_names = &parent_name;
+ init.num_parents = 1;
+
+ if (pll_clk->rate_table) {
+ for (len = 0; pll_clk->rate_table[len].rate != 0; )
+ len++;
+
+ pll->rate_count = len;
+ pll->rate_table = kmemdup(pll_clk->rate_table,
+ pll->rate_count *
+ sizeof(struct imx_int_pll_rate_table),
+ GFP_KERNEL);
+ WARN(!pll->rate_table, "%s : could not alloc rate table\n", __func__);
+ }
+
+ switch (pll_clk->type) {
+ case PLL_1416X:
+ if (!pll->rate_table)
+ init.ops = &clk_pll1416x_min_ops;
+ else
+ init.ops = &clk_pll1416x_ops;
+ break;
+ case PLL_1443X:
+ init.ops = &clk_pll1443x_ops;
+ break;
+ default:
+ pr_err("%s: Unknown pll type for pll clk %s\n",
+ __func__, name);
+ };
+
+ pll->base = base;
+ pll->hw.init = &init;
+ pll->type = pll_clk->type;
+
+ clk = clk_register(NULL, &pll->hw);
+ if (IS_ERR(clk)) {
+ pr_err("%s: failed to register pll %s %lu\n",
+ __func__, name, PTR_ERR(clk));
+ kfree(pll);
+ }
+
+ return clk;
+}
diff --git a/drivers/clk/imx/clk-mux-scu.c b/drivers/clk/imx/clk-mux-scu.c
new file mode 100644
index 000000000000..ac1c8bc385bd
--- /dev/null
+++ b/drivers/clk/imx/clk-mux-scu.c
@@ -0,0 +1,445 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017 NXP
+ *
+ * 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/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/pm_domain.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <soc/imx8/sc/sci.h>
+
+#include "clk-imx8.h"
+
+/*
+ * DOC: basic adjustable multiplexer clock that cannot gate
+ *
+ * Traits of this clock:
+ * prepare - clk_prepare only ensures that parents are prepared
+ * enable - clk_enable only ensures that parents are enabled
+ * rate - rate is only affected by parent switching. No clk_set_rate support
+ * parent - parent is adjustable through clk_set_parent
+ */
+
+struct clk_mux_scu {
+ struct clk_hw hw;
+ void __iomem *reg;
+ u32 *table;
+ u32 mask;
+ u8 shift;
+ u8 flags;
+ u32 val;
+ bool update;
+ spinlock_t *lock;
+ char *pd_name;
+ struct generic_pm_domain *pd;
+};
+
+struct clk_mux_gpr_scu {
+ struct clk_hw hw;
+ sc_rsrc_t rsrc_id;
+ sc_ctrl_t gpr_id;
+};
+
+struct clk_mux2_scu {
+ struct clk_hw hw;
+ sc_rsrc_t rsrc_id;
+ sc_pm_clk_t clk_type;
+};
+
+#define to_clk_mux_scu(_hw) container_of(_hw, struct clk_mux_scu, hw)
+#define to_clk_mux_gpr_scu(_hw) container_of(_hw, struct clk_mux_gpr_scu, hw)
+#define to_clk_mux2_scu(_hw) container_of(_hw, struct clk_mux2_scu, hw)
+
+/* Get the power domain associated with the clock from the device tree. */
+static void populate_mux_pd(struct clk_mux_scu *clk)
+{
+ struct device_node *np;
+ struct of_phandle_args pd_args;
+
+ np = of_find_node_by_name(NULL, clk->pd_name);
+ if (np) {
+ pd_args.np = np;
+ pd_args.args_count = 0;
+ clk->pd = genpd_get_from_provider(&pd_args);
+ if (IS_ERR(clk->pd))
+ pr_warn("%s: failed to get pd\n", __func__);
+ }
+}
+
+static int check_mux_pd(struct clk_mux_scu *mux)
+{
+ if (!ccm_ipc_handle)
+ return -1;
+
+ if (mux->pd == NULL && mux->pd_name)
+ populate_mux_pd(mux);
+
+ if (IS_ERR_OR_NULL(mux->pd))
+ return -1;
+
+ if (mux->pd->status != GPD_STATE_ACTIVE)
+ return -1;
+
+ return 0;
+}
+
+static u8 clk_mux_get_parent_scu(struct clk_hw *hw)
+{
+ struct clk_mux_scu *mux = to_clk_mux_scu(hw);
+ int num_parents = clk_hw_get_num_parents(hw);
+ u32 val;
+
+ /*
+ * FIXME need a mux-specific flag to determine if val is bitwise or numeric
+ * e.g. sys_clkin_ck's clksel field is 3 bits wide, but ranges from 0x1
+ * to 0x7 (index starts at one)
+ * OTOH, pmd_trace_clk_mux_ck uses a separate bit for each clock, so
+ * val = 0x4 really means "bit 2, index starts at bit 0"
+ */
+ val = mux->val >> mux->shift;
+ val &= mux->mask;
+
+ if (mux->table) {
+ int i;
+
+ for (i = 0; i < num_parents; i++)
+ if (mux->table[i] == val)
+ return i;
+ return -EINVAL;
+ }
+
+ if (val && (mux->flags & CLK_MUX_INDEX_BIT))
+ val = ffs(val) - 1;
+
+ if (val && (mux->flags & CLK_MUX_INDEX_ONE))
+ val--;
+
+ if (val >= num_parents)
+ return -EINVAL;
+
+ return val;
+}
+
+static int clk_mux_prepare_scu(struct clk_hw *hw)
+{
+ struct clk_mux_scu *mux = to_clk_mux_scu(hw);
+ unsigned long flags = 0;
+ int ret;
+
+ ret = check_mux_pd(mux);
+ if (ret)
+ return ret;
+
+ if (mux->lock)
+ spin_lock_irqsave(mux->lock, flags);
+
+ if (mux->update) {
+ clk_writel(mux->val, mux->reg);
+ mux->update = 0;
+ }
+
+ if (mux->lock)
+ spin_unlock_irqrestore(mux->lock, flags);
+
+ return 0;
+}
+
+static int clk_mux_set_parent_scu(struct clk_hw *hw, u8 index)
+{
+ struct clk_mux_scu *mux = to_clk_mux_scu(hw);
+ unsigned long flags = 0;
+ int ret;
+
+ ret = check_mux_pd(mux);
+
+ if (mux->table) {
+ index = mux->table[index];
+ } else {
+ if (mux->flags & CLK_MUX_INDEX_BIT)
+ index = 1 << index;
+ if (mux->flags & CLK_MUX_INDEX_ONE)
+ index++;
+ }
+
+ if (mux->lock)
+ spin_lock_irqsave(mux->lock, flags);
+
+ if (mux->flags & CLK_MUX_HIWORD_MASK) {
+ mux->val = mux->mask << (mux->shift + 16);
+ } else {
+ mux->val &= ~(mux->mask << mux->shift);
+ }
+ mux->val |= index << mux->shift;
+ mux->update = (ret != 0);
+
+ if (ret == 0)
+ clk_writel(mux->val, mux->reg);
+
+ if (mux->lock)
+ spin_unlock_irqrestore(mux->lock, flags);
+
+ return 0;
+}
+
+const struct clk_ops clk_mux_scu_ops = {
+ .prepare = clk_mux_prepare_scu,
+ .get_parent = clk_mux_get_parent_scu,
+ .set_parent = clk_mux_set_parent_scu,
+ .determine_rate = __clk_mux_determine_rate,
+};
+
+const struct clk_ops clk_mux_ro_scu_ops = {
+ .get_parent = clk_mux_get_parent_scu,
+};
+
+struct clk *clk_register_mux_table_scu(struct device *dev, const char *name,
+ const char **parent_names, u8 num_parents, unsigned long flags,
+ void __iomem *reg, u8 shift, u32 mask,
+ u8 clk_mux_flags, u32 *table, spinlock_t *lock,
+ const char *pd_name)
+{
+ struct clk_mux_scu *mux;
+ struct clk *clk;
+ struct clk_init_data init;
+ u8 width = 0;
+
+ if (clk_mux_flags & CLK_MUX_HIWORD_MASK) {
+ width = fls(mask) - ffs(mask) + 1;
+ if (width + shift > 16) {
+ pr_err("mux value exceeds LOWORD field\n");
+ return ERR_PTR(-EINVAL);
+ }
+ }
+
+ /* allocate the mux */
+ mux = kzalloc(sizeof(struct clk_mux_scu), GFP_KERNEL);
+ if (!mux) {
+ pr_err("%s: could not allocate mux clk\n", __func__);
+ return ERR_PTR(-ENOMEM);
+ }
+
+ init.name = name;
+ if (clk_mux_flags & CLK_MUX_READ_ONLY)
+ init.ops = &clk_mux_ro_scu_ops;
+ else
+ init.ops = &clk_mux_scu_ops;
+ init.flags = flags | CLK_IS_BASIC;
+ init.parent_names = parent_names;
+ init.num_parents = num_parents;
+
+ /* struct clk_mux_scu assignments */
+ mux->reg = reg;
+ mux->shift = shift;
+ mux->mask = mask;
+ mux->flags = clk_mux_flags;
+ mux->lock = lock;
+ mux->table = table;
+ mux->hw.init = &init;
+ mux->pd_name = NULL;
+ if (pd_name) {
+ mux->pd_name = kzalloc(strlen(pd_name) + 1, GFP_KERNEL);
+ strcpy(mux->pd_name, pd_name);
+ }
+
+ clk = clk_register(dev, &mux->hw);
+
+ if (IS_ERR(clk)) {
+ kfree(mux->pd_name);
+ kfree(mux);
+ }
+
+ return clk;
+}
+
+struct clk *clk_register_mux_scu(struct device *dev, const char *name,
+ const char **parent_names, u8 num_parents, unsigned long flags,
+ void __iomem *reg, u8 shift, u8 width,
+ u8 clk_mux_flags, spinlock_t *lock,
+ const char *pd_name)
+{
+ u32 mask = BIT(width) - 1;
+
+ return clk_register_mux_table_scu(dev, name, parent_names, num_parents,
+ flags, reg, shift, mask, clk_mux_flags,
+ NULL, lock, pd_name);
+}
+
+void clk_unregister_mux_scu(struct clk *clk)
+{
+ struct clk_mux_scu *mux;
+ struct clk_hw *hw;
+
+ hw = __clk_get_hw(clk);
+ if (!hw)
+ return;
+
+ mux = to_clk_mux_scu(hw);
+
+ clk_unregister(clk);
+ kfree(mux);
+}
+
+static u8 clk_mux_gpr_scu_get_parent(struct clk_hw *hw)
+{
+ struct clk_mux_gpr_scu *gpr_mux = to_clk_mux_gpr_scu(hw);
+ u32 val = 0;
+
+ if (!ccm_ipc_handle)
+ return 0;
+
+ sc_misc_get_control(ccm_ipc_handle,
+ gpr_mux->rsrc_id, gpr_mux->gpr_id, &val);
+
+ return (u8)val;
+}
+
+static int clk_mux_gpr_scu_set_parent(struct clk_hw *hw, u8 index)
+{
+ struct clk_mux_gpr_scu *gpr_mux = to_clk_mux_gpr_scu(hw);
+
+ if (!ccm_ipc_handle)
+ return -1;
+
+ sc_misc_set_control(ccm_ipc_handle,
+ gpr_mux->rsrc_id, gpr_mux->gpr_id, index);
+
+ return 0;
+}
+
+static const struct clk_ops clk_mux_gpr_scu_ops = {
+ .get_parent = clk_mux_gpr_scu_get_parent,
+ .set_parent = clk_mux_gpr_scu_set_parent,
+};
+
+struct clk *clk_register_mux_gpr_scu(struct device *dev, const char *name,
+ const char **parents, int num_parents, spinlock_t *lock,
+ sc_rsrc_t rsrc_id, sc_ctrl_t gpr_id)
+{
+ struct clk_mux_gpr_scu *gpr_scu_mux;
+ struct clk *clk;
+ struct clk_init_data init;
+
+ if (!imx8_clk_is_resource_owned(rsrc_id)) {
+ pr_debug("skip clk %s rsrc %d not owned\n", name, rsrc_id);
+ return ERR_PTR(-ENODEV);
+ }
+
+ if (rsrc_id >= SC_R_LAST)
+ return NULL;
+
+ if (gpr_id >= SC_C_LAST)
+ return NULL;
+
+ gpr_scu_mux = kzalloc(sizeof(struct clk_mux_gpr_scu), GFP_KERNEL);
+ if (!gpr_scu_mux)
+ return ERR_PTR(-ENOMEM);
+
+ init.name = name;
+ init.ops = &clk_mux_gpr_scu_ops;
+ init.parent_names = parents;
+ init.num_parents = num_parents;
+ init.flags |= CLK_SET_PARENT_NOCACHE;
+
+ gpr_scu_mux->hw.init = &init;
+ gpr_scu_mux->rsrc_id = rsrc_id;
+ gpr_scu_mux->gpr_id = gpr_id;
+
+ clk = clk_register(NULL, &gpr_scu_mux->hw);
+ if (IS_ERR(clk))
+ kfree(gpr_scu_mux);
+
+ return clk;
+}
+
+static u8 clk_mux2_scu_get_parent(struct clk_hw *hw)
+{
+ struct clk_mux2_scu *mux = to_clk_mux2_scu(hw);
+ sc_pm_clk_parent_t parent;
+ sc_err_t ret;
+
+ if (!ccm_ipc_handle)
+ return -EBUSY;
+
+ ret = sc_pm_get_clock_parent(ccm_ipc_handle, mux->rsrc_id,
+ mux->clk_type, &parent);
+ if (ret != SC_ERR_NONE)
+ return -EINVAL;
+
+ return (u8)parent;
+}
+
+static int clk_mux2_scu_set_parent(struct clk_hw *hw, u8 index)
+{
+ struct clk_mux2_scu *mux = to_clk_mux2_scu(hw);
+ sc_err_t ret;
+
+ if (!ccm_ipc_handle)
+ return -EBUSY;
+
+ ret = sc_pm_set_clock_parent(ccm_ipc_handle, mux->rsrc_id,
+ mux->clk_type, index);
+ if (ret != SC_ERR_NONE)
+ return -EINVAL;
+
+ return 0;
+}
+
+static const struct clk_ops clk_mux2_scu_ops = {
+ .get_parent = clk_mux2_scu_get_parent,
+ .set_parent = clk_mux2_scu_set_parent,
+};
+
+
+struct clk *clk_register_mux2_scu(struct device *dev, const char *name,
+ const char **parents, int num_parents,
+ unsigned long flags, sc_rsrc_t rsrc_id,
+ sc_pm_clk_t clk_type)
+{
+ struct clk_mux2_scu *mux;
+ struct clk *clk;
+ struct clk_init_data init;
+
+ if (!imx8_clk_is_resource_owned(rsrc_id)) {
+ pr_debug("skip clk %s rsrc %d not owned\n", name, rsrc_id);
+ return ERR_PTR(-ENODEV);
+ }
+
+ if (rsrc_id >= SC_R_LAST)
+ return ERR_PTR(-EINVAL);
+
+ mux = kzalloc(sizeof(struct clk_mux2_scu), GFP_KERNEL);
+ if (!mux)
+ return ERR_PTR(-ENOMEM);
+
+ init.name = name;
+ init.ops = &clk_mux2_scu_ops;
+ init.parent_names = parents;
+ init.num_parents = num_parents;
+ init.flags = flags |= CLK_SET_PARENT_NOCACHE;
+
+ mux->hw.init = &init;
+ mux->rsrc_id = rsrc_id;
+ mux->clk_type = clk_type;
+
+ clk = clk_register(NULL, &mux->hw);
+ if (IS_ERR(clk))
+ kfree(mux);
+
+ return clk;
+}
diff --git a/drivers/clk/imx/clk-pfd.c b/drivers/clk/imx/clk-pfd.c
index 04a3e78ea1bc..e29bd792522f 100644
--- a/drivers/clk/imx/clk-pfd.c
+++ b/drivers/clk/imx/clk-pfd.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2012 Freescale Semiconductor, Inc.
+ * Copyright 2012-2015 Freescale Semiconductor, Inc.
* Copyright 2012 Linaro Ltd.
*
* The code contained herein is licensed under the GNU General Public
@@ -11,11 +11,14 @@
*/
#include <linux/clk-provider.h>
+#include <linux/imx_sema4.h>
#include <linux/io.h>
#include <linux/slab.h>
#include <linux/err.h>
+#include <soc/imx/src.h>
#include "clk.h"
+
/**
* struct clk_pfd - IMX PFD clock
* @clk_hw: clock source
@@ -38,20 +41,57 @@ struct clk_pfd {
#define CLR 0x8
#define OTG 0xc
-static int clk_pfd_enable(struct clk_hw *hw)
+static void clk_pfd_do_hardware(struct clk_pfd *pfd, bool enable)
+{
+ if (enable)
+ writel_relaxed(1 << ((pfd->idx + 1) * 8 - 1), pfd->reg + CLR);
+ else
+ writel_relaxed(1 << ((pfd->idx + 1) * 8 - 1), pfd->reg + SET);
+}
+
+static void clk_pfd_do_shared_clks(struct clk_hw *hw, bool enable)
{
struct clk_pfd *pfd = to_clk_pfd(hw);
- writel_relaxed(1 << ((pfd->idx + 1) * 8 - 1), pfd->reg + CLR);
+ if (imx_src_is_m4_enabled() && clk_on_imx6sx()) {
+#ifdef CONFIG_SOC_IMX6SX
+ if (!amp_power_mutex || !shared_mem) {
+ if (enable)
+ clk_pfd_do_hardware(pfd, enable);
+ return;
+ }
+
+ imx_sema4_mutex_lock(amp_power_mutex);
+ if (shared_mem->ca9_valid != SHARED_MEM_MAGIC_NUMBER ||
+ shared_mem->cm4_valid != SHARED_MEM_MAGIC_NUMBER) {
+ imx_sema4_mutex_unlock(amp_power_mutex);
+ return;
+ }
+
+ if (!imx_update_shared_mem(hw, enable)) {
+ imx_sema4_mutex_unlock(amp_power_mutex);
+ return;
+ }
+
+ clk_pfd_do_hardware(pfd, enable);
+
+ imx_sema4_mutex_unlock(amp_power_mutex);
+#endif
+ } else {
+ clk_pfd_do_hardware(pfd, enable);
+ }
+}
+
+static int clk_pfd_enable(struct clk_hw *hw)
+{
+ clk_pfd_do_shared_clks(hw, true);
return 0;
}
static void clk_pfd_disable(struct clk_hw *hw)
{
- struct clk_pfd *pfd = to_clk_pfd(hw);
-
- writel_relaxed(1 << ((pfd->idx + 1) * 8 - 1), pfd->reg + SET);
+ clk_pfd_do_shared_clks(hw, false);
}
static unsigned long clk_pfd_recalc_rate(struct clk_hw *hw,
diff --git a/drivers/clk/imx/clk-pfdv2.c b/drivers/clk/imx/clk-pfdv2.c
new file mode 100644
index 000000000000..b342f3c3d843
--- /dev/null
+++ b/drivers/clk/imx/clk-pfdv2.c
@@ -0,0 +1,207 @@
+/*
+ * Copyright 2016 Freescale Semiconductor, Inc.
+ *
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <linux/err.h>
+#include <linux/iopoll.h>
+
+#include "clk.h"
+
+/**
+ * struct clk_pfdv2 - IMX PFD clock
+ * @clk_hw: clock source
+ * @reg: PFD register address
+ * @gate_bit: Gate bit offset
+ * @vld_bit: Valid bit offset
+ * @frac_off: PLL Fractional Divider offset
+ */
+
+struct clk_pfdv2 {
+ struct clk_hw hw;
+ void __iomem *reg;
+ u32 gate_bit;
+ u32 vld_bit;
+ u8 frac_off;
+};
+
+#define to_clk_pfdv2(_hw) container_of(_hw, struct clk_pfdv2, hw)
+
+#define CLK_PFDV2_FRAC_MASK 0x3f
+
+#define LOCK_TIMEOUT_US USEC_PER_MSEC
+
+static DEFINE_SPINLOCK(pfd_lock);
+
+static int clk_pfdv2_wait(struct clk_pfdv2 *pfd)
+{
+ u32 val;
+
+ return readl_poll_timeout(pfd->reg, val, val & pfd->vld_bit,
+ 0, LOCK_TIMEOUT_US);
+}
+
+static int clk_pfd_enable(struct clk_hw *hw)
+{
+ struct clk_pfdv2 *pfd = to_clk_pfdv2(hw);
+ unsigned long flags;
+ u32 val;
+
+ spin_lock_irqsave(&pfd_lock, flags);
+ val = readl_relaxed(pfd->reg);
+ val &= ~pfd->gate_bit;
+ writel_relaxed(val, pfd->reg);
+ spin_unlock_irqrestore(&pfd_lock, flags);
+
+ return clk_pfdv2_wait(pfd);
+}
+
+static void clk_pfd_disable(struct clk_hw *hw)
+{
+ struct clk_pfdv2 *pfd = to_clk_pfdv2(hw);
+ unsigned long flags;
+ u32 val;
+
+ spin_lock_irqsave(&pfd_lock, flags);
+ val = readl_relaxed(pfd->reg);
+ val |= pfd->gate_bit;
+ writel_relaxed(val, pfd->reg);
+ spin_unlock_irqrestore(&pfd_lock, flags);
+}
+
+static unsigned long clk_pfd_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ struct clk_pfdv2 *pfd = to_clk_pfdv2(hw);
+ u64 tmp = parent_rate;
+ u8 frac;
+
+ frac = (readl_relaxed(pfd->reg) >> pfd->frac_off)
+ & CLK_PFDV2_FRAC_MASK;
+
+ if (!frac) {
+ pr_debug("clk_pfdv2: %s invalid pfd frac value 0\n",
+ clk_hw_get_name(hw));
+ return 0;
+ }
+
+ tmp *= 18;
+ do_div(tmp, frac);
+
+ return tmp;
+}
+
+static long clk_pfd_round_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long *prate)
+{
+ u64 tmp = *prate;
+ u8 frac;
+
+ tmp = tmp * 18 + rate / 2;
+ do_div(tmp, rate);
+ frac = tmp;
+ if (frac < 12)
+ frac = 12;
+ else if (frac > 35)
+ frac = 35;
+ tmp = *prate;
+ tmp *= 18;
+ do_div(tmp, frac);
+
+ return tmp;
+}
+
+static int clk_pfd_is_enabled(struct clk_hw *hw)
+{
+ struct clk_pfdv2 *pfd = to_clk_pfdv2(hw);
+
+ if (readl_relaxed(pfd->reg) & pfd->gate_bit)
+ return 0;
+
+ return 1;
+}
+
+static int clk_pfd_set_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long parent_rate)
+{
+ struct clk_pfdv2 *pfd = to_clk_pfdv2(hw);
+ unsigned long flags;
+ u64 tmp = parent_rate;
+ u32 val;
+ u8 frac;
+
+ if (!rate)
+ return -EINVAL;
+
+ /* PFD can NOT change rate without gating */
+ WARN_ON(clk_pfd_is_enabled(hw));
+
+ tmp = tmp * 18 + rate / 2;
+ do_div(tmp, rate);
+ frac = tmp;
+ if (frac < 12)
+ frac = 12;
+ else if (frac > 35)
+ frac = 35;
+
+ spin_lock_irqsave(&pfd_lock, flags);
+ val = readl_relaxed(pfd->reg);
+ val &= ~(CLK_PFDV2_FRAC_MASK << pfd->frac_off);
+ val |= frac << pfd->frac_off;
+ writel_relaxed(val, pfd->reg);
+ spin_unlock_irqrestore(&pfd_lock, flags);
+
+ return 0;
+}
+
+static const struct clk_ops clk_pfdv2_ops = {
+ .enable = clk_pfd_enable,
+ .disable = clk_pfd_disable,
+ .recalc_rate = clk_pfd_recalc_rate,
+ .round_rate = clk_pfd_round_rate,
+ .set_rate = clk_pfd_set_rate,
+ .is_enabled = clk_pfd_is_enabled,
+};
+
+struct clk *imx_clk_pfdv2(const char *name, const char *parent_name,
+ void __iomem *reg, u8 idx)
+{
+ struct clk_pfdv2 *pfd;
+ struct clk *clk;
+ struct clk_init_data init;
+
+ WARN_ON(idx > 3);
+
+ pfd = kzalloc(sizeof(*pfd), GFP_KERNEL);
+ if (!pfd)
+ return ERR_PTR(-ENOMEM);
+
+ pfd->reg = reg;
+ pfd->gate_bit = 1 << ((idx + 1) * 8 - 1);
+ pfd->vld_bit = pfd->gate_bit >> 1;
+ pfd->frac_off = idx * 8;
+
+ init.name = name;
+ init.ops = &clk_pfdv2_ops;
+ init.parent_names = &parent_name;
+ init.num_parents = 1;
+ init.flags = CLK_SET_RATE_GATE;
+
+ pfd->hw.init = &init;
+
+ clk = clk_register(NULL, &pfd->hw);
+ if (IS_ERR(clk))
+ kfree(pfd);
+
+ return clk;
+}
diff --git a/drivers/clk/imx/clk-pllv3.c b/drivers/clk/imx/clk-pllv3.c
index 9af62ee8f347..cebd6a37bc8e 100644
--- a/drivers/clk/imx/clk-pllv3.c
+++ b/drivers/clk/imx/clk-pllv3.c
@@ -11,15 +11,20 @@
*/
#include <linux/clk-provider.h>
-#include <linux/delay.h>
+#include <linux/imx_sema4.h>
#include <linux/io.h>
#include <linux/slab.h>
#include <linux/jiffies.h>
#include <linux/err.h>
+#include <soc/imx/src.h>
#include "clk.h"
-#define PLL_NUM_OFFSET 0x10
-#define PLL_DENOM_OFFSET 0x20
+#define PLL_NUM_OFFSET 0x10
+#define PLL_DENOM_OFFSET 0x20
+#define PLL_AV_IMX7_NUM_OFFSET 0x20
+#define PLL_AV_IMX7_DENOM_OFFSET 0x30
+#define PLL_PLL2_NUM_OFFSET 0x20
+#define PLL_PLL2_DENOM_OFFSET 0x30
#define PLL_VF610_NUM_OFFSET 0x20
#define PLL_VF610_DENOM_OFFSET 0x30
@@ -49,6 +54,8 @@ struct clk_pllv3 {
u32 div_mask;
u32 div_shift;
unsigned long ref_clock;
+ u32 num_offset;
+ u32 denom_offset;
};
#define to_clk_pllv3(_hw) container_of(_hw, struct clk_pllv3, hw)
@@ -68,38 +75,79 @@ static int clk_pllv3_wait_lock(struct clk_pllv3 *pll)
break;
if (time_after(jiffies, timeout))
break;
- usleep_range(50, 500);
} while (1);
return readl_relaxed(pll->base) & BM_PLL_LOCK ? 0 : -ETIMEDOUT;
}
-static int clk_pllv3_prepare(struct clk_hw *hw)
+static int clk_pllv3_do_hardware(struct clk_hw *hw, bool enable)
{
struct clk_pllv3 *pll = to_clk_pllv3(hw);
+ int ret;
u32 val;
val = readl_relaxed(pll->base);
- if (pll->powerup_set)
- val |= pll->power_bit;
- else
- val &= ~pll->power_bit;
- writel_relaxed(val, pll->base);
+ if (enable) {
+ if (pll->powerup_set)
+ val |= pll->power_bit;
+ else
+ val &= ~pll->power_bit;
+ writel_relaxed(val, pll->base);
+
+ ret = clk_pllv3_wait_lock(pll);
+ if (ret)
+ return ret;
+ } else {
+ if (pll->powerup_set)
+ val &= ~pll->power_bit;
+ else
+ val |= pll->power_bit;
+ writel_relaxed(val, pll->base);
+ }
- return clk_pllv3_wait_lock(pll);
+ return 0;
}
-static void clk_pllv3_unprepare(struct clk_hw *hw)
+static void clk_pllv3_do_shared_clks(struct clk_hw *hw, bool enable)
{
- struct clk_pllv3 *pll = to_clk_pllv3(hw);
- u32 val;
+ if (imx_src_is_m4_enabled() && clk_on_imx6sx()) {
+#ifdef CONFIG_SOC_IMX6SX
+ if (!amp_power_mutex || !shared_mem) {
+ if (enable)
+ clk_pllv3_do_hardware(hw, enable);
+ return;
+ }
+
+ imx_sema4_mutex_lock(amp_power_mutex);
+ if (shared_mem->ca9_valid != SHARED_MEM_MAGIC_NUMBER ||
+ shared_mem->cm4_valid != SHARED_MEM_MAGIC_NUMBER) {
+ imx_sema4_mutex_unlock(amp_power_mutex);
+ return;
+ }
+
+ if (!imx_update_shared_mem(hw, enable)) {
+ imx_sema4_mutex_unlock(amp_power_mutex);
+ return;
+ }
+ clk_pllv3_do_hardware(hw, enable);
+
+ imx_sema4_mutex_unlock(amp_power_mutex);
+#endif
+ } else {
+ clk_pllv3_do_hardware(hw, enable);
+ }
+}
- val = readl_relaxed(pll->base);
- if (pll->powerup_set)
- val &= ~pll->power_bit;
- else
- val |= pll->power_bit;
- writel_relaxed(val, pll->base);
+static int clk_pllv3_prepare(struct clk_hw *hw)
+{
+ clk_pllv3_do_shared_clks(hw, true);
+
+ return 0;
+}
+
+static void clk_pllv3_unprepare(struct clk_hw *hw)
+{
+ clk_pllv3_do_shared_clks(hw, false);
}
static int clk_pllv3_is_prepared(struct clk_hw *hw)
@@ -219,8 +267,8 @@ static unsigned long clk_pllv3_av_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
struct clk_pllv3 *pll = to_clk_pllv3(hw);
- u32 mfn = readl_relaxed(pll->base + PLL_NUM_OFFSET);
- u32 mfd = readl_relaxed(pll->base + PLL_DENOM_OFFSET);
+ u32 mfn = readl_relaxed(pll->base + pll->num_offset);
+ u32 mfd = readl_relaxed(pll->base + pll->denom_offset);
u32 div = readl_relaxed(pll->base) & pll->div_mask;
u64 temp64 = (u64)parent_rate;
@@ -250,7 +298,7 @@ static long clk_pllv3_av_round_rate(struct clk_hw *hw, unsigned long rate,
mfd = parent_rate;
div = rate / parent_rate;
- temp64 = (u64) (rate - div * parent_rate);
+ temp64 = rate - div * parent_rate;
temp64 *= mfd;
do_div(temp64, parent_rate);
mfn = temp64;
@@ -280,7 +328,7 @@ static int clk_pllv3_av_set_rate(struct clk_hw *hw, unsigned long rate,
mfd = parent_rate;
div = rate / parent_rate;
- temp64 = (u64) (rate - div * parent_rate);
+ temp64 = rate - div * parent_rate;
temp64 *= mfd;
do_div(temp64, parent_rate);
mfn = temp64;
@@ -289,8 +337,8 @@ static int clk_pllv3_av_set_rate(struct clk_hw *hw, unsigned long rate,
val &= ~pll->div_mask;
val |= div;
writel_relaxed(val, pll->base);
- writel_relaxed(mfn, pll->base + PLL_NUM_OFFSET);
- writel_relaxed(mfd, pll->base + PLL_DENOM_OFFSET);
+ writel_relaxed(mfn, pll->base + pll->num_offset);
+ writel_relaxed(mfd, pll->base + pll->denom_offset);
return clk_pllv3_wait_lock(pll);
}
@@ -412,6 +460,28 @@ static const struct clk_ops clk_pllv3_enet_ops = {
.recalc_rate = clk_pllv3_enet_recalc_rate,
};
+static unsigned long clk_pllv3_pll2_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_shift) & pll->div_mask;
+ u32 mfn = readl_relaxed(pll->base + pll->num_offset);
+ u32 mfd = readl_relaxed(pll->base + pll->denom_offset);
+ u64 temp64 = (u64)parent_rate;
+
+ temp64 *= mfn;
+ do_div(temp64, mfd);
+
+ return (parent_rate * ((div == 1) ? 22 : 20)) + (u32)temp64;
+}
+
+static const struct clk_ops clk_pllv3_pll2_ops = {
+ .prepare = clk_pllv3_prepare,
+ .unprepare = clk_pllv3_unprepare,
+ .is_prepared = clk_pllv3_is_prepared,
+ .recalc_rate = clk_pllv3_pll2_recalc_rate,
+};
+
struct clk *imx_clk_pllv3(enum imx_pllv3_type type, const char *name,
const char *parent_name, void __iomem *base,
u32 div_mask)
@@ -426,6 +496,8 @@ struct clk *imx_clk_pllv3(enum imx_pllv3_type type, const char *name,
return ERR_PTR(-ENOMEM);
pll->power_bit = BM_PLL_POWER;
+ pll->num_offset = PLL_NUM_OFFSET;
+ pll->denom_offset = PLL_DENOM_OFFSET;
switch (type) {
case IMX_PLLV3_SYS:
@@ -434,12 +506,21 @@ struct clk *imx_clk_pllv3(enum imx_pllv3_type type, const char *name,
case IMX_PLLV3_SYS_VF610:
ops = &clk_pllv3_vf610_ops;
break;
+ case IMX_PLLV3_PLL2:
+ pll->num_offset = PLL_PLL2_NUM_OFFSET;
+ pll->denom_offset = PLL_PLL2_DENOM_OFFSET;
+ ops = &clk_pllv3_pll2_ops;
+ break;
case IMX_PLLV3_USB_VF610:
pll->div_shift = 1;
case IMX_PLLV3_USB:
ops = &clk_pllv3_ops;
pll->powerup_set = true;
break;
+ case IMX_PLLV3_AV_IMX7:
+ pll->num_offset = PLL_AV_IMX7_NUM_OFFSET;
+ pll->denom_offset = PLL_AV_IMX7_DENOM_OFFSET;
+ /* fall through */
case IMX_PLLV3_AV:
ops = &clk_pllv3_av_ops;
break;
diff --git a/drivers/clk/imx/clk-pllv4.c b/drivers/clk/imx/clk-pllv4.c
new file mode 100644
index 000000000000..0aa1d01d7dc4
--- /dev/null
+++ b/drivers/clk/imx/clk-pllv4.c
@@ -0,0 +1,215 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017-2018 NXP.
+ *
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/err.h>
+#include <linux/iopoll.h>
+#include <linux/slab.h>
+
+#include "clk.h"
+
+/* PLL Control Status Register (xPLLCSR) */
+#define PLL_CSR_OFFSET 0x0
+#define PLL_VLD BIT(24)
+#define PLL_EN BIT(0)
+#define BP_PLL_MULT 16
+#define BM_PLL_MULT (0x7f << 16)
+#define PLL_CFG_OFFSET 0x08
+#define PLL_NUM_OFFSET 0x10
+#define PLL_DENOM_OFFSET 0x14
+
+struct clk_pllv4 {
+ struct clk_hw hw;
+ void __iomem *base;
+};
+
+/* Valid PLL MULT Table */
+static const int pllv4_mult_table[] = {33, 27, 22, 20, 17, 16};
+
+#define to_clk_pllv4(__hw) container_of(__hw, struct clk_pllv4, hw)
+
+#define LOCK_TIMEOUT_US USEC_PER_MSEC
+
+static inline int clk_pllv4_wait_lock(struct clk_pllv4 *pll)
+{
+ u32 csr;
+
+ return readl_poll_timeout(pll->base + PLL_CSR_OFFSET,
+ csr, csr & PLL_VLD, 0, LOCK_TIMEOUT_US);
+}
+
+
+static unsigned long clk_pllv4_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ struct clk_pllv4 *pll = to_clk_pllv4(hw);
+ u32 mfn = readl_relaxed(pll->base + PLL_NUM_OFFSET);
+ u32 mfd = readl_relaxed(pll->base + PLL_DENOM_OFFSET);
+ u32 mult = (readl_relaxed(pll->base + PLL_CFG_OFFSET)
+ & BM_PLL_MULT) >> BP_PLL_MULT;
+ u64 temp64 = (u64)parent_rate;
+
+ temp64 *= mfn;
+ do_div(temp64, mfd);
+
+ return (parent_rate * mult) + (u32)temp64;
+}
+
+static long clk_pllv4_round_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long *prate)
+{
+ unsigned long parent_rate = *prate;
+ unsigned long round_rate;
+ u32 mfn, mfd = 1000000;
+ bool found = false;
+ u64 temp64, i;
+
+ for (i = 0; i < ARRAY_SIZE(pllv4_mult_table); i++) {
+ round_rate = parent_rate * pllv4_mult_table[i];
+ if (rate >= round_rate) {
+ found = true;
+ break;
+ }
+ }
+
+ if (!found) {
+ pr_warn("%s: unable to round rate %lu prate %lu\n",
+ clk_hw_get_name(hw), rate, parent_rate);
+ return 0;
+ }
+
+ temp64 = (u64) (rate - round_rate);
+ temp64 *= mfd;
+ do_div(temp64, parent_rate);
+ mfn = temp64;
+
+ /*
+ * NOTE: The value of numerator must always be configured to be
+ * less than the value of the denominator. If we can't get a proper
+ * pair of mfn/mfd, we simply return the round_rate without using
+ * the frac part.
+ */
+ if (mfn >= mfd)
+ return round_rate;
+
+ return round_rate + parent_rate / mfd * mfn;
+}
+
+static bool clk_pllv4_is_valid_mult(unsigned int mult)
+{
+ int i;
+
+ /* check if mult is in valid MULT table */
+ for (i = 0; i < ARRAY_SIZE(pllv4_mult_table); i++) {
+ if (pllv4_mult_table[i] == mult)
+ return true;
+ }
+
+ return false;
+}
+
+static int clk_pllv4_set_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long parent_rate)
+{
+ struct clk_pllv4 *pll = to_clk_pllv4(hw);
+ u32 val, mult;
+ u32 mfn, mfd = 1000000;
+ u64 temp64;
+
+ mult = rate / parent_rate;
+
+ if (!clk_pllv4_is_valid_mult(mult))
+ return -EINVAL;
+
+ temp64 = (u64) (rate - mult * parent_rate);
+ temp64 *= mfd;
+ do_div(temp64, parent_rate);
+ mfn = temp64;
+
+ val = readl_relaxed(pll->base + PLL_CFG_OFFSET);
+ val &= ~BM_PLL_MULT;
+ val |= mult << BP_PLL_MULT;
+ writel_relaxed(val, pll->base + PLL_CFG_OFFSET);
+ writel_relaxed(mfn, pll->base + PLL_NUM_OFFSET);
+ writel_relaxed(mfd, pll->base + PLL_DENOM_OFFSET);
+
+ return 0;
+}
+
+static int clk_pllv4_enable(struct clk_hw *hw)
+{
+ u32 val;
+ struct clk_pllv4 *pll = to_clk_pllv4(hw);
+
+ val = readl_relaxed(pll->base);
+ val |= PLL_EN;
+ writel_relaxed(val, pll->base);
+
+ return clk_pllv4_wait_lock(pll);
+}
+
+static void clk_pllv4_disable(struct clk_hw *hw)
+{
+ u32 val;
+ struct clk_pllv4 *pll = to_clk_pllv4(hw);
+
+ val = readl_relaxed(pll->base);
+ val &= ~PLL_EN;
+ writel_relaxed(val, pll->base);
+}
+
+static int clk_pllv4_is_enabled(struct clk_hw *hw)
+{
+ struct clk_pllv4 *pll = to_clk_pllv4(hw);
+
+ if (readl_relaxed(pll->base) & PLL_EN)
+ return 1;
+
+ return 0;
+}
+
+static const struct clk_ops clk_pllv4_ops = {
+ .recalc_rate = clk_pllv4_recalc_rate,
+ .round_rate = clk_pllv4_round_rate,
+ .set_rate = clk_pllv4_set_rate,
+ .enable = clk_pllv4_enable,
+ .disable = clk_pllv4_disable,
+ .is_enabled = clk_pllv4_is_enabled,
+};
+
+struct clk *imx_clk_pllv4(const char *name, const char *parent_name,
+ void __iomem *base)
+{
+ struct clk_pllv4 *pll;
+ struct clk *clk;
+ struct clk_init_data init;
+
+ pll = kzalloc(sizeof(*pll), GFP_KERNEL);
+ if (!pll)
+ return ERR_PTR(-ENOMEM);
+
+ pll->base = base;
+ init.name = name;
+ init.ops = &clk_pllv4_ops;
+ init.parent_names = &parent_name;
+ init.num_parents = 1;
+ init.flags = CLK_SET_RATE_GATE;
+
+ pll->hw.init = &init;
+
+ clk = clk_register(NULL, &pll->hw);
+ if (IS_ERR(clk))
+ kfree(pll);
+
+ return clk;
+}
diff --git a/drivers/clk/imx/clk-pllv5.c b/drivers/clk/imx/clk-pllv5.c
new file mode 100644
index 000000000000..c45704c7942e
--- /dev/null
+++ b/drivers/clk/imx/clk-pllv5.c
@@ -0,0 +1,199 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ *
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/err.h>
+#include <linux/slab.h>
+
+#include "clk.h"
+
+#define PLL_EN BIT(0)
+#define BP_PLL_DIV 16
+#define BM_PLL_DIV (0x7 << 16)
+#define PLL_CFG_OFFSET 0x08
+
+struct clk_pllv5 {
+ struct clk_hw hw;
+ void __iomem *base;
+ u32 div_mask;
+ u32 div_shift;
+ u32 cfg_offset;
+};
+
+#define to_clk_pllv5(__hw) container_of(__hw, struct clk_pllv5, hw)
+
+static unsigned long clk_pllv5_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ struct clk_pllv5 *pll = to_clk_pllv5(hw);
+ u32 val = (readl_relaxed(pll->base + pll->cfg_offset) & pll->div_mask) >> pll->div_shift;
+ u32 div;
+
+ switch (val) {
+ case 1:
+ div = 15;
+ break;
+ case 2:
+ div = 16;
+ break;
+ case 3:
+ div = 20;
+ break;
+ case 4:
+ div = 22;
+ break;
+ case 5:
+ div = 25;
+ break;
+ case 6:
+ div = 30;
+ break;
+ default:
+ div = 20;
+ break;
+ }
+
+ return parent_rate * div;
+}
+
+static long clk_pllv5_round_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long *prate)
+{
+ unsigned long parent_rate = *prate;
+ u32 div;
+
+ div = rate / parent_rate;
+
+ if (div == 15 || div == 16 ||
+ div == 20 || div == 22 ||
+ div == 25 || div == 30)
+ return parent_rate * div;
+ else
+ return parent_rate * 20;
+}
+
+static int clk_pllv5_set_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long parent_rate)
+{
+ struct clk_pllv5 *pll = to_clk_pllv5(hw);
+ unsigned long min_rate = parent_rate * 15;
+ unsigned long max_rate = parent_rate * 30;
+ u32 val, div, reg;
+
+ if (rate < min_rate || rate > max_rate)
+ return -EINVAL;
+
+ div = rate / parent_rate;
+
+ switch (div) {
+ case 15:
+ val = 1;
+ break;
+ case 16:
+ val = 2;
+ break;
+ case 20:
+ val = 3;
+ break;
+ case 22:
+ val = 4;
+ break;
+ case 25:
+ val = 5;
+ break;
+ case 30:
+ val = 6;
+ break;
+ default:
+ val = 3;
+ break;
+ }
+
+ reg = readl_relaxed(pll->base + pll->cfg_offset);
+ reg &= ~pll->div_mask;
+ reg |= (val << pll->div_shift);
+ writel_relaxed(val, pll->base + pll->cfg_offset);
+
+ return 0;
+}
+
+static int clk_pllv5_enable(struct clk_hw *hw)
+{
+ u32 val;
+ struct clk_pllv5 *pll = to_clk_pllv5(hw);
+
+ val = readl_relaxed(pll->base);
+ val |= PLL_EN;
+ writel_relaxed(val, pll->base);
+
+ return 0;
+}
+
+static void clk_pllv5_disable(struct clk_hw *hw)
+{
+ u32 val;
+ struct clk_pllv5 *pll = to_clk_pllv5(hw);
+
+ val = readl_relaxed(pll->base);
+ val &= ~PLL_EN;
+ writel_relaxed(val, pll->base);
+}
+
+static int clk_pllv5_is_enabled(struct clk_hw *hw)
+{
+ struct clk_pllv5 *pll = to_clk_pllv5(hw);
+
+ if (readl_relaxed(pll->base) & PLL_EN)
+ return 0;
+
+ return 1;
+}
+
+static const struct clk_ops clk_pllv5_ops = {
+ .recalc_rate = clk_pllv5_recalc_rate,
+ .round_rate = clk_pllv5_round_rate,
+ .set_rate = clk_pllv5_set_rate,
+ .enable = clk_pllv5_enable,
+ .disable = clk_pllv5_disable,
+ .is_enabled = clk_pllv5_is_enabled,
+};
+
+struct clk *imx_clk_pllv5(const char *name, const char *parent_name,
+ void __iomem *base)
+{
+ struct clk_pllv5 *pll;
+ struct clk *clk;
+ struct clk_init_data init;
+
+ pll = kzalloc(sizeof(*pll), GFP_KERNEL);
+ if (!pll)
+ return ERR_PTR(-ENOMEM);
+
+ pll->base = base;
+ pll->div_mask = BM_PLL_DIV;
+ pll->div_shift = BP_PLL_DIV;
+ pll->cfg_offset = PLL_CFG_OFFSET;
+
+ init.name = name;
+ init.ops = &clk_pllv5_ops;
+ init.parent_names = &parent_name;
+ init.num_parents = 1;
+
+ pll->hw.init = &init;
+
+ clk = clk_register(NULL, &pll->hw);
+ if (IS_ERR(clk))
+ kfree(pll);
+
+ return clk;
+}
+
diff --git a/drivers/clk/imx/clk-sccg-pll.c b/drivers/clk/imx/clk-sccg-pll.c
new file mode 100644
index 000000000000..ff288ffe5065
--- /dev/null
+++ b/drivers/clk/imx/clk-sccg-pll.c
@@ -0,0 +1,540 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright 2018 NXP.
+ *
+ * This driver supports the SCCG plls found in the imx8m SOCs
+ *
+ * Documentation for this SCCG pll can be found at:
+ * https://www.nxp.com/docs/en/reference-manual/IMX8MDQLQRM.pdf#page=834
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/err.h>
+#include <linux/iopoll.h>
+#include <linux/slab.h>
+#include <linux/bitfield.h>
+
+#include "clk.h"
+
+/* PLL CFGs */
+#define PLL_CFG0 0x0
+#define PLL_CFG1 0x4
+#define PLL_CFG2 0x8
+
+#define PLL_DIVF1_MASK GENMASK(18, 13)
+#define PLL_DIVF2_MASK GENMASK(12, 7)
+
+#define PLL_DIVR1_MASK GENMASK(27, 25)
+#define PLL_DIVR2_MASK GENMASK(24, 19)
+#define PLL_DIVQ_MASK GENMASK(6, 1)
+
+#define PLL_LOCK_MASK BIT(31)
+#define PLL_PD_MASK BIT(7)
+
+/* These are the specification limits for the SSCG PLL */
+#define PLL_REF_MIN_FREQ 25000000
+#define PLL_REF_MAX_FREQ 235000000
+
+#define PLL_STAGE1_MIN_FREQ 1600000000
+#define PLL_STAGE1_MAX_FREQ 2400000000
+
+#define PLL_STAGE1_REF_MIN_FREQ 25000000
+#define PLL_STAGE1_REF_MAX_FREQ 54000000
+
+#define PLL_STAGE2_MIN_FREQ 1200000000
+#define PLL_STAGE2_MAX_FREQ 2400000000
+
+#define PLL_STAGE2_REF_MIN_FREQ 54000000
+#define PLL_STAGE2_REF_MAX_FREQ 75000000
+
+#define PLL_OUT_MIN_FREQ 20000000
+#define PLL_OUT_MAX_FREQ 1200000000
+
+#define PLL_DIVR1_MAX 7
+#define PLL_DIVR2_MAX 63
+#define PLL_DIVF1_MAX 63
+#define PLL_DIVF2_MAX 63
+#define PLL_DIVQ_MAX 63
+
+#define PLL_BYPASS_NONE 0x0
+#define PLL_BYPASS1 0x2
+#define PLL_BYPASS2 0x1
+
+#define SSCG_PLL_BYPASS1_MASK BIT(5)
+#define SSCG_PLL_BYPASS2_MASK BIT(4)
+#define SSCG_PLL_BYPASS_MASK GENMASK(5, 4)
+
+#define PLL_SCCG_LOCK_TIMEOUT 70
+
+struct clk_sccg_pll_setup {
+ int divr1, divf1;
+ int divr2, divf2;
+ int divq;
+ int bypass;
+
+ unsigned long vco1;
+ unsigned long vco2;
+ unsigned long fout;
+ unsigned long ref;
+ unsigned long ref_div1;
+ unsigned long ref_div2;
+ unsigned long fout_request;
+ int fout_error;
+};
+
+struct clk_sccg_pll {
+ struct clk_hw hw;
+ const struct clk_ops ops;
+
+ void __iomem *base;
+
+ struct clk_sccg_pll_setup setup;
+
+ u8 parent;
+ u8 bypass1;
+ u8 bypass2;
+};
+
+#define to_clk_sccg_pll(_hw) container_of(_hw, struct clk_sccg_pll, hw)
+
+static int clk_sccg_pll_wait_lock(struct clk_sccg_pll *pll)
+{
+ u32 val;
+
+ val = readl_relaxed(pll->base + PLL_CFG0);
+
+ /* don't wait for lock if all plls are bypassed */
+ if (!(val & SSCG_PLL_BYPASS2_MASK))
+ return readl_poll_timeout(pll->base, val, val & PLL_LOCK_MASK,
+ 0, PLL_SCCG_LOCK_TIMEOUT);
+
+ return 0;
+}
+
+static int clk_sccg_pll2_check_match(struct clk_sccg_pll_setup *setup,
+ struct clk_sccg_pll_setup *temp_setup)
+{
+ int new_diff = temp_setup->fout - temp_setup->fout_request;
+ int diff = temp_setup->fout_error;
+
+ if (abs(diff) > abs(new_diff)) {
+ temp_setup->fout_error = new_diff;
+ memcpy(setup, temp_setup, sizeof(struct clk_sccg_pll_setup));
+
+ if (temp_setup->fout_request == temp_setup->fout)
+ return 0;
+ }
+ return -1;
+}
+
+static int clk_sccg_divq_lookup(struct clk_sccg_pll_setup *setup,
+ struct clk_sccg_pll_setup *temp_setup)
+{
+ int ret = -EINVAL;
+
+ for (temp_setup->divq = 0; temp_setup->divq <= PLL_DIVQ_MAX;
+ temp_setup->divq++) {
+ temp_setup->vco2 = temp_setup->vco1;
+ do_div(temp_setup->vco2, temp_setup->divr2 + 1);
+ temp_setup->vco2 *= 2;
+ temp_setup->vco2 *= temp_setup->divf2 + 1;
+ if (temp_setup->vco2 >= PLL_STAGE2_MIN_FREQ &&
+ temp_setup->vco2 <= PLL_STAGE2_MAX_FREQ) {
+ temp_setup->fout = temp_setup->vco2;
+ do_div(temp_setup->fout, 2 * (temp_setup->divq + 1));
+
+ ret = clk_sccg_pll2_check_match(setup, temp_setup);
+ if (!ret) {
+ temp_setup->bypass = PLL_BYPASS1;
+ return ret;
+ }
+ }
+ }
+
+ return ret;
+}
+
+static int clk_sccg_divf2_lookup(struct clk_sccg_pll_setup *setup,
+ struct clk_sccg_pll_setup *temp_setup)
+{
+ int ret = -EINVAL;
+
+ for (temp_setup->divf2 = 0; temp_setup->divf2 <= PLL_DIVF2_MAX;
+ temp_setup->divf2++) {
+ ret = clk_sccg_divq_lookup(setup, temp_setup);
+ if (!ret)
+ return ret;
+ }
+
+ return ret;
+}
+
+static int clk_sccg_divr2_lookup(struct clk_sccg_pll_setup *setup,
+ struct clk_sccg_pll_setup *temp_setup)
+{
+ int ret = -EINVAL;
+
+ for (temp_setup->divr2 = 0; temp_setup->divr2 <= PLL_DIVR2_MAX;
+ temp_setup->divr2++) {
+ temp_setup->ref_div2 = temp_setup->vco1;
+ do_div(temp_setup->ref_div2, temp_setup->divr2 + 1);
+ if (temp_setup->ref_div2 >= PLL_STAGE2_REF_MIN_FREQ &&
+ temp_setup->ref_div2 <= PLL_STAGE2_REF_MAX_FREQ) {
+ ret = clk_sccg_divf2_lookup(setup, temp_setup);
+ if (!ret)
+ return ret;
+ }
+ }
+
+ return ret;
+}
+
+static int clk_sccg_pll2_find_setup(struct clk_sccg_pll_setup *setup,
+ struct clk_sccg_pll_setup *temp_setup,
+ long ref)
+{
+
+ int ret = -EINVAL;
+
+ if (ref < PLL_STAGE1_MIN_FREQ || ref > PLL_STAGE1_MAX_FREQ)
+ return ret;
+
+ temp_setup->vco1 = ref;
+
+ ret = clk_sccg_divr2_lookup(setup, temp_setup);
+ return ret;
+}
+
+static int clk_sccg_divf1_lookup(struct clk_sccg_pll_setup *setup,
+ struct clk_sccg_pll_setup *temp_setup)
+{
+ int ret = -EINVAL;
+
+ for (temp_setup->divf1 = 0; temp_setup->divf1 <= PLL_DIVF1_MAX;
+ temp_setup->divf1++) {
+ long vco1 = temp_setup->ref;
+
+ do_div(vco1, temp_setup->divr1 + 1);
+ vco1 *= 2;
+ vco1 *= temp_setup->divf1 + 1;
+
+ ret = clk_sccg_pll2_find_setup(setup, temp_setup, vco1);
+ if (!ret) {
+ temp_setup->bypass = PLL_BYPASS_NONE;
+ return ret;
+ }
+ }
+ return ret;
+}
+
+static int clk_sccg_divr1_lookup(struct clk_sccg_pll_setup *setup,
+ struct clk_sccg_pll_setup *temp_setup)
+{
+ int ret = -EINVAL;
+
+ for (temp_setup->divr1 = 0; temp_setup->divr1 <= PLL_DIVR1_MAX;
+ temp_setup->divr1++) {
+ temp_setup->ref_div1 = temp_setup->ref;
+ do_div(temp_setup->ref_div1, temp_setup->divr1 + 1);
+ if (temp_setup->ref_div1 >= PLL_STAGE1_REF_MIN_FREQ &&
+ temp_setup->ref_div1 <= PLL_STAGE1_REF_MAX_FREQ) {
+ ret = clk_sccg_divf1_lookup(setup, temp_setup);
+ if (!ret)
+ return ret;
+ }
+ }
+ return ret;
+}
+
+static int clk_sccg_pll1_find_setup(struct clk_sccg_pll_setup *setup,
+ struct clk_sccg_pll_setup *temp_setup,
+ long ref)
+{
+
+ int ret = -EINVAL;
+
+ if (ref < PLL_REF_MIN_FREQ || ref > PLL_REF_MAX_FREQ)
+ return ret;
+
+ temp_setup->ref = ref;
+
+ ret = clk_sccg_divr1_lookup(setup, temp_setup);
+
+ return ret;
+}
+
+static int clk_sccg_pll_find_setup(struct clk_sccg_pll_setup *setup,
+ unsigned long prate,
+ unsigned long rate, int try_bypass)
+{
+ struct clk_sccg_pll_setup temp_setup;
+ int ret = -EINVAL;
+
+ memset(&temp_setup, 0, sizeof(struct clk_sccg_pll_setup));
+ memset(setup, 0, sizeof(struct clk_sccg_pll_setup));
+
+ temp_setup.fout_error = PLL_OUT_MAX_FREQ;
+ temp_setup.fout_request = rate;
+
+ switch (try_bypass) {
+
+ case PLL_BYPASS2:
+ if (prate == rate) {
+ setup->bypass = PLL_BYPASS2;
+ setup->fout = rate;
+ ret = 0;
+ }
+ break;
+
+ case PLL_BYPASS1:
+ ret = clk_sccg_pll2_find_setup(setup, &temp_setup, prate);
+ break;
+
+ case PLL_BYPASS_NONE:
+ ret = clk_sccg_pll1_find_setup(setup, &temp_setup, prate);
+ break;
+ }
+
+ return ret;
+}
+
+
+static int clk_sccg_pll_is_prepared(struct clk_hw *hw)
+{
+ struct clk_sccg_pll *pll = to_clk_sccg_pll(hw);
+
+ u32 val = readl_relaxed(pll->base + PLL_CFG0);
+
+ return (val & PLL_PD_MASK) ? 0 : 1;
+}
+
+static int clk_sccg_pll_prepare(struct clk_hw *hw)
+{
+ struct clk_sccg_pll *pll = to_clk_sccg_pll(hw);
+ u32 val;
+
+ val = readl_relaxed(pll->base + PLL_CFG0);
+ val &= ~PLL_PD_MASK;
+ writel_relaxed(val, pll->base + PLL_CFG0);
+
+ return clk_sccg_pll_wait_lock(pll);
+}
+
+static void clk_sccg_pll_unprepare(struct clk_hw *hw)
+{
+ struct clk_sccg_pll *pll = to_clk_sccg_pll(hw);
+ u32 val;
+
+ val = readl_relaxed(pll->base + PLL_CFG0);
+ val |= PLL_PD_MASK;
+ writel_relaxed(val, pll->base + PLL_CFG0);
+}
+
+static unsigned long clk_sccg_pll_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ struct clk_sccg_pll *pll = to_clk_sccg_pll(hw);
+ u32 val, divr1, divf1, divr2, divf2, divq;
+ u64 temp64;
+
+ val = readl_relaxed(pll->base + PLL_CFG2);
+ divr1 = FIELD_GET(PLL_DIVR1_MASK, val);
+ divr2 = FIELD_GET(PLL_DIVR2_MASK, val);
+ divf1 = FIELD_GET(PLL_DIVF1_MASK, val);
+ divf2 = FIELD_GET(PLL_DIVF2_MASK, val);
+ divq = FIELD_GET(PLL_DIVQ_MASK, val);
+
+ temp64 = parent_rate;
+
+ val = clk_readl(pll->base + PLL_CFG0);
+ if (val & SSCG_PLL_BYPASS2_MASK) {
+ temp64 = parent_rate;
+ } else if (val & SSCG_PLL_BYPASS1_MASK) {
+ temp64 *= divf2;
+ do_div(temp64, (divr2 + 1) * (divq + 1));
+ } else {
+ temp64 *= 2;
+ temp64 *= (divf1 + 1) * (divf2 + 1);
+ do_div(temp64, (divr1 + 1) * (divr2 + 1) * (divq + 1));
+ }
+
+ return (unsigned long)temp64;
+}
+
+static int clk_sccg_pll_set_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long parent_rate)
+{
+ struct clk_sccg_pll *pll = to_clk_sccg_pll(hw);
+ struct clk_sccg_pll_setup *setup = &pll->setup;
+ u32 val;
+
+ /* set bypass here too since the parent might be the same */
+ val = clk_readl(pll->base + PLL_CFG0);
+ val &= ~SSCG_PLL_BYPASS_MASK;
+ val |= FIELD_PREP(SSCG_PLL_BYPASS_MASK, setup->bypass);
+ clk_writel(val, pll->base + PLL_CFG0);
+
+ val = readl_relaxed(pll->base + PLL_CFG2);
+ val &= ~(PLL_DIVF1_MASK | PLL_DIVF2_MASK);
+ val &= ~(PLL_DIVR1_MASK | PLL_DIVR2_MASK | PLL_DIVQ_MASK);
+ val |= FIELD_PREP(PLL_DIVF1_MASK, setup->divf1);
+ val |= FIELD_PREP(PLL_DIVF2_MASK, setup->divf2);
+ val |= FIELD_PREP(PLL_DIVR1_MASK, setup->divr1);
+ val |= FIELD_PREP(PLL_DIVR2_MASK, setup->divr2);
+ val |= FIELD_PREP(PLL_DIVQ_MASK, setup->divq);
+ writel_relaxed(val, pll->base + PLL_CFG2);
+
+ return clk_sccg_pll_wait_lock(pll);
+}
+
+static u8 clk_sccg_pll_get_parent(struct clk_hw *hw)
+{
+ struct clk_sccg_pll *pll = to_clk_sccg_pll(hw);
+ u32 val;
+ u8 ret = pll->parent;
+
+ val = clk_readl(pll->base + PLL_CFG0);
+ if (val & SSCG_PLL_BYPASS2_MASK)
+ ret = pll->bypass2;
+ else if (val & SSCG_PLL_BYPASS1_MASK)
+ ret = pll->bypass1;
+ return ret;
+}
+
+static int clk_sccg_pll_set_parent(struct clk_hw *hw, u8 index)
+{
+ struct clk_sccg_pll *pll = to_clk_sccg_pll(hw);
+ u32 val;
+
+ val = clk_readl(pll->base + PLL_CFG0);
+ val &= ~SSCG_PLL_BYPASS_MASK;
+ val |= FIELD_PREP(SSCG_PLL_BYPASS_MASK, pll->setup.bypass);
+ clk_writel(val, pll->base + PLL_CFG0);
+
+ return 0;
+}
+
+static int __clk_sccg_pll_determine_rate(struct clk_hw *hw,
+ struct clk_rate_request *req,
+ unsigned long min,
+ unsigned long max,
+ unsigned long rate,
+ int bypass)
+{
+ struct clk_sccg_pll *pll = to_clk_sccg_pll(hw);
+ struct clk_sccg_pll_setup *setup = &pll->setup;
+ struct clk_hw *parent_hw = NULL;
+ int bypass_parent_index;
+ int ret = -EINVAL;
+
+ req->max_rate = max;
+ req->min_rate = min;
+
+ switch (bypass) {
+ case PLL_BYPASS2:
+ bypass_parent_index = pll->bypass2;
+ break;
+ case PLL_BYPASS1:
+ bypass_parent_index = pll->bypass1;
+ break;
+ default:
+ bypass_parent_index = pll->parent;
+ break;
+ }
+
+ parent_hw = clk_hw_get_parent_by_index(hw, bypass_parent_index);
+ ret = __clk_determine_rate(parent_hw, req);
+ if (!ret) {
+ ret = clk_sccg_pll_find_setup(setup, req->rate,
+ rate, bypass);
+ }
+
+ req->best_parent_hw = parent_hw;
+ req->best_parent_rate = req->rate;
+ req->rate = setup->fout;
+
+ return ret;
+}
+
+static int clk_sccg_pll_determine_rate(struct clk_hw *hw,
+ struct clk_rate_request *req)
+{
+ struct clk_sccg_pll *pll = to_clk_sccg_pll(hw);
+ struct clk_sccg_pll_setup *setup = &pll->setup;
+ unsigned long rate = req->rate;
+ unsigned long min = req->min_rate;
+ unsigned long max = req->max_rate;
+ int ret = -EINVAL;
+
+ if (rate < PLL_OUT_MIN_FREQ || rate > PLL_OUT_MAX_FREQ)
+ return ret;
+
+ ret = __clk_sccg_pll_determine_rate(hw, req, req->rate, req->rate,
+ rate, PLL_BYPASS2);
+ if (!ret)
+ return ret;
+
+ ret = __clk_sccg_pll_determine_rate(hw, req, PLL_STAGE1_REF_MIN_FREQ,
+ PLL_STAGE1_REF_MAX_FREQ, rate,
+ PLL_BYPASS1);
+ if (!ret)
+ return ret;
+
+ ret = __clk_sccg_pll_determine_rate(hw, req, PLL_REF_MIN_FREQ,
+ PLL_REF_MAX_FREQ, rate,
+ PLL_BYPASS_NONE);
+ if (!ret)
+ return ret;
+
+ if (setup->fout >= min && setup->fout <= max)
+ ret = 0;
+
+ return ret;
+}
+
+static const struct clk_ops clk_sccg_pll_ops = {
+ .prepare = clk_sccg_pll_prepare,
+ .unprepare = clk_sccg_pll_unprepare,
+ .is_prepared = clk_sccg_pll_is_prepared,
+ .recalc_rate = clk_sccg_pll_recalc_rate,
+ .set_rate = clk_sccg_pll_set_rate,
+ .set_parent = clk_sccg_pll_set_parent,
+ .get_parent = clk_sccg_pll_get_parent,
+ .determine_rate = clk_sccg_pll_determine_rate,
+};
+
+struct clk *imx_clk_sccg_pll(const char *name,
+ const char * const *parent_names,
+ u8 num_parents,
+ u8 parent, u8 bypass1, u8 bypass2,
+ void __iomem *base,
+ unsigned long flags)
+{
+ struct clk_sccg_pll *pll;
+ struct clk *clk;
+ struct clk_init_data init;
+
+ pll = kzalloc(sizeof(*pll), GFP_KERNEL);
+ if (!pll)
+ return ERR_PTR(-ENOMEM);
+
+ pll->parent = parent;
+ pll->bypass1 = bypass1;
+ pll->bypass2 = bypass2;
+
+ pll->base = base;
+ init.name = name;
+ init.ops = &clk_sccg_pll_ops;
+
+ init.flags = flags;
+ init.parent_names = parent_names;
+ init.num_parents = num_parents;
+
+ pll->hw.init = &init;
+
+ clk = clk_register(NULL, &pll->hw);
+ if (IS_ERR(clk))
+ kfree(pll);
+
+ return clk;
+}
diff --git a/drivers/clk/imx/clk.c b/drivers/clk/imx/clk.c
index 9074e6974b6d..a6103b1832dd 100644
--- a/drivers/clk/imx/clk.c
+++ b/drivers/clk/imx/clk.c
@@ -8,6 +8,8 @@
DEFINE_SPINLOCK(imx_ccm_lock);
+bool uart_from_osc;
+
void __init imx_check_clocks(struct clk *clks[], unsigned int count)
{
unsigned i;
@@ -102,6 +104,9 @@ void __init imx_register_uart_clocks(struct clk ** const clks[])
static int __init imx_clk_disable_uart(void)
{
+ if (imx_src_is_m4_enabled())
+ return 0;
+
if (imx_keep_uart_clocks && imx_uart_clocks) {
int i;
@@ -112,3 +117,11 @@ static int __init imx_clk_disable_uart(void)
return 0;
}
late_initcall_sync(imx_clk_disable_uart);
+
+static int __init setup_uart_clk(char *uart_rate)
+{
+ uart_from_osc = true;
+ return 1;
+}
+__setup("uart_from_osc", setup_uart_clk);
+
diff --git a/drivers/clk/imx/clk.h b/drivers/clk/imx/clk.h
index b03fbd502528..6b80ae82e073 100644
--- a/drivers/clk/imx/clk.h
+++ b/drivers/clk/imx/clk.h
@@ -4,6 +4,8 @@
#include <linux/spinlock.h>
#include <linux/clk-provider.h>
+#include <linux/clk.h>
+#include <soc/imx/src.h>
extern spinlock_t imx_ccm_lock;
@@ -11,6 +13,10 @@ void imx_check_clocks(struct clk *clks[], unsigned int count);
void imx_register_uart_clocks(struct clk ** const clks[]);
extern void imx_cscmr1_fixup(u32 *val);
+extern struct imx_sema4_mutex *amp_power_mutex;
+extern struct imx_shared_mem *shared_mem;
+extern bool uart_from_osc;
+extern const struct clk_ops clk_frac_divider_ops;
enum imx_pllv1_type {
IMX_PLLV1_IMX1,
@@ -21,12 +27,48 @@ enum imx_pllv1_type {
IMX_PLLV1_IMX35,
};
+enum imx_int_pll_type {
+ PLL_1416X,
+ PLL_1443X,
+};
+
+enum imx_sccg_pll_type {
+ SCCG_PLL1,
+ SCCG_PLL2,
+};
+
+/* NOTE: Rate table should be kept sorted in descending order. */
+struct imx_int_pll_rate_table {
+ unsigned int rate;
+ unsigned int pdiv;
+ unsigned int mdiv;
+ unsigned int sdiv;
+ unsigned int kdiv;
+};
+
+struct imx_int_pll_clk {
+ enum imx_int_pll_type type;
+ const struct imx_int_pll_rate_table *rate_table;
+ int flags;
+};
+
+struct clk *imx_clk_int_pll(const char *name, const char *parent_name, void __iomem *base, const struct imx_int_pll_clk *pll_clk);
+
struct clk *imx_clk_pllv1(enum imx_pllv1_type type, const char *name,
const char *parent, void __iomem *base);
struct clk *imx_clk_pllv2(const char *name, const char *parent,
void __iomem *base);
+struct clk *imx_clk_frac_pll(const char *name, const char *parent_name, void __iomem *base);
+
+struct clk *imx_clk_sccg_pll(const char *name,
+ const char * const *parent_names,
+ u8 num_parents,
+ u8 parent, u8 bypass1, u8 bypass2,
+ void __iomem *base,
+ unsigned long flags);
+
enum imx_pllv3_type {
IMX_PLLV3_GENERIC,
IMX_PLLV3_SYS,
@@ -37,11 +79,54 @@ enum imx_pllv3_type {
IMX_PLLV3_ENET_IMX7,
IMX_PLLV3_SYS_VF610,
IMX_PLLV3_DDR_IMX7,
+ IMX_PLLV3_AV_IMX7,
+ IMX_PLLV3_PLL2,
+};
+
+/*
+ * frac_divider, found on i.MX7ULP PCC module.
+ * the output clock of the fractional divider is:
+ * Divider output clock = Input clock * (FRAC + 1)
+ * / (DIV + 1)
+ */
+struct clk_frac_divider {
+ struct clk_hw hw;
+ void __iomem *reg;
+ u8 mshift;
+ u8 mwidth;
+ u32 mmask;
+ u8 nshift;
+ u8 nwidth;
+ u32 nmask;
+};
+
+#define MAX_SHARED_CLK_NUMBER 100
+#define SHARED_MEM_MAGIC_NUMBER 0x12345678
+#define MCC_POWER_SHMEM_NUMBER (6)
+
+struct imx_shared_clk {
+ struct clk *self;
+ struct clk *parent;
+ void *m4_clk;
+ void *m4_clk_parent;
+ u8 ca9_enabled;
+ u8 cm4_enabled;
+};
+
+struct imx_shared_mem {
+ u32 ca9_valid;
+ u32 cm4_valid;
+ struct imx_shared_clk imx_clk[MAX_SHARED_CLK_NUMBER];
};
struct clk *imx_clk_pllv3(enum imx_pllv3_type type, const char *name,
const char *parent_name, void __iomem *base, u32 div_mask);
+struct clk *imx_clk_pllv4(const char *name,
+ const char *parent_name, void __iomem *base);
+struct clk *imx_clk_pllv5(const char *name, const char *parent_name,
+ void __iomem *base);
+
struct clk *clk_register_gate2(struct device *dev, const char *name,
const char *parent_name, unsigned long flags,
void __iomem *reg, u8 bit_idx, u8 cgr_val,
@@ -54,6 +139,33 @@ struct clk * imx_obtain_fixed_clock(
struct clk *imx_clk_gate_exclusive(const char *name, const char *parent,
void __iomem *reg, u8 shift, u32 exclusive_mask);
+static inline void imx_clk_prepare_enable(struct clk *clk)
+{
+ int ret = clk_prepare_enable(clk);
+
+ if (ret)
+ pr_err("failed to prepare and enable clk %s: %d\n",
+ __clk_get_name(clk), ret);
+}
+
+static inline void imx_clk_set_parent(struct clk *clk, struct clk *parent)
+{
+ int ret = clk_set_parent(clk, parent);
+
+ if (ret)
+ pr_err("failed to set parent of clk %s to %s: %d\n",
+ __clk_get_name(clk), __clk_get_name(parent), ret);
+}
+
+static inline void imx_clk_set_rate(struct clk *clk, unsigned long rate)
+{
+ int ret = clk_set_rate(clk, rate);
+
+ if (ret)
+ pr_err("failed to set rate of clk %s to %ld: %d\n",
+ __clk_get_name(clk), rate, ret);
+}
+
struct clk *imx_clk_pfd(const char *name, const char *parent_name,
void __iomem *reg, u8 idx);
@@ -65,6 +177,9 @@ struct clk *imx_clk_busy_mux(const char *name, void __iomem *reg, u8 shift,
u8 width, void __iomem *busy_reg, u8 busy_shift,
const char * const *parent_names, int num_parents);
+struct clk *imx_clk_busy_gate(const char *name, const char *parent,
+ void __iomem *reg, u8 shift);
+
struct clk *imx_clk_fixup_divider(const char *name, const char *parent,
void __iomem *reg, u8 shift, u8 width,
void (*fixup)(u32 *val));
@@ -97,10 +212,19 @@ static inline struct clk *imx_clk_fixed_factor(const char *name,
static inline struct clk *imx_clk_divider(const char *name, const char *parent,
void __iomem *reg, u8 shift, u8 width)
{
- return clk_register_divider(NULL, name, parent, CLK_SET_RATE_PARENT,
+ return clk_register_divider(NULL, name, parent,
+ CLK_SET_RATE_PARENT | CLK_SET_RATE_GATE,
reg, shift, width, 0, &imx_ccm_lock);
}
+static inline struct clk *imx_clk_divider2(const char *name, const char *parent,
+ void __iomem *reg, u8 shift, u8 width)
+{
+ return clk_register_divider(NULL, name, parent,
+ CLK_SET_RATE_PARENT | CLK_SET_RATE_GATE | CLK_OPS_PARENT_ENABLE,
+ reg, shift, width, CLK_DIVIDER_ROUND_CLOSEST, &imx_ccm_lock);
+}
+
static inline struct clk *imx_clk_divider_flags(const char *name,
const char *parent, void __iomem *reg, u8 shift, u8 width,
unsigned long flags)
@@ -109,14 +233,6 @@ static inline struct clk *imx_clk_divider_flags(const char *name,
reg, shift, width, 0, &imx_ccm_lock);
}
-static inline struct clk *imx_clk_divider2(const char *name, const char *parent,
- void __iomem *reg, u8 shift, u8 width)
-{
- return clk_register_divider(NULL, name, parent,
- CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE,
- reg, shift, width, 0, &imx_ccm_lock);
-}
-
static inline struct clk *imx_clk_gate(const char *name, const char *parent,
void __iomem *reg, u8 shift)
{
@@ -134,7 +250,15 @@ static inline struct clk *imx_clk_gate_dis(const char *name, const char *parent,
static inline struct clk *imx_clk_gate2(const char *name, const char *parent,
void __iomem *reg, u8 shift)
{
- return clk_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT, reg,
+ return clk_register_gate2(NULL, name, parent,
+ CLK_SET_RATE_PARENT | CLK_SET_RATE_GATE, reg,
+ shift, 0x3, 0, &imx_ccm_lock, NULL);
+}
+
+static inline struct clk *imx_clk_gate2_flags(const char *name, const char *parent,
+ void __iomem *reg, u8 shift, unsigned long flags)
+{
+ return clk_register_gate2(NULL, name, parent, flags, reg,
shift, 0x3, 0, &imx_ccm_lock, NULL);
}
@@ -142,7 +266,8 @@ static inline struct clk *imx_clk_gate2_shared(const char *name,
const char *parent, void __iomem *reg, u8 shift,
unsigned int *share_count)
{
- return clk_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT, reg,
+ return clk_register_gate2(NULL, name, parent,
+ CLK_SET_RATE_PARENT | CLK_SET_RATE_GATE, reg,
shift, 0x3, 0, &imx_ccm_lock, share_count);
}
@@ -151,8 +276,8 @@ static inline struct clk *imx_clk_gate2_shared2(const char *name,
unsigned int *share_count)
{
return clk_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT |
- CLK_OPS_PARENT_ENABLE, reg, shift, 0x3, 0,
- &imx_ccm_lock, share_count);
+ CLK_SET_RATE_GATE | CLK_OPS_PARENT_ENABLE,
+ reg, shift, 0x3, 0, &imx_ccm_lock, share_count);
}
static inline struct clk *imx_clk_gate2_cgr(const char *name,
@@ -165,7 +290,17 @@ static inline struct clk *imx_clk_gate2_cgr(const char *name,
static inline struct clk *imx_clk_gate3(const char *name, const char *parent,
void __iomem *reg, u8 shift)
{
- return clk_register_gate(NULL, name, parent,
+ /*
+ * per design team's suggestion, clk root is NOT consuming
+ * much power, and clk root enable/disable does NOT have domain
+ * control, so they suggest to leave clk root always on when
+ * M4 is enabled.
+ */
+ if (imx_src_is_m4_enabled())
+ return clk_register_fixed_factor(NULL, name, parent,
+ CLK_SET_RATE_PARENT, 1, 1);
+ else
+ return clk_register_gate(NULL, name, parent,
CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE,
reg, shift, 0, &imx_ccm_lock);
}
@@ -174,17 +309,25 @@ static inline struct clk *imx_clk_gate4(const char *name, const char *parent,
void __iomem *reg, u8 shift)
{
return clk_register_gate2(NULL, name, parent,
- CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE,
+ CLK_SET_RATE_PARENT | CLK_SET_RATE_GATE | CLK_OPS_PARENT_ENABLE,
reg, shift, 0x3, 0, &imx_ccm_lock, NULL);
}
+static inline struct clk *imx_clk_mux_bus(const char *name, void __iomem *reg,
+ u8 shift, u8 width, const char **parents, int num_parents)
+{
+ return clk_register_mux(NULL, name, parents, num_parents,
+ CLK_SET_RATE_NO_REPARENT,
+ reg, shift, width, 0, &imx_ccm_lock);
+}
+
static inline struct clk *imx_clk_mux(const char *name, void __iomem *reg,
u8 shift, u8 width, const char * const *parents,
int num_parents)
{
return clk_register_mux(NULL, name, parents, num_parents,
- CLK_SET_RATE_NO_REPARENT, reg, shift,
- width, 0, &imx_ccm_lock);
+ CLK_SET_RATE_NO_REPARENT | CLK_SET_PARENT_GATE,
+ reg, shift, width, 0, &imx_ccm_lock);
}
static inline struct clk *imx_clk_mux2(const char *name, void __iomem *reg,
@@ -202,12 +345,58 @@ static inline struct clk *imx_clk_mux_flags(const char *name,
unsigned long flags)
{
return clk_register_mux(NULL, name, parents, num_parents,
- flags | CLK_SET_RATE_NO_REPARENT, reg, shift, width, 0,
- &imx_ccm_lock);
+ flags | CLK_SET_RATE_NO_REPARENT | CLK_SET_PARENT_GATE,
+ reg, shift, width, 0, &imx_ccm_lock);
+}
+
+static inline struct clk *imx_clk_mux_flags_bus(const char *name,
+ void __iomem *reg, u8 shift, u8 width, const char **paretns,
+ int num_parents, unsigned long flags)
+{
+ return clk_register_mux(NULL, name, paretns, num_parents,
+ flags | CLK_SET_RATE_NO_REPARENT, reg, shift,
+ width, 0, &imx_ccm_lock);
+}
+
+static inline struct clk *imx_clk_mux_glitchless(const char *name,
+ void __iomem *reg, u8 shift, u8 width, const char **parents,
+ int num_parents)
+{
+ return clk_register_mux(NULL, name, parents, num_parents,
+ CLK_SET_RATE_NO_REPARENT, reg, shift,
+ width, 0, &imx_ccm_lock);
}
struct clk *imx_clk_cpu(const char *name, const char *parent_name,
struct clk *div, struct clk *mux, struct clk *pll,
struct clk *step);
+int imx_update_shared_mem(struct clk_hw *hw, bool enable);
+
+static inline int clk_on_imx6sx(void)
+{
+ return of_machine_is_compatible("fsl,imx6sx");
+}
+
+struct clk *imx7ulp_clk_composite(const char *name, const char **parent_name,
+ int num_parents, bool mux_present, bool rate_present,
+ bool gate_present, void __iomem *reg);
+
+struct clk *imx_clk_pfdv2(const char *name, const char *parent_name,
+ void __iomem *reg, u8 idx);
+
+struct clk *imx8m_clk_composite_flags(const char *name, const char **parent_names,
+ int num_parents, void __iomem *reg, unsigned long flags);
+
+#define __imx8m_clk_composite(name, parent_names, reg, flags) \
+ imx8m_clk_composite_flags(name, parent_names, \
+ ARRAY_SIZE(parent_names), reg, \
+ flags | CLK_SET_RATE_NO_REPARENT | CLK_OPS_PARENT_ENABLE)
+
+#define imx8m_clk_composite(name, parent_names, reg) \
+ __imx8m_clk_composite(name, parent_names, reg, 0)
+
+#define imx8m_clk_composite_critical(name, parent_names, reg) \
+ __imx8m_clk_composite(name, parent_names, reg, CLK_IS_CRITICAL)
+
#endif
diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index cc6062049170..40d676b91dda 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -595,7 +595,7 @@ config H8300_TPU
config CLKSRC_IMX_GPT
bool "Clocksource using i.MX GPT" if COMPILE_TEST
- depends on ARM && CLKDEV_LOOKUP
+ depends on (ARM || ARM64) && CLKDEV_LOOKUP
select CLKSRC_MMIO
config CLKSRC_IMX_TPM
@@ -606,6 +606,10 @@ config CLKSRC_IMX_TPM
Enable this option to use IMX Timer/PWM Module (TPM) timer as
clocksource.
+config CLKSRC_IMX_SYS_CNT
+ bool "Clocksource using i.MX system counter timer"
+ depends on ARM_ARCH_TIMER
+
config CLKSRC_ST_LPC
bool "Low power clocksource found in the LPC" if COMPILE_TEST
select TIMER_OF if OF
diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
index 72711f1491e3..e7dbf43eecaf 100644
--- a/drivers/clocksource/Makefile
+++ b/drivers/clocksource/Makefile
@@ -69,6 +69,7 @@ obj-$(CONFIG_CLKSRC_MIPS_GIC) += mips-gic-timer.o
obj-$(CONFIG_CLKSRC_TANGO_XTAL) += tango_xtal.o
obj-$(CONFIG_CLKSRC_IMX_GPT) += timer-imx-gpt.o
obj-$(CONFIG_CLKSRC_IMX_TPM) += timer-imx-tpm.o
+obj-$(CONFIG_CLKSRC_IMX_SYS_CNT) += timer-imx-sysctr.o
obj-$(CONFIG_ASM9260_TIMER) += asm9260_timer.o
obj-$(CONFIG_H8300_TMR8) += h8300_timer8.o
obj-$(CONFIG_H8300_TMR16) += h8300_timer16.o
diff --git a/drivers/clocksource/timer-imx-gpt.c b/drivers/clocksource/timer-imx-gpt.c
index 6ec6d79b237c..85ef1674d62f 100644
--- a/drivers/clocksource/timer-imx-gpt.c
+++ b/drivers/clocksource/timer-imx-gpt.c
@@ -157,21 +157,28 @@ static u64 notrace mxc_read_sched_clock(void)
return sched_clock_reg ? readl_relaxed(sched_clock_reg) : 0;
}
+#ifndef CONFIG_ARM64
static struct delay_timer imx_delay_timer;
static unsigned long imx_read_current_timer(void)
{
return readl_relaxed(sched_clock_reg);
}
+#endif
static int __init mxc_clocksource_init(struct imx_timer *imxtm)
{
unsigned int c = clk_get_rate(imxtm->clk_per);
void __iomem *reg = imxtm->base + imxtm->gpt->reg_tcn;
+ if (c == 0)
+ return -EINVAL;
+
+#ifndef CONFIG_ARM64
imx_delay_timer.read_current_timer = &imx_read_current_timer;
imx_delay_timer.freq = c;
register_current_timer_delay(&imx_delay_timer);
+#endif
sched_clock_reg = reg;
@@ -489,12 +496,16 @@ static int __init mxc_timer_init_dt(struct device_node *np, enum imx_gpt_type t
return -ENOMEM;
imxtm->base = of_iomap(np, 0);
- if (!imxtm->base)
+ if (!imxtm->base) {
+ kfree(imxtm);
return -ENXIO;
+ }
imxtm->irq = irq_of_parse_and_map(np, 0);
- if (imxtm->irq <= 0)
+ if (imxtm->irq <= 0) {
+ kfree(imxtm);
return -EINVAL;
+ }
imxtm->clk_ipg = of_clk_get_by_name(np, "ipg");
@@ -545,6 +556,19 @@ static int __init imx6dl_timer_init_dt(struct device_node *np)
return mxc_timer_init_dt(np, GPT_TYPE_IMX6DL);
}
+#ifdef CONFIG_ARM64
+static int __init imx8qxp_timer_init(void)
+{
+ struct device_node *np;
+
+ np = of_find_compatible_node(NULL, NULL, "fsl,imx8qxp-gpt");
+ if (!np)
+ return -ENOENT;
+
+ return mxc_timer_init_dt(np, GPT_TYPE_IMX6DL);
+}
+#endif
+
TIMER_OF_DECLARE(imx1_timer, "fsl,imx1-gpt", imx1_timer_init_dt);
TIMER_OF_DECLARE(imx21_timer, "fsl,imx21-gpt", imx21_timer_init_dt);
TIMER_OF_DECLARE(imx27_timer, "fsl,imx27-gpt", imx21_timer_init_dt);
@@ -556,4 +580,10 @@ TIMER_OF_DECLARE(imx53_timer, "fsl,imx53-gpt", imx31_timer_init_dt);
TIMER_OF_DECLARE(imx6q_timer, "fsl,imx6q-gpt", imx31_timer_init_dt);
TIMER_OF_DECLARE(imx6dl_timer, "fsl,imx6dl-gpt", imx6dl_timer_init_dt);
TIMER_OF_DECLARE(imx6sl_timer, "fsl,imx6sl-gpt", imx6dl_timer_init_dt);
+TIMER_OF_DECLARE(imx6sll_timer, "fsl,imx6sll-gpt", imx6dl_timer_init_dt);
TIMER_OF_DECLARE(imx6sx_timer, "fsl,imx6sx-gpt", imx6dl_timer_init_dt);
+TIMER_OF_DECLARE(imx6ul_timer, "fsl,imx6ul-gpt", imx6dl_timer_init_dt);
+TIMER_OF_DECLARE(mx7d_timer, "fsl,imx7d-gpt", imx6dl_timer_init_dt);
+#ifdef CONFIG_ARM64
+subsys_initcall(imx8qxp_timer_init);
+#endif
diff --git a/drivers/clocksource/timer-imx-sysctr.c b/drivers/clocksource/timer-imx-sysctr.c
new file mode 100644
index 000000000000..7c4d4ec54540
--- /dev/null
+++ b/drivers/clocksource/timer-imx-sysctr.c
@@ -0,0 +1,187 @@
+/*
+ * Copyright 2017 NXP
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ */
+
+#include <linux/interrupt.h>
+#include <linux/clockchips.h>
+#include <linux/clocksource.h>
+#include <linux/delay.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/sched_clock.h>
+
+#define CNTCV_LO 0x8
+#define CNTCV_HI 0xc
+#define CMPCV_LO 0x20
+#define CMPCV_HI 0x24
+#define CMPCR 0x2c
+
+#define SYS_CTR_EN 0x1
+#define SYS_CTR_IRQ_MASK 0x2
+
+static void __iomem *sys_ctr_rd_base;
+static void __iomem *sys_ctr_cmp_base;
+static struct clock_event_device clockevent_sysctr;
+
+static inline void sysctr_timer_enable(bool enable)
+{
+ u32 val;
+
+ val = readl(sys_ctr_cmp_base + CMPCR);
+ val &= ~SYS_CTR_EN;
+ if (enable)
+ val |= SYS_CTR_EN;
+
+ writel(val, sys_ctr_cmp_base + CMPCR);
+}
+
+static void sysctr_irq_acknowledge(void)
+{
+ u32 val;
+
+ /* clear th enable bit(EN=0) to clear the ISTAT */
+ val = readl(sys_ctr_cmp_base + CMPCR);
+ val &= ~SYS_CTR_EN;
+ writel(val, sys_ctr_cmp_base + CMPCR);
+}
+
+static inline u64 sysctr_read_counter(void)
+{
+ u32 cnt_hi, tmp_hi, cnt_lo;
+
+ do {
+ cnt_hi = readl_relaxed(sys_ctr_rd_base + CNTCV_HI);
+ cnt_lo = readl_relaxed(sys_ctr_rd_base + CNTCV_LO);
+ tmp_hi = readl_relaxed(sys_ctr_rd_base + CNTCV_HI);
+ } while (tmp_hi != cnt_hi);
+
+ return ((u64) cnt_hi << 32) | cnt_lo;
+}
+
+static u64 notrace sysctr_read_sched_clock(void)
+{
+ return sysctr_read_counter();
+}
+
+static u64 sysctr_clocksourc_read(struct clocksource *cs)
+{
+ return sysctr_read_counter();
+}
+
+static int __init sysctr_clocksource_init(unsigned int rate)
+{
+ sched_clock_register(sysctr_read_sched_clock, 56, rate);
+ return clocksource_mmio_init(sys_ctr_rd_base, "imx sysctr",
+ rate, 200, 56, sysctr_clocksourc_read);
+}
+
+static int sysctr_set_next_event(unsigned long delta,
+ struct clock_event_device *evt)
+{
+ u32 cmp_hi, cmp_lo;
+ u64 next;
+
+ sysctr_timer_enable(false);
+
+ next = sysctr_read_counter();
+
+ next += delta;
+
+ cmp_hi = (next >> 32) & 0x00fffff;
+ cmp_lo = next & 0xffffffff;
+
+ writel_relaxed(cmp_hi, sys_ctr_cmp_base + CMPCV_HI);
+ writel_relaxed(cmp_lo, sys_ctr_cmp_base + CMPCV_LO);
+
+ sysctr_timer_enable(true);
+
+ return 0;
+}
+
+static int sysctr_set_state_oneshot(struct clock_event_device *evt)
+{
+ /* enable timer */
+ sysctr_timer_enable(true);
+
+ return 0;
+}
+
+static int sysctr_set_state_shutdown(struct clock_event_device *evt)
+{
+ /* disable the timer */
+ sysctr_timer_enable(false);
+
+ return 0;
+}
+
+static irqreturn_t sysctr_timer_interrupt(int irq, void *dev_id)
+{
+ struct clock_event_device *evt = &clockevent_sysctr;
+
+ sysctr_irq_acknowledge();
+
+ evt->event_handler(evt);
+
+ return IRQ_HANDLED;
+}
+
+static struct clock_event_device clockevent_sysctr = {
+ .name = "i.MX system counter timer",
+ .features = CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_DYNIRQ,
+ .set_state_oneshot = sysctr_set_state_oneshot,
+ .set_next_event = sysctr_set_next_event,
+ .set_state_shutdown = sysctr_set_state_shutdown,
+ .rating = 200,
+};
+
+static struct irqaction sysctr_timer_irq = {
+ .name = "iMX system counter timer",
+ .flags = IRQF_TIMER | IRQF_IRQPOLL,
+ .handler = sysctr_timer_interrupt,
+ .dev_id = &clockevent_sysctr,
+};
+
+static int __init sysctr_clockevent_init(unsigned long rate, int irq)
+{
+ setup_irq(irq, &sysctr_timer_irq);
+
+ clockevent_sysctr.cpumask = cpumask_of(0);
+ clockevent_sysctr.irq = irq;
+ clockevents_config_and_register(&clockevent_sysctr,
+ rate, 0xff, 0x7fffffff);
+
+ return 0;
+}
+
+static int __init sysctr_timer_init(struct device_node *np)
+{
+ u32 rate;
+ int irq;
+
+ pr_info("system counter timer init\n");
+ sys_ctr_rd_base = of_iomap(np, 0);
+ BUG_ON(!sys_ctr_rd_base);
+
+ sys_ctr_cmp_base = of_iomap(np, 1);
+ BUG_ON(!sys_ctr_cmp_base);
+
+ /*
+ * the purpose of this driver is to provide a global timer,
+ * So only use one compare frame, request frame0's irq only.
+ */
+ irq = irq_of_parse_and_map(np, 0);
+
+ if (of_property_read_u32(np, "clock-frequency", &rate))
+ return -EINVAL;
+
+ sysctr_clocksource_init(rate);
+ sysctr_clockevent_init(rate, irq);
+
+ return 0;
+}
+CLOCKSOURCE_OF_DECLARE(imx8m, "nxp,sysctr-timer", sysctr_timer_init);
diff --git a/drivers/cpufreq/Kconfig b/drivers/cpufreq/Kconfig
index d8addbce40bc..84a050cb0be6 100644
--- a/drivers/cpufreq/Kconfig
+++ b/drivers/cpufreq/Kconfig
@@ -104,6 +104,16 @@ config CPU_FREQ_DEFAULT_GOV_SCHEDUTIL
have a look at the help section of that governor. The fallback
governor will be 'performance'.
+config CPU_FREQ_DEFAULT_GOV_INTERACTIVE
+ bool "interactive"
+ select CPU_FREQ_GOV_INTERACTIVE
+ select CPU_FREQ_GOV_PERFORMANCE
+ help
+ Use the CPUFreq governor 'interactive' as default. This allows
+ you to get a full dynamic cpu frequency capable system by simply
+ loading your cpufreq low-level hardware driver, using the
+ 'interactive' governor for latency-sensitive workloads.
+
endchoice
config CPU_FREQ_GOV_PERFORMANCE
@@ -202,6 +212,26 @@ config CPU_FREQ_GOV_SCHEDUTIL
If in doubt, say N.
+config CPU_FREQ_GOV_INTERACTIVE
+ tristate "'interactive' cpufreq policy governor"
+ depends on CPU_FREQ
+ select CPU_FREQ_GOV_ATTR_SET
+ select IRQ_WORK
+ help
+ 'interactive' - This driver adds a dynamic cpufreq policy governor
+ designed for latency-sensitive workloads.
+
+ This governor attempts to reduce the latency of clock
+ increases so that the system is more responsive to
+ interactive workloads.
+
+ To compile this driver as a module, choose M here: the
+ module will be called cpufreq_interactive.
+
+ For details, take a look at linux/Documentation/cpu-freq.
+
+ If in doubt, say N.
+
comment "CPU frequency scaling drivers"
config CPUFREQ_DT
diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm
index bdce4488ded1..4c82123c0ce6 100644
--- a/drivers/cpufreq/Kconfig.arm
+++ b/drivers/cpufreq/Kconfig.arm
@@ -81,6 +81,30 @@ config ARM_IMX6Q_CPUFREQ
If in doubt, say N.
+config ARM_IMX7ULP_CPUFREQ
+ tristate "NXP i.MX7ULP cpufreq support"
+ depends on ARCH_MXC
+ help
+ This adds cpufreq driver support for NXP i.MX7ULP series SoCs.
+
+ If in doubt, say N.
+
+config ARM_IMX8_CPUFREQ
+ tristate "NXP i.MX8 cpufreq support"
+ select PM_OPP
+ help
+ This adds cpufreq driver support for NXP i.MX8 series SoCs.
+
+ If in doubt, say N.
+
+config ARM_IMX8MQ_CPUFREQ
+ tristate "NXP i.MX8MQ cpufreq support"
+ select PM_OPP
+ help
+ This adds cpufreq driver support for NXP i.MX8MQ series SoCs.
+
+ If in doubt, say N.
+
config ARM_KIRKWOOD_CPUFREQ
def_bool MACH_KIRKWOOD
help
diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile
index 812f9e0d01a3..1f4fa4597411 100644
--- a/drivers/cpufreq/Makefile
+++ b/drivers/cpufreq/Makefile
@@ -11,6 +11,7 @@ obj-$(CONFIG_CPU_FREQ_GOV_POWERSAVE) += cpufreq_powersave.o
obj-$(CONFIG_CPU_FREQ_GOV_USERSPACE) += cpufreq_userspace.o
obj-$(CONFIG_CPU_FREQ_GOV_ONDEMAND) += cpufreq_ondemand.o
obj-$(CONFIG_CPU_FREQ_GOV_CONSERVATIVE) += cpufreq_conservative.o
+obj-$(CONFIG_CPU_FREQ_GOV_INTERACTIVE) += cpufreq_interactive.o
obj-$(CONFIG_CPU_FREQ_GOV_COMMON) += cpufreq_governor.o
obj-$(CONFIG_CPU_FREQ_GOV_ATTR_SET) += cpufreq_governor_attr_set.o
@@ -57,6 +58,9 @@ obj-$(CONFIG_ARCH_DAVINCI) += davinci-cpufreq.o
obj-$(CONFIG_ARM_EXYNOS5440_CPUFREQ) += exynos5440-cpufreq.o
obj-$(CONFIG_ARM_HIGHBANK_CPUFREQ) += highbank-cpufreq.o
obj-$(CONFIG_ARM_IMX6Q_CPUFREQ) += imx6q-cpufreq.o
+obj-$(CONFIG_ARM_IMX7ULP_CPUFREQ) += imx7ulp-cpufreq.o
+obj-$(CONFIG_ARM_IMX8_CPUFREQ) += imx8-cpufreq.o
+obj-$(CONFIG_ARM_IMX8MQ_CPUFREQ) += imx8mq-cpufreq.o
obj-$(CONFIG_ARM_KIRKWOOD_CPUFREQ) += kirkwood-cpufreq.o
obj-$(CONFIG_ARM_MEDIATEK_CPUFREQ) += mediatek-cpufreq.o
obj-$(CONFIG_ARM_OMAP2PLUS_CPUFREQ) += omap-cpufreq.o
diff --git a/drivers/cpufreq/cpufreq_governor.h b/drivers/cpufreq/cpufreq_governor.h
index 8463f5def0f5..3275558345d8 100644
--- a/drivers/cpufreq/cpufreq_governor.h
+++ b/drivers/cpufreq/cpufreq_governor.h
@@ -70,14 +70,6 @@ static ssize_t show_##file_name \
return sprintf(buf, "%u\n", dbs_data->file_name); \
}
-#define gov_attr_ro(_name) \
-static struct governor_attr _name = \
-__ATTR(_name, 0444, show_##_name, NULL)
-
-#define gov_attr_rw(_name) \
-static struct governor_attr _name = \
-__ATTR(_name, 0644, show_##_name, store_##_name)
-
/* Common to all CPUs of a policy */
struct policy_dbs_info {
struct cpufreq_policy *policy;
diff --git a/drivers/cpufreq/cpufreq_interactive.c b/drivers/cpufreq/cpufreq_interactive.c
new file mode 100644
index 000000000000..f82b71bebb18
--- /dev/null
+++ b/drivers/cpufreq/cpufreq_interactive.c
@@ -0,0 +1,1368 @@
+/*
+ * drivers/cpufreq/cpufreq_interactive.c
+ *
+ * Copyright (C) 2010-2016 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * Author: Mike Chan (mike@android.com)
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/cpu.h>
+#include <linux/cpumask.h>
+#include <linux/cpufreq.h>
+#include <linux/irq_work.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/rwsem.h>
+#include <linux/sched.h>
+#include <linux/sched/rt.h>
+#include <linux/tick.h>
+#include <linux/time.h>
+#include <linux/timer.h>
+#include <linux/kthread.h>
+#include <linux/slab.h>
+#include <linux/sched/task.h>
+#include <linux/sched/types.h>
+#include <linux/sched/cpufreq.h>
+
+#define CREATE_TRACE_POINTS
+#include <trace/events/cpufreq_interactive.h>
+
+/* Separate instance required for each 'interactive' directory in sysfs */
+struct interactive_tunables {
+ struct gov_attr_set attr_set;
+
+ /* Hi speed to bump to from lo speed when load burst (default max) */
+ unsigned int hispeed_freq;
+
+ /* Go to hi speed when CPU load at or above this value. */
+#define DEFAULT_GO_HISPEED_LOAD 99
+ unsigned long go_hispeed_load;
+
+ /* Target load. Lower values result in higher CPU speeds. */
+ spinlock_t target_loads_lock;
+ unsigned int *target_loads;
+ int ntarget_loads;
+
+ /*
+ * The minimum amount of time to spend at a frequency before we can ramp
+ * down.
+ */
+#define DEFAULT_MIN_SAMPLE_TIME (80 * USEC_PER_MSEC)
+ unsigned long min_sample_time;
+
+ /* The sample rate of the timer used to increase frequency */
+ unsigned long sampling_rate;
+
+ /*
+ * Wait this long before raising speed above hispeed, by default a
+ * single timer interval.
+ */
+ spinlock_t above_hispeed_delay_lock;
+ unsigned int *above_hispeed_delay;
+ int nabove_hispeed_delay;
+
+ /* Non-zero means indefinite speed boost active */
+ int boost;
+ /* Duration of a boot pulse in usecs */
+ int boostpulse_duration;
+ /* End time of boost pulse in ktime converted to usecs */
+ u64 boostpulse_endtime;
+ bool boosted;
+
+ /*
+ * Max additional time to wait in idle, beyond sampling_rate, at speeds
+ * above minimum before wakeup to reduce speed, or -1 if unnecessary.
+ */
+#define DEFAULT_TIMER_SLACK (4 * DEFAULT_SAMPLING_RATE)
+ unsigned long timer_slack_delay;
+ unsigned long timer_slack;
+ bool io_is_busy;
+};
+
+/* Separate instance required for each 'struct cpufreq_policy' */
+struct interactive_policy {
+ struct cpufreq_policy *policy;
+ struct interactive_tunables *tunables;
+ struct list_head tunables_hook;
+};
+
+/* Separate instance required for each CPU */
+struct interactive_cpu {
+ struct update_util_data update_util;
+ struct interactive_policy *ipolicy;
+
+ struct irq_work irq_work;
+ u64 last_sample_time;
+ bool work_in_progress;
+
+ struct rw_semaphore enable_sem;
+ struct timer_list slack_timer;
+
+ spinlock_t load_lock; /* protects the next 4 fields */
+ u64 time_in_idle;
+ u64 time_in_idle_timestamp;
+ u64 cputime_speedadj;
+ u64 cputime_speedadj_timestamp;
+
+ spinlock_t target_freq_lock; /*protects target freq */
+ unsigned int target_freq;
+
+ unsigned int floor_freq;
+ u64 pol_floor_val_time; /* policy floor_validate_time */
+ u64 loc_floor_val_time; /* per-cpu floor_validate_time */
+ u64 pol_hispeed_val_time; /* policy hispeed_validate_time */
+ u64 loc_hispeed_val_time; /* per-cpu hispeed_validate_time */
+};
+
+static DEFINE_PER_CPU(struct interactive_cpu, interactive_cpu);
+
+/* Realtime thread handles frequency scaling */
+static struct task_struct *speedchange_task;
+static cpumask_t speedchange_cpumask;
+static spinlock_t speedchange_cpumask_lock;
+
+/* Target load. Lower values result in higher CPU speeds. */
+#define DEFAULT_TARGET_LOAD 90
+static unsigned int default_target_loads[] = {DEFAULT_TARGET_LOAD};
+
+#define DEFAULT_SAMPLING_RATE (20 * USEC_PER_MSEC)
+#define DEFAULT_ABOVE_HISPEED_DELAY DEFAULT_SAMPLING_RATE
+static unsigned int default_above_hispeed_delay[] = {
+ DEFAULT_ABOVE_HISPEED_DELAY
+};
+
+/* Iterate over interactive policies for tunables */
+#define for_each_ipolicy(__ip) \
+ list_for_each_entry(__ip, &tunables->attr_set.policy_list, tunables_hook)
+
+static struct interactive_tunables *global_tunables;
+static DEFINE_MUTEX(global_tunables_lock);
+
+static inline void update_slack_delay(struct interactive_tunables *tunables)
+{
+ tunables->timer_slack_delay = usecs_to_jiffies(tunables->timer_slack +
+ tunables->sampling_rate);
+}
+
+static bool timer_slack_required(struct interactive_cpu *icpu)
+{
+ struct interactive_policy *ipolicy = icpu->ipolicy;
+ struct interactive_tunables *tunables = ipolicy->tunables;
+
+ if (tunables->timer_slack < 0)
+ return false;
+
+ if (icpu->target_freq > ipolicy->policy->min)
+ return true;
+
+ return false;
+}
+
+static void gov_slack_timer_start(struct interactive_cpu *icpu, int cpu)
+{
+ struct interactive_tunables *tunables = icpu->ipolicy->tunables;
+
+ icpu->slack_timer.expires = jiffies + tunables->timer_slack_delay;
+ add_timer_on(&icpu->slack_timer, cpu);
+}
+
+static void gov_slack_timer_modify(struct interactive_cpu *icpu)
+{
+ struct interactive_tunables *tunables = icpu->ipolicy->tunables;
+
+ mod_timer(&icpu->slack_timer, jiffies + tunables->timer_slack_delay);
+}
+
+static void slack_timer_resched(struct interactive_cpu *icpu, int cpu,
+ bool modify)
+{
+ struct interactive_tunables *tunables = icpu->ipolicy->tunables;
+ unsigned long flags;
+
+ spin_lock_irqsave(&icpu->load_lock, flags);
+
+ icpu->time_in_idle = get_cpu_idle_time(cpu,
+ &icpu->time_in_idle_timestamp,
+ tunables->io_is_busy);
+ icpu->cputime_speedadj = 0;
+ icpu->cputime_speedadj_timestamp = icpu->time_in_idle_timestamp;
+
+ if (timer_slack_required(icpu)) {
+ if (modify)
+ gov_slack_timer_modify(icpu);
+ else
+ gov_slack_timer_start(icpu, cpu);
+ }
+
+ spin_unlock_irqrestore(&icpu->load_lock, flags);
+}
+
+static unsigned int
+freq_to_above_hispeed_delay(struct interactive_tunables *tunables,
+ unsigned int freq)
+{
+ unsigned long flags;
+ unsigned int ret;
+ int i;
+
+ spin_lock_irqsave(&tunables->above_hispeed_delay_lock, flags);
+
+ for (i = 0; i < tunables->nabove_hispeed_delay - 1 &&
+ freq >= tunables->above_hispeed_delay[i + 1]; i += 2)
+ ;
+
+ ret = tunables->above_hispeed_delay[i];
+ spin_unlock_irqrestore(&tunables->above_hispeed_delay_lock, flags);
+
+ return ret;
+}
+
+static unsigned int freq_to_targetload(struct interactive_tunables *tunables,
+ unsigned int freq)
+{
+ unsigned long flags;
+ unsigned int ret;
+ int i;
+
+ spin_lock_irqsave(&tunables->target_loads_lock, flags);
+
+ for (i = 0; i < tunables->ntarget_loads - 1 &&
+ freq >= tunables->target_loads[i + 1]; i += 2)
+ ;
+
+ ret = tunables->target_loads[i];
+ spin_unlock_irqrestore(&tunables->target_loads_lock, flags);
+ return ret;
+}
+
+/*
+ * If increasing frequencies never map to a lower target load then
+ * choose_freq() will find the minimum frequency that does not exceed its
+ * target load given the current load.
+ */
+static unsigned int choose_freq(struct interactive_cpu *icpu,
+ unsigned int loadadjfreq)
+{
+ struct cpufreq_policy *policy = icpu->ipolicy->policy;
+ struct cpufreq_frequency_table *freq_table = policy->freq_table;
+ unsigned int prevfreq, freqmin = 0, freqmax = UINT_MAX, tl;
+ unsigned int freq = policy->cur;
+ int index;
+
+ do {
+ prevfreq = freq;
+ tl = freq_to_targetload(icpu->ipolicy->tunables, freq);
+
+ /*
+ * Find the lowest frequency where the computed load is less
+ * than or equal to the target load.
+ */
+
+ index = cpufreq_frequency_table_target(policy, loadadjfreq / tl,
+ CPUFREQ_RELATION_L);
+ if (index < 0)
+ break;
+
+ freq = freq_table[index].frequency;
+
+ if (freq > prevfreq) {
+ /* The previous frequency is too low */
+ freqmin = prevfreq;
+
+ if (freq < freqmax)
+ continue;
+
+ /* Find highest frequency that is less than freqmax */
+ index = cpufreq_frequency_table_target(policy,
+ freqmax - 1, CPUFREQ_RELATION_H);
+ if (index < 0)
+ break;
+
+ freq = freq_table[index].frequency;
+
+ if (freq == freqmin) {
+ /*
+ * The first frequency below freqmax has already
+ * been found to be too low. freqmax is the
+ * lowest speed we found that is fast enough.
+ */
+ freq = freqmax;
+ break;
+ }
+ } else if (freq < prevfreq) {
+ /* The previous frequency is high enough. */
+ freqmax = prevfreq;
+
+ if (freq > freqmin)
+ continue;
+
+ /* Find lowest frequency that is higher than freqmin */
+ index = cpufreq_frequency_table_target(policy,
+ freqmin + 1, CPUFREQ_RELATION_L);
+ if (index < 0)
+ break;
+
+ freq = freq_table[index].frequency;
+
+ /*
+ * If freqmax is the first frequency above
+ * freqmin then we have already found that
+ * this speed is fast enough.
+ */
+ if (freq == freqmax)
+ break;
+ }
+
+ /* If same frequency chosen as previous then done. */
+ } while (freq != prevfreq);
+
+ return freq;
+}
+
+static u64 update_load(struct interactive_cpu *icpu, int cpu)
+{
+ struct interactive_tunables *tunables = icpu->ipolicy->tunables;
+ unsigned int delta_idle, delta_time;
+ u64 now_idle, now, active_time;
+
+ now_idle = get_cpu_idle_time(cpu, &now, tunables->io_is_busy);
+ delta_idle = (unsigned int)(now_idle - icpu->time_in_idle);
+ delta_time = (unsigned int)(now - icpu->time_in_idle_timestamp);
+
+ if (delta_time <= delta_idle)
+ active_time = 0;
+ else
+ active_time = delta_time - delta_idle;
+
+ icpu->cputime_speedadj += active_time * icpu->ipolicy->policy->cur;
+
+ icpu->time_in_idle = now_idle;
+ icpu->time_in_idle_timestamp = now;
+
+ return now;
+}
+
+/* Re-evaluate load to see if a frequency change is required or not */
+static void eval_target_freq(struct interactive_cpu *icpu)
+{
+ struct interactive_tunables *tunables = icpu->ipolicy->tunables;
+ struct cpufreq_policy *policy = icpu->ipolicy->policy;
+ struct cpufreq_frequency_table *freq_table = policy->freq_table;
+ u64 cputime_speedadj, now, max_fvtime;
+ unsigned int new_freq, loadadjfreq, index, delta_time;
+ unsigned long flags;
+ int cpu_load;
+ int cpu = smp_processor_id();
+
+ spin_lock_irqsave(&icpu->load_lock, flags);
+ now = update_load(icpu, smp_processor_id());
+ delta_time = (unsigned int)(now - icpu->cputime_speedadj_timestamp);
+ cputime_speedadj = icpu->cputime_speedadj;
+ spin_unlock_irqrestore(&icpu->load_lock, flags);
+
+ if (WARN_ON_ONCE(!delta_time))
+ return;
+
+ spin_lock_irqsave(&icpu->target_freq_lock, flags);
+ do_div(cputime_speedadj, delta_time);
+ loadadjfreq = (unsigned int)cputime_speedadj * 100;
+ cpu_load = loadadjfreq / policy->cur;
+ tunables->boosted = tunables->boost ||
+ now < tunables->boostpulse_endtime;
+
+ if (cpu_load >= tunables->go_hispeed_load || tunables->boosted) {
+ if (policy->cur < tunables->hispeed_freq) {
+ new_freq = tunables->hispeed_freq;
+ } else {
+ new_freq = choose_freq(icpu, loadadjfreq);
+
+ if (new_freq < tunables->hispeed_freq)
+ new_freq = tunables->hispeed_freq;
+ }
+ } else {
+ new_freq = choose_freq(icpu, loadadjfreq);
+ if (new_freq > tunables->hispeed_freq &&
+ policy->cur < tunables->hispeed_freq)
+ new_freq = tunables->hispeed_freq;
+ }
+
+ if (policy->cur >= tunables->hispeed_freq &&
+ new_freq > policy->cur &&
+ now - icpu->pol_hispeed_val_time < freq_to_above_hispeed_delay(tunables, policy->cur)) {
+ trace_cpufreq_interactive_notyet(cpu, cpu_load,
+ icpu->target_freq, policy->cur, new_freq);
+ goto exit;
+ }
+
+ icpu->loc_hispeed_val_time = now;
+
+ index = cpufreq_frequency_table_target(policy, new_freq,
+ CPUFREQ_RELATION_L);
+ new_freq = freq_table[index].frequency;
+
+ /*
+ * Do not scale below floor_freq unless we have been at or above the
+ * floor frequency for the minimum sample time since last validated.
+ */
+ max_fvtime = max(icpu->pol_floor_val_time, icpu->loc_floor_val_time);
+ if (new_freq < icpu->floor_freq && icpu->target_freq >= policy->cur) {
+ if (now - max_fvtime < tunables->min_sample_time) {
+ trace_cpufreq_interactive_notyet(cpu, cpu_load,
+ icpu->target_freq, policy->cur, new_freq);
+ goto exit;
+ }
+ }
+
+ /*
+ * Update the timestamp for checking whether speed has been held at
+ * or above the selected frequency for a minimum of min_sample_time,
+ * if not boosted to hispeed_freq. If boosted to hispeed_freq then we
+ * allow the speed to drop as soon as the boostpulse duration expires
+ * (or the indefinite boost is turned off).
+ */
+
+ if (!tunables->boosted || new_freq > tunables->hispeed_freq) {
+ icpu->floor_freq = new_freq;
+ if (icpu->target_freq >= policy->cur || new_freq >= policy->cur)
+ icpu->loc_floor_val_time = now;
+ }
+
+ if (icpu->target_freq == new_freq &&
+ icpu->target_freq <= policy->cur) {
+ trace_cpufreq_interactive_already(cpu, cpu_load,
+ icpu->target_freq, policy->cur, new_freq);
+ goto exit;
+ }
+
+ trace_cpufreq_interactive_target(cpu, cpu_load, icpu->target_freq,
+ policy->cur, new_freq);
+
+ icpu->target_freq = new_freq;
+ spin_unlock_irqrestore(&icpu->target_freq_lock, flags);
+
+ spin_lock_irqsave(&speedchange_cpumask_lock, flags);
+ cpumask_set_cpu(cpu, &speedchange_cpumask);
+ spin_unlock_irqrestore(&speedchange_cpumask_lock, flags);
+
+ wake_up_process(speedchange_task);
+ return;
+
+exit:
+ spin_unlock_irqrestore(&icpu->target_freq_lock, flags);
+}
+
+static void cpufreq_interactive_update(struct interactive_cpu *icpu)
+{
+ eval_target_freq(icpu);
+ slack_timer_resched(icpu, smp_processor_id(), true);
+}
+
+static void cpufreq_interactive_get_policy_info(struct cpufreq_policy *policy,
+ unsigned int *pmax_freq,
+ u64 *phvt, u64 *pfvt)
+{
+ struct interactive_cpu *icpu;
+ u64 hvt = ~0ULL, fvt = 0;
+ unsigned int max_freq = 0, i;
+
+ for_each_cpu(i, policy->cpus) {
+ icpu = &per_cpu(interactive_cpu, i);
+
+ fvt = max(fvt, icpu->loc_floor_val_time);
+ if (icpu->target_freq > max_freq) {
+ max_freq = icpu->target_freq;
+ hvt = icpu->loc_hispeed_val_time;
+ } else if (icpu->target_freq == max_freq) {
+ hvt = min(hvt, icpu->loc_hispeed_val_time);
+ }
+ }
+
+ *pmax_freq = max_freq;
+ *phvt = hvt;
+ *pfvt = fvt;
+}
+
+static void cpufreq_interactive_adjust_cpu(unsigned int cpu,
+ struct cpufreq_policy *policy)
+{
+ struct interactive_cpu *icpu;
+ u64 hvt, fvt;
+ unsigned int max_freq;
+ int i;
+
+ cpufreq_interactive_get_policy_info(policy, &max_freq, &hvt, &fvt);
+
+ for_each_cpu(i, policy->cpus) {
+ icpu = &per_cpu(interactive_cpu, i);
+ icpu->pol_floor_val_time = fvt;
+ }
+
+ if (max_freq != policy->cur) {
+ __cpufreq_driver_target(policy, max_freq, CPUFREQ_RELATION_H);
+ for_each_cpu(i, policy->cpus) {
+ icpu = &per_cpu(interactive_cpu, i);
+ icpu->pol_hispeed_val_time = hvt;
+ }
+ }
+
+ trace_cpufreq_interactive_setspeed(cpu, max_freq, policy->cur);
+}
+
+static int cpufreq_interactive_speedchange_task(void *data)
+{
+ unsigned int cpu;
+ cpumask_t tmp_mask;
+ unsigned long flags;
+
+again:
+ set_current_state(TASK_INTERRUPTIBLE);
+ spin_lock_irqsave(&speedchange_cpumask_lock, flags);
+
+ if (cpumask_empty(&speedchange_cpumask)) {
+ spin_unlock_irqrestore(&speedchange_cpumask_lock, flags);
+ schedule();
+
+ if (kthread_should_stop())
+ return 0;
+
+ spin_lock_irqsave(&speedchange_cpumask_lock, flags);
+ }
+
+ set_current_state(TASK_RUNNING);
+ tmp_mask = speedchange_cpumask;
+ cpumask_clear(&speedchange_cpumask);
+ spin_unlock_irqrestore(&speedchange_cpumask_lock, flags);
+
+ for_each_cpu(cpu, &tmp_mask) {
+ struct interactive_cpu *icpu = &per_cpu(interactive_cpu, cpu);
+ struct cpufreq_policy *policy = icpu->ipolicy->policy;
+
+ if (unlikely(!down_read_trylock(&icpu->enable_sem)))
+ continue;
+
+ if (likely(icpu->ipolicy))
+ cpufreq_interactive_adjust_cpu(cpu, policy);
+
+ up_read(&icpu->enable_sem);
+ }
+
+ goto again;
+}
+
+static void cpufreq_interactive_boost(struct interactive_tunables *tunables)
+{
+ struct interactive_policy *ipolicy;
+ struct cpufreq_policy *policy;
+ struct interactive_cpu *icpu;
+ unsigned long flags[2];
+ bool wakeup = false;
+ int i;
+
+ tunables->boosted = true;
+
+ spin_lock_irqsave(&speedchange_cpumask_lock, flags[0]);
+
+ for_each_ipolicy(ipolicy) {
+ policy = ipolicy->policy;
+
+ for_each_cpu(i, policy->cpus) {
+ icpu = &per_cpu(interactive_cpu, i);
+
+ if (!down_read_trylock(&icpu->enable_sem))
+ continue;
+
+ if (!icpu->ipolicy) {
+ up_read(&icpu->enable_sem);
+ continue;
+ }
+
+ spin_lock_irqsave(&icpu->target_freq_lock, flags[1]);
+ if (icpu->target_freq < tunables->hispeed_freq) {
+ icpu->target_freq = tunables->hispeed_freq;
+ cpumask_set_cpu(i, &speedchange_cpumask);
+ icpu->pol_hispeed_val_time = ktime_to_us(ktime_get());
+ wakeup = true;
+ }
+ spin_unlock_irqrestore(&icpu->target_freq_lock, flags[1]);
+
+ up_read(&icpu->enable_sem);
+ }
+ }
+
+ spin_unlock_irqrestore(&speedchange_cpumask_lock, flags[0]);
+
+ if (wakeup)
+ wake_up_process(speedchange_task);
+}
+
+static int cpufreq_interactive_notifier(struct notifier_block *nb,
+ unsigned long val, void *data)
+{
+ struct cpufreq_freqs *freq = data;
+ struct interactive_cpu *icpu = &per_cpu(interactive_cpu, freq->cpu);
+ unsigned long flags;
+
+ if (val != CPUFREQ_POSTCHANGE)
+ return 0;
+
+ if (!down_read_trylock(&icpu->enable_sem))
+ return 0;
+
+ if (!icpu->ipolicy) {
+ up_read(&icpu->enable_sem);
+ return 0;
+ }
+
+ spin_lock_irqsave(&icpu->load_lock, flags);
+ update_load(icpu, freq->cpu);
+ spin_unlock_irqrestore(&icpu->load_lock, flags);
+
+ up_read(&icpu->enable_sem);
+
+ return 0;
+}
+
+static struct notifier_block cpufreq_notifier_block = {
+ .notifier_call = cpufreq_interactive_notifier,
+};
+
+static unsigned int *get_tokenized_data(const char *buf, int *num_tokens)
+{
+ const char *cp = buf;
+ int ntokens = 1, i = 0;
+ unsigned int *tokenized_data;
+ int err = -EINVAL;
+
+ while ((cp = strpbrk(cp + 1, " :")))
+ ntokens++;
+
+ if (!(ntokens & 0x1))
+ goto err;
+
+ tokenized_data = kcalloc(ntokens, sizeof(*tokenized_data), GFP_KERNEL);
+ if (!tokenized_data) {
+ err = -ENOMEM;
+ goto err;
+ }
+
+ cp = buf;
+ while (i < ntokens) {
+ if (kstrtouint(cp, 0, &tokenized_data[i++]) < 0)
+ goto err_kfree;
+
+ cp = strpbrk(cp, " :");
+ if (!cp)
+ break;
+ cp++;
+ }
+
+ if (i != ntokens)
+ goto err_kfree;
+
+ *num_tokens = ntokens;
+ return tokenized_data;
+
+err_kfree:
+ kfree(tokenized_data);
+err:
+ return ERR_PTR(err);
+}
+
+/* Interactive governor sysfs interface */
+static struct interactive_tunables *to_tunables(struct gov_attr_set *attr_set)
+{
+ return container_of(attr_set, struct interactive_tunables, attr_set);
+}
+
+#define show_one(file_name, type) \
+static ssize_t show_##file_name(struct gov_attr_set *attr_set, char *buf) \
+{ \
+ struct interactive_tunables *tunables = to_tunables(attr_set); \
+ return sprintf(buf, type "\n", tunables->file_name); \
+}
+
+static ssize_t show_target_loads(struct gov_attr_set *attr_set, char *buf)
+{
+ struct interactive_tunables *tunables = to_tunables(attr_set);
+ unsigned long flags;
+ ssize_t ret = 0;
+ int i;
+
+ spin_lock_irqsave(&tunables->target_loads_lock, flags);
+
+ for (i = 0; i < tunables->ntarget_loads; i++)
+ ret += sprintf(buf + ret, "%u%s", tunables->target_loads[i],
+ i & 0x1 ? ":" : " ");
+
+ sprintf(buf + ret - 1, "\n");
+ spin_unlock_irqrestore(&tunables->target_loads_lock, flags);
+
+ return ret;
+}
+
+static ssize_t store_target_loads(struct gov_attr_set *attr_set,
+ const char *buf, size_t count)
+{
+ struct interactive_tunables *tunables = to_tunables(attr_set);
+ unsigned int *new_target_loads;
+ unsigned long flags;
+ int ntokens;
+
+ new_target_loads = get_tokenized_data(buf, &ntokens);
+ if (IS_ERR(new_target_loads))
+ return PTR_ERR(new_target_loads);
+
+ spin_lock_irqsave(&tunables->target_loads_lock, flags);
+ if (tunables->target_loads != default_target_loads)
+ kfree(tunables->target_loads);
+ tunables->target_loads = new_target_loads;
+ tunables->ntarget_loads = ntokens;
+ spin_unlock_irqrestore(&tunables->target_loads_lock, flags);
+
+ return count;
+}
+
+static ssize_t show_above_hispeed_delay(struct gov_attr_set *attr_set,
+ char *buf)
+{
+ struct interactive_tunables *tunables = to_tunables(attr_set);
+ unsigned long flags;
+ ssize_t ret = 0;
+ int i;
+
+ spin_lock_irqsave(&tunables->above_hispeed_delay_lock, flags);
+
+ for (i = 0; i < tunables->nabove_hispeed_delay; i++)
+ ret += sprintf(buf + ret, "%u%s",
+ tunables->above_hispeed_delay[i],
+ i & 0x1 ? ":" : " ");
+
+ sprintf(buf + ret - 1, "\n");
+ spin_unlock_irqrestore(&tunables->above_hispeed_delay_lock, flags);
+
+ return ret;
+}
+
+static ssize_t store_above_hispeed_delay(struct gov_attr_set *attr_set,
+ const char *buf, size_t count)
+{
+ struct interactive_tunables *tunables = to_tunables(attr_set);
+ unsigned int *new_above_hispeed_delay = NULL;
+ unsigned long flags;
+ int ntokens;
+
+ new_above_hispeed_delay = get_tokenized_data(buf, &ntokens);
+ if (IS_ERR(new_above_hispeed_delay))
+ return PTR_ERR(new_above_hispeed_delay);
+
+ spin_lock_irqsave(&tunables->above_hispeed_delay_lock, flags);
+ if (tunables->above_hispeed_delay != default_above_hispeed_delay)
+ kfree(tunables->above_hispeed_delay);
+ tunables->above_hispeed_delay = new_above_hispeed_delay;
+ tunables->nabove_hispeed_delay = ntokens;
+ spin_unlock_irqrestore(&tunables->above_hispeed_delay_lock, flags);
+
+ return count;
+}
+
+static ssize_t store_hispeed_freq(struct gov_attr_set *attr_set,
+ const char *buf, size_t count)
+{
+ struct interactive_tunables *tunables = to_tunables(attr_set);
+ unsigned long int val;
+ int ret;
+
+ ret = kstrtoul(buf, 0, &val);
+ if (ret < 0)
+ return ret;
+
+ tunables->hispeed_freq = val;
+
+ return count;
+}
+
+static ssize_t store_go_hispeed_load(struct gov_attr_set *attr_set,
+ const char *buf, size_t count)
+{
+ struct interactive_tunables *tunables = to_tunables(attr_set);
+ unsigned long val;
+ int ret;
+
+ ret = kstrtoul(buf, 0, &val);
+ if (ret < 0)
+ return ret;
+
+ tunables->go_hispeed_load = val;
+
+ return count;
+}
+
+static ssize_t store_min_sample_time(struct gov_attr_set *attr_set,
+ const char *buf, size_t count)
+{
+ struct interactive_tunables *tunables = to_tunables(attr_set);
+ unsigned long val;
+ int ret;
+
+ ret = kstrtoul(buf, 0, &val);
+ if (ret < 0)
+ return ret;
+
+ tunables->min_sample_time = val;
+
+ return count;
+}
+
+static ssize_t show_timer_rate(struct gov_attr_set *attr_set, char *buf)
+{
+ struct interactive_tunables *tunables = to_tunables(attr_set);
+
+ return sprintf(buf, "%lu\n", tunables->sampling_rate);
+}
+
+static ssize_t store_timer_rate(struct gov_attr_set *attr_set, const char *buf,
+ size_t count)
+{
+ struct interactive_tunables *tunables = to_tunables(attr_set);
+ unsigned long val, val_round;
+ int ret;
+
+ ret = kstrtoul(buf, 0, &val);
+ if (ret < 0)
+ return ret;
+
+ val_round = jiffies_to_usecs(usecs_to_jiffies(val));
+ if (val != val_round)
+ pr_warn("timer_rate not aligned to jiffy. Rounded up to %lu\n",
+ val_round);
+
+ tunables->sampling_rate = val_round;
+
+ return count;
+}
+
+static ssize_t store_timer_slack(struct gov_attr_set *attr_set, const char *buf,
+ size_t count)
+{
+ struct interactive_tunables *tunables = to_tunables(attr_set);
+ unsigned long val;
+ int ret;
+
+ ret = kstrtol(buf, 10, &val);
+ if (ret < 0)
+ return ret;
+
+ tunables->timer_slack = val;
+ update_slack_delay(tunables);
+
+ return count;
+}
+
+static ssize_t store_boost(struct gov_attr_set *attr_set, const char *buf,
+ size_t count)
+{
+ struct interactive_tunables *tunables = to_tunables(attr_set);
+ unsigned long val;
+ int ret;
+
+ ret = kstrtoul(buf, 0, &val);
+ if (ret < 0)
+ return ret;
+
+ tunables->boost = val;
+
+ if (tunables->boost) {
+ trace_cpufreq_interactive_boost("on");
+ if (!tunables->boosted)
+ cpufreq_interactive_boost(tunables);
+ } else {
+ tunables->boostpulse_endtime = ktime_to_us(ktime_get());
+ trace_cpufreq_interactive_unboost("off");
+ }
+
+ return count;
+}
+
+static ssize_t store_boostpulse(struct gov_attr_set *attr_set, const char *buf,
+ size_t count)
+{
+ struct interactive_tunables *tunables = to_tunables(attr_set);
+ unsigned long val;
+ int ret;
+
+ ret = kstrtoul(buf, 0, &val);
+ if (ret < 0)
+ return ret;
+
+ tunables->boostpulse_endtime = ktime_to_us(ktime_get()) +
+ tunables->boostpulse_duration;
+ trace_cpufreq_interactive_boost("pulse");
+ if (!tunables->boosted)
+ cpufreq_interactive_boost(tunables);
+
+ return count;
+}
+
+static ssize_t store_boostpulse_duration(struct gov_attr_set *attr_set,
+ const char *buf, size_t count)
+{
+ struct interactive_tunables *tunables = to_tunables(attr_set);
+ unsigned long val;
+ int ret;
+
+ ret = kstrtoul(buf, 0, &val);
+ if (ret < 0)
+ return ret;
+
+ tunables->boostpulse_duration = val;
+
+ return count;
+}
+
+static ssize_t store_io_is_busy(struct gov_attr_set *attr_set, const char *buf,
+ size_t count)
+{
+ struct interactive_tunables *tunables = to_tunables(attr_set);
+ unsigned long val;
+ int ret;
+
+ ret = kstrtoul(buf, 0, &val);
+ if (ret < 0)
+ return ret;
+
+ tunables->io_is_busy = val;
+
+ return count;
+}
+
+show_one(hispeed_freq, "%u");
+show_one(go_hispeed_load, "%lu");
+show_one(min_sample_time, "%lu");
+show_one(timer_slack, "%lu");
+show_one(boost, "%u");
+show_one(boostpulse_duration, "%u");
+show_one(io_is_busy, "%u");
+
+gov_attr_rw(target_loads);
+gov_attr_rw(above_hispeed_delay);
+gov_attr_rw(hispeed_freq);
+gov_attr_rw(go_hispeed_load);
+gov_attr_rw(min_sample_time);
+gov_attr_rw(timer_rate);
+gov_attr_rw(timer_slack);
+gov_attr_rw(boost);
+gov_attr_wo(boostpulse);
+gov_attr_rw(boostpulse_duration);
+gov_attr_rw(io_is_busy);
+
+static struct attribute *interactive_attributes[] = {
+ &target_loads.attr,
+ &above_hispeed_delay.attr,
+ &hispeed_freq.attr,
+ &go_hispeed_load.attr,
+ &min_sample_time.attr,
+ &timer_rate.attr,
+ &timer_slack.attr,
+ &boost.attr,
+ &boostpulse.attr,
+ &boostpulse_duration.attr,
+ &io_is_busy.attr,
+ NULL
+};
+
+static struct kobj_type interactive_tunables_ktype = {
+ .default_attrs = interactive_attributes,
+ .sysfs_ops = &governor_sysfs_ops,
+};
+
+/* Interactive Governor callbacks */
+struct interactive_governor {
+ struct cpufreq_governor gov;
+ unsigned int usage_count;
+};
+
+static struct interactive_governor interactive_gov;
+
+#define CPU_FREQ_GOV_INTERACTIVE (&interactive_gov.gov)
+
+static void irq_work(struct irq_work *irq_work)
+{
+ struct interactive_cpu *icpu = container_of(irq_work, struct
+ interactive_cpu, irq_work);
+
+ cpufreq_interactive_update(icpu);
+ icpu->work_in_progress = false;
+}
+
+static void update_util_handler(struct update_util_data *data, u64 time,
+ unsigned int flags)
+{
+ struct interactive_cpu *icpu = container_of(data,
+ struct interactive_cpu, update_util);
+ struct interactive_policy *ipolicy = icpu->ipolicy;
+ struct interactive_tunables *tunables = ipolicy->tunables;
+ u64 delta_ns;
+
+ /*
+ * The irq-work may not be allowed to be queued up right now.
+ * Possible reasons:
+ * - Work has already been queued up or is in progress.
+ * - It is too early (too little time from the previous sample).
+ */
+ if (icpu->work_in_progress)
+ return;
+
+ delta_ns = time - icpu->last_sample_time;
+ if ((s64)delta_ns < tunables->sampling_rate * NSEC_PER_USEC)
+ return;
+
+ icpu->last_sample_time = time;
+
+ icpu->work_in_progress = true;
+ irq_work_queue(&icpu->irq_work);
+}
+
+static void gov_set_update_util(struct interactive_policy *ipolicy)
+{
+ struct cpufreq_policy *policy = ipolicy->policy;
+ struct interactive_cpu *icpu;
+ int cpu;
+
+ for_each_cpu(cpu, policy->cpus) {
+ icpu = &per_cpu(interactive_cpu, cpu);
+
+ icpu->last_sample_time = 0;
+ cpufreq_add_update_util_hook(cpu, &icpu->update_util,
+ update_util_handler);
+ }
+}
+
+static inline void gov_clear_update_util(struct cpufreq_policy *policy)
+{
+ int i;
+
+ for_each_cpu(i, policy->cpus)
+ cpufreq_remove_update_util_hook(i);
+
+ synchronize_sched();
+}
+
+static void icpu_cancel_work(struct interactive_cpu *icpu)
+{
+ irq_work_sync(&icpu->irq_work);
+ icpu->work_in_progress = false;
+ del_timer_sync(&icpu->slack_timer);
+}
+
+static struct interactive_policy *
+interactive_policy_alloc(struct cpufreq_policy *policy)
+{
+ struct interactive_policy *ipolicy;
+
+ ipolicy = kzalloc(sizeof(*ipolicy), GFP_KERNEL);
+ if (!ipolicy)
+ return NULL;
+
+ ipolicy->policy = policy;
+
+ return ipolicy;
+}
+
+static void interactive_policy_free(struct interactive_policy *ipolicy)
+{
+ kfree(ipolicy);
+}
+
+static struct interactive_tunables *
+interactive_tunables_alloc(struct interactive_policy *ipolicy)
+{
+ struct interactive_tunables *tunables;
+
+ tunables = kzalloc(sizeof(*tunables), GFP_KERNEL);
+ if (!tunables)
+ return NULL;
+
+ gov_attr_set_init(&tunables->attr_set, &ipolicy->tunables_hook);
+ if (!have_governor_per_policy())
+ global_tunables = tunables;
+
+ ipolicy->tunables = tunables;
+
+ return tunables;
+}
+
+static void interactive_tunables_free(struct interactive_tunables *tunables)
+{
+ if (!have_governor_per_policy())
+ global_tunables = NULL;
+
+ kfree(tunables);
+}
+
+int cpufreq_interactive_init(struct cpufreq_policy *policy)
+{
+ struct interactive_policy *ipolicy;
+ struct interactive_tunables *tunables;
+ int ret;
+
+ /* State should be equivalent to EXIT */
+ if (policy->governor_data)
+ return -EBUSY;
+
+ ipolicy = interactive_policy_alloc(policy);
+ if (!ipolicy)
+ return -ENOMEM;
+
+ mutex_lock(&global_tunables_lock);
+
+ if (global_tunables) {
+ if (WARN_ON(have_governor_per_policy())) {
+ ret = -EINVAL;
+ goto free_int_policy;
+ }
+
+ policy->governor_data = ipolicy;
+ ipolicy->tunables = global_tunables;
+
+ gov_attr_set_get(&global_tunables->attr_set,
+ &ipolicy->tunables_hook);
+ goto out;
+ }
+
+ tunables = interactive_tunables_alloc(ipolicy);
+ if (!tunables) {
+ ret = -ENOMEM;
+ goto free_int_policy;
+ }
+
+ tunables->hispeed_freq = policy->max;
+ tunables->above_hispeed_delay = default_above_hispeed_delay;
+ tunables->nabove_hispeed_delay =
+ ARRAY_SIZE(default_above_hispeed_delay);
+ tunables->go_hispeed_load = DEFAULT_GO_HISPEED_LOAD;
+ tunables->target_loads = default_target_loads;
+ tunables->ntarget_loads = ARRAY_SIZE(default_target_loads);
+ tunables->min_sample_time = DEFAULT_MIN_SAMPLE_TIME;
+ tunables->boostpulse_duration = DEFAULT_MIN_SAMPLE_TIME;
+ tunables->sampling_rate = DEFAULT_SAMPLING_RATE;
+ tunables->timer_slack = DEFAULT_TIMER_SLACK;
+ update_slack_delay(tunables);
+
+ spin_lock_init(&tunables->target_loads_lock);
+ spin_lock_init(&tunables->above_hispeed_delay_lock);
+
+ policy->governor_data = ipolicy;
+
+ ret = kobject_init_and_add(&tunables->attr_set.kobj,
+ &interactive_tunables_ktype,
+ get_governor_parent_kobj(policy), "%s",
+ interactive_gov.gov.name);
+ if (ret)
+ goto fail;
+
+ /* One time initialization for governor */
+ if (!interactive_gov.usage_count++) {
+ cpufreq_register_notifier(&cpufreq_notifier_block,
+ CPUFREQ_TRANSITION_NOTIFIER);
+ }
+
+ out:
+ mutex_unlock(&global_tunables_lock);
+ return 0;
+
+ fail:
+ policy->governor_data = NULL;
+ interactive_tunables_free(tunables);
+
+ free_int_policy:
+ mutex_unlock(&global_tunables_lock);
+
+ interactive_policy_free(ipolicy);
+ pr_err("governor initialization failed (%d)\n", ret);
+
+ return ret;
+}
+
+void cpufreq_interactive_exit(struct cpufreq_policy *policy)
+{
+ struct interactive_policy *ipolicy = policy->governor_data;
+ struct interactive_tunables *tunables = ipolicy->tunables;
+ unsigned int count;
+
+ mutex_lock(&global_tunables_lock);
+
+ /* Last policy using the governor ? */
+ if (!--interactive_gov.usage_count) {
+ cpufreq_unregister_notifier(&cpufreq_notifier_block,
+ CPUFREQ_TRANSITION_NOTIFIER);
+ }
+
+ count = gov_attr_set_put(&tunables->attr_set, &ipolicy->tunables_hook);
+ policy->governor_data = NULL;
+ if (!count)
+ interactive_tunables_free(tunables);
+
+ mutex_unlock(&global_tunables_lock);
+
+ interactive_policy_free(ipolicy);
+}
+
+int cpufreq_interactive_start(struct cpufreq_policy *policy)
+{
+ struct interactive_policy *ipolicy = policy->governor_data;
+ struct interactive_cpu *icpu;
+ unsigned int cpu;
+
+ for_each_cpu(cpu, policy->cpus) {
+ icpu = &per_cpu(interactive_cpu, cpu);
+
+ icpu->target_freq = policy->cur;
+ icpu->floor_freq = icpu->target_freq;
+ icpu->pol_floor_val_time = ktime_to_us(ktime_get());
+ icpu->loc_floor_val_time = icpu->pol_floor_val_time;
+ icpu->pol_hispeed_val_time = icpu->pol_floor_val_time;
+ icpu->loc_hispeed_val_time = icpu->pol_floor_val_time;
+
+ down_write(&icpu->enable_sem);
+ icpu->ipolicy = ipolicy;
+ up_write(&icpu->enable_sem);
+
+ slack_timer_resched(icpu, cpu, false);
+ }
+
+ gov_set_update_util(ipolicy);
+ return 0;
+}
+
+void cpufreq_interactive_stop(struct cpufreq_policy *policy)
+{
+ struct interactive_policy *ipolicy = policy->governor_data;
+ struct interactive_cpu *icpu;
+ unsigned int cpu;
+
+ gov_clear_update_util(ipolicy->policy);
+
+ for_each_cpu(cpu, policy->cpus) {
+ icpu = &per_cpu(interactive_cpu, cpu);
+
+ icpu_cancel_work(icpu);
+
+ down_write(&icpu->enable_sem);
+ icpu->ipolicy = NULL;
+ up_write(&icpu->enable_sem);
+ }
+}
+
+void cpufreq_interactive_limits(struct cpufreq_policy *policy)
+{
+ struct interactive_cpu *icpu;
+ unsigned int cpu;
+ unsigned long flags;
+
+ cpufreq_policy_apply_limits(policy);
+
+ for_each_cpu(cpu, policy->cpus) {
+ icpu = &per_cpu(interactive_cpu, cpu);
+
+ spin_lock_irqsave(&icpu->target_freq_lock, flags);
+
+ if (policy->max < icpu->target_freq)
+ icpu->target_freq = policy->max;
+ else if (policy->min > icpu->target_freq)
+ icpu->target_freq = policy->min;
+
+ spin_unlock_irqrestore(&icpu->target_freq_lock, flags);
+ }
+}
+
+static struct interactive_governor interactive_gov = {
+ .gov = {
+ .name = "interactive",
+ .dynamic_switching = true,
+ .owner = THIS_MODULE,
+ .init = cpufreq_interactive_init,
+ .exit = cpufreq_interactive_exit,
+ .start = cpufreq_interactive_start,
+ .stop = cpufreq_interactive_stop,
+ .limits = cpufreq_interactive_limits,
+ }
+};
+
+static void cpufreq_interactive_nop_timer(unsigned long data)
+{
+ /*
+ * The purpose of slack-timer is to wake up the CPU from IDLE, in order
+ * to decrease its frequency if it is not set to minimum already.
+ *
+ * This is important for platforms where CPU with higher frequencies
+ * consume higher power even at IDLE.
+ */
+}
+
+static int __init cpufreq_interactive_gov_init(void)
+{
+ struct sched_param param = { .sched_priority = MAX_RT_PRIO - 1 };
+ struct interactive_cpu *icpu;
+ unsigned int cpu;
+
+ for_each_possible_cpu(cpu) {
+ icpu = &per_cpu(interactive_cpu, cpu);
+
+ init_irq_work(&icpu->irq_work, irq_work);
+ spin_lock_init(&icpu->load_lock);
+ spin_lock_init(&icpu->target_freq_lock);
+ init_rwsem(&icpu->enable_sem);
+
+ /* Initialize per-cpu slack-timer */
+ init_timer_pinned(&icpu->slack_timer);
+ icpu->slack_timer.function = cpufreq_interactive_nop_timer;
+ }
+
+ spin_lock_init(&speedchange_cpumask_lock);
+ speedchange_task = kthread_create(cpufreq_interactive_speedchange_task,
+ NULL, "cfinteractive");
+ if (IS_ERR(speedchange_task))
+ return PTR_ERR(speedchange_task);
+
+ sched_setscheduler_nocheck(speedchange_task, SCHED_FIFO, &param);
+ get_task_struct(speedchange_task);
+
+ /* wake up so the thread does not look hung to the freezer */
+ wake_up_process(speedchange_task);
+
+ return cpufreq_register_governor(CPU_FREQ_GOV_INTERACTIVE);
+}
+
+#ifdef CONFIG_CPU_FREQ_DEFAULT_GOV_INTERACTIVE
+struct cpufreq_governor *cpufreq_default_governor(void)
+{
+ return CPU_FREQ_GOV_INTERACTIVE;
+}
+
+fs_initcall(cpufreq_interactive_gov_init);
+#else
+module_init(cpufreq_interactive_gov_init);
+#endif
+
+static void __exit cpufreq_interactive_gov_exit(void)
+{
+ cpufreq_unregister_governor(CPU_FREQ_GOV_INTERACTIVE);
+ kthread_stop(speedchange_task);
+ put_task_struct(speedchange_task);
+}
+module_exit(cpufreq_interactive_gov_exit);
+
+MODULE_AUTHOR("Mike Chan <mike@android.com>");
+MODULE_DESCRIPTION("'cpufreq_interactive' - A dynamic cpufreq governor for Latency sensitive workloads");
+MODULE_LICENSE("GPL");
diff --git a/drivers/cpufreq/imx6q-cpufreq.c b/drivers/cpufreq/imx6q-cpufreq.c
index 63d28323a29c..bf1092d02428 100644
--- a/drivers/cpufreq/imx6q-cpufreq.c
+++ b/drivers/cpufreq/imx6q-cpufreq.c
@@ -1,11 +1,13 @@
/*
- * Copyright (C) 2013 Freescale Semiconductor, Inc.
+ * Copyright (C) 2013-2016 Freescale Semiconductor, Inc.
+ * Copyright 2017 NXP.
*
* 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/busfreq-imx.h>
#include <linux/clk.h>
#include <linux/cpu.h>
#include <linux/cpufreq.h>
@@ -15,14 +17,22 @@
#include <linux/pm_opp.h>
#include <linux/platform_device.h>
#include <linux/regulator/consumer.h>
+#include <linux/suspend.h>
#define PU_SOC_VOLTAGE_NORMAL 1250000
#define PU_SOC_VOLTAGE_HIGH 1275000
+#define DC_VOLTAGE_MIN 1300000
+#define DC_VOLTAGE_MAX 1400000
#define FREQ_1P2_GHZ 1200000000
+#define FREQ_396_MHZ 396000
+#define FREQ_528_MHZ 528000
+#define FREQ_198_MHZ 198000
+#define FREQ_24_MHZ 24000
-static struct regulator *arm_reg;
+struct regulator *arm_reg;
static struct regulator *pu_reg;
-static struct regulator *soc_reg;
+struct regulator *soc_reg;
+static struct regulator *dc_reg;
static struct clk *arm_clk;
static struct clk *pll1_sys_clk;
@@ -31,6 +41,9 @@ static struct clk *step_clk;
static struct clk *pll2_pfd2_396m_clk;
/* clk used by i.MX6UL */
+static struct clk *pll1_bypass_clk;
+static struct clk *pll1_bypass_src_clk;
+static struct clk *pll1_clk;
static struct clk *pll2_bus_clk;
static struct clk *secondary_sel_clk;
@@ -41,6 +54,8 @@ static unsigned int transition_latency;
static u32 *imx6_soc_volt;
static u32 soc_opp_count;
+static bool ignore_dc_reg;
+static bool low_power_run_support;
static int imx6q_set_target(struct cpufreq_policy *policy, unsigned int index)
{
@@ -48,11 +63,21 @@ static int imx6q_set_target(struct cpufreq_policy *policy, unsigned int index)
unsigned long freq_hz, volt, volt_old;
unsigned int old_freq, new_freq;
bool pll1_sys_temp_enabled = false;
- int ret;
+ int ret, ret1;
new_freq = freq_table[index].frequency;
freq_hz = new_freq * 1000;
- old_freq = clk_get_rate(arm_clk) / 1000;
+ old_freq = policy->cur;
+
+ /*
+ * ON i.MX6ULL, the 24MHz setpoint is not seen by cpufreq
+ * so we neet to prevent the cpufreq change frequency
+ * from 24MHz to 198Mhz directly. busfreq will handle this
+ * when exit from low bus mode.
+ */
+ if (old_freq == FREQ_24_MHZ && new_freq == FREQ_198_MHZ) {
+ return 0;
+ };
opp = dev_pm_opp_find_freq_ceil(cpu_dev, &freq_hz);
if (IS_ERR(opp)) {
@@ -68,6 +93,16 @@ static int imx6q_set_target(struct cpufreq_policy *policy, unsigned int index)
dev_dbg(cpu_dev, "%u MHz, %ld mV --> %u MHz, %ld mV\n",
old_freq / 1000, volt_old / 1000,
new_freq / 1000, volt / 1000);
+ /*
+ * CPU freq is increasing, so need to ensure
+ * that bus frequency is increased too.
+ */
+ if (low_power_run_support) {
+ if (old_freq == freq_table[0].frequency)
+ request_bus_freq(BUS_FREQ_HIGH);
+ } else if (old_freq <= FREQ_396_MHZ && new_freq > FREQ_396_MHZ) {
+ request_bus_freq(BUS_FREQ_HIGH);
+ }
/* scaling up? scale voltage before frequency */
if (new_freq > old_freq) {
@@ -103,7 +138,8 @@ static int imx6q_set_target(struct cpufreq_policy *policy, unsigned int index)
* - Disable pll2_pfd2_396m_clk
*/
if (of_machine_is_compatible("fsl,imx6ul") ||
- of_machine_is_compatible("fsl,imx6ull")) {
+ of_machine_is_compatible("fsl,imx6ull") ||
+ of_machine_is_compatible("fsl,imx6ulz")) {
/*
* When changing pll1_sw_clk's parent to pll1_sys_clk,
* CPU may run at higher than 528MHz, this will lead to
@@ -119,15 +155,26 @@ static int imx6q_set_target(struct cpufreq_policy *policy, unsigned int index)
clk_set_parent(secondary_sel_clk, pll2_pfd2_396m_clk);
clk_set_parent(step_clk, secondary_sel_clk);
clk_set_parent(pll1_sw_clk, step_clk);
+ if (freq_hz > clk_get_rate(pll2_bus_clk)) {
+ clk_set_rate(pll1_clk, new_freq * 1000);
+ clk_set_parent(pll1_sw_clk, pll1_sys_clk);
+ }
} else {
clk_set_parent(step_clk, pll2_pfd2_396m_clk);
clk_set_parent(pll1_sw_clk, step_clk);
if (freq_hz > clk_get_rate(pll2_pfd2_396m_clk)) {
+ /* Ensure that pll1_bypass is set back to
+ * pll1. We have to do this first so that the
+ * change rate done to pll1_sys_clk done below
+ * can propagate up to pll1.
+ */
+ clk_set_parent(pll1_bypass_clk, pll1_clk);
clk_set_rate(pll1_sys_clk, new_freq * 1000);
clk_set_parent(pll1_sw_clk, pll1_sys_clk);
} else {
/* pll1_sys needs to be enabled for divider rate change to work. */
pll1_sys_temp_enabled = true;
+ clk_set_parent(pll1_bypass_clk, pll1_bypass_src_clk);
clk_prepare_enable(pll1_sys_clk);
}
}
@@ -135,13 +182,13 @@ static int imx6q_set_target(struct cpufreq_policy *policy, unsigned int index)
/* Ensure the arm clock divider is what we expect */
ret = clk_set_rate(arm_clk, new_freq * 1000);
if (ret) {
- int ret1;
-
dev_err(cpu_dev, "failed to set clock rate: %d\n", ret);
ret1 = regulator_set_voltage_tol(arm_reg, volt_old, 0);
- if (ret1)
- dev_warn(cpu_dev,
- "failed to restore vddarm voltage: %d\n", ret1);
+ if (ret1) {
+ dev_err(cpu_dev,
+ "failed to restore vddarm: %d\n", ret1);
+ return ret1;
+ }
return ret;
}
@@ -170,6 +217,16 @@ static int imx6q_set_target(struct cpufreq_policy *policy, unsigned int index)
}
}
}
+ /*
+ * If CPU is dropped to the lowest level, release the need
+ * for a high bus frequency.
+ */
+ if (low_power_run_support) {
+ if (new_freq == freq_table[0].frequency)
+ release_bus_freq(BUS_FREQ_HIGH);
+ } else if (old_freq > FREQ_396_MHZ && new_freq <= FREQ_396_MHZ) {
+ release_bus_freq(BUS_FREQ_HIGH);
+ }
return 0;
}
@@ -179,10 +236,20 @@ static int imx6q_cpufreq_init(struct cpufreq_policy *policy)
int ret;
policy->clk = arm_clk;
+ policy->cur = clk_get_rate(arm_clk) / 1000;
ret = cpufreq_generic_init(policy, freq_table, transition_latency);
policy->suspend_freq = policy->max;
+ if (ret) {
+ dev_err(cpu_dev, "imx6 cpufreq init failed!\n");
+ return ret;
+ }
+ if (low_power_run_support && policy->cur > freq_table[0].frequency) {
+ request_bus_freq(BUS_FREQ_HIGH);
+ } else if (policy->cur > FREQ_396_MHZ) {
+ request_bus_freq(BUS_FREQ_HIGH);
+ }
- return ret;
+ return 0;
}
static struct cpufreq_driver imx6q_cpufreq_driver = {
@@ -196,15 +263,54 @@ static struct cpufreq_driver imx6q_cpufreq_driver = {
.suspend = cpufreq_generic_suspend,
};
+static int imx6_cpufreq_pm_notify(struct notifier_block *nb,
+ unsigned long event, void *dummy)
+{
+ int ret;
+
+ switch (event) {
+ case PM_SUSPEND_PREPARE:
+ if (!IS_ERR(dc_reg) && !ignore_dc_reg) {
+ ret = regulator_set_voltage_tol(dc_reg, DC_VOLTAGE_MAX, 0);
+ if (ret) {
+ dev_err(cpu_dev,
+ "failed to scale dc_reg to max: %d\n", ret);
+ return ret;
+ }
+ }
+ break;
+ case PM_POST_SUSPEND:
+ if (!IS_ERR(dc_reg) && !ignore_dc_reg) {
+ ret = regulator_set_voltage_tol(dc_reg, DC_VOLTAGE_MIN, 0);
+ if (ret) {
+ dev_err(cpu_dev,
+ "failed to scale dc_reg to min: %d\n", ret);
+ return ret;
+ }
+ }
+ break;
+ default:
+ break;
+ }
+
+ return NOTIFY_OK;
+}
+
+static struct notifier_block imx6_cpufreq_pm_notifier = {
+ .notifier_call = imx6_cpufreq_pm_notify,
+};
+
static int imx6q_cpufreq_probe(struct platform_device *pdev)
{
struct device_node *np;
struct dev_pm_opp *opp;
+ struct clk *vpu_axi_podf;
unsigned long min_volt, max_volt;
int num, ret;
const struct property *prop;
const __be32 *val;
- u32 nr, i, j;
+ u32 nr, j, i = 0;
+ u32 vpu_axi_rate = 0;
cpu_dev = get_cpu_device(0);
if (!cpu_dev) {
@@ -223,15 +329,20 @@ static int imx6q_cpufreq_probe(struct platform_device *pdev)
pll1_sw_clk = clk_get(cpu_dev, "pll1_sw");
step_clk = clk_get(cpu_dev, "step");
pll2_pfd2_396m_clk = clk_get(cpu_dev, "pll2_pfd2_396m");
+ pll1_clk = clk_get(cpu_dev, "pll1");
+ pll1_bypass_clk = clk_get(cpu_dev, "pll1_bypass");
+ pll1_bypass_src_clk = clk_get(cpu_dev, "pll1_bypass_src");
if (IS_ERR(arm_clk) || IS_ERR(pll1_sys_clk) || IS_ERR(pll1_sw_clk) ||
- IS_ERR(step_clk) || IS_ERR(pll2_pfd2_396m_clk)) {
+ IS_ERR(step_clk) || IS_ERR(pll2_pfd2_396m_clk) || IS_ERR(pll1_clk) ||
+ IS_ERR(pll1_bypass_clk) || IS_ERR(pll1_bypass_src_clk)) {
dev_err(cpu_dev, "failed to get clocks\n");
ret = -ENOENT;
goto put_clk;
}
if (of_machine_is_compatible("fsl,imx6ul") ||
- of_machine_is_compatible("fsl,imx6ull")) {
+ of_machine_is_compatible("fsl,imx6ull") ||
+ of_machine_is_compatible("fsl,imx6ulz")) {
pll2_bus_clk = clk_get(cpu_dev, "pll2_bus");
secondary_sel_clk = clk_get(cpu_dev, "secondary_sel");
if (IS_ERR(pll2_bus_clk) || IS_ERR(secondary_sel_clk)) {
@@ -241,6 +352,12 @@ static int imx6q_cpufreq_probe(struct platform_device *pdev)
}
}
+ vpu_axi_podf = clk_get(cpu_dev, "vpu_axi_podf");
+ if (!IS_ERR(vpu_axi_podf)) {
+ vpu_axi_rate = clk_get_rate(vpu_axi_podf);
+ clk_put(vpu_axi_podf);
+ }
+
arm_reg = regulator_get(cpu_dev, "arm");
pu_reg = regulator_get_optional(cpu_dev, "pu");
soc_reg = regulator_get(cpu_dev, "soc");
@@ -257,6 +374,22 @@ static int imx6q_cpufreq_probe(struct platform_device *pdev)
goto put_reg;
}
+ dc_reg = devm_regulator_get_optional(cpu_dev, "dc");
+
+ /*
+ * soc_reg sync with arm_reg if arm shares the same regulator
+ * with soc. Otherwise, regulator common framework will refuse to update
+ * this consumer's voltage right now while another consumer voltage
+ * still keep in old one. For example, imx6sx-sdb with pfuze200 in
+ * ldo-bypass mode.
+ */
+ of_property_read_u32(np, "fsl,arm-soc-shared", &i);
+ if (i == 1)
+ soc_reg = arm_reg;
+
+ /* On i.MX6ULL, check the 24MHz low power run mode support */
+ low_power_run_support = of_property_read_bool(np, "fsl,low-power-run");
+
/*
* We expect an OPP table supplied by platform.
* Just, incase the platform did not supply the OPP
@@ -287,6 +420,21 @@ static int imx6q_cpufreq_probe(struct platform_device *pdev)
goto out_free_opp;
}
+ /*
+ * On i.MX6UL/ULL EVK board, if the SOC is run in overide frequency,
+ * the dc_regulator voltage should not be touched.
+ */
+ if (freq_table[num - 1].frequency > FREQ_528_MHZ)
+ ignore_dc_reg = true;
+ if (!IS_ERR(dc_reg) && !ignore_dc_reg) {
+ ret = regulator_set_voltage_tol(dc_reg, DC_VOLTAGE_MIN, 0);
+ if (ret) {
+ dev_err(cpu_dev,
+ "failed to scale dc_reg to min: %d\n", ret);
+ return ret;
+ }
+ }
+
/* Make imx6_soc_volt array's size same as arm opp number */
imx6_soc_volt = devm_kzalloc(cpu_dev, sizeof(*imx6_soc_volt) * num, GFP_KERNEL);
if (imx6_soc_volt == NULL) {
@@ -313,6 +461,19 @@ static int imx6q_cpufreq_probe(struct platform_device *pdev)
unsigned long volt = be32_to_cpup(val++);
if (freq_table[j].frequency == freq) {
imx6_soc_volt[soc_opp_count++] = volt;
+#ifdef CONFIG_MX6_VPU_352M
+ if (freq == 792000) {
+ pr_info("increase SOC/PU voltage for VPU352MHz\n");
+ imx6_soc_volt[soc_opp_count - 1] = 1250000;
+ }
+#endif
+ if (vpu_axi_rate == 396000000) {
+ if (freq <= 996000) {
+ pr_info("increase SOC/PU voltage for VPU396MHz at %ld MHz\n",
+ freq / 1000);
+ imx6_soc_volt[soc_opp_count - 1] = 1275000;
+ }
+ }
break;
}
}
@@ -368,6 +529,8 @@ soc_opp_out:
goto free_freq_table;
}
+ register_pm_notifier(&imx6_cpufreq_pm_notifier);
+
of_node_put(np);
return 0;
@@ -394,6 +557,12 @@ put_clk:
clk_put(step_clk);
if (!IS_ERR(pll2_pfd2_396m_clk))
clk_put(pll2_pfd2_396m_clk);
+ if (!IS_ERR(pll1_clk))
+ clk_put(pll1_clk);
+ if (!IS_ERR(pll1_bypass_clk))
+ clk_put(pll1_bypass_clk);
+ if (!IS_ERR(pll1_bypass_src_clk))
+ clk_put(pll1_bypass_src_clk);
if (!IS_ERR(pll2_bus_clk))
clk_put(pll2_bus_clk);
if (!IS_ERR(secondary_sel_clk))
diff --git a/drivers/cpufreq/imx7ulp-cpufreq.c b/drivers/cpufreq/imx7ulp-cpufreq.c
new file mode 100644
index 000000000000..55c52d8f611b
--- /dev/null
+++ b/drivers/cpufreq/imx7ulp-cpufreq.c
@@ -0,0 +1,266 @@
+ /*
+ * Copyright 2017 NXP.
+ *
+ * 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/cpu.h>
+#include <linux/cpufreq.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/pm_opp.h>
+#include <linux/pm_qos.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/consumer.h>
+#include <linux/suspend.h>
+
+#define MAX_RUN_FREQ 528000
+
+static struct clk *arm_clk;
+static struct clk *core_div;
+static struct clk *sys_sel;
+static struct clk *hsrun_sys_sel;
+static struct clk *hsrun_core;
+static struct clk *spll_pfd0;
+static struct clk *spll_sel;
+static struct clk *firc_clk;
+static struct clk *spll;
+
+static struct pm_qos_request pm_qos_hsrun;
+static struct regulator *arm_reg;
+static struct device *cpu_dev;
+static struct cpufreq_frequency_table *freq_table;
+static unsigned int transition_latency;
+
+static int imx7ulp_set_target(struct cpufreq_policy *policy, unsigned int index)
+{
+ struct dev_pm_opp *opp;
+ unsigned long freq_hz, volt, volt_old;
+ unsigned int old_freq, new_freq;
+ int ret;
+
+ new_freq = freq_table[index].frequency;
+ freq_hz = new_freq * 1000;
+ old_freq = clk_get_rate(arm_clk) / 1000;
+ if (new_freq == 0 || old_freq == 0)
+ return -EINVAL;
+
+ opp = dev_pm_opp_find_freq_ceil(cpu_dev, &freq_hz);
+ if (IS_ERR(opp)) {
+ dev_err(cpu_dev, "failed to find OPP for %ld\n", freq_hz);
+ return PTR_ERR(opp);
+ }
+ volt = dev_pm_opp_get_voltage(opp);
+ dev_pm_opp_put(opp);
+
+ volt_old = regulator_get_voltage(arm_reg);
+
+ dev_dbg(cpu_dev, "%u MHz, %ld mV --> %u MHz, %ld mV\n",
+ old_freq / 1000, volt_old / 1000,
+ new_freq / 1000, volt / 1000);
+
+ /* Scaling up? scale voltage before frequency */
+ if (new_freq > old_freq) {
+ ret = regulator_set_voltage_tol(arm_reg, volt, 0);
+ if (ret) {
+ dev_err(cpu_dev, "failed to scale vddarm up: %d\n", ret);
+ return ret;
+ }
+ }
+
+ /* before changing pll_arm rate, change the arm_src's soure
+ * to firc clk first.
+ */
+ if (new_freq > MAX_RUN_FREQ) {
+ pm_qos_add_request(&pm_qos_hsrun, PM_QOS_CPU_DMA_LATENCY, 0);
+ /* change the RUN clock to firc */
+ clk_set_parent(sys_sel, firc_clk);
+ /* change the clock rate in HSRUN */
+ clk_set_rate(spll, 480000000);
+ clk_set_rate(spll_pfd0, new_freq * 1000);
+ clk_set_parent(hsrun_sys_sel, spll_sel);
+ clk_set_parent(arm_clk, hsrun_core);
+ } else {
+ /* change the HSRUN clock to firc */
+ clk_set_parent(hsrun_sys_sel, firc_clk);
+ /* change the clock rate in RUN */
+ clk_set_rate(spll, 528000000);
+ clk_set_rate(spll_pfd0, new_freq * 1000);
+ clk_set_parent(sys_sel, spll_sel);
+ clk_set_parent(arm_clk, core_div);
+ if (old_freq > MAX_RUN_FREQ)
+ pm_qos_remove_request(&pm_qos_hsrun);
+ }
+
+ /* scaling down? scaling voltage after frequency */
+ if (new_freq < old_freq) {
+ ret = regulator_set_voltage_tol(arm_reg, volt, 0);
+ if (ret) {
+ dev_warn(cpu_dev, "failed to scale vddarm down: %d\n", ret);
+ ret = 0;
+ }
+ }
+
+ return 0;
+}
+
+static int imx7ulp_cpufreq_init(struct cpufreq_policy *policy)
+{
+ int ret;
+ policy->clk = arm_clk;
+ policy->cur = clk_get_rate(arm_clk) / 1000;
+ policy->suspend_freq = freq_table[0].frequency;
+
+ ret = cpufreq_generic_init(policy, freq_table, transition_latency);
+
+ if (ret) {
+ dev_err(cpu_dev, "imx7ulp cpufreq init failed\n");
+ return ret;
+ }
+
+ return 0;
+}
+
+static struct cpufreq_driver imx7ulp_cpufreq_driver = {
+ .flags = CPUFREQ_NEED_INITIAL_FREQ_CHECK,
+ .verify = cpufreq_generic_frequency_table_verify,
+ .target_index = imx7ulp_set_target,
+ .get = cpufreq_generic_get,
+ .init = imx7ulp_cpufreq_init,
+ .name = "imx7ulp-cpufreq",
+ .attr = cpufreq_generic_attr,
+#ifdef CONFIG_PM
+ .suspend = cpufreq_generic_suspend,
+#endif
+};
+
+static int imx7ulp_cpufreq_probe(struct platform_device *pdev)
+{
+ struct device_node *np;
+ int ret;
+
+ cpu_dev = get_cpu_device(0);
+ if (!cpu_dev) {
+ pr_err("failed to get cpu0 device\n");
+ return -ENOENT;
+ }
+
+ np = of_node_get(cpu_dev->of_node);
+ if (!np) {
+ dev_err(cpu_dev, "failed to find the cpu0 node\n");
+ return -ENOENT;
+ }
+
+ arm_clk = clk_get(cpu_dev, "arm");
+ sys_sel = clk_get(cpu_dev, "sys_sel");
+ core_div = clk_get(cpu_dev, "core_div");
+ hsrun_sys_sel = clk_get(cpu_dev, "hsrun_sys_sel");
+ hsrun_core = clk_get(cpu_dev, "hsrun_core");
+ spll_pfd0 = clk_get(cpu_dev, "spll_pfd0");
+ spll_sel = clk_get(cpu_dev, "spll_sel");
+ firc_clk = clk_get(cpu_dev, "firc");
+ spll = clk_get(cpu_dev, "spll");
+
+ if (IS_ERR(arm_clk) || IS_ERR(sys_sel) || IS_ERR(spll_sel) ||
+ IS_ERR(spll_sel) || IS_ERR(firc_clk) || IS_ERR(hsrun_sys_sel) ||
+ IS_ERR(hsrun_core) || IS_ERR(spll)) {
+ dev_err(cpu_dev, "failed to get cpu clock\n");
+ ret = -ENOENT;
+ goto put_clk;
+ }
+
+ arm_reg = regulator_get(cpu_dev, "arm");
+ if (IS_ERR(arm_reg)) {
+ dev_err(cpu_dev, "failed to get regulator\n");
+ ret = -ENOENT;
+ goto put_reg;
+ }
+
+ ret = dev_pm_opp_of_add_table(cpu_dev);
+ if (ret < 0) {
+ dev_err(cpu_dev, "failed to init OPP table: %d\n", ret);
+ goto put_reg;
+ }
+
+ ret = dev_pm_opp_init_cpufreq_table(cpu_dev, &freq_table);
+ if (ret) {
+ dev_err(cpu_dev, "failed to init cpufreq table\n");
+ goto put_reg;
+ }
+
+ if (of_property_read_u32(np, "clock-latency", &transition_latency))
+ transition_latency = CPUFREQ_ETERNAL;
+
+ ret = cpufreq_register_driver(&imx7ulp_cpufreq_driver);
+ if (ret) {
+ dev_err(cpu_dev, "failed to register driver\n");
+ goto free_opp_table;
+ }
+
+ return 0;
+
+free_opp_table:
+ dev_pm_opp_free_cpufreq_table(cpu_dev, &freq_table);
+put_reg:
+ regulator_put(arm_reg);
+put_clk:
+ if (!IS_ERR(arm_clk))
+ clk_put(arm_clk);
+ if (!IS_ERR(sys_sel))
+ clk_put(sys_sel);
+ if (!IS_ERR(core_div))
+ clk_put(core_div);
+ if (!IS_ERR(hsrun_sys_sel))
+ clk_put(hsrun_sys_sel);
+ if (!IS_ERR(hsrun_core))
+ clk_put(hsrun_core);
+ if (!IS_ERR(spll_pfd0))
+ clk_put(spll_pfd0);
+ if (!IS_ERR(spll_sel))
+ clk_put(spll_sel);
+ if (!IS_ERR(firc_clk))
+ clk_put(firc_clk);
+ if (!IS_ERR(spll))
+ clk_put(spll);
+
+ return ret;
+}
+
+static int imx7ulp_cpufreq_remove(struct platform_device *pdev)
+{
+ cpufreq_unregister_driver(&imx7ulp_cpufreq_driver);
+ dev_pm_opp_free_cpufreq_table(cpu_dev, &freq_table);
+
+ regulator_put(arm_reg);
+ clk_put(arm_clk);
+ clk_put(sys_sel);
+ clk_put(core_div);
+ clk_put(hsrun_sys_sel);
+ clk_put(hsrun_core);
+ clk_put(spll_pfd0);
+ clk_put(spll_sel);
+ clk_put(firc_clk);
+ clk_put(spll);
+
+ return 0;
+}
+
+static struct platform_driver imx7ulp_cpufreq_platdrv = {
+ .driver = {
+ .name = "imx7ulp-cpufreq",
+ .owner = THIS_MODULE,
+ },
+ .probe = imx7ulp_cpufreq_probe,
+ .remove = imx7ulp_cpufreq_remove,
+};
+
+module_platform_driver(imx7ulp_cpufreq_platdrv);
+
+MODULE_DESCRIPTION("NXP i.MX7ULP cpufreq driver");
+MODULE_LICENSE("GPL v2");
+
diff --git a/drivers/cpufreq/imx8-cpufreq.c b/drivers/cpufreq/imx8-cpufreq.c
new file mode 100644
index 000000000000..5cefb4500303
--- /dev/null
+++ b/drivers/cpufreq/imx8-cpufreq.c
@@ -0,0 +1,293 @@
+/*
+ * Copyright 2017 NXP
+ *
+ * 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/arm-smccc.h>
+#include <linux/clk.h>
+#include <linux/cpu.h>
+#include <linux/cpufreq.h>
+#include <linux/cpu_cooling.h>
+#include <linux/err.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/pm_opp.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/consumer.h>
+#include <linux/syscalls.h>
+#include <soc/imx/fsl_sip.h>
+
+#define MAX_CLUSTER_NUM 2
+
+static struct delayed_work cpufreq_governor_daemon;
+
+static DEFINE_SPINLOCK(cpufreq_psci_lock);
+
+struct imx8_cpufreq {
+ struct clk *cpu_clk;
+};
+
+struct imx8_cpufreq cluster_freq[MAX_CLUSTER_NUM];
+static struct cpufreq_frequency_table *freq_table[MAX_CLUSTER_NUM];
+static unsigned int transition_latency[MAX_CLUSTER_NUM];
+struct device *cpu_dev;
+static struct thermal_cooling_device *cdev[2];
+
+static void cpufreq_governor_daemon_handler(struct work_struct *work)
+{
+ int fd, i;
+ unsigned char cluster_governor[MAX_CLUSTER_NUM][54] = {
+ "/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor",
+ "",
+ };
+
+ /* generate second cluster's cpufreq governor path */
+ sprintf(cluster_governor[MAX_CLUSTER_NUM - 1],
+ "%s%d%s", "/sys/devices/system/cpu/cpu", num_online_cpus() - 1,
+ "/cpufreq/scaling_governor");
+
+ for (i = 0; i < MAX_CLUSTER_NUM; i++) {
+ fd = sys_open((const char __user __force *)cluster_governor[i],
+ O_RDWR, 0700);
+ if (fd >= 0) {
+ sys_write(fd, "schedutil", strlen("schedutil"));
+ sys_close(fd);
+ pr_info("switch cluster %d cpu-freq governor to schedutil\n",
+ i);
+ } else {
+ /* re-schedule if sys write is NOT ready */
+ schedule_delayed_work(&cpufreq_governor_daemon,
+ msecs_to_jiffies(3000));
+ break;
+ }
+ }
+}
+
+static int imx8_set_target(struct cpufreq_policy *policy, unsigned int index)
+{
+ struct arm_smccc_res res;
+ unsigned int old_freq, new_freq;
+ unsigned int cluster_id = topology_physical_package_id(policy->cpu);
+
+ new_freq = freq_table[cluster_id][index].frequency;
+ old_freq = policy->cur;
+
+ dev_dbg(cpu_dev, "%u MHz --> %u MHz\n",
+ old_freq / 1000, new_freq / 1000);
+
+ spin_lock(&cpufreq_psci_lock);
+ arm_smccc_smc(FSL_SIP_CPUFREQ, FSL_SIP_SET_CPUFREQ,
+ cluster_id, new_freq * 1000, 0, 0, 0, 0, &res);
+ spin_unlock(&cpufreq_psci_lock);
+
+ /*
+ * As we can only set CPU clock rate in ATF, clock
+ * framework does NOT know CPU clock rate is changed,
+ * so here do clk_get_rate once to update CPU clock
+ * rate, otherwise cat /sys/kernel/debug/clk/xxx/clk_rate
+ * will return incorrect rate as it does NOT do a
+ * recalculation.
+ */
+ clk_get_rate(cluster_freq[cluster_id].cpu_clk);
+
+ return 0;
+}
+
+static int imx8_cpufreq_init(struct cpufreq_policy *policy)
+{
+ int cluster_id = topology_physical_package_id(policy->cpu);
+ int ret = 0;
+
+ policy->clk = cluster_freq[cluster_id].cpu_clk;
+ policy->cur = clk_get_rate(cluster_freq[cluster_id].cpu_clk) / 1000;
+ /*
+ * The driver only supports the SMP configuartion where all processors
+ * share the clock and voltage and clock.
+ */
+ cpumask_copy(policy->cpus, topology_core_cpumask(policy->cpu));
+
+ ret = cpufreq_table_validate_and_show(policy, freq_table[cluster_id]);
+ if (ret) {
+ pr_err("%s: invalid frequency table: %d\n", __func__, ret);
+ return ret;
+ }
+
+ policy->cpuinfo.transition_latency = transition_latency[cluster_id];
+ policy->suspend_freq = policy->max;
+
+ pr_info("%s: cluster %d running at freq %d MHz, suspend freq %d MHz\n",
+ __func__, cluster_id, policy->cur / 1000,
+ policy->suspend_freq / 1000);
+
+ return ret;
+}
+
+static void imx8_cpufreq_ready(struct cpufreq_policy *policy)
+{
+ struct device_node *np = of_get_cpu_node(policy->cpu, NULL);
+ unsigned int cluster_id = topology_physical_package_id(policy->cpu);
+
+ if (of_find_property(np, "#cooling-cells", NULL)) {
+ cdev[cluster_id] = of_cpufreq_cooling_register(np, policy);
+
+ if (IS_ERR(cdev[cluster_id]) && PTR_ERR(cdev[cluster_id]) != -ENOSYS) {
+ pr_err("cpu%d is not running as cooling device: %ld\n",
+ policy->cpu, PTR_ERR(cdev[cluster_id]));
+
+ cdev[cluster_id] = NULL;
+ }
+ }
+
+ of_node_put(np);
+}
+
+static struct cpufreq_driver imx8_cpufreq_driver = {
+ .flags = CPUFREQ_NEED_INITIAL_FREQ_CHECK,
+ .verify = cpufreq_generic_frequency_table_verify,
+ .target_index = imx8_set_target,
+ .get = cpufreq_generic_get,
+ .init = imx8_cpufreq_init,
+ .name = "imx8-cpufreq",
+ .attr = cpufreq_generic_attr,
+ .ready = imx8_cpufreq_ready,
+#ifdef CONFIG_PM
+ .suspend = cpufreq_generic_suspend,
+#endif
+};
+
+static int imx8_cpufreq_probe(struct platform_device *pdev)
+{
+ struct device_node *np;
+ int ret = 0;
+ int i, cluster_id;
+ struct device *first_cpu_dev = NULL;
+
+ cpu_dev = get_cpu_device(0);
+
+ if (!cpu_dev) {
+ pr_err("failed to get cpu device 0\n");
+ return -ENODEV;
+ }
+
+ np = of_node_get(cpu_dev->of_node);
+ if (!np) {
+ pr_warn("failed to find cpu 0 node\n");
+ return -ENODEV;
+ }
+
+ ret = dev_pm_opp_of_add_table(cpu_dev);
+ if (ret < 0) {
+ dev_err(cpu_dev, "failed to init OPP table: %d\n", ret);
+ goto put_node;
+ }
+
+ cluster_id = topology_physical_package_id(0);
+ cluster_freq[cluster_id].cpu_clk = devm_clk_get(cpu_dev, NULL);
+ if (IS_ERR(cluster_freq[cluster_id].cpu_clk)) {
+ dev_err(cpu_dev, "failed to get cluster %d clock\n", cluster_id);
+ ret = -ENOENT;
+ goto put_node;
+ }
+
+ ret = dev_pm_opp_init_cpufreq_table(cpu_dev, &freq_table[cluster_id]);
+ if (ret) {
+ dev_err(cpu_dev, "failed to init cpufreq table: %d\n", ret);
+ goto out_free_opp;
+ }
+
+ if (of_property_read_u32(np, "clock-latency", &transition_latency[cluster_id]))
+ transition_latency[cluster_id] = CPUFREQ_ETERNAL;
+
+ /* init next cluster if there is */
+ for (i = 1; i < num_online_cpus(); i++) {
+ if (topology_physical_package_id(i) == topology_physical_package_id(0))
+ continue;
+
+ INIT_DELAYED_WORK(&cpufreq_governor_daemon,
+ cpufreq_governor_daemon_handler);
+ schedule_delayed_work(&cpufreq_governor_daemon,
+ msecs_to_jiffies(3000));
+ first_cpu_dev = cpu_dev;
+ cpu_dev = get_cpu_device(i);
+ if (!cpu_dev) {
+ pr_err("failed to get cpu device %d\n", i);
+ return -ENODEV;
+ }
+
+ np = of_node_get(cpu_dev->of_node);
+ if (!np) {
+ pr_warn("failed to find cpu %d node\n", i);
+ ret = -ENODEV;
+ goto put_node;
+ }
+
+ cluster_id = topology_physical_package_id(i);
+ cluster_freq[cluster_id].cpu_clk = devm_clk_get(cpu_dev, NULL);
+ if (IS_ERR(cluster_freq[cluster_id].cpu_clk)) {
+ dev_err(cpu_dev, "failed to get cluster %d clock\n", cluster_id);
+ ret = -ENOENT;
+ goto put_node;
+ }
+
+ ret = dev_pm_opp_of_add_table(cpu_dev);
+ if (ret < 0) {
+ dev_err(cpu_dev, "failed to init OPP table: %d\n", ret);
+ goto put_node;
+ }
+
+ ret = dev_pm_opp_init_cpufreq_table(cpu_dev, &freq_table[cluster_id]);
+ if (ret) {
+ dev_err(cpu_dev, "failed to init cpufreq table: %d\n", ret);
+ goto out_free_opp;
+ }
+
+ if (of_property_read_u32(np, "clock-latency", &transition_latency[cluster_id]))
+ transition_latency[cluster_id] = CPUFREQ_ETERNAL;
+ break;
+ }
+
+ ret = cpufreq_register_driver(&imx8_cpufreq_driver);
+ if (ret) {
+ dev_err(cpu_dev, "failed register driver: %d\n", ret);
+ if (cluster_id > 0 && first_cpu_dev != NULL) {
+ dev_pm_opp_free_cpufreq_table(first_cpu_dev, &freq_table[0]);
+ dev_pm_opp_of_remove_table(first_cpu_dev);
+ }
+ goto free_freq_table;
+ }
+
+ of_node_put(np);
+
+ return 0;
+
+free_freq_table:
+ dev_pm_opp_free_cpufreq_table(cpu_dev, &freq_table[cluster_id]);
+out_free_opp:
+ dev_pm_opp_of_remove_table(cpu_dev);
+put_node:
+ of_node_put(np);
+ return ret;
+}
+
+static int imx8_cpufreq_remove(struct platform_device *pdev)
+{
+ cpufreq_unregister_driver(&imx8_cpufreq_driver);
+
+ return 0;
+}
+
+static struct platform_driver imx8_cpufreq_platdrv = {
+ .driver = {
+ .name = "imx8-cpufreq",
+ },
+ .probe = imx8_cpufreq_probe,
+ .remove = imx8_cpufreq_remove,
+};
+module_platform_driver(imx8_cpufreq_platdrv);
+
+MODULE_AUTHOR("Anson Huang <Anson.Huang@nxp.com>");
+MODULE_DESCRIPTION("NXP i.MX8 cpufreq driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/cpufreq/imx8mq-cpufreq.c b/drivers/cpufreq/imx8mq-cpufreq.c
new file mode 100644
index 000000000000..326710dd6c17
--- /dev/null
+++ b/drivers/cpufreq/imx8mq-cpufreq.c
@@ -0,0 +1,275 @@
+/*
+ * Copyright (C) 2017-2018 NXP
+ *
+ * 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/cpu.h>
+#include <linux/cpufreq.h>
+#include <linux/cpu_cooling.h>
+#include <linux/err.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/of.h>
+#include <linux/pm_opp.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/consumer.h>
+#include <linux/suspend.h>
+
+#define DC_VOLTAGE_MIN 900000
+#define DC_VOLTAGE_MAX 1000000
+
+static struct device *cpu_dev;
+static bool free_opp;
+static struct cpufreq_frequency_table *freq_table;
+static unsigned int transition_latency;
+static struct clk *a53_clk;
+static struct clk *arm_a53_src_clk;
+static struct clk *arm_pll_clk;
+static struct clk *arm_pll_out_clk;
+static struct clk *sys1_pll_800m_clk;
+struct thermal_cooling_device *cdev;
+static struct regulator *dc_reg;
+static struct regulator *arm_reg;
+
+static int imx8mq_set_target(struct cpufreq_policy *policy, unsigned int index)
+{
+ struct dev_pm_opp *opp;
+ unsigned long freq_hz, volt;
+ unsigned int old_freq, new_freq;
+ int ret;
+
+ new_freq = freq_table[index].frequency;
+ freq_hz = new_freq * 1000;
+ old_freq = policy->cur;
+
+ opp = dev_pm_opp_find_freq_ceil(cpu_dev, &freq_hz);
+ if (IS_ERR(opp)) {
+ dev_err(cpu_dev, "failed to find OPP for %ld\n", freq_hz);
+ return PTR_ERR(opp);
+ }
+ volt = dev_pm_opp_get_voltage(opp);
+ dev_pm_opp_put(opp);
+
+ dev_dbg(cpu_dev, "%u MHz --> %u MHz\n",
+ old_freq / 1000, new_freq / 1000);
+
+ if (new_freq == policy->max) {
+ if (!IS_ERR(dc_reg)) {
+ ret = regulator_set_voltage_tol(dc_reg, DC_VOLTAGE_MAX, 0);
+ if (ret) {
+ dev_err(cpu_dev, "failed to scale dc_reg up: %d\n", ret);
+ return ret;
+ }
+ }
+ }
+
+ if (new_freq > old_freq) {
+ if (!IS_ERR(arm_reg)) {
+ ret = regulator_set_voltage_tol(arm_reg, volt, 0);
+ if (ret) {
+ dev_err(cpu_dev, "failed to scale arm_reg up: %d\n", ret);
+ return ret;
+ }
+ }
+ }
+
+ clk_set_parent(arm_a53_src_clk, sys1_pll_800m_clk);
+ clk_set_rate(arm_pll_clk, new_freq * 1000);
+ clk_set_parent(arm_a53_src_clk, arm_pll_out_clk);
+
+ if (old_freq == policy->max) {
+ if (!IS_ERR(dc_reg)) {
+ ret = regulator_set_voltage_tol(dc_reg, DC_VOLTAGE_MIN, 0);
+ if (ret) {
+ dev_err(cpu_dev, "failed to scale dc_reg down: %d\n", ret);
+ return ret;
+ }
+ }
+ }
+
+ if (new_freq < old_freq) {
+ if (!IS_ERR(arm_reg)) {
+ ret = regulator_set_voltage_tol(arm_reg, volt, 0);
+ if (ret) {
+ dev_err(cpu_dev, "failed to scale arm_reg down: %d\n", ret);
+ return ret;
+ }
+ }
+ }
+
+ /* Ensure the arm clock divider is what we expect */
+ ret = clk_set_rate(a53_clk, new_freq * 1000);
+ if (ret)
+ dev_err(cpu_dev, "failed to set clock rate: %d\n", ret);
+
+ return ret;
+}
+
+static void imx8mq_cpufreq_ready(struct cpufreq_policy *policy)
+{
+ struct device_node *np = of_get_cpu_node(policy->cpu, NULL);
+
+ if (of_find_property(np, "#cooling-cells", NULL)) {
+ cdev = of_cpufreq_cooling_register(np, policy);
+
+ if (IS_ERR(cdev) && PTR_ERR(cdev) != -ENOSYS) {
+ pr_err("cpu%d is not running as cooling device: %ld\n",
+ policy->cpu, PTR_ERR(cdev));
+
+ cdev = NULL;
+ }
+ }
+
+ of_node_put(np);
+}
+
+static int imx8mq_cpufreq_init(struct cpufreq_policy *policy)
+{
+ int ret;
+
+ policy->clk = a53_clk;
+ policy->cur = clk_get_rate(a53_clk) / 1000;
+
+ ret = cpufreq_generic_init(policy, freq_table, transition_latency);
+ if (ret) {
+ dev_err(cpu_dev, "imx8mq cpufreq init failed!\n");
+ return ret;
+ }
+
+ policy->suspend_freq = policy->max;
+
+ return 0;
+}
+
+static struct cpufreq_driver imx8mq_cpufreq_driver = {
+ .flags = CPUFREQ_NEED_INITIAL_FREQ_CHECK,
+ .verify = cpufreq_generic_frequency_table_verify,
+ .target_index = imx8mq_set_target,
+ .get = cpufreq_generic_get,
+ .init = imx8mq_cpufreq_init,
+ .name = "imx8mq-cpufreq",
+ .ready = imx8mq_cpufreq_ready,
+ .attr = cpufreq_generic_attr,
+#ifdef CONFIG_PM
+ .suspend = cpufreq_generic_suspend,
+#endif
+};
+
+static int imx8mq_cpufreq_probe(struct platform_device *pdev)
+{
+ struct device_node *np;
+ int ret, num;
+
+ cpu_dev = get_cpu_device(0);
+ if (!cpu_dev) {
+ pr_err("failed to get cpu0 device\n");
+ return -ENODEV;
+ }
+
+ np = of_node_get(cpu_dev->of_node);
+ if (!np) {
+ dev_err(cpu_dev, "failed to find cpu0 node\n");
+ return -ENOENT;
+ }
+
+ a53_clk = clk_get(cpu_dev, "a53");
+ arm_a53_src_clk = clk_get(cpu_dev, "arm_a53_src");
+ arm_pll_clk = clk_get(cpu_dev, "arm_pll");
+ arm_pll_out_clk = clk_get(cpu_dev, "arm_pll_out");
+ sys1_pll_800m_clk = clk_get(cpu_dev, "sys1_pll_800m");
+ if (IS_ERR(a53_clk) || IS_ERR(arm_a53_src_clk)
+ || IS_ERR(arm_pll_out_clk) || IS_ERR(arm_pll_clk)
+ || IS_ERR(sys1_pll_800m_clk)) {
+ dev_err(cpu_dev, "failed to get clocks\n");
+ ret = -ENOENT;
+ goto put_clk;
+ }
+
+ dc_reg = regulator_get_optional(cpu_dev, "dc");
+ arm_reg = regulator_get_optional(cpu_dev, "arm");
+
+ /*
+ * We expect an OPP table supplied by platform.
+ * Just, incase the platform did not supply the OPP
+ * table, it will try to get it.
+ */
+ num = dev_pm_opp_get_opp_count(cpu_dev);
+ if (num < 0) {
+ ret = dev_pm_opp_of_add_table(cpu_dev);
+ if (ret < 0) {
+ dev_err(cpu_dev, "failed to init OPP table: %d\n", ret);
+ goto put_clk;
+ }
+ }
+
+ ret = dev_pm_opp_init_cpufreq_table(cpu_dev, &freq_table);
+ if (ret) {
+ dev_err(cpu_dev, "failed to init cpufreq table: %d\n", ret);
+ goto out_free_opp;
+ }
+
+ if (of_property_read_u32(np, "clock-latency", &transition_latency))
+ transition_latency = CPUFREQ_ETERNAL;
+
+ ret = cpufreq_register_driver(&imx8mq_cpufreq_driver);
+ if (ret) {
+ dev_err(cpu_dev, "failed register driver: %d\n", ret);
+ goto free_freq_table;
+ }
+
+ of_node_put(np);
+ dev_info(cpu_dev, "registered imx8mq-cpufreq\n");
+
+ return 0;
+
+free_freq_table:
+ dev_pm_opp_free_cpufreq_table(cpu_dev, &freq_table);
+out_free_opp:
+ dev_pm_opp_of_remove_table(cpu_dev);
+put_clk:
+ if (!IS_ERR(a53_clk))
+ clk_put(a53_clk);
+ if (!IS_ERR(arm_a53_src_clk))
+ clk_put(arm_a53_src_clk);
+ if (!IS_ERR(arm_pll_clk))
+ clk_put(arm_pll_clk);
+ if (!IS_ERR(arm_pll_out_clk))
+ clk_put(arm_pll_out_clk);
+ if (!IS_ERR(sys1_pll_800m_clk))
+ clk_put(sys1_pll_800m_clk);
+ of_node_put(np);
+ return ret;
+}
+
+static int imx8mq_cpufreq_remove(struct platform_device *pdev)
+{
+ cpufreq_cooling_unregister(cdev);
+ cpufreq_unregister_driver(&imx8mq_cpufreq_driver);
+ dev_pm_opp_free_cpufreq_table(cpu_dev, &freq_table);
+ if (free_opp)
+ dev_pm_opp_of_remove_table(cpu_dev);
+ clk_put(a53_clk);
+ clk_put(arm_a53_src_clk);
+ clk_put(arm_pll_clk);
+ clk_put(arm_pll_out_clk);
+ clk_put(sys1_pll_800m_clk);
+
+ return 0;
+}
+
+static struct platform_driver imx8mq_cpufreq_platdrv = {
+ .driver = {
+ .name = "imx8mq-cpufreq",
+ },
+ .probe = imx8mq_cpufreq_probe,
+ .remove = imx8mq_cpufreq_remove,
+};
+module_platform_driver(imx8mq_cpufreq_platdrv);
+
+MODULE_AUTHOR("Anson Huang <Anson.Huang@nxp.com>");
+MODULE_DESCRIPTION("Freescale i.MX8MQ cpufreq driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/crypto/caam/Kconfig b/drivers/crypto/caam/Kconfig
index 1eb852765469..4b9168fb382a 100644
--- a/drivers/crypto/caam/Kconfig
+++ b/drivers/crypto/caam/Kconfig
@@ -1,6 +1,6 @@
config CRYPTO_DEV_FSL_CAAM
tristate "Freescale CAAM-Multicore driver backend"
- depends on FSL_SOC || ARCH_MXC || ARCH_LAYERSCAPE
+ depends on FSL_SOC || ARCH_MXC || ARCH_LAYERSCAPE || ARCH_MXC_ARM64
select SOC_BUS
help
Enables the driver module for Freescale's Cryptographic Accelerator
@@ -80,6 +80,7 @@ config CRYPTO_DEV_FSL_CAAM_CRYPTO_API
select CRYPTO_AEAD
select CRYPTO_AUTHENC
select CRYPTO_BLKCIPHER
+ select CRYPTO_DES
help
Selecting this will offload crypto for users of the
scatterlist crypto API (such as the linux native IPSec
@@ -142,6 +143,66 @@ config CRYPTO_DEV_FSL_CAAM_RNG_API
To compile this as a module, choose M here: the module
will be called caamrng.
+config CRYPTO_DEV_FSL_CAAM_TK_API
+ bool "Register tagged key cryptography implementations with Crypto API"
+ depends on CRYPTO_DEV_FSL_CAAM_CRYPTO_API
+ help
+ Selecting this will register algorithms supporting tagged
+ key.
+
+ Tagged key are keys that contains metadata indicating what
+ they are and how to handle them.
+
+config CRYPTO_DEV_FSL_CAAM_RNG_TEST
+ boolean "Test caam rng"
+ depends on CRYPTO_DEV_FSL_CAAM_RNG_API
+ default n
+ help
+ Selecting this will enable a self-test to run for the
+ caam RNG. This test is several minutes long and executes
+ just before the RNG is registered with the hw_random API.
+
+config CRYPTO_DEV_FSL_CAAM_SM
+ tristate "CAAM Secure Memory / Keystore API (EXPERIMENTAL)"
+ default n
+ help
+ Enables use of a prototype kernel-level Keystore API with CAAM
+ Secure Memory for insertion/extraction of bus-protected secrets.
+
+config CRYPTO_DEV_FSL_CAAM_SM_SLOTSIZE
+ int "Size of each keystore slot in Secure Memory"
+ depends on CRYPTO_DEV_FSL_CAAM_SM
+ range 5 9
+ default 7
+ help
+ Select size of allocation units to divide Secure Memory pages into
+ (the size of a "slot" as referenced inside the API code).
+ Established as powers of two.
+ Examples:
+ 5 => 32 bytes
+ 6 => 64 bytes
+ 7 => 128 bytes
+ 8 => 256 bytes
+ 9 => 512 bytes
+
+config CRYPTO_DEV_FSL_CAAM_SM_TEST
+ tristate "CAAM Secure Memory - Keystore Test/Example (EXPERIMENTAL)"
+ depends on CRYPTO_DEV_FSL_CAAM_SM
+ default n
+ help
+ Example thread to exercise the Keystore API and to verify that
+ stored and recovered secrets can be used for general purpose
+ encryption/decryption.
+
+config CRYPTO_DEV_FSL_CAAM_SECVIO
+ tristate "CAAM/SNVS Security Violation Handler (EXPERIMENTAL)"
+ depends on CRYPTO_DEV_FSL_CAAM
+ default n
+ help
+ Enables installation of an interrupt handler with registrable
+ handler functions which can be specified to act on the consequences
+ of a security violation.
+
config CRYPTO_DEV_FSL_CAAM_DEBUG
bool "Enable debug output in CAAM driver"
depends on CRYPTO_DEV_FSL_CAAM
diff --git a/drivers/crypto/caam/Makefile b/drivers/crypto/caam/Makefile
index cb652ee7dfc8..229e7d986dfa 100644
--- a/drivers/crypto/caam/Makefile
+++ b/drivers/crypto/caam/Makefile
@@ -14,11 +14,16 @@ obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API_DESC) += caamalg_desc.o
obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM_AHASH_API) += caamhash.o
obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM_RNG_API) += caamrng.o
obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM_PKC_API) += caam_pkc.o
+obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM_SM) += sm_store.o
+obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM_SM_TEST) += sm_test.o
+obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM_SECVIO) += secvio.o
caam-objs := ctrl.o
-caam_jr-objs := jr.o key_gen.o error.o
+caam_jr-objs := jr.o key_gen.o error.o inst_rng.o
caam_pkc-y := caampkc.o pkc_desc.o
ifneq ($(CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API_QI),)
ccflags-y += -DCONFIG_CAAM_QI
caam-objs += qi.o
endif
+
+obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM_TK_API) += tag_object.o
diff --git a/drivers/crypto/caam/caamalg.c b/drivers/crypto/caam/caamalg.c
index 78feafcb7083..fbbc9c8b5a30 100644
--- a/drivers/crypto/caam/caamalg.c
+++ b/drivers/crypto/caam/caamalg.c
@@ -1,8 +1,8 @@
/*
* caam - Freescale FSL CAAM support for crypto API
*
- * Copyright 2008-2011 Freescale Semiconductor, Inc.
- * Copyright 2016 NXP
+ * Copyright 2008-2016 Freescale Semiconductor, Inc.
+ * Copyright 2017-2018 NXP
*
* Based on talitos crypto API driver.
*
@@ -56,6 +56,10 @@
#include "key_gen.h"
#include "caamalg_desc.h"
+#ifdef CONFIG_CRYPTO_DEV_FSL_CAAM_TK_API
+#include "tag_object.h"
+#endif /* CONFIG_CRYPTO_DEV_FSL_CAAM_TK_API */
+
/*
* crypto alg
*/
@@ -88,6 +92,10 @@ struct caam_alg_entry {
int class2_alg_type;
bool rfc3686;
bool geniv;
+
+#ifdef CONFIG_CRYPTO_DEV_FSL_CAAM_TK_API
+ bool is_tagged_key;
+#endif /* CONFIG_CRYPTO_DEV_FSL_CAAM_TK_API */
};
struct caam_aead_alg {
@@ -112,6 +120,10 @@ struct caam_ctx {
struct alginfo adata;
struct alginfo cdata;
unsigned int authsize;
+
+#ifdef CONFIG_CRYPTO_DEV_FSL_CAAM_TK_API
+ bool is_tagged_key;
+#endif /* CONFIG_CRYPTO_DEV_FSL_CAAM_TK_API */
};
static int aead_null_set_sh_desc(struct crypto_aead *aead)
@@ -613,6 +625,7 @@ static int rfc4543_setkey(struct crypto_aead *aead,
static int ablkcipher_setkey(struct crypto_ablkcipher *ablkcipher,
const u8 *key, unsigned int keylen)
{
+ int ret = 0;
struct caam_ctx *ctx = crypto_ablkcipher_ctx(ablkcipher);
struct crypto_tfm *tfm = crypto_ablkcipher_tfm(ablkcipher);
const char *alg_name = crypto_tfm_alg_name(tfm);
@@ -625,11 +638,67 @@ static int ablkcipher_setkey(struct crypto_ablkcipher *ablkcipher,
const bool is_rfc3686 = (ctr_mode &&
(strstr(alg_name, "rfc3686") != NULL));
- memcpy(ctx->key, key, keylen);
#ifdef DEBUG
print_hex_dump(KERN_ERR, "key in @"__stringify(__LINE__)": ",
DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1);
#endif
+
+ /* Check the key can be copied in context */
+ if (keylen > sizeof(ctx->key)) {
+ dev_err(jrdev, "Key cannot be copied\n");
+ ret = -ENOMEM;
+ goto exit;
+ }
+
+ /* Copy the key in context */
+ memcpy(ctx->key, key, keylen);
+
+ /* The key to load is in the context */
+ ctx->cdata.key_virt = ctx->key;
+ ctx->cdata.keylen = keylen;
+ ctx->cdata.key_real_len = keylen;
+ ctx->cdata.key_cmd_opt = 0;
+
+ ctx->cdata.key_inline = true;
+
+#ifdef CONFIG_CRYPTO_DEV_FSL_CAAM_TK_API
+ /*
+ * Check if the key is not in plaintext format
+ */
+ if (ctx->is_tagged_key) {
+ struct tag_object_conf *tagged_key_conf;
+
+ /* Get the configuration */
+ ret = get_tag_object_conf(ctx->cdata.key_virt,
+ ctx->cdata.keylen, &tagged_key_conf);
+ if (ret) {
+ dev_err(jrdev,
+ "caam algorithms can't process tagged key\n");
+ goto exit;
+ }
+
+ /* Only support black key */
+ if (!is_bk_conf(tagged_key_conf)) {
+ ret = -EINVAL;
+ dev_err(jrdev,
+ "The tagged key provided is not a black key\n");
+ goto exit;
+ }
+
+ get_blackey_conf(&tagged_key_conf->conf.bk_conf,
+ &ctx->cdata.key_real_len,
+ &ctx->cdata.key_cmd_opt);
+
+ ret = get_tagged_data(ctx->cdata.key_virt, ctx->cdata.keylen,
+ &ctx->cdata.key_virt, &ctx->cdata.keylen);
+ if (ret) {
+ dev_err(jrdev,
+ "caam algorithms wrong data from tagged key\n");
+ goto exit;
+ }
+ }
+#endif /* CONFIG_CRYPTO_DEV_FSL_CAAM_TK_API */
+
/*
* AES-CTR needs to load IV in CONTEXT1 reg
* at an offset of 128bits (16bytes)
@@ -645,18 +714,19 @@ static int ablkcipher_setkey(struct crypto_ablkcipher *ablkcipher,
*/
if (is_rfc3686) {
ctx1_iv_off = 16 + CTR_RFC3686_NONCE_SIZE;
- keylen -= CTR_RFC3686_NONCE_SIZE;
+ ctx->cdata.keylen -= CTR_RFC3686_NONCE_SIZE;
+ ctx->cdata.key_real_len = ctx->cdata.keylen;
}
- dma_sync_single_for_device(jrdev, ctx->key_dma, keylen, DMA_TO_DEVICE);
- ctx->cdata.keylen = keylen;
- ctx->cdata.key_virt = ctx->key;
- ctx->cdata.key_inline = true;
+ if (!ctx->cdata.key_inline)
+ dma_sync_single_for_device(jrdev, ctx->key_dma,
+ ctx->cdata.keylen, DMA_TO_DEVICE);
/* ablkcipher_encrypt shared descriptor */
desc = ctx->sh_desc_enc;
cnstr_shdsc_ablkcipher_encap(desc, &ctx->cdata, ivsize, is_rfc3686,
ctx1_iv_off);
+
dma_sync_single_for_device(jrdev, ctx->sh_desc_enc_dma,
desc_bytes(desc), DMA_TO_DEVICE);
@@ -664,6 +734,7 @@ static int ablkcipher_setkey(struct crypto_ablkcipher *ablkcipher,
desc = ctx->sh_desc_dec;
cnstr_shdsc_ablkcipher_decap(desc, &ctx->cdata, ivsize, is_rfc3686,
ctx1_iv_off);
+
dma_sync_single_for_device(jrdev, ctx->sh_desc_dec_dma,
desc_bytes(desc), DMA_TO_DEVICE);
@@ -671,12 +742,41 @@ static int ablkcipher_setkey(struct crypto_ablkcipher *ablkcipher,
desc = ctx->sh_desc_givenc;
cnstr_shdsc_ablkcipher_givencap(desc, &ctx->cdata, ivsize, is_rfc3686,
ctx1_iv_off);
+
dma_sync_single_for_device(jrdev, ctx->sh_desc_givenc_dma,
desc_bytes(desc), DMA_TO_DEVICE);
- return 0;
+exit:
+ return ret;
+}
+
+
+static int ablkcipher_des_setkey(struct crypto_ablkcipher *ablkcipher,
+ const u8 *key, unsigned int keylen)
+{
+ u32 tmp[DES_EXPKEY_WORDS];
+ u32 flags;
+ int ret;
+
+ if (keylen != DES_KEY_SIZE) {
+ crypto_ablkcipher_set_flags(ablkcipher,
+ CRYPTO_TFM_RES_BAD_KEY_LEN);
+ return -EINVAL;
+ }
+
+ ret = des_ekey(tmp, key);
+
+ flags = crypto_ablkcipher_get_flags(ablkcipher);
+ if (!ret && (flags & CRYPTO_TFM_REQ_WEAK_KEY)) {
+ crypto_ablkcipher_set_flags(ablkcipher,
+ CRYPTO_TFM_RES_WEAK_KEY);
+ return -EINVAL;
+ }
+
+ return ablkcipher_setkey(ablkcipher, key, keylen);
}
+
static int xts_ablkcipher_setkey(struct crypto_ablkcipher *ablkcipher,
const u8 *key, unsigned int keylen)
{
@@ -854,7 +954,9 @@ static void ablkcipher_encrypt_done(struct device *jrdev, u32 *desc, u32 err,
struct ablkcipher_edesc *edesc;
struct crypto_ablkcipher *ablkcipher = crypto_ablkcipher_reqtfm(req);
struct caam_ctx *ctx = crypto_ablkcipher_ctx(ablkcipher);
+ int bsize = crypto_ablkcipher_blocksize(ablkcipher);
int ivsize = crypto_ablkcipher_ivsize(ablkcipher);
+ size_t ivcopy = min_t(size_t, bsize, ivsize);
#ifdef DEBUG
dev_err(jrdev, "%s %d: err 0x%x\n", __func__, __LINE__, err);
@@ -898,6 +1000,12 @@ static void ablkcipher_encrypt_done(struct device *jrdev, u32 *desc, u32 err,
kfree(edesc);
+ /* Pass IV along for cbc */
+ if ((ctx->cdata.algtype & OP_ALG_AAI_MASK) == OP_ALG_AAI_CBC) {
+ scatterwalk_map_and_copy(req->info, req->dst,
+ req->nbytes - bsize, ivcopy, 0);
+ }
+
ablkcipher_request_complete(req, err);
}
@@ -1150,6 +1258,9 @@ static void init_ablkcipher_giv_job(u32 *sh_desc, dma_addr_t ptr,
append_seq_out_ptr(desc, dst_dma, req->nbytes + ivsize, LDST_SGF);
}
+static uint8_t *ecb_zero_iv;
+static dma_addr_t ecb_ziv_dma;
+
/*
* allocate and map the aead extended descriptor
*/
@@ -1453,6 +1564,7 @@ static struct ablkcipher_edesc *ablkcipher_edesc_alloc(struct ablkcipher_request
u8 *iv;
int ivsize = crypto_ablkcipher_ivsize(ablkcipher);
int dst_sg_idx, sec4_sg_ents, sec4_sg_bytes;
+ uint32_t c1_alg_typ = ctx->cdata.algtype;
src_nents = sg_nents_for_len(req->src, req->nbytes);
if (unlikely(src_nents < 0)) {
@@ -1522,13 +1634,19 @@ static struct ablkcipher_edesc *ablkcipher_edesc_alloc(struct ablkcipher_request
iv = (u8 *)edesc->hw_desc + desc_bytes + sec4_sg_bytes;
memcpy(iv, req->info, ivsize);
- iv_dma = dma_map_single(jrdev, iv, ivsize, DMA_TO_DEVICE);
- if (dma_mapping_error(jrdev, iv_dma)) {
- dev_err(jrdev, "unable to map IV\n");
- caam_unmap(jrdev, req->src, req->dst, src_nents, dst_nents, 0,
- 0, DMA_NONE, 0, 0);
- kfree(edesc);
- return ERR_PTR(-ENOMEM);
+ if ((!req->info && ivsize) &&
+ ((c1_alg_typ & OP_ALG_ALGSEL_MASK) == OP_ALG_ALGSEL_AES) &&
+ ((c1_alg_typ & OP_ALG_AAI_MASK) == OP_ALG_AAI_ECB)) {
+ iv_dma = ecb_ziv_dma;
+ } else {
+ iv_dma = dma_map_single(jrdev, iv, ivsize, DMA_TO_DEVICE);
+ if (dma_mapping_error(jrdev, iv_dma)) {
+ dev_err(jrdev, "unable to map IV\n");
+ caam_unmap(jrdev, req->src, req->dst, src_nents, dst_nents, 0,
+ 0, DMA_NONE, 0, 0);
+ kfree(edesc);
+ return ERR_PTR(-ENOMEM);
+ }
}
dma_to_sec4_sg_one(edesc->sec4_sg, iv_dma, ivsize, 0);
@@ -1812,6 +1930,7 @@ struct caam_alg_template {
} template_u;
u32 class1_alg_type;
u32 class2_alg_type;
+ bool support_tagged_key;
};
static struct caam_alg_template driver_algs[] = {
@@ -1832,6 +1951,24 @@ static struct caam_alg_template driver_algs[] = {
.ivsize = AES_BLOCK_SIZE,
},
.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
+ .support_tagged_key = true,
+ },
+ {
+ .name = "ecb(aes)",
+ .driver_name = "ecb-aes-caam",
+ .blocksize = AES_BLOCK_SIZE,
+ .type = CRYPTO_ALG_TYPE_ABLKCIPHER,
+ .template_ablkcipher = {
+ .setkey = ablkcipher_setkey,
+ .encrypt = ablkcipher_encrypt,
+ .decrypt = ablkcipher_decrypt,
+ .geniv = "eseqiv",
+ .min_keysize = AES_MIN_KEY_SIZE,
+ .max_keysize = AES_MAX_KEY_SIZE,
+ .ivsize = 0,
+ },
+ .class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_ECB,
+ .support_tagged_key = true,
},
{
.name = "cbc(des3_ede)",
@@ -1851,6 +1988,22 @@ static struct caam_alg_template driver_algs[] = {
.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
},
{
+ .name = "ecb(des3_ede)",
+ .driver_name = "ecb-des3-caam",
+ .blocksize = DES3_EDE_BLOCK_SIZE,
+ .type = CRYPTO_ALG_TYPE_ABLKCIPHER,
+ .template_ablkcipher = {
+ .setkey = ablkcipher_setkey,
+ .encrypt = ablkcipher_encrypt,
+ .decrypt = ablkcipher_decrypt,
+ .geniv = "eseqiv",
+ .min_keysize = DES3_EDE_KEY_SIZE,
+ .max_keysize = DES3_EDE_KEY_SIZE,
+ .ivsize = DES3_EDE_BLOCK_SIZE,
+ },
+ .class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_ECB,
+ },
+ {
.name = "cbc(des)",
.driver_name = "cbc-des-caam",
.blocksize = DES_BLOCK_SIZE,
@@ -1868,6 +2021,22 @@ static struct caam_alg_template driver_algs[] = {
.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
},
{
+ .name = "ecb(des)",
+ .driver_name = "ecb-des-caam",
+ .blocksize = DES_BLOCK_SIZE,
+ .type = CRYPTO_ALG_TYPE_ABLKCIPHER,
+ .template_ablkcipher = {
+ .setkey = ablkcipher_des_setkey,
+ .encrypt = ablkcipher_encrypt,
+ .decrypt = ablkcipher_decrypt,
+ .geniv = "eseqiv",
+ .min_keysize = DES_KEY_SIZE,
+ .max_keysize = DES_KEY_SIZE,
+ .ivsize = DES_BLOCK_SIZE,
+ },
+ .class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_ECB,
+ },
+ {
.name = "ctr(aes)",
.driver_name = "ctr-aes-caam",
.blocksize = 1,
@@ -1918,6 +2087,23 @@ static struct caam_alg_template driver_algs[] = {
},
.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_XTS,
},
+ {
+ .name = "ecb(arc4)",
+ .driver_name = "ecb-arc4-caam",
+ .blocksize = ARC4_BLOCK_SIZE,
+ .type = CRYPTO_ALG_TYPE_ABLKCIPHER,
+ .template_ablkcipher = {
+ .setkey = ablkcipher_setkey,
+ .encrypt = ablkcipher_encrypt,
+ .decrypt = ablkcipher_decrypt,
+ .geniv = "eseqiv",
+ .min_keysize = ARC4_MIN_KEY_SIZE,
+ .max_keysize = ARC4_MAX_KEY_SIZE,
+ .ivsize = ARC4_BLOCK_SIZE,
+ },
+ .class1_alg_type = OP_ALG_ALGSEL_ARC4 | OP_ALG_AAI_ECB
+ },
+
};
static struct caam_aead_alg driver_aeads[] = {
@@ -3238,6 +3424,11 @@ static int caam_init_common(struct caam_ctx *ctx, struct caam_alg_entry *caam)
ctx->cdata.algtype = OP_TYPE_CLASS1_ALG | caam->class1_alg_type;
ctx->adata.algtype = OP_TYPE_CLASS2_ALG | caam->class2_alg_type;
+#ifdef CONFIG_CRYPTO_DEV_FSL_CAAM_TK_API
+ /* Pass the information if the input key is a tagged key */
+ ctx->is_tagged_key = caam->is_tagged_key;
+#endif
+
return 0;
}
@@ -3281,10 +3472,35 @@ static void caam_aead_exit(struct crypto_aead *tfm)
static void __exit caam_algapi_exit(void)
{
-
+ struct device_node *dev_node;
+ struct platform_device *pdev;
+ struct device *ctrldev;
struct caam_crypto_alg *t_alg, *n;
int i;
+ if (!ecb_zero_iv)
+ goto skip_ecb_ziv;
+
+ dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec-v4.0");
+ if (!dev_node) {
+ dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec4.0");
+ if (!dev_node)
+ goto skip_ecb_ziv;
+ }
+
+ pdev = of_find_device_by_node(dev_node);
+
+ if (!pdev) {
+ of_node_put(dev_node);
+ goto skip_ecb_ziv;
+ }
+
+ ctrldev = &pdev->dev;
+
+ dma_unmap_single(ctrldev, ecb_ziv_dma, AES_BLOCK_SIZE, DMA_TO_DEVICE);
+ kfree(ecb_zero_iv);
+
+skip_ecb_ziv:
for (i = 0; i < ARRAY_SIZE(driver_aeads); i++) {
struct caam_aead_alg *t_alg = driver_aeads + i;
@@ -3303,7 +3519,7 @@ static void __exit caam_algapi_exit(void)
}
static struct caam_crypto_alg *caam_alg_alloc(struct caam_alg_template
- *template)
+ *template, bool sup_tag_key)
{
struct caam_crypto_alg *t_alg;
struct crypto_alg *alg;
@@ -3326,8 +3542,12 @@ static struct caam_crypto_alg *caam_alg_alloc(struct caam_alg_template
alg->cra_blocksize = template->blocksize;
alg->cra_alignmask = 0;
alg->cra_ctxsize = sizeof(struct caam_ctx);
- alg->cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_KERN_DRIVER_ONLY |
- template->type;
+ alg->cra_flags = CRYPTO_ALG_ASYNC | template->type;
+
+#ifdef CRYPTO_ALG_KERN_DRIVER_ONLY
+ alg->cra_flags |= CRYPTO_ALG_KERN_DRIVER_ONLY;
+#endif
+
switch (template->type) {
case CRYPTO_ALG_TYPE_GIVCIPHER:
alg->cra_type = &crypto_givcipher_type;
@@ -3342,6 +3562,39 @@ static struct caam_crypto_alg *caam_alg_alloc(struct caam_alg_template
t_alg->caam.class1_alg_type = template->class1_alg_type;
t_alg->caam.class2_alg_type = template->class2_alg_type;
+#ifdef CONFIG_CRYPTO_DEV_FSL_CAAM_TK_API
+ /* Modifications of algo to support tagged keys */
+ if (sup_tag_key) {
+ /* Indicate it only supports tagged keys */
+ t_alg->caam.is_tagged_key = true;
+
+ /* Adapt name and driver name */
+ snprintf(alg->cra_name, CRYPTO_MAX_ALG_NAME, "tk(%s)",
+ template->name);
+ snprintf(alg->cra_driver_name, CRYPTO_MAX_ALG_NAME, "tk-%s",
+ template->driver_name);
+
+ /* Minimal priority because it is a special case */
+ alg->cra_priority = 1;
+
+ /*
+ * The tagged key can have the size varying from only the size
+ * of the tag (no key) or CAAM_MAX_KEY_SIZE as it will be copied
+ * in the context
+ */
+ switch (template->type) {
+ case CRYPTO_ALG_TYPE_GIVCIPHER:
+ alg->cra_ablkcipher.min_keysize = TAG_MIN_SIZE;
+ alg->cra_ablkcipher.max_keysize = CAAM_MAX_KEY_SIZE;
+ break;
+ case CRYPTO_ALG_TYPE_ABLKCIPHER:
+ alg->cra_ablkcipher.min_keysize = TAG_MIN_SIZE;
+ alg->cra_ablkcipher.max_keysize = CAAM_MAX_KEY_SIZE;
+ break;
+ }
+ }
+#endif /* CONFIG_CRYPTO_DEV_FSL_CAAM_TK_API */
+
return t_alg;
}
@@ -3358,6 +3611,33 @@ static void caam_aead_alg_init(struct caam_aead_alg *t_alg)
alg->exit = caam_aead_exit;
}
+static bool caam_aes_support_gcm(const struct caam_drv_private *priv,
+ u32 aes_vid, u32 aes_rn)
+{
+ /*
+ * For ERA 10 and later, bit 9 of the AESA_VERSION register should be
+ * used to detect presence of GCM.
+ * For ERA 9 and earlier, the AESRNs 8, 9, and 10 with AESVID=3 all
+ * have GCM.
+ */
+ if (priv->era < 10) {
+ if (aes_vid == CHA_ID_LS_AES_LP) {
+ /* Only specific RN support GCM */
+ if (aes_rn >= 8)
+ return true;
+ else
+ return false;
+ } else {
+ /* AES HP support GCM */
+ return true;
+ }
+
+ } else {
+ /* We do not support ERA 10 for now */
+ return false;
+ }
+}
+
static int __init caam_algapi_init(void)
{
struct device_node *dev_node;
@@ -3365,7 +3645,8 @@ static int __init caam_algapi_init(void)
struct device *ctrldev;
struct caam_drv_private *priv;
int i = 0, err = 0;
- u32 cha_vid, cha_inst, des_inst, aes_inst, md_inst;
+ u32 cha_vid, cha_inst, des_inst, aes_inst, md_inst, arc4_inst;
+ u32 cha_rn;
unsigned int md_limit = SHA512_DIGEST_SIZE;
bool registered = false;
@@ -3393,6 +3674,16 @@ static int __init caam_algapi_init(void)
if (!priv)
return -ENODEV;
+ ecb_zero_iv = kzalloc(AES_BLOCK_SIZE, GFP_KERNEL);
+ if (!ecb_zero_iv)
+ return -ENOMEM;
+
+ ecb_ziv_dma = dma_map_single(ctrldev, ecb_zero_iv, AES_BLOCK_SIZE,
+ DMA_TO_DEVICE);
+ if (dma_mapping_error(ctrldev, ecb_ziv_dma)) {
+ kfree(ecb_zero_iv);
+ return -ENOMEM;
+ }
INIT_LIST_HEAD(&alg_list);
@@ -3400,11 +3691,20 @@ static int __init caam_algapi_init(void)
* Register crypto algorithms the device supports.
* First, detect presence and attributes of DES, AES, and MD blocks.
*/
- cha_vid = rd_reg32(&priv->ctrl->perfmon.cha_id_ls);
- cha_inst = rd_reg32(&priv->ctrl->perfmon.cha_num_ls);
+ if (priv->has_seco) {
+ i = priv->first_jr_index;
+ cha_vid = rd_reg32(&priv->jr[i]->perfmon.cha_id_ls);
+ cha_inst = rd_reg32(&priv->jr[i]->perfmon.cha_num_ls);
+ cha_rn = rd_reg32(&priv->jr[i]->perfmon.cha_rev_ls);
+ } else {
+ cha_vid = rd_reg32(&priv->ctrl->perfmon.cha_id_ls);
+ cha_inst = rd_reg32(&priv->ctrl->perfmon.cha_num_ls);
+ cha_rn = rd_reg32(&priv->ctrl->perfmon.cha_rev_ls);
+ }
des_inst = (cha_inst & CHA_ID_LS_DES_MASK) >> CHA_ID_LS_DES_SHIFT;
aes_inst = (cha_inst & CHA_ID_LS_AES_MASK) >> CHA_ID_LS_AES_SHIFT;
md_inst = (cha_inst & CHA_ID_LS_MD_MASK) >> CHA_ID_LS_MD_SHIFT;
+ arc4_inst = (cha_inst & CHA_ID_LS_ARC4_MASK) >> CHA_ID_LS_ARC4_SHIFT;
/* If MD is present, limit digest size based on LP256 */
if (md_inst && ((cha_vid & CHA_ID_LS_MD_MASK) == CHA_ID_LS_MD_LP256))
@@ -3425,6 +3725,10 @@ static int __init caam_algapi_init(void)
if (!aes_inst && (alg_sel == OP_ALG_ALGSEL_AES))
continue;
+ /* Skip ARC4 algorithms if not supported by device */
+ if (!arc4_inst && (alg_sel == OP_ALG_ALGSEL_ARC4))
+ continue;
+
/*
* Check support for AES modes not available
* on LP devices.
@@ -3434,7 +3738,7 @@ static int __init caam_algapi_init(void)
OP_ALG_AAI_XTS)
continue;
- t_alg = caam_alg_alloc(alg);
+ t_alg = caam_alg_alloc(alg, false);
if (IS_ERR(t_alg)) {
err = PTR_ERR(t_alg);
pr_warn("%s alg allocation failed\n", alg->driver_name);
@@ -3451,6 +3755,29 @@ static int __init caam_algapi_init(void)
list_add_tail(&t_alg->entry, &alg_list);
registered = true;
+
+#ifdef CONFIG_CRYPTO_DEV_FSL_CAAM_TK_API
+ if (alg->support_tagged_key) {
+ /* Register algo for tagged key */
+ t_alg = caam_alg_alloc(alg, true);
+ if (IS_ERR(t_alg)) {
+ err = PTR_ERR(t_alg);
+ pr_warn("%s alg allocation failed\n",
+ alg->driver_name);
+ continue;
+ }
+
+ err = crypto_register_alg(&t_alg->crypto_alg);
+ if (err) {
+ pr_warn("%s alg registration failed\n",
+ t_alg->crypto_alg.cra_driver_name);
+ kfree(t_alg);
+ continue;
+ }
+
+ list_add_tail(&t_alg->entry, &alg_list);
+ }
+#endif /* CONFIG_CRYPTO_DEV_FSL_CAAM_TK_API */
}
for (i = 0; i < ARRAY_SIZE(driver_aeads); i++) {
@@ -3472,11 +3799,13 @@ static int __init caam_algapi_init(void)
continue;
/*
- * Check support for AES algorithms not available
- * on LP devices.
+ * If we try to register gcm aes, check it is supported.
*/
- if ((cha_vid & CHA_ID_LS_AES_MASK) == CHA_ID_LS_AES_LP)
- if (alg_aai == OP_ALG_AAI_GCM)
+ if (c1_alg_sel == OP_ALG_ALGSEL_AES &&
+ alg_aai == OP_ALG_AAI_GCM)
+ if (!caam_aes_support_gcm(priv,
+ cha_vid & CHA_ID_LS_AES_MASK,
+ cha_rn & CHA_ID_LS_AES_MASK))
continue;
/*
diff --git a/drivers/crypto/caam/caamalg_desc.c b/drivers/crypto/caam/caamalg_desc.c
index b23c7b72525c..51e53272f1c7 100644
--- a/drivers/crypto/caam/caamalg_desc.c
+++ b/drivers/crypto/caam/caamalg_desc.c
@@ -1072,6 +1072,7 @@ void cnstr_shdsc_ablkcipher_encap(u32 * const desc, struct alginfo *cdata,
const u32 ctx1_iv_off)
{
u32 *key_jump_cmd;
+ u32 key_option;
init_sh_desc(desc, HDR_SHARE_SERIAL | HDR_SAVECTX);
/* Skip if already shared */
@@ -1079,8 +1080,13 @@ void cnstr_shdsc_ablkcipher_encap(u32 * const desc, struct alginfo *cdata,
JUMP_COND_SHRD);
/* Load class1 key only */
- append_key_as_imm(desc, cdata->key_virt, cdata->keylen,
- cdata->keylen, CLASS_1 | KEY_DEST_CLASS_REG);
+ key_option = CLASS_1 | KEY_DEST_CLASS_REG | cdata->key_cmd_opt;
+ if (cdata->key_inline)
+ append_key_as_imm(desc, cdata->key_virt, cdata->keylen,
+ cdata->key_real_len, key_option);
+ else
+ append_key(desc, cdata->key_dma, cdata->key_real_len,
+ key_option);
/* Load nonce into CONTEXT1 reg */
if (is_rfc3686) {
@@ -1137,6 +1143,7 @@ void cnstr_shdsc_ablkcipher_decap(u32 * const desc, struct alginfo *cdata,
const u32 ctx1_iv_off)
{
u32 *key_jump_cmd;
+ u32 key_option;
init_sh_desc(desc, HDR_SHARE_SERIAL | HDR_SAVECTX);
/* Skip if already shared */
@@ -1144,8 +1151,13 @@ void cnstr_shdsc_ablkcipher_decap(u32 * const desc, struct alginfo *cdata,
JUMP_COND_SHRD);
/* Load class1 key only */
- append_key_as_imm(desc, cdata->key_virt, cdata->keylen,
- cdata->keylen, CLASS_1 | KEY_DEST_CLASS_REG);
+ key_option = CLASS_1 | KEY_DEST_CLASS_REG | cdata->key_cmd_opt;
+ if (cdata->key_inline)
+ append_key_as_imm(desc, cdata->key_virt, cdata->keylen,
+ cdata->key_real_len, key_option);
+ else
+ append_key(desc, cdata->key_dma, cdata->key_real_len,
+ key_option);
/* Load nonce into CONTEXT1 reg */
if (is_rfc3686) {
@@ -1206,6 +1218,7 @@ void cnstr_shdsc_ablkcipher_givencap(u32 * const desc, struct alginfo *cdata,
const u32 ctx1_iv_off)
{
u32 *key_jump_cmd, geniv;
+ u32 key_option;
init_sh_desc(desc, HDR_SHARE_SERIAL | HDR_SAVECTX);
/* Skip if already shared */
@@ -1213,8 +1226,13 @@ void cnstr_shdsc_ablkcipher_givencap(u32 * const desc, struct alginfo *cdata,
JUMP_COND_SHRD);
/* Load class1 key only */
- append_key_as_imm(desc, cdata->key_virt, cdata->keylen,
- cdata->keylen, CLASS_1 | KEY_DEST_CLASS_REG);
+ key_option = CLASS_1 | KEY_DEST_CLASS_REG | cdata->key_cmd_opt;
+ if (cdata->key_inline)
+ append_key_as_imm(desc, cdata->key_virt, cdata->keylen,
+ cdata->key_real_len, key_option);
+ else
+ append_key(desc, cdata->key_dma, cdata->key_real_len,
+ key_option);
/* Load Nonce into CONTEXT1 reg */
if (is_rfc3686) {
diff --git a/drivers/crypto/caam/caamhash.c b/drivers/crypto/caam/caamhash.c
index 8fa35bc75870..148f5be97be4 100644
--- a/drivers/crypto/caam/caamhash.c
+++ b/drivers/crypto/caam/caamhash.c
@@ -2,6 +2,7 @@
* caam - Freescale FSL CAAM support for ahash functions of crypto API
*
* Copyright 2011 Freescale Semiconductor, Inc.
+ * Copyright 2017-2018 NXP
*
* Based on caamalg.c crypto API driver.
*
@@ -62,6 +63,7 @@
#include "error.h"
#include "sg_sw_sec4.h"
#include "key_gen.h"
+#include <linux/string.h>
#define CAAM_CRA_PRIORITY 3000
@@ -111,12 +113,14 @@ struct caam_hash_ctx {
u8 key[CAAM_MAX_HASH_KEY_SIZE];
int ctx_len;
struct alginfo adata;
+ unsigned int key_len;
};
/* ahash state */
struct caam_hash_state {
dma_addr_t buf_dma;
dma_addr_t ctx_dma;
+ int ctx_dma_len;
u8 buf_0[CAAM_MAX_HASH_BLOCK_SIZE] ____cacheline_aligned;
int buflen_0;
u8 buf_1[CAAM_MAX_HASH_BLOCK_SIZE] ____cacheline_aligned;
@@ -169,6 +173,7 @@ static inline int map_seq_out_ptr_ctx(u32 *desc, struct device *jrdev,
struct caam_hash_state *state,
int ctx_len)
{
+ state->ctx_dma_len = ctx_len;
state->ctx_dma = dma_map_single(jrdev, state->caam_ctx,
ctx_len, DMA_FROM_DEVICE);
if (dma_mapping_error(jrdev, state->ctx_dma)) {
@@ -182,18 +187,6 @@ static inline int map_seq_out_ptr_ctx(u32 *desc, struct device *jrdev,
return 0;
}
-/* Map req->result, and append seq_out_ptr command that points to it */
-static inline dma_addr_t map_seq_out_ptr_result(u32 *desc, struct device *jrdev,
- u8 *result, int digestsize)
-{
- dma_addr_t dst_dma;
-
- dst_dma = dma_map_single(jrdev, result, digestsize, DMA_FROM_DEVICE);
- append_seq_out_ptr(desc, dst_dma, digestsize, 0);
-
- return dst_dma;
-}
-
/* Map current buffer in state (if length > 0) and put it in link table */
static inline int buf_map_to_sec4_sg(struct device *jrdev,
struct sec4_sg_entry *sec4_sg,
@@ -222,6 +215,7 @@ static inline int ctx_map_to_sec4_sg(u32 *desc, struct device *jrdev,
struct caam_hash_state *state, int ctx_len,
struct sec4_sg_entry *sec4_sg, u32 flag)
{
+ state->ctx_dma_len = ctx_len;
state->ctx_dma = dma_map_single(jrdev, state->caam_ctx, ctx_len, flag);
if (dma_mapping_error(jrdev, state->ctx_dma)) {
dev_err(jrdev, "unable to map ctx\n");
@@ -234,6 +228,68 @@ static inline int ctx_map_to_sec4_sg(u32 *desc, struct device *jrdev,
return 0;
}
+static inline void append_key_axcbc(u32 *desc, struct caam_hash_ctx *ctx)
+{
+ append_key_as_imm(desc, ctx->key, ctx->key_len,
+ ctx->key_len, CLASS_1 |
+ KEY_DEST_CLASS_REG);
+}
+
+static inline void init_sh_desc_key_axcbc(u32 *desc, struct caam_hash_ctx *ctx)
+{
+ u32 *key_jump_cmd;
+
+ init_sh_desc(desc, HDR_SHARE_SERIAL);
+
+ if (ctx->key_len) {
+ key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
+ JUMP_COND_SHRD);
+
+ append_key_axcbc(desc, ctx);
+
+ set_jump_tgt_here(desc, key_jump_cmd);
+ }
+
+ /* Propagate errors from shared to job descriptor */
+ append_cmd(desc, SET_OK_NO_PROP_ERRORS | CMD_LOAD);
+}
+
+static inline void axcbc_append_load_str(u32 *desc, int digestsize)
+{
+ /* Calculate remaining bytes to read */
+ append_math_add(desc, VARSEQINLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
+
+ /* Read remaining bytes */
+ append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLD_TYPE_LAST1 |
+ FIFOLD_TYPE_MSG | KEY_VLF);
+
+ /* Store class1 context bytes */
+ append_seq_store(desc, digestsize, LDST_CLASS_1_CCB |
+ LDST_SRCDST_BYTE_CONTEXT);
+}
+
+/*
+ * For ahash update, final and finup, import context, read and write to seqout
+ */
+static inline void axcbc_ctx_data_to_out(u32 *desc, u32 op, u32 state,
+ int digestsize,
+ struct caam_hash_ctx *ctx)
+{
+ init_sh_desc_key_axcbc(desc, ctx);
+
+ /* Import context from software */
+ append_cmd(desc, CMD_SEQ_LOAD | LDST_SRCDST_BYTE_CONTEXT |
+ LDST_CLASS_1_CCB | ctx->ctx_len);
+
+ /* Class 1 operation */
+ append_operation(desc, op | state | OP_ALG_ENCRYPT);
+
+ /*
+ * Load from buf and/or src and write to req->result or state->context
+ */
+ axcbc_append_load_str(desc, digestsize);
+}
+
/*
* For ahash update, final and finup (import_ctx = true)
* import context, read and write to seqout
@@ -284,6 +340,21 @@ static inline void ahash_gen_sh_desc(u32 *desc, u32 state, int digestsize,
LDST_SRCDST_BYTE_CONTEXT);
}
+/* For ahash firsts and digest, read and write to seqout */
+static inline void axcbc_data_to_out(u32 *desc, u32 op, u32 state,
+ int digestsize, struct caam_hash_ctx *ctx)
+{
+ init_sh_desc_key_axcbc(desc, ctx);
+
+ /* Class 1 operation */
+ append_operation(desc, op | state | OP_ALG_ENCRYPT);
+
+ /*
+ * Load from buf and/or src and write to req->result or state->context
+ */
+ axcbc_append_load_str(desc, digestsize);
+}
+
static int ahash_set_sh_desc(struct crypto_ahash *ahash)
{
struct caam_hash_ctx *ctx = crypto_ahash_ctx(ahash);
@@ -339,6 +410,125 @@ static int ahash_set_sh_desc(struct crypto_ahash *ahash)
return 0;
}
+static int axcbc_set_sh_desc(struct crypto_ahash *ahash)
+{
+ struct caam_hash_ctx *ctx = crypto_ahash_ctx(ahash);
+ int digestsize = crypto_ahash_digestsize(ahash);
+ struct device *jrdev = ctx->jrdev;
+ u32 have_key = 0;
+ u32 *desc;
+
+ /* ahash_update shared descriptor */
+ desc = ctx->sh_desc_update;
+
+ init_sh_desc(desc, HDR_SHARE_SERIAL);
+
+ /* Import context from software */
+ append_cmd(desc, CMD_SEQ_LOAD | LDST_SRCDST_BYTE_CONTEXT |
+ LDST_CLASS_1_CCB | ctx->ctx_len);
+
+ /* Class 1 operation */
+ append_operation(desc, ctx->adata.algtype | OP_ALG_AS_UPDATE |
+ OP_ALG_ENCRYPT);
+
+ /* Load data and write to result or context */
+ axcbc_append_load_str(desc, ctx->ctx_len);
+
+ ctx->sh_desc_update_dma = dma_map_single(jrdev, desc, desc_bytes(desc),
+ DMA_TO_DEVICE);
+ if (dma_mapping_error(jrdev, ctx->sh_desc_update_dma)) {
+ dev_err(jrdev, "unable to map shared descriptor\n");
+ return -ENOMEM;
+ }
+#ifdef DEBUG
+ print_hex_dump(KERN_ERR, "ahash update shdesc@"__stringify(__LINE__)": ",
+ DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc), 1);
+#endif
+
+ /* ahash_update_first shared descriptor */
+ desc = ctx->sh_desc_update_first;
+
+ axcbc_data_to_out(desc, have_key | ctx->adata.algtype, OP_ALG_AS_INIT,
+ ctx->ctx_len, ctx);
+
+ ctx->sh_desc_update_first_dma = dma_map_single(jrdev, desc,
+ desc_bytes(desc),
+ DMA_TO_DEVICE);
+ if (dma_mapping_error(jrdev, ctx->sh_desc_update_first_dma)) {
+ dev_err(jrdev, "unable to map shared descriptor\n");
+ return -ENOMEM;
+ }
+#ifdef DEBUG
+ print_hex_dump(KERN_ERR, "ahash update first shdesc@"__stringify(__LINE__)": ",
+ DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc), 1);
+#endif
+ dma_sync_single_for_device(jrdev, ctx->sh_desc_update_first_dma,
+ desc_bytes(desc), DMA_TO_DEVICE);
+
+ /* ahash_final shared descriptor */
+ desc = ctx->sh_desc_fin;
+
+ axcbc_ctx_data_to_out(desc, have_key | ctx->adata.algtype,
+ OP_ALG_AS_FINALIZE, digestsize, ctx);
+
+ ctx->sh_desc_fin_dma = dma_map_single(jrdev, desc, desc_bytes(desc),
+ DMA_TO_DEVICE);
+ if (dma_mapping_error(jrdev, ctx->sh_desc_fin_dma)) {
+ dev_err(jrdev, "unable to map shared descriptor\n");
+ return -ENOMEM;
+ }
+#ifdef DEBUG
+ print_hex_dump(KERN_ERR, "ahash final shdesc@"__stringify(__LINE__)": ",
+ DUMP_PREFIX_ADDRESS, 16, 4, desc,
+ desc_bytes(desc), 1);
+#endif
+ dma_sync_single_for_device(jrdev, ctx->sh_desc_fin_dma,
+ desc_bytes(desc), DMA_TO_DEVICE);
+
+ /* ahash_finup shared descriptor */
+ desc = ctx->sh_desc_fin;
+
+ axcbc_ctx_data_to_out(desc, have_key | ctx->adata.algtype,
+ OP_ALG_AS_FINALIZE, digestsize, ctx);
+
+ ctx->sh_desc_fin_dma = dma_map_single(jrdev, desc, desc_bytes(desc),
+ DMA_TO_DEVICE);
+ if (dma_mapping_error(jrdev, ctx->sh_desc_fin_dma)) {
+ dev_err(jrdev, "unable to map shared descriptor\n");
+ return -ENOMEM;
+ }
+#ifdef DEBUG
+ print_hex_dump(KERN_ERR, "ahash finup shdesc@"__stringify(__LINE__)": ",
+ DUMP_PREFIX_ADDRESS, 16, 4, desc,
+ desc_bytes(desc), 1);
+#endif
+ dma_sync_single_for_device(jrdev, ctx->sh_desc_fin_dma,
+ desc_bytes(desc), DMA_TO_DEVICE);
+
+ /* ahash_digest shared descriptor */
+ desc = ctx->sh_desc_digest;
+
+ axcbc_data_to_out(desc, have_key | ctx->adata.algtype, OP_ALG_AS_INITFINAL,
+ digestsize, ctx);
+
+ ctx->sh_desc_digest_dma = dma_map_single(jrdev, desc,
+ desc_bytes(desc),
+ DMA_TO_DEVICE);
+ if (dma_mapping_error(jrdev, ctx->sh_desc_digest_dma)) {
+ dev_err(jrdev, "unable to map shared descriptor\n");
+ return -ENOMEM;
+ }
+#ifdef DEBUG
+ print_hex_dump(KERN_ERR, "ahash digest shdesc@"__stringify(__LINE__)": ",
+ DUMP_PREFIX_ADDRESS, 16, 4, desc,
+ desc_bytes(desc), 1);
+#endif
+ dma_sync_single_for_device(jrdev, ctx->sh_desc_digest_dma,
+ desc_bytes(desc), DMA_TO_DEVICE);
+
+ return 0;
+}
+
/* Digest hash size if it is too large */
static int hash_digest_key(struct caam_hash_ctx *ctx, const u8 *key_in,
u32 *keylen, u8 *key_out, u32 digestsize)
@@ -460,9 +650,27 @@ static int ahash_setkey(struct crypto_ahash *ahash,
return -EINVAL;
}
+static int axcbc_setkey(struct crypto_ahash *ahash,
+ const u8 *key, unsigned int keylen)
+{
+ struct caam_hash_ctx *ctx = crypto_ahash_ctx(ahash);
+ int ret = 0;
+
+ ctx->key_len = keylen;
+ memcpy(ctx->key, key, keylen);
+
+#ifdef DEBUG
+ print_hex_dump(KERN_ERR, "ctx.key@"__stringify(__LINE__)": ",
+ DUMP_PREFIX_ADDRESS, 16, 4, ctx->key,
+ ctx->key_len, 1);
+#endif
+
+ ret = axcbc_set_sh_desc(ahash);
+
+ return ret;
+}
/*
* ahash_edesc - s/w-extended ahash descriptor
- * @dst_dma: physical mapped address of req->result
* @sec4_sg_dma: physical mapped address of h/w link table
* @src_nents: number of segments in input scatterlist
* @sec4_sg_bytes: length of dma mapped sec4_sg space
@@ -470,7 +678,6 @@ static int ahash_setkey(struct crypto_ahash *ahash,
* @sec4_sg: h/w link table
*/
struct ahash_edesc {
- dma_addr_t dst_dma;
dma_addr_t sec4_sg_dma;
int src_nents;
int sec4_sg_bytes;
@@ -486,8 +693,6 @@ static inline void ahash_unmap(struct device *dev,
if (edesc->src_nents)
dma_unmap_sg(dev, req->src, edesc->src_nents, DMA_TO_DEVICE);
- if (edesc->dst_dma)
- dma_unmap_single(dev, edesc->dst_dma, dst_len, DMA_FROM_DEVICE);
if (edesc->sec4_sg_bytes)
dma_unmap_single(dev, edesc->sec4_sg_dma,
@@ -504,12 +709,10 @@ static inline void ahash_unmap_ctx(struct device *dev,
struct ahash_edesc *edesc,
struct ahash_request *req, int dst_len, u32 flag)
{
- struct crypto_ahash *ahash = crypto_ahash_reqtfm(req);
- struct caam_hash_ctx *ctx = crypto_ahash_ctx(ahash);
struct caam_hash_state *state = ahash_request_ctx(req);
if (state->ctx_dma) {
- dma_unmap_single(dev, state->ctx_dma, ctx->ctx_len, flag);
+ dma_unmap_single(dev, state->ctx_dma, state->ctx_dma_len, flag);
state->ctx_dma = 0;
}
ahash_unmap(dev, edesc, req, dst_len);
@@ -522,9 +725,9 @@ static void ahash_done(struct device *jrdev, u32 *desc, u32 err,
struct ahash_edesc *edesc;
struct crypto_ahash *ahash = crypto_ahash_reqtfm(req);
int digestsize = crypto_ahash_digestsize(ahash);
+ struct caam_hash_state *state = ahash_request_ctx(req);
#ifdef DEBUG
struct caam_hash_ctx *ctx = crypto_ahash_ctx(ahash);
- struct caam_hash_state *state = ahash_request_ctx(req);
dev_err(jrdev, "%s %d: err 0x%x\n", __func__, __LINE__, err);
#endif
@@ -533,17 +736,14 @@ static void ahash_done(struct device *jrdev, u32 *desc, u32 err,
if (err)
caam_jr_strstatus(jrdev, err);
- ahash_unmap(jrdev, edesc, req, digestsize);
+ ahash_unmap_ctx(jrdev, edesc, req, digestsize, DMA_FROM_DEVICE);
+ memcpy(req->result, state->caam_ctx, digestsize);
kfree(edesc);
#ifdef DEBUG
print_hex_dump(KERN_ERR, "ctx@"__stringify(__LINE__)": ",
DUMP_PREFIX_ADDRESS, 16, 4, state->caam_ctx,
ctx->ctx_len, 1);
- if (req->result)
- print_hex_dump(KERN_ERR, "result@"__stringify(__LINE__)": ",
- DUMP_PREFIX_ADDRESS, 16, 4, req->result,
- digestsize, 1);
#endif
req->base.complete(&req->base, err);
@@ -591,9 +791,9 @@ static void ahash_done_ctx_src(struct device *jrdev, u32 *desc, u32 err,
struct ahash_edesc *edesc;
struct crypto_ahash *ahash = crypto_ahash_reqtfm(req);
int digestsize = crypto_ahash_digestsize(ahash);
+ struct caam_hash_state *state = ahash_request_ctx(req);
#ifdef DEBUG
struct caam_hash_ctx *ctx = crypto_ahash_ctx(ahash);
- struct caam_hash_state *state = ahash_request_ctx(req);
dev_err(jrdev, "%s %d: err 0x%x\n", __func__, __LINE__, err);
#endif
@@ -602,17 +802,14 @@ static void ahash_done_ctx_src(struct device *jrdev, u32 *desc, u32 err,
if (err)
caam_jr_strstatus(jrdev, err);
- ahash_unmap_ctx(jrdev, edesc, req, digestsize, DMA_TO_DEVICE);
+ ahash_unmap_ctx(jrdev, edesc, req, digestsize, DMA_BIDIRECTIONAL);
+ memcpy(req->result, state->caam_ctx, digestsize);
kfree(edesc);
#ifdef DEBUG
print_hex_dump(KERN_ERR, "ctx@"__stringify(__LINE__)": ",
DUMP_PREFIX_ADDRESS, 16, 4, state->caam_ctx,
ctx->ctx_len, 1);
- if (req->result)
- print_hex_dump(KERN_ERR, "result@"__stringify(__LINE__)": ",
- DUMP_PREFIX_ADDRESS, 16, 4, req->result,
- digestsize, 1);
#endif
req->base.complete(&req->base, err);
@@ -874,7 +1071,7 @@ static int ahash_final_ctx(struct ahash_request *req)
edesc->src_nents = 0;
ret = ctx_map_to_sec4_sg(desc, jrdev, state, ctx->ctx_len,
- edesc->sec4_sg, DMA_TO_DEVICE);
+ edesc->sec4_sg, DMA_BIDIRECTIONAL);
if (ret)
goto unmap_ctx;
@@ -895,13 +1092,7 @@ static int ahash_final_ctx(struct ahash_request *req)
append_seq_in_ptr(desc, edesc->sec4_sg_dma, ctx->ctx_len + buflen,
LDST_SGF);
- edesc->dst_dma = map_seq_out_ptr_result(desc, jrdev, req->result,
- digestsize);
- if (dma_mapping_error(jrdev, edesc->dst_dma)) {
- dev_err(jrdev, "unable to map dst\n");
- ret = -ENOMEM;
- goto unmap_ctx;
- }
+ append_seq_out_ptr(desc, state->ctx_dma, digestsize, 0);
#ifdef DEBUG
print_hex_dump(KERN_ERR, "jobdesc@"__stringify(__LINE__)": ",
@@ -914,7 +1105,7 @@ static int ahash_final_ctx(struct ahash_request *req)
return -EINPROGRESS;
unmap_ctx:
- ahash_unmap_ctx(jrdev, edesc, req, digestsize, DMA_FROM_DEVICE);
+ ahash_unmap_ctx(jrdev, edesc, req, digestsize, DMA_BIDIRECTIONAL);
kfree(edesc);
return ret;
}
@@ -968,7 +1159,7 @@ static int ahash_finup_ctx(struct ahash_request *req)
edesc->src_nents = src_nents;
ret = ctx_map_to_sec4_sg(desc, jrdev, state, ctx->ctx_len,
- edesc->sec4_sg, DMA_TO_DEVICE);
+ edesc->sec4_sg, DMA_BIDIRECTIONAL);
if (ret)
goto unmap_ctx;
@@ -982,13 +1173,7 @@ static int ahash_finup_ctx(struct ahash_request *req)
if (ret)
goto unmap_ctx;
- edesc->dst_dma = map_seq_out_ptr_result(desc, jrdev, req->result,
- digestsize);
- if (dma_mapping_error(jrdev, edesc->dst_dma)) {
- dev_err(jrdev, "unable to map dst\n");
- ret = -ENOMEM;
- goto unmap_ctx;
- }
+ append_seq_out_ptr(desc, state->ctx_dma, digestsize, 0);
#ifdef DEBUG
print_hex_dump(KERN_ERR, "jobdesc@"__stringify(__LINE__)": ",
@@ -1001,7 +1186,7 @@ static int ahash_finup_ctx(struct ahash_request *req)
return -EINPROGRESS;
unmap_ctx:
- ahash_unmap_ctx(jrdev, edesc, req, digestsize, DMA_FROM_DEVICE);
+ ahash_unmap_ctx(jrdev, edesc, req, digestsize, DMA_BIDIRECTIONAL);
kfree(edesc);
return ret;
}
@@ -1060,10 +1245,9 @@ static int ahash_digest(struct ahash_request *req)
desc = edesc->hw_desc;
- edesc->dst_dma = map_seq_out_ptr_result(desc, jrdev, req->result,
- digestsize);
- if (dma_mapping_error(jrdev, edesc->dst_dma)) {
- dev_err(jrdev, "unable to map dst\n");
+ ret = map_seq_out_ptr_ctx(desc, jrdev, state, digestsize);
+ if (ret) {
+ dev_err(jrdev, "unable to map state\n");
ahash_unmap(jrdev, edesc, req, digestsize);
kfree(edesc);
return -ENOMEM;
@@ -1078,7 +1262,7 @@ static int ahash_digest(struct ahash_request *req)
if (!ret) {
ret = -EINPROGRESS;
} else {
- ahash_unmap(jrdev, edesc, req, digestsize);
+ ahash_unmap_ctx(jrdev, edesc, req, digestsize, DMA_FROM_DEVICE);
kfree(edesc);
}
@@ -1120,10 +1304,9 @@ static int ahash_final_no_ctx(struct ahash_request *req)
append_seq_in_ptr(desc, state->buf_dma, buflen, 0);
}
- edesc->dst_dma = map_seq_out_ptr_result(desc, jrdev, req->result,
- digestsize);
- if (dma_mapping_error(jrdev, edesc->dst_dma)) {
- dev_err(jrdev, "unable to map dst\n");
+ ret = map_seq_out_ptr_ctx(desc, jrdev, state, digestsize);
+ if (ret) {
+ dev_err(jrdev, "unable to map state\n");
goto unmap;
}
edesc->src_nents = 0;
@@ -1137,7 +1320,7 @@ static int ahash_final_no_ctx(struct ahash_request *req)
if (!ret) {
ret = -EINPROGRESS;
} else {
- ahash_unmap(jrdev, edesc, req, digestsize);
+ ahash_unmap_ctx(jrdev, edesc, req, digestsize, DMA_FROM_DEVICE);
kfree(edesc);
}
@@ -1208,7 +1391,6 @@ static int ahash_update_no_ctx(struct ahash_request *req)
edesc->src_nents = src_nents;
edesc->sec4_sg_bytes = sec4_sg_bytes;
- edesc->dst_dma = 0;
ret = buf_map_to_sec4_sg(jrdev, edesc->sec4_sg, state);
if (ret)
@@ -1337,10 +1519,9 @@ static int ahash_finup_no_ctx(struct ahash_request *req)
goto unmap;
}
- edesc->dst_dma = map_seq_out_ptr_result(desc, jrdev, req->result,
- digestsize);
- if (dma_mapping_error(jrdev, edesc->dst_dma)) {
- dev_err(jrdev, "unable to map dst\n");
+ ret = map_seq_out_ptr_ctx(desc, jrdev, state, digestsize);
+ if (ret) {
+ dev_err(jrdev, "unable to map state\n");
goto unmap;
}
@@ -1353,7 +1534,7 @@ static int ahash_finup_no_ctx(struct ahash_request *req)
if (!ret) {
ret = -EINPROGRESS;
} else {
- ahash_unmap(jrdev, edesc, req, digestsize);
+ ahash_unmap_ctx(jrdev, edesc, req, digestsize, DMA_FROM_DEVICE);
kfree(edesc);
}
@@ -1420,7 +1601,6 @@ static int ahash_update_first(struct ahash_request *req)
}
edesc->src_nents = src_nents;
- edesc->dst_dma = 0;
ret = ahash_edesc_add_src(ctx, edesc, req, mapped_nents, 0, 0,
to_hash);
@@ -1486,6 +1666,7 @@ static int ahash_init(struct ahash_request *req)
state->final = ahash_final_no_ctx;
state->ctx_dma = 0;
+ state->ctx_dma_len = 0;
state->current_buf = 0;
state->buf_dma = 0;
state->buflen_0 = 0;
@@ -1695,6 +1876,28 @@ static struct caam_hash_template driver_hash[] = {
},
.alg_type = OP_ALG_ALGSEL_MD5,
},
+ {
+ .name = "xcbc(aes)",
+ .driver_name = "xcbc-aes-caam",
+ .hmac_name = "xcbc(aes)",
+ .hmac_driver_name = "xcbc-aes-caam",
+ .blocksize = XCBC_MAC_BLOCK_WORDS * 4,
+ .template_ahash = {
+ .init = ahash_init,
+ .update = ahash_update,
+ .final = ahash_final,
+ .finup = ahash_finup,
+ .digest = ahash_digest,
+ .export = ahash_export,
+ .import = ahash_import,
+ .setkey = axcbc_setkey,
+ .halg = {
+ .digestsize = XCBC_MAC_DIGEST_SIZE,
+ .statesize = sizeof(struct caam_export_state),
+ },
+ },
+ .alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_XCBC_MAC,
+ },
};
struct caam_hash_alg {
@@ -1764,6 +1967,40 @@ static int caam_hash_cra_init(struct crypto_tfm *tfm)
return ahash_set_sh_desc(ahash);
}
+static int caam_axcbc_cra_init(struct crypto_tfm *tfm)
+{
+ struct crypto_ahash *ahash = __crypto_ahash_cast(tfm);
+ struct crypto_alg *base = tfm->__crt_alg;
+ struct hash_alg_common *halg =
+ container_of(base, struct hash_alg_common, base);
+ struct ahash_alg *alg =
+ container_of(halg, struct ahash_alg, halg);
+ struct caam_hash_alg *caam_hash =
+ container_of(alg, struct caam_hash_alg, ahash_alg);
+ struct caam_hash_ctx *ctx = crypto_tfm_ctx(tfm);
+ int ret = 0;
+
+ /*
+ * Get a Job ring from Job Ring driver to ensure in-order
+ * crypto request processing per tfm
+ */
+ ctx->jrdev = caam_jr_alloc();
+ if (IS_ERR(ctx->jrdev)) {
+ pr_err("Job Ring Device allocation for transform failed\n");
+ return PTR_ERR(ctx->jrdev);
+ }
+
+ /* copy descriptor header template value */
+ ctx->adata.algtype = OP_TYPE_CLASS1_ALG | caam_hash->alg_type;
+
+ crypto_ahash_set_reqsize(__crypto_ahash_cast(tfm),
+ sizeof(struct caam_hash_state));
+
+ ret = axcbc_set_sh_desc(ahash);
+
+ return ret;
+}
+
static void caam_hash_cra_exit(struct crypto_tfm *tfm)
{
struct caam_hash_ctx *ctx = crypto_tfm_ctx(tfm);
@@ -1820,7 +2057,11 @@ caam_hash_alloc(struct caam_hash_template *template,
t_alg->ahash_alg.setkey = NULL;
}
alg->cra_module = THIS_MODULE;
- alg->cra_init = caam_hash_cra_init;
+
+ if (strstr(alg->cra_name, "xcbc") > 0)
+ alg->cra_init = caam_axcbc_cra_init;
+ else
+ alg->cra_init = caam_hash_cra_init;
alg->cra_exit = caam_hash_cra_exit;
alg->cra_ctxsize = sizeof(struct caam_hash_ctx);
alg->cra_priority = CAAM_CRA_PRIORITY;
@@ -1872,8 +2113,14 @@ static int __init caam_algapi_hash_init(void)
* Register crypto algorithms the device supports. First, identify
* presence and attributes of MD block.
*/
- cha_vid = rd_reg32(&priv->ctrl->perfmon.cha_id_ls);
- cha_inst = rd_reg32(&priv->ctrl->perfmon.cha_num_ls);
+ if (priv->has_seco) {
+ i = priv->first_jr_index;
+ cha_vid = rd_reg32(&priv->jr[i]->perfmon.cha_id_ls);
+ cha_inst = rd_reg32(&priv->jr[i]->perfmon.cha_num_ls);
+ } else {
+ cha_vid = rd_reg32(&priv->ctrl->perfmon.cha_id_ls);
+ cha_inst = rd_reg32(&priv->ctrl->perfmon.cha_num_ls);
+ }
/*
* Skip registration of any hashing algorithms if MD block
@@ -1914,6 +2161,9 @@ static int __init caam_algapi_hash_init(void)
} else
list_add_tail(&t_alg->entry, &hash_list);
+ if ((alg->alg_type & OP_ALG_ALGSEL_MASK) == OP_ALG_ALGSEL_AES)
+ continue;
+
/* register unkeyed version */
t_alg = caam_hash_alloc(alg, false);
if (IS_ERR(t_alg)) {
diff --git a/drivers/crypto/caam/caampkc.c b/drivers/crypto/caam/caampkc.c
index 6f3f81bb880b..1c90fe760a49 100644
--- a/drivers/crypto/caam/caampkc.c
+++ b/drivers/crypto/caam/caampkc.c
@@ -2,6 +2,7 @@
* caam - Freescale FSL CAAM support for Public Key Cryptography
*
* Copyright 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017-2018 NXP
*
* There is no Shared Descriptor for PKC so that the Job Descriptor must carry
* all the desired key parameters, input and output pointers.
@@ -1051,7 +1052,13 @@ static int __init caam_pkc_init(void)
return -ENODEV;
/* Determine public key hardware accelerator presence. */
- cha_inst = rd_reg32(&priv->ctrl->perfmon.cha_num_ls);
+ if (priv->has_seco) {
+ int i = priv->first_jr_index;
+
+ cha_inst = rd_reg32(&priv->jr[i]->perfmon.cha_num_ls);
+ } else {
+ cha_inst = rd_reg32(&priv->ctrl->perfmon.cha_num_ls);
+ }
pk_inst = (cha_inst & CHA_ID_LS_PK_MASK) >> CHA_ID_LS_PK_SHIFT;
/* Do not register algorithms if PKHA is not present. */
diff --git a/drivers/crypto/caam/caamrng.c b/drivers/crypto/caam/caamrng.c
index fde07d4ff019..6e17963b9abf 100644
--- a/drivers/crypto/caam/caamrng.c
+++ b/drivers/crypto/caam/caamrng.c
@@ -2,6 +2,7 @@
* caam - Freescale FSL CAAM support for hw_random
*
* Copyright 2011 Freescale Semiconductor, Inc.
+ * Copyright 2018 NXP
*
* Based on caamalg.c crypto API driver.
*
@@ -252,6 +253,49 @@ static void caam_cleanup(struct hwrng *rng)
rng_unmap_ctx(rng_ctx);
}
+#ifdef CONFIG_CRYPTO_DEV_FSL_CAAM_RNG_TEST
+static inline void test_len(struct hwrng *rng, size_t len, bool wait)
+{
+ u8 *buf;
+ int real_len;
+
+ buf = kzalloc(sizeof(u8) * len, GFP_KERNEL);
+ real_len = rng->read(rng, buf, len, wait);
+ if (real_len == 0 && wait)
+ pr_err("WAITING FAILED\n");
+ pr_info("wanted %d bytes, got %d\n", len, real_len);
+ print_hex_dump(KERN_INFO, "random bytes@: ", DUMP_PREFIX_ADDRESS,
+ 16, 4, buf, real_len, 1);
+ kfree(buf);
+}
+
+static inline void test_mode_once(struct hwrng *rng, bool wait)
+{
+#define TEST_CHUNK (RN_BUF_SIZE / 4)
+
+ test_len(rng, TEST_CHUNK, wait);
+ test_len(rng, RN_BUF_SIZE * 2, wait);
+ test_len(rng, RN_BUF_SIZE * 2 - TEST_CHUNK, wait);
+}
+
+static inline void test_mode(struct hwrng *rng, bool wait)
+{
+#define TEST_PASS 1
+ int i;
+
+ for (i = 0; i < TEST_PASS; i++)
+ test_mode_once(rng, wait);
+}
+
+static void self_test(struct hwrng *rng)
+{
+ pr_info("testing without waiting\n");
+ test_mode(rng, false);
+ pr_info("testing with waiting\n");
+ test_mode(rng, true);
+}
+#endif
+
static int caam_init_buf(struct caam_rng_ctx *ctx, int buf_id)
{
struct buf_data *bd = &ctx->bufs[buf_id];
@@ -309,6 +353,7 @@ static int __init caam_rng_init(void)
struct device *ctrldev;
struct caam_drv_private *priv;
int err;
+ u32 cha_inst;
dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec-v4.0");
if (!dev_node) {
@@ -335,7 +380,14 @@ static int __init caam_rng_init(void)
return -ENODEV;
/* Check for an instantiated RNG before registration */
- if (!(rd_reg32(&priv->ctrl->perfmon.cha_num_ls) & CHA_ID_LS_RNG_MASK))
+ if (priv->has_seco) {
+ int i = priv->first_jr_index;
+
+ cha_inst = rd_reg32(&priv->jr[i]->perfmon.cha_num_ls);
+ } else {
+ cha_inst = rd_reg32(&priv->ctrl->perfmon.cha_num_ls);
+ }
+ if (!(cha_inst & CHA_ID_LS_RNG_MASK))
return -ENODEV;
dev = caam_jr_alloc();
@@ -352,6 +404,10 @@ static int __init caam_rng_init(void)
if (err)
goto free_rng_ctx;
+#ifdef CONFIG_CRYPTO_DEV_FSL_CAAM_RNG_TEST
+ self_test(&caam_rng);
+#endif
+
dev_info(dev, "registering rng-caam\n");
return hwrng_register(&caam_rng);
diff --git a/drivers/crypto/caam/ctrl.c b/drivers/crypto/caam/ctrl.c
index 39f70411f28f..df5ec6479b9f 100644
--- a/drivers/crypto/caam/ctrl.c
+++ b/drivers/crypto/caam/ctrl.c
@@ -1,7 +1,8 @@
/* * CAAM control-plane driver backend
* Controller-level driver, kernel property detection, initialization
*
- * Copyright 2008-2012 Freescale Semiconductor, Inc.
+ * Copyright 2008-2016 Freescale Semiconductor, Inc.
+ * Copyright 2017-2019 NXP
*/
#include <linux/device.h>
@@ -15,6 +16,7 @@
#include "jr.h"
#include "desc_constr.h"
#include "ctrl.h"
+#include "sm.h"
bool caam_little_end;
EXPORT_SYMBOL(caam_little_end);
@@ -27,6 +29,27 @@ EXPORT_SYMBOL(caam_imx);
#include "qi.h"
#endif
+/* Forward declarations of the functions in order of appearance */
+static inline struct clk *caam_drv_identify_clk(struct device *dev,
+ char *clk_name);
+static int caam_remove(struct platform_device *pdev);
+static void detect_era(struct caam_drv_private *ctrlpriv);
+static void handle_imx6_err005766(struct caam_drv_private *ctrlpriv);
+static int init_clocks(struct caam_drv_private *ctrlpriv);
+static int caam_probe(struct platform_device *pdev);
+static void check_virt(struct caam_drv_private *ctrlpriv, u32 comp_params);
+static int enable_jobrings(struct caam_drv_private *ctrlpriv, int block_offset);
+static void enable_qi(struct caam_drv_private *ctrlpriv, int block_offset);
+static int read_first_jr_index(struct caam_drv_private *ctrlpriv);
+static int probe_w_seco(struct caam_drv_private *ctrlpriv);
+static void init_debugfs(struct caam_drv_private *ctrlpriv);
+static void caam_ctrl_hw_configuration(struct caam_drv_private *ctrlpriv);
+static void enable_virt(struct caam_drv_private *ctrlpriv);
+
+#ifdef CONFIG_PM_SLEEP
+static int caam_off_during_pm(void);
+#endif
+
/*
* i.MX targets tend to have clock control subsystems that can
* enable/disable clocking to our device.
@@ -37,397 +60,276 @@ static inline struct clk *caam_drv_identify_clk(struct device *dev,
return caam_imx ? devm_clk_get(dev, clk_name) : NULL;
}
-/*
- * Descriptor to instantiate RNG State Handle 0 in normal mode and
- * load the JDKEK, TDKEK and TDSK registers
- */
-static void build_instantiation_desc(u32 *desc, int handle, int do_sk)
+static int caam_remove(struct platform_device *pdev)
{
- u32 *jump_cmd, op_flags;
-
- init_job_desc(desc, 0);
+ struct device *ctrldev;
+ struct caam_drv_private *ctrlpriv;
+ struct caam_ctrl __iomem *ctrl;
- op_flags = OP_TYPE_CLASS1_ALG | OP_ALG_ALGSEL_RNG |
- (handle << OP_ALG_AAI_SHIFT) | OP_ALG_AS_INIT;
+ ctrldev = &pdev->dev;
+ ctrlpriv = dev_get_drvdata(ctrldev);
+ ctrl = (struct caam_ctrl __iomem *)ctrlpriv->ctrl;
- /* INIT RNG in non-test mode */
- append_operation(desc, op_flags);
+ /* Remove platform devices under the crypto node */
+ of_platform_depopulate(ctrldev);
- if (!handle && do_sk) {
- /*
- * For SH0, Secure Keys must be generated as well
- */
+#ifdef CONFIG_CAAM_QI
+ if (ctrlpriv->qidev)
+ caam_qi_shutdown(ctrlpriv->qidev);
+#endif
- /* wait for done */
- jump_cmd = append_jump(desc, JUMP_CLASS_CLASS1);
- set_jump_tgt_here(desc, jump_cmd);
+ /* Shut down debug views */
+#ifdef CONFIG_DEBUG_FS
+ debugfs_remove_recursive(ctrlpriv->dfs_root);
+#endif
- /*
- * load 1 to clear written reg:
- * resets the done interrrupt and returns the RNG to idle.
- */
- append_load_imm_u32(desc, 1, LDST_SRCDST_WORD_CLRW);
+ /* Unmap controller region */
+ iounmap(ctrl);
- /* Initialize State Handle */
- append_operation(desc, OP_TYPE_CLASS1_ALG | OP_ALG_ALGSEL_RNG |
- OP_ALG_AAI_RNG4_SK);
+ /* shut clocks off before finalizing shutdown */
+ if (!of_machine_is_compatible("fsl,imx8mm") &&
+ !of_machine_is_compatible("fsl,imx8mq") &&
+ !of_machine_is_compatible("fsl,imx8qm") &&
+ !of_machine_is_compatible("fsl,imx8qxp")) {
+ clk_disable_unprepare(ctrlpriv->caam_ipg);
+ clk_disable_unprepare(ctrlpriv->caam_aclk);
+ if (ctrlpriv->caam_mem)
+ clk_disable_unprepare(ctrlpriv->caam_mem);
+ if (ctrlpriv->caam_emi_slow)
+ clk_disable_unprepare(ctrlpriv->caam_emi_slow);
}
- append_jump(desc, JUMP_CLASS_CLASS1 | JUMP_TYPE_HALT);
-}
-
-/* Descriptor for deinstantiation of State Handle 0 of the RNG block. */
-static void build_deinstantiation_desc(u32 *desc, int handle)
-{
- init_job_desc(desc, 0);
-
- /* Uninstantiate State Handle 0 */
- append_operation(desc, OP_TYPE_CLASS1_ALG | OP_ALG_ALGSEL_RNG |
- (handle << OP_ALG_AAI_SHIFT) | OP_ALG_AS_INITFINAL);
-
- append_jump(desc, JUMP_CLASS_CLASS1 | JUMP_TYPE_HALT);
+ return 0;
}
-/*
- * run_descriptor_deco0 - runs a descriptor on DECO0, under direct control of
- * the software (no JR/QI used).
- * @ctrldev - pointer to device
- * @status - descriptor status, after being run
- *
- * Return: - 0 if no error occurred
- * - -ENODEV if the DECO couldn't be acquired
- * - -EAGAIN if an error occurred while executing the descriptor
- */
-static inline int run_descriptor_deco0(struct device *ctrldev, u32 *desc,
- u32 *status)
+static void detect_era(struct caam_drv_private *ctrlpriv)
{
- struct caam_drv_private *ctrlpriv = dev_get_drvdata(ctrldev);
- struct caam_ctrl __iomem *ctrl = ctrlpriv->ctrl;
- struct caam_deco __iomem *deco = ctrlpriv->deco;
- unsigned int timeout = 100000;
- u32 deco_dbg_reg, flags;
- int i;
+ int ret, i;
+ u32 caam_era;
+ u32 caam_id_ms;
+ char *era_source;
+ struct device_node *caam_node;
+ struct sec_vid sec_vid;
+ struct device *dev = ctrlpriv->dev;
+ static const struct {
+ u16 ip_id;
+ u8 maj_rev;
+ u8 era;
+ } caam_eras[] = {
+ {0x0A10, 1, 1},
+ {0x0A10, 2, 2},
+ {0x0A12, 1, 3},
+ {0x0A14, 1, 3},
+ {0x0A10, 3, 4},
+ {0x0A11, 1, 4},
+ {0x0A14, 2, 4},
+ {0x0A16, 1, 4},
+ {0x0A18, 1, 4},
+ {0x0A11, 2, 5},
+ {0x0A12, 2, 5},
+ {0x0A13, 1, 5},
+ {0x0A1C, 1, 5},
+ {0x0A12, 4, 6},
+ {0x0A13, 2, 6},
+ {0x0A16, 2, 6},
+ {0x0A17, 1, 6},
+ {0x0A18, 2, 6},
+ {0x0A1A, 1, 6},
+ {0x0A1C, 2, 6},
+ {0x0A14, 3, 7},
+ {0x0A10, 4, 8},
+ {0x0A11, 3, 8},
+ {0x0A11, 4, 8},
+ {0x0A12, 5, 8},
+ {0x0A16, 3, 8},
+ };
+ /* If the user or bootloader has set the property we'll use that */
+ caam_node = of_find_compatible_node(NULL, NULL, "fsl,sec-v4.0");
+ ret = of_property_read_u32(caam_node, "fsl,sec-era", &caam_era);
+ of_node_put(caam_node);
- if (ctrlpriv->virt_en == 1) {
- clrsetbits_32(&ctrl->deco_rsr, 0, DECORSR_JR0);
+ if (!ret) {
+ era_source = "device tree";
+ goto era_found;
+ }
- while (!(rd_reg32(&ctrl->deco_rsr) & DECORSR_VALID) &&
- --timeout)
- cpu_relax();
+ i = ctrlpriv->first_jr_index;
+ /* If ccbvid has the era, use that (era 6 and onwards) */
+ if (ctrlpriv->has_seco)
+ caam_era = rd_reg32(&ctrlpriv->jr[i]->perfmon.ccb_id);
+ else
+ caam_era = rd_reg32(&ctrlpriv->ctrl->perfmon.ccb_id);
- timeout = 100000;
+ caam_era = caam_era >> CCB_VID_ERA_SHIFT & CCB_VID_ERA_MASK;
+ if (caam_era) {
+ era_source = "CCBVID";
+ goto era_found;
}
- clrsetbits_32(&ctrl->deco_rq, 0, DECORR_RQD0ENABLE);
-
- while (!(rd_reg32(&ctrl->deco_rq) & DECORR_DEN0) &&
- --timeout)
- cpu_relax();
+ /* If we can match caamvid to known versions, use that */
+ if (ctrlpriv->has_seco)
+ caam_id_ms = rd_reg32(&ctrlpriv->jr[i]->perfmon.caam_id_ms);
+ else
+ caam_id_ms = rd_reg32(&ctrlpriv->ctrl->perfmon.caam_id_ms);
+ sec_vid.ip_id = caam_id_ms >> SEC_VID_IPID_SHIFT;
+ sec_vid.maj_rev = (caam_id_ms & SEC_VID_MAJ_MASK) >> SEC_VID_MAJ_SHIFT;
+
+ for (i = 0; i < ARRAY_SIZE(caam_eras); i++)
+ if (caam_eras[i].ip_id == sec_vid.ip_id &&
+ caam_eras[i].maj_rev == sec_vid.maj_rev) {
+ caam_era = caam_eras[i].era;
+ era_source = "CAAMVID";
+ goto era_found;
+ }
- if (!timeout) {
- dev_err(ctrldev, "failed to acquire DECO 0\n");
- clrsetbits_32(&ctrl->deco_rq, DECORR_RQD0ENABLE, 0);
- return -ENODEV;
- }
+ ctrlpriv->era = -ENOTSUPP;
+ dev_info(dev, "ERA undetermined!.\n");
+ return;
- for (i = 0; i < desc_len(desc); i++)
- wr_reg32(&deco->descbuf[i], caam32_to_cpu(*(desc + i)));
+era_found:
+ ctrlpriv->era = caam_era;
+ dev_info(dev, "ERA source: %s.\n", era_source);
+}
- flags = DECO_JQCR_WHL;
+static void handle_imx6_err005766(struct caam_drv_private *ctrlpriv)
+{
/*
- * If the descriptor length is longer than 4 words, then the
- * FOUR bit in JRCTRL register must be set.
+ * ERRATA: mx6 devices have an issue wherein AXI bus transactions
+ * may not occur in the correct order. This isn't a problem running
+ * single descriptors, but can be if running multiple concurrent
+ * descriptors. Reworking the driver to throttle to single requests
+ * is impractical, thus the workaround is to limit the AXI pipeline
+ * to a depth of 1 (from it's default of 4) to preclude this situation
+ * from occurring.
*/
- if (desc_len(desc) >= 4)
- flags |= DECO_JQCR_FOUR;
-
- /* Instruct the DECO to execute it */
- clrsetbits_32(&deco->jr_ctl_hi, 0, flags);
-
- timeout = 10000000;
- do {
- deco_dbg_reg = rd_reg32(&deco->desc_dbg);
- /*
- * If an error occured in the descriptor, then
- * the DECO status field will be set to 0x0D
- */
- if ((deco_dbg_reg & DESC_DBG_DECO_STAT_MASK) ==
- DESC_DBG_DECO_STAT_HOST_ERR)
- break;
- cpu_relax();
- } while ((deco_dbg_reg & DESC_DBG_DECO_STAT_VALID) && --timeout);
- *status = rd_reg32(&deco->op_status_hi) &
- DECO_OP_STATUS_HI_ERR_MASK;
-
- if (ctrlpriv->virt_en == 1)
- clrsetbits_32(&ctrl->deco_rsr, DECORSR_JR0, 0);
+ u32 mcr_val;
- /* Mark the DECO as free */
- clrsetbits_32(&ctrl->deco_rq, DECORR_RQD0ENABLE, 0);
+ if (ctrlpriv->era != IMX_ERR005766_ERA)
+ return;
- if (!timeout)
- return -EAGAIN;
-
- return 0;
+ if (of_machine_is_compatible("fsl,imx6q") ||
+ of_machine_is_compatible("fsl,imx6dl") ||
+ of_machine_is_compatible("fsl,imx6qp")) {
+ dev_info(&ctrlpriv->pdev->dev,
+ "AXI pipeline throttling enabled.\n");
+ mcr_val = rd_reg32(&ctrlpriv->ctrl->mcr);
+ wr_reg32(&ctrlpriv->ctrl->mcr,
+ (mcr_val & ~(MCFGR_AXIPIPE_MASK)) |
+ ((1 << MCFGR_AXIPIPE_SHIFT) & MCFGR_AXIPIPE_MASK));
+ }
}
-/*
- * instantiate_rng - builds and executes a descriptor on DECO0,
- * which initializes the RNG block.
- * @ctrldev - pointer to device
- * @state_handle_mask - bitmask containing the instantiation status
- * for the RNG4 state handles which exist in
- * the RNG4 block: 1 if it's been instantiated
- * by an external entry, 0 otherwise.
- * @gen_sk - generate data to be loaded into the JDKEK, TDKEK and TDSK;
- * Caution: this can be done only once; if the keys need to be
- * regenerated, a POR is required
- *
- * Return: - 0 if no error occurred
- * - -ENOMEM if there isn't enough memory to allocate the descriptor
- * - -ENODEV if DECO0 couldn't be acquired
- * - -EAGAIN if an error occurred when executing the descriptor
- * f.i. there was a RNG hardware error due to not "good enough"
- * entropy being aquired.
- */
-static int instantiate_rng(struct device *ctrldev, int state_handle_mask,
- int gen_sk)
+static int init_clocks(struct caam_drv_private *ctrlpriv)
{
- struct caam_drv_private *ctrlpriv = dev_get_drvdata(ctrldev);
- struct caam_ctrl __iomem *ctrl;
- u32 *desc, status = 0, rdsta_val;
- int ret = 0, sh_idx;
-
- ctrl = (struct caam_ctrl __iomem *)ctrlpriv->ctrl;
- desc = kmalloc(CAAM_CMD_SZ * 7, GFP_KERNEL);
- if (!desc)
- return -ENOMEM;
-
- for (sh_idx = 0; sh_idx < RNG4_MAX_HANDLES; sh_idx++) {
- /*
- * If the corresponding bit is set, this state handle
- * was initialized by somebody else, so it's left alone.
- */
- if ((1 << sh_idx) & state_handle_mask)
- continue;
-
- /* Create the descriptor for instantiating RNG State Handle */
- build_instantiation_desc(desc, sh_idx, gen_sk);
-
- /* Try to run it through DECO0 */
- ret = run_descriptor_deco0(ctrldev, desc, &status);
-
- /*
- * If ret is not 0, or descriptor status is not 0, then
- * something went wrong. No need to try the next state
- * handle (if available), bail out here.
- * Also, if for some reason, the State Handle didn't get
- * instantiated although the descriptor has finished
- * without any error (HW optimizations for later
- * CAAM eras), then try again.
- */
- if (ret)
- break;
-
- rdsta_val = rd_reg32(&ctrl->r4tst[0].rdsta) & RDSTA_IFMASK;
- if ((status && status != JRSTA_SSRC_JUMP_HALT_CC) ||
- !(rdsta_val & (1 << sh_idx))) {
- ret = -EAGAIN;
- break;
- }
+ struct clk *clk;
+ struct device *dev = ctrlpriv->dev;
+ int ret = 0;
- dev_info(ctrldev, "Instantiated RNG4 SH%d\n", sh_idx);
- /* Clear the contents before recreating the descriptor */
- memset(desc, 0x00, CAAM_CMD_SZ * 7);
+ /* Enable clocking */
+ clk = caam_drv_identify_clk(dev, "ipg");
+ if (IS_ERR(clk)) {
+ ret = PTR_ERR(clk);
+ dev_err(dev, "can't identify CAAM ipg clk: %d\n", ret);
+ goto exit;
}
+ ctrlpriv->caam_ipg = clk;
- kfree(desc);
-
- return ret;
-}
+ ret = clk_prepare_enable(ctrlpriv->caam_ipg);
+ if (ret < 0) {
+ dev_err(dev, "can't enable CAAM ipg clock: %d\n", ret);
+ goto exit;
+ }
-/*
- * deinstantiate_rng - builds and executes a descriptor on DECO0,
- * which deinitializes the RNG block.
- * @ctrldev - pointer to device
- * @state_handle_mask - bitmask containing the instantiation status
- * for the RNG4 state handles which exist in
- * the RNG4 block: 1 if it's been instantiated
- *
- * Return: - 0 if no error occurred
- * - -ENOMEM if there isn't enough memory to allocate the descriptor
- * - -ENODEV if DECO0 couldn't be acquired
- * - -EAGAIN if an error occurred when executing the descriptor
- */
-static int deinstantiate_rng(struct device *ctrldev, int state_handle_mask)
-{
- u32 *desc, status;
- int sh_idx, ret = 0;
+ clk = caam_drv_identify_clk(dev, "aclk");
+ if (IS_ERR(clk)) {
+ ret = PTR_ERR(clk);
+ dev_err(dev, "can't identify CAAM aclk clk: %d\n", ret);
+ goto disable_caam_ipg;
+ }
+ ctrlpriv->caam_aclk = clk;
- desc = kmalloc(CAAM_CMD_SZ * 3, GFP_KERNEL);
- if (!desc)
- return -ENOMEM;
+ ret = clk_prepare_enable(ctrlpriv->caam_aclk);
+ if (ret < 0) {
+ dev_err(dev, "can't enable CAAM aclk clock: %d\n", ret);
+ goto disable_caam_ipg;
+ }
- for (sh_idx = 0; sh_idx < RNG4_MAX_HANDLES; sh_idx++) {
- /*
- * If the corresponding bit is set, then it means the state
- * handle was initialized by us, and thus it needs to be
- * deinitialized as well
- */
- if ((1 << sh_idx) & state_handle_mask) {
- /*
- * Create the descriptor for deinstantating this state
- * handle
- */
- build_deinstantiation_desc(desc, sh_idx);
+ if (!(of_find_compatible_node(NULL, NULL, "fsl,imx7d-caam"))) {
+ clk = caam_drv_identify_clk(dev, "mem");
+ if (IS_ERR(clk)) {
+ ret = PTR_ERR(clk);
+ dev_err(dev, "can't identify CAAM mem clk: %d\n", ret);
+ goto disable_caam_aclk;
+ }
+ ctrlpriv->caam_mem = clk;
- /* Try to run it through DECO0 */
- ret = run_descriptor_deco0(ctrldev, desc, &status);
+ ret = clk_prepare_enable(ctrlpriv->caam_mem);
+ if (ret < 0) {
+ dev_err(dev, "can't enable CAAM secure mem clock: %d\n",
+ ret);
+ goto disable_caam_aclk;
+ }
- if (ret ||
- (status && status != JRSTA_SSRC_JUMP_HALT_CC)) {
- dev_err(ctrldev,
- "Failed to deinstantiate RNG4 SH%d\n",
- sh_idx);
- break;
+ if (!(of_find_compatible_node(NULL, NULL, "fsl,imx6ul-caam"))) {
+ clk = caam_drv_identify_clk(dev, "emi_slow");
+ if (IS_ERR(clk)) {
+ ret = PTR_ERR(clk);
+ dev_err(dev,
+ "can't identify CAAM emi_slow clk: %d\n",
+ ret);
+ goto disable_caam_mem;
+ }
+ ctrlpriv->caam_emi_slow = clk;
+
+ ret = clk_prepare_enable(ctrlpriv->caam_emi_slow);
+ if (ret < 0) {
+ dev_err(dev,
+ "can't enable CAAM emi slow clock: %d\n",
+ ret);
+ goto disable_caam_mem;
}
- dev_info(ctrldev, "Deinstantiated RNG4 SH%d\n", sh_idx);
}
}
- kfree(desc);
-
- return ret;
-}
-
-static int caam_remove(struct platform_device *pdev)
-{
- struct device *ctrldev;
- struct caam_drv_private *ctrlpriv;
- struct caam_ctrl __iomem *ctrl;
-
- ctrldev = &pdev->dev;
- ctrlpriv = dev_get_drvdata(ctrldev);
- ctrl = (struct caam_ctrl __iomem *)ctrlpriv->ctrl;
-
- /* Remove platform devices under the crypto node */
- of_platform_depopulate(ctrldev);
-
-#ifdef CONFIG_CAAM_QI
- if (ctrlpriv->qidev)
- caam_qi_shutdown(ctrlpriv->qidev);
-#endif
-
- /*
- * De-initialize RNG state handles initialized by this driver.
- * In case of DPAA 2.x, RNG is managed by MC firmware.
- */
- if (!caam_dpaa2 && ctrlpriv->rng4_sh_init)
- deinstantiate_rng(ctrldev, ctrlpriv->rng4_sh_init);
-
- /* Shut down debug views */
-#ifdef CONFIG_DEBUG_FS
- debugfs_remove_recursive(ctrlpriv->dfs_root);
-#endif
-
- /* Unmap controller region */
- iounmap(ctrl);
+ goto exit;
- /* shut clocks off before finalizing shutdown */
- clk_disable_unprepare(ctrlpriv->caam_ipg);
+disable_caam_mem:
clk_disable_unprepare(ctrlpriv->caam_mem);
+disable_caam_aclk:
clk_disable_unprepare(ctrlpriv->caam_aclk);
- if (ctrlpriv->caam_emi_slow)
- clk_disable_unprepare(ctrlpriv->caam_emi_slow);
- return 0;
+disable_caam_ipg:
+ clk_disable_unprepare(ctrlpriv->caam_ipg);
+exit:
+ return ret;
}
-/*
- * kick_trng - sets the various parameters for enabling the initialization
- * of the RNG4 block in CAAM
- * @pdev - pointer to the platform device
- * @ent_delay - Defines the length (in system clocks) of each entropy sample.
- */
-static void kick_trng(struct platform_device *pdev, int ent_delay)
+static void caam_ctrl_hw_configuration(struct caam_drv_private *ctrlpriv)
{
- struct device *ctrldev = &pdev->dev;
- struct caam_drv_private *ctrlpriv = dev_get_drvdata(ctrldev);
- struct caam_ctrl __iomem *ctrl;
- struct rng4tst __iomem *r4tst;
- u32 val;
-
- ctrl = (struct caam_ctrl __iomem *)ctrlpriv->ctrl;
- r4tst = &ctrl->r4tst[0];
-
- /* put RNG4 into program mode */
- clrsetbits_32(&r4tst->rtmctl, 0, RTMCTL_PRGM);
-
- /*
- * Performance-wise, it does not make sense to
- * set the delay to a value that is lower
- * than the last one that worked (i.e. the state handles
- * were instantiated properly. Thus, instead of wasting
- * time trying to set the values controlling the sample
- * frequency, the function simply returns.
- */
- val = (rd_reg32(&r4tst->rtsdctl) & RTSDCTL_ENT_DLY_MASK)
- >> RTSDCTL_ENT_DLY_SHIFT;
- if (ent_delay <= val)
- goto start_rng;
-
- val = rd_reg32(&r4tst->rtsdctl);
- val = (val & ~RTSDCTL_ENT_DLY_MASK) |
- (ent_delay << RTSDCTL_ENT_DLY_SHIFT);
- wr_reg32(&r4tst->rtsdctl, val);
- /* min. freq. count, equal to 1/4 of the entropy sample length */
- wr_reg32(&r4tst->rtfrqmin, ent_delay >> 2);
- /* disable maximum frequency count */
- wr_reg32(&r4tst->rtfrqmax, RTFRQMAX_DISABLE);
- /* read the control register */
- val = rd_reg32(&r4tst->rtmctl);
-start_rng:
/*
- * select raw sampling in both entropy shifter
- * and statistical checker; ; put RNG4 into run mode
+ * Enable DECO watchdogs and, if this is a PHYS_ADDR_T_64BIT kernel,
+ * long pointers in master configuration register.
+ * In case of DPAA 2.x, Management Complex firmware performs
+ * the configuration.
*/
- clrsetbits_32(&r4tst->rtmctl, RTMCTL_PRGM, RTMCTL_SAMP_MODE_RAW_ES_SC);
-}
-
-/**
- * caam_get_era() - Return the ERA of the SEC on SoC, based
- * on "sec-era" propery in the DTS. This property is updated by u-boot.
- **/
-int caam_get_era(void)
-{
- struct device_node *caam_node;
- int ret;
- u32 prop;
+ if (!caam_dpaa2)
+ clrsetbits_32(&ctrlpriv->ctrl->mcr,
+ MCFGR_AWCACHE_MASK | MCFGR_LONG_PTR,
+ MCFGR_AWCACHE_CACH | MCFGR_AWCACHE_BUFF |
+ MCFGR_WDENABLE | MCFGR_LARGE_BURST |
+ (sizeof(dma_addr_t) == sizeof(u64) ?
+ MCFGR_LONG_PTR : 0));
- caam_node = of_find_compatible_node(NULL, NULL, "fsl,sec-v4.0");
- ret = of_property_read_u32(caam_node, "fsl,sec-era", &prop);
- of_node_put(caam_node);
+ handle_imx6_err005766(ctrlpriv);
- return ret ? -ENOTSUPP : prop;
+ enable_virt(ctrlpriv);
}
-EXPORT_SYMBOL(caam_get_era);
-
-static const struct of_device_id caam_match[] = {
- {
- .compatible = "fsl,sec-v4.0",
- },
- {
- .compatible = "fsl,sec4.0",
- },
- {},
-};
-MODULE_DEVICE_TABLE(of, caam_match);
/* Probe routine for CAAM top (controller) level */
static int caam_probe(struct platform_device *pdev)
{
- int ret, ring, gen_sk, ent_delay = RTSDCTL_ENT_DLY_MIN;
+ int ret;
u64 caam_id;
static const struct soc_device_attribute imx_soc[] = {
{.family = "Freescale i.MX"},
@@ -435,150 +337,219 @@ static int caam_probe(struct platform_device *pdev)
};
struct device *dev;
struct device_node *nprop, *np;
+ struct resource res_regs;
struct caam_ctrl __iomem *ctrl;
struct caam_drv_private *ctrlpriv;
- struct clk *clk;
-#ifdef CONFIG_DEBUG_FS
- struct caam_perfmon *perfmon;
-#endif
- u32 scfgr, comp_params;
- u32 cha_vid_ls;
+ u32 comp_params;
int pg_size;
- int BLOCK_OFFSET = 0;
+ int block_offset = 0;
ctrlpriv = devm_kzalloc(&pdev->dev, sizeof(*ctrlpriv), GFP_KERNEL);
- if (!ctrlpriv)
- return -ENOMEM;
+ if (!ctrlpriv) {
+ ret = -ENOMEM;
+ goto exit;
+ }
dev = &pdev->dev;
dev_set_drvdata(dev, ctrlpriv);
+ ctrlpriv->dev = dev;
+ ctrlpriv->pdev = pdev;
nprop = pdev->dev.of_node;
caam_imx = (bool)soc_device_match(imx_soc);
- /* Enable clocking */
- clk = caam_drv_identify_clk(&pdev->dev, "ipg");
- if (IS_ERR(clk)) {
- ret = PTR_ERR(clk);
- dev_err(&pdev->dev,
- "can't identify CAAM ipg clk: %d\n", ret);
- return ret;
- }
- ctrlpriv->caam_ipg = clk;
-
- clk = caam_drv_identify_clk(&pdev->dev, "mem");
- if (IS_ERR(clk)) {
- ret = PTR_ERR(clk);
- dev_err(&pdev->dev,
- "can't identify CAAM mem clk: %d\n", ret);
- return ret;
- }
- ctrlpriv->caam_mem = clk;
-
- clk = caam_drv_identify_clk(&pdev->dev, "aclk");
- if (IS_ERR(clk)) {
- ret = PTR_ERR(clk);
- dev_err(&pdev->dev,
- "can't identify CAAM aclk clk: %d\n", ret);
- return ret;
- }
- ctrlpriv->caam_aclk = clk;
-
- if (!of_machine_is_compatible("fsl,imx6ul")) {
- clk = caam_drv_identify_clk(&pdev->dev, "emi_slow");
- if (IS_ERR(clk)) {
- ret = PTR_ERR(clk);
- dev_err(&pdev->dev,
- "can't identify CAAM emi_slow clk: %d\n", ret);
- return ret;
- }
- ctrlpriv->caam_emi_slow = clk;
- }
-
- ret = clk_prepare_enable(ctrlpriv->caam_ipg);
- if (ret < 0) {
- dev_err(&pdev->dev, "can't enable CAAM ipg clock: %d\n", ret);
- return ret;
- }
-
- ret = clk_prepare_enable(ctrlpriv->caam_mem);
- if (ret < 0) {
- dev_err(&pdev->dev, "can't enable CAAM secure mem clock: %d\n",
- ret);
- goto disable_caam_ipg;
- }
-
- ret = clk_prepare_enable(ctrlpriv->caam_aclk);
- if (ret < 0) {
- dev_err(&pdev->dev, "can't enable CAAM aclk clock: %d\n", ret);
- goto disable_caam_mem;
- }
-
- if (ctrlpriv->caam_emi_slow) {
- ret = clk_prepare_enable(ctrlpriv->caam_emi_slow);
- if (ret < 0) {
- dev_err(&pdev->dev, "can't enable CAAM emi slow clock: %d\n",
- ret);
- goto disable_caam_aclk;
- }
+ if (!of_machine_is_compatible("fsl,imx8mm") &&
+ !of_machine_is_compatible("fsl,imx8mq") &&
+ !of_machine_is_compatible("fsl,imx8qm") &&
+ !of_machine_is_compatible("fsl,imx8qxp")) {
+ ret = init_clocks(ctrlpriv);
+ if (ret)
+ goto exit;
}
-
/* Get configuration properties from device tree */
/* First, get register page */
ctrl = of_iomap(nprop, 0);
if (ctrl == NULL) {
dev_err(dev, "caam: of_iomap() failed\n");
ret = -ENOMEM;
- goto disable_caam_emi_slow;
+ goto disable_clocks;
+ }
+ ctrlpriv->ctrl = (struct caam_ctrl __force *)ctrl;
+
+ if (of_find_compatible_node(NULL, NULL, "linaro,optee-tz"))
+ ctrlpriv->has_optee = 1;
+
+ if (of_machine_is_compatible("fsl,imx8qm") ||
+ of_machine_is_compatible("fsl,imx8qxp"))
+ ctrlpriv->has_seco = 1;
+
+ /*
+ * The driver does not have access to Page 0 of the CAAM if there
+ * is a secure component managing the CAAM as optee or SECO.
+ */
+ ctrlpriv->has_access_p0 = !(ctrlpriv->has_optee || ctrlpriv->has_seco);
+
+#ifdef CONFIG_PM_SLEEP
+ ctrlpriv->caam_off_during_pm = caam_off_during_pm();
+#endif
+
+ if (ctrlpriv->has_seco) {
+ ret = probe_w_seco(ctrlpriv);
+ if (ret)
+ goto iounmap_ctrl;
+ return ret;
}
- caam_little_end = !(bool)(rd_reg32(&ctrl->perfmon.status) &
+ if (caam_imx)
+ caam_little_end = true;
+ else
+ caam_little_end = !(bool)(rd_reg32(&ctrl->perfmon.status) &
(CSTA_PLEND | CSTA_ALT_PLEND));
/* Finding the page size for using the CTPR_MS register */
comp_params = rd_reg32(&ctrl->perfmon.comp_parms_ms);
pg_size = (comp_params & CTPR_MS_PG_SZ_MASK) >> CTPR_MS_PG_SZ_SHIFT;
- /* Allocating the BLOCK_OFFSET based on the supported page size on
+ /* Allocating the block_offset based on the supported page size on
* the platform
*/
if (pg_size == 0)
- BLOCK_OFFSET = PG_SIZE_4K;
+ block_offset = PG_SIZE_4K;
else
- BLOCK_OFFSET = PG_SIZE_64K;
+ block_offset = PG_SIZE_64K;
- ctrlpriv->ctrl = (struct caam_ctrl __iomem __force *)ctrl;
ctrlpriv->assure = (struct caam_assurance __iomem __force *)
((__force uint8_t *)ctrl +
- BLOCK_OFFSET * ASSURE_BLOCK_NUMBER
- );
+ block_offset * ASSURE_BLOCK_NUMBER);
ctrlpriv->deco = (struct caam_deco __iomem __force *)
((__force uint8_t *)ctrl +
- BLOCK_OFFSET * DECO_BLOCK_NUMBER
- );
+ block_offset * DECO_BLOCK_NUMBER);
- /* Get the IRQ of the controller (for security violations only) */
- ctrlpriv->secvio_irq = irq_of_parse_and_map(nprop, 0);
+ detect_era(ctrlpriv);
+
+ /* Get CAAM-SM node and of_iomap() and save */
+ np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-caam-sm");
+ if (!np) {
+ ret = -ENODEV;
+ goto iounmap_ctrl;
+ }
+
+ /* Get CAAM SM registers base address from device tree */
+ ret = of_address_to_resource(np, 0, &res_regs);
+ if (ret) {
+ dev_err(dev, "failed to retrieve registers base from device tree\n");
+ ret = -ENODEV;
+ goto iounmap_ctrl;
+ }
+
+ ctrlpriv->sm_phy = res_regs.start;
+ ctrlpriv->sm_base = devm_ioremap_resource(dev, &res_regs);
+ if (IS_ERR(ctrlpriv->sm_base)) {
+ ret = PTR_ERR(ctrlpriv->sm_base);
+ goto iounmap_ctrl;
+ }
+
+ if (!of_machine_is_compatible("fsl,imx8mm") &&
+ !of_machine_is_compatible("fsl,imx8mq") &&
+ !of_machine_is_compatible("fsl,imx8qm") &&
+ !of_machine_is_compatible("fsl,imx8qxp")) {
+ ctrlpriv->sm_size = resource_size(&res_regs);
+ } else {
+ ctrlpriv->sm_size = PG_SIZE_64K;
+ }
- /*
- * Enable DECO watchdogs and, if this is a PHYS_ADDR_T_64BIT kernel,
- * long pointers in master configuration register.
- * In case of DPAA 2.x, Management Complex firmware performs
- * the configuration.
- */
caam_dpaa2 = !!(comp_params & CTPR_MS_DPAA2);
- if (!caam_dpaa2)
- clrsetbits_32(&ctrl->mcr, MCFGR_AWCACHE_MASK | MCFGR_LONG_PTR,
- MCFGR_AWCACHE_CACH | MCFGR_AWCACHE_BUFF |
- MCFGR_WDENABLE | MCFGR_LARGE_BURST |
- (sizeof(dma_addr_t) == sizeof(u64) ?
- MCFGR_LONG_PTR : 0));
+ check_virt(ctrlpriv, comp_params);
+
+ if (ctrlpriv->has_access_p0)
+ caam_ctrl_hw_configuration(ctrlpriv);
+
+ /* Set DMA masks according to platform ranging */
+ if (of_machine_is_compatible("fsl,imx8mm") ||
+ of_machine_is_compatible("fsl,imx8qm") ||
+ of_machine_is_compatible("fsl,imx8qxp") ||
+ of_machine_is_compatible("fsl,imx8mq")) {
+ ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32));
+ } else if (sizeof(dma_addr_t) == sizeof(u64))
+ if (of_device_is_compatible(nprop, "fsl,sec-v5.0"))
+ ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(40));
+ else
+ ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(36));
+ else
+ ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32));
+
+ if (ret) {
+ dev_err(dev, "dma_set_mask_and_coherent failed (%d)\n",
+ ret);
+ goto iounmap_ctrl;
+ }
+
+ ret = enable_jobrings(ctrlpriv, block_offset);
+ if (ret)
+ goto iounmap_ctrl;
+
+ enable_qi(ctrlpriv, block_offset);
+
+ /* If no QI and no rings specified, quit and go home */
+ if ((!ctrlpriv->qi_present) && (!ctrlpriv->total_jobrs)) {
+ dev_err(dev, "no queues configured, terminating\n");
+ ret = -ENOMEM;
+ goto caam_remove;
+ }
+
+ /* NOTE: RTIC detection ought to go here, around Si time */
+
+ caam_id = (u64)rd_reg32(&ctrl->perfmon.caam_id_ms) << 32 |
+ (u64)rd_reg32(&ctrl->perfmon.caam_id_ls);
+
+ dev_info(dev, "device ID = 0x%016llx (Era %d)\n", caam_id,
+ ctrlpriv->era);
+ dev_info(dev, "job rings = %d, qi = %d, dpaa2 = %s\n",
+ ctrlpriv->total_jobrs, ctrlpriv->qi_present,
+ caam_dpaa2 ? "yes" : "no");
+
+ init_debugfs(ctrlpriv);
+
+ return 0;
+
+caam_remove:
+ caam_remove(pdev);
+ return ret;
+
+iounmap_ctrl:
+ iounmap(ctrl);
+disable_clocks:
+ if (!of_machine_is_compatible("fsl,imx8mm") &&
+ !of_machine_is_compatible("fsl,imx8mq") &&
+ !of_machine_is_compatible("fsl,imx8qm") &&
+ !of_machine_is_compatible("fsl,imx8qxp")) {
+ clk_disable_unprepare(ctrlpriv->caam_emi_slow);
+ clk_disable_unprepare(ctrlpriv->caam_aclk);
+ clk_disable_unprepare(ctrlpriv->caam_mem);
+ clk_disable_unprepare(ctrlpriv->caam_ipg);
+ }
+
+exit:
+ return ret;
+}
+
+static void enable_virt(struct caam_drv_private *ctrlpriv)
+{
+ if (ctrlpriv->virt_en == 1)
+ clrsetbits_32(&ctrlpriv->ctrl->jrstart, 0, JRSTART_JR0_START |
+ JRSTART_JR1_START | JRSTART_JR2_START |
+ JRSTART_JR3_START);
+}
+static void check_virt(struct caam_drv_private *ctrlpriv, u32 comp_params)
+{
/*
- * Read the Compile Time paramters and SCFGR to determine
+ * Read the Compile Time parameters and SCFGR to determine
* if Virtualization is enabled for this platform
*/
- scfgr = rd_reg32(&ctrl->scfgr);
+ u32 scfgr;
+
+ scfgr = rd_reg32(&ctrlpriv->ctrl->scfgr);
ctrlpriv->virt_en = 0;
if (comp_params & CTPR_MS_VIRT_EN_INCL) {
@@ -588,38 +559,20 @@ static int caam_probe(struct platform_device *pdev)
if ((comp_params & CTPR_MS_VIRT_EN_POR) ||
(!(comp_params & CTPR_MS_VIRT_EN_POR) &&
(scfgr & SCFGR_VIRT_EN)))
- ctrlpriv->virt_en = 1;
+ ctrlpriv->virt_en = 1;
} else {
/* VIRT_EN_INCL = 0 && VIRT_EN_POR_VALUE = 1 */
if (comp_params & CTPR_MS_VIRT_EN_POR)
- ctrlpriv->virt_en = 1;
- }
-
- if (ctrlpriv->virt_en == 1)
- clrsetbits_32(&ctrl->jrstart, 0, JRSTART_JR0_START |
- JRSTART_JR1_START | JRSTART_JR2_START |
- JRSTART_JR3_START);
-
- if (sizeof(dma_addr_t) == sizeof(u64)) {
- if (caam_dpaa2)
- ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(49));
- else if (of_device_is_compatible(nprop, "fsl,sec-v5.0"))
- ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(40));
- else
- ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(36));
- } else {
- ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32));
- }
- if (ret) {
- dev_err(dev, "dma_set_mask_and_coherent failed (%d)\n", ret);
- goto iounmap_ctrl;
+ ctrlpriv->virt_en = 1;
}
+}
- ret = of_platform_populate(nprop, caam_match, NULL, dev);
- if (ret) {
- dev_err(dev, "JR platform devices creation error\n");
- goto iounmap_ctrl;
- }
+static int enable_jobrings(struct caam_drv_private *ctrlpriv, int block_offset)
+{
+ int ring, index;
+ int ret;
+ struct device_node *nprop, *np;
+ struct device *dev = ctrlpriv->dev;
#ifdef CONFIG_DEBUG_FS
/*
@@ -627,32 +580,57 @@ static int caam_probe(struct platform_device *pdev)
* "caam" and nprop->full_name. The OF name isn't distinctive,
* but does separate instances
*/
- perfmon = (struct caam_perfmon __force *)&ctrl->perfmon;
ctrlpriv->dfs_root = debugfs_create_dir(dev_name(dev), NULL);
ctrlpriv->ctl = debugfs_create_dir("ctl", ctrlpriv->dfs_root);
#endif
+ nprop = ctrlpriv->pdev->dev.of_node;
+ ret = of_platform_populate(nprop, NULL, NULL, dev);
+ if (ret) {
+ dev_err(dev, "JR platform devices creation error\n");
+ return -ENOMEM;
+ }
+
ring = 0;
for_each_available_child_of_node(nprop, np)
if (of_device_is_compatible(np, "fsl,sec-v4.0-job-ring") ||
of_device_is_compatible(np, "fsl,sec4.0-job-ring")) {
- ctrlpriv->jr[ring] = (struct caam_job_ring __iomem __force *)
- ((__force uint8_t *)ctrl +
- (ring + JR_BLOCK_NUMBER) *
- BLOCK_OFFSET
- );
+
+ if (of_property_read_u32_index(np, "reg", 0, &index)) {
+ dev_err(dev, "%s read reg property error %d.",
+ np->full_name, index);
+ continue;
+ }
+ /* Get actual job ring index from its offset
+ * ex: CAAM JR2 offset 0x30000 index = 2
+ */
+ while (index >= 16)
+ index = index >> 4;
+ index -= 1;
+ ctrlpriv->jr[index] = (struct caam_job_ring __force *)
+ ((uint8_t *)ctrlpriv->ctrl +
+ (index + JR_BLOCK_NUMBER) *
+ block_offset);
ctrlpriv->total_jobrs++;
ring++;
}
+ return 0;
+}
+
+static void enable_qi(struct caam_drv_private *ctrlpriv, int block_offset)
+{
+ u32 parms_ms = rd_reg32(&ctrlpriv->ctrl->perfmon.comp_parms_ms);
+
/* Check to see if (DPAA 1.x) QI present. If so, enable */
- ctrlpriv->qi_present = !!(comp_params & CTPR_MS_QI_MASK);
+ ctrlpriv->qi_present = !!(parms_ms & CTPR_MS_QI_MASK);
if (ctrlpriv->qi_present && !caam_dpaa2) {
ctrlpriv->qi = (struct caam_queue_if __iomem __force *)
- ((__force uint8_t *)ctrl +
- BLOCK_OFFSET * QI_BLOCK_NUMBER
+ ((__force uint8_t *)ctrlpriv->ctrl +
+ block_offset * QI_BLOCK_NUMBER
);
+
/* This is all that's required to physically enable QI */
wr_reg32(&ctrlpriv->qi->qi_control_lo, QICTL_DQEN);
@@ -663,125 +641,163 @@ static int caam_probe(struct platform_device *pdev)
dev_err(dev, "caam qi i/f init failed: %d\n", ret);
#endif
}
+}
- /* If no QI and no rings specified, quit and go home */
- if ((!ctrlpriv->qi_present) && (!ctrlpriv->total_jobrs)) {
- dev_err(dev, "no queues configured, terminating\n");
- ret = -ENOMEM;
- goto caam_remove;
- }
+static int read_first_jr_index(struct caam_drv_private *ctrlpriv)
+{
+ struct device_node *caam_node;
+ int ret;
+ u32 first_index;
+
+ caam_node = of_find_compatible_node(NULL, NULL, "fsl,sec-v4.0");
+ ret = of_property_read_u32(caam_node,
+ "fsl,first-jr-index", &first_index);
+ of_node_put(caam_node);
+ if (ret == 0)
+ if (first_index > 0 && first_index < 4)
+ ctrlpriv->first_jr_index = first_index;
+ return ret;
+}
- cha_vid_ls = rd_reg32(&ctrl->perfmon.cha_id_ls);
+static int probe_w_seco(struct caam_drv_private *ctrlpriv)
+{
+ int ret = 0;
+ struct device_node *np;
+ u32 idx;
+ ctrlpriv->has_seco = true;
/*
- * If SEC has RNG version >= 4 and RNG state handle has not been
- * already instantiated, do RNG instantiation
- * In case of DPAA 2.x, RNG is managed by MC firmware.
+ * For imx8 page size is 64k, we can't access ctrl regs to dynamically
+ * obtain this info.
*/
- if (!caam_dpaa2 &&
- (cha_vid_ls & CHA_ID_LS_RNG_MASK) >> CHA_ID_LS_RNG_SHIFT >= 4) {
- ctrlpriv->rng4_sh_init =
- rd_reg32(&ctrl->r4tst[0].rdsta);
- /*
- * If the secure keys (TDKEK, JDKEK, TDSK), were already
- * generated, signal this to the function that is instantiating
- * the state handles. An error would occur if RNG4 attempts
- * to regenerate these keys before the next POR.
- */
- gen_sk = ctrlpriv->rng4_sh_init & RDSTA_SKVN ? 0 : 1;
- ctrlpriv->rng4_sh_init &= RDSTA_IFMASK;
- do {
- int inst_handles =
- rd_reg32(&ctrl->r4tst[0].rdsta) &
- RDSTA_IFMASK;
- /*
- * If either SH were instantiated by somebody else
- * (e.g. u-boot) then it is assumed that the entropy
- * parameters are properly set and thus the function
- * setting these (kick_trng(...)) is skipped.
- * Also, if a handle was instantiated, do not change
- * the TRNG parameters.
- */
- if (!(ctrlpriv->rng4_sh_init || inst_handles)) {
- dev_info(dev,
- "Entropy delay = %u\n",
- ent_delay);
- kick_trng(pdev, ent_delay);
- ent_delay += 400;
- }
- /*
- * if instantiate_rng(...) fails, the loop will rerun
- * and the kick_trng(...) function will modfiy the
- * upper and lower limits of the entropy sampling
- * interval, leading to a sucessful initialization of
- * the RNG.
- */
- ret = instantiate_rng(dev, inst_handles,
- gen_sk);
- if (ret == -EAGAIN)
- /*
- * if here, the loop will rerun,
- * so don't hog the CPU
- */
- cpu_relax();
- } while ((ret == -EAGAIN) && (ent_delay < RTSDCTL_ENT_DLY_MAX));
- if (ret) {
- dev_err(dev, "failed to instantiate RNG");
- goto caam_remove;
- }
- /*
- * Set handles init'ed by this module as the complement of the
- * already initialized ones
- */
- ctrlpriv->rng4_sh_init = ~ctrlpriv->rng4_sh_init & RDSTA_IFMASK;
+ ret = enable_jobrings(ctrlpriv, PG_SIZE_64K);
+ if (ret)
+ return ret;
+ if (!ctrlpriv->total_jobrs) {
+ dev_err(ctrlpriv->dev, "no job rings configured!\n");
+ return -ENODEV;
+ }
- /* Enable RDB bit so that RNG works faster */
- clrsetbits_32(&ctrl->scfgr, 0, SCFGR_RDBENABLE);
+ /*
+ * Read first job ring index for aliased registers
+ */
+ if (read_first_jr_index(ctrlpriv)) {
+ dev_err(ctrlpriv->dev, "missing first job ring index!\n");
+ return -ENODEV;
+ }
+ idx = ctrlpriv->first_jr_index;
+
+ caam_little_end = true;
+ ctrlpriv->assure = ((struct caam_assurance __force *)
+ ((uint8_t *)ctrlpriv->ctrl +
+ PG_SIZE_64K * ASSURE_BLOCK_NUMBER));
+ ctrlpriv->deco = ((struct caam_deco __force *)
+ ((uint8_t *)ctrlpriv->ctrl +
+ PG_SIZE_64K * DECO_BLOCK_NUMBER));
+
+ detect_era(ctrlpriv);
+
+ /* Get CAAM-SM node and of_iomap() and save */
+ np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-caam-sm");
+ if (!np) {
+ dev_warn(ctrlpriv->dev, "No CAAM-SM node found!\n");
+ return -ENODEV;
}
- /* NOTE: RTIC detection ought to go here, around Si time */
+ ctrlpriv->sm_base = of_iomap(np, 0);
+ ctrlpriv->sm_size = 0x3fff;
- caam_id = (u64)rd_reg32(&ctrl->perfmon.caam_id_ms) << 32 |
- (u64)rd_reg32(&ctrl->perfmon.caam_id_ls);
+ /* Can't enable DECO WD and LPs those are in MCR */
- /* Report "alive" for developer to see */
- dev_info(dev, "device ID = 0x%016llx (Era %d)\n", caam_id,
- caam_get_era());
- dev_info(dev, "job rings = %d, qi = %d, dpaa2 = %s\n",
- ctrlpriv->total_jobrs, ctrlpriv->qi_present,
- caam_dpaa2 ? "yes" : "no");
+ /*
+ * can't check for virtualization because we need access to SCFGR for it
+ */
+
+ /* Set DMA masks according to platform ranging */
+ if (of_machine_is_compatible("fsl,imx8mm") ||
+ of_machine_is_compatible("fsl,imx8qm") ||
+ of_machine_is_compatible("fsl,imx8qxp") ||
+ of_machine_is_compatible("fsl,imx8mq")) {
+ ret = dma_set_mask_and_coherent(ctrlpriv->dev,
+ DMA_BIT_MASK(32));
+ } else if (sizeof(dma_addr_t) == sizeof(u64))
+ if (of_device_is_compatible(ctrlpriv->pdev->dev.of_node,
+ "fsl,sec-v5.0"))
+ ret = dma_set_mask_and_coherent(ctrlpriv->dev,
+ DMA_BIT_MASK(40));
+ else
+ ret = dma_set_mask_and_coherent(ctrlpriv->dev,
+ DMA_BIT_MASK(36));
+ else
+ ret = dma_set_mask_and_coherent(ctrlpriv->dev,
+ DMA_BIT_MASK(32));
+
+ if (ret) {
+ dev_err(ctrlpriv->dev, "dma_set_mask_and_coherent failed (%d)\n",
+ ret);
+ return ret;
+ }
+
+ /*
+ * this is where we should run the descriptor for DRNG init
+ * TRNG must be initialized by SECO
+ */
+ return ret;
+}
+static void init_debugfs(struct caam_drv_private *ctrlpriv)
+{
#ifdef CONFIG_DEBUG_FS
- debugfs_create_file("rq_dequeued", S_IRUSR | S_IRGRP | S_IROTH,
+ struct caam_perfmon *perfmon;
+ /* Read permission of the file created:
+ * - S_IRUSR (user): 0x400
+ * - S_IRGRP (group): 0x040
+ * - S_IROTH (other): 0x004
+ */
+ umode_t perm = 0x400 | 0x040 | 0x004;
+
+ /*
+ * FIXME: needs better naming distinction, as some amalgamation of
+ * "caam" and nprop->full_name. The OF name isn't distinctive,
+ * but does separate instances
+ */
+ perfmon = (struct caam_perfmon __force *)&ctrlpriv->ctrl->perfmon;
+
+ ctrlpriv->dfs_root = debugfs_create_dir(dev_name(ctrlpriv->dev), NULL);
+ ctrlpriv->ctl = debugfs_create_dir("ctl", ctrlpriv->dfs_root);
+
+ /* Controller-level - performance monitor counters */
+
+ debugfs_create_file("rq_dequeued", perm,
ctrlpriv->ctl, &perfmon->req_dequeued,
&caam_fops_u64_ro);
- debugfs_create_file("ob_rq_encrypted", S_IRUSR | S_IRGRP | S_IROTH,
+ debugfs_create_file("ob_rq_encrypted", perm,
ctrlpriv->ctl, &perfmon->ob_enc_req,
&caam_fops_u64_ro);
- debugfs_create_file("ib_rq_decrypted", S_IRUSR | S_IRGRP | S_IROTH,
+ debugfs_create_file("ib_rq_decrypted", perm,
ctrlpriv->ctl, &perfmon->ib_dec_req,
&caam_fops_u64_ro);
- debugfs_create_file("ob_bytes_encrypted", S_IRUSR | S_IRGRP | S_IROTH,
+ debugfs_create_file("ob_bytes_encrypted", perm,
ctrlpriv->ctl, &perfmon->ob_enc_bytes,
&caam_fops_u64_ro);
- debugfs_create_file("ob_bytes_protected", S_IRUSR | S_IRGRP | S_IROTH,
+ debugfs_create_file("ob_bytes_protected", perm,
ctrlpriv->ctl, &perfmon->ob_prot_bytes,
&caam_fops_u64_ro);
- debugfs_create_file("ib_bytes_decrypted", S_IRUSR | S_IRGRP | S_IROTH,
+ debugfs_create_file("ib_bytes_decrypted", perm,
ctrlpriv->ctl, &perfmon->ib_dec_bytes,
&caam_fops_u64_ro);
- debugfs_create_file("ib_bytes_validated", S_IRUSR | S_IRGRP | S_IROTH,
+ debugfs_create_file("ib_bytes_validated", perm,
ctrlpriv->ctl, &perfmon->ib_valid_bytes,
&caam_fops_u64_ro);
/* Controller level - global status values */
- debugfs_create_file("fault_addr", S_IRUSR | S_IRGRP | S_IROTH,
+ debugfs_create_file("fault_addr", perm,
ctrlpriv->ctl, &perfmon->faultaddr,
&caam_fops_u32_ro);
- debugfs_create_file("fault_detail", S_IRUSR | S_IRGRP | S_IROTH,
+ debugfs_create_file("fault_detail", perm,
ctrlpriv->ctl, &perfmon->faultdetail,
&caam_fops_u32_ro);
- debugfs_create_file("fault_status", S_IRUSR | S_IRGRP | S_IROTH,
+ debugfs_create_file("fault_status", perm,
ctrlpriv->ctl, &perfmon->status,
&caam_fops_u32_ro);
@@ -789,51 +805,138 @@ static int caam_probe(struct platform_device *pdev)
ctrlpriv->ctl_kek_wrap.data = (__force void *)&ctrlpriv->ctrl->kek[0];
ctrlpriv->ctl_kek_wrap.size = KEK_KEY_SIZE * sizeof(u32);
ctrlpriv->ctl_kek = debugfs_create_blob("kek",
- S_IRUSR |
- S_IRGRP | S_IROTH,
+ perm,
ctrlpriv->ctl,
&ctrlpriv->ctl_kek_wrap);
ctrlpriv->ctl_tkek_wrap.data = (__force void *)&ctrlpriv->ctrl->tkek[0];
ctrlpriv->ctl_tkek_wrap.size = KEK_KEY_SIZE * sizeof(u32);
ctrlpriv->ctl_tkek = debugfs_create_blob("tkek",
- S_IRUSR |
- S_IRGRP | S_IROTH,
+ perm,
ctrlpriv->ctl,
&ctrlpriv->ctl_tkek_wrap);
ctrlpriv->ctl_tdsk_wrap.data = (__force void *)&ctrlpriv->ctrl->tdsk[0];
ctrlpriv->ctl_tdsk_wrap.size = KEK_KEY_SIZE * sizeof(u32);
ctrlpriv->ctl_tdsk = debugfs_create_blob("tdsk",
- S_IRUSR |
- S_IRGRP | S_IROTH,
+ perm,
ctrlpriv->ctl,
&ctrlpriv->ctl_tdsk_wrap);
#endif
+}
+
+static const struct of_device_id caam_match[] = {
+ {
+ .compatible = "fsl,sec-v4.0",
+ },
+ {
+ .compatible = "fsl,sec4.0",
+ },
+ {},
+};
+MODULE_DEVICE_TABLE(of, caam_match);
+
+#ifdef CONFIG_PM_SLEEP
+
+/*
+ * Indicate if the internal state of the CAAM is lost during PM
+ */
+static int caam_off_during_pm(void)
+{
+ if (IS_ENABLED(CONFIG_ARM64))
+ return 1;
+
+ if (of_machine_is_compatible("fsl,imx6sx") ||
+ of_machine_is_compatible("fsl,imx6ul") ||
+ of_machine_is_compatible("fsl,imx7ulp") ||
+ of_machine_is_compatible("fsl,imx7d") ||
+ of_machine_is_compatible("fsl,imx7s"))
+ return 1;
+
return 0;
+}
-caam_remove:
- caam_remove(pdev);
- return ret;
+static void caam_state_save(struct device *dev)
+{
+ int idx;
+ struct caam_drv_private *ctrlpriv = dev_get_drvdata(dev);
+ struct caam_ctl_state *state = &ctrlpriv->state;
+ struct caam_ctrl *ctrl = ctrlpriv->ctrl;
+
+ /* Save SCFGR */
+ state->scfgr = rd_reg32(&ctrl->scfgr);
+
+ /* Save DECO mid */
+ state->deco_mid[0].liodn_ms = rd_reg32(&ctrl->deco_mid[0].liodn_ms);
+ state->deco_mid[0].liodn_ls = rd_reg32(&ctrl->deco_mid[0].liodn_ls);
+
+ /* Save the MID for JR assigned to linux */
+ for (idx = 0; idx < JOBR_MAX_COUNT; idx++)
+ if (ctrlpriv->jr[idx]) {
+ state->jr_mid[idx].liodn_ms =
+ rd_reg32(&ctrl->jr_mid[idx].liodn_ms);
+ state->jr_mid[idx].liodn_ls =
+ rd_reg32(&ctrl->jr_mid[idx].liodn_ls);
+ }
+}
-iounmap_ctrl:
- iounmap(ctrl);
-disable_caam_emi_slow:
- if (ctrlpriv->caam_emi_slow)
- clk_disable_unprepare(ctrlpriv->caam_emi_slow);
-disable_caam_aclk:
- clk_disable_unprepare(ctrlpriv->caam_aclk);
-disable_caam_mem:
- clk_disable_unprepare(ctrlpriv->caam_mem);
-disable_caam_ipg:
- clk_disable_unprepare(ctrlpriv->caam_ipg);
- return ret;
+static void caam_state_restore(const struct device *dev)
+{
+ int idx;
+ const struct caam_drv_private *ctrlpriv = dev_get_drvdata(dev);
+ const struct caam_ctl_state *state = &ctrlpriv->state;
+ struct caam_ctrl *ctrl = ctrlpriv->ctrl;
+
+ /* Restore SCFGR */
+ wr_reg32(&ctrl->scfgr, state->scfgr);
+
+ /* Restore DECO mid */
+ wr_reg32(&ctrl->deco_mid[0].liodn_ms, state->deco_mid[0].liodn_ms);
+ wr_reg32(&ctrl->deco_mid[0].liodn_ls, state->deco_mid[0].liodn_ls);
+
+ /* Restore the MID for JR assigned to linux */
+ for (idx = 0; idx < JOBR_MAX_COUNT; idx++)
+ if (ctrlpriv->jr[idx]) {
+ wr_reg32(&ctrl->jr_mid[idx].liodn_ms,
+ state->jr_mid[idx].liodn_ms);
+ wr_reg32(&ctrl->jr_mid[idx].liodn_ls,
+ state->jr_mid[idx].liodn_ls);
+ }
+}
+
+static int caam_ctrl_suspend(struct device *dev)
+{
+ const struct caam_drv_private *ctrlpriv = dev_get_drvdata(dev);
+
+ if (ctrlpriv->caam_off_during_pm && ctrlpriv->has_access_p0)
+ caam_state_save(dev);
+
+ return 0;
}
+static int caam_ctrl_resume(struct device *dev)
+{
+ struct caam_drv_private *ctrlpriv = dev_get_drvdata(dev);
+
+ if (ctrlpriv->caam_off_during_pm && ctrlpriv->has_access_p0) {
+ caam_state_restore(dev);
+ caam_ctrl_hw_configuration(ctrlpriv);
+ }
+
+ return 0;
+}
+
+SIMPLE_DEV_PM_OPS(caam_ctrl_pm_ops, caam_ctrl_suspend, caam_ctrl_resume);
+
+#endif /* CONFIG_PM_SLEEP */
+
static struct platform_driver caam_driver = {
.driver = {
.name = "caam",
.of_match_table = caam_match,
+#ifdef CONFIG_PM_SLEEP
+ .pm = &caam_ctrl_pm_ops,
+#endif
},
.probe = caam_probe,
.remove = caam_remove,
diff --git a/drivers/crypto/caam/ctrl.h b/drivers/crypto/caam/ctrl.h
index be693a2cc25e..c0a7b89e81af 100644
--- a/drivers/crypto/caam/ctrl.h
+++ b/drivers/crypto/caam/ctrl.h
@@ -2,14 +2,13 @@
/*
* CAAM control-plane driver backend public-level include definitions
*
- * Copyright 2012 Freescale Semiconductor, Inc.
+ * Copyright (C) 2015 Freescale Semiconductor, Inc.
*/
#ifndef CTRL_H
#define CTRL_H
/* Prototypes for backend-level services exposed to APIs */
-int caam_get_era(void);
extern bool caam_dpaa2;
diff --git a/drivers/crypto/caam/desc.h b/drivers/crypto/caam/desc.h
index 6633fbb80e74..9dc79b06c0e4 100644
--- a/drivers/crypto/caam/desc.h
+++ b/drivers/crypto/caam/desc.h
@@ -3,7 +3,7 @@
* CAAM descriptor composition header
* Definitions to support CAAM descriptor instruction generation
*
- * Copyright 2008-2011 Freescale Semiconductor, Inc.
+ * Copyright (C) 2008-2015 Freescale Semiconductor, Inc.
*/
#ifndef DESC_H
@@ -395,6 +395,10 @@
#define FIFOST_TYPE_PKHA_N (0x08 << FIFOST_TYPE_SHIFT)
#define FIFOST_TYPE_PKHA_A (0x0c << FIFOST_TYPE_SHIFT)
#define FIFOST_TYPE_PKHA_B (0x0d << FIFOST_TYPE_SHIFT)
+#define FIFOST_TYPE_AF_SBOX_CCM_JKEK (0x10 << FIFOST_TYPE_SHIFT)
+#define FIFOST_TYPE_AF_SBOX_CCM_TKEK (0x11 << FIFOST_TYPE_SHIFT)
+#define FIFOST_TYPE_KEY_CCM_JKEK (0x14 << FIFOST_TYPE_SHIFT)
+#define FIFOST_TYPE_KEY_CCM_TKEK (0x15 << FIFOST_TYPE_SHIFT)
#define FIFOST_TYPE_AF_SBOX_JKEK (0x20 << FIFOST_TYPE_SHIFT)
#define FIFOST_TYPE_AF_SBOX_TKEK (0x21 << FIFOST_TYPE_SHIFT)
#define FIFOST_TYPE_PKHA_E_JKEK (0x22 << FIFOST_TYPE_SHIFT)
@@ -1099,6 +1103,23 @@
#define OP_PCL_PKPROT_ECC 0x0002
#define OP_PCL_PKPROT_F2M 0x0001
+/* Blob protocol protinfo bits */
+#define OP_PCL_BLOB_TK 0x0200
+#define OP_PCL_BLOB_EKT 0x0100
+
+#define OP_PCL_BLOB_K2KR_MEM 0x0000
+#define OP_PCL_BLOB_K2KR_C1KR 0x0010
+#define OP_PCL_BLOB_K2KR_C2KR 0x0030
+#define OP_PCL_BLOB_K2KR_AFHAS 0x0050
+#define OP_PCL_BLOB_K2KR_C2KR_SPLIT 0x0070
+
+#define OP_PCL_BLOB_PTXT_SECMEM 0x0008
+#define OP_PCL_BLOB_BLACK 0x0004
+
+#define OP_PCL_BLOB_FMT_NORMAL 0x0000
+#define OP_PCL_BLOB_FMT_MSTR 0x0002
+#define OP_PCL_BLOB_FMT_TEST 0x0003
+
/* For non-protocol/alg-only op commands */
#define OP_ALG_TYPE_SHIFT 24
#define OP_ALG_TYPE_MASK (0x7 << OP_ALG_TYPE_SHIFT)
@@ -1624,4 +1645,12 @@
/* Frame Descriptor Command for Replacement Job Descriptor */
#define FD_CMD_REPLACE_JOB_DESC 0x20000000
+#define ARC4_BLOCK_SIZE 1
+#define ARC4_MAX_KEY_SIZE 256
+#define ARC4_MIN_KEY_SIZE 1
+
+#define XCBC_MAC_DIGEST_SIZE 16
+#define XCBC_MAC_BLOCK_WORDS 16
+
+
#endif /* DESC_H */
diff --git a/drivers/crypto/caam/desc_constr.h b/drivers/crypto/caam/desc_constr.h
index ba1ca0806f0a..6354a51056c9 100644
--- a/drivers/crypto/caam/desc_constr.h
+++ b/drivers/crypto/caam/desc_constr.h
@@ -2,7 +2,8 @@
/*
* caam descriptor construction helper functions
*
- * Copyright 2008-2012 Freescale Semiconductor, Inc.
+ * Copyright 2008-2016 Freescale Semiconductor, Inc.
+ * Copyright 2017-2018 NXP
*/
#ifndef DESC_CONSTR_H
@@ -13,7 +14,7 @@
#define IMMEDIATE (1 << 23)
#define CAAM_CMD_SZ sizeof(u32)
-#define CAAM_PTR_SZ sizeof(dma_addr_t)
+#define CAAM_PTR_SZ sizeof(caam_dma_addr_t)
#define CAAM_DESC_BYTES_MAX (CAAM_CMD_SZ * MAX_CAAM_DESCSIZE)
#define DESC_JOB_IO_LEN (CAAM_CMD_SZ * 5 + CAAM_PTR_SZ * 3)
@@ -90,9 +91,9 @@ static inline void init_job_desc_pdb(u32 * const desc, u32 options,
init_job_desc(desc, (((pdb_len + 1) << HDR_START_IDX_SHIFT)) | options);
}
-static inline void append_ptr(u32 * const desc, dma_addr_t ptr)
+static inline void append_ptr(u32 * const desc, caam_dma_addr_t ptr)
{
- dma_addr_t *offset = (dma_addr_t *)desc_end(desc);
+ caam_dma_addr_t *offset = (caam_dma_addr_t *)desc_end(desc);
*offset = cpu_to_caam_dma(ptr);
@@ -100,7 +101,7 @@ static inline void append_ptr(u32 * const desc, dma_addr_t ptr)
CAAM_PTR_SZ / CAAM_CMD_SZ);
}
-static inline void init_job_desc_shared(u32 * const desc, dma_addr_t ptr,
+static inline void init_job_desc_shared(u32 * const desc, caam_dma_addr_t ptr,
int len, u32 options)
{
PRINT_POS;
@@ -155,15 +156,15 @@ static inline u32 *write_cmd(u32 * const desc, u32 command)
return desc + 1;
}
-static inline void append_cmd_ptr(u32 * const desc, dma_addr_t ptr, int len,
- u32 command)
+static inline void append_cmd_ptr(u32 * const desc, caam_dma_addr_t ptr,
+ int len, u32 command)
{
append_cmd(desc, command | len);
append_ptr(desc, ptr);
}
/* Write length after pointer, rather than inside command */
-static inline void append_cmd_ptr_extlen(u32 * const desc, dma_addr_t ptr,
+static inline void append_cmd_ptr_extlen(u32 * const desc, caam_dma_addr_t ptr,
unsigned int len, u32 command)
{
append_cmd(desc, command);
@@ -227,8 +228,8 @@ APPEND_CMD_LEN(seq_fifo_load, SEQ_FIFO_LOAD)
APPEND_CMD_LEN(seq_fifo_store, SEQ_FIFO_STORE)
#define APPEND_CMD_PTR(cmd, op) \
-static inline void append_##cmd(u32 * const desc, dma_addr_t ptr, \
- unsigned int len, u32 options) \
+static inline void append_##cmd(u32 * const desc, caam_dma_addr_t ptr, \
+ unsigned int len, u32 options) \
{ \
PRINT_POS; \
append_cmd_ptr(desc, ptr, len, CMD_##op | options); \
@@ -238,7 +239,7 @@ APPEND_CMD_PTR(load, LOAD)
APPEND_CMD_PTR(fifo_load, FIFO_LOAD)
APPEND_CMD_PTR(fifo_store, FIFO_STORE)
-static inline void append_store(u32 * const desc, dma_addr_t ptr,
+static inline void append_store(u32 * const desc, caam_dma_addr_t ptr,
unsigned int len, u32 options)
{
u32 cmd_src;
@@ -257,9 +258,9 @@ static inline void append_store(u32 * const desc, dma_addr_t ptr,
#define APPEND_SEQ_PTR_INTLEN(cmd, op) \
static inline void append_seq_##cmd##_ptr_intlen(u32 * const desc, \
- dma_addr_t ptr, \
- unsigned int len, \
- u32 options) \
+ caam_dma_addr_t ptr, \
+ unsigned int len, \
+ u32 options) \
{ \
PRINT_POS; \
if (options & (SQIN_RTO | SQIN_PRE)) \
@@ -281,8 +282,9 @@ APPEND_CMD_PTR_TO_IMM(load, LOAD);
APPEND_CMD_PTR_TO_IMM(fifo_load, FIFO_LOAD);
#define APPEND_CMD_PTR_EXTLEN(cmd, op) \
-static inline void append_##cmd##_extlen(u32 * const desc, dma_addr_t ptr, \
- unsigned int len, u32 options) \
+static inline void append_##cmd##_extlen(u32 * const desc, \
+ caam_dma_addr_t ptr, \
+ unsigned int len, u32 options) \
{ \
PRINT_POS; \
append_cmd_ptr_extlen(desc, ptr, len, CMD_##op | SQIN_EXT | options); \
@@ -295,7 +297,7 @@ APPEND_CMD_PTR_EXTLEN(seq_out_ptr, SEQ_OUT_PTR)
* the size of its type
*/
#define APPEND_CMD_PTR_LEN(cmd, op, type) \
-static inline void append_##cmd(u32 * const desc, dma_addr_t ptr, \
+static inline void append_##cmd(u32 * const desc, caam_dma_addr_t ptr, \
type len, u32 options) \
{ \
PRINT_POS; \
@@ -445,16 +447,20 @@ do { \
* is true, dma (bus) address if key_inline is false.
* @key_inline: true - key can be inlined in the descriptor; false - key is
* referenced by the descriptor
+ * @key_real_len: Size of the key to be loaded by the CAAM
+ * @key_cmd_opt: Optional parameters for KEY command
*/
struct alginfo {
u32 algtype;
- unsigned int keylen;
- unsigned int keylen_pad;
+ u32 keylen;
+ u32 keylen_pad;
union {
- dma_addr_t key_dma;
+ caam_dma_addr_t key_dma;
void *key_virt;
};
bool key_inline;
+ u32 key_real_len;
+ u32 key_cmd_opt;
};
/**
diff --git a/drivers/crypto/caam/error.c b/drivers/crypto/caam/error.c
index 8da88beb1abb..8c37a3c278e1 100644
--- a/drivers/crypto/caam/error.c
+++ b/drivers/crypto/caam/error.c
@@ -156,6 +156,20 @@ static const char * const rng_err_id_list[] = {
"Secure key generation",
};
+#define SPRINTFCAT(str, format, param, max_alloc) \
+{ \
+ char *tmp; \
+ \
+ tmp = kmalloc(sizeof(format) + max_alloc, GFP_ATOMIC); \
+ if (likely(tmp)) { \
+ sprintf(tmp, format, param); \
+ strcat(str, tmp); \
+ kfree(tmp); \
+ } else { \
+ strcat(str, "kmalloc failure in SPRINTFCAT"); \
+ } \
+}
+
static void report_ccb_status(struct device *jrdev, const u32 status,
const char *error)
{
diff --git a/drivers/crypto/caam/inst_rng.c b/drivers/crypto/caam/inst_rng.c
new file mode 100644
index 000000000000..2cdbef347e23
--- /dev/null
+++ b/drivers/crypto/caam/inst_rng.c
@@ -0,0 +1,377 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * CAAM RNG instantiation driver backend
+ *
+ * Copyright 2017-2019 NXP
+ */
+
+#include <linux/device.h>
+#include <linux/of_address.h>
+#include <linux/wait.h>
+#include "compat.h"
+#include "regs.h"
+#include "intern.h"
+#include "jr.h"
+#include "desc_constr.h"
+#include "error.h"
+#include "ctrl.h"
+#include "inst_rng.h"
+
+static DECLARE_WAIT_QUEUE_HEAD(wq_desc);
+static int desc_completed;
+static int desc_status;
+
+/*
+ * Descriptor to instantiate RNG State Handle 0 in normal mode and
+ * load the JDKEK, TDKEK and TDSK registers
+ */
+static void build_instantiation_desc(u32 *desc, int handle, int do_sk)
+{
+ u32 *jump_cmd, op_flags;
+
+ init_job_desc(desc, 0);
+
+ op_flags = OP_TYPE_CLASS1_ALG | OP_ALG_ALGSEL_RNG |
+ (handle << OP_ALG_AAI_SHIFT) | OP_ALG_AS_INIT;
+
+ /* INIT RNG in non-test mode */
+ append_operation(desc, op_flags);
+
+ if (!handle && do_sk) {
+ /*
+ * For SH0, Secure Keys must be generated as well
+ */
+
+ /* wait for done */
+ jump_cmd = append_jump(desc, JUMP_CLASS_CLASS1);
+ set_jump_tgt_here(desc, jump_cmd);
+
+ /*
+ * load 1 to clear written reg:
+ * resets the done interrupt and returns the RNG to idle.
+ */
+ append_load_imm_u32(desc, 1, LDST_SRCDST_WORD_CLRW);
+
+ /* Initialize State Handle */
+ append_operation(desc, OP_TYPE_CLASS1_ALG | OP_ALG_ALGSEL_RNG |
+ OP_ALG_AAI_RNG4_SK);
+ }
+
+ append_jump(desc, JUMP_CLASS_CLASS1 | JUMP_TYPE_HALT);
+}
+
+/* Descriptor for deinstantiation of State Handle 0 of the RNG block. */
+static void build_deinstantiation_desc(u32 *desc, int handle)
+{
+ init_job_desc(desc, 0);
+
+ /* Uninstantiate State Handle 0 */
+ append_operation(desc, OP_TYPE_CLASS1_ALG | OP_ALG_ALGSEL_RNG |
+ (handle << OP_ALG_AAI_SHIFT) | OP_ALG_AS_INITFINAL);
+
+ append_jump(desc, JUMP_CLASS_CLASS1 | JUMP_TYPE_HALT);
+}
+
+void cbk_jr_rng_inst(struct device *jrdev, u32 *desc, u32 status, void *areq)
+{
+ if ((status & JRSTA_SSRC_JUMP_HALT_CC) == JRSTA_SSRC_JUMP_HALT_CC) {
+ dev_info(jrdev, "Instantiated RNG4 SH%d.\n", *((int *)areq));
+ desc_status = 0;
+ } else {
+ desc_status = -EAGAIN;
+ }
+ desc_completed = 1;
+ wake_up(&wq_desc);
+}
+
+/*
+ * run_descriptor_jr - runs a descriptor on first JR
+ * @status - descriptor status, after being run
+ *
+ * Return: - 0 if no error occurred
+ * - -ENODEV if the DECO couldn't be acquired
+ * - -EAGAIN if an error occurred while executing the descriptor
+ */
+static int run_descriptor_jr(u32 *desc, int sh_idx)
+{
+ struct device *jrdev;
+ int ret;
+
+ jrdev = caam_jr_alloc();
+ if (IS_ERR(jrdev)) {
+ pr_err("Job Ring Device allocation for transform failed\n");
+ return -ENODEV;
+ }
+ ret = caam_jr_enqueue(jrdev, desc, cbk_jr_rng_inst, &sh_idx);
+ if (ret) {
+ dev_err(jrdev, "caam_jr_enqueue() failed\n");
+ return ret;
+ }
+ /* wait for job descriptor completion */
+ wait_event(wq_desc, desc_completed != 0);
+ desc_completed = 0;
+ caam_jr_free(jrdev);
+ return desc_status;
+}
+
+/*
+ * instantiate_rng - builds and executes a descriptor on JR0,
+ * which initializes the RNG block.
+ * @state_handle_mask - bitmask containing the instantiation status
+ * for the RNG4 state handles which exist in
+ * the RNG4 block: 1 if it's been instantiated
+ * by an external entry, 0 otherwise.
+ * @gen_sk - generate data to be loaded into the JDKEK, TDKEK and TDSK;
+ * Caution: this can be done only once; if the keys need to be
+ * regenerated, a POR is required
+ *
+ * Return: - 0 if no error occurred
+ * - -ENOMEM if there isn't enough memory to allocate the descriptor
+ * - -ENODEV if DECO0 couldn't be acquired
+ * - -EAGAIN if an error occurred when executing the descriptor
+ * f.i. there was a RNG hardware error due to not "good enough"
+ * entropy being acquired.
+ */
+static int instantiate_rng(int state_handle_mask, int gen_sk)
+{
+ u32 *desc;
+ int sh_idx, ret = 0;
+
+ desc = kmalloc(CAAM_CMD_SZ * 7, GFP_KERNEL);
+ if (!desc)
+ return -ENOMEM;
+
+ for (sh_idx = 0; sh_idx < RNG4_MAX_HANDLES; sh_idx++) {
+ /*
+ * If the corresponding bit is set, this state handle
+ * was initialized by somebody else, so it's left alone.
+ */
+ if ((1 << sh_idx) & state_handle_mask)
+ continue;
+
+ /* Create the descriptor for instantiating RNG State Handle */
+ build_instantiation_desc(desc, sh_idx, gen_sk);
+
+ /* Try to run it through JR */
+ ret = run_descriptor_jr(desc, sh_idx);
+ if (ret)
+ pr_debug("Failed to run desc RNG4 SH%d status (0x%x)\n",
+ sh_idx, ret);
+ /* Clear the contents before recreating the descriptor */
+ memset(desc, 0x00, CAAM_CMD_SZ * 7);
+ }
+
+ kfree(desc);
+
+ return ret;
+}
+
+/*
+ * deinstantiate_rng - builds and executes a descriptor on JR0,
+ * which deinitializes the RNG block.
+ * @state_handle_mask - bitmask containing the instantiation status
+ * for the RNG4 state handles which exist in
+ * the RNG4 block: 1 if it's been instantiated
+ *
+ * Return: - 0 if no error occurred
+ * - -ENOMEM if there isn't enough memory to allocate the descriptor
+ * - -ENODEV if DECO0 couldn't be acquired
+ * - -EAGAIN if an error occurred when executing the descriptor
+ */
+int deinstantiate_rng(int state_handle_mask)
+{
+ u32 *desc;
+ int sh_idx, ret = 0;
+
+ desc = kmalloc(CAAM_CMD_SZ * 3, GFP_KERNEL);
+ if (!desc)
+ return -ENOMEM;
+
+ for (sh_idx = 0; sh_idx < RNG4_MAX_HANDLES; sh_idx++) {
+ /*
+ * If the corresponding bit is set, then it means the state
+ * handle was initialized by us, and thus it needs to be
+ * deinitialized as well
+ */
+ if ((1 << sh_idx) & state_handle_mask) {
+ /*
+ * Create the descriptor for deinstantating this state
+ * handle
+ */
+ build_deinstantiation_desc(desc, sh_idx);
+
+ /* Try to run it through JR */
+ ret = run_descriptor_jr(desc, sh_idx);
+ if (ret)
+ pr_debug("Failed to run desc to deinstantiate RNG4 SH%d\n",
+ sh_idx);
+ }
+ }
+
+ kfree(desc);
+
+ return ret;
+}
+
+/*
+ * kick_trng - sets the various parameters for enabling the initialization
+ * of the RNG4 block in CAAM
+ * @ctrldev - pointer to the device
+ * @ent_delay - Defines the length (in system clocks) of each entropy sample.
+ */
+static void kick_trng(struct device *ctrldev, int ent_delay)
+{
+ struct caam_drv_private *ctrlpriv = dev_get_drvdata(ctrldev);
+ struct caam_ctrl __iomem *ctrl;
+ struct rng4tst __iomem *r4tst;
+ u32 val;
+
+ ctrl = (struct caam_ctrl __iomem *)ctrlpriv->ctrl;
+ r4tst = &ctrl->r4tst[0];
+
+ /* put RNG4 into program mode */
+ /* Setting both RTMCTL:PRGM and RTMCTL:TRNG_ACC causes TRNG to
+ * properly invalidate the entropy in the entropy register and
+ * force re-generation.
+ */
+ clrsetbits_32(&r4tst->rtmctl, 0, RTMCTL_PRGM | RTMCTL_ACC);
+
+ /*
+ * Performance-wise, it does not make sense to
+ * set the delay to a value that is lower
+ * than the last one that worked (i.e. the state handles
+ * were instantiated properly. Thus, instead of wasting
+ * time trying to set the values controlling the sample
+ * frequency, the function simply returns.
+ */
+ val = (rd_reg32(&r4tst->rtsdctl) & RTSDCTL_ENT_DLY_MASK)
+ >> RTSDCTL_ENT_DLY_SHIFT;
+ if (ent_delay <= val) {
+ /* put RNG4 into run mode */
+ clrsetbits_32(&r4tst->rtmctl, RTMCTL_PRGM | RTMCTL_ACC, 0);
+ return;
+ }
+
+ val = rd_reg32(&r4tst->rtsdctl);
+ val = (val & ~RTSDCTL_ENT_DLY_MASK) |
+ (ent_delay << RTSDCTL_ENT_DLY_SHIFT);
+ wr_reg32(&r4tst->rtsdctl, val);
+ /* min. freq. count, equal to 1/4 of the entropy sample length */
+ wr_reg32(&r4tst->rtfrqmin, ent_delay >> 2);
+ /* max. freq. count, equal to 16 times the entropy sample length */
+ wr_reg32(&r4tst->rtfrqmax, ent_delay << 4);
+ /* read the control register */
+ val = rd_reg32(&r4tst->rtmctl);
+ /*
+ * select raw sampling in both entropy shifter
+ * and statistical checker
+ */
+ clrsetbits_32(&val, 0, RTMCTL_SAMP_MODE_RAW_ES_SC);
+ /* put RNG4 into run mode */
+ clrsetbits_32(&val, RTMCTL_PRGM | RTMCTL_ACC, 0);
+ /* write back the control register */
+ wr_reg32(&r4tst->rtmctl, val);
+}
+
+/*
+ * inst_rng_imx - RNG instantiation function for i.MX6/7/8m platforms
+ * @pdev - pointer to the device
+ */
+int inst_rng_imx(struct platform_device *pdev)
+{
+ struct device *ctrldev, *dev;
+ struct caam_drv_private *ctrlpriv;
+ struct caam_ctrl __iomem *ctrl;
+ int ret = 0, gen_sk, ent_delay = RTSDCTL_ENT_DLY_MIN;
+ u32 cha_vid_ls;
+
+ dev = &pdev->dev;
+ ctrldev = pdev->dev.parent;
+ ctrlpriv = dev_get_drvdata(ctrldev);
+ ctrl = (struct caam_ctrl __iomem *)ctrlpriv->ctrl;
+
+ cha_vid_ls = rd_reg32(&ctrl->perfmon.cha_id_ls);
+
+ /*
+ * If SEC has RNG version >= 4 and RNG state handle has not been
+ * already instantiated, do RNG instantiation
+ * In case of DPAA 2.x, RNG is managed by MC firmware.
+ */
+ if (!caam_dpaa2 &&
+ (cha_vid_ls & CHA_ID_LS_RNG_MASK) >> CHA_ID_LS_RNG_SHIFT >= 4) {
+ ctrlpriv->rng4_sh_init =
+ rd_reg32(&ctrl->r4tst[0].rdsta);
+ /*
+ * If the secure keys (TDKEK, JDKEK, TDSK), were already
+ * generated, signal this to the function that is instantiating
+ * the state handles. An error would occur if RNG4 attempts
+ * to regenerate these keys before the next POR.
+ */
+ gen_sk = ctrlpriv->rng4_sh_init & RDSTA_SKVN ? 0 : 1;
+ ctrlpriv->rng4_sh_init &= RDSTA_IFMASK;
+ do {
+ int inst_handles =
+ rd_reg32(&ctrl->r4tst[0].rdsta) &
+ RDSTA_IFMASK;
+ /*
+ * If either SH were instantiated by somebody else
+ * (e.g. u-boot) then it is assumed that the entropy
+ * parameters are properly set and thus the function
+ * setting these (kick_trng(...)) is skipped.
+ * Also, if a handle was instantiated, do not change
+ * the TRNG parameters.
+ */
+ if (!(ctrlpriv->rng4_sh_init || inst_handles)) {
+ dev_info(dev,
+ "Entropy delay = %u\n",
+ ent_delay);
+ kick_trng(ctrldev, ent_delay);
+ ent_delay += ENT_DELAY_STEP;
+ }
+ /*
+ * if instantiate_rng(...) fails, the loop will rerun
+ * and the kick_trng(...) function will modfiy the
+ * upper and lower limits of the entropy sampling
+ * interval, leading to a sucessful initialization of
+ * the RNG.
+ */
+ ret = instantiate_rng(inst_handles, gen_sk);
+ if (ret == -EAGAIN)
+ /*
+ * if here, the loop will rerun,
+ * so don't hog the CPU
+ */
+ cpu_relax();
+ } while ((ret == -EAGAIN) && (ent_delay < RTSDCTL_ENT_DLY_MAX));
+ if (ret) {
+ dev_err(dev, "failed to instantiate RNG");
+ return ret;
+ }
+ /*
+ * Set handles init'ed by this module as the complement of the
+ * already initialized ones
+ */
+ ctrlpriv->rng4_sh_init = ~ctrlpriv->rng4_sh_init & RDSTA_IFMASK;
+ /* Enable RDB bit so that RNG works faster */
+ clrsetbits_32(&ctrl->scfgr, 0, SCFGR_RDBENABLE);
+ }
+ return ret;
+}
+
+/*
+ * deinst_rng - RNG de-instantiation function
+ * @pdev - pointer to the device
+ */
+int deinst_rng(struct platform_device *pdev)
+{
+ struct device *ctrldev, *dev;
+ struct caam_drv_private *ctrlpriv;
+ int ret = 0;
+
+ dev = &pdev->dev;
+ ctrldev = pdev->dev.parent;
+ ctrlpriv = dev_get_drvdata(ctrldev);
+
+ ret = deinstantiate_rng(ctrlpriv->rng4_sh_init);
+ return ret;
+}
diff --git a/drivers/crypto/caam/inst_rng.h b/drivers/crypto/caam/inst_rng.h
new file mode 100644
index 000000000000..e0477262fe2a
--- /dev/null
+++ b/drivers/crypto/caam/inst_rng.h
@@ -0,0 +1,18 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * CAAM Private/internal definitions between modules
+ *
+ * Copyright 2017-2018 NXP
+ */
+
+#ifndef INST_RNG_H
+#define INST_RNG_H
+
+#include <linux/platform_device.h>
+
+#define ENT_DELAY_STEP (400)
+int inst_rng_imx(struct platform_device *pdev);
+
+int deinst_rng(struct platform_device *pdev);
+
+#endif /* INST_RNG_H */
diff --git a/drivers/crypto/caam/intern.h b/drivers/crypto/caam/intern.h
index 91f1107276e5..debdb603ff0e 100644
--- a/drivers/crypto/caam/intern.h
+++ b/drivers/crypto/caam/intern.h
@@ -3,16 +3,21 @@
* CAAM/SEC 4.x driver backend
* Private/internal definitions between modules
*
- * Copyright 2008-2011 Freescale Semiconductor, Inc.
+ * Copyright 2008-2016 Freescale Semiconductor, Inc.
+ * Copyright 2017-2019 NXP
*
*/
#ifndef INTERN_H
#define INTERN_H
+#include "regs.h"
/* Currently comes from Kconfig param as a ^2 (driver-required) */
#define JOBR_DEPTH (1 << CONFIG_CRYPTO_DEV_FSL_CAAM_RINGSIZE)
+/* Job ring count */
+#define JOBR_MAX_COUNT 4
+
/* Kconfig params for interrupt coalescing if selected (else zero) */
#ifdef CONFIG_CRYPTO_DEV_FSL_CAAM_INTC
#define JOBR_INTC JRCFG_ICEN
@@ -32,10 +37,22 @@ struct caam_jrentry_info {
void (*callbk)(struct device *dev, u32 *desc, u32 status, void *arg);
void *cbkarg; /* Argument per ring entry */
u32 *desc_addr_virt; /* Stored virt addr for postprocessing */
- dma_addr_t desc_addr_dma; /* Stored bus addr for done matching */
+ caam_dma_addr_t desc_addr_dma; /* Stored bus addr for done matching */
u32 desc_size; /* Stored size for postprocessing, header derived */
};
+#ifdef CONFIG_PM_SLEEP
+struct caam_jr_state {
+ dma_addr_t inpbusaddr;
+ dma_addr_t outbusaddr;
+};
+#endif
+
+struct caam_jr_dequeue_params {
+ struct device *dev;
+ int enable_itr;
+};
+
/* Private sub-storage for a single JobR */
struct caam_drv_private_jr {
struct list_head list_node; /* Job Ring device list */
@@ -43,6 +60,7 @@ struct caam_drv_private_jr {
int ridx;
struct caam_job_ring __iomem *rregs; /* JobR's register space */
struct tasklet_struct irqtask;
+ struct caam_jr_dequeue_params tasklet_params;
int irq; /* One per queue */
/* Number of scatterlist crypt transforms active on the JobR */
@@ -54,13 +72,25 @@ struct caam_drv_private_jr {
spinlock_t inplock ____cacheline_aligned; /* Input ring index lock */
int inp_ring_write_index; /* Input index "tail" */
int head; /* entinfo (s/w ring) head index */
- dma_addr_t *inpring; /* Base of input ring, alloc DMA-safe */
+ caam_dma_addr_t *inpring; /* Base of input ring, alloc DMA-safe */
spinlock_t outlock ____cacheline_aligned; /* Output ring index lock */
int out_ring_read_index; /* Output index "tail" */
int tail; /* entinfo (s/w ring) tail index */
struct jr_outentry *outring; /* Base of output ring, DMA-safe */
+
+#ifdef CONFIG_PM_SLEEP
+ struct caam_jr_state state; /* State of the JR during PM */
+#endif
};
+#ifdef CONFIG_PM_SLEEP
+struct caam_ctl_state {
+ u32 scfgr;
+ struct masterid deco_mid[1];
+ struct masterid jr_mid[4];
+};
+#endif
+
/*
* Driver-private storage for a single CAAM block instance
*/
@@ -68,13 +98,26 @@ struct caam_drv_private {
#ifdef CONFIG_CAAM_QI
struct device *qidev;
#endif
+ struct device *dev;
+ struct platform_device *pdev;
+ struct device *smdev;
+
+ /*
+ * ERA of the CAAM block,
+ * -ENOTSUPP if no era version was supplied or detected.
+ */
+#define IMX_ERR005766_ERA 4 /* ERA affected by i.mx AXI errata */
+ int era;
/* Physical-presence section */
struct caam_ctrl __iomem *ctrl; /* controller region */
struct caam_deco __iomem *deco; /* DECO/CCB views */
struct caam_assurance __iomem *assure;
struct caam_queue_if __iomem *qi; /* QI control region */
- struct caam_job_ring __iomem *jr[4]; /* JobR's register space */
+ struct caam_job_ring __iomem *jr[JOBR_MAX_COUNT]; /* JRs registers */
+ dma_addr_t __iomem *sm_base; /* Secure memory storage base */
+ phys_addr_t sm_phy; /* Secure memory storage physical */
+ u32 sm_size;
/*
* Detected geometry block. Filled in from device tree if powerpc,
@@ -82,7 +125,6 @@ struct caam_drv_private {
*/
u8 total_jobrs; /* Total Job Rings in device */
u8 qi_present; /* Nonzero if QI present in device */
- int secvio_irq; /* Security violation interrupt number */
int virt_en; /* Virtualization enabled in CAAM */
#define RNG4_MAX_HANDLES 2
@@ -96,6 +138,8 @@ struct caam_drv_private {
struct clk *caam_aclk;
struct clk *caam_emi_slow;
+ bool has_seco;
+ u32 first_jr_index;
/*
* debugfs entries for developer view into driver/device
* variables at runtime.
@@ -106,6 +150,14 @@ struct caam_drv_private {
struct debugfs_blob_wrapper ctl_kek_wrap, ctl_tkek_wrap, ctl_tdsk_wrap;
struct dentry *ctl_kek, *ctl_tkek, *ctl_tdsk;
#endif
+
+ int has_optee;
+ int has_access_p0; /* If driver has acces to page 0 of the CAAM */
+
+#ifdef CONFIG_PM_SLEEP
+ int caam_off_during_pm; /* If the CAAM is reset after suspend */
+ struct caam_ctl_state state; /* State of the CTL during PM */
+#endif
};
void caam_jr_algapi_init(struct device *dev);
diff --git a/drivers/crypto/caam/jr.c b/drivers/crypto/caam/jr.c
index 7fa1be184553..88ec227b67a9 100644
--- a/drivers/crypto/caam/jr.c
+++ b/drivers/crypto/caam/jr.c
@@ -2,7 +2,8 @@
* CAAM/SEC 4.x transport/backend driver
* JobR backend functionality
*
- * Copyright 2008-2012 Freescale Semiconductor, Inc.
+ * Copyright 2008-2016 Freescale Semiconductor, Inc.
+ * Copyright 2017-2019 NXP
*/
#include <linux/of_irq.h>
@@ -14,6 +15,7 @@
#include "jr.h"
#include "desc.h"
#include "intern.h"
+#include "inst_rng.h"
struct jr_driver_data {
/* List of Physical JobR's with the Driver */
@@ -23,42 +25,122 @@ struct jr_driver_data {
static struct jr_driver_data driver_data;
+static inline void mask_itr(struct device *dev)
+{
+ struct caam_drv_private_jr *jrp = dev_get_drvdata(dev);
+
+ clrsetbits_32(&jrp->rregs->rconfig_lo, 0, JRCFG_IMSK);
+}
+
+static inline void unmask_itr(struct device *dev)
+{
+ struct caam_drv_private_jr *jrp = dev_get_drvdata(dev);
+
+ clrsetbits_32(&jrp->rregs->rconfig_lo, JRCFG_IMSK, 0);
+}
+
+/*
+ * Put the CAAM in quiesce, ie stop
+ *
+ * Must be called with itr disabled
+ */
+static int caam_jr_stop_processing(struct device *dev, u32 jrcr_bits)
+{
+ unsigned int timeout = 100000;
+ unsigned int halt_status;
+ struct caam_drv_private_jr *jrp = dev_get_drvdata(dev);
+
+ if (rd_reg32(&jrp->rregs->jrintstatus) & JRINT_ERR_HALT_MASK) {
+ dev_err(dev, "Not ready to quiesce\n");
+ return -EINVAL;
+ }
+
+ /* initiate quiesce */
+ wr_reg32(&jrp->rregs->jrcommand, jrcr_bits);
+
+ /* Wait for the quiesce completion or timeout run out */
+ do {
+ cpu_relax();
+ halt_status = rd_reg32(&jrp->rregs->jrintstatus) &
+ JRINT_ERR_HALT_MASK;
+ } while ((halt_status == JRINT_ERR_HALT_INPROGRESS) &&
+ --timeout);
+
+ halt_status = rd_reg32(&jrp->rregs->jrintstatus) & JRINT_ERR_HALT_MASK;
+
+ /* Check that the flush is complete */
+ if (halt_status != JRINT_ERR_HALT_COMPLETE) {
+ dev_err(dev, "failed to quiesce\n");
+ return -EIO;
+ }
+
+ return 0;
+}
+
+/*
+ * Flush the job ring, so the jobs running will be stopped, jobs queued will be
+ * invalidated and the CAAM will no longer fetch fron input ring.
+ *
+ * Must be called with itr disabled
+ */
+static int caam_jr_flush(struct device *dev)
+{
+ return caam_jr_stop_processing(dev, JRCR_RESET);
+}
+
+#ifdef CONFIG_PM_SLEEP
+
+/* The resume can be used after a park or a flush if CAAM has not been reset */
+static int caam_jr_restart_processing(struct device *dev)
+{
+ struct caam_drv_private_jr *jrp = dev_get_drvdata(dev);
+ u32 park_status = rd_reg32(&jrp->rregs->jrintstatus) &
+ JRINT_ERR_HALT_MASK;
+
+ /* Check that the flush/park is completed */
+ if (park_status != JRINT_ERR_HALT_COMPLETE)
+ return -1;
+
+ /* Resume processing of jobs */
+ wr_reg32(&jrp->rregs->jrintstatus, JRINT_ERR_HALT_COMPLETE);
+
+ return 0;
+}
+
+#endif /* CONFIG_PM_SLEEP */
+
static int caam_reset_hw_jr(struct device *dev)
{
+ int err = 0;
struct caam_drv_private_jr *jrp = dev_get_drvdata(dev);
unsigned int timeout = 100000;
+ unsigned int reset_status;
/*
* mask interrupts since we are going to poll
* for reset completion status
*/
- clrsetbits_32(&jrp->rregs->rconfig_lo, 0, JRCFG_IMSK);
+ mask_itr(dev);
- /* initiate flush (required prior to reset) */
- wr_reg32(&jrp->rregs->jrcommand, JRCR_RESET);
- while (((rd_reg32(&jrp->rregs->jrintstatus) & JRINT_ERR_HALT_MASK) ==
- JRINT_ERR_HALT_INPROGRESS) && --timeout)
- cpu_relax();
-
- if ((rd_reg32(&jrp->rregs->jrintstatus) & JRINT_ERR_HALT_MASK) !=
- JRINT_ERR_HALT_COMPLETE || timeout == 0) {
- dev_err(dev, "failed to flush job ring %d\n", jrp->ridx);
- return -EIO;
- }
+ err = caam_jr_flush(dev);
+ if (err)
+ return err;
/* initiate reset */
- timeout = 100000;
wr_reg32(&jrp->rregs->jrcommand, JRCR_RESET);
- while ((rd_reg32(&jrp->rregs->jrcommand) & JRCR_RESET) && --timeout)
+ do {
cpu_relax();
+ reset_status = rd_reg32(&jrp->rregs->jrcommand) & JRCR_RESET;
+ } while (reset_status && --timeout);
- if (timeout == 0) {
+ reset_status = rd_reg32(&jrp->rregs->jrcommand) & JRCR_RESET;
+ if (reset_status != 0) {
dev_err(dev, "failed to reset job ring %d\n", jrp->ridx);
return -EIO;
}
/* unmask interrupts */
- clrsetbits_32(&jrp->rregs->rconfig_lo, JRCFG_IMSK, 0);
+ unmask_itr(dev);
return 0;
}
@@ -101,6 +183,12 @@ static int caam_jr_remove(struct platform_device *pdev)
jrpriv = dev_get_drvdata(jrdev);
/*
+ * Deinstantiate RNG by first JR
+ */
+ if (jrpriv->ridx == 0)
+ deinst_rng(pdev);
+
+ /*
* Return EBUSY if job ring already allocated.
*/
if (atomic_read(&jrpriv->tfm_count)) {
@@ -148,7 +236,7 @@ static irqreturn_t caam_jr_interrupt(int irq, void *st_dev)
}
/* mask valid interrupts */
- clrsetbits_32(&jrp->rregs->rconfig_lo, 0, JRCFG_IMSK);
+ mask_itr(dev);
/* Have valid interrupt at this point, just ACK and trigger */
wr_reg32(&jrp->rregs->jrintstatus, irqstate);
@@ -161,10 +249,11 @@ static irqreturn_t caam_jr_interrupt(int irq, void *st_dev)
}
/* Deferred service handler, run as interrupt-fired tasklet */
-static void caam_jr_dequeue(unsigned long devarg)
+static void caam_jr_dequeue(unsigned long data)
{
int hw_idx, sw_idx, i, head, tail;
- struct device *dev = (struct device *)devarg;
+ struct caam_jr_dequeue_params *params = (void *)data;
+ struct device *dev = params->dev;
struct caam_drv_private_jr *jrp = dev_get_drvdata(dev);
void (*usercall)(struct device *dev, u32 *desc, u32 status, void *arg);
u32 *userdesc, userstatus;
@@ -238,7 +327,8 @@ static void caam_jr_dequeue(unsigned long devarg)
}
/* reenable / unmask IRQs */
- clrsetbits_32(&jrp->rregs->rconfig_lo, JRCFG_IMSK, 0);
+ if (params->enable_itr)
+ unmask_itr(dev);
}
/**
@@ -298,8 +388,7 @@ EXPORT_SYMBOL(caam_jr_free);
* caam_jr_enqueue() - Enqueue a job descriptor head. Returns 0 if OK,
* -EBUSY if the queue is full, -EIO if it cannot map the caller's
* descriptor.
- * @dev: device of the job ring to be used. This device should have
- * been assigned prior by caam_jr_register().
+ * @dev: device of the job ring to be used.
* @desc: points to a job descriptor that execute our request. All
* descriptors (and all referenced data) must be in a DMAable
* region, and all data references must be physical addresses
@@ -359,7 +448,6 @@ int caam_jr_enqueue(struct device *dev, u32 *desc,
head_entry->desc_addr_dma = desc_dma;
jrp->inpring[jrp->inp_ring_write_index] = cpu_to_caam_dma(desc_dma);
-
/*
* Guarantee that the descriptor's DMA address has been written to
* the next slot in the ring before the write index is updated, since
@@ -385,6 +473,30 @@ int caam_jr_enqueue(struct device *dev, u32 *desc,
}
EXPORT_SYMBOL(caam_jr_enqueue);
+static void caam_jr_init_hw(struct device *dev, dma_addr_t inpbusaddr,
+ dma_addr_t outbusaddr)
+{
+ struct caam_drv_private_jr *jrp = dev_get_drvdata(dev);
+
+ wr_reg64(&jrp->rregs->inpring_base, inpbusaddr);
+ wr_reg64(&jrp->rregs->outring_base, outbusaddr);
+ wr_reg32(&jrp->rregs->inpring_size, JOBR_DEPTH);
+ wr_reg32(&jrp->rregs->outring_size, JOBR_DEPTH);
+
+ /* Select interrupt coalescing parameters */
+ clrsetbits_32(&jrp->rregs->rconfig_lo, 0, JOBR_INTC |
+ (JOBR_INTC_COUNT_THLD << JRCFG_ICDCT_SHIFT) |
+ (JOBR_INTC_TIME_THLD << JRCFG_ICTT_SHIFT));
+}
+
+static void caam_jr_reset_index(struct caam_drv_private_jr *jrp)
+{
+ jrp->inp_ring_write_index = 0;
+ jrp->out_ring_read_index = 0;
+ jrp->head = 0;
+ jrp->tail = 0;
+}
+
/*
* Init JobR independent of platform property detection
*/
@@ -396,7 +508,14 @@ static int caam_jr_init(struct device *dev)
jrp = dev_get_drvdata(dev);
- tasklet_init(&jrp->irqtask, caam_jr_dequeue, (unsigned long)dev);
+ error = caam_reset_hw_jr(dev);
+ if (error)
+ goto out_kill_deq;
+
+ jrp->tasklet_params.dev = dev;
+ jrp->tasklet_params.enable_itr = 1;
+ tasklet_init(&jrp->irqtask, caam_jr_dequeue,
+ (unsigned long)&jrp->tasklet_params);
/* Connect job ring interrupt handler. */
error = request_irq(jrp->irq, caam_jr_interrupt, IRQF_SHARED,
@@ -407,10 +526,6 @@ static int caam_jr_init(struct device *dev)
goto out_kill_deq;
}
- error = caam_reset_hw_jr(dev);
- if (error)
- goto out_free_irq;
-
error = -ENOMEM;
jrp->inpring = dma_alloc_coherent(dev, sizeof(*jrp->inpring) *
JOBR_DEPTH, &inpbusaddr, GFP_KERNEL);
@@ -430,26 +545,15 @@ static int caam_jr_init(struct device *dev)
jrp->entinfo[i].desc_addr_dma = !0;
/* Setup rings */
- jrp->inp_ring_write_index = 0;
- jrp->out_ring_read_index = 0;
- jrp->head = 0;
- jrp->tail = 0;
-
- wr_reg64(&jrp->rregs->inpring_base, inpbusaddr);
- wr_reg64(&jrp->rregs->outring_base, outbusaddr);
- wr_reg32(&jrp->rregs->inpring_size, JOBR_DEPTH);
- wr_reg32(&jrp->rregs->outring_size, JOBR_DEPTH);
+ caam_jr_reset_index(jrp);
jrp->ringsize = JOBR_DEPTH;
+ caam_jr_init_hw(dev, inpbusaddr, outbusaddr);
+
spin_lock_init(&jrp->inplock);
spin_lock_init(&jrp->outlock);
- /* Select interrupt coalescing parameters */
- clrsetbits_32(&jrp->rregs->rconfig_lo, 0, JOBR_INTC |
- (JOBR_INTC_COUNT_THLD << JRCFG_ICDCT_SHIFT) |
- (JOBR_INTC_TIME_THLD << JRCFG_ICTT_SHIFT));
-
return 0;
out_free_outring:
@@ -466,6 +570,29 @@ out_kill_deq:
return error;
}
+static int caam_jr_instantiate_rng(struct device *jrdev)
+{
+ int error = 0;
+ struct caam_drv_private_jr *jrpriv;
+ struct caam_drv_private *ctrlpriv = dev_get_drvdata(jrdev->parent);
+
+ if (ctrlpriv->has_seco || ctrlpriv->has_optee) {
+ dev_dbg(jrdev, "RNG instantiated by secure component\n");
+ goto exit;
+ }
+
+ jrpriv = dev_get_drvdata(jrdev);
+
+ /*
+ * If this is the first available JR
+ * then try to instantiate RNG
+ */
+ if (jrpriv->ridx == 0)
+ error = inst_rng_imx(to_platform_device(jrdev));
+
+exit:
+ return error;
+}
/*
* Probe routine for each detected JobR subsystem.
@@ -481,10 +608,13 @@ static int caam_jr_probe(struct platform_device *pdev)
jrdev = &pdev->dev;
jrpriv = devm_kmalloc(jrdev, sizeof(*jrpriv), GFP_KERNEL);
- if (!jrpriv)
- return -ENOMEM;
+ if (!jrpriv) {
+ error = -ENOMEM;
+ goto exit;
+ }
dev_set_drvdata(jrdev, jrpriv);
+ jrpriv->dev = jrdev;
/* save ring identity relative to detection */
jrpriv->ridx = total_jobrs++;
@@ -495,12 +625,18 @@ static int caam_jr_probe(struct platform_device *pdev)
ctrl = of_iomap(nprop, 0);
if (!ctrl) {
dev_err(jrdev, "of_iomap() failed\n");
- return -ENOMEM;
+ error = -ENOMEM;
+ goto exit;
}
jrpriv->rregs = (struct caam_job_ring __iomem __force *)ctrl;
- if (sizeof(dma_addr_t) == sizeof(u64)) {
+ if (of_machine_is_compatible("fsl,imx8mm") ||
+ of_machine_is_compatible("fsl,imx8qm") ||
+ of_machine_is_compatible("fsl,imx8qxp") ||
+ of_machine_is_compatible("fsl,imx8mq")) {
+ error = dma_set_mask_and_coherent(jrdev, DMA_BIT_MASK(32));
+ } else if (sizeof(dma_addr_t) == sizeof(u64)) {
if (caam_dpaa2)
error = dma_set_mask_and_coherent(jrdev,
DMA_BIT_MASK(49));
@@ -517,31 +653,164 @@ static int caam_jr_probe(struct platform_device *pdev)
if (error) {
dev_err(jrdev, "dma_set_mask_and_coherent failed (%d)\n",
error);
- iounmap(ctrl);
- return error;
+ goto unmap_ctrl;
}
/* Identify the interrupt */
jrpriv->irq = irq_of_parse_and_map(nprop, 0);
+ if (jrpriv->irq <= 0) {
+ kfree(jrpriv);
+ return -EINVAL;
+ }
/* Now do the platform independent part */
error = caam_jr_init(jrdev); /* now turn on hardware */
- if (error) {
- irq_dispose_mapping(jrpriv->irq);
- iounmap(ctrl);
- return error;
- }
+ if (error)
+ goto dispose_irq_mapping;
- jrpriv->dev = jrdev;
spin_lock(&driver_data.jr_alloc_lock);
list_add_tail(&jrpriv->list_node, &driver_data.jr_list);
spin_unlock(&driver_data.jr_alloc_lock);
atomic_set(&jrpriv->tfm_count, 0);
- return 0;
+ device_init_wakeup(&pdev->dev, 1);
+ device_set_wakeup_enable(&pdev->dev, false);
+
+ error = caam_jr_instantiate_rng(jrdev);
+ if (error)
+ goto remove_jr_from_list;
+
+ goto exit;
+
+remove_jr_from_list:
+ spin_lock(&driver_data.jr_alloc_lock);
+ list_del(&jrpriv->list_node);
+ spin_unlock(&driver_data.jr_alloc_lock);
+dispose_irq_mapping:
+ irq_dispose_mapping(jrpriv->irq);
+unmap_ctrl:
+ iounmap(ctrl);
+
+exit:
+ return error;
+}
+
+#ifdef CONFIG_PM_SLEEP
+
+static void caam_jr_get_hw_state(struct device *dev)
+{
+ struct caam_drv_private_jr *jrp = dev_get_drvdata(dev);
+
+ jrp->state.inpbusaddr = rd_reg64(&jrp->rregs->inpring_base);
+ jrp->state.outbusaddr = rd_reg64(&jrp->rregs->outring_base);
+}
+
+static int caam_jr_suspend(struct device *dev)
+{
+ int err = 0;
+ struct platform_device *pdev = to_platform_device(dev);
+ struct caam_drv_private_jr *jrpriv = platform_get_drvdata(pdev);
+ struct caam_drv_private *ctrlpriv = dev_get_drvdata(dev->parent);
+ struct caam_jr_dequeue_params suspend_params = {
+ .dev = dev,
+ .enable_itr = 0,
+ };
+
+ if (ctrlpriv->caam_off_during_pm) {
+ tasklet_disable(&jrpriv->irqtask);
+
+ /* mask itr to call flush */
+ mask_itr(dev);
+
+ /* Invalid job in process */
+ err = caam_jr_flush(dev);
+ if (err) {
+ dev_err(dev, "Failed to flush\n");
+ goto exit;
+ }
+
+ /* Dequeing jobs flushed */
+ caam_jr_dequeue((unsigned long)&suspend_params);
+
+ /* Save state */
+ caam_jr_get_hw_state(dev);
+
+ } else if (device_may_wakeup(&pdev->dev)) {
+ enable_irq_wake(jrpriv->irq);
+ }
+
+exit:
+ return err;
}
+static int caam_jr_resume(struct device *dev)
+{
+ int err = 0;
+ struct platform_device *pdev = to_platform_device(dev);
+ struct caam_drv_private_jr *jrpriv = platform_get_drvdata(pdev);
+ struct caam_drv_private *ctrlpriv = dev_get_drvdata(dev->parent);
+
+ if (ctrlpriv->caam_off_during_pm) {
+ u64 inp_addr;
+
+ /*
+ * Check if the CAAM has been resetted checking the address of
+ * the input ring
+ */
+ inp_addr = rd_reg64(&jrpriv->rregs->inpring_base);
+ if (inp_addr != 0) {
+ /* JR still has some configuration */
+ if (inp_addr == jrpriv->state.inpbusaddr) {
+ /* JR has not been resetted */
+ err = caam_jr_restart_processing(dev);
+ if (err)
+ goto exit;
+
+ tasklet_enable(&jrpriv->irqtask);
+
+ unmask_itr(dev);
+
+ goto exit;
+ } else if (ctrlpriv->has_optee) {
+ /* JR has been used by OPTEE, reset it */
+ err = caam_reset_hw_jr(dev);
+ if (err) {
+ dev_err(dev, "Failed to reset JR\n");
+ goto exit;
+ }
+ } else {
+ /* No explanation, return error */
+ err = -EIO;
+ goto exit;
+ }
+ }
+
+ caam_jr_reset_index(jrpriv);
+
+ caam_jr_init_hw(dev, jrpriv->state.inpbusaddr,
+ jrpriv->state.outbusaddr);
+
+ tasklet_enable(&jrpriv->irqtask);
+
+ err = caam_jr_instantiate_rng(dev);
+ if (err) {
+ dev_err(dev, "Failed to instantiate RNG\n");
+ goto exit;
+ }
+
+ } else if (device_may_wakeup(&pdev->dev)) {
+ disable_irq_wake(jrpriv->irq);
+ }
+
+exit:
+ return err;
+}
+
+SIMPLE_DEV_PM_OPS(caam_jr_pm_ops, caam_jr_suspend, caam_jr_resume);
+
+#endif /* CONFIG_PM_SLEEP */
+
static const struct of_device_id caam_jr_match[] = {
{
.compatible = "fsl,sec-v4.0-job-ring",
@@ -557,6 +826,9 @@ static struct platform_driver caam_jr_driver = {
.driver = {
.name = "caam_jr",
.of_match_table = caam_jr_match,
+#ifdef CONFIG_PM_SLEEP
+ .pm = &caam_jr_pm_ops,
+#endif
},
.probe = caam_jr_probe,
.remove = caam_jr_remove,
diff --git a/drivers/crypto/caam/pdb.h b/drivers/crypto/caam/pdb.h
index 810f0bef0652..68f27e07e01e 100644
--- a/drivers/crypto/caam/pdb.h
+++ b/drivers/crypto/caam/pdb.h
@@ -3,12 +3,14 @@
* CAAM Protocol Data Block (PDB) definition header file
*
* Copyright 2008-2016 Freescale Semiconductor, Inc.
+ * Copyright 2018 NXP
*
*/
#ifndef CAAM_PDB_H
#define CAAM_PDB_H
#include "compat.h"
+#include "regs.h"
/*
* PDB- IPSec ESP Header Modification Options
@@ -507,10 +509,10 @@ struct dsa_verify_pdb {
*/
struct rsa_pub_pdb {
u32 sgf;
- dma_addr_t f_dma;
- dma_addr_t g_dma;
- dma_addr_t n_dma;
- dma_addr_t e_dma;
+ caam_dma_addr_t f_dma;
+ caam_dma_addr_t g_dma;
+ caam_dma_addr_t n_dma;
+ caam_dma_addr_t e_dma;
u32 f_len;
} __packed;
@@ -524,10 +526,10 @@ struct rsa_pub_pdb {
*/
struct rsa_priv_f1_pdb {
u32 sgf;
- dma_addr_t g_dma;
- dma_addr_t f_dma;
- dma_addr_t n_dma;
- dma_addr_t d_dma;
+ caam_dma_addr_t g_dma;
+ caam_dma_addr_t f_dma;
+ caam_dma_addr_t n_dma;
+ caam_dma_addr_t d_dma;
} __packed;
/**
@@ -546,13 +548,13 @@ struct rsa_priv_f1_pdb {
*/
struct rsa_priv_f2_pdb {
u32 sgf;
- dma_addr_t g_dma;
- dma_addr_t f_dma;
- dma_addr_t d_dma;
- dma_addr_t p_dma;
- dma_addr_t q_dma;
- dma_addr_t tmp1_dma;
- dma_addr_t tmp2_dma;
+ caam_dma_addr_t g_dma;
+ caam_dma_addr_t f_dma;
+ caam_dma_addr_t d_dma;
+ caam_dma_addr_t p_dma;
+ caam_dma_addr_t q_dma;
+ caam_dma_addr_t tmp1_dma;
+ caam_dma_addr_t tmp2_dma;
u32 p_q_len;
} __packed;
@@ -576,15 +578,15 @@ struct rsa_priv_f2_pdb {
*/
struct rsa_priv_f3_pdb {
u32 sgf;
- dma_addr_t g_dma;
- dma_addr_t f_dma;
- dma_addr_t c_dma;
- dma_addr_t p_dma;
- dma_addr_t q_dma;
- dma_addr_t dp_dma;
- dma_addr_t dq_dma;
- dma_addr_t tmp1_dma;
- dma_addr_t tmp2_dma;
+ caam_dma_addr_t g_dma;
+ caam_dma_addr_t f_dma;
+ caam_dma_addr_t c_dma;
+ caam_dma_addr_t p_dma;
+ caam_dma_addr_t q_dma;
+ caam_dma_addr_t dp_dma;
+ caam_dma_addr_t dq_dma;
+ caam_dma_addr_t tmp1_dma;
+ caam_dma_addr_t tmp2_dma;
u32 p_q_len;
} __packed;
diff --git a/drivers/crypto/caam/regs.h b/drivers/crypto/caam/regs.h
index e5513cc59ec3..9bd62c9a678f 100644
--- a/drivers/crypto/caam/regs.h
+++ b/drivers/crypto/caam/regs.h
@@ -2,7 +2,8 @@
/*
* CAAM hardware register-level view
*
- * Copyright 2008-2011 Freescale Semiconductor, Inc.
+ * Copyright 2008-2016 Freescale Semiconductor, Inc.
+ * Copyright 2017-2019 NXP
*/
#ifndef REGS_H
@@ -136,7 +137,7 @@ static inline void clrsetbits_32(void __iomem *reg, u32 clear, u32 set)
* base + 0x0000 : least-significant 32 bits
* base + 0x0004 : most-significant 32 bits
*/
-#ifdef CONFIG_64BIT
+#if defined(CONFIG_64BIT) && !(defined(CONFIG_HAVE_IMX8_SOC))
static inline void wr_reg64(void __iomem *reg, u64 data)
{
if (caam_little_end)
@@ -179,8 +180,12 @@ static inline u64 rd_reg64(void __iomem *reg)
static inline u64 cpu_to_caam_dma64(dma_addr_t value)
{
if (caam_imx)
+#if IS_ENABLED(CONFIG_ARCH_DMA_ADDR_T_64BIT)
return (((u64)cpu_to_caam32(lower_32_bits(value)) << 32) |
(u64)cpu_to_caam32(upper_32_bits(value)));
+#else
+ return (u64)cpu_to_caam32(lower_32_bits(value)) << 32;
+#endif
return cpu_to_caam64(value);
}
@@ -194,7 +199,7 @@ static inline u64 caam_dma64_to_cpu(u64 value)
return caam64_to_cpu(value);
}
-#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
+#if defined(CONFIG_ARCH_DMA_ADDR_T_64BIT) && !defined(CONFIG_HAVE_IMX8_SOC)
#define cpu_to_caam_dma(value) cpu_to_caam_dma64(value)
#define caam_dma_to_cpu(value) caam_dma64_to_cpu(value)
#else
@@ -203,11 +208,26 @@ static inline u64 caam_dma64_to_cpu(u64 value)
#endif /* CONFIG_ARCH_DMA_ADDR_T_64BIT */
/*
+ * On i.MX8 boards the arch is arm64 but the CAAM dma address size is
+ * 32 bits on 8MQ and 36 bits on 8QM and 8QXP.
+ * For 8QM and 8QXP there is a configurable field PS called pointer size
+ * in the MCFGR register to switch between 32 and 64 (default 32)
+ * But this register is only accessible by the SECO and is left to its
+ * default value.
+ * Here we set the CAAM dma address size to 32 bits for all i.MX8
+ */
+#ifdef CONFIG_HAVE_IMX8_SOC
+#define caam_dma_addr_t u32
+#else
+#define caam_dma_addr_t dma_addr_t
+#endif
+
+/*
* jr_outentry
* Represents each entry in a JobR output ring
*/
struct jr_outentry {
- dma_addr_t desc;/* Pointer to completed descriptor */
+ caam_dma_addr_t desc;/* Pointer to completed descriptor */
u32 jrstatus; /* Status for completed descriptor */
} __packed;
@@ -269,12 +289,26 @@ struct jr_outentry {
#define CHA_ID_MS_JR_SHIFT 28
#define CHA_ID_MS_JR_MASK (0xfull << CHA_ID_MS_JR_SHIFT)
+/*
+ * caam_perfmon - Performance Monitor/Secure Memory Status/
+ * CAAM Global Status/Component Version IDs
+ *
+ * Spans f00-fff wherever instantiated
+ */
+
struct sec_vid {
u16 ip_id;
u8 maj_rev;
u8 min_rev;
};
+#define SEC_VID_IPID_SHIFT 16
+#define SEC_VID_MAJ_SHIFT 8
+#define SEC_VID_MAJ_MASK 0x0000FF00
+
+#define CCB_VID_ERA_SHIFT 24
+#define CCB_VID_ERA_MASK 0x000000FF
+
struct caam_perfmon {
/* Performance Monitor Registers f00-f9f */
u64 req_dequeued; /* PC_REQ_DEQ - Dequeued Requests */
@@ -298,17 +332,22 @@ struct caam_perfmon {
#define CTPR_MS_PG_SZ_SHIFT 4
u32 comp_parms_ms; /* CTPR - Compile Parameters Register */
u32 comp_parms_ls; /* CTPR - Compile Parameters Register */
- u64 rsvd1[2];
+ /* Secure Memory State Visibility */
+ u32 rsvd1;
+ u32 smstatus; /* Secure memory status */
+ u32 rsvd2;
+ u32 smpartown; /* Secure memory partition owner */
/* CAAM Global Status fc0-fdf */
u64 faultaddr; /* FAR - Fault Address */
u32 faultliodn; /* FALR - Fault Address LIODN */
u32 faultdetail; /* FADR - Fault Addr Detail */
- u32 rsvd2;
#define CSTA_PLEND BIT(10)
#define CSTA_ALT_PLEND BIT(18)
+ u32 rsvd3;
u32 status; /* CSTA - CAAM Status */
- u64 rsvd3;
+ u32 smpart; /* Secure Memory Partition Parameters */
+ u32 smvid; /* Secure Memory Version ID */
/* Component Instantiation Parameters fe0-fff */
u32 rtic_id; /* RVID - RTIC Version ID */
@@ -321,6 +360,62 @@ struct caam_perfmon {
u32 caam_id_ls; /* CAAMVID - CAAM Version ID LS */
};
+#define SMSTATUS_PART_SHIFT 28
+#define SMSTATUS_PART_MASK (0xf << SMSTATUS_PART_SHIFT)
+#define SMSTATUS_PAGE_SHIFT 16
+#define SMSTATUS_PAGE_MASK (0x7ff << SMSTATUS_PAGE_SHIFT)
+#define SMSTATUS_MID_SHIFT 8
+#define SMSTATUS_MID_MASK (0x3f << SMSTATUS_MID_SHIFT)
+#define SMSTATUS_ACCERR_SHIFT 4
+#define SMSTATUS_ACCERR_MASK (0xf << SMSTATUS_ACCERR_SHIFT)
+#define SMSTATUS_ACCERR_NONE 0
+#define SMSTATUS_ACCERR_ALLOC 1 /* Page not allocated */
+#define SMSTATUS_ACCESS_ID 2 /* Not granted by ID */
+#define SMSTATUS_ACCESS_WRITE 3 /* Writes not allowed */
+#define SMSTATUS_ACCESS_READ 4 /* Reads not allowed */
+#define SMSTATUS_ACCESS_NONKEY 6 /* Non-key reads not allowed */
+#define SMSTATUS_ACCESS_BLOB 9 /* Blob access not allowed */
+#define SMSTATUS_ACCESS_DESCB 10 /* Descriptor Blob access spans pages */
+#define SMSTATUS_ACCESS_NON_SM 11 /* Outside Secure Memory range */
+#define SMSTATUS_ACCESS_XPAGE 12 /* Access crosses pages */
+#define SMSTATUS_ACCESS_INITPG 13 /* Page still initializing */
+#define SMSTATUS_STATE_SHIFT 0
+#define SMSTATUS_STATE_MASK (0xf << SMSTATUS_STATE_SHIFT)
+#define SMSTATUS_STATE_RESET 0
+#define SMSTATUS_STATE_INIT 1
+#define SMSTATUS_STATE_NORMAL 2
+#define SMSTATUS_STATE_FAIL 3
+
+/* up to 15 rings, 2 bits shifted by ring number */
+#define SMPARTOWN_RING_SHIFT 2
+#define SMPARTOWN_RING_MASK 3
+#define SMPARTOWN_AVAILABLE 0
+#define SMPARTOWN_NOEXIST 1
+#define SMPARTOWN_UNAVAILABLE 2
+#define SMPARTOWN_OURS 3
+
+/* Maximum number of pages possible */
+#define SMPART_MAX_NUMPG_SHIFT 16
+#define SMPART_MAX_NUMPG_MASK (0x3f << SMPART_MAX_NUMPG_SHIFT)
+
+/* Maximum partition number */
+#define SMPART_MAX_PNUM_SHIFT 12
+#define SMPART_MAX_PNUM_MASK (0xf << SMPART_MAX_PNUM_SHIFT)
+
+/* Highest possible page number */
+#define SMPART_MAX_PG_SHIFT 0
+#define SMPART_MAX_PG_MASK (0x3f << SMPART_MAX_PG_SHIFT)
+
+/* Max size of a page */
+#define SMVID_PG_SIZE_SHIFT 16
+#define SMVID_PG_SIZE_MASK (0x7 << SMVID_PG_SIZE_SHIFT)
+
+/* Major/Minor Version ID */
+#define SMVID_MAJ_VERS_SHIFT 8
+#define SMVID_MAJ_VERS (0xf << SMVID_MAJ_VERS_SHIFT)
+#define SMVID_MIN_VERS_SHIFT 0
+#define SMVID_MIN_VERS (0xf << SMVID_MIN_VERS_SHIFT)
+
/* LIODN programming for DMA configuration */
#define MSTRID_LOCK_LIODN 0x80000000
#define MSTRID_LOCK_MAKETRUSTED 0x00010000 /* only for JR masterid */
@@ -331,12 +426,6 @@ struct masterid {
u32 liodn_ls; /* LIODN for non-sequence and seq access */
};
-/* Partition ID for DMA configuration */
-struct partid {
- u32 rsvd1;
- u32 pidr; /* partition ID, DECO */
-};
-
/* RNGB test mode (replicated twice in some configurations) */
/* Padded out to 0x100 */
struct rngtst {
@@ -372,7 +461,8 @@ struct rngtst {
/* RNG4 TRNG test registers */
struct rng4tst {
-#define RTMCTL_PRGM 0x00010000 /* 1 -> program mode, 0 -> run mode */
+#define RTMCTL_ACC BIT(5) /* TRNG access mode */
+#define RTMCTL_PRGM BIT(16) /* 1 -> program mode, 0 -> run mode */
#define RTMCTL_SAMP_MODE_VON_NEUMANN_ES_SC 0 /* use von Neumann data in
both entropy shifter and
statistical checker */
@@ -449,7 +539,7 @@ struct caam_ctrl {
u32 deco_rsr; /* DECORSR - Deco Request Source */
u32 rsvd11;
u32 deco_rq; /* DECORR - DECO Request */
- struct partid deco_mid[5]; /* DECOxLIODNR - 1 per DECO */
+ struct masterid deco_mid[5]; /* DECOxLIODNR - 1 per DECO */
u32 rsvd5[22];
/* DECO Availability/Reset Section 120-3ff */
@@ -522,6 +612,35 @@ struct caam_ctrl {
#define JRSTART_JR2_START 0x00000004 /* Start Job ring 2 */
#define JRSTART_JR3_START 0x00000008 /* Start Job ring 3 */
+/* Secure Memory Configuration - if you have it */
+/* Secure Memory Register Offset from JR Base Reg*/
+#define SM_V1_OFFSET 0x0f4
+#define SM_V2_OFFSET 0xa00
+
+/* Minimum SM Version ID requiring v2 SM register mapping */
+#define SMVID_V2 0x20105
+
+struct caam_secure_mem_v1 {
+ u32 sm_cmd; /* SMCJRx - Secure memory command */
+ u32 rsvd1;
+ u32 sm_status; /* SMCSJRx - Secure memory status */
+ u32 rsvd2;
+
+ u32 sm_perm; /* SMAPJRx - Secure memory access perms */
+ u32 sm_group2; /* SMAP2JRx - Secure memory access group 2 */
+ u32 sm_group1; /* SMAP1JRx - Secure memory access group 1 */
+};
+
+struct caam_secure_mem_v2 {
+ u32 sm_perm; /* SMAPJRx - Secure memory access perms */
+ u32 sm_group2; /* SMAP2JRx - Secure memory access group 2 */
+ u32 sm_group1; /* SMAP1JRx - Secure memory access group 1 */
+ u32 rsvd1[118];
+ u32 sm_cmd; /* SMCJRx - Secure memory command */
+ u32 rsvd2;
+ u32 sm_status; /* SMCSJRx - Secure memory status */
+};
+
/*
* caam_job_ring - direct job ring setup
* 1-4 possible per instantiation, base + 1000/2000/3000/4000
@@ -563,8 +682,7 @@ struct caam_job_ring {
/* Command/control */
u32 rsvd11;
u32 jrcommand; /* JRCRx - JobR command */
-
- u32 rsvd12[932];
+ u32 rsvd12[931];
/* Performance Monitor f00-fff */
struct caam_perfmon perfmon;
@@ -687,6 +805,62 @@ struct caam_job_ring {
#define JRCR_RESET 0x01
+/* secure memory command */
+#define SMC_PAGE_SHIFT 16
+#define SMC_PAGE_MASK (0xffff << SMC_PAGE_SHIFT)
+#define SMC_PART_SHIFT 8
+#define SMC_PART_MASK (0x0f << SMC_PART_SHIFT)
+#define SMC_CMD_SHIFT 0
+#define SMC_CMD_MASK (0x0f << SMC_CMD_SHIFT)
+
+#define SMC_CMD_ALLOC_PAGE 0x01 /* allocate page to this partition */
+#define SMC_CMD_DEALLOC_PAGE 0x02 /* deallocate page from partition */
+#define SMC_CMD_DEALLOC_PART 0x03 /* deallocate partition */
+#define SMC_CMD_PAGE_INQUIRY 0x05 /* find partition associate with page */
+
+/* secure memory (command) status */
+#define SMCS_PAGE_SHIFT 16
+#define SMCS_PAGE_MASK (0x0fff << SMCS_PAGE_SHIFT)
+#define SMCS_CMDERR_SHIFT 14
+#define SMCS_CMDERR_MASK (3 << SMCS_CMDERR_SHIFT)
+#define SMCS_ALCERR_SHIFT 12
+#define SMCS_ALCERR_MASK (3 << SMCS_ALCERR_SHIFT)
+#define SMCS_PGOWN_SHIFT 6
+#define SMCS_PGWON_MASK (3 << SMCS_PGOWN_SHIFT)
+#define SMCS_PART_SHIFT 0
+#define SMCS_PART_MASK (0xf << SMCS_PART_SHIFT)
+
+#define SMCS_CMDERR_NONE 0
+#define SMCS_CMDERR_INCOMP 1 /* Command not yet complete */
+#define SMCS_CMDERR_SECFAIL 2 /* Security failure occurred */
+#define SMCS_CMDERR_OVERFLOW 3 /* Command overflow */
+
+#define SMCS_ALCERR_NONE 0
+#define SMCS_ALCERR_PSPERR 1 /* Partion marked PSP (dealloc only) */
+#define SMCS_ALCERR_PAGEAVAIL 2 /* Page not available */
+#define SMCS_ALCERR_PARTOWN 3 /* Partition ownership error */
+
+#define SMCS_PGOWN_AVAIL 0 /* Page is available */
+#define SMCS_PGOWN_NOEXIST 1 /* Page initializing or nonexistent */
+#define SMCS_PGOWN_NOOWN 2 /* Page owned by another processor */
+#define SMCS_PGOWN_OWNED 3 /* Page belongs to this processor */
+
+/* secure memory access permissions */
+#define SMCS_PERM_KEYMOD_SHIFT 16
+#define SMCA_PERM_KEYMOD_MASK (0xff << SMCS_PERM_KEYMOD_SHIFT)
+#define SMCA_PERM_CSP_ZERO 0x8000 /* Zero when deallocated or released */
+#define SMCA_PERM_PSP_LOCK 0x4000 /* Part./pages can't be deallocated */
+#define SMCA_PERM_PERM_LOCK 0x2000 /* Lock permissions */
+#define SMCA_PERM_GRP_LOCK 0x1000 /* Lock access groups */
+#define SMCA_PERM_RINGID_SHIFT 10
+#define SMCA_PERM_RINGID_MASK (3 << SMCA_PERM_RINGID_SHIFT)
+#define SMCA_PERM_G2_BLOB 0x0080 /* Group 2 blob import/export */
+#define SMCA_PERM_G2_WRITE 0x0020 /* Group 2 write */
+#define SMCA_PERM_G2_READ 0x0010 /* Group 2 read */
+#define SMCA_PERM_G1_BLOB 0x0008 /* Group 1... */
+#define SMCA_PERM_G1_WRITE 0x0002
+#define SMCA_PERM_G1_READ 0x0001
+
/*
* caam_assurance - Assurance Controller View
* base + 0x6000 padded out to 0x1000
diff --git a/drivers/crypto/caam/secvio.c b/drivers/crypto/caam/secvio.c
new file mode 100644
index 000000000000..dac2fef7039b
--- /dev/null
+++ b/drivers/crypto/caam/secvio.c
@@ -0,0 +1,340 @@
+
+/*
+ * SNVS Security Violation Handler
+ * Copyright (C) 2012-2016 Freescale Semiconductor, Inc., All Rights Reserved
+ */
+
+#include "compat.h"
+#include "secvio.h"
+#include "regs.h"
+#include "intern.h"
+#include <linux/of.h>
+#include <linux/of_irq.h>
+#include <linux/of_address.h>
+
+/* The driver is matched with node caam_snvs to get regmap
+ * It will then retrieve interruption and tamper alarm configuration from
+ * node caam-secvio searching for the compat string "fsl,imx6q-caam-secvio"
+ */
+#define DRIVER_NAME "caam-snvs"
+
+/*
+ * These names are associated with each violation handler.
+ * The source names were taken from MX6, and are based on recommendations
+ * for most common SoCs.
+ */
+static const u8 *violation_src_name[] = {
+ "CAAM Internal Security Violation",
+ "JTAG Alarm",
+ "Watchdog",
+ "(reserved)",
+ "External Boot",
+ "External Tamper Detect",
+};
+
+/* These names help describe security monitor state for the console */
+static const u8 *snvs_ssm_state_name[] = {
+ "init",
+ "hard fail",
+ "(undef:2)",
+ "soft fail",
+ "(undef:4)",
+ "(undef:5)",
+ "(undef:6)",
+ "(undef:7)",
+ "transition",
+ "check",
+ "(undef:10)",
+ "non-secure",
+ "(undef:12)",
+ "trusted",
+ "(undef:14)",
+ "secure",
+};
+
+/* Top-level security violation interrupt */
+static irqreturn_t snvs_secvio_interrupt(int irq, void *snvsdev)
+{
+ struct device *dev = snvsdev;
+ struct snvs_secvio_drv_private *svpriv = dev_get_drvdata(dev);
+
+ clk_enable(svpriv->clk);
+ /* Check the HP secvio status register */
+ svpriv->irqcause = rd_reg32(&svpriv->svregs->hp.secvio_status) &
+ HP_SECVIOST_SECVIOMASK;
+
+ if (!svpriv->irqcause) {
+ clk_disable(svpriv->clk);
+ return IRQ_NONE;
+ }
+
+ /* Now ACK cause */
+ clrsetbits_32(&svpriv->svregs->hp.secvio_status, 0, svpriv->irqcause);
+
+ /* And run deferred service */
+ preempt_disable();
+ tasklet_schedule(&svpriv->irqtask[smp_processor_id()]);
+ preempt_enable();
+
+ clk_disable(svpriv->clk);
+
+ return IRQ_HANDLED;
+}
+
+/* Deferred service handler. Tasklet arg is simply the SNVS dev */
+static void snvs_secvio_dispatch(unsigned long indev)
+{
+ struct device *dev = (struct device *)indev;
+ struct snvs_secvio_drv_private *svpriv = dev_get_drvdata(dev);
+ unsigned long flags;
+ int i;
+
+
+ /* Look through stored causes, call each handler if exists */
+ for (i = 0; i < MAX_SECVIO_SOURCES; i++)
+ if (svpriv->irqcause & (1 << i)) {
+ spin_lock_irqsave(&svpriv->svlock, flags);
+ svpriv->intsrc[i].handler(dev, i,
+ svpriv->intsrc[i].ext);
+ spin_unlock_irqrestore(&svpriv->svlock, flags);
+ };
+
+ /* Re-enable now-serviced interrupts */
+ clrsetbits_32(&svpriv->svregs->hp.secvio_intcfg, 0, svpriv->irqcause);
+}
+
+/*
+ * Default cause handler, used in lieu of an application-defined handler.
+ * All it does at this time is print a console message. It could force a halt.
+ */
+static void snvs_secvio_default(struct device *dev, u32 cause, void *ext)
+{
+ struct snvs_secvio_drv_private *svpriv = dev_get_drvdata(dev);
+
+ dev_err(dev, "Unhandled Security Violation Interrupt %d = %s\n",
+ cause, svpriv->intsrc[cause].intname);
+}
+
+/*
+ * Install an application-defined handler for a specified cause
+ * Arguments:
+ * - dev points to SNVS-owning device
+ * - cause interrupt source cause
+ * - handler application-defined handler, gets called with dev
+ * source cause, and locally-defined handler argument
+ * - cause_description points to a string to override the default cause
+ * name, this can be used as an alternate for error
+ * messages and such. If left NULL, the default
+ * description string is used.
+ * - ext pointer to any extra data needed by the handler.
+ */
+int snvs_secvio_install_handler(struct device *dev, enum secvio_cause cause,
+ void (*handler)(struct device *dev, u32 cause,
+ void *ext),
+ u8 *cause_description, void *ext)
+{
+ unsigned long flags;
+ struct snvs_secvio_drv_private *svpriv;
+
+ svpriv = dev_get_drvdata(dev);
+
+ if ((handler == NULL) || (cause > SECVIO_CAUSE_SOURCE_5))
+ return -EINVAL;
+
+ spin_lock_irqsave(&svpriv->svlock, flags);
+ svpriv->intsrc[cause].handler = handler;
+ if (cause_description != NULL)
+ svpriv->intsrc[cause].intname = cause_description;
+ if (ext != NULL)
+ svpriv->intsrc[cause].ext = ext;
+ spin_unlock_irqrestore(&svpriv->svlock, flags);
+
+ return 0;
+}
+EXPORT_SYMBOL(snvs_secvio_install_handler);
+
+/*
+ * Remove an application-defined handler for a specified cause (and, by
+ * implication, restore the "default".
+ * Arguments:
+ * - dev points to SNVS-owning device
+ * - cause interrupt source cause
+ */
+int snvs_secvio_remove_handler(struct device *dev, enum secvio_cause cause)
+{
+ unsigned long flags;
+ struct snvs_secvio_drv_private *svpriv;
+
+ svpriv = dev_get_drvdata(dev);
+
+ if (cause > SECVIO_CAUSE_SOURCE_5)
+ return -EINVAL;
+
+ spin_lock_irqsave(&svpriv->svlock, flags);
+ svpriv->intsrc[cause].intname = violation_src_name[cause];
+ svpriv->intsrc[cause].handler = snvs_secvio_default;
+ svpriv->intsrc[cause].ext = NULL;
+ spin_unlock_irqrestore(&svpriv->svlock, flags);
+ return 0;
+}
+EXPORT_SYMBOL(snvs_secvio_remove_handler);
+
+static int snvs_secvio_remove(struct platform_device *pdev)
+{
+ struct device *svdev;
+ struct snvs_secvio_drv_private *svpriv;
+ int i;
+
+ svdev = &pdev->dev;
+ svpriv = dev_get_drvdata(svdev);
+
+ clk_enable(svpriv->clk);
+ /* Set all sources to nonfatal */
+ wr_reg32(&svpriv->svregs->hp.secvio_intcfg, 0);
+
+ /* Remove tasklets and release interrupt */
+ for_each_possible_cpu(i)
+ tasklet_kill(&svpriv->irqtask[i]);
+
+ clk_disable_unprepare(svpriv->clk);
+ free_irq(svpriv->irq, svdev);
+ iounmap(svpriv->svregs);
+ kfree(svpriv);
+
+ return 0;
+}
+
+static int snvs_secvio_probe(struct platform_device *pdev)
+{
+ struct device *svdev;
+ struct snvs_secvio_drv_private *svpriv;
+ struct device_node *np, *npirq;
+ struct snvs_full __iomem *snvsregs;
+ int i, error;
+ u32 hpstate;
+ const void *jtd, *wtd, *itd, *etd;
+ u32 td_en;
+
+ svpriv = kzalloc(sizeof(struct snvs_secvio_drv_private), GFP_KERNEL);
+ if (!svpriv)
+ return -ENOMEM;
+
+ svdev = &pdev->dev;
+ dev_set_drvdata(svdev, svpriv);
+ svpriv->pdev = pdev;
+ np = pdev->dev.of_node;
+
+ npirq = of_find_compatible_node(NULL, NULL, "fsl,imx6q-caam-secvio");
+ if (!npirq) {
+ dev_err(svdev, "can't find secvio node\n");
+ kfree(svpriv);
+ return -EINVAL;
+ }
+ svpriv->irq = irq_of_parse_and_map(npirq, 0);
+ if (svpriv->irq <= 0) {
+ dev_err(svdev, "can't identify secvio interrupt\n");
+ kfree(svpriv);
+ return -EINVAL;
+ }
+
+ jtd = of_get_property(npirq, "jtag-tamper", NULL);
+ wtd = of_get_property(npirq, "watchdog-tamper", NULL);
+ itd = of_get_property(npirq, "internal-boot-tamper", NULL);
+ etd = of_get_property(npirq, "external-pin-tamper", NULL);
+ if (!jtd | !wtd | !itd | !etd ) {
+ dev_err(svdev, "can't identify all tamper alarm configuration\n");
+ kfree(svpriv);
+ return -EINVAL;
+ }
+
+ /*
+ * Configure all sources according to device tree property.
+ * If the property is enabled then the source is ser as
+ * fatal violations except LP section,
+ * source #5 (typically used as an external tamper detect), and
+ * source #3 (typically unused). Whenever the transition to
+ * secure mode has occurred, these will now be "fatal" violations
+ */
+ td_en = HP_SECVIO_INTEN_SRC0;
+ if (!strcmp(jtd, "enabled"))
+ td_en |= HP_SECVIO_INTEN_SRC1;
+ if (!strcmp(wtd, "enabled"))
+ td_en |= HP_SECVIO_INTEN_SRC2;
+ if (!strcmp(itd, "enabled"))
+ td_en |= HP_SECVIO_INTEN_SRC4;
+ if (!strcmp(etd, "enabled"))
+ td_en |= HP_SECVIO_INTEN_SRC5;
+
+ snvsregs = of_iomap(np, 0);
+ if (!snvsregs) {
+ dev_err(svdev, "register mapping failed\n");
+ return -ENOMEM;
+ }
+ svpriv->svregs = (struct snvs_full __force *)snvsregs;
+
+ svpriv->clk = devm_clk_get(&pdev->dev, NULL);
+ if (IS_ERR(svpriv->clk)) {
+ dev_err(&pdev->dev, "can't get snvs clock\n");
+ svpriv->clk = NULL;
+ }
+
+ /* Write the Secvio Enable Config the SVCR */
+ wr_reg32(&svpriv->svregs->hp.secvio_ctl, td_en);
+ wr_reg32(&svpriv->svregs->hp.secvio_intcfg, td_en);
+
+ /* Device data set up. Now init interrupt source descriptions */
+ for (i = 0; i < MAX_SECVIO_SOURCES; i++) {
+ svpriv->intsrc[i].intname = violation_src_name[i];
+ svpriv->intsrc[i].handler = snvs_secvio_default;
+ }
+ /* Connect main handler */
+ for_each_possible_cpu(i)
+ tasklet_init(&svpriv->irqtask[i], snvs_secvio_dispatch,
+ (unsigned long)svdev);
+
+ error = request_irq(svpriv->irq, snvs_secvio_interrupt,
+ IRQF_SHARED, DRIVER_NAME, svdev);
+ if (error) {
+ dev_err(svdev, "can't connect secvio interrupt\n");
+ irq_dispose_mapping(svpriv->irq);
+ svpriv->irq = 0;
+ iounmap(svpriv->svregs);
+ kfree(svpriv);
+ return -EINVAL;
+ }
+
+ clk_prepare_enable(svpriv->clk);
+
+ hpstate = (rd_reg32(&svpriv->svregs->hp.status) &
+ HP_STATUS_SSM_ST_MASK) >> HP_STATUS_SSM_ST_SHIFT;
+ dev_info(svdev, "violation handlers armed - %s state\n",
+ snvs_ssm_state_name[hpstate]);
+
+ clk_disable(svpriv->clk);
+
+ return 0;
+}
+
+static struct of_device_id snvs_secvio_match[] = {
+ {
+ .compatible = "fsl,imx6q-caam-snvs",
+ },
+ {},
+};
+MODULE_DEVICE_TABLE(of, snvs_secvio_match);
+
+static struct platform_driver snvs_secvio_driver = {
+ .driver = {
+ .name = DRIVER_NAME,
+ .owner = THIS_MODULE,
+ .of_match_table = snvs_secvio_match,
+ },
+ .probe = snvs_secvio_probe,
+ .remove = snvs_secvio_remove,
+};
+
+module_platform_driver(snvs_secvio_driver);
+
+MODULE_LICENSE("Dual BSD/GPL");
+MODULE_DESCRIPTION("FSL SNVS Security Violation Handler");
+MODULE_AUTHOR("Freescale Semiconductor - MCU");
diff --git a/drivers/crypto/caam/secvio.h b/drivers/crypto/caam/secvio.h
new file mode 100644
index 000000000000..97eb2723f19c
--- /dev/null
+++ b/drivers/crypto/caam/secvio.h
@@ -0,0 +1,67 @@
+
+/*
+ * CAAM Security Violation Handler
+ * Copyright (C) 2012-2015 Freescale Semiconductor, Inc., All Rights Reserved
+ */
+
+#ifndef SECVIO_H
+#define SECVIO_H
+
+#include "snvsregs.h"
+
+
+/*
+ * Defines the published interfaces to install/remove application-specified
+ * handlers for catching violations
+ */
+
+#define MAX_SECVIO_SOURCES 6
+
+/* these are the untranslated causes */
+enum secvio_cause {
+ SECVIO_CAUSE_SOURCE_0,
+ SECVIO_CAUSE_SOURCE_1,
+ SECVIO_CAUSE_SOURCE_2,
+ SECVIO_CAUSE_SOURCE_3,
+ SECVIO_CAUSE_SOURCE_4,
+ SECVIO_CAUSE_SOURCE_5
+};
+
+/* These are common "recommended" cause definitions for most devices */
+#define SECVIO_CAUSE_CAAM_VIOLATION SECVIO_CAUSE_SOURCE_0
+#define SECVIO_CAUSE_JTAG_ALARM SECVIO_CAUSE_SOURCE_1
+#define SECVIO_CAUSE_WATCHDOG SECVIO_CAUSE_SOURCE_2
+#define SECVIO_CAUSE_EXTERNAL_BOOT SECVIO_CAUSE_SOURCE_4
+#define SECVIO_CAUSE_TAMPER_DETECT SECVIO_CAUSE_SOURCE_5
+
+int snvs_secvio_install_handler(struct device *dev, enum secvio_cause cause,
+ void (*handler)(struct device *dev, u32 cause,
+ void *ext),
+ u8 *cause_description, void *ext);
+int snvs_secvio_remove_handler(struct device *dev, enum secvio_cause cause);
+
+/*
+ * Private data definitions for the secvio "driver"
+ */
+
+struct secvio_int_src {
+ const u8 *intname; /* Points to a descriptive name for source */
+ void *ext; /* Extended data to pass to the handler */
+ void (*handler)(struct device *dev, u32 cause, void *ext);
+};
+
+struct snvs_secvio_drv_private {
+ struct platform_device *pdev;
+ spinlock_t svlock ____cacheline_aligned;
+ struct tasklet_struct irqtask[NR_CPUS];
+ struct snvs_full __iomem *svregs; /* both HP and LP domains */
+ struct clk *clk;
+ int irq;
+ u32 irqcause; /* stashed cause of violation interrupt */
+
+ /* Registered handlers for each violation */
+ struct secvio_int_src intsrc[MAX_SECVIO_SOURCES];
+
+};
+
+#endif /* SECVIO_H */
diff --git a/drivers/crypto/caam/sm.h b/drivers/crypto/caam/sm.h
new file mode 100644
index 000000000000..65ec9d75ef56
--- /dev/null
+++ b/drivers/crypto/caam/sm.h
@@ -0,0 +1,125 @@
+
+/*
+ * CAAM Secure Memory/Keywrap API Definitions
+ * Copyright (C) 2008-2015 Freescale Semiconductor, Inc.
+ */
+
+#ifndef SM_H
+#define SM_H
+
+
+/* Storage access permissions */
+#define SM_PERM_READ 0x01
+#define SM_PERM_WRITE 0x02
+#define SM_PERM_BLOB 0x03
+
+/* Define treatment of secure memory vs. general memory blobs */
+#define SM_SECMEM 0
+#define SM_GENMEM 1
+
+/* Define treatment of red/black keys */
+#define RED_KEY 0
+#define BLACK_KEY 1
+
+/* Define key encryption/covering options */
+#define KEY_COVER_ECB 0 /* cover key in AES-ECB */
+#define KEY_COVER_CCM 1 /* cover key with AES-CCM */
+
+/*
+ * Round a key size up to an AES blocksize boundary so to allow for
+ * padding out to a full block
+ */
+#define AES_BLOCK_PAD(x) ((x % 16) ? ((x >> 4) + 1) << 4 : x)
+
+/* Define space required for BKEK + MAC tag storage in any blob */
+#define BLOB_OVERHEAD (32 + 16)
+
+/* Keystore maintenance functions */
+void sm_init_keystore(struct device *dev);
+u32 sm_detect_keystore_units(struct device *dev);
+int sm_establish_keystore(struct device *dev, u32 unit);
+void sm_release_keystore(struct device *dev, u32 unit);
+void caam_sm_shutdown(struct platform_device *pdev);
+int caam_sm_example_init(struct platform_device *pdev);
+
+/* Keystore accessor functions */
+extern int sm_keystore_slot_alloc(struct device *dev, u32 unit, u32 size,
+ u32 *slot);
+extern int sm_keystore_slot_dealloc(struct device *dev, u32 unit, u32 slot);
+extern int sm_keystore_slot_load(struct device *dev, u32 unit, u32 slot,
+ const u8 *key_data, u32 key_length);
+extern int sm_keystore_slot_read(struct device *dev, u32 unit, u32 slot,
+ u32 key_length, u8 *key_data);
+extern int sm_keystore_cover_key(struct device *dev, u32 unit, u32 slot,
+ u16 key_length, u8 keyauth);
+extern int sm_keystore_slot_export(struct device *dev, u32 unit, u32 slot,
+ u8 keycolor, u8 keyauth, u8 *outbuf,
+ u16 keylen, u8 *keymod);
+extern int sm_keystore_slot_import(struct device *dev, u32 unit, u32 slot,
+ u8 keycolor, u8 keyauth, u8 *inbuf,
+ u16 keylen, u8 *keymod);
+
+/* Prior functions from legacy API, deprecated */
+extern int sm_keystore_slot_encapsulate(struct device *dev, u32 unit,
+ u32 inslot, u32 outslot, u16 secretlen,
+ u8 *keymod, u16 keymodlen);
+extern int sm_keystore_slot_decapsulate(struct device *dev, u32 unit,
+ u32 inslot, u32 outslot, u16 secretlen,
+ u8 *keymod, u16 keymodlen);
+
+/* Data structure to hold per-slot information */
+struct keystore_data_slot_info {
+ u8 allocated; /* Track slot assignments */
+ u32 key_length; /* Size of the key */
+};
+
+/* Data structure to hold keystore information */
+struct keystore_data {
+ void *base_address; /* Virtual base of secure memory pages */
+ void *phys_address; /* Physical base of secure memory pages */
+ u32 slot_count; /* Number of slots in the keystore */
+ struct keystore_data_slot_info *slot; /* Per-slot information */
+};
+
+/* store the detected attributes of a secure memory page */
+struct sm_page_descriptor {
+ u16 phys_pagenum; /* may be discontiguous */
+ u16 own_part; /* Owning partition */
+ void *pg_base; /* Calculated virtual address */
+ void *pg_phys; /* Calculated physical address */
+ struct keystore_data *ksdata;
+};
+
+struct caam_drv_private_sm {
+ struct device *parentdev; /* this ends up as the controller */
+ struct device *smringdev; /* ring that owns this instance */
+ struct platform_device *sm_pdev; /* Secure Memory platform device */
+ spinlock_t kslock ____cacheline_aligned;
+
+ /* SM Register offset from JR base address */
+ u32 sm_reg_offset;
+
+ /* Default parameters for geometry */
+ u32 max_pages; /* maximum pages this instance can support */
+ u32 top_partition; /* highest partition number in this instance */
+ u32 top_page; /* highest page number in this instance */
+ u32 page_size; /* page size */
+ u32 slot_size; /* selected size of each storage block */
+
+ /* Partition/Page Allocation Map */
+ u32 localpages; /* Number of pages we can access */
+ struct sm_page_descriptor *pagedesc; /* Allocated per-page */
+
+ /* Installed handlers for keystore access */
+ int (*data_init)(struct device *dev, u32 unit);
+ void (*data_cleanup)(struct device *dev, u32 unit);
+ int (*slot_alloc)(struct device *dev, u32 unit, u32 size, u32 *slot);
+ int (*slot_dealloc)(struct device *dev, u32 unit, u32 slot);
+ void *(*slot_get_address)(struct device *dev, u32 unit, u32 handle);
+ void *(*slot_get_physical)(struct device *dev, u32 unit, u32 handle);
+ u32 (*slot_get_base)(struct device *dev, u32 unit, u32 handle);
+ u32 (*slot_get_offset)(struct device *dev, u32 unit, u32 handle);
+ u32 (*slot_get_slot_size)(struct device *dev, u32 unit, u32 handle);
+};
+
+#endif /* SM_H */
diff --git a/drivers/crypto/caam/sm_store.c b/drivers/crypto/caam/sm_store.c
new file mode 100644
index 000000000000..3f1dd914bb69
--- /dev/null
+++ b/drivers/crypto/caam/sm_store.c
@@ -0,0 +1,1336 @@
+/*
+ * CAAM Secure Memory Storage Interface
+ * Copyright (C) 2008-2015 Freescale Semiconductor, Inc.
+ * Copyright 2018 NXP
+ *
+ * Loosely based on the SHW Keystore API for SCC/SCC2
+ * Experimental implementation and NOT intended for upstream use. Expect
+ * this interface to be amended significantly in the future once it becomes
+ * integrated into live applications.
+ *
+ * Known issues:
+ *
+ * - Executes one instance of an secure memory "driver". This is tied to the
+ * fact that job rings can't run as standalone instances in the present
+ * configuration.
+ *
+ * - It does not expose a userspace interface. The value of a userspace
+ * interface for access to secrets is a point for further architectural
+ * discussion.
+ *
+ * - Partition/permission management is not part of this interface. It
+ * depends on some level of "knowledge" agreed upon between bootloader,
+ * provisioning applications, and OS-hosted software (which uses this
+ * driver).
+ *
+ * - No means of identifying the location or purpose of secrets managed by
+ * this interface exists; "slot location" and format of a given secret
+ * needs to be agreed upon between bootloader, provisioner, and OS-hosted
+ * application.
+ */
+
+#include "compat.h"
+#include "regs.h"
+#include "jr.h"
+#include "desc.h"
+#include "intern.h"
+#include "error.h"
+#include "sm.h"
+#include <linux/of_address.h>
+
+#define SECMEM_KEYMOD_LEN 8
+#define GENMEM_KEYMOD_LEN 16
+
+#ifdef SM_DEBUG_CONT
+void sm_show_page(struct device *dev, struct sm_page_descriptor *pgdesc)
+{
+ struct caam_drv_private_sm *smpriv = dev_get_drvdata(dev);
+ u32 i, *smdata;
+
+ dev_info(dev, "physical page %d content at 0x%08x\n",
+ pgdesc->phys_pagenum, pgdesc->pg_base);
+ smdata = pgdesc->pg_base;
+ for (i = 0; i < (smpriv->page_size / sizeof(u32)); i += 4)
+ dev_info(dev, "[0x%08x] 0x%08x 0x%08x 0x%08x 0x%08x\n",
+ (u32)&smdata[i], smdata[i], smdata[i+1], smdata[i+2],
+ smdata[i+3]);
+}
+#endif
+
+#define INITIAL_DESCSZ 16 /* size of tmp buffer for descriptor const. */
+
+static __always_inline u32 sm_send_cmd(struct caam_drv_private_sm *smpriv,
+ struct caam_drv_private_jr *jrpriv,
+ u32 cmd, u32 *status)
+{
+ void __iomem *write_address;
+ void __iomem *read_address;
+
+ if (smpriv->sm_reg_offset == SM_V1_OFFSET) {
+ struct caam_secure_mem_v1 *sm_regs_v1;
+ sm_regs_v1 = (struct caam_secure_mem_v1 *)
+ ((void *)jrpriv->rregs + SM_V1_OFFSET);
+ write_address = &sm_regs_v1->sm_cmd;
+ read_address = &sm_regs_v1->sm_status;
+
+ } else if (smpriv->sm_reg_offset == SM_V2_OFFSET) {
+ struct caam_secure_mem_v2 *sm_regs_v2;
+ sm_regs_v2 = (struct caam_secure_mem_v2 *)
+ ((void *)jrpriv->rregs + SM_V2_OFFSET);
+ write_address = &sm_regs_v2->sm_cmd;
+ read_address = &sm_regs_v2->sm_status;
+
+ } else {
+ return -EINVAL;
+ }
+
+ wr_reg32(write_address, cmd);
+
+ udelay(10);
+
+ /* Read until the command has terminated and the status is correct */
+ do {
+ *status = rd_reg32(read_address);
+ } while (((*status & SMCS_CMDERR_MASK) >> SMCS_CMDERR_SHIFT)
+ == SMCS_CMDERR_INCOMP);
+
+ return 0;
+}
+/*
+ * Construct a black key conversion job descriptor
+ *
+ * This function constructs a job descriptor capable of performing
+ * a key blackening operation on a plaintext secure memory resident object.
+ *
+ * - desc pointer to a pointer to the descriptor generated by this
+ * function. Caller will be responsible to kfree() this
+ * descriptor after execution.
+ * - key physical pointer to the plaintext, which will also hold
+ * the result. Since encryption occurs in place, caller must
+ * ensure that the space is large enough to accommodate the
+ * blackened key
+ * - keysz size of the plaintext
+ * - auth if a CCM-covered key is required, use KEY_COVER_CCM, else
+ * use KEY_COVER_ECB.
+ *
+ * KEY to key1 from @key_addr LENGTH 16 BYTES;
+ * FIFO STORE from key1[ecb] TO @key_addr LENGTH 16 BYTES;
+ *
+ * Note that this variant uses the JDKEK only; it does not accommodate the
+ * trusted key encryption key at this time.
+ *
+ */
+static int blacken_key_jobdesc(u32 **desc, void *key, u16 keysz, bool auth)
+{
+ u32 *tdesc, tmpdesc[INITIAL_DESCSZ];
+ u16 dsize, idx;
+
+ memset(tmpdesc, 0, INITIAL_DESCSZ * sizeof(u32));
+ idx = 1;
+
+ /* Load key to class 1 key register */
+ tmpdesc[idx++] = CMD_KEY | CLASS_1 | (keysz & KEY_LENGTH_MASK);
+ tmpdesc[idx++] = (uintptr_t)key;
+
+ /* ...and write back out via FIFO store*/
+ tmpdesc[idx] = CMD_FIFO_STORE | CLASS_1 | (keysz & KEY_LENGTH_MASK);
+
+ /* plus account for ECB/CCM option in FIFO_STORE */
+ if (auth == KEY_COVER_ECB)
+ tmpdesc[idx] |= FIFOST_TYPE_KEY_KEK;
+ else
+ tmpdesc[idx] |= FIFOST_TYPE_KEY_CCM_JKEK;
+
+ idx++;
+ tmpdesc[idx++] = (uintptr_t)key;
+
+ /* finish off the job header */
+ tmpdesc[0] = CMD_DESC_HDR | HDR_ONE | (idx & HDR_DESCLEN_MASK);
+ dsize = idx * sizeof(u32);
+
+ /* now allocate execution buffer and coat it with executable */
+ tdesc = kmalloc(dsize, GFP_KERNEL | GFP_DMA);
+ if (tdesc == NULL)
+ return 0;
+
+ memcpy(tdesc, tmpdesc, dsize);
+ *desc = tdesc;
+
+ return dsize;
+}
+
+/*
+ * Construct a blob encapsulation job descriptor
+ *
+ * This function dynamically constructs a blob encapsulation job descriptor
+ * from the following arguments:
+ *
+ * - desc pointer to a pointer to the descriptor generated by this
+ * function. Caller will be responsible to kfree() this
+ * descriptor after execution.
+ * - keymod Physical pointer to a key modifier, which must reside in a
+ * contiguous piece of memory. Modifier will be assumed to be
+ * 8 bytes long for a blob of type SM_SECMEM, or 16 bytes long
+ * for a blob of type SM_GENMEM (see blobtype argument).
+ * - secretbuf Physical pointer to a secret, normally a black or red key,
+ * possibly residing within an accessible secure memory page,
+ * of the secret to be encapsulated to an output blob.
+ * - outbuf Physical pointer to the destination buffer to receive the
+ * encapsulated output. This buffer will need to be 48 bytes
+ * larger than the input because of the added encapsulation data.
+ * The generated descriptor will account for the increase in size,
+ * but the caller must also account for this increase in the
+ * buffer allocator.
+ * - secretsz Size of input secret, in bytes. This is limited to 65536
+ * less the size of blob overhead, since the length embeds into
+ * DECO pointer in/out instructions.
+ * - keycolor Determines if the source data is covered (black key) or
+ * plaintext (red key). RED_KEY or BLACK_KEY are defined in
+ * for this purpose.
+ * - blobtype Determine if encapsulated blob should be a secure memory
+ * blob (SM_SECMEM), with partition data embedded with key
+ * material, or a general memory blob (SM_GENMEM).
+ * - auth If BLACK_KEY source is covered via AES-CCM, specify
+ * KEY_COVER_CCM, else uses AES-ECB (KEY_COVER_ECB).
+ *
+ * Upon completion, desc points to a buffer containing a CAAM job
+ * descriptor which encapsulates data into an externally-storable blob
+ * suitable for use across power cycles.
+ *
+ * This is an example of a black key encapsulation job into a general memory
+ * blob. Notice the 16-byte key modifier in the LOAD instruction. Also note
+ * the output 48 bytes longer than the input:
+ *
+ * [00] B0800008 jobhdr: stidx=0 len=8
+ * [01] 14400010 ld: ccb2-key len=16 offs=0
+ * [02] 08144891 ptr->@0x08144891
+ * [03] F800003A seqoutptr: len=58
+ * [04] 01000000 out_ptr->@0x01000000
+ * [05] F000000A seqinptr: len=10
+ * [06] 09745090 in_ptr->@0x09745090
+ * [07] 870D0004 operation: encap blob reg=memory, black, format=normal
+ *
+ * This is an example of a red key encapsulation job for storing a red key
+ * into a secure memory blob. Note the 8 byte modifier on the 12 byte offset
+ * in the LOAD instruction; this accounts for blob permission storage:
+ *
+ * [00] B0800008 jobhdr: stidx=0 len=8
+ * [01] 14400C08 ld: ccb2-key len=8 offs=12
+ * [02] 087D0784 ptr->@0x087d0784
+ * [03] F8000050 seqoutptr: len=80
+ * [04] 09251BB2 out_ptr->@0x09251bb2
+ * [05] F0000020 seqinptr: len=32
+ * [06] 40000F31 in_ptr->@0x40000f31
+ * [07] 870D0008 operation: encap blob reg=memory, red, sec_mem,
+ * format=normal
+ *
+ * Note: this function only generates 32-bit pointers at present, and should
+ * be refactored using a scheme that allows both 32 and 64 bit addressing
+ */
+
+static int blob_encap_jobdesc(u32 **desc, dma_addr_t keymod,
+ void *secretbuf, dma_addr_t outbuf,
+ u16 secretsz, u8 keycolor, u8 blobtype, u8 auth)
+{
+ u32 *tdesc, tmpdesc[INITIAL_DESCSZ];
+ u16 dsize, idx;
+
+ memset(tmpdesc, 0, INITIAL_DESCSZ * sizeof(u32));
+ idx = 1;
+
+ /*
+ * Key modifier works differently for secure/general memory blobs
+ * This accounts for the permission/protection data encapsulated
+ * within the blob if a secure memory blob is requested
+ */
+ if (blobtype == SM_SECMEM)
+ tmpdesc[idx++] = CMD_LOAD | LDST_CLASS_2_CCB |
+ LDST_SRCDST_BYTE_KEY |
+ ((12 << LDST_OFFSET_SHIFT) & LDST_OFFSET_MASK)
+ | (8 & LDST_LEN_MASK);
+ else /* is general memory blob */
+ tmpdesc[idx++] = CMD_LOAD | LDST_CLASS_2_CCB |
+ LDST_SRCDST_BYTE_KEY | (16 & LDST_LEN_MASK);
+
+ tmpdesc[idx++] = (u32)keymod;
+
+ /*
+ * Encapsulation output must include space for blob key encryption
+ * key and MAC tag
+ */
+ tmpdesc[idx++] = CMD_SEQ_OUT_PTR | (secretsz + BLOB_OVERHEAD);
+ tmpdesc[idx++] = (u32)outbuf;
+
+ /* Input data, should be somewhere in secure memory */
+ tmpdesc[idx++] = CMD_SEQ_IN_PTR | secretsz;
+ tmpdesc[idx++] = (uintptr_t)secretbuf;
+
+ /* Set blob encap, then color */
+ tmpdesc[idx] = CMD_OPERATION | OP_TYPE_ENCAP_PROTOCOL | OP_PCLID_BLOB;
+
+ if (blobtype == SM_SECMEM)
+ tmpdesc[idx] |= OP_PCL_BLOB_PTXT_SECMEM;
+
+ if (auth == KEY_COVER_CCM)
+ tmpdesc[idx] |= OP_PCL_BLOB_EKT;
+
+ if (keycolor == BLACK_KEY)
+ tmpdesc[idx] |= OP_PCL_BLOB_BLACK;
+
+ idx++;
+ tmpdesc[0] = CMD_DESC_HDR | HDR_ONE | (idx & HDR_DESCLEN_MASK);
+ dsize = idx * sizeof(u32);
+
+ tdesc = kmalloc(dsize, GFP_KERNEL | GFP_DMA);
+ if (tdesc == NULL)
+ return 0;
+
+ memcpy(tdesc, tmpdesc, dsize);
+ *desc = tdesc;
+ return dsize;
+}
+
+/*
+ * Construct a blob decapsulation job descriptor
+ *
+ * This function dynamically constructs a blob decapsulation job descriptor
+ * from the following arguments:
+ *
+ * - desc pointer to a pointer to the descriptor generated by this
+ * function. Caller will be responsible to kfree() this
+ * descriptor after execution.
+ * - keymod Physical pointer to a key modifier, which must reside in a
+ * contiguous piece of memory. Modifier will be assumed to be
+ * 8 bytes long for a blob of type SM_SECMEM, or 16 bytes long
+ * for a blob of type SM_GENMEM (see blobtype argument).
+ * - blobbuf Physical pointer (into external memory) of the blob to
+ * be decapsulated. Blob must reside in a contiguous memory
+ * segment.
+ * - outbuf Physical pointer of the decapsulated output, possibly into
+ * a location within a secure memory page. Must be contiguous.
+ * - secretsz Size of encapsulated secret in bytes (not the size of the
+ * input blob).
+ * - keycolor Determines if decapsulated content is encrypted (BLACK_KEY)
+ * or left as plaintext (RED_KEY).
+ * - blobtype Determine if encapsulated blob should be a secure memory
+ * blob (SM_SECMEM), with partition data embedded with key
+ * material, or a general memory blob (SM_GENMEM).
+ * - auth If decapsulation path is specified by BLACK_KEY, then if
+ * AES-CCM is requested for key covering use KEY_COVER_CCM, else
+ * use AES-ECB (KEY_COVER_ECB).
+ *
+ * Upon completion, desc points to a buffer containing a CAAM job descriptor
+ * that decapsulates a key blob from external memory into a black (encrypted)
+ * key or red (plaintext) content.
+ *
+ * This is an example of a black key decapsulation job from a general memory
+ * blob. Notice the 16-byte key modifier in the LOAD instruction.
+ *
+ * [00] B0800008 jobhdr: stidx=0 len=8
+ * [01] 14400010 ld: ccb2-key len=16 offs=0
+ * [02] 08A63B7F ptr->@0x08a63b7f
+ * [03] F8000010 seqoutptr: len=16
+ * [04] 01000000 out_ptr->@0x01000000
+ * [05] F000003A seqinptr: len=58
+ * [06] 01000010 in_ptr->@0x01000010
+ * [07] 860D0004 operation: decap blob reg=memory, black, format=normal
+ *
+ * This is an example of a red key decapsulation job for restoring a red key
+ * from a secure memory blob. Note the 8 byte modifier on the 12 byte offset
+ * in the LOAD instruction:
+ *
+ * [00] B0800008 jobhdr: stidx=0 len=8
+ * [01] 14400C08 ld: ccb2-key len=8 offs=12
+ * [02] 01000000 ptr->@0x01000000
+ * [03] F8000020 seqoutptr: len=32
+ * [04] 400000E6 out_ptr->@0x400000e6
+ * [05] F0000050 seqinptr: len=80
+ * [06] 08F0C0EA in_ptr->@0x08f0c0ea
+ * [07] 860D0008 operation: decap blob reg=memory, red, sec_mem,
+ * format=normal
+ *
+ * Note: this function only generates 32-bit pointers at present, and should
+ * be refactored using a scheme that allows both 32 and 64 bit addressing
+ */
+
+static int blob_decap_jobdesc(u32 **desc, dma_addr_t keymod, dma_addr_t blobbuf,
+ u8 *outbuf, u16 secretsz, u8 keycolor,
+ u8 blobtype, u8 auth)
+{
+ u32 *tdesc, tmpdesc[INITIAL_DESCSZ];
+ u16 dsize, idx;
+
+ memset(tmpdesc, 0, INITIAL_DESCSZ * sizeof(u32));
+ idx = 1;
+
+ /* Load key modifier */
+ if (blobtype == SM_SECMEM)
+ tmpdesc[idx++] = CMD_LOAD | LDST_CLASS_2_CCB |
+ LDST_SRCDST_BYTE_KEY |
+ ((12 << LDST_OFFSET_SHIFT) & LDST_OFFSET_MASK)
+ | (8 & LDST_LEN_MASK);
+ else /* is general memory blob */
+ tmpdesc[idx++] = CMD_LOAD | LDST_CLASS_2_CCB |
+ LDST_SRCDST_BYTE_KEY | (16 & LDST_LEN_MASK);
+
+ tmpdesc[idx++] = (u32)keymod;
+
+ /* Compensate BKEK + MAC tag over size of encapsulated secret */
+ tmpdesc[idx++] = CMD_SEQ_IN_PTR | (secretsz + BLOB_OVERHEAD);
+ tmpdesc[idx++] = (u32)blobbuf;
+ tmpdesc[idx++] = CMD_SEQ_OUT_PTR | secretsz;
+ tmpdesc[idx++] = (uintptr_t)outbuf;
+
+ /* Decapsulate from secure memory partition to black blob */
+ tmpdesc[idx] = CMD_OPERATION | OP_TYPE_DECAP_PROTOCOL | OP_PCLID_BLOB;
+
+ if (blobtype == SM_SECMEM)
+ tmpdesc[idx] |= OP_PCL_BLOB_PTXT_SECMEM;
+
+ if (auth == KEY_COVER_CCM)
+ tmpdesc[idx] |= OP_PCL_BLOB_EKT;
+
+ if (keycolor == BLACK_KEY)
+ tmpdesc[idx] |= OP_PCL_BLOB_BLACK;
+
+ idx++;
+ tmpdesc[0] = CMD_DESC_HDR | HDR_ONE | (idx & HDR_DESCLEN_MASK);
+ dsize = idx * sizeof(u32);
+
+ tdesc = kmalloc(dsize, GFP_KERNEL | GFP_DMA);
+ if (tdesc == NULL)
+ return 0;
+
+ memcpy(tdesc, tmpdesc, dsize);
+ *desc = tdesc;
+ return dsize;
+}
+
+/*
+ * Pseudo-synchronous ring access functions for carrying out key
+ * encapsulation and decapsulation
+ */
+
+struct sm_key_job_result {
+ int error;
+ struct completion completion;
+};
+
+void sm_key_job_done(struct device *dev, u32 *desc, u32 err, void *context)
+{
+ struct sm_key_job_result *res = context;
+
+ if (err)
+ caam_jr_strstatus(dev, err);
+
+ res->error = err; /* save off the error for postprocessing */
+
+ complete(&res->completion); /* mark us complete */
+}
+
+static int sm_key_job(struct device *ksdev, u32 *jobdesc)
+{
+ struct sm_key_job_result testres = {0};
+ struct caam_drv_private_sm *kspriv;
+ int rtn = 0;
+
+ kspriv = dev_get_drvdata(ksdev);
+
+ init_completion(&testres.completion);
+
+ rtn = caam_jr_enqueue(kspriv->smringdev, jobdesc, sm_key_job_done,
+ &testres);
+ if (rtn)
+ goto exit;
+
+ wait_for_completion_interruptible(&testres.completion);
+ rtn = testres.error;
+
+exit:
+ return rtn;
+}
+
+/*
+ * Following section establishes the default methods for keystore access
+ * They are NOT intended for use external to this module
+ *
+ * In the present version, these are the only means for the higher-level
+ * interface to deal with the mechanics of accessing the phyiscal keystore
+ */
+
+
+int slot_alloc(struct device *dev, u32 unit, u32 size, u32 *slot)
+{
+ struct caam_drv_private_sm *smpriv = dev_get_drvdata(dev);
+ struct keystore_data *ksdata = smpriv->pagedesc[unit].ksdata;
+ u32 i;
+#ifdef SM_DEBUG
+ dev_info(dev, "slot_alloc(): requesting slot for %d bytes\n", size);
+#endif
+
+ if (size > smpriv->slot_size)
+ return -EKEYREJECTED;
+
+ for (i = 0; i < ksdata->slot_count; i++) {
+ if (ksdata->slot[i].allocated == 0) {
+ ksdata->slot[i].allocated = 1;
+ (*slot) = i;
+#ifdef SM_DEBUG
+ dev_info(dev, "slot_alloc(): new slot %d allocated\n",
+ *slot);
+#endif
+ return 0;
+ }
+ }
+
+ return -ENOSPC;
+}
+EXPORT_SYMBOL(slot_alloc);
+
+int slot_dealloc(struct device *dev, u32 unit, u32 slot)
+{
+ struct caam_drv_private_sm *smpriv = dev_get_drvdata(dev);
+ struct keystore_data *ksdata = smpriv->pagedesc[unit].ksdata;
+ u8 __iomem *slotdata;
+
+#ifdef SM_DEBUG
+ dev_info(dev, "slot_dealloc(): releasing slot %d\n", slot);
+#endif
+ if (slot >= ksdata->slot_count)
+ return -EINVAL;
+ slotdata = ksdata->base_address + slot * smpriv->slot_size;
+
+ if (ksdata->slot[slot].allocated == 1) {
+ /* Forcibly overwrite the data from the keystore */
+ memset_io(ksdata->base_address + slot * smpriv->slot_size, 0,
+ smpriv->slot_size);
+
+ ksdata->slot[slot].allocated = 0;
+#ifdef SM_DEBUG
+ dev_info(dev, "slot_dealloc(): slot %d released\n", slot);
+#endif
+ return 0;
+ }
+
+ return -EINVAL;
+}
+EXPORT_SYMBOL(slot_dealloc);
+
+void *slot_get_address(struct device *dev, u32 unit, u32 slot)
+{
+ struct caam_drv_private_sm *smpriv = dev_get_drvdata(dev);
+ struct keystore_data *ksdata = smpriv->pagedesc[unit].ksdata;
+
+ if (slot >= ksdata->slot_count)
+ return NULL;
+
+#ifdef SM_DEBUG
+ dev_info(dev, "slot_get_address(): slot %d is 0x%08x\n", slot,
+ (u32)ksdata->base_address + slot * smpriv->slot_size);
+#endif
+
+ return ksdata->base_address + slot * smpriv->slot_size;
+}
+
+void *slot_get_physical(struct device *dev, u32 unit, u32 slot)
+{
+ struct caam_drv_private_sm *smpriv = dev_get_drvdata(dev);
+ struct keystore_data *ksdata = smpriv->pagedesc[unit].ksdata;
+
+ if (slot >= ksdata->slot_count)
+ return NULL;
+
+#ifdef SM_DEBUG
+ dev_info(dev, "slot_get_physical(): slot %d is 0x%08x\n", slot,
+ (u32)ksdata->phys_address + slot * smpriv->slot_size);
+#endif
+
+ return ksdata->phys_address + slot * smpriv->slot_size;
+}
+
+u32 slot_get_base(struct device *dev, u32 unit, u32 slot)
+{
+ struct caam_drv_private_sm *smpriv = dev_get_drvdata(dev);
+ struct keystore_data *ksdata = smpriv->pagedesc[unit].ksdata;
+
+ /*
+ * There could potentially be more than one secure partition object
+ * associated with this keystore. For now, there is just one.
+ */
+
+ (void)slot;
+
+#ifdef SM_DEBUG
+ dev_info(dev, "slot_get_base(): slot %d = 0x%08x\n",
+ slot, (u32)ksdata->base_address);
+#endif
+
+ return (uintptr_t)(ksdata->base_address);
+}
+
+u32 slot_get_offset(struct device *dev, u32 unit, u32 slot)
+{
+ struct caam_drv_private_sm *smpriv = dev_get_drvdata(dev);
+ struct keystore_data *ksdata = smpriv->pagedesc[unit].ksdata;
+
+ if (slot >= ksdata->slot_count)
+ return -EINVAL;
+
+#ifdef SM_DEBUG
+ dev_info(dev, "slot_get_offset(): slot %d = %d\n", slot,
+ slot * smpriv->slot_size);
+#endif
+
+ return slot * smpriv->slot_size;
+}
+
+u32 slot_get_slot_size(struct device *dev, u32 unit, u32 slot)
+{
+ struct caam_drv_private_sm *smpriv = dev_get_drvdata(dev);
+
+
+#ifdef SM_DEBUG
+ dev_info(dev, "slot_get_slot_size(): slot %d = %d\n", slot,
+ smpriv->slot_size);
+#endif
+ /* All slots are the same size in the default implementation */
+ return smpriv->slot_size;
+}
+
+
+
+int kso_init_data(struct device *dev, u32 unit)
+{
+ struct caam_drv_private_sm *smpriv = dev_get_drvdata(dev);
+ struct keystore_data *keystore_data = NULL;
+ u32 slot_count;
+ u32 keystore_data_size;
+
+ /*
+ * Calculate the required size of the keystore data structure, based
+ * on the number of keys that can fit in the partition.
+ */
+ slot_count = smpriv->page_size / smpriv->slot_size;
+#ifdef SM_DEBUG
+ dev_info(dev, "kso_init_data: %d slots initializing\n", slot_count);
+#endif
+
+ keystore_data_size = sizeof(struct keystore_data) +
+ slot_count *
+ sizeof(struct keystore_data_slot_info);
+
+ keystore_data = kzalloc(keystore_data_size, GFP_KERNEL);
+
+ if (!keystore_data)
+ return -ENOMEM;
+
+#ifdef SM_DEBUG
+ dev_info(dev, "kso_init_data: keystore data size = %d\n",
+ keystore_data_size);
+#endif
+
+ /*
+ * Place the slot information structure directly after the keystore data
+ * structure.
+ */
+ keystore_data->slot = (struct keystore_data_slot_info *)
+ (keystore_data + 1);
+ keystore_data->slot_count = slot_count;
+
+ smpriv->pagedesc[unit].ksdata = keystore_data;
+ smpriv->pagedesc[unit].ksdata->base_address =
+ smpriv->pagedesc[unit].pg_base;
+ smpriv->pagedesc[unit].ksdata->phys_address =
+ smpriv->pagedesc[unit].pg_phys;
+
+ return 0;
+}
+
+void kso_cleanup_data(struct device *dev, u32 unit)
+{
+ struct caam_drv_private_sm *smpriv = dev_get_drvdata(dev);
+ struct keystore_data *keystore_data = NULL;
+
+ if (smpriv->pagedesc[unit].ksdata != NULL)
+ keystore_data = smpriv->pagedesc[unit].ksdata;
+
+ /* Release the allocated keystore management data */
+ kfree(smpriv->pagedesc[unit].ksdata);
+
+ return;
+}
+
+
+
+/*
+ * Keystore management section
+ */
+
+void sm_init_keystore(struct device *dev)
+{
+ struct caam_drv_private_sm *smpriv = dev_get_drvdata(dev);
+
+ smpriv->data_init = kso_init_data;
+ smpriv->data_cleanup = kso_cleanup_data;
+ smpriv->slot_alloc = slot_alloc;
+ smpriv->slot_dealloc = slot_dealloc;
+ smpriv->slot_get_address = slot_get_address;
+ smpriv->slot_get_physical = slot_get_physical;
+ smpriv->slot_get_base = slot_get_base;
+ smpriv->slot_get_offset = slot_get_offset;
+ smpriv->slot_get_slot_size = slot_get_slot_size;
+#ifdef SM_DEBUG
+ dev_info(dev, "sm_init_keystore(): handlers installed\n");
+#endif
+}
+EXPORT_SYMBOL(sm_init_keystore);
+
+/* Return available pages/units */
+u32 sm_detect_keystore_units(struct device *dev)
+{
+ struct caam_drv_private_sm *smpriv = dev_get_drvdata(dev);
+
+ return smpriv->localpages;
+}
+EXPORT_SYMBOL(sm_detect_keystore_units);
+
+/*
+ * Do any keystore specific initializations
+ */
+int sm_establish_keystore(struct device *dev, u32 unit)
+{
+ struct caam_drv_private_sm *smpriv = dev_get_drvdata(dev);
+
+#ifdef SM_DEBUG
+ dev_info(dev, "sm_establish_keystore(): unit %d initializing\n", unit);
+#endif
+
+ if (smpriv->data_init == NULL)
+ return -EINVAL;
+
+ /* Call the data_init function for any user setup */
+ return smpriv->data_init(dev, unit);
+}
+EXPORT_SYMBOL(sm_establish_keystore);
+
+void sm_release_keystore(struct device *dev, u32 unit)
+{
+ struct caam_drv_private_sm *smpriv = dev_get_drvdata(dev);
+
+#ifdef SM_DEBUG
+ dev_info(dev, "sm_establish_keystore(): unit %d releasing\n", unit);
+#endif
+ if ((smpriv != NULL) && (smpriv->data_cleanup != NULL))
+ smpriv->data_cleanup(dev, unit);
+
+ return;
+}
+EXPORT_SYMBOL(sm_release_keystore);
+
+/*
+ * Subsequent interfacce (sm_keystore_*) forms the accessor interfacce to
+ * the keystore
+ */
+int sm_keystore_slot_alloc(struct device *dev, u32 unit, u32 size, u32 *slot)
+{
+ struct caam_drv_private_sm *smpriv = dev_get_drvdata(dev);
+ int retval = -EINVAL;
+
+ spin_lock(&smpriv->kslock);
+
+ if ((smpriv->slot_alloc == NULL) ||
+ (smpriv->pagedesc[unit].ksdata == NULL))
+ goto out;
+
+ retval = smpriv->slot_alloc(dev, unit, size, slot);
+
+out:
+ spin_unlock(&smpriv->kslock);
+ return retval;
+}
+EXPORT_SYMBOL(sm_keystore_slot_alloc);
+
+int sm_keystore_slot_dealloc(struct device *dev, u32 unit, u32 slot)
+{
+ struct caam_drv_private_sm *smpriv = dev_get_drvdata(dev);
+ int retval = -EINVAL;
+
+ spin_lock(&smpriv->kslock);
+
+ if ((smpriv->slot_alloc == NULL) ||
+ (smpriv->pagedesc[unit].ksdata == NULL))
+ goto out;
+
+ retval = smpriv->slot_dealloc(dev, unit, slot);
+out:
+ spin_unlock(&smpriv->kslock);
+ return retval;
+}
+EXPORT_SYMBOL(sm_keystore_slot_dealloc);
+
+int sm_keystore_slot_load(struct device *dev, u32 unit, u32 slot,
+ const u8 *key_data, u32 key_length)
+{
+ struct caam_drv_private_sm *smpriv = dev_get_drvdata(dev);
+ int retval = -EINVAL;
+ u32 slot_size;
+ u8 __iomem *slot_location;
+
+ spin_lock(&smpriv->kslock);
+
+ slot_size = smpriv->slot_get_slot_size(dev, unit, slot);
+
+ if (key_length > slot_size) {
+ retval = -EFBIG;
+ goto out;
+ }
+
+ slot_location = smpriv->slot_get_address(dev, unit, slot);
+
+ memcpy_toio(slot_location, key_data, key_length);
+
+ retval = 0;
+
+out:
+ spin_unlock(&smpriv->kslock);
+ return retval;
+}
+EXPORT_SYMBOL(sm_keystore_slot_load);
+
+int sm_keystore_slot_read(struct device *dev, u32 unit, u32 slot,
+ u32 key_length, u8 *key_data)
+{
+ struct caam_drv_private_sm *smpriv = dev_get_drvdata(dev);
+ int retval = -EINVAL;
+ u8 __iomem *slot_addr;
+ u32 slot_size;
+
+ spin_lock(&smpriv->kslock);
+
+ slot_addr = smpriv->slot_get_address(dev, unit, slot);
+ slot_size = smpriv->slot_get_slot_size(dev, unit, slot);
+
+ if (key_length > slot_size) {
+ retval = -EKEYREJECTED;
+ goto out;
+ }
+
+ memcpy_fromio(key_data, slot_addr, key_length);
+ retval = 0;
+
+out:
+ spin_unlock(&smpriv->kslock);
+ return retval;
+}
+EXPORT_SYMBOL(sm_keystore_slot_read);
+
+/*
+ * Blacken a clear key in a slot. Operates "in place".
+ * Limited to class 1 keys at the present time
+ */
+int sm_keystore_cover_key(struct device *dev, u32 unit, u32 slot,
+ u16 key_length, u8 keyauth)
+{
+ struct caam_drv_private_sm *smpriv = dev_get_drvdata(dev);
+ int retval = 0;
+ u8 __iomem *slotaddr;
+ void *slotphys;
+ u32 dsize, jstat;
+ u32 __iomem *coverdesc = NULL;
+
+ /* Get the address of the object in the slot */
+ slotaddr = (u8 *)smpriv->slot_get_address(dev, unit, slot);
+ slotphys = (u8 *)smpriv->slot_get_physical(dev, unit, slot);
+
+ dsize = blacken_key_jobdesc(&coverdesc, slotphys, key_length, keyauth);
+ if (!dsize)
+ return -ENOMEM;
+ jstat = sm_key_job(dev, coverdesc);
+ if (jstat)
+ retval = -EIO;
+
+ kfree(coverdesc);
+ return retval;
+}
+EXPORT_SYMBOL(sm_keystore_cover_key);
+
+/* Export a black/red key to a blob in external memory */
+int sm_keystore_slot_export(struct device *dev, u32 unit, u32 slot, u8 keycolor,
+ u8 keyauth, u8 *outbuf, u16 keylen, u8 *keymod)
+{
+ struct caam_drv_private_sm *smpriv = dev_get_drvdata(dev);
+ int retval = 0;
+ u8 __iomem *slotaddr, *lkeymod;
+ u8 __iomem *slotphys;
+ dma_addr_t keymod_dma, outbuf_dma;
+ u32 dsize, jstat;
+ u32 __iomem *encapdesc = NULL;
+ struct device *dev_for_dma_op;
+
+ /* Use the ring as device for DMA operations */
+ dev_for_dma_op = smpriv->smringdev;
+
+ /* Get the base address(es) of the specified slot */
+ slotaddr = (u8 *)smpriv->slot_get_address(dev, unit, slot);
+ slotphys = smpriv->slot_get_physical(dev, unit, slot);
+
+ /* Allocate memory for key modifier compatible with DMA */
+ lkeymod = kmalloc(SECMEM_KEYMOD_LEN, GFP_KERNEL | GFP_DMA);
+ if (!lkeymod) {
+ retval = (-ENOMEM);
+ goto exit;
+ }
+
+ /* Get DMA address for the key modifier */
+ keymod_dma = dma_map_single(dev_for_dma_op, lkeymod,
+ SECMEM_KEYMOD_LEN, DMA_TO_DEVICE);
+ if (dma_mapping_error(dev_for_dma_op, keymod_dma)) {
+ dev_err(dev, "unable to map keymod: %p\n", lkeymod);
+ retval = (-ENOMEM);
+ goto free_keymod;
+ }
+
+ /* Copy the keymod and synchronize the DMA */
+ memcpy(lkeymod, keymod, SECMEM_KEYMOD_LEN);
+ dma_sync_single_for_device(dev_for_dma_op, keymod_dma,
+ SECMEM_KEYMOD_LEN, DMA_TO_DEVICE);
+
+ /* Get DMA address for the destination */
+ outbuf_dma = dma_map_single(dev_for_dma_op, outbuf,
+ keylen + BLOB_OVERHEAD, DMA_FROM_DEVICE);
+ if (dma_mapping_error(dev_for_dma_op, outbuf_dma)) {
+ dev_err(dev, "unable to map outbuf: %p\n", outbuf);
+ retval = (-ENOMEM);
+ goto unmap_keymod;
+ }
+
+ /* Build the encapsulation job descriptor */
+ dsize = blob_encap_jobdesc(&encapdesc, keymod_dma, slotphys, outbuf_dma,
+ keylen, keycolor, SM_SECMEM, keyauth);
+ if (!dsize) {
+ dev_err(dev, "can't alloc an encapsulation descriptor\n");
+ retval = -ENOMEM;
+ goto unmap_outbuf;
+ }
+
+ /* Run the job */
+ jstat = sm_key_job(dev, encapdesc);
+ if (jstat) {
+ retval = (-EIO);
+ goto free_desc;
+ }
+
+ /* Synchronize the data received */
+ dma_sync_single_for_cpu(dev_for_dma_op, outbuf_dma,
+ keylen + BLOB_OVERHEAD, DMA_FROM_DEVICE);
+
+free_desc:
+ kfree(encapdesc);
+
+unmap_outbuf:
+ dma_unmap_single(dev_for_dma_op, outbuf_dma, keylen + BLOB_OVERHEAD,
+ DMA_FROM_DEVICE);
+
+unmap_keymod:
+ dma_unmap_single(dev_for_dma_op, keymod_dma, SECMEM_KEYMOD_LEN,
+ DMA_TO_DEVICE);
+
+free_keymod:
+ kfree(lkeymod);
+
+exit:
+ return retval;
+}
+EXPORT_SYMBOL(sm_keystore_slot_export);
+
+/* Import a black/red key from a blob residing in external memory */
+int sm_keystore_slot_import(struct device *dev, u32 unit, u32 slot, u8 keycolor,
+ u8 keyauth, u8 *inbuf, u16 keylen, u8 *keymod)
+{
+ struct caam_drv_private_sm *smpriv = dev_get_drvdata(dev);
+ int retval = 0;
+ u8 __iomem *slotaddr, *lkeymod;
+ u8 __iomem *slotphys;
+ dma_addr_t keymod_dma, inbuf_dma;
+ u32 dsize, jstat;
+ u32 __iomem *decapdesc = NULL;
+ struct device *dev_for_dma_op;
+
+ /* Use the ring as device for DMA operations */
+ dev_for_dma_op = smpriv->smringdev;
+
+ /* Get the base address(es) of the specified slot */
+ slotaddr = (u8 *)smpriv->slot_get_address(dev, unit, slot);
+ slotphys = smpriv->slot_get_physical(dev, unit, slot);
+
+ /* Allocate memory for key modifier compatible with DMA */
+ lkeymod = kmalloc(SECMEM_KEYMOD_LEN, GFP_KERNEL | GFP_DMA);
+ if (!lkeymod) {
+ retval = (-ENOMEM);
+ goto exit;
+ }
+
+ /* Get DMA address for the key modifier */
+ keymod_dma = dma_map_single(dev_for_dma_op, lkeymod,
+ SECMEM_KEYMOD_LEN, DMA_TO_DEVICE);
+ if (dma_mapping_error(dev_for_dma_op, keymod_dma)) {
+ dev_err(dev, "unable to map keymod: %p\n", lkeymod);
+ retval = (-ENOMEM);
+ goto free_keymod;
+ }
+
+ /* Copy the keymod and synchronize the DMA */
+ memcpy(lkeymod, keymod, SECMEM_KEYMOD_LEN);
+ dma_sync_single_for_device(dev_for_dma_op, keymod_dma,
+ SECMEM_KEYMOD_LEN, DMA_TO_DEVICE);
+
+ /* Get DMA address for the input */
+ inbuf_dma = dma_map_single(dev_for_dma_op, inbuf,
+ keylen + BLOB_OVERHEAD, DMA_TO_DEVICE);
+ if (dma_mapping_error(dev_for_dma_op, inbuf_dma)) {
+ dev_err(dev, "unable to map inbuf: %p\n", (void *)inbuf_dma);
+ retval = (-ENOMEM);
+ goto unmap_keymod;
+ }
+
+ /* synchronize the DMA */
+ dma_sync_single_for_device(dev_for_dma_op, inbuf_dma,
+ keylen + BLOB_OVERHEAD, DMA_TO_DEVICE);
+
+ /* Build the encapsulation job descriptor */
+ dsize = blob_decap_jobdesc(&decapdesc, keymod_dma, inbuf_dma, slotphys,
+ keylen, keycolor, SM_SECMEM, keyauth);
+ if (!dsize) {
+ dev_err(dev, "can't alloc a decapsulation descriptor\n");
+ retval = -ENOMEM;
+ goto unmap_inbuf;
+ }
+
+ /* Run the job */
+ jstat = sm_key_job(dev, decapdesc);
+
+ /*
+ * May want to expand upon error meanings a bit. Any CAAM status
+ * is reported as EIO, but we might want to look for something more
+ * meaningful for something like an ICV error on restore, otherwise
+ * the caller is left guessing.
+ */
+ if (jstat) {
+ retval = (-EIO);
+ goto free_desc;
+ }
+
+free_desc:
+ kfree(decapdesc);
+
+unmap_inbuf:
+ dma_unmap_single(dev_for_dma_op, inbuf_dma, keylen + BLOB_OVERHEAD,
+ DMA_TO_DEVICE);
+
+unmap_keymod:
+ dma_unmap_single(dev_for_dma_op, keymod_dma, SECMEM_KEYMOD_LEN,
+ DMA_TO_DEVICE);
+
+free_keymod:
+ kfree(lkeymod);
+
+exit:
+ return retval;
+}
+EXPORT_SYMBOL(sm_keystore_slot_import);
+
+/*
+ * Initialization/shutdown subsystem
+ * Assumes statically-invoked startup/shutdown from the controller driver
+ * for the present time, to be reworked when a device tree becomes
+ * available. This code will not modularize in present form.
+ *
+ * Also, simply uses ring 0 for execution at the present
+ */
+
+int caam_sm_startup(struct platform_device *pdev)
+{
+ struct device *ctrldev, *smdev;
+ struct caam_drv_private *ctrlpriv;
+ struct caam_drv_private_sm *smpriv;
+ struct caam_drv_private_jr *jrpriv; /* need this for reg page */
+ struct platform_device *sm_pdev;
+ struct sm_page_descriptor *lpagedesc;
+ u32 page, pgstat, lpagect, detectedpage, smvid, smpart;
+ int ret = 0;
+
+ struct device_node *np;
+ ctrldev = &pdev->dev;
+ ctrlpriv = dev_get_drvdata(ctrldev);
+
+ /*
+ * If ctrlpriv is NULL, it's probably because the caam driver wasn't
+ * properly initialized (e.g. RNG4 init failed). Thus, bail out here.
+ */
+ if (!ctrlpriv) {
+ ret = -ENODEV;
+ goto exit;
+ }
+
+ /*
+ * Set up the private block for secure memory
+ * Only one instance is possible
+ */
+ smpriv = kzalloc(sizeof(struct caam_drv_private_sm), GFP_KERNEL);
+ if (smpriv == NULL) {
+ dev_err(ctrldev, "can't alloc private mem for secure memory\n");
+ ret = -ENOMEM;
+ goto exit;
+ }
+ smpriv->parentdev = ctrldev; /* copy of parent dev is handy */
+ spin_lock_init(&smpriv->kslock);
+
+ /* Create the dev */
+ np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-caam-sm");
+ if (np)
+ of_node_clear_flag(np, OF_POPULATED);
+ sm_pdev = of_platform_device_create(np, "caam_sm", ctrldev);
+
+ if (sm_pdev == NULL) {
+ ret = -EINVAL;
+ goto free_smpriv;
+ }
+
+ /* Save a pointer to the platform device for Secure Memory */
+ smpriv->sm_pdev = sm_pdev;
+ smdev = &sm_pdev->dev;
+ dev_set_drvdata(smdev, smpriv);
+ ctrlpriv->smdev = smdev;
+
+ /* Set the Secure Memory Register Map Version */
+ if (ctrlpriv->has_seco) {
+ int i = ctrlpriv->first_jr_index;
+
+ smvid = rd_reg32(&ctrlpriv->jr[i]->perfmon.smvid);
+ smpart = rd_reg32(&ctrlpriv->jr[i]->perfmon.smpart);
+
+ } else {
+ smvid = rd_reg32(&ctrlpriv->ctrl->perfmon.smvid);
+ smpart = rd_reg32(&ctrlpriv->ctrl->perfmon.smpart);
+
+ }
+
+ if (smvid < SMVID_V2)
+ smpriv->sm_reg_offset = SM_V1_OFFSET;
+ else
+ smpriv->sm_reg_offset = SM_V2_OFFSET;
+
+ /*
+ * Collect configuration limit data for reference
+ * This batch comes from the partition data/vid registers in perfmon
+ */
+ smpriv->max_pages = ((smpart & SMPART_MAX_NUMPG_MASK) >>
+ SMPART_MAX_NUMPG_SHIFT) + 1;
+ smpriv->top_partition = ((smpart & SMPART_MAX_PNUM_MASK) >>
+ SMPART_MAX_PNUM_SHIFT) + 1;
+ smpriv->top_page = ((smpart & SMPART_MAX_PG_MASK) >>
+ SMPART_MAX_PG_SHIFT) + 1;
+ smpriv->page_size = 1024 << ((smvid & SMVID_PG_SIZE_MASK) >>
+ SMVID_PG_SIZE_SHIFT);
+ smpriv->slot_size = 1 << CONFIG_CRYPTO_DEV_FSL_CAAM_SM_SLOTSIZE;
+
+#ifdef SM_DEBUG
+ dev_info(smdev, "max pages = %d, top partition = %d\n",
+ smpriv->max_pages, smpriv->top_partition);
+ dev_info(smdev, "top page = %d, page size = %d (total = %d)\n",
+ smpriv->top_page, smpriv->page_size,
+ smpriv->top_page * smpriv->page_size);
+ dev_info(smdev, "selected slot size = %d\n", smpriv->slot_size);
+#endif
+
+ /*
+ * Now probe for partitions/pages to which we have access. Note that
+ * these have likely been set up by a bootloader or platform
+ * provisioning application, so we have to assume that we "inherit"
+ * a configuration and work within the constraints of what it might be.
+ *
+ * Assume use of the zeroth ring in the present iteration (until
+ * we can divorce the controller and ring drivers, and then assign
+ * an SM instance to any ring instance).
+ */
+ smpriv->smringdev = caam_jr_alloc();
+ if (!smpriv->smringdev) {
+ dev_err(smdev, "Device for job ring not created\n");
+ ret = -ENODEV;
+ goto unregister_smpdev;
+ }
+
+ jrpriv = dev_get_drvdata(smpriv->smringdev);
+ lpagect = 0;
+ pgstat = 0;
+ lpagedesc = kzalloc(sizeof(struct sm_page_descriptor)
+ * smpriv->max_pages, GFP_KERNEL);
+ if (lpagedesc == NULL) {
+ ret = -ENOMEM;
+ goto free_smringdev;
+ }
+
+ for (page = 0; page < smpriv->max_pages; page++) {
+ u32 page_ownership;
+
+ if (sm_send_cmd(smpriv, jrpriv,
+ ((page << SMC_PAGE_SHIFT) & SMC_PAGE_MASK) |
+ (SMC_CMD_PAGE_INQUIRY & SMC_CMD_MASK),
+ &pgstat)) {
+ ret = -EINVAL;
+ goto free_lpagedesc;
+ }
+
+ page_ownership = (pgstat & SMCS_PGWON_MASK) >> SMCS_PGOWN_SHIFT;
+ if ((page_ownership == SMCS_PGOWN_OWNED)
+ || (page_ownership == SMCS_PGOWN_NOOWN)) {
+ /* page allocated */
+ lpagedesc[page].phys_pagenum =
+ (pgstat & SMCS_PAGE_MASK) >> SMCS_PAGE_SHIFT;
+ lpagedesc[page].own_part =
+ (pgstat & SMCS_PART_SHIFT) >> SMCS_PART_MASK;
+ lpagedesc[page].pg_base = (u8 *)ctrlpriv->sm_base +
+ (smpriv->page_size * page);
+ if (ctrlpriv->has_seco) {
+/* FIXME: get different addresses viewed by CPU and CAAM from
+ * platform property
+ */
+ lpagedesc[page].pg_phys = (u8 *)0x20800000 +
+ (smpriv->page_size * page);
+ } else {
+ lpagedesc[page].pg_phys =
+ (u8 *) ctrlpriv->sm_phy +
+ (smpriv->page_size * page);
+ }
+ lpagect++;
+#ifdef SM_DEBUG
+ dev_info(smdev,
+ "physical page %d, owning partition = %d\n",
+ lpagedesc[page].phys_pagenum,
+ lpagedesc[page].own_part);
+#endif
+ }
+ }
+
+ smpriv->pagedesc = kzalloc(sizeof(struct sm_page_descriptor) * lpagect,
+ GFP_KERNEL);
+ if (smpriv->pagedesc == NULL) {
+ ret = -ENOMEM;
+ goto free_lpagedesc;
+ }
+ smpriv->localpages = lpagect;
+
+ detectedpage = 0;
+ for (page = 0; page < smpriv->max_pages; page++) {
+ if (lpagedesc[page].pg_base != NULL) { /* e.g. live entry */
+ memcpy(&smpriv->pagedesc[detectedpage],
+ &lpagedesc[page],
+ sizeof(struct sm_page_descriptor));
+#ifdef SM_DEBUG_CONT
+ sm_show_page(smdev, &smpriv->pagedesc[detectedpage]);
+#endif
+ detectedpage++;
+ }
+ }
+
+ kfree(lpagedesc);
+
+ sm_init_keystore(smdev);
+
+ goto exit;
+
+free_lpagedesc:
+ kfree(lpagedesc);
+free_smringdev:
+ caam_jr_free(smpriv->smringdev);
+unregister_smpdev:
+ of_device_unregister(smpriv->sm_pdev);
+free_smpriv:
+ kfree(smpriv);
+
+exit:
+ return ret;
+}
+
+void caam_sm_shutdown(struct platform_device *pdev)
+{
+ struct device *ctrldev, *smdev;
+ struct caam_drv_private *priv;
+ struct caam_drv_private_sm *smpriv;
+
+ ctrldev = &pdev->dev;
+ priv = dev_get_drvdata(ctrldev);
+ smdev = priv->smdev;
+
+ /* Return if resource not initialized by startup */
+ if (smdev == NULL)
+ return;
+
+ smpriv = dev_get_drvdata(smdev);
+
+ caam_jr_free(smpriv->smringdev);
+
+ /* Remove Secure Memory Platform Device */
+ of_device_unregister(smpriv->sm_pdev);
+
+ kfree(smpriv->pagedesc);
+ kfree(smpriv);
+}
+EXPORT_SYMBOL(caam_sm_shutdown);
+
+static void __exit caam_sm_exit(void)
+{
+ struct device_node *dev_node;
+ struct platform_device *pdev;
+
+ dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec-v4.0");
+ if (!dev_node) {
+ dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec4.0");
+ if (!dev_node)
+ return;
+ }
+
+ pdev = of_find_device_by_node(dev_node);
+ if (!pdev)
+ return;
+
+ of_node_put(dev_node);
+
+ caam_sm_shutdown(pdev);
+
+ return;
+}
+
+static int __init caam_sm_init(void)
+{
+ struct device_node *dev_node;
+ struct platform_device *pdev;
+
+ /*
+ * Do of_find_compatible_node() then of_find_device_by_node()
+ * once a functional device tree is available
+ */
+ dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec-v4.0");
+ if (!dev_node) {
+ dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec4.0");
+ if (!dev_node)
+ return -ENODEV;
+ }
+
+ pdev = of_find_device_by_node(dev_node);
+ if (!pdev)
+ return -ENODEV;
+
+ of_node_get(dev_node);
+
+ caam_sm_startup(pdev);
+
+ return 0;
+}
+
+module_init(caam_sm_init);
+module_exit(caam_sm_exit);
+
+MODULE_LICENSE("Dual BSD/GPL");
+MODULE_DESCRIPTION("FSL CAAM Secure Memory / Keystore");
+MODULE_AUTHOR("Freescale Semiconductor - NMSG/MAD");
diff --git a/drivers/crypto/caam/sm_test.c b/drivers/crypto/caam/sm_test.c
new file mode 100644
index 000000000000..9a366e8c02a3
--- /dev/null
+++ b/drivers/crypto/caam/sm_test.c
@@ -0,0 +1,527 @@
+/*
+ * Secure Memory / Keystore Exemplification Module
+ * Copyright (C) 2012-2015 Freescale Semiconductor, Inc. All Rights Reserved
+ *
+ * This module has been overloaded as an example to show:
+ * - Secure memory subsystem initialization/shutdown
+ * - Allocation/deallocation of "slots" in a secure memory page
+ * - Loading and unloading of key material into slots
+ * - Covering of secure memory objects into "black keys" (ECB only at present)
+ * - Verification of key covering (by differentiation only)
+ * - Exportation of keys into secure memory blobs (with display of result)
+ * - Importation of keys from secure memory blobs (with display of result)
+ * - Verification of re-imported keys where possible.
+ *
+ * The module does not show the use of key objects as working key register
+ * source material at this time.
+ *
+ * This module can use a substantial amount of refactoring, which may occur
+ * after the API gets some mileage. Furthermore, expect this module to
+ * eventually disappear once the API is integrated into "real" software.
+ */
+
+#include "compat.h"
+#include "regs.h"
+#include "intern.h"
+#include "desc.h"
+#include "error.h"
+#include "jr.h"
+#include "sm.h"
+
+/* Fixed known pattern for a key modifier */
+static u8 skeymod[] = {
+ 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08,
+ 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00
+};
+
+/* Fixed known pattern for a key */
+static u8 clrkey[] = {
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x0f, 0x06, 0x07,
+ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+ 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
+ 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
+ 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+ 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
+ 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
+ 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
+ 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
+ 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
+ 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
+ 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
+ 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
+ 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
+ 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
+ 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
+ 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
+ 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
+ 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
+ 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
+ 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
+ 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
+ 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
+ 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
+ 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
+ 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
+ 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
+ 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
+ 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
+ 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
+};
+
+static void key_display(struct device *dev, u8 *label, u16 size, u8 *key)
+{
+ unsigned i;
+
+ dev_info(dev, label);
+ for (i = 0; i < size; i += 8)
+ dev_info(dev,
+ "[%04d] %02x %02x %02x %02x %02x %02x %02x %02x\n",
+ i, key[i], key[i + 1], key[i + 2], key[i + 3],
+ key[i + 4], key[i + 5], key[i + 6], key[i + 7]);
+}
+
+int caam_sm_example_init(struct platform_device *pdev)
+{
+ struct device *ctrldev, *ksdev;
+ struct caam_drv_private *ctrlpriv;
+ struct caam_drv_private_sm *kspriv;
+ u32 unit, units;
+ int rtnval = 0;
+ u8 clrkey8[8], clrkey16[16], clrkey24[24], clrkey32[32];
+ u8 blkkey8[AES_BLOCK_PAD(8)], blkkey16[AES_BLOCK_PAD(16)];
+ u8 blkkey24[AES_BLOCK_PAD(24)], blkkey32[AES_BLOCK_PAD(32)];
+ u8 rstkey8[AES_BLOCK_PAD(8)], rstkey16[AES_BLOCK_PAD(16)];
+ u8 rstkey24[AES_BLOCK_PAD(24)], rstkey32[AES_BLOCK_PAD(32)];
+ u8 __iomem *blob8, *blob16, *blob24, *blob32;
+ u32 keyslot8, keyslot16, keyslot24, keyslot32 = 0;
+
+ blob8 = blob16 = blob24 = blob32 = NULL;
+
+ /*
+ * 3.5.x and later revs for MX6 should be able to ditch this
+ * and detect via dts property
+ */
+ ctrldev = &pdev->dev;
+ ctrlpriv = dev_get_drvdata(ctrldev);
+
+ /*
+ * If ctrlpriv is NULL, it's probably because the caam driver wasn't
+ * properly initialized (e.g. RNG4 init failed). Thus, bail out here.
+ */
+ if (!ctrlpriv)
+ return -ENODEV;
+
+ ksdev = ctrlpriv->smdev;
+ kspriv = dev_get_drvdata(ksdev);
+ if (kspriv == NULL)
+ return -ENODEV;
+
+ /* What keystores are available ? */
+ units = sm_detect_keystore_units(ksdev);
+ if (!units)
+ dev_err(ksdev, "blkkey_ex: no keystore units available\n");
+
+ /*
+ * MX6 bootloader stores some stuff in unit 0, so let's
+ * use 1 or above
+ */
+ if (units < 2) {
+ dev_err(ksdev, "blkkey_ex: insufficient keystore units\n");
+ return -ENODEV;
+ }
+ unit = 1;
+
+ dev_info(ksdev, "blkkey_ex: %d keystore units available\n", units);
+
+ /* Initialize/Establish Keystore */
+ sm_establish_keystore(ksdev, unit); /* Initalize store in #1 */
+
+ /*
+ * Now let's set up buffers for blobs in DMA-able memory. All are
+ * larger than need to be so that blob size can be seen.
+ */
+ blob8 = kzalloc(128, GFP_KERNEL | GFP_DMA);
+ blob16 = kzalloc(128, GFP_KERNEL | GFP_DMA);
+ blob24 = kzalloc(128, GFP_KERNEL | GFP_DMA);
+ blob32 = kzalloc(128, GFP_KERNEL | GFP_DMA);
+
+ if ((blob8 == NULL) || (blob16 == NULL) || (blob24 == NULL) ||
+ (blob32 == NULL)) {
+ rtnval = -ENOMEM;
+ dev_err(ksdev, "blkkey_ex: can't get blob buffers\n");
+ goto freemem;
+ }
+
+ /* Initialize clear keys with a known and recognizable pattern */
+ memcpy(clrkey8, clrkey, 8);
+ memcpy(clrkey16, clrkey, 16);
+ memcpy(clrkey24, clrkey, 24);
+ memcpy(clrkey32, clrkey, 32);
+
+ memset(blkkey8, 0, AES_BLOCK_PAD(8));
+ memset(blkkey16, 0, AES_BLOCK_PAD(16));
+ memset(blkkey24, 0, AES_BLOCK_PAD(24));
+ memset(blkkey32, 0, AES_BLOCK_PAD(32));
+
+ memset(rstkey8, 0, AES_BLOCK_PAD(8));
+ memset(rstkey16, 0, AES_BLOCK_PAD(16));
+ memset(rstkey24, 0, AES_BLOCK_PAD(24));
+ memset(rstkey32, 0, AES_BLOCK_PAD(32));
+
+ /*
+ * Allocate keyslots. Since we're going to blacken keys in-place,
+ * we want slots big enough to pad out to the next larger AES blocksize
+ * so pad them out.
+ */
+ if (sm_keystore_slot_alloc(ksdev, unit, AES_BLOCK_PAD(8), &keyslot8))
+ goto freemem;
+
+ if (sm_keystore_slot_alloc(ksdev, unit, AES_BLOCK_PAD(16), &keyslot16))
+ goto dealloc_slot8;
+
+ if (sm_keystore_slot_alloc(ksdev, unit, AES_BLOCK_PAD(24), &keyslot24))
+ goto dealloc_slot16;
+
+ if (sm_keystore_slot_alloc(ksdev, unit, AES_BLOCK_PAD(32), &keyslot32))
+ goto dealloc_slot24;
+
+
+ /* Now load clear key data into the newly allocated slots */
+ if (sm_keystore_slot_load(ksdev, unit, keyslot8, clrkey8, 8))
+ goto dealloc;
+
+ if (sm_keystore_slot_load(ksdev, unit, keyslot16, clrkey16, 16))
+ goto dealloc;
+
+ if (sm_keystore_slot_load(ksdev, unit, keyslot24, clrkey24, 24))
+ goto dealloc;
+
+ if (sm_keystore_slot_load(ksdev, unit, keyslot32, clrkey32, 32))
+ goto dealloc;
+
+ /*
+ * All cleartext keys are loaded into slots (in an unprotected
+ * partition at this time)
+ *
+ * Cover keys in-place
+ */
+ if (sm_keystore_cover_key(ksdev, unit, keyslot8, 8, KEY_COVER_ECB)) {
+ dev_info(ksdev, "blkkey_ex: can't cover 64-bit key\n");
+ goto dealloc;
+ }
+
+ if (sm_keystore_cover_key(ksdev, unit, keyslot16, 16, KEY_COVER_ECB)) {
+ dev_info(ksdev, "blkkey_ex: can't cover 128-bit key\n");
+ goto dealloc;
+ }
+
+ if (sm_keystore_cover_key(ksdev, unit, keyslot24, 24, KEY_COVER_ECB)) {
+ dev_info(ksdev, "blkkey_ex: can't cover 192-bit key\n");
+ goto dealloc;
+ }
+
+ if (sm_keystore_cover_key(ksdev, unit, keyslot32, 32, KEY_COVER_ECB)) {
+ dev_info(ksdev, "blkkey_ex: can't cover 256-bit key\n");
+ goto dealloc;
+ }
+
+ /*
+ * Keys should be covered and appear sufficiently "random"
+ * as a result of the covering (blackening) process. Assuming
+ * non-secure mode, read them back out for examination; they should
+ * appear as random data, completely differing from the clear
+ * inputs. So, this will read them back from secure memory and
+ * compare them. If they match the clear key, then the covering
+ * operation didn't occur.
+ */
+
+ if (sm_keystore_slot_read(ksdev, unit, keyslot8, AES_BLOCK_PAD(8),
+ blkkey8)) {
+ dev_info(ksdev, "blkkey_ex: can't read 64-bit black key\n");
+ goto dealloc;
+ }
+
+ if (sm_keystore_slot_read(ksdev, unit, keyslot16, AES_BLOCK_PAD(16),
+ blkkey16)) {
+ dev_info(ksdev, "blkkey_ex: can't read 128-bit black key\n");
+ goto dealloc;
+ }
+
+ if (sm_keystore_slot_read(ksdev, unit, keyslot24, AES_BLOCK_PAD(24),
+ blkkey24)) {
+ dev_info(ksdev, "blkkey_ex: can't read 192-bit black key\n");
+ goto dealloc;
+ }
+
+ if (sm_keystore_slot_read(ksdev, unit, keyslot32, AES_BLOCK_PAD(32),
+ blkkey32)) {
+ dev_info(ksdev, "blkkey_ex: can't read 256-bit black key\n");
+ goto dealloc;
+ }
+
+
+ if (!memcmp(blkkey8, clrkey8, 8)) {
+ dev_info(ksdev, "blkkey_ex: 64-bit key cover failed\n");
+ goto dealloc;
+ }
+
+ if (!memcmp(blkkey16, clrkey16, 16)) {
+ dev_info(ksdev, "blkkey_ex: 128-bit key cover failed\n");
+ goto dealloc;
+ }
+
+ if (!memcmp(blkkey24, clrkey24, 24)) {
+ dev_info(ksdev, "blkkey_ex: 192-bit key cover failed\n");
+ goto dealloc;
+ }
+
+ if (!memcmp(blkkey32, clrkey32, 32)) {
+ dev_info(ksdev, "blkkey_ex: 256-bit key cover failed\n");
+ goto dealloc;
+ }
+
+
+ key_display(ksdev, "64-bit clear key:", 8, clrkey8);
+ key_display(ksdev, "64-bit black key:", AES_BLOCK_PAD(8), blkkey8);
+
+ key_display(ksdev, "128-bit clear key:", 16, clrkey16);
+ key_display(ksdev, "128-bit black key:", AES_BLOCK_PAD(16), blkkey16);
+
+ key_display(ksdev, "192-bit clear key:", 24, clrkey24);
+ key_display(ksdev, "192-bit black key:", AES_BLOCK_PAD(24), blkkey24);
+
+ key_display(ksdev, "256-bit clear key:", 32, clrkey32);
+ key_display(ksdev, "256-bit black key:", AES_BLOCK_PAD(32), blkkey32);
+
+ /*
+ * Now encapsulate all keys as SM blobs out to external memory
+ * Blobs will appear as random-looking blocks of data different
+ * from the original source key, and 48 bytes longer than the
+ * original key, to account for the extra data encapsulated within.
+ */
+ key_display(ksdev, "64-bit unwritten blob:", 96, blob8);
+ key_display(ksdev, "128-bit unwritten blob:", 96, blob16);
+ key_display(ksdev, "196-bit unwritten blob:", 96, blob24);
+ key_display(ksdev, "256-bit unwritten blob:", 96, blob32);
+
+ if (sm_keystore_slot_export(ksdev, unit, keyslot8, BLACK_KEY,
+ KEY_COVER_ECB, blob8, 8, skeymod)) {
+ dev_info(ksdev, "blkkey_ex: can't encapsulate 64-bit key\n");
+ goto dealloc;
+ }
+
+ if (sm_keystore_slot_export(ksdev, unit, keyslot16, BLACK_KEY,
+ KEY_COVER_ECB, blob16, 16, skeymod)) {
+ dev_info(ksdev, "blkkey_ex: can't encapsulate 128-bit key\n");
+ goto dealloc;
+ }
+
+ if (sm_keystore_slot_export(ksdev, unit, keyslot24, BLACK_KEY,
+ KEY_COVER_ECB, blob24, 24, skeymod)) {
+ dev_info(ksdev, "blkkey_ex: can't encapsulate 192-bit key\n");
+ goto dealloc;
+ }
+
+ if (sm_keystore_slot_export(ksdev, unit, keyslot32, BLACK_KEY,
+ KEY_COVER_ECB, blob32, 32, skeymod)) {
+ dev_info(ksdev, "blkkey_ex: can't encapsulate 256-bit key\n");
+ goto dealloc;
+ }
+
+ key_display(ksdev, "64-bit black key in blob:", 96, blob8);
+ key_display(ksdev, "128-bit black key in blob:", 96, blob16);
+ key_display(ksdev, "192-bit black key in blob:", 96, blob24);
+ key_display(ksdev, "256-bit black key in blob:", 96, blob32);
+
+ /*
+ * Now re-import black keys from secure-memory blobs stored
+ * in general memory from the previous operation. Since we are
+ * working with black keys, and since power has not cycled, the
+ * restored black keys should match the original blackened keys
+ * (this would not be true if the blobs were save in some non-volatile
+ * store, and power was cycled between the save and restore)
+ */
+ if (sm_keystore_slot_import(ksdev, unit, keyslot8, BLACK_KEY,
+ KEY_COVER_ECB, blob8, 8, skeymod)) {
+ dev_info(ksdev, "blkkey_ex: can't decapsulate 64-bit blob\n");
+ goto dealloc;
+ }
+
+ if (sm_keystore_slot_import(ksdev, unit, keyslot16, BLACK_KEY,
+ KEY_COVER_ECB, blob16, 16, skeymod)) {
+ dev_info(ksdev, "blkkey_ex: can't decapsulate 128-bit blob\n");
+ goto dealloc;
+ }
+
+ if (sm_keystore_slot_import(ksdev, unit, keyslot24, BLACK_KEY,
+ KEY_COVER_ECB, blob24, 24, skeymod)) {
+ dev_info(ksdev, "blkkey_ex: can't decapsulate 196-bit blob\n");
+ goto dealloc;
+ }
+
+ if (sm_keystore_slot_import(ksdev, unit, keyslot32, BLACK_KEY,
+ KEY_COVER_ECB, blob32, 32, skeymod)) {
+ dev_info(ksdev, "blkkey_ex: can't decapsulate 256-bit blob\n");
+ goto dealloc;
+ }
+
+
+ /*
+ * Blobs are now restored as black keys. Read those black keys back
+ * for a comparison with the original black key, they should match
+ */
+ if (sm_keystore_slot_read(ksdev, unit, keyslot8, AES_BLOCK_PAD(8),
+ rstkey8)) {
+ dev_info(ksdev,
+ "blkkey_ex: can't read restored 64-bit black key\n");
+ goto dealloc;
+ }
+
+ if (sm_keystore_slot_read(ksdev, unit, keyslot16, AES_BLOCK_PAD(16),
+ rstkey16)) {
+ dev_info(ksdev,
+ "blkkey_ex: can't read restored 128-bit black key\n");
+ goto dealloc;
+ }
+
+ if (sm_keystore_slot_read(ksdev, unit, keyslot24, AES_BLOCK_PAD(24),
+ rstkey24)) {
+ dev_info(ksdev,
+ "blkkey_ex: can't read restored 196-bit black key\n");
+ goto dealloc;
+ }
+
+ if (sm_keystore_slot_read(ksdev, unit, keyslot32, AES_BLOCK_PAD(32),
+ rstkey32)) {
+ dev_info(ksdev,
+ "blkkey_ex: can't read restored 256-bit black key\n");
+ goto dealloc;
+ }
+
+ key_display(ksdev, "restored 64-bit black key:", AES_BLOCK_PAD(8),
+ rstkey8);
+ key_display(ksdev, "restored 128-bit black key:", AES_BLOCK_PAD(16),
+ rstkey16);
+ key_display(ksdev, "restored 192-bit black key:", AES_BLOCK_PAD(24),
+ rstkey24);
+ key_display(ksdev, "restored 256-bit black key:", AES_BLOCK_PAD(32),
+ rstkey32);
+
+ /*
+ * Compare the restored black keys with the original blackened keys
+ * As long as we're operating within the same power cycle, a black key
+ * restored from a blob should match the original black key IF the
+ * key happens to be of a size that matches a multiple of the AES
+ * blocksize. Any key that is padded to fill the block size will not
+ * match, excepting a key that exceeds a block; only the first full
+ * blocks will match (assuming ECB).
+ *
+ * Therefore, compare the 16 and 32 bit keys, they should match.
+ * The 24 bit key can only match within the first 16 byte block.
+ */
+
+ if (memcmp(rstkey16, blkkey16, AES_BLOCK_PAD(16))) {
+ dev_info(ksdev, "blkkey_ex: 128-bit restored key mismatch\n");
+ rtnval--;
+ }
+
+ /* Only first AES block will match, remainder subject to padding */
+ if (memcmp(rstkey24, blkkey24, 16)) {
+ dev_info(ksdev, "blkkey_ex: 192-bit restored key mismatch\n");
+ rtnval--;
+ }
+
+ if (memcmp(rstkey32, blkkey32, AES_BLOCK_PAD(32))) {
+ dev_info(ksdev, "blkkey_ex: 256-bit restored key mismatch\n");
+ rtnval--;
+ }
+
+
+ /* Remove keys from keystore */
+dealloc:
+ sm_keystore_slot_dealloc(ksdev, unit, keyslot32);
+dealloc_slot24:
+ sm_keystore_slot_dealloc(ksdev, unit, keyslot24);
+dealloc_slot16:
+ sm_keystore_slot_dealloc(ksdev, unit, keyslot16);
+dealloc_slot8:
+ sm_keystore_slot_dealloc(ksdev, unit, keyslot8);
+
+ /* Free resources */
+freemem:
+ kfree(blob8);
+ kfree(blob16);
+ kfree(blob24);
+ kfree(blob32);
+
+ /* Disconnect from keystore and leave */
+ sm_release_keystore(ksdev, unit);
+
+ return rtnval;
+}
+EXPORT_SYMBOL(caam_sm_example_init);
+
+void caam_sm_example_shutdown(void)
+{
+ /* unused in present version */
+ struct device_node *dev_node;
+ struct platform_device *pdev;
+
+ /*
+ * Do of_find_compatible_node() then of_find_device_by_node()
+ * once a functional device tree is available
+ */
+ dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec-v4.0");
+ if (!dev_node) {
+ dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec4.0");
+ if (!dev_node)
+ return;
+ }
+
+ pdev = of_find_device_by_node(dev_node);
+ if (!pdev)
+ return;
+
+ of_node_get(dev_node);
+
+}
+
+static int __init caam_sm_test_init(void)
+{
+ struct device_node *dev_node;
+ struct platform_device *pdev;
+
+ /*
+ * Do of_find_compatible_node() then of_find_device_by_node()
+ * once a functional device tree is available
+ */
+ dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec-v4.0");
+ if (!dev_node) {
+ dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec4.0");
+ if (!dev_node)
+ return -ENODEV;
+ }
+
+ pdev = of_find_device_by_node(dev_node);
+ if (!pdev)
+ return -ENODEV;
+
+ of_node_put(dev_node);
+
+ caam_sm_example_init(pdev);
+
+ return 0;
+}
+
+
+/* Module-based initialization needs to wait for dev tree */
+#ifdef CONFIG_OF
+module_init(caam_sm_test_init);
+module_exit(caam_sm_example_shutdown);
+
+MODULE_LICENSE("Dual BSD/GPL");
+MODULE_DESCRIPTION("FSL CAAM Black Key Usage Example");
+MODULE_AUTHOR("Freescale Semiconductor - NMSG/MAD");
+#endif
diff --git a/drivers/crypto/caam/snvsregs.h b/drivers/crypto/caam/snvsregs.h
new file mode 100644
index 000000000000..eef6b8930db5
--- /dev/null
+++ b/drivers/crypto/caam/snvsregs.h
@@ -0,0 +1,237 @@
+/*
+ * SNVS hardware register-level view
+ *
+ * Copyright (C) 2012-2015 Freescale Semiconductor, Inc., All Rights Reserved
+ */
+
+#ifndef SNVSREGS_H
+#define SNVSREGS_H
+
+#include <linux/types.h>
+#include <linux/io.h>
+
+/*
+ * SNVS High Power Domain
+ * Includes security violations, HA counter, RTC, alarm
+ */
+struct snvs_hp {
+ u32 lock; /* HPLR - HP Lock */
+ u32 cmd; /* HPCOMR - HP Command */
+ u32 ctl; /* HPCR - HP Control */
+ u32 secvio_intcfg; /* HPSICR - Security Violation Int Config */
+ u32 secvio_ctl; /* HPSVCR - Security Violation Control */
+ u32 status; /* HPSR - HP Status */
+ u32 secvio_status; /* HPSVSR - Security Violation Status */
+ u32 ha_counteriv; /* High Assurance Counter IV */
+ u32 ha_counter; /* High Assurance Counter */
+ u32 rtc_msb; /* Real Time Clock/Counter MSB */
+ u32 rtc_lsb; /* Real Time Counter LSB */
+ u32 time_alarm_msb; /* Time Alarm MSB */
+ u32 time_alarm_lsb; /* Time Alarm LSB */
+};
+
+#define HP_LOCK_HAC_LCK 0x00040000
+#define HP_LOCK_HPSICR_LCK 0x00020000
+#define HP_LOCK_HPSVCR_LCK 0x00010000
+#define HP_LOCK_MKEYSEL_LCK 0x00000200
+#define HP_LOCK_TAMPCFG_LCK 0x00000100
+#define HP_LOCK_TAMPFLT_LCK 0x00000080
+#define HP_LOCK_SECVIO_LCK 0x00000040
+#define HP_LOCK_GENP_LCK 0x00000020
+#define HP_LOCK_MONOCTR_LCK 0x00000010
+#define HP_LOCK_CALIB_LCK 0x00000008
+#define HP_LOCK_SRTC_LCK 0x00000004
+#define HP_LOCK_ZMK_RD_LCK 0x00000002
+#define HP_LOCK_ZMK_WT_LCK 0x00000001
+
+#define HP_CMD_NONPRIV_AXS 0x80000000
+#define HP_CMD_HAC_STOP 0x00080000
+#define HP_CMD_HAC_CLEAR 0x00040000
+#define HP_CMD_HAC_LOAD 0x00020000
+#define HP_CMD_HAC_CFG_EN 0x00010000
+#define HP_CMD_SNVS_MSTR_KEY 0x00002000
+#define HP_CMD_PROG_ZMK 0x00001000
+#define HP_CMD_SW_LPSV 0x00000400
+#define HP_CMD_SW_FSV 0x00000200
+#define HP_CMD_SW_SV 0x00000100
+#define HP_CMD_LP_SWR_DIS 0x00000020
+#define HP_CMD_LP_SWR 0x00000010
+#define HP_CMD_SSM_SFNS_DIS 0x00000004
+#define HP_CMD_SSM_ST_DIS 0x00000002
+#define HP_CMD_SMM_ST 0x00000001
+
+#define HP_CTL_TIME_SYNC 0x00010000
+#define HP_CTL_CAL_VAL_SHIFT 10
+#define HP_CTL_CAL_VAL_MASK (0x1f << HP_CTL_CALIB_SHIFT)
+#define HP_CTL_CALIB_EN 0x00000100
+#define HP_CTL_PI_FREQ_SHIFT 4
+#define HP_CTL_PI_FREQ_MASK (0xf << HP_CTL_PI_FREQ_SHIFT)
+#define HP_CTL_PI_EN 0x00000008
+#define HP_CTL_TIMEALARM_EN 0x00000002
+#define HP_CTL_RTC_EN 0x00000001
+
+#define HP_SECVIO_INTEN_EN 0x10000000
+#define HP_SECVIO_INTEN_SRC5 0x00000020
+#define HP_SECVIO_INTEN_SRC4 0x00000010
+#define HP_SECVIO_INTEN_SRC3 0x00000008
+#define HP_SECVIO_INTEN_SRC2 0x00000004
+#define HP_SECVIO_INTEN_SRC1 0x00000002
+#define HP_SECVIO_INTEN_SRC0 0x00000001
+#define HP_SECVIO_INTEN_ALL 0x8000003f
+
+#define HP_SECVIO_ICTL_CFG_SHIFT 30
+#define HP_SECVIO_ICTL_CFG_MASK (0x3 << HP_SECVIO_ICTL_CFG_SHIFT)
+#define HP_SECVIO_ICTL_CFG5_SHIFT 5
+#define HP_SECVIO_ICTL_CFG5_MASK (0x3 << HP_SECVIO_ICTL_CFG5_SHIFT)
+#define HP_SECVIO_ICTL_CFG_DISABLE 0
+#define HP_SECVIO_ICTL_CFG_NONFATAL 1
+#define HP_SECVIO_ICTL_CFG_FATAL 2
+#define HP_SECVIO_ICTL_CFG4_FATAL 0x00000010
+#define HP_SECVIO_ICTL_CFG3_FATAL 0x00000008
+#define HP_SECVIO_ICTL_CFG2_FATAL 0x00000004
+#define HP_SECVIO_ICTL_CFG1_FATAL 0x00000002
+#define HP_SECVIO_ICTL_CFG0_FATAL 0x00000001
+
+#define HP_STATUS_ZMK_ZERO 0x80000000
+#define HP_STATUS_OTPMK_ZERO 0x08000000
+#define HP_STATUS_OTPMK_SYN_SHIFT 16
+#define HP_STATUS_OTPMK_SYN_MASK (0x1ff << HP_STATUS_OTPMK_SYN_SHIFT)
+#define HP_STATUS_SSM_ST_SHIFT 8
+#define HP_STATUS_SSM_ST_MASK (0xf << HP_STATUS_SSM_ST_SHIFT)
+#define HP_STATUS_SSM_ST_INIT 0
+#define HP_STATUS_SSM_ST_HARDFAIL 1
+#define HP_STATUS_SSM_ST_SOFTFAIL 3
+#define HP_STATUS_SSM_ST_INITINT 8
+#define HP_STATUS_SSM_ST_CHECK 9
+#define HP_STATUS_SSM_ST_NONSECURE 11
+#define HP_STATUS_SSM_ST_TRUSTED 13
+#define HP_STATUS_SSM_ST_SECURE 15
+
+#define HP_SECVIOST_ZMK_ECC_FAIL 0x08000000 /* write to clear */
+#define HP_SECVIOST_ZMK_SYN_SHIFT 16
+#define HP_SECVIOST_ZMK_SYN_MASK (0x1ff << HP_SECVIOST_ZMK_SYN_SHIFT)
+#define HP_SECVIOST_SECVIO5 0x00000020
+#define HP_SECVIOST_SECVIO4 0x00000010
+#define HP_SECVIOST_SECVIO3 0x00000008
+#define HP_SECVIOST_SECVIO2 0x00000004
+#define HP_SECVIOST_SECVIO1 0x00000002
+#define HP_SECVIOST_SECVIO0 0x00000001
+#define HP_SECVIOST_SECVIOMASK 0x0000003f
+
+/*
+ * SNVS Low Power Domain
+ * Includes glitch detector, SRTC, alarm, monotonic counter, ZMK
+ */
+struct snvs_lp {
+ u32 lock;
+ u32 ctl;
+ u32 mstr_key_ctl; /* Master Key Control */
+ u32 secvio_ctl; /* Security Violation Control */
+ u32 tamper_filt_cfg; /* Tamper Glitch Filters Configuration */
+ u32 tamper_det_cfg; /* Tamper Detectors Configuration */
+ u32 status;
+ u32 srtc_msb; /* Secure Real Time Clock/Counter MSB */
+ u32 srtc_lsb; /* Secure Real Time Clock/Counter LSB */
+ u32 time_alarm; /* Time Alarm */
+ u32 smc_msb; /* Secure Monotonic Counter MSB */
+ u32 smc_lsb; /* Secure Monotonic Counter LSB */
+ u32 pwr_glitch_det; /* Power Glitch Detector */
+ u32 gen_purpose;
+ u32 zmk[8]; /* Zeroizable Master Key */
+};
+
+#define LP_LOCK_MKEYSEL_LCK 0x00000200
+#define LP_LOCK_TAMPDET_LCK 0x00000100
+#define LP_LOCK_TAMPFLT_LCK 0x00000080
+#define LP_LOCK_SECVIO_LCK 0x00000040
+#define LP_LOCK_GENP_LCK 0x00000020
+#define LP_LOCK_MONOCTR_LCK 0x00000010
+#define LP_LOCK_CALIB_LCK 0x00000008
+#define LP_LOCK_SRTC_LCK 0x00000004
+#define LP_LOCK_ZMK_RD_LCK 0x00000002
+#define LP_LOCK_ZMK_WT_LCK 0x00000001
+
+#define LP_CTL_CAL_VAL_SHIFT 10
+#define LP_CTL_CAL_VAL_MASK (0x1f << LP_CTL_CAL_VAL_SHIFT)
+#define LP_CTL_CALIB_EN 0x00000100
+#define LP_CTL_SRTC_INVAL_EN 0x00000010
+#define LP_CTL_WAKE_INT_EN 0x00000008
+#define LP_CTL_MONOCTR_EN 0x00000004
+#define LP_CTL_TIMEALARM_EN 0x00000002
+#define LP_CTL_SRTC_EN 0x00000001
+
+#define LP_MKEYCTL_ZMKECC_SHIFT 8
+#define LP_MKEYCTL_ZMKECC_MASK (0xff << LP_MKEYCTL_ZMKECC_SHIFT)
+#define LP_MKEYCTL_ZMKECC_EN 0x00000010
+#define LP_MKEYCTL_ZMKECC_VAL 0x00000008
+#define LP_MKEYCTL_ZMKECC_PROG 0x00000004
+#define LP_MKEYCTL_MKSEL_SHIFT 0
+#define LP_MKEYCTL_MKSEL_MASK (3 << LP_MKEYCTL_MKSEL_SHIFT)
+#define LP_MKEYCTL_MK_OTP 0
+#define LP_MKEYCTL_MK_ZMK 2
+#define LP_MKEYCTL_MK_COMB 3
+
+#define LP_SECVIO_CTL_SRC5 0x20
+#define LP_SECVIO_CTL_SRC4 0x10
+#define LP_SECVIO_CTL_SRC3 0x08
+#define LP_SECVIO_CTL_SRC2 0x04
+#define LP_SECVIO_CTL_SRC1 0x02
+#define LP_SECVIO_CTL_SRC0 0x01
+
+#define LP_TAMPFILT_EXT2_EN 0x80000000
+#define LP_TAMPFILT_EXT2_SHIFT 24
+#define LP_TAMPFILT_EXT2_MASK (0x1f << LP_TAMPFILT_EXT2_SHIFT)
+#define LP_TAMPFILT_EXT1_EN 0x00800000
+#define LP_TAMPFILT_EXT1_SHIFT 16
+#define LP_TAMPFILT_EXT1_MASK (0x1f << LP_TAMPFILT_EXT1_SHIFT)
+#define LP_TAMPFILT_WM_EN 0x00000080
+#define LP_TAMPFILT_WM_SHIFT 0
+#define LP_TAMPFILT_WM_MASK (0x1f << LP_TAMPFILT_WM_SHIFT)
+
+#define LP_TAMPDET_OSC_BPS 0x10000000
+#define LP_TAMPDET_VRC_SHIFT 24
+#define LP_TAMPDET_VRC_MASK (3 << LP_TAMPFILT_VRC_SHIFT)
+#define LP_TAMPDET_HTDC_SHIFT 20
+#define LP_TAMPDET_HTDC_MASK (3 << LP_TAMPFILT_HTDC_SHIFT)
+#define LP_TAMPDET_LTDC_SHIFT 16
+#define LP_TAMPDET_LTDC_MASK (3 << LP_TAMPFILT_LTDC_SHIFT)
+#define LP_TAMPDET_POR_OBS 0x00008000
+#define LP_TAMPDET_PFD_OBS 0x00004000
+#define LP_TAMPDET_ET2_EN 0x00000400
+#define LP_TAMPDET_ET1_EN 0x00000200
+#define LP_TAMPDET_WMT2_EN 0x00000100
+#define LP_TAMPDET_WMT1_EN 0x00000080
+#define LP_TAMPDET_VT_EN 0x00000040
+#define LP_TAMPDET_TT_EN 0x00000020
+#define LP_TAMPDET_CT_EN 0x00000010
+#define LP_TAMPDET_MCR_EN 0x00000004
+#define LP_TAMPDET_SRTCR_EN 0x00000002
+
+#define LP_STATUS_SECURE
+#define LP_STATUS_NONSECURE
+#define LP_STATUS_SCANEXIT 0x00100000 /* all write 1 clear here on */
+#define LP_STATUS_EXT_SECVIO 0x00010000
+#define LP_STATUS_ET2 0x00000400
+#define LP_STATUS_ET1 0x00000200
+#define LP_STATUS_WMT2 0x00000100
+#define LP_STATUS_WMT1 0x00000080
+#define LP_STATUS_VTD 0x00000040
+#define LP_STATUS_TTD 0x00000020
+#define LP_STATUS_CTD 0x00000010
+#define LP_STATUS_PGD 0x00000008
+#define LP_STATUS_MCR 0x00000004
+#define LP_STATUS_SRTCR 0x00000002
+#define LP_STATUS_LPTA 0x00000001
+
+/* Full SNVS register page, including version/options */
+struct snvs_full {
+ struct snvs_hp hp;
+ struct snvs_lp lp;
+ u32 rsvd[731]; /* deadspace 0x08c-0xbf7 */
+
+ /* Version / Revision / Option ID space - end of register page */
+ u32 vid; /* 0xbf8 HP Version ID (VID 1) */
+ u32 opt_rev; /* 0xbfc HP Options / Revision (VID 2) */
+};
+
+#endif /* SNVSREGS_H */
diff --git a/drivers/crypto/caam/tag_object.c b/drivers/crypto/caam/tag_object.c
new file mode 100644
index 000000000000..f4218a4341bc
--- /dev/null
+++ b/drivers/crypto/caam/tag_object.c
@@ -0,0 +1,260 @@
+// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
+/*
+ * Copyright 2018 NXP
+ */
+
+#include <linux/export.h>
+#include <linux/string.h>
+#include <linux/errno.h>
+
+#include "tag_object.h"
+#include "desc.h"
+
+/*
+ * Magic number to clearly identify the structure is for us
+ * 0x54 = 'T'
+ * 0x61 = 'a'
+ * 0x67 = 'g'
+ * 0x4f = 'O'
+ */
+#define TAG_OBJECT_MAGIC 0x5461674f
+
+/**
+ * struct tagged_object - Structure representing a tagged object
+ * @tag : The configuration of the data
+ * @object : The object
+ */
+struct tagged_object {
+ struct tag_object_conf tag;
+ char object;
+};
+
+/**
+ * is_bk_type() - Determines if black key type.
+ * @type: The type
+ *
+ * Return: True if black key type, False otherwise.
+ */
+static bool is_bk_type(enum tag_type type)
+{
+ return (type == TAG_TYPE_BLACK_KEY_ECB) ||
+ (type == TAG_TYPE_BLACK_KEY_ECB_TRUSTED) ||
+ (type == TAG_TYPE_BLACK_KEY_CCM) ||
+ (type == TAG_TYPE_BLACK_KEY_CCM_TRUSTED);
+}
+
+/**
+ * is_bk_conf() - Determines if black key conf.
+ * @tag_obj_conf : The tag object conf
+ *
+ * Return: True if black key conf, False otherwise.
+ */
+bool is_bk_conf(const struct tag_object_conf *tag_obj_conf)
+{
+ return is_bk_type(tag_obj_conf->header.type);
+}
+EXPORT_SYMBOL(is_bk_conf);
+
+/**
+ * get_bk_conf() - Gets the block conf.
+ * @tag_obj_conf : The tag object conf
+ *
+ * Return: The block conf.
+ */
+const struct blackey_conf *get_bk_conf(const struct tag_object_conf *tag_obj_conf)
+{
+ return &tag_obj_conf->conf.bk_conf;
+}
+
+/**
+ * get_tag_object_overhead() - Gets the tag object overhead.
+ *
+ * Return: The tag object overhead.
+ */
+size_t get_tag_object_overhead(void)
+{
+ return TAG_OVERHEAD;
+}
+EXPORT_SYMBOL(get_tag_object_overhead);
+
+/**
+ * is_valid_type() - Determines if valid type.
+ * @type : The type
+ *
+ * Return: True if valid type, False otherwise.
+ */
+bool is_valid_type(enum tag_type type)
+{
+ return (type > TAG_TYPE_NOT_SUPPORTED) && (type < NB_TAG_TYPE);
+}
+EXPORT_SYMBOL(is_valid_type);
+
+/**
+ * is_valid_header() - Determines if valid header.
+ * @header : The header
+ *
+ * Return: True if valid tag object conf, False otherwise.
+ */
+static bool is_valid_header(const struct conf_header *header)
+{
+ bool valid = header->_magic_number == TAG_OBJECT_MAGIC;
+
+ valid = valid && is_valid_type(header->type);
+
+ return valid;
+}
+
+/**
+ * is_valid_tag_object_conf() - Determines if valid tag object conf.
+ * @tag_obj_conf : The tag object conf
+ *
+ * Return: True if valid header, False otherwise.
+ */
+bool is_valid_tag_object_conf(const struct tag_object_conf *tag_obj_conf)
+{
+ bool valid = true;
+
+ valid = is_valid_header(&tag_obj_conf->header);
+
+ return valid;
+}
+EXPORT_SYMBOL(is_valid_tag_object_conf);
+
+/**
+ * get_tag_object_conf() - Gets a pointer on the tag object conf.
+ * @tag_obj_conf : The tag object conf
+ * @buffer : The buffer
+ * @size : The size
+ *
+ * Return: 0 if success, else error code
+ */
+int get_tag_object_conf(void *buffer, size_t size,
+ struct tag_object_conf **tag_obj_conf)
+{
+ bool is_valid;
+ struct tagged_object *tago = (struct tagged_object *)buffer;
+ size_t conf_size = get_tag_object_overhead();
+
+ /* Check we can retrieve the conf */
+ if (size < conf_size)
+ return -EINVAL;
+
+ is_valid = is_valid_tag_object_conf(&tago->tag);
+
+ *tag_obj_conf = &tago->tag;
+
+ return (is_valid) ? 0 : -EINVAL;
+}
+EXPORT_SYMBOL(get_tag_object_conf);
+
+/**
+ * init_tag_object_header() - Initialize the tag object header
+ * @conf_header : The configuration header
+ * @type : The type
+ *
+ * It initialize the header structure
+ */
+void init_tag_object_header(struct conf_header *conf_header,
+ enum tag_type type)
+{
+ conf_header->_magic_number = TAG_OBJECT_MAGIC;
+ conf_header->type = type;
+}
+EXPORT_SYMBOL(init_tag_object_header);
+
+/**
+ * set_tag_object_conf() - Sets the tag object conf.
+ * @tag_obj_conf : The tag object conf
+ * @buffer : The buffer
+ * @obj_size : The object size
+ * @to_size : The tagged object size
+ *
+ * Return: 0 if success, else error code
+ */
+int set_tag_object_conf(const struct tag_object_conf *tag_obj_conf,
+ void *buffer, size_t obj_size, u32 *to_size)
+{
+ struct tagged_object *tago = buffer;
+ size_t conf_size = get_tag_object_overhead();
+ size_t req_size = obj_size + conf_size;
+
+ /* Check we can set the conf */
+ if (*to_size < req_size) {
+ *to_size = req_size;
+ return -EINVAL;
+ }
+
+ /* Move the object */
+ memmove(&tago->object, buffer, obj_size);
+
+ /* Copy the tag */
+ memcpy(&tago->tag, tag_obj_conf, conf_size);
+
+ *to_size = req_size;
+
+ return 0;
+}
+EXPORT_SYMBOL(set_tag_object_conf);
+
+/**
+ * init_blackey_conf() - Initialize the black key configuration
+ * @blackey_conf : The blackey conf
+ * @len : The length
+ * @ccm : The ccm
+ * @tk : The trusted key
+ *
+ * It initialize the black key configuration structure
+ */
+void init_blackey_conf(struct blackey_conf *blackey_conf,
+ size_t len, bool ccm, bool tk)
+{
+ blackey_conf->real_len = len;
+ blackey_conf->load = KEY_ENC
+ | ((ccm) ? KEY_EKT : 0)
+ | ((tk) ? KEY_TK : 0);
+}
+EXPORT_SYMBOL(init_blackey_conf);
+
+/**
+ * get_blackey_conf() - Get the black key configuration
+ * @blackey_conf : The blackey conf
+ * @real_len : The real length
+ * @load_param : The load parameter
+ *
+ * It retrieve the black key configuration
+ */
+void get_blackey_conf(const struct blackey_conf *blackey_conf,
+ u32 *real_len, u32 *load_param)
+{
+ *real_len = blackey_conf->real_len;
+ *load_param = blackey_conf->load;
+}
+EXPORT_SYMBOL(get_blackey_conf);
+
+/**
+ * get_tagged_data() - Get a pointer on the data and the size
+ * @tagged_object : Pointer on the tagged object
+ * @tagged_object_size : tagged object size in bytes
+ * @data : Pointer on the data
+ * @data_size : data size in bytes
+ *
+ * Return: 0 if success, else error code
+ */
+int get_tagged_data(void *tagged_object, size_t tagged_object_size,
+ void **data, u32 *data_size)
+{
+ struct tagged_object *tago =
+ (struct tagged_object *)tagged_object;
+ size_t conf_size = get_tag_object_overhead();
+
+ /* Check we can retrieve the object */
+ if (tagged_object_size < conf_size)
+ return -EINVAL;
+
+ /* Retrieve the object */
+ *data = &tago->object;
+ *data_size = tagged_object_size - conf_size;
+
+ return 0;
+}
+EXPORT_SYMBOL(get_tagged_data);
diff --git a/drivers/crypto/caam/tag_object.h b/drivers/crypto/caam/tag_object.h
new file mode 100644
index 000000000000..2ecc1bed3764
--- /dev/null
+++ b/drivers/crypto/caam/tag_object.h
@@ -0,0 +1,100 @@
+/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
+/*
+ * Copyright 2018 NXP
+ */
+
+#ifndef _TAG_OBJECT_H_
+#define _TAG_OBJECT_H_
+
+#include <linux/types.h>
+
+#define TAG_MIN_SIZE (2 * sizeof(struct conf_header))
+#define TAG_OVERHEAD sizeof(struct tag_object_conf)
+
+/**
+ * enum tag_type - Type of data represented by the tag
+ */
+enum tag_type {
+ /** @TAG_TYPE_NOT_SUPPORTED: The type is not supported */
+ TAG_TYPE_NOT_SUPPORTED = 0,
+
+ /* Type that passes is_tag_type_valid() */
+ /** @TAG_TYPE_BLACK_KEY_ECB: Black key encrypted with ECB */
+ TAG_TYPE_BLACK_KEY_ECB,
+ /**
+ * @TAG_TYPE_BLACK_KEY_ECB_TRUSTED: ECB Black key created by trusted
+ * descriptor
+ */
+ TAG_TYPE_BLACK_KEY_ECB_TRUSTED,
+ /** @TAG_TYPE_BLACK_KEY_CCM: Black key encrypted with CCM */
+ TAG_TYPE_BLACK_KEY_CCM,
+ /**
+ * @TAG_TYPE_BLACK_KEY_CCM_TRUSTED: CCM Black key created by trusted
+ * descriptor
+ */
+ TAG_TYPE_BLACK_KEY_CCM_TRUSTED,
+
+ /** @NB_TAG_TYPE: Number of type of tag */
+ NB_TAG_TYPE,
+};
+
+/**
+ * struct conf_header - Common struture holding the type of data and the magic
+ * number
+ * @_magic_number : A magic number to identify the structure
+ * @type : The type of data contained
+ */
+struct conf_header {
+ u32 _magic_number;
+ u32 type;
+};
+
+/**
+ * struct blackey_conf - Configuration for a black key
+ * @load : Load parameter for CAAM
+ * @real_len : Length of the key before encryption
+ */
+struct blackey_conf {
+ u32 load;
+ u32 real_len;
+};
+
+/**
+ * struct tag_object_conf - Common structure which is the tag applied to data
+ * @header : Part of the data initialized with common function
+ * :c:func:`init_tag_object_header`
+ * @conf : Configuration data about the object tagged, initialized with
+ * specific function
+ */
+struct tag_object_conf {
+ struct conf_header header;
+ union {
+ struct blackey_conf bk_conf;
+ } conf;
+};
+
+bool is_bk_conf(const struct tag_object_conf *tag_obj_conf);
+
+bool is_valid_tag_object_conf(const struct tag_object_conf *tag_obj_conf);
+
+void init_tag_object_header(struct conf_header *conf_header,
+ enum tag_type type);
+
+int get_tag_object_conf(void *buffer, size_t buffer_size,
+ struct tag_object_conf **tag_obj_conf);
+
+int set_tag_object_conf(const struct tag_object_conf *tag_obj_conf,
+ void *buffer, size_t obj_size, u32 *to_size);
+
+size_t get_tag_object_overhead(void);
+
+void get_blackey_conf(const struct blackey_conf *blackey_conf,
+ u32 *real_len, u32 *load_param);
+
+void init_blackey_conf(struct blackey_conf *blackey_conf,
+ size_t len, bool ccm, bool tk);
+
+int get_tagged_data(void *buffer, size_t buffer_size,
+ void **data, u32 *data_size);
+
+#endif /* _TAG_OBJECT_H_ */
diff --git a/drivers/crypto/mxs-dcp.c b/drivers/crypto/mxs-dcp.c
index e1e1e8110790..620ffc2f4e62 100644
--- a/drivers/crypto/mxs-dcp.c
+++ b/drivers/crypto/mxs-dcp.c
@@ -20,6 +20,7 @@
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/stmp_device.h>
+#include <linux/clk.h>
#include <crypto/aes.h>
#include <crypto/sha.h>
@@ -82,6 +83,10 @@ struct dcp {
spinlock_t lock[DCP_MAX_CHANS];
struct task_struct *thread[DCP_MAX_CHANS];
struct crypto_queue queue[DCP_MAX_CHANS];
+#ifdef CONFIG_ARM
+ struct clk *dcp_clk;
+#endif
+ int enable_sha_workaround;
};
enum dcp_chan {
@@ -115,6 +120,11 @@ struct dcp_sha_req_ctx {
unsigned int fini:1;
};
+struct dcp_export_state {
+ struct dcp_sha_req_ctx req_ctx;
+ struct dcp_async_ctx async_ctx;
+};
+
/*
* There can even be only one instance of the MXS DCP due to the
* design of Linux Crypto API.
@@ -299,6 +309,12 @@ static int mxs_dcp_aes_block_crypt(struct crypto_async_request *arq)
actx->fill = 0;
+ /*
+ * We are not supporting the case where there is no message to encrypt
+ */
+ if (nents == 0)
+ return -EINVAL;
+
/* Copy the key from the temporary location. */
memcpy(key, actx->key, actx->key_len);
@@ -579,19 +595,8 @@ static int mxs_dcp_run_sha(struct ahash_request *req)
desc->payload = 0;
desc->status = 0;
- /*
- * Align driver with hw behavior when generating null hashes
- */
- if (rctx->init && rctx->fini && desc->size == 0) {
- struct hash_alg_common *halg = crypto_hash_alg_common(tfm);
- const uint8_t *sha_buf =
- (actx->alg == MXS_DCP_CONTROL1_HASH_SELECT_SHA1) ?
- sha1_null_hash : sha256_null_hash;
- memcpy(sdcp->coh->sha_out_buf, sha_buf, halg->digestsize);
- ret = 0;
- goto done_run;
- }
-
+==== BASE ====
+==== BASE ====
/* Set HASH_TERM bit for last transfer block. */
if (rctx->fini) {
digest_phys = dma_map_single(sdcp->dev, sdcp->coh->sha_out_buf,
@@ -811,6 +816,35 @@ static int dcp_sha_finup(struct ahash_request *req)
return dcp_sha_update_fx(req, 1);
}
+static int dcp_sha_export(struct ahash_request *req, void *out)
+{
+ struct dcp_sha_req_ctx *rctx_state = ahash_request_ctx(req);
+ struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
+ struct dcp_async_ctx *actx_state = crypto_ahash_ctx(tfm);
+ struct dcp_export_state *export = out;
+
+ memcpy(&export->req_ctx, rctx_state, sizeof(struct dcp_sha_req_ctx));
+ memcpy(&export->async_ctx, actx_state, sizeof(struct dcp_async_ctx));
+
+ return 0;
+}
+
+static int dcp_sha_import(struct ahash_request *req, const void *in)
+{
+ struct dcp_sha_req_ctx *rctx = ahash_request_ctx(req);
+ struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
+ struct dcp_async_ctx *actx = crypto_ahash_ctx(tfm);
+ const struct dcp_export_state *export = in;
+
+ memset(rctx, 0, sizeof(struct dcp_sha_req_ctx));
+ memset(actx, 0, sizeof(struct dcp_async_ctx));
+
+ memcpy(rctx, &export->req_ctx, sizeof(struct dcp_sha_req_ctx));
+ memcpy(actx, &export->async_ctx, sizeof(struct dcp_async_ctx));
+
+ return 0;
+}
+
static int dcp_sha_digest(struct ahash_request *req)
{
int ret;
@@ -892,8 +926,11 @@ static struct ahash_alg dcp_sha1_alg = {
.final = dcp_sha_final,
.finup = dcp_sha_finup,
.digest = dcp_sha_digest,
+ .export = dcp_sha_export,
+ .import = dcp_sha_import,
.halg = {
.digestsize = SHA1_DIGEST_SIZE,
+ .statesize = sizeof(struct dcp_export_state),
.base = {
.cra_name = "sha1",
.cra_driver_name = "sha1-dcp",
@@ -916,8 +953,11 @@ static struct ahash_alg dcp_sha256_alg = {
.final = dcp_sha_final,
.finup = dcp_sha_finup,
.digest = dcp_sha_digest,
+ .export = dcp_sha_export,
+ .import = dcp_sha_import,
.halg = {
.digestsize = SHA256_DIGEST_SIZE,
+ .statesize = sizeof(struct dcp_export_state),
.base = {
.cra_name = "sha256",
.cra_driver_name = "sha256-dcp",
@@ -991,6 +1031,26 @@ static int mxs_dcp_probe(struct platform_device *pdev)
if (IS_ERR(sdcp->base))
return PTR_ERR(sdcp->base);
+#ifdef CONFIG_ARM
+ sdcp->dcp_clk = devm_clk_get(dev, "dcp");
+
+ if (IS_ERR(sdcp->dcp_clk)) {
+ ret = PTR_ERR(sdcp->dcp_clk);
+ dev_err(dev, "can't identify DCP clk: %d\n", ret);
+ return -ENODEV;
+ }
+
+ ret = clk_prepare(sdcp->dcp_clk);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "can't prepare DCP clock: %d\n", ret);
+ return -ENODEV;
+ }
+ ret = clk_enable(sdcp->dcp_clk);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "can't enable DCP clock: %d\n", ret);
+ return -ENODEV;
+ }
+#endif
ret = devm_request_irq(dev, dcp_vmi_irq, mxs_dcp_irq, 0,
"dcp-vmi-irq", sdcp);
@@ -1051,6 +1111,11 @@ static int mxs_dcp_probe(struct platform_device *pdev)
crypto_init_queue(&sdcp->queue[i], 50);
}
+ /*
+ * Enable driver alignment with hw behavior for sha generation
+ */
+ sdcp->enable_sha_workaround = 1;
+
/* Create the SHA and AES handler threads. */
sdcp->thread[DCP_CHAN_HASH_SHA] = kthread_run(dcp_chan_thread_sha,
NULL, "mxs_dcp_chan/sha");
@@ -1132,6 +1197,11 @@ static int mxs_dcp_remove(struct platform_device *pdev)
kthread_stop(sdcp->thread[DCP_CHAN_HASH_SHA]);
kthread_stop(sdcp->thread[DCP_CHAN_CRYPTO]);
+#ifdef CONFIG_ARM
+ /* shut clocks off before finalizing shutdown */
+ clk_disable(sdcp->dcp_clk);
+#endif
+
platform_set_drvdata(pdev, NULL);
global_sdcp = NULL;
@@ -1142,6 +1212,7 @@ static int mxs_dcp_remove(struct platform_device *pdev)
static const struct of_device_id mxs_dcp_dt_ids[] = {
{ .compatible = "fsl,imx23-dcp", .data = NULL, },
{ .compatible = "fsl,imx28-dcp", .data = NULL, },
+ { .compatible = "fsl,imx6sl-dcp", .data = NULL, },
{ /* sentinel */ }
};
diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c
index 1195a3d2e67c..2e458f61b6bb 100644
--- a/drivers/dma-buf/dma-buf.c
+++ b/drivers/dma-buf/dma-buf.c
@@ -34,6 +34,7 @@
#include <linux/poll.h>
#include <linux/reservation.h>
#include <linux/mm.h>
+#include <linux/device.h>
#include <uapi/linux/dma-buf.h>
@@ -287,6 +288,36 @@ static long dma_buf_ioctl(struct file *file,
dmabuf = file->private_data;
switch (cmd) {
+ case DMA_BUF_IOCTL_PHYS: {
+ struct dma_buf_attachment *attachment = NULL;
+ struct sg_table *sgt = NULL;
+ unsigned long phys = 0;
+ struct device dev;
+
+ if (!dmabuf || IS_ERR(dmabuf)) {
+ return -EFAULT;
+ }
+ memset(&dev, 0, sizeof(dev));
+ device_initialize(&dev);
+ dev.coherent_dma_mask = DMA_BIT_MASK(64);
+ dev.dma_mask = &dev.coherent_dma_mask;
+ arch_setup_dma_ops(&dev, 0, 0, NULL, false);
+ attachment = dma_buf_attach(dmabuf, &dev);
+ if (!attachment || IS_ERR(attachment)) {
+ return -EFAULT;
+ }
+
+ sgt = dma_buf_map_attachment(attachment, DMA_BIDIRECTIONAL);
+ if (sgt && !IS_ERR(sgt)) {
+ phys = sg_dma_address(sgt->sgl);
+ dma_buf_unmap_attachment(attachment, sgt,
+ DMA_BIDIRECTIONAL);
+ }
+ dma_buf_detach(dmabuf, attachment);
+ if (copy_to_user((void __user *) arg, &phys, sizeof(phys)))
+ return -EFAULT;
+ return 0;
+ }
case DMA_BUF_IOCTL_SYNC:
if (copy_from_user(&sync, (void __user *) arg, sizeof(sync)))
return -EFAULT;
diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index 79b809dbfda0..4a10ff3c9bab 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -215,6 +215,18 @@ config FSL_EDMA
multiplexing capability for DMA request sources(slot).
This module can be found on Freescale Vybrid and LS-1 SoCs.
+config FSL_EDMA_V3
+ tristate "Freescale eDMA v3 engine support"
+ depends on OF
+ select DMA_ENGINE
+ select DMA_VIRTUAL_CHANNELS
+ help
+ Support the Freescale eDMA v3 engine with programmable channel.
+ This driver is based on FSL_EDMA but big changes come such as
+ different interrupt for different channel, different register
+ scope for different channel.
+ This module can be found on Freescale i.MX8QM.
+
config FSL_RAID
tristate "Freescale RAID engine Support"
depends on FSL_SOC && !ASYNC_TX_ENABLE_CHANNEL_SWITCH
@@ -245,8 +257,9 @@ config IMX_DMA
config IMX_SDMA
tristate "i.MX SDMA support"
- depends on ARCH_MXC
+ depends on ARCH_MXC || ARCH_FSL_IMX8MQ
select DMA_ENGINE
+ select DMA_VIRTUAL_CHANNELS
help
Support the i.MX SDMA engine. This engine is integrated into
Freescale i.MX25/31/35/51/53/6 chips.
@@ -377,13 +390,15 @@ config MV_XOR_V2
config MXS_DMA
bool "MXS DMA support"
- depends on ARCH_MXS || ARCH_MXC || COMPILE_TEST
+ depends on ARCH_MXS || ARCH_MXC || ARCH_MXC_ARM64 || COMPILE_TEST
select STMP_DEVICE
select DMA_ENGINE
help
Support the MXS DMA engine. This engine including APBH-DMA
and APBX-DMA is integrated into some Freescale chips.
+source "drivers/dma/pxp/Kconfig"
+
config MX3_IPU
bool "MX3x Image Processing Unit support"
depends on ARCH_MXC
diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile
index 9d0156b50294..f0a61c081662 100644
--- a/drivers/dma/Makefile
+++ b/drivers/dma/Makefile
@@ -32,6 +32,7 @@ obj-$(CONFIG_DW_DMAC_CORE) += dw/
obj-$(CONFIG_EP93XX_DMA) += ep93xx_dma.o
obj-$(CONFIG_FSL_DMA) += fsldma.o
obj-$(CONFIG_FSL_EDMA) += fsl-edma.o
+obj-$(CONFIG_FSL_EDMA_V3) += fsl-edma-v3.o
obj-$(CONFIG_FSL_RAID) += fsl_raid.o
obj-$(CONFIG_HSU_DMA) += hsu/
obj-$(CONFIG_IMG_MDC_DMA) += img-mdc-dma.o
@@ -56,6 +57,8 @@ obj-$(CONFIG_PCH_DMA) += pch_dma.o
obj-$(CONFIG_PL330_DMA) += pl330.o
obj-$(CONFIG_PPC_BESTCOMM) += bestcomm/
obj-$(CONFIG_PXA_DMA) += pxa_dma.o
+obj-$(CONFIG_MXC_PXP_V2) += pxp/
+obj-$(CONFIG_MXC_PXP_V3) += pxp/
obj-$(CONFIG_RENESAS_DMA) += sh/
obj-$(CONFIG_SIRF_DMA) += sirf-dma.o
obj-$(CONFIG_STE_DMA40) += ste_dma40.o ste_dma40_ll.o
diff --git a/drivers/dma/fsl-edma-v3.c b/drivers/dma/fsl-edma-v3.c
new file mode 100644
index 000000000000..0e7f5eeca2cb
--- /dev/null
+++ b/drivers/dma/fsl-edma-v3.c
@@ -0,0 +1,1094 @@
+/*
+ * drivers/dma/fsl-edma3-v3.c
+ *
+ * Copyright 2017-2018 NXP .
+ *
+ * Driver for the Freescale eDMA engine v3. This driver based on fsl-edma3.c
+ * but changed to meet the IP change on i.MX8QM: every dma channel is specific
+ * to hardware. For example, channel 14 for LPUART1 receive request and channel
+ * 13 for transmit requesst. The eDMA block can be found on i.MX8QM
+ *
+ * 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/init.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/clk.h>
+#include <linux/dma-mapping.h>
+#include <linux/dmapool.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/of_dma.h>
+
+#include <soc/imx/revision.h>
+#include <soc/imx8/soc.h>
+
+#include "virt-dma.h"
+
+#define EDMA_CH_CSR 0x00
+#define EDMA_CH_ES 0x04
+#define EDMA_CH_INT 0x08
+#define EDMA_CH_SBR 0x0C
+#define EDMA_CH_PRI 0x10
+#define EDMA_TCD_SADDR 0x20
+#define EDMA_TCD_SOFF 0x24
+#define EDMA_TCD_ATTR 0x26
+#define EDMA_TCD_NBYTES 0x28
+#define EDMA_TCD_SLAST 0x2C
+#define EDMA_TCD_DADDR 0x30
+#define EDMA_TCD_DOFF 0x34
+#define EDMA_TCD_CITER_ELINK 0x36
+#define EDMA_TCD_CITER 0x36
+#define EDMA_TCD_DLAST_SGA 0x38
+#define EDMA_TCD_CSR 0x3C
+#define EDMA_TCD_BITER_ELINK 0x3E
+#define EDMA_TCD_BITER 0x3E
+
+#define EDMA_CH_SBR_RD BIT(22)
+#define EDMA_CH_SBR_WR BIT(21)
+#define EDMA_CH_CSR_ERQ BIT(0)
+#define EDMA_CH_CSR_EARQ BIT(1)
+#define EDMA_CH_CSR_EEI BIT(2)
+#define EDMA_CH_CSR_DONE BIT(30)
+#define EDMA_CH_CSR_ACTIVE BIT(31)
+
+#define EDMA_TCD_ATTR_DSIZE(x) (((x) & 0x0007))
+#define EDMA_TCD_ATTR_DMOD(x) (((x) & 0x001F) << 3)
+#define EDMA_TCD_ATTR_SSIZE(x) (((x) & 0x0007) << 8)
+#define EDMA_TCD_ATTR_SMOD(x) (((x) & 0x001F) << 11)
+#define EDMA_TCD_ATTR_SSIZE_8BIT (0x0000)
+#define EDMA_TCD_ATTR_SSIZE_16BIT (0x0100)
+#define EDMA_TCD_ATTR_SSIZE_32BIT (0x0200)
+#define EDMA_TCD_ATTR_SSIZE_64BIT (0x0300)
+#define EDMA_TCD_ATTR_SSIZE_16BYTE (0x0400)
+#define EDMA_TCD_ATTR_SSIZE_32BYTE (0x0500)
+#define EDMA_TCD_ATTR_SSIZE_64BYTE (0x0600)
+#define EDMA_TCD_ATTR_DSIZE_8BIT (0x0000)
+#define EDMA_TCD_ATTR_DSIZE_16BIT (0x0001)
+#define EDMA_TCD_ATTR_DSIZE_32BIT (0x0002)
+#define EDMA_TCD_ATTR_DSIZE_64BIT (0x0003)
+#define EDMA_TCD_ATTR_DSIZE_16BYTE (0x0004)
+#define EDMA_TCD_ATTR_DSIZE_32BYTE (0x0005)
+#define EDMA_TCD_ATTR_DSIZE_64BYTE (0x0006)
+
+#define EDMA_TCD_SOFF_SOFF(x) (x)
+#define EDMA_TCD_NBYTES_NBYTES(x) (x)
+#define EDMA_TCD_NBYTES_MLOFF(x) (x << 10)
+#define EDMA_TCD_NBYTES_DMLOE (1 << 30)
+#define EDMA_TCD_NBYTES_SMLOE (1 << 31)
+#define EDMA_TCD_SLAST_SLAST(x) (x)
+#define EDMA_TCD_DADDR_DADDR(x) (x)
+#define EDMA_TCD_CITER_CITER(x) ((x) & 0x7FFF)
+#define EDMA_TCD_DOFF_DOFF(x) (x)
+#define EDMA_TCD_DLAST_SGA_DLAST_SGA(x) (x)
+#define EDMA_TCD_BITER_BITER(x) ((x) & 0x7FFF)
+
+#define EDMA_TCD_CSR_START BIT(0)
+#define EDMA_TCD_CSR_INT_MAJOR BIT(1)
+#define EDMA_TCD_CSR_INT_HALF BIT(2)
+#define EDMA_TCD_CSR_D_REQ BIT(3)
+#define EDMA_TCD_CSR_E_SG BIT(4)
+#define EDMA_TCD_CSR_E_LINK BIT(5)
+#define EDMA_TCD_CSR_ACTIVE BIT(6)
+#define EDMA_TCD_CSR_DONE BIT(7)
+
+#define FSL_EDMA_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) | \
+ BIT(DMA_SLAVE_BUSWIDTH_16_BYTES))
+
+#define ARGS_RX BIT(0)
+#define ARGS_REMOTE BIT(1)
+#define ARGS_DFIFO BIT(2)
+
+/* channel name template define in dts */
+#define CHAN_PREFIX "edma0-chan"
+#define CHAN_POSFIX "-tx"
+
+enum fsl_edma3_pm_state {
+ RUNNING = 0,
+ SUSPENDED,
+};
+
+struct fsl_edma3_hw_tcd {
+ __le32 saddr;
+ __le16 soff;
+ __le16 attr;
+ __le32 nbytes;
+ __le32 slast;
+ __le32 daddr;
+ __le16 doff;
+ __le16 citer;
+ __le32 dlast_sga;
+ __le16 csr;
+ __le16 biter;
+};
+
+struct fsl_edma3_sw_tcd {
+ dma_addr_t ptcd;
+ struct fsl_edma3_hw_tcd *vtcd;
+};
+
+struct fsl_edma3_slave_config {
+ enum dma_transfer_direction dir;
+ enum dma_slave_buswidth addr_width;
+ u32 dev_addr;
+ u32 dev2_addr; /* source addr for dev2dev */
+ u32 burst;
+ u32 attr;
+};
+
+struct fsl_edma3_chan {
+ struct virt_dma_chan vchan;
+ enum dma_status status;
+ enum fsl_edma3_pm_state pm_state;
+ bool idle;
+ bool used;
+ struct fsl_edma3_engine *edma3;
+ struct fsl_edma3_desc *edesc;
+ struct fsl_edma3_slave_config fsc;
+ void __iomem *membase;
+ int txirq;
+ int hw_chanid;
+ int priority;
+ int is_rxchan;
+ int is_remote;
+ int is_dfifo;
+ struct dma_pool *tcd_pool;
+ u32 chn_real_count;
+ char txirq_name[32];
+ struct platform_device *pdev;
+};
+
+struct fsl_edma3_desc {
+ struct virt_dma_desc vdesc;
+ struct fsl_edma3_chan *echan;
+ bool iscyclic;
+ unsigned int n_tcds;
+ struct fsl_edma3_sw_tcd tcd[];
+};
+
+struct fsl_edma3_reg_save {
+ u32 csr;
+ u32 sbr;
+};
+
+struct fsl_edma3_engine {
+ struct dma_device dma_dev;
+ unsigned long irqflag;
+ struct mutex fsl_edma3_mutex;
+ u32 n_chans;
+ int errirq;
+ #define MAX_CHAN_NUM 32
+ struct fsl_edma3_reg_save edma_regs[MAX_CHAN_NUM];
+ bool swap; /* remote/local swapped on Audio edma */
+ struct fsl_edma3_chan chans[];
+};
+
+static struct fsl_edma3_chan *to_fsl_edma3_chan(struct dma_chan *chan)
+{
+ return container_of(chan, struct fsl_edma3_chan, vchan.chan);
+}
+
+static struct fsl_edma3_desc *to_fsl_edma3_desc(struct virt_dma_desc *vd)
+{
+ return container_of(vd, struct fsl_edma3_desc, vdesc);
+}
+
+static void fsl_edma3_enable_request(struct fsl_edma3_chan *fsl_chan)
+{
+ void __iomem *addr = fsl_chan->membase;
+ u32 val;
+
+ val = readl(addr + EDMA_CH_SBR);
+ /* Remote/local swapped wrongly on iMX8 QM Audio edma */
+ if (fsl_chan->edma3->swap) {
+ if (!fsl_chan->is_rxchan)
+ val |= EDMA_CH_SBR_RD;
+ else
+ val |= EDMA_CH_SBR_WR;
+ } else {
+ if (fsl_chan->is_rxchan)
+ val |= EDMA_CH_SBR_RD;
+ else
+ val |= EDMA_CH_SBR_WR;
+ }
+
+ if (fsl_chan->is_remote)
+ val &= ~(EDMA_CH_SBR_RD | EDMA_CH_SBR_WR);
+
+ writel(val, addr + EDMA_CH_SBR);
+
+ val = readl(addr + EDMA_CH_CSR);
+
+ val |= EDMA_CH_CSR_ERQ;
+ writel(val, addr + EDMA_CH_CSR);
+
+ fsl_chan->used = true;
+}
+
+static void fsl_edma3_disable_request(struct fsl_edma3_chan *fsl_chan)
+{
+ void __iomem *addr = fsl_chan->membase;
+ u32 val = readl(addr + EDMA_CH_CSR);
+
+ val &= ~EDMA_CH_CSR_ERQ;
+ writel(val, addr + EDMA_CH_CSR);
+}
+
+static unsigned int fsl_edma3_get_tcd_attr(enum dma_slave_buswidth addr_width)
+{
+ switch (addr_width) {
+ case 1:
+ return EDMA_TCD_ATTR_SSIZE_8BIT | EDMA_TCD_ATTR_DSIZE_8BIT;
+ case 2:
+ return EDMA_TCD_ATTR_SSIZE_16BIT | EDMA_TCD_ATTR_DSIZE_16BIT;
+ case 4:
+ return EDMA_TCD_ATTR_SSIZE_32BIT | EDMA_TCD_ATTR_DSIZE_32BIT;
+ case 8:
+ return EDMA_TCD_ATTR_SSIZE_64BIT | EDMA_TCD_ATTR_DSIZE_64BIT;
+ case 16:
+ return EDMA_TCD_ATTR_SSIZE_16BYTE | EDMA_TCD_ATTR_DSIZE_16BYTE;
+ case 32:
+ return EDMA_TCD_ATTR_SSIZE_32BYTE | EDMA_TCD_ATTR_DSIZE_32BYTE;
+ case 64:
+ return EDMA_TCD_ATTR_SSIZE_64BYTE | EDMA_TCD_ATTR_DSIZE_64BYTE;
+ default:
+ return EDMA_TCD_ATTR_SSIZE_32BIT | EDMA_TCD_ATTR_DSIZE_32BIT;
+ }
+}
+
+static void fsl_edma3_free_desc(struct virt_dma_desc *vdesc)
+{
+ struct fsl_edma3_desc *fsl_desc;
+ int i;
+
+ fsl_desc = to_fsl_edma3_desc(vdesc);
+ for (i = 0; i < fsl_desc->n_tcds; i++)
+ dma_pool_free(fsl_desc->echan->tcd_pool, fsl_desc->tcd[i].vtcd,
+ fsl_desc->tcd[i].ptcd);
+ kfree(fsl_desc);
+}
+
+static int fsl_edma3_terminate_all(struct dma_chan *chan)
+{
+ struct fsl_edma3_chan *fsl_chan = to_fsl_edma3_chan(chan);
+ unsigned long flags;
+ LIST_HEAD(head);
+
+ spin_lock_irqsave(&fsl_chan->vchan.lock, flags);
+ fsl_edma3_disable_request(fsl_chan);
+ fsl_chan->edesc = NULL;
+ fsl_chan->idle = true;
+ fsl_chan->used = false;
+ fsl_chan->vchan.cyclic = 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_edma3_pause(struct dma_chan *chan)
+{
+ struct fsl_edma3_chan *fsl_chan = to_fsl_edma3_chan(chan);
+ unsigned long flags;
+
+ spin_lock_irqsave(&fsl_chan->vchan.lock, flags);
+ if (fsl_chan->edesc) {
+ fsl_edma3_disable_request(fsl_chan);
+ fsl_chan->status = DMA_PAUSED;
+ fsl_chan->idle = true;
+ }
+ spin_unlock_irqrestore(&fsl_chan->vchan.lock, flags);
+ return 0;
+}
+
+static int fsl_edma3_resume(struct dma_chan *chan)
+{
+ struct fsl_edma3_chan *fsl_chan = to_fsl_edma3_chan(chan);
+ unsigned long flags;
+
+ spin_lock_irqsave(&fsl_chan->vchan.lock, flags);
+ if (fsl_chan->edesc) {
+ fsl_edma3_enable_request(fsl_chan);
+ fsl_chan->status = DMA_IN_PROGRESS;
+ fsl_chan->idle = false;
+ }
+ spin_unlock_irqrestore(&fsl_chan->vchan.lock, flags);
+ return 0;
+}
+
+static int fsl_edma3_slave_config(struct dma_chan *chan,
+ struct dma_slave_config *cfg)
+{
+ struct fsl_edma3_chan *fsl_chan = to_fsl_edma3_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_edma3_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_edma3_get_tcd_attr
+ (cfg->dst_addr_width);
+ } else if (cfg->direction == DMA_DEV_TO_DEV) {
+ fsl_chan->fsc.dev2_addr = cfg->src_addr;
+ 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_edma3_get_tcd_attr
+ (cfg->dst_addr_width);
+ } else {
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static size_t fsl_edma3_desc_residue(struct fsl_edma3_chan *fsl_chan,
+ struct virt_dma_desc *vdesc, bool in_progress)
+{
+ struct fsl_edma3_desc *edesc = fsl_chan->edesc;
+ void __iomem *addr = fsl_chan->membase;
+ enum dma_transfer_direction dir = fsl_chan->fsc.dir;
+ dma_addr_t cur_addr, dma_addr;
+ size_t len, size;
+ int i;
+
+ /* calculate the total size in this desc */
+ for (len = i = 0; i < fsl_chan->edesc->n_tcds; i++)
+ len += le32_to_cpu(edesc->tcd[i].vtcd->nbytes)
+ * le16_to_cpu(edesc->tcd[i].vtcd->biter);
+
+ if (!in_progress)
+ return len;
+
+ if (dir == DMA_MEM_TO_DEV)
+ cur_addr = readl(addr + EDMA_TCD_SADDR);
+ else
+ cur_addr = readl(addr + EDMA_TCD_DADDR);
+
+ /* figure out the finished and calculate the residue */
+ for (i = 0; i < fsl_chan->edesc->n_tcds; i++) {
+ size = le32_to_cpu(edesc->tcd[i].vtcd->nbytes)
+ * le16_to_cpu(edesc->tcd[i].vtcd->biter);
+ if (dir == DMA_MEM_TO_DEV)
+ dma_addr = le32_to_cpu(edesc->tcd[i].vtcd->saddr);
+ else
+ dma_addr = le32_to_cpu(edesc->tcd[i].vtcd->daddr);
+
+ len -= size;
+ if (cur_addr >= dma_addr && cur_addr < dma_addr + size) {
+ len += dma_addr + size - cur_addr;
+ break;
+ }
+ }
+
+ return len;
+}
+
+static enum dma_status fsl_edma3_tx_status(struct dma_chan *chan,
+ dma_cookie_t cookie, struct dma_tx_state *txstate)
+{
+ struct fsl_edma3_chan *fsl_chan = to_fsl_edma3_chan(chan);
+ struct virt_dma_desc *vdesc;
+ enum dma_status status;
+ unsigned long flags;
+
+ status = dma_cookie_status(chan, cookie, txstate);
+ if (status == DMA_COMPLETE) {
+ spin_lock_irqsave(&fsl_chan->vchan.lock, flags);
+ txstate->residue = fsl_chan->chn_real_count;
+ spin_unlock_irqrestore(&fsl_chan->vchan.lock, flags);
+ return status;
+ }
+
+ if (!txstate)
+ return fsl_chan->status;
+
+ spin_lock_irqsave(&fsl_chan->vchan.lock, flags);
+ vdesc = vchan_find_desc(&fsl_chan->vchan, cookie);
+ if (fsl_chan->edesc && cookie == fsl_chan->edesc->vdesc.tx.cookie)
+ txstate->residue = fsl_edma3_desc_residue(fsl_chan, vdesc,
+ true);
+ else if (fsl_chan->edesc && vdesc)
+ txstate->residue = fsl_edma3_desc_residue(fsl_chan, vdesc,
+ false);
+ else
+ txstate->residue = 0;
+
+ spin_unlock_irqrestore(&fsl_chan->vchan.lock, flags);
+
+ return fsl_chan->status;
+}
+
+static void fsl_edma3_set_tcd_regs(struct fsl_edma3_chan *fsl_chan,
+ struct fsl_edma3_hw_tcd *tcd)
+{
+ void __iomem *addr = fsl_chan->membase;
+ /*
+ * TCD parameters are stored in struct fsl_edma3_hw_tcd in little
+ * endian format. However, we need to load the TCD registers in
+ * big- or little-endian obeying the eDMA engine model endian.
+ */
+ writew(0, addr + EDMA_TCD_CSR);
+ writel(le32_to_cpu(tcd->saddr), addr + EDMA_TCD_SADDR);
+ writel(le32_to_cpu(tcd->daddr), addr + EDMA_TCD_DADDR);
+
+ writew(le16_to_cpu(tcd->attr), addr + EDMA_TCD_ATTR);
+ writew(le16_to_cpu(tcd->soff), addr + EDMA_TCD_SOFF);
+
+ writel(le32_to_cpu(tcd->nbytes), addr + EDMA_TCD_NBYTES);
+ writel(le32_to_cpu(tcd->slast), addr + EDMA_TCD_SLAST);
+
+ writew(le16_to_cpu(tcd->citer), addr + EDMA_TCD_CITER);
+ writew(le16_to_cpu(tcd->biter), addr + EDMA_TCD_BITER);
+ writew(le16_to_cpu(tcd->doff), addr + EDMA_TCD_DOFF);
+
+ writel(le32_to_cpu(tcd->dlast_sga), addr + EDMA_TCD_DLAST_SGA);
+
+ /* Must clear CHa_CSR[DONE] bit before enable TCDa_CSR[ESG] */
+ writel(readl(addr + EDMA_CH_CSR), addr + EDMA_CH_CSR);
+
+ writew(le16_to_cpu(tcd->csr), addr + EDMA_TCD_CSR);
+}
+
+static inline
+void fsl_edma3_fill_tcd(struct fsl_edma3_chan *fsl_chan,
+ struct fsl_edma3_hw_tcd *tcd, u32 src, u32 dst,
+ u16 attr, u16 soff, u32 nbytes, u32 slast, u16 citer,
+ u16 biter, u16 doff, u32 dlast_sga, bool major_int,
+ bool disable_req, bool enable_sg)
+{
+ u16 csr = 0;
+
+ /*
+ * eDMA hardware SGs require the TCDs to be stored in little
+ * endian format irrespective of the register endian model.
+ * So we put the value in little endian in memory, waiting
+ * for fsl_edma3_set_tcd_regs doing the swap.
+ */
+ tcd->saddr = cpu_to_le32(src);
+ tcd->daddr = cpu_to_le32(dst);
+
+ tcd->attr = cpu_to_le16(attr);
+
+ tcd->soff = cpu_to_le16(EDMA_TCD_SOFF_SOFF(soff));
+
+ if (fsl_chan->is_dfifo) {
+ /* set mloff as -8 */
+ nbytes |= EDMA_TCD_NBYTES_MLOFF(-8);
+ /* enable DMLOE/SMLOE */
+ if (fsl_chan->fsc.dir == DMA_MEM_TO_DEV) {
+ nbytes |= EDMA_TCD_NBYTES_DMLOE;
+ nbytes &= ~EDMA_TCD_NBYTES_SMLOE;
+ } else {
+ nbytes |= EDMA_TCD_NBYTES_SMLOE;
+ nbytes &= ~EDMA_TCD_NBYTES_DMLOE;
+ }
+ }
+
+ tcd->nbytes = cpu_to_le32(EDMA_TCD_NBYTES_NBYTES(nbytes));
+ tcd->slast = cpu_to_le32(EDMA_TCD_SLAST_SLAST(slast));
+
+ tcd->citer = cpu_to_le16(EDMA_TCD_CITER_CITER(citer));
+ tcd->doff = cpu_to_le16(EDMA_TCD_DOFF_DOFF(doff));
+
+ tcd->dlast_sga = cpu_to_le32(EDMA_TCD_DLAST_SGA_DLAST_SGA(dlast_sga));
+
+ tcd->biter = cpu_to_le16(EDMA_TCD_BITER_BITER(biter));
+ if (major_int)
+ csr |= EDMA_TCD_CSR_INT_MAJOR;
+
+ if (disable_req)
+ csr |= EDMA_TCD_CSR_D_REQ;
+
+ if (enable_sg)
+ csr |= EDMA_TCD_CSR_E_SG;
+
+ if (fsl_chan->is_rxchan)
+ csr |= EDMA_TCD_CSR_ACTIVE;
+
+ tcd->csr = cpu_to_le16(csr);
+}
+
+static struct fsl_edma3_desc *fsl_edma3_alloc_desc(struct fsl_edma3_chan
+ *fsl_chan, int sg_len)
+{
+ struct fsl_edma3_desc *fsl_desc;
+ int i;
+
+ fsl_desc = kzalloc(sizeof(*fsl_desc) + sizeof(struct fsl_edma3_sw_tcd)
+ * sg_len, GFP_ATOMIC);
+ if (!fsl_desc)
+ return NULL;
+
+ fsl_desc->echan = fsl_chan;
+ fsl_desc->n_tcds = sg_len;
+ for (i = 0; i < sg_len; i++) {
+ fsl_desc->tcd[i].vtcd = dma_pool_alloc(fsl_chan->tcd_pool,
+ GFP_ATOMIC, &fsl_desc->tcd[i].ptcd);
+ if (!fsl_desc->tcd[i].vtcd)
+ goto err;
+ }
+ return fsl_desc;
+
+err:
+ while (--i >= 0)
+ dma_pool_free(fsl_chan->tcd_pool, fsl_desc->tcd[i].vtcd,
+ fsl_desc->tcd[i].ptcd);
+ kfree(fsl_desc);
+ return NULL;
+}
+
+static struct dma_async_tx_descriptor *fsl_edma3_prep_dma_cyclic(
+ struct dma_chan *chan, dma_addr_t dma_addr, size_t buf_len,
+ size_t period_len, enum dma_transfer_direction direction,
+ unsigned long flags)
+{
+ struct fsl_edma3_chan *fsl_chan = to_fsl_edma3_chan(chan);
+ struct fsl_edma3_desc *fsl_desc;
+ dma_addr_t dma_buf_next;
+ int sg_len, i;
+ u32 src_addr, dst_addr, last_sg, nbytes;
+ u16 soff, doff, iter;
+
+ sg_len = buf_len / period_len;
+ fsl_desc = fsl_edma3_alloc_desc(fsl_chan, sg_len);
+ if (!fsl_desc)
+ return NULL;
+ fsl_desc->iscyclic = true;
+
+ dma_buf_next = dma_addr;
+ nbytes = fsl_chan->fsc.addr_width * fsl_chan->fsc.burst;
+ iter = period_len / nbytes;
+
+ for (i = 0; i < sg_len; i++) {
+ if (dma_buf_next >= dma_addr + buf_len)
+ dma_buf_next = dma_addr;
+
+ /* get next sg's physical address */
+ last_sg = fsl_desc->tcd[(i + 1) % sg_len].ptcd;
+
+ if (fsl_chan->fsc.dir == DMA_MEM_TO_DEV) {
+ src_addr = dma_buf_next;
+ dst_addr = fsl_chan->fsc.dev_addr;
+ soff = fsl_chan->fsc.addr_width;
+ if (fsl_chan->is_dfifo)
+ doff = 4;
+ else
+ doff = 0;
+ } else if (fsl_chan->fsc.dir == DMA_DEV_TO_MEM) {
+ src_addr = fsl_chan->fsc.dev_addr;
+ dst_addr = dma_buf_next;
+ if (fsl_chan->is_dfifo)
+ soff = 4;
+ else
+ soff = 0;
+ doff = fsl_chan->fsc.addr_width;
+ } else {
+ /* DMA_DEV_TO_DEV */
+ src_addr = fsl_chan->fsc.dev2_addr;
+ dst_addr = fsl_chan->fsc.dev_addr;
+ soff = 0;
+ doff = 0;
+ }
+
+ fsl_edma3_fill_tcd(fsl_chan, fsl_desc->tcd[i].vtcd, src_addr,
+ dst_addr, fsl_chan->fsc.attr, soff, nbytes, 0,
+ iter, iter, doff, last_sg, true, false, true);
+ dma_buf_next += period_len;
+ }
+
+ return vchan_tx_prep(&fsl_chan->vchan, &fsl_desc->vdesc, flags);
+}
+
+static struct dma_async_tx_descriptor *fsl_edma3_prep_slave_sg(
+ struct dma_chan *chan, struct scatterlist *sgl,
+ unsigned int sg_len, enum dma_transfer_direction direction,
+ unsigned long flags, void *context)
+{
+ struct fsl_edma3_chan *fsl_chan = to_fsl_edma3_chan(chan);
+ struct fsl_edma3_desc *fsl_desc;
+ struct scatterlist *sg;
+ u32 src_addr, dst_addr, last_sg, nbytes;
+ u16 soff, doff, iter;
+ int i;
+
+ if (!is_slave_direction(fsl_chan->fsc.dir))
+ return NULL;
+
+ fsl_desc = fsl_edma3_alloc_desc(fsl_chan, sg_len);
+ if (!fsl_desc)
+ return NULL;
+ fsl_desc->iscyclic = false;
+
+ nbytes = fsl_chan->fsc.addr_width * fsl_chan->fsc.burst;
+ for_each_sg(sgl, sg, sg_len, i) {
+ /* get next sg's physical address */
+ last_sg = fsl_desc->tcd[(i + 1) % sg_len].ptcd;
+
+ if (fsl_chan->fsc.dir == DMA_MEM_TO_DEV) {
+ src_addr = sg_dma_address(sg);
+ dst_addr = fsl_chan->fsc.dev_addr;
+ soff = fsl_chan->fsc.addr_width;
+ doff = 0;
+ } else if (fsl_chan->fsc.dir == DMA_DEV_TO_MEM) {
+ src_addr = fsl_chan->fsc.dev_addr;
+ dst_addr = sg_dma_address(sg);
+ soff = 0;
+ doff = fsl_chan->fsc.addr_width;
+ } else {
+ /* DMA_DEV_TO_DEV */
+ src_addr = fsl_chan->fsc.dev2_addr;
+ dst_addr = fsl_chan->fsc.dev_addr;
+ soff = 0;
+ doff = 0;
+ }
+
+ iter = sg_dma_len(sg) / nbytes;
+ if (i < sg_len - 1) {
+ last_sg = fsl_desc->tcd[(i + 1)].ptcd;
+ fsl_edma3_fill_tcd(fsl_chan, fsl_desc->tcd[i].vtcd,
+ src_addr, dst_addr, fsl_chan->fsc.attr,
+ soff, nbytes, 0, iter, iter, doff,
+ last_sg, false, false, true);
+ } else {
+ last_sg = 0;
+ fsl_edma3_fill_tcd(fsl_chan, fsl_desc->tcd[i].vtcd,
+ src_addr, dst_addr, fsl_chan->fsc.attr,
+ soff, nbytes, 0, iter, iter, doff,
+ last_sg, true, true, false);
+ }
+ }
+
+ return vchan_tx_prep(&fsl_chan->vchan, &fsl_desc->vdesc, flags);
+}
+
+static void fsl_edma3_xfer_desc(struct fsl_edma3_chan *fsl_chan)
+{
+ struct virt_dma_desc *vdesc;
+
+ vdesc = vchan_next_desc(&fsl_chan->vchan);
+ if (!vdesc)
+ return;
+ fsl_chan->edesc = to_fsl_edma3_desc(vdesc);
+ fsl_edma3_set_tcd_regs(fsl_chan, fsl_chan->edesc->tcd[0].vtcd);
+ fsl_edma3_enable_request(fsl_chan);
+ fsl_chan->status = DMA_IN_PROGRESS;
+ fsl_chan->idle = false;
+}
+
+static size_t fsl_edma3_desc_residue(struct fsl_edma3_chan *fsl_chan,
+ struct virt_dma_desc *vdesc, bool in_progress);
+
+static void fsl_edma3_get_realcnt(struct fsl_edma3_chan *fsl_chan)
+{
+ fsl_chan->chn_real_count = fsl_edma3_desc_residue(fsl_chan, NULL, true);
+}
+
+static irqreturn_t fsl_edma3_tx_handler(int irq, void *dev_id)
+{
+ struct fsl_edma3_chan *fsl_chan = dev_id;
+ unsigned int intr;
+ void __iomem *base_addr;
+
+ base_addr = fsl_chan->membase;
+
+ intr = readl(base_addr + EDMA_CH_INT);
+ if (!intr)
+ return IRQ_NONE;
+
+ writel(1, base_addr + EDMA_CH_INT);
+
+ spin_lock(&fsl_chan->vchan.lock);
+
+ /* Ignore this interrupt since channel has been disabled already */
+ if (!fsl_chan->edesc)
+ goto irq_handled;
+
+ if (!fsl_chan->edesc->iscyclic) {
+ fsl_edma3_get_realcnt(fsl_chan);
+ list_del(&fsl_chan->edesc->vdesc.node);
+ vchan_cookie_complete(&fsl_chan->edesc->vdesc);
+ fsl_chan->edesc = NULL;
+ fsl_chan->status = DMA_COMPLETE;
+ fsl_chan->idle = true;
+ } else {
+ vchan_cyclic_callback(&fsl_chan->edesc->vdesc);
+ }
+
+ if (!fsl_chan->edesc)
+ fsl_edma3_xfer_desc(fsl_chan);
+irq_handled:
+ spin_unlock(&fsl_chan->vchan.lock);
+
+ return IRQ_HANDLED;
+}
+
+static void fsl_edma3_issue_pending(struct dma_chan *chan)
+{
+ struct fsl_edma3_chan *fsl_chan = to_fsl_edma3_chan(chan);
+ unsigned long flags;
+
+ spin_lock_irqsave(&fsl_chan->vchan.lock, flags);
+
+ if (unlikely(fsl_chan->pm_state != RUNNING)) {
+ spin_unlock_irqrestore(&fsl_chan->vchan.lock, flags);
+ /* cannot submit due to suspend */
+ return;
+ }
+
+ if (vchan_issue_pending(&fsl_chan->vchan) && !fsl_chan->edesc)
+ fsl_edma3_xfer_desc(fsl_chan);
+
+ spin_unlock_irqrestore(&fsl_chan->vchan.lock, flags);
+}
+
+static struct dma_chan *fsl_edma3_xlate(struct of_phandle_args *dma_spec,
+ struct of_dma *ofdma)
+{
+ struct fsl_edma3_engine *fsl_edma3 = ofdma->of_dma_data;
+ struct dma_chan *chan, *_chan;
+ struct fsl_edma3_chan *fsl_chan;
+
+ if (dma_spec->args_count != 3)
+ return NULL;
+
+ mutex_lock(&fsl_edma3->fsl_edma3_mutex);
+ list_for_each_entry_safe(chan, _chan, &fsl_edma3->dma_dev.channels,
+ device_node) {
+ if (chan->client_count)
+ continue;
+
+ fsl_chan = to_fsl_edma3_chan(chan);
+ if (fsl_chan->hw_chanid == dma_spec->args[0]) {
+ chan = dma_get_slave_channel(chan);
+ chan->device->privatecnt++;
+ fsl_chan->priority = dma_spec->args[1];
+ fsl_chan->is_rxchan = dma_spec->args[2] & ARGS_RX;
+ fsl_chan->is_remote = dma_spec->args[2] & ARGS_REMOTE;
+ fsl_chan->is_dfifo = dma_spec->args[2] & ARGS_DFIFO;
+ mutex_unlock(&fsl_edma3->fsl_edma3_mutex);
+ return chan;
+ }
+ }
+ mutex_unlock(&fsl_edma3->fsl_edma3_mutex);
+ return NULL;
+}
+
+static int fsl_edma3_alloc_chan_resources(struct dma_chan *chan)
+{
+ struct fsl_edma3_chan *fsl_chan = to_fsl_edma3_chan(chan);
+ struct platform_device *pdev = fsl_chan->pdev;
+ int ret;
+
+ fsl_chan->tcd_pool = dma_pool_create("tcd_pool", chan->device->dev,
+ sizeof(struct fsl_edma3_hw_tcd),
+ 32, 0);
+ /* clear meaningless pending irq anyway */
+ writel(1, fsl_chan->membase + EDMA_CH_INT);
+ ret = devm_request_irq(&pdev->dev, fsl_chan->txirq,
+ fsl_edma3_tx_handler, fsl_chan->edma3->irqflag,
+ fsl_chan->txirq_name, fsl_chan);
+ if (ret) {
+ dev_err(&pdev->dev, "Can't register %s IRQ.\n",
+ fsl_chan->txirq_name);
+ return ret;
+ }
+
+ return 0;
+}
+
+static void fsl_edma3_free_chan_resources(struct dma_chan *chan)
+{
+ struct fsl_edma3_chan *fsl_chan = to_fsl_edma3_chan(chan);
+ unsigned long flags;
+ LIST_HEAD(head);
+
+ devm_free_irq(&fsl_chan->pdev->dev, fsl_chan->txirq, fsl_chan);
+
+ spin_lock_irqsave(&fsl_chan->vchan.lock, flags);
+ fsl_edma3_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);
+ dma_pool_destroy(fsl_chan->tcd_pool);
+ fsl_chan->tcd_pool = NULL;
+ fsl_chan->used = false;
+}
+
+static void fsl_edma3_synchronize(struct dma_chan *chan)
+{
+ struct fsl_edma3_chan *fsl_chan = to_fsl_edma3_chan(chan);
+
+ vchan_synchronize(&fsl_chan->vchan);
+}
+
+static int fsl_edma3_probe(struct platform_device *pdev)
+{
+ struct device_node *np = pdev->dev.of_node;
+ struct fsl_edma3_engine *fsl_edma3;
+ struct fsl_edma3_chan *fsl_chan;
+ struct resource *res;
+ int len, chans;
+ int ret, i;
+
+ ret = of_property_read_u32(np, "dma-channels", &chans);
+ if (ret) {
+ dev_err(&pdev->dev, "Can't get dma-channels.\n");
+ return ret;
+ }
+
+ len = sizeof(*fsl_edma3) + sizeof(*fsl_chan) * chans;
+ fsl_edma3 = devm_kzalloc(&pdev->dev, len, GFP_KERNEL);
+ if (!fsl_edma3)
+ return -ENOMEM;
+
+ /* Audio edma rx/tx channel shared interrupt */
+ if (of_property_read_bool(np, "shared-interrupt"))
+ fsl_edma3->irqflag = IRQF_SHARED;
+
+ fsl_edma3->swap = false;
+ fsl_edma3->n_chans = chans;
+
+ /*
+ * FIXUP: if this is the i.MX8QM TO1.0, need set the swap.
+ * FIXME: This will be revisted to set the swap property
+ * from the device-tree node later instead of revison check,
+ * but, this will need add extra DT file, not perfect too.
+ */
+
+ if ((of_device_is_compatible(np, "fsl,imx8qm-adma")) &&
+ cpu_is_imx8qm() &&
+ imx8_get_soc_revision() == IMX_CHIP_REVISION_1_0)
+ fsl_edma3->swap = true;
+
+ INIT_LIST_HEAD(&fsl_edma3->dma_dev.channels);
+ for (i = 0; i < fsl_edma3->n_chans; i++) {
+ struct fsl_edma3_chan *fsl_chan = &fsl_edma3->chans[i];
+ const char *txirq_name;
+ char chanid[3], id_len = 0;
+ char *p = chanid;
+ unsigned long val;
+
+ fsl_chan->edma3 = fsl_edma3;
+ fsl_chan->pdev = pdev;
+ fsl_chan->pm_state = RUNNING;
+ fsl_chan->idle = true;
+ /* Get per channel membase */
+ res = platform_get_resource(pdev, IORESOURCE_MEM, i);
+ fsl_chan->membase = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(fsl_chan->membase))
+ return PTR_ERR(fsl_chan->membase);
+
+ /* Get the hardware chanel id by the channel membase
+ * channel0:0x10000, channel1:0x20000... total 32 channels
+ */
+ fsl_chan->hw_chanid = (res->start >> 16) & 0x1f;
+
+ ret = of_property_read_string_index(np, "interrupt-names", i,
+ &txirq_name);
+ if (ret) {
+ dev_err(&pdev->dev, "read interrupt-names fail.\n");
+ return ret;
+ }
+ /* Get channel id length from dts, one-digit or double-digit */
+ id_len = strlen(txirq_name) - strlen(CHAN_PREFIX) -
+ strlen(CHAN_POSFIX);
+ if (id_len > 2) {
+ dev_err(&pdev->dev, "%s is edmaX-chanX-tx in dts?\n",
+ res->name);
+ return -EINVAL;
+ }
+ /* Grab channel id from txirq_name */
+ strncpy(p, txirq_name + strlen(CHAN_PREFIX), id_len);
+ *(p + id_len) = '\0';
+
+ /* check if the channel id match well with hw_chanid */
+ ret = kstrtoul(chanid, 0, &val);
+ if (ret || val != fsl_chan->hw_chanid) {
+ dev_err(&pdev->dev, "%s,wrong id?\n", txirq_name);
+ return -EINVAL;
+ }
+
+ /* request channel irq */
+ fsl_chan->txirq = platform_get_irq_byname(pdev, txirq_name);
+ if (fsl_chan->txirq < 0) {
+ dev_err(&pdev->dev, "Can't get %s irq.\n", txirq_name);
+ return fsl_chan->txirq;
+ }
+
+ memcpy(fsl_chan->txirq_name, txirq_name, strlen(txirq_name));
+
+ fsl_chan->vchan.desc_free = fsl_edma3_free_desc;
+ vchan_init(&fsl_chan->vchan, &fsl_edma3->dma_dev);
+ fsl_chan->used = false;
+ }
+
+ mutex_init(&fsl_edma3->fsl_edma3_mutex);
+
+ dma_cap_set(DMA_PRIVATE, fsl_edma3->dma_dev.cap_mask);
+ dma_cap_set(DMA_SLAVE, fsl_edma3->dma_dev.cap_mask);
+ dma_cap_set(DMA_CYCLIC, fsl_edma3->dma_dev.cap_mask);
+
+ fsl_edma3->dma_dev.dev = &pdev->dev;
+ fsl_edma3->dma_dev.device_alloc_chan_resources
+ = fsl_edma3_alloc_chan_resources;
+ fsl_edma3->dma_dev.device_free_chan_resources
+ = fsl_edma3_free_chan_resources;
+ fsl_edma3->dma_dev.device_tx_status = fsl_edma3_tx_status;
+ fsl_edma3->dma_dev.device_prep_slave_sg = fsl_edma3_prep_slave_sg;
+ fsl_edma3->dma_dev.device_prep_dma_cyclic = fsl_edma3_prep_dma_cyclic;
+ fsl_edma3->dma_dev.device_config = fsl_edma3_slave_config;
+ fsl_edma3->dma_dev.device_pause = fsl_edma3_pause;
+ fsl_edma3->dma_dev.device_resume = fsl_edma3_resume;
+ fsl_edma3->dma_dev.device_terminate_all = fsl_edma3_terminate_all;
+ fsl_edma3->dma_dev.device_issue_pending = fsl_edma3_issue_pending;
+ fsl_edma3->dma_dev.device_synchronize = fsl_edma3_synchronize;
+
+ fsl_edma3->dma_dev.src_addr_widths = FSL_EDMA_BUSWIDTHS;
+ fsl_edma3->dma_dev.dst_addr_widths = FSL_EDMA_BUSWIDTHS;
+ fsl_edma3->dma_dev.directions = BIT(DMA_DEV_TO_MEM) |
+ BIT(DMA_MEM_TO_DEV) |
+ BIT(DMA_DEV_TO_DEV);
+
+ platform_set_drvdata(pdev, fsl_edma3);
+
+ ret = dma_async_device_register(&fsl_edma3->dma_dev);
+ if (ret) {
+ dev_err(&pdev->dev, "Can't register Freescale eDMA engine.\n");
+ return ret;
+ }
+
+ ret = of_dma_controller_register(np, fsl_edma3_xlate, fsl_edma3);
+ if (ret) {
+ dev_err(&pdev->dev, "Can't register Freescale eDMA of_dma.\n");
+ dma_async_device_unregister(&fsl_edma3->dma_dev);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int fsl_edma3_remove(struct platform_device *pdev)
+{
+ struct device_node *np = pdev->dev.of_node;
+ struct fsl_edma3_engine *fsl_edma3 = platform_get_drvdata(pdev);
+
+ of_dma_controller_free(np);
+ dma_async_device_unregister(&fsl_edma3->dma_dev);
+
+ return 0;
+}
+
+static int fsl_edma3_suspend_late(struct device *dev)
+{
+ struct fsl_edma3_engine *fsl_edma = dev_get_drvdata(dev);
+ struct fsl_edma3_chan *fsl_chan;
+ unsigned long flags;
+ void __iomem *addr;
+ int i;
+
+ for (i = 0; i < fsl_edma->n_chans; i++) {
+ fsl_chan = &fsl_edma->chans[i];
+ addr = fsl_chan->membase;
+
+ if (!fsl_chan->used)
+ continue;
+ spin_lock_irqsave(&fsl_chan->vchan.lock, flags);
+ fsl_edma->edma_regs[i].csr = readl(addr + EDMA_CH_CSR);
+ fsl_edma->edma_regs[i].sbr = readl(addr + EDMA_CH_SBR);
+ /* Make sure chan is idle or will force disable. */
+ if (unlikely(!fsl_chan->idle)) {
+ dev_warn(dev, "WARN: There is non-idle channel.");
+ fsl_edma3_disable_request(fsl_chan);
+ }
+ fsl_chan->pm_state = SUSPENDED;
+ spin_unlock_irqrestore(&fsl_chan->vchan.lock, flags);
+ }
+
+ return 0;
+}
+
+static int fsl_edma3_resume_early(struct device *dev)
+{
+ struct fsl_edma3_engine *fsl_edma = dev_get_drvdata(dev);
+ struct fsl_edma3_chan *fsl_chan;
+ void __iomem *addr;
+ unsigned long flags;
+ int i;
+
+ for (i = 0; i < fsl_edma->n_chans; i++) {
+ fsl_chan = &fsl_edma->chans[i];
+ addr = fsl_chan->membase;
+
+ if (!fsl_chan->used)
+ continue;
+
+ spin_lock_irqsave(&fsl_chan->vchan.lock, flags);
+ writel(fsl_edma->edma_regs[i].csr, addr + EDMA_CH_CSR);
+ writel(fsl_edma->edma_regs[i].sbr, addr + EDMA_CH_SBR);
+ /* restore tcd if this channel not terminated before suspend */
+ if (fsl_chan->edesc)
+ fsl_edma3_set_tcd_regs(fsl_chan,
+ fsl_chan->edesc->tcd[0].vtcd);
+ fsl_chan->pm_state = RUNNING;
+ spin_unlock_irqrestore(&fsl_chan->vchan.lock, flags);
+ }
+
+ return 0;
+}
+
+static const struct dev_pm_ops fsl_edma3_pm_ops = {
+ .suspend_late = fsl_edma3_suspend_late,
+ .resume_early = fsl_edma3_resume_early,
+};
+
+static const struct of_device_id fsl_edma3_dt_ids[] = {
+ { .compatible = "fsl,imx8qm-edma", },
+ { .compatible = "fsl,imx8qm-adma", },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, fsl_edma3_dt_ids);
+
+static struct platform_driver fsl_edma3_driver = {
+ .driver = {
+ .name = "fsl-edma-v3",
+ .of_match_table = fsl_edma3_dt_ids,
+ .pm = &fsl_edma3_pm_ops,
+ },
+ .probe = fsl_edma3_probe,
+ .remove = fsl_edma3_remove,
+};
+
+static int __init fsl_edma3_init(void)
+{
+ return platform_driver_register(&fsl_edma3_driver);
+}
+subsys_initcall(fsl_edma3_init);
+
+static void __exit fsl_edma3_exit(void)
+{
+ platform_driver_unregister(&fsl_edma3_driver);
+}
+module_exit(fsl_edma3_exit);
+
+MODULE_ALIAS("platform:fsl-edma3");
+MODULE_DESCRIPTION("Freescale eDMA-V3 engine driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/dma/fsl-edma.c b/drivers/dma/fsl-edma.c
index c7568869284e..afc4215d4b47 100644
--- a/drivers/dma/fsl-edma.c
+++ b/drivers/dma/fsl-edma.c
@@ -2,6 +2,7 @@
* drivers/dma/fsl-edma.c
*
* Copyright 2013-2014 Freescale Semiconductor, Inc.
+ * Copyright 2017 NXP
*
* Driver for the Freescale eDMA engine with flexible channel multiplexing
* capability for DMA request sources. The eDMA block can be found on some
@@ -111,11 +112,18 @@
#define EDMAMUX_CHCFG_SOURCE(n) ((n) & 0x3F)
#define DMAMUX_NR 2
+#define FSL_EDMA_REG_NUM 3
+#define FSL_DMAMUX_SLOTS 32
+#define FSL_DMAMUX_REG_NUM (DMAMUX_NR * FSL_DMAMUX_SLOTS)
#define FSL_EDMA_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)
+
+/* Controller will loss power in i.MX7ULP VLLS low power mode */
+#define FSL_EDMA_QUIRK_VLLS_MODE (1 << 0)
+
enum fsl_edma_pm_state {
RUNNING = 0,
SUSPENDED,
@@ -158,6 +166,8 @@ struct fsl_edma_chan {
struct fsl_edma_desc *edesc;
struct fsl_edma_slave_config fsc;
struct dma_pool *tcd_pool;
+ char chan_name[16];
+ u32 chn_real_count;
};
struct fsl_edma_desc {
@@ -172,15 +182,79 @@ struct fsl_edma_engine {
struct dma_device dma_dev;
void __iomem *membase;
void __iomem *muxbase[DMAMUX_NR];
+ struct clk *dmaclk;
struct clk *muxclk[DMAMUX_NR];
struct mutex fsl_edma_mutex;
u32 n_chans;
int txirq;
int errirq;
bool big_endian;
+ u32 dmamux_nr;
+ u32 version;
+ void (*mux_configure)(struct fsl_edma_chan *,
+ void __iomem *muxaddr, u32 off,
+ u32 slot, bool enable);
+ u32 edma_regs[FSL_EDMA_REG_NUM];
+ u32 dmamux_regs[FSL_DMAMUX_REG_NUM];
+ u32 quirks;
struct fsl_edma_chan chans[];
};
+static struct platform_device_id fsl_edma_devtype[] = {
+ {
+ .name = "vf610-edma",
+ .driver_data = 0,
+ }, {
+ .name = "imx7ulp-edma",
+ .driver_data = FSL_EDMA_QUIRK_VLLS_MODE,
+ }, {
+ /* sentinel */
+ }
+};
+MODULE_DEVICE_TABLE(platform, fsl_edma_devtype);
+
+enum fsl_edma_type {
+ VF610_EDMA,
+ IMX7ULP_EDMA,
+};
+
+static const struct of_device_id fsl_edma_dt_ids[] = {
+ {
+ .compatible = "fsl,vf610-edma",
+ .data = &fsl_edma_devtype[VF610_EDMA],
+ }, {
+ .compatible = "nxp,imx7ulp-edma",
+ .data = &fsl_edma_devtype[IMX7ULP_EDMA],
+ }, { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, fsl_edma_dt_ids);
+
+void mux_configure8(struct fsl_edma_chan *fsl_chan, void __iomem *muxaddr,
+ u32 off, u32 slot, bool enable)
+{
+ u8 val8;
+
+ if (enable)
+ val8 = EDMAMUX_CHCFG_ENBL | slot;
+ else
+ val8 = EDMAMUX_CHCFG_DIS;
+
+ iowrite8(val8, muxaddr + off);
+}
+
+void mux_configure32(struct fsl_edma_chan *fsl_chan, void __iomem *muxaddr,
+ u32 off, u32 slot, bool enable)
+{
+ u32 val;
+
+ if (enable)
+ val = EDMAMUX_CHCFG_ENBL << 24 | slot;
+ else
+ val = EDMAMUX_CHCFG_DIS;
+
+ iowrite32(val, muxaddr + off * 4);
+}
+
/*
* R/W functions for big- or little-endian registers:
* The eDMA controller's endian is independent of the CPU core's endian.
@@ -257,15 +331,12 @@ static void fsl_edma_chan_mux(struct fsl_edma_chan *fsl_chan,
void __iomem *muxaddr;
unsigned chans_per_mux, ch_off;
- chans_per_mux = fsl_chan->edma->n_chans / DMAMUX_NR;
+ chans_per_mux = fsl_chan->edma->n_chans / fsl_chan->edma->dmamux_nr;
ch_off = fsl_chan->vchan.chan.chan_id % chans_per_mux;
muxaddr = fsl_chan->edma->muxbase[ch / chans_per_mux];
slot = EDMAMUX_CHCFG_SOURCE(slot);
- if (enable)
- iowrite8(EDMAMUX_CHCFG_ENBL | slot, muxaddr + ch_off);
- else
- iowrite8(EDMAMUX_CHCFG_DIS, muxaddr + ch_off);
+ fsl_chan->edma->mux_configure(fsl_chan, muxaddr, ch_off, slot, enable);
}
static unsigned int fsl_edma_get_tcd_attr(enum dma_slave_buswidth addr_width)
@@ -306,13 +377,14 @@ static int fsl_edma_terminate_all(struct dma_chan *chan)
fsl_edma_disable_request(fsl_chan);
fsl_chan->edesc = NULL;
fsl_chan->idle = true;
+ fsl_chan->vchan.cyclic = 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)
+static int fsl_edma_device_pause(struct dma_chan *chan)
{
struct fsl_edma_chan *fsl_chan = to_fsl_edma_chan(chan);
unsigned long flags;
@@ -327,7 +399,7 @@ static int fsl_edma_pause(struct dma_chan *chan)
return 0;
}
-static int fsl_edma_resume(struct dma_chan *chan)
+static int fsl_edma_device_resume(struct dma_chan *chan)
{
struct fsl_edma_chan *fsl_chan = to_fsl_edma_chan(chan);
unsigned long flags;
@@ -416,8 +488,12 @@ static enum dma_status fsl_edma_tx_status(struct dma_chan *chan,
unsigned long flags;
status = dma_cookie_status(chan, cookie, txstate);
- if (status == DMA_COMPLETE)
+ if (status == DMA_COMPLETE) {
+ spin_lock_irqsave(&fsl_chan->vchan.lock, flags);
+ txstate->residue = fsl_chan->chn_real_count;
+ spin_unlock_irqrestore(&fsl_chan->vchan.lock, flags);
return status;
+ }
if (!txstate)
return fsl_chan->status;
@@ -426,7 +502,7 @@ static enum dma_status fsl_edma_tx_status(struct dma_chan *chan,
vdesc = vchan_find_desc(&fsl_chan->vchan, cookie);
if (fsl_chan->edesc && cookie == fsl_chan->edesc->vdesc.tx.cookie)
txstate->residue = fsl_edma_desc_residue(fsl_chan, vdesc, true);
- else if (vdesc)
+ else if (fsl_chan->edesc && vdesc)
txstate->residue = fsl_edma_desc_residue(fsl_chan, vdesc, false);
else
txstate->residue = 0;
@@ -661,6 +737,11 @@ static void fsl_edma_xfer_desc(struct fsl_edma_chan *fsl_chan)
fsl_chan->idle = false;
}
+static void fsl_edma_get_realcnt(struct fsl_edma_chan *fsl_chan)
+{
+ fsl_chan->chn_real_count = fsl_edma_desc_residue(fsl_chan, NULL, true);
+}
+
static irqreturn_t fsl_edma_tx_handler(int irq, void *dev_id)
{
struct fsl_edma_engine *fsl_edma = dev_id;
@@ -683,6 +764,7 @@ static irqreturn_t fsl_edma_tx_handler(int irq, void *dev_id)
spin_lock(&fsl_chan->vchan.lock);
if (!fsl_chan->edesc->iscyclic) {
+ fsl_edma_get_realcnt(fsl_chan);
list_del(&fsl_chan->edesc->vdesc.node);
vchan_cookie_complete(&fsl_chan->edesc->vdesc);
fsl_chan->edesc = NULL;
@@ -712,6 +794,7 @@ static irqreturn_t fsl_edma_err_handler(int irq, void *dev_id)
for (ch = 0; ch < fsl_edma->n_chans; ch++) {
if (err & (0x1 << ch)) {
+ dev_err(fsl_edma->dma_dev.dev, "DMA CH%d Err!\n", ch);
fsl_edma_disable_request(&fsl_edma->chans[ch]);
edma_writeb(fsl_edma, EDMA_CERR_CERR(ch),
fsl_edma->membase + EDMA_CERR);
@@ -755,7 +838,7 @@ static struct dma_chan *fsl_edma_xlate(struct of_phandle_args *dma_spec,
struct fsl_edma_engine *fsl_edma = ofdma->of_dma_data;
struct dma_chan *chan, *_chan;
struct fsl_edma_chan *fsl_chan;
- unsigned long chans_per_mux = fsl_edma->n_chans / DMAMUX_NR;
+ unsigned long chans_per_mux = fsl_edma->n_chans / fsl_edma->dmamux_nr;
if (dma_spec->args_count != 2)
return NULL;
@@ -867,8 +950,58 @@ static void fsl_disable_clocks(struct fsl_edma_engine *fsl_edma, int nr_clocks)
{
int i;
- for (i = 0; i < nr_clocks; i++)
+ for (i = 0; i < fsl_edma->dmamux_nr; i++)
clk_disable_unprepare(fsl_edma->muxclk[i]);
+
+ if (fsl_edma->dmaclk)
+ clk_disable_unprepare(fsl_edma->dmaclk);
+}
+
+static int
+fsl_edma2_irq_init(struct platform_device *pdev,
+ struct fsl_edma_engine *fsl_edma)
+{
+ struct device_node *np = pdev->dev.of_node;
+ int i, ret, irq;
+ int count = 0;
+
+ count = of_irq_count(np);
+ dev_info(&pdev->dev, "%s Found %d interrupts\r\n", __func__, count);
+ if(count < 2){
+ dev_err(&pdev->dev, "Interrupts in DTS not correct.\n");
+ return -EINVAL;
+ }
+
+ for (i = 0; i < count; i++) {
+ irq = platform_get_irq(pdev, i);
+ if (irq < 0)
+ return -ENXIO;
+
+ sprintf(fsl_edma->chans[i].chan_name, "eDMA2-CH%02d", i);
+
+ /* The last IRQ is for eDMA err */
+ if (i == count - 1)
+ ret = devm_request_irq(&pdev->dev, irq,
+ fsl_edma_err_handler,
+ 0, "eDMA2-ERR", fsl_edma);
+ else
+
+ ret = devm_request_irq(&pdev->dev, irq,
+ fsl_edma_tx_handler, 0,
+ fsl_edma->chans[i].chan_name,
+ fsl_edma);
+ if(ret)
+ return ret;
+ }
+
+ return 0;
+}
+
+static void fsl_edma_synchronize(struct dma_chan *chan)
+{
+ struct fsl_edma_chan *fsl_chan = to_fsl_edma_chan(chan);
+
+ vchan_synchronize(&fsl_chan->vchan);
}
static int fsl_edma_probe(struct platform_device *pdev)
@@ -876,6 +1009,7 @@ static int fsl_edma_probe(struct platform_device *pdev)
struct device_node *np = pdev->dev.of_node;
struct fsl_edma_engine *fsl_edma;
struct fsl_edma_chan *fsl_chan;
+ const struct of_device_id *of_id;
struct resource *res;
int len, chans;
int ret, i;
@@ -891,6 +1025,11 @@ static int fsl_edma_probe(struct platform_device *pdev)
if (!fsl_edma)
return -ENOMEM;
+ of_id = of_match_device(fsl_edma_dt_ids, &pdev->dev);
+ if (of_id)
+ pdev->id_entry = of_id->data;
+ fsl_edma->quirks = pdev->id_entry->driver_data;
+
fsl_edma->n_chans = chans;
mutex_init(&fsl_edma->fsl_edma_mutex);
@@ -899,7 +1038,29 @@ static int fsl_edma_probe(struct platform_device *pdev)
if (IS_ERR(fsl_edma->membase))
return PTR_ERR(fsl_edma->membase);
- for (i = 0; i < DMAMUX_NR; i++) {
+ fsl_edma->dmamux_nr = DMAMUX_NR;
+ fsl_edma->mux_configure = mux_configure8;
+ fsl_edma->version = 1;
+
+ if (of_device_is_compatible(np, "nxp,imx7ulp-edma")) {
+ fsl_edma->dmamux_nr = 1;
+ fsl_edma->mux_configure = mux_configure32;
+ fsl_edma->version = 2;
+
+ fsl_edma->dmaclk = devm_clk_get(&pdev->dev, "dma");
+ if (IS_ERR(fsl_edma->dmaclk)) {
+ dev_err(&pdev->dev, "Missing DMA block clock.\n");
+ return PTR_ERR(fsl_edma->dmaclk);
+ }
+
+ ret = clk_prepare_enable(fsl_edma->dmaclk);
+ if (ret) {
+ dev_err(&pdev->dev, "DMA clk block failed.\n");
+ return ret;
+ }
+ }
+
+ for (i = 0; i < fsl_edma->dmamux_nr; i++) {
char clkname[32];
res = platform_get_resource(pdev, IORESOURCE_MEM, 1 + i);
@@ -926,6 +1087,14 @@ static int fsl_edma_probe(struct platform_device *pdev)
}
+ edma_writel(fsl_edma, ~0, fsl_edma->membase + EDMA_INTR);
+ if (fsl_edma->version == 1)
+ ret = fsl_edma_irq_init(pdev, fsl_edma);
+ else
+ ret = fsl_edma2_irq_init(pdev, fsl_edma);
+ if (ret)
+ return ret;
+
fsl_edma->big_endian = of_property_read_bool(np, "big-endian");
INIT_LIST_HEAD(&fsl_edma->dma_dev.channels);
@@ -940,14 +1109,11 @@ static int fsl_edma_probe(struct platform_device *pdev)
vchan_init(&fsl_chan->vchan, &fsl_edma->dma_dev);
edma_writew(fsl_edma, 0x0, fsl_edma->membase + EDMA_TCD_CSR(i));
+ fsl_chan->vchan.chan.chan_id = i;
fsl_edma_chan_mux(fsl_chan, 0, false);
+ fsl_chan->vchan.chan.chan_id = 0;
}
- edma_writel(fsl_edma, ~0, fsl_edma->membase + EDMA_INTR);
- ret = fsl_edma_irq_init(pdev, fsl_edma);
- if (ret)
- return ret;
-
dma_cap_set(DMA_PRIVATE, fsl_edma->dma_dev.cap_mask);
dma_cap_set(DMA_SLAVE, fsl_edma->dma_dev.cap_mask);
dma_cap_set(DMA_CYCLIC, fsl_edma->dma_dev.cap_mask);
@@ -961,10 +1127,11 @@ static int fsl_edma_probe(struct platform_device *pdev)
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_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_pause = fsl_edma_device_pause;
+ fsl_edma->dma_dev.device_resume = fsl_edma_device_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_synchronize = fsl_edma_synchronize;
fsl_edma->dma_dev.src_addr_widths = FSL_EDMA_BUSWIDTHS;
fsl_edma->dma_dev.dst_addr_widths = FSL_EDMA_BUSWIDTHS;
@@ -1020,6 +1187,56 @@ static int fsl_edma_remove(struct platform_device *pdev)
return 0;
}
+static int fsl_edma_register_save(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct fsl_edma_engine *fsl_edma = platform_get_drvdata(pdev);
+ int i, j;
+
+ if (!(fsl_edma->quirks & FSL_EDMA_QUIRK_VLLS_MODE))
+ return 0;
+
+ /* save regs */
+ fsl_edma->edma_regs[0] =
+ edma_readl(fsl_edma, fsl_edma->membase + EDMA_CR);
+ fsl_edma->edma_regs[1] =
+ edma_readl(fsl_edma, fsl_edma->membase + EDMA_ERQ);
+ fsl_edma->edma_regs[2] =
+ edma_readl(fsl_edma, fsl_edma->membase + EDMA_EEI);
+ for (i = 0; i < fsl_edma->dmamux_nr; i++)
+ for (j = 0; j < fsl_edma->n_chans; j++)
+ fsl_edma->dmamux_regs[i * fsl_edma->n_chans + j] =
+ edma_readl(fsl_edma,
+ fsl_edma->muxbase[i] + j * 4);
+
+ return 0;
+}
+
+static int fsl_edma_register_restore(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct fsl_edma_engine *fsl_edma = platform_get_drvdata(pdev);
+ int i, j;
+
+ if (!(fsl_edma->quirks & FSL_EDMA_QUIRK_VLLS_MODE))
+ return 0;
+
+ /* restore the regs */
+ for (i = 0; i < fsl_edma->dmamux_nr; i++)
+ for (j = 0; j < fsl_edma->n_chans; j++)
+ edma_writel(fsl_edma,
+ fsl_edma->dmamux_regs[i * fsl_edma->n_chans + j],
+ fsl_edma->muxbase[i] + j * 4);
+ edma_writel(fsl_edma, fsl_edma->edma_regs[1],
+ fsl_edma->membase + EDMA_ERQ);
+ edma_writel(fsl_edma, fsl_edma->edma_regs[2],
+ fsl_edma->membase + EDMA_EEI);
+ edma_writel(fsl_edma, fsl_edma->edma_regs[0],
+ fsl_edma->membase + EDMA_CR);
+
+ return 0;
+}
+
static int fsl_edma_suspend_late(struct device *dev)
{
struct fsl_edma_engine *fsl_edma = dev_get_drvdata(dev);
@@ -1041,6 +1258,8 @@ static int fsl_edma_suspend_late(struct device *dev)
spin_unlock_irqrestore(&fsl_chan->vchan.lock, flags);
}
+ fsl_edma_register_save(dev);
+
return 0;
}
@@ -1050,6 +1269,8 @@ static int fsl_edma_resume_early(struct device *dev)
struct fsl_edma_chan *fsl_chan;
int i;
+ fsl_edma_register_restore(dev);
+
for (i = 0; i < fsl_edma->n_chans; i++) {
fsl_chan = &fsl_edma->chans[i];
fsl_chan->pm_state = RUNNING;
@@ -1074,18 +1295,13 @@ static const struct dev_pm_ops fsl_edma_pm_ops = {
.resume_early = fsl_edma_resume_early,
};
-static const struct of_device_id fsl_edma_dt_ids[] = {
- { .compatible = "fsl,vf610-edma", },
- { /* sentinel */ }
-};
-MODULE_DEVICE_TABLE(of, fsl_edma_dt_ids);
-
static struct platform_driver fsl_edma_driver = {
.driver = {
.name = "fsl-edma",
.of_match_table = fsl_edma_dt_ids,
.pm = &fsl_edma_pm_ops,
},
+ .id_table = fsl_edma_devtype,
.probe = fsl_edma_probe,
.remove = fsl_edma_remove,
};
diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c
index 0fc12a8783e3..ec071112499d 100644
--- a/drivers/dma/imx-sdma.c
+++ b/drivers/dma/imx-sdma.c
@@ -7,7 +7,8 @@
*
* Based on code from Freescale:
*
- * Copyright 2004-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2004-2016 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2018 NXP.
*
* The code contained herein is licensed under the GNU General Public
* License. You may obtain a copy of the GNU General Public License
@@ -30,7 +31,9 @@
#include <linux/semaphore.h>
#include <linux/spinlock.h>
#include <linux/device.h>
+#include <linux/genalloc.h>
#include <linux/dma-mapping.h>
+#include <linux/dmapool.h>
#include <linux/firmware.h>
#include <linux/slab.h>
#include <linux/platform_device.h>
@@ -48,6 +51,7 @@
#include <linux/mfd/syscon/imx6q-iomuxc-gpr.h>
#include "dmaengine.h"
+#include "virt-dma.h"
/* SDMA registers */
#define SDMA_H_C0PTR 0x000
@@ -79,6 +83,9 @@
#define SDMA_CHNENBL0_IMX35 0x200
#define SDMA_CHNENBL0_IMX31 0x080
#define SDMA_CHNPRI_0 0x100
+#define SDMA_DONE0_CONFIG 0x1000
+#define SDMA_DONE0_CONFIG_DONE_SEL 0x7
+#define SDMA_DONE0_CONFIG_DONE_DIS 0x6
/*
* Buffer descriptor status values.
@@ -173,11 +180,26 @@
#define SDMA_WATERMARK_LEVEL_SPDIF BIT(10)
#define SDMA_WATERMARK_LEVEL_SP BIT(11)
#define SDMA_WATERMARK_LEVEL_DP BIT(12)
+#define SDMA_WATERMARK_LEVEL_SD BIT(13)
+#define SDMA_WATERMARK_LEVEL_DD BIT(14)
#define SDMA_WATERMARK_LEVEL_HWML (0xFF << 16)
#define SDMA_WATERMARK_LEVEL_LWE BIT(28)
#define SDMA_WATERMARK_LEVEL_HWE BIT(29)
#define SDMA_WATERMARK_LEVEL_CONT BIT(31)
+#define SDMA_DMA_BUSWIDTHS (BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | \
+ BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) | \
+ BIT(DMA_SLAVE_BUSWIDTH_3_BYTES) | \
+ BIT(DMA_SLAVE_BUSWIDTH_4_BYTES))
+
+#define SDMA_DMA_DIRECTIONS (BIT(DMA_DEV_TO_MEM) | \
+ BIT(DMA_MEM_TO_DEV) | \
+ BIT(DMA_DEV_TO_DEV))
+
+#define SDMA_WATERMARK_LEVEL_FIFOS_OFF 12
+#define SDMA_WATERMARK_LEVEL_SW_DONE BIT(23)
+#define SDMA_WATERMARK_LEVEL_SW_DONE_SEL_OFF 24
+
/*
* Mode/Count of data node descriptors - IPCv2
*/
@@ -284,9 +306,22 @@ struct sdma_context_data {
} __attribute__ ((packed));
#define NUM_BD (int)(PAGE_SIZE / sizeof(struct sdma_buffer_descriptor))
+#define SDMA_BD_MAX_CNT 0xfffc /* align with 4 bytes */
struct sdma_engine;
+struct sdma_desc {
+ struct virt_dma_desc vd;
+ struct list_head node;
+ unsigned int num_bd;
+ dma_addr_t bd_phys;
+ bool bd_iram;
+ unsigned int buf_tail;
+ unsigned int buf_ptail;
+ struct sdma_channel *sdmac;
+ struct sdma_buffer_descriptor *bd;
+};
+
/**
* struct sdma_channel - housekeeping for a SDMA channel
*
@@ -300,36 +335,40 @@ struct sdma_engine;
* @buf_tail ID of the buffer that was processed
* @buf_ptail ID of the previous buffer that was processed
* @num_bd max NUM_BD. number of descriptors currently handling
+ * @bd_iram flag indicating the memory location of buffer descriptor
*/
struct sdma_channel {
+ struct virt_dma_chan vc;
+ struct list_head pending;
struct sdma_engine *sdma;
+ struct sdma_desc *desc;
unsigned int channel;
enum dma_transfer_direction direction;
enum sdma_peripheral_type peripheral_type;
unsigned int event_id0;
unsigned int event_id1;
enum dma_slave_buswidth word_size;
- unsigned int buf_tail;
- unsigned int buf_ptail;
- unsigned int num_bd;
unsigned int period_len;
- struct sdma_buffer_descriptor *bd;
- dma_addr_t bd_phys;
unsigned int pc_from_device, pc_to_device;
unsigned int device_to_device;
+ unsigned int pc_to_pc;
unsigned long flags;
dma_addr_t per_address, per_address2;
unsigned long event_mask[2];
unsigned long watermark_level;
u32 shp_addr, per_addr;
- struct dma_chan chan;
- spinlock_t lock;
- struct dma_async_tx_descriptor desc;
enum dma_status status;
+ struct imx_dma_data data;
unsigned int chn_count;
unsigned int chn_real_count;
- struct tasklet_struct tasklet;
- struct imx_dma_data data;
+ bool context_loaded;
+ u32 bd_size_sum;
+ bool src_dualfifo;
+ bool dst_dualfifo;
+ unsigned int fifo_num;
+ bool sw_done;
+ u32 sw_done_sel;
+ struct dma_pool *bd_pool;
};
#define IMX_DMA_SG_LOOP BIT(0)
@@ -338,6 +377,14 @@ struct sdma_channel {
#define MXC_SDMA_DEFAULT_PRIORITY 1
#define MXC_SDMA_MIN_PRIORITY 1
#define MXC_SDMA_MAX_PRIORITY 7
+/*
+ * 0x78(SDMA_XTRIG_CONF2+4)~0x100(SDMA_CHNPRI_O) registers are reserved and
+ * can't be accessed. Skip these register touch in suspend/resume. Also below
+ * two macros are only used on i.mx6sx.
+ */
+#define MXC_SDMA_RESERVED_REG (SDMA_CHNPRI_0 - SDMA_XTRIG_CONF2 - 4)
+#define MXC_SDMA_SAVED_REG_NUM (((SDMA_CHNENBL0_IMX35 + 4 * 48) - \
+ MXC_SDMA_RESERVED_REG) / 4)
#define SDMA_FIRMWARE_MAGIC 0x414d4453
@@ -376,6 +423,8 @@ struct sdma_engine {
struct device_dma_parameters dma_parms;
struct sdma_channel channel[MAX_DMA_CHANNELS];
struct sdma_channel_control *channel_control;
+ u32 save_regs[MXC_SDMA_SAVED_REG_NUM];
+ const char *fw_name;
void __iomem *regs;
struct sdma_context_data *context;
dma_addr_t context_phys;
@@ -389,6 +438,15 @@ struct sdma_engine {
u32 spba_start_addr;
u32 spba_end_addr;
unsigned int irq;
+ struct gen_pool *iram_pool;
+ /* channel0 bd */
+ dma_addr_t bd0_phys;
+ bool bd0_iram;
+ struct sdma_buffer_descriptor *bd0;
+ bool fw_loaded;
+ int idx;
+ /* clock ration for AHB:SDMA core. 1:1 is 1, 2:1 is 0*/
+ bool clk_ratio;
};
static struct sdma_driver_data sdma_imx31 = {
@@ -466,7 +524,6 @@ static struct sdma_script_start_addrs sdma_script_imx6q = {
.ap_2_ap_addr = 642,
.uart_2_mcu_addr = 817,
.mcu_2_app_addr = 747,
- .per_2_per_addr = 6331,
.uartsh_2_mcu_addr = 1032,
.mcu_2_shp_addr = 960,
.app_2_mcu_addr = 683,
@@ -481,6 +538,30 @@ static struct sdma_driver_data sdma_imx6q = {
.script_addrs = &sdma_script_imx6q,
};
+static struct sdma_script_start_addrs sdma_script_imx6sx = {
+ .ap_2_ap_addr = 642,
+ .uart_2_mcu_addr = 817,
+ .mcu_2_app_addr = 747,
+ .uartsh_2_mcu_addr = 1032,
+ .mcu_2_shp_addr = 960,
+ .app_2_mcu_addr = 683,
+ .shp_2_mcu_addr = 891,
+ .spdif_2_mcu_addr = 1100,
+ .mcu_2_spdif_addr = 1134,
+};
+
+static struct sdma_driver_data sdma_imx6sx = {
+ .chnenbl0 = SDMA_CHNENBL0_IMX35,
+ .num_events = 48,
+ .script_addrs = &sdma_script_imx6sx,
+};
+
+static struct sdma_driver_data sdma_imx6ul = {
+ .chnenbl0 = SDMA_CHNENBL0_IMX35,
+ .num_events = 48,
+ .script_addrs = &sdma_script_imx6sx,
+};
+
static struct sdma_script_start_addrs sdma_script_imx7d = {
.ap_2_ap_addr = 644,
.uart_2_mcu_addr = 819,
@@ -499,6 +580,12 @@ static struct sdma_driver_data sdma_imx7d = {
.script_addrs = &sdma_script_imx7d,
};
+static struct sdma_driver_data sdma_imx8m = {
+ .chnenbl0 = SDMA_CHNENBL0_IMX35,
+ .num_events = 48,
+ .script_addrs = &sdma_script_imx7d,
+};
+
static const struct platform_device_id sdma_devtypes[] = {
{
.name = "imx25-sdma",
@@ -519,15 +606,23 @@ static const struct platform_device_id sdma_devtypes[] = {
.name = "imx6q-sdma",
.driver_data = (unsigned long)&sdma_imx6q,
}, {
+ .name = "imx6sx-sdma",
+ .driver_data = (unsigned long)&sdma_imx6sx,
+ }, {
.name = "imx7d-sdma",
.driver_data = (unsigned long)&sdma_imx7d,
}, {
+ .name = "imx8mq-sdma",
+ .driver_data = (unsigned long)&sdma_imx8m,
+ }, {
/* sentinel */
}
};
MODULE_DEVICE_TABLE(platform, sdma_devtypes);
static const struct of_device_id sdma_dt_ids[] = {
+ { .compatible = "fsl,imx6ul-sdma", .data = &sdma_imx6ul, },
+ { .compatible = "fsl,imx6sx-sdma", .data = &sdma_imx6sx, },
{ .compatible = "fsl,imx6q-sdma", .data = &sdma_imx6q, },
{ .compatible = "fsl,imx53-sdma", .data = &sdma_imx53, },
{ .compatible = "fsl,imx51-sdma", .data = &sdma_imx51, },
@@ -535,15 +630,20 @@ static const struct of_device_id sdma_dt_ids[] = {
{ .compatible = "fsl,imx31-sdma", .data = &sdma_imx31, },
{ .compatible = "fsl,imx25-sdma", .data = &sdma_imx25, },
{ .compatible = "fsl,imx7d-sdma", .data = &sdma_imx7d, },
+ { .compatible = "fsl,imx8mq-sdma", .data = &sdma_imx8m, },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, sdma_dt_ids);
+static int sdma_dev_idx;
+
#define SDMA_H_CONFIG_DSPDMA BIT(12) /* indicates if the DSPDMA is used */
#define SDMA_H_CONFIG_RTD_PINS BIT(11) /* indicates if Real-Time Debug pins are enabled */
#define SDMA_H_CONFIG_ACR BIT(4) /* indicates if AHB freq /core freq = 2 or 1 */
#define SDMA_H_CONFIG_CSM (3) /* indicates which context switch mode is selected*/
+static void sdma_start_desc(struct sdma_channel *sdmac);
+
static inline u32 chnenbl_ofs(struct sdma_engine *sdma, unsigned int event)
{
u32 chnenbl0 = sdma->drvdata->chnenbl0;
@@ -616,17 +716,19 @@ static int sdma_run_channel0(struct sdma_engine *sdma)
static int sdma_load_script(struct sdma_engine *sdma, void *buf, int size,
u32 address)
{
- struct sdma_buffer_descriptor *bd0 = sdma->channel[0].bd;
+ struct sdma_buffer_descriptor *bd0 = sdma->bd0;
void *buf_virt;
dma_addr_t buf_phys;
int ret;
unsigned long flags;
+ bool use_iram = true;
- buf_virt = dma_alloc_coherent(NULL,
- size,
- &buf_phys, GFP_KERNEL);
+ buf_virt = gen_pool_dma_alloc(sdma->iram_pool, size, &buf_phys);
if (!buf_virt) {
- return -ENOMEM;
+ use_iram = false;
+ buf_virt = dma_alloc_coherent(sdma->dev, size, &buf_phys, GFP_KERNEL);
+ if (!buf_virt)
+ return -ENOMEM;
}
spin_lock_irqsave(&sdma->channel_0_lock, flags);
@@ -643,7 +745,10 @@ static int sdma_load_script(struct sdma_engine *sdma, void *buf, int size,
spin_unlock_irqrestore(&sdma->channel_0_lock, flags);
- dma_free_coherent(NULL, size, buf_virt, buf_phys);
+ if (use_iram)
+ gen_pool_free(sdma->iram_pool, (unsigned long)buf_virt, size);
+ else
+ dma_free_coherent(sdma->dev, size, buf_virt, buf_phys);
return ret;
}
@@ -658,6 +763,21 @@ static void sdma_event_enable(struct sdma_channel *sdmac, unsigned int event)
val = readl_relaxed(sdma->regs + chnenbl);
__set_bit(channel, &val);
writel_relaxed(val, sdma->regs + chnenbl);
+
+ /* Set SDMA_DONEx_CONFIG is sw_done enabled */
+ if (sdmac->sw_done) {
+ u32 offset = SDMA_DONE0_CONFIG + sdmac->sw_done_sel / 4;
+ u32 done_sel = SDMA_DONE0_CONFIG_DONE_SEL +
+ ((sdmac->sw_done_sel % 4) << 3);
+ u32 sw_done_dis = SDMA_DONE0_CONFIG_DONE_DIS +
+ ((sdmac->sw_done_sel % 4) << 3);
+
+ val = readl_relaxed(sdma->regs + offset);
+ __set_bit(done_sel, &val);
+ __clear_bit(sw_done_dis, &val);
+ writel_relaxed(val, sdma->regs + offset);
+ }
+
}
static void sdma_event_disable(struct sdma_channel *sdmac, unsigned int event)
@@ -682,8 +802,10 @@ static void sdma_update_channel_loop(struct sdma_channel *sdmac)
* loop mode. Iterate over descriptors, re-setup them and
* call callback function.
*/
- while (1) {
- bd = &sdmac->bd[sdmac->buf_tail];
+ while (sdmac->desc) {
+ struct sdma_desc *desc = sdmac->desc;
+
+ bd = &desc->bd[desc->buf_tail];
if (bd->mode.status & BD_DONE)
break;
@@ -702,36 +824,35 @@ static void sdma_update_channel_loop(struct sdma_channel *sdmac)
sdmac->chn_real_count = bd->mode.count;
bd->mode.status |= BD_DONE;
bd->mode.count = sdmac->period_len;
- sdmac->buf_ptail = sdmac->buf_tail;
- sdmac->buf_tail = (sdmac->buf_tail + 1) % sdmac->num_bd;
-
- /*
- * The callback is called from the interrupt context in order
- * to reduce latency and to avoid the risk of altering the
- * SDMA transaction status by the time the client tasklet is
- * executed.
- */
-
- dmaengine_desc_get_callback_invoke(&sdmac->desc, NULL);
+ desc->buf_ptail = desc->buf_tail;
+ desc->buf_tail = (desc->buf_tail + 1) % desc->num_bd;
if (error)
sdmac->status = old_status;
+ /*
+ * The callback is called from the interrupt context in order
+ * to reduce latency and to avoid the risk of altering the
+ * SDMA transaction status by the time the client tasklet is
+ * executed.
+ */
+ spin_unlock(&sdmac->vc.lock);
+ dmaengine_desc_get_callback_invoke(&desc->vd.tx, NULL);
+ spin_lock(&sdmac->vc.lock);
}
}
-static void mxc_sdma_handle_channel_normal(unsigned long data)
+static void mxc_sdma_handle_channel_normal(struct sdma_channel *data)
{
struct sdma_channel *sdmac = (struct sdma_channel *) data;
struct sdma_buffer_descriptor *bd;
int i, error = 0;
- sdmac->chn_real_count = 0;
/*
* non loop mode. Iterate over all descriptors, collect
* errors and call callback function
*/
- for (i = 0; i < sdmac->num_bd; i++) {
- bd = &sdmac->bd[i];
+ for (i = 0; i < sdmac->desc->num_bd; i++) {
+ bd = &sdmac->desc->bd[i];
if (bd->mode.status & (BD_DONE | BD_RROR))
error = -EIO;
@@ -742,10 +863,6 @@ static void mxc_sdma_handle_channel_normal(unsigned long data)
sdmac->status = DMA_ERROR;
else
sdmac->status = DMA_COMPLETE;
-
- dma_cookie_complete(&sdmac->desc);
-
- dmaengine_desc_get_callback_invoke(&sdmac->desc, NULL);
}
static irqreturn_t sdma_int_handler(int irq, void *dev_id)
@@ -753,6 +870,9 @@ static irqreturn_t sdma_int_handler(int irq, void *dev_id)
struct sdma_engine *sdma = dev_id;
unsigned long stat;
+ clk_enable(sdma->clk_ipg);
+ clk_enable(sdma->clk_ahb);
+
stat = readl_relaxed(sdma->regs + SDMA_H_INTR);
writel_relaxed(stat, sdma->regs + SDMA_H_INTR);
/* channel 0 is special and not handled here, see run_channel0() */
@@ -761,15 +881,31 @@ static irqreturn_t sdma_int_handler(int irq, void *dev_id)
while (stat) {
int channel = fls(stat) - 1;
struct sdma_channel *sdmac = &sdma->channel[channel];
-
- if (sdmac->flags & IMX_DMA_SG_LOOP)
- sdma_update_channel_loop(sdmac);
- else
- tasklet_schedule(&sdmac->tasklet);
-
+ struct sdma_desc *desc;
+
+ spin_lock(&sdmac->vc.lock);
+ desc = sdmac->desc;
+ if (desc) {
+ if (sdmac->flags & IMX_DMA_SG_LOOP) {
+ if (sdmac->peripheral_type != IMX_DMATYPE_HDMI)
+ sdma_update_channel_loop(sdmac);
+ else
+ vchan_cyclic_callback(&desc->vd);
+ } else {
+ mxc_sdma_handle_channel_normal(sdmac);
+ vchan_cookie_complete(&desc->vd);
+ if (!list_empty(&sdmac->pending))
+ list_del(&desc->node);
+ sdma_start_desc(sdmac);
+ }
+ }
__clear_bit(channel, &stat);
+ spin_unlock(&sdmac->vc.lock);
}
+ clk_disable(sdma->clk_ipg);
+ clk_disable(sdma->clk_ahb);
+
return IRQ_HANDLED;
}
@@ -785,14 +921,16 @@ static void sdma_get_pc(struct sdma_channel *sdmac,
* These are needed once we start to support transfers between
* two peripherals or memory-to-memory transfers
*/
- int per_2_per = 0;
+ int per_2_per = 0, emi_2_emi = 0;
sdmac->pc_from_device = 0;
sdmac->pc_to_device = 0;
sdmac->device_to_device = 0;
+ sdmac->pc_to_pc = 0;
switch (peripheral_type) {
case IMX_DMATYPE_MEMORY:
+ emi_2_emi = sdma->script_addrs->ap_2_ap_addr;
break;
case IMX_DMATYPE_DSP:
emi_2_per = sdma->script_addrs->bp_2_ap_addr;
@@ -815,6 +953,9 @@ static void sdma_get_pc(struct sdma_channel *sdmac,
emi_2_per = sdma->script_addrs->mcu_2_ata_addr;
break;
case IMX_DMATYPE_CSPI:
+ per_2_emi = sdma->script_addrs->app_2_mcu_addr;
+ emi_2_per = sdma->script_addrs->mcu_2_ecspi_addr;
+ break;
case IMX_DMATYPE_EXT:
case IMX_DMATYPE_SSI:
case IMX_DMATYPE_SAI:
@@ -858,6 +999,12 @@ static void sdma_get_pc(struct sdma_channel *sdmac,
case IMX_DMATYPE_IPU_MEMORY:
emi_2_per = sdma->script_addrs->ext_mem_2_ipu_addr;
break;
+ case IMX_DMATYPE_HDMI:
+ emi_2_per = sdma->script_addrs->hdmi_dma_addr;
+ break;
+ case IMX_DMATYPE_MULTI_SAI:
+ per_2_emi = sdma->script_addrs->sai_2_mcu_addr;
+ emi_2_per = sdma->script_addrs->mcu_2_sai_addr;
default:
break;
}
@@ -865,6 +1012,7 @@ static void sdma_get_pc(struct sdma_channel *sdmac,
sdmac->pc_from_device = per_2_emi;
sdmac->pc_to_device = emi_2_per;
sdmac->device_to_device = per_2_per;
+ sdmac->pc_to_pc = emi_2_emi;
}
static int sdma_load_context(struct sdma_channel *sdmac)
@@ -873,14 +1021,19 @@ static int sdma_load_context(struct sdma_channel *sdmac)
int channel = sdmac->channel;
int load_address;
struct sdma_context_data *context = sdma->context;
- struct sdma_buffer_descriptor *bd0 = sdma->channel[0].bd;
+ struct sdma_buffer_descriptor *bd0 = sdma->bd0;
int ret;
unsigned long flags;
+ if (sdmac->context_loaded)
+ return 0;
+
if (sdmac->direction == DMA_DEV_TO_MEM)
load_address = sdmac->pc_from_device;
else if (sdmac->direction == DMA_DEV_TO_DEV)
load_address = sdmac->device_to_device;
+ else if (sdmac->direction == DMA_MEM_TO_MEM)
+ load_address = sdmac->pc_to_pc;
else
load_address = sdmac->pc_to_device;
@@ -902,11 +1055,16 @@ static int sdma_load_context(struct sdma_channel *sdmac)
/* Send by context the event mask,base address for peripheral
* and watermark level
*/
- context->gReg[0] = sdmac->event_mask[1];
- context->gReg[1] = sdmac->event_mask[0];
- context->gReg[2] = sdmac->per_addr;
- context->gReg[6] = sdmac->shp_addr;
- context->gReg[7] = sdmac->watermark_level;
+ if (sdmac->peripheral_type == IMX_DMATYPE_HDMI) {
+ context->gReg[4] = sdmac->per_addr;
+ context->gReg[6] = sdmac->shp_addr;
+ } else {
+ context->gReg[0] = sdmac->event_mask[1];
+ context->gReg[1] = sdmac->event_mask[0];
+ context->gReg[2] = sdmac->per_addr;
+ context->gReg[6] = sdmac->shp_addr;
+ context->gReg[7] = sdmac->watermark_level;
+ }
bd0->mode.command = C0_SETDM;
bd0->mode.status = BD_DONE | BD_WRAP | BD_EXTD;
@@ -917,12 +1075,39 @@ static int sdma_load_context(struct sdma_channel *sdmac)
spin_unlock_irqrestore(&sdma->channel_0_lock, flags);
+ sdmac->context_loaded = true;
+
+ return ret;
+}
+
+static int sdma_save_restore_context(struct sdma_engine *sdma, bool save)
+{
+ struct sdma_context_data *context = sdma->context;
+ struct sdma_buffer_descriptor *bd0 = sdma->bd0;
+ unsigned long flags;
+ int ret;
+
+ spin_lock_irqsave(&sdma->channel_0_lock, flags);
+
+ if (save)
+ bd0->mode.command = C0_GETDM;
+ else
+ bd0->mode.command = C0_SETDM;
+
+ bd0->mode.status = BD_DONE | BD_WRAP | BD_EXTD;
+ bd0->mode.count = MAX_DMA_CHANNELS * sizeof(*context) / 4;
+ bd0->buffer_addr = sdma->context_phys;
+ bd0->ext_buffer_addr = 2048;
+ ret = sdma_run_channel0(sdma);
+
+ spin_unlock_irqrestore(&sdma->channel_0_lock, flags);
+
return ret;
}
static struct sdma_channel *to_sdma_chan(struct dma_chan *chan)
{
- return container_of(chan, struct sdma_channel, chan);
+ return container_of(chan, struct sdma_channel, vc.chan);
}
static int sdma_disable_channel(struct dma_chan *chan)
@@ -937,21 +1122,6 @@ static int sdma_disable_channel(struct dma_chan *chan)
return 0;
}
-static int sdma_disable_channel_with_delay(struct dma_chan *chan)
-{
- sdma_disable_channel(chan);
-
- /*
- * According to NXP R&D team a delay of one BD SDMA cost time
- * (maximum is 1ms) should be added after disable of the channel
- * bit, to ensure SDMA core has really been stopped after SDMA
- * clients call .device_terminate_all.
- */
- mdelay(1);
-
- return 0;
-}
-
static void sdma_set_watermarklevel_for_p2p(struct sdma_channel *sdmac)
{
struct sdma_engine *sdma = sdmac->sdma;
@@ -990,6 +1160,31 @@ static void sdma_set_watermarklevel_for_p2p(struct sdma_channel *sdmac)
sdmac->watermark_level |= SDMA_WATERMARK_LEVEL_DP;
sdmac->watermark_level |= SDMA_WATERMARK_LEVEL_CONT;
+
+ if (sdmac->src_dualfifo)
+ sdmac->watermark_level |= SDMA_WATERMARK_LEVEL_SD;
+ if (sdmac->dst_dualfifo)
+ sdmac->watermark_level |= SDMA_WATERMARK_LEVEL_DD;
+}
+
+static void sdma_set_watermarklevel_for_sais(struct sdma_channel *sdmac)
+{
+ sdmac->watermark_level &= ~(0xFF << SDMA_WATERMARK_LEVEL_FIFOS_OFF |
+ SDMA_WATERMARK_LEVEL_SW_DONE |
+ 0xf << SDMA_WATERMARK_LEVEL_SW_DONE_SEL_OFF);
+
+ if (sdmac->sw_done)
+ sdmac->watermark_level |= SDMA_WATERMARK_LEVEL_SW_DONE |
+ sdmac->sw_done_sel <<
+ SDMA_WATERMARK_LEVEL_SW_DONE_SEL_OFF;
+
+ /* For fifo_num
+ * bit 12-15 is the fifo number;
+ * bit 16-19 is the fifo offset,
+ * so here only need to shift left fifo_num 12 bit for watermake_level
+ */
+ sdmac->watermark_level |= sdmac->fifo_num<<
+ SDMA_WATERMARK_LEVEL_FIFOS_OFF;
}
static int sdma_config_channel(struct dma_chan *chan)
@@ -1004,11 +1199,9 @@ static int sdma_config_channel(struct dma_chan *chan)
sdmac->shp_addr = 0;
sdmac->per_addr = 0;
- if (sdmac->event_id0) {
- if (sdmac->event_id0 >= sdmac->sdma->drvdata->num_events)
- return -EINVAL;
- sdma_event_enable(sdmac, sdmac->event_id0);
- }
+ if (sdmac->event_id0 >= sdmac->sdma->drvdata->num_events)
+ return -EINVAL;
+ sdma_event_enable(sdmac, sdmac->event_id0);
if (sdmac->event_id1) {
if (sdmac->event_id1 >= sdmac->sdma->drvdata->num_events)
@@ -1037,8 +1230,18 @@ static int sdma_config_channel(struct dma_chan *chan)
if (sdmac->peripheral_type == IMX_DMATYPE_ASRC_SP ||
sdmac->peripheral_type == IMX_DMATYPE_ASRC)
sdma_set_watermarklevel_for_p2p(sdmac);
- } else
+ } else {
+ /* ERR008517 fixed on i.mx6ul, no workaround needed */
+ if (sdmac->peripheral_type == IMX_DMATYPE_CSPI &&
+ sdmac->direction == DMA_MEM_TO_DEV &&
+ sdmac->sdma->drvdata == &sdma_imx6ul)
+ __set_bit(31, &sdmac->watermark_level);
+ else if (sdmac->peripheral_type ==
+ IMX_DMATYPE_MULTI_SAI)
+ sdma_set_watermarklevel_for_sais(sdmac);
+
__set_bit(sdmac->event_id0, sdmac->event_mask);
+ }
/* Address */
sdmac->shp_addr = sdmac->per_address;
@@ -1047,6 +1250,8 @@ static int sdma_config_channel(struct dma_chan *chan)
sdmac->watermark_level = 0; /* FIXME: M3_BASE_ADDRESS */
}
+ sdmac->context_loaded = false;
+
ret = sdma_load_context(sdmac);
return ret;
@@ -1068,52 +1273,181 @@ static int sdma_set_channel_priority(struct sdma_channel *sdmac,
return 0;
}
-static int sdma_request_channel(struct sdma_channel *sdmac)
+static int sdma_alloc_bd(struct sdma_desc *desc)
{
- struct sdma_engine *sdma = sdmac->sdma;
- int channel = sdmac->channel;
- int ret = -EBUSY;
+ u32 bd_size = desc->num_bd * sizeof(struct sdma_buffer_descriptor);
+ int ret = -ENOMEM;
+ unsigned long flags;
- sdmac->bd = dma_zalloc_coherent(NULL, PAGE_SIZE, &sdmac->bd_phys,
- GFP_KERNEL);
- if (!sdmac->bd) {
- ret = -ENOMEM;
- goto out;
+ desc->bd_iram = true;
+ desc->bd = gen_pool_dma_alloc(desc->sdmac->sdma->iram_pool, bd_size,
+ &desc->bd_phys);
+ if (!desc->bd) {
+ desc->bd_iram = false;
+ desc->bd = dma_pool_alloc(desc->sdmac->bd_pool, GFP_ATOMIC,
+ &desc->bd_phys);
+ if (!desc->bd)
+ return ret;
+ }
+ spin_lock_irqsave(&desc->sdmac->vc.lock, flags);
+ desc->sdmac->bd_size_sum += bd_size;
+ spin_unlock_irqrestore(&desc->sdmac->vc.lock, flags);
+
+ memset(desc->bd, 0, bd_size);
+
+ return 0;
+}
+
+static void sdma_free_bd(struct sdma_desc *desc)
+{
+ u32 bd_size = desc->num_bd * sizeof(struct sdma_buffer_descriptor);
+ unsigned long flags;
+
+ if (desc->bd) {
+ if (desc->bd_iram)
+ gen_pool_free(desc->sdmac->sdma->iram_pool,
+ (unsigned long)desc->bd, bd_size);
+ else
+ dma_pool_free(desc->sdmac->bd_pool, desc->bd,
+ desc->bd_phys);
+ spin_lock_irqsave(&desc->sdmac->vc.lock, flags);
+ desc->sdmac->bd_size_sum -= bd_size;
+ spin_unlock_irqrestore(&desc->sdmac->vc.lock, flags);
}
+}
- sdma->channel_control[channel].base_bd_ptr = sdmac->bd_phys;
- sdma->channel_control[channel].current_bd_ptr = sdmac->bd_phys;
+static int sdma_request_channel0(struct sdma_engine *sdma)
+{
+ int ret = 0;
- sdma_set_channel_priority(sdmac, MXC_SDMA_DEFAULT_PRIORITY);
+ sdma->bd0_iram = true;
+ sdma->bd0 = gen_pool_dma_alloc(sdma->iram_pool, PAGE_SIZE, &sdma->bd0_phys);
+ if (!sdma->bd0) {
+ sdma->bd0_iram = false;
+ sdma->bd0 = dma_alloc_coherent(sdma->dev, PAGE_SIZE,
+ &sdma->bd0_phys, GFP_KERNEL);
+ if (!sdma->bd0) {
+ ret = -ENOMEM;
+ goto out;
+ }
+ }
+
+ memset(sdma->bd0, 0, PAGE_SIZE);
+
+ sdma->channel_control[0].base_bd_ptr = sdma->bd0_phys;
+ sdma->channel_control[0].current_bd_ptr = sdma->bd0_phys;
+
+ sdma_set_channel_priority(&sdma->channel[0], MXC_SDMA_DEFAULT_PRIORITY);
return 0;
out:
return ret;
}
-static dma_cookie_t sdma_tx_submit(struct dma_async_tx_descriptor *tx)
+static struct sdma_desc *to_sdma_desc(struct dma_async_tx_descriptor *t)
+{
+ return container_of(t, struct sdma_desc, vd.tx);
+}
+
+static void sdma_desc_free(struct virt_dma_desc *vd)
+{
+ struct sdma_desc *desc = container_of(vd, struct sdma_desc, vd);
+ if (desc) {
+ sdma_free_bd(desc);
+ kfree(desc);
+ }
+}
+
+static int sdma_channel_pause(struct dma_chan *chan)
+{
+ struct sdma_channel *sdmac = to_sdma_chan(chan);
+ unsigned long flags;
+
+ if (!(sdmac->flags & IMX_DMA_SG_LOOP))
+ return -EINVAL;
+
+ sdma_disable_channel(chan);
+ spin_lock_irqsave(&sdmac->vc.lock, flags);
+ sdmac->status = DMA_PAUSED;
+ spin_unlock_irqrestore(&sdmac->vc.lock, flags);
+
+ return 0;
+}
+
+static int sdma_channel_resume(struct dma_chan *chan)
{
+ struct sdma_channel *sdmac = to_sdma_chan(chan);
unsigned long flags;
- struct sdma_channel *sdmac = to_sdma_chan(tx->chan);
- dma_cookie_t cookie;
- spin_lock_irqsave(&sdmac->lock, flags);
+ if (!(sdmac->flags & IMX_DMA_SG_LOOP))
+ return -EINVAL;
- cookie = dma_cookie_assign(tx);
+ sdma_enable_channel(sdmac->sdma, sdmac->channel);
+ spin_lock_irqsave(&sdmac->vc.lock, flags);
+ sdmac->status = DMA_IN_PROGRESS;
+ spin_unlock_irqrestore(&sdmac->vc.lock, flags);
- spin_unlock_irqrestore(&sdmac->lock, flags);
+ return 0;
+}
+
+static int sdma_terminate_all(struct dma_chan *chan)
+{
+ struct sdma_channel *sdmac = to_sdma_chan(chan);
+ unsigned long flags;
+ LIST_HEAD(head);
+
+ spin_lock_irqsave(&sdmac->vc.lock, flags);
+ vchan_get_all_descriptors(&sdmac->vc, &head);
+ while (!list_empty(&sdmac->pending)) {
+ struct sdma_desc *desc = list_first_entry(&sdmac->pending,
+ struct sdma_desc, node);
+
+ list_del(&desc->node);
+ spin_unlock_irqrestore(&sdmac->vc.lock, flags);
+ sdmac->vc.desc_free(&desc->vd);
+ spin_lock_irqsave(&sdmac->vc.lock, flags);
+ sdmac->vc.cyclic = NULL;
+ }
+ if (sdmac->desc)
+ sdmac->desc = NULL;
+ spin_unlock_irqrestore(&sdmac->vc.lock, flags);
+ vchan_dma_desc_free_list(&sdmac->vc, &head);
+ sdma_disable_channel(chan);
+ sdmac->context_loaded = false;
- return cookie;
+ return 0;
}
static int sdma_alloc_chan_resources(struct dma_chan *chan)
{
struct sdma_channel *sdmac = to_sdma_chan(chan);
struct imx_dma_data *data = chan->private;
+ struct imx_dma_data default_data;
int prio, ret;
- if (!data)
- return -EINVAL;
+ ret = clk_enable(sdmac->sdma->clk_ipg);
+ if (ret)
+ return ret;
+ ret = clk_enable(sdmac->sdma->clk_ahb);
+ if (ret)
+ goto disable_clk_ipg;
+
+ /*
+ * dmatest(memcpy) will never call slave_config before prep, so we need
+ * do some job in slave_config in this case.
+ */
+ if (!data) {
+ sdmac->word_size = sdmac->sdma->dma_device.copy_align;
+ default_data.priority = 2;
+ default_data.peripheral_type = IMX_DMATYPE_MEMORY;
+ default_data.dma_request = 0;
+ default_data.dma_request2 = 0;
+ data = &default_data;
+
+ sdma_config_ownership(sdmac, false, true, false);
+ sdma_get_pc(sdmac, IMX_DMATYPE_MEMORY);
+ sdma_load_context(sdmac);
+ }
switch (data->priority) {
case DMA_PRIO_HIGH:
@@ -1131,26 +1465,23 @@ static int sdma_alloc_chan_resources(struct dma_chan *chan)
sdmac->peripheral_type = data->peripheral_type;
sdmac->event_id0 = data->dma_request;
sdmac->event_id1 = data->dma_request2;
-
- ret = clk_enable(sdmac->sdma->clk_ipg);
- if (ret)
- return ret;
- ret = clk_enable(sdmac->sdma->clk_ahb);
- if (ret)
- goto disable_clk_ipg;
-
- ret = sdma_request_channel(sdmac);
- if (ret)
- goto disable_clk_ahb;
+ sdmac->src_dualfifo = data->src_dualfifo;
+ sdmac->dst_dualfifo = data->dst_dualfifo;
+ /* Get software done selector if sw_done enabled */
+ if (data->done_sel & BIT(31)) {
+ sdmac->sw_done = true;
+ sdmac->sw_done_sel = (data->done_sel >> 8) & 0xff;
+ }
ret = sdma_set_channel_priority(sdmac, prio);
if (ret)
goto disable_clk_ahb;
- dma_async_tx_descriptor_init(&sdmac->desc, chan);
- sdmac->desc.tx_submit = sdma_tx_submit;
- /* txd.flags will be overwritten in prep funcs */
- sdmac->desc.flags = DMA_CTRL_ACK;
+ sdmac->bd_size_sum = 0;
+
+ sdmac->bd_pool = dma_pool_create("bd_pool", chan->device->dev,
+ sizeof(struct sdma_buffer_descriptor),
+ 32, 0);
return 0;
@@ -1166,10 +1497,9 @@ 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(chan);
+ sdma_terminate_all(chan);
- if (sdmac->event_id0)
- sdma_event_disable(sdmac, sdmac->event_id0);
+ sdma_event_disable(sdmac, sdmac->event_id0);
if (sdmac->event_id1)
sdma_event_disable(sdmac, sdmac->event_id1);
@@ -1178,115 +1508,238 @@ static void sdma_free_chan_resources(struct dma_chan *chan)
sdma_set_channel_priority(sdmac, 0);
- dma_free_coherent(NULL, PAGE_SIZE, sdmac->bd, sdmac->bd_phys);
-
clk_disable(sdma->clk_ipg);
clk_disable(sdma->clk_ahb);
+
+ dma_pool_destroy(sdmac->bd_pool);
+ sdmac->bd_pool = NULL;
}
-static struct dma_async_tx_descriptor *sdma_prep_slave_sg(
- struct dma_chan *chan, struct scatterlist *sgl,
- unsigned int sg_len, enum dma_transfer_direction direction,
- unsigned long flags, void *context)
+static struct sdma_desc *sdma_transfer_init(struct sdma_channel *sdmac,
+ enum dma_transfer_direction direction, u32 bds)
+{
+ struct sdma_desc *desc;
+
+ if (!sdmac->sdma->fw_loaded) {
+ dev_err(sdmac->sdma->dev, "sdma firmware not ready!\n");
+ goto err_out;
+ }
+
+ /* Now allocate and setup the descriptor. */
+ desc = kzalloc((sizeof(*desc)), GFP_ATOMIC);
+ if (!desc)
+ goto err_out;
+
+ sdmac->status = DMA_IN_PROGRESS;
+ sdmac->direction = direction;
+ sdmac->flags = 0;
+ sdmac->chn_count = 0;
+ sdmac->chn_real_count = 0;
+
+ desc->sdmac = sdmac;
+ desc->num_bd = bds;
+ INIT_LIST_HEAD(&desc->node);
+
+ if (sdma_alloc_bd(desc))
+ goto err_desc_out;
+
+ if (sdma_load_context(sdmac))
+ goto err_desc_out;
+
+ return desc;
+
+err_desc_out:
+ kfree(desc);
+err_out:
+ return NULL;
+}
+
+static int check_bd_buswidth(struct sdma_buffer_descriptor *bd,
+ struct sdma_channel *sdmac, int count,
+ dma_addr_t dma_dst, dma_addr_t dma_src)
+{
+ int ret = 0;
+
+ switch (sdmac->word_size) {
+ case DMA_SLAVE_BUSWIDTH_4_BYTES:
+ bd->mode.command = 0;
+ if ((count | dma_dst | dma_src) & 3)
+ ret = -EINVAL;
+ break;
+ case DMA_SLAVE_BUSWIDTH_2_BYTES:
+ bd->mode.command = 2;
+ if ((count | dma_dst | dma_src) & 1)
+ ret = -EINVAL;
+ break;
+ case DMA_SLAVE_BUSWIDTH_1_BYTE:
+ bd->mode.command = 1;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return ret;
+}
+
+static struct dma_async_tx_descriptor *sdma_prep_memcpy(
+ struct dma_chan *chan, dma_addr_t dma_dst,
+ dma_addr_t dma_src, size_t len, unsigned long flags)
{
struct sdma_channel *sdmac = to_sdma_chan(chan);
struct sdma_engine *sdma = sdmac->sdma;
- int ret, i, count;
int channel = sdmac->channel;
- struct scatterlist *sg;
+ size_t count;
+ int i = 0, param;
+ struct sdma_buffer_descriptor *bd;
+ struct sdma_desc *desc;
- if (sdmac->status == DMA_IN_PROGRESS)
+ if (!chan || !len)
return NULL;
- sdmac->status = DMA_IN_PROGRESS;
- sdmac->flags = 0;
+ dev_dbg(sdma->dev, "memcpy: %pad->%pad, len=%zu, channel=%d.\n",
+ &dma_src, &dma_dst, len, channel);
- sdmac->buf_tail = 0;
- sdmac->buf_ptail = 0;
- sdmac->chn_real_count = 0;
+ desc = sdma_transfer_init(sdmac, DMA_MEM_TO_MEM, len / SDMA_BD_MAX_CNT + 1);
+ if (!desc)
+ goto err_out;
- dev_dbg(sdma->dev, "setting up %d entries for channel %d.\n",
- sg_len, channel);
+ do {
+ count = min_t(size_t, len, SDMA_BD_MAX_CNT);
+ bd = &desc->bd[i];
+ bd->buffer_addr = dma_src;
+ bd->ext_buffer_addr = dma_dst;
+ bd->mode.count = count;
+ sdmac->chn_count += count;
- sdmac->direction = direction;
- ret = sdma_load_context(sdmac);
- if (ret)
- goto err_out;
+ if (check_bd_buswidth(bd, sdmac, count, dma_dst, dma_src))
+ goto err_bd_out;
- if (sg_len > NUM_BD) {
- dev_err(sdma->dev, "SDMA channel %d: maximum number of sg exceeded: %d > %d\n",
- channel, sg_len, NUM_BD);
- ret = -EINVAL;
+ dma_src += count;
+ dma_dst += count;
+ len -= count;
+ i++;
+
+ param = BD_DONE | BD_EXTD | BD_CONT;
+ /* last bd */
+ if (!len) {
+ param |= BD_INTR;
+ param |= BD_LAST;
+ param &= ~BD_CONT;
+ }
+
+ dev_dbg(sdma->dev, "entry %d: count: %zd dma: 0x%x %s%s\n",
+ i, count, bd->buffer_addr,
+ param & BD_WRAP ? "wrap" : "",
+ param & BD_INTR ? " intr" : "");
+
+ bd->mode.status = param;
+ } while (len);
+
+ return vchan_tx_prep(&sdmac->vc, &desc->vd, flags);
+err_bd_out:
+ sdma_free_bd(desc);
+ kfree(desc);
+err_out:
+ return NULL;
+}
+
+/*
+ * Please ensure dst_nents no smaller than src_nents , also every sg_len of
+ * dst_sg node no smaller than src_sg. To simply things, please use the same
+ * size of dst_sg as src_sg.
+ */
+static struct dma_async_tx_descriptor *sdma_prep_sg(
+ struct dma_chan *chan,
+ struct scatterlist *dst_sg, unsigned int dst_nents,
+ struct scatterlist *src_sg, unsigned int src_nents,
+ enum dma_transfer_direction direction, unsigned long flags)
+{
+ struct sdma_channel *sdmac = to_sdma_chan(chan);
+ struct sdma_engine *sdma = sdmac->sdma;
+ int ret, i, count;
+ int channel = sdmac->channel;
+ struct scatterlist *sg_src = src_sg, *sg_dst = dst_sg;
+ struct sdma_desc *desc;
+
+ if (!chan)
+ return NULL;
+
+ dev_dbg(sdma->dev, "setting up %d entries for channel %d.\n",
+ src_nents, channel);
+
+ desc = sdma_transfer_init(sdmac, direction, src_nents);
+ if (!desc)
goto err_out;
- }
- sdmac->chn_count = 0;
- for_each_sg(sgl, sg, sg_len, i) {
- struct sdma_buffer_descriptor *bd = &sdmac->bd[i];
+ for_each_sg(src_sg, sg_src, src_nents, i) {
+ struct sdma_buffer_descriptor *bd = &desc->bd[i];
int param;
- bd->buffer_addr = sg->dma_address;
+ bd->buffer_addr = sg_src->dma_address;
+
+ if (direction == DMA_MEM_TO_MEM) {
+ BUG_ON(!sg_dst);
+ bd->ext_buffer_addr = sg_dst->dma_address;
+ }
- count = sg_dma_len(sg);
+ count = sg_dma_len(sg_src);
- if (count > 0xffff) {
+ if (count > SDMA_BD_MAX_CNT) {
dev_err(sdma->dev, "SDMA channel %d: maximum bytes for sg entry exceeded: %d > %d\n",
- channel, count, 0xffff);
+ channel, count, SDMA_BD_MAX_CNT);
ret = -EINVAL;
- goto err_out;
+ goto err_bd_out;
}
bd->mode.count = count;
sdmac->chn_count += count;
- if (sdmac->word_size > DMA_SLAVE_BUSWIDTH_4_BYTES) {
- ret = -EINVAL;
- goto err_out;
- }
-
- switch (sdmac->word_size) {
- case DMA_SLAVE_BUSWIDTH_4_BYTES:
- bd->mode.command = 0;
- if (count & 3 || sg->dma_address & 3)
- return NULL;
- break;
- case DMA_SLAVE_BUSWIDTH_2_BYTES:
- bd->mode.command = 2;
- if (count & 1 || sg->dma_address & 1)
- return NULL;
- break;
- case DMA_SLAVE_BUSWIDTH_1_BYTE:
- bd->mode.command = 1;
- break;
- default:
- return NULL;
- }
+ if (direction == DMA_MEM_TO_MEM)
+ ret = check_bd_buswidth(bd, sdmac, count,
+ sg_dst->dma_address,
+ sg_src->dma_address);
+ else
+ ret = check_bd_buswidth(bd, sdmac, count, 0,
+ sg_src->dma_address);
+ if (ret)
+ goto err_bd_out;
param = BD_DONE | BD_EXTD | BD_CONT;
- if (i + 1 == sg_len) {
+ if (i + 1 == src_nents) {
param |= BD_INTR;
param |= BD_LAST;
param &= ~BD_CONT;
}
- dev_dbg(sdma->dev, "entry %d: count: %d dma: %#llx %s%s\n",
- i, count, (u64)sg->dma_address,
+ dev_dbg(sdma->dev, "entry %d: count: %d dma: 0x%pad %s%s\n",
+ i, count, &sg_src->dma_address,
param & BD_WRAP ? "wrap" : "",
param & BD_INTR ? " intr" : "");
bd->mode.status = param;
+ if (direction == DMA_MEM_TO_MEM)
+ sg_dst = sg_next(sg_dst);
}
- sdmac->num_bd = sg_len;
- sdma->channel_control[channel].current_bd_ptr = sdmac->bd_phys;
+ return vchan_tx_prep(&sdmac->vc, &desc->vd, flags);
- return &sdmac->desc;
+err_bd_out:
+ sdma_free_bd(desc);
+ kfree(desc);
err_out:
- sdmac->status = DMA_ERROR;
+ dev_dbg(sdma->dev, "Can't get desc.\n");
return NULL;
}
+static struct dma_async_tx_descriptor *sdma_prep_slave_sg(
+ struct dma_chan *chan, struct scatterlist *sgl,
+ unsigned int sg_len, enum dma_transfer_direction direction,
+ unsigned long flags, void *context)
+{
+ return sdma_prep_sg(chan, NULL, 0, sgl, sg_len, direction, flags);
+}
+
static struct dma_async_tx_descriptor *sdma_prep_dma_cyclic(
struct dma_chan *chan, dma_addr_t dma_addr, size_t buf_len,
size_t period_len, enum dma_transfer_direction direction,
@@ -1294,42 +1747,42 @@ static struct dma_async_tx_descriptor *sdma_prep_dma_cyclic(
{
struct sdma_channel *sdmac = to_sdma_chan(chan);
struct sdma_engine *sdma = sdmac->sdma;
- int num_periods = buf_len / period_len;
int channel = sdmac->channel;
- int ret, i = 0, buf = 0;
+ int i = 0, buf = 0;
+ int num_periods = 0;
+ struct sdma_desc *desc;
dev_dbg(sdma->dev, "%s channel: %d\n", __func__, channel);
- if (sdmac->status == DMA_IN_PROGRESS)
- return NULL;
-
- sdmac->status = DMA_IN_PROGRESS;
+ if (sdmac->peripheral_type != IMX_DMATYPE_HDMI)
+ num_periods = buf_len / period_len;
+ /* Now allocate and setup the descriptor. */
+ desc = sdma_transfer_init(sdmac, direction, num_periods);
+ if (!desc)
+ goto err_out;
- sdmac->buf_tail = 0;
- sdmac->buf_ptail = 0;
- sdmac->chn_real_count = 0;
sdmac->period_len = period_len;
-
sdmac->flags |= IMX_DMA_SG_LOOP;
- sdmac->direction = direction;
- ret = sdma_load_context(sdmac);
- if (ret)
- goto err_out;
- if (num_periods > NUM_BD) {
- dev_err(sdma->dev, "SDMA channel %d: maximum number of sg exceeded: %d > %d\n",
- channel, num_periods, NUM_BD);
- goto err_out;
- }
+ /* for hdmi-audio without BDs */
+ if (sdmac->peripheral_type == IMX_DMATYPE_HDMI)
+ return vchan_tx_prep(&sdmac->vc, &desc->vd, flags);
- if (period_len > 0xffff) {
+ desc->buf_tail = 0;
+ desc->buf_ptail = 0;
+ sdmac->chn_real_count = 0;
+
+ if (period_len > SDMA_BD_MAX_CNT) {
dev_err(sdma->dev, "SDMA channel %d: maximum period size exceeded: %zu > %d\n",
- channel, period_len, 0xffff);
- goto err_out;
+ channel, period_len, SDMA_BD_MAX_CNT);
+ goto err_bd_out;
}
+ if (sdmac->peripheral_type == IMX_DMATYPE_UART)
+ sdmac->chn_count = period_len;
+
while (buf < buf_len) {
- struct sdma_buffer_descriptor *bd = &sdmac->bd[i];
+ struct sdma_buffer_descriptor *bd = &desc->bd[i];
int param;
bd->buffer_addr = dma_addr;
@@ -1337,7 +1790,7 @@ static struct dma_async_tx_descriptor *sdma_prep_dma_cyclic(
bd->mode.count = period_len;
if (sdmac->word_size > DMA_SLAVE_BUSWIDTH_4_BYTES)
- goto err_out;
+ goto err_bd_out;
if (sdmac->word_size == DMA_SLAVE_BUSWIDTH_4_BYTES)
bd->mode.command = 0;
else
@@ -1347,8 +1800,8 @@ static struct dma_async_tx_descriptor *sdma_prep_dma_cyclic(
if (i + 1 == num_periods)
param |= BD_WRAP;
- dev_dbg(sdma->dev, "entry %d: count: %zu dma: %#llx %s%s\n",
- i, period_len, (u64)dma_addr,
+ dev_dbg(sdma->dev, "entry %d: count: %zu dma: %pad %s%s\n",
+ i, period_len, &dma_addr,
param & BD_WRAP ? "wrap" : "",
param & BD_INTR ? " intr" : "");
@@ -1359,13 +1812,12 @@ static struct dma_async_tx_descriptor *sdma_prep_dma_cyclic(
i++;
}
+ return vchan_tx_prep(&sdmac->vc, &desc->vd, flags);
- sdmac->num_bd = num_periods;
- sdma->channel_control[channel].current_bd_ptr = sdmac->bd_phys;
-
- return &sdmac->desc;
+err_bd_out:
+ sdma_free_bd(desc);
+ kfree(desc);
err_out:
- sdmac->status = DMA_ERROR;
return NULL;
}
@@ -1373,12 +1825,14 @@ static int sdma_config(struct dma_chan *chan,
struct dma_slave_config *dmaengine_cfg)
{
struct sdma_channel *sdmac = to_sdma_chan(chan);
-
+ /* clear watermark_level before setting */
+ sdmac->watermark_level = 0;
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;
+ sdmac->fifo_num = dmaengine_cfg->src_fifo_num;
} else if (dmaengine_cfg->direction == DMA_DEV_TO_DEV) {
sdmac->per_address2 = dmaengine_cfg->src_addr;
sdmac->per_address = dmaengine_cfg->dst_addr;
@@ -1387,48 +1841,115 @@ static int sdma_config(struct dma_chan *chan,
sdmac->watermark_level |= (dmaengine_cfg->dst_maxburst << 16) &
SDMA_WATERMARK_LEVEL_HWML;
sdmac->word_size = dmaengine_cfg->dst_addr_width;
+ } else if (sdmac->peripheral_type == IMX_DMATYPE_HDMI) {
+ sdmac->per_address = dmaengine_cfg->dst_addr;
+ sdmac->per_address2 = dmaengine_cfg->src_addr;
+ sdmac->watermark_level = 0;
+ } else if (dmaengine_cfg->direction == DMA_MEM_TO_MEM) {
+ sdmac->word_size = dmaengine_cfg->dst_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->fifo_num = dmaengine_cfg->dst_fifo_num;
}
sdmac->direction = dmaengine_cfg->direction;
return sdma_config_channel(chan);
}
+static void sdma_wait_tasklet(struct dma_chan *chan)
+{
+ struct sdma_channel *sdmac = to_sdma_chan(chan);
+
+ tasklet_kill(&sdmac->vc.task);
+}
+
static enum dma_status sdma_tx_status(struct dma_chan *chan,
dma_cookie_t cookie,
struct dma_tx_state *txstate)
{
struct sdma_channel *sdmac = to_sdma_chan(chan);
u32 residue;
+ struct virt_dma_desc *vd;
+ struct sdma_desc *desc;
+ enum dma_status ret;
+ unsigned long flags;
- if (sdmac->flags & IMX_DMA_SG_LOOP)
- residue = (sdmac->num_bd - sdmac->buf_ptail) *
- sdmac->period_len - sdmac->chn_real_count;
- else
+ ret = dma_cookie_status(chan, cookie, txstate);
+ if (!txstate) {
+ return ret;
+ } else if (ret == DMA_COMPLETE) {
+ spin_lock_irqsave(&sdmac->vc.lock, flags);
+ txstate->residue = sdmac->chn_count - sdmac->chn_real_count;
+ spin_unlock_irqrestore(&sdmac->vc.lock, flags);
+ return ret;
+ }
+
+ spin_lock_irqsave(&sdmac->vc.lock, flags);
+ vd = vchan_find_desc(&sdmac->vc, cookie);
+ desc = to_sdma_desc(&vd->tx);
+ if (vd) {
+ if ((sdmac->flags & IMX_DMA_SG_LOOP)) {
+ if (sdmac->peripheral_type != IMX_DMATYPE_UART)
+ residue = (desc->num_bd - desc->buf_ptail) *
+ sdmac->period_len - sdmac->chn_real_count;
+ else
+ residue = sdmac->chn_count - sdmac->chn_real_count;
+ } else
+ residue = sdmac->chn_count;
+ } else if (sdmac->desc && sdmac->desc->vd.tx.cookie == cookie)
residue = sdmac->chn_count - sdmac->chn_real_count;
+ else
+ residue = 0;
- dma_set_tx_state(txstate, chan->completed_cookie, chan->cookie,
- residue);
+ txstate->residue = residue;
+ ret = sdmac->status;
+ spin_unlock_irqrestore(&sdmac->vc.lock, flags);
+
+ return ret;
+}
+
+static void sdma_start_desc(struct sdma_channel *sdmac)
+{
+ struct virt_dma_desc *vd = vchan_next_desc(&sdmac->vc);
+ struct sdma_desc *desc;
+ struct sdma_engine *sdma = sdmac->sdma;
+ int channel = sdmac->channel;
- return sdmac->status;
+ if (!vd) {
+ sdmac->desc = NULL;
+ return;
+ }
+ sdmac->desc = desc = to_sdma_desc(&vd->tx);
+ /*
+ * Do not delete the node in desc_issued list in cyclic mode, otherwise
+ * the desc alloced will never be freed in vchan_dma_desc_free_list
+ */
+ if (!(sdmac->flags & IMX_DMA_SG_LOOP)) {
+ list_add_tail(&sdmac->desc->node, &sdmac->pending);
+ list_del(&vd->node);
+ }
+ sdma->channel_control[channel].base_bd_ptr = desc->bd_phys;
+ sdma->channel_control[channel].current_bd_ptr = desc->bd_phys;
+ sdma_enable_channel(sdma, sdmac->channel);
}
static void sdma_issue_pending(struct dma_chan *chan)
{
struct sdma_channel *sdmac = to_sdma_chan(chan);
- struct sdma_engine *sdma = sdmac->sdma;
+ unsigned long flags;
- if (sdmac->status == DMA_IN_PROGRESS)
- sdma_enable_channel(sdma, sdmac->channel);
+ spin_lock_irqsave(&sdmac->vc.lock, flags);
+ if (vchan_issue_pending(&sdmac->vc) && !sdmac->desc)
+ sdma_start_desc(sdmac);
+ spin_unlock_irqrestore(&sdmac->vc.lock, flags);
}
#define SDMA_SCRIPT_ADDRS_ARRAY_SIZE_V1 34
#define SDMA_SCRIPT_ADDRS_ARRAY_SIZE_V2 38
-#define SDMA_SCRIPT_ADDRS_ARRAY_SIZE_V3 41
-#define SDMA_SCRIPT_ADDRS_ARRAY_SIZE_V4 42
+#define SDMA_SCRIPT_ADDRS_ARRAY_SIZE_V3 43
+#define SDMA_SCRIPT_ADDRS_ARRAY_SIZE_V4 44
static void sdma_add_scripts(struct sdma_engine *sdma,
const struct sdma_script_start_addrs *addr)
@@ -1459,7 +1980,7 @@ static void sdma_load_firmware(const struct firmware *fw, void *context)
return;
}
- if (fw->size < sizeof(*header))
+ if (fw->size < sizeof(*header) || sdma->fw_loaded)
goto err_firmware;
header = (struct sdma_firmware_header *)fw->data;
@@ -1504,6 +2025,8 @@ static void sdma_load_firmware(const struct firmware *fw, void *context)
header->version_major,
header->version_minor);
+ sdma->fw_loaded = true;
+
err_firmware:
release_firmware(fw);
}
@@ -1588,7 +2111,7 @@ static int sdma_get_firmware(struct sdma_engine *sdma,
static int sdma_init(struct sdma_engine *sdma)
{
- int i, ret;
+ int i, ret, ccbsize;
dma_addr_t ccb_phys;
ret = clk_enable(sdma->clk_ipg);
@@ -1601,14 +2124,17 @@ static int sdma_init(struct sdma_engine *sdma)
/* Be sure SDMA has not started yet */
writel_relaxed(0, sdma->regs + SDMA_H_C0PTR);
- sdma->channel_control = dma_alloc_coherent(NULL,
- MAX_DMA_CHANNELS * sizeof (struct sdma_channel_control) +
- sizeof(struct sdma_context_data),
- &ccb_phys, GFP_KERNEL);
+ ccbsize = MAX_DMA_CHANNELS * (sizeof(struct sdma_channel_control)
+ + sizeof(struct sdma_context_data));
+ sdma->channel_control = gen_pool_dma_alloc(sdma->iram_pool, ccbsize, &ccb_phys);
if (!sdma->channel_control) {
- ret = -ENOMEM;
- goto err_dma_alloc;
+ sdma->channel_control = dma_alloc_coherent(sdma->dev, ccbsize,
+ &ccb_phys, GFP_KERNEL);
+ if (!sdma->channel_control) {
+ ret = -ENOMEM;
+ goto err_dma_alloc;
+ }
}
sdma->context = (void *)sdma->channel_control +
@@ -1628,7 +2154,7 @@ static int sdma_init(struct sdma_engine *sdma)
for (i = 0; i < MAX_DMA_CHANNELS; i++)
writel_relaxed(0, sdma->regs + SDMA_CHNPRI_0 + i * 4);
- ret = sdma_request_channel(&sdma->channel[0]);
+ ret = sdma_request_channel0(sdma);
if (ret)
goto err_dma_alloc;
@@ -1639,7 +2165,10 @@ static int sdma_init(struct sdma_engine *sdma)
/* Set bits of CONFIG register but with static context switching */
/* FIXME: Check whether to set ACR bit depending on clock ratios */
- writel_relaxed(0, sdma->regs + SDMA_H_CONFIG);
+ if (sdma->clk_ratio)
+ writel_relaxed(SDMA_H_CONFIG_ACR, sdma->regs + SDMA_H_CONFIG);
+ else
+ writel_relaxed(0, sdma->regs + SDMA_H_CONFIG);
writel_relaxed(ccb_phys, sdma->regs + SDMA_H_C0PTR);
@@ -1666,6 +2195,10 @@ static bool sdma_filter_fn(struct dma_chan *chan, void *fn_param)
if (!imx_dma_is_general_purpose(chan))
return false;
+ /* return false if it's not the right device */
+ if ((sdmac->sdma->drvdata == &sdma_imx8m)
+ && (sdmac->sdma->idx != data->idx))
+ return false;
sdmac->data = *data;
chan->private = &sdmac->data;
@@ -1683,17 +2216,15 @@ static struct dma_chan *sdma_xlate(struct of_phandle_args *dma_spec,
if (dma_spec->args_count != 3)
return NULL;
+ memset(&data, 0, sizeof(data));
+
data.dma_request = dma_spec->args[0];
data.peripheral_type = dma_spec->args[1];
- data.priority = dma_spec->args[2];
- /*
- * init dma_request2 to zero, which is not used by the dts.
- * For P2P, dma_request2 is init from dma_request_channel(),
- * chan->private will point to the imx_dma_data, and in
- * device_alloc_chan_resources(), imx_dma_data.dma_request2 will
- * be set to sdmac->event_id1.
- */
- data.dma_request2 = 0;
+ /* Get sw_done setting if sw_done enabled */
+ if (dma_spec->args[2] & BIT(31))
+ data.done_sel = dma_spec->args[2];
+ data.priority = dma_spec->args[2] & 0xff;
+ data.idx = sdma->idx;
return dma_request_channel(mask, sdma_filter_fn, &data);
}
@@ -1733,6 +2264,8 @@ static int sdma_probe(struct platform_device *pdev)
if (!sdma)
return -ENOMEM;
+ sdma->clk_ratio = of_property_read_bool(np, "fsl,ratio-1-1");
+
spin_lock_init(&sdma->channel_0_lock);
sdma->dev = &pdev->dev;
@@ -1783,6 +2316,7 @@ static int sdma_probe(struct platform_device *pdev)
dma_cap_set(DMA_SLAVE, sdma->dma_device.cap_mask);
dma_cap_set(DMA_CYCLIC, sdma->dma_device.cap_mask);
+ dma_cap_set(DMA_MEMCPY, sdma->dma_device.cap_mask);
INIT_LIST_HEAD(&sdma->dma_device.channels);
/* Initialize channel parameters */
@@ -1790,24 +2324,26 @@ static int sdma_probe(struct platform_device *pdev)
struct sdma_channel *sdmac = &sdma->channel[i];
sdmac->sdma = sdma;
- spin_lock_init(&sdmac->lock);
-
- sdmac->chan.device = &sdma->dma_device;
- dma_cookie_init(&sdmac->chan);
+ sdmac->context_loaded = false;
sdmac->channel = i;
+ sdmac->status = DMA_IN_PROGRESS;
+ sdmac->vc.desc_free = sdma_desc_free;
+ INIT_LIST_HEAD(&sdmac->pending);
- tasklet_init(&sdmac->tasklet, mxc_sdma_handle_channel_normal,
- (unsigned long) sdmac);
/*
* Add the channel to the DMAC list. Do not add channel 0 though
* because we need it internally in the SDMA driver. This also means
* that channel 0 in dmaengine counting matches sdma channel 1.
*/
if (i)
- list_add_tail(&sdmac->chan.device_node,
- &sdma->dma_device.channels);
+ vchan_init(&sdmac->vc, &sdma->dma_device);
}
+ if (np)
+ sdma->iram_pool = of_gen_pool_get(np, "iram", 0);
+ if (!sdma->iram_pool)
+ dev_warn(&pdev->dev, "no iram assigned, using external mem\n");
+
ret = sdma_init(sdma);
if (ret)
goto err_init;
@@ -1826,17 +2362,22 @@ static int sdma_probe(struct platform_device *pdev)
sdma->dma_device.device_alloc_chan_resources = sdma_alloc_chan_resources;
sdma->dma_device.device_free_chan_resources = sdma_free_chan_resources;
sdma->dma_device.device_tx_status = sdma_tx_status;
+ sdma->dma_device.device_synchronize = sdma_wait_tasklet;
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_config = sdma_config;
- sdma->dma_device.device_terminate_all = sdma_disable_channel_with_delay;
- 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.device_terminate_all = sdma_terminate_all;
+ sdma->dma_device.device_pause = sdma_channel_pause;
+ sdma->dma_device.device_resume = sdma_channel_resume;
+ sdma->dma_device.src_addr_widths = SDMA_DMA_BUSWIDTHS;
+ sdma->dma_device.dst_addr_widths = SDMA_DMA_BUSWIDTHS;
+ sdma->dma_device.directions = SDMA_DMA_DIRECTIONS;
sdma->dma_device.residue_granularity = DMA_RESIDUE_GRANULARITY_SEGMENT;
+ sdma->dma_device.device_prep_dma_memcpy = sdma_prep_memcpy;
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);
+ sdma->dma_device.copy_align = 2;
+ dma_set_max_seg_size(sdma->dma_device.dev, SDMA_BD_MAX_CNT);
platform_set_drvdata(pdev, sdma);
@@ -1861,6 +2402,8 @@ static int sdma_probe(struct platform_device *pdev)
}
of_node_put(spba_bus);
}
+ /* There maybe multi sdma devices such as i.mx8mscale */
+ sdma->idx = sdma_dev_idx++;
/*
* Kick off firmware loading as the very last step:
@@ -1916,17 +2459,136 @@ static int sdma_remove(struct platform_device *pdev)
for (i = 0; i < MAX_DMA_CHANNELS; i++) {
struct sdma_channel *sdmac = &sdma->channel[i];
- tasklet_kill(&sdmac->tasklet);
+ tasklet_kill(&sdmac->vc.task);
+ sdma_free_chan_resources(&sdmac->vc.chan);
}
platform_set_drvdata(pdev, NULL);
return 0;
}
+#ifdef CONFIG_PM_SLEEP
+static int sdma_suspend(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct sdma_engine *sdma = platform_get_drvdata(pdev);
+ int i, ret = 0;
+
+ /* Do nothing if not i.MX6SX or i.MX7D*/
+ if (sdma->drvdata != &sdma_imx6sx && sdma->drvdata != &sdma_imx7d
+ && sdma->drvdata != &sdma_imx6ul)
+ return 0;
+
+ clk_enable(sdma->clk_ipg);
+ clk_enable(sdma->clk_ahb);
+
+ ret = sdma_save_restore_context(sdma, true);
+ if (ret) {
+ dev_err(sdma->dev, "save context error!\n");
+ return ret;
+ }
+ /* save regs */
+ for (i = 0; i < MXC_SDMA_SAVED_REG_NUM; i++) {
+ /*
+ * 0x78(SDMA_XTRIG_CONF2+4)~0x100(SDMA_CHNPRI_O) registers are
+ * reserved and can't be touched. Skip these regs.
+ */
+ if (i > SDMA_XTRIG_CONF2 / 4)
+ sdma->save_regs[i] = readl_relaxed(sdma->regs +
+ MXC_SDMA_RESERVED_REG
+ + 4 * i);
+ else
+ sdma->save_regs[i] = readl_relaxed(sdma->regs + 4 * i);
+ }
+
+ clk_disable(sdma->clk_ipg);
+ clk_disable(sdma->clk_ahb);
+
+ return 0;
+}
+
+static int sdma_resume(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct sdma_engine *sdma = platform_get_drvdata(pdev);
+ unsigned long timeout = jiffies + msecs_to_jiffies(2);
+ int i, ret;
+
+ /* Do nothing if not i.MX6SX or i.MX7D*/
+ if (sdma->drvdata != &sdma_imx6sx && sdma->drvdata != &sdma_imx7d
+ && sdma->drvdata != &sdma_imx6ul)
+ return 0;
+
+ clk_enable(sdma->clk_ipg);
+ clk_enable(sdma->clk_ahb);
+ /* Do nothing if mega/fast mix not turned off */
+ if (readl_relaxed(sdma->regs + SDMA_H_C0PTR)) {
+ clk_disable(sdma->clk_ipg);
+ clk_disable(sdma->clk_ahb);
+ return 0;
+ }
+
+ /* Firmware was lost, mark as "not ready" */
+ sdma->fw_loaded = false;
+
+ /* restore regs and load firmware */
+ for (i = 0; i < MXC_SDMA_SAVED_REG_NUM; i++) {
+ /*
+ * 0x78(SDMA_XTRIG_CONF2+4)~0x100(SDMA_CHNPRI_O) registers are
+ * reserved and can't be touched. Skip these regs.
+ */
+ if (i > SDMA_XTRIG_CONF2 / 4)
+ writel_relaxed(sdma->save_regs[i], sdma->regs +
+ MXC_SDMA_RESERVED_REG + 4 * i);
+ /* set static context switch mode before channel0 running */
+ else if (i == SDMA_H_CONFIG / 4)
+ writel_relaxed(sdma->save_regs[i] & ~SDMA_H_CONFIG_CSM,
+ sdma->regs + SDMA_H_CONFIG);
+ else
+ writel_relaxed(sdma->save_regs[i] , sdma->regs + 4 * i);
+ }
+
+ /* prepare priority for channel0 to start */
+ sdma_set_channel_priority(&sdma->channel[0], MXC_SDMA_DEFAULT_PRIORITY);
+
+ ret = sdma_get_firmware(sdma, sdma->fw_name);
+ if (ret) {
+ dev_warn(&pdev->dev, "failed to get firware\n");
+ goto out;
+ }
+ /* wait firmware loaded */
+ do {
+ if (time_after(jiffies, timeout)) {
+ dev_warn(&pdev->dev, "failed to load firmware\n");
+ break;
+ }
+ usleep_range(50, 500);
+ } while (!sdma->fw_loaded);
+
+ ret = sdma_save_restore_context(sdma, false);
+ if (ret) {
+ dev_err(sdma->dev, "restore context error!\n");
+ goto out;
+ }
+
+ ret = 0;
+out:
+ clk_disable(sdma->clk_ipg);
+ clk_disable(sdma->clk_ahb);
+
+ return ret;
+}
+#endif
+
+static const struct dev_pm_ops sdma_pm_ops = {
+ SET_LATE_SYSTEM_SLEEP_PM_OPS(sdma_suspend, sdma_resume)
+};
+
static struct platform_driver sdma_driver = {
.driver = {
.name = "imx-sdma",
.of_match_table = sdma_dt_ids,
+ .pm = &sdma_pm_ops,
},
.id_table = sdma_devtypes,
.remove = sdma_remove,
diff --git a/drivers/dma/mxs-dma.c b/drivers/dma/mxs-dma.c
index 41d167921fab..488dc93766b6 100644
--- a/drivers/dma/mxs-dma.c
+++ b/drivers/dma/mxs-dma.c
@@ -1,5 +1,6 @@
/*
- * Copyright 2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2011-2015 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2017 NXP
*
* Refer to drivers/dma/imx-sdma.c
*
@@ -28,8 +29,9 @@
#include <linux/of_device.h>
#include <linux/of_dma.h>
#include <linux/list.h>
-
#include <asm/irq.h>
+#include <linux/pm_runtime.h>
+#include <linux/dmapool.h>
#include "dmaengine.h"
@@ -42,6 +44,8 @@
#define dma_is_apbh(mxs_dma) ((mxs_dma)->type == MXS_DMA_APBH)
#define apbh_is_old(mxs_dma) ((mxs_dma)->dev_id == IMX23_DMA)
+#define MXS_DMA_RPM_TIMEOUT 50 /* ms */
+
#define HW_APBHX_CTRL0 0x000
#define BM_APBH_CTRL0_APB_BURST8_EN (1 << 29)
#define BM_APBH_CTRL0_APB_BURST_EN (1 << 28)
@@ -120,6 +124,7 @@ struct mxs_dma_chan {
enum dma_status status;
unsigned int flags;
bool reset;
+ struct dma_pool *ccw_pool;
#define MXS_DMA_SG_LOOP (1 << 0)
#define MXS_DMA_USE_SEMAPHORE (1 << 1)
};
@@ -135,6 +140,8 @@ enum mxs_dma_devtype {
enum mxs_dma_id {
IMX23_DMA,
IMX28_DMA,
+ IMX7D_DMA,
+ IMX8QXP_DMA,
};
struct mxs_dma_engine {
@@ -142,6 +149,7 @@ struct mxs_dma_engine {
enum mxs_dma_devtype type;
void __iomem *base;
struct clk *clk;
+ struct clk *clk_io;
struct dma_device dma_device;
struct device_dma_parameters dma_parms;
struct mxs_dma_chan mxs_chans[MXS_DMA_CHANNELS];
@@ -167,6 +175,12 @@ static struct mxs_dma_type mxs_dma_types[] = {
}, {
.id = IMX28_DMA,
.type = MXS_DMA_APBX,
+ }, {
+ .id = IMX7D_DMA,
+ .type = MXS_DMA_APBH,
+ }, {
+ .id = IMX8QXP_DMA,
+ .type = MXS_DMA_APBH,
}
};
@@ -184,6 +198,12 @@ static const struct platform_device_id mxs_dma_ids[] = {
.name = "imx28-dma-apbx",
.driver_data = (kernel_ulong_t) &mxs_dma_types[3],
}, {
+ .name = "imx7d-dma-apbh",
+ .driver_data = (kernel_ulong_t) &mxs_dma_types[4],
+ }, {
+ .name = "imx8qxp-dma-apbh",
+ .driver_data = (kernel_ulong_t) &mxs_dma_types[5],
+ }, {
/* end of list */
}
};
@@ -193,6 +213,8 @@ static const struct of_device_id mxs_dma_dt_ids[] = {
{ .compatible = "fsl,imx23-dma-apbx", .data = &mxs_dma_ids[1], },
{ .compatible = "fsl,imx28-dma-apbh", .data = &mxs_dma_ids[2], },
{ .compatible = "fsl,imx28-dma-apbx", .data = &mxs_dma_ids[3], },
+ { .compatible = "fsl,imx7d-dma-apbh", .data = &mxs_dma_ids[4], },
+ { .compatible = "fsl,imx8qxp-dma-apbh", .data = &mxs_dma_ids[5], },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, mxs_dma_dt_ids);
@@ -418,11 +440,12 @@ static int mxs_dma_alloc_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;
+ struct device *dev = &mxs_dma->pdev->dev;
int ret;
- mxs_chan->ccw = dma_zalloc_coherent(mxs_dma->dma_device.dev,
- CCW_BLOCK_SIZE,
- &mxs_chan->ccw_phys, GFP_KERNEL);
+ mxs_chan->ccw = dma_pool_zalloc(mxs_chan->ccw_pool,
+ GFP_ATOMIC,
+ &mxs_chan->ccw_phys);
if (!mxs_chan->ccw) {
ret = -ENOMEM;
goto err_alloc;
@@ -433,9 +456,11 @@ static int mxs_dma_alloc_chan_resources(struct dma_chan *chan)
if (ret)
goto err_irq;
- ret = clk_prepare_enable(mxs_dma->clk);
- if (ret)
+ ret = pm_runtime_get_sync(dev);
+ if (ret < 0) {
+ dev_err(dev, "Failed to enable clock\n");
goto err_clk;
+ }
mxs_dma_reset_chan(chan);
@@ -450,8 +475,8 @@ static int mxs_dma_alloc_chan_resources(struct dma_chan *chan)
err_clk:
free_irq(mxs_chan->chan_irq, mxs_dma);
err_irq:
- dma_free_coherent(mxs_dma->dma_device.dev, CCW_BLOCK_SIZE,
- mxs_chan->ccw, mxs_chan->ccw_phys);
+ dma_pool_free(mxs_chan->ccw_pool, mxs_chan->ccw,
+ mxs_chan->ccw_phys);
err_alloc:
return ret;
}
@@ -460,15 +485,18 @@ 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;
+ struct device *dev = &mxs_dma->pdev->dev;
mxs_dma_disable_chan(chan);
free_irq(mxs_chan->chan_irq, mxs_dma);
- dma_free_coherent(mxs_dma->dma_device.dev, CCW_BLOCK_SIZE,
- mxs_chan->ccw, mxs_chan->ccw_phys);
+ dma_pool_free(mxs_chan->ccw_pool, mxs_chan->ccw,
+ mxs_chan->ccw_phys);
+
+ pm_runtime_mark_last_busy(dev);
+ pm_runtime_put_autosuspend(dev);
- clk_disable_unprepare(mxs_dma->clk);
}
/*
@@ -690,17 +718,35 @@ static enum dma_status mxs_dma_tx_status(struct dma_chan *chan,
return mxs_chan->status;
}
-static int __init mxs_dma_init(struct mxs_dma_engine *mxs_dma)
+static int mxs_dma_init_rpm(struct mxs_dma_engine *mxs_dma)
+{
+ struct device *dev = &mxs_dma->pdev->dev;
+
+ pm_runtime_enable(dev);
+ pm_runtime_set_autosuspend_delay(dev, MXS_DMA_RPM_TIMEOUT);
+ pm_runtime_use_autosuspend(dev);
+
+ return 0;
+}
+
+static int mxs_dma_init(struct mxs_dma_engine *mxs_dma)
{
+ struct device *dev = &mxs_dma->pdev->dev;
int ret;
- ret = clk_prepare_enable(mxs_dma->clk);
+ ret = mxs_dma_init_rpm(mxs_dma);
if (ret)
return ret;
+ ret = pm_runtime_get_sync(dev);
+ if (ret < 0) {
+ dev_err(dev, "Failed to enable clock\n");
+ return ret;
+ }
+
ret = stmp_reset_block(mxs_dma->base);
if (ret)
- goto err_out;
+ goto err_clk;
/* enable apbh burst */
if (dma_is_apbh(mxs_dma)) {
@@ -714,8 +760,10 @@ static int __init mxs_dma_init(struct mxs_dma_engine *mxs_dma)
writel(MXS_DMA_CHANNELS_MASK << MXS_DMA_CHANNELS,
mxs_dma->base + HW_APBHX_CTRL1 + STMP_OFFSET_REG_SET);
-err_out:
- clk_disable_unprepare(mxs_dma->clk);
+ pm_runtime_mark_last_busy(dev);
+ pm_runtime_put_autosuspend(dev);
+
+err_clk:
return ret;
}
@@ -731,6 +779,12 @@ static bool mxs_dma_filter_fn(struct dma_chan *chan, void *fn_param)
struct mxs_dma_engine *mxs_dma = mxs_chan->mxs_dma;
int chan_irq;
+ if (strcmp(chan->device->dev->driver->name, "mxs-dma"))
+ return false;
+
+ if (!mxs_dma)
+ return false;
+
if (mxs_dma->dma_device.dev->of_node != param->of_node)
return false;
@@ -765,7 +819,7 @@ static struct dma_chan *mxs_dma_xlate(struct of_phandle_args *dma_spec,
return dma_request_channel(mask, mxs_dma_filter_fn, &param);
}
-static int __init mxs_dma_probe(struct platform_device *pdev)
+static int mxs_dma_probe(struct platform_device *pdev)
{
struct device_node *np = pdev->dev.of_node;
const struct platform_device_id *id_entry;
@@ -773,6 +827,7 @@ static int __init mxs_dma_probe(struct platform_device *pdev)
const struct mxs_dma_type *dma_type;
struct mxs_dma_engine *mxs_dma;
struct resource *iores;
+ struct dma_pool *ccw_pool;
int ret, i;
mxs_dma = devm_kzalloc(&pdev->dev, sizeof(*mxs_dma), GFP_KERNEL);
@@ -820,18 +875,30 @@ static int __init mxs_dma_probe(struct platform_device *pdev)
tasklet_init(&mxs_chan->tasklet, mxs_dma_tasklet,
(unsigned long) mxs_chan);
-
/* Add the channel to mxs_chan list */
list_add_tail(&mxs_chan->chan.device_node,
&mxs_dma->dma_device.channels);
}
+ platform_set_drvdata(pdev, mxs_dma);
+ mxs_dma->pdev = pdev;
+
ret = mxs_dma_init(mxs_dma);
if (ret)
return ret;
- mxs_dma->pdev = pdev;
mxs_dma->dma_device.dev = &pdev->dev;
+ dev_set_drvdata(&pdev->dev, mxs_dma);
+
+ /* create the dma pool */
+ ccw_pool = dma_pool_create("ccw_pool",
+ mxs_dma->dma_device.dev,
+ CCW_BLOCK_SIZE, 32, 0);
+
+ for (i = 0; i < MXS_DMA_CHANNELS; i++) {
+ struct mxs_dma_chan *mxs_chan = &mxs_dma->mxs_chans[i];
+ mxs_chan->ccw_pool = ccw_pool;
+ }
/* mxs_dma gets 65535 bytes maximum sg size */
mxs_dma->dma_device.dev->dma_parms = &mxs_dma->dma_parms;
@@ -869,16 +936,81 @@ static int __init mxs_dma_probe(struct platform_device *pdev)
return 0;
}
+static int mxs_dma_remove(struct platform_device *pdev)
+{
+ struct mxs_dma_engine *mxs_dma = platform_get_drvdata(pdev);
+ int i;
+
+ dma_async_device_unregister(&mxs_dma->dma_device);
+ dma_pool_destroy(mxs_dma->mxs_chans[0].ccw_pool);
+
+ for (i = 0; i < MXS_DMA_CHANNELS; i++) {
+ struct mxs_dma_chan *mxs_chan = &mxs_dma->mxs_chans[i];
+ tasklet_kill(&mxs_chan->tasklet);
+ mxs_chan->ccw_pool = NULL;
+ }
+
+ return 0;
+}
+
+static int mxs_dma_pm_suspend(struct device *dev)
+{
+ int ret;
+
+ ret = pm_runtime_force_suspend(dev);
+
+ return ret;
+}
+
+static int mxs_dma_pm_resume(struct device *dev)
+{
+ struct mxs_dma_engine *mxs_dma = dev_get_drvdata(dev);
+ int ret;
+
+ ret = mxs_dma_init(mxs_dma);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+int mxs_dma_runtime_suspend(struct device *dev)
+{
+ struct mxs_dma_engine *mxs_dma = dev_get_drvdata(dev);
+
+ clk_disable_unprepare(mxs_dma->clk);
+
+ return 0;
+}
+
+int mxs_dma_runtime_resume(struct device *dev)
+{
+ struct mxs_dma_engine *mxs_dma = dev_get_drvdata(dev);
+ int ret;
+
+ ret = clk_prepare_enable(mxs_dma->clk);
+ if (ret) {
+ dev_err(&mxs_dma->pdev->dev, "failed to enable the clock\n");
+ return ret;
+ }
+
+ return 0;
+}
+
+static const struct dev_pm_ops mxs_dma_pm_ops = {
+ SET_RUNTIME_PM_OPS(mxs_dma_runtime_suspend, mxs_dma_runtime_resume, NULL)
+ SET_SYSTEM_SLEEP_PM_OPS(mxs_dma_pm_suspend, mxs_dma_pm_resume)
+};
+
static struct platform_driver mxs_dma_driver = {
.driver = {
.name = "mxs-dma",
+ .pm = &mxs_dma_pm_ops,
.of_match_table = mxs_dma_dt_ids,
},
.id_table = mxs_dma_ids,
+ .remove = mxs_dma_remove,
+ .probe = mxs_dma_probe,
};
-static int __init mxs_dma_module_init(void)
-{
- return platform_driver_probe(&mxs_dma_driver, mxs_dma_probe);
-}
-subsys_initcall(mxs_dma_module_init);
+module_platform_driver(mxs_dma_driver);
diff --git a/drivers/dma/pxp/Kconfig b/drivers/dma/pxp/Kconfig
new file mode 100644
index 000000000000..76717f7d78e1
--- /dev/null
+++ b/drivers/dma/pxp/Kconfig
@@ -0,0 +1,22 @@
+config MXC_PXP_V2
+ bool "MXC PxP V2 support"
+ depends on ARM
+ select DMA_ENGINE
+ help
+ Support the PxP (Pixel Pipeline) on i.MX6 DualLite and i.MX6 SoloLite.
+ If unsure, select N.
+
+config MXC_PXP_V3
+ bool "MXC PxP V3 support"
+ depends on ARM
+ select DMA_ENGINE
+ help
+ Support the PxP V3(Pixel Pipeline) on i.MX7D. The PxP V3 supports
+ more functions than PxP V2, dithering, reagl/-D and etc.
+ If unsure, select N.
+
+config MXC_PXP_CLIENT_DEVICE
+ bool "MXC PxP Client Device"
+ default y
+ depends on MXC_PXP_V2 || MXC_PXP_V3
+
diff --git a/drivers/dma/pxp/Makefile b/drivers/dma/pxp/Makefile
new file mode 100644
index 000000000000..42e4ace02fbd
--- /dev/null
+++ b/drivers/dma/pxp/Makefile
@@ -0,0 +1,3 @@
+obj-$(CONFIG_MXC_PXP_V2) += pxp_dma_v2.o
+obj-$(CONFIG_MXC_PXP_V3) += pxp_dma_v3.o
+obj-$(CONFIG_MXC_PXP_CLIENT_DEVICE) += pxp_device.o
diff --git a/drivers/dma/pxp/pxp_device.c b/drivers/dma/pxp/pxp_device.c
new file mode 100644
index 000000000000..a4a65a45d30c
--- /dev/null
+++ b/drivers/dma/pxp/pxp_device.c
@@ -0,0 +1,878 @@
+/*
+ * Copyright (C) 2010-2015 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+#include <linux/interrupt.h>
+#include <linux/miscdevice.h>
+#include <linux/platform_device.h>
+#include <linux/fs.h>
+#include <linux/slab.h>
+#include <linux/uaccess.h>
+#include <linux/delay.h>
+#include <linux/dmaengine.h>
+#include <linux/dma-mapping.h>
+#include <linux/sched.h>
+#include <linux/module.h>
+#include <linux/pxp_device.h>
+#include <linux/atomic.h>
+#include <linux/platform_data/dma-imx.h>
+
+#define BUFFER_HASH_ORDER 4
+
+static struct pxp_buffer_hash bufhash;
+static struct pxp_irq_info irq_info[NR_PXP_VIRT_CHANNEL];
+
+static int pxp_ht_create(struct pxp_buffer_hash *hash, int order)
+{
+ unsigned long i;
+ unsigned long table_size;
+
+ table_size = 1U << order;
+
+ hash->order = order;
+ hash->hash_table = kmalloc(sizeof(*hash->hash_table) * table_size, GFP_KERNEL);
+
+ if (!hash->hash_table) {
+ pr_err("%s: Out of memory for hash table\n", __func__);
+ return -ENOMEM;
+ }
+
+ for (i = 0; i < table_size; i++)
+ INIT_HLIST_HEAD(&hash->hash_table[i]);
+
+ return 0;
+}
+
+static int pxp_ht_insert_item(struct pxp_buffer_hash *hash,
+ struct pxp_buf_obj *new)
+{
+ unsigned long hashkey;
+ struct hlist_head *h_list;
+
+ hashkey = hash_long(new->offset >> PAGE_SHIFT, hash->order);
+ h_list = &hash->hash_table[hashkey];
+
+ spin_lock(&hash->hash_lock);
+ hlist_add_head_rcu(&new->item, h_list);
+ spin_unlock(&hash->hash_lock);
+
+ return 0;
+}
+
+static int pxp_ht_remove_item(struct pxp_buffer_hash *hash,
+ struct pxp_buf_obj *obj)
+{
+ spin_lock(&hash->hash_lock);
+ hlist_del_init_rcu(&obj->item);
+ spin_unlock(&hash->hash_lock);
+ return 0;
+}
+
+static struct hlist_node *pxp_ht_find_key(struct pxp_buffer_hash *hash,
+ unsigned long key)
+{
+ struct pxp_buf_obj *entry;
+ struct hlist_head *h_list;
+ unsigned long hashkey;
+
+ hashkey = hash_long(key, hash->order);
+ h_list = &hash->hash_table[hashkey];
+
+ hlist_for_each_entry_rcu(entry, h_list, item) {
+ if (entry->offset >> PAGE_SHIFT == key)
+ return &entry->item;
+ }
+
+ return NULL;
+}
+
+static void pxp_ht_destroy(struct pxp_buffer_hash *hash)
+{
+ kfree(hash->hash_table);
+ hash->hash_table = NULL;
+}
+
+static int pxp_buffer_handle_create(struct pxp_file *file_priv,
+ struct pxp_buf_obj *obj,
+ uint32_t *handlep)
+{
+ int ret;
+
+ idr_preload(GFP_KERNEL);
+ spin_lock(&file_priv->buffer_lock);
+
+ ret = idr_alloc(&file_priv->buffer_idr, obj, 1, 0, GFP_NOWAIT);
+
+ spin_unlock(&file_priv->buffer_lock);
+ idr_preload_end();
+
+ if (ret < 0)
+ return ret;
+
+ *handlep = ret;
+
+ return 0;
+}
+
+static struct pxp_buf_obj *
+pxp_buffer_object_lookup(struct pxp_file *file_priv,
+ uint32_t handle)
+{
+ struct pxp_buf_obj *obj;
+
+ spin_lock(&file_priv->buffer_lock);
+
+ obj = idr_find(&file_priv->buffer_idr, handle);
+ if (!obj) {
+ spin_unlock(&file_priv->buffer_lock);
+ return NULL;
+ }
+
+ spin_unlock(&file_priv->buffer_lock);
+
+ return obj;
+}
+
+static int pxp_buffer_handle_delete(struct pxp_file *file_priv,
+ uint32_t handle)
+{
+ struct pxp_buf_obj *obj;
+
+ spin_lock(&file_priv->buffer_lock);
+
+ obj = idr_find(&file_priv->buffer_idr, handle);
+ if (!obj) {
+ spin_unlock(&file_priv->buffer_lock);
+ return -EINVAL;
+ }
+
+ idr_remove(&file_priv->buffer_idr, handle);
+ spin_unlock(&file_priv->buffer_lock);
+
+ return 0;
+}
+
+static int pxp_channel_handle_create(struct pxp_file *file_priv,
+ struct pxp_chan_obj *obj,
+ uint32_t *handlep)
+{
+ int ret;
+
+ idr_preload(GFP_KERNEL);
+ spin_lock(&file_priv->channel_lock);
+
+ ret = idr_alloc(&file_priv->channel_idr, obj, 0, 0, GFP_NOWAIT);
+
+ spin_unlock(&file_priv->channel_lock);
+ idr_preload_end();
+
+ if (ret < 0)
+ return ret;
+
+ *handlep = ret;
+
+ return 0;
+}
+
+static struct pxp_chan_obj *
+pxp_channel_object_lookup(struct pxp_file *file_priv,
+ uint32_t handle)
+{
+ struct pxp_chan_obj *obj;
+
+ spin_lock(&file_priv->channel_lock);
+
+ obj = idr_find(&file_priv->channel_idr, handle);
+ if (!obj) {
+ spin_unlock(&file_priv->channel_lock);
+ return NULL;
+ }
+
+ spin_unlock(&file_priv->channel_lock);
+
+ return obj;
+}
+
+static int pxp_channel_handle_delete(struct pxp_file *file_priv,
+ uint32_t handle)
+{
+ struct pxp_chan_obj *obj;
+
+ spin_lock(&file_priv->channel_lock);
+
+ obj = idr_find(&file_priv->channel_idr, handle);
+ if (!obj) {
+ spin_unlock(&file_priv->channel_lock);
+ return -EINVAL;
+ }
+
+ idr_remove(&file_priv->channel_idr, handle);
+ spin_unlock(&file_priv->channel_lock);
+
+ return 0;
+}
+
+static int pxp_alloc_dma_buffer(struct pxp_buf_obj *obj)
+{
+ obj->virtual = dma_alloc_coherent(NULL, PAGE_ALIGN(obj->size),
+ (dma_addr_t *) (&obj->offset),
+ GFP_DMA | GFP_KERNEL);
+ pr_debug("[ALLOC] mem alloc phys_addr = 0x%lx\n", obj->offset);
+
+ if (obj->virtual == NULL) {
+ printk(KERN_ERR "Physical memory allocation error!\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+static void pxp_free_dma_buffer(struct pxp_buf_obj *obj)
+{
+ if (obj->virtual != NULL) {
+ dma_free_coherent(0, PAGE_ALIGN(obj->size),
+ obj->virtual, (dma_addr_t)obj->offset);
+ }
+}
+
+static int
+pxp_buffer_object_free(int id, void *ptr, void *data)
+{
+ struct pxp_file *file_priv = data;
+ struct pxp_buf_obj *obj = ptr;
+ int ret;
+
+ ret = pxp_buffer_handle_delete(file_priv, obj->handle);
+ if (ret < 0)
+ return ret;
+
+ pxp_ht_remove_item(&bufhash, obj);
+ pxp_free_dma_buffer(obj);
+ kfree(obj);
+
+ return 0;
+}
+
+static int
+pxp_channel_object_free(int id, void *ptr, void *data)
+{
+ struct pxp_file *file_priv = data;
+ struct pxp_chan_obj *obj = ptr;
+ int chan_id;
+
+ chan_id = obj->chan->chan_id;
+ wait_event(irq_info[chan_id].waitq,
+ atomic_read(&irq_info[chan_id].irq_pending) == 0);
+
+ pxp_channel_handle_delete(file_priv, obj->handle);
+ dma_release_channel(obj->chan);
+ kfree(obj);
+
+ return 0;
+}
+
+static void pxp_free_buffers(struct pxp_file *file_priv)
+{
+ idr_for_each(&file_priv->buffer_idr,
+ &pxp_buffer_object_free, file_priv);
+ idr_destroy(&file_priv->buffer_idr);
+}
+
+static void pxp_free_channels(struct pxp_file *file_priv)
+{
+ idr_for_each(&file_priv->channel_idr,
+ &pxp_channel_object_free, file_priv);
+ idr_destroy(&file_priv->channel_idr);
+}
+
+/* Callback function triggered after PxP receives an EOF interrupt */
+static void pxp_dma_done(void *arg)
+{
+ struct pxp_tx_desc *tx_desc = to_tx_desc(arg);
+ struct dma_chan *chan = tx_desc->txd.chan;
+ struct pxp_channel *pxp_chan = to_pxp_channel(chan);
+ int chan_id = pxp_chan->dma_chan.chan_id;
+
+ pr_debug("DMA Done ISR, chan_id %d\n", chan_id);
+
+ atomic_dec(&irq_info[chan_id].irq_pending);
+ irq_info[chan_id].hist_status = tx_desc->hist_status;
+
+ wake_up(&(irq_info[chan_id].waitq));
+}
+
+static int pxp_ioc_config_chan(struct pxp_file *priv, unsigned long arg)
+{
+ struct scatterlist *sg;
+ struct pxp_tx_desc *desc;
+ struct dma_async_tx_descriptor *txd;
+ struct pxp_config_data *pxp_conf;
+ dma_cookie_t cookie;
+ int handle, chan_id;
+ struct dma_chan *chan;
+ struct pxp_chan_obj *obj;
+ int i = 0, j = 0, k = 0, m = 0, length, ret, sg_len;
+
+ pxp_conf = kzalloc(sizeof(*pxp_conf), GFP_KERNEL);
+ if (!pxp_conf)
+ return -ENOMEM;
+
+ ret = copy_from_user(pxp_conf,
+ (struct pxp_config_data *)arg,
+ sizeof(struct pxp_config_data));
+ if (ret) {
+ kfree(pxp_conf);
+ return -EFAULT;
+ }
+
+ handle = pxp_conf->handle;
+ obj = pxp_channel_object_lookup(priv, handle);
+ if (!obj) {
+ kfree(pxp_conf);
+ return -EINVAL;
+ }
+ chan = obj->chan;
+ chan_id = chan->chan_id;
+
+ sg_len = 3;
+ if (pxp_conf->proc_data.engine_enable & PXP_ENABLE_WFE_A)
+ sg_len += 4;
+ if (pxp_conf->proc_data.engine_enable & PXP_ENABLE_WFE_B)
+ sg_len += 4;
+ if (pxp_conf->proc_data.engine_enable & PXP_ENABLE_DITHER)
+ sg_len += 4;
+
+ sg = kmalloc(sizeof(*sg) * sg_len, GFP_KERNEL);
+ if (!sg) {
+ kfree(pxp_conf);
+ return -ENOMEM;
+ }
+
+ sg_init_table(sg, sg_len);
+
+ txd = chan->device->device_prep_slave_sg(chan,
+ sg, sg_len,
+ DMA_TO_DEVICE,
+ DMA_PREP_INTERRUPT,
+ NULL);
+ if (!txd) {
+ pr_err("Error preparing a DMA transaction descriptor.\n");
+ kfree(pxp_conf);
+ kfree(sg);
+ return -EIO;
+ }
+
+ txd->callback_param = txd;
+ txd->callback = pxp_dma_done;
+
+ desc = to_tx_desc(txd);
+
+ length = desc->len;
+ for (i = 0; i < length; i++) {
+ if (i == 0) { /* S0 */
+ memcpy(&desc->proc_data,
+ &pxp_conf->proc_data,
+ sizeof(struct pxp_proc_data));
+ memcpy(&desc->layer_param.s0_param,
+ &pxp_conf->s0_param,
+ sizeof(struct pxp_layer_param));
+ desc = desc->next;
+ } else if (i == 1) { /* Output */
+ memcpy(&desc->layer_param.out_param,
+ &pxp_conf->out_param,
+ sizeof(struct pxp_layer_param));
+ desc = desc->next;
+ } else if (i == 2) {
+ /* OverLay */
+ memcpy(&desc->layer_param.ol_param,
+ &pxp_conf->ol_param,
+ sizeof(struct pxp_layer_param));
+ desc = desc->next;
+ } else if ((pxp_conf->proc_data.engine_enable & PXP_ENABLE_WFE_A) && (j < 4)) {
+ for (j = 0; j < 4; j++) {
+ if (j == 0) {
+ memcpy(&desc->layer_param.processing_param,
+ &pxp_conf->wfe_a_fetch_param[0],
+ sizeof(struct pxp_layer_param));
+ desc->layer_param.processing_param.flag = PXP_BUF_FLAG_WFE_A_FETCH0;
+ } else if (j == 1) {
+ memcpy(&desc->layer_param.processing_param,
+ &pxp_conf->wfe_a_fetch_param[1],
+ sizeof(struct pxp_layer_param));
+ desc->layer_param.processing_param.flag = PXP_BUF_FLAG_WFE_A_FETCH1;
+ } else if (j == 2) {
+ memcpy(&desc->layer_param.processing_param,
+ &pxp_conf->wfe_a_store_param[0],
+ sizeof(struct pxp_layer_param));
+ desc->layer_param.processing_param.flag = PXP_BUF_FLAG_WFE_A_STORE0;
+ } else if (j == 3) {
+ memcpy(&desc->layer_param.processing_param,
+ &pxp_conf->wfe_a_store_param[1],
+ sizeof(struct pxp_layer_param));
+ desc->layer_param.processing_param.flag = PXP_BUF_FLAG_WFE_A_STORE1;
+ }
+
+ desc = desc->next;
+ }
+
+ i += 4;
+
+ } else if ((pxp_conf->proc_data.engine_enable & PXP_ENABLE_WFE_B) && (m < 4)) {
+ for (m = 0; m < 4; m++) {
+ if (m == 0) {
+ memcpy(&desc->layer_param.processing_param,
+ &pxp_conf->wfe_b_fetch_param[0],
+ sizeof(struct pxp_layer_param));
+ desc->layer_param.processing_param.flag = PXP_BUF_FLAG_WFE_B_FETCH0;
+ } else if (m == 1) {
+ memcpy(&desc->layer_param.processing_param,
+ &pxp_conf->wfe_b_fetch_param[1],
+ sizeof(struct pxp_layer_param));
+ desc->layer_param.processing_param.flag = PXP_BUF_FLAG_WFE_B_FETCH1;
+ } else if (m == 2) {
+ memcpy(&desc->layer_param.processing_param,
+ &pxp_conf->wfe_b_store_param[0],
+ sizeof(struct pxp_layer_param));
+ desc->layer_param.processing_param.flag = PXP_BUF_FLAG_WFE_B_STORE0;
+ } else if (m == 3) {
+ memcpy(&desc->layer_param.processing_param,
+ &pxp_conf->wfe_b_store_param[1],
+ sizeof(struct pxp_layer_param));
+ desc->layer_param.processing_param.flag = PXP_BUF_FLAG_WFE_B_STORE1;
+ }
+
+ desc = desc->next;
+ }
+
+ i += 4;
+
+ } else if ((pxp_conf->proc_data.engine_enable & PXP_ENABLE_DITHER) && (k < 4)) {
+ for (k = 0; k < 4; k++) {
+ if (k == 0) {
+ memcpy(&desc->layer_param.processing_param,
+ &pxp_conf->dither_fetch_param[0],
+ sizeof(struct pxp_layer_param));
+ desc->layer_param.processing_param.flag = PXP_BUF_FLAG_DITHER_FETCH0;
+ } else if (k == 1) {
+ memcpy(&desc->layer_param.processing_param,
+ &pxp_conf->dither_fetch_param[1],
+ sizeof(struct pxp_layer_param));
+ desc->layer_param.processing_param.flag = PXP_BUF_FLAG_DITHER_FETCH1;
+ } else if (k == 2) {
+ memcpy(&desc->layer_param.processing_param,
+ &pxp_conf->dither_store_param[0],
+ sizeof(struct pxp_layer_param));
+ desc->layer_param.processing_param.flag = PXP_BUF_FLAG_DITHER_STORE0;
+ } else if (k == 3) {
+ memcpy(&desc->layer_param.processing_param,
+ &pxp_conf->dither_store_param[1],
+ sizeof(struct pxp_layer_param));
+ desc->layer_param.processing_param.flag = PXP_BUF_FLAG_DITHER_STORE1;
+ }
+
+ desc = desc->next;
+ }
+
+ i += 4;
+ }
+ }
+
+ cookie = txd->tx_submit(txd);
+ if (cookie < 0) {
+ pr_err("Error tx_submit\n");
+ kfree(pxp_conf);
+ kfree(sg);
+ return -EIO;
+ }
+
+ atomic_inc(&irq_info[chan_id].irq_pending);
+
+ kfree(pxp_conf);
+ kfree(sg);
+
+ return 0;
+}
+
+static int pxp_device_open(struct inode *inode, struct file *filp)
+{
+ struct pxp_file *priv;
+
+ priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+
+ if (!priv)
+ return -ENOMEM;
+
+ filp->private_data = priv;
+ priv->filp = filp;
+
+ idr_init(&priv->buffer_idr);
+ spin_lock_init(&priv->buffer_lock);
+
+ idr_init(&priv->channel_idr);
+ spin_lock_init(&priv->channel_lock);
+
+ return 0;
+}
+
+static int pxp_device_release(struct inode *inode, struct file *filp)
+{
+ struct pxp_file *priv = filp->private_data;
+
+ if (priv) {
+ pxp_free_channels(priv);
+ pxp_free_buffers(priv);
+ kfree(priv);
+ filp->private_data = NULL;
+ }
+
+ return 0;
+}
+
+static int pxp_device_mmap(struct file *file, struct vm_area_struct *vma)
+{
+ int request_size;
+ struct hlist_node *node;
+ struct pxp_buf_obj *obj;
+
+ request_size = vma->vm_end - vma->vm_start;
+
+ pr_debug("start=0x%x, pgoff=0x%x, size=0x%x\n",
+ (unsigned int)(vma->vm_start), (unsigned int)(vma->vm_pgoff),
+ request_size);
+
+ node = pxp_ht_find_key(&bufhash, vma->vm_pgoff);
+ if (!node)
+ return -EINVAL;
+
+ obj = list_entry(node, struct pxp_buf_obj, item);
+ if (obj->offset + (obj->size >> PAGE_SHIFT) <
+ (vma->vm_pgoff + vma_pages(vma)))
+ return -ENOMEM;
+
+ switch (obj->mem_type) {
+ case MEMORY_TYPE_UNCACHED:
+ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+ break;
+ case MEMORY_TYPE_WC:
+ vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
+ break;
+ case MEMORY_TYPE_CACHED:
+ break;
+ default:
+ pr_err("%s: invalid memory type!\n", __func__);
+ return -EINVAL;
+ }
+
+ return remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
+ request_size, vma->vm_page_prot) ? -EAGAIN : 0;
+}
+
+static bool chan_filter(struct dma_chan *chan, void *arg)
+{
+ if (imx_dma_is_pxp(chan))
+ return true;
+ else
+ return false;
+}
+
+static long pxp_device_ioctl(struct file *filp,
+ unsigned int cmd, unsigned long arg)
+{
+ int ret = 0;
+ struct pxp_file *file_priv = filp->private_data;
+
+ switch (cmd) {
+ case PXP_IOC_GET_CHAN:
+ {
+ int ret;
+ struct dma_chan *chan = NULL;
+ dma_cap_mask_t mask;
+ struct pxp_chan_obj *obj = NULL;
+
+ pr_debug("drv: PXP_IOC_GET_CHAN Line %d\n", __LINE__);
+
+ dma_cap_zero(mask);
+ dma_cap_set(DMA_SLAVE, mask);
+ dma_cap_set(DMA_PRIVATE, mask);
+
+ chan = dma_request_channel(mask, chan_filter, NULL);
+ if (!chan) {
+ pr_err("Unsccessfully received channel!\n");
+ return -EBUSY;
+ }
+
+ pr_debug("Successfully received channel."
+ "chan_id %d\n", chan->chan_id);
+
+ obj = kzalloc(sizeof(*obj), GFP_KERNEL);
+ if (!obj) {
+ dma_release_channel(chan);
+ return -ENOMEM;
+ }
+ obj->chan = chan;
+
+ ret = pxp_channel_handle_create(file_priv, obj,
+ &obj->handle);
+ if (ret) {
+ dma_release_channel(chan);
+ kfree(obj);
+ return ret;
+ }
+
+ init_waitqueue_head(&(irq_info[chan->chan_id].waitq));
+ if (put_user(obj->handle, (u32 __user *) arg)) {
+ pxp_channel_handle_delete(file_priv, obj->handle);
+ dma_release_channel(chan);
+ kfree(obj);
+ return -EFAULT;
+ }
+
+ break;
+ }
+ case PXP_IOC_PUT_CHAN:
+ {
+ int handle;
+ struct pxp_chan_obj *obj;
+
+ if (get_user(handle, (u32 __user *) arg))
+ return -EFAULT;
+
+ pr_debug("%d release handle %d\n", __LINE__, handle);
+
+ obj = pxp_channel_object_lookup(file_priv, handle);
+ if (!obj)
+ return -EINVAL;
+
+ pxp_channel_handle_delete(file_priv, obj->handle);
+ dma_release_channel(obj->chan);
+ kfree(obj);
+
+ break;
+ }
+ case PXP_IOC_CONFIG_CHAN:
+ {
+ int ret;
+
+ ret = pxp_ioc_config_chan(file_priv, arg);
+ if (ret)
+ return ret;
+
+ break;
+ }
+ case PXP_IOC_START_CHAN:
+ {
+ int handle;
+ struct pxp_chan_obj *obj = NULL;
+
+ if (get_user(handle, (u32 __user *) arg))
+ return -EFAULT;
+
+ obj = pxp_channel_object_lookup(file_priv, handle);
+ if (!obj)
+ return -EINVAL;
+
+ dma_async_issue_pending(obj->chan);
+
+ break;
+ }
+ case PXP_IOC_GET_PHYMEM:
+ {
+ struct pxp_mem_desc buffer;
+ struct pxp_buf_obj *obj;
+
+ ret = copy_from_user(&buffer,
+ (struct pxp_mem_desc *)arg,
+ sizeof(struct pxp_mem_desc));
+ if (ret)
+ return -EFAULT;
+
+ pr_debug("[ALLOC] mem alloc size = 0x%x\n",
+ buffer.size);
+
+ obj = kzalloc(sizeof(*obj), GFP_KERNEL);
+ if (!obj)
+ return -ENOMEM;
+ obj->size = buffer.size;
+ obj->mem_type = buffer.mtype;
+
+ ret = pxp_alloc_dma_buffer(obj);
+ if (ret == -1) {
+ printk(KERN_ERR
+ "Physical memory allocation error!\n");
+ kfree(obj);
+ return ret;
+ }
+
+ ret = pxp_buffer_handle_create(file_priv, obj, &obj->handle);
+ if (ret) {
+ pxp_free_dma_buffer(obj);
+ kfree(obj);
+ return ret;
+ }
+ buffer.handle = obj->handle;
+ buffer.phys_addr = obj->offset;
+
+ ret = copy_to_user((void __user *)arg, &buffer,
+ sizeof(struct pxp_mem_desc));
+ if (ret) {
+ pxp_buffer_handle_delete(file_priv, buffer.handle);
+ pxp_free_dma_buffer(obj);
+ kfree(obj);
+ return -EFAULT;
+ }
+
+ pxp_ht_insert_item(&bufhash, obj);
+
+ break;
+ }
+ case PXP_IOC_PUT_PHYMEM:
+ {
+ struct pxp_mem_desc pxp_mem;
+ struct pxp_buf_obj *obj;
+
+ ret = copy_from_user(&pxp_mem,
+ (struct pxp_mem_desc *)arg,
+ sizeof(struct pxp_mem_desc));
+ if (ret)
+ return -EACCES;
+
+ obj = pxp_buffer_object_lookup(file_priv, pxp_mem.handle);
+ if (!obj)
+ return -EINVAL;
+
+ ret = pxp_buffer_handle_delete(file_priv, obj->handle);
+ if (ret)
+ return ret;
+
+ pxp_ht_remove_item(&bufhash, obj);
+ pxp_free_dma_buffer(obj);
+ kfree(obj);
+
+ break;
+ }
+ case PXP_IOC_FLUSH_PHYMEM:
+ {
+ int ret;
+ struct pxp_mem_flush flush;
+ struct pxp_buf_obj *obj;
+
+ ret = copy_from_user(&flush,
+ (struct pxp_mem_flush *)arg,
+ sizeof(struct pxp_mem_flush));
+ if (ret)
+ return -EACCES;
+
+ obj = pxp_buffer_object_lookup(file_priv, flush.handle);
+ if (!obj)
+ return -EINVAL;
+
+ switch (flush.type) {
+ case CACHE_CLEAN:
+ dma_sync_single_for_device(NULL, obj->offset,
+ obj->size, DMA_TO_DEVICE);
+ break;
+ case CACHE_INVALIDATE:
+ dma_sync_single_for_device(NULL, obj->offset,
+ obj->size, DMA_FROM_DEVICE);
+ break;
+ case CACHE_FLUSH:
+ dma_sync_single_for_device(NULL, obj->offset,
+ obj->size, DMA_TO_DEVICE);
+ dma_sync_single_for_device(NULL, obj->offset,
+ obj->size, DMA_FROM_DEVICE);
+ break;
+ default:
+ pr_err("%s: invalid cache flush type\n", __func__);
+ return -EINVAL;
+ }
+
+ break;
+ }
+ case PXP_IOC_WAIT4CMPLT:
+ {
+ struct pxp_chan_handle chan_handle;
+ int ret, chan_id, handle;
+ struct pxp_chan_obj *obj = NULL;
+
+ ret = copy_from_user(&chan_handle,
+ (struct pxp_chan_handle *)arg,
+ sizeof(struct pxp_chan_handle));
+ if (ret)
+ return -EFAULT;
+
+ handle = chan_handle.handle;
+ obj = pxp_channel_object_lookup(file_priv, handle);
+ if (!obj)
+ return -EINVAL;
+ chan_id = obj->chan->chan_id;
+
+ ret = wait_event_interruptible
+ (irq_info[chan_id].waitq,
+ (atomic_read(&irq_info[chan_id].irq_pending) == 0));
+ if (ret < 0)
+ return -ERESTARTSYS;
+
+ chan_handle.hist_status = irq_info[chan_id].hist_status;
+ ret = copy_to_user((struct pxp_chan_handle *)arg,
+ &chan_handle,
+ sizeof(struct pxp_chan_handle));
+ if (ret)
+ return -EFAULT;
+ break;
+ }
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+static const struct file_operations pxp_device_fops = {
+ .open = pxp_device_open,
+ .release = pxp_device_release,
+ .unlocked_ioctl = pxp_device_ioctl,
+ .mmap = pxp_device_mmap,
+};
+
+static struct miscdevice pxp_device_miscdev = {
+ .minor = MISC_DYNAMIC_MINOR,
+ .name = "pxp_device",
+ .fops = &pxp_device_fops,
+};
+
+int register_pxp_device(void)
+{
+ int ret;
+
+ ret = misc_register(&pxp_device_miscdev);
+ if (ret)
+ return ret;
+
+ ret = pxp_ht_create(&bufhash, BUFFER_HASH_ORDER);
+ if (ret)
+ return ret;
+ spin_lock_init(&(bufhash.hash_lock));
+
+ pr_debug("PxP_Device registered Successfully\n");
+ return 0;
+}
+
+void unregister_pxp_device(void)
+{
+ pxp_ht_destroy(&bufhash);
+ misc_deregister(&pxp_device_miscdev);
+}
diff --git a/drivers/dma/pxp/pxp_dma_v2.c b/drivers/dma/pxp/pxp_dma_v2.c
new file mode 100644
index 000000000000..8ab9e29dc896
--- /dev/null
+++ b/drivers/dma/pxp/pxp_dma_v2.c
@@ -0,0 +1,1865 @@
+/*
+ * Copyright (C) 2010-2016 Freescale Semiconductor, Inc.
+ * Copyright 2017 NXP
+ *
+ * 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
+ *
+ */
+/*
+ * Based on STMP378X PxP driver
+ * Copyright 2008-2009 Embedded Alley Solutions, Inc All Rights Reserved.
+ */
+
+#include <linux/clk.h>
+#include <linux/dma-mapping.h>
+#include <linux/dmaengine.h>
+#include <linux/freezer.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/kthread.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/pxp_dma.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/timer.h>
+#include <linux/vmalloc.h>
+#include <linux/workqueue.h>
+
+#include "regs-pxp_v2.h"
+
+#define PXP_DOWNSCALE_THRESHOLD 0x4000
+
+static LIST_HEAD(head);
+static int timeout_in_ms = 600;
+static unsigned int block_size;
+static struct kmem_cache *tx_desc_cache;
+
+struct pxp_dma {
+ struct dma_device dma;
+};
+
+struct pxps {
+ struct platform_device *pdev;
+ struct clk *clk;
+ struct clk *clk_disp_axi; /* may exist on some SoC for gating */
+ void __iomem *base;
+ int irq; /* PXP IRQ to the CPU */
+
+ spinlock_t lock;
+ struct mutex clk_mutex;
+ int clk_stat;
+#define CLK_STAT_OFF 0
+#define CLK_STAT_ON 1
+ int pxp_ongoing;
+ int lut_state;
+
+ struct device *dev;
+ struct pxp_dma pxp_dma;
+ struct pxp_channel channel[NR_PXP_VIRT_CHANNEL];
+ struct work_struct work;
+
+ /* describes most recent processing configuration */
+ struct pxp_config_data pxp_conf_state;
+
+ /* to turn clock off when pxp is inactive */
+ struct timer_list clk_timer;
+
+ /* for pxp config dispatch asynchronously*/
+ struct task_struct *dispatch;
+ wait_queue_head_t thread_waitq;
+ struct completion complete;
+};
+
+#define to_pxp_dma(d) container_of(d, struct pxp_dma, dma)
+#define to_tx_desc(tx) container_of(tx, struct pxp_tx_desc, txd)
+#define to_pxp_channel(d) container_of(d, struct pxp_channel, dma_chan)
+#define to_pxp(id) container_of(id, struct pxps, pxp_dma)
+
+#define PXP_DEF_BUFS 2
+#define PXP_MIN_PIX 8
+
+/*
+ * PXP common functions
+ */
+static void dump_pxp_reg(struct pxps *pxp)
+{
+ dev_dbg(pxp->dev, "PXP_CTRL 0x%x",
+ __raw_readl(pxp->base + HW_PXP_CTRL));
+ dev_dbg(pxp->dev, "PXP_STAT 0x%x",
+ __raw_readl(pxp->base + HW_PXP_STAT));
+ dev_dbg(pxp->dev, "PXP_OUT_CTRL 0x%x",
+ __raw_readl(pxp->base + HW_PXP_OUT_CTRL));
+ dev_dbg(pxp->dev, "PXP_OUT_BUF 0x%x",
+ __raw_readl(pxp->base + HW_PXP_OUT_BUF));
+ dev_dbg(pxp->dev, "PXP_OUT_BUF2 0x%x",
+ __raw_readl(pxp->base + HW_PXP_OUT_BUF2));
+ dev_dbg(pxp->dev, "PXP_OUT_PITCH 0x%x",
+ __raw_readl(pxp->base + HW_PXP_OUT_PITCH));
+ dev_dbg(pxp->dev, "PXP_OUT_LRC 0x%x",
+ __raw_readl(pxp->base + HW_PXP_OUT_LRC));
+ dev_dbg(pxp->dev, "PXP_OUT_PS_ULC 0x%x",
+ __raw_readl(pxp->base + HW_PXP_OUT_PS_ULC));
+ dev_dbg(pxp->dev, "PXP_OUT_PS_LRC 0x%x",
+ __raw_readl(pxp->base + HW_PXP_OUT_PS_LRC));
+ dev_dbg(pxp->dev, "PXP_OUT_AS_ULC 0x%x",
+ __raw_readl(pxp->base + HW_PXP_OUT_AS_ULC));
+ dev_dbg(pxp->dev, "PXP_OUT_AS_LRC 0x%x",
+ __raw_readl(pxp->base + HW_PXP_OUT_AS_LRC));
+ dev_dbg(pxp->dev, "PXP_PS_CTRL 0x%x",
+ __raw_readl(pxp->base + HW_PXP_PS_CTRL));
+ dev_dbg(pxp->dev, "PXP_PS_BUF 0x%x",
+ __raw_readl(pxp->base + HW_PXP_PS_BUF));
+ dev_dbg(pxp->dev, "PXP_PS_UBUF 0x%x",
+ __raw_readl(pxp->base + HW_PXP_PS_UBUF));
+ dev_dbg(pxp->dev, "PXP_PS_VBUF 0x%x",
+ __raw_readl(pxp->base + HW_PXP_PS_VBUF));
+ dev_dbg(pxp->dev, "PXP_PS_PITCH 0x%x",
+ __raw_readl(pxp->base + HW_PXP_PS_PITCH));
+ dev_dbg(pxp->dev, "PXP_PS_BACKGROUND 0x%x",
+ __raw_readl(pxp->base + HW_PXP_PS_BACKGROUND));
+ dev_dbg(pxp->dev, "PXP_PS_SCALE 0x%x",
+ __raw_readl(pxp->base + HW_PXP_PS_SCALE));
+ dev_dbg(pxp->dev, "PXP_PS_OFFSET 0x%x",
+ __raw_readl(pxp->base + HW_PXP_PS_OFFSET));
+ dev_dbg(pxp->dev, "PXP_PS_CLRKEYLOW 0x%x",
+ __raw_readl(pxp->base + HW_PXP_PS_CLRKEYLOW));
+ dev_dbg(pxp->dev, "PXP_PS_CLRKEYHIGH 0x%x",
+ __raw_readl(pxp->base + HW_PXP_PS_CLRKEYHIGH));
+ dev_dbg(pxp->dev, "PXP_AS_CTRL 0x%x",
+ __raw_readl(pxp->base + HW_PXP_AS_CTRL));
+ dev_dbg(pxp->dev, "PXP_AS_BUF 0x%x",
+ __raw_readl(pxp->base + HW_PXP_AS_BUF));
+ dev_dbg(pxp->dev, "PXP_AS_PITCH 0x%x",
+ __raw_readl(pxp->base + HW_PXP_AS_PITCH));
+ dev_dbg(pxp->dev, "PXP_AS_CLRKEYLOW 0x%x",
+ __raw_readl(pxp->base + HW_PXP_AS_CLRKEYLOW));
+ dev_dbg(pxp->dev, "PXP_AS_CLRKEYHIGH 0x%x",
+ __raw_readl(pxp->base + HW_PXP_AS_CLRKEYHIGH));
+ dev_dbg(pxp->dev, "PXP_CSC1_COEF0 0x%x",
+ __raw_readl(pxp->base + HW_PXP_CSC1_COEF0));
+ dev_dbg(pxp->dev, "PXP_CSC1_COEF1 0x%x",
+ __raw_readl(pxp->base + HW_PXP_CSC1_COEF1));
+ dev_dbg(pxp->dev, "PXP_CSC1_COEF2 0x%x",
+ __raw_readl(pxp->base + HW_PXP_CSC1_COEF2));
+ dev_dbg(pxp->dev, "PXP_CSC2_CTRL 0x%x",
+ __raw_readl(pxp->base + HW_PXP_CSC2_CTRL));
+ dev_dbg(pxp->dev, "PXP_CSC2_COEF0 0x%x",
+ __raw_readl(pxp->base + HW_PXP_CSC2_COEF0));
+ dev_dbg(pxp->dev, "PXP_CSC2_COEF1 0x%x",
+ __raw_readl(pxp->base + HW_PXP_CSC2_COEF1));
+ dev_dbg(pxp->dev, "PXP_CSC2_COEF2 0x%x",
+ __raw_readl(pxp->base + HW_PXP_CSC2_COEF2));
+ dev_dbg(pxp->dev, "PXP_CSC2_COEF3 0x%x",
+ __raw_readl(pxp->base + HW_PXP_CSC2_COEF3));
+ dev_dbg(pxp->dev, "PXP_CSC2_COEF4 0x%x",
+ __raw_readl(pxp->base + HW_PXP_CSC2_COEF4));
+ dev_dbg(pxp->dev, "PXP_CSC2_COEF5 0x%x",
+ __raw_readl(pxp->base + HW_PXP_CSC2_COEF5));
+ dev_dbg(pxp->dev, "PXP_LUT_CTRL 0x%x",
+ __raw_readl(pxp->base + HW_PXP_LUT_CTRL));
+ dev_dbg(pxp->dev, "PXP_LUT_ADDR 0x%x",
+ __raw_readl(pxp->base + HW_PXP_LUT_ADDR));
+ dev_dbg(pxp->dev, "PXP_LUT_DATA 0x%x",
+ __raw_readl(pxp->base + HW_PXP_LUT_DATA));
+ dev_dbg(pxp->dev, "PXP_LUT_EXTMEM 0x%x",
+ __raw_readl(pxp->base + HW_PXP_LUT_EXTMEM));
+ dev_dbg(pxp->dev, "PXP_CFA 0x%x",
+ __raw_readl(pxp->base + HW_PXP_CFA));
+ dev_dbg(pxp->dev, "PXP_HIST_CTRL 0x%x",
+ __raw_readl(pxp->base + HW_PXP_HIST_CTRL));
+ dev_dbg(pxp->dev, "PXP_HIST2_PARAM 0x%x",
+ __raw_readl(pxp->base + HW_PXP_HIST2_PARAM));
+ dev_dbg(pxp->dev, "PXP_HIST4_PARAM 0x%x",
+ __raw_readl(pxp->base + HW_PXP_HIST4_PARAM));
+ dev_dbg(pxp->dev, "PXP_HIST8_PARAM0 0x%x",
+ __raw_readl(pxp->base + HW_PXP_HIST8_PARAM0));
+ dev_dbg(pxp->dev, "PXP_HIST8_PARAM1 0x%x",
+ __raw_readl(pxp->base + HW_PXP_HIST8_PARAM1));
+ dev_dbg(pxp->dev, "PXP_HIST16_PARAM0 0x%x",
+ __raw_readl(pxp->base + HW_PXP_HIST16_PARAM0));
+ dev_dbg(pxp->dev, "PXP_HIST16_PARAM1 0x%x",
+ __raw_readl(pxp->base + HW_PXP_HIST16_PARAM1));
+ dev_dbg(pxp->dev, "PXP_HIST16_PARAM2 0x%x",
+ __raw_readl(pxp->base + HW_PXP_HIST16_PARAM2));
+ dev_dbg(pxp->dev, "PXP_HIST16_PARAM3 0x%x",
+ __raw_readl(pxp->base + HW_PXP_HIST16_PARAM3));
+ dev_dbg(pxp->dev, "PXP_POWER 0x%x",
+ __raw_readl(pxp->base + HW_PXP_POWER));
+ dev_dbg(pxp->dev, "PXP_NEXT 0x%x",
+ __raw_readl(pxp->base + HW_PXP_NEXT));
+ dev_dbg(pxp->dev, "PXP_DEBUGCTRL 0x%x",
+ __raw_readl(pxp->base + HW_PXP_DEBUGCTRL));
+ dev_dbg(pxp->dev, "PXP_DEBUG 0x%x",
+ __raw_readl(pxp->base + HW_PXP_DEBUG));
+ dev_dbg(pxp->dev, "PXP_VERSION 0x%x",
+ __raw_readl(pxp->base + HW_PXP_VERSION));
+}
+
+static bool is_yuv(u32 pix_fmt)
+{
+ switch (pix_fmt) {
+ case PXP_PIX_FMT_YUYV:
+ case PXP_PIX_FMT_UYVY:
+ case PXP_PIX_FMT_YVYU:
+ case PXP_PIX_FMT_VYUY:
+ case PXP_PIX_FMT_Y41P:
+ case PXP_PIX_FMT_VUY444:
+ case PXP_PIX_FMT_NV12:
+ case PXP_PIX_FMT_NV21:
+ case PXP_PIX_FMT_NV16:
+ case PXP_PIX_FMT_NV61:
+ case PXP_PIX_FMT_GREY:
+ case PXP_PIX_FMT_GY04:
+ case PXP_PIX_FMT_YVU410P:
+ case PXP_PIX_FMT_YUV410P:
+ case PXP_PIX_FMT_YVU420P:
+ case PXP_PIX_FMT_YUV420P:
+ case PXP_PIX_FMT_YUV420P2:
+ case PXP_PIX_FMT_YVU422P:
+ case PXP_PIX_FMT_YUV422P:
+ return true;
+ default:
+ return false;
+ }
+}
+
+static void pxp_soft_reset(struct pxps *pxp)
+{
+ __raw_writel(BM_PXP_CTRL_SFTRST, pxp->base + HW_PXP_CTRL_CLR);
+ __raw_writel(BM_PXP_CTRL_CLKGATE, pxp->base + HW_PXP_CTRL_CLR);
+
+ __raw_writel(BM_PXP_CTRL_SFTRST, pxp->base + HW_PXP_CTRL_SET);
+ while (!(__raw_readl(pxp->base + HW_PXP_CTRL) & BM_PXP_CTRL_CLKGATE))
+ dev_dbg(pxp->dev, "%s: wait for clock gate off", __func__);
+
+ __raw_writel(BM_PXP_CTRL_SFTRST, pxp->base + HW_PXP_CTRL_CLR);
+ __raw_writel(BM_PXP_CTRL_CLKGATE, pxp->base + HW_PXP_CTRL_CLR);
+}
+
+static void pxp_set_ctrl(struct pxps *pxp)
+{
+ struct pxp_config_data *pxp_conf = &pxp->pxp_conf_state;
+ struct pxp_proc_data *proc_data = &pxp_conf->proc_data;
+ u32 ctrl;
+ u32 fmt_ctrl;
+ int need_swap = 0; /* to support YUYV and YVYU formats */
+
+ /* Configure S0 input format */
+ switch (pxp_conf->s0_param.pixel_fmt) {
+ case PXP_PIX_FMT_XRGB32:
+ fmt_ctrl = BV_PXP_PS_CTRL_FORMAT__RGB888;
+ break;
+ case PXP_PIX_FMT_RGB565:
+ fmt_ctrl = BV_PXP_PS_CTRL_FORMAT__RGB565;
+ break;
+ case PXP_PIX_FMT_RGB555:
+ fmt_ctrl = BV_PXP_PS_CTRL_FORMAT__RGB555;
+ break;
+ case PXP_PIX_FMT_YUV420P:
+ fmt_ctrl = BV_PXP_PS_CTRL_FORMAT__YUV420;
+ break;
+ case PXP_PIX_FMT_YVU420P:
+ fmt_ctrl = BV_PXP_PS_CTRL_FORMAT__YUV420;
+ break;
+ case PXP_PIX_FMT_GREY:
+ fmt_ctrl = BV_PXP_PS_CTRL_FORMAT__Y8;
+ break;
+ case PXP_PIX_FMT_GY04:
+ fmt_ctrl = BV_PXP_PS_CTRL_FORMAT__Y4;
+ break;
+ case PXP_PIX_FMT_VUY444:
+ fmt_ctrl = BV_PXP_PS_CTRL_FORMAT__YUV1P444;
+ break;
+ case PXP_PIX_FMT_YUV422P:
+ fmt_ctrl = BV_PXP_PS_CTRL_FORMAT__YUV422;
+ break;
+ case PXP_PIX_FMT_UYVY:
+ fmt_ctrl = BV_PXP_PS_CTRL_FORMAT__UYVY1P422;
+ break;
+ case PXP_PIX_FMT_YUYV:
+ fmt_ctrl = BV_PXP_PS_CTRL_FORMAT__UYVY1P422;
+ need_swap = 1;
+ break;
+ case PXP_PIX_FMT_VYUY:
+ fmt_ctrl = BV_PXP_PS_CTRL_FORMAT__VYUY1P422;
+ break;
+ case PXP_PIX_FMT_YVYU:
+ fmt_ctrl = BV_PXP_PS_CTRL_FORMAT__VYUY1P422;
+ need_swap = 1;
+ break;
+ case PXP_PIX_FMT_NV12:
+ fmt_ctrl = BV_PXP_PS_CTRL_FORMAT__YUV2P420;
+ break;
+ case PXP_PIX_FMT_NV21:
+ fmt_ctrl = BV_PXP_PS_CTRL_FORMAT__YVU2P420;
+ break;
+ case PXP_PIX_FMT_NV16:
+ fmt_ctrl = BV_PXP_PS_CTRL_FORMAT__YUV2P422;
+ break;
+ case PXP_PIX_FMT_NV61:
+ fmt_ctrl = BV_PXP_PS_CTRL_FORMAT__YVU2P422;
+ break;
+ default:
+ fmt_ctrl = 0;
+ }
+
+ ctrl = BF_PXP_PS_CTRL_FORMAT(fmt_ctrl) | BF_PXP_PS_CTRL_SWAP(need_swap);
+ __raw_writel(ctrl, pxp->base + HW_PXP_PS_CTRL_SET);
+
+ /* Configure output format based on out_channel format */
+ switch (pxp_conf->out_param.pixel_fmt) {
+ case PXP_PIX_FMT_XRGB32:
+ fmt_ctrl = BV_PXP_OUT_CTRL_FORMAT__RGB888;
+ break;
+ case PXP_PIX_FMT_BGRA32:
+ fmt_ctrl = BV_PXP_OUT_CTRL_FORMAT__ARGB8888;
+ break;
+ case PXP_PIX_FMT_RGB24:
+ fmt_ctrl = BV_PXP_OUT_CTRL_FORMAT__RGB888P;
+ break;
+ case PXP_PIX_FMT_RGB565:
+ fmt_ctrl = BV_PXP_OUT_CTRL_FORMAT__RGB565;
+ break;
+ case PXP_PIX_FMT_RGB555:
+ fmt_ctrl = BV_PXP_OUT_CTRL_FORMAT__RGB555;
+ break;
+ case PXP_PIX_FMT_GREY:
+ fmt_ctrl = BV_PXP_OUT_CTRL_FORMAT__Y8;
+ break;
+ case PXP_PIX_FMT_GY04:
+ fmt_ctrl = BV_PXP_OUT_CTRL_FORMAT__Y4;
+ break;
+ case PXP_PIX_FMT_UYVY:
+ fmt_ctrl = BV_PXP_OUT_CTRL_FORMAT__UYVY1P422;
+ break;
+ case PXP_PIX_FMT_VYUY:
+ fmt_ctrl = BV_PXP_OUT_CTRL_FORMAT__VYUY1P422;
+ break;
+ case PXP_PIX_FMT_NV12:
+ fmt_ctrl = BV_PXP_OUT_CTRL_FORMAT__YUV2P420;
+ break;
+ case PXP_PIX_FMT_NV21:
+ fmt_ctrl = BV_PXP_OUT_CTRL_FORMAT__YVU2P420;
+ break;
+ case PXP_PIX_FMT_NV16:
+ fmt_ctrl = BV_PXP_OUT_CTRL_FORMAT__YUV2P422;
+ break;
+ case PXP_PIX_FMT_NV61:
+ fmt_ctrl = BV_PXP_OUT_CTRL_FORMAT__YVU2P422;
+ break;
+ default:
+ fmt_ctrl = 0;
+ }
+
+ ctrl = BF_PXP_OUT_CTRL_FORMAT(fmt_ctrl);
+ __raw_writel(ctrl, pxp->base + HW_PXP_OUT_CTRL);
+
+ ctrl = 0;
+ if (proc_data->scaling)
+ ;
+ if (proc_data->vflip)
+ ctrl |= BM_PXP_CTRL_VFLIP;
+ if (proc_data->hflip)
+ ctrl |= BM_PXP_CTRL_HFLIP;
+ if (proc_data->rotate)
+ ctrl |= BF_PXP_CTRL_ROTATE(proc_data->rotate / 90);
+
+ /* In default, the block size is set to 8x8
+ * But block size can be set to 16x16 due to
+ * blocksize variable modification
+ */
+ ctrl |= block_size << 23;
+
+ __raw_writel(ctrl, pxp->base + HW_PXP_CTRL);
+}
+
+static int pxp_start(struct pxps *pxp)
+{
+ __raw_writel(BM_PXP_CTRL_IRQ_ENABLE, pxp->base + HW_PXP_CTRL_SET);
+ __raw_writel(BM_PXP_CTRL_ENABLE, pxp->base + HW_PXP_CTRL_SET);
+ dump_pxp_reg(pxp);
+
+ return 0;
+}
+
+static void pxp_set_outbuf(struct pxps *pxp)
+{
+ struct pxp_config_data *pxp_conf = &pxp->pxp_conf_state;
+ struct pxp_layer_param *out_params = &pxp_conf->out_param;
+ struct pxp_proc_data *proc_data = &pxp_conf->proc_data;
+
+ __raw_writel(out_params->paddr, pxp->base + HW_PXP_OUT_BUF);
+
+ if ((out_params->pixel_fmt == PXP_PIX_FMT_NV12) ||
+ (out_params->pixel_fmt == PXP_PIX_FMT_NV21) ||
+ (out_params->pixel_fmt == PXP_PIX_FMT_NV16) ||
+ (out_params->pixel_fmt == PXP_PIX_FMT_NV61)) {
+ dma_addr_t Y, U;
+
+ Y = out_params->paddr;
+ U = Y + (out_params->width * out_params->height);
+
+ __raw_writel(U, pxp->base + HW_PXP_OUT_BUF2);
+ }
+
+ if (proc_data->rotate == 90 || proc_data->rotate == 270)
+ __raw_writel(BF_PXP_OUT_LRC_X(out_params->height - 1) |
+ BF_PXP_OUT_LRC_Y(out_params->width - 1),
+ pxp->base + HW_PXP_OUT_LRC);
+ else
+ __raw_writel(BF_PXP_OUT_LRC_X(out_params->width - 1) |
+ BF_PXP_OUT_LRC_Y(out_params->height - 1),
+ pxp->base + HW_PXP_OUT_LRC);
+
+ if (out_params->pixel_fmt == PXP_PIX_FMT_RGB24) {
+ __raw_writel(out_params->stride * 3,
+ pxp->base + HW_PXP_OUT_PITCH);
+ } else if (out_params->pixel_fmt == PXP_PIX_FMT_BGRA32 ||
+ out_params->pixel_fmt == PXP_PIX_FMT_XRGB32) {
+ __raw_writel(out_params->stride << 2,
+ pxp->base + HW_PXP_OUT_PITCH);
+ } else if ((out_params->pixel_fmt == PXP_PIX_FMT_RGB565) ||
+ (out_params->pixel_fmt == PXP_PIX_FMT_RGB555)) {
+ __raw_writel(out_params->stride << 1,
+ pxp->base + HW_PXP_OUT_PITCH);
+ } else if (out_params->pixel_fmt == PXP_PIX_FMT_UYVY ||
+ (out_params->pixel_fmt == PXP_PIX_FMT_VYUY)) {
+ __raw_writel(out_params->stride << 1,
+ pxp->base + HW_PXP_OUT_PITCH);
+ } else if (out_params->pixel_fmt == PXP_PIX_FMT_GREY ||
+ out_params->pixel_fmt == PXP_PIX_FMT_NV12 ||
+ out_params->pixel_fmt == PXP_PIX_FMT_NV21 ||
+ out_params->pixel_fmt == PXP_PIX_FMT_NV16 ||
+ out_params->pixel_fmt == PXP_PIX_FMT_NV61) {
+ __raw_writel(out_params->stride,
+ pxp->base + HW_PXP_OUT_PITCH);
+ } else if (out_params->pixel_fmt == PXP_PIX_FMT_GY04) {
+ __raw_writel(out_params->stride >> 1,
+ pxp->base + HW_PXP_OUT_PITCH);
+ } else {
+ __raw_writel(0, pxp->base + HW_PXP_OUT_PITCH);
+ }
+
+ /* set global alpha if necessary */
+ if (out_params->global_alpha_enable) {
+ __raw_writel(out_params->global_alpha << 24,
+ pxp->base + HW_PXP_OUT_CTRL_SET);
+ __raw_writel(BM_PXP_OUT_CTRL_ALPHA_OUTPUT,
+ pxp->base + HW_PXP_OUT_CTRL_SET);
+ }
+}
+
+static void pxp_set_s0colorkey(struct pxps *pxp)
+{
+ struct pxp_config_data *pxp_conf = &pxp->pxp_conf_state;
+ struct pxp_layer_param *s0_params = &pxp_conf->s0_param;
+
+ /* Low and high are set equal. V4L does not allow a chromakey range */
+ if (s0_params->color_key_enable == 0 || s0_params->color_key == -1) {
+ /* disable color key */
+ __raw_writel(0xFFFFFF, pxp->base + HW_PXP_PS_CLRKEYLOW);
+ __raw_writel(0, pxp->base + HW_PXP_PS_CLRKEYHIGH);
+ } else {
+ __raw_writel(s0_params->color_key,
+ pxp->base + HW_PXP_PS_CLRKEYLOW);
+ __raw_writel(s0_params->color_key,
+ pxp->base + HW_PXP_PS_CLRKEYHIGH);
+ }
+}
+
+static void pxp_set_olcolorkey(int layer_no, struct pxps *pxp)
+{
+ struct pxp_config_data *pxp_conf = &pxp->pxp_conf_state;
+ struct pxp_layer_param *ol_params = &pxp_conf->ol_param[layer_no];
+
+ /* Low and high are set equal. V4L does not allow a chromakey range */
+ if (ol_params->color_key_enable != 0 && ol_params->color_key != -1) {
+ __raw_writel(ol_params->color_key,
+ pxp->base + HW_PXP_AS_CLRKEYLOW);
+ __raw_writel(ol_params->color_key,
+ pxp->base + HW_PXP_AS_CLRKEYHIGH);
+ } else {
+ /* disable color key */
+ __raw_writel(0xFFFFFF, pxp->base + HW_PXP_AS_CLRKEYLOW);
+ __raw_writel(0, pxp->base + HW_PXP_AS_CLRKEYHIGH);
+ }
+}
+
+static void pxp_set_oln(int layer_no, struct pxps *pxp)
+{
+ struct pxp_config_data *pxp_conf = &pxp->pxp_conf_state;
+ struct pxp_layer_param *olparams_data = &pxp_conf->ol_param[layer_no];
+ dma_addr_t phys_addr = olparams_data->paddr;
+ u32 pitch = olparams_data->stride ? olparams_data->stride :
+ olparams_data->width;
+
+ __raw_writel(phys_addr, pxp->base + HW_PXP_AS_BUF);
+
+ /* Fixme */
+ if (olparams_data->width == 0 && olparams_data->height == 0) {
+ __raw_writel(0xffffffff, pxp->base + HW_PXP_OUT_AS_ULC);
+ __raw_writel(0x0, pxp->base + HW_PXP_OUT_AS_LRC);
+ } else {
+ __raw_writel(0x0, pxp->base + HW_PXP_OUT_AS_ULC);
+ __raw_writel(BF_PXP_OUT_AS_LRC_X(olparams_data->width - 1) |
+ BF_PXP_OUT_AS_LRC_Y(olparams_data->height - 1),
+ pxp->base + HW_PXP_OUT_AS_LRC);
+ }
+
+ if ((olparams_data->pixel_fmt == PXP_PIX_FMT_BGRA32) ||
+ (olparams_data->pixel_fmt == PXP_PIX_FMT_XRGB32)) {
+ __raw_writel(pitch << 2,
+ pxp->base + HW_PXP_AS_PITCH);
+ } else if ((olparams_data->pixel_fmt == PXP_PIX_FMT_RGB565) ||
+ (olparams_data->pixel_fmt == PXP_PIX_FMT_RGB555)) {
+ __raw_writel(pitch << 1,
+ pxp->base + HW_PXP_AS_PITCH);
+ } else {
+ __raw_writel(0, pxp->base + HW_PXP_AS_PITCH);
+ }
+}
+
+static void pxp_set_olparam(int layer_no, struct pxps *pxp)
+{
+ struct pxp_config_data *pxp_conf = &pxp->pxp_conf_state;
+ struct pxp_layer_param *olparams_data = &pxp_conf->ol_param[layer_no];
+ u32 olparam;
+
+ olparam = BF_PXP_AS_CTRL_ALPHA(olparams_data->global_alpha);
+ if (olparams_data->pixel_fmt == PXP_PIX_FMT_XRGB32) {
+ olparam |=
+ BF_PXP_AS_CTRL_FORMAT(BV_PXP_AS_CTRL_FORMAT__RGB888);
+ } else if (olparams_data->pixel_fmt == PXP_PIX_FMT_BGRA32) {
+ olparam |=
+ BF_PXP_AS_CTRL_FORMAT(BV_PXP_AS_CTRL_FORMAT__ARGB8888);
+ if (!olparams_data->combine_enable) {
+ olparam |=
+ BF_PXP_AS_CTRL_ALPHA_CTRL
+ (BV_PXP_AS_CTRL_ALPHA_CTRL__ROPs);
+ olparam |= 0x3 << 16;
+ }
+ } else if (olparams_data->pixel_fmt == PXP_PIX_FMT_RGB565) {
+ olparam |=
+ BF_PXP_AS_CTRL_FORMAT(BV_PXP_AS_CTRL_FORMAT__RGB565);
+ } else if (olparams_data->pixel_fmt == PXP_PIX_FMT_RGB555) {
+ olparam |=
+ BF_PXP_AS_CTRL_FORMAT(BV_PXP_AS_CTRL_FORMAT__RGB555);
+ }
+
+ if (olparams_data->global_alpha_enable) {
+ if (olparams_data->global_override) {
+ olparam |=
+ BF_PXP_AS_CTRL_ALPHA_CTRL
+ (BV_PXP_AS_CTRL_ALPHA_CTRL__Override);
+ } else {
+ olparam |=
+ BF_PXP_AS_CTRL_ALPHA_CTRL
+ (BV_PXP_AS_CTRL_ALPHA_CTRL__Multiply);
+ }
+ if (olparams_data->alpha_invert)
+ olparam |= BM_PXP_AS_CTRL_ALPHA_INVERT;
+ }
+ if (olparams_data->color_key_enable)
+ olparam |= BM_PXP_AS_CTRL_ENABLE_COLORKEY;
+
+ __raw_writel(olparam, pxp->base + HW_PXP_AS_CTRL);
+}
+
+static void pxp_set_s0param(struct pxps *pxp)
+{
+ struct pxp_config_data *pxp_conf = &pxp->pxp_conf_state;
+ struct pxp_proc_data *proc_data = &pxp_conf->proc_data;
+ struct pxp_layer_param *out_params = &pxp_conf->out_param;
+ u32 s0param_ulc, s0param_lrc;
+
+ /* contains the coordinate for the PS in the OUTPUT buffer. */
+ if ((pxp_conf->s0_param).width == 0 &&
+ (pxp_conf->s0_param).height == 0) {
+ __raw_writel(0xffffffff, pxp->base + HW_PXP_OUT_PS_ULC);
+ __raw_writel(0x0, pxp->base + HW_PXP_OUT_PS_LRC);
+ } else {
+ switch (proc_data->rotate) {
+ case 0:
+ s0param_ulc = BF_PXP_OUT_PS_ULC_X(proc_data->drect.left);
+ s0param_ulc |= BF_PXP_OUT_PS_ULC_Y(proc_data->drect.top);
+ s0param_lrc = BF_PXP_OUT_PS_LRC_X(((s0param_ulc & BM_PXP_OUT_PS_ULC_X) >> 16) + proc_data->drect.width - 1);
+ s0param_lrc |= BF_PXP_OUT_PS_LRC_Y((s0param_ulc & BM_PXP_OUT_PS_ULC_Y) + proc_data->drect.height - 1);
+ break;
+ case 90:
+ s0param_ulc = BF_PXP_OUT_PS_ULC_Y(out_params->width - (proc_data->drect.left + proc_data->drect.width));
+ s0param_ulc |= BF_PXP_OUT_PS_ULC_X(proc_data->drect.top);
+ s0param_lrc = BF_PXP_OUT_PS_LRC_X(((s0param_ulc & BM_PXP_OUT_PS_ULC_X) >> 16) + proc_data->drect.height - 1);
+ s0param_lrc |= BF_PXP_OUT_PS_LRC_Y((s0param_ulc & BM_PXP_OUT_PS_ULC_Y) + proc_data->drect.width - 1);
+ break;
+ case 180:
+ s0param_ulc = BF_PXP_OUT_PS_ULC_X(out_params->width - (proc_data->drect.left + proc_data->drect.width));
+ s0param_ulc |= BF_PXP_OUT_PS_ULC_Y(out_params->height - (proc_data->drect.top + proc_data->drect.height));
+ s0param_lrc = BF_PXP_OUT_PS_LRC_X(((s0param_ulc & BM_PXP_OUT_PS_ULC_X) >> 16) + proc_data->drect.width - 1);
+ s0param_lrc |= BF_PXP_OUT_PS_LRC_Y((s0param_ulc & BM_PXP_OUT_PS_ULC_Y) + proc_data->drect.height - 1);
+ break;
+ case 270:
+ s0param_ulc = BF_PXP_OUT_PS_ULC_X(out_params->height - (proc_data->drect.top + proc_data->drect.height));
+ s0param_ulc |= BF_PXP_OUT_PS_ULC_Y(proc_data->drect.left);
+ s0param_lrc = BF_PXP_OUT_PS_LRC_X(((s0param_ulc & BM_PXP_OUT_PS_ULC_X) >> 16) + proc_data->drect.height - 1);
+ s0param_lrc |= BF_PXP_OUT_PS_LRC_Y((s0param_ulc & BM_PXP_OUT_PS_ULC_Y) + proc_data->drect.width - 1);
+ break;
+ default:
+ return;
+ }
+ __raw_writel(s0param_ulc, pxp->base + HW_PXP_OUT_PS_ULC);
+ __raw_writel(s0param_lrc, pxp->base + HW_PXP_OUT_PS_LRC);
+ }
+
+ /* Since user apps always pass the rotated drect
+ * to this driver, we need to first swap the width
+ * and height which is used to calculate the scale
+ * factors later.
+ */
+ if (proc_data->rotate == 90 || proc_data->rotate == 270) {
+ int temp;
+ temp = proc_data->drect.width;
+ proc_data->drect.width = proc_data->drect.height;
+ proc_data->drect.height = temp;
+ }
+}
+
+/* crop behavior is re-designed in h/w. */
+static void pxp_set_s0crop(struct pxps *pxp)
+{
+ /*
+ * place-holder, it's implemented in other functions in this driver.
+ * Refer to "Clipping source images" section in RM for detail.
+ */
+}
+
+static int pxp_set_scaling(struct pxps *pxp)
+{
+ int ret = 0;
+ u32 xscale, yscale, s0scale;
+ u32 decx, decy, xdec = 0, ydec = 0;
+ struct pxp_proc_data *proc_data = &pxp->pxp_conf_state.proc_data;
+ struct pxp_config_data *pxp_conf = &pxp->pxp_conf_state;
+ struct pxp_layer_param *s0_params = &pxp_conf->s0_param;
+ struct pxp_layer_param *out_params = &pxp_conf->out_param;
+
+ proc_data->scaling = 1;
+
+ if (!proc_data->drect.width || !proc_data->drect.height) {
+ pr_err("Invalid drect width and height passed in\n");
+ return -EINVAL;
+ }
+
+ decx = proc_data->srect.width / proc_data->drect.width;
+ decy = proc_data->srect.height / proc_data->drect.height;
+ if (decx > 1) {
+ if (decx >= 2 && decx < 4) {
+ decx = 2;
+ xdec = 1;
+ } else if (decx >= 4 && decx < 8) {
+ decx = 4;
+ xdec = 2;
+ } else if (decx >= 8) {
+ decx = 8;
+ xdec = 3;
+ }
+ xscale = proc_data->srect.width * 0x1000 /
+ (proc_data->drect.width * decx);
+ } else {
+ if (!is_yuv(s0_params->pixel_fmt) ||
+ (is_yuv(s0_params->pixel_fmt) ==
+ is_yuv(out_params->pixel_fmt)) ||
+ (s0_params->pixel_fmt == PXP_PIX_FMT_GREY) ||
+ (s0_params->pixel_fmt == PXP_PIX_FMT_GY04) ||
+ (s0_params->pixel_fmt == PXP_PIX_FMT_VUY444)) {
+ if ((proc_data->srect.width > 1) &&
+ (proc_data->drect.width > 1))
+ xscale = (proc_data->srect.width - 1) * 0x1000 /
+ (proc_data->drect.width - 1);
+ else
+ xscale = proc_data->srect.width * 0x1000 /
+ proc_data->drect.width;
+ } else {
+ if ((proc_data->srect.width > 2) &&
+ (proc_data->drect.width > 1))
+ xscale = (proc_data->srect.width - 2) * 0x1000 /
+ (proc_data->drect.width - 1);
+ else
+ xscale = proc_data->srect.width * 0x1000 /
+ proc_data->drect.width;
+ }
+ }
+ if (decy > 1) {
+ if (decy >= 2 && decy < 4) {
+ decy = 2;
+ ydec = 1;
+ } else if (decy >= 4 && decy < 8) {
+ decy = 4;
+ ydec = 2;
+ } else if (decy >= 8) {
+ decy = 8;
+ ydec = 3;
+ }
+ yscale = proc_data->srect.height * 0x1000 /
+ (proc_data->drect.height * decy);
+ } else {
+ if ((proc_data->srect.height > 1) &&
+ (proc_data->drect.height > 1))
+ yscale = (proc_data->srect.height - 1) * 0x1000 /
+ (proc_data->drect.height - 1);
+ else
+ yscale = proc_data->srect.height * 0x1000 /
+ proc_data->drect.height;
+ }
+
+ __raw_writel((xdec << 10) | (ydec << 8), pxp->base + HW_PXP_PS_CTRL);
+
+ if (xscale > PXP_DOWNSCALE_THRESHOLD)
+ xscale = PXP_DOWNSCALE_THRESHOLD;
+ if (yscale > PXP_DOWNSCALE_THRESHOLD)
+ yscale = PXP_DOWNSCALE_THRESHOLD;
+ s0scale = BF_PXP_PS_SCALE_YSCALE(yscale) |
+ BF_PXP_PS_SCALE_XSCALE(xscale);
+ __raw_writel(s0scale, pxp->base + HW_PXP_PS_SCALE);
+
+ pxp_set_ctrl(pxp);
+
+ return ret;
+}
+
+static void pxp_set_bg(struct pxps *pxp)
+{
+ __raw_writel(pxp->pxp_conf_state.proc_data.bgcolor,
+ pxp->base + HW_PXP_PS_BACKGROUND);
+}
+
+static void pxp_set_lut(struct pxps *pxp)
+{
+ struct pxp_config_data *pxp_conf = &pxp->pxp_conf_state;
+ int lut_op = pxp_conf->proc_data.lut_transform;
+ u32 reg_val;
+ int i;
+ bool use_cmap = (lut_op & PXP_LUT_USE_CMAP) ? true : false;
+ u8 *cmap = pxp_conf->proc_data.lut_map;
+ u32 entry_src;
+ u32 pix_val;
+ u8 entry[4];
+
+ /*
+ * If LUT already configured as needed, return...
+ * Unless CMAP is needed and it has been updated.
+ */
+ if ((pxp->lut_state == lut_op) &&
+ !(use_cmap && pxp_conf->proc_data.lut_map_updated))
+ return;
+
+ if (lut_op == PXP_LUT_NONE) {
+ __raw_writel(BM_PXP_LUT_CTRL_BYPASS,
+ pxp->base + HW_PXP_LUT_CTRL);
+ } else if (((lut_op & PXP_LUT_INVERT) != 0)
+ && ((lut_op & PXP_LUT_BLACK_WHITE) != 0)) {
+ /* Fill out LUT table with inverted monochromized values */
+
+ /* clear bypass bit, set lookup mode & out mode */
+ __raw_writel(BF_PXP_LUT_CTRL_LOOKUP_MODE
+ (BV_PXP_LUT_CTRL_LOOKUP_MODE__DIRECT_Y8) |
+ BF_PXP_LUT_CTRL_OUT_MODE
+ (BV_PXP_LUT_CTRL_OUT_MODE__Y8),
+ pxp->base + HW_PXP_LUT_CTRL);
+
+ /* Initialize LUT address to 0 and set NUM_BYTES to 0 */
+ __raw_writel(0, pxp->base + HW_PXP_LUT_ADDR);
+
+ /* LUT address pointer auto-increments after each data write */
+ for (pix_val = 0; pix_val < 256; pix_val += 4) {
+ for (i = 0; i < 4; i++) {
+ entry_src = use_cmap ?
+ cmap[pix_val + i] : pix_val + i;
+ entry[i] = (entry_src < 0x80) ? 0xFF : 0x00;
+ }
+ reg_val = (entry[3] << 24) | (entry[2] << 16) |
+ (entry[1] << 8) | entry[0];
+ __raw_writel(reg_val, pxp->base + HW_PXP_LUT_DATA);
+ }
+ } else if ((lut_op & PXP_LUT_INVERT) != 0) {
+ /* Fill out LUT table with 8-bit inverted values */
+
+ /* clear bypass bit, set lookup mode & out mode */
+ __raw_writel(BF_PXP_LUT_CTRL_LOOKUP_MODE
+ (BV_PXP_LUT_CTRL_LOOKUP_MODE__DIRECT_Y8) |
+ BF_PXP_LUT_CTRL_OUT_MODE
+ (BV_PXP_LUT_CTRL_OUT_MODE__Y8),
+ pxp->base + HW_PXP_LUT_CTRL);
+
+ /* Initialize LUT address to 0 and set NUM_BYTES to 0 */
+ __raw_writel(0, pxp->base + HW_PXP_LUT_ADDR);
+
+ /* LUT address pointer auto-increments after each data write */
+ for (pix_val = 0; pix_val < 256; pix_val += 4) {
+ for (i = 0; i < 4; i++) {
+ entry_src = use_cmap ?
+ cmap[pix_val + i] : pix_val + i;
+ entry[i] = ~entry_src & 0xFF;
+ }
+ reg_val = (entry[3] << 24) | (entry[2] << 16) |
+ (entry[1] << 8) | entry[0];
+ __raw_writel(reg_val, pxp->base + HW_PXP_LUT_DATA);
+ }
+ } else if ((lut_op & PXP_LUT_BLACK_WHITE) != 0) {
+ /* Fill out LUT table with 8-bit monochromized values */
+
+ /* clear bypass bit, set lookup mode & out mode */
+ __raw_writel(BF_PXP_LUT_CTRL_LOOKUP_MODE
+ (BV_PXP_LUT_CTRL_LOOKUP_MODE__DIRECT_Y8) |
+ BF_PXP_LUT_CTRL_OUT_MODE
+ (BV_PXP_LUT_CTRL_OUT_MODE__Y8),
+ pxp->base + HW_PXP_LUT_CTRL);
+
+ /* Initialize LUT address to 0 and set NUM_BYTES to 0 */
+ __raw_writel(0, pxp->base + HW_PXP_LUT_ADDR);
+
+ /* LUT address pointer auto-increments after each data write */
+ for (pix_val = 0; pix_val < 256; pix_val += 4) {
+ for (i = 0; i < 4; i++) {
+ entry_src = use_cmap ?
+ cmap[pix_val + i] : pix_val + i;
+ entry[i] = (entry_src < 0x80) ? 0x00 : 0xFF;
+ }
+ reg_val = (entry[3] << 24) | (entry[2] << 16) |
+ (entry[1] << 8) | entry[0];
+ __raw_writel(reg_val, pxp->base + HW_PXP_LUT_DATA);
+ }
+ } else if (use_cmap) {
+ /* Fill out LUT table using colormap values */
+
+ /* clear bypass bit, set lookup mode & out mode */
+ __raw_writel(BF_PXP_LUT_CTRL_LOOKUP_MODE
+ (BV_PXP_LUT_CTRL_LOOKUP_MODE__DIRECT_Y8) |
+ BF_PXP_LUT_CTRL_OUT_MODE
+ (BV_PXP_LUT_CTRL_OUT_MODE__Y8),
+ pxp->base + HW_PXP_LUT_CTRL);
+
+ /* Initialize LUT address to 0 and set NUM_BYTES to 0 */
+ __raw_writel(0, pxp->base + HW_PXP_LUT_ADDR);
+
+ /* LUT address pointer auto-increments after each data write */
+ for (pix_val = 0; pix_val < 256; pix_val += 4) {
+ for (i = 0; i < 4; i++)
+ entry[i] = cmap[pix_val + i];
+ reg_val = (entry[3] << 24) | (entry[2] << 16) |
+ (entry[1] << 8) | entry[0];
+ __raw_writel(reg_val, pxp->base + HW_PXP_LUT_DATA);
+ }
+ }
+
+ pxp->lut_state = lut_op;
+}
+
+static void pxp_set_csc(struct pxps *pxp)
+{
+ struct pxp_config_data *pxp_conf = &pxp->pxp_conf_state;
+ struct pxp_layer_param *s0_params = &pxp_conf->s0_param;
+ struct pxp_layer_param *ol_params = &pxp_conf->ol_param[0];
+ struct pxp_layer_param *out_params = &pxp_conf->out_param;
+
+ bool input_is_YUV = is_yuv(s0_params->pixel_fmt);
+ bool output_is_YUV = is_yuv(out_params->pixel_fmt);
+
+ if (input_is_YUV && output_is_YUV) {
+ /*
+ * Input = YUV, Output = YUV
+ * No CSC unless we need to do combining
+ */
+ if (ol_params->combine_enable) {
+ /* Must convert to RGB for combining with RGB overlay */
+
+ /* CSC1 - YUV->RGB */
+ __raw_writel(0x04030000, pxp->base + HW_PXP_CSC1_COEF0);
+ __raw_writel(0x01230208, pxp->base + HW_PXP_CSC1_COEF1);
+ __raw_writel(0x076b079c, pxp->base + HW_PXP_CSC1_COEF2);
+
+ /* CSC2 - RGB->YUV */
+ __raw_writel(0x4, pxp->base + HW_PXP_CSC2_CTRL);
+ __raw_writel(0x0096004D, pxp->base + HW_PXP_CSC2_COEF0);
+ __raw_writel(0x05DA001D, pxp->base + HW_PXP_CSC2_COEF1);
+ __raw_writel(0x007005B6, pxp->base + HW_PXP_CSC2_COEF2);
+ __raw_writel(0x057C009E, pxp->base + HW_PXP_CSC2_COEF3);
+ __raw_writel(0x000005E6, pxp->base + HW_PXP_CSC2_COEF4);
+ __raw_writel(0x00000000, pxp->base + HW_PXP_CSC2_COEF5);
+ } else {
+ /* Input & Output both YUV, so bypass both CSCs */
+
+ /* CSC1 - Bypass */
+ __raw_writel(0x40000000, pxp->base + HW_PXP_CSC1_COEF0);
+
+ /* CSC2 - Bypass */
+ __raw_writel(0x1, pxp->base + HW_PXP_CSC2_CTRL);
+ }
+ } else if (input_is_YUV && !output_is_YUV) {
+ /*
+ * Input = YUV, Output = RGB
+ * Use CSC1 to convert to RGB
+ */
+
+ /* CSC1 - YUV->RGB */
+ __raw_writel(0x84ab01f0, pxp->base + HW_PXP_CSC1_COEF0);
+ __raw_writel(0x01980204, pxp->base + HW_PXP_CSC1_COEF1);
+ __raw_writel(0x0730079c, pxp->base + HW_PXP_CSC1_COEF2);
+
+ /* CSC2 - Bypass */
+ __raw_writel(0x1, pxp->base + HW_PXP_CSC2_CTRL);
+ } else if (!input_is_YUV && output_is_YUV) {
+ /*
+ * Input = RGB, Output = YUV
+ * Use CSC2 to convert to YUV
+ */
+
+ /* CSC1 - Bypass */
+ __raw_writel(0x40000000, pxp->base + HW_PXP_CSC1_COEF0);
+
+ /* CSC2 - RGB->YUV */
+ __raw_writel(0x4, pxp->base + HW_PXP_CSC2_CTRL);
+ __raw_writel(0x0096004D, pxp->base + HW_PXP_CSC2_COEF0);
+ __raw_writel(0x05DA001D, pxp->base + HW_PXP_CSC2_COEF1);
+ __raw_writel(0x007005B6, pxp->base + HW_PXP_CSC2_COEF2);
+ __raw_writel(0x057C009E, pxp->base + HW_PXP_CSC2_COEF3);
+ __raw_writel(0x000005E6, pxp->base + HW_PXP_CSC2_COEF4);
+ __raw_writel(0x00000000, pxp->base + HW_PXP_CSC2_COEF5);
+ } else {
+ /*
+ * Input = RGB, Output = RGB
+ * Input & Output both RGB, so bypass both CSCs
+ */
+
+ /* CSC1 - Bypass */
+ __raw_writel(0x40000000, pxp->base + HW_PXP_CSC1_COEF0);
+
+ /* CSC2 - Bypass */
+ __raw_writel(0x1, pxp->base + HW_PXP_CSC2_CTRL);
+ }
+
+ /* YCrCb colorspace */
+ /* Not sure when we use this...no YCrCb formats are defined for PxP */
+ /*
+ __raw_writel(0x84ab01f0, HW_PXP_CSCCOEFF0_ADDR);
+ __raw_writel(0x01230204, HW_PXP_CSCCOEFF1_ADDR);
+ __raw_writel(0x0730079c, HW_PXP_CSCCOEFF2_ADDR);
+ */
+
+}
+
+static void pxp_set_s0buf(struct pxps *pxp)
+{
+ struct pxp_config_data *pxp_conf = &pxp->pxp_conf_state;
+ struct pxp_layer_param *s0_params = &pxp_conf->s0_param;
+ struct pxp_proc_data *proc_data = &pxp_conf->proc_data;
+ dma_addr_t Y, U, V;
+ dma_addr_t Y1, U1, V1;
+ u32 offset, bpp = 1;
+ u32 pitch = s0_params->stride ? s0_params->stride :
+ s0_params->width;
+
+ Y = s0_params->paddr;
+
+ if ((s0_params->pixel_fmt == PXP_PIX_FMT_RGB565) ||
+ (s0_params->pixel_fmt == PXP_PIX_FMT_RGB555))
+ bpp = 2;
+ else if (s0_params->pixel_fmt == PXP_PIX_FMT_XRGB32)
+ bpp = 4;
+ offset = (proc_data->srect.top * s0_params->width +
+ proc_data->srect.left) * bpp;
+ /* clipping or cropping */
+ Y1 = Y + offset;
+ __raw_writel(Y1, pxp->base + HW_PXP_PS_BUF);
+ if ((s0_params->pixel_fmt == PXP_PIX_FMT_YUV420P) ||
+ (s0_params->pixel_fmt == PXP_PIX_FMT_YVU420P) ||
+ (s0_params->pixel_fmt == PXP_PIX_FMT_GREY) ||
+ (s0_params->pixel_fmt == PXP_PIX_FMT_YUV422P)) {
+ /* Set to 1 if YUV format is 4:2:2 rather than 4:2:0 */
+ int s = 2;
+ if (s0_params->pixel_fmt == PXP_PIX_FMT_YUV422P)
+ s = 1;
+
+ offset = proc_data->srect.top * s0_params->width / 4 +
+ proc_data->srect.left / 2;
+ U = Y + (s0_params->width * s0_params->height);
+ U1 = U + offset;
+ V = U + ((s0_params->width * s0_params->height) >> s);
+ V1 = V + offset;
+ if (s0_params->pixel_fmt == PXP_PIX_FMT_YVU420P) {
+ __raw_writel(V1, pxp->base + HW_PXP_PS_UBUF);
+ __raw_writel(U1, pxp->base + HW_PXP_PS_VBUF);
+ } else {
+ __raw_writel(U1, pxp->base + HW_PXP_PS_UBUF);
+ __raw_writel(V1, pxp->base + HW_PXP_PS_VBUF);
+ }
+ } else if ((s0_params->pixel_fmt == PXP_PIX_FMT_NV12) ||
+ (s0_params->pixel_fmt == PXP_PIX_FMT_NV21) ||
+ (s0_params->pixel_fmt == PXP_PIX_FMT_NV16) ||
+ (s0_params->pixel_fmt == PXP_PIX_FMT_NV61)) {
+ int s = 2;
+ if ((s0_params->pixel_fmt == PXP_PIX_FMT_NV16) ||
+ (s0_params->pixel_fmt == PXP_PIX_FMT_NV61))
+ s = 1;
+
+ offset = (proc_data->srect.top * s0_params->width +
+ proc_data->srect.left) / s;
+ U = Y + (s0_params->width * s0_params->height);
+ U1 = U + offset;
+
+ __raw_writel(U1, pxp->base + HW_PXP_PS_UBUF);
+ }
+
+ /* TODO: only support RGB565, Y8, Y4, YUV420 */
+ if (s0_params->pixel_fmt == PXP_PIX_FMT_GREY ||
+ s0_params->pixel_fmt == PXP_PIX_FMT_YUV420P ||
+ s0_params->pixel_fmt == PXP_PIX_FMT_YVU420P ||
+ s0_params->pixel_fmt == PXP_PIX_FMT_NV12 ||
+ s0_params->pixel_fmt == PXP_PIX_FMT_NV21 ||
+ s0_params->pixel_fmt == PXP_PIX_FMT_NV16 ||
+ s0_params->pixel_fmt == PXP_PIX_FMT_NV61 ||
+ s0_params->pixel_fmt == PXP_PIX_FMT_YUV422P) {
+ __raw_writel(pitch, pxp->base + HW_PXP_PS_PITCH);
+ }
+ else if (s0_params->pixel_fmt == PXP_PIX_FMT_GY04)
+ __raw_writel(pitch >> 1,
+ pxp->base + HW_PXP_PS_PITCH);
+ else if (s0_params->pixel_fmt == PXP_PIX_FMT_XRGB32 ||
+ s0_params->pixel_fmt == PXP_PIX_FMT_VUY444)
+ __raw_writel(pitch << 2,
+ pxp->base + HW_PXP_PS_PITCH);
+ else if (s0_params->pixel_fmt == PXP_PIX_FMT_UYVY ||
+ s0_params->pixel_fmt == PXP_PIX_FMT_YUYV ||
+ s0_params->pixel_fmt == PXP_PIX_FMT_VYUY ||
+ s0_params->pixel_fmt == PXP_PIX_FMT_YVYU)
+ __raw_writel(pitch << 1,
+ pxp->base + HW_PXP_PS_PITCH);
+ else if ((s0_params->pixel_fmt == PXP_PIX_FMT_RGB565) ||
+ (s0_params->pixel_fmt == PXP_PIX_FMT_RGB555))
+ __raw_writel(pitch << 1,
+ pxp->base + HW_PXP_PS_PITCH);
+ else
+ __raw_writel(0, pxp->base + HW_PXP_PS_PITCH);
+}
+
+/**
+ * pxp_config() - configure PxP for a processing task
+ * @pxps: PXP context.
+ * @pxp_chan: PXP channel.
+ * @return: 0 on success or negative error code on failure.
+ */
+static int pxp_config(struct pxps *pxp, struct pxp_channel *pxp_chan)
+{
+ /* Configure PxP regs */
+ pxp_set_ctrl(pxp);
+ pxp_set_s0param(pxp);
+ pxp_set_s0crop(pxp);
+ pxp_set_scaling(pxp);
+ pxp_set_s0colorkey(pxp);
+
+ pxp_set_oln(0, pxp);
+ pxp_set_olparam(0, pxp);
+ pxp_set_olcolorkey(0, pxp);
+
+ pxp_set_csc(pxp);
+ pxp_set_bg(pxp);
+ pxp_set_lut(pxp);
+
+ pxp_set_s0buf(pxp);
+ pxp_set_outbuf(pxp);
+
+ return 0;
+}
+
+static void pxp_clk_enable(struct pxps *pxp)
+{
+ mutex_lock(&pxp->clk_mutex);
+
+ if (pxp->clk_stat == CLK_STAT_ON) {
+ mutex_unlock(&pxp->clk_mutex);
+ return;
+ }
+
+ pm_runtime_get_sync(pxp->dev);
+
+ if (pxp->clk_disp_axi)
+ clk_prepare_enable(pxp->clk_disp_axi);
+ clk_prepare_enable(pxp->clk);
+ pxp->clk_stat = CLK_STAT_ON;
+
+ mutex_unlock(&pxp->clk_mutex);
+}
+
+static void pxp_clk_disable(struct pxps *pxp)
+{
+ unsigned long flags;
+
+ mutex_lock(&pxp->clk_mutex);
+
+ if (pxp->clk_stat == CLK_STAT_OFF) {
+ mutex_unlock(&pxp->clk_mutex);
+ return;
+ }
+
+ spin_lock_irqsave(&pxp->lock, flags);
+ if ((pxp->pxp_ongoing == 0) && list_empty(&head)) {
+ spin_unlock_irqrestore(&pxp->lock, flags);
+ clk_disable_unprepare(pxp->clk);
+ if (pxp->clk_disp_axi)
+ clk_disable_unprepare(pxp->clk_disp_axi);
+ pxp->clk_stat = CLK_STAT_OFF;
+ pm_runtime_put_sync_suspend(pxp->dev);
+ } else
+ spin_unlock_irqrestore(&pxp->lock, flags);
+
+ mutex_unlock(&pxp->clk_mutex);
+}
+
+static inline void clkoff_callback(struct work_struct *w)
+{
+ struct pxps *pxp = container_of(w, struct pxps, work);
+
+ pxp_clk_disable(pxp);
+}
+
+static void pxp_clkoff_timer(unsigned long arg)
+{
+ struct pxps *pxp = (struct pxps *)arg;
+
+ if ((pxp->pxp_ongoing == 0) && list_empty(&head))
+ schedule_work(&pxp->work);
+ else
+ mod_timer(&pxp->clk_timer,
+ jiffies + msecs_to_jiffies(timeout_in_ms));
+}
+
+static struct pxp_tx_desc *pxpdma_first_queued(struct pxp_channel *pxp_chan)
+{
+ return list_entry(pxp_chan->queue.next, struct pxp_tx_desc, list);
+}
+
+/* called with pxp_chan->lock held */
+static void __pxpdma_dostart(struct pxp_channel *pxp_chan)
+{
+ struct pxp_dma *pxp_dma = to_pxp_dma(pxp_chan->dma_chan.device);
+ struct pxps *pxp = to_pxp(pxp_dma);
+ struct pxp_tx_desc *desc;
+ struct pxp_tx_desc *child;
+ int i = 0;
+
+ memset(&pxp->pxp_conf_state.s0_param, 0, sizeof(struct pxp_layer_param));
+ memset(&pxp->pxp_conf_state.out_param, 0, sizeof(struct pxp_layer_param));
+ memset(pxp->pxp_conf_state.ol_param, 0, sizeof(struct pxp_layer_param) * 8);
+ memset(&pxp->pxp_conf_state.proc_data, 0, sizeof(struct pxp_proc_data));
+ /* S0 */
+ desc = list_first_entry(&head, struct pxp_tx_desc, list);
+ memcpy(&pxp->pxp_conf_state.s0_param,
+ &desc->layer_param.s0_param, sizeof(struct pxp_layer_param));
+ memcpy(&pxp->pxp_conf_state.proc_data,
+ &desc->proc_data, sizeof(struct pxp_proc_data));
+
+ /* Save PxP configuration */
+ list_for_each_entry(child, &desc->tx_list, list) {
+ if (i == 0) { /* Output */
+ memcpy(&pxp->pxp_conf_state.out_param,
+ &child->layer_param.out_param,
+ sizeof(struct pxp_layer_param));
+ } else { /* Overlay */
+ memcpy(&pxp->pxp_conf_state.ol_param[i - 1],
+ &child->layer_param.ol_param,
+ sizeof(struct pxp_layer_param));
+ }
+
+ i++;
+ }
+ pr_debug("%s:%d S0 w/h %d/%d paddr %08x\n", __func__, __LINE__,
+ pxp->pxp_conf_state.s0_param.width,
+ pxp->pxp_conf_state.s0_param.height,
+ pxp->pxp_conf_state.s0_param.paddr);
+ pr_debug("%s:%d OUT w/h %d/%d paddr %08x\n", __func__, __LINE__,
+ pxp->pxp_conf_state.out_param.width,
+ pxp->pxp_conf_state.out_param.height,
+ pxp->pxp_conf_state.out_param.paddr);
+}
+
+static void pxpdma_dostart_work(struct pxps *pxp)
+{
+ struct pxp_channel *pxp_chan = NULL;
+ unsigned long flags;
+ struct pxp_tx_desc *desc = NULL;
+
+ spin_lock_irqsave(&pxp->lock, flags);
+
+ desc = list_entry(head.next, struct pxp_tx_desc, list);
+ pxp_chan = to_pxp_channel(desc->txd.chan);
+
+ __pxpdma_dostart(pxp_chan);
+
+ /* Configure PxP */
+ pxp_config(pxp, pxp_chan);
+
+ pxp_start(pxp);
+
+ spin_unlock_irqrestore(&pxp->lock, flags);
+}
+
+static void pxpdma_dequeue(struct pxp_channel *pxp_chan, struct pxps *pxp)
+{
+ unsigned long flags;
+ struct pxp_tx_desc *desc = NULL;
+
+ do {
+ desc = pxpdma_first_queued(pxp_chan);
+ spin_lock_irqsave(&pxp->lock, flags);
+ list_move_tail(&desc->list, &head);
+ spin_unlock_irqrestore(&pxp->lock, flags);
+ } while (!list_empty(&pxp_chan->queue));
+}
+
+static dma_cookie_t pxp_tx_submit(struct dma_async_tx_descriptor *tx)
+{
+ struct pxp_tx_desc *desc = to_tx_desc(tx);
+ struct pxp_channel *pxp_chan = to_pxp_channel(tx->chan);
+ dma_cookie_t cookie;
+
+ dev_dbg(&pxp_chan->dma_chan.dev->device, "received TX\n");
+
+ /* pxp_chan->lock can be taken under ichan->lock, but not v.v. */
+ spin_lock(&pxp_chan->lock);
+
+ cookie = pxp_chan->dma_chan.cookie;
+
+ if (++cookie < 0)
+ cookie = 1;
+
+ /* from dmaengine.h: "last cookie value returned to client" */
+ pxp_chan->dma_chan.cookie = cookie;
+ tx->cookie = cookie;
+
+ /* Here we add the tx descriptor to our PxP task queue. */
+ list_add_tail(&desc->list, &pxp_chan->queue);
+
+ spin_unlock(&pxp_chan->lock);
+
+ dev_dbg(&pxp_chan->dma_chan.dev->device, "done TX\n");
+
+ return cookie;
+}
+
+/**
+ * pxp_init_channel() - initialize a PXP channel.
+ * @pxp_dma: PXP DMA context.
+ * @pchan: pointer to the channel object.
+ * @return 0 on success or negative error code on failure.
+ */
+static int pxp_init_channel(struct pxp_dma *pxp_dma,
+ struct pxp_channel *pxp_chan)
+{
+ int ret = 0;
+
+ /*
+ * We are using _virtual_ channel here.
+ * Each channel contains all parameters of corresponding layers
+ * for one transaction; each layer is represented as one descriptor
+ * (i.e., pxp_tx_desc) here.
+ */
+
+ INIT_LIST_HEAD(&pxp_chan->queue);
+
+ return ret;
+}
+
+static irqreturn_t pxp_irq(int irq, void *dev_id)
+{
+ struct pxps *pxp = dev_id;
+ struct pxp_channel *pxp_chan;
+ struct pxp_tx_desc *desc;
+ struct pxp_tx_desc *child, *_child;
+ dma_async_tx_callback callback;
+ void *callback_param;
+ unsigned long flags;
+ u32 hist_status;
+
+ dump_pxp_reg(pxp);
+
+ hist_status =
+ __raw_readl(pxp->base + HW_PXP_HIST_CTRL) & BM_PXP_HIST_CTRL_STATUS;
+
+ __raw_writel(BM_PXP_STAT_IRQ, pxp->base + HW_PXP_STAT_CLR);
+
+ /* set the SFTRST bit to be 1 to reset
+ * the PXP block to its default state.
+ */
+ pxp_soft_reset(pxp);
+
+ spin_lock_irqsave(&pxp->lock, flags);
+
+ if (list_empty(&head)) {
+ pxp->pxp_ongoing = 0;
+ spin_unlock_irqrestore(&pxp->lock, flags);
+ return IRQ_NONE;
+ }
+
+ /* Get descriptor and call callback */
+ desc = list_entry(head.next, struct pxp_tx_desc, list);
+ pxp_chan = to_pxp_channel(desc->txd.chan);
+
+ pxp_chan->completed = desc->txd.cookie;
+
+ callback = desc->txd.callback;
+ callback_param = desc->txd.callback_param;
+
+ /* Send histogram status back to caller */
+ desc->hist_status = hist_status;
+
+ if ((desc->txd.flags & DMA_PREP_INTERRUPT) && callback)
+ callback(callback_param);
+
+ pxp_chan->status = PXP_CHANNEL_INITIALIZED;
+
+ list_for_each_entry_safe(child, _child, &desc->tx_list, list) {
+ list_del_init(&child->list);
+ kmem_cache_free(tx_desc_cache, (void *)child);
+ }
+ list_del_init(&desc->list);
+ kmem_cache_free(tx_desc_cache, (void *)desc);
+
+ complete(&pxp->complete);
+ pxp->pxp_ongoing = 0;
+ mod_timer(&pxp->clk_timer, jiffies + msecs_to_jiffies(timeout_in_ms));
+
+ spin_unlock_irqrestore(&pxp->lock, flags);
+
+ return IRQ_HANDLED;
+}
+
+/* allocate/free dma tx descriptor dynamically*/
+static struct pxp_tx_desc *pxpdma_desc_alloc(struct pxp_channel *pxp_chan)
+{
+ struct pxp_tx_desc *desc = NULL;
+ struct dma_async_tx_descriptor *txd = NULL;
+
+ desc = kmem_cache_alloc(tx_desc_cache, GFP_KERNEL | __GFP_ZERO);
+ if (desc == NULL)
+ return NULL;
+
+ INIT_LIST_HEAD(&desc->list);
+ INIT_LIST_HEAD(&desc->tx_list);
+ txd = &desc->txd;
+ dma_async_tx_descriptor_init(txd, &pxp_chan->dma_chan);
+ txd->tx_submit = pxp_tx_submit;
+
+ return desc;
+}
+
+/* Allocate and initialise a transfer descriptor. */
+static struct dma_async_tx_descriptor *pxp_prep_slave_sg(struct dma_chan *chan,
+ struct scatterlist
+ *sgl,
+ unsigned int sg_len,
+ enum
+ dma_transfer_direction
+ direction,
+ unsigned long tx_flags,
+ void *context)
+{
+ struct pxp_channel *pxp_chan = to_pxp_channel(chan);
+ struct pxp_dma *pxp_dma = to_pxp_dma(chan->device);
+ struct pxps *pxp = to_pxp(pxp_dma);
+ struct pxp_tx_desc *pos = NULL, *next = NULL;
+ struct pxp_tx_desc *desc = NULL;
+ struct pxp_tx_desc *first = NULL, *prev = NULL;
+ struct scatterlist *sg;
+ dma_addr_t phys_addr;
+ int i;
+
+ if (direction != DMA_DEV_TO_MEM && direction != DMA_MEM_TO_DEV) {
+ dev_err(chan->device->dev, "Invalid DMA direction %d!\n",
+ direction);
+ return NULL;
+ }
+
+ if (unlikely(sg_len < 2))
+ return NULL;
+
+ for_each_sg(sgl, sg, sg_len, i) {
+ desc = pxpdma_desc_alloc(pxp_chan);
+ if (!desc) {
+ dev_err(chan->device->dev, "no enough memory to allocate tx descriptor\n");
+
+ if (first) {
+ list_for_each_entry_safe(pos, next, &first->tx_list, list) {
+ list_del_init(&pos->list);
+ kmem_cache_free(tx_desc_cache, (void*)pos);
+ }
+ list_del_init(&first->list);
+ kmem_cache_free(tx_desc_cache, (void*)first);
+ }
+
+ return NULL;
+ }
+
+ phys_addr = sg_dma_address(sg);
+
+ if (!first) {
+ first = desc;
+
+ desc->layer_param.s0_param.paddr = phys_addr;
+ } else {
+ list_add_tail(&desc->list, &first->tx_list);
+ prev->next = desc;
+ desc->next = NULL;
+
+ if (i == 1)
+ desc->layer_param.out_param.paddr = phys_addr;
+ else
+ desc->layer_param.ol_param.paddr = phys_addr;
+ }
+
+ prev = desc;
+ }
+
+ pxp->pxp_conf_state.layer_nr = sg_len;
+ first->txd.flags = tx_flags;
+ first->len = sg_len;
+ pr_debug("%s:%d first %p, first->len %d, flags %08x\n",
+ __func__, __LINE__, first, first->len, first->txd.flags);
+
+ return &first->txd;
+}
+
+static void pxp_issue_pending(struct dma_chan *chan)
+{
+ struct pxp_channel *pxp_chan = to_pxp_channel(chan);
+ struct pxp_dma *pxp_dma = to_pxp_dma(chan->device);
+ struct pxps *pxp = to_pxp(pxp_dma);
+
+ spin_lock(&pxp_chan->lock);
+
+ if (list_empty(&pxp_chan->queue)) {
+ spin_unlock(&pxp_chan->lock);
+ return;
+ }
+
+ pxpdma_dequeue(pxp_chan, pxp);
+ pxp_chan->status = PXP_CHANNEL_READY;
+
+ spin_unlock(&pxp_chan->lock);
+
+ pxp_clk_enable(pxp);
+ wake_up_interruptible(&pxp->thread_waitq);
+}
+
+static void __pxp_terminate_all(struct dma_chan *chan)
+{
+ struct pxp_channel *pxp_chan = to_pxp_channel(chan);
+
+ pxp_chan->status = PXP_CHANNEL_INITIALIZED;
+}
+
+static int pxp_device_terminate_all(struct dma_chan *chan)
+{
+ struct pxp_channel *pxp_chan = to_pxp_channel(chan);
+
+ spin_lock(&pxp_chan->lock);
+ __pxp_terminate_all(chan);
+ spin_unlock(&pxp_chan->lock);
+
+ return 0;
+}
+
+static int pxp_alloc_chan_resources(struct dma_chan *chan)
+{
+ struct pxp_channel *pxp_chan = to_pxp_channel(chan);
+ struct pxp_dma *pxp_dma = to_pxp_dma(chan->device);
+ int ret;
+
+ /* dmaengine.c now guarantees to only offer free channels */
+ BUG_ON(chan->client_count > 1);
+ WARN_ON(pxp_chan->status != PXP_CHANNEL_FREE);
+
+ chan->cookie = 1;
+ pxp_chan->completed = -ENXIO;
+
+ pr_debug("%s dma_chan.chan_id %d\n", __func__, chan->chan_id);
+ ret = pxp_init_channel(pxp_dma, pxp_chan);
+ if (ret < 0)
+ goto err_chan;
+
+ pxp_chan->status = PXP_CHANNEL_INITIALIZED;
+
+ dev_dbg(&chan->dev->device, "Found channel 0x%x, irq %d\n",
+ chan->chan_id, pxp_chan->eof_irq);
+
+ return ret;
+
+err_chan:
+ return ret;
+}
+
+static void pxp_free_chan_resources(struct dma_chan *chan)
+{
+ struct pxp_channel *pxp_chan = to_pxp_channel(chan);
+
+ spin_lock(&pxp_chan->lock);
+
+ __pxp_terminate_all(chan);
+
+ pxp_chan->status = PXP_CHANNEL_FREE;
+
+ spin_unlock(&pxp_chan->lock);
+}
+
+static enum dma_status pxp_tx_status(struct dma_chan *chan,
+ dma_cookie_t cookie,
+ struct dma_tx_state *txstate)
+{
+ struct pxp_channel *pxp_chan = to_pxp_channel(chan);
+
+ if (cookie != chan->cookie)
+ return DMA_ERROR;
+
+ if (txstate) {
+ txstate->last = pxp_chan->completed;
+ txstate->used = chan->cookie;
+ txstate->residue = 0;
+ }
+ return DMA_COMPLETE;
+}
+
+static int pxp_dma_init(struct pxps *pxp)
+{
+ struct pxp_dma *pxp_dma = &pxp->pxp_dma;
+ struct dma_device *dma = &pxp_dma->dma;
+ int i;
+
+ dma_cap_set(DMA_SLAVE, dma->cap_mask);
+ dma_cap_set(DMA_PRIVATE, dma->cap_mask);
+
+ /* Compulsory common fields */
+ dma->dev = pxp->dev;
+ dma->device_alloc_chan_resources = pxp_alloc_chan_resources;
+ dma->device_free_chan_resources = pxp_free_chan_resources;
+ dma->device_tx_status = pxp_tx_status;
+ dma->device_issue_pending = pxp_issue_pending;
+
+ /* Compulsory for DMA_SLAVE fields */
+ dma->device_prep_slave_sg = pxp_prep_slave_sg;
+ dma->device_terminate_all = pxp_device_terminate_all;
+
+ /* Initialize PxP Channels */
+ INIT_LIST_HEAD(&dma->channels);
+ for (i = 0; i < NR_PXP_VIRT_CHANNEL; i++) {
+ struct pxp_channel *pxp_chan = pxp->channel + i;
+ struct dma_chan *dma_chan = &pxp_chan->dma_chan;
+
+ spin_lock_init(&pxp_chan->lock);
+
+ /* Only one EOF IRQ for PxP, shared by all channels */
+ pxp_chan->eof_irq = pxp->irq;
+ pxp_chan->status = PXP_CHANNEL_FREE;
+ pxp_chan->completed = -ENXIO;
+ snprintf(pxp_chan->eof_name, sizeof(pxp_chan->eof_name),
+ "PXP EOF %d", i);
+
+ dma_chan->device = &pxp_dma->dma;
+ dma_chan->cookie = 1;
+ dma_chan->chan_id = i;
+ list_add_tail(&dma_chan->device_node, &dma->channels);
+ }
+
+ return dma_async_device_register(&pxp_dma->dma);
+}
+
+static ssize_t clk_off_timeout_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ return sprintf(buf, "%d\n", timeout_in_ms);
+}
+
+static ssize_t clk_off_timeout_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int val;
+ if (sscanf(buf, "%d", &val) > 0) {
+ timeout_in_ms = val;
+ return count;
+ }
+ return -EINVAL;
+}
+
+static DEVICE_ATTR(clk_off_timeout, 0644, clk_off_timeout_show,
+ clk_off_timeout_store);
+
+static ssize_t block_size_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ return sprintf(buf, "%d\n", block_size);
+}
+
+static ssize_t block_size_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ char **last = NULL;
+
+ block_size = simple_strtoul(buf, last, 0);
+ if (block_size > 1)
+ block_size = 1;
+
+ return count;
+}
+static DEVICE_ATTR(block_size, S_IWUSR | S_IRUGO,
+ block_size_show, block_size_store);
+
+static const struct of_device_id imx_pxpdma_dt_ids[] = {
+ { .compatible = "fsl,imx6dl-pxp-dma", },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, imx_pxpdma_dt_ids);
+
+static int has_pending_task(struct pxps *pxp, struct pxp_channel *task)
+{
+ int found;
+ unsigned long flags;
+
+ spin_lock_irqsave(&pxp->lock, flags);
+ found = !list_empty(&head);
+ spin_unlock_irqrestore(&pxp->lock, flags);
+
+ return found;
+}
+
+static int pxp_dispatch_thread(void *argv)
+{
+ struct pxps *pxp = (struct pxps *)argv;
+ struct pxp_channel *pending = NULL;
+ unsigned long flags;
+
+ set_freezable();
+
+ while (!kthread_should_stop()) {
+ int ret;
+ ret = wait_event_freezable(pxp->thread_waitq,
+ has_pending_task(pxp, pending) ||
+ kthread_should_stop());
+ if (ret < 0)
+ continue;
+
+ if (kthread_should_stop())
+ break;
+
+ spin_lock_irqsave(&pxp->lock, flags);
+ pxp->pxp_ongoing = 1;
+ spin_unlock_irqrestore(&pxp->lock, flags);
+ init_completion(&pxp->complete);
+ pxpdma_dostart_work(pxp);
+ ret = wait_for_completion_timeout(&pxp->complete, 2 * HZ);
+ if (ret == 0) {
+ printk(KERN_EMERG "%s: task is timeout\n\n", __func__);
+ break;
+ }
+ }
+
+ return 0;
+}
+
+static int pxp_probe(struct platform_device *pdev)
+{
+ struct pxps *pxp;
+ struct resource *res;
+ int irq;
+ int err = 0;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ irq = platform_get_irq(pdev, 0);
+ if (!res || irq < 0) {
+ err = -ENODEV;
+ goto exit;
+ }
+
+ pxp = devm_kzalloc(&pdev->dev, sizeof(*pxp), GFP_KERNEL);
+ if (!pxp) {
+ dev_err(&pdev->dev, "failed to allocate control object\n");
+ err = -ENOMEM;
+ goto exit;
+ }
+
+ pxp->dev = &pdev->dev;
+
+ platform_set_drvdata(pdev, pxp);
+ pxp->irq = irq;
+
+ spin_lock_init(&pxp->lock);
+ mutex_init(&pxp->clk_mutex);
+
+ pxp->base = devm_ioremap_resource(&pdev->dev, res);
+ if (pxp->base == NULL) {
+ dev_err(&pdev->dev, "Couldn't ioremap regs\n");
+ err = -ENODEV;
+ goto exit;
+ }
+
+ pxp->pdev = pdev;
+
+ pxp->clk_disp_axi = devm_clk_get(&pdev->dev, "disp-axi");
+ if (IS_ERR(pxp->clk_disp_axi))
+ pxp->clk_disp_axi = NULL;
+ pxp->clk = devm_clk_get(&pdev->dev, "pxp-axi");
+
+ err = devm_request_irq(&pdev->dev, pxp->irq, pxp_irq, 0,
+ "pxp-dmaengine", pxp);
+ if (err)
+ goto exit;
+ /* Initialize DMA engine */
+ err = pxp_dma_init(pxp);
+ if (err < 0)
+ goto exit;
+
+ if (device_create_file(&pdev->dev, &dev_attr_clk_off_timeout)) {
+ dev_err(&pdev->dev,
+ "Unable to create file from clk_off_timeout\n");
+ goto exit;
+ }
+
+ device_create_file(&pdev->dev, &dev_attr_block_size);
+ pxp_clk_enable(pxp);
+ dump_pxp_reg(pxp);
+ pxp_clk_disable(pxp);
+
+ INIT_WORK(&pxp->work, clkoff_callback);
+ init_timer(&pxp->clk_timer);
+ pxp->clk_timer.function = pxp_clkoff_timer;
+ pxp->clk_timer.data = (unsigned long)pxp;
+
+ init_waitqueue_head(&pxp->thread_waitq);
+ /* allocate a kernel thread to dispatch pxp conf */
+ pxp->dispatch = kthread_run(pxp_dispatch_thread, pxp, "pxp_dispatch");
+ if (IS_ERR(pxp->dispatch)) {
+ err = PTR_ERR(pxp->dispatch);
+ goto exit;
+ }
+ tx_desc_cache = kmem_cache_create("tx_desc", sizeof(struct pxp_tx_desc),
+ 0, SLAB_HWCACHE_ALIGN, NULL);
+ if (!tx_desc_cache) {
+ err = -ENOMEM;
+ goto exit;
+ }
+
+ register_pxp_device();
+
+ pm_runtime_enable(pxp->dev);
+
+exit:
+ if (err)
+ dev_err(&pdev->dev, "Exiting (unsuccessfully) pxp_probe()\n");
+ return err;
+}
+
+static int pxp_remove(struct platform_device *pdev)
+{
+ struct pxps *pxp = platform_get_drvdata(pdev);
+
+ unregister_pxp_device();
+ kmem_cache_destroy(tx_desc_cache);
+ kthread_stop(pxp->dispatch);
+ cancel_work_sync(&pxp->work);
+ del_timer_sync(&pxp->clk_timer);
+ clk_disable_unprepare(pxp->clk);
+ if (pxp->clk_disp_axi)
+ clk_disable_unprepare(pxp->clk_disp_axi);
+ device_remove_file(&pdev->dev, &dev_attr_clk_off_timeout);
+ device_remove_file(&pdev->dev, &dev_attr_block_size);
+ dma_async_device_unregister(&(pxp->pxp_dma.dma));
+
+ return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int pxp_suspend(struct device *dev)
+{
+ struct pxps *pxp = dev_get_drvdata(dev);
+
+ pxp_clk_enable(pxp);
+ while (__raw_readl(pxp->base + HW_PXP_CTRL) & BM_PXP_CTRL_ENABLE)
+ ;
+
+ __raw_writel(BM_PXP_CTRL_SFTRST, pxp->base + HW_PXP_CTRL);
+ pxp_clk_disable(pxp);
+
+ return 0;
+}
+
+static int pxp_resume(struct device *dev)
+{
+ struct pxps *pxp = dev_get_drvdata(dev);
+
+ pxp_clk_enable(pxp);
+ /* Pull PxP out of reset */
+ __raw_writel(0, pxp->base + HW_PXP_CTRL);
+ pxp_clk_disable(pxp);
+
+ return 0;
+}
+#else
+#define pxp_suspend NULL
+#define pxp_resume NULL
+#endif
+
+#ifdef CONFIG_PM
+static int pxp_runtime_suspend(struct device *dev)
+{
+ dev_dbg(dev, "pxp busfreq high release.\n");
+ return 0;
+}
+
+static int pxp_runtime_resume(struct device *dev)
+{
+ dev_dbg(dev, "pxp busfreq high request.\n");
+ return 0;
+}
+#else
+#define pxp_runtime_suspend NULL
+#define pxp_runtime_resume NULL
+#endif
+
+static const struct dev_pm_ops pxp_pm_ops = {
+ SET_RUNTIME_PM_OPS(pxp_runtime_suspend, pxp_runtime_resume, NULL)
+ SET_SYSTEM_SLEEP_PM_OPS(pxp_suspend, pxp_resume)
+};
+
+static struct platform_driver pxp_driver = {
+ .driver = {
+ .name = "imx-pxp",
+ .of_match_table = of_match_ptr(imx_pxpdma_dt_ids),
+ .pm = &pxp_pm_ops,
+ },
+ .probe = pxp_probe,
+ .remove = pxp_remove,
+};
+
+module_platform_driver(pxp_driver);
+
+
+MODULE_DESCRIPTION("i.MX PxP driver");
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_LICENSE("GPL");
diff --git a/drivers/dma/pxp/pxp_dma_v3.c b/drivers/dma/pxp/pxp_dma_v3.c
new file mode 100644
index 000000000000..2704916df0f6
--- /dev/null
+++ b/drivers/dma/pxp/pxp_dma_v3.c
@@ -0,0 +1,8138 @@
+/*
+ * Copyright (C) 2010-2016 Freescale Semiconductor, Inc.
+ *
+ * Copyright 2017-2018 NXP
+ *
+ * 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
+ *
+ */
+/*
+ * Based on STMP378X PxP driver
+ * Copyright 2008-2009 Embedded Alley Solutions, Inc All Rights Reserved.
+ */
+
+#include <linux/dma-mapping.h>
+#include <linux/freezer.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/kthread.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/of_gpio.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
+#include <linux/dmaengine.h>
+#include <linux/pxp_dma.h>
+#include <linux/timer.h>
+#include <linux/clk.h>
+#include <linux/workqueue.h>
+#include <linux/sched.h>
+#include <linux/of.h>
+
+#include "regs-pxp_v3.h"
+#include "reg_bitfields.h"
+
+#ifdef CONFIG_MXC_FPGA_M4_TEST
+#include "cm4_image.c"
+#define FPGA_TCML_ADDR 0x0C7F8000
+#define PINCTRL 0x0C018000
+#define PIN_DOUT 0x700
+void __iomem *fpga_tcml_base;
+void __iomem *pinctrl_base;
+#endif
+
+
+#define PXP_FILL_TIMEOUT 3000
+#define busy_wait(cond) \
+ ({ \
+ unsigned long end_jiffies = jiffies + \
+ msecs_to_jiffies(PXP_FILL_TIMEOUT); \
+ bool succeeded = false; \
+ do { \
+ if (cond) { \
+ succeeded = true; \
+ break; \
+ } \
+ cpu_relax(); \
+ } while (time_after(end_jiffies, jiffies)); \
+ succeeded; \
+ })
+
+#define PXP_DOWNSCALE_THRESHOLD 0x4000
+
+#define CONFIG_FB_MXC_EINK_FPGA
+
+/* define all the pxp 2d nodes */
+#define PXP_2D_PS 0
+#define PXP_2D_AS 1
+#define PXP_2D_INPUT_FETCH0 2
+#define PXP_2D_INPUT_FETCH1 3
+#define PXP_2D_CSC1 4
+#define PXP_2D_ROTATION1 5
+#define PXP_2D_ALPHA0_S0 6
+#define PXP_2D_ALPHA0_S1 7
+#define PXP_2D_ALPHA1_S0 8
+#define PXP_2D_ALPHA1_S1 9
+#define PXP_2D_CSC2 10
+#define PXP_2D_LUT 11
+#define PXP_2D_ROTATION0 12
+#define PXP_2D_OUT 13
+#define PXP_2D_INPUT_STORE0 14
+#define PXP_2D_INPUT_STORE1 15
+#define PXP_2D_NUM 16
+
+#define PXP_2D_ALPHA0_S0_S1 0xaa
+#define PXP_2D_ALPHA1_S0_S1 0xbb
+
+#define PXP_2D_MUX_BASE 50
+#define PXP_2D_MUX_MUX0 (PXP_2D_MUX_BASE + 0)
+#define PXP_2D_MUX_MUX1 (PXP_2D_MUX_BASE + 1)
+#define PXP_2D_MUX_MUX2 (PXP_2D_MUX_BASE + 2)
+#define PXP_2D_MUX_MUX3 (PXP_2D_MUX_BASE + 3)
+#define PXP_2D_MUX_MUX4 (PXP_2D_MUX_BASE + 4)
+#define PXP_2D_MUX_MUX5 (PXP_2D_MUX_BASE + 5)
+#define PXP_2D_MUX_MUX6 (PXP_2D_MUX_BASE + 6)
+#define PXP_2D_MUX_MUX7 (PXP_2D_MUX_BASE + 7)
+#define PXP_2D_MUX_MUX8 (PXP_2D_MUX_BASE + 8)
+#define PXP_2D_MUX_MUX9 (PXP_2D_MUX_BASE + 9)
+#define PXP_2D_MUX_MUX10 (PXP_2D_MUX_BASE + 10)
+#define PXP_2D_MUX_MUX11 (PXP_2D_MUX_BASE + 11)
+#define PXP_2D_MUX_MUX12 (PXP_2D_MUX_BASE + 12)
+#define PXP_2D_MUX_MUX13 (PXP_2D_MUX_BASE + 13)
+#define PXP_2D_MUX_MUX14 (PXP_2D_MUX_BASE + 14)
+#define PXP_2D_MUX_MUX15 (PXP_2D_MUX_BASE + 15)
+
+/* define pxp 2d node types */
+#define PXP_2D_TYPE_INPUT 1
+#define PXP_2D_TYPE_ALU 2
+#define PXP_2D_TYPE_OUTPUT 3
+
+#define DISTANCE_INFINITY 0xffff
+#define NO_PATH_NODE 0xffffffff
+
+#define PXP_MAX_INPUT_NUM 2
+#define PXP_MAX_OUTPUT_NUM 2
+
+#define FETCH_NOOP 0x01
+#define FETCH_EXPAND 0x02
+#define FETCH_SHIFT 0x04
+
+#define STORE_NOOP 0x01
+#define STORE_SHIFT 0x02
+#define STORE_SHRINK 0x04
+
+#define NEED_YUV_SWAP 0x02
+
+#define IN_NEED_COMPOSITE (0x01 | IN_NEED_FMT_UNIFIED)
+#define IN_NEED_CSC (0x02 | IN_NEED_FMT_UNIFIED)
+#define IN_NEED_SCALE (0x04 | IN_NEED_FMT_UNIFIED)
+#define IN_NEED_ROTATE_FLIP (0x08 | IN_NEED_FMT_UNIFIED)
+#define IN_NEED_FMT_UNIFIED 0x10
+#define IN_NEED_SHIFT 0x20
+#define IN_NEED_LUT (0x40 | IN_NEED_UNIFIED)
+
+#define OUT_NEED_SHRINK 0x100
+#define OUT_NEED_SHIFT 0x200
+
+#define PXP_ROTATE_0 0
+#define PXP_ROTATE_90 1
+#define PXP_ROTATE_180 2
+#define PXP_ROTATE_270 3
+
+#define PXP_H_FLIP 1
+#define PXP_V_FLIP 2
+
+#define PXP_OP_TYPE_2D 0x001
+#define PXP_OP_TYPE_DITHER 0x002
+#define PXP_OP_TYPE_WFE_A 0x004
+#define PXP_OP_TYPE_WFE_B 0x008
+
+/* define store engine output mode */
+#define STORE_MODE_NORMAL 1
+#define STORE_MODE_BYPASS 2
+#define STORE_MODE_DUAL 3
+#define STORE_MODE_HANDSHAKE 4
+
+/* define fetch engine input mode */
+#define FETCH_MODE_NORMAL 1
+#define FETCH_MODE_BYPASS 2
+#define FETCH_MODE_HANDSHAKE 3
+
+#define COMMON_FMT_BPP 32
+
+#define R_COMP 0
+#define G_COMP 1
+#define B_COMP 2
+#define A_COMP 3
+
+#define Y_COMP 0
+#define U_COMP 1
+#define V_COMP 2
+#define Y1_COMP 4
+
+static LIST_HEAD(head);
+static int timeout_in_ms = 600;
+static unsigned int block_size;
+static struct kmem_cache *tx_desc_cache;
+static struct kmem_cache *edge_node_cache;
+static struct pxp_collision_info col_info;
+static dma_addr_t paddr;
+static bool v3p_flag;
+static int alpha_blending_version;
+static bool pxp_legacy;
+
+struct pxp_dma {
+ struct dma_device dma;
+};
+
+enum pxp_alpha_blending_version {
+ PXP_ALPHA_BLENDING_NONE = 0x0,
+ PXP_ALPHA_BLENDING_V1 = 0x1,
+ PXP_ALPHA_BLENDING_V2 = 0x2,
+};
+
+struct pxp_alpha_global {
+ unsigned int color_key_enable;
+ bool combine_enable;
+ bool global_alpha_enable;
+ bool global_override;
+ bool alpha_invert;
+ bool local_alpha_enable;
+ unsigned char global_alpha;
+ int comp_mask;
+};
+
+struct rectangle {
+ uint16_t x;
+ uint16_t y;
+ uint16_t width;
+ uint16_t height;
+};
+
+struct pxp_alpha_info {
+ uint8_t alpha_mode;
+ uint8_t rop_type;
+
+ struct pxp_alpha s0_alpha;
+ struct pxp_alpha s1_alpha;
+};
+
+struct pxp_op_info{
+ uint16_t op_type;
+ uint16_t rotation;
+ uint8_t flip;
+ uint8_t fill_en;
+ uint32_t fill_data;
+ uint8_t alpha_blending;
+ struct pxp_alpha_info alpha_info;
+
+ /* Dithering specific data */
+ uint32_t dither_mode;
+ uint32_t quant_bit;
+
+ /*
+ * partial:
+ * 0 - full update
+ * 1 - partial update
+ * alpha_en:
+ * 0 - upd is {Y4[3:0],4'b0000} format
+ * 1 - upd is {Y4[3:0],3'b000,alpha} format
+ * reagl_en:
+ * 0 - use normal waveform algorithm
+ * 1 - enable reagl/-d waveform algorithm
+ * detection_only:
+ * 0 - write working buffer
+ * 1 - do no write working buffer, detection only
+ * lut:
+ * valid value 0-63
+ * set to the lut used for next update
+ */
+ bool partial_update;
+ bool alpha_en;
+ bool lut_update;
+ bool reagl_en; /* enable reagl/-d */
+ bool reagl_d_en; /* enable reagl or reagl-d */
+ bool detection_only;
+ int lut;
+ uint32_t lut_status_1;
+ uint32_t lut_status_2;
+};
+
+struct pxp_pixmap {
+ uint8_t channel_id;
+ uint8_t bpp;
+ int32_t pitch;
+ uint16_t width;
+ uint16_t height;
+ struct rectangle crop;
+ uint32_t rotate;
+ uint8_t flip;
+ uint32_t format; /* fourcc pixmap format */
+ uint32_t flags;
+ bool valid;
+ dma_addr_t paddr;
+ struct pxp_alpha_global g_alpha;
+};
+
+struct pxp_task_info {
+ uint8_t input_num;
+ uint8_t output_num;
+ struct pxp_pixmap input[PXP_MAX_INPUT_NUM];
+ struct pxp_pixmap output[PXP_MAX_OUTPUT_NUM];
+ struct pxp_op_info op_info;
+ uint32_t pxp_2d_flags;
+};
+
+struct pxps {
+ struct platform_device *pdev;
+ struct clk *ipg_clk;
+ struct clk *axi_clk;
+ void __iomem *base;
+ int irq; /* PXP IRQ to the CPU */
+
+ spinlock_t lock;
+ struct mutex clk_mutex;
+ int clk_stat;
+#define CLK_STAT_OFF 0
+#define CLK_STAT_ON 1
+ int pxp_ongoing;
+ int lut_state;
+
+ struct device *dev;
+ struct pxp_dma pxp_dma;
+ struct pxp_channel channel[NR_PXP_VIRT_CHANNEL];
+ struct work_struct work;
+
+ const struct pxp_devdata *devdata;
+ struct pxp_task_info task;
+
+ /* describes most recent processing configuration */
+ struct pxp_config_data pxp_conf_state;
+
+ /* to turn clock off when pxp is inactive */
+ struct timer_list clk_timer;
+
+ /* for pxp config dispatch asynchronously*/
+ struct task_struct *dispatch;
+ wait_queue_head_t thread_waitq;
+ struct completion complete;
+};
+
+#define to_pxp_dma(d) container_of(d, struct pxp_dma, dma)
+#define to_tx_desc(tx) container_of(tx, struct pxp_tx_desc, txd)
+#define to_pxp_channel(d) container_of(d, struct pxp_channel, dma_chan)
+#define to_pxp(id) container_of(id, struct pxps, pxp_dma)
+
+#define to_pxp_task_info(op) container_of((op), struct pxp_task_info, op_info)
+#define to_pxp_from_task(task) container_of((task), struct pxps, task)
+
+#define PXP_DEF_BUFS 2
+#define PXP_MIN_PIX 8
+
+static uint8_t active_bpp(uint8_t bpp)
+{
+ switch(bpp) {
+ case 8:
+ return 0x0;
+ case 16:
+ return 0x1;
+ case 32:
+ return 0x2;
+ case 64:
+ return 0x3;
+ default:
+ return 0xff;
+ }
+}
+
+static uint8_t rotate_map(uint32_t degree)
+{
+ switch (degree) {
+ case 0:
+ return PXP_ROTATE_0;
+ case 90:
+ return PXP_ROTATE_90;
+ case 180:
+ return PXP_ROTATE_180;
+ case 270:
+ return PXP_ROTATE_270;
+ default:
+ return 0;
+ }
+}
+
+static uint8_t expand_format(uint32_t format)
+{
+ switch (format) {
+ case PXP_PIX_FMT_RGB565:
+ case PXP_PIX_FMT_BGR565:
+ return 0x0;
+ case PXP_PIX_FMT_RGB555:
+ return 0x1;
+ case PXP_PIX_FMT_YUYV:
+ case PXP_PIX_FMT_YVYU:
+ return 0x5;
+ case PXP_PIX_FMT_UYVY:
+ case PXP_PIX_FMT_VYUY:
+ return 0x6;
+ case PXP_PIX_FMT_NV16:
+ return 0x7;
+ default:
+ return 0xff;
+ }
+}
+
+struct color_component {
+ uint8_t id;
+ uint8_t offset;
+ uint8_t length;
+ uint8_t mask;
+};
+
+struct color {
+ uint32_t format;
+ struct color_component comp[4];
+};
+
+struct color rgb_colors[] = {
+ {
+ .format = PXP_PIX_FMT_RGB565,
+ .comp = {
+ { .id = B_COMP, .offset = 0, .length = 5, .mask = 0x1f, },
+ { .id = G_COMP, .offset = 5, .length = 6, .mask = 0x3f, },
+ { .id = R_COMP, .offset = 11, .length = 5, .mask = 0x1f, },
+ { .id = A_COMP, .offset = 0, .length = 0, .mask = 0x0, },
+ },
+ }, {
+ .format = PXP_PIX_FMT_BGR565,
+ .comp = {
+ { .id = R_COMP, .offset = 0, .length = 5, .mask = 0x1f, },
+ { .id = G_COMP, .offset = 5, .length = 6, .mask = 0x3f, },
+ { .id = B_COMP, .offset = 11, .length = 6, .mask = 0x3f, },
+ { .id = A_COMP, .offset = 0, .length = 0, .mask = 0x0, },
+ },
+ }, {
+ .format = PXP_PIX_FMT_ARGB555,
+ .comp = {
+ { .id = B_COMP, .offset = 0, .length = 5, .mask = 0x1f, },
+ { .id = G_COMP, .offset = 5, .length = 5, .mask = 0x1f, },
+ { .id = R_COMP, .offset = 10, .length = 5, .mask = 0x1f, },
+ { .id = A_COMP, .offset = 15, .length = 1, .mask = 0x1, },
+ },
+ }, {
+ .format = PXP_PIX_FMT_XRGB555,
+ .comp = {
+ { .id = B_COMP, .offset = 0, .length = 5, .mask = 0x1f, },
+ { .id = G_COMP, .offset = 5, .length = 5, .mask = 0x1f, },
+ { .id = R_COMP, .offset = 10, .length = 5, .mask = 0x1f, },
+ { .id = A_COMP, .offset = 15, .length = 1, .mask = 0x1, },
+ },
+ }, {
+ .format = PXP_PIX_FMT_RGB555,
+ .comp = {
+ { .id = B_COMP, .offset = 0, .length = 5, .mask = 0x1f, },
+ { .id = G_COMP, .offset = 5, .length = 5, .mask = 0x1f, },
+ { .id = R_COMP, .offset = 10, .length = 5, .mask = 0x1f, },
+ { .id = A_COMP, .offset = 15, .length = 1, .mask = 0x1, },
+ },
+ }, {
+ .format = PXP_PIX_FMT_RGBA555,
+ .comp = {
+ { .id = A_COMP, .offset = 0, .length = 1, .mask = 0x1, },
+ { .id = B_COMP, .offset = 1, .length = 5, .mask = 0x1f, },
+ { .id = G_COMP, .offset = 6, .length = 5, .mask = 0x1f, },
+ { .id = R_COMP, .offset = 11, .length = 5, .mask = 0x1f, },
+ },
+ }, {
+ .format = PXP_PIX_FMT_ARGB444,
+ .comp = {
+ { .id = B_COMP, .offset = 0, .length = 4, .mask = 0xf, },
+ { .id = G_COMP, .offset = 4, .length = 4, .mask = 0xf, },
+ { .id = R_COMP, .offset = 8, .length = 4, .mask = 0xf, },
+ { .id = A_COMP, .offset = 12, .length = 4, .mask = 0xf, },
+ },
+ }, {
+ .format = PXP_PIX_FMT_XRGB444,
+ .comp = {
+ { .id = B_COMP, .offset = 0, .length = 4, .mask = 0xf, },
+ { .id = G_COMP, .offset = 4, .length = 4, .mask = 0xf, },
+ { .id = R_COMP, .offset = 8, .length = 4, .mask = 0xf, },
+ { .id = A_COMP, .offset = 12, .length = 4, .mask = 0xf, },
+ },
+ }, {
+ .format = PXP_PIX_FMT_RGBA444,
+ .comp = {
+ { .id = A_COMP, .offset = 0, .length = 4, .mask = 0xf, },
+ { .id = B_COMP, .offset = 4, .length = 4, .mask = 0xf, },
+ { .id = G_COMP, .offset = 8, .length = 4, .mask = 0xf, },
+ { .id = R_COMP, .offset = 12, .length = 4, .mask = 0xf, },
+ },
+ }, {
+ .format = PXP_PIX_FMT_RGB24,
+ .comp = {
+ { .id = B_COMP, .offset = 0, .length = 8, .mask = 0xff, },
+ { .id = G_COMP, .offset = 8, .length = 8, .mask = 0xff, },
+ { .id = R_COMP, .offset = 16, .length = 8, .mask = 0xff, },
+ { .id = A_COMP, .offset = 0, .length = 0, .mask = 0x0, },
+ },
+ }, {
+ .format = PXP_PIX_FMT_BGR24,
+ .comp = {
+ { .id = R_COMP, .offset = 0, .length = 8, .mask = 0xff, },
+ { .id = G_COMP, .offset = 8, .length = 8, .mask = 0xff, },
+ { .id = B_COMP, .offset = 16, .length = 8, .mask = 0xff, },
+ { .id = A_COMP, .offset = 0, .length = 0, .mask = 0x0, },
+ },
+ }, {
+ .format = PXP_PIX_FMT_XRGB32,
+ .comp = {
+ { .id = B_COMP, .offset = 0, .length = 8, .mask = 0xff, },
+ { .id = G_COMP, .offset = 8, .length = 8, .mask = 0xff, },
+ { .id = R_COMP, .offset = 16, .length = 8, .mask = 0xff, },
+ { .id = A_COMP, .offset = 24, .length = 8, .mask = 0xff, },
+ },
+ }, {
+ .format = PXP_PIX_FMT_RGBX32,
+ .comp = {
+ { .id = A_COMP, .offset = 0, .length = 8, .mask = 0xff, },
+ { .id = B_COMP, .offset = 8, .length = 8, .mask = 0xff, },
+ { .id = G_COMP, .offset = 16, .length = 8, .mask = 0xff, },
+ { .id = R_COMP, .offset = 24, .length = 8, .mask = 0xff, },
+ },
+ }, {
+ .format = PXP_PIX_FMT_XBGR32,
+ .comp = {
+ { .id = R_COMP, .offset = 0, .length = 8, .mask = 0xff, },
+ { .id = G_COMP, .offset = 8, .length = 8, .mask = 0xff, },
+ { .id = B_COMP, .offset = 16, .length = 8, .mask = 0xff, },
+ { .id = A_COMP, .offset = 24, .length = 8, .mask = 0xff, },
+ },
+ }, {
+ .format = PXP_PIX_FMT_BGRX32,
+ .comp = {
+ { .id = A_COMP, .offset = 0, .length = 8, .mask = 0xff, },
+ { .id = R_COMP, .offset = 8, .length = 8, .mask = 0xff, },
+ { .id = G_COMP, .offset = 16, .length = 8, .mask = 0xff, },
+ { .id = B_COMP, .offset = 24, .length = 8, .mask = 0xff, },
+ },
+ }, {
+ .format = PXP_PIX_FMT_ARGB32,
+ .comp = {
+ { .id = B_COMP, .offset = 0, .length = 8, .mask = 0xff, },
+ { .id = G_COMP, .offset = 8, .length = 8, .mask = 0xff, },
+ { .id = R_COMP, .offset = 16, .length = 8, .mask = 0xff, },
+ { .id = A_COMP, .offset = 24, .length = 8, .mask = 0xff, },
+ },
+ }, {
+ .format = PXP_PIX_FMT_ABGR32,
+ .comp = {
+ { .id = R_COMP, .offset = 0, .length = 8, .mask = 0xff, },
+ { .id = G_COMP, .offset = 8, .length = 8, .mask = 0xff, },
+ { .id = B_COMP, .offset = 16, .length = 8, .mask = 0xff, },
+ { .id = A_COMP, .offset = 24, .length = 8, .mask = 0xff, },
+ },
+ }, {
+ .format = PXP_PIX_FMT_RGBA32,
+ .comp = {
+ { .id = A_COMP, .offset = 0, .length = 8, .mask = 0xff, },
+ { .id = B_COMP, .offset = 8, .length = 8, .mask = 0xff, },
+ { .id = G_COMP, .offset = 16, .length = 8, .mask = 0xff, },
+ { .id = R_COMP, .offset = 24, .length = 8, .mask = 0xff, },
+ },
+ }, {
+ .format = PXP_PIX_FMT_BGRA32,
+ .comp = {
+ { .id = A_COMP, .offset = 0, .length = 8, .mask = 0xff, },
+ { .id = R_COMP, .offset = 8, .length = 8, .mask = 0xff, },
+ { .id = G_COMP, .offset = 16, .length = 8, .mask = 0xff, },
+ { .id = B_COMP, .offset = 24, .length = 8, .mask = 0xff, },
+ },
+ },
+};
+
+/* only one plane yuv formats */
+struct color yuv_colors[] = {
+ {
+ .format = PXP_PIX_FMT_GREY,
+ .comp = {
+ { .id = Y_COMP, .offset = 0, .length = 8, .mask = 0xff, },
+ { .id = U_COMP, .offset = 8, .length = 0, .mask = 0x00, },
+ { .id = V_COMP, .offset = 16, .length = 0, .mask = 0x00, },
+ { .id = A_COMP, .offset = 24, .length = 0, .mask = 0x00, },
+ },
+ }, {
+ .format = PXP_PIX_FMT_YUYV,
+ .comp = {
+ { .id = V_COMP, .offset = 0, .length = 8, .mask = 0xff, },
+ { .id = Y1_COMP, .offset = 8, .length = 8, .mask = 0xff, },
+ { .id = U_COMP, .offset = 16, .length = 8, .mask = 0xff, },
+ { .id = Y_COMP, .offset = 24, .length = 8, .mask = 0xff, },
+ },
+ }, {
+ .format = PXP_PIX_FMT_UYVY,
+ .comp = {
+ { .id = Y1_COMP, .offset = 0, .length = 8, .mask = 0xff, },
+ { .id = V_COMP, .offset = 8, .length = 8, .mask = 0xff, },
+ { .id = Y_COMP, .offset = 16, .length = 8, .mask = 0xff, },
+ { .id = U_COMP, .offset = 24, .length = 8, .mask = 0xff, },
+ },
+ }, {
+ .format = PXP_PIX_FMT_YVYU,
+ .comp = {
+ { .id = U_COMP, .offset = 0, .length = 8, .mask = 0xff, },
+ { .id = Y1_COMP, .offset = 8, .length = 8, .mask = 0xff, },
+ { .id = V_COMP, .offset = 16, .length = 8, .mask = 0xff, },
+ { .id = Y_COMP, .offset = 24, .length = 8, .mask = 0xff, },
+ },
+ }, {
+ .format = PXP_PIX_FMT_VYUY,
+ .comp = {
+ { .id = Y1_COMP, .offset = 0, .length = 8, .mask = 0xff, },
+ { .id = U_COMP, .offset = 8, .length = 8, .mask = 0xff, },
+ { .id = Y_COMP, .offset = 16, .length = 8, .mask = 0xff, },
+ { .id = V_COMP, .offset = 24, .length = 8, .mask = 0xff, },
+ },
+ }, {
+ .format = PXP_PIX_FMT_YUV444,
+ .comp = {
+ { .id = V_COMP, .offset = 0, .length = 8, .mask = 0xff, },
+ { .id = U_COMP, .offset = 8, .length = 8, .mask = 0xff, },
+ { .id = Y_COMP, .offset = 16, .length = 8, .mask = 0xff, },
+ { .id = A_COMP, .offset = 24, .length = 8, .mask = 0xff, },
+ },
+ }, {
+ .format = PXP_PIX_FMT_YVU444,
+ .comp = {
+ { .id = U_COMP, .offset = 0, .length = 8, .mask = 0xff, },
+ { .id = V_COMP, .offset = 8, .length = 8, .mask = 0xff, },
+ { .id = Y_COMP, .offset = 16, .length = 8, .mask = 0xff, },
+ { .id = A_COMP, .offset = 24, .length = 8, .mask = 0xff, },
+ },
+ },
+};
+
+/* 4 to 1 mux */
+struct mux {
+ uint32_t id;
+ uint8_t mux_inputs[4];
+ uint8_t mux_outputs[2];
+};
+
+/* Adjacent list structure */
+struct edge_node {
+ uint32_t adjvex;
+ uint32_t prev_vnode;
+ struct edge_node *next;
+ uint32_t mux_used;
+ struct mux_config muxes;
+};
+
+struct vetex_node {
+ uint8_t type;
+ struct edge_node *first;
+};
+
+struct path_node {
+ struct list_head node;
+ uint32_t id;
+ uint32_t distance;
+ uint32_t prev_node;
+};
+
+static struct vetex_node adj_list[PXP_2D_NUM];
+static struct path_node path_table[PXP_2D_NUM][PXP_2D_NUM];
+
+static bool adj_array_v3[PXP_2D_NUM][PXP_2D_NUM] = {
+ /* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 */
+ {0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, /* 0 */
+ {0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0}, /* 1 */
+ {0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0}, /* 2 */
+ {0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1}, /* 3 */
+ {0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}, /* 4 */
+ {0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0}, /* 5 */
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0}, /* 6 */
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0}, /* 7 */
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0}, /* 8 */
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0}, /* 9 */
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0}, /* 10 */
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0}, /* 11 */
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0}, /* 12 */
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, /* 13 */
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, /* 14 */
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, /* 15 */
+};
+
+
+static struct mux muxes_v3[16] = {
+ {
+ /* mux0 */
+ .id = 0,
+ .mux_inputs = {PXP_2D_CSC1, PXP_2D_INPUT_FETCH0, PXP_2D_INPUT_FETCH1, 0xff},
+ .mux_outputs = {PXP_2D_ROTATION1, 0xff},
+ }, {
+ /* mux1 */
+ .id = 1,
+ .mux_inputs = {PXP_2D_INPUT_FETCH0, PXP_2D_ROTATION1, 0xff, 0xff},
+ .mux_outputs = {PXP_2D_ALPHA1_S1, PXP_2D_MUX_MUX5},
+ }, {
+ /* mux2 */
+ .id = 2,
+ .mux_inputs = {PXP_2D_INPUT_FETCH1, PXP_2D_ROTATION1, 0xff, 0xff},
+ .mux_outputs = {PXP_2D_ALPHA1_S0, 0xff},
+ }, {
+ /* mux3 */
+ .id = 3,
+ .mux_inputs = {PXP_2D_CSC1, PXP_2D_ROTATION1, 0xff, 0xff},
+ .mux_outputs = {PXP_2D_ALPHA0_S0, 0xff},
+ }, {
+ /* mux4 is not used in ULT1 */
+ .id = 4,
+ .mux_inputs = {0xff, 0xff, 0xff, 0xff},
+ .mux_outputs = {0xff, 0xff},
+ }, {
+ /* mux5 */
+ .id = 5,
+ .mux_inputs = {PXP_2D_MUX_MUX1, PXP_2D_ALPHA1_S0_S1, 0xff, 0xff},
+ .mux_outputs = {PXP_2D_MUX_MUX7, 0xff},
+ }, {
+ /* mux6 */
+ .id = 6,
+ .mux_inputs = {PXP_2D_ALPHA1_S0_S1, PXP_2D_ALPHA0_S0_S1, 0xff, 0xff},
+ .mux_outputs = {PXP_2D_CSC2, 0xff},
+ }, {
+ /* mux7 */
+ .id = 7,
+ .mux_inputs = {PXP_2D_MUX_MUX5, PXP_2D_CSC2, 0xff, 0xff},
+ .mux_outputs = {PXP_2D_MUX_MUX9, PXP_2D_MUX_MUX10},
+ }, {
+ /* mux8 */
+ .id = 8,
+ .mux_inputs = {PXP_2D_CSC2, PXP_2D_ALPHA0_S0_S1, 0xff, 0xff},
+ .mux_outputs = {PXP_2D_MUX_MUX9, PXP_2D_MUX_MUX11},
+ }, {
+ /* mux9 */
+ .id = 9,
+ .mux_inputs = {PXP_2D_MUX_MUX7, PXP_2D_MUX_MUX8, 0xff, 0xff},
+ .mux_outputs = {PXP_2D_LUT, 0xff},
+ }, {
+ /* mux10 */
+ .id = 10,
+ .mux_inputs = {PXP_2D_MUX_MUX7, PXP_2D_LUT, 0xff, 0xff},
+ .mux_outputs = {PXP_2D_MUX_MUX12, PXP_2D_MUX_MUX15},
+ }, {
+ /* mux11 */
+ .id = 11,
+ .mux_inputs = {PXP_2D_LUT, PXP_2D_MUX_MUX8, 0xff, 0xff},
+ .mux_outputs = {PXP_2D_MUX_MUX12, PXP_2D_MUX_MUX14},
+ }, {
+ /* mux12 */
+ .id = 12,
+ .mux_inputs = {PXP_2D_MUX_MUX10, PXP_2D_MUX_MUX11, 0xff, 0xff},
+ .mux_outputs = {PXP_2D_ROTATION0, 0xff},
+ }, {
+ /* mux13 */
+ .id = 13,
+ .mux_inputs = {PXP_2D_INPUT_FETCH1, 0xff, 0xff, 0xff},
+ .mux_outputs = {PXP_2D_INPUT_STORE1, 0xff},
+ }, {
+ /* mux14 */
+ .id = 14,
+ .mux_inputs = {PXP_2D_ROTATION0, PXP_2D_MUX_MUX11, 0xff, 0xff},
+ .mux_outputs = {PXP_2D_OUT, 0xff},
+ }, {
+ /* mux15 */
+ .id = 15,
+ .mux_inputs = {PXP_2D_INPUT_FETCH0, PXP_2D_MUX_MUX10, 0xff, 0xff},
+ .mux_outputs = {PXP_2D_INPUT_STORE0, 0xff},
+ },
+};
+
+static bool adj_array_v3p[PXP_2D_NUM][PXP_2D_NUM] = {
+ /* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 */
+ {0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, /* 0 */
+ {0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0}, /* 1 */
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, /* 2 */
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, /* 3 */
+ {0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}, /* 4 */
+ {0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}, /* 5 */
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0}, /* 6 */
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0}, /* 7 */
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, /* 8 */
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, /* 9 */
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0}, /* 10 */
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0}, /* 11 */
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0}, /* 12 */
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, /* 13 */
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, /* 14 */
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, /* 15 */
+};
+
+static struct mux muxes_v3p[16] = {
+ {
+ /* mux0 */
+ .id = 0,
+ .mux_inputs = {0xff, 0xff, 0xff, 0xff},
+ .mux_outputs = {0xff, 0xff},
+ }, {
+ /* mux1 */
+ .id = 1,
+ .mux_inputs = {0xff, 0xff, 0xff, 0xff},
+ .mux_outputs = {0xff, 0xff},
+ }, {
+ /* mux2 */
+ .id = 2,
+ .mux_inputs = {0xff, 0xff, 0xff, 0xff},
+ .mux_outputs = {0xff, 0xff},
+ }, {
+ /* mux3 */
+ .id = 3,
+ .mux_inputs = {PXP_2D_CSC1, PXP_2D_ROTATION1, 0xff, 0xff},
+ .mux_outputs = {PXP_2D_ALPHA0_S0, 0xff},
+ }, {
+ /* mux4 is not used in ULT1 */
+ .id = 4,
+ .mux_inputs = {0xff, 0xff, 0xff, 0xff},
+ .mux_outputs = {0xff, 0xff},
+ }, {
+ /* mux5 */
+ .id = 5,
+ .mux_inputs = {0xff, 0xff, 0xff, 0xff},
+ .mux_outputs = {0xff, 0xff},
+ }, {
+ /* mux6 */
+ .id = 6,
+ .mux_inputs = {0xff, 0xff, 0xff, 0xff},
+ .mux_outputs = {0xff, 0xff},
+ }, {
+ /* mux7 */
+ .id = 7,
+ .mux_inputs = {0xff, 0xff, 0xff, 0xff},
+ .mux_outputs = {0xff, 0xff},
+ }, {
+ /* mux8 */
+ .id = 8,
+ .mux_inputs = {PXP_2D_CSC2, PXP_2D_ALPHA0_S0_S1, 0xff, 0xff},
+ .mux_outputs = {PXP_2D_MUX_MUX9, PXP_2D_MUX_MUX11},
+ }, {
+ /* mux9 */
+ .id = 9,
+ .mux_inputs = {0xff, PXP_2D_MUX_MUX8, 0xff, 0xff},
+ .mux_outputs = {PXP_2D_LUT, 0xff},
+ }, {
+ /* mux10 */
+ .id = 10,
+ .mux_inputs = {0xff, 0xff, 0xff, 0xff},
+ .mux_outputs = {0xff, 0xff},
+ }, {
+ /* mux11 */
+ .id = 11,
+ .mux_inputs = {PXP_2D_LUT, PXP_2D_MUX_MUX8, 0xff, 0xff},
+ .mux_outputs = {PXP_2D_MUX_MUX12, PXP_2D_ROTATION0},
+ }, {
+ /* mux12 */
+ .id = 12,
+ .mux_inputs = {PXP_2D_ROTATION0, PXP_2D_MUX_MUX11, 0xff, 0xff},
+ .mux_outputs = {PXP_2D_MUX_MUX14, 0xff},
+ }, {
+ /* mux13 */
+ .id = 13,
+ .mux_inputs = {0xff, 0xff, 0xff, 0xff},
+ .mux_outputs = {0xff, 0xff},
+ }, {
+ /* mux14 */
+ .id = 14,
+ .mux_inputs = {0xff, PXP_2D_MUX_MUX12, 0xff, 0xff},
+ .mux_outputs = {PXP_2D_OUT, 0xff},
+ }, {
+ /* mux15 */
+ .id = 15,
+ .mux_inputs = {0xff, 0xff, 0xff, 0xff},
+ .mux_outputs = {0xff, 0xff},
+ },
+};
+
+static void __iomem *pxp_reg_base;
+
+#define pxp_writel(val, reg) writel(val, pxp_reg_base + (reg))
+
+static __attribute__((aligned (1024*4))) unsigned int active_matrix_data_8x8[64]={
+ 0x06050100, 0x04030207, 0x06050100, 0x04030207,
+ 0x00040302, 0x07060501, 0x00040302, 0x07060501,
+ 0x02070605, 0x01000403, 0x02070605, 0x01000403,
+ 0x05010004, 0x03020706, 0x05010004, 0x03020706,
+ 0x04030207, 0x06050100, 0x04030207, 0x06050100,
+ 0x07060501, 0x00040302, 0x07060501, 0x00040302,
+ 0x01000403, 0x02070605, 0x01000403, 0x02070605,
+ 0x03020706, 0x05010004, 0x03020706, 0x05010004,
+ 0x06050100, 0x04030207, 0x06050100, 0x04030207,
+ 0x00040302, 0x07060501, 0x00040302, 0x07060501,
+ 0x02070605, 0x01000403, 0x02070605, 0x01000403,
+ 0x05010004, 0x03020706, 0x05010004, 0x03020706,
+ 0x04030207, 0x06050100, 0x04030207, 0x06050100,
+ 0x07060501, 0x00040302, 0x07060501, 0x00040302,
+ 0x01000403, 0x02070605, 0x01000403, 0x02070605,
+ 0x03020706, 0x05010004, 0x03020706, 0x05010004
+ };
+
+static __attribute__((aligned (1024*4))) unsigned int bit1_dither_data_8x8[64]={
+
+ 1, 49*2, 13*2, 61*2, 4*2, 52*2, 16*2, 64*2,
+ 33*2, 17*2, 45*2, 29*2, 36*2, 20*2, 48*2, 32*2,
+ 9*2, 57*2, 5*2, 53*2, 12*2, 60*2, 8*2, 56*2,
+ 41*2, 25*2, 37*2, 21*2, 44*2, 28*2, 40*2, 24*2,
+ 3*2, 51*2, 15*2, 63*2, 2*2, 50*2, 14*2, 62*2,
+ 35*2, 19*2, 47*2, 31*2, 34*2, 18*2, 46*2, 30*2,
+ 11*2, 59*2, 7*2, 55*2, 10*2, 58*2, 6*2, 54*2,
+ 43*2, 27*2, 39*2, 23*2, 42*2, 26*2, 38*2, 22*2
+};
+
+static __attribute__((aligned (1024*4))) unsigned int bit2_dither_data_8x8[64]={
+
+ 1, 49, 13, 61, 4, 52, 16, 64,
+ 33, 17, 45, 29, 36, 20, 48, 32,
+ 9, 57, 5, 53, 12, 60, 8, 56,
+ 41, 25, 37, 21, 44, 28, 40, 24,
+ 3, 51, 15, 63, 2, 50, 14, 62,
+ 35, 19, 47, 31, 34, 18, 46, 30,
+ 11, 59, 7, 55, 10, 58, 6, 54,
+ 43, 27, 39, 23, 42, 26, 38, 22
+};
+
+static __attribute__((aligned (1024*4))) unsigned int bit4_dither_data_8x8[64]={
+
+ 1, 49/4, 13/4, 61/4, 4/4, 52/4, 16/4, 64/4,
+ 33/4, 17/4, 45/4, 29/4, 36/4, 20/4, 48/4, 32/4,
+ 9/4, 57/4, 5/4, 53/4, 12/4, 60/4, 8/4, 56/4,
+ 41/4, 25/4, 37/4, 21/4, 44/4, 28/4, 40/4, 24/4,
+ 3/4, 51/4, 15/4, 63/4, 2/4, 50/4, 14/4, 62/4,
+ 35/4, 19/4, 47/4, 31/4, 34/4, 18/4, 46/4, 30/4,
+ 11/4, 59/4, 7/4, 55/4, 10/4, 58/4, 6/4, 54/4,
+ 43/4, 27/4, 39/4, 23/4, 42/4, 26/4, 38/4, 22/4
+};
+
+static void pxp_dithering_configure(struct pxps *pxp);
+static void pxp_dithering_configure_v3p(struct pxps *pxp);
+static void pxp_dithering_process(struct pxps *pxp);
+static void pxp_wfe_a_process(struct pxps *pxp);
+static void pxp_wfe_a_process_v3p(struct pxps *pxp);
+static void pxp_wfe_a_configure(struct pxps *pxp);
+static void pxp_wfe_a_configure_v3p(struct pxps *pxp);
+static void pxp_wfe_b_process(struct pxps *pxp);
+static void pxp_wfe_b_configure(struct pxps *pxp);
+static void pxp_lut_status_set(struct pxps *pxp, unsigned int lut);
+static void pxp_lut_status_set_v3p(struct pxps *pxp, unsigned int lut);
+static void pxp_lut_status_clr(unsigned int lut);
+static void pxp_lut_status_clr_v3p(unsigned int lut);
+static void pxp_start2(struct pxps *pxp);
+static void pxp_data_path_config_v3p(struct pxps *pxp);
+static void pxp_soft_reset(struct pxps *pxp);
+static void pxp_collision_detection_disable(struct pxps *pxp);
+static void pxp_collision_detection_enable(struct pxps *pxp,
+ unsigned int width,
+ unsigned int height);
+static void pxp_luts_activate(struct pxps *pxp, u64 lut_status);
+static bool pxp_collision_status_report(struct pxps *pxp, struct pxp_collision_info *info);
+static void pxp_histogram_status_report(struct pxps *pxp, u32 *hist_status);
+static void pxp_histogram_enable(struct pxps *pxp,
+ unsigned int width,
+ unsigned int height);
+static void pxp_histogram_disable(struct pxps *pxp);
+static void pxp_lut_cleanup_multiple(struct pxps *pxp, u64 lut, bool set);
+static void pxp_lut_cleanup_multiple_v3p(struct pxps *pxp, u64 lut, bool set);
+static void pxp_luts_deactivate(struct pxps *pxp, u64 lut_status);
+static void pxp_set_colorkey(struct pxps *pxp);
+
+enum {
+ DITHER0_LUT = 0x0, /* Select the LUT memory for access */
+ DITHER0_ERR0 = 0x1, /* Select the ERR0 memory for access */
+ DITHER0_ERR1 = 0x2, /* Select the ERR1 memory for access */
+ DITHER1_LUT = 0x3, /* Select the LUT memory for access */
+ DITHER2_LUT = 0x4, /* Select the LUT memory for access */
+ ALU_A = 0x5, /* Select the ALU instr memory for access */
+ ALU_B = 0x6, /* Select the ALU instr memory for access */
+ WFE_A = 0x7, /* Select the WFE_A instr memory for access */
+ WFE_B = 0x8, /* Select the WFE_B instr memory for access */
+ RESERVED = 0x15,
+};
+
+enum pxp_devtype {
+ PXP_V3,
+ PXP_V3P, /* minor changes over V3, use WFE_B to replace WFE_A */
+};
+
+#define pxp_is_v3(pxp) (pxp->devdata->version == 30)
+#define pxp_is_v3p(pxp) (pxp->devdata->version == 31)
+
+struct pxp_devdata {
+ void (*pxp_wfe_a_configure)(struct pxps *pxp);
+ void (*pxp_wfe_a_process)(struct pxps *pxp);
+ void (*pxp_lut_status_set)(struct pxps *pxp, unsigned int lut);
+ void (*pxp_lut_status_clr)(unsigned int lut);
+ void (*pxp_dithering_configure)(struct pxps *pxp);
+ void (*pxp_lut_cleanup_multiple)(struct pxps *pxp, u64 lut, bool set);
+ void (*pxp_data_path_config)(struct pxps *pxp);
+ unsigned int version;
+};
+
+static const struct pxp_devdata pxp_devdata[] = {
+ [PXP_V3] = {
+ .pxp_wfe_a_configure = pxp_wfe_a_configure,
+ .pxp_wfe_a_process = pxp_wfe_a_process,
+ .pxp_lut_status_set = pxp_lut_status_set,
+ .pxp_lut_status_clr = pxp_lut_status_clr,
+ .pxp_lut_cleanup_multiple = pxp_lut_cleanup_multiple,
+ .pxp_dithering_configure = pxp_dithering_configure,
+ .pxp_data_path_config = NULL,
+ .version = 30,
+ },
+ [PXP_V3P] = {
+ .pxp_wfe_a_configure = pxp_wfe_a_configure_v3p,
+ .pxp_wfe_a_process = pxp_wfe_a_process_v3p,
+ .pxp_lut_status_set = pxp_lut_status_set_v3p,
+ .pxp_lut_status_clr = pxp_lut_status_clr_v3p,
+ .pxp_lut_cleanup_multiple = pxp_lut_cleanup_multiple_v3p,
+ .pxp_dithering_configure = pxp_dithering_configure_v3p,
+ .pxp_data_path_config = pxp_data_path_config_v3p,
+ .version = 31,
+ },
+};
+
+/*
+ * PXP common functions
+ */
+static void dump_pxp_reg(struct pxps *pxp)
+{
+ dev_dbg(pxp->dev, "PXP_CTRL 0x%x",
+ __raw_readl(pxp->base + HW_PXP_CTRL));
+ dev_dbg(pxp->dev, "PXP_STAT 0x%x",
+ __raw_readl(pxp->base + HW_PXP_STAT));
+ dev_dbg(pxp->dev, "PXP_OUT_CTRL 0x%x",
+ __raw_readl(pxp->base + HW_PXP_OUT_CTRL));
+ dev_dbg(pxp->dev, "PXP_OUT_BUF 0x%x",
+ __raw_readl(pxp->base + HW_PXP_OUT_BUF));
+ dev_dbg(pxp->dev, "PXP_OUT_BUF2 0x%x",
+ __raw_readl(pxp->base + HW_PXP_OUT_BUF2));
+ dev_dbg(pxp->dev, "PXP_OUT_PITCH 0x%x",
+ __raw_readl(pxp->base + HW_PXP_OUT_PITCH));
+ dev_dbg(pxp->dev, "PXP_OUT_LRC 0x%x",
+ __raw_readl(pxp->base + HW_PXP_OUT_LRC));
+ dev_dbg(pxp->dev, "PXP_OUT_PS_ULC 0x%x",
+ __raw_readl(pxp->base + HW_PXP_OUT_PS_ULC));
+ dev_dbg(pxp->dev, "PXP_OUT_PS_LRC 0x%x",
+ __raw_readl(pxp->base + HW_PXP_OUT_PS_LRC));
+ dev_dbg(pxp->dev, "PXP_OUT_AS_ULC 0x%x",
+ __raw_readl(pxp->base + HW_PXP_OUT_AS_ULC));
+ dev_dbg(pxp->dev, "PXP_OUT_AS_LRC 0x%x",
+ __raw_readl(pxp->base + HW_PXP_OUT_AS_LRC));
+ dev_dbg(pxp->dev, "PXP_PS_CTRL 0x%x",
+ __raw_readl(pxp->base + HW_PXP_PS_CTRL));
+ dev_dbg(pxp->dev, "PXP_PS_BUF 0x%x",
+ __raw_readl(pxp->base + HW_PXP_PS_BUF));
+ dev_dbg(pxp->dev, "PXP_PS_UBUF 0x%x",
+ __raw_readl(pxp->base + HW_PXP_PS_UBUF));
+ dev_dbg(pxp->dev, "PXP_PS_VBUF 0x%x",
+ __raw_readl(pxp->base + HW_PXP_PS_VBUF));
+ dev_dbg(pxp->dev, "PXP_PS_PITCH 0x%x",
+ __raw_readl(pxp->base + HW_PXP_PS_PITCH));
+ dev_dbg(pxp->dev, "PXP_PS_BACKGROUND_0 0x%x",
+ __raw_readl(pxp->base + HW_PXP_PS_BACKGROUND_0));
+ dev_dbg(pxp->dev, "PXP_PS_SCALE 0x%x",
+ __raw_readl(pxp->base + HW_PXP_PS_SCALE));
+ dev_dbg(pxp->dev, "PXP_PS_OFFSET 0x%x",
+ __raw_readl(pxp->base + HW_PXP_PS_OFFSET));
+ dev_dbg(pxp->dev, "PXP_PS_CLRKEYLOW_0 0x%x",
+ __raw_readl(pxp->base + HW_PXP_PS_CLRKEYLOW_0));
+ dev_dbg(pxp->dev, "PXP_PS_CLRKEYHIGH 0x%x",
+ __raw_readl(pxp->base + HW_PXP_PS_CLRKEYHIGH_0));
+ dev_dbg(pxp->dev, "PXP_AS_CTRL 0x%x",
+ __raw_readl(pxp->base + HW_PXP_AS_CTRL));
+ dev_dbg(pxp->dev, "PXP_AS_BUF 0x%x",
+ __raw_readl(pxp->base + HW_PXP_AS_BUF));
+ dev_dbg(pxp->dev, "PXP_AS_PITCH 0x%x",
+ __raw_readl(pxp->base + HW_PXP_AS_PITCH));
+ dev_dbg(pxp->dev, "PXP_AS_CLRKEYLOW 0x%x",
+ __raw_readl(pxp->base + HW_PXP_AS_CLRKEYLOW_0));
+ dev_dbg(pxp->dev, "PXP_AS_CLRKEYHIGH 0x%x",
+ __raw_readl(pxp->base + HW_PXP_AS_CLRKEYHIGH_0));
+ dev_dbg(pxp->dev, "PXP_CSC1_COEF0 0x%x",
+ __raw_readl(pxp->base + HW_PXP_CSC1_COEF0));
+ dev_dbg(pxp->dev, "PXP_CSC1_COEF1 0x%x",
+ __raw_readl(pxp->base + HW_PXP_CSC1_COEF1));
+ dev_dbg(pxp->dev, "PXP_CSC1_COEF2 0x%x",
+ __raw_readl(pxp->base + HW_PXP_CSC1_COEF2));
+ dev_dbg(pxp->dev, "PXP_CSC2_CTRL 0x%x",
+ __raw_readl(pxp->base + HW_PXP_CSC2_CTRL));
+ dev_dbg(pxp->dev, "PXP_CSC2_COEF0 0x%x",
+ __raw_readl(pxp->base + HW_PXP_CSC2_COEF0));
+ dev_dbg(pxp->dev, "PXP_CSC2_COEF1 0x%x",
+ __raw_readl(pxp->base + HW_PXP_CSC2_COEF1));
+ dev_dbg(pxp->dev, "PXP_CSC2_COEF2 0x%x",
+ __raw_readl(pxp->base + HW_PXP_CSC2_COEF2));
+ dev_dbg(pxp->dev, "PXP_CSC2_COEF3 0x%x",
+ __raw_readl(pxp->base + HW_PXP_CSC2_COEF3));
+ dev_dbg(pxp->dev, "PXP_CSC2_COEF4 0x%x",
+ __raw_readl(pxp->base + HW_PXP_CSC2_COEF4));
+ dev_dbg(pxp->dev, "PXP_CSC2_COEF5 0x%x",
+ __raw_readl(pxp->base + HW_PXP_CSC2_COEF5));
+ dev_dbg(pxp->dev, "PXP_LUT_CTRL 0x%x",
+ __raw_readl(pxp->base + HW_PXP_LUT_CTRL));
+ dev_dbg(pxp->dev, "PXP_LUT_ADDR 0x%x",
+ __raw_readl(pxp->base + HW_PXP_LUT_ADDR));
+ dev_dbg(pxp->dev, "PXP_LUT_DATA 0x%x",
+ __raw_readl(pxp->base + HW_PXP_LUT_DATA));
+ dev_dbg(pxp->dev, "PXP_LUT_EXTMEM 0x%x",
+ __raw_readl(pxp->base + HW_PXP_LUT_EXTMEM));
+ dev_dbg(pxp->dev, "PXP_CFA 0x%x",
+ __raw_readl(pxp->base + HW_PXP_CFA));
+ dev_dbg(pxp->dev, "PXP_ALPHA_A_CTRL 0x%x",
+ __raw_readl(pxp->base + HW_PXP_ALPHA_A_CTRL));
+ dev_dbg(pxp->dev, "PXP_ALPHA_B_CTRL 0x%x",
+ __raw_readl(pxp->base + HW_PXP_ALPHA_B_CTRL));
+ dev_dbg(pxp->dev, "PXP_POWER_REG0 0x%x",
+ __raw_readl(pxp->base + HW_PXP_POWER_REG0));
+ dev_dbg(pxp->dev, "PXP_NEXT 0x%x",
+ __raw_readl(pxp->base + HW_PXP_NEXT));
+ dev_dbg(pxp->dev, "PXP_DEBUGCTRL 0x%x",
+ __raw_readl(pxp->base + HW_PXP_DEBUGCTRL));
+ dev_dbg(pxp->dev, "PXP_DEBUG 0x%x",
+ __raw_readl(pxp->base + HW_PXP_DEBUG));
+ dev_dbg(pxp->dev, "PXP_VERSION 0x%x",
+ __raw_readl(pxp->base + HW_PXP_VERSION));
+}
+
+static void dump_pxp_reg2(struct pxps *pxp)
+{
+#ifdef DEBUG
+ int i = 0;
+
+ for (i=0; i< ((0x33C0/0x10) + 1);i++) {
+ printk("0x%08x: 0x%08x\n", 0x10*i, __raw_readl(pxp->base + 0x10*i));
+ }
+#endif
+}
+
+static void print_param(struct pxp_layer_param *p, char *s)
+{
+ pr_debug("%s: t/l/w/h/s %d/%d/%d/%d/%d, addr %x\n", s,
+ p->top, p->left, p->width, p->height, p->stride, p->paddr);
+}
+
+/* when it is, return yuv plane number */
+static uint8_t is_yuv(uint32_t format)
+{
+ switch (format) {
+ case PXP_PIX_FMT_GREY:
+ case PXP_PIX_FMT_GY04:
+ case PXP_PIX_FMT_YUYV:
+ case PXP_PIX_FMT_UYVY:
+ case PXP_PIX_FMT_YVYU:
+ case PXP_PIX_FMT_VYUY:
+ case PXP_PIX_FMT_YUV444:
+ case PXP_PIX_FMT_YVU444:
+ case PXP_PIX_FMT_VUY444:
+ return 1;
+ case PXP_PIX_FMT_NV12:
+ case PXP_PIX_FMT_NV21:
+ case PXP_PIX_FMT_NV16:
+ case PXP_PIX_FMT_NV61:
+ return 2;
+ case PXP_PIX_FMT_YUV420P:
+ case PXP_PIX_FMT_YUV422P:
+ case PXP_PIX_FMT_YVU420P:
+ case PXP_PIX_FMT_YVU422P:
+ return 3;
+ default:
+ return 0;
+ }
+}
+
+static u32 get_bpp_from_fmt(u32 pix_fmt)
+{
+ unsigned int bpp = 0;
+
+ switch (pix_fmt) {
+ case PXP_PIX_FMT_GREY:
+ case PXP_PIX_FMT_NV16:
+ case PXP_PIX_FMT_NV61:
+ case PXP_PIX_FMT_NV12:
+ case PXP_PIX_FMT_NV21:
+ case PXP_PIX_FMT_YUV422P:
+ case PXP_PIX_FMT_YVU422P:
+ case PXP_PIX_FMT_YUV420P:
+ case PXP_PIX_FMT_YVU420P:
+ bpp = 8;
+ break;
+ case PXP_PIX_FMT_RGB555:
+ case PXP_PIX_FMT_ARGB555:
+ case PXP_PIX_FMT_XRGB555:
+ case PXP_PIX_FMT_RGBA555:
+ case PXP_PIX_FMT_ARGB444:
+ case PXP_PIX_FMT_XRGB444:
+ case PXP_PIX_FMT_RGBA444:
+ case PXP_PIX_FMT_RGB565:
+ case PXP_PIX_FMT_BGR565:
+ case PXP_PIX_FMT_YUYV:
+ case PXP_PIX_FMT_YVYU:
+ case PXP_PIX_FMT_UYVY:
+ case PXP_PIX_FMT_VYUY:
+ bpp = 16;
+ break;
+ case PXP_PIX_FMT_RGB24:
+ case PXP_PIX_FMT_BGR24:
+ bpp = 24;
+ break;
+ case PXP_PIX_FMT_XRGB32:
+ case PXP_PIX_FMT_RGBX32:
+ case PXP_PIX_FMT_XBGR32:
+ case PXP_PIX_FMT_BGRX32:
+ case PXP_PIX_FMT_ARGB32:
+ case PXP_PIX_FMT_RGBA32:
+ case PXP_PIX_FMT_ABGR32:
+ case PXP_PIX_FMT_BGRA32:
+ case PXP_PIX_FMT_YUV444:
+ case PXP_PIX_FMT_YVU444:
+ case PXP_PIX_FMT_VUY444:
+ bpp = 32;
+ break;
+ default:
+ pr_err("%s: pix_fmt unsupport yet: 0x%x\n", __func__, pix_fmt);
+ break;
+ }
+
+ return bpp;
+}
+
+static uint32_t pxp_parse_ps_fmt(uint32_t format)
+{
+ uint32_t fmt_ctrl;
+
+ switch (format) {
+ case PXP_PIX_FMT_XRGB32:
+ case PXP_PIX_FMT_ARGB32:
+ fmt_ctrl = BV_PXP_PS_CTRL_FORMAT__RGB888;
+ break;
+ case PXP_PIX_FMT_RGB565:
+ fmt_ctrl = BV_PXP_PS_CTRL_FORMAT__RGB565;
+ break;
+ case PXP_PIX_FMT_RGB555:
+ fmt_ctrl = BV_PXP_PS_CTRL_FORMAT__RGB555;
+ break;
+ case PXP_PIX_FMT_YUV420P:
+ fmt_ctrl = BV_PXP_PS_CTRL_FORMAT__YUV420;
+ break;
+ case PXP_PIX_FMT_YVU420P:
+ fmt_ctrl = BV_PXP_PS_CTRL_FORMAT__YUV420;
+ break;
+ case PXP_PIX_FMT_GREY:
+ fmt_ctrl = BV_PXP_PS_CTRL_FORMAT__Y8;
+ break;
+ case PXP_PIX_FMT_GY04:
+ fmt_ctrl = BV_PXP_PS_CTRL_FORMAT__Y4;
+ break;
+ case PXP_PIX_FMT_VUY444:
+ fmt_ctrl = BV_PXP_PS_CTRL_FORMAT__YUV1P444;
+ break;
+ case PXP_PIX_FMT_YUV422P:
+ fmt_ctrl = BV_PXP_PS_CTRL_FORMAT__YUV422;
+ break;
+ case PXP_PIX_FMT_UYVY:
+ fmt_ctrl = BV_PXP_PS_CTRL_FORMAT__UYVY1P422;
+ break;
+ case PXP_PIX_FMT_YUYV:
+ fmt_ctrl = BV_PXP_PS_CTRL_FORMAT__UYVY1P422;
+ break;
+ case PXP_PIX_FMT_VYUY:
+ fmt_ctrl = BV_PXP_PS_CTRL_FORMAT__VYUY1P422;
+ break;
+ case PXP_PIX_FMT_YVYU:
+ fmt_ctrl = BV_PXP_PS_CTRL_FORMAT__VYUY1P422;
+ break;
+ case PXP_PIX_FMT_NV12:
+ fmt_ctrl = BV_PXP_PS_CTRL_FORMAT__YUV2P420;
+ break;
+ case PXP_PIX_FMT_NV21:
+ fmt_ctrl = BV_PXP_PS_CTRL_FORMAT__YVU2P420;
+ break;
+ case PXP_PIX_FMT_NV16:
+ fmt_ctrl = BV_PXP_PS_CTRL_FORMAT__YUV2P422;
+ break;
+ case PXP_PIX_FMT_NV61:
+ fmt_ctrl = BV_PXP_PS_CTRL_FORMAT__YVU2P422;
+ break;
+ case PXP_PIX_FMT_RGBA32:
+ case PXP_PIX_FMT_RGBX32:
+ fmt_ctrl = BV_PXP_PS_CTRL_FORMAT__RGBA888;
+ break;
+ default:
+ pr_debug("PS doesn't support this format\n");
+ fmt_ctrl = 0;
+ }
+
+ return fmt_ctrl;
+}
+
+static void pxp_set_colorkey(struct pxps *pxp)
+{
+ struct pxp_config_data *pxp_conf = &pxp->pxp_conf_state;
+ struct pxp_layer_param *s0_params = &pxp_conf->s0_param;
+ struct pxp_layer_param *ol_params = &pxp_conf->ol_param[0];
+
+ /* Low and high are set equal. V4L does not allow a chromakey range */
+ if (s0_params->color_key_enable == 0 || s0_params->color_key == -1) {
+ /* disable color key */
+ pxp_writel(0xFFFFFF, HW_PXP_PS_CLRKEYLOW_0);
+ pxp_writel(0, HW_PXP_PS_CLRKEYHIGH_0);
+ } else {
+ pxp_writel(s0_params->color_key, HW_PXP_PS_CLRKEYLOW_0);
+ pxp_writel(s0_params->color_key, HW_PXP_PS_CLRKEYHIGH_0);
+ }
+
+ if (ol_params->color_key_enable != 0 && ol_params->color_key != -1) {
+ pxp_writel(ol_params->color_key, HW_PXP_AS_CLRKEYLOW_0);
+ pxp_writel(ol_params->color_key, HW_PXP_AS_CLRKEYHIGH_0);
+ } else {
+ /* disable color key */
+ pxp_writel(0xFFFFFF, HW_PXP_AS_CLRKEYLOW_0);
+ pxp_writel(0, HW_PXP_AS_CLRKEYHIGH_0);
+ }
+}
+
+static uint32_t pxp_parse_as_fmt(uint32_t format)
+{
+ uint32_t fmt_ctrl;
+
+ switch (format) {
+ case PXP_PIX_FMT_BGRA32:
+ case PXP_PIX_FMT_ARGB32:
+ fmt_ctrl = BV_PXP_AS_CTRL_FORMAT__ARGB8888;
+ break;
+ case PXP_PIX_FMT_RGBA32:
+ fmt_ctrl = BV_PXP_AS_CTRL_FORMAT__RGBA8888;
+ break;
+ case PXP_PIX_FMT_XRGB32:
+ fmt_ctrl = BV_PXP_AS_CTRL_FORMAT__RGB888;
+ break;
+ case PXP_PIX_FMT_ARGB555:
+ fmt_ctrl = BV_PXP_AS_CTRL_FORMAT__ARGB1555;
+ break;
+ case PXP_PIX_FMT_ARGB444:
+ fmt_ctrl = BV_PXP_AS_CTRL_FORMAT__ARGB4444;
+ break;
+ case PXP_PIX_FMT_RGBA555:
+ fmt_ctrl = BV_PXP_AS_CTRL_FORMAT__RGBA5551;
+ break;
+ case PXP_PIX_FMT_RGBA444:
+ fmt_ctrl = BV_PXP_AS_CTRL_FORMAT__RGBA4444;
+ break;
+ case PXP_PIX_FMT_RGB555:
+ fmt_ctrl = BV_PXP_AS_CTRL_FORMAT__RGB555;
+ break;
+ case PXP_PIX_FMT_RGB444:
+ fmt_ctrl = BV_PXP_AS_CTRL_FORMAT__RGB444;
+ break;
+ case PXP_PIX_FMT_RGB565:
+ fmt_ctrl = BV_PXP_AS_CTRL_FORMAT__RGB565;
+ break;
+ default:
+ pr_debug("AS doesn't support this format\n");
+ fmt_ctrl = 0xf;
+ break;
+ }
+
+ return fmt_ctrl;
+}
+
+static uint32_t pxp_parse_out_fmt(uint32_t format)
+{
+ uint32_t fmt_ctrl;
+
+ switch (format) {
+ case PXP_PIX_FMT_BGRA32:
+ case PXP_PIX_FMT_ARGB32:
+ fmt_ctrl = BV_PXP_OUT_CTRL_FORMAT__ARGB8888;
+ break;
+ case PXP_PIX_FMT_XRGB32:
+ fmt_ctrl = BV_PXP_OUT_CTRL_FORMAT__RGB888;
+ break;
+ case PXP_PIX_FMT_RGB24:
+ fmt_ctrl = BV_PXP_OUT_CTRL_FORMAT__RGB888P;
+ break;
+ case PXP_PIX_FMT_RGB565:
+ fmt_ctrl = BV_PXP_OUT_CTRL_FORMAT__RGB565;
+ break;
+ case PXP_PIX_FMT_RGB555:
+ fmt_ctrl = BV_PXP_OUT_CTRL_FORMAT__RGB555;
+ break;
+ case PXP_PIX_FMT_GREY:
+ fmt_ctrl = BV_PXP_OUT_CTRL_FORMAT__Y8;
+ break;
+ case PXP_PIX_FMT_GY04:
+ fmt_ctrl = BV_PXP_OUT_CTRL_FORMAT__Y4;
+ break;
+ case PXP_PIX_FMT_UYVY:
+ fmt_ctrl = BV_PXP_OUT_CTRL_FORMAT__UYVY1P422;
+ break;
+ case PXP_PIX_FMT_VYUY:
+ fmt_ctrl = BV_PXP_OUT_CTRL_FORMAT__VYUY1P422;
+ break;
+ case PXP_PIX_FMT_NV12:
+ fmt_ctrl = BV_PXP_OUT_CTRL_FORMAT__YUV2P420;
+ break;
+ case PXP_PIX_FMT_NV21:
+ fmt_ctrl = BV_PXP_OUT_CTRL_FORMAT__YVU2P420;
+ break;
+ case PXP_PIX_FMT_NV16:
+ fmt_ctrl = BV_PXP_OUT_CTRL_FORMAT__YUV2P422;
+ break;
+ case PXP_PIX_FMT_NV61:
+ fmt_ctrl = BV_PXP_OUT_CTRL_FORMAT__YVU2P422;
+ break;
+ default:
+ pr_debug("OUT doesn't support this format\n");
+ fmt_ctrl = 0;
+ }
+
+ return fmt_ctrl;
+}
+
+static void set_mux(struct mux_config *path_ctrl)
+{
+ struct mux_config *mux = path_ctrl;
+
+ *(uint32_t *)path_ctrl = 0xFFFFFFFF;
+
+ mux->mux0_sel = 0;
+ mux->mux3_sel = 1;
+ mux->mux6_sel = 1;
+ mux->mux8_sel = 0;
+ mux->mux9_sel = 1;
+ mux->mux11_sel = 0;
+ mux->mux12_sel = 1;
+ mux->mux14_sel = 0;
+}
+
+static void set_mux_val(struct mux_config *muxes,
+ uint32_t mux_id,
+ uint32_t mux_val)
+{
+ BUG_ON(!muxes);
+ BUG_ON(mux_id > 15);
+
+ switch (mux_id) {
+ case 0:
+ muxes->mux0_sel = mux_val;
+ break;
+ case 1:
+ muxes->mux1_sel = mux_val;
+ break;
+ case 2:
+ muxes->mux2_sel = mux_val;
+ break;
+ case 3:
+ muxes->mux3_sel = mux_val;
+ break;
+ case 4:
+ muxes->mux4_sel = mux_val;
+ break;
+ case 5:
+ muxes->mux5_sel = mux_val;
+ break;
+ case 6:
+ muxes->mux6_sel = mux_val;
+ break;
+ case 7:
+ muxes->mux7_sel = mux_val;
+ break;
+ case 8:
+ muxes->mux8_sel = mux_val;
+ break;
+ case 9:
+ muxes->mux9_sel = mux_val;
+ break;
+ case 10:
+ muxes->mux10_sel = mux_val;
+ break;
+ case 11:
+ muxes->mux11_sel = mux_val;
+ break;
+ case 12:
+ muxes->mux12_sel = mux_val;
+ break;
+ case 13:
+ muxes->mux13_sel = mux_val;
+ break;
+ case 14:
+ muxes->mux14_sel = mux_val;
+ break;
+ case 15:
+ muxes->mux15_sel = mux_val;
+ break;
+ default:
+ break;
+ }
+}
+
+static uint32_t get_mux_val(struct mux_config *muxes,
+ uint32_t mux_id)
+{
+ BUG_ON(!muxes);
+ BUG_ON(mux_id > 15);
+
+ switch (mux_id) {
+ case 0:
+ return muxes->mux0_sel;
+ case 1:
+ return muxes->mux1_sel;
+ case 2:
+ return muxes->mux2_sel;
+ case 3:
+ return muxes->mux3_sel;
+ case 4:
+ return muxes->mux4_sel;
+ case 5:
+ return muxes->mux5_sel;
+ case 6:
+ return muxes->mux6_sel;
+ case 7:
+ return muxes->mux7_sel;
+ case 8:
+ return muxes->mux8_sel;
+ case 9:
+ return muxes->mux9_sel;
+ case 10:
+ return muxes->mux10_sel;
+ case 11:
+ return muxes->mux11_sel;
+ case 12:
+ return muxes->mux12_sel;
+ case 13:
+ return muxes->mux13_sel;
+ case 14:
+ return muxes->mux14_sel;
+ case 15:
+ return muxes->mux15_sel;
+ default:
+ return -EINVAL;
+ }
+}
+
+static uint32_t pxp_store_ctrl_config(struct pxp_pixmap *out, uint8_t mode,
+ uint8_t fill_en, uint8_t combine_2ch)
+{
+ struct store_ctrl ctrl;
+ uint8_t output_active_bpp;
+
+ memset((void*)&ctrl, 0x0, sizeof(ctrl));
+
+ if (combine_2ch) {
+ ctrl.combine_2channel = 1;
+ if (out) {
+ output_active_bpp = active_bpp(out->bpp);
+ ctrl.pack_in_sel = (output_active_bpp < 0x3) ? 1 : 0;
+ ctrl.store_memory_en = 1;
+ }
+ } else {
+ if (fill_en) {
+ ctrl.fill_data_en = 1;
+ ctrl.wr_num_bytes = 2;
+ }
+ ctrl.store_memory_en = 1;
+ }
+
+ if (out->rotate || out->flip)
+ ctrl.block_en = 1;
+
+ ctrl.ch_en = 1;
+
+ return *(uint32_t *)&ctrl;
+}
+
+static uint32_t pxp_store_size_config(struct pxp_pixmap *out)
+{
+ struct store_size size;
+
+ memset((void*)&size, 0x0, sizeof(size));
+
+ size.out_height = out->height - 1;
+ size.out_width = out->width - 1;
+
+ return *(uint32_t *)&size;
+}
+
+static uint32_t pxp_store_pitch_config(struct pxp_pixmap *out0,
+ struct pxp_pixmap *out1)
+{
+ struct store_pitch pitch;
+
+ memset((void*)&pitch, 0x0, sizeof(pitch));
+
+ pitch.ch0_out_pitch = out0->pitch;
+ pitch.ch1_out_pitch = out1 ? out1->pitch : 0;
+
+ return *(uint32_t *)&pitch;
+}
+
+static struct color *pxp_find_rgb_color(uint32_t format)
+{
+ int i;
+
+ for (i = 0; i < sizeof(rgb_colors) / sizeof(struct color); i++) {
+ if (rgb_colors[i].format == format)
+ return &rgb_colors[i];
+ }
+
+ return NULL;
+}
+
+static struct color_component *pxp_find_comp(struct color *color, uint8_t id)
+{
+ int i;
+
+ for (i = 0; i < 4; i++) {
+ if (id == color->comp[i].id)
+ return &color->comp[i];
+ }
+
+ return NULL;
+}
+
+static struct color *pxp_find_yuv_color(uint32_t format)
+{
+ int i;
+
+ for (i = 0; i < sizeof(yuv_colors) / sizeof(struct color); i++) {
+ if (yuv_colors[i].format == format)
+ return &yuv_colors[i];
+ }
+
+ return NULL;
+}
+
+static uint64_t pxp_store_d_shift_calc(uint32_t in_fmt, uint32_t out_fmt,
+ struct store_d_mask *d_mask)
+{
+ int i, shift_width, shift_flag, drop = 0;
+ struct store_d_shift d_shift;
+ struct color *input_color, *output_color;
+ struct color_component *input_comp, *output_comp;
+
+ BUG_ON((in_fmt == out_fmt));
+ memset((void*)&d_shift, 0x0, sizeof(d_shift));
+ memset((void*)d_mask, 0x0, sizeof(*d_mask) * 8);
+
+ if (!is_yuv(in_fmt)) {
+ input_color = pxp_find_rgb_color(in_fmt);
+ output_color = pxp_find_rgb_color(out_fmt);
+ } else {
+ input_color = pxp_find_yuv_color(in_fmt);
+ output_color = pxp_find_yuv_color(out_fmt);
+ }
+
+ for (i = 0; i < 4; i++) {
+ input_comp = &input_color->comp[i];
+ if (!input_comp->length)
+ continue;
+
+ output_comp = pxp_find_comp(output_color, input_comp->id);
+ if (!output_comp->length)
+ continue;
+
+ /* only rgb format can drop color bits */
+ if (input_comp->length > output_comp->length) {
+ drop = input_comp->length - output_comp->length;
+ input_comp->offset += drop;
+ }
+ d_mask[i].d_mask_l = output_comp->mask << input_comp->offset;
+
+ shift_width = input_comp->offset - output_comp->offset;
+ if (shift_width > 0)
+ shift_flag = 0; /* right shift */
+ else if (shift_width < 0) {
+ shift_flag = 1; /* left shift */
+ shift_width = -shift_width;
+ } else
+ shift_width = shift_flag = 0; /* no shift require */
+
+ switch (i) {
+ case 0:
+ d_shift.d_shift_width0 = shift_width;
+ d_shift.d_shift_flag0 = shift_flag;
+ break;
+ case 1:
+ d_shift.d_shift_width1 = shift_width;
+ d_shift.d_shift_flag1 = shift_flag;
+ break;
+ case 2:
+ d_shift.d_shift_width2 = shift_width;
+ d_shift.d_shift_flag2 = shift_flag;
+ break;
+ case 3:
+ d_shift.d_shift_width3 = shift_width;
+ d_shift.d_shift_flag3 = shift_flag;
+ break;
+ default:
+ printk(KERN_ERR "unsupport d shift\n");
+ break;
+ }
+
+ input_comp->offset -= drop;
+ }
+
+ return *(uint64_t *)&d_shift;
+}
+
+static uint32_t pxp_store_shift_ctrl_config(struct pxp_pixmap *out,
+ uint8_t shift_bypass)
+{
+ struct store_shift_ctrl shift_ctrl;
+
+ memset((void*)&shift_ctrl, 0x0, sizeof(shift_ctrl));
+
+ shift_ctrl.output_active_bpp = active_bpp(out->bpp);
+ /* Not general data */
+ if (!shift_bypass) {
+ switch(out->format) {
+ case PXP_PIX_FMT_YUYV:
+ shift_bypass = 1;
+ case PXP_PIX_FMT_YVYU:
+ shift_ctrl.out_yuv422_1p_en = 1;
+ break;
+ case PXP_PIX_FMT_NV16:
+ shift_bypass = 1;
+ case PXP_PIX_FMT_NV61:
+ shift_ctrl.out_yuv422_2p_en = 1;
+ break;
+ default:
+ break;
+ }
+ }
+ shift_ctrl.shift_bypass = shift_bypass;
+
+ return *(uint32_t *)&shift_ctrl;
+}
+
+static uint32_t pxp_fetch_ctrl_config(struct pxp_pixmap *in,
+ uint8_t mode)
+{
+ struct fetch_ctrl ctrl;
+
+ memset((void*)&ctrl, 0x0, sizeof(ctrl));
+
+ if (mode == FETCH_MODE_NORMAL)
+ ctrl.bypass_pixel_en = 0;
+
+ if (in->flip == PXP_H_FLIP)
+ ctrl.hflip = 1;
+ else if (in->flip == PXP_V_FLIP)
+ ctrl.vflip = 1;
+
+ ctrl.rotation_angle = rotate_map(in->rotate);
+
+ if (in->rotate || in->flip)
+ ctrl.block_en = 1;
+
+ ctrl.ch_en = 1;
+
+ return *(uint32_t *)&ctrl;
+}
+
+static uint32_t pxp_fetch_active_size_ulc(struct pxp_pixmap *in)
+{
+ struct fetch_active_size_ulc size_ulc;
+
+ memset((void*)&size_ulc, 0x0, sizeof(size_ulc));
+
+ size_ulc.active_size_ulc_x = 0;
+ size_ulc.active_size_ulc_y = 0;
+
+ return *(uint32_t *)&size_ulc;
+}
+
+static uint32_t pxp_fetch_active_size_lrc(struct pxp_pixmap *in)
+{
+ struct fetch_active_size_lrc size_lrc;
+
+ memset((void*)&size_lrc, 0x0, sizeof(size_lrc));
+
+ size_lrc.active_size_lrc_x = in->crop.width - 1;
+ size_lrc.active_size_lrc_y = in->crop.height - 1;
+
+ return *(uint32_t *)&size_lrc;
+}
+
+static uint32_t pxp_fetch_pitch_config(struct pxp_pixmap *in0,
+ struct pxp_pixmap *in1)
+{
+ struct fetch_pitch pitch;
+
+ memset((void*)&pitch, 0x0, sizeof(pitch));
+
+ if (in0)
+ pitch.ch0_input_pitch = in0->pitch;
+ if (in1)
+ pitch.ch1_input_pitch = in1->pitch;
+
+ return *(uint32_t *)&pitch;
+}
+
+static uint32_t pxp_fetch_shift_ctrl_config(struct pxp_pixmap *in,
+ uint8_t shift_bypass,
+ uint8_t need_expand)
+{
+ uint8_t input_expand_format;
+ struct fetch_shift_ctrl shift_ctrl;
+
+ memset((void*)&shift_ctrl, 0x0, sizeof(shift_ctrl));
+
+ shift_ctrl.input_active_bpp = active_bpp(in->bpp);
+ shift_ctrl.shift_bypass = shift_bypass;
+
+ if (in->bpp == 32)
+ need_expand = 0;
+
+ if (need_expand) {
+ input_expand_format = expand_format(in->format);
+
+ if (input_expand_format <= 0x7) {
+ shift_ctrl.expand_en = 1;
+ shift_ctrl.expand_format = input_expand_format;
+ }
+ }
+
+ return *(uint32_t *)&shift_ctrl;
+}
+
+static uint32_t pxp_fetch_shift_calc(uint32_t in_fmt, uint32_t out_fmt,
+ struct fetch_shift_width *shift_width)
+{
+ int i;
+ struct fetch_shift_offset shift_offset;
+ struct color *input_color, *output_color;
+ struct color_component *input_comp, *output_comp;
+
+ memset((void*)&shift_offset, 0x0, sizeof(shift_offset));
+ memset((void*)shift_width, 0x0, sizeof(*shift_width));
+
+ if (!is_yuv(in_fmt)) {
+ input_color = pxp_find_rgb_color(in_fmt);
+ output_color = pxp_find_rgb_color(out_fmt);
+ } else {
+ input_color = pxp_find_yuv_color(in_fmt);
+ output_color = pxp_find_yuv_color(out_fmt);
+ }
+
+ for(i = 0; i < 4; i++) {
+ output_comp = &output_color->comp[i];
+ if (!output_comp->length)
+ continue;
+
+ input_comp = pxp_find_comp(input_color, output_comp->id);
+ switch (i) {
+ case 0:
+ shift_offset.offset0 = input_comp->offset;
+ shift_width->width0 = input_comp->length;
+ break;
+ case 1:
+ shift_offset.offset1 = input_comp->offset;
+ shift_width->width1 = input_comp->length;
+ break;
+ case 2:
+ shift_offset.offset2 = input_comp->offset;
+ shift_width->width2 = input_comp->length;
+ break;
+ case 3:
+ shift_offset.offset3 = input_comp->offset;
+ shift_width->width3 = input_comp->length;
+ break;
+ }
+ }
+
+ return *(uint32_t *)&shift_offset;
+}
+
+static int pxp_start(struct pxps *pxp)
+{
+ __raw_writel(BM_PXP_CTRL_ENABLE_ROTATE1 | BM_PXP_CTRL_ENABLE |
+ BM_PXP_CTRL_ENABLE_CSC2 | BM_PXP_CTRL_ENABLE_LUT |
+ BM_PXP_CTRL_ENABLE_PS_AS_OUT | BM_PXP_CTRL_ENABLE_ROTATE0,
+ pxp->base + HW_PXP_CTRL_SET);
+ dump_pxp_reg(pxp);
+
+ return 0;
+}
+
+static bool fmt_ps_support(uint32_t format)
+{
+ switch (format) {
+ case PXP_PIX_FMT_XRGB32:
+ case PXP_PIX_FMT_ARGB32:
+ case PXP_PIX_FMT_RGB555:
+ case PXP_PIX_FMT_XRGB555:
+ case PXP_PIX_FMT_ARGB555:
+ case PXP_PIX_FMT_RGB444:
+ case PXP_PIX_FMT_XRGB444:
+ case PXP_PIX_FMT_ARGB444:
+ case PXP_PIX_FMT_RGB565:
+ case PXP_PIX_FMT_YUV444:
+ case PXP_PIX_FMT_UYVY:
+ case PXP_PIX_FMT_VUY444:
+ /* need word byte swap */
+ case PXP_PIX_FMT_YUYV:
+ case PXP_PIX_FMT_VYUY:
+ /* need word byte swap */
+ case PXP_PIX_FMT_YVYU:
+ case PXP_PIX_FMT_GREY:
+ case PXP_PIX_FMT_GY04:
+ case PXP_PIX_FMT_NV16:
+ case PXP_PIX_FMT_NV12:
+ case PXP_PIX_FMT_NV61:
+ case PXP_PIX_FMT_NV21:
+ case PXP_PIX_FMT_YUV422P:
+ case PXP_PIX_FMT_YUV420P:
+ case PXP_PIX_FMT_YVU420P:
+ case PXP_PIX_FMT_RGBA32:
+ case PXP_PIX_FMT_RGBX32:
+ case PXP_PIX_FMT_RGBA555:
+ case PXP_PIX_FMT_RGBA444:
+ return true;
+ default:
+ return false;
+ }
+}
+
+static bool fmt_as_support(uint32_t format)
+{
+ switch (format) {
+ case PXP_PIX_FMT_ARGB32:
+ case PXP_PIX_FMT_RGBA32:
+ case PXP_PIX_FMT_XRGB32:
+ case PXP_PIX_FMT_BGRA32:
+ case PXP_PIX_FMT_ARGB555:
+ case PXP_PIX_FMT_ARGB444:
+ case PXP_PIX_FMT_RGBA555:
+ case PXP_PIX_FMT_RGBA444:
+ case PXP_PIX_FMT_RGB555:
+ case PXP_PIX_FMT_RGB444:
+ case PXP_PIX_FMT_RGB565:
+ return true;
+ default:
+ return false;
+ }
+}
+
+static bool fmt_out_support(uint32_t format)
+{
+ switch (format) {
+ case PXP_PIX_FMT_ARGB32:
+ case PXP_PIX_FMT_XRGB32:
+ case PXP_PIX_FMT_BGRA32:
+ case PXP_PIX_FMT_RGB24:
+ case PXP_PIX_FMT_ARGB555:
+ case PXP_PIX_FMT_ARGB444:
+ case PXP_PIX_FMT_RGB555:
+ case PXP_PIX_FMT_RGB444:
+ case PXP_PIX_FMT_RGB565:
+ case PXP_PIX_FMT_YUV444:
+ case PXP_PIX_FMT_UYVY:
+ case PXP_PIX_FMT_VYUY:
+ case PXP_PIX_FMT_GREY:
+ case PXP_PIX_FMT_GY04:
+ case PXP_PIX_FMT_NV16:
+ case PXP_PIX_FMT_NV12:
+ case PXP_PIX_FMT_NV61:
+ case PXP_PIX_FMT_NV21:
+ return true;
+ default:
+ return false;
+ }
+}
+
+/* common means 'ARGB32/XRGB32/YUV444' */
+static uint8_t fmt_fetch_to_common(uint32_t in)
+{
+ switch (in) {
+ case PXP_PIX_FMT_ARGB32:
+ case PXP_PIX_FMT_XRGB32:
+ case PXP_PIX_FMT_YUV444:
+ return FETCH_NOOP;
+
+ case PXP_PIX_FMT_RGB565:
+ case PXP_PIX_FMT_RGB555:
+ case PXP_PIX_FMT_ARGB555:
+ case PXP_PIX_FMT_RGB444:
+ case PXP_PIX_FMT_ARGB444:
+ case PXP_PIX_FMT_YUYV:
+ case PXP_PIX_FMT_UYVY:
+ case PXP_PIX_FMT_NV16:
+ return FETCH_EXPAND;
+
+ case PXP_PIX_FMT_RGBA32:
+ case PXP_PIX_FMT_RGBX32:
+ case PXP_PIX_FMT_BGRA32:
+ case PXP_PIX_FMT_BGRX32:
+ case PXP_PIX_FMT_ABGR32:
+ case PXP_PIX_FMT_XBGR32:
+ case PXP_PIX_FMT_YVU444:
+ return FETCH_SHIFT;
+
+ case PXP_PIX_FMT_BGR565:
+ case PXP_PIX_FMT_YVYU:
+ case PXP_PIX_FMT_VYUY:
+ return FETCH_EXPAND | FETCH_SHIFT;
+
+ default:
+ return 0;
+ }
+}
+
+static uint8_t fmt_store_from_common(uint32_t out)
+{
+ switch (out) {
+ case PXP_PIX_FMT_ARGB32:
+ case PXP_PIX_FMT_XRGB32:
+ case PXP_PIX_FMT_YUV444:
+ return STORE_NOOP;
+
+ case PXP_PIX_FMT_YUYV:
+ case PXP_PIX_FMT_NV16:
+ return STORE_SHRINK;
+
+ case PXP_PIX_FMT_RGBA32:
+ case PXP_PIX_FMT_RGBX32:
+ case PXP_PIX_FMT_BGRA32:
+ case PXP_PIX_FMT_BGRX32:
+ case PXP_PIX_FMT_ABGR32:
+ case PXP_PIX_FMT_XBGR32:
+ case PXP_PIX_FMT_YVU444:
+ case PXP_PIX_FMT_RGB565:
+ case PXP_PIX_FMT_RGB555:
+ case PXP_PIX_FMT_ARGB555:
+ case PXP_PIX_FMT_RGB444:
+ case PXP_PIX_FMT_ARGB444:
+ case PXP_PIX_FMT_GREY:
+ return STORE_SHIFT;
+
+ case PXP_PIX_FMT_YVYU:
+ case PXP_PIX_FMT_NV61:
+ return STORE_SHIFT | STORE_SHRINK;
+
+ default:
+ return 0;
+ }
+}
+
+static void filter_possible_inputs(struct pxp_pixmap *input,
+ uint32_t *possible)
+{
+ uint8_t clear = 0xff;
+ uint8_t position = 0;
+
+ do {
+ position = find_next_bit((unsigned long *)possible, 32, position);
+ if (position >= sizeof(uint32_t) * 8)
+ break;
+
+ switch (position) {
+ case PXP_2D_PS:
+ if (!fmt_ps_support(input->format))
+ clear = PXP_2D_PS;
+ break;
+ case PXP_2D_AS:
+ if (!fmt_as_support(input->format))
+ clear = PXP_2D_AS;
+ break;
+ case PXP_2D_INPUT_FETCH0:
+ case PXP_2D_INPUT_FETCH1:
+ if ((is_yuv(input->format) == 3)) {
+ clear = position;
+ break;
+ }
+ if ((input->flags & IN_NEED_FMT_UNIFIED) ||
+ is_yuv(input->format) == 2)
+ if (!fmt_fetch_to_common(input->format))
+ clear = position;
+ break;
+ default:
+ pr_err("invalid input node: %d\n", position);
+ clear = position;
+ break;
+ }
+
+ if (clear != 0xff) {
+ clear_bit(clear, (unsigned long*)possible);
+ clear = 0xff;
+ }
+
+ position++;
+ } while (1);
+}
+
+static void filter_possible_outputs(struct pxp_pixmap *output,
+ uint32_t *possible)
+{
+ uint8_t clear = 0xff;
+ uint8_t position = 0;
+
+ do {
+ position = find_next_bit((unsigned long *)possible, 32, position);
+ if (position >= sizeof(uint32_t) * 8)
+ break;
+
+ switch (position) {
+ case PXP_2D_OUT:
+ if (!fmt_out_support(output->format))
+ clear = PXP_2D_OUT;
+ break;
+ case PXP_2D_INPUT_STORE0:
+ case PXP_2D_INPUT_STORE1:
+ if (output->flags) {
+ if (!fmt_store_from_common(output->format))
+ clear = position;
+ }
+ break;
+ default:
+ pr_err("invalid output node: %d\n", position);
+ clear = position;
+ break;
+ }
+
+ if (clear != 0xff) {
+ clear_bit(clear, (unsigned long*)possible);
+ clear = 0xff;
+ }
+
+ position++;
+ } while (1);
+}
+
+static uint32_t calc_shortest_path(uint32_t *nodes_used)
+{
+ uint32_t distance = 0;
+ uint32_t from = 0, to = 0, bypass, end;
+
+ do {
+ from = find_next_bit((unsigned long *)nodes_used, 32, from);
+ if (from >= sizeof(uint32_t) * 8)
+ break;
+
+ if (to != 0) {
+ if (path_table[to][from].distance == DISTANCE_INFINITY)
+ return DISTANCE_INFINITY;
+
+ distance += path_table[to][from].distance;
+ /* backtrace */
+ end = from;
+ while (1) {
+ bypass = path_table[to][end].prev_node;
+ if (bypass == to)
+ break;
+ set_bit(bypass, (unsigned long*)nodes_used);
+ end = bypass;
+ }
+ }
+
+ to = find_next_bit((unsigned long *)nodes_used, 32, from + 1);
+ if (to >= sizeof(uint32_t) * 8)
+ break;
+
+ if (path_table[from][to].distance == DISTANCE_INFINITY)
+ return DISTANCE_INFINITY;
+
+ distance += path_table[from][to].distance;
+ /* backtrace */
+ end = to;
+ while (1) {
+ bypass = path_table[from][end].prev_node;
+ if (bypass == from)
+ break;
+ set_bit(bypass, (unsigned long*)nodes_used);
+ end = bypass;
+ }
+
+ from = to + 1;
+ } while (1);
+
+ return distance;
+}
+
+static uint32_t find_best_path(uint32_t inputs,
+ uint32_t outputs,
+ struct pxp_pixmap *in,
+ uint32_t *nodes_used)
+{
+ uint32_t outs;
+ uint32_t nodes_add, best_nodes_used = 0;
+ uint8_t in_pos = 0, out_pos = 0;
+ uint32_t nodes_in_path, best_nodes_in_path = 0;
+ uint32_t best_distance = DISTANCE_INFINITY, distance;
+
+ do {
+ outs = outputs;
+ in_pos = find_next_bit((unsigned long *)&inputs, 32, in_pos);
+ if (in_pos >= sizeof(uint32_t) * 8)
+ break;
+ nodes_add = 0;
+ set_bit(in_pos, (unsigned long *)&nodes_add);
+
+ switch (in_pos) {
+ case PXP_2D_PS:
+ if ((in->flags & IN_NEED_CSC) == IN_NEED_CSC) {
+ if (is_yuv(in->format))
+ set_bit(PXP_2D_CSC1,
+ (unsigned long *)&nodes_add);
+ else
+ set_bit(PXP_2D_CSC2,
+ (unsigned long *)&nodes_add);
+ }
+ if ((in->flags & IN_NEED_ROTATE_FLIP) == IN_NEED_ROTATE_FLIP)
+ set_bit(PXP_2D_ROTATION1,
+ (unsigned long *)&nodes_add);
+ clear_bit(PXP_2D_INPUT_STORE0, (unsigned long *)&outs);
+ break;
+ case PXP_2D_AS:
+ if ((in->flags & IN_NEED_CSC) == IN_NEED_CSC)
+ set_bit(PXP_2D_CSC2,
+ (unsigned long *)&nodes_add);
+ if ((in->flags & IN_NEED_ROTATE_FLIP) == IN_NEED_ROTATE_FLIP)
+ set_bit(PXP_2D_ROTATION0,
+ (unsigned long *)&nodes_add);
+ clear_bit(PXP_2D_INPUT_STORE0, (unsigned long *)&outs);
+ break;
+ case PXP_2D_INPUT_FETCH0:
+ case PXP_2D_INPUT_FETCH1:
+ if ((in->flags & IN_NEED_CSC) == IN_NEED_CSC)
+ set_bit(PXP_2D_CSC2,
+ (unsigned long *)&nodes_add);
+ clear_bit(PXP_2D_OUT, (unsigned long *)&outs);
+ if ((in->flags & IN_NEED_ROTATE_FLIP) == IN_NEED_ROTATE_FLIP)
+ set_bit(PXP_2D_ROTATION1,
+ (unsigned long *)&nodes_add);
+ break;
+ default:
+ /* alph0_s0/s1, alpha1_s0/s1 */
+ break;
+ }
+
+ nodes_add |= *nodes_used;
+
+ do {
+ out_pos = find_next_bit((unsigned long *)&outs, 32, out_pos);
+ if (out_pos >= sizeof(uint32_t) * 8)
+ break;
+ set_bit(out_pos, (unsigned long *)&nodes_add);
+
+ switch(out_pos) {
+ case PXP_2D_ALPHA0_S0:
+ case PXP_2D_ALPHA0_S1:
+ case PXP_2D_ALPHA1_S0:
+ case PXP_2D_ALPHA1_S1:
+ clear_bit(PXP_2D_CSC2, (unsigned long *)&nodes_add);
+ clear_bit(PXP_2D_ROTATION0, (unsigned long *)&nodes_add);
+ clear_bit(PXP_2D_LUT, (unsigned long *)&nodes_add);
+ break;
+ default:
+ break;
+ }
+
+ nodes_in_path = nodes_add;
+ distance = calc_shortest_path(&nodes_in_path);
+ if (best_distance > distance) {
+ best_distance = distance;
+ best_nodes_used = nodes_add;
+ best_nodes_in_path = nodes_in_path;
+ }
+ pr_debug("%s: out_pos = %d, nodes_in_path = 0x%x, nodes_add = 0x%x, distance = 0x%x\n",
+ __func__, out_pos, nodes_in_path, nodes_add, distance);
+
+ clear_bit(out_pos, (unsigned long *)&nodes_add);
+
+ out_pos++;
+ } while (1);
+
+ in_pos++;
+ } while (1);
+
+ *nodes_used = best_nodes_used;
+
+ return best_nodes_in_path;
+}
+
+static uint32_t ps_calc_scaling(struct pxp_pixmap *input,
+ struct pxp_pixmap *output,
+ struct ps_ctrl *ctrl)
+{
+ struct ps_scale scale;
+ uint32_t decx, decy;
+
+ memset((void*)&scale, 0x0, sizeof(scale));
+
+ if (!output->crop.width || !output->crop.height) {
+ pr_err("Invalid drect width and height passed in\n");
+ return 0;
+ }
+
+ if ((input->rotate == 90) || (input->rotate == 270))
+ swap(output->crop.width, output->crop.height);
+
+ decx = input->crop.width / output->crop.width;
+ decy = input->crop.height / output->crop.height;
+
+ if (decx > 1) {
+ if (decx >= 2 && decx < 4) {
+ decx = 2;
+ ctrl->decx = 1;
+ } else if (decx >= 4 && decx < 8) {
+ decx = 4;
+ ctrl->decx = 2;
+ } else if (decx >= 8) {
+ decx = 8;
+ ctrl->decx = 3;
+ }
+ scale.xscale = input->crop.width * 0x1000 /
+ (output->crop.width * decx);
+
+ /* A factor greater than 2 is not supported
+ * with the bilinear filter, so correct it in
+ * driver
+ */
+ if (((scale.xscale >> BP_PXP_PS_SCALE_OFFSET) & 0x3) > 2) {
+ scale.xscale &= (~(0x3 << BP_PXP_PS_SCALE_OFFSET));
+ scale.xscale |= (0x2 << BP_PXP_PS_SCALE_OFFSET);
+ pr_warn("%s: scale.xscale is larger than 2, forcing to 2"
+ "input w/h=(%d,%d), output w/h=(%d, %d)\n",
+ __func__, input->crop.width, input->crop.height,
+ output->crop.width, output->crop.height);
+ }
+ } else {
+ if (!is_yuv(input->format) ||
+ (is_yuv(input->format) == is_yuv(output->format)) ||
+ (input->format == PXP_PIX_FMT_GREY) ||
+ (input->format == PXP_PIX_FMT_GY04) ||
+ (input->format == PXP_PIX_FMT_VUY444)) {
+ if ((input->crop.width > 1) &&
+ (output->crop.width > 1))
+ scale.xscale = (input->crop.width - 1) * 0x1000 /
+ (output->crop.width - 1);
+ else
+ scale.xscale = input->crop.width * 0x1000 /
+ output->crop.width;
+ } else {
+ if ((input->crop.width > 2) &&
+ (output->crop.width > 1))
+ scale.xscale = (input->crop.width - 2) * 0x1000 /
+ (output->crop.width - 1);
+ else
+ scale.xscale = input->crop.width * 0x1000 /
+ output->crop.width;
+ }
+ }
+
+ if (decy > 1) {
+ if (decy >= 2 && decy < 4) {
+ decy = 2;
+ ctrl->decy = 1;
+ } else if (decy >= 4 && decy < 8) {
+ decy = 4;
+ ctrl->decy = 2;
+ } else if (decy >= 8) {
+ decy = 8;
+ ctrl->decy = 3;
+ }
+ scale.yscale = input->crop.height * 0x1000 /
+ (output->crop.height * decy);
+
+ /* A factor greater than 2 is not supported
+ * with the bilinear filter, so correct it in
+ * driver
+ */
+ if (((scale.yscale >> BP_PXP_PS_SCALE_OFFSET) & 0x3) > 2) {
+ scale.yscale &= (~(0x3 << BP_PXP_PS_SCALE_OFFSET));
+ scale.yscale |= (0x2 << BP_PXP_PS_SCALE_OFFSET);
+ pr_warn("%s: scale.yscale is larger than 2, forcing to 2"
+ "input w/h=(%d,%d), output w/h=(%d, %d)\n",
+ __func__, input->crop.width, input->crop.height,
+ output->crop.width, output->crop.height);
+ }
+ } else {
+ if ((input->crop.height > 1) && (output->crop.height > 1))
+ scale.yscale = (input->crop.height - 1) * 0x1000 /
+ (output->crop.height - 1);
+ else
+ scale.yscale = input->crop.height * 0x1000 /
+ output->crop.height;
+ }
+
+ return *(uint32_t *)&scale;
+}
+
+static int pxp_ps_config(struct pxp_pixmap *input,
+ struct pxp_pixmap *output)
+{
+ uint32_t offset, U, V;
+ struct ps_ctrl ctrl;
+ struct coordinate out_ps_ulc, out_ps_lrc;
+
+ memset((void*)&ctrl, 0x0, sizeof(ctrl));
+
+ ctrl.format = pxp_parse_ps_fmt(input->format);
+
+ switch (output->rotate) {
+ case 0:
+ out_ps_ulc.x = output->crop.x;
+ out_ps_ulc.y = output->crop.y;
+ out_ps_lrc.x = out_ps_ulc.x + output->crop.width - 1;
+ out_ps_lrc.y = out_ps_ulc.y + output->crop.height - 1;
+ break;
+ case 90:
+ out_ps_ulc.x = output->crop.y;
+ out_ps_ulc.y = output->width - (output->crop.x + output->crop.width);
+ out_ps_lrc.x = out_ps_ulc.x + output->crop.height - 1;
+ out_ps_lrc.y = out_ps_ulc.y + output->crop.width - 1;
+ break;
+ case 180:
+ out_ps_ulc.x = output->width - (output->crop.x + output->crop.width);
+ out_ps_ulc.y = output->height - (output->crop.y + output->crop.height);
+ out_ps_lrc.x = out_ps_ulc.x + output->crop.width - 1;
+ out_ps_lrc.y = out_ps_ulc.y + output->crop.height - 1;
+ break;
+ case 270:
+ out_ps_ulc.x = output->height - (output->crop.y + output->crop.height);
+ out_ps_ulc.y = output->crop.x;
+ out_ps_lrc.x = out_ps_ulc.x + output->crop.height - 1;
+ out_ps_lrc.y = out_ps_ulc.y + output->crop.width - 1;
+ break;
+ default:
+ pr_err("PxP only support rotate 0 90 180 270\n");
+ return -EINVAL;
+ break;
+ }
+
+ if ((input->format == PXP_PIX_FMT_YUYV) ||
+ (input->format == PXP_PIX_FMT_YVYU))
+ ctrl.wb_swap = 1;
+
+ pxp_writel(ps_calc_scaling(input, output, &ctrl),
+ HW_PXP_PS_SCALE);
+ pxp_writel(*(uint32_t *)&ctrl, HW_PXP_PS_CTRL);
+
+ offset = input->crop.y * input->pitch +
+ input->crop.x * (input->bpp >> 3);
+ pxp_writel(input->paddr + offset, HW_PXP_PS_BUF);
+
+ switch (is_yuv(input->format)) {
+ case 0: /* RGB */
+ case 1: /* 1 Plane YUV */
+ break;
+ case 2: /* NV16,NV61,NV12,NV21 */
+ if ((input->format == PXP_PIX_FMT_NV16) ||
+ (input->format == PXP_PIX_FMT_NV61)) {
+ U = input->paddr + input->width * input->height;
+ pxp_writel(U + offset, HW_PXP_PS_UBUF);
+ }
+ else {
+ U = input->paddr + input->width * input->height;
+ pxp_writel(U + (offset >> 1), HW_PXP_PS_UBUF);
+ }
+ break;
+ case 3: /* YUV422P, YUV420P */
+ if (input->format == PXP_PIX_FMT_YUV422P) {
+ U = input->paddr + input->width * input->height;
+ pxp_writel(U + (offset >> 1), HW_PXP_PS_UBUF);
+ V = U + (input->width * input->height >> 1);
+ pxp_writel(V + (offset >> 1), HW_PXP_PS_VBUF);
+ } else if (input->format == PXP_PIX_FMT_YUV420P) {
+ U = input->paddr + input->width * input->height;
+ pxp_writel(U + (offset >> 2), HW_PXP_PS_UBUF);
+ V = U + (input->width * input->height >> 2);
+ pxp_writel(V + (offset >> 2), HW_PXP_PS_VBUF);
+ } else if (input->format == PXP_PIX_FMT_YVU420P) {
+ U = input->paddr + input->width * input->height;
+ V = U + (input->width * input->height >> 2);
+ pxp_writel(U + (offset >> 2), HW_PXP_PS_VBUF);
+ pxp_writel(V + (offset >> 2), HW_PXP_PS_UBUF);
+ }
+
+ break;
+ default:
+ break;
+ }
+
+ pxp_writel(input->pitch, HW_PXP_PS_PITCH);
+ pxp_writel(*(uint32_t *)&out_ps_ulc, HW_PXP_OUT_PS_ULC);
+ pxp_writel(*(uint32_t *)&out_ps_lrc, HW_PXP_OUT_PS_LRC);
+
+ pxp_writel(BF_PXP_CTRL_ENABLE_PS_AS_OUT(1) |
+ BF_PXP_CTRL_IRQ_ENABLE(1),
+ HW_PXP_CTRL_SET);
+
+ return 0;
+}
+
+static int pxp_as_config(struct pxp_pixmap *input,
+ struct pxp_pixmap *output)
+{
+ uint32_t offset;
+ struct as_ctrl ctrl;
+ struct coordinate out_as_ulc, out_as_lrc;
+
+ memset((void*)&ctrl, 0x0, sizeof(ctrl));
+
+ ctrl.format = pxp_parse_as_fmt(input->format);
+
+ if (alpha_blending_version == PXP_ALPHA_BLENDING_V1) {
+ if (input->format == PXP_PIX_FMT_BGRA32) {
+ if (!input->g_alpha.combine_enable) {
+ ctrl.alpha_ctrl = BV_PXP_AS_CTRL_ALPHA_CTRL__ROPs;
+ ctrl.rop = 0x3;
+ }
+ }
+
+ if (input->g_alpha.global_alpha_enable) {
+ if (input->g_alpha.global_override)
+ ctrl.alpha_ctrl = BV_PXP_AS_CTRL_ALPHA_CTRL__Override;
+ else
+ ctrl.alpha_ctrl = BV_PXP_AS_CTRL_ALPHA_CTRL__Multiply;
+
+ if (input->g_alpha.alpha_invert)
+ ctrl.alpha0_invert = 0x1;
+ }
+
+ if (input->g_alpha.color_key_enable) {
+ ctrl.enable_colorkey = 1;
+ }
+
+ ctrl.alpha = input->g_alpha.global_alpha;
+ }
+
+ out_as_ulc.x = out_as_ulc.y = 0;
+ if (input->g_alpha.combine_enable) {
+ out_as_lrc.x = input->width - 1;
+ out_as_lrc.y = input->height - 1;
+ } else {
+ out_as_lrc.x = output->crop.width - 1;
+ out_as_lrc.y = output->crop.height - 1;
+ }
+
+ offset = input->crop.y * input->pitch +
+ input->crop.x * (input->bpp >> 3);
+ pxp_writel(input->paddr + offset, HW_PXP_AS_BUF);
+
+ pxp_writel(input->pitch, HW_PXP_AS_PITCH);
+ pxp_writel(*(uint32_t *)&out_as_ulc, HW_PXP_OUT_AS_ULC);
+ pxp_writel(*(uint32_t *)&out_as_lrc, HW_PXP_OUT_AS_LRC);
+
+ pxp_writel(*(uint32_t *)&ctrl, HW_PXP_AS_CTRL);
+ pxp_writel(BF_PXP_CTRL_ENABLE_PS_AS_OUT(1) |
+ BF_PXP_CTRL_IRQ_ENABLE(1),
+ HW_PXP_CTRL_SET);
+
+ return 0;
+}
+
+static uint32_t pxp_fetch_size_config(struct pxp_pixmap *input)
+{
+ struct fetch_size total_size;
+
+ memset((void*)&total_size, 0x0, sizeof(total_size));
+
+ total_size.input_total_width = input->width - 1;
+ total_size.input_total_height = input->height - 1;
+
+ return *(uint32_t *)&total_size;
+}
+
+static int pxp_fetch_config(struct pxp_pixmap *input,
+ uint32_t fetch_index)
+{
+ uint8_t shift_bypass = 1, expand_en = 0;
+ uint32_t flags, pitch = 0, offset, UV = 0;
+ uint32_t in_fmt, out_fmt;
+ uint32_t size_ulc, size_lrc;
+ uint32_t fetch_ctrl, total_size;
+ uint32_t shift_ctrl, shift_offset = 0;
+ struct fetch_shift_width shift_width;
+
+ memset((unsigned int *)&shift_width, 0x0, sizeof(shift_width));
+ fetch_ctrl = pxp_fetch_ctrl_config(input, FETCH_MODE_NORMAL);
+ size_ulc = pxp_fetch_active_size_ulc(input);
+ size_lrc = pxp_fetch_active_size_lrc(input);
+ total_size = pxp_fetch_size_config(input);
+
+ if (input->flags) {
+ flags = fmt_fetch_to_common(input->format);
+ shift_bypass = (flags & FETCH_SHIFT) ? 0 : 1;
+ expand_en = (flags & FETCH_EXPAND) ? 1 : 0;
+
+ if (!shift_bypass) {
+ if (expand_en) {
+ if (is_yuv(input->format)) {
+ in_fmt = PXP_PIX_FMT_YVU444;
+ out_fmt = PXP_PIX_FMT_YUV444;
+ } else {
+ in_fmt = PXP_PIX_FMT_ABGR32;
+ out_fmt = PXP_PIX_FMT_ARGB32;
+ }
+ } else {
+ in_fmt = input->format;
+ out_fmt = is_yuv(input->format) ?
+ PXP_PIX_FMT_YUV444 :
+ PXP_PIX_FMT_ARGB32;
+ }
+
+ shift_offset = pxp_fetch_shift_calc(in_fmt, out_fmt,
+ &shift_width);
+ }
+ }
+ shift_ctrl = pxp_fetch_shift_ctrl_config(input, shift_bypass, expand_en);
+
+ offset = input->crop.y * input->pitch +
+ input->crop.x * (input->bpp >> 3);
+ if (is_yuv(input->format) == 2)
+ UV = input->paddr + input->width * input->height;
+
+ switch (fetch_index) {
+ case PXP_2D_INPUT_FETCH0:
+ pitch = __raw_readl(pxp_reg_base + HW_PXP_INPUT_FETCH_PITCH);
+ pitch |= pxp_fetch_pitch_config(input, NULL);
+ pxp_writel(fetch_ctrl, HW_PXP_INPUT_FETCH_CTRL_CH0);
+ pxp_writel(size_ulc, HW_PXP_INPUT_FETCH_ACTIVE_SIZE_ULC_CH0);
+ pxp_writel(size_lrc, HW_PXP_INPUT_FETCH_ACTIVE_SIZE_LRC_CH0);
+ pxp_writel(total_size, HW_PXP_INPUT_FETCH_SIZE_CH0);
+ pxp_writel(shift_ctrl, HW_PXP_INPUT_FETCH_SHIFT_CTRL_CH0);
+ pxp_writel(input->paddr + offset, HW_PXP_INPUT_FETCH_ADDR_0_CH0);
+ if (UV)
+ pxp_writel(UV + offset, HW_PXP_INPUT_FETCH_ADDR_1_CH0);
+ pxp_writel(shift_ctrl, HW_PXP_INPUT_FETCH_SHIFT_CTRL_CH0);
+ if (shift_offset)
+ pxp_writel(*(uint32_t *)&shift_offset, HW_PXP_INPUT_FETCH_SHIFT_OFFSET_CH0);
+ pxp_writel(*(uint32_t *)&shift_width, HW_PXP_INPUT_FETCH_SHIFT_WIDTH_CH0);
+ break;
+ case PXP_2D_INPUT_FETCH1:
+ pitch = __raw_readl(pxp_reg_base + HW_PXP_INPUT_FETCH_PITCH);
+ pitch |= pxp_fetch_pitch_config(NULL, input);
+ pxp_writel(fetch_ctrl, HW_PXP_INPUT_FETCH_CTRL_CH1);
+ pxp_writel(size_ulc, HW_PXP_INPUT_FETCH_ACTIVE_SIZE_ULC_CH1);
+ pxp_writel(size_lrc, HW_PXP_INPUT_FETCH_ACTIVE_SIZE_LRC_CH1);
+ pxp_writel(total_size, HW_PXP_INPUT_FETCH_SIZE_CH1);
+ pxp_writel(shift_ctrl, HW_PXP_INPUT_FETCH_SHIFT_CTRL_CH1);
+ pxp_writel(input->paddr + offset, HW_PXP_INPUT_FETCH_ADDR_0_CH1);
+ if (UV)
+ pxp_writel(UV + offset, HW_PXP_INPUT_FETCH_ADDR_1_CH1);
+ pxp_writel(shift_ctrl, HW_PXP_INPUT_FETCH_SHIFT_CTRL_CH1);
+ if (shift_offset)
+ pxp_writel(*(uint32_t *)&shift_offset, HW_PXP_INPUT_FETCH_SHIFT_OFFSET_CH1);
+ pxp_writel(*(uint32_t *)&shift_width, HW_PXP_INPUT_FETCH_SHIFT_WIDTH_CH1);
+ break;
+ default:
+ break;
+ }
+
+ pxp_writel(pitch, HW_PXP_INPUT_FETCH_PITCH);
+ pxp_writel(BF_PXP_CTRL_ENABLE_INPUT_FETCH_STORE(1), HW_PXP_CTRL_SET);
+
+ return 0;
+}
+
+static int pxp_csc1_config(struct pxp_pixmap *input,
+ bool is_ycbcr)
+{
+ BUG_ON(!is_yuv(input->format));
+
+ if (!is_ycbcr) {
+ /* YUV -> RGB */
+ pxp_writel(0x04030000, HW_PXP_CSC1_COEF0);
+ pxp_writel(0x01230208, HW_PXP_CSC1_COEF1);
+ pxp_writel(0x076b079c, HW_PXP_CSC1_COEF2);
+
+ return 0;
+ }
+
+ /* YCbCr -> RGB */
+ pxp_writel(0x84ab01f0, HW_PXP_CSC1_COEF0);
+ pxp_writel(0x01980204, HW_PXP_CSC1_COEF1);
+ pxp_writel(0x0730079c, HW_PXP_CSC1_COEF2);
+
+ return 0;
+}
+
+static int pxp_rotation1_config(struct pxp_pixmap *input)
+{
+ uint8_t rotate;
+
+ if (input->flip == PXP_H_FLIP)
+ pxp_writel(BF_PXP_CTRL_HFLIP1(1), HW_PXP_CTRL_SET);
+ else if (input->flip == PXP_V_FLIP)
+ pxp_writel(BF_PXP_CTRL_VFLIP1(1), HW_PXP_CTRL_SET);
+
+ rotate = rotate_map(input->rotate);
+ pxp_writel(BF_PXP_CTRL_ROTATE1(rotate), HW_PXP_CTRL_SET);
+
+ pxp_writel(BF_PXP_CTRL_ENABLE_ROTATE1(1), HW_PXP_CTRL_SET);
+
+ return 0;
+}
+
+static int pxp_rotation0_config(struct pxp_pixmap *input)
+{
+ uint8_t rotate;
+
+ if (input->flip == PXP_H_FLIP)
+ pxp_writel(BF_PXP_CTRL_HFLIP0(1), HW_PXP_CTRL_SET);
+ else if (input->flip == PXP_V_FLIP)
+ pxp_writel(BF_PXP_CTRL_VFLIP0(1), HW_PXP_CTRL_SET);
+
+ rotate = rotate_map(input->rotate);
+ pxp_writel(BF_PXP_CTRL_ROTATE0(rotate), HW_PXP_CTRL_SET);
+
+ pxp_writel(BF_PXP_CTRL_ENABLE_ROTATE0(1), HW_PXP_CTRL_SET);
+
+ return 0;
+}
+
+static int pxp_csc2_config(struct pxp_pixmap *output)
+{
+ if (is_yuv(output->format)) {
+ /* RGB -> YUV */
+ pxp_writel(0x4, HW_PXP_CSC2_CTRL);
+ pxp_writel(0x0096004D, HW_PXP_CSC2_COEF0);
+ pxp_writel(0x05DA001D, HW_PXP_CSC2_COEF1);
+ pxp_writel(0x007005B6, HW_PXP_CSC2_COEF2);
+ pxp_writel(0x057C009E, HW_PXP_CSC2_COEF3);
+ pxp_writel(0x000005E6, HW_PXP_CSC2_COEF4);
+ pxp_writel(0x00000000, HW_PXP_CSC2_COEF5);
+ }
+
+ pxp_writel(BF_PXP_CTRL_ENABLE_CSC2(1), HW_PXP_CTRL_SET);
+
+ return 0;
+}
+
+static int pxp_out_config(struct pxp_pixmap *output)
+{
+ uint32_t offset, UV;
+ struct out_ctrl ctrl;
+ struct coordinate out_lrc;
+
+ memset((void*)&ctrl, 0x0, sizeof(ctrl));
+
+ ctrl.format = pxp_parse_out_fmt(output->format);
+ offset = output->crop.y * output->pitch +
+ output->crop.x * (output->bpp >> 3);
+
+ pxp_writel(*(uint32_t *)&ctrl, HW_PXP_OUT_CTRL);
+
+ pxp_writel(output->paddr, HW_PXP_OUT_BUF);
+ if (is_yuv(output->format) == 2) {
+ UV = output->paddr + output->width * output->height;
+ if ((output->format == PXP_PIX_FMT_NV16) ||
+ (output->format == PXP_PIX_FMT_NV61))
+ pxp_writel(UV + offset, HW_PXP_OUT_BUF2);
+ else
+ pxp_writel(UV + (offset >> 1), HW_PXP_OUT_BUF2);
+ }
+
+ if (output->rotate == 90 || output->rotate == 270) {
+ out_lrc.y = output->width - 1;
+ out_lrc.x = output->height - 1;
+ } else {
+ out_lrc.x = output->width - 1;
+ out_lrc.y = output->height - 1;
+ }
+
+ pxp_writel(*(uint32_t *)&out_lrc, HW_PXP_OUT_LRC);
+
+ pxp_writel(output->pitch, HW_PXP_OUT_PITCH);
+
+ /* set global alpha if necessary */
+ if (output->g_alpha.global_alpha_enable) {
+ pxp_writel(output->g_alpha.global_alpha << 24, HW_PXP_OUT_CTRL_SET);
+ pxp_writel(BM_PXP_OUT_CTRL_ALPHA_OUTPUT, HW_PXP_OUT_CTRL_SET);
+ }
+
+ pxp_writel(BF_PXP_CTRL_ENABLE_PS_AS_OUT(1) |
+ BF_PXP_CTRL_IRQ_ENABLE(1),
+ HW_PXP_CTRL_SET);
+
+ return 0;
+}
+
+static int pxp_store_config(struct pxp_pixmap *output,
+ struct pxp_op_info *op)
+{
+ uint8_t combine_2ch, flags;
+ uint32_t in_fmt, out_fmt, offset, UV = 0;
+ uint64_t d_shift = 0;
+ struct store_d_mask d_mask[8];
+ uint32_t store_ctrl, store_size, store_pitch, shift_ctrl;
+
+ memset((void*)d_mask, 0x0, sizeof(*d_mask) * 8);
+ combine_2ch = (output->bpp == 64) ? 1 : 0;
+ store_ctrl = pxp_store_ctrl_config(output, STORE_MODE_NORMAL,
+ op->fill_en, combine_2ch);
+ store_size = pxp_store_size_config(output);
+ store_pitch = pxp_store_pitch_config(output, NULL);
+
+ pxp_writel(store_ctrl, HW_PXP_INPUT_STORE_CTRL_CH0);
+
+ if (output->flags) {
+ flags = fmt_store_from_common(output->format);
+ if (flags == STORE_NOOP)
+ shift_ctrl = pxp_store_shift_ctrl_config(output, 1);
+ else if (flags & STORE_SHIFT) {
+ in_fmt = is_yuv(output->format) ? PXP_PIX_FMT_YUV444 :
+ PXP_PIX_FMT_ARGB32;
+ out_fmt = (flags & STORE_SHRINK) ? PXP_PIX_FMT_YVU444 :
+ output->format;
+ d_shift = pxp_store_d_shift_calc(in_fmt, out_fmt, d_mask);
+ shift_ctrl = pxp_store_shift_ctrl_config(output, 0);
+ } else
+ shift_ctrl = pxp_store_shift_ctrl_config(output, 0);
+
+ if (flags & STORE_SHIFT) {
+ pxp_writel((uint32_t)d_shift, HW_PXP_INPUT_STORE_D_SHIFT_L_CH0);
+ /* TODO use only 4 masks */
+ pxp_writel(d_mask[0].d_mask_l, HW_PXP_INPUT_STORE_D_MASK0_L_CH0);
+ pxp_writel(d_mask[0].d_mask_h, HW_PXP_INPUT_STORE_D_MASK0_H_CH0);
+ pxp_writel(d_mask[1].d_mask_l, HW_PXP_INPUT_STORE_D_MASK1_L_CH0);
+ pxp_writel(d_mask[1].d_mask_h, HW_PXP_INPUT_STORE_D_MASK1_H_CH0);
+ pxp_writel(d_mask[2].d_mask_l, HW_PXP_INPUT_STORE_D_MASK2_L_CH0);
+ pxp_writel(d_mask[2].d_mask_h, HW_PXP_INPUT_STORE_D_MASK2_H_CH0);
+ pxp_writel(d_mask[3].d_mask_l, HW_PXP_INPUT_STORE_D_MASK3_L_CH0);
+ pxp_writel(d_mask[3].d_mask_h, HW_PXP_INPUT_STORE_D_MASK3_H_CH0);
+ }
+ } else
+ shift_ctrl = pxp_store_shift_ctrl_config(output, 1);
+
+ pxp_writel(shift_ctrl, HW_PXP_INPUT_STORE_SHIFT_CTRL_CH0);
+ pxp_writel(store_size, HW_PXP_INPUT_STORE_SIZE_CH0);
+ pxp_writel(store_pitch, HW_PXP_INPUT_STORE_PITCH);
+ if (op->fill_en) {
+ uint32_t lrc;
+
+ lrc = (output->width - 1) | ((output->height - 1) << 16);
+ pxp_writel(op->fill_data, HW_PXP_INPUT_STORE_FILL_DATA_CH0);
+
+ pxp_writel(0x1, HW_PXP_INPUT_FETCH_CTRL_CH0);
+ pxp_writel(0, HW_PXP_INPUT_FETCH_ACTIVE_SIZE_ULC_CH0);
+ pxp_writel(lrc, HW_PXP_INPUT_FETCH_ACTIVE_SIZE_LRC_CH0);
+ }
+
+ offset = output->crop.y * output->pitch +
+ output->crop.x * (output->bpp >> 3);
+ if (is_yuv(output->format == 2)) {
+ UV = output->paddr + output->width * output->height;
+ pxp_writel(UV + offset, HW_PXP_INPUT_STORE_ADDR_1_CH0);
+ }
+ pxp_writel(output->paddr + offset, HW_PXP_INPUT_STORE_ADDR_0_CH0);
+
+ pxp_writel(BF_PXP_CTRL_ENABLE_INPUT_FETCH_STORE(1), HW_PXP_CTRL_SET);
+
+ return 0;
+}
+
+static int pxp_alpha_config(struct pxp_op_info *op,
+ uint8_t alpha_node)
+{
+ uint32_t as_ctrl;
+ struct pxp_alpha_ctrl alpha_ctrl;
+ struct pxp_alpha_info *alpha = &op->alpha_info;
+ struct pxp_alpha *s0_alpha, *s1_alpha;
+
+ memset((void*)&alpha_ctrl, 0x0, sizeof(alpha_ctrl));
+
+ if (alpha_blending_version != PXP_ALPHA_BLENDING_V1) {
+ if (alpha->alpha_mode == ALPHA_MODE_ROP) {
+ switch (alpha_node) {
+ case PXP_2D_ALPHA0_S0:
+ as_ctrl = __raw_readl(pxp_reg_base + HW_PXP_AS_CTRL);
+ as_ctrl |= BF_PXP_AS_CTRL_ALPHA_CTRL(BV_PXP_AS_CTRL_ALPHA_CTRL__ROPs);
+ as_ctrl |= BF_PXP_AS_CTRL_ROP(alpha->rop_type);
+ pxp_writel(as_ctrl, HW_PXP_AS_CTRL);
+ break;
+ case PXP_2D_ALPHA1_S0:
+ pxp_writel(BM_PXP_ALPHA_B_CTRL_1_ROP_ENABLE |
+ BF_PXP_ALPHA_B_CTRL_1_ROP(alpha->rop_type),
+ HW_PXP_ALPHA_B_CTRL_1);
+ pxp_writel(BF_PXP_CTRL_ENABLE_ALPHA_B(1), HW_PXP_CTRL_SET);
+ break;
+ default:
+ break;
+ }
+
+ return 0;
+ }
+
+ s0_alpha = &alpha->s0_alpha;
+ s1_alpha = &alpha->s1_alpha;
+
+ alpha_ctrl.poter_duff_enable = 1;
+
+ alpha_ctrl.s0_s1_factor_mode = s1_alpha->factor_mode;
+ alpha_ctrl.s0_global_alpha_mode = s0_alpha->global_alpha_mode;
+ alpha_ctrl.s0_alpha_mode = s0_alpha->alpha_mode;
+ alpha_ctrl.s0_color_mode = s0_alpha->color_mode;
+
+ alpha_ctrl.s1_s0_factor_mode = s0_alpha->factor_mode;
+ alpha_ctrl.s1_global_alpha_mode = s1_alpha->global_alpha_mode;
+ alpha_ctrl.s1_alpha_mode = s1_alpha->alpha_mode;
+ alpha_ctrl.s1_color_mode = s1_alpha->color_mode;
+
+ alpha_ctrl.s0_global_alpha = s0_alpha->global_alpha_value;
+ alpha_ctrl.s1_global_alpha = s1_alpha->global_alpha_value;
+
+ switch (alpha_node) {
+ case PXP_2D_ALPHA0_S0:
+ pxp_writel(*(uint32_t *)&alpha_ctrl, HW_PXP_ALPHA_A_CTRL);
+ break;
+ case PXP_2D_ALPHA1_S0:
+ pxp_writel(*(uint32_t *)&alpha_ctrl, HW_PXP_ALPHA_B_CTRL);
+ pxp_writel(BF_PXP_CTRL_ENABLE_ALPHA_B(1), HW_PXP_CTRL_SET);
+ break;
+ default:
+ break;
+ }
+ }
+
+ return 0;
+}
+
+static void pxp_lut_config(struct pxp_op_info *op)
+{
+ struct pxp_task_info *task = to_pxp_task_info(op);
+ struct pxps *pxp = to_pxp_from_task(task);
+ struct pxp_proc_data *proc_data = &pxp->pxp_conf_state.proc_data;
+ int lut_op = proc_data->lut_transform;
+ u32 reg_val;
+ int i;
+ bool use_cmap = (lut_op & PXP_LUT_USE_CMAP) ? true : false;
+ u8 *cmap = proc_data->lut_map;
+ u32 entry_src;
+ u32 pix_val;
+ u8 entry[4];
+
+ /*
+ * If LUT already configured as needed, return...
+ * Unless CMAP is needed and it has been updated.
+ */
+ if ((pxp->lut_state == lut_op) &&
+ !(use_cmap && proc_data->lut_map_updated))
+ return;
+
+ if (lut_op == PXP_LUT_NONE) {
+ __raw_writel(BM_PXP_LUT_CTRL_BYPASS,
+ pxp->base + HW_PXP_LUT_CTRL);
+ } else if (((lut_op & PXP_LUT_INVERT) != 0)
+ && ((lut_op & PXP_LUT_BLACK_WHITE) != 0)) {
+ /* Fill out LUT table with inverted monochromized values */
+
+ /* clear bypass bit, set lookup mode & out mode */
+ __raw_writel(BF_PXP_LUT_CTRL_LOOKUP_MODE
+ (BV_PXP_LUT_CTRL_LOOKUP_MODE__DIRECT_Y8) |
+ BF_PXP_LUT_CTRL_OUT_MODE
+ (BV_PXP_LUT_CTRL_OUT_MODE__Y8),
+ pxp->base + HW_PXP_LUT_CTRL);
+
+ /* Initialize LUT address to 0 and set NUM_BYTES to 0 */
+ __raw_writel(0, pxp->base + HW_PXP_LUT_ADDR);
+
+ /* LUT address pointer auto-increments after each data write */
+ for (pix_val = 0; pix_val < 256; pix_val += 4) {
+ for (i = 0; i < 4; i++) {
+ entry_src = use_cmap ?
+ cmap[pix_val + i] : pix_val + i;
+ entry[i] = (entry_src < 0x80) ? 0xFF : 0x00;
+ }
+ reg_val = (entry[3] << 24) | (entry[2] << 16) |
+ (entry[1] << 8) | entry[0];
+ __raw_writel(reg_val, pxp->base + HW_PXP_LUT_DATA);
+ }
+ } else if ((lut_op & PXP_LUT_INVERT) != 0) {
+ /* Fill out LUT table with 8-bit inverted values */
+
+ /* clear bypass bit, set lookup mode & out mode */
+ __raw_writel(BF_PXP_LUT_CTRL_LOOKUP_MODE
+ (BV_PXP_LUT_CTRL_LOOKUP_MODE__DIRECT_Y8) |
+ BF_PXP_LUT_CTRL_OUT_MODE
+ (BV_PXP_LUT_CTRL_OUT_MODE__Y8),
+ pxp->base + HW_PXP_LUT_CTRL);
+
+ /* Initialize LUT address to 0 and set NUM_BYTES to 0 */
+ __raw_writel(0, pxp->base + HW_PXP_LUT_ADDR);
+
+ /* LUT address pointer auto-increments after each data write */
+ for (pix_val = 0; pix_val < 256; pix_val += 4) {
+ for (i = 0; i < 4; i++) {
+ entry_src = use_cmap ?
+ cmap[pix_val + i] : pix_val + i;
+ entry[i] = ~entry_src & 0xFF;
+ }
+ reg_val = (entry[3] << 24) | (entry[2] << 16) |
+ (entry[1] << 8) | entry[0];
+ __raw_writel(reg_val, pxp->base + HW_PXP_LUT_DATA);
+ }
+ } else if ((lut_op & PXP_LUT_BLACK_WHITE) != 0) {
+ /* Fill out LUT table with 8-bit monochromized values */
+
+ /* clear bypass bit, set lookup mode & out mode */
+ __raw_writel(BF_PXP_LUT_CTRL_LOOKUP_MODE
+ (BV_PXP_LUT_CTRL_LOOKUP_MODE__DIRECT_Y8) |
+ BF_PXP_LUT_CTRL_OUT_MODE
+ (BV_PXP_LUT_CTRL_OUT_MODE__Y8),
+ pxp->base + HW_PXP_LUT_CTRL);
+
+ /* Initialize LUT address to 0 and set NUM_BYTES to 0 */
+ __raw_writel(0, pxp->base + HW_PXP_LUT_ADDR);
+
+ /* LUT address pointer auto-increments after each data write */
+ for (pix_val = 0; pix_val < 256; pix_val += 4) {
+ for (i = 0; i < 4; i++) {
+ entry_src = use_cmap ?
+ cmap[pix_val + i] : pix_val + i;
+ entry[i] = (entry_src < 0x80) ? 0x00 : 0xFF;
+ }
+ reg_val = (entry[3] << 24) | (entry[2] << 16) |
+ (entry[1] << 8) | entry[0];
+ __raw_writel(reg_val, pxp->base + HW_PXP_LUT_DATA);
+ }
+ } else if (use_cmap) {
+ /* Fill out LUT table using colormap values */
+
+ /* clear bypass bit, set lookup mode & out mode */
+ __raw_writel(BF_PXP_LUT_CTRL_LOOKUP_MODE
+ (BV_PXP_LUT_CTRL_LOOKUP_MODE__DIRECT_Y8) |
+ BF_PXP_LUT_CTRL_OUT_MODE
+ (BV_PXP_LUT_CTRL_OUT_MODE__Y8),
+ pxp->base + HW_PXP_LUT_CTRL);
+
+ /* Initialize LUT address to 0 and set NUM_BYTES to 0 */
+ __raw_writel(0, pxp->base + HW_PXP_LUT_ADDR);
+
+ /* LUT address pointer auto-increments after each data write */
+ for (pix_val = 0; pix_val < 256; pix_val += 4) {
+ for (i = 0; i < 4; i++)
+ entry[i] = cmap[pix_val + i];
+ reg_val = (entry[3] << 24) | (entry[2] << 16) |
+ (entry[1] << 8) | entry[0];
+ __raw_writel(reg_val, pxp->base + HW_PXP_LUT_DATA);
+ }
+ }
+
+ pxp_writel(BM_PXP_CTRL_ENABLE_ROTATE1 | BM_PXP_CTRL_ENABLE_ROTATE0 |
+ BM_PXP_CTRL_ENABLE_CSC2 | BM_PXP_CTRL_ENABLE_LUT,
+ HW_PXP_CTRL_SET);
+
+ pxp->lut_state = lut_op;
+}
+
+static int pxp_2d_task_config(struct pxp_pixmap *input,
+ struct pxp_pixmap *output,
+ struct pxp_op_info *op,
+ uint32_t nodes_used)
+{
+ uint8_t position = 0;
+
+ do {
+ position = find_next_bit((unsigned long *)&nodes_used, 32, position);
+ if (position >= sizeof(uint32_t) * 8)
+ break;
+
+ switch (position) {
+ case PXP_2D_PS:
+ pxp_ps_config(input, output);
+ break;
+ case PXP_2D_AS:
+ pxp_as_config(input, output);
+ break;
+ case PXP_2D_INPUT_FETCH0:
+ case PXP_2D_INPUT_FETCH1:
+ pxp_fetch_config(input, position);
+ break;
+ case PXP_2D_CSC1:
+ pxp_csc1_config(input, true);
+ break;
+ case PXP_2D_ROTATION1:
+ pxp_rotation1_config(input);
+ break;
+ case PXP_2D_ALPHA0_S0:
+ case PXP_2D_ALPHA1_S0:
+ pxp_alpha_config(op, position);
+ break;
+ case PXP_2D_ALPHA0_S1:
+ case PXP_2D_ALPHA1_S1:
+ break;
+ case PXP_2D_CSC2:
+ pxp_csc2_config(output);
+ break;
+ case PXP_2D_LUT:
+ pxp_lut_config(op);
+ break;
+ case PXP_2D_ROTATION0:
+ pxp_rotation0_config(input);
+ break;
+ case PXP_2D_OUT:
+ pxp_out_config(output);
+ break;
+ case PXP_2D_INPUT_STORE0:
+ case PXP_2D_INPUT_STORE1:
+ pxp_store_config(output, op);
+ break;
+ default:
+ break;
+ }
+
+ position++;
+ } while (1);
+
+ return 0;
+}
+
+static void mux_config_helper(struct mux_config *path_ctrl,
+ struct edge_node *enode)
+{
+ uint32_t mux_val, mux_pos = 0;
+
+ if (enode->mux_used) {
+ do {
+ mux_pos = find_next_bit((unsigned long *)&enode->mux_used,
+ 32, mux_pos);
+ if (mux_pos >= 16)
+ break;
+
+ mux_val = get_mux_val(&enode->muxes, mux_pos);
+ pr_debug("%s: mux_pos = %d, mux_val = %d\n",
+ __func__, mux_pos, mux_val);
+ set_mux_val(path_ctrl, mux_pos, mux_val);
+
+ mux_pos++;
+ } while (1);
+ }
+}
+
+static void pxp_2d_calc_mux(uint32_t nodes, struct mux_config *path_ctrl)
+{
+ struct edge_node *enode;
+ uint8_t from = 0, to = 0;
+
+ do {
+ from = find_next_bit((unsigned long *)&nodes, 32, from);
+ if (from >= sizeof(uint32_t) * 8)
+ break;
+
+ if (to != 0) {
+ enode = adj_list[to].first;
+ while (enode) {
+ if (enode->adjvex == from) {
+ mux_config_helper(path_ctrl, enode);
+ break;
+ }
+ enode = enode->next;
+ }
+ }
+
+ to = find_next_bit((unsigned long *)&nodes, 32, from + 1);
+ if (to >= sizeof(uint32_t) * 8)
+ break;
+
+ enode = adj_list[from].first;
+ while (enode) {
+ if (enode->adjvex == to) {
+ mux_config_helper(path_ctrl, enode);
+ break;
+ }
+ enode = enode->next;
+ }
+
+ from = to + 1;
+ } while (1);
+}
+
+static int pxp_2d_op_handler(struct pxps *pxp)
+{
+ struct mux_config path_ctrl0;
+ struct pxp_proc_data *proc_data = &pxp->pxp_conf_state.proc_data;
+ struct pxp_task_info *task = &pxp->task;
+ struct pxp_op_info *op = &task->op_info;
+ struct pxp_pixmap *input, *output, *input_s0, *input_s1;
+ uint32_t possible_inputs, possible_outputs;
+ uint32_t possible_inputs_s0, possible_inputs_s1;
+ uint32_t inputs_filter_s0, inputs_filter_s1;
+ uint32_t nodes_used = 0, nodes_in_path;
+ uint32_t partial_nodes_used = 0;
+ uint32_t nodes_used_s0 = 0, nodes_used_s1 = 0;
+ uint32_t nodes_in_path_s0, nodes_in_path_s1;
+ uint32_t val;
+
+ output = &task->output[0];
+ if (!output->pitch)
+ return -EINVAL;
+
+ *(unsigned int*)&path_ctrl0 = 0xffffffff;
+
+reparse:
+ switch (task->input_num) {
+ case 0:
+ /* Fill operation: use input store engine */
+ if (is_yuv(output->format) > 1)
+ return -EINVAL;
+
+ if (output->bpp > 32)
+ return -EINVAL;
+
+ nodes_used = 1 << PXP_2D_INPUT_STORE0;
+ pxp_2d_task_config(NULL, output, op, nodes_used);
+ break;
+ case 1:
+ /* No Composite */
+ possible_inputs = (1 << PXP_2D_PS) |
+ (1 << PXP_2D_AS) |
+ (1 << PXP_2D_INPUT_FETCH0);
+ possible_outputs = (1 << PXP_2D_OUT) |
+ (1 << PXP_2D_INPUT_STORE0);
+
+ input = &task->input[0];
+ if (!input->pitch)
+ return -EINVAL;
+
+ if (input->rotate || input->flip) {
+ input->flags |= IN_NEED_ROTATE_FLIP;
+ output->rotate = input->rotate;
+ output->flip = input->flip;
+ }
+
+ if (!is_yuv(input->format) != !is_yuv(output->format))
+ input->flags |= IN_NEED_CSC;
+ else if (input->format != output->format)
+ input->flags |= IN_NEED_FMT_UNIFIED;
+
+ if ((input->rotate == 90) || (input->rotate == 270)) {
+ if ((input->crop.width != output->crop.height) ||
+ (input->crop.height != output->crop.width))
+ input->flags |= IN_NEED_SCALE;
+ } else {
+ if ((input->crop.width != output->crop.width) ||
+ (input->crop.height != output->crop.height))
+ input->flags |= IN_NEED_SCALE;
+ }
+
+ if (input->flags) {
+ /* only ps has scaling function */
+ if ((input->flags & IN_NEED_SCALE) == IN_NEED_SCALE)
+ possible_inputs = 1 << PXP_2D_PS;
+ output->flags |= (output->bpp < 32) ? OUT_NEED_SHRINK :
+ OUT_NEED_SHIFT;
+ }
+
+ filter_possible_inputs(input, &possible_inputs);
+ filter_possible_outputs(output, &possible_outputs);
+
+ if (!possible_inputs || !possible_outputs) {
+ dev_err(&pxp->pdev->dev, "unsupport 2d operation\n");
+ return -EINVAL;
+ }
+
+ if (proc_data->lut_transform)
+ nodes_used |= (1 << PXP_2D_LUT);
+
+ nodes_in_path = find_best_path(possible_inputs,
+ possible_outputs,
+ input, &nodes_used);
+
+ if (nodes_in_path & (1 << PXP_2D_ROTATION1)) {
+ clear_bit(PXP_2D_ROTATION1, (unsigned long *)&nodes_in_path);
+ set_bit(PXP_2D_ROTATION0, (unsigned long *)&nodes_in_path);
+ }
+
+ if (nodes_used & (1 << PXP_2D_ROTATION1)) {
+ clear_bit(PXP_2D_ROTATION1, (unsigned long *)&nodes_used);
+ set_bit(PXP_2D_ROTATION0, (unsigned long *)&nodes_used);
+ }
+
+ pr_debug("%s: nodes_in_path = 0x%x, nodes_used = 0x%x\n",
+ __func__, nodes_in_path, nodes_used);
+ if (!nodes_used) {
+ dev_err(&pxp->pdev->dev, "unsupport 2d operation\n");
+ return -EINVAL;
+ }
+
+ /* If use input fetch0, should use
+ * alpha b instead of alpha a */
+ if (nodes_in_path & (1 << PXP_2D_ALPHA0_S0)) {
+ if (nodes_in_path & (1 << PXP_2D_INPUT_FETCH0)) {
+ clear_bit(PXP_2D_ALPHA0_S0,
+ (unsigned long *)&nodes_in_path);
+ set_bit(PXP_2D_ALPHA1_S1,
+ (unsigned long *)&nodes_in_path);
+ }
+ }
+
+ /* In this case input read in
+ * by input fetch engine
+ */
+ if ((nodes_in_path & (1 << PXP_2D_ALPHA1_S1)) ||
+ (nodes_in_path & (1 << PXP_2D_ALPHA1_S0))) {
+ memcpy(&task->input[1], input, sizeof(*input));
+ if (input->rotate == 90 || input->rotate == 270) {
+ uint32_t temp;
+
+ input = &task->input[1];
+ input->rotate = 0;
+ input->flags = 0;
+ temp = input->width;
+ input->width = input->height;
+ input->height = temp;
+ input->pitch = input->width * (input->bpp >> 3);
+ temp = input->crop.width;
+ input->crop.width = input->crop.height;
+ input->crop.height = temp;
+ }
+
+ op->alpha_info.alpha_mode = ALPHA_MODE_ROP;
+ /* s0 AND s1 */
+ op->alpha_info.rop_type = 0x0;
+ task->input_num = 2;
+ goto reparse;
+ }
+
+ pxp_2d_calc_mux(nodes_in_path, &path_ctrl0);
+ pr_debug("%s: path_ctrl0 = 0x%x\n",
+ __func__, *(uint32_t *)&path_ctrl0);
+ pxp_2d_task_config(input, output, op, nodes_used);
+
+ if (is_yuv(input->format) && is_yuv(output->format)) {
+ val = readl(pxp_reg_base + HW_PXP_CSC1_COEF0);
+ val |= (BF_PXP_CSC1_COEF0_YCBCR_MODE(1) |
+ BF_PXP_CSC1_COEF0_BYPASS(1));
+ pxp_writel(val, HW_PXP_CSC1_COEF0);
+ }
+ break;
+ case 2:
+ /* Composite */
+ input_s0 = &task->input[0];
+ input_s1 = &task->input[1];
+ if (!input_s0->pitch || !input_s1->pitch)
+ return -EINVAL;
+
+ possible_inputs_s0 = (1 << PXP_2D_PS) |
+ (1 << PXP_2D_INPUT_FETCH0) |
+ (1 << PXP_2D_INPUT_FETCH1);
+ possible_inputs_s1 = (1 << PXP_2D_AS) |
+ (1 << PXP_2D_INPUT_FETCH0);
+ possible_outputs = (1 << PXP_2D_OUT) |
+ (1 << PXP_2D_INPUT_STORE0);
+
+ if (input_s0->rotate || input_s0->flip) {
+ input_s0->flags |= IN_NEED_ROTATE_FLIP;
+ output->rotate = input_s0->rotate;
+ output->flip = input_s0->flip;
+ }
+ if (input_s1->rotate || input_s1->flip) {
+ input_s1->flags |= IN_NEED_ROTATE_FLIP;
+ clear_bit(PXP_2D_AS,
+ (unsigned long *)&possible_inputs_s1);
+ }
+
+ if (is_yuv(input_s0->format) && is_yuv(input_s1->format))
+ return -EINVAL;
+
+ if (is_yuv(input_s0->format)){
+ /* need do yuv -> rgb conversion by csc1 */
+ possible_inputs_s0 = 1 << PXP_2D_PS;
+ input_s0->flags |= IN_NEED_CSC;
+ } else if (is_yuv(input_s1->format)) {
+ possible_inputs_s1 = 1 << PXP_2D_PS;
+ input_s1->flags |= IN_NEED_CSC;
+ }
+
+ filter_possible_inputs(input_s0, &possible_inputs_s0);
+ filter_possible_inputs(input_s1, &possible_inputs_s1);
+
+ if (!possible_inputs_s0 || !possible_inputs_s0)
+ return -EINVAL;
+
+ filter_possible_outputs(output, &possible_outputs);
+ if (!possible_outputs)
+ return -EINVAL;
+
+ pr_debug("%s: poss_s0 = 0x%x, poss_s1 = 0x%x, poss_out = 0x%x\n",
+ __func__, possible_inputs_s0, possible_inputs_s1, possible_outputs);
+
+ inputs_filter_s0 = possible_inputs_s0;
+ inputs_filter_s1 = possible_inputs_s1;
+
+ /* Using alpha0, possible cases:
+ * 1. PS --> S0, AS --> S1;
+ */
+ if (possible_inputs_s1 & (1 << PXP_2D_AS)) {
+ clear_bit(PXP_2D_INPUT_FETCH0,
+ (unsigned long *)&possible_inputs_s0);
+ clear_bit(PXP_2D_INPUT_FETCH1,
+ (unsigned long *)&possible_inputs_s0);
+ clear_bit(PXP_2D_INPUT_STORE0,
+ (unsigned long *)&possible_outputs);
+
+ if (!possible_inputs_s0 || !possible_outputs)
+ goto alpha1;
+
+ nodes_in_path_s0 = find_best_path(possible_inputs_s0,
+ 1 << PXP_2D_ALPHA0_S0,
+ input_s0,
+ &partial_nodes_used);
+ if (!nodes_in_path_s0)
+ goto alpha1;
+
+ nodes_used_s0 |= partial_nodes_used;
+ partial_nodes_used = 0;
+
+ if (is_yuv(output->format))
+ set_bit(PXP_2D_CSC2,
+ (unsigned long *)&partial_nodes_used);
+ if (output->rotate || output->flip)
+ set_bit(PXP_2D_ROTATION0,
+ (unsigned long *)&partial_nodes_used);
+
+ nodes_in_path_s0 |= find_best_path(1 << PXP_2D_ALPHA0_S0,
+ possible_outputs,
+ input_s0,
+ &partial_nodes_used);
+ if (!(nodes_in_path_s0 & possible_outputs))
+ goto alpha1;
+ nodes_used_s0 |= partial_nodes_used;
+
+ possible_inputs_s1 = (1 << PXP_2D_AS);
+ nodes_in_path_s1 = find_best_path(possible_inputs_s1,
+ 1 << PXP_2D_ALPHA0_S1,
+ input_s1,
+ &nodes_used_s1);
+ if (!nodes_in_path_s1)
+ goto alpha1;
+
+ goto config;
+ }
+alpha1:
+ partial_nodes_used = 0;
+ possible_inputs_s0 = inputs_filter_s0;
+ possible_inputs_s1 = inputs_filter_s1;
+
+ /* Using alpha1, possible cases:
+ * 1. FETCH1 --> S0, FETCH0 --> S1;
+ */
+ clear_bit(PXP_2D_PS,
+ (unsigned long *)&possible_inputs_s0);
+ clear_bit(PXP_2D_INPUT_FETCH0,
+ (unsigned long *)&possible_inputs_s0);
+ clear_bit(PXP_2D_OUT,
+ (unsigned long *)&possible_outputs);
+
+ if (!possible_inputs_s0 || !possible_outputs)
+ return -EINVAL;
+
+ nodes_in_path_s0 = find_best_path(possible_inputs_s0,
+ 1 << PXP_2D_ALPHA1_S0,
+ input_s0,
+ &partial_nodes_used);
+ pr_debug("%s: nodes_in_path_s0 = 0x%x\n", __func__, nodes_in_path_s0);
+ BUG_ON(!nodes_in_path_s0);
+
+ nodes_used_s0 |= partial_nodes_used;
+ if ((nodes_used_s0 & (1 << PXP_2D_INPUT_FETCH0)) ||
+ (nodes_used_s0 & (1 << PXP_2D_INPUT_FETCH1)))
+ clear_bit(PXP_2D_OUT, (unsigned long *)&possible_outputs);
+ else
+ clear_bit(PXP_2D_INPUT_STORE0,
+ (unsigned long *)&possible_outputs);
+ partial_nodes_used = 0;
+
+ if (is_yuv(output->format))
+ set_bit(PXP_2D_CSC2,
+ (unsigned long *)&partial_nodes_used);
+ if (output->rotate || output->flip)
+ set_bit(PXP_2D_ROTATION0,
+ (unsigned long *)&partial_nodes_used);
+
+ nodes_in_path_s0 |= find_best_path(1 << PXP_2D_ALPHA1_S0,
+ possible_outputs,
+ input_s0,
+ &partial_nodes_used);
+ BUG_ON(!(nodes_in_path_s0 & possible_outputs));
+ nodes_used_s0 |= partial_nodes_used;
+ pr_debug("%s: nodes_in_path_s0 = 0x%x, nodes_used_s0 = 0x%x\n",
+ __func__, nodes_in_path_s0, nodes_used_s0);
+
+ clear_bit(PXP_2D_AS,
+ (unsigned long *)&possible_inputs_s1);
+ BUG_ON(!possible_inputs_s1);
+
+ nodes_in_path_s1 = find_best_path(possible_inputs_s1,
+ 1 << PXP_2D_ALPHA1_S1,
+ input_s1,
+ &nodes_used_s1);
+ pr_debug("%s: poss_s1 = 0x%x, nodes_used_s1 = 0x%x\n",
+ __func__, possible_inputs_s1, nodes_used_s1);
+ BUG_ON(!nodes_in_path_s1);
+ /* To workaround an IC bug */
+ path_ctrl0.mux4_sel = 0x0;
+config:
+ if (nodes_in_path_s0 & (1 << PXP_2D_ROTATION1)) {
+ clear_bit(PXP_2D_ROTATION1, (unsigned long *)&nodes_in_path_s0);
+ set_bit(PXP_2D_ROTATION0, (unsigned long *)&nodes_in_path_s0);
+ }
+
+ pr_debug("%s: nodes_in_path_s0 = 0x%x, nodes_used_s0 = 0x%x, nodes_in_path_s1 = 0x%x, nodes_used_s1 = 0x%x\n",
+ __func__, nodes_in_path_s0, nodes_used_s0, nodes_in_path_s1, nodes_used_s1);
+ pxp_2d_calc_mux(nodes_in_path_s0, &path_ctrl0);
+ pxp_2d_calc_mux(nodes_in_path_s1, &path_ctrl0);
+
+ pr_debug("%s: s0 paddr = 0x%x, s1 paddr = 0x%x, out paddr = 0x%x\n",
+ __func__, input_s0->paddr, input_s1->paddr, output->paddr);
+
+ if (nodes_used_s0 & (1 << PXP_2D_ROTATION1)) {
+ clear_bit(PXP_2D_ROTATION1, (unsigned long *)&nodes_used_s0);
+ set_bit(PXP_2D_ROTATION0, (unsigned long *)&nodes_used_s0);
+ }
+
+ pxp_2d_task_config(input_s0, output, op, nodes_used_s0);
+ pxp_2d_task_config(input_s1, output, op, nodes_used_s1);
+ break;
+ default:
+ break;
+ }
+
+ __raw_writel(proc_data->bgcolor,
+ pxp->base + HW_PXP_PS_BACKGROUND_0);
+ pxp_set_colorkey(pxp);
+
+ if (proc_data->lut_transform && pxp_is_v3(pxp))
+ set_mux(&path_ctrl0);
+
+ pr_debug("%s: path_ctrl0 = 0x%x\n",
+ __func__, *(uint32_t *)&path_ctrl0);
+ pxp_writel(*(uint32_t *)&path_ctrl0, HW_PXP_DATA_PATH_CTRL0);
+
+ return 0;
+}
+
+/**
+ * pxp_config() - configure PxP for a processing task
+ * @pxps: PXP context.
+ * @pxp_chan: PXP channel.
+ * @return: 0 on success or negative error code on failure.
+ */
+static int pxp_config(struct pxps *pxp, struct pxp_channel *pxp_chan)
+{
+ int ret = 0;
+ struct pxp_task_info *task = &pxp->task;
+ struct pxp_op_info *op = &task->op_info;
+ struct pxp_config_data *pxp_conf_data = &pxp->pxp_conf_state;
+ struct pxp_proc_data *proc_data = &pxp_conf_data->proc_data;
+
+ switch (op->op_type) {
+ case PXP_OP_TYPE_2D:
+ pxp_writel(0xffffffff, HW_PXP_OUT_AS_ULC);
+ pxp_writel(0x0, HW_PXP_OUT_AS_LRC);
+ pxp_writel(0xffffffff, HW_PXP_OUT_PS_ULC);
+ pxp_writel(0x0, HW_PXP_OUT_PS_LRC);
+ pxp_writel(0x0, HW_PXP_INPUT_FETCH_PITCH);
+ pxp_writel(0x40000000, HW_PXP_CSC1_COEF0);
+ ret = pxp_2d_op_handler(pxp);
+ break;
+ case PXP_OP_TYPE_DITHER:
+ pxp_dithering_process(pxp);
+ if (pxp_is_v3p(pxp)) {
+ __raw_writel(
+ BM_PXP_CTRL_ENABLE |
+ BM_PXP_CTRL_ENABLE_DITHER |
+ BM_PXP_CTRL_ENABLE_CSC2 |
+ BM_PXP_CTRL_ENABLE_LUT |
+ BM_PXP_CTRL_ENABLE_ROTATE0 |
+ BM_PXP_CTRL_ENABLE_PS_AS_OUT,
+ pxp->base + HW_PXP_CTRL_SET);
+ return 0;
+ }
+ break;
+ case PXP_OP_TYPE_WFE_A:
+ pxp_luts_deactivate(pxp, proc_data->lut_sels);
+
+ if (proc_data->lut_cleanup == 0) {
+ /* We should enable histogram in standard mode
+ * in wfe_a processing for waveform mode selection
+ */
+ pxp_histogram_enable(pxp, pxp_conf_data->wfe_a_fetch_param[0].width,
+ pxp_conf_data->wfe_a_fetch_param[0].height);
+
+ pxp_luts_activate(pxp, (u64)proc_data->lut_status_1 |
+ ((u64)proc_data->lut_status_2 << 32));
+
+ /* collision detection should be always enable in standard mode */
+ pxp_collision_detection_enable(pxp, pxp_conf_data->wfe_a_fetch_param[0].width,
+ pxp_conf_data->wfe_a_fetch_param[0].height);
+ }
+
+ if (pxp->devdata && pxp->devdata->pxp_wfe_a_configure)
+ pxp->devdata->pxp_wfe_a_configure(pxp);
+ if (pxp->devdata && pxp->devdata->pxp_wfe_a_process)
+ pxp->devdata->pxp_wfe_a_process(pxp);
+ break;
+ case PXP_OP_TYPE_WFE_B:
+ pxp_wfe_b_configure(pxp);
+ pxp_wfe_b_process(pxp);
+ break;
+ default:
+ /* Unsupport */
+ ret = -EINVAL;
+ pr_err("Invalid pxp operation type passed\n");
+ break;
+ }
+
+ return ret;
+}
+
+static void pxp_clk_enable(struct pxps *pxp)
+{
+ mutex_lock(&pxp->clk_mutex);
+
+ if (pxp->clk_stat == CLK_STAT_ON) {
+ mutex_unlock(&pxp->clk_mutex);
+ return;
+ }
+
+ pm_runtime_get_sync(pxp->dev);
+
+ clk_prepare_enable(pxp->ipg_clk);
+ clk_prepare_enable(pxp->axi_clk);
+ pxp->clk_stat = CLK_STAT_ON;
+
+ mutex_unlock(&pxp->clk_mutex);
+}
+
+static void pxp_clk_disable(struct pxps *pxp)
+{
+ unsigned long flags;
+
+ mutex_lock(&pxp->clk_mutex);
+
+ if (pxp->clk_stat == CLK_STAT_OFF) {
+ mutex_unlock(&pxp->clk_mutex);
+ return;
+ }
+
+ spin_lock_irqsave(&pxp->lock, flags);
+ if ((pxp->pxp_ongoing == 0) && list_empty(&head)) {
+ spin_unlock_irqrestore(&pxp->lock, flags);
+ clk_disable_unprepare(pxp->ipg_clk);
+ clk_disable_unprepare(pxp->axi_clk);
+ pxp->clk_stat = CLK_STAT_OFF;
+ } else
+ spin_unlock_irqrestore(&pxp->lock, flags);
+
+ pm_runtime_put_sync_suspend(pxp->dev);
+
+ mutex_unlock(&pxp->clk_mutex);
+}
+
+static inline void clkoff_callback(struct work_struct *w)
+{
+ struct pxps *pxp = container_of(w, struct pxps, work);
+
+ pxp_clk_disable(pxp);
+}
+
+static void pxp_clkoff_timer(unsigned long arg)
+{
+ struct pxps *pxp = (struct pxps *)arg;
+
+ if ((pxp->pxp_ongoing == 0) && list_empty(&head))
+ schedule_work(&pxp->work);
+ else
+ mod_timer(&pxp->clk_timer,
+ jiffies + msecs_to_jiffies(timeout_in_ms));
+}
+
+static struct pxp_tx_desc *pxpdma_first_queued(struct pxp_channel *pxp_chan)
+{
+ return list_entry(pxp_chan->queue.next, struct pxp_tx_desc, list);
+}
+
+static int convert_param_to_pixmap(struct pxp_pixmap *pixmap,
+ struct pxp_layer_param *param)
+{
+ if (!param->width || !param->height)
+ return -EINVAL;
+
+ pixmap->width = param->width;
+ pixmap->height = param->height;
+ pixmap->format = param->pixel_fmt;
+ pixmap->paddr = param->paddr;
+ pixmap->bpp = get_bpp_from_fmt(pixmap->format);
+
+ if (pxp_legacy) {
+ pixmap->pitch = (param->stride) ? (param->stride * pixmap->bpp >> 3) :
+ (param->width * pixmap->bpp >> 3);
+ } else {
+ if (!param->stride || (param->stride == param->width))
+ pixmap->pitch = param->width * pixmap->bpp >> 3;
+ else
+ pixmap->pitch = param->stride;
+ }
+
+ pixmap->crop.x = param->crop.left;
+ pixmap->crop.y = param->crop.top;
+ pixmap->crop.width = param->crop.width;
+ pixmap->crop.height = param->crop.height;
+
+ pixmap->g_alpha.color_key_enable = param->color_key_enable;
+ pixmap->g_alpha.combine_enable = param->combine_enable;
+ pixmap->g_alpha.global_alpha_enable = param->global_alpha_enable;
+ pixmap->g_alpha.global_override = param->global_override;
+ pixmap->g_alpha.global_alpha = param->global_alpha;
+ pixmap->g_alpha.alpha_invert = param->alpha_invert;
+ pixmap->g_alpha.local_alpha_enable = param->local_alpha_enable;
+ pixmap->g_alpha.comp_mask = param->comp_mask;
+
+ return 0;
+}
+
+/* called with pxp_chan->lock held */
+static void __pxpdma_dostart(struct pxp_channel *pxp_chan)
+{
+ struct pxp_dma *pxp_dma = to_pxp_dma(pxp_chan->dma_chan.device);
+ struct pxps *pxp = to_pxp(pxp_dma);
+ struct pxp_config_data *config_data = &pxp->pxp_conf_state;
+ struct pxp_proc_data *proc_data = &config_data->proc_data;
+ struct pxp_tx_desc *desc;
+ struct pxp_tx_desc *child;
+ struct pxp_task_info *task = &pxp->task;
+ struct pxp_op_info *op = &task->op_info;
+ struct pxp_alpha_info *alpha = &op->alpha_info;
+ struct pxp_layer_param *param = NULL;
+ struct pxp_pixmap *input, *output;
+ int i = 0, ret;
+ bool combine_enable = false;
+
+ memset(&pxp->pxp_conf_state.s0_param, 0, sizeof(struct pxp_layer_param));
+ memset(&pxp->pxp_conf_state.out_param, 0, sizeof(struct pxp_layer_param));
+ memset(pxp->pxp_conf_state.ol_param, 0, sizeof(struct pxp_layer_param));
+ memset(&pxp->pxp_conf_state.proc_data, 0, sizeof(struct pxp_proc_data));
+
+ memset(task, 0, sizeof(*task));
+ /* S0 */
+ desc = list_first_entry(&head, struct pxp_tx_desc, list);
+ memcpy(&pxp->pxp_conf_state.s0_param,
+ &desc->layer_param.s0_param, sizeof(struct pxp_layer_param));
+ memcpy(&pxp->pxp_conf_state.proc_data,
+ &desc->proc_data, sizeof(struct pxp_proc_data));
+
+ if (proc_data->combine_enable)
+ alpha_blending_version = PXP_ALPHA_BLENDING_V2;
+ else
+ alpha_blending_version = PXP_ALPHA_BLENDING_NONE;
+
+ pxp_legacy = (proc_data->pxp_legacy) ? true : false;
+
+ /* Save PxP configuration */
+ list_for_each_entry(child, &desc->tx_list, list) {
+ if (i == 0) { /* Output */
+ memcpy(&pxp->pxp_conf_state.out_param,
+ &child->layer_param.out_param,
+ sizeof(struct pxp_layer_param));
+ } else if (i == 1) { /* Overlay */
+ memcpy(&pxp->pxp_conf_state.ol_param[i - 1],
+ &child->layer_param.ol_param,
+ sizeof(struct pxp_layer_param));
+ if (pxp->pxp_conf_state.ol_param[i - 1].width != 0 &&
+ pxp->pxp_conf_state.ol_param[i - 1].height != 0) {
+ if (pxp->pxp_conf_state.ol_param[i - 1].combine_enable)
+ alpha_blending_version = PXP_ALPHA_BLENDING_V1;
+ }
+ }
+
+ if (proc_data->engine_enable & PXP_ENABLE_DITHER) {
+ if (child->layer_param.processing_param.flag & PXP_BUF_FLAG_DITHER_FETCH0)
+ memcpy(&pxp->pxp_conf_state.dither_fetch_param[0],
+ &child->layer_param.processing_param,
+ sizeof(struct pxp_layer_param));
+ if (child->layer_param.processing_param.flag & PXP_BUF_FLAG_DITHER_FETCH1)
+ memcpy(&pxp->pxp_conf_state.dither_fetch_param[1],
+ &child->layer_param.processing_param,
+ sizeof(struct pxp_layer_param));
+ if (child->layer_param.processing_param.flag & PXP_BUF_FLAG_DITHER_STORE0)
+ memcpy(&pxp->pxp_conf_state.dither_store_param[0],
+ &child->layer_param.processing_param,
+ sizeof(struct pxp_layer_param));
+ if (child->layer_param.processing_param.flag & PXP_BUF_FLAG_DITHER_STORE1)
+ memcpy(&pxp->pxp_conf_state.dither_store_param[1],
+ &child->layer_param.processing_param,
+ sizeof(struct pxp_layer_param));
+ op->op_type = PXP_OP_TYPE_DITHER;
+ }
+
+ if (proc_data->engine_enable & PXP_ENABLE_WFE_A) {
+ if (child->layer_param.processing_param.flag & PXP_BUF_FLAG_WFE_A_FETCH0)
+ memcpy(&pxp->pxp_conf_state.wfe_a_fetch_param[0],
+ &child->layer_param.processing_param,
+ sizeof(struct pxp_layer_param));
+ if (child->layer_param.processing_param.flag & PXP_BUF_FLAG_WFE_A_FETCH1)
+ memcpy(&pxp->pxp_conf_state.wfe_a_fetch_param[1],
+ &child->layer_param.processing_param,
+ sizeof(struct pxp_layer_param));
+ if (child->layer_param.processing_param.flag & PXP_BUF_FLAG_WFE_A_STORE0)
+ memcpy(&pxp->pxp_conf_state.wfe_a_store_param[0],
+ &child->layer_param.processing_param,
+ sizeof(struct pxp_layer_param));
+ if (child->layer_param.processing_param.flag & PXP_BUF_FLAG_WFE_A_STORE1)
+ memcpy(&pxp->pxp_conf_state.wfe_a_store_param[1],
+ &child->layer_param.processing_param,
+ sizeof(struct pxp_layer_param));
+ op->op_type = PXP_OP_TYPE_WFE_A;
+ }
+
+ if (proc_data->engine_enable & PXP_ENABLE_WFE_B) {
+ if (child->layer_param.processing_param.flag & PXP_BUF_FLAG_WFE_B_FETCH0)
+ memcpy(&pxp->pxp_conf_state.wfe_b_fetch_param[0],
+ &child->layer_param.processing_param,
+ sizeof(struct pxp_layer_param));
+ if (child->layer_param.processing_param.flag & PXP_BUF_FLAG_WFE_B_FETCH1)
+ memcpy(&pxp->pxp_conf_state.wfe_b_fetch_param[1],
+ &child->layer_param.processing_param,
+ sizeof(struct pxp_layer_param));
+ if (child->layer_param.processing_param.flag & PXP_BUF_FLAG_WFE_B_STORE0)
+ memcpy(&pxp->pxp_conf_state.wfe_b_store_param[0],
+ &child->layer_param.processing_param,
+ sizeof(struct pxp_layer_param));
+ if (child->layer_param.processing_param.flag & PXP_BUF_FLAG_WFE_B_STORE1)
+ memcpy(&pxp->pxp_conf_state.wfe_b_store_param[1],
+ &child->layer_param.processing_param,
+ sizeof(struct pxp_layer_param));
+ op->op_type = PXP_OP_TYPE_WFE_B;
+ }
+
+ i++;
+ }
+
+ if (!op->op_type) {
+ op->op_type = PXP_OP_TYPE_2D;
+
+ if ((alpha_blending_version == PXP_ALPHA_BLENDING_V1) ||
+ (alpha_blending_version == PXP_ALPHA_BLENDING_V2))
+ combine_enable = true;
+
+ if (combine_enable)
+ task->input_num = 2;
+ else if (proc_data->fill_en)
+ task->input_num = 0;
+ else
+ task->input_num = 1;
+
+ output = &task->output[0];
+ switch (task->input_num) {
+ case 0:
+ op->fill_en = 1;
+ op->fill_data = proc_data->bgcolor;
+ break;
+ case 1:
+ param = &pxp->pxp_conf_state.s0_param;
+ input = &task->input[0];
+
+ ret = convert_param_to_pixmap(input, param);
+ if (ret < 0) {
+ param = &pxp->pxp_conf_state.ol_param[0];
+ ret = convert_param_to_pixmap(input, param);
+ BUG_ON(ret < 0);
+ } else {
+ input->crop.x = proc_data->srect.left;
+ input->crop.y = proc_data->srect.top;
+ input->crop.width = proc_data->srect.width;
+ input->crop.height = proc_data->srect.height;
+ }
+
+ input->rotate = proc_data->rotate;
+ input->flip = (proc_data->hflip) ? PXP_H_FLIP :
+ (proc_data->vflip) ? PXP_V_FLIP : 0;
+ break;
+ case 2:
+ /* s0 */
+ param = &pxp->pxp_conf_state.s0_param;
+ input = &task->input[0];
+
+ ret = convert_param_to_pixmap(input, param);
+ BUG_ON(ret < 0);
+ input->crop.x = proc_data->srect.left;
+ input->crop.y = proc_data->srect.top;
+ input->crop.width = proc_data->srect.width;
+ input->crop.height = proc_data->srect.height;
+ alpha->s0_alpha = param->alpha;
+
+ input->rotate = proc_data->rotate;
+ input->flip = (proc_data->hflip) ? PXP_H_FLIP :
+ (proc_data->vflip) ? PXP_V_FLIP : 0;
+
+ /* overlay */
+ param = &pxp->pxp_conf_state.ol_param[0];
+ input = &task->input[1];
+
+ ret = convert_param_to_pixmap(input, param);
+ BUG_ON(ret < 0);
+ alpha->s1_alpha = param->alpha;
+ alpha->alpha_mode = proc_data->alpha_mode;
+ break;
+ }
+
+ param = &pxp->pxp_conf_state.out_param;
+ ret = convert_param_to_pixmap(output, param);
+ BUG_ON(ret < 0);
+
+ output->crop.x = proc_data->drect.left;
+ output->crop.y = proc_data->drect.top;
+ output->crop.width = proc_data->drect.width;
+ output->crop.height = proc_data->drect.height;
+ }
+
+ pr_debug("%s:%d S0 w/h %d/%d paddr %08x\n", __func__, __LINE__,
+ pxp->pxp_conf_state.s0_param.width,
+ pxp->pxp_conf_state.s0_param.height,
+ pxp->pxp_conf_state.s0_param.paddr);
+ pr_debug("%s:%d S0 crop (top, left)=(%d, %d), (width, height)=(%d, %d)\n",
+ __func__, __LINE__,
+ pxp->pxp_conf_state.s0_param.crop.top,
+ pxp->pxp_conf_state.s0_param.crop.left,
+ pxp->pxp_conf_state.s0_param.crop.width,
+ pxp->pxp_conf_state.s0_param.crop.height);
+ pr_debug("%s:%d OUT w/h %d/%d paddr %08x\n", __func__, __LINE__,
+ pxp->pxp_conf_state.out_param.width,
+ pxp->pxp_conf_state.out_param.height,
+ pxp->pxp_conf_state.out_param.paddr);
+}
+
+static int pxpdma_dostart_work(struct pxps *pxp)
+{
+ int ret;
+ struct pxp_channel *pxp_chan = NULL;
+ unsigned long flags;
+ dma_async_tx_callback callback;
+ void *callback_param;
+ struct pxp_tx_desc *desc = NULL;
+ struct pxp_tx_desc *child, *_child;
+ struct pxp_config_data *config_data = &pxp->pxp_conf_state;
+ struct pxp_proc_data *proc_data = &config_data->proc_data;
+
+ spin_lock_irqsave(&pxp->lock, flags);
+
+ desc = list_entry(head.next, struct pxp_tx_desc, list);
+ pxp_chan = to_pxp_channel(desc->txd.chan);
+
+ __pxpdma_dostart(pxp_chan);
+
+ /* Configure PxP */
+ ret = pxp_config(pxp, pxp_chan);
+ if (ret) {
+ callback = desc->txd.callback;
+ callback_param = desc->txd.callback_param;
+
+ callback(callback_param);
+
+ /* Unsupport operation */
+ list_for_each_entry_safe(child, _child, &desc->tx_list, list) {
+ list_del_init(&child->list);
+ kmem_cache_free(tx_desc_cache, (void *)child);
+ }
+ list_del_init(&desc->list);
+ kmem_cache_free(tx_desc_cache, (void *)desc);
+
+ spin_unlock_irqrestore(&pxp->lock, flags);
+ return -EINVAL;
+ }
+
+ if (proc_data->working_mode & PXP_MODE_STANDARD) {
+ if(!pxp_is_v3p(pxp) || !(proc_data->engine_enable & PXP_ENABLE_DITHER))
+ pxp_start2(pxp);
+ } else
+ pxp_start(pxp);
+
+ spin_unlock_irqrestore(&pxp->lock, flags);
+
+ return 0;
+}
+
+static void pxpdma_dequeue(struct pxp_channel *pxp_chan, struct pxps *pxp)
+{
+ unsigned long flags;
+ struct pxp_tx_desc *desc = NULL;
+
+ do {
+ desc = pxpdma_first_queued(pxp_chan);
+ spin_lock_irqsave(&pxp->lock, flags);
+ list_move_tail(&desc->list, &head);
+ spin_unlock_irqrestore(&pxp->lock, flags);
+ } while (!list_empty(&pxp_chan->queue));
+}
+
+static dma_cookie_t pxp_tx_submit(struct dma_async_tx_descriptor *tx)
+{
+ struct pxp_tx_desc *desc = to_tx_desc(tx);
+ struct pxp_channel *pxp_chan = to_pxp_channel(tx->chan);
+ dma_cookie_t cookie;
+
+ dev_dbg(&pxp_chan->dma_chan.dev->device, "received TX\n");
+
+ /* pxp_chan->lock can be taken under ichan->lock, but not v.v. */
+ spin_lock(&pxp_chan->lock);
+
+ cookie = pxp_chan->dma_chan.cookie;
+
+ if (++cookie < 0)
+ cookie = 1;
+
+ /* from dmaengine.h: "last cookie value returned to client" */
+ pxp_chan->dma_chan.cookie = cookie;
+ tx->cookie = cookie;
+
+ /* Here we add the tx descriptor to our PxP task queue. */
+ list_add_tail(&desc->list, &pxp_chan->queue);
+
+ spin_unlock(&pxp_chan->lock);
+
+ dev_dbg(&pxp_chan->dma_chan.dev->device, "done TX\n");
+
+ return cookie;
+}
+
+/**
+ * pxp_init_channel() - initialize a PXP channel.
+ * @pxp_dma: PXP DMA context.
+ * @pchan: pointer to the channel object.
+ * @return 0 on success or negative error code on failure.
+ */
+static int pxp_init_channel(struct pxp_dma *pxp_dma,
+ struct pxp_channel *pxp_chan)
+{
+ int ret = 0;
+
+ /*
+ * We are using _virtual_ channel here.
+ * Each channel contains all parameters of corresponding layers
+ * for one transaction; each layer is represented as one descriptor
+ * (i.e., pxp_tx_desc) here.
+ */
+
+ INIT_LIST_HEAD(&pxp_chan->queue);
+
+ return ret;
+}
+
+static irqreturn_t pxp_irq(int irq, void *dev_id)
+{
+ struct pxps *pxp = dev_id;
+ struct pxp_channel *pxp_chan;
+ struct pxp_tx_desc *desc;
+ struct pxp_tx_desc *child, *_child;
+ dma_async_tx_callback callback;
+ void *callback_param;
+ unsigned long flags;
+ u32 hist_status;
+ int pxp_irq_status = 0;
+
+ dump_pxp_reg(pxp);
+
+ if (__raw_readl(pxp->base + HW_PXP_STAT) & BM_PXP_STAT_IRQ0)
+ __raw_writel(BM_PXP_STAT_IRQ0, pxp->base + HW_PXP_STAT_CLR);
+ else {
+ int irq_clr = 0;
+
+ pxp_irq_status = __raw_readl(pxp->base + HW_PXP_IRQ);
+ BUG_ON(!pxp_irq_status);
+
+ if (pxp_irq_status & BM_PXP_IRQ_FIRST_CH0_PREFETCH_IRQ)
+ irq_clr |= BM_PXP_IRQ_FIRST_CH0_PREFETCH_IRQ;
+ if (pxp_irq_status & BM_PXP_IRQ_FIRST_CH1_PREFETCH_IRQ)
+ irq_clr |= BM_PXP_IRQ_FIRST_CH1_PREFETCH_IRQ;
+ if (pxp_irq_status & BM_PXP_IRQ_FIRST_CH0_STORE_IRQ)
+ irq_clr |= BM_PXP_IRQ_FIRST_CH0_STORE_IRQ;
+ if (pxp_irq_status & BM_PXP_IRQ_FIRST_CH1_STORE_IRQ)
+ irq_clr |= BM_PXP_IRQ_FIRST_CH1_STORE_IRQ;
+ if (pxp_irq_status & BM_PXP_IRQ_FIRST_STORE_IRQ)
+ irq_clr |= BM_PXP_IRQ_FIRST_STORE_IRQ;
+
+ if (pxp_irq_status & BM_PXP_IRQ_WFE_B_STORE_IRQ)
+ irq_clr |= BM_PXP_IRQ_WFE_B_STORE_IRQ;
+ if (pxp_irq_status & BM_PXP_IRQ_WFE_A_STORE_IRQ)
+ irq_clr |= BM_PXP_IRQ_WFE_A_STORE_IRQ;
+ if (pxp_irq_status & BM_PXP_IRQ_DITHER_STORE_IRQ)
+ irq_clr |= BM_PXP_IRQ_DITHER_STORE_IRQ;
+
+ if (pxp_irq_status & BM_PXP_IRQ_WFE_A_CH0_STORE_IRQ)
+ irq_clr |= BM_PXP_IRQ_WFE_A_CH0_STORE_IRQ;
+ if (pxp_irq_status & BM_PXP_IRQ_WFE_A_CH1_STORE_IRQ)
+ irq_clr |= BM_PXP_IRQ_WFE_A_CH1_STORE_IRQ;
+
+ if (pxp_irq_status & BM_PXP_IRQ_WFE_B_CH0_STORE_IRQ)
+ irq_clr |= BM_PXP_IRQ_WFE_B_CH0_STORE_IRQ;
+ if (pxp_irq_status & BM_PXP_IRQ_WFE_B_CH1_STORE_IRQ)
+ irq_clr |= BM_PXP_IRQ_WFE_B_CH1_STORE_IRQ;
+
+ if (pxp_irq_status & BM_PXP_IRQ_DITHER_CH0_PREFETCH_IRQ)
+ irq_clr |= BM_PXP_IRQ_DITHER_CH0_PREFETCH_IRQ;
+ if (pxp_irq_status & BM_PXP_IRQ_DITHER_CH1_PREFETCH_IRQ)
+ irq_clr |= BM_PXP_IRQ_DITHER_CH1_PREFETCH_IRQ;
+ if (pxp_irq_status & BM_PXP_IRQ_DITHER_CH0_STORE_IRQ)
+ irq_clr |= BM_PXP_IRQ_DITHER_CH0_STORE_IRQ;
+ if (pxp_irq_status & BM_PXP_IRQ_DITHER_CH1_STORE_IRQ)
+ irq_clr |= BM_PXP_IRQ_DITHER_CH1_STORE_IRQ;
+ /*XXX other irqs status clear should be added below */
+
+ __raw_writel(irq_clr, pxp->base + HW_PXP_IRQ_CLR);
+
+ pxp_writel(BM_PXP_CTRL_ENABLE, HW_PXP_CTRL_CLR);
+ }
+ pxp_collision_status_report(pxp, &col_info);
+ pxp_histogram_status_report(pxp, &hist_status);
+ /*XXX before a new update operation, we should
+ * always clear all the collision information
+ */
+ pxp_collision_detection_disable(pxp);
+ pxp_histogram_disable(pxp);
+
+ pxp_writel(0x0, HW_PXP_CTRL);
+ pxp_soft_reset(pxp);
+ if (pxp->devdata && pxp->devdata->pxp_data_path_config)
+ pxp->devdata->pxp_data_path_config(pxp);
+ __raw_writel(0xffff, pxp->base + HW_PXP_IRQ_MASK);
+
+ spin_lock_irqsave(&pxp->lock, flags);
+ if (list_empty(&head)) {
+ pxp->pxp_ongoing = 0;
+ spin_unlock_irqrestore(&pxp->lock, flags);
+ return IRQ_NONE;
+ }
+
+ /* Get descriptor and call callback */
+ desc = list_entry(head.next, struct pxp_tx_desc, list);
+ pxp_chan = to_pxp_channel(desc->txd.chan);
+
+ pxp_chan->completed = desc->txd.cookie;
+
+ callback = desc->txd.callback;
+ callback_param = desc->txd.callback_param;
+
+ /* Send histogram status back to caller */
+ desc->hist_status = hist_status;
+
+ if ((desc->txd.flags & DMA_PREP_INTERRUPT) && callback)
+ callback(callback_param);
+
+ pxp_chan->status = PXP_CHANNEL_INITIALIZED;
+
+ list_for_each_entry_safe(child, _child, &desc->tx_list, list) {
+ list_del_init(&child->list);
+ kmem_cache_free(tx_desc_cache, (void *)child);
+ }
+ list_del_init(&desc->list);
+ kmem_cache_free(tx_desc_cache, (void *)desc);
+
+ complete(&pxp->complete);
+ pxp->pxp_ongoing = 0;
+ mod_timer(&pxp->clk_timer, jiffies + msecs_to_jiffies(timeout_in_ms));
+
+ spin_unlock_irqrestore(&pxp->lock, flags);
+
+ return IRQ_HANDLED;
+}
+
+/* allocate/free dma tx descriptor dynamically*/
+static struct pxp_tx_desc *pxpdma_desc_alloc(struct pxp_channel *pxp_chan)
+{
+ struct pxp_tx_desc *desc = NULL;
+ struct dma_async_tx_descriptor *txd = NULL;
+
+ desc = kmem_cache_alloc(tx_desc_cache, GFP_KERNEL | __GFP_ZERO);
+ if (desc == NULL)
+ return NULL;
+
+ INIT_LIST_HEAD(&desc->list);
+ INIT_LIST_HEAD(&desc->tx_list);
+ txd = &desc->txd;
+ dma_async_tx_descriptor_init(txd, &pxp_chan->dma_chan);
+ txd->tx_submit = pxp_tx_submit;
+
+ return desc;
+}
+
+
+/* Allocate and initialise a transfer descriptor. */
+static struct dma_async_tx_descriptor *pxp_prep_slave_sg(struct dma_chan *chan,
+ struct scatterlist
+ *sgl,
+ unsigned int sg_len,
+ enum
+ dma_transfer_direction
+ direction,
+ unsigned long tx_flags,
+ void *context)
+{
+ struct pxp_channel *pxp_chan = to_pxp_channel(chan);
+ struct pxp_dma *pxp_dma = to_pxp_dma(chan->device);
+ struct pxps *pxp = to_pxp(pxp_dma);
+ struct pxp_tx_desc *pos = NULL, *next = NULL;
+ struct pxp_tx_desc *desc = NULL;
+ struct pxp_tx_desc *first = NULL, *prev = NULL;
+ struct scatterlist *sg;
+ dma_addr_t phys_addr;
+ int i;
+
+ if (direction != DMA_DEV_TO_MEM && direction != DMA_MEM_TO_DEV) {
+ dev_err(chan->device->dev, "Invalid DMA direction %d!\n",
+ direction);
+ return NULL;
+ }
+
+ if (unlikely(sg_len < 2))
+ return NULL;
+
+ for_each_sg(sgl, sg, sg_len, i) {
+ desc = pxpdma_desc_alloc(pxp_chan);
+ if (!desc) {
+ dev_err(chan->device->dev, "no enough memory to allocate tx descriptor\n");
+
+ if (first) {
+ list_for_each_entry_safe(pos, next, &first->tx_list, list) {
+ list_del_init(&pos->list);
+ kmem_cache_free(tx_desc_cache, (void*)pos);
+ }
+ list_del_init(&first->list);
+ kmem_cache_free(tx_desc_cache, (void*)first);
+ }
+
+ return NULL;
+ }
+
+ phys_addr = sg_dma_address(sg);
+
+ if (!first) {
+ first = desc;
+
+ desc->layer_param.s0_param.paddr = phys_addr;
+ } else {
+ list_add_tail(&desc->list, &first->tx_list);
+ prev->next = desc;
+ desc->next = NULL;
+
+ if (i == 1)
+ desc->layer_param.out_param.paddr = phys_addr;
+ else
+ desc->layer_param.ol_param.paddr = phys_addr;
+ }
+
+ prev = desc;
+ }
+
+ pxp->pxp_conf_state.layer_nr = sg_len;
+ first->txd.flags = tx_flags;
+ first->len = sg_len;
+ pr_debug("%s:%d first %p, first->len %d, flags %08x\n",
+ __func__, __LINE__, first, first->len, first->txd.flags);
+
+ return &first->txd;
+}
+
+static void pxp_issue_pending(struct dma_chan *chan)
+{
+ struct pxp_channel *pxp_chan = to_pxp_channel(chan);
+ struct pxp_dma *pxp_dma = to_pxp_dma(chan->device);
+ struct pxps *pxp = to_pxp(pxp_dma);
+
+ spin_lock(&pxp_chan->lock);
+
+ if (list_empty(&pxp_chan->queue)) {
+ spin_unlock(&pxp_chan->lock);
+ return;
+ }
+
+ pxpdma_dequeue(pxp_chan, pxp);
+ pxp_chan->status = PXP_CHANNEL_READY;
+
+ spin_unlock(&pxp_chan->lock);
+
+ pxp_clk_enable(pxp);
+ wake_up_interruptible(&pxp->thread_waitq);
+}
+
+static void __pxp_terminate_all(struct dma_chan *chan)
+{
+ struct pxp_channel *pxp_chan = to_pxp_channel(chan);
+ pxp_chan->status = PXP_CHANNEL_INITIALIZED;
+}
+
+static int pxp_device_terminate_all(struct dma_chan *chan)
+{
+ struct pxp_channel *pxp_chan = to_pxp_channel(chan);
+
+ spin_lock(&pxp_chan->lock);
+ __pxp_terminate_all(chan);
+ spin_unlock(&pxp_chan->lock);
+
+ return 0;
+}
+
+static int pxp_alloc_chan_resources(struct dma_chan *chan)
+{
+ struct pxp_channel *pxp_chan = to_pxp_channel(chan);
+ struct pxp_dma *pxp_dma = to_pxp_dma(chan->device);
+ int ret;
+
+ /* dmaengine.c now guarantees to only offer free channels */
+ BUG_ON(chan->client_count > 1);
+ WARN_ON(pxp_chan->status != PXP_CHANNEL_FREE);
+
+ chan->cookie = 1;
+ pxp_chan->completed = -ENXIO;
+
+ pr_debug("%s dma_chan.chan_id %d\n", __func__, chan->chan_id);
+ ret = pxp_init_channel(pxp_dma, pxp_chan);
+ if (ret < 0)
+ goto err_chan;
+
+ pxp_chan->status = PXP_CHANNEL_INITIALIZED;
+
+ dev_dbg(&chan->dev->device, "Found channel 0x%x, irq %d\n",
+ chan->chan_id, pxp_chan->eof_irq);
+
+ return ret;
+
+err_chan:
+ return ret;
+}
+
+static void pxp_free_chan_resources(struct dma_chan *chan)
+{
+ struct pxp_channel *pxp_chan = to_pxp_channel(chan);
+
+ spin_lock(&pxp_chan->lock);
+
+ __pxp_terminate_all(chan);
+
+ pxp_chan->status = PXP_CHANNEL_FREE;
+
+ spin_unlock(&pxp_chan->lock);
+}
+
+static enum dma_status pxp_tx_status(struct dma_chan *chan,
+ dma_cookie_t cookie,
+ struct dma_tx_state *txstate)
+{
+ struct pxp_channel *pxp_chan = to_pxp_channel(chan);
+
+ if (cookie != chan->cookie)
+ return DMA_ERROR;
+
+ if (txstate) {
+ txstate->last = pxp_chan->completed;
+ txstate->used = chan->cookie;
+ txstate->residue = 0;
+ }
+ return DMA_COMPLETE;
+}
+
+static void pxp_data_path_config_v3p(struct pxps *pxp)
+{
+ u32 val = 0;
+
+ __raw_writel(
+ BF_PXP_DATA_PATH_CTRL0_MUX15_SEL(0)|
+ BF_PXP_DATA_PATH_CTRL0_MUX14_SEL(1)|
+ BF_PXP_DATA_PATH_CTRL0_MUX13_SEL(0)|
+ BF_PXP_DATA_PATH_CTRL0_MUX12_SEL(0)|
+ BF_PXP_DATA_PATH_CTRL0_MUX11_SEL(0)|
+ BF_PXP_DATA_PATH_CTRL0_MUX10_SEL(0)|
+ BF_PXP_DATA_PATH_CTRL0_MUX9_SEL(1)|
+ BF_PXP_DATA_PATH_CTRL0_MUX8_SEL(0)|
+ BF_PXP_DATA_PATH_CTRL0_MUX7_SEL(0)|
+ BF_PXP_DATA_PATH_CTRL0_MUX6_SEL(0)|
+ BF_PXP_DATA_PATH_CTRL0_MUX5_SEL(0)|
+ BF_PXP_DATA_PATH_CTRL0_MUX4_SEL(0)|
+ BF_PXP_DATA_PATH_CTRL0_MUX3_SEL(0)|
+ BF_PXP_DATA_PATH_CTRL0_MUX2_SEL(0)|
+ BF_PXP_DATA_PATH_CTRL0_MUX1_SEL(0)|
+ BF_PXP_DATA_PATH_CTRL0_MUX0_SEL(0),
+ pxp->base + HW_PXP_DATA_PATH_CTRL0);
+
+ /*
+ * MUX17: HIST_B as histogram: 0: output buffer, 1: wfe_store
+ * MUX16: HIST_A as collision: 0: output buffer, 1: wfe_store
+ */
+ if (pxp_is_v3(pxp))
+ val = BF_PXP_DATA_PATH_CTRL1_MUX17_SEL(1)|
+ BF_PXP_DATA_PATH_CTRL1_MUX16_SEL(0);
+ else if (pxp_is_v3p(pxp))
+ val = BF_PXP_DATA_PATH_CTRL1_MUX17_SEL(1)|
+ BF_PXP_DATA_PATH_CTRL1_MUX16_SEL(1);
+ __raw_writel(val, pxp->base + HW_PXP_DATA_PATH_CTRL1);
+}
+
+static void pxp_soft_reset(struct pxps *pxp)
+{
+ __raw_writel(BM_PXP_CTRL_SFTRST, pxp->base + HW_PXP_CTRL_CLR);
+ __raw_writel(BM_PXP_CTRL_CLKGATE, pxp->base + HW_PXP_CTRL_CLR);
+
+ __raw_writel(BM_PXP_CTRL_SFTRST, pxp->base + HW_PXP_CTRL_SET);
+ while (!(__raw_readl(pxp->base + HW_PXP_CTRL) & BM_PXP_CTRL_CLKGATE))
+ dev_dbg(pxp->dev, "%s: wait for clock gate off", __func__);
+
+ __raw_writel(BM_PXP_CTRL_SFTRST, pxp->base + HW_PXP_CTRL_CLR);
+ __raw_writel(BM_PXP_CTRL_CLKGATE, pxp->base + HW_PXP_CTRL_CLR);
+}
+
+static void pxp_sram_init(struct pxps *pxp, u32 select,
+ u32 buffer_addr, u32 length)
+{
+ u32 i;
+
+ __raw_writel(
+ BF_PXP_INIT_MEM_CTRL_ADDR(0) |
+ BF_PXP_INIT_MEM_CTRL_SELECT(select) |
+ BF_PXP_INIT_MEM_CTRL_START(1),
+ pxp->base + HW_PXP_INIT_MEM_CTRL);
+
+ if ((select == WFE_A) || (select == WFE_B)) {
+ for (i = 0; i < length / 2; i++) {
+ __raw_writel(*(((u32*)buffer_addr) + 2 * i + 1),
+ pxp->base + HW_PXP_INIT_MEM_DATA_HIGH);
+
+ __raw_writel(*(((u32*)buffer_addr) + 2 * i),
+ pxp->base + HW_PXP_INIT_MEM_DATA);
+ }
+ } else {
+ for (i = 0; i < length; i++) {
+ __raw_writel(*(((u32*) buffer_addr) + i),
+ pxp->base + HW_PXP_INIT_MEM_DATA);
+ }
+ }
+
+ __raw_writel(
+ BF_PXP_INIT_MEM_CTRL_ADDR(0) |
+ BF_PXP_INIT_MEM_CTRL_SELECT(select) |
+ BF_PXP_INIT_MEM_CTRL_START(0),
+ pxp->base + HW_PXP_INIT_MEM_CTRL);
+}
+
+/*
+ * wfe a configuration
+ * configure wfe a engine for waveform processing
+ * including its fetch and store module
+ */
+static void pxp_wfe_a_configure(struct pxps *pxp)
+{
+ struct pxp_config_data *pxp_conf = &pxp->pxp_conf_state;
+ struct pxp_proc_data *proc_data = &pxp_conf->proc_data;
+
+ /* FETCH */
+ __raw_writel(
+ BF_PXP_WFA_FETCH_CTRL_BF1_EN(1) |
+ BF_PXP_WFA_FETCH_CTRL_BF1_HSK_MODE(0) |
+ BF_PXP_WFA_FETCH_CTRL_BF1_BYTES_PP(0) |
+ BF_PXP_WFA_FETCH_CTRL_BF1_LINE_MODE(0) |
+ BF_PXP_WFA_FETCH_CTRL_BF1_SRAM_IF(0) |
+ BF_PXP_WFA_FETCH_CTRL_BF1_BURST_LEN(0) |
+ BF_PXP_WFA_FETCH_CTRL_BF1_BYPASS_MODE(0) |
+ BF_PXP_WFA_FETCH_CTRL_BF2_EN(1) |
+ BF_PXP_WFA_FETCH_CTRL_BF2_HSK_MODE(0) |
+ BF_PXP_WFA_FETCH_CTRL_BF2_BYTES_PP(1) |
+ BF_PXP_WFA_FETCH_CTRL_BF2_LINE_MODE(0) |
+ BF_PXP_WFA_FETCH_CTRL_BF2_SRAM_IF(0) |
+ BF_PXP_WFA_FETCH_CTRL_BF2_BURST_LEN(0) |
+ BF_PXP_WFA_FETCH_CTRL_BF2_BYPASS_MODE(0),
+ pxp->base + HW_PXP_WFA_FETCH_CTRL);
+
+ __raw_writel(
+ BF_PXP_WFA_ARRAY_PIXEL0_MASK_SIGN_Y(0) |
+ BF_PXP_WFA_ARRAY_PIXEL0_MASK_OFFSET_Y(0) |
+ BF_PXP_WFA_ARRAY_PIXEL0_MASK_SIGN_X(0) |
+ BF_PXP_WFA_ARRAY_PIXEL0_MASK_OFFSET_X(0) |
+ BF_PXP_WFA_ARRAY_PIXEL0_MASK_BUF_SEL(1) |
+ BF_PXP_WFA_ARRAY_PIXEL0_MASK_H_OFS(0) |
+ BF_PXP_WFA_ARRAY_PIXEL0_MASK_L_OFS(3),
+ pxp->base + HW_PXP_WFA_ARRAY_PIXEL0_MASK);
+
+ __raw_writel(
+ BF_PXP_WFA_ARRAY_PIXEL1_MASK_SIGN_Y(0) |
+ BF_PXP_WFA_ARRAY_PIXEL1_MASK_OFFSET_Y(0) |
+ BF_PXP_WFA_ARRAY_PIXEL1_MASK_SIGN_X(0) |
+ BF_PXP_WFA_ARRAY_PIXEL1_MASK_OFFSET_X(0) |
+ BF_PXP_WFA_ARRAY_PIXEL1_MASK_BUF_SEL(1) |
+ BF_PXP_WFA_ARRAY_PIXEL1_MASK_H_OFS(4) |
+ BF_PXP_WFA_ARRAY_PIXEL1_MASK_L_OFS(7),
+ pxp->base + HW_PXP_WFA_ARRAY_PIXEL1_MASK);
+
+ __raw_writel(
+ BF_PXP_WFA_ARRAY_PIXEL3_MASK_SIGN_Y(0) |
+ BF_PXP_WFA_ARRAY_PIXEL3_MASK_OFFSET_Y(0) |
+ BF_PXP_WFA_ARRAY_PIXEL3_MASK_SIGN_X(0) |
+ BF_PXP_WFA_ARRAY_PIXEL3_MASK_OFFSET_X(0) |
+ BF_PXP_WFA_ARRAY_PIXEL3_MASK_BUF_SEL(1) |
+ BF_PXP_WFA_ARRAY_PIXEL3_MASK_H_OFS(8) |
+ BF_PXP_WFA_ARRAY_PIXEL3_MASK_L_OFS(9),
+ pxp->base + HW_PXP_WFA_ARRAY_PIXEL2_MASK);
+
+ __raw_writel(
+ BF_PXP_WFA_ARRAY_PIXEL4_MASK_SIGN_Y(0) |
+ BF_PXP_WFA_ARRAY_PIXEL4_MASK_OFFSET_Y(0) |
+ BF_PXP_WFA_ARRAY_PIXEL4_MASK_SIGN_X(0) |
+ BF_PXP_WFA_ARRAY_PIXEL4_MASK_OFFSET_X(0) |
+ BF_PXP_WFA_ARRAY_PIXEL4_MASK_BUF_SEL(1) |
+ BF_PXP_WFA_ARRAY_PIXEL4_MASK_H_OFS(10) |
+ BF_PXP_WFA_ARRAY_PIXEL4_MASK_L_OFS(15),
+ pxp->base + HW_PXP_WFA_ARRAY_PIXEL3_MASK);
+
+ __raw_writel(
+ BF_PXP_WFA_ARRAY_PIXEL2_MASK_SIGN_Y(0) |
+ BF_PXP_WFA_ARRAY_PIXEL2_MASK_OFFSET_Y(0) |
+ BF_PXP_WFA_ARRAY_PIXEL2_MASK_SIGN_X(0) |
+ BF_PXP_WFA_ARRAY_PIXEL2_MASK_OFFSET_X(0) |
+ BF_PXP_WFA_ARRAY_PIXEL2_MASK_BUF_SEL(0) |
+ BF_PXP_WFA_ARRAY_PIXEL2_MASK_H_OFS(4) |
+ BF_PXP_WFA_ARRAY_PIXEL2_MASK_L_OFS(7),
+ pxp->base + HW_PXP_WFA_ARRAY_PIXEL4_MASK);
+
+ __raw_writel(1, pxp->base + HW_PXP_WFA_ARRAY_REG2);
+
+ /* STORE */
+ __raw_writel(
+ BF_PXP_WFE_A_STORE_CTRL_CH0_CH_EN(1)|
+ BF_PXP_WFE_A_STORE_CTRL_CH0_BLOCK_EN(0)|
+ BF_PXP_WFE_A_STORE_CTRL_CH0_BLOCK_16(0)|
+ BF_PXP_WFE_A_STORE_CTRL_CH0_HANDSHAKE_EN(0)|
+ BF_PXP_WFE_A_STORE_CTRL_CH0_ARRAY_EN(0)|
+ BF_PXP_WFE_A_STORE_CTRL_CH0_ARRAY_LINE_NUM(0)|
+ BF_PXP_WFE_A_STORE_CTRL_CH0_STORE_BYPASS_EN(0)|
+ BF_PXP_WFE_A_STORE_CTRL_CH0_STORE_MEMORY_EN(1)|
+ BF_PXP_WFE_A_STORE_CTRL_CH0_PACK_IN_SEL(1)|
+ BF_PXP_WFE_A_STORE_CTRL_CH0_FILL_DATA_EN(0)|
+ BF_PXP_WFE_A_STORE_CTRL_CH0_WR_NUM_BYTES(8)|
+ BF_PXP_WFE_A_STORE_CTRL_CH0_COMBINE_2CHANNEL(1) |
+ BF_PXP_WFE_A_STORE_CTRL_CH0_ARBIT_EN(0),
+ pxp->base + HW_PXP_WFE_A_STORE_CTRL_CH0);
+
+ __raw_writel(
+ BF_PXP_WFE_A_STORE_CTRL_CH1_CH_EN(1)|
+ BF_PXP_WFE_A_STORE_CTRL_CH1_BLOCK_EN(0)|
+ BF_PXP_WFE_A_STORE_CTRL_CH1_BLOCK_16(0)|
+ BF_PXP_WFE_A_STORE_CTRL_CH1_HANDSHAKE_EN(0)|
+ BF_PXP_WFE_A_STORE_CTRL_CH1_ARRAY_EN(0)|
+ BF_PXP_WFE_A_STORE_CTRL_CH1_ARRAY_LINE_NUM(0)|
+ BF_PXP_WFE_A_STORE_CTRL_CH1_STORE_BYPASS_EN(0)|
+ BF_PXP_WFE_A_STORE_CTRL_CH1_STORE_MEMORY_EN(1)|
+ BF_PXP_WFE_A_STORE_CTRL_CH1_PACK_IN_SEL(1)|
+ BF_PXP_WFE_A_STORE_CTRL_CH1_WR_NUM_BYTES(16),
+ pxp->base + HW_PXP_WFE_A_STORE_CTRL_CH1);
+
+ __raw_writel(
+ BF_PXP_WFE_A_STORE_SHIFT_CTRL_CH0_OUTPUT_ACTIVE_BPP(0)|
+ BF_PXP_WFE_A_STORE_SHIFT_CTRL_CH0_OUT_YUV422_1P_EN(0)|
+ BF_PXP_WFE_A_STORE_SHIFT_CTRL_CH0_OUT_YUV422_2P_EN(0)|
+ BF_PXP_WFE_A_STORE_SHIFT_CTRL_CH0_SHIFT_BYPASS(0),
+ pxp->base + HW_PXP_WFE_A_STORE_SHIFT_CTRL_CH0);
+
+
+ __raw_writel(
+ BF_PXP_WFE_A_STORE_SHIFT_CTRL_CH1_OUTPUT_ACTIVE_BPP(1)|
+ BF_PXP_WFE_A_STORE_SHIFT_CTRL_CH1_OUT_YUV422_1P_EN(0)|
+ BF_PXP_WFE_A_STORE_SHIFT_CTRL_CH1_OUT_YUV422_2P_EN(0),
+ pxp->base + HW_PXP_WFE_A_STORE_SHIFT_CTRL_CH1);
+
+ __raw_writel(BF_PXP_WFE_A_STORE_FILL_DATA_CH0_FILL_DATA_CH0(0),
+ pxp->base + HW_PXP_WFE_A_STORE_FILL_DATA_CH0);
+
+ __raw_writel(BF_PXP_WFE_A_STORE_D_MASK0_H_CH0_D_MASK0_H_CH0(0x0),
+ pxp->base + HW_PXP_WFE_A_STORE_D_MASK0_H_CH0);
+
+ __raw_writel(BF_PXP_WFE_A_STORE_D_MASK0_L_CH0_D_MASK0_L_CH0(0xf), /* fetch CP */
+ pxp->base + HW_PXP_WFE_A_STORE_D_MASK0_L_CH0);
+
+ __raw_writel(BF_PXP_WFE_A_STORE_D_MASK1_H_CH0_D_MASK1_H_CH0(0x0),
+ pxp->base + HW_PXP_WFE_A_STORE_D_MASK1_H_CH0);
+
+ __raw_writel(BF_PXP_WFE_A_STORE_D_MASK1_L_CH0_D_MASK1_L_CH0(0xf00), /* fetch NP */
+ pxp->base + HW_PXP_WFE_A_STORE_D_MASK1_L_CH0);
+
+ __raw_writel(BF_PXP_WFE_A_STORE_D_MASK2_H_CH0_D_MASK2_H_CH0(0x0),
+ pxp->base + HW_PXP_WFE_A_STORE_D_MASK2_H_CH0);
+
+ __raw_writel(BF_PXP_WFE_A_STORE_D_MASK2_L_CH0_D_MASK2_L_CH0(0x00000),
+ pxp->base + HW_PXP_WFE_A_STORE_D_MASK2_L_CH0);
+
+ __raw_writel(BF_PXP_WFE_A_STORE_D_MASK3_H_CH0_D_MASK3_H_CH0(0x0),
+ pxp->base + HW_PXP_WFE_A_STORE_D_MASK3_H_CH0);
+
+ __raw_writel(BF_PXP_WFE_A_STORE_D_MASK3_L_CH0_D_MASK3_L_CH0(0x3f000000), /* fetch LUT */
+ pxp->base + HW_PXP_WFE_A_STORE_D_MASK3_L_CH0);
+
+ __raw_writel(BF_PXP_WFE_A_STORE_D_MASK4_H_CH0_D_MASK4_H_CH0(0xf),
+ pxp->base + HW_PXP_WFE_A_STORE_D_MASK4_H_CH0);
+
+ __raw_writel(BF_PXP_WFE_A_STORE_D_MASK4_L_CH0_D_MASK4_L_CH0(0x0), /* fetch Y4 */
+ pxp->base + HW_PXP_WFE_A_STORE_D_MASK4_L_CH0);
+
+ __raw_writel(
+ BF_PXP_WFE_A_STORE_D_SHIFT_L_CH0_D_SHIFT_WIDTH0(32) |
+ BF_PXP_WFE_A_STORE_D_SHIFT_L_CH0_D_SHIFT_FLAG0(1) |
+ BF_PXP_WFE_A_STORE_D_SHIFT_L_CH0_D_SHIFT_WIDTH1(28)|
+ BF_PXP_WFE_A_STORE_D_SHIFT_L_CH0_D_SHIFT_FLAG1(1) |
+ BF_PXP_WFE_A_STORE_D_SHIFT_L_CH0_D_SHIFT_WIDTH2(24)|
+ BF_PXP_WFE_A_STORE_D_SHIFT_L_CH0_D_SHIFT_FLAG2(1)|
+ BF_PXP_WFE_A_STORE_D_SHIFT_L_CH0_D_SHIFT_WIDTH3(18)|
+ BF_PXP_WFE_A_STORE_D_SHIFT_L_CH0_D_SHIFT_FLAG3(1),
+ pxp->base + HW_PXP_WFE_A_STORE_D_SHIFT_L_CH0);
+
+ __raw_writel(
+ BF_PXP_WFE_A_STORE_D_SHIFT_H_CH0_D_SHIFT_WIDTH4(28) |
+ BF_PXP_WFE_A_STORE_D_SHIFT_H_CH0_D_SHIFT_FLAG4(0) |
+ BF_PXP_WFE_A_STORE_D_SHIFT_H_CH0_D_SHIFT_WIDTH5(0)|
+ BF_PXP_WFE_A_STORE_D_SHIFT_H_CH0_D_SHIFT_FLAG5(0) |
+ BF_PXP_WFE_A_STORE_D_SHIFT_H_CH0_D_SHIFT_WIDTH6(0)|
+ BF_PXP_WFE_A_STORE_D_SHIFT_H_CH0_D_SHIFT_FLAG6(0) |
+ BF_PXP_WFE_A_STORE_D_SHIFT_H_CH0_D_SHIFT_WIDTH7(0),
+ pxp->base + HW_PXP_WFE_A_STORE_D_SHIFT_H_CH0);
+
+ __raw_writel(
+ BF_PXP_WFE_A_STORE_F_SHIFT_L_CH0_F_SHIFT_WIDTH0(1)|
+ BF_PXP_WFE_A_STORE_F_SHIFT_L_CH0_F_SHIFT_FLAG0(1)|
+ BF_PXP_WFE_A_STORE_F_SHIFT_L_CH0_F_SHIFT_WIDTH1(1)|
+ BF_PXP_WFE_A_STORE_F_SHIFT_L_CH0_F_SHIFT_FLAG1(0)|
+ BF_PXP_WFE_A_STORE_F_SHIFT_L_CH0_F_SHIFT_WIDTH2(32+6)|
+ BF_PXP_WFE_A_STORE_F_SHIFT_L_CH0_F_SHIFT_FLAG2(1)|
+ BF_PXP_WFE_A_STORE_F_SHIFT_L_CH0_F_SHIFT_WIDTH3(32+6)|
+ BF_PXP_WFE_A_STORE_F_SHIFT_L_CH0_F_SHIFT_FLAG3(1),
+ pxp->base + HW_PXP_WFE_A_STORE_F_SHIFT_L_CH0);
+
+ __raw_writel(
+ BF_PXP_WFE_A_STORE_F_MASK_H_CH0_F_MASK4(0)|
+ BF_PXP_WFE_A_STORE_F_MASK_H_CH0_F_MASK5(0)|
+ BF_PXP_WFE_A_STORE_F_MASK_H_CH0_F_MASK6(0)|
+ BF_PXP_WFE_A_STORE_F_MASK_H_CH0_F_MASK7(0),
+ pxp->base + HW_PXP_WFE_A_STORE_F_MASK_H_CH0);
+
+
+ __raw_writel(
+ BF_PXP_WFE_A_STORE_F_MASK_L_CH0_F_MASK0(0x1) |
+ BF_PXP_WFE_A_STORE_F_MASK_L_CH0_F_MASK1(0x2) |
+ BF_PXP_WFE_A_STORE_F_MASK_L_CH0_F_MASK2(0x4) |
+ BF_PXP_WFE_A_STORE_F_MASK_L_CH0_F_MASK3(0x8),
+ pxp->base + HW_PXP_WFE_A_STORE_F_MASK_L_CH0);
+
+ /* ALU */
+ __raw_writel(BF_PXP_ALU_A_INST_ENTRY_ENTRY_ADDR(0),
+ pxp->base + HW_PXP_ALU_A_INST_ENTRY);
+
+ __raw_writel(BF_PXP_ALU_A_PARAM_PARAM0(0) |
+ BF_PXP_ALU_A_PARAM_PARAM1(0),
+ pxp->base + HW_PXP_ALU_A_PARAM);
+
+ __raw_writel(BF_PXP_ALU_A_CONFIG_BUF_ADDR(0),
+ pxp->base + HW_PXP_ALU_A_CONFIG);
+
+ __raw_writel(BF_PXP_ALU_A_LUT_CONFIG_MODE(0) |
+ BF_PXP_ALU_A_LUT_CONFIG_EN(0),
+ pxp->base + HW_PXP_ALU_A_LUT_CONFIG);
+
+ __raw_writel(BF_PXP_ALU_A_LUT_DATA0_LUT_DATA_L(0),
+ pxp->base + HW_PXP_ALU_A_LUT_DATA0);
+
+ __raw_writel(BF_PXP_ALU_A_LUT_DATA1_LUT_DATA_H(0),
+ pxp->base + HW_PXP_ALU_A_LUT_DATA1);
+
+ __raw_writel(BF_PXP_ALU_A_CTRL_BYPASS (1) |
+ BF_PXP_ALU_A_CTRL_ENABLE (1) |
+ BF_PXP_ALU_A_CTRL_START (0) |
+ BF_PXP_ALU_A_CTRL_SW_RESET (0),
+ pxp->base + HW_PXP_ALU_A_CTRL);
+
+ /* WFE A */
+ __raw_writel(0x3F3F0303, pxp->base + HW_PXP_WFE_A_STAGE1_MUX0);
+ __raw_writel(0x0C00000C, pxp->base + HW_PXP_WFE_A_STAGE1_MUX1);
+ __raw_writel(0x01040000, pxp->base + HW_PXP_WFE_A_STAGE1_MUX2);
+ __raw_writel(0x0A0A0904, pxp->base + HW_PXP_WFE_A_STAGE1_MUX3);
+ __raw_writel(0x00000B0B, pxp->base + HW_PXP_WFE_A_STAGE1_MUX4);
+
+ __raw_writel(0x1800280E, pxp->base + HW_PXP_WFE_A_STAGE2_MUX0);
+ __raw_writel(0x00280E01, pxp->base + HW_PXP_WFE_A_STAGE2_MUX1);
+ __raw_writel(0x280E0118, pxp->base + HW_PXP_WFE_A_STAGE2_MUX2);
+ __raw_writel(0x00011800, pxp->base + HW_PXP_WFE_A_STAGE2_MUX3);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_A_STAGE2_MUX4);
+ __raw_writel(0x1800280E, pxp->base + HW_PXP_WFE_A_STAGE2_MUX5);
+ __raw_writel(0x00280E01, pxp->base + HW_PXP_WFE_A_STAGE2_MUX6);
+ __raw_writel(0x1A0E0118, pxp->base + HW_PXP_WFE_A_STAGE2_MUX7);
+ __raw_writel(0x1B012911, pxp->base + HW_PXP_WFE_A_STAGE2_MUX8);
+ __raw_writel(0x00002911, pxp->base + HW_PXP_WFE_A_STAGE2_MUX9);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_A_STAGE2_MUX10);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_A_STAGE2_MUX11);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_A_STAGE2_MUX12);
+
+ __raw_writel(0x07060504, pxp->base + HW_PXP_WFE_A_STAGE3_MUX0);
+ __raw_writel(0x3F3F3F08, pxp->base + HW_PXP_WFE_A_STAGE3_MUX1);
+ __raw_writel(0x03020100, pxp->base + HW_PXP_WFE_A_STAGE3_MUX2);
+ __raw_writel(0x3F3F3F3F, pxp->base + HW_PXP_WFE_A_STAGE3_MUX3);
+
+ __raw_writel(0x001F1F1F, pxp->base + HW_PXP_WFE_A_STAGE2_5X6_MASKS_0);
+ __raw_writel(0x3f030100, pxp->base + HW_PXP_WFE_A_STAGE2_5X6_ADDR_0);
+
+ __raw_writel(0x00000700, pxp->base + HW_PXP_WFE_A_STG2_5X1_OUT0);
+ __raw_writel(0x00007000, pxp->base + HW_PXP_WFE_A_STG2_5X1_OUT1);
+ __raw_writel(0x0000A000, pxp->base + HW_PXP_WFE_A_STG2_5X1_OUT2);
+ __raw_writel(0x000000C0, pxp->base + HW_PXP_WFE_A_STG2_5X1_OUT3);
+ __raw_writel(0x071F1F1F, pxp->base + HW_PXP_WFE_A_STG2_5X1_MASKS);
+
+ __raw_writel(0xFFFFFFFF, pxp->base + HW_PXP_WFE_A_STG1_8X1_OUT0_2);
+ __raw_writel(0xFFFFFFFF, pxp->base + HW_PXP_WFE_A_STG1_8X1_OUT0_3);
+ __raw_writel(0xFFFFFFFF, pxp->base + HW_PXP_WFE_A_STG1_8X1_OUT0_4);
+ __raw_writel(0xFFFFFFFF, pxp->base + HW_PXP_WFE_A_STG1_8X1_OUT0_5);
+ __raw_writel(0xFFFFFFFF, pxp->base + HW_PXP_WFE_A_STG1_8X1_OUT0_6);
+ __raw_writel(0xFFFFFFFF, pxp->base + HW_PXP_WFE_A_STG1_8X1_OUT0_7);
+
+ __raw_writel(0, pxp->base + HW_PXP_WFE_A_STG1_8X1_OUT1_0);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_A_STG1_8X1_OUT1_1);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_A_STG1_8X1_OUT1_2);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_A_STG1_8X1_OUT1_3);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_A_STG1_8X1_OUT1_4);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_A_STG1_8X1_OUT1_5);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_A_STG1_8X1_OUT1_6);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_A_STG1_8X1_OUT1_7);
+
+ __raw_writel(0, pxp->base + HW_PXP_WFE_A_STG1_8X1_OUT2_0);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_A_STG1_8X1_OUT2_1);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_A_STG1_8X1_OUT2_2);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_A_STG1_8X1_OUT2_3);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_A_STG1_8X1_OUT2_4);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_A_STG1_8X1_OUT2_5);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_A_STG1_8X1_OUT2_6);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_A_STG1_8X1_OUT2_7);
+
+ __raw_writel(0, pxp->base + HW_PXP_WFE_A_STG1_8X1_OUT3_0);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_A_STG1_8X1_OUT3_1);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_A_STG1_8X1_OUT3_2);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_A_STG1_8X1_OUT3_3);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_A_STG1_8X1_OUT3_4);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_A_STG1_8X1_OUT3_5);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_A_STG1_8X1_OUT3_6);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_A_STG1_8X1_OUT3_7);
+
+ __raw_writel(0x04040404, pxp->base + HW_PXP_WFE_A_STG2_5X6_OUT0_0);
+ __raw_writel(0x04040404, pxp->base + HW_PXP_WFE_A_STG2_5X6_OUT0_1);
+ __raw_writel(0x04050505, pxp->base + HW_PXP_WFE_A_STG2_5X6_OUT0_2);
+ __raw_writel(0x04040404, pxp->base + HW_PXP_WFE_A_STG2_5X6_OUT0_3);
+ __raw_writel(0x04040404, pxp->base + HW_PXP_WFE_A_STG2_5X6_OUT0_4);
+ __raw_writel(0x04040404, pxp->base + HW_PXP_WFE_A_STG2_5X6_OUT0_5);
+ __raw_writel(0x04040404, pxp->base + HW_PXP_WFE_A_STG2_5X6_OUT0_6);
+ __raw_writel(0x04040404, pxp->base + HW_PXP_WFE_A_STG2_5X6_OUT0_7);
+
+ __raw_writel(0x05050505, pxp->base + HW_PXP_WFE_A_STG2_5X6_OUT1_0);
+ __raw_writel(0x05050505, pxp->base + HW_PXP_WFE_A_STG2_5X6_OUT1_1);
+ __raw_writel(0x05080808, pxp->base + HW_PXP_WFE_A_STG2_5X6_OUT1_2);
+ __raw_writel(0x05050505, pxp->base + HW_PXP_WFE_A_STG2_5X6_OUT1_3);
+ __raw_writel(0x05050505, pxp->base + HW_PXP_WFE_A_STG2_5X6_OUT1_4);
+ __raw_writel(0x05050505, pxp->base + HW_PXP_WFE_A_STG2_5X6_OUT1_5);
+ __raw_writel(0x05050505, pxp->base + HW_PXP_WFE_A_STG2_5X6_OUT1_6);
+ __raw_writel(0x05050505, pxp->base + HW_PXP_WFE_A_STG2_5X6_OUT1_7);
+
+ __raw_writel(0x07070707, pxp->base + HW_PXP_WFE_A_STG2_5X6_OUT2_0);
+ __raw_writel(0x07070707, pxp->base + HW_PXP_WFE_A_STG2_5X6_OUT2_1);
+ __raw_writel(0x070C0C0C, pxp->base + HW_PXP_WFE_A_STG2_5X6_OUT2_2);
+ __raw_writel(0x07070707, pxp->base + HW_PXP_WFE_A_STG2_5X6_OUT2_3);
+ __raw_writel(0X0F0F0F0F, pxp->base + HW_PXP_WFE_A_STG2_5X6_OUT2_4);
+ __raw_writel(0X0F0F0F0F, pxp->base + HW_PXP_WFE_A_STG2_5X6_OUT2_5);
+ __raw_writel(0X0F0F0F0F, pxp->base + HW_PXP_WFE_A_STG2_5X6_OUT2_6);
+ __raw_writel(0X0F0F0F0F, pxp->base + HW_PXP_WFE_A_STG2_5X6_OUT2_7);
+
+ __raw_writel(0, pxp->base + HW_PXP_WFE_A_STG2_5X6_OUT3_0);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_A_STG2_5X6_OUT3_1);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_A_STG2_5X6_OUT3_2);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_A_STG2_5X6_OUT3_3);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_A_STG2_5X6_OUT3_4);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_A_STG2_5X6_OUT3_5);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_A_STG2_5X6_OUT3_6);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_A_STG2_5X6_OUT3_7);
+
+ if (pxp->devdata && pxp->devdata->pxp_lut_cleanup_multiple)
+ pxp->devdata->pxp_lut_cleanup_multiple(pxp,
+ proc_data->lut_sels, 1);
+}
+
+static void pxp_wfe_a_configure_v3p(struct pxps *pxp)
+{
+ struct pxp_config_data *pxp_conf = &pxp->pxp_conf_state;
+ struct pxp_proc_data *proc_data = &pxp_conf->proc_data;
+
+ /* FETCH */
+ __raw_writel(
+ BF_PXP_WFB_FETCH_CTRL_BF1_EN(1) |
+ BF_PXP_WFB_FETCH_CTRL_BF1_HSK_MODE(0) |
+ BF_PXP_WFB_FETCH_CTRL_BF1_BYTES_PP(0) |
+ BF_PXP_WFB_FETCH_CTRL_BF1_LINE_MODE(0) |
+ BF_PXP_WFB_FETCH_CTRL_BF1_SRAM_IF(0) |
+ BF_PXP_WFB_FETCH_CTRL_BF1_BURST_LEN(0) |
+ BF_PXP_WFB_FETCH_CTRL_BF1_BYPASS_MODE(0) |
+ BF_PXP_WFB_FETCH_CTRL_BF2_EN(1) |
+ BF_PXP_WFB_FETCH_CTRL_BF2_HSK_MODE(0) |
+ BF_PXP_WFB_FETCH_CTRL_BF2_BYTES_PP(1) |
+ BF_PXP_WFB_FETCH_CTRL_BF2_LINE_MODE(0) |
+ BF_PXP_WFB_FETCH_CTRL_BF2_SRAM_IF(0) |
+ BF_PXP_WFB_FETCH_CTRL_BF2_BURST_LEN(0) |
+ BF_PXP_WFB_FETCH_CTRL_BF2_BYPASS_MODE(0),
+ pxp->base + HW_PXP_WFB_FETCH_CTRL);
+
+ __raw_writel(
+ BF_PXP_WFB_ARRAY_PIXEL0_MASK_SIGN_Y(0) |
+ BF_PXP_WFB_ARRAY_PIXEL0_MASK_OFFSET_Y(0) |
+ BF_PXP_WFB_ARRAY_PIXEL0_MASK_SIGN_X(0) |
+ BF_PXP_WFB_ARRAY_PIXEL0_MASK_OFFSET_X(0) |
+ BF_PXP_WFB_ARRAY_PIXEL0_MASK_BUF_SEL(1) |
+ BF_PXP_WFB_ARRAY_PIXEL0_MASK_H_OFS(0) |
+ BF_PXP_WFB_ARRAY_PIXEL0_MASK_L_OFS(3),
+ pxp->base + HW_PXP_WFB_ARRAY_PIXEL0_MASK);
+
+ __raw_writel(
+ BF_PXP_WFB_ARRAY_PIXEL1_MASK_SIGN_Y(0) |
+ BF_PXP_WFB_ARRAY_PIXEL1_MASK_OFFSET_Y(0) |
+ BF_PXP_WFB_ARRAY_PIXEL1_MASK_SIGN_X(0) |
+ BF_PXP_WFB_ARRAY_PIXEL1_MASK_OFFSET_X(0) |
+ BF_PXP_WFB_ARRAY_PIXEL1_MASK_BUF_SEL(1) |
+ BF_PXP_WFB_ARRAY_PIXEL1_MASK_H_OFS(4) |
+ BF_PXP_WFB_ARRAY_PIXEL1_MASK_L_OFS(7),
+ pxp->base + HW_PXP_WFB_ARRAY_PIXEL1_MASK);
+
+ __raw_writel(
+ BF_PXP_WFB_ARRAY_PIXEL2_MASK_SIGN_Y(0) |
+ BF_PXP_WFB_ARRAY_PIXEL2_MASK_OFFSET_Y(0) |
+ BF_PXP_WFB_ARRAY_PIXEL2_MASK_SIGN_X(0) |
+ BF_PXP_WFB_ARRAY_PIXEL2_MASK_OFFSET_X(0) |
+ BF_PXP_WFB_ARRAY_PIXEL2_MASK_BUF_SEL(1) |
+ BF_PXP_WFB_ARRAY_PIXEL2_MASK_H_OFS(8) |
+ BF_PXP_WFB_ARRAY_PIXEL2_MASK_L_OFS(9),
+ pxp->base + HW_PXP_WFB_ARRAY_PIXEL2_MASK);
+
+ __raw_writel(
+ BF_PXP_WFB_ARRAY_PIXEL3_MASK_SIGN_Y(0) |
+ BF_PXP_WFB_ARRAY_PIXEL3_MASK_OFFSET_Y(0) |
+ BF_PXP_WFB_ARRAY_PIXEL3_MASK_SIGN_X(0) |
+ BF_PXP_WFB_ARRAY_PIXEL3_MASK_OFFSET_X(0) |
+ BF_PXP_WFB_ARRAY_PIXEL3_MASK_BUF_SEL(1) |
+ BF_PXP_WFB_ARRAY_PIXEL3_MASK_H_OFS(10) |
+ BF_PXP_WFB_ARRAY_PIXEL3_MASK_L_OFS(15),
+ pxp->base + HW_PXP_WFB_ARRAY_PIXEL3_MASK);
+
+ __raw_writel(
+ BF_PXP_WFB_ARRAY_PIXEL4_MASK_SIGN_Y(0) |
+ BF_PXP_WFB_ARRAY_PIXEL4_MASK_OFFSET_Y(0) |
+ BF_PXP_WFB_ARRAY_PIXEL4_MASK_SIGN_X(0) |
+ BF_PXP_WFB_ARRAY_PIXEL4_MASK_OFFSET_X(0) |
+ BF_PXP_WFB_ARRAY_PIXEL4_MASK_BUF_SEL(0) |
+ BF_PXP_WFB_ARRAY_PIXEL4_MASK_H_OFS(4) |
+ BF_PXP_WFB_ARRAY_PIXEL4_MASK_L_OFS(7),
+ pxp->base + HW_PXP_WFB_ARRAY_PIXEL4_MASK);
+
+ __raw_writel(1, pxp->base + HW_PXP_WFB_ARRAY_REG2);
+
+ /* STORE */
+ __raw_writel(
+ BF_PXP_WFE_B_STORE_CTRL_CH0_CH_EN(1)|
+ BF_PXP_WFE_B_STORE_CTRL_CH0_BLOCK_EN(0)|
+ BF_PXP_WFE_B_STORE_CTRL_CH0_BLOCK_16(0)|
+ BF_PXP_WFE_B_STORE_CTRL_CH0_HANDSHAKE_EN(0)|
+ BF_PXP_WFE_B_STORE_CTRL_CH0_ARRAY_EN(0)|
+ BF_PXP_WFE_B_STORE_CTRL_CH0_ARRAY_LINE_NUM(0)|
+ BF_PXP_WFE_B_STORE_CTRL_CH0_STORE_BYPASS_EN(0)|
+ BF_PXP_WFE_B_STORE_CTRL_CH0_STORE_MEMORY_EN(1)|
+ BF_PXP_WFE_B_STORE_CTRL_CH0_PACK_IN_SEL(1)|
+ BF_PXP_WFE_B_STORE_CTRL_CH0_FILL_DATA_EN(0)|
+ BF_PXP_WFE_B_STORE_CTRL_CH0_WR_NUM_BYTES(8)|
+ BF_PXP_WFE_B_STORE_CTRL_CH0_COMBINE_2CHANNEL(1) |
+ BF_PXP_WFE_B_STORE_CTRL_CH0_ARBIT_EN(0),
+ pxp->base + HW_PXP_WFE_B_STORE_CTRL_CH0);
+
+ __raw_writel(
+ BF_PXP_WFE_B_STORE_CTRL_CH1_CH_EN(1)|
+ BF_PXP_WFE_B_STORE_CTRL_CH1_BLOCK_EN(0)|
+ BF_PXP_WFE_B_STORE_CTRL_CH1_BLOCK_16(0)|
+ BF_PXP_WFE_B_STORE_CTRL_CH1_HANDSHAKE_EN(0)|
+ BF_PXP_WFE_B_STORE_CTRL_CH1_ARRAY_EN(0)|
+ BF_PXP_WFE_B_STORE_CTRL_CH1_ARRAY_LINE_NUM(0)|
+ BF_PXP_WFE_B_STORE_CTRL_CH1_STORE_BYPASS_EN(0)|
+ BF_PXP_WFE_B_STORE_CTRL_CH1_STORE_MEMORY_EN(1)|
+ BF_PXP_WFE_B_STORE_CTRL_CH1_PACK_IN_SEL(1)|
+ BF_PXP_WFE_B_STORE_CTRL_CH1_WR_NUM_BYTES(16),
+ pxp->base + HW_PXP_WFE_B_STORE_CTRL_CH1);
+
+ __raw_writel(
+ BF_PXP_WFE_B_STORE_SHIFT_CTRL_CH0_OUTPUT_ACTIVE_BPP(0)|
+ BF_PXP_WFE_B_STORE_SHIFT_CTRL_CH0_OUT_YUV422_1P_EN(0)|
+ BF_PXP_WFE_B_STORE_SHIFT_CTRL_CH0_OUT_YUV422_2P_EN(0)|
+ BF_PXP_WFE_B_STORE_SHIFT_CTRL_CH0_SHIFT_BYPASS(0),
+ pxp->base + HW_PXP_WFE_B_STORE_SHIFT_CTRL_CH0);
+
+
+ __raw_writel(
+ BF_PXP_WFE_B_STORE_SHIFT_CTRL_CH1_OUTPUT_ACTIVE_BPP(1)|
+ BF_PXP_WFE_B_STORE_SHIFT_CTRL_CH1_OUT_YUV422_1P_EN(0)|
+ BF_PXP_WFE_B_STORE_SHIFT_CTRL_CH1_OUT_YUV422_2P_EN(0),
+ pxp->base + HW_PXP_WFE_B_STORE_SHIFT_CTRL_CH1);
+
+ __raw_writel(BF_PXP_WFE_B_STORE_FILL_DATA_CH0_FILL_DATA_CH0(0),
+ pxp->base + HW_PXP_WFE_B_STORE_FILL_DATA_CH0);
+
+ __raw_writel(BF_PXP_WFE_B_STORE_D_MASK0_H_CH0_D_MASK0_H_CH0(0x0),
+ pxp->base + HW_PXP_WFE_B_STORE_D_MASK0_H_CH0);
+
+ __raw_writel(BF_PXP_WFE_B_STORE_D_MASK0_L_CH0_D_MASK0_L_CH0(0xf), /* fetch CP */
+ pxp->base + HW_PXP_WFE_B_STORE_D_MASK0_L_CH0);
+
+ __raw_writel(BF_PXP_WFE_B_STORE_D_MASK1_H_CH0_D_MASK1_H_CH0(0x0),
+ pxp->base + HW_PXP_WFE_B_STORE_D_MASK1_H_CH0);
+
+ __raw_writel(BF_PXP_WFE_B_STORE_D_MASK1_L_CH0_D_MASK1_L_CH0(0xf00), /* fetch NP */
+ pxp->base + HW_PXP_WFE_B_STORE_D_MASK1_L_CH0);
+
+ __raw_writel(BF_PXP_WFE_B_STORE_D_MASK2_H_CH0_D_MASK2_H_CH0(0x0),
+ pxp->base + HW_PXP_WFE_B_STORE_D_MASK2_H_CH0);
+
+ __raw_writel(BF_PXP_WFE_B_STORE_D_MASK2_L_CH0_D_MASK2_L_CH0(0x00000),
+ pxp->base + HW_PXP_WFE_B_STORE_D_MASK2_L_CH0);
+
+ __raw_writel(BF_PXP_WFE_B_STORE_D_MASK3_H_CH0_D_MASK3_H_CH0(0x0),
+ pxp->base + HW_PXP_WFE_B_STORE_D_MASK3_H_CH0);
+
+ __raw_writel(BF_PXP_WFE_B_STORE_D_MASK3_L_CH0_D_MASK3_L_CH0(0x3f000000), /* fetch LUT */
+ pxp->base + HW_PXP_WFE_B_STORE_D_MASK3_L_CH0);
+
+ __raw_writel(BF_PXP_WFE_B_STORE_D_MASK4_H_CH0_D_MASK4_H_CH0(0xf),
+ pxp->base + HW_PXP_WFE_B_STORE_D_MASK4_H_CH0);
+
+ __raw_writel(BF_PXP_WFE_B_STORE_D_MASK4_L_CH0_D_MASK4_L_CH0(0x0), /* fetch Y4 */
+ pxp->base + HW_PXP_WFE_B_STORE_D_MASK4_L_CH0);
+
+ __raw_writel(0x0, pxp->base + HW_PXP_WFE_B_STORE_D_MASK5_H_CH0);
+ __raw_writel(0x0, pxp->base + HW_PXP_WFE_B_STORE_D_MASK5_L_CH0);
+ __raw_writel(0x0, pxp->base + HW_PXP_WFE_B_STORE_D_MASK6_H_CH0);
+ __raw_writel(0x0, pxp->base + HW_PXP_WFE_B_STORE_D_MASK6_L_CH0);
+ __raw_writel(0x0, pxp->base + HW_PXP_WFE_B_STORE_D_MASK7_H_CH0);
+ __raw_writel(0x0, pxp->base + HW_PXP_WFE_B_STORE_D_MASK7_L_CH0);
+
+ __raw_writel(
+ BF_PXP_WFE_B_STORE_D_SHIFT_L_CH0_D_SHIFT_WIDTH0(32) |
+ BF_PXP_WFE_B_STORE_D_SHIFT_L_CH0_D_SHIFT_FLAG0(1) |
+ BF_PXP_WFE_B_STORE_D_SHIFT_L_CH0_D_SHIFT_WIDTH1(28)|
+ BF_PXP_WFE_B_STORE_D_SHIFT_L_CH0_D_SHIFT_FLAG1(1) |
+ BF_PXP_WFE_B_STORE_D_SHIFT_L_CH0_D_SHIFT_WIDTH2(24)|
+ BF_PXP_WFE_B_STORE_D_SHIFT_L_CH0_D_SHIFT_FLAG2(1)|
+ BF_PXP_WFE_B_STORE_D_SHIFT_L_CH0_D_SHIFT_WIDTH3(18)|
+ BF_PXP_WFE_B_STORE_D_SHIFT_L_CH0_D_SHIFT_FLAG3(1),
+ pxp->base + HW_PXP_WFE_B_STORE_D_SHIFT_L_CH0);
+
+ __raw_writel(
+ BF_PXP_WFE_B_STORE_D_SHIFT_H_CH0_D_SHIFT_WIDTH4(28) |
+ BF_PXP_WFE_B_STORE_D_SHIFT_H_CH0_D_SHIFT_FLAG4(0) |
+ BF_PXP_WFE_B_STORE_D_SHIFT_H_CH0_D_SHIFT_WIDTH5(0)|
+ BF_PXP_WFE_B_STORE_D_SHIFT_H_CH0_D_SHIFT_FLAG5(0) |
+ BF_PXP_WFE_B_STORE_D_SHIFT_H_CH0_D_SHIFT_WIDTH6(0)|
+ BF_PXP_WFE_B_STORE_D_SHIFT_H_CH0_D_SHIFT_FLAG6(0) |
+ BF_PXP_WFE_B_STORE_D_SHIFT_H_CH0_D_SHIFT_WIDTH7(0),
+ pxp->base + HW_PXP_WFE_B_STORE_D_SHIFT_H_CH0);
+
+ __raw_writel(
+ BF_PXP_WFE_B_STORE_F_SHIFT_L_CH0_F_SHIFT_WIDTH0(1)|
+ BF_PXP_WFE_B_STORE_F_SHIFT_L_CH0_F_SHIFT_FLAG0(1)|
+ BF_PXP_WFE_B_STORE_F_SHIFT_L_CH0_F_SHIFT_WIDTH1(1)|
+ BF_PXP_WFE_B_STORE_F_SHIFT_L_CH0_F_SHIFT_FLAG1(0)|
+ BF_PXP_WFE_B_STORE_F_SHIFT_L_CH0_F_SHIFT_WIDTH2(32+6)|
+ BF_PXP_WFE_B_STORE_F_SHIFT_L_CH0_F_SHIFT_FLAG2(1)|
+ BF_PXP_WFE_B_STORE_F_SHIFT_L_CH0_F_SHIFT_WIDTH3(32+6)|
+ BF_PXP_WFE_B_STORE_F_SHIFT_L_CH0_F_SHIFT_FLAG3(1),
+ pxp->base + HW_PXP_WFE_B_STORE_F_SHIFT_L_CH0);
+
+ __raw_writel(
+ BF_PXP_WFE_B_STORE_F_SHIFT_H_CH0_F_SHIFT_WIDTH4(0)|
+ BF_PXP_WFE_B_STORE_F_SHIFT_H_CH0_F_SHIFT_FLAG4(0)|
+ BF_PXP_WFE_B_STORE_F_SHIFT_H_CH0_F_SHIFT_WIDTH5(0)|
+ BF_PXP_WFE_B_STORE_F_SHIFT_H_CH0_F_SHIFT_FLAG5(0)|
+ BF_PXP_WFE_B_STORE_F_SHIFT_H_CH0_F_SHIFT_WIDTH6(0)|
+ BF_PXP_WFE_B_STORE_F_SHIFT_H_CH0_F_SHIFT_FLAG6(0)|
+ BF_PXP_WFE_B_STORE_F_SHIFT_H_CH0_F_SHIFT_WIDTH7(0)|
+ BF_PXP_WFE_B_STORE_F_SHIFT_H_CH0_F_SHIFT_FLAG7(0),
+ pxp->base + HW_PXP_WFE_B_STORE_F_SHIFT_H_CH0);
+
+ __raw_writel(
+ BF_PXP_WFE_B_STORE_F_MASK_L_CH0_F_MASK0(0x1) |
+ BF_PXP_WFE_B_STORE_F_MASK_L_CH0_F_MASK1(0x2) |
+ BF_PXP_WFE_B_STORE_F_MASK_L_CH0_F_MASK2(0x4) |
+ BF_PXP_WFE_B_STORE_F_MASK_L_CH0_F_MASK3(0x8),
+ pxp->base + HW_PXP_WFE_B_STORE_F_MASK_L_CH0);
+
+ __raw_writel(
+ BF_PXP_WFE_B_STORE_F_MASK_H_CH0_F_MASK4(0x0)|
+ BF_PXP_WFE_B_STORE_F_MASK_H_CH0_F_MASK5(0x0)|
+ BF_PXP_WFE_B_STORE_F_MASK_H_CH0_F_MASK6(0x0)|
+ BF_PXP_WFE_B_STORE_F_MASK_H_CH0_F_MASK7(0x0),
+ pxp->base + HW_PXP_WFE_B_STORE_F_MASK_H_CH0);
+
+
+ /* ALU */
+ __raw_writel(BF_PXP_ALU_B_INST_ENTRY_ENTRY_ADDR(0),
+ pxp->base + HW_PXP_ALU_B_INST_ENTRY);
+
+ __raw_writel(BF_PXP_ALU_B_PARAM_PARAM0(0) |
+ BF_PXP_ALU_B_PARAM_PARAM1(0),
+ pxp->base + HW_PXP_ALU_B_PARAM);
+
+ __raw_writel(BF_PXP_ALU_B_CONFIG_BUF_ADDR(0),
+ pxp->base + HW_PXP_ALU_B_CONFIG);
+
+ __raw_writel(BF_PXP_ALU_B_LUT_CONFIG_MODE(0) |
+ BF_PXP_ALU_B_LUT_CONFIG_EN(0),
+ pxp->base + HW_PXP_ALU_B_LUT_CONFIG);
+
+ __raw_writel(BF_PXP_ALU_B_LUT_DATA0_LUT_DATA_L(0),
+ pxp->base + HW_PXP_ALU_B_LUT_DATA0);
+
+ __raw_writel(BF_PXP_ALU_B_LUT_DATA1_LUT_DATA_H(0),
+ pxp->base + HW_PXP_ALU_B_LUT_DATA1);
+
+ __raw_writel(BF_PXP_ALU_B_CTRL_BYPASS (1) |
+ BF_PXP_ALU_B_CTRL_ENABLE (1) |
+ BF_PXP_ALU_B_CTRL_START (0) |
+ BF_PXP_ALU_B_CTRL_SW_RESET (0),
+ pxp->base + HW_PXP_ALU_B_CTRL);
+
+ /* WFE A */
+ __raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STAGE1_MUX0);
+ __raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STAGE1_MUX1);
+ __raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STAGE1_MUX2);
+ __raw_writel(0x03000000, pxp->base + HW_PXP_WFE_B_STAGE1_MUX3);
+ __raw_writel(0x00000003, pxp->base + HW_PXP_WFE_B_STAGE1_MUX4);
+ __raw_writel(0x04000000, pxp->base + HW_PXP_WFE_B_STAGE1_MUX5);
+ __raw_writel(0x0A090401, pxp->base + HW_PXP_WFE_B_STAGE1_MUX6);
+ __raw_writel(0x000B0B0A, pxp->base + HW_PXP_WFE_B_STAGE1_MUX7);
+ __raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STAGE1_MUX8);
+
+ __raw_writel(0x1901290C, pxp->base + HW_PXP_WFE_B_STAGE2_MUX0);
+ __raw_writel(0x01290C02, pxp->base + HW_PXP_WFE_B_STAGE2_MUX1);
+ __raw_writel(0x290C0219, pxp->base + HW_PXP_WFE_B_STAGE2_MUX2);
+ __raw_writel(0x00021901, pxp->base + HW_PXP_WFE_B_STAGE2_MUX3);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_B_STAGE2_MUX4);
+ __raw_writel(0x1901290C, pxp->base + HW_PXP_WFE_B_STAGE2_MUX5);
+ __raw_writel(0x01290C02, pxp->base + HW_PXP_WFE_B_STAGE2_MUX6);
+ __raw_writel(0x1B0C0219, pxp->base + HW_PXP_WFE_B_STAGE2_MUX7);
+ __raw_writel(0x1C022A0F, pxp->base + HW_PXP_WFE_B_STAGE2_MUX8);
+ __raw_writel(0x02002A0F, pxp->base + HW_PXP_WFE_B_STAGE2_MUX9);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_B_STAGE2_MUX10);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_B_STAGE2_MUX11);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_B_STAGE2_MUX12);
+
+ __raw_writel(0x2a123a1d, pxp->base + HW_PXP_WFE_B_STAGE3_MUX0);
+ __raw_writel(0x00000013, pxp->base + HW_PXP_WFE_B_STAGE3_MUX1);
+ __raw_writel(0x2a123a1d, pxp->base + HW_PXP_WFE_B_STAGE3_MUX2);
+ __raw_writel(0x00000013, pxp->base + HW_PXP_WFE_B_STAGE3_MUX3);
+ __raw_writel(0x3b202c1d, pxp->base + HW_PXP_WFE_B_STAGE3_MUX4);
+ __raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STAGE3_MUX5);
+ __raw_writel(0x003b202d, pxp->base + HW_PXP_WFE_B_STAGE3_MUX6);
+ __raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STAGE3_MUX7);
+ __raw_writel(0x07060504, pxp->base + HW_PXP_WFE_B_STAGE3_MUX8);
+ __raw_writel(0x00000008, pxp->base + HW_PXP_WFE_B_STAGE3_MUX9);
+ __raw_writel(0x03020100, pxp->base + HW_PXP_WFE_B_STAGE3_MUX10);
+
+ __raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STG1_5X8_OUT0_0);
+ __raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STG1_5X8_OUT0_1);
+ __raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STG1_5X8_OUT0_2);
+ __raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STG1_5X8_OUT0_3);
+ __raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STG1_5X8_OUT0_4);
+ __raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STG1_5X8_OUT0_5);
+ __raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STG1_5X8_OUT0_6);
+ __raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STG1_5X8_OUT0_7);
+
+ __raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STG1_5X8_OUT1_0);
+ __raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STG1_5X8_OUT1_1);
+ __raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STG1_5X8_OUT1_2);
+ __raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STG1_5X8_OUT1_3);
+ __raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STG1_5X8_OUT1_4);
+ __raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STG1_5X8_OUT1_5);
+ __raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STG1_5X8_OUT1_6);
+ __raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STG1_5X8_OUT1_7);
+
+ __raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STAGE1_5X8_MASKS_0);
+
+ __raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STG1_5X1_OUT0);
+ __raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STG1_5X1_MASKS);
+
+ __raw_writel(0xFFFFFFFF, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT0_2);
+ __raw_writel(0xFFFFFFFF, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT0_3);
+ __raw_writel(0xFFFFFFFF, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT0_4);
+ __raw_writel(0xFFFFFFFF, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT0_5);
+ __raw_writel(0xFFFFFFFF, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT0_6);
+ __raw_writel(0xFFFFFFFF, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT0_7);
+
+ __raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT1_0);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT1_1);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT1_2);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT1_3);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT1_4);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT1_5);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT1_6);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT1_7);
+
+ __raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT2_0);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT2_1);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT2_2);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT2_3);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT2_4);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT2_5);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT2_6);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT2_7);
+
+ __raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT3_0);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT3_1);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT3_2);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT3_3);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT3_4);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT3_5);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT3_6);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT3_7);
+
+ __raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT4_0);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT4_1);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT4_2);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT4_3);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT4_4);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT4_5);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT4_6);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT4_7);
+
+ __raw_writel(0x00000700, pxp->base + HW_PXP_WFE_B_STG2_5X1_OUT0);
+ __raw_writel(0x00007000, pxp->base + HW_PXP_WFE_B_STG2_5X1_OUT1);
+ __raw_writel(0x0000A000, pxp->base + HW_PXP_WFE_B_STG2_5X1_OUT2);
+ __raw_writel(0x000000C0, pxp->base + HW_PXP_WFE_B_STG2_5X1_OUT3);
+ __raw_writel(0x070F1F1F, pxp->base + HW_PXP_WFE_B_STG2_5X1_MASKS);
+
+ __raw_writel(0x001F1F1F, pxp->base + HW_PXP_WFE_B_STAGE2_5X6_MASKS_0);
+ __raw_writel(0x3f232120, pxp->base + HW_PXP_WFE_B_STAGE2_5X6_ADDR_0);
+
+ __raw_writel(0x04040404, pxp->base + HW_PXP_WFE_B_STG2_5X6_OUT0_0);
+ __raw_writel(0x04040404, pxp->base + HW_PXP_WFE_B_STG2_5X6_OUT0_1);
+ __raw_writel(0x04050505, pxp->base + HW_PXP_WFE_B_STG2_5X6_OUT0_2);
+ __raw_writel(0x04040404, pxp->base + HW_PXP_WFE_B_STG2_5X6_OUT0_3);
+ __raw_writel(0x04040404, pxp->base + HW_PXP_WFE_B_STG2_5X6_OUT0_4);
+ __raw_writel(0x04040404, pxp->base + HW_PXP_WFE_B_STG2_5X6_OUT0_5);
+ __raw_writel(0x04040404, pxp->base + HW_PXP_WFE_B_STG2_5X6_OUT0_6);
+ __raw_writel(0x04040404, pxp->base + HW_PXP_WFE_B_STG2_5X6_OUT0_7);
+
+ __raw_writel(0x05050505, pxp->base + HW_PXP_WFE_B_STG2_5X6_OUT1_0);
+ __raw_writel(0x05050505, pxp->base + HW_PXP_WFE_B_STG2_5X6_OUT1_1);
+ __raw_writel(0x05080808, pxp->base + HW_PXP_WFE_B_STG2_5X6_OUT1_2);
+ __raw_writel(0x05050505, pxp->base + HW_PXP_WFE_B_STG2_5X6_OUT1_3);
+ __raw_writel(0x05050505, pxp->base + HW_PXP_WFE_B_STG2_5X6_OUT1_4);
+ __raw_writel(0x05050505, pxp->base + HW_PXP_WFE_B_STG2_5X6_OUT1_5);
+ __raw_writel(0x05050505, pxp->base + HW_PXP_WFE_B_STG2_5X6_OUT1_6);
+ __raw_writel(0x05050505, pxp->base + HW_PXP_WFE_B_STG2_5X6_OUT1_7);
+
+ __raw_writel(0x07070707, pxp->base + HW_PXP_WFE_B_STG2_5X6_OUT2_0);
+ __raw_writel(0x07070707, pxp->base + HW_PXP_WFE_B_STG2_5X6_OUT2_1);
+ __raw_writel(0x070C0C0C, pxp->base + HW_PXP_WFE_B_STG2_5X6_OUT2_2);
+ __raw_writel(0x07070707, pxp->base + HW_PXP_WFE_B_STG2_5X6_OUT2_3);
+ __raw_writel(0x0F0F0F0F, pxp->base + HW_PXP_WFE_B_STG2_5X6_OUT2_4);
+ __raw_writel(0x0F0F0F0F, pxp->base + HW_PXP_WFE_B_STG2_5X6_OUT2_5);
+ __raw_writel(0x0F0F0F0F, pxp->base + HW_PXP_WFE_B_STG2_5X6_OUT2_6);
+ __raw_writel(0x0F0F0F0F, pxp->base + HW_PXP_WFE_B_STG2_5X6_OUT2_7);
+
+ __raw_writel(0, pxp->base + HW_PXP_WFE_B_STG2_5X6_OUT3_0);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_B_STG2_5X6_OUT3_1);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_B_STG2_5X6_OUT3_2);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_B_STG2_5X6_OUT3_3);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_B_STG2_5X6_OUT3_4);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_B_STG2_5X6_OUT3_5);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_B_STG2_5X6_OUT3_6);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_B_STG2_5X6_OUT3_7);
+
+ __raw_writel(0x070F1F1F, pxp->base + HW_PXP_WFE_B_STG3_F8X1_MASKS);
+
+ __raw_writel(0x00000700, pxp->base + HW_PXP_WFE_B_STG3_F8X1_OUT0_0);
+ __raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STG3_F8X1_OUT0_1);
+ __raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STG3_F8X1_OUT0_2);
+ __raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STG3_F8X1_OUT0_3);
+ __raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STG3_F8X1_OUT0_4);
+ __raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STG3_F8X1_OUT0_5);
+ __raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STG3_F8X1_OUT0_6);
+ __raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STG3_F8X1_OUT0_7);
+
+ __raw_writel(0x00007000, pxp->base + HW_PXP_WFE_B_STG3_F8X1_OUT1_0);
+ __raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STG3_F8X1_OUT1_1);
+ __raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STG3_F8X1_OUT1_2);
+ __raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STG3_F8X1_OUT1_3);
+ __raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STG3_F8X1_OUT1_4);
+ __raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STG3_F8X1_OUT1_5);
+ __raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STG3_F8X1_OUT1_6);
+ __raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STG3_F8X1_OUT1_7);
+
+ __raw_writel(0x0000A000, pxp->base + HW_PXP_WFE_B_STG3_F8X1_OUT2_0);
+ __raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STG3_F8X1_OUT2_1);
+ __raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STG3_F8X1_OUT2_2);
+ __raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STG3_F8X1_OUT2_3);
+ __raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STG3_F8X1_OUT2_4);
+ __raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STG3_F8X1_OUT2_5);
+ __raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STG3_F8X1_OUT2_6);
+ __raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STG3_F8X1_OUT2_7);
+
+ __raw_writel(0x000000C0, pxp->base + HW_PXP_WFE_B_STG3_F8X1_OUT3_0);
+ __raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STG3_F8X1_OUT3_1);
+ __raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STG3_F8X1_OUT3_2);
+ __raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STG3_F8X1_OUT3_3);
+ __raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STG3_F8X1_OUT3_4);
+ __raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STG3_F8X1_OUT3_5);
+ __raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STG3_F8X1_OUT3_6);
+ __raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STG3_F8X1_OUT3_7);
+
+ if (pxp->devdata && pxp->devdata->pxp_lut_cleanup_multiple)
+ pxp->devdata->pxp_lut_cleanup_multiple(pxp,
+ proc_data->lut_sels, 1);
+}
+
+/*
+ * wfe a processing
+ * use wfe a to process an update
+ * x,y,width,height:
+ * coordinate and size of the update region
+ * wb:
+ * working buffer, 16bpp
+ * upd:
+ * update buffer, in Y4 with or without alpha, 8bpp
+ * twb:
+ * temp working buffer, 16bpp
+ * only used when reagl_en is 1
+ * y4c:
+ * y4c buffer, {Y4[3:0],3'b000,collision}, 8bpp
+ * lut:
+ * valid value 0-63
+ * set to the lut used for next update
+ * partial:
+ * 0 - full update
+ * 1 - partial update
+ * reagl_en:
+ * 0 - use normal waveform algorithm
+ * 1 - enable reagl/-d waveform algorithm
+ * detection_only:
+ * 0 - write working buffer
+ * 1 - do no write working buffer, detection only
+ * alpha_en:
+ * 0 - upd is {Y4[3:0],4'b0000} format
+ * 1 - upd is {Y4[3:0],3'b000,alpha} format
+ */
+static void pxp_wfe_a_process(struct pxps *pxp)
+{
+ struct pxp_config_data *config_data = &pxp->pxp_conf_state;
+ struct pxp_proc_data *proc_data = &config_data->proc_data;
+ struct pxp_layer_param *fetch_ch0 = &config_data->wfe_a_fetch_param[0];
+ struct pxp_layer_param *fetch_ch1 = &config_data->wfe_a_fetch_param[1];
+ struct pxp_layer_param *store_ch0 = &config_data->wfe_a_store_param[0];
+ struct pxp_layer_param *store_ch1 = &config_data->wfe_a_store_param[1];
+ int v;
+
+ if (fetch_ch0->width != fetch_ch1->width ||
+ fetch_ch0->height != fetch_ch1->height) {
+ dev_err(pxp->dev, "width/height should be same for two fetch "
+ "channels\n");
+ }
+
+ print_param(fetch_ch0, "wfe_a fetch_ch0");
+ print_param(fetch_ch1, "wfe_a fetch_ch1");
+ print_param(store_ch0, "wfe_a store_ch0");
+ print_param(store_ch1, "wfe_a store_ch1");
+
+ /* Fetch */
+ __raw_writel(fetch_ch0->paddr, pxp->base + HW_PXP_WFA_FETCH_BUF1_ADDR);
+
+ __raw_writel(BF_PXP_WFA_FETCH_BUF1_CORD_YCORD(fetch_ch0->top) |
+ BF_PXP_WFA_FETCH_BUF1_CORD_XCORD(fetch_ch0->left),
+ pxp->base + HW_PXP_WFA_FETCH_BUF1_CORD);
+
+ __raw_writel(fetch_ch0->stride, pxp->base + HW_PXP_WFA_FETCH_BUF1_PITCH);
+
+ __raw_writel(BF_PXP_WFA_FETCH_BUF1_SIZE_BUF_HEIGHT(fetch_ch0->height - 1) |
+ BF_PXP_WFA_FETCH_BUF1_SIZE_BUF_WIDTH(fetch_ch0->width - 1),
+ pxp->base + HW_PXP_WFA_FETCH_BUF1_SIZE);
+
+ __raw_writel(fetch_ch1->paddr, pxp->base + HW_PXP_WFA_FETCH_BUF2_ADDR);
+
+ __raw_writel(BF_PXP_WFA_FETCH_BUF2_CORD_YCORD(fetch_ch1->top) |
+ BF_PXP_WFA_FETCH_BUF2_CORD_XCORD(fetch_ch1->left),
+ pxp->base + HW_PXP_WFA_FETCH_BUF2_CORD);
+
+ __raw_writel(fetch_ch1->stride * 2, pxp->base + HW_PXP_WFA_FETCH_BUF2_PITCH);
+
+ __raw_writel(BF_PXP_WFA_FETCH_BUF2_SIZE_BUF_HEIGHT(fetch_ch1->height - 1) |
+ BF_PXP_WFA_FETCH_BUF2_SIZE_BUF_WIDTH(fetch_ch1->width - 1),
+ pxp->base + HW_PXP_WFA_FETCH_BUF2_SIZE);
+
+ /* Store */
+ __raw_writel(BF_PXP_WFE_A_STORE_SIZE_CH0_OUT_WIDTH(store_ch0->width - 1) |
+ BF_PXP_WFE_A_STORE_SIZE_CH0_OUT_HEIGHT(store_ch0->height - 1),
+ pxp->base + HW_PXP_WFE_A_STORE_SIZE_CH0);
+
+
+ __raw_writel(BF_PXP_WFE_A_STORE_SIZE_CH1_OUT_WIDTH(store_ch1->width - 1) |
+ BF_PXP_WFE_A_STORE_SIZE_CH1_OUT_HEIGHT(store_ch1->height - 1),
+ pxp->base + HW_PXP_WFE_A_STORE_SIZE_CH1);
+
+ __raw_writel(BF_PXP_WFE_A_STORE_PITCH_CH0_OUT_PITCH(store_ch0->stride) |
+ BF_PXP_WFE_A_STORE_PITCH_CH1_OUT_PITCH(store_ch1->stride * 2),
+ pxp->base + HW_PXP_WFE_A_STORE_PITCH);
+
+ __raw_writel(BF_PXP_WFE_A_STORE_ADDR_0_CH0_OUT_BASE_ADDR0(store_ch0->paddr),
+ pxp->base + HW_PXP_WFE_A_STORE_ADDR_0_CH0);
+ __raw_writel(BF_PXP_WFE_A_STORE_ADDR_1_CH0_OUT_BASE_ADDR1(0),
+ pxp->base + HW_PXP_WFE_A_STORE_ADDR_1_CH0);
+
+ __raw_writel(BF_PXP_WFE_A_STORE_ADDR_0_CH1_OUT_BASE_ADDR0(
+ store_ch1->paddr + (store_ch1->left + store_ch1->top *
+ store_ch1->stride) * 2),
+ pxp->base + HW_PXP_WFE_A_STORE_ADDR_0_CH1);
+
+ __raw_writel(BF_PXP_WFE_A_STORE_ADDR_1_CH1_OUT_BASE_ADDR1(0),
+ pxp->base + HW_PXP_WFE_A_STORE_ADDR_1_CH1);
+
+ /* ALU */
+ __raw_writel(BF_PXP_ALU_A_BUF_SIZE_BUF_WIDTH(fetch_ch0->width) |
+ BF_PXP_ALU_A_BUF_SIZE_BUF_HEIGHT(fetch_ch0->height),
+ pxp->base + HW_PXP_ALU_A_BUF_SIZE);
+
+ /* WFE */
+ __raw_writel(BF_PXP_WFE_A_DIMENSIONS_WIDTH(fetch_ch0->width) |
+ BF_PXP_WFE_A_DIMENSIONS_HEIGHT(fetch_ch0->height),
+ pxp->base + HW_PXP_WFE_A_DIMENSIONS);
+
+ /* Here it should be fetch_ch1 */
+ __raw_writel(BF_PXP_WFE_A_OFFSET_X_OFFSET(fetch_ch1->left) |
+ BF_PXP_WFE_A_OFFSET_Y_OFFSET(fetch_ch1->top),
+ pxp->base + HW_PXP_WFE_A_OFFSET);
+
+ __raw_writel((proc_data->lut & 0x000000FF) | 0x00000F00,
+ pxp->base + HW_PXP_WFE_A_SW_DATA_REGS);
+ __raw_writel((proc_data->partial_update | (proc_data->reagl_en << 1)),
+ pxp->base + HW_PXP_WFE_A_SW_FLAG_REGS);
+
+ __raw_writel(
+ BF_PXP_WFE_A_CTRL_ENABLE(1) |
+ BF_PXP_WFE_A_CTRL_SW_RESET(1),
+ pxp->base + HW_PXP_WFE_A_CTRL);
+
+ if (proc_data->alpha_en) {
+ __raw_writel(BF_PXP_WFA_ARRAY_FLAG0_MASK_SIGN_Y(0) |
+ BF_PXP_WFA_ARRAY_FLAG0_MASK_OFFSET_Y(0) |
+ BF_PXP_WFA_ARRAY_FLAG0_MASK_SIGN_X(0) |
+ BF_PXP_WFA_ARRAY_FLAG0_MASK_OFFSET_X(0) |
+ BF_PXP_WFA_ARRAY_FLAG0_MASK_BUF_SEL(0) |
+ BF_PXP_WFA_ARRAY_FLAG0_MASK_H_OFS(0) |
+ BF_PXP_WFA_ARRAY_FLAG0_MASK_L_OFS(0),
+ pxp->base + HW_PXP_WFA_ARRAY_FLAG0_MASK);
+ } else {
+ __raw_writel(BF_PXP_WFA_ARRAY_FLAG0_MASK_SIGN_Y(0) |
+ BF_PXP_WFA_ARRAY_FLAG0_MASK_OFFSET_Y(0) |
+ BF_PXP_WFA_ARRAY_FLAG0_MASK_SIGN_X(0) |
+ BF_PXP_WFA_ARRAY_FLAG0_MASK_OFFSET_X(0) |
+ BF_PXP_WFA_ARRAY_FLAG0_MASK_BUF_SEL(2) |
+ BF_PXP_WFA_ARRAY_FLAG0_MASK_H_OFS(0) |
+ BF_PXP_WFA_ARRAY_FLAG0_MASK_L_OFS(0),
+ pxp->base + HW_PXP_WFA_ARRAY_FLAG0_MASK);
+ }
+
+ /* disable CH1 when only doing detection */
+ v = __raw_readl(pxp->base + HW_PXP_WFE_A_STORE_CTRL_CH1);
+ if (proc_data->detection_only) {
+ v &= ~BF_PXP_WFE_A_STORE_CTRL_CH1_CH_EN(1);
+ printk(KERN_EMERG "%s: detection only happens\n", __func__);
+ } else
+ v |= BF_PXP_WFE_A_STORE_CTRL_CH1_CH_EN(1);
+ __raw_writel(v, pxp->base + HW_PXP_WFE_A_STORE_CTRL_CH1);
+}
+
+static void pxp_wfe_a_process_v3p(struct pxps *pxp)
+{
+ struct pxp_config_data *config_data = &pxp->pxp_conf_state;
+ struct pxp_proc_data *proc_data = &config_data->proc_data;
+ struct pxp_layer_param *fetch_ch0 = &config_data->wfe_a_fetch_param[0];
+ struct pxp_layer_param *fetch_ch1 = &config_data->wfe_a_fetch_param[1];
+ struct pxp_layer_param *store_ch0 = &config_data->wfe_a_store_param[0];
+ struct pxp_layer_param *store_ch1 = &config_data->wfe_a_store_param[1];
+ int v;
+
+ if (fetch_ch0->width != fetch_ch1->width ||
+ fetch_ch0->height != fetch_ch1->height) {
+ dev_err(pxp->dev, "width/height should be same for two fetch "
+ "channels\n");
+ }
+
+ print_param(fetch_ch0, "wfe_a fetch_ch0");
+ print_param(fetch_ch1, "wfe_a fetch_ch1");
+ print_param(store_ch0, "wfe_a store_ch0");
+ print_param(store_ch1, "wfe_a store_ch1");
+
+ /* Fetch */
+ __raw_writel(fetch_ch0->paddr, pxp->base + HW_PXP_WFB_FETCH_BUF1_ADDR);
+
+ __raw_writel(BF_PXP_WFB_FETCH_BUF1_CORD_YCORD(fetch_ch0->top) |
+ BF_PXP_WFB_FETCH_BUF1_CORD_XCORD(fetch_ch0->left),
+ pxp->base + HW_PXP_WFB_FETCH_BUF1_CORD);
+
+ __raw_writel(fetch_ch0->stride, pxp->base + HW_PXP_WFB_FETCH_BUF1_PITCH);
+
+ __raw_writel(BF_PXP_WFB_FETCH_BUF1_SIZE_BUF_HEIGHT(fetch_ch0->height - 1) |
+ BF_PXP_WFB_FETCH_BUF1_SIZE_BUF_WIDTH(fetch_ch0->width - 1),
+ pxp->base + HW_PXP_WFB_FETCH_BUF1_SIZE);
+
+ __raw_writel(fetch_ch1->paddr, pxp->base + HW_PXP_WFB_FETCH_BUF2_ADDR);
+
+ __raw_writel(BF_PXP_WFB_FETCH_BUF2_CORD_YCORD(fetch_ch1->top) |
+ BF_PXP_WFB_FETCH_BUF2_CORD_XCORD(fetch_ch1->left),
+ pxp->base + HW_PXP_WFB_FETCH_BUF2_CORD);
+
+ __raw_writel(fetch_ch1->stride * 2, pxp->base + HW_PXP_WFB_FETCH_BUF2_PITCH);
+
+ __raw_writel(BF_PXP_WFB_FETCH_BUF2_SIZE_BUF_HEIGHT(fetch_ch1->height - 1) |
+ BF_PXP_WFB_FETCH_BUF2_SIZE_BUF_WIDTH(fetch_ch1->width - 1),
+ pxp->base + HW_PXP_WFB_FETCH_BUF2_SIZE);
+
+ /* Store */
+ __raw_writel(BF_PXP_WFE_B_STORE_SIZE_CH0_OUT_WIDTH(store_ch0->width - 1) |
+ BF_PXP_WFE_B_STORE_SIZE_CH0_OUT_HEIGHT(store_ch0->height - 1),
+ pxp->base + HW_PXP_WFE_B_STORE_SIZE_CH0);
+
+
+ __raw_writel(BF_PXP_WFE_B_STORE_SIZE_CH1_OUT_WIDTH(store_ch1->width - 1) |
+ BF_PXP_WFE_B_STORE_SIZE_CH1_OUT_HEIGHT(store_ch1->height - 1),
+ pxp->base + HW_PXP_WFE_B_STORE_SIZE_CH1);
+
+ __raw_writel(BF_PXP_WFE_B_STORE_PITCH_CH0_OUT_PITCH(store_ch0->stride) |
+ BF_PXP_WFE_B_STORE_PITCH_CH1_OUT_PITCH(store_ch1->stride * 2),
+ pxp->base + HW_PXP_WFE_B_STORE_PITCH);
+
+ __raw_writel(BF_PXP_WFE_B_STORE_ADDR_0_CH0_OUT_BASE_ADDR0(store_ch0->paddr),
+ pxp->base + HW_PXP_WFE_B_STORE_ADDR_0_CH0);
+ __raw_writel(BF_PXP_WFE_B_STORE_ADDR_1_CH0_OUT_BASE_ADDR1(0),
+ pxp->base + HW_PXP_WFE_B_STORE_ADDR_1_CH0);
+
+ __raw_writel(BF_PXP_WFE_B_STORE_ADDR_0_CH1_OUT_BASE_ADDR0(
+ store_ch1->paddr + (store_ch1->left + store_ch1->top *
+ store_ch1->stride) * 2),
+ pxp->base + HW_PXP_WFE_B_STORE_ADDR_0_CH1);
+
+ __raw_writel(BF_PXP_WFE_B_STORE_ADDR_1_CH1_OUT_BASE_ADDR1(0),
+ pxp->base + HW_PXP_WFE_B_STORE_ADDR_1_CH1);
+
+ /* ALU */
+ __raw_writel(BF_PXP_ALU_B_BUF_SIZE_BUF_WIDTH(fetch_ch0->width) |
+ BF_PXP_ALU_B_BUF_SIZE_BUF_HEIGHT(fetch_ch0->height),
+ pxp->base + HW_PXP_ALU_B_BUF_SIZE);
+
+ /* WFE */
+ __raw_writel(BF_PXP_WFE_B_DIMENSIONS_WIDTH(fetch_ch0->width) |
+ BF_PXP_WFE_B_DIMENSIONS_HEIGHT(fetch_ch0->height),
+ pxp->base + HW_PXP_WFE_B_DIMENSIONS);
+
+ /* Here it should be fetch_ch1 */
+ __raw_writel(BF_PXP_WFE_B_OFFSET_X_OFFSET(fetch_ch1->left) |
+ BF_PXP_WFE_B_OFFSET_Y_OFFSET(fetch_ch1->top),
+ pxp->base + HW_PXP_WFE_B_OFFSET);
+
+ __raw_writel((proc_data->lut & 0x000000FF) | 0x00000F00,
+ pxp->base + HW_PXP_WFE_B_SW_DATA_REGS);
+ __raw_writel((proc_data->partial_update | (proc_data->reagl_en << 1)),
+ pxp->base + HW_PXP_WFE_B_SW_FLAG_REGS);
+
+ __raw_writel(
+ BF_PXP_WFE_B_CTRL_ENABLE(1) |
+ BF_PXP_WFE_B_CTRL_SW_RESET(1),
+ pxp->base + HW_PXP_WFE_B_CTRL);
+
+ if (proc_data->alpha_en) {
+ __raw_writel(BF_PXP_WFB_ARRAY_FLAG0_MASK_SIGN_Y(0) |
+ BF_PXP_WFB_ARRAY_FLAG0_MASK_OFFSET_Y(0) |
+ BF_PXP_WFB_ARRAY_FLAG0_MASK_SIGN_X(0) |
+ BF_PXP_WFB_ARRAY_FLAG0_MASK_OFFSET_X(0) |
+ BF_PXP_WFB_ARRAY_FLAG0_MASK_BUF_SEL(0) |
+ BF_PXP_WFB_ARRAY_FLAG0_MASK_H_OFS(0) |
+ BF_PXP_WFB_ARRAY_FLAG0_MASK_L_OFS(0),
+ pxp->base + HW_PXP_WFB_ARRAY_FLAG0_MASK);
+ } else {
+ __raw_writel(BF_PXP_WFB_ARRAY_FLAG0_MASK_SIGN_Y(0) |
+ BF_PXP_WFB_ARRAY_FLAG0_MASK_OFFSET_Y(0) |
+ BF_PXP_WFB_ARRAY_FLAG0_MASK_SIGN_X(0) |
+ BF_PXP_WFB_ARRAY_FLAG0_MASK_OFFSET_X(0) |
+ BF_PXP_WFB_ARRAY_FLAG0_MASK_BUF_SEL(2) |
+ BF_PXP_WFB_ARRAY_FLAG0_MASK_H_OFS(0) |
+ BF_PXP_WFB_ARRAY_FLAG0_MASK_L_OFS(0),
+ pxp->base + HW_PXP_WFB_ARRAY_FLAG0_MASK);
+ }
+
+ /* disable CH1 when only doing detection */
+ v = __raw_readl(pxp->base + HW_PXP_WFE_B_STORE_CTRL_CH1);
+ if (proc_data->detection_only) {
+ v &= ~BF_PXP_WFE_B_STORE_CTRL_CH1_CH_EN(1);
+ printk(KERN_EMERG "%s: detection only happens\n", __func__);
+ } else
+ v |= BF_PXP_WFE_B_STORE_CTRL_CH1_CH_EN(1);
+ __raw_writel(v, pxp->base + HW_PXP_WFE_B_STORE_CTRL_CH1);
+}
+
+/*
+ * wfe b configuration
+ *
+ * configure wfe b engnine for reagl/-d waveform processing
+ */
+static void pxp_wfe_b_configure(struct pxps *pxp)
+{
+ /* Fetch */
+ __raw_writel(
+ BF_PXP_WFB_FETCH_CTRL_BF1_EN(1) |
+ BF_PXP_WFB_FETCH_CTRL_BF1_HSK_MODE(0) |
+ BF_PXP_WFB_FETCH_CTRL_BF1_BYTES_PP(0) |
+ BF_PXP_WFB_FETCH_CTRL_BF1_LINE_MODE(1) |
+ BF_PXP_WFB_FETCH_CTRL_BF1_SRAM_IF(1) |
+ BF_PXP_WFB_FETCH_CTRL_BF1_BURST_LEN(0) |
+ BF_PXP_WFB_FETCH_CTRL_BF1_BYPASS_MODE(0) |
+ BF_PXP_WFB_FETCH_CTRL_BF1_BORDER_MODE(1) |
+ BF_PXP_WFB_FETCH_CTRL_BF2_EN(1) |
+ BF_PXP_WFB_FETCH_CTRL_BF2_HSK_MODE(0) |
+ BF_PXP_WFB_FETCH_CTRL_BF2_BYTES_PP(1) |
+ BF_PXP_WFB_FETCH_CTRL_BF2_LINE_MODE(1) |
+ BF_PXP_WFB_FETCH_CTRL_BF2_SRAM_IF(0) |
+ BF_PXP_WFB_FETCH_CTRL_BF2_BURST_LEN(0) |
+ BF_PXP_WFB_FETCH_CTRL_BF2_BORDER_MODE(1) |
+ BF_PXP_WFB_FETCH_CTRL_BF2_BYPASS_MODE(0),
+ pxp->base + HW_PXP_WFB_FETCH_CTRL);
+
+ __raw_writel(
+ BF_PXP_WFB_ARRAY_PIXEL0_MASK_SIGN_Y(0) |
+ BF_PXP_WFB_ARRAY_PIXEL0_MASK_OFFSET_Y(0) |
+ BF_PXP_WFB_ARRAY_PIXEL0_MASK_SIGN_X(0) |
+ BF_PXP_WFB_ARRAY_PIXEL0_MASK_OFFSET_X(0) |
+ BF_PXP_WFB_ARRAY_PIXEL0_MASK_BUF_SEL(1) |
+ BF_PXP_WFB_ARRAY_PIXEL0_MASK_H_OFS(0) |
+ BF_PXP_WFB_ARRAY_PIXEL0_MASK_L_OFS(7),
+ pxp->base + HW_PXP_WFB_ARRAY_PIXEL0_MASK);
+
+ __raw_writel(
+ BF_PXP_WFB_ARRAY_PIXEL1_MASK_SIGN_Y(0) |
+ BF_PXP_WFB_ARRAY_PIXEL1_MASK_OFFSET_Y(0) |
+ BF_PXP_WFB_ARRAY_PIXEL1_MASK_SIGN_X(0) |
+ BF_PXP_WFB_ARRAY_PIXEL1_MASK_OFFSET_X(0) |
+ BF_PXP_WFB_ARRAY_PIXEL1_MASK_BUF_SEL(1) |
+ BF_PXP_WFB_ARRAY_PIXEL1_MASK_H_OFS(10) |
+ BF_PXP_WFB_ARRAY_PIXEL1_MASK_L_OFS(15),
+ pxp->base + HW_PXP_WFB_ARRAY_PIXEL1_MASK);
+
+ __raw_writel(
+ BF_PXP_WFB_ARRAY_PIXEL2_MASK_SIGN_Y(0) |
+ BF_PXP_WFB_ARRAY_PIXEL2_MASK_OFFSET_Y(0) |
+ BF_PXP_WFB_ARRAY_PIXEL2_MASK_SIGN_X(0) |
+ BF_PXP_WFB_ARRAY_PIXEL2_MASK_OFFSET_X(0) |
+ BF_PXP_WFB_ARRAY_PIXEL2_MASK_BUF_SEL(0) |
+ BF_PXP_WFB_ARRAY_PIXEL2_MASK_H_OFS(2) |
+ BF_PXP_WFB_ARRAY_PIXEL2_MASK_L_OFS(7),
+ pxp->base + HW_PXP_WFB_ARRAY_PIXEL2_MASK);
+
+ __raw_writel(
+ BF_PXP_WFB_ARRAY_PIXEL3_MASK_SIGN_Y(0) |
+ BF_PXP_WFB_ARRAY_PIXEL3_MASK_OFFSET_Y(0) |
+ BF_PXP_WFB_ARRAY_PIXEL3_MASK_SIGN_X(0) |
+ BF_PXP_WFB_ARRAY_PIXEL3_MASK_OFFSET_X(0) |
+ BF_PXP_WFB_ARRAY_PIXEL3_MASK_BUF_SEL(0) |
+ BF_PXP_WFB_ARRAY_PIXEL3_MASK_H_OFS(0) |
+ BF_PXP_WFB_ARRAY_PIXEL3_MASK_L_OFS(7),
+ pxp->base + HW_PXP_WFB_ARRAY_PIXEL3_MASK);
+
+ __raw_writel(
+ BF_PXP_WFB_ARRAY_PIXEL4_MASK_SIGN_Y(0) |
+ BF_PXP_WFB_ARRAY_PIXEL4_MASK_OFFSET_Y(0) |
+ BF_PXP_WFB_ARRAY_PIXEL4_MASK_SIGN_X(1) |
+ BF_PXP_WFB_ARRAY_PIXEL4_MASK_OFFSET_X(1) |
+ BF_PXP_WFB_ARRAY_PIXEL4_MASK_BUF_SEL(0) |
+ BF_PXP_WFB_ARRAY_PIXEL4_MASK_H_OFS(0) |
+ BF_PXP_WFB_ARRAY_PIXEL4_MASK_L_OFS(7),
+ pxp->base + HW_PXP_WFB_ARRAY_PIXEL4_MASK);
+
+ __raw_writel(
+ BF_PXP_WFB_ARRAY_PIXEL5_MASK_SIGN_Y(0) |
+ BF_PXP_WFB_ARRAY_PIXEL5_MASK_OFFSET_Y(0) |
+ BF_PXP_WFB_ARRAY_PIXEL5_MASK_SIGN_X(0) |
+ BF_PXP_WFB_ARRAY_PIXEL5_MASK_OFFSET_X(1) |
+ BF_PXP_WFB_ARRAY_PIXEL5_MASK_BUF_SEL(0) |
+ BF_PXP_WFB_ARRAY_PIXEL5_MASK_H_OFS(0) |
+ BF_PXP_WFB_ARRAY_PIXEL5_MASK_L_OFS(7),
+ pxp->base + HW_PXP_WFB_ARRAY_PIXEL5_MASK);
+
+ __raw_writel(
+ BF_PXP_WFB_ARRAY_PIXEL6_MASK_SIGN_Y(1) |
+ BF_PXP_WFB_ARRAY_PIXEL6_MASK_OFFSET_Y(1) |
+ BF_PXP_WFB_ARRAY_PIXEL6_MASK_SIGN_X(0) |
+ BF_PXP_WFB_ARRAY_PIXEL6_MASK_OFFSET_X(0) |
+ BF_PXP_WFB_ARRAY_PIXEL6_MASK_BUF_SEL(0) |
+ BF_PXP_WFB_ARRAY_PIXEL6_MASK_H_OFS(0) |
+ BF_PXP_WFB_ARRAY_PIXEL6_MASK_L_OFS(7),
+ pxp->base + HW_PXP_WFB_ARRAY_PIXEL6_MASK);
+
+ __raw_writel(
+ BF_PXP_WFB_ARRAY_PIXEL7_MASK_SIGN_Y(0) |
+ BF_PXP_WFB_ARRAY_PIXEL7_MASK_OFFSET_Y(1) |
+ BF_PXP_WFB_ARRAY_PIXEL7_MASK_SIGN_X(0) |
+ BF_PXP_WFB_ARRAY_PIXEL7_MASK_OFFSET_X(0) |
+ BF_PXP_WFB_ARRAY_PIXEL7_MASK_BUF_SEL(0) |
+ BF_PXP_WFB_ARRAY_PIXEL7_MASK_H_OFS(0) |
+ BF_PXP_WFB_ARRAY_PIXEL7_MASK_L_OFS(7),
+ pxp->base + HW_PXP_WFB_ARRAY_PIXEL7_MASK);
+
+ __raw_writel(
+ BF_PXP_WFB_ARRAY_FLAG0_MASK_SIGN_Y(0) |
+ BF_PXP_WFB_ARRAY_FLAG0_MASK_OFFSET_Y(0) |
+ BF_PXP_WFB_ARRAY_FLAG0_MASK_SIGN_X(0) |
+ BF_PXP_WFB_ARRAY_FLAG0_MASK_OFFSET_X(0) |
+ BF_PXP_WFB_ARRAY_FLAG0_MASK_BUF_SEL(1) |
+ BF_PXP_WFB_ARRAY_FLAG0_MASK_H_OFS(8) |
+ BF_PXP_WFB_ARRAY_FLAG0_MASK_L_OFS(8),
+ pxp->base + HW_PXP_WFB_ARRAY_FLAG0_MASK);
+
+ __raw_writel(
+ BF_PXP_WFB_ARRAY_FLAG1_MASK_SIGN_Y(0) |
+ BF_PXP_WFB_ARRAY_FLAG1_MASK_OFFSET_Y(0) |
+ BF_PXP_WFB_ARRAY_FLAG1_MASK_SIGN_X(0) |
+ BF_PXP_WFB_ARRAY_FLAG1_MASK_OFFSET_X(0) |
+ BF_PXP_WFB_ARRAY_FLAG1_MASK_BUF_SEL(1) |
+ BF_PXP_WFB_ARRAY_FLAG1_MASK_H_OFS(9) |
+ BF_PXP_WFB_ARRAY_FLAG1_MASK_L_OFS(9),
+ pxp->base + HW_PXP_WFB_ARRAY_FLAG1_MASK);
+
+ __raw_writel(
+ BF_PXP_WFB_ARRAY_FLAG2_MASK_SIGN_Y(0) |
+ BF_PXP_WFB_ARRAY_FLAG2_MASK_OFFSET_Y(0) |
+ BF_PXP_WFB_ARRAY_FLAG2_MASK_SIGN_X(1) |
+ BF_PXP_WFB_ARRAY_FLAG2_MASK_OFFSET_X(1) |
+ BF_PXP_WFB_ARRAY_FLAG2_MASK_BUF_SEL(1) |
+ BF_PXP_WFB_ARRAY_FLAG2_MASK_H_OFS(8) |
+ BF_PXP_WFB_ARRAY_FLAG2_MASK_L_OFS(8),
+ pxp->base + HW_PXP_WFB_ARRAY_FLAG2_MASK);
+
+ __raw_writel(
+ BF_PXP_WFB_ARRAY_FLAG3_MASK_SIGN_Y(0) |
+ BF_PXP_WFB_ARRAY_FLAG3_MASK_OFFSET_Y(0) |
+ BF_PXP_WFB_ARRAY_FLAG3_MASK_SIGN_X(1) |
+ BF_PXP_WFB_ARRAY_FLAG3_MASK_OFFSET_X(1) |
+ BF_PXP_WFB_ARRAY_FLAG3_MASK_BUF_SEL(1) |
+ BF_PXP_WFB_ARRAY_FLAG3_MASK_H_OFS(9) |
+ BF_PXP_WFB_ARRAY_FLAG3_MASK_L_OFS(9),
+ pxp->base + HW_PXP_WFB_ARRAY_FLAG3_MASK);
+
+ __raw_writel(
+ BF_PXP_WFB_ARRAY_FLAG4_MASK_SIGN_Y(0) |
+ BF_PXP_WFB_ARRAY_FLAG4_MASK_OFFSET_Y(0) |
+ BF_PXP_WFB_ARRAY_FLAG4_MASK_SIGN_X(0) |
+ BF_PXP_WFB_ARRAY_FLAG4_MASK_OFFSET_X(1) |
+ BF_PXP_WFB_ARRAY_FLAG4_MASK_BUF_SEL(1) |
+ BF_PXP_WFB_ARRAY_FLAG4_MASK_H_OFS(8) |
+ BF_PXP_WFB_ARRAY_FLAG4_MASK_L_OFS(8),
+ pxp->base + HW_PXP_WFB_ARRAY_FLAG4_MASK);
+
+ __raw_writel(
+ BF_PXP_WFB_ARRAY_FLAG5_MASK_SIGN_Y(0) |
+ BF_PXP_WFB_ARRAY_FLAG5_MASK_OFFSET_Y(0) |
+ BF_PXP_WFB_ARRAY_FLAG5_MASK_SIGN_X(0) |
+ BF_PXP_WFB_ARRAY_FLAG5_MASK_OFFSET_X(1) |
+ BF_PXP_WFB_ARRAY_FLAG5_MASK_BUF_SEL(1) |
+ BF_PXP_WFB_ARRAY_FLAG5_MASK_H_OFS(9) |
+ BF_PXP_WFB_ARRAY_FLAG5_MASK_L_OFS(9),
+ pxp->base + HW_PXP_WFB_ARRAY_FLAG5_MASK);
+
+ __raw_writel(
+ BF_PXP_WFB_ARRAY_FLAG6_MASK_SIGN_Y(1) |
+ BF_PXP_WFB_ARRAY_FLAG6_MASK_OFFSET_Y(1) |
+ BF_PXP_WFB_ARRAY_FLAG6_MASK_SIGN_X(0) |
+ BF_PXP_WFB_ARRAY_FLAG6_MASK_OFFSET_X(0) |
+ BF_PXP_WFB_ARRAY_FLAG6_MASK_BUF_SEL(1) |
+ BF_PXP_WFB_ARRAY_FLAG6_MASK_H_OFS(8) |
+ BF_PXP_WFB_ARRAY_FLAG6_MASK_L_OFS(8),
+ pxp->base + HW_PXP_WFB_ARRAY_FLAG6_MASK);
+
+ __raw_writel(
+ BF_PXP_WFB_ARRAY_FLAG7_MASK_SIGN_Y(1) |
+ BF_PXP_WFB_ARRAY_FLAG7_MASK_OFFSET_Y(1) |
+ BF_PXP_WFB_ARRAY_FLAG7_MASK_SIGN_X(0) |
+ BF_PXP_WFB_ARRAY_FLAG7_MASK_OFFSET_X(0) |
+ BF_PXP_WFB_ARRAY_FLAG7_MASK_BUF_SEL(1) |
+ BF_PXP_WFB_ARRAY_FLAG7_MASK_H_OFS(9) |
+ BF_PXP_WFB_ARRAY_FLAG7_MASK_L_OFS(9),
+ pxp->base + HW_PXP_WFB_ARRAY_FLAG7_MASK);
+
+ __raw_writel(
+ BF_PXP_WFB_ARRAY_FLAG8_MASK_SIGN_Y(0) |
+ BF_PXP_WFB_ARRAY_FLAG8_MASK_OFFSET_Y(1) |
+ BF_PXP_WFB_ARRAY_FLAG8_MASK_SIGN_X(0) |
+ BF_PXP_WFB_ARRAY_FLAG8_MASK_OFFSET_X(0) |
+ BF_PXP_WFB_ARRAY_FLAG8_MASK_BUF_SEL(1) |
+ BF_PXP_WFB_ARRAY_FLAG8_MASK_H_OFS(8) |
+ BF_PXP_WFB_ARRAY_FLAG8_MASK_L_OFS(8),
+ pxp->base + HW_PXP_WFB_ARRAY_FLAG8_MASK);
+
+ __raw_writel(
+ BF_PXP_WFB_ARRAY_FLAG9_MASK_SIGN_Y(0) |
+ BF_PXP_WFB_ARRAY_FLAG9_MASK_OFFSET_Y(1) |
+ BF_PXP_WFB_ARRAY_FLAG9_MASK_SIGN_X(0) |
+ BF_PXP_WFB_ARRAY_FLAG9_MASK_OFFSET_X(0) |
+ BF_PXP_WFB_ARRAY_FLAG9_MASK_BUF_SEL(1) |
+ BF_PXP_WFB_ARRAY_FLAG9_MASK_H_OFS(9) |
+ BF_PXP_WFB_ARRAY_FLAG9_MASK_L_OFS(9),
+ pxp->base + HW_PXP_WFB_ARRAY_FLAG9_MASK);
+
+ pxp_sram_init(pxp, WFE_B, (u32)active_matrix_data_8x8, 64);
+
+ /* Store */
+ __raw_writel(
+ BF_PXP_WFE_B_STORE_CTRL_CH0_CH_EN(1)|
+ BF_PXP_WFE_B_STORE_CTRL_CH0_BLOCK_EN(0)|
+ BF_PXP_WFE_B_STORE_CTRL_CH0_BLOCK_16(0)|
+ BF_PXP_WFE_B_STORE_CTRL_CH0_HANDSHAKE_EN(0)|
+ BF_PXP_WFE_B_STORE_CTRL_CH0_ARRAY_EN(0)|
+ BF_PXP_WFE_B_STORE_CTRL_CH0_ARRAY_LINE_NUM(0)|
+ BF_PXP_WFE_B_STORE_CTRL_CH0_STORE_BYPASS_EN(0)|
+ BF_PXP_WFE_B_STORE_CTRL_CH0_STORE_MEMORY_EN(1)|
+ BF_PXP_WFE_B_STORE_CTRL_CH0_PACK_IN_SEL(1)|
+ BF_PXP_WFE_B_STORE_CTRL_CH0_FILL_DATA_EN(0)|
+ BF_PXP_WFE_B_STORE_CTRL_CH0_WR_NUM_BYTES(32)|
+ BF_PXP_WFE_B_STORE_CTRL_CH0_COMBINE_2CHANNEL(1) |
+ BF_PXP_WFE_B_STORE_CTRL_CH0_ARBIT_EN(0),
+ pxp->base + HW_PXP_WFE_B_STORE_CTRL_CH0);
+
+ __raw_writel(
+ BF_PXP_WFE_B_STORE_CTRL_CH1_CH_EN(0)|
+ BF_PXP_WFE_B_STORE_CTRL_CH1_BLOCK_EN(0)|
+ BF_PXP_WFE_B_STORE_CTRL_CH1_BLOCK_16(0)|
+ BF_PXP_WFE_B_STORE_CTRL_CH1_HANDSHAKE_EN(0)|
+ BF_PXP_WFE_B_STORE_CTRL_CH1_ARRAY_EN(0)|
+ BF_PXP_WFE_B_STORE_CTRL_CH1_ARRAY_LINE_NUM(0)|
+ BF_PXP_WFE_B_STORE_CTRL_CH1_STORE_BYPASS_EN(0)|
+ BF_PXP_WFE_B_STORE_CTRL_CH1_STORE_MEMORY_EN(0)|
+ BF_PXP_WFE_B_STORE_CTRL_CH1_PACK_IN_SEL(1)|
+ BF_PXP_WFE_B_STORE_CTRL_CH1_WR_NUM_BYTES(32),
+ pxp->base + HW_PXP_WFE_B_STORE_CTRL_CH1);
+
+ __raw_writel(
+ BF_PXP_WFE_B_STORE_SHIFT_CTRL_CH0_OUTPUT_ACTIVE_BPP(1)|
+ BF_PXP_WFE_B_STORE_SHIFT_CTRL_CH0_OUT_YUV422_1P_EN(0)|
+ BF_PXP_WFE_B_STORE_SHIFT_CTRL_CH0_OUT_YUV422_2P_EN(0)|
+ BF_PXP_WFE_B_STORE_SHIFT_CTRL_CH0_SHIFT_BYPASS(0),
+ pxp->base + HW_PXP_WFE_B_STORE_SHIFT_CTRL_CH0);
+
+ __raw_writel(
+ BF_PXP_WFE_B_STORE_SHIFT_CTRL_CH0_OUTPUT_ACTIVE_BPP(1)|
+ BF_PXP_WFE_B_STORE_SHIFT_CTRL_CH0_OUT_YUV422_1P_EN(0)|
+ BF_PXP_WFE_B_STORE_SHIFT_CTRL_CH0_OUT_YUV422_2P_EN(0)|
+ BF_PXP_WFE_B_STORE_SHIFT_CTRL_CH0_SHIFT_BYPASS(0),
+ pxp->base + HW_PXP_WFE_B_STORE_SHIFT_CTRL_CH1);
+
+ __raw_writel(BF_PXP_WFE_B_STORE_ADDR_1_CH0_OUT_BASE_ADDR1(0),
+ pxp->base + HW_PXP_WFE_B_STORE_ADDR_1_CH0);
+
+ __raw_writel(BF_PXP_WFE_B_STORE_ADDR_0_CH1_OUT_BASE_ADDR0(0),
+ pxp->base + HW_PXP_WFE_B_STORE_ADDR_0_CH1);
+
+ __raw_writel(BF_PXP_WFE_B_STORE_ADDR_1_CH1_OUT_BASE_ADDR1(0),
+ pxp->base + HW_PXP_WFE_B_STORE_ADDR_1_CH1);
+
+ __raw_writel(BF_PXP_WFE_B_STORE_FILL_DATA_CH0_FILL_DATA_CH0(0),
+ pxp->base + HW_PXP_WFE_B_STORE_FILL_DATA_CH0);
+
+ __raw_writel(BF_PXP_WFE_B_STORE_D_MASK0_H_CH0_D_MASK0_H_CH0(0x00000000),
+ pxp->base + HW_PXP_WFE_B_STORE_D_MASK0_H_CH0);
+
+ __raw_writel(BF_PXP_WFE_B_STORE_D_MASK0_L_CH0_D_MASK0_L_CH0(0xff),
+ pxp->base + HW_PXP_WFE_B_STORE_D_MASK0_L_CH0);
+
+ __raw_writel(BF_PXP_WFE_B_STORE_D_MASK1_H_CH0_D_MASK1_H_CH0(0x0),
+ pxp->base + HW_PXP_WFE_B_STORE_D_MASK1_H_CH0);
+
+ __raw_writel(BF_PXP_WFE_B_STORE_D_MASK1_L_CH0_D_MASK1_L_CH0(0x3f00),
+ pxp->base + HW_PXP_WFE_B_STORE_D_MASK1_L_CH0);
+
+ __raw_writel(BF_PXP_WFE_B_STORE_D_MASK2_H_CH0_D_MASK2_H_CH0(0x0),
+ pxp->base + HW_PXP_WFE_B_STORE_D_MASK2_H_CH0);
+
+ __raw_writel(BF_PXP_WFE_B_STORE_D_MASK2_L_CH0_D_MASK2_L_CH0(0x0),
+ pxp->base + HW_PXP_WFE_B_STORE_D_MASK2_L_CH0);
+
+ __raw_writel(
+ BF_PXP_WFE_B_STORE_D_SHIFT_H_CH0_D_SHIFT_WIDTH4(0) |
+ BF_PXP_WFE_B_STORE_D_SHIFT_H_CH0_D_SHIFT_FLAG4(0) |
+ BF_PXP_WFE_B_STORE_D_SHIFT_H_CH0_D_SHIFT_WIDTH5(0)|
+ BF_PXP_WFE_B_STORE_D_SHIFT_H_CH0_D_SHIFT_FLAG5(0) |
+ BF_PXP_WFE_B_STORE_D_SHIFT_H_CH0_D_SHIFT_WIDTH6(0)|
+ BF_PXP_WFE_B_STORE_D_SHIFT_H_CH0_D_SHIFT_FLAG6(0)|
+ BF_PXP_WFE_B_STORE_D_SHIFT_H_CH0_D_SHIFT_WIDTH7(0)|
+ BF_PXP_WFE_B_STORE_D_SHIFT_H_CH0_D_SHIFT_FLAG7(0),
+ pxp->base + HW_PXP_WFE_B_STORE_D_SHIFT_H_CH0);
+
+ __raw_writel(
+ BF_PXP_WFE_B_STORE_D_SHIFT_L_CH0_D_SHIFT_WIDTH0(0) |
+ BF_PXP_WFE_B_STORE_D_SHIFT_L_CH0_D_SHIFT_FLAG0(0) |
+ BF_PXP_WFE_B_STORE_D_SHIFT_L_CH0_D_SHIFT_WIDTH1(2)|
+ BF_PXP_WFE_B_STORE_D_SHIFT_L_CH0_D_SHIFT_FLAG1(1) |
+ BF_PXP_WFE_B_STORE_D_SHIFT_L_CH0_D_SHIFT_WIDTH2(6)|
+ BF_PXP_WFE_B_STORE_D_SHIFT_L_CH0_D_SHIFT_FLAG2(0)|
+ BF_PXP_WFE_B_STORE_D_SHIFT_L_CH0_D_SHIFT_WIDTH3(0)|
+ BF_PXP_WFE_B_STORE_D_SHIFT_L_CH0_D_SHIFT_FLAG3(0),
+ pxp->base + HW_PXP_WFE_B_STORE_D_SHIFT_L_CH0);
+
+ __raw_writel(
+ BF_PXP_WFE_B_STORE_F_SHIFT_L_CH0_F_SHIFT_WIDTH0(8)|
+ BF_PXP_WFE_B_STORE_F_SHIFT_L_CH0_F_SHIFT_FLAG0(1)|
+ BF_PXP_WFE_B_STORE_F_SHIFT_L_CH0_F_SHIFT_WIDTH1(0)|
+ BF_PXP_WFE_B_STORE_F_SHIFT_L_CH0_F_SHIFT_FLAG1(0)|
+ BF_PXP_WFE_B_STORE_F_SHIFT_L_CH0_F_SHIFT_WIDTH2(0)|
+ BF_PXP_WFE_B_STORE_F_SHIFT_L_CH0_F_SHIFT_FLAG2(0)|
+ BF_PXP_WFE_B_STORE_F_SHIFT_L_CH0_F_SHIFT_WIDTH3(0)|
+ BF_PXP_WFE_B_STORE_F_SHIFT_L_CH0_F_SHIFT_FLAG3(0),
+ pxp->base + HW_PXP_WFE_B_STORE_F_SHIFT_L_CH0);
+
+ __raw_writel(
+ BF_PXP_WFE_B_STORE_F_MASK_H_CH0_F_MASK4(0)|
+ BF_PXP_WFE_B_STORE_F_MASK_H_CH0_F_MASK5(0)|
+ BF_PXP_WFE_B_STORE_F_MASK_H_CH0_F_MASK6(0)|
+ BF_PXP_WFE_B_STORE_F_MASK_H_CH0_F_MASK7(0),
+ pxp->base + HW_PXP_WFE_B_STORE_F_MASK_H_CH0);
+
+ /* ALU */
+ __raw_writel(BF_PXP_ALU_B_INST_ENTRY_ENTRY_ADDR(0),
+ pxp->base + HW_PXP_ALU_B_INST_ENTRY);
+
+ __raw_writel(BF_PXP_ALU_B_PARAM_PARAM0(0) |
+ BF_PXP_ALU_B_PARAM_PARAM1(0),
+ pxp->base + HW_PXP_ALU_B_PARAM);
+
+ __raw_writel(BF_PXP_ALU_B_CONFIG_BUF_ADDR(0),
+ pxp->base + HW_PXP_ALU_B_CONFIG);
+
+ __raw_writel(BF_PXP_ALU_B_LUT_CONFIG_MODE(0) |
+ BF_PXP_ALU_B_LUT_CONFIG_EN(0),
+ pxp->base + HW_PXP_ALU_B_LUT_CONFIG);
+
+ __raw_writel(BF_PXP_ALU_B_LUT_DATA0_LUT_DATA_L(0),
+ pxp->base + HW_PXP_ALU_B_LUT_DATA0);
+
+ __raw_writel(BF_PXP_ALU_B_LUT_DATA1_LUT_DATA_H(0),
+ pxp->base + HW_PXP_ALU_B_LUT_DATA1);
+
+ __raw_writel(
+ BF_PXP_ALU_B_CTRL_BYPASS (1) |
+ BF_PXP_ALU_B_CTRL_ENABLE (1) |
+ BF_PXP_ALU_B_CTRL_START (0) |
+ BF_PXP_ALU_B_CTRL_SW_RESET (0),
+ pxp->base + HW_PXP_ALU_B_CTRL);
+
+ /* WFE */
+ __raw_writel(0x00000402, pxp->base + HW_PXP_WFE_B_SW_DATA_REGS);
+
+ __raw_writel(0x02040608, pxp->base + HW_PXP_WFE_B_STAGE1_MUX0);
+ __raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STAGE1_MUX1);
+ __raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STAGE1_MUX2);
+ __raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STAGE1_MUX3);
+ __raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STAGE1_MUX4);
+ __raw_writel(0x03000000, pxp->base + HW_PXP_WFE_B_STAGE1_MUX5);
+ __raw_writel(0x050A040A, pxp->base + HW_PXP_WFE_B_STAGE1_MUX6);
+ __raw_writel(0x070A060A, pxp->base + HW_PXP_WFE_B_STAGE1_MUX7);
+ __raw_writel(0x0000000A, pxp->base + HW_PXP_WFE_B_STAGE1_MUX8);
+
+ __raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STAGE2_MUX0);
+ __raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STAGE2_MUX1);
+ __raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STAGE2_MUX2);
+ __raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STAGE2_MUX3);
+ __raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STAGE2_MUX4);
+ __raw_writel(0x1C1E2022, pxp->base + HW_PXP_WFE_B_STAGE2_MUX5);
+ __raw_writel(0x1215181A, pxp->base + HW_PXP_WFE_B_STAGE2_MUX6);
+ __raw_writel(0x00000C0F, pxp->base + HW_PXP_WFE_B_STAGE2_MUX7);
+ __raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STAGE2_MUX8);
+ __raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STAGE2_MUX9);
+ __raw_writel(0x01000000, pxp->base + HW_PXP_WFE_B_STAGE2_MUX10);
+ __raw_writel(0x000C010B, pxp->base + HW_PXP_WFE_B_STAGE2_MUX11);
+ __raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STAGE2_MUX12);
+
+ __raw_writel(0x09000C01, pxp->base + HW_PXP_WFE_B_STAGE3_MUX0);
+ __raw_writel(0x003A2A1D, pxp->base + HW_PXP_WFE_B_STAGE3_MUX1);
+ __raw_writel(0x09000C01, pxp->base + HW_PXP_WFE_B_STAGE3_MUX2);
+ __raw_writel(0x003A2A1D, pxp->base + HW_PXP_WFE_B_STAGE3_MUX3);
+ __raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STAGE3_MUX4);
+ __raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STAGE3_MUX5);
+ __raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STAGE3_MUX6);
+ __raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STAGE3_MUX7);
+ __raw_writel(0x07060504, pxp->base + HW_PXP_WFE_B_STAGE3_MUX8);
+ __raw_writel(0x00000008, pxp->base + HW_PXP_WFE_B_STAGE3_MUX9);
+ __raw_writel(0x00001211, pxp->base + HW_PXP_WFE_B_STAGE3_MUX10);
+
+ __raw_writel(0x02010100, pxp->base + HW_PXP_WFE_B_STG1_5X8_OUT0_0);
+ __raw_writel(0x03020201, pxp->base + HW_PXP_WFE_B_STG1_5X8_OUT0_1);
+ __raw_writel(0x03020201, pxp->base + HW_PXP_WFE_B_STG1_5X8_OUT0_2);
+ __raw_writel(0x04030302, pxp->base + HW_PXP_WFE_B_STG1_5X8_OUT0_3);
+ __raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STG1_5X8_OUT0_4);
+ __raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STG1_5X8_OUT0_5);
+ __raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STG1_5X8_OUT0_6);
+ __raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STG1_5X8_OUT0_7);
+
+ __raw_writel(0x02010100, pxp->base + HW_PXP_WFE_B_STG1_5X8_OUT1_0);
+ __raw_writel(0x03020201, pxp->base + HW_PXP_WFE_B_STG1_5X8_OUT1_1);
+ __raw_writel(0x03020201, pxp->base + HW_PXP_WFE_B_STG1_5X8_OUT1_2);
+ __raw_writel(0x04030302, pxp->base + HW_PXP_WFE_B_STG1_5X8_OUT1_3);
+ __raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STG1_5X8_OUT1_4);
+ __raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STG1_5X8_OUT1_5);
+ __raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STG1_5X8_OUT1_6);
+ __raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STG1_5X8_OUT1_7);
+
+ __raw_writel(0x0000000F, pxp->base + HW_PXP_WFE_B_STAGE1_5X8_MASKS_0);
+
+ __raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STG1_5X1_OUT0);
+ __raw_writel(0x0000000F, pxp->base + HW_PXP_WFE_B_STG1_5X1_MASKS);
+
+ __raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT0_0);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT0_1);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT0_2);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT0_3);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT0_4);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT0_5);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT0_6);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT0_7);
+
+ __raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT1_0);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT1_1);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT1_2);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT1_3);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT1_4);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT1_5);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT1_6);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT1_7);
+
+ __raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT2_0);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT2_1);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT2_2);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT2_3);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT2_4);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT2_5);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT2_6);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT2_7);
+
+ __raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT3_0);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT3_1);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT3_2);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT3_3);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT3_4);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT3_5);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT3_6);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT3_7);
+
+ __raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT4_0);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT4_1);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT4_2);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT4_3);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT4_4);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT4_5);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT4_6);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT4_7);
+
+ __raw_writel(0, pxp->base + HW_PXP_WFE_B_STAGE2_5X6_MASKS_0);
+ __raw_writel(0x3F3F3F3F, pxp->base + HW_PXP_WFE_B_STAGE2_5X6_ADDR_0);
+
+ __raw_writel(0, pxp->base + HW_PXP_WFE_B_STG2_5X6_OUT0_0);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_B_STG2_5X6_OUT0_1);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_B_STG2_5X6_OUT0_2);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_B_STG2_5X6_OUT0_3);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_B_STG2_5X6_OUT0_4);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_B_STG2_5X6_OUT0_5);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_B_STG2_5X6_OUT0_6);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_B_STG2_5X6_OUT0_7);
+
+ __raw_writel(0, pxp->base + HW_PXP_WFE_B_STG2_5X6_OUT1_0);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_B_STG2_5X6_OUT1_1);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_B_STG2_5X6_OUT1_2);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_B_STG2_5X6_OUT1_3);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_B_STG2_5X6_OUT1_4);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_B_STG2_5X6_OUT1_5);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_B_STG2_5X6_OUT1_6);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_B_STG2_5X6_OUT1_7);
+
+ __raw_writel(0x00008000, pxp->base + HW_PXP_WFE_B_STG2_5X1_OUT0);
+ __raw_writel(0x0000FFFE, pxp->base + HW_PXP_WFE_B_STG2_5X1_OUT1);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_B_STG2_5X1_OUT2);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_B_STG2_5X1_OUT3);
+ __raw_writel(0x00000F0F, pxp->base + HW_PXP_WFE_B_STG2_5X1_MASKS);
+
+ __raw_writel(0x00007F7F, pxp->base + HW_PXP_WFE_B_STG3_F8X1_MASKS);
+
+ __raw_writel(0, pxp->base + HW_PXP_WFE_B_STG3_F8X1_OUT0_0);
+ __raw_writel(0x00FF00FF, pxp->base + HW_PXP_WFE_B_STG3_F8X1_OUT0_1);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_B_STG3_F8X1_OUT0_2);
+ __raw_writel(0x000000FF, pxp->base + HW_PXP_WFE_B_STG3_F8X1_OUT0_3);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_B_STG3_F8X1_OUT0_4);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_B_STG3_F8X1_OUT0_5);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_B_STG3_F8X1_OUT0_6);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_B_STG3_F8X1_OUT0_7);
+
+ __raw_writel(0, pxp->base + HW_PXP_WFE_B_STG3_F8X1_OUT1_0);
+ __raw_writel(0xFF3FFF3F, pxp->base + HW_PXP_WFE_B_STG3_F8X1_OUT1_1);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_B_STG3_F8X1_OUT1_2);
+ __raw_writel(0xFFFFFF1F, pxp->base + HW_PXP_WFE_B_STG3_F8X1_OUT1_3);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_B_STG3_F8X1_OUT1_4);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_B_STG3_F8X1_OUT1_5);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_B_STG3_F8X1_OUT1_6);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_B_STG3_F8X1_OUT1_7);
+
+ __raw_writel(
+ BF_PXP_WFE_B_CTRL_ENABLE(1) |
+ BF_PXP_WFE_B_CTRL_SW_RESET(1),
+ pxp->base + HW_PXP_WFE_B_CTRL);
+}
+
+/* wfe b processing
+ * use wfe b to process an update
+ * call this function only after pxp_wfe_a_processing
+ * x,y,width,height:
+ * coordinate and size of the update region
+ * twb:
+ * temp working buffer, 16bpp
+ * only used when reagl_en is 1
+ * wb:
+ * working buffer, 16bpp
+ * lut:
+ * lut buffer, 8bpp
+ * lut_update:
+ * 0 - wfe_b is used for reagl/reagl-d operation
+ * 1 - wfe_b is used for lut update operation
+ * reagl_d_en:
+ * 0 - use reagl waveform algorithm
+ * 1 - use reagl/-d waveform algorithm
+ */
+static void pxp_wfe_b_process(struct pxps *pxp)
+{
+ struct pxp_config_data *config_data = &pxp->pxp_conf_state;
+ struct pxp_proc_data *proc_data = &config_data->proc_data;
+ struct pxp_layer_param *fetch_ch0 = &config_data->wfe_b_fetch_param[0];
+ struct pxp_layer_param *fetch_ch1 = &config_data->wfe_b_fetch_param[1];
+ struct pxp_layer_param *store_ch0 = &config_data->wfe_b_store_param[0];
+ struct pxp_layer_param *store_ch1 = &config_data->wfe_b_store_param[1];
+ static int comp_mask;
+ /* Fetch */
+
+ print_param(fetch_ch0, "wfe_b fetch_ch0");
+ print_param(fetch_ch1, "wfe_b fetch_ch1");
+ print_param(store_ch0, "wfe_b store_ch0");
+ print_param(store_ch1, "wfe_b store_ch1");
+
+ __raw_writel(fetch_ch0->paddr, pxp->base + HW_PXP_WFB_FETCH_BUF1_ADDR);
+
+ __raw_writel(
+ BF_PXP_WFB_FETCH_BUF1_CORD_YCORD(fetch_ch0->top) |
+ BF_PXP_WFB_FETCH_BUF1_CORD_XCORD(fetch_ch0->left),
+ pxp->base + HW_PXP_WFB_FETCH_BUF1_CORD);
+
+ __raw_writel(fetch_ch0->stride,
+ pxp->base + HW_PXP_WFB_FETCH_BUF1_PITCH);
+
+ __raw_writel(
+ BF_PXP_WFB_FETCH_BUF1_SIZE_BUF_HEIGHT(fetch_ch0->height-1) |
+ BF_PXP_WFB_FETCH_BUF1_SIZE_BUF_WIDTH(fetch_ch0->width-1),
+ pxp->base + HW_PXP_WFB_FETCH_BUF1_SIZE);
+
+ __raw_writel(fetch_ch1->paddr, pxp->base + HW_PXP_WFB_FETCH_BUF2_ADDR);
+
+ __raw_writel(fetch_ch1->stride * 2,
+ pxp->base + HW_PXP_WFB_FETCH_BUF2_PITCH);
+
+ __raw_writel(
+ BF_PXP_WFB_FETCH_BUF2_CORD_YCORD(fetch_ch1->top) |
+ BF_PXP_WFB_FETCH_BUF2_CORD_XCORD(fetch_ch1->left),
+ pxp->base + HW_PXP_WFB_FETCH_BUF2_CORD);
+
+ __raw_writel(
+ BF_PXP_WFB_FETCH_BUF2_SIZE_BUF_HEIGHT(fetch_ch1->height-1) |
+ BF_PXP_WFB_FETCH_BUF2_SIZE_BUF_WIDTH(fetch_ch1->width-1),
+ pxp->base + HW_PXP_WFB_FETCH_BUF2_SIZE);
+
+ if (!proc_data->lut_update) {
+ __raw_writel(
+ BF_PXP_WFB_FETCH_CTRL_BF1_EN(1) |
+ BF_PXP_WFB_FETCH_CTRL_BF1_HSK_MODE(0) |
+ BF_PXP_WFB_FETCH_CTRL_BF1_BYTES_PP(0) |
+ BF_PXP_WFB_FETCH_CTRL_BF1_LINE_MODE(1) |
+ BF_PXP_WFB_FETCH_CTRL_BF1_SRAM_IF(1) |
+ BF_PXP_WFB_FETCH_CTRL_BF1_BURST_LEN(0) |
+ BF_PXP_WFB_FETCH_CTRL_BF1_BYPASS_MODE(0) |
+ BF_PXP_WFB_FETCH_CTRL_BF1_BORDER_MODE(1) |
+ BF_PXP_WFB_FETCH_CTRL_BF2_EN(1) |
+ BF_PXP_WFB_FETCH_CTRL_BF2_HSK_MODE(0) |
+ BF_PXP_WFB_FETCH_CTRL_BF2_BYTES_PP(1) |
+ BF_PXP_WFB_FETCH_CTRL_BF2_LINE_MODE(1) |
+ BF_PXP_WFB_FETCH_CTRL_BF2_SRAM_IF(0) |
+ BF_PXP_WFB_FETCH_CTRL_BF2_BURST_LEN(0) |
+ BF_PXP_WFB_FETCH_CTRL_BF2_BORDER_MODE(1) |
+ BF_PXP_WFB_FETCH_CTRL_BF2_BYPASS_MODE(0),
+ pxp->base + HW_PXP_WFB_FETCH_CTRL);
+ } else {
+ __raw_writel(
+ BF_PXP_WFB_FETCH_CTRL_BF1_EN(1) |
+ BF_PXP_WFB_FETCH_CTRL_BF1_HSK_MODE(0) |
+ BF_PXP_WFB_FETCH_CTRL_BF1_BYTES_PP(0) |
+ BF_PXP_WFB_FETCH_CTRL_BF1_LINE_MODE(1) |
+ BF_PXP_WFB_FETCH_CTRL_BF1_SRAM_IF(0) |
+ BF_PXP_WFB_FETCH_CTRL_BF1_BURST_LEN(0) |
+ BF_PXP_WFB_FETCH_CTRL_BF1_BORDER_MODE(1) |
+ BF_PXP_WFB_FETCH_CTRL_BF1_BYPASS_MODE(0) |
+ BF_PXP_WFB_FETCH_CTRL_BF2_EN(1) |
+ BF_PXP_WFB_FETCH_CTRL_BF2_HSK_MODE(0) |
+ BF_PXP_WFB_FETCH_CTRL_BF2_BYTES_PP(1) |
+ BF_PXP_WFB_FETCH_CTRL_BF2_LINE_MODE(1) |
+ BF_PXP_WFB_FETCH_CTRL_BF2_SRAM_IF(0) |
+ BF_PXP_WFB_FETCH_CTRL_BF2_BURST_LEN(0) |
+ BF_PXP_WFB_FETCH_CTRL_BF2_BORDER_MODE(1) |
+ BF_PXP_WFB_FETCH_CTRL_BF2_BYPASS_MODE(0),
+ pxp->base + HW_PXP_WFB_FETCH_CTRL);
+ }
+
+#ifdef CONFIG_REAGLD_ALGO_CHECK
+ __raw_writel(
+ (__raw_readl(pxp->base + HW_PXP_WFE_B_SW_DATA_REGS) & 0x0000FFFF) | ((fetch_ch0->comp_mask&0x000000FF)<<16),
+ pxp->base + HW_PXP_WFE_B_SW_DATA_REGS);
+#else
+ __raw_writel(
+ (__raw_readl(pxp->base + HW_PXP_WFE_B_SW_DATA_REGS) & 0x0000FFFF) | ((comp_mask&0x000000FF)<<16),
+ pxp->base + HW_PXP_WFE_B_SW_DATA_REGS);
+
+ /* comp_mask only need to be updated upon REAGL-D, 0,1,...7, 0,1,... */
+ if (proc_data->reagl_d_en) {
+ comp_mask++;
+ if (comp_mask>7)
+ comp_mask = 0;
+ }
+#endif
+
+ /* Store */
+ __raw_writel(
+ BF_PXP_WFE_B_STORE_SIZE_CH0_OUT_WIDTH(store_ch0->width-1)|
+ BF_PXP_WFE_B_STORE_SIZE_CH0_OUT_HEIGHT(store_ch0->height-1),
+ pxp->base + HW_PXP_WFE_B_STORE_SIZE_CH0);
+
+ __raw_writel(
+ BF_PXP_WFE_B_STORE_SIZE_CH1_OUT_WIDTH(store_ch1->width-1)|
+ BF_PXP_WFE_B_STORE_SIZE_CH1_OUT_HEIGHT(store_ch1->height-1),
+ pxp->base + HW_PXP_WFE_B_STORE_SIZE_CH1);
+
+ __raw_writel(
+ BF_PXP_WFE_B_STORE_PITCH_CH0_OUT_PITCH(store_ch0->stride * 2)|
+ BF_PXP_WFE_B_STORE_PITCH_CH1_OUT_PITCH(store_ch1->stride * 2),
+ pxp->base + HW_PXP_WFE_B_STORE_PITCH);
+
+ __raw_writel(
+ BF_PXP_WFE_B_STORE_ADDR_0_CH0_OUT_BASE_ADDR0(store_ch0->paddr
+ + (store_ch0->left + store_ch0->top * store_ch0->stride) * 2),
+ pxp->base + HW_PXP_WFE_B_STORE_ADDR_0_CH0);
+
+ if (proc_data->lut_update) {
+ __raw_writel(
+ BF_PXP_WFE_B_STORE_D_MASK1_H_CH0_D_MASK1_H_CH0(0x0),
+ pxp->base + HW_PXP_WFE_B_STORE_D_MASK1_H_CH0);
+
+ __raw_writel(
+ BF_PXP_WFE_B_STORE_D_MASK1_L_CH0_D_MASK1_L_CH0(0x0),
+ pxp->base + HW_PXP_WFE_B_STORE_D_MASK1_L_CH0);
+
+ __raw_writel(
+ BF_PXP_WFE_B_STORE_D_MASK2_H_CH0_D_MASK2_H_CH0(0x0),
+ pxp->base + HW_PXP_WFE_B_STORE_D_MASK2_H_CH0);
+
+ __raw_writel(
+ BF_PXP_WFE_B_STORE_D_MASK2_L_CH0_D_MASK2_L_CH0(0x3f0000),
+ pxp->base + HW_PXP_WFE_B_STORE_D_MASK2_L_CH0);
+
+ __raw_writel(
+ BF_PXP_WFE_B_STORE_F_MASK_L_CH0_F_MASK0(0x30)|
+ BF_PXP_WFE_B_STORE_F_MASK_L_CH0_F_MASK1(0)|
+ BF_PXP_WFE_B_STORE_F_MASK_L_CH0_F_MASK2(0)|
+ BF_PXP_WFE_B_STORE_F_MASK_L_CH0_F_MASK3(0),
+ pxp->base + HW_PXP_WFE_B_STORE_F_MASK_L_CH0);
+
+ __raw_writel(
+ BF_PXP_WFE_B_STORE_F_SHIFT_L_CH0_F_SHIFT_WIDTH0(4)|
+ BF_PXP_WFE_B_STORE_F_SHIFT_L_CH0_F_SHIFT_FLAG0(1)|
+ BF_PXP_WFE_B_STORE_F_SHIFT_L_CH0_F_SHIFT_WIDTH1(0)|
+ BF_PXP_WFE_B_STORE_F_SHIFT_L_CH0_F_SHIFT_FLAG1(0)|
+ BF_PXP_WFE_B_STORE_F_SHIFT_L_CH0_F_SHIFT_WIDTH2(0)|
+ BF_PXP_WFE_B_STORE_F_SHIFT_L_CH0_F_SHIFT_FLAG2(0)|
+ BF_PXP_WFE_B_STORE_F_SHIFT_L_CH0_F_SHIFT_WIDTH3(0)|
+ BF_PXP_WFE_B_STORE_F_SHIFT_L_CH0_F_SHIFT_FLAG3(0),
+ pxp->base + HW_PXP_WFE_B_STORE_F_SHIFT_L_CH0);
+ } else {
+ __raw_writel(
+ BF_PXP_WFE_B_STORE_D_MASK1_H_CH0_D_MASK1_H_CH0(0x0),
+ pxp->base + HW_PXP_WFE_B_STORE_D_MASK1_H_CH0);
+
+ __raw_writel(
+ BF_PXP_WFE_B_STORE_D_MASK1_L_CH0_D_MASK1_L_CH0(0x3f00),
+ pxp->base + HW_PXP_WFE_B_STORE_D_MASK1_L_CH0);
+
+ __raw_writel(
+ BF_PXP_WFE_B_STORE_D_MASK2_H_CH0_D_MASK2_H_CH0(0x0),
+ pxp->base + HW_PXP_WFE_B_STORE_D_MASK2_H_CH0);
+
+ __raw_writel(
+ BF_PXP_WFE_B_STORE_D_MASK2_L_CH0_D_MASK2_L_CH0(0x0),
+ pxp->base + HW_PXP_WFE_B_STORE_D_MASK2_L_CH0);
+
+ __raw_writel(
+ BF_PXP_WFE_B_STORE_F_MASK_L_CH0_F_MASK0(3)|
+ BF_PXP_WFE_B_STORE_F_MASK_L_CH0_F_MASK1(0)|
+ BF_PXP_WFE_B_STORE_F_MASK_L_CH0_F_MASK2(0)|
+ BF_PXP_WFE_B_STORE_F_MASK_L_CH0_F_MASK3(0),
+ pxp->base + HW_PXP_WFE_B_STORE_F_MASK_L_CH0);
+
+ __raw_writel(
+ BF_PXP_WFE_B_STORE_F_SHIFT_L_CH0_F_SHIFT_WIDTH0(8)|
+ BF_PXP_WFE_B_STORE_F_SHIFT_L_CH0_F_SHIFT_FLAG0(1)|
+ BF_PXP_WFE_B_STORE_F_SHIFT_L_CH0_F_SHIFT_WIDTH1(0)|
+ BF_PXP_WFE_B_STORE_F_SHIFT_L_CH0_F_SHIFT_FLAG1(0)|
+ BF_PXP_WFE_B_STORE_F_SHIFT_L_CH0_F_SHIFT_WIDTH2(0)|
+ BF_PXP_WFE_B_STORE_F_SHIFT_L_CH0_F_SHIFT_FLAG2(0)|
+ BF_PXP_WFE_B_STORE_F_SHIFT_L_CH0_F_SHIFT_WIDTH3(0)|
+ BF_PXP_WFE_B_STORE_F_SHIFT_L_CH0_F_SHIFT_FLAG3(0),
+ pxp->base + HW_PXP_WFE_B_STORE_F_SHIFT_L_CH0);
+ }
+
+ /* ALU */
+ __raw_writel(
+ BF_PXP_ALU_B_BUF_SIZE_BUF_WIDTH(fetch_ch0->width) |
+ BF_PXP_ALU_B_BUF_SIZE_BUF_HEIGHT(fetch_ch0->height),
+ pxp->base + HW_PXP_ALU_B_BUF_SIZE);
+
+ /* WFE */
+ __raw_writel(
+ BF_PXP_WFE_B_DIMENSIONS_WIDTH(fetch_ch0->width) |
+ BF_PXP_WFE_B_DIMENSIONS_HEIGHT(fetch_ch0->height),
+ pxp->base + HW_PXP_WFE_B_DIMENSIONS);
+
+ __raw_writel( /*TODO check*/
+ BF_PXP_WFE_B_OFFSET_X_OFFSET(fetch_ch0->left) |
+ BF_PXP_WFE_B_OFFSET_Y_OFFSET(fetch_ch0->top),
+ pxp->base + HW_PXP_WFE_B_OFFSET);
+
+ __raw_writel(proc_data->reagl_d_en, pxp->base + HW_PXP_WFE_B_SW_FLAG_REGS);
+}
+
+void pxp_fill(
+ u32 bpp,
+ u32 value,
+ u32 width,
+ u32 height,
+ u32 output_buffer,
+ u32 output_pitch)
+{
+ u32 active_bpp;
+ u32 pitch;
+
+ if (bpp == 8) {
+ active_bpp = 0;
+ pitch = output_pitch;
+ } else if(bpp == 16) {
+ active_bpp = 1;
+ pitch = output_pitch * 2;
+ } else {
+ active_bpp = 2;
+ pitch = output_pitch * 4;
+ }
+
+ __raw_writel(
+ BF_PXP_WFE_B_STORE_CTRL_CH0_CH_EN(1)|
+ BF_PXP_WFE_B_STORE_CTRL_CH0_BLOCK_EN(0)|
+ BF_PXP_WFE_B_STORE_CTRL_CH0_BLOCK_16(0)|
+ BF_PXP_WFE_B_STORE_CTRL_CH0_HANDSHAKE_EN(0)|
+ BF_PXP_WFE_B_STORE_CTRL_CH0_ARRAY_EN(0)|
+ BF_PXP_WFE_B_STORE_CTRL_CH0_ARRAY_LINE_NUM(0)|
+ BF_PXP_WFE_B_STORE_CTRL_CH0_STORE_BYPASS_EN(0)|
+ BF_PXP_WFE_B_STORE_CTRL_CH0_STORE_MEMORY_EN(1)|
+ BF_PXP_WFE_B_STORE_CTRL_CH0_PACK_IN_SEL(0)|
+ BF_PXP_WFE_B_STORE_CTRL_CH0_FILL_DATA_EN(1)|
+ BF_PXP_WFE_B_STORE_CTRL_CH0_WR_NUM_BYTES(32)|
+ BF_PXP_WFE_B_STORE_CTRL_CH0_COMBINE_2CHANNEL(0) |
+ BF_PXP_WFE_B_STORE_CTRL_CH0_ARBIT_EN(0),
+ pxp_reg_base + HW_PXP_WFE_B_STORE_CTRL_CH0);
+
+ __raw_writel(
+ BF_PXP_WFE_B_STORE_CTRL_CH1_CH_EN(0)|
+ BF_PXP_WFE_B_STORE_CTRL_CH1_BLOCK_EN(0)|
+ BF_PXP_WFE_B_STORE_CTRL_CH1_BLOCK_16(0)|
+ BF_PXP_WFE_B_STORE_CTRL_CH1_HANDSHAKE_EN(0)|
+ BF_PXP_WFE_B_STORE_CTRL_CH1_ARRAY_EN(0)|
+ BF_PXP_WFE_B_STORE_CTRL_CH1_ARRAY_LINE_NUM(0)|
+ BF_PXP_WFE_B_STORE_CTRL_CH1_STORE_BYPASS_EN(0)|
+ BF_PXP_WFE_B_STORE_CTRL_CH1_STORE_MEMORY_EN(1)|
+ BF_PXP_WFE_B_STORE_CTRL_CH1_PACK_IN_SEL(0)|
+ BF_PXP_WFE_B_STORE_CTRL_CH1_WR_NUM_BYTES(16),
+ pxp_reg_base + HW_PXP_WFE_B_STORE_CTRL_CH1);
+
+ __raw_writel(
+ BF_PXP_WFE_B_STORE_SIZE_CH0_OUT_WIDTH(width-1)|
+ BF_PXP_WFE_B_STORE_SIZE_CH0_OUT_HEIGHT(height-1),
+ pxp_reg_base + HW_PXP_WFE_B_STORE_SIZE_CH0);
+
+ __raw_writel(
+ BF_PXP_WFE_B_STORE_SIZE_CH1_OUT_WIDTH(width-1)|
+ BF_PXP_WFE_B_STORE_SIZE_CH1_OUT_HEIGHT(height-1),
+ pxp_reg_base + HW_PXP_WFE_B_STORE_SIZE_CH1);
+
+ __raw_writel(
+ BF_PXP_WFE_B_STORE_PITCH_CH0_OUT_PITCH(pitch)|
+ BF_PXP_WFE_B_STORE_PITCH_CH1_OUT_PITCH(pitch),
+ pxp_reg_base + HW_PXP_WFE_B_STORE_PITCH);
+
+ __raw_writel(
+ BF_PXP_WFE_B_STORE_SHIFT_CTRL_CH0_OUTPUT_ACTIVE_BPP(active_bpp)|
+ BF_PXP_WFE_B_STORE_SHIFT_CTRL_CH0_OUT_YUV422_1P_EN(0)|
+ BF_PXP_WFE_B_STORE_SHIFT_CTRL_CH0_OUT_YUV422_2P_EN(0)|
+ BF_PXP_WFE_B_STORE_SHIFT_CTRL_CH0_SHIFT_BYPASS(1),
+ pxp_reg_base + HW_PXP_WFE_B_STORE_SHIFT_CTRL_CH0);
+
+ __raw_writel(
+ BF_PXP_WFE_B_STORE_SHIFT_CTRL_CH1_OUTPUT_ACTIVE_BPP(active_bpp)|
+ BF_PXP_WFE_B_STORE_SHIFT_CTRL_CH1_OUT_YUV422_1P_EN(0)|
+ BF_PXP_WFE_B_STORE_SHIFT_CTRL_CH1_OUT_YUV422_2P_EN(0),
+ pxp_reg_base + HW_PXP_WFE_B_STORE_SHIFT_CTRL_CH1);
+
+ __raw_writel(
+ BF_PXP_WFE_B_STORE_ADDR_0_CH0_OUT_BASE_ADDR0(output_buffer),
+ pxp_reg_base + HW_PXP_WFE_B_STORE_ADDR_0_CH0);
+
+ __raw_writel(
+ BF_PXP_WFE_B_STORE_ADDR_1_CH0_OUT_BASE_ADDR1(0),
+ pxp_reg_base + HW_PXP_WFE_B_STORE_ADDR_1_CH0);
+
+ __raw_writel(
+ BF_PXP_WFE_B_STORE_ADDR_0_CH1_OUT_BASE_ADDR0(output_buffer),
+ pxp_reg_base + HW_PXP_WFE_B_STORE_ADDR_0_CH1);
+
+ __raw_writel(
+ BF_PXP_WFE_B_STORE_ADDR_1_CH1_OUT_BASE_ADDR1(0),
+ pxp_reg_base + HW_PXP_WFE_B_STORE_ADDR_1_CH1);
+
+ __raw_writel(
+ BF_PXP_WFE_B_STORE_FILL_DATA_CH0_FILL_DATA_CH0(value),
+ pxp_reg_base + HW_PXP_WFE_B_STORE_FILL_DATA_CH0);
+
+ __raw_writel(
+ BF_PXP_WFE_B_STORE_D_MASK0_H_CH0_D_MASK0_H_CH0(0x00000000),
+ pxp_reg_base + HW_PXP_WFE_B_STORE_D_MASK0_H_CH0);
+
+ __raw_writel(
+ BF_PXP_WFE_B_STORE_D_MASK0_L_CH0_D_MASK0_L_CH0(0x000000ff),
+ pxp_reg_base + HW_PXP_WFE_B_STORE_D_MASK0_L_CH0);
+
+ __raw_writel(
+ BF_PXP_WFE_B_STORE_D_MASK1_H_CH0_D_MASK1_H_CH0(0x00000000),
+ pxp_reg_base + HW_PXP_WFE_B_STORE_D_MASK1_H_CH0);
+
+ __raw_writel(
+ BF_PXP_WFE_B_STORE_D_MASK1_L_CH0_D_MASK1_L_CH0(0x000000ff),
+ pxp_reg_base + HW_PXP_WFE_B_STORE_D_MASK1_L_CH0);
+
+ __raw_writel(
+ BF_PXP_WFE_B_STORE_D_MASK2_H_CH0_D_MASK2_H_CH0(0x00000000),
+ pxp_reg_base + HW_PXP_WFE_B_STORE_D_MASK2_H_CH0);
+
+ __raw_writel(
+ BF_PXP_WFE_B_STORE_D_MASK2_L_CH0_D_MASK2_L_CH0(0x000000ff),
+ pxp_reg_base + HW_PXP_WFE_B_STORE_D_MASK2_L_CH0);
+
+ __raw_writel(
+ BF_PXP_WFE_B_STORE_D_SHIFT_L_CH0_D_SHIFT_WIDTH0(0) |
+ BF_PXP_WFE_B_STORE_D_SHIFT_L_CH0_D_SHIFT_FLAG0(0) |
+ BF_PXP_WFE_B_STORE_D_SHIFT_L_CH0_D_SHIFT_WIDTH1(32)|
+ BF_PXP_WFE_B_STORE_D_SHIFT_L_CH0_D_SHIFT_FLAG1(1) |
+ BF_PXP_WFE_B_STORE_D_SHIFT_L_CH0_D_SHIFT_WIDTH2(40)|
+ BF_PXP_WFE_B_STORE_D_SHIFT_L_CH0_D_SHIFT_FLAG2(1)|
+ BF_PXP_WFE_B_STORE_D_SHIFT_L_CH0_D_SHIFT_WIDTH3(0)|
+ BF_PXP_WFE_B_STORE_D_SHIFT_L_CH0_D_SHIFT_FLAG3(0),
+ pxp_reg_base + HW_PXP_WFE_B_STORE_D_SHIFT_L_CH0);
+
+ __raw_writel(
+ BF_PXP_CTRL2_ENABLE (1) |
+ BF_PXP_CTRL2_ROTATE0 (0) |
+ BF_PXP_CTRL2_HFLIP0 (0) |
+ BF_PXP_CTRL2_VFLIP0 (0) |
+ BF_PXP_CTRL2_ROTATE1 (0) |
+ BF_PXP_CTRL2_HFLIP1 (0) |
+ BF_PXP_CTRL2_VFLIP1 (0) |
+ BF_PXP_CTRL2_ENABLE_DITHER (0) |
+ BF_PXP_CTRL2_ENABLE_WFE_A (0) |
+ BF_PXP_CTRL2_ENABLE_WFE_B (1) |
+ BF_PXP_CTRL2_ENABLE_INPUT_FETCH_STORE (0) |
+ BF_PXP_CTRL2_ENABLE_ALPHA_B (0) |
+ BF_PXP_CTRL2_BLOCK_SIZE (0) |
+ BF_PXP_CTRL2_ENABLE_CSC2 (0) |
+ BF_PXP_CTRL2_ENABLE_LUT (0) |
+ BF_PXP_CTRL2_ENABLE_ROTATE0 (0) |
+ BF_PXP_CTRL2_ENABLE_ROTATE1 (0),
+ pxp_reg_base + HW_PXP_CTRL2);
+
+ if (busy_wait(BM_PXP_IRQ_WFE_B_CH0_STORE_IRQ &
+ __raw_readl(pxp_reg_base + HW_PXP_IRQ)) == false)
+ printk("%s: wait for completion timeout\n", __func__);
+}
+EXPORT_SYMBOL(pxp_fill);
+
+static void pxp_lut_cleanup_multiple(struct pxps *pxp, u64 lut, bool set)
+{
+ struct pxp_config_data *pxp_conf = &pxp->pxp_conf_state;
+ struct pxp_proc_data *proc_data = &pxp_conf->proc_data;
+
+ if (proc_data->lut_cleanup == 1) {
+ if (set) {
+ __raw_writel((u32)lut, pxp->base + HW_PXP_WFE_A_STG1_8X1_OUT1_0 + 0x4);
+ __raw_writel((u32)(lut>>32), pxp->base + HW_PXP_WFE_A_STG1_8X1_OUT1_1 + 0x4);
+ } else {
+ pxp_luts_deactivate(pxp, lut);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_A_STG1_8X1_OUT1_0);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_A_STG1_8X1_OUT1_1);
+ }
+ }
+}
+
+static void pxp_lut_cleanup_multiple_v3p(struct pxps *pxp, u64 lut, bool set)
+{
+ struct pxp_config_data *pxp_conf = &pxp->pxp_conf_state;
+ struct pxp_proc_data *proc_data = &pxp_conf->proc_data;
+
+ if (proc_data->lut_cleanup == 1) {
+ if (set) {
+ __raw_writel((u32)lut, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT1_0 + 0x4);
+ __raw_writel((u32)(lut>>32), pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT1_1 + 0x4);
+ } else {
+ pxp_luts_deactivate(pxp, lut);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT1_0);
+ __raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT1_1);
+ }
+ }
+}
+
+#ifdef CONFIG_MXC_FPGA_M4_TEST
+void m4_process(void)
+{
+ __raw_writel(0x7, pinctrl_base + PIN_DOUT); /* M4 Start */
+
+ while (!(__raw_readl(pxp_reg_base + HW_PXP_HANDSHAKE_CPU_STORE) & BM_PXP_HANDSHAKE_CPU_STORE_SW0_B0_READY));
+
+ __raw_writel(0x3, pinctrl_base + PIN_DOUT); /* M4 Stop */
+
+
+}
+#else
+void m4_process(void) {}
+#endif
+EXPORT_SYMBOL(m4_process);
+
+static void pxp_lut_status_set(struct pxps *pxp, unsigned int lut)
+{
+ if(lut<32)
+ __raw_writel(
+ __raw_readl(pxp_reg_base + HW_PXP_WFE_A_STG1_8X1_OUT0_0) | (1 << lut),
+ pxp->base + HW_PXP_WFE_A_STG1_8X1_OUT0_0);
+ else {
+ lut = lut -32;
+ __raw_writel(
+ __raw_readl(pxp_reg_base + HW_PXP_WFE_A_STG1_8X1_OUT0_1) | (1 << lut),
+ pxp->base + HW_PXP_WFE_A_STG1_8X1_OUT0_1);
+ }
+}
+
+static void pxp_lut_status_set_v3p(struct pxps *pxp, unsigned int lut)
+{
+ if(lut<32)
+ __raw_writel(
+ __raw_readl(pxp_reg_base + HW_PXP_WFE_B_STG1_8X1_OUT0_0) | (1 << lut),
+ pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT0_0);
+ else {
+ lut = lut -32;
+ __raw_writel(
+ __raw_readl(pxp_reg_base + HW_PXP_WFE_B_STG1_8X1_OUT0_1) | (1 << lut),
+ pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT0_1);
+ }
+}
+
+static void pxp_luts_activate(struct pxps *pxp, u64 lut_status)
+{
+ int i = 0;
+
+ if (!lut_status)
+ return;
+
+ for (i = 0; i < 64; i++) {
+ if (lut_status & (1ULL << i))
+ if (pxp->devdata && pxp->devdata->pxp_lut_status_set)
+ pxp->devdata->pxp_lut_status_set(pxp, i);
+ }
+}
+
+static void pxp_lut_status_clr(unsigned int lut)
+{
+ if(lut<32)
+ __raw_writel(
+ __raw_readl(pxp_reg_base + HW_PXP_WFE_A_STG1_8X1_OUT0_0) & (~(1 << lut)),
+ pxp_reg_base + HW_PXP_WFE_A_STG1_8X1_OUT0_0);
+ else
+ {
+ lut = lut -32;
+ __raw_writel(
+ __raw_readl(pxp_reg_base + HW_PXP_WFE_A_STG1_8X1_OUT0_1) & (~(1 << lut)),
+ pxp_reg_base + HW_PXP_WFE_A_STG1_8X1_OUT0_1);
+ }
+}
+
+static void pxp_lut_status_clr_v3p(unsigned int lut)
+{
+ if(lut<32)
+ __raw_writel(
+ __raw_readl(pxp_reg_base + HW_PXP_WFE_B_STG1_8X1_OUT0_0) & (~(1 << lut)),
+ pxp_reg_base + HW_PXP_WFE_B_STG1_8X1_OUT0_0);
+ else
+ {
+ lut = lut -32;
+ __raw_writel(
+ __raw_readl(pxp_reg_base + HW_PXP_WFE_B_STG1_8X1_OUT0_1) & (~(1 << lut)),
+ pxp_reg_base + HW_PXP_WFE_B_STG1_8X1_OUT0_1);
+ }
+}
+
+/* this function should be called in the epdc
+ * driver explicitly when some epdc lut becomes
+ * idle. So it should be exported.
+ */
+static void pxp_luts_deactivate(struct pxps *pxp, u64 lut_status)
+{
+ int i = 0;
+
+ if (!lut_status)
+ return;
+
+ for (i = 0; i < 64; i++) {
+ if (lut_status & (1ULL << i))
+ if (pxp->devdata && pxp->devdata->pxp_lut_status_clr)
+ pxp->devdata->pxp_lut_status_clr(i);
+ }
+}
+
+/* use histogram_B engine to calculate histogram status */
+static void pxp_histogram_enable(struct pxps *pxp,
+ unsigned int width,
+ unsigned int height)
+{
+ __raw_writel(
+ BF_PXP_HIST_B_BUF_SIZE_HEIGHT(height)|
+ BF_PXP_HIST_B_BUF_SIZE_WIDTH(width),
+ pxp->base + HW_PXP_HIST_B_BUF_SIZE);
+
+ __raw_writel(
+ BF_PXP_HIST_B_MASK_MASK_EN(1)|
+ BF_PXP_HIST_B_MASK_MASK_MODE(0)|
+ BF_PXP_HIST_B_MASK_MASK_OFFSET(64)|
+ BF_PXP_HIST_B_MASK_MASK_WIDTH(0)|
+ BF_PXP_HIST_B_MASK_MASK_VALUE0(1) |
+ BF_PXP_HIST_B_MASK_MASK_VALUE1(0),
+ pxp->base + HW_PXP_HIST_B_MASK);
+
+ __raw_writel(
+ BF_PXP_HIST_B_CTRL_PIXEL_WIDTH(3)|
+ BF_PXP_HIST_B_CTRL_PIXEL_OFFSET(8)|
+ BF_PXP_HIST_B_CTRL_CLEAR(0)|
+ BF_PXP_HIST_B_CTRL_ENABLE(1),
+ pxp->base + HW_PXP_HIST_B_CTRL);
+}
+
+static void pxp_histogram_status_report(struct pxps *pxp, u32 *hist_status)
+{
+ BUG_ON(!hist_status);
+
+ *hist_status = (__raw_readl(pxp->base + HW_PXP_HIST_B_CTRL) & BM_PXP_HIST_B_CTRL_STATUS)
+ >> BP_PXP_HIST_B_CTRL_STATUS;
+ dev_dbg(pxp->dev, "%d pixels are used to calculate histogram status %d\n",
+ __raw_readl(pxp->base + HW_PXP_HIST_B_TOTAL_PIXEL), *hist_status);
+}
+
+static void pxp_histogram_disable(struct pxps *pxp)
+{
+ __raw_writel(
+ BF_PXP_HIST_B_CTRL_PIXEL_WIDTH(3)|
+ BF_PXP_HIST_B_CTRL_PIXEL_OFFSET(4)|
+ BF_PXP_HIST_B_CTRL_CLEAR(1)|
+ BF_PXP_HIST_B_CTRL_ENABLE(0),
+ pxp->base + HW_PXP_HIST_B_CTRL);
+}
+
+/* the collision detection function will be
+ * called by epdc driver when required
+ */
+static void pxp_collision_detection_enable(struct pxps *pxp,
+ unsigned int width,
+ unsigned int height)
+{
+ __raw_writel(
+ BF_PXP_HIST_A_BUF_SIZE_HEIGHT(height)|
+ BF_PXP_HIST_A_BUF_SIZE_WIDTH(width),
+ pxp_reg_base + HW_PXP_HIST_A_BUF_SIZE);
+
+ __raw_writel(
+ BF_PXP_HIST_A_MASK_MASK_EN(1)|
+ BF_PXP_HIST_A_MASK_MASK_MODE(0)|
+ BF_PXP_HIST_A_MASK_MASK_OFFSET(65)|
+ BF_PXP_HIST_A_MASK_MASK_WIDTH(0)|
+ BF_PXP_HIST_A_MASK_MASK_VALUE0(1) |
+ BF_PXP_HIST_A_MASK_MASK_VALUE1(0),
+ pxp_reg_base + HW_PXP_HIST_A_MASK);
+
+ __raw_writel(
+ BF_PXP_HIST_A_CTRL_PIXEL_WIDTH(6)|
+ BF_PXP_HIST_A_CTRL_PIXEL_OFFSET(24)|
+ BF_PXP_HIST_A_CTRL_CLEAR(0)|
+ BF_PXP_HIST_A_CTRL_ENABLE(1),
+ pxp_reg_base + HW_PXP_HIST_A_CTRL);
+}
+
+static void pxp_collision_detection_disable(struct pxps *pxp)
+{
+ __raw_writel(
+ BF_PXP_HIST_A_CTRL_PIXEL_WIDTH(6)|
+ BF_PXP_HIST_A_CTRL_PIXEL_OFFSET(24)|
+ BF_PXP_HIST_A_CTRL_CLEAR(1)|
+ BF_PXP_HIST_A_CTRL_ENABLE(0),
+ pxp_reg_base + HW_PXP_HIST_A_CTRL);
+}
+
+/* this function can be called in the epdc callback
+ * function in the pxp_irq() to let the epdc know
+ * the collision information for the previous working
+ * buffer update.
+ */
+static bool pxp_collision_status_report(struct pxps *pxp, struct pxp_collision_info *info)
+{
+ unsigned int count;
+
+ BUG_ON(!info);
+ memset(info, 0x0, sizeof(*info));
+
+ info->pixel_cnt = count = __raw_readl(pxp->base + HW_PXP_HIST_A_TOTAL_PIXEL);
+ if (!count)
+ return false;
+
+ dev_dbg(pxp->dev, "%s: pixel_cnt = %d\n", __func__, info->pixel_cnt);
+ info->rect_min_x = __raw_readl(pxp->base + HW_PXP_HIST_A_ACTIVE_AREA_X) & 0xffff;
+ dev_dbg(pxp->dev, "%s: rect_min_x = %d\n", __func__, info->rect_min_x);
+ info->rect_max_x = (__raw_readl(pxp->base + HW_PXP_HIST_A_ACTIVE_AREA_X) >> 16) & 0xffff;
+ dev_dbg(pxp->dev, "%s: rect_max_x = %d\n", __func__, info->rect_max_x);
+ info->rect_min_y = __raw_readl(pxp->base + HW_PXP_HIST_A_ACTIVE_AREA_Y) & 0xffff;
+ dev_dbg(pxp->dev, "%s: rect_min_y = %d\n", __func__, info->rect_min_y);
+ info->rect_max_y = (__raw_readl(pxp->base + HW_PXP_HIST_A_ACTIVE_AREA_Y) >> 16) & 0xffff;
+ dev_dbg(pxp->dev, "%s: rect_max_y = %d\n", __func__, info->rect_max_y);
+
+ info->victim_luts[0] = __raw_readl(pxp->base + HW_PXP_HIST_A_RAW_STAT0);
+ dev_dbg(pxp->dev, "%s: victim_luts[0] = 0x%x\n", __func__, info->victim_luts[0]);
+ info->victim_luts[1] = __raw_readl(pxp->base + HW_PXP_HIST_A_RAW_STAT1);
+ dev_dbg(pxp->dev, "%s: victim_luts[1] = 0x%x\n", __func__, info->victim_luts[1]);
+
+ return true;
+}
+
+void pxp_get_collision_info(struct pxp_collision_info *info)
+{
+ BUG_ON(!info);
+
+ memcpy(info, &col_info, sizeof(struct pxp_collision_info));
+}
+EXPORT_SYMBOL(pxp_get_collision_info);
+
+static void dither_prefetch_config(struct pxps *pxp)
+{
+ struct pxp_config_data *config_data = &pxp->pxp_conf_state;
+ struct pxp_layer_param *fetch_ch0 = &config_data->dither_fetch_param[0];
+ struct pxp_layer_param *fetch_ch1 = &config_data->dither_fetch_param[1];
+
+ print_param(fetch_ch0, "dither fetch_ch0");
+ print_param(fetch_ch1, "dither fetch_ch1");
+ __raw_writel(
+ BF_PXP_DITHER_FETCH_CTRL_CH0_CH_EN(1) |
+ BF_PXP_DITHER_FETCH_CTRL_CH0_BLOCK_EN(0) |
+ BF_PXP_DITHER_FETCH_CTRL_CH0_BLOCK_16(0)|
+ BF_PXP_DITHER_FETCH_CTRL_CH0_HANDSHAKE_EN(0) |
+ BF_PXP_DITHER_FETCH_CTRL_CH0_BYPASS_PIXEL_EN(0) |
+ BF_PXP_DITHER_FETCH_CTRL_CH0_HIGH_BYTE(0) |
+ BF_PXP_DITHER_FETCH_CTRL_CH0_HFLIP(0) |
+ BF_PXP_DITHER_FETCH_CTRL_CH0_VFLIP(0) |
+ BF_PXP_DITHER_FETCH_CTRL_CH0_ROTATION_ANGLE(0) |
+ BF_PXP_DITHER_FETCH_CTRL_CH0_RD_NUM_BYTES(32) |
+ BF_PXP_DITHER_FETCH_CTRL_CH0_HANDSHAKE_SCAN_LINE_NUM(0) |
+ BF_PXP_DITHER_FETCH_CTRL_CH0_ARBIT_EN(0),
+ pxp->base + HW_PXP_DITHER_FETCH_CTRL_CH0);
+
+ __raw_writel(
+ BF_PXP_DITHER_FETCH_CTRL_CH1_CH_EN(0) |
+ BF_PXP_DITHER_FETCH_CTRL_CH1_BLOCK_EN(0) |
+ BF_PXP_DITHER_FETCH_CTRL_CH1_BLOCK_16(0)|
+ BF_PXP_DITHER_FETCH_CTRL_CH1_HANDSHAKE_EN(0) |
+ BF_PXP_DITHER_FETCH_CTRL_CH1_BYPASS_PIXEL_EN(0) |
+ BF_PXP_DITHER_FETCH_CTRL_CH1_HFLIP(0) |
+ BF_PXP_DITHER_FETCH_CTRL_CH1_VFLIP(0) |
+ BF_PXP_DITHER_FETCH_CTRL_CH1_ROTATION_ANGLE(0) |
+ BF_PXP_DITHER_FETCH_CTRL_CH1_RD_NUM_BYTES(2) |
+ BF_PXP_DITHER_FETCH_CTRL_CH1_HANDSHAKE_SCAN_LINE_NUM(0),
+ pxp->base + HW_PXP_DITHER_FETCH_CTRL_CH1);
+
+ __raw_writel(
+ BF_PXP_DITHER_FETCH_ACTIVE_SIZE_ULC_CH0_ACTIVE_SIZE_ULC_X(0) |
+ BF_PXP_DITHER_FETCH_ACTIVE_SIZE_ULC_CH0_ACTIVE_SIZE_ULC_Y(0),
+ pxp->base + HW_PXP_DITHER_FETCH_ACTIVE_SIZE_ULC_CH0);
+ __raw_writel(
+ BF_PXP_DITHER_FETCH_ACTIVE_SIZE_LRC_CH0_ACTIVE_SIZE_LRC_X(fetch_ch0->width - 1) |
+ BF_PXP_DITHER_FETCH_ACTIVE_SIZE_LRC_CH0_ACTIVE_SIZE_LRC_Y(fetch_ch0->height - 1),
+ pxp->base + HW_PXP_DITHER_FETCH_ACTIVE_SIZE_LRC_CH0);
+
+ __raw_writel(
+ BF_PXP_DITHER_FETCH_ACTIVE_SIZE_ULC_CH1_ACTIVE_SIZE_ULC_X(0) |
+ BF_PXP_DITHER_FETCH_ACTIVE_SIZE_ULC_CH1_ACTIVE_SIZE_ULC_Y(0),
+ pxp->base + HW_PXP_DITHER_FETCH_ACTIVE_SIZE_ULC_CH1);
+ __raw_writel(
+ BF_PXP_DITHER_FETCH_ACTIVE_SIZE_LRC_CH1_ACTIVE_SIZE_LRC_X(fetch_ch1->width - 1) |
+ BF_PXP_DITHER_FETCH_ACTIVE_SIZE_LRC_CH1_ACTIVE_SIZE_LRC_Y(fetch_ch1->height - 1),
+ pxp->base + HW_PXP_DITHER_FETCH_ACTIVE_SIZE_LRC_CH1);
+ __raw_writel(
+ BF_PXP_DITHER_FETCH_SIZE_CH0_INPUT_TOTAL_WIDTH(fetch_ch0->width - 1) |
+ BF_PXP_DITHER_FETCH_SIZE_CH0_INPUT_TOTAL_HEIGHT(fetch_ch0->height - 1),
+ pxp->base + HW_PXP_DITHER_FETCH_SIZE_CH0);
+
+ __raw_writel(
+ BF_PXP_DITHER_FETCH_SIZE_CH1_INPUT_TOTAL_WIDTH(fetch_ch1->width - 1) |
+ BF_PXP_DITHER_FETCH_SIZE_CH1_INPUT_TOTAL_HEIGHT(fetch_ch1->height - 1),
+ pxp->base + HW_PXP_DITHER_FETCH_SIZE_CH1);
+
+ __raw_writel(
+ BF_PXP_DITHER_FETCH_PITCH_CH0_INPUT_PITCH(fetch_ch0->stride) |
+ BF_PXP_DITHER_FETCH_PITCH_CH1_INPUT_PITCH(fetch_ch1->stride),
+ pxp->base + HW_PXP_DITHER_FETCH_PITCH);
+
+ __raw_writel(
+ BF_PXP_DITHER_FETCH_SHIFT_CTRL_CH0_INPUT_ACTIVE_BPP(0) |
+ BF_PXP_DITHER_FETCH_SHIFT_CTRL_CH0_EXPAND_FORMAT(0) |
+ BF_PXP_DITHER_FETCH_SHIFT_CTRL_CH0_EXPAND_EN(0) |
+ BF_PXP_DITHER_FETCH_SHIFT_CTRL_CH0_SHIFT_BYPASS(1),
+ pxp->base + HW_PXP_DITHER_FETCH_SHIFT_CTRL_CH0);
+
+ __raw_writel(
+ BF_PXP_DITHER_FETCH_SHIFT_CTRL_CH1_INPUT_ACTIVE_BPP(0) |
+ BF_PXP_DITHER_FETCH_SHIFT_CTRL_CH1_EXPAND_FORMAT(0) |
+ BF_PXP_DITHER_FETCH_SHIFT_CTRL_CH1_EXPAND_EN(0) |
+ BF_PXP_DITHER_FETCH_SHIFT_CTRL_CH1_SHIFT_BYPASS(1),
+ pxp->base + HW_PXP_DITHER_FETCH_SHIFT_CTRL_CH1);
+
+ __raw_writel(
+ BF_PXP_DITHER_FETCH_SHIFT_OFFSET_CH0_OFFSET0(0) |
+ BF_PXP_DITHER_FETCH_SHIFT_OFFSET_CH0_OFFSET1(0) |
+ BF_PXP_DITHER_FETCH_SHIFT_OFFSET_CH0_OFFSET2(0) |
+ BF_PXP_DITHER_FETCH_SHIFT_OFFSET_CH0_OFFSET3(0),
+ pxp->base + HW_PXP_DITHER_FETCH_SHIFT_OFFSET_CH0);
+
+ __raw_writel(
+ BF_PXP_DITHER_FETCH_SHIFT_OFFSET_CH1_OFFSET0(0) |
+ BF_PXP_DITHER_FETCH_SHIFT_OFFSET_CH1_OFFSET1(0) |
+ BF_PXP_DITHER_FETCH_SHIFT_OFFSET_CH1_OFFSET2(0) |
+ BF_PXP_DITHER_FETCH_SHIFT_OFFSET_CH1_OFFSET3(0),
+ pxp->base + HW_PXP_DITHER_FETCH_SHIFT_OFFSET_CH1);
+
+ __raw_writel(
+ BF_PXP_DITHER_FETCH_SHIFT_WIDTH_CH0_WIDTH0(7) |
+ BF_PXP_DITHER_FETCH_SHIFT_WIDTH_CH0_WIDTH1(7) |
+ BF_PXP_DITHER_FETCH_SHIFT_WIDTH_CH0_WIDTH2(7) |
+ BF_PXP_DITHER_FETCH_SHIFT_WIDTH_CH0_WIDTH3(7),
+ pxp->base + HW_PXP_DITHER_FETCH_SHIFT_WIDTH_CH0);
+
+ __raw_writel(
+ BF_PXP_DITHER_FETCH_SHIFT_WIDTH_CH1_WIDTH0(7) |
+ BF_PXP_DITHER_FETCH_SHIFT_WIDTH_CH1_WIDTH1(7) |
+ BF_PXP_DITHER_FETCH_SHIFT_WIDTH_CH1_WIDTH2(7) |
+ BF_PXP_DITHER_FETCH_SHIFT_WIDTH_CH1_WIDTH3(7),
+ pxp->base + HW_PXP_DITHER_FETCH_SHIFT_WIDTH_CH1);
+
+ __raw_writel(
+ BF_PXP_DITHER_FETCH_ADDR_0_CH0_INPUT_BASE_ADDR0(fetch_ch0->paddr),
+ pxp->base + HW_PXP_DITHER_FETCH_ADDR_0_CH0);
+
+ __raw_writel(
+ BF_PXP_DITHER_FETCH_ADDR_1_CH0_INPUT_BASE_ADDR1(0),
+ pxp->base + HW_PXP_DITHER_FETCH_ADDR_1_CH0);
+
+ __raw_writel(
+ BF_PXP_DITHER_FETCH_ADDR_0_CH1_INPUT_BASE_ADDR0(fetch_ch1->paddr),
+ pxp->base + HW_PXP_DITHER_FETCH_ADDR_0_CH1);
+
+ __raw_writel(
+ BF_PXP_DITHER_FETCH_ADDR_1_CH1_INPUT_BASE_ADDR1(0),
+ pxp->base + HW_PXP_DITHER_FETCH_ADDR_1_CH1);
+}
+
+static void dither_store_config(struct pxps *pxp)
+{
+ struct pxp_config_data *config_data = &pxp->pxp_conf_state;
+ struct pxp_layer_param *store_ch0 = &config_data->dither_store_param[0];
+ struct pxp_layer_param *store_ch1 = &config_data->dither_store_param[1];
+
+ print_param(store_ch0, "dither store_ch0");
+ print_param(store_ch1, "dither store_ch1");
+
+ __raw_writel(
+ BF_PXP_DITHER_STORE_CTRL_CH0_CH_EN(1)|
+ BF_PXP_DITHER_STORE_CTRL_CH0_BLOCK_EN(0)|
+ BF_PXP_DITHER_STORE_CTRL_CH0_BLOCK_16(0)|
+ BF_PXP_DITHER_STORE_CTRL_CH0_HANDSHAKE_EN(0)|
+ BF_PXP_DITHER_STORE_CTRL_CH0_ARRAY_EN(0)|
+ BF_PXP_DITHER_STORE_CTRL_CH0_ARRAY_LINE_NUM(0)|
+ BF_PXP_DITHER_STORE_CTRL_CH0_STORE_BYPASS_EN(0)|
+ BF_PXP_DITHER_STORE_CTRL_CH0_STORE_MEMORY_EN(1)|
+ BF_PXP_DITHER_STORE_CTRL_CH0_PACK_IN_SEL(0)|
+ BF_PXP_DITHER_STORE_CTRL_CH0_FILL_DATA_EN(0)|
+ BF_PXP_DITHER_STORE_CTRL_CH0_WR_NUM_BYTES(32)|
+ BF_PXP_DITHER_STORE_CTRL_CH0_COMBINE_2CHANNEL(0) |
+ BF_PXP_DITHER_STORE_CTRL_CH0_ARBIT_EN(0),
+ pxp->base + HW_PXP_DITHER_STORE_CTRL_CH0);
+
+ __raw_writel(
+ BF_PXP_DITHER_STORE_CTRL_CH1_CH_EN(0)|
+ BF_PXP_DITHER_STORE_CTRL_CH1_BLOCK_EN(0)|
+ BF_PXP_DITHER_STORE_CTRL_CH1_BLOCK_16(0)|
+ BF_PXP_DITHER_STORE_CTRL_CH1_HANDSHAKE_EN(0)|
+ BF_PXP_DITHER_STORE_CTRL_CH1_ARRAY_EN(0)|
+ BF_PXP_DITHER_STORE_CTRL_CH1_ARRAY_LINE_NUM(0)|
+ BF_PXP_DITHER_STORE_CTRL_CH1_STORE_BYPASS_EN(0)|
+ BF_PXP_DITHER_STORE_CTRL_CH1_STORE_MEMORY_EN(1)|
+ BF_PXP_DITHER_STORE_CTRL_CH1_PACK_IN_SEL(0)|
+ BF_PXP_DITHER_STORE_CTRL_CH1_WR_NUM_BYTES(32),
+ pxp->base + HW_PXP_DITHER_STORE_CTRL_CH1);
+
+ __raw_writel(
+ BF_PXP_DITHER_STORE_SIZE_CH0_OUT_WIDTH(store_ch0->width - 1) |
+ BF_PXP_DITHER_STORE_SIZE_CH0_OUT_HEIGHT(store_ch0->height - 1),
+ pxp->base + HW_PXP_DITHER_STORE_SIZE_CH0);
+
+ __raw_writel(
+ BF_PXP_DITHER_STORE_SIZE_CH1_OUT_WIDTH(store_ch1->width - 1) |
+ BF_PXP_DITHER_STORE_SIZE_CH1_OUT_HEIGHT(store_ch1->height - 1),
+ pxp->base + HW_PXP_DITHER_STORE_SIZE_CH1);
+
+ __raw_writel(
+ BF_PXP_DITHER_STORE_PITCH_CH0_OUT_PITCH(store_ch0->stride) |
+ BF_PXP_DITHER_STORE_PITCH_CH1_OUT_PITCH(store_ch1->stride),
+ pxp->base + HW_PXP_DITHER_STORE_PITCH);
+
+ __raw_writel(
+ BF_PXP_DITHER_STORE_SHIFT_CTRL_CH0_OUTPUT_ACTIVE_BPP(0)|
+ BF_PXP_DITHER_STORE_SHIFT_CTRL_CH0_OUT_YUV422_1P_EN(0)|
+ BF_PXP_DITHER_STORE_SHIFT_CTRL_CH0_OUT_YUV422_2P_EN(0)|
+ BF_PXP_DITHER_STORE_SHIFT_CTRL_CH0_SHIFT_BYPASS(1),
+ pxp->base + HW_PXP_DITHER_STORE_SHIFT_CTRL_CH0);
+
+ __raw_writel(
+ BF_PXP_DITHER_STORE_SHIFT_CTRL_CH1_OUTPUT_ACTIVE_BPP(0)|
+ BF_PXP_DITHER_STORE_SHIFT_CTRL_CH1_OUT_YUV422_1P_EN(0)|
+ BF_PXP_DITHER_STORE_SHIFT_CTRL_CH1_OUT_YUV422_2P_EN(0),
+ pxp->base + HW_PXP_DITHER_STORE_SHIFT_CTRL_CH1);
+
+ __raw_writel(
+ BF_PXP_DITHER_STORE_ADDR_0_CH0_OUT_BASE_ADDR0(store_ch0->paddr),
+ pxp->base + HW_PXP_DITHER_STORE_ADDR_0_CH0);
+
+ __raw_writel(
+ BF_PXP_DITHER_STORE_ADDR_1_CH0_OUT_BASE_ADDR1(0),
+ pxp->base + HW_PXP_DITHER_STORE_ADDR_1_CH0);
+
+ __raw_writel(
+ BF_PXP_DITHER_STORE_ADDR_0_CH1_OUT_BASE_ADDR0(store_ch1->paddr),
+ pxp->base + HW_PXP_DITHER_STORE_ADDR_0_CH1);
+
+ __raw_writel(
+ BF_PXP_DITHER_STORE_ADDR_1_CH1_OUT_BASE_ADDR1(0),
+ pxp->base + HW_PXP_DITHER_STORE_ADDR_1_CH1);
+
+ __raw_writel(
+ BF_PXP_DITHER_STORE_FILL_DATA_CH0_FILL_DATA_CH0(0),
+ pxp->base + HW_PXP_DITHER_STORE_FILL_DATA_CH0);
+
+ __raw_writel(
+ BF_PXP_DITHER_STORE_D_MASK0_H_CH0_D_MASK0_H_CH0(0xffffff),
+ pxp->base + HW_PXP_DITHER_STORE_D_MASK0_H_CH0);
+
+ __raw_writel(
+ BF_PXP_DITHER_STORE_D_MASK0_L_CH0_D_MASK0_L_CH0(0x0),
+ pxp->base + HW_PXP_DITHER_STORE_D_MASK0_L_CH0);
+
+ __raw_writel(
+ BF_PXP_DITHER_STORE_D_MASK1_H_CH0_D_MASK1_H_CH0(0x0),
+ pxp->base + HW_PXP_DITHER_STORE_D_MASK1_H_CH0);
+
+ __raw_writel(
+ BF_PXP_DITHER_STORE_D_MASK1_L_CH0_D_MASK1_L_CH0(0xff),
+ pxp->base + HW_PXP_DITHER_STORE_D_MASK1_L_CH0);
+
+ __raw_writel(
+ BF_PXP_DITHER_STORE_D_SHIFT_L_CH0_D_SHIFT_WIDTH0(32) |
+ BF_PXP_DITHER_STORE_D_SHIFT_L_CH0_D_SHIFT_FLAG0(0) |
+ BF_PXP_DITHER_STORE_D_SHIFT_L_CH0_D_SHIFT_WIDTH1(32)|
+ BF_PXP_DITHER_STORE_D_SHIFT_L_CH0_D_SHIFT_FLAG1(1) |
+ BF_PXP_DITHER_STORE_D_SHIFT_L_CH0_D_SHIFT_WIDTH2(0)|
+ BF_PXP_DITHER_STORE_D_SHIFT_L_CH0_D_SHIFT_FLAG2(0)|
+ BF_PXP_DITHER_STORE_D_SHIFT_L_CH0_D_SHIFT_WIDTH3(0)|
+ BF_PXP_DITHER_STORE_D_SHIFT_L_CH0_D_SHIFT_FLAG3(0),
+ pxp->base + HW_PXP_DITHER_STORE_D_SHIFT_L_CH0);
+}
+
+static void pxp_set_final_lut_data(struct pxps *pxp)
+{
+ struct pxp_config_data *pxp_conf = &pxp->pxp_conf_state;
+ struct pxp_proc_data *proc_data = &pxp_conf->proc_data;
+
+ if(proc_data->quant_bit < 2) {
+ pxp_sram_init(pxp, DITHER0_LUT, (u32)bit1_dither_data_8x8, 64);
+
+ __raw_writel(
+ BF_PXP_DITHER_FINAL_LUT_DATA0_DATA0(0x0) |
+ BF_PXP_DITHER_FINAL_LUT_DATA0_DATA1(0x0) |
+ BF_PXP_DITHER_FINAL_LUT_DATA0_DATA2(0x0) |
+ BF_PXP_DITHER_FINAL_LUT_DATA0_DATA3(0x0),
+ pxp->base + HW_PXP_DITHER_FINAL_LUT_DATA0);
+
+ __raw_writel(
+ BF_PXP_DITHER_FINAL_LUT_DATA1_DATA4(0x0) |
+ BF_PXP_DITHER_FINAL_LUT_DATA1_DATA5(0x0) |
+ BF_PXP_DITHER_FINAL_LUT_DATA1_DATA6(0x0) |
+ BF_PXP_DITHER_FINAL_LUT_DATA1_DATA7(0x0),
+ pxp->base + HW_PXP_DITHER_FINAL_LUT_DATA1);
+
+ __raw_writel(
+ BF_PXP_DITHER_FINAL_LUT_DATA2_DATA8(0xf0) |
+ BF_PXP_DITHER_FINAL_LUT_DATA2_DATA9(0xf0) |
+ BF_PXP_DITHER_FINAL_LUT_DATA2_DATA10(0xf0)|
+ BF_PXP_DITHER_FINAL_LUT_DATA2_DATA11(0xf0),
+ pxp->base + HW_PXP_DITHER_FINAL_LUT_DATA2);
+
+ __raw_writel(
+ BF_PXP_DITHER_FINAL_LUT_DATA3_DATA12(0xf0) |
+ BF_PXP_DITHER_FINAL_LUT_DATA3_DATA13(0xf0) |
+ BF_PXP_DITHER_FINAL_LUT_DATA3_DATA14(0xf0) |
+ BF_PXP_DITHER_FINAL_LUT_DATA3_DATA15(0xf0),
+ pxp->base + HW_PXP_DITHER_FINAL_LUT_DATA3);
+ } else if(proc_data->quant_bit < 4) {
+ pxp_sram_init(pxp, DITHER0_LUT, (u32)bit2_dither_data_8x8, 64);
+
+ __raw_writel(
+ BF_PXP_DITHER_FINAL_LUT_DATA0_DATA0(0x0) |
+ BF_PXP_DITHER_FINAL_LUT_DATA0_DATA1(0x0) |
+ BF_PXP_DITHER_FINAL_LUT_DATA0_DATA2(0x0) |
+ BF_PXP_DITHER_FINAL_LUT_DATA0_DATA3(0x0),
+ pxp->base + HW_PXP_DITHER_FINAL_LUT_DATA0);
+
+ __raw_writel(
+ BF_PXP_DITHER_FINAL_LUT_DATA1_DATA4(0x50) |
+ BF_PXP_DITHER_FINAL_LUT_DATA1_DATA5(0x50) |
+ BF_PXP_DITHER_FINAL_LUT_DATA1_DATA6(0x50) |
+ BF_PXP_DITHER_FINAL_LUT_DATA1_DATA7(0x50),
+ pxp->base + HW_PXP_DITHER_FINAL_LUT_DATA1);
+
+ __raw_writel(
+ BF_PXP_DITHER_FINAL_LUT_DATA2_DATA8(0xa0) |
+ BF_PXP_DITHER_FINAL_LUT_DATA2_DATA9(0xa0) |
+ BF_PXP_DITHER_FINAL_LUT_DATA2_DATA10(0xa0)|
+ BF_PXP_DITHER_FINAL_LUT_DATA2_DATA11(0xa0),
+ pxp->base + HW_PXP_DITHER_FINAL_LUT_DATA2);
+
+ __raw_writel(
+ BF_PXP_DITHER_FINAL_LUT_DATA3_DATA12(0xf0) |
+ BF_PXP_DITHER_FINAL_LUT_DATA3_DATA13(0xf0) |
+ BF_PXP_DITHER_FINAL_LUT_DATA3_DATA14(0xf0) |
+ BF_PXP_DITHER_FINAL_LUT_DATA3_DATA15(0xf0),
+ pxp->base + HW_PXP_DITHER_FINAL_LUT_DATA3);
+ } else {
+ pxp_sram_init(pxp, DITHER0_LUT, (u32)bit4_dither_data_8x8, 64);
+
+ __raw_writel(
+ BF_PXP_DITHER_FINAL_LUT_DATA0_DATA0(0x0) |
+ BF_PXP_DITHER_FINAL_LUT_DATA0_DATA1(0x10) |
+ BF_PXP_DITHER_FINAL_LUT_DATA0_DATA2(0x20) |
+ BF_PXP_DITHER_FINAL_LUT_DATA0_DATA3(0x30),
+ pxp->base + HW_PXP_DITHER_FINAL_LUT_DATA0);
+
+ __raw_writel(
+ BF_PXP_DITHER_FINAL_LUT_DATA1_DATA4(0x40) |
+ BF_PXP_DITHER_FINAL_LUT_DATA1_DATA5(0x50) |
+ BF_PXP_DITHER_FINAL_LUT_DATA1_DATA6(0x60) |
+ BF_PXP_DITHER_FINAL_LUT_DATA1_DATA7(0x70),
+ pxp->base + HW_PXP_DITHER_FINAL_LUT_DATA1);
+
+ __raw_writel(
+ BF_PXP_DITHER_FINAL_LUT_DATA2_DATA8(0x80) |
+ BF_PXP_DITHER_FINAL_LUT_DATA2_DATA9(0x90) |
+ BF_PXP_DITHER_FINAL_LUT_DATA2_DATA10(0xa0)|
+ BF_PXP_DITHER_FINAL_LUT_DATA2_DATA11(0xb0),
+ pxp->base + HW_PXP_DITHER_FINAL_LUT_DATA2);
+
+ __raw_writel(
+ BF_PXP_DITHER_FINAL_LUT_DATA3_DATA12(0xc0) |
+ BF_PXP_DITHER_FINAL_LUT_DATA3_DATA13(0xd0) |
+ BF_PXP_DITHER_FINAL_LUT_DATA3_DATA14(0xe0) |
+ BF_PXP_DITHER_FINAL_LUT_DATA3_DATA15(0xf0),
+ pxp->base + HW_PXP_DITHER_FINAL_LUT_DATA3);
+ }
+}
+
+static void pxp_dithering_process(struct pxps *pxp)
+{
+ struct pxp_config_data *pxp_conf = &pxp->pxp_conf_state;
+ struct pxp_proc_data *proc_data = &pxp_conf->proc_data;
+ u32 val = 0;
+
+ if (pxp->devdata && pxp->devdata->pxp_dithering_configure)
+ pxp->devdata->pxp_dithering_configure(pxp);
+
+ if (pxp_is_v3(pxp))
+ val = BF_PXP_DITHER_CTRL_ENABLE0 (1) |
+ BF_PXP_DITHER_CTRL_ENABLE1 (0) |
+ BF_PXP_DITHER_CTRL_ENABLE2 (0) |
+ BF_PXP_DITHER_CTRL_DITHER_MODE2 (0) |
+ BF_PXP_DITHER_CTRL_DITHER_MODE1 (0) |
+ BF_PXP_DITHER_CTRL_DITHER_MODE0(proc_data->dither_mode) |
+ BF_PXP_DITHER_CTRL_LUT_MODE (0) |
+ BF_PXP_DITHER_CTRL_IDX_MATRIX0_SIZE (1) |
+ BF_PXP_DITHER_CTRL_IDX_MATRIX1_SIZE (0) |
+ BF_PXP_DITHER_CTRL_IDX_MATRIX2_SIZE (0) |
+ BF_PXP_DITHER_CTRL_BUSY2 (0) |
+ BF_PXP_DITHER_CTRL_BUSY1 (0) |
+ BF_PXP_DITHER_CTRL_BUSY0 (0);
+ else if (pxp_is_v3p(pxp)) {
+ if (proc_data->dither_mode != 0 &&
+ proc_data->dither_mode != 3) {
+ dev_err(pxp->dev, "Not supported dithering mode. "
+ "Forced to be Orderred mode!\n");
+ proc_data->dither_mode = 3;
+ }
+
+ val = BF_PXP_DITHER_CTRL_ENABLE0 (1) |
+ BF_PXP_DITHER_CTRL_ENABLE1 (1) |
+ BF_PXP_DITHER_CTRL_ENABLE2 (1) |
+ BF_PXP_DITHER_CTRL_DITHER_MODE2(proc_data->dither_mode) |
+ BF_PXP_DITHER_CTRL_DITHER_MODE1(proc_data->dither_mode) |
+ BF_PXP_DITHER_CTRL_DITHER_MODE0(proc_data->dither_mode) |
+ BF_PXP_DITHER_CTRL_LUT_MODE (0) |
+ BF_PXP_DITHER_CTRL_IDX_MATRIX0_SIZE (1) |
+ BF_PXP_DITHER_CTRL_IDX_MATRIX1_SIZE (1) |
+ BF_PXP_DITHER_CTRL_IDX_MATRIX2_SIZE (1) |
+ BF_PXP_DITHER_CTRL_FINAL_LUT_ENABLE (0) |
+ BF_PXP_DITHER_CTRL_BUSY2 (0) |
+ BF_PXP_DITHER_CTRL_BUSY1 (0) |
+ BF_PXP_DITHER_CTRL_BUSY0 (0);
+ }
+ __raw_writel(val, pxp->base + HW_PXP_DITHER_CTRL);
+
+ switch(proc_data->dither_mode) {
+ case PXP_DITHER_PASS_THROUGH:
+ /* no more settings required */
+ break;
+ case PXP_DITHER_FLOYD:
+ case PXP_DITHER_ATKINSON:
+ case PXP_DITHER_ORDERED:
+ if(!proc_data->quant_bit || proc_data->quant_bit > 7) {
+ dev_err(pxp->dev, "unsupported quantization bit number!\n");
+ return;
+ }
+ __raw_writel(
+ BF_PXP_DITHER_CTRL_FINAL_LUT_ENABLE(1) |
+ BF_PXP_DITHER_CTRL_NUM_QUANT_BIT(proc_data->quant_bit),
+ pxp->base + HW_PXP_DITHER_CTRL_SET);
+ pxp_set_final_lut_data(pxp);
+
+ break;
+ case PXP_DITHER_QUANT_ONLY:
+ if(!proc_data->quant_bit || proc_data->quant_bit > 7) {
+ dev_err(pxp->dev, "unsupported quantization bit number!\n");
+ return;
+ }
+ __raw_writel(
+ BF_PXP_DITHER_CTRL_NUM_QUANT_BIT(proc_data->quant_bit),
+ pxp->base + HW_PXP_DITHER_CTRL_SET);
+ break;
+ default:
+ /* unknown mode */
+ dev_err(pxp->dev, "unknown dithering mode passed!\n");
+ __raw_writel(0x0, pxp->base + HW_PXP_DITHER_CTRL);
+ return;
+ }
+}
+
+static void pxp_dithering_configure(struct pxps *pxp)
+{
+ dither_prefetch_config(pxp);
+ dither_store_config(pxp);
+}
+
+static void pxp_dithering_configure_v3p(struct pxps *pxp)
+{
+ struct pxp_config_data *config_data = &pxp->pxp_conf_state;
+ struct pxp_layer_param *fetch_ch0 = &config_data->dither_fetch_param[0];
+ struct pxp_layer_param *store_ch0 = &config_data->dither_store_param[0];
+
+ __raw_writel(BF_PXP_CTRL_BLOCK_SIZE(BV_PXP_CTRL_BLOCK_SIZE__8X8) |
+ BF_PXP_CTRL_ROTATE0(BV_PXP_CTRL_ROTATE0__ROT_0) |
+ BM_PXP_CTRL_IRQ_ENABLE,
+ pxp->base + HW_PXP_CTRL);
+
+ __raw_writel(BF_PXP_PS_CTRL_DECX(BV_PXP_PS_CTRL_DECX__DISABLE) |
+ BF_PXP_PS_CTRL_DECY(BV_PXP_PS_CTRL_DECY__DISABLE) |
+ BF_PXP_PS_CTRL_FORMAT(BV_PXP_PS_CTRL_FORMAT__Y8),
+ pxp->base + HW_PXP_PS_CTRL);
+
+ __raw_writel(BF_PXP_OUT_CTRL_FORMAT(BV_PXP_OUT_CTRL_FORMAT__Y8),
+ pxp->base + HW_PXP_OUT_CTRL);
+
+ __raw_writel(BF_PXP_PS_SCALE_YSCALE(4096) |
+ BF_PXP_PS_SCALE_XSCALE(4096),
+ pxp->base + HW_PXP_PS_SCALE);
+
+ __raw_writel(store_ch0->paddr, pxp->base + HW_PXP_OUT_BUF);
+
+ __raw_writel(store_ch0->stride, pxp->base + HW_PXP_OUT_PITCH);
+
+ __raw_writel(BF_PXP_OUT_LRC_X(store_ch0->width - 1) |
+ BF_PXP_OUT_LRC_Y(store_ch0->height - 1),
+ pxp->base + HW_PXP_OUT_LRC);
+
+ __raw_writel(BF_PXP_OUT_AS_ULC_X(1) |
+ BF_PXP_OUT_AS_ULC_Y(1),
+ pxp->base + HW_PXP_OUT_AS_ULC);
+
+ __raw_writel(BF_PXP_OUT_AS_LRC_X(0) |
+ BF_PXP_OUT_AS_LRC_Y(0),
+ pxp->base + HW_PXP_OUT_AS_LRC);
+
+ __raw_writel(BF_PXP_OUT_PS_ULC_X(0) |
+ BF_PXP_OUT_PS_ULC_Y(0),
+ pxp->base + HW_PXP_OUT_PS_ULC);
+
+ __raw_writel(BF_PXP_OUT_PS_LRC_X(fetch_ch0->width - 1) |
+ BF_PXP_OUT_PS_LRC_Y(fetch_ch0->height - 1),
+ pxp->base + HW_PXP_OUT_PS_LRC);
+
+ __raw_writel(fetch_ch0->paddr, pxp->base + HW_PXP_PS_BUF);
+
+ __raw_writel(fetch_ch0->stride, pxp->base + HW_PXP_PS_PITCH);
+
+ __raw_writel(0x40000000, pxp->base + HW_PXP_CSC1_COEF0);
+
+ __raw_writel(BF_PXP_DITHER_STORE_SIZE_CH0_OUT_WIDTH(store_ch0->width-1)|
+ BF_PXP_DITHER_STORE_SIZE_CH0_OUT_HEIGHT(store_ch0->height-1),
+ pxp->base + HW_PXP_DITHER_STORE_SIZE_CH0);
+
+ __raw_writel(BF_PXP_DATA_PATH_CTRL0_MUX14_SEL(1),
+ pxp->base + HW_PXP_DATA_PATH_CTRL0_CLR);
+}
+
+static void pxp_start2(struct pxps *pxp)
+{
+ struct pxp_config_data *pxp_conf = &pxp->pxp_conf_state;
+ struct pxp_proc_data *proc_data = &pxp_conf->proc_data;
+ int dither_wfe_a_handshake = 0;
+ int wfe_a_b_handshake = 0;
+ int count = 0;
+
+ int wfe_a_enable = ((proc_data->engine_enable & PXP_ENABLE_WFE_A) == PXP_ENABLE_WFE_A);
+ int wfe_b_enable = ((proc_data->engine_enable & PXP_ENABLE_WFE_B) == PXP_ENABLE_WFE_B);
+ int dither_enable = ((proc_data->engine_enable & PXP_ENABLE_DITHER) == PXP_ENABLE_DITHER);
+ int handshake = ((proc_data->engine_enable & PXP_ENABLE_HANDSHAKE) == PXP_ENABLE_HANDSHAKE);
+ int dither_bypass = ((proc_data->engine_enable & PXP_ENABLE_DITHER_BYPASS) == PXP_ENABLE_DITHER_BYPASS);
+ u32 val = 0;
+
+ if (dither_enable)
+ count++;
+ if (wfe_a_enable)
+ count++;
+ if (wfe_b_enable)
+ count++;
+
+ if (count == 0)
+ return;
+ if (handshake && (count == 1)) {
+ dev_warn(pxp->dev, "Warning: Can not use handshake mode when "
+ "only one sub-block is enabled!\n");
+ handshake = 0;
+ }
+
+ if (handshake && wfe_b_enable && (wfe_a_enable == 0)) {
+ dev_err(pxp->dev, "WFE_B only works when WFE_A is enabled!\n");
+ return;
+ }
+
+ if (handshake && dither_enable && wfe_a_enable)
+ dither_wfe_a_handshake = 1;
+ if (handshake && wfe_a_enable && wfe_b_enable)
+ wfe_a_b_handshake = 1;
+
+ dev_dbg(pxp->dev, "handshake %d, dither_wfe_a_handshake %d, "
+ "wfe_a_b_handshake %d, dither_bypass %d\n",
+ handshake,
+ dither_wfe_a_handshake,
+ wfe_a_b_handshake,
+ dither_bypass);
+
+ if (handshake) {
+ /* for handshake, we only enable the last completion INT */
+ if (wfe_b_enable)
+ __raw_writel(0x8000, pxp->base + HW_PXP_IRQ_MASK);
+ else if (wfe_a_enable)
+ __raw_writel(0x4000, pxp->base + HW_PXP_IRQ_MASK);
+
+ /* Dither fetch */
+ __raw_writel(
+ BF_PXP_DITHER_FETCH_CTRL_CH0_CH_EN(1) |
+ BF_PXP_DITHER_FETCH_CTRL_CH0_BLOCK_EN(0) |
+ BF_PXP_DITHER_FETCH_CTRL_CH0_BLOCK_16(0)|
+ BF_PXP_DITHER_FETCH_CTRL_CH0_HANDSHAKE_EN(0) |
+ BF_PXP_DITHER_FETCH_CTRL_CH0_BYPASS_PIXEL_EN(0) |
+ BF_PXP_DITHER_FETCH_CTRL_CH0_HIGH_BYTE(0) |
+ BF_PXP_DITHER_FETCH_CTRL_CH0_HFLIP(0) |
+ BF_PXP_DITHER_FETCH_CTRL_CH0_VFLIP(0) |
+ BF_PXP_DITHER_FETCH_CTRL_CH0_ROTATION_ANGLE(0) |
+ BF_PXP_DITHER_FETCH_CTRL_CH0_RD_NUM_BYTES(32) |
+ BF_PXP_DITHER_FETCH_CTRL_CH0_HANDSHAKE_SCAN_LINE_NUM(0) |
+ BF_PXP_DITHER_FETCH_CTRL_CH0_ARBIT_EN(0),
+ pxp->base + HW_PXP_DITHER_FETCH_CTRL_CH0);
+
+ if (dither_bypass) {
+ /* Dither store */
+ __raw_writel(
+ BF_PXP_DITHER_STORE_CTRL_CH0_CH_EN(1)|
+ BF_PXP_DITHER_STORE_CTRL_CH0_BLOCK_EN(0)|
+ BF_PXP_DITHER_STORE_CTRL_CH0_BLOCK_16(0)|
+ BF_PXP_DITHER_STORE_CTRL_CH0_HANDSHAKE_EN(0)|
+ BF_PXP_DITHER_STORE_CTRL_CH0_ARRAY_EN(0)|
+ BF_PXP_DITHER_STORE_CTRL_CH0_ARRAY_LINE_NUM(0)|
+ BF_PXP_DITHER_STORE_CTRL_CH0_STORE_BYPASS_EN(1)|
+ BF_PXP_DITHER_STORE_CTRL_CH0_STORE_MEMORY_EN(1)|
+ BF_PXP_DITHER_STORE_CTRL_CH0_PACK_IN_SEL(0)|
+ BF_PXP_DITHER_STORE_CTRL_CH0_FILL_DATA_EN(0)|
+ BF_PXP_DITHER_STORE_CTRL_CH0_WR_NUM_BYTES(32)|
+ BF_PXP_DITHER_STORE_CTRL_CH0_COMBINE_2CHANNEL(0) |
+ BF_PXP_DITHER_STORE_CTRL_CH0_ARBIT_EN(0),
+ pxp->base + HW_PXP_DITHER_STORE_CTRL_CH0);
+
+ /* WFE_A fetch */
+ __raw_writel(
+ BF_PXP_WFA_FETCH_CTRL_BF1_EN(1) |
+ BF_PXP_WFA_FETCH_CTRL_BF1_HSK_MODE(0) |
+ BF_PXP_WFA_FETCH_CTRL_BF1_BYTES_PP(2) |
+ BF_PXP_WFA_FETCH_CTRL_BF1_LINE_MODE(0) |
+ BF_PXP_WFA_FETCH_CTRL_BF1_SRAM_IF(0) |
+ BF_PXP_WFA_FETCH_CTRL_BF1_BURST_LEN(0) |
+ BF_PXP_WFA_FETCH_CTRL_BF1_BYPASS_MODE(1) |
+ BF_PXP_WFA_FETCH_CTRL_BF2_EN(1) |
+ BF_PXP_WFA_FETCH_CTRL_BF2_HSK_MODE(0) |
+ BF_PXP_WFA_FETCH_CTRL_BF2_BYTES_PP(1) |
+ BF_PXP_WFA_FETCH_CTRL_BF2_LINE_MODE(0) |
+ BF_PXP_WFA_FETCH_CTRL_BF2_SRAM_IF(0) |
+ BF_PXP_WFA_FETCH_CTRL_BF2_BURST_LEN(0) |
+ BF_PXP_WFA_FETCH_CTRL_BF2_BYPASS_MODE(0),
+ pxp->base + HW_PXP_WFA_FETCH_CTRL);
+
+ } else if (dither_wfe_a_handshake) {
+ /* Dither store */
+ __raw_writel(
+ BF_PXP_DITHER_STORE_CTRL_CH0_CH_EN(1)|
+ BF_PXP_DITHER_STORE_CTRL_CH0_BLOCK_EN(0)|
+ BF_PXP_DITHER_STORE_CTRL_CH0_BLOCK_16(0)|
+ BF_PXP_DITHER_STORE_CTRL_CH0_HANDSHAKE_EN(1)|
+ BF_PXP_DITHER_STORE_CTRL_CH0_ARRAY_EN(1)|
+ BF_PXP_DITHER_STORE_CTRL_CH0_ARRAY_LINE_NUM(0)|
+ BF_PXP_DITHER_STORE_CTRL_CH0_STORE_BYPASS_EN(0)|
+ BF_PXP_DITHER_STORE_CTRL_CH0_STORE_MEMORY_EN(1)|
+ BF_PXP_DITHER_STORE_CTRL_CH0_PACK_IN_SEL(0)|
+ BF_PXP_DITHER_STORE_CTRL_CH0_FILL_DATA_EN(0)|
+ BF_PXP_DITHER_STORE_CTRL_CH0_WR_NUM_BYTES(32)|
+ BF_PXP_DITHER_STORE_CTRL_CH0_COMBINE_2CHANNEL(0) |
+ BF_PXP_DITHER_STORE_CTRL_CH0_ARBIT_EN(0),
+ pxp->base + HW_PXP_DITHER_STORE_CTRL_CH0);
+
+ /* WFE_A fetch */
+ __raw_writel(
+ BF_PXP_WFA_FETCH_CTRL_BF1_EN(1) |
+ BF_PXP_WFA_FETCH_CTRL_BF1_HSK_MODE(1) |
+ BF_PXP_WFA_FETCH_CTRL_BF1_BYTES_PP(0) |
+ BF_PXP_WFA_FETCH_CTRL_BF1_LINE_MODE(0) |
+ BF_PXP_WFA_FETCH_CTRL_BF1_SRAM_IF(0) |
+ BF_PXP_WFA_FETCH_CTRL_BF1_BURST_LEN(0) |
+ BF_PXP_WFA_FETCH_CTRL_BF1_BYPASS_MODE(0) |
+ BF_PXP_WFA_FETCH_CTRL_BF2_EN(1) |
+ BF_PXP_WFA_FETCH_CTRL_BF2_HSK_MODE(0) |
+ BF_PXP_WFA_FETCH_CTRL_BF2_BYTES_PP(1) |
+ BF_PXP_WFA_FETCH_CTRL_BF2_LINE_MODE(0) |
+ BF_PXP_WFA_FETCH_CTRL_BF2_SRAM_IF(0) |
+ BF_PXP_WFA_FETCH_CTRL_BF2_BURST_LEN(0) |
+ BF_PXP_WFA_FETCH_CTRL_BF2_BYPASS_MODE(0),
+ pxp->base + HW_PXP_WFA_FETCH_CTRL);
+ }
+
+ if (wfe_a_b_handshake) {
+ /* WFE_A Store */
+ __raw_writel(
+ BF_PXP_WFE_A_STORE_CTRL_CH1_CH_EN(1)|
+ BF_PXP_WFE_A_STORE_CTRL_CH1_BLOCK_EN(0)|
+ BF_PXP_WFE_A_STORE_CTRL_CH1_BLOCK_16(0)|
+ BF_PXP_WFE_A_STORE_CTRL_CH1_HANDSHAKE_EN(1)|
+ BF_PXP_WFE_A_STORE_CTRL_CH1_ARRAY_EN(1)|
+ BF_PXP_WFE_A_STORE_CTRL_CH1_ARRAY_LINE_NUM(1)|
+ BF_PXP_WFE_A_STORE_CTRL_CH1_STORE_BYPASS_EN(0)|
+ BF_PXP_WFE_A_STORE_CTRL_CH1_STORE_MEMORY_EN(1)|
+ BF_PXP_WFE_A_STORE_CTRL_CH1_PACK_IN_SEL(1)|
+ BF_PXP_WFE_A_STORE_CTRL_CH1_WR_NUM_BYTES(16),
+ pxp->base + HW_PXP_WFE_A_STORE_CTRL_CH1);
+
+ /* WFE_B fetch */
+ __raw_writel(
+ BF_PXP_WFB_FETCH_CTRL_BF1_EN(1) |
+ BF_PXP_WFB_FETCH_CTRL_BF1_HSK_MODE(0) |
+ BF_PXP_WFB_FETCH_CTRL_BF1_BYTES_PP(0) |
+ BF_PXP_WFB_FETCH_CTRL_BF1_LINE_MODE(1) |
+ BF_PXP_WFB_FETCH_CTRL_BF1_SRAM_IF(1) |
+ BF_PXP_WFB_FETCH_CTRL_BF1_BURST_LEN(0) |
+ BF_PXP_WFB_FETCH_CTRL_BF1_BORDER_MODE(1) |
+ BF_PXP_WFB_FETCH_CTRL_BF1_BYPASS_MODE(0) |
+ BF_PXP_WFB_FETCH_CTRL_BF2_EN(1) |
+ BF_PXP_WFB_FETCH_CTRL_BF2_HSK_MODE(1) |
+ BF_PXP_WFB_FETCH_CTRL_BF2_BYTES_PP(1) |
+ BF_PXP_WFB_FETCH_CTRL_BF2_LINE_MODE(1) |
+ BF_PXP_WFB_FETCH_CTRL_BF2_SRAM_IF(0) |
+ BF_PXP_WFB_FETCH_CTRL_BF2_BURST_LEN(0) |
+ BF_PXP_WFB_FETCH_CTRL_BF2_BORDER_MODE(1) |
+ BF_PXP_WFB_FETCH_CTRL_BF2_BYPASS_MODE(0),
+ pxp->base + HW_PXP_WFB_FETCH_CTRL);
+ } else {
+ /* WFE_A Store */
+ __raw_writel(
+ BF_PXP_WFE_A_STORE_CTRL_CH1_CH_EN(1)|
+ BF_PXP_WFE_A_STORE_CTRL_CH1_BLOCK_EN(0)|
+ BF_PXP_WFE_A_STORE_CTRL_CH1_BLOCK_16(0)|
+ BF_PXP_WFE_A_STORE_CTRL_CH1_HANDSHAKE_EN(0)|
+ BF_PXP_WFE_A_STORE_CTRL_CH1_ARRAY_EN(0)|
+ BF_PXP_WFE_A_STORE_CTRL_CH1_ARRAY_LINE_NUM(0)|
+ BF_PXP_WFE_A_STORE_CTRL_CH1_STORE_BYPASS_EN(0)|
+ BF_PXP_WFE_A_STORE_CTRL_CH1_STORE_MEMORY_EN(1)|
+ BF_PXP_WFE_A_STORE_CTRL_CH1_PACK_IN_SEL(1)|
+ BF_PXP_WFE_A_STORE_CTRL_CH1_WR_NUM_BYTES(16),
+ pxp->base + HW_PXP_WFE_A_STORE_CTRL_CH1);
+ }
+
+ if (pxp_is_v3(pxp))
+ val = BF_PXP_CTRL_ENABLE_WFE_A(wfe_a_enable) |
+ BF_PXP_CTRL_ENABLE_WFE_B(wfe_b_enable);
+ else if (pxp_is_v3p(pxp))
+ val = BF_PXP_CTRL_ENABLE_WFE_B(wfe_a_enable |
+ wfe_b_enable);
+
+ /* trigger operation */
+ __raw_writel(
+ BF_PXP_CTRL_ENABLE(1) |
+ BF_PXP_CTRL_IRQ_ENABLE(0) |
+ BF_PXP_CTRL_NEXT_IRQ_ENABLE(0) |
+ BF_PXP_CTRL_LUT_DMA_IRQ_ENABLE(0) |
+ BF_PXP_CTRL_ENABLE_LCD0_HANDSHAKE(1) |
+ BF_PXP_CTRL_HANDSHAKE_ABORT_SKIP(1) |
+ BF_PXP_CTRL_ROTATE0(0) |
+ BF_PXP_CTRL_HFLIP0(0) |
+ BF_PXP_CTRL_VFLIP0(0) |
+ BF_PXP_CTRL_ROTATE1(0) |
+ BF_PXP_CTRL_HFLIP1(0) |
+ BF_PXP_CTRL_VFLIP1(0) |
+ BF_PXP_CTRL_ENABLE_PS_AS_OUT(0) |
+ BF_PXP_CTRL_ENABLE_DITHER(dither_enable) |
+ BF_PXP_CTRL_ENABLE_INPUT_FETCH_STORE(0) |
+ BF_PXP_CTRL_ENABLE_ALPHA_B(0) |
+ BF_PXP_CTRL_BLOCK_SIZE(1) |
+ BF_PXP_CTRL_ENABLE_CSC2(0) |
+ BF_PXP_CTRL_ENABLE_LUT(1) |
+ BF_PXP_CTRL_ENABLE_ROTATE0(0) |
+ BF_PXP_CTRL_ENABLE_ROTATE1(0) |
+ BF_PXP_CTRL_EN_REPEAT(0) |
+ val,
+ pxp->base + HW_PXP_CTRL);
+
+ return;
+ }
+
+ if (pxp_is_v3(pxp))
+ val = BF_PXP_CTRL_ENABLE_WFE_A(wfe_a_enable) |
+ BF_PXP_CTRL_ENABLE_WFE_B(wfe_b_enable) |
+ BF_PXP_CTRL_ENABLE_INPUT_FETCH_STORE(0) |
+ BF_PXP_CTRL_ENABLE_ALPHA_B(0);
+ else if (pxp_is_v3p(pxp))
+ val = BF_PXP_CTRL_ENABLE_WFE_B(wfe_a_enable |
+ wfe_b_enable);
+
+ __raw_writel(
+ BF_PXP_CTRL_ENABLE(1) |
+ BF_PXP_CTRL_IRQ_ENABLE(0) |
+ BF_PXP_CTRL_NEXT_IRQ_ENABLE(0) |
+ BF_PXP_CTRL_LUT_DMA_IRQ_ENABLE(0) |
+ BF_PXP_CTRL_ENABLE_LCD0_HANDSHAKE(0) |
+ BF_PXP_CTRL_ROTATE0(0) |
+ BF_PXP_CTRL_HFLIP0(0) |
+ BF_PXP_CTRL_VFLIP0(0) |
+ BF_PXP_CTRL_ROTATE1(0) |
+ BF_PXP_CTRL_HFLIP1(0) |
+ BF_PXP_CTRL_VFLIP1(0) |
+ BF_PXP_CTRL_ENABLE_PS_AS_OUT(0) |
+ BF_PXP_CTRL_ENABLE_DITHER(dither_enable) |
+ BF_PXP_CTRL_BLOCK_SIZE(0) |
+ BF_PXP_CTRL_ENABLE_CSC2(0) |
+ BF_PXP_CTRL_ENABLE_LUT(0) |
+ BF_PXP_CTRL_ENABLE_ROTATE0(0) |
+ BF_PXP_CTRL_ENABLE_ROTATE1(0) |
+ BF_PXP_CTRL_EN_REPEAT(0) |
+ val,
+ pxp->base + HW_PXP_CTRL);
+
+ if (pxp_is_v3(pxp))
+ val = BF_PXP_CTRL2_ENABLE_WFE_A (0) |
+ BF_PXP_CTRL2_ENABLE_WFE_B (0) |
+ BF_PXP_CTRL2_ENABLE_INPUT_FETCH_STORE (0) |
+ BF_PXP_CTRL2_ENABLE_ALPHA_B (0);
+ else if (pxp_is_v3p(pxp))
+ val = BF_PXP_CTRL2_ENABLE_WFE_B(0);
+
+ __raw_writel(
+ BF_PXP_CTRL2_ENABLE (0) |
+ BF_PXP_CTRL2_ROTATE0 (0) |
+ BF_PXP_CTRL2_HFLIP0 (0) |
+ BF_PXP_CTRL2_VFLIP0 (0) |
+ BF_PXP_CTRL2_ROTATE1 (0) |
+ BF_PXP_CTRL2_HFLIP1 (0) |
+ BF_PXP_CTRL2_VFLIP1 (0) |
+ BF_PXP_CTRL2_ENABLE_DITHER (0) |
+ BF_PXP_CTRL2_BLOCK_SIZE (0) |
+ BF_PXP_CTRL2_ENABLE_CSC2 (0) |
+ BF_PXP_CTRL2_ENABLE_LUT (0) |
+ BF_PXP_CTRL2_ENABLE_ROTATE0 (0) |
+ BF_PXP_CTRL2_ENABLE_ROTATE1 (0),
+ pxp->base + HW_PXP_CTRL2);
+
+ dump_pxp_reg2(pxp);
+}
+
+static int pxp_dma_init(struct pxps *pxp)
+{
+ struct pxp_dma *pxp_dma = &pxp->pxp_dma;
+ struct dma_device *dma = &pxp_dma->dma;
+ int i;
+
+ dma_cap_set(DMA_SLAVE, dma->cap_mask);
+ dma_cap_set(DMA_PRIVATE, dma->cap_mask);
+
+ /* Compulsory common fields */
+ dma->dev = pxp->dev;
+ dma->device_alloc_chan_resources = pxp_alloc_chan_resources;
+ dma->device_free_chan_resources = pxp_free_chan_resources;
+ dma->device_tx_status = pxp_tx_status;
+ dma->device_issue_pending = pxp_issue_pending;
+
+ /* Compulsory for DMA_SLAVE fields */
+ dma->device_prep_slave_sg = pxp_prep_slave_sg;
+ dma->device_terminate_all = pxp_device_terminate_all;
+
+ /* Initialize PxP Channels */
+ INIT_LIST_HEAD(&dma->channels);
+ for (i = 0; i < NR_PXP_VIRT_CHANNEL; i++) {
+ struct pxp_channel *pxp_chan = pxp->channel + i;
+ struct dma_chan *dma_chan = &pxp_chan->dma_chan;
+
+ spin_lock_init(&pxp_chan->lock);
+
+ /* Only one EOF IRQ for PxP, shared by all channels */
+ pxp_chan->eof_irq = pxp->irq;
+ pxp_chan->status = PXP_CHANNEL_FREE;
+ pxp_chan->completed = -ENXIO;
+ snprintf(pxp_chan->eof_name, sizeof(pxp_chan->eof_name),
+ "PXP EOF %d", i);
+
+ dma_chan->device = &pxp_dma->dma;
+ dma_chan->cookie = 1;
+ dma_chan->chan_id = i;
+ list_add_tail(&dma_chan->device_node, &dma->channels);
+ }
+
+ return dma_async_device_register(&pxp_dma->dma);
+}
+
+static ssize_t clk_off_timeout_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ return sprintf(buf, "%d\n", timeout_in_ms);
+}
+
+static ssize_t clk_off_timeout_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int val;
+ if (sscanf(buf, "%d", &val) > 0) {
+ timeout_in_ms = val;
+ return count;
+ }
+ return -EINVAL;
+}
+
+static DEVICE_ATTR(clk_off_timeout, 0644, clk_off_timeout_show,
+ clk_off_timeout_store);
+
+static ssize_t block_size_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ return sprintf(buf, "%d\n", block_size);
+}
+
+static ssize_t block_size_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ char **last = NULL;
+
+ block_size = simple_strtoul(buf, last, 0);
+ if (block_size > 1)
+ block_size = 1;
+
+ return count;
+}
+static DEVICE_ATTR(block_size, S_IWUSR | S_IRUGO,
+ block_size_show, block_size_store);
+
+static struct platform_device_id imx_pxpdma_devtype[] = {
+ {
+ .name = "imx7d-pxp-dma",
+ .driver_data = PXP_V3,
+ }, {
+ .name = "imx6ull-pxp-dma",
+ .driver_data = PXP_V3P,
+ }, {
+ /* sentinel */
+ }
+};
+MODULE_DEVICE_TABLE(platform, imx_pxpdma_devtype);
+
+static const struct of_device_id imx_pxpdma_dt_ids[] = {
+ { .compatible = "fsl,imx7d-pxp-dma", .data = &imx_pxpdma_devtype[0], },
+ { .compatible = "fsl,imx6ull-pxp-dma", .data = &imx_pxpdma_devtype[1], },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, imx_pxpdma_dt_ids);
+
+static int has_pending_task(struct pxps *pxp, struct pxp_channel *task)
+{
+ int found;
+ unsigned long flags;
+
+ spin_lock_irqsave(&pxp->lock, flags);
+ found = !list_empty(&head);
+ spin_unlock_irqrestore(&pxp->lock, flags);
+
+ return found;
+}
+
+static int pxp_dispatch_thread(void *argv)
+{
+ struct pxps *pxp = (struct pxps *)argv;
+ struct pxp_channel *pending = NULL;
+ unsigned long flags;
+
+ set_freezable();
+
+ while (!kthread_should_stop()) {
+ int ret;
+ ret = wait_event_freezable(pxp->thread_waitq,
+ has_pending_task(pxp, pending) ||
+ kthread_should_stop());
+ if (ret < 0)
+ continue;
+
+ if (kthread_should_stop())
+ break;
+
+ spin_lock_irqsave(&pxp->lock, flags);
+ pxp->pxp_ongoing = 1;
+ spin_unlock_irqrestore(&pxp->lock, flags);
+ init_completion(&pxp->complete);
+ ret = pxpdma_dostart_work(pxp);
+ if (ret) {
+ pxp->pxp_ongoing = 0;
+ continue;
+ }
+ ret = wait_for_completion_timeout(&pxp->complete, 2 * HZ);
+ if (ret == 0) {
+ printk(KERN_EMERG "%s: task is timeout\n\n", __func__);
+ break;
+ }
+ if (pxp->devdata && pxp->devdata->pxp_lut_cleanup_multiple)
+ pxp->devdata->pxp_lut_cleanup_multiple(pxp, 0, 0);
+ }
+
+ return 0;
+}
+
+static int pxp_init_interrupt(struct platform_device *pdev)
+{
+ int legacy_irq, std_irq, err;
+ struct pxps *pxp = platform_get_drvdata(pdev);
+
+ legacy_irq = platform_get_irq(pdev, 0);
+ if (legacy_irq < 0) {
+ dev_err(&pdev->dev, "failed to get pxp legacy irq: %d\n",
+ legacy_irq);
+ return legacy_irq;
+ }
+
+ std_irq = platform_get_irq(pdev, 1);
+ if (std_irq < 0) {
+ dev_err(&pdev->dev, "failed to get pxp standard irq: %d\n",
+ std_irq);
+ return std_irq;
+ }
+
+ err = devm_request_irq(&pdev->dev, legacy_irq, pxp_irq, 0,
+ "pxp-dmaengine-legacy", pxp);
+ if (err) {
+ dev_err(&pdev->dev, "Request pxp legacy irq failed: %d\n", err);
+ return err;
+ }
+
+ err = devm_request_irq(&pdev->dev, std_irq, pxp_irq, 0,
+ "pxp-dmaengine-std", pxp);
+ if (err) {
+ dev_err(&pdev->dev, "Request pxp standard irq failed: %d\n", err);
+ return err;
+ }
+
+ pxp->irq = legacy_irq;
+
+ /* enable all the possible irq raised by PXP */
+ __raw_writel(0xffff, pxp->base + HW_PXP_IRQ_MASK);
+
+ return 0;
+}
+
+static int pxp_create_attrs(struct platform_device *pdev)
+{
+ int ret = 0;
+
+ if ((ret = device_create_file(&pdev->dev, &dev_attr_clk_off_timeout))) {
+ dev_err(&pdev->dev,
+ "Unable to create file from clk_off_timeout\n");
+ return ret;
+ }
+
+ if ((ret = device_create_file(&pdev->dev, &dev_attr_block_size))) {
+ device_remove_file(&pdev->dev, &dev_attr_clk_off_timeout);
+
+ dev_err(&pdev->dev,
+ "Unable to create file from block_size\n");
+ return ret;
+ }
+
+ return 0;
+}
+
+static void pxp_remove_attrs(struct platform_device *pdev)
+{
+ device_remove_file(&pdev->dev, &dev_attr_clk_off_timeout);
+ device_remove_file(&pdev->dev, &dev_attr_block_size);
+}
+
+static void pxp_init_timer(struct pxps *pxp)
+{
+ INIT_WORK(&pxp->work, clkoff_callback);
+
+ init_timer(&pxp->clk_timer);
+ pxp->clk_timer.function = pxp_clkoff_timer;
+ pxp->clk_timer.data = (unsigned long)pxp;
+}
+
+static bool is_mux_node(uint32_t node_id)
+{
+ if ((node_id < PXP_2D_MUX_MUX0) ||
+ (node_id > PXP_2D_MUX_MUX15))
+ return false;
+
+ return true;
+}
+
+static bool search_mux_chain(uint32_t mux_id,
+ struct edge_node *enode)
+{
+ bool found = false;
+ uint32_t i, j, next_mux = 0;
+ uint32_t output;
+ struct mux *muxes;
+
+ muxes = (v3p_flag) ? muxes_v3p : muxes_v3;
+
+ for (i = 0; i < 2; i++) {
+ output = muxes[mux_id].mux_outputs[i];
+ if (output == 0xff)
+ break;
+
+ if ((output == enode->adjvex)) {
+ /* found */
+ found = true;
+ break;
+ } else if (is_mux_node(output)) {
+ next_mux = output - PXP_2D_MUX_BASE;
+ found = search_mux_chain(next_mux, enode);
+
+ if (found) {
+ for (j = 0; j < 4; j++) {
+ if (muxes[next_mux].mux_inputs[j] ==
+ (mux_id + PXP_2D_MUX_BASE))
+ break;
+ }
+
+ set_bit(next_mux, (unsigned long *)&enode->mux_used);
+ set_mux_val(&enode->muxes, next_mux, j);
+ break;
+ }
+ }
+ }
+
+ return found;
+}
+
+static void enode_mux_config(unsigned int vnode_id,
+ struct edge_node *enode)
+{
+ uint32_t i, j;
+ bool via_mux = false, need_search = false;
+ struct mux *muxes;
+
+ BUG_ON(vnode_id >= PXP_2D_NUM);
+ BUG_ON(enode->adjvex >= PXP_2D_NUM);
+
+ muxes = (v3p_flag) ? muxes_v3p : muxes_v3;
+
+ for (i = 0; i < 16; i++) {
+ for (j = 0; j < 4; j++) {
+ if (muxes[i].mux_inputs[j] == 0xff)
+ break;
+
+ if (muxes[i].mux_inputs[j] == vnode_id)
+ need_search = true;
+ else if (muxes[i].mux_inputs[j] == PXP_2D_ALPHA0_S0_S1) {
+ if ((vnode_id == PXP_2D_ALPHA0_S0) ||
+ (vnode_id == PXP_2D_ALPHA0_S1))
+ need_search = true;
+ } else if (muxes[i].mux_inputs[j] == PXP_2D_ALPHA1_S0_S1) {
+ if ((vnode_id == PXP_2D_ALPHA1_S0) ||
+ (vnode_id == PXP_2D_ALPHA1_S1))
+ need_search = true;
+ }
+
+ if (need_search) {
+ via_mux = search_mux_chain(i, enode);
+ need_search = false;
+ break;
+ }
+ }
+
+ if (via_mux) {
+ set_bit(i, (unsigned long *)&enode->mux_used);
+ set_mux_val(&enode->muxes, i, j);
+ break;
+ }
+ }
+}
+
+static int pxp_create_initial_graph(struct platform_device *pdev)
+{
+ int i, j, first;
+ static bool (*adj_array)[PXP_2D_NUM];
+ struct edge_node *enode, *curr = NULL;
+
+ adj_array = (v3p_flag) ? adj_array_v3p : adj_array_v3;
+
+ for (i = 0; i < PXP_2D_NUM; i++) {
+ switch (i) {
+ case PXP_2D_PS:
+ case PXP_2D_AS:
+ case PXP_2D_INPUT_FETCH0:
+ case PXP_2D_INPUT_FETCH1:
+ adj_list[i].type = PXP_2D_TYPE_INPUT;
+ break;
+ case PXP_2D_OUT:
+ case PXP_2D_INPUT_STORE0:
+ case PXP_2D_INPUT_STORE1:
+ adj_list[i].type = PXP_2D_TYPE_OUTPUT;
+ break;
+ default:
+ adj_list[i].type = PXP_2D_TYPE_ALU;
+ break;
+ }
+
+ first = -1;
+
+ for (j = 0; j < PXP_2D_NUM; j++) {
+ if (adj_array[i][j]) {
+ enode = kmem_cache_alloc(edge_node_cache,
+ GFP_KERNEL | __GFP_ZERO);
+ if (!enode) {
+ dev_err(&pdev->dev, "allocate edge node failed\n");
+ return -ENOMEM;
+ }
+ enode->adjvex = j;
+ enode->prev_vnode = i;
+
+ if (unlikely(first == -1)) {
+ first = j;
+ adj_list[i].first = enode;
+ } else
+ curr->next = enode;
+
+ curr = enode;
+ enode_mux_config(i, enode);
+ dev_dbg(&pdev->dev, "(%d -> %d): mux_used 0x%x, mux_config 0x%x\n\n",
+ i, j, enode->mux_used, *(unsigned int*)&enode->muxes);
+ }
+ }
+ }
+
+ return 0;
+}
+
+/* Calculate the shortest paths start via
+ * 'from' node to other nodes
+ */
+static void pxp_find_shortest_path(unsigned int from)
+{
+ int i;
+ struct edge_node *enode;
+ struct path_node *pnode, *adjnode;
+ struct list_head queue;
+
+ INIT_LIST_HEAD(&queue);
+ list_add_tail(&path_table[from][from].node, &queue);
+
+ while(!list_empty(&queue)) {
+ pnode = list_entry(queue.next, struct path_node, node);
+ enode = adj_list[pnode->id].first;
+ while (enode) {
+ adjnode = &path_table[from][enode->adjvex];
+
+ if (adjnode->distance == DISTANCE_INFINITY) {
+ adjnode->distance = pnode->distance + 1;
+ adjnode->prev_node = pnode->id;
+ list_add_tail(&adjnode->node, &queue);
+ }
+
+ enode = enode->next;
+ }
+ list_del_init(&pnode->node);
+ }
+
+ for (i = 0; i < PXP_2D_NUM; i++)
+ pr_debug("From %u: to %d (id = %d, distance = 0x%x, prev_node = %d\n",
+ from, i, path_table[from][i].id, path_table[from][i].distance,
+ path_table[from][i].prev_node);
+}
+
+static int pxp_gen_shortest_paths(struct platform_device *pdev)
+{
+ int i, j;
+
+ for (i = 0; i < PXP_2D_NUM; i++) {
+ for (j = 0; j < PXP_2D_NUM; j++) {
+ path_table[i][j].id = j;
+ path_table[i][j].distance = DISTANCE_INFINITY;
+ path_table[i][j].prev_node = NO_PATH_NODE;
+ INIT_LIST_HEAD(&path_table[i][j].node);
+ }
+
+ path_table[i][i].distance = 0;
+
+ pxp_find_shortest_path(i);
+ }
+
+ return 0;
+}
+
+#ifdef CONFIG_MXC_FPGA_M4_TEST
+static void pxp_config_m4(struct platform_device *pdev)
+{
+ fpga_tcml_base = ioremap(FPGA_TCML_ADDR, SZ_32K);
+ if (fpga_tcml_base == NULL) {
+ dev_err(&pdev->dev,
+ "get fpga_tcml_base error.\n");
+ goto exit;
+ }
+ pinctrl_base = ioremap(PINCTRL, SZ_4K);
+ if (pinctrl_base == NULL) {
+ dev_err(&pdev->dev,
+ "get fpga_tcml_base error.\n");
+ goto exit;
+ }
+
+ __raw_writel(0xC0000000, pinctrl_base + 0x08);
+ __raw_writel(0x3, pinctrl_base + PIN_DOUT);
+ int i;
+ for (i = 0; i < 1024 * 32 / 4; i++) {
+ *(((unsigned int *)(fpga_tcml_base)) + i) = cm4_image[i];
+ }
+}
+#endif
+
+static int pxp_probe(struct platform_device *pdev)
+{
+ const struct of_device_id *of_id =
+ of_match_device(imx_pxpdma_dt_ids, &pdev->dev);
+ struct pxps *pxp;
+ struct resource *res;
+ int err = 0;
+
+ if (of_id)
+ pdev->id_entry = of_id->data;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+
+ pxp = devm_kzalloc(&pdev->dev, sizeof(*pxp), GFP_KERNEL);
+ if (!pxp) {
+ dev_err(&pdev->dev, "failed to allocate control object\n");
+ err = -ENOMEM;
+ goto exit;
+ }
+
+ pxp->dev = &pdev->dev;
+
+ platform_set_drvdata(pdev, pxp);
+
+ spin_lock_init(&pxp->lock);
+ mutex_init(&pxp->clk_mutex);
+
+ pxp->base = devm_ioremap_resource(&pdev->dev, res);
+ if (pxp->base == NULL) {
+ dev_err(&pdev->dev, "Couldn't ioremap regs\n");
+ err = -ENODEV;
+ goto exit;
+ }
+ pxp_reg_base = pxp->base;
+
+ pxp->pdev = pdev;
+ pxp->devdata = &pxp_devdata[pdev->id_entry->driver_data];
+
+ v3p_flag = (pxp_is_v3p(pxp)) ? true : false;
+
+ pxp->ipg_clk = devm_clk_get(&pdev->dev, "pxp_ipg");
+ pxp->axi_clk = devm_clk_get(&pdev->dev, "pxp_axi");
+
+ if (IS_ERR(pxp->ipg_clk) || IS_ERR(pxp->axi_clk)) {
+ dev_err(&pdev->dev, "pxp clocks invalid\n");
+ err = -EINVAL;
+ goto exit;
+ }
+
+ pxp_soft_reset(pxp);
+ pxp_writel(0x0, HW_PXP_CTRL);
+ /* Initialize DMA engine */
+ err = pxp_dma_init(pxp);
+ if (err < 0)
+ goto exit;
+
+ pxp_clk_enable(pxp);
+ pxp_soft_reset(pxp);
+
+ /* Initialize PXP Interrupt */
+ err = pxp_init_interrupt(pdev);
+ if (err < 0)
+ goto exit;
+
+ if (pxp->devdata && pxp->devdata->pxp_data_path_config)
+ pxp->devdata->pxp_data_path_config(pxp);
+
+ dump_pxp_reg(pxp);
+ pxp_clk_disable(pxp);
+
+ pxp_init_timer(pxp);
+
+ init_waitqueue_head(&pxp->thread_waitq);
+ /* allocate a kernel thread to dispatch pxp conf */
+ pxp->dispatch = kthread_run(pxp_dispatch_thread, pxp, "pxp_dispatch");
+ if (IS_ERR(pxp->dispatch)) {
+ err = PTR_ERR(pxp->dispatch);
+ goto exit;
+ }
+ tx_desc_cache = kmem_cache_create("tx_desc", sizeof(struct pxp_tx_desc),
+ 0, SLAB_HWCACHE_ALIGN, NULL);
+ if (!tx_desc_cache) {
+ err = -ENOMEM;
+ goto exit;
+ }
+
+ edge_node_cache = kmem_cache_create("edge_node", sizeof(struct edge_node),
+ 0, SLAB_HWCACHE_ALIGN, NULL);
+ if (!edge_node_cache) {
+ err = -ENOMEM;
+ kmem_cache_destroy(tx_desc_cache);
+ goto exit;
+ }
+
+ err = pxp_create_attrs(pdev);
+ if (err) {
+ kmem_cache_destroy(tx_desc_cache);
+ kmem_cache_destroy(edge_node_cache);
+ goto exit;
+ }
+
+ if ((err = pxp_create_initial_graph(pdev))) {
+ kmem_cache_destroy(tx_desc_cache);
+ kmem_cache_destroy(edge_node_cache);
+ goto exit;
+ }
+
+ pxp_gen_shortest_paths(pdev);
+
+#ifdef CONFIG_MXC_FPGA_M4_TEST
+ pxp_config_m4(pdev);
+#endif
+ register_pxp_device();
+ pm_runtime_enable(pxp->dev);
+
+ dma_alloc_coherent(NULL, PAGE_ALIGN(1920 * 1088 * 4),
+ &paddr, GFP_KERNEL);
+
+exit:
+ if (err)
+ dev_err(&pdev->dev, "Exiting (unsuccessfully) pxp_probe()\n");
+ return err;
+}
+
+static int pxp_remove(struct platform_device *pdev)
+{
+ struct pxps *pxp = platform_get_drvdata(pdev);
+
+ unregister_pxp_device();
+ kmem_cache_destroy(tx_desc_cache);
+ kmem_cache_destroy(edge_node_cache);
+ kthread_stop(pxp->dispatch);
+ cancel_work_sync(&pxp->work);
+ del_timer_sync(&pxp->clk_timer);
+ clk_disable_unprepare(pxp->ipg_clk);
+ clk_disable_unprepare(pxp->axi_clk);
+ pxp_remove_attrs(pdev);
+ dma_async_device_unregister(&(pxp->pxp_dma.dma));
+
+ return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int pxp_suspend(struct device *dev)
+{
+ struct pxps *pxp = dev_get_drvdata(dev);
+
+ pxp_clk_enable(pxp);
+ while (__raw_readl(pxp->base + HW_PXP_CTRL) & BM_PXP_CTRL_ENABLE)
+ ;
+
+ __raw_writel(BM_PXP_CTRL_SFTRST, pxp->base + HW_PXP_CTRL);
+ pxp_clk_disable(pxp);
+
+ return 0;
+}
+
+static int pxp_resume(struct device *dev)
+{
+ struct pxps *pxp = dev_get_drvdata(dev);
+
+ pxp_clk_enable(pxp);
+ /* Pull PxP out of reset */
+ pxp_soft_reset(pxp);
+ if (pxp->devdata && pxp->devdata->pxp_data_path_config)
+ pxp->devdata->pxp_data_path_config(pxp);
+ /* enable all the possible irq raised by PXP */
+ __raw_writel(0xffff, pxp->base + HW_PXP_IRQ_MASK);
+ pxp_clk_disable(pxp);
+
+ return 0;
+}
+#else
+#define pxp_suspend NULL
+#define pxp_resume NULL
+#endif
+
+#ifdef CONFIG_PM
+static int pxp_runtime_suspend(struct device *dev)
+{
+ dev_dbg(dev, "pxp busfreq high release.\n");
+
+ return 0;
+}
+
+static int pxp_runtime_resume(struct device *dev)
+{
+ dev_dbg(dev, "pxp busfreq high request.\n");
+
+ return 0;
+}
+#else
+#define pxp_runtime_suspend NULL
+#define pxp_runtime_resume NULL
+#endif
+
+static const struct dev_pm_ops pxp_pm_ops = {
+ SET_RUNTIME_PM_OPS(pxp_runtime_suspend, pxp_runtime_resume, NULL)
+ SET_SYSTEM_SLEEP_PM_OPS(pxp_suspend, pxp_resume)
+};
+
+static struct platform_driver pxp_driver = {
+ .driver = {
+ .name = "imx-pxp-v3",
+ .of_match_table = of_match_ptr(imx_pxpdma_dt_ids),
+ .pm = &pxp_pm_ops,
+ },
+ .probe = pxp_probe,
+ .remove = pxp_remove,
+};
+
+static int __init pxp_init(void)
+{
+ return platform_driver_register(&pxp_driver);
+}
+late_initcall(pxp_init);
+
+static void __exit pxp_exit(void)
+{
+ platform_driver_unregister(&pxp_driver);
+}
+module_exit(pxp_exit);
+
+
+MODULE_DESCRIPTION("i.MX PxP driver");
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_LICENSE("GPL");
diff --git a/drivers/dma/pxp/reg_bitfields.h b/drivers/dma/pxp/reg_bitfields.h
new file mode 100644
index 000000000000..95b5c83b4b15
--- /dev/null
+++ b/drivers/dma/pxp/reg_bitfields.h
@@ -0,0 +1,280 @@
+/*
+ * Copyright (C) 2010-2016 Freescale Semiconductor, Inc.
+ * Copyright 2017 NXP
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef _REG_BITFIELDS_H
+#define _REG_BITFIELDS_H
+struct mux_config {
+ uint32_t mux0_sel : 2;
+ uint32_t mux1_sel : 2;
+ uint32_t mux2_sel : 2;
+ uint32_t mux3_sel : 2;
+ uint32_t mux4_sel : 2;
+ uint32_t mux5_sel : 2;
+ uint32_t mux6_sel : 2;
+ uint32_t mux7_sel : 2;
+ uint32_t mux8_sel : 2;
+ uint32_t mux9_sel : 2;
+ uint32_t mux10_sel : 2;
+ uint32_t mux11_sel : 2;
+ uint32_t mux12_sel : 2;
+ uint32_t mux13_sel : 2;
+ uint32_t mux14_sel : 2;
+ uint32_t mux15_sel : 2;
+};
+
+/* legacy engine registers */
+struct ps_ctrl {
+ uint32_t format : 6;
+ uint32_t wb_swap : 1;
+ uint32_t rsvd0 : 1;
+ uint32_t decy : 2;
+ uint32_t decx : 2;
+ uint32_t rsvd1 : 20;
+};
+
+struct ps_scale {
+ uint32_t xscale : 15;
+ uint32_t rsvd1 : 1;
+ uint32_t yscale : 15;
+ uint32_t rsvd2 : 1;
+};
+
+struct ps_offset {
+ uint32_t xoffset : 12;
+ uint32_t rsvd1 : 4;
+ uint32_t yoffset : 12;
+ uint32_t rsvd2 : 4;
+};
+
+struct as_ctrl {
+ uint32_t rsvd0 : 1;
+ uint32_t alpha_ctrl : 2;
+ uint32_t enable_colorkey : 1;
+ uint32_t format : 4;
+ uint32_t alpha : 8;
+ uint32_t rop : 4;
+ uint32_t alpha0_invert : 1;
+ uint32_t alpha1_invert : 1;
+ uint32_t rsvd1 : 10;
+};
+
+struct out_ctrl {
+ uint32_t format : 5;
+ uint32_t rsvd0 : 3;
+ uint32_t interlaced_output : 2;
+ uint32_t rsvd1 : 13;
+ uint32_t alpha_output : 1;
+ uint32_t alpha : 8;
+};
+
+struct coordinate {
+ uint32_t y : 14;
+ uint32_t rsvd0 : 2;
+ uint32_t x : 14;
+ uint32_t rsvd1 : 2;
+};
+
+struct pxp_alpha_ctrl {
+ uint32_t poter_duff_enable : 1;
+ uint32_t s0_s1_factor_mode : 2;
+ uint32_t s0_global_alpha_mode : 2;
+ uint32_t s0_alpha_mode : 1;
+ uint32_t s0_color_mode : 1;
+ uint32_t rsvd1 : 1;
+ uint32_t s1_s0_factor_mode : 2;
+ uint32_t s1_global_alpha_mode : 2;
+ uint32_t s1_alpha_mode : 1;
+ uint32_t s1_color_mode : 1;
+ uint32_t rsvd0 : 2;
+ uint32_t s0_global_alpha : 8;
+ uint32_t s1_global_alpha : 8;
+};
+
+/* store engine registers */
+struct store_ctrl {
+ uint32_t ch_en : 1;
+ uint32_t block_en : 1;
+ uint32_t block_16 : 1;
+ uint32_t handshake_en : 1;
+ uint32_t array_en : 1;
+ uint32_t array_line_num : 2;
+ uint32_t rsvd3 : 1;
+ uint32_t store_bypass_en : 1;
+ uint32_t store_memory_en : 1;
+ uint32_t pack_in_sel : 1;
+ uint32_t fill_data_en : 1;
+ uint32_t rsvd2 : 4;
+ uint32_t wr_num_bytes : 2;
+ uint32_t rsvd1 : 6;
+ uint32_t combine_2channel : 1;
+ uint32_t rsvd0 : 6;
+ uint32_t arbit_en : 1;
+};
+
+struct store_size {
+ uint32_t out_width : 16;
+ uint32_t out_height : 16;
+};
+
+struct store_pitch {
+ uint32_t ch0_out_pitch : 16;
+ uint32_t ch1_out_pitch : 16;
+};
+
+struct store_shift_ctrl {
+ uint32_t rsvd2 : 2;
+ uint32_t output_active_bpp : 2;
+ uint32_t out_yuv422_1p_en : 1;
+ uint32_t out_yuv422_2p_en : 1;
+ uint32_t rsvd1 : 1;
+ uint32_t shift_bypass : 1;
+ uint32_t rsvd0 : 24;
+};
+
+struct store_d_shift {
+ uint64_t d_shift_width0 : 6;
+ uint64_t rsvd3 : 1;
+ uint64_t d_shift_flag0 : 1;
+ uint64_t d_shift_width1 : 6;
+ uint64_t rsvd2 : 1;
+ uint64_t d_shift_flag1 : 1;
+ uint64_t d_shift_width2 : 6;
+ uint64_t rsvd1 : 1;
+ uint64_t d_shift_flag2 : 1;
+ uint64_t d_shift_width3 : 6;
+ uint64_t rsvd0 : 1;
+ uint64_t d_shift_flag3 : 1;
+
+ uint64_t d_shift_width4 : 6;
+ uint64_t rsvd7 : 1;
+ uint64_t d_shift_flag4 : 1;
+ uint64_t d_shift_width5 : 6;
+ uint64_t rsvd6 : 1;
+ uint64_t d_shift_flag5 : 1;
+ uint64_t d_shift_width6 : 6;
+ uint64_t rsvd5 : 1;
+ uint64_t d_shift_flag6 : 1;
+ uint64_t d_shift_width7 : 6;
+ uint64_t rsvd4 : 1;
+ uint64_t d_shift_flag7 : 1;
+};
+
+struct store_f_shift {
+ uint64_t f_shift_width0 : 6;
+ uint64_t rsvd3 : 1;
+ uint64_t f_shift_flag0 : 1;
+ uint64_t f_shift_width1 : 6;
+ uint64_t rsvd2 : 1;
+ uint64_t f_shift_flag1 : 1;
+ uint64_t f_shift_width2 : 6;
+ uint64_t rsvd1 : 1;
+ uint64_t f_shift_flag2 : 1;
+ uint64_t f_shift_width3 : 6;
+ uint64_t rsvd0 : 1;
+ uint64_t f_shift_flag3 : 1;
+
+ uint64_t f_shift_width4 : 6;
+ uint64_t rsvd7 : 1;
+ uint64_t f_shift_flag4 : 1;
+ uint64_t f_shift_width5 : 6;
+ uint64_t rsvd6 : 1;
+ uint64_t f_shift_flag5 : 1;
+ uint64_t f_shift_width6 : 6;
+ uint64_t rsvd5 : 1;
+ uint64_t f_shift_flag6 : 1;
+ uint64_t f_shift_width7 : 6;
+ uint64_t rsvd4 : 1;
+ uint64_t f_shift_flag7 : 1;
+};
+
+struct store_d_mask {
+ uint64_t d_mask_l : 32;
+ uint64_t d_mask_h : 32;
+};
+
+/* fetch engine registers */
+struct fetch_ctrl {
+ uint32_t ch_en : 1;
+ uint32_t block_en : 1;
+ uint32_t block_16 : 1;
+ uint32_t handshake_en : 1;
+ uint32_t bypass_pixel_en : 1;
+ uint32_t high_byte : 1;
+ uint32_t rsvd4 : 3;
+ uint32_t hflip : 1;
+ uint32_t vflip : 1;
+ uint32_t rsvd3 : 1;
+ uint32_t rotation_angle : 2;
+ uint32_t rsvd2 : 2;
+ uint32_t rd_num_bytes : 2;
+ uint32_t rsvd1 : 6;
+ uint32_t handshake_scan_line_num : 2;
+ uint32_t rsvd0 : 5;
+ uint32_t arbit_en : 1;
+};
+
+struct fetch_active_size_ulc {
+ uint32_t active_size_ulc_x : 16;
+ uint32_t active_size_ulc_y : 16;
+};
+
+struct fetch_active_size_lrc {
+ uint32_t active_size_lrc_x : 16;
+ uint32_t active_size_lrc_y : 16;
+};
+
+struct fetch_size {
+ uint32_t input_total_width : 16;
+ uint32_t input_total_height : 16;
+};
+
+struct fetch_pitch {
+ uint32_t ch0_input_pitch : 16;
+ uint32_t ch1_input_pitch : 16;
+};
+
+struct fetch_shift_ctrl {
+ uint32_t input_active_bpp : 2;
+ uint32_t rsvd1 : 6;
+ uint32_t expand_format : 3;
+ uint32_t expand_en : 1;
+ uint32_t shift_bypass : 1;
+ uint32_t rsvd0 : 19;
+};
+
+struct fetch_shift_offset {
+ uint32_t offset0 : 5;
+ uint32_t rsvd3 : 3;
+ uint32_t offset1 : 5;
+ uint32_t rsvd2 : 3;
+ uint32_t offset2 : 5;
+ uint32_t rsvd1 : 3;
+ uint32_t offset3 : 5;
+ uint32_t rsvd0 : 3;
+};
+
+struct fetch_shift_width {
+ uint32_t width0 : 4;
+ uint32_t width1 : 4;
+ uint32_t width2 : 4;
+ uint32_t width3 : 4;
+ uint32_t rsvd0 : 16;
+};
+#endif
diff --git a/drivers/dma/pxp/regs-pxp_v2.h b/drivers/dma/pxp/regs-pxp_v2.h
new file mode 100644
index 000000000000..8b20ddef3954
--- /dev/null
+++ b/drivers/dma/pxp/regs-pxp_v2.h
@@ -0,0 +1,1152 @@
+/*
+ * Freescale PXP Register Definitions
+ *
+ * Copyright (C) 2012-2013 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * This file is created by xml file. Don't Edit it.
+ *
+ * Xml Revision: 1.29
+ * Template revision: 1.3
+ */
+
+#ifndef __ARCH_ARM___PXP_H
+#define __ARCH_ARM___PXP_H
+
+#define HW_PXP_CTRL (0x00000000)
+#define HW_PXP_CTRL_SET (0x00000004)
+#define HW_PXP_CTRL_CLR (0x00000008)
+#define HW_PXP_CTRL_TOG (0x0000000c)
+
+#define BM_PXP_CTRL_SFTRST 0x80000000
+#define BM_PXP_CTRL_CLKGATE 0x40000000
+#define BM_PXP_CTRL_RSVD4 0x20000000
+#define BM_PXP_CTRL_EN_REPEAT 0x10000000
+#define BP_PXP_CTRL_RSVD3 26
+#define BM_PXP_CTRL_RSVD3 0x0C000000
+#define BF_PXP_CTRL_RSVD3(v) \
+ (((v) << 26) & BM_PXP_CTRL_RSVD3)
+#define BP_PXP_CTRL_INTERLACED_INPUT 24
+#define BM_PXP_CTRL_INTERLACED_INPUT 0x03000000
+#define BF_PXP_CTRL_INTERLACED_INPUT(v) \
+ (((v) << 24) & BM_PXP_CTRL_INTERLACED_INPUT)
+#define BV_PXP_CTRL_INTERLACED_INPUT__PROGRESSIVE 0x0
+#define BV_PXP_CTRL_INTERLACED_INPUT__FIELD0 0x2
+#define BV_PXP_CTRL_INTERLACED_INPUT__FIELD1 0x3
+#define BM_PXP_CTRL_BLOCK_SIZE 0x00800000
+#define BV_PXP_CTRL_BLOCK_SIZE__8X8 0x0
+#define BV_PXP_CTRL_BLOCK_SIZE__16X16 0x1
+#define BM_PXP_CTRL_ROT_POS 0x00400000
+#define BM_PXP_CTRL_IN_PLACE 0x00200000
+#define BP_PXP_CTRL_RSVD1 12
+#define BM_PXP_CTRL_RSVD1 0x001FF000
+#define BF_PXP_CTRL_RSVD1(v) \
+ (((v) << 12) & BM_PXP_CTRL_RSVD1)
+#define BM_PXP_CTRL_VFLIP 0x00000800
+#define BM_PXP_CTRL_HFLIP 0x00000400
+#define BP_PXP_CTRL_ROTATE 8
+#define BM_PXP_CTRL_ROTATE 0x00000300
+#define BF_PXP_CTRL_ROTATE(v) \
+ (((v) << 8) & BM_PXP_CTRL_ROTATE)
+#define BV_PXP_CTRL_ROTATE__ROT_0 0x0
+#define BV_PXP_CTRL_ROTATE__ROT_90 0x1
+#define BV_PXP_CTRL_ROTATE__ROT_180 0x2
+#define BV_PXP_CTRL_ROTATE__ROT_270 0x3
+#define BP_PXP_CTRL_RSVD0 5
+#define BM_PXP_CTRL_RSVD0 0x000000E0
+#define BF_PXP_CTRL_RSVD0(v) \
+ (((v) << 5) & BM_PXP_CTRL_RSVD0)
+#define BM_PXP_CTRL_ENABLE_LCD_HANDSHAKE 0x00000010
+#define BM_PXP_CTRL_LUT_DMA_IRQ_ENABLE 0x00000008
+#define BM_PXP_CTRL_NEXT_IRQ_ENABLE 0x00000004
+#define BM_PXP_CTRL_IRQ_ENABLE 0x00000002
+#define BM_PXP_CTRL_ENABLE 0x00000001
+
+#define HW_PXP_STAT (0x00000010)
+#define HW_PXP_STAT_SET (0x00000014)
+#define HW_PXP_STAT_CLR (0x00000018)
+#define HW_PXP_STAT_TOG (0x0000001c)
+
+#define BP_PXP_STAT_BLOCKX 24
+#define BM_PXP_STAT_BLOCKX 0xFF000000
+#define BF_PXP_STAT_BLOCKX(v) \
+ (((v) << 24) & BM_PXP_STAT_BLOCKX)
+#define BP_PXP_STAT_BLOCKY 16
+#define BM_PXP_STAT_BLOCKY 0x00FF0000
+#define BF_PXP_STAT_BLOCKY(v) \
+ (((v) << 16) & BM_PXP_STAT_BLOCKY)
+#define BP_PXP_STAT_RSVD2 9
+#define BM_PXP_STAT_RSVD2 0x0000FE00
+#define BF_PXP_STAT_RSVD2(v) \
+ (((v) << 9) & BM_PXP_STAT_RSVD2)
+#define BM_PXP_STAT_LUT_DMA_LOAD_DONE_IRQ 0x00000100
+#define BP_PXP_STAT_AXI_ERROR_ID 4
+#define BM_PXP_STAT_AXI_ERROR_ID 0x000000F0
+#define BF_PXP_STAT_AXI_ERROR_ID(v) \
+ (((v) << 4) & BM_PXP_STAT_AXI_ERROR_ID)
+#define BM_PXP_STAT_NEXT_IRQ 0x00000008
+#define BM_PXP_STAT_AXI_READ_ERROR 0x00000004
+#define BM_PXP_STAT_AXI_WRITE_ERROR 0x00000002
+#define BM_PXP_STAT_IRQ 0x00000001
+
+#define HW_PXP_OUT_CTRL (0x00000020)
+#define HW_PXP_OUT_CTRL_SET (0x00000024)
+#define HW_PXP_OUT_CTRL_CLR (0x00000028)
+#define HW_PXP_OUT_CTRL_TOG (0x0000002c)
+
+#define BP_PXP_OUT_CTRL_ALPHA 24
+#define BM_PXP_OUT_CTRL_ALPHA 0xFF000000
+#define BF_PXP_OUT_CTRL_ALPHA(v) \
+ (((v) << 24) & BM_PXP_OUT_CTRL_ALPHA)
+#define BM_PXP_OUT_CTRL_ALPHA_OUTPUT 0x00800000
+#define BP_PXP_OUT_CTRL_RSVD1 10
+#define BM_PXP_OUT_CTRL_RSVD1 0x007FFC00
+#define BF_PXP_OUT_CTRL_RSVD1(v) \
+ (((v) << 10) & BM_PXP_OUT_CTRL_RSVD1)
+#define BP_PXP_OUT_CTRL_INTERLACED_OUTPUT 8
+#define BM_PXP_OUT_CTRL_INTERLACED_OUTPUT 0x00000300
+#define BF_PXP_OUT_CTRL_INTERLACED_OUTPUT(v) \
+ (((v) << 8) & BM_PXP_OUT_CTRL_INTERLACED_OUTPUT)
+#define BV_PXP_OUT_CTRL_INTERLACED_OUTPUT__PROGRESSIVE 0x0
+#define BV_PXP_OUT_CTRL_INTERLACED_OUTPUT__FIELD0 0x1
+#define BV_PXP_OUT_CTRL_INTERLACED_OUTPUT__FIELD1 0x2
+#define BV_PXP_OUT_CTRL_INTERLACED_OUTPUT__INTERLACED 0x3
+#define BP_PXP_OUT_CTRL_RSVD0 5
+#define BM_PXP_OUT_CTRL_RSVD0 0x000000E0
+#define BF_PXP_OUT_CTRL_RSVD0(v) \
+ (((v) << 5) & BM_PXP_OUT_CTRL_RSVD0)
+#define BP_PXP_OUT_CTRL_FORMAT 0
+#define BM_PXP_OUT_CTRL_FORMAT 0x0000001F
+#define BF_PXP_OUT_CTRL_FORMAT(v) \
+ (((v) << 0) & BM_PXP_OUT_CTRL_FORMAT)
+#define BV_PXP_OUT_CTRL_FORMAT__ARGB8888 0x0
+#define BV_PXP_OUT_CTRL_FORMAT__RGB888 0x4
+#define BV_PXP_OUT_CTRL_FORMAT__RGB888P 0x5
+#define BV_PXP_OUT_CTRL_FORMAT__ARGB1555 0x8
+#define BV_PXP_OUT_CTRL_FORMAT__ARGB4444 0x9
+#define BV_PXP_OUT_CTRL_FORMAT__RGB555 0xC
+#define BV_PXP_OUT_CTRL_FORMAT__RGB444 0xD
+#define BV_PXP_OUT_CTRL_FORMAT__RGB565 0xE
+#define BV_PXP_OUT_CTRL_FORMAT__YUV1P444 0x10
+#define BV_PXP_OUT_CTRL_FORMAT__UYVY1P422 0x12
+#define BV_PXP_OUT_CTRL_FORMAT__VYUY1P422 0x13
+#define BV_PXP_OUT_CTRL_FORMAT__Y8 0x14
+#define BV_PXP_OUT_CTRL_FORMAT__Y4 0x15
+#define BV_PXP_OUT_CTRL_FORMAT__YUV2P422 0x18
+#define BV_PXP_OUT_CTRL_FORMAT__YUV2P420 0x19
+#define BV_PXP_OUT_CTRL_FORMAT__YVU2P422 0x1A
+#define BV_PXP_OUT_CTRL_FORMAT__YVU2P420 0x1B
+
+#define HW_PXP_OUT_BUF (0x00000030)
+
+#define BP_PXP_OUT_BUF_ADDR 0
+#define BM_PXP_OUT_BUF_ADDR 0xFFFFFFFF
+#define BF_PXP_OUT_BUF_ADDR(v) (v)
+
+#define HW_PXP_OUT_BUF2 (0x00000040)
+
+#define BP_PXP_OUT_BUF2_ADDR 0
+#define BM_PXP_OUT_BUF2_ADDR 0xFFFFFFFF
+#define BF_PXP_OUT_BUF2_ADDR(v) (v)
+
+#define HW_PXP_OUT_PITCH (0x00000050)
+
+#define BP_PXP_OUT_PITCH_RSVD 16
+#define BM_PXP_OUT_PITCH_RSVD 0xFFFF0000
+#define BF_PXP_OUT_PITCH_RSVD(v) \
+ (((v) << 16) & BM_PXP_OUT_PITCH_RSVD)
+#define BP_PXP_OUT_PITCH_PITCH 0
+#define BM_PXP_OUT_PITCH_PITCH 0x0000FFFF
+#define BF_PXP_OUT_PITCH_PITCH(v) \
+ (((v) << 0) & BM_PXP_OUT_PITCH_PITCH)
+
+#define HW_PXP_OUT_LRC (0x00000060)
+
+#define BP_PXP_OUT_LRC_RSVD1 30
+#define BM_PXP_OUT_LRC_RSVD1 0xC0000000
+#define BF_PXP_OUT_LRC_RSVD1(v) \
+ (((v) << 30) & BM_PXP_OUT_LRC_RSVD1)
+#define BP_PXP_OUT_LRC_X 16
+#define BM_PXP_OUT_LRC_X 0x3FFF0000
+#define BF_PXP_OUT_LRC_X(v) \
+ (((v) << 16) & BM_PXP_OUT_LRC_X)
+#define BP_PXP_OUT_LRC_RSVD0 14
+#define BM_PXP_OUT_LRC_RSVD0 0x0000C000
+#define BF_PXP_OUT_LRC_RSVD0(v) \
+ (((v) << 14) & BM_PXP_OUT_LRC_RSVD0)
+#define BP_PXP_OUT_LRC_Y 0
+#define BM_PXP_OUT_LRC_Y 0x00003FFF
+#define BF_PXP_OUT_LRC_Y(v) \
+ (((v) << 0) & BM_PXP_OUT_LRC_Y)
+
+#define HW_PXP_OUT_PS_ULC (0x00000070)
+
+#define BP_PXP_OUT_PS_ULC_RSVD1 30
+#define BM_PXP_OUT_PS_ULC_RSVD1 0xC0000000
+#define BF_PXP_OUT_PS_ULC_RSVD1(v) \
+ (((v) << 30) & BM_PXP_OUT_PS_ULC_RSVD1)
+#define BP_PXP_OUT_PS_ULC_X 16
+#define BM_PXP_OUT_PS_ULC_X 0x3FFF0000
+#define BF_PXP_OUT_PS_ULC_X(v) \
+ (((v) << 16) & BM_PXP_OUT_PS_ULC_X)
+#define BP_PXP_OUT_PS_ULC_RSVD0 14
+#define BM_PXP_OUT_PS_ULC_RSVD0 0x0000C000
+#define BF_PXP_OUT_PS_ULC_RSVD0(v) \
+ (((v) << 14) & BM_PXP_OUT_PS_ULC_RSVD0)
+#define BP_PXP_OUT_PS_ULC_Y 0
+#define BM_PXP_OUT_PS_ULC_Y 0x00003FFF
+#define BF_PXP_OUT_PS_ULC_Y(v) \
+ (((v) << 0) & BM_PXP_OUT_PS_ULC_Y)
+
+#define HW_PXP_OUT_PS_LRC (0x00000080)
+
+#define BP_PXP_OUT_PS_LRC_RSVD1 30
+#define BM_PXP_OUT_PS_LRC_RSVD1 0xC0000000
+#define BF_PXP_OUT_PS_LRC_RSVD1(v) \
+ (((v) << 30) & BM_PXP_OUT_PS_LRC_RSVD1)
+#define BP_PXP_OUT_PS_LRC_X 16
+#define BM_PXP_OUT_PS_LRC_X 0x3FFF0000
+#define BF_PXP_OUT_PS_LRC_X(v) \
+ (((v) << 16) & BM_PXP_OUT_PS_LRC_X)
+#define BP_PXP_OUT_PS_LRC_RSVD0 14
+#define BM_PXP_OUT_PS_LRC_RSVD0 0x0000C000
+#define BF_PXP_OUT_PS_LRC_RSVD0(v) \
+ (((v) << 14) & BM_PXP_OUT_PS_LRC_RSVD0)
+#define BP_PXP_OUT_PS_LRC_Y 0
+#define BM_PXP_OUT_PS_LRC_Y 0x00003FFF
+#define BF_PXP_OUT_PS_LRC_Y(v) \
+ (((v) << 0) & BM_PXP_OUT_PS_LRC_Y)
+
+#define HW_PXP_OUT_AS_ULC (0x00000090)
+
+#define BP_PXP_OUT_AS_ULC_RSVD1 30
+#define BM_PXP_OUT_AS_ULC_RSVD1 0xC0000000
+#define BF_PXP_OUT_AS_ULC_RSVD1(v) \
+ (((v) << 30) & BM_PXP_OUT_AS_ULC_RSVD1)
+#define BP_PXP_OUT_AS_ULC_X 16
+#define BM_PXP_OUT_AS_ULC_X 0x3FFF0000
+#define BF_PXP_OUT_AS_ULC_X(v) \
+ (((v) << 16) & BM_PXP_OUT_AS_ULC_X)
+#define BP_PXP_OUT_AS_ULC_RSVD0 14
+#define BM_PXP_OUT_AS_ULC_RSVD0 0x0000C000
+#define BF_PXP_OUT_AS_ULC_RSVD0(v) \
+ (((v) << 14) & BM_PXP_OUT_AS_ULC_RSVD0)
+#define BP_PXP_OUT_AS_ULC_Y 0
+#define BM_PXP_OUT_AS_ULC_Y 0x00003FFF
+#define BF_PXP_OUT_AS_ULC_Y(v) \
+ (((v) << 0) & BM_PXP_OUT_AS_ULC_Y)
+
+#define HW_PXP_OUT_AS_LRC (0x000000a0)
+
+#define BP_PXP_OUT_AS_LRC_RSVD1 30
+#define BM_PXP_OUT_AS_LRC_RSVD1 0xC0000000
+#define BF_PXP_OUT_AS_LRC_RSVD1(v) \
+ (((v) << 30) & BM_PXP_OUT_AS_LRC_RSVD1)
+#define BP_PXP_OUT_AS_LRC_X 16
+#define BM_PXP_OUT_AS_LRC_X 0x3FFF0000
+#define BF_PXP_OUT_AS_LRC_X(v) \
+ (((v) << 16) & BM_PXP_OUT_AS_LRC_X)
+#define BP_PXP_OUT_AS_LRC_RSVD0 14
+#define BM_PXP_OUT_AS_LRC_RSVD0 0x0000C000
+#define BF_PXP_OUT_AS_LRC_RSVD0(v) \
+ (((v) << 14) & BM_PXP_OUT_AS_LRC_RSVD0)
+#define BP_PXP_OUT_AS_LRC_Y 0
+#define BM_PXP_OUT_AS_LRC_Y 0x00003FFF
+#define BF_PXP_OUT_AS_LRC_Y(v) \
+ (((v) << 0) & BM_PXP_OUT_AS_LRC_Y)
+
+#define HW_PXP_PS_CTRL (0x000000b0)
+#define HW_PXP_PS_CTRL_SET (0x000000b4)
+#define HW_PXP_PS_CTRL_CLR (0x000000b8)
+#define HW_PXP_PS_CTRL_TOG (0x000000bc)
+
+#define BP_PXP_PS_CTRL_RSVD1 12
+#define BM_PXP_PS_CTRL_RSVD1 0xFFFFF000
+#define BF_PXP_PS_CTRL_RSVD1(v) \
+ (((v) << 12) & BM_PXP_PS_CTRL_RSVD1)
+#define BP_PXP_PS_CTRL_DECX 10
+#define BM_PXP_PS_CTRL_DECX 0x00000C00
+#define BF_PXP_PS_CTRL_DECX(v) \
+ (((v) << 10) & BM_PXP_PS_CTRL_DECX)
+#define BV_PXP_PS_CTRL_DECX__DISABLE 0x0
+#define BV_PXP_PS_CTRL_DECX__DECX2 0x1
+#define BV_PXP_PS_CTRL_DECX__DECX4 0x2
+#define BV_PXP_PS_CTRL_DECX__DECX8 0x3
+#define BP_PXP_PS_CTRL_DECY 8
+#define BM_PXP_PS_CTRL_DECY 0x00000300
+#define BF_PXP_PS_CTRL_DECY(v) \
+ (((v) << 8) & BM_PXP_PS_CTRL_DECY)
+#define BV_PXP_PS_CTRL_DECY__DISABLE 0x0
+#define BV_PXP_PS_CTRL_DECY__DECY2 0x1
+#define BV_PXP_PS_CTRL_DECY__DECY4 0x2
+#define BV_PXP_PS_CTRL_DECY__DECY8 0x3
+#define BP_PXP_PS_CTRL_SWAP 5
+#define BM_PXP_PS_CTRL_SWAP 0x000000E0
+#define BF_PXP_PS_CTRL_SWAP(v) \
+ (((v) << 5) & BM_PXP_PS_CTRL_SWAP)
+#define BP_PXP_PS_CTRL_FORMAT 0
+#define BM_PXP_PS_CTRL_FORMAT 0x0000001F
+#define BF_PXP_PS_CTRL_FORMAT(v) \
+ (((v) << 0) & BM_PXP_PS_CTRL_FORMAT)
+#define BV_PXP_PS_CTRL_FORMAT__RGB888 0x4
+#define BV_PXP_PS_CTRL_FORMAT__RGB555 0xC
+#define BV_PXP_PS_CTRL_FORMAT__RGB444 0xD
+#define BV_PXP_PS_CTRL_FORMAT__RGB565 0xE
+#define BV_PXP_PS_CTRL_FORMAT__YUV1P444 0x10
+#define BV_PXP_PS_CTRL_FORMAT__UYVY1P422 0x12
+#define BV_PXP_PS_CTRL_FORMAT__VYUY1P422 0x13
+#define BV_PXP_PS_CTRL_FORMAT__Y8 0x14
+#define BV_PXP_PS_CTRL_FORMAT__Y4 0x15
+#define BV_PXP_PS_CTRL_FORMAT__YUV2P422 0x18
+#define BV_PXP_PS_CTRL_FORMAT__YUV2P420 0x19
+#define BV_PXP_PS_CTRL_FORMAT__YVU2P422 0x1A
+#define BV_PXP_PS_CTRL_FORMAT__YVU2P420 0x1B
+#define BV_PXP_PS_CTRL_FORMAT__YUV422 0x1E
+#define BV_PXP_PS_CTRL_FORMAT__YUV420 0x1F
+
+#define HW_PXP_PS_BUF (0x000000c0)
+
+#define BP_PXP_PS_BUF_ADDR 0
+#define BM_PXP_PS_BUF_ADDR 0xFFFFFFFF
+#define BF_PXP_PS_BUF_ADDR(v) (v)
+
+#define HW_PXP_PS_UBUF (0x000000d0)
+
+#define BP_PXP_PS_UBUF_ADDR 0
+#define BM_PXP_PS_UBUF_ADDR 0xFFFFFFFF
+#define BF_PXP_PS_UBUF_ADDR(v) (v)
+
+#define HW_PXP_PS_VBUF (0x000000e0)
+
+#define BP_PXP_PS_VBUF_ADDR 0
+#define BM_PXP_PS_VBUF_ADDR 0xFFFFFFFF
+#define BF_PXP_PS_VBUF_ADDR(v) (v)
+
+#define HW_PXP_PS_PITCH (0x000000f0)
+
+#define BP_PXP_PS_PITCH_RSVD 16
+#define BM_PXP_PS_PITCH_RSVD 0xFFFF0000
+#define BF_PXP_PS_PITCH_RSVD(v) \
+ (((v) << 16) & BM_PXP_PS_PITCH_RSVD)
+#define BP_PXP_PS_PITCH_PITCH 0
+#define BM_PXP_PS_PITCH_PITCH 0x0000FFFF
+#define BF_PXP_PS_PITCH_PITCH(v) \
+ (((v) << 0) & BM_PXP_PS_PITCH_PITCH)
+
+#define HW_PXP_PS_BACKGROUND (0x00000100)
+
+#define BP_PXP_PS_BACKGROUND_RSVD 24
+#define BM_PXP_PS_BACKGROUND_RSVD 0xFF000000
+#define BF_PXP_PS_BACKGROUND_RSVD(v) \
+ (((v) << 24) & BM_PXP_PS_BACKGROUND_RSVD)
+#define BP_PXP_PS_BACKGROUND_COLOR 0
+#define BM_PXP_PS_BACKGROUND_COLOR 0x00FFFFFF
+#define BF_PXP_PS_BACKGROUND_COLOR(v) \
+ (((v) << 0) & BM_PXP_PS_BACKGROUND_COLOR)
+
+#define HW_PXP_PS_SCALE (0x00000110)
+
+#define BM_PXP_PS_SCALE_RSVD2 0x80000000
+#define BP_PXP_PS_SCALE_YSCALE 16
+#define BM_PXP_PS_SCALE_YSCALE 0x7FFF0000
+#define BF_PXP_PS_SCALE_YSCALE(v) \
+ (((v) << 16) & BM_PXP_PS_SCALE_YSCALE)
+#define BM_PXP_PS_SCALE_RSVD1 0x00008000
+#define BP_PXP_PS_SCALE_XSCALE 0
+#define BM_PXP_PS_SCALE_XSCALE 0x00007FFF
+#define BF_PXP_PS_SCALE_XSCALE(v) \
+ (((v) << 0) & BM_PXP_PS_SCALE_XSCALE)
+
+#define HW_PXP_PS_OFFSET (0x00000120)
+
+#define BP_PXP_PS_OFFSET_RSVD2 28
+#define BM_PXP_PS_OFFSET_RSVD2 0xF0000000
+#define BF_PXP_PS_OFFSET_RSVD2(v) \
+ (((v) << 28) & BM_PXP_PS_OFFSET_RSVD2)
+#define BP_PXP_PS_OFFSET_YOFFSET 16
+#define BM_PXP_PS_OFFSET_YOFFSET 0x0FFF0000
+#define BF_PXP_PS_OFFSET_YOFFSET(v) \
+ (((v) << 16) & BM_PXP_PS_OFFSET_YOFFSET)
+#define BP_PXP_PS_OFFSET_RSVD1 12
+#define BM_PXP_PS_OFFSET_RSVD1 0x0000F000
+#define BF_PXP_PS_OFFSET_RSVD1(v) \
+ (((v) << 12) & BM_PXP_PS_OFFSET_RSVD1)
+#define BP_PXP_PS_OFFSET_XOFFSET 0
+#define BM_PXP_PS_OFFSET_XOFFSET 0x00000FFF
+#define BF_PXP_PS_OFFSET_XOFFSET(v) \
+ (((v) << 0) & BM_PXP_PS_OFFSET_XOFFSET)
+
+#define HW_PXP_PS_CLRKEYLOW (0x00000130)
+
+#define BP_PXP_PS_CLRKEYLOW_RSVD1 24
+#define BM_PXP_PS_CLRKEYLOW_RSVD1 0xFF000000
+#define BF_PXP_PS_CLRKEYLOW_RSVD1(v) \
+ (((v) << 24) & BM_PXP_PS_CLRKEYLOW_RSVD1)
+#define BP_PXP_PS_CLRKEYLOW_PIXEL 0
+#define BM_PXP_PS_CLRKEYLOW_PIXEL 0x00FFFFFF
+#define BF_PXP_PS_CLRKEYLOW_PIXEL(v) \
+ (((v) << 0) & BM_PXP_PS_CLRKEYLOW_PIXEL)
+
+#define HW_PXP_PS_CLRKEYHIGH (0x00000140)
+
+#define BP_PXP_PS_CLRKEYHIGH_RSVD1 24
+#define BM_PXP_PS_CLRKEYHIGH_RSVD1 0xFF000000
+#define BF_PXP_PS_CLRKEYHIGH_RSVD1(v) \
+ (((v) << 24) & BM_PXP_PS_CLRKEYHIGH_RSVD1)
+#define BP_PXP_PS_CLRKEYHIGH_PIXEL 0
+#define BM_PXP_PS_CLRKEYHIGH_PIXEL 0x00FFFFFF
+#define BF_PXP_PS_CLRKEYHIGH_PIXEL(v) \
+ (((v) << 0) & BM_PXP_PS_CLRKEYHIGH_PIXEL)
+
+#define HW_PXP_AS_CTRL (0x00000150)
+
+#define BP_PXP_AS_CTRL_RSVD1 21
+#define BM_PXP_AS_CTRL_RSVD1 0xFFE00000
+#define BF_PXP_AS_CTRL_RSVD1(v) \
+ (((v) << 21) & BM_PXP_AS_CTRL_RSVD1)
+#define BM_PXP_AS_CTRL_ALPHA_INVERT 0x00100000
+#define BP_PXP_AS_CTRL_ROP 16
+#define BM_PXP_AS_CTRL_ROP 0x000F0000
+#define BF_PXP_AS_CTRL_ROP(v) \
+ (((v) << 16) & BM_PXP_AS_CTRL_ROP)
+#define BV_PXP_AS_CTRL_ROP__MASKAS 0x0
+#define BV_PXP_AS_CTRL_ROP__MASKNOTAS 0x1
+#define BV_PXP_AS_CTRL_ROP__MASKASNOT 0x2
+#define BV_PXP_AS_CTRL_ROP__MERGEAS 0x3
+#define BV_PXP_AS_CTRL_ROP__MERGENOTAS 0x4
+#define BV_PXP_AS_CTRL_ROP__MERGEASNOT 0x5
+#define BV_PXP_AS_CTRL_ROP__NOTCOPYAS 0x6
+#define BV_PXP_AS_CTRL_ROP__NOT 0x7
+#define BV_PXP_AS_CTRL_ROP__NOTMASKAS 0x8
+#define BV_PXP_AS_CTRL_ROP__NOTMERGEAS 0x9
+#define BV_PXP_AS_CTRL_ROP__XORAS 0xA
+#define BV_PXP_AS_CTRL_ROP__NOTXORAS 0xB
+#define BP_PXP_AS_CTRL_ALPHA 8
+#define BM_PXP_AS_CTRL_ALPHA 0x0000FF00
+#define BF_PXP_AS_CTRL_ALPHA(v) \
+ (((v) << 8) & BM_PXP_AS_CTRL_ALPHA)
+#define BP_PXP_AS_CTRL_FORMAT 4
+#define BM_PXP_AS_CTRL_FORMAT 0x000000F0
+#define BF_PXP_AS_CTRL_FORMAT(v) \
+ (((v) << 4) & BM_PXP_AS_CTRL_FORMAT)
+#define BV_PXP_AS_CTRL_FORMAT__ARGB8888 0x0
+#define BV_PXP_AS_CTRL_FORMAT__RGB888 0x4
+#define BV_PXP_AS_CTRL_FORMAT__ARGB1555 0x8
+#define BV_PXP_AS_CTRL_FORMAT__ARGB4444 0x9
+#define BV_PXP_AS_CTRL_FORMAT__RGB555 0xC
+#define BV_PXP_AS_CTRL_FORMAT__RGB444 0xD
+#define BV_PXP_AS_CTRL_FORMAT__RGB565 0xE
+#define BM_PXP_AS_CTRL_ENABLE_COLORKEY 0x00000008
+#define BP_PXP_AS_CTRL_ALPHA_CTRL 1
+#define BM_PXP_AS_CTRL_ALPHA_CTRL 0x00000006
+#define BF_PXP_AS_CTRL_ALPHA_CTRL(v) \
+ (((v) << 1) & BM_PXP_AS_CTRL_ALPHA_CTRL)
+#define BV_PXP_AS_CTRL_ALPHA_CTRL__Embedded 0x0
+#define BV_PXP_AS_CTRL_ALPHA_CTRL__Override 0x1
+#define BV_PXP_AS_CTRL_ALPHA_CTRL__Multiply 0x2
+#define BV_PXP_AS_CTRL_ALPHA_CTRL__ROPs 0x3
+#define BM_PXP_AS_CTRL_RSVD0 0x00000001
+
+#define HW_PXP_AS_BUF (0x00000160)
+
+#define BP_PXP_AS_BUF_ADDR 0
+#define BM_PXP_AS_BUF_ADDR 0xFFFFFFFF
+#define BF_PXP_AS_BUF_ADDR(v) (v)
+
+#define HW_PXP_AS_PITCH (0x00000170)
+
+#define BP_PXP_AS_PITCH_RSVD 16
+#define BM_PXP_AS_PITCH_RSVD 0xFFFF0000
+#define BF_PXP_AS_PITCH_RSVD(v) \
+ (((v) << 16) & BM_PXP_AS_PITCH_RSVD)
+#define BP_PXP_AS_PITCH_PITCH 0
+#define BM_PXP_AS_PITCH_PITCH 0x0000FFFF
+#define BF_PXP_AS_PITCH_PITCH(v) \
+ (((v) << 0) & BM_PXP_AS_PITCH_PITCH)
+
+#define HW_PXP_AS_CLRKEYLOW (0x00000180)
+
+#define BP_PXP_AS_CLRKEYLOW_RSVD1 24
+#define BM_PXP_AS_CLRKEYLOW_RSVD1 0xFF000000
+#define BF_PXP_AS_CLRKEYLOW_RSVD1(v) \
+ (((v) << 24) & BM_PXP_AS_CLRKEYLOW_RSVD1)
+#define BP_PXP_AS_CLRKEYLOW_PIXEL 0
+#define BM_PXP_AS_CLRKEYLOW_PIXEL 0x00FFFFFF
+#define BF_PXP_AS_CLRKEYLOW_PIXEL(v) \
+ (((v) << 0) & BM_PXP_AS_CLRKEYLOW_PIXEL)
+
+#define HW_PXP_AS_CLRKEYHIGH (0x00000190)
+
+#define BP_PXP_AS_CLRKEYHIGH_RSVD1 24
+#define BM_PXP_AS_CLRKEYHIGH_RSVD1 0xFF000000
+#define BF_PXP_AS_CLRKEYHIGH_RSVD1(v) \
+ (((v) << 24) & BM_PXP_AS_CLRKEYHIGH_RSVD1)
+#define BP_PXP_AS_CLRKEYHIGH_PIXEL 0
+#define BM_PXP_AS_CLRKEYHIGH_PIXEL 0x00FFFFFF
+#define BF_PXP_AS_CLRKEYHIGH_PIXEL(v) \
+ (((v) << 0) & BM_PXP_AS_CLRKEYHIGH_PIXEL)
+
+#define HW_PXP_CSC1_COEF0 (0x000001a0)
+
+#define BM_PXP_CSC1_COEF0_YCBCR_MODE 0x80000000
+#define BM_PXP_CSC1_COEF0_BYPASS 0x40000000
+#define BM_PXP_CSC1_COEF0_RSVD1 0x20000000
+#define BP_PXP_CSC1_COEF0_C0 18
+#define BM_PXP_CSC1_COEF0_C0 0x1FFC0000
+#define BF_PXP_CSC1_COEF0_C0(v) \
+ (((v) << 18) & BM_PXP_CSC1_COEF0_C0)
+#define BP_PXP_CSC1_COEF0_UV_OFFSET 9
+#define BM_PXP_CSC1_COEF0_UV_OFFSET 0x0003FE00
+#define BF_PXP_CSC1_COEF0_UV_OFFSET(v) \
+ (((v) << 9) & BM_PXP_CSC1_COEF0_UV_OFFSET)
+#define BP_PXP_CSC1_COEF0_Y_OFFSET 0
+#define BM_PXP_CSC1_COEF0_Y_OFFSET 0x000001FF
+#define BF_PXP_CSC1_COEF0_Y_OFFSET(v) \
+ (((v) << 0) & BM_PXP_CSC1_COEF0_Y_OFFSET)
+
+#define HW_PXP_CSC1_COEF1 (0x000001b0)
+
+#define BP_PXP_CSC1_COEF1_RSVD1 27
+#define BM_PXP_CSC1_COEF1_RSVD1 0xF8000000
+#define BF_PXP_CSC1_COEF1_RSVD1(v) \
+ (((v) << 27) & BM_PXP_CSC1_COEF1_RSVD1)
+#define BP_PXP_CSC1_COEF1_C1 16
+#define BM_PXP_CSC1_COEF1_C1 0x07FF0000
+#define BF_PXP_CSC1_COEF1_C1(v) \
+ (((v) << 16) & BM_PXP_CSC1_COEF1_C1)
+#define BP_PXP_CSC1_COEF1_RSVD0 11
+#define BM_PXP_CSC1_COEF1_RSVD0 0x0000F800
+#define BF_PXP_CSC1_COEF1_RSVD0(v) \
+ (((v) << 11) & BM_PXP_CSC1_COEF1_RSVD0)
+#define BP_PXP_CSC1_COEF1_C4 0
+#define BM_PXP_CSC1_COEF1_C4 0x000007FF
+#define BF_PXP_CSC1_COEF1_C4(v) \
+ (((v) << 0) & BM_PXP_CSC1_COEF1_C4)
+
+#define HW_PXP_CSC1_COEF2 (0x000001c0)
+
+#define BP_PXP_CSC1_COEF2_RSVD1 27
+#define BM_PXP_CSC1_COEF2_RSVD1 0xF8000000
+#define BF_PXP_CSC1_COEF2_RSVD1(v) \
+ (((v) << 27) & BM_PXP_CSC1_COEF2_RSVD1)
+#define BP_PXP_CSC1_COEF2_C2 16
+#define BM_PXP_CSC1_COEF2_C2 0x07FF0000
+#define BF_PXP_CSC1_COEF2_C2(v) \
+ (((v) << 16) & BM_PXP_CSC1_COEF2_C2)
+#define BP_PXP_CSC1_COEF2_RSVD0 11
+#define BM_PXP_CSC1_COEF2_RSVD0 0x0000F800
+#define BF_PXP_CSC1_COEF2_RSVD0(v) \
+ (((v) << 11) & BM_PXP_CSC1_COEF2_RSVD0)
+#define BP_PXP_CSC1_COEF2_C3 0
+#define BM_PXP_CSC1_COEF2_C3 0x000007FF
+#define BF_PXP_CSC1_COEF2_C3(v) \
+ (((v) << 0) & BM_PXP_CSC1_COEF2_C3)
+
+#define HW_PXP_CSC2_CTRL (0x000001d0)
+
+#define BP_PXP_CSC2_CTRL_RSVD 3
+#define BM_PXP_CSC2_CTRL_RSVD 0xFFFFFFF8
+#define BF_PXP_CSC2_CTRL_RSVD(v) \
+ (((v) << 3) & BM_PXP_CSC2_CTRL_RSVD)
+#define BP_PXP_CSC2_CTRL_CSC_MODE 1
+#define BM_PXP_CSC2_CTRL_CSC_MODE 0x00000006
+#define BF_PXP_CSC2_CTRL_CSC_MODE(v) \
+ (((v) << 1) & BM_PXP_CSC2_CTRL_CSC_MODE)
+#define BV_PXP_CSC2_CTRL_CSC_MODE__YUV2RGB 0x0
+#define BV_PXP_CSC2_CTRL_CSC_MODE__YCbCr2RGB 0x1
+#define BV_PXP_CSC2_CTRL_CSC_MODE__RGB2YUV 0x2
+#define BV_PXP_CSC2_CTRL_CSC_MODE__RGB2YCbCr 0x3
+#define BM_PXP_CSC2_CTRL_BYPASS 0x00000001
+
+#define HW_PXP_CSC2_COEF0 (0x000001e0)
+
+#define BP_PXP_CSC2_COEF0_RSVD1 27
+#define BM_PXP_CSC2_COEF0_RSVD1 0xF8000000
+#define BF_PXP_CSC2_COEF0_RSVD1(v) \
+ (((v) << 27) & BM_PXP_CSC2_COEF0_RSVD1)
+#define BP_PXP_CSC2_COEF0_A2 16
+#define BM_PXP_CSC2_COEF0_A2 0x07FF0000
+#define BF_PXP_CSC2_COEF0_A2(v) \
+ (((v) << 16) & BM_PXP_CSC2_COEF0_A2)
+#define BP_PXP_CSC2_COEF0_RSVD0 11
+#define BM_PXP_CSC2_COEF0_RSVD0 0x0000F800
+#define BF_PXP_CSC2_COEF0_RSVD0(v) \
+ (((v) << 11) & BM_PXP_CSC2_COEF0_RSVD0)
+#define BP_PXP_CSC2_COEF0_A1 0
+#define BM_PXP_CSC2_COEF0_A1 0x000007FF
+#define BF_PXP_CSC2_COEF0_A1(v) \
+ (((v) << 0) & BM_PXP_CSC2_COEF0_A1)
+
+#define HW_PXP_CSC2_COEF1 (0x000001f0)
+
+#define BP_PXP_CSC2_COEF1_RSVD1 27
+#define BM_PXP_CSC2_COEF1_RSVD1 0xF8000000
+#define BF_PXP_CSC2_COEF1_RSVD1(v) \
+ (((v) << 27) & BM_PXP_CSC2_COEF1_RSVD1)
+#define BP_PXP_CSC2_COEF1_B1 16
+#define BM_PXP_CSC2_COEF1_B1 0x07FF0000
+#define BF_PXP_CSC2_COEF1_B1(v) \
+ (((v) << 16) & BM_PXP_CSC2_COEF1_B1)
+#define BP_PXP_CSC2_COEF1_RSVD0 11
+#define BM_PXP_CSC2_COEF1_RSVD0 0x0000F800
+#define BF_PXP_CSC2_COEF1_RSVD0(v) \
+ (((v) << 11) & BM_PXP_CSC2_COEF1_RSVD0)
+#define BP_PXP_CSC2_COEF1_A3 0
+#define BM_PXP_CSC2_COEF1_A3 0x000007FF
+#define BF_PXP_CSC2_COEF1_A3(v) \
+ (((v) << 0) & BM_PXP_CSC2_COEF1_A3)
+
+#define HW_PXP_CSC2_COEF2 (0x00000200)
+
+#define BP_PXP_CSC2_COEF2_RSVD1 27
+#define BM_PXP_CSC2_COEF2_RSVD1 0xF8000000
+#define BF_PXP_CSC2_COEF2_RSVD1(v) \
+ (((v) << 27) & BM_PXP_CSC2_COEF2_RSVD1)
+#define BP_PXP_CSC2_COEF2_B3 16
+#define BM_PXP_CSC2_COEF2_B3 0x07FF0000
+#define BF_PXP_CSC2_COEF2_B3(v) \
+ (((v) << 16) & BM_PXP_CSC2_COEF2_B3)
+#define BP_PXP_CSC2_COEF2_RSVD0 11
+#define BM_PXP_CSC2_COEF2_RSVD0 0x0000F800
+#define BF_PXP_CSC2_COEF2_RSVD0(v) \
+ (((v) << 11) & BM_PXP_CSC2_COEF2_RSVD0)
+#define BP_PXP_CSC2_COEF2_B2 0
+#define BM_PXP_CSC2_COEF2_B2 0x000007FF
+#define BF_PXP_CSC2_COEF2_B2(v) \
+ (((v) << 0) & BM_PXP_CSC2_COEF2_B2)
+
+#define HW_PXP_CSC2_COEF3 (0x00000210)
+
+#define BP_PXP_CSC2_COEF3_RSVD1 27
+#define BM_PXP_CSC2_COEF3_RSVD1 0xF8000000
+#define BF_PXP_CSC2_COEF3_RSVD1(v) \
+ (((v) << 27) & BM_PXP_CSC2_COEF3_RSVD1)
+#define BP_PXP_CSC2_COEF3_C2 16
+#define BM_PXP_CSC2_COEF3_C2 0x07FF0000
+#define BF_PXP_CSC2_COEF3_C2(v) \
+ (((v) << 16) & BM_PXP_CSC2_COEF3_C2)
+#define BP_PXP_CSC2_COEF3_RSVD0 11
+#define BM_PXP_CSC2_COEF3_RSVD0 0x0000F800
+#define BF_PXP_CSC2_COEF3_RSVD0(v) \
+ (((v) << 11) & BM_PXP_CSC2_COEF3_RSVD0)
+#define BP_PXP_CSC2_COEF3_C1 0
+#define BM_PXP_CSC2_COEF3_C1 0x000007FF
+#define BF_PXP_CSC2_COEF3_C1(v) \
+ (((v) << 0) & BM_PXP_CSC2_COEF3_C1)
+
+#define HW_PXP_CSC2_COEF4 (0x00000220)
+
+#define BP_PXP_CSC2_COEF4_RSVD1 25
+#define BM_PXP_CSC2_COEF4_RSVD1 0xFE000000
+#define BF_PXP_CSC2_COEF4_RSVD1(v) \
+ (((v) << 25) & BM_PXP_CSC2_COEF4_RSVD1)
+#define BP_PXP_CSC2_COEF4_D1 16
+#define BM_PXP_CSC2_COEF4_D1 0x01FF0000
+#define BF_PXP_CSC2_COEF4_D1(v) \
+ (((v) << 16) & BM_PXP_CSC2_COEF4_D1)
+#define BP_PXP_CSC2_COEF4_RSVD0 11
+#define BM_PXP_CSC2_COEF4_RSVD0 0x0000F800
+#define BF_PXP_CSC2_COEF4_RSVD0(v) \
+ (((v) << 11) & BM_PXP_CSC2_COEF4_RSVD0)
+#define BP_PXP_CSC2_COEF4_C3 0
+#define BM_PXP_CSC2_COEF4_C3 0x000007FF
+#define BF_PXP_CSC2_COEF4_C3(v) \
+ (((v) << 0) & BM_PXP_CSC2_COEF4_C3)
+
+#define HW_PXP_CSC2_COEF5 (0x00000230)
+
+#define BP_PXP_CSC2_COEF5_RSVD1 25
+#define BM_PXP_CSC2_COEF5_RSVD1 0xFE000000
+#define BF_PXP_CSC2_COEF5_RSVD1(v) \
+ (((v) << 25) & BM_PXP_CSC2_COEF5_RSVD1)
+#define BP_PXP_CSC2_COEF5_D3 16
+#define BM_PXP_CSC2_COEF5_D3 0x01FF0000
+#define BF_PXP_CSC2_COEF5_D3(v) \
+ (((v) << 16) & BM_PXP_CSC2_COEF5_D3)
+#define BP_PXP_CSC2_COEF5_RSVD0 9
+#define BM_PXP_CSC2_COEF5_RSVD0 0x0000FE00
+#define BF_PXP_CSC2_COEF5_RSVD0(v) \
+ (((v) << 9) & BM_PXP_CSC2_COEF5_RSVD0)
+#define BP_PXP_CSC2_COEF5_D2 0
+#define BM_PXP_CSC2_COEF5_D2 0x000001FF
+#define BF_PXP_CSC2_COEF5_D2(v) \
+ (((v) << 0) & BM_PXP_CSC2_COEF5_D2)
+
+#define HW_PXP_LUT_CTRL (0x00000240)
+
+#define BM_PXP_LUT_CTRL_BYPASS 0x80000000
+#define BP_PXP_LUT_CTRL_RSVD3 26
+#define BM_PXP_LUT_CTRL_RSVD3 0x7C000000
+#define BF_PXP_LUT_CTRL_RSVD3(v) \
+ (((v) << 26) & BM_PXP_LUT_CTRL_RSVD3)
+#define BP_PXP_LUT_CTRL_LOOKUP_MODE 24
+#define BM_PXP_LUT_CTRL_LOOKUP_MODE 0x03000000
+#define BF_PXP_LUT_CTRL_LOOKUP_MODE(v) \
+ (((v) << 24) & BM_PXP_LUT_CTRL_LOOKUP_MODE)
+#define BV_PXP_LUT_CTRL_LOOKUP_MODE__CACHE_RGB565 0x0
+#define BV_PXP_LUT_CTRL_LOOKUP_MODE__DIRECT_Y8 0x1
+#define BV_PXP_LUT_CTRL_LOOKUP_MODE__DIRECT_RGB444 0x2
+#define BV_PXP_LUT_CTRL_LOOKUP_MODE__DIRECT_RGB454 0x3
+#define BP_PXP_LUT_CTRL_RSVD2 18
+#define BM_PXP_LUT_CTRL_RSVD2 0x00FC0000
+#define BF_PXP_LUT_CTRL_RSVD2(v) \
+ (((v) << 18) & BM_PXP_LUT_CTRL_RSVD2)
+#define BP_PXP_LUT_CTRL_OUT_MODE 16
+#define BM_PXP_LUT_CTRL_OUT_MODE 0x00030000
+#define BF_PXP_LUT_CTRL_OUT_MODE(v) \
+ (((v) << 16) & BM_PXP_LUT_CTRL_OUT_MODE)
+#define BV_PXP_LUT_CTRL_OUT_MODE__RESERVED 0x0
+#define BV_PXP_LUT_CTRL_OUT_MODE__Y8 0x1
+#define BV_PXP_LUT_CTRL_OUT_MODE__RGBW4444CFA 0x2
+#define BV_PXP_LUT_CTRL_OUT_MODE__RGB888 0x3
+#define BP_PXP_LUT_CTRL_RSVD1 11
+#define BM_PXP_LUT_CTRL_RSVD1 0x0000F800
+#define BF_PXP_LUT_CTRL_RSVD1(v) \
+ (((v) << 11) & BM_PXP_LUT_CTRL_RSVD1)
+#define BM_PXP_LUT_CTRL_SEL_8KB 0x00000400
+#define BM_PXP_LUT_CTRL_LRU_UPD 0x00000200
+#define BM_PXP_LUT_CTRL_INVALID 0x00000100
+#define BP_PXP_LUT_CTRL_RSVD0 1
+#define BM_PXP_LUT_CTRL_RSVD0 0x000000FE
+#define BF_PXP_LUT_CTRL_RSVD0(v) \
+ (((v) << 1) & BM_PXP_LUT_CTRL_RSVD0)
+#define BM_PXP_LUT_CTRL_DMA_START 0x00000001
+
+#define HW_PXP_LUT_ADDR (0x00000250)
+
+#define BM_PXP_LUT_ADDR_RSVD2 0x80000000
+#define BP_PXP_LUT_ADDR_NUM_BYTES 16
+#define BM_PXP_LUT_ADDR_NUM_BYTES 0x7FFF0000
+#define BF_PXP_LUT_ADDR_NUM_BYTES(v) \
+ (((v) << 16) & BM_PXP_LUT_ADDR_NUM_BYTES)
+#define BP_PXP_LUT_ADDR_RSVD1 14
+#define BM_PXP_LUT_ADDR_RSVD1 0x0000C000
+#define BF_PXP_LUT_ADDR_RSVD1(v) \
+ (((v) << 14) & BM_PXP_LUT_ADDR_RSVD1)
+#define BP_PXP_LUT_ADDR_ADDR 0
+#define BM_PXP_LUT_ADDR_ADDR 0x00003FFF
+#define BF_PXP_LUT_ADDR_ADDR(v) \
+ (((v) << 0) & BM_PXP_LUT_ADDR_ADDR)
+
+#define HW_PXP_LUT_DATA (0x00000260)
+
+#define BP_PXP_LUT_DATA_DATA 0
+#define BM_PXP_LUT_DATA_DATA 0xFFFFFFFF
+#define BF_PXP_LUT_DATA_DATA(v) (v)
+
+#define HW_PXP_LUT_EXTMEM (0x00000270)
+
+#define BP_PXP_LUT_EXTMEM_ADDR 0
+#define BM_PXP_LUT_EXTMEM_ADDR 0xFFFFFFFF
+#define BF_PXP_LUT_EXTMEM_ADDR(v) (v)
+
+#define HW_PXP_CFA (0x00000280)
+
+#define BP_PXP_CFA_DATA 0
+#define BM_PXP_CFA_DATA 0xFFFFFFFF
+#define BF_PXP_CFA_DATA(v) (v)
+
+#define HW_PXP_HIST_CTRL (0x00000290)
+
+#define BP_PXP_HIST_CTRL_RSVD 6
+#define BM_PXP_HIST_CTRL_RSVD 0xFFFFFFC0
+#define BF_PXP_HIST_CTRL_RSVD(v) \
+ (((v) << 6) & BM_PXP_HIST_CTRL_RSVD)
+#define BP_PXP_HIST_CTRL_PANEL_MODE 4
+#define BM_PXP_HIST_CTRL_PANEL_MODE 0x00000030
+#define BF_PXP_HIST_CTRL_PANEL_MODE(v) \
+ (((v) << 4) & BM_PXP_HIST_CTRL_PANEL_MODE)
+#define BV_PXP_HIST_CTRL_PANEL_MODE__GRAY4 0x0
+#define BV_PXP_HIST_CTRL_PANEL_MODE__GRAY8 0x1
+#define BV_PXP_HIST_CTRL_PANEL_MODE__GRAY16 0x2
+#define BV_PXP_HIST_CTRL_PANEL_MODE__GRAY32 0x3
+#define BP_PXP_HIST_CTRL_STATUS 0
+#define BM_PXP_HIST_CTRL_STATUS 0x0000000F
+#define BF_PXP_HIST_CTRL_STATUS(v) \
+ (((v) << 0) & BM_PXP_HIST_CTRL_STATUS)
+
+#define HW_PXP_HIST2_PARAM (0x000002a0)
+
+#define BP_PXP_HIST2_PARAM_RSVD 16
+#define BM_PXP_HIST2_PARAM_RSVD 0xFFFF0000
+#define BF_PXP_HIST2_PARAM_RSVD(v) \
+ (((v) << 16) & BM_PXP_HIST2_PARAM_RSVD)
+#define BP_PXP_HIST2_PARAM_RSVD1 13
+#define BM_PXP_HIST2_PARAM_RSVD1 0x0000E000
+#define BF_PXP_HIST2_PARAM_RSVD1(v) \
+ (((v) << 13) & BM_PXP_HIST2_PARAM_RSVD1)
+#define BP_PXP_HIST2_PARAM_VALUE1 8
+#define BM_PXP_HIST2_PARAM_VALUE1 0x00001F00
+#define BF_PXP_HIST2_PARAM_VALUE1(v) \
+ (((v) << 8) & BM_PXP_HIST2_PARAM_VALUE1)
+#define BP_PXP_HIST2_PARAM_RSVD0 5
+#define BM_PXP_HIST2_PARAM_RSVD0 0x000000E0
+#define BF_PXP_HIST2_PARAM_RSVD0(v) \
+ (((v) << 5) & BM_PXP_HIST2_PARAM_RSVD0)
+#define BP_PXP_HIST2_PARAM_VALUE0 0
+#define BM_PXP_HIST2_PARAM_VALUE0 0x0000001F
+#define BF_PXP_HIST2_PARAM_VALUE0(v) \
+ (((v) << 0) & BM_PXP_HIST2_PARAM_VALUE0)
+
+#define HW_PXP_HIST4_PARAM (0x000002b0)
+
+#define BP_PXP_HIST4_PARAM_RSVD3 29
+#define BM_PXP_HIST4_PARAM_RSVD3 0xE0000000
+#define BF_PXP_HIST4_PARAM_RSVD3(v) \
+ (((v) << 29) & BM_PXP_HIST4_PARAM_RSVD3)
+#define BP_PXP_HIST4_PARAM_VALUE3 24
+#define BM_PXP_HIST4_PARAM_VALUE3 0x1F000000
+#define BF_PXP_HIST4_PARAM_VALUE3(v) \
+ (((v) << 24) & BM_PXP_HIST4_PARAM_VALUE3)
+#define BP_PXP_HIST4_PARAM_RSVD2 21
+#define BM_PXP_HIST4_PARAM_RSVD2 0x00E00000
+#define BF_PXP_HIST4_PARAM_RSVD2(v) \
+ (((v) << 21) & BM_PXP_HIST4_PARAM_RSVD2)
+#define BP_PXP_HIST4_PARAM_VALUE2 16
+#define BM_PXP_HIST4_PARAM_VALUE2 0x001F0000
+#define BF_PXP_HIST4_PARAM_VALUE2(v) \
+ (((v) << 16) & BM_PXP_HIST4_PARAM_VALUE2)
+#define BP_PXP_HIST4_PARAM_RSVD1 13
+#define BM_PXP_HIST4_PARAM_RSVD1 0x0000E000
+#define BF_PXP_HIST4_PARAM_RSVD1(v) \
+ (((v) << 13) & BM_PXP_HIST4_PARAM_RSVD1)
+#define BP_PXP_HIST4_PARAM_VALUE1 8
+#define BM_PXP_HIST4_PARAM_VALUE1 0x00001F00
+#define BF_PXP_HIST4_PARAM_VALUE1(v) \
+ (((v) << 8) & BM_PXP_HIST4_PARAM_VALUE1)
+#define BP_PXP_HIST4_PARAM_RSVD0 5
+#define BM_PXP_HIST4_PARAM_RSVD0 0x000000E0
+#define BF_PXP_HIST4_PARAM_RSVD0(v) \
+ (((v) << 5) & BM_PXP_HIST4_PARAM_RSVD0)
+#define BP_PXP_HIST4_PARAM_VALUE0 0
+#define BM_PXP_HIST4_PARAM_VALUE0 0x0000001F
+#define BF_PXP_HIST4_PARAM_VALUE0(v) \
+ (((v) << 0) & BM_PXP_HIST4_PARAM_VALUE0)
+
+#define HW_PXP_HIST8_PARAM0 (0x000002c0)
+
+#define BP_PXP_HIST8_PARAM0_RSVD3 29
+#define BM_PXP_HIST8_PARAM0_RSVD3 0xE0000000
+#define BF_PXP_HIST8_PARAM0_RSVD3(v) \
+ (((v) << 29) & BM_PXP_HIST8_PARAM0_RSVD3)
+#define BP_PXP_HIST8_PARAM0_VALUE3 24
+#define BM_PXP_HIST8_PARAM0_VALUE3 0x1F000000
+#define BF_PXP_HIST8_PARAM0_VALUE3(v) \
+ (((v) << 24) & BM_PXP_HIST8_PARAM0_VALUE3)
+#define BP_PXP_HIST8_PARAM0_RSVD2 21
+#define BM_PXP_HIST8_PARAM0_RSVD2 0x00E00000
+#define BF_PXP_HIST8_PARAM0_RSVD2(v) \
+ (((v) << 21) & BM_PXP_HIST8_PARAM0_RSVD2)
+#define BP_PXP_HIST8_PARAM0_VALUE2 16
+#define BM_PXP_HIST8_PARAM0_VALUE2 0x001F0000
+#define BF_PXP_HIST8_PARAM0_VALUE2(v) \
+ (((v) << 16) & BM_PXP_HIST8_PARAM0_VALUE2)
+#define BP_PXP_HIST8_PARAM0_RSVD1 13
+#define BM_PXP_HIST8_PARAM0_RSVD1 0x0000E000
+#define BF_PXP_HIST8_PARAM0_RSVD1(v) \
+ (((v) << 13) & BM_PXP_HIST8_PARAM0_RSVD1)
+#define BP_PXP_HIST8_PARAM0_VALUE1 8
+#define BM_PXP_HIST8_PARAM0_VALUE1 0x00001F00
+#define BF_PXP_HIST8_PARAM0_VALUE1(v) \
+ (((v) << 8) & BM_PXP_HIST8_PARAM0_VALUE1)
+#define BP_PXP_HIST8_PARAM0_RSVD0 5
+#define BM_PXP_HIST8_PARAM0_RSVD0 0x000000E0
+#define BF_PXP_HIST8_PARAM0_RSVD0(v) \
+ (((v) << 5) & BM_PXP_HIST8_PARAM0_RSVD0)
+#define BP_PXP_HIST8_PARAM0_VALUE0 0
+#define BM_PXP_HIST8_PARAM0_VALUE0 0x0000001F
+#define BF_PXP_HIST8_PARAM0_VALUE0(v) \
+ (((v) << 0) & BM_PXP_HIST8_PARAM0_VALUE0)
+
+#define HW_PXP_HIST8_PARAM1 (0x000002d0)
+
+#define BP_PXP_HIST8_PARAM1_RSVD7 29
+#define BM_PXP_HIST8_PARAM1_RSVD7 0xE0000000
+#define BF_PXP_HIST8_PARAM1_RSVD7(v) \
+ (((v) << 29) & BM_PXP_HIST8_PARAM1_RSVD7)
+#define BP_PXP_HIST8_PARAM1_VALUE7 24
+#define BM_PXP_HIST8_PARAM1_VALUE7 0x1F000000
+#define BF_PXP_HIST8_PARAM1_VALUE7(v) \
+ (((v) << 24) & BM_PXP_HIST8_PARAM1_VALUE7)
+#define BP_PXP_HIST8_PARAM1_RSVD6 21
+#define BM_PXP_HIST8_PARAM1_RSVD6 0x00E00000
+#define BF_PXP_HIST8_PARAM1_RSVD6(v) \
+ (((v) << 21) & BM_PXP_HIST8_PARAM1_RSVD6)
+#define BP_PXP_HIST8_PARAM1_VALUE6 16
+#define BM_PXP_HIST8_PARAM1_VALUE6 0x001F0000
+#define BF_PXP_HIST8_PARAM1_VALUE6(v) \
+ (((v) << 16) & BM_PXP_HIST8_PARAM1_VALUE6)
+#define BP_PXP_HIST8_PARAM1_RSVD5 13
+#define BM_PXP_HIST8_PARAM1_RSVD5 0x0000E000
+#define BF_PXP_HIST8_PARAM1_RSVD5(v) \
+ (((v) << 13) & BM_PXP_HIST8_PARAM1_RSVD5)
+#define BP_PXP_HIST8_PARAM1_VALUE5 8
+#define BM_PXP_HIST8_PARAM1_VALUE5 0x00001F00
+#define BF_PXP_HIST8_PARAM1_VALUE5(v) \
+ (((v) << 8) & BM_PXP_HIST8_PARAM1_VALUE5)
+#define BP_PXP_HIST8_PARAM1_RSVD4 5
+#define BM_PXP_HIST8_PARAM1_RSVD4 0x000000E0
+#define BF_PXP_HIST8_PARAM1_RSVD4(v) \
+ (((v) << 5) & BM_PXP_HIST8_PARAM1_RSVD4)
+#define BP_PXP_HIST8_PARAM1_VALUE4 0
+#define BM_PXP_HIST8_PARAM1_VALUE4 0x0000001F
+#define BF_PXP_HIST8_PARAM1_VALUE4(v) \
+ (((v) << 0) & BM_PXP_HIST8_PARAM1_VALUE4)
+
+#define HW_PXP_HIST16_PARAM0 (0x000002e0)
+
+#define BP_PXP_HIST16_PARAM0_RSVD3 29
+#define BM_PXP_HIST16_PARAM0_RSVD3 0xE0000000
+#define BF_PXP_HIST16_PARAM0_RSVD3(v) \
+ (((v) << 29) & BM_PXP_HIST16_PARAM0_RSVD3)
+#define BP_PXP_HIST16_PARAM0_VALUE3 24
+#define BM_PXP_HIST16_PARAM0_VALUE3 0x1F000000
+#define BF_PXP_HIST16_PARAM0_VALUE3(v) \
+ (((v) << 24) & BM_PXP_HIST16_PARAM0_VALUE3)
+#define BP_PXP_HIST16_PARAM0_RSVD2 21
+#define BM_PXP_HIST16_PARAM0_RSVD2 0x00E00000
+#define BF_PXP_HIST16_PARAM0_RSVD2(v) \
+ (((v) << 21) & BM_PXP_HIST16_PARAM0_RSVD2)
+#define BP_PXP_HIST16_PARAM0_VALUE2 16
+#define BM_PXP_HIST16_PARAM0_VALUE2 0x001F0000
+#define BF_PXP_HIST16_PARAM0_VALUE2(v) \
+ (((v) << 16) & BM_PXP_HIST16_PARAM0_VALUE2)
+#define BP_PXP_HIST16_PARAM0_RSVD1 13
+#define BM_PXP_HIST16_PARAM0_RSVD1 0x0000E000
+#define BF_PXP_HIST16_PARAM0_RSVD1(v) \
+ (((v) << 13) & BM_PXP_HIST16_PARAM0_RSVD1)
+#define BP_PXP_HIST16_PARAM0_VALUE1 8
+#define BM_PXP_HIST16_PARAM0_VALUE1 0x00001F00
+#define BF_PXP_HIST16_PARAM0_VALUE1(v) \
+ (((v) << 8) & BM_PXP_HIST16_PARAM0_VALUE1)
+#define BP_PXP_HIST16_PARAM0_RSVD0 5
+#define BM_PXP_HIST16_PARAM0_RSVD0 0x000000E0
+#define BF_PXP_HIST16_PARAM0_RSVD0(v) \
+ (((v) << 5) & BM_PXP_HIST16_PARAM0_RSVD0)
+#define BP_PXP_HIST16_PARAM0_VALUE0 0
+#define BM_PXP_HIST16_PARAM0_VALUE0 0x0000001F
+#define BF_PXP_HIST16_PARAM0_VALUE0(v) \
+ (((v) << 0) & BM_PXP_HIST16_PARAM0_VALUE0)
+
+#define HW_PXP_HIST16_PARAM1 (0x000002f0)
+
+#define BP_PXP_HIST16_PARAM1_RSVD7 29
+#define BM_PXP_HIST16_PARAM1_RSVD7 0xE0000000
+#define BF_PXP_HIST16_PARAM1_RSVD7(v) \
+ (((v) << 29) & BM_PXP_HIST16_PARAM1_RSVD7)
+#define BP_PXP_HIST16_PARAM1_VALUE7 24
+#define BM_PXP_HIST16_PARAM1_VALUE7 0x1F000000
+#define BF_PXP_HIST16_PARAM1_VALUE7(v) \
+ (((v) << 24) & BM_PXP_HIST16_PARAM1_VALUE7)
+#define BP_PXP_HIST16_PARAM1_RSVD6 21
+#define BM_PXP_HIST16_PARAM1_RSVD6 0x00E00000
+#define BF_PXP_HIST16_PARAM1_RSVD6(v) \
+ (((v) << 21) & BM_PXP_HIST16_PARAM1_RSVD6)
+#define BP_PXP_HIST16_PARAM1_VALUE6 16
+#define BM_PXP_HIST16_PARAM1_VALUE6 0x001F0000
+#define BF_PXP_HIST16_PARAM1_VALUE6(v) \
+ (((v) << 16) & BM_PXP_HIST16_PARAM1_VALUE6)
+#define BP_PXP_HIST16_PARAM1_RSVD5 13
+#define BM_PXP_HIST16_PARAM1_RSVD5 0x0000E000
+#define BF_PXP_HIST16_PARAM1_RSVD5(v) \
+ (((v) << 13) & BM_PXP_HIST16_PARAM1_RSVD5)
+#define BP_PXP_HIST16_PARAM1_VALUE5 8
+#define BM_PXP_HIST16_PARAM1_VALUE5 0x00001F00
+#define BF_PXP_HIST16_PARAM1_VALUE5(v) \
+ (((v) << 8) & BM_PXP_HIST16_PARAM1_VALUE5)
+#define BP_PXP_HIST16_PARAM1_RSVD4 5
+#define BM_PXP_HIST16_PARAM1_RSVD4 0x000000E0
+#define BF_PXP_HIST16_PARAM1_RSVD4(v) \
+ (((v) << 5) & BM_PXP_HIST16_PARAM1_RSVD4)
+#define BP_PXP_HIST16_PARAM1_VALUE4 0
+#define BM_PXP_HIST16_PARAM1_VALUE4 0x0000001F
+#define BF_PXP_HIST16_PARAM1_VALUE4(v) \
+ (((v) << 0) & BM_PXP_HIST16_PARAM1_VALUE4)
+
+#define HW_PXP_HIST16_PARAM2 (0x00000300)
+
+#define BP_PXP_HIST16_PARAM2_RSVD11 29
+#define BM_PXP_HIST16_PARAM2_RSVD11 0xE0000000
+#define BF_PXP_HIST16_PARAM2_RSVD11(v) \
+ (((v) << 29) & BM_PXP_HIST16_PARAM2_RSVD11)
+#define BP_PXP_HIST16_PARAM2_VALUE11 24
+#define BM_PXP_HIST16_PARAM2_VALUE11 0x1F000000
+#define BF_PXP_HIST16_PARAM2_VALUE11(v) \
+ (((v) << 24) & BM_PXP_HIST16_PARAM2_VALUE11)
+#define BP_PXP_HIST16_PARAM2_RSVD10 21
+#define BM_PXP_HIST16_PARAM2_RSVD10 0x00E00000
+#define BF_PXP_HIST16_PARAM2_RSVD10(v) \
+ (((v) << 21) & BM_PXP_HIST16_PARAM2_RSVD10)
+#define BP_PXP_HIST16_PARAM2_VALUE10 16
+#define BM_PXP_HIST16_PARAM2_VALUE10 0x001F0000
+#define BF_PXP_HIST16_PARAM2_VALUE10(v) \
+ (((v) << 16) & BM_PXP_HIST16_PARAM2_VALUE10)
+#define BP_PXP_HIST16_PARAM2_RSVD9 13
+#define BM_PXP_HIST16_PARAM2_RSVD9 0x0000E000
+#define BF_PXP_HIST16_PARAM2_RSVD9(v) \
+ (((v) << 13) & BM_PXP_HIST16_PARAM2_RSVD9)
+#define BP_PXP_HIST16_PARAM2_VALUE9 8
+#define BM_PXP_HIST16_PARAM2_VALUE9 0x00001F00
+#define BF_PXP_HIST16_PARAM2_VALUE9(v) \
+ (((v) << 8) & BM_PXP_HIST16_PARAM2_VALUE9)
+#define BP_PXP_HIST16_PARAM2_RSVD8 5
+#define BM_PXP_HIST16_PARAM2_RSVD8 0x000000E0
+#define BF_PXP_HIST16_PARAM2_RSVD8(v) \
+ (((v) << 5) & BM_PXP_HIST16_PARAM2_RSVD8)
+#define BP_PXP_HIST16_PARAM2_VALUE8 0
+#define BM_PXP_HIST16_PARAM2_VALUE8 0x0000001F
+#define BF_PXP_HIST16_PARAM2_VALUE8(v) \
+ (((v) << 0) & BM_PXP_HIST16_PARAM2_VALUE8)
+
+#define HW_PXP_HIST16_PARAM3 (0x00000310)
+
+#define BP_PXP_HIST16_PARAM3_RSVD15 29
+#define BM_PXP_HIST16_PARAM3_RSVD15 0xE0000000
+#define BF_PXP_HIST16_PARAM3_RSVD15(v) \
+ (((v) << 29) & BM_PXP_HIST16_PARAM3_RSVD15)
+#define BP_PXP_HIST16_PARAM3_VALUE15 24
+#define BM_PXP_HIST16_PARAM3_VALUE15 0x1F000000
+#define BF_PXP_HIST16_PARAM3_VALUE15(v) \
+ (((v) << 24) & BM_PXP_HIST16_PARAM3_VALUE15)
+#define BP_PXP_HIST16_PARAM3_RSVD14 21
+#define BM_PXP_HIST16_PARAM3_RSVD14 0x00E00000
+#define BF_PXP_HIST16_PARAM3_RSVD14(v) \
+ (((v) << 21) & BM_PXP_HIST16_PARAM3_RSVD14)
+#define BP_PXP_HIST16_PARAM3_VALUE14 16
+#define BM_PXP_HIST16_PARAM3_VALUE14 0x001F0000
+#define BF_PXP_HIST16_PARAM3_VALUE14(v) \
+ (((v) << 16) & BM_PXP_HIST16_PARAM3_VALUE14)
+#define BP_PXP_HIST16_PARAM3_RSVD13 13
+#define BM_PXP_HIST16_PARAM3_RSVD13 0x0000E000
+#define BF_PXP_HIST16_PARAM3_RSVD13(v) \
+ (((v) << 13) & BM_PXP_HIST16_PARAM3_RSVD13)
+#define BP_PXP_HIST16_PARAM3_VALUE13 8
+#define BM_PXP_HIST16_PARAM3_VALUE13 0x00001F00
+#define BF_PXP_HIST16_PARAM3_VALUE13(v) \
+ (((v) << 8) & BM_PXP_HIST16_PARAM3_VALUE13)
+#define BP_PXP_HIST16_PARAM3_RSVD12 5
+#define BM_PXP_HIST16_PARAM3_RSVD12 0x000000E0
+#define BF_PXP_HIST16_PARAM3_RSVD12(v) \
+ (((v) << 5) & BM_PXP_HIST16_PARAM3_RSVD12)
+#define BP_PXP_HIST16_PARAM3_VALUE12 0
+#define BM_PXP_HIST16_PARAM3_VALUE12 0x0000001F
+#define BF_PXP_HIST16_PARAM3_VALUE12(v) \
+ (((v) << 0) & BM_PXP_HIST16_PARAM3_VALUE12)
+
+#define HW_PXP_POWER (0x00000320)
+
+#define BP_PXP_POWER_CTRL 12
+#define BM_PXP_POWER_CTRL 0xFFFFF000
+#define BF_PXP_POWER_CTRL(v) \
+ (((v) << 12) & BM_PXP_POWER_CTRL)
+#define BP_PXP_POWER_ROT_MEM_LP_STATE 9
+#define BM_PXP_POWER_ROT_MEM_LP_STATE 0x00000E00
+#define BF_PXP_POWER_ROT_MEM_LP_STATE(v) \
+ (((v) << 9) & BM_PXP_POWER_ROT_MEM_LP_STATE)
+#define BV_PXP_POWER_ROT_MEM_LP_STATE__NONE 0x0
+#define BV_PXP_POWER_ROT_MEM_LP_STATE__LS 0x1
+#define BV_PXP_POWER_ROT_MEM_LP_STATE__DS 0x2
+#define BV_PXP_POWER_ROT_MEM_LP_STATE__SD 0x4
+#define BP_PXP_POWER_LUT_LP_STATE_WAY1_BANKN 6
+#define BM_PXP_POWER_LUT_LP_STATE_WAY1_BANKN 0x000001C0
+#define BF_PXP_POWER_LUT_LP_STATE_WAY1_BANKN(v) \
+ (((v) << 6) & BM_PXP_POWER_LUT_LP_STATE_WAY1_BANKN)
+#define BV_PXP_POWER_LUT_LP_STATE_WAY1_BANKN__NONE 0x0
+#define BV_PXP_POWER_LUT_LP_STATE_WAY1_BANKN__LS 0x1
+#define BV_PXP_POWER_LUT_LP_STATE_WAY1_BANKN__DS 0x2
+#define BV_PXP_POWER_LUT_LP_STATE_WAY1_BANKN__SD 0x4
+#define BP_PXP_POWER_LUT_LP_STATE_WAY0_BANKN 3
+#define BM_PXP_POWER_LUT_LP_STATE_WAY0_BANKN 0x00000038
+#define BF_PXP_POWER_LUT_LP_STATE_WAY0_BANKN(v) \
+ (((v) << 3) & BM_PXP_POWER_LUT_LP_STATE_WAY0_BANKN)
+#define BV_PXP_POWER_LUT_LP_STATE_WAY0_BANKN__NONE 0x0
+#define BV_PXP_POWER_LUT_LP_STATE_WAY0_BANKN__LS 0x1
+#define BV_PXP_POWER_LUT_LP_STATE_WAY0_BANKN__DS 0x2
+#define BV_PXP_POWER_LUT_LP_STATE_WAY0_BANKN__SD 0x4
+#define BP_PXP_POWER_LUT_LP_STATE_WAY0_BANK0 0
+#define BM_PXP_POWER_LUT_LP_STATE_WAY0_BANK0 0x00000007
+#define BF_PXP_POWER_LUT_LP_STATE_WAY0_BANK0(v) \
+ (((v) << 0) & BM_PXP_POWER_LUT_LP_STATE_WAY0_BANK0)
+#define BV_PXP_POWER_LUT_LP_STATE_WAY0_BANK0__NONE 0x0
+#define BV_PXP_POWER_LUT_LP_STATE_WAY0_BANK0__LS 0x1
+#define BV_PXP_POWER_LUT_LP_STATE_WAY0_BANK0__DS 0x2
+#define BV_PXP_POWER_LUT_LP_STATE_WAY0_BANK0__SD 0x4
+
+#define HW_PXP_NEXT (0x00000400)
+
+#define BP_PXP_NEXT_POINTER 2
+#define BM_PXP_NEXT_POINTER 0xFFFFFFFC
+#define BF_PXP_NEXT_POINTER(v) \
+ (((v) << 2) & BM_PXP_NEXT_POINTER)
+#define BM_PXP_NEXT_RSVD 0x00000002
+#define BM_PXP_NEXT_ENABLED 0x00000001
+
+#define HW_PXP_DEBUGCTRL (0x00000410)
+
+#define BP_PXP_DEBUGCTRL_RSVD 12
+#define BM_PXP_DEBUGCTRL_RSVD 0xFFFFF000
+#define BF_PXP_DEBUGCTRL_RSVD(v) \
+ (((v) << 12) & BM_PXP_DEBUGCTRL_RSVD)
+#define BP_PXP_DEBUGCTRL_LUT_CLR_STAT_CNT 8
+#define BM_PXP_DEBUGCTRL_LUT_CLR_STAT_CNT 0x00000F00
+#define BF_PXP_DEBUGCTRL_LUT_CLR_STAT_CNT(v) \
+ (((v) << 8) & BM_PXP_DEBUGCTRL_LUT_CLR_STAT_CNT)
+#define BV_PXP_DEBUGCTRL_LUT_CLR_STAT_CNT__NONE 0x0
+#define BV_PXP_DEBUGCTRL_LUT_CLR_STAT_CNT__MISS_CNT 0x1
+#define BV_PXP_DEBUGCTRL_LUT_CLR_STAT_CNT__HIT_CNT 0x2
+#define BV_PXP_DEBUGCTRL_LUT_CLR_STAT_CNT__LAT_CNT 0x4
+#define BV_PXP_DEBUGCTRL_LUT_CLR_STAT_CNT__MAX_LAT 0x8
+#define BP_PXP_DEBUGCTRL_SELECT 0
+#define BM_PXP_DEBUGCTRL_SELECT 0x000000FF
+#define BF_PXP_DEBUGCTRL_SELECT(v) \
+ (((v) << 0) & BM_PXP_DEBUGCTRL_SELECT)
+#define BV_PXP_DEBUGCTRL_SELECT__NONE 0x0
+#define BV_PXP_DEBUGCTRL_SELECT__CTRL 0x1
+#define BV_PXP_DEBUGCTRL_SELECT__PSBUF 0x2
+#define BV_PXP_DEBUGCTRL_SELECT__PSBAX 0x3
+#define BV_PXP_DEBUGCTRL_SELECT__PSBAY 0x4
+#define BV_PXP_DEBUGCTRL_SELECT__ASBUF 0x5
+#define BV_PXP_DEBUGCTRL_SELECT__ROTATION 0x6
+#define BV_PXP_DEBUGCTRL_SELECT__OUTBUF0 0x7
+#define BV_PXP_DEBUGCTRL_SELECT__OUTBUF1 0x8
+#define BV_PXP_DEBUGCTRL_SELECT__OUTBUF2 0x9
+#define BV_PXP_DEBUGCTRL_SELECT__LUT_STAT 0x10
+#define BV_PXP_DEBUGCTRL_SELECT__LUT_MISS 0x11
+#define BV_PXP_DEBUGCTRL_SELECT__LUT_HIT 0x12
+#define BV_PXP_DEBUGCTRL_SELECT__LUT_LAT 0x13
+#define BV_PXP_DEBUGCTRL_SELECT__LUT_MAX_LAT 0x14
+
+#define HW_PXP_DEBUG (0x00000420)
+
+#define BP_PXP_DEBUG_DATA 0
+#define BM_PXP_DEBUG_DATA 0xFFFFFFFF
+#define BF_PXP_DEBUG_DATA(v) (v)
+
+#define HW_PXP_VERSION (0x00000430)
+
+#define BP_PXP_VERSION_MAJOR 24
+#define BM_PXP_VERSION_MAJOR 0xFF000000
+#define BF_PXP_VERSION_MAJOR(v) \
+ (((v) << 24) & BM_PXP_VERSION_MAJOR)
+#define BP_PXP_VERSION_MINOR 16
+#define BM_PXP_VERSION_MINOR 0x00FF0000
+#define BF_PXP_VERSION_MINOR(v) \
+ (((v) << 16) & BM_PXP_VERSION_MINOR)
+#define BP_PXP_VERSION_STEP 0
+#define BM_PXP_VERSION_STEP 0x0000FFFF
+#define BF_PXP_VERSION_STEP(v) \
+ (((v) << 0) & BM_PXP_VERSION_STEP)
+#endif /* __ARCH_ARM___PXP_H */
diff --git a/drivers/dma/pxp/regs-pxp_v3.h b/drivers/dma/pxp/regs-pxp_v3.h
new file mode 100644
index 000000000000..80e310bb5ca7
--- /dev/null
+++ b/drivers/dma/pxp/regs-pxp_v3.h
@@ -0,0 +1,26952 @@
+/*
+ * Freescale PXP Register Definitions
+ *
+ * Copyright 2014-2015 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * This file is created by xml file. Don't Edit it.
+ *
+ * Xml Revision: 1.77
+ * Template revision: 1.3
+ */
+
+#ifndef __ARCH_ARM___PXP_H
+#define __ARCH_ARM___PXP_H
+
+
+#define HW_PXP_CTRL (0x00000000)
+#define HW_PXP_CTRL_SET (0x00000004)
+#define HW_PXP_CTRL_CLR (0x00000008)
+#define HW_PXP_CTRL_TOG (0x0000000c)
+
+#define BM_PXP_CTRL_SFTRST 0x80000000
+#define BF_PXP_CTRL_SFTRST(v) \
+ (((v) << 31) & BM_PXP_CTRL_SFTRST)
+#define BM_PXP_CTRL_CLKGATE 0x40000000
+#define BF_PXP_CTRL_CLKGATE(v) \
+ (((v) << 30) & BM_PXP_CTRL_CLKGATE)
+#define BM_PXP_CTRL_RSVD4 0x20000000
+#define BF_PXP_CTRL_RSVD4(v) \
+ (((v) << 29) & BM_PXP_CTRL_RSVD4)
+#define BM_PXP_CTRL_EN_REPEAT 0x10000000
+#define BF_PXP_CTRL_EN_REPEAT(v) \
+ (((v) << 28) & BM_PXP_CTRL_EN_REPEAT)
+#define BM_PXP_CTRL_ENABLE_ROTATE1 0x08000000
+#define BF_PXP_CTRL_ENABLE_ROTATE1(v) \
+ (((v) << 27) & BM_PXP_CTRL_ENABLE_ROTATE1)
+#define BM_PXP_CTRL_ENABLE_ROTATE0 0x04000000
+#define BF_PXP_CTRL_ENABLE_ROTATE0(v) \
+ (((v) << 26) & BM_PXP_CTRL_ENABLE_ROTATE0)
+#define BM_PXP_CTRL_ENABLE_LUT 0x02000000
+#define BF_PXP_CTRL_ENABLE_LUT(v) \
+ (((v) << 25) & BM_PXP_CTRL_ENABLE_LUT)
+#define BM_PXP_CTRL_ENABLE_CSC2 0x01000000
+#define BF_PXP_CTRL_ENABLE_CSC2(v) \
+ (((v) << 24) & BM_PXP_CTRL_ENABLE_CSC2)
+#define BM_PXP_CTRL_BLOCK_SIZE 0x00800000
+#define BF_PXP_CTRL_BLOCK_SIZE(v) \
+ (((v) << 23) & BM_PXP_CTRL_BLOCK_SIZE)
+#define BV_PXP_CTRL_BLOCK_SIZE__8X8 0x0
+#define BV_PXP_CTRL_BLOCK_SIZE__16X16 0x1
+#define BM_PXP_CTRL_RSVD1 0x00400000
+#define BF_PXP_CTRL_RSVD1(v) \
+ (((v) << 22) & BM_PXP_CTRL_RSVD1)
+#define BM_PXP_CTRL_ENABLE_ALPHA_B 0x00200000
+#define BF_PXP_CTRL_ENABLE_ALPHA_B(v) \
+ (((v) << 21) & BM_PXP_CTRL_ENABLE_ALPHA_B)
+#define BM_PXP_CTRL_ENABLE_INPUT_FETCH_STORE 0x00100000
+#define BF_PXP_CTRL_ENABLE_INPUT_FETCH_STORE(v) \
+ (((v) << 20) & BM_PXP_CTRL_ENABLE_INPUT_FETCH_STORE)
+#define BM_PXP_CTRL_ENABLE_WFE_B 0x00080000
+#define BF_PXP_CTRL_ENABLE_WFE_B(v) \
+ (((v) << 19) & BM_PXP_CTRL_ENABLE_WFE_B)
+#define BM_PXP_CTRL_ENABLE_WFE_A 0x00040000
+#define BF_PXP_CTRL_ENABLE_WFE_A(v) \
+ (((v) << 18) & BM_PXP_CTRL_ENABLE_WFE_A)
+#define BM_PXP_CTRL_ENABLE_DITHER 0x00020000
+#define BF_PXP_CTRL_ENABLE_DITHER(v) \
+ (((v) << 17) & BM_PXP_CTRL_ENABLE_DITHER)
+#define BM_PXP_CTRL_ENABLE_PS_AS_OUT 0x00010000
+#define BF_PXP_CTRL_ENABLE_PS_AS_OUT(v) \
+ (((v) << 16) & BM_PXP_CTRL_ENABLE_PS_AS_OUT)
+#define BM_PXP_CTRL_VFLIP1 0x00008000
+#define BF_PXP_CTRL_VFLIP1(v) \
+ (((v) << 15) & BM_PXP_CTRL_VFLIP1)
+#define BM_PXP_CTRL_HFLIP1 0x00004000
+#define BF_PXP_CTRL_HFLIP1(v) \
+ (((v) << 14) & BM_PXP_CTRL_HFLIP1)
+#define BP_PXP_CTRL_ROTATE1 12
+#define BM_PXP_CTRL_ROTATE1 0x00003000
+#define BF_PXP_CTRL_ROTATE1(v) \
+ (((v) << 12) & BM_PXP_CTRL_ROTATE1)
+#define BV_PXP_CTRL_ROTATE1__ROT_0 0x0
+#define BV_PXP_CTRL_ROTATE1__ROT_90 0x1
+#define BV_PXP_CTRL_ROTATE1__ROT_180 0x2
+#define BV_PXP_CTRL_ROTATE1__ROT_270 0x3
+#define BM_PXP_CTRL_VFLIP0 0x00000800
+#define BF_PXP_CTRL_VFLIP0(v) \
+ (((v) << 11) & BM_PXP_CTRL_VFLIP0)
+#define BM_PXP_CTRL_HFLIP0 0x00000400
+#define BF_PXP_CTRL_HFLIP0(v) \
+ (((v) << 10) & BM_PXP_CTRL_HFLIP0)
+#define BP_PXP_CTRL_ROTATE0 8
+#define BM_PXP_CTRL_ROTATE0 0x00000300
+#define BF_PXP_CTRL_ROTATE0(v) \
+ (((v) << 8) & BM_PXP_CTRL_ROTATE0)
+#define BV_PXP_CTRL_ROTATE0__ROT_0 0x0
+#define BV_PXP_CTRL_ROTATE0__ROT_90 0x1
+#define BV_PXP_CTRL_ROTATE0__ROT_180 0x2
+#define BV_PXP_CTRL_ROTATE0__ROT_270 0x3
+#define BP_PXP_CTRL_RSVD0 6
+#define BM_PXP_CTRL_RSVD0 0x000000C0
+#define BF_PXP_CTRL_RSVD0(v) \
+ (((v) << 6) & BM_PXP_CTRL_RSVD0)
+#define BM_PXP_CTRL_HANDSHAKE_ABORT_SKIP 0x00000020
+#define BF_PXP_CTRL_HANDSHAKE_ABORT_SKIP(v) \
+ (((v) << 5) & BM_PXP_CTRL_HANDSHAKE_ABORT_SKIP)
+#define BM_PXP_CTRL_ENABLE_LCD0_HANDSHAKE 0x00000010
+#define BF_PXP_CTRL_ENABLE_LCD0_HANDSHAKE(v) \
+ (((v) << 4) & BM_PXP_CTRL_ENABLE_LCD0_HANDSHAKE)
+#define BM_PXP_CTRL_LUT_DMA_IRQ_ENABLE 0x00000008
+#define BF_PXP_CTRL_LUT_DMA_IRQ_ENABLE(v) \
+ (((v) << 3) & BM_PXP_CTRL_LUT_DMA_IRQ_ENABLE)
+#define BM_PXP_CTRL_NEXT_IRQ_ENABLE 0x00000004
+#define BF_PXP_CTRL_NEXT_IRQ_ENABLE(v) \
+ (((v) << 2) & BM_PXP_CTRL_NEXT_IRQ_ENABLE)
+#define BM_PXP_CTRL_IRQ_ENABLE 0x00000002
+#define BF_PXP_CTRL_IRQ_ENABLE(v) \
+ (((v) << 1) & BM_PXP_CTRL_IRQ_ENABLE)
+#define BM_PXP_CTRL_ENABLE 0x00000001
+#define BF_PXP_CTRL_ENABLE(v) \
+ (((v) << 0) & BM_PXP_CTRL_ENABLE)
+
+#define HW_PXP_STAT (0x00000010)
+#define HW_PXP_STAT_SET (0x00000014)
+#define HW_PXP_STAT_CLR (0x00000018)
+#define HW_PXP_STAT_TOG (0x0000001c)
+
+#define BP_PXP_STAT_BLOCKX 24
+#define BM_PXP_STAT_BLOCKX 0xFF000000
+#define BF_PXP_STAT_BLOCKX(v) \
+ (((v) << 24) & BM_PXP_STAT_BLOCKX)
+#define BP_PXP_STAT_BLOCKY 16
+#define BM_PXP_STAT_BLOCKY 0x00FF0000
+#define BF_PXP_STAT_BLOCKY(v) \
+ (((v) << 16) & BM_PXP_STAT_BLOCKY)
+#define BP_PXP_STAT_AXI_ERROR_ID_1 12
+#define BM_PXP_STAT_AXI_ERROR_ID_1 0x0000F000
+#define BF_PXP_STAT_AXI_ERROR_ID_1(v) \
+ (((v) << 12) & BM_PXP_STAT_AXI_ERROR_ID_1)
+#define BM_PXP_STAT_RSVD2 0x00000800
+#define BF_PXP_STAT_RSVD2(v) \
+ (((v) << 11) & BM_PXP_STAT_RSVD2)
+#define BM_PXP_STAT_AXI_READ_ERROR_1 0x00000400
+#define BF_PXP_STAT_AXI_READ_ERROR_1(v) \
+ (((v) << 10) & BM_PXP_STAT_AXI_READ_ERROR_1)
+#define BM_PXP_STAT_AXI_WRITE_ERROR_1 0x00000200
+#define BF_PXP_STAT_AXI_WRITE_ERROR_1(v) \
+ (((v) << 9) & BM_PXP_STAT_AXI_WRITE_ERROR_1)
+#define BM_PXP_STAT_LUT_DMA_LOAD_DONE_IRQ 0x00000100
+#define BF_PXP_STAT_LUT_DMA_LOAD_DONE_IRQ(v) \
+ (((v) << 8) & BM_PXP_STAT_LUT_DMA_LOAD_DONE_IRQ)
+#define BP_PXP_STAT_AXI_ERROR_ID_0 4
+#define BM_PXP_STAT_AXI_ERROR_ID_0 0x000000F0
+#define BF_PXP_STAT_AXI_ERROR_ID_0(v) \
+ (((v) << 4) & BM_PXP_STAT_AXI_ERROR_ID_0)
+#define BM_PXP_STAT_NEXT_IRQ 0x00000008
+#define BF_PXP_STAT_NEXT_IRQ(v) \
+ (((v) << 3) & BM_PXP_STAT_NEXT_IRQ)
+#define BM_PXP_STAT_AXI_READ_ERROR_0 0x00000004
+#define BF_PXP_STAT_AXI_READ_ERROR_0(v) \
+ (((v) << 2) & BM_PXP_STAT_AXI_READ_ERROR_0)
+#define BM_PXP_STAT_AXI_WRITE_ERROR_0 0x00000002
+#define BF_PXP_STAT_AXI_WRITE_ERROR_0(v) \
+ (((v) << 1) & BM_PXP_STAT_AXI_WRITE_ERROR_0)
+#define BM_PXP_STAT_IRQ0 0x00000001
+#define BF_PXP_STAT_IRQ0(v) \
+ (((v) << 0) & BM_PXP_STAT_IRQ0)
+
+#define HW_PXP_OUT_CTRL (0x00000020)
+#define HW_PXP_OUT_CTRL_SET (0x00000024)
+#define HW_PXP_OUT_CTRL_CLR (0x00000028)
+#define HW_PXP_OUT_CTRL_TOG (0x0000002c)
+
+#define BP_PXP_OUT_CTRL_ALPHA 24
+#define BM_PXP_OUT_CTRL_ALPHA 0xFF000000
+#define BF_PXP_OUT_CTRL_ALPHA(v) \
+ (((v) << 24) & BM_PXP_OUT_CTRL_ALPHA)
+#define BM_PXP_OUT_CTRL_ALPHA_OUTPUT 0x00800000
+#define BF_PXP_OUT_CTRL_ALPHA_OUTPUT(v) \
+ (((v) << 23) & BM_PXP_OUT_CTRL_ALPHA_OUTPUT)
+#define BP_PXP_OUT_CTRL_RSVD1 10
+#define BM_PXP_OUT_CTRL_RSVD1 0x007FFC00
+#define BF_PXP_OUT_CTRL_RSVD1(v) \
+ (((v) << 10) & BM_PXP_OUT_CTRL_RSVD1)
+#define BP_PXP_OUT_CTRL_INTERLACED_OUTPUT 8
+#define BM_PXP_OUT_CTRL_INTERLACED_OUTPUT 0x00000300
+#define BF_PXP_OUT_CTRL_INTERLACED_OUTPUT(v) \
+ (((v) << 8) & BM_PXP_OUT_CTRL_INTERLACED_OUTPUT)
+#define BV_PXP_OUT_CTRL_INTERLACED_OUTPUT__PROGRESSIVE 0x0
+#define BV_PXP_OUT_CTRL_INTERLACED_OUTPUT__FIELD0 0x1
+#define BV_PXP_OUT_CTRL_INTERLACED_OUTPUT__FIELD1 0x2
+#define BV_PXP_OUT_CTRL_INTERLACED_OUTPUT__INTERLACED 0x3
+#define BP_PXP_OUT_CTRL_RSVD0 5
+#define BM_PXP_OUT_CTRL_RSVD0 0x000000E0
+#define BF_PXP_OUT_CTRL_RSVD0(v) \
+ (((v) << 5) & BM_PXP_OUT_CTRL_RSVD0)
+#define BP_PXP_OUT_CTRL_FORMAT 0
+#define BM_PXP_OUT_CTRL_FORMAT 0x0000001F
+#define BF_PXP_OUT_CTRL_FORMAT(v) \
+ (((v) << 0) & BM_PXP_OUT_CTRL_FORMAT)
+#define BV_PXP_OUT_CTRL_FORMAT__ARGB8888 0x0
+#define BV_PXP_OUT_CTRL_FORMAT__RGB888 0x4
+#define BV_PXP_OUT_CTRL_FORMAT__RGB888P 0x5
+#define BV_PXP_OUT_CTRL_FORMAT__ARGB1555 0x8
+#define BV_PXP_OUT_CTRL_FORMAT__ARGB4444 0x9
+#define BV_PXP_OUT_CTRL_FORMAT__RGB555 0xC
+#define BV_PXP_OUT_CTRL_FORMAT__RGB444 0xD
+#define BV_PXP_OUT_CTRL_FORMAT__RGB565 0xE
+#define BV_PXP_OUT_CTRL_FORMAT__YUV1P444 0x10
+#define BV_PXP_OUT_CTRL_FORMAT__UYVY1P422 0x12
+#define BV_PXP_OUT_CTRL_FORMAT__VYUY1P422 0x13
+#define BV_PXP_OUT_CTRL_FORMAT__Y8 0x14
+#define BV_PXP_OUT_CTRL_FORMAT__Y4 0x15
+#define BV_PXP_OUT_CTRL_FORMAT__YUV2P422 0x18
+#define BV_PXP_OUT_CTRL_FORMAT__YUV2P420 0x19
+#define BV_PXP_OUT_CTRL_FORMAT__YVU2P422 0x1A
+#define BV_PXP_OUT_CTRL_FORMAT__YVU2P420 0x1B
+
+#define HW_PXP_OUT_BUF (0x00000030)
+
+#define BP_PXP_OUT_BUF_ADDR 0
+#define BM_PXP_OUT_BUF_ADDR 0xFFFFFFFF
+#define BF_PXP_OUT_BUF_ADDR(v) (v)
+
+#define HW_PXP_OUT_BUF2 (0x00000040)
+
+#define BP_PXP_OUT_BUF2_ADDR 0
+#define BM_PXP_OUT_BUF2_ADDR 0xFFFFFFFF
+#define BF_PXP_OUT_BUF2_ADDR(v) (v)
+
+#define HW_PXP_OUT_PITCH (0x00000050)
+
+#define BP_PXP_OUT_PITCH_RSVD 16
+#define BM_PXP_OUT_PITCH_RSVD 0xFFFF0000
+#define BF_PXP_OUT_PITCH_RSVD(v) \
+ (((v) << 16) & BM_PXP_OUT_PITCH_RSVD)
+#define BP_PXP_OUT_PITCH_PITCH 0
+#define BM_PXP_OUT_PITCH_PITCH 0x0000FFFF
+#define BF_PXP_OUT_PITCH_PITCH(v) \
+ (((v) << 0) & BM_PXP_OUT_PITCH_PITCH)
+
+#define HW_PXP_OUT_LRC (0x00000060)
+
+#define BP_PXP_OUT_LRC_RSVD1 30
+#define BM_PXP_OUT_LRC_RSVD1 0xC0000000
+#define BF_PXP_OUT_LRC_RSVD1(v) \
+ (((v) << 30) & BM_PXP_OUT_LRC_RSVD1)
+#define BP_PXP_OUT_LRC_X 16
+#define BM_PXP_OUT_LRC_X 0x3FFF0000
+#define BF_PXP_OUT_LRC_X(v) \
+ (((v) << 16) & BM_PXP_OUT_LRC_X)
+#define BP_PXP_OUT_LRC_RSVD0 14
+#define BM_PXP_OUT_LRC_RSVD0 0x0000C000
+#define BF_PXP_OUT_LRC_RSVD0(v) \
+ (((v) << 14) & BM_PXP_OUT_LRC_RSVD0)
+#define BP_PXP_OUT_LRC_Y 0
+#define BM_PXP_OUT_LRC_Y 0x00003FFF
+#define BF_PXP_OUT_LRC_Y(v) \
+ (((v) << 0) & BM_PXP_OUT_LRC_Y)
+
+#define HW_PXP_OUT_PS_ULC (0x00000070)
+
+#define BP_PXP_OUT_PS_ULC_RSVD1 30
+#define BM_PXP_OUT_PS_ULC_RSVD1 0xC0000000
+#define BF_PXP_OUT_PS_ULC_RSVD1(v) \
+ (((v) << 30) & BM_PXP_OUT_PS_ULC_RSVD1)
+#define BP_PXP_OUT_PS_ULC_X 16
+#define BM_PXP_OUT_PS_ULC_X 0x3FFF0000
+#define BF_PXP_OUT_PS_ULC_X(v) \
+ (((v) << 16) & BM_PXP_OUT_PS_ULC_X)
+#define BP_PXP_OUT_PS_ULC_RSVD0 14
+#define BM_PXP_OUT_PS_ULC_RSVD0 0x0000C000
+#define BF_PXP_OUT_PS_ULC_RSVD0(v) \
+ (((v) << 14) & BM_PXP_OUT_PS_ULC_RSVD0)
+#define BP_PXP_OUT_PS_ULC_Y 0
+#define BM_PXP_OUT_PS_ULC_Y 0x00003FFF
+#define BF_PXP_OUT_PS_ULC_Y(v) \
+ (((v) << 0) & BM_PXP_OUT_PS_ULC_Y)
+
+#define HW_PXP_OUT_PS_LRC (0x00000080)
+
+#define BP_PXP_OUT_PS_LRC_RSVD1 30
+#define BM_PXP_OUT_PS_LRC_RSVD1 0xC0000000
+#define BF_PXP_OUT_PS_LRC_RSVD1(v) \
+ (((v) << 30) & BM_PXP_OUT_PS_LRC_RSVD1)
+#define BP_PXP_OUT_PS_LRC_X 16
+#define BM_PXP_OUT_PS_LRC_X 0x3FFF0000
+#define BF_PXP_OUT_PS_LRC_X(v) \
+ (((v) << 16) & BM_PXP_OUT_PS_LRC_X)
+#define BP_PXP_OUT_PS_LRC_RSVD0 14
+#define BM_PXP_OUT_PS_LRC_RSVD0 0x0000C000
+#define BF_PXP_OUT_PS_LRC_RSVD0(v) \
+ (((v) << 14) & BM_PXP_OUT_PS_LRC_RSVD0)
+#define BP_PXP_OUT_PS_LRC_Y 0
+#define BM_PXP_OUT_PS_LRC_Y 0x00003FFF
+#define BF_PXP_OUT_PS_LRC_Y(v) \
+ (((v) << 0) & BM_PXP_OUT_PS_LRC_Y)
+
+#define HW_PXP_OUT_AS_ULC (0x00000090)
+
+#define BP_PXP_OUT_AS_ULC_RSVD1 30
+#define BM_PXP_OUT_AS_ULC_RSVD1 0xC0000000
+#define BF_PXP_OUT_AS_ULC_RSVD1(v) \
+ (((v) << 30) & BM_PXP_OUT_AS_ULC_RSVD1)
+#define BP_PXP_OUT_AS_ULC_X 16
+#define BM_PXP_OUT_AS_ULC_X 0x3FFF0000
+#define BF_PXP_OUT_AS_ULC_X(v) \
+ (((v) << 16) & BM_PXP_OUT_AS_ULC_X)
+#define BP_PXP_OUT_AS_ULC_RSVD0 14
+#define BM_PXP_OUT_AS_ULC_RSVD0 0x0000C000
+#define BF_PXP_OUT_AS_ULC_RSVD0(v) \
+ (((v) << 14) & BM_PXP_OUT_AS_ULC_RSVD0)
+#define BP_PXP_OUT_AS_ULC_Y 0
+#define BM_PXP_OUT_AS_ULC_Y 0x00003FFF
+#define BF_PXP_OUT_AS_ULC_Y(v) \
+ (((v) << 0) & BM_PXP_OUT_AS_ULC_Y)
+
+#define HW_PXP_OUT_AS_LRC (0x000000a0)
+
+#define BP_PXP_OUT_AS_LRC_RSVD1 30
+#define BM_PXP_OUT_AS_LRC_RSVD1 0xC0000000
+#define BF_PXP_OUT_AS_LRC_RSVD1(v) \
+ (((v) << 30) & BM_PXP_OUT_AS_LRC_RSVD1)
+#define BP_PXP_OUT_AS_LRC_X 16
+#define BM_PXP_OUT_AS_LRC_X 0x3FFF0000
+#define BF_PXP_OUT_AS_LRC_X(v) \
+ (((v) << 16) & BM_PXP_OUT_AS_LRC_X)
+#define BP_PXP_OUT_AS_LRC_RSVD0 14
+#define BM_PXP_OUT_AS_LRC_RSVD0 0x0000C000
+#define BF_PXP_OUT_AS_LRC_RSVD0(v) \
+ (((v) << 14) & BM_PXP_OUT_AS_LRC_RSVD0)
+#define BP_PXP_OUT_AS_LRC_Y 0
+#define BM_PXP_OUT_AS_LRC_Y 0x00003FFF
+#define BF_PXP_OUT_AS_LRC_Y(v) \
+ (((v) << 0) & BM_PXP_OUT_AS_LRC_Y)
+
+#define HW_PXP_PS_CTRL (0x000000b0)
+#define HW_PXP_PS_CTRL_SET (0x000000b4)
+#define HW_PXP_PS_CTRL_CLR (0x000000b8)
+#define HW_PXP_PS_CTRL_TOG (0x000000bc)
+
+#define BP_PXP_PS_CTRL_RSVD1 12
+#define BM_PXP_PS_CTRL_RSVD1 0xFFFFF000
+#define BF_PXP_PS_CTRL_RSVD1(v) \
+ (((v) << 12) & BM_PXP_PS_CTRL_RSVD1)
+#define BP_PXP_PS_CTRL_DECX 10
+#define BM_PXP_PS_CTRL_DECX 0x00000C00
+#define BF_PXP_PS_CTRL_DECX(v) \
+ (((v) << 10) & BM_PXP_PS_CTRL_DECX)
+#define BV_PXP_PS_CTRL_DECX__DISABLE 0x0
+#define BV_PXP_PS_CTRL_DECX__DECX2 0x1
+#define BV_PXP_PS_CTRL_DECX__DECX4 0x2
+#define BV_PXP_PS_CTRL_DECX__DECX8 0x3
+#define BP_PXP_PS_CTRL_DECY 8
+#define BM_PXP_PS_CTRL_DECY 0x00000300
+#define BF_PXP_PS_CTRL_DECY(v) \
+ (((v) << 8) & BM_PXP_PS_CTRL_DECY)
+#define BV_PXP_PS_CTRL_DECY__DISABLE 0x0
+#define BV_PXP_PS_CTRL_DECY__DECY2 0x1
+#define BV_PXP_PS_CTRL_DECY__DECY4 0x2
+#define BV_PXP_PS_CTRL_DECY__DECY8 0x3
+#define BM_PXP_PS_CTRL_RSVD0 0x00000080
+#define BF_PXP_PS_CTRL_RSVD0(v) \
+ (((v) << 7) & BM_PXP_PS_CTRL_RSVD0)
+#define BM_PXP_PS_CTRL_WB_SWAP 0x00000040
+#define BF_PXP_PS_CTRL_WB_SWAP(v) \
+ (((v) << 6) & BM_PXP_PS_CTRL_WB_SWAP)
+#define BP_PXP_PS_CTRL_FORMAT 0
+#define BM_PXP_PS_CTRL_FORMAT 0x0000003F
+#define BF_PXP_PS_CTRL_FORMAT(v) \
+ (((v) << 0) & BM_PXP_PS_CTRL_FORMAT)
+#define BV_PXP_PS_CTRL_FORMAT__RGB888 0x4
+#define BV_PXP_PS_CTRL_FORMAT__RGB555 0xC
+#define BV_PXP_PS_CTRL_FORMAT__RGB444 0xD
+#define BV_PXP_PS_CTRL_FORMAT__RGB565 0xE
+#define BV_PXP_PS_CTRL_FORMAT__YUV1P444 0x10
+#define BV_PXP_PS_CTRL_FORMAT__UYVY1P422 0x12
+#define BV_PXP_PS_CTRL_FORMAT__VYUY1P422 0x13
+#define BV_PXP_PS_CTRL_FORMAT__Y8 0x14
+#define BV_PXP_PS_CTRL_FORMAT__Y4 0x15
+#define BV_PXP_PS_CTRL_FORMAT__YUV2P422 0x18
+#define BV_PXP_PS_CTRL_FORMAT__YUV2P420 0x19
+#define BV_PXP_PS_CTRL_FORMAT__YVU2P422 0x1A
+#define BV_PXP_PS_CTRL_FORMAT__YVU2P420 0x1B
+#define BV_PXP_PS_CTRL_FORMAT__YUV422 0x1E
+#define BV_PXP_PS_CTRL_FORMAT__YUV420 0x1F
+#define BV_PXP_PS_CTRL_FORMAT__RGBA888 0x24
+
+#define HW_PXP_PS_BUF (0x000000c0)
+
+#define BP_PXP_PS_BUF_ADDR 0
+#define BM_PXP_PS_BUF_ADDR 0xFFFFFFFF
+#define BF_PXP_PS_BUF_ADDR(v) (v)
+
+#define HW_PXP_PS_UBUF (0x000000d0)
+
+#define BP_PXP_PS_UBUF_ADDR 0
+#define BM_PXP_PS_UBUF_ADDR 0xFFFFFFFF
+#define BF_PXP_PS_UBUF_ADDR(v) (v)
+
+#define HW_PXP_PS_VBUF (0x000000e0)
+
+#define BP_PXP_PS_VBUF_ADDR 0
+#define BM_PXP_PS_VBUF_ADDR 0xFFFFFFFF
+#define BF_PXP_PS_VBUF_ADDR(v) (v)
+
+#define HW_PXP_PS_PITCH (0x000000f0)
+
+#define BP_PXP_PS_PITCH_RSVD 16
+#define BM_PXP_PS_PITCH_RSVD 0xFFFF0000
+#define BF_PXP_PS_PITCH_RSVD(v) \
+ (((v) << 16) & BM_PXP_PS_PITCH_RSVD)
+#define BP_PXP_PS_PITCH_PITCH 0
+#define BM_PXP_PS_PITCH_PITCH 0x0000FFFF
+#define BF_PXP_PS_PITCH_PITCH(v) \
+ (((v) << 0) & BM_PXP_PS_PITCH_PITCH)
+
+#define HW_PXP_PS_BACKGROUND_0 (0x00000100)
+
+#define BP_PXP_PS_BACKGROUND_0_RSVD 24
+#define BM_PXP_PS_BACKGROUND_0_RSVD 0xFF000000
+#define BF_PXP_PS_BACKGROUND_0_RSVD(v) \
+ (((v) << 24) & BM_PXP_PS_BACKGROUND_0_RSVD)
+#define BP_PXP_PS_BACKGROUND_0_COLOR 0
+#define BM_PXP_PS_BACKGROUND_0_COLOR 0x00FFFFFF
+#define BF_PXP_PS_BACKGROUND_0_COLOR(v) \
+ (((v) << 0) & BM_PXP_PS_BACKGROUND_0_COLOR)
+
+#define HW_PXP_PS_SCALE (0x00000110)
+
+#define BM_PXP_PS_SCALE_RSVD2 0x80000000
+#define BF_PXP_PS_SCALE_RSVD2(v) \
+ (((v) << 31) & BM_PXP_PS_SCALE_RSVD2)
+#define BP_PXP_PS_SCALE_YSCALE 16
+#define BM_PXP_PS_SCALE_YSCALE 0x7FFF0000
+#define BF_PXP_PS_SCALE_YSCALE(v) \
+ (((v) << 16) & BM_PXP_PS_SCALE_YSCALE)
+#define BM_PXP_PS_SCALE_RSVD1 0x00008000
+#define BF_PXP_PS_SCALE_RSVD1(v) \
+ (((v) << 15) & BM_PXP_PS_SCALE_RSVD1)
+#define BP_PXP_PS_SCALE_XSCALE 0
+#define BM_PXP_PS_SCALE_XSCALE 0x00007FFF
+#define BF_PXP_PS_SCALE_XSCALE(v) \
+ (((v) << 0) & BM_PXP_PS_SCALE_XSCALE)
+
+#define BP_PXP_PS_SCALE_OFFSET 12
+
+#define HW_PXP_PS_OFFSET (0x00000120)
+
+#define BP_PXP_PS_OFFSET_RSVD2 28
+#define BM_PXP_PS_OFFSET_RSVD2 0xF0000000
+#define BF_PXP_PS_OFFSET_RSVD2(v) \
+ (((v) << 28) & BM_PXP_PS_OFFSET_RSVD2)
+#define BP_PXP_PS_OFFSET_YOFFSET 16
+#define BM_PXP_PS_OFFSET_YOFFSET 0x0FFF0000
+#define BF_PXP_PS_OFFSET_YOFFSET(v) \
+ (((v) << 16) & BM_PXP_PS_OFFSET_YOFFSET)
+#define BP_PXP_PS_OFFSET_RSVD1 12
+#define BM_PXP_PS_OFFSET_RSVD1 0x0000F000
+#define BF_PXP_PS_OFFSET_RSVD1(v) \
+ (((v) << 12) & BM_PXP_PS_OFFSET_RSVD1)
+#define BP_PXP_PS_OFFSET_XOFFSET 0
+#define BM_PXP_PS_OFFSET_XOFFSET 0x00000FFF
+#define BF_PXP_PS_OFFSET_XOFFSET(v) \
+ (((v) << 0) & BM_PXP_PS_OFFSET_XOFFSET)
+
+#define HW_PXP_PS_CLRKEYLOW_0 (0x00000130)
+
+#define BP_PXP_PS_CLRKEYLOW_0_RSVD1 24
+#define BM_PXP_PS_CLRKEYLOW_0_RSVD1 0xFF000000
+#define BF_PXP_PS_CLRKEYLOW_0_RSVD1(v) \
+ (((v) << 24) & BM_PXP_PS_CLRKEYLOW_0_RSVD1)
+#define BP_PXP_PS_CLRKEYLOW_0_PIXEL 0
+#define BM_PXP_PS_CLRKEYLOW_0_PIXEL 0x00FFFFFF
+#define BF_PXP_PS_CLRKEYLOW_0_PIXEL(v) \
+ (((v) << 0) & BM_PXP_PS_CLRKEYLOW_0_PIXEL)
+
+#define HW_PXP_PS_CLRKEYHIGH_0 (0x00000140)
+
+#define BP_PXP_PS_CLRKEYHIGH_0_RSVD1 24
+#define BM_PXP_PS_CLRKEYHIGH_0_RSVD1 0xFF000000
+#define BF_PXP_PS_CLRKEYHIGH_0_RSVD1(v) \
+ (((v) << 24) & BM_PXP_PS_CLRKEYHIGH_0_RSVD1)
+#define BP_PXP_PS_CLRKEYHIGH_0_PIXEL 0
+#define BM_PXP_PS_CLRKEYHIGH_0_PIXEL 0x00FFFFFF
+#define BF_PXP_PS_CLRKEYHIGH_0_PIXEL(v) \
+ (((v) << 0) & BM_PXP_PS_CLRKEYHIGH_0_PIXEL)
+
+#define HW_PXP_AS_CTRL (0x00000150)
+
+#define BP_PXP_AS_CTRL_RSVD1 22
+#define BM_PXP_AS_CTRL_RSVD1 0xFFC00000
+#define BF_PXP_AS_CTRL_RSVD1(v) \
+ (((v) << 22) & BM_PXP_AS_CTRL_RSVD1)
+#define BM_PXP_AS_CTRL_ALPHA1_INVERT 0x00200000
+#define BF_PXP_AS_CTRL_ALPHA1_INVERT(v) \
+ (((v) << 21) & BM_PXP_AS_CTRL_ALPHA1_INVERT)
+#define BM_PXP_AS_CTRL_ALPHA0_INVERT 0x00100000
+#define BF_PXP_AS_CTRL_ALPHA0_INVERT(v) \
+ (((v) << 20) & BM_PXP_AS_CTRL_ALPHA0_INVERT)
+#define BP_PXP_AS_CTRL_ROP 16
+#define BM_PXP_AS_CTRL_ROP 0x000F0000
+#define BF_PXP_AS_CTRL_ROP(v) \
+ (((v) << 16) & BM_PXP_AS_CTRL_ROP)
+#define BV_PXP_AS_CTRL_ROP__MASKAS 0x0
+#define BV_PXP_AS_CTRL_ROP__MASKNOTAS 0x1
+#define BV_PXP_AS_CTRL_ROP__MASKASNOT 0x2
+#define BV_PXP_AS_CTRL_ROP__MERGEAS 0x3
+#define BV_PXP_AS_CTRL_ROP__MERGENOTAS 0x4
+#define BV_PXP_AS_CTRL_ROP__MERGEASNOT 0x5
+#define BV_PXP_AS_CTRL_ROP__NOTCOPYAS 0x6
+#define BV_PXP_AS_CTRL_ROP__NOT 0x7
+#define BV_PXP_AS_CTRL_ROP__NOTMASKAS 0x8
+#define BV_PXP_AS_CTRL_ROP__NOTMERGEAS 0x9
+#define BV_PXP_AS_CTRL_ROP__XORAS 0xA
+#define BV_PXP_AS_CTRL_ROP__NOTXORAS 0xB
+#define BP_PXP_AS_CTRL_ALPHA 8
+#define BM_PXP_AS_CTRL_ALPHA 0x0000FF00
+#define BF_PXP_AS_CTRL_ALPHA(v) \
+ (((v) << 8) & BM_PXP_AS_CTRL_ALPHA)
+#define BP_PXP_AS_CTRL_FORMAT 4
+#define BM_PXP_AS_CTRL_FORMAT 0x000000F0
+#define BF_PXP_AS_CTRL_FORMAT(v) \
+ (((v) << 4) & BM_PXP_AS_CTRL_FORMAT)
+#define BV_PXP_AS_CTRL_FORMAT__ARGB8888 0x0
+#define BV_PXP_AS_CTRL_FORMAT__RGBA8888 0x1
+#define BV_PXP_AS_CTRL_FORMAT__RGB888 0x4
+#define BV_PXP_AS_CTRL_FORMAT__ARGB1555 0x8
+#define BV_PXP_AS_CTRL_FORMAT__ARGB4444 0x9
+#define BV_PXP_AS_CTRL_FORMAT__RGBA5551 0xA
+#define BV_PXP_AS_CTRL_FORMAT__RGBA4444 0xB
+#define BV_PXP_AS_CTRL_FORMAT__RGB555 0xC
+#define BV_PXP_AS_CTRL_FORMAT__RGB444 0xD
+#define BV_PXP_AS_CTRL_FORMAT__RGB565 0xE
+#define BM_PXP_AS_CTRL_ENABLE_COLORKEY 0x00000008
+#define BF_PXP_AS_CTRL_ENABLE_COLORKEY(v) \
+ (((v) << 3) & BM_PXP_AS_CTRL_ENABLE_COLORKEY)
+#define BP_PXP_AS_CTRL_ALPHA_CTRL 1
+#define BM_PXP_AS_CTRL_ALPHA_CTRL 0x00000006
+#define BF_PXP_AS_CTRL_ALPHA_CTRL(v) \
+ (((v) << 1) & BM_PXP_AS_CTRL_ALPHA_CTRL)
+#define BV_PXP_AS_CTRL_ALPHA_CTRL__Embedded 0x0
+#define BV_PXP_AS_CTRL_ALPHA_CTRL__Override 0x1
+#define BV_PXP_AS_CTRL_ALPHA_CTRL__Multiply 0x2
+#define BV_PXP_AS_CTRL_ALPHA_CTRL__ROPs 0x3
+#define BM_PXP_AS_CTRL_RSVD0 0x00000001
+#define BF_PXP_AS_CTRL_RSVD0(v) \
+ (((v) << 0) & BM_PXP_AS_CTRL_RSVD0)
+
+#define HW_PXP_AS_BUF (0x00000160)
+
+#define BP_PXP_AS_BUF_ADDR 0
+#define BM_PXP_AS_BUF_ADDR 0xFFFFFFFF
+#define BF_PXP_AS_BUF_ADDR(v) (v)
+
+#define HW_PXP_AS_PITCH (0x00000170)
+
+#define BP_PXP_AS_PITCH_RSVD 16
+#define BM_PXP_AS_PITCH_RSVD 0xFFFF0000
+#define BF_PXP_AS_PITCH_RSVD(v) \
+ (((v) << 16) & BM_PXP_AS_PITCH_RSVD)
+#define BP_PXP_AS_PITCH_PITCH 0
+#define BM_PXP_AS_PITCH_PITCH 0x0000FFFF
+#define BF_PXP_AS_PITCH_PITCH(v) \
+ (((v) << 0) & BM_PXP_AS_PITCH_PITCH)
+
+#define HW_PXP_AS_CLRKEYLOW_0 (0x00000180)
+
+#define BP_PXP_AS_CLRKEYLOW_0_RSVD1 24
+#define BM_PXP_AS_CLRKEYLOW_0_RSVD1 0xFF000000
+#define BF_PXP_AS_CLRKEYLOW_0_RSVD1(v) \
+ (((v) << 24) & BM_PXP_AS_CLRKEYLOW_0_RSVD1)
+#define BP_PXP_AS_CLRKEYLOW_0_PIXEL 0
+#define BM_PXP_AS_CLRKEYLOW_0_PIXEL 0x00FFFFFF
+#define BF_PXP_AS_CLRKEYLOW_0_PIXEL(v) \
+ (((v) << 0) & BM_PXP_AS_CLRKEYLOW_0_PIXEL)
+
+#define HW_PXP_AS_CLRKEYHIGH_0 (0x00000190)
+
+#define BP_PXP_AS_CLRKEYHIGH_0_RSVD1 24
+#define BM_PXP_AS_CLRKEYHIGH_0_RSVD1 0xFF000000
+#define BF_PXP_AS_CLRKEYHIGH_0_RSVD1(v) \
+ (((v) << 24) & BM_PXP_AS_CLRKEYHIGH_0_RSVD1)
+#define BP_PXP_AS_CLRKEYHIGH_0_PIXEL 0
+#define BM_PXP_AS_CLRKEYHIGH_0_PIXEL 0x00FFFFFF
+#define BF_PXP_AS_CLRKEYHIGH_0_PIXEL(v) \
+ (((v) << 0) & BM_PXP_AS_CLRKEYHIGH_0_PIXEL)
+
+#define HW_PXP_CSC1_COEF0 (0x000001a0)
+
+#define BM_PXP_CSC1_COEF0_YCBCR_MODE 0x80000000
+#define BF_PXP_CSC1_COEF0_YCBCR_MODE(v) \
+ (((v) << 31) & BM_PXP_CSC1_COEF0_YCBCR_MODE)
+#define BM_PXP_CSC1_COEF0_BYPASS 0x40000000
+#define BF_PXP_CSC1_COEF0_BYPASS(v) \
+ (((v) << 30) & BM_PXP_CSC1_COEF0_BYPASS)
+#define BM_PXP_CSC1_COEF0_RSVD1 0x20000000
+#define BF_PXP_CSC1_COEF0_RSVD1(v) \
+ (((v) << 29) & BM_PXP_CSC1_COEF0_RSVD1)
+#define BP_PXP_CSC1_COEF0_C0 18
+#define BM_PXP_CSC1_COEF0_C0 0x1FFC0000
+#define BF_PXP_CSC1_COEF0_C0(v) \
+ (((v) << 18) & BM_PXP_CSC1_COEF0_C0)
+#define BP_PXP_CSC1_COEF0_UV_OFFSET 9
+#define BM_PXP_CSC1_COEF0_UV_OFFSET 0x0003FE00
+#define BF_PXP_CSC1_COEF0_UV_OFFSET(v) \
+ (((v) << 9) & BM_PXP_CSC1_COEF0_UV_OFFSET)
+#define BP_PXP_CSC1_COEF0_Y_OFFSET 0
+#define BM_PXP_CSC1_COEF0_Y_OFFSET 0x000001FF
+#define BF_PXP_CSC1_COEF0_Y_OFFSET(v) \
+ (((v) << 0) & BM_PXP_CSC1_COEF0_Y_OFFSET)
+
+#define HW_PXP_CSC1_COEF1 (0x000001b0)
+
+#define BP_PXP_CSC1_COEF1_RSVD1 27
+#define BM_PXP_CSC1_COEF1_RSVD1 0xF8000000
+#define BF_PXP_CSC1_COEF1_RSVD1(v) \
+ (((v) << 27) & BM_PXP_CSC1_COEF1_RSVD1)
+#define BP_PXP_CSC1_COEF1_C1 16
+#define BM_PXP_CSC1_COEF1_C1 0x07FF0000
+#define BF_PXP_CSC1_COEF1_C1(v) \
+ (((v) << 16) & BM_PXP_CSC1_COEF1_C1)
+#define BP_PXP_CSC1_COEF1_RSVD0 11
+#define BM_PXP_CSC1_COEF1_RSVD0 0x0000F800
+#define BF_PXP_CSC1_COEF1_RSVD0(v) \
+ (((v) << 11) & BM_PXP_CSC1_COEF1_RSVD0)
+#define BP_PXP_CSC1_COEF1_C4 0
+#define BM_PXP_CSC1_COEF1_C4 0x000007FF
+#define BF_PXP_CSC1_COEF1_C4(v) \
+ (((v) << 0) & BM_PXP_CSC1_COEF1_C4)
+
+#define HW_PXP_CSC1_COEF2 (0x000001c0)
+
+#define BP_PXP_CSC1_COEF2_RSVD1 27
+#define BM_PXP_CSC1_COEF2_RSVD1 0xF8000000
+#define BF_PXP_CSC1_COEF2_RSVD1(v) \
+ (((v) << 27) & BM_PXP_CSC1_COEF2_RSVD1)
+#define BP_PXP_CSC1_COEF2_C2 16
+#define BM_PXP_CSC1_COEF2_C2 0x07FF0000
+#define BF_PXP_CSC1_COEF2_C2(v) \
+ (((v) << 16) & BM_PXP_CSC1_COEF2_C2)
+#define BP_PXP_CSC1_COEF2_RSVD0 11
+#define BM_PXP_CSC1_COEF2_RSVD0 0x0000F800
+#define BF_PXP_CSC1_COEF2_RSVD0(v) \
+ (((v) << 11) & BM_PXP_CSC1_COEF2_RSVD0)
+#define BP_PXP_CSC1_COEF2_C3 0
+#define BM_PXP_CSC1_COEF2_C3 0x000007FF
+#define BF_PXP_CSC1_COEF2_C3(v) \
+ (((v) << 0) & BM_PXP_CSC1_COEF2_C3)
+
+#define HW_PXP_CSC2_CTRL (0x000001d0)
+
+#define BP_PXP_CSC2_CTRL_RSVD 3
+#define BM_PXP_CSC2_CTRL_RSVD 0xFFFFFFF8
+#define BF_PXP_CSC2_CTRL_RSVD(v) \
+ (((v) << 3) & BM_PXP_CSC2_CTRL_RSVD)
+#define BP_PXP_CSC2_CTRL_CSC_MODE 1
+#define BM_PXP_CSC2_CTRL_CSC_MODE 0x00000006
+#define BF_PXP_CSC2_CTRL_CSC_MODE(v) \
+ (((v) << 1) & BM_PXP_CSC2_CTRL_CSC_MODE)
+#define BV_PXP_CSC2_CTRL_CSC_MODE__YUV2RGB 0x0
+#define BV_PXP_CSC2_CTRL_CSC_MODE__YCbCr2RGB 0x1
+#define BV_PXP_CSC2_CTRL_CSC_MODE__RGB2YUV 0x2
+#define BV_PXP_CSC2_CTRL_CSC_MODE__RGB2YCbCr 0x3
+#define BM_PXP_CSC2_CTRL_BYPASS 0x00000001
+#define BF_PXP_CSC2_CTRL_BYPASS(v) \
+ (((v) << 0) & BM_PXP_CSC2_CTRL_BYPASS)
+
+#define HW_PXP_CSC2_COEF0 (0x000001e0)
+
+#define BP_PXP_CSC2_COEF0_RSVD1 27
+#define BM_PXP_CSC2_COEF0_RSVD1 0xF8000000
+#define BF_PXP_CSC2_COEF0_RSVD1(v) \
+ (((v) << 27) & BM_PXP_CSC2_COEF0_RSVD1)
+#define BP_PXP_CSC2_COEF0_A2 16
+#define BM_PXP_CSC2_COEF0_A2 0x07FF0000
+#define BF_PXP_CSC2_COEF0_A2(v) \
+ (((v) << 16) & BM_PXP_CSC2_COEF0_A2)
+#define BP_PXP_CSC2_COEF0_RSVD0 11
+#define BM_PXP_CSC2_COEF0_RSVD0 0x0000F800
+#define BF_PXP_CSC2_COEF0_RSVD0(v) \
+ (((v) << 11) & BM_PXP_CSC2_COEF0_RSVD0)
+#define BP_PXP_CSC2_COEF0_A1 0
+#define BM_PXP_CSC2_COEF0_A1 0x000007FF
+#define BF_PXP_CSC2_COEF0_A1(v) \
+ (((v) << 0) & BM_PXP_CSC2_COEF0_A1)
+
+#define HW_PXP_CSC2_COEF1 (0x000001f0)
+
+#define BP_PXP_CSC2_COEF1_RSVD1 27
+#define BM_PXP_CSC2_COEF1_RSVD1 0xF8000000
+#define BF_PXP_CSC2_COEF1_RSVD1(v) \
+ (((v) << 27) & BM_PXP_CSC2_COEF1_RSVD1)
+#define BP_PXP_CSC2_COEF1_B1 16
+#define BM_PXP_CSC2_COEF1_B1 0x07FF0000
+#define BF_PXP_CSC2_COEF1_B1(v) \
+ (((v) << 16) & BM_PXP_CSC2_COEF1_B1)
+#define BP_PXP_CSC2_COEF1_RSVD0 11
+#define BM_PXP_CSC2_COEF1_RSVD0 0x0000F800
+#define BF_PXP_CSC2_COEF1_RSVD0(v) \
+ (((v) << 11) & BM_PXP_CSC2_COEF1_RSVD0)
+#define BP_PXP_CSC2_COEF1_A3 0
+#define BM_PXP_CSC2_COEF1_A3 0x000007FF
+#define BF_PXP_CSC2_COEF1_A3(v) \
+ (((v) << 0) & BM_PXP_CSC2_COEF1_A3)
+
+#define HW_PXP_CSC2_COEF2 (0x00000200)
+
+#define BP_PXP_CSC2_COEF2_RSVD1 27
+#define BM_PXP_CSC2_COEF2_RSVD1 0xF8000000
+#define BF_PXP_CSC2_COEF2_RSVD1(v) \
+ (((v) << 27) & BM_PXP_CSC2_COEF2_RSVD1)
+#define BP_PXP_CSC2_COEF2_B3 16
+#define BM_PXP_CSC2_COEF2_B3 0x07FF0000
+#define BF_PXP_CSC2_COEF2_B3(v) \
+ (((v) << 16) & BM_PXP_CSC2_COEF2_B3)
+#define BP_PXP_CSC2_COEF2_RSVD0 11
+#define BM_PXP_CSC2_COEF2_RSVD0 0x0000F800
+#define BF_PXP_CSC2_COEF2_RSVD0(v) \
+ (((v) << 11) & BM_PXP_CSC2_COEF2_RSVD0)
+#define BP_PXP_CSC2_COEF2_B2 0
+#define BM_PXP_CSC2_COEF2_B2 0x000007FF
+#define BF_PXP_CSC2_COEF2_B2(v) \
+ (((v) << 0) & BM_PXP_CSC2_COEF2_B2)
+
+#define HW_PXP_CSC2_COEF3 (0x00000210)
+
+#define BP_PXP_CSC2_COEF3_RSVD1 27
+#define BM_PXP_CSC2_COEF3_RSVD1 0xF8000000
+#define BF_PXP_CSC2_COEF3_RSVD1(v) \
+ (((v) << 27) & BM_PXP_CSC2_COEF3_RSVD1)
+#define BP_PXP_CSC2_COEF3_C2 16
+#define BM_PXP_CSC2_COEF3_C2 0x07FF0000
+#define BF_PXP_CSC2_COEF3_C2(v) \
+ (((v) << 16) & BM_PXP_CSC2_COEF3_C2)
+#define BP_PXP_CSC2_COEF3_RSVD0 11
+#define BM_PXP_CSC2_COEF3_RSVD0 0x0000F800
+#define BF_PXP_CSC2_COEF3_RSVD0(v) \
+ (((v) << 11) & BM_PXP_CSC2_COEF3_RSVD0)
+#define BP_PXP_CSC2_COEF3_C1 0
+#define BM_PXP_CSC2_COEF3_C1 0x000007FF
+#define BF_PXP_CSC2_COEF3_C1(v) \
+ (((v) << 0) & BM_PXP_CSC2_COEF3_C1)
+
+#define HW_PXP_CSC2_COEF4 (0x00000220)
+
+#define BP_PXP_CSC2_COEF4_RSVD1 25
+#define BM_PXP_CSC2_COEF4_RSVD1 0xFE000000
+#define BF_PXP_CSC2_COEF4_RSVD1(v) \
+ (((v) << 25) & BM_PXP_CSC2_COEF4_RSVD1)
+#define BP_PXP_CSC2_COEF4_D1 16
+#define BM_PXP_CSC2_COEF4_D1 0x01FF0000
+#define BF_PXP_CSC2_COEF4_D1(v) \
+ (((v) << 16) & BM_PXP_CSC2_COEF4_D1)
+#define BP_PXP_CSC2_COEF4_RSVD0 11
+#define BM_PXP_CSC2_COEF4_RSVD0 0x0000F800
+#define BF_PXP_CSC2_COEF4_RSVD0(v) \
+ (((v) << 11) & BM_PXP_CSC2_COEF4_RSVD0)
+#define BP_PXP_CSC2_COEF4_C3 0
+#define BM_PXP_CSC2_COEF4_C3 0x000007FF
+#define BF_PXP_CSC2_COEF4_C3(v) \
+ (((v) << 0) & BM_PXP_CSC2_COEF4_C3)
+
+#define HW_PXP_CSC2_COEF5 (0x00000230)
+
+#define BP_PXP_CSC2_COEF5_RSVD1 25
+#define BM_PXP_CSC2_COEF5_RSVD1 0xFE000000
+#define BF_PXP_CSC2_COEF5_RSVD1(v) \
+ (((v) << 25) & BM_PXP_CSC2_COEF5_RSVD1)
+#define BP_PXP_CSC2_COEF5_D3 16
+#define BM_PXP_CSC2_COEF5_D3 0x01FF0000
+#define BF_PXP_CSC2_COEF5_D3(v) \
+ (((v) << 16) & BM_PXP_CSC2_COEF5_D3)
+#define BP_PXP_CSC2_COEF5_RSVD0 9
+#define BM_PXP_CSC2_COEF5_RSVD0 0x0000FE00
+#define BF_PXP_CSC2_COEF5_RSVD0(v) \
+ (((v) << 9) & BM_PXP_CSC2_COEF5_RSVD0)
+#define BP_PXP_CSC2_COEF5_D2 0
+#define BM_PXP_CSC2_COEF5_D2 0x000001FF
+#define BF_PXP_CSC2_COEF5_D2(v) \
+ (((v) << 0) & BM_PXP_CSC2_COEF5_D2)
+
+#define HW_PXP_LUT_CTRL (0x00000240)
+
+#define BM_PXP_LUT_CTRL_BYPASS 0x80000000
+#define BF_PXP_LUT_CTRL_BYPASS(v) \
+ (((v) << 31) & BM_PXP_LUT_CTRL_BYPASS)
+#define BP_PXP_LUT_CTRL_RSVD3 26
+#define BM_PXP_LUT_CTRL_RSVD3 0x7C000000
+#define BF_PXP_LUT_CTRL_RSVD3(v) \
+ (((v) << 26) & BM_PXP_LUT_CTRL_RSVD3)
+#define BP_PXP_LUT_CTRL_LOOKUP_MODE 24
+#define BM_PXP_LUT_CTRL_LOOKUP_MODE 0x03000000
+#define BF_PXP_LUT_CTRL_LOOKUP_MODE(v) \
+ (((v) << 24) & BM_PXP_LUT_CTRL_LOOKUP_MODE)
+#define BV_PXP_LUT_CTRL_LOOKUP_MODE__CACHE_RGB565 0x0
+#define BV_PXP_LUT_CTRL_LOOKUP_MODE__DIRECT_Y8 0x1
+#define BV_PXP_LUT_CTRL_LOOKUP_MODE__DIRECT_RGB444 0x2
+#define BV_PXP_LUT_CTRL_LOOKUP_MODE__DIRECT_RGB454 0x3
+#define BP_PXP_LUT_CTRL_RSVD2 18
+#define BM_PXP_LUT_CTRL_RSVD2 0x00FC0000
+#define BF_PXP_LUT_CTRL_RSVD2(v) \
+ (((v) << 18) & BM_PXP_LUT_CTRL_RSVD2)
+#define BP_PXP_LUT_CTRL_OUT_MODE 16
+#define BM_PXP_LUT_CTRL_OUT_MODE 0x00030000
+#define BF_PXP_LUT_CTRL_OUT_MODE(v) \
+ (((v) << 16) & BM_PXP_LUT_CTRL_OUT_MODE)
+#define BV_PXP_LUT_CTRL_OUT_MODE__RESERVED 0x0
+#define BV_PXP_LUT_CTRL_OUT_MODE__Y8 0x1
+#define BV_PXP_LUT_CTRL_OUT_MODE__RGBW4444CFA 0x2
+#define BV_PXP_LUT_CTRL_OUT_MODE__RGB888 0x3
+#define BP_PXP_LUT_CTRL_RSVD1 11
+#define BM_PXP_LUT_CTRL_RSVD1 0x0000F800
+#define BF_PXP_LUT_CTRL_RSVD1(v) \
+ (((v) << 11) & BM_PXP_LUT_CTRL_RSVD1)
+#define BM_PXP_LUT_CTRL_SEL_8KB 0x00000400
+#define BF_PXP_LUT_CTRL_SEL_8KB(v) \
+ (((v) << 10) & BM_PXP_LUT_CTRL_SEL_8KB)
+#define BM_PXP_LUT_CTRL_LRU_UPD 0x00000200
+#define BF_PXP_LUT_CTRL_LRU_UPD(v) \
+ (((v) << 9) & BM_PXP_LUT_CTRL_LRU_UPD)
+#define BM_PXP_LUT_CTRL_INVALID 0x00000100
+#define BF_PXP_LUT_CTRL_INVALID(v) \
+ (((v) << 8) & BM_PXP_LUT_CTRL_INVALID)
+#define BP_PXP_LUT_CTRL_RSVD0 1
+#define BM_PXP_LUT_CTRL_RSVD0 0x000000FE
+#define BF_PXP_LUT_CTRL_RSVD0(v) \
+ (((v) << 1) & BM_PXP_LUT_CTRL_RSVD0)
+#define BM_PXP_LUT_CTRL_DMA_START 0x00000001
+#define BF_PXP_LUT_CTRL_DMA_START(v) \
+ (((v) << 0) & BM_PXP_LUT_CTRL_DMA_START)
+
+#define HW_PXP_LUT_ADDR (0x00000250)
+
+#define BM_PXP_LUT_ADDR_RSVD2 0x80000000
+#define BF_PXP_LUT_ADDR_RSVD2(v) \
+ (((v) << 31) & BM_PXP_LUT_ADDR_RSVD2)
+#define BP_PXP_LUT_ADDR_NUM_BYTES 16
+#define BM_PXP_LUT_ADDR_NUM_BYTES 0x7FFF0000
+#define BF_PXP_LUT_ADDR_NUM_BYTES(v) \
+ (((v) << 16) & BM_PXP_LUT_ADDR_NUM_BYTES)
+#define BP_PXP_LUT_ADDR_RSVD1 14
+#define BM_PXP_LUT_ADDR_RSVD1 0x0000C000
+#define BF_PXP_LUT_ADDR_RSVD1(v) \
+ (((v) << 14) & BM_PXP_LUT_ADDR_RSVD1)
+#define BP_PXP_LUT_ADDR_ADDR 0
+#define BM_PXP_LUT_ADDR_ADDR 0x00003FFF
+#define BF_PXP_LUT_ADDR_ADDR(v) \
+ (((v) << 0) & BM_PXP_LUT_ADDR_ADDR)
+
+#define HW_PXP_LUT_DATA (0x00000260)
+
+#define BP_PXP_LUT_DATA_DATA 0
+#define BM_PXP_LUT_DATA_DATA 0xFFFFFFFF
+#define BF_PXP_LUT_DATA_DATA(v) (v)
+
+#define HW_PXP_LUT_EXTMEM (0x00000270)
+
+#define BP_PXP_LUT_EXTMEM_ADDR 0
+#define BM_PXP_LUT_EXTMEM_ADDR 0xFFFFFFFF
+#define BF_PXP_LUT_EXTMEM_ADDR(v) (v)
+
+#define HW_PXP_CFA (0x00000280)
+
+#define BP_PXP_CFA_DATA 0
+#define BM_PXP_CFA_DATA 0xFFFFFFFF
+#define BF_PXP_CFA_DATA(v) (v)
+
+#define HW_PXP_ALPHA_A_CTRL (0x00000290)
+
+#define BP_PXP_ALPHA_A_CTRL_S1_GLOBAL_ALPHA 24
+#define BM_PXP_ALPHA_A_CTRL_S1_GLOBAL_ALPHA 0xFF000000
+#define BF_PXP_ALPHA_A_CTRL_S1_GLOBAL_ALPHA(v) \
+ (((v) << 24) & BM_PXP_ALPHA_A_CTRL_S1_GLOBAL_ALPHA)
+#define BP_PXP_ALPHA_A_CTRL_S0_GLOBAL_ALPHA 16
+#define BM_PXP_ALPHA_A_CTRL_S0_GLOBAL_ALPHA 0x00FF0000
+#define BF_PXP_ALPHA_A_CTRL_S0_GLOBAL_ALPHA(v) \
+ (((v) << 16) & BM_PXP_ALPHA_A_CTRL_S0_GLOBAL_ALPHA)
+#define BP_PXP_ALPHA_A_CTRL_RSVD0 14
+#define BM_PXP_ALPHA_A_CTRL_RSVD0 0x0000C000
+#define BF_PXP_ALPHA_A_CTRL_RSVD0(v) \
+ (((v) << 14) & BM_PXP_ALPHA_A_CTRL_RSVD0)
+#define BM_PXP_ALPHA_A_CTRL_S1_COLOR_MODE 0x00002000
+#define BF_PXP_ALPHA_A_CTRL_S1_COLOR_MODE(v) \
+ (((v) << 13) & BM_PXP_ALPHA_A_CTRL_S1_COLOR_MODE)
+#define BV_PXP_ALPHA_A_CTRL_S1_COLOR_MODE__0 0x0
+#define BV_PXP_ALPHA_A_CTRL_S1_COLOR_MODE__1 0x1
+#define BM_PXP_ALPHA_A_CTRL_S1_ALPHA_MODE 0x00001000
+#define BF_PXP_ALPHA_A_CTRL_S1_ALPHA_MODE(v) \
+ (((v) << 12) & BM_PXP_ALPHA_A_CTRL_S1_ALPHA_MODE)
+#define BV_PXP_ALPHA_A_CTRL_S1_ALPHA_MODE__0 0x0
+#define BV_PXP_ALPHA_A_CTRL_S1_ALPHA_MODE__1 0x1
+#define BP_PXP_ALPHA_A_CTRL_S1_GLOBAL_ALPHA_MODE 10
+#define BM_PXP_ALPHA_A_CTRL_S1_GLOBAL_ALPHA_MODE 0x00000C00
+#define BF_PXP_ALPHA_A_CTRL_S1_GLOBAL_ALPHA_MODE(v) \
+ (((v) << 10) & BM_PXP_ALPHA_A_CTRL_S1_GLOBAL_ALPHA_MODE)
+#define BV_PXP_ALPHA_A_CTRL_S1_GLOBAL_ALPHA_MODE__0 0x0
+#define BV_PXP_ALPHA_A_CTRL_S1_GLOBAL_ALPHA_MODE__1 0x0
+#define BV_PXP_ALPHA_A_CTRL_S1_GLOBAL_ALPHA_MODE__2 0x0
+#define BV_PXP_ALPHA_A_CTRL_S1_GLOBAL_ALPHA_MODE__3 0x0
+#define BP_PXP_ALPHA_A_CTRL_S1_S0_FACTOR_MODE 8
+#define BM_PXP_ALPHA_A_CTRL_S1_S0_FACTOR_MODE 0x00000300
+#define BF_PXP_ALPHA_A_CTRL_S1_S0_FACTOR_MODE(v) \
+ (((v) << 8) & BM_PXP_ALPHA_A_CTRL_S1_S0_FACTOR_MODE)
+#define BV_PXP_ALPHA_A_CTRL_S1_S0_FACTOR_MODE__0 0x0
+#define BV_PXP_ALPHA_A_CTRL_S1_S0_FACTOR_MODE__1 0x1
+#define BV_PXP_ALPHA_A_CTRL_S1_S0_FACTOR_MODE__2 0x2
+#define BV_PXP_ALPHA_A_CTRL_S1_S0_FACTOR_MODE__3 0x3
+#define BM_PXP_ALPHA_A_CTRL_RSVD1 0x00000080
+#define BF_PXP_ALPHA_A_CTRL_RSVD1(v) \
+ (((v) << 7) & BM_PXP_ALPHA_A_CTRL_RSVD1)
+#define BM_PXP_ALPHA_A_CTRL_S0_COLOR_MODE 0x00000040
+#define BF_PXP_ALPHA_A_CTRL_S0_COLOR_MODE(v) \
+ (((v) << 6) & BM_PXP_ALPHA_A_CTRL_S0_COLOR_MODE)
+#define BV_PXP_ALPHA_A_CTRL_S0_COLOR_MODE__0 0x0
+#define BV_PXP_ALPHA_A_CTRL_S0_COLOR_MODE__1 0x1
+#define BM_PXP_ALPHA_A_CTRL_S0_ALPHA_MODE 0x00000020
+#define BF_PXP_ALPHA_A_CTRL_S0_ALPHA_MODE(v) \
+ (((v) << 5) & BM_PXP_ALPHA_A_CTRL_S0_ALPHA_MODE)
+#define BV_PXP_ALPHA_A_CTRL_S0_ALPHA_MODE__0 0x0
+#define BV_PXP_ALPHA_A_CTRL_S0_ALPHA_MODE__1 0x1
+#define BP_PXP_ALPHA_A_CTRL_S0_GLOBAL_ALPHA_MODE 3
+#define BM_PXP_ALPHA_A_CTRL_S0_GLOBAL_ALPHA_MODE 0x00000018
+#define BF_PXP_ALPHA_A_CTRL_S0_GLOBAL_ALPHA_MODE(v) \
+ (((v) << 3) & BM_PXP_ALPHA_A_CTRL_S0_GLOBAL_ALPHA_MODE)
+#define BV_PXP_ALPHA_A_CTRL_S0_GLOBAL_ALPHA_MODE__0 0x0
+#define BV_PXP_ALPHA_A_CTRL_S0_GLOBAL_ALPHA_MODE__1 0x1
+#define BV_PXP_ALPHA_A_CTRL_S0_GLOBAL_ALPHA_MODE__2 0x2
+#define BV_PXP_ALPHA_A_CTRL_S0_GLOBAL_ALPHA_MODE__3 0x3
+#define BP_PXP_ALPHA_A_CTRL_S0_S1_FACTOR_MODE 1
+#define BM_PXP_ALPHA_A_CTRL_S0_S1_FACTOR_MODE 0x00000006
+#define BF_PXP_ALPHA_A_CTRL_S0_S1_FACTOR_MODE(v) \
+ (((v) << 1) & BM_PXP_ALPHA_A_CTRL_S0_S1_FACTOR_MODE)
+#define BV_PXP_ALPHA_A_CTRL_S0_S1_FACTOR_MODE__0 0x0
+#define BV_PXP_ALPHA_A_CTRL_S0_S1_FACTOR_MODE__1 0x1
+#define BV_PXP_ALPHA_A_CTRL_S0_S1_FACTOR_MODE__2 0x2
+#define BV_PXP_ALPHA_A_CTRL_S0_S1_FACTOR_MODE__3 0x3
+#define BM_PXP_ALPHA_A_CTRL_POTER_DUFF_ENABLE 0x00000001
+#define BF_PXP_ALPHA_A_CTRL_POTER_DUFF_ENABLE(v) \
+ (((v) << 0) & BM_PXP_ALPHA_A_CTRL_POTER_DUFF_ENABLE)
+#define BV_PXP_ALPHA_A_CTRL_POTER_DUFF_ENABLE__0 0x0
+#define BV_PXP_ALPHA_A_CTRL_POTER_DUFF_ENABLE__1 0x1
+
+#define HW_PXP_ALPHA_B_CTRL (0x000002a0)
+
+#define BP_PXP_ALPHA_B_CTRL_S1_GLOBAL_ALPHA 24
+#define BM_PXP_ALPHA_B_CTRL_S1_GLOBAL_ALPHA 0xFF000000
+#define BF_PXP_ALPHA_B_CTRL_S1_GLOBAL_ALPHA(v) \
+ (((v) << 24) & BM_PXP_ALPHA_B_CTRL_S1_GLOBAL_ALPHA)
+#define BP_PXP_ALPHA_B_CTRL_S0_GLOBAL_ALPHA 16
+#define BM_PXP_ALPHA_B_CTRL_S0_GLOBAL_ALPHA 0x00FF0000
+#define BF_PXP_ALPHA_B_CTRL_S0_GLOBAL_ALPHA(v) \
+ (((v) << 16) & BM_PXP_ALPHA_B_CTRL_S0_GLOBAL_ALPHA)
+#define BP_PXP_ALPHA_B_CTRL_RSVD0 14
+#define BM_PXP_ALPHA_B_CTRL_RSVD0 0x0000C000
+#define BF_PXP_ALPHA_B_CTRL_RSVD0(v) \
+ (((v) << 14) & BM_PXP_ALPHA_B_CTRL_RSVD0)
+#define BM_PXP_ALPHA_B_CTRL_S1_COLOR_MODE 0x00002000
+#define BF_PXP_ALPHA_B_CTRL_S1_COLOR_MODE(v) \
+ (((v) << 13) & BM_PXP_ALPHA_B_CTRL_S1_COLOR_MODE)
+#define BV_PXP_ALPHA_B_CTRL_S1_COLOR_MODE__0 0x0
+#define BV_PXP_ALPHA_B_CTRL_S1_COLOR_MODE__1 0x1
+#define BM_PXP_ALPHA_B_CTRL_S1_ALPHA_MODE 0x00001000
+#define BF_PXP_ALPHA_B_CTRL_S1_ALPHA_MODE(v) \
+ (((v) << 12) & BM_PXP_ALPHA_B_CTRL_S1_ALPHA_MODE)
+#define BV_PXP_ALPHA_B_CTRL_S1_ALPHA_MODE__0 0x0
+#define BV_PXP_ALPHA_B_CTRL_S1_ALPHA_MODE__1 0x1
+#define BP_PXP_ALPHA_B_CTRL_S1_GLOBAL_ALPHA_MODE 10
+#define BM_PXP_ALPHA_B_CTRL_S1_GLOBAL_ALPHA_MODE 0x00000C00
+#define BF_PXP_ALPHA_B_CTRL_S1_GLOBAL_ALPHA_MODE(v) \
+ (((v) << 10) & BM_PXP_ALPHA_B_CTRL_S1_GLOBAL_ALPHA_MODE)
+#define BV_PXP_ALPHA_B_CTRL_S1_GLOBAL_ALPHA_MODE__0 0x0
+#define BV_PXP_ALPHA_B_CTRL_S1_GLOBAL_ALPHA_MODE__1 0x1
+#define BV_PXP_ALPHA_B_CTRL_S1_GLOBAL_ALPHA_MODE__2 0x2
+#define BV_PXP_ALPHA_B_CTRL_S1_GLOBAL_ALPHA_MODE__3 0x3
+#define BP_PXP_ALPHA_B_CTRL_S1_S0_FACTOR_MODE 8
+#define BM_PXP_ALPHA_B_CTRL_S1_S0_FACTOR_MODE 0x00000300
+#define BF_PXP_ALPHA_B_CTRL_S1_S0_FACTOR_MODE(v) \
+ (((v) << 8) & BM_PXP_ALPHA_B_CTRL_S1_S0_FACTOR_MODE)
+#define BV_PXP_ALPHA_B_CTRL_S1_S0_FACTOR_MODE__0 0x0
+#define BV_PXP_ALPHA_B_CTRL_S1_S0_FACTOR_MODE__1 0x1
+#define BV_PXP_ALPHA_B_CTRL_S1_S0_FACTOR_MODE__2 0x2
+#define BV_PXP_ALPHA_B_CTRL_S1_S0_FACTOR_MODE__3 0x3
+#define BM_PXP_ALPHA_B_CTRL_RSVD1 0x00000080
+#define BF_PXP_ALPHA_B_CTRL_RSVD1(v) \
+ (((v) << 7) & BM_PXP_ALPHA_B_CTRL_RSVD1)
+#define BM_PXP_ALPHA_B_CTRL_S0_COLOR_MODE 0x00000040
+#define BF_PXP_ALPHA_B_CTRL_S0_COLOR_MODE(v) \
+ (((v) << 6) & BM_PXP_ALPHA_B_CTRL_S0_COLOR_MODE)
+#define BV_PXP_ALPHA_B_CTRL_S0_COLOR_MODE__0 0x0
+#define BV_PXP_ALPHA_B_CTRL_S0_COLOR_MODE__1 0x1
+#define BM_PXP_ALPHA_B_CTRL_S0_ALPHA_MODE 0x00000020
+#define BF_PXP_ALPHA_B_CTRL_S0_ALPHA_MODE(v) \
+ (((v) << 5) & BM_PXP_ALPHA_B_CTRL_S0_ALPHA_MODE)
+#define BV_PXP_ALPHA_B_CTRL_S0_ALPHA_MODE__0 0x0
+#define BV_PXP_ALPHA_B_CTRL_S0_ALPHA_MODE__1 0x1
+#define BP_PXP_ALPHA_B_CTRL_S0_GLOBAL_ALPHA_MODE 3
+#define BM_PXP_ALPHA_B_CTRL_S0_GLOBAL_ALPHA_MODE 0x00000018
+#define BF_PXP_ALPHA_B_CTRL_S0_GLOBAL_ALPHA_MODE(v) \
+ (((v) << 3) & BM_PXP_ALPHA_B_CTRL_S0_GLOBAL_ALPHA_MODE)
+#define BV_PXP_ALPHA_B_CTRL_S0_GLOBAL_ALPHA_MODE__0 0x0
+#define BV_PXP_ALPHA_B_CTRL_S0_GLOBAL_ALPHA_MODE__1 0x1
+#define BV_PXP_ALPHA_B_CTRL_S0_GLOBAL_ALPHA_MODE__2 0x2
+#define BV_PXP_ALPHA_B_CTRL_S0_GLOBAL_ALPHA_MODE__3 0x3
+#define BP_PXP_ALPHA_B_CTRL_S0_S1_FACTOR_MODE 1
+#define BM_PXP_ALPHA_B_CTRL_S0_S1_FACTOR_MODE 0x00000006
+#define BF_PXP_ALPHA_B_CTRL_S0_S1_FACTOR_MODE(v) \
+ (((v) << 1) & BM_PXP_ALPHA_B_CTRL_S0_S1_FACTOR_MODE)
+#define BV_PXP_ALPHA_B_CTRL_S0_S1_FACTOR_MODE__0 0x0
+#define BV_PXP_ALPHA_B_CTRL_S0_S1_FACTOR_MODE__1 0x1
+#define BV_PXP_ALPHA_B_CTRL_S0_S1_FACTOR_MODE__2 0x2
+#define BV_PXP_ALPHA_B_CTRL_S0_S1_FACTOR_MODE__3 0x3
+#define BM_PXP_ALPHA_B_CTRL_POTER_DUFF_ENABLE 0x00000001
+#define BF_PXP_ALPHA_B_CTRL_POTER_DUFF_ENABLE(v) \
+ (((v) << 0) & BM_PXP_ALPHA_B_CTRL_POTER_DUFF_ENABLE)
+#define BV_PXP_ALPHA_B_CTRL_POTER_DUFF_ENABLE__0 0x0
+#define BV_PXP_ALPHA_B_CTRL_POTER_DUFF_ENABLE__1 0x1
+
+#define HW_PXP_ALPHA_B_CTRL_1 (0x000002b0)
+
+#define BP_PXP_ALPHA_B_CTRL_1_RSVD0 8
+#define BM_PXP_ALPHA_B_CTRL_1_RSVD0 0xFFFFFF00
+#define BF_PXP_ALPHA_B_CTRL_1_RSVD0(v) \
+ (((v) << 8) & BM_PXP_ALPHA_B_CTRL_1_RSVD0)
+#define BP_PXP_ALPHA_B_CTRL_1_ROP 4
+#define BM_PXP_ALPHA_B_CTRL_1_ROP 0x000000F0
+#define BF_PXP_ALPHA_B_CTRL_1_ROP(v) \
+ (((v) << 4) & BM_PXP_ALPHA_B_CTRL_1_ROP)
+#define BV_PXP_ALPHA_B_CTRL_1_ROP__MASKAS 0x0
+#define BV_PXP_ALPHA_B_CTRL_1_ROP__MASKNOTAS 0x1
+#define BV_PXP_ALPHA_B_CTRL_1_ROP__MASKASNOT 0x2
+#define BV_PXP_ALPHA_B_CTRL_1_ROP__MERGEAS 0x3
+#define BV_PXP_ALPHA_B_CTRL_1_ROP__MERGENOTAS 0x4
+#define BV_PXP_ALPHA_B_CTRL_1_ROP__MERGEASNOT 0x5
+#define BV_PXP_ALPHA_B_CTRL_1_ROP__NOTCOPYAS 0x6
+#define BV_PXP_ALPHA_B_CTRL_1_ROP__NOT 0x7
+#define BV_PXP_ALPHA_B_CTRL_1_ROP__NOTMASKAS 0x8
+#define BV_PXP_ALPHA_B_CTRL_1_ROP__NOTMERGEAS 0x9
+#define BV_PXP_ALPHA_B_CTRL_1_ROP__XORAS 0xA
+#define BV_PXP_ALPHA_B_CTRL_1_ROP__NOTXORAS 0xB
+#define BP_PXP_ALPHA_B_CTRL_1_RSVD1 2
+#define BM_PXP_ALPHA_B_CTRL_1_RSVD1 0x0000000C
+#define BF_PXP_ALPHA_B_CTRL_1_RSVD1(v) \
+ (((v) << 2) & BM_PXP_ALPHA_B_CTRL_1_RSVD1)
+#define BM_PXP_ALPHA_B_CTRL_1_OL_CLRKEY_ENABLE 0x00000002
+#define BF_PXP_ALPHA_B_CTRL_1_OL_CLRKEY_ENABLE(v) \
+ (((v) << 1) & BM_PXP_ALPHA_B_CTRL_1_OL_CLRKEY_ENABLE)
+#define BM_PXP_ALPHA_B_CTRL_1_ROP_ENABLE 0x00000001
+#define BF_PXP_ALPHA_B_CTRL_1_ROP_ENABLE(v) \
+ (((v) << 0) & BM_PXP_ALPHA_B_CTRL_1_ROP_ENABLE)
+
+#define HW_PXP_PS_BACKGROUND_1 (0x000002c0)
+
+#define BP_PXP_PS_BACKGROUND_1_RSVD 24
+#define BM_PXP_PS_BACKGROUND_1_RSVD 0xFF000000
+#define BF_PXP_PS_BACKGROUND_1_RSVD(v) \
+ (((v) << 24) & BM_PXP_PS_BACKGROUND_1_RSVD)
+#define BP_PXP_PS_BACKGROUND_1_COLOR 0
+#define BM_PXP_PS_BACKGROUND_1_COLOR 0x00FFFFFF
+#define BF_PXP_PS_BACKGROUND_1_COLOR(v) \
+ (((v) << 0) & BM_PXP_PS_BACKGROUND_1_COLOR)
+
+#define HW_PXP_PS_CLRKEYLOW_1 (0x000002d0)
+
+#define BP_PXP_PS_CLRKEYLOW_1_RSVD1 24
+#define BM_PXP_PS_CLRKEYLOW_1_RSVD1 0xFF000000
+#define BF_PXP_PS_CLRKEYLOW_1_RSVD1(v) \
+ (((v) << 24) & BM_PXP_PS_CLRKEYLOW_1_RSVD1)
+#define BP_PXP_PS_CLRKEYLOW_1_PIXEL 0
+#define BM_PXP_PS_CLRKEYLOW_1_PIXEL 0x00FFFFFF
+#define BF_PXP_PS_CLRKEYLOW_1_PIXEL(v) \
+ (((v) << 0) & BM_PXP_PS_CLRKEYLOW_1_PIXEL)
+
+#define HW_PXP_PS_CLRKEYHIGH_1 (0x000002e0)
+
+#define BP_PXP_PS_CLRKEYHIGH_1_RSVD1 24
+#define BM_PXP_PS_CLRKEYHIGH_1_RSVD1 0xFF000000
+#define BF_PXP_PS_CLRKEYHIGH_1_RSVD1(v) \
+ (((v) << 24) & BM_PXP_PS_CLRKEYHIGH_1_RSVD1)
+#define BP_PXP_PS_CLRKEYHIGH_1_PIXEL 0
+#define BM_PXP_PS_CLRKEYHIGH_1_PIXEL 0x00FFFFFF
+#define BF_PXP_PS_CLRKEYHIGH_1_PIXEL(v) \
+ (((v) << 0) & BM_PXP_PS_CLRKEYHIGH_1_PIXEL)
+
+#define HW_PXP_AS_CLRKEYLOW_1 (0x000002f0)
+
+#define BP_PXP_AS_CLRKEYLOW_1_RSVD1 24
+#define BM_PXP_AS_CLRKEYLOW_1_RSVD1 0xFF000000
+#define BF_PXP_AS_CLRKEYLOW_1_RSVD1(v) \
+ (((v) << 24) & BM_PXP_AS_CLRKEYLOW_1_RSVD1)
+#define BP_PXP_AS_CLRKEYLOW_1_PIXEL 0
+#define BM_PXP_AS_CLRKEYLOW_1_PIXEL 0x00FFFFFF
+#define BF_PXP_AS_CLRKEYLOW_1_PIXEL(v) \
+ (((v) << 0) & BM_PXP_AS_CLRKEYLOW_1_PIXEL)
+
+#define HW_PXP_AS_CLRKEYHIGH_1 (0x00000300)
+
+#define BP_PXP_AS_CLRKEYHIGH_1_RSVD1 24
+#define BM_PXP_AS_CLRKEYHIGH_1_RSVD1 0xFF000000
+#define BF_PXP_AS_CLRKEYHIGH_1_RSVD1(v) \
+ (((v) << 24) & BM_PXP_AS_CLRKEYHIGH_1_RSVD1)
+#define BP_PXP_AS_CLRKEYHIGH_1_PIXEL 0
+#define BM_PXP_AS_CLRKEYHIGH_1_PIXEL 0x00FFFFFF
+#define BF_PXP_AS_CLRKEYHIGH_1_PIXEL(v) \
+ (((v) << 0) & BM_PXP_AS_CLRKEYHIGH_1_PIXEL)
+
+#define HW_PXP_CTRL2 (0x00000310)
+#define HW_PXP_CTRL2_SET (0x00000314)
+#define HW_PXP_CTRL2_CLR (0x00000318)
+#define HW_PXP_CTRL2_TOG (0x0000031c)
+
+#define BP_PXP_CTRL2_RSVD3 28
+#define BM_PXP_CTRL2_RSVD3 0xF0000000
+#define BF_PXP_CTRL2_RSVD3(v) \
+ (((v) << 28) & BM_PXP_CTRL2_RSVD3)
+#define BM_PXP_CTRL2_ENABLE_ROTATE1 0x08000000
+#define BF_PXP_CTRL2_ENABLE_ROTATE1(v) \
+ (((v) << 27) & BM_PXP_CTRL2_ENABLE_ROTATE1)
+#define BM_PXP_CTRL2_ENABLE_ROTATE0 0x04000000
+#define BF_PXP_CTRL2_ENABLE_ROTATE0(v) \
+ (((v) << 26) & BM_PXP_CTRL2_ENABLE_ROTATE0)
+#define BM_PXP_CTRL2_ENABLE_LUT 0x02000000
+#define BF_PXP_CTRL2_ENABLE_LUT(v) \
+ (((v) << 25) & BM_PXP_CTRL2_ENABLE_LUT)
+#define BM_PXP_CTRL2_ENABLE_CSC2 0x01000000
+#define BF_PXP_CTRL2_ENABLE_CSC2(v) \
+ (((v) << 24) & BM_PXP_CTRL2_ENABLE_CSC2)
+#define BM_PXP_CTRL2_BLOCK_SIZE 0x00800000
+#define BF_PXP_CTRL2_BLOCK_SIZE(v) \
+ (((v) << 23) & BM_PXP_CTRL2_BLOCK_SIZE)
+#define BV_PXP_CTRL2_BLOCK_SIZE__8X8 0x0
+#define BV_PXP_CTRL2_BLOCK_SIZE__16X16 0x1
+#define BM_PXP_CTRL2_RSVD2 0x00400000
+#define BF_PXP_CTRL2_RSVD2(v) \
+ (((v) << 22) & BM_PXP_CTRL2_RSVD2)
+#define BM_PXP_CTRL2_ENABLE_ALPHA_B 0x00200000
+#define BF_PXP_CTRL2_ENABLE_ALPHA_B(v) \
+ (((v) << 21) & BM_PXP_CTRL2_ENABLE_ALPHA_B)
+#define BM_PXP_CTRL2_ENABLE_INPUT_FETCH_STORE 0x00100000
+#define BF_PXP_CTRL2_ENABLE_INPUT_FETCH_STORE(v) \
+ (((v) << 20) & BM_PXP_CTRL2_ENABLE_INPUT_FETCH_STORE)
+#define BM_PXP_CTRL2_ENABLE_WFE_B 0x00080000
+#define BF_PXP_CTRL2_ENABLE_WFE_B(v) \
+ (((v) << 19) & BM_PXP_CTRL2_ENABLE_WFE_B)
+#define BM_PXP_CTRL2_ENABLE_WFE_A 0x00040000
+#define BF_PXP_CTRL2_ENABLE_WFE_A(v) \
+ (((v) << 18) & BM_PXP_CTRL2_ENABLE_WFE_A)
+#define BM_PXP_CTRL2_ENABLE_DITHER 0x00020000
+#define BF_PXP_CTRL2_ENABLE_DITHER(v) \
+ (((v) << 17) & BM_PXP_CTRL2_ENABLE_DITHER)
+#define BM_PXP_CTRL2_RSVD1 0x00010000
+#define BF_PXP_CTRL2_RSVD1(v) \
+ (((v) << 16) & BM_PXP_CTRL2_RSVD1)
+#define BM_PXP_CTRL2_VFLIP1 0x00008000
+#define BF_PXP_CTRL2_VFLIP1(v) \
+ (((v) << 15) & BM_PXP_CTRL2_VFLIP1)
+#define BM_PXP_CTRL2_HFLIP1 0x00004000
+#define BF_PXP_CTRL2_HFLIP1(v) \
+ (((v) << 14) & BM_PXP_CTRL2_HFLIP1)
+#define BP_PXP_CTRL2_ROTATE1 12
+#define BM_PXP_CTRL2_ROTATE1 0x00003000
+#define BF_PXP_CTRL2_ROTATE1(v) \
+ (((v) << 12) & BM_PXP_CTRL2_ROTATE1)
+#define BV_PXP_CTRL2_ROTATE1__ROT_0 0x0
+#define BV_PXP_CTRL2_ROTATE1__ROT_90 0x1
+#define BV_PXP_CTRL2_ROTATE1__ROT_180 0x2
+#define BV_PXP_CTRL2_ROTATE1__ROT_270 0x3
+#define BM_PXP_CTRL2_VFLIP0 0x00000800
+#define BF_PXP_CTRL2_VFLIP0(v) \
+ (((v) << 11) & BM_PXP_CTRL2_VFLIP0)
+#define BM_PXP_CTRL2_HFLIP0 0x00000400
+#define BF_PXP_CTRL2_HFLIP0(v) \
+ (((v) << 10) & BM_PXP_CTRL2_HFLIP0)
+#define BP_PXP_CTRL2_ROTATE0 8
+#define BM_PXP_CTRL2_ROTATE0 0x00000300
+#define BF_PXP_CTRL2_ROTATE0(v) \
+ (((v) << 8) & BM_PXP_CTRL2_ROTATE0)
+#define BV_PXP_CTRL2_ROTATE0__ROT_0 0x0
+#define BV_PXP_CTRL2_ROTATE0__ROT_90 0x1
+#define BV_PXP_CTRL2_ROTATE0__ROT_180 0x2
+#define BV_PXP_CTRL2_ROTATE0__ROT_270 0x3
+#define BP_PXP_CTRL2_RSVD0 1
+#define BM_PXP_CTRL2_RSVD0 0x000000FE
+#define BF_PXP_CTRL2_RSVD0(v) \
+ (((v) << 1) & BM_PXP_CTRL2_RSVD0)
+#define BM_PXP_CTRL2_ENABLE 0x00000001
+#define BF_PXP_CTRL2_ENABLE(v) \
+ (((v) << 0) & BM_PXP_CTRL2_ENABLE)
+
+#define HW_PXP_POWER_REG0 (0x00000320)
+
+#define BP_PXP_POWER_REG0_CTRL 12
+#define BM_PXP_POWER_REG0_CTRL 0xFFFFF000
+#define BF_PXP_POWER_REG0_CTRL(v) \
+ (((v) << 12) & BM_PXP_POWER_REG0_CTRL)
+#define BP_PXP_POWER_REG0_ROT0_MEM_LP_STATE 9
+#define BM_PXP_POWER_REG0_ROT0_MEM_LP_STATE 0x00000E00
+#define BF_PXP_POWER_REG0_ROT0_MEM_LP_STATE(v) \
+ (((v) << 9) & BM_PXP_POWER_REG0_ROT0_MEM_LP_STATE)
+#define BV_PXP_POWER_REG0_ROT0_MEM_LP_STATE__NONE 0x0
+#define BV_PXP_POWER_REG0_ROT0_MEM_LP_STATE__LS 0x1
+#define BV_PXP_POWER_REG0_ROT0_MEM_LP_STATE__DS 0x2
+#define BV_PXP_POWER_REG0_ROT0_MEM_LP_STATE__SD 0x4
+#define BP_PXP_POWER_REG0_LUT_LP_STATE_WAY1_BANKN 6
+#define BM_PXP_POWER_REG0_LUT_LP_STATE_WAY1_BANKN 0x000001C0
+#define BF_PXP_POWER_REG0_LUT_LP_STATE_WAY1_BANKN(v) \
+ (((v) << 6) & BM_PXP_POWER_REG0_LUT_LP_STATE_WAY1_BANKN)
+#define BV_PXP_POWER_REG0_LUT_LP_STATE_WAY1_BANKN__NONE 0x0
+#define BV_PXP_POWER_REG0_LUT_LP_STATE_WAY1_BANKN__LS 0x1
+#define BV_PXP_POWER_REG0_LUT_LP_STATE_WAY1_BANKN__DS 0x2
+#define BV_PXP_POWER_REG0_LUT_LP_STATE_WAY1_BANKN__SD 0x4
+#define BP_PXP_POWER_REG0_LUT_LP_STATE_WAY0_BANKN 3
+#define BM_PXP_POWER_REG0_LUT_LP_STATE_WAY0_BANKN 0x00000038
+#define BF_PXP_POWER_REG0_LUT_LP_STATE_WAY0_BANKN(v) \
+ (((v) << 3) & BM_PXP_POWER_REG0_LUT_LP_STATE_WAY0_BANKN)
+#define BV_PXP_POWER_REG0_LUT_LP_STATE_WAY0_BANKN__NONE 0x0
+#define BV_PXP_POWER_REG0_LUT_LP_STATE_WAY0_BANKN__LS 0x1
+#define BV_PXP_POWER_REG0_LUT_LP_STATE_WAY0_BANKN__DS 0x2
+#define BV_PXP_POWER_REG0_LUT_LP_STATE_WAY0_BANKN__SD 0x4
+#define BP_PXP_POWER_REG0_LUT_LP_STATE_WAY0_BANK0 0
+#define BM_PXP_POWER_REG0_LUT_LP_STATE_WAY0_BANK0 0x00000007
+#define BF_PXP_POWER_REG0_LUT_LP_STATE_WAY0_BANK0(v) \
+ (((v) << 0) & BM_PXP_POWER_REG0_LUT_LP_STATE_WAY0_BANK0)
+#define BV_PXP_POWER_REG0_LUT_LP_STATE_WAY0_BANK0__NONE 0x0
+#define BV_PXP_POWER_REG0_LUT_LP_STATE_WAY0_BANK0__LS 0x1
+#define BV_PXP_POWER_REG0_LUT_LP_STATE_WAY0_BANK0__DS 0x2
+#define BV_PXP_POWER_REG0_LUT_LP_STATE_WAY0_BANK0__SD 0x4
+
+#define HW_PXP_POWER_REG1 (0x00000330)
+
+#define BP_PXP_POWER_REG1_RSVD0 24
+#define BM_PXP_POWER_REG1_RSVD0 0xFF000000
+#define BF_PXP_POWER_REG1_RSVD0(v) \
+ (((v) << 24) & BM_PXP_POWER_REG1_RSVD0)
+#define BP_PXP_POWER_REG1_ALU_B_MEM_LP_STATE 21
+#define BM_PXP_POWER_REG1_ALU_B_MEM_LP_STATE 0x00E00000
+#define BF_PXP_POWER_REG1_ALU_B_MEM_LP_STATE(v) \
+ (((v) << 21) & BM_PXP_POWER_REG1_ALU_B_MEM_LP_STATE)
+#define BV_PXP_POWER_REG1_ALU_B_MEM_LP_STATE__NONE 0x0
+#define BV_PXP_POWER_REG1_ALU_B_MEM_LP_STATE__LS 0x1
+#define BV_PXP_POWER_REG1_ALU_B_MEM_LP_STATE__DS 0x2
+#define BV_PXP_POWER_REG1_ALU_B_MEM_LP_STATE__SD 0x4
+#define BP_PXP_POWER_REG1_ALU_A_MEM_LP_STATE 18
+#define BM_PXP_POWER_REG1_ALU_A_MEM_LP_STATE 0x001C0000
+#define BF_PXP_POWER_REG1_ALU_A_MEM_LP_STATE(v) \
+ (((v) << 18) & BM_PXP_POWER_REG1_ALU_A_MEM_LP_STATE)
+#define BV_PXP_POWER_REG1_ALU_A_MEM_LP_STATE__NONE 0x0
+#define BV_PXP_POWER_REG1_ALU_A_MEM_LP_STATE__LS 0x1
+#define BV_PXP_POWER_REG1_ALU_A_MEM_LP_STATE__DS 0x2
+#define BV_PXP_POWER_REG1_ALU_A_MEM_LP_STATE__SD 0x4
+#define BP_PXP_POWER_REG1_DITH2_LUT_MEM_LP_STATE 15
+#define BM_PXP_POWER_REG1_DITH2_LUT_MEM_LP_STATE 0x00038000
+#define BF_PXP_POWER_REG1_DITH2_LUT_MEM_LP_STATE(v) \
+ (((v) << 15) & BM_PXP_POWER_REG1_DITH2_LUT_MEM_LP_STATE)
+#define BV_PXP_POWER_REG1_DITH2_LUT_MEM_LP_STATE__NONE 0x0
+#define BV_PXP_POWER_REG1_DITH2_LUT_MEM_LP_STATE__LS 0x1
+#define BV_PXP_POWER_REG1_DITH2_LUT_MEM_LP_STATE__DS 0x2
+#define BV_PXP_POWER_REG1_DITH2_LUT_MEM_LP_STATE__SD 0x4
+#define BP_PXP_POWER_REG1_DITH1_LUT_MEM_LP_STATE 12
+#define BM_PXP_POWER_REG1_DITH1_LUT_MEM_LP_STATE 0x00007000
+#define BF_PXP_POWER_REG1_DITH1_LUT_MEM_LP_STATE(v) \
+ (((v) << 12) & BM_PXP_POWER_REG1_DITH1_LUT_MEM_LP_STATE)
+#define BV_PXP_POWER_REG1_DITH1_LUT_MEM_LP_STATE__NONE 0x0
+#define BV_PXP_POWER_REG1_DITH1_LUT_MEM_LP_STATE__LS 0x1
+#define BV_PXP_POWER_REG1_DITH1_LUT_MEM_LP_STATE__DS 0x2
+#define BV_PXP_POWER_REG1_DITH1_LUT_MEM_LP_STATE__SD 0x4
+#define BP_PXP_POWER_REG1_DITH0_ERR1_MEM_LP_STATE 9
+#define BM_PXP_POWER_REG1_DITH0_ERR1_MEM_LP_STATE 0x00000E00
+#define BF_PXP_POWER_REG1_DITH0_ERR1_MEM_LP_STATE(v) \
+ (((v) << 9) & BM_PXP_POWER_REG1_DITH0_ERR1_MEM_LP_STATE)
+#define BV_PXP_POWER_REG1_DITH0_ERR1_MEM_LP_STATE__NONE 0x0
+#define BV_PXP_POWER_REG1_DITH0_ERR1_MEM_LP_STATE__LS 0x1
+#define BV_PXP_POWER_REG1_DITH0_ERR1_MEM_LP_STATE__DS 0x2
+#define BV_PXP_POWER_REG1_DITH0_ERR1_MEM_LP_STATE__SD 0x4
+#define BP_PXP_POWER_REG1_DITH0_ERR0_MEM_LP_STATE 6
+#define BM_PXP_POWER_REG1_DITH0_ERR0_MEM_LP_STATE 0x000001C0
+#define BF_PXP_POWER_REG1_DITH0_ERR0_MEM_LP_STATE(v) \
+ (((v) << 6) & BM_PXP_POWER_REG1_DITH0_ERR0_MEM_LP_STATE)
+#define BV_PXP_POWER_REG1_DITH0_ERR0_MEM_LP_STATE__NONE 0x0
+#define BV_PXP_POWER_REG1_DITH0_ERR0_MEM_LP_STATE__LS 0x1
+#define BV_PXP_POWER_REG1_DITH0_ERR0_MEM_LP_STATE__DS 0x2
+#define BV_PXP_POWER_REG1_DITH0_ERR0_MEM_LP_STATE__SD 0x4
+#define BP_PXP_POWER_REG1_DITH0_LUT_MEM_LP_STATE 3
+#define BM_PXP_POWER_REG1_DITH0_LUT_MEM_LP_STATE 0x00000038
+#define BF_PXP_POWER_REG1_DITH0_LUT_MEM_LP_STATE(v) \
+ (((v) << 3) & BM_PXP_POWER_REG1_DITH0_LUT_MEM_LP_STATE)
+#define BV_PXP_POWER_REG1_DITH0_LUT_MEM_LP_STATE__NONE 0x0
+#define BV_PXP_POWER_REG1_DITH0_LUT_MEM_LP_STATE__LS 0x1
+#define BV_PXP_POWER_REG1_DITH0_LUT_MEM_LP_STATE__DS 0x2
+#define BV_PXP_POWER_REG1_DITH0_LUT_MEM_LP_STATE__SD 0x4
+#define BP_PXP_POWER_REG1_ROT1_MEM_LP_STATE 0
+#define BM_PXP_POWER_REG1_ROT1_MEM_LP_STATE 0x00000007
+#define BF_PXP_POWER_REG1_ROT1_MEM_LP_STATE(v) \
+ (((v) << 0) & BM_PXP_POWER_REG1_ROT1_MEM_LP_STATE)
+#define BV_PXP_POWER_REG1_ROT1_MEM_LP_STATE__NONE 0x0
+#define BV_PXP_POWER_REG1_ROT1_MEM_LP_STATE__LS 0x1
+#define BV_PXP_POWER_REG1_ROT1_MEM_LP_STATE__DS 0x2
+#define BV_PXP_POWER_REG1_ROT1_MEM_LP_STATE__SD 0x4
+
+#define HW_PXP_DATA_PATH_CTRL0 (0x00000340)
+#define HW_PXP_DATA_PATH_CTRL0_SET (0x00000344)
+#define HW_PXP_DATA_PATH_CTRL0_CLR (0x00000348)
+#define HW_PXP_DATA_PATH_CTRL0_TOG (0x0000034c)
+
+#define BP_PXP_DATA_PATH_CTRL0_MUX15_SEL 30
+#define BM_PXP_DATA_PATH_CTRL0_MUX15_SEL 0xC0000000
+#define BF_PXP_DATA_PATH_CTRL0_MUX15_SEL(v) \
+ (((v) << 30) & BM_PXP_DATA_PATH_CTRL0_MUX15_SEL)
+#define BV_PXP_DATA_PATH_CTRL0_MUX15_SEL__0 0x0
+#define BV_PXP_DATA_PATH_CTRL0_MUX15_SEL__1 0x1
+#define BV_PXP_DATA_PATH_CTRL0_MUX15_SEL__2 0x2
+#define BV_PXP_DATA_PATH_CTRL0_MUX15_SEL__3 0x3
+#define BP_PXP_DATA_PATH_CTRL0_MUX14_SEL 28
+#define BM_PXP_DATA_PATH_CTRL0_MUX14_SEL 0x30000000
+#define BF_PXP_DATA_PATH_CTRL0_MUX14_SEL(v) \
+ (((v) << 28) & BM_PXP_DATA_PATH_CTRL0_MUX14_SEL)
+#define BV_PXP_DATA_PATH_CTRL0_MUX14_SEL__0 0x0
+#define BV_PXP_DATA_PATH_CTRL0_MUX14_SEL__1 0x1
+#define BV_PXP_DATA_PATH_CTRL0_MUX14_SEL__2 0x2
+#define BV_PXP_DATA_PATH_CTRL0_MUX14_SEL__3 0x3
+#define BP_PXP_DATA_PATH_CTRL0_MUX13_SEL 26
+#define BM_PXP_DATA_PATH_CTRL0_MUX13_SEL 0x0C000000
+#define BF_PXP_DATA_PATH_CTRL0_MUX13_SEL(v) \
+ (((v) << 26) & BM_PXP_DATA_PATH_CTRL0_MUX13_SEL)
+#define BV_PXP_DATA_PATH_CTRL0_MUX13_SEL__0 0x0
+#define BV_PXP_DATA_PATH_CTRL0_MUX13_SEL__1 0x1
+#define BV_PXP_DATA_PATH_CTRL0_MUX13_SEL__2 0x2
+#define BV_PXP_DATA_PATH_CTRL0_MUX13_SEL__3 0x3
+#define BP_PXP_DATA_PATH_CTRL0_MUX12_SEL 24
+#define BM_PXP_DATA_PATH_CTRL0_MUX12_SEL 0x03000000
+#define BF_PXP_DATA_PATH_CTRL0_MUX12_SEL(v) \
+ (((v) << 24) & BM_PXP_DATA_PATH_CTRL0_MUX12_SEL)
+#define BV_PXP_DATA_PATH_CTRL0_MUX12_SEL__0 0x0
+#define BV_PXP_DATA_PATH_CTRL0_MUX12_SEL__1 0x1
+#define BV_PXP_DATA_PATH_CTRL0_MUX12_SEL__2 0x2
+#define BV_PXP_DATA_PATH_CTRL0_MUX12_SEL__3 0x3
+#define BP_PXP_DATA_PATH_CTRL0_MUX11_SEL 22
+#define BM_PXP_DATA_PATH_CTRL0_MUX11_SEL 0x00C00000
+#define BF_PXP_DATA_PATH_CTRL0_MUX11_SEL(v) \
+ (((v) << 22) & BM_PXP_DATA_PATH_CTRL0_MUX11_SEL)
+#define BV_PXP_DATA_PATH_CTRL0_MUX11_SEL__0 0x0
+#define BV_PXP_DATA_PATH_CTRL0_MUX11_SEL__1 0x1
+#define BV_PXP_DATA_PATH_CTRL0_MUX11_SEL__2 0x2
+#define BV_PXP_DATA_PATH_CTRL0_MUX11_SEL__3 0x3
+#define BP_PXP_DATA_PATH_CTRL0_MUX10_SEL 20
+#define BM_PXP_DATA_PATH_CTRL0_MUX10_SEL 0x00300000
+#define BF_PXP_DATA_PATH_CTRL0_MUX10_SEL(v) \
+ (((v) << 20) & BM_PXP_DATA_PATH_CTRL0_MUX10_SEL)
+#define BV_PXP_DATA_PATH_CTRL0_MUX10_SEL__0 0x0
+#define BV_PXP_DATA_PATH_CTRL0_MUX10_SEL__1 0x1
+#define BV_PXP_DATA_PATH_CTRL0_MUX10_SEL__2 0x2
+#define BV_PXP_DATA_PATH_CTRL0_MUX10_SEL__3 0x3
+#define BP_PXP_DATA_PATH_CTRL0_MUX9_SEL 18
+#define BM_PXP_DATA_PATH_CTRL0_MUX9_SEL 0x000C0000
+#define BF_PXP_DATA_PATH_CTRL0_MUX9_SEL(v) \
+ (((v) << 18) & BM_PXP_DATA_PATH_CTRL0_MUX9_SEL)
+#define BV_PXP_DATA_PATH_CTRL0_MUX9_SEL__0 0x0
+#define BV_PXP_DATA_PATH_CTRL0_MUX9_SEL__1 0x1
+#define BV_PXP_DATA_PATH_CTRL0_MUX9_SEL__2 0x2
+#define BV_PXP_DATA_PATH_CTRL0_MUX9_SEL__3 0x3
+#define BP_PXP_DATA_PATH_CTRL0_MUX8_SEL 16
+#define BM_PXP_DATA_PATH_CTRL0_MUX8_SEL 0x00030000
+#define BF_PXP_DATA_PATH_CTRL0_MUX8_SEL(v) \
+ (((v) << 16) & BM_PXP_DATA_PATH_CTRL0_MUX8_SEL)
+#define BV_PXP_DATA_PATH_CTRL0_MUX8_SEL__0 0x0
+#define BV_PXP_DATA_PATH_CTRL0_MUX8_SEL__1 0x1
+#define BV_PXP_DATA_PATH_CTRL0_MUX8_SEL__2 0x2
+#define BV_PXP_DATA_PATH_CTRL0_MUX8_SEL__3 0x3
+#define BP_PXP_DATA_PATH_CTRL0_MUX7_SEL 14
+#define BM_PXP_DATA_PATH_CTRL0_MUX7_SEL 0x0000C000
+#define BF_PXP_DATA_PATH_CTRL0_MUX7_SEL(v) \
+ (((v) << 14) & BM_PXP_DATA_PATH_CTRL0_MUX7_SEL)
+#define BV_PXP_DATA_PATH_CTRL0_MUX7_SEL__0 0x0
+#define BV_PXP_DATA_PATH_CTRL0_MUX7_SEL__1 0x1
+#define BV_PXP_DATA_PATH_CTRL0_MUX7_SEL__2 0x2
+#define BV_PXP_DATA_PATH_CTRL0_MUX7_SEL__3 0x3
+#define BP_PXP_DATA_PATH_CTRL0_MUX6_SEL 12
+#define BM_PXP_DATA_PATH_CTRL0_MUX6_SEL 0x00003000
+#define BF_PXP_DATA_PATH_CTRL0_MUX6_SEL(v) \
+ (((v) << 12) & BM_PXP_DATA_PATH_CTRL0_MUX6_SEL)
+#define BV_PXP_DATA_PATH_CTRL0_MUX6_SEL__0 0x0
+#define BV_PXP_DATA_PATH_CTRL0_MUX6_SEL__1 0x1
+#define BV_PXP_DATA_PATH_CTRL0_MUX6_SEL__2 0x2
+#define BV_PXP_DATA_PATH_CTRL0_MUX6_SEL__3 0x3
+#define BP_PXP_DATA_PATH_CTRL0_MUX5_SEL 10
+#define BM_PXP_DATA_PATH_CTRL0_MUX5_SEL 0x00000C00
+#define BF_PXP_DATA_PATH_CTRL0_MUX5_SEL(v) \
+ (((v) << 10) & BM_PXP_DATA_PATH_CTRL0_MUX5_SEL)
+#define BV_PXP_DATA_PATH_CTRL0_MUX5_SEL__0 0x0
+#define BV_PXP_DATA_PATH_CTRL0_MUX5_SEL__1 0x1
+#define BV_PXP_DATA_PATH_CTRL0_MUX5_SEL__2 0x2
+#define BV_PXP_DATA_PATH_CTRL0_MUX5_SEL__3 0x3
+#define BP_PXP_DATA_PATH_CTRL0_MUX4_SEL 8
+#define BM_PXP_DATA_PATH_CTRL0_MUX4_SEL 0x00000300
+#define BF_PXP_DATA_PATH_CTRL0_MUX4_SEL(v) \
+ (((v) << 8) & BM_PXP_DATA_PATH_CTRL0_MUX4_SEL)
+#define BV_PXP_DATA_PATH_CTRL0_MUX4_SEL__0 0x0
+#define BV_PXP_DATA_PATH_CTRL0_MUX4_SEL__1 0x1
+#define BV_PXP_DATA_PATH_CTRL0_MUX4_SEL__2 0x2
+#define BV_PXP_DATA_PATH_CTRL0_MUX4_SEL__3 0x3
+#define BP_PXP_DATA_PATH_CTRL0_MUX3_SEL 6
+#define BM_PXP_DATA_PATH_CTRL0_MUX3_SEL 0x000000C0
+#define BF_PXP_DATA_PATH_CTRL0_MUX3_SEL(v) \
+ (((v) << 6) & BM_PXP_DATA_PATH_CTRL0_MUX3_SEL)
+#define BV_PXP_DATA_PATH_CTRL0_MUX3_SEL__0 0x0
+#define BV_PXP_DATA_PATH_CTRL0_MUX3_SEL__1 0x1
+#define BV_PXP_DATA_PATH_CTRL0_MUX3_SEL__2 0x2
+#define BV_PXP_DATA_PATH_CTRL0_MUX3_SEL__3 0x3
+#define BP_PXP_DATA_PATH_CTRL0_MUX2_SEL 4
+#define BM_PXP_DATA_PATH_CTRL0_MUX2_SEL 0x00000030
+#define BF_PXP_DATA_PATH_CTRL0_MUX2_SEL(v) \
+ (((v) << 4) & BM_PXP_DATA_PATH_CTRL0_MUX2_SEL)
+#define BV_PXP_DATA_PATH_CTRL0_MUX2_SEL__0 0x0
+#define BV_PXP_DATA_PATH_CTRL0_MUX2_SEL__1 0x1
+#define BV_PXP_DATA_PATH_CTRL0_MUX2_SEL__2 0x2
+#define BV_PXP_DATA_PATH_CTRL0_MUX2_SEL__3 0x3
+#define BP_PXP_DATA_PATH_CTRL0_MUX1_SEL 2
+#define BM_PXP_DATA_PATH_CTRL0_MUX1_SEL 0x0000000C
+#define BF_PXP_DATA_PATH_CTRL0_MUX1_SEL(v) \
+ (((v) << 2) & BM_PXP_DATA_PATH_CTRL0_MUX1_SEL)
+#define BV_PXP_DATA_PATH_CTRL0_MUX1_SEL__0 0x0
+#define BV_PXP_DATA_PATH_CTRL0_MUX1_SEL__1 0x1
+#define BV_PXP_DATA_PATH_CTRL0_MUX1_SEL__2 0x2
+#define BV_PXP_DATA_PATH_CTRL0_MUX1_SEL__3 0x3
+#define BP_PXP_DATA_PATH_CTRL0_MUX0_SEL 0
+#define BM_PXP_DATA_PATH_CTRL0_MUX0_SEL 0x00000003
+#define BF_PXP_DATA_PATH_CTRL0_MUX0_SEL(v) \
+ (((v) << 0) & BM_PXP_DATA_PATH_CTRL0_MUX0_SEL)
+#define BV_PXP_DATA_PATH_CTRL0_MUX0_SEL__0 0x0
+#define BV_PXP_DATA_PATH_CTRL0_MUX0_SEL__1 0x1
+#define BV_PXP_DATA_PATH_CTRL0_MUX0_SEL__2 0x2
+#define BV_PXP_DATA_PATH_CTRL0_MUX0_SEL__3 0x3
+
+#define HW_PXP_DATA_PATH_CTRL1 (0x00000350)
+#define HW_PXP_DATA_PATH_CTRL1_SET (0x00000354)
+#define HW_PXP_DATA_PATH_CTRL1_CLR (0x00000358)
+#define HW_PXP_DATA_PATH_CTRL1_TOG (0x0000035c)
+
+#define BP_PXP_DATA_PATH_CTRL1_RSVD0 4
+#define BM_PXP_DATA_PATH_CTRL1_RSVD0 0xFFFFFFF0
+#define BF_PXP_DATA_PATH_CTRL1_RSVD0(v) \
+ (((v) << 4) & BM_PXP_DATA_PATH_CTRL1_RSVD0)
+#define BP_PXP_DATA_PATH_CTRL1_MUX17_SEL 2
+#define BM_PXP_DATA_PATH_CTRL1_MUX17_SEL 0x0000000C
+#define BF_PXP_DATA_PATH_CTRL1_MUX17_SEL(v) \
+ (((v) << 2) & BM_PXP_DATA_PATH_CTRL1_MUX17_SEL)
+#define BV_PXP_DATA_PATH_CTRL1_MUX17_SEL__0 0x0
+#define BV_PXP_DATA_PATH_CTRL1_MUX17_SEL__1 0x1
+#define BV_PXP_DATA_PATH_CTRL1_MUX17_SEL__2 0x2
+#define BV_PXP_DATA_PATH_CTRL1_MUX17_SEL__3 0x3
+#define BP_PXP_DATA_PATH_CTRL1_MUX16_SEL 0
+#define BM_PXP_DATA_PATH_CTRL1_MUX16_SEL 0x00000003
+#define BF_PXP_DATA_PATH_CTRL1_MUX16_SEL(v) \
+ (((v) << 0) & BM_PXP_DATA_PATH_CTRL1_MUX16_SEL)
+#define BV_PXP_DATA_PATH_CTRL1_MUX16_SEL__0 0x0
+#define BV_PXP_DATA_PATH_CTRL1_MUX16_SEL__1 0x1
+#define BV_PXP_DATA_PATH_CTRL1_MUX16_SEL__2 0x2
+#define BV_PXP_DATA_PATH_CTRL1_MUX16_SEL__3 0x3
+
+#define HW_PXP_INIT_MEM_CTRL (0x00000360)
+#define HW_PXP_INIT_MEM_CTRL_SET (0x00000364)
+#define HW_PXP_INIT_MEM_CTRL_CLR (0x00000368)
+#define HW_PXP_INIT_MEM_CTRL_TOG (0x0000036c)
+
+#define BM_PXP_INIT_MEM_CTRL_START 0x80000000
+#define BF_PXP_INIT_MEM_CTRL_START(v) \
+ (((v) << 31) & BM_PXP_INIT_MEM_CTRL_START)
+#define BP_PXP_INIT_MEM_CTRL_SELECT 27
+#define BM_PXP_INIT_MEM_CTRL_SELECT 0x78000000
+#define BF_PXP_INIT_MEM_CTRL_SELECT(v) \
+ (((v) << 27) & BM_PXP_INIT_MEM_CTRL_SELECT)
+#define BV_PXP_INIT_MEM_CTRL_SELECT__DITHER0_LUT 0x0
+#define BV_PXP_INIT_MEM_CTRL_SELECT__DITHER0_ERR0 0x1
+#define BV_PXP_INIT_MEM_CTRL_SELECT__DITHER0_ERR1 0x2
+#define BV_PXP_INIT_MEM_CTRL_SELECT__DITHER1_LUT 0x3
+#define BV_PXP_INIT_MEM_CTRL_SELECT__DITHER2_LUT 0x4
+#define BV_PXP_INIT_MEM_CTRL_SELECT__ALU_A 0x5
+#define BV_PXP_INIT_MEM_CTRL_SELECT__ALU_B 0x6
+#define BV_PXP_INIT_MEM_CTRL_SELECT__WFE_A_FETCH 0x7
+#define BV_PXP_INIT_MEM_CTRL_SELECT__WFE_B_FETCH 0x8
+#define BV_PXP_INIT_MEM_CTRL_SELECT__RESERVED 0x15
+#define BP_PXP_INIT_MEM_CTRL_RSVD0 16
+#define BM_PXP_INIT_MEM_CTRL_RSVD0 0x07FF0000
+#define BF_PXP_INIT_MEM_CTRL_RSVD0(v) \
+ (((v) << 16) & BM_PXP_INIT_MEM_CTRL_RSVD0)
+#define BP_PXP_INIT_MEM_CTRL_ADDR 0
+#define BM_PXP_INIT_MEM_CTRL_ADDR 0x0000FFFF
+#define BF_PXP_INIT_MEM_CTRL_ADDR(v) \
+ (((v) << 0) & BM_PXP_INIT_MEM_CTRL_ADDR)
+
+#define HW_PXP_INIT_MEM_DATA (0x00000370)
+
+#define BP_PXP_INIT_MEM_DATA_DATA 0
+#define BM_PXP_INIT_MEM_DATA_DATA 0xFFFFFFFF
+#define BF_PXP_INIT_MEM_DATA_DATA(v) (v)
+
+#define HW_PXP_INIT_MEM_DATA_HIGH (0x00000380)
+
+#define BP_PXP_INIT_MEM_DATA_HIGH_DATA 0
+#define BM_PXP_INIT_MEM_DATA_HIGH_DATA 0xFFFFFFFF
+#define BF_PXP_INIT_MEM_DATA_HIGH_DATA(v) (v)
+
+#define HW_PXP_IRQ_MASK (0x00000390)
+#define HW_PXP_IRQ_MASK_SET (0x00000394)
+#define HW_PXP_IRQ_MASK_CLR (0x00000398)
+#define HW_PXP_IRQ_MASK_TOG (0x0000039c)
+
+#define BM_PXP_IRQ_MASK_COMPRESS_DONE_IRQ_EN 0x80000000
+#define BF_PXP_IRQ_MASK_COMPRESS_DONE_IRQ_EN(v) \
+ (((v) << 31) & BM_PXP_IRQ_MASK_COMPRESS_DONE_IRQ_EN)
+#define BP_PXP_IRQ_MASK_RSVD1 16
+#define BM_PXP_IRQ_MASK_RSVD1 0x7FFF0000
+#define BF_PXP_IRQ_MASK_RSVD1(v) \
+ (((v) << 16) & BM_PXP_IRQ_MASK_RSVD1)
+#define BM_PXP_IRQ_MASK_WFE_B_STORE_IRQ_EN 0x00008000
+#define BF_PXP_IRQ_MASK_WFE_B_STORE_IRQ_EN(v) \
+ (((v) << 15) & BM_PXP_IRQ_MASK_WFE_B_STORE_IRQ_EN)
+#define BM_PXP_IRQ_MASK_WFE_A_STORE_IRQ_EN 0x00004000
+#define BF_PXP_IRQ_MASK_WFE_A_STORE_IRQ_EN(v) \
+ (((v) << 14) & BM_PXP_IRQ_MASK_WFE_A_STORE_IRQ_EN)
+#define BM_PXP_IRQ_MASK_DITHER_STORE_IRQ_EN 0x00002000
+#define BF_PXP_IRQ_MASK_DITHER_STORE_IRQ_EN(v) \
+ (((v) << 13) & BM_PXP_IRQ_MASK_DITHER_STORE_IRQ_EN)
+#define BM_PXP_IRQ_MASK_FIRST_STORE_IRQ_EN 0x00001000
+#define BF_PXP_IRQ_MASK_FIRST_STORE_IRQ_EN(v) \
+ (((v) << 12) & BM_PXP_IRQ_MASK_FIRST_STORE_IRQ_EN)
+#define BM_PXP_IRQ_MASK_WFE_B_CH1_STORE_IRQ_EN 0x00000800
+#define BF_PXP_IRQ_MASK_WFE_B_CH1_STORE_IRQ_EN(v) \
+ (((v) << 11) & BM_PXP_IRQ_MASK_WFE_B_CH1_STORE_IRQ_EN)
+#define BM_PXP_IRQ_MASK_WFE_B_CH0_STORE_IRQ_EN 0x00000400
+#define BF_PXP_IRQ_MASK_WFE_B_CH0_STORE_IRQ_EN(v) \
+ (((v) << 10) & BM_PXP_IRQ_MASK_WFE_B_CH0_STORE_IRQ_EN)
+#define BM_PXP_IRQ_MASK_WFE_A_CH1_STORE_IRQ_EN 0x00000200
+#define BF_PXP_IRQ_MASK_WFE_A_CH1_STORE_IRQ_EN(v) \
+ (((v) << 9) & BM_PXP_IRQ_MASK_WFE_A_CH1_STORE_IRQ_EN)
+#define BM_PXP_IRQ_MASK_WFE_A_CH0_STORE_IRQ_EN 0x00000100
+#define BF_PXP_IRQ_MASK_WFE_A_CH0_STORE_IRQ_EN(v) \
+ (((v) << 8) & BM_PXP_IRQ_MASK_WFE_A_CH0_STORE_IRQ_EN)
+#define BM_PXP_IRQ_MASK_DITHER_CH1_STORE_IRQ_EN 0x00000080
+#define BF_PXP_IRQ_MASK_DITHER_CH1_STORE_IRQ_EN(v) \
+ (((v) << 7) & BM_PXP_IRQ_MASK_DITHER_CH1_STORE_IRQ_EN)
+#define BM_PXP_IRQ_MASK_DITHER_CH0_STORE_IRQ_EN 0x00000040
+#define BF_PXP_IRQ_MASK_DITHER_CH0_STORE_IRQ_EN(v) \
+ (((v) << 6) & BM_PXP_IRQ_MASK_DITHER_CH0_STORE_IRQ_EN)
+#define BM_PXP_IRQ_MASK_DITHER_CH1_PREFETCH_IRQ_EN 0x00000020
+#define BF_PXP_IRQ_MASK_DITHER_CH1_PREFETCH_IRQ_EN(v) \
+ (((v) << 5) & BM_PXP_IRQ_MASK_DITHER_CH1_PREFETCH_IRQ_EN)
+#define BM_PXP_IRQ_MASK_DITHER_CH0_PREFETCH_IRQ_EN 0x00000010
+#define BF_PXP_IRQ_MASK_DITHER_CH0_PREFETCH_IRQ_EN(v) \
+ (((v) << 4) & BM_PXP_IRQ_MASK_DITHER_CH0_PREFETCH_IRQ_EN)
+#define BM_PXP_IRQ_MASK_FIRST_CH1_STORE_IRQ_EN 0x00000008
+#define BF_PXP_IRQ_MASK_FIRST_CH1_STORE_IRQ_EN(v) \
+ (((v) << 3) & BM_PXP_IRQ_MASK_FIRST_CH1_STORE_IRQ_EN)
+#define BM_PXP_IRQ_MASK_FIRST_CH0_STORE_IRQ_EN 0x00000004
+#define BF_PXP_IRQ_MASK_FIRST_CH0_STORE_IRQ_EN(v) \
+ (((v) << 2) & BM_PXP_IRQ_MASK_FIRST_CH0_STORE_IRQ_EN)
+#define BM_PXP_IRQ_MASK_FIRST_CH1_PREFETCH_IRQ_EN 0x00000002
+#define BF_PXP_IRQ_MASK_FIRST_CH1_PREFETCH_IRQ_EN(v) \
+ (((v) << 1) & BM_PXP_IRQ_MASK_FIRST_CH1_PREFETCH_IRQ_EN)
+#define BM_PXP_IRQ_MASK_FIRST_CH0_PREFETCH_IRQ_EN 0x00000001
+#define BF_PXP_IRQ_MASK_FIRST_CH0_PREFETCH_IRQ_EN(v) \
+ (((v) << 0) & BM_PXP_IRQ_MASK_FIRST_CH0_PREFETCH_IRQ_EN)
+
+#define HW_PXP_IRQ (0x000003a0)
+#define HW_PXP_IRQ_SET (0x000003a4)
+#define HW_PXP_IRQ_CLR (0x000003a8)
+#define HW_PXP_IRQ_TOG (0x000003ac)
+
+#define BM_PXP_IRQ_COMPRESS_DONE_IRQ 0x80000000
+#define BF_PXP_IRQ_COMPRESS_DONE_IRQ(v) \
+ (((v) << 31) & BM_PXP_IRQ_COMPRESS_DONE_IRQ)
+#define BP_PXP_IRQ_RSVD1 16
+#define BM_PXP_IRQ_RSVD1 0x7FFF0000
+#define BF_PXP_IRQ_RSVD1(v) \
+ (((v) << 16) & BM_PXP_IRQ_RSVD1)
+#define BM_PXP_IRQ_WFE_B_STORE_IRQ 0x00008000
+#define BF_PXP_IRQ_WFE_B_STORE_IRQ(v) \
+ (((v) << 15) & BM_PXP_IRQ_WFE_B_STORE_IRQ)
+#define BM_PXP_IRQ_WFE_A_STORE_IRQ 0x00004000
+#define BF_PXP_IRQ_WFE_A_STORE_IRQ(v) \
+ (((v) << 14) & BM_PXP_IRQ_WFE_A_STORE_IRQ)
+#define BM_PXP_IRQ_DITHER_STORE_IRQ 0x00002000
+#define BF_PXP_IRQ_DITHER_STORE_IRQ(v) \
+ (((v) << 13) & BM_PXP_IRQ_DITHER_STORE_IRQ)
+#define BM_PXP_IRQ_FIRST_STORE_IRQ 0x00001000
+#define BF_PXP_IRQ_FIRST_STORE_IRQ(v) \
+ (((v) << 12) & BM_PXP_IRQ_FIRST_STORE_IRQ)
+#define BM_PXP_IRQ_WFE_B_CH1_STORE_IRQ 0x00000800
+#define BF_PXP_IRQ_WFE_B_CH1_STORE_IRQ(v) \
+ (((v) << 11) & BM_PXP_IRQ_WFE_B_CH1_STORE_IRQ)
+#define BM_PXP_IRQ_WFE_B_CH0_STORE_IRQ 0x00000400
+#define BF_PXP_IRQ_WFE_B_CH0_STORE_IRQ(v) \
+ (((v) << 10) & BM_PXP_IRQ_WFE_B_CH0_STORE_IRQ)
+#define BM_PXP_IRQ_WFE_A_CH1_STORE_IRQ 0x00000200
+#define BF_PXP_IRQ_WFE_A_CH1_STORE_IRQ(v) \
+ (((v) << 9) & BM_PXP_IRQ_WFE_A_CH1_STORE_IRQ)
+#define BM_PXP_IRQ_WFE_A_CH0_STORE_IRQ 0x00000100
+#define BF_PXP_IRQ_WFE_A_CH0_STORE_IRQ(v) \
+ (((v) << 8) & BM_PXP_IRQ_WFE_A_CH0_STORE_IRQ)
+#define BM_PXP_IRQ_DITHER_CH1_STORE_IRQ 0x00000080
+#define BF_PXP_IRQ_DITHER_CH1_STORE_IRQ(v) \
+ (((v) << 7) & BM_PXP_IRQ_DITHER_CH1_STORE_IRQ)
+#define BM_PXP_IRQ_DITHER_CH0_STORE_IRQ 0x00000040
+#define BF_PXP_IRQ_DITHER_CH0_STORE_IRQ(v) \
+ (((v) << 6) & BM_PXP_IRQ_DITHER_CH0_STORE_IRQ)
+#define BM_PXP_IRQ_DITHER_CH1_PREFETCH_IRQ 0x00000020
+#define BF_PXP_IRQ_DITHER_CH1_PREFETCH_IRQ(v) \
+ (((v) << 5) & BM_PXP_IRQ_DITHER_CH1_PREFETCH_IRQ)
+#define BM_PXP_IRQ_DITHER_CH0_PREFETCH_IRQ 0x00000010
+#define BF_PXP_IRQ_DITHER_CH0_PREFETCH_IRQ(v) \
+ (((v) << 4) & BM_PXP_IRQ_DITHER_CH0_PREFETCH_IRQ)
+#define BM_PXP_IRQ_FIRST_CH1_STORE_IRQ 0x00000008
+#define BF_PXP_IRQ_FIRST_CH1_STORE_IRQ(v) \
+ (((v) << 3) & BM_PXP_IRQ_FIRST_CH1_STORE_IRQ)
+#define BM_PXP_IRQ_FIRST_CH0_STORE_IRQ 0x00000004
+#define BF_PXP_IRQ_FIRST_CH0_STORE_IRQ(v) \
+ (((v) << 2) & BM_PXP_IRQ_FIRST_CH0_STORE_IRQ)
+#define BM_PXP_IRQ_FIRST_CH1_PREFETCH_IRQ 0x00000002
+#define BF_PXP_IRQ_FIRST_CH1_PREFETCH_IRQ(v) \
+ (((v) << 1) & BM_PXP_IRQ_FIRST_CH1_PREFETCH_IRQ)
+#define BM_PXP_IRQ_FIRST_CH0_PREFETCH_IRQ 0x00000001
+#define BF_PXP_IRQ_FIRST_CH0_PREFETCH_IRQ(v) \
+ (((v) << 0) & BM_PXP_IRQ_FIRST_CH0_PREFETCH_IRQ)
+
+#define HW_PXP_NEXT (0x00000400)
+
+#define BP_PXP_NEXT_POINTER 2
+#define BM_PXP_NEXT_POINTER 0xFFFFFFFC
+#define BF_PXP_NEXT_POINTER(v) \
+ (((v) << 2) & BM_PXP_NEXT_POINTER)
+#define BM_PXP_NEXT_RSVD 0x00000002
+#define BF_PXP_NEXT_RSVD(v) \
+ (((v) << 1) & BM_PXP_NEXT_RSVD)
+#define BM_PXP_NEXT_ENABLED 0x00000001
+#define BF_PXP_NEXT_ENABLED(v) \
+ (((v) << 0) & BM_PXP_NEXT_ENABLED)
+
+#define HW_PXP_DEBUGCTRL (0x00000410)
+
+#define BP_PXP_DEBUGCTRL_RSVD 12
+#define BM_PXP_DEBUGCTRL_RSVD 0xFFFFF000
+#define BF_PXP_DEBUGCTRL_RSVD(v) \
+ (((v) << 12) & BM_PXP_DEBUGCTRL_RSVD)
+#define BP_PXP_DEBUGCTRL_LUT_CLR_STAT_CNT 8
+#define BM_PXP_DEBUGCTRL_LUT_CLR_STAT_CNT 0x00000F00
+#define BF_PXP_DEBUGCTRL_LUT_CLR_STAT_CNT(v) \
+ (((v) << 8) & BM_PXP_DEBUGCTRL_LUT_CLR_STAT_CNT)
+#define BV_PXP_DEBUGCTRL_LUT_CLR_STAT_CNT__NONE 0x0
+#define BV_PXP_DEBUGCTRL_LUT_CLR_STAT_CNT__MISS_CNT 0x1
+#define BV_PXP_DEBUGCTRL_LUT_CLR_STAT_CNT__HIT_CNT 0x2
+#define BV_PXP_DEBUGCTRL_LUT_CLR_STAT_CNT__LAT_CNT 0x4
+#define BV_PXP_DEBUGCTRL_LUT_CLR_STAT_CNT__MAX_LAT 0x8
+#define BP_PXP_DEBUGCTRL_SELECT 0
+#define BM_PXP_DEBUGCTRL_SELECT 0x000000FF
+#define BF_PXP_DEBUGCTRL_SELECT(v) \
+ (((v) << 0) & BM_PXP_DEBUGCTRL_SELECT)
+#define BV_PXP_DEBUGCTRL_SELECT__NONE 0x0
+#define BV_PXP_DEBUGCTRL_SELECT__CTRL 0x1
+#define BV_PXP_DEBUGCTRL_SELECT__PSBUF 0x2
+#define BV_PXP_DEBUGCTRL_SELECT__PSBAX 0x3
+#define BV_PXP_DEBUGCTRL_SELECT__PSBAY 0x4
+#define BV_PXP_DEBUGCTRL_SELECT__ASBUF 0x5
+#define BV_PXP_DEBUGCTRL_SELECT__ROTATION 0x6
+#define BV_PXP_DEBUGCTRL_SELECT__OUTBUF0 0x7
+#define BV_PXP_DEBUGCTRL_SELECT__OUTBUF1 0x8
+#define BV_PXP_DEBUGCTRL_SELECT__OUTBUF2 0x9
+#define BV_PXP_DEBUGCTRL_SELECT__LUT_STAT 0x10
+#define BV_PXP_DEBUGCTRL_SELECT__LUT_MISS 0x11
+#define BV_PXP_DEBUGCTRL_SELECT__LUT_HIT 0x12
+#define BV_PXP_DEBUGCTRL_SELECT__LUT_LAT 0x13
+#define BV_PXP_DEBUGCTRL_SELECT__LUT_MAX_LAT 0x14
+
+#define HW_PXP_DEBUG (0x00000420)
+
+#define BP_PXP_DEBUG_DATA 0
+#define BM_PXP_DEBUG_DATA 0xFFFFFFFF
+#define BF_PXP_DEBUG_DATA(v) (v)
+
+#define HW_PXP_VERSION (0x00000430)
+
+#define BP_PXP_VERSION_MAJOR 24
+#define BM_PXP_VERSION_MAJOR 0xFF000000
+#define BF_PXP_VERSION_MAJOR(v) \
+ (((v) << 24) & BM_PXP_VERSION_MAJOR)
+#define BP_PXP_VERSION_MINOR 16
+#define BM_PXP_VERSION_MINOR 0x00FF0000
+#define BF_PXP_VERSION_MINOR(v) \
+ (((v) << 16) & BM_PXP_VERSION_MINOR)
+#define BP_PXP_VERSION_STEP 0
+#define BM_PXP_VERSION_STEP 0x0000FFFF
+#define BF_PXP_VERSION_STEP(v) \
+ (((v) << 0) & BM_PXP_VERSION_STEP)
+
+#define HW_PXP_INPUT_FETCH_CTRL_CH0 (0x00000450)
+#define HW_PXP_INPUT_FETCH_CTRL_CH0_SET (0x00000454)
+#define HW_PXP_INPUT_FETCH_CTRL_CH0_CLR (0x00000458)
+#define HW_PXP_INPUT_FETCH_CTRL_CH0_TOG (0x0000045c)
+
+#define BM_PXP_INPUT_FETCH_CTRL_CH0_ARBIT_EN 0x80000000
+#define BF_PXP_INPUT_FETCH_CTRL_CH0_ARBIT_EN(v) \
+ (((v) << 31) & BM_PXP_INPUT_FETCH_CTRL_CH0_ARBIT_EN)
+#define BV_PXP_INPUT_FETCH_CTRL_CH0_ARBIT_EN__0 0x0
+#define BV_PXP_INPUT_FETCH_CTRL_CH0_ARBIT_EN__1 0x1
+#define BP_PXP_INPUT_FETCH_CTRL_CH0_RSVD0 26
+#define BM_PXP_INPUT_FETCH_CTRL_CH0_RSVD0 0x7C000000
+#define BF_PXP_INPUT_FETCH_CTRL_CH0_RSVD0(v) \
+ (((v) << 26) & BM_PXP_INPUT_FETCH_CTRL_CH0_RSVD0)
+#define BP_PXP_INPUT_FETCH_CTRL_CH0_HANDSHAKE_SCAN_LINE_NUM 24
+#define BM_PXP_INPUT_FETCH_CTRL_CH0_HANDSHAKE_SCAN_LINE_NUM 0x03000000
+#define BF_PXP_INPUT_FETCH_CTRL_CH0_HANDSHAKE_SCAN_LINE_NUM(v) \
+ (((v) << 24) & BM_PXP_INPUT_FETCH_CTRL_CH0_HANDSHAKE_SCAN_LINE_NUM)
+#define BV_PXP_INPUT_FETCH_CTRL_CH0_HANDSHAKE_SCAN_LINE_NUM__0 0x0
+#define BV_PXP_INPUT_FETCH_CTRL_CH0_HANDSHAKE_SCAN_LINE_NUM__1 0x1
+#define BV_PXP_INPUT_FETCH_CTRL_CH0_HANDSHAKE_SCAN_LINE_NUM__2 0x2
+#define BV_PXP_INPUT_FETCH_CTRL_CH0_HANDSHAKE_SCAN_LINE_NUM__3 0x3
+#define BP_PXP_INPUT_FETCH_CTRL_CH0_RSVD1 18
+#define BM_PXP_INPUT_FETCH_CTRL_CH0_RSVD1 0x00FC0000
+#define BF_PXP_INPUT_FETCH_CTRL_CH0_RSVD1(v) \
+ (((v) << 18) & BM_PXP_INPUT_FETCH_CTRL_CH0_RSVD1)
+#define BP_PXP_INPUT_FETCH_CTRL_CH0_RD_NUM_BYTES 16
+#define BM_PXP_INPUT_FETCH_CTRL_CH0_RD_NUM_BYTES 0x00030000
+#define BF_PXP_INPUT_FETCH_CTRL_CH0_RD_NUM_BYTES(v) \
+ (((v) << 16) & BM_PXP_INPUT_FETCH_CTRL_CH0_RD_NUM_BYTES)
+#define BV_PXP_INPUT_FETCH_CTRL_CH0_RD_NUM_BYTES__8_bytes 0x0
+#define BV_PXP_INPUT_FETCH_CTRL_CH0_RD_NUM_BYTES__16_bytes 0x1
+#define BV_PXP_INPUT_FETCH_CTRL_CH0_RD_NUM_BYTES__32_bytes 0x2
+#define BV_PXP_INPUT_FETCH_CTRL_CH0_RD_NUM_BYTES__64_bytes 0x3
+#define BP_PXP_INPUT_FETCH_CTRL_CH0_RSVD2 14
+#define BM_PXP_INPUT_FETCH_CTRL_CH0_RSVD2 0x0000C000
+#define BF_PXP_INPUT_FETCH_CTRL_CH0_RSVD2(v) \
+ (((v) << 14) & BM_PXP_INPUT_FETCH_CTRL_CH0_RSVD2)
+#define BP_PXP_INPUT_FETCH_CTRL_CH0_ROTATION_ANGLE 12
+#define BM_PXP_INPUT_FETCH_CTRL_CH0_ROTATION_ANGLE 0x00003000
+#define BF_PXP_INPUT_FETCH_CTRL_CH0_ROTATION_ANGLE(v) \
+ (((v) << 12) & BM_PXP_INPUT_FETCH_CTRL_CH0_ROTATION_ANGLE)
+#define BV_PXP_INPUT_FETCH_CTRL_CH0_ROTATION_ANGLE__ROT_0 0x0
+#define BV_PXP_INPUT_FETCH_CTRL_CH0_ROTATION_ANGLE__ROT_90 0x1
+#define BV_PXP_INPUT_FETCH_CTRL_CH0_ROTATION_ANGLE__ROT_180 0x2
+#define BV_PXP_INPUT_FETCH_CTRL_CH0_ROTATION_ANGLE__ROT_270 0x3
+#define BM_PXP_INPUT_FETCH_CTRL_CH0_RSVD3 0x00000800
+#define BF_PXP_INPUT_FETCH_CTRL_CH0_RSVD3(v) \
+ (((v) << 11) & BM_PXP_INPUT_FETCH_CTRL_CH0_RSVD3)
+#define BM_PXP_INPUT_FETCH_CTRL_CH0_VFLIP 0x00000400
+#define BF_PXP_INPUT_FETCH_CTRL_CH0_VFLIP(v) \
+ (((v) << 10) & BM_PXP_INPUT_FETCH_CTRL_CH0_VFLIP)
+#define BV_PXP_INPUT_FETCH_CTRL_CH0_VFLIP__0 0x0
+#define BV_PXP_INPUT_FETCH_CTRL_CH0_VFLIP__1 0x1
+#define BM_PXP_INPUT_FETCH_CTRL_CH0_HFLIP 0x00000200
+#define BF_PXP_INPUT_FETCH_CTRL_CH0_HFLIP(v) \
+ (((v) << 9) & BM_PXP_INPUT_FETCH_CTRL_CH0_HFLIP)
+#define BV_PXP_INPUT_FETCH_CTRL_CH0_HFLIP__0 0x0
+#define BV_PXP_INPUT_FETCH_CTRL_CH0_HFLIP__1 0x1
+#define BP_PXP_INPUT_FETCH_CTRL_CH0_RSVD4 6
+#define BM_PXP_INPUT_FETCH_CTRL_CH0_RSVD4 0x000001C0
+#define BF_PXP_INPUT_FETCH_CTRL_CH0_RSVD4(v) \
+ (((v) << 6) & BM_PXP_INPUT_FETCH_CTRL_CH0_RSVD4)
+#define BM_PXP_INPUT_FETCH_CTRL_CH0_HIGH_BYTE 0x00000020
+#define BF_PXP_INPUT_FETCH_CTRL_CH0_HIGH_BYTE(v) \
+ (((v) << 5) & BM_PXP_INPUT_FETCH_CTRL_CH0_HIGH_BYTE)
+#define BV_PXP_INPUT_FETCH_CTRL_CH0_HIGH_BYTE__0 0x0
+#define BV_PXP_INPUT_FETCH_CTRL_CH0_HIGH_BYTE__1 0x1
+#define BM_PXP_INPUT_FETCH_CTRL_CH0_BYPASS_PIXEL_EN 0x00000010
+#define BF_PXP_INPUT_FETCH_CTRL_CH0_BYPASS_PIXEL_EN(v) \
+ (((v) << 4) & BM_PXP_INPUT_FETCH_CTRL_CH0_BYPASS_PIXEL_EN)
+#define BV_PXP_INPUT_FETCH_CTRL_CH0_BYPASS_PIXEL_EN__0 0x0
+#define BV_PXP_INPUT_FETCH_CTRL_CH0_BYPASS_PIXEL_EN__1 0x1
+#define BM_PXP_INPUT_FETCH_CTRL_CH0_HANDSHAKE_EN 0x00000008
+#define BF_PXP_INPUT_FETCH_CTRL_CH0_HANDSHAKE_EN(v) \
+ (((v) << 3) & BM_PXP_INPUT_FETCH_CTRL_CH0_HANDSHAKE_EN)
+#define BV_PXP_INPUT_FETCH_CTRL_CH0_HANDSHAKE_EN__0 0x0
+#define BV_PXP_INPUT_FETCH_CTRL_CH0_HANDSHAKE_EN__1 0x1
+#define BM_PXP_INPUT_FETCH_CTRL_CH0_BLOCK_16 0x00000004
+#define BF_PXP_INPUT_FETCH_CTRL_CH0_BLOCK_16(v) \
+ (((v) << 2) & BM_PXP_INPUT_FETCH_CTRL_CH0_BLOCK_16)
+#define BV_PXP_INPUT_FETCH_CTRL_CH0_BLOCK_16__8x8 0x0
+#define BV_PXP_INPUT_FETCH_CTRL_CH0_BLOCK_16__16x16 0x1
+#define BM_PXP_INPUT_FETCH_CTRL_CH0_BLOCK_EN 0x00000002
+#define BF_PXP_INPUT_FETCH_CTRL_CH0_BLOCK_EN(v) \
+ (((v) << 1) & BM_PXP_INPUT_FETCH_CTRL_CH0_BLOCK_EN)
+#define BV_PXP_INPUT_FETCH_CTRL_CH0_BLOCK_EN__0 0x0
+#define BV_PXP_INPUT_FETCH_CTRL_CH0_BLOCK_EN__1 0x1
+#define BM_PXP_INPUT_FETCH_CTRL_CH0_CH_EN 0x00000001
+#define BF_PXP_INPUT_FETCH_CTRL_CH0_CH_EN(v) \
+ (((v) << 0) & BM_PXP_INPUT_FETCH_CTRL_CH0_CH_EN)
+#define BV_PXP_INPUT_FETCH_CTRL_CH0_CH_EN__0 0x0
+#define BV_PXP_INPUT_FETCH_CTRL_CH0_CH_EN__1 0x1
+
+#define HW_PXP_INPUT_FETCH_CTRL_CH1 (0x00000460)
+#define HW_PXP_INPUT_FETCH_CTRL_CH1_SET (0x00000464)
+#define HW_PXP_INPUT_FETCH_CTRL_CH1_CLR (0x00000468)
+#define HW_PXP_INPUT_FETCH_CTRL_CH1_TOG (0x0000046c)
+
+#define BP_PXP_INPUT_FETCH_CTRL_CH1_RSVD0 26
+#define BM_PXP_INPUT_FETCH_CTRL_CH1_RSVD0 0xFC000000
+#define BF_PXP_INPUT_FETCH_CTRL_CH1_RSVD0(v) \
+ (((v) << 26) & BM_PXP_INPUT_FETCH_CTRL_CH1_RSVD0)
+#define BP_PXP_INPUT_FETCH_CTRL_CH1_HANDSHAKE_SCAN_LINE_NUM 24
+#define BM_PXP_INPUT_FETCH_CTRL_CH1_HANDSHAKE_SCAN_LINE_NUM 0x03000000
+#define BF_PXP_INPUT_FETCH_CTRL_CH1_HANDSHAKE_SCAN_LINE_NUM(v) \
+ (((v) << 24) & BM_PXP_INPUT_FETCH_CTRL_CH1_HANDSHAKE_SCAN_LINE_NUM)
+#define BV_PXP_INPUT_FETCH_CTRL_CH1_HANDSHAKE_SCAN_LINE_NUM__0 0x0
+#define BV_PXP_INPUT_FETCH_CTRL_CH1_HANDSHAKE_SCAN_LINE_NUM__1 0x1
+#define BV_PXP_INPUT_FETCH_CTRL_CH1_HANDSHAKE_SCAN_LINE_NUM__2 0x2
+#define BV_PXP_INPUT_FETCH_CTRL_CH1_HANDSHAKE_SCAN_LINE_NUM__3 0x3
+#define BP_PXP_INPUT_FETCH_CTRL_CH1_RSVD1 18
+#define BM_PXP_INPUT_FETCH_CTRL_CH1_RSVD1 0x00FC0000
+#define BF_PXP_INPUT_FETCH_CTRL_CH1_RSVD1(v) \
+ (((v) << 18) & BM_PXP_INPUT_FETCH_CTRL_CH1_RSVD1)
+#define BP_PXP_INPUT_FETCH_CTRL_CH1_RD_NUM_BYTES 16
+#define BM_PXP_INPUT_FETCH_CTRL_CH1_RD_NUM_BYTES 0x00030000
+#define BF_PXP_INPUT_FETCH_CTRL_CH1_RD_NUM_BYTES(v) \
+ (((v) << 16) & BM_PXP_INPUT_FETCH_CTRL_CH1_RD_NUM_BYTES)
+#define BV_PXP_INPUT_FETCH_CTRL_CH1_RD_NUM_BYTES__8_bytes 0x0
+#define BV_PXP_INPUT_FETCH_CTRL_CH1_RD_NUM_BYTES__16_bytes 0x1
+#define BV_PXP_INPUT_FETCH_CTRL_CH1_RD_NUM_BYTES__32_bytes 0x2
+#define BV_PXP_INPUT_FETCH_CTRL_CH1_RD_NUM_BYTES__64_bytes 0x3
+#define BP_PXP_INPUT_FETCH_CTRL_CH1_RSVD2 14
+#define BM_PXP_INPUT_FETCH_CTRL_CH1_RSVD2 0x0000C000
+#define BF_PXP_INPUT_FETCH_CTRL_CH1_RSVD2(v) \
+ (((v) << 14) & BM_PXP_INPUT_FETCH_CTRL_CH1_RSVD2)
+#define BP_PXP_INPUT_FETCH_CTRL_CH1_ROTATION_ANGLE 12
+#define BM_PXP_INPUT_FETCH_CTRL_CH1_ROTATION_ANGLE 0x00003000
+#define BF_PXP_INPUT_FETCH_CTRL_CH1_ROTATION_ANGLE(v) \
+ (((v) << 12) & BM_PXP_INPUT_FETCH_CTRL_CH1_ROTATION_ANGLE)
+#define BV_PXP_INPUT_FETCH_CTRL_CH1_ROTATION_ANGLE__ROT_0 0x0
+#define BV_PXP_INPUT_FETCH_CTRL_CH1_ROTATION_ANGLE__ROT_90 0x1
+#define BV_PXP_INPUT_FETCH_CTRL_CH1_ROTATION_ANGLE__ROT_180 0x2
+#define BV_PXP_INPUT_FETCH_CTRL_CH1_ROTATION_ANGLE__ROT_270 0x3
+#define BM_PXP_INPUT_FETCH_CTRL_CH1_RSVD3 0x00000800
+#define BF_PXP_INPUT_FETCH_CTRL_CH1_RSVD3(v) \
+ (((v) << 11) & BM_PXP_INPUT_FETCH_CTRL_CH1_RSVD3)
+#define BM_PXP_INPUT_FETCH_CTRL_CH1_VFLIP 0x00000400
+#define BF_PXP_INPUT_FETCH_CTRL_CH1_VFLIP(v) \
+ (((v) << 10) & BM_PXP_INPUT_FETCH_CTRL_CH1_VFLIP)
+#define BV_PXP_INPUT_FETCH_CTRL_CH1_VFLIP__0 0x0
+#define BV_PXP_INPUT_FETCH_CTRL_CH1_VFLIP__1 0x1
+#define BM_PXP_INPUT_FETCH_CTRL_CH1_HFLIP 0x00000200
+#define BF_PXP_INPUT_FETCH_CTRL_CH1_HFLIP(v) \
+ (((v) << 9) & BM_PXP_INPUT_FETCH_CTRL_CH1_HFLIP)
+#define BV_PXP_INPUT_FETCH_CTRL_CH1_HFLIP__0 0x0
+#define BV_PXP_INPUT_FETCH_CTRL_CH1_HFLIP__1 0x1
+#define BP_PXP_INPUT_FETCH_CTRL_CH1_RSVD4 5
+#define BM_PXP_INPUT_FETCH_CTRL_CH1_RSVD4 0x000001E0
+#define BF_PXP_INPUT_FETCH_CTRL_CH1_RSVD4(v) \
+ (((v) << 5) & BM_PXP_INPUT_FETCH_CTRL_CH1_RSVD4)
+#define BM_PXP_INPUT_FETCH_CTRL_CH1_BYPASS_PIXEL_EN 0x00000010
+#define BF_PXP_INPUT_FETCH_CTRL_CH1_BYPASS_PIXEL_EN(v) \
+ (((v) << 4) & BM_PXP_INPUT_FETCH_CTRL_CH1_BYPASS_PIXEL_EN)
+#define BV_PXP_INPUT_FETCH_CTRL_CH1_BYPASS_PIXEL_EN__0 0x0
+#define BV_PXP_INPUT_FETCH_CTRL_CH1_BYPASS_PIXEL_EN__1 0x1
+#define BM_PXP_INPUT_FETCH_CTRL_CH1_HANDSHAKE_EN 0x00000008
+#define BF_PXP_INPUT_FETCH_CTRL_CH1_HANDSHAKE_EN(v) \
+ (((v) << 3) & BM_PXP_INPUT_FETCH_CTRL_CH1_HANDSHAKE_EN)
+#define BV_PXP_INPUT_FETCH_CTRL_CH1_HANDSHAKE_EN__0 0x0
+#define BV_PXP_INPUT_FETCH_CTRL_CH1_HANDSHAKE_EN__1 0x1
+#define BM_PXP_INPUT_FETCH_CTRL_CH1_BLOCK_16 0x00000004
+#define BF_PXP_INPUT_FETCH_CTRL_CH1_BLOCK_16(v) \
+ (((v) << 2) & BM_PXP_INPUT_FETCH_CTRL_CH1_BLOCK_16)
+#define BV_PXP_INPUT_FETCH_CTRL_CH1_BLOCK_16__8x8 0x0
+#define BV_PXP_INPUT_FETCH_CTRL_CH1_BLOCK_16__16x16 0x1
+#define BM_PXP_INPUT_FETCH_CTRL_CH1_BLOCK_EN 0x00000002
+#define BF_PXP_INPUT_FETCH_CTRL_CH1_BLOCK_EN(v) \
+ (((v) << 1) & BM_PXP_INPUT_FETCH_CTRL_CH1_BLOCK_EN)
+#define BV_PXP_INPUT_FETCH_CTRL_CH1_BLOCK_EN__0 0x0
+#define BV_PXP_INPUT_FETCH_CTRL_CH1_BLOCK_EN__1 0x1
+#define BM_PXP_INPUT_FETCH_CTRL_CH1_CH_EN 0x00000001
+#define BF_PXP_INPUT_FETCH_CTRL_CH1_CH_EN(v) \
+ (((v) << 0) & BM_PXP_INPUT_FETCH_CTRL_CH1_CH_EN)
+#define BV_PXP_INPUT_FETCH_CTRL_CH1_CH_EN__0 0x0
+#define BV_PXP_INPUT_FETCH_CTRL_CH1_CH_EN__1 0x1
+
+#define HW_PXP_INPUT_FETCH_STATUS_CH0 (0x00000470)
+
+#define BP_PXP_INPUT_FETCH_STATUS_CH0_PREFETCH_BLOCK_Y 16
+#define BM_PXP_INPUT_FETCH_STATUS_CH0_PREFETCH_BLOCK_Y 0xFFFF0000
+#define BF_PXP_INPUT_FETCH_STATUS_CH0_PREFETCH_BLOCK_Y(v) \
+ (((v) << 16) & BM_PXP_INPUT_FETCH_STATUS_CH0_PREFETCH_BLOCK_Y)
+#define BP_PXP_INPUT_FETCH_STATUS_CH0_PREFETCH_BLOCK_X 0
+#define BM_PXP_INPUT_FETCH_STATUS_CH0_PREFETCH_BLOCK_X 0x0000FFFF
+#define BF_PXP_INPUT_FETCH_STATUS_CH0_PREFETCH_BLOCK_X(v) \
+ (((v) << 0) & BM_PXP_INPUT_FETCH_STATUS_CH0_PREFETCH_BLOCK_X)
+
+#define HW_PXP_INPUT_FETCH_STATUS_CH1 (0x00000480)
+
+#define BP_PXP_INPUT_FETCH_STATUS_CH1_PREFETCH_BLOCK_Y 16
+#define BM_PXP_INPUT_FETCH_STATUS_CH1_PREFETCH_BLOCK_Y 0xFFFF0000
+#define BF_PXP_INPUT_FETCH_STATUS_CH1_PREFETCH_BLOCK_Y(v) \
+ (((v) << 16) & BM_PXP_INPUT_FETCH_STATUS_CH1_PREFETCH_BLOCK_Y)
+#define BP_PXP_INPUT_FETCH_STATUS_CH1_PREFETCH_BLOCK_X 0
+#define BM_PXP_INPUT_FETCH_STATUS_CH1_PREFETCH_BLOCK_X 0x0000FFFF
+#define BF_PXP_INPUT_FETCH_STATUS_CH1_PREFETCH_BLOCK_X(v) \
+ (((v) << 0) & BM_PXP_INPUT_FETCH_STATUS_CH1_PREFETCH_BLOCK_X)
+
+#define HW_PXP_INPUT_FETCH_ACTIVE_SIZE_ULC_CH0 (0x00000490)
+
+#define BP_PXP_INPUT_FETCH_ACTIVE_SIZE_ULC_CH0_ACTIVE_SIZE_ULC_Y 16
+#define BM_PXP_INPUT_FETCH_ACTIVE_SIZE_ULC_CH0_ACTIVE_SIZE_ULC_Y 0xFFFF0000
+#define BF_PXP_INPUT_FETCH_ACTIVE_SIZE_ULC_CH0_ACTIVE_SIZE_ULC_Y(v) \
+ (((v) << 16) & BM_PXP_INPUT_FETCH_ACTIVE_SIZE_ULC_CH0_ACTIVE_SIZE_ULC_Y)
+#define BP_PXP_INPUT_FETCH_ACTIVE_SIZE_ULC_CH0_ACTIVE_SIZE_ULC_X 0
+#define BM_PXP_INPUT_FETCH_ACTIVE_SIZE_ULC_CH0_ACTIVE_SIZE_ULC_X 0x0000FFFF
+#define BF_PXP_INPUT_FETCH_ACTIVE_SIZE_ULC_CH0_ACTIVE_SIZE_ULC_X(v) \
+ (((v) << 0) & BM_PXP_INPUT_FETCH_ACTIVE_SIZE_ULC_CH0_ACTIVE_SIZE_ULC_X)
+
+#define HW_PXP_INPUT_FETCH_ACTIVE_SIZE_LRC_CH0 (0x000004a0)
+
+#define BP_PXP_INPUT_FETCH_ACTIVE_SIZE_LRC_CH0_ACTIVE_SIZE_LRC_Y 16
+#define BM_PXP_INPUT_FETCH_ACTIVE_SIZE_LRC_CH0_ACTIVE_SIZE_LRC_Y 0xFFFF0000
+#define BF_PXP_INPUT_FETCH_ACTIVE_SIZE_LRC_CH0_ACTIVE_SIZE_LRC_Y(v) \
+ (((v) << 16) & BM_PXP_INPUT_FETCH_ACTIVE_SIZE_LRC_CH0_ACTIVE_SIZE_LRC_Y)
+#define BP_PXP_INPUT_FETCH_ACTIVE_SIZE_LRC_CH0_ACTIVE_SIZE_LRC_X 0
+#define BM_PXP_INPUT_FETCH_ACTIVE_SIZE_LRC_CH0_ACTIVE_SIZE_LRC_X 0x0000FFFF
+#define BF_PXP_INPUT_FETCH_ACTIVE_SIZE_LRC_CH0_ACTIVE_SIZE_LRC_X(v) \
+ (((v) << 0) & BM_PXP_INPUT_FETCH_ACTIVE_SIZE_LRC_CH0_ACTIVE_SIZE_LRC_X)
+
+#define HW_PXP_INPUT_FETCH_ACTIVE_SIZE_ULC_CH1 (0x000004b0)
+
+#define BP_PXP_INPUT_FETCH_ACTIVE_SIZE_ULC_CH1_ACTIVE_SIZE_ULC_Y 16
+#define BM_PXP_INPUT_FETCH_ACTIVE_SIZE_ULC_CH1_ACTIVE_SIZE_ULC_Y 0xFFFF0000
+#define BF_PXP_INPUT_FETCH_ACTIVE_SIZE_ULC_CH1_ACTIVE_SIZE_ULC_Y(v) \
+ (((v) << 16) & BM_PXP_INPUT_FETCH_ACTIVE_SIZE_ULC_CH1_ACTIVE_SIZE_ULC_Y)
+#define BP_PXP_INPUT_FETCH_ACTIVE_SIZE_ULC_CH1_ACTIVE_SIZE_ULC_X 0
+#define BM_PXP_INPUT_FETCH_ACTIVE_SIZE_ULC_CH1_ACTIVE_SIZE_ULC_X 0x0000FFFF
+#define BF_PXP_INPUT_FETCH_ACTIVE_SIZE_ULC_CH1_ACTIVE_SIZE_ULC_X(v) \
+ (((v) << 0) & BM_PXP_INPUT_FETCH_ACTIVE_SIZE_ULC_CH1_ACTIVE_SIZE_ULC_X)
+
+#define HW_PXP_INPUT_FETCH_ACTIVE_SIZE_LRC_CH1 (0x000004c0)
+
+#define BP_PXP_INPUT_FETCH_ACTIVE_SIZE_LRC_CH1_ACTIVE_SIZE_LRC_Y 16
+#define BM_PXP_INPUT_FETCH_ACTIVE_SIZE_LRC_CH1_ACTIVE_SIZE_LRC_Y 0xFFFF0000
+#define BF_PXP_INPUT_FETCH_ACTIVE_SIZE_LRC_CH1_ACTIVE_SIZE_LRC_Y(v) \
+ (((v) << 16) & BM_PXP_INPUT_FETCH_ACTIVE_SIZE_LRC_CH1_ACTIVE_SIZE_LRC_Y)
+#define BP_PXP_INPUT_FETCH_ACTIVE_SIZE_LRC_CH1_ACTIVE_SIZE_LRC_X 0
+#define BM_PXP_INPUT_FETCH_ACTIVE_SIZE_LRC_CH1_ACTIVE_SIZE_LRC_X 0x0000FFFF
+#define BF_PXP_INPUT_FETCH_ACTIVE_SIZE_LRC_CH1_ACTIVE_SIZE_LRC_X(v) \
+ (((v) << 0) & BM_PXP_INPUT_FETCH_ACTIVE_SIZE_LRC_CH1_ACTIVE_SIZE_LRC_X)
+
+#define HW_PXP_INPUT_FETCH_SIZE_CH0 (0x000004d0)
+
+#define BP_PXP_INPUT_FETCH_SIZE_CH0_INPUT_TOTAL_HEIGHT 16
+#define BM_PXP_INPUT_FETCH_SIZE_CH0_INPUT_TOTAL_HEIGHT 0xFFFF0000
+#define BF_PXP_INPUT_FETCH_SIZE_CH0_INPUT_TOTAL_HEIGHT(v) \
+ (((v) << 16) & BM_PXP_INPUT_FETCH_SIZE_CH0_INPUT_TOTAL_HEIGHT)
+#define BP_PXP_INPUT_FETCH_SIZE_CH0_INPUT_TOTAL_WIDTH 0
+#define BM_PXP_INPUT_FETCH_SIZE_CH0_INPUT_TOTAL_WIDTH 0x0000FFFF
+#define BF_PXP_INPUT_FETCH_SIZE_CH0_INPUT_TOTAL_WIDTH(v) \
+ (((v) << 0) & BM_PXP_INPUT_FETCH_SIZE_CH0_INPUT_TOTAL_WIDTH)
+
+#define HW_PXP_INPUT_FETCH_SIZE_CH1 (0x000004e0)
+
+#define BP_PXP_INPUT_FETCH_SIZE_CH1_INPUT_TOTAL_HEIGHT 16
+#define BM_PXP_INPUT_FETCH_SIZE_CH1_INPUT_TOTAL_HEIGHT 0xFFFF0000
+#define BF_PXP_INPUT_FETCH_SIZE_CH1_INPUT_TOTAL_HEIGHT(v) \
+ (((v) << 16) & BM_PXP_INPUT_FETCH_SIZE_CH1_INPUT_TOTAL_HEIGHT)
+#define BP_PXP_INPUT_FETCH_SIZE_CH1_INPUT_TOTAL_WIDTH 0
+#define BM_PXP_INPUT_FETCH_SIZE_CH1_INPUT_TOTAL_WIDTH 0x0000FFFF
+#define BF_PXP_INPUT_FETCH_SIZE_CH1_INPUT_TOTAL_WIDTH(v) \
+ (((v) << 0) & BM_PXP_INPUT_FETCH_SIZE_CH1_INPUT_TOTAL_WIDTH)
+
+#define HW_PXP_INPUT_FETCH_BACKGROUND_COLOR_CH0 (0x000004f0)
+
+#define BP_PXP_INPUT_FETCH_BACKGROUND_COLOR_CH0_BACKGROUND_COLOR 0
+#define BM_PXP_INPUT_FETCH_BACKGROUND_COLOR_CH0_BACKGROUND_COLOR 0xFFFFFFFF
+#define BF_PXP_INPUT_FETCH_BACKGROUND_COLOR_CH0_BACKGROUND_COLOR(v) (v)
+
+#define HW_PXP_INPUT_FETCH_BACKGROUND_COLOR_CH1 (0x00000500)
+
+#define BP_PXP_INPUT_FETCH_BACKGROUND_COLOR_CH1_BACKGROUND_COLOR 0
+#define BM_PXP_INPUT_FETCH_BACKGROUND_COLOR_CH1_BACKGROUND_COLOR 0xFFFFFFFF
+#define BF_PXP_INPUT_FETCH_BACKGROUND_COLOR_CH1_BACKGROUND_COLOR(v) (v)
+
+#define HW_PXP_INPUT_FETCH_PITCH (0x00000510)
+
+#define BP_PXP_INPUT_FETCH_PITCH_CH1_INPUT_PITCH 16
+#define BM_PXP_INPUT_FETCH_PITCH_CH1_INPUT_PITCH 0xFFFF0000
+#define BF_PXP_INPUT_FETCH_PITCH_CH1_INPUT_PITCH(v) \
+ (((v) << 16) & BM_PXP_INPUT_FETCH_PITCH_CH1_INPUT_PITCH)
+#define BP_PXP_INPUT_FETCH_PITCH_CH0_INPUT_PITCH 0
+#define BM_PXP_INPUT_FETCH_PITCH_CH0_INPUT_PITCH 0x0000FFFF
+#define BF_PXP_INPUT_FETCH_PITCH_CH0_INPUT_PITCH(v) \
+ (((v) << 0) & BM_PXP_INPUT_FETCH_PITCH_CH0_INPUT_PITCH)
+
+#define HW_PXP_INPUT_FETCH_SHIFT_CTRL_CH0 (0x00000520)
+#define HW_PXP_INPUT_FETCH_SHIFT_CTRL_CH0_SET (0x00000524)
+#define HW_PXP_INPUT_FETCH_SHIFT_CTRL_CH0_CLR (0x00000528)
+#define HW_PXP_INPUT_FETCH_SHIFT_CTRL_CH0_TOG (0x0000052c)
+
+#define BP_PXP_INPUT_FETCH_SHIFT_CTRL_CH0_RSVD0 13
+#define BM_PXP_INPUT_FETCH_SHIFT_CTRL_CH0_RSVD0 0xFFFFE000
+#define BF_PXP_INPUT_FETCH_SHIFT_CTRL_CH0_RSVD0(v) \
+ (((v) << 13) & BM_PXP_INPUT_FETCH_SHIFT_CTRL_CH0_RSVD0)
+#define BM_PXP_INPUT_FETCH_SHIFT_CTRL_CH0_SHIFT_BYPASS 0x00001000
+#define BF_PXP_INPUT_FETCH_SHIFT_CTRL_CH0_SHIFT_BYPASS(v) \
+ (((v) << 12) & BM_PXP_INPUT_FETCH_SHIFT_CTRL_CH0_SHIFT_BYPASS)
+#define BV_PXP_INPUT_FETCH_SHIFT_CTRL_CH0_SHIFT_BYPASS__0 0x0
+#define BV_PXP_INPUT_FETCH_SHIFT_CTRL_CH0_SHIFT_BYPASS__1 0x1
+#define BM_PXP_INPUT_FETCH_SHIFT_CTRL_CH0_EXPAND_EN 0x00000800
+#define BF_PXP_INPUT_FETCH_SHIFT_CTRL_CH0_EXPAND_EN(v) \
+ (((v) << 11) & BM_PXP_INPUT_FETCH_SHIFT_CTRL_CH0_EXPAND_EN)
+#define BV_PXP_INPUT_FETCH_SHIFT_CTRL_CH0_EXPAND_EN__0 0x0
+#define BV_PXP_INPUT_FETCH_SHIFT_CTRL_CH0_EXPAND_EN__1 0x1
+#define BP_PXP_INPUT_FETCH_SHIFT_CTRL_CH0_EXPAND_FORMAT 8
+#define BM_PXP_INPUT_FETCH_SHIFT_CTRL_CH0_EXPAND_FORMAT 0x00000700
+#define BF_PXP_INPUT_FETCH_SHIFT_CTRL_CH0_EXPAND_FORMAT(v) \
+ (((v) << 8) & BM_PXP_INPUT_FETCH_SHIFT_CTRL_CH0_EXPAND_FORMAT)
+#define BV_PXP_INPUT_FETCH_SHIFT_CTRL_CH0_EXPAND_FORMAT__0 0x0
+#define BV_PXP_INPUT_FETCH_SHIFT_CTRL_CH0_EXPAND_FORMAT__1 0x1
+#define BV_PXP_INPUT_FETCH_SHIFT_CTRL_CH0_EXPAND_FORMAT__2 0x2
+#define BV_PXP_INPUT_FETCH_SHIFT_CTRL_CH0_EXPAND_FORMAT__3 0x3
+#define BV_PXP_INPUT_FETCH_SHIFT_CTRL_CH0_EXPAND_FORMAT__4 0x4
+#define BV_PXP_INPUT_FETCH_SHIFT_CTRL_CH0_EXPAND_FORMAT__5 0x5
+#define BV_PXP_INPUT_FETCH_SHIFT_CTRL_CH0_EXPAND_FORMAT__6 0x6
+#define BV_PXP_INPUT_FETCH_SHIFT_CTRL_CH0_EXPAND_FORMAT__7 0x7
+#define BP_PXP_INPUT_FETCH_SHIFT_CTRL_CH0_RSVD1 2
+#define BM_PXP_INPUT_FETCH_SHIFT_CTRL_CH0_RSVD1 0x000000FC
+#define BF_PXP_INPUT_FETCH_SHIFT_CTRL_CH0_RSVD1(v) \
+ (((v) << 2) & BM_PXP_INPUT_FETCH_SHIFT_CTRL_CH0_RSVD1)
+#define BP_PXP_INPUT_FETCH_SHIFT_CTRL_CH0_INPUT_ACTIVE_BPP 0
+#define BM_PXP_INPUT_FETCH_SHIFT_CTRL_CH0_INPUT_ACTIVE_BPP 0x00000003
+#define BF_PXP_INPUT_FETCH_SHIFT_CTRL_CH0_INPUT_ACTIVE_BPP(v) \
+ (((v) << 0) & BM_PXP_INPUT_FETCH_SHIFT_CTRL_CH0_INPUT_ACTIVE_BPP)
+#define BV_PXP_INPUT_FETCH_SHIFT_CTRL_CH0_INPUT_ACTIVE_BPP__0 0x0
+#define BV_PXP_INPUT_FETCH_SHIFT_CTRL_CH0_INPUT_ACTIVE_BPP__1 0x1
+#define BV_PXP_INPUT_FETCH_SHIFT_CTRL_CH0_INPUT_ACTIVE_BPP__2 0x2
+#define BV_PXP_INPUT_FETCH_SHIFT_CTRL_CH0_INPUT_ACTIVE_BPP__3 0x3
+
+#define HW_PXP_INPUT_FETCH_SHIFT_CTRL_CH1 (0x00000530)
+#define HW_PXP_INPUT_FETCH_SHIFT_CTRL_CH1_SET (0x00000534)
+#define HW_PXP_INPUT_FETCH_SHIFT_CTRL_CH1_CLR (0x00000538)
+#define HW_PXP_INPUT_FETCH_SHIFT_CTRL_CH1_TOG (0x0000053c)
+
+#define BP_PXP_INPUT_FETCH_SHIFT_CTRL_CH1_RSVD0 13
+#define BM_PXP_INPUT_FETCH_SHIFT_CTRL_CH1_RSVD0 0xFFFFE000
+#define BF_PXP_INPUT_FETCH_SHIFT_CTRL_CH1_RSVD0(v) \
+ (((v) << 13) & BM_PXP_INPUT_FETCH_SHIFT_CTRL_CH1_RSVD0)
+#define BM_PXP_INPUT_FETCH_SHIFT_CTRL_CH1_SHIFT_BYPASS 0x00001000
+#define BF_PXP_INPUT_FETCH_SHIFT_CTRL_CH1_SHIFT_BYPASS(v) \
+ (((v) << 12) & BM_PXP_INPUT_FETCH_SHIFT_CTRL_CH1_SHIFT_BYPASS)
+#define BV_PXP_INPUT_FETCH_SHIFT_CTRL_CH1_SHIFT_BYPASS__0 0x0
+#define BV_PXP_INPUT_FETCH_SHIFT_CTRL_CH1_SHIFT_BYPASS__1 0x1
+#define BM_PXP_INPUT_FETCH_SHIFT_CTRL_CH1_EXPAND_EN 0x00000800
+#define BF_PXP_INPUT_FETCH_SHIFT_CTRL_CH1_EXPAND_EN(v) \
+ (((v) << 11) & BM_PXP_INPUT_FETCH_SHIFT_CTRL_CH1_EXPAND_EN)
+#define BV_PXP_INPUT_FETCH_SHIFT_CTRL_CH1_EXPAND_EN__0 0x0
+#define BV_PXP_INPUT_FETCH_SHIFT_CTRL_CH1_EXPAND_EN__1 0x1
+#define BP_PXP_INPUT_FETCH_SHIFT_CTRL_CH1_EXPAND_FORMAT 8
+#define BM_PXP_INPUT_FETCH_SHIFT_CTRL_CH1_EXPAND_FORMAT 0x00000700
+#define BF_PXP_INPUT_FETCH_SHIFT_CTRL_CH1_EXPAND_FORMAT(v) \
+ (((v) << 8) & BM_PXP_INPUT_FETCH_SHIFT_CTRL_CH1_EXPAND_FORMAT)
+#define BV_PXP_INPUT_FETCH_SHIFT_CTRL_CH1_EXPAND_FORMAT__0 0x0
+#define BV_PXP_INPUT_FETCH_SHIFT_CTRL_CH1_EXPAND_FORMAT__1 0x1
+#define BV_PXP_INPUT_FETCH_SHIFT_CTRL_CH1_EXPAND_FORMAT__2 0x2
+#define BV_PXP_INPUT_FETCH_SHIFT_CTRL_CH1_EXPAND_FORMAT__3 0x3
+#define BV_PXP_INPUT_FETCH_SHIFT_CTRL_CH1_EXPAND_FORMAT__4 0x4
+#define BV_PXP_INPUT_FETCH_SHIFT_CTRL_CH1_EXPAND_FORMAT__5 0x5
+#define BV_PXP_INPUT_FETCH_SHIFT_CTRL_CH1_EXPAND_FORMAT__6 0x6
+#define BV_PXP_INPUT_FETCH_SHIFT_CTRL_CH1_EXPAND_FORMAT__7 0x7
+#define BP_PXP_INPUT_FETCH_SHIFT_CTRL_CH1_RSVD1 2
+#define BM_PXP_INPUT_FETCH_SHIFT_CTRL_CH1_RSVD1 0x000000FC
+#define BF_PXP_INPUT_FETCH_SHIFT_CTRL_CH1_RSVD1(v) \
+ (((v) << 2) & BM_PXP_INPUT_FETCH_SHIFT_CTRL_CH1_RSVD1)
+#define BP_PXP_INPUT_FETCH_SHIFT_CTRL_CH1_INPUT_ACTIVE_BPP 0
+#define BM_PXP_INPUT_FETCH_SHIFT_CTRL_CH1_INPUT_ACTIVE_BPP 0x00000003
+#define BF_PXP_INPUT_FETCH_SHIFT_CTRL_CH1_INPUT_ACTIVE_BPP(v) \
+ (((v) << 0) & BM_PXP_INPUT_FETCH_SHIFT_CTRL_CH1_INPUT_ACTIVE_BPP)
+#define BV_PXP_INPUT_FETCH_SHIFT_CTRL_CH1_INPUT_ACTIVE_BPP__0 0x0
+#define BV_PXP_INPUT_FETCH_SHIFT_CTRL_CH1_INPUT_ACTIVE_BPP__1 0x1
+#define BV_PXP_INPUT_FETCH_SHIFT_CTRL_CH1_INPUT_ACTIVE_BPP__2 0x2
+#define BV_PXP_INPUT_FETCH_SHIFT_CTRL_CH1_INPUT_ACTIVE_BPP__3 0x3
+
+#define HW_PXP_INPUT_FETCH_SHIFT_OFFSET_CH0 (0x00000540)
+#define HW_PXP_INPUT_FETCH_SHIFT_OFFSET_CH0_SET (0x00000544)
+#define HW_PXP_INPUT_FETCH_SHIFT_OFFSET_CH0_CLR (0x00000548)
+#define HW_PXP_INPUT_FETCH_SHIFT_OFFSET_CH0_TOG (0x0000054c)
+
+#define BP_PXP_INPUT_FETCH_SHIFT_OFFSET_CH0_RSVD0 29
+#define BM_PXP_INPUT_FETCH_SHIFT_OFFSET_CH0_RSVD0 0xE0000000
+#define BF_PXP_INPUT_FETCH_SHIFT_OFFSET_CH0_RSVD0(v) \
+ (((v) << 29) & BM_PXP_INPUT_FETCH_SHIFT_OFFSET_CH0_RSVD0)
+#define BP_PXP_INPUT_FETCH_SHIFT_OFFSET_CH0_OFFSET3 24
+#define BM_PXP_INPUT_FETCH_SHIFT_OFFSET_CH0_OFFSET3 0x1F000000
+#define BF_PXP_INPUT_FETCH_SHIFT_OFFSET_CH0_OFFSET3(v) \
+ (((v) << 24) & BM_PXP_INPUT_FETCH_SHIFT_OFFSET_CH0_OFFSET3)
+#define BP_PXP_INPUT_FETCH_SHIFT_OFFSET_CH0_RSVD1 21
+#define BM_PXP_INPUT_FETCH_SHIFT_OFFSET_CH0_RSVD1 0x00E00000
+#define BF_PXP_INPUT_FETCH_SHIFT_OFFSET_CH0_RSVD1(v) \
+ (((v) << 21) & BM_PXP_INPUT_FETCH_SHIFT_OFFSET_CH0_RSVD1)
+#define BP_PXP_INPUT_FETCH_SHIFT_OFFSET_CH0_OFFSET2 16
+#define BM_PXP_INPUT_FETCH_SHIFT_OFFSET_CH0_OFFSET2 0x001F0000
+#define BF_PXP_INPUT_FETCH_SHIFT_OFFSET_CH0_OFFSET2(v) \
+ (((v) << 16) & BM_PXP_INPUT_FETCH_SHIFT_OFFSET_CH0_OFFSET2)
+#define BP_PXP_INPUT_FETCH_SHIFT_OFFSET_CH0_RSVD2 13
+#define BM_PXP_INPUT_FETCH_SHIFT_OFFSET_CH0_RSVD2 0x0000E000
+#define BF_PXP_INPUT_FETCH_SHIFT_OFFSET_CH0_RSVD2(v) \
+ (((v) << 13) & BM_PXP_INPUT_FETCH_SHIFT_OFFSET_CH0_RSVD2)
+#define BP_PXP_INPUT_FETCH_SHIFT_OFFSET_CH0_OFFSET1 8
+#define BM_PXP_INPUT_FETCH_SHIFT_OFFSET_CH0_OFFSET1 0x00001F00
+#define BF_PXP_INPUT_FETCH_SHIFT_OFFSET_CH0_OFFSET1(v) \
+ (((v) << 8) & BM_PXP_INPUT_FETCH_SHIFT_OFFSET_CH0_OFFSET1)
+#define BP_PXP_INPUT_FETCH_SHIFT_OFFSET_CH0_RSVD3 5
+#define BM_PXP_INPUT_FETCH_SHIFT_OFFSET_CH0_RSVD3 0x000000E0
+#define BF_PXP_INPUT_FETCH_SHIFT_OFFSET_CH0_RSVD3(v) \
+ (((v) << 5) & BM_PXP_INPUT_FETCH_SHIFT_OFFSET_CH0_RSVD3)
+#define BP_PXP_INPUT_FETCH_SHIFT_OFFSET_CH0_OFFSET0 0
+#define BM_PXP_INPUT_FETCH_SHIFT_OFFSET_CH0_OFFSET0 0x0000001F
+#define BF_PXP_INPUT_FETCH_SHIFT_OFFSET_CH0_OFFSET0(v) \
+ (((v) << 0) & BM_PXP_INPUT_FETCH_SHIFT_OFFSET_CH0_OFFSET0)
+
+#define HW_PXP_INPUT_FETCH_SHIFT_OFFSET_CH1 (0x00000550)
+#define HW_PXP_INPUT_FETCH_SHIFT_OFFSET_CH1_SET (0x00000554)
+#define HW_PXP_INPUT_FETCH_SHIFT_OFFSET_CH1_CLR (0x00000558)
+#define HW_PXP_INPUT_FETCH_SHIFT_OFFSET_CH1_TOG (0x0000055c)
+
+#define BP_PXP_INPUT_FETCH_SHIFT_OFFSET_CH1_RSVD0 29
+#define BM_PXP_INPUT_FETCH_SHIFT_OFFSET_CH1_RSVD0 0xE0000000
+#define BF_PXP_INPUT_FETCH_SHIFT_OFFSET_CH1_RSVD0(v) \
+ (((v) << 29) & BM_PXP_INPUT_FETCH_SHIFT_OFFSET_CH1_RSVD0)
+#define BP_PXP_INPUT_FETCH_SHIFT_OFFSET_CH1_OFFSET3 24
+#define BM_PXP_INPUT_FETCH_SHIFT_OFFSET_CH1_OFFSET3 0x1F000000
+#define BF_PXP_INPUT_FETCH_SHIFT_OFFSET_CH1_OFFSET3(v) \
+ (((v) << 24) & BM_PXP_INPUT_FETCH_SHIFT_OFFSET_CH1_OFFSET3)
+#define BP_PXP_INPUT_FETCH_SHIFT_OFFSET_CH1_RSVD1 21
+#define BM_PXP_INPUT_FETCH_SHIFT_OFFSET_CH1_RSVD1 0x00E00000
+#define BF_PXP_INPUT_FETCH_SHIFT_OFFSET_CH1_RSVD1(v) \
+ (((v) << 21) & BM_PXP_INPUT_FETCH_SHIFT_OFFSET_CH1_RSVD1)
+#define BP_PXP_INPUT_FETCH_SHIFT_OFFSET_CH1_OFFSET2 16
+#define BM_PXP_INPUT_FETCH_SHIFT_OFFSET_CH1_OFFSET2 0x001F0000
+#define BF_PXP_INPUT_FETCH_SHIFT_OFFSET_CH1_OFFSET2(v) \
+ (((v) << 16) & BM_PXP_INPUT_FETCH_SHIFT_OFFSET_CH1_OFFSET2)
+#define BP_PXP_INPUT_FETCH_SHIFT_OFFSET_CH1_RSVD2 13
+#define BM_PXP_INPUT_FETCH_SHIFT_OFFSET_CH1_RSVD2 0x0000E000
+#define BF_PXP_INPUT_FETCH_SHIFT_OFFSET_CH1_RSVD2(v) \
+ (((v) << 13) & BM_PXP_INPUT_FETCH_SHIFT_OFFSET_CH1_RSVD2)
+#define BP_PXP_INPUT_FETCH_SHIFT_OFFSET_CH1_OFFSET1 8
+#define BM_PXP_INPUT_FETCH_SHIFT_OFFSET_CH1_OFFSET1 0x00001F00
+#define BF_PXP_INPUT_FETCH_SHIFT_OFFSET_CH1_OFFSET1(v) \
+ (((v) << 8) & BM_PXP_INPUT_FETCH_SHIFT_OFFSET_CH1_OFFSET1)
+#define BP_PXP_INPUT_FETCH_SHIFT_OFFSET_CH1_RSVD3 5
+#define BM_PXP_INPUT_FETCH_SHIFT_OFFSET_CH1_RSVD3 0x000000E0
+#define BF_PXP_INPUT_FETCH_SHIFT_OFFSET_CH1_RSVD3(v) \
+ (((v) << 5) & BM_PXP_INPUT_FETCH_SHIFT_OFFSET_CH1_RSVD3)
+#define BP_PXP_INPUT_FETCH_SHIFT_OFFSET_CH1_OFFSET0 0
+#define BM_PXP_INPUT_FETCH_SHIFT_OFFSET_CH1_OFFSET0 0x0000001F
+#define BF_PXP_INPUT_FETCH_SHIFT_OFFSET_CH1_OFFSET0(v) \
+ (((v) << 0) & BM_PXP_INPUT_FETCH_SHIFT_OFFSET_CH1_OFFSET0)
+
+#define HW_PXP_INPUT_FETCH_SHIFT_WIDTH_CH0 (0x00000560)
+#define HW_PXP_INPUT_FETCH_SHIFT_WIDTH_CH0_SET (0x00000564)
+#define HW_PXP_INPUT_FETCH_SHIFT_WIDTH_CH0_CLR (0x00000568)
+#define HW_PXP_INPUT_FETCH_SHIFT_WIDTH_CH0_TOG (0x0000056c)
+
+#define BP_PXP_INPUT_FETCH_SHIFT_WIDTH_CH0_RSVD0 16
+#define BM_PXP_INPUT_FETCH_SHIFT_WIDTH_CH0_RSVD0 0xFFFF0000
+#define BF_PXP_INPUT_FETCH_SHIFT_WIDTH_CH0_RSVD0(v) \
+ (((v) << 16) & BM_PXP_INPUT_FETCH_SHIFT_WIDTH_CH0_RSVD0)
+#define BP_PXP_INPUT_FETCH_SHIFT_WIDTH_CH0_WIDTH3 12
+#define BM_PXP_INPUT_FETCH_SHIFT_WIDTH_CH0_WIDTH3 0x0000F000
+#define BF_PXP_INPUT_FETCH_SHIFT_WIDTH_CH0_WIDTH3(v) \
+ (((v) << 12) & BM_PXP_INPUT_FETCH_SHIFT_WIDTH_CH0_WIDTH3)
+#define BP_PXP_INPUT_FETCH_SHIFT_WIDTH_CH0_WIDTH2 8
+#define BM_PXP_INPUT_FETCH_SHIFT_WIDTH_CH0_WIDTH2 0x00000F00
+#define BF_PXP_INPUT_FETCH_SHIFT_WIDTH_CH0_WIDTH2(v) \
+ (((v) << 8) & BM_PXP_INPUT_FETCH_SHIFT_WIDTH_CH0_WIDTH2)
+#define BP_PXP_INPUT_FETCH_SHIFT_WIDTH_CH0_WIDTH1 4
+#define BM_PXP_INPUT_FETCH_SHIFT_WIDTH_CH0_WIDTH1 0x000000F0
+#define BF_PXP_INPUT_FETCH_SHIFT_WIDTH_CH0_WIDTH1(v) \
+ (((v) << 4) & BM_PXP_INPUT_FETCH_SHIFT_WIDTH_CH0_WIDTH1)
+#define BP_PXP_INPUT_FETCH_SHIFT_WIDTH_CH0_WIDTH0 0
+#define BM_PXP_INPUT_FETCH_SHIFT_WIDTH_CH0_WIDTH0 0x0000000F
+#define BF_PXP_INPUT_FETCH_SHIFT_WIDTH_CH0_WIDTH0(v) \
+ (((v) << 0) & BM_PXP_INPUT_FETCH_SHIFT_WIDTH_CH0_WIDTH0)
+
+#define HW_PXP_INPUT_FETCH_SHIFT_WIDTH_CH1 (0x00000570)
+#define HW_PXP_INPUT_FETCH_SHIFT_WIDTH_CH1_SET (0x00000574)
+#define HW_PXP_INPUT_FETCH_SHIFT_WIDTH_CH1_CLR (0x00000578)
+#define HW_PXP_INPUT_FETCH_SHIFT_WIDTH_CH1_TOG (0x0000057c)
+
+#define BP_PXP_INPUT_FETCH_SHIFT_WIDTH_CH1_RSVD0 16
+#define BM_PXP_INPUT_FETCH_SHIFT_WIDTH_CH1_RSVD0 0xFFFF0000
+#define BF_PXP_INPUT_FETCH_SHIFT_WIDTH_CH1_RSVD0(v) \
+ (((v) << 16) & BM_PXP_INPUT_FETCH_SHIFT_WIDTH_CH1_RSVD0)
+#define BP_PXP_INPUT_FETCH_SHIFT_WIDTH_CH1_WIDTH3 12
+#define BM_PXP_INPUT_FETCH_SHIFT_WIDTH_CH1_WIDTH3 0x0000F000
+#define BF_PXP_INPUT_FETCH_SHIFT_WIDTH_CH1_WIDTH3(v) \
+ (((v) << 12) & BM_PXP_INPUT_FETCH_SHIFT_WIDTH_CH1_WIDTH3)
+#define BP_PXP_INPUT_FETCH_SHIFT_WIDTH_CH1_WIDTH2 8
+#define BM_PXP_INPUT_FETCH_SHIFT_WIDTH_CH1_WIDTH2 0x00000F00
+#define BF_PXP_INPUT_FETCH_SHIFT_WIDTH_CH1_WIDTH2(v) \
+ (((v) << 8) & BM_PXP_INPUT_FETCH_SHIFT_WIDTH_CH1_WIDTH2)
+#define BP_PXP_INPUT_FETCH_SHIFT_WIDTH_CH1_WIDTH1 4
+#define BM_PXP_INPUT_FETCH_SHIFT_WIDTH_CH1_WIDTH1 0x000000F0
+#define BF_PXP_INPUT_FETCH_SHIFT_WIDTH_CH1_WIDTH1(v) \
+ (((v) << 4) & BM_PXP_INPUT_FETCH_SHIFT_WIDTH_CH1_WIDTH1)
+#define BP_PXP_INPUT_FETCH_SHIFT_WIDTH_CH1_WIDTH0 0
+#define BM_PXP_INPUT_FETCH_SHIFT_WIDTH_CH1_WIDTH0 0x0000000F
+#define BF_PXP_INPUT_FETCH_SHIFT_WIDTH_CH1_WIDTH0(v) \
+ (((v) << 0) & BM_PXP_INPUT_FETCH_SHIFT_WIDTH_CH1_WIDTH0)
+
+#define HW_PXP_INPUT_FETCH_ADDR_0_CH0 (0x00000580)
+
+#define BP_PXP_INPUT_FETCH_ADDR_0_CH0_INPUT_BASE_ADDR0 0
+#define BM_PXP_INPUT_FETCH_ADDR_0_CH0_INPUT_BASE_ADDR0 0xFFFFFFFF
+#define BF_PXP_INPUT_FETCH_ADDR_0_CH0_INPUT_BASE_ADDR0(v) (v)
+
+#define HW_PXP_INPUT_FETCH_ADDR_1_CH0 (0x00000590)
+
+#define BP_PXP_INPUT_FETCH_ADDR_1_CH0_INPUT_BASE_ADDR1 0
+#define BM_PXP_INPUT_FETCH_ADDR_1_CH0_INPUT_BASE_ADDR1 0xFFFFFFFF
+#define BF_PXP_INPUT_FETCH_ADDR_1_CH0_INPUT_BASE_ADDR1(v) (v)
+
+#define HW_PXP_INPUT_FETCH_ADDR_0_CH1 (0x000005a0)
+
+#define BP_PXP_INPUT_FETCH_ADDR_0_CH1_INPUT_BASE_ADDR0 0
+#define BM_PXP_INPUT_FETCH_ADDR_0_CH1_INPUT_BASE_ADDR0 0xFFFFFFFF
+#define BF_PXP_INPUT_FETCH_ADDR_0_CH1_INPUT_BASE_ADDR0(v) (v)
+
+#define HW_PXP_INPUT_FETCH_ADDR_1_CH1 (0x000005b0)
+
+#define BP_PXP_INPUT_FETCH_ADDR_1_CH1_INPUT_BASE_ADDR1 0
+#define BM_PXP_INPUT_FETCH_ADDR_1_CH1_INPUT_BASE_ADDR1 0xFFFFFFFF
+#define BF_PXP_INPUT_FETCH_ADDR_1_CH1_INPUT_BASE_ADDR1(v) (v)
+
+#define HW_PXP_INPUT_STORE_CTRL_CH0 (0x000005c0)
+#define HW_PXP_INPUT_STORE_CTRL_CH0_SET (0x000005c4)
+#define HW_PXP_INPUT_STORE_CTRL_CH0_CLR (0x000005c8)
+#define HW_PXP_INPUT_STORE_CTRL_CH0_TOG (0x000005cc)
+
+#define BM_PXP_INPUT_STORE_CTRL_CH0_ARBIT_EN 0x80000000
+#define BF_PXP_INPUT_STORE_CTRL_CH0_ARBIT_EN(v) \
+ (((v) << 31) & BM_PXP_INPUT_STORE_CTRL_CH0_ARBIT_EN)
+#define BV_PXP_INPUT_STORE_CTRL_CH0_ARBIT_EN__0 0x0
+#define BV_PXP_INPUT_STORE_CTRL_CH0_ARBIT_EN__1 0x1
+#define BP_PXP_INPUT_STORE_CTRL_CH0_RSVD0 25
+#define BM_PXP_INPUT_STORE_CTRL_CH0_RSVD0 0x7E000000
+#define BF_PXP_INPUT_STORE_CTRL_CH0_RSVD0(v) \
+ (((v) << 25) & BM_PXP_INPUT_STORE_CTRL_CH0_RSVD0)
+#define BM_PXP_INPUT_STORE_CTRL_CH0_COMBINE_2CHANNEL 0x01000000
+#define BF_PXP_INPUT_STORE_CTRL_CH0_COMBINE_2CHANNEL(v) \
+ (((v) << 24) & BM_PXP_INPUT_STORE_CTRL_CH0_COMBINE_2CHANNEL)
+#define BV_PXP_INPUT_STORE_CTRL_CH0_COMBINE_2CHANNEL__0 0x0
+#define BV_PXP_INPUT_STORE_CTRL_CH0_COMBINE_2CHANNEL__1 0x1
+#define BP_PXP_INPUT_STORE_CTRL_CH0_RSVD1 18
+#define BM_PXP_INPUT_STORE_CTRL_CH0_RSVD1 0x00FC0000
+#define BF_PXP_INPUT_STORE_CTRL_CH0_RSVD1(v) \
+ (((v) << 18) & BM_PXP_INPUT_STORE_CTRL_CH0_RSVD1)
+#define BP_PXP_INPUT_STORE_CTRL_CH0_WR_NUM_BYTES 16
+#define BM_PXP_INPUT_STORE_CTRL_CH0_WR_NUM_BYTES 0x00030000
+#define BF_PXP_INPUT_STORE_CTRL_CH0_WR_NUM_BYTES(v) \
+ (((v) << 16) & BM_PXP_INPUT_STORE_CTRL_CH0_WR_NUM_BYTES)
+#define BV_PXP_INPUT_STORE_CTRL_CH0_WR_NUM_BYTES__8_bytes 0x0
+#define BV_PXP_INPUT_STORE_CTRL_CH0_WR_NUM_BYTES__16_bytes 0x1
+#define BV_PXP_INPUT_STORE_CTRL_CH0_WR_NUM_BYTES__32_bytes 0x2
+#define BV_PXP_INPUT_STORE_CTRL_CH0_WR_NUM_BYTES__64_bytes 0x3
+#define BP_PXP_INPUT_STORE_CTRL_CH0_RSVD2 12
+#define BM_PXP_INPUT_STORE_CTRL_CH0_RSVD2 0x0000F000
+#define BF_PXP_INPUT_STORE_CTRL_CH0_RSVD2(v) \
+ (((v) << 12) & BM_PXP_INPUT_STORE_CTRL_CH0_RSVD2)
+#define BM_PXP_INPUT_STORE_CTRL_CH0_FILL_DATA_EN 0x00000800
+#define BF_PXP_INPUT_STORE_CTRL_CH0_FILL_DATA_EN(v) \
+ (((v) << 11) & BM_PXP_INPUT_STORE_CTRL_CH0_FILL_DATA_EN)
+#define BV_PXP_INPUT_STORE_CTRL_CH0_FILL_DATA_EN__0 0x0
+#define BV_PXP_INPUT_STORE_CTRL_CH0_FILL_DATA_EN__1 0x1
+#define BM_PXP_INPUT_STORE_CTRL_CH0_PACK_IN_SEL 0x00000400
+#define BF_PXP_INPUT_STORE_CTRL_CH0_PACK_IN_SEL(v) \
+ (((v) << 10) & BM_PXP_INPUT_STORE_CTRL_CH0_PACK_IN_SEL)
+#define BV_PXP_INPUT_STORE_CTRL_CH0_PACK_IN_SEL__0 0x0
+#define BV_PXP_INPUT_STORE_CTRL_CH0_PACK_IN_SEL__1 0x1
+#define BM_PXP_INPUT_STORE_CTRL_CH0_STORE_MEMORY_EN 0x00000200
+#define BF_PXP_INPUT_STORE_CTRL_CH0_STORE_MEMORY_EN(v) \
+ (((v) << 9) & BM_PXP_INPUT_STORE_CTRL_CH0_STORE_MEMORY_EN)
+#define BV_PXP_INPUT_STORE_CTRL_CH0_STORE_MEMORY_EN__0 0x0
+#define BV_PXP_INPUT_STORE_CTRL_CH0_STORE_MEMORY_EN__1 0x1
+#define BM_PXP_INPUT_STORE_CTRL_CH0_STORE_BYPASS_EN 0x00000100
+#define BF_PXP_INPUT_STORE_CTRL_CH0_STORE_BYPASS_EN(v) \
+ (((v) << 8) & BM_PXP_INPUT_STORE_CTRL_CH0_STORE_BYPASS_EN)
+#define BV_PXP_INPUT_STORE_CTRL_CH0_STORE_BYPASS_EN__0 0x0
+#define BV_PXP_INPUT_STORE_CTRL_CH0_STORE_BYPASS_EN__1 0x1
+#define BM_PXP_INPUT_STORE_CTRL_CH0_RSVD3 0x00000080
+#define BF_PXP_INPUT_STORE_CTRL_CH0_RSVD3(v) \
+ (((v) << 7) & BM_PXP_INPUT_STORE_CTRL_CH0_RSVD3)
+#define BP_PXP_INPUT_STORE_CTRL_CH0_ARRAY_LINE_NUM 5
+#define BM_PXP_INPUT_STORE_CTRL_CH0_ARRAY_LINE_NUM 0x00000060
+#define BF_PXP_INPUT_STORE_CTRL_CH0_ARRAY_LINE_NUM(v) \
+ (((v) << 5) & BM_PXP_INPUT_STORE_CTRL_CH0_ARRAY_LINE_NUM)
+#define BV_PXP_INPUT_STORE_CTRL_CH0_ARRAY_LINE_NUM__0 0x0
+#define BV_PXP_INPUT_STORE_CTRL_CH0_ARRAY_LINE_NUM__1 0x1
+#define BV_PXP_INPUT_STORE_CTRL_CH0_ARRAY_LINE_NUM__2 0x2
+#define BV_PXP_INPUT_STORE_CTRL_CH0_ARRAY_LINE_NUM__3 0x3
+#define BM_PXP_INPUT_STORE_CTRL_CH0_ARRAY_EN 0x00000010
+#define BF_PXP_INPUT_STORE_CTRL_CH0_ARRAY_EN(v) \
+ (((v) << 4) & BM_PXP_INPUT_STORE_CTRL_CH0_ARRAY_EN)
+#define BV_PXP_INPUT_STORE_CTRL_CH0_ARRAY_EN__0 0x0
+#define BV_PXP_INPUT_STORE_CTRL_CH0_ARRAY_EN__1 0x1
+#define BM_PXP_INPUT_STORE_CTRL_CH0_HANDSHAKE_EN 0x00000008
+#define BF_PXP_INPUT_STORE_CTRL_CH0_HANDSHAKE_EN(v) \
+ (((v) << 3) & BM_PXP_INPUT_STORE_CTRL_CH0_HANDSHAKE_EN)
+#define BV_PXP_INPUT_STORE_CTRL_CH0_HANDSHAKE_EN__0 0x0
+#define BV_PXP_INPUT_STORE_CTRL_CH0_HANDSHAKE_EN__1 0x1
+#define BM_PXP_INPUT_STORE_CTRL_CH0_BLOCK_16 0x00000004
+#define BF_PXP_INPUT_STORE_CTRL_CH0_BLOCK_16(v) \
+ (((v) << 2) & BM_PXP_INPUT_STORE_CTRL_CH0_BLOCK_16)
+#define BV_PXP_INPUT_STORE_CTRL_CH0_BLOCK_16__8x8 0x0
+#define BV_PXP_INPUT_STORE_CTRL_CH0_BLOCK_16__16x16 0x1
+#define BM_PXP_INPUT_STORE_CTRL_CH0_BLOCK_EN 0x00000002
+#define BF_PXP_INPUT_STORE_CTRL_CH0_BLOCK_EN(v) \
+ (((v) << 1) & BM_PXP_INPUT_STORE_CTRL_CH0_BLOCK_EN)
+#define BV_PXP_INPUT_STORE_CTRL_CH0_BLOCK_EN__0 0x0
+#define BV_PXP_INPUT_STORE_CTRL_CH0_BLOCK_EN__1 0x1
+#define BM_PXP_INPUT_STORE_CTRL_CH0_CH_EN 0x00000001
+#define BF_PXP_INPUT_STORE_CTRL_CH0_CH_EN(v) \
+ (((v) << 0) & BM_PXP_INPUT_STORE_CTRL_CH0_CH_EN)
+#define BV_PXP_INPUT_STORE_CTRL_CH0_CH_EN__0 0x0
+#define BV_PXP_INPUT_STORE_CTRL_CH0_CH_EN__1 0x1
+
+#define HW_PXP_INPUT_STORE_CTRL_CH1 (0x000005d0)
+#define HW_PXP_INPUT_STORE_CTRL_CH1_SET (0x000005d4)
+#define HW_PXP_INPUT_STORE_CTRL_CH1_CLR (0x000005d8)
+#define HW_PXP_INPUT_STORE_CTRL_CH1_TOG (0x000005dc)
+
+#define BP_PXP_INPUT_STORE_CTRL_CH1_RSVD0 18
+#define BM_PXP_INPUT_STORE_CTRL_CH1_RSVD0 0xFFFC0000
+#define BF_PXP_INPUT_STORE_CTRL_CH1_RSVD0(v) \
+ (((v) << 18) & BM_PXP_INPUT_STORE_CTRL_CH1_RSVD0)
+#define BP_PXP_INPUT_STORE_CTRL_CH1_WR_NUM_BYTES 16
+#define BM_PXP_INPUT_STORE_CTRL_CH1_WR_NUM_BYTES 0x00030000
+#define BF_PXP_INPUT_STORE_CTRL_CH1_WR_NUM_BYTES(v) \
+ (((v) << 16) & BM_PXP_INPUT_STORE_CTRL_CH1_WR_NUM_BYTES)
+#define BV_PXP_INPUT_STORE_CTRL_CH1_WR_NUM_BYTES__8_bytes 0x0
+#define BV_PXP_INPUT_STORE_CTRL_CH1_WR_NUM_BYTES__16_bytes 0x1
+#define BV_PXP_INPUT_STORE_CTRL_CH1_WR_NUM_BYTES__32_bytes 0x2
+#define BV_PXP_INPUT_STORE_CTRL_CH1_WR_NUM_BYTES__64_bytes 0x3
+#define BP_PXP_INPUT_STORE_CTRL_CH1_RSVD1 11
+#define BM_PXP_INPUT_STORE_CTRL_CH1_RSVD1 0x0000F800
+#define BF_PXP_INPUT_STORE_CTRL_CH1_RSVD1(v) \
+ (((v) << 11) & BM_PXP_INPUT_STORE_CTRL_CH1_RSVD1)
+#define BM_PXP_INPUT_STORE_CTRL_CH1_PACK_IN_SEL 0x00000400
+#define BF_PXP_INPUT_STORE_CTRL_CH1_PACK_IN_SEL(v) \
+ (((v) << 10) & BM_PXP_INPUT_STORE_CTRL_CH1_PACK_IN_SEL)
+#define BV_PXP_INPUT_STORE_CTRL_CH1_PACK_IN_SEL__0 0x0
+#define BV_PXP_INPUT_STORE_CTRL_CH1_PACK_IN_SEL__1 0x1
+#define BM_PXP_INPUT_STORE_CTRL_CH1_STORE_MEMORY_EN 0x00000200
+#define BF_PXP_INPUT_STORE_CTRL_CH1_STORE_MEMORY_EN(v) \
+ (((v) << 9) & BM_PXP_INPUT_STORE_CTRL_CH1_STORE_MEMORY_EN)
+#define BV_PXP_INPUT_STORE_CTRL_CH1_STORE_MEMORY_EN__0 0x0
+#define BV_PXP_INPUT_STORE_CTRL_CH1_STORE_MEMORY_EN__1 0x1
+#define BM_PXP_INPUT_STORE_CTRL_CH1_STORE_BYPASS_EN 0x00000100
+#define BF_PXP_INPUT_STORE_CTRL_CH1_STORE_BYPASS_EN(v) \
+ (((v) << 8) & BM_PXP_INPUT_STORE_CTRL_CH1_STORE_BYPASS_EN)
+#define BV_PXP_INPUT_STORE_CTRL_CH1_STORE_BYPASS_EN__0 0x0
+#define BV_PXP_INPUT_STORE_CTRL_CH1_STORE_BYPASS_EN__1 0x1
+#define BM_PXP_INPUT_STORE_CTRL_CH1_RSVD3 0x00000080
+#define BF_PXP_INPUT_STORE_CTRL_CH1_RSVD3(v) \
+ (((v) << 7) & BM_PXP_INPUT_STORE_CTRL_CH1_RSVD3)
+#define BP_PXP_INPUT_STORE_CTRL_CH1_ARRAY_LINE_NUM 5
+#define BM_PXP_INPUT_STORE_CTRL_CH1_ARRAY_LINE_NUM 0x00000060
+#define BF_PXP_INPUT_STORE_CTRL_CH1_ARRAY_LINE_NUM(v) \
+ (((v) << 5) & BM_PXP_INPUT_STORE_CTRL_CH1_ARRAY_LINE_NUM)
+#define BV_PXP_INPUT_STORE_CTRL_CH1_ARRAY_LINE_NUM__0 0x0
+#define BV_PXP_INPUT_STORE_CTRL_CH1_ARRAY_LINE_NUM__1 0x1
+#define BV_PXP_INPUT_STORE_CTRL_CH1_ARRAY_LINE_NUM__2 0x2
+#define BV_PXP_INPUT_STORE_CTRL_CH1_ARRAY_LINE_NUM__3 0x3
+#define BM_PXP_INPUT_STORE_CTRL_CH1_ARRAY_EN 0x00000010
+#define BF_PXP_INPUT_STORE_CTRL_CH1_ARRAY_EN(v) \
+ (((v) << 4) & BM_PXP_INPUT_STORE_CTRL_CH1_ARRAY_EN)
+#define BV_PXP_INPUT_STORE_CTRL_CH1_ARRAY_EN__0 0x0
+#define BV_PXP_INPUT_STORE_CTRL_CH1_ARRAY_EN__1 0x1
+#define BM_PXP_INPUT_STORE_CTRL_CH1_HANDSHAKE_EN 0x00000008
+#define BF_PXP_INPUT_STORE_CTRL_CH1_HANDSHAKE_EN(v) \
+ (((v) << 3) & BM_PXP_INPUT_STORE_CTRL_CH1_HANDSHAKE_EN)
+#define BV_PXP_INPUT_STORE_CTRL_CH1_HANDSHAKE_EN__0 0x0
+#define BV_PXP_INPUT_STORE_CTRL_CH1_HANDSHAKE_EN__1 0x1
+#define BM_PXP_INPUT_STORE_CTRL_CH1_BLOCK_16 0x00000004
+#define BF_PXP_INPUT_STORE_CTRL_CH1_BLOCK_16(v) \
+ (((v) << 2) & BM_PXP_INPUT_STORE_CTRL_CH1_BLOCK_16)
+#define BV_PXP_INPUT_STORE_CTRL_CH1_BLOCK_16__8x8 0x0
+#define BV_PXP_INPUT_STORE_CTRL_CH1_BLOCK_16__16x16 0x1
+#define BM_PXP_INPUT_STORE_CTRL_CH1_BLOCK_EN 0x00000002
+#define BF_PXP_INPUT_STORE_CTRL_CH1_BLOCK_EN(v) \
+ (((v) << 1) & BM_PXP_INPUT_STORE_CTRL_CH1_BLOCK_EN)
+#define BV_PXP_INPUT_STORE_CTRL_CH1_BLOCK_EN__0 0x0
+#define BV_PXP_INPUT_STORE_CTRL_CH1_BLOCK_EN__1 0x1
+#define BM_PXP_INPUT_STORE_CTRL_CH1_CH_EN 0x00000001
+#define BF_PXP_INPUT_STORE_CTRL_CH1_CH_EN(v) \
+ (((v) << 0) & BM_PXP_INPUT_STORE_CTRL_CH1_CH_EN)
+#define BV_PXP_INPUT_STORE_CTRL_CH1_CH_EN__0 0x0
+#define BV_PXP_INPUT_STORE_CTRL_CH1_CH_EN__1 0x1
+
+#define HW_PXP_INPUT_STORE_STATUS_CH0 (0x000005e0)
+
+#define BP_PXP_INPUT_STORE_STATUS_CH0_STORE_BLOCK_Y 16
+#define BM_PXP_INPUT_STORE_STATUS_CH0_STORE_BLOCK_Y 0xFFFF0000
+#define BF_PXP_INPUT_STORE_STATUS_CH0_STORE_BLOCK_Y(v) \
+ (((v) << 16) & BM_PXP_INPUT_STORE_STATUS_CH0_STORE_BLOCK_Y)
+#define BP_PXP_INPUT_STORE_STATUS_CH0_STORE_BLOCK_X 0
+#define BM_PXP_INPUT_STORE_STATUS_CH0_STORE_BLOCK_X 0x0000FFFF
+#define BF_PXP_INPUT_STORE_STATUS_CH0_STORE_BLOCK_X(v) \
+ (((v) << 0) & BM_PXP_INPUT_STORE_STATUS_CH0_STORE_BLOCK_X)
+
+#define HW_PXP_INPUT_STORE_STATUS_CH1 (0x000005f0)
+
+#define BP_PXP_INPUT_STORE_STATUS_CH1_STORE_BLOCK_Y 16
+#define BM_PXP_INPUT_STORE_STATUS_CH1_STORE_BLOCK_Y 0xFFFF0000
+#define BF_PXP_INPUT_STORE_STATUS_CH1_STORE_BLOCK_Y(v) \
+ (((v) << 16) & BM_PXP_INPUT_STORE_STATUS_CH1_STORE_BLOCK_Y)
+#define BP_PXP_INPUT_STORE_STATUS_CH1_STORE_BLOCK_X 0
+#define BM_PXP_INPUT_STORE_STATUS_CH1_STORE_BLOCK_X 0x0000FFFF
+#define BF_PXP_INPUT_STORE_STATUS_CH1_STORE_BLOCK_X(v) \
+ (((v) << 0) & BM_PXP_INPUT_STORE_STATUS_CH1_STORE_BLOCK_X)
+
+#define HW_PXP_INPUT_STORE_SIZE_CH0 (0x00000600)
+
+#define BP_PXP_INPUT_STORE_SIZE_CH0_OUT_HEIGHT 16
+#define BM_PXP_INPUT_STORE_SIZE_CH0_OUT_HEIGHT 0xFFFF0000
+#define BF_PXP_INPUT_STORE_SIZE_CH0_OUT_HEIGHT(v) \
+ (((v) << 16) & BM_PXP_INPUT_STORE_SIZE_CH0_OUT_HEIGHT)
+#define BP_PXP_INPUT_STORE_SIZE_CH0_OUT_WIDTH 0
+#define BM_PXP_INPUT_STORE_SIZE_CH0_OUT_WIDTH 0x0000FFFF
+#define BF_PXP_INPUT_STORE_SIZE_CH0_OUT_WIDTH(v) \
+ (((v) << 0) & BM_PXP_INPUT_STORE_SIZE_CH0_OUT_WIDTH)
+
+#define HW_PXP_INPUT_STORE_SIZE_CH1 (0x00000610)
+
+#define BP_PXP_INPUT_STORE_SIZE_CH1_OUT_HEIGHT 16
+#define BM_PXP_INPUT_STORE_SIZE_CH1_OUT_HEIGHT 0xFFFF0000
+#define BF_PXP_INPUT_STORE_SIZE_CH1_OUT_HEIGHT(v) \
+ (((v) << 16) & BM_PXP_INPUT_STORE_SIZE_CH1_OUT_HEIGHT)
+#define BP_PXP_INPUT_STORE_SIZE_CH1_OUT_WIDTH 0
+#define BM_PXP_INPUT_STORE_SIZE_CH1_OUT_WIDTH 0x0000FFFF
+#define BF_PXP_INPUT_STORE_SIZE_CH1_OUT_WIDTH(v) \
+ (((v) << 0) & BM_PXP_INPUT_STORE_SIZE_CH1_OUT_WIDTH)
+
+#define HW_PXP_INPUT_STORE_PITCH (0x00000620)
+
+#define BP_PXP_INPUT_STORE_PITCH_CH1_OUT_PITCH 16
+#define BM_PXP_INPUT_STORE_PITCH_CH1_OUT_PITCH 0xFFFF0000
+#define BF_PXP_INPUT_STORE_PITCH_CH1_OUT_PITCH(v) \
+ (((v) << 16) & BM_PXP_INPUT_STORE_PITCH_CH1_OUT_PITCH)
+#define BP_PXP_INPUT_STORE_PITCH_CH0_OUT_PITCH 0
+#define BM_PXP_INPUT_STORE_PITCH_CH0_OUT_PITCH 0x0000FFFF
+#define BF_PXP_INPUT_STORE_PITCH_CH0_OUT_PITCH(v) \
+ (((v) << 0) & BM_PXP_INPUT_STORE_PITCH_CH0_OUT_PITCH)
+
+#define HW_PXP_INPUT_STORE_SHIFT_CTRL_CH0 (0x00000630)
+#define HW_PXP_INPUT_STORE_SHIFT_CTRL_CH0_SET (0x00000634)
+#define HW_PXP_INPUT_STORE_SHIFT_CTRL_CH0_CLR (0x00000638)
+#define HW_PXP_INPUT_STORE_SHIFT_CTRL_CH0_TOG (0x0000063c)
+
+#define BP_PXP_INPUT_STORE_SHIFT_CTRL_CH0_RSVD0 8
+#define BM_PXP_INPUT_STORE_SHIFT_CTRL_CH0_RSVD0 0xFFFFFF00
+#define BF_PXP_INPUT_STORE_SHIFT_CTRL_CH0_RSVD0(v) \
+ (((v) << 8) & BM_PXP_INPUT_STORE_SHIFT_CTRL_CH0_RSVD0)
+#define BM_PXP_INPUT_STORE_SHIFT_CTRL_CH0_SHIFT_BYPASS 0x00000080
+#define BF_PXP_INPUT_STORE_SHIFT_CTRL_CH0_SHIFT_BYPASS(v) \
+ (((v) << 7) & BM_PXP_INPUT_STORE_SHIFT_CTRL_CH0_SHIFT_BYPASS)
+#define BV_PXP_INPUT_STORE_SHIFT_CTRL_CH0_SHIFT_BYPASS__0 0x0
+#define BV_PXP_INPUT_STORE_SHIFT_CTRL_CH0_SHIFT_BYPASS__1 0x1
+#define BM_PXP_INPUT_STORE_SHIFT_CTRL_CH0_RSVD1 0x00000040
+#define BF_PXP_INPUT_STORE_SHIFT_CTRL_CH0_RSVD1(v) \
+ (((v) << 6) & BM_PXP_INPUT_STORE_SHIFT_CTRL_CH0_RSVD1)
+#define BM_PXP_INPUT_STORE_SHIFT_CTRL_CH0_OUT_YUV422_2P_EN 0x00000020
+#define BF_PXP_INPUT_STORE_SHIFT_CTRL_CH0_OUT_YUV422_2P_EN(v) \
+ (((v) << 5) & BM_PXP_INPUT_STORE_SHIFT_CTRL_CH0_OUT_YUV422_2P_EN)
+#define BV_PXP_INPUT_STORE_SHIFT_CTRL_CH0_OUT_YUV422_2P_EN__0 0x0
+#define BV_PXP_INPUT_STORE_SHIFT_CTRL_CH0_OUT_YUV422_2P_EN__1 0x1
+#define BM_PXP_INPUT_STORE_SHIFT_CTRL_CH0_OUT_YUV422_1P_EN 0x00000010
+#define BF_PXP_INPUT_STORE_SHIFT_CTRL_CH0_OUT_YUV422_1P_EN(v) \
+ (((v) << 4) & BM_PXP_INPUT_STORE_SHIFT_CTRL_CH0_OUT_YUV422_1P_EN)
+#define BV_PXP_INPUT_STORE_SHIFT_CTRL_CH0_OUT_YUV422_1P_EN__0 0x0
+#define BV_PXP_INPUT_STORE_SHIFT_CTRL_CH0_OUT_YUV422_1P_EN__1 0x1
+#define BP_PXP_INPUT_STORE_SHIFT_CTRL_CH0_OUTPUT_ACTIVE_BPP 2
+#define BM_PXP_INPUT_STORE_SHIFT_CTRL_CH0_OUTPUT_ACTIVE_BPP 0x0000000C
+#define BF_PXP_INPUT_STORE_SHIFT_CTRL_CH0_OUTPUT_ACTIVE_BPP(v) \
+ (((v) << 2) & BM_PXP_INPUT_STORE_SHIFT_CTRL_CH0_OUTPUT_ACTIVE_BPP)
+#define BV_PXP_INPUT_STORE_SHIFT_CTRL_CH0_OUTPUT_ACTIVE_BPP__0 0x0
+#define BV_PXP_INPUT_STORE_SHIFT_CTRL_CH0_OUTPUT_ACTIVE_BPP__1 0x1
+#define BV_PXP_INPUT_STORE_SHIFT_CTRL_CH0_OUTPUT_ACTIVE_BPP__2 0x2
+#define BV_PXP_INPUT_STORE_SHIFT_CTRL_CH0_OUTPUT_ACTIVE_BPP__3 0x3
+#define BP_PXP_INPUT_STORE_SHIFT_CTRL_CH0_RSVD2 0
+#define BM_PXP_INPUT_STORE_SHIFT_CTRL_CH0_RSVD2 0x00000003
+#define BF_PXP_INPUT_STORE_SHIFT_CTRL_CH0_RSVD2(v) \
+ (((v) << 0) & BM_PXP_INPUT_STORE_SHIFT_CTRL_CH0_RSVD2)
+
+#define HW_PXP_INPUT_STORE_SHIFT_CTRL_CH1 (0x00000640)
+#define HW_PXP_INPUT_STORE_SHIFT_CTRL_CH1_SET (0x00000644)
+#define HW_PXP_INPUT_STORE_SHIFT_CTRL_CH1_CLR (0x00000648)
+#define HW_PXP_INPUT_STORE_SHIFT_CTRL_CH1_TOG (0x0000064c)
+
+#define BP_PXP_INPUT_STORE_SHIFT_CTRL_CH1_RSVD0 6
+#define BM_PXP_INPUT_STORE_SHIFT_CTRL_CH1_RSVD0 0xFFFFFFC0
+#define BF_PXP_INPUT_STORE_SHIFT_CTRL_CH1_RSVD0(v) \
+ (((v) << 6) & BM_PXP_INPUT_STORE_SHIFT_CTRL_CH1_RSVD0)
+#define BM_PXP_INPUT_STORE_SHIFT_CTRL_CH1_OUT_YUV422_2P_EN 0x00000020
+#define BF_PXP_INPUT_STORE_SHIFT_CTRL_CH1_OUT_YUV422_2P_EN(v) \
+ (((v) << 5) & BM_PXP_INPUT_STORE_SHIFT_CTRL_CH1_OUT_YUV422_2P_EN)
+#define BV_PXP_INPUT_STORE_SHIFT_CTRL_CH1_OUT_YUV422_2P_EN__0 0x0
+#define BV_PXP_INPUT_STORE_SHIFT_CTRL_CH1_OUT_YUV422_2P_EN__1 0x1
+#define BM_PXP_INPUT_STORE_SHIFT_CTRL_CH1_OUT_YUV422_1P_EN 0x00000010
+#define BF_PXP_INPUT_STORE_SHIFT_CTRL_CH1_OUT_YUV422_1P_EN(v) \
+ (((v) << 4) & BM_PXP_INPUT_STORE_SHIFT_CTRL_CH1_OUT_YUV422_1P_EN)
+#define BV_PXP_INPUT_STORE_SHIFT_CTRL_CH1_OUT_YUV422_1P_EN__0 0x0
+#define BV_PXP_INPUT_STORE_SHIFT_CTRL_CH1_OUT_YUV422_1P_EN__1 0x1
+#define BP_PXP_INPUT_STORE_SHIFT_CTRL_CH1_OUTPUT_ACTIVE_BPP 2
+#define BM_PXP_INPUT_STORE_SHIFT_CTRL_CH1_OUTPUT_ACTIVE_BPP 0x0000000C
+#define BF_PXP_INPUT_STORE_SHIFT_CTRL_CH1_OUTPUT_ACTIVE_BPP(v) \
+ (((v) << 2) & BM_PXP_INPUT_STORE_SHIFT_CTRL_CH1_OUTPUT_ACTIVE_BPP)
+#define BV_PXP_INPUT_STORE_SHIFT_CTRL_CH1_OUTPUT_ACTIVE_BPP__0 0x0
+#define BV_PXP_INPUT_STORE_SHIFT_CTRL_CH1_OUTPUT_ACTIVE_BPP__1 0x1
+#define BV_PXP_INPUT_STORE_SHIFT_CTRL_CH1_OUTPUT_ACTIVE_BPP__2 0x2
+#define BV_PXP_INPUT_STORE_SHIFT_CTRL_CH1_OUTPUT_ACTIVE_BPP__3 0x3
+#define BP_PXP_INPUT_STORE_SHIFT_CTRL_CH1_RSVD2 0
+#define BM_PXP_INPUT_STORE_SHIFT_CTRL_CH1_RSVD2 0x00000003
+#define BF_PXP_INPUT_STORE_SHIFT_CTRL_CH1_RSVD2(v) \
+ (((v) << 0) & BM_PXP_INPUT_STORE_SHIFT_CTRL_CH1_RSVD2)
+
+#define HW_PXP_INPUT_STORE_ADDR_0_CH0 (0x00000690)
+
+#define BP_PXP_INPUT_STORE_ADDR_0_CH0_OUT_BASE_ADDR0 0
+#define BM_PXP_INPUT_STORE_ADDR_0_CH0_OUT_BASE_ADDR0 0xFFFFFFFF
+#define BF_PXP_INPUT_STORE_ADDR_0_CH0_OUT_BASE_ADDR0(v) (v)
+
+#define HW_PXP_INPUT_STORE_ADDR_1_CH0 (0x000006a0)
+
+#define BP_PXP_INPUT_STORE_ADDR_1_CH0_OUT_BASE_ADDR1 0
+#define BM_PXP_INPUT_STORE_ADDR_1_CH0_OUT_BASE_ADDR1 0xFFFFFFFF
+#define BF_PXP_INPUT_STORE_ADDR_1_CH0_OUT_BASE_ADDR1(v) (v)
+
+#define HW_PXP_INPUT_STORE_FILL_DATA_CH0 (0x000006b0)
+
+#define BP_PXP_INPUT_STORE_FILL_DATA_CH0_FILL_DATA_CH0 0
+#define BM_PXP_INPUT_STORE_FILL_DATA_CH0_FILL_DATA_CH0 0xFFFFFFFF
+#define BF_PXP_INPUT_STORE_FILL_DATA_CH0_FILL_DATA_CH0(v) (v)
+
+#define HW_PXP_INPUT_STORE_ADDR_0_CH1 (0x000006c0)
+
+#define BP_PXP_INPUT_STORE_ADDR_0_CH1_OUT_BASE_ADDR0 0
+#define BM_PXP_INPUT_STORE_ADDR_0_CH1_OUT_BASE_ADDR0 0xFFFFFFFF
+#define BF_PXP_INPUT_STORE_ADDR_0_CH1_OUT_BASE_ADDR0(v) (v)
+
+#define HW_PXP_INPUT_STORE_ADDR_1_CH1 (0x000006d0)
+
+#define BP_PXP_INPUT_STORE_ADDR_1_CH1_OUT_BASE_ADDR1 0
+#define BM_PXP_INPUT_STORE_ADDR_1_CH1_OUT_BASE_ADDR1 0xFFFFFFFF
+#define BF_PXP_INPUT_STORE_ADDR_1_CH1_OUT_BASE_ADDR1(v) (v)
+
+#define HW_PXP_INPUT_STORE_D_MASK0_H_CH0 (0x000006e0)
+
+#define BP_PXP_INPUT_STORE_D_MASK0_H_CH0_D_MASK0_H_CH0 0
+#define BM_PXP_INPUT_STORE_D_MASK0_H_CH0_D_MASK0_H_CH0 0xFFFFFFFF
+#define BF_PXP_INPUT_STORE_D_MASK0_H_CH0_D_MASK0_H_CH0(v) (v)
+
+#define HW_PXP_INPUT_STORE_D_MASK0_L_CH0 (0x000006f0)
+
+#define BP_PXP_INPUT_STORE_D_MASK0_L_CH0_D_MASK0_L_CH0 0
+#define BM_PXP_INPUT_STORE_D_MASK0_L_CH0_D_MASK0_L_CH0 0xFFFFFFFF
+#define BF_PXP_INPUT_STORE_D_MASK0_L_CH0_D_MASK0_L_CH0(v) (v)
+
+#define HW_PXP_INPUT_STORE_D_MASK1_H_CH0 (0x00000700)
+
+#define BP_PXP_INPUT_STORE_D_MASK1_H_CH0_D_MASK1_H_CH0 0
+#define BM_PXP_INPUT_STORE_D_MASK1_H_CH0_D_MASK1_H_CH0 0xFFFFFFFF
+#define BF_PXP_INPUT_STORE_D_MASK1_H_CH0_D_MASK1_H_CH0(v) (v)
+
+#define HW_PXP_INPUT_STORE_D_MASK1_L_CH0 (0x00000710)
+
+#define BP_PXP_INPUT_STORE_D_MASK1_L_CH0_D_MASK1_L_CH0 0
+#define BM_PXP_INPUT_STORE_D_MASK1_L_CH0_D_MASK1_L_CH0 0xFFFFFFFF
+#define BF_PXP_INPUT_STORE_D_MASK1_L_CH0_D_MASK1_L_CH0(v) (v)
+
+#define HW_PXP_INPUT_STORE_D_MASK2_H_CH0 (0x00000720)
+
+#define BP_PXP_INPUT_STORE_D_MASK2_H_CH0_D_MASK2_H_CH0 0
+#define BM_PXP_INPUT_STORE_D_MASK2_H_CH0_D_MASK2_H_CH0 0xFFFFFFFF
+#define BF_PXP_INPUT_STORE_D_MASK2_H_CH0_D_MASK2_H_CH0(v) (v)
+
+#define HW_PXP_INPUT_STORE_D_MASK2_L_CH0 (0x00000730)
+
+#define BP_PXP_INPUT_STORE_D_MASK2_L_CH0_D_MASK2_L_CH0 0
+#define BM_PXP_INPUT_STORE_D_MASK2_L_CH0_D_MASK2_L_CH0 0xFFFFFFFF
+#define BF_PXP_INPUT_STORE_D_MASK2_L_CH0_D_MASK2_L_CH0(v) (v)
+
+#define HW_PXP_INPUT_STORE_D_MASK3_H_CH0 (0x00000740)
+
+#define BP_PXP_INPUT_STORE_D_MASK3_H_CH0_D_MASK3_H_CH0 0
+#define BM_PXP_INPUT_STORE_D_MASK3_H_CH0_D_MASK3_H_CH0 0xFFFFFFFF
+#define BF_PXP_INPUT_STORE_D_MASK3_H_CH0_D_MASK3_H_CH0(v) (v)
+
+#define HW_PXP_INPUT_STORE_D_MASK3_L_CH0 (0x00000750)
+
+#define BP_PXP_INPUT_STORE_D_MASK3_L_CH0_D_MASK3_L_CH0 0
+#define BM_PXP_INPUT_STORE_D_MASK3_L_CH0_D_MASK3_L_CH0 0xFFFFFFFF
+#define BF_PXP_INPUT_STORE_D_MASK3_L_CH0_D_MASK3_L_CH0(v) (v)
+
+#define HW_PXP_INPUT_STORE_D_MASK4_H_CH0 (0x00000760)
+
+#define BP_PXP_INPUT_STORE_D_MASK4_H_CH0_D_MASK4_H_CH0 0
+#define BM_PXP_INPUT_STORE_D_MASK4_H_CH0_D_MASK4_H_CH0 0xFFFFFFFF
+#define BF_PXP_INPUT_STORE_D_MASK4_H_CH0_D_MASK4_H_CH0(v) (v)
+
+#define HW_PXP_INPUT_STORE_D_MASK4_L_CH0 (0x00000770)
+
+#define BP_PXP_INPUT_STORE_D_MASK4_L_CH0_D_MASK4_L_CH0 0
+#define BM_PXP_INPUT_STORE_D_MASK4_L_CH0_D_MASK4_L_CH0 0xFFFFFFFF
+#define BF_PXP_INPUT_STORE_D_MASK4_L_CH0_D_MASK4_L_CH0(v) (v)
+
+#define HW_PXP_INPUT_STORE_D_MASK5_H_CH0 (0x00000780)
+
+#define BP_PXP_INPUT_STORE_D_MASK5_H_CH0_D_MASK5_H_CH0 0
+#define BM_PXP_INPUT_STORE_D_MASK5_H_CH0_D_MASK5_H_CH0 0xFFFFFFFF
+#define BF_PXP_INPUT_STORE_D_MASK5_H_CH0_D_MASK5_H_CH0(v) (v)
+
+#define HW_PXP_INPUT_STORE_D_MASK5_L_CH0 (0x00000790)
+
+#define BP_PXP_INPUT_STORE_D_MASK5_L_CH0_D_MASK5_L_CH0 0
+#define BM_PXP_INPUT_STORE_D_MASK5_L_CH0_D_MASK5_L_CH0 0xFFFFFFFF
+#define BF_PXP_INPUT_STORE_D_MASK5_L_CH0_D_MASK5_L_CH0(v) (v)
+
+#define HW_PXP_INPUT_STORE_D_MASK6_H_CH0 (0x000007a0)
+
+#define BP_PXP_INPUT_STORE_D_MASK6_H_CH0_D_MASK6_H_CH0 0
+#define BM_PXP_INPUT_STORE_D_MASK6_H_CH0_D_MASK6_H_CH0 0xFFFFFFFF
+#define BF_PXP_INPUT_STORE_D_MASK6_H_CH0_D_MASK6_H_CH0(v) (v)
+
+#define HW_PXP_INPUT_STORE_D_MASK6_L_CH0 (0x000007b0)
+
+#define BP_PXP_INPUT_STORE_D_MASK6_L_CH0_D_MASK6_L_CH0 0
+#define BM_PXP_INPUT_STORE_D_MASK6_L_CH0_D_MASK6_L_CH0 0xFFFFFFFF
+#define BF_PXP_INPUT_STORE_D_MASK6_L_CH0_D_MASK6_L_CH0(v) (v)
+
+#define HW_PXP_INPUT_STORE_D_MASK7_H_CH0 (0x000007c0)
+
+#define BP_PXP_INPUT_STORE_D_MASK7_H_CH0_D_MASK7_H_CH0 0
+#define BM_PXP_INPUT_STORE_D_MASK7_H_CH0_D_MASK7_H_CH0 0xFFFFFFFF
+#define BF_PXP_INPUT_STORE_D_MASK7_H_CH0_D_MASK7_H_CH0(v) (v)
+
+#define HW_PXP_INPUT_STORE_D_MASK7_L_CH0 (0x000007e0)
+
+#define BP_PXP_INPUT_STORE_D_MASK7_L_CH0_D_MASK7_L_CH0 0
+#define BM_PXP_INPUT_STORE_D_MASK7_L_CH0_D_MASK7_L_CH0 0xFFFFFFFF
+#define BF_PXP_INPUT_STORE_D_MASK7_L_CH0_D_MASK7_L_CH0(v) (v)
+
+#define HW_PXP_INPUT_STORE_D_SHIFT_L_CH0 (0x000007f0)
+
+#define BM_PXP_INPUT_STORE_D_SHIFT_L_CH0_D_SHIFT_FLAG3 0x80000000
+#define BF_PXP_INPUT_STORE_D_SHIFT_L_CH0_D_SHIFT_FLAG3(v) \
+ (((v) << 31) & BM_PXP_INPUT_STORE_D_SHIFT_L_CH0_D_SHIFT_FLAG3)
+#define BM_PXP_INPUT_STORE_D_SHIFT_L_CH0_RSVD0 0x40000000
+#define BF_PXP_INPUT_STORE_D_SHIFT_L_CH0_RSVD0(v) \
+ (((v) << 30) & BM_PXP_INPUT_STORE_D_SHIFT_L_CH0_RSVD0)
+#define BP_PXP_INPUT_STORE_D_SHIFT_L_CH0_D_SHIFT_WIDTH3 24
+#define BM_PXP_INPUT_STORE_D_SHIFT_L_CH0_D_SHIFT_WIDTH3 0x3F000000
+#define BF_PXP_INPUT_STORE_D_SHIFT_L_CH0_D_SHIFT_WIDTH3(v) \
+ (((v) << 24) & BM_PXP_INPUT_STORE_D_SHIFT_L_CH0_D_SHIFT_WIDTH3)
+#define BM_PXP_INPUT_STORE_D_SHIFT_L_CH0_D_SHIFT_FLAG2 0x00800000
+#define BF_PXP_INPUT_STORE_D_SHIFT_L_CH0_D_SHIFT_FLAG2(v) \
+ (((v) << 23) & BM_PXP_INPUT_STORE_D_SHIFT_L_CH0_D_SHIFT_FLAG2)
+#define BM_PXP_INPUT_STORE_D_SHIFT_L_CH0_RSVD1 0x00400000
+#define BF_PXP_INPUT_STORE_D_SHIFT_L_CH0_RSVD1(v) \
+ (((v) << 22) & BM_PXP_INPUT_STORE_D_SHIFT_L_CH0_RSVD1)
+#define BP_PXP_INPUT_STORE_D_SHIFT_L_CH0_D_SHIFT_WIDTH2 16
+#define BM_PXP_INPUT_STORE_D_SHIFT_L_CH0_D_SHIFT_WIDTH2 0x003F0000
+#define BF_PXP_INPUT_STORE_D_SHIFT_L_CH0_D_SHIFT_WIDTH2(v) \
+ (((v) << 16) & BM_PXP_INPUT_STORE_D_SHIFT_L_CH0_D_SHIFT_WIDTH2)
+#define BM_PXP_INPUT_STORE_D_SHIFT_L_CH0_D_SHIFT_FLAG1 0x00008000
+#define BF_PXP_INPUT_STORE_D_SHIFT_L_CH0_D_SHIFT_FLAG1(v) \
+ (((v) << 15) & BM_PXP_INPUT_STORE_D_SHIFT_L_CH0_D_SHIFT_FLAG1)
+#define BM_PXP_INPUT_STORE_D_SHIFT_L_CH0_RSVD2 0x00004000
+#define BF_PXP_INPUT_STORE_D_SHIFT_L_CH0_RSVD2(v) \
+ (((v) << 14) & BM_PXP_INPUT_STORE_D_SHIFT_L_CH0_RSVD2)
+#define BP_PXP_INPUT_STORE_D_SHIFT_L_CH0_D_SHIFT_WIDTH1 8
+#define BM_PXP_INPUT_STORE_D_SHIFT_L_CH0_D_SHIFT_WIDTH1 0x00003F00
+#define BF_PXP_INPUT_STORE_D_SHIFT_L_CH0_D_SHIFT_WIDTH1(v) \
+ (((v) << 8) & BM_PXP_INPUT_STORE_D_SHIFT_L_CH0_D_SHIFT_WIDTH1)
+#define BM_PXP_INPUT_STORE_D_SHIFT_L_CH0_D_SHIFT_FLAG0 0x00000080
+#define BF_PXP_INPUT_STORE_D_SHIFT_L_CH0_D_SHIFT_FLAG0(v) \
+ (((v) << 7) & BM_PXP_INPUT_STORE_D_SHIFT_L_CH0_D_SHIFT_FLAG0)
+#define BM_PXP_INPUT_STORE_D_SHIFT_L_CH0_RSVD3 0x00000040
+#define BF_PXP_INPUT_STORE_D_SHIFT_L_CH0_RSVD3(v) \
+ (((v) << 6) & BM_PXP_INPUT_STORE_D_SHIFT_L_CH0_RSVD3)
+#define BP_PXP_INPUT_STORE_D_SHIFT_L_CH0_D_SHIFT_WIDTH0 0
+#define BM_PXP_INPUT_STORE_D_SHIFT_L_CH0_D_SHIFT_WIDTH0 0x0000003F
+#define BF_PXP_INPUT_STORE_D_SHIFT_L_CH0_D_SHIFT_WIDTH0(v) \
+ (((v) << 0) & BM_PXP_INPUT_STORE_D_SHIFT_L_CH0_D_SHIFT_WIDTH0)
+
+#define HW_PXP_INPUT_STORE_D_SHIFT_H_CH0 (0x00000800)
+
+#define BM_PXP_INPUT_STORE_D_SHIFT_H_CH0_D_SHIFT_FLAG7 0x80000000
+#define BF_PXP_INPUT_STORE_D_SHIFT_H_CH0_D_SHIFT_FLAG7(v) \
+ (((v) << 31) & BM_PXP_INPUT_STORE_D_SHIFT_H_CH0_D_SHIFT_FLAG7)
+#define BM_PXP_INPUT_STORE_D_SHIFT_H_CH0_RSVD0 0x40000000
+#define BF_PXP_INPUT_STORE_D_SHIFT_H_CH0_RSVD0(v) \
+ (((v) << 30) & BM_PXP_INPUT_STORE_D_SHIFT_H_CH0_RSVD0)
+#define BP_PXP_INPUT_STORE_D_SHIFT_H_CH0_D_SHIFT_WIDTH7 24
+#define BM_PXP_INPUT_STORE_D_SHIFT_H_CH0_D_SHIFT_WIDTH7 0x3F000000
+#define BF_PXP_INPUT_STORE_D_SHIFT_H_CH0_D_SHIFT_WIDTH7(v) \
+ (((v) << 24) & BM_PXP_INPUT_STORE_D_SHIFT_H_CH0_D_SHIFT_WIDTH7)
+#define BM_PXP_INPUT_STORE_D_SHIFT_H_CH0_D_SHIFT_FLAG6 0x00800000
+#define BF_PXP_INPUT_STORE_D_SHIFT_H_CH0_D_SHIFT_FLAG6(v) \
+ (((v) << 23) & BM_PXP_INPUT_STORE_D_SHIFT_H_CH0_D_SHIFT_FLAG6)
+#define BM_PXP_INPUT_STORE_D_SHIFT_H_CH0_RSVD1 0x00400000
+#define BF_PXP_INPUT_STORE_D_SHIFT_H_CH0_RSVD1(v) \
+ (((v) << 22) & BM_PXP_INPUT_STORE_D_SHIFT_H_CH0_RSVD1)
+#define BP_PXP_INPUT_STORE_D_SHIFT_H_CH0_D_SHIFT_WIDTH6 16
+#define BM_PXP_INPUT_STORE_D_SHIFT_H_CH0_D_SHIFT_WIDTH6 0x003F0000
+#define BF_PXP_INPUT_STORE_D_SHIFT_H_CH0_D_SHIFT_WIDTH6(v) \
+ (((v) << 16) & BM_PXP_INPUT_STORE_D_SHIFT_H_CH0_D_SHIFT_WIDTH6)
+#define BM_PXP_INPUT_STORE_D_SHIFT_H_CH0_D_SHIFT_FLAG5 0x00008000
+#define BF_PXP_INPUT_STORE_D_SHIFT_H_CH0_D_SHIFT_FLAG5(v) \
+ (((v) << 15) & BM_PXP_INPUT_STORE_D_SHIFT_H_CH0_D_SHIFT_FLAG5)
+#define BM_PXP_INPUT_STORE_D_SHIFT_H_CH0_RSVD2 0x00004000
+#define BF_PXP_INPUT_STORE_D_SHIFT_H_CH0_RSVD2(v) \
+ (((v) << 14) & BM_PXP_INPUT_STORE_D_SHIFT_H_CH0_RSVD2)
+#define BP_PXP_INPUT_STORE_D_SHIFT_H_CH0_D_SHIFT_WIDTH5 8
+#define BM_PXP_INPUT_STORE_D_SHIFT_H_CH0_D_SHIFT_WIDTH5 0x00003F00
+#define BF_PXP_INPUT_STORE_D_SHIFT_H_CH0_D_SHIFT_WIDTH5(v) \
+ (((v) << 8) & BM_PXP_INPUT_STORE_D_SHIFT_H_CH0_D_SHIFT_WIDTH5)
+#define BM_PXP_INPUT_STORE_D_SHIFT_H_CH0_D_SHIFT_FLAG4 0x00000080
+#define BF_PXP_INPUT_STORE_D_SHIFT_H_CH0_D_SHIFT_FLAG4(v) \
+ (((v) << 7) & BM_PXP_INPUT_STORE_D_SHIFT_H_CH0_D_SHIFT_FLAG4)
+#define BM_PXP_INPUT_STORE_D_SHIFT_H_CH0_RSVD3 0x00000040
+#define BF_PXP_INPUT_STORE_D_SHIFT_H_CH0_RSVD3(v) \
+ (((v) << 6) & BM_PXP_INPUT_STORE_D_SHIFT_H_CH0_RSVD3)
+#define BP_PXP_INPUT_STORE_D_SHIFT_H_CH0_D_SHIFT_WIDTH4 0
+#define BM_PXP_INPUT_STORE_D_SHIFT_H_CH0_D_SHIFT_WIDTH4 0x0000003F
+#define BF_PXP_INPUT_STORE_D_SHIFT_H_CH0_D_SHIFT_WIDTH4(v) \
+ (((v) << 0) & BM_PXP_INPUT_STORE_D_SHIFT_H_CH0_D_SHIFT_WIDTH4)
+
+#define HW_PXP_INPUT_STORE_F_SHIFT_L_CH0 (0x00000810)
+
+#define BM_PXP_INPUT_STORE_F_SHIFT_L_CH0_RSVD0 0x80000000
+#define BF_PXP_INPUT_STORE_F_SHIFT_L_CH0_RSVD0(v) \
+ (((v) << 31) & BM_PXP_INPUT_STORE_F_SHIFT_L_CH0_RSVD0)
+#define BM_PXP_INPUT_STORE_F_SHIFT_L_CH0_F_SHIFT_FLAG3 0x40000000
+#define BF_PXP_INPUT_STORE_F_SHIFT_L_CH0_F_SHIFT_FLAG3(v) \
+ (((v) << 30) & BM_PXP_INPUT_STORE_F_SHIFT_L_CH0_F_SHIFT_FLAG3)
+#define BP_PXP_INPUT_STORE_F_SHIFT_L_CH0_F_SHIFT_WIDTH3 24
+#define BM_PXP_INPUT_STORE_F_SHIFT_L_CH0_F_SHIFT_WIDTH3 0x3F000000
+#define BF_PXP_INPUT_STORE_F_SHIFT_L_CH0_F_SHIFT_WIDTH3(v) \
+ (((v) << 24) & BM_PXP_INPUT_STORE_F_SHIFT_L_CH0_F_SHIFT_WIDTH3)
+#define BM_PXP_INPUT_STORE_F_SHIFT_L_CH0_RSVD1 0x00800000
+#define BF_PXP_INPUT_STORE_F_SHIFT_L_CH0_RSVD1(v) \
+ (((v) << 23) & BM_PXP_INPUT_STORE_F_SHIFT_L_CH0_RSVD1)
+#define BM_PXP_INPUT_STORE_F_SHIFT_L_CH0_F_SHIFT_FLAG2 0x00400000
+#define BF_PXP_INPUT_STORE_F_SHIFT_L_CH0_F_SHIFT_FLAG2(v) \
+ (((v) << 22) & BM_PXP_INPUT_STORE_F_SHIFT_L_CH0_F_SHIFT_FLAG2)
+#define BP_PXP_INPUT_STORE_F_SHIFT_L_CH0_F_SHIFT_WIDTH2 16
+#define BM_PXP_INPUT_STORE_F_SHIFT_L_CH0_F_SHIFT_WIDTH2 0x003F0000
+#define BF_PXP_INPUT_STORE_F_SHIFT_L_CH0_F_SHIFT_WIDTH2(v) \
+ (((v) << 16) & BM_PXP_INPUT_STORE_F_SHIFT_L_CH0_F_SHIFT_WIDTH2)
+#define BM_PXP_INPUT_STORE_F_SHIFT_L_CH0_RSVD2 0x00008000
+#define BF_PXP_INPUT_STORE_F_SHIFT_L_CH0_RSVD2(v) \
+ (((v) << 15) & BM_PXP_INPUT_STORE_F_SHIFT_L_CH0_RSVD2)
+#define BM_PXP_INPUT_STORE_F_SHIFT_L_CH0_F_SHIFT_FLAG1 0x00004000
+#define BF_PXP_INPUT_STORE_F_SHIFT_L_CH0_F_SHIFT_FLAG1(v) \
+ (((v) << 14) & BM_PXP_INPUT_STORE_F_SHIFT_L_CH0_F_SHIFT_FLAG1)
+#define BP_PXP_INPUT_STORE_F_SHIFT_L_CH0_F_SHIFT_WIDTH1 8
+#define BM_PXP_INPUT_STORE_F_SHIFT_L_CH0_F_SHIFT_WIDTH1 0x00003F00
+#define BF_PXP_INPUT_STORE_F_SHIFT_L_CH0_F_SHIFT_WIDTH1(v) \
+ (((v) << 8) & BM_PXP_INPUT_STORE_F_SHIFT_L_CH0_F_SHIFT_WIDTH1)
+#define BM_PXP_INPUT_STORE_F_SHIFT_L_CH0_RSVD3 0x00000080
+#define BF_PXP_INPUT_STORE_F_SHIFT_L_CH0_RSVD3(v) \
+ (((v) << 7) & BM_PXP_INPUT_STORE_F_SHIFT_L_CH0_RSVD3)
+#define BM_PXP_INPUT_STORE_F_SHIFT_L_CH0_F_SHIFT_FLAG0 0x00000040
+#define BF_PXP_INPUT_STORE_F_SHIFT_L_CH0_F_SHIFT_FLAG0(v) \
+ (((v) << 6) & BM_PXP_INPUT_STORE_F_SHIFT_L_CH0_F_SHIFT_FLAG0)
+#define BP_PXP_INPUT_STORE_F_SHIFT_L_CH0_F_SHIFT_WIDTH0 0
+#define BM_PXP_INPUT_STORE_F_SHIFT_L_CH0_F_SHIFT_WIDTH0 0x0000003F
+#define BF_PXP_INPUT_STORE_F_SHIFT_L_CH0_F_SHIFT_WIDTH0(v) \
+ (((v) << 0) & BM_PXP_INPUT_STORE_F_SHIFT_L_CH0_F_SHIFT_WIDTH0)
+
+#define HW_PXP_INPUT_STORE_F_SHIFT_H_CH0 (0x00000820)
+
+#define BM_PXP_INPUT_STORE_F_SHIFT_H_CH0_RSVD0 0x80000000
+#define BF_PXP_INPUT_STORE_F_SHIFT_H_CH0_RSVD0(v) \
+ (((v) << 31) & BM_PXP_INPUT_STORE_F_SHIFT_H_CH0_RSVD0)
+#define BM_PXP_INPUT_STORE_F_SHIFT_H_CH0_F_SHIFT_FLAG7 0x40000000
+#define BF_PXP_INPUT_STORE_F_SHIFT_H_CH0_F_SHIFT_FLAG7(v) \
+ (((v) << 30) & BM_PXP_INPUT_STORE_F_SHIFT_H_CH0_F_SHIFT_FLAG7)
+#define BP_PXP_INPUT_STORE_F_SHIFT_H_CH0_F_SHIFT_WIDTH7 24
+#define BM_PXP_INPUT_STORE_F_SHIFT_H_CH0_F_SHIFT_WIDTH7 0x3F000000
+#define BF_PXP_INPUT_STORE_F_SHIFT_H_CH0_F_SHIFT_WIDTH7(v) \
+ (((v) << 24) & BM_PXP_INPUT_STORE_F_SHIFT_H_CH0_F_SHIFT_WIDTH7)
+#define BM_PXP_INPUT_STORE_F_SHIFT_H_CH0_RSVD1 0x00800000
+#define BF_PXP_INPUT_STORE_F_SHIFT_H_CH0_RSVD1(v) \
+ (((v) << 23) & BM_PXP_INPUT_STORE_F_SHIFT_H_CH0_RSVD1)
+#define BM_PXP_INPUT_STORE_F_SHIFT_H_CH0_F_SHIFT_FLAG6 0x00400000
+#define BF_PXP_INPUT_STORE_F_SHIFT_H_CH0_F_SHIFT_FLAG6(v) \
+ (((v) << 22) & BM_PXP_INPUT_STORE_F_SHIFT_H_CH0_F_SHIFT_FLAG6)
+#define BP_PXP_INPUT_STORE_F_SHIFT_H_CH0_F_SHIFT_WIDTH6 16
+#define BM_PXP_INPUT_STORE_F_SHIFT_H_CH0_F_SHIFT_WIDTH6 0x003F0000
+#define BF_PXP_INPUT_STORE_F_SHIFT_H_CH0_F_SHIFT_WIDTH6(v) \
+ (((v) << 16) & BM_PXP_INPUT_STORE_F_SHIFT_H_CH0_F_SHIFT_WIDTH6)
+#define BM_PXP_INPUT_STORE_F_SHIFT_H_CH0_RSVD2 0x00008000
+#define BF_PXP_INPUT_STORE_F_SHIFT_H_CH0_RSVD2(v) \
+ (((v) << 15) & BM_PXP_INPUT_STORE_F_SHIFT_H_CH0_RSVD2)
+#define BM_PXP_INPUT_STORE_F_SHIFT_H_CH0_F_SHIFT_FLAG5 0x00004000
+#define BF_PXP_INPUT_STORE_F_SHIFT_H_CH0_F_SHIFT_FLAG5(v) \
+ (((v) << 14) & BM_PXP_INPUT_STORE_F_SHIFT_H_CH0_F_SHIFT_FLAG5)
+#define BP_PXP_INPUT_STORE_F_SHIFT_H_CH0_F_SHIFT_WIDTH5 8
+#define BM_PXP_INPUT_STORE_F_SHIFT_H_CH0_F_SHIFT_WIDTH5 0x00003F00
+#define BF_PXP_INPUT_STORE_F_SHIFT_H_CH0_F_SHIFT_WIDTH5(v) \
+ (((v) << 8) & BM_PXP_INPUT_STORE_F_SHIFT_H_CH0_F_SHIFT_WIDTH5)
+#define BM_PXP_INPUT_STORE_F_SHIFT_H_CH0_RSVD3 0x00000080
+#define BF_PXP_INPUT_STORE_F_SHIFT_H_CH0_RSVD3(v) \
+ (((v) << 7) & BM_PXP_INPUT_STORE_F_SHIFT_H_CH0_RSVD3)
+#define BM_PXP_INPUT_STORE_F_SHIFT_H_CH0_F_SHIFT_FLAG4 0x00000040
+#define BF_PXP_INPUT_STORE_F_SHIFT_H_CH0_F_SHIFT_FLAG4(v) \
+ (((v) << 6) & BM_PXP_INPUT_STORE_F_SHIFT_H_CH0_F_SHIFT_FLAG4)
+#define BP_PXP_INPUT_STORE_F_SHIFT_H_CH0_F_SHIFT_WIDTH4 0
+#define BM_PXP_INPUT_STORE_F_SHIFT_H_CH0_F_SHIFT_WIDTH4 0x0000003F
+#define BF_PXP_INPUT_STORE_F_SHIFT_H_CH0_F_SHIFT_WIDTH4(v) \
+ (((v) << 0) & BM_PXP_INPUT_STORE_F_SHIFT_H_CH0_F_SHIFT_WIDTH4)
+
+#define HW_PXP_INPUT_STORE_F_MASK_L_CH0 (0x00000830)
+
+#define BP_PXP_INPUT_STORE_F_MASK_L_CH0_F_MASK3 24
+#define BM_PXP_INPUT_STORE_F_MASK_L_CH0_F_MASK3 0xFF000000
+#define BF_PXP_INPUT_STORE_F_MASK_L_CH0_F_MASK3(v) \
+ (((v) << 24) & BM_PXP_INPUT_STORE_F_MASK_L_CH0_F_MASK3)
+#define BP_PXP_INPUT_STORE_F_MASK_L_CH0_F_MASK2 16
+#define BM_PXP_INPUT_STORE_F_MASK_L_CH0_F_MASK2 0x00FF0000
+#define BF_PXP_INPUT_STORE_F_MASK_L_CH0_F_MASK2(v) \
+ (((v) << 16) & BM_PXP_INPUT_STORE_F_MASK_L_CH0_F_MASK2)
+#define BP_PXP_INPUT_STORE_F_MASK_L_CH0_F_MASK1 8
+#define BM_PXP_INPUT_STORE_F_MASK_L_CH0_F_MASK1 0x0000FF00
+#define BF_PXP_INPUT_STORE_F_MASK_L_CH0_F_MASK1(v) \
+ (((v) << 8) & BM_PXP_INPUT_STORE_F_MASK_L_CH0_F_MASK1)
+#define BP_PXP_INPUT_STORE_F_MASK_L_CH0_F_MASK0 0
+#define BM_PXP_INPUT_STORE_F_MASK_L_CH0_F_MASK0 0x000000FF
+#define BF_PXP_INPUT_STORE_F_MASK_L_CH0_F_MASK0(v) \
+ (((v) << 0) & BM_PXP_INPUT_STORE_F_MASK_L_CH0_F_MASK0)
+
+#define HW_PXP_INPUT_STORE_F_MASK_H_CH0 (0x00000840)
+
+#define BP_PXP_INPUT_STORE_F_MASK_H_CH0_F_MASK7 24
+#define BM_PXP_INPUT_STORE_F_MASK_H_CH0_F_MASK7 0xFF000000
+#define BF_PXP_INPUT_STORE_F_MASK_H_CH0_F_MASK7(v) \
+ (((v) << 24) & BM_PXP_INPUT_STORE_F_MASK_H_CH0_F_MASK7)
+#define BP_PXP_INPUT_STORE_F_MASK_H_CH0_F_MASK6 16
+#define BM_PXP_INPUT_STORE_F_MASK_H_CH0_F_MASK6 0x00FF0000
+#define BF_PXP_INPUT_STORE_F_MASK_H_CH0_F_MASK6(v) \
+ (((v) << 16) & BM_PXP_INPUT_STORE_F_MASK_H_CH0_F_MASK6)
+#define BP_PXP_INPUT_STORE_F_MASK_H_CH0_F_MASK5 8
+#define BM_PXP_INPUT_STORE_F_MASK_H_CH0_F_MASK5 0x0000FF00
+#define BF_PXP_INPUT_STORE_F_MASK_H_CH0_F_MASK5(v) \
+ (((v) << 8) & BM_PXP_INPUT_STORE_F_MASK_H_CH0_F_MASK5)
+#define BP_PXP_INPUT_STORE_F_MASK_H_CH0_F_MASK4 0
+#define BM_PXP_INPUT_STORE_F_MASK_H_CH0_F_MASK4 0x000000FF
+#define BF_PXP_INPUT_STORE_F_MASK_H_CH0_F_MASK4(v) \
+ (((v) << 0) & BM_PXP_INPUT_STORE_F_MASK_H_CH0_F_MASK4)
+
+#define HW_PXP_DITHER_FETCH_CTRL_CH0 (0x00000850)
+#define HW_PXP_DITHER_FETCH_CTRL_CH0_SET (0x00000854)
+#define HW_PXP_DITHER_FETCH_CTRL_CH0_CLR (0x00000858)
+#define HW_PXP_DITHER_FETCH_CTRL_CH0_TOG (0x0000085c)
+
+#define BM_PXP_DITHER_FETCH_CTRL_CH0_ARBIT_EN 0x80000000
+#define BF_PXP_DITHER_FETCH_CTRL_CH0_ARBIT_EN(v) \
+ (((v) << 31) & BM_PXP_DITHER_FETCH_CTRL_CH0_ARBIT_EN)
+#define BV_PXP_DITHER_FETCH_CTRL_CH0_ARBIT_EN__0 0x0
+#define BV_PXP_DITHER_FETCH_CTRL_CH0_ARBIT_EN__1 0x1
+#define BP_PXP_DITHER_FETCH_CTRL_CH0_RSVD0 26
+#define BM_PXP_DITHER_FETCH_CTRL_CH0_RSVD0 0x7C000000
+#define BF_PXP_DITHER_FETCH_CTRL_CH0_RSVD0(v) \
+ (((v) << 26) & BM_PXP_DITHER_FETCH_CTRL_CH0_RSVD0)
+#define BP_PXP_DITHER_FETCH_CTRL_CH0_HANDSHAKE_SCAN_LINE_NUM 24
+#define BM_PXP_DITHER_FETCH_CTRL_CH0_HANDSHAKE_SCAN_LINE_NUM 0x03000000
+#define BF_PXP_DITHER_FETCH_CTRL_CH0_HANDSHAKE_SCAN_LINE_NUM(v) \
+ (((v) << 24) & BM_PXP_DITHER_FETCH_CTRL_CH0_HANDSHAKE_SCAN_LINE_NUM)
+#define BV_PXP_DITHER_FETCH_CTRL_CH0_HANDSHAKE_SCAN_LINE_NUM__0 0x0
+#define BV_PXP_DITHER_FETCH_CTRL_CH0_HANDSHAKE_SCAN_LINE_NUM__1 0x1
+#define BV_PXP_DITHER_FETCH_CTRL_CH0_HANDSHAKE_SCAN_LINE_NUM__2 0x2
+#define BV_PXP_DITHER_FETCH_CTRL_CH0_HANDSHAKE_SCAN_LINE_NUM__3 0x3
+#define BP_PXP_DITHER_FETCH_CTRL_CH0_RSVD1 18
+#define BM_PXP_DITHER_FETCH_CTRL_CH0_RSVD1 0x00FC0000
+#define BF_PXP_DITHER_FETCH_CTRL_CH0_RSVD1(v) \
+ (((v) << 18) & BM_PXP_DITHER_FETCH_CTRL_CH0_RSVD1)
+#define BP_PXP_DITHER_FETCH_CTRL_CH0_RD_NUM_BYTES 16
+#define BM_PXP_DITHER_FETCH_CTRL_CH0_RD_NUM_BYTES 0x00030000
+#define BF_PXP_DITHER_FETCH_CTRL_CH0_RD_NUM_BYTES(v) \
+ (((v) << 16) & BM_PXP_DITHER_FETCH_CTRL_CH0_RD_NUM_BYTES)
+#define BV_PXP_DITHER_FETCH_CTRL_CH0_RD_NUM_BYTES__8_bytes 0x0
+#define BV_PXP_DITHER_FETCH_CTRL_CH0_RD_NUM_BYTES__16_bytes 0x1
+#define BV_PXP_DITHER_FETCH_CTRL_CH0_RD_NUM_BYTES__32_bytes 0x2
+#define BV_PXP_DITHER_FETCH_CTRL_CH0_RD_NUM_BYTES__64_bytes 0x3
+#define BP_PXP_DITHER_FETCH_CTRL_CH0_RSVD2 14
+#define BM_PXP_DITHER_FETCH_CTRL_CH0_RSVD2 0x0000C000
+#define BF_PXP_DITHER_FETCH_CTRL_CH0_RSVD2(v) \
+ (((v) << 14) & BM_PXP_DITHER_FETCH_CTRL_CH0_RSVD2)
+#define BP_PXP_DITHER_FETCH_CTRL_CH0_ROTATION_ANGLE 12
+#define BM_PXP_DITHER_FETCH_CTRL_CH0_ROTATION_ANGLE 0x00003000
+#define BF_PXP_DITHER_FETCH_CTRL_CH0_ROTATION_ANGLE(v) \
+ (((v) << 12) & BM_PXP_DITHER_FETCH_CTRL_CH0_ROTATION_ANGLE)
+#define BV_PXP_DITHER_FETCH_CTRL_CH0_ROTATION_ANGLE__ROT_0 0x0
+#define BV_PXP_DITHER_FETCH_CTRL_CH0_ROTATION_ANGLE__ROT_90 0x1
+#define BV_PXP_DITHER_FETCH_CTRL_CH0_ROTATION_ANGLE__ROT_180 0x2
+#define BV_PXP_DITHER_FETCH_CTRL_CH0_ROTATION_ANGLE__ROT_270 0x3
+#define BM_PXP_DITHER_FETCH_CTRL_CH0_RSVD3 0x00000800
+#define BF_PXP_DITHER_FETCH_CTRL_CH0_RSVD3(v) \
+ (((v) << 11) & BM_PXP_DITHER_FETCH_CTRL_CH0_RSVD3)
+#define BM_PXP_DITHER_FETCH_CTRL_CH0_VFLIP 0x00000400
+#define BF_PXP_DITHER_FETCH_CTRL_CH0_VFLIP(v) \
+ (((v) << 10) & BM_PXP_DITHER_FETCH_CTRL_CH0_VFLIP)
+#define BV_PXP_DITHER_FETCH_CTRL_CH0_VFLIP__0 0x0
+#define BV_PXP_DITHER_FETCH_CTRL_CH0_VFLIP__1 0x1
+#define BM_PXP_DITHER_FETCH_CTRL_CH0_HFLIP 0x00000200
+#define BF_PXP_DITHER_FETCH_CTRL_CH0_HFLIP(v) \
+ (((v) << 9) & BM_PXP_DITHER_FETCH_CTRL_CH0_HFLIP)
+#define BV_PXP_DITHER_FETCH_CTRL_CH0_HFLIP__0 0x0
+#define BV_PXP_DITHER_FETCH_CTRL_CH0_HFLIP__1 0x1
+#define BP_PXP_DITHER_FETCH_CTRL_CH0_RSVD4 6
+#define BM_PXP_DITHER_FETCH_CTRL_CH0_RSVD4 0x000001C0
+#define BF_PXP_DITHER_FETCH_CTRL_CH0_RSVD4(v) \
+ (((v) << 6) & BM_PXP_DITHER_FETCH_CTRL_CH0_RSVD4)
+#define BM_PXP_DITHER_FETCH_CTRL_CH0_HIGH_BYTE 0x00000020
+#define BF_PXP_DITHER_FETCH_CTRL_CH0_HIGH_BYTE(v) \
+ (((v) << 5) & BM_PXP_DITHER_FETCH_CTRL_CH0_HIGH_BYTE)
+#define BV_PXP_DITHER_FETCH_CTRL_CH0_HIGH_BYTE__0 0x0
+#define BV_PXP_DITHER_FETCH_CTRL_CH0_HIGH_BYTE__1 0x1
+#define BM_PXP_DITHER_FETCH_CTRL_CH0_BYPASS_PIXEL_EN 0x00000010
+#define BF_PXP_DITHER_FETCH_CTRL_CH0_BYPASS_PIXEL_EN(v) \
+ (((v) << 4) & BM_PXP_DITHER_FETCH_CTRL_CH0_BYPASS_PIXEL_EN)
+#define BV_PXP_DITHER_FETCH_CTRL_CH0_BYPASS_PIXEL_EN__0 0x0
+#define BV_PXP_DITHER_FETCH_CTRL_CH0_BYPASS_PIXEL_EN__1 0x1
+#define BM_PXP_DITHER_FETCH_CTRL_CH0_HANDSHAKE_EN 0x00000008
+#define BF_PXP_DITHER_FETCH_CTRL_CH0_HANDSHAKE_EN(v) \
+ (((v) << 3) & BM_PXP_DITHER_FETCH_CTRL_CH0_HANDSHAKE_EN)
+#define BV_PXP_DITHER_FETCH_CTRL_CH0_HANDSHAKE_EN__0 0x0
+#define BV_PXP_DITHER_FETCH_CTRL_CH0_HANDSHAKE_EN__1 0x1
+#define BM_PXP_DITHER_FETCH_CTRL_CH0_BLOCK_16 0x00000004
+#define BF_PXP_DITHER_FETCH_CTRL_CH0_BLOCK_16(v) \
+ (((v) << 2) & BM_PXP_DITHER_FETCH_CTRL_CH0_BLOCK_16)
+#define BV_PXP_DITHER_FETCH_CTRL_CH0_BLOCK_16__8x8 0x0
+#define BV_PXP_DITHER_FETCH_CTRL_CH0_BLOCK_16__16x16 0x1
+#define BM_PXP_DITHER_FETCH_CTRL_CH0_BLOCK_EN 0x00000002
+#define BF_PXP_DITHER_FETCH_CTRL_CH0_BLOCK_EN(v) \
+ (((v) << 1) & BM_PXP_DITHER_FETCH_CTRL_CH0_BLOCK_EN)
+#define BV_PXP_DITHER_FETCH_CTRL_CH0_BLOCK_EN__0 0x0
+#define BV_PXP_DITHER_FETCH_CTRL_CH0_BLOCK_EN__1 0x1
+#define BM_PXP_DITHER_FETCH_CTRL_CH0_CH_EN 0x00000001
+#define BF_PXP_DITHER_FETCH_CTRL_CH0_CH_EN(v) \
+ (((v) << 0) & BM_PXP_DITHER_FETCH_CTRL_CH0_CH_EN)
+#define BV_PXP_DITHER_FETCH_CTRL_CH0_CH_EN__0 0x0
+#define BV_PXP_DITHER_FETCH_CTRL_CH0_CH_EN__1 0x1
+
+#define HW_PXP_DITHER_FETCH_CTRL_CH1 (0x00000860)
+#define HW_PXP_DITHER_FETCH_CTRL_CH1_SET (0x00000864)
+#define HW_PXP_DITHER_FETCH_CTRL_CH1_CLR (0x00000868)
+#define HW_PXP_DITHER_FETCH_CTRL_CH1_TOG (0x0000086c)
+
+#define BP_PXP_DITHER_FETCH_CTRL_CH1_RSVD0 26
+#define BM_PXP_DITHER_FETCH_CTRL_CH1_RSVD0 0xFC000000
+#define BF_PXP_DITHER_FETCH_CTRL_CH1_RSVD0(v) \
+ (((v) << 26) & BM_PXP_DITHER_FETCH_CTRL_CH1_RSVD0)
+#define BP_PXP_DITHER_FETCH_CTRL_CH1_HANDSHAKE_SCAN_LINE_NUM 24
+#define BM_PXP_DITHER_FETCH_CTRL_CH1_HANDSHAKE_SCAN_LINE_NUM 0x03000000
+#define BF_PXP_DITHER_FETCH_CTRL_CH1_HANDSHAKE_SCAN_LINE_NUM(v) \
+ (((v) << 24) & BM_PXP_DITHER_FETCH_CTRL_CH1_HANDSHAKE_SCAN_LINE_NUM)
+#define BV_PXP_DITHER_FETCH_CTRL_CH1_HANDSHAKE_SCAN_LINE_NUM__0 0x0
+#define BV_PXP_DITHER_FETCH_CTRL_CH1_HANDSHAKE_SCAN_LINE_NUM__1 0x1
+#define BV_PXP_DITHER_FETCH_CTRL_CH1_HANDSHAKE_SCAN_LINE_NUM__2 0x2
+#define BV_PXP_DITHER_FETCH_CTRL_CH1_HANDSHAKE_SCAN_LINE_NUM__3 0x3
+#define BP_PXP_DITHER_FETCH_CTRL_CH1_RSVD1 18
+#define BM_PXP_DITHER_FETCH_CTRL_CH1_RSVD1 0x00FC0000
+#define BF_PXP_DITHER_FETCH_CTRL_CH1_RSVD1(v) \
+ (((v) << 18) & BM_PXP_DITHER_FETCH_CTRL_CH1_RSVD1)
+#define BP_PXP_DITHER_FETCH_CTRL_CH1_RD_NUM_BYTES 16
+#define BM_PXP_DITHER_FETCH_CTRL_CH1_RD_NUM_BYTES 0x00030000
+#define BF_PXP_DITHER_FETCH_CTRL_CH1_RD_NUM_BYTES(v) \
+ (((v) << 16) & BM_PXP_DITHER_FETCH_CTRL_CH1_RD_NUM_BYTES)
+#define BV_PXP_DITHER_FETCH_CTRL_CH1_RD_NUM_BYTES__8_bytes 0x0
+#define BV_PXP_DITHER_FETCH_CTRL_CH1_RD_NUM_BYTES__16_bytes 0x1
+#define BV_PXP_DITHER_FETCH_CTRL_CH1_RD_NUM_BYTES__32_bytes 0x2
+#define BV_PXP_DITHER_FETCH_CTRL_CH1_RD_NUM_BYTES__64_bytes 0x3
+#define BP_PXP_DITHER_FETCH_CTRL_CH1_RSVD2 14
+#define BM_PXP_DITHER_FETCH_CTRL_CH1_RSVD2 0x0000C000
+#define BF_PXP_DITHER_FETCH_CTRL_CH1_RSVD2(v) \
+ (((v) << 14) & BM_PXP_DITHER_FETCH_CTRL_CH1_RSVD2)
+#define BP_PXP_DITHER_FETCH_CTRL_CH1_ROTATION_ANGLE 12
+#define BM_PXP_DITHER_FETCH_CTRL_CH1_ROTATION_ANGLE 0x00003000
+#define BF_PXP_DITHER_FETCH_CTRL_CH1_ROTATION_ANGLE(v) \
+ (((v) << 12) & BM_PXP_DITHER_FETCH_CTRL_CH1_ROTATION_ANGLE)
+#define BV_PXP_DITHER_FETCH_CTRL_CH1_ROTATION_ANGLE__ROT_0 0x0
+#define BV_PXP_DITHER_FETCH_CTRL_CH1_ROTATION_ANGLE__ROT_90 0x1
+#define BV_PXP_DITHER_FETCH_CTRL_CH1_ROTATION_ANGLE__ROT_180 0x2
+#define BV_PXP_DITHER_FETCH_CTRL_CH1_ROTATION_ANGLE__ROT_270 0x3
+#define BM_PXP_DITHER_FETCH_CTRL_CH1_RSVD3 0x00000800
+#define BF_PXP_DITHER_FETCH_CTRL_CH1_RSVD3(v) \
+ (((v) << 11) & BM_PXP_DITHER_FETCH_CTRL_CH1_RSVD3)
+#define BM_PXP_DITHER_FETCH_CTRL_CH1_VFLIP 0x00000400
+#define BF_PXP_DITHER_FETCH_CTRL_CH1_VFLIP(v) \
+ (((v) << 10) & BM_PXP_DITHER_FETCH_CTRL_CH1_VFLIP)
+#define BV_PXP_DITHER_FETCH_CTRL_CH1_VFLIP__0 0x0
+#define BV_PXP_DITHER_FETCH_CTRL_CH1_VFLIP__1 0x1
+#define BM_PXP_DITHER_FETCH_CTRL_CH1_HFLIP 0x00000200
+#define BF_PXP_DITHER_FETCH_CTRL_CH1_HFLIP(v) \
+ (((v) << 9) & BM_PXP_DITHER_FETCH_CTRL_CH1_HFLIP)
+#define BV_PXP_DITHER_FETCH_CTRL_CH1_HFLIP__0 0x0
+#define BV_PXP_DITHER_FETCH_CTRL_CH1_HFLIP__1 0x1
+#define BP_PXP_DITHER_FETCH_CTRL_CH1_RSVD4 5
+#define BM_PXP_DITHER_FETCH_CTRL_CH1_RSVD4 0x000001E0
+#define BF_PXP_DITHER_FETCH_CTRL_CH1_RSVD4(v) \
+ (((v) << 5) & BM_PXP_DITHER_FETCH_CTRL_CH1_RSVD4)
+#define BM_PXP_DITHER_FETCH_CTRL_CH1_BYPASS_PIXEL_EN 0x00000010
+#define BF_PXP_DITHER_FETCH_CTRL_CH1_BYPASS_PIXEL_EN(v) \
+ (((v) << 4) & BM_PXP_DITHER_FETCH_CTRL_CH1_BYPASS_PIXEL_EN)
+#define BV_PXP_DITHER_FETCH_CTRL_CH1_BYPASS_PIXEL_EN__0 0x0
+#define BV_PXP_DITHER_FETCH_CTRL_CH1_BYPASS_PIXEL_EN__1 0x1
+#define BM_PXP_DITHER_FETCH_CTRL_CH1_HANDSHAKE_EN 0x00000008
+#define BF_PXP_DITHER_FETCH_CTRL_CH1_HANDSHAKE_EN(v) \
+ (((v) << 3) & BM_PXP_DITHER_FETCH_CTRL_CH1_HANDSHAKE_EN)
+#define BV_PXP_DITHER_FETCH_CTRL_CH1_HANDSHAKE_EN__0 0x0
+#define BV_PXP_DITHER_FETCH_CTRL_CH1_HANDSHAKE_EN__1 0x1
+#define BM_PXP_DITHER_FETCH_CTRL_CH1_BLOCK_16 0x00000004
+#define BF_PXP_DITHER_FETCH_CTRL_CH1_BLOCK_16(v) \
+ (((v) << 2) & BM_PXP_DITHER_FETCH_CTRL_CH1_BLOCK_16)
+#define BV_PXP_DITHER_FETCH_CTRL_CH1_BLOCK_16__8x8 0x0
+#define BV_PXP_DITHER_FETCH_CTRL_CH1_BLOCK_16__16x16 0x1
+#define BM_PXP_DITHER_FETCH_CTRL_CH1_BLOCK_EN 0x00000002
+#define BF_PXP_DITHER_FETCH_CTRL_CH1_BLOCK_EN(v) \
+ (((v) << 1) & BM_PXP_DITHER_FETCH_CTRL_CH1_BLOCK_EN)
+#define BV_PXP_DITHER_FETCH_CTRL_CH1_BLOCK_EN__0 0x0
+#define BV_PXP_DITHER_FETCH_CTRL_CH1_BLOCK_EN__1 0x1
+#define BM_PXP_DITHER_FETCH_CTRL_CH1_CH_EN 0x00000001
+#define BF_PXP_DITHER_FETCH_CTRL_CH1_CH_EN(v) \
+ (((v) << 0) & BM_PXP_DITHER_FETCH_CTRL_CH1_CH_EN)
+#define BV_PXP_DITHER_FETCH_CTRL_CH1_CH_EN__0 0x0
+#define BV_PXP_DITHER_FETCH_CTRL_CH1_CH_EN__1 0x1
+
+#define HW_PXP_DITHER_FETCH_STATUS_CH0 (0x00000870)
+
+#define BP_PXP_DITHER_FETCH_STATUS_CH0_PREFETCH_BLOCK_Y 16
+#define BM_PXP_DITHER_FETCH_STATUS_CH0_PREFETCH_BLOCK_Y 0xFFFF0000
+#define BF_PXP_DITHER_FETCH_STATUS_CH0_PREFETCH_BLOCK_Y(v) \
+ (((v) << 16) & BM_PXP_DITHER_FETCH_STATUS_CH0_PREFETCH_BLOCK_Y)
+#define BP_PXP_DITHER_FETCH_STATUS_CH0_PREFETCH_BLOCK_X 0
+#define BM_PXP_DITHER_FETCH_STATUS_CH0_PREFETCH_BLOCK_X 0x0000FFFF
+#define BF_PXP_DITHER_FETCH_STATUS_CH0_PREFETCH_BLOCK_X(v) \
+ (((v) << 0) & BM_PXP_DITHER_FETCH_STATUS_CH0_PREFETCH_BLOCK_X)
+
+#define HW_PXP_DITHER_FETCH_STATUS_CH1 (0x00000880)
+
+#define BP_PXP_DITHER_FETCH_STATUS_CH1_PREFETCH_BLOCK_Y 16
+#define BM_PXP_DITHER_FETCH_STATUS_CH1_PREFETCH_BLOCK_Y 0xFFFF0000
+#define BF_PXP_DITHER_FETCH_STATUS_CH1_PREFETCH_BLOCK_Y(v) \
+ (((v) << 16) & BM_PXP_DITHER_FETCH_STATUS_CH1_PREFETCH_BLOCK_Y)
+#define BP_PXP_DITHER_FETCH_STATUS_CH1_PREFETCH_BLOCK_X 0
+#define BM_PXP_DITHER_FETCH_STATUS_CH1_PREFETCH_BLOCK_X 0x0000FFFF
+#define BF_PXP_DITHER_FETCH_STATUS_CH1_PREFETCH_BLOCK_X(v) \
+ (((v) << 0) & BM_PXP_DITHER_FETCH_STATUS_CH1_PREFETCH_BLOCK_X)
+
+#define HW_PXP_DITHER_FETCH_ACTIVE_SIZE_ULC_CH0 (0x00000890)
+
+#define BP_PXP_DITHER_FETCH_ACTIVE_SIZE_ULC_CH0_ACTIVE_SIZE_ULC_Y 16
+#define BM_PXP_DITHER_FETCH_ACTIVE_SIZE_ULC_CH0_ACTIVE_SIZE_ULC_Y 0xFFFF0000
+#define BF_PXP_DITHER_FETCH_ACTIVE_SIZE_ULC_CH0_ACTIVE_SIZE_ULC_Y(v) \
+ (((v) << 16) & BM_PXP_DITHER_FETCH_ACTIVE_SIZE_ULC_CH0_ACTIVE_SIZE_ULC_Y)
+#define BP_PXP_DITHER_FETCH_ACTIVE_SIZE_ULC_CH0_ACTIVE_SIZE_ULC_X 0
+#define BM_PXP_DITHER_FETCH_ACTIVE_SIZE_ULC_CH0_ACTIVE_SIZE_ULC_X 0x0000FFFF
+#define BF_PXP_DITHER_FETCH_ACTIVE_SIZE_ULC_CH0_ACTIVE_SIZE_ULC_X(v) \
+ (((v) << 0) & BM_PXP_DITHER_FETCH_ACTIVE_SIZE_ULC_CH0_ACTIVE_SIZE_ULC_X)
+
+#define HW_PXP_DITHER_FETCH_ACTIVE_SIZE_LRC_CH0 (0x000008a0)
+
+#define BP_PXP_DITHER_FETCH_ACTIVE_SIZE_LRC_CH0_ACTIVE_SIZE_LRC_Y 16
+#define BM_PXP_DITHER_FETCH_ACTIVE_SIZE_LRC_CH0_ACTIVE_SIZE_LRC_Y 0xFFFF0000
+#define BF_PXP_DITHER_FETCH_ACTIVE_SIZE_LRC_CH0_ACTIVE_SIZE_LRC_Y(v) \
+ (((v) << 16) & BM_PXP_DITHER_FETCH_ACTIVE_SIZE_LRC_CH0_ACTIVE_SIZE_LRC_Y)
+#define BP_PXP_DITHER_FETCH_ACTIVE_SIZE_LRC_CH0_ACTIVE_SIZE_LRC_X 0
+#define BM_PXP_DITHER_FETCH_ACTIVE_SIZE_LRC_CH0_ACTIVE_SIZE_LRC_X 0x0000FFFF
+#define BF_PXP_DITHER_FETCH_ACTIVE_SIZE_LRC_CH0_ACTIVE_SIZE_LRC_X(v) \
+ (((v) << 0) & BM_PXP_DITHER_FETCH_ACTIVE_SIZE_LRC_CH0_ACTIVE_SIZE_LRC_X)
+
+#define HW_PXP_DITHER_FETCH_ACTIVE_SIZE_ULC_CH1 (0x000008b0)
+
+#define BP_PXP_DITHER_FETCH_ACTIVE_SIZE_ULC_CH1_ACTIVE_SIZE_ULC_Y 16
+#define BM_PXP_DITHER_FETCH_ACTIVE_SIZE_ULC_CH1_ACTIVE_SIZE_ULC_Y 0xFFFF0000
+#define BF_PXP_DITHER_FETCH_ACTIVE_SIZE_ULC_CH1_ACTIVE_SIZE_ULC_Y(v) \
+ (((v) << 16) & BM_PXP_DITHER_FETCH_ACTIVE_SIZE_ULC_CH1_ACTIVE_SIZE_ULC_Y)
+#define BP_PXP_DITHER_FETCH_ACTIVE_SIZE_ULC_CH1_ACTIVE_SIZE_ULC_X 0
+#define BM_PXP_DITHER_FETCH_ACTIVE_SIZE_ULC_CH1_ACTIVE_SIZE_ULC_X 0x0000FFFF
+#define BF_PXP_DITHER_FETCH_ACTIVE_SIZE_ULC_CH1_ACTIVE_SIZE_ULC_X(v) \
+ (((v) << 0) & BM_PXP_DITHER_FETCH_ACTIVE_SIZE_ULC_CH1_ACTIVE_SIZE_ULC_X)
+
+#define HW_PXP_DITHER_FETCH_ACTIVE_SIZE_LRC_CH1 (0x000008c0)
+
+#define BP_PXP_DITHER_FETCH_ACTIVE_SIZE_LRC_CH1_ACTIVE_SIZE_LRC_Y 16
+#define BM_PXP_DITHER_FETCH_ACTIVE_SIZE_LRC_CH1_ACTIVE_SIZE_LRC_Y 0xFFFF0000
+#define BF_PXP_DITHER_FETCH_ACTIVE_SIZE_LRC_CH1_ACTIVE_SIZE_LRC_Y(v) \
+ (((v) << 16) & BM_PXP_DITHER_FETCH_ACTIVE_SIZE_LRC_CH1_ACTIVE_SIZE_LRC_Y)
+#define BP_PXP_DITHER_FETCH_ACTIVE_SIZE_LRC_CH1_ACTIVE_SIZE_LRC_X 0
+#define BM_PXP_DITHER_FETCH_ACTIVE_SIZE_LRC_CH1_ACTIVE_SIZE_LRC_X 0x0000FFFF
+#define BF_PXP_DITHER_FETCH_ACTIVE_SIZE_LRC_CH1_ACTIVE_SIZE_LRC_X(v) \
+ (((v) << 0) & BM_PXP_DITHER_FETCH_ACTIVE_SIZE_LRC_CH1_ACTIVE_SIZE_LRC_X)
+
+#define HW_PXP_DITHER_FETCH_SIZE_CH0 (0x000008d0)
+
+#define BP_PXP_DITHER_FETCH_SIZE_CH0_INPUT_TOTAL_HEIGHT 16
+#define BM_PXP_DITHER_FETCH_SIZE_CH0_INPUT_TOTAL_HEIGHT 0xFFFF0000
+#define BF_PXP_DITHER_FETCH_SIZE_CH0_INPUT_TOTAL_HEIGHT(v) \
+ (((v) << 16) & BM_PXP_DITHER_FETCH_SIZE_CH0_INPUT_TOTAL_HEIGHT)
+#define BP_PXP_DITHER_FETCH_SIZE_CH0_INPUT_TOTAL_WIDTH 0
+#define BM_PXP_DITHER_FETCH_SIZE_CH0_INPUT_TOTAL_WIDTH 0x0000FFFF
+#define BF_PXP_DITHER_FETCH_SIZE_CH0_INPUT_TOTAL_WIDTH(v) \
+ (((v) << 0) & BM_PXP_DITHER_FETCH_SIZE_CH0_INPUT_TOTAL_WIDTH)
+
+#define HW_PXP_DITHER_FETCH_SIZE_CH1 (0x000008e0)
+
+#define BP_PXP_DITHER_FETCH_SIZE_CH1_INPUT_TOTAL_HEIGHT 16
+#define BM_PXP_DITHER_FETCH_SIZE_CH1_INPUT_TOTAL_HEIGHT 0xFFFF0000
+#define BF_PXP_DITHER_FETCH_SIZE_CH1_INPUT_TOTAL_HEIGHT(v) \
+ (((v) << 16) & BM_PXP_DITHER_FETCH_SIZE_CH1_INPUT_TOTAL_HEIGHT)
+#define BP_PXP_DITHER_FETCH_SIZE_CH1_INPUT_TOTAL_WIDTH 0
+#define BM_PXP_DITHER_FETCH_SIZE_CH1_INPUT_TOTAL_WIDTH 0x0000FFFF
+#define BF_PXP_DITHER_FETCH_SIZE_CH1_INPUT_TOTAL_WIDTH(v) \
+ (((v) << 0) & BM_PXP_DITHER_FETCH_SIZE_CH1_INPUT_TOTAL_WIDTH)
+
+#define HW_PXP_DITHER_FETCH_BACKGROUND_COLOR_CH0 (0x000008f0)
+
+#define BP_PXP_DITHER_FETCH_BACKGROUND_COLOR_CH0_BACKGROUND_COLOR 0
+#define BM_PXP_DITHER_FETCH_BACKGROUND_COLOR_CH0_BACKGROUND_COLOR 0xFFFFFFFF
+#define BF_PXP_DITHER_FETCH_BACKGROUND_COLOR_CH0_BACKGROUND_COLOR(v) (v)
+
+#define HW_PXP_DITHER_FETCH_BACKGROUND_COLOR_CH1 (0x00000900)
+
+#define BP_PXP_DITHER_FETCH_BACKGROUND_COLOR_CH1_BACKGROUND_COLOR 0
+#define BM_PXP_DITHER_FETCH_BACKGROUND_COLOR_CH1_BACKGROUND_COLOR 0xFFFFFFFF
+#define BF_PXP_DITHER_FETCH_BACKGROUND_COLOR_CH1_BACKGROUND_COLOR(v) (v)
+
+#define HW_PXP_DITHER_FETCH_PITCH (0x00000910)
+
+#define BP_PXP_DITHER_FETCH_PITCH_CH1_INPUT_PITCH 16
+#define BM_PXP_DITHER_FETCH_PITCH_CH1_INPUT_PITCH 0xFFFF0000
+#define BF_PXP_DITHER_FETCH_PITCH_CH1_INPUT_PITCH(v) \
+ (((v) << 16) & BM_PXP_DITHER_FETCH_PITCH_CH1_INPUT_PITCH)
+#define BP_PXP_DITHER_FETCH_PITCH_CH0_INPUT_PITCH 0
+#define BM_PXP_DITHER_FETCH_PITCH_CH0_INPUT_PITCH 0x0000FFFF
+#define BF_PXP_DITHER_FETCH_PITCH_CH0_INPUT_PITCH(v) \
+ (((v) << 0) & BM_PXP_DITHER_FETCH_PITCH_CH0_INPUT_PITCH)
+
+#define HW_PXP_DITHER_FETCH_SHIFT_CTRL_CH0 (0x00000920)
+#define HW_PXP_DITHER_FETCH_SHIFT_CTRL_CH0_SET (0x00000924)
+#define HW_PXP_DITHER_FETCH_SHIFT_CTRL_CH0_CLR (0x00000928)
+#define HW_PXP_DITHER_FETCH_SHIFT_CTRL_CH0_TOG (0x0000092c)
+
+#define BP_PXP_DITHER_FETCH_SHIFT_CTRL_CH0_RSVD0 13
+#define BM_PXP_DITHER_FETCH_SHIFT_CTRL_CH0_RSVD0 0xFFFFE000
+#define BF_PXP_DITHER_FETCH_SHIFT_CTRL_CH0_RSVD0(v) \
+ (((v) << 13) & BM_PXP_DITHER_FETCH_SHIFT_CTRL_CH0_RSVD0)
+#define BM_PXP_DITHER_FETCH_SHIFT_CTRL_CH0_SHIFT_BYPASS 0x00001000
+#define BF_PXP_DITHER_FETCH_SHIFT_CTRL_CH0_SHIFT_BYPASS(v) \
+ (((v) << 12) & BM_PXP_DITHER_FETCH_SHIFT_CTRL_CH0_SHIFT_BYPASS)
+#define BV_PXP_DITHER_FETCH_SHIFT_CTRL_CH0_SHIFT_BYPASS__0 0x0
+#define BV_PXP_DITHER_FETCH_SHIFT_CTRL_CH0_SHIFT_BYPASS__1 0x1
+#define BM_PXP_DITHER_FETCH_SHIFT_CTRL_CH0_EXPAND_EN 0x00000800
+#define BF_PXP_DITHER_FETCH_SHIFT_CTRL_CH0_EXPAND_EN(v) \
+ (((v) << 11) & BM_PXP_DITHER_FETCH_SHIFT_CTRL_CH0_EXPAND_EN)
+#define BV_PXP_DITHER_FETCH_SHIFT_CTRL_CH0_EXPAND_EN__0 0x0
+#define BV_PXP_DITHER_FETCH_SHIFT_CTRL_CH0_EXPAND_EN__1 0x1
+#define BP_PXP_DITHER_FETCH_SHIFT_CTRL_CH0_EXPAND_FORMAT 8
+#define BM_PXP_DITHER_FETCH_SHIFT_CTRL_CH0_EXPAND_FORMAT 0x00000700
+#define BF_PXP_DITHER_FETCH_SHIFT_CTRL_CH0_EXPAND_FORMAT(v) \
+ (((v) << 8) & BM_PXP_DITHER_FETCH_SHIFT_CTRL_CH0_EXPAND_FORMAT)
+#define BV_PXP_DITHER_FETCH_SHIFT_CTRL_CH0_EXPAND_FORMAT__0 0x0
+#define BV_PXP_DITHER_FETCH_SHIFT_CTRL_CH0_EXPAND_FORMAT__1 0x1
+#define BV_PXP_DITHER_FETCH_SHIFT_CTRL_CH0_EXPAND_FORMAT__2 0x2
+#define BV_PXP_DITHER_FETCH_SHIFT_CTRL_CH0_EXPAND_FORMAT__3 0x3
+#define BV_PXP_DITHER_FETCH_SHIFT_CTRL_CH0_EXPAND_FORMAT__4 0x4
+#define BV_PXP_DITHER_FETCH_SHIFT_CTRL_CH0_EXPAND_FORMAT__5 0x5
+#define BV_PXP_DITHER_FETCH_SHIFT_CTRL_CH0_EXPAND_FORMAT__6 0x6
+#define BV_PXP_DITHER_FETCH_SHIFT_CTRL_CH0_EXPAND_FORMAT__7 0x7
+#define BP_PXP_DITHER_FETCH_SHIFT_CTRL_CH0_RSVD1 2
+#define BM_PXP_DITHER_FETCH_SHIFT_CTRL_CH0_RSVD1 0x000000FC
+#define BF_PXP_DITHER_FETCH_SHIFT_CTRL_CH0_RSVD1(v) \
+ (((v) << 2) & BM_PXP_DITHER_FETCH_SHIFT_CTRL_CH0_RSVD1)
+#define BP_PXP_DITHER_FETCH_SHIFT_CTRL_CH0_INPUT_ACTIVE_BPP 0
+#define BM_PXP_DITHER_FETCH_SHIFT_CTRL_CH0_INPUT_ACTIVE_BPP 0x00000003
+#define BF_PXP_DITHER_FETCH_SHIFT_CTRL_CH0_INPUT_ACTIVE_BPP(v) \
+ (((v) << 0) & BM_PXP_DITHER_FETCH_SHIFT_CTRL_CH0_INPUT_ACTIVE_BPP)
+#define BV_PXP_DITHER_FETCH_SHIFT_CTRL_CH0_INPUT_ACTIVE_BPP__0 0x0
+#define BV_PXP_DITHER_FETCH_SHIFT_CTRL_CH0_INPUT_ACTIVE_BPP__1 0x1
+#define BV_PXP_DITHER_FETCH_SHIFT_CTRL_CH0_INPUT_ACTIVE_BPP__2 0x2
+#define BV_PXP_DITHER_FETCH_SHIFT_CTRL_CH0_INPUT_ACTIVE_BPP__3 0x3
+
+#define HW_PXP_DITHER_FETCH_SHIFT_CTRL_CH1 (0x00000930)
+#define HW_PXP_DITHER_FETCH_SHIFT_CTRL_CH1_SET (0x00000934)
+#define HW_PXP_DITHER_FETCH_SHIFT_CTRL_CH1_CLR (0x00000938)
+#define HW_PXP_DITHER_FETCH_SHIFT_CTRL_CH1_TOG (0x0000093c)
+
+#define BP_PXP_DITHER_FETCH_SHIFT_CTRL_CH1_RSVD0 13
+#define BM_PXP_DITHER_FETCH_SHIFT_CTRL_CH1_RSVD0 0xFFFFE000
+#define BF_PXP_DITHER_FETCH_SHIFT_CTRL_CH1_RSVD0(v) \
+ (((v) << 13) & BM_PXP_DITHER_FETCH_SHIFT_CTRL_CH1_RSVD0)
+#define BM_PXP_DITHER_FETCH_SHIFT_CTRL_CH1_SHIFT_BYPASS 0x00001000
+#define BF_PXP_DITHER_FETCH_SHIFT_CTRL_CH1_SHIFT_BYPASS(v) \
+ (((v) << 12) & BM_PXP_DITHER_FETCH_SHIFT_CTRL_CH1_SHIFT_BYPASS)
+#define BV_PXP_DITHER_FETCH_SHIFT_CTRL_CH1_SHIFT_BYPASS__0 0x0
+#define BV_PXP_DITHER_FETCH_SHIFT_CTRL_CH1_SHIFT_BYPASS__1 0x1
+#define BM_PXP_DITHER_FETCH_SHIFT_CTRL_CH1_EXPAND_EN 0x00000800
+#define BF_PXP_DITHER_FETCH_SHIFT_CTRL_CH1_EXPAND_EN(v) \
+ (((v) << 11) & BM_PXP_DITHER_FETCH_SHIFT_CTRL_CH1_EXPAND_EN)
+#define BV_PXP_DITHER_FETCH_SHIFT_CTRL_CH1_EXPAND_EN__0 0x0
+#define BV_PXP_DITHER_FETCH_SHIFT_CTRL_CH1_EXPAND_EN__1 0x1
+#define BP_PXP_DITHER_FETCH_SHIFT_CTRL_CH1_EXPAND_FORMAT 8
+#define BM_PXP_DITHER_FETCH_SHIFT_CTRL_CH1_EXPAND_FORMAT 0x00000700
+#define BF_PXP_DITHER_FETCH_SHIFT_CTRL_CH1_EXPAND_FORMAT(v) \
+ (((v) << 8) & BM_PXP_DITHER_FETCH_SHIFT_CTRL_CH1_EXPAND_FORMAT)
+#define BV_PXP_DITHER_FETCH_SHIFT_CTRL_CH1_EXPAND_FORMAT__0 0x0
+#define BV_PXP_DITHER_FETCH_SHIFT_CTRL_CH1_EXPAND_FORMAT__1 0x1
+#define BV_PXP_DITHER_FETCH_SHIFT_CTRL_CH1_EXPAND_FORMAT__2 0x2
+#define BV_PXP_DITHER_FETCH_SHIFT_CTRL_CH1_EXPAND_FORMAT__3 0x3
+#define BV_PXP_DITHER_FETCH_SHIFT_CTRL_CH1_EXPAND_FORMAT__4 0x4
+#define BV_PXP_DITHER_FETCH_SHIFT_CTRL_CH1_EXPAND_FORMAT__5 0x5
+#define BV_PXP_DITHER_FETCH_SHIFT_CTRL_CH1_EXPAND_FORMAT__6 0x6
+#define BV_PXP_DITHER_FETCH_SHIFT_CTRL_CH1_EXPAND_FORMAT__7 0x7
+#define BP_PXP_DITHER_FETCH_SHIFT_CTRL_CH1_RSVD1 2
+#define BM_PXP_DITHER_FETCH_SHIFT_CTRL_CH1_RSVD1 0x000000FC
+#define BF_PXP_DITHER_FETCH_SHIFT_CTRL_CH1_RSVD1(v) \
+ (((v) << 2) & BM_PXP_DITHER_FETCH_SHIFT_CTRL_CH1_RSVD1)
+#define BP_PXP_DITHER_FETCH_SHIFT_CTRL_CH1_INPUT_ACTIVE_BPP 0
+#define BM_PXP_DITHER_FETCH_SHIFT_CTRL_CH1_INPUT_ACTIVE_BPP 0x00000003
+#define BF_PXP_DITHER_FETCH_SHIFT_CTRL_CH1_INPUT_ACTIVE_BPP(v) \
+ (((v) << 0) & BM_PXP_DITHER_FETCH_SHIFT_CTRL_CH1_INPUT_ACTIVE_BPP)
+#define BV_PXP_DITHER_FETCH_SHIFT_CTRL_CH1_INPUT_ACTIVE_BPP__0 0x0
+#define BV_PXP_DITHER_FETCH_SHIFT_CTRL_CH1_INPUT_ACTIVE_BPP__1 0x1
+#define BV_PXP_DITHER_FETCH_SHIFT_CTRL_CH1_INPUT_ACTIVE_BPP__2 0x2
+#define BV_PXP_DITHER_FETCH_SHIFT_CTRL_CH1_INPUT_ACTIVE_BPP__3 0x3
+
+#define HW_PXP_DITHER_FETCH_SHIFT_OFFSET_CH0 (0x00000940)
+#define HW_PXP_DITHER_FETCH_SHIFT_OFFSET_CH0_SET (0x00000944)
+#define HW_PXP_DITHER_FETCH_SHIFT_OFFSET_CH0_CLR (0x00000948)
+#define HW_PXP_DITHER_FETCH_SHIFT_OFFSET_CH0_TOG (0x0000094c)
+
+#define BP_PXP_DITHER_FETCH_SHIFT_OFFSET_CH0_RSVD0 29
+#define BM_PXP_DITHER_FETCH_SHIFT_OFFSET_CH0_RSVD0 0xE0000000
+#define BF_PXP_DITHER_FETCH_SHIFT_OFFSET_CH0_RSVD0(v) \
+ (((v) << 29) & BM_PXP_DITHER_FETCH_SHIFT_OFFSET_CH0_RSVD0)
+#define BP_PXP_DITHER_FETCH_SHIFT_OFFSET_CH0_OFFSET3 24
+#define BM_PXP_DITHER_FETCH_SHIFT_OFFSET_CH0_OFFSET3 0x1F000000
+#define BF_PXP_DITHER_FETCH_SHIFT_OFFSET_CH0_OFFSET3(v) \
+ (((v) << 24) & BM_PXP_DITHER_FETCH_SHIFT_OFFSET_CH0_OFFSET3)
+#define BP_PXP_DITHER_FETCH_SHIFT_OFFSET_CH0_RSVD1 21
+#define BM_PXP_DITHER_FETCH_SHIFT_OFFSET_CH0_RSVD1 0x00E00000
+#define BF_PXP_DITHER_FETCH_SHIFT_OFFSET_CH0_RSVD1(v) \
+ (((v) << 21) & BM_PXP_DITHER_FETCH_SHIFT_OFFSET_CH0_RSVD1)
+#define BP_PXP_DITHER_FETCH_SHIFT_OFFSET_CH0_OFFSET2 16
+#define BM_PXP_DITHER_FETCH_SHIFT_OFFSET_CH0_OFFSET2 0x001F0000
+#define BF_PXP_DITHER_FETCH_SHIFT_OFFSET_CH0_OFFSET2(v) \
+ (((v) << 16) & BM_PXP_DITHER_FETCH_SHIFT_OFFSET_CH0_OFFSET2)
+#define BP_PXP_DITHER_FETCH_SHIFT_OFFSET_CH0_RSVD2 13
+#define BM_PXP_DITHER_FETCH_SHIFT_OFFSET_CH0_RSVD2 0x0000E000
+#define BF_PXP_DITHER_FETCH_SHIFT_OFFSET_CH0_RSVD2(v) \
+ (((v) << 13) & BM_PXP_DITHER_FETCH_SHIFT_OFFSET_CH0_RSVD2)
+#define BP_PXP_DITHER_FETCH_SHIFT_OFFSET_CH0_OFFSET1 8
+#define BM_PXP_DITHER_FETCH_SHIFT_OFFSET_CH0_OFFSET1 0x00001F00
+#define BF_PXP_DITHER_FETCH_SHIFT_OFFSET_CH0_OFFSET1(v) \
+ (((v) << 8) & BM_PXP_DITHER_FETCH_SHIFT_OFFSET_CH0_OFFSET1)
+#define BP_PXP_DITHER_FETCH_SHIFT_OFFSET_CH0_RSVD3 5
+#define BM_PXP_DITHER_FETCH_SHIFT_OFFSET_CH0_RSVD3 0x000000E0
+#define BF_PXP_DITHER_FETCH_SHIFT_OFFSET_CH0_RSVD3(v) \
+ (((v) << 5) & BM_PXP_DITHER_FETCH_SHIFT_OFFSET_CH0_RSVD3)
+#define BP_PXP_DITHER_FETCH_SHIFT_OFFSET_CH0_OFFSET0 0
+#define BM_PXP_DITHER_FETCH_SHIFT_OFFSET_CH0_OFFSET0 0x0000001F
+#define BF_PXP_DITHER_FETCH_SHIFT_OFFSET_CH0_OFFSET0(v) \
+ (((v) << 0) & BM_PXP_DITHER_FETCH_SHIFT_OFFSET_CH0_OFFSET0)
+
+#define HW_PXP_DITHER_FETCH_SHIFT_OFFSET_CH1 (0x00000950)
+#define HW_PXP_DITHER_FETCH_SHIFT_OFFSET_CH1_SET (0x00000954)
+#define HW_PXP_DITHER_FETCH_SHIFT_OFFSET_CH1_CLR (0x00000958)
+#define HW_PXP_DITHER_FETCH_SHIFT_OFFSET_CH1_TOG (0x0000095c)
+
+#define BP_PXP_DITHER_FETCH_SHIFT_OFFSET_CH1_RSVD0 29
+#define BM_PXP_DITHER_FETCH_SHIFT_OFFSET_CH1_RSVD0 0xE0000000
+#define BF_PXP_DITHER_FETCH_SHIFT_OFFSET_CH1_RSVD0(v) \
+ (((v) << 29) & BM_PXP_DITHER_FETCH_SHIFT_OFFSET_CH1_RSVD0)
+#define BP_PXP_DITHER_FETCH_SHIFT_OFFSET_CH1_OFFSET3 24
+#define BM_PXP_DITHER_FETCH_SHIFT_OFFSET_CH1_OFFSET3 0x1F000000
+#define BF_PXP_DITHER_FETCH_SHIFT_OFFSET_CH1_OFFSET3(v) \
+ (((v) << 24) & BM_PXP_DITHER_FETCH_SHIFT_OFFSET_CH1_OFFSET3)
+#define BP_PXP_DITHER_FETCH_SHIFT_OFFSET_CH1_RSVD1 21
+#define BM_PXP_DITHER_FETCH_SHIFT_OFFSET_CH1_RSVD1 0x00E00000
+#define BF_PXP_DITHER_FETCH_SHIFT_OFFSET_CH1_RSVD1(v) \
+ (((v) << 21) & BM_PXP_DITHER_FETCH_SHIFT_OFFSET_CH1_RSVD1)
+#define BP_PXP_DITHER_FETCH_SHIFT_OFFSET_CH1_OFFSET2 16
+#define BM_PXP_DITHER_FETCH_SHIFT_OFFSET_CH1_OFFSET2 0x001F0000
+#define BF_PXP_DITHER_FETCH_SHIFT_OFFSET_CH1_OFFSET2(v) \
+ (((v) << 16) & BM_PXP_DITHER_FETCH_SHIFT_OFFSET_CH1_OFFSET2)
+#define BP_PXP_DITHER_FETCH_SHIFT_OFFSET_CH1_RSVD2 13
+#define BM_PXP_DITHER_FETCH_SHIFT_OFFSET_CH1_RSVD2 0x0000E000
+#define BF_PXP_DITHER_FETCH_SHIFT_OFFSET_CH1_RSVD2(v) \
+ (((v) << 13) & BM_PXP_DITHER_FETCH_SHIFT_OFFSET_CH1_RSVD2)
+#define BP_PXP_DITHER_FETCH_SHIFT_OFFSET_CH1_OFFSET1 8
+#define BM_PXP_DITHER_FETCH_SHIFT_OFFSET_CH1_OFFSET1 0x00001F00
+#define BF_PXP_DITHER_FETCH_SHIFT_OFFSET_CH1_OFFSET1(v) \
+ (((v) << 8) & BM_PXP_DITHER_FETCH_SHIFT_OFFSET_CH1_OFFSET1)
+#define BP_PXP_DITHER_FETCH_SHIFT_OFFSET_CH1_RSVD3 5
+#define BM_PXP_DITHER_FETCH_SHIFT_OFFSET_CH1_RSVD3 0x000000E0
+#define BF_PXP_DITHER_FETCH_SHIFT_OFFSET_CH1_RSVD3(v) \
+ (((v) << 5) & BM_PXP_DITHER_FETCH_SHIFT_OFFSET_CH1_RSVD3)
+#define BP_PXP_DITHER_FETCH_SHIFT_OFFSET_CH1_OFFSET0 0
+#define BM_PXP_DITHER_FETCH_SHIFT_OFFSET_CH1_OFFSET0 0x0000001F
+#define BF_PXP_DITHER_FETCH_SHIFT_OFFSET_CH1_OFFSET0(v) \
+ (((v) << 0) & BM_PXP_DITHER_FETCH_SHIFT_OFFSET_CH1_OFFSET0)
+
+#define HW_PXP_DITHER_FETCH_SHIFT_WIDTH_CH0 (0x00000960)
+#define HW_PXP_DITHER_FETCH_SHIFT_WIDTH_CH0_SET (0x00000964)
+#define HW_PXP_DITHER_FETCH_SHIFT_WIDTH_CH0_CLR (0x00000968)
+#define HW_PXP_DITHER_FETCH_SHIFT_WIDTH_CH0_TOG (0x0000096c)
+
+#define BP_PXP_DITHER_FETCH_SHIFT_WIDTH_CH0_RSVD0 16
+#define BM_PXP_DITHER_FETCH_SHIFT_WIDTH_CH0_RSVD0 0xFFFF0000
+#define BF_PXP_DITHER_FETCH_SHIFT_WIDTH_CH0_RSVD0(v) \
+ (((v) << 16) & BM_PXP_DITHER_FETCH_SHIFT_WIDTH_CH0_RSVD0)
+#define BP_PXP_DITHER_FETCH_SHIFT_WIDTH_CH0_WIDTH3 12
+#define BM_PXP_DITHER_FETCH_SHIFT_WIDTH_CH0_WIDTH3 0x0000F000
+#define BF_PXP_DITHER_FETCH_SHIFT_WIDTH_CH0_WIDTH3(v) \
+ (((v) << 12) & BM_PXP_DITHER_FETCH_SHIFT_WIDTH_CH0_WIDTH3)
+#define BP_PXP_DITHER_FETCH_SHIFT_WIDTH_CH0_WIDTH2 8
+#define BM_PXP_DITHER_FETCH_SHIFT_WIDTH_CH0_WIDTH2 0x00000F00
+#define BF_PXP_DITHER_FETCH_SHIFT_WIDTH_CH0_WIDTH2(v) \
+ (((v) << 8) & BM_PXP_DITHER_FETCH_SHIFT_WIDTH_CH0_WIDTH2)
+#define BP_PXP_DITHER_FETCH_SHIFT_WIDTH_CH0_WIDTH1 4
+#define BM_PXP_DITHER_FETCH_SHIFT_WIDTH_CH0_WIDTH1 0x000000F0
+#define BF_PXP_DITHER_FETCH_SHIFT_WIDTH_CH0_WIDTH1(v) \
+ (((v) << 4) & BM_PXP_DITHER_FETCH_SHIFT_WIDTH_CH0_WIDTH1)
+#define BP_PXP_DITHER_FETCH_SHIFT_WIDTH_CH0_WIDTH0 0
+#define BM_PXP_DITHER_FETCH_SHIFT_WIDTH_CH0_WIDTH0 0x0000000F
+#define BF_PXP_DITHER_FETCH_SHIFT_WIDTH_CH0_WIDTH0(v) \
+ (((v) << 0) & BM_PXP_DITHER_FETCH_SHIFT_WIDTH_CH0_WIDTH0)
+
+#define HW_PXP_DITHER_FETCH_SHIFT_WIDTH_CH1 (0x00000970)
+#define HW_PXP_DITHER_FETCH_SHIFT_WIDTH_CH1_SET (0x00000974)
+#define HW_PXP_DITHER_FETCH_SHIFT_WIDTH_CH1_CLR (0x00000978)
+#define HW_PXP_DITHER_FETCH_SHIFT_WIDTH_CH1_TOG (0x0000097c)
+
+#define BP_PXP_DITHER_FETCH_SHIFT_WIDTH_CH1_RSVD0 16
+#define BM_PXP_DITHER_FETCH_SHIFT_WIDTH_CH1_RSVD0 0xFFFF0000
+#define BF_PXP_DITHER_FETCH_SHIFT_WIDTH_CH1_RSVD0(v) \
+ (((v) << 16) & BM_PXP_DITHER_FETCH_SHIFT_WIDTH_CH1_RSVD0)
+#define BP_PXP_DITHER_FETCH_SHIFT_WIDTH_CH1_WIDTH3 12
+#define BM_PXP_DITHER_FETCH_SHIFT_WIDTH_CH1_WIDTH3 0x0000F000
+#define BF_PXP_DITHER_FETCH_SHIFT_WIDTH_CH1_WIDTH3(v) \
+ (((v) << 12) & BM_PXP_DITHER_FETCH_SHIFT_WIDTH_CH1_WIDTH3)
+#define BP_PXP_DITHER_FETCH_SHIFT_WIDTH_CH1_WIDTH2 8
+#define BM_PXP_DITHER_FETCH_SHIFT_WIDTH_CH1_WIDTH2 0x00000F00
+#define BF_PXP_DITHER_FETCH_SHIFT_WIDTH_CH1_WIDTH2(v) \
+ (((v) << 8) & BM_PXP_DITHER_FETCH_SHIFT_WIDTH_CH1_WIDTH2)
+#define BP_PXP_DITHER_FETCH_SHIFT_WIDTH_CH1_WIDTH1 4
+#define BM_PXP_DITHER_FETCH_SHIFT_WIDTH_CH1_WIDTH1 0x000000F0
+#define BF_PXP_DITHER_FETCH_SHIFT_WIDTH_CH1_WIDTH1(v) \
+ (((v) << 4) & BM_PXP_DITHER_FETCH_SHIFT_WIDTH_CH1_WIDTH1)
+#define BP_PXP_DITHER_FETCH_SHIFT_WIDTH_CH1_WIDTH0 0
+#define BM_PXP_DITHER_FETCH_SHIFT_WIDTH_CH1_WIDTH0 0x0000000F
+#define BF_PXP_DITHER_FETCH_SHIFT_WIDTH_CH1_WIDTH0(v) \
+ (((v) << 0) & BM_PXP_DITHER_FETCH_SHIFT_WIDTH_CH1_WIDTH0)
+
+#define HW_PXP_DITHER_FETCH_ADDR_0_CH0 (0x00000980)
+
+#define BP_PXP_DITHER_FETCH_ADDR_0_CH0_INPUT_BASE_ADDR0 0
+#define BM_PXP_DITHER_FETCH_ADDR_0_CH0_INPUT_BASE_ADDR0 0xFFFFFFFF
+#define BF_PXP_DITHER_FETCH_ADDR_0_CH0_INPUT_BASE_ADDR0(v) (v)
+
+#define HW_PXP_DITHER_FETCH_ADDR_1_CH0 (0x00000990)
+
+#define BP_PXP_DITHER_FETCH_ADDR_1_CH0_INPUT_BASE_ADDR1 0
+#define BM_PXP_DITHER_FETCH_ADDR_1_CH0_INPUT_BASE_ADDR1 0xFFFFFFFF
+#define BF_PXP_DITHER_FETCH_ADDR_1_CH0_INPUT_BASE_ADDR1(v) (v)
+
+#define HW_PXP_DITHER_FETCH_ADDR_0_CH1 (0x000009a0)
+
+#define BP_PXP_DITHER_FETCH_ADDR_0_CH1_INPUT_BASE_ADDR0 0
+#define BM_PXP_DITHER_FETCH_ADDR_0_CH1_INPUT_BASE_ADDR0 0xFFFFFFFF
+#define BF_PXP_DITHER_FETCH_ADDR_0_CH1_INPUT_BASE_ADDR0(v) (v)
+
+#define HW_PXP_DITHER_FETCH_ADDR_1_CH1 (0x000009b0)
+
+#define BP_PXP_DITHER_FETCH_ADDR_1_CH1_INPUT_BASE_ADDR1 0
+#define BM_PXP_DITHER_FETCH_ADDR_1_CH1_INPUT_BASE_ADDR1 0xFFFFFFFF
+#define BF_PXP_DITHER_FETCH_ADDR_1_CH1_INPUT_BASE_ADDR1(v) (v)
+
+#define HW_PXP_DITHER_STORE_CTRL_CH0 (0x000009c0)
+#define HW_PXP_DITHER_STORE_CTRL_CH0_SET (0x000009c4)
+#define HW_PXP_DITHER_STORE_CTRL_CH0_CLR (0x000009c8)
+#define HW_PXP_DITHER_STORE_CTRL_CH0_TOG (0x000009cc)
+
+#define BM_PXP_DITHER_STORE_CTRL_CH0_ARBIT_EN 0x80000000
+#define BF_PXP_DITHER_STORE_CTRL_CH0_ARBIT_EN(v) \
+ (((v) << 31) & BM_PXP_DITHER_STORE_CTRL_CH0_ARBIT_EN)
+#define BV_PXP_DITHER_STORE_CTRL_CH0_ARBIT_EN__0 0x0
+#define BV_PXP_DITHER_STORE_CTRL_CH0_ARBIT_EN__1 0x1
+#define BP_PXP_DITHER_STORE_CTRL_CH0_RSVD0 25
+#define BM_PXP_DITHER_STORE_CTRL_CH0_RSVD0 0x7E000000
+#define BF_PXP_DITHER_STORE_CTRL_CH0_RSVD0(v) \
+ (((v) << 25) & BM_PXP_DITHER_STORE_CTRL_CH0_RSVD0)
+#define BM_PXP_DITHER_STORE_CTRL_CH0_COMBINE_2CHANNEL 0x01000000
+#define BF_PXP_DITHER_STORE_CTRL_CH0_COMBINE_2CHANNEL(v) \
+ (((v) << 24) & BM_PXP_DITHER_STORE_CTRL_CH0_COMBINE_2CHANNEL)
+#define BV_PXP_DITHER_STORE_CTRL_CH0_COMBINE_2CHANNEL__0 0x0
+#define BV_PXP_DITHER_STORE_CTRL_CH0_COMBINE_2CHANNEL__1 0x1
+#define BP_PXP_DITHER_STORE_CTRL_CH0_RSVD1 18
+#define BM_PXP_DITHER_STORE_CTRL_CH0_RSVD1 0x00FC0000
+#define BF_PXP_DITHER_STORE_CTRL_CH0_RSVD1(v) \
+ (((v) << 18) & BM_PXP_DITHER_STORE_CTRL_CH0_RSVD1)
+#define BP_PXP_DITHER_STORE_CTRL_CH0_WR_NUM_BYTES 16
+#define BM_PXP_DITHER_STORE_CTRL_CH0_WR_NUM_BYTES 0x00030000
+#define BF_PXP_DITHER_STORE_CTRL_CH0_WR_NUM_BYTES(v) \
+ (((v) << 16) & BM_PXP_DITHER_STORE_CTRL_CH0_WR_NUM_BYTES)
+#define BV_PXP_DITHER_STORE_CTRL_CH0_WR_NUM_BYTES__8_bytes 0x0
+#define BV_PXP_DITHER_STORE_CTRL_CH0_WR_NUM_BYTES__16_bytes 0x1
+#define BV_PXP_DITHER_STORE_CTRL_CH0_WR_NUM_BYTES__32_bytes 0x2
+#define BV_PXP_DITHER_STORE_CTRL_CH0_WR_NUM_BYTES__64_bytes 0x3
+#define BP_PXP_DITHER_STORE_CTRL_CH0_RSVD2 12
+#define BM_PXP_DITHER_STORE_CTRL_CH0_RSVD2 0x0000F000
+#define BF_PXP_DITHER_STORE_CTRL_CH0_RSVD2(v) \
+ (((v) << 12) & BM_PXP_DITHER_STORE_CTRL_CH0_RSVD2)
+#define BM_PXP_DITHER_STORE_CTRL_CH0_FILL_DATA_EN 0x00000800
+#define BF_PXP_DITHER_STORE_CTRL_CH0_FILL_DATA_EN(v) \
+ (((v) << 11) & BM_PXP_DITHER_STORE_CTRL_CH0_FILL_DATA_EN)
+#define BV_PXP_DITHER_STORE_CTRL_CH0_FILL_DATA_EN__0 0x0
+#define BV_PXP_DITHER_STORE_CTRL_CH0_FILL_DATA_EN__1 0x1
+#define BM_PXP_DITHER_STORE_CTRL_CH0_PACK_IN_SEL 0x00000400
+#define BF_PXP_DITHER_STORE_CTRL_CH0_PACK_IN_SEL(v) \
+ (((v) << 10) & BM_PXP_DITHER_STORE_CTRL_CH0_PACK_IN_SEL)
+#define BV_PXP_DITHER_STORE_CTRL_CH0_PACK_IN_SEL__0 0x0
+#define BV_PXP_DITHER_STORE_CTRL_CH0_PACK_IN_SEL__1 0x1
+#define BM_PXP_DITHER_STORE_CTRL_CH0_STORE_MEMORY_EN 0x00000200
+#define BF_PXP_DITHER_STORE_CTRL_CH0_STORE_MEMORY_EN(v) \
+ (((v) << 9) & BM_PXP_DITHER_STORE_CTRL_CH0_STORE_MEMORY_EN)
+#define BV_PXP_DITHER_STORE_CTRL_CH0_STORE_MEMORY_EN__0 0x0
+#define BV_PXP_DITHER_STORE_CTRL_CH0_STORE_MEMORY_EN__1 0x1
+#define BM_PXP_DITHER_STORE_CTRL_CH0_STORE_BYPASS_EN 0x00000100
+#define BF_PXP_DITHER_STORE_CTRL_CH0_STORE_BYPASS_EN(v) \
+ (((v) << 8) & BM_PXP_DITHER_STORE_CTRL_CH0_STORE_BYPASS_EN)
+#define BV_PXP_DITHER_STORE_CTRL_CH0_STORE_BYPASS_EN__0 0x0
+#define BV_PXP_DITHER_STORE_CTRL_CH0_STORE_BYPASS_EN__1 0x1
+#define BM_PXP_DITHER_STORE_CTRL_CH0_RSVD3 0x00000080
+#define BF_PXP_DITHER_STORE_CTRL_CH0_RSVD3(v) \
+ (((v) << 7) & BM_PXP_DITHER_STORE_CTRL_CH0_RSVD3)
+#define BP_PXP_DITHER_STORE_CTRL_CH0_ARRAY_LINE_NUM 5
+#define BM_PXP_DITHER_STORE_CTRL_CH0_ARRAY_LINE_NUM 0x00000060
+#define BF_PXP_DITHER_STORE_CTRL_CH0_ARRAY_LINE_NUM(v) \
+ (((v) << 5) & BM_PXP_DITHER_STORE_CTRL_CH0_ARRAY_LINE_NUM)
+#define BV_PXP_DITHER_STORE_CTRL_CH0_ARRAY_LINE_NUM__0 0x0
+#define BV_PXP_DITHER_STORE_CTRL_CH0_ARRAY_LINE_NUM__1 0x1
+#define BV_PXP_DITHER_STORE_CTRL_CH0_ARRAY_LINE_NUM__2 0x2
+#define BV_PXP_DITHER_STORE_CTRL_CH0_ARRAY_LINE_NUM__3 0x3
+#define BM_PXP_DITHER_STORE_CTRL_CH0_ARRAY_EN 0x00000010
+#define BF_PXP_DITHER_STORE_CTRL_CH0_ARRAY_EN(v) \
+ (((v) << 4) & BM_PXP_DITHER_STORE_CTRL_CH0_ARRAY_EN)
+#define BV_PXP_DITHER_STORE_CTRL_CH0_ARRAY_EN__0 0x0
+#define BV_PXP_DITHER_STORE_CTRL_CH0_ARRAY_EN__1 0x1
+#define BM_PXP_DITHER_STORE_CTRL_CH0_HANDSHAKE_EN 0x00000008
+#define BF_PXP_DITHER_STORE_CTRL_CH0_HANDSHAKE_EN(v) \
+ (((v) << 3) & BM_PXP_DITHER_STORE_CTRL_CH0_HANDSHAKE_EN)
+#define BV_PXP_DITHER_STORE_CTRL_CH0_HANDSHAKE_EN__0 0x0
+#define BV_PXP_DITHER_STORE_CTRL_CH0_HANDSHAKE_EN__1 0x1
+#define BM_PXP_DITHER_STORE_CTRL_CH0_BLOCK_16 0x00000004
+#define BF_PXP_DITHER_STORE_CTRL_CH0_BLOCK_16(v) \
+ (((v) << 2) & BM_PXP_DITHER_STORE_CTRL_CH0_BLOCK_16)
+#define BV_PXP_DITHER_STORE_CTRL_CH0_BLOCK_16__8x8 0x0
+#define BV_PXP_DITHER_STORE_CTRL_CH0_BLOCK_16__16x16 0x1
+#define BM_PXP_DITHER_STORE_CTRL_CH0_BLOCK_EN 0x00000002
+#define BF_PXP_DITHER_STORE_CTRL_CH0_BLOCK_EN(v) \
+ (((v) << 1) & BM_PXP_DITHER_STORE_CTRL_CH0_BLOCK_EN)
+#define BV_PXP_DITHER_STORE_CTRL_CH0_BLOCK_EN__0 0x0
+#define BV_PXP_DITHER_STORE_CTRL_CH0_BLOCK_EN__1 0x1
+#define BM_PXP_DITHER_STORE_CTRL_CH0_CH_EN 0x00000001
+#define BF_PXP_DITHER_STORE_CTRL_CH0_CH_EN(v) \
+ (((v) << 0) & BM_PXP_DITHER_STORE_CTRL_CH0_CH_EN)
+#define BV_PXP_DITHER_STORE_CTRL_CH0_CH_EN__0 0x0
+#define BV_PXP_DITHER_STORE_CTRL_CH0_CH_EN__1 0x1
+
+#define HW_PXP_DITHER_STORE_CTRL_CH1 (0x000009d0)
+#define HW_PXP_DITHER_STORE_CTRL_CH1_SET (0x000009d4)
+#define HW_PXP_DITHER_STORE_CTRL_CH1_CLR (0x000009d8)
+#define HW_PXP_DITHER_STORE_CTRL_CH1_TOG (0x000009dc)
+
+#define BP_PXP_DITHER_STORE_CTRL_CH1_RSVD0 18
+#define BM_PXP_DITHER_STORE_CTRL_CH1_RSVD0 0xFFFC0000
+#define BF_PXP_DITHER_STORE_CTRL_CH1_RSVD0(v) \
+ (((v) << 18) & BM_PXP_DITHER_STORE_CTRL_CH1_RSVD0)
+#define BP_PXP_DITHER_STORE_CTRL_CH1_WR_NUM_BYTES 16
+#define BM_PXP_DITHER_STORE_CTRL_CH1_WR_NUM_BYTES 0x00030000
+#define BF_PXP_DITHER_STORE_CTRL_CH1_WR_NUM_BYTES(v) \
+ (((v) << 16) & BM_PXP_DITHER_STORE_CTRL_CH1_WR_NUM_BYTES)
+#define BV_PXP_DITHER_STORE_CTRL_CH1_WR_NUM_BYTES__8_bytes 0x0
+#define BV_PXP_DITHER_STORE_CTRL_CH1_WR_NUM_BYTES__16_bytes 0x1
+#define BV_PXP_DITHER_STORE_CTRL_CH1_WR_NUM_BYTES__32_bytes 0x2
+#define BV_PXP_DITHER_STORE_CTRL_CH1_WR_NUM_BYTES__64_bytes 0x3
+#define BP_PXP_DITHER_STORE_CTRL_CH1_RSVD1 11
+#define BM_PXP_DITHER_STORE_CTRL_CH1_RSVD1 0x0000F800
+#define BF_PXP_DITHER_STORE_CTRL_CH1_RSVD1(v) \
+ (((v) << 11) & BM_PXP_DITHER_STORE_CTRL_CH1_RSVD1)
+#define BM_PXP_DITHER_STORE_CTRL_CH1_PACK_IN_SEL 0x00000400
+#define BF_PXP_DITHER_STORE_CTRL_CH1_PACK_IN_SEL(v) \
+ (((v) << 10) & BM_PXP_DITHER_STORE_CTRL_CH1_PACK_IN_SEL)
+#define BV_PXP_DITHER_STORE_CTRL_CH1_PACK_IN_SEL__0 0x0
+#define BV_PXP_DITHER_STORE_CTRL_CH1_PACK_IN_SEL__1 0x1
+#define BM_PXP_DITHER_STORE_CTRL_CH1_STORE_MEMORY_EN 0x00000200
+#define BF_PXP_DITHER_STORE_CTRL_CH1_STORE_MEMORY_EN(v) \
+ (((v) << 9) & BM_PXP_DITHER_STORE_CTRL_CH1_STORE_MEMORY_EN)
+#define BV_PXP_DITHER_STORE_CTRL_CH1_STORE_MEMORY_EN__0 0x0
+#define BV_PXP_DITHER_STORE_CTRL_CH1_STORE_MEMORY_EN__1 0x1
+#define BM_PXP_DITHER_STORE_CTRL_CH1_STORE_BYPASS_EN 0x00000100
+#define BF_PXP_DITHER_STORE_CTRL_CH1_STORE_BYPASS_EN(v) \
+ (((v) << 8) & BM_PXP_DITHER_STORE_CTRL_CH1_STORE_BYPASS_EN)
+#define BV_PXP_DITHER_STORE_CTRL_CH1_STORE_BYPASS_EN__0 0x0
+#define BV_PXP_DITHER_STORE_CTRL_CH1_STORE_BYPASS_EN__1 0x1
+#define BM_PXP_DITHER_STORE_CTRL_CH1_RSVD3 0x00000080
+#define BF_PXP_DITHER_STORE_CTRL_CH1_RSVD3(v) \
+ (((v) << 7) & BM_PXP_DITHER_STORE_CTRL_CH1_RSVD3)
+#define BP_PXP_DITHER_STORE_CTRL_CH1_ARRAY_LINE_NUM 5
+#define BM_PXP_DITHER_STORE_CTRL_CH1_ARRAY_LINE_NUM 0x00000060
+#define BF_PXP_DITHER_STORE_CTRL_CH1_ARRAY_LINE_NUM(v) \
+ (((v) << 5) & BM_PXP_DITHER_STORE_CTRL_CH1_ARRAY_LINE_NUM)
+#define BV_PXP_DITHER_STORE_CTRL_CH1_ARRAY_LINE_NUM__0 0x0
+#define BV_PXP_DITHER_STORE_CTRL_CH1_ARRAY_LINE_NUM__1 0x1
+#define BV_PXP_DITHER_STORE_CTRL_CH1_ARRAY_LINE_NUM__2 0x2
+#define BV_PXP_DITHER_STORE_CTRL_CH1_ARRAY_LINE_NUM__3 0x3
+#define BM_PXP_DITHER_STORE_CTRL_CH1_ARRAY_EN 0x00000010
+#define BF_PXP_DITHER_STORE_CTRL_CH1_ARRAY_EN(v) \
+ (((v) << 4) & BM_PXP_DITHER_STORE_CTRL_CH1_ARRAY_EN)
+#define BV_PXP_DITHER_STORE_CTRL_CH1_ARRAY_EN__0 0x0
+#define BV_PXP_DITHER_STORE_CTRL_CH1_ARRAY_EN__1 0x1
+#define BM_PXP_DITHER_STORE_CTRL_CH1_HANDSHAKE_EN 0x00000008
+#define BF_PXP_DITHER_STORE_CTRL_CH1_HANDSHAKE_EN(v) \
+ (((v) << 3) & BM_PXP_DITHER_STORE_CTRL_CH1_HANDSHAKE_EN)
+#define BV_PXP_DITHER_STORE_CTRL_CH1_HANDSHAKE_EN__0 0x0
+#define BV_PXP_DITHER_STORE_CTRL_CH1_HANDSHAKE_EN__1 0x1
+#define BM_PXP_DITHER_STORE_CTRL_CH1_BLOCK_16 0x00000004
+#define BF_PXP_DITHER_STORE_CTRL_CH1_BLOCK_16(v) \
+ (((v) << 2) & BM_PXP_DITHER_STORE_CTRL_CH1_BLOCK_16)
+#define BV_PXP_DITHER_STORE_CTRL_CH1_BLOCK_16__8x8 0x0
+#define BV_PXP_DITHER_STORE_CTRL_CH1_BLOCK_16__16x16 0x1
+#define BM_PXP_DITHER_STORE_CTRL_CH1_BLOCK_EN 0x00000002
+#define BF_PXP_DITHER_STORE_CTRL_CH1_BLOCK_EN(v) \
+ (((v) << 1) & BM_PXP_DITHER_STORE_CTRL_CH1_BLOCK_EN)
+#define BV_PXP_DITHER_STORE_CTRL_CH1_BLOCK_EN__0 0x0
+#define BV_PXP_DITHER_STORE_CTRL_CH1_BLOCK_EN__1 0x1
+#define BM_PXP_DITHER_STORE_CTRL_CH1_CH_EN 0x00000001
+#define BF_PXP_DITHER_STORE_CTRL_CH1_CH_EN(v) \
+ (((v) << 0) & BM_PXP_DITHER_STORE_CTRL_CH1_CH_EN)
+#define BV_PXP_DITHER_STORE_CTRL_CH1_CH_EN__0 0x0
+#define BV_PXP_DITHER_STORE_CTRL_CH1_CH_EN__1 0x1
+
+#define HW_PXP_DITHER_STORE_STATUS_CH0 (0x000009e0)
+
+#define BP_PXP_DITHER_STORE_STATUS_CH0_STORE_BLOCK_Y 16
+#define BM_PXP_DITHER_STORE_STATUS_CH0_STORE_BLOCK_Y 0xFFFF0000
+#define BF_PXP_DITHER_STORE_STATUS_CH0_STORE_BLOCK_Y(v) \
+ (((v) << 16) & BM_PXP_DITHER_STORE_STATUS_CH0_STORE_BLOCK_Y)
+#define BP_PXP_DITHER_STORE_STATUS_CH0_STORE_BLOCK_X 0
+#define BM_PXP_DITHER_STORE_STATUS_CH0_STORE_BLOCK_X 0x0000FFFF
+#define BF_PXP_DITHER_STORE_STATUS_CH0_STORE_BLOCK_X(v) \
+ (((v) << 0) & BM_PXP_DITHER_STORE_STATUS_CH0_STORE_BLOCK_X)
+
+#define HW_PXP_DITHER_STORE_STATUS_CH1 (0x000009f0)
+
+#define BP_PXP_DITHER_STORE_STATUS_CH1_STORE_BLOCK_Y 16
+#define BM_PXP_DITHER_STORE_STATUS_CH1_STORE_BLOCK_Y 0xFFFF0000
+#define BF_PXP_DITHER_STORE_STATUS_CH1_STORE_BLOCK_Y(v) \
+ (((v) << 16) & BM_PXP_DITHER_STORE_STATUS_CH1_STORE_BLOCK_Y)
+#define BP_PXP_DITHER_STORE_STATUS_CH1_STORE_BLOCK_X 0
+#define BM_PXP_DITHER_STORE_STATUS_CH1_STORE_BLOCK_X 0x0000FFFF
+#define BF_PXP_DITHER_STORE_STATUS_CH1_STORE_BLOCK_X(v) \
+ (((v) << 0) & BM_PXP_DITHER_STORE_STATUS_CH1_STORE_BLOCK_X)
+
+#define HW_PXP_DITHER_STORE_SIZE_CH0 (0x00000a00)
+
+#define BP_PXP_DITHER_STORE_SIZE_CH0_OUT_HEIGHT 16
+#define BM_PXP_DITHER_STORE_SIZE_CH0_OUT_HEIGHT 0xFFFF0000
+#define BF_PXP_DITHER_STORE_SIZE_CH0_OUT_HEIGHT(v) \
+ (((v) << 16) & BM_PXP_DITHER_STORE_SIZE_CH0_OUT_HEIGHT)
+#define BP_PXP_DITHER_STORE_SIZE_CH0_OUT_WIDTH 0
+#define BM_PXP_DITHER_STORE_SIZE_CH0_OUT_WIDTH 0x0000FFFF
+#define BF_PXP_DITHER_STORE_SIZE_CH0_OUT_WIDTH(v) \
+ (((v) << 0) & BM_PXP_DITHER_STORE_SIZE_CH0_OUT_WIDTH)
+
+#define HW_PXP_DITHER_STORE_SIZE_CH1 (0x00000a10)
+
+#define BP_PXP_DITHER_STORE_SIZE_CH1_OUT_HEIGHT 16
+#define BM_PXP_DITHER_STORE_SIZE_CH1_OUT_HEIGHT 0xFFFF0000
+#define BF_PXP_DITHER_STORE_SIZE_CH1_OUT_HEIGHT(v) \
+ (((v) << 16) & BM_PXP_DITHER_STORE_SIZE_CH1_OUT_HEIGHT)
+#define BP_PXP_DITHER_STORE_SIZE_CH1_OUT_WIDTH 0
+#define BM_PXP_DITHER_STORE_SIZE_CH1_OUT_WIDTH 0x0000FFFF
+#define BF_PXP_DITHER_STORE_SIZE_CH1_OUT_WIDTH(v) \
+ (((v) << 0) & BM_PXP_DITHER_STORE_SIZE_CH1_OUT_WIDTH)
+
+#define HW_PXP_DITHER_STORE_PITCH (0x00000a20)
+
+#define BP_PXP_DITHER_STORE_PITCH_CH1_OUT_PITCH 16
+#define BM_PXP_DITHER_STORE_PITCH_CH1_OUT_PITCH 0xFFFF0000
+#define BF_PXP_DITHER_STORE_PITCH_CH1_OUT_PITCH(v) \
+ (((v) << 16) & BM_PXP_DITHER_STORE_PITCH_CH1_OUT_PITCH)
+#define BP_PXP_DITHER_STORE_PITCH_CH0_OUT_PITCH 0
+#define BM_PXP_DITHER_STORE_PITCH_CH0_OUT_PITCH 0x0000FFFF
+#define BF_PXP_DITHER_STORE_PITCH_CH0_OUT_PITCH(v) \
+ (((v) << 0) & BM_PXP_DITHER_STORE_PITCH_CH0_OUT_PITCH)
+
+#define HW_PXP_DITHER_STORE_SHIFT_CTRL_CH0 (0x00000a30)
+#define HW_PXP_DITHER_STORE_SHIFT_CTRL_CH0_SET (0x00000a34)
+#define HW_PXP_DITHER_STORE_SHIFT_CTRL_CH0_CLR (0x00000a38)
+#define HW_PXP_DITHER_STORE_SHIFT_CTRL_CH0_TOG (0x00000a3c)
+
+#define BP_PXP_DITHER_STORE_SHIFT_CTRL_CH0_RSVD0 8
+#define BM_PXP_DITHER_STORE_SHIFT_CTRL_CH0_RSVD0 0xFFFFFF00
+#define BF_PXP_DITHER_STORE_SHIFT_CTRL_CH0_RSVD0(v) \
+ (((v) << 8) & BM_PXP_DITHER_STORE_SHIFT_CTRL_CH0_RSVD0)
+#define BM_PXP_DITHER_STORE_SHIFT_CTRL_CH0_SHIFT_BYPASS 0x00000080
+#define BF_PXP_DITHER_STORE_SHIFT_CTRL_CH0_SHIFT_BYPASS(v) \
+ (((v) << 7) & BM_PXP_DITHER_STORE_SHIFT_CTRL_CH0_SHIFT_BYPASS)
+#define BV_PXP_DITHER_STORE_SHIFT_CTRL_CH0_SHIFT_BYPASS__0 0x0
+#define BV_PXP_DITHER_STORE_SHIFT_CTRL_CH0_SHIFT_BYPASS__1 0x1
+#define BM_PXP_DITHER_STORE_SHIFT_CTRL_CH0_RSVD1 0x00000040
+#define BF_PXP_DITHER_STORE_SHIFT_CTRL_CH0_RSVD1(v) \
+ (((v) << 6) & BM_PXP_DITHER_STORE_SHIFT_CTRL_CH0_RSVD1)
+#define BM_PXP_DITHER_STORE_SHIFT_CTRL_CH0_OUT_YUV422_2P_EN 0x00000020
+#define BF_PXP_DITHER_STORE_SHIFT_CTRL_CH0_OUT_YUV422_2P_EN(v) \
+ (((v) << 5) & BM_PXP_DITHER_STORE_SHIFT_CTRL_CH0_OUT_YUV422_2P_EN)
+#define BV_PXP_DITHER_STORE_SHIFT_CTRL_CH0_OUT_YUV422_2P_EN__0 0x0
+#define BV_PXP_DITHER_STORE_SHIFT_CTRL_CH0_OUT_YUV422_2P_EN__1 0x1
+#define BM_PXP_DITHER_STORE_SHIFT_CTRL_CH0_OUT_YUV422_1P_EN 0x00000010
+#define BF_PXP_DITHER_STORE_SHIFT_CTRL_CH0_OUT_YUV422_1P_EN(v) \
+ (((v) << 4) & BM_PXP_DITHER_STORE_SHIFT_CTRL_CH0_OUT_YUV422_1P_EN)
+#define BV_PXP_DITHER_STORE_SHIFT_CTRL_CH0_OUT_YUV422_1P_EN__0 0x0
+#define BV_PXP_DITHER_STORE_SHIFT_CTRL_CH0_OUT_YUV422_1P_EN__1 0x1
+#define BP_PXP_DITHER_STORE_SHIFT_CTRL_CH0_OUTPUT_ACTIVE_BPP 2
+#define BM_PXP_DITHER_STORE_SHIFT_CTRL_CH0_OUTPUT_ACTIVE_BPP 0x0000000C
+#define BF_PXP_DITHER_STORE_SHIFT_CTRL_CH0_OUTPUT_ACTIVE_BPP(v) \
+ (((v) << 2) & BM_PXP_DITHER_STORE_SHIFT_CTRL_CH0_OUTPUT_ACTIVE_BPP)
+#define BV_PXP_DITHER_STORE_SHIFT_CTRL_CH0_OUTPUT_ACTIVE_BPP__0 0x0
+#define BV_PXP_DITHER_STORE_SHIFT_CTRL_CH0_OUTPUT_ACTIVE_BPP__1 0x1
+#define BV_PXP_DITHER_STORE_SHIFT_CTRL_CH0_OUTPUT_ACTIVE_BPP__2 0x2
+#define BV_PXP_DITHER_STORE_SHIFT_CTRL_CH0_OUTPUT_ACTIVE_BPP__3 0x3
+#define BP_PXP_DITHER_STORE_SHIFT_CTRL_CH0_RSVD2 0
+#define BM_PXP_DITHER_STORE_SHIFT_CTRL_CH0_RSVD2 0x00000003
+#define BF_PXP_DITHER_STORE_SHIFT_CTRL_CH0_RSVD2(v) \
+ (((v) << 0) & BM_PXP_DITHER_STORE_SHIFT_CTRL_CH0_RSVD2)
+
+#define HW_PXP_DITHER_STORE_SHIFT_CTRL_CH1 (0x00000a40)
+#define HW_PXP_DITHER_STORE_SHIFT_CTRL_CH1_SET (0x00000a44)
+#define HW_PXP_DITHER_STORE_SHIFT_CTRL_CH1_CLR (0x00000a48)
+#define HW_PXP_DITHER_STORE_SHIFT_CTRL_CH1_TOG (0x00000a4c)
+
+#define BP_PXP_DITHER_STORE_SHIFT_CTRL_CH1_RSVD0 6
+#define BM_PXP_DITHER_STORE_SHIFT_CTRL_CH1_RSVD0 0xFFFFFFC0
+#define BF_PXP_DITHER_STORE_SHIFT_CTRL_CH1_RSVD0(v) \
+ (((v) << 6) & BM_PXP_DITHER_STORE_SHIFT_CTRL_CH1_RSVD0)
+#define BM_PXP_DITHER_STORE_SHIFT_CTRL_CH1_OUT_YUV422_2P_EN 0x00000020
+#define BF_PXP_DITHER_STORE_SHIFT_CTRL_CH1_OUT_YUV422_2P_EN(v) \
+ (((v) << 5) & BM_PXP_DITHER_STORE_SHIFT_CTRL_CH1_OUT_YUV422_2P_EN)
+#define BV_PXP_DITHER_STORE_SHIFT_CTRL_CH1_OUT_YUV422_2P_EN__0 0x0
+#define BV_PXP_DITHER_STORE_SHIFT_CTRL_CH1_OUT_YUV422_2P_EN__1 0x1
+#define BM_PXP_DITHER_STORE_SHIFT_CTRL_CH1_OUT_YUV422_1P_EN 0x00000010
+#define BF_PXP_DITHER_STORE_SHIFT_CTRL_CH1_OUT_YUV422_1P_EN(v) \
+ (((v) << 4) & BM_PXP_DITHER_STORE_SHIFT_CTRL_CH1_OUT_YUV422_1P_EN)
+#define BV_PXP_DITHER_STORE_SHIFT_CTRL_CH1_OUT_YUV422_1P_EN__0 0x0
+#define BV_PXP_DITHER_STORE_SHIFT_CTRL_CH1_OUT_YUV422_1P_EN__1 0x1
+#define BP_PXP_DITHER_STORE_SHIFT_CTRL_CH1_OUTPUT_ACTIVE_BPP 2
+#define BM_PXP_DITHER_STORE_SHIFT_CTRL_CH1_OUTPUT_ACTIVE_BPP 0x0000000C
+#define BF_PXP_DITHER_STORE_SHIFT_CTRL_CH1_OUTPUT_ACTIVE_BPP(v) \
+ (((v) << 2) & BM_PXP_DITHER_STORE_SHIFT_CTRL_CH1_OUTPUT_ACTIVE_BPP)
+#define BV_PXP_DITHER_STORE_SHIFT_CTRL_CH1_OUTPUT_ACTIVE_BPP__0 0x0
+#define BV_PXP_DITHER_STORE_SHIFT_CTRL_CH1_OUTPUT_ACTIVE_BPP__1 0x1
+#define BV_PXP_DITHER_STORE_SHIFT_CTRL_CH1_OUTPUT_ACTIVE_BPP__2 0x2
+#define BV_PXP_DITHER_STORE_SHIFT_CTRL_CH1_OUTPUT_ACTIVE_BPP__3 0x3
+#define BP_PXP_DITHER_STORE_SHIFT_CTRL_CH1_RSVD2 0
+#define BM_PXP_DITHER_STORE_SHIFT_CTRL_CH1_RSVD2 0x00000003
+#define BF_PXP_DITHER_STORE_SHIFT_CTRL_CH1_RSVD2(v) \
+ (((v) << 0) & BM_PXP_DITHER_STORE_SHIFT_CTRL_CH1_RSVD2)
+
+#define HW_PXP_DITHER_STORE_ADDR_0_CH0 (0x00000a90)
+
+#define BP_PXP_DITHER_STORE_ADDR_0_CH0_OUT_BASE_ADDR0 0
+#define BM_PXP_DITHER_STORE_ADDR_0_CH0_OUT_BASE_ADDR0 0xFFFFFFFF
+#define BF_PXP_DITHER_STORE_ADDR_0_CH0_OUT_BASE_ADDR0(v) (v)
+
+#define HW_PXP_DITHER_STORE_ADDR_1_CH0 (0x00000aa0)
+
+#define BP_PXP_DITHER_STORE_ADDR_1_CH0_OUT_BASE_ADDR1 0
+#define BM_PXP_DITHER_STORE_ADDR_1_CH0_OUT_BASE_ADDR1 0xFFFFFFFF
+#define BF_PXP_DITHER_STORE_ADDR_1_CH0_OUT_BASE_ADDR1(v) (v)
+
+#define HW_PXP_DITHER_STORE_FILL_DATA_CH0 (0x00000ab0)
+
+#define BP_PXP_DITHER_STORE_FILL_DATA_CH0_FILL_DATA_CH0 0
+#define BM_PXP_DITHER_STORE_FILL_DATA_CH0_FILL_DATA_CH0 0xFFFFFFFF
+#define BF_PXP_DITHER_STORE_FILL_DATA_CH0_FILL_DATA_CH0(v) (v)
+
+#define HW_PXP_DITHER_STORE_ADDR_0_CH1 (0x00000ac0)
+
+#define BP_PXP_DITHER_STORE_ADDR_0_CH1_OUT_BASE_ADDR0 0
+#define BM_PXP_DITHER_STORE_ADDR_0_CH1_OUT_BASE_ADDR0 0xFFFFFFFF
+#define BF_PXP_DITHER_STORE_ADDR_0_CH1_OUT_BASE_ADDR0(v) (v)
+
+#define HW_PXP_DITHER_STORE_ADDR_1_CH1 (0x00000ad0)
+
+#define BP_PXP_DITHER_STORE_ADDR_1_CH1_OUT_BASE_ADDR1 0
+#define BM_PXP_DITHER_STORE_ADDR_1_CH1_OUT_BASE_ADDR1 0xFFFFFFFF
+#define BF_PXP_DITHER_STORE_ADDR_1_CH1_OUT_BASE_ADDR1(v) (v)
+
+#define HW_PXP_DITHER_STORE_D_MASK0_H_CH0 (0x00000ae0)
+
+#define BP_PXP_DITHER_STORE_D_MASK0_H_CH0_D_MASK0_H_CH0 0
+#define BM_PXP_DITHER_STORE_D_MASK0_H_CH0_D_MASK0_H_CH0 0xFFFFFFFF
+#define BF_PXP_DITHER_STORE_D_MASK0_H_CH0_D_MASK0_H_CH0(v) (v)
+
+#define HW_PXP_DITHER_STORE_D_MASK0_L_CH0 (0x00000af0)
+
+#define BP_PXP_DITHER_STORE_D_MASK0_L_CH0_D_MASK0_L_CH0 0
+#define BM_PXP_DITHER_STORE_D_MASK0_L_CH0_D_MASK0_L_CH0 0xFFFFFFFF
+#define BF_PXP_DITHER_STORE_D_MASK0_L_CH0_D_MASK0_L_CH0(v) (v)
+
+#define HW_PXP_DITHER_STORE_D_MASK1_H_CH0 (0x00000b00)
+
+#define BP_PXP_DITHER_STORE_D_MASK1_H_CH0_D_MASK1_H_CH0 0
+#define BM_PXP_DITHER_STORE_D_MASK1_H_CH0_D_MASK1_H_CH0 0xFFFFFFFF
+#define BF_PXP_DITHER_STORE_D_MASK1_H_CH0_D_MASK1_H_CH0(v) (v)
+
+#define HW_PXP_DITHER_STORE_D_MASK1_L_CH0 (0x00000b10)
+
+#define BP_PXP_DITHER_STORE_D_MASK1_L_CH0_D_MASK1_L_CH0 0
+#define BM_PXP_DITHER_STORE_D_MASK1_L_CH0_D_MASK1_L_CH0 0xFFFFFFFF
+#define BF_PXP_DITHER_STORE_D_MASK1_L_CH0_D_MASK1_L_CH0(v) (v)
+
+#define HW_PXP_DITHER_STORE_D_MASK2_H_CH0 (0x00000b20)
+
+#define BP_PXP_DITHER_STORE_D_MASK2_H_CH0_D_MASK2_H_CH0 0
+#define BM_PXP_DITHER_STORE_D_MASK2_H_CH0_D_MASK2_H_CH0 0xFFFFFFFF
+#define BF_PXP_DITHER_STORE_D_MASK2_H_CH0_D_MASK2_H_CH0(v) (v)
+
+#define HW_PXP_DITHER_STORE_D_MASK2_L_CH0 (0x00000b30)
+
+#define BP_PXP_DITHER_STORE_D_MASK2_L_CH0_D_MASK2_L_CH0 0
+#define BM_PXP_DITHER_STORE_D_MASK2_L_CH0_D_MASK2_L_CH0 0xFFFFFFFF
+#define BF_PXP_DITHER_STORE_D_MASK2_L_CH0_D_MASK2_L_CH0(v) (v)
+
+#define HW_PXP_DITHER_STORE_D_MASK3_H_CH0 (0x00000b40)
+
+#define BP_PXP_DITHER_STORE_D_MASK3_H_CH0_D_MASK3_H_CH0 0
+#define BM_PXP_DITHER_STORE_D_MASK3_H_CH0_D_MASK3_H_CH0 0xFFFFFFFF
+#define BF_PXP_DITHER_STORE_D_MASK3_H_CH0_D_MASK3_H_CH0(v) (v)
+
+#define HW_PXP_DITHER_STORE_D_MASK3_L_CH0 (0x00000b50)
+
+#define BP_PXP_DITHER_STORE_D_MASK3_L_CH0_D_MASK3_L_CH0 0
+#define BM_PXP_DITHER_STORE_D_MASK3_L_CH0_D_MASK3_L_CH0 0xFFFFFFFF
+#define BF_PXP_DITHER_STORE_D_MASK3_L_CH0_D_MASK3_L_CH0(v) (v)
+
+#define HW_PXP_DITHER_STORE_D_MASK4_H_CH0 (0x00000b60)
+
+#define BP_PXP_DITHER_STORE_D_MASK4_H_CH0_D_MASK4_H_CH0 0
+#define BM_PXP_DITHER_STORE_D_MASK4_H_CH0_D_MASK4_H_CH0 0xFFFFFFFF
+#define BF_PXP_DITHER_STORE_D_MASK4_H_CH0_D_MASK4_H_CH0(v) (v)
+
+#define HW_PXP_DITHER_STORE_D_MASK4_L_CH0 (0x00000b70)
+
+#define BP_PXP_DITHER_STORE_D_MASK4_L_CH0_D_MASK4_L_CH0 0
+#define BM_PXP_DITHER_STORE_D_MASK4_L_CH0_D_MASK4_L_CH0 0xFFFFFFFF
+#define BF_PXP_DITHER_STORE_D_MASK4_L_CH0_D_MASK4_L_CH0(v) (v)
+
+#define HW_PXP_DITHER_STORE_D_MASK5_H_CH0 (0x00000b80)
+
+#define BP_PXP_DITHER_STORE_D_MASK5_H_CH0_D_MASK5_H_CH0 0
+#define BM_PXP_DITHER_STORE_D_MASK5_H_CH0_D_MASK5_H_CH0 0xFFFFFFFF
+#define BF_PXP_DITHER_STORE_D_MASK5_H_CH0_D_MASK5_H_CH0(v) (v)
+
+#define HW_PXP_DITHER_STORE_D_MASK5_L_CH0 (0x00000b90)
+
+#define BP_PXP_DITHER_STORE_D_MASK5_L_CH0_D_MASK5_L_CH0 0
+#define BM_PXP_DITHER_STORE_D_MASK5_L_CH0_D_MASK5_L_CH0 0xFFFFFFFF
+#define BF_PXP_DITHER_STORE_D_MASK5_L_CH0_D_MASK5_L_CH0(v) (v)
+
+#define HW_PXP_DITHER_STORE_D_MASK6_H_CH0 (0x00000ba0)
+
+#define BP_PXP_DITHER_STORE_D_MASK6_H_CH0_D_MASK6_H_CH0 0
+#define BM_PXP_DITHER_STORE_D_MASK6_H_CH0_D_MASK6_H_CH0 0xFFFFFFFF
+#define BF_PXP_DITHER_STORE_D_MASK6_H_CH0_D_MASK6_H_CH0(v) (v)
+
+#define HW_PXP_DITHER_STORE_D_MASK6_L_CH0 (0x00000bb0)
+
+#define BP_PXP_DITHER_STORE_D_MASK6_L_CH0_D_MASK6_L_CH0 0
+#define BM_PXP_DITHER_STORE_D_MASK6_L_CH0_D_MASK6_L_CH0 0xFFFFFFFF
+#define BF_PXP_DITHER_STORE_D_MASK6_L_CH0_D_MASK6_L_CH0(v) (v)
+
+#define HW_PXP_DITHER_STORE_D_MASK7_H_CH0 (0x00000bc0)
+
+#define BP_PXP_DITHER_STORE_D_MASK7_H_CH0_D_MASK7_H_CH0 0
+#define BM_PXP_DITHER_STORE_D_MASK7_H_CH0_D_MASK7_H_CH0 0xFFFFFFFF
+#define BF_PXP_DITHER_STORE_D_MASK7_H_CH0_D_MASK7_H_CH0(v) (v)
+
+#define HW_PXP_DITHER_STORE_D_MASK7_L_CH0 (0x00000bd0)
+
+#define BP_PXP_DITHER_STORE_D_MASK7_L_CH0_D_MASK7_L_CH0 0
+#define BM_PXP_DITHER_STORE_D_MASK7_L_CH0_D_MASK7_L_CH0 0xFFFFFFFF
+#define BF_PXP_DITHER_STORE_D_MASK7_L_CH0_D_MASK7_L_CH0(v) (v)
+
+#define HW_PXP_DITHER_STORE_D_SHIFT_L_CH0 (0x00000be0)
+
+#define BM_PXP_DITHER_STORE_D_SHIFT_L_CH0_D_SHIFT_FLAG3 0x80000000
+#define BF_PXP_DITHER_STORE_D_SHIFT_L_CH0_D_SHIFT_FLAG3(v) \
+ (((v) << 31) & BM_PXP_DITHER_STORE_D_SHIFT_L_CH0_D_SHIFT_FLAG3)
+#define BM_PXP_DITHER_STORE_D_SHIFT_L_CH0_RSVD0 0x40000000
+#define BF_PXP_DITHER_STORE_D_SHIFT_L_CH0_RSVD0(v) \
+ (((v) << 30) & BM_PXP_DITHER_STORE_D_SHIFT_L_CH0_RSVD0)
+#define BP_PXP_DITHER_STORE_D_SHIFT_L_CH0_D_SHIFT_WIDTH3 24
+#define BM_PXP_DITHER_STORE_D_SHIFT_L_CH0_D_SHIFT_WIDTH3 0x3F000000
+#define BF_PXP_DITHER_STORE_D_SHIFT_L_CH0_D_SHIFT_WIDTH3(v) \
+ (((v) << 24) & BM_PXP_DITHER_STORE_D_SHIFT_L_CH0_D_SHIFT_WIDTH3)
+#define BM_PXP_DITHER_STORE_D_SHIFT_L_CH0_D_SHIFT_FLAG2 0x00800000
+#define BF_PXP_DITHER_STORE_D_SHIFT_L_CH0_D_SHIFT_FLAG2(v) \
+ (((v) << 23) & BM_PXP_DITHER_STORE_D_SHIFT_L_CH0_D_SHIFT_FLAG2)
+#define BM_PXP_DITHER_STORE_D_SHIFT_L_CH0_RSVD1 0x00400000
+#define BF_PXP_DITHER_STORE_D_SHIFT_L_CH0_RSVD1(v) \
+ (((v) << 22) & BM_PXP_DITHER_STORE_D_SHIFT_L_CH0_RSVD1)
+#define BP_PXP_DITHER_STORE_D_SHIFT_L_CH0_D_SHIFT_WIDTH2 16
+#define BM_PXP_DITHER_STORE_D_SHIFT_L_CH0_D_SHIFT_WIDTH2 0x003F0000
+#define BF_PXP_DITHER_STORE_D_SHIFT_L_CH0_D_SHIFT_WIDTH2(v) \
+ (((v) << 16) & BM_PXP_DITHER_STORE_D_SHIFT_L_CH0_D_SHIFT_WIDTH2)
+#define BM_PXP_DITHER_STORE_D_SHIFT_L_CH0_D_SHIFT_FLAG1 0x00008000
+#define BF_PXP_DITHER_STORE_D_SHIFT_L_CH0_D_SHIFT_FLAG1(v) \
+ (((v) << 15) & BM_PXP_DITHER_STORE_D_SHIFT_L_CH0_D_SHIFT_FLAG1)
+#define BM_PXP_DITHER_STORE_D_SHIFT_L_CH0_RSVD2 0x00004000
+#define BF_PXP_DITHER_STORE_D_SHIFT_L_CH0_RSVD2(v) \
+ (((v) << 14) & BM_PXP_DITHER_STORE_D_SHIFT_L_CH0_RSVD2)
+#define BP_PXP_DITHER_STORE_D_SHIFT_L_CH0_D_SHIFT_WIDTH1 8
+#define BM_PXP_DITHER_STORE_D_SHIFT_L_CH0_D_SHIFT_WIDTH1 0x00003F00
+#define BF_PXP_DITHER_STORE_D_SHIFT_L_CH0_D_SHIFT_WIDTH1(v) \
+ (((v) << 8) & BM_PXP_DITHER_STORE_D_SHIFT_L_CH0_D_SHIFT_WIDTH1)
+#define BM_PXP_DITHER_STORE_D_SHIFT_L_CH0_D_SHIFT_FLAG0 0x00000080
+#define BF_PXP_DITHER_STORE_D_SHIFT_L_CH0_D_SHIFT_FLAG0(v) \
+ (((v) << 7) & BM_PXP_DITHER_STORE_D_SHIFT_L_CH0_D_SHIFT_FLAG0)
+#define BM_PXP_DITHER_STORE_D_SHIFT_L_CH0_RSVD3 0x00000040
+#define BF_PXP_DITHER_STORE_D_SHIFT_L_CH0_RSVD3(v) \
+ (((v) << 6) & BM_PXP_DITHER_STORE_D_SHIFT_L_CH0_RSVD3)
+#define BP_PXP_DITHER_STORE_D_SHIFT_L_CH0_D_SHIFT_WIDTH0 0
+#define BM_PXP_DITHER_STORE_D_SHIFT_L_CH0_D_SHIFT_WIDTH0 0x0000003F
+#define BF_PXP_DITHER_STORE_D_SHIFT_L_CH0_D_SHIFT_WIDTH0(v) \
+ (((v) << 0) & BM_PXP_DITHER_STORE_D_SHIFT_L_CH0_D_SHIFT_WIDTH0)
+
+#define HW_PXP_DITHER_STORE_D_SHIFT_H_CH0 (0x00000bf0)
+
+#define BM_PXP_DITHER_STORE_D_SHIFT_H_CH0_D_SHIFT_FLAG7 0x80000000
+#define BF_PXP_DITHER_STORE_D_SHIFT_H_CH0_D_SHIFT_FLAG7(v) \
+ (((v) << 31) & BM_PXP_DITHER_STORE_D_SHIFT_H_CH0_D_SHIFT_FLAG7)
+#define BM_PXP_DITHER_STORE_D_SHIFT_H_CH0_RSVD0 0x40000000
+#define BF_PXP_DITHER_STORE_D_SHIFT_H_CH0_RSVD0(v) \
+ (((v) << 30) & BM_PXP_DITHER_STORE_D_SHIFT_H_CH0_RSVD0)
+#define BP_PXP_DITHER_STORE_D_SHIFT_H_CH0_D_SHIFT_WIDTH7 24
+#define BM_PXP_DITHER_STORE_D_SHIFT_H_CH0_D_SHIFT_WIDTH7 0x3F000000
+#define BF_PXP_DITHER_STORE_D_SHIFT_H_CH0_D_SHIFT_WIDTH7(v) \
+ (((v) << 24) & BM_PXP_DITHER_STORE_D_SHIFT_H_CH0_D_SHIFT_WIDTH7)
+#define BM_PXP_DITHER_STORE_D_SHIFT_H_CH0_D_SHIFT_FLAG6 0x00800000
+#define BF_PXP_DITHER_STORE_D_SHIFT_H_CH0_D_SHIFT_FLAG6(v) \
+ (((v) << 23) & BM_PXP_DITHER_STORE_D_SHIFT_H_CH0_D_SHIFT_FLAG6)
+#define BM_PXP_DITHER_STORE_D_SHIFT_H_CH0_RSVD1 0x00400000
+#define BF_PXP_DITHER_STORE_D_SHIFT_H_CH0_RSVD1(v) \
+ (((v) << 22) & BM_PXP_DITHER_STORE_D_SHIFT_H_CH0_RSVD1)
+#define BP_PXP_DITHER_STORE_D_SHIFT_H_CH0_D_SHIFT_WIDTH6 16
+#define BM_PXP_DITHER_STORE_D_SHIFT_H_CH0_D_SHIFT_WIDTH6 0x003F0000
+#define BF_PXP_DITHER_STORE_D_SHIFT_H_CH0_D_SHIFT_WIDTH6(v) \
+ (((v) << 16) & BM_PXP_DITHER_STORE_D_SHIFT_H_CH0_D_SHIFT_WIDTH6)
+#define BM_PXP_DITHER_STORE_D_SHIFT_H_CH0_D_SHIFT_FLAG5 0x00008000
+#define BF_PXP_DITHER_STORE_D_SHIFT_H_CH0_D_SHIFT_FLAG5(v) \
+ (((v) << 15) & BM_PXP_DITHER_STORE_D_SHIFT_H_CH0_D_SHIFT_FLAG5)
+#define BM_PXP_DITHER_STORE_D_SHIFT_H_CH0_RSVD2 0x00004000
+#define BF_PXP_DITHER_STORE_D_SHIFT_H_CH0_RSVD2(v) \
+ (((v) << 14) & BM_PXP_DITHER_STORE_D_SHIFT_H_CH0_RSVD2)
+#define BP_PXP_DITHER_STORE_D_SHIFT_H_CH0_D_SHIFT_WIDTH5 8
+#define BM_PXP_DITHER_STORE_D_SHIFT_H_CH0_D_SHIFT_WIDTH5 0x00003F00
+#define BF_PXP_DITHER_STORE_D_SHIFT_H_CH0_D_SHIFT_WIDTH5(v) \
+ (((v) << 8) & BM_PXP_DITHER_STORE_D_SHIFT_H_CH0_D_SHIFT_WIDTH5)
+#define BM_PXP_DITHER_STORE_D_SHIFT_H_CH0_D_SHIFT_FLAG4 0x00000080
+#define BF_PXP_DITHER_STORE_D_SHIFT_H_CH0_D_SHIFT_FLAG4(v) \
+ (((v) << 7) & BM_PXP_DITHER_STORE_D_SHIFT_H_CH0_D_SHIFT_FLAG4)
+#define BM_PXP_DITHER_STORE_D_SHIFT_H_CH0_RSVD3 0x00000040
+#define BF_PXP_DITHER_STORE_D_SHIFT_H_CH0_RSVD3(v) \
+ (((v) << 6) & BM_PXP_DITHER_STORE_D_SHIFT_H_CH0_RSVD3)
+#define BP_PXP_DITHER_STORE_D_SHIFT_H_CH0_D_SHIFT_WIDTH4 0
+#define BM_PXP_DITHER_STORE_D_SHIFT_H_CH0_D_SHIFT_WIDTH4 0x0000003F
+#define BF_PXP_DITHER_STORE_D_SHIFT_H_CH0_D_SHIFT_WIDTH4(v) \
+ (((v) << 0) & BM_PXP_DITHER_STORE_D_SHIFT_H_CH0_D_SHIFT_WIDTH4)
+
+#define HW_PXP_DITHER_STORE_F_SHIFT_L_CH0 (0x00000c00)
+
+#define BM_PXP_DITHER_STORE_F_SHIFT_L_CH0_RSVD0 0x80000000
+#define BF_PXP_DITHER_STORE_F_SHIFT_L_CH0_RSVD0(v) \
+ (((v) << 31) & BM_PXP_DITHER_STORE_F_SHIFT_L_CH0_RSVD0)
+#define BM_PXP_DITHER_STORE_F_SHIFT_L_CH0_F_SHIFT_FLAG3 0x40000000
+#define BF_PXP_DITHER_STORE_F_SHIFT_L_CH0_F_SHIFT_FLAG3(v) \
+ (((v) << 30) & BM_PXP_DITHER_STORE_F_SHIFT_L_CH0_F_SHIFT_FLAG3)
+#define BP_PXP_DITHER_STORE_F_SHIFT_L_CH0_F_SHIFT_WIDTH3 24
+#define BM_PXP_DITHER_STORE_F_SHIFT_L_CH0_F_SHIFT_WIDTH3 0x3F000000
+#define BF_PXP_DITHER_STORE_F_SHIFT_L_CH0_F_SHIFT_WIDTH3(v) \
+ (((v) << 24) & BM_PXP_DITHER_STORE_F_SHIFT_L_CH0_F_SHIFT_WIDTH3)
+#define BM_PXP_DITHER_STORE_F_SHIFT_L_CH0_RSVD1 0x00800000
+#define BF_PXP_DITHER_STORE_F_SHIFT_L_CH0_RSVD1(v) \
+ (((v) << 23) & BM_PXP_DITHER_STORE_F_SHIFT_L_CH0_RSVD1)
+#define BM_PXP_DITHER_STORE_F_SHIFT_L_CH0_F_SHIFT_FLAG2 0x00400000
+#define BF_PXP_DITHER_STORE_F_SHIFT_L_CH0_F_SHIFT_FLAG2(v) \
+ (((v) << 22) & BM_PXP_DITHER_STORE_F_SHIFT_L_CH0_F_SHIFT_FLAG2)
+#define BP_PXP_DITHER_STORE_F_SHIFT_L_CH0_F_SHIFT_WIDTH2 16
+#define BM_PXP_DITHER_STORE_F_SHIFT_L_CH0_F_SHIFT_WIDTH2 0x003F0000
+#define BF_PXP_DITHER_STORE_F_SHIFT_L_CH0_F_SHIFT_WIDTH2(v) \
+ (((v) << 16) & BM_PXP_DITHER_STORE_F_SHIFT_L_CH0_F_SHIFT_WIDTH2)
+#define BM_PXP_DITHER_STORE_F_SHIFT_L_CH0_RSVD2 0x00008000
+#define BF_PXP_DITHER_STORE_F_SHIFT_L_CH0_RSVD2(v) \
+ (((v) << 15) & BM_PXP_DITHER_STORE_F_SHIFT_L_CH0_RSVD2)
+#define BM_PXP_DITHER_STORE_F_SHIFT_L_CH0_F_SHIFT_FLAG1 0x00004000
+#define BF_PXP_DITHER_STORE_F_SHIFT_L_CH0_F_SHIFT_FLAG1(v) \
+ (((v) << 14) & BM_PXP_DITHER_STORE_F_SHIFT_L_CH0_F_SHIFT_FLAG1)
+#define BP_PXP_DITHER_STORE_F_SHIFT_L_CH0_F_SHIFT_WIDTH1 8
+#define BM_PXP_DITHER_STORE_F_SHIFT_L_CH0_F_SHIFT_WIDTH1 0x00003F00
+#define BF_PXP_DITHER_STORE_F_SHIFT_L_CH0_F_SHIFT_WIDTH1(v) \
+ (((v) << 8) & BM_PXP_DITHER_STORE_F_SHIFT_L_CH0_F_SHIFT_WIDTH1)
+#define BM_PXP_DITHER_STORE_F_SHIFT_L_CH0_RSVD3 0x00000080
+#define BF_PXP_DITHER_STORE_F_SHIFT_L_CH0_RSVD3(v) \
+ (((v) << 7) & BM_PXP_DITHER_STORE_F_SHIFT_L_CH0_RSVD3)
+#define BM_PXP_DITHER_STORE_F_SHIFT_L_CH0_F_SHIFT_FLAG0 0x00000040
+#define BF_PXP_DITHER_STORE_F_SHIFT_L_CH0_F_SHIFT_FLAG0(v) \
+ (((v) << 6) & BM_PXP_DITHER_STORE_F_SHIFT_L_CH0_F_SHIFT_FLAG0)
+#define BP_PXP_DITHER_STORE_F_SHIFT_L_CH0_F_SHIFT_WIDTH0 0
+#define BM_PXP_DITHER_STORE_F_SHIFT_L_CH0_F_SHIFT_WIDTH0 0x0000003F
+#define BF_PXP_DITHER_STORE_F_SHIFT_L_CH0_F_SHIFT_WIDTH0(v) \
+ (((v) << 0) & BM_PXP_DITHER_STORE_F_SHIFT_L_CH0_F_SHIFT_WIDTH0)
+
+#define HW_PXP_DITHER_STORE_F_SHIFT_H_CH0 (0x00000c10)
+
+#define BM_PXP_DITHER_STORE_F_SHIFT_H_CH0_RSVD0 0x80000000
+#define BF_PXP_DITHER_STORE_F_SHIFT_H_CH0_RSVD0(v) \
+ (((v) << 31) & BM_PXP_DITHER_STORE_F_SHIFT_H_CH0_RSVD0)
+#define BM_PXP_DITHER_STORE_F_SHIFT_H_CH0_F_SHIFT_FLAG7 0x40000000
+#define BF_PXP_DITHER_STORE_F_SHIFT_H_CH0_F_SHIFT_FLAG7(v) \
+ (((v) << 30) & BM_PXP_DITHER_STORE_F_SHIFT_H_CH0_F_SHIFT_FLAG7)
+#define BP_PXP_DITHER_STORE_F_SHIFT_H_CH0_F_SHIFT_WIDTH7 24
+#define BM_PXP_DITHER_STORE_F_SHIFT_H_CH0_F_SHIFT_WIDTH7 0x3F000000
+#define BF_PXP_DITHER_STORE_F_SHIFT_H_CH0_F_SHIFT_WIDTH7(v) \
+ (((v) << 24) & BM_PXP_DITHER_STORE_F_SHIFT_H_CH0_F_SHIFT_WIDTH7)
+#define BM_PXP_DITHER_STORE_F_SHIFT_H_CH0_RSVD1 0x00800000
+#define BF_PXP_DITHER_STORE_F_SHIFT_H_CH0_RSVD1(v) \
+ (((v) << 23) & BM_PXP_DITHER_STORE_F_SHIFT_H_CH0_RSVD1)
+#define BM_PXP_DITHER_STORE_F_SHIFT_H_CH0_F_SHIFT_FLAG6 0x00400000
+#define BF_PXP_DITHER_STORE_F_SHIFT_H_CH0_F_SHIFT_FLAG6(v) \
+ (((v) << 22) & BM_PXP_DITHER_STORE_F_SHIFT_H_CH0_F_SHIFT_FLAG6)
+#define BP_PXP_DITHER_STORE_F_SHIFT_H_CH0_F_SHIFT_WIDTH6 16
+#define BM_PXP_DITHER_STORE_F_SHIFT_H_CH0_F_SHIFT_WIDTH6 0x003F0000
+#define BF_PXP_DITHER_STORE_F_SHIFT_H_CH0_F_SHIFT_WIDTH6(v) \
+ (((v) << 16) & BM_PXP_DITHER_STORE_F_SHIFT_H_CH0_F_SHIFT_WIDTH6)
+#define BM_PXP_DITHER_STORE_F_SHIFT_H_CH0_RSVD2 0x00008000
+#define BF_PXP_DITHER_STORE_F_SHIFT_H_CH0_RSVD2(v) \
+ (((v) << 15) & BM_PXP_DITHER_STORE_F_SHIFT_H_CH0_RSVD2)
+#define BM_PXP_DITHER_STORE_F_SHIFT_H_CH0_F_SHIFT_FLAG5 0x00004000
+#define BF_PXP_DITHER_STORE_F_SHIFT_H_CH0_F_SHIFT_FLAG5(v) \
+ (((v) << 14) & BM_PXP_DITHER_STORE_F_SHIFT_H_CH0_F_SHIFT_FLAG5)
+#define BP_PXP_DITHER_STORE_F_SHIFT_H_CH0_F_SHIFT_WIDTH5 8
+#define BM_PXP_DITHER_STORE_F_SHIFT_H_CH0_F_SHIFT_WIDTH5 0x00003F00
+#define BF_PXP_DITHER_STORE_F_SHIFT_H_CH0_F_SHIFT_WIDTH5(v) \
+ (((v) << 8) & BM_PXP_DITHER_STORE_F_SHIFT_H_CH0_F_SHIFT_WIDTH5)
+#define BM_PXP_DITHER_STORE_F_SHIFT_H_CH0_RSVD3 0x00000080
+#define BF_PXP_DITHER_STORE_F_SHIFT_H_CH0_RSVD3(v) \
+ (((v) << 7) & BM_PXP_DITHER_STORE_F_SHIFT_H_CH0_RSVD3)
+#define BM_PXP_DITHER_STORE_F_SHIFT_H_CH0_F_SHIFT_FLAG4 0x00000040
+#define BF_PXP_DITHER_STORE_F_SHIFT_H_CH0_F_SHIFT_FLAG4(v) \
+ (((v) << 6) & BM_PXP_DITHER_STORE_F_SHIFT_H_CH0_F_SHIFT_FLAG4)
+#define BP_PXP_DITHER_STORE_F_SHIFT_H_CH0_F_SHIFT_WIDTH4 0
+#define BM_PXP_DITHER_STORE_F_SHIFT_H_CH0_F_SHIFT_WIDTH4 0x0000003F
+#define BF_PXP_DITHER_STORE_F_SHIFT_H_CH0_F_SHIFT_WIDTH4(v) \
+ (((v) << 0) & BM_PXP_DITHER_STORE_F_SHIFT_H_CH0_F_SHIFT_WIDTH4)
+
+#define HW_PXP_DITHER_STORE_F_MASK_L_CH0 (0x00000c20)
+
+#define BP_PXP_DITHER_STORE_F_MASK_L_CH0_F_MASK3 24
+#define BM_PXP_DITHER_STORE_F_MASK_L_CH0_F_MASK3 0xFF000000
+#define BF_PXP_DITHER_STORE_F_MASK_L_CH0_F_MASK3(v) \
+ (((v) << 24) & BM_PXP_DITHER_STORE_F_MASK_L_CH0_F_MASK3)
+#define BP_PXP_DITHER_STORE_F_MASK_L_CH0_F_MASK2 16
+#define BM_PXP_DITHER_STORE_F_MASK_L_CH0_F_MASK2 0x00FF0000
+#define BF_PXP_DITHER_STORE_F_MASK_L_CH0_F_MASK2(v) \
+ (((v) << 16) & BM_PXP_DITHER_STORE_F_MASK_L_CH0_F_MASK2)
+#define BP_PXP_DITHER_STORE_F_MASK_L_CH0_F_MASK1 8
+#define BM_PXP_DITHER_STORE_F_MASK_L_CH0_F_MASK1 0x0000FF00
+#define BF_PXP_DITHER_STORE_F_MASK_L_CH0_F_MASK1(v) \
+ (((v) << 8) & BM_PXP_DITHER_STORE_F_MASK_L_CH0_F_MASK1)
+#define BP_PXP_DITHER_STORE_F_MASK_L_CH0_F_MASK0 0
+#define BM_PXP_DITHER_STORE_F_MASK_L_CH0_F_MASK0 0x000000FF
+#define BF_PXP_DITHER_STORE_F_MASK_L_CH0_F_MASK0(v) \
+ (((v) << 0) & BM_PXP_DITHER_STORE_F_MASK_L_CH0_F_MASK0)
+
+#define HW_PXP_DITHER_STORE_F_MASK_H_CH0 (0x00000c30)
+
+#define BP_PXP_DITHER_STORE_F_MASK_H_CH0_F_MASK7 24
+#define BM_PXP_DITHER_STORE_F_MASK_H_CH0_F_MASK7 0xFF000000
+#define BF_PXP_DITHER_STORE_F_MASK_H_CH0_F_MASK7(v) \
+ (((v) << 24) & BM_PXP_DITHER_STORE_F_MASK_H_CH0_F_MASK7)
+#define BP_PXP_DITHER_STORE_F_MASK_H_CH0_F_MASK6 16
+#define BM_PXP_DITHER_STORE_F_MASK_H_CH0_F_MASK6 0x00FF0000
+#define BF_PXP_DITHER_STORE_F_MASK_H_CH0_F_MASK6(v) \
+ (((v) << 16) & BM_PXP_DITHER_STORE_F_MASK_H_CH0_F_MASK6)
+#define BP_PXP_DITHER_STORE_F_MASK_H_CH0_F_MASK5 8
+#define BM_PXP_DITHER_STORE_F_MASK_H_CH0_F_MASK5 0x0000FF00
+#define BF_PXP_DITHER_STORE_F_MASK_H_CH0_F_MASK5(v) \
+ (((v) << 8) & BM_PXP_DITHER_STORE_F_MASK_H_CH0_F_MASK5)
+#define BP_PXP_DITHER_STORE_F_MASK_H_CH0_F_MASK4 0
+#define BM_PXP_DITHER_STORE_F_MASK_H_CH0_F_MASK4 0x000000FF
+#define BF_PXP_DITHER_STORE_F_MASK_H_CH0_F_MASK4(v) \
+ (((v) << 0) & BM_PXP_DITHER_STORE_F_MASK_H_CH0_F_MASK4)
+
+#define HW_PXP_WFA_FETCH_CTRL (0x00000c40)
+#define HW_PXP_WFA_FETCH_CTRL_SET (0x00000c44)
+#define HW_PXP_WFA_FETCH_CTRL_CLR (0x00000c48)
+#define HW_PXP_WFA_FETCH_CTRL_TOG (0x00000c4c)
+
+#define BM_PXP_WFA_FETCH_CTRL_BUF2_DONE_IRQ_EN 0x80000000
+#define BF_PXP_WFA_FETCH_CTRL_BUF2_DONE_IRQ_EN(v) \
+ (((v) << 31) & BM_PXP_WFA_FETCH_CTRL_BUF2_DONE_IRQ_EN)
+#define BM_PXP_WFA_FETCH_CTRL_BUF1_DONE_IRQ_EN 0x40000000
+#define BF_PXP_WFA_FETCH_CTRL_BUF1_DONE_IRQ_EN(v) \
+ (((v) << 30) & BM_PXP_WFA_FETCH_CTRL_BUF1_DONE_IRQ_EN)
+#define BM_PXP_WFA_FETCH_CTRL_BUF2_DONE_IRQ 0x20000000
+#define BF_PXP_WFA_FETCH_CTRL_BUF2_DONE_IRQ(v) \
+ (((v) << 29) & BM_PXP_WFA_FETCH_CTRL_BUF2_DONE_IRQ)
+#define BM_PXP_WFA_FETCH_CTRL_BUF1_DONE_IRQ 0x10000000
+#define BF_PXP_WFA_FETCH_CTRL_BUF1_DONE_IRQ(v) \
+ (((v) << 28) & BM_PXP_WFA_FETCH_CTRL_BUF1_DONE_IRQ)
+#define BP_PXP_WFA_FETCH_CTRL_RSVD0 24
+#define BM_PXP_WFA_FETCH_CTRL_RSVD0 0x0F000000
+#define BF_PXP_WFA_FETCH_CTRL_RSVD0(v) \
+ (((v) << 24) & BM_PXP_WFA_FETCH_CTRL_RSVD0)
+#define BP_PXP_WFA_FETCH_CTRL_BF2_LINE_MODE 22
+#define BM_PXP_WFA_FETCH_CTRL_BF2_LINE_MODE 0x00C00000
+#define BF_PXP_WFA_FETCH_CTRL_BF2_LINE_MODE(v) \
+ (((v) << 22) & BM_PXP_WFA_FETCH_CTRL_BF2_LINE_MODE)
+#define BV_PXP_WFA_FETCH_CTRL_BF2_LINE_MODE__0 0x0
+#define BV_PXP_WFA_FETCH_CTRL_BF2_LINE_MODE__1 0x1
+#define BV_PXP_WFA_FETCH_CTRL_BF2_LINE_MODE__2 0x2
+#define BV_PXP_WFA_FETCH_CTRL_BF2_LINE_MODE__3 0x3
+#define BP_PXP_WFA_FETCH_CTRL_BF2_BYTES_PP 20
+#define BM_PXP_WFA_FETCH_CTRL_BF2_BYTES_PP 0x00300000
+#define BF_PXP_WFA_FETCH_CTRL_BF2_BYTES_PP(v) \
+ (((v) << 20) & BM_PXP_WFA_FETCH_CTRL_BF2_BYTES_PP)
+#define BP_PXP_WFA_FETCH_CTRL_BF1_LINE_MODE 18
+#define BM_PXP_WFA_FETCH_CTRL_BF1_LINE_MODE 0x000C0000
+#define BF_PXP_WFA_FETCH_CTRL_BF1_LINE_MODE(v) \
+ (((v) << 18) & BM_PXP_WFA_FETCH_CTRL_BF1_LINE_MODE)
+#define BV_PXP_WFA_FETCH_CTRL_BF1_LINE_MODE__0 0x0
+#define BV_PXP_WFA_FETCH_CTRL_BF1_LINE_MODE__1 0x1
+#define BV_PXP_WFA_FETCH_CTRL_BF1_LINE_MODE__2 0x2
+#define BV_PXP_WFA_FETCH_CTRL_BF1_LINE_MODE__3 0x3
+#define BP_PXP_WFA_FETCH_CTRL_BF1_BYTES_PP 16
+#define BM_PXP_WFA_FETCH_CTRL_BF1_BYTES_PP 0x00030000
+#define BF_PXP_WFA_FETCH_CTRL_BF1_BYTES_PP(v) \
+ (((v) << 16) & BM_PXP_WFA_FETCH_CTRL_BF1_BYTES_PP)
+#define BP_PXP_WFA_FETCH_CTRL_RSVD1 14
+#define BM_PXP_WFA_FETCH_CTRL_RSVD1 0x0000C000
+#define BF_PXP_WFA_FETCH_CTRL_RSVD1(v) \
+ (((v) << 14) & BM_PXP_WFA_FETCH_CTRL_RSVD1)
+#define BM_PXP_WFA_FETCH_CTRL_BF2_BORDER_MODE 0x00002000
+#define BF_PXP_WFA_FETCH_CTRL_BF2_BORDER_MODE(v) \
+ (((v) << 13) & BM_PXP_WFA_FETCH_CTRL_BF2_BORDER_MODE)
+#define BV_PXP_WFA_FETCH_CTRL_BF2_BORDER_MODE__0 0x0
+#define BV_PXP_WFA_FETCH_CTRL_BF2_BORDER_MODE__1 0x1
+#define BM_PXP_WFA_FETCH_CTRL_BF2_BURST_LEN 0x00001000
+#define BF_PXP_WFA_FETCH_CTRL_BF2_BURST_LEN(v) \
+ (((v) << 12) & BM_PXP_WFA_FETCH_CTRL_BF2_BURST_LEN)
+#define BV_PXP_WFA_FETCH_CTRL_BF2_BURST_LEN__0 0x0
+#define BV_PXP_WFA_FETCH_CTRL_BF2_BURST_LEN__1 0x1
+#define BM_PXP_WFA_FETCH_CTRL_BF2_BYPASS_MODE 0x00000800
+#define BF_PXP_WFA_FETCH_CTRL_BF2_BYPASS_MODE(v) \
+ (((v) << 11) & BM_PXP_WFA_FETCH_CTRL_BF2_BYPASS_MODE)
+#define BV_PXP_WFA_FETCH_CTRL_BF2_BYPASS_MODE__0 0x0
+#define BV_PXP_WFA_FETCH_CTRL_BF2_BYPASS_MODE__1 0x1
+#define BM_PXP_WFA_FETCH_CTRL_BF2_HSK_MODE 0x00000400
+#define BF_PXP_WFA_FETCH_CTRL_BF2_HSK_MODE(v) \
+ (((v) << 10) & BM_PXP_WFA_FETCH_CTRL_BF2_HSK_MODE)
+#define BV_PXP_WFA_FETCH_CTRL_BF2_HSK_MODE__0 0x0
+#define BV_PXP_WFA_FETCH_CTRL_BF2_HSK_MODE__1 0x1
+#define BM_PXP_WFA_FETCH_CTRL_BF2_SRAM_IF 0x00000200
+#define BF_PXP_WFA_FETCH_CTRL_BF2_SRAM_IF(v) \
+ (((v) << 9) & BM_PXP_WFA_FETCH_CTRL_BF2_SRAM_IF)
+#define BV_PXP_WFA_FETCH_CTRL_BF2_SRAM_IF__0 0x0
+#define BV_PXP_WFA_FETCH_CTRL_BF2_SRAM_IF__1 0x1
+#define BM_PXP_WFA_FETCH_CTRL_BF2_EN 0x00000100
+#define BF_PXP_WFA_FETCH_CTRL_BF2_EN(v) \
+ (((v) << 8) & BM_PXP_WFA_FETCH_CTRL_BF2_EN)
+#define BV_PXP_WFA_FETCH_CTRL_BF2_EN__0 0x0
+#define BV_PXP_WFA_FETCH_CTRL_BF2_EN__1 0x1
+#define BP_PXP_WFA_FETCH_CTRL_RSVD2 6
+#define BM_PXP_WFA_FETCH_CTRL_RSVD2 0x000000C0
+#define BF_PXP_WFA_FETCH_CTRL_RSVD2(v) \
+ (((v) << 6) & BM_PXP_WFA_FETCH_CTRL_RSVD2)
+#define BM_PXP_WFA_FETCH_CTRL_BF1_BORDER_MODE 0x00000020
+#define BF_PXP_WFA_FETCH_CTRL_BF1_BORDER_MODE(v) \
+ (((v) << 5) & BM_PXP_WFA_FETCH_CTRL_BF1_BORDER_MODE)
+#define BV_PXP_WFA_FETCH_CTRL_BF1_BORDER_MODE__0 0x0
+#define BV_PXP_WFA_FETCH_CTRL_BF1_BORDER_MODE__1 0x1
+#define BM_PXP_WFA_FETCH_CTRL_BF1_BURST_LEN 0x00000010
+#define BF_PXP_WFA_FETCH_CTRL_BF1_BURST_LEN(v) \
+ (((v) << 4) & BM_PXP_WFA_FETCH_CTRL_BF1_BURST_LEN)
+#define BV_PXP_WFA_FETCH_CTRL_BF1_BURST_LEN__0 0x0
+#define BV_PXP_WFA_FETCH_CTRL_BF1_BURST_LEN__1 0x1
+#define BM_PXP_WFA_FETCH_CTRL_BF1_BYPASS_MODE 0x00000008
+#define BF_PXP_WFA_FETCH_CTRL_BF1_BYPASS_MODE(v) \
+ (((v) << 3) & BM_PXP_WFA_FETCH_CTRL_BF1_BYPASS_MODE)
+#define BV_PXP_WFA_FETCH_CTRL_BF1_BYPASS_MODE__0 0x0
+#define BV_PXP_WFA_FETCH_CTRL_BF1_BYPASS_MODE__1 0x1
+#define BM_PXP_WFA_FETCH_CTRL_BF1_HSK_MODE 0x00000004
+#define BF_PXP_WFA_FETCH_CTRL_BF1_HSK_MODE(v) \
+ (((v) << 2) & BM_PXP_WFA_FETCH_CTRL_BF1_HSK_MODE)
+#define BV_PXP_WFA_FETCH_CTRL_BF1_HSK_MODE__0 0x0
+#define BV_PXP_WFA_FETCH_CTRL_BF1_HSK_MODE__1 0x1
+#define BM_PXP_WFA_FETCH_CTRL_BF1_SRAM_IF 0x00000002
+#define BF_PXP_WFA_FETCH_CTRL_BF1_SRAM_IF(v) \
+ (((v) << 1) & BM_PXP_WFA_FETCH_CTRL_BF1_SRAM_IF)
+#define BV_PXP_WFA_FETCH_CTRL_BF1_SRAM_IF__0 0x0
+#define BV_PXP_WFA_FETCH_CTRL_BF1_SRAM_IF__1 0x1
+#define BM_PXP_WFA_FETCH_CTRL_BF1_EN 0x00000001
+#define BF_PXP_WFA_FETCH_CTRL_BF1_EN(v) \
+ (((v) << 0) & BM_PXP_WFA_FETCH_CTRL_BF1_EN)
+#define BV_PXP_WFA_FETCH_CTRL_BF1_EN__0 0x0
+#define BV_PXP_WFA_FETCH_CTRL_BF1_EN__1 0x1
+
+#define HW_PXP_WFA_FETCH_BUF1_ADDR (0x00000c50)
+
+#define BP_PXP_WFA_FETCH_BUF1_ADDR_BUF_ADDR 0
+#define BM_PXP_WFA_FETCH_BUF1_ADDR_BUF_ADDR 0xFFFFFFFF
+#define BF_PXP_WFA_FETCH_BUF1_ADDR_BUF_ADDR(v) (v)
+
+#define HW_PXP_WFA_FETCH_BUF1_PITCH (0x00000c60)
+
+#define BP_PXP_WFA_FETCH_BUF1_PITCH_RSVD 16
+#define BM_PXP_WFA_FETCH_BUF1_PITCH_RSVD 0xFFFF0000
+#define BF_PXP_WFA_FETCH_BUF1_PITCH_RSVD(v) \
+ (((v) << 16) & BM_PXP_WFA_FETCH_BUF1_PITCH_RSVD)
+#define BP_PXP_WFA_FETCH_BUF1_PITCH_PITCH 0
+#define BM_PXP_WFA_FETCH_BUF1_PITCH_PITCH 0x0000FFFF
+#define BF_PXP_WFA_FETCH_BUF1_PITCH_PITCH(v) \
+ (((v) << 0) & BM_PXP_WFA_FETCH_BUF1_PITCH_PITCH)
+
+#define HW_PXP_WFA_FETCH_BUF1_SIZE (0x00000c70)
+
+#define BP_PXP_WFA_FETCH_BUF1_SIZE_RSVD0 30
+#define BM_PXP_WFA_FETCH_BUF1_SIZE_RSVD0 0xC0000000
+#define BF_PXP_WFA_FETCH_BUF1_SIZE_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFA_FETCH_BUF1_SIZE_RSVD0)
+#define BP_PXP_WFA_FETCH_BUF1_SIZE_BUF_HEIGHT 16
+#define BM_PXP_WFA_FETCH_BUF1_SIZE_BUF_HEIGHT 0x3FFF0000
+#define BF_PXP_WFA_FETCH_BUF1_SIZE_BUF_HEIGHT(v) \
+ (((v) << 16) & BM_PXP_WFA_FETCH_BUF1_SIZE_BUF_HEIGHT)
+#define BP_PXP_WFA_FETCH_BUF1_SIZE_RSVD1 14
+#define BM_PXP_WFA_FETCH_BUF1_SIZE_RSVD1 0x0000C000
+#define BF_PXP_WFA_FETCH_BUF1_SIZE_RSVD1(v) \
+ (((v) << 14) & BM_PXP_WFA_FETCH_BUF1_SIZE_RSVD1)
+#define BP_PXP_WFA_FETCH_BUF1_SIZE_BUF_WIDTH 0
+#define BM_PXP_WFA_FETCH_BUF1_SIZE_BUF_WIDTH 0x00003FFF
+#define BF_PXP_WFA_FETCH_BUF1_SIZE_BUF_WIDTH(v) \
+ (((v) << 0) & BM_PXP_WFA_FETCH_BUF1_SIZE_BUF_WIDTH)
+
+#define HW_PXP_WFA_FETCH_BUF2_ADDR (0x00000c80)
+
+#define BP_PXP_WFA_FETCH_BUF2_ADDR_BUF_ADDR 0
+#define BM_PXP_WFA_FETCH_BUF2_ADDR_BUF_ADDR 0xFFFFFFFF
+#define BF_PXP_WFA_FETCH_BUF2_ADDR_BUF_ADDR(v) (v)
+
+#define HW_PXP_WFA_FETCH_BUF2_PITCH (0x00000c90)
+
+#define BP_PXP_WFA_FETCH_BUF2_PITCH_RSVD 16
+#define BM_PXP_WFA_FETCH_BUF2_PITCH_RSVD 0xFFFF0000
+#define BF_PXP_WFA_FETCH_BUF2_PITCH_RSVD(v) \
+ (((v) << 16) & BM_PXP_WFA_FETCH_BUF2_PITCH_RSVD)
+#define BP_PXP_WFA_FETCH_BUF2_PITCH_PITCH 0
+#define BM_PXP_WFA_FETCH_BUF2_PITCH_PITCH 0x0000FFFF
+#define BF_PXP_WFA_FETCH_BUF2_PITCH_PITCH(v) \
+ (((v) << 0) & BM_PXP_WFA_FETCH_BUF2_PITCH_PITCH)
+
+#define HW_PXP_WFA_FETCH_BUF2_SIZE (0x00000ca0)
+
+#define BP_PXP_WFA_FETCH_BUF2_SIZE_RSVD0 30
+#define BM_PXP_WFA_FETCH_BUF2_SIZE_RSVD0 0xC0000000
+#define BF_PXP_WFA_FETCH_BUF2_SIZE_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFA_FETCH_BUF2_SIZE_RSVD0)
+#define BP_PXP_WFA_FETCH_BUF2_SIZE_BUF_HEIGHT 16
+#define BM_PXP_WFA_FETCH_BUF2_SIZE_BUF_HEIGHT 0x3FFF0000
+#define BF_PXP_WFA_FETCH_BUF2_SIZE_BUF_HEIGHT(v) \
+ (((v) << 16) & BM_PXP_WFA_FETCH_BUF2_SIZE_BUF_HEIGHT)
+#define BP_PXP_WFA_FETCH_BUF2_SIZE_RSVD1 14
+#define BM_PXP_WFA_FETCH_BUF2_SIZE_RSVD1 0x0000C000
+#define BF_PXP_WFA_FETCH_BUF2_SIZE_RSVD1(v) \
+ (((v) << 14) & BM_PXP_WFA_FETCH_BUF2_SIZE_RSVD1)
+#define BP_PXP_WFA_FETCH_BUF2_SIZE_BUF_WIDTH 0
+#define BM_PXP_WFA_FETCH_BUF2_SIZE_BUF_WIDTH 0x00003FFF
+#define BF_PXP_WFA_FETCH_BUF2_SIZE_BUF_WIDTH(v) \
+ (((v) << 0) & BM_PXP_WFA_FETCH_BUF2_SIZE_BUF_WIDTH)
+
+#define HW_PXP_WFA_ARRAY_PIXEL0_MASK (0x00000cb0)
+
+#define BP_PXP_WFA_ARRAY_PIXEL0_MASK_RSVD0 30
+#define BM_PXP_WFA_ARRAY_PIXEL0_MASK_RSVD0 0xC0000000
+#define BF_PXP_WFA_ARRAY_PIXEL0_MASK_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFA_ARRAY_PIXEL0_MASK_RSVD0)
+#define BP_PXP_WFA_ARRAY_PIXEL0_MASK_BUF_SEL 28
+#define BM_PXP_WFA_ARRAY_PIXEL0_MASK_BUF_SEL 0x30000000
+#define BF_PXP_WFA_ARRAY_PIXEL0_MASK_BUF_SEL(v) \
+ (((v) << 28) & BM_PXP_WFA_ARRAY_PIXEL0_MASK_BUF_SEL)
+#define BV_PXP_WFA_ARRAY_PIXEL0_MASK_BUF_SEL__0 0x0
+#define BV_PXP_WFA_ARRAY_PIXEL0_MASK_BUF_SEL__1 0x1
+#define BV_PXP_WFA_ARRAY_PIXEL0_MASK_BUF_SEL__2 0x2
+#define BP_PXP_WFA_ARRAY_PIXEL0_MASK_RSVD1 26
+#define BM_PXP_WFA_ARRAY_PIXEL0_MASK_RSVD1 0x0C000000
+#define BF_PXP_WFA_ARRAY_PIXEL0_MASK_RSVD1(v) \
+ (((v) << 26) & BM_PXP_WFA_ARRAY_PIXEL0_MASK_RSVD1)
+#define BM_PXP_WFA_ARRAY_PIXEL0_MASK_SIGN_Y 0x02000000
+#define BF_PXP_WFA_ARRAY_PIXEL0_MASK_SIGN_Y(v) \
+ (((v) << 25) & BM_PXP_WFA_ARRAY_PIXEL0_MASK_SIGN_Y)
+#define BV_PXP_WFA_ARRAY_PIXEL0_MASK_SIGN_Y__0 0x0
+#define BV_PXP_WFA_ARRAY_PIXEL0_MASK_SIGN_Y__1 0x1
+#define BM_PXP_WFA_ARRAY_PIXEL0_MASK_SIGN_X 0x01000000
+#define BF_PXP_WFA_ARRAY_PIXEL0_MASK_SIGN_X(v) \
+ (((v) << 24) & BM_PXP_WFA_ARRAY_PIXEL0_MASK_SIGN_X)
+#define BV_PXP_WFA_ARRAY_PIXEL0_MASK_SIGN_X__0 0x0
+#define BV_PXP_WFA_ARRAY_PIXEL0_MASK_SIGN_X__1 0x1
+#define BP_PXP_WFA_ARRAY_PIXEL0_MASK_RSVD2 22
+#define BM_PXP_WFA_ARRAY_PIXEL0_MASK_RSVD2 0x00C00000
+#define BF_PXP_WFA_ARRAY_PIXEL0_MASK_RSVD2(v) \
+ (((v) << 22) & BM_PXP_WFA_ARRAY_PIXEL0_MASK_RSVD2)
+#define BP_PXP_WFA_ARRAY_PIXEL0_MASK_OFFSET_Y 20
+#define BM_PXP_WFA_ARRAY_PIXEL0_MASK_OFFSET_Y 0x00300000
+#define BF_PXP_WFA_ARRAY_PIXEL0_MASK_OFFSET_Y(v) \
+ (((v) << 20) & BM_PXP_WFA_ARRAY_PIXEL0_MASK_OFFSET_Y)
+#define BP_PXP_WFA_ARRAY_PIXEL0_MASK_RSVD3 18
+#define BM_PXP_WFA_ARRAY_PIXEL0_MASK_RSVD3 0x000C0000
+#define BF_PXP_WFA_ARRAY_PIXEL0_MASK_RSVD3(v) \
+ (((v) << 18) & BM_PXP_WFA_ARRAY_PIXEL0_MASK_RSVD3)
+#define BP_PXP_WFA_ARRAY_PIXEL0_MASK_OFFSET_X 16
+#define BM_PXP_WFA_ARRAY_PIXEL0_MASK_OFFSET_X 0x00030000
+#define BF_PXP_WFA_ARRAY_PIXEL0_MASK_OFFSET_X(v) \
+ (((v) << 16) & BM_PXP_WFA_ARRAY_PIXEL0_MASK_OFFSET_X)
+#define BP_PXP_WFA_ARRAY_PIXEL0_MASK_RSVD4 13
+#define BM_PXP_WFA_ARRAY_PIXEL0_MASK_RSVD4 0x0000E000
+#define BF_PXP_WFA_ARRAY_PIXEL0_MASK_RSVD4(v) \
+ (((v) << 13) & BM_PXP_WFA_ARRAY_PIXEL0_MASK_RSVD4)
+#define BP_PXP_WFA_ARRAY_PIXEL0_MASK_H_OFS 8
+#define BM_PXP_WFA_ARRAY_PIXEL0_MASK_H_OFS 0x00001F00
+#define BF_PXP_WFA_ARRAY_PIXEL0_MASK_H_OFS(v) \
+ (((v) << 8) & BM_PXP_WFA_ARRAY_PIXEL0_MASK_H_OFS)
+#define BP_PXP_WFA_ARRAY_PIXEL0_MASK_RSVD5 5
+#define BM_PXP_WFA_ARRAY_PIXEL0_MASK_RSVD5 0x000000E0
+#define BF_PXP_WFA_ARRAY_PIXEL0_MASK_RSVD5(v) \
+ (((v) << 5) & BM_PXP_WFA_ARRAY_PIXEL0_MASK_RSVD5)
+#define BP_PXP_WFA_ARRAY_PIXEL0_MASK_L_OFS 0
+#define BM_PXP_WFA_ARRAY_PIXEL0_MASK_L_OFS 0x0000001F
+#define BF_PXP_WFA_ARRAY_PIXEL0_MASK_L_OFS(v) \
+ (((v) << 0) & BM_PXP_WFA_ARRAY_PIXEL0_MASK_L_OFS)
+
+#define HW_PXP_WFA_ARRAY_PIXEL1_MASK (0x00000cc0)
+
+#define BP_PXP_WFA_ARRAY_PIXEL1_MASK_RSVD0 30
+#define BM_PXP_WFA_ARRAY_PIXEL1_MASK_RSVD0 0xC0000000
+#define BF_PXP_WFA_ARRAY_PIXEL1_MASK_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFA_ARRAY_PIXEL1_MASK_RSVD0)
+#define BP_PXP_WFA_ARRAY_PIXEL1_MASK_BUF_SEL 28
+#define BM_PXP_WFA_ARRAY_PIXEL1_MASK_BUF_SEL 0x30000000
+#define BF_PXP_WFA_ARRAY_PIXEL1_MASK_BUF_SEL(v) \
+ (((v) << 28) & BM_PXP_WFA_ARRAY_PIXEL1_MASK_BUF_SEL)
+#define BV_PXP_WFA_ARRAY_PIXEL1_MASK_BUF_SEL__0 0x0
+#define BV_PXP_WFA_ARRAY_PIXEL1_MASK_BUF_SEL__1 0x1
+#define BV_PXP_WFA_ARRAY_PIXEL1_MASK_BUF_SEL__2 0x2
+#define BP_PXP_WFA_ARRAY_PIXEL1_MASK_RSVD1 26
+#define BM_PXP_WFA_ARRAY_PIXEL1_MASK_RSVD1 0x0C000000
+#define BF_PXP_WFA_ARRAY_PIXEL1_MASK_RSVD1(v) \
+ (((v) << 26) & BM_PXP_WFA_ARRAY_PIXEL1_MASK_RSVD1)
+#define BM_PXP_WFA_ARRAY_PIXEL1_MASK_SIGN_Y 0x02000000
+#define BF_PXP_WFA_ARRAY_PIXEL1_MASK_SIGN_Y(v) \
+ (((v) << 25) & BM_PXP_WFA_ARRAY_PIXEL1_MASK_SIGN_Y)
+#define BV_PXP_WFA_ARRAY_PIXEL1_MASK_SIGN_Y__0 0x0
+#define BV_PXP_WFA_ARRAY_PIXEL1_MASK_SIGN_Y__1 0x1
+#define BM_PXP_WFA_ARRAY_PIXEL1_MASK_SIGN_X 0x01000000
+#define BF_PXP_WFA_ARRAY_PIXEL1_MASK_SIGN_X(v) \
+ (((v) << 24) & BM_PXP_WFA_ARRAY_PIXEL1_MASK_SIGN_X)
+#define BV_PXP_WFA_ARRAY_PIXEL1_MASK_SIGN_X__0 0x0
+#define BV_PXP_WFA_ARRAY_PIXEL1_MASK_SIGN_X__1 0x1
+#define BP_PXP_WFA_ARRAY_PIXEL1_MASK_RSVD2 22
+#define BM_PXP_WFA_ARRAY_PIXEL1_MASK_RSVD2 0x00C00000
+#define BF_PXP_WFA_ARRAY_PIXEL1_MASK_RSVD2(v) \
+ (((v) << 22) & BM_PXP_WFA_ARRAY_PIXEL1_MASK_RSVD2)
+#define BP_PXP_WFA_ARRAY_PIXEL1_MASK_OFFSET_Y 20
+#define BM_PXP_WFA_ARRAY_PIXEL1_MASK_OFFSET_Y 0x00300000
+#define BF_PXP_WFA_ARRAY_PIXEL1_MASK_OFFSET_Y(v) \
+ (((v) << 20) & BM_PXP_WFA_ARRAY_PIXEL1_MASK_OFFSET_Y)
+#define BP_PXP_WFA_ARRAY_PIXEL1_MASK_RSVD3 18
+#define BM_PXP_WFA_ARRAY_PIXEL1_MASK_RSVD3 0x000C0000
+#define BF_PXP_WFA_ARRAY_PIXEL1_MASK_RSVD3(v) \
+ (((v) << 18) & BM_PXP_WFA_ARRAY_PIXEL1_MASK_RSVD3)
+#define BP_PXP_WFA_ARRAY_PIXEL1_MASK_OFFSET_X 16
+#define BM_PXP_WFA_ARRAY_PIXEL1_MASK_OFFSET_X 0x00030000
+#define BF_PXP_WFA_ARRAY_PIXEL1_MASK_OFFSET_X(v) \
+ (((v) << 16) & BM_PXP_WFA_ARRAY_PIXEL1_MASK_OFFSET_X)
+#define BP_PXP_WFA_ARRAY_PIXEL1_MASK_RSVD4 13
+#define BM_PXP_WFA_ARRAY_PIXEL1_MASK_RSVD4 0x0000E000
+#define BF_PXP_WFA_ARRAY_PIXEL1_MASK_RSVD4(v) \
+ (((v) << 13) & BM_PXP_WFA_ARRAY_PIXEL1_MASK_RSVD4)
+#define BP_PXP_WFA_ARRAY_PIXEL1_MASK_H_OFS 8
+#define BM_PXP_WFA_ARRAY_PIXEL1_MASK_H_OFS 0x00001F00
+#define BF_PXP_WFA_ARRAY_PIXEL1_MASK_H_OFS(v) \
+ (((v) << 8) & BM_PXP_WFA_ARRAY_PIXEL1_MASK_H_OFS)
+#define BP_PXP_WFA_ARRAY_PIXEL1_MASK_RSVD5 5
+#define BM_PXP_WFA_ARRAY_PIXEL1_MASK_RSVD5 0x000000E0
+#define BF_PXP_WFA_ARRAY_PIXEL1_MASK_RSVD5(v) \
+ (((v) << 5) & BM_PXP_WFA_ARRAY_PIXEL1_MASK_RSVD5)
+#define BP_PXP_WFA_ARRAY_PIXEL1_MASK_L_OFS 0
+#define BM_PXP_WFA_ARRAY_PIXEL1_MASK_L_OFS 0x0000001F
+#define BF_PXP_WFA_ARRAY_PIXEL1_MASK_L_OFS(v) \
+ (((v) << 0) & BM_PXP_WFA_ARRAY_PIXEL1_MASK_L_OFS)
+
+#define HW_PXP_WFA_ARRAY_PIXEL2_MASK (0x00000cd0)
+
+#define BP_PXP_WFA_ARRAY_PIXEL2_MASK_RSVD0 30
+#define BM_PXP_WFA_ARRAY_PIXEL2_MASK_RSVD0 0xC0000000
+#define BF_PXP_WFA_ARRAY_PIXEL2_MASK_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFA_ARRAY_PIXEL2_MASK_RSVD0)
+#define BP_PXP_WFA_ARRAY_PIXEL2_MASK_BUF_SEL 28
+#define BM_PXP_WFA_ARRAY_PIXEL2_MASK_BUF_SEL 0x30000000
+#define BF_PXP_WFA_ARRAY_PIXEL2_MASK_BUF_SEL(v) \
+ (((v) << 28) & BM_PXP_WFA_ARRAY_PIXEL2_MASK_BUF_SEL)
+#define BV_PXP_WFA_ARRAY_PIXEL2_MASK_BUF_SEL__0 0x0
+#define BV_PXP_WFA_ARRAY_PIXEL2_MASK_BUF_SEL__1 0x1
+#define BV_PXP_WFA_ARRAY_PIXEL2_MASK_BUF_SEL__2 0x2
+#define BP_PXP_WFA_ARRAY_PIXEL2_MASK_RSVD1 26
+#define BM_PXP_WFA_ARRAY_PIXEL2_MASK_RSVD1 0x0C000000
+#define BF_PXP_WFA_ARRAY_PIXEL2_MASK_RSVD1(v) \
+ (((v) << 26) & BM_PXP_WFA_ARRAY_PIXEL2_MASK_RSVD1)
+#define BM_PXP_WFA_ARRAY_PIXEL2_MASK_SIGN_Y 0x02000000
+#define BF_PXP_WFA_ARRAY_PIXEL2_MASK_SIGN_Y(v) \
+ (((v) << 25) & BM_PXP_WFA_ARRAY_PIXEL2_MASK_SIGN_Y)
+#define BV_PXP_WFA_ARRAY_PIXEL2_MASK_SIGN_Y__0 0x0
+#define BV_PXP_WFA_ARRAY_PIXEL2_MASK_SIGN_Y__1 0x1
+#define BM_PXP_WFA_ARRAY_PIXEL2_MASK_SIGN_X 0x01000000
+#define BF_PXP_WFA_ARRAY_PIXEL2_MASK_SIGN_X(v) \
+ (((v) << 24) & BM_PXP_WFA_ARRAY_PIXEL2_MASK_SIGN_X)
+#define BV_PXP_WFA_ARRAY_PIXEL2_MASK_SIGN_X__0 0x0
+#define BV_PXP_WFA_ARRAY_PIXEL2_MASK_SIGN_X__1 0x1
+#define BP_PXP_WFA_ARRAY_PIXEL2_MASK_RSVD2 22
+#define BM_PXP_WFA_ARRAY_PIXEL2_MASK_RSVD2 0x00C00000
+#define BF_PXP_WFA_ARRAY_PIXEL2_MASK_RSVD2(v) \
+ (((v) << 22) & BM_PXP_WFA_ARRAY_PIXEL2_MASK_RSVD2)
+#define BP_PXP_WFA_ARRAY_PIXEL2_MASK_OFFSET_Y 20
+#define BM_PXP_WFA_ARRAY_PIXEL2_MASK_OFFSET_Y 0x00300000
+#define BF_PXP_WFA_ARRAY_PIXEL2_MASK_OFFSET_Y(v) \
+ (((v) << 20) & BM_PXP_WFA_ARRAY_PIXEL2_MASK_OFFSET_Y)
+#define BP_PXP_WFA_ARRAY_PIXEL2_MASK_RSVD3 18
+#define BM_PXP_WFA_ARRAY_PIXEL2_MASK_RSVD3 0x000C0000
+#define BF_PXP_WFA_ARRAY_PIXEL2_MASK_RSVD3(v) \
+ (((v) << 18) & BM_PXP_WFA_ARRAY_PIXEL2_MASK_RSVD3)
+#define BP_PXP_WFA_ARRAY_PIXEL2_MASK_OFFSET_X 16
+#define BM_PXP_WFA_ARRAY_PIXEL2_MASK_OFFSET_X 0x00030000
+#define BF_PXP_WFA_ARRAY_PIXEL2_MASK_OFFSET_X(v) \
+ (((v) << 16) & BM_PXP_WFA_ARRAY_PIXEL2_MASK_OFFSET_X)
+#define BP_PXP_WFA_ARRAY_PIXEL2_MASK_RSVD4 13
+#define BM_PXP_WFA_ARRAY_PIXEL2_MASK_RSVD4 0x0000E000
+#define BF_PXP_WFA_ARRAY_PIXEL2_MASK_RSVD4(v) \
+ (((v) << 13) & BM_PXP_WFA_ARRAY_PIXEL2_MASK_RSVD4)
+#define BP_PXP_WFA_ARRAY_PIXEL2_MASK_H_OFS 8
+#define BM_PXP_WFA_ARRAY_PIXEL2_MASK_H_OFS 0x00001F00
+#define BF_PXP_WFA_ARRAY_PIXEL2_MASK_H_OFS(v) \
+ (((v) << 8) & BM_PXP_WFA_ARRAY_PIXEL2_MASK_H_OFS)
+#define BP_PXP_WFA_ARRAY_PIXEL2_MASK_RSVD5 5
+#define BM_PXP_WFA_ARRAY_PIXEL2_MASK_RSVD5 0x000000E0
+#define BF_PXP_WFA_ARRAY_PIXEL2_MASK_RSVD5(v) \
+ (((v) << 5) & BM_PXP_WFA_ARRAY_PIXEL2_MASK_RSVD5)
+#define BP_PXP_WFA_ARRAY_PIXEL2_MASK_L_OFS 0
+#define BM_PXP_WFA_ARRAY_PIXEL2_MASK_L_OFS 0x0000001F
+#define BF_PXP_WFA_ARRAY_PIXEL2_MASK_L_OFS(v) \
+ (((v) << 0) & BM_PXP_WFA_ARRAY_PIXEL2_MASK_L_OFS)
+
+#define HW_PXP_WFA_ARRAY_PIXEL3_MASK (0x00000ce0)
+
+#define BP_PXP_WFA_ARRAY_PIXEL3_MASK_RSVD0 30
+#define BM_PXP_WFA_ARRAY_PIXEL3_MASK_RSVD0 0xC0000000
+#define BF_PXP_WFA_ARRAY_PIXEL3_MASK_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFA_ARRAY_PIXEL3_MASK_RSVD0)
+#define BP_PXP_WFA_ARRAY_PIXEL3_MASK_BUF_SEL 28
+#define BM_PXP_WFA_ARRAY_PIXEL3_MASK_BUF_SEL 0x30000000
+#define BF_PXP_WFA_ARRAY_PIXEL3_MASK_BUF_SEL(v) \
+ (((v) << 28) & BM_PXP_WFA_ARRAY_PIXEL3_MASK_BUF_SEL)
+#define BV_PXP_WFA_ARRAY_PIXEL3_MASK_BUF_SEL__0 0x0
+#define BV_PXP_WFA_ARRAY_PIXEL3_MASK_BUF_SEL__1 0x1
+#define BV_PXP_WFA_ARRAY_PIXEL3_MASK_BUF_SEL__2 0x2
+#define BP_PXP_WFA_ARRAY_PIXEL3_MASK_RSVD1 26
+#define BM_PXP_WFA_ARRAY_PIXEL3_MASK_RSVD1 0x0C000000
+#define BF_PXP_WFA_ARRAY_PIXEL3_MASK_RSVD1(v) \
+ (((v) << 26) & BM_PXP_WFA_ARRAY_PIXEL3_MASK_RSVD1)
+#define BM_PXP_WFA_ARRAY_PIXEL3_MASK_SIGN_Y 0x02000000
+#define BF_PXP_WFA_ARRAY_PIXEL3_MASK_SIGN_Y(v) \
+ (((v) << 25) & BM_PXP_WFA_ARRAY_PIXEL3_MASK_SIGN_Y)
+#define BV_PXP_WFA_ARRAY_PIXEL3_MASK_SIGN_Y__0 0x0
+#define BV_PXP_WFA_ARRAY_PIXEL3_MASK_SIGN_Y__1 0x1
+#define BM_PXP_WFA_ARRAY_PIXEL3_MASK_SIGN_X 0x01000000
+#define BF_PXP_WFA_ARRAY_PIXEL3_MASK_SIGN_X(v) \
+ (((v) << 24) & BM_PXP_WFA_ARRAY_PIXEL3_MASK_SIGN_X)
+#define BV_PXP_WFA_ARRAY_PIXEL3_MASK_SIGN_X__0 0x0
+#define BV_PXP_WFA_ARRAY_PIXEL3_MASK_SIGN_X__1 0x1
+#define BP_PXP_WFA_ARRAY_PIXEL3_MASK_RSVD2 22
+#define BM_PXP_WFA_ARRAY_PIXEL3_MASK_RSVD2 0x00C00000
+#define BF_PXP_WFA_ARRAY_PIXEL3_MASK_RSVD2(v) \
+ (((v) << 22) & BM_PXP_WFA_ARRAY_PIXEL3_MASK_RSVD2)
+#define BP_PXP_WFA_ARRAY_PIXEL3_MASK_OFFSET_Y 20
+#define BM_PXP_WFA_ARRAY_PIXEL3_MASK_OFFSET_Y 0x00300000
+#define BF_PXP_WFA_ARRAY_PIXEL3_MASK_OFFSET_Y(v) \
+ (((v) << 20) & BM_PXP_WFA_ARRAY_PIXEL3_MASK_OFFSET_Y)
+#define BP_PXP_WFA_ARRAY_PIXEL3_MASK_RSVD3 18
+#define BM_PXP_WFA_ARRAY_PIXEL3_MASK_RSVD3 0x000C0000
+#define BF_PXP_WFA_ARRAY_PIXEL3_MASK_RSVD3(v) \
+ (((v) << 18) & BM_PXP_WFA_ARRAY_PIXEL3_MASK_RSVD3)
+#define BP_PXP_WFA_ARRAY_PIXEL3_MASK_OFFSET_X 16
+#define BM_PXP_WFA_ARRAY_PIXEL3_MASK_OFFSET_X 0x00030000
+#define BF_PXP_WFA_ARRAY_PIXEL3_MASK_OFFSET_X(v) \
+ (((v) << 16) & BM_PXP_WFA_ARRAY_PIXEL3_MASK_OFFSET_X)
+#define BP_PXP_WFA_ARRAY_PIXEL3_MASK_RSVD4 13
+#define BM_PXP_WFA_ARRAY_PIXEL3_MASK_RSVD4 0x0000E000
+#define BF_PXP_WFA_ARRAY_PIXEL3_MASK_RSVD4(v) \
+ (((v) << 13) & BM_PXP_WFA_ARRAY_PIXEL3_MASK_RSVD4)
+#define BP_PXP_WFA_ARRAY_PIXEL3_MASK_H_OFS 8
+#define BM_PXP_WFA_ARRAY_PIXEL3_MASK_H_OFS 0x00001F00
+#define BF_PXP_WFA_ARRAY_PIXEL3_MASK_H_OFS(v) \
+ (((v) << 8) & BM_PXP_WFA_ARRAY_PIXEL3_MASK_H_OFS)
+#define BP_PXP_WFA_ARRAY_PIXEL3_MASK_RSVD5 5
+#define BM_PXP_WFA_ARRAY_PIXEL3_MASK_RSVD5 0x000000E0
+#define BF_PXP_WFA_ARRAY_PIXEL3_MASK_RSVD5(v) \
+ (((v) << 5) & BM_PXP_WFA_ARRAY_PIXEL3_MASK_RSVD5)
+#define BP_PXP_WFA_ARRAY_PIXEL3_MASK_L_OFS 0
+#define BM_PXP_WFA_ARRAY_PIXEL3_MASK_L_OFS 0x0000001F
+#define BF_PXP_WFA_ARRAY_PIXEL3_MASK_L_OFS(v) \
+ (((v) << 0) & BM_PXP_WFA_ARRAY_PIXEL3_MASK_L_OFS)
+
+#define HW_PXP_WFA_ARRAY_PIXEL4_MASK (0x00000cf0)
+
+#define BP_PXP_WFA_ARRAY_PIXEL4_MASK_RSVD0 30
+#define BM_PXP_WFA_ARRAY_PIXEL4_MASK_RSVD0 0xC0000000
+#define BF_PXP_WFA_ARRAY_PIXEL4_MASK_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFA_ARRAY_PIXEL4_MASK_RSVD0)
+#define BP_PXP_WFA_ARRAY_PIXEL4_MASK_BUF_SEL 28
+#define BM_PXP_WFA_ARRAY_PIXEL4_MASK_BUF_SEL 0x30000000
+#define BF_PXP_WFA_ARRAY_PIXEL4_MASK_BUF_SEL(v) \
+ (((v) << 28) & BM_PXP_WFA_ARRAY_PIXEL4_MASK_BUF_SEL)
+#define BV_PXP_WFA_ARRAY_PIXEL4_MASK_BUF_SEL__0 0x0
+#define BV_PXP_WFA_ARRAY_PIXEL4_MASK_BUF_SEL__1 0x1
+#define BV_PXP_WFA_ARRAY_PIXEL4_MASK_BUF_SEL__2 0x2
+#define BP_PXP_WFA_ARRAY_PIXEL4_MASK_RSVD1 26
+#define BM_PXP_WFA_ARRAY_PIXEL4_MASK_RSVD1 0x0C000000
+#define BF_PXP_WFA_ARRAY_PIXEL4_MASK_RSVD1(v) \
+ (((v) << 26) & BM_PXP_WFA_ARRAY_PIXEL4_MASK_RSVD1)
+#define BM_PXP_WFA_ARRAY_PIXEL4_MASK_SIGN_Y 0x02000000
+#define BF_PXP_WFA_ARRAY_PIXEL4_MASK_SIGN_Y(v) \
+ (((v) << 25) & BM_PXP_WFA_ARRAY_PIXEL4_MASK_SIGN_Y)
+#define BV_PXP_WFA_ARRAY_PIXEL4_MASK_SIGN_Y__0 0x0
+#define BV_PXP_WFA_ARRAY_PIXEL4_MASK_SIGN_Y__1 0x1
+#define BM_PXP_WFA_ARRAY_PIXEL4_MASK_SIGN_X 0x01000000
+#define BF_PXP_WFA_ARRAY_PIXEL4_MASK_SIGN_X(v) \
+ (((v) << 24) & BM_PXP_WFA_ARRAY_PIXEL4_MASK_SIGN_X)
+#define BV_PXP_WFA_ARRAY_PIXEL4_MASK_SIGN_X__0 0x0
+#define BV_PXP_WFA_ARRAY_PIXEL4_MASK_SIGN_X__1 0x1
+#define BP_PXP_WFA_ARRAY_PIXEL4_MASK_RSVD2 22
+#define BM_PXP_WFA_ARRAY_PIXEL4_MASK_RSVD2 0x00C00000
+#define BF_PXP_WFA_ARRAY_PIXEL4_MASK_RSVD2(v) \
+ (((v) << 22) & BM_PXP_WFA_ARRAY_PIXEL4_MASK_RSVD2)
+#define BP_PXP_WFA_ARRAY_PIXEL4_MASK_OFFSET_Y 20
+#define BM_PXP_WFA_ARRAY_PIXEL4_MASK_OFFSET_Y 0x00300000
+#define BF_PXP_WFA_ARRAY_PIXEL4_MASK_OFFSET_Y(v) \
+ (((v) << 20) & BM_PXP_WFA_ARRAY_PIXEL4_MASK_OFFSET_Y)
+#define BP_PXP_WFA_ARRAY_PIXEL4_MASK_RSVD3 18
+#define BM_PXP_WFA_ARRAY_PIXEL4_MASK_RSVD3 0x000C0000
+#define BF_PXP_WFA_ARRAY_PIXEL4_MASK_RSVD3(v) \
+ (((v) << 18) & BM_PXP_WFA_ARRAY_PIXEL4_MASK_RSVD3)
+#define BP_PXP_WFA_ARRAY_PIXEL4_MASK_OFFSET_X 16
+#define BM_PXP_WFA_ARRAY_PIXEL4_MASK_OFFSET_X 0x00030000
+#define BF_PXP_WFA_ARRAY_PIXEL4_MASK_OFFSET_X(v) \
+ (((v) << 16) & BM_PXP_WFA_ARRAY_PIXEL4_MASK_OFFSET_X)
+#define BP_PXP_WFA_ARRAY_PIXEL4_MASK_RSVD4 13
+#define BM_PXP_WFA_ARRAY_PIXEL4_MASK_RSVD4 0x0000E000
+#define BF_PXP_WFA_ARRAY_PIXEL4_MASK_RSVD4(v) \
+ (((v) << 13) & BM_PXP_WFA_ARRAY_PIXEL4_MASK_RSVD4)
+#define BP_PXP_WFA_ARRAY_PIXEL4_MASK_H_OFS 8
+#define BM_PXP_WFA_ARRAY_PIXEL4_MASK_H_OFS 0x00001F00
+#define BF_PXP_WFA_ARRAY_PIXEL4_MASK_H_OFS(v) \
+ (((v) << 8) & BM_PXP_WFA_ARRAY_PIXEL4_MASK_H_OFS)
+#define BP_PXP_WFA_ARRAY_PIXEL4_MASK_RSVD5 5
+#define BM_PXP_WFA_ARRAY_PIXEL4_MASK_RSVD5 0x000000E0
+#define BF_PXP_WFA_ARRAY_PIXEL4_MASK_RSVD5(v) \
+ (((v) << 5) & BM_PXP_WFA_ARRAY_PIXEL4_MASK_RSVD5)
+#define BP_PXP_WFA_ARRAY_PIXEL4_MASK_L_OFS 0
+#define BM_PXP_WFA_ARRAY_PIXEL4_MASK_L_OFS 0x0000001F
+#define BF_PXP_WFA_ARRAY_PIXEL4_MASK_L_OFS(v) \
+ (((v) << 0) & BM_PXP_WFA_ARRAY_PIXEL4_MASK_L_OFS)
+
+#define HW_PXP_WFA_ARRAY_PIXEL5_MASK (0x00000d00)
+
+#define BP_PXP_WFA_ARRAY_PIXEL5_MASK_RSVD0 30
+#define BM_PXP_WFA_ARRAY_PIXEL5_MASK_RSVD0 0xC0000000
+#define BF_PXP_WFA_ARRAY_PIXEL5_MASK_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFA_ARRAY_PIXEL5_MASK_RSVD0)
+#define BP_PXP_WFA_ARRAY_PIXEL5_MASK_BUF_SEL 28
+#define BM_PXP_WFA_ARRAY_PIXEL5_MASK_BUF_SEL 0x30000000
+#define BF_PXP_WFA_ARRAY_PIXEL5_MASK_BUF_SEL(v) \
+ (((v) << 28) & BM_PXP_WFA_ARRAY_PIXEL5_MASK_BUF_SEL)
+#define BV_PXP_WFA_ARRAY_PIXEL5_MASK_BUF_SEL__0 0x0
+#define BV_PXP_WFA_ARRAY_PIXEL5_MASK_BUF_SEL__1 0x1
+#define BV_PXP_WFA_ARRAY_PIXEL5_MASK_BUF_SEL__2 0x2
+#define BP_PXP_WFA_ARRAY_PIXEL5_MASK_RSVD1 26
+#define BM_PXP_WFA_ARRAY_PIXEL5_MASK_RSVD1 0x0C000000
+#define BF_PXP_WFA_ARRAY_PIXEL5_MASK_RSVD1(v) \
+ (((v) << 26) & BM_PXP_WFA_ARRAY_PIXEL5_MASK_RSVD1)
+#define BM_PXP_WFA_ARRAY_PIXEL5_MASK_SIGN_Y 0x02000000
+#define BF_PXP_WFA_ARRAY_PIXEL5_MASK_SIGN_Y(v) \
+ (((v) << 25) & BM_PXP_WFA_ARRAY_PIXEL5_MASK_SIGN_Y)
+#define BV_PXP_WFA_ARRAY_PIXEL5_MASK_SIGN_Y__0 0x0
+#define BV_PXP_WFA_ARRAY_PIXEL5_MASK_SIGN_Y__1 0x1
+#define BM_PXP_WFA_ARRAY_PIXEL5_MASK_SIGN_X 0x01000000
+#define BF_PXP_WFA_ARRAY_PIXEL5_MASK_SIGN_X(v) \
+ (((v) << 24) & BM_PXP_WFA_ARRAY_PIXEL5_MASK_SIGN_X)
+#define BV_PXP_WFA_ARRAY_PIXEL5_MASK_SIGN_X__0 0x0
+#define BV_PXP_WFA_ARRAY_PIXEL5_MASK_SIGN_X__1 0x1
+#define BP_PXP_WFA_ARRAY_PIXEL5_MASK_RSVD2 22
+#define BM_PXP_WFA_ARRAY_PIXEL5_MASK_RSVD2 0x00C00000
+#define BF_PXP_WFA_ARRAY_PIXEL5_MASK_RSVD2(v) \
+ (((v) << 22) & BM_PXP_WFA_ARRAY_PIXEL5_MASK_RSVD2)
+#define BP_PXP_WFA_ARRAY_PIXEL5_MASK_OFFSET_Y 20
+#define BM_PXP_WFA_ARRAY_PIXEL5_MASK_OFFSET_Y 0x00300000
+#define BF_PXP_WFA_ARRAY_PIXEL5_MASK_OFFSET_Y(v) \
+ (((v) << 20) & BM_PXP_WFA_ARRAY_PIXEL5_MASK_OFFSET_Y)
+#define BP_PXP_WFA_ARRAY_PIXEL5_MASK_RSVD3 18
+#define BM_PXP_WFA_ARRAY_PIXEL5_MASK_RSVD3 0x000C0000
+#define BF_PXP_WFA_ARRAY_PIXEL5_MASK_RSVD3(v) \
+ (((v) << 18) & BM_PXP_WFA_ARRAY_PIXEL5_MASK_RSVD3)
+#define BP_PXP_WFA_ARRAY_PIXEL5_MASK_OFFSET_X 16
+#define BM_PXP_WFA_ARRAY_PIXEL5_MASK_OFFSET_X 0x00030000
+#define BF_PXP_WFA_ARRAY_PIXEL5_MASK_OFFSET_X(v) \
+ (((v) << 16) & BM_PXP_WFA_ARRAY_PIXEL5_MASK_OFFSET_X)
+#define BP_PXP_WFA_ARRAY_PIXEL5_MASK_RSVD4 13
+#define BM_PXP_WFA_ARRAY_PIXEL5_MASK_RSVD4 0x0000E000
+#define BF_PXP_WFA_ARRAY_PIXEL5_MASK_RSVD4(v) \
+ (((v) << 13) & BM_PXP_WFA_ARRAY_PIXEL5_MASK_RSVD4)
+#define BP_PXP_WFA_ARRAY_PIXEL5_MASK_H_OFS 8
+#define BM_PXP_WFA_ARRAY_PIXEL5_MASK_H_OFS 0x00001F00
+#define BF_PXP_WFA_ARRAY_PIXEL5_MASK_H_OFS(v) \
+ (((v) << 8) & BM_PXP_WFA_ARRAY_PIXEL5_MASK_H_OFS)
+#define BP_PXP_WFA_ARRAY_PIXEL5_MASK_RSVD5 5
+#define BM_PXP_WFA_ARRAY_PIXEL5_MASK_RSVD5 0x000000E0
+#define BF_PXP_WFA_ARRAY_PIXEL5_MASK_RSVD5(v) \
+ (((v) << 5) & BM_PXP_WFA_ARRAY_PIXEL5_MASK_RSVD5)
+#define BP_PXP_WFA_ARRAY_PIXEL5_MASK_L_OFS 0
+#define BM_PXP_WFA_ARRAY_PIXEL5_MASK_L_OFS 0x0000001F
+#define BF_PXP_WFA_ARRAY_PIXEL5_MASK_L_OFS(v) \
+ (((v) << 0) & BM_PXP_WFA_ARRAY_PIXEL5_MASK_L_OFS)
+
+#define HW_PXP_WFA_ARRAY_PIXEL6_MASK (0x00000d10)
+
+#define BP_PXP_WFA_ARRAY_PIXEL6_MASK_RSVD0 30
+#define BM_PXP_WFA_ARRAY_PIXEL6_MASK_RSVD0 0xC0000000
+#define BF_PXP_WFA_ARRAY_PIXEL6_MASK_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFA_ARRAY_PIXEL6_MASK_RSVD0)
+#define BP_PXP_WFA_ARRAY_PIXEL6_MASK_BUF_SEL 28
+#define BM_PXP_WFA_ARRAY_PIXEL6_MASK_BUF_SEL 0x30000000
+#define BF_PXP_WFA_ARRAY_PIXEL6_MASK_BUF_SEL(v) \
+ (((v) << 28) & BM_PXP_WFA_ARRAY_PIXEL6_MASK_BUF_SEL)
+#define BV_PXP_WFA_ARRAY_PIXEL6_MASK_BUF_SEL__0 0x0
+#define BV_PXP_WFA_ARRAY_PIXEL6_MASK_BUF_SEL__1 0x1
+#define BV_PXP_WFA_ARRAY_PIXEL6_MASK_BUF_SEL__2 0x2
+#define BP_PXP_WFA_ARRAY_PIXEL6_MASK_RSVD1 26
+#define BM_PXP_WFA_ARRAY_PIXEL6_MASK_RSVD1 0x0C000000
+#define BF_PXP_WFA_ARRAY_PIXEL6_MASK_RSVD1(v) \
+ (((v) << 26) & BM_PXP_WFA_ARRAY_PIXEL6_MASK_RSVD1)
+#define BM_PXP_WFA_ARRAY_PIXEL6_MASK_SIGN_Y 0x02000000
+#define BF_PXP_WFA_ARRAY_PIXEL6_MASK_SIGN_Y(v) \
+ (((v) << 25) & BM_PXP_WFA_ARRAY_PIXEL6_MASK_SIGN_Y)
+#define BV_PXP_WFA_ARRAY_PIXEL6_MASK_SIGN_Y__0 0x0
+#define BV_PXP_WFA_ARRAY_PIXEL6_MASK_SIGN_Y__1 0x1
+#define BM_PXP_WFA_ARRAY_PIXEL6_MASK_SIGN_X 0x01000000
+#define BF_PXP_WFA_ARRAY_PIXEL6_MASK_SIGN_X(v) \
+ (((v) << 24) & BM_PXP_WFA_ARRAY_PIXEL6_MASK_SIGN_X)
+#define BV_PXP_WFA_ARRAY_PIXEL6_MASK_SIGN_X__0 0x0
+#define BV_PXP_WFA_ARRAY_PIXEL6_MASK_SIGN_X__1 0x1
+#define BP_PXP_WFA_ARRAY_PIXEL6_MASK_RSVD2 22
+#define BM_PXP_WFA_ARRAY_PIXEL6_MASK_RSVD2 0x00C00000
+#define BF_PXP_WFA_ARRAY_PIXEL6_MASK_RSVD2(v) \
+ (((v) << 22) & BM_PXP_WFA_ARRAY_PIXEL6_MASK_RSVD2)
+#define BP_PXP_WFA_ARRAY_PIXEL6_MASK_OFFSET_Y 20
+#define BM_PXP_WFA_ARRAY_PIXEL6_MASK_OFFSET_Y 0x00300000
+#define BF_PXP_WFA_ARRAY_PIXEL6_MASK_OFFSET_Y(v) \
+ (((v) << 20) & BM_PXP_WFA_ARRAY_PIXEL6_MASK_OFFSET_Y)
+#define BP_PXP_WFA_ARRAY_PIXEL6_MASK_RSVD3 18
+#define BM_PXP_WFA_ARRAY_PIXEL6_MASK_RSVD3 0x000C0000
+#define BF_PXP_WFA_ARRAY_PIXEL6_MASK_RSVD3(v) \
+ (((v) << 18) & BM_PXP_WFA_ARRAY_PIXEL6_MASK_RSVD3)
+#define BP_PXP_WFA_ARRAY_PIXEL6_MASK_OFFSET_X 16
+#define BM_PXP_WFA_ARRAY_PIXEL6_MASK_OFFSET_X 0x00030000
+#define BF_PXP_WFA_ARRAY_PIXEL6_MASK_OFFSET_X(v) \
+ (((v) << 16) & BM_PXP_WFA_ARRAY_PIXEL6_MASK_OFFSET_X)
+#define BP_PXP_WFA_ARRAY_PIXEL6_MASK_RSVD4 13
+#define BM_PXP_WFA_ARRAY_PIXEL6_MASK_RSVD4 0x0000E000
+#define BF_PXP_WFA_ARRAY_PIXEL6_MASK_RSVD4(v) \
+ (((v) << 13) & BM_PXP_WFA_ARRAY_PIXEL6_MASK_RSVD4)
+#define BP_PXP_WFA_ARRAY_PIXEL6_MASK_H_OFS 8
+#define BM_PXP_WFA_ARRAY_PIXEL6_MASK_H_OFS 0x00001F00
+#define BF_PXP_WFA_ARRAY_PIXEL6_MASK_H_OFS(v) \
+ (((v) << 8) & BM_PXP_WFA_ARRAY_PIXEL6_MASK_H_OFS)
+#define BP_PXP_WFA_ARRAY_PIXEL6_MASK_RSVD5 5
+#define BM_PXP_WFA_ARRAY_PIXEL6_MASK_RSVD5 0x000000E0
+#define BF_PXP_WFA_ARRAY_PIXEL6_MASK_RSVD5(v) \
+ (((v) << 5) & BM_PXP_WFA_ARRAY_PIXEL6_MASK_RSVD5)
+#define BP_PXP_WFA_ARRAY_PIXEL6_MASK_L_OFS 0
+#define BM_PXP_WFA_ARRAY_PIXEL6_MASK_L_OFS 0x0000001F
+#define BF_PXP_WFA_ARRAY_PIXEL6_MASK_L_OFS(v) \
+ (((v) << 0) & BM_PXP_WFA_ARRAY_PIXEL6_MASK_L_OFS)
+
+#define HW_PXP_WFA_ARRAY_PIXEL7_MASK (0x00000d20)
+
+#define BP_PXP_WFA_ARRAY_PIXEL7_MASK_RSVD0 30
+#define BM_PXP_WFA_ARRAY_PIXEL7_MASK_RSVD0 0xC0000000
+#define BF_PXP_WFA_ARRAY_PIXEL7_MASK_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFA_ARRAY_PIXEL7_MASK_RSVD0)
+#define BP_PXP_WFA_ARRAY_PIXEL7_MASK_BUF_SEL 28
+#define BM_PXP_WFA_ARRAY_PIXEL7_MASK_BUF_SEL 0x30000000
+#define BF_PXP_WFA_ARRAY_PIXEL7_MASK_BUF_SEL(v) \
+ (((v) << 28) & BM_PXP_WFA_ARRAY_PIXEL7_MASK_BUF_SEL)
+#define BV_PXP_WFA_ARRAY_PIXEL7_MASK_BUF_SEL__0 0x0
+#define BV_PXP_WFA_ARRAY_PIXEL7_MASK_BUF_SEL__1 0x1
+#define BV_PXP_WFA_ARRAY_PIXEL7_MASK_BUF_SEL__2 0x2
+#define BP_PXP_WFA_ARRAY_PIXEL7_MASK_RSVD1 26
+#define BM_PXP_WFA_ARRAY_PIXEL7_MASK_RSVD1 0x0C000000
+#define BF_PXP_WFA_ARRAY_PIXEL7_MASK_RSVD1(v) \
+ (((v) << 26) & BM_PXP_WFA_ARRAY_PIXEL7_MASK_RSVD1)
+#define BM_PXP_WFA_ARRAY_PIXEL7_MASK_SIGN_Y 0x02000000
+#define BF_PXP_WFA_ARRAY_PIXEL7_MASK_SIGN_Y(v) \
+ (((v) << 25) & BM_PXP_WFA_ARRAY_PIXEL7_MASK_SIGN_Y)
+#define BV_PXP_WFA_ARRAY_PIXEL7_MASK_SIGN_Y__0 0x0
+#define BV_PXP_WFA_ARRAY_PIXEL7_MASK_SIGN_Y__1 0x1
+#define BM_PXP_WFA_ARRAY_PIXEL7_MASK_SIGN_X 0x01000000
+#define BF_PXP_WFA_ARRAY_PIXEL7_MASK_SIGN_X(v) \
+ (((v) << 24) & BM_PXP_WFA_ARRAY_PIXEL7_MASK_SIGN_X)
+#define BV_PXP_WFA_ARRAY_PIXEL7_MASK_SIGN_X__0 0x0
+#define BV_PXP_WFA_ARRAY_PIXEL7_MASK_SIGN_X__1 0x1
+#define BP_PXP_WFA_ARRAY_PIXEL7_MASK_RSVD2 22
+#define BM_PXP_WFA_ARRAY_PIXEL7_MASK_RSVD2 0x00C00000
+#define BF_PXP_WFA_ARRAY_PIXEL7_MASK_RSVD2(v) \
+ (((v) << 22) & BM_PXP_WFA_ARRAY_PIXEL7_MASK_RSVD2)
+#define BP_PXP_WFA_ARRAY_PIXEL7_MASK_OFFSET_Y 20
+#define BM_PXP_WFA_ARRAY_PIXEL7_MASK_OFFSET_Y 0x00300000
+#define BF_PXP_WFA_ARRAY_PIXEL7_MASK_OFFSET_Y(v) \
+ (((v) << 20) & BM_PXP_WFA_ARRAY_PIXEL7_MASK_OFFSET_Y)
+#define BP_PXP_WFA_ARRAY_PIXEL7_MASK_RSVD3 18
+#define BM_PXP_WFA_ARRAY_PIXEL7_MASK_RSVD3 0x000C0000
+#define BF_PXP_WFA_ARRAY_PIXEL7_MASK_RSVD3(v) \
+ (((v) << 18) & BM_PXP_WFA_ARRAY_PIXEL7_MASK_RSVD3)
+#define BP_PXP_WFA_ARRAY_PIXEL7_MASK_OFFSET_X 16
+#define BM_PXP_WFA_ARRAY_PIXEL7_MASK_OFFSET_X 0x00030000
+#define BF_PXP_WFA_ARRAY_PIXEL7_MASK_OFFSET_X(v) \
+ (((v) << 16) & BM_PXP_WFA_ARRAY_PIXEL7_MASK_OFFSET_X)
+#define BP_PXP_WFA_ARRAY_PIXEL7_MASK_RSVD4 13
+#define BM_PXP_WFA_ARRAY_PIXEL7_MASK_RSVD4 0x0000E000
+#define BF_PXP_WFA_ARRAY_PIXEL7_MASK_RSVD4(v) \
+ (((v) << 13) & BM_PXP_WFA_ARRAY_PIXEL7_MASK_RSVD4)
+#define BP_PXP_WFA_ARRAY_PIXEL7_MASK_H_OFS 8
+#define BM_PXP_WFA_ARRAY_PIXEL7_MASK_H_OFS 0x00001F00
+#define BF_PXP_WFA_ARRAY_PIXEL7_MASK_H_OFS(v) \
+ (((v) << 8) & BM_PXP_WFA_ARRAY_PIXEL7_MASK_H_OFS)
+#define BP_PXP_WFA_ARRAY_PIXEL7_MASK_RSVD5 5
+#define BM_PXP_WFA_ARRAY_PIXEL7_MASK_RSVD5 0x000000E0
+#define BF_PXP_WFA_ARRAY_PIXEL7_MASK_RSVD5(v) \
+ (((v) << 5) & BM_PXP_WFA_ARRAY_PIXEL7_MASK_RSVD5)
+#define BP_PXP_WFA_ARRAY_PIXEL7_MASK_L_OFS 0
+#define BM_PXP_WFA_ARRAY_PIXEL7_MASK_L_OFS 0x0000001F
+#define BF_PXP_WFA_ARRAY_PIXEL7_MASK_L_OFS(v) \
+ (((v) << 0) & BM_PXP_WFA_ARRAY_PIXEL7_MASK_L_OFS)
+
+#define HW_PXP_WFA_ARRAY_FLAG0_MASK (0x00000d30)
+
+#define BP_PXP_WFA_ARRAY_FLAG0_MASK_RSVD0 30
+#define BM_PXP_WFA_ARRAY_FLAG0_MASK_RSVD0 0xC0000000
+#define BF_PXP_WFA_ARRAY_FLAG0_MASK_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFA_ARRAY_FLAG0_MASK_RSVD0)
+#define BP_PXP_WFA_ARRAY_FLAG0_MASK_BUF_SEL 28
+#define BM_PXP_WFA_ARRAY_FLAG0_MASK_BUF_SEL 0x30000000
+#define BF_PXP_WFA_ARRAY_FLAG0_MASK_BUF_SEL(v) \
+ (((v) << 28) & BM_PXP_WFA_ARRAY_FLAG0_MASK_BUF_SEL)
+#define BV_PXP_WFA_ARRAY_FLAG0_MASK_BUF_SEL__0 0x0
+#define BV_PXP_WFA_ARRAY_FLAG0_MASK_BUF_SEL__1 0x1
+#define BV_PXP_WFA_ARRAY_FLAG0_MASK_BUF_SEL__2 0x2
+#define BP_PXP_WFA_ARRAY_FLAG0_MASK_RSVD1 26
+#define BM_PXP_WFA_ARRAY_FLAG0_MASK_RSVD1 0x0C000000
+#define BF_PXP_WFA_ARRAY_FLAG0_MASK_RSVD1(v) \
+ (((v) << 26) & BM_PXP_WFA_ARRAY_FLAG0_MASK_RSVD1)
+#define BM_PXP_WFA_ARRAY_FLAG0_MASK_SIGN_Y 0x02000000
+#define BF_PXP_WFA_ARRAY_FLAG0_MASK_SIGN_Y(v) \
+ (((v) << 25) & BM_PXP_WFA_ARRAY_FLAG0_MASK_SIGN_Y)
+#define BV_PXP_WFA_ARRAY_FLAG0_MASK_SIGN_Y__0 0x0
+#define BV_PXP_WFA_ARRAY_FLAG0_MASK_SIGN_Y__1 0x1
+#define BM_PXP_WFA_ARRAY_FLAG0_MASK_SIGN_X 0x01000000
+#define BF_PXP_WFA_ARRAY_FLAG0_MASK_SIGN_X(v) \
+ (((v) << 24) & BM_PXP_WFA_ARRAY_FLAG0_MASK_SIGN_X)
+#define BV_PXP_WFA_ARRAY_FLAG0_MASK_SIGN_X__0 0x0
+#define BV_PXP_WFA_ARRAY_FLAG0_MASK_SIGN_X__1 0x1
+#define BP_PXP_WFA_ARRAY_FLAG0_MASK_RSVD2 22
+#define BM_PXP_WFA_ARRAY_FLAG0_MASK_RSVD2 0x00C00000
+#define BF_PXP_WFA_ARRAY_FLAG0_MASK_RSVD2(v) \
+ (((v) << 22) & BM_PXP_WFA_ARRAY_FLAG0_MASK_RSVD2)
+#define BP_PXP_WFA_ARRAY_FLAG0_MASK_OFFSET_Y 20
+#define BM_PXP_WFA_ARRAY_FLAG0_MASK_OFFSET_Y 0x00300000
+#define BF_PXP_WFA_ARRAY_FLAG0_MASK_OFFSET_Y(v) \
+ (((v) << 20) & BM_PXP_WFA_ARRAY_FLAG0_MASK_OFFSET_Y)
+#define BP_PXP_WFA_ARRAY_FLAG0_MASK_RSVD3 18
+#define BM_PXP_WFA_ARRAY_FLAG0_MASK_RSVD3 0x000C0000
+#define BF_PXP_WFA_ARRAY_FLAG0_MASK_RSVD3(v) \
+ (((v) << 18) & BM_PXP_WFA_ARRAY_FLAG0_MASK_RSVD3)
+#define BP_PXP_WFA_ARRAY_FLAG0_MASK_OFFSET_X 16
+#define BM_PXP_WFA_ARRAY_FLAG0_MASK_OFFSET_X 0x00030000
+#define BF_PXP_WFA_ARRAY_FLAG0_MASK_OFFSET_X(v) \
+ (((v) << 16) & BM_PXP_WFA_ARRAY_FLAG0_MASK_OFFSET_X)
+#define BP_PXP_WFA_ARRAY_FLAG0_MASK_RSVD4 13
+#define BM_PXP_WFA_ARRAY_FLAG0_MASK_RSVD4 0x0000E000
+#define BF_PXP_WFA_ARRAY_FLAG0_MASK_RSVD4(v) \
+ (((v) << 13) & BM_PXP_WFA_ARRAY_FLAG0_MASK_RSVD4)
+#define BP_PXP_WFA_ARRAY_FLAG0_MASK_H_OFS 8
+#define BM_PXP_WFA_ARRAY_FLAG0_MASK_H_OFS 0x00001F00
+#define BF_PXP_WFA_ARRAY_FLAG0_MASK_H_OFS(v) \
+ (((v) << 8) & BM_PXP_WFA_ARRAY_FLAG0_MASK_H_OFS)
+#define BP_PXP_WFA_ARRAY_FLAG0_MASK_RSVD5 5
+#define BM_PXP_WFA_ARRAY_FLAG0_MASK_RSVD5 0x000000E0
+#define BF_PXP_WFA_ARRAY_FLAG0_MASK_RSVD5(v) \
+ (((v) << 5) & BM_PXP_WFA_ARRAY_FLAG0_MASK_RSVD5)
+#define BP_PXP_WFA_ARRAY_FLAG0_MASK_L_OFS 0
+#define BM_PXP_WFA_ARRAY_FLAG0_MASK_L_OFS 0x0000001F
+#define BF_PXP_WFA_ARRAY_FLAG0_MASK_L_OFS(v) \
+ (((v) << 0) & BM_PXP_WFA_ARRAY_FLAG0_MASK_L_OFS)
+
+#define HW_PXP_WFA_ARRAY_FLAG1_MASK (0x00000d40)
+
+#define BP_PXP_WFA_ARRAY_FLAG1_MASK_RSVD0 30
+#define BM_PXP_WFA_ARRAY_FLAG1_MASK_RSVD0 0xC0000000
+#define BF_PXP_WFA_ARRAY_FLAG1_MASK_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFA_ARRAY_FLAG1_MASK_RSVD0)
+#define BP_PXP_WFA_ARRAY_FLAG1_MASK_BUF_SEL 28
+#define BM_PXP_WFA_ARRAY_FLAG1_MASK_BUF_SEL 0x30000000
+#define BF_PXP_WFA_ARRAY_FLAG1_MASK_BUF_SEL(v) \
+ (((v) << 28) & BM_PXP_WFA_ARRAY_FLAG1_MASK_BUF_SEL)
+#define BV_PXP_WFA_ARRAY_FLAG1_MASK_BUF_SEL__0 0x0
+#define BV_PXP_WFA_ARRAY_FLAG1_MASK_BUF_SEL__1 0x1
+#define BV_PXP_WFA_ARRAY_FLAG1_MASK_BUF_SEL__2 0x2
+#define BP_PXP_WFA_ARRAY_FLAG1_MASK_RSVD1 26
+#define BM_PXP_WFA_ARRAY_FLAG1_MASK_RSVD1 0x0C000000
+#define BF_PXP_WFA_ARRAY_FLAG1_MASK_RSVD1(v) \
+ (((v) << 26) & BM_PXP_WFA_ARRAY_FLAG1_MASK_RSVD1)
+#define BM_PXP_WFA_ARRAY_FLAG1_MASK_SIGN_Y 0x02000000
+#define BF_PXP_WFA_ARRAY_FLAG1_MASK_SIGN_Y(v) \
+ (((v) << 25) & BM_PXP_WFA_ARRAY_FLAG1_MASK_SIGN_Y)
+#define BV_PXP_WFA_ARRAY_FLAG1_MASK_SIGN_Y__0 0x0
+#define BV_PXP_WFA_ARRAY_FLAG1_MASK_SIGN_Y__1 0x1
+#define BM_PXP_WFA_ARRAY_FLAG1_MASK_SIGN_X 0x01000000
+#define BF_PXP_WFA_ARRAY_FLAG1_MASK_SIGN_X(v) \
+ (((v) << 24) & BM_PXP_WFA_ARRAY_FLAG1_MASK_SIGN_X)
+#define BV_PXP_WFA_ARRAY_FLAG1_MASK_SIGN_X__0 0x0
+#define BV_PXP_WFA_ARRAY_FLAG1_MASK_SIGN_X__1 0x1
+#define BP_PXP_WFA_ARRAY_FLAG1_MASK_RSVD2 22
+#define BM_PXP_WFA_ARRAY_FLAG1_MASK_RSVD2 0x00C00000
+#define BF_PXP_WFA_ARRAY_FLAG1_MASK_RSVD2(v) \
+ (((v) << 22) & BM_PXP_WFA_ARRAY_FLAG1_MASK_RSVD2)
+#define BP_PXP_WFA_ARRAY_FLAG1_MASK_OFFSET_Y 20
+#define BM_PXP_WFA_ARRAY_FLAG1_MASK_OFFSET_Y 0x00300000
+#define BF_PXP_WFA_ARRAY_FLAG1_MASK_OFFSET_Y(v) \
+ (((v) << 20) & BM_PXP_WFA_ARRAY_FLAG1_MASK_OFFSET_Y)
+#define BP_PXP_WFA_ARRAY_FLAG1_MASK_RSVD3 18
+#define BM_PXP_WFA_ARRAY_FLAG1_MASK_RSVD3 0x000C0000
+#define BF_PXP_WFA_ARRAY_FLAG1_MASK_RSVD3(v) \
+ (((v) << 18) & BM_PXP_WFA_ARRAY_FLAG1_MASK_RSVD3)
+#define BP_PXP_WFA_ARRAY_FLAG1_MASK_OFFSET_X 16
+#define BM_PXP_WFA_ARRAY_FLAG1_MASK_OFFSET_X 0x00030000
+#define BF_PXP_WFA_ARRAY_FLAG1_MASK_OFFSET_X(v) \
+ (((v) << 16) & BM_PXP_WFA_ARRAY_FLAG1_MASK_OFFSET_X)
+#define BP_PXP_WFA_ARRAY_FLAG1_MASK_RSVD4 13
+#define BM_PXP_WFA_ARRAY_FLAG1_MASK_RSVD4 0x0000E000
+#define BF_PXP_WFA_ARRAY_FLAG1_MASK_RSVD4(v) \
+ (((v) << 13) & BM_PXP_WFA_ARRAY_FLAG1_MASK_RSVD4)
+#define BP_PXP_WFA_ARRAY_FLAG1_MASK_H_OFS 8
+#define BM_PXP_WFA_ARRAY_FLAG1_MASK_H_OFS 0x00001F00
+#define BF_PXP_WFA_ARRAY_FLAG1_MASK_H_OFS(v) \
+ (((v) << 8) & BM_PXP_WFA_ARRAY_FLAG1_MASK_H_OFS)
+#define BP_PXP_WFA_ARRAY_FLAG1_MASK_RSVD5 5
+#define BM_PXP_WFA_ARRAY_FLAG1_MASK_RSVD5 0x000000E0
+#define BF_PXP_WFA_ARRAY_FLAG1_MASK_RSVD5(v) \
+ (((v) << 5) & BM_PXP_WFA_ARRAY_FLAG1_MASK_RSVD5)
+#define BP_PXP_WFA_ARRAY_FLAG1_MASK_L_OFS 0
+#define BM_PXP_WFA_ARRAY_FLAG1_MASK_L_OFS 0x0000001F
+#define BF_PXP_WFA_ARRAY_FLAG1_MASK_L_OFS(v) \
+ (((v) << 0) & BM_PXP_WFA_ARRAY_FLAG1_MASK_L_OFS)
+
+#define HW_PXP_WFA_ARRAY_FLAG2_MASK (0x00000d50)
+
+#define BP_PXP_WFA_ARRAY_FLAG2_MASK_RSVD0 30
+#define BM_PXP_WFA_ARRAY_FLAG2_MASK_RSVD0 0xC0000000
+#define BF_PXP_WFA_ARRAY_FLAG2_MASK_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFA_ARRAY_FLAG2_MASK_RSVD0)
+#define BP_PXP_WFA_ARRAY_FLAG2_MASK_BUF_SEL 28
+#define BM_PXP_WFA_ARRAY_FLAG2_MASK_BUF_SEL 0x30000000
+#define BF_PXP_WFA_ARRAY_FLAG2_MASK_BUF_SEL(v) \
+ (((v) << 28) & BM_PXP_WFA_ARRAY_FLAG2_MASK_BUF_SEL)
+#define BV_PXP_WFA_ARRAY_FLAG2_MASK_BUF_SEL__0 0x0
+#define BV_PXP_WFA_ARRAY_FLAG2_MASK_BUF_SEL__1 0x1
+#define BV_PXP_WFA_ARRAY_FLAG2_MASK_BUF_SEL__2 0x2
+#define BP_PXP_WFA_ARRAY_FLAG2_MASK_RSVD1 26
+#define BM_PXP_WFA_ARRAY_FLAG2_MASK_RSVD1 0x0C000000
+#define BF_PXP_WFA_ARRAY_FLAG2_MASK_RSVD1(v) \
+ (((v) << 26) & BM_PXP_WFA_ARRAY_FLAG2_MASK_RSVD1)
+#define BM_PXP_WFA_ARRAY_FLAG2_MASK_SIGN_Y 0x02000000
+#define BF_PXP_WFA_ARRAY_FLAG2_MASK_SIGN_Y(v) \
+ (((v) << 25) & BM_PXP_WFA_ARRAY_FLAG2_MASK_SIGN_Y)
+#define BV_PXP_WFA_ARRAY_FLAG2_MASK_SIGN_Y__0 0x0
+#define BV_PXP_WFA_ARRAY_FLAG2_MASK_SIGN_Y__1 0x1
+#define BM_PXP_WFA_ARRAY_FLAG2_MASK_SIGN_X 0x01000000
+#define BF_PXP_WFA_ARRAY_FLAG2_MASK_SIGN_X(v) \
+ (((v) << 24) & BM_PXP_WFA_ARRAY_FLAG2_MASK_SIGN_X)
+#define BV_PXP_WFA_ARRAY_FLAG2_MASK_SIGN_X__0 0x0
+#define BV_PXP_WFA_ARRAY_FLAG2_MASK_SIGN_X__1 0x1
+#define BP_PXP_WFA_ARRAY_FLAG2_MASK_RSVD2 22
+#define BM_PXP_WFA_ARRAY_FLAG2_MASK_RSVD2 0x00C00000
+#define BF_PXP_WFA_ARRAY_FLAG2_MASK_RSVD2(v) \
+ (((v) << 22) & BM_PXP_WFA_ARRAY_FLAG2_MASK_RSVD2)
+#define BP_PXP_WFA_ARRAY_FLAG2_MASK_OFFSET_Y 20
+#define BM_PXP_WFA_ARRAY_FLAG2_MASK_OFFSET_Y 0x00300000
+#define BF_PXP_WFA_ARRAY_FLAG2_MASK_OFFSET_Y(v) \
+ (((v) << 20) & BM_PXP_WFA_ARRAY_FLAG2_MASK_OFFSET_Y)
+#define BP_PXP_WFA_ARRAY_FLAG2_MASK_RSVD3 18
+#define BM_PXP_WFA_ARRAY_FLAG2_MASK_RSVD3 0x000C0000
+#define BF_PXP_WFA_ARRAY_FLAG2_MASK_RSVD3(v) \
+ (((v) << 18) & BM_PXP_WFA_ARRAY_FLAG2_MASK_RSVD3)
+#define BP_PXP_WFA_ARRAY_FLAG2_MASK_OFFSET_X 16
+#define BM_PXP_WFA_ARRAY_FLAG2_MASK_OFFSET_X 0x00030000
+#define BF_PXP_WFA_ARRAY_FLAG2_MASK_OFFSET_X(v) \
+ (((v) << 16) & BM_PXP_WFA_ARRAY_FLAG2_MASK_OFFSET_X)
+#define BP_PXP_WFA_ARRAY_FLAG2_MASK_RSVD4 13
+#define BM_PXP_WFA_ARRAY_FLAG2_MASK_RSVD4 0x0000E000
+#define BF_PXP_WFA_ARRAY_FLAG2_MASK_RSVD4(v) \
+ (((v) << 13) & BM_PXP_WFA_ARRAY_FLAG2_MASK_RSVD4)
+#define BP_PXP_WFA_ARRAY_FLAG2_MASK_H_OFS 8
+#define BM_PXP_WFA_ARRAY_FLAG2_MASK_H_OFS 0x00001F00
+#define BF_PXP_WFA_ARRAY_FLAG2_MASK_H_OFS(v) \
+ (((v) << 8) & BM_PXP_WFA_ARRAY_FLAG2_MASK_H_OFS)
+#define BP_PXP_WFA_ARRAY_FLAG2_MASK_RSVD5 5
+#define BM_PXP_WFA_ARRAY_FLAG2_MASK_RSVD5 0x000000E0
+#define BF_PXP_WFA_ARRAY_FLAG2_MASK_RSVD5(v) \
+ (((v) << 5) & BM_PXP_WFA_ARRAY_FLAG2_MASK_RSVD5)
+#define BP_PXP_WFA_ARRAY_FLAG2_MASK_L_OFS 0
+#define BM_PXP_WFA_ARRAY_FLAG2_MASK_L_OFS 0x0000001F
+#define BF_PXP_WFA_ARRAY_FLAG2_MASK_L_OFS(v) \
+ (((v) << 0) & BM_PXP_WFA_ARRAY_FLAG2_MASK_L_OFS)
+
+#define HW_PXP_WFA_ARRAY_FLAG3_MASK (0x00000d60)
+
+#define BP_PXP_WFA_ARRAY_FLAG3_MASK_RSVD0 30
+#define BM_PXP_WFA_ARRAY_FLAG3_MASK_RSVD0 0xC0000000
+#define BF_PXP_WFA_ARRAY_FLAG3_MASK_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFA_ARRAY_FLAG3_MASK_RSVD0)
+#define BP_PXP_WFA_ARRAY_FLAG3_MASK_BUF_SEL 28
+#define BM_PXP_WFA_ARRAY_FLAG3_MASK_BUF_SEL 0x30000000
+#define BF_PXP_WFA_ARRAY_FLAG3_MASK_BUF_SEL(v) \
+ (((v) << 28) & BM_PXP_WFA_ARRAY_FLAG3_MASK_BUF_SEL)
+#define BV_PXP_WFA_ARRAY_FLAG3_MASK_BUF_SEL__0 0x0
+#define BV_PXP_WFA_ARRAY_FLAG3_MASK_BUF_SEL__1 0x1
+#define BV_PXP_WFA_ARRAY_FLAG3_MASK_BUF_SEL__2 0x2
+#define BP_PXP_WFA_ARRAY_FLAG3_MASK_RSVD1 26
+#define BM_PXP_WFA_ARRAY_FLAG3_MASK_RSVD1 0x0C000000
+#define BF_PXP_WFA_ARRAY_FLAG3_MASK_RSVD1(v) \
+ (((v) << 26) & BM_PXP_WFA_ARRAY_FLAG3_MASK_RSVD1)
+#define BM_PXP_WFA_ARRAY_FLAG3_MASK_SIGN_Y 0x02000000
+#define BF_PXP_WFA_ARRAY_FLAG3_MASK_SIGN_Y(v) \
+ (((v) << 25) & BM_PXP_WFA_ARRAY_FLAG3_MASK_SIGN_Y)
+#define BV_PXP_WFA_ARRAY_FLAG3_MASK_SIGN_Y__0 0x0
+#define BV_PXP_WFA_ARRAY_FLAG3_MASK_SIGN_Y__1 0x1
+#define BM_PXP_WFA_ARRAY_FLAG3_MASK_SIGN_X 0x01000000
+#define BF_PXP_WFA_ARRAY_FLAG3_MASK_SIGN_X(v) \
+ (((v) << 24) & BM_PXP_WFA_ARRAY_FLAG3_MASK_SIGN_X)
+#define BV_PXP_WFA_ARRAY_FLAG3_MASK_SIGN_X__0 0x0
+#define BV_PXP_WFA_ARRAY_FLAG3_MASK_SIGN_X__1 0x1
+#define BP_PXP_WFA_ARRAY_FLAG3_MASK_RSVD2 22
+#define BM_PXP_WFA_ARRAY_FLAG3_MASK_RSVD2 0x00C00000
+#define BF_PXP_WFA_ARRAY_FLAG3_MASK_RSVD2(v) \
+ (((v) << 22) & BM_PXP_WFA_ARRAY_FLAG3_MASK_RSVD2)
+#define BP_PXP_WFA_ARRAY_FLAG3_MASK_OFFSET_Y 20
+#define BM_PXP_WFA_ARRAY_FLAG3_MASK_OFFSET_Y 0x00300000
+#define BF_PXP_WFA_ARRAY_FLAG3_MASK_OFFSET_Y(v) \
+ (((v) << 20) & BM_PXP_WFA_ARRAY_FLAG3_MASK_OFFSET_Y)
+#define BP_PXP_WFA_ARRAY_FLAG3_MASK_RSVD3 18
+#define BM_PXP_WFA_ARRAY_FLAG3_MASK_RSVD3 0x000C0000
+#define BF_PXP_WFA_ARRAY_FLAG3_MASK_RSVD3(v) \
+ (((v) << 18) & BM_PXP_WFA_ARRAY_FLAG3_MASK_RSVD3)
+#define BP_PXP_WFA_ARRAY_FLAG3_MASK_OFFSET_X 16
+#define BM_PXP_WFA_ARRAY_FLAG3_MASK_OFFSET_X 0x00030000
+#define BF_PXP_WFA_ARRAY_FLAG3_MASK_OFFSET_X(v) \
+ (((v) << 16) & BM_PXP_WFA_ARRAY_FLAG3_MASK_OFFSET_X)
+#define BP_PXP_WFA_ARRAY_FLAG3_MASK_RSVD4 13
+#define BM_PXP_WFA_ARRAY_FLAG3_MASK_RSVD4 0x0000E000
+#define BF_PXP_WFA_ARRAY_FLAG3_MASK_RSVD4(v) \
+ (((v) << 13) & BM_PXP_WFA_ARRAY_FLAG3_MASK_RSVD4)
+#define BP_PXP_WFA_ARRAY_FLAG3_MASK_H_OFS 8
+#define BM_PXP_WFA_ARRAY_FLAG3_MASK_H_OFS 0x00001F00
+#define BF_PXP_WFA_ARRAY_FLAG3_MASK_H_OFS(v) \
+ (((v) << 8) & BM_PXP_WFA_ARRAY_FLAG3_MASK_H_OFS)
+#define BP_PXP_WFA_ARRAY_FLAG3_MASK_RSVD5 5
+#define BM_PXP_WFA_ARRAY_FLAG3_MASK_RSVD5 0x000000E0
+#define BF_PXP_WFA_ARRAY_FLAG3_MASK_RSVD5(v) \
+ (((v) << 5) & BM_PXP_WFA_ARRAY_FLAG3_MASK_RSVD5)
+#define BP_PXP_WFA_ARRAY_FLAG3_MASK_L_OFS 0
+#define BM_PXP_WFA_ARRAY_FLAG3_MASK_L_OFS 0x0000001F
+#define BF_PXP_WFA_ARRAY_FLAG3_MASK_L_OFS(v) \
+ (((v) << 0) & BM_PXP_WFA_ARRAY_FLAG3_MASK_L_OFS)
+
+#define HW_PXP_WFA_ARRAY_FLAG4_MASK (0x00000d70)
+
+#define BP_PXP_WFA_ARRAY_FLAG4_MASK_RSVD0 30
+#define BM_PXP_WFA_ARRAY_FLAG4_MASK_RSVD0 0xC0000000
+#define BF_PXP_WFA_ARRAY_FLAG4_MASK_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFA_ARRAY_FLAG4_MASK_RSVD0)
+#define BP_PXP_WFA_ARRAY_FLAG4_MASK_BUF_SEL 28
+#define BM_PXP_WFA_ARRAY_FLAG4_MASK_BUF_SEL 0x30000000
+#define BF_PXP_WFA_ARRAY_FLAG4_MASK_BUF_SEL(v) \
+ (((v) << 28) & BM_PXP_WFA_ARRAY_FLAG4_MASK_BUF_SEL)
+#define BV_PXP_WFA_ARRAY_FLAG4_MASK_BUF_SEL__0 0x0
+#define BV_PXP_WFA_ARRAY_FLAG4_MASK_BUF_SEL__1 0x1
+#define BV_PXP_WFA_ARRAY_FLAG4_MASK_BUF_SEL__2 0x2
+#define BP_PXP_WFA_ARRAY_FLAG4_MASK_RSVD1 26
+#define BM_PXP_WFA_ARRAY_FLAG4_MASK_RSVD1 0x0C000000
+#define BF_PXP_WFA_ARRAY_FLAG4_MASK_RSVD1(v) \
+ (((v) << 26) & BM_PXP_WFA_ARRAY_FLAG4_MASK_RSVD1)
+#define BM_PXP_WFA_ARRAY_FLAG4_MASK_SIGN_Y 0x02000000
+#define BF_PXP_WFA_ARRAY_FLAG4_MASK_SIGN_Y(v) \
+ (((v) << 25) & BM_PXP_WFA_ARRAY_FLAG4_MASK_SIGN_Y)
+#define BV_PXP_WFA_ARRAY_FLAG4_MASK_SIGN_Y__0 0x0
+#define BV_PXP_WFA_ARRAY_FLAG4_MASK_SIGN_Y__1 0x1
+#define BM_PXP_WFA_ARRAY_FLAG4_MASK_SIGN_X 0x01000000
+#define BF_PXP_WFA_ARRAY_FLAG4_MASK_SIGN_X(v) \
+ (((v) << 24) & BM_PXP_WFA_ARRAY_FLAG4_MASK_SIGN_X)
+#define BV_PXP_WFA_ARRAY_FLAG4_MASK_SIGN_X__0 0x0
+#define BV_PXP_WFA_ARRAY_FLAG4_MASK_SIGN_X__1 0x1
+#define BP_PXP_WFA_ARRAY_FLAG4_MASK_RSVD2 22
+#define BM_PXP_WFA_ARRAY_FLAG4_MASK_RSVD2 0x00C00000
+#define BF_PXP_WFA_ARRAY_FLAG4_MASK_RSVD2(v) \
+ (((v) << 22) & BM_PXP_WFA_ARRAY_FLAG4_MASK_RSVD2)
+#define BP_PXP_WFA_ARRAY_FLAG4_MASK_OFFSET_Y 20
+#define BM_PXP_WFA_ARRAY_FLAG4_MASK_OFFSET_Y 0x00300000
+#define BF_PXP_WFA_ARRAY_FLAG4_MASK_OFFSET_Y(v) \
+ (((v) << 20) & BM_PXP_WFA_ARRAY_FLAG4_MASK_OFFSET_Y)
+#define BP_PXP_WFA_ARRAY_FLAG4_MASK_RSVD3 18
+#define BM_PXP_WFA_ARRAY_FLAG4_MASK_RSVD3 0x000C0000
+#define BF_PXP_WFA_ARRAY_FLAG4_MASK_RSVD3(v) \
+ (((v) << 18) & BM_PXP_WFA_ARRAY_FLAG4_MASK_RSVD3)
+#define BP_PXP_WFA_ARRAY_FLAG4_MASK_OFFSET_X 16
+#define BM_PXP_WFA_ARRAY_FLAG4_MASK_OFFSET_X 0x00030000
+#define BF_PXP_WFA_ARRAY_FLAG4_MASK_OFFSET_X(v) \
+ (((v) << 16) & BM_PXP_WFA_ARRAY_FLAG4_MASK_OFFSET_X)
+#define BP_PXP_WFA_ARRAY_FLAG4_MASK_RSVD4 13
+#define BM_PXP_WFA_ARRAY_FLAG4_MASK_RSVD4 0x0000E000
+#define BF_PXP_WFA_ARRAY_FLAG4_MASK_RSVD4(v) \
+ (((v) << 13) & BM_PXP_WFA_ARRAY_FLAG4_MASK_RSVD4)
+#define BP_PXP_WFA_ARRAY_FLAG4_MASK_H_OFS 8
+#define BM_PXP_WFA_ARRAY_FLAG4_MASK_H_OFS 0x00001F00
+#define BF_PXP_WFA_ARRAY_FLAG4_MASK_H_OFS(v) \
+ (((v) << 8) & BM_PXP_WFA_ARRAY_FLAG4_MASK_H_OFS)
+#define BP_PXP_WFA_ARRAY_FLAG4_MASK_RSVD5 5
+#define BM_PXP_WFA_ARRAY_FLAG4_MASK_RSVD5 0x000000E0
+#define BF_PXP_WFA_ARRAY_FLAG4_MASK_RSVD5(v) \
+ (((v) << 5) & BM_PXP_WFA_ARRAY_FLAG4_MASK_RSVD5)
+#define BP_PXP_WFA_ARRAY_FLAG4_MASK_L_OFS 0
+#define BM_PXP_WFA_ARRAY_FLAG4_MASK_L_OFS 0x0000001F
+#define BF_PXP_WFA_ARRAY_FLAG4_MASK_L_OFS(v) \
+ (((v) << 0) & BM_PXP_WFA_ARRAY_FLAG4_MASK_L_OFS)
+
+#define HW_PXP_WFA_ARRAY_FLAG5_MASK (0x00000d80)
+
+#define BP_PXP_WFA_ARRAY_FLAG5_MASK_RSVD0 30
+#define BM_PXP_WFA_ARRAY_FLAG5_MASK_RSVD0 0xC0000000
+#define BF_PXP_WFA_ARRAY_FLAG5_MASK_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFA_ARRAY_FLAG5_MASK_RSVD0)
+#define BP_PXP_WFA_ARRAY_FLAG5_MASK_BUF_SEL 28
+#define BM_PXP_WFA_ARRAY_FLAG5_MASK_BUF_SEL 0x30000000
+#define BF_PXP_WFA_ARRAY_FLAG5_MASK_BUF_SEL(v) \
+ (((v) << 28) & BM_PXP_WFA_ARRAY_FLAG5_MASK_BUF_SEL)
+#define BV_PXP_WFA_ARRAY_FLAG5_MASK_BUF_SEL__0 0x0
+#define BV_PXP_WFA_ARRAY_FLAG5_MASK_BUF_SEL__1 0x1
+#define BV_PXP_WFA_ARRAY_FLAG5_MASK_BUF_SEL__2 0x2
+#define BP_PXP_WFA_ARRAY_FLAG5_MASK_RSVD1 26
+#define BM_PXP_WFA_ARRAY_FLAG5_MASK_RSVD1 0x0C000000
+#define BF_PXP_WFA_ARRAY_FLAG5_MASK_RSVD1(v) \
+ (((v) << 26) & BM_PXP_WFA_ARRAY_FLAG5_MASK_RSVD1)
+#define BM_PXP_WFA_ARRAY_FLAG5_MASK_SIGN_Y 0x02000000
+#define BF_PXP_WFA_ARRAY_FLAG5_MASK_SIGN_Y(v) \
+ (((v) << 25) & BM_PXP_WFA_ARRAY_FLAG5_MASK_SIGN_Y)
+#define BV_PXP_WFA_ARRAY_FLAG5_MASK_SIGN_Y__0 0x0
+#define BV_PXP_WFA_ARRAY_FLAG5_MASK_SIGN_Y__1 0x1
+#define BM_PXP_WFA_ARRAY_FLAG5_MASK_SIGN_X 0x01000000
+#define BF_PXP_WFA_ARRAY_FLAG5_MASK_SIGN_X(v) \
+ (((v) << 24) & BM_PXP_WFA_ARRAY_FLAG5_MASK_SIGN_X)
+#define BV_PXP_WFA_ARRAY_FLAG5_MASK_SIGN_X__0 0x0
+#define BV_PXP_WFA_ARRAY_FLAG5_MASK_SIGN_X__1 0x1
+#define BP_PXP_WFA_ARRAY_FLAG5_MASK_RSVD2 22
+#define BM_PXP_WFA_ARRAY_FLAG5_MASK_RSVD2 0x00C00000
+#define BF_PXP_WFA_ARRAY_FLAG5_MASK_RSVD2(v) \
+ (((v) << 22) & BM_PXP_WFA_ARRAY_FLAG5_MASK_RSVD2)
+#define BP_PXP_WFA_ARRAY_FLAG5_MASK_OFFSET_Y 20
+#define BM_PXP_WFA_ARRAY_FLAG5_MASK_OFFSET_Y 0x00300000
+#define BF_PXP_WFA_ARRAY_FLAG5_MASK_OFFSET_Y(v) \
+ (((v) << 20) & BM_PXP_WFA_ARRAY_FLAG5_MASK_OFFSET_Y)
+#define BP_PXP_WFA_ARRAY_FLAG5_MASK_RSVD3 18
+#define BM_PXP_WFA_ARRAY_FLAG5_MASK_RSVD3 0x000C0000
+#define BF_PXP_WFA_ARRAY_FLAG5_MASK_RSVD3(v) \
+ (((v) << 18) & BM_PXP_WFA_ARRAY_FLAG5_MASK_RSVD3)
+#define BP_PXP_WFA_ARRAY_FLAG5_MASK_OFFSET_X 16
+#define BM_PXP_WFA_ARRAY_FLAG5_MASK_OFFSET_X 0x00030000
+#define BF_PXP_WFA_ARRAY_FLAG5_MASK_OFFSET_X(v) \
+ (((v) << 16) & BM_PXP_WFA_ARRAY_FLAG5_MASK_OFFSET_X)
+#define BP_PXP_WFA_ARRAY_FLAG5_MASK_RSVD4 13
+#define BM_PXP_WFA_ARRAY_FLAG5_MASK_RSVD4 0x0000E000
+#define BF_PXP_WFA_ARRAY_FLAG5_MASK_RSVD4(v) \
+ (((v) << 13) & BM_PXP_WFA_ARRAY_FLAG5_MASK_RSVD4)
+#define BP_PXP_WFA_ARRAY_FLAG5_MASK_H_OFS 8
+#define BM_PXP_WFA_ARRAY_FLAG5_MASK_H_OFS 0x00001F00
+#define BF_PXP_WFA_ARRAY_FLAG5_MASK_H_OFS(v) \
+ (((v) << 8) & BM_PXP_WFA_ARRAY_FLAG5_MASK_H_OFS)
+#define BP_PXP_WFA_ARRAY_FLAG5_MASK_RSVD5 5
+#define BM_PXP_WFA_ARRAY_FLAG5_MASK_RSVD5 0x000000E0
+#define BF_PXP_WFA_ARRAY_FLAG5_MASK_RSVD5(v) \
+ (((v) << 5) & BM_PXP_WFA_ARRAY_FLAG5_MASK_RSVD5)
+#define BP_PXP_WFA_ARRAY_FLAG5_MASK_L_OFS 0
+#define BM_PXP_WFA_ARRAY_FLAG5_MASK_L_OFS 0x0000001F
+#define BF_PXP_WFA_ARRAY_FLAG5_MASK_L_OFS(v) \
+ (((v) << 0) & BM_PXP_WFA_ARRAY_FLAG5_MASK_L_OFS)
+
+#define HW_PXP_WFA_ARRAY_FLAG6_MASK (0x00000d90)
+
+#define BP_PXP_WFA_ARRAY_FLAG6_MASK_RSVD0 30
+#define BM_PXP_WFA_ARRAY_FLAG6_MASK_RSVD0 0xC0000000
+#define BF_PXP_WFA_ARRAY_FLAG6_MASK_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFA_ARRAY_FLAG6_MASK_RSVD0)
+#define BP_PXP_WFA_ARRAY_FLAG6_MASK_BUF_SEL 28
+#define BM_PXP_WFA_ARRAY_FLAG6_MASK_BUF_SEL 0x30000000
+#define BF_PXP_WFA_ARRAY_FLAG6_MASK_BUF_SEL(v) \
+ (((v) << 28) & BM_PXP_WFA_ARRAY_FLAG6_MASK_BUF_SEL)
+#define BV_PXP_WFA_ARRAY_FLAG6_MASK_BUF_SEL__0 0x0
+#define BV_PXP_WFA_ARRAY_FLAG6_MASK_BUF_SEL__1 0x1
+#define BV_PXP_WFA_ARRAY_FLAG6_MASK_BUF_SEL__2 0x2
+#define BP_PXP_WFA_ARRAY_FLAG6_MASK_RSVD1 26
+#define BM_PXP_WFA_ARRAY_FLAG6_MASK_RSVD1 0x0C000000
+#define BF_PXP_WFA_ARRAY_FLAG6_MASK_RSVD1(v) \
+ (((v) << 26) & BM_PXP_WFA_ARRAY_FLAG6_MASK_RSVD1)
+#define BM_PXP_WFA_ARRAY_FLAG6_MASK_SIGN_Y 0x02000000
+#define BF_PXP_WFA_ARRAY_FLAG6_MASK_SIGN_Y(v) \
+ (((v) << 25) & BM_PXP_WFA_ARRAY_FLAG6_MASK_SIGN_Y)
+#define BV_PXP_WFA_ARRAY_FLAG6_MASK_SIGN_Y__0 0x0
+#define BV_PXP_WFA_ARRAY_FLAG6_MASK_SIGN_Y__1 0x1
+#define BM_PXP_WFA_ARRAY_FLAG6_MASK_SIGN_X 0x01000000
+#define BF_PXP_WFA_ARRAY_FLAG6_MASK_SIGN_X(v) \
+ (((v) << 24) & BM_PXP_WFA_ARRAY_FLAG6_MASK_SIGN_X)
+#define BV_PXP_WFA_ARRAY_FLAG6_MASK_SIGN_X__0 0x0
+#define BV_PXP_WFA_ARRAY_FLAG6_MASK_SIGN_X__1 0x1
+#define BP_PXP_WFA_ARRAY_FLAG6_MASK_RSVD2 22
+#define BM_PXP_WFA_ARRAY_FLAG6_MASK_RSVD2 0x00C00000
+#define BF_PXP_WFA_ARRAY_FLAG6_MASK_RSVD2(v) \
+ (((v) << 22) & BM_PXP_WFA_ARRAY_FLAG6_MASK_RSVD2)
+#define BP_PXP_WFA_ARRAY_FLAG6_MASK_OFFSET_Y 20
+#define BM_PXP_WFA_ARRAY_FLAG6_MASK_OFFSET_Y 0x00300000
+#define BF_PXP_WFA_ARRAY_FLAG6_MASK_OFFSET_Y(v) \
+ (((v) << 20) & BM_PXP_WFA_ARRAY_FLAG6_MASK_OFFSET_Y)
+#define BP_PXP_WFA_ARRAY_FLAG6_MASK_RSVD3 18
+#define BM_PXP_WFA_ARRAY_FLAG6_MASK_RSVD3 0x000C0000
+#define BF_PXP_WFA_ARRAY_FLAG6_MASK_RSVD3(v) \
+ (((v) << 18) & BM_PXP_WFA_ARRAY_FLAG6_MASK_RSVD3)
+#define BP_PXP_WFA_ARRAY_FLAG6_MASK_OFFSET_X 16
+#define BM_PXP_WFA_ARRAY_FLAG6_MASK_OFFSET_X 0x00030000
+#define BF_PXP_WFA_ARRAY_FLAG6_MASK_OFFSET_X(v) \
+ (((v) << 16) & BM_PXP_WFA_ARRAY_FLAG6_MASK_OFFSET_X)
+#define BP_PXP_WFA_ARRAY_FLAG6_MASK_RSVD4 13
+#define BM_PXP_WFA_ARRAY_FLAG6_MASK_RSVD4 0x0000E000
+#define BF_PXP_WFA_ARRAY_FLAG6_MASK_RSVD4(v) \
+ (((v) << 13) & BM_PXP_WFA_ARRAY_FLAG6_MASK_RSVD4)
+#define BP_PXP_WFA_ARRAY_FLAG6_MASK_H_OFS 8
+#define BM_PXP_WFA_ARRAY_FLAG6_MASK_H_OFS 0x00001F00
+#define BF_PXP_WFA_ARRAY_FLAG6_MASK_H_OFS(v) \
+ (((v) << 8) & BM_PXP_WFA_ARRAY_FLAG6_MASK_H_OFS)
+#define BP_PXP_WFA_ARRAY_FLAG6_MASK_RSVD5 5
+#define BM_PXP_WFA_ARRAY_FLAG6_MASK_RSVD5 0x000000E0
+#define BF_PXP_WFA_ARRAY_FLAG6_MASK_RSVD5(v) \
+ (((v) << 5) & BM_PXP_WFA_ARRAY_FLAG6_MASK_RSVD5)
+#define BP_PXP_WFA_ARRAY_FLAG6_MASK_L_OFS 0
+#define BM_PXP_WFA_ARRAY_FLAG6_MASK_L_OFS 0x0000001F
+#define BF_PXP_WFA_ARRAY_FLAG6_MASK_L_OFS(v) \
+ (((v) << 0) & BM_PXP_WFA_ARRAY_FLAG6_MASK_L_OFS)
+
+#define HW_PXP_WFA_ARRAY_FLAG7_MASK (0x00000da0)
+
+#define BP_PXP_WFA_ARRAY_FLAG7_MASK_RSVD0 30
+#define BM_PXP_WFA_ARRAY_FLAG7_MASK_RSVD0 0xC0000000
+#define BF_PXP_WFA_ARRAY_FLAG7_MASK_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFA_ARRAY_FLAG7_MASK_RSVD0)
+#define BP_PXP_WFA_ARRAY_FLAG7_MASK_BUF_SEL 28
+#define BM_PXP_WFA_ARRAY_FLAG7_MASK_BUF_SEL 0x30000000
+#define BF_PXP_WFA_ARRAY_FLAG7_MASK_BUF_SEL(v) \
+ (((v) << 28) & BM_PXP_WFA_ARRAY_FLAG7_MASK_BUF_SEL)
+#define BV_PXP_WFA_ARRAY_FLAG7_MASK_BUF_SEL__0 0x0
+#define BV_PXP_WFA_ARRAY_FLAG7_MASK_BUF_SEL__1 0x1
+#define BV_PXP_WFA_ARRAY_FLAG7_MASK_BUF_SEL__2 0x2
+#define BP_PXP_WFA_ARRAY_FLAG7_MASK_RSVD1 26
+#define BM_PXP_WFA_ARRAY_FLAG7_MASK_RSVD1 0x0C000000
+#define BF_PXP_WFA_ARRAY_FLAG7_MASK_RSVD1(v) \
+ (((v) << 26) & BM_PXP_WFA_ARRAY_FLAG7_MASK_RSVD1)
+#define BM_PXP_WFA_ARRAY_FLAG7_MASK_SIGN_Y 0x02000000
+#define BF_PXP_WFA_ARRAY_FLAG7_MASK_SIGN_Y(v) \
+ (((v) << 25) & BM_PXP_WFA_ARRAY_FLAG7_MASK_SIGN_Y)
+#define BV_PXP_WFA_ARRAY_FLAG7_MASK_SIGN_Y__0 0x0
+#define BV_PXP_WFA_ARRAY_FLAG7_MASK_SIGN_Y__1 0x1
+#define BM_PXP_WFA_ARRAY_FLAG7_MASK_SIGN_X 0x01000000
+#define BF_PXP_WFA_ARRAY_FLAG7_MASK_SIGN_X(v) \
+ (((v) << 24) & BM_PXP_WFA_ARRAY_FLAG7_MASK_SIGN_X)
+#define BV_PXP_WFA_ARRAY_FLAG7_MASK_SIGN_X__0 0x0
+#define BV_PXP_WFA_ARRAY_FLAG7_MASK_SIGN_X__1 0x1
+#define BP_PXP_WFA_ARRAY_FLAG7_MASK_RSVD2 22
+#define BM_PXP_WFA_ARRAY_FLAG7_MASK_RSVD2 0x00C00000
+#define BF_PXP_WFA_ARRAY_FLAG7_MASK_RSVD2(v) \
+ (((v) << 22) & BM_PXP_WFA_ARRAY_FLAG7_MASK_RSVD2)
+#define BP_PXP_WFA_ARRAY_FLAG7_MASK_OFFSET_Y 20
+#define BM_PXP_WFA_ARRAY_FLAG7_MASK_OFFSET_Y 0x00300000
+#define BF_PXP_WFA_ARRAY_FLAG7_MASK_OFFSET_Y(v) \
+ (((v) << 20) & BM_PXP_WFA_ARRAY_FLAG7_MASK_OFFSET_Y)
+#define BP_PXP_WFA_ARRAY_FLAG7_MASK_RSVD3 18
+#define BM_PXP_WFA_ARRAY_FLAG7_MASK_RSVD3 0x000C0000
+#define BF_PXP_WFA_ARRAY_FLAG7_MASK_RSVD3(v) \
+ (((v) << 18) & BM_PXP_WFA_ARRAY_FLAG7_MASK_RSVD3)
+#define BP_PXP_WFA_ARRAY_FLAG7_MASK_OFFSET_X 16
+#define BM_PXP_WFA_ARRAY_FLAG7_MASK_OFFSET_X 0x00030000
+#define BF_PXP_WFA_ARRAY_FLAG7_MASK_OFFSET_X(v) \
+ (((v) << 16) & BM_PXP_WFA_ARRAY_FLAG7_MASK_OFFSET_X)
+#define BP_PXP_WFA_ARRAY_FLAG7_MASK_RSVD4 13
+#define BM_PXP_WFA_ARRAY_FLAG7_MASK_RSVD4 0x0000E000
+#define BF_PXP_WFA_ARRAY_FLAG7_MASK_RSVD4(v) \
+ (((v) << 13) & BM_PXP_WFA_ARRAY_FLAG7_MASK_RSVD4)
+#define BP_PXP_WFA_ARRAY_FLAG7_MASK_H_OFS 8
+#define BM_PXP_WFA_ARRAY_FLAG7_MASK_H_OFS 0x00001F00
+#define BF_PXP_WFA_ARRAY_FLAG7_MASK_H_OFS(v) \
+ (((v) << 8) & BM_PXP_WFA_ARRAY_FLAG7_MASK_H_OFS)
+#define BP_PXP_WFA_ARRAY_FLAG7_MASK_RSVD5 5
+#define BM_PXP_WFA_ARRAY_FLAG7_MASK_RSVD5 0x000000E0
+#define BF_PXP_WFA_ARRAY_FLAG7_MASK_RSVD5(v) \
+ (((v) << 5) & BM_PXP_WFA_ARRAY_FLAG7_MASK_RSVD5)
+#define BP_PXP_WFA_ARRAY_FLAG7_MASK_L_OFS 0
+#define BM_PXP_WFA_ARRAY_FLAG7_MASK_L_OFS 0x0000001F
+#define BF_PXP_WFA_ARRAY_FLAG7_MASK_L_OFS(v) \
+ (((v) << 0) & BM_PXP_WFA_ARRAY_FLAG7_MASK_L_OFS)
+
+#define HW_PXP_WFA_FETCH_BUF1_CORD (0x00000db0)
+
+#define BP_PXP_WFA_FETCH_BUF1_CORD_RSVD0 30
+#define BM_PXP_WFA_FETCH_BUF1_CORD_RSVD0 0xC0000000
+#define BF_PXP_WFA_FETCH_BUF1_CORD_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFA_FETCH_BUF1_CORD_RSVD0)
+#define BP_PXP_WFA_FETCH_BUF1_CORD_YCORD 16
+#define BM_PXP_WFA_FETCH_BUF1_CORD_YCORD 0x3FFF0000
+#define BF_PXP_WFA_FETCH_BUF1_CORD_YCORD(v) \
+ (((v) << 16) & BM_PXP_WFA_FETCH_BUF1_CORD_YCORD)
+#define BP_PXP_WFA_FETCH_BUF1_CORD_RSVD1 14
+#define BM_PXP_WFA_FETCH_BUF1_CORD_RSVD1 0x0000C000
+#define BF_PXP_WFA_FETCH_BUF1_CORD_RSVD1(v) \
+ (((v) << 14) & BM_PXP_WFA_FETCH_BUF1_CORD_RSVD1)
+#define BP_PXP_WFA_FETCH_BUF1_CORD_XCORD 0
+#define BM_PXP_WFA_FETCH_BUF1_CORD_XCORD 0x00003FFF
+#define BF_PXP_WFA_FETCH_BUF1_CORD_XCORD(v) \
+ (((v) << 0) & BM_PXP_WFA_FETCH_BUF1_CORD_XCORD)
+
+#define HW_PXP_WFA_FETCH_BUF2_CORD (0x00000dc0)
+
+#define BP_PXP_WFA_FETCH_BUF2_CORD_RSVD0 30
+#define BM_PXP_WFA_FETCH_BUF2_CORD_RSVD0 0xC0000000
+#define BF_PXP_WFA_FETCH_BUF2_CORD_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFA_FETCH_BUF2_CORD_RSVD0)
+#define BP_PXP_WFA_FETCH_BUF2_CORD_YCORD 16
+#define BM_PXP_WFA_FETCH_BUF2_CORD_YCORD 0x3FFF0000
+#define BF_PXP_WFA_FETCH_BUF2_CORD_YCORD(v) \
+ (((v) << 16) & BM_PXP_WFA_FETCH_BUF2_CORD_YCORD)
+#define BP_PXP_WFA_FETCH_BUF2_CORD_RSVD1 14
+#define BM_PXP_WFA_FETCH_BUF2_CORD_RSVD1 0x0000C000
+#define BF_PXP_WFA_FETCH_BUF2_CORD_RSVD1(v) \
+ (((v) << 14) & BM_PXP_WFA_FETCH_BUF2_CORD_RSVD1)
+#define BP_PXP_WFA_FETCH_BUF2_CORD_XCORD 0
+#define BM_PXP_WFA_FETCH_BUF2_CORD_XCORD 0x00003FFF
+#define BF_PXP_WFA_FETCH_BUF2_CORD_XCORD(v) \
+ (((v) << 0) & BM_PXP_WFA_FETCH_BUF2_CORD_XCORD)
+
+#define HW_PXP_WFA_ARRAY_FLAG8_MASK (0x00000dd0)
+
+#define BP_PXP_WFA_ARRAY_FLAG8_MASK_RSVD0 30
+#define BM_PXP_WFA_ARRAY_FLAG8_MASK_RSVD0 0xC0000000
+#define BF_PXP_WFA_ARRAY_FLAG8_MASK_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFA_ARRAY_FLAG8_MASK_RSVD0)
+#define BP_PXP_WFA_ARRAY_FLAG8_MASK_BUF_SEL 28
+#define BM_PXP_WFA_ARRAY_FLAG8_MASK_BUF_SEL 0x30000000
+#define BF_PXP_WFA_ARRAY_FLAG8_MASK_BUF_SEL(v) \
+ (((v) << 28) & BM_PXP_WFA_ARRAY_FLAG8_MASK_BUF_SEL)
+#define BV_PXP_WFA_ARRAY_FLAG8_MASK_BUF_SEL__0 0x0
+#define BV_PXP_WFA_ARRAY_FLAG8_MASK_BUF_SEL__1 0x1
+#define BV_PXP_WFA_ARRAY_FLAG8_MASK_BUF_SEL__2 0x2
+#define BP_PXP_WFA_ARRAY_FLAG8_MASK_RSVD1 26
+#define BM_PXP_WFA_ARRAY_FLAG8_MASK_RSVD1 0x0C000000
+#define BF_PXP_WFA_ARRAY_FLAG8_MASK_RSVD1(v) \
+ (((v) << 26) & BM_PXP_WFA_ARRAY_FLAG8_MASK_RSVD1)
+#define BM_PXP_WFA_ARRAY_FLAG8_MASK_SIGN_Y 0x02000000
+#define BF_PXP_WFA_ARRAY_FLAG8_MASK_SIGN_Y(v) \
+ (((v) << 25) & BM_PXP_WFA_ARRAY_FLAG8_MASK_SIGN_Y)
+#define BV_PXP_WFA_ARRAY_FLAG8_MASK_SIGN_Y__0 0x0
+#define BV_PXP_WFA_ARRAY_FLAG8_MASK_SIGN_Y__1 0x1
+#define BM_PXP_WFA_ARRAY_FLAG8_MASK_SIGN_X 0x01000000
+#define BF_PXP_WFA_ARRAY_FLAG8_MASK_SIGN_X(v) \
+ (((v) << 24) & BM_PXP_WFA_ARRAY_FLAG8_MASK_SIGN_X)
+#define BV_PXP_WFA_ARRAY_FLAG8_MASK_SIGN_X__0 0x0
+#define BV_PXP_WFA_ARRAY_FLAG8_MASK_SIGN_X__1 0x1
+#define BP_PXP_WFA_ARRAY_FLAG8_MASK_RSVD2 22
+#define BM_PXP_WFA_ARRAY_FLAG8_MASK_RSVD2 0x00C00000
+#define BF_PXP_WFA_ARRAY_FLAG8_MASK_RSVD2(v) \
+ (((v) << 22) & BM_PXP_WFA_ARRAY_FLAG8_MASK_RSVD2)
+#define BP_PXP_WFA_ARRAY_FLAG8_MASK_OFFSET_Y 20
+#define BM_PXP_WFA_ARRAY_FLAG8_MASK_OFFSET_Y 0x00300000
+#define BF_PXP_WFA_ARRAY_FLAG8_MASK_OFFSET_Y(v) \
+ (((v) << 20) & BM_PXP_WFA_ARRAY_FLAG8_MASK_OFFSET_Y)
+#define BP_PXP_WFA_ARRAY_FLAG8_MASK_RSVD3 18
+#define BM_PXP_WFA_ARRAY_FLAG8_MASK_RSVD3 0x000C0000
+#define BF_PXP_WFA_ARRAY_FLAG8_MASK_RSVD3(v) \
+ (((v) << 18) & BM_PXP_WFA_ARRAY_FLAG8_MASK_RSVD3)
+#define BP_PXP_WFA_ARRAY_FLAG8_MASK_OFFSET_X 16
+#define BM_PXP_WFA_ARRAY_FLAG8_MASK_OFFSET_X 0x00030000
+#define BF_PXP_WFA_ARRAY_FLAG8_MASK_OFFSET_X(v) \
+ (((v) << 16) & BM_PXP_WFA_ARRAY_FLAG8_MASK_OFFSET_X)
+#define BP_PXP_WFA_ARRAY_FLAG8_MASK_RSVD4 13
+#define BM_PXP_WFA_ARRAY_FLAG8_MASK_RSVD4 0x0000E000
+#define BF_PXP_WFA_ARRAY_FLAG8_MASK_RSVD4(v) \
+ (((v) << 13) & BM_PXP_WFA_ARRAY_FLAG8_MASK_RSVD4)
+#define BP_PXP_WFA_ARRAY_FLAG8_MASK_H_OFS 8
+#define BM_PXP_WFA_ARRAY_FLAG8_MASK_H_OFS 0x00001F00
+#define BF_PXP_WFA_ARRAY_FLAG8_MASK_H_OFS(v) \
+ (((v) << 8) & BM_PXP_WFA_ARRAY_FLAG8_MASK_H_OFS)
+#define BP_PXP_WFA_ARRAY_FLAG8_MASK_RSVD5 5
+#define BM_PXP_WFA_ARRAY_FLAG8_MASK_RSVD5 0x000000E0
+#define BF_PXP_WFA_ARRAY_FLAG8_MASK_RSVD5(v) \
+ (((v) << 5) & BM_PXP_WFA_ARRAY_FLAG8_MASK_RSVD5)
+#define BP_PXP_WFA_ARRAY_FLAG8_MASK_L_OFS 0
+#define BM_PXP_WFA_ARRAY_FLAG8_MASK_L_OFS 0x0000001F
+#define BF_PXP_WFA_ARRAY_FLAG8_MASK_L_OFS(v) \
+ (((v) << 0) & BM_PXP_WFA_ARRAY_FLAG8_MASK_L_OFS)
+
+#define HW_PXP_WFA_ARRAY_FLAG9_MASK (0x00000de0)
+
+#define BP_PXP_WFA_ARRAY_FLAG9_MASK_RSVD0 30
+#define BM_PXP_WFA_ARRAY_FLAG9_MASK_RSVD0 0xC0000000
+#define BF_PXP_WFA_ARRAY_FLAG9_MASK_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFA_ARRAY_FLAG9_MASK_RSVD0)
+#define BP_PXP_WFA_ARRAY_FLAG9_MASK_BUF_SEL 28
+#define BM_PXP_WFA_ARRAY_FLAG9_MASK_BUF_SEL 0x30000000
+#define BF_PXP_WFA_ARRAY_FLAG9_MASK_BUF_SEL(v) \
+ (((v) << 28) & BM_PXP_WFA_ARRAY_FLAG9_MASK_BUF_SEL)
+#define BV_PXP_WFA_ARRAY_FLAG9_MASK_BUF_SEL__0 0x0
+#define BV_PXP_WFA_ARRAY_FLAG9_MASK_BUF_SEL__1 0x1
+#define BV_PXP_WFA_ARRAY_FLAG9_MASK_BUF_SEL__2 0x2
+#define BP_PXP_WFA_ARRAY_FLAG9_MASK_RSVD1 26
+#define BM_PXP_WFA_ARRAY_FLAG9_MASK_RSVD1 0x0C000000
+#define BF_PXP_WFA_ARRAY_FLAG9_MASK_RSVD1(v) \
+ (((v) << 26) & BM_PXP_WFA_ARRAY_FLAG9_MASK_RSVD1)
+#define BM_PXP_WFA_ARRAY_FLAG9_MASK_SIGN_Y 0x02000000
+#define BF_PXP_WFA_ARRAY_FLAG9_MASK_SIGN_Y(v) \
+ (((v) << 25) & BM_PXP_WFA_ARRAY_FLAG9_MASK_SIGN_Y)
+#define BV_PXP_WFA_ARRAY_FLAG9_MASK_SIGN_Y__0 0x0
+#define BV_PXP_WFA_ARRAY_FLAG9_MASK_SIGN_Y__1 0x1
+#define BM_PXP_WFA_ARRAY_FLAG9_MASK_SIGN_X 0x01000000
+#define BF_PXP_WFA_ARRAY_FLAG9_MASK_SIGN_X(v) \
+ (((v) << 24) & BM_PXP_WFA_ARRAY_FLAG9_MASK_SIGN_X)
+#define BV_PXP_WFA_ARRAY_FLAG9_MASK_SIGN_X__0 0x0
+#define BV_PXP_WFA_ARRAY_FLAG9_MASK_SIGN_X__1 0x1
+#define BP_PXP_WFA_ARRAY_FLAG9_MASK_RSVD2 22
+#define BM_PXP_WFA_ARRAY_FLAG9_MASK_RSVD2 0x00C00000
+#define BF_PXP_WFA_ARRAY_FLAG9_MASK_RSVD2(v) \
+ (((v) << 22) & BM_PXP_WFA_ARRAY_FLAG9_MASK_RSVD2)
+#define BP_PXP_WFA_ARRAY_FLAG9_MASK_OFFSET_Y 20
+#define BM_PXP_WFA_ARRAY_FLAG9_MASK_OFFSET_Y 0x00300000
+#define BF_PXP_WFA_ARRAY_FLAG9_MASK_OFFSET_Y(v) \
+ (((v) << 20) & BM_PXP_WFA_ARRAY_FLAG9_MASK_OFFSET_Y)
+#define BP_PXP_WFA_ARRAY_FLAG9_MASK_RSVD3 18
+#define BM_PXP_WFA_ARRAY_FLAG9_MASK_RSVD3 0x000C0000
+#define BF_PXP_WFA_ARRAY_FLAG9_MASK_RSVD3(v) \
+ (((v) << 18) & BM_PXP_WFA_ARRAY_FLAG9_MASK_RSVD3)
+#define BP_PXP_WFA_ARRAY_FLAG9_MASK_OFFSET_X 16
+#define BM_PXP_WFA_ARRAY_FLAG9_MASK_OFFSET_X 0x00030000
+#define BF_PXP_WFA_ARRAY_FLAG9_MASK_OFFSET_X(v) \
+ (((v) << 16) & BM_PXP_WFA_ARRAY_FLAG9_MASK_OFFSET_X)
+#define BP_PXP_WFA_ARRAY_FLAG9_MASK_RSVD4 13
+#define BM_PXP_WFA_ARRAY_FLAG9_MASK_RSVD4 0x0000E000
+#define BF_PXP_WFA_ARRAY_FLAG9_MASK_RSVD4(v) \
+ (((v) << 13) & BM_PXP_WFA_ARRAY_FLAG9_MASK_RSVD4)
+#define BP_PXP_WFA_ARRAY_FLAG9_MASK_H_OFS 8
+#define BM_PXP_WFA_ARRAY_FLAG9_MASK_H_OFS 0x00001F00
+#define BF_PXP_WFA_ARRAY_FLAG9_MASK_H_OFS(v) \
+ (((v) << 8) & BM_PXP_WFA_ARRAY_FLAG9_MASK_H_OFS)
+#define BP_PXP_WFA_ARRAY_FLAG9_MASK_RSVD5 5
+#define BM_PXP_WFA_ARRAY_FLAG9_MASK_RSVD5 0x000000E0
+#define BF_PXP_WFA_ARRAY_FLAG9_MASK_RSVD5(v) \
+ (((v) << 5) & BM_PXP_WFA_ARRAY_FLAG9_MASK_RSVD5)
+#define BP_PXP_WFA_ARRAY_FLAG9_MASK_L_OFS 0
+#define BM_PXP_WFA_ARRAY_FLAG9_MASK_L_OFS 0x0000001F
+#define BF_PXP_WFA_ARRAY_FLAG9_MASK_L_OFS(v) \
+ (((v) << 0) & BM_PXP_WFA_ARRAY_FLAG9_MASK_L_OFS)
+
+#define HW_PXP_WFA_ARRAY_FLAG10_MASK (0x00000df0)
+
+#define BP_PXP_WFA_ARRAY_FLAG10_MASK_RSVD0 30
+#define BM_PXP_WFA_ARRAY_FLAG10_MASK_RSVD0 0xC0000000
+#define BF_PXP_WFA_ARRAY_FLAG10_MASK_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFA_ARRAY_FLAG10_MASK_RSVD0)
+#define BP_PXP_WFA_ARRAY_FLAG10_MASK_BUF_SEL 28
+#define BM_PXP_WFA_ARRAY_FLAG10_MASK_BUF_SEL 0x30000000
+#define BF_PXP_WFA_ARRAY_FLAG10_MASK_BUF_SEL(v) \
+ (((v) << 28) & BM_PXP_WFA_ARRAY_FLAG10_MASK_BUF_SEL)
+#define BV_PXP_WFA_ARRAY_FLAG10_MASK_BUF_SEL__0 0x0
+#define BV_PXP_WFA_ARRAY_FLAG10_MASK_BUF_SEL__1 0x1
+#define BV_PXP_WFA_ARRAY_FLAG10_MASK_BUF_SEL__2 0x2
+#define BP_PXP_WFA_ARRAY_FLAG10_MASK_RSVD1 26
+#define BM_PXP_WFA_ARRAY_FLAG10_MASK_RSVD1 0x0C000000
+#define BF_PXP_WFA_ARRAY_FLAG10_MASK_RSVD1(v) \
+ (((v) << 26) & BM_PXP_WFA_ARRAY_FLAG10_MASK_RSVD1)
+#define BM_PXP_WFA_ARRAY_FLAG10_MASK_SIGN_Y 0x02000000
+#define BF_PXP_WFA_ARRAY_FLAG10_MASK_SIGN_Y(v) \
+ (((v) << 25) & BM_PXP_WFA_ARRAY_FLAG10_MASK_SIGN_Y)
+#define BV_PXP_WFA_ARRAY_FLAG10_MASK_SIGN_Y__0 0x0
+#define BV_PXP_WFA_ARRAY_FLAG10_MASK_SIGN_Y__1 0x1
+#define BM_PXP_WFA_ARRAY_FLAG10_MASK_SIGN_X 0x01000000
+#define BF_PXP_WFA_ARRAY_FLAG10_MASK_SIGN_X(v) \
+ (((v) << 24) & BM_PXP_WFA_ARRAY_FLAG10_MASK_SIGN_X)
+#define BV_PXP_WFA_ARRAY_FLAG10_MASK_SIGN_X__0 0x0
+#define BV_PXP_WFA_ARRAY_FLAG10_MASK_SIGN_X__1 0x1
+#define BP_PXP_WFA_ARRAY_FLAG10_MASK_RSVD2 22
+#define BM_PXP_WFA_ARRAY_FLAG10_MASK_RSVD2 0x00C00000
+#define BF_PXP_WFA_ARRAY_FLAG10_MASK_RSVD2(v) \
+ (((v) << 22) & BM_PXP_WFA_ARRAY_FLAG10_MASK_RSVD2)
+#define BP_PXP_WFA_ARRAY_FLAG10_MASK_OFFSET_Y 20
+#define BM_PXP_WFA_ARRAY_FLAG10_MASK_OFFSET_Y 0x00300000
+#define BF_PXP_WFA_ARRAY_FLAG10_MASK_OFFSET_Y(v) \
+ (((v) << 20) & BM_PXP_WFA_ARRAY_FLAG10_MASK_OFFSET_Y)
+#define BP_PXP_WFA_ARRAY_FLAG10_MASK_RSVD3 18
+#define BM_PXP_WFA_ARRAY_FLAG10_MASK_RSVD3 0x000C0000
+#define BF_PXP_WFA_ARRAY_FLAG10_MASK_RSVD3(v) \
+ (((v) << 18) & BM_PXP_WFA_ARRAY_FLAG10_MASK_RSVD3)
+#define BP_PXP_WFA_ARRAY_FLAG10_MASK_OFFSET_X 16
+#define BM_PXP_WFA_ARRAY_FLAG10_MASK_OFFSET_X 0x00030000
+#define BF_PXP_WFA_ARRAY_FLAG10_MASK_OFFSET_X(v) \
+ (((v) << 16) & BM_PXP_WFA_ARRAY_FLAG10_MASK_OFFSET_X)
+#define BP_PXP_WFA_ARRAY_FLAG10_MASK_RSVD4 13
+#define BM_PXP_WFA_ARRAY_FLAG10_MASK_RSVD4 0x0000E000
+#define BF_PXP_WFA_ARRAY_FLAG10_MASK_RSVD4(v) \
+ (((v) << 13) & BM_PXP_WFA_ARRAY_FLAG10_MASK_RSVD4)
+#define BP_PXP_WFA_ARRAY_FLAG10_MASK_H_OFS 8
+#define BM_PXP_WFA_ARRAY_FLAG10_MASK_H_OFS 0x00001F00
+#define BF_PXP_WFA_ARRAY_FLAG10_MASK_H_OFS(v) \
+ (((v) << 8) & BM_PXP_WFA_ARRAY_FLAG10_MASK_H_OFS)
+#define BP_PXP_WFA_ARRAY_FLAG10_MASK_RSVD5 5
+#define BM_PXP_WFA_ARRAY_FLAG10_MASK_RSVD5 0x000000E0
+#define BF_PXP_WFA_ARRAY_FLAG10_MASK_RSVD5(v) \
+ (((v) << 5) & BM_PXP_WFA_ARRAY_FLAG10_MASK_RSVD5)
+#define BP_PXP_WFA_ARRAY_FLAG10_MASK_L_OFS 0
+#define BM_PXP_WFA_ARRAY_FLAG10_MASK_L_OFS 0x0000001F
+#define BF_PXP_WFA_ARRAY_FLAG10_MASK_L_OFS(v) \
+ (((v) << 0) & BM_PXP_WFA_ARRAY_FLAG10_MASK_L_OFS)
+
+#define HW_PXP_WFA_ARRAY_FLAG11_MASK (0x00000e00)
+
+#define BP_PXP_WFA_ARRAY_FLAG11_MASK_RSVD0 30
+#define BM_PXP_WFA_ARRAY_FLAG11_MASK_RSVD0 0xC0000000
+#define BF_PXP_WFA_ARRAY_FLAG11_MASK_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFA_ARRAY_FLAG11_MASK_RSVD0)
+#define BP_PXP_WFA_ARRAY_FLAG11_MASK_BUF_SEL 28
+#define BM_PXP_WFA_ARRAY_FLAG11_MASK_BUF_SEL 0x30000000
+#define BF_PXP_WFA_ARRAY_FLAG11_MASK_BUF_SEL(v) \
+ (((v) << 28) & BM_PXP_WFA_ARRAY_FLAG11_MASK_BUF_SEL)
+#define BV_PXP_WFA_ARRAY_FLAG11_MASK_BUF_SEL__0 0x0
+#define BV_PXP_WFA_ARRAY_FLAG11_MASK_BUF_SEL__1 0x1
+#define BV_PXP_WFA_ARRAY_FLAG11_MASK_BUF_SEL__2 0x2
+#define BP_PXP_WFA_ARRAY_FLAG11_MASK_RSVD1 26
+#define BM_PXP_WFA_ARRAY_FLAG11_MASK_RSVD1 0x0C000000
+#define BF_PXP_WFA_ARRAY_FLAG11_MASK_RSVD1(v) \
+ (((v) << 26) & BM_PXP_WFA_ARRAY_FLAG11_MASK_RSVD1)
+#define BM_PXP_WFA_ARRAY_FLAG11_MASK_SIGN_Y 0x02000000
+#define BF_PXP_WFA_ARRAY_FLAG11_MASK_SIGN_Y(v) \
+ (((v) << 25) & BM_PXP_WFA_ARRAY_FLAG11_MASK_SIGN_Y)
+#define BV_PXP_WFA_ARRAY_FLAG11_MASK_SIGN_Y__0 0x0
+#define BV_PXP_WFA_ARRAY_FLAG11_MASK_SIGN_Y__1 0x1
+#define BM_PXP_WFA_ARRAY_FLAG11_MASK_SIGN_X 0x01000000
+#define BF_PXP_WFA_ARRAY_FLAG11_MASK_SIGN_X(v) \
+ (((v) << 24) & BM_PXP_WFA_ARRAY_FLAG11_MASK_SIGN_X)
+#define BV_PXP_WFA_ARRAY_FLAG11_MASK_SIGN_X__0 0x0
+#define BV_PXP_WFA_ARRAY_FLAG11_MASK_SIGN_X__1 0x1
+#define BP_PXP_WFA_ARRAY_FLAG11_MASK_RSVD2 22
+#define BM_PXP_WFA_ARRAY_FLAG11_MASK_RSVD2 0x00C00000
+#define BF_PXP_WFA_ARRAY_FLAG11_MASK_RSVD2(v) \
+ (((v) << 22) & BM_PXP_WFA_ARRAY_FLAG11_MASK_RSVD2)
+#define BP_PXP_WFA_ARRAY_FLAG11_MASK_OFFSET_Y 20
+#define BM_PXP_WFA_ARRAY_FLAG11_MASK_OFFSET_Y 0x00300000
+#define BF_PXP_WFA_ARRAY_FLAG11_MASK_OFFSET_Y(v) \
+ (((v) << 20) & BM_PXP_WFA_ARRAY_FLAG11_MASK_OFFSET_Y)
+#define BP_PXP_WFA_ARRAY_FLAG11_MASK_RSVD3 18
+#define BM_PXP_WFA_ARRAY_FLAG11_MASK_RSVD3 0x000C0000
+#define BF_PXP_WFA_ARRAY_FLAG11_MASK_RSVD3(v) \
+ (((v) << 18) & BM_PXP_WFA_ARRAY_FLAG11_MASK_RSVD3)
+#define BP_PXP_WFA_ARRAY_FLAG11_MASK_OFFSET_X 16
+#define BM_PXP_WFA_ARRAY_FLAG11_MASK_OFFSET_X 0x00030000
+#define BF_PXP_WFA_ARRAY_FLAG11_MASK_OFFSET_X(v) \
+ (((v) << 16) & BM_PXP_WFA_ARRAY_FLAG11_MASK_OFFSET_X)
+#define BP_PXP_WFA_ARRAY_FLAG11_MASK_RSVD4 13
+#define BM_PXP_WFA_ARRAY_FLAG11_MASK_RSVD4 0x0000E000
+#define BF_PXP_WFA_ARRAY_FLAG11_MASK_RSVD4(v) \
+ (((v) << 13) & BM_PXP_WFA_ARRAY_FLAG11_MASK_RSVD4)
+#define BP_PXP_WFA_ARRAY_FLAG11_MASK_H_OFS 8
+#define BM_PXP_WFA_ARRAY_FLAG11_MASK_H_OFS 0x00001F00
+#define BF_PXP_WFA_ARRAY_FLAG11_MASK_H_OFS(v) \
+ (((v) << 8) & BM_PXP_WFA_ARRAY_FLAG11_MASK_H_OFS)
+#define BP_PXP_WFA_ARRAY_FLAG11_MASK_RSVD5 5
+#define BM_PXP_WFA_ARRAY_FLAG11_MASK_RSVD5 0x000000E0
+#define BF_PXP_WFA_ARRAY_FLAG11_MASK_RSVD5(v) \
+ (((v) << 5) & BM_PXP_WFA_ARRAY_FLAG11_MASK_RSVD5)
+#define BP_PXP_WFA_ARRAY_FLAG11_MASK_L_OFS 0
+#define BM_PXP_WFA_ARRAY_FLAG11_MASK_L_OFS 0x0000001F
+#define BF_PXP_WFA_ARRAY_FLAG11_MASK_L_OFS(v) \
+ (((v) << 0) & BM_PXP_WFA_ARRAY_FLAG11_MASK_L_OFS)
+
+#define HW_PXP_WFA_ARRAY_FLAG12_MASK (0x00000e10)
+
+#define BP_PXP_WFA_ARRAY_FLAG12_MASK_RSVD0 30
+#define BM_PXP_WFA_ARRAY_FLAG12_MASK_RSVD0 0xC0000000
+#define BF_PXP_WFA_ARRAY_FLAG12_MASK_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFA_ARRAY_FLAG12_MASK_RSVD0)
+#define BP_PXP_WFA_ARRAY_FLAG12_MASK_BUF_SEL 28
+#define BM_PXP_WFA_ARRAY_FLAG12_MASK_BUF_SEL 0x30000000
+#define BF_PXP_WFA_ARRAY_FLAG12_MASK_BUF_SEL(v) \
+ (((v) << 28) & BM_PXP_WFA_ARRAY_FLAG12_MASK_BUF_SEL)
+#define BV_PXP_WFA_ARRAY_FLAG12_MASK_BUF_SEL__0 0x0
+#define BV_PXP_WFA_ARRAY_FLAG12_MASK_BUF_SEL__1 0x1
+#define BV_PXP_WFA_ARRAY_FLAG12_MASK_BUF_SEL__2 0x2
+#define BP_PXP_WFA_ARRAY_FLAG12_MASK_RSVD1 26
+#define BM_PXP_WFA_ARRAY_FLAG12_MASK_RSVD1 0x0C000000
+#define BF_PXP_WFA_ARRAY_FLAG12_MASK_RSVD1(v) \
+ (((v) << 26) & BM_PXP_WFA_ARRAY_FLAG12_MASK_RSVD1)
+#define BM_PXP_WFA_ARRAY_FLAG12_MASK_SIGN_Y 0x02000000
+#define BF_PXP_WFA_ARRAY_FLAG12_MASK_SIGN_Y(v) \
+ (((v) << 25) & BM_PXP_WFA_ARRAY_FLAG12_MASK_SIGN_Y)
+#define BV_PXP_WFA_ARRAY_FLAG12_MASK_SIGN_Y__0 0x0
+#define BV_PXP_WFA_ARRAY_FLAG12_MASK_SIGN_Y__1 0x1
+#define BM_PXP_WFA_ARRAY_FLAG12_MASK_SIGN_X 0x01000000
+#define BF_PXP_WFA_ARRAY_FLAG12_MASK_SIGN_X(v) \
+ (((v) << 24) & BM_PXP_WFA_ARRAY_FLAG12_MASK_SIGN_X)
+#define BV_PXP_WFA_ARRAY_FLAG12_MASK_SIGN_X__0 0x0
+#define BV_PXP_WFA_ARRAY_FLAG12_MASK_SIGN_X__1 0x1
+#define BP_PXP_WFA_ARRAY_FLAG12_MASK_RSVD2 22
+#define BM_PXP_WFA_ARRAY_FLAG12_MASK_RSVD2 0x00C00000
+#define BF_PXP_WFA_ARRAY_FLAG12_MASK_RSVD2(v) \
+ (((v) << 22) & BM_PXP_WFA_ARRAY_FLAG12_MASK_RSVD2)
+#define BP_PXP_WFA_ARRAY_FLAG12_MASK_OFFSET_Y 20
+#define BM_PXP_WFA_ARRAY_FLAG12_MASK_OFFSET_Y 0x00300000
+#define BF_PXP_WFA_ARRAY_FLAG12_MASK_OFFSET_Y(v) \
+ (((v) << 20) & BM_PXP_WFA_ARRAY_FLAG12_MASK_OFFSET_Y)
+#define BP_PXP_WFA_ARRAY_FLAG12_MASK_RSVD3 18
+#define BM_PXP_WFA_ARRAY_FLAG12_MASK_RSVD3 0x000C0000
+#define BF_PXP_WFA_ARRAY_FLAG12_MASK_RSVD3(v) \
+ (((v) << 18) & BM_PXP_WFA_ARRAY_FLAG12_MASK_RSVD3)
+#define BP_PXP_WFA_ARRAY_FLAG12_MASK_OFFSET_X 16
+#define BM_PXP_WFA_ARRAY_FLAG12_MASK_OFFSET_X 0x00030000
+#define BF_PXP_WFA_ARRAY_FLAG12_MASK_OFFSET_X(v) \
+ (((v) << 16) & BM_PXP_WFA_ARRAY_FLAG12_MASK_OFFSET_X)
+#define BP_PXP_WFA_ARRAY_FLAG12_MASK_RSVD4 13
+#define BM_PXP_WFA_ARRAY_FLAG12_MASK_RSVD4 0x0000E000
+#define BF_PXP_WFA_ARRAY_FLAG12_MASK_RSVD4(v) \
+ (((v) << 13) & BM_PXP_WFA_ARRAY_FLAG12_MASK_RSVD4)
+#define BP_PXP_WFA_ARRAY_FLAG12_MASK_H_OFS 8
+#define BM_PXP_WFA_ARRAY_FLAG12_MASK_H_OFS 0x00001F00
+#define BF_PXP_WFA_ARRAY_FLAG12_MASK_H_OFS(v) \
+ (((v) << 8) & BM_PXP_WFA_ARRAY_FLAG12_MASK_H_OFS)
+#define BP_PXP_WFA_ARRAY_FLAG12_MASK_RSVD5 5
+#define BM_PXP_WFA_ARRAY_FLAG12_MASK_RSVD5 0x000000E0
+#define BF_PXP_WFA_ARRAY_FLAG12_MASK_RSVD5(v) \
+ (((v) << 5) & BM_PXP_WFA_ARRAY_FLAG12_MASK_RSVD5)
+#define BP_PXP_WFA_ARRAY_FLAG12_MASK_L_OFS 0
+#define BM_PXP_WFA_ARRAY_FLAG12_MASK_L_OFS 0x0000001F
+#define BF_PXP_WFA_ARRAY_FLAG12_MASK_L_OFS(v) \
+ (((v) << 0) & BM_PXP_WFA_ARRAY_FLAG12_MASK_L_OFS)
+
+#define HW_PXP_WFA_ARRAY_FLAG13_MASK (0x00000e20)
+
+#define BP_PXP_WFA_ARRAY_FLAG13_MASK_RSVD0 30
+#define BM_PXP_WFA_ARRAY_FLAG13_MASK_RSVD0 0xC0000000
+#define BF_PXP_WFA_ARRAY_FLAG13_MASK_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFA_ARRAY_FLAG13_MASK_RSVD0)
+#define BP_PXP_WFA_ARRAY_FLAG13_MASK_BUF_SEL 28
+#define BM_PXP_WFA_ARRAY_FLAG13_MASK_BUF_SEL 0x30000000
+#define BF_PXP_WFA_ARRAY_FLAG13_MASK_BUF_SEL(v) \
+ (((v) << 28) & BM_PXP_WFA_ARRAY_FLAG13_MASK_BUF_SEL)
+#define BV_PXP_WFA_ARRAY_FLAG13_MASK_BUF_SEL__0 0x0
+#define BV_PXP_WFA_ARRAY_FLAG13_MASK_BUF_SEL__1 0x1
+#define BV_PXP_WFA_ARRAY_FLAG13_MASK_BUF_SEL__2 0x2
+#define BP_PXP_WFA_ARRAY_FLAG13_MASK_RSVD1 26
+#define BM_PXP_WFA_ARRAY_FLAG13_MASK_RSVD1 0x0C000000
+#define BF_PXP_WFA_ARRAY_FLAG13_MASK_RSVD1(v) \
+ (((v) << 26) & BM_PXP_WFA_ARRAY_FLAG13_MASK_RSVD1)
+#define BM_PXP_WFA_ARRAY_FLAG13_MASK_SIGN_Y 0x02000000
+#define BF_PXP_WFA_ARRAY_FLAG13_MASK_SIGN_Y(v) \
+ (((v) << 25) & BM_PXP_WFA_ARRAY_FLAG13_MASK_SIGN_Y)
+#define BV_PXP_WFA_ARRAY_FLAG13_MASK_SIGN_Y__0 0x0
+#define BV_PXP_WFA_ARRAY_FLAG13_MASK_SIGN_Y__1 0x1
+#define BM_PXP_WFA_ARRAY_FLAG13_MASK_SIGN_X 0x01000000
+#define BF_PXP_WFA_ARRAY_FLAG13_MASK_SIGN_X(v) \
+ (((v) << 24) & BM_PXP_WFA_ARRAY_FLAG13_MASK_SIGN_X)
+#define BV_PXP_WFA_ARRAY_FLAG13_MASK_SIGN_X__0 0x0
+#define BV_PXP_WFA_ARRAY_FLAG13_MASK_SIGN_X__1 0x1
+#define BP_PXP_WFA_ARRAY_FLAG13_MASK_RSVD2 22
+#define BM_PXP_WFA_ARRAY_FLAG13_MASK_RSVD2 0x00C00000
+#define BF_PXP_WFA_ARRAY_FLAG13_MASK_RSVD2(v) \
+ (((v) << 22) & BM_PXP_WFA_ARRAY_FLAG13_MASK_RSVD2)
+#define BP_PXP_WFA_ARRAY_FLAG13_MASK_OFFSET_Y 20
+#define BM_PXP_WFA_ARRAY_FLAG13_MASK_OFFSET_Y 0x00300000
+#define BF_PXP_WFA_ARRAY_FLAG13_MASK_OFFSET_Y(v) \
+ (((v) << 20) & BM_PXP_WFA_ARRAY_FLAG13_MASK_OFFSET_Y)
+#define BP_PXP_WFA_ARRAY_FLAG13_MASK_RSVD3 18
+#define BM_PXP_WFA_ARRAY_FLAG13_MASK_RSVD3 0x000C0000
+#define BF_PXP_WFA_ARRAY_FLAG13_MASK_RSVD3(v) \
+ (((v) << 18) & BM_PXP_WFA_ARRAY_FLAG13_MASK_RSVD3)
+#define BP_PXP_WFA_ARRAY_FLAG13_MASK_OFFSET_X 16
+#define BM_PXP_WFA_ARRAY_FLAG13_MASK_OFFSET_X 0x00030000
+#define BF_PXP_WFA_ARRAY_FLAG13_MASK_OFFSET_X(v) \
+ (((v) << 16) & BM_PXP_WFA_ARRAY_FLAG13_MASK_OFFSET_X)
+#define BP_PXP_WFA_ARRAY_FLAG13_MASK_RSVD4 13
+#define BM_PXP_WFA_ARRAY_FLAG13_MASK_RSVD4 0x0000E000
+#define BF_PXP_WFA_ARRAY_FLAG13_MASK_RSVD4(v) \
+ (((v) << 13) & BM_PXP_WFA_ARRAY_FLAG13_MASK_RSVD4)
+#define BP_PXP_WFA_ARRAY_FLAG13_MASK_H_OFS 8
+#define BM_PXP_WFA_ARRAY_FLAG13_MASK_H_OFS 0x00001F00
+#define BF_PXP_WFA_ARRAY_FLAG13_MASK_H_OFS(v) \
+ (((v) << 8) & BM_PXP_WFA_ARRAY_FLAG13_MASK_H_OFS)
+#define BP_PXP_WFA_ARRAY_FLAG13_MASK_RSVD5 5
+#define BM_PXP_WFA_ARRAY_FLAG13_MASK_RSVD5 0x000000E0
+#define BF_PXP_WFA_ARRAY_FLAG13_MASK_RSVD5(v) \
+ (((v) << 5) & BM_PXP_WFA_ARRAY_FLAG13_MASK_RSVD5)
+#define BP_PXP_WFA_ARRAY_FLAG13_MASK_L_OFS 0
+#define BM_PXP_WFA_ARRAY_FLAG13_MASK_L_OFS 0x0000001F
+#define BF_PXP_WFA_ARRAY_FLAG13_MASK_L_OFS(v) \
+ (((v) << 0) & BM_PXP_WFA_ARRAY_FLAG13_MASK_L_OFS)
+
+#define HW_PXP_WFA_ARRAY_FLAG14_MASK (0x00000e30)
+
+#define BP_PXP_WFA_ARRAY_FLAG14_MASK_RSVD0 30
+#define BM_PXP_WFA_ARRAY_FLAG14_MASK_RSVD0 0xC0000000
+#define BF_PXP_WFA_ARRAY_FLAG14_MASK_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFA_ARRAY_FLAG14_MASK_RSVD0)
+#define BP_PXP_WFA_ARRAY_FLAG14_MASK_BUF_SEL 28
+#define BM_PXP_WFA_ARRAY_FLAG14_MASK_BUF_SEL 0x30000000
+#define BF_PXP_WFA_ARRAY_FLAG14_MASK_BUF_SEL(v) \
+ (((v) << 28) & BM_PXP_WFA_ARRAY_FLAG14_MASK_BUF_SEL)
+#define BV_PXP_WFA_ARRAY_FLAG14_MASK_BUF_SEL__0 0x0
+#define BV_PXP_WFA_ARRAY_FLAG14_MASK_BUF_SEL__1 0x1
+#define BV_PXP_WFA_ARRAY_FLAG14_MASK_BUF_SEL__2 0x2
+#define BP_PXP_WFA_ARRAY_FLAG14_MASK_RSVD1 26
+#define BM_PXP_WFA_ARRAY_FLAG14_MASK_RSVD1 0x0C000000
+#define BF_PXP_WFA_ARRAY_FLAG14_MASK_RSVD1(v) \
+ (((v) << 26) & BM_PXP_WFA_ARRAY_FLAG14_MASK_RSVD1)
+#define BM_PXP_WFA_ARRAY_FLAG14_MASK_SIGN_Y 0x02000000
+#define BF_PXP_WFA_ARRAY_FLAG14_MASK_SIGN_Y(v) \
+ (((v) << 25) & BM_PXP_WFA_ARRAY_FLAG14_MASK_SIGN_Y)
+#define BV_PXP_WFA_ARRAY_FLAG14_MASK_SIGN_Y__0 0x0
+#define BV_PXP_WFA_ARRAY_FLAG14_MASK_SIGN_Y__1 0x1
+#define BM_PXP_WFA_ARRAY_FLAG14_MASK_SIGN_X 0x01000000
+#define BF_PXP_WFA_ARRAY_FLAG14_MASK_SIGN_X(v) \
+ (((v) << 24) & BM_PXP_WFA_ARRAY_FLAG14_MASK_SIGN_X)
+#define BV_PXP_WFA_ARRAY_FLAG14_MASK_SIGN_X__0 0x0
+#define BV_PXP_WFA_ARRAY_FLAG14_MASK_SIGN_X__1 0x1
+#define BP_PXP_WFA_ARRAY_FLAG14_MASK_RSVD2 22
+#define BM_PXP_WFA_ARRAY_FLAG14_MASK_RSVD2 0x00C00000
+#define BF_PXP_WFA_ARRAY_FLAG14_MASK_RSVD2(v) \
+ (((v) << 22) & BM_PXP_WFA_ARRAY_FLAG14_MASK_RSVD2)
+#define BP_PXP_WFA_ARRAY_FLAG14_MASK_OFFSET_Y 20
+#define BM_PXP_WFA_ARRAY_FLAG14_MASK_OFFSET_Y 0x00300000
+#define BF_PXP_WFA_ARRAY_FLAG14_MASK_OFFSET_Y(v) \
+ (((v) << 20) & BM_PXP_WFA_ARRAY_FLAG14_MASK_OFFSET_Y)
+#define BP_PXP_WFA_ARRAY_FLAG14_MASK_RSVD3 18
+#define BM_PXP_WFA_ARRAY_FLAG14_MASK_RSVD3 0x000C0000
+#define BF_PXP_WFA_ARRAY_FLAG14_MASK_RSVD3(v) \
+ (((v) << 18) & BM_PXP_WFA_ARRAY_FLAG14_MASK_RSVD3)
+#define BP_PXP_WFA_ARRAY_FLAG14_MASK_OFFSET_X 16
+#define BM_PXP_WFA_ARRAY_FLAG14_MASK_OFFSET_X 0x00030000
+#define BF_PXP_WFA_ARRAY_FLAG14_MASK_OFFSET_X(v) \
+ (((v) << 16) & BM_PXP_WFA_ARRAY_FLAG14_MASK_OFFSET_X)
+#define BP_PXP_WFA_ARRAY_FLAG14_MASK_RSVD4 13
+#define BM_PXP_WFA_ARRAY_FLAG14_MASK_RSVD4 0x0000E000
+#define BF_PXP_WFA_ARRAY_FLAG14_MASK_RSVD4(v) \
+ (((v) << 13) & BM_PXP_WFA_ARRAY_FLAG14_MASK_RSVD4)
+#define BP_PXP_WFA_ARRAY_FLAG14_MASK_H_OFS 8
+#define BM_PXP_WFA_ARRAY_FLAG14_MASK_H_OFS 0x00001F00
+#define BF_PXP_WFA_ARRAY_FLAG14_MASK_H_OFS(v) \
+ (((v) << 8) & BM_PXP_WFA_ARRAY_FLAG14_MASK_H_OFS)
+#define BP_PXP_WFA_ARRAY_FLAG14_MASK_RSVD5 5
+#define BM_PXP_WFA_ARRAY_FLAG14_MASK_RSVD5 0x000000E0
+#define BF_PXP_WFA_ARRAY_FLAG14_MASK_RSVD5(v) \
+ (((v) << 5) & BM_PXP_WFA_ARRAY_FLAG14_MASK_RSVD5)
+#define BP_PXP_WFA_ARRAY_FLAG14_MASK_L_OFS 0
+#define BM_PXP_WFA_ARRAY_FLAG14_MASK_L_OFS 0x0000001F
+#define BF_PXP_WFA_ARRAY_FLAG14_MASK_L_OFS(v) \
+ (((v) << 0) & BM_PXP_WFA_ARRAY_FLAG14_MASK_L_OFS)
+
+#define HW_PXP_WFA_ARRAY_FLAG15_MASK (0x00000e40)
+
+#define BP_PXP_WFA_ARRAY_FLAG15_MASK_RSVD0 30
+#define BM_PXP_WFA_ARRAY_FLAG15_MASK_RSVD0 0xC0000000
+#define BF_PXP_WFA_ARRAY_FLAG15_MASK_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFA_ARRAY_FLAG15_MASK_RSVD0)
+#define BP_PXP_WFA_ARRAY_FLAG15_MASK_BUF_SEL 28
+#define BM_PXP_WFA_ARRAY_FLAG15_MASK_BUF_SEL 0x30000000
+#define BF_PXP_WFA_ARRAY_FLAG15_MASK_BUF_SEL(v) \
+ (((v) << 28) & BM_PXP_WFA_ARRAY_FLAG15_MASK_BUF_SEL)
+#define BV_PXP_WFA_ARRAY_FLAG15_MASK_BUF_SEL__0 0x0
+#define BV_PXP_WFA_ARRAY_FLAG15_MASK_BUF_SEL__1 0x1
+#define BV_PXP_WFA_ARRAY_FLAG15_MASK_BUF_SEL__2 0x2
+#define BP_PXP_WFA_ARRAY_FLAG15_MASK_RSVD1 26
+#define BM_PXP_WFA_ARRAY_FLAG15_MASK_RSVD1 0x0C000000
+#define BF_PXP_WFA_ARRAY_FLAG15_MASK_RSVD1(v) \
+ (((v) << 26) & BM_PXP_WFA_ARRAY_FLAG15_MASK_RSVD1)
+#define BM_PXP_WFA_ARRAY_FLAG15_MASK_SIGN_Y 0x02000000
+#define BF_PXP_WFA_ARRAY_FLAG15_MASK_SIGN_Y(v) \
+ (((v) << 25) & BM_PXP_WFA_ARRAY_FLAG15_MASK_SIGN_Y)
+#define BV_PXP_WFA_ARRAY_FLAG15_MASK_SIGN_Y__0 0x0
+#define BV_PXP_WFA_ARRAY_FLAG15_MASK_SIGN_Y__1 0x1
+#define BM_PXP_WFA_ARRAY_FLAG15_MASK_SIGN_X 0x01000000
+#define BF_PXP_WFA_ARRAY_FLAG15_MASK_SIGN_X(v) \
+ (((v) << 24) & BM_PXP_WFA_ARRAY_FLAG15_MASK_SIGN_X)
+#define BV_PXP_WFA_ARRAY_FLAG15_MASK_SIGN_X__0 0x0
+#define BV_PXP_WFA_ARRAY_FLAG15_MASK_SIGN_X__1 0x1
+#define BP_PXP_WFA_ARRAY_FLAG15_MASK_RSVD2 22
+#define BM_PXP_WFA_ARRAY_FLAG15_MASK_RSVD2 0x00C00000
+#define BF_PXP_WFA_ARRAY_FLAG15_MASK_RSVD2(v) \
+ (((v) << 22) & BM_PXP_WFA_ARRAY_FLAG15_MASK_RSVD2)
+#define BP_PXP_WFA_ARRAY_FLAG15_MASK_OFFSET_Y 20
+#define BM_PXP_WFA_ARRAY_FLAG15_MASK_OFFSET_Y 0x00300000
+#define BF_PXP_WFA_ARRAY_FLAG15_MASK_OFFSET_Y(v) \
+ (((v) << 20) & BM_PXP_WFA_ARRAY_FLAG15_MASK_OFFSET_Y)
+#define BP_PXP_WFA_ARRAY_FLAG15_MASK_RSVD3 18
+#define BM_PXP_WFA_ARRAY_FLAG15_MASK_RSVD3 0x000C0000
+#define BF_PXP_WFA_ARRAY_FLAG15_MASK_RSVD3(v) \
+ (((v) << 18) & BM_PXP_WFA_ARRAY_FLAG15_MASK_RSVD3)
+#define BP_PXP_WFA_ARRAY_FLAG15_MASK_OFFSET_X 16
+#define BM_PXP_WFA_ARRAY_FLAG15_MASK_OFFSET_X 0x00030000
+#define BF_PXP_WFA_ARRAY_FLAG15_MASK_OFFSET_X(v) \
+ (((v) << 16) & BM_PXP_WFA_ARRAY_FLAG15_MASK_OFFSET_X)
+#define BP_PXP_WFA_ARRAY_FLAG15_MASK_RSVD4 13
+#define BM_PXP_WFA_ARRAY_FLAG15_MASK_RSVD4 0x0000E000
+#define BF_PXP_WFA_ARRAY_FLAG15_MASK_RSVD4(v) \
+ (((v) << 13) & BM_PXP_WFA_ARRAY_FLAG15_MASK_RSVD4)
+#define BP_PXP_WFA_ARRAY_FLAG15_MASK_H_OFS 8
+#define BM_PXP_WFA_ARRAY_FLAG15_MASK_H_OFS 0x00001F00
+#define BF_PXP_WFA_ARRAY_FLAG15_MASK_H_OFS(v) \
+ (((v) << 8) & BM_PXP_WFA_ARRAY_FLAG15_MASK_H_OFS)
+#define BP_PXP_WFA_ARRAY_FLAG15_MASK_RSVD5 5
+#define BM_PXP_WFA_ARRAY_FLAG15_MASK_RSVD5 0x000000E0
+#define BF_PXP_WFA_ARRAY_FLAG15_MASK_RSVD5(v) \
+ (((v) << 5) & BM_PXP_WFA_ARRAY_FLAG15_MASK_RSVD5)
+#define BP_PXP_WFA_ARRAY_FLAG15_MASK_L_OFS 0
+#define BM_PXP_WFA_ARRAY_FLAG15_MASK_L_OFS 0x0000001F
+#define BF_PXP_WFA_ARRAY_FLAG15_MASK_L_OFS(v) \
+ (((v) << 0) & BM_PXP_WFA_ARRAY_FLAG15_MASK_L_OFS)
+
+#define HW_PXP_WFA_ARRAY_REG0 (0x00000e50)
+
+#define BP_PXP_WFA_ARRAY_REG0_SW_PIXLE3 24
+#define BM_PXP_WFA_ARRAY_REG0_SW_PIXLE3 0xFF000000
+#define BF_PXP_WFA_ARRAY_REG0_SW_PIXLE3(v) \
+ (((v) << 24) & BM_PXP_WFA_ARRAY_REG0_SW_PIXLE3)
+#define BP_PXP_WFA_ARRAY_REG0_SW_PIXLE2 16
+#define BM_PXP_WFA_ARRAY_REG0_SW_PIXLE2 0x00FF0000
+#define BF_PXP_WFA_ARRAY_REG0_SW_PIXLE2(v) \
+ (((v) << 16) & BM_PXP_WFA_ARRAY_REG0_SW_PIXLE2)
+#define BP_PXP_WFA_ARRAY_REG0_SW_PIXLE1 8
+#define BM_PXP_WFA_ARRAY_REG0_SW_PIXLE1 0x0000FF00
+#define BF_PXP_WFA_ARRAY_REG0_SW_PIXLE1(v) \
+ (((v) << 8) & BM_PXP_WFA_ARRAY_REG0_SW_PIXLE1)
+#define BP_PXP_WFA_ARRAY_REG0_SW_PIXLE0 0
+#define BM_PXP_WFA_ARRAY_REG0_SW_PIXLE0 0x000000FF
+#define BF_PXP_WFA_ARRAY_REG0_SW_PIXLE0(v) \
+ (((v) << 0) & BM_PXP_WFA_ARRAY_REG0_SW_PIXLE0)
+
+#define HW_PXP_WFA_ARRAY_REG1 (0x00000e60)
+
+#define BP_PXP_WFA_ARRAY_REG1_SW_PIXLE7 24
+#define BM_PXP_WFA_ARRAY_REG1_SW_PIXLE7 0xFF000000
+#define BF_PXP_WFA_ARRAY_REG1_SW_PIXLE7(v) \
+ (((v) << 24) & BM_PXP_WFA_ARRAY_REG1_SW_PIXLE7)
+#define BP_PXP_WFA_ARRAY_REG1_SW_PIXLE6 16
+#define BM_PXP_WFA_ARRAY_REG1_SW_PIXLE6 0x00FF0000
+#define BF_PXP_WFA_ARRAY_REG1_SW_PIXLE6(v) \
+ (((v) << 16) & BM_PXP_WFA_ARRAY_REG1_SW_PIXLE6)
+#define BP_PXP_WFA_ARRAY_REG1_SW_PIXLE5 8
+#define BM_PXP_WFA_ARRAY_REG1_SW_PIXLE5 0x0000FF00
+#define BF_PXP_WFA_ARRAY_REG1_SW_PIXLE5(v) \
+ (((v) << 8) & BM_PXP_WFA_ARRAY_REG1_SW_PIXLE5)
+#define BP_PXP_WFA_ARRAY_REG1_SW_PIXLE4 0
+#define BM_PXP_WFA_ARRAY_REG1_SW_PIXLE4 0x000000FF
+#define BF_PXP_WFA_ARRAY_REG1_SW_PIXLE4(v) \
+ (((v) << 0) & BM_PXP_WFA_ARRAY_REG1_SW_PIXLE4)
+
+#define HW_PXP_WFA_ARRAY_REG2 (0x00000e70)
+
+#define BP_PXP_WFA_ARRAY_REG2_RSVD0 16
+#define BM_PXP_WFA_ARRAY_REG2_RSVD0 0xFFFF0000
+#define BF_PXP_WFA_ARRAY_REG2_RSVD0(v) \
+ (((v) << 16) & BM_PXP_WFA_ARRAY_REG2_RSVD0)
+#define BM_PXP_WFA_ARRAY_REG2_SW_FLAG15 0x00008000
+#define BF_PXP_WFA_ARRAY_REG2_SW_FLAG15(v) \
+ (((v) << 15) & BM_PXP_WFA_ARRAY_REG2_SW_FLAG15)
+#define BM_PXP_WFA_ARRAY_REG2_SW_FLAG14 0x00004000
+#define BF_PXP_WFA_ARRAY_REG2_SW_FLAG14(v) \
+ (((v) << 14) & BM_PXP_WFA_ARRAY_REG2_SW_FLAG14)
+#define BM_PXP_WFA_ARRAY_REG2_SW_FLAG13 0x00002000
+#define BF_PXP_WFA_ARRAY_REG2_SW_FLAG13(v) \
+ (((v) << 13) & BM_PXP_WFA_ARRAY_REG2_SW_FLAG13)
+#define BM_PXP_WFA_ARRAY_REG2_SW_FLAG12 0x00001000
+#define BF_PXP_WFA_ARRAY_REG2_SW_FLAG12(v) \
+ (((v) << 12) & BM_PXP_WFA_ARRAY_REG2_SW_FLAG12)
+#define BM_PXP_WFA_ARRAY_REG2_SW_FLAG11 0x00000800
+#define BF_PXP_WFA_ARRAY_REG2_SW_FLAG11(v) \
+ (((v) << 11) & BM_PXP_WFA_ARRAY_REG2_SW_FLAG11)
+#define BM_PXP_WFA_ARRAY_REG2_SW_FLAG10 0x00000400
+#define BF_PXP_WFA_ARRAY_REG2_SW_FLAG10(v) \
+ (((v) << 10) & BM_PXP_WFA_ARRAY_REG2_SW_FLAG10)
+#define BM_PXP_WFA_ARRAY_REG2_SW_FLAG9 0x00000200
+#define BF_PXP_WFA_ARRAY_REG2_SW_FLAG9(v) \
+ (((v) << 9) & BM_PXP_WFA_ARRAY_REG2_SW_FLAG9)
+#define BM_PXP_WFA_ARRAY_REG2_SW_FLAG8 0x00000100
+#define BF_PXP_WFA_ARRAY_REG2_SW_FLAG8(v) \
+ (((v) << 8) & BM_PXP_WFA_ARRAY_REG2_SW_FLAG8)
+#define BM_PXP_WFA_ARRAY_REG2_SW_FLAG7 0x00000080
+#define BF_PXP_WFA_ARRAY_REG2_SW_FLAG7(v) \
+ (((v) << 7) & BM_PXP_WFA_ARRAY_REG2_SW_FLAG7)
+#define BM_PXP_WFA_ARRAY_REG2_SW_FLAG6 0x00000040
+#define BF_PXP_WFA_ARRAY_REG2_SW_FLAG6(v) \
+ (((v) << 6) & BM_PXP_WFA_ARRAY_REG2_SW_FLAG6)
+#define BM_PXP_WFA_ARRAY_REG2_SW_FLAG5 0x00000020
+#define BF_PXP_WFA_ARRAY_REG2_SW_FLAG5(v) \
+ (((v) << 5) & BM_PXP_WFA_ARRAY_REG2_SW_FLAG5)
+#define BM_PXP_WFA_ARRAY_REG2_SW_FLAG4 0x00000010
+#define BF_PXP_WFA_ARRAY_REG2_SW_FLAG4(v) \
+ (((v) << 4) & BM_PXP_WFA_ARRAY_REG2_SW_FLAG4)
+#define BM_PXP_WFA_ARRAY_REG2_SW_FLAG3 0x00000008
+#define BF_PXP_WFA_ARRAY_REG2_SW_FLAG3(v) \
+ (((v) << 3) & BM_PXP_WFA_ARRAY_REG2_SW_FLAG3)
+#define BM_PXP_WFA_ARRAY_REG2_SW_FLAG2 0x00000004
+#define BF_PXP_WFA_ARRAY_REG2_SW_FLAG2(v) \
+ (((v) << 2) & BM_PXP_WFA_ARRAY_REG2_SW_FLAG2)
+#define BM_PXP_WFA_ARRAY_REG2_SW_FLAG1 0x00000002
+#define BF_PXP_WFA_ARRAY_REG2_SW_FLAG1(v) \
+ (((v) << 1) & BM_PXP_WFA_ARRAY_REG2_SW_FLAG1)
+#define BM_PXP_WFA_ARRAY_REG2_SW_FLAG0 0x00000001
+#define BF_PXP_WFA_ARRAY_REG2_SW_FLAG0(v) \
+ (((v) << 0) & BM_PXP_WFA_ARRAY_REG2_SW_FLAG0)
+
+#define HW_PXP_WFE_A_STORE_CTRL_CH0 (0x00000e80)
+#define HW_PXP_WFE_A_STORE_CTRL_CH0_SET (0x00000e84)
+#define HW_PXP_WFE_A_STORE_CTRL_CH0_CLR (0x00000e88)
+#define HW_PXP_WFE_A_STORE_CTRL_CH0_TOG (0x00000e8c)
+
+#define BM_PXP_WFE_A_STORE_CTRL_CH0_ARBIT_EN 0x80000000
+#define BF_PXP_WFE_A_STORE_CTRL_CH0_ARBIT_EN(v) \
+ (((v) << 31) & BM_PXP_WFE_A_STORE_CTRL_CH0_ARBIT_EN)
+#define BV_PXP_WFE_A_STORE_CTRL_CH0_ARBIT_EN__0 0x0
+#define BV_PXP_WFE_A_STORE_CTRL_CH0_ARBIT_EN__1 0x1
+#define BP_PXP_WFE_A_STORE_CTRL_CH0_RSVD0 25
+#define BM_PXP_WFE_A_STORE_CTRL_CH0_RSVD0 0x7E000000
+#define BF_PXP_WFE_A_STORE_CTRL_CH0_RSVD0(v) \
+ (((v) << 25) & BM_PXP_WFE_A_STORE_CTRL_CH0_RSVD0)
+#define BM_PXP_WFE_A_STORE_CTRL_CH0_COMBINE_2CHANNEL 0x01000000
+#define BF_PXP_WFE_A_STORE_CTRL_CH0_COMBINE_2CHANNEL(v) \
+ (((v) << 24) & BM_PXP_WFE_A_STORE_CTRL_CH0_COMBINE_2CHANNEL)
+#define BV_PXP_WFE_A_STORE_CTRL_CH0_COMBINE_2CHANNEL__0 0x0
+#define BV_PXP_WFE_A_STORE_CTRL_CH0_COMBINE_2CHANNEL__1 0x1
+#define BP_PXP_WFE_A_STORE_CTRL_CH0_RSVD1 18
+#define BM_PXP_WFE_A_STORE_CTRL_CH0_RSVD1 0x00FC0000
+#define BF_PXP_WFE_A_STORE_CTRL_CH0_RSVD1(v) \
+ (((v) << 18) & BM_PXP_WFE_A_STORE_CTRL_CH0_RSVD1)
+#define BP_PXP_WFE_A_STORE_CTRL_CH0_WR_NUM_BYTES 16
+#define BM_PXP_WFE_A_STORE_CTRL_CH0_WR_NUM_BYTES 0x00030000
+#define BF_PXP_WFE_A_STORE_CTRL_CH0_WR_NUM_BYTES(v) \
+ (((v) << 16) & BM_PXP_WFE_A_STORE_CTRL_CH0_WR_NUM_BYTES)
+#define BV_PXP_WFE_A_STORE_CTRL_CH0_WR_NUM_BYTES__8_bytes 0x0
+#define BV_PXP_WFE_A_STORE_CTRL_CH0_WR_NUM_BYTES__16_bytes 0x1
+#define BV_PXP_WFE_A_STORE_CTRL_CH0_WR_NUM_BYTES__32_bytes 0x2
+#define BV_PXP_WFE_A_STORE_CTRL_CH0_WR_NUM_BYTES__64_bytes 0x3
+#define BP_PXP_WFE_A_STORE_CTRL_CH0_RSVD2 12
+#define BM_PXP_WFE_A_STORE_CTRL_CH0_RSVD2 0x0000F000
+#define BF_PXP_WFE_A_STORE_CTRL_CH0_RSVD2(v) \
+ (((v) << 12) & BM_PXP_WFE_A_STORE_CTRL_CH0_RSVD2)
+#define BM_PXP_WFE_A_STORE_CTRL_CH0_FILL_DATA_EN 0x00000800
+#define BF_PXP_WFE_A_STORE_CTRL_CH0_FILL_DATA_EN(v) \
+ (((v) << 11) & BM_PXP_WFE_A_STORE_CTRL_CH0_FILL_DATA_EN)
+#define BV_PXP_WFE_A_STORE_CTRL_CH0_FILL_DATA_EN__0 0x0
+#define BV_PXP_WFE_A_STORE_CTRL_CH0_FILL_DATA_EN__1 0x1
+#define BM_PXP_WFE_A_STORE_CTRL_CH0_PACK_IN_SEL 0x00000400
+#define BF_PXP_WFE_A_STORE_CTRL_CH0_PACK_IN_SEL(v) \
+ (((v) << 10) & BM_PXP_WFE_A_STORE_CTRL_CH0_PACK_IN_SEL)
+#define BV_PXP_WFE_A_STORE_CTRL_CH0_PACK_IN_SEL__0 0x0
+#define BV_PXP_WFE_A_STORE_CTRL_CH0_PACK_IN_SEL__1 0x1
+#define BM_PXP_WFE_A_STORE_CTRL_CH0_STORE_MEMORY_EN 0x00000200
+#define BF_PXP_WFE_A_STORE_CTRL_CH0_STORE_MEMORY_EN(v) \
+ (((v) << 9) & BM_PXP_WFE_A_STORE_CTRL_CH0_STORE_MEMORY_EN)
+#define BV_PXP_WFE_A_STORE_CTRL_CH0_STORE_MEMORY_EN__0 0x0
+#define BV_PXP_WFE_A_STORE_CTRL_CH0_STORE_MEMORY_EN__1 0x1
+#define BM_PXP_WFE_A_STORE_CTRL_CH0_STORE_BYPASS_EN 0x00000100
+#define BF_PXP_WFE_A_STORE_CTRL_CH0_STORE_BYPASS_EN(v) \
+ (((v) << 8) & BM_PXP_WFE_A_STORE_CTRL_CH0_STORE_BYPASS_EN)
+#define BV_PXP_WFE_A_STORE_CTRL_CH0_STORE_BYPASS_EN__0 0x0
+#define BV_PXP_WFE_A_STORE_CTRL_CH0_STORE_BYPASS_EN__1 0x1
+#define BM_PXP_WFE_A_STORE_CTRL_CH0_RSVD3 0x00000080
+#define BF_PXP_WFE_A_STORE_CTRL_CH0_RSVD3(v) \
+ (((v) << 7) & BM_PXP_WFE_A_STORE_CTRL_CH0_RSVD3)
+#define BP_PXP_WFE_A_STORE_CTRL_CH0_ARRAY_LINE_NUM 5
+#define BM_PXP_WFE_A_STORE_CTRL_CH0_ARRAY_LINE_NUM 0x00000060
+#define BF_PXP_WFE_A_STORE_CTRL_CH0_ARRAY_LINE_NUM(v) \
+ (((v) << 5) & BM_PXP_WFE_A_STORE_CTRL_CH0_ARRAY_LINE_NUM)
+#define BV_PXP_WFE_A_STORE_CTRL_CH0_ARRAY_LINE_NUM__0 0x0
+#define BV_PXP_WFE_A_STORE_CTRL_CH0_ARRAY_LINE_NUM__1 0x1
+#define BV_PXP_WFE_A_STORE_CTRL_CH0_ARRAY_LINE_NUM__2 0x2
+#define BV_PXP_WFE_A_STORE_CTRL_CH0_ARRAY_LINE_NUM__3 0x3
+#define BM_PXP_WFE_A_STORE_CTRL_CH0_ARRAY_EN 0x00000010
+#define BF_PXP_WFE_A_STORE_CTRL_CH0_ARRAY_EN(v) \
+ (((v) << 4) & BM_PXP_WFE_A_STORE_CTRL_CH0_ARRAY_EN)
+#define BV_PXP_WFE_A_STORE_CTRL_CH0_ARRAY_EN__0 0x0
+#define BV_PXP_WFE_A_STORE_CTRL_CH0_ARRAY_EN__1 0x1
+#define BM_PXP_WFE_A_STORE_CTRL_CH0_HANDSHAKE_EN 0x00000008
+#define BF_PXP_WFE_A_STORE_CTRL_CH0_HANDSHAKE_EN(v) \
+ (((v) << 3) & BM_PXP_WFE_A_STORE_CTRL_CH0_HANDSHAKE_EN)
+#define BV_PXP_WFE_A_STORE_CTRL_CH0_HANDSHAKE_EN__0 0x0
+#define BV_PXP_WFE_A_STORE_CTRL_CH0_HANDSHAKE_EN__1 0x1
+#define BM_PXP_WFE_A_STORE_CTRL_CH0_BLOCK_16 0x00000004
+#define BF_PXP_WFE_A_STORE_CTRL_CH0_BLOCK_16(v) \
+ (((v) << 2) & BM_PXP_WFE_A_STORE_CTRL_CH0_BLOCK_16)
+#define BV_PXP_WFE_A_STORE_CTRL_CH0_BLOCK_16__8x8 0x0
+#define BV_PXP_WFE_A_STORE_CTRL_CH0_BLOCK_16__16x16 0x1
+#define BM_PXP_WFE_A_STORE_CTRL_CH0_BLOCK_EN 0x00000002
+#define BF_PXP_WFE_A_STORE_CTRL_CH0_BLOCK_EN(v) \
+ (((v) << 1) & BM_PXP_WFE_A_STORE_CTRL_CH0_BLOCK_EN)
+#define BV_PXP_WFE_A_STORE_CTRL_CH0_BLOCK_EN__0 0x0
+#define BV_PXP_WFE_A_STORE_CTRL_CH0_BLOCK_EN__1 0x1
+#define BM_PXP_WFE_A_STORE_CTRL_CH0_CH_EN 0x00000001
+#define BF_PXP_WFE_A_STORE_CTRL_CH0_CH_EN(v) \
+ (((v) << 0) & BM_PXP_WFE_A_STORE_CTRL_CH0_CH_EN)
+#define BV_PXP_WFE_A_STORE_CTRL_CH0_CH_EN__0 0x0
+#define BV_PXP_WFE_A_STORE_CTRL_CH0_CH_EN__1 0x1
+
+#define HW_PXP_WFE_A_STORE_CTRL_CH1 (0x00000e90)
+#define HW_PXP_WFE_A_STORE_CTRL_CH1_SET (0x00000e94)
+#define HW_PXP_WFE_A_STORE_CTRL_CH1_CLR (0x00000e98)
+#define HW_PXP_WFE_A_STORE_CTRL_CH1_TOG (0x00000e9c)
+
+#define BP_PXP_WFE_A_STORE_CTRL_CH1_RSVD0 18
+#define BM_PXP_WFE_A_STORE_CTRL_CH1_RSVD0 0xFFFC0000
+#define BF_PXP_WFE_A_STORE_CTRL_CH1_RSVD0(v) \
+ (((v) << 18) & BM_PXP_WFE_A_STORE_CTRL_CH1_RSVD0)
+#define BP_PXP_WFE_A_STORE_CTRL_CH1_WR_NUM_BYTES 16
+#define BM_PXP_WFE_A_STORE_CTRL_CH1_WR_NUM_BYTES 0x00030000
+#define BF_PXP_WFE_A_STORE_CTRL_CH1_WR_NUM_BYTES(v) \
+ (((v) << 16) & BM_PXP_WFE_A_STORE_CTRL_CH1_WR_NUM_BYTES)
+#define BV_PXP_WFE_A_STORE_CTRL_CH1_WR_NUM_BYTES__8_bytes 0x0
+#define BV_PXP_WFE_A_STORE_CTRL_CH1_WR_NUM_BYTES__16_bytes 0x1
+#define BV_PXP_WFE_A_STORE_CTRL_CH1_WR_NUM_BYTES__32_bytes 0x2
+#define BV_PXP_WFE_A_STORE_CTRL_CH1_WR_NUM_BYTES__64_bytes 0x3
+#define BP_PXP_WFE_A_STORE_CTRL_CH1_RSVD1 11
+#define BM_PXP_WFE_A_STORE_CTRL_CH1_RSVD1 0x0000F800
+#define BF_PXP_WFE_A_STORE_CTRL_CH1_RSVD1(v) \
+ (((v) << 11) & BM_PXP_WFE_A_STORE_CTRL_CH1_RSVD1)
+#define BM_PXP_WFE_A_STORE_CTRL_CH1_PACK_IN_SEL 0x00000400
+#define BF_PXP_WFE_A_STORE_CTRL_CH1_PACK_IN_SEL(v) \
+ (((v) << 10) & BM_PXP_WFE_A_STORE_CTRL_CH1_PACK_IN_SEL)
+#define BV_PXP_WFE_A_STORE_CTRL_CH1_PACK_IN_SEL__0 0x0
+#define BV_PXP_WFE_A_STORE_CTRL_CH1_PACK_IN_SEL__1 0x1
+#define BM_PXP_WFE_A_STORE_CTRL_CH1_STORE_MEMORY_EN 0x00000200
+#define BF_PXP_WFE_A_STORE_CTRL_CH1_STORE_MEMORY_EN(v) \
+ (((v) << 9) & BM_PXP_WFE_A_STORE_CTRL_CH1_STORE_MEMORY_EN)
+#define BV_PXP_WFE_A_STORE_CTRL_CH1_STORE_MEMORY_EN__0 0x0
+#define BV_PXP_WFE_A_STORE_CTRL_CH1_STORE_MEMORY_EN__1 0x1
+#define BM_PXP_WFE_A_STORE_CTRL_CH1_STORE_BYPASS_EN 0x00000100
+#define BF_PXP_WFE_A_STORE_CTRL_CH1_STORE_BYPASS_EN(v) \
+ (((v) << 8) & BM_PXP_WFE_A_STORE_CTRL_CH1_STORE_BYPASS_EN)
+#define BV_PXP_WFE_A_STORE_CTRL_CH1_STORE_BYPASS_EN__0 0x0
+#define BV_PXP_WFE_A_STORE_CTRL_CH1_STORE_BYPASS_EN__1 0x1
+#define BM_PXP_WFE_A_STORE_CTRL_CH1_RSVD3 0x00000080
+#define BF_PXP_WFE_A_STORE_CTRL_CH1_RSVD3(v) \
+ (((v) << 7) & BM_PXP_WFE_A_STORE_CTRL_CH1_RSVD3)
+#define BP_PXP_WFE_A_STORE_CTRL_CH1_ARRAY_LINE_NUM 5
+#define BM_PXP_WFE_A_STORE_CTRL_CH1_ARRAY_LINE_NUM 0x00000060
+#define BF_PXP_WFE_A_STORE_CTRL_CH1_ARRAY_LINE_NUM(v) \
+ (((v) << 5) & BM_PXP_WFE_A_STORE_CTRL_CH1_ARRAY_LINE_NUM)
+#define BV_PXP_WFE_A_STORE_CTRL_CH1_ARRAY_LINE_NUM__0 0x0
+#define BV_PXP_WFE_A_STORE_CTRL_CH1_ARRAY_LINE_NUM__1 0x1
+#define BV_PXP_WFE_A_STORE_CTRL_CH1_ARRAY_LINE_NUM__2 0x2
+#define BV_PXP_WFE_A_STORE_CTRL_CH1_ARRAY_LINE_NUM__3 0x3
+#define BM_PXP_WFE_A_STORE_CTRL_CH1_ARRAY_EN 0x00000010
+#define BF_PXP_WFE_A_STORE_CTRL_CH1_ARRAY_EN(v) \
+ (((v) << 4) & BM_PXP_WFE_A_STORE_CTRL_CH1_ARRAY_EN)
+#define BV_PXP_WFE_A_STORE_CTRL_CH1_ARRAY_EN__0 0x0
+#define BV_PXP_WFE_A_STORE_CTRL_CH1_ARRAY_EN__1 0x1
+#define BM_PXP_WFE_A_STORE_CTRL_CH1_HANDSHAKE_EN 0x00000008
+#define BF_PXP_WFE_A_STORE_CTRL_CH1_HANDSHAKE_EN(v) \
+ (((v) << 3) & BM_PXP_WFE_A_STORE_CTRL_CH1_HANDSHAKE_EN)
+#define BV_PXP_WFE_A_STORE_CTRL_CH1_HANDSHAKE_EN__0 0x0
+#define BV_PXP_WFE_A_STORE_CTRL_CH1_HANDSHAKE_EN__1 0x1
+#define BM_PXP_WFE_A_STORE_CTRL_CH1_BLOCK_16 0x00000004
+#define BF_PXP_WFE_A_STORE_CTRL_CH1_BLOCK_16(v) \
+ (((v) << 2) & BM_PXP_WFE_A_STORE_CTRL_CH1_BLOCK_16)
+#define BV_PXP_WFE_A_STORE_CTRL_CH1_BLOCK_16__8x8 0x0
+#define BV_PXP_WFE_A_STORE_CTRL_CH1_BLOCK_16__16x16 0x1
+#define BM_PXP_WFE_A_STORE_CTRL_CH1_BLOCK_EN 0x00000002
+#define BF_PXP_WFE_A_STORE_CTRL_CH1_BLOCK_EN(v) \
+ (((v) << 1) & BM_PXP_WFE_A_STORE_CTRL_CH1_BLOCK_EN)
+#define BV_PXP_WFE_A_STORE_CTRL_CH1_BLOCK_EN__0 0x0
+#define BV_PXP_WFE_A_STORE_CTRL_CH1_BLOCK_EN__1 0x1
+#define BM_PXP_WFE_A_STORE_CTRL_CH1_CH_EN 0x00000001
+#define BF_PXP_WFE_A_STORE_CTRL_CH1_CH_EN(v) \
+ (((v) << 0) & BM_PXP_WFE_A_STORE_CTRL_CH1_CH_EN)
+#define BV_PXP_WFE_A_STORE_CTRL_CH1_CH_EN__0 0x0
+#define BV_PXP_WFE_A_STORE_CTRL_CH1_CH_EN__1 0x1
+
+#define HW_PXP_WFE_A_STORE_STATUS_CH0 (0x00000ea0)
+
+#define BP_PXP_WFE_A_STORE_STATUS_CH0_STORE_BLOCK_Y 16
+#define BM_PXP_WFE_A_STORE_STATUS_CH0_STORE_BLOCK_Y 0xFFFF0000
+#define BF_PXP_WFE_A_STORE_STATUS_CH0_STORE_BLOCK_Y(v) \
+ (((v) << 16) & BM_PXP_WFE_A_STORE_STATUS_CH0_STORE_BLOCK_Y)
+#define BP_PXP_WFE_A_STORE_STATUS_CH0_STORE_BLOCK_X 0
+#define BM_PXP_WFE_A_STORE_STATUS_CH0_STORE_BLOCK_X 0x0000FFFF
+#define BF_PXP_WFE_A_STORE_STATUS_CH0_STORE_BLOCK_X(v) \
+ (((v) << 0) & BM_PXP_WFE_A_STORE_STATUS_CH0_STORE_BLOCK_X)
+
+#define HW_PXP_WFE_A_STORE_STATUS_CH1 (0x00000eb0)
+
+#define BP_PXP_WFE_A_STORE_STATUS_CH1_STORE_BLOCK_Y 16
+#define BM_PXP_WFE_A_STORE_STATUS_CH1_STORE_BLOCK_Y 0xFFFF0000
+#define BF_PXP_WFE_A_STORE_STATUS_CH1_STORE_BLOCK_Y(v) \
+ (((v) << 16) & BM_PXP_WFE_A_STORE_STATUS_CH1_STORE_BLOCK_Y)
+#define BP_PXP_WFE_A_STORE_STATUS_CH1_STORE_BLOCK_X 0
+#define BM_PXP_WFE_A_STORE_STATUS_CH1_STORE_BLOCK_X 0x0000FFFF
+#define BF_PXP_WFE_A_STORE_STATUS_CH1_STORE_BLOCK_X(v) \
+ (((v) << 0) & BM_PXP_WFE_A_STORE_STATUS_CH1_STORE_BLOCK_X)
+
+#define HW_PXP_WFE_A_STORE_SIZE_CH0 (0x00000ec0)
+
+#define BP_PXP_WFE_A_STORE_SIZE_CH0_OUT_HEIGHT 16
+#define BM_PXP_WFE_A_STORE_SIZE_CH0_OUT_HEIGHT 0xFFFF0000
+#define BF_PXP_WFE_A_STORE_SIZE_CH0_OUT_HEIGHT(v) \
+ (((v) << 16) & BM_PXP_WFE_A_STORE_SIZE_CH0_OUT_HEIGHT)
+#define BP_PXP_WFE_A_STORE_SIZE_CH0_OUT_WIDTH 0
+#define BM_PXP_WFE_A_STORE_SIZE_CH0_OUT_WIDTH 0x0000FFFF
+#define BF_PXP_WFE_A_STORE_SIZE_CH0_OUT_WIDTH(v) \
+ (((v) << 0) & BM_PXP_WFE_A_STORE_SIZE_CH0_OUT_WIDTH)
+
+#define HW_PXP_WFE_A_STORE_SIZE_CH1 (0x00000ed0)
+
+#define BP_PXP_WFE_A_STORE_SIZE_CH1_OUT_HEIGHT 16
+#define BM_PXP_WFE_A_STORE_SIZE_CH1_OUT_HEIGHT 0xFFFF0000
+#define BF_PXP_WFE_A_STORE_SIZE_CH1_OUT_HEIGHT(v) \
+ (((v) << 16) & BM_PXP_WFE_A_STORE_SIZE_CH1_OUT_HEIGHT)
+#define BP_PXP_WFE_A_STORE_SIZE_CH1_OUT_WIDTH 0
+#define BM_PXP_WFE_A_STORE_SIZE_CH1_OUT_WIDTH 0x0000FFFF
+#define BF_PXP_WFE_A_STORE_SIZE_CH1_OUT_WIDTH(v) \
+ (((v) << 0) & BM_PXP_WFE_A_STORE_SIZE_CH1_OUT_WIDTH)
+
+#define HW_PXP_WFE_A_STORE_PITCH (0x00000ee0)
+
+#define BP_PXP_WFE_A_STORE_PITCH_CH1_OUT_PITCH 16
+#define BM_PXP_WFE_A_STORE_PITCH_CH1_OUT_PITCH 0xFFFF0000
+#define BF_PXP_WFE_A_STORE_PITCH_CH1_OUT_PITCH(v) \
+ (((v) << 16) & BM_PXP_WFE_A_STORE_PITCH_CH1_OUT_PITCH)
+#define BP_PXP_WFE_A_STORE_PITCH_CH0_OUT_PITCH 0
+#define BM_PXP_WFE_A_STORE_PITCH_CH0_OUT_PITCH 0x0000FFFF
+#define BF_PXP_WFE_A_STORE_PITCH_CH0_OUT_PITCH(v) \
+ (((v) << 0) & BM_PXP_WFE_A_STORE_PITCH_CH0_OUT_PITCH)
+
+#define HW_PXP_WFE_A_STORE_SHIFT_CTRL_CH0 (0x00000ef0)
+#define HW_PXP_WFE_A_STORE_SHIFT_CTRL_CH0_SET (0x00000ef4)
+#define HW_PXP_WFE_A_STORE_SHIFT_CTRL_CH0_CLR (0x00000ef8)
+#define HW_PXP_WFE_A_STORE_SHIFT_CTRL_CH0_TOG (0x00000efc)
+
+#define BP_PXP_WFE_A_STORE_SHIFT_CTRL_CH0_RSVD0 8
+#define BM_PXP_WFE_A_STORE_SHIFT_CTRL_CH0_RSVD0 0xFFFFFF00
+#define BF_PXP_WFE_A_STORE_SHIFT_CTRL_CH0_RSVD0(v) \
+ (((v) << 8) & BM_PXP_WFE_A_STORE_SHIFT_CTRL_CH0_RSVD0)
+#define BM_PXP_WFE_A_STORE_SHIFT_CTRL_CH0_SHIFT_BYPASS 0x00000080
+#define BF_PXP_WFE_A_STORE_SHIFT_CTRL_CH0_SHIFT_BYPASS(v) \
+ (((v) << 7) & BM_PXP_WFE_A_STORE_SHIFT_CTRL_CH0_SHIFT_BYPASS)
+#define BV_PXP_WFE_A_STORE_SHIFT_CTRL_CH0_SHIFT_BYPASS__0 0x0
+#define BV_PXP_WFE_A_STORE_SHIFT_CTRL_CH0_SHIFT_BYPASS__1 0x1
+#define BM_PXP_WFE_A_STORE_SHIFT_CTRL_CH0_RSVD1 0x00000040
+#define BF_PXP_WFE_A_STORE_SHIFT_CTRL_CH0_RSVD1(v) \
+ (((v) << 6) & BM_PXP_WFE_A_STORE_SHIFT_CTRL_CH0_RSVD1)
+#define BM_PXP_WFE_A_STORE_SHIFT_CTRL_CH0_OUT_YUV422_2P_EN 0x00000020
+#define BF_PXP_WFE_A_STORE_SHIFT_CTRL_CH0_OUT_YUV422_2P_EN(v) \
+ (((v) << 5) & BM_PXP_WFE_A_STORE_SHIFT_CTRL_CH0_OUT_YUV422_2P_EN)
+#define BV_PXP_WFE_A_STORE_SHIFT_CTRL_CH0_OUT_YUV422_2P_EN__0 0x0
+#define BV_PXP_WFE_A_STORE_SHIFT_CTRL_CH0_OUT_YUV422_2P_EN__1 0x1
+#define BM_PXP_WFE_A_STORE_SHIFT_CTRL_CH0_OUT_YUV422_1P_EN 0x00000010
+#define BF_PXP_WFE_A_STORE_SHIFT_CTRL_CH0_OUT_YUV422_1P_EN(v) \
+ (((v) << 4) & BM_PXP_WFE_A_STORE_SHIFT_CTRL_CH0_OUT_YUV422_1P_EN)
+#define BV_PXP_WFE_A_STORE_SHIFT_CTRL_CH0_OUT_YUV422_1P_EN__0 0x0
+#define BV_PXP_WFE_A_STORE_SHIFT_CTRL_CH0_OUT_YUV422_1P_EN__1 0x1
+#define BP_PXP_WFE_A_STORE_SHIFT_CTRL_CH0_OUTPUT_ACTIVE_BPP 2
+#define BM_PXP_WFE_A_STORE_SHIFT_CTRL_CH0_OUTPUT_ACTIVE_BPP 0x0000000C
+#define BF_PXP_WFE_A_STORE_SHIFT_CTRL_CH0_OUTPUT_ACTIVE_BPP(v) \
+ (((v) << 2) & BM_PXP_WFE_A_STORE_SHIFT_CTRL_CH0_OUTPUT_ACTIVE_BPP)
+#define BV_PXP_WFE_A_STORE_SHIFT_CTRL_CH0_OUTPUT_ACTIVE_BPP__0 0x0
+#define BV_PXP_WFE_A_STORE_SHIFT_CTRL_CH0_OUTPUT_ACTIVE_BPP__1 0x1
+#define BV_PXP_WFE_A_STORE_SHIFT_CTRL_CH0_OUTPUT_ACTIVE_BPP__2 0x2
+#define BV_PXP_WFE_A_STORE_SHIFT_CTRL_CH0_OUTPUT_ACTIVE_BPP__3 0x3
+#define BP_PXP_WFE_A_STORE_SHIFT_CTRL_CH0_RSVD2 0
+#define BM_PXP_WFE_A_STORE_SHIFT_CTRL_CH0_RSVD2 0x00000003
+#define BF_PXP_WFE_A_STORE_SHIFT_CTRL_CH0_RSVD2(v) \
+ (((v) << 0) & BM_PXP_WFE_A_STORE_SHIFT_CTRL_CH0_RSVD2)
+
+#define HW_PXP_WFE_A_STORE_SHIFT_CTRL_CH1 (0x00000f00)
+#define HW_PXP_WFE_A_STORE_SHIFT_CTRL_CH1_SET (0x00000f04)
+#define HW_PXP_WFE_A_STORE_SHIFT_CTRL_CH1_CLR (0x00000f08)
+#define HW_PXP_WFE_A_STORE_SHIFT_CTRL_CH1_TOG (0x00000f0c)
+
+#define BP_PXP_WFE_A_STORE_SHIFT_CTRL_CH1_RSVD0 6
+#define BM_PXP_WFE_A_STORE_SHIFT_CTRL_CH1_RSVD0 0xFFFFFFC0
+#define BF_PXP_WFE_A_STORE_SHIFT_CTRL_CH1_RSVD0(v) \
+ (((v) << 6) & BM_PXP_WFE_A_STORE_SHIFT_CTRL_CH1_RSVD0)
+#define BM_PXP_WFE_A_STORE_SHIFT_CTRL_CH1_OUT_YUV422_2P_EN 0x00000020
+#define BF_PXP_WFE_A_STORE_SHIFT_CTRL_CH1_OUT_YUV422_2P_EN(v) \
+ (((v) << 5) & BM_PXP_WFE_A_STORE_SHIFT_CTRL_CH1_OUT_YUV422_2P_EN)
+#define BV_PXP_WFE_A_STORE_SHIFT_CTRL_CH1_OUT_YUV422_2P_EN__0 0x0
+#define BV_PXP_WFE_A_STORE_SHIFT_CTRL_CH1_OUT_YUV422_2P_EN__1 0x1
+#define BM_PXP_WFE_A_STORE_SHIFT_CTRL_CH1_OUT_YUV422_1P_EN 0x00000010
+#define BF_PXP_WFE_A_STORE_SHIFT_CTRL_CH1_OUT_YUV422_1P_EN(v) \
+ (((v) << 4) & BM_PXP_WFE_A_STORE_SHIFT_CTRL_CH1_OUT_YUV422_1P_EN)
+#define BV_PXP_WFE_A_STORE_SHIFT_CTRL_CH1_OUT_YUV422_1P_EN__0 0x0
+#define BV_PXP_WFE_A_STORE_SHIFT_CTRL_CH1_OUT_YUV422_1P_EN__1 0x1
+#define BP_PXP_WFE_A_STORE_SHIFT_CTRL_CH1_OUTPUT_ACTIVE_BPP 2
+#define BM_PXP_WFE_A_STORE_SHIFT_CTRL_CH1_OUTPUT_ACTIVE_BPP 0x0000000C
+#define BF_PXP_WFE_A_STORE_SHIFT_CTRL_CH1_OUTPUT_ACTIVE_BPP(v) \
+ (((v) << 2) & BM_PXP_WFE_A_STORE_SHIFT_CTRL_CH1_OUTPUT_ACTIVE_BPP)
+#define BV_PXP_WFE_A_STORE_SHIFT_CTRL_CH1_OUTPUT_ACTIVE_BPP__0 0x0
+#define BV_PXP_WFE_A_STORE_SHIFT_CTRL_CH1_OUTPUT_ACTIVE_BPP__1 0x1
+#define BV_PXP_WFE_A_STORE_SHIFT_CTRL_CH1_OUTPUT_ACTIVE_BPP__2 0x2
+#define BV_PXP_WFE_A_STORE_SHIFT_CTRL_CH1_OUTPUT_ACTIVE_BPP__3 0x3
+#define BP_PXP_WFE_A_STORE_SHIFT_CTRL_CH1_RSVD2 0
+#define BM_PXP_WFE_A_STORE_SHIFT_CTRL_CH1_RSVD2 0x00000003
+#define BF_PXP_WFE_A_STORE_SHIFT_CTRL_CH1_RSVD2(v) \
+ (((v) << 0) & BM_PXP_WFE_A_STORE_SHIFT_CTRL_CH1_RSVD2)
+
+#define HW_PXP_WFE_A_STORE_ADDR_0_CH0 (0x00000f50)
+
+#define BP_PXP_WFE_A_STORE_ADDR_0_CH0_OUT_BASE_ADDR0 0
+#define BM_PXP_WFE_A_STORE_ADDR_0_CH0_OUT_BASE_ADDR0 0xFFFFFFFF
+#define BF_PXP_WFE_A_STORE_ADDR_0_CH0_OUT_BASE_ADDR0(v) (v)
+
+#define HW_PXP_WFE_A_STORE_ADDR_1_CH0 (0x00000f60)
+
+#define BP_PXP_WFE_A_STORE_ADDR_1_CH0_OUT_BASE_ADDR1 0
+#define BM_PXP_WFE_A_STORE_ADDR_1_CH0_OUT_BASE_ADDR1 0xFFFFFFFF
+#define BF_PXP_WFE_A_STORE_ADDR_1_CH0_OUT_BASE_ADDR1(v) (v)
+
+#define HW_PXP_WFE_A_STORE_FILL_DATA_CH0 (0x00000f70)
+
+#define BP_PXP_WFE_A_STORE_FILL_DATA_CH0_FILL_DATA_CH0 0
+#define BM_PXP_WFE_A_STORE_FILL_DATA_CH0_FILL_DATA_CH0 0xFFFFFFFF
+#define BF_PXP_WFE_A_STORE_FILL_DATA_CH0_FILL_DATA_CH0(v) (v)
+
+#define HW_PXP_WFE_A_STORE_ADDR_0_CH1 (0x00000f80)
+
+#define BP_PXP_WFE_A_STORE_ADDR_0_CH1_OUT_BASE_ADDR0 0
+#define BM_PXP_WFE_A_STORE_ADDR_0_CH1_OUT_BASE_ADDR0 0xFFFFFFFF
+#define BF_PXP_WFE_A_STORE_ADDR_0_CH1_OUT_BASE_ADDR0(v) (v)
+
+#define HW_PXP_WFE_A_STORE_ADDR_1_CH1 (0x00000f90)
+
+#define BP_PXP_WFE_A_STORE_ADDR_1_CH1_OUT_BASE_ADDR1 0
+#define BM_PXP_WFE_A_STORE_ADDR_1_CH1_OUT_BASE_ADDR1 0xFFFFFFFF
+#define BF_PXP_WFE_A_STORE_ADDR_1_CH1_OUT_BASE_ADDR1(v) (v)
+
+#define HW_PXP_WFE_A_STORE_D_MASK0_H_CH0 (0x00000fa0)
+
+#define BP_PXP_WFE_A_STORE_D_MASK0_H_CH0_D_MASK0_H_CH0 0
+#define BM_PXP_WFE_A_STORE_D_MASK0_H_CH0_D_MASK0_H_CH0 0xFFFFFFFF
+#define BF_PXP_WFE_A_STORE_D_MASK0_H_CH0_D_MASK0_H_CH0(v) (v)
+
+#define HW_PXP_WFE_A_STORE_D_MASK0_L_CH0 (0x00000fb0)
+
+#define BP_PXP_WFE_A_STORE_D_MASK0_L_CH0_D_MASK0_L_CH0 0
+#define BM_PXP_WFE_A_STORE_D_MASK0_L_CH0_D_MASK0_L_CH0 0xFFFFFFFF
+#define BF_PXP_WFE_A_STORE_D_MASK0_L_CH0_D_MASK0_L_CH0(v) (v)
+
+#define HW_PXP_WFE_A_STORE_D_MASK1_H_CH0 (0x00000fc0)
+
+#define BP_PXP_WFE_A_STORE_D_MASK1_H_CH0_D_MASK1_H_CH0 0
+#define BM_PXP_WFE_A_STORE_D_MASK1_H_CH0_D_MASK1_H_CH0 0xFFFFFFFF
+#define BF_PXP_WFE_A_STORE_D_MASK1_H_CH0_D_MASK1_H_CH0(v) (v)
+
+#define HW_PXP_WFE_A_STORE_D_MASK1_L_CH0 (0x00000fd0)
+
+#define BP_PXP_WFE_A_STORE_D_MASK1_L_CH0_D_MASK1_L_CH0 0
+#define BM_PXP_WFE_A_STORE_D_MASK1_L_CH0_D_MASK1_L_CH0 0xFFFFFFFF
+#define BF_PXP_WFE_A_STORE_D_MASK1_L_CH0_D_MASK1_L_CH0(v) (v)
+
+#define HW_PXP_WFE_A_STORE_D_MASK2_H_CH0 (0x00000fe0)
+
+#define BP_PXP_WFE_A_STORE_D_MASK2_H_CH0_D_MASK2_H_CH0 0
+#define BM_PXP_WFE_A_STORE_D_MASK2_H_CH0_D_MASK2_H_CH0 0xFFFFFFFF
+#define BF_PXP_WFE_A_STORE_D_MASK2_H_CH0_D_MASK2_H_CH0(v) (v)
+
+#define HW_PXP_WFE_A_STORE_D_MASK2_L_CH0 (0x00000ff0)
+
+#define BP_PXP_WFE_A_STORE_D_MASK2_L_CH0_D_MASK2_L_CH0 0
+#define BM_PXP_WFE_A_STORE_D_MASK2_L_CH0_D_MASK2_L_CH0 0xFFFFFFFF
+#define BF_PXP_WFE_A_STORE_D_MASK2_L_CH0_D_MASK2_L_CH0(v) (v)
+
+#define HW_PXP_WFE_A_STORE_D_MASK3_H_CH0 (0x00001000)
+
+#define BP_PXP_WFE_A_STORE_D_MASK3_H_CH0_D_MASK3_H_CH0 0
+#define BM_PXP_WFE_A_STORE_D_MASK3_H_CH0_D_MASK3_H_CH0 0xFFFFFFFF
+#define BF_PXP_WFE_A_STORE_D_MASK3_H_CH0_D_MASK3_H_CH0(v) (v)
+
+#define HW_PXP_WFE_A_STORE_D_MASK3_L_CH0 (0x00001010)
+
+#define BP_PXP_WFE_A_STORE_D_MASK3_L_CH0_D_MASK3_L_CH0 0
+#define BM_PXP_WFE_A_STORE_D_MASK3_L_CH0_D_MASK3_L_CH0 0xFFFFFFFF
+#define BF_PXP_WFE_A_STORE_D_MASK3_L_CH0_D_MASK3_L_CH0(v) (v)
+
+#define HW_PXP_WFE_A_STORE_D_MASK4_H_CH0 (0x00001020)
+
+#define BP_PXP_WFE_A_STORE_D_MASK4_H_CH0_D_MASK4_H_CH0 0
+#define BM_PXP_WFE_A_STORE_D_MASK4_H_CH0_D_MASK4_H_CH0 0xFFFFFFFF
+#define BF_PXP_WFE_A_STORE_D_MASK4_H_CH0_D_MASK4_H_CH0(v) (v)
+
+#define HW_PXP_WFE_A_STORE_D_MASK4_L_CH0 (0x00001030)
+
+#define BP_PXP_WFE_A_STORE_D_MASK4_L_CH0_D_MASK4_L_CH0 0
+#define BM_PXP_WFE_A_STORE_D_MASK4_L_CH0_D_MASK4_L_CH0 0xFFFFFFFF
+#define BF_PXP_WFE_A_STORE_D_MASK4_L_CH0_D_MASK4_L_CH0(v) (v)
+
+#define HW_PXP_WFE_A_STORE_D_MASK5_H_CH0 (0x00001040)
+
+#define BP_PXP_WFE_A_STORE_D_MASK5_H_CH0_D_MASK5_H_CH0 0
+#define BM_PXP_WFE_A_STORE_D_MASK5_H_CH0_D_MASK5_H_CH0 0xFFFFFFFF
+#define BF_PXP_WFE_A_STORE_D_MASK5_H_CH0_D_MASK5_H_CH0(v) (v)
+
+#define HW_PXP_WFE_A_STORE_D_MASK5_L_CH0 (0x00001050)
+
+#define BP_PXP_WFE_A_STORE_D_MASK5_L_CH0_D_MASK5_L_CH0 0
+#define BM_PXP_WFE_A_STORE_D_MASK5_L_CH0_D_MASK5_L_CH0 0xFFFFFFFF
+#define BF_PXP_WFE_A_STORE_D_MASK5_L_CH0_D_MASK5_L_CH0(v) (v)
+
+#define HW_PXP_WFE_A_STORE_D_MASK6_H_CH0 (0x00001060)
+
+#define BP_PXP_WFE_A_STORE_D_MASK6_H_CH0_D_MASK6_H_CH0 0
+#define BM_PXP_WFE_A_STORE_D_MASK6_H_CH0_D_MASK6_H_CH0 0xFFFFFFFF
+#define BF_PXP_WFE_A_STORE_D_MASK6_H_CH0_D_MASK6_H_CH0(v) (v)
+
+#define HW_PXP_WFE_A_STORE_D_MASK6_L_CH0 (0x00001070)
+
+#define BP_PXP_WFE_A_STORE_D_MASK6_L_CH0_D_MASK6_L_CH0 0
+#define BM_PXP_WFE_A_STORE_D_MASK6_L_CH0_D_MASK6_L_CH0 0xFFFFFFFF
+#define BF_PXP_WFE_A_STORE_D_MASK6_L_CH0_D_MASK6_L_CH0(v) (v)
+
+#define HW_PXP_WFE_A_STORE_D_MASK7_H_CH0 (0x00001080)
+
+#define BP_PXP_WFE_A_STORE_D_MASK7_H_CH0_D_MASK7_H_CH0 0
+#define BM_PXP_WFE_A_STORE_D_MASK7_H_CH0_D_MASK7_H_CH0 0xFFFFFFFF
+#define BF_PXP_WFE_A_STORE_D_MASK7_H_CH0_D_MASK7_H_CH0(v) (v)
+
+#define HW_PXP_WFE_A_STORE_D_MASK7_L_CH0 (0x00001090)
+
+#define BP_PXP_WFE_A_STORE_D_MASK7_L_CH0_D_MASK7_L_CH0 0
+#define BM_PXP_WFE_A_STORE_D_MASK7_L_CH0_D_MASK7_L_CH0 0xFFFFFFFF
+#define BF_PXP_WFE_A_STORE_D_MASK7_L_CH0_D_MASK7_L_CH0(v) (v)
+
+#define HW_PXP_WFE_A_STORE_D_SHIFT_L_CH0 (0x000010a0)
+
+#define BM_PXP_WFE_A_STORE_D_SHIFT_L_CH0_D_SHIFT_FLAG3 0x80000000
+#define BF_PXP_WFE_A_STORE_D_SHIFT_L_CH0_D_SHIFT_FLAG3(v) \
+ (((v) << 31) & BM_PXP_WFE_A_STORE_D_SHIFT_L_CH0_D_SHIFT_FLAG3)
+#define BM_PXP_WFE_A_STORE_D_SHIFT_L_CH0_RSVD0 0x40000000
+#define BF_PXP_WFE_A_STORE_D_SHIFT_L_CH0_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFE_A_STORE_D_SHIFT_L_CH0_RSVD0)
+#define BP_PXP_WFE_A_STORE_D_SHIFT_L_CH0_D_SHIFT_WIDTH3 24
+#define BM_PXP_WFE_A_STORE_D_SHIFT_L_CH0_D_SHIFT_WIDTH3 0x3F000000
+#define BF_PXP_WFE_A_STORE_D_SHIFT_L_CH0_D_SHIFT_WIDTH3(v) \
+ (((v) << 24) & BM_PXP_WFE_A_STORE_D_SHIFT_L_CH0_D_SHIFT_WIDTH3)
+#define BM_PXP_WFE_A_STORE_D_SHIFT_L_CH0_D_SHIFT_FLAG2 0x00800000
+#define BF_PXP_WFE_A_STORE_D_SHIFT_L_CH0_D_SHIFT_FLAG2(v) \
+ (((v) << 23) & BM_PXP_WFE_A_STORE_D_SHIFT_L_CH0_D_SHIFT_FLAG2)
+#define BM_PXP_WFE_A_STORE_D_SHIFT_L_CH0_RSVD1 0x00400000
+#define BF_PXP_WFE_A_STORE_D_SHIFT_L_CH0_RSVD1(v) \
+ (((v) << 22) & BM_PXP_WFE_A_STORE_D_SHIFT_L_CH0_RSVD1)
+#define BP_PXP_WFE_A_STORE_D_SHIFT_L_CH0_D_SHIFT_WIDTH2 16
+#define BM_PXP_WFE_A_STORE_D_SHIFT_L_CH0_D_SHIFT_WIDTH2 0x003F0000
+#define BF_PXP_WFE_A_STORE_D_SHIFT_L_CH0_D_SHIFT_WIDTH2(v) \
+ (((v) << 16) & BM_PXP_WFE_A_STORE_D_SHIFT_L_CH0_D_SHIFT_WIDTH2)
+#define BM_PXP_WFE_A_STORE_D_SHIFT_L_CH0_D_SHIFT_FLAG1 0x00008000
+#define BF_PXP_WFE_A_STORE_D_SHIFT_L_CH0_D_SHIFT_FLAG1(v) \
+ (((v) << 15) & BM_PXP_WFE_A_STORE_D_SHIFT_L_CH0_D_SHIFT_FLAG1)
+#define BM_PXP_WFE_A_STORE_D_SHIFT_L_CH0_RSVD2 0x00004000
+#define BF_PXP_WFE_A_STORE_D_SHIFT_L_CH0_RSVD2(v) \
+ (((v) << 14) & BM_PXP_WFE_A_STORE_D_SHIFT_L_CH0_RSVD2)
+#define BP_PXP_WFE_A_STORE_D_SHIFT_L_CH0_D_SHIFT_WIDTH1 8
+#define BM_PXP_WFE_A_STORE_D_SHIFT_L_CH0_D_SHIFT_WIDTH1 0x00003F00
+#define BF_PXP_WFE_A_STORE_D_SHIFT_L_CH0_D_SHIFT_WIDTH1(v) \
+ (((v) << 8) & BM_PXP_WFE_A_STORE_D_SHIFT_L_CH0_D_SHIFT_WIDTH1)
+#define BM_PXP_WFE_A_STORE_D_SHIFT_L_CH0_D_SHIFT_FLAG0 0x00000080
+#define BF_PXP_WFE_A_STORE_D_SHIFT_L_CH0_D_SHIFT_FLAG0(v) \
+ (((v) << 7) & BM_PXP_WFE_A_STORE_D_SHIFT_L_CH0_D_SHIFT_FLAG0)
+#define BM_PXP_WFE_A_STORE_D_SHIFT_L_CH0_RSVD3 0x00000040
+#define BF_PXP_WFE_A_STORE_D_SHIFT_L_CH0_RSVD3(v) \
+ (((v) << 6) & BM_PXP_WFE_A_STORE_D_SHIFT_L_CH0_RSVD3)
+#define BP_PXP_WFE_A_STORE_D_SHIFT_L_CH0_D_SHIFT_WIDTH0 0
+#define BM_PXP_WFE_A_STORE_D_SHIFT_L_CH0_D_SHIFT_WIDTH0 0x0000003F
+#define BF_PXP_WFE_A_STORE_D_SHIFT_L_CH0_D_SHIFT_WIDTH0(v) \
+ (((v) << 0) & BM_PXP_WFE_A_STORE_D_SHIFT_L_CH0_D_SHIFT_WIDTH0)
+
+#define HW_PXP_WFE_A_STORE_D_SHIFT_H_CH0 (0x000010b0)
+
+#define BM_PXP_WFE_A_STORE_D_SHIFT_H_CH0_D_SHIFT_FLAG7 0x80000000
+#define BF_PXP_WFE_A_STORE_D_SHIFT_H_CH0_D_SHIFT_FLAG7(v) \
+ (((v) << 31) & BM_PXP_WFE_A_STORE_D_SHIFT_H_CH0_D_SHIFT_FLAG7)
+#define BM_PXP_WFE_A_STORE_D_SHIFT_H_CH0_RSVD0 0x40000000
+#define BF_PXP_WFE_A_STORE_D_SHIFT_H_CH0_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFE_A_STORE_D_SHIFT_H_CH0_RSVD0)
+#define BP_PXP_WFE_A_STORE_D_SHIFT_H_CH0_D_SHIFT_WIDTH7 24
+#define BM_PXP_WFE_A_STORE_D_SHIFT_H_CH0_D_SHIFT_WIDTH7 0x3F000000
+#define BF_PXP_WFE_A_STORE_D_SHIFT_H_CH0_D_SHIFT_WIDTH7(v) \
+ (((v) << 24) & BM_PXP_WFE_A_STORE_D_SHIFT_H_CH0_D_SHIFT_WIDTH7)
+#define BM_PXP_WFE_A_STORE_D_SHIFT_H_CH0_D_SHIFT_FLAG6 0x00800000
+#define BF_PXP_WFE_A_STORE_D_SHIFT_H_CH0_D_SHIFT_FLAG6(v) \
+ (((v) << 23) & BM_PXP_WFE_A_STORE_D_SHIFT_H_CH0_D_SHIFT_FLAG6)
+#define BM_PXP_WFE_A_STORE_D_SHIFT_H_CH0_RSVD1 0x00400000
+#define BF_PXP_WFE_A_STORE_D_SHIFT_H_CH0_RSVD1(v) \
+ (((v) << 22) & BM_PXP_WFE_A_STORE_D_SHIFT_H_CH0_RSVD1)
+#define BP_PXP_WFE_A_STORE_D_SHIFT_H_CH0_D_SHIFT_WIDTH6 16
+#define BM_PXP_WFE_A_STORE_D_SHIFT_H_CH0_D_SHIFT_WIDTH6 0x003F0000
+#define BF_PXP_WFE_A_STORE_D_SHIFT_H_CH0_D_SHIFT_WIDTH6(v) \
+ (((v) << 16) & BM_PXP_WFE_A_STORE_D_SHIFT_H_CH0_D_SHIFT_WIDTH6)
+#define BM_PXP_WFE_A_STORE_D_SHIFT_H_CH0_D_SHIFT_FLAG5 0x00008000
+#define BF_PXP_WFE_A_STORE_D_SHIFT_H_CH0_D_SHIFT_FLAG5(v) \
+ (((v) << 15) & BM_PXP_WFE_A_STORE_D_SHIFT_H_CH0_D_SHIFT_FLAG5)
+#define BM_PXP_WFE_A_STORE_D_SHIFT_H_CH0_RSVD2 0x00004000
+#define BF_PXP_WFE_A_STORE_D_SHIFT_H_CH0_RSVD2(v) \
+ (((v) << 14) & BM_PXP_WFE_A_STORE_D_SHIFT_H_CH0_RSVD2)
+#define BP_PXP_WFE_A_STORE_D_SHIFT_H_CH0_D_SHIFT_WIDTH5 8
+#define BM_PXP_WFE_A_STORE_D_SHIFT_H_CH0_D_SHIFT_WIDTH5 0x00003F00
+#define BF_PXP_WFE_A_STORE_D_SHIFT_H_CH0_D_SHIFT_WIDTH5(v) \
+ (((v) << 8) & BM_PXP_WFE_A_STORE_D_SHIFT_H_CH0_D_SHIFT_WIDTH5)
+#define BM_PXP_WFE_A_STORE_D_SHIFT_H_CH0_D_SHIFT_FLAG4 0x00000080
+#define BF_PXP_WFE_A_STORE_D_SHIFT_H_CH0_D_SHIFT_FLAG4(v) \
+ (((v) << 7) & BM_PXP_WFE_A_STORE_D_SHIFT_H_CH0_D_SHIFT_FLAG4)
+#define BM_PXP_WFE_A_STORE_D_SHIFT_H_CH0_RSVD3 0x00000040
+#define BF_PXP_WFE_A_STORE_D_SHIFT_H_CH0_RSVD3(v) \
+ (((v) << 6) & BM_PXP_WFE_A_STORE_D_SHIFT_H_CH0_RSVD3)
+#define BP_PXP_WFE_A_STORE_D_SHIFT_H_CH0_D_SHIFT_WIDTH4 0
+#define BM_PXP_WFE_A_STORE_D_SHIFT_H_CH0_D_SHIFT_WIDTH4 0x0000003F
+#define BF_PXP_WFE_A_STORE_D_SHIFT_H_CH0_D_SHIFT_WIDTH4(v) \
+ (((v) << 0) & BM_PXP_WFE_A_STORE_D_SHIFT_H_CH0_D_SHIFT_WIDTH4)
+
+#define HW_PXP_WFE_A_STORE_F_SHIFT_L_CH0 (0x000010c0)
+
+#define BM_PXP_WFE_A_STORE_F_SHIFT_L_CH0_RSVD0 0x80000000
+#define BF_PXP_WFE_A_STORE_F_SHIFT_L_CH0_RSVD0(v) \
+ (((v) << 31) & BM_PXP_WFE_A_STORE_F_SHIFT_L_CH0_RSVD0)
+#define BM_PXP_WFE_A_STORE_F_SHIFT_L_CH0_F_SHIFT_FLAG3 0x40000000
+#define BF_PXP_WFE_A_STORE_F_SHIFT_L_CH0_F_SHIFT_FLAG3(v) \
+ (((v) << 30) & BM_PXP_WFE_A_STORE_F_SHIFT_L_CH0_F_SHIFT_FLAG3)
+#define BP_PXP_WFE_A_STORE_F_SHIFT_L_CH0_F_SHIFT_WIDTH3 24
+#define BM_PXP_WFE_A_STORE_F_SHIFT_L_CH0_F_SHIFT_WIDTH3 0x3F000000
+#define BF_PXP_WFE_A_STORE_F_SHIFT_L_CH0_F_SHIFT_WIDTH3(v) \
+ (((v) << 24) & BM_PXP_WFE_A_STORE_F_SHIFT_L_CH0_F_SHIFT_WIDTH3)
+#define BM_PXP_WFE_A_STORE_F_SHIFT_L_CH0_RSVD1 0x00800000
+#define BF_PXP_WFE_A_STORE_F_SHIFT_L_CH0_RSVD1(v) \
+ (((v) << 23) & BM_PXP_WFE_A_STORE_F_SHIFT_L_CH0_RSVD1)
+#define BM_PXP_WFE_A_STORE_F_SHIFT_L_CH0_F_SHIFT_FLAG2 0x00400000
+#define BF_PXP_WFE_A_STORE_F_SHIFT_L_CH0_F_SHIFT_FLAG2(v) \
+ (((v) << 22) & BM_PXP_WFE_A_STORE_F_SHIFT_L_CH0_F_SHIFT_FLAG2)
+#define BP_PXP_WFE_A_STORE_F_SHIFT_L_CH0_F_SHIFT_WIDTH2 16
+#define BM_PXP_WFE_A_STORE_F_SHIFT_L_CH0_F_SHIFT_WIDTH2 0x003F0000
+#define BF_PXP_WFE_A_STORE_F_SHIFT_L_CH0_F_SHIFT_WIDTH2(v) \
+ (((v) << 16) & BM_PXP_WFE_A_STORE_F_SHIFT_L_CH0_F_SHIFT_WIDTH2)
+#define BM_PXP_WFE_A_STORE_F_SHIFT_L_CH0_RSVD2 0x00008000
+#define BF_PXP_WFE_A_STORE_F_SHIFT_L_CH0_RSVD2(v) \
+ (((v) << 15) & BM_PXP_WFE_A_STORE_F_SHIFT_L_CH0_RSVD2)
+#define BM_PXP_WFE_A_STORE_F_SHIFT_L_CH0_F_SHIFT_FLAG1 0x00004000
+#define BF_PXP_WFE_A_STORE_F_SHIFT_L_CH0_F_SHIFT_FLAG1(v) \
+ (((v) << 14) & BM_PXP_WFE_A_STORE_F_SHIFT_L_CH0_F_SHIFT_FLAG1)
+#define BP_PXP_WFE_A_STORE_F_SHIFT_L_CH0_F_SHIFT_WIDTH1 8
+#define BM_PXP_WFE_A_STORE_F_SHIFT_L_CH0_F_SHIFT_WIDTH1 0x00003F00
+#define BF_PXP_WFE_A_STORE_F_SHIFT_L_CH0_F_SHIFT_WIDTH1(v) \
+ (((v) << 8) & BM_PXP_WFE_A_STORE_F_SHIFT_L_CH0_F_SHIFT_WIDTH1)
+#define BM_PXP_WFE_A_STORE_F_SHIFT_L_CH0_RSVD3 0x00000080
+#define BF_PXP_WFE_A_STORE_F_SHIFT_L_CH0_RSVD3(v) \
+ (((v) << 7) & BM_PXP_WFE_A_STORE_F_SHIFT_L_CH0_RSVD3)
+#define BM_PXP_WFE_A_STORE_F_SHIFT_L_CH0_F_SHIFT_FLAG0 0x00000040
+#define BF_PXP_WFE_A_STORE_F_SHIFT_L_CH0_F_SHIFT_FLAG0(v) \
+ (((v) << 6) & BM_PXP_WFE_A_STORE_F_SHIFT_L_CH0_F_SHIFT_FLAG0)
+#define BP_PXP_WFE_A_STORE_F_SHIFT_L_CH0_F_SHIFT_WIDTH0 0
+#define BM_PXP_WFE_A_STORE_F_SHIFT_L_CH0_F_SHIFT_WIDTH0 0x0000003F
+#define BF_PXP_WFE_A_STORE_F_SHIFT_L_CH0_F_SHIFT_WIDTH0(v) \
+ (((v) << 0) & BM_PXP_WFE_A_STORE_F_SHIFT_L_CH0_F_SHIFT_WIDTH0)
+
+#define HW_PXP_WFE_A_STORE_F_SHIFT_H_CH0 (0x000010d0)
+
+#define BM_PXP_WFE_A_STORE_F_SHIFT_H_CH0_RSVD0 0x80000000
+#define BF_PXP_WFE_A_STORE_F_SHIFT_H_CH0_RSVD0(v) \
+ (((v) << 31) & BM_PXP_WFE_A_STORE_F_SHIFT_H_CH0_RSVD0)
+#define BM_PXP_WFE_A_STORE_F_SHIFT_H_CH0_F_SHIFT_FLAG7 0x40000000
+#define BF_PXP_WFE_A_STORE_F_SHIFT_H_CH0_F_SHIFT_FLAG7(v) \
+ (((v) << 30) & BM_PXP_WFE_A_STORE_F_SHIFT_H_CH0_F_SHIFT_FLAG7)
+#define BP_PXP_WFE_A_STORE_F_SHIFT_H_CH0_F_SHIFT_WIDTH7 24
+#define BM_PXP_WFE_A_STORE_F_SHIFT_H_CH0_F_SHIFT_WIDTH7 0x3F000000
+#define BF_PXP_WFE_A_STORE_F_SHIFT_H_CH0_F_SHIFT_WIDTH7(v) \
+ (((v) << 24) & BM_PXP_WFE_A_STORE_F_SHIFT_H_CH0_F_SHIFT_WIDTH7)
+#define BM_PXP_WFE_A_STORE_F_SHIFT_H_CH0_RSVD1 0x00800000
+#define BF_PXP_WFE_A_STORE_F_SHIFT_H_CH0_RSVD1(v) \
+ (((v) << 23) & BM_PXP_WFE_A_STORE_F_SHIFT_H_CH0_RSVD1)
+#define BM_PXP_WFE_A_STORE_F_SHIFT_H_CH0_F_SHIFT_FLAG6 0x00400000
+#define BF_PXP_WFE_A_STORE_F_SHIFT_H_CH0_F_SHIFT_FLAG6(v) \
+ (((v) << 22) & BM_PXP_WFE_A_STORE_F_SHIFT_H_CH0_F_SHIFT_FLAG6)
+#define BP_PXP_WFE_A_STORE_F_SHIFT_H_CH0_F_SHIFT_WIDTH6 16
+#define BM_PXP_WFE_A_STORE_F_SHIFT_H_CH0_F_SHIFT_WIDTH6 0x003F0000
+#define BF_PXP_WFE_A_STORE_F_SHIFT_H_CH0_F_SHIFT_WIDTH6(v) \
+ (((v) << 16) & BM_PXP_WFE_A_STORE_F_SHIFT_H_CH0_F_SHIFT_WIDTH6)
+#define BM_PXP_WFE_A_STORE_F_SHIFT_H_CH0_RSVD2 0x00008000
+#define BF_PXP_WFE_A_STORE_F_SHIFT_H_CH0_RSVD2(v) \
+ (((v) << 15) & BM_PXP_WFE_A_STORE_F_SHIFT_H_CH0_RSVD2)
+#define BM_PXP_WFE_A_STORE_F_SHIFT_H_CH0_F_SHIFT_FLAG5 0x00004000
+#define BF_PXP_WFE_A_STORE_F_SHIFT_H_CH0_F_SHIFT_FLAG5(v) \
+ (((v) << 14) & BM_PXP_WFE_A_STORE_F_SHIFT_H_CH0_F_SHIFT_FLAG5)
+#define BP_PXP_WFE_A_STORE_F_SHIFT_H_CH0_F_SHIFT_WIDTH5 8
+#define BM_PXP_WFE_A_STORE_F_SHIFT_H_CH0_F_SHIFT_WIDTH5 0x00003F00
+#define BF_PXP_WFE_A_STORE_F_SHIFT_H_CH0_F_SHIFT_WIDTH5(v) \
+ (((v) << 8) & BM_PXP_WFE_A_STORE_F_SHIFT_H_CH0_F_SHIFT_WIDTH5)
+#define BM_PXP_WFE_A_STORE_F_SHIFT_H_CH0_RSVD3 0x00000080
+#define BF_PXP_WFE_A_STORE_F_SHIFT_H_CH0_RSVD3(v) \
+ (((v) << 7) & BM_PXP_WFE_A_STORE_F_SHIFT_H_CH0_RSVD3)
+#define BM_PXP_WFE_A_STORE_F_SHIFT_H_CH0_F_SHIFT_FLAG4 0x00000040
+#define BF_PXP_WFE_A_STORE_F_SHIFT_H_CH0_F_SHIFT_FLAG4(v) \
+ (((v) << 6) & BM_PXP_WFE_A_STORE_F_SHIFT_H_CH0_F_SHIFT_FLAG4)
+#define BP_PXP_WFE_A_STORE_F_SHIFT_H_CH0_F_SHIFT_WIDTH4 0
+#define BM_PXP_WFE_A_STORE_F_SHIFT_H_CH0_F_SHIFT_WIDTH4 0x0000003F
+#define BF_PXP_WFE_A_STORE_F_SHIFT_H_CH0_F_SHIFT_WIDTH4(v) \
+ (((v) << 0) & BM_PXP_WFE_A_STORE_F_SHIFT_H_CH0_F_SHIFT_WIDTH4)
+
+#define HW_PXP_WFE_A_STORE_F_MASK_L_CH0 (0x000010e0)
+
+#define BP_PXP_WFE_A_STORE_F_MASK_L_CH0_F_MASK3 24
+#define BM_PXP_WFE_A_STORE_F_MASK_L_CH0_F_MASK3 0xFF000000
+#define BF_PXP_WFE_A_STORE_F_MASK_L_CH0_F_MASK3(v) \
+ (((v) << 24) & BM_PXP_WFE_A_STORE_F_MASK_L_CH0_F_MASK3)
+#define BP_PXP_WFE_A_STORE_F_MASK_L_CH0_F_MASK2 16
+#define BM_PXP_WFE_A_STORE_F_MASK_L_CH0_F_MASK2 0x00FF0000
+#define BF_PXP_WFE_A_STORE_F_MASK_L_CH0_F_MASK2(v) \
+ (((v) << 16) & BM_PXP_WFE_A_STORE_F_MASK_L_CH0_F_MASK2)
+#define BP_PXP_WFE_A_STORE_F_MASK_L_CH0_F_MASK1 8
+#define BM_PXP_WFE_A_STORE_F_MASK_L_CH0_F_MASK1 0x0000FF00
+#define BF_PXP_WFE_A_STORE_F_MASK_L_CH0_F_MASK1(v) \
+ (((v) << 8) & BM_PXP_WFE_A_STORE_F_MASK_L_CH0_F_MASK1)
+#define BP_PXP_WFE_A_STORE_F_MASK_L_CH0_F_MASK0 0
+#define BM_PXP_WFE_A_STORE_F_MASK_L_CH0_F_MASK0 0x000000FF
+#define BF_PXP_WFE_A_STORE_F_MASK_L_CH0_F_MASK0(v) \
+ (((v) << 0) & BM_PXP_WFE_A_STORE_F_MASK_L_CH0_F_MASK0)
+
+#define HW_PXP_WFE_A_STORE_F_MASK_H_CH0 (0x000010f0)
+
+#define BP_PXP_WFE_A_STORE_F_MASK_H_CH0_F_MASK7 24
+#define BM_PXP_WFE_A_STORE_F_MASK_H_CH0_F_MASK7 0xFF000000
+#define BF_PXP_WFE_A_STORE_F_MASK_H_CH0_F_MASK7(v) \
+ (((v) << 24) & BM_PXP_WFE_A_STORE_F_MASK_H_CH0_F_MASK7)
+#define BP_PXP_WFE_A_STORE_F_MASK_H_CH0_F_MASK6 16
+#define BM_PXP_WFE_A_STORE_F_MASK_H_CH0_F_MASK6 0x00FF0000
+#define BF_PXP_WFE_A_STORE_F_MASK_H_CH0_F_MASK6(v) \
+ (((v) << 16) & BM_PXP_WFE_A_STORE_F_MASK_H_CH0_F_MASK6)
+#define BP_PXP_WFE_A_STORE_F_MASK_H_CH0_F_MASK5 8
+#define BM_PXP_WFE_A_STORE_F_MASK_H_CH0_F_MASK5 0x0000FF00
+#define BF_PXP_WFE_A_STORE_F_MASK_H_CH0_F_MASK5(v) \
+ (((v) << 8) & BM_PXP_WFE_A_STORE_F_MASK_H_CH0_F_MASK5)
+#define BP_PXP_WFE_A_STORE_F_MASK_H_CH0_F_MASK4 0
+#define BM_PXP_WFE_A_STORE_F_MASK_H_CH0_F_MASK4 0x000000FF
+#define BF_PXP_WFE_A_STORE_F_MASK_H_CH0_F_MASK4(v) \
+ (((v) << 0) & BM_PXP_WFE_A_STORE_F_MASK_H_CH0_F_MASK4)
+
+#define HW_PXP_WFB_FETCH_CTRL (0x00001100)
+#define HW_PXP_WFB_FETCH_CTRL_SET (0x00001104)
+#define HW_PXP_WFB_FETCH_CTRL_CLR (0x00001108)
+#define HW_PXP_WFB_FETCH_CTRL_TOG (0x0000110c)
+
+#define BM_PXP_WFB_FETCH_CTRL_BUF2_DONE_IRQ_EN 0x80000000
+#define BF_PXP_WFB_FETCH_CTRL_BUF2_DONE_IRQ_EN(v) \
+ (((v) << 31) & BM_PXP_WFB_FETCH_CTRL_BUF2_DONE_IRQ_EN)
+#define BM_PXP_WFB_FETCH_CTRL_BUF1_DONE_IRQ_EN 0x40000000
+#define BF_PXP_WFB_FETCH_CTRL_BUF1_DONE_IRQ_EN(v) \
+ (((v) << 30) & BM_PXP_WFB_FETCH_CTRL_BUF1_DONE_IRQ_EN)
+#define BM_PXP_WFB_FETCH_CTRL_BUF2_DONE_IRQ 0x20000000
+#define BF_PXP_WFB_FETCH_CTRL_BUF2_DONE_IRQ(v) \
+ (((v) << 29) & BM_PXP_WFB_FETCH_CTRL_BUF2_DONE_IRQ)
+#define BM_PXP_WFB_FETCH_CTRL_BUF1_DONE_IRQ 0x10000000
+#define BF_PXP_WFB_FETCH_CTRL_BUF1_DONE_IRQ(v) \
+ (((v) << 28) & BM_PXP_WFB_FETCH_CTRL_BUF1_DONE_IRQ)
+#define BP_PXP_WFB_FETCH_CTRL_RSVD0 24
+#define BM_PXP_WFB_FETCH_CTRL_RSVD0 0x0F000000
+#define BF_PXP_WFB_FETCH_CTRL_RSVD0(v) \
+ (((v) << 24) & BM_PXP_WFB_FETCH_CTRL_RSVD0)
+#define BP_PXP_WFB_FETCH_CTRL_BF2_LINE_MODE 22
+#define BM_PXP_WFB_FETCH_CTRL_BF2_LINE_MODE 0x00C00000
+#define BF_PXP_WFB_FETCH_CTRL_BF2_LINE_MODE(v) \
+ (((v) << 22) & BM_PXP_WFB_FETCH_CTRL_BF2_LINE_MODE)
+#define BV_PXP_WFB_FETCH_CTRL_BF2_LINE_MODE__0 0x0
+#define BV_PXP_WFB_FETCH_CTRL_BF2_LINE_MODE__1 0x1
+#define BV_PXP_WFB_FETCH_CTRL_BF2_LINE_MODE__2 0x2
+#define BV_PXP_WFB_FETCH_CTRL_BF2_LINE_MODE__3 0x3
+#define BP_PXP_WFB_FETCH_CTRL_BF2_BYTES_PP 20
+#define BM_PXP_WFB_FETCH_CTRL_BF2_BYTES_PP 0x00300000
+#define BF_PXP_WFB_FETCH_CTRL_BF2_BYTES_PP(v) \
+ (((v) << 20) & BM_PXP_WFB_FETCH_CTRL_BF2_BYTES_PP)
+#define BP_PXP_WFB_FETCH_CTRL_BF1_LINE_MODE 18
+#define BM_PXP_WFB_FETCH_CTRL_BF1_LINE_MODE 0x000C0000
+#define BF_PXP_WFB_FETCH_CTRL_BF1_LINE_MODE(v) \
+ (((v) << 18) & BM_PXP_WFB_FETCH_CTRL_BF1_LINE_MODE)
+#define BV_PXP_WFB_FETCH_CTRL_BF1_LINE_MODE__0 0x0
+#define BV_PXP_WFB_FETCH_CTRL_BF1_LINE_MODE__1 0x1
+#define BV_PXP_WFB_FETCH_CTRL_BF1_LINE_MODE__2 0x2
+#define BV_PXP_WFB_FETCH_CTRL_BF1_LINE_MODE__3 0x3
+#define BP_PXP_WFB_FETCH_CTRL_BF1_BYTES_PP 16
+#define BM_PXP_WFB_FETCH_CTRL_BF1_BYTES_PP 0x00030000
+#define BF_PXP_WFB_FETCH_CTRL_BF1_BYTES_PP(v) \
+ (((v) << 16) & BM_PXP_WFB_FETCH_CTRL_BF1_BYTES_PP)
+#define BP_PXP_WFB_FETCH_CTRL_RSVD1 14
+#define BM_PXP_WFB_FETCH_CTRL_RSVD1 0x0000C000
+#define BF_PXP_WFB_FETCH_CTRL_RSVD1(v) \
+ (((v) << 14) & BM_PXP_WFB_FETCH_CTRL_RSVD1)
+#define BM_PXP_WFB_FETCH_CTRL_BF2_BORDER_MODE 0x00002000
+#define BF_PXP_WFB_FETCH_CTRL_BF2_BORDER_MODE(v) \
+ (((v) << 13) & BM_PXP_WFB_FETCH_CTRL_BF2_BORDER_MODE)
+#define BV_PXP_WFB_FETCH_CTRL_BF2_BORDER_MODE__0 0x0
+#define BV_PXP_WFB_FETCH_CTRL_BF2_BORDER_MODE__1 0x1
+#define BM_PXP_WFB_FETCH_CTRL_BF2_BURST_LEN 0x00001000
+#define BF_PXP_WFB_FETCH_CTRL_BF2_BURST_LEN(v) \
+ (((v) << 12) & BM_PXP_WFB_FETCH_CTRL_BF2_BURST_LEN)
+#define BV_PXP_WFB_FETCH_CTRL_BF2_BURST_LEN__0 0x0
+#define BV_PXP_WFB_FETCH_CTRL_BF2_BURST_LEN__1 0x1
+#define BM_PXP_WFB_FETCH_CTRL_BF2_BYPASS_MODE 0x00000800
+#define BF_PXP_WFB_FETCH_CTRL_BF2_BYPASS_MODE(v) \
+ (((v) << 11) & BM_PXP_WFB_FETCH_CTRL_BF2_BYPASS_MODE)
+#define BV_PXP_WFB_FETCH_CTRL_BF2_BYPASS_MODE__0 0x0
+#define BV_PXP_WFB_FETCH_CTRL_BF2_BYPASS_MODE__1 0x1
+#define BM_PXP_WFB_FETCH_CTRL_BF2_HSK_MODE 0x00000400
+#define BF_PXP_WFB_FETCH_CTRL_BF2_HSK_MODE(v) \
+ (((v) << 10) & BM_PXP_WFB_FETCH_CTRL_BF2_HSK_MODE)
+#define BV_PXP_WFB_FETCH_CTRL_BF2_HSK_MODE__0 0x0
+#define BV_PXP_WFB_FETCH_CTRL_BF2_HSK_MODE__1 0x1
+#define BM_PXP_WFB_FETCH_CTRL_BF2_SRAM_IF 0x00000200
+#define BF_PXP_WFB_FETCH_CTRL_BF2_SRAM_IF(v) \
+ (((v) << 9) & BM_PXP_WFB_FETCH_CTRL_BF2_SRAM_IF)
+#define BV_PXP_WFB_FETCH_CTRL_BF2_SRAM_IF__0 0x0
+#define BV_PXP_WFB_FETCH_CTRL_BF2_SRAM_IF__1 0x1
+#define BM_PXP_WFB_FETCH_CTRL_BF2_EN 0x00000100
+#define BF_PXP_WFB_FETCH_CTRL_BF2_EN(v) \
+ (((v) << 8) & BM_PXP_WFB_FETCH_CTRL_BF2_EN)
+#define BV_PXP_WFB_FETCH_CTRL_BF2_EN__0 0x0
+#define BV_PXP_WFB_FETCH_CTRL_BF2_EN__1 0x1
+#define BP_PXP_WFB_FETCH_CTRL_RSVD2 6
+#define BM_PXP_WFB_FETCH_CTRL_RSVD2 0x000000C0
+#define BF_PXP_WFB_FETCH_CTRL_RSVD2(v) \
+ (((v) << 6) & BM_PXP_WFB_FETCH_CTRL_RSVD2)
+#define BM_PXP_WFB_FETCH_CTRL_BF1_BORDER_MODE 0x00000020
+#define BF_PXP_WFB_FETCH_CTRL_BF1_BORDER_MODE(v) \
+ (((v) << 5) & BM_PXP_WFB_FETCH_CTRL_BF1_BORDER_MODE)
+#define BV_PXP_WFB_FETCH_CTRL_BF1_BORDER_MODE__0 0x0
+#define BV_PXP_WFB_FETCH_CTRL_BF1_BORDER_MODE__1 0x1
+#define BM_PXP_WFB_FETCH_CTRL_BF1_BURST_LEN 0x00000010
+#define BF_PXP_WFB_FETCH_CTRL_BF1_BURST_LEN(v) \
+ (((v) << 4) & BM_PXP_WFB_FETCH_CTRL_BF1_BURST_LEN)
+#define BV_PXP_WFB_FETCH_CTRL_BF1_BURST_LEN__0 0x0
+#define BV_PXP_WFB_FETCH_CTRL_BF1_BURST_LEN__1 0x1
+#define BM_PXP_WFB_FETCH_CTRL_BF1_BYPASS_MODE 0x00000008
+#define BF_PXP_WFB_FETCH_CTRL_BF1_BYPASS_MODE(v) \
+ (((v) << 3) & BM_PXP_WFB_FETCH_CTRL_BF1_BYPASS_MODE)
+#define BV_PXP_WFB_FETCH_CTRL_BF1_BYPASS_MODE__0 0x0
+#define BV_PXP_WFB_FETCH_CTRL_BF1_BYPASS_MODE__1 0x1
+#define BM_PXP_WFB_FETCH_CTRL_BF1_HSK_MODE 0x00000004
+#define BF_PXP_WFB_FETCH_CTRL_BF1_HSK_MODE(v) \
+ (((v) << 2) & BM_PXP_WFB_FETCH_CTRL_BF1_HSK_MODE)
+#define BV_PXP_WFB_FETCH_CTRL_BF1_HSK_MODE__0 0x0
+#define BV_PXP_WFB_FETCH_CTRL_BF1_HSK_MODE__1 0x1
+#define BM_PXP_WFB_FETCH_CTRL_BF1_SRAM_IF 0x00000002
+#define BF_PXP_WFB_FETCH_CTRL_BF1_SRAM_IF(v) \
+ (((v) << 1) & BM_PXP_WFB_FETCH_CTRL_BF1_SRAM_IF)
+#define BV_PXP_WFB_FETCH_CTRL_BF1_SRAM_IF__0 0x0
+#define BV_PXP_WFB_FETCH_CTRL_BF1_SRAM_IF__1 0x1
+#define BM_PXP_WFB_FETCH_CTRL_BF1_EN 0x00000001
+#define BF_PXP_WFB_FETCH_CTRL_BF1_EN(v) \
+ (((v) << 0) & BM_PXP_WFB_FETCH_CTRL_BF1_EN)
+#define BV_PXP_WFB_FETCH_CTRL_BF1_EN__0 0x0
+#define BV_PXP_WFB_FETCH_CTRL_BF1_EN__1 0x1
+
+#define HW_PXP_WFB_FETCH_BUF1_ADDR (0x00001110)
+
+#define BP_PXP_WFB_FETCH_BUF1_ADDR_BUF_ADDR 0
+#define BM_PXP_WFB_FETCH_BUF1_ADDR_BUF_ADDR 0xFFFFFFFF
+#define BF_PXP_WFB_FETCH_BUF1_ADDR_BUF_ADDR(v) (v)
+
+#define HW_PXP_WFB_FETCH_BUF1_PITCH (0x00001120)
+
+#define BP_PXP_WFB_FETCH_BUF1_PITCH_RSVD 16
+#define BM_PXP_WFB_FETCH_BUF1_PITCH_RSVD 0xFFFF0000
+#define BF_PXP_WFB_FETCH_BUF1_PITCH_RSVD(v) \
+ (((v) << 16) & BM_PXP_WFB_FETCH_BUF1_PITCH_RSVD)
+#define BP_PXP_WFB_FETCH_BUF1_PITCH_PITCH 0
+#define BM_PXP_WFB_FETCH_BUF1_PITCH_PITCH 0x0000FFFF
+#define BF_PXP_WFB_FETCH_BUF1_PITCH_PITCH(v) \
+ (((v) << 0) & BM_PXP_WFB_FETCH_BUF1_PITCH_PITCH)
+
+#define HW_PXP_WFB_FETCH_BUF1_SIZE (0x00001130)
+
+#define BP_PXP_WFB_FETCH_BUF1_SIZE_BUF_HEIGHT 16
+#define BM_PXP_WFB_FETCH_BUF1_SIZE_BUF_HEIGHT 0xFFFF0000
+#define BF_PXP_WFB_FETCH_BUF1_SIZE_BUF_HEIGHT(v) \
+ (((v) << 16) & BM_PXP_WFB_FETCH_BUF1_SIZE_BUF_HEIGHT)
+#define BP_PXP_WFB_FETCH_BUF1_SIZE_BUF_WIDTH 0
+#define BM_PXP_WFB_FETCH_BUF1_SIZE_BUF_WIDTH 0x0000FFFF
+#define BF_PXP_WFB_FETCH_BUF1_SIZE_BUF_WIDTH(v) \
+ (((v) << 0) & BM_PXP_WFB_FETCH_BUF1_SIZE_BUF_WIDTH)
+
+#define HW_PXP_WFB_FETCH_BUF2_ADDR (0x00001140)
+
+#define BP_PXP_WFB_FETCH_BUF2_ADDR_BUF_ADDR 0
+#define BM_PXP_WFB_FETCH_BUF2_ADDR_BUF_ADDR 0xFFFFFFFF
+#define BF_PXP_WFB_FETCH_BUF2_ADDR_BUF_ADDR(v) (v)
+
+#define HW_PXP_WFB_FETCH_BUF2_PITCH (0x00001150)
+
+#define BP_PXP_WFB_FETCH_BUF2_PITCH_RSVD 16
+#define BM_PXP_WFB_FETCH_BUF2_PITCH_RSVD 0xFFFF0000
+#define BF_PXP_WFB_FETCH_BUF2_PITCH_RSVD(v) \
+ (((v) << 16) & BM_PXP_WFB_FETCH_BUF2_PITCH_RSVD)
+#define BP_PXP_WFB_FETCH_BUF2_PITCH_PITCH 0
+#define BM_PXP_WFB_FETCH_BUF2_PITCH_PITCH 0x0000FFFF
+#define BF_PXP_WFB_FETCH_BUF2_PITCH_PITCH(v) \
+ (((v) << 0) & BM_PXP_WFB_FETCH_BUF2_PITCH_PITCH)
+
+#define HW_PXP_WFB_FETCH_BUF2_SIZE (0x00001160)
+
+#define BP_PXP_WFB_FETCH_BUF2_SIZE_BUF_HEIGHT 16
+#define BM_PXP_WFB_FETCH_BUF2_SIZE_BUF_HEIGHT 0xFFFF0000
+#define BF_PXP_WFB_FETCH_BUF2_SIZE_BUF_HEIGHT(v) \
+ (((v) << 16) & BM_PXP_WFB_FETCH_BUF2_SIZE_BUF_HEIGHT)
+#define BP_PXP_WFB_FETCH_BUF2_SIZE_BUF_WIDTH 0
+#define BM_PXP_WFB_FETCH_BUF2_SIZE_BUF_WIDTH 0x0000FFFF
+#define BF_PXP_WFB_FETCH_BUF2_SIZE_BUF_WIDTH(v) \
+ (((v) << 0) & BM_PXP_WFB_FETCH_BUF2_SIZE_BUF_WIDTH)
+
+#define HW_PXP_WFB_ARRAY_PIXEL0_MASK (0x00001170)
+
+#define BP_PXP_WFB_ARRAY_PIXEL0_MASK_RSVD0 30
+#define BM_PXP_WFB_ARRAY_PIXEL0_MASK_RSVD0 0xC0000000
+#define BF_PXP_WFB_ARRAY_PIXEL0_MASK_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFB_ARRAY_PIXEL0_MASK_RSVD0)
+#define BP_PXP_WFB_ARRAY_PIXEL0_MASK_BUF_SEL 28
+#define BM_PXP_WFB_ARRAY_PIXEL0_MASK_BUF_SEL 0x30000000
+#define BF_PXP_WFB_ARRAY_PIXEL0_MASK_BUF_SEL(v) \
+ (((v) << 28) & BM_PXP_WFB_ARRAY_PIXEL0_MASK_BUF_SEL)
+#define BV_PXP_WFB_ARRAY_PIXEL0_MASK_BUF_SEL__0 0x0
+#define BV_PXP_WFB_ARRAY_PIXEL0_MASK_BUF_SEL__1 0x1
+#define BV_PXP_WFB_ARRAY_PIXEL0_MASK_BUF_SEL__2 0x2
+#define BP_PXP_WFB_ARRAY_PIXEL0_MASK_RSVD1 26
+#define BM_PXP_WFB_ARRAY_PIXEL0_MASK_RSVD1 0x0C000000
+#define BF_PXP_WFB_ARRAY_PIXEL0_MASK_RSVD1(v) \
+ (((v) << 26) & BM_PXP_WFB_ARRAY_PIXEL0_MASK_RSVD1)
+#define BM_PXP_WFB_ARRAY_PIXEL0_MASK_SIGN_Y 0x02000000
+#define BF_PXP_WFB_ARRAY_PIXEL0_MASK_SIGN_Y(v) \
+ (((v) << 25) & BM_PXP_WFB_ARRAY_PIXEL0_MASK_SIGN_Y)
+#define BV_PXP_WFB_ARRAY_PIXEL0_MASK_SIGN_Y__0 0x0
+#define BV_PXP_WFB_ARRAY_PIXEL0_MASK_SIGN_Y__1 0x1
+#define BM_PXP_WFB_ARRAY_PIXEL0_MASK_SIGN_X 0x01000000
+#define BF_PXP_WFB_ARRAY_PIXEL0_MASK_SIGN_X(v) \
+ (((v) << 24) & BM_PXP_WFB_ARRAY_PIXEL0_MASK_SIGN_X)
+#define BV_PXP_WFB_ARRAY_PIXEL0_MASK_SIGN_X__0 0x0
+#define BV_PXP_WFB_ARRAY_PIXEL0_MASK_SIGN_X__1 0x1
+#define BP_PXP_WFB_ARRAY_PIXEL0_MASK_RSVD2 22
+#define BM_PXP_WFB_ARRAY_PIXEL0_MASK_RSVD2 0x00C00000
+#define BF_PXP_WFB_ARRAY_PIXEL0_MASK_RSVD2(v) \
+ (((v) << 22) & BM_PXP_WFB_ARRAY_PIXEL0_MASK_RSVD2)
+#define BP_PXP_WFB_ARRAY_PIXEL0_MASK_OFFSET_Y 20
+#define BM_PXP_WFB_ARRAY_PIXEL0_MASK_OFFSET_Y 0x00300000
+#define BF_PXP_WFB_ARRAY_PIXEL0_MASK_OFFSET_Y(v) \
+ (((v) << 20) & BM_PXP_WFB_ARRAY_PIXEL0_MASK_OFFSET_Y)
+#define BP_PXP_WFB_ARRAY_PIXEL0_MASK_RSVD3 18
+#define BM_PXP_WFB_ARRAY_PIXEL0_MASK_RSVD3 0x000C0000
+#define BF_PXP_WFB_ARRAY_PIXEL0_MASK_RSVD3(v) \
+ (((v) << 18) & BM_PXP_WFB_ARRAY_PIXEL0_MASK_RSVD3)
+#define BP_PXP_WFB_ARRAY_PIXEL0_MASK_OFFSET_X 16
+#define BM_PXP_WFB_ARRAY_PIXEL0_MASK_OFFSET_X 0x00030000
+#define BF_PXP_WFB_ARRAY_PIXEL0_MASK_OFFSET_X(v) \
+ (((v) << 16) & BM_PXP_WFB_ARRAY_PIXEL0_MASK_OFFSET_X)
+#define BP_PXP_WFB_ARRAY_PIXEL0_MASK_RSVD4 13
+#define BM_PXP_WFB_ARRAY_PIXEL0_MASK_RSVD4 0x0000E000
+#define BF_PXP_WFB_ARRAY_PIXEL0_MASK_RSVD4(v) \
+ (((v) << 13) & BM_PXP_WFB_ARRAY_PIXEL0_MASK_RSVD4)
+#define BP_PXP_WFB_ARRAY_PIXEL0_MASK_H_OFS 8
+#define BM_PXP_WFB_ARRAY_PIXEL0_MASK_H_OFS 0x00001F00
+#define BF_PXP_WFB_ARRAY_PIXEL0_MASK_H_OFS(v) \
+ (((v) << 8) & BM_PXP_WFB_ARRAY_PIXEL0_MASK_H_OFS)
+#define BP_PXP_WFB_ARRAY_PIXEL0_MASK_RSVD5 5
+#define BM_PXP_WFB_ARRAY_PIXEL0_MASK_RSVD5 0x000000E0
+#define BF_PXP_WFB_ARRAY_PIXEL0_MASK_RSVD5(v) \
+ (((v) << 5) & BM_PXP_WFB_ARRAY_PIXEL0_MASK_RSVD5)
+#define BP_PXP_WFB_ARRAY_PIXEL0_MASK_L_OFS 0
+#define BM_PXP_WFB_ARRAY_PIXEL0_MASK_L_OFS 0x0000001F
+#define BF_PXP_WFB_ARRAY_PIXEL0_MASK_L_OFS(v) \
+ (((v) << 0) & BM_PXP_WFB_ARRAY_PIXEL0_MASK_L_OFS)
+
+#define HW_PXP_WFB_ARRAY_PIXEL1_MASK (0x00001180)
+
+#define BP_PXP_WFB_ARRAY_PIXEL1_MASK_RSVD0 30
+#define BM_PXP_WFB_ARRAY_PIXEL1_MASK_RSVD0 0xC0000000
+#define BF_PXP_WFB_ARRAY_PIXEL1_MASK_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFB_ARRAY_PIXEL1_MASK_RSVD0)
+#define BP_PXP_WFB_ARRAY_PIXEL1_MASK_BUF_SEL 28
+#define BM_PXP_WFB_ARRAY_PIXEL1_MASK_BUF_SEL 0x30000000
+#define BF_PXP_WFB_ARRAY_PIXEL1_MASK_BUF_SEL(v) \
+ (((v) << 28) & BM_PXP_WFB_ARRAY_PIXEL1_MASK_BUF_SEL)
+#define BV_PXP_WFB_ARRAY_PIXEL1_MASK_BUF_SEL__0 0x0
+#define BV_PXP_WFB_ARRAY_PIXEL1_MASK_BUF_SEL__1 0x1
+#define BV_PXP_WFB_ARRAY_PIXEL1_MASK_BUF_SEL__2 0x2
+#define BP_PXP_WFB_ARRAY_PIXEL1_MASK_RSVD1 26
+#define BM_PXP_WFB_ARRAY_PIXEL1_MASK_RSVD1 0x0C000000
+#define BF_PXP_WFB_ARRAY_PIXEL1_MASK_RSVD1(v) \
+ (((v) << 26) & BM_PXP_WFB_ARRAY_PIXEL1_MASK_RSVD1)
+#define BM_PXP_WFB_ARRAY_PIXEL1_MASK_SIGN_Y 0x02000000
+#define BF_PXP_WFB_ARRAY_PIXEL1_MASK_SIGN_Y(v) \
+ (((v) << 25) & BM_PXP_WFB_ARRAY_PIXEL1_MASK_SIGN_Y)
+#define BV_PXP_WFB_ARRAY_PIXEL1_MASK_SIGN_Y__0 0x0
+#define BV_PXP_WFB_ARRAY_PIXEL1_MASK_SIGN_Y__1 0x1
+#define BM_PXP_WFB_ARRAY_PIXEL1_MASK_SIGN_X 0x01000000
+#define BF_PXP_WFB_ARRAY_PIXEL1_MASK_SIGN_X(v) \
+ (((v) << 24) & BM_PXP_WFB_ARRAY_PIXEL1_MASK_SIGN_X)
+#define BV_PXP_WFB_ARRAY_PIXEL1_MASK_SIGN_X__0 0x0
+#define BV_PXP_WFB_ARRAY_PIXEL1_MASK_SIGN_X__1 0x1
+#define BP_PXP_WFB_ARRAY_PIXEL1_MASK_RSVD2 22
+#define BM_PXP_WFB_ARRAY_PIXEL1_MASK_RSVD2 0x00C00000
+#define BF_PXP_WFB_ARRAY_PIXEL1_MASK_RSVD2(v) \
+ (((v) << 22) & BM_PXP_WFB_ARRAY_PIXEL1_MASK_RSVD2)
+#define BP_PXP_WFB_ARRAY_PIXEL1_MASK_OFFSET_Y 20
+#define BM_PXP_WFB_ARRAY_PIXEL1_MASK_OFFSET_Y 0x00300000
+#define BF_PXP_WFB_ARRAY_PIXEL1_MASK_OFFSET_Y(v) \
+ (((v) << 20) & BM_PXP_WFB_ARRAY_PIXEL1_MASK_OFFSET_Y)
+#define BP_PXP_WFB_ARRAY_PIXEL1_MASK_RSVD3 18
+#define BM_PXP_WFB_ARRAY_PIXEL1_MASK_RSVD3 0x000C0000
+#define BF_PXP_WFB_ARRAY_PIXEL1_MASK_RSVD3(v) \
+ (((v) << 18) & BM_PXP_WFB_ARRAY_PIXEL1_MASK_RSVD3)
+#define BP_PXP_WFB_ARRAY_PIXEL1_MASK_OFFSET_X 16
+#define BM_PXP_WFB_ARRAY_PIXEL1_MASK_OFFSET_X 0x00030000
+#define BF_PXP_WFB_ARRAY_PIXEL1_MASK_OFFSET_X(v) \
+ (((v) << 16) & BM_PXP_WFB_ARRAY_PIXEL1_MASK_OFFSET_X)
+#define BP_PXP_WFB_ARRAY_PIXEL1_MASK_RSVD4 13
+#define BM_PXP_WFB_ARRAY_PIXEL1_MASK_RSVD4 0x0000E000
+#define BF_PXP_WFB_ARRAY_PIXEL1_MASK_RSVD4(v) \
+ (((v) << 13) & BM_PXP_WFB_ARRAY_PIXEL1_MASK_RSVD4)
+#define BP_PXP_WFB_ARRAY_PIXEL1_MASK_H_OFS 8
+#define BM_PXP_WFB_ARRAY_PIXEL1_MASK_H_OFS 0x00001F00
+#define BF_PXP_WFB_ARRAY_PIXEL1_MASK_H_OFS(v) \
+ (((v) << 8) & BM_PXP_WFB_ARRAY_PIXEL1_MASK_H_OFS)
+#define BP_PXP_WFB_ARRAY_PIXEL1_MASK_RSVD5 5
+#define BM_PXP_WFB_ARRAY_PIXEL1_MASK_RSVD5 0x000000E0
+#define BF_PXP_WFB_ARRAY_PIXEL1_MASK_RSVD5(v) \
+ (((v) << 5) & BM_PXP_WFB_ARRAY_PIXEL1_MASK_RSVD5)
+#define BP_PXP_WFB_ARRAY_PIXEL1_MASK_L_OFS 0
+#define BM_PXP_WFB_ARRAY_PIXEL1_MASK_L_OFS 0x0000001F
+#define BF_PXP_WFB_ARRAY_PIXEL1_MASK_L_OFS(v) \
+ (((v) << 0) & BM_PXP_WFB_ARRAY_PIXEL1_MASK_L_OFS)
+
+#define HW_PXP_WFB_ARRAY_PIXEL2_MASK (0x00001190)
+
+#define BP_PXP_WFB_ARRAY_PIXEL2_MASK_RSVD0 30
+#define BM_PXP_WFB_ARRAY_PIXEL2_MASK_RSVD0 0xC0000000
+#define BF_PXP_WFB_ARRAY_PIXEL2_MASK_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFB_ARRAY_PIXEL2_MASK_RSVD0)
+#define BP_PXP_WFB_ARRAY_PIXEL2_MASK_BUF_SEL 28
+#define BM_PXP_WFB_ARRAY_PIXEL2_MASK_BUF_SEL 0x30000000
+#define BF_PXP_WFB_ARRAY_PIXEL2_MASK_BUF_SEL(v) \
+ (((v) << 28) & BM_PXP_WFB_ARRAY_PIXEL2_MASK_BUF_SEL)
+#define BV_PXP_WFB_ARRAY_PIXEL2_MASK_BUF_SEL__0 0x0
+#define BV_PXP_WFB_ARRAY_PIXEL2_MASK_BUF_SEL__1 0x1
+#define BV_PXP_WFB_ARRAY_PIXEL2_MASK_BUF_SEL__2 0x2
+#define BP_PXP_WFB_ARRAY_PIXEL2_MASK_RSVD1 26
+#define BM_PXP_WFB_ARRAY_PIXEL2_MASK_RSVD1 0x0C000000
+#define BF_PXP_WFB_ARRAY_PIXEL2_MASK_RSVD1(v) \
+ (((v) << 26) & BM_PXP_WFB_ARRAY_PIXEL2_MASK_RSVD1)
+#define BM_PXP_WFB_ARRAY_PIXEL2_MASK_SIGN_Y 0x02000000
+#define BF_PXP_WFB_ARRAY_PIXEL2_MASK_SIGN_Y(v) \
+ (((v) << 25) & BM_PXP_WFB_ARRAY_PIXEL2_MASK_SIGN_Y)
+#define BV_PXP_WFB_ARRAY_PIXEL2_MASK_SIGN_Y__0 0x0
+#define BV_PXP_WFB_ARRAY_PIXEL2_MASK_SIGN_Y__1 0x1
+#define BM_PXP_WFB_ARRAY_PIXEL2_MASK_SIGN_X 0x01000000
+#define BF_PXP_WFB_ARRAY_PIXEL2_MASK_SIGN_X(v) \
+ (((v) << 24) & BM_PXP_WFB_ARRAY_PIXEL2_MASK_SIGN_X)
+#define BV_PXP_WFB_ARRAY_PIXEL2_MASK_SIGN_X__0 0x0
+#define BV_PXP_WFB_ARRAY_PIXEL2_MASK_SIGN_X__1 0x1
+#define BP_PXP_WFB_ARRAY_PIXEL2_MASK_RSVD2 22
+#define BM_PXP_WFB_ARRAY_PIXEL2_MASK_RSVD2 0x00C00000
+#define BF_PXP_WFB_ARRAY_PIXEL2_MASK_RSVD2(v) \
+ (((v) << 22) & BM_PXP_WFB_ARRAY_PIXEL2_MASK_RSVD2)
+#define BP_PXP_WFB_ARRAY_PIXEL2_MASK_OFFSET_Y 20
+#define BM_PXP_WFB_ARRAY_PIXEL2_MASK_OFFSET_Y 0x00300000
+#define BF_PXP_WFB_ARRAY_PIXEL2_MASK_OFFSET_Y(v) \
+ (((v) << 20) & BM_PXP_WFB_ARRAY_PIXEL2_MASK_OFFSET_Y)
+#define BP_PXP_WFB_ARRAY_PIXEL2_MASK_RSVD3 18
+#define BM_PXP_WFB_ARRAY_PIXEL2_MASK_RSVD3 0x000C0000
+#define BF_PXP_WFB_ARRAY_PIXEL2_MASK_RSVD3(v) \
+ (((v) << 18) & BM_PXP_WFB_ARRAY_PIXEL2_MASK_RSVD3)
+#define BP_PXP_WFB_ARRAY_PIXEL2_MASK_OFFSET_X 16
+#define BM_PXP_WFB_ARRAY_PIXEL2_MASK_OFFSET_X 0x00030000
+#define BF_PXP_WFB_ARRAY_PIXEL2_MASK_OFFSET_X(v) \
+ (((v) << 16) & BM_PXP_WFB_ARRAY_PIXEL2_MASK_OFFSET_X)
+#define BP_PXP_WFB_ARRAY_PIXEL2_MASK_RSVD4 13
+#define BM_PXP_WFB_ARRAY_PIXEL2_MASK_RSVD4 0x0000E000
+#define BF_PXP_WFB_ARRAY_PIXEL2_MASK_RSVD4(v) \
+ (((v) << 13) & BM_PXP_WFB_ARRAY_PIXEL2_MASK_RSVD4)
+#define BP_PXP_WFB_ARRAY_PIXEL2_MASK_H_OFS 8
+#define BM_PXP_WFB_ARRAY_PIXEL2_MASK_H_OFS 0x00001F00
+#define BF_PXP_WFB_ARRAY_PIXEL2_MASK_H_OFS(v) \
+ (((v) << 8) & BM_PXP_WFB_ARRAY_PIXEL2_MASK_H_OFS)
+#define BP_PXP_WFB_ARRAY_PIXEL2_MASK_RSVD5 5
+#define BM_PXP_WFB_ARRAY_PIXEL2_MASK_RSVD5 0x000000E0
+#define BF_PXP_WFB_ARRAY_PIXEL2_MASK_RSVD5(v) \
+ (((v) << 5) & BM_PXP_WFB_ARRAY_PIXEL2_MASK_RSVD5)
+#define BP_PXP_WFB_ARRAY_PIXEL2_MASK_L_OFS 0
+#define BM_PXP_WFB_ARRAY_PIXEL2_MASK_L_OFS 0x0000001F
+#define BF_PXP_WFB_ARRAY_PIXEL2_MASK_L_OFS(v) \
+ (((v) << 0) & BM_PXP_WFB_ARRAY_PIXEL2_MASK_L_OFS)
+
+#define HW_PXP_WFB_ARRAY_PIXEL3_MASK (0x000011a0)
+
+#define BP_PXP_WFB_ARRAY_PIXEL3_MASK_RSVD0 30
+#define BM_PXP_WFB_ARRAY_PIXEL3_MASK_RSVD0 0xC0000000
+#define BF_PXP_WFB_ARRAY_PIXEL3_MASK_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFB_ARRAY_PIXEL3_MASK_RSVD0)
+#define BP_PXP_WFB_ARRAY_PIXEL3_MASK_BUF_SEL 28
+#define BM_PXP_WFB_ARRAY_PIXEL3_MASK_BUF_SEL 0x30000000
+#define BF_PXP_WFB_ARRAY_PIXEL3_MASK_BUF_SEL(v) \
+ (((v) << 28) & BM_PXP_WFB_ARRAY_PIXEL3_MASK_BUF_SEL)
+#define BV_PXP_WFB_ARRAY_PIXEL3_MASK_BUF_SEL__0 0x0
+#define BV_PXP_WFB_ARRAY_PIXEL3_MASK_BUF_SEL__1 0x1
+#define BV_PXP_WFB_ARRAY_PIXEL3_MASK_BUF_SEL__2 0x2
+#define BP_PXP_WFB_ARRAY_PIXEL3_MASK_RSVD1 26
+#define BM_PXP_WFB_ARRAY_PIXEL3_MASK_RSVD1 0x0C000000
+#define BF_PXP_WFB_ARRAY_PIXEL3_MASK_RSVD1(v) \
+ (((v) << 26) & BM_PXP_WFB_ARRAY_PIXEL3_MASK_RSVD1)
+#define BM_PXP_WFB_ARRAY_PIXEL3_MASK_SIGN_Y 0x02000000
+#define BF_PXP_WFB_ARRAY_PIXEL3_MASK_SIGN_Y(v) \
+ (((v) << 25) & BM_PXP_WFB_ARRAY_PIXEL3_MASK_SIGN_Y)
+#define BV_PXP_WFB_ARRAY_PIXEL3_MASK_SIGN_Y__0 0x0
+#define BV_PXP_WFB_ARRAY_PIXEL3_MASK_SIGN_Y__1 0x1
+#define BM_PXP_WFB_ARRAY_PIXEL3_MASK_SIGN_X 0x01000000
+#define BF_PXP_WFB_ARRAY_PIXEL3_MASK_SIGN_X(v) \
+ (((v) << 24) & BM_PXP_WFB_ARRAY_PIXEL3_MASK_SIGN_X)
+#define BV_PXP_WFB_ARRAY_PIXEL3_MASK_SIGN_X__0 0x0
+#define BV_PXP_WFB_ARRAY_PIXEL3_MASK_SIGN_X__1 0x1
+#define BP_PXP_WFB_ARRAY_PIXEL3_MASK_RSVD2 22
+#define BM_PXP_WFB_ARRAY_PIXEL3_MASK_RSVD2 0x00C00000
+#define BF_PXP_WFB_ARRAY_PIXEL3_MASK_RSVD2(v) \
+ (((v) << 22) & BM_PXP_WFB_ARRAY_PIXEL3_MASK_RSVD2)
+#define BP_PXP_WFB_ARRAY_PIXEL3_MASK_OFFSET_Y 20
+#define BM_PXP_WFB_ARRAY_PIXEL3_MASK_OFFSET_Y 0x00300000
+#define BF_PXP_WFB_ARRAY_PIXEL3_MASK_OFFSET_Y(v) \
+ (((v) << 20) & BM_PXP_WFB_ARRAY_PIXEL3_MASK_OFFSET_Y)
+#define BP_PXP_WFB_ARRAY_PIXEL3_MASK_RSVD3 18
+#define BM_PXP_WFB_ARRAY_PIXEL3_MASK_RSVD3 0x000C0000
+#define BF_PXP_WFB_ARRAY_PIXEL3_MASK_RSVD3(v) \
+ (((v) << 18) & BM_PXP_WFB_ARRAY_PIXEL3_MASK_RSVD3)
+#define BP_PXP_WFB_ARRAY_PIXEL3_MASK_OFFSET_X 16
+#define BM_PXP_WFB_ARRAY_PIXEL3_MASK_OFFSET_X 0x00030000
+#define BF_PXP_WFB_ARRAY_PIXEL3_MASK_OFFSET_X(v) \
+ (((v) << 16) & BM_PXP_WFB_ARRAY_PIXEL3_MASK_OFFSET_X)
+#define BP_PXP_WFB_ARRAY_PIXEL3_MASK_RSVD4 13
+#define BM_PXP_WFB_ARRAY_PIXEL3_MASK_RSVD4 0x0000E000
+#define BF_PXP_WFB_ARRAY_PIXEL3_MASK_RSVD4(v) \
+ (((v) << 13) & BM_PXP_WFB_ARRAY_PIXEL3_MASK_RSVD4)
+#define BP_PXP_WFB_ARRAY_PIXEL3_MASK_H_OFS 8
+#define BM_PXP_WFB_ARRAY_PIXEL3_MASK_H_OFS 0x00001F00
+#define BF_PXP_WFB_ARRAY_PIXEL3_MASK_H_OFS(v) \
+ (((v) << 8) & BM_PXP_WFB_ARRAY_PIXEL3_MASK_H_OFS)
+#define BP_PXP_WFB_ARRAY_PIXEL3_MASK_RSVD5 5
+#define BM_PXP_WFB_ARRAY_PIXEL3_MASK_RSVD5 0x000000E0
+#define BF_PXP_WFB_ARRAY_PIXEL3_MASK_RSVD5(v) \
+ (((v) << 5) & BM_PXP_WFB_ARRAY_PIXEL3_MASK_RSVD5)
+#define BP_PXP_WFB_ARRAY_PIXEL3_MASK_L_OFS 0
+#define BM_PXP_WFB_ARRAY_PIXEL3_MASK_L_OFS 0x0000001F
+#define BF_PXP_WFB_ARRAY_PIXEL3_MASK_L_OFS(v) \
+ (((v) << 0) & BM_PXP_WFB_ARRAY_PIXEL3_MASK_L_OFS)
+
+#define HW_PXP_WFB_ARRAY_PIXEL4_MASK (0x000011b0)
+
+#define BP_PXP_WFB_ARRAY_PIXEL4_MASK_RSVD0 30
+#define BM_PXP_WFB_ARRAY_PIXEL4_MASK_RSVD0 0xC0000000
+#define BF_PXP_WFB_ARRAY_PIXEL4_MASK_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFB_ARRAY_PIXEL4_MASK_RSVD0)
+#define BP_PXP_WFB_ARRAY_PIXEL4_MASK_BUF_SEL 28
+#define BM_PXP_WFB_ARRAY_PIXEL4_MASK_BUF_SEL 0x30000000
+#define BF_PXP_WFB_ARRAY_PIXEL4_MASK_BUF_SEL(v) \
+ (((v) << 28) & BM_PXP_WFB_ARRAY_PIXEL4_MASK_BUF_SEL)
+#define BV_PXP_WFB_ARRAY_PIXEL4_MASK_BUF_SEL__0 0x0
+#define BV_PXP_WFB_ARRAY_PIXEL4_MASK_BUF_SEL__1 0x1
+#define BV_PXP_WFB_ARRAY_PIXEL4_MASK_BUF_SEL__2 0x2
+#define BP_PXP_WFB_ARRAY_PIXEL4_MASK_RSVD1 26
+#define BM_PXP_WFB_ARRAY_PIXEL4_MASK_RSVD1 0x0C000000
+#define BF_PXP_WFB_ARRAY_PIXEL4_MASK_RSVD1(v) \
+ (((v) << 26) & BM_PXP_WFB_ARRAY_PIXEL4_MASK_RSVD1)
+#define BM_PXP_WFB_ARRAY_PIXEL4_MASK_SIGN_Y 0x02000000
+#define BF_PXP_WFB_ARRAY_PIXEL4_MASK_SIGN_Y(v) \
+ (((v) << 25) & BM_PXP_WFB_ARRAY_PIXEL4_MASK_SIGN_Y)
+#define BV_PXP_WFB_ARRAY_PIXEL4_MASK_SIGN_Y__0 0x0
+#define BV_PXP_WFB_ARRAY_PIXEL4_MASK_SIGN_Y__1 0x1
+#define BM_PXP_WFB_ARRAY_PIXEL4_MASK_SIGN_X 0x01000000
+#define BF_PXP_WFB_ARRAY_PIXEL4_MASK_SIGN_X(v) \
+ (((v) << 24) & BM_PXP_WFB_ARRAY_PIXEL4_MASK_SIGN_X)
+#define BV_PXP_WFB_ARRAY_PIXEL4_MASK_SIGN_X__0 0x0
+#define BV_PXP_WFB_ARRAY_PIXEL4_MASK_SIGN_X__1 0x1
+#define BP_PXP_WFB_ARRAY_PIXEL4_MASK_RSVD2 22
+#define BM_PXP_WFB_ARRAY_PIXEL4_MASK_RSVD2 0x00C00000
+#define BF_PXP_WFB_ARRAY_PIXEL4_MASK_RSVD2(v) \
+ (((v) << 22) & BM_PXP_WFB_ARRAY_PIXEL4_MASK_RSVD2)
+#define BP_PXP_WFB_ARRAY_PIXEL4_MASK_OFFSET_Y 20
+#define BM_PXP_WFB_ARRAY_PIXEL4_MASK_OFFSET_Y 0x00300000
+#define BF_PXP_WFB_ARRAY_PIXEL4_MASK_OFFSET_Y(v) \
+ (((v) << 20) & BM_PXP_WFB_ARRAY_PIXEL4_MASK_OFFSET_Y)
+#define BP_PXP_WFB_ARRAY_PIXEL4_MASK_RSVD3 18
+#define BM_PXP_WFB_ARRAY_PIXEL4_MASK_RSVD3 0x000C0000
+#define BF_PXP_WFB_ARRAY_PIXEL4_MASK_RSVD3(v) \
+ (((v) << 18) & BM_PXP_WFB_ARRAY_PIXEL4_MASK_RSVD3)
+#define BP_PXP_WFB_ARRAY_PIXEL4_MASK_OFFSET_X 16
+#define BM_PXP_WFB_ARRAY_PIXEL4_MASK_OFFSET_X 0x00030000
+#define BF_PXP_WFB_ARRAY_PIXEL4_MASK_OFFSET_X(v) \
+ (((v) << 16) & BM_PXP_WFB_ARRAY_PIXEL4_MASK_OFFSET_X)
+#define BP_PXP_WFB_ARRAY_PIXEL4_MASK_RSVD4 13
+#define BM_PXP_WFB_ARRAY_PIXEL4_MASK_RSVD4 0x0000E000
+#define BF_PXP_WFB_ARRAY_PIXEL4_MASK_RSVD4(v) \
+ (((v) << 13) & BM_PXP_WFB_ARRAY_PIXEL4_MASK_RSVD4)
+#define BP_PXP_WFB_ARRAY_PIXEL4_MASK_H_OFS 8
+#define BM_PXP_WFB_ARRAY_PIXEL4_MASK_H_OFS 0x00001F00
+#define BF_PXP_WFB_ARRAY_PIXEL4_MASK_H_OFS(v) \
+ (((v) << 8) & BM_PXP_WFB_ARRAY_PIXEL4_MASK_H_OFS)
+#define BP_PXP_WFB_ARRAY_PIXEL4_MASK_RSVD5 5
+#define BM_PXP_WFB_ARRAY_PIXEL4_MASK_RSVD5 0x000000E0
+#define BF_PXP_WFB_ARRAY_PIXEL4_MASK_RSVD5(v) \
+ (((v) << 5) & BM_PXP_WFB_ARRAY_PIXEL4_MASK_RSVD5)
+#define BP_PXP_WFB_ARRAY_PIXEL4_MASK_L_OFS 0
+#define BM_PXP_WFB_ARRAY_PIXEL4_MASK_L_OFS 0x0000001F
+#define BF_PXP_WFB_ARRAY_PIXEL4_MASK_L_OFS(v) \
+ (((v) << 0) & BM_PXP_WFB_ARRAY_PIXEL4_MASK_L_OFS)
+
+#define HW_PXP_WFB_ARRAY_PIXEL5_MASK (0x000011c0)
+
+#define BP_PXP_WFB_ARRAY_PIXEL5_MASK_RSVD0 30
+#define BM_PXP_WFB_ARRAY_PIXEL5_MASK_RSVD0 0xC0000000
+#define BF_PXP_WFB_ARRAY_PIXEL5_MASK_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFB_ARRAY_PIXEL5_MASK_RSVD0)
+#define BP_PXP_WFB_ARRAY_PIXEL5_MASK_BUF_SEL 28
+#define BM_PXP_WFB_ARRAY_PIXEL5_MASK_BUF_SEL 0x30000000
+#define BF_PXP_WFB_ARRAY_PIXEL5_MASK_BUF_SEL(v) \
+ (((v) << 28) & BM_PXP_WFB_ARRAY_PIXEL5_MASK_BUF_SEL)
+#define BV_PXP_WFB_ARRAY_PIXEL5_MASK_BUF_SEL__0 0x0
+#define BV_PXP_WFB_ARRAY_PIXEL5_MASK_BUF_SEL__1 0x1
+#define BV_PXP_WFB_ARRAY_PIXEL5_MASK_BUF_SEL__2 0x2
+#define BP_PXP_WFB_ARRAY_PIXEL5_MASK_RSVD1 26
+#define BM_PXP_WFB_ARRAY_PIXEL5_MASK_RSVD1 0x0C000000
+#define BF_PXP_WFB_ARRAY_PIXEL5_MASK_RSVD1(v) \
+ (((v) << 26) & BM_PXP_WFB_ARRAY_PIXEL5_MASK_RSVD1)
+#define BM_PXP_WFB_ARRAY_PIXEL5_MASK_SIGN_Y 0x02000000
+#define BF_PXP_WFB_ARRAY_PIXEL5_MASK_SIGN_Y(v) \
+ (((v) << 25) & BM_PXP_WFB_ARRAY_PIXEL5_MASK_SIGN_Y)
+#define BV_PXP_WFB_ARRAY_PIXEL5_MASK_SIGN_Y__0 0x0
+#define BV_PXP_WFB_ARRAY_PIXEL5_MASK_SIGN_Y__1 0x1
+#define BM_PXP_WFB_ARRAY_PIXEL5_MASK_SIGN_X 0x01000000
+#define BF_PXP_WFB_ARRAY_PIXEL5_MASK_SIGN_X(v) \
+ (((v) << 24) & BM_PXP_WFB_ARRAY_PIXEL5_MASK_SIGN_X)
+#define BV_PXP_WFB_ARRAY_PIXEL5_MASK_SIGN_X__0 0x0
+#define BV_PXP_WFB_ARRAY_PIXEL5_MASK_SIGN_X__1 0x1
+#define BP_PXP_WFB_ARRAY_PIXEL5_MASK_RSVD2 22
+#define BM_PXP_WFB_ARRAY_PIXEL5_MASK_RSVD2 0x00C00000
+#define BF_PXP_WFB_ARRAY_PIXEL5_MASK_RSVD2(v) \
+ (((v) << 22) & BM_PXP_WFB_ARRAY_PIXEL5_MASK_RSVD2)
+#define BP_PXP_WFB_ARRAY_PIXEL5_MASK_OFFSET_Y 20
+#define BM_PXP_WFB_ARRAY_PIXEL5_MASK_OFFSET_Y 0x00300000
+#define BF_PXP_WFB_ARRAY_PIXEL5_MASK_OFFSET_Y(v) \
+ (((v) << 20) & BM_PXP_WFB_ARRAY_PIXEL5_MASK_OFFSET_Y)
+#define BP_PXP_WFB_ARRAY_PIXEL5_MASK_RSVD3 18
+#define BM_PXP_WFB_ARRAY_PIXEL5_MASK_RSVD3 0x000C0000
+#define BF_PXP_WFB_ARRAY_PIXEL5_MASK_RSVD3(v) \
+ (((v) << 18) & BM_PXP_WFB_ARRAY_PIXEL5_MASK_RSVD3)
+#define BP_PXP_WFB_ARRAY_PIXEL5_MASK_OFFSET_X 16
+#define BM_PXP_WFB_ARRAY_PIXEL5_MASK_OFFSET_X 0x00030000
+#define BF_PXP_WFB_ARRAY_PIXEL5_MASK_OFFSET_X(v) \
+ (((v) << 16) & BM_PXP_WFB_ARRAY_PIXEL5_MASK_OFFSET_X)
+#define BP_PXP_WFB_ARRAY_PIXEL5_MASK_RSVD4 13
+#define BM_PXP_WFB_ARRAY_PIXEL5_MASK_RSVD4 0x0000E000
+#define BF_PXP_WFB_ARRAY_PIXEL5_MASK_RSVD4(v) \
+ (((v) << 13) & BM_PXP_WFB_ARRAY_PIXEL5_MASK_RSVD4)
+#define BP_PXP_WFB_ARRAY_PIXEL5_MASK_H_OFS 8
+#define BM_PXP_WFB_ARRAY_PIXEL5_MASK_H_OFS 0x00001F00
+#define BF_PXP_WFB_ARRAY_PIXEL5_MASK_H_OFS(v) \
+ (((v) << 8) & BM_PXP_WFB_ARRAY_PIXEL5_MASK_H_OFS)
+#define BP_PXP_WFB_ARRAY_PIXEL5_MASK_RSVD5 5
+#define BM_PXP_WFB_ARRAY_PIXEL5_MASK_RSVD5 0x000000E0
+#define BF_PXP_WFB_ARRAY_PIXEL5_MASK_RSVD5(v) \
+ (((v) << 5) & BM_PXP_WFB_ARRAY_PIXEL5_MASK_RSVD5)
+#define BP_PXP_WFB_ARRAY_PIXEL5_MASK_L_OFS 0
+#define BM_PXP_WFB_ARRAY_PIXEL5_MASK_L_OFS 0x0000001F
+#define BF_PXP_WFB_ARRAY_PIXEL5_MASK_L_OFS(v) \
+ (((v) << 0) & BM_PXP_WFB_ARRAY_PIXEL5_MASK_L_OFS)
+
+#define HW_PXP_WFB_ARRAY_PIXEL6_MASK (0x000011d0)
+
+#define BP_PXP_WFB_ARRAY_PIXEL6_MASK_RSVD0 30
+#define BM_PXP_WFB_ARRAY_PIXEL6_MASK_RSVD0 0xC0000000
+#define BF_PXP_WFB_ARRAY_PIXEL6_MASK_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFB_ARRAY_PIXEL6_MASK_RSVD0)
+#define BP_PXP_WFB_ARRAY_PIXEL6_MASK_BUF_SEL 28
+#define BM_PXP_WFB_ARRAY_PIXEL6_MASK_BUF_SEL 0x30000000
+#define BF_PXP_WFB_ARRAY_PIXEL6_MASK_BUF_SEL(v) \
+ (((v) << 28) & BM_PXP_WFB_ARRAY_PIXEL6_MASK_BUF_SEL)
+#define BV_PXP_WFB_ARRAY_PIXEL6_MASK_BUF_SEL__0 0x0
+#define BV_PXP_WFB_ARRAY_PIXEL6_MASK_BUF_SEL__1 0x1
+#define BV_PXP_WFB_ARRAY_PIXEL6_MASK_BUF_SEL__2 0x2
+#define BP_PXP_WFB_ARRAY_PIXEL6_MASK_RSVD1 26
+#define BM_PXP_WFB_ARRAY_PIXEL6_MASK_RSVD1 0x0C000000
+#define BF_PXP_WFB_ARRAY_PIXEL6_MASK_RSVD1(v) \
+ (((v) << 26) & BM_PXP_WFB_ARRAY_PIXEL6_MASK_RSVD1)
+#define BM_PXP_WFB_ARRAY_PIXEL6_MASK_SIGN_Y 0x02000000
+#define BF_PXP_WFB_ARRAY_PIXEL6_MASK_SIGN_Y(v) \
+ (((v) << 25) & BM_PXP_WFB_ARRAY_PIXEL6_MASK_SIGN_Y)
+#define BV_PXP_WFB_ARRAY_PIXEL6_MASK_SIGN_Y__0 0x0
+#define BV_PXP_WFB_ARRAY_PIXEL6_MASK_SIGN_Y__1 0x1
+#define BM_PXP_WFB_ARRAY_PIXEL6_MASK_SIGN_X 0x01000000
+#define BF_PXP_WFB_ARRAY_PIXEL6_MASK_SIGN_X(v) \
+ (((v) << 24) & BM_PXP_WFB_ARRAY_PIXEL6_MASK_SIGN_X)
+#define BV_PXP_WFB_ARRAY_PIXEL6_MASK_SIGN_X__0 0x0
+#define BV_PXP_WFB_ARRAY_PIXEL6_MASK_SIGN_X__1 0x1
+#define BP_PXP_WFB_ARRAY_PIXEL6_MASK_RSVD2 22
+#define BM_PXP_WFB_ARRAY_PIXEL6_MASK_RSVD2 0x00C00000
+#define BF_PXP_WFB_ARRAY_PIXEL6_MASK_RSVD2(v) \
+ (((v) << 22) & BM_PXP_WFB_ARRAY_PIXEL6_MASK_RSVD2)
+#define BP_PXP_WFB_ARRAY_PIXEL6_MASK_OFFSET_Y 20
+#define BM_PXP_WFB_ARRAY_PIXEL6_MASK_OFFSET_Y 0x00300000
+#define BF_PXP_WFB_ARRAY_PIXEL6_MASK_OFFSET_Y(v) \
+ (((v) << 20) & BM_PXP_WFB_ARRAY_PIXEL6_MASK_OFFSET_Y)
+#define BP_PXP_WFB_ARRAY_PIXEL6_MASK_RSVD3 18
+#define BM_PXP_WFB_ARRAY_PIXEL6_MASK_RSVD3 0x000C0000
+#define BF_PXP_WFB_ARRAY_PIXEL6_MASK_RSVD3(v) \
+ (((v) << 18) & BM_PXP_WFB_ARRAY_PIXEL6_MASK_RSVD3)
+#define BP_PXP_WFB_ARRAY_PIXEL6_MASK_OFFSET_X 16
+#define BM_PXP_WFB_ARRAY_PIXEL6_MASK_OFFSET_X 0x00030000
+#define BF_PXP_WFB_ARRAY_PIXEL6_MASK_OFFSET_X(v) \
+ (((v) << 16) & BM_PXP_WFB_ARRAY_PIXEL6_MASK_OFFSET_X)
+#define BP_PXP_WFB_ARRAY_PIXEL6_MASK_RSVD4 13
+#define BM_PXP_WFB_ARRAY_PIXEL6_MASK_RSVD4 0x0000E000
+#define BF_PXP_WFB_ARRAY_PIXEL6_MASK_RSVD4(v) \
+ (((v) << 13) & BM_PXP_WFB_ARRAY_PIXEL6_MASK_RSVD4)
+#define BP_PXP_WFB_ARRAY_PIXEL6_MASK_H_OFS 8
+#define BM_PXP_WFB_ARRAY_PIXEL6_MASK_H_OFS 0x00001F00
+#define BF_PXP_WFB_ARRAY_PIXEL6_MASK_H_OFS(v) \
+ (((v) << 8) & BM_PXP_WFB_ARRAY_PIXEL6_MASK_H_OFS)
+#define BP_PXP_WFB_ARRAY_PIXEL6_MASK_RSVD5 5
+#define BM_PXP_WFB_ARRAY_PIXEL6_MASK_RSVD5 0x000000E0
+#define BF_PXP_WFB_ARRAY_PIXEL6_MASK_RSVD5(v) \
+ (((v) << 5) & BM_PXP_WFB_ARRAY_PIXEL6_MASK_RSVD5)
+#define BP_PXP_WFB_ARRAY_PIXEL6_MASK_L_OFS 0
+#define BM_PXP_WFB_ARRAY_PIXEL6_MASK_L_OFS 0x0000001F
+#define BF_PXP_WFB_ARRAY_PIXEL6_MASK_L_OFS(v) \
+ (((v) << 0) & BM_PXP_WFB_ARRAY_PIXEL6_MASK_L_OFS)
+
+#define HW_PXP_WFB_ARRAY_PIXEL7_MASK (0x000011e0)
+
+#define BP_PXP_WFB_ARRAY_PIXEL7_MASK_RSVD0 30
+#define BM_PXP_WFB_ARRAY_PIXEL7_MASK_RSVD0 0xC0000000
+#define BF_PXP_WFB_ARRAY_PIXEL7_MASK_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFB_ARRAY_PIXEL7_MASK_RSVD0)
+#define BP_PXP_WFB_ARRAY_PIXEL7_MASK_BUF_SEL 28
+#define BM_PXP_WFB_ARRAY_PIXEL7_MASK_BUF_SEL 0x30000000
+#define BF_PXP_WFB_ARRAY_PIXEL7_MASK_BUF_SEL(v) \
+ (((v) << 28) & BM_PXP_WFB_ARRAY_PIXEL7_MASK_BUF_SEL)
+#define BV_PXP_WFB_ARRAY_PIXEL7_MASK_BUF_SEL__0 0x0
+#define BV_PXP_WFB_ARRAY_PIXEL7_MASK_BUF_SEL__1 0x1
+#define BV_PXP_WFB_ARRAY_PIXEL7_MASK_BUF_SEL__2 0x2
+#define BP_PXP_WFB_ARRAY_PIXEL7_MASK_RSVD1 26
+#define BM_PXP_WFB_ARRAY_PIXEL7_MASK_RSVD1 0x0C000000
+#define BF_PXP_WFB_ARRAY_PIXEL7_MASK_RSVD1(v) \
+ (((v) << 26) & BM_PXP_WFB_ARRAY_PIXEL7_MASK_RSVD1)
+#define BM_PXP_WFB_ARRAY_PIXEL7_MASK_SIGN_Y 0x02000000
+#define BF_PXP_WFB_ARRAY_PIXEL7_MASK_SIGN_Y(v) \
+ (((v) << 25) & BM_PXP_WFB_ARRAY_PIXEL7_MASK_SIGN_Y)
+#define BV_PXP_WFB_ARRAY_PIXEL7_MASK_SIGN_Y__0 0x0
+#define BV_PXP_WFB_ARRAY_PIXEL7_MASK_SIGN_Y__1 0x1
+#define BM_PXP_WFB_ARRAY_PIXEL7_MASK_SIGN_X 0x01000000
+#define BF_PXP_WFB_ARRAY_PIXEL7_MASK_SIGN_X(v) \
+ (((v) << 24) & BM_PXP_WFB_ARRAY_PIXEL7_MASK_SIGN_X)
+#define BV_PXP_WFB_ARRAY_PIXEL7_MASK_SIGN_X__0 0x0
+#define BV_PXP_WFB_ARRAY_PIXEL7_MASK_SIGN_X__1 0x1
+#define BP_PXP_WFB_ARRAY_PIXEL7_MASK_RSVD2 22
+#define BM_PXP_WFB_ARRAY_PIXEL7_MASK_RSVD2 0x00C00000
+#define BF_PXP_WFB_ARRAY_PIXEL7_MASK_RSVD2(v) \
+ (((v) << 22) & BM_PXP_WFB_ARRAY_PIXEL7_MASK_RSVD2)
+#define BP_PXP_WFB_ARRAY_PIXEL7_MASK_OFFSET_Y 20
+#define BM_PXP_WFB_ARRAY_PIXEL7_MASK_OFFSET_Y 0x00300000
+#define BF_PXP_WFB_ARRAY_PIXEL7_MASK_OFFSET_Y(v) \
+ (((v) << 20) & BM_PXP_WFB_ARRAY_PIXEL7_MASK_OFFSET_Y)
+#define BP_PXP_WFB_ARRAY_PIXEL7_MASK_RSVD3 18
+#define BM_PXP_WFB_ARRAY_PIXEL7_MASK_RSVD3 0x000C0000
+#define BF_PXP_WFB_ARRAY_PIXEL7_MASK_RSVD3(v) \
+ (((v) << 18) & BM_PXP_WFB_ARRAY_PIXEL7_MASK_RSVD3)
+#define BP_PXP_WFB_ARRAY_PIXEL7_MASK_OFFSET_X 16
+#define BM_PXP_WFB_ARRAY_PIXEL7_MASK_OFFSET_X 0x00030000
+#define BF_PXP_WFB_ARRAY_PIXEL7_MASK_OFFSET_X(v) \
+ (((v) << 16) & BM_PXP_WFB_ARRAY_PIXEL7_MASK_OFFSET_X)
+#define BP_PXP_WFB_ARRAY_PIXEL7_MASK_RSVD4 13
+#define BM_PXP_WFB_ARRAY_PIXEL7_MASK_RSVD4 0x0000E000
+#define BF_PXP_WFB_ARRAY_PIXEL7_MASK_RSVD4(v) \
+ (((v) << 13) & BM_PXP_WFB_ARRAY_PIXEL7_MASK_RSVD4)
+#define BP_PXP_WFB_ARRAY_PIXEL7_MASK_H_OFS 8
+#define BM_PXP_WFB_ARRAY_PIXEL7_MASK_H_OFS 0x00001F00
+#define BF_PXP_WFB_ARRAY_PIXEL7_MASK_H_OFS(v) \
+ (((v) << 8) & BM_PXP_WFB_ARRAY_PIXEL7_MASK_H_OFS)
+#define BP_PXP_WFB_ARRAY_PIXEL7_MASK_RSVD5 5
+#define BM_PXP_WFB_ARRAY_PIXEL7_MASK_RSVD5 0x000000E0
+#define BF_PXP_WFB_ARRAY_PIXEL7_MASK_RSVD5(v) \
+ (((v) << 5) & BM_PXP_WFB_ARRAY_PIXEL7_MASK_RSVD5)
+#define BP_PXP_WFB_ARRAY_PIXEL7_MASK_L_OFS 0
+#define BM_PXP_WFB_ARRAY_PIXEL7_MASK_L_OFS 0x0000001F
+#define BF_PXP_WFB_ARRAY_PIXEL7_MASK_L_OFS(v) \
+ (((v) << 0) & BM_PXP_WFB_ARRAY_PIXEL7_MASK_L_OFS)
+
+#define HW_PXP_WFB_ARRAY_FLAG0_MASK (0x000011f0)
+
+#define BP_PXP_WFB_ARRAY_FLAG0_MASK_RSVD0 30
+#define BM_PXP_WFB_ARRAY_FLAG0_MASK_RSVD0 0xC0000000
+#define BF_PXP_WFB_ARRAY_FLAG0_MASK_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFB_ARRAY_FLAG0_MASK_RSVD0)
+#define BP_PXP_WFB_ARRAY_FLAG0_MASK_BUF_SEL 28
+#define BM_PXP_WFB_ARRAY_FLAG0_MASK_BUF_SEL 0x30000000
+#define BF_PXP_WFB_ARRAY_FLAG0_MASK_BUF_SEL(v) \
+ (((v) << 28) & BM_PXP_WFB_ARRAY_FLAG0_MASK_BUF_SEL)
+#define BV_PXP_WFB_ARRAY_FLAG0_MASK_BUF_SEL__0 0x0
+#define BV_PXP_WFB_ARRAY_FLAG0_MASK_BUF_SEL__1 0x1
+#define BV_PXP_WFB_ARRAY_FLAG0_MASK_BUF_SEL__2 0x2
+#define BP_PXP_WFB_ARRAY_FLAG0_MASK_RSVD1 26
+#define BM_PXP_WFB_ARRAY_FLAG0_MASK_RSVD1 0x0C000000
+#define BF_PXP_WFB_ARRAY_FLAG0_MASK_RSVD1(v) \
+ (((v) << 26) & BM_PXP_WFB_ARRAY_FLAG0_MASK_RSVD1)
+#define BM_PXP_WFB_ARRAY_FLAG0_MASK_SIGN_Y 0x02000000
+#define BF_PXP_WFB_ARRAY_FLAG0_MASK_SIGN_Y(v) \
+ (((v) << 25) & BM_PXP_WFB_ARRAY_FLAG0_MASK_SIGN_Y)
+#define BV_PXP_WFB_ARRAY_FLAG0_MASK_SIGN_Y__0 0x0
+#define BV_PXP_WFB_ARRAY_FLAG0_MASK_SIGN_Y__1 0x1
+#define BM_PXP_WFB_ARRAY_FLAG0_MASK_SIGN_X 0x01000000
+#define BF_PXP_WFB_ARRAY_FLAG0_MASK_SIGN_X(v) \
+ (((v) << 24) & BM_PXP_WFB_ARRAY_FLAG0_MASK_SIGN_X)
+#define BV_PXP_WFB_ARRAY_FLAG0_MASK_SIGN_X__0 0x0
+#define BV_PXP_WFB_ARRAY_FLAG0_MASK_SIGN_X__1 0x1
+#define BP_PXP_WFB_ARRAY_FLAG0_MASK_RSVD2 22
+#define BM_PXP_WFB_ARRAY_FLAG0_MASK_RSVD2 0x00C00000
+#define BF_PXP_WFB_ARRAY_FLAG0_MASK_RSVD2(v) \
+ (((v) << 22) & BM_PXP_WFB_ARRAY_FLAG0_MASK_RSVD2)
+#define BP_PXP_WFB_ARRAY_FLAG0_MASK_OFFSET_Y 20
+#define BM_PXP_WFB_ARRAY_FLAG0_MASK_OFFSET_Y 0x00300000
+#define BF_PXP_WFB_ARRAY_FLAG0_MASK_OFFSET_Y(v) \
+ (((v) << 20) & BM_PXP_WFB_ARRAY_FLAG0_MASK_OFFSET_Y)
+#define BP_PXP_WFB_ARRAY_FLAG0_MASK_RSVD3 18
+#define BM_PXP_WFB_ARRAY_FLAG0_MASK_RSVD3 0x000C0000
+#define BF_PXP_WFB_ARRAY_FLAG0_MASK_RSVD3(v) \
+ (((v) << 18) & BM_PXP_WFB_ARRAY_FLAG0_MASK_RSVD3)
+#define BP_PXP_WFB_ARRAY_FLAG0_MASK_OFFSET_X 16
+#define BM_PXP_WFB_ARRAY_FLAG0_MASK_OFFSET_X 0x00030000
+#define BF_PXP_WFB_ARRAY_FLAG0_MASK_OFFSET_X(v) \
+ (((v) << 16) & BM_PXP_WFB_ARRAY_FLAG0_MASK_OFFSET_X)
+#define BP_PXP_WFB_ARRAY_FLAG0_MASK_RSVD4 13
+#define BM_PXP_WFB_ARRAY_FLAG0_MASK_RSVD4 0x0000E000
+#define BF_PXP_WFB_ARRAY_FLAG0_MASK_RSVD4(v) \
+ (((v) << 13) & BM_PXP_WFB_ARRAY_FLAG0_MASK_RSVD4)
+#define BP_PXP_WFB_ARRAY_FLAG0_MASK_H_OFS 8
+#define BM_PXP_WFB_ARRAY_FLAG0_MASK_H_OFS 0x00001F00
+#define BF_PXP_WFB_ARRAY_FLAG0_MASK_H_OFS(v) \
+ (((v) << 8) & BM_PXP_WFB_ARRAY_FLAG0_MASK_H_OFS)
+#define BP_PXP_WFB_ARRAY_FLAG0_MASK_RSVD5 5
+#define BM_PXP_WFB_ARRAY_FLAG0_MASK_RSVD5 0x000000E0
+#define BF_PXP_WFB_ARRAY_FLAG0_MASK_RSVD5(v) \
+ (((v) << 5) & BM_PXP_WFB_ARRAY_FLAG0_MASK_RSVD5)
+#define BP_PXP_WFB_ARRAY_FLAG0_MASK_L_OFS 0
+#define BM_PXP_WFB_ARRAY_FLAG0_MASK_L_OFS 0x0000001F
+#define BF_PXP_WFB_ARRAY_FLAG0_MASK_L_OFS(v) \
+ (((v) << 0) & BM_PXP_WFB_ARRAY_FLAG0_MASK_L_OFS)
+
+#define HW_PXP_WFB_ARRAY_FLAG1_MASK (0x00001200)
+
+#define BP_PXP_WFB_ARRAY_FLAG1_MASK_RSVD0 30
+#define BM_PXP_WFB_ARRAY_FLAG1_MASK_RSVD0 0xC0000000
+#define BF_PXP_WFB_ARRAY_FLAG1_MASK_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFB_ARRAY_FLAG1_MASK_RSVD0)
+#define BP_PXP_WFB_ARRAY_FLAG1_MASK_BUF_SEL 28
+#define BM_PXP_WFB_ARRAY_FLAG1_MASK_BUF_SEL 0x30000000
+#define BF_PXP_WFB_ARRAY_FLAG1_MASK_BUF_SEL(v) \
+ (((v) << 28) & BM_PXP_WFB_ARRAY_FLAG1_MASK_BUF_SEL)
+#define BV_PXP_WFB_ARRAY_FLAG1_MASK_BUF_SEL__0 0x0
+#define BV_PXP_WFB_ARRAY_FLAG1_MASK_BUF_SEL__1 0x1
+#define BV_PXP_WFB_ARRAY_FLAG1_MASK_BUF_SEL__2 0x2
+#define BP_PXP_WFB_ARRAY_FLAG1_MASK_RSVD1 26
+#define BM_PXP_WFB_ARRAY_FLAG1_MASK_RSVD1 0x0C000000
+#define BF_PXP_WFB_ARRAY_FLAG1_MASK_RSVD1(v) \
+ (((v) << 26) & BM_PXP_WFB_ARRAY_FLAG1_MASK_RSVD1)
+#define BM_PXP_WFB_ARRAY_FLAG1_MASK_SIGN_Y 0x02000000
+#define BF_PXP_WFB_ARRAY_FLAG1_MASK_SIGN_Y(v) \
+ (((v) << 25) & BM_PXP_WFB_ARRAY_FLAG1_MASK_SIGN_Y)
+#define BV_PXP_WFB_ARRAY_FLAG1_MASK_SIGN_Y__0 0x0
+#define BV_PXP_WFB_ARRAY_FLAG1_MASK_SIGN_Y__1 0x1
+#define BM_PXP_WFB_ARRAY_FLAG1_MASK_SIGN_X 0x01000000
+#define BF_PXP_WFB_ARRAY_FLAG1_MASK_SIGN_X(v) \
+ (((v) << 24) & BM_PXP_WFB_ARRAY_FLAG1_MASK_SIGN_X)
+#define BV_PXP_WFB_ARRAY_FLAG1_MASK_SIGN_X__0 0x0
+#define BV_PXP_WFB_ARRAY_FLAG1_MASK_SIGN_X__1 0x1
+#define BP_PXP_WFB_ARRAY_FLAG1_MASK_RSVD2 22
+#define BM_PXP_WFB_ARRAY_FLAG1_MASK_RSVD2 0x00C00000
+#define BF_PXP_WFB_ARRAY_FLAG1_MASK_RSVD2(v) \
+ (((v) << 22) & BM_PXP_WFB_ARRAY_FLAG1_MASK_RSVD2)
+#define BP_PXP_WFB_ARRAY_FLAG1_MASK_OFFSET_Y 20
+#define BM_PXP_WFB_ARRAY_FLAG1_MASK_OFFSET_Y 0x00300000
+#define BF_PXP_WFB_ARRAY_FLAG1_MASK_OFFSET_Y(v) \
+ (((v) << 20) & BM_PXP_WFB_ARRAY_FLAG1_MASK_OFFSET_Y)
+#define BP_PXP_WFB_ARRAY_FLAG1_MASK_RSVD3 18
+#define BM_PXP_WFB_ARRAY_FLAG1_MASK_RSVD3 0x000C0000
+#define BF_PXP_WFB_ARRAY_FLAG1_MASK_RSVD3(v) \
+ (((v) << 18) & BM_PXP_WFB_ARRAY_FLAG1_MASK_RSVD3)
+#define BP_PXP_WFB_ARRAY_FLAG1_MASK_OFFSET_X 16
+#define BM_PXP_WFB_ARRAY_FLAG1_MASK_OFFSET_X 0x00030000
+#define BF_PXP_WFB_ARRAY_FLAG1_MASK_OFFSET_X(v) \
+ (((v) << 16) & BM_PXP_WFB_ARRAY_FLAG1_MASK_OFFSET_X)
+#define BP_PXP_WFB_ARRAY_FLAG1_MASK_RSVD4 13
+#define BM_PXP_WFB_ARRAY_FLAG1_MASK_RSVD4 0x0000E000
+#define BF_PXP_WFB_ARRAY_FLAG1_MASK_RSVD4(v) \
+ (((v) << 13) & BM_PXP_WFB_ARRAY_FLAG1_MASK_RSVD4)
+#define BP_PXP_WFB_ARRAY_FLAG1_MASK_H_OFS 8
+#define BM_PXP_WFB_ARRAY_FLAG1_MASK_H_OFS 0x00001F00
+#define BF_PXP_WFB_ARRAY_FLAG1_MASK_H_OFS(v) \
+ (((v) << 8) & BM_PXP_WFB_ARRAY_FLAG1_MASK_H_OFS)
+#define BP_PXP_WFB_ARRAY_FLAG1_MASK_RSVD5 5
+#define BM_PXP_WFB_ARRAY_FLAG1_MASK_RSVD5 0x000000E0
+#define BF_PXP_WFB_ARRAY_FLAG1_MASK_RSVD5(v) \
+ (((v) << 5) & BM_PXP_WFB_ARRAY_FLAG1_MASK_RSVD5)
+#define BP_PXP_WFB_ARRAY_FLAG1_MASK_L_OFS 0
+#define BM_PXP_WFB_ARRAY_FLAG1_MASK_L_OFS 0x0000001F
+#define BF_PXP_WFB_ARRAY_FLAG1_MASK_L_OFS(v) \
+ (((v) << 0) & BM_PXP_WFB_ARRAY_FLAG1_MASK_L_OFS)
+
+#define HW_PXP_WFB_ARRAY_FLAG2_MASK (0x00001210)
+
+#define BP_PXP_WFB_ARRAY_FLAG2_MASK_RSVD0 30
+#define BM_PXP_WFB_ARRAY_FLAG2_MASK_RSVD0 0xC0000000
+#define BF_PXP_WFB_ARRAY_FLAG2_MASK_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFB_ARRAY_FLAG2_MASK_RSVD0)
+#define BP_PXP_WFB_ARRAY_FLAG2_MASK_BUF_SEL 28
+#define BM_PXP_WFB_ARRAY_FLAG2_MASK_BUF_SEL 0x30000000
+#define BF_PXP_WFB_ARRAY_FLAG2_MASK_BUF_SEL(v) \
+ (((v) << 28) & BM_PXP_WFB_ARRAY_FLAG2_MASK_BUF_SEL)
+#define BV_PXP_WFB_ARRAY_FLAG2_MASK_BUF_SEL__0 0x0
+#define BV_PXP_WFB_ARRAY_FLAG2_MASK_BUF_SEL__1 0x1
+#define BV_PXP_WFB_ARRAY_FLAG2_MASK_BUF_SEL__2 0x2
+#define BP_PXP_WFB_ARRAY_FLAG2_MASK_RSVD1 26
+#define BM_PXP_WFB_ARRAY_FLAG2_MASK_RSVD1 0x0C000000
+#define BF_PXP_WFB_ARRAY_FLAG2_MASK_RSVD1(v) \
+ (((v) << 26) & BM_PXP_WFB_ARRAY_FLAG2_MASK_RSVD1)
+#define BM_PXP_WFB_ARRAY_FLAG2_MASK_SIGN_Y 0x02000000
+#define BF_PXP_WFB_ARRAY_FLAG2_MASK_SIGN_Y(v) \
+ (((v) << 25) & BM_PXP_WFB_ARRAY_FLAG2_MASK_SIGN_Y)
+#define BV_PXP_WFB_ARRAY_FLAG2_MASK_SIGN_Y__0 0x0
+#define BV_PXP_WFB_ARRAY_FLAG2_MASK_SIGN_Y__1 0x1
+#define BM_PXP_WFB_ARRAY_FLAG2_MASK_SIGN_X 0x01000000
+#define BF_PXP_WFB_ARRAY_FLAG2_MASK_SIGN_X(v) \
+ (((v) << 24) & BM_PXP_WFB_ARRAY_FLAG2_MASK_SIGN_X)
+#define BV_PXP_WFB_ARRAY_FLAG2_MASK_SIGN_X__0 0x0
+#define BV_PXP_WFB_ARRAY_FLAG2_MASK_SIGN_X__1 0x1
+#define BP_PXP_WFB_ARRAY_FLAG2_MASK_RSVD2 22
+#define BM_PXP_WFB_ARRAY_FLAG2_MASK_RSVD2 0x00C00000
+#define BF_PXP_WFB_ARRAY_FLAG2_MASK_RSVD2(v) \
+ (((v) << 22) & BM_PXP_WFB_ARRAY_FLAG2_MASK_RSVD2)
+#define BP_PXP_WFB_ARRAY_FLAG2_MASK_OFFSET_Y 20
+#define BM_PXP_WFB_ARRAY_FLAG2_MASK_OFFSET_Y 0x00300000
+#define BF_PXP_WFB_ARRAY_FLAG2_MASK_OFFSET_Y(v) \
+ (((v) << 20) & BM_PXP_WFB_ARRAY_FLAG2_MASK_OFFSET_Y)
+#define BP_PXP_WFB_ARRAY_FLAG2_MASK_RSVD3 18
+#define BM_PXP_WFB_ARRAY_FLAG2_MASK_RSVD3 0x000C0000
+#define BF_PXP_WFB_ARRAY_FLAG2_MASK_RSVD3(v) \
+ (((v) << 18) & BM_PXP_WFB_ARRAY_FLAG2_MASK_RSVD3)
+#define BP_PXP_WFB_ARRAY_FLAG2_MASK_OFFSET_X 16
+#define BM_PXP_WFB_ARRAY_FLAG2_MASK_OFFSET_X 0x00030000
+#define BF_PXP_WFB_ARRAY_FLAG2_MASK_OFFSET_X(v) \
+ (((v) << 16) & BM_PXP_WFB_ARRAY_FLAG2_MASK_OFFSET_X)
+#define BP_PXP_WFB_ARRAY_FLAG2_MASK_RSVD4 13
+#define BM_PXP_WFB_ARRAY_FLAG2_MASK_RSVD4 0x0000E000
+#define BF_PXP_WFB_ARRAY_FLAG2_MASK_RSVD4(v) \
+ (((v) << 13) & BM_PXP_WFB_ARRAY_FLAG2_MASK_RSVD4)
+#define BP_PXP_WFB_ARRAY_FLAG2_MASK_H_OFS 8
+#define BM_PXP_WFB_ARRAY_FLAG2_MASK_H_OFS 0x00001F00
+#define BF_PXP_WFB_ARRAY_FLAG2_MASK_H_OFS(v) \
+ (((v) << 8) & BM_PXP_WFB_ARRAY_FLAG2_MASK_H_OFS)
+#define BP_PXP_WFB_ARRAY_FLAG2_MASK_RSVD5 5
+#define BM_PXP_WFB_ARRAY_FLAG2_MASK_RSVD5 0x000000E0
+#define BF_PXP_WFB_ARRAY_FLAG2_MASK_RSVD5(v) \
+ (((v) << 5) & BM_PXP_WFB_ARRAY_FLAG2_MASK_RSVD5)
+#define BP_PXP_WFB_ARRAY_FLAG2_MASK_L_OFS 0
+#define BM_PXP_WFB_ARRAY_FLAG2_MASK_L_OFS 0x0000001F
+#define BF_PXP_WFB_ARRAY_FLAG2_MASK_L_OFS(v) \
+ (((v) << 0) & BM_PXP_WFB_ARRAY_FLAG2_MASK_L_OFS)
+
+#define HW_PXP_WFB_ARRAY_FLAG3_MASK (0x00001220)
+
+#define BP_PXP_WFB_ARRAY_FLAG3_MASK_RSVD0 30
+#define BM_PXP_WFB_ARRAY_FLAG3_MASK_RSVD0 0xC0000000
+#define BF_PXP_WFB_ARRAY_FLAG3_MASK_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFB_ARRAY_FLAG3_MASK_RSVD0)
+#define BP_PXP_WFB_ARRAY_FLAG3_MASK_BUF_SEL 28
+#define BM_PXP_WFB_ARRAY_FLAG3_MASK_BUF_SEL 0x30000000
+#define BF_PXP_WFB_ARRAY_FLAG3_MASK_BUF_SEL(v) \
+ (((v) << 28) & BM_PXP_WFB_ARRAY_FLAG3_MASK_BUF_SEL)
+#define BV_PXP_WFB_ARRAY_FLAG3_MASK_BUF_SEL__0 0x0
+#define BV_PXP_WFB_ARRAY_FLAG3_MASK_BUF_SEL__1 0x1
+#define BV_PXP_WFB_ARRAY_FLAG3_MASK_BUF_SEL__2 0x2
+#define BP_PXP_WFB_ARRAY_FLAG3_MASK_RSVD1 26
+#define BM_PXP_WFB_ARRAY_FLAG3_MASK_RSVD1 0x0C000000
+#define BF_PXP_WFB_ARRAY_FLAG3_MASK_RSVD1(v) \
+ (((v) << 26) & BM_PXP_WFB_ARRAY_FLAG3_MASK_RSVD1)
+#define BM_PXP_WFB_ARRAY_FLAG3_MASK_SIGN_Y 0x02000000
+#define BF_PXP_WFB_ARRAY_FLAG3_MASK_SIGN_Y(v) \
+ (((v) << 25) & BM_PXP_WFB_ARRAY_FLAG3_MASK_SIGN_Y)
+#define BV_PXP_WFB_ARRAY_FLAG3_MASK_SIGN_Y__0 0x0
+#define BV_PXP_WFB_ARRAY_FLAG3_MASK_SIGN_Y__1 0x1
+#define BM_PXP_WFB_ARRAY_FLAG3_MASK_SIGN_X 0x01000000
+#define BF_PXP_WFB_ARRAY_FLAG3_MASK_SIGN_X(v) \
+ (((v) << 24) & BM_PXP_WFB_ARRAY_FLAG3_MASK_SIGN_X)
+#define BV_PXP_WFB_ARRAY_FLAG3_MASK_SIGN_X__0 0x0
+#define BV_PXP_WFB_ARRAY_FLAG3_MASK_SIGN_X__1 0x1
+#define BP_PXP_WFB_ARRAY_FLAG3_MASK_RSVD2 22
+#define BM_PXP_WFB_ARRAY_FLAG3_MASK_RSVD2 0x00C00000
+#define BF_PXP_WFB_ARRAY_FLAG3_MASK_RSVD2(v) \
+ (((v) << 22) & BM_PXP_WFB_ARRAY_FLAG3_MASK_RSVD2)
+#define BP_PXP_WFB_ARRAY_FLAG3_MASK_OFFSET_Y 20
+#define BM_PXP_WFB_ARRAY_FLAG3_MASK_OFFSET_Y 0x00300000
+#define BF_PXP_WFB_ARRAY_FLAG3_MASK_OFFSET_Y(v) \
+ (((v) << 20) & BM_PXP_WFB_ARRAY_FLAG3_MASK_OFFSET_Y)
+#define BP_PXP_WFB_ARRAY_FLAG3_MASK_RSVD3 18
+#define BM_PXP_WFB_ARRAY_FLAG3_MASK_RSVD3 0x000C0000
+#define BF_PXP_WFB_ARRAY_FLAG3_MASK_RSVD3(v) \
+ (((v) << 18) & BM_PXP_WFB_ARRAY_FLAG3_MASK_RSVD3)
+#define BP_PXP_WFB_ARRAY_FLAG3_MASK_OFFSET_X 16
+#define BM_PXP_WFB_ARRAY_FLAG3_MASK_OFFSET_X 0x00030000
+#define BF_PXP_WFB_ARRAY_FLAG3_MASK_OFFSET_X(v) \
+ (((v) << 16) & BM_PXP_WFB_ARRAY_FLAG3_MASK_OFFSET_X)
+#define BP_PXP_WFB_ARRAY_FLAG3_MASK_RSVD4 13
+#define BM_PXP_WFB_ARRAY_FLAG3_MASK_RSVD4 0x0000E000
+#define BF_PXP_WFB_ARRAY_FLAG3_MASK_RSVD4(v) \
+ (((v) << 13) & BM_PXP_WFB_ARRAY_FLAG3_MASK_RSVD4)
+#define BP_PXP_WFB_ARRAY_FLAG3_MASK_H_OFS 8
+#define BM_PXP_WFB_ARRAY_FLAG3_MASK_H_OFS 0x00001F00
+#define BF_PXP_WFB_ARRAY_FLAG3_MASK_H_OFS(v) \
+ (((v) << 8) & BM_PXP_WFB_ARRAY_FLAG3_MASK_H_OFS)
+#define BP_PXP_WFB_ARRAY_FLAG3_MASK_RSVD5 5
+#define BM_PXP_WFB_ARRAY_FLAG3_MASK_RSVD5 0x000000E0
+#define BF_PXP_WFB_ARRAY_FLAG3_MASK_RSVD5(v) \
+ (((v) << 5) & BM_PXP_WFB_ARRAY_FLAG3_MASK_RSVD5)
+#define BP_PXP_WFB_ARRAY_FLAG3_MASK_L_OFS 0
+#define BM_PXP_WFB_ARRAY_FLAG3_MASK_L_OFS 0x0000001F
+#define BF_PXP_WFB_ARRAY_FLAG3_MASK_L_OFS(v) \
+ (((v) << 0) & BM_PXP_WFB_ARRAY_FLAG3_MASK_L_OFS)
+
+#define HW_PXP_WFB_ARRAY_FLAG4_MASK (0x00001230)
+
+#define BP_PXP_WFB_ARRAY_FLAG4_MASK_RSVD0 30
+#define BM_PXP_WFB_ARRAY_FLAG4_MASK_RSVD0 0xC0000000
+#define BF_PXP_WFB_ARRAY_FLAG4_MASK_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFB_ARRAY_FLAG4_MASK_RSVD0)
+#define BP_PXP_WFB_ARRAY_FLAG4_MASK_BUF_SEL 28
+#define BM_PXP_WFB_ARRAY_FLAG4_MASK_BUF_SEL 0x30000000
+#define BF_PXP_WFB_ARRAY_FLAG4_MASK_BUF_SEL(v) \
+ (((v) << 28) & BM_PXP_WFB_ARRAY_FLAG4_MASK_BUF_SEL)
+#define BV_PXP_WFB_ARRAY_FLAG4_MASK_BUF_SEL__0 0x0
+#define BV_PXP_WFB_ARRAY_FLAG4_MASK_BUF_SEL__1 0x1
+#define BV_PXP_WFB_ARRAY_FLAG4_MASK_BUF_SEL__2 0x2
+#define BP_PXP_WFB_ARRAY_FLAG4_MASK_RSVD1 26
+#define BM_PXP_WFB_ARRAY_FLAG4_MASK_RSVD1 0x0C000000
+#define BF_PXP_WFB_ARRAY_FLAG4_MASK_RSVD1(v) \
+ (((v) << 26) & BM_PXP_WFB_ARRAY_FLAG4_MASK_RSVD1)
+#define BM_PXP_WFB_ARRAY_FLAG4_MASK_SIGN_Y 0x02000000
+#define BF_PXP_WFB_ARRAY_FLAG4_MASK_SIGN_Y(v) \
+ (((v) << 25) & BM_PXP_WFB_ARRAY_FLAG4_MASK_SIGN_Y)
+#define BV_PXP_WFB_ARRAY_FLAG4_MASK_SIGN_Y__0 0x0
+#define BV_PXP_WFB_ARRAY_FLAG4_MASK_SIGN_Y__1 0x1
+#define BM_PXP_WFB_ARRAY_FLAG4_MASK_SIGN_X 0x01000000
+#define BF_PXP_WFB_ARRAY_FLAG4_MASK_SIGN_X(v) \
+ (((v) << 24) & BM_PXP_WFB_ARRAY_FLAG4_MASK_SIGN_X)
+#define BV_PXP_WFB_ARRAY_FLAG4_MASK_SIGN_X__0 0x0
+#define BV_PXP_WFB_ARRAY_FLAG4_MASK_SIGN_X__1 0x1
+#define BP_PXP_WFB_ARRAY_FLAG4_MASK_RSVD2 22
+#define BM_PXP_WFB_ARRAY_FLAG4_MASK_RSVD2 0x00C00000
+#define BF_PXP_WFB_ARRAY_FLAG4_MASK_RSVD2(v) \
+ (((v) << 22) & BM_PXP_WFB_ARRAY_FLAG4_MASK_RSVD2)
+#define BP_PXP_WFB_ARRAY_FLAG4_MASK_OFFSET_Y 20
+#define BM_PXP_WFB_ARRAY_FLAG4_MASK_OFFSET_Y 0x00300000
+#define BF_PXP_WFB_ARRAY_FLAG4_MASK_OFFSET_Y(v) \
+ (((v) << 20) & BM_PXP_WFB_ARRAY_FLAG4_MASK_OFFSET_Y)
+#define BP_PXP_WFB_ARRAY_FLAG4_MASK_RSVD3 18
+#define BM_PXP_WFB_ARRAY_FLAG4_MASK_RSVD3 0x000C0000
+#define BF_PXP_WFB_ARRAY_FLAG4_MASK_RSVD3(v) \
+ (((v) << 18) & BM_PXP_WFB_ARRAY_FLAG4_MASK_RSVD3)
+#define BP_PXP_WFB_ARRAY_FLAG4_MASK_OFFSET_X 16
+#define BM_PXP_WFB_ARRAY_FLAG4_MASK_OFFSET_X 0x00030000
+#define BF_PXP_WFB_ARRAY_FLAG4_MASK_OFFSET_X(v) \
+ (((v) << 16) & BM_PXP_WFB_ARRAY_FLAG4_MASK_OFFSET_X)
+#define BP_PXP_WFB_ARRAY_FLAG4_MASK_RSVD4 13
+#define BM_PXP_WFB_ARRAY_FLAG4_MASK_RSVD4 0x0000E000
+#define BF_PXP_WFB_ARRAY_FLAG4_MASK_RSVD4(v) \
+ (((v) << 13) & BM_PXP_WFB_ARRAY_FLAG4_MASK_RSVD4)
+#define BP_PXP_WFB_ARRAY_FLAG4_MASK_H_OFS 8
+#define BM_PXP_WFB_ARRAY_FLAG4_MASK_H_OFS 0x00001F00
+#define BF_PXP_WFB_ARRAY_FLAG4_MASK_H_OFS(v) \
+ (((v) << 8) & BM_PXP_WFB_ARRAY_FLAG4_MASK_H_OFS)
+#define BP_PXP_WFB_ARRAY_FLAG4_MASK_RSVD5 5
+#define BM_PXP_WFB_ARRAY_FLAG4_MASK_RSVD5 0x000000E0
+#define BF_PXP_WFB_ARRAY_FLAG4_MASK_RSVD5(v) \
+ (((v) << 5) & BM_PXP_WFB_ARRAY_FLAG4_MASK_RSVD5)
+#define BP_PXP_WFB_ARRAY_FLAG4_MASK_L_OFS 0
+#define BM_PXP_WFB_ARRAY_FLAG4_MASK_L_OFS 0x0000001F
+#define BF_PXP_WFB_ARRAY_FLAG4_MASK_L_OFS(v) \
+ (((v) << 0) & BM_PXP_WFB_ARRAY_FLAG4_MASK_L_OFS)
+
+#define HW_PXP_WFB_ARRAY_FLAG5_MASK (0x00001240)
+
+#define BP_PXP_WFB_ARRAY_FLAG5_MASK_RSVD0 30
+#define BM_PXP_WFB_ARRAY_FLAG5_MASK_RSVD0 0xC0000000
+#define BF_PXP_WFB_ARRAY_FLAG5_MASK_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFB_ARRAY_FLAG5_MASK_RSVD0)
+#define BP_PXP_WFB_ARRAY_FLAG5_MASK_BUF_SEL 28
+#define BM_PXP_WFB_ARRAY_FLAG5_MASK_BUF_SEL 0x30000000
+#define BF_PXP_WFB_ARRAY_FLAG5_MASK_BUF_SEL(v) \
+ (((v) << 28) & BM_PXP_WFB_ARRAY_FLAG5_MASK_BUF_SEL)
+#define BV_PXP_WFB_ARRAY_FLAG5_MASK_BUF_SEL__0 0x0
+#define BV_PXP_WFB_ARRAY_FLAG5_MASK_BUF_SEL__1 0x1
+#define BV_PXP_WFB_ARRAY_FLAG5_MASK_BUF_SEL__2 0x2
+#define BP_PXP_WFB_ARRAY_FLAG5_MASK_RSVD1 26
+#define BM_PXP_WFB_ARRAY_FLAG5_MASK_RSVD1 0x0C000000
+#define BF_PXP_WFB_ARRAY_FLAG5_MASK_RSVD1(v) \
+ (((v) << 26) & BM_PXP_WFB_ARRAY_FLAG5_MASK_RSVD1)
+#define BM_PXP_WFB_ARRAY_FLAG5_MASK_SIGN_Y 0x02000000
+#define BF_PXP_WFB_ARRAY_FLAG5_MASK_SIGN_Y(v) \
+ (((v) << 25) & BM_PXP_WFB_ARRAY_FLAG5_MASK_SIGN_Y)
+#define BV_PXP_WFB_ARRAY_FLAG5_MASK_SIGN_Y__0 0x0
+#define BV_PXP_WFB_ARRAY_FLAG5_MASK_SIGN_Y__1 0x1
+#define BM_PXP_WFB_ARRAY_FLAG5_MASK_SIGN_X 0x01000000
+#define BF_PXP_WFB_ARRAY_FLAG5_MASK_SIGN_X(v) \
+ (((v) << 24) & BM_PXP_WFB_ARRAY_FLAG5_MASK_SIGN_X)
+#define BV_PXP_WFB_ARRAY_FLAG5_MASK_SIGN_X__0 0x0
+#define BV_PXP_WFB_ARRAY_FLAG5_MASK_SIGN_X__1 0x1
+#define BP_PXP_WFB_ARRAY_FLAG5_MASK_RSVD2 22
+#define BM_PXP_WFB_ARRAY_FLAG5_MASK_RSVD2 0x00C00000
+#define BF_PXP_WFB_ARRAY_FLAG5_MASK_RSVD2(v) \
+ (((v) << 22) & BM_PXP_WFB_ARRAY_FLAG5_MASK_RSVD2)
+#define BP_PXP_WFB_ARRAY_FLAG5_MASK_OFFSET_Y 20
+#define BM_PXP_WFB_ARRAY_FLAG5_MASK_OFFSET_Y 0x00300000
+#define BF_PXP_WFB_ARRAY_FLAG5_MASK_OFFSET_Y(v) \
+ (((v) << 20) & BM_PXP_WFB_ARRAY_FLAG5_MASK_OFFSET_Y)
+#define BP_PXP_WFB_ARRAY_FLAG5_MASK_RSVD3 18
+#define BM_PXP_WFB_ARRAY_FLAG5_MASK_RSVD3 0x000C0000
+#define BF_PXP_WFB_ARRAY_FLAG5_MASK_RSVD3(v) \
+ (((v) << 18) & BM_PXP_WFB_ARRAY_FLAG5_MASK_RSVD3)
+#define BP_PXP_WFB_ARRAY_FLAG5_MASK_OFFSET_X 16
+#define BM_PXP_WFB_ARRAY_FLAG5_MASK_OFFSET_X 0x00030000
+#define BF_PXP_WFB_ARRAY_FLAG5_MASK_OFFSET_X(v) \
+ (((v) << 16) & BM_PXP_WFB_ARRAY_FLAG5_MASK_OFFSET_X)
+#define BP_PXP_WFB_ARRAY_FLAG5_MASK_RSVD4 13
+#define BM_PXP_WFB_ARRAY_FLAG5_MASK_RSVD4 0x0000E000
+#define BF_PXP_WFB_ARRAY_FLAG5_MASK_RSVD4(v) \
+ (((v) << 13) & BM_PXP_WFB_ARRAY_FLAG5_MASK_RSVD4)
+#define BP_PXP_WFB_ARRAY_FLAG5_MASK_H_OFS 8
+#define BM_PXP_WFB_ARRAY_FLAG5_MASK_H_OFS 0x00001F00
+#define BF_PXP_WFB_ARRAY_FLAG5_MASK_H_OFS(v) \
+ (((v) << 8) & BM_PXP_WFB_ARRAY_FLAG5_MASK_H_OFS)
+#define BP_PXP_WFB_ARRAY_FLAG5_MASK_RSVD5 5
+#define BM_PXP_WFB_ARRAY_FLAG5_MASK_RSVD5 0x000000E0
+#define BF_PXP_WFB_ARRAY_FLAG5_MASK_RSVD5(v) \
+ (((v) << 5) & BM_PXP_WFB_ARRAY_FLAG5_MASK_RSVD5)
+#define BP_PXP_WFB_ARRAY_FLAG5_MASK_L_OFS 0
+#define BM_PXP_WFB_ARRAY_FLAG5_MASK_L_OFS 0x0000001F
+#define BF_PXP_WFB_ARRAY_FLAG5_MASK_L_OFS(v) \
+ (((v) << 0) & BM_PXP_WFB_ARRAY_FLAG5_MASK_L_OFS)
+
+#define HW_PXP_WFB_ARRAY_FLAG6_MASK (0x00001250)
+
+#define BP_PXP_WFB_ARRAY_FLAG6_MASK_RSVD0 30
+#define BM_PXP_WFB_ARRAY_FLAG6_MASK_RSVD0 0xC0000000
+#define BF_PXP_WFB_ARRAY_FLAG6_MASK_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFB_ARRAY_FLAG6_MASK_RSVD0)
+#define BP_PXP_WFB_ARRAY_FLAG6_MASK_BUF_SEL 28
+#define BM_PXP_WFB_ARRAY_FLAG6_MASK_BUF_SEL 0x30000000
+#define BF_PXP_WFB_ARRAY_FLAG6_MASK_BUF_SEL(v) \
+ (((v) << 28) & BM_PXP_WFB_ARRAY_FLAG6_MASK_BUF_SEL)
+#define BV_PXP_WFB_ARRAY_FLAG6_MASK_BUF_SEL__0 0x0
+#define BV_PXP_WFB_ARRAY_FLAG6_MASK_BUF_SEL__1 0x1
+#define BV_PXP_WFB_ARRAY_FLAG6_MASK_BUF_SEL__2 0x2
+#define BP_PXP_WFB_ARRAY_FLAG6_MASK_RSVD1 26
+#define BM_PXP_WFB_ARRAY_FLAG6_MASK_RSVD1 0x0C000000
+#define BF_PXP_WFB_ARRAY_FLAG6_MASK_RSVD1(v) \
+ (((v) << 26) & BM_PXP_WFB_ARRAY_FLAG6_MASK_RSVD1)
+#define BM_PXP_WFB_ARRAY_FLAG6_MASK_SIGN_Y 0x02000000
+#define BF_PXP_WFB_ARRAY_FLAG6_MASK_SIGN_Y(v) \
+ (((v) << 25) & BM_PXP_WFB_ARRAY_FLAG6_MASK_SIGN_Y)
+#define BV_PXP_WFB_ARRAY_FLAG6_MASK_SIGN_Y__0 0x0
+#define BV_PXP_WFB_ARRAY_FLAG6_MASK_SIGN_Y__1 0x1
+#define BM_PXP_WFB_ARRAY_FLAG6_MASK_SIGN_X 0x01000000
+#define BF_PXP_WFB_ARRAY_FLAG6_MASK_SIGN_X(v) \
+ (((v) << 24) & BM_PXP_WFB_ARRAY_FLAG6_MASK_SIGN_X)
+#define BV_PXP_WFB_ARRAY_FLAG6_MASK_SIGN_X__0 0x0
+#define BV_PXP_WFB_ARRAY_FLAG6_MASK_SIGN_X__1 0x1
+#define BP_PXP_WFB_ARRAY_FLAG6_MASK_RSVD2 22
+#define BM_PXP_WFB_ARRAY_FLAG6_MASK_RSVD2 0x00C00000
+#define BF_PXP_WFB_ARRAY_FLAG6_MASK_RSVD2(v) \
+ (((v) << 22) & BM_PXP_WFB_ARRAY_FLAG6_MASK_RSVD2)
+#define BP_PXP_WFB_ARRAY_FLAG6_MASK_OFFSET_Y 20
+#define BM_PXP_WFB_ARRAY_FLAG6_MASK_OFFSET_Y 0x00300000
+#define BF_PXP_WFB_ARRAY_FLAG6_MASK_OFFSET_Y(v) \
+ (((v) << 20) & BM_PXP_WFB_ARRAY_FLAG6_MASK_OFFSET_Y)
+#define BP_PXP_WFB_ARRAY_FLAG6_MASK_RSVD3 18
+#define BM_PXP_WFB_ARRAY_FLAG6_MASK_RSVD3 0x000C0000
+#define BF_PXP_WFB_ARRAY_FLAG6_MASK_RSVD3(v) \
+ (((v) << 18) & BM_PXP_WFB_ARRAY_FLAG6_MASK_RSVD3)
+#define BP_PXP_WFB_ARRAY_FLAG6_MASK_OFFSET_X 16
+#define BM_PXP_WFB_ARRAY_FLAG6_MASK_OFFSET_X 0x00030000
+#define BF_PXP_WFB_ARRAY_FLAG6_MASK_OFFSET_X(v) \
+ (((v) << 16) & BM_PXP_WFB_ARRAY_FLAG6_MASK_OFFSET_X)
+#define BP_PXP_WFB_ARRAY_FLAG6_MASK_RSVD4 13
+#define BM_PXP_WFB_ARRAY_FLAG6_MASK_RSVD4 0x0000E000
+#define BF_PXP_WFB_ARRAY_FLAG6_MASK_RSVD4(v) \
+ (((v) << 13) & BM_PXP_WFB_ARRAY_FLAG6_MASK_RSVD4)
+#define BP_PXP_WFB_ARRAY_FLAG6_MASK_H_OFS 8
+#define BM_PXP_WFB_ARRAY_FLAG6_MASK_H_OFS 0x00001F00
+#define BF_PXP_WFB_ARRAY_FLAG6_MASK_H_OFS(v) \
+ (((v) << 8) & BM_PXP_WFB_ARRAY_FLAG6_MASK_H_OFS)
+#define BP_PXP_WFB_ARRAY_FLAG6_MASK_RSVD5 5
+#define BM_PXP_WFB_ARRAY_FLAG6_MASK_RSVD5 0x000000E0
+#define BF_PXP_WFB_ARRAY_FLAG6_MASK_RSVD5(v) \
+ (((v) << 5) & BM_PXP_WFB_ARRAY_FLAG6_MASK_RSVD5)
+#define BP_PXP_WFB_ARRAY_FLAG6_MASK_L_OFS 0
+#define BM_PXP_WFB_ARRAY_FLAG6_MASK_L_OFS 0x0000001F
+#define BF_PXP_WFB_ARRAY_FLAG6_MASK_L_OFS(v) \
+ (((v) << 0) & BM_PXP_WFB_ARRAY_FLAG6_MASK_L_OFS)
+
+#define HW_PXP_WFB_ARRAY_FLAG7_MASK (0x00001260)
+
+#define BP_PXP_WFB_ARRAY_FLAG7_MASK_RSVD0 30
+#define BM_PXP_WFB_ARRAY_FLAG7_MASK_RSVD0 0xC0000000
+#define BF_PXP_WFB_ARRAY_FLAG7_MASK_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFB_ARRAY_FLAG7_MASK_RSVD0)
+#define BP_PXP_WFB_ARRAY_FLAG7_MASK_BUF_SEL 28
+#define BM_PXP_WFB_ARRAY_FLAG7_MASK_BUF_SEL 0x30000000
+#define BF_PXP_WFB_ARRAY_FLAG7_MASK_BUF_SEL(v) \
+ (((v) << 28) & BM_PXP_WFB_ARRAY_FLAG7_MASK_BUF_SEL)
+#define BV_PXP_WFB_ARRAY_FLAG7_MASK_BUF_SEL__0 0x0
+#define BV_PXP_WFB_ARRAY_FLAG7_MASK_BUF_SEL__1 0x1
+#define BV_PXP_WFB_ARRAY_FLAG7_MASK_BUF_SEL__2 0x2
+#define BP_PXP_WFB_ARRAY_FLAG7_MASK_RSVD1 26
+#define BM_PXP_WFB_ARRAY_FLAG7_MASK_RSVD1 0x0C000000
+#define BF_PXP_WFB_ARRAY_FLAG7_MASK_RSVD1(v) \
+ (((v) << 26) & BM_PXP_WFB_ARRAY_FLAG7_MASK_RSVD1)
+#define BM_PXP_WFB_ARRAY_FLAG7_MASK_SIGN_Y 0x02000000
+#define BF_PXP_WFB_ARRAY_FLAG7_MASK_SIGN_Y(v) \
+ (((v) << 25) & BM_PXP_WFB_ARRAY_FLAG7_MASK_SIGN_Y)
+#define BV_PXP_WFB_ARRAY_FLAG7_MASK_SIGN_Y__0 0x0
+#define BV_PXP_WFB_ARRAY_FLAG7_MASK_SIGN_Y__1 0x1
+#define BM_PXP_WFB_ARRAY_FLAG7_MASK_SIGN_X 0x01000000
+#define BF_PXP_WFB_ARRAY_FLAG7_MASK_SIGN_X(v) \
+ (((v) << 24) & BM_PXP_WFB_ARRAY_FLAG7_MASK_SIGN_X)
+#define BV_PXP_WFB_ARRAY_FLAG7_MASK_SIGN_X__0 0x0
+#define BV_PXP_WFB_ARRAY_FLAG7_MASK_SIGN_X__1 0x1
+#define BP_PXP_WFB_ARRAY_FLAG7_MASK_RSVD2 22
+#define BM_PXP_WFB_ARRAY_FLAG7_MASK_RSVD2 0x00C00000
+#define BF_PXP_WFB_ARRAY_FLAG7_MASK_RSVD2(v) \
+ (((v) << 22) & BM_PXP_WFB_ARRAY_FLAG7_MASK_RSVD2)
+#define BP_PXP_WFB_ARRAY_FLAG7_MASK_OFFSET_Y 20
+#define BM_PXP_WFB_ARRAY_FLAG7_MASK_OFFSET_Y 0x00300000
+#define BF_PXP_WFB_ARRAY_FLAG7_MASK_OFFSET_Y(v) \
+ (((v) << 20) & BM_PXP_WFB_ARRAY_FLAG7_MASK_OFFSET_Y)
+#define BP_PXP_WFB_ARRAY_FLAG7_MASK_RSVD3 18
+#define BM_PXP_WFB_ARRAY_FLAG7_MASK_RSVD3 0x000C0000
+#define BF_PXP_WFB_ARRAY_FLAG7_MASK_RSVD3(v) \
+ (((v) << 18) & BM_PXP_WFB_ARRAY_FLAG7_MASK_RSVD3)
+#define BP_PXP_WFB_ARRAY_FLAG7_MASK_OFFSET_X 16
+#define BM_PXP_WFB_ARRAY_FLAG7_MASK_OFFSET_X 0x00030000
+#define BF_PXP_WFB_ARRAY_FLAG7_MASK_OFFSET_X(v) \
+ (((v) << 16) & BM_PXP_WFB_ARRAY_FLAG7_MASK_OFFSET_X)
+#define BP_PXP_WFB_ARRAY_FLAG7_MASK_RSVD4 13
+#define BM_PXP_WFB_ARRAY_FLAG7_MASK_RSVD4 0x0000E000
+#define BF_PXP_WFB_ARRAY_FLAG7_MASK_RSVD4(v) \
+ (((v) << 13) & BM_PXP_WFB_ARRAY_FLAG7_MASK_RSVD4)
+#define BP_PXP_WFB_ARRAY_FLAG7_MASK_H_OFS 8
+#define BM_PXP_WFB_ARRAY_FLAG7_MASK_H_OFS 0x00001F00
+#define BF_PXP_WFB_ARRAY_FLAG7_MASK_H_OFS(v) \
+ (((v) << 8) & BM_PXP_WFB_ARRAY_FLAG7_MASK_H_OFS)
+#define BP_PXP_WFB_ARRAY_FLAG7_MASK_RSVD5 5
+#define BM_PXP_WFB_ARRAY_FLAG7_MASK_RSVD5 0x000000E0
+#define BF_PXP_WFB_ARRAY_FLAG7_MASK_RSVD5(v) \
+ (((v) << 5) & BM_PXP_WFB_ARRAY_FLAG7_MASK_RSVD5)
+#define BP_PXP_WFB_ARRAY_FLAG7_MASK_L_OFS 0
+#define BM_PXP_WFB_ARRAY_FLAG7_MASK_L_OFS 0x0000001F
+#define BF_PXP_WFB_ARRAY_FLAG7_MASK_L_OFS(v) \
+ (((v) << 0) & BM_PXP_WFB_ARRAY_FLAG7_MASK_L_OFS)
+
+#define HW_PXP_WFB_FETCH_BUF1_CORD (0x00001270)
+
+#define BP_PXP_WFB_FETCH_BUF1_CORD_RSVD0 30
+#define BM_PXP_WFB_FETCH_BUF1_CORD_RSVD0 0xC0000000
+#define BF_PXP_WFB_FETCH_BUF1_CORD_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFB_FETCH_BUF1_CORD_RSVD0)
+#define BP_PXP_WFB_FETCH_BUF1_CORD_YCORD 16
+#define BM_PXP_WFB_FETCH_BUF1_CORD_YCORD 0x3FFF0000
+#define BF_PXP_WFB_FETCH_BUF1_CORD_YCORD(v) \
+ (((v) << 16) & BM_PXP_WFB_FETCH_BUF1_CORD_YCORD)
+#define BP_PXP_WFB_FETCH_BUF1_CORD_RSVD1 14
+#define BM_PXP_WFB_FETCH_BUF1_CORD_RSVD1 0x0000C000
+#define BF_PXP_WFB_FETCH_BUF1_CORD_RSVD1(v) \
+ (((v) << 14) & BM_PXP_WFB_FETCH_BUF1_CORD_RSVD1)
+#define BP_PXP_WFB_FETCH_BUF1_CORD_XCORD 0
+#define BM_PXP_WFB_FETCH_BUF1_CORD_XCORD 0x00003FFF
+#define BF_PXP_WFB_FETCH_BUF1_CORD_XCORD(v) \
+ (((v) << 0) & BM_PXP_WFB_FETCH_BUF1_CORD_XCORD)
+
+#define HW_PXP_WFB_FETCH_BUF2_CORD (0x00001280)
+
+#define BP_PXP_WFB_FETCH_BUF2_CORD_RSVD0 30
+#define BM_PXP_WFB_FETCH_BUF2_CORD_RSVD0 0xC0000000
+#define BF_PXP_WFB_FETCH_BUF2_CORD_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFB_FETCH_BUF2_CORD_RSVD0)
+#define BP_PXP_WFB_FETCH_BUF2_CORD_YCORD 16
+#define BM_PXP_WFB_FETCH_BUF2_CORD_YCORD 0x3FFF0000
+#define BF_PXP_WFB_FETCH_BUF2_CORD_YCORD(v) \
+ (((v) << 16) & BM_PXP_WFB_FETCH_BUF2_CORD_YCORD)
+#define BP_PXP_WFB_FETCH_BUF2_CORD_RSVD1 14
+#define BM_PXP_WFB_FETCH_BUF2_CORD_RSVD1 0x0000C000
+#define BF_PXP_WFB_FETCH_BUF2_CORD_RSVD1(v) \
+ (((v) << 14) & BM_PXP_WFB_FETCH_BUF2_CORD_RSVD1)
+#define BP_PXP_WFB_FETCH_BUF2_CORD_XCORD 0
+#define BM_PXP_WFB_FETCH_BUF2_CORD_XCORD 0x00003FFF
+#define BF_PXP_WFB_FETCH_BUF2_CORD_XCORD(v) \
+ (((v) << 0) & BM_PXP_WFB_FETCH_BUF2_CORD_XCORD)
+
+#define HW_PXP_WFB_ARRAY_FLAG8_MASK (0x00001290)
+
+#define BP_PXP_WFB_ARRAY_FLAG8_MASK_RSVD0 30
+#define BM_PXP_WFB_ARRAY_FLAG8_MASK_RSVD0 0xC0000000
+#define BF_PXP_WFB_ARRAY_FLAG8_MASK_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFB_ARRAY_FLAG8_MASK_RSVD0)
+#define BP_PXP_WFB_ARRAY_FLAG8_MASK_BUF_SEL 28
+#define BM_PXP_WFB_ARRAY_FLAG8_MASK_BUF_SEL 0x30000000
+#define BF_PXP_WFB_ARRAY_FLAG8_MASK_BUF_SEL(v) \
+ (((v) << 28) & BM_PXP_WFB_ARRAY_FLAG8_MASK_BUF_SEL)
+#define BV_PXP_WFB_ARRAY_FLAG8_MASK_BUF_SEL__0 0x0
+#define BV_PXP_WFB_ARRAY_FLAG8_MASK_BUF_SEL__1 0x1
+#define BV_PXP_WFB_ARRAY_FLAG8_MASK_BUF_SEL__2 0x2
+#define BP_PXP_WFB_ARRAY_FLAG8_MASK_RSVD1 26
+#define BM_PXP_WFB_ARRAY_FLAG8_MASK_RSVD1 0x0C000000
+#define BF_PXP_WFB_ARRAY_FLAG8_MASK_RSVD1(v) \
+ (((v) << 26) & BM_PXP_WFB_ARRAY_FLAG8_MASK_RSVD1)
+#define BM_PXP_WFB_ARRAY_FLAG8_MASK_SIGN_Y 0x02000000
+#define BF_PXP_WFB_ARRAY_FLAG8_MASK_SIGN_Y(v) \
+ (((v) << 25) & BM_PXP_WFB_ARRAY_FLAG8_MASK_SIGN_Y)
+#define BV_PXP_WFB_ARRAY_FLAG8_MASK_SIGN_Y__0 0x0
+#define BV_PXP_WFB_ARRAY_FLAG8_MASK_SIGN_Y__1 0x1
+#define BM_PXP_WFB_ARRAY_FLAG8_MASK_SIGN_X 0x01000000
+#define BF_PXP_WFB_ARRAY_FLAG8_MASK_SIGN_X(v) \
+ (((v) << 24) & BM_PXP_WFB_ARRAY_FLAG8_MASK_SIGN_X)
+#define BV_PXP_WFB_ARRAY_FLAG8_MASK_SIGN_X__0 0x0
+#define BV_PXP_WFB_ARRAY_FLAG8_MASK_SIGN_X__1 0x1
+#define BP_PXP_WFB_ARRAY_FLAG8_MASK_RSVD2 22
+#define BM_PXP_WFB_ARRAY_FLAG8_MASK_RSVD2 0x00C00000
+#define BF_PXP_WFB_ARRAY_FLAG8_MASK_RSVD2(v) \
+ (((v) << 22) & BM_PXP_WFB_ARRAY_FLAG8_MASK_RSVD2)
+#define BP_PXP_WFB_ARRAY_FLAG8_MASK_OFFSET_Y 20
+#define BM_PXP_WFB_ARRAY_FLAG8_MASK_OFFSET_Y 0x00300000
+#define BF_PXP_WFB_ARRAY_FLAG8_MASK_OFFSET_Y(v) \
+ (((v) << 20) & BM_PXP_WFB_ARRAY_FLAG8_MASK_OFFSET_Y)
+#define BP_PXP_WFB_ARRAY_FLAG8_MASK_RSVD3 18
+#define BM_PXP_WFB_ARRAY_FLAG8_MASK_RSVD3 0x000C0000
+#define BF_PXP_WFB_ARRAY_FLAG8_MASK_RSVD3(v) \
+ (((v) << 18) & BM_PXP_WFB_ARRAY_FLAG8_MASK_RSVD3)
+#define BP_PXP_WFB_ARRAY_FLAG8_MASK_OFFSET_X 16
+#define BM_PXP_WFB_ARRAY_FLAG8_MASK_OFFSET_X 0x00030000
+#define BF_PXP_WFB_ARRAY_FLAG8_MASK_OFFSET_X(v) \
+ (((v) << 16) & BM_PXP_WFB_ARRAY_FLAG8_MASK_OFFSET_X)
+#define BP_PXP_WFB_ARRAY_FLAG8_MASK_RSVD4 13
+#define BM_PXP_WFB_ARRAY_FLAG8_MASK_RSVD4 0x0000E000
+#define BF_PXP_WFB_ARRAY_FLAG8_MASK_RSVD4(v) \
+ (((v) << 13) & BM_PXP_WFB_ARRAY_FLAG8_MASK_RSVD4)
+#define BP_PXP_WFB_ARRAY_FLAG8_MASK_H_OFS 8
+#define BM_PXP_WFB_ARRAY_FLAG8_MASK_H_OFS 0x00001F00
+#define BF_PXP_WFB_ARRAY_FLAG8_MASK_H_OFS(v) \
+ (((v) << 8) & BM_PXP_WFB_ARRAY_FLAG8_MASK_H_OFS)
+#define BP_PXP_WFB_ARRAY_FLAG8_MASK_RSVD5 5
+#define BM_PXP_WFB_ARRAY_FLAG8_MASK_RSVD5 0x000000E0
+#define BF_PXP_WFB_ARRAY_FLAG8_MASK_RSVD5(v) \
+ (((v) << 5) & BM_PXP_WFB_ARRAY_FLAG8_MASK_RSVD5)
+#define BP_PXP_WFB_ARRAY_FLAG8_MASK_L_OFS 0
+#define BM_PXP_WFB_ARRAY_FLAG8_MASK_L_OFS 0x0000001F
+#define BF_PXP_WFB_ARRAY_FLAG8_MASK_L_OFS(v) \
+ (((v) << 0) & BM_PXP_WFB_ARRAY_FLAG8_MASK_L_OFS)
+
+#define HW_PXP_WFB_ARRAY_FLAG9_MASK (0x000012a0)
+
+#define BP_PXP_WFB_ARRAY_FLAG9_MASK_RSVD0 30
+#define BM_PXP_WFB_ARRAY_FLAG9_MASK_RSVD0 0xC0000000
+#define BF_PXP_WFB_ARRAY_FLAG9_MASK_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFB_ARRAY_FLAG9_MASK_RSVD0)
+#define BP_PXP_WFB_ARRAY_FLAG9_MASK_BUF_SEL 28
+#define BM_PXP_WFB_ARRAY_FLAG9_MASK_BUF_SEL 0x30000000
+#define BF_PXP_WFB_ARRAY_FLAG9_MASK_BUF_SEL(v) \
+ (((v) << 28) & BM_PXP_WFB_ARRAY_FLAG9_MASK_BUF_SEL)
+#define BV_PXP_WFB_ARRAY_FLAG9_MASK_BUF_SEL__0 0x0
+#define BV_PXP_WFB_ARRAY_FLAG9_MASK_BUF_SEL__1 0x1
+#define BV_PXP_WFB_ARRAY_FLAG9_MASK_BUF_SEL__2 0x2
+#define BP_PXP_WFB_ARRAY_FLAG9_MASK_RSVD1 26
+#define BM_PXP_WFB_ARRAY_FLAG9_MASK_RSVD1 0x0C000000
+#define BF_PXP_WFB_ARRAY_FLAG9_MASK_RSVD1(v) \
+ (((v) << 26) & BM_PXP_WFB_ARRAY_FLAG9_MASK_RSVD1)
+#define BM_PXP_WFB_ARRAY_FLAG9_MASK_SIGN_Y 0x02000000
+#define BF_PXP_WFB_ARRAY_FLAG9_MASK_SIGN_Y(v) \
+ (((v) << 25) & BM_PXP_WFB_ARRAY_FLAG9_MASK_SIGN_Y)
+#define BV_PXP_WFB_ARRAY_FLAG9_MASK_SIGN_Y__0 0x0
+#define BV_PXP_WFB_ARRAY_FLAG9_MASK_SIGN_Y__1 0x1
+#define BM_PXP_WFB_ARRAY_FLAG9_MASK_SIGN_X 0x01000000
+#define BF_PXP_WFB_ARRAY_FLAG9_MASK_SIGN_X(v) \
+ (((v) << 24) & BM_PXP_WFB_ARRAY_FLAG9_MASK_SIGN_X)
+#define BV_PXP_WFB_ARRAY_FLAG9_MASK_SIGN_X__0 0x0
+#define BV_PXP_WFB_ARRAY_FLAG9_MASK_SIGN_X__1 0x1
+#define BP_PXP_WFB_ARRAY_FLAG9_MASK_RSVD2 22
+#define BM_PXP_WFB_ARRAY_FLAG9_MASK_RSVD2 0x00C00000
+#define BF_PXP_WFB_ARRAY_FLAG9_MASK_RSVD2(v) \
+ (((v) << 22) & BM_PXP_WFB_ARRAY_FLAG9_MASK_RSVD2)
+#define BP_PXP_WFB_ARRAY_FLAG9_MASK_OFFSET_Y 20
+#define BM_PXP_WFB_ARRAY_FLAG9_MASK_OFFSET_Y 0x00300000
+#define BF_PXP_WFB_ARRAY_FLAG9_MASK_OFFSET_Y(v) \
+ (((v) << 20) & BM_PXP_WFB_ARRAY_FLAG9_MASK_OFFSET_Y)
+#define BP_PXP_WFB_ARRAY_FLAG9_MASK_RSVD3 18
+#define BM_PXP_WFB_ARRAY_FLAG9_MASK_RSVD3 0x000C0000
+#define BF_PXP_WFB_ARRAY_FLAG9_MASK_RSVD3(v) \
+ (((v) << 18) & BM_PXP_WFB_ARRAY_FLAG9_MASK_RSVD3)
+#define BP_PXP_WFB_ARRAY_FLAG9_MASK_OFFSET_X 16
+#define BM_PXP_WFB_ARRAY_FLAG9_MASK_OFFSET_X 0x00030000
+#define BF_PXP_WFB_ARRAY_FLAG9_MASK_OFFSET_X(v) \
+ (((v) << 16) & BM_PXP_WFB_ARRAY_FLAG9_MASK_OFFSET_X)
+#define BP_PXP_WFB_ARRAY_FLAG9_MASK_RSVD4 13
+#define BM_PXP_WFB_ARRAY_FLAG9_MASK_RSVD4 0x0000E000
+#define BF_PXP_WFB_ARRAY_FLAG9_MASK_RSVD4(v) \
+ (((v) << 13) & BM_PXP_WFB_ARRAY_FLAG9_MASK_RSVD4)
+#define BP_PXP_WFB_ARRAY_FLAG9_MASK_H_OFS 8
+#define BM_PXP_WFB_ARRAY_FLAG9_MASK_H_OFS 0x00001F00
+#define BF_PXP_WFB_ARRAY_FLAG9_MASK_H_OFS(v) \
+ (((v) << 8) & BM_PXP_WFB_ARRAY_FLAG9_MASK_H_OFS)
+#define BP_PXP_WFB_ARRAY_FLAG9_MASK_RSVD5 5
+#define BM_PXP_WFB_ARRAY_FLAG9_MASK_RSVD5 0x000000E0
+#define BF_PXP_WFB_ARRAY_FLAG9_MASK_RSVD5(v) \
+ (((v) << 5) & BM_PXP_WFB_ARRAY_FLAG9_MASK_RSVD5)
+#define BP_PXP_WFB_ARRAY_FLAG9_MASK_L_OFS 0
+#define BM_PXP_WFB_ARRAY_FLAG9_MASK_L_OFS 0x0000001F
+#define BF_PXP_WFB_ARRAY_FLAG9_MASK_L_OFS(v) \
+ (((v) << 0) & BM_PXP_WFB_ARRAY_FLAG9_MASK_L_OFS)
+
+#define HW_PXP_WFB_ARRAY_FLAG10_MASK (0x000012b0)
+
+#define BP_PXP_WFB_ARRAY_FLAG10_MASK_RSVD0 30
+#define BM_PXP_WFB_ARRAY_FLAG10_MASK_RSVD0 0xC0000000
+#define BF_PXP_WFB_ARRAY_FLAG10_MASK_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFB_ARRAY_FLAG10_MASK_RSVD0)
+#define BP_PXP_WFB_ARRAY_FLAG10_MASK_BUF_SEL 28
+#define BM_PXP_WFB_ARRAY_FLAG10_MASK_BUF_SEL 0x30000000
+#define BF_PXP_WFB_ARRAY_FLAG10_MASK_BUF_SEL(v) \
+ (((v) << 28) & BM_PXP_WFB_ARRAY_FLAG10_MASK_BUF_SEL)
+#define BV_PXP_WFB_ARRAY_FLAG10_MASK_BUF_SEL__0 0x0
+#define BV_PXP_WFB_ARRAY_FLAG10_MASK_BUF_SEL__1 0x1
+#define BV_PXP_WFB_ARRAY_FLAG10_MASK_BUF_SEL__2 0x2
+#define BP_PXP_WFB_ARRAY_FLAG10_MASK_RSVD1 26
+#define BM_PXP_WFB_ARRAY_FLAG10_MASK_RSVD1 0x0C000000
+#define BF_PXP_WFB_ARRAY_FLAG10_MASK_RSVD1(v) \
+ (((v) << 26) & BM_PXP_WFB_ARRAY_FLAG10_MASK_RSVD1)
+#define BM_PXP_WFB_ARRAY_FLAG10_MASK_SIGN_Y 0x02000000
+#define BF_PXP_WFB_ARRAY_FLAG10_MASK_SIGN_Y(v) \
+ (((v) << 25) & BM_PXP_WFB_ARRAY_FLAG10_MASK_SIGN_Y)
+#define BV_PXP_WFB_ARRAY_FLAG10_MASK_SIGN_Y__0 0x0
+#define BV_PXP_WFB_ARRAY_FLAG10_MASK_SIGN_Y__1 0x1
+#define BM_PXP_WFB_ARRAY_FLAG10_MASK_SIGN_X 0x01000000
+#define BF_PXP_WFB_ARRAY_FLAG10_MASK_SIGN_X(v) \
+ (((v) << 24) & BM_PXP_WFB_ARRAY_FLAG10_MASK_SIGN_X)
+#define BV_PXP_WFB_ARRAY_FLAG10_MASK_SIGN_X__0 0x0
+#define BV_PXP_WFB_ARRAY_FLAG10_MASK_SIGN_X__1 0x1
+#define BP_PXP_WFB_ARRAY_FLAG10_MASK_RSVD2 22
+#define BM_PXP_WFB_ARRAY_FLAG10_MASK_RSVD2 0x00C00000
+#define BF_PXP_WFB_ARRAY_FLAG10_MASK_RSVD2(v) \
+ (((v) << 22) & BM_PXP_WFB_ARRAY_FLAG10_MASK_RSVD2)
+#define BP_PXP_WFB_ARRAY_FLAG10_MASK_OFFSET_Y 20
+#define BM_PXP_WFB_ARRAY_FLAG10_MASK_OFFSET_Y 0x00300000
+#define BF_PXP_WFB_ARRAY_FLAG10_MASK_OFFSET_Y(v) \
+ (((v) << 20) & BM_PXP_WFB_ARRAY_FLAG10_MASK_OFFSET_Y)
+#define BP_PXP_WFB_ARRAY_FLAG10_MASK_RSVD3 18
+#define BM_PXP_WFB_ARRAY_FLAG10_MASK_RSVD3 0x000C0000
+#define BF_PXP_WFB_ARRAY_FLAG10_MASK_RSVD3(v) \
+ (((v) << 18) & BM_PXP_WFB_ARRAY_FLAG10_MASK_RSVD3)
+#define BP_PXP_WFB_ARRAY_FLAG10_MASK_OFFSET_X 16
+#define BM_PXP_WFB_ARRAY_FLAG10_MASK_OFFSET_X 0x00030000
+#define BF_PXP_WFB_ARRAY_FLAG10_MASK_OFFSET_X(v) \
+ (((v) << 16) & BM_PXP_WFB_ARRAY_FLAG10_MASK_OFFSET_X)
+#define BP_PXP_WFB_ARRAY_FLAG10_MASK_RSVD4 13
+#define BM_PXP_WFB_ARRAY_FLAG10_MASK_RSVD4 0x0000E000
+#define BF_PXP_WFB_ARRAY_FLAG10_MASK_RSVD4(v) \
+ (((v) << 13) & BM_PXP_WFB_ARRAY_FLAG10_MASK_RSVD4)
+#define BP_PXP_WFB_ARRAY_FLAG10_MASK_H_OFS 8
+#define BM_PXP_WFB_ARRAY_FLAG10_MASK_H_OFS 0x00001F00
+#define BF_PXP_WFB_ARRAY_FLAG10_MASK_H_OFS(v) \
+ (((v) << 8) & BM_PXP_WFB_ARRAY_FLAG10_MASK_H_OFS)
+#define BP_PXP_WFB_ARRAY_FLAG10_MASK_RSVD5 5
+#define BM_PXP_WFB_ARRAY_FLAG10_MASK_RSVD5 0x000000E0
+#define BF_PXP_WFB_ARRAY_FLAG10_MASK_RSVD5(v) \
+ (((v) << 5) & BM_PXP_WFB_ARRAY_FLAG10_MASK_RSVD5)
+#define BP_PXP_WFB_ARRAY_FLAG10_MASK_L_OFS 0
+#define BM_PXP_WFB_ARRAY_FLAG10_MASK_L_OFS 0x0000001F
+#define BF_PXP_WFB_ARRAY_FLAG10_MASK_L_OFS(v) \
+ (((v) << 0) & BM_PXP_WFB_ARRAY_FLAG10_MASK_L_OFS)
+
+#define HW_PXP_WFB_ARRAY_FLAG11_MASK (0x000012c0)
+
+#define BP_PXP_WFB_ARRAY_FLAG11_MASK_RSVD0 30
+#define BM_PXP_WFB_ARRAY_FLAG11_MASK_RSVD0 0xC0000000
+#define BF_PXP_WFB_ARRAY_FLAG11_MASK_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFB_ARRAY_FLAG11_MASK_RSVD0)
+#define BP_PXP_WFB_ARRAY_FLAG11_MASK_BUF_SEL 28
+#define BM_PXP_WFB_ARRAY_FLAG11_MASK_BUF_SEL 0x30000000
+#define BF_PXP_WFB_ARRAY_FLAG11_MASK_BUF_SEL(v) \
+ (((v) << 28) & BM_PXP_WFB_ARRAY_FLAG11_MASK_BUF_SEL)
+#define BV_PXP_WFB_ARRAY_FLAG11_MASK_BUF_SEL__0 0x0
+#define BV_PXP_WFB_ARRAY_FLAG11_MASK_BUF_SEL__1 0x1
+#define BV_PXP_WFB_ARRAY_FLAG11_MASK_BUF_SEL__2 0x2
+#define BP_PXP_WFB_ARRAY_FLAG11_MASK_RSVD1 26
+#define BM_PXP_WFB_ARRAY_FLAG11_MASK_RSVD1 0x0C000000
+#define BF_PXP_WFB_ARRAY_FLAG11_MASK_RSVD1(v) \
+ (((v) << 26) & BM_PXP_WFB_ARRAY_FLAG11_MASK_RSVD1)
+#define BM_PXP_WFB_ARRAY_FLAG11_MASK_SIGN_Y 0x02000000
+#define BF_PXP_WFB_ARRAY_FLAG11_MASK_SIGN_Y(v) \
+ (((v) << 25) & BM_PXP_WFB_ARRAY_FLAG11_MASK_SIGN_Y)
+#define BV_PXP_WFB_ARRAY_FLAG11_MASK_SIGN_Y__0 0x0
+#define BV_PXP_WFB_ARRAY_FLAG11_MASK_SIGN_Y__1 0x1
+#define BM_PXP_WFB_ARRAY_FLAG11_MASK_SIGN_X 0x01000000
+#define BF_PXP_WFB_ARRAY_FLAG11_MASK_SIGN_X(v) \
+ (((v) << 24) & BM_PXP_WFB_ARRAY_FLAG11_MASK_SIGN_X)
+#define BV_PXP_WFB_ARRAY_FLAG11_MASK_SIGN_X__0 0x0
+#define BV_PXP_WFB_ARRAY_FLAG11_MASK_SIGN_X__1 0x1
+#define BP_PXP_WFB_ARRAY_FLAG11_MASK_RSVD2 22
+#define BM_PXP_WFB_ARRAY_FLAG11_MASK_RSVD2 0x00C00000
+#define BF_PXP_WFB_ARRAY_FLAG11_MASK_RSVD2(v) \
+ (((v) << 22) & BM_PXP_WFB_ARRAY_FLAG11_MASK_RSVD2)
+#define BP_PXP_WFB_ARRAY_FLAG11_MASK_OFFSET_Y 20
+#define BM_PXP_WFB_ARRAY_FLAG11_MASK_OFFSET_Y 0x00300000
+#define BF_PXP_WFB_ARRAY_FLAG11_MASK_OFFSET_Y(v) \
+ (((v) << 20) & BM_PXP_WFB_ARRAY_FLAG11_MASK_OFFSET_Y)
+#define BP_PXP_WFB_ARRAY_FLAG11_MASK_RSVD3 18
+#define BM_PXP_WFB_ARRAY_FLAG11_MASK_RSVD3 0x000C0000
+#define BF_PXP_WFB_ARRAY_FLAG11_MASK_RSVD3(v) \
+ (((v) << 18) & BM_PXP_WFB_ARRAY_FLAG11_MASK_RSVD3)
+#define BP_PXP_WFB_ARRAY_FLAG11_MASK_OFFSET_X 16
+#define BM_PXP_WFB_ARRAY_FLAG11_MASK_OFFSET_X 0x00030000
+#define BF_PXP_WFB_ARRAY_FLAG11_MASK_OFFSET_X(v) \
+ (((v) << 16) & BM_PXP_WFB_ARRAY_FLAG11_MASK_OFFSET_X)
+#define BP_PXP_WFB_ARRAY_FLAG11_MASK_RSVD4 13
+#define BM_PXP_WFB_ARRAY_FLAG11_MASK_RSVD4 0x0000E000
+#define BF_PXP_WFB_ARRAY_FLAG11_MASK_RSVD4(v) \
+ (((v) << 13) & BM_PXP_WFB_ARRAY_FLAG11_MASK_RSVD4)
+#define BP_PXP_WFB_ARRAY_FLAG11_MASK_H_OFS 8
+#define BM_PXP_WFB_ARRAY_FLAG11_MASK_H_OFS 0x00001F00
+#define BF_PXP_WFB_ARRAY_FLAG11_MASK_H_OFS(v) \
+ (((v) << 8) & BM_PXP_WFB_ARRAY_FLAG11_MASK_H_OFS)
+#define BP_PXP_WFB_ARRAY_FLAG11_MASK_RSVD5 5
+#define BM_PXP_WFB_ARRAY_FLAG11_MASK_RSVD5 0x000000E0
+#define BF_PXP_WFB_ARRAY_FLAG11_MASK_RSVD5(v) \
+ (((v) << 5) & BM_PXP_WFB_ARRAY_FLAG11_MASK_RSVD5)
+#define BP_PXP_WFB_ARRAY_FLAG11_MASK_L_OFS 0
+#define BM_PXP_WFB_ARRAY_FLAG11_MASK_L_OFS 0x0000001F
+#define BF_PXP_WFB_ARRAY_FLAG11_MASK_L_OFS(v) \
+ (((v) << 0) & BM_PXP_WFB_ARRAY_FLAG11_MASK_L_OFS)
+
+#define HW_PXP_WFB_ARRAY_FLAG12_MASK (0x000012d0)
+
+#define BP_PXP_WFB_ARRAY_FLAG12_MASK_RSVD0 30
+#define BM_PXP_WFB_ARRAY_FLAG12_MASK_RSVD0 0xC0000000
+#define BF_PXP_WFB_ARRAY_FLAG12_MASK_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFB_ARRAY_FLAG12_MASK_RSVD0)
+#define BP_PXP_WFB_ARRAY_FLAG12_MASK_BUF_SEL 28
+#define BM_PXP_WFB_ARRAY_FLAG12_MASK_BUF_SEL 0x30000000
+#define BF_PXP_WFB_ARRAY_FLAG12_MASK_BUF_SEL(v) \
+ (((v) << 28) & BM_PXP_WFB_ARRAY_FLAG12_MASK_BUF_SEL)
+#define BV_PXP_WFB_ARRAY_FLAG12_MASK_BUF_SEL__0 0x0
+#define BV_PXP_WFB_ARRAY_FLAG12_MASK_BUF_SEL__1 0x1
+#define BV_PXP_WFB_ARRAY_FLAG12_MASK_BUF_SEL__2 0x2
+#define BP_PXP_WFB_ARRAY_FLAG12_MASK_RSVD1 26
+#define BM_PXP_WFB_ARRAY_FLAG12_MASK_RSVD1 0x0C000000
+#define BF_PXP_WFB_ARRAY_FLAG12_MASK_RSVD1(v) \
+ (((v) << 26) & BM_PXP_WFB_ARRAY_FLAG12_MASK_RSVD1)
+#define BM_PXP_WFB_ARRAY_FLAG12_MASK_SIGN_Y 0x02000000
+#define BF_PXP_WFB_ARRAY_FLAG12_MASK_SIGN_Y(v) \
+ (((v) << 25) & BM_PXP_WFB_ARRAY_FLAG12_MASK_SIGN_Y)
+#define BV_PXP_WFB_ARRAY_FLAG12_MASK_SIGN_Y__0 0x0
+#define BV_PXP_WFB_ARRAY_FLAG12_MASK_SIGN_Y__1 0x1
+#define BM_PXP_WFB_ARRAY_FLAG12_MASK_SIGN_X 0x01000000
+#define BF_PXP_WFB_ARRAY_FLAG12_MASK_SIGN_X(v) \
+ (((v) << 24) & BM_PXP_WFB_ARRAY_FLAG12_MASK_SIGN_X)
+#define BV_PXP_WFB_ARRAY_FLAG12_MASK_SIGN_X__0 0x0
+#define BV_PXP_WFB_ARRAY_FLAG12_MASK_SIGN_X__1 0x1
+#define BP_PXP_WFB_ARRAY_FLAG12_MASK_RSVD2 22
+#define BM_PXP_WFB_ARRAY_FLAG12_MASK_RSVD2 0x00C00000
+#define BF_PXP_WFB_ARRAY_FLAG12_MASK_RSVD2(v) \
+ (((v) << 22) & BM_PXP_WFB_ARRAY_FLAG12_MASK_RSVD2)
+#define BP_PXP_WFB_ARRAY_FLAG12_MASK_OFFSET_Y 20
+#define BM_PXP_WFB_ARRAY_FLAG12_MASK_OFFSET_Y 0x00300000
+#define BF_PXP_WFB_ARRAY_FLAG12_MASK_OFFSET_Y(v) \
+ (((v) << 20) & BM_PXP_WFB_ARRAY_FLAG12_MASK_OFFSET_Y)
+#define BP_PXP_WFB_ARRAY_FLAG12_MASK_RSVD3 18
+#define BM_PXP_WFB_ARRAY_FLAG12_MASK_RSVD3 0x000C0000
+#define BF_PXP_WFB_ARRAY_FLAG12_MASK_RSVD3(v) \
+ (((v) << 18) & BM_PXP_WFB_ARRAY_FLAG12_MASK_RSVD3)
+#define BP_PXP_WFB_ARRAY_FLAG12_MASK_OFFSET_X 16
+#define BM_PXP_WFB_ARRAY_FLAG12_MASK_OFFSET_X 0x00030000
+#define BF_PXP_WFB_ARRAY_FLAG12_MASK_OFFSET_X(v) \
+ (((v) << 16) & BM_PXP_WFB_ARRAY_FLAG12_MASK_OFFSET_X)
+#define BP_PXP_WFB_ARRAY_FLAG12_MASK_RSVD4 13
+#define BM_PXP_WFB_ARRAY_FLAG12_MASK_RSVD4 0x0000E000
+#define BF_PXP_WFB_ARRAY_FLAG12_MASK_RSVD4(v) \
+ (((v) << 13) & BM_PXP_WFB_ARRAY_FLAG12_MASK_RSVD4)
+#define BP_PXP_WFB_ARRAY_FLAG12_MASK_H_OFS 8
+#define BM_PXP_WFB_ARRAY_FLAG12_MASK_H_OFS 0x00001F00
+#define BF_PXP_WFB_ARRAY_FLAG12_MASK_H_OFS(v) \
+ (((v) << 8) & BM_PXP_WFB_ARRAY_FLAG12_MASK_H_OFS)
+#define BP_PXP_WFB_ARRAY_FLAG12_MASK_RSVD5 5
+#define BM_PXP_WFB_ARRAY_FLAG12_MASK_RSVD5 0x000000E0
+#define BF_PXP_WFB_ARRAY_FLAG12_MASK_RSVD5(v) \
+ (((v) << 5) & BM_PXP_WFB_ARRAY_FLAG12_MASK_RSVD5)
+#define BP_PXP_WFB_ARRAY_FLAG12_MASK_L_OFS 0
+#define BM_PXP_WFB_ARRAY_FLAG12_MASK_L_OFS 0x0000001F
+#define BF_PXP_WFB_ARRAY_FLAG12_MASK_L_OFS(v) \
+ (((v) << 0) & BM_PXP_WFB_ARRAY_FLAG12_MASK_L_OFS)
+
+#define HW_PXP_WFB_ARRAY_FLAG13_MASK (0x000012e0)
+
+#define BP_PXP_WFB_ARRAY_FLAG13_MASK_RSVD0 30
+#define BM_PXP_WFB_ARRAY_FLAG13_MASK_RSVD0 0xC0000000
+#define BF_PXP_WFB_ARRAY_FLAG13_MASK_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFB_ARRAY_FLAG13_MASK_RSVD0)
+#define BP_PXP_WFB_ARRAY_FLAG13_MASK_BUF_SEL 28
+#define BM_PXP_WFB_ARRAY_FLAG13_MASK_BUF_SEL 0x30000000
+#define BF_PXP_WFB_ARRAY_FLAG13_MASK_BUF_SEL(v) \
+ (((v) << 28) & BM_PXP_WFB_ARRAY_FLAG13_MASK_BUF_SEL)
+#define BV_PXP_WFB_ARRAY_FLAG13_MASK_BUF_SEL__0 0x0
+#define BV_PXP_WFB_ARRAY_FLAG13_MASK_BUF_SEL__1 0x1
+#define BV_PXP_WFB_ARRAY_FLAG13_MASK_BUF_SEL__2 0x2
+#define BP_PXP_WFB_ARRAY_FLAG13_MASK_RSVD1 26
+#define BM_PXP_WFB_ARRAY_FLAG13_MASK_RSVD1 0x0C000000
+#define BF_PXP_WFB_ARRAY_FLAG13_MASK_RSVD1(v) \
+ (((v) << 26) & BM_PXP_WFB_ARRAY_FLAG13_MASK_RSVD1)
+#define BM_PXP_WFB_ARRAY_FLAG13_MASK_SIGN_Y 0x02000000
+#define BF_PXP_WFB_ARRAY_FLAG13_MASK_SIGN_Y(v) \
+ (((v) << 25) & BM_PXP_WFB_ARRAY_FLAG13_MASK_SIGN_Y)
+#define BV_PXP_WFB_ARRAY_FLAG13_MASK_SIGN_Y__0 0x0
+#define BV_PXP_WFB_ARRAY_FLAG13_MASK_SIGN_Y__1 0x1
+#define BM_PXP_WFB_ARRAY_FLAG13_MASK_SIGN_X 0x01000000
+#define BF_PXP_WFB_ARRAY_FLAG13_MASK_SIGN_X(v) \
+ (((v) << 24) & BM_PXP_WFB_ARRAY_FLAG13_MASK_SIGN_X)
+#define BV_PXP_WFB_ARRAY_FLAG13_MASK_SIGN_X__0 0x0
+#define BV_PXP_WFB_ARRAY_FLAG13_MASK_SIGN_X__1 0x1
+#define BP_PXP_WFB_ARRAY_FLAG13_MASK_RSVD2 22
+#define BM_PXP_WFB_ARRAY_FLAG13_MASK_RSVD2 0x00C00000
+#define BF_PXP_WFB_ARRAY_FLAG13_MASK_RSVD2(v) \
+ (((v) << 22) & BM_PXP_WFB_ARRAY_FLAG13_MASK_RSVD2)
+#define BP_PXP_WFB_ARRAY_FLAG13_MASK_OFFSET_Y 20
+#define BM_PXP_WFB_ARRAY_FLAG13_MASK_OFFSET_Y 0x00300000
+#define BF_PXP_WFB_ARRAY_FLAG13_MASK_OFFSET_Y(v) \
+ (((v) << 20) & BM_PXP_WFB_ARRAY_FLAG13_MASK_OFFSET_Y)
+#define BP_PXP_WFB_ARRAY_FLAG13_MASK_RSVD3 18
+#define BM_PXP_WFB_ARRAY_FLAG13_MASK_RSVD3 0x000C0000
+#define BF_PXP_WFB_ARRAY_FLAG13_MASK_RSVD3(v) \
+ (((v) << 18) & BM_PXP_WFB_ARRAY_FLAG13_MASK_RSVD3)
+#define BP_PXP_WFB_ARRAY_FLAG13_MASK_OFFSET_X 16
+#define BM_PXP_WFB_ARRAY_FLAG13_MASK_OFFSET_X 0x00030000
+#define BF_PXP_WFB_ARRAY_FLAG13_MASK_OFFSET_X(v) \
+ (((v) << 16) & BM_PXP_WFB_ARRAY_FLAG13_MASK_OFFSET_X)
+#define BP_PXP_WFB_ARRAY_FLAG13_MASK_RSVD4 13
+#define BM_PXP_WFB_ARRAY_FLAG13_MASK_RSVD4 0x0000E000
+#define BF_PXP_WFB_ARRAY_FLAG13_MASK_RSVD4(v) \
+ (((v) << 13) & BM_PXP_WFB_ARRAY_FLAG13_MASK_RSVD4)
+#define BP_PXP_WFB_ARRAY_FLAG13_MASK_H_OFS 8
+#define BM_PXP_WFB_ARRAY_FLAG13_MASK_H_OFS 0x00001F00
+#define BF_PXP_WFB_ARRAY_FLAG13_MASK_H_OFS(v) \
+ (((v) << 8) & BM_PXP_WFB_ARRAY_FLAG13_MASK_H_OFS)
+#define BP_PXP_WFB_ARRAY_FLAG13_MASK_RSVD5 5
+#define BM_PXP_WFB_ARRAY_FLAG13_MASK_RSVD5 0x000000E0
+#define BF_PXP_WFB_ARRAY_FLAG13_MASK_RSVD5(v) \
+ (((v) << 5) & BM_PXP_WFB_ARRAY_FLAG13_MASK_RSVD5)
+#define BP_PXP_WFB_ARRAY_FLAG13_MASK_L_OFS 0
+#define BM_PXP_WFB_ARRAY_FLAG13_MASK_L_OFS 0x0000001F
+#define BF_PXP_WFB_ARRAY_FLAG13_MASK_L_OFS(v) \
+ (((v) << 0) & BM_PXP_WFB_ARRAY_FLAG13_MASK_L_OFS)
+
+#define HW_PXP_WFB_ARRAY_FLAG14_MASK (0x000012f0)
+
+#define BP_PXP_WFB_ARRAY_FLAG14_MASK_RSVD0 30
+#define BM_PXP_WFB_ARRAY_FLAG14_MASK_RSVD0 0xC0000000
+#define BF_PXP_WFB_ARRAY_FLAG14_MASK_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFB_ARRAY_FLAG14_MASK_RSVD0)
+#define BP_PXP_WFB_ARRAY_FLAG14_MASK_BUF_SEL 28
+#define BM_PXP_WFB_ARRAY_FLAG14_MASK_BUF_SEL 0x30000000
+#define BF_PXP_WFB_ARRAY_FLAG14_MASK_BUF_SEL(v) \
+ (((v) << 28) & BM_PXP_WFB_ARRAY_FLAG14_MASK_BUF_SEL)
+#define BV_PXP_WFB_ARRAY_FLAG14_MASK_BUF_SEL__0 0x0
+#define BV_PXP_WFB_ARRAY_FLAG14_MASK_BUF_SEL__1 0x1
+#define BV_PXP_WFB_ARRAY_FLAG14_MASK_BUF_SEL__2 0x2
+#define BP_PXP_WFB_ARRAY_FLAG14_MASK_RSVD1 26
+#define BM_PXP_WFB_ARRAY_FLAG14_MASK_RSVD1 0x0C000000
+#define BF_PXP_WFB_ARRAY_FLAG14_MASK_RSVD1(v) \
+ (((v) << 26) & BM_PXP_WFB_ARRAY_FLAG14_MASK_RSVD1)
+#define BM_PXP_WFB_ARRAY_FLAG14_MASK_SIGN_Y 0x02000000
+#define BF_PXP_WFB_ARRAY_FLAG14_MASK_SIGN_Y(v) \
+ (((v) << 25) & BM_PXP_WFB_ARRAY_FLAG14_MASK_SIGN_Y)
+#define BV_PXP_WFB_ARRAY_FLAG14_MASK_SIGN_Y__0 0x0
+#define BV_PXP_WFB_ARRAY_FLAG14_MASK_SIGN_Y__1 0x1
+#define BM_PXP_WFB_ARRAY_FLAG14_MASK_SIGN_X 0x01000000
+#define BF_PXP_WFB_ARRAY_FLAG14_MASK_SIGN_X(v) \
+ (((v) << 24) & BM_PXP_WFB_ARRAY_FLAG14_MASK_SIGN_X)
+#define BV_PXP_WFB_ARRAY_FLAG14_MASK_SIGN_X__0 0x0
+#define BV_PXP_WFB_ARRAY_FLAG14_MASK_SIGN_X__1 0x1
+#define BP_PXP_WFB_ARRAY_FLAG14_MASK_RSVD2 22
+#define BM_PXP_WFB_ARRAY_FLAG14_MASK_RSVD2 0x00C00000
+#define BF_PXP_WFB_ARRAY_FLAG14_MASK_RSVD2(v) \
+ (((v) << 22) & BM_PXP_WFB_ARRAY_FLAG14_MASK_RSVD2)
+#define BP_PXP_WFB_ARRAY_FLAG14_MASK_OFFSET_Y 20
+#define BM_PXP_WFB_ARRAY_FLAG14_MASK_OFFSET_Y 0x00300000
+#define BF_PXP_WFB_ARRAY_FLAG14_MASK_OFFSET_Y(v) \
+ (((v) << 20) & BM_PXP_WFB_ARRAY_FLAG14_MASK_OFFSET_Y)
+#define BP_PXP_WFB_ARRAY_FLAG14_MASK_RSVD3 18
+#define BM_PXP_WFB_ARRAY_FLAG14_MASK_RSVD3 0x000C0000
+#define BF_PXP_WFB_ARRAY_FLAG14_MASK_RSVD3(v) \
+ (((v) << 18) & BM_PXP_WFB_ARRAY_FLAG14_MASK_RSVD3)
+#define BP_PXP_WFB_ARRAY_FLAG14_MASK_OFFSET_X 16
+#define BM_PXP_WFB_ARRAY_FLAG14_MASK_OFFSET_X 0x00030000
+#define BF_PXP_WFB_ARRAY_FLAG14_MASK_OFFSET_X(v) \
+ (((v) << 16) & BM_PXP_WFB_ARRAY_FLAG14_MASK_OFFSET_X)
+#define BP_PXP_WFB_ARRAY_FLAG14_MASK_RSVD4 13
+#define BM_PXP_WFB_ARRAY_FLAG14_MASK_RSVD4 0x0000E000
+#define BF_PXP_WFB_ARRAY_FLAG14_MASK_RSVD4(v) \
+ (((v) << 13) & BM_PXP_WFB_ARRAY_FLAG14_MASK_RSVD4)
+#define BP_PXP_WFB_ARRAY_FLAG14_MASK_H_OFS 8
+#define BM_PXP_WFB_ARRAY_FLAG14_MASK_H_OFS 0x00001F00
+#define BF_PXP_WFB_ARRAY_FLAG14_MASK_H_OFS(v) \
+ (((v) << 8) & BM_PXP_WFB_ARRAY_FLAG14_MASK_H_OFS)
+#define BP_PXP_WFB_ARRAY_FLAG14_MASK_RSVD5 5
+#define BM_PXP_WFB_ARRAY_FLAG14_MASK_RSVD5 0x000000E0
+#define BF_PXP_WFB_ARRAY_FLAG14_MASK_RSVD5(v) \
+ (((v) << 5) & BM_PXP_WFB_ARRAY_FLAG14_MASK_RSVD5)
+#define BP_PXP_WFB_ARRAY_FLAG14_MASK_L_OFS 0
+#define BM_PXP_WFB_ARRAY_FLAG14_MASK_L_OFS 0x0000001F
+#define BF_PXP_WFB_ARRAY_FLAG14_MASK_L_OFS(v) \
+ (((v) << 0) & BM_PXP_WFB_ARRAY_FLAG14_MASK_L_OFS)
+
+#define HW_PXP_WFB_ARRAY_FLAG15_MASK (0x00001300)
+
+#define BP_PXP_WFB_ARRAY_FLAG15_MASK_RSVD0 30
+#define BM_PXP_WFB_ARRAY_FLAG15_MASK_RSVD0 0xC0000000
+#define BF_PXP_WFB_ARRAY_FLAG15_MASK_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFB_ARRAY_FLAG15_MASK_RSVD0)
+#define BP_PXP_WFB_ARRAY_FLAG15_MASK_BUF_SEL 28
+#define BM_PXP_WFB_ARRAY_FLAG15_MASK_BUF_SEL 0x30000000
+#define BF_PXP_WFB_ARRAY_FLAG15_MASK_BUF_SEL(v) \
+ (((v) << 28) & BM_PXP_WFB_ARRAY_FLAG15_MASK_BUF_SEL)
+#define BV_PXP_WFB_ARRAY_FLAG15_MASK_BUF_SEL__0 0x0
+#define BV_PXP_WFB_ARRAY_FLAG15_MASK_BUF_SEL__1 0x1
+#define BV_PXP_WFB_ARRAY_FLAG15_MASK_BUF_SEL__2 0x2
+#define BP_PXP_WFB_ARRAY_FLAG15_MASK_RSVD1 26
+#define BM_PXP_WFB_ARRAY_FLAG15_MASK_RSVD1 0x0C000000
+#define BF_PXP_WFB_ARRAY_FLAG15_MASK_RSVD1(v) \
+ (((v) << 26) & BM_PXP_WFB_ARRAY_FLAG15_MASK_RSVD1)
+#define BM_PXP_WFB_ARRAY_FLAG15_MASK_SIGN_Y 0x02000000
+#define BF_PXP_WFB_ARRAY_FLAG15_MASK_SIGN_Y(v) \
+ (((v) << 25) & BM_PXP_WFB_ARRAY_FLAG15_MASK_SIGN_Y)
+#define BV_PXP_WFB_ARRAY_FLAG15_MASK_SIGN_Y__0 0x0
+#define BV_PXP_WFB_ARRAY_FLAG15_MASK_SIGN_Y__1 0x1
+#define BM_PXP_WFB_ARRAY_FLAG15_MASK_SIGN_X 0x01000000
+#define BF_PXP_WFB_ARRAY_FLAG15_MASK_SIGN_X(v) \
+ (((v) << 24) & BM_PXP_WFB_ARRAY_FLAG15_MASK_SIGN_X)
+#define BV_PXP_WFB_ARRAY_FLAG15_MASK_SIGN_X__0 0x0
+#define BV_PXP_WFB_ARRAY_FLAG15_MASK_SIGN_X__1 0x1
+#define BP_PXP_WFB_ARRAY_FLAG15_MASK_RSVD2 22
+#define BM_PXP_WFB_ARRAY_FLAG15_MASK_RSVD2 0x00C00000
+#define BF_PXP_WFB_ARRAY_FLAG15_MASK_RSVD2(v) \
+ (((v) << 22) & BM_PXP_WFB_ARRAY_FLAG15_MASK_RSVD2)
+#define BP_PXP_WFB_ARRAY_FLAG15_MASK_OFFSET_Y 20
+#define BM_PXP_WFB_ARRAY_FLAG15_MASK_OFFSET_Y 0x00300000
+#define BF_PXP_WFB_ARRAY_FLAG15_MASK_OFFSET_Y(v) \
+ (((v) << 20) & BM_PXP_WFB_ARRAY_FLAG15_MASK_OFFSET_Y)
+#define BP_PXP_WFB_ARRAY_FLAG15_MASK_RSVD3 18
+#define BM_PXP_WFB_ARRAY_FLAG15_MASK_RSVD3 0x000C0000
+#define BF_PXP_WFB_ARRAY_FLAG15_MASK_RSVD3(v) \
+ (((v) << 18) & BM_PXP_WFB_ARRAY_FLAG15_MASK_RSVD3)
+#define BP_PXP_WFB_ARRAY_FLAG15_MASK_OFFSET_X 16
+#define BM_PXP_WFB_ARRAY_FLAG15_MASK_OFFSET_X 0x00030000
+#define BF_PXP_WFB_ARRAY_FLAG15_MASK_OFFSET_X(v) \
+ (((v) << 16) & BM_PXP_WFB_ARRAY_FLAG15_MASK_OFFSET_X)
+#define BP_PXP_WFB_ARRAY_FLAG15_MASK_RSVD4 13
+#define BM_PXP_WFB_ARRAY_FLAG15_MASK_RSVD4 0x0000E000
+#define BF_PXP_WFB_ARRAY_FLAG15_MASK_RSVD4(v) \
+ (((v) << 13) & BM_PXP_WFB_ARRAY_FLAG15_MASK_RSVD4)
+#define BP_PXP_WFB_ARRAY_FLAG15_MASK_H_OFS 8
+#define BM_PXP_WFB_ARRAY_FLAG15_MASK_H_OFS 0x00001F00
+#define BF_PXP_WFB_ARRAY_FLAG15_MASK_H_OFS(v) \
+ (((v) << 8) & BM_PXP_WFB_ARRAY_FLAG15_MASK_H_OFS)
+#define BP_PXP_WFB_ARRAY_FLAG15_MASK_RSVD5 5
+#define BM_PXP_WFB_ARRAY_FLAG15_MASK_RSVD5 0x000000E0
+#define BF_PXP_WFB_ARRAY_FLAG15_MASK_RSVD5(v) \
+ (((v) << 5) & BM_PXP_WFB_ARRAY_FLAG15_MASK_RSVD5)
+#define BP_PXP_WFB_ARRAY_FLAG15_MASK_L_OFS 0
+#define BM_PXP_WFB_ARRAY_FLAG15_MASK_L_OFS 0x0000001F
+#define BF_PXP_WFB_ARRAY_FLAG15_MASK_L_OFS(v) \
+ (((v) << 0) & BM_PXP_WFB_ARRAY_FLAG15_MASK_L_OFS)
+
+#define HW_PXP_WFB_ARRAY_REG0 (0x00001310)
+
+#define BP_PXP_WFB_ARRAY_REG0_SW_PIXLE3 24
+#define BM_PXP_WFB_ARRAY_REG0_SW_PIXLE3 0xFF000000
+#define BF_PXP_WFB_ARRAY_REG0_SW_PIXLE3(v) \
+ (((v) << 24) & BM_PXP_WFB_ARRAY_REG0_SW_PIXLE3)
+#define BP_PXP_WFB_ARRAY_REG0_SW_PIXLE2 16
+#define BM_PXP_WFB_ARRAY_REG0_SW_PIXLE2 0x00FF0000
+#define BF_PXP_WFB_ARRAY_REG0_SW_PIXLE2(v) \
+ (((v) << 16) & BM_PXP_WFB_ARRAY_REG0_SW_PIXLE2)
+#define BP_PXP_WFB_ARRAY_REG0_SW_PIXLE1 8
+#define BM_PXP_WFB_ARRAY_REG0_SW_PIXLE1 0x0000FF00
+#define BF_PXP_WFB_ARRAY_REG0_SW_PIXLE1(v) \
+ (((v) << 8) & BM_PXP_WFB_ARRAY_REG0_SW_PIXLE1)
+#define BP_PXP_WFB_ARRAY_REG0_SW_PIXLE0 0
+#define BM_PXP_WFB_ARRAY_REG0_SW_PIXLE0 0x000000FF
+#define BF_PXP_WFB_ARRAY_REG0_SW_PIXLE0(v) \
+ (((v) << 0) & BM_PXP_WFB_ARRAY_REG0_SW_PIXLE0)
+
+#define HW_PXP_WFB_ARRAY_REG1 (0x00001320)
+
+#define BP_PXP_WFB_ARRAY_REG1_SW_PIXLE7 24
+#define BM_PXP_WFB_ARRAY_REG1_SW_PIXLE7 0xFF000000
+#define BF_PXP_WFB_ARRAY_REG1_SW_PIXLE7(v) \
+ (((v) << 24) & BM_PXP_WFB_ARRAY_REG1_SW_PIXLE7)
+#define BP_PXP_WFB_ARRAY_REG1_SW_PIXLE6 16
+#define BM_PXP_WFB_ARRAY_REG1_SW_PIXLE6 0x00FF0000
+#define BF_PXP_WFB_ARRAY_REG1_SW_PIXLE6(v) \
+ (((v) << 16) & BM_PXP_WFB_ARRAY_REG1_SW_PIXLE6)
+#define BP_PXP_WFB_ARRAY_REG1_SW_PIXLE5 8
+#define BM_PXP_WFB_ARRAY_REG1_SW_PIXLE5 0x0000FF00
+#define BF_PXP_WFB_ARRAY_REG1_SW_PIXLE5(v) \
+ (((v) << 8) & BM_PXP_WFB_ARRAY_REG1_SW_PIXLE5)
+#define BP_PXP_WFB_ARRAY_REG1_SW_PIXLE4 0
+#define BM_PXP_WFB_ARRAY_REG1_SW_PIXLE4 0x000000FF
+#define BF_PXP_WFB_ARRAY_REG1_SW_PIXLE4(v) \
+ (((v) << 0) & BM_PXP_WFB_ARRAY_REG1_SW_PIXLE4)
+
+#define HW_PXP_WFB_ARRAY_REG2 (0x00001330)
+
+#define BP_PXP_WFB_ARRAY_REG2_RSVD0 16
+#define BM_PXP_WFB_ARRAY_REG2_RSVD0 0xFFFF0000
+#define BF_PXP_WFB_ARRAY_REG2_RSVD0(v) \
+ (((v) << 16) & BM_PXP_WFB_ARRAY_REG2_RSVD0)
+#define BM_PXP_WFB_ARRAY_REG2_SW_FLAG15 0x00008000
+#define BF_PXP_WFB_ARRAY_REG2_SW_FLAG15(v) \
+ (((v) << 15) & BM_PXP_WFB_ARRAY_REG2_SW_FLAG15)
+#define BM_PXP_WFB_ARRAY_REG2_SW_FLAG14 0x00004000
+#define BF_PXP_WFB_ARRAY_REG2_SW_FLAG14(v) \
+ (((v) << 14) & BM_PXP_WFB_ARRAY_REG2_SW_FLAG14)
+#define BM_PXP_WFB_ARRAY_REG2_SW_FLAG13 0x00002000
+#define BF_PXP_WFB_ARRAY_REG2_SW_FLAG13(v) \
+ (((v) << 13) & BM_PXP_WFB_ARRAY_REG2_SW_FLAG13)
+#define BM_PXP_WFB_ARRAY_REG2_SW_FLAG12 0x00001000
+#define BF_PXP_WFB_ARRAY_REG2_SW_FLAG12(v) \
+ (((v) << 12) & BM_PXP_WFB_ARRAY_REG2_SW_FLAG12)
+#define BM_PXP_WFB_ARRAY_REG2_SW_FLAG11 0x00000800
+#define BF_PXP_WFB_ARRAY_REG2_SW_FLAG11(v) \
+ (((v) << 11) & BM_PXP_WFB_ARRAY_REG2_SW_FLAG11)
+#define BM_PXP_WFB_ARRAY_REG2_SW_FLAG10 0x00000400
+#define BF_PXP_WFB_ARRAY_REG2_SW_FLAG10(v) \
+ (((v) << 10) & BM_PXP_WFB_ARRAY_REG2_SW_FLAG10)
+#define BM_PXP_WFB_ARRAY_REG2_SW_FLAG9 0x00000200
+#define BF_PXP_WFB_ARRAY_REG2_SW_FLAG9(v) \
+ (((v) << 9) & BM_PXP_WFB_ARRAY_REG2_SW_FLAG9)
+#define BM_PXP_WFB_ARRAY_REG2_SW_FLAG8 0x00000100
+#define BF_PXP_WFB_ARRAY_REG2_SW_FLAG8(v) \
+ (((v) << 8) & BM_PXP_WFB_ARRAY_REG2_SW_FLAG8)
+#define BM_PXP_WFB_ARRAY_REG2_SW_FLAG7 0x00000080
+#define BF_PXP_WFB_ARRAY_REG2_SW_FLAG7(v) \
+ (((v) << 7) & BM_PXP_WFB_ARRAY_REG2_SW_FLAG7)
+#define BM_PXP_WFB_ARRAY_REG2_SW_FLAG6 0x00000040
+#define BF_PXP_WFB_ARRAY_REG2_SW_FLAG6(v) \
+ (((v) << 6) & BM_PXP_WFB_ARRAY_REG2_SW_FLAG6)
+#define BM_PXP_WFB_ARRAY_REG2_SW_FLAG5 0x00000020
+#define BF_PXP_WFB_ARRAY_REG2_SW_FLAG5(v) \
+ (((v) << 5) & BM_PXP_WFB_ARRAY_REG2_SW_FLAG5)
+#define BM_PXP_WFB_ARRAY_REG2_SW_FLAG4 0x00000010
+#define BF_PXP_WFB_ARRAY_REG2_SW_FLAG4(v) \
+ (((v) << 4) & BM_PXP_WFB_ARRAY_REG2_SW_FLAG4)
+#define BM_PXP_WFB_ARRAY_REG2_SW_FLAG3 0x00000008
+#define BF_PXP_WFB_ARRAY_REG2_SW_FLAG3(v) \
+ (((v) << 3) & BM_PXP_WFB_ARRAY_REG2_SW_FLAG3)
+#define BM_PXP_WFB_ARRAY_REG2_SW_FLAG2 0x00000004
+#define BF_PXP_WFB_ARRAY_REG2_SW_FLAG2(v) \
+ (((v) << 2) & BM_PXP_WFB_ARRAY_REG2_SW_FLAG2)
+#define BM_PXP_WFB_ARRAY_REG2_SW_FLAG1 0x00000002
+#define BF_PXP_WFB_ARRAY_REG2_SW_FLAG1(v) \
+ (((v) << 1) & BM_PXP_WFB_ARRAY_REG2_SW_FLAG1)
+#define BM_PXP_WFB_ARRAY_REG2_SW_FLAG0 0x00000001
+#define BF_PXP_WFB_ARRAY_REG2_SW_FLAG0(v) \
+ (((v) << 0) & BM_PXP_WFB_ARRAY_REG2_SW_FLAG0)
+
+#define HW_PXP_WFE_B_STORE_CTRL_CH0 (0x00001340)
+#define HW_PXP_WFE_B_STORE_CTRL_CH0_SET (0x00001344)
+#define HW_PXP_WFE_B_STORE_CTRL_CH0_CLR (0x00001348)
+#define HW_PXP_WFE_B_STORE_CTRL_CH0_TOG (0x0000134c)
+
+#define BM_PXP_WFE_B_STORE_CTRL_CH0_ARBIT_EN 0x80000000
+#define BF_PXP_WFE_B_STORE_CTRL_CH0_ARBIT_EN(v) \
+ (((v) << 31) & BM_PXP_WFE_B_STORE_CTRL_CH0_ARBIT_EN)
+#define BV_PXP_WFE_B_STORE_CTRL_CH0_ARBIT_EN__0 0x0
+#define BV_PXP_WFE_B_STORE_CTRL_CH0_ARBIT_EN__1 0x1
+#define BP_PXP_WFE_B_STORE_CTRL_CH0_RSVD0 25
+#define BM_PXP_WFE_B_STORE_CTRL_CH0_RSVD0 0x7E000000
+#define BF_PXP_WFE_B_STORE_CTRL_CH0_RSVD0(v) \
+ (((v) << 25) & BM_PXP_WFE_B_STORE_CTRL_CH0_RSVD0)
+#define BM_PXP_WFE_B_STORE_CTRL_CH0_COMBINE_2CHANNEL 0x01000000
+#define BF_PXP_WFE_B_STORE_CTRL_CH0_COMBINE_2CHANNEL(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STORE_CTRL_CH0_COMBINE_2CHANNEL)
+#define BV_PXP_WFE_B_STORE_CTRL_CH0_COMBINE_2CHANNEL__0 0x0
+#define BV_PXP_WFE_B_STORE_CTRL_CH0_COMBINE_2CHANNEL__1 0x1
+#define BP_PXP_WFE_B_STORE_CTRL_CH0_RSVD1 18
+#define BM_PXP_WFE_B_STORE_CTRL_CH0_RSVD1 0x00FC0000
+#define BF_PXP_WFE_B_STORE_CTRL_CH0_RSVD1(v) \
+ (((v) << 18) & BM_PXP_WFE_B_STORE_CTRL_CH0_RSVD1)
+#define BP_PXP_WFE_B_STORE_CTRL_CH0_WR_NUM_BYTES 16
+#define BM_PXP_WFE_B_STORE_CTRL_CH0_WR_NUM_BYTES 0x00030000
+#define BF_PXP_WFE_B_STORE_CTRL_CH0_WR_NUM_BYTES(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STORE_CTRL_CH0_WR_NUM_BYTES)
+#define BV_PXP_WFE_B_STORE_CTRL_CH0_WR_NUM_BYTES__8_bytes 0x0
+#define BV_PXP_WFE_B_STORE_CTRL_CH0_WR_NUM_BYTES__16_bytes 0x1
+#define BV_PXP_WFE_B_STORE_CTRL_CH0_WR_NUM_BYTES__32_bytes 0x2
+#define BV_PXP_WFE_B_STORE_CTRL_CH0_WR_NUM_BYTES__64_bytes 0x3
+#define BP_PXP_WFE_B_STORE_CTRL_CH0_RSVD2 12
+#define BM_PXP_WFE_B_STORE_CTRL_CH0_RSVD2 0x0000F000
+#define BF_PXP_WFE_B_STORE_CTRL_CH0_RSVD2(v) \
+ (((v) << 12) & BM_PXP_WFE_B_STORE_CTRL_CH0_RSVD2)
+#define BM_PXP_WFE_B_STORE_CTRL_CH0_FILL_DATA_EN 0x00000800
+#define BF_PXP_WFE_B_STORE_CTRL_CH0_FILL_DATA_EN(v) \
+ (((v) << 11) & BM_PXP_WFE_B_STORE_CTRL_CH0_FILL_DATA_EN)
+#define BV_PXP_WFE_B_STORE_CTRL_CH0_FILL_DATA_EN__0 0x0
+#define BV_PXP_WFE_B_STORE_CTRL_CH0_FILL_DATA_EN__1 0x1
+#define BM_PXP_WFE_B_STORE_CTRL_CH0_PACK_IN_SEL 0x00000400
+#define BF_PXP_WFE_B_STORE_CTRL_CH0_PACK_IN_SEL(v) \
+ (((v) << 10) & BM_PXP_WFE_B_STORE_CTRL_CH0_PACK_IN_SEL)
+#define BV_PXP_WFE_B_STORE_CTRL_CH0_PACK_IN_SEL__0 0x0
+#define BV_PXP_WFE_B_STORE_CTRL_CH0_PACK_IN_SEL__1 0x1
+#define BM_PXP_WFE_B_STORE_CTRL_CH0_STORE_MEMORY_EN 0x00000200
+#define BF_PXP_WFE_B_STORE_CTRL_CH0_STORE_MEMORY_EN(v) \
+ (((v) << 9) & BM_PXP_WFE_B_STORE_CTRL_CH0_STORE_MEMORY_EN)
+#define BV_PXP_WFE_B_STORE_CTRL_CH0_STORE_MEMORY_EN__0 0x0
+#define BV_PXP_WFE_B_STORE_CTRL_CH0_STORE_MEMORY_EN__1 0x1
+#define BM_PXP_WFE_B_STORE_CTRL_CH0_STORE_BYPASS_EN 0x00000100
+#define BF_PXP_WFE_B_STORE_CTRL_CH0_STORE_BYPASS_EN(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STORE_CTRL_CH0_STORE_BYPASS_EN)
+#define BV_PXP_WFE_B_STORE_CTRL_CH0_STORE_BYPASS_EN__0 0x0
+#define BV_PXP_WFE_B_STORE_CTRL_CH0_STORE_BYPASS_EN__1 0x1
+#define BM_PXP_WFE_B_STORE_CTRL_CH0_RSVD3 0x00000080
+#define BF_PXP_WFE_B_STORE_CTRL_CH0_RSVD3(v) \
+ (((v) << 7) & BM_PXP_WFE_B_STORE_CTRL_CH0_RSVD3)
+#define BP_PXP_WFE_B_STORE_CTRL_CH0_ARRAY_LINE_NUM 5
+#define BM_PXP_WFE_B_STORE_CTRL_CH0_ARRAY_LINE_NUM 0x00000060
+#define BF_PXP_WFE_B_STORE_CTRL_CH0_ARRAY_LINE_NUM(v) \
+ (((v) << 5) & BM_PXP_WFE_B_STORE_CTRL_CH0_ARRAY_LINE_NUM)
+#define BV_PXP_WFE_B_STORE_CTRL_CH0_ARRAY_LINE_NUM__0 0x0
+#define BV_PXP_WFE_B_STORE_CTRL_CH0_ARRAY_LINE_NUM__1 0x1
+#define BV_PXP_WFE_B_STORE_CTRL_CH0_ARRAY_LINE_NUM__2 0x2
+#define BV_PXP_WFE_B_STORE_CTRL_CH0_ARRAY_LINE_NUM__3 0x3
+#define BM_PXP_WFE_B_STORE_CTRL_CH0_ARRAY_EN 0x00000010
+#define BF_PXP_WFE_B_STORE_CTRL_CH0_ARRAY_EN(v) \
+ (((v) << 4) & BM_PXP_WFE_B_STORE_CTRL_CH0_ARRAY_EN)
+#define BV_PXP_WFE_B_STORE_CTRL_CH0_ARRAY_EN__0 0x0
+#define BV_PXP_WFE_B_STORE_CTRL_CH0_ARRAY_EN__1 0x1
+#define BM_PXP_WFE_B_STORE_CTRL_CH0_HANDSHAKE_EN 0x00000008
+#define BF_PXP_WFE_B_STORE_CTRL_CH0_HANDSHAKE_EN(v) \
+ (((v) << 3) & BM_PXP_WFE_B_STORE_CTRL_CH0_HANDSHAKE_EN)
+#define BV_PXP_WFE_B_STORE_CTRL_CH0_HANDSHAKE_EN__0 0x0
+#define BV_PXP_WFE_B_STORE_CTRL_CH0_HANDSHAKE_EN__1 0x1
+#define BM_PXP_WFE_B_STORE_CTRL_CH0_BLOCK_16 0x00000004
+#define BF_PXP_WFE_B_STORE_CTRL_CH0_BLOCK_16(v) \
+ (((v) << 2) & BM_PXP_WFE_B_STORE_CTRL_CH0_BLOCK_16)
+#define BV_PXP_WFE_B_STORE_CTRL_CH0_BLOCK_16__8x8 0x0
+#define BV_PXP_WFE_B_STORE_CTRL_CH0_BLOCK_16__16x16 0x1
+#define BM_PXP_WFE_B_STORE_CTRL_CH0_BLOCK_EN 0x00000002
+#define BF_PXP_WFE_B_STORE_CTRL_CH0_BLOCK_EN(v) \
+ (((v) << 1) & BM_PXP_WFE_B_STORE_CTRL_CH0_BLOCK_EN)
+#define BV_PXP_WFE_B_STORE_CTRL_CH0_BLOCK_EN__0 0x0
+#define BV_PXP_WFE_B_STORE_CTRL_CH0_BLOCK_EN__1 0x1
+#define BM_PXP_WFE_B_STORE_CTRL_CH0_CH_EN 0x00000001
+#define BF_PXP_WFE_B_STORE_CTRL_CH0_CH_EN(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STORE_CTRL_CH0_CH_EN)
+#define BV_PXP_WFE_B_STORE_CTRL_CH0_CH_EN__0 0x0
+#define BV_PXP_WFE_B_STORE_CTRL_CH0_CH_EN__1 0x1
+
+#define HW_PXP_WFE_B_STORE_CTRL_CH1 (0x00001350)
+#define HW_PXP_WFE_B_STORE_CTRL_CH1_SET (0x00001354)
+#define HW_PXP_WFE_B_STORE_CTRL_CH1_CLR (0x00001358)
+#define HW_PXP_WFE_B_STORE_CTRL_CH1_TOG (0x0000135c)
+
+#define BP_PXP_WFE_B_STORE_CTRL_CH1_RSVD0 18
+#define BM_PXP_WFE_B_STORE_CTRL_CH1_RSVD0 0xFFFC0000
+#define BF_PXP_WFE_B_STORE_CTRL_CH1_RSVD0(v) \
+ (((v) << 18) & BM_PXP_WFE_B_STORE_CTRL_CH1_RSVD0)
+#define BP_PXP_WFE_B_STORE_CTRL_CH1_WR_NUM_BYTES 16
+#define BM_PXP_WFE_B_STORE_CTRL_CH1_WR_NUM_BYTES 0x00030000
+#define BF_PXP_WFE_B_STORE_CTRL_CH1_WR_NUM_BYTES(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STORE_CTRL_CH1_WR_NUM_BYTES)
+#define BV_PXP_WFE_B_STORE_CTRL_CH1_WR_NUM_BYTES__8_bytes 0x0
+#define BV_PXP_WFE_B_STORE_CTRL_CH1_WR_NUM_BYTES__16_bytes 0x1
+#define BV_PXP_WFE_B_STORE_CTRL_CH1_WR_NUM_BYTES__32_bytes 0x2
+#define BV_PXP_WFE_B_STORE_CTRL_CH1_WR_NUM_BYTES__64_bytes 0x3
+#define BP_PXP_WFE_B_STORE_CTRL_CH1_RSVD1 11
+#define BM_PXP_WFE_B_STORE_CTRL_CH1_RSVD1 0x0000F800
+#define BF_PXP_WFE_B_STORE_CTRL_CH1_RSVD1(v) \
+ (((v) << 11) & BM_PXP_WFE_B_STORE_CTRL_CH1_RSVD1)
+#define BM_PXP_WFE_B_STORE_CTRL_CH1_PACK_IN_SEL 0x00000400
+#define BF_PXP_WFE_B_STORE_CTRL_CH1_PACK_IN_SEL(v) \
+ (((v) << 10) & BM_PXP_WFE_B_STORE_CTRL_CH1_PACK_IN_SEL)
+#define BV_PXP_WFE_B_STORE_CTRL_CH1_PACK_IN_SEL__0 0x0
+#define BV_PXP_WFE_B_STORE_CTRL_CH1_PACK_IN_SEL__1 0x1
+#define BM_PXP_WFE_B_STORE_CTRL_CH1_STORE_MEMORY_EN 0x00000200
+#define BF_PXP_WFE_B_STORE_CTRL_CH1_STORE_MEMORY_EN(v) \
+ (((v) << 9) & BM_PXP_WFE_B_STORE_CTRL_CH1_STORE_MEMORY_EN)
+#define BV_PXP_WFE_B_STORE_CTRL_CH1_STORE_MEMORY_EN__0 0x0
+#define BV_PXP_WFE_B_STORE_CTRL_CH1_STORE_MEMORY_EN__1 0x1
+#define BM_PXP_WFE_B_STORE_CTRL_CH1_STORE_BYPASS_EN 0x00000100
+#define BF_PXP_WFE_B_STORE_CTRL_CH1_STORE_BYPASS_EN(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STORE_CTRL_CH1_STORE_BYPASS_EN)
+#define BV_PXP_WFE_B_STORE_CTRL_CH1_STORE_BYPASS_EN__0 0x0
+#define BV_PXP_WFE_B_STORE_CTRL_CH1_STORE_BYPASS_EN__1 0x1
+#define BM_PXP_WFE_B_STORE_CTRL_CH1_RSVD3 0x00000080
+#define BF_PXP_WFE_B_STORE_CTRL_CH1_RSVD3(v) \
+ (((v) << 7) & BM_PXP_WFE_B_STORE_CTRL_CH1_RSVD3)
+#define BP_PXP_WFE_B_STORE_CTRL_CH1_ARRAY_LINE_NUM 5
+#define BM_PXP_WFE_B_STORE_CTRL_CH1_ARRAY_LINE_NUM 0x00000060
+#define BF_PXP_WFE_B_STORE_CTRL_CH1_ARRAY_LINE_NUM(v) \
+ (((v) << 5) & BM_PXP_WFE_B_STORE_CTRL_CH1_ARRAY_LINE_NUM)
+#define BV_PXP_WFE_B_STORE_CTRL_CH1_ARRAY_LINE_NUM__0 0x0
+#define BV_PXP_WFE_B_STORE_CTRL_CH1_ARRAY_LINE_NUM__1 0x1
+#define BV_PXP_WFE_B_STORE_CTRL_CH1_ARRAY_LINE_NUM__2 0x2
+#define BV_PXP_WFE_B_STORE_CTRL_CH1_ARRAY_LINE_NUM__3 0x3
+#define BM_PXP_WFE_B_STORE_CTRL_CH1_ARRAY_EN 0x00000010
+#define BF_PXP_WFE_B_STORE_CTRL_CH1_ARRAY_EN(v) \
+ (((v) << 4) & BM_PXP_WFE_B_STORE_CTRL_CH1_ARRAY_EN)
+#define BV_PXP_WFE_B_STORE_CTRL_CH1_ARRAY_EN__0 0x0
+#define BV_PXP_WFE_B_STORE_CTRL_CH1_ARRAY_EN__1 0x1
+#define BM_PXP_WFE_B_STORE_CTRL_CH1_HANDSHAKE_EN 0x00000008
+#define BF_PXP_WFE_B_STORE_CTRL_CH1_HANDSHAKE_EN(v) \
+ (((v) << 3) & BM_PXP_WFE_B_STORE_CTRL_CH1_HANDSHAKE_EN)
+#define BV_PXP_WFE_B_STORE_CTRL_CH1_HANDSHAKE_EN__0 0x0
+#define BV_PXP_WFE_B_STORE_CTRL_CH1_HANDSHAKE_EN__1 0x1
+#define BM_PXP_WFE_B_STORE_CTRL_CH1_BLOCK_16 0x00000004
+#define BF_PXP_WFE_B_STORE_CTRL_CH1_BLOCK_16(v) \
+ (((v) << 2) & BM_PXP_WFE_B_STORE_CTRL_CH1_BLOCK_16)
+#define BV_PXP_WFE_B_STORE_CTRL_CH1_BLOCK_16__8x8 0x0
+#define BV_PXP_WFE_B_STORE_CTRL_CH1_BLOCK_16__16x16 0x1
+#define BM_PXP_WFE_B_STORE_CTRL_CH1_BLOCK_EN 0x00000002
+#define BF_PXP_WFE_B_STORE_CTRL_CH1_BLOCK_EN(v) \
+ (((v) << 1) & BM_PXP_WFE_B_STORE_CTRL_CH1_BLOCK_EN)
+#define BV_PXP_WFE_B_STORE_CTRL_CH1_BLOCK_EN__0 0x0
+#define BV_PXP_WFE_B_STORE_CTRL_CH1_BLOCK_EN__1 0x1
+#define BM_PXP_WFE_B_STORE_CTRL_CH1_CH_EN 0x00000001
+#define BF_PXP_WFE_B_STORE_CTRL_CH1_CH_EN(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STORE_CTRL_CH1_CH_EN)
+#define BV_PXP_WFE_B_STORE_CTRL_CH1_CH_EN__0 0x0
+#define BV_PXP_WFE_B_STORE_CTRL_CH1_CH_EN__1 0x1
+
+#define HW_PXP_WFE_B_STORE_STATUS_CH0 (0x00001360)
+
+#define BP_PXP_WFE_B_STORE_STATUS_CH0_STORE_BLOCK_Y 16
+#define BM_PXP_WFE_B_STORE_STATUS_CH0_STORE_BLOCK_Y 0xFFFF0000
+#define BF_PXP_WFE_B_STORE_STATUS_CH0_STORE_BLOCK_Y(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STORE_STATUS_CH0_STORE_BLOCK_Y)
+#define BP_PXP_WFE_B_STORE_STATUS_CH0_STORE_BLOCK_X 0
+#define BM_PXP_WFE_B_STORE_STATUS_CH0_STORE_BLOCK_X 0x0000FFFF
+#define BF_PXP_WFE_B_STORE_STATUS_CH0_STORE_BLOCK_X(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STORE_STATUS_CH0_STORE_BLOCK_X)
+
+#define HW_PXP_WFE_B_STORE_STATUS_CH1 (0x00001370)
+
+#define BP_PXP_WFE_B_STORE_STATUS_CH1_STORE_BLOCK_Y 16
+#define BM_PXP_WFE_B_STORE_STATUS_CH1_STORE_BLOCK_Y 0xFFFF0000
+#define BF_PXP_WFE_B_STORE_STATUS_CH1_STORE_BLOCK_Y(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STORE_STATUS_CH1_STORE_BLOCK_Y)
+#define BP_PXP_WFE_B_STORE_STATUS_CH1_STORE_BLOCK_X 0
+#define BM_PXP_WFE_B_STORE_STATUS_CH1_STORE_BLOCK_X 0x0000FFFF
+#define BF_PXP_WFE_B_STORE_STATUS_CH1_STORE_BLOCK_X(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STORE_STATUS_CH1_STORE_BLOCK_X)
+
+#define HW_PXP_WFE_B_STORE_SIZE_CH0 (0x00001380)
+
+#define BP_PXP_WFE_B_STORE_SIZE_CH0_OUT_HEIGHT 16
+#define BM_PXP_WFE_B_STORE_SIZE_CH0_OUT_HEIGHT 0xFFFF0000
+#define BF_PXP_WFE_B_STORE_SIZE_CH0_OUT_HEIGHT(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STORE_SIZE_CH0_OUT_HEIGHT)
+#define BP_PXP_WFE_B_STORE_SIZE_CH0_OUT_WIDTH 0
+#define BM_PXP_WFE_B_STORE_SIZE_CH0_OUT_WIDTH 0x0000FFFF
+#define BF_PXP_WFE_B_STORE_SIZE_CH0_OUT_WIDTH(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STORE_SIZE_CH0_OUT_WIDTH)
+
+#define HW_PXP_WFE_B_STORE_SIZE_CH1 (0x00001390)
+
+#define BP_PXP_WFE_B_STORE_SIZE_CH1_OUT_HEIGHT 16
+#define BM_PXP_WFE_B_STORE_SIZE_CH1_OUT_HEIGHT 0xFFFF0000
+#define BF_PXP_WFE_B_STORE_SIZE_CH1_OUT_HEIGHT(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STORE_SIZE_CH1_OUT_HEIGHT)
+#define BP_PXP_WFE_B_STORE_SIZE_CH1_OUT_WIDTH 0
+#define BM_PXP_WFE_B_STORE_SIZE_CH1_OUT_WIDTH 0x0000FFFF
+#define BF_PXP_WFE_B_STORE_SIZE_CH1_OUT_WIDTH(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STORE_SIZE_CH1_OUT_WIDTH)
+
+#define HW_PXP_WFE_B_STORE_PITCH (0x000013a0)
+
+#define BP_PXP_WFE_B_STORE_PITCH_CH1_OUT_PITCH 16
+#define BM_PXP_WFE_B_STORE_PITCH_CH1_OUT_PITCH 0xFFFF0000
+#define BF_PXP_WFE_B_STORE_PITCH_CH1_OUT_PITCH(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STORE_PITCH_CH1_OUT_PITCH)
+#define BP_PXP_WFE_B_STORE_PITCH_CH0_OUT_PITCH 0
+#define BM_PXP_WFE_B_STORE_PITCH_CH0_OUT_PITCH 0x0000FFFF
+#define BF_PXP_WFE_B_STORE_PITCH_CH0_OUT_PITCH(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STORE_PITCH_CH0_OUT_PITCH)
+
+#define HW_PXP_WFE_B_STORE_SHIFT_CTRL_CH0 (0x000013b0)
+#define HW_PXP_WFE_B_STORE_SHIFT_CTRL_CH0_SET (0x000013b4)
+#define HW_PXP_WFE_B_STORE_SHIFT_CTRL_CH0_CLR (0x000013b8)
+#define HW_PXP_WFE_B_STORE_SHIFT_CTRL_CH0_TOG (0x000013bc)
+
+#define BP_PXP_WFE_B_STORE_SHIFT_CTRL_CH0_RSVD0 8
+#define BM_PXP_WFE_B_STORE_SHIFT_CTRL_CH0_RSVD0 0xFFFFFF00
+#define BF_PXP_WFE_B_STORE_SHIFT_CTRL_CH0_RSVD0(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STORE_SHIFT_CTRL_CH0_RSVD0)
+#define BM_PXP_WFE_B_STORE_SHIFT_CTRL_CH0_SHIFT_BYPASS 0x00000080
+#define BF_PXP_WFE_B_STORE_SHIFT_CTRL_CH0_SHIFT_BYPASS(v) \
+ (((v) << 7) & BM_PXP_WFE_B_STORE_SHIFT_CTRL_CH0_SHIFT_BYPASS)
+#define BV_PXP_WFE_B_STORE_SHIFT_CTRL_CH0_SHIFT_BYPASS__0 0x0
+#define BV_PXP_WFE_B_STORE_SHIFT_CTRL_CH0_SHIFT_BYPASS__1 0x1
+#define BM_PXP_WFE_B_STORE_SHIFT_CTRL_CH0_RSVD1 0x00000040
+#define BF_PXP_WFE_B_STORE_SHIFT_CTRL_CH0_RSVD1(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STORE_SHIFT_CTRL_CH0_RSVD1)
+#define BM_PXP_WFE_B_STORE_SHIFT_CTRL_CH0_OUT_YUV422_2P_EN 0x00000020
+#define BF_PXP_WFE_B_STORE_SHIFT_CTRL_CH0_OUT_YUV422_2P_EN(v) \
+ (((v) << 5) & BM_PXP_WFE_B_STORE_SHIFT_CTRL_CH0_OUT_YUV422_2P_EN)
+#define BV_PXP_WFE_B_STORE_SHIFT_CTRL_CH0_OUT_YUV422_2P_EN__0 0x0
+#define BV_PXP_WFE_B_STORE_SHIFT_CTRL_CH0_OUT_YUV422_2P_EN__1 0x1
+#define BM_PXP_WFE_B_STORE_SHIFT_CTRL_CH0_OUT_YUV422_1P_EN 0x00000010
+#define BF_PXP_WFE_B_STORE_SHIFT_CTRL_CH0_OUT_YUV422_1P_EN(v) \
+ (((v) << 4) & BM_PXP_WFE_B_STORE_SHIFT_CTRL_CH0_OUT_YUV422_1P_EN)
+#define BV_PXP_WFE_B_STORE_SHIFT_CTRL_CH0_OUT_YUV422_1P_EN__0 0x0
+#define BV_PXP_WFE_B_STORE_SHIFT_CTRL_CH0_OUT_YUV422_1P_EN__1 0x1
+#define BP_PXP_WFE_B_STORE_SHIFT_CTRL_CH0_OUTPUT_ACTIVE_BPP 2
+#define BM_PXP_WFE_B_STORE_SHIFT_CTRL_CH0_OUTPUT_ACTIVE_BPP 0x0000000C
+#define BF_PXP_WFE_B_STORE_SHIFT_CTRL_CH0_OUTPUT_ACTIVE_BPP(v) \
+ (((v) << 2) & BM_PXP_WFE_B_STORE_SHIFT_CTRL_CH0_OUTPUT_ACTIVE_BPP)
+#define BV_PXP_WFE_B_STORE_SHIFT_CTRL_CH0_OUTPUT_ACTIVE_BPP__0 0x0
+#define BV_PXP_WFE_B_STORE_SHIFT_CTRL_CH0_OUTPUT_ACTIVE_BPP__1 0x1
+#define BV_PXP_WFE_B_STORE_SHIFT_CTRL_CH0_OUTPUT_ACTIVE_BPP__2 0x2
+#define BV_PXP_WFE_B_STORE_SHIFT_CTRL_CH0_OUTPUT_ACTIVE_BPP__3 0x3
+#define BP_PXP_WFE_B_STORE_SHIFT_CTRL_CH0_RSVD2 0
+#define BM_PXP_WFE_B_STORE_SHIFT_CTRL_CH0_RSVD2 0x00000003
+#define BF_PXP_WFE_B_STORE_SHIFT_CTRL_CH0_RSVD2(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STORE_SHIFT_CTRL_CH0_RSVD2)
+
+#define HW_PXP_WFE_B_STORE_SHIFT_CTRL_CH1 (0x000013c0)
+#define HW_PXP_WFE_B_STORE_SHIFT_CTRL_CH1_SET (0x000013c4)
+#define HW_PXP_WFE_B_STORE_SHIFT_CTRL_CH1_CLR (0x000013c8)
+#define HW_PXP_WFE_B_STORE_SHIFT_CTRL_CH1_TOG (0x000013cc)
+
+#define BP_PXP_WFE_B_STORE_SHIFT_CTRL_CH1_RSVD0 6
+#define BM_PXP_WFE_B_STORE_SHIFT_CTRL_CH1_RSVD0 0xFFFFFFC0
+#define BF_PXP_WFE_B_STORE_SHIFT_CTRL_CH1_RSVD0(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STORE_SHIFT_CTRL_CH1_RSVD0)
+#define BM_PXP_WFE_B_STORE_SHIFT_CTRL_CH1_OUT_YUV422_2P_EN 0x00000020
+#define BF_PXP_WFE_B_STORE_SHIFT_CTRL_CH1_OUT_YUV422_2P_EN(v) \
+ (((v) << 5) & BM_PXP_WFE_B_STORE_SHIFT_CTRL_CH1_OUT_YUV422_2P_EN)
+#define BV_PXP_WFE_B_STORE_SHIFT_CTRL_CH1_OUT_YUV422_2P_EN__0 0x0
+#define BV_PXP_WFE_B_STORE_SHIFT_CTRL_CH1_OUT_YUV422_2P_EN__1 0x1
+#define BM_PXP_WFE_B_STORE_SHIFT_CTRL_CH1_OUT_YUV422_1P_EN 0x00000010
+#define BF_PXP_WFE_B_STORE_SHIFT_CTRL_CH1_OUT_YUV422_1P_EN(v) \
+ (((v) << 4) & BM_PXP_WFE_B_STORE_SHIFT_CTRL_CH1_OUT_YUV422_1P_EN)
+#define BV_PXP_WFE_B_STORE_SHIFT_CTRL_CH1_OUT_YUV422_1P_EN__0 0x0
+#define BV_PXP_WFE_B_STORE_SHIFT_CTRL_CH1_OUT_YUV422_1P_EN__1 0x1
+#define BP_PXP_WFE_B_STORE_SHIFT_CTRL_CH1_OUTPUT_ACTIVE_BPP 2
+#define BM_PXP_WFE_B_STORE_SHIFT_CTRL_CH1_OUTPUT_ACTIVE_BPP 0x0000000C
+#define BF_PXP_WFE_B_STORE_SHIFT_CTRL_CH1_OUTPUT_ACTIVE_BPP(v) \
+ (((v) << 2) & BM_PXP_WFE_B_STORE_SHIFT_CTRL_CH1_OUTPUT_ACTIVE_BPP)
+#define BV_PXP_WFE_B_STORE_SHIFT_CTRL_CH1_OUTPUT_ACTIVE_BPP__0 0x0
+#define BV_PXP_WFE_B_STORE_SHIFT_CTRL_CH1_OUTPUT_ACTIVE_BPP__1 0x1
+#define BV_PXP_WFE_B_STORE_SHIFT_CTRL_CH1_OUTPUT_ACTIVE_BPP__2 0x2
+#define BV_PXP_WFE_B_STORE_SHIFT_CTRL_CH1_OUTPUT_ACTIVE_BPP__3 0x3
+#define BP_PXP_WFE_B_STORE_SHIFT_CTRL_CH1_RSVD2 0
+#define BM_PXP_WFE_B_STORE_SHIFT_CTRL_CH1_RSVD2 0x00000003
+#define BF_PXP_WFE_B_STORE_SHIFT_CTRL_CH1_RSVD2(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STORE_SHIFT_CTRL_CH1_RSVD2)
+
+#define HW_PXP_WFE_B_STORE_ADDR_0_CH0 (0x00001410)
+
+#define BP_PXP_WFE_B_STORE_ADDR_0_CH0_OUT_BASE_ADDR0 0
+#define BM_PXP_WFE_B_STORE_ADDR_0_CH0_OUT_BASE_ADDR0 0xFFFFFFFF
+#define BF_PXP_WFE_B_STORE_ADDR_0_CH0_OUT_BASE_ADDR0(v) (v)
+
+#define HW_PXP_WFE_B_STORE_ADDR_1_CH0 (0x00001420)
+
+#define BP_PXP_WFE_B_STORE_ADDR_1_CH0_OUT_BASE_ADDR1 0
+#define BM_PXP_WFE_B_STORE_ADDR_1_CH0_OUT_BASE_ADDR1 0xFFFFFFFF
+#define BF_PXP_WFE_B_STORE_ADDR_1_CH0_OUT_BASE_ADDR1(v) (v)
+
+#define HW_PXP_WFE_B_STORE_FILL_DATA_CH0 (0x00001430)
+
+#define BP_PXP_WFE_B_STORE_FILL_DATA_CH0_FILL_DATA_CH0 0
+#define BM_PXP_WFE_B_STORE_FILL_DATA_CH0_FILL_DATA_CH0 0xFFFFFFFF
+#define BF_PXP_WFE_B_STORE_FILL_DATA_CH0_FILL_DATA_CH0(v) (v)
+
+#define HW_PXP_WFE_B_STORE_ADDR_0_CH1 (0x00001440)
+
+#define BP_PXP_WFE_B_STORE_ADDR_0_CH1_OUT_BASE_ADDR0 0
+#define BM_PXP_WFE_B_STORE_ADDR_0_CH1_OUT_BASE_ADDR0 0xFFFFFFFF
+#define BF_PXP_WFE_B_STORE_ADDR_0_CH1_OUT_BASE_ADDR0(v) (v)
+
+#define HW_PXP_WFE_B_STORE_ADDR_1_CH1 (0x00001450)
+
+#define BP_PXP_WFE_B_STORE_ADDR_1_CH1_OUT_BASE_ADDR1 0
+#define BM_PXP_WFE_B_STORE_ADDR_1_CH1_OUT_BASE_ADDR1 0xFFFFFFFF
+#define BF_PXP_WFE_B_STORE_ADDR_1_CH1_OUT_BASE_ADDR1(v) (v)
+
+#define HW_PXP_WFE_B_STORE_D_MASK0_H_CH0 (0x00001460)
+
+#define BP_PXP_WFE_B_STORE_D_MASK0_H_CH0_D_MASK0_H_CH0 0
+#define BM_PXP_WFE_B_STORE_D_MASK0_H_CH0_D_MASK0_H_CH0 0xFFFFFFFF
+#define BF_PXP_WFE_B_STORE_D_MASK0_H_CH0_D_MASK0_H_CH0(v) (v)
+
+#define HW_PXP_WFE_B_STORE_D_MASK0_L_CH0 (0x00001470)
+
+#define BP_PXP_WFE_B_STORE_D_MASK0_L_CH0_D_MASK0_L_CH0 0
+#define BM_PXP_WFE_B_STORE_D_MASK0_L_CH0_D_MASK0_L_CH0 0xFFFFFFFF
+#define BF_PXP_WFE_B_STORE_D_MASK0_L_CH0_D_MASK0_L_CH0(v) (v)
+
+#define HW_PXP_WFE_B_STORE_D_MASK1_H_CH0 (0x00001480)
+
+#define BP_PXP_WFE_B_STORE_D_MASK1_H_CH0_D_MASK1_H_CH0 0
+#define BM_PXP_WFE_B_STORE_D_MASK1_H_CH0_D_MASK1_H_CH0 0xFFFFFFFF
+#define BF_PXP_WFE_B_STORE_D_MASK1_H_CH0_D_MASK1_H_CH0(v) (v)
+
+#define HW_PXP_WFE_B_STORE_D_MASK1_L_CH0 (0x00001490)
+
+#define BP_PXP_WFE_B_STORE_D_MASK1_L_CH0_D_MASK1_L_CH0 0
+#define BM_PXP_WFE_B_STORE_D_MASK1_L_CH0_D_MASK1_L_CH0 0xFFFFFFFF
+#define BF_PXP_WFE_B_STORE_D_MASK1_L_CH0_D_MASK1_L_CH0(v) (v)
+
+#define HW_PXP_WFE_B_STORE_D_MASK2_H_CH0 (0x000014a0)
+
+#define BP_PXP_WFE_B_STORE_D_MASK2_H_CH0_D_MASK2_H_CH0 0
+#define BM_PXP_WFE_B_STORE_D_MASK2_H_CH0_D_MASK2_H_CH0 0xFFFFFFFF
+#define BF_PXP_WFE_B_STORE_D_MASK2_H_CH0_D_MASK2_H_CH0(v) (v)
+
+#define HW_PXP_WFE_B_STORE_D_MASK2_L_CH0 (0x000014b0)
+
+#define BP_PXP_WFE_B_STORE_D_MASK2_L_CH0_D_MASK2_L_CH0 0
+#define BM_PXP_WFE_B_STORE_D_MASK2_L_CH0_D_MASK2_L_CH0 0xFFFFFFFF
+#define BF_PXP_WFE_B_STORE_D_MASK2_L_CH0_D_MASK2_L_CH0(v) (v)
+
+#define HW_PXP_WFE_B_STORE_D_MASK3_H_CH0 (0x000014c0)
+
+#define BP_PXP_WFE_B_STORE_D_MASK3_H_CH0_D_MASK3_H_CH0 0
+#define BM_PXP_WFE_B_STORE_D_MASK3_H_CH0_D_MASK3_H_CH0 0xFFFFFFFF
+#define BF_PXP_WFE_B_STORE_D_MASK3_H_CH0_D_MASK3_H_CH0(v) (v)
+
+#define HW_PXP_WFE_B_STORE_D_MASK3_L_CH0 (0x000014d0)
+
+#define BP_PXP_WFE_B_STORE_D_MASK3_L_CH0_D_MASK3_L_CH0 0
+#define BM_PXP_WFE_B_STORE_D_MASK3_L_CH0_D_MASK3_L_CH0 0xFFFFFFFF
+#define BF_PXP_WFE_B_STORE_D_MASK3_L_CH0_D_MASK3_L_CH0(v) (v)
+
+#define HW_PXP_WFE_B_STORE_D_MASK4_H_CH0 (0x000014e0)
+
+#define BP_PXP_WFE_B_STORE_D_MASK4_H_CH0_D_MASK4_H_CH0 0
+#define BM_PXP_WFE_B_STORE_D_MASK4_H_CH0_D_MASK4_H_CH0 0xFFFFFFFF
+#define BF_PXP_WFE_B_STORE_D_MASK4_H_CH0_D_MASK4_H_CH0(v) (v)
+
+#define HW_PXP_WFE_B_STORE_D_MASK4_L_CH0 (0x000014f0)
+
+#define BP_PXP_WFE_B_STORE_D_MASK4_L_CH0_D_MASK4_L_CH0 0
+#define BM_PXP_WFE_B_STORE_D_MASK4_L_CH0_D_MASK4_L_CH0 0xFFFFFFFF
+#define BF_PXP_WFE_B_STORE_D_MASK4_L_CH0_D_MASK4_L_CH0(v) (v)
+
+#define HW_PXP_WFE_B_STORE_D_MASK5_H_CH0 (0x00001500)
+
+#define BP_PXP_WFE_B_STORE_D_MASK5_H_CH0_D_MASK5_H_CH0 0
+#define BM_PXP_WFE_B_STORE_D_MASK5_H_CH0_D_MASK5_H_CH0 0xFFFFFFFF
+#define BF_PXP_WFE_B_STORE_D_MASK5_H_CH0_D_MASK5_H_CH0(v) (v)
+
+#define HW_PXP_WFE_B_STORE_D_MASK5_L_CH0 (0x00001510)
+
+#define BP_PXP_WFE_B_STORE_D_MASK5_L_CH0_D_MASK5_L_CH0 0
+#define BM_PXP_WFE_B_STORE_D_MASK5_L_CH0_D_MASK5_L_CH0 0xFFFFFFFF
+#define BF_PXP_WFE_B_STORE_D_MASK5_L_CH0_D_MASK5_L_CH0(v) (v)
+
+#define HW_PXP_WFE_B_STORE_D_MASK6_H_CH0 (0x00001520)
+
+#define BP_PXP_WFE_B_STORE_D_MASK6_H_CH0_D_MASK6_H_CH0 0
+#define BM_PXP_WFE_B_STORE_D_MASK6_H_CH0_D_MASK6_H_CH0 0xFFFFFFFF
+#define BF_PXP_WFE_B_STORE_D_MASK6_H_CH0_D_MASK6_H_CH0(v) (v)
+
+#define HW_PXP_WFE_B_STORE_D_MASK6_L_CH0 (0x00001530)
+
+#define BP_PXP_WFE_B_STORE_D_MASK6_L_CH0_D_MASK6_L_CH0 0
+#define BM_PXP_WFE_B_STORE_D_MASK6_L_CH0_D_MASK6_L_CH0 0xFFFFFFFF
+#define BF_PXP_WFE_B_STORE_D_MASK6_L_CH0_D_MASK6_L_CH0(v) (v)
+
+#define HW_PXP_WFE_B_STORE_D_MASK7_H_CH0 (0x00001540)
+
+#define BP_PXP_WFE_B_STORE_D_MASK7_H_CH0_D_MASK7_H_CH0 0
+#define BM_PXP_WFE_B_STORE_D_MASK7_H_CH0_D_MASK7_H_CH0 0xFFFFFFFF
+#define BF_PXP_WFE_B_STORE_D_MASK7_H_CH0_D_MASK7_H_CH0(v) (v)
+
+#define HW_PXP_WFE_B_STORE_D_MASK7_L_CH0 (0x00001550)
+
+#define BP_PXP_WFE_B_STORE_D_MASK7_L_CH0_D_MASK7_L_CH0 0
+#define BM_PXP_WFE_B_STORE_D_MASK7_L_CH0_D_MASK7_L_CH0 0xFFFFFFFF
+#define BF_PXP_WFE_B_STORE_D_MASK7_L_CH0_D_MASK7_L_CH0(v) (v)
+
+#define HW_PXP_WFE_B_STORE_D_SHIFT_L_CH0 (0x00001560)
+
+#define BM_PXP_WFE_B_STORE_D_SHIFT_L_CH0_D_SHIFT_FLAG3 0x80000000
+#define BF_PXP_WFE_B_STORE_D_SHIFT_L_CH0_D_SHIFT_FLAG3(v) \
+ (((v) << 31) & BM_PXP_WFE_B_STORE_D_SHIFT_L_CH0_D_SHIFT_FLAG3)
+#define BM_PXP_WFE_B_STORE_D_SHIFT_L_CH0_RSVD0 0x40000000
+#define BF_PXP_WFE_B_STORE_D_SHIFT_L_CH0_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STORE_D_SHIFT_L_CH0_RSVD0)
+#define BP_PXP_WFE_B_STORE_D_SHIFT_L_CH0_D_SHIFT_WIDTH3 24
+#define BM_PXP_WFE_B_STORE_D_SHIFT_L_CH0_D_SHIFT_WIDTH3 0x3F000000
+#define BF_PXP_WFE_B_STORE_D_SHIFT_L_CH0_D_SHIFT_WIDTH3(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STORE_D_SHIFT_L_CH0_D_SHIFT_WIDTH3)
+#define BM_PXP_WFE_B_STORE_D_SHIFT_L_CH0_D_SHIFT_FLAG2 0x00800000
+#define BF_PXP_WFE_B_STORE_D_SHIFT_L_CH0_D_SHIFT_FLAG2(v) \
+ (((v) << 23) & BM_PXP_WFE_B_STORE_D_SHIFT_L_CH0_D_SHIFT_FLAG2)
+#define BM_PXP_WFE_B_STORE_D_SHIFT_L_CH0_RSVD1 0x00400000
+#define BF_PXP_WFE_B_STORE_D_SHIFT_L_CH0_RSVD1(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STORE_D_SHIFT_L_CH0_RSVD1)
+#define BP_PXP_WFE_B_STORE_D_SHIFT_L_CH0_D_SHIFT_WIDTH2 16
+#define BM_PXP_WFE_B_STORE_D_SHIFT_L_CH0_D_SHIFT_WIDTH2 0x003F0000
+#define BF_PXP_WFE_B_STORE_D_SHIFT_L_CH0_D_SHIFT_WIDTH2(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STORE_D_SHIFT_L_CH0_D_SHIFT_WIDTH2)
+#define BM_PXP_WFE_B_STORE_D_SHIFT_L_CH0_D_SHIFT_FLAG1 0x00008000
+#define BF_PXP_WFE_B_STORE_D_SHIFT_L_CH0_D_SHIFT_FLAG1(v) \
+ (((v) << 15) & BM_PXP_WFE_B_STORE_D_SHIFT_L_CH0_D_SHIFT_FLAG1)
+#define BM_PXP_WFE_B_STORE_D_SHIFT_L_CH0_RSVD2 0x00004000
+#define BF_PXP_WFE_B_STORE_D_SHIFT_L_CH0_RSVD2(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STORE_D_SHIFT_L_CH0_RSVD2)
+#define BP_PXP_WFE_B_STORE_D_SHIFT_L_CH0_D_SHIFT_WIDTH1 8
+#define BM_PXP_WFE_B_STORE_D_SHIFT_L_CH0_D_SHIFT_WIDTH1 0x00003F00
+#define BF_PXP_WFE_B_STORE_D_SHIFT_L_CH0_D_SHIFT_WIDTH1(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STORE_D_SHIFT_L_CH0_D_SHIFT_WIDTH1)
+#define BM_PXP_WFE_B_STORE_D_SHIFT_L_CH0_D_SHIFT_FLAG0 0x00000080
+#define BF_PXP_WFE_B_STORE_D_SHIFT_L_CH0_D_SHIFT_FLAG0(v) \
+ (((v) << 7) & BM_PXP_WFE_B_STORE_D_SHIFT_L_CH0_D_SHIFT_FLAG0)
+#define BM_PXP_WFE_B_STORE_D_SHIFT_L_CH0_RSVD3 0x00000040
+#define BF_PXP_WFE_B_STORE_D_SHIFT_L_CH0_RSVD3(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STORE_D_SHIFT_L_CH0_RSVD3)
+#define BP_PXP_WFE_B_STORE_D_SHIFT_L_CH0_D_SHIFT_WIDTH0 0
+#define BM_PXP_WFE_B_STORE_D_SHIFT_L_CH0_D_SHIFT_WIDTH0 0x0000003F
+#define BF_PXP_WFE_B_STORE_D_SHIFT_L_CH0_D_SHIFT_WIDTH0(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STORE_D_SHIFT_L_CH0_D_SHIFT_WIDTH0)
+
+#define HW_PXP_WFE_B_STORE_D_SHIFT_H_CH0 (0x00001570)
+
+#define BM_PXP_WFE_B_STORE_D_SHIFT_H_CH0_D_SHIFT_FLAG7 0x80000000
+#define BF_PXP_WFE_B_STORE_D_SHIFT_H_CH0_D_SHIFT_FLAG7(v) \
+ (((v) << 31) & BM_PXP_WFE_B_STORE_D_SHIFT_H_CH0_D_SHIFT_FLAG7)
+#define BM_PXP_WFE_B_STORE_D_SHIFT_H_CH0_RSVD0 0x40000000
+#define BF_PXP_WFE_B_STORE_D_SHIFT_H_CH0_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STORE_D_SHIFT_H_CH0_RSVD0)
+#define BP_PXP_WFE_B_STORE_D_SHIFT_H_CH0_D_SHIFT_WIDTH7 24
+#define BM_PXP_WFE_B_STORE_D_SHIFT_H_CH0_D_SHIFT_WIDTH7 0x3F000000
+#define BF_PXP_WFE_B_STORE_D_SHIFT_H_CH0_D_SHIFT_WIDTH7(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STORE_D_SHIFT_H_CH0_D_SHIFT_WIDTH7)
+#define BM_PXP_WFE_B_STORE_D_SHIFT_H_CH0_D_SHIFT_FLAG6 0x00800000
+#define BF_PXP_WFE_B_STORE_D_SHIFT_H_CH0_D_SHIFT_FLAG6(v) \
+ (((v) << 23) & BM_PXP_WFE_B_STORE_D_SHIFT_H_CH0_D_SHIFT_FLAG6)
+#define BM_PXP_WFE_B_STORE_D_SHIFT_H_CH0_RSVD1 0x00400000
+#define BF_PXP_WFE_B_STORE_D_SHIFT_H_CH0_RSVD1(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STORE_D_SHIFT_H_CH0_RSVD1)
+#define BP_PXP_WFE_B_STORE_D_SHIFT_H_CH0_D_SHIFT_WIDTH6 16
+#define BM_PXP_WFE_B_STORE_D_SHIFT_H_CH0_D_SHIFT_WIDTH6 0x003F0000
+#define BF_PXP_WFE_B_STORE_D_SHIFT_H_CH0_D_SHIFT_WIDTH6(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STORE_D_SHIFT_H_CH0_D_SHIFT_WIDTH6)
+#define BM_PXP_WFE_B_STORE_D_SHIFT_H_CH0_D_SHIFT_FLAG5 0x00008000
+#define BF_PXP_WFE_B_STORE_D_SHIFT_H_CH0_D_SHIFT_FLAG5(v) \
+ (((v) << 15) & BM_PXP_WFE_B_STORE_D_SHIFT_H_CH0_D_SHIFT_FLAG5)
+#define BM_PXP_WFE_B_STORE_D_SHIFT_H_CH0_RSVD2 0x00004000
+#define BF_PXP_WFE_B_STORE_D_SHIFT_H_CH0_RSVD2(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STORE_D_SHIFT_H_CH0_RSVD2)
+#define BP_PXP_WFE_B_STORE_D_SHIFT_H_CH0_D_SHIFT_WIDTH5 8
+#define BM_PXP_WFE_B_STORE_D_SHIFT_H_CH0_D_SHIFT_WIDTH5 0x00003F00
+#define BF_PXP_WFE_B_STORE_D_SHIFT_H_CH0_D_SHIFT_WIDTH5(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STORE_D_SHIFT_H_CH0_D_SHIFT_WIDTH5)
+#define BM_PXP_WFE_B_STORE_D_SHIFT_H_CH0_D_SHIFT_FLAG4 0x00000080
+#define BF_PXP_WFE_B_STORE_D_SHIFT_H_CH0_D_SHIFT_FLAG4(v) \
+ (((v) << 7) & BM_PXP_WFE_B_STORE_D_SHIFT_H_CH0_D_SHIFT_FLAG4)
+#define BM_PXP_WFE_B_STORE_D_SHIFT_H_CH0_RSVD3 0x00000040
+#define BF_PXP_WFE_B_STORE_D_SHIFT_H_CH0_RSVD3(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STORE_D_SHIFT_H_CH0_RSVD3)
+#define BP_PXP_WFE_B_STORE_D_SHIFT_H_CH0_D_SHIFT_WIDTH4 0
+#define BM_PXP_WFE_B_STORE_D_SHIFT_H_CH0_D_SHIFT_WIDTH4 0x0000003F
+#define BF_PXP_WFE_B_STORE_D_SHIFT_H_CH0_D_SHIFT_WIDTH4(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STORE_D_SHIFT_H_CH0_D_SHIFT_WIDTH4)
+
+#define HW_PXP_WFE_B_STORE_F_SHIFT_L_CH0 (0x00001580)
+
+#define BM_PXP_WFE_B_STORE_F_SHIFT_L_CH0_RSVD0 0x80000000
+#define BF_PXP_WFE_B_STORE_F_SHIFT_L_CH0_RSVD0(v) \
+ (((v) << 31) & BM_PXP_WFE_B_STORE_F_SHIFT_L_CH0_RSVD0)
+#define BM_PXP_WFE_B_STORE_F_SHIFT_L_CH0_F_SHIFT_FLAG3 0x40000000
+#define BF_PXP_WFE_B_STORE_F_SHIFT_L_CH0_F_SHIFT_FLAG3(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STORE_F_SHIFT_L_CH0_F_SHIFT_FLAG3)
+#define BP_PXP_WFE_B_STORE_F_SHIFT_L_CH0_F_SHIFT_WIDTH3 24
+#define BM_PXP_WFE_B_STORE_F_SHIFT_L_CH0_F_SHIFT_WIDTH3 0x3F000000
+#define BF_PXP_WFE_B_STORE_F_SHIFT_L_CH0_F_SHIFT_WIDTH3(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STORE_F_SHIFT_L_CH0_F_SHIFT_WIDTH3)
+#define BM_PXP_WFE_B_STORE_F_SHIFT_L_CH0_RSVD1 0x00800000
+#define BF_PXP_WFE_B_STORE_F_SHIFT_L_CH0_RSVD1(v) \
+ (((v) << 23) & BM_PXP_WFE_B_STORE_F_SHIFT_L_CH0_RSVD1)
+#define BM_PXP_WFE_B_STORE_F_SHIFT_L_CH0_F_SHIFT_FLAG2 0x00400000
+#define BF_PXP_WFE_B_STORE_F_SHIFT_L_CH0_F_SHIFT_FLAG2(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STORE_F_SHIFT_L_CH0_F_SHIFT_FLAG2)
+#define BP_PXP_WFE_B_STORE_F_SHIFT_L_CH0_F_SHIFT_WIDTH2 16
+#define BM_PXP_WFE_B_STORE_F_SHIFT_L_CH0_F_SHIFT_WIDTH2 0x003F0000
+#define BF_PXP_WFE_B_STORE_F_SHIFT_L_CH0_F_SHIFT_WIDTH2(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STORE_F_SHIFT_L_CH0_F_SHIFT_WIDTH2)
+#define BM_PXP_WFE_B_STORE_F_SHIFT_L_CH0_RSVD2 0x00008000
+#define BF_PXP_WFE_B_STORE_F_SHIFT_L_CH0_RSVD2(v) \
+ (((v) << 15) & BM_PXP_WFE_B_STORE_F_SHIFT_L_CH0_RSVD2)
+#define BM_PXP_WFE_B_STORE_F_SHIFT_L_CH0_F_SHIFT_FLAG1 0x00004000
+#define BF_PXP_WFE_B_STORE_F_SHIFT_L_CH0_F_SHIFT_FLAG1(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STORE_F_SHIFT_L_CH0_F_SHIFT_FLAG1)
+#define BP_PXP_WFE_B_STORE_F_SHIFT_L_CH0_F_SHIFT_WIDTH1 8
+#define BM_PXP_WFE_B_STORE_F_SHIFT_L_CH0_F_SHIFT_WIDTH1 0x00003F00
+#define BF_PXP_WFE_B_STORE_F_SHIFT_L_CH0_F_SHIFT_WIDTH1(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STORE_F_SHIFT_L_CH0_F_SHIFT_WIDTH1)
+#define BM_PXP_WFE_B_STORE_F_SHIFT_L_CH0_RSVD3 0x00000080
+#define BF_PXP_WFE_B_STORE_F_SHIFT_L_CH0_RSVD3(v) \
+ (((v) << 7) & BM_PXP_WFE_B_STORE_F_SHIFT_L_CH0_RSVD3)
+#define BM_PXP_WFE_B_STORE_F_SHIFT_L_CH0_F_SHIFT_FLAG0 0x00000040
+#define BF_PXP_WFE_B_STORE_F_SHIFT_L_CH0_F_SHIFT_FLAG0(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STORE_F_SHIFT_L_CH0_F_SHIFT_FLAG0)
+#define BP_PXP_WFE_B_STORE_F_SHIFT_L_CH0_F_SHIFT_WIDTH0 0
+#define BM_PXP_WFE_B_STORE_F_SHIFT_L_CH0_F_SHIFT_WIDTH0 0x0000003F
+#define BF_PXP_WFE_B_STORE_F_SHIFT_L_CH0_F_SHIFT_WIDTH0(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STORE_F_SHIFT_L_CH0_F_SHIFT_WIDTH0)
+
+#define HW_PXP_WFE_B_STORE_F_SHIFT_H_CH0 (0x00001590)
+
+#define BM_PXP_WFE_B_STORE_F_SHIFT_H_CH0_RSVD0 0x80000000
+#define BF_PXP_WFE_B_STORE_F_SHIFT_H_CH0_RSVD0(v) \
+ (((v) << 31) & BM_PXP_WFE_B_STORE_F_SHIFT_H_CH0_RSVD0)
+#define BM_PXP_WFE_B_STORE_F_SHIFT_H_CH0_F_SHIFT_FLAG7 0x40000000
+#define BF_PXP_WFE_B_STORE_F_SHIFT_H_CH0_F_SHIFT_FLAG7(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STORE_F_SHIFT_H_CH0_F_SHIFT_FLAG7)
+#define BP_PXP_WFE_B_STORE_F_SHIFT_H_CH0_F_SHIFT_WIDTH7 24
+#define BM_PXP_WFE_B_STORE_F_SHIFT_H_CH0_F_SHIFT_WIDTH7 0x3F000000
+#define BF_PXP_WFE_B_STORE_F_SHIFT_H_CH0_F_SHIFT_WIDTH7(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STORE_F_SHIFT_H_CH0_F_SHIFT_WIDTH7)
+#define BM_PXP_WFE_B_STORE_F_SHIFT_H_CH0_RSVD1 0x00800000
+#define BF_PXP_WFE_B_STORE_F_SHIFT_H_CH0_RSVD1(v) \
+ (((v) << 23) & BM_PXP_WFE_B_STORE_F_SHIFT_H_CH0_RSVD1)
+#define BM_PXP_WFE_B_STORE_F_SHIFT_H_CH0_F_SHIFT_FLAG6 0x00400000
+#define BF_PXP_WFE_B_STORE_F_SHIFT_H_CH0_F_SHIFT_FLAG6(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STORE_F_SHIFT_H_CH0_F_SHIFT_FLAG6)
+#define BP_PXP_WFE_B_STORE_F_SHIFT_H_CH0_F_SHIFT_WIDTH6 16
+#define BM_PXP_WFE_B_STORE_F_SHIFT_H_CH0_F_SHIFT_WIDTH6 0x003F0000
+#define BF_PXP_WFE_B_STORE_F_SHIFT_H_CH0_F_SHIFT_WIDTH6(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STORE_F_SHIFT_H_CH0_F_SHIFT_WIDTH6)
+#define BM_PXP_WFE_B_STORE_F_SHIFT_H_CH0_RSVD2 0x00008000
+#define BF_PXP_WFE_B_STORE_F_SHIFT_H_CH0_RSVD2(v) \
+ (((v) << 15) & BM_PXP_WFE_B_STORE_F_SHIFT_H_CH0_RSVD2)
+#define BM_PXP_WFE_B_STORE_F_SHIFT_H_CH0_F_SHIFT_FLAG5 0x00004000
+#define BF_PXP_WFE_B_STORE_F_SHIFT_H_CH0_F_SHIFT_FLAG5(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STORE_F_SHIFT_H_CH0_F_SHIFT_FLAG5)
+#define BP_PXP_WFE_B_STORE_F_SHIFT_H_CH0_F_SHIFT_WIDTH5 8
+#define BM_PXP_WFE_B_STORE_F_SHIFT_H_CH0_F_SHIFT_WIDTH5 0x00003F00
+#define BF_PXP_WFE_B_STORE_F_SHIFT_H_CH0_F_SHIFT_WIDTH5(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STORE_F_SHIFT_H_CH0_F_SHIFT_WIDTH5)
+#define BM_PXP_WFE_B_STORE_F_SHIFT_H_CH0_RSVD3 0x00000080
+#define BF_PXP_WFE_B_STORE_F_SHIFT_H_CH0_RSVD3(v) \
+ (((v) << 7) & BM_PXP_WFE_B_STORE_F_SHIFT_H_CH0_RSVD3)
+#define BM_PXP_WFE_B_STORE_F_SHIFT_H_CH0_F_SHIFT_FLAG4 0x00000040
+#define BF_PXP_WFE_B_STORE_F_SHIFT_H_CH0_F_SHIFT_FLAG4(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STORE_F_SHIFT_H_CH0_F_SHIFT_FLAG4)
+#define BP_PXP_WFE_B_STORE_F_SHIFT_H_CH0_F_SHIFT_WIDTH4 0
+#define BM_PXP_WFE_B_STORE_F_SHIFT_H_CH0_F_SHIFT_WIDTH4 0x0000003F
+#define BF_PXP_WFE_B_STORE_F_SHIFT_H_CH0_F_SHIFT_WIDTH4(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STORE_F_SHIFT_H_CH0_F_SHIFT_WIDTH4)
+
+#define HW_PXP_WFE_B_STORE_F_MASK_L_CH0 (0x000015a0)
+
+#define BP_PXP_WFE_B_STORE_F_MASK_L_CH0_F_MASK3 24
+#define BM_PXP_WFE_B_STORE_F_MASK_L_CH0_F_MASK3 0xFF000000
+#define BF_PXP_WFE_B_STORE_F_MASK_L_CH0_F_MASK3(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STORE_F_MASK_L_CH0_F_MASK3)
+#define BP_PXP_WFE_B_STORE_F_MASK_L_CH0_F_MASK2 16
+#define BM_PXP_WFE_B_STORE_F_MASK_L_CH0_F_MASK2 0x00FF0000
+#define BF_PXP_WFE_B_STORE_F_MASK_L_CH0_F_MASK2(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STORE_F_MASK_L_CH0_F_MASK2)
+#define BP_PXP_WFE_B_STORE_F_MASK_L_CH0_F_MASK1 8
+#define BM_PXP_WFE_B_STORE_F_MASK_L_CH0_F_MASK1 0x0000FF00
+#define BF_PXP_WFE_B_STORE_F_MASK_L_CH0_F_MASK1(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STORE_F_MASK_L_CH0_F_MASK1)
+#define BP_PXP_WFE_B_STORE_F_MASK_L_CH0_F_MASK0 0
+#define BM_PXP_WFE_B_STORE_F_MASK_L_CH0_F_MASK0 0x000000FF
+#define BF_PXP_WFE_B_STORE_F_MASK_L_CH0_F_MASK0(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STORE_F_MASK_L_CH0_F_MASK0)
+
+#define HW_PXP_WFE_B_STORE_F_MASK_H_CH0 (0x000015b0)
+
+#define BP_PXP_WFE_B_STORE_F_MASK_H_CH0_F_MASK7 24
+#define BM_PXP_WFE_B_STORE_F_MASK_H_CH0_F_MASK7 0xFF000000
+#define BF_PXP_WFE_B_STORE_F_MASK_H_CH0_F_MASK7(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STORE_F_MASK_H_CH0_F_MASK7)
+#define BP_PXP_WFE_B_STORE_F_MASK_H_CH0_F_MASK6 16
+#define BM_PXP_WFE_B_STORE_F_MASK_H_CH0_F_MASK6 0x00FF0000
+#define BF_PXP_WFE_B_STORE_F_MASK_H_CH0_F_MASK6(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STORE_F_MASK_H_CH0_F_MASK6)
+#define BP_PXP_WFE_B_STORE_F_MASK_H_CH0_F_MASK5 8
+#define BM_PXP_WFE_B_STORE_F_MASK_H_CH0_F_MASK5 0x0000FF00
+#define BF_PXP_WFE_B_STORE_F_MASK_H_CH0_F_MASK5(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STORE_F_MASK_H_CH0_F_MASK5)
+#define BP_PXP_WFE_B_STORE_F_MASK_H_CH0_F_MASK4 0
+#define BM_PXP_WFE_B_STORE_F_MASK_H_CH0_F_MASK4 0x000000FF
+#define BF_PXP_WFE_B_STORE_F_MASK_H_CH0_F_MASK4(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STORE_F_MASK_H_CH0_F_MASK4)
+
+#define HW_PXP_FETCH_WFE_A_DEBUG (0x000015c0)
+
+#define BP_PXP_FETCH_WFE_A_DEBUG_RSVD 29
+#define BM_PXP_FETCH_WFE_A_DEBUG_RSVD 0xE0000000
+#define BF_PXP_FETCH_WFE_A_DEBUG_RSVD(v) \
+ (((v) << 29) & BM_PXP_FETCH_WFE_A_DEBUG_RSVD)
+#define BM_PXP_FETCH_WFE_A_DEBUG_BUF_SEL 0x10000000
+#define BF_PXP_FETCH_WFE_A_DEBUG_BUF_SEL(v) \
+ (((v) << 28) & BM_PXP_FETCH_WFE_A_DEBUG_BUF_SEL)
+#define BV_PXP_FETCH_WFE_A_DEBUG_BUF_SEL__BF0 0x0
+#define BV_PXP_FETCH_WFE_A_DEBUG_BUF_SEL__BF1 0x1
+#define BP_PXP_FETCH_WFE_A_DEBUG_ITEM_SEL 24
+#define BM_PXP_FETCH_WFE_A_DEBUG_ITEM_SEL 0x0F000000
+#define BF_PXP_FETCH_WFE_A_DEBUG_ITEM_SEL(v) \
+ (((v) << 24) & BM_PXP_FETCH_WFE_A_DEBUG_ITEM_SEL)
+#define BP_PXP_FETCH_WFE_A_DEBUG_DEBUG_VALUE 0
+#define BM_PXP_FETCH_WFE_A_DEBUG_DEBUG_VALUE 0x00FFFFFF
+#define BF_PXP_FETCH_WFE_A_DEBUG_DEBUG_VALUE(v) \
+ (((v) << 0) & BM_PXP_FETCH_WFE_A_DEBUG_DEBUG_VALUE)
+
+#define HW_PXP_FETCH_WFE_B_DEBUG (0x000015d0)
+
+#define BP_PXP_FETCH_WFE_B_DEBUG_RSVD 29
+#define BM_PXP_FETCH_WFE_B_DEBUG_RSVD 0xE0000000
+#define BF_PXP_FETCH_WFE_B_DEBUG_RSVD(v) \
+ (((v) << 29) & BM_PXP_FETCH_WFE_B_DEBUG_RSVD)
+#define BM_PXP_FETCH_WFE_B_DEBUG_BUF_SEL 0x10000000
+#define BF_PXP_FETCH_WFE_B_DEBUG_BUF_SEL(v) \
+ (((v) << 28) & BM_PXP_FETCH_WFE_B_DEBUG_BUF_SEL)
+#define BV_PXP_FETCH_WFE_B_DEBUG_BUF_SEL__BF0 0x0
+#define BV_PXP_FETCH_WFE_B_DEBUG_BUF_SEL__BF1 0x1
+#define BP_PXP_FETCH_WFE_B_DEBUG_ITEM_SEL 24
+#define BM_PXP_FETCH_WFE_B_DEBUG_ITEM_SEL 0x0F000000
+#define BF_PXP_FETCH_WFE_B_DEBUG_ITEM_SEL(v) \
+ (((v) << 24) & BM_PXP_FETCH_WFE_B_DEBUG_ITEM_SEL)
+#define BP_PXP_FETCH_WFE_B_DEBUG_DEBUG_VALUE 0
+#define BM_PXP_FETCH_WFE_B_DEBUG_DEBUG_VALUE 0x00FFFFFF
+#define BF_PXP_FETCH_WFE_B_DEBUG_DEBUG_VALUE(v) \
+ (((v) << 0) & BM_PXP_FETCH_WFE_B_DEBUG_DEBUG_VALUE)
+
+#define HW_PXP_DITHER_CTRL (0x00001670)
+#define HW_PXP_DITHER_CTRL_SET (0x00001674)
+#define HW_PXP_DITHER_CTRL_CLR (0x00001678)
+#define HW_PXP_DITHER_CTRL_TOG (0x0000167c)
+
+#define BM_PXP_DITHER_CTRL_BUSY0 0x80000000
+#define BF_PXP_DITHER_CTRL_BUSY0(v) \
+ (((v) << 31) & BM_PXP_DITHER_CTRL_BUSY0)
+#define BM_PXP_DITHER_CTRL_BUSY1 0x40000000
+#define BF_PXP_DITHER_CTRL_BUSY1(v) \
+ (((v) << 30) & BM_PXP_DITHER_CTRL_BUSY1)
+#define BM_PXP_DITHER_CTRL_BUSY2 0x20000000
+#define BF_PXP_DITHER_CTRL_BUSY2(v) \
+ (((v) << 29) & BM_PXP_DITHER_CTRL_BUSY2)
+#define BP_PXP_DITHER_CTRL_RSVD0 25
+#define BM_PXP_DITHER_CTRL_RSVD0 0x1E000000
+#define BF_PXP_DITHER_CTRL_RSVD0(v) \
+ (((v) << 25) & BM_PXP_DITHER_CTRL_RSVD0)
+#define BM_PXP_DITHER_CTRL_ORDERED_ROUND_MODE 0x01000000
+#define BF_PXP_DITHER_CTRL_ORDERED_ROUND_MODE(v) \
+ (((v) << 24) & BM_PXP_DITHER_CTRL_ORDERED_ROUND_MODE)
+#define BV_PXP_DITHER_CTRL_ORDERED_ROUND_MODE__0 0x0
+#define BV_PXP_DITHER_CTRL_ORDERED_ROUND_MODE__1 0x1
+#define BM_PXP_DITHER_CTRL_FINAL_LUT_ENABLE 0x00800000
+#define BF_PXP_DITHER_CTRL_FINAL_LUT_ENABLE(v) \
+ (((v) << 23) & BM_PXP_DITHER_CTRL_FINAL_LUT_ENABLE)
+#define BV_PXP_DITHER_CTRL_FINAL_LUT_ENABLE__Disabled 0x0
+#define BV_PXP_DITHER_CTRL_FINAL_LUT_ENABLE__Enabled 0x1
+#define BP_PXP_DITHER_CTRL_IDX_MATRIX2_SIZE 21
+#define BM_PXP_DITHER_CTRL_IDX_MATRIX2_SIZE 0x00600000
+#define BF_PXP_DITHER_CTRL_IDX_MATRIX2_SIZE(v) \
+ (((v) << 21) & BM_PXP_DITHER_CTRL_IDX_MATRIX2_SIZE)
+#define BV_PXP_DITHER_CTRL_IDX_MATRIX2_SIZE__0 0x0
+#define BV_PXP_DITHER_CTRL_IDX_MATRIX2_SIZE__1 0x1
+#define BV_PXP_DITHER_CTRL_IDX_MATRIX2_SIZE__2 0x2
+#define BV_PXP_DITHER_CTRL_IDX_MATRIX2_SIZE__3 0x3
+#define BP_PXP_DITHER_CTRL_IDX_MATRIX1_SIZE 19
+#define BM_PXP_DITHER_CTRL_IDX_MATRIX1_SIZE 0x00180000
+#define BF_PXP_DITHER_CTRL_IDX_MATRIX1_SIZE(v) \
+ (((v) << 19) & BM_PXP_DITHER_CTRL_IDX_MATRIX1_SIZE)
+#define BV_PXP_DITHER_CTRL_IDX_MATRIX1_SIZE__0 0x0
+#define BV_PXP_DITHER_CTRL_IDX_MATRIX1_SIZE__1 0x1
+#define BV_PXP_DITHER_CTRL_IDX_MATRIX1_SIZE__2 0x2
+#define BV_PXP_DITHER_CTRL_IDX_MATRIX1_SIZE__3 0x3
+#define BP_PXP_DITHER_CTRL_IDX_MATRIX0_SIZE 17
+#define BM_PXP_DITHER_CTRL_IDX_MATRIX0_SIZE 0x00060000
+#define BF_PXP_DITHER_CTRL_IDX_MATRIX0_SIZE(v) \
+ (((v) << 17) & BM_PXP_DITHER_CTRL_IDX_MATRIX0_SIZE)
+#define BV_PXP_DITHER_CTRL_IDX_MATRIX0_SIZE__0 0x0
+#define BV_PXP_DITHER_CTRL_IDX_MATRIX0_SIZE__1 0x1
+#define BV_PXP_DITHER_CTRL_IDX_MATRIX0_SIZE__2 0x2
+#define BV_PXP_DITHER_CTRL_IDX_MATRIX0_SIZE__3 0x3
+#define BP_PXP_DITHER_CTRL_LUT_MODE 15
+#define BM_PXP_DITHER_CTRL_LUT_MODE 0x00018000
+#define BF_PXP_DITHER_CTRL_LUT_MODE(v) \
+ (((v) << 15) & BM_PXP_DITHER_CTRL_LUT_MODE)
+#define BV_PXP_DITHER_CTRL_LUT_MODE__0 0x0
+#define BV_PXP_DITHER_CTRL_LUT_MODE__1 0x1
+#define BV_PXP_DITHER_CTRL_LUT_MODE__2 0x2
+#define BV_PXP_DITHER_CTRL_LUT_MODE__3 0x3
+#define BP_PXP_DITHER_CTRL_NUM_QUANT_BIT 12
+#define BM_PXP_DITHER_CTRL_NUM_QUANT_BIT 0x00007000
+#define BF_PXP_DITHER_CTRL_NUM_QUANT_BIT(v) \
+ (((v) << 12) & BM_PXP_DITHER_CTRL_NUM_QUANT_BIT)
+#define BV_PXP_DITHER_CTRL_NUM_QUANT_BIT__0 0x0
+#define BV_PXP_DITHER_CTRL_NUM_QUANT_BIT__1 0x1
+#define BV_PXP_DITHER_CTRL_NUM_QUANT_BIT__2 0x2
+#define BV_PXP_DITHER_CTRL_NUM_QUANT_BIT__3 0x3
+#define BV_PXP_DITHER_CTRL_NUM_QUANT_BIT__4 0x4
+#define BV_PXP_DITHER_CTRL_NUM_QUANT_BIT__5 0x5
+#define BV_PXP_DITHER_CTRL_NUM_QUANT_BIT__6 0x6
+#define BV_PXP_DITHER_CTRL_NUM_QUANT_BIT__7 0x7
+#define BP_PXP_DITHER_CTRL_DITHER_MODE2 9
+#define BM_PXP_DITHER_CTRL_DITHER_MODE2 0x00000E00
+#define BF_PXP_DITHER_CTRL_DITHER_MODE2(v) \
+ (((v) << 9) & BM_PXP_DITHER_CTRL_DITHER_MODE2)
+#define BV_PXP_DITHER_CTRL_DITHER_MODE2__0 0x0
+#define BV_PXP_DITHER_CTRL_DITHER_MODE2__1 0x1
+#define BV_PXP_DITHER_CTRL_DITHER_MODE2__2 0x2
+#define BV_PXP_DITHER_CTRL_DITHER_MODE2__3 0x3
+#define BV_PXP_DITHER_CTRL_DITHER_MODE2__4 0x4
+#define BV_PXP_DITHER_CTRL_DITHER_MODE2__5 0x5
+#define BV_PXP_DITHER_CTRL_DITHER_MODE2__6 0x6
+#define BV_PXP_DITHER_CTRL_DITHER_MODE2__7 0x7
+#define BP_PXP_DITHER_CTRL_DITHER_MODE1 6
+#define BM_PXP_DITHER_CTRL_DITHER_MODE1 0x000001C0
+#define BF_PXP_DITHER_CTRL_DITHER_MODE1(v) \
+ (((v) << 6) & BM_PXP_DITHER_CTRL_DITHER_MODE1)
+#define BV_PXP_DITHER_CTRL_DITHER_MODE1__0 0x0
+#define BV_PXP_DITHER_CTRL_DITHER_MODE1__1 0x1
+#define BV_PXP_DITHER_CTRL_DITHER_MODE1__2 0x2
+#define BV_PXP_DITHER_CTRL_DITHER_MODE1__3 0x3
+#define BV_PXP_DITHER_CTRL_DITHER_MODE1__4 0x4
+#define BV_PXP_DITHER_CTRL_DITHER_MODE1__5 0x5
+#define BV_PXP_DITHER_CTRL_DITHER_MODE1__6 0x6
+#define BV_PXP_DITHER_CTRL_DITHER_MODE1__7 0x7
+#define BP_PXP_DITHER_CTRL_DITHER_MODE0 3
+#define BM_PXP_DITHER_CTRL_DITHER_MODE0 0x00000038
+#define BF_PXP_DITHER_CTRL_DITHER_MODE0(v) \
+ (((v) << 3) & BM_PXP_DITHER_CTRL_DITHER_MODE0)
+#define BV_PXP_DITHER_CTRL_DITHER_MODE0__0 0x0
+#define BV_PXP_DITHER_CTRL_DITHER_MODE0__1 0x1
+#define BV_PXP_DITHER_CTRL_DITHER_MODE0__2 0x2
+#define BV_PXP_DITHER_CTRL_DITHER_MODE0__3 0x3
+#define BV_PXP_DITHER_CTRL_DITHER_MODE0__4 0x4
+#define BV_PXP_DITHER_CTRL_DITHER_MODE0__5 0x5
+#define BV_PXP_DITHER_CTRL_DITHER_MODE0__6 0x6
+#define BV_PXP_DITHER_CTRL_DITHER_MODE0__7 0x7
+#define BM_PXP_DITHER_CTRL_ENABLE2 0x00000004
+#define BF_PXP_DITHER_CTRL_ENABLE2(v) \
+ (((v) << 2) & BM_PXP_DITHER_CTRL_ENABLE2)
+#define BV_PXP_DITHER_CTRL_ENABLE2__Disabled 0x0
+#define BV_PXP_DITHER_CTRL_ENABLE2__Enabled 0x1
+#define BM_PXP_DITHER_CTRL_ENABLE1 0x00000002
+#define BF_PXP_DITHER_CTRL_ENABLE1(v) \
+ (((v) << 1) & BM_PXP_DITHER_CTRL_ENABLE1)
+#define BV_PXP_DITHER_CTRL_ENABLE1__Disabled 0x0
+#define BV_PXP_DITHER_CTRL_ENABLE1__Enabled 0x1
+#define BM_PXP_DITHER_CTRL_ENABLE0 0x00000001
+#define BF_PXP_DITHER_CTRL_ENABLE0(v) \
+ (((v) << 0) & BM_PXP_DITHER_CTRL_ENABLE0)
+#define BV_PXP_DITHER_CTRL_ENABLE0__Disabled 0x0
+#define BV_PXP_DITHER_CTRL_ENABLE0__Enabled 0x1
+
+#define HW_PXP_DITHER_FINAL_LUT_DATA0 (0x00001680)
+#define HW_PXP_DITHER_FINAL_LUT_DATA0_SET (0x00001684)
+#define HW_PXP_DITHER_FINAL_LUT_DATA0_CLR (0x00001688)
+#define HW_PXP_DITHER_FINAL_LUT_DATA0_TOG (0x0000168c)
+
+#define BP_PXP_DITHER_FINAL_LUT_DATA0_DATA3 24
+#define BM_PXP_DITHER_FINAL_LUT_DATA0_DATA3 0xFF000000
+#define BF_PXP_DITHER_FINAL_LUT_DATA0_DATA3(v) \
+ (((v) << 24) & BM_PXP_DITHER_FINAL_LUT_DATA0_DATA3)
+#define BP_PXP_DITHER_FINAL_LUT_DATA0_DATA2 16
+#define BM_PXP_DITHER_FINAL_LUT_DATA0_DATA2 0x00FF0000
+#define BF_PXP_DITHER_FINAL_LUT_DATA0_DATA2(v) \
+ (((v) << 16) & BM_PXP_DITHER_FINAL_LUT_DATA0_DATA2)
+#define BP_PXP_DITHER_FINAL_LUT_DATA0_DATA1 8
+#define BM_PXP_DITHER_FINAL_LUT_DATA0_DATA1 0x0000FF00
+#define BF_PXP_DITHER_FINAL_LUT_DATA0_DATA1(v) \
+ (((v) << 8) & BM_PXP_DITHER_FINAL_LUT_DATA0_DATA1)
+#define BP_PXP_DITHER_FINAL_LUT_DATA0_DATA0 0
+#define BM_PXP_DITHER_FINAL_LUT_DATA0_DATA0 0x000000FF
+#define BF_PXP_DITHER_FINAL_LUT_DATA0_DATA0(v) \
+ (((v) << 0) & BM_PXP_DITHER_FINAL_LUT_DATA0_DATA0)
+
+#define HW_PXP_DITHER_FINAL_LUT_DATA1 (0x00001690)
+#define HW_PXP_DITHER_FINAL_LUT_DATA1_SET (0x00001694)
+#define HW_PXP_DITHER_FINAL_LUT_DATA1_CLR (0x00001698)
+#define HW_PXP_DITHER_FINAL_LUT_DATA1_TOG (0x0000169c)
+
+#define BP_PXP_DITHER_FINAL_LUT_DATA1_DATA7 24
+#define BM_PXP_DITHER_FINAL_LUT_DATA1_DATA7 0xFF000000
+#define BF_PXP_DITHER_FINAL_LUT_DATA1_DATA7(v) \
+ (((v) << 24) & BM_PXP_DITHER_FINAL_LUT_DATA1_DATA7)
+#define BP_PXP_DITHER_FINAL_LUT_DATA1_DATA6 16
+#define BM_PXP_DITHER_FINAL_LUT_DATA1_DATA6 0x00FF0000
+#define BF_PXP_DITHER_FINAL_LUT_DATA1_DATA6(v) \
+ (((v) << 16) & BM_PXP_DITHER_FINAL_LUT_DATA1_DATA6)
+#define BP_PXP_DITHER_FINAL_LUT_DATA1_DATA5 8
+#define BM_PXP_DITHER_FINAL_LUT_DATA1_DATA5 0x0000FF00
+#define BF_PXP_DITHER_FINAL_LUT_DATA1_DATA5(v) \
+ (((v) << 8) & BM_PXP_DITHER_FINAL_LUT_DATA1_DATA5)
+#define BP_PXP_DITHER_FINAL_LUT_DATA1_DATA4 0
+#define BM_PXP_DITHER_FINAL_LUT_DATA1_DATA4 0x000000FF
+#define BF_PXP_DITHER_FINAL_LUT_DATA1_DATA4(v) \
+ (((v) << 0) & BM_PXP_DITHER_FINAL_LUT_DATA1_DATA4)
+
+#define HW_PXP_DITHER_FINAL_LUT_DATA2 (0x000016a0)
+#define HW_PXP_DITHER_FINAL_LUT_DATA2_SET (0x000016a4)
+#define HW_PXP_DITHER_FINAL_LUT_DATA2_CLR (0x000016a8)
+#define HW_PXP_DITHER_FINAL_LUT_DATA2_TOG (0x000016ac)
+
+#define BP_PXP_DITHER_FINAL_LUT_DATA2_DATA11 24
+#define BM_PXP_DITHER_FINAL_LUT_DATA2_DATA11 0xFF000000
+#define BF_PXP_DITHER_FINAL_LUT_DATA2_DATA11(v) \
+ (((v) << 24) & BM_PXP_DITHER_FINAL_LUT_DATA2_DATA11)
+#define BP_PXP_DITHER_FINAL_LUT_DATA2_DATA10 16
+#define BM_PXP_DITHER_FINAL_LUT_DATA2_DATA10 0x00FF0000
+#define BF_PXP_DITHER_FINAL_LUT_DATA2_DATA10(v) \
+ (((v) << 16) & BM_PXP_DITHER_FINAL_LUT_DATA2_DATA10)
+#define BP_PXP_DITHER_FINAL_LUT_DATA2_DATA9 8
+#define BM_PXP_DITHER_FINAL_LUT_DATA2_DATA9 0x0000FF00
+#define BF_PXP_DITHER_FINAL_LUT_DATA2_DATA9(v) \
+ (((v) << 8) & BM_PXP_DITHER_FINAL_LUT_DATA2_DATA9)
+#define BP_PXP_DITHER_FINAL_LUT_DATA2_DATA8 0
+#define BM_PXP_DITHER_FINAL_LUT_DATA2_DATA8 0x000000FF
+#define BF_PXP_DITHER_FINAL_LUT_DATA2_DATA8(v) \
+ (((v) << 0) & BM_PXP_DITHER_FINAL_LUT_DATA2_DATA8)
+
+#define HW_PXP_DITHER_FINAL_LUT_DATA3 (0x000016b0)
+#define HW_PXP_DITHER_FINAL_LUT_DATA3_SET (0x000016b4)
+#define HW_PXP_DITHER_FINAL_LUT_DATA3_CLR (0x000016b8)
+#define HW_PXP_DITHER_FINAL_LUT_DATA3_TOG (0x000016bc)
+
+#define BP_PXP_DITHER_FINAL_LUT_DATA3_DATA15 24
+#define BM_PXP_DITHER_FINAL_LUT_DATA3_DATA15 0xFF000000
+#define BF_PXP_DITHER_FINAL_LUT_DATA3_DATA15(v) \
+ (((v) << 24) & BM_PXP_DITHER_FINAL_LUT_DATA3_DATA15)
+#define BP_PXP_DITHER_FINAL_LUT_DATA3_DATA14 16
+#define BM_PXP_DITHER_FINAL_LUT_DATA3_DATA14 0x00FF0000
+#define BF_PXP_DITHER_FINAL_LUT_DATA3_DATA14(v) \
+ (((v) << 16) & BM_PXP_DITHER_FINAL_LUT_DATA3_DATA14)
+#define BP_PXP_DITHER_FINAL_LUT_DATA3_DATA13 8
+#define BM_PXP_DITHER_FINAL_LUT_DATA3_DATA13 0x0000FF00
+#define BF_PXP_DITHER_FINAL_LUT_DATA3_DATA13(v) \
+ (((v) << 8) & BM_PXP_DITHER_FINAL_LUT_DATA3_DATA13)
+#define BP_PXP_DITHER_FINAL_LUT_DATA3_DATA12 0
+#define BM_PXP_DITHER_FINAL_LUT_DATA3_DATA12 0x000000FF
+#define BF_PXP_DITHER_FINAL_LUT_DATA3_DATA12(v) \
+ (((v) << 0) & BM_PXP_DITHER_FINAL_LUT_DATA3_DATA12)
+
+#define HW_PXP_WFE_A_CTRL (0x000016c0)
+#define HW_PXP_WFE_A_CTRL_SET (0x000016c4)
+#define HW_PXP_WFE_A_CTRL_CLR (0x000016c8)
+#define HW_PXP_WFE_A_CTRL_TOG (0x000016cc)
+
+#define BM_PXP_WFE_A_CTRL_DONE 0x80000000
+#define BF_PXP_WFE_A_CTRL_DONE(v) \
+ (((v) << 31) & BM_PXP_WFE_A_CTRL_DONE)
+#define BP_PXP_WFE_A_CTRL_RSVD0 3
+#define BM_PXP_WFE_A_CTRL_RSVD0 0x7FFFFFF8
+#define BF_PXP_WFE_A_CTRL_RSVD0(v) \
+ (((v) << 3) & BM_PXP_WFE_A_CTRL_RSVD0)
+#define BM_PXP_WFE_A_CTRL_SW_RESET 0x00000004
+#define BF_PXP_WFE_A_CTRL_SW_RESET(v) \
+ (((v) << 2) & BM_PXP_WFE_A_CTRL_SW_RESET)
+#define BM_PXP_WFE_A_CTRL_RSVD1 0x00000002
+#define BF_PXP_WFE_A_CTRL_RSVD1(v) \
+ (((v) << 1) & BM_PXP_WFE_A_CTRL_RSVD1)
+#define BM_PXP_WFE_A_CTRL_ENABLE 0x00000001
+#define BF_PXP_WFE_A_CTRL_ENABLE(v) \
+ (((v) << 0) & BM_PXP_WFE_A_CTRL_ENABLE)
+#define BV_PXP_WFE_A_CTRL_ENABLE__0 0x0
+#define BV_PXP_WFE_A_CTRL_ENABLE__1 0x1
+
+#define HW_PXP_WFE_A_DIMENSIONS (0x000016d0)
+
+#define BP_PXP_WFE_A_DIMENSIONS_RSVD0 28
+#define BM_PXP_WFE_A_DIMENSIONS_RSVD0 0xF0000000
+#define BF_PXP_WFE_A_DIMENSIONS_RSVD0(v) \
+ (((v) << 28) & BM_PXP_WFE_A_DIMENSIONS_RSVD0)
+#define BP_PXP_WFE_A_DIMENSIONS_HEIGHT 16
+#define BM_PXP_WFE_A_DIMENSIONS_HEIGHT 0x0FFF0000
+#define BF_PXP_WFE_A_DIMENSIONS_HEIGHT(v) \
+ (((v) << 16) & BM_PXP_WFE_A_DIMENSIONS_HEIGHT)
+#define BP_PXP_WFE_A_DIMENSIONS_RSVD1 12
+#define BM_PXP_WFE_A_DIMENSIONS_RSVD1 0x0000F000
+#define BF_PXP_WFE_A_DIMENSIONS_RSVD1(v) \
+ (((v) << 12) & BM_PXP_WFE_A_DIMENSIONS_RSVD1)
+#define BP_PXP_WFE_A_DIMENSIONS_WIDTH 0
+#define BM_PXP_WFE_A_DIMENSIONS_WIDTH 0x00000FFF
+#define BF_PXP_WFE_A_DIMENSIONS_WIDTH(v) \
+ (((v) << 0) & BM_PXP_WFE_A_DIMENSIONS_WIDTH)
+
+#define HW_PXP_WFE_A_OFFSET (0x000016e0)
+
+#define BP_PXP_WFE_A_OFFSET_RSVD0 28
+#define BM_PXP_WFE_A_OFFSET_RSVD0 0xF0000000
+#define BF_PXP_WFE_A_OFFSET_RSVD0(v) \
+ (((v) << 28) & BM_PXP_WFE_A_OFFSET_RSVD0)
+#define BP_PXP_WFE_A_OFFSET_Y_OFFSET 16
+#define BM_PXP_WFE_A_OFFSET_Y_OFFSET 0x0FFF0000
+#define BF_PXP_WFE_A_OFFSET_Y_OFFSET(v) \
+ (((v) << 16) & BM_PXP_WFE_A_OFFSET_Y_OFFSET)
+#define BP_PXP_WFE_A_OFFSET_RSVD1 12
+#define BM_PXP_WFE_A_OFFSET_RSVD1 0x0000F000
+#define BF_PXP_WFE_A_OFFSET_RSVD1(v) \
+ (((v) << 12) & BM_PXP_WFE_A_OFFSET_RSVD1)
+#define BP_PXP_WFE_A_OFFSET_X_OFFSET 0
+#define BM_PXP_WFE_A_OFFSET_X_OFFSET 0x00000FFF
+#define BF_PXP_WFE_A_OFFSET_X_OFFSET(v) \
+ (((v) << 0) & BM_PXP_WFE_A_OFFSET_X_OFFSET)
+
+#define HW_PXP_WFE_A_SW_DATA_REGS (0x000016f0)
+
+#define BP_PXP_WFE_A_SW_DATA_REGS_VAL3 24
+#define BM_PXP_WFE_A_SW_DATA_REGS_VAL3 0xFF000000
+#define BF_PXP_WFE_A_SW_DATA_REGS_VAL3(v) \
+ (((v) << 24) & BM_PXP_WFE_A_SW_DATA_REGS_VAL3)
+#define BP_PXP_WFE_A_SW_DATA_REGS_VAL2 16
+#define BM_PXP_WFE_A_SW_DATA_REGS_VAL2 0x00FF0000
+#define BF_PXP_WFE_A_SW_DATA_REGS_VAL2(v) \
+ (((v) << 16) & BM_PXP_WFE_A_SW_DATA_REGS_VAL2)
+#define BP_PXP_WFE_A_SW_DATA_REGS_VAL1 8
+#define BM_PXP_WFE_A_SW_DATA_REGS_VAL1 0x0000FF00
+#define BF_PXP_WFE_A_SW_DATA_REGS_VAL1(v) \
+ (((v) << 8) & BM_PXP_WFE_A_SW_DATA_REGS_VAL1)
+#define BP_PXP_WFE_A_SW_DATA_REGS_VAL0 0
+#define BM_PXP_WFE_A_SW_DATA_REGS_VAL0 0x000000FF
+#define BF_PXP_WFE_A_SW_DATA_REGS_VAL0(v) \
+ (((v) << 0) & BM_PXP_WFE_A_SW_DATA_REGS_VAL0)
+
+#define HW_PXP_WFE_A_SW_FLAG_REGS (0x00001700)
+
+#define BP_PXP_WFE_A_SW_FLAG_REGS_RSVD 4
+#define BM_PXP_WFE_A_SW_FLAG_REGS_RSVD 0xFFFFFFF0
+#define BF_PXP_WFE_A_SW_FLAG_REGS_RSVD(v) \
+ (((v) << 4) & BM_PXP_WFE_A_SW_FLAG_REGS_RSVD)
+#define BM_PXP_WFE_A_SW_FLAG_REGS_VAL3 0x00000008
+#define BF_PXP_WFE_A_SW_FLAG_REGS_VAL3(v) \
+ (((v) << 3) & BM_PXP_WFE_A_SW_FLAG_REGS_VAL3)
+#define BM_PXP_WFE_A_SW_FLAG_REGS_VAL2 0x00000004
+#define BF_PXP_WFE_A_SW_FLAG_REGS_VAL2(v) \
+ (((v) << 2) & BM_PXP_WFE_A_SW_FLAG_REGS_VAL2)
+#define BM_PXP_WFE_A_SW_FLAG_REGS_VAL1 0x00000002
+#define BF_PXP_WFE_A_SW_FLAG_REGS_VAL1(v) \
+ (((v) << 1) & BM_PXP_WFE_A_SW_FLAG_REGS_VAL1)
+#define BM_PXP_WFE_A_SW_FLAG_REGS_VAL0 0x00000001
+#define BF_PXP_WFE_A_SW_FLAG_REGS_VAL0(v) \
+ (((v) << 0) & BM_PXP_WFE_A_SW_FLAG_REGS_VAL0)
+
+#define HW_PXP_WFE_A_STAGE1_MUX0 (0x00001710)
+#define HW_PXP_WFE_A_STAGE1_MUX0_SET (0x00001714)
+#define HW_PXP_WFE_A_STAGE1_MUX0_CLR (0x00001718)
+#define HW_PXP_WFE_A_STAGE1_MUX0_TOG (0x0000171c)
+
+#define BP_PXP_WFE_A_STAGE1_MUX0_RSVD0 30
+#define BM_PXP_WFE_A_STAGE1_MUX0_RSVD0 0xC0000000
+#define BF_PXP_WFE_A_STAGE1_MUX0_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFE_A_STAGE1_MUX0_RSVD0)
+#define BP_PXP_WFE_A_STAGE1_MUX0_MUX3 24
+#define BM_PXP_WFE_A_STAGE1_MUX0_MUX3 0x3F000000
+#define BF_PXP_WFE_A_STAGE1_MUX0_MUX3(v) \
+ (((v) << 24) & BM_PXP_WFE_A_STAGE1_MUX0_MUX3)
+#define BP_PXP_WFE_A_STAGE1_MUX0_RSVD1 22
+#define BM_PXP_WFE_A_STAGE1_MUX0_RSVD1 0x00C00000
+#define BF_PXP_WFE_A_STAGE1_MUX0_RSVD1(v) \
+ (((v) << 22) & BM_PXP_WFE_A_STAGE1_MUX0_RSVD1)
+#define BP_PXP_WFE_A_STAGE1_MUX0_MUX2 16
+#define BM_PXP_WFE_A_STAGE1_MUX0_MUX2 0x003F0000
+#define BF_PXP_WFE_A_STAGE1_MUX0_MUX2(v) \
+ (((v) << 16) & BM_PXP_WFE_A_STAGE1_MUX0_MUX2)
+#define BP_PXP_WFE_A_STAGE1_MUX0_RSVD2 14
+#define BM_PXP_WFE_A_STAGE1_MUX0_RSVD2 0x0000C000
+#define BF_PXP_WFE_A_STAGE1_MUX0_RSVD2(v) \
+ (((v) << 14) & BM_PXP_WFE_A_STAGE1_MUX0_RSVD2)
+#define BP_PXP_WFE_A_STAGE1_MUX0_MUX1 8
+#define BM_PXP_WFE_A_STAGE1_MUX0_MUX1 0x00003F00
+#define BF_PXP_WFE_A_STAGE1_MUX0_MUX1(v) \
+ (((v) << 8) & BM_PXP_WFE_A_STAGE1_MUX0_MUX1)
+#define BP_PXP_WFE_A_STAGE1_MUX0_RSVD3 6
+#define BM_PXP_WFE_A_STAGE1_MUX0_RSVD3 0x000000C0
+#define BF_PXP_WFE_A_STAGE1_MUX0_RSVD3(v) \
+ (((v) << 6) & BM_PXP_WFE_A_STAGE1_MUX0_RSVD3)
+#define BP_PXP_WFE_A_STAGE1_MUX0_MUX0 0
+#define BM_PXP_WFE_A_STAGE1_MUX0_MUX0 0x0000003F
+#define BF_PXP_WFE_A_STAGE1_MUX0_MUX0(v) \
+ (((v) << 0) & BM_PXP_WFE_A_STAGE1_MUX0_MUX0)
+
+#define HW_PXP_WFE_A_STAGE1_MUX1 (0x00001720)
+#define HW_PXP_WFE_A_STAGE1_MUX1_SET (0x00001724)
+#define HW_PXP_WFE_A_STAGE1_MUX1_CLR (0x00001728)
+#define HW_PXP_WFE_A_STAGE1_MUX1_TOG (0x0000172c)
+
+#define BP_PXP_WFE_A_STAGE1_MUX1_RSVD0 30
+#define BM_PXP_WFE_A_STAGE1_MUX1_RSVD0 0xC0000000
+#define BF_PXP_WFE_A_STAGE1_MUX1_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFE_A_STAGE1_MUX1_RSVD0)
+#define BP_PXP_WFE_A_STAGE1_MUX1_MUX7 24
+#define BM_PXP_WFE_A_STAGE1_MUX1_MUX7 0x3F000000
+#define BF_PXP_WFE_A_STAGE1_MUX1_MUX7(v) \
+ (((v) << 24) & BM_PXP_WFE_A_STAGE1_MUX1_MUX7)
+#define BV_PXP_WFE_A_STAGE1_MUX1_MUX7__INC 0x0
+#define BV_PXP_WFE_A_STAGE1_MUX1_MUX7__DEC 0x1
+#define BV_PXP_WFE_A_STAGE1_MUX1_MUX7__ADD 0x2
+#define BV_PXP_WFE_A_STAGE1_MUX1_MUX7__MINUS 0x3
+#define BV_PXP_WFE_A_STAGE1_MUX1_MUX7__AND 0x4
+#define BV_PXP_WFE_A_STAGE1_MUX1_MUX7__OR 0x5
+#define BV_PXP_WFE_A_STAGE1_MUX1_MUX7__XOR 0x6
+#define BV_PXP_WFE_A_STAGE1_MUX1_MUX7__SHIFTLEFT 0x7
+#define BV_PXP_WFE_A_STAGE1_MUX1_MUX7__SHIFTRIGHT 0x8
+#define BV_PXP_WFE_A_STAGE1_MUX1_MUX7__BIT_AND 0x9
+#define BV_PXP_WFE_A_STAGE1_MUX1_MUX7__BIT_OR 0xa
+#define BV_PXP_WFE_A_STAGE1_MUX1_MUX7__BIT_CMP 0xb
+#define BV_PXP_WFE_A_STAGE1_MUX1_MUX7__NOP 0xc
+#define BP_PXP_WFE_A_STAGE1_MUX1_RSVD1 22
+#define BM_PXP_WFE_A_STAGE1_MUX1_RSVD1 0x00C00000
+#define BF_PXP_WFE_A_STAGE1_MUX1_RSVD1(v) \
+ (((v) << 22) & BM_PXP_WFE_A_STAGE1_MUX1_RSVD1)
+#define BP_PXP_WFE_A_STAGE1_MUX1_MUX6 16
+#define BM_PXP_WFE_A_STAGE1_MUX1_MUX6 0x003F0000
+#define BF_PXP_WFE_A_STAGE1_MUX1_MUX6(v) \
+ (((v) << 16) & BM_PXP_WFE_A_STAGE1_MUX1_MUX6)
+#define BP_PXP_WFE_A_STAGE1_MUX1_RSVD2 14
+#define BM_PXP_WFE_A_STAGE1_MUX1_RSVD2 0x0000C000
+#define BF_PXP_WFE_A_STAGE1_MUX1_RSVD2(v) \
+ (((v) << 14) & BM_PXP_WFE_A_STAGE1_MUX1_RSVD2)
+#define BP_PXP_WFE_A_STAGE1_MUX1_MUX5 8
+#define BM_PXP_WFE_A_STAGE1_MUX1_MUX5 0x00003F00
+#define BF_PXP_WFE_A_STAGE1_MUX1_MUX5(v) \
+ (((v) << 8) & BM_PXP_WFE_A_STAGE1_MUX1_MUX5)
+#define BP_PXP_WFE_A_STAGE1_MUX1_RSVD3 6
+#define BM_PXP_WFE_A_STAGE1_MUX1_RSVD3 0x000000C0
+#define BF_PXP_WFE_A_STAGE1_MUX1_RSVD3(v) \
+ (((v) << 6) & BM_PXP_WFE_A_STAGE1_MUX1_RSVD3)
+#define BP_PXP_WFE_A_STAGE1_MUX1_MUX4 0
+#define BM_PXP_WFE_A_STAGE1_MUX1_MUX4 0x0000003F
+#define BF_PXP_WFE_A_STAGE1_MUX1_MUX4(v) \
+ (((v) << 0) & BM_PXP_WFE_A_STAGE1_MUX1_MUX4)
+#define BV_PXP_WFE_A_STAGE1_MUX1_MUX4__INC 0x0
+#define BV_PXP_WFE_A_STAGE1_MUX1_MUX4__DEC 0x1
+#define BV_PXP_WFE_A_STAGE1_MUX1_MUX4__ADD 0x2
+#define BV_PXP_WFE_A_STAGE1_MUX1_MUX4__MINUS 0x3
+#define BV_PXP_WFE_A_STAGE1_MUX1_MUX4__AND 0x4
+#define BV_PXP_WFE_A_STAGE1_MUX1_MUX4__OR 0x5
+#define BV_PXP_WFE_A_STAGE1_MUX1_MUX4__XOR 0x6
+#define BV_PXP_WFE_A_STAGE1_MUX1_MUX4__SHIFTLEFT 0x7
+#define BV_PXP_WFE_A_STAGE1_MUX1_MUX4__SHIFTRIGHT 0x8
+#define BV_PXP_WFE_A_STAGE1_MUX1_MUX4__BIT_AND 0x9
+#define BV_PXP_WFE_A_STAGE1_MUX1_MUX4__BIT_OR 0xa
+#define BV_PXP_WFE_A_STAGE1_MUX1_MUX4__BIT_CMP 0xb
+#define BV_PXP_WFE_A_STAGE1_MUX1_MUX4__NOP 0xc
+
+#define HW_PXP_WFE_A_STAGE1_MUX2 (0x00001730)
+#define HW_PXP_WFE_A_STAGE1_MUX2_SET (0x00001734)
+#define HW_PXP_WFE_A_STAGE1_MUX2_CLR (0x00001738)
+#define HW_PXP_WFE_A_STAGE1_MUX2_TOG (0x0000173c)
+
+#define BP_PXP_WFE_A_STAGE1_MUX2_RSVD0 30
+#define BM_PXP_WFE_A_STAGE1_MUX2_RSVD0 0xC0000000
+#define BF_PXP_WFE_A_STAGE1_MUX2_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFE_A_STAGE1_MUX2_RSVD0)
+#define BP_PXP_WFE_A_STAGE1_MUX2_MUX11 24
+#define BM_PXP_WFE_A_STAGE1_MUX2_MUX11 0x3F000000
+#define BF_PXP_WFE_A_STAGE1_MUX2_MUX11(v) \
+ (((v) << 24) & BM_PXP_WFE_A_STAGE1_MUX2_MUX11)
+#define BP_PXP_WFE_A_STAGE1_MUX2_RSVD1 22
+#define BM_PXP_WFE_A_STAGE1_MUX2_RSVD1 0x00C00000
+#define BF_PXP_WFE_A_STAGE1_MUX2_RSVD1(v) \
+ (((v) << 22) & BM_PXP_WFE_A_STAGE1_MUX2_RSVD1)
+#define BP_PXP_WFE_A_STAGE1_MUX2_MUX10 16
+#define BM_PXP_WFE_A_STAGE1_MUX2_MUX10 0x003F0000
+#define BF_PXP_WFE_A_STAGE1_MUX2_MUX10(v) \
+ (((v) << 16) & BM_PXP_WFE_A_STAGE1_MUX2_MUX10)
+#define BP_PXP_WFE_A_STAGE1_MUX2_RSVD2 14
+#define BM_PXP_WFE_A_STAGE1_MUX2_RSVD2 0x0000C000
+#define BF_PXP_WFE_A_STAGE1_MUX2_RSVD2(v) \
+ (((v) << 14) & BM_PXP_WFE_A_STAGE1_MUX2_RSVD2)
+#define BP_PXP_WFE_A_STAGE1_MUX2_MUX9 8
+#define BM_PXP_WFE_A_STAGE1_MUX2_MUX9 0x00003F00
+#define BF_PXP_WFE_A_STAGE1_MUX2_MUX9(v) \
+ (((v) << 8) & BM_PXP_WFE_A_STAGE1_MUX2_MUX9)
+#define BP_PXP_WFE_A_STAGE1_MUX2_RSVD3 6
+#define BM_PXP_WFE_A_STAGE1_MUX2_RSVD3 0x000000C0
+#define BF_PXP_WFE_A_STAGE1_MUX2_RSVD3(v) \
+ (((v) << 6) & BM_PXP_WFE_A_STAGE1_MUX2_RSVD3)
+#define BP_PXP_WFE_A_STAGE1_MUX2_MUX8 0
+#define BM_PXP_WFE_A_STAGE1_MUX2_MUX8 0x0000003F
+#define BF_PXP_WFE_A_STAGE1_MUX2_MUX8(v) \
+ (((v) << 0) & BM_PXP_WFE_A_STAGE1_MUX2_MUX8)
+
+#define HW_PXP_WFE_A_STAGE1_MUX3 (0x00001740)
+#define HW_PXP_WFE_A_STAGE1_MUX3_SET (0x00001744)
+#define HW_PXP_WFE_A_STAGE1_MUX3_CLR (0x00001748)
+#define HW_PXP_WFE_A_STAGE1_MUX3_TOG (0x0000174c)
+
+#define BP_PXP_WFE_A_STAGE1_MUX3_RSVD0 30
+#define BM_PXP_WFE_A_STAGE1_MUX3_RSVD0 0xC0000000
+#define BF_PXP_WFE_A_STAGE1_MUX3_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFE_A_STAGE1_MUX3_RSVD0)
+#define BP_PXP_WFE_A_STAGE1_MUX3_MUX15 24
+#define BM_PXP_WFE_A_STAGE1_MUX3_MUX15 0x3F000000
+#define BF_PXP_WFE_A_STAGE1_MUX3_MUX15(v) \
+ (((v) << 24) & BM_PXP_WFE_A_STAGE1_MUX3_MUX15)
+#define BP_PXP_WFE_A_STAGE1_MUX3_RSVD1 22
+#define BM_PXP_WFE_A_STAGE1_MUX3_RSVD1 0x00C00000
+#define BF_PXP_WFE_A_STAGE1_MUX3_RSVD1(v) \
+ (((v) << 22) & BM_PXP_WFE_A_STAGE1_MUX3_RSVD1)
+#define BP_PXP_WFE_A_STAGE1_MUX3_MUX14 16
+#define BM_PXP_WFE_A_STAGE1_MUX3_MUX14 0x003F0000
+#define BF_PXP_WFE_A_STAGE1_MUX3_MUX14(v) \
+ (((v) << 16) & BM_PXP_WFE_A_STAGE1_MUX3_MUX14)
+#define BP_PXP_WFE_A_STAGE1_MUX3_RSVD2 14
+#define BM_PXP_WFE_A_STAGE1_MUX3_RSVD2 0x0000C000
+#define BF_PXP_WFE_A_STAGE1_MUX3_RSVD2(v) \
+ (((v) << 14) & BM_PXP_WFE_A_STAGE1_MUX3_RSVD2)
+#define BP_PXP_WFE_A_STAGE1_MUX3_MUX13 8
+#define BM_PXP_WFE_A_STAGE1_MUX3_MUX13 0x00003F00
+#define BF_PXP_WFE_A_STAGE1_MUX3_MUX13(v) \
+ (((v) << 8) & BM_PXP_WFE_A_STAGE1_MUX3_MUX13)
+#define BP_PXP_WFE_A_STAGE1_MUX3_RSVD3 6
+#define BM_PXP_WFE_A_STAGE1_MUX3_RSVD3 0x000000C0
+#define BF_PXP_WFE_A_STAGE1_MUX3_RSVD3(v) \
+ (((v) << 6) & BM_PXP_WFE_A_STAGE1_MUX3_RSVD3)
+#define BP_PXP_WFE_A_STAGE1_MUX3_MUX12 0
+#define BM_PXP_WFE_A_STAGE1_MUX3_MUX12 0x0000003F
+#define BF_PXP_WFE_A_STAGE1_MUX3_MUX12(v) \
+ (((v) << 0) & BM_PXP_WFE_A_STAGE1_MUX3_MUX12)
+
+#define HW_PXP_WFE_A_STAGE1_MUX4 (0x00001750)
+#define HW_PXP_WFE_A_STAGE1_MUX4_SET (0x00001754)
+#define HW_PXP_WFE_A_STAGE1_MUX4_CLR (0x00001758)
+#define HW_PXP_WFE_A_STAGE1_MUX4_TOG (0x0000175c)
+
+#define BP_PXP_WFE_A_STAGE1_MUX4_RSVD0 24
+#define BM_PXP_WFE_A_STAGE1_MUX4_RSVD0 0xFF000000
+#define BF_PXP_WFE_A_STAGE1_MUX4_RSVD0(v) \
+ (((v) << 24) & BM_PXP_WFE_A_STAGE1_MUX4_RSVD0)
+#define BP_PXP_WFE_A_STAGE1_MUX4_RSVD1 16
+#define BM_PXP_WFE_A_STAGE1_MUX4_RSVD1 0x00FF0000
+#define BF_PXP_WFE_A_STAGE1_MUX4_RSVD1(v) \
+ (((v) << 16) & BM_PXP_WFE_A_STAGE1_MUX4_RSVD1)
+#define BP_PXP_WFE_A_STAGE1_MUX4_RSVD2 14
+#define BM_PXP_WFE_A_STAGE1_MUX4_RSVD2 0x0000C000
+#define BF_PXP_WFE_A_STAGE1_MUX4_RSVD2(v) \
+ (((v) << 14) & BM_PXP_WFE_A_STAGE1_MUX4_RSVD2)
+#define BP_PXP_WFE_A_STAGE1_MUX4_MUX17 8
+#define BM_PXP_WFE_A_STAGE1_MUX4_MUX17 0x00003F00
+#define BF_PXP_WFE_A_STAGE1_MUX4_MUX17(v) \
+ (((v) << 8) & BM_PXP_WFE_A_STAGE1_MUX4_MUX17)
+#define BP_PXP_WFE_A_STAGE1_MUX4_RSVD3 6
+#define BM_PXP_WFE_A_STAGE1_MUX4_RSVD3 0x000000C0
+#define BF_PXP_WFE_A_STAGE1_MUX4_RSVD3(v) \
+ (((v) << 6) & BM_PXP_WFE_A_STAGE1_MUX4_RSVD3)
+#define BP_PXP_WFE_A_STAGE1_MUX4_MUX16 0
+#define BM_PXP_WFE_A_STAGE1_MUX4_MUX16 0x0000003F
+#define BF_PXP_WFE_A_STAGE1_MUX4_MUX16(v) \
+ (((v) << 0) & BM_PXP_WFE_A_STAGE1_MUX4_MUX16)
+
+#define HW_PXP_WFE_A_STAGE2_MUX0 (0x00001760)
+#define HW_PXP_WFE_A_STAGE2_MUX0_SET (0x00001764)
+#define HW_PXP_WFE_A_STAGE2_MUX0_CLR (0x00001768)
+#define HW_PXP_WFE_A_STAGE2_MUX0_TOG (0x0000176c)
+
+#define BP_PXP_WFE_A_STAGE2_MUX0_RSVD0 30
+#define BM_PXP_WFE_A_STAGE2_MUX0_RSVD0 0xC0000000
+#define BF_PXP_WFE_A_STAGE2_MUX0_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFE_A_STAGE2_MUX0_RSVD0)
+#define BP_PXP_WFE_A_STAGE2_MUX0_MUX3 24
+#define BM_PXP_WFE_A_STAGE2_MUX0_MUX3 0x3F000000
+#define BF_PXP_WFE_A_STAGE2_MUX0_MUX3(v) \
+ (((v) << 24) & BM_PXP_WFE_A_STAGE2_MUX0_MUX3)
+#define BP_PXP_WFE_A_STAGE2_MUX0_RSVD1 22
+#define BM_PXP_WFE_A_STAGE2_MUX0_RSVD1 0x00C00000
+#define BF_PXP_WFE_A_STAGE2_MUX0_RSVD1(v) \
+ (((v) << 22) & BM_PXP_WFE_A_STAGE2_MUX0_RSVD1)
+#define BP_PXP_WFE_A_STAGE2_MUX0_MUX2 16
+#define BM_PXP_WFE_A_STAGE2_MUX0_MUX2 0x003F0000
+#define BF_PXP_WFE_A_STAGE2_MUX0_MUX2(v) \
+ (((v) << 16) & BM_PXP_WFE_A_STAGE2_MUX0_MUX2)
+#define BP_PXP_WFE_A_STAGE2_MUX0_RSVD2 14
+#define BM_PXP_WFE_A_STAGE2_MUX0_RSVD2 0x0000C000
+#define BF_PXP_WFE_A_STAGE2_MUX0_RSVD2(v) \
+ (((v) << 14) & BM_PXP_WFE_A_STAGE2_MUX0_RSVD2)
+#define BP_PXP_WFE_A_STAGE2_MUX0_MUX1 8
+#define BM_PXP_WFE_A_STAGE2_MUX0_MUX1 0x00003F00
+#define BF_PXP_WFE_A_STAGE2_MUX0_MUX1(v) \
+ (((v) << 8) & BM_PXP_WFE_A_STAGE2_MUX0_MUX1)
+#define BP_PXP_WFE_A_STAGE2_MUX0_RSVD3 6
+#define BM_PXP_WFE_A_STAGE2_MUX0_RSVD3 0x000000C0
+#define BF_PXP_WFE_A_STAGE2_MUX0_RSVD3(v) \
+ (((v) << 6) & BM_PXP_WFE_A_STAGE2_MUX0_RSVD3)
+#define BP_PXP_WFE_A_STAGE2_MUX0_MUX0 0
+#define BM_PXP_WFE_A_STAGE2_MUX0_MUX0 0x0000003F
+#define BF_PXP_WFE_A_STAGE2_MUX0_MUX0(v) \
+ (((v) << 0) & BM_PXP_WFE_A_STAGE2_MUX0_MUX0)
+
+#define HW_PXP_WFE_A_STAGE2_MUX1 (0x00001770)
+#define HW_PXP_WFE_A_STAGE2_MUX1_SET (0x00001774)
+#define HW_PXP_WFE_A_STAGE2_MUX1_CLR (0x00001778)
+#define HW_PXP_WFE_A_STAGE2_MUX1_TOG (0x0000177c)
+
+#define BP_PXP_WFE_A_STAGE2_MUX1_RSVD0 30
+#define BM_PXP_WFE_A_STAGE2_MUX1_RSVD0 0xC0000000
+#define BF_PXP_WFE_A_STAGE2_MUX1_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFE_A_STAGE2_MUX1_RSVD0)
+#define BP_PXP_WFE_A_STAGE2_MUX1_MUX7 24
+#define BM_PXP_WFE_A_STAGE2_MUX1_MUX7 0x3F000000
+#define BF_PXP_WFE_A_STAGE2_MUX1_MUX7(v) \
+ (((v) << 24) & BM_PXP_WFE_A_STAGE2_MUX1_MUX7)
+#define BP_PXP_WFE_A_STAGE2_MUX1_RSVD1 22
+#define BM_PXP_WFE_A_STAGE2_MUX1_RSVD1 0x00C00000
+#define BF_PXP_WFE_A_STAGE2_MUX1_RSVD1(v) \
+ (((v) << 22) & BM_PXP_WFE_A_STAGE2_MUX1_RSVD1)
+#define BP_PXP_WFE_A_STAGE2_MUX1_MUX6 16
+#define BM_PXP_WFE_A_STAGE2_MUX1_MUX6 0x003F0000
+#define BF_PXP_WFE_A_STAGE2_MUX1_MUX6(v) \
+ (((v) << 16) & BM_PXP_WFE_A_STAGE2_MUX1_MUX6)
+#define BP_PXP_WFE_A_STAGE2_MUX1_RSVD2 14
+#define BM_PXP_WFE_A_STAGE2_MUX1_RSVD2 0x0000C000
+#define BF_PXP_WFE_A_STAGE2_MUX1_RSVD2(v) \
+ (((v) << 14) & BM_PXP_WFE_A_STAGE2_MUX1_RSVD2)
+#define BP_PXP_WFE_A_STAGE2_MUX1_MUX5 8
+#define BM_PXP_WFE_A_STAGE2_MUX1_MUX5 0x00003F00
+#define BF_PXP_WFE_A_STAGE2_MUX1_MUX5(v) \
+ (((v) << 8) & BM_PXP_WFE_A_STAGE2_MUX1_MUX5)
+#define BP_PXP_WFE_A_STAGE2_MUX1_RSVD3 6
+#define BM_PXP_WFE_A_STAGE2_MUX1_RSVD3 0x000000C0
+#define BF_PXP_WFE_A_STAGE2_MUX1_RSVD3(v) \
+ (((v) << 6) & BM_PXP_WFE_A_STAGE2_MUX1_RSVD3)
+#define BP_PXP_WFE_A_STAGE2_MUX1_MUX4 0
+#define BM_PXP_WFE_A_STAGE2_MUX1_MUX4 0x0000003F
+#define BF_PXP_WFE_A_STAGE2_MUX1_MUX4(v) \
+ (((v) << 0) & BM_PXP_WFE_A_STAGE2_MUX1_MUX4)
+
+#define HW_PXP_WFE_A_STAGE2_MUX2 (0x00001780)
+#define HW_PXP_WFE_A_STAGE2_MUX2_SET (0x00001784)
+#define HW_PXP_WFE_A_STAGE2_MUX2_CLR (0x00001788)
+#define HW_PXP_WFE_A_STAGE2_MUX2_TOG (0x0000178c)
+
+#define BP_PXP_WFE_A_STAGE2_MUX2_RSVD0 30
+#define BM_PXP_WFE_A_STAGE2_MUX2_RSVD0 0xC0000000
+#define BF_PXP_WFE_A_STAGE2_MUX2_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFE_A_STAGE2_MUX2_RSVD0)
+#define BP_PXP_WFE_A_STAGE2_MUX2_MUX11 24
+#define BM_PXP_WFE_A_STAGE2_MUX2_MUX11 0x3F000000
+#define BF_PXP_WFE_A_STAGE2_MUX2_MUX11(v) \
+ (((v) << 24) & BM_PXP_WFE_A_STAGE2_MUX2_MUX11)
+#define BP_PXP_WFE_A_STAGE2_MUX2_RSVD1 22
+#define BM_PXP_WFE_A_STAGE2_MUX2_RSVD1 0x00C00000
+#define BF_PXP_WFE_A_STAGE2_MUX2_RSVD1(v) \
+ (((v) << 22) & BM_PXP_WFE_A_STAGE2_MUX2_RSVD1)
+#define BP_PXP_WFE_A_STAGE2_MUX2_MUX10 16
+#define BM_PXP_WFE_A_STAGE2_MUX2_MUX10 0x003F0000
+#define BF_PXP_WFE_A_STAGE2_MUX2_MUX10(v) \
+ (((v) << 16) & BM_PXP_WFE_A_STAGE2_MUX2_MUX10)
+#define BP_PXP_WFE_A_STAGE2_MUX2_RSVD2 14
+#define BM_PXP_WFE_A_STAGE2_MUX2_RSVD2 0x0000C000
+#define BF_PXP_WFE_A_STAGE2_MUX2_RSVD2(v) \
+ (((v) << 14) & BM_PXP_WFE_A_STAGE2_MUX2_RSVD2)
+#define BP_PXP_WFE_A_STAGE2_MUX2_MUX9 8
+#define BM_PXP_WFE_A_STAGE2_MUX2_MUX9 0x00003F00
+#define BF_PXP_WFE_A_STAGE2_MUX2_MUX9(v) \
+ (((v) << 8) & BM_PXP_WFE_A_STAGE2_MUX2_MUX9)
+#define BP_PXP_WFE_A_STAGE2_MUX2_RSVD3 6
+#define BM_PXP_WFE_A_STAGE2_MUX2_RSVD3 0x000000C0
+#define BF_PXP_WFE_A_STAGE2_MUX2_RSVD3(v) \
+ (((v) << 6) & BM_PXP_WFE_A_STAGE2_MUX2_RSVD3)
+#define BP_PXP_WFE_A_STAGE2_MUX2_MUX8 0
+#define BM_PXP_WFE_A_STAGE2_MUX2_MUX8 0x0000003F
+#define BF_PXP_WFE_A_STAGE2_MUX2_MUX8(v) \
+ (((v) << 0) & BM_PXP_WFE_A_STAGE2_MUX2_MUX8)
+
+#define HW_PXP_WFE_A_STAGE2_MUX3 (0x00001790)
+#define HW_PXP_WFE_A_STAGE2_MUX3_SET (0x00001794)
+#define HW_PXP_WFE_A_STAGE2_MUX3_CLR (0x00001798)
+#define HW_PXP_WFE_A_STAGE2_MUX3_TOG (0x0000179c)
+
+#define BP_PXP_WFE_A_STAGE2_MUX3_RSVD0 30
+#define BM_PXP_WFE_A_STAGE2_MUX3_RSVD0 0xC0000000
+#define BF_PXP_WFE_A_STAGE2_MUX3_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFE_A_STAGE2_MUX3_RSVD0)
+#define BP_PXP_WFE_A_STAGE2_MUX3_MUX15 24
+#define BM_PXP_WFE_A_STAGE2_MUX3_MUX15 0x3F000000
+#define BF_PXP_WFE_A_STAGE2_MUX3_MUX15(v) \
+ (((v) << 24) & BM_PXP_WFE_A_STAGE2_MUX3_MUX15)
+#define BP_PXP_WFE_A_STAGE2_MUX3_RSVD1 22
+#define BM_PXP_WFE_A_STAGE2_MUX3_RSVD1 0x00C00000
+#define BF_PXP_WFE_A_STAGE2_MUX3_RSVD1(v) \
+ (((v) << 22) & BM_PXP_WFE_A_STAGE2_MUX3_RSVD1)
+#define BP_PXP_WFE_A_STAGE2_MUX3_MUX14 16
+#define BM_PXP_WFE_A_STAGE2_MUX3_MUX14 0x003F0000
+#define BF_PXP_WFE_A_STAGE2_MUX3_MUX14(v) \
+ (((v) << 16) & BM_PXP_WFE_A_STAGE2_MUX3_MUX14)
+#define BP_PXP_WFE_A_STAGE2_MUX3_RSVD2 14
+#define BM_PXP_WFE_A_STAGE2_MUX3_RSVD2 0x0000C000
+#define BF_PXP_WFE_A_STAGE2_MUX3_RSVD2(v) \
+ (((v) << 14) & BM_PXP_WFE_A_STAGE2_MUX3_RSVD2)
+#define BP_PXP_WFE_A_STAGE2_MUX3_MUX13 8
+#define BM_PXP_WFE_A_STAGE2_MUX3_MUX13 0x00003F00
+#define BF_PXP_WFE_A_STAGE2_MUX3_MUX13(v) \
+ (((v) << 8) & BM_PXP_WFE_A_STAGE2_MUX3_MUX13)
+#define BP_PXP_WFE_A_STAGE2_MUX3_RSVD3 6
+#define BM_PXP_WFE_A_STAGE2_MUX3_RSVD3 0x000000C0
+#define BF_PXP_WFE_A_STAGE2_MUX3_RSVD3(v) \
+ (((v) << 6) & BM_PXP_WFE_A_STAGE2_MUX3_RSVD3)
+#define BP_PXP_WFE_A_STAGE2_MUX3_MUX12 0
+#define BM_PXP_WFE_A_STAGE2_MUX3_MUX12 0x0000003F
+#define BF_PXP_WFE_A_STAGE2_MUX3_MUX12(v) \
+ (((v) << 0) & BM_PXP_WFE_A_STAGE2_MUX3_MUX12)
+
+#define HW_PXP_WFE_A_STAGE2_MUX4 (0x000017a0)
+#define HW_PXP_WFE_A_STAGE2_MUX4_SET (0x000017a4)
+#define HW_PXP_WFE_A_STAGE2_MUX4_CLR (0x000017a8)
+#define HW_PXP_WFE_A_STAGE2_MUX4_TOG (0x000017ac)
+
+#define BP_PXP_WFE_A_STAGE2_MUX4_RSVD0 30
+#define BM_PXP_WFE_A_STAGE2_MUX4_RSVD0 0xC0000000
+#define BF_PXP_WFE_A_STAGE2_MUX4_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFE_A_STAGE2_MUX4_RSVD0)
+#define BP_PXP_WFE_A_STAGE2_MUX4_MUX19 24
+#define BM_PXP_WFE_A_STAGE2_MUX4_MUX19 0x3F000000
+#define BF_PXP_WFE_A_STAGE2_MUX4_MUX19(v) \
+ (((v) << 24) & BM_PXP_WFE_A_STAGE2_MUX4_MUX19)
+#define BP_PXP_WFE_A_STAGE2_MUX4_RSVD1 22
+#define BM_PXP_WFE_A_STAGE2_MUX4_RSVD1 0x00C00000
+#define BF_PXP_WFE_A_STAGE2_MUX4_RSVD1(v) \
+ (((v) << 22) & BM_PXP_WFE_A_STAGE2_MUX4_RSVD1)
+#define BP_PXP_WFE_A_STAGE2_MUX4_MUX18 16
+#define BM_PXP_WFE_A_STAGE2_MUX4_MUX18 0x003F0000
+#define BF_PXP_WFE_A_STAGE2_MUX4_MUX18(v) \
+ (((v) << 16) & BM_PXP_WFE_A_STAGE2_MUX4_MUX18)
+#define BP_PXP_WFE_A_STAGE2_MUX4_RSVD2 14
+#define BM_PXP_WFE_A_STAGE2_MUX4_RSVD2 0x0000C000
+#define BF_PXP_WFE_A_STAGE2_MUX4_RSVD2(v) \
+ (((v) << 14) & BM_PXP_WFE_A_STAGE2_MUX4_RSVD2)
+#define BP_PXP_WFE_A_STAGE2_MUX4_MUX17 8
+#define BM_PXP_WFE_A_STAGE2_MUX4_MUX17 0x00003F00
+#define BF_PXP_WFE_A_STAGE2_MUX4_MUX17(v) \
+ (((v) << 8) & BM_PXP_WFE_A_STAGE2_MUX4_MUX17)
+#define BP_PXP_WFE_A_STAGE2_MUX4_RSVD3 6
+#define BM_PXP_WFE_A_STAGE2_MUX4_RSVD3 0x000000C0
+#define BF_PXP_WFE_A_STAGE2_MUX4_RSVD3(v) \
+ (((v) << 6) & BM_PXP_WFE_A_STAGE2_MUX4_RSVD3)
+#define BP_PXP_WFE_A_STAGE2_MUX4_MUX16 0
+#define BM_PXP_WFE_A_STAGE2_MUX4_MUX16 0x0000003F
+#define BF_PXP_WFE_A_STAGE2_MUX4_MUX16(v) \
+ (((v) << 0) & BM_PXP_WFE_A_STAGE2_MUX4_MUX16)
+
+#define HW_PXP_WFE_A_STAGE2_MUX5 (0x000017b0)
+#define HW_PXP_WFE_A_STAGE2_MUX5_SET (0x000017b4)
+#define HW_PXP_WFE_A_STAGE2_MUX5_CLR (0x000017b8)
+#define HW_PXP_WFE_A_STAGE2_MUX5_TOG (0x000017bc)
+
+#define BP_PXP_WFE_A_STAGE2_MUX5_RSVD0 30
+#define BM_PXP_WFE_A_STAGE2_MUX5_RSVD0 0xC0000000
+#define BF_PXP_WFE_A_STAGE2_MUX5_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFE_A_STAGE2_MUX5_RSVD0)
+#define BP_PXP_WFE_A_STAGE2_MUX5_MUX23 24
+#define BM_PXP_WFE_A_STAGE2_MUX5_MUX23 0x3F000000
+#define BF_PXP_WFE_A_STAGE2_MUX5_MUX23(v) \
+ (((v) << 24) & BM_PXP_WFE_A_STAGE2_MUX5_MUX23)
+#define BP_PXP_WFE_A_STAGE2_MUX5_RSVD1 22
+#define BM_PXP_WFE_A_STAGE2_MUX5_RSVD1 0x00C00000
+#define BF_PXP_WFE_A_STAGE2_MUX5_RSVD1(v) \
+ (((v) << 22) & BM_PXP_WFE_A_STAGE2_MUX5_RSVD1)
+#define BP_PXP_WFE_A_STAGE2_MUX5_MUX22 16
+#define BM_PXP_WFE_A_STAGE2_MUX5_MUX22 0x003F0000
+#define BF_PXP_WFE_A_STAGE2_MUX5_MUX22(v) \
+ (((v) << 16) & BM_PXP_WFE_A_STAGE2_MUX5_MUX22)
+#define BP_PXP_WFE_A_STAGE2_MUX5_RSVD2 14
+#define BM_PXP_WFE_A_STAGE2_MUX5_RSVD2 0x0000C000
+#define BF_PXP_WFE_A_STAGE2_MUX5_RSVD2(v) \
+ (((v) << 14) & BM_PXP_WFE_A_STAGE2_MUX5_RSVD2)
+#define BP_PXP_WFE_A_STAGE2_MUX5_MUX21 8
+#define BM_PXP_WFE_A_STAGE2_MUX5_MUX21 0x00003F00
+#define BF_PXP_WFE_A_STAGE2_MUX5_MUX21(v) \
+ (((v) << 8) & BM_PXP_WFE_A_STAGE2_MUX5_MUX21)
+#define BP_PXP_WFE_A_STAGE2_MUX5_RSVD3 6
+#define BM_PXP_WFE_A_STAGE2_MUX5_RSVD3 0x000000C0
+#define BF_PXP_WFE_A_STAGE2_MUX5_RSVD3(v) \
+ (((v) << 6) & BM_PXP_WFE_A_STAGE2_MUX5_RSVD3)
+#define BP_PXP_WFE_A_STAGE2_MUX5_MUX20 0
+#define BM_PXP_WFE_A_STAGE2_MUX5_MUX20 0x0000003F
+#define BF_PXP_WFE_A_STAGE2_MUX5_MUX20(v) \
+ (((v) << 0) & BM_PXP_WFE_A_STAGE2_MUX5_MUX20)
+
+#define HW_PXP_WFE_A_STAGE2_MUX6 (0x000017c0)
+#define HW_PXP_WFE_A_STAGE2_MUX6_SET (0x000017c4)
+#define HW_PXP_WFE_A_STAGE2_MUX6_CLR (0x000017c8)
+#define HW_PXP_WFE_A_STAGE2_MUX6_TOG (0x000017cc)
+
+#define BP_PXP_WFE_A_STAGE2_MUX6_RSVD0 30
+#define BM_PXP_WFE_A_STAGE2_MUX6_RSVD0 0xC0000000
+#define BF_PXP_WFE_A_STAGE2_MUX6_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFE_A_STAGE2_MUX6_RSVD0)
+#define BP_PXP_WFE_A_STAGE2_MUX6_MUX27 24
+#define BM_PXP_WFE_A_STAGE2_MUX6_MUX27 0x3F000000
+#define BF_PXP_WFE_A_STAGE2_MUX6_MUX27(v) \
+ (((v) << 24) & BM_PXP_WFE_A_STAGE2_MUX6_MUX27)
+#define BP_PXP_WFE_A_STAGE2_MUX6_RSVD1 22
+#define BM_PXP_WFE_A_STAGE2_MUX6_RSVD1 0x00C00000
+#define BF_PXP_WFE_A_STAGE2_MUX6_RSVD1(v) \
+ (((v) << 22) & BM_PXP_WFE_A_STAGE2_MUX6_RSVD1)
+#define BP_PXP_WFE_A_STAGE2_MUX6_MUX26 16
+#define BM_PXP_WFE_A_STAGE2_MUX6_MUX26 0x003F0000
+#define BF_PXP_WFE_A_STAGE2_MUX6_MUX26(v) \
+ (((v) << 16) & BM_PXP_WFE_A_STAGE2_MUX6_MUX26)
+#define BP_PXP_WFE_A_STAGE2_MUX6_RSVD2 14
+#define BM_PXP_WFE_A_STAGE2_MUX6_RSVD2 0x0000C000
+#define BF_PXP_WFE_A_STAGE2_MUX6_RSVD2(v) \
+ (((v) << 14) & BM_PXP_WFE_A_STAGE2_MUX6_RSVD2)
+#define BP_PXP_WFE_A_STAGE2_MUX6_MUX25 8
+#define BM_PXP_WFE_A_STAGE2_MUX6_MUX25 0x00003F00
+#define BF_PXP_WFE_A_STAGE2_MUX6_MUX25(v) \
+ (((v) << 8) & BM_PXP_WFE_A_STAGE2_MUX6_MUX25)
+#define BP_PXP_WFE_A_STAGE2_MUX6_RSVD3 6
+#define BM_PXP_WFE_A_STAGE2_MUX6_RSVD3 0x000000C0
+#define BF_PXP_WFE_A_STAGE2_MUX6_RSVD3(v) \
+ (((v) << 6) & BM_PXP_WFE_A_STAGE2_MUX6_RSVD3)
+#define BP_PXP_WFE_A_STAGE2_MUX6_MUX24 0
+#define BM_PXP_WFE_A_STAGE2_MUX6_MUX24 0x0000003F
+#define BF_PXP_WFE_A_STAGE2_MUX6_MUX24(v) \
+ (((v) << 0) & BM_PXP_WFE_A_STAGE2_MUX6_MUX24)
+
+#define HW_PXP_WFE_A_STAGE2_MUX7 (0x000017d0)
+#define HW_PXP_WFE_A_STAGE2_MUX7_SET (0x000017d4)
+#define HW_PXP_WFE_A_STAGE2_MUX7_CLR (0x000017d8)
+#define HW_PXP_WFE_A_STAGE2_MUX7_TOG (0x000017dc)
+
+#define BP_PXP_WFE_A_STAGE2_MUX7_RSVD0 30
+#define BM_PXP_WFE_A_STAGE2_MUX7_RSVD0 0xC0000000
+#define BF_PXP_WFE_A_STAGE2_MUX7_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFE_A_STAGE2_MUX7_RSVD0)
+#define BP_PXP_WFE_A_STAGE2_MUX7_MUX31 24
+#define BM_PXP_WFE_A_STAGE2_MUX7_MUX31 0x3F000000
+#define BF_PXP_WFE_A_STAGE2_MUX7_MUX31(v) \
+ (((v) << 24) & BM_PXP_WFE_A_STAGE2_MUX7_MUX31)
+#define BP_PXP_WFE_A_STAGE2_MUX7_RSVD1 22
+#define BM_PXP_WFE_A_STAGE2_MUX7_RSVD1 0x00C00000
+#define BF_PXP_WFE_A_STAGE2_MUX7_RSVD1(v) \
+ (((v) << 22) & BM_PXP_WFE_A_STAGE2_MUX7_RSVD1)
+#define BP_PXP_WFE_A_STAGE2_MUX7_MUX30 16
+#define BM_PXP_WFE_A_STAGE2_MUX7_MUX30 0x003F0000
+#define BF_PXP_WFE_A_STAGE2_MUX7_MUX30(v) \
+ (((v) << 16) & BM_PXP_WFE_A_STAGE2_MUX7_MUX30)
+#define BP_PXP_WFE_A_STAGE2_MUX7_RSVD2 14
+#define BM_PXP_WFE_A_STAGE2_MUX7_RSVD2 0x0000C000
+#define BF_PXP_WFE_A_STAGE2_MUX7_RSVD2(v) \
+ (((v) << 14) & BM_PXP_WFE_A_STAGE2_MUX7_RSVD2)
+#define BP_PXP_WFE_A_STAGE2_MUX7_MUX29 8
+#define BM_PXP_WFE_A_STAGE2_MUX7_MUX29 0x00003F00
+#define BF_PXP_WFE_A_STAGE2_MUX7_MUX29(v) \
+ (((v) << 8) & BM_PXP_WFE_A_STAGE2_MUX7_MUX29)
+#define BP_PXP_WFE_A_STAGE2_MUX7_RSVD3 6
+#define BM_PXP_WFE_A_STAGE2_MUX7_RSVD3 0x000000C0
+#define BF_PXP_WFE_A_STAGE2_MUX7_RSVD3(v) \
+ (((v) << 6) & BM_PXP_WFE_A_STAGE2_MUX7_RSVD3)
+#define BP_PXP_WFE_A_STAGE2_MUX7_MUX28 0
+#define BM_PXP_WFE_A_STAGE2_MUX7_MUX28 0x0000003F
+#define BF_PXP_WFE_A_STAGE2_MUX7_MUX28(v) \
+ (((v) << 0) & BM_PXP_WFE_A_STAGE2_MUX7_MUX28)
+
+#define HW_PXP_WFE_A_STAGE2_MUX8 (0x000017e0)
+#define HW_PXP_WFE_A_STAGE2_MUX8_SET (0x000017e4)
+#define HW_PXP_WFE_A_STAGE2_MUX8_CLR (0x000017e8)
+#define HW_PXP_WFE_A_STAGE2_MUX8_TOG (0x000017ec)
+
+#define BP_PXP_WFE_A_STAGE2_MUX8_RSVD0 30
+#define BM_PXP_WFE_A_STAGE2_MUX8_RSVD0 0xC0000000
+#define BF_PXP_WFE_A_STAGE2_MUX8_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFE_A_STAGE2_MUX8_RSVD0)
+#define BP_PXP_WFE_A_STAGE2_MUX8_MUX35 24
+#define BM_PXP_WFE_A_STAGE2_MUX8_MUX35 0x3F000000
+#define BF_PXP_WFE_A_STAGE2_MUX8_MUX35(v) \
+ (((v) << 24) & BM_PXP_WFE_A_STAGE2_MUX8_MUX35)
+#define BP_PXP_WFE_A_STAGE2_MUX8_RSVD1 22
+#define BM_PXP_WFE_A_STAGE2_MUX8_RSVD1 0x00C00000
+#define BF_PXP_WFE_A_STAGE2_MUX8_RSVD1(v) \
+ (((v) << 22) & BM_PXP_WFE_A_STAGE2_MUX8_RSVD1)
+#define BP_PXP_WFE_A_STAGE2_MUX8_MUX34 16
+#define BM_PXP_WFE_A_STAGE2_MUX8_MUX34 0x003F0000
+#define BF_PXP_WFE_A_STAGE2_MUX8_MUX34(v) \
+ (((v) << 16) & BM_PXP_WFE_A_STAGE2_MUX8_MUX34)
+#define BP_PXP_WFE_A_STAGE2_MUX8_RSVD2 14
+#define BM_PXP_WFE_A_STAGE2_MUX8_RSVD2 0x0000C000
+#define BF_PXP_WFE_A_STAGE2_MUX8_RSVD2(v) \
+ (((v) << 14) & BM_PXP_WFE_A_STAGE2_MUX8_RSVD2)
+#define BP_PXP_WFE_A_STAGE2_MUX8_MUX33 8
+#define BM_PXP_WFE_A_STAGE2_MUX8_MUX33 0x00003F00
+#define BF_PXP_WFE_A_STAGE2_MUX8_MUX33(v) \
+ (((v) << 8) & BM_PXP_WFE_A_STAGE2_MUX8_MUX33)
+#define BP_PXP_WFE_A_STAGE2_MUX8_RSVD3 6
+#define BM_PXP_WFE_A_STAGE2_MUX8_RSVD3 0x000000C0
+#define BF_PXP_WFE_A_STAGE2_MUX8_RSVD3(v) \
+ (((v) << 6) & BM_PXP_WFE_A_STAGE2_MUX8_RSVD3)
+#define BP_PXP_WFE_A_STAGE2_MUX8_MUX32 0
+#define BM_PXP_WFE_A_STAGE2_MUX8_MUX32 0x0000003F
+#define BF_PXP_WFE_A_STAGE2_MUX8_MUX32(v) \
+ (((v) << 0) & BM_PXP_WFE_A_STAGE2_MUX8_MUX32)
+
+#define HW_PXP_WFE_A_STAGE2_MUX9 (0x000017f0)
+#define HW_PXP_WFE_A_STAGE2_MUX9_SET (0x000017f4)
+#define HW_PXP_WFE_A_STAGE2_MUX9_CLR (0x000017f8)
+#define HW_PXP_WFE_A_STAGE2_MUX9_TOG (0x000017fc)
+
+#define BP_PXP_WFE_A_STAGE2_MUX9_RSVD0 30
+#define BM_PXP_WFE_A_STAGE2_MUX9_RSVD0 0xC0000000
+#define BF_PXP_WFE_A_STAGE2_MUX9_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFE_A_STAGE2_MUX9_RSVD0)
+#define BP_PXP_WFE_A_STAGE2_MUX9_MUX39 24
+#define BM_PXP_WFE_A_STAGE2_MUX9_MUX39 0x3F000000
+#define BF_PXP_WFE_A_STAGE2_MUX9_MUX39(v) \
+ (((v) << 24) & BM_PXP_WFE_A_STAGE2_MUX9_MUX39)
+#define BP_PXP_WFE_A_STAGE2_MUX9_RSVD1 22
+#define BM_PXP_WFE_A_STAGE2_MUX9_RSVD1 0x00C00000
+#define BF_PXP_WFE_A_STAGE2_MUX9_RSVD1(v) \
+ (((v) << 22) & BM_PXP_WFE_A_STAGE2_MUX9_RSVD1)
+#define BP_PXP_WFE_A_STAGE2_MUX9_MUX38 16
+#define BM_PXP_WFE_A_STAGE2_MUX9_MUX38 0x003F0000
+#define BF_PXP_WFE_A_STAGE2_MUX9_MUX38(v) \
+ (((v) << 16) & BM_PXP_WFE_A_STAGE2_MUX9_MUX38)
+#define BP_PXP_WFE_A_STAGE2_MUX9_RSVD2 14
+#define BM_PXP_WFE_A_STAGE2_MUX9_RSVD2 0x0000C000
+#define BF_PXP_WFE_A_STAGE2_MUX9_RSVD2(v) \
+ (((v) << 14) & BM_PXP_WFE_A_STAGE2_MUX9_RSVD2)
+#define BP_PXP_WFE_A_STAGE2_MUX9_MUX37 8
+#define BM_PXP_WFE_A_STAGE2_MUX9_MUX37 0x00003F00
+#define BF_PXP_WFE_A_STAGE2_MUX9_MUX37(v) \
+ (((v) << 8) & BM_PXP_WFE_A_STAGE2_MUX9_MUX37)
+#define BP_PXP_WFE_A_STAGE2_MUX9_RSVD3 6
+#define BM_PXP_WFE_A_STAGE2_MUX9_RSVD3 0x000000C0
+#define BF_PXP_WFE_A_STAGE2_MUX9_RSVD3(v) \
+ (((v) << 6) & BM_PXP_WFE_A_STAGE2_MUX9_RSVD3)
+#define BP_PXP_WFE_A_STAGE2_MUX9_MUX36 0
+#define BM_PXP_WFE_A_STAGE2_MUX9_MUX36 0x0000003F
+#define BF_PXP_WFE_A_STAGE2_MUX9_MUX36(v) \
+ (((v) << 0) & BM_PXP_WFE_A_STAGE2_MUX9_MUX36)
+
+#define HW_PXP_WFE_A_STAGE2_MUX10 (0x00001800)
+#define HW_PXP_WFE_A_STAGE2_MUX10_SET (0x00001804)
+#define HW_PXP_WFE_A_STAGE2_MUX10_CLR (0x00001808)
+#define HW_PXP_WFE_A_STAGE2_MUX10_TOG (0x0000180c)
+
+#define BP_PXP_WFE_A_STAGE2_MUX10_RSVD0 30
+#define BM_PXP_WFE_A_STAGE2_MUX10_RSVD0 0xC0000000
+#define BF_PXP_WFE_A_STAGE2_MUX10_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFE_A_STAGE2_MUX10_RSVD0)
+#define BP_PXP_WFE_A_STAGE2_MUX10_MUX43 24
+#define BM_PXP_WFE_A_STAGE2_MUX10_MUX43 0x3F000000
+#define BF_PXP_WFE_A_STAGE2_MUX10_MUX43(v) \
+ (((v) << 24) & BM_PXP_WFE_A_STAGE2_MUX10_MUX43)
+#define BV_PXP_WFE_A_STAGE2_MUX10_MUX43__INC 0x0
+#define BV_PXP_WFE_A_STAGE2_MUX10_MUX43__DEC 0x1
+#define BV_PXP_WFE_A_STAGE2_MUX10_MUX43__ADD 0x2
+#define BV_PXP_WFE_A_STAGE2_MUX10_MUX43__MINUS 0x3
+#define BV_PXP_WFE_A_STAGE2_MUX10_MUX43__AND 0x4
+#define BV_PXP_WFE_A_STAGE2_MUX10_MUX43__OR 0x5
+#define BV_PXP_WFE_A_STAGE2_MUX10_MUX43__XOR 0x6
+#define BV_PXP_WFE_A_STAGE2_MUX10_MUX43__SHIFTLEFT 0x7
+#define BV_PXP_WFE_A_STAGE2_MUX10_MUX43__SHIFTRIGHT 0x8
+#define BV_PXP_WFE_A_STAGE2_MUX10_MUX43__BIT_AND 0x9
+#define BV_PXP_WFE_A_STAGE2_MUX10_MUX43__BIT_OR 0xa
+#define BV_PXP_WFE_A_STAGE2_MUX10_MUX43__BIT_CMP 0xb
+#define BV_PXP_WFE_A_STAGE2_MUX10_MUX43__NOP 0xc
+#define BP_PXP_WFE_A_STAGE2_MUX10_RSVD1 22
+#define BM_PXP_WFE_A_STAGE2_MUX10_RSVD1 0x00C00000
+#define BF_PXP_WFE_A_STAGE2_MUX10_RSVD1(v) \
+ (((v) << 22) & BM_PXP_WFE_A_STAGE2_MUX10_RSVD1)
+#define BP_PXP_WFE_A_STAGE2_MUX10_MUX42 16
+#define BM_PXP_WFE_A_STAGE2_MUX10_MUX42 0x003F0000
+#define BF_PXP_WFE_A_STAGE2_MUX10_MUX42(v) \
+ (((v) << 16) & BM_PXP_WFE_A_STAGE2_MUX10_MUX42)
+#define BP_PXP_WFE_A_STAGE2_MUX10_RSVD2 14
+#define BM_PXP_WFE_A_STAGE2_MUX10_RSVD2 0x0000C000
+#define BF_PXP_WFE_A_STAGE2_MUX10_RSVD2(v) \
+ (((v) << 14) & BM_PXP_WFE_A_STAGE2_MUX10_RSVD2)
+#define BP_PXP_WFE_A_STAGE2_MUX10_MUX41 8
+#define BM_PXP_WFE_A_STAGE2_MUX10_MUX41 0x00003F00
+#define BF_PXP_WFE_A_STAGE2_MUX10_MUX41(v) \
+ (((v) << 8) & BM_PXP_WFE_A_STAGE2_MUX10_MUX41)
+#define BP_PXP_WFE_A_STAGE2_MUX10_RSVD3 6
+#define BM_PXP_WFE_A_STAGE2_MUX10_RSVD3 0x000000C0
+#define BF_PXP_WFE_A_STAGE2_MUX10_RSVD3(v) \
+ (((v) << 6) & BM_PXP_WFE_A_STAGE2_MUX10_RSVD3)
+#define BP_PXP_WFE_A_STAGE2_MUX10_MUX40 0
+#define BM_PXP_WFE_A_STAGE2_MUX10_MUX40 0x0000003F
+#define BF_PXP_WFE_A_STAGE2_MUX10_MUX40(v) \
+ (((v) << 0) & BM_PXP_WFE_A_STAGE2_MUX10_MUX40)
+#define BV_PXP_WFE_A_STAGE2_MUX10_MUX40__INC 0x0
+#define BV_PXP_WFE_A_STAGE2_MUX10_MUX40__DEC 0x1
+#define BV_PXP_WFE_A_STAGE2_MUX10_MUX40__ADD 0x2
+#define BV_PXP_WFE_A_STAGE2_MUX10_MUX40__MINUS 0x3
+#define BV_PXP_WFE_A_STAGE2_MUX10_MUX40__AND 0x4
+#define BV_PXP_WFE_A_STAGE2_MUX10_MUX40__OR 0x5
+#define BV_PXP_WFE_A_STAGE2_MUX10_MUX40__XOR 0x6
+#define BV_PXP_WFE_A_STAGE2_MUX10_MUX40__SHIFTLEFT 0x7
+#define BV_PXP_WFE_A_STAGE2_MUX10_MUX40__SHIFTRIGHT 0x8
+#define BV_PXP_WFE_A_STAGE2_MUX10_MUX40__BIT_AND 0x9
+#define BV_PXP_WFE_A_STAGE2_MUX10_MUX40__BIT_OR 0xa
+#define BV_PXP_WFE_A_STAGE2_MUX10_MUX40__BIT_CMP 0xb
+#define BV_PXP_WFE_A_STAGE2_MUX10_MUX40__NOP 0xc
+
+#define HW_PXP_WFE_A_STAGE2_MUX11 (0x00001810)
+#define HW_PXP_WFE_A_STAGE2_MUX11_SET (0x00001814)
+#define HW_PXP_WFE_A_STAGE2_MUX11_CLR (0x00001818)
+#define HW_PXP_WFE_A_STAGE2_MUX11_TOG (0x0000181c)
+
+#define BP_PXP_WFE_A_STAGE2_MUX11_RSVD0 30
+#define BM_PXP_WFE_A_STAGE2_MUX11_RSVD0 0xC0000000
+#define BF_PXP_WFE_A_STAGE2_MUX11_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFE_A_STAGE2_MUX11_RSVD0)
+#define BP_PXP_WFE_A_STAGE2_MUX11_MUX47 24
+#define BM_PXP_WFE_A_STAGE2_MUX11_MUX47 0x3F000000
+#define BF_PXP_WFE_A_STAGE2_MUX11_MUX47(v) \
+ (((v) << 24) & BM_PXP_WFE_A_STAGE2_MUX11_MUX47)
+#define BP_PXP_WFE_A_STAGE2_MUX11_RSVD1 22
+#define BM_PXP_WFE_A_STAGE2_MUX11_RSVD1 0x00C00000
+#define BF_PXP_WFE_A_STAGE2_MUX11_RSVD1(v) \
+ (((v) << 22) & BM_PXP_WFE_A_STAGE2_MUX11_RSVD1)
+#define BP_PXP_WFE_A_STAGE2_MUX11_MUX46 16
+#define BM_PXP_WFE_A_STAGE2_MUX11_MUX46 0x003F0000
+#define BF_PXP_WFE_A_STAGE2_MUX11_MUX46(v) \
+ (((v) << 16) & BM_PXP_WFE_A_STAGE2_MUX11_MUX46)
+#define BP_PXP_WFE_A_STAGE2_MUX11_RSVD2 14
+#define BM_PXP_WFE_A_STAGE2_MUX11_RSVD2 0x0000C000
+#define BF_PXP_WFE_A_STAGE2_MUX11_RSVD2(v) \
+ (((v) << 14) & BM_PXP_WFE_A_STAGE2_MUX11_RSVD2)
+#define BP_PXP_WFE_A_STAGE2_MUX11_MUX45 8
+#define BM_PXP_WFE_A_STAGE2_MUX11_MUX45 0x00003F00
+#define BF_PXP_WFE_A_STAGE2_MUX11_MUX45(v) \
+ (((v) << 8) & BM_PXP_WFE_A_STAGE2_MUX11_MUX45)
+#define BP_PXP_WFE_A_STAGE2_MUX11_RSVD3 6
+#define BM_PXP_WFE_A_STAGE2_MUX11_RSVD3 0x000000C0
+#define BF_PXP_WFE_A_STAGE2_MUX11_RSVD3(v) \
+ (((v) << 6) & BM_PXP_WFE_A_STAGE2_MUX11_RSVD3)
+#define BP_PXP_WFE_A_STAGE2_MUX11_MUX44 0
+#define BM_PXP_WFE_A_STAGE2_MUX11_MUX44 0x0000003F
+#define BF_PXP_WFE_A_STAGE2_MUX11_MUX44(v) \
+ (((v) << 0) & BM_PXP_WFE_A_STAGE2_MUX11_MUX44)
+
+#define HW_PXP_WFE_A_STAGE2_MUX12 (0x00001820)
+#define HW_PXP_WFE_A_STAGE2_MUX12_SET (0x00001824)
+#define HW_PXP_WFE_A_STAGE2_MUX12_CLR (0x00001828)
+#define HW_PXP_WFE_A_STAGE2_MUX12_TOG (0x0000182c)
+
+#define BP_PXP_WFE_A_STAGE2_MUX12_RSVD0 14
+#define BM_PXP_WFE_A_STAGE2_MUX12_RSVD0 0xFFFFC000
+#define BF_PXP_WFE_A_STAGE2_MUX12_RSVD0(v) \
+ (((v) << 14) & BM_PXP_WFE_A_STAGE2_MUX12_RSVD0)
+#define BP_PXP_WFE_A_STAGE2_MUX12_MUX49 8
+#define BM_PXP_WFE_A_STAGE2_MUX12_MUX49 0x00003F00
+#define BF_PXP_WFE_A_STAGE2_MUX12_MUX49(v) \
+ (((v) << 8) & BM_PXP_WFE_A_STAGE2_MUX12_MUX49)
+#define BP_PXP_WFE_A_STAGE2_MUX12_RSVD3 6
+#define BM_PXP_WFE_A_STAGE2_MUX12_RSVD3 0x000000C0
+#define BF_PXP_WFE_A_STAGE2_MUX12_RSVD3(v) \
+ (((v) << 6) & BM_PXP_WFE_A_STAGE2_MUX12_RSVD3)
+#define BP_PXP_WFE_A_STAGE2_MUX12_MUX48 0
+#define BM_PXP_WFE_A_STAGE2_MUX12_MUX48 0x0000003F
+#define BF_PXP_WFE_A_STAGE2_MUX12_MUX48(v) \
+ (((v) << 0) & BM_PXP_WFE_A_STAGE2_MUX12_MUX48)
+
+#define HW_PXP_WFE_A_STAGE3_MUX0 (0x00001830)
+#define HW_PXP_WFE_A_STAGE3_MUX0_SET (0x00001834)
+#define HW_PXP_WFE_A_STAGE3_MUX0_CLR (0x00001838)
+#define HW_PXP_WFE_A_STAGE3_MUX0_TOG (0x0000183c)
+
+#define BP_PXP_WFE_A_STAGE3_MUX0_RSVD0 30
+#define BM_PXP_WFE_A_STAGE3_MUX0_RSVD0 0xC0000000
+#define BF_PXP_WFE_A_STAGE3_MUX0_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFE_A_STAGE3_MUX0_RSVD0)
+#define BP_PXP_WFE_A_STAGE3_MUX0_MUX3 24
+#define BM_PXP_WFE_A_STAGE3_MUX0_MUX3 0x3F000000
+#define BF_PXP_WFE_A_STAGE3_MUX0_MUX3(v) \
+ (((v) << 24) & BM_PXP_WFE_A_STAGE3_MUX0_MUX3)
+#define BP_PXP_WFE_A_STAGE3_MUX0_RSVD1 22
+#define BM_PXP_WFE_A_STAGE3_MUX0_RSVD1 0x00C00000
+#define BF_PXP_WFE_A_STAGE3_MUX0_RSVD1(v) \
+ (((v) << 22) & BM_PXP_WFE_A_STAGE3_MUX0_RSVD1)
+#define BP_PXP_WFE_A_STAGE3_MUX0_MUX2 16
+#define BM_PXP_WFE_A_STAGE3_MUX0_MUX2 0x003F0000
+#define BF_PXP_WFE_A_STAGE3_MUX0_MUX2(v) \
+ (((v) << 16) & BM_PXP_WFE_A_STAGE3_MUX0_MUX2)
+#define BP_PXP_WFE_A_STAGE3_MUX0_RSVD2 14
+#define BM_PXP_WFE_A_STAGE3_MUX0_RSVD2 0x0000C000
+#define BF_PXP_WFE_A_STAGE3_MUX0_RSVD2(v) \
+ (((v) << 14) & BM_PXP_WFE_A_STAGE3_MUX0_RSVD2)
+#define BP_PXP_WFE_A_STAGE3_MUX0_MUX1 8
+#define BM_PXP_WFE_A_STAGE3_MUX0_MUX1 0x00003F00
+#define BF_PXP_WFE_A_STAGE3_MUX0_MUX1(v) \
+ (((v) << 8) & BM_PXP_WFE_A_STAGE3_MUX0_MUX1)
+#define BP_PXP_WFE_A_STAGE3_MUX0_RSVD3 6
+#define BM_PXP_WFE_A_STAGE3_MUX0_RSVD3 0x000000C0
+#define BF_PXP_WFE_A_STAGE3_MUX0_RSVD3(v) \
+ (((v) << 6) & BM_PXP_WFE_A_STAGE3_MUX0_RSVD3)
+#define BP_PXP_WFE_A_STAGE3_MUX0_MUX0 0
+#define BM_PXP_WFE_A_STAGE3_MUX0_MUX0 0x0000003F
+#define BF_PXP_WFE_A_STAGE3_MUX0_MUX0(v) \
+ (((v) << 0) & BM_PXP_WFE_A_STAGE3_MUX0_MUX0)
+
+#define HW_PXP_WFE_A_STAGE3_MUX1 (0x00001840)
+#define HW_PXP_WFE_A_STAGE3_MUX1_SET (0x00001844)
+#define HW_PXP_WFE_A_STAGE3_MUX1_CLR (0x00001848)
+#define HW_PXP_WFE_A_STAGE3_MUX1_TOG (0x0000184c)
+
+#define BP_PXP_WFE_A_STAGE3_MUX1_RSVD0 30
+#define BM_PXP_WFE_A_STAGE3_MUX1_RSVD0 0xC0000000
+#define BF_PXP_WFE_A_STAGE3_MUX1_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFE_A_STAGE3_MUX1_RSVD0)
+#define BP_PXP_WFE_A_STAGE3_MUX1_MUX7 24
+#define BM_PXP_WFE_A_STAGE3_MUX1_MUX7 0x3F000000
+#define BF_PXP_WFE_A_STAGE3_MUX1_MUX7(v) \
+ (((v) << 24) & BM_PXP_WFE_A_STAGE3_MUX1_MUX7)
+#define BP_PXP_WFE_A_STAGE3_MUX1_RSVD1 22
+#define BM_PXP_WFE_A_STAGE3_MUX1_RSVD1 0x00C00000
+#define BF_PXP_WFE_A_STAGE3_MUX1_RSVD1(v) \
+ (((v) << 22) & BM_PXP_WFE_A_STAGE3_MUX1_RSVD1)
+#define BP_PXP_WFE_A_STAGE3_MUX1_MUX6 16
+#define BM_PXP_WFE_A_STAGE3_MUX1_MUX6 0x003F0000
+#define BF_PXP_WFE_A_STAGE3_MUX1_MUX6(v) \
+ (((v) << 16) & BM_PXP_WFE_A_STAGE3_MUX1_MUX6)
+#define BP_PXP_WFE_A_STAGE3_MUX1_RSVD2 14
+#define BM_PXP_WFE_A_STAGE3_MUX1_RSVD2 0x0000C000
+#define BF_PXP_WFE_A_STAGE3_MUX1_RSVD2(v) \
+ (((v) << 14) & BM_PXP_WFE_A_STAGE3_MUX1_RSVD2)
+#define BP_PXP_WFE_A_STAGE3_MUX1_MUX5 8
+#define BM_PXP_WFE_A_STAGE3_MUX1_MUX5 0x00003F00
+#define BF_PXP_WFE_A_STAGE3_MUX1_MUX5(v) \
+ (((v) << 8) & BM_PXP_WFE_A_STAGE3_MUX1_MUX5)
+#define BP_PXP_WFE_A_STAGE3_MUX1_RSVD3 6
+#define BM_PXP_WFE_A_STAGE3_MUX1_RSVD3 0x000000C0
+#define BF_PXP_WFE_A_STAGE3_MUX1_RSVD3(v) \
+ (((v) << 6) & BM_PXP_WFE_A_STAGE3_MUX1_RSVD3)
+#define BP_PXP_WFE_A_STAGE3_MUX1_MUX4 0
+#define BM_PXP_WFE_A_STAGE3_MUX1_MUX4 0x0000003F
+#define BF_PXP_WFE_A_STAGE3_MUX1_MUX4(v) \
+ (((v) << 0) & BM_PXP_WFE_A_STAGE3_MUX1_MUX4)
+
+#define HW_PXP_WFE_A_STAGE3_MUX2 (0x00001850)
+#define HW_PXP_WFE_A_STAGE3_MUX2_SET (0x00001854)
+#define HW_PXP_WFE_A_STAGE3_MUX2_CLR (0x00001858)
+#define HW_PXP_WFE_A_STAGE3_MUX2_TOG (0x0000185c)
+
+#define BP_PXP_WFE_A_STAGE3_MUX2_RSVD0 30
+#define BM_PXP_WFE_A_STAGE3_MUX2_RSVD0 0xC0000000
+#define BF_PXP_WFE_A_STAGE3_MUX2_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFE_A_STAGE3_MUX2_RSVD0)
+#define BP_PXP_WFE_A_STAGE3_MUX2_MUX11 24
+#define BM_PXP_WFE_A_STAGE3_MUX2_MUX11 0x3F000000
+#define BF_PXP_WFE_A_STAGE3_MUX2_MUX11(v) \
+ (((v) << 24) & BM_PXP_WFE_A_STAGE3_MUX2_MUX11)
+#define BP_PXP_WFE_A_STAGE3_MUX2_RSVD1 22
+#define BM_PXP_WFE_A_STAGE3_MUX2_RSVD1 0x00C00000
+#define BF_PXP_WFE_A_STAGE3_MUX2_RSVD1(v) \
+ (((v) << 22) & BM_PXP_WFE_A_STAGE3_MUX2_RSVD1)
+#define BP_PXP_WFE_A_STAGE3_MUX2_MUX10 16
+#define BM_PXP_WFE_A_STAGE3_MUX2_MUX10 0x003F0000
+#define BF_PXP_WFE_A_STAGE3_MUX2_MUX10(v) \
+ (((v) << 16) & BM_PXP_WFE_A_STAGE3_MUX2_MUX10)
+#define BP_PXP_WFE_A_STAGE3_MUX2_RSVD2 14
+#define BM_PXP_WFE_A_STAGE3_MUX2_RSVD2 0x0000C000
+#define BF_PXP_WFE_A_STAGE3_MUX2_RSVD2(v) \
+ (((v) << 14) & BM_PXP_WFE_A_STAGE3_MUX2_RSVD2)
+#define BP_PXP_WFE_A_STAGE3_MUX2_MUX9 8
+#define BM_PXP_WFE_A_STAGE3_MUX2_MUX9 0x00003F00
+#define BF_PXP_WFE_A_STAGE3_MUX2_MUX9(v) \
+ (((v) << 8) & BM_PXP_WFE_A_STAGE3_MUX2_MUX9)
+#define BP_PXP_WFE_A_STAGE3_MUX2_RSVD3 6
+#define BM_PXP_WFE_A_STAGE3_MUX2_RSVD3 0x000000C0
+#define BF_PXP_WFE_A_STAGE3_MUX2_RSVD3(v) \
+ (((v) << 6) & BM_PXP_WFE_A_STAGE3_MUX2_RSVD3)
+#define BP_PXP_WFE_A_STAGE3_MUX2_MUX8 0
+#define BM_PXP_WFE_A_STAGE3_MUX2_MUX8 0x0000003F
+#define BF_PXP_WFE_A_STAGE3_MUX2_MUX8(v) \
+ (((v) << 0) & BM_PXP_WFE_A_STAGE3_MUX2_MUX8)
+
+#define HW_PXP_WFE_A_STAGE3_MUX3 (0x00001860)
+#define HW_PXP_WFE_A_STAGE3_MUX3_SET (0x00001864)
+#define HW_PXP_WFE_A_STAGE3_MUX3_CLR (0x00001868)
+#define HW_PXP_WFE_A_STAGE3_MUX3_TOG (0x0000186c)
+
+#define BP_PXP_WFE_A_STAGE3_MUX3_RSVD0 30
+#define BM_PXP_WFE_A_STAGE3_MUX3_RSVD0 0xC0000000
+#define BF_PXP_WFE_A_STAGE3_MUX3_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFE_A_STAGE3_MUX3_RSVD0)
+#define BP_PXP_WFE_A_STAGE3_MUX3_MUX15 24
+#define BM_PXP_WFE_A_STAGE3_MUX3_MUX15 0x3F000000
+#define BF_PXP_WFE_A_STAGE3_MUX3_MUX15(v) \
+ (((v) << 24) & BM_PXP_WFE_A_STAGE3_MUX3_MUX15)
+#define BP_PXP_WFE_A_STAGE3_MUX3_RSVD1 22
+#define BM_PXP_WFE_A_STAGE3_MUX3_RSVD1 0x00C00000
+#define BF_PXP_WFE_A_STAGE3_MUX3_RSVD1(v) \
+ (((v) << 22) & BM_PXP_WFE_A_STAGE3_MUX3_RSVD1)
+#define BP_PXP_WFE_A_STAGE3_MUX3_MUX14 16
+#define BM_PXP_WFE_A_STAGE3_MUX3_MUX14 0x003F0000
+#define BF_PXP_WFE_A_STAGE3_MUX3_MUX14(v) \
+ (((v) << 16) & BM_PXP_WFE_A_STAGE3_MUX3_MUX14)
+#define BP_PXP_WFE_A_STAGE3_MUX3_RSVD2 14
+#define BM_PXP_WFE_A_STAGE3_MUX3_RSVD2 0x0000C000
+#define BF_PXP_WFE_A_STAGE3_MUX3_RSVD2(v) \
+ (((v) << 14) & BM_PXP_WFE_A_STAGE3_MUX3_RSVD2)
+#define BP_PXP_WFE_A_STAGE3_MUX3_MUX13 8
+#define BM_PXP_WFE_A_STAGE3_MUX3_MUX13 0x00003F00
+#define BF_PXP_WFE_A_STAGE3_MUX3_MUX13(v) \
+ (((v) << 8) & BM_PXP_WFE_A_STAGE3_MUX3_MUX13)
+#define BP_PXP_WFE_A_STAGE3_MUX3_RSVD3 6
+#define BM_PXP_WFE_A_STAGE3_MUX3_RSVD3 0x000000C0
+#define BF_PXP_WFE_A_STAGE3_MUX3_RSVD3(v) \
+ (((v) << 6) & BM_PXP_WFE_A_STAGE3_MUX3_RSVD3)
+#define BP_PXP_WFE_A_STAGE3_MUX3_MUX12 0
+#define BM_PXP_WFE_A_STAGE3_MUX3_MUX12 0x0000003F
+#define BF_PXP_WFE_A_STAGE3_MUX3_MUX12(v) \
+ (((v) << 0) & BM_PXP_WFE_A_STAGE3_MUX3_MUX12)
+
+#define HW_PXP_WFE_A_STG1_8X1_OUT0_0 (0x00001870)
+
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_0_LUTOUT31 0x80000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_0_LUTOUT31(v) \
+ (((v) << 31) & BM_PXP_WFE_A_STG1_8X1_OUT0_0_LUTOUT31)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_0_LUTOUT30 0x40000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_0_LUTOUT30(v) \
+ (((v) << 30) & BM_PXP_WFE_A_STG1_8X1_OUT0_0_LUTOUT30)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_0_LUTOUT29 0x20000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_0_LUTOUT29(v) \
+ (((v) << 29) & BM_PXP_WFE_A_STG1_8X1_OUT0_0_LUTOUT29)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_0_LUTOUT28 0x10000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_0_LUTOUT28(v) \
+ (((v) << 28) & BM_PXP_WFE_A_STG1_8X1_OUT0_0_LUTOUT28)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_0_LUTOUT27 0x08000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_0_LUTOUT27(v) \
+ (((v) << 27) & BM_PXP_WFE_A_STG1_8X1_OUT0_0_LUTOUT27)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_0_LUTOUT26 0x04000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_0_LUTOUT26(v) \
+ (((v) << 26) & BM_PXP_WFE_A_STG1_8X1_OUT0_0_LUTOUT26)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_0_LUTOUT25 0x02000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_0_LUTOUT25(v) \
+ (((v) << 25) & BM_PXP_WFE_A_STG1_8X1_OUT0_0_LUTOUT25)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_0_LUTOUT24 0x01000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_0_LUTOUT24(v) \
+ (((v) << 24) & BM_PXP_WFE_A_STG1_8X1_OUT0_0_LUTOUT24)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_0_LUTOUT23 0x00800000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_0_LUTOUT23(v) \
+ (((v) << 23) & BM_PXP_WFE_A_STG1_8X1_OUT0_0_LUTOUT23)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_0_LUTOUT22 0x00400000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_0_LUTOUT22(v) \
+ (((v) << 22) & BM_PXP_WFE_A_STG1_8X1_OUT0_0_LUTOUT22)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_0_LUTOUT21 0x00200000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_0_LUTOUT21(v) \
+ (((v) << 21) & BM_PXP_WFE_A_STG1_8X1_OUT0_0_LUTOUT21)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_0_LUTOUT20 0x00100000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_0_LUTOUT20(v) \
+ (((v) << 20) & BM_PXP_WFE_A_STG1_8X1_OUT0_0_LUTOUT20)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_0_LUTOUT19 0x00080000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_0_LUTOUT19(v) \
+ (((v) << 19) & BM_PXP_WFE_A_STG1_8X1_OUT0_0_LUTOUT19)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_0_LUTOUT18 0x00040000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_0_LUTOUT18(v) \
+ (((v) << 18) & BM_PXP_WFE_A_STG1_8X1_OUT0_0_LUTOUT18)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_0_LUTOUT17 0x00020000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_0_LUTOUT17(v) \
+ (((v) << 17) & BM_PXP_WFE_A_STG1_8X1_OUT0_0_LUTOUT17)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_0_LUTOUT16 0x00010000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_0_LUTOUT16(v) \
+ (((v) << 16) & BM_PXP_WFE_A_STG1_8X1_OUT0_0_LUTOUT16)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_0_LUTOUT15 0x00008000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_0_LUTOUT15(v) \
+ (((v) << 15) & BM_PXP_WFE_A_STG1_8X1_OUT0_0_LUTOUT15)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_0_LUTOUT14 0x00004000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_0_LUTOUT14(v) \
+ (((v) << 14) & BM_PXP_WFE_A_STG1_8X1_OUT0_0_LUTOUT14)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_0_LUTOUT13 0x00002000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_0_LUTOUT13(v) \
+ (((v) << 13) & BM_PXP_WFE_A_STG1_8X1_OUT0_0_LUTOUT13)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_0_LUTOUT12 0x00001000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_0_LUTOUT12(v) \
+ (((v) << 12) & BM_PXP_WFE_A_STG1_8X1_OUT0_0_LUTOUT12)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_0_LUTOUT11 0x00000800
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_0_LUTOUT11(v) \
+ (((v) << 11) & BM_PXP_WFE_A_STG1_8X1_OUT0_0_LUTOUT11)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_0_LUTOUT10 0x00000400
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_0_LUTOUT10(v) \
+ (((v) << 10) & BM_PXP_WFE_A_STG1_8X1_OUT0_0_LUTOUT10)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_0_LUTOUT9 0x00000200
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_0_LUTOUT9(v) \
+ (((v) << 9) & BM_PXP_WFE_A_STG1_8X1_OUT0_0_LUTOUT9)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_0_LUTOUT8 0x00000100
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_0_LUTOUT8(v) \
+ (((v) << 8) & BM_PXP_WFE_A_STG1_8X1_OUT0_0_LUTOUT8)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_0_LUTOUT7 0x00000080
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_0_LUTOUT7(v) \
+ (((v) << 7) & BM_PXP_WFE_A_STG1_8X1_OUT0_0_LUTOUT7)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_0_LUTOUT6 0x00000040
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_0_LUTOUT6(v) \
+ (((v) << 6) & BM_PXP_WFE_A_STG1_8X1_OUT0_0_LUTOUT6)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_0_LUTOUT5 0x00000020
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_0_LUTOUT5(v) \
+ (((v) << 5) & BM_PXP_WFE_A_STG1_8X1_OUT0_0_LUTOUT5)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_0_LUTOUT4 0x00000010
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_0_LUTOUT4(v) \
+ (((v) << 4) & BM_PXP_WFE_A_STG1_8X1_OUT0_0_LUTOUT4)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_0_LUTOUT3 0x00000008
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_0_LUTOUT3(v) \
+ (((v) << 3) & BM_PXP_WFE_A_STG1_8X1_OUT0_0_LUTOUT3)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_0_LUTOUT2 0x00000004
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_0_LUTOUT2(v) \
+ (((v) << 2) & BM_PXP_WFE_A_STG1_8X1_OUT0_0_LUTOUT2)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_0_LUTOUT1 0x00000002
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_0_LUTOUT1(v) \
+ (((v) << 1) & BM_PXP_WFE_A_STG1_8X1_OUT0_0_LUTOUT1)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_0_LUTOUT0 0x00000001
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_0_LUTOUT0(v) \
+ (((v) << 0) & BM_PXP_WFE_A_STG1_8X1_OUT0_0_LUTOUT0)
+
+#define HW_PXP_WFE_A_STG1_8X1_OUT0_1 (0x00001880)
+
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_1_LUTOUT63 0x80000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_1_LUTOUT63(v) \
+ (((v) << 31) & BM_PXP_WFE_A_STG1_8X1_OUT0_1_LUTOUT63)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_1_LUTOUT62 0x40000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_1_LUTOUT62(v) \
+ (((v) << 30) & BM_PXP_WFE_A_STG1_8X1_OUT0_1_LUTOUT62)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_1_LUTOUT61 0x20000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_1_LUTOUT61(v) \
+ (((v) << 29) & BM_PXP_WFE_A_STG1_8X1_OUT0_1_LUTOUT61)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_1_LUTOUT60 0x10000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_1_LUTOUT60(v) \
+ (((v) << 28) & BM_PXP_WFE_A_STG1_8X1_OUT0_1_LUTOUT60)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_1_LUTOUT59 0x08000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_1_LUTOUT59(v) \
+ (((v) << 27) & BM_PXP_WFE_A_STG1_8X1_OUT0_1_LUTOUT59)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_1_LUTOUT58 0x04000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_1_LUTOUT58(v) \
+ (((v) << 26) & BM_PXP_WFE_A_STG1_8X1_OUT0_1_LUTOUT58)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_1_LUTOUT57 0x02000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_1_LUTOUT57(v) \
+ (((v) << 25) & BM_PXP_WFE_A_STG1_8X1_OUT0_1_LUTOUT57)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_1_LUTOUT56 0x01000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_1_LUTOUT56(v) \
+ (((v) << 24) & BM_PXP_WFE_A_STG1_8X1_OUT0_1_LUTOUT56)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_1_LUTOUT55 0x00800000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_1_LUTOUT55(v) \
+ (((v) << 23) & BM_PXP_WFE_A_STG1_8X1_OUT0_1_LUTOUT55)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_1_LUTOUT54 0x00400000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_1_LUTOUT54(v) \
+ (((v) << 22) & BM_PXP_WFE_A_STG1_8X1_OUT0_1_LUTOUT54)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_1_LUTOUT53 0x00200000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_1_LUTOUT53(v) \
+ (((v) << 21) & BM_PXP_WFE_A_STG1_8X1_OUT0_1_LUTOUT53)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_1_LUTOUT52 0x00100000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_1_LUTOUT52(v) \
+ (((v) << 20) & BM_PXP_WFE_A_STG1_8X1_OUT0_1_LUTOUT52)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_1_LUTOUT51 0x00080000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_1_LUTOUT51(v) \
+ (((v) << 19) & BM_PXP_WFE_A_STG1_8X1_OUT0_1_LUTOUT51)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_1_LUTOUT50 0x00040000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_1_LUTOUT50(v) \
+ (((v) << 18) & BM_PXP_WFE_A_STG1_8X1_OUT0_1_LUTOUT50)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_1_LUTOUT49 0x00020000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_1_LUTOUT49(v) \
+ (((v) << 17) & BM_PXP_WFE_A_STG1_8X1_OUT0_1_LUTOUT49)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_1_LUTOUT48 0x00010000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_1_LUTOUT48(v) \
+ (((v) << 16) & BM_PXP_WFE_A_STG1_8X1_OUT0_1_LUTOUT48)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_1_LUTOUT47 0x00008000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_1_LUTOUT47(v) \
+ (((v) << 15) & BM_PXP_WFE_A_STG1_8X1_OUT0_1_LUTOUT47)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_1_LUTOUT46 0x00004000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_1_LUTOUT46(v) \
+ (((v) << 14) & BM_PXP_WFE_A_STG1_8X1_OUT0_1_LUTOUT46)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_1_LUTOUT45 0x00002000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_1_LUTOUT45(v) \
+ (((v) << 13) & BM_PXP_WFE_A_STG1_8X1_OUT0_1_LUTOUT45)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_1_LUTOUT44 0x00001000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_1_LUTOUT44(v) \
+ (((v) << 12) & BM_PXP_WFE_A_STG1_8X1_OUT0_1_LUTOUT44)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_1_LUTOUT43 0x00000800
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_1_LUTOUT43(v) \
+ (((v) << 11) & BM_PXP_WFE_A_STG1_8X1_OUT0_1_LUTOUT43)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_1_LUTOUT42 0x00000400
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_1_LUTOUT42(v) \
+ (((v) << 10) & BM_PXP_WFE_A_STG1_8X1_OUT0_1_LUTOUT42)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_1_LUTOUT41 0x00000200
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_1_LUTOUT41(v) \
+ (((v) << 9) & BM_PXP_WFE_A_STG1_8X1_OUT0_1_LUTOUT41)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_1_LUTOUT40 0x00000100
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_1_LUTOUT40(v) \
+ (((v) << 8) & BM_PXP_WFE_A_STG1_8X1_OUT0_1_LUTOUT40)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_1_LUTOUT39 0x00000080
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_1_LUTOUT39(v) \
+ (((v) << 7) & BM_PXP_WFE_A_STG1_8X1_OUT0_1_LUTOUT39)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_1_LUTOUT38 0x00000040
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_1_LUTOUT38(v) \
+ (((v) << 6) & BM_PXP_WFE_A_STG1_8X1_OUT0_1_LUTOUT38)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_1_LUTOUT37 0x00000020
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_1_LUTOUT37(v) \
+ (((v) << 5) & BM_PXP_WFE_A_STG1_8X1_OUT0_1_LUTOUT37)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_1_LUTOUT36 0x00000010
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_1_LUTOUT36(v) \
+ (((v) << 4) & BM_PXP_WFE_A_STG1_8X1_OUT0_1_LUTOUT36)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_1_LUTOUT35 0x00000008
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_1_LUTOUT35(v) \
+ (((v) << 3) & BM_PXP_WFE_A_STG1_8X1_OUT0_1_LUTOUT35)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_1_LUTOUT34 0x00000004
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_1_LUTOUT34(v) \
+ (((v) << 2) & BM_PXP_WFE_A_STG1_8X1_OUT0_1_LUTOUT34)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_1_LUTOUT33 0x00000002
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_1_LUTOUT33(v) \
+ (((v) << 1) & BM_PXP_WFE_A_STG1_8X1_OUT0_1_LUTOUT33)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_1_LUTOUT32 0x00000001
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_1_LUTOUT32(v) \
+ (((v) << 0) & BM_PXP_WFE_A_STG1_8X1_OUT0_1_LUTOUT32)
+
+#define HW_PXP_WFE_A_STG1_8X1_OUT0_2 (0x00001890)
+
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_2_LUTOUT95 0x80000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_2_LUTOUT95(v) \
+ (((v) << 31) & BM_PXP_WFE_A_STG1_8X1_OUT0_2_LUTOUT95)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_2_LUTOUT94 0x40000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_2_LUTOUT94(v) \
+ (((v) << 30) & BM_PXP_WFE_A_STG1_8X1_OUT0_2_LUTOUT94)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_2_LUTOUT93 0x20000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_2_LUTOUT93(v) \
+ (((v) << 29) & BM_PXP_WFE_A_STG1_8X1_OUT0_2_LUTOUT93)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_2_LUTOUT92 0x10000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_2_LUTOUT92(v) \
+ (((v) << 28) & BM_PXP_WFE_A_STG1_8X1_OUT0_2_LUTOUT92)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_2_LUTOUT91 0x08000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_2_LUTOUT91(v) \
+ (((v) << 27) & BM_PXP_WFE_A_STG1_8X1_OUT0_2_LUTOUT91)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_2_LUTOUT90 0x04000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_2_LUTOUT90(v) \
+ (((v) << 26) & BM_PXP_WFE_A_STG1_8X1_OUT0_2_LUTOUT90)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_2_LUTOUT89 0x02000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_2_LUTOUT89(v) \
+ (((v) << 25) & BM_PXP_WFE_A_STG1_8X1_OUT0_2_LUTOUT89)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_2_LUTOUT88 0x01000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_2_LUTOUT88(v) \
+ (((v) << 24) & BM_PXP_WFE_A_STG1_8X1_OUT0_2_LUTOUT88)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_2_LUTOUT87 0x00800000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_2_LUTOUT87(v) \
+ (((v) << 23) & BM_PXP_WFE_A_STG1_8X1_OUT0_2_LUTOUT87)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_2_LUTOUT86 0x00400000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_2_LUTOUT86(v) \
+ (((v) << 22) & BM_PXP_WFE_A_STG1_8X1_OUT0_2_LUTOUT86)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_2_LUTOUT85 0x00200000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_2_LUTOUT85(v) \
+ (((v) << 21) & BM_PXP_WFE_A_STG1_8X1_OUT0_2_LUTOUT85)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_2_LUTOUT84 0x00100000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_2_LUTOUT84(v) \
+ (((v) << 20) & BM_PXP_WFE_A_STG1_8X1_OUT0_2_LUTOUT84)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_2_LUTOUT83 0x00080000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_2_LUTOUT83(v) \
+ (((v) << 19) & BM_PXP_WFE_A_STG1_8X1_OUT0_2_LUTOUT83)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_2_LUTOUT82 0x00040000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_2_LUTOUT82(v) \
+ (((v) << 18) & BM_PXP_WFE_A_STG1_8X1_OUT0_2_LUTOUT82)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_2_LUTOUT81 0x00020000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_2_LUTOUT81(v) \
+ (((v) << 17) & BM_PXP_WFE_A_STG1_8X1_OUT0_2_LUTOUT81)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_2_LUTOUT80 0x00010000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_2_LUTOUT80(v) \
+ (((v) << 16) & BM_PXP_WFE_A_STG1_8X1_OUT0_2_LUTOUT80)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_2_LUTOUT79 0x00008000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_2_LUTOUT79(v) \
+ (((v) << 15) & BM_PXP_WFE_A_STG1_8X1_OUT0_2_LUTOUT79)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_2_LUTOUT78 0x00004000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_2_LUTOUT78(v) \
+ (((v) << 14) & BM_PXP_WFE_A_STG1_8X1_OUT0_2_LUTOUT78)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_2_LUTOUT77 0x00002000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_2_LUTOUT77(v) \
+ (((v) << 13) & BM_PXP_WFE_A_STG1_8X1_OUT0_2_LUTOUT77)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_2_LUTOUT76 0x00001000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_2_LUTOUT76(v) \
+ (((v) << 12) & BM_PXP_WFE_A_STG1_8X1_OUT0_2_LUTOUT76)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_2_LUTOUT75 0x00000800
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_2_LUTOUT75(v) \
+ (((v) << 11) & BM_PXP_WFE_A_STG1_8X1_OUT0_2_LUTOUT75)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_2_LUTOUT74 0x00000400
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_2_LUTOUT74(v) \
+ (((v) << 10) & BM_PXP_WFE_A_STG1_8X1_OUT0_2_LUTOUT74)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_2_LUTOUT73 0x00000200
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_2_LUTOUT73(v) \
+ (((v) << 9) & BM_PXP_WFE_A_STG1_8X1_OUT0_2_LUTOUT73)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_2_LUTOUT72 0x00000100
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_2_LUTOUT72(v) \
+ (((v) << 8) & BM_PXP_WFE_A_STG1_8X1_OUT0_2_LUTOUT72)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_2_LUTOUT71 0x00000080
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_2_LUTOUT71(v) \
+ (((v) << 7) & BM_PXP_WFE_A_STG1_8X1_OUT0_2_LUTOUT71)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_2_LUTOUT70 0x00000040
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_2_LUTOUT70(v) \
+ (((v) << 6) & BM_PXP_WFE_A_STG1_8X1_OUT0_2_LUTOUT70)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_2_LUTOUT69 0x00000020
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_2_LUTOUT69(v) \
+ (((v) << 5) & BM_PXP_WFE_A_STG1_8X1_OUT0_2_LUTOUT69)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_2_LUTOUT68 0x00000010
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_2_LUTOUT68(v) \
+ (((v) << 4) & BM_PXP_WFE_A_STG1_8X1_OUT0_2_LUTOUT68)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_2_LUTOUT67 0x00000008
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_2_LUTOUT67(v) \
+ (((v) << 3) & BM_PXP_WFE_A_STG1_8X1_OUT0_2_LUTOUT67)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_2_LUTOUT66 0x00000004
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_2_LUTOUT66(v) \
+ (((v) << 2) & BM_PXP_WFE_A_STG1_8X1_OUT0_2_LUTOUT66)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_2_LUTOUT65 0x00000002
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_2_LUTOUT65(v) \
+ (((v) << 1) & BM_PXP_WFE_A_STG1_8X1_OUT0_2_LUTOUT65)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_2_LUTOUT64 0x00000001
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_2_LUTOUT64(v) \
+ (((v) << 0) & BM_PXP_WFE_A_STG1_8X1_OUT0_2_LUTOUT64)
+
+#define HW_PXP_WFE_A_STG1_8X1_OUT0_3 (0x000018a0)
+
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_3_LUTOUT127 0x80000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_3_LUTOUT127(v) \
+ (((v) << 31) & BM_PXP_WFE_A_STG1_8X1_OUT0_3_LUTOUT127)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_3_LUTOUT126 0x40000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_3_LUTOUT126(v) \
+ (((v) << 30) & BM_PXP_WFE_A_STG1_8X1_OUT0_3_LUTOUT126)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_3_LUTOUT125 0x20000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_3_LUTOUT125(v) \
+ (((v) << 29) & BM_PXP_WFE_A_STG1_8X1_OUT0_3_LUTOUT125)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_3_LUTOUT124 0x10000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_3_LUTOUT124(v) \
+ (((v) << 28) & BM_PXP_WFE_A_STG1_8X1_OUT0_3_LUTOUT124)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_3_LUTOUT123 0x08000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_3_LUTOUT123(v) \
+ (((v) << 27) & BM_PXP_WFE_A_STG1_8X1_OUT0_3_LUTOUT123)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_3_LUTOUT122 0x04000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_3_LUTOUT122(v) \
+ (((v) << 26) & BM_PXP_WFE_A_STG1_8X1_OUT0_3_LUTOUT122)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_3_LUTOUT121 0x02000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_3_LUTOUT121(v) \
+ (((v) << 25) & BM_PXP_WFE_A_STG1_8X1_OUT0_3_LUTOUT121)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_3_LUTOUT120 0x01000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_3_LUTOUT120(v) \
+ (((v) << 24) & BM_PXP_WFE_A_STG1_8X1_OUT0_3_LUTOUT120)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_3_LUTOUT119 0x00800000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_3_LUTOUT119(v) \
+ (((v) << 23) & BM_PXP_WFE_A_STG1_8X1_OUT0_3_LUTOUT119)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_3_LUTOUT118 0x00400000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_3_LUTOUT118(v) \
+ (((v) << 22) & BM_PXP_WFE_A_STG1_8X1_OUT0_3_LUTOUT118)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_3_LUTOUT117 0x00200000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_3_LUTOUT117(v) \
+ (((v) << 21) & BM_PXP_WFE_A_STG1_8X1_OUT0_3_LUTOUT117)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_3_LUTOUT116 0x00100000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_3_LUTOUT116(v) \
+ (((v) << 20) & BM_PXP_WFE_A_STG1_8X1_OUT0_3_LUTOUT116)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_3_LUTOUT115 0x00080000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_3_LUTOUT115(v) \
+ (((v) << 19) & BM_PXP_WFE_A_STG1_8X1_OUT0_3_LUTOUT115)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_3_LUTOUT114 0x00040000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_3_LUTOUT114(v) \
+ (((v) << 18) & BM_PXP_WFE_A_STG1_8X1_OUT0_3_LUTOUT114)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_3_LUTOUT113 0x00020000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_3_LUTOUT113(v) \
+ (((v) << 17) & BM_PXP_WFE_A_STG1_8X1_OUT0_3_LUTOUT113)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_3_LUTOUT112 0x00010000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_3_LUTOUT112(v) \
+ (((v) << 16) & BM_PXP_WFE_A_STG1_8X1_OUT0_3_LUTOUT112)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_3_LUTOUT111 0x00008000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_3_LUTOUT111(v) \
+ (((v) << 15) & BM_PXP_WFE_A_STG1_8X1_OUT0_3_LUTOUT111)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_3_LUTOUT110 0x00004000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_3_LUTOUT110(v) \
+ (((v) << 14) & BM_PXP_WFE_A_STG1_8X1_OUT0_3_LUTOUT110)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_3_LUTOUT109 0x00002000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_3_LUTOUT109(v) \
+ (((v) << 13) & BM_PXP_WFE_A_STG1_8X1_OUT0_3_LUTOUT109)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_3_LUTOUT108 0x00001000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_3_LUTOUT108(v) \
+ (((v) << 12) & BM_PXP_WFE_A_STG1_8X1_OUT0_3_LUTOUT108)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_3_LUTOUT107 0x00000800
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_3_LUTOUT107(v) \
+ (((v) << 11) & BM_PXP_WFE_A_STG1_8X1_OUT0_3_LUTOUT107)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_3_LUTOUT106 0x00000400
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_3_LUTOUT106(v) \
+ (((v) << 10) & BM_PXP_WFE_A_STG1_8X1_OUT0_3_LUTOUT106)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_3_LUTOUT105 0x00000200
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_3_LUTOUT105(v) \
+ (((v) << 9) & BM_PXP_WFE_A_STG1_8X1_OUT0_3_LUTOUT105)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_3_LUTOUT104 0x00000100
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_3_LUTOUT104(v) \
+ (((v) << 8) & BM_PXP_WFE_A_STG1_8X1_OUT0_3_LUTOUT104)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_3_LUTOUT103 0x00000080
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_3_LUTOUT103(v) \
+ (((v) << 7) & BM_PXP_WFE_A_STG1_8X1_OUT0_3_LUTOUT103)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_3_LUTOUT102 0x00000040
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_3_LUTOUT102(v) \
+ (((v) << 6) & BM_PXP_WFE_A_STG1_8X1_OUT0_3_LUTOUT102)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_3_LUTOUT101 0x00000020
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_3_LUTOUT101(v) \
+ (((v) << 5) & BM_PXP_WFE_A_STG1_8X1_OUT0_3_LUTOUT101)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_3_LUTOUT100 0x00000010
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_3_LUTOUT100(v) \
+ (((v) << 4) & BM_PXP_WFE_A_STG1_8X1_OUT0_3_LUTOUT100)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_3_LUTOUT99 0x00000008
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_3_LUTOUT99(v) \
+ (((v) << 3) & BM_PXP_WFE_A_STG1_8X1_OUT0_3_LUTOUT99)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_3_LUTOUT98 0x00000004
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_3_LUTOUT98(v) \
+ (((v) << 2) & BM_PXP_WFE_A_STG1_8X1_OUT0_3_LUTOUT98)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_3_LUTOUT97 0x00000002
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_3_LUTOUT97(v) \
+ (((v) << 1) & BM_PXP_WFE_A_STG1_8X1_OUT0_3_LUTOUT97)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_3_LUTOUT96 0x00000001
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_3_LUTOUT96(v) \
+ (((v) << 0) & BM_PXP_WFE_A_STG1_8X1_OUT0_3_LUTOUT96)
+
+#define HW_PXP_WFE_A_STG1_8X1_OUT0_4 (0x000018b0)
+
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_4_LUTOUT159 0x80000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_4_LUTOUT159(v) \
+ (((v) << 31) & BM_PXP_WFE_A_STG1_8X1_OUT0_4_LUTOUT159)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_4_LUTOUT158 0x40000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_4_LUTOUT158(v) \
+ (((v) << 30) & BM_PXP_WFE_A_STG1_8X1_OUT0_4_LUTOUT158)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_4_LUTOUT157 0x20000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_4_LUTOUT157(v) \
+ (((v) << 29) & BM_PXP_WFE_A_STG1_8X1_OUT0_4_LUTOUT157)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_4_LUTOUT156 0x10000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_4_LUTOUT156(v) \
+ (((v) << 28) & BM_PXP_WFE_A_STG1_8X1_OUT0_4_LUTOUT156)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_4_LUTOUT155 0x08000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_4_LUTOUT155(v) \
+ (((v) << 27) & BM_PXP_WFE_A_STG1_8X1_OUT0_4_LUTOUT155)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_4_LUTOUT154 0x04000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_4_LUTOUT154(v) \
+ (((v) << 26) & BM_PXP_WFE_A_STG1_8X1_OUT0_4_LUTOUT154)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_4_LUTOUT153 0x02000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_4_LUTOUT153(v) \
+ (((v) << 25) & BM_PXP_WFE_A_STG1_8X1_OUT0_4_LUTOUT153)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_4_LUTOUT152 0x01000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_4_LUTOUT152(v) \
+ (((v) << 24) & BM_PXP_WFE_A_STG1_8X1_OUT0_4_LUTOUT152)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_4_LUTOUT151 0x00800000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_4_LUTOUT151(v) \
+ (((v) << 23) & BM_PXP_WFE_A_STG1_8X1_OUT0_4_LUTOUT151)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_4_LUTOUT150 0x00400000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_4_LUTOUT150(v) \
+ (((v) << 22) & BM_PXP_WFE_A_STG1_8X1_OUT0_4_LUTOUT150)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_4_LUTOUT149 0x00200000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_4_LUTOUT149(v) \
+ (((v) << 21) & BM_PXP_WFE_A_STG1_8X1_OUT0_4_LUTOUT149)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_4_LUTOUT148 0x00100000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_4_LUTOUT148(v) \
+ (((v) << 20) & BM_PXP_WFE_A_STG1_8X1_OUT0_4_LUTOUT148)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_4_LUTOUT147 0x00080000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_4_LUTOUT147(v) \
+ (((v) << 19) & BM_PXP_WFE_A_STG1_8X1_OUT0_4_LUTOUT147)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_4_LUTOUT146 0x00040000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_4_LUTOUT146(v) \
+ (((v) << 18) & BM_PXP_WFE_A_STG1_8X1_OUT0_4_LUTOUT146)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_4_LUTOUT145 0x00020000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_4_LUTOUT145(v) \
+ (((v) << 17) & BM_PXP_WFE_A_STG1_8X1_OUT0_4_LUTOUT145)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_4_LUTOUT144 0x00010000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_4_LUTOUT144(v) \
+ (((v) << 16) & BM_PXP_WFE_A_STG1_8X1_OUT0_4_LUTOUT144)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_4_LUTOUT143 0x00008000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_4_LUTOUT143(v) \
+ (((v) << 15) & BM_PXP_WFE_A_STG1_8X1_OUT0_4_LUTOUT143)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_4_LUTOUT142 0x00004000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_4_LUTOUT142(v) \
+ (((v) << 14) & BM_PXP_WFE_A_STG1_8X1_OUT0_4_LUTOUT142)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_4_LUTOUT141 0x00002000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_4_LUTOUT141(v) \
+ (((v) << 13) & BM_PXP_WFE_A_STG1_8X1_OUT0_4_LUTOUT141)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_4_LUTOUT140 0x00001000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_4_LUTOUT140(v) \
+ (((v) << 12) & BM_PXP_WFE_A_STG1_8X1_OUT0_4_LUTOUT140)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_4_LUTOUT139 0x00000800
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_4_LUTOUT139(v) \
+ (((v) << 11) & BM_PXP_WFE_A_STG1_8X1_OUT0_4_LUTOUT139)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_4_LUTOUT138 0x00000400
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_4_LUTOUT138(v) \
+ (((v) << 10) & BM_PXP_WFE_A_STG1_8X1_OUT0_4_LUTOUT138)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_4_LUTOUT137 0x00000200
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_4_LUTOUT137(v) \
+ (((v) << 9) & BM_PXP_WFE_A_STG1_8X1_OUT0_4_LUTOUT137)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_4_LUTOUT136 0x00000100
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_4_LUTOUT136(v) \
+ (((v) << 8) & BM_PXP_WFE_A_STG1_8X1_OUT0_4_LUTOUT136)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_4_LUTOUT135 0x00000080
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_4_LUTOUT135(v) \
+ (((v) << 7) & BM_PXP_WFE_A_STG1_8X1_OUT0_4_LUTOUT135)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_4_LUTOUT134 0x00000040
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_4_LUTOUT134(v) \
+ (((v) << 6) & BM_PXP_WFE_A_STG1_8X1_OUT0_4_LUTOUT134)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_4_LUTOUT133 0x00000020
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_4_LUTOUT133(v) \
+ (((v) << 5) & BM_PXP_WFE_A_STG1_8X1_OUT0_4_LUTOUT133)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_4_LUTOUT132 0x00000010
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_4_LUTOUT132(v) \
+ (((v) << 4) & BM_PXP_WFE_A_STG1_8X1_OUT0_4_LUTOUT132)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_4_LUTOUT131 0x00000008
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_4_LUTOUT131(v) \
+ (((v) << 3) & BM_PXP_WFE_A_STG1_8X1_OUT0_4_LUTOUT131)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_4_LUTOUT130 0x00000004
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_4_LUTOUT130(v) \
+ (((v) << 2) & BM_PXP_WFE_A_STG1_8X1_OUT0_4_LUTOUT130)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_4_LUTOUT129 0x00000002
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_4_LUTOUT129(v) \
+ (((v) << 1) & BM_PXP_WFE_A_STG1_8X1_OUT0_4_LUTOUT129)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_4_LUTOUT128 0x00000001
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_4_LUTOUT128(v) \
+ (((v) << 0) & BM_PXP_WFE_A_STG1_8X1_OUT0_4_LUTOUT128)
+
+#define HW_PXP_WFE_A_STG1_8X1_OUT0_5 (0x000018c0)
+
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_5_LUTOUT191 0x80000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_5_LUTOUT191(v) \
+ (((v) << 31) & BM_PXP_WFE_A_STG1_8X1_OUT0_5_LUTOUT191)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_5_LUTOUT190 0x40000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_5_LUTOUT190(v) \
+ (((v) << 30) & BM_PXP_WFE_A_STG1_8X1_OUT0_5_LUTOUT190)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_5_LUTOUT189 0x20000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_5_LUTOUT189(v) \
+ (((v) << 29) & BM_PXP_WFE_A_STG1_8X1_OUT0_5_LUTOUT189)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_5_LUTOUT188 0x10000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_5_LUTOUT188(v) \
+ (((v) << 28) & BM_PXP_WFE_A_STG1_8X1_OUT0_5_LUTOUT188)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_5_LUTOUT187 0x08000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_5_LUTOUT187(v) \
+ (((v) << 27) & BM_PXP_WFE_A_STG1_8X1_OUT0_5_LUTOUT187)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_5_LUTOUT186 0x04000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_5_LUTOUT186(v) \
+ (((v) << 26) & BM_PXP_WFE_A_STG1_8X1_OUT0_5_LUTOUT186)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_5_LUTOUT185 0x02000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_5_LUTOUT185(v) \
+ (((v) << 25) & BM_PXP_WFE_A_STG1_8X1_OUT0_5_LUTOUT185)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_5_LUTOUT184 0x01000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_5_LUTOUT184(v) \
+ (((v) << 24) & BM_PXP_WFE_A_STG1_8X1_OUT0_5_LUTOUT184)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_5_LUTOUT183 0x00800000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_5_LUTOUT183(v) \
+ (((v) << 23) & BM_PXP_WFE_A_STG1_8X1_OUT0_5_LUTOUT183)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_5_LUTOUT182 0x00400000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_5_LUTOUT182(v) \
+ (((v) << 22) & BM_PXP_WFE_A_STG1_8X1_OUT0_5_LUTOUT182)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_5_LUTOUT181 0x00200000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_5_LUTOUT181(v) \
+ (((v) << 21) & BM_PXP_WFE_A_STG1_8X1_OUT0_5_LUTOUT181)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_5_LUTOUT180 0x00100000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_5_LUTOUT180(v) \
+ (((v) << 20) & BM_PXP_WFE_A_STG1_8X1_OUT0_5_LUTOUT180)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_5_LUTOUT179 0x00080000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_5_LUTOUT179(v) \
+ (((v) << 19) & BM_PXP_WFE_A_STG1_8X1_OUT0_5_LUTOUT179)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_5_LUTOUT178 0x00040000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_5_LUTOUT178(v) \
+ (((v) << 18) & BM_PXP_WFE_A_STG1_8X1_OUT0_5_LUTOUT178)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_5_LUTOUT177 0x00020000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_5_LUTOUT177(v) \
+ (((v) << 17) & BM_PXP_WFE_A_STG1_8X1_OUT0_5_LUTOUT177)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_5_LUTOUT176 0x00010000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_5_LUTOUT176(v) \
+ (((v) << 16) & BM_PXP_WFE_A_STG1_8X1_OUT0_5_LUTOUT176)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_5_LUTOUT175 0x00008000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_5_LUTOUT175(v) \
+ (((v) << 15) & BM_PXP_WFE_A_STG1_8X1_OUT0_5_LUTOUT175)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_5_LUTOUT174 0x00004000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_5_LUTOUT174(v) \
+ (((v) << 14) & BM_PXP_WFE_A_STG1_8X1_OUT0_5_LUTOUT174)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_5_LUTOUT173 0x00002000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_5_LUTOUT173(v) \
+ (((v) << 13) & BM_PXP_WFE_A_STG1_8X1_OUT0_5_LUTOUT173)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_5_LUTOUT172 0x00001000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_5_LUTOUT172(v) \
+ (((v) << 12) & BM_PXP_WFE_A_STG1_8X1_OUT0_5_LUTOUT172)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_5_LUTOUT171 0x00000800
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_5_LUTOUT171(v) \
+ (((v) << 11) & BM_PXP_WFE_A_STG1_8X1_OUT0_5_LUTOUT171)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_5_LUTOUT170 0x00000400
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_5_LUTOUT170(v) \
+ (((v) << 10) & BM_PXP_WFE_A_STG1_8X1_OUT0_5_LUTOUT170)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_5_LUTOUT169 0x00000200
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_5_LUTOUT169(v) \
+ (((v) << 9) & BM_PXP_WFE_A_STG1_8X1_OUT0_5_LUTOUT169)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_5_LUTOUT168 0x00000100
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_5_LUTOUT168(v) \
+ (((v) << 8) & BM_PXP_WFE_A_STG1_8X1_OUT0_5_LUTOUT168)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_5_LUTOUT167 0x00000080
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_5_LUTOUT167(v) \
+ (((v) << 7) & BM_PXP_WFE_A_STG1_8X1_OUT0_5_LUTOUT167)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_5_LUTOUT166 0x00000040
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_5_LUTOUT166(v) \
+ (((v) << 6) & BM_PXP_WFE_A_STG1_8X1_OUT0_5_LUTOUT166)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_5_LUTOUT165 0x00000020
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_5_LUTOUT165(v) \
+ (((v) << 5) & BM_PXP_WFE_A_STG1_8X1_OUT0_5_LUTOUT165)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_5_LUTOUT164 0x00000010
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_5_LUTOUT164(v) \
+ (((v) << 4) & BM_PXP_WFE_A_STG1_8X1_OUT0_5_LUTOUT164)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_5_LUTOUT163 0x00000008
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_5_LUTOUT163(v) \
+ (((v) << 3) & BM_PXP_WFE_A_STG1_8X1_OUT0_5_LUTOUT163)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_5_LUTOUT162 0x00000004
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_5_LUTOUT162(v) \
+ (((v) << 2) & BM_PXP_WFE_A_STG1_8X1_OUT0_5_LUTOUT162)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_5_LUTOUT161 0x00000002
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_5_LUTOUT161(v) \
+ (((v) << 1) & BM_PXP_WFE_A_STG1_8X1_OUT0_5_LUTOUT161)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_5_LUTOUT160 0x00000001
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_5_LUTOUT160(v) \
+ (((v) << 0) & BM_PXP_WFE_A_STG1_8X1_OUT0_5_LUTOUT160)
+
+#define HW_PXP_WFE_A_STG1_8X1_OUT0_6 (0x000018d0)
+
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_6_LUTOUT223 0x80000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_6_LUTOUT223(v) \
+ (((v) << 31) & BM_PXP_WFE_A_STG1_8X1_OUT0_6_LUTOUT223)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_6_LUTOUT222 0x40000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_6_LUTOUT222(v) \
+ (((v) << 30) & BM_PXP_WFE_A_STG1_8X1_OUT0_6_LUTOUT222)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_6_LUTOUT221 0x20000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_6_LUTOUT221(v) \
+ (((v) << 29) & BM_PXP_WFE_A_STG1_8X1_OUT0_6_LUTOUT221)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_6_LUTOUT220 0x10000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_6_LUTOUT220(v) \
+ (((v) << 28) & BM_PXP_WFE_A_STG1_8X1_OUT0_6_LUTOUT220)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_6_LUTOUT219 0x08000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_6_LUTOUT219(v) \
+ (((v) << 27) & BM_PXP_WFE_A_STG1_8X1_OUT0_6_LUTOUT219)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_6_LUTOUT218 0x04000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_6_LUTOUT218(v) \
+ (((v) << 26) & BM_PXP_WFE_A_STG1_8X1_OUT0_6_LUTOUT218)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_6_LUTOUT217 0x02000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_6_LUTOUT217(v) \
+ (((v) << 25) & BM_PXP_WFE_A_STG1_8X1_OUT0_6_LUTOUT217)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_6_LUTOUT216 0x01000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_6_LUTOUT216(v) \
+ (((v) << 24) & BM_PXP_WFE_A_STG1_8X1_OUT0_6_LUTOUT216)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_6_LUTOUT215 0x00800000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_6_LUTOUT215(v) \
+ (((v) << 23) & BM_PXP_WFE_A_STG1_8X1_OUT0_6_LUTOUT215)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_6_LUTOUT214 0x00400000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_6_LUTOUT214(v) \
+ (((v) << 22) & BM_PXP_WFE_A_STG1_8X1_OUT0_6_LUTOUT214)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_6_LUTOUT213 0x00200000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_6_LUTOUT213(v) \
+ (((v) << 21) & BM_PXP_WFE_A_STG1_8X1_OUT0_6_LUTOUT213)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_6_LUTOUT212 0x00100000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_6_LUTOUT212(v) \
+ (((v) << 20) & BM_PXP_WFE_A_STG1_8X1_OUT0_6_LUTOUT212)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_6_LUTOUT211 0x00080000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_6_LUTOUT211(v) \
+ (((v) << 19) & BM_PXP_WFE_A_STG1_8X1_OUT0_6_LUTOUT211)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_6_LUTOUT210 0x00040000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_6_LUTOUT210(v) \
+ (((v) << 18) & BM_PXP_WFE_A_STG1_8X1_OUT0_6_LUTOUT210)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_6_LUTOUT209 0x00020000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_6_LUTOUT209(v) \
+ (((v) << 17) & BM_PXP_WFE_A_STG1_8X1_OUT0_6_LUTOUT209)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_6_LUTOUT208 0x00010000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_6_LUTOUT208(v) \
+ (((v) << 16) & BM_PXP_WFE_A_STG1_8X1_OUT0_6_LUTOUT208)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_6_LUTOUT207 0x00008000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_6_LUTOUT207(v) \
+ (((v) << 15) & BM_PXP_WFE_A_STG1_8X1_OUT0_6_LUTOUT207)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_6_LUTOUT206 0x00004000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_6_LUTOUT206(v) \
+ (((v) << 14) & BM_PXP_WFE_A_STG1_8X1_OUT0_6_LUTOUT206)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_6_LUTOUT205 0x00002000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_6_LUTOUT205(v) \
+ (((v) << 13) & BM_PXP_WFE_A_STG1_8X1_OUT0_6_LUTOUT205)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_6_LUTOUT204 0x00001000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_6_LUTOUT204(v) \
+ (((v) << 12) & BM_PXP_WFE_A_STG1_8X1_OUT0_6_LUTOUT204)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_6_LUTOUT203 0x00000800
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_6_LUTOUT203(v) \
+ (((v) << 11) & BM_PXP_WFE_A_STG1_8X1_OUT0_6_LUTOUT203)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_6_LUTOUT202 0x00000400
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_6_LUTOUT202(v) \
+ (((v) << 10) & BM_PXP_WFE_A_STG1_8X1_OUT0_6_LUTOUT202)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_6_LUTOUT201 0x00000200
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_6_LUTOUT201(v) \
+ (((v) << 9) & BM_PXP_WFE_A_STG1_8X1_OUT0_6_LUTOUT201)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_6_LUTOUT200 0x00000100
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_6_LUTOUT200(v) \
+ (((v) << 8) & BM_PXP_WFE_A_STG1_8X1_OUT0_6_LUTOUT200)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_6_LUTOUT199 0x00000080
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_6_LUTOUT199(v) \
+ (((v) << 7) & BM_PXP_WFE_A_STG1_8X1_OUT0_6_LUTOUT199)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_6_LUTOUT198 0x00000040
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_6_LUTOUT198(v) \
+ (((v) << 6) & BM_PXP_WFE_A_STG1_8X1_OUT0_6_LUTOUT198)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_6_LUTOUT197 0x00000020
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_6_LUTOUT197(v) \
+ (((v) << 5) & BM_PXP_WFE_A_STG1_8X1_OUT0_6_LUTOUT197)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_6_LUTOUT196 0x00000010
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_6_LUTOUT196(v) \
+ (((v) << 4) & BM_PXP_WFE_A_STG1_8X1_OUT0_6_LUTOUT196)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_6_LUTOUT195 0x00000008
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_6_LUTOUT195(v) \
+ (((v) << 3) & BM_PXP_WFE_A_STG1_8X1_OUT0_6_LUTOUT195)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_6_LUTOUT194 0x00000004
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_6_LUTOUT194(v) \
+ (((v) << 2) & BM_PXP_WFE_A_STG1_8X1_OUT0_6_LUTOUT194)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_6_LUTOUT193 0x00000002
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_6_LUTOUT193(v) \
+ (((v) << 1) & BM_PXP_WFE_A_STG1_8X1_OUT0_6_LUTOUT193)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_6_LUTOUT192 0x00000001
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_6_LUTOUT192(v) \
+ (((v) << 0) & BM_PXP_WFE_A_STG1_8X1_OUT0_6_LUTOUT192)
+
+#define HW_PXP_WFE_A_STG1_8X1_OUT0_7 (0x000018e0)
+
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_7_LUTOUT255 0x80000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_7_LUTOUT255(v) \
+ (((v) << 31) & BM_PXP_WFE_A_STG1_8X1_OUT0_7_LUTOUT255)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_7_LUTOUT254 0x40000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_7_LUTOUT254(v) \
+ (((v) << 30) & BM_PXP_WFE_A_STG1_8X1_OUT0_7_LUTOUT254)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_7_LUTOUT253 0x20000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_7_LUTOUT253(v) \
+ (((v) << 29) & BM_PXP_WFE_A_STG1_8X1_OUT0_7_LUTOUT253)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_7_LUTOUT252 0x10000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_7_LUTOUT252(v) \
+ (((v) << 28) & BM_PXP_WFE_A_STG1_8X1_OUT0_7_LUTOUT252)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_7_LUTOUT251 0x08000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_7_LUTOUT251(v) \
+ (((v) << 27) & BM_PXP_WFE_A_STG1_8X1_OUT0_7_LUTOUT251)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_7_LUTOUT250 0x04000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_7_LUTOUT250(v) \
+ (((v) << 26) & BM_PXP_WFE_A_STG1_8X1_OUT0_7_LUTOUT250)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_7_LUTOUT249 0x02000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_7_LUTOUT249(v) \
+ (((v) << 25) & BM_PXP_WFE_A_STG1_8X1_OUT0_7_LUTOUT249)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_7_LUTOUT248 0x01000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_7_LUTOUT248(v) \
+ (((v) << 24) & BM_PXP_WFE_A_STG1_8X1_OUT0_7_LUTOUT248)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_7_LUTOUT247 0x00800000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_7_LUTOUT247(v) \
+ (((v) << 23) & BM_PXP_WFE_A_STG1_8X1_OUT0_7_LUTOUT247)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_7_LUTOUT246 0x00400000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_7_LUTOUT246(v) \
+ (((v) << 22) & BM_PXP_WFE_A_STG1_8X1_OUT0_7_LUTOUT246)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_7_LUTOUT245 0x00200000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_7_LUTOUT245(v) \
+ (((v) << 21) & BM_PXP_WFE_A_STG1_8X1_OUT0_7_LUTOUT245)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_7_LUTOUT244 0x00100000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_7_LUTOUT244(v) \
+ (((v) << 20) & BM_PXP_WFE_A_STG1_8X1_OUT0_7_LUTOUT244)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_7_LUTOUT243 0x00080000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_7_LUTOUT243(v) \
+ (((v) << 19) & BM_PXP_WFE_A_STG1_8X1_OUT0_7_LUTOUT243)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_7_LUTOUT242 0x00040000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_7_LUTOUT242(v) \
+ (((v) << 18) & BM_PXP_WFE_A_STG1_8X1_OUT0_7_LUTOUT242)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_7_LUTOUT241 0x00020000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_7_LUTOUT241(v) \
+ (((v) << 17) & BM_PXP_WFE_A_STG1_8X1_OUT0_7_LUTOUT241)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_7_LUTOUT240 0x00010000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_7_LUTOUT240(v) \
+ (((v) << 16) & BM_PXP_WFE_A_STG1_8X1_OUT0_7_LUTOUT240)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_7_LUTOUT239 0x00008000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_7_LUTOUT239(v) \
+ (((v) << 15) & BM_PXP_WFE_A_STG1_8X1_OUT0_7_LUTOUT239)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_7_LUTOUT238 0x00004000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_7_LUTOUT238(v) \
+ (((v) << 14) & BM_PXP_WFE_A_STG1_8X1_OUT0_7_LUTOUT238)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_7_LUTOUT237 0x00002000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_7_LUTOUT237(v) \
+ (((v) << 13) & BM_PXP_WFE_A_STG1_8X1_OUT0_7_LUTOUT237)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_7_LUTOUT236 0x00001000
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_7_LUTOUT236(v) \
+ (((v) << 12) & BM_PXP_WFE_A_STG1_8X1_OUT0_7_LUTOUT236)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_7_LUTOUT235 0x00000800
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_7_LUTOUT235(v) \
+ (((v) << 11) & BM_PXP_WFE_A_STG1_8X1_OUT0_7_LUTOUT235)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_7_LUTOUT234 0x00000400
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_7_LUTOUT234(v) \
+ (((v) << 10) & BM_PXP_WFE_A_STG1_8X1_OUT0_7_LUTOUT234)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_7_LUTOUT233 0x00000200
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_7_LUTOUT233(v) \
+ (((v) << 9) & BM_PXP_WFE_A_STG1_8X1_OUT0_7_LUTOUT233)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_7_LUTOUT232 0x00000100
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_7_LUTOUT232(v) \
+ (((v) << 8) & BM_PXP_WFE_A_STG1_8X1_OUT0_7_LUTOUT232)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_7_LUTOUT231 0x00000080
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_7_LUTOUT231(v) \
+ (((v) << 7) & BM_PXP_WFE_A_STG1_8X1_OUT0_7_LUTOUT231)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_7_LUTOUT230 0x00000040
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_7_LUTOUT230(v) \
+ (((v) << 6) & BM_PXP_WFE_A_STG1_8X1_OUT0_7_LUTOUT230)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_7_LUTOUT229 0x00000020
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_7_LUTOUT229(v) \
+ (((v) << 5) & BM_PXP_WFE_A_STG1_8X1_OUT0_7_LUTOUT229)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_7_LUTOUT228 0x00000010
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_7_LUTOUT228(v) \
+ (((v) << 4) & BM_PXP_WFE_A_STG1_8X1_OUT0_7_LUTOUT228)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_7_LUTOUT227 0x00000008
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_7_LUTOUT227(v) \
+ (((v) << 3) & BM_PXP_WFE_A_STG1_8X1_OUT0_7_LUTOUT227)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_7_LUTOUT226 0x00000004
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_7_LUTOUT226(v) \
+ (((v) << 2) & BM_PXP_WFE_A_STG1_8X1_OUT0_7_LUTOUT226)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_7_LUTOUT225 0x00000002
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_7_LUTOUT225(v) \
+ (((v) << 1) & BM_PXP_WFE_A_STG1_8X1_OUT0_7_LUTOUT225)
+#define BM_PXP_WFE_A_STG1_8X1_OUT0_7_LUTOUT224 0x00000001
+#define BF_PXP_WFE_A_STG1_8X1_OUT0_7_LUTOUT224(v) \
+ (((v) << 0) & BM_PXP_WFE_A_STG1_8X1_OUT0_7_LUTOUT224)
+
+#define HW_PXP_WFE_A_STG1_8X1_OUT1_0 (0x000018f0)
+
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_0_LUTOUT31 0x80000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_0_LUTOUT31(v) \
+ (((v) << 31) & BM_PXP_WFE_A_STG1_8X1_OUT1_0_LUTOUT31)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_0_LUTOUT30 0x40000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_0_LUTOUT30(v) \
+ (((v) << 30) & BM_PXP_WFE_A_STG1_8X1_OUT1_0_LUTOUT30)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_0_LUTOUT29 0x20000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_0_LUTOUT29(v) \
+ (((v) << 29) & BM_PXP_WFE_A_STG1_8X1_OUT1_0_LUTOUT29)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_0_LUTOUT28 0x10000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_0_LUTOUT28(v) \
+ (((v) << 28) & BM_PXP_WFE_A_STG1_8X1_OUT1_0_LUTOUT28)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_0_LUTOUT27 0x08000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_0_LUTOUT27(v) \
+ (((v) << 27) & BM_PXP_WFE_A_STG1_8X1_OUT1_0_LUTOUT27)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_0_LUTOUT26 0x04000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_0_LUTOUT26(v) \
+ (((v) << 26) & BM_PXP_WFE_A_STG1_8X1_OUT1_0_LUTOUT26)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_0_LUTOUT25 0x02000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_0_LUTOUT25(v) \
+ (((v) << 25) & BM_PXP_WFE_A_STG1_8X1_OUT1_0_LUTOUT25)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_0_LUTOUT24 0x01000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_0_LUTOUT24(v) \
+ (((v) << 24) & BM_PXP_WFE_A_STG1_8X1_OUT1_0_LUTOUT24)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_0_LUTOUT23 0x00800000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_0_LUTOUT23(v) \
+ (((v) << 23) & BM_PXP_WFE_A_STG1_8X1_OUT1_0_LUTOUT23)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_0_LUTOUT22 0x00400000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_0_LUTOUT22(v) \
+ (((v) << 22) & BM_PXP_WFE_A_STG1_8X1_OUT1_0_LUTOUT22)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_0_LUTOUT21 0x00200000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_0_LUTOUT21(v) \
+ (((v) << 21) & BM_PXP_WFE_A_STG1_8X1_OUT1_0_LUTOUT21)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_0_LUTOUT20 0x00100000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_0_LUTOUT20(v) \
+ (((v) << 20) & BM_PXP_WFE_A_STG1_8X1_OUT1_0_LUTOUT20)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_0_LUTOUT19 0x00080000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_0_LUTOUT19(v) \
+ (((v) << 19) & BM_PXP_WFE_A_STG1_8X1_OUT1_0_LUTOUT19)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_0_LUTOUT18 0x00040000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_0_LUTOUT18(v) \
+ (((v) << 18) & BM_PXP_WFE_A_STG1_8X1_OUT1_0_LUTOUT18)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_0_LUTOUT17 0x00020000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_0_LUTOUT17(v) \
+ (((v) << 17) & BM_PXP_WFE_A_STG1_8X1_OUT1_0_LUTOUT17)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_0_LUTOUT16 0x00010000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_0_LUTOUT16(v) \
+ (((v) << 16) & BM_PXP_WFE_A_STG1_8X1_OUT1_0_LUTOUT16)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_0_LUTOUT15 0x00008000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_0_LUTOUT15(v) \
+ (((v) << 15) & BM_PXP_WFE_A_STG1_8X1_OUT1_0_LUTOUT15)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_0_LUTOUT14 0x00004000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_0_LUTOUT14(v) \
+ (((v) << 14) & BM_PXP_WFE_A_STG1_8X1_OUT1_0_LUTOUT14)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_0_LUTOUT13 0x00002000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_0_LUTOUT13(v) \
+ (((v) << 13) & BM_PXP_WFE_A_STG1_8X1_OUT1_0_LUTOUT13)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_0_LUTOUT12 0x00001000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_0_LUTOUT12(v) \
+ (((v) << 12) & BM_PXP_WFE_A_STG1_8X1_OUT1_0_LUTOUT12)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_0_LUTOUT11 0x00000800
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_0_LUTOUT11(v) \
+ (((v) << 11) & BM_PXP_WFE_A_STG1_8X1_OUT1_0_LUTOUT11)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_0_LUTOUT10 0x00000400
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_0_LUTOUT10(v) \
+ (((v) << 10) & BM_PXP_WFE_A_STG1_8X1_OUT1_0_LUTOUT10)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_0_LUTOUT9 0x00000200
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_0_LUTOUT9(v) \
+ (((v) << 9) & BM_PXP_WFE_A_STG1_8X1_OUT1_0_LUTOUT9)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_0_LUTOUT8 0x00000100
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_0_LUTOUT8(v) \
+ (((v) << 8) & BM_PXP_WFE_A_STG1_8X1_OUT1_0_LUTOUT8)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_0_LUTOUT7 0x00000080
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_0_LUTOUT7(v) \
+ (((v) << 7) & BM_PXP_WFE_A_STG1_8X1_OUT1_0_LUTOUT7)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_0_LUTOUT6 0x00000040
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_0_LUTOUT6(v) \
+ (((v) << 6) & BM_PXP_WFE_A_STG1_8X1_OUT1_0_LUTOUT6)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_0_LUTOUT5 0x00000020
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_0_LUTOUT5(v) \
+ (((v) << 5) & BM_PXP_WFE_A_STG1_8X1_OUT1_0_LUTOUT5)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_0_LUTOUT4 0x00000010
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_0_LUTOUT4(v) \
+ (((v) << 4) & BM_PXP_WFE_A_STG1_8X1_OUT1_0_LUTOUT4)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_0_LUTOUT3 0x00000008
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_0_LUTOUT3(v) \
+ (((v) << 3) & BM_PXP_WFE_A_STG1_8X1_OUT1_0_LUTOUT3)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_0_LUTOUT2 0x00000004
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_0_LUTOUT2(v) \
+ (((v) << 2) & BM_PXP_WFE_A_STG1_8X1_OUT1_0_LUTOUT2)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_0_LUTOUT1 0x00000002
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_0_LUTOUT1(v) \
+ (((v) << 1) & BM_PXP_WFE_A_STG1_8X1_OUT1_0_LUTOUT1)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_0_LUTOUT0 0x00000001
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_0_LUTOUT0(v) \
+ (((v) << 0) & BM_PXP_WFE_A_STG1_8X1_OUT1_0_LUTOUT0)
+
+#define HW_PXP_WFE_A_STG1_8X1_OUT1_1 (0x00001900)
+
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_1_LUTOUT63 0x80000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_1_LUTOUT63(v) \
+ (((v) << 31) & BM_PXP_WFE_A_STG1_8X1_OUT1_1_LUTOUT63)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_1_LUTOUT62 0x40000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_1_LUTOUT62(v) \
+ (((v) << 30) & BM_PXP_WFE_A_STG1_8X1_OUT1_1_LUTOUT62)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_1_LUTOUT61 0x20000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_1_LUTOUT61(v) \
+ (((v) << 29) & BM_PXP_WFE_A_STG1_8X1_OUT1_1_LUTOUT61)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_1_LUTOUT60 0x10000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_1_LUTOUT60(v) \
+ (((v) << 28) & BM_PXP_WFE_A_STG1_8X1_OUT1_1_LUTOUT60)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_1_LUTOUT59 0x08000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_1_LUTOUT59(v) \
+ (((v) << 27) & BM_PXP_WFE_A_STG1_8X1_OUT1_1_LUTOUT59)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_1_LUTOUT58 0x04000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_1_LUTOUT58(v) \
+ (((v) << 26) & BM_PXP_WFE_A_STG1_8X1_OUT1_1_LUTOUT58)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_1_LUTOUT57 0x02000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_1_LUTOUT57(v) \
+ (((v) << 25) & BM_PXP_WFE_A_STG1_8X1_OUT1_1_LUTOUT57)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_1_LUTOUT56 0x01000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_1_LUTOUT56(v) \
+ (((v) << 24) & BM_PXP_WFE_A_STG1_8X1_OUT1_1_LUTOUT56)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_1_LUTOUT55 0x00800000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_1_LUTOUT55(v) \
+ (((v) << 23) & BM_PXP_WFE_A_STG1_8X1_OUT1_1_LUTOUT55)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_1_LUTOUT54 0x00400000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_1_LUTOUT54(v) \
+ (((v) << 22) & BM_PXP_WFE_A_STG1_8X1_OUT1_1_LUTOUT54)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_1_LUTOUT53 0x00200000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_1_LUTOUT53(v) \
+ (((v) << 21) & BM_PXP_WFE_A_STG1_8X1_OUT1_1_LUTOUT53)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_1_LUTOUT52 0x00100000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_1_LUTOUT52(v) \
+ (((v) << 20) & BM_PXP_WFE_A_STG1_8X1_OUT1_1_LUTOUT52)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_1_LUTOUT51 0x00080000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_1_LUTOUT51(v) \
+ (((v) << 19) & BM_PXP_WFE_A_STG1_8X1_OUT1_1_LUTOUT51)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_1_LUTOUT50 0x00040000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_1_LUTOUT50(v) \
+ (((v) << 18) & BM_PXP_WFE_A_STG1_8X1_OUT1_1_LUTOUT50)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_1_LUTOUT49 0x00020000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_1_LUTOUT49(v) \
+ (((v) << 17) & BM_PXP_WFE_A_STG1_8X1_OUT1_1_LUTOUT49)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_1_LUTOUT48 0x00010000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_1_LUTOUT48(v) \
+ (((v) << 16) & BM_PXP_WFE_A_STG1_8X1_OUT1_1_LUTOUT48)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_1_LUTOUT47 0x00008000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_1_LUTOUT47(v) \
+ (((v) << 15) & BM_PXP_WFE_A_STG1_8X1_OUT1_1_LUTOUT47)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_1_LUTOUT46 0x00004000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_1_LUTOUT46(v) \
+ (((v) << 14) & BM_PXP_WFE_A_STG1_8X1_OUT1_1_LUTOUT46)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_1_LUTOUT45 0x00002000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_1_LUTOUT45(v) \
+ (((v) << 13) & BM_PXP_WFE_A_STG1_8X1_OUT1_1_LUTOUT45)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_1_LUTOUT44 0x00001000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_1_LUTOUT44(v) \
+ (((v) << 12) & BM_PXP_WFE_A_STG1_8X1_OUT1_1_LUTOUT44)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_1_LUTOUT43 0x00000800
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_1_LUTOUT43(v) \
+ (((v) << 11) & BM_PXP_WFE_A_STG1_8X1_OUT1_1_LUTOUT43)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_1_LUTOUT42 0x00000400
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_1_LUTOUT42(v) \
+ (((v) << 10) & BM_PXP_WFE_A_STG1_8X1_OUT1_1_LUTOUT42)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_1_LUTOUT41 0x00000200
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_1_LUTOUT41(v) \
+ (((v) << 9) & BM_PXP_WFE_A_STG1_8X1_OUT1_1_LUTOUT41)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_1_LUTOUT40 0x00000100
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_1_LUTOUT40(v) \
+ (((v) << 8) & BM_PXP_WFE_A_STG1_8X1_OUT1_1_LUTOUT40)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_1_LUTOUT39 0x00000080
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_1_LUTOUT39(v) \
+ (((v) << 7) & BM_PXP_WFE_A_STG1_8X1_OUT1_1_LUTOUT39)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_1_LUTOUT38 0x00000040
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_1_LUTOUT38(v) \
+ (((v) << 6) & BM_PXP_WFE_A_STG1_8X1_OUT1_1_LUTOUT38)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_1_LUTOUT37 0x00000020
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_1_LUTOUT37(v) \
+ (((v) << 5) & BM_PXP_WFE_A_STG1_8X1_OUT1_1_LUTOUT37)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_1_LUTOUT36 0x00000010
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_1_LUTOUT36(v) \
+ (((v) << 4) & BM_PXP_WFE_A_STG1_8X1_OUT1_1_LUTOUT36)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_1_LUTOUT35 0x00000008
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_1_LUTOUT35(v) \
+ (((v) << 3) & BM_PXP_WFE_A_STG1_8X1_OUT1_1_LUTOUT35)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_1_LUTOUT34 0x00000004
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_1_LUTOUT34(v) \
+ (((v) << 2) & BM_PXP_WFE_A_STG1_8X1_OUT1_1_LUTOUT34)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_1_LUTOUT33 0x00000002
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_1_LUTOUT33(v) \
+ (((v) << 1) & BM_PXP_WFE_A_STG1_8X1_OUT1_1_LUTOUT33)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_1_LUTOUT32 0x00000001
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_1_LUTOUT32(v) \
+ (((v) << 0) & BM_PXP_WFE_A_STG1_8X1_OUT1_1_LUTOUT32)
+
+#define HW_PXP_WFE_A_STG1_8X1_OUT1_2 (0x00001910)
+
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_2_LUTOUT95 0x80000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_2_LUTOUT95(v) \
+ (((v) << 31) & BM_PXP_WFE_A_STG1_8X1_OUT1_2_LUTOUT95)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_2_LUTOUT94 0x40000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_2_LUTOUT94(v) \
+ (((v) << 30) & BM_PXP_WFE_A_STG1_8X1_OUT1_2_LUTOUT94)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_2_LUTOUT93 0x20000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_2_LUTOUT93(v) \
+ (((v) << 29) & BM_PXP_WFE_A_STG1_8X1_OUT1_2_LUTOUT93)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_2_LUTOUT92 0x10000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_2_LUTOUT92(v) \
+ (((v) << 28) & BM_PXP_WFE_A_STG1_8X1_OUT1_2_LUTOUT92)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_2_LUTOUT91 0x08000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_2_LUTOUT91(v) \
+ (((v) << 27) & BM_PXP_WFE_A_STG1_8X1_OUT1_2_LUTOUT91)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_2_LUTOUT90 0x04000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_2_LUTOUT90(v) \
+ (((v) << 26) & BM_PXP_WFE_A_STG1_8X1_OUT1_2_LUTOUT90)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_2_LUTOUT89 0x02000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_2_LUTOUT89(v) \
+ (((v) << 25) & BM_PXP_WFE_A_STG1_8X1_OUT1_2_LUTOUT89)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_2_LUTOUT88 0x01000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_2_LUTOUT88(v) \
+ (((v) << 24) & BM_PXP_WFE_A_STG1_8X1_OUT1_2_LUTOUT88)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_2_LUTOUT87 0x00800000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_2_LUTOUT87(v) \
+ (((v) << 23) & BM_PXP_WFE_A_STG1_8X1_OUT1_2_LUTOUT87)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_2_LUTOUT86 0x00400000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_2_LUTOUT86(v) \
+ (((v) << 22) & BM_PXP_WFE_A_STG1_8X1_OUT1_2_LUTOUT86)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_2_LUTOUT85 0x00200000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_2_LUTOUT85(v) \
+ (((v) << 21) & BM_PXP_WFE_A_STG1_8X1_OUT1_2_LUTOUT85)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_2_LUTOUT84 0x00100000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_2_LUTOUT84(v) \
+ (((v) << 20) & BM_PXP_WFE_A_STG1_8X1_OUT1_2_LUTOUT84)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_2_LUTOUT83 0x00080000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_2_LUTOUT83(v) \
+ (((v) << 19) & BM_PXP_WFE_A_STG1_8X1_OUT1_2_LUTOUT83)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_2_LUTOUT82 0x00040000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_2_LUTOUT82(v) \
+ (((v) << 18) & BM_PXP_WFE_A_STG1_8X1_OUT1_2_LUTOUT82)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_2_LUTOUT81 0x00020000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_2_LUTOUT81(v) \
+ (((v) << 17) & BM_PXP_WFE_A_STG1_8X1_OUT1_2_LUTOUT81)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_2_LUTOUT80 0x00010000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_2_LUTOUT80(v) \
+ (((v) << 16) & BM_PXP_WFE_A_STG1_8X1_OUT1_2_LUTOUT80)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_2_LUTOUT79 0x00008000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_2_LUTOUT79(v) \
+ (((v) << 15) & BM_PXP_WFE_A_STG1_8X1_OUT1_2_LUTOUT79)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_2_LUTOUT78 0x00004000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_2_LUTOUT78(v) \
+ (((v) << 14) & BM_PXP_WFE_A_STG1_8X1_OUT1_2_LUTOUT78)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_2_LUTOUT77 0x00002000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_2_LUTOUT77(v) \
+ (((v) << 13) & BM_PXP_WFE_A_STG1_8X1_OUT1_2_LUTOUT77)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_2_LUTOUT76 0x00001000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_2_LUTOUT76(v) \
+ (((v) << 12) & BM_PXP_WFE_A_STG1_8X1_OUT1_2_LUTOUT76)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_2_LUTOUT75 0x00000800
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_2_LUTOUT75(v) \
+ (((v) << 11) & BM_PXP_WFE_A_STG1_8X1_OUT1_2_LUTOUT75)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_2_LUTOUT74 0x00000400
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_2_LUTOUT74(v) \
+ (((v) << 10) & BM_PXP_WFE_A_STG1_8X1_OUT1_2_LUTOUT74)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_2_LUTOUT73 0x00000200
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_2_LUTOUT73(v) \
+ (((v) << 9) & BM_PXP_WFE_A_STG1_8X1_OUT1_2_LUTOUT73)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_2_LUTOUT72 0x00000100
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_2_LUTOUT72(v) \
+ (((v) << 8) & BM_PXP_WFE_A_STG1_8X1_OUT1_2_LUTOUT72)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_2_LUTOUT71 0x00000080
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_2_LUTOUT71(v) \
+ (((v) << 7) & BM_PXP_WFE_A_STG1_8X1_OUT1_2_LUTOUT71)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_2_LUTOUT70 0x00000040
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_2_LUTOUT70(v) \
+ (((v) << 6) & BM_PXP_WFE_A_STG1_8X1_OUT1_2_LUTOUT70)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_2_LUTOUT69 0x00000020
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_2_LUTOUT69(v) \
+ (((v) << 5) & BM_PXP_WFE_A_STG1_8X1_OUT1_2_LUTOUT69)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_2_LUTOUT68 0x00000010
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_2_LUTOUT68(v) \
+ (((v) << 4) & BM_PXP_WFE_A_STG1_8X1_OUT1_2_LUTOUT68)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_2_LUTOUT67 0x00000008
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_2_LUTOUT67(v) \
+ (((v) << 3) & BM_PXP_WFE_A_STG1_8X1_OUT1_2_LUTOUT67)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_2_LUTOUT66 0x00000004
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_2_LUTOUT66(v) \
+ (((v) << 2) & BM_PXP_WFE_A_STG1_8X1_OUT1_2_LUTOUT66)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_2_LUTOUT65 0x00000002
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_2_LUTOUT65(v) \
+ (((v) << 1) & BM_PXP_WFE_A_STG1_8X1_OUT1_2_LUTOUT65)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_2_LUTOUT64 0x00000001
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_2_LUTOUT64(v) \
+ (((v) << 0) & BM_PXP_WFE_A_STG1_8X1_OUT1_2_LUTOUT64)
+
+#define HW_PXP_WFE_A_STG1_8X1_OUT1_3 (0x00001920)
+
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_3_LUTOUT127 0x80000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_3_LUTOUT127(v) \
+ (((v) << 31) & BM_PXP_WFE_A_STG1_8X1_OUT1_3_LUTOUT127)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_3_LUTOUT126 0x40000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_3_LUTOUT126(v) \
+ (((v) << 30) & BM_PXP_WFE_A_STG1_8X1_OUT1_3_LUTOUT126)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_3_LUTOUT125 0x20000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_3_LUTOUT125(v) \
+ (((v) << 29) & BM_PXP_WFE_A_STG1_8X1_OUT1_3_LUTOUT125)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_3_LUTOUT124 0x10000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_3_LUTOUT124(v) \
+ (((v) << 28) & BM_PXP_WFE_A_STG1_8X1_OUT1_3_LUTOUT124)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_3_LUTOUT123 0x08000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_3_LUTOUT123(v) \
+ (((v) << 27) & BM_PXP_WFE_A_STG1_8X1_OUT1_3_LUTOUT123)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_3_LUTOUT122 0x04000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_3_LUTOUT122(v) \
+ (((v) << 26) & BM_PXP_WFE_A_STG1_8X1_OUT1_3_LUTOUT122)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_3_LUTOUT121 0x02000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_3_LUTOUT121(v) \
+ (((v) << 25) & BM_PXP_WFE_A_STG1_8X1_OUT1_3_LUTOUT121)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_3_LUTOUT120 0x01000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_3_LUTOUT120(v) \
+ (((v) << 24) & BM_PXP_WFE_A_STG1_8X1_OUT1_3_LUTOUT120)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_3_LUTOUT119 0x00800000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_3_LUTOUT119(v) \
+ (((v) << 23) & BM_PXP_WFE_A_STG1_8X1_OUT1_3_LUTOUT119)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_3_LUTOUT118 0x00400000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_3_LUTOUT118(v) \
+ (((v) << 22) & BM_PXP_WFE_A_STG1_8X1_OUT1_3_LUTOUT118)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_3_LUTOUT117 0x00200000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_3_LUTOUT117(v) \
+ (((v) << 21) & BM_PXP_WFE_A_STG1_8X1_OUT1_3_LUTOUT117)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_3_LUTOUT116 0x00100000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_3_LUTOUT116(v) \
+ (((v) << 20) & BM_PXP_WFE_A_STG1_8X1_OUT1_3_LUTOUT116)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_3_LUTOUT115 0x00080000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_3_LUTOUT115(v) \
+ (((v) << 19) & BM_PXP_WFE_A_STG1_8X1_OUT1_3_LUTOUT115)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_3_LUTOUT114 0x00040000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_3_LUTOUT114(v) \
+ (((v) << 18) & BM_PXP_WFE_A_STG1_8X1_OUT1_3_LUTOUT114)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_3_LUTOUT113 0x00020000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_3_LUTOUT113(v) \
+ (((v) << 17) & BM_PXP_WFE_A_STG1_8X1_OUT1_3_LUTOUT113)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_3_LUTOUT112 0x00010000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_3_LUTOUT112(v) \
+ (((v) << 16) & BM_PXP_WFE_A_STG1_8X1_OUT1_3_LUTOUT112)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_3_LUTOUT111 0x00008000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_3_LUTOUT111(v) \
+ (((v) << 15) & BM_PXP_WFE_A_STG1_8X1_OUT1_3_LUTOUT111)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_3_LUTOUT110 0x00004000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_3_LUTOUT110(v) \
+ (((v) << 14) & BM_PXP_WFE_A_STG1_8X1_OUT1_3_LUTOUT110)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_3_LUTOUT109 0x00002000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_3_LUTOUT109(v) \
+ (((v) << 13) & BM_PXP_WFE_A_STG1_8X1_OUT1_3_LUTOUT109)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_3_LUTOUT108 0x00001000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_3_LUTOUT108(v) \
+ (((v) << 12) & BM_PXP_WFE_A_STG1_8X1_OUT1_3_LUTOUT108)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_3_LUTOUT107 0x00000800
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_3_LUTOUT107(v) \
+ (((v) << 11) & BM_PXP_WFE_A_STG1_8X1_OUT1_3_LUTOUT107)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_3_LUTOUT106 0x00000400
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_3_LUTOUT106(v) \
+ (((v) << 10) & BM_PXP_WFE_A_STG1_8X1_OUT1_3_LUTOUT106)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_3_LUTOUT105 0x00000200
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_3_LUTOUT105(v) \
+ (((v) << 9) & BM_PXP_WFE_A_STG1_8X1_OUT1_3_LUTOUT105)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_3_LUTOUT104 0x00000100
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_3_LUTOUT104(v) \
+ (((v) << 8) & BM_PXP_WFE_A_STG1_8X1_OUT1_3_LUTOUT104)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_3_LUTOUT103 0x00000080
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_3_LUTOUT103(v) \
+ (((v) << 7) & BM_PXP_WFE_A_STG1_8X1_OUT1_3_LUTOUT103)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_3_LUTOUT102 0x00000040
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_3_LUTOUT102(v) \
+ (((v) << 6) & BM_PXP_WFE_A_STG1_8X1_OUT1_3_LUTOUT102)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_3_LUTOUT101 0x00000020
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_3_LUTOUT101(v) \
+ (((v) << 5) & BM_PXP_WFE_A_STG1_8X1_OUT1_3_LUTOUT101)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_3_LUTOUT100 0x00000010
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_3_LUTOUT100(v) \
+ (((v) << 4) & BM_PXP_WFE_A_STG1_8X1_OUT1_3_LUTOUT100)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_3_LUTOUT99 0x00000008
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_3_LUTOUT99(v) \
+ (((v) << 3) & BM_PXP_WFE_A_STG1_8X1_OUT1_3_LUTOUT99)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_3_LUTOUT98 0x00000004
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_3_LUTOUT98(v) \
+ (((v) << 2) & BM_PXP_WFE_A_STG1_8X1_OUT1_3_LUTOUT98)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_3_LUTOUT97 0x00000002
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_3_LUTOUT97(v) \
+ (((v) << 1) & BM_PXP_WFE_A_STG1_8X1_OUT1_3_LUTOUT97)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_3_LUTOUT96 0x00000001
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_3_LUTOUT96(v) \
+ (((v) << 0) & BM_PXP_WFE_A_STG1_8X1_OUT1_3_LUTOUT96)
+
+#define HW_PXP_WFE_A_STG1_8X1_OUT1_4 (0x00001930)
+
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_4_LUTOUT159 0x80000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_4_LUTOUT159(v) \
+ (((v) << 31) & BM_PXP_WFE_A_STG1_8X1_OUT1_4_LUTOUT159)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_4_LUTOUT158 0x40000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_4_LUTOUT158(v) \
+ (((v) << 30) & BM_PXP_WFE_A_STG1_8X1_OUT1_4_LUTOUT158)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_4_LUTOUT157 0x20000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_4_LUTOUT157(v) \
+ (((v) << 29) & BM_PXP_WFE_A_STG1_8X1_OUT1_4_LUTOUT157)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_4_LUTOUT156 0x10000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_4_LUTOUT156(v) \
+ (((v) << 28) & BM_PXP_WFE_A_STG1_8X1_OUT1_4_LUTOUT156)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_4_LUTOUT155 0x08000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_4_LUTOUT155(v) \
+ (((v) << 27) & BM_PXP_WFE_A_STG1_8X1_OUT1_4_LUTOUT155)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_4_LUTOUT154 0x04000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_4_LUTOUT154(v) \
+ (((v) << 26) & BM_PXP_WFE_A_STG1_8X1_OUT1_4_LUTOUT154)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_4_LUTOUT153 0x02000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_4_LUTOUT153(v) \
+ (((v) << 25) & BM_PXP_WFE_A_STG1_8X1_OUT1_4_LUTOUT153)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_4_LUTOUT152 0x01000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_4_LUTOUT152(v) \
+ (((v) << 24) & BM_PXP_WFE_A_STG1_8X1_OUT1_4_LUTOUT152)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_4_LUTOUT151 0x00800000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_4_LUTOUT151(v) \
+ (((v) << 23) & BM_PXP_WFE_A_STG1_8X1_OUT1_4_LUTOUT151)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_4_LUTOUT150 0x00400000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_4_LUTOUT150(v) \
+ (((v) << 22) & BM_PXP_WFE_A_STG1_8X1_OUT1_4_LUTOUT150)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_4_LUTOUT149 0x00200000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_4_LUTOUT149(v) \
+ (((v) << 21) & BM_PXP_WFE_A_STG1_8X1_OUT1_4_LUTOUT149)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_4_LUTOUT148 0x00100000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_4_LUTOUT148(v) \
+ (((v) << 20) & BM_PXP_WFE_A_STG1_8X1_OUT1_4_LUTOUT148)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_4_LUTOUT147 0x00080000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_4_LUTOUT147(v) \
+ (((v) << 19) & BM_PXP_WFE_A_STG1_8X1_OUT1_4_LUTOUT147)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_4_LUTOUT146 0x00040000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_4_LUTOUT146(v) \
+ (((v) << 18) & BM_PXP_WFE_A_STG1_8X1_OUT1_4_LUTOUT146)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_4_LUTOUT145 0x00020000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_4_LUTOUT145(v) \
+ (((v) << 17) & BM_PXP_WFE_A_STG1_8X1_OUT1_4_LUTOUT145)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_4_LUTOUT144 0x00010000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_4_LUTOUT144(v) \
+ (((v) << 16) & BM_PXP_WFE_A_STG1_8X1_OUT1_4_LUTOUT144)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_4_LUTOUT143 0x00008000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_4_LUTOUT143(v) \
+ (((v) << 15) & BM_PXP_WFE_A_STG1_8X1_OUT1_4_LUTOUT143)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_4_LUTOUT142 0x00004000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_4_LUTOUT142(v) \
+ (((v) << 14) & BM_PXP_WFE_A_STG1_8X1_OUT1_4_LUTOUT142)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_4_LUTOUT141 0x00002000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_4_LUTOUT141(v) \
+ (((v) << 13) & BM_PXP_WFE_A_STG1_8X1_OUT1_4_LUTOUT141)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_4_LUTOUT140 0x00001000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_4_LUTOUT140(v) \
+ (((v) << 12) & BM_PXP_WFE_A_STG1_8X1_OUT1_4_LUTOUT140)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_4_LUTOUT139 0x00000800
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_4_LUTOUT139(v) \
+ (((v) << 11) & BM_PXP_WFE_A_STG1_8X1_OUT1_4_LUTOUT139)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_4_LUTOUT138 0x00000400
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_4_LUTOUT138(v) \
+ (((v) << 10) & BM_PXP_WFE_A_STG1_8X1_OUT1_4_LUTOUT138)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_4_LUTOUT137 0x00000200
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_4_LUTOUT137(v) \
+ (((v) << 9) & BM_PXP_WFE_A_STG1_8X1_OUT1_4_LUTOUT137)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_4_LUTOUT136 0x00000100
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_4_LUTOUT136(v) \
+ (((v) << 8) & BM_PXP_WFE_A_STG1_8X1_OUT1_4_LUTOUT136)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_4_LUTOUT135 0x00000080
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_4_LUTOUT135(v) \
+ (((v) << 7) & BM_PXP_WFE_A_STG1_8X1_OUT1_4_LUTOUT135)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_4_LUTOUT134 0x00000040
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_4_LUTOUT134(v) \
+ (((v) << 6) & BM_PXP_WFE_A_STG1_8X1_OUT1_4_LUTOUT134)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_4_LUTOUT133 0x00000020
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_4_LUTOUT133(v) \
+ (((v) << 5) & BM_PXP_WFE_A_STG1_8X1_OUT1_4_LUTOUT133)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_4_LUTOUT132 0x00000010
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_4_LUTOUT132(v) \
+ (((v) << 4) & BM_PXP_WFE_A_STG1_8X1_OUT1_4_LUTOUT132)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_4_LUTOUT131 0x00000008
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_4_LUTOUT131(v) \
+ (((v) << 3) & BM_PXP_WFE_A_STG1_8X1_OUT1_4_LUTOUT131)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_4_LUTOUT130 0x00000004
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_4_LUTOUT130(v) \
+ (((v) << 2) & BM_PXP_WFE_A_STG1_8X1_OUT1_4_LUTOUT130)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_4_LUTOUT129 0x00000002
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_4_LUTOUT129(v) \
+ (((v) << 1) & BM_PXP_WFE_A_STG1_8X1_OUT1_4_LUTOUT129)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_4_LUTOUT128 0x00000001
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_4_LUTOUT128(v) \
+ (((v) << 0) & BM_PXP_WFE_A_STG1_8X1_OUT1_4_LUTOUT128)
+
+#define HW_PXP_WFE_A_STG1_8X1_OUT1_5 (0x00001940)
+
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_5_LUTOUT191 0x80000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_5_LUTOUT191(v) \
+ (((v) << 31) & BM_PXP_WFE_A_STG1_8X1_OUT1_5_LUTOUT191)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_5_LUTOUT190 0x40000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_5_LUTOUT190(v) \
+ (((v) << 30) & BM_PXP_WFE_A_STG1_8X1_OUT1_5_LUTOUT190)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_5_LUTOUT189 0x20000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_5_LUTOUT189(v) \
+ (((v) << 29) & BM_PXP_WFE_A_STG1_8X1_OUT1_5_LUTOUT189)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_5_LUTOUT188 0x10000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_5_LUTOUT188(v) \
+ (((v) << 28) & BM_PXP_WFE_A_STG1_8X1_OUT1_5_LUTOUT188)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_5_LUTOUT187 0x08000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_5_LUTOUT187(v) \
+ (((v) << 27) & BM_PXP_WFE_A_STG1_8X1_OUT1_5_LUTOUT187)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_5_LUTOUT186 0x04000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_5_LUTOUT186(v) \
+ (((v) << 26) & BM_PXP_WFE_A_STG1_8X1_OUT1_5_LUTOUT186)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_5_LUTOUT185 0x02000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_5_LUTOUT185(v) \
+ (((v) << 25) & BM_PXP_WFE_A_STG1_8X1_OUT1_5_LUTOUT185)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_5_LUTOUT184 0x01000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_5_LUTOUT184(v) \
+ (((v) << 24) & BM_PXP_WFE_A_STG1_8X1_OUT1_5_LUTOUT184)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_5_LUTOUT183 0x00800000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_5_LUTOUT183(v) \
+ (((v) << 23) & BM_PXP_WFE_A_STG1_8X1_OUT1_5_LUTOUT183)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_5_LUTOUT182 0x00400000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_5_LUTOUT182(v) \
+ (((v) << 22) & BM_PXP_WFE_A_STG1_8X1_OUT1_5_LUTOUT182)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_5_LUTOUT181 0x00200000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_5_LUTOUT181(v) \
+ (((v) << 21) & BM_PXP_WFE_A_STG1_8X1_OUT1_5_LUTOUT181)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_5_LUTOUT180 0x00100000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_5_LUTOUT180(v) \
+ (((v) << 20) & BM_PXP_WFE_A_STG1_8X1_OUT1_5_LUTOUT180)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_5_LUTOUT179 0x00080000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_5_LUTOUT179(v) \
+ (((v) << 19) & BM_PXP_WFE_A_STG1_8X1_OUT1_5_LUTOUT179)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_5_LUTOUT178 0x00040000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_5_LUTOUT178(v) \
+ (((v) << 18) & BM_PXP_WFE_A_STG1_8X1_OUT1_5_LUTOUT178)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_5_LUTOUT177 0x00020000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_5_LUTOUT177(v) \
+ (((v) << 17) & BM_PXP_WFE_A_STG1_8X1_OUT1_5_LUTOUT177)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_5_LUTOUT176 0x00010000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_5_LUTOUT176(v) \
+ (((v) << 16) & BM_PXP_WFE_A_STG1_8X1_OUT1_5_LUTOUT176)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_5_LUTOUT175 0x00008000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_5_LUTOUT175(v) \
+ (((v) << 15) & BM_PXP_WFE_A_STG1_8X1_OUT1_5_LUTOUT175)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_5_LUTOUT174 0x00004000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_5_LUTOUT174(v) \
+ (((v) << 14) & BM_PXP_WFE_A_STG1_8X1_OUT1_5_LUTOUT174)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_5_LUTOUT173 0x00002000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_5_LUTOUT173(v) \
+ (((v) << 13) & BM_PXP_WFE_A_STG1_8X1_OUT1_5_LUTOUT173)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_5_LUTOUT172 0x00001000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_5_LUTOUT172(v) \
+ (((v) << 12) & BM_PXP_WFE_A_STG1_8X1_OUT1_5_LUTOUT172)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_5_LUTOUT171 0x00000800
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_5_LUTOUT171(v) \
+ (((v) << 11) & BM_PXP_WFE_A_STG1_8X1_OUT1_5_LUTOUT171)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_5_LUTOUT170 0x00000400
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_5_LUTOUT170(v) \
+ (((v) << 10) & BM_PXP_WFE_A_STG1_8X1_OUT1_5_LUTOUT170)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_5_LUTOUT169 0x00000200
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_5_LUTOUT169(v) \
+ (((v) << 9) & BM_PXP_WFE_A_STG1_8X1_OUT1_5_LUTOUT169)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_5_LUTOUT168 0x00000100
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_5_LUTOUT168(v) \
+ (((v) << 8) & BM_PXP_WFE_A_STG1_8X1_OUT1_5_LUTOUT168)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_5_LUTOUT167 0x00000080
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_5_LUTOUT167(v) \
+ (((v) << 7) & BM_PXP_WFE_A_STG1_8X1_OUT1_5_LUTOUT167)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_5_LUTOUT166 0x00000040
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_5_LUTOUT166(v) \
+ (((v) << 6) & BM_PXP_WFE_A_STG1_8X1_OUT1_5_LUTOUT166)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_5_LUTOUT165 0x00000020
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_5_LUTOUT165(v) \
+ (((v) << 5) & BM_PXP_WFE_A_STG1_8X1_OUT1_5_LUTOUT165)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_5_LUTOUT164 0x00000010
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_5_LUTOUT164(v) \
+ (((v) << 4) & BM_PXP_WFE_A_STG1_8X1_OUT1_5_LUTOUT164)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_5_LUTOUT163 0x00000008
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_5_LUTOUT163(v) \
+ (((v) << 3) & BM_PXP_WFE_A_STG1_8X1_OUT1_5_LUTOUT163)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_5_LUTOUT162 0x00000004
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_5_LUTOUT162(v) \
+ (((v) << 2) & BM_PXP_WFE_A_STG1_8X1_OUT1_5_LUTOUT162)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_5_LUTOUT161 0x00000002
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_5_LUTOUT161(v) \
+ (((v) << 1) & BM_PXP_WFE_A_STG1_8X1_OUT1_5_LUTOUT161)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_5_LUTOUT160 0x00000001
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_5_LUTOUT160(v) \
+ (((v) << 0) & BM_PXP_WFE_A_STG1_8X1_OUT1_5_LUTOUT160)
+
+#define HW_PXP_WFE_A_STG1_8X1_OUT1_6 (0x00001950)
+
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_6_LUTOUT223 0x80000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_6_LUTOUT223(v) \
+ (((v) << 31) & BM_PXP_WFE_A_STG1_8X1_OUT1_6_LUTOUT223)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_6_LUTOUT222 0x40000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_6_LUTOUT222(v) \
+ (((v) << 30) & BM_PXP_WFE_A_STG1_8X1_OUT1_6_LUTOUT222)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_6_LUTOUT221 0x20000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_6_LUTOUT221(v) \
+ (((v) << 29) & BM_PXP_WFE_A_STG1_8X1_OUT1_6_LUTOUT221)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_6_LUTOUT220 0x10000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_6_LUTOUT220(v) \
+ (((v) << 28) & BM_PXP_WFE_A_STG1_8X1_OUT1_6_LUTOUT220)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_6_LUTOUT219 0x08000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_6_LUTOUT219(v) \
+ (((v) << 27) & BM_PXP_WFE_A_STG1_8X1_OUT1_6_LUTOUT219)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_6_LUTOUT218 0x04000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_6_LUTOUT218(v) \
+ (((v) << 26) & BM_PXP_WFE_A_STG1_8X1_OUT1_6_LUTOUT218)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_6_LUTOUT217 0x02000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_6_LUTOUT217(v) \
+ (((v) << 25) & BM_PXP_WFE_A_STG1_8X1_OUT1_6_LUTOUT217)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_6_LUTOUT216 0x01000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_6_LUTOUT216(v) \
+ (((v) << 24) & BM_PXP_WFE_A_STG1_8X1_OUT1_6_LUTOUT216)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_6_LUTOUT215 0x00800000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_6_LUTOUT215(v) \
+ (((v) << 23) & BM_PXP_WFE_A_STG1_8X1_OUT1_6_LUTOUT215)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_6_LUTOUT214 0x00400000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_6_LUTOUT214(v) \
+ (((v) << 22) & BM_PXP_WFE_A_STG1_8X1_OUT1_6_LUTOUT214)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_6_LUTOUT213 0x00200000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_6_LUTOUT213(v) \
+ (((v) << 21) & BM_PXP_WFE_A_STG1_8X1_OUT1_6_LUTOUT213)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_6_LUTOUT212 0x00100000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_6_LUTOUT212(v) \
+ (((v) << 20) & BM_PXP_WFE_A_STG1_8X1_OUT1_6_LUTOUT212)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_6_LUTOUT211 0x00080000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_6_LUTOUT211(v) \
+ (((v) << 19) & BM_PXP_WFE_A_STG1_8X1_OUT1_6_LUTOUT211)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_6_LUTOUT210 0x00040000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_6_LUTOUT210(v) \
+ (((v) << 18) & BM_PXP_WFE_A_STG1_8X1_OUT1_6_LUTOUT210)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_6_LUTOUT209 0x00020000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_6_LUTOUT209(v) \
+ (((v) << 17) & BM_PXP_WFE_A_STG1_8X1_OUT1_6_LUTOUT209)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_6_LUTOUT208 0x00010000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_6_LUTOUT208(v) \
+ (((v) << 16) & BM_PXP_WFE_A_STG1_8X1_OUT1_6_LUTOUT208)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_6_LUTOUT207 0x00008000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_6_LUTOUT207(v) \
+ (((v) << 15) & BM_PXP_WFE_A_STG1_8X1_OUT1_6_LUTOUT207)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_6_LUTOUT206 0x00004000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_6_LUTOUT206(v) \
+ (((v) << 14) & BM_PXP_WFE_A_STG1_8X1_OUT1_6_LUTOUT206)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_6_LUTOUT205 0x00002000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_6_LUTOUT205(v) \
+ (((v) << 13) & BM_PXP_WFE_A_STG1_8X1_OUT1_6_LUTOUT205)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_6_LUTOUT204 0x00001000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_6_LUTOUT204(v) \
+ (((v) << 12) & BM_PXP_WFE_A_STG1_8X1_OUT1_6_LUTOUT204)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_6_LUTOUT203 0x00000800
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_6_LUTOUT203(v) \
+ (((v) << 11) & BM_PXP_WFE_A_STG1_8X1_OUT1_6_LUTOUT203)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_6_LUTOUT202 0x00000400
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_6_LUTOUT202(v) \
+ (((v) << 10) & BM_PXP_WFE_A_STG1_8X1_OUT1_6_LUTOUT202)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_6_LUTOUT201 0x00000200
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_6_LUTOUT201(v) \
+ (((v) << 9) & BM_PXP_WFE_A_STG1_8X1_OUT1_6_LUTOUT201)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_6_LUTOUT200 0x00000100
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_6_LUTOUT200(v) \
+ (((v) << 8) & BM_PXP_WFE_A_STG1_8X1_OUT1_6_LUTOUT200)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_6_LUTOUT199 0x00000080
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_6_LUTOUT199(v) \
+ (((v) << 7) & BM_PXP_WFE_A_STG1_8X1_OUT1_6_LUTOUT199)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_6_LUTOUT198 0x00000040
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_6_LUTOUT198(v) \
+ (((v) << 6) & BM_PXP_WFE_A_STG1_8X1_OUT1_6_LUTOUT198)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_6_LUTOUT197 0x00000020
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_6_LUTOUT197(v) \
+ (((v) << 5) & BM_PXP_WFE_A_STG1_8X1_OUT1_6_LUTOUT197)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_6_LUTOUT196 0x00000010
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_6_LUTOUT196(v) \
+ (((v) << 4) & BM_PXP_WFE_A_STG1_8X1_OUT1_6_LUTOUT196)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_6_LUTOUT195 0x00000008
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_6_LUTOUT195(v) \
+ (((v) << 3) & BM_PXP_WFE_A_STG1_8X1_OUT1_6_LUTOUT195)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_6_LUTOUT194 0x00000004
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_6_LUTOUT194(v) \
+ (((v) << 2) & BM_PXP_WFE_A_STG1_8X1_OUT1_6_LUTOUT194)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_6_LUTOUT193 0x00000002
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_6_LUTOUT193(v) \
+ (((v) << 1) & BM_PXP_WFE_A_STG1_8X1_OUT1_6_LUTOUT193)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_6_LUTOUT192 0x00000001
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_6_LUTOUT192(v) \
+ (((v) << 0) & BM_PXP_WFE_A_STG1_8X1_OUT1_6_LUTOUT192)
+
+#define HW_PXP_WFE_A_STG1_8X1_OUT1_7 (0x00001960)
+
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_7_LUTOUT255 0x80000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_7_LUTOUT255(v) \
+ (((v) << 31) & BM_PXP_WFE_A_STG1_8X1_OUT1_7_LUTOUT255)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_7_LUTOUT254 0x40000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_7_LUTOUT254(v) \
+ (((v) << 30) & BM_PXP_WFE_A_STG1_8X1_OUT1_7_LUTOUT254)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_7_LUTOUT253 0x20000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_7_LUTOUT253(v) \
+ (((v) << 29) & BM_PXP_WFE_A_STG1_8X1_OUT1_7_LUTOUT253)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_7_LUTOUT252 0x10000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_7_LUTOUT252(v) \
+ (((v) << 28) & BM_PXP_WFE_A_STG1_8X1_OUT1_7_LUTOUT252)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_7_LUTOUT251 0x08000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_7_LUTOUT251(v) \
+ (((v) << 27) & BM_PXP_WFE_A_STG1_8X1_OUT1_7_LUTOUT251)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_7_LUTOUT250 0x04000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_7_LUTOUT250(v) \
+ (((v) << 26) & BM_PXP_WFE_A_STG1_8X1_OUT1_7_LUTOUT250)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_7_LUTOUT249 0x02000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_7_LUTOUT249(v) \
+ (((v) << 25) & BM_PXP_WFE_A_STG1_8X1_OUT1_7_LUTOUT249)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_7_LUTOUT248 0x01000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_7_LUTOUT248(v) \
+ (((v) << 24) & BM_PXP_WFE_A_STG1_8X1_OUT1_7_LUTOUT248)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_7_LUTOUT247 0x00800000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_7_LUTOUT247(v) \
+ (((v) << 23) & BM_PXP_WFE_A_STG1_8X1_OUT1_7_LUTOUT247)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_7_LUTOUT246 0x00400000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_7_LUTOUT246(v) \
+ (((v) << 22) & BM_PXP_WFE_A_STG1_8X1_OUT1_7_LUTOUT246)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_7_LUTOUT245 0x00200000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_7_LUTOUT245(v) \
+ (((v) << 21) & BM_PXP_WFE_A_STG1_8X1_OUT1_7_LUTOUT245)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_7_LUTOUT244 0x00100000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_7_LUTOUT244(v) \
+ (((v) << 20) & BM_PXP_WFE_A_STG1_8X1_OUT1_7_LUTOUT244)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_7_LUTOUT243 0x00080000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_7_LUTOUT243(v) \
+ (((v) << 19) & BM_PXP_WFE_A_STG1_8X1_OUT1_7_LUTOUT243)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_7_LUTOUT242 0x00040000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_7_LUTOUT242(v) \
+ (((v) << 18) & BM_PXP_WFE_A_STG1_8X1_OUT1_7_LUTOUT242)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_7_LUTOUT241 0x00020000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_7_LUTOUT241(v) \
+ (((v) << 17) & BM_PXP_WFE_A_STG1_8X1_OUT1_7_LUTOUT241)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_7_LUTOUT240 0x00010000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_7_LUTOUT240(v) \
+ (((v) << 16) & BM_PXP_WFE_A_STG1_8X1_OUT1_7_LUTOUT240)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_7_LUTOUT239 0x00008000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_7_LUTOUT239(v) \
+ (((v) << 15) & BM_PXP_WFE_A_STG1_8X1_OUT1_7_LUTOUT239)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_7_LUTOUT238 0x00004000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_7_LUTOUT238(v) \
+ (((v) << 14) & BM_PXP_WFE_A_STG1_8X1_OUT1_7_LUTOUT238)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_7_LUTOUT237 0x00002000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_7_LUTOUT237(v) \
+ (((v) << 13) & BM_PXP_WFE_A_STG1_8X1_OUT1_7_LUTOUT237)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_7_LUTOUT236 0x00001000
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_7_LUTOUT236(v) \
+ (((v) << 12) & BM_PXP_WFE_A_STG1_8X1_OUT1_7_LUTOUT236)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_7_LUTOUT235 0x00000800
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_7_LUTOUT235(v) \
+ (((v) << 11) & BM_PXP_WFE_A_STG1_8X1_OUT1_7_LUTOUT235)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_7_LUTOUT234 0x00000400
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_7_LUTOUT234(v) \
+ (((v) << 10) & BM_PXP_WFE_A_STG1_8X1_OUT1_7_LUTOUT234)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_7_LUTOUT233 0x00000200
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_7_LUTOUT233(v) \
+ (((v) << 9) & BM_PXP_WFE_A_STG1_8X1_OUT1_7_LUTOUT233)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_7_LUTOUT232 0x00000100
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_7_LUTOUT232(v) \
+ (((v) << 8) & BM_PXP_WFE_A_STG1_8X1_OUT1_7_LUTOUT232)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_7_LUTOUT231 0x00000080
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_7_LUTOUT231(v) \
+ (((v) << 7) & BM_PXP_WFE_A_STG1_8X1_OUT1_7_LUTOUT231)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_7_LUTOUT230 0x00000040
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_7_LUTOUT230(v) \
+ (((v) << 6) & BM_PXP_WFE_A_STG1_8X1_OUT1_7_LUTOUT230)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_7_LUTOUT229 0x00000020
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_7_LUTOUT229(v) \
+ (((v) << 5) & BM_PXP_WFE_A_STG1_8X1_OUT1_7_LUTOUT229)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_7_LUTOUT228 0x00000010
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_7_LUTOUT228(v) \
+ (((v) << 4) & BM_PXP_WFE_A_STG1_8X1_OUT1_7_LUTOUT228)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_7_LUTOUT227 0x00000008
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_7_LUTOUT227(v) \
+ (((v) << 3) & BM_PXP_WFE_A_STG1_8X1_OUT1_7_LUTOUT227)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_7_LUTOUT226 0x00000004
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_7_LUTOUT226(v) \
+ (((v) << 2) & BM_PXP_WFE_A_STG1_8X1_OUT1_7_LUTOUT226)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_7_LUTOUT225 0x00000002
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_7_LUTOUT225(v) \
+ (((v) << 1) & BM_PXP_WFE_A_STG1_8X1_OUT1_7_LUTOUT225)
+#define BM_PXP_WFE_A_STG1_8X1_OUT1_7_LUTOUT224 0x00000001
+#define BF_PXP_WFE_A_STG1_8X1_OUT1_7_LUTOUT224(v) \
+ (((v) << 0) & BM_PXP_WFE_A_STG1_8X1_OUT1_7_LUTOUT224)
+
+#define HW_PXP_WFE_A_STG1_8X1_OUT2_0 (0x00001970)
+
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_0_LUTOUT31 0x80000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_0_LUTOUT31(v) \
+ (((v) << 31) & BM_PXP_WFE_A_STG1_8X1_OUT2_0_LUTOUT31)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_0_LUTOUT30 0x40000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_0_LUTOUT30(v) \
+ (((v) << 30) & BM_PXP_WFE_A_STG1_8X1_OUT2_0_LUTOUT30)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_0_LUTOUT29 0x20000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_0_LUTOUT29(v) \
+ (((v) << 29) & BM_PXP_WFE_A_STG1_8X1_OUT2_0_LUTOUT29)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_0_LUTOUT28 0x10000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_0_LUTOUT28(v) \
+ (((v) << 28) & BM_PXP_WFE_A_STG1_8X1_OUT2_0_LUTOUT28)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_0_LUTOUT27 0x08000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_0_LUTOUT27(v) \
+ (((v) << 27) & BM_PXP_WFE_A_STG1_8X1_OUT2_0_LUTOUT27)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_0_LUTOUT26 0x04000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_0_LUTOUT26(v) \
+ (((v) << 26) & BM_PXP_WFE_A_STG1_8X1_OUT2_0_LUTOUT26)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_0_LUTOUT25 0x02000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_0_LUTOUT25(v) \
+ (((v) << 25) & BM_PXP_WFE_A_STG1_8X1_OUT2_0_LUTOUT25)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_0_LUTOUT24 0x01000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_0_LUTOUT24(v) \
+ (((v) << 24) & BM_PXP_WFE_A_STG1_8X1_OUT2_0_LUTOUT24)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_0_LUTOUT23 0x00800000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_0_LUTOUT23(v) \
+ (((v) << 23) & BM_PXP_WFE_A_STG1_8X1_OUT2_0_LUTOUT23)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_0_LUTOUT22 0x00400000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_0_LUTOUT22(v) \
+ (((v) << 22) & BM_PXP_WFE_A_STG1_8X1_OUT2_0_LUTOUT22)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_0_LUTOUT21 0x00200000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_0_LUTOUT21(v) \
+ (((v) << 21) & BM_PXP_WFE_A_STG1_8X1_OUT2_0_LUTOUT21)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_0_LUTOUT20 0x00100000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_0_LUTOUT20(v) \
+ (((v) << 20) & BM_PXP_WFE_A_STG1_8X1_OUT2_0_LUTOUT20)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_0_LUTOUT19 0x00080000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_0_LUTOUT19(v) \
+ (((v) << 19) & BM_PXP_WFE_A_STG1_8X1_OUT2_0_LUTOUT19)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_0_LUTOUT18 0x00040000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_0_LUTOUT18(v) \
+ (((v) << 18) & BM_PXP_WFE_A_STG1_8X1_OUT2_0_LUTOUT18)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_0_LUTOUT17 0x00020000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_0_LUTOUT17(v) \
+ (((v) << 17) & BM_PXP_WFE_A_STG1_8X1_OUT2_0_LUTOUT17)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_0_LUTOUT16 0x00010000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_0_LUTOUT16(v) \
+ (((v) << 16) & BM_PXP_WFE_A_STG1_8X1_OUT2_0_LUTOUT16)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_0_LUTOUT15 0x00008000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_0_LUTOUT15(v) \
+ (((v) << 15) & BM_PXP_WFE_A_STG1_8X1_OUT2_0_LUTOUT15)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_0_LUTOUT14 0x00004000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_0_LUTOUT14(v) \
+ (((v) << 14) & BM_PXP_WFE_A_STG1_8X1_OUT2_0_LUTOUT14)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_0_LUTOUT13 0x00002000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_0_LUTOUT13(v) \
+ (((v) << 13) & BM_PXP_WFE_A_STG1_8X1_OUT2_0_LUTOUT13)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_0_LUTOUT12 0x00001000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_0_LUTOUT12(v) \
+ (((v) << 12) & BM_PXP_WFE_A_STG1_8X1_OUT2_0_LUTOUT12)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_0_LUTOUT11 0x00000800
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_0_LUTOUT11(v) \
+ (((v) << 11) & BM_PXP_WFE_A_STG1_8X1_OUT2_0_LUTOUT11)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_0_LUTOUT10 0x00000400
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_0_LUTOUT10(v) \
+ (((v) << 10) & BM_PXP_WFE_A_STG1_8X1_OUT2_0_LUTOUT10)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_0_LUTOUT9 0x00000200
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_0_LUTOUT9(v) \
+ (((v) << 9) & BM_PXP_WFE_A_STG1_8X1_OUT2_0_LUTOUT9)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_0_LUTOUT8 0x00000100
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_0_LUTOUT8(v) \
+ (((v) << 8) & BM_PXP_WFE_A_STG1_8X1_OUT2_0_LUTOUT8)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_0_LUTOUT7 0x00000080
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_0_LUTOUT7(v) \
+ (((v) << 7) & BM_PXP_WFE_A_STG1_8X1_OUT2_0_LUTOUT7)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_0_LUTOUT6 0x00000040
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_0_LUTOUT6(v) \
+ (((v) << 6) & BM_PXP_WFE_A_STG1_8X1_OUT2_0_LUTOUT6)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_0_LUTOUT5 0x00000020
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_0_LUTOUT5(v) \
+ (((v) << 5) & BM_PXP_WFE_A_STG1_8X1_OUT2_0_LUTOUT5)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_0_LUTOUT4 0x00000010
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_0_LUTOUT4(v) \
+ (((v) << 4) & BM_PXP_WFE_A_STG1_8X1_OUT2_0_LUTOUT4)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_0_LUTOUT3 0x00000008
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_0_LUTOUT3(v) \
+ (((v) << 3) & BM_PXP_WFE_A_STG1_8X1_OUT2_0_LUTOUT3)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_0_LUTOUT2 0x00000004
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_0_LUTOUT2(v) \
+ (((v) << 2) & BM_PXP_WFE_A_STG1_8X1_OUT2_0_LUTOUT2)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_0_LUTOUT1 0x00000002
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_0_LUTOUT1(v) \
+ (((v) << 1) & BM_PXP_WFE_A_STG1_8X1_OUT2_0_LUTOUT1)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_0_LUTOUT0 0x00000001
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_0_LUTOUT0(v) \
+ (((v) << 0) & BM_PXP_WFE_A_STG1_8X1_OUT2_0_LUTOUT0)
+
+#define HW_PXP_WFE_A_STG1_8X1_OUT2_1 (0x00001980)
+
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_1_LUTOUT63 0x80000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_1_LUTOUT63(v) \
+ (((v) << 31) & BM_PXP_WFE_A_STG1_8X1_OUT2_1_LUTOUT63)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_1_LUTOUT62 0x40000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_1_LUTOUT62(v) \
+ (((v) << 30) & BM_PXP_WFE_A_STG1_8X1_OUT2_1_LUTOUT62)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_1_LUTOUT61 0x20000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_1_LUTOUT61(v) \
+ (((v) << 29) & BM_PXP_WFE_A_STG1_8X1_OUT2_1_LUTOUT61)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_1_LUTOUT60 0x10000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_1_LUTOUT60(v) \
+ (((v) << 28) & BM_PXP_WFE_A_STG1_8X1_OUT2_1_LUTOUT60)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_1_LUTOUT59 0x08000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_1_LUTOUT59(v) \
+ (((v) << 27) & BM_PXP_WFE_A_STG1_8X1_OUT2_1_LUTOUT59)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_1_LUTOUT58 0x04000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_1_LUTOUT58(v) \
+ (((v) << 26) & BM_PXP_WFE_A_STG1_8X1_OUT2_1_LUTOUT58)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_1_LUTOUT57 0x02000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_1_LUTOUT57(v) \
+ (((v) << 25) & BM_PXP_WFE_A_STG1_8X1_OUT2_1_LUTOUT57)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_1_LUTOUT56 0x01000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_1_LUTOUT56(v) \
+ (((v) << 24) & BM_PXP_WFE_A_STG1_8X1_OUT2_1_LUTOUT56)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_1_LUTOUT55 0x00800000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_1_LUTOUT55(v) \
+ (((v) << 23) & BM_PXP_WFE_A_STG1_8X1_OUT2_1_LUTOUT55)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_1_LUTOUT54 0x00400000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_1_LUTOUT54(v) \
+ (((v) << 22) & BM_PXP_WFE_A_STG1_8X1_OUT2_1_LUTOUT54)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_1_LUTOUT53 0x00200000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_1_LUTOUT53(v) \
+ (((v) << 21) & BM_PXP_WFE_A_STG1_8X1_OUT2_1_LUTOUT53)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_1_LUTOUT52 0x00100000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_1_LUTOUT52(v) \
+ (((v) << 20) & BM_PXP_WFE_A_STG1_8X1_OUT2_1_LUTOUT52)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_1_LUTOUT51 0x00080000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_1_LUTOUT51(v) \
+ (((v) << 19) & BM_PXP_WFE_A_STG1_8X1_OUT2_1_LUTOUT51)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_1_LUTOUT50 0x00040000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_1_LUTOUT50(v) \
+ (((v) << 18) & BM_PXP_WFE_A_STG1_8X1_OUT2_1_LUTOUT50)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_1_LUTOUT49 0x00020000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_1_LUTOUT49(v) \
+ (((v) << 17) & BM_PXP_WFE_A_STG1_8X1_OUT2_1_LUTOUT49)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_1_LUTOUT48 0x00010000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_1_LUTOUT48(v) \
+ (((v) << 16) & BM_PXP_WFE_A_STG1_8X1_OUT2_1_LUTOUT48)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_1_LUTOUT47 0x00008000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_1_LUTOUT47(v) \
+ (((v) << 15) & BM_PXP_WFE_A_STG1_8X1_OUT2_1_LUTOUT47)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_1_LUTOUT46 0x00004000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_1_LUTOUT46(v) \
+ (((v) << 14) & BM_PXP_WFE_A_STG1_8X1_OUT2_1_LUTOUT46)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_1_LUTOUT45 0x00002000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_1_LUTOUT45(v) \
+ (((v) << 13) & BM_PXP_WFE_A_STG1_8X1_OUT2_1_LUTOUT45)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_1_LUTOUT44 0x00001000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_1_LUTOUT44(v) \
+ (((v) << 12) & BM_PXP_WFE_A_STG1_8X1_OUT2_1_LUTOUT44)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_1_LUTOUT43 0x00000800
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_1_LUTOUT43(v) \
+ (((v) << 11) & BM_PXP_WFE_A_STG1_8X1_OUT2_1_LUTOUT43)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_1_LUTOUT42 0x00000400
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_1_LUTOUT42(v) \
+ (((v) << 10) & BM_PXP_WFE_A_STG1_8X1_OUT2_1_LUTOUT42)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_1_LUTOUT41 0x00000200
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_1_LUTOUT41(v) \
+ (((v) << 9) & BM_PXP_WFE_A_STG1_8X1_OUT2_1_LUTOUT41)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_1_LUTOUT40 0x00000100
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_1_LUTOUT40(v) \
+ (((v) << 8) & BM_PXP_WFE_A_STG1_8X1_OUT2_1_LUTOUT40)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_1_LUTOUT39 0x00000080
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_1_LUTOUT39(v) \
+ (((v) << 7) & BM_PXP_WFE_A_STG1_8X1_OUT2_1_LUTOUT39)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_1_LUTOUT38 0x00000040
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_1_LUTOUT38(v) \
+ (((v) << 6) & BM_PXP_WFE_A_STG1_8X1_OUT2_1_LUTOUT38)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_1_LUTOUT37 0x00000020
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_1_LUTOUT37(v) \
+ (((v) << 5) & BM_PXP_WFE_A_STG1_8X1_OUT2_1_LUTOUT37)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_1_LUTOUT36 0x00000010
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_1_LUTOUT36(v) \
+ (((v) << 4) & BM_PXP_WFE_A_STG1_8X1_OUT2_1_LUTOUT36)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_1_LUTOUT35 0x00000008
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_1_LUTOUT35(v) \
+ (((v) << 3) & BM_PXP_WFE_A_STG1_8X1_OUT2_1_LUTOUT35)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_1_LUTOUT34 0x00000004
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_1_LUTOUT34(v) \
+ (((v) << 2) & BM_PXP_WFE_A_STG1_8X1_OUT2_1_LUTOUT34)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_1_LUTOUT33 0x00000002
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_1_LUTOUT33(v) \
+ (((v) << 1) & BM_PXP_WFE_A_STG1_8X1_OUT2_1_LUTOUT33)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_1_LUTOUT32 0x00000001
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_1_LUTOUT32(v) \
+ (((v) << 0) & BM_PXP_WFE_A_STG1_8X1_OUT2_1_LUTOUT32)
+
+#define HW_PXP_WFE_A_STG1_8X1_OUT2_2 (0x00001990)
+
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_2_LUTOUT95 0x80000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_2_LUTOUT95(v) \
+ (((v) << 31) & BM_PXP_WFE_A_STG1_8X1_OUT2_2_LUTOUT95)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_2_LUTOUT94 0x40000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_2_LUTOUT94(v) \
+ (((v) << 30) & BM_PXP_WFE_A_STG1_8X1_OUT2_2_LUTOUT94)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_2_LUTOUT93 0x20000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_2_LUTOUT93(v) \
+ (((v) << 29) & BM_PXP_WFE_A_STG1_8X1_OUT2_2_LUTOUT93)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_2_LUTOUT92 0x10000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_2_LUTOUT92(v) \
+ (((v) << 28) & BM_PXP_WFE_A_STG1_8X1_OUT2_2_LUTOUT92)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_2_LUTOUT91 0x08000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_2_LUTOUT91(v) \
+ (((v) << 27) & BM_PXP_WFE_A_STG1_8X1_OUT2_2_LUTOUT91)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_2_LUTOUT90 0x04000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_2_LUTOUT90(v) \
+ (((v) << 26) & BM_PXP_WFE_A_STG1_8X1_OUT2_2_LUTOUT90)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_2_LUTOUT89 0x02000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_2_LUTOUT89(v) \
+ (((v) << 25) & BM_PXP_WFE_A_STG1_8X1_OUT2_2_LUTOUT89)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_2_LUTOUT88 0x01000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_2_LUTOUT88(v) \
+ (((v) << 24) & BM_PXP_WFE_A_STG1_8X1_OUT2_2_LUTOUT88)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_2_LUTOUT87 0x00800000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_2_LUTOUT87(v) \
+ (((v) << 23) & BM_PXP_WFE_A_STG1_8X1_OUT2_2_LUTOUT87)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_2_LUTOUT86 0x00400000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_2_LUTOUT86(v) \
+ (((v) << 22) & BM_PXP_WFE_A_STG1_8X1_OUT2_2_LUTOUT86)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_2_LUTOUT85 0x00200000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_2_LUTOUT85(v) \
+ (((v) << 21) & BM_PXP_WFE_A_STG1_8X1_OUT2_2_LUTOUT85)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_2_LUTOUT84 0x00100000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_2_LUTOUT84(v) \
+ (((v) << 20) & BM_PXP_WFE_A_STG1_8X1_OUT2_2_LUTOUT84)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_2_LUTOUT83 0x00080000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_2_LUTOUT83(v) \
+ (((v) << 19) & BM_PXP_WFE_A_STG1_8X1_OUT2_2_LUTOUT83)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_2_LUTOUT82 0x00040000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_2_LUTOUT82(v) \
+ (((v) << 18) & BM_PXP_WFE_A_STG1_8X1_OUT2_2_LUTOUT82)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_2_LUTOUT81 0x00020000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_2_LUTOUT81(v) \
+ (((v) << 17) & BM_PXP_WFE_A_STG1_8X1_OUT2_2_LUTOUT81)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_2_LUTOUT80 0x00010000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_2_LUTOUT80(v) \
+ (((v) << 16) & BM_PXP_WFE_A_STG1_8X1_OUT2_2_LUTOUT80)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_2_LUTOUT79 0x00008000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_2_LUTOUT79(v) \
+ (((v) << 15) & BM_PXP_WFE_A_STG1_8X1_OUT2_2_LUTOUT79)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_2_LUTOUT78 0x00004000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_2_LUTOUT78(v) \
+ (((v) << 14) & BM_PXP_WFE_A_STG1_8X1_OUT2_2_LUTOUT78)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_2_LUTOUT77 0x00002000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_2_LUTOUT77(v) \
+ (((v) << 13) & BM_PXP_WFE_A_STG1_8X1_OUT2_2_LUTOUT77)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_2_LUTOUT76 0x00001000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_2_LUTOUT76(v) \
+ (((v) << 12) & BM_PXP_WFE_A_STG1_8X1_OUT2_2_LUTOUT76)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_2_LUTOUT75 0x00000800
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_2_LUTOUT75(v) \
+ (((v) << 11) & BM_PXP_WFE_A_STG1_8X1_OUT2_2_LUTOUT75)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_2_LUTOUT74 0x00000400
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_2_LUTOUT74(v) \
+ (((v) << 10) & BM_PXP_WFE_A_STG1_8X1_OUT2_2_LUTOUT74)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_2_LUTOUT73 0x00000200
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_2_LUTOUT73(v) \
+ (((v) << 9) & BM_PXP_WFE_A_STG1_8X1_OUT2_2_LUTOUT73)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_2_LUTOUT72 0x00000100
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_2_LUTOUT72(v) \
+ (((v) << 8) & BM_PXP_WFE_A_STG1_8X1_OUT2_2_LUTOUT72)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_2_LUTOUT71 0x00000080
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_2_LUTOUT71(v) \
+ (((v) << 7) & BM_PXP_WFE_A_STG1_8X1_OUT2_2_LUTOUT71)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_2_LUTOUT70 0x00000040
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_2_LUTOUT70(v) \
+ (((v) << 6) & BM_PXP_WFE_A_STG1_8X1_OUT2_2_LUTOUT70)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_2_LUTOUT69 0x00000020
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_2_LUTOUT69(v) \
+ (((v) << 5) & BM_PXP_WFE_A_STG1_8X1_OUT2_2_LUTOUT69)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_2_LUTOUT68 0x00000010
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_2_LUTOUT68(v) \
+ (((v) << 4) & BM_PXP_WFE_A_STG1_8X1_OUT2_2_LUTOUT68)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_2_LUTOUT67 0x00000008
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_2_LUTOUT67(v) \
+ (((v) << 3) & BM_PXP_WFE_A_STG1_8X1_OUT2_2_LUTOUT67)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_2_LUTOUT66 0x00000004
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_2_LUTOUT66(v) \
+ (((v) << 2) & BM_PXP_WFE_A_STG1_8X1_OUT2_2_LUTOUT66)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_2_LUTOUT65 0x00000002
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_2_LUTOUT65(v) \
+ (((v) << 1) & BM_PXP_WFE_A_STG1_8X1_OUT2_2_LUTOUT65)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_2_LUTOUT64 0x00000001
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_2_LUTOUT64(v) \
+ (((v) << 0) & BM_PXP_WFE_A_STG1_8X1_OUT2_2_LUTOUT64)
+
+#define HW_PXP_WFE_A_STG1_8X1_OUT2_3 (0x000019a0)
+
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_3_LUTOUT127 0x80000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_3_LUTOUT127(v) \
+ (((v) << 31) & BM_PXP_WFE_A_STG1_8X1_OUT2_3_LUTOUT127)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_3_LUTOUT126 0x40000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_3_LUTOUT126(v) \
+ (((v) << 30) & BM_PXP_WFE_A_STG1_8X1_OUT2_3_LUTOUT126)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_3_LUTOUT125 0x20000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_3_LUTOUT125(v) \
+ (((v) << 29) & BM_PXP_WFE_A_STG1_8X1_OUT2_3_LUTOUT125)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_3_LUTOUT124 0x10000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_3_LUTOUT124(v) \
+ (((v) << 28) & BM_PXP_WFE_A_STG1_8X1_OUT2_3_LUTOUT124)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_3_LUTOUT123 0x08000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_3_LUTOUT123(v) \
+ (((v) << 27) & BM_PXP_WFE_A_STG1_8X1_OUT2_3_LUTOUT123)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_3_LUTOUT122 0x04000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_3_LUTOUT122(v) \
+ (((v) << 26) & BM_PXP_WFE_A_STG1_8X1_OUT2_3_LUTOUT122)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_3_LUTOUT121 0x02000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_3_LUTOUT121(v) \
+ (((v) << 25) & BM_PXP_WFE_A_STG1_8X1_OUT2_3_LUTOUT121)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_3_LUTOUT120 0x01000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_3_LUTOUT120(v) \
+ (((v) << 24) & BM_PXP_WFE_A_STG1_8X1_OUT2_3_LUTOUT120)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_3_LUTOUT119 0x00800000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_3_LUTOUT119(v) \
+ (((v) << 23) & BM_PXP_WFE_A_STG1_8X1_OUT2_3_LUTOUT119)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_3_LUTOUT118 0x00400000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_3_LUTOUT118(v) \
+ (((v) << 22) & BM_PXP_WFE_A_STG1_8X1_OUT2_3_LUTOUT118)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_3_LUTOUT117 0x00200000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_3_LUTOUT117(v) \
+ (((v) << 21) & BM_PXP_WFE_A_STG1_8X1_OUT2_3_LUTOUT117)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_3_LUTOUT116 0x00100000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_3_LUTOUT116(v) \
+ (((v) << 20) & BM_PXP_WFE_A_STG1_8X1_OUT2_3_LUTOUT116)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_3_LUTOUT115 0x00080000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_3_LUTOUT115(v) \
+ (((v) << 19) & BM_PXP_WFE_A_STG1_8X1_OUT2_3_LUTOUT115)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_3_LUTOUT114 0x00040000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_3_LUTOUT114(v) \
+ (((v) << 18) & BM_PXP_WFE_A_STG1_8X1_OUT2_3_LUTOUT114)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_3_LUTOUT113 0x00020000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_3_LUTOUT113(v) \
+ (((v) << 17) & BM_PXP_WFE_A_STG1_8X1_OUT2_3_LUTOUT113)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_3_LUTOUT112 0x00010000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_3_LUTOUT112(v) \
+ (((v) << 16) & BM_PXP_WFE_A_STG1_8X1_OUT2_3_LUTOUT112)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_3_LUTOUT111 0x00008000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_3_LUTOUT111(v) \
+ (((v) << 15) & BM_PXP_WFE_A_STG1_8X1_OUT2_3_LUTOUT111)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_3_LUTOUT110 0x00004000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_3_LUTOUT110(v) \
+ (((v) << 14) & BM_PXP_WFE_A_STG1_8X1_OUT2_3_LUTOUT110)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_3_LUTOUT109 0x00002000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_3_LUTOUT109(v) \
+ (((v) << 13) & BM_PXP_WFE_A_STG1_8X1_OUT2_3_LUTOUT109)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_3_LUTOUT108 0x00001000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_3_LUTOUT108(v) \
+ (((v) << 12) & BM_PXP_WFE_A_STG1_8X1_OUT2_3_LUTOUT108)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_3_LUTOUT107 0x00000800
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_3_LUTOUT107(v) \
+ (((v) << 11) & BM_PXP_WFE_A_STG1_8X1_OUT2_3_LUTOUT107)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_3_LUTOUT106 0x00000400
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_3_LUTOUT106(v) \
+ (((v) << 10) & BM_PXP_WFE_A_STG1_8X1_OUT2_3_LUTOUT106)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_3_LUTOUT105 0x00000200
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_3_LUTOUT105(v) \
+ (((v) << 9) & BM_PXP_WFE_A_STG1_8X1_OUT2_3_LUTOUT105)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_3_LUTOUT104 0x00000100
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_3_LUTOUT104(v) \
+ (((v) << 8) & BM_PXP_WFE_A_STG1_8X1_OUT2_3_LUTOUT104)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_3_LUTOUT103 0x00000080
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_3_LUTOUT103(v) \
+ (((v) << 7) & BM_PXP_WFE_A_STG1_8X1_OUT2_3_LUTOUT103)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_3_LUTOUT102 0x00000040
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_3_LUTOUT102(v) \
+ (((v) << 6) & BM_PXP_WFE_A_STG1_8X1_OUT2_3_LUTOUT102)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_3_LUTOUT101 0x00000020
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_3_LUTOUT101(v) \
+ (((v) << 5) & BM_PXP_WFE_A_STG1_8X1_OUT2_3_LUTOUT101)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_3_LUTOUT100 0x00000010
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_3_LUTOUT100(v) \
+ (((v) << 4) & BM_PXP_WFE_A_STG1_8X1_OUT2_3_LUTOUT100)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_3_LUTOUT99 0x00000008
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_3_LUTOUT99(v) \
+ (((v) << 3) & BM_PXP_WFE_A_STG1_8X1_OUT2_3_LUTOUT99)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_3_LUTOUT98 0x00000004
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_3_LUTOUT98(v) \
+ (((v) << 2) & BM_PXP_WFE_A_STG1_8X1_OUT2_3_LUTOUT98)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_3_LUTOUT97 0x00000002
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_3_LUTOUT97(v) \
+ (((v) << 1) & BM_PXP_WFE_A_STG1_8X1_OUT2_3_LUTOUT97)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_3_LUTOUT96 0x00000001
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_3_LUTOUT96(v) \
+ (((v) << 0) & BM_PXP_WFE_A_STG1_8X1_OUT2_3_LUTOUT96)
+
+#define HW_PXP_WFE_A_STG1_8X1_OUT2_4 (0x000019b0)
+
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_4_LUTOUT159 0x80000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_4_LUTOUT159(v) \
+ (((v) << 31) & BM_PXP_WFE_A_STG1_8X1_OUT2_4_LUTOUT159)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_4_LUTOUT158 0x40000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_4_LUTOUT158(v) \
+ (((v) << 30) & BM_PXP_WFE_A_STG1_8X1_OUT2_4_LUTOUT158)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_4_LUTOUT157 0x20000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_4_LUTOUT157(v) \
+ (((v) << 29) & BM_PXP_WFE_A_STG1_8X1_OUT2_4_LUTOUT157)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_4_LUTOUT156 0x10000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_4_LUTOUT156(v) \
+ (((v) << 28) & BM_PXP_WFE_A_STG1_8X1_OUT2_4_LUTOUT156)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_4_LUTOUT155 0x08000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_4_LUTOUT155(v) \
+ (((v) << 27) & BM_PXP_WFE_A_STG1_8X1_OUT2_4_LUTOUT155)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_4_LUTOUT154 0x04000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_4_LUTOUT154(v) \
+ (((v) << 26) & BM_PXP_WFE_A_STG1_8X1_OUT2_4_LUTOUT154)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_4_LUTOUT153 0x02000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_4_LUTOUT153(v) \
+ (((v) << 25) & BM_PXP_WFE_A_STG1_8X1_OUT2_4_LUTOUT153)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_4_LUTOUT152 0x01000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_4_LUTOUT152(v) \
+ (((v) << 24) & BM_PXP_WFE_A_STG1_8X1_OUT2_4_LUTOUT152)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_4_LUTOUT151 0x00800000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_4_LUTOUT151(v) \
+ (((v) << 23) & BM_PXP_WFE_A_STG1_8X1_OUT2_4_LUTOUT151)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_4_LUTOUT150 0x00400000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_4_LUTOUT150(v) \
+ (((v) << 22) & BM_PXP_WFE_A_STG1_8X1_OUT2_4_LUTOUT150)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_4_LUTOUT149 0x00200000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_4_LUTOUT149(v) \
+ (((v) << 21) & BM_PXP_WFE_A_STG1_8X1_OUT2_4_LUTOUT149)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_4_LUTOUT148 0x00100000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_4_LUTOUT148(v) \
+ (((v) << 20) & BM_PXP_WFE_A_STG1_8X1_OUT2_4_LUTOUT148)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_4_LUTOUT147 0x00080000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_4_LUTOUT147(v) \
+ (((v) << 19) & BM_PXP_WFE_A_STG1_8X1_OUT2_4_LUTOUT147)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_4_LUTOUT146 0x00040000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_4_LUTOUT146(v) \
+ (((v) << 18) & BM_PXP_WFE_A_STG1_8X1_OUT2_4_LUTOUT146)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_4_LUTOUT145 0x00020000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_4_LUTOUT145(v) \
+ (((v) << 17) & BM_PXP_WFE_A_STG1_8X1_OUT2_4_LUTOUT145)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_4_LUTOUT144 0x00010000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_4_LUTOUT144(v) \
+ (((v) << 16) & BM_PXP_WFE_A_STG1_8X1_OUT2_4_LUTOUT144)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_4_LUTOUT143 0x00008000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_4_LUTOUT143(v) \
+ (((v) << 15) & BM_PXP_WFE_A_STG1_8X1_OUT2_4_LUTOUT143)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_4_LUTOUT142 0x00004000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_4_LUTOUT142(v) \
+ (((v) << 14) & BM_PXP_WFE_A_STG1_8X1_OUT2_4_LUTOUT142)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_4_LUTOUT141 0x00002000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_4_LUTOUT141(v) \
+ (((v) << 13) & BM_PXP_WFE_A_STG1_8X1_OUT2_4_LUTOUT141)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_4_LUTOUT140 0x00001000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_4_LUTOUT140(v) \
+ (((v) << 12) & BM_PXP_WFE_A_STG1_8X1_OUT2_4_LUTOUT140)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_4_LUTOUT139 0x00000800
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_4_LUTOUT139(v) \
+ (((v) << 11) & BM_PXP_WFE_A_STG1_8X1_OUT2_4_LUTOUT139)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_4_LUTOUT138 0x00000400
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_4_LUTOUT138(v) \
+ (((v) << 10) & BM_PXP_WFE_A_STG1_8X1_OUT2_4_LUTOUT138)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_4_LUTOUT137 0x00000200
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_4_LUTOUT137(v) \
+ (((v) << 9) & BM_PXP_WFE_A_STG1_8X1_OUT2_4_LUTOUT137)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_4_LUTOUT136 0x00000100
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_4_LUTOUT136(v) \
+ (((v) << 8) & BM_PXP_WFE_A_STG1_8X1_OUT2_4_LUTOUT136)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_4_LUTOUT135 0x00000080
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_4_LUTOUT135(v) \
+ (((v) << 7) & BM_PXP_WFE_A_STG1_8X1_OUT2_4_LUTOUT135)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_4_LUTOUT134 0x00000040
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_4_LUTOUT134(v) \
+ (((v) << 6) & BM_PXP_WFE_A_STG1_8X1_OUT2_4_LUTOUT134)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_4_LUTOUT133 0x00000020
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_4_LUTOUT133(v) \
+ (((v) << 5) & BM_PXP_WFE_A_STG1_8X1_OUT2_4_LUTOUT133)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_4_LUTOUT132 0x00000010
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_4_LUTOUT132(v) \
+ (((v) << 4) & BM_PXP_WFE_A_STG1_8X1_OUT2_4_LUTOUT132)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_4_LUTOUT131 0x00000008
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_4_LUTOUT131(v) \
+ (((v) << 3) & BM_PXP_WFE_A_STG1_8X1_OUT2_4_LUTOUT131)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_4_LUTOUT130 0x00000004
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_4_LUTOUT130(v) \
+ (((v) << 2) & BM_PXP_WFE_A_STG1_8X1_OUT2_4_LUTOUT130)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_4_LUTOUT129 0x00000002
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_4_LUTOUT129(v) \
+ (((v) << 1) & BM_PXP_WFE_A_STG1_8X1_OUT2_4_LUTOUT129)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_4_LUTOUT128 0x00000001
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_4_LUTOUT128(v) \
+ (((v) << 0) & BM_PXP_WFE_A_STG1_8X1_OUT2_4_LUTOUT128)
+
+#define HW_PXP_WFE_A_STG1_8X1_OUT2_5 (0x000019c0)
+
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_5_LUTOUT191 0x80000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_5_LUTOUT191(v) \
+ (((v) << 31) & BM_PXP_WFE_A_STG1_8X1_OUT2_5_LUTOUT191)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_5_LUTOUT190 0x40000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_5_LUTOUT190(v) \
+ (((v) << 30) & BM_PXP_WFE_A_STG1_8X1_OUT2_5_LUTOUT190)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_5_LUTOUT189 0x20000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_5_LUTOUT189(v) \
+ (((v) << 29) & BM_PXP_WFE_A_STG1_8X1_OUT2_5_LUTOUT189)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_5_LUTOUT188 0x10000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_5_LUTOUT188(v) \
+ (((v) << 28) & BM_PXP_WFE_A_STG1_8X1_OUT2_5_LUTOUT188)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_5_LUTOUT187 0x08000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_5_LUTOUT187(v) \
+ (((v) << 27) & BM_PXP_WFE_A_STG1_8X1_OUT2_5_LUTOUT187)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_5_LUTOUT186 0x04000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_5_LUTOUT186(v) \
+ (((v) << 26) & BM_PXP_WFE_A_STG1_8X1_OUT2_5_LUTOUT186)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_5_LUTOUT185 0x02000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_5_LUTOUT185(v) \
+ (((v) << 25) & BM_PXP_WFE_A_STG1_8X1_OUT2_5_LUTOUT185)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_5_LUTOUT184 0x01000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_5_LUTOUT184(v) \
+ (((v) << 24) & BM_PXP_WFE_A_STG1_8X1_OUT2_5_LUTOUT184)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_5_LUTOUT183 0x00800000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_5_LUTOUT183(v) \
+ (((v) << 23) & BM_PXP_WFE_A_STG1_8X1_OUT2_5_LUTOUT183)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_5_LUTOUT182 0x00400000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_5_LUTOUT182(v) \
+ (((v) << 22) & BM_PXP_WFE_A_STG1_8X1_OUT2_5_LUTOUT182)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_5_LUTOUT181 0x00200000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_5_LUTOUT181(v) \
+ (((v) << 21) & BM_PXP_WFE_A_STG1_8X1_OUT2_5_LUTOUT181)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_5_LUTOUT180 0x00100000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_5_LUTOUT180(v) \
+ (((v) << 20) & BM_PXP_WFE_A_STG1_8X1_OUT2_5_LUTOUT180)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_5_LUTOUT179 0x00080000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_5_LUTOUT179(v) \
+ (((v) << 19) & BM_PXP_WFE_A_STG1_8X1_OUT2_5_LUTOUT179)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_5_LUTOUT178 0x00040000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_5_LUTOUT178(v) \
+ (((v) << 18) & BM_PXP_WFE_A_STG1_8X1_OUT2_5_LUTOUT178)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_5_LUTOUT177 0x00020000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_5_LUTOUT177(v) \
+ (((v) << 17) & BM_PXP_WFE_A_STG1_8X1_OUT2_5_LUTOUT177)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_5_LUTOUT176 0x00010000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_5_LUTOUT176(v) \
+ (((v) << 16) & BM_PXP_WFE_A_STG1_8X1_OUT2_5_LUTOUT176)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_5_LUTOUT175 0x00008000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_5_LUTOUT175(v) \
+ (((v) << 15) & BM_PXP_WFE_A_STG1_8X1_OUT2_5_LUTOUT175)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_5_LUTOUT174 0x00004000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_5_LUTOUT174(v) \
+ (((v) << 14) & BM_PXP_WFE_A_STG1_8X1_OUT2_5_LUTOUT174)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_5_LUTOUT173 0x00002000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_5_LUTOUT173(v) \
+ (((v) << 13) & BM_PXP_WFE_A_STG1_8X1_OUT2_5_LUTOUT173)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_5_LUTOUT172 0x00001000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_5_LUTOUT172(v) \
+ (((v) << 12) & BM_PXP_WFE_A_STG1_8X1_OUT2_5_LUTOUT172)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_5_LUTOUT171 0x00000800
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_5_LUTOUT171(v) \
+ (((v) << 11) & BM_PXP_WFE_A_STG1_8X1_OUT2_5_LUTOUT171)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_5_LUTOUT170 0x00000400
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_5_LUTOUT170(v) \
+ (((v) << 10) & BM_PXP_WFE_A_STG1_8X1_OUT2_5_LUTOUT170)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_5_LUTOUT169 0x00000200
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_5_LUTOUT169(v) \
+ (((v) << 9) & BM_PXP_WFE_A_STG1_8X1_OUT2_5_LUTOUT169)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_5_LUTOUT168 0x00000100
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_5_LUTOUT168(v) \
+ (((v) << 8) & BM_PXP_WFE_A_STG1_8X1_OUT2_5_LUTOUT168)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_5_LUTOUT167 0x00000080
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_5_LUTOUT167(v) \
+ (((v) << 7) & BM_PXP_WFE_A_STG1_8X1_OUT2_5_LUTOUT167)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_5_LUTOUT166 0x00000040
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_5_LUTOUT166(v) \
+ (((v) << 6) & BM_PXP_WFE_A_STG1_8X1_OUT2_5_LUTOUT166)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_5_LUTOUT165 0x00000020
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_5_LUTOUT165(v) \
+ (((v) << 5) & BM_PXP_WFE_A_STG1_8X1_OUT2_5_LUTOUT165)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_5_LUTOUT164 0x00000010
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_5_LUTOUT164(v) \
+ (((v) << 4) & BM_PXP_WFE_A_STG1_8X1_OUT2_5_LUTOUT164)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_5_LUTOUT163 0x00000008
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_5_LUTOUT163(v) \
+ (((v) << 3) & BM_PXP_WFE_A_STG1_8X1_OUT2_5_LUTOUT163)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_5_LUTOUT162 0x00000004
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_5_LUTOUT162(v) \
+ (((v) << 2) & BM_PXP_WFE_A_STG1_8X1_OUT2_5_LUTOUT162)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_5_LUTOUT161 0x00000002
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_5_LUTOUT161(v) \
+ (((v) << 1) & BM_PXP_WFE_A_STG1_8X1_OUT2_5_LUTOUT161)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_5_LUTOUT160 0x00000001
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_5_LUTOUT160(v) \
+ (((v) << 0) & BM_PXP_WFE_A_STG1_8X1_OUT2_5_LUTOUT160)
+
+#define HW_PXP_WFE_A_STG1_8X1_OUT2_6 (0x000019d0)
+
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_6_LUTOUT223 0x80000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_6_LUTOUT223(v) \
+ (((v) << 31) & BM_PXP_WFE_A_STG1_8X1_OUT2_6_LUTOUT223)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_6_LUTOUT222 0x40000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_6_LUTOUT222(v) \
+ (((v) << 30) & BM_PXP_WFE_A_STG1_8X1_OUT2_6_LUTOUT222)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_6_LUTOUT221 0x20000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_6_LUTOUT221(v) \
+ (((v) << 29) & BM_PXP_WFE_A_STG1_8X1_OUT2_6_LUTOUT221)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_6_LUTOUT220 0x10000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_6_LUTOUT220(v) \
+ (((v) << 28) & BM_PXP_WFE_A_STG1_8X1_OUT2_6_LUTOUT220)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_6_LUTOUT219 0x08000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_6_LUTOUT219(v) \
+ (((v) << 27) & BM_PXP_WFE_A_STG1_8X1_OUT2_6_LUTOUT219)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_6_LUTOUT218 0x04000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_6_LUTOUT218(v) \
+ (((v) << 26) & BM_PXP_WFE_A_STG1_8X1_OUT2_6_LUTOUT218)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_6_LUTOUT217 0x02000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_6_LUTOUT217(v) \
+ (((v) << 25) & BM_PXP_WFE_A_STG1_8X1_OUT2_6_LUTOUT217)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_6_LUTOUT216 0x01000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_6_LUTOUT216(v) \
+ (((v) << 24) & BM_PXP_WFE_A_STG1_8X1_OUT2_6_LUTOUT216)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_6_LUTOUT215 0x00800000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_6_LUTOUT215(v) \
+ (((v) << 23) & BM_PXP_WFE_A_STG1_8X1_OUT2_6_LUTOUT215)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_6_LUTOUT214 0x00400000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_6_LUTOUT214(v) \
+ (((v) << 22) & BM_PXP_WFE_A_STG1_8X1_OUT2_6_LUTOUT214)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_6_LUTOUT213 0x00200000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_6_LUTOUT213(v) \
+ (((v) << 21) & BM_PXP_WFE_A_STG1_8X1_OUT2_6_LUTOUT213)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_6_LUTOUT212 0x00100000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_6_LUTOUT212(v) \
+ (((v) << 20) & BM_PXP_WFE_A_STG1_8X1_OUT2_6_LUTOUT212)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_6_LUTOUT211 0x00080000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_6_LUTOUT211(v) \
+ (((v) << 19) & BM_PXP_WFE_A_STG1_8X1_OUT2_6_LUTOUT211)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_6_LUTOUT210 0x00040000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_6_LUTOUT210(v) \
+ (((v) << 18) & BM_PXP_WFE_A_STG1_8X1_OUT2_6_LUTOUT210)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_6_LUTOUT209 0x00020000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_6_LUTOUT209(v) \
+ (((v) << 17) & BM_PXP_WFE_A_STG1_8X1_OUT2_6_LUTOUT209)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_6_LUTOUT208 0x00010000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_6_LUTOUT208(v) \
+ (((v) << 16) & BM_PXP_WFE_A_STG1_8X1_OUT2_6_LUTOUT208)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_6_LUTOUT207 0x00008000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_6_LUTOUT207(v) \
+ (((v) << 15) & BM_PXP_WFE_A_STG1_8X1_OUT2_6_LUTOUT207)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_6_LUTOUT206 0x00004000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_6_LUTOUT206(v) \
+ (((v) << 14) & BM_PXP_WFE_A_STG1_8X1_OUT2_6_LUTOUT206)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_6_LUTOUT205 0x00002000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_6_LUTOUT205(v) \
+ (((v) << 13) & BM_PXP_WFE_A_STG1_8X1_OUT2_6_LUTOUT205)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_6_LUTOUT204 0x00001000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_6_LUTOUT204(v) \
+ (((v) << 12) & BM_PXP_WFE_A_STG1_8X1_OUT2_6_LUTOUT204)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_6_LUTOUT203 0x00000800
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_6_LUTOUT203(v) \
+ (((v) << 11) & BM_PXP_WFE_A_STG1_8X1_OUT2_6_LUTOUT203)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_6_LUTOUT202 0x00000400
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_6_LUTOUT202(v) \
+ (((v) << 10) & BM_PXP_WFE_A_STG1_8X1_OUT2_6_LUTOUT202)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_6_LUTOUT201 0x00000200
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_6_LUTOUT201(v) \
+ (((v) << 9) & BM_PXP_WFE_A_STG1_8X1_OUT2_6_LUTOUT201)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_6_LUTOUT200 0x00000100
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_6_LUTOUT200(v) \
+ (((v) << 8) & BM_PXP_WFE_A_STG1_8X1_OUT2_6_LUTOUT200)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_6_LUTOUT199 0x00000080
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_6_LUTOUT199(v) \
+ (((v) << 7) & BM_PXP_WFE_A_STG1_8X1_OUT2_6_LUTOUT199)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_6_LUTOUT198 0x00000040
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_6_LUTOUT198(v) \
+ (((v) << 6) & BM_PXP_WFE_A_STG1_8X1_OUT2_6_LUTOUT198)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_6_LUTOUT197 0x00000020
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_6_LUTOUT197(v) \
+ (((v) << 5) & BM_PXP_WFE_A_STG1_8X1_OUT2_6_LUTOUT197)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_6_LUTOUT196 0x00000010
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_6_LUTOUT196(v) \
+ (((v) << 4) & BM_PXP_WFE_A_STG1_8X1_OUT2_6_LUTOUT196)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_6_LUTOUT195 0x00000008
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_6_LUTOUT195(v) \
+ (((v) << 3) & BM_PXP_WFE_A_STG1_8X1_OUT2_6_LUTOUT195)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_6_LUTOUT194 0x00000004
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_6_LUTOUT194(v) \
+ (((v) << 2) & BM_PXP_WFE_A_STG1_8X1_OUT2_6_LUTOUT194)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_6_LUTOUT193 0x00000002
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_6_LUTOUT193(v) \
+ (((v) << 1) & BM_PXP_WFE_A_STG1_8X1_OUT2_6_LUTOUT193)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_6_LUTOUT192 0x00000001
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_6_LUTOUT192(v) \
+ (((v) << 0) & BM_PXP_WFE_A_STG1_8X1_OUT2_6_LUTOUT192)
+
+#define HW_PXP_WFE_A_STG1_8X1_OUT2_7 (0x000019e0)
+
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_7_LUTOUT255 0x80000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_7_LUTOUT255(v) \
+ (((v) << 31) & BM_PXP_WFE_A_STG1_8X1_OUT2_7_LUTOUT255)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_7_LUTOUT254 0x40000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_7_LUTOUT254(v) \
+ (((v) << 30) & BM_PXP_WFE_A_STG1_8X1_OUT2_7_LUTOUT254)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_7_LUTOUT253 0x20000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_7_LUTOUT253(v) \
+ (((v) << 29) & BM_PXP_WFE_A_STG1_8X1_OUT2_7_LUTOUT253)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_7_LUTOUT252 0x10000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_7_LUTOUT252(v) \
+ (((v) << 28) & BM_PXP_WFE_A_STG1_8X1_OUT2_7_LUTOUT252)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_7_LUTOUT251 0x08000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_7_LUTOUT251(v) \
+ (((v) << 27) & BM_PXP_WFE_A_STG1_8X1_OUT2_7_LUTOUT251)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_7_LUTOUT250 0x04000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_7_LUTOUT250(v) \
+ (((v) << 26) & BM_PXP_WFE_A_STG1_8X1_OUT2_7_LUTOUT250)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_7_LUTOUT249 0x02000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_7_LUTOUT249(v) \
+ (((v) << 25) & BM_PXP_WFE_A_STG1_8X1_OUT2_7_LUTOUT249)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_7_LUTOUT248 0x01000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_7_LUTOUT248(v) \
+ (((v) << 24) & BM_PXP_WFE_A_STG1_8X1_OUT2_7_LUTOUT248)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_7_LUTOUT247 0x00800000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_7_LUTOUT247(v) \
+ (((v) << 23) & BM_PXP_WFE_A_STG1_8X1_OUT2_7_LUTOUT247)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_7_LUTOUT246 0x00400000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_7_LUTOUT246(v) \
+ (((v) << 22) & BM_PXP_WFE_A_STG1_8X1_OUT2_7_LUTOUT246)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_7_LUTOUT245 0x00200000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_7_LUTOUT245(v) \
+ (((v) << 21) & BM_PXP_WFE_A_STG1_8X1_OUT2_7_LUTOUT245)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_7_LUTOUT244 0x00100000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_7_LUTOUT244(v) \
+ (((v) << 20) & BM_PXP_WFE_A_STG1_8X1_OUT2_7_LUTOUT244)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_7_LUTOUT243 0x00080000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_7_LUTOUT243(v) \
+ (((v) << 19) & BM_PXP_WFE_A_STG1_8X1_OUT2_7_LUTOUT243)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_7_LUTOUT242 0x00040000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_7_LUTOUT242(v) \
+ (((v) << 18) & BM_PXP_WFE_A_STG1_8X1_OUT2_7_LUTOUT242)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_7_LUTOUT241 0x00020000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_7_LUTOUT241(v) \
+ (((v) << 17) & BM_PXP_WFE_A_STG1_8X1_OUT2_7_LUTOUT241)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_7_LUTOUT240 0x00010000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_7_LUTOUT240(v) \
+ (((v) << 16) & BM_PXP_WFE_A_STG1_8X1_OUT2_7_LUTOUT240)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_7_LUTOUT239 0x00008000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_7_LUTOUT239(v) \
+ (((v) << 15) & BM_PXP_WFE_A_STG1_8X1_OUT2_7_LUTOUT239)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_7_LUTOUT238 0x00004000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_7_LUTOUT238(v) \
+ (((v) << 14) & BM_PXP_WFE_A_STG1_8X1_OUT2_7_LUTOUT238)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_7_LUTOUT237 0x00002000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_7_LUTOUT237(v) \
+ (((v) << 13) & BM_PXP_WFE_A_STG1_8X1_OUT2_7_LUTOUT237)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_7_LUTOUT236 0x00001000
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_7_LUTOUT236(v) \
+ (((v) << 12) & BM_PXP_WFE_A_STG1_8X1_OUT2_7_LUTOUT236)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_7_LUTOUT235 0x00000800
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_7_LUTOUT235(v) \
+ (((v) << 11) & BM_PXP_WFE_A_STG1_8X1_OUT2_7_LUTOUT235)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_7_LUTOUT234 0x00000400
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_7_LUTOUT234(v) \
+ (((v) << 10) & BM_PXP_WFE_A_STG1_8X1_OUT2_7_LUTOUT234)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_7_LUTOUT233 0x00000200
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_7_LUTOUT233(v) \
+ (((v) << 9) & BM_PXP_WFE_A_STG1_8X1_OUT2_7_LUTOUT233)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_7_LUTOUT232 0x00000100
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_7_LUTOUT232(v) \
+ (((v) << 8) & BM_PXP_WFE_A_STG1_8X1_OUT2_7_LUTOUT232)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_7_LUTOUT231 0x00000080
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_7_LUTOUT231(v) \
+ (((v) << 7) & BM_PXP_WFE_A_STG1_8X1_OUT2_7_LUTOUT231)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_7_LUTOUT230 0x00000040
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_7_LUTOUT230(v) \
+ (((v) << 6) & BM_PXP_WFE_A_STG1_8X1_OUT2_7_LUTOUT230)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_7_LUTOUT229 0x00000020
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_7_LUTOUT229(v) \
+ (((v) << 5) & BM_PXP_WFE_A_STG1_8X1_OUT2_7_LUTOUT229)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_7_LUTOUT228 0x00000010
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_7_LUTOUT228(v) \
+ (((v) << 4) & BM_PXP_WFE_A_STG1_8X1_OUT2_7_LUTOUT228)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_7_LUTOUT227 0x00000008
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_7_LUTOUT227(v) \
+ (((v) << 3) & BM_PXP_WFE_A_STG1_8X1_OUT2_7_LUTOUT227)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_7_LUTOUT226 0x00000004
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_7_LUTOUT226(v) \
+ (((v) << 2) & BM_PXP_WFE_A_STG1_8X1_OUT2_7_LUTOUT226)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_7_LUTOUT225 0x00000002
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_7_LUTOUT225(v) \
+ (((v) << 1) & BM_PXP_WFE_A_STG1_8X1_OUT2_7_LUTOUT225)
+#define BM_PXP_WFE_A_STG1_8X1_OUT2_7_LUTOUT224 0x00000001
+#define BF_PXP_WFE_A_STG1_8X1_OUT2_7_LUTOUT224(v) \
+ (((v) << 0) & BM_PXP_WFE_A_STG1_8X1_OUT2_7_LUTOUT224)
+
+#define HW_PXP_WFE_A_STG1_8X1_OUT3_0 (0x000019f0)
+
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_0_LUTOUT31 0x80000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_0_LUTOUT31(v) \
+ (((v) << 31) & BM_PXP_WFE_A_STG1_8X1_OUT3_0_LUTOUT31)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_0_LUTOUT30 0x40000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_0_LUTOUT30(v) \
+ (((v) << 30) & BM_PXP_WFE_A_STG1_8X1_OUT3_0_LUTOUT30)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_0_LUTOUT29 0x20000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_0_LUTOUT29(v) \
+ (((v) << 29) & BM_PXP_WFE_A_STG1_8X1_OUT3_0_LUTOUT29)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_0_LUTOUT28 0x10000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_0_LUTOUT28(v) \
+ (((v) << 28) & BM_PXP_WFE_A_STG1_8X1_OUT3_0_LUTOUT28)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_0_LUTOUT27 0x08000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_0_LUTOUT27(v) \
+ (((v) << 27) & BM_PXP_WFE_A_STG1_8X1_OUT3_0_LUTOUT27)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_0_LUTOUT26 0x04000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_0_LUTOUT26(v) \
+ (((v) << 26) & BM_PXP_WFE_A_STG1_8X1_OUT3_0_LUTOUT26)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_0_LUTOUT25 0x02000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_0_LUTOUT25(v) \
+ (((v) << 25) & BM_PXP_WFE_A_STG1_8X1_OUT3_0_LUTOUT25)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_0_LUTOUT24 0x01000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_0_LUTOUT24(v) \
+ (((v) << 24) & BM_PXP_WFE_A_STG1_8X1_OUT3_0_LUTOUT24)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_0_LUTOUT23 0x00800000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_0_LUTOUT23(v) \
+ (((v) << 23) & BM_PXP_WFE_A_STG1_8X1_OUT3_0_LUTOUT23)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_0_LUTOUT22 0x00400000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_0_LUTOUT22(v) \
+ (((v) << 22) & BM_PXP_WFE_A_STG1_8X1_OUT3_0_LUTOUT22)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_0_LUTOUT21 0x00200000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_0_LUTOUT21(v) \
+ (((v) << 21) & BM_PXP_WFE_A_STG1_8X1_OUT3_0_LUTOUT21)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_0_LUTOUT20 0x00100000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_0_LUTOUT20(v) \
+ (((v) << 20) & BM_PXP_WFE_A_STG1_8X1_OUT3_0_LUTOUT20)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_0_LUTOUT19 0x00080000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_0_LUTOUT19(v) \
+ (((v) << 19) & BM_PXP_WFE_A_STG1_8X1_OUT3_0_LUTOUT19)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_0_LUTOUT18 0x00040000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_0_LUTOUT18(v) \
+ (((v) << 18) & BM_PXP_WFE_A_STG1_8X1_OUT3_0_LUTOUT18)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_0_LUTOUT17 0x00020000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_0_LUTOUT17(v) \
+ (((v) << 17) & BM_PXP_WFE_A_STG1_8X1_OUT3_0_LUTOUT17)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_0_LUTOUT16 0x00010000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_0_LUTOUT16(v) \
+ (((v) << 16) & BM_PXP_WFE_A_STG1_8X1_OUT3_0_LUTOUT16)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_0_LUTOUT15 0x00008000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_0_LUTOUT15(v) \
+ (((v) << 15) & BM_PXP_WFE_A_STG1_8X1_OUT3_0_LUTOUT15)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_0_LUTOUT14 0x00004000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_0_LUTOUT14(v) \
+ (((v) << 14) & BM_PXP_WFE_A_STG1_8X1_OUT3_0_LUTOUT14)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_0_LUTOUT13 0x00002000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_0_LUTOUT13(v) \
+ (((v) << 13) & BM_PXP_WFE_A_STG1_8X1_OUT3_0_LUTOUT13)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_0_LUTOUT12 0x00001000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_0_LUTOUT12(v) \
+ (((v) << 12) & BM_PXP_WFE_A_STG1_8X1_OUT3_0_LUTOUT12)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_0_LUTOUT11 0x00000800
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_0_LUTOUT11(v) \
+ (((v) << 11) & BM_PXP_WFE_A_STG1_8X1_OUT3_0_LUTOUT11)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_0_LUTOUT10 0x00000400
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_0_LUTOUT10(v) \
+ (((v) << 10) & BM_PXP_WFE_A_STG1_8X1_OUT3_0_LUTOUT10)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_0_LUTOUT9 0x00000200
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_0_LUTOUT9(v) \
+ (((v) << 9) & BM_PXP_WFE_A_STG1_8X1_OUT3_0_LUTOUT9)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_0_LUTOUT8 0x00000100
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_0_LUTOUT8(v) \
+ (((v) << 8) & BM_PXP_WFE_A_STG1_8X1_OUT3_0_LUTOUT8)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_0_LUTOUT7 0x00000080
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_0_LUTOUT7(v) \
+ (((v) << 7) & BM_PXP_WFE_A_STG1_8X1_OUT3_0_LUTOUT7)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_0_LUTOUT6 0x00000040
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_0_LUTOUT6(v) \
+ (((v) << 6) & BM_PXP_WFE_A_STG1_8X1_OUT3_0_LUTOUT6)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_0_LUTOUT5 0x00000020
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_0_LUTOUT5(v) \
+ (((v) << 5) & BM_PXP_WFE_A_STG1_8X1_OUT3_0_LUTOUT5)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_0_LUTOUT4 0x00000010
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_0_LUTOUT4(v) \
+ (((v) << 4) & BM_PXP_WFE_A_STG1_8X1_OUT3_0_LUTOUT4)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_0_LUTOUT3 0x00000008
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_0_LUTOUT3(v) \
+ (((v) << 3) & BM_PXP_WFE_A_STG1_8X1_OUT3_0_LUTOUT3)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_0_LUTOUT2 0x00000004
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_0_LUTOUT2(v) \
+ (((v) << 2) & BM_PXP_WFE_A_STG1_8X1_OUT3_0_LUTOUT2)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_0_LUTOUT1 0x00000002
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_0_LUTOUT1(v) \
+ (((v) << 1) & BM_PXP_WFE_A_STG1_8X1_OUT3_0_LUTOUT1)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_0_LUTOUT0 0x00000001
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_0_LUTOUT0(v) \
+ (((v) << 0) & BM_PXP_WFE_A_STG1_8X1_OUT3_0_LUTOUT0)
+
+#define HW_PXP_WFE_A_STG1_8X1_OUT3_1 (0x00001a00)
+
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_1_LUTOUT63 0x80000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_1_LUTOUT63(v) \
+ (((v) << 31) & BM_PXP_WFE_A_STG1_8X1_OUT3_1_LUTOUT63)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_1_LUTOUT62 0x40000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_1_LUTOUT62(v) \
+ (((v) << 30) & BM_PXP_WFE_A_STG1_8X1_OUT3_1_LUTOUT62)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_1_LUTOUT61 0x20000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_1_LUTOUT61(v) \
+ (((v) << 29) & BM_PXP_WFE_A_STG1_8X1_OUT3_1_LUTOUT61)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_1_LUTOUT60 0x10000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_1_LUTOUT60(v) \
+ (((v) << 28) & BM_PXP_WFE_A_STG1_8X1_OUT3_1_LUTOUT60)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_1_LUTOUT59 0x08000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_1_LUTOUT59(v) \
+ (((v) << 27) & BM_PXP_WFE_A_STG1_8X1_OUT3_1_LUTOUT59)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_1_LUTOUT58 0x04000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_1_LUTOUT58(v) \
+ (((v) << 26) & BM_PXP_WFE_A_STG1_8X1_OUT3_1_LUTOUT58)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_1_LUTOUT57 0x02000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_1_LUTOUT57(v) \
+ (((v) << 25) & BM_PXP_WFE_A_STG1_8X1_OUT3_1_LUTOUT57)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_1_LUTOUT56 0x01000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_1_LUTOUT56(v) \
+ (((v) << 24) & BM_PXP_WFE_A_STG1_8X1_OUT3_1_LUTOUT56)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_1_LUTOUT55 0x00800000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_1_LUTOUT55(v) \
+ (((v) << 23) & BM_PXP_WFE_A_STG1_8X1_OUT3_1_LUTOUT55)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_1_LUTOUT54 0x00400000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_1_LUTOUT54(v) \
+ (((v) << 22) & BM_PXP_WFE_A_STG1_8X1_OUT3_1_LUTOUT54)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_1_LUTOUT53 0x00200000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_1_LUTOUT53(v) \
+ (((v) << 21) & BM_PXP_WFE_A_STG1_8X1_OUT3_1_LUTOUT53)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_1_LUTOUT52 0x00100000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_1_LUTOUT52(v) \
+ (((v) << 20) & BM_PXP_WFE_A_STG1_8X1_OUT3_1_LUTOUT52)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_1_LUTOUT51 0x00080000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_1_LUTOUT51(v) \
+ (((v) << 19) & BM_PXP_WFE_A_STG1_8X1_OUT3_1_LUTOUT51)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_1_LUTOUT50 0x00040000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_1_LUTOUT50(v) \
+ (((v) << 18) & BM_PXP_WFE_A_STG1_8X1_OUT3_1_LUTOUT50)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_1_LUTOUT49 0x00020000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_1_LUTOUT49(v) \
+ (((v) << 17) & BM_PXP_WFE_A_STG1_8X1_OUT3_1_LUTOUT49)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_1_LUTOUT48 0x00010000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_1_LUTOUT48(v) \
+ (((v) << 16) & BM_PXP_WFE_A_STG1_8X1_OUT3_1_LUTOUT48)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_1_LUTOUT47 0x00008000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_1_LUTOUT47(v) \
+ (((v) << 15) & BM_PXP_WFE_A_STG1_8X1_OUT3_1_LUTOUT47)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_1_LUTOUT46 0x00004000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_1_LUTOUT46(v) \
+ (((v) << 14) & BM_PXP_WFE_A_STG1_8X1_OUT3_1_LUTOUT46)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_1_LUTOUT45 0x00002000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_1_LUTOUT45(v) \
+ (((v) << 13) & BM_PXP_WFE_A_STG1_8X1_OUT3_1_LUTOUT45)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_1_LUTOUT44 0x00001000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_1_LUTOUT44(v) \
+ (((v) << 12) & BM_PXP_WFE_A_STG1_8X1_OUT3_1_LUTOUT44)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_1_LUTOUT43 0x00000800
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_1_LUTOUT43(v) \
+ (((v) << 11) & BM_PXP_WFE_A_STG1_8X1_OUT3_1_LUTOUT43)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_1_LUTOUT42 0x00000400
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_1_LUTOUT42(v) \
+ (((v) << 10) & BM_PXP_WFE_A_STG1_8X1_OUT3_1_LUTOUT42)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_1_LUTOUT41 0x00000200
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_1_LUTOUT41(v) \
+ (((v) << 9) & BM_PXP_WFE_A_STG1_8X1_OUT3_1_LUTOUT41)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_1_LUTOUT40 0x00000100
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_1_LUTOUT40(v) \
+ (((v) << 8) & BM_PXP_WFE_A_STG1_8X1_OUT3_1_LUTOUT40)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_1_LUTOUT39 0x00000080
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_1_LUTOUT39(v) \
+ (((v) << 7) & BM_PXP_WFE_A_STG1_8X1_OUT3_1_LUTOUT39)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_1_LUTOUT38 0x00000040
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_1_LUTOUT38(v) \
+ (((v) << 6) & BM_PXP_WFE_A_STG1_8X1_OUT3_1_LUTOUT38)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_1_LUTOUT37 0x00000020
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_1_LUTOUT37(v) \
+ (((v) << 5) & BM_PXP_WFE_A_STG1_8X1_OUT3_1_LUTOUT37)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_1_LUTOUT36 0x00000010
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_1_LUTOUT36(v) \
+ (((v) << 4) & BM_PXP_WFE_A_STG1_8X1_OUT3_1_LUTOUT36)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_1_LUTOUT35 0x00000008
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_1_LUTOUT35(v) \
+ (((v) << 3) & BM_PXP_WFE_A_STG1_8X1_OUT3_1_LUTOUT35)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_1_LUTOUT34 0x00000004
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_1_LUTOUT34(v) \
+ (((v) << 2) & BM_PXP_WFE_A_STG1_8X1_OUT3_1_LUTOUT34)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_1_LUTOUT33 0x00000002
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_1_LUTOUT33(v) \
+ (((v) << 1) & BM_PXP_WFE_A_STG1_8X1_OUT3_1_LUTOUT33)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_1_LUTOUT32 0x00000001
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_1_LUTOUT32(v) \
+ (((v) << 0) & BM_PXP_WFE_A_STG1_8X1_OUT3_1_LUTOUT32)
+
+#define HW_PXP_WFE_A_STG1_8X1_OUT3_2 (0x00001a10)
+
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_2_LUTOUT95 0x80000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_2_LUTOUT95(v) \
+ (((v) << 31) & BM_PXP_WFE_A_STG1_8X1_OUT3_2_LUTOUT95)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_2_LUTOUT94 0x40000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_2_LUTOUT94(v) \
+ (((v) << 30) & BM_PXP_WFE_A_STG1_8X1_OUT3_2_LUTOUT94)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_2_LUTOUT93 0x20000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_2_LUTOUT93(v) \
+ (((v) << 29) & BM_PXP_WFE_A_STG1_8X1_OUT3_2_LUTOUT93)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_2_LUTOUT92 0x10000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_2_LUTOUT92(v) \
+ (((v) << 28) & BM_PXP_WFE_A_STG1_8X1_OUT3_2_LUTOUT92)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_2_LUTOUT91 0x08000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_2_LUTOUT91(v) \
+ (((v) << 27) & BM_PXP_WFE_A_STG1_8X1_OUT3_2_LUTOUT91)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_2_LUTOUT90 0x04000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_2_LUTOUT90(v) \
+ (((v) << 26) & BM_PXP_WFE_A_STG1_8X1_OUT3_2_LUTOUT90)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_2_LUTOUT89 0x02000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_2_LUTOUT89(v) \
+ (((v) << 25) & BM_PXP_WFE_A_STG1_8X1_OUT3_2_LUTOUT89)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_2_LUTOUT88 0x01000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_2_LUTOUT88(v) \
+ (((v) << 24) & BM_PXP_WFE_A_STG1_8X1_OUT3_2_LUTOUT88)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_2_LUTOUT87 0x00800000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_2_LUTOUT87(v) \
+ (((v) << 23) & BM_PXP_WFE_A_STG1_8X1_OUT3_2_LUTOUT87)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_2_LUTOUT86 0x00400000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_2_LUTOUT86(v) \
+ (((v) << 22) & BM_PXP_WFE_A_STG1_8X1_OUT3_2_LUTOUT86)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_2_LUTOUT85 0x00200000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_2_LUTOUT85(v) \
+ (((v) << 21) & BM_PXP_WFE_A_STG1_8X1_OUT3_2_LUTOUT85)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_2_LUTOUT84 0x00100000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_2_LUTOUT84(v) \
+ (((v) << 20) & BM_PXP_WFE_A_STG1_8X1_OUT3_2_LUTOUT84)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_2_LUTOUT83 0x00080000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_2_LUTOUT83(v) \
+ (((v) << 19) & BM_PXP_WFE_A_STG1_8X1_OUT3_2_LUTOUT83)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_2_LUTOUT82 0x00040000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_2_LUTOUT82(v) \
+ (((v) << 18) & BM_PXP_WFE_A_STG1_8X1_OUT3_2_LUTOUT82)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_2_LUTOUT81 0x00020000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_2_LUTOUT81(v) \
+ (((v) << 17) & BM_PXP_WFE_A_STG1_8X1_OUT3_2_LUTOUT81)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_2_LUTOUT80 0x00010000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_2_LUTOUT80(v) \
+ (((v) << 16) & BM_PXP_WFE_A_STG1_8X1_OUT3_2_LUTOUT80)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_2_LUTOUT79 0x00008000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_2_LUTOUT79(v) \
+ (((v) << 15) & BM_PXP_WFE_A_STG1_8X1_OUT3_2_LUTOUT79)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_2_LUTOUT78 0x00004000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_2_LUTOUT78(v) \
+ (((v) << 14) & BM_PXP_WFE_A_STG1_8X1_OUT3_2_LUTOUT78)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_2_LUTOUT77 0x00002000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_2_LUTOUT77(v) \
+ (((v) << 13) & BM_PXP_WFE_A_STG1_8X1_OUT3_2_LUTOUT77)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_2_LUTOUT76 0x00001000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_2_LUTOUT76(v) \
+ (((v) << 12) & BM_PXP_WFE_A_STG1_8X1_OUT3_2_LUTOUT76)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_2_LUTOUT75 0x00000800
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_2_LUTOUT75(v) \
+ (((v) << 11) & BM_PXP_WFE_A_STG1_8X1_OUT3_2_LUTOUT75)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_2_LUTOUT74 0x00000400
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_2_LUTOUT74(v) \
+ (((v) << 10) & BM_PXP_WFE_A_STG1_8X1_OUT3_2_LUTOUT74)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_2_LUTOUT73 0x00000200
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_2_LUTOUT73(v) \
+ (((v) << 9) & BM_PXP_WFE_A_STG1_8X1_OUT3_2_LUTOUT73)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_2_LUTOUT72 0x00000100
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_2_LUTOUT72(v) \
+ (((v) << 8) & BM_PXP_WFE_A_STG1_8X1_OUT3_2_LUTOUT72)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_2_LUTOUT71 0x00000080
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_2_LUTOUT71(v) \
+ (((v) << 7) & BM_PXP_WFE_A_STG1_8X1_OUT3_2_LUTOUT71)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_2_LUTOUT70 0x00000040
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_2_LUTOUT70(v) \
+ (((v) << 6) & BM_PXP_WFE_A_STG1_8X1_OUT3_2_LUTOUT70)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_2_LUTOUT69 0x00000020
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_2_LUTOUT69(v) \
+ (((v) << 5) & BM_PXP_WFE_A_STG1_8X1_OUT3_2_LUTOUT69)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_2_LUTOUT68 0x00000010
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_2_LUTOUT68(v) \
+ (((v) << 4) & BM_PXP_WFE_A_STG1_8X1_OUT3_2_LUTOUT68)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_2_LUTOUT67 0x00000008
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_2_LUTOUT67(v) \
+ (((v) << 3) & BM_PXP_WFE_A_STG1_8X1_OUT3_2_LUTOUT67)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_2_LUTOUT66 0x00000004
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_2_LUTOUT66(v) \
+ (((v) << 2) & BM_PXP_WFE_A_STG1_8X1_OUT3_2_LUTOUT66)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_2_LUTOUT65 0x00000002
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_2_LUTOUT65(v) \
+ (((v) << 1) & BM_PXP_WFE_A_STG1_8X1_OUT3_2_LUTOUT65)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_2_LUTOUT64 0x00000001
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_2_LUTOUT64(v) \
+ (((v) << 0) & BM_PXP_WFE_A_STG1_8X1_OUT3_2_LUTOUT64)
+
+#define HW_PXP_WFE_A_STG1_8X1_OUT3_3 (0x00001a20)
+
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_3_LUTOUT127 0x80000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_3_LUTOUT127(v) \
+ (((v) << 31) & BM_PXP_WFE_A_STG1_8X1_OUT3_3_LUTOUT127)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_3_LUTOUT126 0x40000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_3_LUTOUT126(v) \
+ (((v) << 30) & BM_PXP_WFE_A_STG1_8X1_OUT3_3_LUTOUT126)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_3_LUTOUT125 0x20000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_3_LUTOUT125(v) \
+ (((v) << 29) & BM_PXP_WFE_A_STG1_8X1_OUT3_3_LUTOUT125)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_3_LUTOUT124 0x10000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_3_LUTOUT124(v) \
+ (((v) << 28) & BM_PXP_WFE_A_STG1_8X1_OUT3_3_LUTOUT124)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_3_LUTOUT123 0x08000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_3_LUTOUT123(v) \
+ (((v) << 27) & BM_PXP_WFE_A_STG1_8X1_OUT3_3_LUTOUT123)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_3_LUTOUT122 0x04000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_3_LUTOUT122(v) \
+ (((v) << 26) & BM_PXP_WFE_A_STG1_8X1_OUT3_3_LUTOUT122)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_3_LUTOUT121 0x02000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_3_LUTOUT121(v) \
+ (((v) << 25) & BM_PXP_WFE_A_STG1_8X1_OUT3_3_LUTOUT121)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_3_LUTOUT120 0x01000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_3_LUTOUT120(v) \
+ (((v) << 24) & BM_PXP_WFE_A_STG1_8X1_OUT3_3_LUTOUT120)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_3_LUTOUT119 0x00800000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_3_LUTOUT119(v) \
+ (((v) << 23) & BM_PXP_WFE_A_STG1_8X1_OUT3_3_LUTOUT119)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_3_LUTOUT118 0x00400000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_3_LUTOUT118(v) \
+ (((v) << 22) & BM_PXP_WFE_A_STG1_8X1_OUT3_3_LUTOUT118)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_3_LUTOUT117 0x00200000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_3_LUTOUT117(v) \
+ (((v) << 21) & BM_PXP_WFE_A_STG1_8X1_OUT3_3_LUTOUT117)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_3_LUTOUT116 0x00100000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_3_LUTOUT116(v) \
+ (((v) << 20) & BM_PXP_WFE_A_STG1_8X1_OUT3_3_LUTOUT116)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_3_LUTOUT115 0x00080000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_3_LUTOUT115(v) \
+ (((v) << 19) & BM_PXP_WFE_A_STG1_8X1_OUT3_3_LUTOUT115)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_3_LUTOUT114 0x00040000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_3_LUTOUT114(v) \
+ (((v) << 18) & BM_PXP_WFE_A_STG1_8X1_OUT3_3_LUTOUT114)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_3_LUTOUT113 0x00020000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_3_LUTOUT113(v) \
+ (((v) << 17) & BM_PXP_WFE_A_STG1_8X1_OUT3_3_LUTOUT113)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_3_LUTOUT112 0x00010000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_3_LUTOUT112(v) \
+ (((v) << 16) & BM_PXP_WFE_A_STG1_8X1_OUT3_3_LUTOUT112)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_3_LUTOUT111 0x00008000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_3_LUTOUT111(v) \
+ (((v) << 15) & BM_PXP_WFE_A_STG1_8X1_OUT3_3_LUTOUT111)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_3_LUTOUT110 0x00004000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_3_LUTOUT110(v) \
+ (((v) << 14) & BM_PXP_WFE_A_STG1_8X1_OUT3_3_LUTOUT110)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_3_LUTOUT109 0x00002000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_3_LUTOUT109(v) \
+ (((v) << 13) & BM_PXP_WFE_A_STG1_8X1_OUT3_3_LUTOUT109)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_3_LUTOUT108 0x00001000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_3_LUTOUT108(v) \
+ (((v) << 12) & BM_PXP_WFE_A_STG1_8X1_OUT3_3_LUTOUT108)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_3_LUTOUT107 0x00000800
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_3_LUTOUT107(v) \
+ (((v) << 11) & BM_PXP_WFE_A_STG1_8X1_OUT3_3_LUTOUT107)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_3_LUTOUT106 0x00000400
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_3_LUTOUT106(v) \
+ (((v) << 10) & BM_PXP_WFE_A_STG1_8X1_OUT3_3_LUTOUT106)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_3_LUTOUT105 0x00000200
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_3_LUTOUT105(v) \
+ (((v) << 9) & BM_PXP_WFE_A_STG1_8X1_OUT3_3_LUTOUT105)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_3_LUTOUT104 0x00000100
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_3_LUTOUT104(v) \
+ (((v) << 8) & BM_PXP_WFE_A_STG1_8X1_OUT3_3_LUTOUT104)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_3_LUTOUT103 0x00000080
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_3_LUTOUT103(v) \
+ (((v) << 7) & BM_PXP_WFE_A_STG1_8X1_OUT3_3_LUTOUT103)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_3_LUTOUT102 0x00000040
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_3_LUTOUT102(v) \
+ (((v) << 6) & BM_PXP_WFE_A_STG1_8X1_OUT3_3_LUTOUT102)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_3_LUTOUT101 0x00000020
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_3_LUTOUT101(v) \
+ (((v) << 5) & BM_PXP_WFE_A_STG1_8X1_OUT3_3_LUTOUT101)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_3_LUTOUT100 0x00000010
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_3_LUTOUT100(v) \
+ (((v) << 4) & BM_PXP_WFE_A_STG1_8X1_OUT3_3_LUTOUT100)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_3_LUTOUT99 0x00000008
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_3_LUTOUT99(v) \
+ (((v) << 3) & BM_PXP_WFE_A_STG1_8X1_OUT3_3_LUTOUT99)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_3_LUTOUT98 0x00000004
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_3_LUTOUT98(v) \
+ (((v) << 2) & BM_PXP_WFE_A_STG1_8X1_OUT3_3_LUTOUT98)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_3_LUTOUT97 0x00000002
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_3_LUTOUT97(v) \
+ (((v) << 1) & BM_PXP_WFE_A_STG1_8X1_OUT3_3_LUTOUT97)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_3_LUTOUT96 0x00000001
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_3_LUTOUT96(v) \
+ (((v) << 0) & BM_PXP_WFE_A_STG1_8X1_OUT3_3_LUTOUT96)
+
+#define HW_PXP_WFE_A_STG1_8X1_OUT3_4 (0x00001a30)
+
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_4_LUTOUT159 0x80000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_4_LUTOUT159(v) \
+ (((v) << 31) & BM_PXP_WFE_A_STG1_8X1_OUT3_4_LUTOUT159)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_4_LUTOUT158 0x40000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_4_LUTOUT158(v) \
+ (((v) << 30) & BM_PXP_WFE_A_STG1_8X1_OUT3_4_LUTOUT158)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_4_LUTOUT157 0x20000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_4_LUTOUT157(v) \
+ (((v) << 29) & BM_PXP_WFE_A_STG1_8X1_OUT3_4_LUTOUT157)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_4_LUTOUT156 0x10000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_4_LUTOUT156(v) \
+ (((v) << 28) & BM_PXP_WFE_A_STG1_8X1_OUT3_4_LUTOUT156)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_4_LUTOUT155 0x08000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_4_LUTOUT155(v) \
+ (((v) << 27) & BM_PXP_WFE_A_STG1_8X1_OUT3_4_LUTOUT155)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_4_LUTOUT154 0x04000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_4_LUTOUT154(v) \
+ (((v) << 26) & BM_PXP_WFE_A_STG1_8X1_OUT3_4_LUTOUT154)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_4_LUTOUT153 0x02000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_4_LUTOUT153(v) \
+ (((v) << 25) & BM_PXP_WFE_A_STG1_8X1_OUT3_4_LUTOUT153)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_4_LUTOUT152 0x01000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_4_LUTOUT152(v) \
+ (((v) << 24) & BM_PXP_WFE_A_STG1_8X1_OUT3_4_LUTOUT152)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_4_LUTOUT151 0x00800000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_4_LUTOUT151(v) \
+ (((v) << 23) & BM_PXP_WFE_A_STG1_8X1_OUT3_4_LUTOUT151)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_4_LUTOUT150 0x00400000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_4_LUTOUT150(v) \
+ (((v) << 22) & BM_PXP_WFE_A_STG1_8X1_OUT3_4_LUTOUT150)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_4_LUTOUT149 0x00200000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_4_LUTOUT149(v) \
+ (((v) << 21) & BM_PXP_WFE_A_STG1_8X1_OUT3_4_LUTOUT149)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_4_LUTOUT148 0x00100000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_4_LUTOUT148(v) \
+ (((v) << 20) & BM_PXP_WFE_A_STG1_8X1_OUT3_4_LUTOUT148)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_4_LUTOUT147 0x00080000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_4_LUTOUT147(v) \
+ (((v) << 19) & BM_PXP_WFE_A_STG1_8X1_OUT3_4_LUTOUT147)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_4_LUTOUT146 0x00040000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_4_LUTOUT146(v) \
+ (((v) << 18) & BM_PXP_WFE_A_STG1_8X1_OUT3_4_LUTOUT146)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_4_LUTOUT145 0x00020000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_4_LUTOUT145(v) \
+ (((v) << 17) & BM_PXP_WFE_A_STG1_8X1_OUT3_4_LUTOUT145)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_4_LUTOUT144 0x00010000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_4_LUTOUT144(v) \
+ (((v) << 16) & BM_PXP_WFE_A_STG1_8X1_OUT3_4_LUTOUT144)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_4_LUTOUT143 0x00008000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_4_LUTOUT143(v) \
+ (((v) << 15) & BM_PXP_WFE_A_STG1_8X1_OUT3_4_LUTOUT143)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_4_LUTOUT142 0x00004000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_4_LUTOUT142(v) \
+ (((v) << 14) & BM_PXP_WFE_A_STG1_8X1_OUT3_4_LUTOUT142)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_4_LUTOUT141 0x00002000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_4_LUTOUT141(v) \
+ (((v) << 13) & BM_PXP_WFE_A_STG1_8X1_OUT3_4_LUTOUT141)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_4_LUTOUT140 0x00001000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_4_LUTOUT140(v) \
+ (((v) << 12) & BM_PXP_WFE_A_STG1_8X1_OUT3_4_LUTOUT140)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_4_LUTOUT139 0x00000800
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_4_LUTOUT139(v) \
+ (((v) << 11) & BM_PXP_WFE_A_STG1_8X1_OUT3_4_LUTOUT139)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_4_LUTOUT138 0x00000400
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_4_LUTOUT138(v) \
+ (((v) << 10) & BM_PXP_WFE_A_STG1_8X1_OUT3_4_LUTOUT138)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_4_LUTOUT137 0x00000200
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_4_LUTOUT137(v) \
+ (((v) << 9) & BM_PXP_WFE_A_STG1_8X1_OUT3_4_LUTOUT137)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_4_LUTOUT136 0x00000100
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_4_LUTOUT136(v) \
+ (((v) << 8) & BM_PXP_WFE_A_STG1_8X1_OUT3_4_LUTOUT136)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_4_LUTOUT135 0x00000080
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_4_LUTOUT135(v) \
+ (((v) << 7) & BM_PXP_WFE_A_STG1_8X1_OUT3_4_LUTOUT135)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_4_LUTOUT134 0x00000040
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_4_LUTOUT134(v) \
+ (((v) << 6) & BM_PXP_WFE_A_STG1_8X1_OUT3_4_LUTOUT134)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_4_LUTOUT133 0x00000020
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_4_LUTOUT133(v) \
+ (((v) << 5) & BM_PXP_WFE_A_STG1_8X1_OUT3_4_LUTOUT133)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_4_LUTOUT132 0x00000010
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_4_LUTOUT132(v) \
+ (((v) << 4) & BM_PXP_WFE_A_STG1_8X1_OUT3_4_LUTOUT132)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_4_LUTOUT131 0x00000008
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_4_LUTOUT131(v) \
+ (((v) << 3) & BM_PXP_WFE_A_STG1_8X1_OUT3_4_LUTOUT131)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_4_LUTOUT130 0x00000004
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_4_LUTOUT130(v) \
+ (((v) << 2) & BM_PXP_WFE_A_STG1_8X1_OUT3_4_LUTOUT130)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_4_LUTOUT129 0x00000002
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_4_LUTOUT129(v) \
+ (((v) << 1) & BM_PXP_WFE_A_STG1_8X1_OUT3_4_LUTOUT129)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_4_LUTOUT128 0x00000001
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_4_LUTOUT128(v) \
+ (((v) << 0) & BM_PXP_WFE_A_STG1_8X1_OUT3_4_LUTOUT128)
+
+#define HW_PXP_WFE_A_STG1_8X1_OUT3_5 (0x00001a40)
+
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_5_LUTOUT191 0x80000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_5_LUTOUT191(v) \
+ (((v) << 31) & BM_PXP_WFE_A_STG1_8X1_OUT3_5_LUTOUT191)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_5_LUTOUT190 0x40000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_5_LUTOUT190(v) \
+ (((v) << 30) & BM_PXP_WFE_A_STG1_8X1_OUT3_5_LUTOUT190)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_5_LUTOUT189 0x20000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_5_LUTOUT189(v) \
+ (((v) << 29) & BM_PXP_WFE_A_STG1_8X1_OUT3_5_LUTOUT189)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_5_LUTOUT188 0x10000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_5_LUTOUT188(v) \
+ (((v) << 28) & BM_PXP_WFE_A_STG1_8X1_OUT3_5_LUTOUT188)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_5_LUTOUT187 0x08000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_5_LUTOUT187(v) \
+ (((v) << 27) & BM_PXP_WFE_A_STG1_8X1_OUT3_5_LUTOUT187)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_5_LUTOUT186 0x04000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_5_LUTOUT186(v) \
+ (((v) << 26) & BM_PXP_WFE_A_STG1_8X1_OUT3_5_LUTOUT186)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_5_LUTOUT185 0x02000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_5_LUTOUT185(v) \
+ (((v) << 25) & BM_PXP_WFE_A_STG1_8X1_OUT3_5_LUTOUT185)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_5_LUTOUT184 0x01000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_5_LUTOUT184(v) \
+ (((v) << 24) & BM_PXP_WFE_A_STG1_8X1_OUT3_5_LUTOUT184)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_5_LUTOUT183 0x00800000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_5_LUTOUT183(v) \
+ (((v) << 23) & BM_PXP_WFE_A_STG1_8X1_OUT3_5_LUTOUT183)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_5_LUTOUT182 0x00400000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_5_LUTOUT182(v) \
+ (((v) << 22) & BM_PXP_WFE_A_STG1_8X1_OUT3_5_LUTOUT182)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_5_LUTOUT181 0x00200000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_5_LUTOUT181(v) \
+ (((v) << 21) & BM_PXP_WFE_A_STG1_8X1_OUT3_5_LUTOUT181)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_5_LUTOUT180 0x00100000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_5_LUTOUT180(v) \
+ (((v) << 20) & BM_PXP_WFE_A_STG1_8X1_OUT3_5_LUTOUT180)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_5_LUTOUT179 0x00080000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_5_LUTOUT179(v) \
+ (((v) << 19) & BM_PXP_WFE_A_STG1_8X1_OUT3_5_LUTOUT179)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_5_LUTOUT178 0x00040000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_5_LUTOUT178(v) \
+ (((v) << 18) & BM_PXP_WFE_A_STG1_8X1_OUT3_5_LUTOUT178)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_5_LUTOUT177 0x00020000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_5_LUTOUT177(v) \
+ (((v) << 17) & BM_PXP_WFE_A_STG1_8X1_OUT3_5_LUTOUT177)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_5_LUTOUT176 0x00010000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_5_LUTOUT176(v) \
+ (((v) << 16) & BM_PXP_WFE_A_STG1_8X1_OUT3_5_LUTOUT176)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_5_LUTOUT175 0x00008000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_5_LUTOUT175(v) \
+ (((v) << 15) & BM_PXP_WFE_A_STG1_8X1_OUT3_5_LUTOUT175)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_5_LUTOUT174 0x00004000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_5_LUTOUT174(v) \
+ (((v) << 14) & BM_PXP_WFE_A_STG1_8X1_OUT3_5_LUTOUT174)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_5_LUTOUT173 0x00002000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_5_LUTOUT173(v) \
+ (((v) << 13) & BM_PXP_WFE_A_STG1_8X1_OUT3_5_LUTOUT173)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_5_LUTOUT172 0x00001000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_5_LUTOUT172(v) \
+ (((v) << 12) & BM_PXP_WFE_A_STG1_8X1_OUT3_5_LUTOUT172)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_5_LUTOUT171 0x00000800
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_5_LUTOUT171(v) \
+ (((v) << 11) & BM_PXP_WFE_A_STG1_8X1_OUT3_5_LUTOUT171)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_5_LUTOUT170 0x00000400
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_5_LUTOUT170(v) \
+ (((v) << 10) & BM_PXP_WFE_A_STG1_8X1_OUT3_5_LUTOUT170)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_5_LUTOUT169 0x00000200
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_5_LUTOUT169(v) \
+ (((v) << 9) & BM_PXP_WFE_A_STG1_8X1_OUT3_5_LUTOUT169)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_5_LUTOUT168 0x00000100
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_5_LUTOUT168(v) \
+ (((v) << 8) & BM_PXP_WFE_A_STG1_8X1_OUT3_5_LUTOUT168)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_5_LUTOUT167 0x00000080
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_5_LUTOUT167(v) \
+ (((v) << 7) & BM_PXP_WFE_A_STG1_8X1_OUT3_5_LUTOUT167)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_5_LUTOUT166 0x00000040
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_5_LUTOUT166(v) \
+ (((v) << 6) & BM_PXP_WFE_A_STG1_8X1_OUT3_5_LUTOUT166)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_5_LUTOUT165 0x00000020
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_5_LUTOUT165(v) \
+ (((v) << 5) & BM_PXP_WFE_A_STG1_8X1_OUT3_5_LUTOUT165)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_5_LUTOUT164 0x00000010
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_5_LUTOUT164(v) \
+ (((v) << 4) & BM_PXP_WFE_A_STG1_8X1_OUT3_5_LUTOUT164)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_5_LUTOUT163 0x00000008
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_5_LUTOUT163(v) \
+ (((v) << 3) & BM_PXP_WFE_A_STG1_8X1_OUT3_5_LUTOUT163)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_5_LUTOUT162 0x00000004
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_5_LUTOUT162(v) \
+ (((v) << 2) & BM_PXP_WFE_A_STG1_8X1_OUT3_5_LUTOUT162)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_5_LUTOUT161 0x00000002
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_5_LUTOUT161(v) \
+ (((v) << 1) & BM_PXP_WFE_A_STG1_8X1_OUT3_5_LUTOUT161)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_5_LUTOUT160 0x00000001
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_5_LUTOUT160(v) \
+ (((v) << 0) & BM_PXP_WFE_A_STG1_8X1_OUT3_5_LUTOUT160)
+
+#define HW_PXP_WFE_A_STG1_8X1_OUT3_6 (0x00001a50)
+
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_6_LUTOUT223 0x80000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_6_LUTOUT223(v) \
+ (((v) << 31) & BM_PXP_WFE_A_STG1_8X1_OUT3_6_LUTOUT223)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_6_LUTOUT222 0x40000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_6_LUTOUT222(v) \
+ (((v) << 30) & BM_PXP_WFE_A_STG1_8X1_OUT3_6_LUTOUT222)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_6_LUTOUT221 0x20000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_6_LUTOUT221(v) \
+ (((v) << 29) & BM_PXP_WFE_A_STG1_8X1_OUT3_6_LUTOUT221)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_6_LUTOUT220 0x10000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_6_LUTOUT220(v) \
+ (((v) << 28) & BM_PXP_WFE_A_STG1_8X1_OUT3_6_LUTOUT220)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_6_LUTOUT219 0x08000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_6_LUTOUT219(v) \
+ (((v) << 27) & BM_PXP_WFE_A_STG1_8X1_OUT3_6_LUTOUT219)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_6_LUTOUT218 0x04000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_6_LUTOUT218(v) \
+ (((v) << 26) & BM_PXP_WFE_A_STG1_8X1_OUT3_6_LUTOUT218)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_6_LUTOUT217 0x02000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_6_LUTOUT217(v) \
+ (((v) << 25) & BM_PXP_WFE_A_STG1_8X1_OUT3_6_LUTOUT217)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_6_LUTOUT216 0x01000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_6_LUTOUT216(v) \
+ (((v) << 24) & BM_PXP_WFE_A_STG1_8X1_OUT3_6_LUTOUT216)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_6_LUTOUT215 0x00800000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_6_LUTOUT215(v) \
+ (((v) << 23) & BM_PXP_WFE_A_STG1_8X1_OUT3_6_LUTOUT215)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_6_LUTOUT214 0x00400000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_6_LUTOUT214(v) \
+ (((v) << 22) & BM_PXP_WFE_A_STG1_8X1_OUT3_6_LUTOUT214)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_6_LUTOUT213 0x00200000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_6_LUTOUT213(v) \
+ (((v) << 21) & BM_PXP_WFE_A_STG1_8X1_OUT3_6_LUTOUT213)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_6_LUTOUT212 0x00100000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_6_LUTOUT212(v) \
+ (((v) << 20) & BM_PXP_WFE_A_STG1_8X1_OUT3_6_LUTOUT212)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_6_LUTOUT211 0x00080000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_6_LUTOUT211(v) \
+ (((v) << 19) & BM_PXP_WFE_A_STG1_8X1_OUT3_6_LUTOUT211)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_6_LUTOUT210 0x00040000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_6_LUTOUT210(v) \
+ (((v) << 18) & BM_PXP_WFE_A_STG1_8X1_OUT3_6_LUTOUT210)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_6_LUTOUT209 0x00020000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_6_LUTOUT209(v) \
+ (((v) << 17) & BM_PXP_WFE_A_STG1_8X1_OUT3_6_LUTOUT209)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_6_LUTOUT208 0x00010000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_6_LUTOUT208(v) \
+ (((v) << 16) & BM_PXP_WFE_A_STG1_8X1_OUT3_6_LUTOUT208)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_6_LUTOUT207 0x00008000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_6_LUTOUT207(v) \
+ (((v) << 15) & BM_PXP_WFE_A_STG1_8X1_OUT3_6_LUTOUT207)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_6_LUTOUT206 0x00004000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_6_LUTOUT206(v) \
+ (((v) << 14) & BM_PXP_WFE_A_STG1_8X1_OUT3_6_LUTOUT206)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_6_LUTOUT205 0x00002000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_6_LUTOUT205(v) \
+ (((v) << 13) & BM_PXP_WFE_A_STG1_8X1_OUT3_6_LUTOUT205)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_6_LUTOUT204 0x00001000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_6_LUTOUT204(v) \
+ (((v) << 12) & BM_PXP_WFE_A_STG1_8X1_OUT3_6_LUTOUT204)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_6_LUTOUT203 0x00000800
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_6_LUTOUT203(v) \
+ (((v) << 11) & BM_PXP_WFE_A_STG1_8X1_OUT3_6_LUTOUT203)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_6_LUTOUT202 0x00000400
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_6_LUTOUT202(v) \
+ (((v) << 10) & BM_PXP_WFE_A_STG1_8X1_OUT3_6_LUTOUT202)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_6_LUTOUT201 0x00000200
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_6_LUTOUT201(v) \
+ (((v) << 9) & BM_PXP_WFE_A_STG1_8X1_OUT3_6_LUTOUT201)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_6_LUTOUT200 0x00000100
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_6_LUTOUT200(v) \
+ (((v) << 8) & BM_PXP_WFE_A_STG1_8X1_OUT3_6_LUTOUT200)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_6_LUTOUT199 0x00000080
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_6_LUTOUT199(v) \
+ (((v) << 7) & BM_PXP_WFE_A_STG1_8X1_OUT3_6_LUTOUT199)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_6_LUTOUT198 0x00000040
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_6_LUTOUT198(v) \
+ (((v) << 6) & BM_PXP_WFE_A_STG1_8X1_OUT3_6_LUTOUT198)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_6_LUTOUT197 0x00000020
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_6_LUTOUT197(v) \
+ (((v) << 5) & BM_PXP_WFE_A_STG1_8X1_OUT3_6_LUTOUT197)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_6_LUTOUT196 0x00000010
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_6_LUTOUT196(v) \
+ (((v) << 4) & BM_PXP_WFE_A_STG1_8X1_OUT3_6_LUTOUT196)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_6_LUTOUT195 0x00000008
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_6_LUTOUT195(v) \
+ (((v) << 3) & BM_PXP_WFE_A_STG1_8X1_OUT3_6_LUTOUT195)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_6_LUTOUT194 0x00000004
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_6_LUTOUT194(v) \
+ (((v) << 2) & BM_PXP_WFE_A_STG1_8X1_OUT3_6_LUTOUT194)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_6_LUTOUT193 0x00000002
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_6_LUTOUT193(v) \
+ (((v) << 1) & BM_PXP_WFE_A_STG1_8X1_OUT3_6_LUTOUT193)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_6_LUTOUT192 0x00000001
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_6_LUTOUT192(v) \
+ (((v) << 0) & BM_PXP_WFE_A_STG1_8X1_OUT3_6_LUTOUT192)
+
+#define HW_PXP_WFE_A_STG1_8X1_OUT3_7 (0x00001a60)
+
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_7_LUTOUT255 0x80000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_7_LUTOUT255(v) \
+ (((v) << 31) & BM_PXP_WFE_A_STG1_8X1_OUT3_7_LUTOUT255)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_7_LUTOUT254 0x40000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_7_LUTOUT254(v) \
+ (((v) << 30) & BM_PXP_WFE_A_STG1_8X1_OUT3_7_LUTOUT254)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_7_LUTOUT253 0x20000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_7_LUTOUT253(v) \
+ (((v) << 29) & BM_PXP_WFE_A_STG1_8X1_OUT3_7_LUTOUT253)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_7_LUTOUT252 0x10000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_7_LUTOUT252(v) \
+ (((v) << 28) & BM_PXP_WFE_A_STG1_8X1_OUT3_7_LUTOUT252)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_7_LUTOUT251 0x08000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_7_LUTOUT251(v) \
+ (((v) << 27) & BM_PXP_WFE_A_STG1_8X1_OUT3_7_LUTOUT251)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_7_LUTOUT250 0x04000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_7_LUTOUT250(v) \
+ (((v) << 26) & BM_PXP_WFE_A_STG1_8X1_OUT3_7_LUTOUT250)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_7_LUTOUT249 0x02000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_7_LUTOUT249(v) \
+ (((v) << 25) & BM_PXP_WFE_A_STG1_8X1_OUT3_7_LUTOUT249)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_7_LUTOUT248 0x01000000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_7_LUTOUT248(v) \
+ (((v) << 24) & BM_PXP_WFE_A_STG1_8X1_OUT3_7_LUTOUT248)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_7_LUTOUT247 0x00800000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_7_LUTOUT247(v) \
+ (((v) << 23) & BM_PXP_WFE_A_STG1_8X1_OUT3_7_LUTOUT247)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_7_LUTOUT246 0x00400000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_7_LUTOUT246(v) \
+ (((v) << 22) & BM_PXP_WFE_A_STG1_8X1_OUT3_7_LUTOUT246)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_7_LUTOUT245 0x00200000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_7_LUTOUT245(v) \
+ (((v) << 21) & BM_PXP_WFE_A_STG1_8X1_OUT3_7_LUTOUT245)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_7_LUTOUT244 0x00100000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_7_LUTOUT244(v) \
+ (((v) << 20) & BM_PXP_WFE_A_STG1_8X1_OUT3_7_LUTOUT244)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_7_LUTOUT243 0x00080000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_7_LUTOUT243(v) \
+ (((v) << 19) & BM_PXP_WFE_A_STG1_8X1_OUT3_7_LUTOUT243)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_7_LUTOUT242 0x00040000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_7_LUTOUT242(v) \
+ (((v) << 18) & BM_PXP_WFE_A_STG1_8X1_OUT3_7_LUTOUT242)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_7_LUTOUT241 0x00020000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_7_LUTOUT241(v) \
+ (((v) << 17) & BM_PXP_WFE_A_STG1_8X1_OUT3_7_LUTOUT241)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_7_LUTOUT240 0x00010000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_7_LUTOUT240(v) \
+ (((v) << 16) & BM_PXP_WFE_A_STG1_8X1_OUT3_7_LUTOUT240)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_7_LUTOUT239 0x00008000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_7_LUTOUT239(v) \
+ (((v) << 15) & BM_PXP_WFE_A_STG1_8X1_OUT3_7_LUTOUT239)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_7_LUTOUT238 0x00004000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_7_LUTOUT238(v) \
+ (((v) << 14) & BM_PXP_WFE_A_STG1_8X1_OUT3_7_LUTOUT238)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_7_LUTOUT237 0x00002000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_7_LUTOUT237(v) \
+ (((v) << 13) & BM_PXP_WFE_A_STG1_8X1_OUT3_7_LUTOUT237)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_7_LUTOUT236 0x00001000
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_7_LUTOUT236(v) \
+ (((v) << 12) & BM_PXP_WFE_A_STG1_8X1_OUT3_7_LUTOUT236)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_7_LUTOUT235 0x00000800
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_7_LUTOUT235(v) \
+ (((v) << 11) & BM_PXP_WFE_A_STG1_8X1_OUT3_7_LUTOUT235)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_7_LUTOUT234 0x00000400
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_7_LUTOUT234(v) \
+ (((v) << 10) & BM_PXP_WFE_A_STG1_8X1_OUT3_7_LUTOUT234)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_7_LUTOUT233 0x00000200
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_7_LUTOUT233(v) \
+ (((v) << 9) & BM_PXP_WFE_A_STG1_8X1_OUT3_7_LUTOUT233)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_7_LUTOUT232 0x00000100
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_7_LUTOUT232(v) \
+ (((v) << 8) & BM_PXP_WFE_A_STG1_8X1_OUT3_7_LUTOUT232)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_7_LUTOUT231 0x00000080
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_7_LUTOUT231(v) \
+ (((v) << 7) & BM_PXP_WFE_A_STG1_8X1_OUT3_7_LUTOUT231)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_7_LUTOUT230 0x00000040
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_7_LUTOUT230(v) \
+ (((v) << 6) & BM_PXP_WFE_A_STG1_8X1_OUT3_7_LUTOUT230)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_7_LUTOUT229 0x00000020
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_7_LUTOUT229(v) \
+ (((v) << 5) & BM_PXP_WFE_A_STG1_8X1_OUT3_7_LUTOUT229)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_7_LUTOUT228 0x00000010
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_7_LUTOUT228(v) \
+ (((v) << 4) & BM_PXP_WFE_A_STG1_8X1_OUT3_7_LUTOUT228)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_7_LUTOUT227 0x00000008
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_7_LUTOUT227(v) \
+ (((v) << 3) & BM_PXP_WFE_A_STG1_8X1_OUT3_7_LUTOUT227)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_7_LUTOUT226 0x00000004
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_7_LUTOUT226(v) \
+ (((v) << 2) & BM_PXP_WFE_A_STG1_8X1_OUT3_7_LUTOUT226)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_7_LUTOUT225 0x00000002
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_7_LUTOUT225(v) \
+ (((v) << 1) & BM_PXP_WFE_A_STG1_8X1_OUT3_7_LUTOUT225)
+#define BM_PXP_WFE_A_STG1_8X1_OUT3_7_LUTOUT224 0x00000001
+#define BF_PXP_WFE_A_STG1_8X1_OUT3_7_LUTOUT224(v) \
+ (((v) << 0) & BM_PXP_WFE_A_STG1_8X1_OUT3_7_LUTOUT224)
+
+#define HW_PXP_WFE_A_STG2_5X6_OUT0_0 (0x00001a70)
+
+#define BP_PXP_WFE_A_STG2_5X6_OUT0_0_RSVD0 30
+#define BM_PXP_WFE_A_STG2_5X6_OUT0_0_RSVD0 0xC0000000
+#define BF_PXP_WFE_A_STG2_5X6_OUT0_0_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFE_A_STG2_5X6_OUT0_0_RSVD0)
+#define BP_PXP_WFE_A_STG2_5X6_OUT0_0_LUTOUT3 24
+#define BM_PXP_WFE_A_STG2_5X6_OUT0_0_LUTOUT3 0x3F000000
+#define BF_PXP_WFE_A_STG2_5X6_OUT0_0_LUTOUT3(v) \
+ (((v) << 24) & BM_PXP_WFE_A_STG2_5X6_OUT0_0_LUTOUT3)
+#define BP_PXP_WFE_A_STG2_5X6_OUT0_0_RSVD1 22
+#define BM_PXP_WFE_A_STG2_5X6_OUT0_0_RSVD1 0x00C00000
+#define BF_PXP_WFE_A_STG2_5X6_OUT0_0_RSVD1(v) \
+ (((v) << 22) & BM_PXP_WFE_A_STG2_5X6_OUT0_0_RSVD1)
+#define BP_PXP_WFE_A_STG2_5X6_OUT0_0_LUTOUT2 16
+#define BM_PXP_WFE_A_STG2_5X6_OUT0_0_LUTOUT2 0x003F0000
+#define BF_PXP_WFE_A_STG2_5X6_OUT0_0_LUTOUT2(v) \
+ (((v) << 16) & BM_PXP_WFE_A_STG2_5X6_OUT0_0_LUTOUT2)
+#define BP_PXP_WFE_A_STG2_5X6_OUT0_0_RSVD2 14
+#define BM_PXP_WFE_A_STG2_5X6_OUT0_0_RSVD2 0x0000C000
+#define BF_PXP_WFE_A_STG2_5X6_OUT0_0_RSVD2(v) \
+ (((v) << 14) & BM_PXP_WFE_A_STG2_5X6_OUT0_0_RSVD2)
+#define BP_PXP_WFE_A_STG2_5X6_OUT0_0_LUTOUT1 8
+#define BM_PXP_WFE_A_STG2_5X6_OUT0_0_LUTOUT1 0x00003F00
+#define BF_PXP_WFE_A_STG2_5X6_OUT0_0_LUTOUT1(v) \
+ (((v) << 8) & BM_PXP_WFE_A_STG2_5X6_OUT0_0_LUTOUT1)
+#define BP_PXP_WFE_A_STG2_5X6_OUT0_0_RSVD3 6
+#define BM_PXP_WFE_A_STG2_5X6_OUT0_0_RSVD3 0x000000C0
+#define BF_PXP_WFE_A_STG2_5X6_OUT0_0_RSVD3(v) \
+ (((v) << 6) & BM_PXP_WFE_A_STG2_5X6_OUT0_0_RSVD3)
+#define BP_PXP_WFE_A_STG2_5X6_OUT0_0_LUTOUT0 0
+#define BM_PXP_WFE_A_STG2_5X6_OUT0_0_LUTOUT0 0x0000003F
+#define BF_PXP_WFE_A_STG2_5X6_OUT0_0_LUTOUT0(v) \
+ (((v) << 0) & BM_PXP_WFE_A_STG2_5X6_OUT0_0_LUTOUT0)
+
+#define HW_PXP_WFE_A_STG2_5X6_OUT0_1 (0x00001a80)
+
+#define BP_PXP_WFE_A_STG2_5X6_OUT0_1_RSVD0 30
+#define BM_PXP_WFE_A_STG2_5X6_OUT0_1_RSVD0 0xC0000000
+#define BF_PXP_WFE_A_STG2_5X6_OUT0_1_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFE_A_STG2_5X6_OUT0_1_RSVD0)
+#define BP_PXP_WFE_A_STG2_5X6_OUT0_1_LUTOUT7 24
+#define BM_PXP_WFE_A_STG2_5X6_OUT0_1_LUTOUT7 0x3F000000
+#define BF_PXP_WFE_A_STG2_5X6_OUT0_1_LUTOUT7(v) \
+ (((v) << 24) & BM_PXP_WFE_A_STG2_5X6_OUT0_1_LUTOUT7)
+#define BP_PXP_WFE_A_STG2_5X6_OUT0_1_RSVD1 22
+#define BM_PXP_WFE_A_STG2_5X6_OUT0_1_RSVD1 0x00C00000
+#define BF_PXP_WFE_A_STG2_5X6_OUT0_1_RSVD1(v) \
+ (((v) << 22) & BM_PXP_WFE_A_STG2_5X6_OUT0_1_RSVD1)
+#define BP_PXP_WFE_A_STG2_5X6_OUT0_1_LUTOUT6 16
+#define BM_PXP_WFE_A_STG2_5X6_OUT0_1_LUTOUT6 0x003F0000
+#define BF_PXP_WFE_A_STG2_5X6_OUT0_1_LUTOUT6(v) \
+ (((v) << 16) & BM_PXP_WFE_A_STG2_5X6_OUT0_1_LUTOUT6)
+#define BP_PXP_WFE_A_STG2_5X6_OUT0_1_RSVD2 14
+#define BM_PXP_WFE_A_STG2_5X6_OUT0_1_RSVD2 0x0000C000
+#define BF_PXP_WFE_A_STG2_5X6_OUT0_1_RSVD2(v) \
+ (((v) << 14) & BM_PXP_WFE_A_STG2_5X6_OUT0_1_RSVD2)
+#define BP_PXP_WFE_A_STG2_5X6_OUT0_1_LUTOUT5 8
+#define BM_PXP_WFE_A_STG2_5X6_OUT0_1_LUTOUT5 0x00003F00
+#define BF_PXP_WFE_A_STG2_5X6_OUT0_1_LUTOUT5(v) \
+ (((v) << 8) & BM_PXP_WFE_A_STG2_5X6_OUT0_1_LUTOUT5)
+#define BP_PXP_WFE_A_STG2_5X6_OUT0_1_RSVD3 6
+#define BM_PXP_WFE_A_STG2_5X6_OUT0_1_RSVD3 0x000000C0
+#define BF_PXP_WFE_A_STG2_5X6_OUT0_1_RSVD3(v) \
+ (((v) << 6) & BM_PXP_WFE_A_STG2_5X6_OUT0_1_RSVD3)
+#define BP_PXP_WFE_A_STG2_5X6_OUT0_1_LUTOUT4 0
+#define BM_PXP_WFE_A_STG2_5X6_OUT0_1_LUTOUT4 0x0000003F
+#define BF_PXP_WFE_A_STG2_5X6_OUT0_1_LUTOUT4(v) \
+ (((v) << 0) & BM_PXP_WFE_A_STG2_5X6_OUT0_1_LUTOUT4)
+
+#define HW_PXP_WFE_A_STG2_5X6_OUT0_2 (0x00001a90)
+
+#define BP_PXP_WFE_A_STG2_5X6_OUT0_2_RSVD0 30
+#define BM_PXP_WFE_A_STG2_5X6_OUT0_2_RSVD0 0xC0000000
+#define BF_PXP_WFE_A_STG2_5X6_OUT0_2_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFE_A_STG2_5X6_OUT0_2_RSVD0)
+#define BP_PXP_WFE_A_STG2_5X6_OUT0_2_LUTOUT11 24
+#define BM_PXP_WFE_A_STG2_5X6_OUT0_2_LUTOUT11 0x3F000000
+#define BF_PXP_WFE_A_STG2_5X6_OUT0_2_LUTOUT11(v) \
+ (((v) << 24) & BM_PXP_WFE_A_STG2_5X6_OUT0_2_LUTOUT11)
+#define BP_PXP_WFE_A_STG2_5X6_OUT0_2_RSVD1 22
+#define BM_PXP_WFE_A_STG2_5X6_OUT0_2_RSVD1 0x00C00000
+#define BF_PXP_WFE_A_STG2_5X6_OUT0_2_RSVD1(v) \
+ (((v) << 22) & BM_PXP_WFE_A_STG2_5X6_OUT0_2_RSVD1)
+#define BP_PXP_WFE_A_STG2_5X6_OUT0_2_LUTOUT10 16
+#define BM_PXP_WFE_A_STG2_5X6_OUT0_2_LUTOUT10 0x003F0000
+#define BF_PXP_WFE_A_STG2_5X6_OUT0_2_LUTOUT10(v) \
+ (((v) << 16) & BM_PXP_WFE_A_STG2_5X6_OUT0_2_LUTOUT10)
+#define BP_PXP_WFE_A_STG2_5X6_OUT0_2_RSVD2 14
+#define BM_PXP_WFE_A_STG2_5X6_OUT0_2_RSVD2 0x0000C000
+#define BF_PXP_WFE_A_STG2_5X6_OUT0_2_RSVD2(v) \
+ (((v) << 14) & BM_PXP_WFE_A_STG2_5X6_OUT0_2_RSVD2)
+#define BP_PXP_WFE_A_STG2_5X6_OUT0_2_LUTOUT9 8
+#define BM_PXP_WFE_A_STG2_5X6_OUT0_2_LUTOUT9 0x00003F00
+#define BF_PXP_WFE_A_STG2_5X6_OUT0_2_LUTOUT9(v) \
+ (((v) << 8) & BM_PXP_WFE_A_STG2_5X6_OUT0_2_LUTOUT9)
+#define BP_PXP_WFE_A_STG2_5X6_OUT0_2_RSVD3 6
+#define BM_PXP_WFE_A_STG2_5X6_OUT0_2_RSVD3 0x000000C0
+#define BF_PXP_WFE_A_STG2_5X6_OUT0_2_RSVD3(v) \
+ (((v) << 6) & BM_PXP_WFE_A_STG2_5X6_OUT0_2_RSVD3)
+#define BP_PXP_WFE_A_STG2_5X6_OUT0_2_LUTOUT8 0
+#define BM_PXP_WFE_A_STG2_5X6_OUT0_2_LUTOUT8 0x0000003F
+#define BF_PXP_WFE_A_STG2_5X6_OUT0_2_LUTOUT8(v) \
+ (((v) << 0) & BM_PXP_WFE_A_STG2_5X6_OUT0_2_LUTOUT8)
+
+#define HW_PXP_WFE_A_STG2_5X6_OUT0_3 (0x00001aa0)
+
+#define BP_PXP_WFE_A_STG2_5X6_OUT0_3_RSVD0 30
+#define BM_PXP_WFE_A_STG2_5X6_OUT0_3_RSVD0 0xC0000000
+#define BF_PXP_WFE_A_STG2_5X6_OUT0_3_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFE_A_STG2_5X6_OUT0_3_RSVD0)
+#define BP_PXP_WFE_A_STG2_5X6_OUT0_3_LUTOUT15 24
+#define BM_PXP_WFE_A_STG2_5X6_OUT0_3_LUTOUT15 0x3F000000
+#define BF_PXP_WFE_A_STG2_5X6_OUT0_3_LUTOUT15(v) \
+ (((v) << 24) & BM_PXP_WFE_A_STG2_5X6_OUT0_3_LUTOUT15)
+#define BP_PXP_WFE_A_STG2_5X6_OUT0_3_RSVD1 22
+#define BM_PXP_WFE_A_STG2_5X6_OUT0_3_RSVD1 0x00C00000
+#define BF_PXP_WFE_A_STG2_5X6_OUT0_3_RSVD1(v) \
+ (((v) << 22) & BM_PXP_WFE_A_STG2_5X6_OUT0_3_RSVD1)
+#define BP_PXP_WFE_A_STG2_5X6_OUT0_3_LUTOUT14 16
+#define BM_PXP_WFE_A_STG2_5X6_OUT0_3_LUTOUT14 0x003F0000
+#define BF_PXP_WFE_A_STG2_5X6_OUT0_3_LUTOUT14(v) \
+ (((v) << 16) & BM_PXP_WFE_A_STG2_5X6_OUT0_3_LUTOUT14)
+#define BP_PXP_WFE_A_STG2_5X6_OUT0_3_RSVD2 14
+#define BM_PXP_WFE_A_STG2_5X6_OUT0_3_RSVD2 0x0000C000
+#define BF_PXP_WFE_A_STG2_5X6_OUT0_3_RSVD2(v) \
+ (((v) << 14) & BM_PXP_WFE_A_STG2_5X6_OUT0_3_RSVD2)
+#define BP_PXP_WFE_A_STG2_5X6_OUT0_3_LUTOUT13 8
+#define BM_PXP_WFE_A_STG2_5X6_OUT0_3_LUTOUT13 0x00003F00
+#define BF_PXP_WFE_A_STG2_5X6_OUT0_3_LUTOUT13(v) \
+ (((v) << 8) & BM_PXP_WFE_A_STG2_5X6_OUT0_3_LUTOUT13)
+#define BP_PXP_WFE_A_STG2_5X6_OUT0_3_RSVD3 6
+#define BM_PXP_WFE_A_STG2_5X6_OUT0_3_RSVD3 0x000000C0
+#define BF_PXP_WFE_A_STG2_5X6_OUT0_3_RSVD3(v) \
+ (((v) << 6) & BM_PXP_WFE_A_STG2_5X6_OUT0_3_RSVD3)
+#define BP_PXP_WFE_A_STG2_5X6_OUT0_3_LUTOUT12 0
+#define BM_PXP_WFE_A_STG2_5X6_OUT0_3_LUTOUT12 0x0000003F
+#define BF_PXP_WFE_A_STG2_5X6_OUT0_3_LUTOUT12(v) \
+ (((v) << 0) & BM_PXP_WFE_A_STG2_5X6_OUT0_3_LUTOUT12)
+
+#define HW_PXP_WFE_A_STG2_5X6_OUT0_4 (0x00001ab0)
+
+#define BP_PXP_WFE_A_STG2_5X6_OUT0_4_RSVD0 30
+#define BM_PXP_WFE_A_STG2_5X6_OUT0_4_RSVD0 0xC0000000
+#define BF_PXP_WFE_A_STG2_5X6_OUT0_4_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFE_A_STG2_5X6_OUT0_4_RSVD0)
+#define BP_PXP_WFE_A_STG2_5X6_OUT0_4_LUTOUT19 24
+#define BM_PXP_WFE_A_STG2_5X6_OUT0_4_LUTOUT19 0x3F000000
+#define BF_PXP_WFE_A_STG2_5X6_OUT0_4_LUTOUT19(v) \
+ (((v) << 24) & BM_PXP_WFE_A_STG2_5X6_OUT0_4_LUTOUT19)
+#define BP_PXP_WFE_A_STG2_5X6_OUT0_4_RSVD1 22
+#define BM_PXP_WFE_A_STG2_5X6_OUT0_4_RSVD1 0x00C00000
+#define BF_PXP_WFE_A_STG2_5X6_OUT0_4_RSVD1(v) \
+ (((v) << 22) & BM_PXP_WFE_A_STG2_5X6_OUT0_4_RSVD1)
+#define BP_PXP_WFE_A_STG2_5X6_OUT0_4_LUTOUT18 16
+#define BM_PXP_WFE_A_STG2_5X6_OUT0_4_LUTOUT18 0x003F0000
+#define BF_PXP_WFE_A_STG2_5X6_OUT0_4_LUTOUT18(v) \
+ (((v) << 16) & BM_PXP_WFE_A_STG2_5X6_OUT0_4_LUTOUT18)
+#define BP_PXP_WFE_A_STG2_5X6_OUT0_4_RSVD2 14
+#define BM_PXP_WFE_A_STG2_5X6_OUT0_4_RSVD2 0x0000C000
+#define BF_PXP_WFE_A_STG2_5X6_OUT0_4_RSVD2(v) \
+ (((v) << 14) & BM_PXP_WFE_A_STG2_5X6_OUT0_4_RSVD2)
+#define BP_PXP_WFE_A_STG2_5X6_OUT0_4_LUTOUT17 8
+#define BM_PXP_WFE_A_STG2_5X6_OUT0_4_LUTOUT17 0x00003F00
+#define BF_PXP_WFE_A_STG2_5X6_OUT0_4_LUTOUT17(v) \
+ (((v) << 8) & BM_PXP_WFE_A_STG2_5X6_OUT0_4_LUTOUT17)
+#define BP_PXP_WFE_A_STG2_5X6_OUT0_4_RSVD3 6
+#define BM_PXP_WFE_A_STG2_5X6_OUT0_4_RSVD3 0x000000C0
+#define BF_PXP_WFE_A_STG2_5X6_OUT0_4_RSVD3(v) \
+ (((v) << 6) & BM_PXP_WFE_A_STG2_5X6_OUT0_4_RSVD3)
+#define BP_PXP_WFE_A_STG2_5X6_OUT0_4_LUTOUT16 0
+#define BM_PXP_WFE_A_STG2_5X6_OUT0_4_LUTOUT16 0x0000003F
+#define BF_PXP_WFE_A_STG2_5X6_OUT0_4_LUTOUT16(v) \
+ (((v) << 0) & BM_PXP_WFE_A_STG2_5X6_OUT0_4_LUTOUT16)
+
+#define HW_PXP_WFE_A_STG2_5X6_OUT0_5 (0x00001ac0)
+
+#define BP_PXP_WFE_A_STG2_5X6_OUT0_5_RSVD0 30
+#define BM_PXP_WFE_A_STG2_5X6_OUT0_5_RSVD0 0xC0000000
+#define BF_PXP_WFE_A_STG2_5X6_OUT0_5_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFE_A_STG2_5X6_OUT0_5_RSVD0)
+#define BP_PXP_WFE_A_STG2_5X6_OUT0_5_LUTOUT23 24
+#define BM_PXP_WFE_A_STG2_5X6_OUT0_5_LUTOUT23 0x3F000000
+#define BF_PXP_WFE_A_STG2_5X6_OUT0_5_LUTOUT23(v) \
+ (((v) << 24) & BM_PXP_WFE_A_STG2_5X6_OUT0_5_LUTOUT23)
+#define BP_PXP_WFE_A_STG2_5X6_OUT0_5_RSVD1 22
+#define BM_PXP_WFE_A_STG2_5X6_OUT0_5_RSVD1 0x00C00000
+#define BF_PXP_WFE_A_STG2_5X6_OUT0_5_RSVD1(v) \
+ (((v) << 22) & BM_PXP_WFE_A_STG2_5X6_OUT0_5_RSVD1)
+#define BP_PXP_WFE_A_STG2_5X6_OUT0_5_LUTOUT22 16
+#define BM_PXP_WFE_A_STG2_5X6_OUT0_5_LUTOUT22 0x003F0000
+#define BF_PXP_WFE_A_STG2_5X6_OUT0_5_LUTOUT22(v) \
+ (((v) << 16) & BM_PXP_WFE_A_STG2_5X6_OUT0_5_LUTOUT22)
+#define BP_PXP_WFE_A_STG2_5X6_OUT0_5_RSVD2 14
+#define BM_PXP_WFE_A_STG2_5X6_OUT0_5_RSVD2 0x0000C000
+#define BF_PXP_WFE_A_STG2_5X6_OUT0_5_RSVD2(v) \
+ (((v) << 14) & BM_PXP_WFE_A_STG2_5X6_OUT0_5_RSVD2)
+#define BP_PXP_WFE_A_STG2_5X6_OUT0_5_LUTOUT21 8
+#define BM_PXP_WFE_A_STG2_5X6_OUT0_5_LUTOUT21 0x00003F00
+#define BF_PXP_WFE_A_STG2_5X6_OUT0_5_LUTOUT21(v) \
+ (((v) << 8) & BM_PXP_WFE_A_STG2_5X6_OUT0_5_LUTOUT21)
+#define BP_PXP_WFE_A_STG2_5X6_OUT0_5_RSVD3 6
+#define BM_PXP_WFE_A_STG2_5X6_OUT0_5_RSVD3 0x000000C0
+#define BF_PXP_WFE_A_STG2_5X6_OUT0_5_RSVD3(v) \
+ (((v) << 6) & BM_PXP_WFE_A_STG2_5X6_OUT0_5_RSVD3)
+#define BP_PXP_WFE_A_STG2_5X6_OUT0_5_LUTOUT20 0
+#define BM_PXP_WFE_A_STG2_5X6_OUT0_5_LUTOUT20 0x0000003F
+#define BF_PXP_WFE_A_STG2_5X6_OUT0_5_LUTOUT20(v) \
+ (((v) << 0) & BM_PXP_WFE_A_STG2_5X6_OUT0_5_LUTOUT20)
+
+#define HW_PXP_WFE_A_STG2_5X6_OUT0_6 (0x00001ad0)
+
+#define BP_PXP_WFE_A_STG2_5X6_OUT0_6_RSVD0 30
+#define BM_PXP_WFE_A_STG2_5X6_OUT0_6_RSVD0 0xC0000000
+#define BF_PXP_WFE_A_STG2_5X6_OUT0_6_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFE_A_STG2_5X6_OUT0_6_RSVD0)
+#define BP_PXP_WFE_A_STG2_5X6_OUT0_6_LUTOUT27 24
+#define BM_PXP_WFE_A_STG2_5X6_OUT0_6_LUTOUT27 0x3F000000
+#define BF_PXP_WFE_A_STG2_5X6_OUT0_6_LUTOUT27(v) \
+ (((v) << 24) & BM_PXP_WFE_A_STG2_5X6_OUT0_6_LUTOUT27)
+#define BP_PXP_WFE_A_STG2_5X6_OUT0_6_RSVD1 22
+#define BM_PXP_WFE_A_STG2_5X6_OUT0_6_RSVD1 0x00C00000
+#define BF_PXP_WFE_A_STG2_5X6_OUT0_6_RSVD1(v) \
+ (((v) << 22) & BM_PXP_WFE_A_STG2_5X6_OUT0_6_RSVD1)
+#define BP_PXP_WFE_A_STG2_5X6_OUT0_6_LUTOUT26 16
+#define BM_PXP_WFE_A_STG2_5X6_OUT0_6_LUTOUT26 0x003F0000
+#define BF_PXP_WFE_A_STG2_5X6_OUT0_6_LUTOUT26(v) \
+ (((v) << 16) & BM_PXP_WFE_A_STG2_5X6_OUT0_6_LUTOUT26)
+#define BP_PXP_WFE_A_STG2_5X6_OUT0_6_RSVD2 14
+#define BM_PXP_WFE_A_STG2_5X6_OUT0_6_RSVD2 0x0000C000
+#define BF_PXP_WFE_A_STG2_5X6_OUT0_6_RSVD2(v) \
+ (((v) << 14) & BM_PXP_WFE_A_STG2_5X6_OUT0_6_RSVD2)
+#define BP_PXP_WFE_A_STG2_5X6_OUT0_6_LUTOUT25 8
+#define BM_PXP_WFE_A_STG2_5X6_OUT0_6_LUTOUT25 0x00003F00
+#define BF_PXP_WFE_A_STG2_5X6_OUT0_6_LUTOUT25(v) \
+ (((v) << 8) & BM_PXP_WFE_A_STG2_5X6_OUT0_6_LUTOUT25)
+#define BP_PXP_WFE_A_STG2_5X6_OUT0_6_RSVD3 6
+#define BM_PXP_WFE_A_STG2_5X6_OUT0_6_RSVD3 0x000000C0
+#define BF_PXP_WFE_A_STG2_5X6_OUT0_6_RSVD3(v) \
+ (((v) << 6) & BM_PXP_WFE_A_STG2_5X6_OUT0_6_RSVD3)
+#define BP_PXP_WFE_A_STG2_5X6_OUT0_6_LUTOUT24 0
+#define BM_PXP_WFE_A_STG2_5X6_OUT0_6_LUTOUT24 0x0000003F
+#define BF_PXP_WFE_A_STG2_5X6_OUT0_6_LUTOUT24(v) \
+ (((v) << 0) & BM_PXP_WFE_A_STG2_5X6_OUT0_6_LUTOUT24)
+
+#define HW_PXP_WFE_A_STG2_5X6_OUT0_7 (0x00001ae0)
+
+#define BP_PXP_WFE_A_STG2_5X6_OUT0_7_RSVD0 30
+#define BM_PXP_WFE_A_STG2_5X6_OUT0_7_RSVD0 0xC0000000
+#define BF_PXP_WFE_A_STG2_5X6_OUT0_7_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFE_A_STG2_5X6_OUT0_7_RSVD0)
+#define BP_PXP_WFE_A_STG2_5X6_OUT0_7_LUTOUT31 24
+#define BM_PXP_WFE_A_STG2_5X6_OUT0_7_LUTOUT31 0x3F000000
+#define BF_PXP_WFE_A_STG2_5X6_OUT0_7_LUTOUT31(v) \
+ (((v) << 24) & BM_PXP_WFE_A_STG2_5X6_OUT0_7_LUTOUT31)
+#define BP_PXP_WFE_A_STG2_5X6_OUT0_7_RSVD1 22
+#define BM_PXP_WFE_A_STG2_5X6_OUT0_7_RSVD1 0x00C00000
+#define BF_PXP_WFE_A_STG2_5X6_OUT0_7_RSVD1(v) \
+ (((v) << 22) & BM_PXP_WFE_A_STG2_5X6_OUT0_7_RSVD1)
+#define BP_PXP_WFE_A_STG2_5X6_OUT0_7_LUTOUT30 16
+#define BM_PXP_WFE_A_STG2_5X6_OUT0_7_LUTOUT30 0x003F0000
+#define BF_PXP_WFE_A_STG2_5X6_OUT0_7_LUTOUT30(v) \
+ (((v) << 16) & BM_PXP_WFE_A_STG2_5X6_OUT0_7_LUTOUT30)
+#define BP_PXP_WFE_A_STG2_5X6_OUT0_7_RSVD2 14
+#define BM_PXP_WFE_A_STG2_5X6_OUT0_7_RSVD2 0x0000C000
+#define BF_PXP_WFE_A_STG2_5X6_OUT0_7_RSVD2(v) \
+ (((v) << 14) & BM_PXP_WFE_A_STG2_5X6_OUT0_7_RSVD2)
+#define BP_PXP_WFE_A_STG2_5X6_OUT0_7_LUTOUT29 8
+#define BM_PXP_WFE_A_STG2_5X6_OUT0_7_LUTOUT29 0x00003F00
+#define BF_PXP_WFE_A_STG2_5X6_OUT0_7_LUTOUT29(v) \
+ (((v) << 8) & BM_PXP_WFE_A_STG2_5X6_OUT0_7_LUTOUT29)
+#define BP_PXP_WFE_A_STG2_5X6_OUT0_7_RSVD3 6
+#define BM_PXP_WFE_A_STG2_5X6_OUT0_7_RSVD3 0x000000C0
+#define BF_PXP_WFE_A_STG2_5X6_OUT0_7_RSVD3(v) \
+ (((v) << 6) & BM_PXP_WFE_A_STG2_5X6_OUT0_7_RSVD3)
+#define BP_PXP_WFE_A_STG2_5X6_OUT0_7_LUTOUT28 0
+#define BM_PXP_WFE_A_STG2_5X6_OUT0_7_LUTOUT28 0x0000003F
+#define BF_PXP_WFE_A_STG2_5X6_OUT0_7_LUTOUT28(v) \
+ (((v) << 0) & BM_PXP_WFE_A_STG2_5X6_OUT0_7_LUTOUT28)
+
+#define HW_PXP_WFE_A_STG2_5X6_OUT1_0 (0x00001af0)
+
+#define BP_PXP_WFE_A_STG2_5X6_OUT1_0_RSVD0 30
+#define BM_PXP_WFE_A_STG2_5X6_OUT1_0_RSVD0 0xC0000000
+#define BF_PXP_WFE_A_STG2_5X6_OUT1_0_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFE_A_STG2_5X6_OUT1_0_RSVD0)
+#define BP_PXP_WFE_A_STG2_5X6_OUT1_0_LUTOUT3 24
+#define BM_PXP_WFE_A_STG2_5X6_OUT1_0_LUTOUT3 0x3F000000
+#define BF_PXP_WFE_A_STG2_5X6_OUT1_0_LUTOUT3(v) \
+ (((v) << 24) & BM_PXP_WFE_A_STG2_5X6_OUT1_0_LUTOUT3)
+#define BP_PXP_WFE_A_STG2_5X6_OUT1_0_RSVD1 22
+#define BM_PXP_WFE_A_STG2_5X6_OUT1_0_RSVD1 0x00C00000
+#define BF_PXP_WFE_A_STG2_5X6_OUT1_0_RSVD1(v) \
+ (((v) << 22) & BM_PXP_WFE_A_STG2_5X6_OUT1_0_RSVD1)
+#define BP_PXP_WFE_A_STG2_5X6_OUT1_0_LUTOUT2 16
+#define BM_PXP_WFE_A_STG2_5X6_OUT1_0_LUTOUT2 0x003F0000
+#define BF_PXP_WFE_A_STG2_5X6_OUT1_0_LUTOUT2(v) \
+ (((v) << 16) & BM_PXP_WFE_A_STG2_5X6_OUT1_0_LUTOUT2)
+#define BP_PXP_WFE_A_STG2_5X6_OUT1_0_RSVD2 14
+#define BM_PXP_WFE_A_STG2_5X6_OUT1_0_RSVD2 0x0000C000
+#define BF_PXP_WFE_A_STG2_5X6_OUT1_0_RSVD2(v) \
+ (((v) << 14) & BM_PXP_WFE_A_STG2_5X6_OUT1_0_RSVD2)
+#define BP_PXP_WFE_A_STG2_5X6_OUT1_0_LUTOUT1 8
+#define BM_PXP_WFE_A_STG2_5X6_OUT1_0_LUTOUT1 0x00003F00
+#define BF_PXP_WFE_A_STG2_5X6_OUT1_0_LUTOUT1(v) \
+ (((v) << 8) & BM_PXP_WFE_A_STG2_5X6_OUT1_0_LUTOUT1)
+#define BP_PXP_WFE_A_STG2_5X6_OUT1_0_RSVD3 6
+#define BM_PXP_WFE_A_STG2_5X6_OUT1_0_RSVD3 0x000000C0
+#define BF_PXP_WFE_A_STG2_5X6_OUT1_0_RSVD3(v) \
+ (((v) << 6) & BM_PXP_WFE_A_STG2_5X6_OUT1_0_RSVD3)
+#define BP_PXP_WFE_A_STG2_5X6_OUT1_0_LUTOUT0 0
+#define BM_PXP_WFE_A_STG2_5X6_OUT1_0_LUTOUT0 0x0000003F
+#define BF_PXP_WFE_A_STG2_5X6_OUT1_0_LUTOUT0(v) \
+ (((v) << 0) & BM_PXP_WFE_A_STG2_5X6_OUT1_0_LUTOUT0)
+
+#define HW_PXP_WFE_A_STG2_5X6_OUT1_1 (0x00001b00)
+
+#define BP_PXP_WFE_A_STG2_5X6_OUT1_1_RSVD0 30
+#define BM_PXP_WFE_A_STG2_5X6_OUT1_1_RSVD0 0xC0000000
+#define BF_PXP_WFE_A_STG2_5X6_OUT1_1_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFE_A_STG2_5X6_OUT1_1_RSVD0)
+#define BP_PXP_WFE_A_STG2_5X6_OUT1_1_LUTOUT7 24
+#define BM_PXP_WFE_A_STG2_5X6_OUT1_1_LUTOUT7 0x3F000000
+#define BF_PXP_WFE_A_STG2_5X6_OUT1_1_LUTOUT7(v) \
+ (((v) << 24) & BM_PXP_WFE_A_STG2_5X6_OUT1_1_LUTOUT7)
+#define BP_PXP_WFE_A_STG2_5X6_OUT1_1_RSVD1 22
+#define BM_PXP_WFE_A_STG2_5X6_OUT1_1_RSVD1 0x00C00000
+#define BF_PXP_WFE_A_STG2_5X6_OUT1_1_RSVD1(v) \
+ (((v) << 22) & BM_PXP_WFE_A_STG2_5X6_OUT1_1_RSVD1)
+#define BP_PXP_WFE_A_STG2_5X6_OUT1_1_LUTOUT6 16
+#define BM_PXP_WFE_A_STG2_5X6_OUT1_1_LUTOUT6 0x003F0000
+#define BF_PXP_WFE_A_STG2_5X6_OUT1_1_LUTOUT6(v) \
+ (((v) << 16) & BM_PXP_WFE_A_STG2_5X6_OUT1_1_LUTOUT6)
+#define BP_PXP_WFE_A_STG2_5X6_OUT1_1_RSVD2 14
+#define BM_PXP_WFE_A_STG2_5X6_OUT1_1_RSVD2 0x0000C000
+#define BF_PXP_WFE_A_STG2_5X6_OUT1_1_RSVD2(v) \
+ (((v) << 14) & BM_PXP_WFE_A_STG2_5X6_OUT1_1_RSVD2)
+#define BP_PXP_WFE_A_STG2_5X6_OUT1_1_LUTOUT5 8
+#define BM_PXP_WFE_A_STG2_5X6_OUT1_1_LUTOUT5 0x00003F00
+#define BF_PXP_WFE_A_STG2_5X6_OUT1_1_LUTOUT5(v) \
+ (((v) << 8) & BM_PXP_WFE_A_STG2_5X6_OUT1_1_LUTOUT5)
+#define BP_PXP_WFE_A_STG2_5X6_OUT1_1_RSVD3 6
+#define BM_PXP_WFE_A_STG2_5X6_OUT1_1_RSVD3 0x000000C0
+#define BF_PXP_WFE_A_STG2_5X6_OUT1_1_RSVD3(v) \
+ (((v) << 6) & BM_PXP_WFE_A_STG2_5X6_OUT1_1_RSVD3)
+#define BP_PXP_WFE_A_STG2_5X6_OUT1_1_LUTOUT4 0
+#define BM_PXP_WFE_A_STG2_5X6_OUT1_1_LUTOUT4 0x0000003F
+#define BF_PXP_WFE_A_STG2_5X6_OUT1_1_LUTOUT4(v) \
+ (((v) << 0) & BM_PXP_WFE_A_STG2_5X6_OUT1_1_LUTOUT4)
+
+#define HW_PXP_WFE_A_STG2_5X6_OUT1_2 (0x00001b10)
+
+#define BP_PXP_WFE_A_STG2_5X6_OUT1_2_RSVD0 30
+#define BM_PXP_WFE_A_STG2_5X6_OUT1_2_RSVD0 0xC0000000
+#define BF_PXP_WFE_A_STG2_5X6_OUT1_2_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFE_A_STG2_5X6_OUT1_2_RSVD0)
+#define BP_PXP_WFE_A_STG2_5X6_OUT1_2_LUTOUT11 24
+#define BM_PXP_WFE_A_STG2_5X6_OUT1_2_LUTOUT11 0x3F000000
+#define BF_PXP_WFE_A_STG2_5X6_OUT1_2_LUTOUT11(v) \
+ (((v) << 24) & BM_PXP_WFE_A_STG2_5X6_OUT1_2_LUTOUT11)
+#define BP_PXP_WFE_A_STG2_5X6_OUT1_2_RSVD1 22
+#define BM_PXP_WFE_A_STG2_5X6_OUT1_2_RSVD1 0x00C00000
+#define BF_PXP_WFE_A_STG2_5X6_OUT1_2_RSVD1(v) \
+ (((v) << 22) & BM_PXP_WFE_A_STG2_5X6_OUT1_2_RSVD1)
+#define BP_PXP_WFE_A_STG2_5X6_OUT1_2_LUTOUT10 16
+#define BM_PXP_WFE_A_STG2_5X6_OUT1_2_LUTOUT10 0x003F0000
+#define BF_PXP_WFE_A_STG2_5X6_OUT1_2_LUTOUT10(v) \
+ (((v) << 16) & BM_PXP_WFE_A_STG2_5X6_OUT1_2_LUTOUT10)
+#define BP_PXP_WFE_A_STG2_5X6_OUT1_2_RSVD2 14
+#define BM_PXP_WFE_A_STG2_5X6_OUT1_2_RSVD2 0x0000C000
+#define BF_PXP_WFE_A_STG2_5X6_OUT1_2_RSVD2(v) \
+ (((v) << 14) & BM_PXP_WFE_A_STG2_5X6_OUT1_2_RSVD2)
+#define BP_PXP_WFE_A_STG2_5X6_OUT1_2_LUTOUT9 8
+#define BM_PXP_WFE_A_STG2_5X6_OUT1_2_LUTOUT9 0x00003F00
+#define BF_PXP_WFE_A_STG2_5X6_OUT1_2_LUTOUT9(v) \
+ (((v) << 8) & BM_PXP_WFE_A_STG2_5X6_OUT1_2_LUTOUT9)
+#define BP_PXP_WFE_A_STG2_5X6_OUT1_2_RSVD3 6
+#define BM_PXP_WFE_A_STG2_5X6_OUT1_2_RSVD3 0x000000C0
+#define BF_PXP_WFE_A_STG2_5X6_OUT1_2_RSVD3(v) \
+ (((v) << 6) & BM_PXP_WFE_A_STG2_5X6_OUT1_2_RSVD3)
+#define BP_PXP_WFE_A_STG2_5X6_OUT1_2_LUTOUT8 0
+#define BM_PXP_WFE_A_STG2_5X6_OUT1_2_LUTOUT8 0x0000003F
+#define BF_PXP_WFE_A_STG2_5X6_OUT1_2_LUTOUT8(v) \
+ (((v) << 0) & BM_PXP_WFE_A_STG2_5X6_OUT1_2_LUTOUT8)
+
+#define HW_PXP_WFE_A_STG2_5X6_OUT1_3 (0x00001b20)
+
+#define BP_PXP_WFE_A_STG2_5X6_OUT1_3_RSVD0 30
+#define BM_PXP_WFE_A_STG2_5X6_OUT1_3_RSVD0 0xC0000000
+#define BF_PXP_WFE_A_STG2_5X6_OUT1_3_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFE_A_STG2_5X6_OUT1_3_RSVD0)
+#define BP_PXP_WFE_A_STG2_5X6_OUT1_3_LUTOUT15 24
+#define BM_PXP_WFE_A_STG2_5X6_OUT1_3_LUTOUT15 0x3F000000
+#define BF_PXP_WFE_A_STG2_5X6_OUT1_3_LUTOUT15(v) \
+ (((v) << 24) & BM_PXP_WFE_A_STG2_5X6_OUT1_3_LUTOUT15)
+#define BP_PXP_WFE_A_STG2_5X6_OUT1_3_RSVD1 22
+#define BM_PXP_WFE_A_STG2_5X6_OUT1_3_RSVD1 0x00C00000
+#define BF_PXP_WFE_A_STG2_5X6_OUT1_3_RSVD1(v) \
+ (((v) << 22) & BM_PXP_WFE_A_STG2_5X6_OUT1_3_RSVD1)
+#define BP_PXP_WFE_A_STG2_5X6_OUT1_3_LUTOUT14 16
+#define BM_PXP_WFE_A_STG2_5X6_OUT1_3_LUTOUT14 0x003F0000
+#define BF_PXP_WFE_A_STG2_5X6_OUT1_3_LUTOUT14(v) \
+ (((v) << 16) & BM_PXP_WFE_A_STG2_5X6_OUT1_3_LUTOUT14)
+#define BP_PXP_WFE_A_STG2_5X6_OUT1_3_RSVD2 14
+#define BM_PXP_WFE_A_STG2_5X6_OUT1_3_RSVD2 0x0000C000
+#define BF_PXP_WFE_A_STG2_5X6_OUT1_3_RSVD2(v) \
+ (((v) << 14) & BM_PXP_WFE_A_STG2_5X6_OUT1_3_RSVD2)
+#define BP_PXP_WFE_A_STG2_5X6_OUT1_3_LUTOUT13 8
+#define BM_PXP_WFE_A_STG2_5X6_OUT1_3_LUTOUT13 0x00003F00
+#define BF_PXP_WFE_A_STG2_5X6_OUT1_3_LUTOUT13(v) \
+ (((v) << 8) & BM_PXP_WFE_A_STG2_5X6_OUT1_3_LUTOUT13)
+#define BP_PXP_WFE_A_STG2_5X6_OUT1_3_RSVD3 6
+#define BM_PXP_WFE_A_STG2_5X6_OUT1_3_RSVD3 0x000000C0
+#define BF_PXP_WFE_A_STG2_5X6_OUT1_3_RSVD3(v) \
+ (((v) << 6) & BM_PXP_WFE_A_STG2_5X6_OUT1_3_RSVD3)
+#define BP_PXP_WFE_A_STG2_5X6_OUT1_3_LUTOUT12 0
+#define BM_PXP_WFE_A_STG2_5X6_OUT1_3_LUTOUT12 0x0000003F
+#define BF_PXP_WFE_A_STG2_5X6_OUT1_3_LUTOUT12(v) \
+ (((v) << 0) & BM_PXP_WFE_A_STG2_5X6_OUT1_3_LUTOUT12)
+
+#define HW_PXP_WFE_A_STG2_5X6_OUT1_4 (0x00001b30)
+
+#define BP_PXP_WFE_A_STG2_5X6_OUT1_4_RSVD0 30
+#define BM_PXP_WFE_A_STG2_5X6_OUT1_4_RSVD0 0xC0000000
+#define BF_PXP_WFE_A_STG2_5X6_OUT1_4_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFE_A_STG2_5X6_OUT1_4_RSVD0)
+#define BP_PXP_WFE_A_STG2_5X6_OUT1_4_LUTOUT19 24
+#define BM_PXP_WFE_A_STG2_5X6_OUT1_4_LUTOUT19 0x3F000000
+#define BF_PXP_WFE_A_STG2_5X6_OUT1_4_LUTOUT19(v) \
+ (((v) << 24) & BM_PXP_WFE_A_STG2_5X6_OUT1_4_LUTOUT19)
+#define BP_PXP_WFE_A_STG2_5X6_OUT1_4_RSVD1 22
+#define BM_PXP_WFE_A_STG2_5X6_OUT1_4_RSVD1 0x00C00000
+#define BF_PXP_WFE_A_STG2_5X6_OUT1_4_RSVD1(v) \
+ (((v) << 22) & BM_PXP_WFE_A_STG2_5X6_OUT1_4_RSVD1)
+#define BP_PXP_WFE_A_STG2_5X6_OUT1_4_LUTOUT18 16
+#define BM_PXP_WFE_A_STG2_5X6_OUT1_4_LUTOUT18 0x003F0000
+#define BF_PXP_WFE_A_STG2_5X6_OUT1_4_LUTOUT18(v) \
+ (((v) << 16) & BM_PXP_WFE_A_STG2_5X6_OUT1_4_LUTOUT18)
+#define BP_PXP_WFE_A_STG2_5X6_OUT1_4_RSVD2 14
+#define BM_PXP_WFE_A_STG2_5X6_OUT1_4_RSVD2 0x0000C000
+#define BF_PXP_WFE_A_STG2_5X6_OUT1_4_RSVD2(v) \
+ (((v) << 14) & BM_PXP_WFE_A_STG2_5X6_OUT1_4_RSVD2)
+#define BP_PXP_WFE_A_STG2_5X6_OUT1_4_LUTOUT17 8
+#define BM_PXP_WFE_A_STG2_5X6_OUT1_4_LUTOUT17 0x00003F00
+#define BF_PXP_WFE_A_STG2_5X6_OUT1_4_LUTOUT17(v) \
+ (((v) << 8) & BM_PXP_WFE_A_STG2_5X6_OUT1_4_LUTOUT17)
+#define BP_PXP_WFE_A_STG2_5X6_OUT1_4_RSVD3 6
+#define BM_PXP_WFE_A_STG2_5X6_OUT1_4_RSVD3 0x000000C0
+#define BF_PXP_WFE_A_STG2_5X6_OUT1_4_RSVD3(v) \
+ (((v) << 6) & BM_PXP_WFE_A_STG2_5X6_OUT1_4_RSVD3)
+#define BP_PXP_WFE_A_STG2_5X6_OUT1_4_LUTOUT16 0
+#define BM_PXP_WFE_A_STG2_5X6_OUT1_4_LUTOUT16 0x0000003F
+#define BF_PXP_WFE_A_STG2_5X6_OUT1_4_LUTOUT16(v) \
+ (((v) << 0) & BM_PXP_WFE_A_STG2_5X6_OUT1_4_LUTOUT16)
+
+#define HW_PXP_WFE_A_STG2_5X6_OUT1_5 (0x00001b40)
+
+#define BP_PXP_WFE_A_STG2_5X6_OUT1_5_RSVD0 30
+#define BM_PXP_WFE_A_STG2_5X6_OUT1_5_RSVD0 0xC0000000
+#define BF_PXP_WFE_A_STG2_5X6_OUT1_5_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFE_A_STG2_5X6_OUT1_5_RSVD0)
+#define BP_PXP_WFE_A_STG2_5X6_OUT1_5_LUTOUT23 24
+#define BM_PXP_WFE_A_STG2_5X6_OUT1_5_LUTOUT23 0x3F000000
+#define BF_PXP_WFE_A_STG2_5X6_OUT1_5_LUTOUT23(v) \
+ (((v) << 24) & BM_PXP_WFE_A_STG2_5X6_OUT1_5_LUTOUT23)
+#define BP_PXP_WFE_A_STG2_5X6_OUT1_5_RSVD1 22
+#define BM_PXP_WFE_A_STG2_5X6_OUT1_5_RSVD1 0x00C00000
+#define BF_PXP_WFE_A_STG2_5X6_OUT1_5_RSVD1(v) \
+ (((v) << 22) & BM_PXP_WFE_A_STG2_5X6_OUT1_5_RSVD1)
+#define BP_PXP_WFE_A_STG2_5X6_OUT1_5_LUTOUT22 16
+#define BM_PXP_WFE_A_STG2_5X6_OUT1_5_LUTOUT22 0x003F0000
+#define BF_PXP_WFE_A_STG2_5X6_OUT1_5_LUTOUT22(v) \
+ (((v) << 16) & BM_PXP_WFE_A_STG2_5X6_OUT1_5_LUTOUT22)
+#define BP_PXP_WFE_A_STG2_5X6_OUT1_5_RSVD2 14
+#define BM_PXP_WFE_A_STG2_5X6_OUT1_5_RSVD2 0x0000C000
+#define BF_PXP_WFE_A_STG2_5X6_OUT1_5_RSVD2(v) \
+ (((v) << 14) & BM_PXP_WFE_A_STG2_5X6_OUT1_5_RSVD2)
+#define BP_PXP_WFE_A_STG2_5X6_OUT1_5_LUTOUT21 8
+#define BM_PXP_WFE_A_STG2_5X6_OUT1_5_LUTOUT21 0x00003F00
+#define BF_PXP_WFE_A_STG2_5X6_OUT1_5_LUTOUT21(v) \
+ (((v) << 8) & BM_PXP_WFE_A_STG2_5X6_OUT1_5_LUTOUT21)
+#define BP_PXP_WFE_A_STG2_5X6_OUT1_5_RSVD3 6
+#define BM_PXP_WFE_A_STG2_5X6_OUT1_5_RSVD3 0x000000C0
+#define BF_PXP_WFE_A_STG2_5X6_OUT1_5_RSVD3(v) \
+ (((v) << 6) & BM_PXP_WFE_A_STG2_5X6_OUT1_5_RSVD3)
+#define BP_PXP_WFE_A_STG2_5X6_OUT1_5_LUTOUT20 0
+#define BM_PXP_WFE_A_STG2_5X6_OUT1_5_LUTOUT20 0x0000003F
+#define BF_PXP_WFE_A_STG2_5X6_OUT1_5_LUTOUT20(v) \
+ (((v) << 0) & BM_PXP_WFE_A_STG2_5X6_OUT1_5_LUTOUT20)
+
+#define HW_PXP_WFE_A_STG2_5X6_OUT1_6 (0x00001b50)
+
+#define BP_PXP_WFE_A_STG2_5X6_OUT1_6_RSVD0 30
+#define BM_PXP_WFE_A_STG2_5X6_OUT1_6_RSVD0 0xC0000000
+#define BF_PXP_WFE_A_STG2_5X6_OUT1_6_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFE_A_STG2_5X6_OUT1_6_RSVD0)
+#define BP_PXP_WFE_A_STG2_5X6_OUT1_6_LUTOUT27 24
+#define BM_PXP_WFE_A_STG2_5X6_OUT1_6_LUTOUT27 0x3F000000
+#define BF_PXP_WFE_A_STG2_5X6_OUT1_6_LUTOUT27(v) \
+ (((v) << 24) & BM_PXP_WFE_A_STG2_5X6_OUT1_6_LUTOUT27)
+#define BP_PXP_WFE_A_STG2_5X6_OUT1_6_RSVD1 22
+#define BM_PXP_WFE_A_STG2_5X6_OUT1_6_RSVD1 0x00C00000
+#define BF_PXP_WFE_A_STG2_5X6_OUT1_6_RSVD1(v) \
+ (((v) << 22) & BM_PXP_WFE_A_STG2_5X6_OUT1_6_RSVD1)
+#define BP_PXP_WFE_A_STG2_5X6_OUT1_6_LUTOUT26 16
+#define BM_PXP_WFE_A_STG2_5X6_OUT1_6_LUTOUT26 0x003F0000
+#define BF_PXP_WFE_A_STG2_5X6_OUT1_6_LUTOUT26(v) \
+ (((v) << 16) & BM_PXP_WFE_A_STG2_5X6_OUT1_6_LUTOUT26)
+#define BP_PXP_WFE_A_STG2_5X6_OUT1_6_RSVD2 14
+#define BM_PXP_WFE_A_STG2_5X6_OUT1_6_RSVD2 0x0000C000
+#define BF_PXP_WFE_A_STG2_5X6_OUT1_6_RSVD2(v) \
+ (((v) << 14) & BM_PXP_WFE_A_STG2_5X6_OUT1_6_RSVD2)
+#define BP_PXP_WFE_A_STG2_5X6_OUT1_6_LUTOUT25 8
+#define BM_PXP_WFE_A_STG2_5X6_OUT1_6_LUTOUT25 0x00003F00
+#define BF_PXP_WFE_A_STG2_5X6_OUT1_6_LUTOUT25(v) \
+ (((v) << 8) & BM_PXP_WFE_A_STG2_5X6_OUT1_6_LUTOUT25)
+#define BP_PXP_WFE_A_STG2_5X6_OUT1_6_RSVD3 6
+#define BM_PXP_WFE_A_STG2_5X6_OUT1_6_RSVD3 0x000000C0
+#define BF_PXP_WFE_A_STG2_5X6_OUT1_6_RSVD3(v) \
+ (((v) << 6) & BM_PXP_WFE_A_STG2_5X6_OUT1_6_RSVD3)
+#define BP_PXP_WFE_A_STG2_5X6_OUT1_6_LUTOUT24 0
+#define BM_PXP_WFE_A_STG2_5X6_OUT1_6_LUTOUT24 0x0000003F
+#define BF_PXP_WFE_A_STG2_5X6_OUT1_6_LUTOUT24(v) \
+ (((v) << 0) & BM_PXP_WFE_A_STG2_5X6_OUT1_6_LUTOUT24)
+
+#define HW_PXP_WFE_A_STG2_5X6_OUT1_7 (0x00001b60)
+
+#define BP_PXP_WFE_A_STG2_5X6_OUT1_7_RSVD0 30
+#define BM_PXP_WFE_A_STG2_5X6_OUT1_7_RSVD0 0xC0000000
+#define BF_PXP_WFE_A_STG2_5X6_OUT1_7_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFE_A_STG2_5X6_OUT1_7_RSVD0)
+#define BP_PXP_WFE_A_STG2_5X6_OUT1_7_LUTOUT31 24
+#define BM_PXP_WFE_A_STG2_5X6_OUT1_7_LUTOUT31 0x3F000000
+#define BF_PXP_WFE_A_STG2_5X6_OUT1_7_LUTOUT31(v) \
+ (((v) << 24) & BM_PXP_WFE_A_STG2_5X6_OUT1_7_LUTOUT31)
+#define BP_PXP_WFE_A_STG2_5X6_OUT1_7_RSVD1 22
+#define BM_PXP_WFE_A_STG2_5X6_OUT1_7_RSVD1 0x00C00000
+#define BF_PXP_WFE_A_STG2_5X6_OUT1_7_RSVD1(v) \
+ (((v) << 22) & BM_PXP_WFE_A_STG2_5X6_OUT1_7_RSVD1)
+#define BP_PXP_WFE_A_STG2_5X6_OUT1_7_LUTOUT30 16
+#define BM_PXP_WFE_A_STG2_5X6_OUT1_7_LUTOUT30 0x003F0000
+#define BF_PXP_WFE_A_STG2_5X6_OUT1_7_LUTOUT30(v) \
+ (((v) << 16) & BM_PXP_WFE_A_STG2_5X6_OUT1_7_LUTOUT30)
+#define BP_PXP_WFE_A_STG2_5X6_OUT1_7_RSVD2 14
+#define BM_PXP_WFE_A_STG2_5X6_OUT1_7_RSVD2 0x0000C000
+#define BF_PXP_WFE_A_STG2_5X6_OUT1_7_RSVD2(v) \
+ (((v) << 14) & BM_PXP_WFE_A_STG2_5X6_OUT1_7_RSVD2)
+#define BP_PXP_WFE_A_STG2_5X6_OUT1_7_LUTOUT29 8
+#define BM_PXP_WFE_A_STG2_5X6_OUT1_7_LUTOUT29 0x00003F00
+#define BF_PXP_WFE_A_STG2_5X6_OUT1_7_LUTOUT29(v) \
+ (((v) << 8) & BM_PXP_WFE_A_STG2_5X6_OUT1_7_LUTOUT29)
+#define BP_PXP_WFE_A_STG2_5X6_OUT1_7_RSVD3 6
+#define BM_PXP_WFE_A_STG2_5X6_OUT1_7_RSVD3 0x000000C0
+#define BF_PXP_WFE_A_STG2_5X6_OUT1_7_RSVD3(v) \
+ (((v) << 6) & BM_PXP_WFE_A_STG2_5X6_OUT1_7_RSVD3)
+#define BP_PXP_WFE_A_STG2_5X6_OUT1_7_LUTOUT28 0
+#define BM_PXP_WFE_A_STG2_5X6_OUT1_7_LUTOUT28 0x0000003F
+#define BF_PXP_WFE_A_STG2_5X6_OUT1_7_LUTOUT28(v) \
+ (((v) << 0) & BM_PXP_WFE_A_STG2_5X6_OUT1_7_LUTOUT28)
+
+#define HW_PXP_WFE_A_STG2_5X6_OUT2_0 (0x00001b70)
+
+#define BP_PXP_WFE_A_STG2_5X6_OUT2_0_RSVD0 30
+#define BM_PXP_WFE_A_STG2_5X6_OUT2_0_RSVD0 0xC0000000
+#define BF_PXP_WFE_A_STG2_5X6_OUT2_0_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFE_A_STG2_5X6_OUT2_0_RSVD0)
+#define BP_PXP_WFE_A_STG2_5X6_OUT2_0_LUTOUT3 24
+#define BM_PXP_WFE_A_STG2_5X6_OUT2_0_LUTOUT3 0x3F000000
+#define BF_PXP_WFE_A_STG2_5X6_OUT2_0_LUTOUT3(v) \
+ (((v) << 24) & BM_PXP_WFE_A_STG2_5X6_OUT2_0_LUTOUT3)
+#define BP_PXP_WFE_A_STG2_5X6_OUT2_0_RSVD1 22
+#define BM_PXP_WFE_A_STG2_5X6_OUT2_0_RSVD1 0x00C00000
+#define BF_PXP_WFE_A_STG2_5X6_OUT2_0_RSVD1(v) \
+ (((v) << 22) & BM_PXP_WFE_A_STG2_5X6_OUT2_0_RSVD1)
+#define BP_PXP_WFE_A_STG2_5X6_OUT2_0_LUTOUT2 16
+#define BM_PXP_WFE_A_STG2_5X6_OUT2_0_LUTOUT2 0x003F0000
+#define BF_PXP_WFE_A_STG2_5X6_OUT2_0_LUTOUT2(v) \
+ (((v) << 16) & BM_PXP_WFE_A_STG2_5X6_OUT2_0_LUTOUT2)
+#define BP_PXP_WFE_A_STG2_5X6_OUT2_0_RSVD2 14
+#define BM_PXP_WFE_A_STG2_5X6_OUT2_0_RSVD2 0x0000C000
+#define BF_PXP_WFE_A_STG2_5X6_OUT2_0_RSVD2(v) \
+ (((v) << 14) & BM_PXP_WFE_A_STG2_5X6_OUT2_0_RSVD2)
+#define BP_PXP_WFE_A_STG2_5X6_OUT2_0_LUTOUT1 8
+#define BM_PXP_WFE_A_STG2_5X6_OUT2_0_LUTOUT1 0x00003F00
+#define BF_PXP_WFE_A_STG2_5X6_OUT2_0_LUTOUT1(v) \
+ (((v) << 8) & BM_PXP_WFE_A_STG2_5X6_OUT2_0_LUTOUT1)
+#define BP_PXP_WFE_A_STG2_5X6_OUT2_0_RSVD3 6
+#define BM_PXP_WFE_A_STG2_5X6_OUT2_0_RSVD3 0x000000C0
+#define BF_PXP_WFE_A_STG2_5X6_OUT2_0_RSVD3(v) \
+ (((v) << 6) & BM_PXP_WFE_A_STG2_5X6_OUT2_0_RSVD3)
+#define BP_PXP_WFE_A_STG2_5X6_OUT2_0_LUTOUT0 0
+#define BM_PXP_WFE_A_STG2_5X6_OUT2_0_LUTOUT0 0x0000003F
+#define BF_PXP_WFE_A_STG2_5X6_OUT2_0_LUTOUT0(v) \
+ (((v) << 0) & BM_PXP_WFE_A_STG2_5X6_OUT2_0_LUTOUT0)
+
+#define HW_PXP_WFE_A_STG2_5X6_OUT2_1 (0x00001b80)
+
+#define BP_PXP_WFE_A_STG2_5X6_OUT2_1_RSVD0 30
+#define BM_PXP_WFE_A_STG2_5X6_OUT2_1_RSVD0 0xC0000000
+#define BF_PXP_WFE_A_STG2_5X6_OUT2_1_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFE_A_STG2_5X6_OUT2_1_RSVD0)
+#define BP_PXP_WFE_A_STG2_5X6_OUT2_1_LUTOUT7 24
+#define BM_PXP_WFE_A_STG2_5X6_OUT2_1_LUTOUT7 0x3F000000
+#define BF_PXP_WFE_A_STG2_5X6_OUT2_1_LUTOUT7(v) \
+ (((v) << 24) & BM_PXP_WFE_A_STG2_5X6_OUT2_1_LUTOUT7)
+#define BP_PXP_WFE_A_STG2_5X6_OUT2_1_RSVD1 22
+#define BM_PXP_WFE_A_STG2_5X6_OUT2_1_RSVD1 0x00C00000
+#define BF_PXP_WFE_A_STG2_5X6_OUT2_1_RSVD1(v) \
+ (((v) << 22) & BM_PXP_WFE_A_STG2_5X6_OUT2_1_RSVD1)
+#define BP_PXP_WFE_A_STG2_5X6_OUT2_1_LUTOUT6 16
+#define BM_PXP_WFE_A_STG2_5X6_OUT2_1_LUTOUT6 0x003F0000
+#define BF_PXP_WFE_A_STG2_5X6_OUT2_1_LUTOUT6(v) \
+ (((v) << 16) & BM_PXP_WFE_A_STG2_5X6_OUT2_1_LUTOUT6)
+#define BP_PXP_WFE_A_STG2_5X6_OUT2_1_RSVD2 14
+#define BM_PXP_WFE_A_STG2_5X6_OUT2_1_RSVD2 0x0000C000
+#define BF_PXP_WFE_A_STG2_5X6_OUT2_1_RSVD2(v) \
+ (((v) << 14) & BM_PXP_WFE_A_STG2_5X6_OUT2_1_RSVD2)
+#define BP_PXP_WFE_A_STG2_5X6_OUT2_1_LUTOUT5 8
+#define BM_PXP_WFE_A_STG2_5X6_OUT2_1_LUTOUT5 0x00003F00
+#define BF_PXP_WFE_A_STG2_5X6_OUT2_1_LUTOUT5(v) \
+ (((v) << 8) & BM_PXP_WFE_A_STG2_5X6_OUT2_1_LUTOUT5)
+#define BP_PXP_WFE_A_STG2_5X6_OUT2_1_RSVD3 6
+#define BM_PXP_WFE_A_STG2_5X6_OUT2_1_RSVD3 0x000000C0
+#define BF_PXP_WFE_A_STG2_5X6_OUT2_1_RSVD3(v) \
+ (((v) << 6) & BM_PXP_WFE_A_STG2_5X6_OUT2_1_RSVD3)
+#define BP_PXP_WFE_A_STG2_5X6_OUT2_1_LUTOUT4 0
+#define BM_PXP_WFE_A_STG2_5X6_OUT2_1_LUTOUT4 0x0000003F
+#define BF_PXP_WFE_A_STG2_5X6_OUT2_1_LUTOUT4(v) \
+ (((v) << 0) & BM_PXP_WFE_A_STG2_5X6_OUT2_1_LUTOUT4)
+
+#define HW_PXP_WFE_A_STG2_5X6_OUT2_2 (0x00001b90)
+
+#define BP_PXP_WFE_A_STG2_5X6_OUT2_2_RSVD0 30
+#define BM_PXP_WFE_A_STG2_5X6_OUT2_2_RSVD0 0xC0000000
+#define BF_PXP_WFE_A_STG2_5X6_OUT2_2_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFE_A_STG2_5X6_OUT2_2_RSVD0)
+#define BP_PXP_WFE_A_STG2_5X6_OUT2_2_LUTOUT11 24
+#define BM_PXP_WFE_A_STG2_5X6_OUT2_2_LUTOUT11 0x3F000000
+#define BF_PXP_WFE_A_STG2_5X6_OUT2_2_LUTOUT11(v) \
+ (((v) << 24) & BM_PXP_WFE_A_STG2_5X6_OUT2_2_LUTOUT11)
+#define BP_PXP_WFE_A_STG2_5X6_OUT2_2_RSVD1 22
+#define BM_PXP_WFE_A_STG2_5X6_OUT2_2_RSVD1 0x00C00000
+#define BF_PXP_WFE_A_STG2_5X6_OUT2_2_RSVD1(v) \
+ (((v) << 22) & BM_PXP_WFE_A_STG2_5X6_OUT2_2_RSVD1)
+#define BP_PXP_WFE_A_STG2_5X6_OUT2_2_LUTOUT10 16
+#define BM_PXP_WFE_A_STG2_5X6_OUT2_2_LUTOUT10 0x003F0000
+#define BF_PXP_WFE_A_STG2_5X6_OUT2_2_LUTOUT10(v) \
+ (((v) << 16) & BM_PXP_WFE_A_STG2_5X6_OUT2_2_LUTOUT10)
+#define BP_PXP_WFE_A_STG2_5X6_OUT2_2_RSVD2 14
+#define BM_PXP_WFE_A_STG2_5X6_OUT2_2_RSVD2 0x0000C000
+#define BF_PXP_WFE_A_STG2_5X6_OUT2_2_RSVD2(v) \
+ (((v) << 14) & BM_PXP_WFE_A_STG2_5X6_OUT2_2_RSVD2)
+#define BP_PXP_WFE_A_STG2_5X6_OUT2_2_LUTOUT9 8
+#define BM_PXP_WFE_A_STG2_5X6_OUT2_2_LUTOUT9 0x00003F00
+#define BF_PXP_WFE_A_STG2_5X6_OUT2_2_LUTOUT9(v) \
+ (((v) << 8) & BM_PXP_WFE_A_STG2_5X6_OUT2_2_LUTOUT9)
+#define BP_PXP_WFE_A_STG2_5X6_OUT2_2_RSVD3 6
+#define BM_PXP_WFE_A_STG2_5X6_OUT2_2_RSVD3 0x000000C0
+#define BF_PXP_WFE_A_STG2_5X6_OUT2_2_RSVD3(v) \
+ (((v) << 6) & BM_PXP_WFE_A_STG2_5X6_OUT2_2_RSVD3)
+#define BP_PXP_WFE_A_STG2_5X6_OUT2_2_LUTOUT8 0
+#define BM_PXP_WFE_A_STG2_5X6_OUT2_2_LUTOUT8 0x0000003F
+#define BF_PXP_WFE_A_STG2_5X6_OUT2_2_LUTOUT8(v) \
+ (((v) << 0) & BM_PXP_WFE_A_STG2_5X6_OUT2_2_LUTOUT8)
+
+#define HW_PXP_WFE_A_STG2_5X6_OUT2_3 (0x00001ba0)
+
+#define BP_PXP_WFE_A_STG2_5X6_OUT2_3_RSVD0 30
+#define BM_PXP_WFE_A_STG2_5X6_OUT2_3_RSVD0 0xC0000000
+#define BF_PXP_WFE_A_STG2_5X6_OUT2_3_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFE_A_STG2_5X6_OUT2_3_RSVD0)
+#define BP_PXP_WFE_A_STG2_5X6_OUT2_3_LUTOUT15 24
+#define BM_PXP_WFE_A_STG2_5X6_OUT2_3_LUTOUT15 0x3F000000
+#define BF_PXP_WFE_A_STG2_5X6_OUT2_3_LUTOUT15(v) \
+ (((v) << 24) & BM_PXP_WFE_A_STG2_5X6_OUT2_3_LUTOUT15)
+#define BP_PXP_WFE_A_STG2_5X6_OUT2_3_RSVD1 22
+#define BM_PXP_WFE_A_STG2_5X6_OUT2_3_RSVD1 0x00C00000
+#define BF_PXP_WFE_A_STG2_5X6_OUT2_3_RSVD1(v) \
+ (((v) << 22) & BM_PXP_WFE_A_STG2_5X6_OUT2_3_RSVD1)
+#define BP_PXP_WFE_A_STG2_5X6_OUT2_3_LUTOUT14 16
+#define BM_PXP_WFE_A_STG2_5X6_OUT2_3_LUTOUT14 0x003F0000
+#define BF_PXP_WFE_A_STG2_5X6_OUT2_3_LUTOUT14(v) \
+ (((v) << 16) & BM_PXP_WFE_A_STG2_5X6_OUT2_3_LUTOUT14)
+#define BP_PXP_WFE_A_STG2_5X6_OUT2_3_RSVD2 14
+#define BM_PXP_WFE_A_STG2_5X6_OUT2_3_RSVD2 0x0000C000
+#define BF_PXP_WFE_A_STG2_5X6_OUT2_3_RSVD2(v) \
+ (((v) << 14) & BM_PXP_WFE_A_STG2_5X6_OUT2_3_RSVD2)
+#define BP_PXP_WFE_A_STG2_5X6_OUT2_3_LUTOUT13 8
+#define BM_PXP_WFE_A_STG2_5X6_OUT2_3_LUTOUT13 0x00003F00
+#define BF_PXP_WFE_A_STG2_5X6_OUT2_3_LUTOUT13(v) \
+ (((v) << 8) & BM_PXP_WFE_A_STG2_5X6_OUT2_3_LUTOUT13)
+#define BP_PXP_WFE_A_STG2_5X6_OUT2_3_RSVD3 6
+#define BM_PXP_WFE_A_STG2_5X6_OUT2_3_RSVD3 0x000000C0
+#define BF_PXP_WFE_A_STG2_5X6_OUT2_3_RSVD3(v) \
+ (((v) << 6) & BM_PXP_WFE_A_STG2_5X6_OUT2_3_RSVD3)
+#define BP_PXP_WFE_A_STG2_5X6_OUT2_3_LUTOUT12 0
+#define BM_PXP_WFE_A_STG2_5X6_OUT2_3_LUTOUT12 0x0000003F
+#define BF_PXP_WFE_A_STG2_5X6_OUT2_3_LUTOUT12(v) \
+ (((v) << 0) & BM_PXP_WFE_A_STG2_5X6_OUT2_3_LUTOUT12)
+
+#define HW_PXP_WFE_A_STG2_5X6_OUT2_4 (0x00001bb0)
+
+#define BP_PXP_WFE_A_STG2_5X6_OUT2_4_RSVD0 30
+#define BM_PXP_WFE_A_STG2_5X6_OUT2_4_RSVD0 0xC0000000
+#define BF_PXP_WFE_A_STG2_5X6_OUT2_4_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFE_A_STG2_5X6_OUT2_4_RSVD0)
+#define BP_PXP_WFE_A_STG2_5X6_OUT2_4_LUTOUT19 24
+#define BM_PXP_WFE_A_STG2_5X6_OUT2_4_LUTOUT19 0x3F000000
+#define BF_PXP_WFE_A_STG2_5X6_OUT2_4_LUTOUT19(v) \
+ (((v) << 24) & BM_PXP_WFE_A_STG2_5X6_OUT2_4_LUTOUT19)
+#define BP_PXP_WFE_A_STG2_5X6_OUT2_4_RSVD1 22
+#define BM_PXP_WFE_A_STG2_5X6_OUT2_4_RSVD1 0x00C00000
+#define BF_PXP_WFE_A_STG2_5X6_OUT2_4_RSVD1(v) \
+ (((v) << 22) & BM_PXP_WFE_A_STG2_5X6_OUT2_4_RSVD1)
+#define BP_PXP_WFE_A_STG2_5X6_OUT2_4_LUTOUT18 16
+#define BM_PXP_WFE_A_STG2_5X6_OUT2_4_LUTOUT18 0x003F0000
+#define BF_PXP_WFE_A_STG2_5X6_OUT2_4_LUTOUT18(v) \
+ (((v) << 16) & BM_PXP_WFE_A_STG2_5X6_OUT2_4_LUTOUT18)
+#define BP_PXP_WFE_A_STG2_5X6_OUT2_4_RSVD2 14
+#define BM_PXP_WFE_A_STG2_5X6_OUT2_4_RSVD2 0x0000C000
+#define BF_PXP_WFE_A_STG2_5X6_OUT2_4_RSVD2(v) \
+ (((v) << 14) & BM_PXP_WFE_A_STG2_5X6_OUT2_4_RSVD2)
+#define BP_PXP_WFE_A_STG2_5X6_OUT2_4_LUTOUT17 8
+#define BM_PXP_WFE_A_STG2_5X6_OUT2_4_LUTOUT17 0x00003F00
+#define BF_PXP_WFE_A_STG2_5X6_OUT2_4_LUTOUT17(v) \
+ (((v) << 8) & BM_PXP_WFE_A_STG2_5X6_OUT2_4_LUTOUT17)
+#define BP_PXP_WFE_A_STG2_5X6_OUT2_4_RSVD3 6
+#define BM_PXP_WFE_A_STG2_5X6_OUT2_4_RSVD3 0x000000C0
+#define BF_PXP_WFE_A_STG2_5X6_OUT2_4_RSVD3(v) \
+ (((v) << 6) & BM_PXP_WFE_A_STG2_5X6_OUT2_4_RSVD3)
+#define BP_PXP_WFE_A_STG2_5X6_OUT2_4_LUTOUT16 0
+#define BM_PXP_WFE_A_STG2_5X6_OUT2_4_LUTOUT16 0x0000003F
+#define BF_PXP_WFE_A_STG2_5X6_OUT2_4_LUTOUT16(v) \
+ (((v) << 0) & BM_PXP_WFE_A_STG2_5X6_OUT2_4_LUTOUT16)
+
+#define HW_PXP_WFE_A_STG2_5X6_OUT2_5 (0x00001bc0)
+
+#define BP_PXP_WFE_A_STG2_5X6_OUT2_5_RSVD0 30
+#define BM_PXP_WFE_A_STG2_5X6_OUT2_5_RSVD0 0xC0000000
+#define BF_PXP_WFE_A_STG2_5X6_OUT2_5_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFE_A_STG2_5X6_OUT2_5_RSVD0)
+#define BP_PXP_WFE_A_STG2_5X6_OUT2_5_LUTOUT23 24
+#define BM_PXP_WFE_A_STG2_5X6_OUT2_5_LUTOUT23 0x3F000000
+#define BF_PXP_WFE_A_STG2_5X6_OUT2_5_LUTOUT23(v) \
+ (((v) << 24) & BM_PXP_WFE_A_STG2_5X6_OUT2_5_LUTOUT23)
+#define BP_PXP_WFE_A_STG2_5X6_OUT2_5_RSVD1 22
+#define BM_PXP_WFE_A_STG2_5X6_OUT2_5_RSVD1 0x00C00000
+#define BF_PXP_WFE_A_STG2_5X6_OUT2_5_RSVD1(v) \
+ (((v) << 22) & BM_PXP_WFE_A_STG2_5X6_OUT2_5_RSVD1)
+#define BP_PXP_WFE_A_STG2_5X6_OUT2_5_LUTOUT22 16
+#define BM_PXP_WFE_A_STG2_5X6_OUT2_5_LUTOUT22 0x003F0000
+#define BF_PXP_WFE_A_STG2_5X6_OUT2_5_LUTOUT22(v) \
+ (((v) << 16) & BM_PXP_WFE_A_STG2_5X6_OUT2_5_LUTOUT22)
+#define BP_PXP_WFE_A_STG2_5X6_OUT2_5_RSVD2 14
+#define BM_PXP_WFE_A_STG2_5X6_OUT2_5_RSVD2 0x0000C000
+#define BF_PXP_WFE_A_STG2_5X6_OUT2_5_RSVD2(v) \
+ (((v) << 14) & BM_PXP_WFE_A_STG2_5X6_OUT2_5_RSVD2)
+#define BP_PXP_WFE_A_STG2_5X6_OUT2_5_LUTOUT21 8
+#define BM_PXP_WFE_A_STG2_5X6_OUT2_5_LUTOUT21 0x00003F00
+#define BF_PXP_WFE_A_STG2_5X6_OUT2_5_LUTOUT21(v) \
+ (((v) << 8) & BM_PXP_WFE_A_STG2_5X6_OUT2_5_LUTOUT21)
+#define BP_PXP_WFE_A_STG2_5X6_OUT2_5_RSVD3 6
+#define BM_PXP_WFE_A_STG2_5X6_OUT2_5_RSVD3 0x000000C0
+#define BF_PXP_WFE_A_STG2_5X6_OUT2_5_RSVD3(v) \
+ (((v) << 6) & BM_PXP_WFE_A_STG2_5X6_OUT2_5_RSVD3)
+#define BP_PXP_WFE_A_STG2_5X6_OUT2_5_LUTOUT20 0
+#define BM_PXP_WFE_A_STG2_5X6_OUT2_5_LUTOUT20 0x0000003F
+#define BF_PXP_WFE_A_STG2_5X6_OUT2_5_LUTOUT20(v) \
+ (((v) << 0) & BM_PXP_WFE_A_STG2_5X6_OUT2_5_LUTOUT20)
+
+#define HW_PXP_WFE_A_STG2_5X6_OUT2_6 (0x00001bd0)
+
+#define BP_PXP_WFE_A_STG2_5X6_OUT2_6_RSVD0 30
+#define BM_PXP_WFE_A_STG2_5X6_OUT2_6_RSVD0 0xC0000000
+#define BF_PXP_WFE_A_STG2_5X6_OUT2_6_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFE_A_STG2_5X6_OUT2_6_RSVD0)
+#define BP_PXP_WFE_A_STG2_5X6_OUT2_6_LUTOUT27 24
+#define BM_PXP_WFE_A_STG2_5X6_OUT2_6_LUTOUT27 0x3F000000
+#define BF_PXP_WFE_A_STG2_5X6_OUT2_6_LUTOUT27(v) \
+ (((v) << 24) & BM_PXP_WFE_A_STG2_5X6_OUT2_6_LUTOUT27)
+#define BP_PXP_WFE_A_STG2_5X6_OUT2_6_RSVD1 22
+#define BM_PXP_WFE_A_STG2_5X6_OUT2_6_RSVD1 0x00C00000
+#define BF_PXP_WFE_A_STG2_5X6_OUT2_6_RSVD1(v) \
+ (((v) << 22) & BM_PXP_WFE_A_STG2_5X6_OUT2_6_RSVD1)
+#define BP_PXP_WFE_A_STG2_5X6_OUT2_6_LUTOUT26 16
+#define BM_PXP_WFE_A_STG2_5X6_OUT2_6_LUTOUT26 0x003F0000
+#define BF_PXP_WFE_A_STG2_5X6_OUT2_6_LUTOUT26(v) \
+ (((v) << 16) & BM_PXP_WFE_A_STG2_5X6_OUT2_6_LUTOUT26)
+#define BP_PXP_WFE_A_STG2_5X6_OUT2_6_RSVD2 14
+#define BM_PXP_WFE_A_STG2_5X6_OUT2_6_RSVD2 0x0000C000
+#define BF_PXP_WFE_A_STG2_5X6_OUT2_6_RSVD2(v) \
+ (((v) << 14) & BM_PXP_WFE_A_STG2_5X6_OUT2_6_RSVD2)
+#define BP_PXP_WFE_A_STG2_5X6_OUT2_6_LUTOUT25 8
+#define BM_PXP_WFE_A_STG2_5X6_OUT2_6_LUTOUT25 0x00003F00
+#define BF_PXP_WFE_A_STG2_5X6_OUT2_6_LUTOUT25(v) \
+ (((v) << 8) & BM_PXP_WFE_A_STG2_5X6_OUT2_6_LUTOUT25)
+#define BP_PXP_WFE_A_STG2_5X6_OUT2_6_RSVD3 6
+#define BM_PXP_WFE_A_STG2_5X6_OUT2_6_RSVD3 0x000000C0
+#define BF_PXP_WFE_A_STG2_5X6_OUT2_6_RSVD3(v) \
+ (((v) << 6) & BM_PXP_WFE_A_STG2_5X6_OUT2_6_RSVD3)
+#define BP_PXP_WFE_A_STG2_5X6_OUT2_6_LUTOUT24 0
+#define BM_PXP_WFE_A_STG2_5X6_OUT2_6_LUTOUT24 0x0000003F
+#define BF_PXP_WFE_A_STG2_5X6_OUT2_6_LUTOUT24(v) \
+ (((v) << 0) & BM_PXP_WFE_A_STG2_5X6_OUT2_6_LUTOUT24)
+
+#define HW_PXP_WFE_A_STG2_5X6_OUT2_7 (0x00001be0)
+
+#define BP_PXP_WFE_A_STG2_5X6_OUT2_7_RSVD0 30
+#define BM_PXP_WFE_A_STG2_5X6_OUT2_7_RSVD0 0xC0000000
+#define BF_PXP_WFE_A_STG2_5X6_OUT2_7_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFE_A_STG2_5X6_OUT2_7_RSVD0)
+#define BP_PXP_WFE_A_STG2_5X6_OUT2_7_LUTOUT31 24
+#define BM_PXP_WFE_A_STG2_5X6_OUT2_7_LUTOUT31 0x3F000000
+#define BF_PXP_WFE_A_STG2_5X6_OUT2_7_LUTOUT31(v) \
+ (((v) << 24) & BM_PXP_WFE_A_STG2_5X6_OUT2_7_LUTOUT31)
+#define BP_PXP_WFE_A_STG2_5X6_OUT2_7_RSVD1 22
+#define BM_PXP_WFE_A_STG2_5X6_OUT2_7_RSVD1 0x00C00000
+#define BF_PXP_WFE_A_STG2_5X6_OUT2_7_RSVD1(v) \
+ (((v) << 22) & BM_PXP_WFE_A_STG2_5X6_OUT2_7_RSVD1)
+#define BP_PXP_WFE_A_STG2_5X6_OUT2_7_LUTOUT30 16
+#define BM_PXP_WFE_A_STG2_5X6_OUT2_7_LUTOUT30 0x003F0000
+#define BF_PXP_WFE_A_STG2_5X6_OUT2_7_LUTOUT30(v) \
+ (((v) << 16) & BM_PXP_WFE_A_STG2_5X6_OUT2_7_LUTOUT30)
+#define BP_PXP_WFE_A_STG2_5X6_OUT2_7_RSVD2 14
+#define BM_PXP_WFE_A_STG2_5X6_OUT2_7_RSVD2 0x0000C000
+#define BF_PXP_WFE_A_STG2_5X6_OUT2_7_RSVD2(v) \
+ (((v) << 14) & BM_PXP_WFE_A_STG2_5X6_OUT2_7_RSVD2)
+#define BP_PXP_WFE_A_STG2_5X6_OUT2_7_LUTOUT29 8
+#define BM_PXP_WFE_A_STG2_5X6_OUT2_7_LUTOUT29 0x00003F00
+#define BF_PXP_WFE_A_STG2_5X6_OUT2_7_LUTOUT29(v) \
+ (((v) << 8) & BM_PXP_WFE_A_STG2_5X6_OUT2_7_LUTOUT29)
+#define BP_PXP_WFE_A_STG2_5X6_OUT2_7_RSVD3 6
+#define BM_PXP_WFE_A_STG2_5X6_OUT2_7_RSVD3 0x000000C0
+#define BF_PXP_WFE_A_STG2_5X6_OUT2_7_RSVD3(v) \
+ (((v) << 6) & BM_PXP_WFE_A_STG2_5X6_OUT2_7_RSVD3)
+#define BP_PXP_WFE_A_STG2_5X6_OUT2_7_LUTOUT28 0
+#define BM_PXP_WFE_A_STG2_5X6_OUT2_7_LUTOUT28 0x0000003F
+#define BF_PXP_WFE_A_STG2_5X6_OUT2_7_LUTOUT28(v) \
+ (((v) << 0) & BM_PXP_WFE_A_STG2_5X6_OUT2_7_LUTOUT28)
+
+#define HW_PXP_WFE_A_STG2_5X6_OUT3_0 (0x00001bf0)
+
+#define BP_PXP_WFE_A_STG2_5X6_OUT3_0_RSVD0 30
+#define BM_PXP_WFE_A_STG2_5X6_OUT3_0_RSVD0 0xC0000000
+#define BF_PXP_WFE_A_STG2_5X6_OUT3_0_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFE_A_STG2_5X6_OUT3_0_RSVD0)
+#define BP_PXP_WFE_A_STG2_5X6_OUT3_0_LUTOUT3 24
+#define BM_PXP_WFE_A_STG2_5X6_OUT3_0_LUTOUT3 0x3F000000
+#define BF_PXP_WFE_A_STG2_5X6_OUT3_0_LUTOUT3(v) \
+ (((v) << 24) & BM_PXP_WFE_A_STG2_5X6_OUT3_0_LUTOUT3)
+#define BP_PXP_WFE_A_STG2_5X6_OUT3_0_RSVD1 22
+#define BM_PXP_WFE_A_STG2_5X6_OUT3_0_RSVD1 0x00C00000
+#define BF_PXP_WFE_A_STG2_5X6_OUT3_0_RSVD1(v) \
+ (((v) << 22) & BM_PXP_WFE_A_STG2_5X6_OUT3_0_RSVD1)
+#define BP_PXP_WFE_A_STG2_5X6_OUT3_0_LUTOUT2 16
+#define BM_PXP_WFE_A_STG2_5X6_OUT3_0_LUTOUT2 0x003F0000
+#define BF_PXP_WFE_A_STG2_5X6_OUT3_0_LUTOUT2(v) \
+ (((v) << 16) & BM_PXP_WFE_A_STG2_5X6_OUT3_0_LUTOUT2)
+#define BP_PXP_WFE_A_STG2_5X6_OUT3_0_RSVD2 14
+#define BM_PXP_WFE_A_STG2_5X6_OUT3_0_RSVD2 0x0000C000
+#define BF_PXP_WFE_A_STG2_5X6_OUT3_0_RSVD2(v) \
+ (((v) << 14) & BM_PXP_WFE_A_STG2_5X6_OUT3_0_RSVD2)
+#define BP_PXP_WFE_A_STG2_5X6_OUT3_0_LUTOUT1 8
+#define BM_PXP_WFE_A_STG2_5X6_OUT3_0_LUTOUT1 0x00003F00
+#define BF_PXP_WFE_A_STG2_5X6_OUT3_0_LUTOUT1(v) \
+ (((v) << 8) & BM_PXP_WFE_A_STG2_5X6_OUT3_0_LUTOUT1)
+#define BP_PXP_WFE_A_STG2_5X6_OUT3_0_RSVD3 6
+#define BM_PXP_WFE_A_STG2_5X6_OUT3_0_RSVD3 0x000000C0
+#define BF_PXP_WFE_A_STG2_5X6_OUT3_0_RSVD3(v) \
+ (((v) << 6) & BM_PXP_WFE_A_STG2_5X6_OUT3_0_RSVD3)
+#define BP_PXP_WFE_A_STG2_5X6_OUT3_0_LUTOUT0 0
+#define BM_PXP_WFE_A_STG2_5X6_OUT3_0_LUTOUT0 0x0000003F
+#define BF_PXP_WFE_A_STG2_5X6_OUT3_0_LUTOUT0(v) \
+ (((v) << 0) & BM_PXP_WFE_A_STG2_5X6_OUT3_0_LUTOUT0)
+
+#define HW_PXP_WFE_A_STG2_5X6_OUT3_1 (0x00001c00)
+
+#define BP_PXP_WFE_A_STG2_5X6_OUT3_1_RSVD0 30
+#define BM_PXP_WFE_A_STG2_5X6_OUT3_1_RSVD0 0xC0000000
+#define BF_PXP_WFE_A_STG2_5X6_OUT3_1_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFE_A_STG2_5X6_OUT3_1_RSVD0)
+#define BP_PXP_WFE_A_STG2_5X6_OUT3_1_LUTOUT7 24
+#define BM_PXP_WFE_A_STG2_5X6_OUT3_1_LUTOUT7 0x3F000000
+#define BF_PXP_WFE_A_STG2_5X6_OUT3_1_LUTOUT7(v) \
+ (((v) << 24) & BM_PXP_WFE_A_STG2_5X6_OUT3_1_LUTOUT7)
+#define BP_PXP_WFE_A_STG2_5X6_OUT3_1_RSVD1 22
+#define BM_PXP_WFE_A_STG2_5X6_OUT3_1_RSVD1 0x00C00000
+#define BF_PXP_WFE_A_STG2_5X6_OUT3_1_RSVD1(v) \
+ (((v) << 22) & BM_PXP_WFE_A_STG2_5X6_OUT3_1_RSVD1)
+#define BP_PXP_WFE_A_STG2_5X6_OUT3_1_LUTOUT6 16
+#define BM_PXP_WFE_A_STG2_5X6_OUT3_1_LUTOUT6 0x003F0000
+#define BF_PXP_WFE_A_STG2_5X6_OUT3_1_LUTOUT6(v) \
+ (((v) << 16) & BM_PXP_WFE_A_STG2_5X6_OUT3_1_LUTOUT6)
+#define BP_PXP_WFE_A_STG2_5X6_OUT3_1_RSVD2 14
+#define BM_PXP_WFE_A_STG2_5X6_OUT3_1_RSVD2 0x0000C000
+#define BF_PXP_WFE_A_STG2_5X6_OUT3_1_RSVD2(v) \
+ (((v) << 14) & BM_PXP_WFE_A_STG2_5X6_OUT3_1_RSVD2)
+#define BP_PXP_WFE_A_STG2_5X6_OUT3_1_LUTOUT5 8
+#define BM_PXP_WFE_A_STG2_5X6_OUT3_1_LUTOUT5 0x00003F00
+#define BF_PXP_WFE_A_STG2_5X6_OUT3_1_LUTOUT5(v) \
+ (((v) << 8) & BM_PXP_WFE_A_STG2_5X6_OUT3_1_LUTOUT5)
+#define BP_PXP_WFE_A_STG2_5X6_OUT3_1_RSVD3 6
+#define BM_PXP_WFE_A_STG2_5X6_OUT3_1_RSVD3 0x000000C0
+#define BF_PXP_WFE_A_STG2_5X6_OUT3_1_RSVD3(v) \
+ (((v) << 6) & BM_PXP_WFE_A_STG2_5X6_OUT3_1_RSVD3)
+#define BP_PXP_WFE_A_STG2_5X6_OUT3_1_LUTOUT4 0
+#define BM_PXP_WFE_A_STG2_5X6_OUT3_1_LUTOUT4 0x0000003F
+#define BF_PXP_WFE_A_STG2_5X6_OUT3_1_LUTOUT4(v) \
+ (((v) << 0) & BM_PXP_WFE_A_STG2_5X6_OUT3_1_LUTOUT4)
+
+#define HW_PXP_WFE_A_STG2_5X6_OUT3_2 (0x00001c10)
+
+#define BP_PXP_WFE_A_STG2_5X6_OUT3_2_RSVD0 30
+#define BM_PXP_WFE_A_STG2_5X6_OUT3_2_RSVD0 0xC0000000
+#define BF_PXP_WFE_A_STG2_5X6_OUT3_2_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFE_A_STG2_5X6_OUT3_2_RSVD0)
+#define BP_PXP_WFE_A_STG2_5X6_OUT3_2_LUTOUT11 24
+#define BM_PXP_WFE_A_STG2_5X6_OUT3_2_LUTOUT11 0x3F000000
+#define BF_PXP_WFE_A_STG2_5X6_OUT3_2_LUTOUT11(v) \
+ (((v) << 24) & BM_PXP_WFE_A_STG2_5X6_OUT3_2_LUTOUT11)
+#define BP_PXP_WFE_A_STG2_5X6_OUT3_2_RSVD1 22
+#define BM_PXP_WFE_A_STG2_5X6_OUT3_2_RSVD1 0x00C00000
+#define BF_PXP_WFE_A_STG2_5X6_OUT3_2_RSVD1(v) \
+ (((v) << 22) & BM_PXP_WFE_A_STG2_5X6_OUT3_2_RSVD1)
+#define BP_PXP_WFE_A_STG2_5X6_OUT3_2_LUTOUT10 16
+#define BM_PXP_WFE_A_STG2_5X6_OUT3_2_LUTOUT10 0x003F0000
+#define BF_PXP_WFE_A_STG2_5X6_OUT3_2_LUTOUT10(v) \
+ (((v) << 16) & BM_PXP_WFE_A_STG2_5X6_OUT3_2_LUTOUT10)
+#define BP_PXP_WFE_A_STG2_5X6_OUT3_2_RSVD2 14
+#define BM_PXP_WFE_A_STG2_5X6_OUT3_2_RSVD2 0x0000C000
+#define BF_PXP_WFE_A_STG2_5X6_OUT3_2_RSVD2(v) \
+ (((v) << 14) & BM_PXP_WFE_A_STG2_5X6_OUT3_2_RSVD2)
+#define BP_PXP_WFE_A_STG2_5X6_OUT3_2_LUTOUT9 8
+#define BM_PXP_WFE_A_STG2_5X6_OUT3_2_LUTOUT9 0x00003F00
+#define BF_PXP_WFE_A_STG2_5X6_OUT3_2_LUTOUT9(v) \
+ (((v) << 8) & BM_PXP_WFE_A_STG2_5X6_OUT3_2_LUTOUT9)
+#define BP_PXP_WFE_A_STG2_5X6_OUT3_2_RSVD3 6
+#define BM_PXP_WFE_A_STG2_5X6_OUT3_2_RSVD3 0x000000C0
+#define BF_PXP_WFE_A_STG2_5X6_OUT3_2_RSVD3(v) \
+ (((v) << 6) & BM_PXP_WFE_A_STG2_5X6_OUT3_2_RSVD3)
+#define BP_PXP_WFE_A_STG2_5X6_OUT3_2_LUTOUT8 0
+#define BM_PXP_WFE_A_STG2_5X6_OUT3_2_LUTOUT8 0x0000003F
+#define BF_PXP_WFE_A_STG2_5X6_OUT3_2_LUTOUT8(v) \
+ (((v) << 0) & BM_PXP_WFE_A_STG2_5X6_OUT3_2_LUTOUT8)
+
+#define HW_PXP_WFE_A_STG2_5X6_OUT3_3 (0x00001c20)
+
+#define BP_PXP_WFE_A_STG2_5X6_OUT3_3_RSVD0 30
+#define BM_PXP_WFE_A_STG2_5X6_OUT3_3_RSVD0 0xC0000000
+#define BF_PXP_WFE_A_STG2_5X6_OUT3_3_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFE_A_STG2_5X6_OUT3_3_RSVD0)
+#define BP_PXP_WFE_A_STG2_5X6_OUT3_3_LUTOUT15 24
+#define BM_PXP_WFE_A_STG2_5X6_OUT3_3_LUTOUT15 0x3F000000
+#define BF_PXP_WFE_A_STG2_5X6_OUT3_3_LUTOUT15(v) \
+ (((v) << 24) & BM_PXP_WFE_A_STG2_5X6_OUT3_3_LUTOUT15)
+#define BP_PXP_WFE_A_STG2_5X6_OUT3_3_RSVD1 22
+#define BM_PXP_WFE_A_STG2_5X6_OUT3_3_RSVD1 0x00C00000
+#define BF_PXP_WFE_A_STG2_5X6_OUT3_3_RSVD1(v) \
+ (((v) << 22) & BM_PXP_WFE_A_STG2_5X6_OUT3_3_RSVD1)
+#define BP_PXP_WFE_A_STG2_5X6_OUT3_3_LUTOUT14 16
+#define BM_PXP_WFE_A_STG2_5X6_OUT3_3_LUTOUT14 0x003F0000
+#define BF_PXP_WFE_A_STG2_5X6_OUT3_3_LUTOUT14(v) \
+ (((v) << 16) & BM_PXP_WFE_A_STG2_5X6_OUT3_3_LUTOUT14)
+#define BP_PXP_WFE_A_STG2_5X6_OUT3_3_RSVD2 14
+#define BM_PXP_WFE_A_STG2_5X6_OUT3_3_RSVD2 0x0000C000
+#define BF_PXP_WFE_A_STG2_5X6_OUT3_3_RSVD2(v) \
+ (((v) << 14) & BM_PXP_WFE_A_STG2_5X6_OUT3_3_RSVD2)
+#define BP_PXP_WFE_A_STG2_5X6_OUT3_3_LUTOUT13 8
+#define BM_PXP_WFE_A_STG2_5X6_OUT3_3_LUTOUT13 0x00003F00
+#define BF_PXP_WFE_A_STG2_5X6_OUT3_3_LUTOUT13(v) \
+ (((v) << 8) & BM_PXP_WFE_A_STG2_5X6_OUT3_3_LUTOUT13)
+#define BP_PXP_WFE_A_STG2_5X6_OUT3_3_RSVD3 6
+#define BM_PXP_WFE_A_STG2_5X6_OUT3_3_RSVD3 0x000000C0
+#define BF_PXP_WFE_A_STG2_5X6_OUT3_3_RSVD3(v) \
+ (((v) << 6) & BM_PXP_WFE_A_STG2_5X6_OUT3_3_RSVD3)
+#define BP_PXP_WFE_A_STG2_5X6_OUT3_3_LUTOUT12 0
+#define BM_PXP_WFE_A_STG2_5X6_OUT3_3_LUTOUT12 0x0000003F
+#define BF_PXP_WFE_A_STG2_5X6_OUT3_3_LUTOUT12(v) \
+ (((v) << 0) & BM_PXP_WFE_A_STG2_5X6_OUT3_3_LUTOUT12)
+
+#define HW_PXP_WFE_A_STG2_5X6_OUT3_4 (0x00001c30)
+
+#define BP_PXP_WFE_A_STG2_5X6_OUT3_4_RSVD0 30
+#define BM_PXP_WFE_A_STG2_5X6_OUT3_4_RSVD0 0xC0000000
+#define BF_PXP_WFE_A_STG2_5X6_OUT3_4_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFE_A_STG2_5X6_OUT3_4_RSVD0)
+#define BP_PXP_WFE_A_STG2_5X6_OUT3_4_LUTOUT19 24
+#define BM_PXP_WFE_A_STG2_5X6_OUT3_4_LUTOUT19 0x3F000000
+#define BF_PXP_WFE_A_STG2_5X6_OUT3_4_LUTOUT19(v) \
+ (((v) << 24) & BM_PXP_WFE_A_STG2_5X6_OUT3_4_LUTOUT19)
+#define BP_PXP_WFE_A_STG2_5X6_OUT3_4_RSVD1 22
+#define BM_PXP_WFE_A_STG2_5X6_OUT3_4_RSVD1 0x00C00000
+#define BF_PXP_WFE_A_STG2_5X6_OUT3_4_RSVD1(v) \
+ (((v) << 22) & BM_PXP_WFE_A_STG2_5X6_OUT3_4_RSVD1)
+#define BP_PXP_WFE_A_STG2_5X6_OUT3_4_LUTOUT18 16
+#define BM_PXP_WFE_A_STG2_5X6_OUT3_4_LUTOUT18 0x003F0000
+#define BF_PXP_WFE_A_STG2_5X6_OUT3_4_LUTOUT18(v) \
+ (((v) << 16) & BM_PXP_WFE_A_STG2_5X6_OUT3_4_LUTOUT18)
+#define BP_PXP_WFE_A_STG2_5X6_OUT3_4_RSVD2 14
+#define BM_PXP_WFE_A_STG2_5X6_OUT3_4_RSVD2 0x0000C000
+#define BF_PXP_WFE_A_STG2_5X6_OUT3_4_RSVD2(v) \
+ (((v) << 14) & BM_PXP_WFE_A_STG2_5X6_OUT3_4_RSVD2)
+#define BP_PXP_WFE_A_STG2_5X6_OUT3_4_LUTOUT17 8
+#define BM_PXP_WFE_A_STG2_5X6_OUT3_4_LUTOUT17 0x00003F00
+#define BF_PXP_WFE_A_STG2_5X6_OUT3_4_LUTOUT17(v) \
+ (((v) << 8) & BM_PXP_WFE_A_STG2_5X6_OUT3_4_LUTOUT17)
+#define BP_PXP_WFE_A_STG2_5X6_OUT3_4_RSVD3 6
+#define BM_PXP_WFE_A_STG2_5X6_OUT3_4_RSVD3 0x000000C0
+#define BF_PXP_WFE_A_STG2_5X6_OUT3_4_RSVD3(v) \
+ (((v) << 6) & BM_PXP_WFE_A_STG2_5X6_OUT3_4_RSVD3)
+#define BP_PXP_WFE_A_STG2_5X6_OUT3_4_LUTOUT16 0
+#define BM_PXP_WFE_A_STG2_5X6_OUT3_4_LUTOUT16 0x0000003F
+#define BF_PXP_WFE_A_STG2_5X6_OUT3_4_LUTOUT16(v) \
+ (((v) << 0) & BM_PXP_WFE_A_STG2_5X6_OUT3_4_LUTOUT16)
+
+#define HW_PXP_WFE_A_STG2_5X6_OUT3_5 (0x00001c40)
+
+#define BP_PXP_WFE_A_STG2_5X6_OUT3_5_RSVD0 30
+#define BM_PXP_WFE_A_STG2_5X6_OUT3_5_RSVD0 0xC0000000
+#define BF_PXP_WFE_A_STG2_5X6_OUT3_5_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFE_A_STG2_5X6_OUT3_5_RSVD0)
+#define BP_PXP_WFE_A_STG2_5X6_OUT3_5_LUTOUT23 24
+#define BM_PXP_WFE_A_STG2_5X6_OUT3_5_LUTOUT23 0x3F000000
+#define BF_PXP_WFE_A_STG2_5X6_OUT3_5_LUTOUT23(v) \
+ (((v) << 24) & BM_PXP_WFE_A_STG2_5X6_OUT3_5_LUTOUT23)
+#define BP_PXP_WFE_A_STG2_5X6_OUT3_5_RSVD1 22
+#define BM_PXP_WFE_A_STG2_5X6_OUT3_5_RSVD1 0x00C00000
+#define BF_PXP_WFE_A_STG2_5X6_OUT3_5_RSVD1(v) \
+ (((v) << 22) & BM_PXP_WFE_A_STG2_5X6_OUT3_5_RSVD1)
+#define BP_PXP_WFE_A_STG2_5X6_OUT3_5_LUTOUT22 16
+#define BM_PXP_WFE_A_STG2_5X6_OUT3_5_LUTOUT22 0x003F0000
+#define BF_PXP_WFE_A_STG2_5X6_OUT3_5_LUTOUT22(v) \
+ (((v) << 16) & BM_PXP_WFE_A_STG2_5X6_OUT3_5_LUTOUT22)
+#define BP_PXP_WFE_A_STG2_5X6_OUT3_5_RSVD2 14
+#define BM_PXP_WFE_A_STG2_5X6_OUT3_5_RSVD2 0x0000C000
+#define BF_PXP_WFE_A_STG2_5X6_OUT3_5_RSVD2(v) \
+ (((v) << 14) & BM_PXP_WFE_A_STG2_5X6_OUT3_5_RSVD2)
+#define BP_PXP_WFE_A_STG2_5X6_OUT3_5_LUTOUT21 8
+#define BM_PXP_WFE_A_STG2_5X6_OUT3_5_LUTOUT21 0x00003F00
+#define BF_PXP_WFE_A_STG2_5X6_OUT3_5_LUTOUT21(v) \
+ (((v) << 8) & BM_PXP_WFE_A_STG2_5X6_OUT3_5_LUTOUT21)
+#define BP_PXP_WFE_A_STG2_5X6_OUT3_5_RSVD3 6
+#define BM_PXP_WFE_A_STG2_5X6_OUT3_5_RSVD3 0x000000C0
+#define BF_PXP_WFE_A_STG2_5X6_OUT3_5_RSVD3(v) \
+ (((v) << 6) & BM_PXP_WFE_A_STG2_5X6_OUT3_5_RSVD3)
+#define BP_PXP_WFE_A_STG2_5X6_OUT3_5_LUTOUT20 0
+#define BM_PXP_WFE_A_STG2_5X6_OUT3_5_LUTOUT20 0x0000003F
+#define BF_PXP_WFE_A_STG2_5X6_OUT3_5_LUTOUT20(v) \
+ (((v) << 0) & BM_PXP_WFE_A_STG2_5X6_OUT3_5_LUTOUT20)
+
+#define HW_PXP_WFE_A_STG2_5X6_OUT3_6 (0x00001c50)
+
+#define BP_PXP_WFE_A_STG2_5X6_OUT3_6_RSVD0 30
+#define BM_PXP_WFE_A_STG2_5X6_OUT3_6_RSVD0 0xC0000000
+#define BF_PXP_WFE_A_STG2_5X6_OUT3_6_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFE_A_STG2_5X6_OUT3_6_RSVD0)
+#define BP_PXP_WFE_A_STG2_5X6_OUT3_6_LUTOUT27 24
+#define BM_PXP_WFE_A_STG2_5X6_OUT3_6_LUTOUT27 0x3F000000
+#define BF_PXP_WFE_A_STG2_5X6_OUT3_6_LUTOUT27(v) \
+ (((v) << 24) & BM_PXP_WFE_A_STG2_5X6_OUT3_6_LUTOUT27)
+#define BP_PXP_WFE_A_STG2_5X6_OUT3_6_RSVD1 22
+#define BM_PXP_WFE_A_STG2_5X6_OUT3_6_RSVD1 0x00C00000
+#define BF_PXP_WFE_A_STG2_5X6_OUT3_6_RSVD1(v) \
+ (((v) << 22) & BM_PXP_WFE_A_STG2_5X6_OUT3_6_RSVD1)
+#define BP_PXP_WFE_A_STG2_5X6_OUT3_6_LUTOUT26 16
+#define BM_PXP_WFE_A_STG2_5X6_OUT3_6_LUTOUT26 0x003F0000
+#define BF_PXP_WFE_A_STG2_5X6_OUT3_6_LUTOUT26(v) \
+ (((v) << 16) & BM_PXP_WFE_A_STG2_5X6_OUT3_6_LUTOUT26)
+#define BP_PXP_WFE_A_STG2_5X6_OUT3_6_RSVD2 14
+#define BM_PXP_WFE_A_STG2_5X6_OUT3_6_RSVD2 0x0000C000
+#define BF_PXP_WFE_A_STG2_5X6_OUT3_6_RSVD2(v) \
+ (((v) << 14) & BM_PXP_WFE_A_STG2_5X6_OUT3_6_RSVD2)
+#define BP_PXP_WFE_A_STG2_5X6_OUT3_6_LUTOUT25 8
+#define BM_PXP_WFE_A_STG2_5X6_OUT3_6_LUTOUT25 0x00003F00
+#define BF_PXP_WFE_A_STG2_5X6_OUT3_6_LUTOUT25(v) \
+ (((v) << 8) & BM_PXP_WFE_A_STG2_5X6_OUT3_6_LUTOUT25)
+#define BP_PXP_WFE_A_STG2_5X6_OUT3_6_RSVD3 6
+#define BM_PXP_WFE_A_STG2_5X6_OUT3_6_RSVD3 0x000000C0
+#define BF_PXP_WFE_A_STG2_5X6_OUT3_6_RSVD3(v) \
+ (((v) << 6) & BM_PXP_WFE_A_STG2_5X6_OUT3_6_RSVD3)
+#define BP_PXP_WFE_A_STG2_5X6_OUT3_6_LUTOUT24 0
+#define BM_PXP_WFE_A_STG2_5X6_OUT3_6_LUTOUT24 0x0000003F
+#define BF_PXP_WFE_A_STG2_5X6_OUT3_6_LUTOUT24(v) \
+ (((v) << 0) & BM_PXP_WFE_A_STG2_5X6_OUT3_6_LUTOUT24)
+
+#define HW_PXP_WFE_A_STG2_5X6_OUT3_7 (0x00001c60)
+
+#define BP_PXP_WFE_A_STG2_5X6_OUT3_7_RSVD0 30
+#define BM_PXP_WFE_A_STG2_5X6_OUT3_7_RSVD0 0xC0000000
+#define BF_PXP_WFE_A_STG2_5X6_OUT3_7_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFE_A_STG2_5X6_OUT3_7_RSVD0)
+#define BP_PXP_WFE_A_STG2_5X6_OUT3_7_LUTOUT31 24
+#define BM_PXP_WFE_A_STG2_5X6_OUT3_7_LUTOUT31 0x3F000000
+#define BF_PXP_WFE_A_STG2_5X6_OUT3_7_LUTOUT31(v) \
+ (((v) << 24) & BM_PXP_WFE_A_STG2_5X6_OUT3_7_LUTOUT31)
+#define BP_PXP_WFE_A_STG2_5X6_OUT3_7_RSVD1 22
+#define BM_PXP_WFE_A_STG2_5X6_OUT3_7_RSVD1 0x00C00000
+#define BF_PXP_WFE_A_STG2_5X6_OUT3_7_RSVD1(v) \
+ (((v) << 22) & BM_PXP_WFE_A_STG2_5X6_OUT3_7_RSVD1)
+#define BP_PXP_WFE_A_STG2_5X6_OUT3_7_LUTOUT30 16
+#define BM_PXP_WFE_A_STG2_5X6_OUT3_7_LUTOUT30 0x003F0000
+#define BF_PXP_WFE_A_STG2_5X6_OUT3_7_LUTOUT30(v) \
+ (((v) << 16) & BM_PXP_WFE_A_STG2_5X6_OUT3_7_LUTOUT30)
+#define BP_PXP_WFE_A_STG2_5X6_OUT3_7_RSVD2 14
+#define BM_PXP_WFE_A_STG2_5X6_OUT3_7_RSVD2 0x0000C000
+#define BF_PXP_WFE_A_STG2_5X6_OUT3_7_RSVD2(v) \
+ (((v) << 14) & BM_PXP_WFE_A_STG2_5X6_OUT3_7_RSVD2)
+#define BP_PXP_WFE_A_STG2_5X6_OUT3_7_LUTOUT29 8
+#define BM_PXP_WFE_A_STG2_5X6_OUT3_7_LUTOUT29 0x00003F00
+#define BF_PXP_WFE_A_STG2_5X6_OUT3_7_LUTOUT29(v) \
+ (((v) << 8) & BM_PXP_WFE_A_STG2_5X6_OUT3_7_LUTOUT29)
+#define BP_PXP_WFE_A_STG2_5X6_OUT3_7_RSVD3 6
+#define BM_PXP_WFE_A_STG2_5X6_OUT3_7_RSVD3 0x000000C0
+#define BF_PXP_WFE_A_STG2_5X6_OUT3_7_RSVD3(v) \
+ (((v) << 6) & BM_PXP_WFE_A_STG2_5X6_OUT3_7_RSVD3)
+#define BP_PXP_WFE_A_STG2_5X6_OUT3_7_LUTOUT28 0
+#define BM_PXP_WFE_A_STG2_5X6_OUT3_7_LUTOUT28 0x0000003F
+#define BF_PXP_WFE_A_STG2_5X6_OUT3_7_LUTOUT28(v) \
+ (((v) << 0) & BM_PXP_WFE_A_STG2_5X6_OUT3_7_LUTOUT28)
+
+#define HW_PXP_WFE_A_STAGE2_5X6_MASKS_0 (0x00001c70)
+
+#define BP_PXP_WFE_A_STAGE2_5X6_MASKS_0_RSVD0 29
+#define BM_PXP_WFE_A_STAGE2_5X6_MASKS_0_RSVD0 0xE0000000
+#define BF_PXP_WFE_A_STAGE2_5X6_MASKS_0_RSVD0(v) \
+ (((v) << 29) & BM_PXP_WFE_A_STAGE2_5X6_MASKS_0_RSVD0)
+#define BP_PXP_WFE_A_STAGE2_5X6_MASKS_0_MASK3 24
+#define BM_PXP_WFE_A_STAGE2_5X6_MASKS_0_MASK3 0x1F000000
+#define BF_PXP_WFE_A_STAGE2_5X6_MASKS_0_MASK3(v) \
+ (((v) << 24) & BM_PXP_WFE_A_STAGE2_5X6_MASKS_0_MASK3)
+#define BP_PXP_WFE_A_STAGE2_5X6_MASKS_0_RSVD1 21
+#define BM_PXP_WFE_A_STAGE2_5X6_MASKS_0_RSVD1 0x00E00000
+#define BF_PXP_WFE_A_STAGE2_5X6_MASKS_0_RSVD1(v) \
+ (((v) << 21) & BM_PXP_WFE_A_STAGE2_5X6_MASKS_0_RSVD1)
+#define BP_PXP_WFE_A_STAGE2_5X6_MASKS_0_MASK2 16
+#define BM_PXP_WFE_A_STAGE2_5X6_MASKS_0_MASK2 0x001F0000
+#define BF_PXP_WFE_A_STAGE2_5X6_MASKS_0_MASK2(v) \
+ (((v) << 16) & BM_PXP_WFE_A_STAGE2_5X6_MASKS_0_MASK2)
+#define BP_PXP_WFE_A_STAGE2_5X6_MASKS_0_RSVD2 13
+#define BM_PXP_WFE_A_STAGE2_5X6_MASKS_0_RSVD2 0x0000E000
+#define BF_PXP_WFE_A_STAGE2_5X6_MASKS_0_RSVD2(v) \
+ (((v) << 13) & BM_PXP_WFE_A_STAGE2_5X6_MASKS_0_RSVD2)
+#define BP_PXP_WFE_A_STAGE2_5X6_MASKS_0_MASK1 8
+#define BM_PXP_WFE_A_STAGE2_5X6_MASKS_0_MASK1 0x00001F00
+#define BF_PXP_WFE_A_STAGE2_5X6_MASKS_0_MASK1(v) \
+ (((v) << 8) & BM_PXP_WFE_A_STAGE2_5X6_MASKS_0_MASK1)
+#define BP_PXP_WFE_A_STAGE2_5X6_MASKS_0_RSVD3 5
+#define BM_PXP_WFE_A_STAGE2_5X6_MASKS_0_RSVD3 0x000000E0
+#define BF_PXP_WFE_A_STAGE2_5X6_MASKS_0_RSVD3(v) \
+ (((v) << 5) & BM_PXP_WFE_A_STAGE2_5X6_MASKS_0_RSVD3)
+#define BP_PXP_WFE_A_STAGE2_5X6_MASKS_0_MASK0 0
+#define BM_PXP_WFE_A_STAGE2_5X6_MASKS_0_MASK0 0x0000001F
+#define BF_PXP_WFE_A_STAGE2_5X6_MASKS_0_MASK0(v) \
+ (((v) << 0) & BM_PXP_WFE_A_STAGE2_5X6_MASKS_0_MASK0)
+
+#define HW_PXP_WFE_A_STAGE2_5X6_ADDR_0 (0x00001c80)
+
+#define BP_PXP_WFE_A_STAGE2_5X6_ADDR_0_RSVD0 30
+#define BM_PXP_WFE_A_STAGE2_5X6_ADDR_0_RSVD0 0xC0000000
+#define BF_PXP_WFE_A_STAGE2_5X6_ADDR_0_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFE_A_STAGE2_5X6_ADDR_0_RSVD0)
+#define BP_PXP_WFE_A_STAGE2_5X6_ADDR_0_MUXADDR3 24
+#define BM_PXP_WFE_A_STAGE2_5X6_ADDR_0_MUXADDR3 0x3F000000
+#define BF_PXP_WFE_A_STAGE2_5X6_ADDR_0_MUXADDR3(v) \
+ (((v) << 24) & BM_PXP_WFE_A_STAGE2_5X6_ADDR_0_MUXADDR3)
+#define BP_PXP_WFE_A_STAGE2_5X6_ADDR_0_RSVD1 22
+#define BM_PXP_WFE_A_STAGE2_5X6_ADDR_0_RSVD1 0x00C00000
+#define BF_PXP_WFE_A_STAGE2_5X6_ADDR_0_RSVD1(v) \
+ (((v) << 22) & BM_PXP_WFE_A_STAGE2_5X6_ADDR_0_RSVD1)
+#define BP_PXP_WFE_A_STAGE2_5X6_ADDR_0_MUXADDR2 16
+#define BM_PXP_WFE_A_STAGE2_5X6_ADDR_0_MUXADDR2 0x003F0000
+#define BF_PXP_WFE_A_STAGE2_5X6_ADDR_0_MUXADDR2(v) \
+ (((v) << 16) & BM_PXP_WFE_A_STAGE2_5X6_ADDR_0_MUXADDR2)
+#define BP_PXP_WFE_A_STAGE2_5X6_ADDR_0_RSVD2 14
+#define BM_PXP_WFE_A_STAGE2_5X6_ADDR_0_RSVD2 0x0000C000
+#define BF_PXP_WFE_A_STAGE2_5X6_ADDR_0_RSVD2(v) \
+ (((v) << 14) & BM_PXP_WFE_A_STAGE2_5X6_ADDR_0_RSVD2)
+#define BP_PXP_WFE_A_STAGE2_5X6_ADDR_0_MUXADDR1 8
+#define BM_PXP_WFE_A_STAGE2_5X6_ADDR_0_MUXADDR1 0x00003F00
+#define BF_PXP_WFE_A_STAGE2_5X6_ADDR_0_MUXADDR1(v) \
+ (((v) << 8) & BM_PXP_WFE_A_STAGE2_5X6_ADDR_0_MUXADDR1)
+#define BP_PXP_WFE_A_STAGE2_5X6_ADDR_0_RSVD3 6
+#define BM_PXP_WFE_A_STAGE2_5X6_ADDR_0_RSVD3 0x000000C0
+#define BF_PXP_WFE_A_STAGE2_5X6_ADDR_0_RSVD3(v) \
+ (((v) << 6) & BM_PXP_WFE_A_STAGE2_5X6_ADDR_0_RSVD3)
+#define BP_PXP_WFE_A_STAGE2_5X6_ADDR_0_MUXADDR0 0
+#define BM_PXP_WFE_A_STAGE2_5X6_ADDR_0_MUXADDR0 0x0000003F
+#define BF_PXP_WFE_A_STAGE2_5X6_ADDR_0_MUXADDR0(v) \
+ (((v) << 0) & BM_PXP_WFE_A_STAGE2_5X6_ADDR_0_MUXADDR0)
+
+#define HW_PXP_WFE_A_STG2_5X1_OUT0 (0x00001c90)
+
+#define BM_PXP_WFE_A_STG2_5X1_OUT0_LUTOUT31 0x80000000
+#define BF_PXP_WFE_A_STG2_5X1_OUT0_LUTOUT31(v) \
+ (((v) << 31) & BM_PXP_WFE_A_STG2_5X1_OUT0_LUTOUT31)
+#define BM_PXP_WFE_A_STG2_5X1_OUT0_LUTOUT30 0x40000000
+#define BF_PXP_WFE_A_STG2_5X1_OUT0_LUTOUT30(v) \
+ (((v) << 30) & BM_PXP_WFE_A_STG2_5X1_OUT0_LUTOUT30)
+#define BM_PXP_WFE_A_STG2_5X1_OUT0_LUTOUT29 0x20000000
+#define BF_PXP_WFE_A_STG2_5X1_OUT0_LUTOUT29(v) \
+ (((v) << 29) & BM_PXP_WFE_A_STG2_5X1_OUT0_LUTOUT29)
+#define BM_PXP_WFE_A_STG2_5X1_OUT0_LUTOUT28 0x10000000
+#define BF_PXP_WFE_A_STG2_5X1_OUT0_LUTOUT28(v) \
+ (((v) << 28) & BM_PXP_WFE_A_STG2_5X1_OUT0_LUTOUT28)
+#define BM_PXP_WFE_A_STG2_5X1_OUT0_LUTOUT27 0x08000000
+#define BF_PXP_WFE_A_STG2_5X1_OUT0_LUTOUT27(v) \
+ (((v) << 27) & BM_PXP_WFE_A_STG2_5X1_OUT0_LUTOUT27)
+#define BM_PXP_WFE_A_STG2_5X1_OUT0_LUTOUT26 0x04000000
+#define BF_PXP_WFE_A_STG2_5X1_OUT0_LUTOUT26(v) \
+ (((v) << 26) & BM_PXP_WFE_A_STG2_5X1_OUT0_LUTOUT26)
+#define BM_PXP_WFE_A_STG2_5X1_OUT0_LUTOUT25 0x02000000
+#define BF_PXP_WFE_A_STG2_5X1_OUT0_LUTOUT25(v) \
+ (((v) << 25) & BM_PXP_WFE_A_STG2_5X1_OUT0_LUTOUT25)
+#define BM_PXP_WFE_A_STG2_5X1_OUT0_LUTOUT24 0x01000000
+#define BF_PXP_WFE_A_STG2_5X1_OUT0_LUTOUT24(v) \
+ (((v) << 24) & BM_PXP_WFE_A_STG2_5X1_OUT0_LUTOUT24)
+#define BM_PXP_WFE_A_STG2_5X1_OUT0_LUTOUT23 0x00800000
+#define BF_PXP_WFE_A_STG2_5X1_OUT0_LUTOUT23(v) \
+ (((v) << 23) & BM_PXP_WFE_A_STG2_5X1_OUT0_LUTOUT23)
+#define BM_PXP_WFE_A_STG2_5X1_OUT0_LUTOUT22 0x00400000
+#define BF_PXP_WFE_A_STG2_5X1_OUT0_LUTOUT22(v) \
+ (((v) << 22) & BM_PXP_WFE_A_STG2_5X1_OUT0_LUTOUT22)
+#define BM_PXP_WFE_A_STG2_5X1_OUT0_LUTOUT21 0x00200000
+#define BF_PXP_WFE_A_STG2_5X1_OUT0_LUTOUT21(v) \
+ (((v) << 21) & BM_PXP_WFE_A_STG2_5X1_OUT0_LUTOUT21)
+#define BM_PXP_WFE_A_STG2_5X1_OUT0_LUTOUT20 0x00100000
+#define BF_PXP_WFE_A_STG2_5X1_OUT0_LUTOUT20(v) \
+ (((v) << 20) & BM_PXP_WFE_A_STG2_5X1_OUT0_LUTOUT20)
+#define BM_PXP_WFE_A_STG2_5X1_OUT0_LUTOUT19 0x00080000
+#define BF_PXP_WFE_A_STG2_5X1_OUT0_LUTOUT19(v) \
+ (((v) << 19) & BM_PXP_WFE_A_STG2_5X1_OUT0_LUTOUT19)
+#define BM_PXP_WFE_A_STG2_5X1_OUT0_LUTOUT18 0x00040000
+#define BF_PXP_WFE_A_STG2_5X1_OUT0_LUTOUT18(v) \
+ (((v) << 18) & BM_PXP_WFE_A_STG2_5X1_OUT0_LUTOUT18)
+#define BM_PXP_WFE_A_STG2_5X1_OUT0_LUTOUT17 0x00020000
+#define BF_PXP_WFE_A_STG2_5X1_OUT0_LUTOUT17(v) \
+ (((v) << 17) & BM_PXP_WFE_A_STG2_5X1_OUT0_LUTOUT17)
+#define BM_PXP_WFE_A_STG2_5X1_OUT0_LUTOUT16 0x00010000
+#define BF_PXP_WFE_A_STG2_5X1_OUT0_LUTOUT16(v) \
+ (((v) << 16) & BM_PXP_WFE_A_STG2_5X1_OUT0_LUTOUT16)
+#define BM_PXP_WFE_A_STG2_5X1_OUT0_LUTOUT15 0x00008000
+#define BF_PXP_WFE_A_STG2_5X1_OUT0_LUTOUT15(v) \
+ (((v) << 15) & BM_PXP_WFE_A_STG2_5X1_OUT0_LUTOUT15)
+#define BM_PXP_WFE_A_STG2_5X1_OUT0_LUTOUT14 0x00004000
+#define BF_PXP_WFE_A_STG2_5X1_OUT0_LUTOUT14(v) \
+ (((v) << 14) & BM_PXP_WFE_A_STG2_5X1_OUT0_LUTOUT14)
+#define BM_PXP_WFE_A_STG2_5X1_OUT0_LUTOUT13 0x00002000
+#define BF_PXP_WFE_A_STG2_5X1_OUT0_LUTOUT13(v) \
+ (((v) << 13) & BM_PXP_WFE_A_STG2_5X1_OUT0_LUTOUT13)
+#define BM_PXP_WFE_A_STG2_5X1_OUT0_LUTOUT12 0x00001000
+#define BF_PXP_WFE_A_STG2_5X1_OUT0_LUTOUT12(v) \
+ (((v) << 12) & BM_PXP_WFE_A_STG2_5X1_OUT0_LUTOUT12)
+#define BM_PXP_WFE_A_STG2_5X1_OUT0_LUTOUT11 0x00000800
+#define BF_PXP_WFE_A_STG2_5X1_OUT0_LUTOUT11(v) \
+ (((v) << 11) & BM_PXP_WFE_A_STG2_5X1_OUT0_LUTOUT11)
+#define BM_PXP_WFE_A_STG2_5X1_OUT0_LUTOUT10 0x00000400
+#define BF_PXP_WFE_A_STG2_5X1_OUT0_LUTOUT10(v) \
+ (((v) << 10) & BM_PXP_WFE_A_STG2_5X1_OUT0_LUTOUT10)
+#define BM_PXP_WFE_A_STG2_5X1_OUT0_LUTOUT9 0x00000200
+#define BF_PXP_WFE_A_STG2_5X1_OUT0_LUTOUT9(v) \
+ (((v) << 9) & BM_PXP_WFE_A_STG2_5X1_OUT0_LUTOUT9)
+#define BM_PXP_WFE_A_STG2_5X1_OUT0_LUTOUT8 0x00000100
+#define BF_PXP_WFE_A_STG2_5X1_OUT0_LUTOUT8(v) \
+ (((v) << 8) & BM_PXP_WFE_A_STG2_5X1_OUT0_LUTOUT8)
+#define BM_PXP_WFE_A_STG2_5X1_OUT0_LUTOUT7 0x00000080
+#define BF_PXP_WFE_A_STG2_5X1_OUT0_LUTOUT7(v) \
+ (((v) << 7) & BM_PXP_WFE_A_STG2_5X1_OUT0_LUTOUT7)
+#define BM_PXP_WFE_A_STG2_5X1_OUT0_LUTOUT6 0x00000040
+#define BF_PXP_WFE_A_STG2_5X1_OUT0_LUTOUT6(v) \
+ (((v) << 6) & BM_PXP_WFE_A_STG2_5X1_OUT0_LUTOUT6)
+#define BM_PXP_WFE_A_STG2_5X1_OUT0_LUTOUT5 0x00000020
+#define BF_PXP_WFE_A_STG2_5X1_OUT0_LUTOUT5(v) \
+ (((v) << 5) & BM_PXP_WFE_A_STG2_5X1_OUT0_LUTOUT5)
+#define BM_PXP_WFE_A_STG2_5X1_OUT0_LUTOUT4 0x00000010
+#define BF_PXP_WFE_A_STG2_5X1_OUT0_LUTOUT4(v) \
+ (((v) << 4) & BM_PXP_WFE_A_STG2_5X1_OUT0_LUTOUT4)
+#define BM_PXP_WFE_A_STG2_5X1_OUT0_LUTOUT3 0x00000008
+#define BF_PXP_WFE_A_STG2_5X1_OUT0_LUTOUT3(v) \
+ (((v) << 3) & BM_PXP_WFE_A_STG2_5X1_OUT0_LUTOUT3)
+#define BM_PXP_WFE_A_STG2_5X1_OUT0_LUTOUT2 0x00000004
+#define BF_PXP_WFE_A_STG2_5X1_OUT0_LUTOUT2(v) \
+ (((v) << 2) & BM_PXP_WFE_A_STG2_5X1_OUT0_LUTOUT2)
+#define BM_PXP_WFE_A_STG2_5X1_OUT0_LUTOUT1 0x00000002
+#define BF_PXP_WFE_A_STG2_5X1_OUT0_LUTOUT1(v) \
+ (((v) << 1) & BM_PXP_WFE_A_STG2_5X1_OUT0_LUTOUT1)
+#define BM_PXP_WFE_A_STG2_5X1_OUT0_LUTOUT0 0x00000001
+#define BF_PXP_WFE_A_STG2_5X1_OUT0_LUTOUT0(v) \
+ (((v) << 0) & BM_PXP_WFE_A_STG2_5X1_OUT0_LUTOUT0)
+
+#define HW_PXP_WFE_A_STG2_5X1_OUT1 (0x00001ca0)
+
+#define BM_PXP_WFE_A_STG2_5X1_OUT1_LUTOUT31 0x80000000
+#define BF_PXP_WFE_A_STG2_5X1_OUT1_LUTOUT31(v) \
+ (((v) << 31) & BM_PXP_WFE_A_STG2_5X1_OUT1_LUTOUT31)
+#define BM_PXP_WFE_A_STG2_5X1_OUT1_LUTOUT30 0x40000000
+#define BF_PXP_WFE_A_STG2_5X1_OUT1_LUTOUT30(v) \
+ (((v) << 30) & BM_PXP_WFE_A_STG2_5X1_OUT1_LUTOUT30)
+#define BM_PXP_WFE_A_STG2_5X1_OUT1_LUTOUT29 0x20000000
+#define BF_PXP_WFE_A_STG2_5X1_OUT1_LUTOUT29(v) \
+ (((v) << 29) & BM_PXP_WFE_A_STG2_5X1_OUT1_LUTOUT29)
+#define BM_PXP_WFE_A_STG2_5X1_OUT1_LUTOUT28 0x10000000
+#define BF_PXP_WFE_A_STG2_5X1_OUT1_LUTOUT28(v) \
+ (((v) << 28) & BM_PXP_WFE_A_STG2_5X1_OUT1_LUTOUT28)
+#define BM_PXP_WFE_A_STG2_5X1_OUT1_LUTOUT27 0x08000000
+#define BF_PXP_WFE_A_STG2_5X1_OUT1_LUTOUT27(v) \
+ (((v) << 27) & BM_PXP_WFE_A_STG2_5X1_OUT1_LUTOUT27)
+#define BM_PXP_WFE_A_STG2_5X1_OUT1_LUTOUT26 0x04000000
+#define BF_PXP_WFE_A_STG2_5X1_OUT1_LUTOUT26(v) \
+ (((v) << 26) & BM_PXP_WFE_A_STG2_5X1_OUT1_LUTOUT26)
+#define BM_PXP_WFE_A_STG2_5X1_OUT1_LUTOUT25 0x02000000
+#define BF_PXP_WFE_A_STG2_5X1_OUT1_LUTOUT25(v) \
+ (((v) << 25) & BM_PXP_WFE_A_STG2_5X1_OUT1_LUTOUT25)
+#define BM_PXP_WFE_A_STG2_5X1_OUT1_LUTOUT24 0x01000000
+#define BF_PXP_WFE_A_STG2_5X1_OUT1_LUTOUT24(v) \
+ (((v) << 24) & BM_PXP_WFE_A_STG2_5X1_OUT1_LUTOUT24)
+#define BM_PXP_WFE_A_STG2_5X1_OUT1_LUTOUT23 0x00800000
+#define BF_PXP_WFE_A_STG2_5X1_OUT1_LUTOUT23(v) \
+ (((v) << 23) & BM_PXP_WFE_A_STG2_5X1_OUT1_LUTOUT23)
+#define BM_PXP_WFE_A_STG2_5X1_OUT1_LUTOUT22 0x00400000
+#define BF_PXP_WFE_A_STG2_5X1_OUT1_LUTOUT22(v) \
+ (((v) << 22) & BM_PXP_WFE_A_STG2_5X1_OUT1_LUTOUT22)
+#define BM_PXP_WFE_A_STG2_5X1_OUT1_LUTOUT21 0x00200000
+#define BF_PXP_WFE_A_STG2_5X1_OUT1_LUTOUT21(v) \
+ (((v) << 21) & BM_PXP_WFE_A_STG2_5X1_OUT1_LUTOUT21)
+#define BM_PXP_WFE_A_STG2_5X1_OUT1_LUTOUT20 0x00100000
+#define BF_PXP_WFE_A_STG2_5X1_OUT1_LUTOUT20(v) \
+ (((v) << 20) & BM_PXP_WFE_A_STG2_5X1_OUT1_LUTOUT20)
+#define BM_PXP_WFE_A_STG2_5X1_OUT1_LUTOUT19 0x00080000
+#define BF_PXP_WFE_A_STG2_5X1_OUT1_LUTOUT19(v) \
+ (((v) << 19) & BM_PXP_WFE_A_STG2_5X1_OUT1_LUTOUT19)
+#define BM_PXP_WFE_A_STG2_5X1_OUT1_LUTOUT18 0x00040000
+#define BF_PXP_WFE_A_STG2_5X1_OUT1_LUTOUT18(v) \
+ (((v) << 18) & BM_PXP_WFE_A_STG2_5X1_OUT1_LUTOUT18)
+#define BM_PXP_WFE_A_STG2_5X1_OUT1_LUTOUT17 0x00020000
+#define BF_PXP_WFE_A_STG2_5X1_OUT1_LUTOUT17(v) \
+ (((v) << 17) & BM_PXP_WFE_A_STG2_5X1_OUT1_LUTOUT17)
+#define BM_PXP_WFE_A_STG2_5X1_OUT1_LUTOUT16 0x00010000
+#define BF_PXP_WFE_A_STG2_5X1_OUT1_LUTOUT16(v) \
+ (((v) << 16) & BM_PXP_WFE_A_STG2_5X1_OUT1_LUTOUT16)
+#define BM_PXP_WFE_A_STG2_5X1_OUT1_LUTOUT15 0x00008000
+#define BF_PXP_WFE_A_STG2_5X1_OUT1_LUTOUT15(v) \
+ (((v) << 15) & BM_PXP_WFE_A_STG2_5X1_OUT1_LUTOUT15)
+#define BM_PXP_WFE_A_STG2_5X1_OUT1_LUTOUT14 0x00004000
+#define BF_PXP_WFE_A_STG2_5X1_OUT1_LUTOUT14(v) \
+ (((v) << 14) & BM_PXP_WFE_A_STG2_5X1_OUT1_LUTOUT14)
+#define BM_PXP_WFE_A_STG2_5X1_OUT1_LUTOUT13 0x00002000
+#define BF_PXP_WFE_A_STG2_5X1_OUT1_LUTOUT13(v) \
+ (((v) << 13) & BM_PXP_WFE_A_STG2_5X1_OUT1_LUTOUT13)
+#define BM_PXP_WFE_A_STG2_5X1_OUT1_LUTOUT12 0x00001000
+#define BF_PXP_WFE_A_STG2_5X1_OUT1_LUTOUT12(v) \
+ (((v) << 12) & BM_PXP_WFE_A_STG2_5X1_OUT1_LUTOUT12)
+#define BM_PXP_WFE_A_STG2_5X1_OUT1_LUTOUT11 0x00000800
+#define BF_PXP_WFE_A_STG2_5X1_OUT1_LUTOUT11(v) \
+ (((v) << 11) & BM_PXP_WFE_A_STG2_5X1_OUT1_LUTOUT11)
+#define BM_PXP_WFE_A_STG2_5X1_OUT1_LUTOUT10 0x00000400
+#define BF_PXP_WFE_A_STG2_5X1_OUT1_LUTOUT10(v) \
+ (((v) << 10) & BM_PXP_WFE_A_STG2_5X1_OUT1_LUTOUT10)
+#define BM_PXP_WFE_A_STG2_5X1_OUT1_LUTOUT9 0x00000200
+#define BF_PXP_WFE_A_STG2_5X1_OUT1_LUTOUT9(v) \
+ (((v) << 9) & BM_PXP_WFE_A_STG2_5X1_OUT1_LUTOUT9)
+#define BM_PXP_WFE_A_STG2_5X1_OUT1_LUTOUT8 0x00000100
+#define BF_PXP_WFE_A_STG2_5X1_OUT1_LUTOUT8(v) \
+ (((v) << 8) & BM_PXP_WFE_A_STG2_5X1_OUT1_LUTOUT8)
+#define BM_PXP_WFE_A_STG2_5X1_OUT1_LUTOUT7 0x00000080
+#define BF_PXP_WFE_A_STG2_5X1_OUT1_LUTOUT7(v) \
+ (((v) << 7) & BM_PXP_WFE_A_STG2_5X1_OUT1_LUTOUT7)
+#define BM_PXP_WFE_A_STG2_5X1_OUT1_LUTOUT6 0x00000040
+#define BF_PXP_WFE_A_STG2_5X1_OUT1_LUTOUT6(v) \
+ (((v) << 6) & BM_PXP_WFE_A_STG2_5X1_OUT1_LUTOUT6)
+#define BM_PXP_WFE_A_STG2_5X1_OUT1_LUTOUT5 0x00000020
+#define BF_PXP_WFE_A_STG2_5X1_OUT1_LUTOUT5(v) \
+ (((v) << 5) & BM_PXP_WFE_A_STG2_5X1_OUT1_LUTOUT5)
+#define BM_PXP_WFE_A_STG2_5X1_OUT1_LUTOUT4 0x00000010
+#define BF_PXP_WFE_A_STG2_5X1_OUT1_LUTOUT4(v) \
+ (((v) << 4) & BM_PXP_WFE_A_STG2_5X1_OUT1_LUTOUT4)
+#define BM_PXP_WFE_A_STG2_5X1_OUT1_LUTOUT3 0x00000008
+#define BF_PXP_WFE_A_STG2_5X1_OUT1_LUTOUT3(v) \
+ (((v) << 3) & BM_PXP_WFE_A_STG2_5X1_OUT1_LUTOUT3)
+#define BM_PXP_WFE_A_STG2_5X1_OUT1_LUTOUT2 0x00000004
+#define BF_PXP_WFE_A_STG2_5X1_OUT1_LUTOUT2(v) \
+ (((v) << 2) & BM_PXP_WFE_A_STG2_5X1_OUT1_LUTOUT2)
+#define BM_PXP_WFE_A_STG2_5X1_OUT1_LUTOUT1 0x00000002
+#define BF_PXP_WFE_A_STG2_5X1_OUT1_LUTOUT1(v) \
+ (((v) << 1) & BM_PXP_WFE_A_STG2_5X1_OUT1_LUTOUT1)
+#define BM_PXP_WFE_A_STG2_5X1_OUT1_LUTOUT0 0x00000001
+#define BF_PXP_WFE_A_STG2_5X1_OUT1_LUTOUT0(v) \
+ (((v) << 0) & BM_PXP_WFE_A_STG2_5X1_OUT1_LUTOUT0)
+
+#define HW_PXP_WFE_A_STG2_5X1_OUT2 (0x00001cb0)
+
+#define BM_PXP_WFE_A_STG2_5X1_OUT2_LUTOUT31 0x80000000
+#define BF_PXP_WFE_A_STG2_5X1_OUT2_LUTOUT31(v) \
+ (((v) << 31) & BM_PXP_WFE_A_STG2_5X1_OUT2_LUTOUT31)
+#define BM_PXP_WFE_A_STG2_5X1_OUT2_LUTOUT30 0x40000000
+#define BF_PXP_WFE_A_STG2_5X1_OUT2_LUTOUT30(v) \
+ (((v) << 30) & BM_PXP_WFE_A_STG2_5X1_OUT2_LUTOUT30)
+#define BM_PXP_WFE_A_STG2_5X1_OUT2_LUTOUT29 0x20000000
+#define BF_PXP_WFE_A_STG2_5X1_OUT2_LUTOUT29(v) \
+ (((v) << 29) & BM_PXP_WFE_A_STG2_5X1_OUT2_LUTOUT29)
+#define BM_PXP_WFE_A_STG2_5X1_OUT2_LUTOUT28 0x10000000
+#define BF_PXP_WFE_A_STG2_5X1_OUT2_LUTOUT28(v) \
+ (((v) << 28) & BM_PXP_WFE_A_STG2_5X1_OUT2_LUTOUT28)
+#define BM_PXP_WFE_A_STG2_5X1_OUT2_LUTOUT27 0x08000000
+#define BF_PXP_WFE_A_STG2_5X1_OUT2_LUTOUT27(v) \
+ (((v) << 27) & BM_PXP_WFE_A_STG2_5X1_OUT2_LUTOUT27)
+#define BM_PXP_WFE_A_STG2_5X1_OUT2_LUTOUT26 0x04000000
+#define BF_PXP_WFE_A_STG2_5X1_OUT2_LUTOUT26(v) \
+ (((v) << 26) & BM_PXP_WFE_A_STG2_5X1_OUT2_LUTOUT26)
+#define BM_PXP_WFE_A_STG2_5X1_OUT2_LUTOUT25 0x02000000
+#define BF_PXP_WFE_A_STG2_5X1_OUT2_LUTOUT25(v) \
+ (((v) << 25) & BM_PXP_WFE_A_STG2_5X1_OUT2_LUTOUT25)
+#define BM_PXP_WFE_A_STG2_5X1_OUT2_LUTOUT24 0x01000000
+#define BF_PXP_WFE_A_STG2_5X1_OUT2_LUTOUT24(v) \
+ (((v) << 24) & BM_PXP_WFE_A_STG2_5X1_OUT2_LUTOUT24)
+#define BM_PXP_WFE_A_STG2_5X1_OUT2_LUTOUT23 0x00800000
+#define BF_PXP_WFE_A_STG2_5X1_OUT2_LUTOUT23(v) \
+ (((v) << 23) & BM_PXP_WFE_A_STG2_5X1_OUT2_LUTOUT23)
+#define BM_PXP_WFE_A_STG2_5X1_OUT2_LUTOUT22 0x00400000
+#define BF_PXP_WFE_A_STG2_5X1_OUT2_LUTOUT22(v) \
+ (((v) << 22) & BM_PXP_WFE_A_STG2_5X1_OUT2_LUTOUT22)
+#define BM_PXP_WFE_A_STG2_5X1_OUT2_LUTOUT21 0x00200000
+#define BF_PXP_WFE_A_STG2_5X1_OUT2_LUTOUT21(v) \
+ (((v) << 21) & BM_PXP_WFE_A_STG2_5X1_OUT2_LUTOUT21)
+#define BM_PXP_WFE_A_STG2_5X1_OUT2_LUTOUT20 0x00100000
+#define BF_PXP_WFE_A_STG2_5X1_OUT2_LUTOUT20(v) \
+ (((v) << 20) & BM_PXP_WFE_A_STG2_5X1_OUT2_LUTOUT20)
+#define BM_PXP_WFE_A_STG2_5X1_OUT2_LUTOUT19 0x00080000
+#define BF_PXP_WFE_A_STG2_5X1_OUT2_LUTOUT19(v) \
+ (((v) << 19) & BM_PXP_WFE_A_STG2_5X1_OUT2_LUTOUT19)
+#define BM_PXP_WFE_A_STG2_5X1_OUT2_LUTOUT18 0x00040000
+#define BF_PXP_WFE_A_STG2_5X1_OUT2_LUTOUT18(v) \
+ (((v) << 18) & BM_PXP_WFE_A_STG2_5X1_OUT2_LUTOUT18)
+#define BM_PXP_WFE_A_STG2_5X1_OUT2_LUTOUT17 0x00020000
+#define BF_PXP_WFE_A_STG2_5X1_OUT2_LUTOUT17(v) \
+ (((v) << 17) & BM_PXP_WFE_A_STG2_5X1_OUT2_LUTOUT17)
+#define BM_PXP_WFE_A_STG2_5X1_OUT2_LUTOUT16 0x00010000
+#define BF_PXP_WFE_A_STG2_5X1_OUT2_LUTOUT16(v) \
+ (((v) << 16) & BM_PXP_WFE_A_STG2_5X1_OUT2_LUTOUT16)
+#define BM_PXP_WFE_A_STG2_5X1_OUT2_LUTOUT15 0x00008000
+#define BF_PXP_WFE_A_STG2_5X1_OUT2_LUTOUT15(v) \
+ (((v) << 15) & BM_PXP_WFE_A_STG2_5X1_OUT2_LUTOUT15)
+#define BM_PXP_WFE_A_STG2_5X1_OUT2_LUTOUT14 0x00004000
+#define BF_PXP_WFE_A_STG2_5X1_OUT2_LUTOUT14(v) \
+ (((v) << 14) & BM_PXP_WFE_A_STG2_5X1_OUT2_LUTOUT14)
+#define BM_PXP_WFE_A_STG2_5X1_OUT2_LUTOUT13 0x00002000
+#define BF_PXP_WFE_A_STG2_5X1_OUT2_LUTOUT13(v) \
+ (((v) << 13) & BM_PXP_WFE_A_STG2_5X1_OUT2_LUTOUT13)
+#define BM_PXP_WFE_A_STG2_5X1_OUT2_LUTOUT12 0x00001000
+#define BF_PXP_WFE_A_STG2_5X1_OUT2_LUTOUT12(v) \
+ (((v) << 12) & BM_PXP_WFE_A_STG2_5X1_OUT2_LUTOUT12)
+#define BM_PXP_WFE_A_STG2_5X1_OUT2_LUTOUT11 0x00000800
+#define BF_PXP_WFE_A_STG2_5X1_OUT2_LUTOUT11(v) \
+ (((v) << 11) & BM_PXP_WFE_A_STG2_5X1_OUT2_LUTOUT11)
+#define BM_PXP_WFE_A_STG2_5X1_OUT2_LUTOUT10 0x00000400
+#define BF_PXP_WFE_A_STG2_5X1_OUT2_LUTOUT10(v) \
+ (((v) << 10) & BM_PXP_WFE_A_STG2_5X1_OUT2_LUTOUT10)
+#define BM_PXP_WFE_A_STG2_5X1_OUT2_LUTOUT9 0x00000200
+#define BF_PXP_WFE_A_STG2_5X1_OUT2_LUTOUT9(v) \
+ (((v) << 9) & BM_PXP_WFE_A_STG2_5X1_OUT2_LUTOUT9)
+#define BM_PXP_WFE_A_STG2_5X1_OUT2_LUTOUT8 0x00000100
+#define BF_PXP_WFE_A_STG2_5X1_OUT2_LUTOUT8(v) \
+ (((v) << 8) & BM_PXP_WFE_A_STG2_5X1_OUT2_LUTOUT8)
+#define BM_PXP_WFE_A_STG2_5X1_OUT2_LUTOUT7 0x00000080
+#define BF_PXP_WFE_A_STG2_5X1_OUT2_LUTOUT7(v) \
+ (((v) << 7) & BM_PXP_WFE_A_STG2_5X1_OUT2_LUTOUT7)
+#define BM_PXP_WFE_A_STG2_5X1_OUT2_LUTOUT6 0x00000040
+#define BF_PXP_WFE_A_STG2_5X1_OUT2_LUTOUT6(v) \
+ (((v) << 6) & BM_PXP_WFE_A_STG2_5X1_OUT2_LUTOUT6)
+#define BM_PXP_WFE_A_STG2_5X1_OUT2_LUTOUT5 0x00000020
+#define BF_PXP_WFE_A_STG2_5X1_OUT2_LUTOUT5(v) \
+ (((v) << 5) & BM_PXP_WFE_A_STG2_5X1_OUT2_LUTOUT5)
+#define BM_PXP_WFE_A_STG2_5X1_OUT2_LUTOUT4 0x00000010
+#define BF_PXP_WFE_A_STG2_5X1_OUT2_LUTOUT4(v) \
+ (((v) << 4) & BM_PXP_WFE_A_STG2_5X1_OUT2_LUTOUT4)
+#define BM_PXP_WFE_A_STG2_5X1_OUT2_LUTOUT3 0x00000008
+#define BF_PXP_WFE_A_STG2_5X1_OUT2_LUTOUT3(v) \
+ (((v) << 3) & BM_PXP_WFE_A_STG2_5X1_OUT2_LUTOUT3)
+#define BM_PXP_WFE_A_STG2_5X1_OUT2_LUTOUT2 0x00000004
+#define BF_PXP_WFE_A_STG2_5X1_OUT2_LUTOUT2(v) \
+ (((v) << 2) & BM_PXP_WFE_A_STG2_5X1_OUT2_LUTOUT2)
+#define BM_PXP_WFE_A_STG2_5X1_OUT2_LUTOUT1 0x00000002
+#define BF_PXP_WFE_A_STG2_5X1_OUT2_LUTOUT1(v) \
+ (((v) << 1) & BM_PXP_WFE_A_STG2_5X1_OUT2_LUTOUT1)
+#define BM_PXP_WFE_A_STG2_5X1_OUT2_LUTOUT0 0x00000001
+#define BF_PXP_WFE_A_STG2_5X1_OUT2_LUTOUT0(v) \
+ (((v) << 0) & BM_PXP_WFE_A_STG2_5X1_OUT2_LUTOUT0)
+
+#define HW_PXP_WFE_A_STG2_5X1_OUT3 (0x00001cc0)
+
+#define BM_PXP_WFE_A_STG2_5X1_OUT3_LUTOUT31 0x80000000
+#define BF_PXP_WFE_A_STG2_5X1_OUT3_LUTOUT31(v) \
+ (((v) << 31) & BM_PXP_WFE_A_STG2_5X1_OUT3_LUTOUT31)
+#define BM_PXP_WFE_A_STG2_5X1_OUT3_LUTOUT30 0x40000000
+#define BF_PXP_WFE_A_STG2_5X1_OUT3_LUTOUT30(v) \
+ (((v) << 30) & BM_PXP_WFE_A_STG2_5X1_OUT3_LUTOUT30)
+#define BM_PXP_WFE_A_STG2_5X1_OUT3_LUTOUT29 0x20000000
+#define BF_PXP_WFE_A_STG2_5X1_OUT3_LUTOUT29(v) \
+ (((v) << 29) & BM_PXP_WFE_A_STG2_5X1_OUT3_LUTOUT29)
+#define BM_PXP_WFE_A_STG2_5X1_OUT3_LUTOUT28 0x10000000
+#define BF_PXP_WFE_A_STG2_5X1_OUT3_LUTOUT28(v) \
+ (((v) << 28) & BM_PXP_WFE_A_STG2_5X1_OUT3_LUTOUT28)
+#define BM_PXP_WFE_A_STG2_5X1_OUT3_LUTOUT27 0x08000000
+#define BF_PXP_WFE_A_STG2_5X1_OUT3_LUTOUT27(v) \
+ (((v) << 27) & BM_PXP_WFE_A_STG2_5X1_OUT3_LUTOUT27)
+#define BM_PXP_WFE_A_STG2_5X1_OUT3_LUTOUT26 0x04000000
+#define BF_PXP_WFE_A_STG2_5X1_OUT3_LUTOUT26(v) \
+ (((v) << 26) & BM_PXP_WFE_A_STG2_5X1_OUT3_LUTOUT26)
+#define BM_PXP_WFE_A_STG2_5X1_OUT3_LUTOUT25 0x02000000
+#define BF_PXP_WFE_A_STG2_5X1_OUT3_LUTOUT25(v) \
+ (((v) << 25) & BM_PXP_WFE_A_STG2_5X1_OUT3_LUTOUT25)
+#define BM_PXP_WFE_A_STG2_5X1_OUT3_LUTOUT24 0x01000000
+#define BF_PXP_WFE_A_STG2_5X1_OUT3_LUTOUT24(v) \
+ (((v) << 24) & BM_PXP_WFE_A_STG2_5X1_OUT3_LUTOUT24)
+#define BM_PXP_WFE_A_STG2_5X1_OUT3_LUTOUT23 0x00800000
+#define BF_PXP_WFE_A_STG2_5X1_OUT3_LUTOUT23(v) \
+ (((v) << 23) & BM_PXP_WFE_A_STG2_5X1_OUT3_LUTOUT23)
+#define BM_PXP_WFE_A_STG2_5X1_OUT3_LUTOUT22 0x00400000
+#define BF_PXP_WFE_A_STG2_5X1_OUT3_LUTOUT22(v) \
+ (((v) << 22) & BM_PXP_WFE_A_STG2_5X1_OUT3_LUTOUT22)
+#define BM_PXP_WFE_A_STG2_5X1_OUT3_LUTOUT21 0x00200000
+#define BF_PXP_WFE_A_STG2_5X1_OUT3_LUTOUT21(v) \
+ (((v) << 21) & BM_PXP_WFE_A_STG2_5X1_OUT3_LUTOUT21)
+#define BM_PXP_WFE_A_STG2_5X1_OUT3_LUTOUT20 0x00100000
+#define BF_PXP_WFE_A_STG2_5X1_OUT3_LUTOUT20(v) \
+ (((v) << 20) & BM_PXP_WFE_A_STG2_5X1_OUT3_LUTOUT20)
+#define BM_PXP_WFE_A_STG2_5X1_OUT3_LUTOUT19 0x00080000
+#define BF_PXP_WFE_A_STG2_5X1_OUT3_LUTOUT19(v) \
+ (((v) << 19) & BM_PXP_WFE_A_STG2_5X1_OUT3_LUTOUT19)
+#define BM_PXP_WFE_A_STG2_5X1_OUT3_LUTOUT18 0x00040000
+#define BF_PXP_WFE_A_STG2_5X1_OUT3_LUTOUT18(v) \
+ (((v) << 18) & BM_PXP_WFE_A_STG2_5X1_OUT3_LUTOUT18)
+#define BM_PXP_WFE_A_STG2_5X1_OUT3_LUTOUT17 0x00020000
+#define BF_PXP_WFE_A_STG2_5X1_OUT3_LUTOUT17(v) \
+ (((v) << 17) & BM_PXP_WFE_A_STG2_5X1_OUT3_LUTOUT17)
+#define BM_PXP_WFE_A_STG2_5X1_OUT3_LUTOUT16 0x00010000
+#define BF_PXP_WFE_A_STG2_5X1_OUT3_LUTOUT16(v) \
+ (((v) << 16) & BM_PXP_WFE_A_STG2_5X1_OUT3_LUTOUT16)
+#define BM_PXP_WFE_A_STG2_5X1_OUT3_LUTOUT15 0x00008000
+#define BF_PXP_WFE_A_STG2_5X1_OUT3_LUTOUT15(v) \
+ (((v) << 15) & BM_PXP_WFE_A_STG2_5X1_OUT3_LUTOUT15)
+#define BM_PXP_WFE_A_STG2_5X1_OUT3_LUTOUT14 0x00004000
+#define BF_PXP_WFE_A_STG2_5X1_OUT3_LUTOUT14(v) \
+ (((v) << 14) & BM_PXP_WFE_A_STG2_5X1_OUT3_LUTOUT14)
+#define BM_PXP_WFE_A_STG2_5X1_OUT3_LUTOUT13 0x00002000
+#define BF_PXP_WFE_A_STG2_5X1_OUT3_LUTOUT13(v) \
+ (((v) << 13) & BM_PXP_WFE_A_STG2_5X1_OUT3_LUTOUT13)
+#define BM_PXP_WFE_A_STG2_5X1_OUT3_LUTOUT12 0x00001000
+#define BF_PXP_WFE_A_STG2_5X1_OUT3_LUTOUT12(v) \
+ (((v) << 12) & BM_PXP_WFE_A_STG2_5X1_OUT3_LUTOUT12)
+#define BM_PXP_WFE_A_STG2_5X1_OUT3_LUTOUT11 0x00000800
+#define BF_PXP_WFE_A_STG2_5X1_OUT3_LUTOUT11(v) \
+ (((v) << 11) & BM_PXP_WFE_A_STG2_5X1_OUT3_LUTOUT11)
+#define BM_PXP_WFE_A_STG2_5X1_OUT3_LUTOUT10 0x00000400
+#define BF_PXP_WFE_A_STG2_5X1_OUT3_LUTOUT10(v) \
+ (((v) << 10) & BM_PXP_WFE_A_STG2_5X1_OUT3_LUTOUT10)
+#define BM_PXP_WFE_A_STG2_5X1_OUT3_LUTOUT9 0x00000200
+#define BF_PXP_WFE_A_STG2_5X1_OUT3_LUTOUT9(v) \
+ (((v) << 9) & BM_PXP_WFE_A_STG2_5X1_OUT3_LUTOUT9)
+#define BM_PXP_WFE_A_STG2_5X1_OUT3_LUTOUT8 0x00000100
+#define BF_PXP_WFE_A_STG2_5X1_OUT3_LUTOUT8(v) \
+ (((v) << 8) & BM_PXP_WFE_A_STG2_5X1_OUT3_LUTOUT8)
+#define BM_PXP_WFE_A_STG2_5X1_OUT3_LUTOUT7 0x00000080
+#define BF_PXP_WFE_A_STG2_5X1_OUT3_LUTOUT7(v) \
+ (((v) << 7) & BM_PXP_WFE_A_STG2_5X1_OUT3_LUTOUT7)
+#define BM_PXP_WFE_A_STG2_5X1_OUT3_LUTOUT6 0x00000040
+#define BF_PXP_WFE_A_STG2_5X1_OUT3_LUTOUT6(v) \
+ (((v) << 6) & BM_PXP_WFE_A_STG2_5X1_OUT3_LUTOUT6)
+#define BM_PXP_WFE_A_STG2_5X1_OUT3_LUTOUT5 0x00000020
+#define BF_PXP_WFE_A_STG2_5X1_OUT3_LUTOUT5(v) \
+ (((v) << 5) & BM_PXP_WFE_A_STG2_5X1_OUT3_LUTOUT5)
+#define BM_PXP_WFE_A_STG2_5X1_OUT3_LUTOUT4 0x00000010
+#define BF_PXP_WFE_A_STG2_5X1_OUT3_LUTOUT4(v) \
+ (((v) << 4) & BM_PXP_WFE_A_STG2_5X1_OUT3_LUTOUT4)
+#define BM_PXP_WFE_A_STG2_5X1_OUT3_LUTOUT3 0x00000008
+#define BF_PXP_WFE_A_STG2_5X1_OUT3_LUTOUT3(v) \
+ (((v) << 3) & BM_PXP_WFE_A_STG2_5X1_OUT3_LUTOUT3)
+#define BM_PXP_WFE_A_STG2_5X1_OUT3_LUTOUT2 0x00000004
+#define BF_PXP_WFE_A_STG2_5X1_OUT3_LUTOUT2(v) \
+ (((v) << 2) & BM_PXP_WFE_A_STG2_5X1_OUT3_LUTOUT2)
+#define BM_PXP_WFE_A_STG2_5X1_OUT3_LUTOUT1 0x00000002
+#define BF_PXP_WFE_A_STG2_5X1_OUT3_LUTOUT1(v) \
+ (((v) << 1) & BM_PXP_WFE_A_STG2_5X1_OUT3_LUTOUT1)
+#define BM_PXP_WFE_A_STG2_5X1_OUT3_LUTOUT0 0x00000001
+#define BF_PXP_WFE_A_STG2_5X1_OUT3_LUTOUT0(v) \
+ (((v) << 0) & BM_PXP_WFE_A_STG2_5X1_OUT3_LUTOUT0)
+
+#define HW_PXP_WFE_A_STG2_5X1_MASKS (0x00001cd0)
+
+#define BP_PXP_WFE_A_STG2_5X1_MASKS_RSVD3 29
+#define BM_PXP_WFE_A_STG2_5X1_MASKS_RSVD3 0xE0000000
+#define BF_PXP_WFE_A_STG2_5X1_MASKS_RSVD3(v) \
+ (((v) << 29) & BM_PXP_WFE_A_STG2_5X1_MASKS_RSVD3)
+#define BP_PXP_WFE_A_STG2_5X1_MASKS_MASK3 24
+#define BM_PXP_WFE_A_STG2_5X1_MASKS_MASK3 0x1F000000
+#define BF_PXP_WFE_A_STG2_5X1_MASKS_MASK3(v) \
+ (((v) << 24) & BM_PXP_WFE_A_STG2_5X1_MASKS_MASK3)
+#define BP_PXP_WFE_A_STG2_5X1_MASKS_RSVD2 21
+#define BM_PXP_WFE_A_STG2_5X1_MASKS_RSVD2 0x00E00000
+#define BF_PXP_WFE_A_STG2_5X1_MASKS_RSVD2(v) \
+ (((v) << 21) & BM_PXP_WFE_A_STG2_5X1_MASKS_RSVD2)
+#define BP_PXP_WFE_A_STG2_5X1_MASKS_MASK2 16
+#define BM_PXP_WFE_A_STG2_5X1_MASKS_MASK2 0x001F0000
+#define BF_PXP_WFE_A_STG2_5X1_MASKS_MASK2(v) \
+ (((v) << 16) & BM_PXP_WFE_A_STG2_5X1_MASKS_MASK2)
+#define BP_PXP_WFE_A_STG2_5X1_MASKS_RSVD1 13
+#define BM_PXP_WFE_A_STG2_5X1_MASKS_RSVD1 0x0000E000
+#define BF_PXP_WFE_A_STG2_5X1_MASKS_RSVD1(v) \
+ (((v) << 13) & BM_PXP_WFE_A_STG2_5X1_MASKS_RSVD1)
+#define BP_PXP_WFE_A_STG2_5X1_MASKS_MASK1 8
+#define BM_PXP_WFE_A_STG2_5X1_MASKS_MASK1 0x00001F00
+#define BF_PXP_WFE_A_STG2_5X1_MASKS_MASK1(v) \
+ (((v) << 8) & BM_PXP_WFE_A_STG2_5X1_MASKS_MASK1)
+#define BP_PXP_WFE_A_STG2_5X1_MASKS_RSVD0 5
+#define BM_PXP_WFE_A_STG2_5X1_MASKS_RSVD0 0x000000E0
+#define BF_PXP_WFE_A_STG2_5X1_MASKS_RSVD0(v) \
+ (((v) << 5) & BM_PXP_WFE_A_STG2_5X1_MASKS_RSVD0)
+#define BP_PXP_WFE_A_STG2_5X1_MASKS_MASK0 0
+#define BM_PXP_WFE_A_STG2_5X1_MASKS_MASK0 0x0000001F
+#define BF_PXP_WFE_A_STG2_5X1_MASKS_MASK0(v) \
+ (((v) << 0) & BM_PXP_WFE_A_STG2_5X1_MASKS_MASK0)
+
+#define HW_PXP_WFE_B_CTRL (0x00001d00)
+#define HW_PXP_WFE_B_CTRL_SET (0x00001d04)
+#define HW_PXP_WFE_B_CTRL_CLR (0x00001d08)
+#define HW_PXP_WFE_B_CTRL_TOG (0x00001d0c)
+
+#define BM_PXP_WFE_B_CTRL_DONE 0x80000000
+#define BF_PXP_WFE_B_CTRL_DONE(v) \
+ (((v) << 31) & BM_PXP_WFE_B_CTRL_DONE)
+#define BP_PXP_WFE_B_CTRL_RSVD0 3
+#define BM_PXP_WFE_B_CTRL_RSVD0 0x7FFFFFF8
+#define BF_PXP_WFE_B_CTRL_RSVD0(v) \
+ (((v) << 3) & BM_PXP_WFE_B_CTRL_RSVD0)
+#define BM_PXP_WFE_B_CTRL_SW_RESET 0x00000004
+#define BF_PXP_WFE_B_CTRL_SW_RESET(v) \
+ (((v) << 2) & BM_PXP_WFE_B_CTRL_SW_RESET)
+#define BM_PXP_WFE_B_CTRL_RSVD1 0x00000002
+#define BF_PXP_WFE_B_CTRL_RSVD1(v) \
+ (((v) << 1) & BM_PXP_WFE_B_CTRL_RSVD1)
+#define BM_PXP_WFE_B_CTRL_ENABLE 0x00000001
+#define BF_PXP_WFE_B_CTRL_ENABLE(v) \
+ (((v) << 0) & BM_PXP_WFE_B_CTRL_ENABLE)
+#define BV_PXP_WFE_B_CTRL_ENABLE__0 0x0
+#define BV_PXP_WFE_B_CTRL_ENABLE__1 0x1
+
+#define HW_PXP_WFE_B_DIMENSIONS (0x00001d10)
+
+#define BP_PXP_WFE_B_DIMENSIONS_RSVD0 28
+#define BM_PXP_WFE_B_DIMENSIONS_RSVD0 0xF0000000
+#define BF_PXP_WFE_B_DIMENSIONS_RSVD0(v) \
+ (((v) << 28) & BM_PXP_WFE_B_DIMENSIONS_RSVD0)
+#define BP_PXP_WFE_B_DIMENSIONS_HEIGHT 16
+#define BM_PXP_WFE_B_DIMENSIONS_HEIGHT 0x0FFF0000
+#define BF_PXP_WFE_B_DIMENSIONS_HEIGHT(v) \
+ (((v) << 16) & BM_PXP_WFE_B_DIMENSIONS_HEIGHT)
+#define BP_PXP_WFE_B_DIMENSIONS_RSVD1 12
+#define BM_PXP_WFE_B_DIMENSIONS_RSVD1 0x0000F000
+#define BF_PXP_WFE_B_DIMENSIONS_RSVD1(v) \
+ (((v) << 12) & BM_PXP_WFE_B_DIMENSIONS_RSVD1)
+#define BP_PXP_WFE_B_DIMENSIONS_WIDTH 0
+#define BM_PXP_WFE_B_DIMENSIONS_WIDTH 0x00000FFF
+#define BF_PXP_WFE_B_DIMENSIONS_WIDTH(v) \
+ (((v) << 0) & BM_PXP_WFE_B_DIMENSIONS_WIDTH)
+
+#define HW_PXP_WFE_B_OFFSET (0x00001d20)
+
+#define BP_PXP_WFE_B_OFFSET_RSVD0 28
+#define BM_PXP_WFE_B_OFFSET_RSVD0 0xF0000000
+#define BF_PXP_WFE_B_OFFSET_RSVD0(v) \
+ (((v) << 28) & BM_PXP_WFE_B_OFFSET_RSVD0)
+#define BP_PXP_WFE_B_OFFSET_Y_OFFSET 16
+#define BM_PXP_WFE_B_OFFSET_Y_OFFSET 0x0FFF0000
+#define BF_PXP_WFE_B_OFFSET_Y_OFFSET(v) \
+ (((v) << 16) & BM_PXP_WFE_B_OFFSET_Y_OFFSET)
+#define BP_PXP_WFE_B_OFFSET_RSVD1 12
+#define BM_PXP_WFE_B_OFFSET_RSVD1 0x0000F000
+#define BF_PXP_WFE_B_OFFSET_RSVD1(v) \
+ (((v) << 12) & BM_PXP_WFE_B_OFFSET_RSVD1)
+#define BP_PXP_WFE_B_OFFSET_X_OFFSET 0
+#define BM_PXP_WFE_B_OFFSET_X_OFFSET 0x00000FFF
+#define BF_PXP_WFE_B_OFFSET_X_OFFSET(v) \
+ (((v) << 0) & BM_PXP_WFE_B_OFFSET_X_OFFSET)
+
+#define HW_PXP_WFE_B_SW_DATA_REGS (0x00001d30)
+
+#define BP_PXP_WFE_B_SW_DATA_REGS_VAL3 24
+#define BM_PXP_WFE_B_SW_DATA_REGS_VAL3 0xFF000000
+#define BF_PXP_WFE_B_SW_DATA_REGS_VAL3(v) \
+ (((v) << 24) & BM_PXP_WFE_B_SW_DATA_REGS_VAL3)
+#define BP_PXP_WFE_B_SW_DATA_REGS_VAL2 16
+#define BM_PXP_WFE_B_SW_DATA_REGS_VAL2 0x00FF0000
+#define BF_PXP_WFE_B_SW_DATA_REGS_VAL2(v) \
+ (((v) << 16) & BM_PXP_WFE_B_SW_DATA_REGS_VAL2)
+#define BP_PXP_WFE_B_SW_DATA_REGS_VAL1 8
+#define BM_PXP_WFE_B_SW_DATA_REGS_VAL1 0x0000FF00
+#define BF_PXP_WFE_B_SW_DATA_REGS_VAL1(v) \
+ (((v) << 8) & BM_PXP_WFE_B_SW_DATA_REGS_VAL1)
+#define BP_PXP_WFE_B_SW_DATA_REGS_VAL0 0
+#define BM_PXP_WFE_B_SW_DATA_REGS_VAL0 0x000000FF
+#define BF_PXP_WFE_B_SW_DATA_REGS_VAL0(v) \
+ (((v) << 0) & BM_PXP_WFE_B_SW_DATA_REGS_VAL0)
+
+#define HW_PXP_WFE_B_SW_FLAG_REGS (0x00001d40)
+
+#define BP_PXP_WFE_B_SW_FLAG_REGS_RSVD 4
+#define BM_PXP_WFE_B_SW_FLAG_REGS_RSVD 0xFFFFFFF0
+#define BF_PXP_WFE_B_SW_FLAG_REGS_RSVD(v) \
+ (((v) << 4) & BM_PXP_WFE_B_SW_FLAG_REGS_RSVD)
+#define BM_PXP_WFE_B_SW_FLAG_REGS_VAL3 0x00000008
+#define BF_PXP_WFE_B_SW_FLAG_REGS_VAL3(v) \
+ (((v) << 3) & BM_PXP_WFE_B_SW_FLAG_REGS_VAL3)
+#define BM_PXP_WFE_B_SW_FLAG_REGS_VAL2 0x00000004
+#define BF_PXP_WFE_B_SW_FLAG_REGS_VAL2(v) \
+ (((v) << 2) & BM_PXP_WFE_B_SW_FLAG_REGS_VAL2)
+#define BM_PXP_WFE_B_SW_FLAG_REGS_VAL1 0x00000002
+#define BF_PXP_WFE_B_SW_FLAG_REGS_VAL1(v) \
+ (((v) << 1) & BM_PXP_WFE_B_SW_FLAG_REGS_VAL1)
+#define BM_PXP_WFE_B_SW_FLAG_REGS_VAL0 0x00000001
+#define BF_PXP_WFE_B_SW_FLAG_REGS_VAL0(v) \
+ (((v) << 0) & BM_PXP_WFE_B_SW_FLAG_REGS_VAL0)
+
+#define HW_PXP_WFE_B_STAGE1_MUX0 (0x00001d50)
+#define HW_PXP_WFE_B_STAGE1_MUX0_SET (0x00001d54)
+#define HW_PXP_WFE_B_STAGE1_MUX0_CLR (0x00001d58)
+#define HW_PXP_WFE_B_STAGE1_MUX0_TOG (0x00001d5c)
+
+#define BP_PXP_WFE_B_STAGE1_MUX0_RSVD0 30
+#define BM_PXP_WFE_B_STAGE1_MUX0_RSVD0 0xC0000000
+#define BF_PXP_WFE_B_STAGE1_MUX0_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STAGE1_MUX0_RSVD0)
+#define BP_PXP_WFE_B_STAGE1_MUX0_MUX3 24
+#define BM_PXP_WFE_B_STAGE1_MUX0_MUX3 0x3F000000
+#define BF_PXP_WFE_B_STAGE1_MUX0_MUX3(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STAGE1_MUX0_MUX3)
+#define BP_PXP_WFE_B_STAGE1_MUX0_RSVD1 22
+#define BM_PXP_WFE_B_STAGE1_MUX0_RSVD1 0x00C00000
+#define BF_PXP_WFE_B_STAGE1_MUX0_RSVD1(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STAGE1_MUX0_RSVD1)
+#define BP_PXP_WFE_B_STAGE1_MUX0_MUX2 16
+#define BM_PXP_WFE_B_STAGE1_MUX0_MUX2 0x003F0000
+#define BF_PXP_WFE_B_STAGE1_MUX0_MUX2(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STAGE1_MUX0_MUX2)
+#define BP_PXP_WFE_B_STAGE1_MUX0_RSVD2 14
+#define BM_PXP_WFE_B_STAGE1_MUX0_RSVD2 0x0000C000
+#define BF_PXP_WFE_B_STAGE1_MUX0_RSVD2(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STAGE1_MUX0_RSVD2)
+#define BP_PXP_WFE_B_STAGE1_MUX0_MUX1 8
+#define BM_PXP_WFE_B_STAGE1_MUX0_MUX1 0x00003F00
+#define BF_PXP_WFE_B_STAGE1_MUX0_MUX1(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STAGE1_MUX0_MUX1)
+#define BP_PXP_WFE_B_STAGE1_MUX0_RSVD3 6
+#define BM_PXP_WFE_B_STAGE1_MUX0_RSVD3 0x000000C0
+#define BF_PXP_WFE_B_STAGE1_MUX0_RSVD3(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STAGE1_MUX0_RSVD3)
+#define BP_PXP_WFE_B_STAGE1_MUX0_MUX0 0
+#define BM_PXP_WFE_B_STAGE1_MUX0_MUX0 0x0000003F
+#define BF_PXP_WFE_B_STAGE1_MUX0_MUX0(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STAGE1_MUX0_MUX0)
+
+#define HW_PXP_WFE_B_STAGE1_MUX1 (0x00001d60)
+#define HW_PXP_WFE_B_STAGE1_MUX1_SET (0x00001d64)
+#define HW_PXP_WFE_B_STAGE1_MUX1_CLR (0x00001d68)
+#define HW_PXP_WFE_B_STAGE1_MUX1_TOG (0x00001d6c)
+
+#define BP_PXP_WFE_B_STAGE1_MUX1_RSVD0 30
+#define BM_PXP_WFE_B_STAGE1_MUX1_RSVD0 0xC0000000
+#define BF_PXP_WFE_B_STAGE1_MUX1_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STAGE1_MUX1_RSVD0)
+#define BP_PXP_WFE_B_STAGE1_MUX1_MUX7 24
+#define BM_PXP_WFE_B_STAGE1_MUX1_MUX7 0x3F000000
+#define BF_PXP_WFE_B_STAGE1_MUX1_MUX7(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STAGE1_MUX1_MUX7)
+#define BP_PXP_WFE_B_STAGE1_MUX1_RSVD1 22
+#define BM_PXP_WFE_B_STAGE1_MUX1_RSVD1 0x00C00000
+#define BF_PXP_WFE_B_STAGE1_MUX1_RSVD1(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STAGE1_MUX1_RSVD1)
+#define BP_PXP_WFE_B_STAGE1_MUX1_MUX6 16
+#define BM_PXP_WFE_B_STAGE1_MUX1_MUX6 0x003F0000
+#define BF_PXP_WFE_B_STAGE1_MUX1_MUX6(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STAGE1_MUX1_MUX6)
+#define BP_PXP_WFE_B_STAGE1_MUX1_RSVD2 14
+#define BM_PXP_WFE_B_STAGE1_MUX1_RSVD2 0x0000C000
+#define BF_PXP_WFE_B_STAGE1_MUX1_RSVD2(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STAGE1_MUX1_RSVD2)
+#define BP_PXP_WFE_B_STAGE1_MUX1_MUX5 8
+#define BM_PXP_WFE_B_STAGE1_MUX1_MUX5 0x00003F00
+#define BF_PXP_WFE_B_STAGE1_MUX1_MUX5(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STAGE1_MUX1_MUX5)
+#define BP_PXP_WFE_B_STAGE1_MUX1_RSVD3 6
+#define BM_PXP_WFE_B_STAGE1_MUX1_RSVD3 0x000000C0
+#define BF_PXP_WFE_B_STAGE1_MUX1_RSVD3(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STAGE1_MUX1_RSVD3)
+#define BP_PXP_WFE_B_STAGE1_MUX1_MUX4 0
+#define BM_PXP_WFE_B_STAGE1_MUX1_MUX4 0x0000003F
+#define BF_PXP_WFE_B_STAGE1_MUX1_MUX4(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STAGE1_MUX1_MUX4)
+
+#define HW_PXP_WFE_B_STAGE1_MUX2 (0x00001d70)
+#define HW_PXP_WFE_B_STAGE1_MUX2_SET (0x00001d74)
+#define HW_PXP_WFE_B_STAGE1_MUX2_CLR (0x00001d78)
+#define HW_PXP_WFE_B_STAGE1_MUX2_TOG (0x00001d7c)
+
+#define BP_PXP_WFE_B_STAGE1_MUX2_RSVD0 30
+#define BM_PXP_WFE_B_STAGE1_MUX2_RSVD0 0xC0000000
+#define BF_PXP_WFE_B_STAGE1_MUX2_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STAGE1_MUX2_RSVD0)
+#define BP_PXP_WFE_B_STAGE1_MUX2_MUX11 24
+#define BM_PXP_WFE_B_STAGE1_MUX2_MUX11 0x3F000000
+#define BF_PXP_WFE_B_STAGE1_MUX2_MUX11(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STAGE1_MUX2_MUX11)
+#define BP_PXP_WFE_B_STAGE1_MUX2_RSVD1 22
+#define BM_PXP_WFE_B_STAGE1_MUX2_RSVD1 0x00C00000
+#define BF_PXP_WFE_B_STAGE1_MUX2_RSVD1(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STAGE1_MUX2_RSVD1)
+#define BP_PXP_WFE_B_STAGE1_MUX2_MUX10 16
+#define BM_PXP_WFE_B_STAGE1_MUX2_MUX10 0x003F0000
+#define BF_PXP_WFE_B_STAGE1_MUX2_MUX10(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STAGE1_MUX2_MUX10)
+#define BP_PXP_WFE_B_STAGE1_MUX2_RSVD2 14
+#define BM_PXP_WFE_B_STAGE1_MUX2_RSVD2 0x0000C000
+#define BF_PXP_WFE_B_STAGE1_MUX2_RSVD2(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STAGE1_MUX2_RSVD2)
+#define BP_PXP_WFE_B_STAGE1_MUX2_MUX9 8
+#define BM_PXP_WFE_B_STAGE1_MUX2_MUX9 0x00003F00
+#define BF_PXP_WFE_B_STAGE1_MUX2_MUX9(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STAGE1_MUX2_MUX9)
+#define BP_PXP_WFE_B_STAGE1_MUX2_RSVD3 6
+#define BM_PXP_WFE_B_STAGE1_MUX2_RSVD3 0x000000C0
+#define BF_PXP_WFE_B_STAGE1_MUX2_RSVD3(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STAGE1_MUX2_RSVD3)
+#define BP_PXP_WFE_B_STAGE1_MUX2_MUX8 0
+#define BM_PXP_WFE_B_STAGE1_MUX2_MUX8 0x0000003F
+#define BF_PXP_WFE_B_STAGE1_MUX2_MUX8(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STAGE1_MUX2_MUX8)
+
+#define HW_PXP_WFE_B_STAGE1_MUX3 (0x00001d80)
+#define HW_PXP_WFE_B_STAGE1_MUX3_SET (0x00001d84)
+#define HW_PXP_WFE_B_STAGE1_MUX3_CLR (0x00001d88)
+#define HW_PXP_WFE_B_STAGE1_MUX3_TOG (0x00001d8c)
+
+#define BP_PXP_WFE_B_STAGE1_MUX3_RSVD0 30
+#define BM_PXP_WFE_B_STAGE1_MUX3_RSVD0 0xC0000000
+#define BF_PXP_WFE_B_STAGE1_MUX3_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STAGE1_MUX3_RSVD0)
+#define BP_PXP_WFE_B_STAGE1_MUX3_MUX15 24
+#define BM_PXP_WFE_B_STAGE1_MUX3_MUX15 0x3F000000
+#define BF_PXP_WFE_B_STAGE1_MUX3_MUX15(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STAGE1_MUX3_MUX15)
+#define BP_PXP_WFE_B_STAGE1_MUX3_RSVD1 22
+#define BM_PXP_WFE_B_STAGE1_MUX3_RSVD1 0x00C00000
+#define BF_PXP_WFE_B_STAGE1_MUX3_RSVD1(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STAGE1_MUX3_RSVD1)
+#define BP_PXP_WFE_B_STAGE1_MUX3_MUX14 16
+#define BM_PXP_WFE_B_STAGE1_MUX3_MUX14 0x003F0000
+#define BF_PXP_WFE_B_STAGE1_MUX3_MUX14(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STAGE1_MUX3_MUX14)
+#define BP_PXP_WFE_B_STAGE1_MUX3_RSVD2 14
+#define BM_PXP_WFE_B_STAGE1_MUX3_RSVD2 0x0000C000
+#define BF_PXP_WFE_B_STAGE1_MUX3_RSVD2(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STAGE1_MUX3_RSVD2)
+#define BP_PXP_WFE_B_STAGE1_MUX3_MUX13 8
+#define BM_PXP_WFE_B_STAGE1_MUX3_MUX13 0x00003F00
+#define BF_PXP_WFE_B_STAGE1_MUX3_MUX13(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STAGE1_MUX3_MUX13)
+#define BP_PXP_WFE_B_STAGE1_MUX3_RSVD3 6
+#define BM_PXP_WFE_B_STAGE1_MUX3_RSVD3 0x000000C0
+#define BF_PXP_WFE_B_STAGE1_MUX3_RSVD3(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STAGE1_MUX3_RSVD3)
+#define BP_PXP_WFE_B_STAGE1_MUX3_MUX12 0
+#define BM_PXP_WFE_B_STAGE1_MUX3_MUX12 0x0000003F
+#define BF_PXP_WFE_B_STAGE1_MUX3_MUX12(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STAGE1_MUX3_MUX12)
+
+#define HW_PXP_WFE_B_STAGE1_MUX4 (0x00001d90)
+#define HW_PXP_WFE_B_STAGE1_MUX4_SET (0x00001d94)
+#define HW_PXP_WFE_B_STAGE1_MUX4_CLR (0x00001d98)
+#define HW_PXP_WFE_B_STAGE1_MUX4_TOG (0x00001d9c)
+
+#define BP_PXP_WFE_B_STAGE1_MUX4_RSVD0 30
+#define BM_PXP_WFE_B_STAGE1_MUX4_RSVD0 0xC0000000
+#define BF_PXP_WFE_B_STAGE1_MUX4_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STAGE1_MUX4_RSVD0)
+#define BP_PXP_WFE_B_STAGE1_MUX4_MUX19 24
+#define BM_PXP_WFE_B_STAGE1_MUX4_MUX19 0x3F000000
+#define BF_PXP_WFE_B_STAGE1_MUX4_MUX19(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STAGE1_MUX4_MUX19)
+#define BP_PXP_WFE_B_STAGE1_MUX4_RSVD1 22
+#define BM_PXP_WFE_B_STAGE1_MUX4_RSVD1 0x00C00000
+#define BF_PXP_WFE_B_STAGE1_MUX4_RSVD1(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STAGE1_MUX4_RSVD1)
+#define BP_PXP_WFE_B_STAGE1_MUX4_MUX18 16
+#define BM_PXP_WFE_B_STAGE1_MUX4_MUX18 0x003F0000
+#define BF_PXP_WFE_B_STAGE1_MUX4_MUX18(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STAGE1_MUX4_MUX18)
+#define BP_PXP_WFE_B_STAGE1_MUX4_RSVD2 14
+#define BM_PXP_WFE_B_STAGE1_MUX4_RSVD2 0x0000C000
+#define BF_PXP_WFE_B_STAGE1_MUX4_RSVD2(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STAGE1_MUX4_RSVD2)
+#define BP_PXP_WFE_B_STAGE1_MUX4_MUX17 8
+#define BM_PXP_WFE_B_STAGE1_MUX4_MUX17 0x00003F00
+#define BF_PXP_WFE_B_STAGE1_MUX4_MUX17(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STAGE1_MUX4_MUX17)
+#define BP_PXP_WFE_B_STAGE1_MUX4_RSVD3 6
+#define BM_PXP_WFE_B_STAGE1_MUX4_RSVD3 0x000000C0
+#define BF_PXP_WFE_B_STAGE1_MUX4_RSVD3(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STAGE1_MUX4_RSVD3)
+#define BP_PXP_WFE_B_STAGE1_MUX4_MUX16 0
+#define BM_PXP_WFE_B_STAGE1_MUX4_MUX16 0x0000003F
+#define BF_PXP_WFE_B_STAGE1_MUX4_MUX16(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STAGE1_MUX4_MUX16)
+
+#define HW_PXP_WFE_B_STAGE1_MUX5 (0x00001da0)
+#define HW_PXP_WFE_B_STAGE1_MUX5_SET (0x00001da4)
+#define HW_PXP_WFE_B_STAGE1_MUX5_CLR (0x00001da8)
+#define HW_PXP_WFE_B_STAGE1_MUX5_TOG (0x00001dac)
+
+#define BP_PXP_WFE_B_STAGE1_MUX5_RSVD0 30
+#define BM_PXP_WFE_B_STAGE1_MUX5_RSVD0 0xC0000000
+#define BF_PXP_WFE_B_STAGE1_MUX5_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STAGE1_MUX5_RSVD0)
+#define BP_PXP_WFE_B_STAGE1_MUX5_MUX23 24
+#define BM_PXP_WFE_B_STAGE1_MUX5_MUX23 0x3F000000
+#define BF_PXP_WFE_B_STAGE1_MUX5_MUX23(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STAGE1_MUX5_MUX23)
+#define BP_PXP_WFE_B_STAGE1_MUX5_RSVD1 22
+#define BM_PXP_WFE_B_STAGE1_MUX5_RSVD1 0x00C00000
+#define BF_PXP_WFE_B_STAGE1_MUX5_RSVD1(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STAGE1_MUX5_RSVD1)
+#define BP_PXP_WFE_B_STAGE1_MUX5_MUX22 16
+#define BM_PXP_WFE_B_STAGE1_MUX5_MUX22 0x003F0000
+#define BF_PXP_WFE_B_STAGE1_MUX5_MUX22(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STAGE1_MUX5_MUX22)
+#define BP_PXP_WFE_B_STAGE1_MUX5_RSVD2 14
+#define BM_PXP_WFE_B_STAGE1_MUX5_RSVD2 0x0000C000
+#define BF_PXP_WFE_B_STAGE1_MUX5_RSVD2(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STAGE1_MUX5_RSVD2)
+#define BP_PXP_WFE_B_STAGE1_MUX5_MUX21 8
+#define BM_PXP_WFE_B_STAGE1_MUX5_MUX21 0x00003F00
+#define BF_PXP_WFE_B_STAGE1_MUX5_MUX21(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STAGE1_MUX5_MUX21)
+#define BP_PXP_WFE_B_STAGE1_MUX5_RSVD3 6
+#define BM_PXP_WFE_B_STAGE1_MUX5_RSVD3 0x000000C0
+#define BF_PXP_WFE_B_STAGE1_MUX5_RSVD3(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STAGE1_MUX5_RSVD3)
+#define BP_PXP_WFE_B_STAGE1_MUX5_MUX20 0
+#define BM_PXP_WFE_B_STAGE1_MUX5_MUX20 0x0000003F
+#define BF_PXP_WFE_B_STAGE1_MUX5_MUX20(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STAGE1_MUX5_MUX20)
+#define BV_PXP_WFE_B_STAGE1_MUX5_MUX20__INC 0x0
+#define BV_PXP_WFE_B_STAGE1_MUX5_MUX20__DEC 0x1
+#define BV_PXP_WFE_B_STAGE1_MUX5_MUX20__ADD 0x2
+#define BV_PXP_WFE_B_STAGE1_MUX5_MUX20__MINUS 0x3
+#define BV_PXP_WFE_B_STAGE1_MUX5_MUX20__AND 0x4
+#define BV_PXP_WFE_B_STAGE1_MUX5_MUX20__OR 0x5
+#define BV_PXP_WFE_B_STAGE1_MUX5_MUX20__XOR 0x6
+#define BV_PXP_WFE_B_STAGE1_MUX5_MUX20__SHIFTLEFT 0x7
+#define BV_PXP_WFE_B_STAGE1_MUX5_MUX20__SHIFTRIGHT 0x8
+#define BV_PXP_WFE_B_STAGE1_MUX5_MUX20__BIT_AND 0x9
+#define BV_PXP_WFE_B_STAGE1_MUX5_MUX20__BIT_OR 0xa
+#define BV_PXP_WFE_B_STAGE1_MUX5_MUX20__BIT_CMP 0xb
+#define BV_PXP_WFE_B_STAGE1_MUX5_MUX20__NOP 0xc
+
+#define HW_PXP_WFE_B_STAGE1_MUX6 (0x00001db0)
+#define HW_PXP_WFE_B_STAGE1_MUX6_SET (0x00001db4)
+#define HW_PXP_WFE_B_STAGE1_MUX6_CLR (0x00001db8)
+#define HW_PXP_WFE_B_STAGE1_MUX6_TOG (0x00001dbc)
+
+#define BP_PXP_WFE_B_STAGE1_MUX6_RSVD0 30
+#define BM_PXP_WFE_B_STAGE1_MUX6_RSVD0 0xC0000000
+#define BF_PXP_WFE_B_STAGE1_MUX6_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STAGE1_MUX6_RSVD0)
+#define BP_PXP_WFE_B_STAGE1_MUX6_MUX27 24
+#define BM_PXP_WFE_B_STAGE1_MUX6_MUX27 0x3F000000
+#define BF_PXP_WFE_B_STAGE1_MUX6_MUX27(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STAGE1_MUX6_MUX27)
+#define BP_PXP_WFE_B_STAGE1_MUX6_RSVD1 22
+#define BM_PXP_WFE_B_STAGE1_MUX6_RSVD1 0x00C00000
+#define BF_PXP_WFE_B_STAGE1_MUX6_RSVD1(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STAGE1_MUX6_RSVD1)
+#define BP_PXP_WFE_B_STAGE1_MUX6_MUX26 16
+#define BM_PXP_WFE_B_STAGE1_MUX6_MUX26 0x003F0000
+#define BF_PXP_WFE_B_STAGE1_MUX6_MUX26(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STAGE1_MUX6_MUX26)
+#define BP_PXP_WFE_B_STAGE1_MUX6_RSVD2 14
+#define BM_PXP_WFE_B_STAGE1_MUX6_RSVD2 0x0000C000
+#define BF_PXP_WFE_B_STAGE1_MUX6_RSVD2(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STAGE1_MUX6_RSVD2)
+#define BP_PXP_WFE_B_STAGE1_MUX6_MUX25 8
+#define BM_PXP_WFE_B_STAGE1_MUX6_MUX25 0x00003F00
+#define BF_PXP_WFE_B_STAGE1_MUX6_MUX25(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STAGE1_MUX6_MUX25)
+#define BP_PXP_WFE_B_STAGE1_MUX6_RSVD3 6
+#define BM_PXP_WFE_B_STAGE1_MUX6_RSVD3 0x000000C0
+#define BF_PXP_WFE_B_STAGE1_MUX6_RSVD3(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STAGE1_MUX6_RSVD3)
+#define BP_PXP_WFE_B_STAGE1_MUX6_MUX24 0
+#define BM_PXP_WFE_B_STAGE1_MUX6_MUX24 0x0000003F
+#define BF_PXP_WFE_B_STAGE1_MUX6_MUX24(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STAGE1_MUX6_MUX24)
+
+#define HW_PXP_WFE_B_STAGE1_MUX7 (0x00001dc0)
+#define HW_PXP_WFE_B_STAGE1_MUX7_SET (0x00001dc4)
+#define HW_PXP_WFE_B_STAGE1_MUX7_CLR (0x00001dc8)
+#define HW_PXP_WFE_B_STAGE1_MUX7_TOG (0x00001dcc)
+
+#define BP_PXP_WFE_B_STAGE1_MUX7_RSVD0 30
+#define BM_PXP_WFE_B_STAGE1_MUX7_RSVD0 0xC0000000
+#define BF_PXP_WFE_B_STAGE1_MUX7_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STAGE1_MUX7_RSVD0)
+#define BP_PXP_WFE_B_STAGE1_MUX7_MUX31 24
+#define BM_PXP_WFE_B_STAGE1_MUX7_MUX31 0x3F000000
+#define BF_PXP_WFE_B_STAGE1_MUX7_MUX31(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STAGE1_MUX7_MUX31)
+#define BP_PXP_WFE_B_STAGE1_MUX7_RSVD1 22
+#define BM_PXP_WFE_B_STAGE1_MUX7_RSVD1 0x00C00000
+#define BF_PXP_WFE_B_STAGE1_MUX7_RSVD1(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STAGE1_MUX7_RSVD1)
+#define BP_PXP_WFE_B_STAGE1_MUX7_MUX30 16
+#define BM_PXP_WFE_B_STAGE1_MUX7_MUX30 0x003F0000
+#define BF_PXP_WFE_B_STAGE1_MUX7_MUX30(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STAGE1_MUX7_MUX30)
+#define BP_PXP_WFE_B_STAGE1_MUX7_RSVD2 14
+#define BM_PXP_WFE_B_STAGE1_MUX7_RSVD2 0x0000C000
+#define BF_PXP_WFE_B_STAGE1_MUX7_RSVD2(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STAGE1_MUX7_RSVD2)
+#define BP_PXP_WFE_B_STAGE1_MUX7_MUX29 8
+#define BM_PXP_WFE_B_STAGE1_MUX7_MUX29 0x00003F00
+#define BF_PXP_WFE_B_STAGE1_MUX7_MUX29(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STAGE1_MUX7_MUX29)
+#define BP_PXP_WFE_B_STAGE1_MUX7_RSVD3 6
+#define BM_PXP_WFE_B_STAGE1_MUX7_RSVD3 0x000000C0
+#define BF_PXP_WFE_B_STAGE1_MUX7_RSVD3(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STAGE1_MUX7_RSVD3)
+#define BP_PXP_WFE_B_STAGE1_MUX7_MUX28 0
+#define BM_PXP_WFE_B_STAGE1_MUX7_MUX28 0x0000003F
+#define BF_PXP_WFE_B_STAGE1_MUX7_MUX28(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STAGE1_MUX7_MUX28)
+
+#define HW_PXP_WFE_B_STAGE1_MUX8 (0x00001dd0)
+#define HW_PXP_WFE_B_STAGE1_MUX8_SET (0x00001dd4)
+#define HW_PXP_WFE_B_STAGE1_MUX8_CLR (0x00001dd8)
+#define HW_PXP_WFE_B_STAGE1_MUX8_TOG (0x00001ddc)
+
+#define BP_PXP_WFE_B_STAGE1_MUX8_RSVD0 6
+#define BM_PXP_WFE_B_STAGE1_MUX8_RSVD0 0xFFFFFFC0
+#define BF_PXP_WFE_B_STAGE1_MUX8_RSVD0(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STAGE1_MUX8_RSVD0)
+#define BP_PXP_WFE_B_STAGE1_MUX8_MUX32 0
+#define BM_PXP_WFE_B_STAGE1_MUX8_MUX32 0x0000003F
+#define BF_PXP_WFE_B_STAGE1_MUX8_MUX32(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STAGE1_MUX8_MUX32)
+
+#define HW_PXP_WFE_B_STAGE2_MUX0 (0x00001de0)
+#define HW_PXP_WFE_B_STAGE2_MUX0_SET (0x00001de4)
+#define HW_PXP_WFE_B_STAGE2_MUX0_CLR (0x00001de8)
+#define HW_PXP_WFE_B_STAGE2_MUX0_TOG (0x00001dec)
+
+#define BP_PXP_WFE_B_STAGE2_MUX0_RSVD0 30
+#define BM_PXP_WFE_B_STAGE2_MUX0_RSVD0 0xC0000000
+#define BF_PXP_WFE_B_STAGE2_MUX0_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STAGE2_MUX0_RSVD0)
+#define BP_PXP_WFE_B_STAGE2_MUX0_MUX3 24
+#define BM_PXP_WFE_B_STAGE2_MUX0_MUX3 0x3F000000
+#define BF_PXP_WFE_B_STAGE2_MUX0_MUX3(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STAGE2_MUX0_MUX3)
+#define BP_PXP_WFE_B_STAGE2_MUX0_RSVD1 22
+#define BM_PXP_WFE_B_STAGE2_MUX0_RSVD1 0x00C00000
+#define BF_PXP_WFE_B_STAGE2_MUX0_RSVD1(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STAGE2_MUX0_RSVD1)
+#define BP_PXP_WFE_B_STAGE2_MUX0_MUX2 16
+#define BM_PXP_WFE_B_STAGE2_MUX0_MUX2 0x003F0000
+#define BF_PXP_WFE_B_STAGE2_MUX0_MUX2(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STAGE2_MUX0_MUX2)
+#define BP_PXP_WFE_B_STAGE2_MUX0_RSVD2 14
+#define BM_PXP_WFE_B_STAGE2_MUX0_RSVD2 0x0000C000
+#define BF_PXP_WFE_B_STAGE2_MUX0_RSVD2(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STAGE2_MUX0_RSVD2)
+#define BP_PXP_WFE_B_STAGE2_MUX0_MUX1 8
+#define BM_PXP_WFE_B_STAGE2_MUX0_MUX1 0x00003F00
+#define BF_PXP_WFE_B_STAGE2_MUX0_MUX1(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STAGE2_MUX0_MUX1)
+#define BP_PXP_WFE_B_STAGE2_MUX0_RSVD3 6
+#define BM_PXP_WFE_B_STAGE2_MUX0_RSVD3 0x000000C0
+#define BF_PXP_WFE_B_STAGE2_MUX0_RSVD3(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STAGE2_MUX0_RSVD3)
+#define BP_PXP_WFE_B_STAGE2_MUX0_MUX0 0
+#define BM_PXP_WFE_B_STAGE2_MUX0_MUX0 0x0000003F
+#define BF_PXP_WFE_B_STAGE2_MUX0_MUX0(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STAGE2_MUX0_MUX0)
+
+#define HW_PXP_WFE_B_STAGE2_MUX1 (0x00001df0)
+#define HW_PXP_WFE_B_STAGE2_MUX1_SET (0x00001df4)
+#define HW_PXP_WFE_B_STAGE2_MUX1_CLR (0x00001df8)
+#define HW_PXP_WFE_B_STAGE2_MUX1_TOG (0x00001dfc)
+
+#define BP_PXP_WFE_B_STAGE2_MUX1_RSVD0 30
+#define BM_PXP_WFE_B_STAGE2_MUX1_RSVD0 0xC0000000
+#define BF_PXP_WFE_B_STAGE2_MUX1_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STAGE2_MUX1_RSVD0)
+#define BP_PXP_WFE_B_STAGE2_MUX1_MUX7 24
+#define BM_PXP_WFE_B_STAGE2_MUX1_MUX7 0x3F000000
+#define BF_PXP_WFE_B_STAGE2_MUX1_MUX7(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STAGE2_MUX1_MUX7)
+#define BP_PXP_WFE_B_STAGE2_MUX1_RSVD1 22
+#define BM_PXP_WFE_B_STAGE2_MUX1_RSVD1 0x00C00000
+#define BF_PXP_WFE_B_STAGE2_MUX1_RSVD1(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STAGE2_MUX1_RSVD1)
+#define BP_PXP_WFE_B_STAGE2_MUX1_MUX6 16
+#define BM_PXP_WFE_B_STAGE2_MUX1_MUX6 0x003F0000
+#define BF_PXP_WFE_B_STAGE2_MUX1_MUX6(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STAGE2_MUX1_MUX6)
+#define BP_PXP_WFE_B_STAGE2_MUX1_RSVD2 14
+#define BM_PXP_WFE_B_STAGE2_MUX1_RSVD2 0x0000C000
+#define BF_PXP_WFE_B_STAGE2_MUX1_RSVD2(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STAGE2_MUX1_RSVD2)
+#define BP_PXP_WFE_B_STAGE2_MUX1_MUX5 8
+#define BM_PXP_WFE_B_STAGE2_MUX1_MUX5 0x00003F00
+#define BF_PXP_WFE_B_STAGE2_MUX1_MUX5(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STAGE2_MUX1_MUX5)
+#define BP_PXP_WFE_B_STAGE2_MUX1_RSVD3 6
+#define BM_PXP_WFE_B_STAGE2_MUX1_RSVD3 0x000000C0
+#define BF_PXP_WFE_B_STAGE2_MUX1_RSVD3(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STAGE2_MUX1_RSVD3)
+#define BP_PXP_WFE_B_STAGE2_MUX1_MUX4 0
+#define BM_PXP_WFE_B_STAGE2_MUX1_MUX4 0x0000003F
+#define BF_PXP_WFE_B_STAGE2_MUX1_MUX4(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STAGE2_MUX1_MUX4)
+
+#define HW_PXP_WFE_B_STAGE2_MUX2 (0x00001e00)
+#define HW_PXP_WFE_B_STAGE2_MUX2_SET (0x00001e04)
+#define HW_PXP_WFE_B_STAGE2_MUX2_CLR (0x00001e08)
+#define HW_PXP_WFE_B_STAGE2_MUX2_TOG (0x00001e0c)
+
+#define BP_PXP_WFE_B_STAGE2_MUX2_RSVD0 30
+#define BM_PXP_WFE_B_STAGE2_MUX2_RSVD0 0xC0000000
+#define BF_PXP_WFE_B_STAGE2_MUX2_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STAGE2_MUX2_RSVD0)
+#define BP_PXP_WFE_B_STAGE2_MUX2_MUX11 24
+#define BM_PXP_WFE_B_STAGE2_MUX2_MUX11 0x3F000000
+#define BF_PXP_WFE_B_STAGE2_MUX2_MUX11(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STAGE2_MUX2_MUX11)
+#define BP_PXP_WFE_B_STAGE2_MUX2_RSVD1 22
+#define BM_PXP_WFE_B_STAGE2_MUX2_RSVD1 0x00C00000
+#define BF_PXP_WFE_B_STAGE2_MUX2_RSVD1(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STAGE2_MUX2_RSVD1)
+#define BP_PXP_WFE_B_STAGE2_MUX2_MUX10 16
+#define BM_PXP_WFE_B_STAGE2_MUX2_MUX10 0x003F0000
+#define BF_PXP_WFE_B_STAGE2_MUX2_MUX10(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STAGE2_MUX2_MUX10)
+#define BP_PXP_WFE_B_STAGE2_MUX2_RSVD2 14
+#define BM_PXP_WFE_B_STAGE2_MUX2_RSVD2 0x0000C000
+#define BF_PXP_WFE_B_STAGE2_MUX2_RSVD2(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STAGE2_MUX2_RSVD2)
+#define BP_PXP_WFE_B_STAGE2_MUX2_MUX9 8
+#define BM_PXP_WFE_B_STAGE2_MUX2_MUX9 0x00003F00
+#define BF_PXP_WFE_B_STAGE2_MUX2_MUX9(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STAGE2_MUX2_MUX9)
+#define BP_PXP_WFE_B_STAGE2_MUX2_RSVD3 6
+#define BM_PXP_WFE_B_STAGE2_MUX2_RSVD3 0x000000C0
+#define BF_PXP_WFE_B_STAGE2_MUX2_RSVD3(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STAGE2_MUX2_RSVD3)
+#define BP_PXP_WFE_B_STAGE2_MUX2_MUX8 0
+#define BM_PXP_WFE_B_STAGE2_MUX2_MUX8 0x0000003F
+#define BF_PXP_WFE_B_STAGE2_MUX2_MUX8(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STAGE2_MUX2_MUX8)
+
+#define HW_PXP_WFE_B_STAGE2_MUX3 (0x00001e10)
+#define HW_PXP_WFE_B_STAGE2_MUX3_SET (0x00001e14)
+#define HW_PXP_WFE_B_STAGE2_MUX3_CLR (0x00001e18)
+#define HW_PXP_WFE_B_STAGE2_MUX3_TOG (0x00001e1c)
+
+#define BP_PXP_WFE_B_STAGE2_MUX3_RSVD0 30
+#define BM_PXP_WFE_B_STAGE2_MUX3_RSVD0 0xC0000000
+#define BF_PXP_WFE_B_STAGE2_MUX3_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STAGE2_MUX3_RSVD0)
+#define BP_PXP_WFE_B_STAGE2_MUX3_MUX15 24
+#define BM_PXP_WFE_B_STAGE2_MUX3_MUX15 0x3F000000
+#define BF_PXP_WFE_B_STAGE2_MUX3_MUX15(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STAGE2_MUX3_MUX15)
+#define BP_PXP_WFE_B_STAGE2_MUX3_RSVD1 22
+#define BM_PXP_WFE_B_STAGE2_MUX3_RSVD1 0x00C00000
+#define BF_PXP_WFE_B_STAGE2_MUX3_RSVD1(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STAGE2_MUX3_RSVD1)
+#define BP_PXP_WFE_B_STAGE2_MUX3_MUX14 16
+#define BM_PXP_WFE_B_STAGE2_MUX3_MUX14 0x003F0000
+#define BF_PXP_WFE_B_STAGE2_MUX3_MUX14(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STAGE2_MUX3_MUX14)
+#define BP_PXP_WFE_B_STAGE2_MUX3_RSVD2 14
+#define BM_PXP_WFE_B_STAGE2_MUX3_RSVD2 0x0000C000
+#define BF_PXP_WFE_B_STAGE2_MUX3_RSVD2(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STAGE2_MUX3_RSVD2)
+#define BP_PXP_WFE_B_STAGE2_MUX3_MUX13 8
+#define BM_PXP_WFE_B_STAGE2_MUX3_MUX13 0x00003F00
+#define BF_PXP_WFE_B_STAGE2_MUX3_MUX13(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STAGE2_MUX3_MUX13)
+#define BP_PXP_WFE_B_STAGE2_MUX3_RSVD3 6
+#define BM_PXP_WFE_B_STAGE2_MUX3_RSVD3 0x000000C0
+#define BF_PXP_WFE_B_STAGE2_MUX3_RSVD3(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STAGE2_MUX3_RSVD3)
+#define BP_PXP_WFE_B_STAGE2_MUX3_MUX12 0
+#define BM_PXP_WFE_B_STAGE2_MUX3_MUX12 0x0000003F
+#define BF_PXP_WFE_B_STAGE2_MUX3_MUX12(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STAGE2_MUX3_MUX12)
+
+#define HW_PXP_WFE_B_STAGE2_MUX4 (0x00001e20)
+#define HW_PXP_WFE_B_STAGE2_MUX4_SET (0x00001e24)
+#define HW_PXP_WFE_B_STAGE2_MUX4_CLR (0x00001e28)
+#define HW_PXP_WFE_B_STAGE2_MUX4_TOG (0x00001e2c)
+
+#define BP_PXP_WFE_B_STAGE2_MUX4_RSVD0 30
+#define BM_PXP_WFE_B_STAGE2_MUX4_RSVD0 0xC0000000
+#define BF_PXP_WFE_B_STAGE2_MUX4_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STAGE2_MUX4_RSVD0)
+#define BP_PXP_WFE_B_STAGE2_MUX4_MUX19 24
+#define BM_PXP_WFE_B_STAGE2_MUX4_MUX19 0x3F000000
+#define BF_PXP_WFE_B_STAGE2_MUX4_MUX19(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STAGE2_MUX4_MUX19)
+#define BP_PXP_WFE_B_STAGE2_MUX4_RSVD1 22
+#define BM_PXP_WFE_B_STAGE2_MUX4_RSVD1 0x00C00000
+#define BF_PXP_WFE_B_STAGE2_MUX4_RSVD1(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STAGE2_MUX4_RSVD1)
+#define BP_PXP_WFE_B_STAGE2_MUX4_MUX18 16
+#define BM_PXP_WFE_B_STAGE2_MUX4_MUX18 0x003F0000
+#define BF_PXP_WFE_B_STAGE2_MUX4_MUX18(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STAGE2_MUX4_MUX18)
+#define BP_PXP_WFE_B_STAGE2_MUX4_RSVD2 14
+#define BM_PXP_WFE_B_STAGE2_MUX4_RSVD2 0x0000C000
+#define BF_PXP_WFE_B_STAGE2_MUX4_RSVD2(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STAGE2_MUX4_RSVD2)
+#define BP_PXP_WFE_B_STAGE2_MUX4_MUX17 8
+#define BM_PXP_WFE_B_STAGE2_MUX4_MUX17 0x00003F00
+#define BF_PXP_WFE_B_STAGE2_MUX4_MUX17(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STAGE2_MUX4_MUX17)
+#define BP_PXP_WFE_B_STAGE2_MUX4_RSVD3 6
+#define BM_PXP_WFE_B_STAGE2_MUX4_RSVD3 0x000000C0
+#define BF_PXP_WFE_B_STAGE2_MUX4_RSVD3(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STAGE2_MUX4_RSVD3)
+#define BP_PXP_WFE_B_STAGE2_MUX4_MUX16 0
+#define BM_PXP_WFE_B_STAGE2_MUX4_MUX16 0x0000003F
+#define BF_PXP_WFE_B_STAGE2_MUX4_MUX16(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STAGE2_MUX4_MUX16)
+
+#define HW_PXP_WFE_B_STAGE2_MUX5 (0x00001e30)
+#define HW_PXP_WFE_B_STAGE2_MUX5_SET (0x00001e34)
+#define HW_PXP_WFE_B_STAGE2_MUX5_CLR (0x00001e38)
+#define HW_PXP_WFE_B_STAGE2_MUX5_TOG (0x00001e3c)
+
+#define BP_PXP_WFE_B_STAGE2_MUX5_RSVD0 30
+#define BM_PXP_WFE_B_STAGE2_MUX5_RSVD0 0xC0000000
+#define BF_PXP_WFE_B_STAGE2_MUX5_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STAGE2_MUX5_RSVD0)
+#define BP_PXP_WFE_B_STAGE2_MUX5_MUX23 24
+#define BM_PXP_WFE_B_STAGE2_MUX5_MUX23 0x3F000000
+#define BF_PXP_WFE_B_STAGE2_MUX5_MUX23(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STAGE2_MUX5_MUX23)
+#define BP_PXP_WFE_B_STAGE2_MUX5_RSVD1 22
+#define BM_PXP_WFE_B_STAGE2_MUX5_RSVD1 0x00C00000
+#define BF_PXP_WFE_B_STAGE2_MUX5_RSVD1(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STAGE2_MUX5_RSVD1)
+#define BP_PXP_WFE_B_STAGE2_MUX5_MUX22 16
+#define BM_PXP_WFE_B_STAGE2_MUX5_MUX22 0x003F0000
+#define BF_PXP_WFE_B_STAGE2_MUX5_MUX22(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STAGE2_MUX5_MUX22)
+#define BP_PXP_WFE_B_STAGE2_MUX5_RSVD2 14
+#define BM_PXP_WFE_B_STAGE2_MUX5_RSVD2 0x0000C000
+#define BF_PXP_WFE_B_STAGE2_MUX5_RSVD2(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STAGE2_MUX5_RSVD2)
+#define BP_PXP_WFE_B_STAGE2_MUX5_MUX21 8
+#define BM_PXP_WFE_B_STAGE2_MUX5_MUX21 0x00003F00
+#define BF_PXP_WFE_B_STAGE2_MUX5_MUX21(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STAGE2_MUX5_MUX21)
+#define BP_PXP_WFE_B_STAGE2_MUX5_RSVD3 6
+#define BM_PXP_WFE_B_STAGE2_MUX5_RSVD3 0x000000C0
+#define BF_PXP_WFE_B_STAGE2_MUX5_RSVD3(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STAGE2_MUX5_RSVD3)
+#define BP_PXP_WFE_B_STAGE2_MUX5_MUX20 0
+#define BM_PXP_WFE_B_STAGE2_MUX5_MUX20 0x0000003F
+#define BF_PXP_WFE_B_STAGE2_MUX5_MUX20(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STAGE2_MUX5_MUX20)
+
+#define HW_PXP_WFE_B_STAGE2_MUX6 (0x00001e40)
+#define HW_PXP_WFE_B_STAGE2_MUX6_SET (0x00001e44)
+#define HW_PXP_WFE_B_STAGE2_MUX6_CLR (0x00001e48)
+#define HW_PXP_WFE_B_STAGE2_MUX6_TOG (0x00001e4c)
+
+#define BP_PXP_WFE_B_STAGE2_MUX6_RSVD0 30
+#define BM_PXP_WFE_B_STAGE2_MUX6_RSVD0 0xC0000000
+#define BF_PXP_WFE_B_STAGE2_MUX6_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STAGE2_MUX6_RSVD0)
+#define BP_PXP_WFE_B_STAGE2_MUX6_MUX27 24
+#define BM_PXP_WFE_B_STAGE2_MUX6_MUX27 0x3F000000
+#define BF_PXP_WFE_B_STAGE2_MUX6_MUX27(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STAGE2_MUX6_MUX27)
+#define BP_PXP_WFE_B_STAGE2_MUX6_RSVD1 22
+#define BM_PXP_WFE_B_STAGE2_MUX6_RSVD1 0x00C00000
+#define BF_PXP_WFE_B_STAGE2_MUX6_RSVD1(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STAGE2_MUX6_RSVD1)
+#define BP_PXP_WFE_B_STAGE2_MUX6_MUX26 16
+#define BM_PXP_WFE_B_STAGE2_MUX6_MUX26 0x003F0000
+#define BF_PXP_WFE_B_STAGE2_MUX6_MUX26(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STAGE2_MUX6_MUX26)
+#define BP_PXP_WFE_B_STAGE2_MUX6_RSVD2 14
+#define BM_PXP_WFE_B_STAGE2_MUX6_RSVD2 0x0000C000
+#define BF_PXP_WFE_B_STAGE2_MUX6_RSVD2(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STAGE2_MUX6_RSVD2)
+#define BP_PXP_WFE_B_STAGE2_MUX6_MUX25 8
+#define BM_PXP_WFE_B_STAGE2_MUX6_MUX25 0x00003F00
+#define BF_PXP_WFE_B_STAGE2_MUX6_MUX25(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STAGE2_MUX6_MUX25)
+#define BP_PXP_WFE_B_STAGE2_MUX6_RSVD3 6
+#define BM_PXP_WFE_B_STAGE2_MUX6_RSVD3 0x000000C0
+#define BF_PXP_WFE_B_STAGE2_MUX6_RSVD3(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STAGE2_MUX6_RSVD3)
+#define BP_PXP_WFE_B_STAGE2_MUX6_MUX24 0
+#define BM_PXP_WFE_B_STAGE2_MUX6_MUX24 0x0000003F
+#define BF_PXP_WFE_B_STAGE2_MUX6_MUX24(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STAGE2_MUX6_MUX24)
+
+#define HW_PXP_WFE_B_STAGE2_MUX7 (0x00001e50)
+#define HW_PXP_WFE_B_STAGE2_MUX7_SET (0x00001e54)
+#define HW_PXP_WFE_B_STAGE2_MUX7_CLR (0x00001e58)
+#define HW_PXP_WFE_B_STAGE2_MUX7_TOG (0x00001e5c)
+
+#define BP_PXP_WFE_B_STAGE2_MUX7_RSVD0 30
+#define BM_PXP_WFE_B_STAGE2_MUX7_RSVD0 0xC0000000
+#define BF_PXP_WFE_B_STAGE2_MUX7_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STAGE2_MUX7_RSVD0)
+#define BP_PXP_WFE_B_STAGE2_MUX7_MUX31 24
+#define BM_PXP_WFE_B_STAGE2_MUX7_MUX31 0x3F000000
+#define BF_PXP_WFE_B_STAGE2_MUX7_MUX31(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STAGE2_MUX7_MUX31)
+#define BP_PXP_WFE_B_STAGE2_MUX7_RSVD1 22
+#define BM_PXP_WFE_B_STAGE2_MUX7_RSVD1 0x00C00000
+#define BF_PXP_WFE_B_STAGE2_MUX7_RSVD1(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STAGE2_MUX7_RSVD1)
+#define BP_PXP_WFE_B_STAGE2_MUX7_MUX30 16
+#define BM_PXP_WFE_B_STAGE2_MUX7_MUX30 0x003F0000
+#define BF_PXP_WFE_B_STAGE2_MUX7_MUX30(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STAGE2_MUX7_MUX30)
+#define BP_PXP_WFE_B_STAGE2_MUX7_RSVD2 14
+#define BM_PXP_WFE_B_STAGE2_MUX7_RSVD2 0x0000C000
+#define BF_PXP_WFE_B_STAGE2_MUX7_RSVD2(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STAGE2_MUX7_RSVD2)
+#define BP_PXP_WFE_B_STAGE2_MUX7_MUX29 8
+#define BM_PXP_WFE_B_STAGE2_MUX7_MUX29 0x00003F00
+#define BF_PXP_WFE_B_STAGE2_MUX7_MUX29(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STAGE2_MUX7_MUX29)
+#define BP_PXP_WFE_B_STAGE2_MUX7_RSVD3 6
+#define BM_PXP_WFE_B_STAGE2_MUX7_RSVD3 0x000000C0
+#define BF_PXP_WFE_B_STAGE2_MUX7_RSVD3(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STAGE2_MUX7_RSVD3)
+#define BP_PXP_WFE_B_STAGE2_MUX7_MUX28 0
+#define BM_PXP_WFE_B_STAGE2_MUX7_MUX28 0x0000003F
+#define BF_PXP_WFE_B_STAGE2_MUX7_MUX28(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STAGE2_MUX7_MUX28)
+
+#define HW_PXP_WFE_B_STAGE2_MUX8 (0x00001e60)
+#define HW_PXP_WFE_B_STAGE2_MUX8_SET (0x00001e64)
+#define HW_PXP_WFE_B_STAGE2_MUX8_CLR (0x00001e68)
+#define HW_PXP_WFE_B_STAGE2_MUX8_TOG (0x00001e6c)
+
+#define BP_PXP_WFE_B_STAGE2_MUX8_RSVD0 30
+#define BM_PXP_WFE_B_STAGE2_MUX8_RSVD0 0xC0000000
+#define BF_PXP_WFE_B_STAGE2_MUX8_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STAGE2_MUX8_RSVD0)
+#define BP_PXP_WFE_B_STAGE2_MUX8_MUX35 24
+#define BM_PXP_WFE_B_STAGE2_MUX8_MUX35 0x3F000000
+#define BF_PXP_WFE_B_STAGE2_MUX8_MUX35(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STAGE2_MUX8_MUX35)
+#define BP_PXP_WFE_B_STAGE2_MUX8_RSVD1 22
+#define BM_PXP_WFE_B_STAGE2_MUX8_RSVD1 0x00C00000
+#define BF_PXP_WFE_B_STAGE2_MUX8_RSVD1(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STAGE2_MUX8_RSVD1)
+#define BP_PXP_WFE_B_STAGE2_MUX8_MUX34 16
+#define BM_PXP_WFE_B_STAGE2_MUX8_MUX34 0x003F0000
+#define BF_PXP_WFE_B_STAGE2_MUX8_MUX34(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STAGE2_MUX8_MUX34)
+#define BP_PXP_WFE_B_STAGE2_MUX8_RSVD2 14
+#define BM_PXP_WFE_B_STAGE2_MUX8_RSVD2 0x0000C000
+#define BF_PXP_WFE_B_STAGE2_MUX8_RSVD2(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STAGE2_MUX8_RSVD2)
+#define BP_PXP_WFE_B_STAGE2_MUX8_MUX33 8
+#define BM_PXP_WFE_B_STAGE2_MUX8_MUX33 0x00003F00
+#define BF_PXP_WFE_B_STAGE2_MUX8_MUX33(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STAGE2_MUX8_MUX33)
+#define BP_PXP_WFE_B_STAGE2_MUX8_RSVD3 6
+#define BM_PXP_WFE_B_STAGE2_MUX8_RSVD3 0x000000C0
+#define BF_PXP_WFE_B_STAGE2_MUX8_RSVD3(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STAGE2_MUX8_RSVD3)
+#define BP_PXP_WFE_B_STAGE2_MUX8_MUX32 0
+#define BM_PXP_WFE_B_STAGE2_MUX8_MUX32 0x0000003F
+#define BF_PXP_WFE_B_STAGE2_MUX8_MUX32(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STAGE2_MUX8_MUX32)
+
+#define HW_PXP_WFE_B_STAGE2_MUX9 (0x00001e70)
+#define HW_PXP_WFE_B_STAGE2_MUX9_SET (0x00001e74)
+#define HW_PXP_WFE_B_STAGE2_MUX9_CLR (0x00001e78)
+#define HW_PXP_WFE_B_STAGE2_MUX9_TOG (0x00001e7c)
+
+#define BP_PXP_WFE_B_STAGE2_MUX9_RSVD0 30
+#define BM_PXP_WFE_B_STAGE2_MUX9_RSVD0 0xC0000000
+#define BF_PXP_WFE_B_STAGE2_MUX9_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STAGE2_MUX9_RSVD0)
+#define BP_PXP_WFE_B_STAGE2_MUX9_MUX39 24
+#define BM_PXP_WFE_B_STAGE2_MUX9_MUX39 0x3F000000
+#define BF_PXP_WFE_B_STAGE2_MUX9_MUX39(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STAGE2_MUX9_MUX39)
+#define BP_PXP_WFE_B_STAGE2_MUX9_RSVD1 22
+#define BM_PXP_WFE_B_STAGE2_MUX9_RSVD1 0x00C00000
+#define BF_PXP_WFE_B_STAGE2_MUX9_RSVD1(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STAGE2_MUX9_RSVD1)
+#define BP_PXP_WFE_B_STAGE2_MUX9_MUX38 16
+#define BM_PXP_WFE_B_STAGE2_MUX9_MUX38 0x003F0000
+#define BF_PXP_WFE_B_STAGE2_MUX9_MUX38(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STAGE2_MUX9_MUX38)
+#define BP_PXP_WFE_B_STAGE2_MUX9_RSVD2 14
+#define BM_PXP_WFE_B_STAGE2_MUX9_RSVD2 0x0000C000
+#define BF_PXP_WFE_B_STAGE2_MUX9_RSVD2(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STAGE2_MUX9_RSVD2)
+#define BP_PXP_WFE_B_STAGE2_MUX9_MUX37 8
+#define BM_PXP_WFE_B_STAGE2_MUX9_MUX37 0x00003F00
+#define BF_PXP_WFE_B_STAGE2_MUX9_MUX37(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STAGE2_MUX9_MUX37)
+#define BP_PXP_WFE_B_STAGE2_MUX9_RSVD3 6
+#define BM_PXP_WFE_B_STAGE2_MUX9_RSVD3 0x000000C0
+#define BF_PXP_WFE_B_STAGE2_MUX9_RSVD3(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STAGE2_MUX9_RSVD3)
+#define BP_PXP_WFE_B_STAGE2_MUX9_MUX36 0
+#define BM_PXP_WFE_B_STAGE2_MUX9_MUX36 0x0000003F
+#define BF_PXP_WFE_B_STAGE2_MUX9_MUX36(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STAGE2_MUX9_MUX36)
+
+#define HW_PXP_WFE_B_STAGE2_MUX10 (0x00001e80)
+#define HW_PXP_WFE_B_STAGE2_MUX10_SET (0x00001e84)
+#define HW_PXP_WFE_B_STAGE2_MUX10_CLR (0x00001e88)
+#define HW_PXP_WFE_B_STAGE2_MUX10_TOG (0x00001e8c)
+
+#define BP_PXP_WFE_B_STAGE2_MUX10_RSVD0 30
+#define BM_PXP_WFE_B_STAGE2_MUX10_RSVD0 0xC0000000
+#define BF_PXP_WFE_B_STAGE2_MUX10_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STAGE2_MUX10_RSVD0)
+#define BP_PXP_WFE_B_STAGE2_MUX10_MUX43 24
+#define BM_PXP_WFE_B_STAGE2_MUX10_MUX43 0x3F000000
+#define BF_PXP_WFE_B_STAGE2_MUX10_MUX43(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STAGE2_MUX10_MUX43)
+#define BP_PXP_WFE_B_STAGE2_MUX10_RSVD1 22
+#define BM_PXP_WFE_B_STAGE2_MUX10_RSVD1 0x00C00000
+#define BF_PXP_WFE_B_STAGE2_MUX10_RSVD1(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STAGE2_MUX10_RSVD1)
+#define BP_PXP_WFE_B_STAGE2_MUX10_MUX42 16
+#define BM_PXP_WFE_B_STAGE2_MUX10_MUX42 0x003F0000
+#define BF_PXP_WFE_B_STAGE2_MUX10_MUX42(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STAGE2_MUX10_MUX42)
+#define BP_PXP_WFE_B_STAGE2_MUX10_RSVD2 14
+#define BM_PXP_WFE_B_STAGE2_MUX10_RSVD2 0x0000C000
+#define BF_PXP_WFE_B_STAGE2_MUX10_RSVD2(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STAGE2_MUX10_RSVD2)
+#define BP_PXP_WFE_B_STAGE2_MUX10_MUX41 8
+#define BM_PXP_WFE_B_STAGE2_MUX10_MUX41 0x00003F00
+#define BF_PXP_WFE_B_STAGE2_MUX10_MUX41(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STAGE2_MUX10_MUX41)
+#define BP_PXP_WFE_B_STAGE2_MUX10_RSVD3 6
+#define BM_PXP_WFE_B_STAGE2_MUX10_RSVD3 0x000000C0
+#define BF_PXP_WFE_B_STAGE2_MUX10_RSVD3(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STAGE2_MUX10_RSVD3)
+#define BP_PXP_WFE_B_STAGE2_MUX10_MUX40 0
+#define BM_PXP_WFE_B_STAGE2_MUX10_MUX40 0x0000003F
+#define BF_PXP_WFE_B_STAGE2_MUX10_MUX40(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STAGE2_MUX10_MUX40)
+#define BV_PXP_WFE_B_STAGE2_MUX10_MUX40__INC 0x0
+#define BV_PXP_WFE_B_STAGE2_MUX10_MUX40__DEC 0x1
+#define BV_PXP_WFE_B_STAGE2_MUX10_MUX40__ADD 0x2
+#define BV_PXP_WFE_B_STAGE2_MUX10_MUX40__MINUS 0x3
+#define BV_PXP_WFE_B_STAGE2_MUX10_MUX40__AND 0x4
+#define BV_PXP_WFE_B_STAGE2_MUX10_MUX40__OR 0x5
+#define BV_PXP_WFE_B_STAGE2_MUX10_MUX40__XOR 0x6
+#define BV_PXP_WFE_B_STAGE2_MUX10_MUX40__SHIFTLEFT 0x7
+#define BV_PXP_WFE_B_STAGE2_MUX10_MUX40__SHIFTRIGHT 0x8
+#define BV_PXP_WFE_B_STAGE2_MUX10_MUX40__BIT_AND 0x9
+#define BV_PXP_WFE_B_STAGE2_MUX10_MUX40__BIT_OR 0xa
+#define BV_PXP_WFE_B_STAGE2_MUX10_MUX40__BIT_CMP 0xb
+#define BV_PXP_WFE_B_STAGE2_MUX10_MUX40__NOP 0xc
+
+#define HW_PXP_WFE_B_STAGE2_MUX11 (0x00001e90)
+#define HW_PXP_WFE_B_STAGE2_MUX11_SET (0x00001e94)
+#define HW_PXP_WFE_B_STAGE2_MUX11_CLR (0x00001e98)
+#define HW_PXP_WFE_B_STAGE2_MUX11_TOG (0x00001e9c)
+
+#define BP_PXP_WFE_B_STAGE2_MUX11_RSVD0 30
+#define BM_PXP_WFE_B_STAGE2_MUX11_RSVD0 0xC0000000
+#define BF_PXP_WFE_B_STAGE2_MUX11_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STAGE2_MUX11_RSVD0)
+#define BP_PXP_WFE_B_STAGE2_MUX11_MUX47 24
+#define BM_PXP_WFE_B_STAGE2_MUX11_MUX47 0x3F000000
+#define BF_PXP_WFE_B_STAGE2_MUX11_MUX47(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STAGE2_MUX11_MUX47)
+#define BP_PXP_WFE_B_STAGE2_MUX11_RSVD1 22
+#define BM_PXP_WFE_B_STAGE2_MUX11_RSVD1 0x00C00000
+#define BF_PXP_WFE_B_STAGE2_MUX11_RSVD1(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STAGE2_MUX11_RSVD1)
+#define BP_PXP_WFE_B_STAGE2_MUX11_MUX46 16
+#define BM_PXP_WFE_B_STAGE2_MUX11_MUX46 0x003F0000
+#define BF_PXP_WFE_B_STAGE2_MUX11_MUX46(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STAGE2_MUX11_MUX46)
+#define BP_PXP_WFE_B_STAGE2_MUX11_RSVD2 14
+#define BM_PXP_WFE_B_STAGE2_MUX11_RSVD2 0x0000C000
+#define BF_PXP_WFE_B_STAGE2_MUX11_RSVD2(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STAGE2_MUX11_RSVD2)
+#define BP_PXP_WFE_B_STAGE2_MUX11_MUX45 8
+#define BM_PXP_WFE_B_STAGE2_MUX11_MUX45 0x00003F00
+#define BF_PXP_WFE_B_STAGE2_MUX11_MUX45(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STAGE2_MUX11_MUX45)
+#define BP_PXP_WFE_B_STAGE2_MUX11_RSVD3 6
+#define BM_PXP_WFE_B_STAGE2_MUX11_RSVD3 0x000000C0
+#define BF_PXP_WFE_B_STAGE2_MUX11_RSVD3(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STAGE2_MUX11_RSVD3)
+#define BP_PXP_WFE_B_STAGE2_MUX11_MUX44 0
+#define BM_PXP_WFE_B_STAGE2_MUX11_MUX44 0x0000003F
+#define BF_PXP_WFE_B_STAGE2_MUX11_MUX44(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STAGE2_MUX11_MUX44)
+
+#define HW_PXP_WFE_B_STAGE2_MUX12 (0x00001ea0)
+#define HW_PXP_WFE_B_STAGE2_MUX12_SET (0x00001ea4)
+#define HW_PXP_WFE_B_STAGE2_MUX12_CLR (0x00001ea8)
+#define HW_PXP_WFE_B_STAGE2_MUX12_TOG (0x00001eac)
+
+#define BP_PXP_WFE_B_STAGE2_MUX12_RSVD0 6
+#define BM_PXP_WFE_B_STAGE2_MUX12_RSVD0 0xFFFFFFC0
+#define BF_PXP_WFE_B_STAGE2_MUX12_RSVD0(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STAGE2_MUX12_RSVD0)
+#define BP_PXP_WFE_B_STAGE2_MUX12_MUX48 0
+#define BM_PXP_WFE_B_STAGE2_MUX12_MUX48 0x0000003F
+#define BF_PXP_WFE_B_STAGE2_MUX12_MUX48(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STAGE2_MUX12_MUX48)
+
+#define HW_PXP_WFE_B_STAGE3_MUX0 (0x00001eb0)
+#define HW_PXP_WFE_B_STAGE3_MUX0_SET (0x00001eb4)
+#define HW_PXP_WFE_B_STAGE3_MUX0_CLR (0x00001eb8)
+#define HW_PXP_WFE_B_STAGE3_MUX0_TOG (0x00001ebc)
+
+#define BP_PXP_WFE_B_STAGE3_MUX0_RSVD0 30
+#define BM_PXP_WFE_B_STAGE3_MUX0_RSVD0 0xC0000000
+#define BF_PXP_WFE_B_STAGE3_MUX0_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STAGE3_MUX0_RSVD0)
+#define BP_PXP_WFE_B_STAGE3_MUX0_MUX3 24
+#define BM_PXP_WFE_B_STAGE3_MUX0_MUX3 0x3F000000
+#define BF_PXP_WFE_B_STAGE3_MUX0_MUX3(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STAGE3_MUX0_MUX3)
+#define BP_PXP_WFE_B_STAGE3_MUX0_RSVD1 22
+#define BM_PXP_WFE_B_STAGE3_MUX0_RSVD1 0x00C00000
+#define BF_PXP_WFE_B_STAGE3_MUX0_RSVD1(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STAGE3_MUX0_RSVD1)
+#define BP_PXP_WFE_B_STAGE3_MUX0_MUX2 16
+#define BM_PXP_WFE_B_STAGE3_MUX0_MUX2 0x003F0000
+#define BF_PXP_WFE_B_STAGE3_MUX0_MUX2(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STAGE3_MUX0_MUX2)
+#define BP_PXP_WFE_B_STAGE3_MUX0_RSVD2 14
+#define BM_PXP_WFE_B_STAGE3_MUX0_RSVD2 0x0000C000
+#define BF_PXP_WFE_B_STAGE3_MUX0_RSVD2(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STAGE3_MUX0_RSVD2)
+#define BP_PXP_WFE_B_STAGE3_MUX0_MUX1 8
+#define BM_PXP_WFE_B_STAGE3_MUX0_MUX1 0x00003F00
+#define BF_PXP_WFE_B_STAGE3_MUX0_MUX1(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STAGE3_MUX0_MUX1)
+#define BP_PXP_WFE_B_STAGE3_MUX0_RSVD3 6
+#define BM_PXP_WFE_B_STAGE3_MUX0_RSVD3 0x000000C0
+#define BF_PXP_WFE_B_STAGE3_MUX0_RSVD3(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STAGE3_MUX0_RSVD3)
+#define BP_PXP_WFE_B_STAGE3_MUX0_MUX0 0
+#define BM_PXP_WFE_B_STAGE3_MUX0_MUX0 0x0000003F
+#define BF_PXP_WFE_B_STAGE3_MUX0_MUX0(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STAGE3_MUX0_MUX0)
+
+#define HW_PXP_WFE_B_STAGE3_MUX1 (0x00001ec0)
+#define HW_PXP_WFE_B_STAGE3_MUX1_SET (0x00001ec4)
+#define HW_PXP_WFE_B_STAGE3_MUX1_CLR (0x00001ec8)
+#define HW_PXP_WFE_B_STAGE3_MUX1_TOG (0x00001ecc)
+
+#define BP_PXP_WFE_B_STAGE3_MUX1_RSVD0 30
+#define BM_PXP_WFE_B_STAGE3_MUX1_RSVD0 0xC0000000
+#define BF_PXP_WFE_B_STAGE3_MUX1_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STAGE3_MUX1_RSVD0)
+#define BP_PXP_WFE_B_STAGE3_MUX1_MUX7 24
+#define BM_PXP_WFE_B_STAGE3_MUX1_MUX7 0x3F000000
+#define BF_PXP_WFE_B_STAGE3_MUX1_MUX7(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STAGE3_MUX1_MUX7)
+#define BP_PXP_WFE_B_STAGE3_MUX1_RSVD1 22
+#define BM_PXP_WFE_B_STAGE3_MUX1_RSVD1 0x00C00000
+#define BF_PXP_WFE_B_STAGE3_MUX1_RSVD1(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STAGE3_MUX1_RSVD1)
+#define BP_PXP_WFE_B_STAGE3_MUX1_MUX6 16
+#define BM_PXP_WFE_B_STAGE3_MUX1_MUX6 0x003F0000
+#define BF_PXP_WFE_B_STAGE3_MUX1_MUX6(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STAGE3_MUX1_MUX6)
+#define BP_PXP_WFE_B_STAGE3_MUX1_RSVD2 14
+#define BM_PXP_WFE_B_STAGE3_MUX1_RSVD2 0x0000C000
+#define BF_PXP_WFE_B_STAGE3_MUX1_RSVD2(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STAGE3_MUX1_RSVD2)
+#define BP_PXP_WFE_B_STAGE3_MUX1_MUX5 8
+#define BM_PXP_WFE_B_STAGE3_MUX1_MUX5 0x00003F00
+#define BF_PXP_WFE_B_STAGE3_MUX1_MUX5(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STAGE3_MUX1_MUX5)
+#define BP_PXP_WFE_B_STAGE3_MUX1_RSVD3 6
+#define BM_PXP_WFE_B_STAGE3_MUX1_RSVD3 0x000000C0
+#define BF_PXP_WFE_B_STAGE3_MUX1_RSVD3(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STAGE3_MUX1_RSVD3)
+#define BP_PXP_WFE_B_STAGE3_MUX1_MUX4 0
+#define BM_PXP_WFE_B_STAGE3_MUX1_MUX4 0x0000003F
+#define BF_PXP_WFE_B_STAGE3_MUX1_MUX4(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STAGE3_MUX1_MUX4)
+
+#define HW_PXP_WFE_B_STAGE3_MUX2 (0x00001ed0)
+#define HW_PXP_WFE_B_STAGE3_MUX2_SET (0x00001ed4)
+#define HW_PXP_WFE_B_STAGE3_MUX2_CLR (0x00001ed8)
+#define HW_PXP_WFE_B_STAGE3_MUX2_TOG (0x00001edc)
+
+#define BP_PXP_WFE_B_STAGE3_MUX2_RSVD0 30
+#define BM_PXP_WFE_B_STAGE3_MUX2_RSVD0 0xC0000000
+#define BF_PXP_WFE_B_STAGE3_MUX2_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STAGE3_MUX2_RSVD0)
+#define BP_PXP_WFE_B_STAGE3_MUX2_MUX11 24
+#define BM_PXP_WFE_B_STAGE3_MUX2_MUX11 0x3F000000
+#define BF_PXP_WFE_B_STAGE3_MUX2_MUX11(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STAGE3_MUX2_MUX11)
+#define BP_PXP_WFE_B_STAGE3_MUX2_RSVD1 22
+#define BM_PXP_WFE_B_STAGE3_MUX2_RSVD1 0x00C00000
+#define BF_PXP_WFE_B_STAGE3_MUX2_RSVD1(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STAGE3_MUX2_RSVD1)
+#define BP_PXP_WFE_B_STAGE3_MUX2_MUX10 16
+#define BM_PXP_WFE_B_STAGE3_MUX2_MUX10 0x003F0000
+#define BF_PXP_WFE_B_STAGE3_MUX2_MUX10(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STAGE3_MUX2_MUX10)
+#define BP_PXP_WFE_B_STAGE3_MUX2_RSVD2 14
+#define BM_PXP_WFE_B_STAGE3_MUX2_RSVD2 0x0000C000
+#define BF_PXP_WFE_B_STAGE3_MUX2_RSVD2(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STAGE3_MUX2_RSVD2)
+#define BP_PXP_WFE_B_STAGE3_MUX2_MUX9 8
+#define BM_PXP_WFE_B_STAGE3_MUX2_MUX9 0x00003F00
+#define BF_PXP_WFE_B_STAGE3_MUX2_MUX9(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STAGE3_MUX2_MUX9)
+#define BP_PXP_WFE_B_STAGE3_MUX2_RSVD3 6
+#define BM_PXP_WFE_B_STAGE3_MUX2_RSVD3 0x000000C0
+#define BF_PXP_WFE_B_STAGE3_MUX2_RSVD3(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STAGE3_MUX2_RSVD3)
+#define BP_PXP_WFE_B_STAGE3_MUX2_MUX8 0
+#define BM_PXP_WFE_B_STAGE3_MUX2_MUX8 0x0000003F
+#define BF_PXP_WFE_B_STAGE3_MUX2_MUX8(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STAGE3_MUX2_MUX8)
+
+#define HW_PXP_WFE_B_STAGE3_MUX3 (0x00001ee0)
+#define HW_PXP_WFE_B_STAGE3_MUX3_SET (0x00001ee4)
+#define HW_PXP_WFE_B_STAGE3_MUX3_CLR (0x00001ee8)
+#define HW_PXP_WFE_B_STAGE3_MUX3_TOG (0x00001eec)
+
+#define BP_PXP_WFE_B_STAGE3_MUX3_RSVD0 30
+#define BM_PXP_WFE_B_STAGE3_MUX3_RSVD0 0xC0000000
+#define BF_PXP_WFE_B_STAGE3_MUX3_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STAGE3_MUX3_RSVD0)
+#define BP_PXP_WFE_B_STAGE3_MUX3_MUX15 24
+#define BM_PXP_WFE_B_STAGE3_MUX3_MUX15 0x3F000000
+#define BF_PXP_WFE_B_STAGE3_MUX3_MUX15(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STAGE3_MUX3_MUX15)
+#define BP_PXP_WFE_B_STAGE3_MUX3_RSVD1 22
+#define BM_PXP_WFE_B_STAGE3_MUX3_RSVD1 0x00C00000
+#define BF_PXP_WFE_B_STAGE3_MUX3_RSVD1(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STAGE3_MUX3_RSVD1)
+#define BP_PXP_WFE_B_STAGE3_MUX3_MUX14 16
+#define BM_PXP_WFE_B_STAGE3_MUX3_MUX14 0x003F0000
+#define BF_PXP_WFE_B_STAGE3_MUX3_MUX14(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STAGE3_MUX3_MUX14)
+#define BP_PXP_WFE_B_STAGE3_MUX3_RSVD2 14
+#define BM_PXP_WFE_B_STAGE3_MUX3_RSVD2 0x0000C000
+#define BF_PXP_WFE_B_STAGE3_MUX3_RSVD2(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STAGE3_MUX3_RSVD2)
+#define BP_PXP_WFE_B_STAGE3_MUX3_MUX13 8
+#define BM_PXP_WFE_B_STAGE3_MUX3_MUX13 0x00003F00
+#define BF_PXP_WFE_B_STAGE3_MUX3_MUX13(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STAGE3_MUX3_MUX13)
+#define BP_PXP_WFE_B_STAGE3_MUX3_RSVD3 6
+#define BM_PXP_WFE_B_STAGE3_MUX3_RSVD3 0x000000C0
+#define BF_PXP_WFE_B_STAGE3_MUX3_RSVD3(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STAGE3_MUX3_RSVD3)
+#define BP_PXP_WFE_B_STAGE3_MUX3_MUX12 0
+#define BM_PXP_WFE_B_STAGE3_MUX3_MUX12 0x0000003F
+#define BF_PXP_WFE_B_STAGE3_MUX3_MUX12(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STAGE3_MUX3_MUX12)
+
+#define HW_PXP_WFE_B_STAGE3_MUX4 (0x00001ef0)
+#define HW_PXP_WFE_B_STAGE3_MUX4_SET (0x00001ef4)
+#define HW_PXP_WFE_B_STAGE3_MUX4_CLR (0x00001ef8)
+#define HW_PXP_WFE_B_STAGE3_MUX4_TOG (0x00001efc)
+
+#define BP_PXP_WFE_B_STAGE3_MUX4_RSVD0 30
+#define BM_PXP_WFE_B_STAGE3_MUX4_RSVD0 0xC0000000
+#define BF_PXP_WFE_B_STAGE3_MUX4_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STAGE3_MUX4_RSVD0)
+#define BP_PXP_WFE_B_STAGE3_MUX4_MUX19 24
+#define BM_PXP_WFE_B_STAGE3_MUX4_MUX19 0x3F000000
+#define BF_PXP_WFE_B_STAGE3_MUX4_MUX19(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STAGE3_MUX4_MUX19)
+#define BP_PXP_WFE_B_STAGE3_MUX4_RSVD1 22
+#define BM_PXP_WFE_B_STAGE3_MUX4_RSVD1 0x00C00000
+#define BF_PXP_WFE_B_STAGE3_MUX4_RSVD1(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STAGE3_MUX4_RSVD1)
+#define BP_PXP_WFE_B_STAGE3_MUX4_MUX18 16
+#define BM_PXP_WFE_B_STAGE3_MUX4_MUX18 0x003F0000
+#define BF_PXP_WFE_B_STAGE3_MUX4_MUX18(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STAGE3_MUX4_MUX18)
+#define BP_PXP_WFE_B_STAGE3_MUX4_RSVD2 14
+#define BM_PXP_WFE_B_STAGE3_MUX4_RSVD2 0x0000C000
+#define BF_PXP_WFE_B_STAGE3_MUX4_RSVD2(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STAGE3_MUX4_RSVD2)
+#define BP_PXP_WFE_B_STAGE3_MUX4_MUX17 8
+#define BM_PXP_WFE_B_STAGE3_MUX4_MUX17 0x00003F00
+#define BF_PXP_WFE_B_STAGE3_MUX4_MUX17(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STAGE3_MUX4_MUX17)
+#define BP_PXP_WFE_B_STAGE3_MUX4_RSVD3 6
+#define BM_PXP_WFE_B_STAGE3_MUX4_RSVD3 0x000000C0
+#define BF_PXP_WFE_B_STAGE3_MUX4_RSVD3(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STAGE3_MUX4_RSVD3)
+#define BP_PXP_WFE_B_STAGE3_MUX4_MUX16 0
+#define BM_PXP_WFE_B_STAGE3_MUX4_MUX16 0x0000003F
+#define BF_PXP_WFE_B_STAGE3_MUX4_MUX16(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STAGE3_MUX4_MUX16)
+
+#define HW_PXP_WFE_B_STAGE3_MUX5 (0x00001f00)
+#define HW_PXP_WFE_B_STAGE3_MUX5_SET (0x00001f04)
+#define HW_PXP_WFE_B_STAGE3_MUX5_CLR (0x00001f08)
+#define HW_PXP_WFE_B_STAGE3_MUX5_TOG (0x00001f0c)
+
+#define BP_PXP_WFE_B_STAGE3_MUX5_RSVD0 30
+#define BM_PXP_WFE_B_STAGE3_MUX5_RSVD0 0xC0000000
+#define BF_PXP_WFE_B_STAGE3_MUX5_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STAGE3_MUX5_RSVD0)
+#define BP_PXP_WFE_B_STAGE3_MUX5_MUX23 24
+#define BM_PXP_WFE_B_STAGE3_MUX5_MUX23 0x3F000000
+#define BF_PXP_WFE_B_STAGE3_MUX5_MUX23(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STAGE3_MUX5_MUX23)
+#define BP_PXP_WFE_B_STAGE3_MUX5_RSVD1 22
+#define BM_PXP_WFE_B_STAGE3_MUX5_RSVD1 0x00C00000
+#define BF_PXP_WFE_B_STAGE3_MUX5_RSVD1(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STAGE3_MUX5_RSVD1)
+#define BP_PXP_WFE_B_STAGE3_MUX5_MUX22 16
+#define BM_PXP_WFE_B_STAGE3_MUX5_MUX22 0x003F0000
+#define BF_PXP_WFE_B_STAGE3_MUX5_MUX22(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STAGE3_MUX5_MUX22)
+#define BP_PXP_WFE_B_STAGE3_MUX5_RSVD2 14
+#define BM_PXP_WFE_B_STAGE3_MUX5_RSVD2 0x0000C000
+#define BF_PXP_WFE_B_STAGE3_MUX5_RSVD2(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STAGE3_MUX5_RSVD2)
+#define BP_PXP_WFE_B_STAGE3_MUX5_MUX21 8
+#define BM_PXP_WFE_B_STAGE3_MUX5_MUX21 0x00003F00
+#define BF_PXP_WFE_B_STAGE3_MUX5_MUX21(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STAGE3_MUX5_MUX21)
+#define BP_PXP_WFE_B_STAGE3_MUX5_RSVD3 6
+#define BM_PXP_WFE_B_STAGE3_MUX5_RSVD3 0x000000C0
+#define BF_PXP_WFE_B_STAGE3_MUX5_RSVD3(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STAGE3_MUX5_RSVD3)
+#define BP_PXP_WFE_B_STAGE3_MUX5_MUX20 0
+#define BM_PXP_WFE_B_STAGE3_MUX5_MUX20 0x0000003F
+#define BF_PXP_WFE_B_STAGE3_MUX5_MUX20(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STAGE3_MUX5_MUX20)
+
+#define HW_PXP_WFE_B_STAGE3_MUX6 (0x00001f10)
+#define HW_PXP_WFE_B_STAGE3_MUX6_SET (0x00001f14)
+#define HW_PXP_WFE_B_STAGE3_MUX6_CLR (0x00001f18)
+#define HW_PXP_WFE_B_STAGE3_MUX6_TOG (0x00001f1c)
+
+#define BP_PXP_WFE_B_STAGE3_MUX6_RSVD0 30
+#define BM_PXP_WFE_B_STAGE3_MUX6_RSVD0 0xC0000000
+#define BF_PXP_WFE_B_STAGE3_MUX6_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STAGE3_MUX6_RSVD0)
+#define BP_PXP_WFE_B_STAGE3_MUX6_MUX27 24
+#define BM_PXP_WFE_B_STAGE3_MUX6_MUX27 0x3F000000
+#define BF_PXP_WFE_B_STAGE3_MUX6_MUX27(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STAGE3_MUX6_MUX27)
+#define BP_PXP_WFE_B_STAGE3_MUX6_RSVD1 22
+#define BM_PXP_WFE_B_STAGE3_MUX6_RSVD1 0x00C00000
+#define BF_PXP_WFE_B_STAGE3_MUX6_RSVD1(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STAGE3_MUX6_RSVD1)
+#define BP_PXP_WFE_B_STAGE3_MUX6_MUX26 16
+#define BM_PXP_WFE_B_STAGE3_MUX6_MUX26 0x003F0000
+#define BF_PXP_WFE_B_STAGE3_MUX6_MUX26(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STAGE3_MUX6_MUX26)
+#define BP_PXP_WFE_B_STAGE3_MUX6_RSVD2 14
+#define BM_PXP_WFE_B_STAGE3_MUX6_RSVD2 0x0000C000
+#define BF_PXP_WFE_B_STAGE3_MUX6_RSVD2(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STAGE3_MUX6_RSVD2)
+#define BP_PXP_WFE_B_STAGE3_MUX6_MUX25 8
+#define BM_PXP_WFE_B_STAGE3_MUX6_MUX25 0x00003F00
+#define BF_PXP_WFE_B_STAGE3_MUX6_MUX25(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STAGE3_MUX6_MUX25)
+#define BP_PXP_WFE_B_STAGE3_MUX6_RSVD3 6
+#define BM_PXP_WFE_B_STAGE3_MUX6_RSVD3 0x000000C0
+#define BF_PXP_WFE_B_STAGE3_MUX6_RSVD3(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STAGE3_MUX6_RSVD3)
+#define BP_PXP_WFE_B_STAGE3_MUX6_MUX24 0
+#define BM_PXP_WFE_B_STAGE3_MUX6_MUX24 0x0000003F
+#define BF_PXP_WFE_B_STAGE3_MUX6_MUX24(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STAGE3_MUX6_MUX24)
+
+#define HW_PXP_WFE_B_STAGE3_MUX7 (0x00001f20)
+#define HW_PXP_WFE_B_STAGE3_MUX7_SET (0x00001f24)
+#define HW_PXP_WFE_B_STAGE3_MUX7_CLR (0x00001f28)
+#define HW_PXP_WFE_B_STAGE3_MUX7_TOG (0x00001f2c)
+
+#define BP_PXP_WFE_B_STAGE3_MUX7_RSVD0 30
+#define BM_PXP_WFE_B_STAGE3_MUX7_RSVD0 0xC0000000
+#define BF_PXP_WFE_B_STAGE3_MUX7_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STAGE3_MUX7_RSVD0)
+#define BP_PXP_WFE_B_STAGE3_MUX7_MUX31 24
+#define BM_PXP_WFE_B_STAGE3_MUX7_MUX31 0x3F000000
+#define BF_PXP_WFE_B_STAGE3_MUX7_MUX31(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STAGE3_MUX7_MUX31)
+#define BP_PXP_WFE_B_STAGE3_MUX7_RSVD1 22
+#define BM_PXP_WFE_B_STAGE3_MUX7_RSVD1 0x00C00000
+#define BF_PXP_WFE_B_STAGE3_MUX7_RSVD1(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STAGE3_MUX7_RSVD1)
+#define BP_PXP_WFE_B_STAGE3_MUX7_MUX30 16
+#define BM_PXP_WFE_B_STAGE3_MUX7_MUX30 0x003F0000
+#define BF_PXP_WFE_B_STAGE3_MUX7_MUX30(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STAGE3_MUX7_MUX30)
+#define BP_PXP_WFE_B_STAGE3_MUX7_RSVD2 14
+#define BM_PXP_WFE_B_STAGE3_MUX7_RSVD2 0x0000C000
+#define BF_PXP_WFE_B_STAGE3_MUX7_RSVD2(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STAGE3_MUX7_RSVD2)
+#define BP_PXP_WFE_B_STAGE3_MUX7_MUX29 8
+#define BM_PXP_WFE_B_STAGE3_MUX7_MUX29 0x00003F00
+#define BF_PXP_WFE_B_STAGE3_MUX7_MUX29(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STAGE3_MUX7_MUX29)
+#define BP_PXP_WFE_B_STAGE3_MUX7_RSVD3 6
+#define BM_PXP_WFE_B_STAGE3_MUX7_RSVD3 0x000000C0
+#define BF_PXP_WFE_B_STAGE3_MUX7_RSVD3(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STAGE3_MUX7_RSVD3)
+#define BP_PXP_WFE_B_STAGE3_MUX7_MUX28 0
+#define BM_PXP_WFE_B_STAGE3_MUX7_MUX28 0x0000003F
+#define BF_PXP_WFE_B_STAGE3_MUX7_MUX28(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STAGE3_MUX7_MUX28)
+
+#define HW_PXP_WFE_B_STAGE3_MUX8 (0x00001f30)
+#define HW_PXP_WFE_B_STAGE3_MUX8_SET (0x00001f34)
+#define HW_PXP_WFE_B_STAGE3_MUX8_CLR (0x00001f38)
+#define HW_PXP_WFE_B_STAGE3_MUX8_TOG (0x00001f3c)
+
+#define BP_PXP_WFE_B_STAGE3_MUX8_RSVD0 30
+#define BM_PXP_WFE_B_STAGE3_MUX8_RSVD0 0xC0000000
+#define BF_PXP_WFE_B_STAGE3_MUX8_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STAGE3_MUX8_RSVD0)
+#define BP_PXP_WFE_B_STAGE3_MUX8_MUX35 24
+#define BM_PXP_WFE_B_STAGE3_MUX8_MUX35 0x3F000000
+#define BF_PXP_WFE_B_STAGE3_MUX8_MUX35(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STAGE3_MUX8_MUX35)
+#define BP_PXP_WFE_B_STAGE3_MUX8_RSVD1 22
+#define BM_PXP_WFE_B_STAGE3_MUX8_RSVD1 0x00C00000
+#define BF_PXP_WFE_B_STAGE3_MUX8_RSVD1(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STAGE3_MUX8_RSVD1)
+#define BP_PXP_WFE_B_STAGE3_MUX8_MUX34 16
+#define BM_PXP_WFE_B_STAGE3_MUX8_MUX34 0x003F0000
+#define BF_PXP_WFE_B_STAGE3_MUX8_MUX34(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STAGE3_MUX8_MUX34)
+#define BP_PXP_WFE_B_STAGE3_MUX8_RSVD2 14
+#define BM_PXP_WFE_B_STAGE3_MUX8_RSVD2 0x0000C000
+#define BF_PXP_WFE_B_STAGE3_MUX8_RSVD2(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STAGE3_MUX8_RSVD2)
+#define BP_PXP_WFE_B_STAGE3_MUX8_MUX33 8
+#define BM_PXP_WFE_B_STAGE3_MUX8_MUX33 0x00003F00
+#define BF_PXP_WFE_B_STAGE3_MUX8_MUX33(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STAGE3_MUX8_MUX33)
+#define BP_PXP_WFE_B_STAGE3_MUX8_RSVD3 6
+#define BM_PXP_WFE_B_STAGE3_MUX8_RSVD3 0x000000C0
+#define BF_PXP_WFE_B_STAGE3_MUX8_RSVD3(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STAGE3_MUX8_RSVD3)
+#define BP_PXP_WFE_B_STAGE3_MUX8_MUX32 0
+#define BM_PXP_WFE_B_STAGE3_MUX8_MUX32 0x0000003F
+#define BF_PXP_WFE_B_STAGE3_MUX8_MUX32(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STAGE3_MUX8_MUX32)
+
+#define HW_PXP_WFE_B_STAGE3_MUX9 (0x00001f40)
+#define HW_PXP_WFE_B_STAGE3_MUX9_SET (0x00001f44)
+#define HW_PXP_WFE_B_STAGE3_MUX9_CLR (0x00001f48)
+#define HW_PXP_WFE_B_STAGE3_MUX9_TOG (0x00001f4c)
+
+#define BP_PXP_WFE_B_STAGE3_MUX9_RSVD0 30
+#define BM_PXP_WFE_B_STAGE3_MUX9_RSVD0 0xC0000000
+#define BF_PXP_WFE_B_STAGE3_MUX9_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STAGE3_MUX9_RSVD0)
+#define BP_PXP_WFE_B_STAGE3_MUX9_MUX39 24
+#define BM_PXP_WFE_B_STAGE3_MUX9_MUX39 0x3F000000
+#define BF_PXP_WFE_B_STAGE3_MUX9_MUX39(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STAGE3_MUX9_MUX39)
+#define BP_PXP_WFE_B_STAGE3_MUX9_RSVD1 22
+#define BM_PXP_WFE_B_STAGE3_MUX9_RSVD1 0x00C00000
+#define BF_PXP_WFE_B_STAGE3_MUX9_RSVD1(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STAGE3_MUX9_RSVD1)
+#define BP_PXP_WFE_B_STAGE3_MUX9_MUX38 16
+#define BM_PXP_WFE_B_STAGE3_MUX9_MUX38 0x003F0000
+#define BF_PXP_WFE_B_STAGE3_MUX9_MUX38(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STAGE3_MUX9_MUX38)
+#define BP_PXP_WFE_B_STAGE3_MUX9_RSVD2 14
+#define BM_PXP_WFE_B_STAGE3_MUX9_RSVD2 0x0000C000
+#define BF_PXP_WFE_B_STAGE3_MUX9_RSVD2(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STAGE3_MUX9_RSVD2)
+#define BP_PXP_WFE_B_STAGE3_MUX9_MUX37 8
+#define BM_PXP_WFE_B_STAGE3_MUX9_MUX37 0x00003F00
+#define BF_PXP_WFE_B_STAGE3_MUX9_MUX37(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STAGE3_MUX9_MUX37)
+#define BP_PXP_WFE_B_STAGE3_MUX9_RSVD3 6
+#define BM_PXP_WFE_B_STAGE3_MUX9_RSVD3 0x000000C0
+#define BF_PXP_WFE_B_STAGE3_MUX9_RSVD3(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STAGE3_MUX9_RSVD3)
+#define BP_PXP_WFE_B_STAGE3_MUX9_MUX36 0
+#define BM_PXP_WFE_B_STAGE3_MUX9_MUX36 0x0000003F
+#define BF_PXP_WFE_B_STAGE3_MUX9_MUX36(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STAGE3_MUX9_MUX36)
+
+#define HW_PXP_WFE_B_STAGE3_MUX10 (0x00001f50)
+#define HW_PXP_WFE_B_STAGE3_MUX10_SET (0x00001f54)
+#define HW_PXP_WFE_B_STAGE3_MUX10_CLR (0x00001f58)
+#define HW_PXP_WFE_B_STAGE3_MUX10_TOG (0x00001f5c)
+
+#define BP_PXP_WFE_B_STAGE3_MUX10_RSVD0 30
+#define BM_PXP_WFE_B_STAGE3_MUX10_RSVD0 0xC0000000
+#define BF_PXP_WFE_B_STAGE3_MUX10_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STAGE3_MUX10_RSVD0)
+#define BP_PXP_WFE_B_STAGE3_MUX10_MUX43 24
+#define BM_PXP_WFE_B_STAGE3_MUX10_MUX43 0x3F000000
+#define BF_PXP_WFE_B_STAGE3_MUX10_MUX43(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STAGE3_MUX10_MUX43)
+#define BP_PXP_WFE_B_STAGE3_MUX10_RSVD1 22
+#define BM_PXP_WFE_B_STAGE3_MUX10_RSVD1 0x00C00000
+#define BF_PXP_WFE_B_STAGE3_MUX10_RSVD1(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STAGE3_MUX10_RSVD1)
+#define BP_PXP_WFE_B_STAGE3_MUX10_MUX42 16
+#define BM_PXP_WFE_B_STAGE3_MUX10_MUX42 0x003F0000
+#define BF_PXP_WFE_B_STAGE3_MUX10_MUX42(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STAGE3_MUX10_MUX42)
+#define BP_PXP_WFE_B_STAGE3_MUX10_RSVD2 14
+#define BM_PXP_WFE_B_STAGE3_MUX10_RSVD2 0x0000C000
+#define BF_PXP_WFE_B_STAGE3_MUX10_RSVD2(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STAGE3_MUX10_RSVD2)
+#define BP_PXP_WFE_B_STAGE3_MUX10_MUX41 8
+#define BM_PXP_WFE_B_STAGE3_MUX10_MUX41 0x00003F00
+#define BF_PXP_WFE_B_STAGE3_MUX10_MUX41(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STAGE3_MUX10_MUX41)
+#define BP_PXP_WFE_B_STAGE3_MUX10_RSVD3 6
+#define BM_PXP_WFE_B_STAGE3_MUX10_RSVD3 0x000000C0
+#define BF_PXP_WFE_B_STAGE3_MUX10_RSVD3(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STAGE3_MUX10_RSVD3)
+#define BP_PXP_WFE_B_STAGE3_MUX10_MUX40 0
+#define BM_PXP_WFE_B_STAGE3_MUX10_MUX40 0x0000003F
+#define BF_PXP_WFE_B_STAGE3_MUX10_MUX40(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STAGE3_MUX10_MUX40)
+
+#define HW_PXP_WFE_B_STG1_5X8_OUT0_0 (0x00001f60)
+
+#define BP_PXP_WFE_B_STG1_5X8_OUT0_0_LUTOUT3 24
+#define BM_PXP_WFE_B_STG1_5X8_OUT0_0_LUTOUT3 0xFF000000
+#define BF_PXP_WFE_B_STG1_5X8_OUT0_0_LUTOUT3(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STG1_5X8_OUT0_0_LUTOUT3)
+#define BP_PXP_WFE_B_STG1_5X8_OUT0_0_LUTOUT2 16
+#define BM_PXP_WFE_B_STG1_5X8_OUT0_0_LUTOUT2 0x00FF0000
+#define BF_PXP_WFE_B_STG1_5X8_OUT0_0_LUTOUT2(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STG1_5X8_OUT0_0_LUTOUT2)
+#define BP_PXP_WFE_B_STG1_5X8_OUT0_0_LUTOUT1 8
+#define BM_PXP_WFE_B_STG1_5X8_OUT0_0_LUTOUT1 0x0000FF00
+#define BF_PXP_WFE_B_STG1_5X8_OUT0_0_LUTOUT1(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STG1_5X8_OUT0_0_LUTOUT1)
+#define BP_PXP_WFE_B_STG1_5X8_OUT0_0_LUTOUT0 0
+#define BM_PXP_WFE_B_STG1_5X8_OUT0_0_LUTOUT0 0x000000FF
+#define BF_PXP_WFE_B_STG1_5X8_OUT0_0_LUTOUT0(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STG1_5X8_OUT0_0_LUTOUT0)
+
+#define HW_PXP_WFE_B_STG1_5X8_OUT0_1 (0x00001f70)
+
+#define BP_PXP_WFE_B_STG1_5X8_OUT0_1_LUTOUT7 24
+#define BM_PXP_WFE_B_STG1_5X8_OUT0_1_LUTOUT7 0xFF000000
+#define BF_PXP_WFE_B_STG1_5X8_OUT0_1_LUTOUT7(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STG1_5X8_OUT0_1_LUTOUT7)
+#define BP_PXP_WFE_B_STG1_5X8_OUT0_1_LUTOUT6 16
+#define BM_PXP_WFE_B_STG1_5X8_OUT0_1_LUTOUT6 0x00FF0000
+#define BF_PXP_WFE_B_STG1_5X8_OUT0_1_LUTOUT6(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STG1_5X8_OUT0_1_LUTOUT6)
+#define BP_PXP_WFE_B_STG1_5X8_OUT0_1_LUTOUT5 8
+#define BM_PXP_WFE_B_STG1_5X8_OUT0_1_LUTOUT5 0x0000FF00
+#define BF_PXP_WFE_B_STG1_5X8_OUT0_1_LUTOUT5(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STG1_5X8_OUT0_1_LUTOUT5)
+#define BP_PXP_WFE_B_STG1_5X8_OUT0_1_LUTOUT4 0
+#define BM_PXP_WFE_B_STG1_5X8_OUT0_1_LUTOUT4 0x000000FF
+#define BF_PXP_WFE_B_STG1_5X8_OUT0_1_LUTOUT4(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STG1_5X8_OUT0_1_LUTOUT4)
+
+#define HW_PXP_WFE_B_STG1_5X8_OUT0_2 (0x00001f80)
+
+#define BP_PXP_WFE_B_STG1_5X8_OUT0_2_LUTOUT11 24
+#define BM_PXP_WFE_B_STG1_5X8_OUT0_2_LUTOUT11 0xFF000000
+#define BF_PXP_WFE_B_STG1_5X8_OUT0_2_LUTOUT11(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STG1_5X8_OUT0_2_LUTOUT11)
+#define BP_PXP_WFE_B_STG1_5X8_OUT0_2_LUTOUT10 16
+#define BM_PXP_WFE_B_STG1_5X8_OUT0_2_LUTOUT10 0x00FF0000
+#define BF_PXP_WFE_B_STG1_5X8_OUT0_2_LUTOUT10(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STG1_5X8_OUT0_2_LUTOUT10)
+#define BP_PXP_WFE_B_STG1_5X8_OUT0_2_LUTOUT9 8
+#define BM_PXP_WFE_B_STG1_5X8_OUT0_2_LUTOUT9 0x0000FF00
+#define BF_PXP_WFE_B_STG1_5X8_OUT0_2_LUTOUT9(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STG1_5X8_OUT0_2_LUTOUT9)
+#define BP_PXP_WFE_B_STG1_5X8_OUT0_2_LUTOUT8 0
+#define BM_PXP_WFE_B_STG1_5X8_OUT0_2_LUTOUT8 0x000000FF
+#define BF_PXP_WFE_B_STG1_5X8_OUT0_2_LUTOUT8(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STG1_5X8_OUT0_2_LUTOUT8)
+
+#define HW_PXP_WFE_B_STG1_5X8_OUT0_3 (0x00001f90)
+
+#define BP_PXP_WFE_B_STG1_5X8_OUT0_3_LUTOUT15 24
+#define BM_PXP_WFE_B_STG1_5X8_OUT0_3_LUTOUT15 0xFF000000
+#define BF_PXP_WFE_B_STG1_5X8_OUT0_3_LUTOUT15(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STG1_5X8_OUT0_3_LUTOUT15)
+#define BP_PXP_WFE_B_STG1_5X8_OUT0_3_LUTOUT14 16
+#define BM_PXP_WFE_B_STG1_5X8_OUT0_3_LUTOUT14 0x00FF0000
+#define BF_PXP_WFE_B_STG1_5X8_OUT0_3_LUTOUT14(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STG1_5X8_OUT0_3_LUTOUT14)
+#define BP_PXP_WFE_B_STG1_5X8_OUT0_3_LUTOUT13 8
+#define BM_PXP_WFE_B_STG1_5X8_OUT0_3_LUTOUT13 0x0000FF00
+#define BF_PXP_WFE_B_STG1_5X8_OUT0_3_LUTOUT13(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STG1_5X8_OUT0_3_LUTOUT13)
+#define BP_PXP_WFE_B_STG1_5X8_OUT0_3_LUTOUT12 0
+#define BM_PXP_WFE_B_STG1_5X8_OUT0_3_LUTOUT12 0x000000FF
+#define BF_PXP_WFE_B_STG1_5X8_OUT0_3_LUTOUT12(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STG1_5X8_OUT0_3_LUTOUT12)
+
+#define HW_PXP_WFE_B_STG1_5X8_OUT0_4 (0x00001fa0)
+
+#define BP_PXP_WFE_B_STG1_5X8_OUT0_4_LUTOUT19 24
+#define BM_PXP_WFE_B_STG1_5X8_OUT0_4_LUTOUT19 0xFF000000
+#define BF_PXP_WFE_B_STG1_5X8_OUT0_4_LUTOUT19(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STG1_5X8_OUT0_4_LUTOUT19)
+#define BP_PXP_WFE_B_STG1_5X8_OUT0_4_LUTOUT18 16
+#define BM_PXP_WFE_B_STG1_5X8_OUT0_4_LUTOUT18 0x00FF0000
+#define BF_PXP_WFE_B_STG1_5X8_OUT0_4_LUTOUT18(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STG1_5X8_OUT0_4_LUTOUT18)
+#define BP_PXP_WFE_B_STG1_5X8_OUT0_4_LUTOUT17 8
+#define BM_PXP_WFE_B_STG1_5X8_OUT0_4_LUTOUT17 0x0000FF00
+#define BF_PXP_WFE_B_STG1_5X8_OUT0_4_LUTOUT17(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STG1_5X8_OUT0_4_LUTOUT17)
+#define BP_PXP_WFE_B_STG1_5X8_OUT0_4_LUTOUT16 0
+#define BM_PXP_WFE_B_STG1_5X8_OUT0_4_LUTOUT16 0x000000FF
+#define BF_PXP_WFE_B_STG1_5X8_OUT0_4_LUTOUT16(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STG1_5X8_OUT0_4_LUTOUT16)
+
+#define HW_PXP_WFE_B_STG1_5X8_OUT0_5 (0x00001fb0)
+
+#define BP_PXP_WFE_B_STG1_5X8_OUT0_5_LUTOUT23 24
+#define BM_PXP_WFE_B_STG1_5X8_OUT0_5_LUTOUT23 0xFF000000
+#define BF_PXP_WFE_B_STG1_5X8_OUT0_5_LUTOUT23(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STG1_5X8_OUT0_5_LUTOUT23)
+#define BP_PXP_WFE_B_STG1_5X8_OUT0_5_LUTOUT22 16
+#define BM_PXP_WFE_B_STG1_5X8_OUT0_5_LUTOUT22 0x00FF0000
+#define BF_PXP_WFE_B_STG1_5X8_OUT0_5_LUTOUT22(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STG1_5X8_OUT0_5_LUTOUT22)
+#define BP_PXP_WFE_B_STG1_5X8_OUT0_5_LUTOUT21 8
+#define BM_PXP_WFE_B_STG1_5X8_OUT0_5_LUTOUT21 0x0000FF00
+#define BF_PXP_WFE_B_STG1_5X8_OUT0_5_LUTOUT21(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STG1_5X8_OUT0_5_LUTOUT21)
+#define BP_PXP_WFE_B_STG1_5X8_OUT0_5_LUTOUT20 0
+#define BM_PXP_WFE_B_STG1_5X8_OUT0_5_LUTOUT20 0x000000FF
+#define BF_PXP_WFE_B_STG1_5X8_OUT0_5_LUTOUT20(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STG1_5X8_OUT0_5_LUTOUT20)
+
+#define HW_PXP_WFE_B_STG1_5X8_OUT0_6 (0x00001fc0)
+
+#define BP_PXP_WFE_B_STG1_5X8_OUT0_6_LUTOUT27 24
+#define BM_PXP_WFE_B_STG1_5X8_OUT0_6_LUTOUT27 0xFF000000
+#define BF_PXP_WFE_B_STG1_5X8_OUT0_6_LUTOUT27(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STG1_5X8_OUT0_6_LUTOUT27)
+#define BP_PXP_WFE_B_STG1_5X8_OUT0_6_LUTOUT26 16
+#define BM_PXP_WFE_B_STG1_5X8_OUT0_6_LUTOUT26 0x00FF0000
+#define BF_PXP_WFE_B_STG1_5X8_OUT0_6_LUTOUT26(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STG1_5X8_OUT0_6_LUTOUT26)
+#define BP_PXP_WFE_B_STG1_5X8_OUT0_6_LUTOUT25 8
+#define BM_PXP_WFE_B_STG1_5X8_OUT0_6_LUTOUT25 0x0000FF00
+#define BF_PXP_WFE_B_STG1_5X8_OUT0_6_LUTOUT25(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STG1_5X8_OUT0_6_LUTOUT25)
+#define BP_PXP_WFE_B_STG1_5X8_OUT0_6_LUTOUT24 0
+#define BM_PXP_WFE_B_STG1_5X8_OUT0_6_LUTOUT24 0x000000FF
+#define BF_PXP_WFE_B_STG1_5X8_OUT0_6_LUTOUT24(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STG1_5X8_OUT0_6_LUTOUT24)
+
+#define HW_PXP_WFE_B_STG1_5X8_OUT0_7 (0x00001fd0)
+
+#define BP_PXP_WFE_B_STG1_5X8_OUT0_7_LUTOUT31 24
+#define BM_PXP_WFE_B_STG1_5X8_OUT0_7_LUTOUT31 0xFF000000
+#define BF_PXP_WFE_B_STG1_5X8_OUT0_7_LUTOUT31(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STG1_5X8_OUT0_7_LUTOUT31)
+#define BP_PXP_WFE_B_STG1_5X8_OUT0_7_LUTOUT30 16
+#define BM_PXP_WFE_B_STG1_5X8_OUT0_7_LUTOUT30 0x00FF0000
+#define BF_PXP_WFE_B_STG1_5X8_OUT0_7_LUTOUT30(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STG1_5X8_OUT0_7_LUTOUT30)
+#define BP_PXP_WFE_B_STG1_5X8_OUT0_7_LUTOUT29 8
+#define BM_PXP_WFE_B_STG1_5X8_OUT0_7_LUTOUT29 0x0000FF00
+#define BF_PXP_WFE_B_STG1_5X8_OUT0_7_LUTOUT29(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STG1_5X8_OUT0_7_LUTOUT29)
+#define BP_PXP_WFE_B_STG1_5X8_OUT0_7_LUTOUT28 0
+#define BM_PXP_WFE_B_STG1_5X8_OUT0_7_LUTOUT28 0x000000FF
+#define BF_PXP_WFE_B_STG1_5X8_OUT0_7_LUTOUT28(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STG1_5X8_OUT0_7_LUTOUT28)
+
+#define HW_PXP_WFE_B_STG1_5X8_OUT1_0 (0x00001fe0)
+
+#define BP_PXP_WFE_B_STG1_5X8_OUT1_0_LUTOUT3 24
+#define BM_PXP_WFE_B_STG1_5X8_OUT1_0_LUTOUT3 0xFF000000
+#define BF_PXP_WFE_B_STG1_5X8_OUT1_0_LUTOUT3(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STG1_5X8_OUT1_0_LUTOUT3)
+#define BP_PXP_WFE_B_STG1_5X8_OUT1_0_LUTOUT2 16
+#define BM_PXP_WFE_B_STG1_5X8_OUT1_0_LUTOUT2 0x00FF0000
+#define BF_PXP_WFE_B_STG1_5X8_OUT1_0_LUTOUT2(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STG1_5X8_OUT1_0_LUTOUT2)
+#define BP_PXP_WFE_B_STG1_5X8_OUT1_0_LUTOUT1 8
+#define BM_PXP_WFE_B_STG1_5X8_OUT1_0_LUTOUT1 0x0000FF00
+#define BF_PXP_WFE_B_STG1_5X8_OUT1_0_LUTOUT1(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STG1_5X8_OUT1_0_LUTOUT1)
+#define BP_PXP_WFE_B_STG1_5X8_OUT1_0_LUTOUT0 0
+#define BM_PXP_WFE_B_STG1_5X8_OUT1_0_LUTOUT0 0x000000FF
+#define BF_PXP_WFE_B_STG1_5X8_OUT1_0_LUTOUT0(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STG1_5X8_OUT1_0_LUTOUT0)
+
+#define HW_PXP_WFE_B_STG1_5X8_OUT1_1 (0x00001ff0)
+
+#define BP_PXP_WFE_B_STG1_5X8_OUT1_1_LUTOUT7 24
+#define BM_PXP_WFE_B_STG1_5X8_OUT1_1_LUTOUT7 0xFF000000
+#define BF_PXP_WFE_B_STG1_5X8_OUT1_1_LUTOUT7(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STG1_5X8_OUT1_1_LUTOUT7)
+#define BP_PXP_WFE_B_STG1_5X8_OUT1_1_LUTOUT6 16
+#define BM_PXP_WFE_B_STG1_5X8_OUT1_1_LUTOUT6 0x00FF0000
+#define BF_PXP_WFE_B_STG1_5X8_OUT1_1_LUTOUT6(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STG1_5X8_OUT1_1_LUTOUT6)
+#define BP_PXP_WFE_B_STG1_5X8_OUT1_1_LUTOUT5 8
+#define BM_PXP_WFE_B_STG1_5X8_OUT1_1_LUTOUT5 0x0000FF00
+#define BF_PXP_WFE_B_STG1_5X8_OUT1_1_LUTOUT5(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STG1_5X8_OUT1_1_LUTOUT5)
+#define BP_PXP_WFE_B_STG1_5X8_OUT1_1_LUTOUT4 0
+#define BM_PXP_WFE_B_STG1_5X8_OUT1_1_LUTOUT4 0x000000FF
+#define BF_PXP_WFE_B_STG1_5X8_OUT1_1_LUTOUT4(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STG1_5X8_OUT1_1_LUTOUT4)
+
+#define HW_PXP_WFE_B_STG1_5X8_OUT1_2 (0x00002000)
+
+#define BP_PXP_WFE_B_STG1_5X8_OUT1_2_LUTOUT11 24
+#define BM_PXP_WFE_B_STG1_5X8_OUT1_2_LUTOUT11 0xFF000000
+#define BF_PXP_WFE_B_STG1_5X8_OUT1_2_LUTOUT11(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STG1_5X8_OUT1_2_LUTOUT11)
+#define BP_PXP_WFE_B_STG1_5X8_OUT1_2_LUTOUT10 16
+#define BM_PXP_WFE_B_STG1_5X8_OUT1_2_LUTOUT10 0x00FF0000
+#define BF_PXP_WFE_B_STG1_5X8_OUT1_2_LUTOUT10(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STG1_5X8_OUT1_2_LUTOUT10)
+#define BP_PXP_WFE_B_STG1_5X8_OUT1_2_LUTOUT9 8
+#define BM_PXP_WFE_B_STG1_5X8_OUT1_2_LUTOUT9 0x0000FF00
+#define BF_PXP_WFE_B_STG1_5X8_OUT1_2_LUTOUT9(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STG1_5X8_OUT1_2_LUTOUT9)
+#define BP_PXP_WFE_B_STG1_5X8_OUT1_2_LUTOUT8 0
+#define BM_PXP_WFE_B_STG1_5X8_OUT1_2_LUTOUT8 0x000000FF
+#define BF_PXP_WFE_B_STG1_5X8_OUT1_2_LUTOUT8(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STG1_5X8_OUT1_2_LUTOUT8)
+
+#define HW_PXP_WFE_B_STG1_5X8_OUT1_3 (0x00002010)
+
+#define BP_PXP_WFE_B_STG1_5X8_OUT1_3_LUTOUT15 24
+#define BM_PXP_WFE_B_STG1_5X8_OUT1_3_LUTOUT15 0xFF000000
+#define BF_PXP_WFE_B_STG1_5X8_OUT1_3_LUTOUT15(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STG1_5X8_OUT1_3_LUTOUT15)
+#define BP_PXP_WFE_B_STG1_5X8_OUT1_3_LUTOUT14 16
+#define BM_PXP_WFE_B_STG1_5X8_OUT1_3_LUTOUT14 0x00FF0000
+#define BF_PXP_WFE_B_STG1_5X8_OUT1_3_LUTOUT14(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STG1_5X8_OUT1_3_LUTOUT14)
+#define BP_PXP_WFE_B_STG1_5X8_OUT1_3_LUTOUT13 8
+#define BM_PXP_WFE_B_STG1_5X8_OUT1_3_LUTOUT13 0x0000FF00
+#define BF_PXP_WFE_B_STG1_5X8_OUT1_3_LUTOUT13(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STG1_5X8_OUT1_3_LUTOUT13)
+#define BP_PXP_WFE_B_STG1_5X8_OUT1_3_LUTOUT12 0
+#define BM_PXP_WFE_B_STG1_5X8_OUT1_3_LUTOUT12 0x000000FF
+#define BF_PXP_WFE_B_STG1_5X8_OUT1_3_LUTOUT12(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STG1_5X8_OUT1_3_LUTOUT12)
+
+#define HW_PXP_WFE_B_STG1_5X8_OUT1_4 (0x00002020)
+
+#define BP_PXP_WFE_B_STG1_5X8_OUT1_4_LUTOUT19 24
+#define BM_PXP_WFE_B_STG1_5X8_OUT1_4_LUTOUT19 0xFF000000
+#define BF_PXP_WFE_B_STG1_5X8_OUT1_4_LUTOUT19(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STG1_5X8_OUT1_4_LUTOUT19)
+#define BP_PXP_WFE_B_STG1_5X8_OUT1_4_LUTOUT18 16
+#define BM_PXP_WFE_B_STG1_5X8_OUT1_4_LUTOUT18 0x00FF0000
+#define BF_PXP_WFE_B_STG1_5X8_OUT1_4_LUTOUT18(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STG1_5X8_OUT1_4_LUTOUT18)
+#define BP_PXP_WFE_B_STG1_5X8_OUT1_4_LUTOUT17 8
+#define BM_PXP_WFE_B_STG1_5X8_OUT1_4_LUTOUT17 0x0000FF00
+#define BF_PXP_WFE_B_STG1_5X8_OUT1_4_LUTOUT17(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STG1_5X8_OUT1_4_LUTOUT17)
+#define BP_PXP_WFE_B_STG1_5X8_OUT1_4_LUTOUT16 0
+#define BM_PXP_WFE_B_STG1_5X8_OUT1_4_LUTOUT16 0x000000FF
+#define BF_PXP_WFE_B_STG1_5X8_OUT1_4_LUTOUT16(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STG1_5X8_OUT1_4_LUTOUT16)
+
+#define HW_PXP_WFE_B_STG1_5X8_OUT1_5 (0x00002030)
+
+#define BP_PXP_WFE_B_STG1_5X8_OUT1_5_LUTOUT23 24
+#define BM_PXP_WFE_B_STG1_5X8_OUT1_5_LUTOUT23 0xFF000000
+#define BF_PXP_WFE_B_STG1_5X8_OUT1_5_LUTOUT23(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STG1_5X8_OUT1_5_LUTOUT23)
+#define BP_PXP_WFE_B_STG1_5X8_OUT1_5_LUTOUT22 16
+#define BM_PXP_WFE_B_STG1_5X8_OUT1_5_LUTOUT22 0x00FF0000
+#define BF_PXP_WFE_B_STG1_5X8_OUT1_5_LUTOUT22(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STG1_5X8_OUT1_5_LUTOUT22)
+#define BP_PXP_WFE_B_STG1_5X8_OUT1_5_LUTOUT21 8
+#define BM_PXP_WFE_B_STG1_5X8_OUT1_5_LUTOUT21 0x0000FF00
+#define BF_PXP_WFE_B_STG1_5X8_OUT1_5_LUTOUT21(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STG1_5X8_OUT1_5_LUTOUT21)
+#define BP_PXP_WFE_B_STG1_5X8_OUT1_5_LUTOUT20 0
+#define BM_PXP_WFE_B_STG1_5X8_OUT1_5_LUTOUT20 0x000000FF
+#define BF_PXP_WFE_B_STG1_5X8_OUT1_5_LUTOUT20(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STG1_5X8_OUT1_5_LUTOUT20)
+
+#define HW_PXP_WFE_B_STG1_5X8_OUT1_6 (0x00002040)
+
+#define BP_PXP_WFE_B_STG1_5X8_OUT1_6_LUTOUT27 24
+#define BM_PXP_WFE_B_STG1_5X8_OUT1_6_LUTOUT27 0xFF000000
+#define BF_PXP_WFE_B_STG1_5X8_OUT1_6_LUTOUT27(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STG1_5X8_OUT1_6_LUTOUT27)
+#define BP_PXP_WFE_B_STG1_5X8_OUT1_6_LUTOUT26 16
+#define BM_PXP_WFE_B_STG1_5X8_OUT1_6_LUTOUT26 0x00FF0000
+#define BF_PXP_WFE_B_STG1_5X8_OUT1_6_LUTOUT26(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STG1_5X8_OUT1_6_LUTOUT26)
+#define BP_PXP_WFE_B_STG1_5X8_OUT1_6_LUTOUT25 8
+#define BM_PXP_WFE_B_STG1_5X8_OUT1_6_LUTOUT25 0x0000FF00
+#define BF_PXP_WFE_B_STG1_5X8_OUT1_6_LUTOUT25(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STG1_5X8_OUT1_6_LUTOUT25)
+#define BP_PXP_WFE_B_STG1_5X8_OUT1_6_LUTOUT24 0
+#define BM_PXP_WFE_B_STG1_5X8_OUT1_6_LUTOUT24 0x000000FF
+#define BF_PXP_WFE_B_STG1_5X8_OUT1_6_LUTOUT24(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STG1_5X8_OUT1_6_LUTOUT24)
+
+#define HW_PXP_WFE_B_STG1_5X8_OUT1_7 (0x00002050)
+
+#define BP_PXP_WFE_B_STG1_5X8_OUT1_7_LUTOUT31 24
+#define BM_PXP_WFE_B_STG1_5X8_OUT1_7_LUTOUT31 0xFF000000
+#define BF_PXP_WFE_B_STG1_5X8_OUT1_7_LUTOUT31(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STG1_5X8_OUT1_7_LUTOUT31)
+#define BP_PXP_WFE_B_STG1_5X8_OUT1_7_LUTOUT30 16
+#define BM_PXP_WFE_B_STG1_5X8_OUT1_7_LUTOUT30 0x00FF0000
+#define BF_PXP_WFE_B_STG1_5X8_OUT1_7_LUTOUT30(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STG1_5X8_OUT1_7_LUTOUT30)
+#define BP_PXP_WFE_B_STG1_5X8_OUT1_7_LUTOUT29 8
+#define BM_PXP_WFE_B_STG1_5X8_OUT1_7_LUTOUT29 0x0000FF00
+#define BF_PXP_WFE_B_STG1_5X8_OUT1_7_LUTOUT29(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STG1_5X8_OUT1_7_LUTOUT29)
+#define BP_PXP_WFE_B_STG1_5X8_OUT1_7_LUTOUT28 0
+#define BM_PXP_WFE_B_STG1_5X8_OUT1_7_LUTOUT28 0x000000FF
+#define BF_PXP_WFE_B_STG1_5X8_OUT1_7_LUTOUT28(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STG1_5X8_OUT1_7_LUTOUT28)
+
+#define HW_PXP_WFE_B_STAGE1_5X8_MASKS_0 (0x00002060)
+
+#define BP_PXP_WFE_B_STAGE1_5X8_MASKS_0_RSVD2 13
+#define BM_PXP_WFE_B_STAGE1_5X8_MASKS_0_RSVD2 0xFFFFE000
+#define BF_PXP_WFE_B_STAGE1_5X8_MASKS_0_RSVD2(v) \
+ (((v) << 13) & BM_PXP_WFE_B_STAGE1_5X8_MASKS_0_RSVD2)
+#define BP_PXP_WFE_B_STAGE1_5X8_MASKS_0_MASK1 8
+#define BM_PXP_WFE_B_STAGE1_5X8_MASKS_0_MASK1 0x00001F00
+#define BF_PXP_WFE_B_STAGE1_5X8_MASKS_0_MASK1(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STAGE1_5X8_MASKS_0_MASK1)
+#define BP_PXP_WFE_B_STAGE1_5X8_MASKS_0_RSVD3 5
+#define BM_PXP_WFE_B_STAGE1_5X8_MASKS_0_RSVD3 0x000000E0
+#define BF_PXP_WFE_B_STAGE1_5X8_MASKS_0_RSVD3(v) \
+ (((v) << 5) & BM_PXP_WFE_B_STAGE1_5X8_MASKS_0_RSVD3)
+#define BP_PXP_WFE_B_STAGE1_5X8_MASKS_0_MASK0 0
+#define BM_PXP_WFE_B_STAGE1_5X8_MASKS_0_MASK0 0x0000001F
+#define BF_PXP_WFE_B_STAGE1_5X8_MASKS_0_MASK0(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STAGE1_5X8_MASKS_0_MASK0)
+
+#define HW_PXP_WFE_B_STG1_5X1_OUT0 (0x00002070)
+
+#define BM_PXP_WFE_B_STG1_5X1_OUT0_LUTOUT31 0x80000000
+#define BF_PXP_WFE_B_STG1_5X1_OUT0_LUTOUT31(v) \
+ (((v) << 31) & BM_PXP_WFE_B_STG1_5X1_OUT0_LUTOUT31)
+#define BM_PXP_WFE_B_STG1_5X1_OUT0_LUTOUT30 0x40000000
+#define BF_PXP_WFE_B_STG1_5X1_OUT0_LUTOUT30(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STG1_5X1_OUT0_LUTOUT30)
+#define BM_PXP_WFE_B_STG1_5X1_OUT0_LUTOUT29 0x20000000
+#define BF_PXP_WFE_B_STG1_5X1_OUT0_LUTOUT29(v) \
+ (((v) << 29) & BM_PXP_WFE_B_STG1_5X1_OUT0_LUTOUT29)
+#define BM_PXP_WFE_B_STG1_5X1_OUT0_LUTOUT28 0x10000000
+#define BF_PXP_WFE_B_STG1_5X1_OUT0_LUTOUT28(v) \
+ (((v) << 28) & BM_PXP_WFE_B_STG1_5X1_OUT0_LUTOUT28)
+#define BM_PXP_WFE_B_STG1_5X1_OUT0_LUTOUT27 0x08000000
+#define BF_PXP_WFE_B_STG1_5X1_OUT0_LUTOUT27(v) \
+ (((v) << 27) & BM_PXP_WFE_B_STG1_5X1_OUT0_LUTOUT27)
+#define BM_PXP_WFE_B_STG1_5X1_OUT0_LUTOUT26 0x04000000
+#define BF_PXP_WFE_B_STG1_5X1_OUT0_LUTOUT26(v) \
+ (((v) << 26) & BM_PXP_WFE_B_STG1_5X1_OUT0_LUTOUT26)
+#define BM_PXP_WFE_B_STG1_5X1_OUT0_LUTOUT25 0x02000000
+#define BF_PXP_WFE_B_STG1_5X1_OUT0_LUTOUT25(v) \
+ (((v) << 25) & BM_PXP_WFE_B_STG1_5X1_OUT0_LUTOUT25)
+#define BM_PXP_WFE_B_STG1_5X1_OUT0_LUTOUT24 0x01000000
+#define BF_PXP_WFE_B_STG1_5X1_OUT0_LUTOUT24(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STG1_5X1_OUT0_LUTOUT24)
+#define BM_PXP_WFE_B_STG1_5X1_OUT0_LUTOUT23 0x00800000
+#define BF_PXP_WFE_B_STG1_5X1_OUT0_LUTOUT23(v) \
+ (((v) << 23) & BM_PXP_WFE_B_STG1_5X1_OUT0_LUTOUT23)
+#define BM_PXP_WFE_B_STG1_5X1_OUT0_LUTOUT22 0x00400000
+#define BF_PXP_WFE_B_STG1_5X1_OUT0_LUTOUT22(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STG1_5X1_OUT0_LUTOUT22)
+#define BM_PXP_WFE_B_STG1_5X1_OUT0_LUTOUT21 0x00200000
+#define BF_PXP_WFE_B_STG1_5X1_OUT0_LUTOUT21(v) \
+ (((v) << 21) & BM_PXP_WFE_B_STG1_5X1_OUT0_LUTOUT21)
+#define BM_PXP_WFE_B_STG1_5X1_OUT0_LUTOUT20 0x00100000
+#define BF_PXP_WFE_B_STG1_5X1_OUT0_LUTOUT20(v) \
+ (((v) << 20) & BM_PXP_WFE_B_STG1_5X1_OUT0_LUTOUT20)
+#define BM_PXP_WFE_B_STG1_5X1_OUT0_LUTOUT19 0x00080000
+#define BF_PXP_WFE_B_STG1_5X1_OUT0_LUTOUT19(v) \
+ (((v) << 19) & BM_PXP_WFE_B_STG1_5X1_OUT0_LUTOUT19)
+#define BM_PXP_WFE_B_STG1_5X1_OUT0_LUTOUT18 0x00040000
+#define BF_PXP_WFE_B_STG1_5X1_OUT0_LUTOUT18(v) \
+ (((v) << 18) & BM_PXP_WFE_B_STG1_5X1_OUT0_LUTOUT18)
+#define BM_PXP_WFE_B_STG1_5X1_OUT0_LUTOUT17 0x00020000
+#define BF_PXP_WFE_B_STG1_5X1_OUT0_LUTOUT17(v) \
+ (((v) << 17) & BM_PXP_WFE_B_STG1_5X1_OUT0_LUTOUT17)
+#define BM_PXP_WFE_B_STG1_5X1_OUT0_LUTOUT16 0x00010000
+#define BF_PXP_WFE_B_STG1_5X1_OUT0_LUTOUT16(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STG1_5X1_OUT0_LUTOUT16)
+#define BM_PXP_WFE_B_STG1_5X1_OUT0_LUTOUT15 0x00008000
+#define BF_PXP_WFE_B_STG1_5X1_OUT0_LUTOUT15(v) \
+ (((v) << 15) & BM_PXP_WFE_B_STG1_5X1_OUT0_LUTOUT15)
+#define BM_PXP_WFE_B_STG1_5X1_OUT0_LUTOUT14 0x00004000
+#define BF_PXP_WFE_B_STG1_5X1_OUT0_LUTOUT14(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STG1_5X1_OUT0_LUTOUT14)
+#define BM_PXP_WFE_B_STG1_5X1_OUT0_LUTOUT13 0x00002000
+#define BF_PXP_WFE_B_STG1_5X1_OUT0_LUTOUT13(v) \
+ (((v) << 13) & BM_PXP_WFE_B_STG1_5X1_OUT0_LUTOUT13)
+#define BM_PXP_WFE_B_STG1_5X1_OUT0_LUTOUT12 0x00001000
+#define BF_PXP_WFE_B_STG1_5X1_OUT0_LUTOUT12(v) \
+ (((v) << 12) & BM_PXP_WFE_B_STG1_5X1_OUT0_LUTOUT12)
+#define BM_PXP_WFE_B_STG1_5X1_OUT0_LUTOUT11 0x00000800
+#define BF_PXP_WFE_B_STG1_5X1_OUT0_LUTOUT11(v) \
+ (((v) << 11) & BM_PXP_WFE_B_STG1_5X1_OUT0_LUTOUT11)
+#define BM_PXP_WFE_B_STG1_5X1_OUT0_LUTOUT10 0x00000400
+#define BF_PXP_WFE_B_STG1_5X1_OUT0_LUTOUT10(v) \
+ (((v) << 10) & BM_PXP_WFE_B_STG1_5X1_OUT0_LUTOUT10)
+#define BM_PXP_WFE_B_STG1_5X1_OUT0_LUTOUT9 0x00000200
+#define BF_PXP_WFE_B_STG1_5X1_OUT0_LUTOUT9(v) \
+ (((v) << 9) & BM_PXP_WFE_B_STG1_5X1_OUT0_LUTOUT9)
+#define BM_PXP_WFE_B_STG1_5X1_OUT0_LUTOUT8 0x00000100
+#define BF_PXP_WFE_B_STG1_5X1_OUT0_LUTOUT8(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STG1_5X1_OUT0_LUTOUT8)
+#define BM_PXP_WFE_B_STG1_5X1_OUT0_LUTOUT7 0x00000080
+#define BF_PXP_WFE_B_STG1_5X1_OUT0_LUTOUT7(v) \
+ (((v) << 7) & BM_PXP_WFE_B_STG1_5X1_OUT0_LUTOUT7)
+#define BM_PXP_WFE_B_STG1_5X1_OUT0_LUTOUT6 0x00000040
+#define BF_PXP_WFE_B_STG1_5X1_OUT0_LUTOUT6(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STG1_5X1_OUT0_LUTOUT6)
+#define BM_PXP_WFE_B_STG1_5X1_OUT0_LUTOUT5 0x00000020
+#define BF_PXP_WFE_B_STG1_5X1_OUT0_LUTOUT5(v) \
+ (((v) << 5) & BM_PXP_WFE_B_STG1_5X1_OUT0_LUTOUT5)
+#define BM_PXP_WFE_B_STG1_5X1_OUT0_LUTOUT4 0x00000010
+#define BF_PXP_WFE_B_STG1_5X1_OUT0_LUTOUT4(v) \
+ (((v) << 4) & BM_PXP_WFE_B_STG1_5X1_OUT0_LUTOUT4)
+#define BM_PXP_WFE_B_STG1_5X1_OUT0_LUTOUT3 0x00000008
+#define BF_PXP_WFE_B_STG1_5X1_OUT0_LUTOUT3(v) \
+ (((v) << 3) & BM_PXP_WFE_B_STG1_5X1_OUT0_LUTOUT3)
+#define BM_PXP_WFE_B_STG1_5X1_OUT0_LUTOUT2 0x00000004
+#define BF_PXP_WFE_B_STG1_5X1_OUT0_LUTOUT2(v) \
+ (((v) << 2) & BM_PXP_WFE_B_STG1_5X1_OUT0_LUTOUT2)
+#define BM_PXP_WFE_B_STG1_5X1_OUT0_LUTOUT1 0x00000002
+#define BF_PXP_WFE_B_STG1_5X1_OUT0_LUTOUT1(v) \
+ (((v) << 1) & BM_PXP_WFE_B_STG1_5X1_OUT0_LUTOUT1)
+#define BM_PXP_WFE_B_STG1_5X1_OUT0_LUTOUT0 0x00000001
+#define BF_PXP_WFE_B_STG1_5X1_OUT0_LUTOUT0(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STG1_5X1_OUT0_LUTOUT0)
+
+#define HW_PXP_WFE_B_STG1_5X1_MASKS (0x00002080)
+
+#define BP_PXP_WFE_B_STG1_5X1_MASKS_RSVD0 5
+#define BM_PXP_WFE_B_STG1_5X1_MASKS_RSVD0 0xFFFFFFE0
+#define BF_PXP_WFE_B_STG1_5X1_MASKS_RSVD0(v) \
+ (((v) << 5) & BM_PXP_WFE_B_STG1_5X1_MASKS_RSVD0)
+#define BP_PXP_WFE_B_STG1_5X1_MASKS_MASK0 0
+#define BM_PXP_WFE_B_STG1_5X1_MASKS_MASK0 0x0000001F
+#define BF_PXP_WFE_B_STG1_5X1_MASKS_MASK0(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STG1_5X1_MASKS_MASK0)
+
+#define HW_PXP_WFE_B_STG1_8X1_OUT0_0 (0x00002090)
+
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_0_LUTOUT31 0x80000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_0_LUTOUT31(v) \
+ (((v) << 31) & BM_PXP_WFE_B_STG1_8X1_OUT0_0_LUTOUT31)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_0_LUTOUT30 0x40000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_0_LUTOUT30(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STG1_8X1_OUT0_0_LUTOUT30)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_0_LUTOUT29 0x20000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_0_LUTOUT29(v) \
+ (((v) << 29) & BM_PXP_WFE_B_STG1_8X1_OUT0_0_LUTOUT29)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_0_LUTOUT28 0x10000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_0_LUTOUT28(v) \
+ (((v) << 28) & BM_PXP_WFE_B_STG1_8X1_OUT0_0_LUTOUT28)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_0_LUTOUT27 0x08000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_0_LUTOUT27(v) \
+ (((v) << 27) & BM_PXP_WFE_B_STG1_8X1_OUT0_0_LUTOUT27)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_0_LUTOUT26 0x04000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_0_LUTOUT26(v) \
+ (((v) << 26) & BM_PXP_WFE_B_STG1_8X1_OUT0_0_LUTOUT26)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_0_LUTOUT25 0x02000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_0_LUTOUT25(v) \
+ (((v) << 25) & BM_PXP_WFE_B_STG1_8X1_OUT0_0_LUTOUT25)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_0_LUTOUT24 0x01000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_0_LUTOUT24(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STG1_8X1_OUT0_0_LUTOUT24)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_0_LUTOUT23 0x00800000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_0_LUTOUT23(v) \
+ (((v) << 23) & BM_PXP_WFE_B_STG1_8X1_OUT0_0_LUTOUT23)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_0_LUTOUT22 0x00400000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_0_LUTOUT22(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STG1_8X1_OUT0_0_LUTOUT22)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_0_LUTOUT21 0x00200000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_0_LUTOUT21(v) \
+ (((v) << 21) & BM_PXP_WFE_B_STG1_8X1_OUT0_0_LUTOUT21)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_0_LUTOUT20 0x00100000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_0_LUTOUT20(v) \
+ (((v) << 20) & BM_PXP_WFE_B_STG1_8X1_OUT0_0_LUTOUT20)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_0_LUTOUT19 0x00080000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_0_LUTOUT19(v) \
+ (((v) << 19) & BM_PXP_WFE_B_STG1_8X1_OUT0_0_LUTOUT19)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_0_LUTOUT18 0x00040000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_0_LUTOUT18(v) \
+ (((v) << 18) & BM_PXP_WFE_B_STG1_8X1_OUT0_0_LUTOUT18)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_0_LUTOUT17 0x00020000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_0_LUTOUT17(v) \
+ (((v) << 17) & BM_PXP_WFE_B_STG1_8X1_OUT0_0_LUTOUT17)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_0_LUTOUT16 0x00010000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_0_LUTOUT16(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STG1_8X1_OUT0_0_LUTOUT16)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_0_LUTOUT15 0x00008000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_0_LUTOUT15(v) \
+ (((v) << 15) & BM_PXP_WFE_B_STG1_8X1_OUT0_0_LUTOUT15)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_0_LUTOUT14 0x00004000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_0_LUTOUT14(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STG1_8X1_OUT0_0_LUTOUT14)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_0_LUTOUT13 0x00002000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_0_LUTOUT13(v) \
+ (((v) << 13) & BM_PXP_WFE_B_STG1_8X1_OUT0_0_LUTOUT13)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_0_LUTOUT12 0x00001000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_0_LUTOUT12(v) \
+ (((v) << 12) & BM_PXP_WFE_B_STG1_8X1_OUT0_0_LUTOUT12)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_0_LUTOUT11 0x00000800
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_0_LUTOUT11(v) \
+ (((v) << 11) & BM_PXP_WFE_B_STG1_8X1_OUT0_0_LUTOUT11)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_0_LUTOUT10 0x00000400
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_0_LUTOUT10(v) \
+ (((v) << 10) & BM_PXP_WFE_B_STG1_8X1_OUT0_0_LUTOUT10)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_0_LUTOUT9 0x00000200
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_0_LUTOUT9(v) \
+ (((v) << 9) & BM_PXP_WFE_B_STG1_8X1_OUT0_0_LUTOUT9)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_0_LUTOUT8 0x00000100
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_0_LUTOUT8(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STG1_8X1_OUT0_0_LUTOUT8)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_0_LUTOUT7 0x00000080
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_0_LUTOUT7(v) \
+ (((v) << 7) & BM_PXP_WFE_B_STG1_8X1_OUT0_0_LUTOUT7)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_0_LUTOUT6 0x00000040
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_0_LUTOUT6(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STG1_8X1_OUT0_0_LUTOUT6)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_0_LUTOUT5 0x00000020
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_0_LUTOUT5(v) \
+ (((v) << 5) & BM_PXP_WFE_B_STG1_8X1_OUT0_0_LUTOUT5)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_0_LUTOUT4 0x00000010
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_0_LUTOUT4(v) \
+ (((v) << 4) & BM_PXP_WFE_B_STG1_8X1_OUT0_0_LUTOUT4)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_0_LUTOUT3 0x00000008
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_0_LUTOUT3(v) \
+ (((v) << 3) & BM_PXP_WFE_B_STG1_8X1_OUT0_0_LUTOUT3)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_0_LUTOUT2 0x00000004
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_0_LUTOUT2(v) \
+ (((v) << 2) & BM_PXP_WFE_B_STG1_8X1_OUT0_0_LUTOUT2)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_0_LUTOUT1 0x00000002
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_0_LUTOUT1(v) \
+ (((v) << 1) & BM_PXP_WFE_B_STG1_8X1_OUT0_0_LUTOUT1)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_0_LUTOUT0 0x00000001
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_0_LUTOUT0(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STG1_8X1_OUT0_0_LUTOUT0)
+
+#define HW_PXP_WFE_B_STG1_8X1_OUT0_1 (0x000020a0)
+
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_1_LUTOUT63 0x80000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_1_LUTOUT63(v) \
+ (((v) << 31) & BM_PXP_WFE_B_STG1_8X1_OUT0_1_LUTOUT63)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_1_LUTOUT62 0x40000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_1_LUTOUT62(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STG1_8X1_OUT0_1_LUTOUT62)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_1_LUTOUT61 0x20000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_1_LUTOUT61(v) \
+ (((v) << 29) & BM_PXP_WFE_B_STG1_8X1_OUT0_1_LUTOUT61)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_1_LUTOUT60 0x10000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_1_LUTOUT60(v) \
+ (((v) << 28) & BM_PXP_WFE_B_STG1_8X1_OUT0_1_LUTOUT60)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_1_LUTOUT59 0x08000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_1_LUTOUT59(v) \
+ (((v) << 27) & BM_PXP_WFE_B_STG1_8X1_OUT0_1_LUTOUT59)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_1_LUTOUT58 0x04000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_1_LUTOUT58(v) \
+ (((v) << 26) & BM_PXP_WFE_B_STG1_8X1_OUT0_1_LUTOUT58)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_1_LUTOUT57 0x02000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_1_LUTOUT57(v) \
+ (((v) << 25) & BM_PXP_WFE_B_STG1_8X1_OUT0_1_LUTOUT57)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_1_LUTOUT56 0x01000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_1_LUTOUT56(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STG1_8X1_OUT0_1_LUTOUT56)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_1_LUTOUT55 0x00800000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_1_LUTOUT55(v) \
+ (((v) << 23) & BM_PXP_WFE_B_STG1_8X1_OUT0_1_LUTOUT55)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_1_LUTOUT54 0x00400000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_1_LUTOUT54(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STG1_8X1_OUT0_1_LUTOUT54)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_1_LUTOUT53 0x00200000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_1_LUTOUT53(v) \
+ (((v) << 21) & BM_PXP_WFE_B_STG1_8X1_OUT0_1_LUTOUT53)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_1_LUTOUT52 0x00100000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_1_LUTOUT52(v) \
+ (((v) << 20) & BM_PXP_WFE_B_STG1_8X1_OUT0_1_LUTOUT52)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_1_LUTOUT51 0x00080000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_1_LUTOUT51(v) \
+ (((v) << 19) & BM_PXP_WFE_B_STG1_8X1_OUT0_1_LUTOUT51)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_1_LUTOUT50 0x00040000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_1_LUTOUT50(v) \
+ (((v) << 18) & BM_PXP_WFE_B_STG1_8X1_OUT0_1_LUTOUT50)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_1_LUTOUT49 0x00020000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_1_LUTOUT49(v) \
+ (((v) << 17) & BM_PXP_WFE_B_STG1_8X1_OUT0_1_LUTOUT49)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_1_LUTOUT48 0x00010000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_1_LUTOUT48(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STG1_8X1_OUT0_1_LUTOUT48)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_1_LUTOUT47 0x00008000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_1_LUTOUT47(v) \
+ (((v) << 15) & BM_PXP_WFE_B_STG1_8X1_OUT0_1_LUTOUT47)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_1_LUTOUT46 0x00004000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_1_LUTOUT46(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STG1_8X1_OUT0_1_LUTOUT46)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_1_LUTOUT45 0x00002000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_1_LUTOUT45(v) \
+ (((v) << 13) & BM_PXP_WFE_B_STG1_8X1_OUT0_1_LUTOUT45)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_1_LUTOUT44 0x00001000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_1_LUTOUT44(v) \
+ (((v) << 12) & BM_PXP_WFE_B_STG1_8X1_OUT0_1_LUTOUT44)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_1_LUTOUT43 0x00000800
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_1_LUTOUT43(v) \
+ (((v) << 11) & BM_PXP_WFE_B_STG1_8X1_OUT0_1_LUTOUT43)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_1_LUTOUT42 0x00000400
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_1_LUTOUT42(v) \
+ (((v) << 10) & BM_PXP_WFE_B_STG1_8X1_OUT0_1_LUTOUT42)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_1_LUTOUT41 0x00000200
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_1_LUTOUT41(v) \
+ (((v) << 9) & BM_PXP_WFE_B_STG1_8X1_OUT0_1_LUTOUT41)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_1_LUTOUT40 0x00000100
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_1_LUTOUT40(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STG1_8X1_OUT0_1_LUTOUT40)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_1_LUTOUT39 0x00000080
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_1_LUTOUT39(v) \
+ (((v) << 7) & BM_PXP_WFE_B_STG1_8X1_OUT0_1_LUTOUT39)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_1_LUTOUT38 0x00000040
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_1_LUTOUT38(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STG1_8X1_OUT0_1_LUTOUT38)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_1_LUTOUT37 0x00000020
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_1_LUTOUT37(v) \
+ (((v) << 5) & BM_PXP_WFE_B_STG1_8X1_OUT0_1_LUTOUT37)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_1_LUTOUT36 0x00000010
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_1_LUTOUT36(v) \
+ (((v) << 4) & BM_PXP_WFE_B_STG1_8X1_OUT0_1_LUTOUT36)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_1_LUTOUT35 0x00000008
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_1_LUTOUT35(v) \
+ (((v) << 3) & BM_PXP_WFE_B_STG1_8X1_OUT0_1_LUTOUT35)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_1_LUTOUT34 0x00000004
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_1_LUTOUT34(v) \
+ (((v) << 2) & BM_PXP_WFE_B_STG1_8X1_OUT0_1_LUTOUT34)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_1_LUTOUT33 0x00000002
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_1_LUTOUT33(v) \
+ (((v) << 1) & BM_PXP_WFE_B_STG1_8X1_OUT0_1_LUTOUT33)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_1_LUTOUT32 0x00000001
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_1_LUTOUT32(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STG1_8X1_OUT0_1_LUTOUT32)
+
+#define HW_PXP_WFE_B_STG1_8X1_OUT0_2 (0x000020b0)
+
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_2_LUTOUT95 0x80000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_2_LUTOUT95(v) \
+ (((v) << 31) & BM_PXP_WFE_B_STG1_8X1_OUT0_2_LUTOUT95)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_2_LUTOUT94 0x40000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_2_LUTOUT94(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STG1_8X1_OUT0_2_LUTOUT94)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_2_LUTOUT93 0x20000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_2_LUTOUT93(v) \
+ (((v) << 29) & BM_PXP_WFE_B_STG1_8X1_OUT0_2_LUTOUT93)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_2_LUTOUT92 0x10000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_2_LUTOUT92(v) \
+ (((v) << 28) & BM_PXP_WFE_B_STG1_8X1_OUT0_2_LUTOUT92)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_2_LUTOUT91 0x08000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_2_LUTOUT91(v) \
+ (((v) << 27) & BM_PXP_WFE_B_STG1_8X1_OUT0_2_LUTOUT91)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_2_LUTOUT90 0x04000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_2_LUTOUT90(v) \
+ (((v) << 26) & BM_PXP_WFE_B_STG1_8X1_OUT0_2_LUTOUT90)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_2_LUTOUT89 0x02000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_2_LUTOUT89(v) \
+ (((v) << 25) & BM_PXP_WFE_B_STG1_8X1_OUT0_2_LUTOUT89)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_2_LUTOUT88 0x01000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_2_LUTOUT88(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STG1_8X1_OUT0_2_LUTOUT88)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_2_LUTOUT87 0x00800000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_2_LUTOUT87(v) \
+ (((v) << 23) & BM_PXP_WFE_B_STG1_8X1_OUT0_2_LUTOUT87)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_2_LUTOUT86 0x00400000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_2_LUTOUT86(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STG1_8X1_OUT0_2_LUTOUT86)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_2_LUTOUT85 0x00200000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_2_LUTOUT85(v) \
+ (((v) << 21) & BM_PXP_WFE_B_STG1_8X1_OUT0_2_LUTOUT85)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_2_LUTOUT84 0x00100000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_2_LUTOUT84(v) \
+ (((v) << 20) & BM_PXP_WFE_B_STG1_8X1_OUT0_2_LUTOUT84)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_2_LUTOUT83 0x00080000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_2_LUTOUT83(v) \
+ (((v) << 19) & BM_PXP_WFE_B_STG1_8X1_OUT0_2_LUTOUT83)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_2_LUTOUT82 0x00040000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_2_LUTOUT82(v) \
+ (((v) << 18) & BM_PXP_WFE_B_STG1_8X1_OUT0_2_LUTOUT82)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_2_LUTOUT81 0x00020000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_2_LUTOUT81(v) \
+ (((v) << 17) & BM_PXP_WFE_B_STG1_8X1_OUT0_2_LUTOUT81)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_2_LUTOUT80 0x00010000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_2_LUTOUT80(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STG1_8X1_OUT0_2_LUTOUT80)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_2_LUTOUT79 0x00008000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_2_LUTOUT79(v) \
+ (((v) << 15) & BM_PXP_WFE_B_STG1_8X1_OUT0_2_LUTOUT79)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_2_LUTOUT78 0x00004000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_2_LUTOUT78(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STG1_8X1_OUT0_2_LUTOUT78)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_2_LUTOUT77 0x00002000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_2_LUTOUT77(v) \
+ (((v) << 13) & BM_PXP_WFE_B_STG1_8X1_OUT0_2_LUTOUT77)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_2_LUTOUT76 0x00001000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_2_LUTOUT76(v) \
+ (((v) << 12) & BM_PXP_WFE_B_STG1_8X1_OUT0_2_LUTOUT76)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_2_LUTOUT75 0x00000800
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_2_LUTOUT75(v) \
+ (((v) << 11) & BM_PXP_WFE_B_STG1_8X1_OUT0_2_LUTOUT75)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_2_LUTOUT74 0x00000400
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_2_LUTOUT74(v) \
+ (((v) << 10) & BM_PXP_WFE_B_STG1_8X1_OUT0_2_LUTOUT74)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_2_LUTOUT73 0x00000200
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_2_LUTOUT73(v) \
+ (((v) << 9) & BM_PXP_WFE_B_STG1_8X1_OUT0_2_LUTOUT73)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_2_LUTOUT72 0x00000100
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_2_LUTOUT72(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STG1_8X1_OUT0_2_LUTOUT72)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_2_LUTOUT71 0x00000080
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_2_LUTOUT71(v) \
+ (((v) << 7) & BM_PXP_WFE_B_STG1_8X1_OUT0_2_LUTOUT71)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_2_LUTOUT70 0x00000040
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_2_LUTOUT70(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STG1_8X1_OUT0_2_LUTOUT70)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_2_LUTOUT69 0x00000020
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_2_LUTOUT69(v) \
+ (((v) << 5) & BM_PXP_WFE_B_STG1_8X1_OUT0_2_LUTOUT69)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_2_LUTOUT68 0x00000010
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_2_LUTOUT68(v) \
+ (((v) << 4) & BM_PXP_WFE_B_STG1_8X1_OUT0_2_LUTOUT68)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_2_LUTOUT67 0x00000008
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_2_LUTOUT67(v) \
+ (((v) << 3) & BM_PXP_WFE_B_STG1_8X1_OUT0_2_LUTOUT67)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_2_LUTOUT66 0x00000004
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_2_LUTOUT66(v) \
+ (((v) << 2) & BM_PXP_WFE_B_STG1_8X1_OUT0_2_LUTOUT66)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_2_LUTOUT65 0x00000002
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_2_LUTOUT65(v) \
+ (((v) << 1) & BM_PXP_WFE_B_STG1_8X1_OUT0_2_LUTOUT65)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_2_LUTOUT64 0x00000001
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_2_LUTOUT64(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STG1_8X1_OUT0_2_LUTOUT64)
+
+#define HW_PXP_WFE_B_STG1_8X1_OUT0_3 (0x000020c0)
+
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_3_LUTOUT127 0x80000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_3_LUTOUT127(v) \
+ (((v) << 31) & BM_PXP_WFE_B_STG1_8X1_OUT0_3_LUTOUT127)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_3_LUTOUT126 0x40000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_3_LUTOUT126(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STG1_8X1_OUT0_3_LUTOUT126)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_3_LUTOUT125 0x20000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_3_LUTOUT125(v) \
+ (((v) << 29) & BM_PXP_WFE_B_STG1_8X1_OUT0_3_LUTOUT125)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_3_LUTOUT124 0x10000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_3_LUTOUT124(v) \
+ (((v) << 28) & BM_PXP_WFE_B_STG1_8X1_OUT0_3_LUTOUT124)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_3_LUTOUT123 0x08000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_3_LUTOUT123(v) \
+ (((v) << 27) & BM_PXP_WFE_B_STG1_8X1_OUT0_3_LUTOUT123)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_3_LUTOUT122 0x04000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_3_LUTOUT122(v) \
+ (((v) << 26) & BM_PXP_WFE_B_STG1_8X1_OUT0_3_LUTOUT122)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_3_LUTOUT121 0x02000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_3_LUTOUT121(v) \
+ (((v) << 25) & BM_PXP_WFE_B_STG1_8X1_OUT0_3_LUTOUT121)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_3_LUTOUT120 0x01000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_3_LUTOUT120(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STG1_8X1_OUT0_3_LUTOUT120)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_3_LUTOUT119 0x00800000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_3_LUTOUT119(v) \
+ (((v) << 23) & BM_PXP_WFE_B_STG1_8X1_OUT0_3_LUTOUT119)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_3_LUTOUT118 0x00400000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_3_LUTOUT118(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STG1_8X1_OUT0_3_LUTOUT118)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_3_LUTOUT117 0x00200000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_3_LUTOUT117(v) \
+ (((v) << 21) & BM_PXP_WFE_B_STG1_8X1_OUT0_3_LUTOUT117)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_3_LUTOUT116 0x00100000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_3_LUTOUT116(v) \
+ (((v) << 20) & BM_PXP_WFE_B_STG1_8X1_OUT0_3_LUTOUT116)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_3_LUTOUT115 0x00080000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_3_LUTOUT115(v) \
+ (((v) << 19) & BM_PXP_WFE_B_STG1_8X1_OUT0_3_LUTOUT115)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_3_LUTOUT114 0x00040000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_3_LUTOUT114(v) \
+ (((v) << 18) & BM_PXP_WFE_B_STG1_8X1_OUT0_3_LUTOUT114)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_3_LUTOUT113 0x00020000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_3_LUTOUT113(v) \
+ (((v) << 17) & BM_PXP_WFE_B_STG1_8X1_OUT0_3_LUTOUT113)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_3_LUTOUT112 0x00010000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_3_LUTOUT112(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STG1_8X1_OUT0_3_LUTOUT112)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_3_LUTOUT111 0x00008000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_3_LUTOUT111(v) \
+ (((v) << 15) & BM_PXP_WFE_B_STG1_8X1_OUT0_3_LUTOUT111)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_3_LUTOUT110 0x00004000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_3_LUTOUT110(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STG1_8X1_OUT0_3_LUTOUT110)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_3_LUTOUT109 0x00002000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_3_LUTOUT109(v) \
+ (((v) << 13) & BM_PXP_WFE_B_STG1_8X1_OUT0_3_LUTOUT109)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_3_LUTOUT108 0x00001000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_3_LUTOUT108(v) \
+ (((v) << 12) & BM_PXP_WFE_B_STG1_8X1_OUT0_3_LUTOUT108)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_3_LUTOUT107 0x00000800
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_3_LUTOUT107(v) \
+ (((v) << 11) & BM_PXP_WFE_B_STG1_8X1_OUT0_3_LUTOUT107)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_3_LUTOUT106 0x00000400
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_3_LUTOUT106(v) \
+ (((v) << 10) & BM_PXP_WFE_B_STG1_8X1_OUT0_3_LUTOUT106)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_3_LUTOUT105 0x00000200
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_3_LUTOUT105(v) \
+ (((v) << 9) & BM_PXP_WFE_B_STG1_8X1_OUT0_3_LUTOUT105)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_3_LUTOUT104 0x00000100
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_3_LUTOUT104(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STG1_8X1_OUT0_3_LUTOUT104)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_3_LUTOUT103 0x00000080
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_3_LUTOUT103(v) \
+ (((v) << 7) & BM_PXP_WFE_B_STG1_8X1_OUT0_3_LUTOUT103)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_3_LUTOUT102 0x00000040
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_3_LUTOUT102(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STG1_8X1_OUT0_3_LUTOUT102)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_3_LUTOUT101 0x00000020
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_3_LUTOUT101(v) \
+ (((v) << 5) & BM_PXP_WFE_B_STG1_8X1_OUT0_3_LUTOUT101)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_3_LUTOUT100 0x00000010
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_3_LUTOUT100(v) \
+ (((v) << 4) & BM_PXP_WFE_B_STG1_8X1_OUT0_3_LUTOUT100)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_3_LUTOUT99 0x00000008
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_3_LUTOUT99(v) \
+ (((v) << 3) & BM_PXP_WFE_B_STG1_8X1_OUT0_3_LUTOUT99)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_3_LUTOUT98 0x00000004
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_3_LUTOUT98(v) \
+ (((v) << 2) & BM_PXP_WFE_B_STG1_8X1_OUT0_3_LUTOUT98)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_3_LUTOUT97 0x00000002
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_3_LUTOUT97(v) \
+ (((v) << 1) & BM_PXP_WFE_B_STG1_8X1_OUT0_3_LUTOUT97)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_3_LUTOUT96 0x00000001
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_3_LUTOUT96(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STG1_8X1_OUT0_3_LUTOUT96)
+
+#define HW_PXP_WFE_B_STG1_8X1_OUT0_4 (0x000020d0)
+
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_4_LUTOUT159 0x80000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_4_LUTOUT159(v) \
+ (((v) << 31) & BM_PXP_WFE_B_STG1_8X1_OUT0_4_LUTOUT159)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_4_LUTOUT158 0x40000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_4_LUTOUT158(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STG1_8X1_OUT0_4_LUTOUT158)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_4_LUTOUT157 0x20000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_4_LUTOUT157(v) \
+ (((v) << 29) & BM_PXP_WFE_B_STG1_8X1_OUT0_4_LUTOUT157)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_4_LUTOUT156 0x10000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_4_LUTOUT156(v) \
+ (((v) << 28) & BM_PXP_WFE_B_STG1_8X1_OUT0_4_LUTOUT156)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_4_LUTOUT155 0x08000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_4_LUTOUT155(v) \
+ (((v) << 27) & BM_PXP_WFE_B_STG1_8X1_OUT0_4_LUTOUT155)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_4_LUTOUT154 0x04000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_4_LUTOUT154(v) \
+ (((v) << 26) & BM_PXP_WFE_B_STG1_8X1_OUT0_4_LUTOUT154)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_4_LUTOUT153 0x02000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_4_LUTOUT153(v) \
+ (((v) << 25) & BM_PXP_WFE_B_STG1_8X1_OUT0_4_LUTOUT153)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_4_LUTOUT152 0x01000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_4_LUTOUT152(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STG1_8X1_OUT0_4_LUTOUT152)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_4_LUTOUT151 0x00800000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_4_LUTOUT151(v) \
+ (((v) << 23) & BM_PXP_WFE_B_STG1_8X1_OUT0_4_LUTOUT151)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_4_LUTOUT150 0x00400000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_4_LUTOUT150(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STG1_8X1_OUT0_4_LUTOUT150)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_4_LUTOUT149 0x00200000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_4_LUTOUT149(v) \
+ (((v) << 21) & BM_PXP_WFE_B_STG1_8X1_OUT0_4_LUTOUT149)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_4_LUTOUT148 0x00100000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_4_LUTOUT148(v) \
+ (((v) << 20) & BM_PXP_WFE_B_STG1_8X1_OUT0_4_LUTOUT148)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_4_LUTOUT147 0x00080000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_4_LUTOUT147(v) \
+ (((v) << 19) & BM_PXP_WFE_B_STG1_8X1_OUT0_4_LUTOUT147)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_4_LUTOUT146 0x00040000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_4_LUTOUT146(v) \
+ (((v) << 18) & BM_PXP_WFE_B_STG1_8X1_OUT0_4_LUTOUT146)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_4_LUTOUT145 0x00020000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_4_LUTOUT145(v) \
+ (((v) << 17) & BM_PXP_WFE_B_STG1_8X1_OUT0_4_LUTOUT145)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_4_LUTOUT144 0x00010000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_4_LUTOUT144(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STG1_8X1_OUT0_4_LUTOUT144)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_4_LUTOUT143 0x00008000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_4_LUTOUT143(v) \
+ (((v) << 15) & BM_PXP_WFE_B_STG1_8X1_OUT0_4_LUTOUT143)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_4_LUTOUT142 0x00004000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_4_LUTOUT142(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STG1_8X1_OUT0_4_LUTOUT142)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_4_LUTOUT141 0x00002000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_4_LUTOUT141(v) \
+ (((v) << 13) & BM_PXP_WFE_B_STG1_8X1_OUT0_4_LUTOUT141)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_4_LUTOUT140 0x00001000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_4_LUTOUT140(v) \
+ (((v) << 12) & BM_PXP_WFE_B_STG1_8X1_OUT0_4_LUTOUT140)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_4_LUTOUT139 0x00000800
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_4_LUTOUT139(v) \
+ (((v) << 11) & BM_PXP_WFE_B_STG1_8X1_OUT0_4_LUTOUT139)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_4_LUTOUT138 0x00000400
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_4_LUTOUT138(v) \
+ (((v) << 10) & BM_PXP_WFE_B_STG1_8X1_OUT0_4_LUTOUT138)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_4_LUTOUT137 0x00000200
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_4_LUTOUT137(v) \
+ (((v) << 9) & BM_PXP_WFE_B_STG1_8X1_OUT0_4_LUTOUT137)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_4_LUTOUT136 0x00000100
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_4_LUTOUT136(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STG1_8X1_OUT0_4_LUTOUT136)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_4_LUTOUT135 0x00000080
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_4_LUTOUT135(v) \
+ (((v) << 7) & BM_PXP_WFE_B_STG1_8X1_OUT0_4_LUTOUT135)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_4_LUTOUT134 0x00000040
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_4_LUTOUT134(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STG1_8X1_OUT0_4_LUTOUT134)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_4_LUTOUT133 0x00000020
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_4_LUTOUT133(v) \
+ (((v) << 5) & BM_PXP_WFE_B_STG1_8X1_OUT0_4_LUTOUT133)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_4_LUTOUT132 0x00000010
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_4_LUTOUT132(v) \
+ (((v) << 4) & BM_PXP_WFE_B_STG1_8X1_OUT0_4_LUTOUT132)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_4_LUTOUT131 0x00000008
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_4_LUTOUT131(v) \
+ (((v) << 3) & BM_PXP_WFE_B_STG1_8X1_OUT0_4_LUTOUT131)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_4_LUTOUT130 0x00000004
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_4_LUTOUT130(v) \
+ (((v) << 2) & BM_PXP_WFE_B_STG1_8X1_OUT0_4_LUTOUT130)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_4_LUTOUT129 0x00000002
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_4_LUTOUT129(v) \
+ (((v) << 1) & BM_PXP_WFE_B_STG1_8X1_OUT0_4_LUTOUT129)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_4_LUTOUT128 0x00000001
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_4_LUTOUT128(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STG1_8X1_OUT0_4_LUTOUT128)
+
+#define HW_PXP_WFE_B_STG1_8X1_OUT0_5 (0x000020e0)
+
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_5_LUTOUT191 0x80000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_5_LUTOUT191(v) \
+ (((v) << 31) & BM_PXP_WFE_B_STG1_8X1_OUT0_5_LUTOUT191)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_5_LUTOUT190 0x40000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_5_LUTOUT190(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STG1_8X1_OUT0_5_LUTOUT190)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_5_LUTOUT189 0x20000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_5_LUTOUT189(v) \
+ (((v) << 29) & BM_PXP_WFE_B_STG1_8X1_OUT0_5_LUTOUT189)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_5_LUTOUT188 0x10000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_5_LUTOUT188(v) \
+ (((v) << 28) & BM_PXP_WFE_B_STG1_8X1_OUT0_5_LUTOUT188)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_5_LUTOUT187 0x08000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_5_LUTOUT187(v) \
+ (((v) << 27) & BM_PXP_WFE_B_STG1_8X1_OUT0_5_LUTOUT187)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_5_LUTOUT186 0x04000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_5_LUTOUT186(v) \
+ (((v) << 26) & BM_PXP_WFE_B_STG1_8X1_OUT0_5_LUTOUT186)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_5_LUTOUT185 0x02000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_5_LUTOUT185(v) \
+ (((v) << 25) & BM_PXP_WFE_B_STG1_8X1_OUT0_5_LUTOUT185)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_5_LUTOUT184 0x01000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_5_LUTOUT184(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STG1_8X1_OUT0_5_LUTOUT184)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_5_LUTOUT183 0x00800000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_5_LUTOUT183(v) \
+ (((v) << 23) & BM_PXP_WFE_B_STG1_8X1_OUT0_5_LUTOUT183)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_5_LUTOUT182 0x00400000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_5_LUTOUT182(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STG1_8X1_OUT0_5_LUTOUT182)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_5_LUTOUT181 0x00200000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_5_LUTOUT181(v) \
+ (((v) << 21) & BM_PXP_WFE_B_STG1_8X1_OUT0_5_LUTOUT181)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_5_LUTOUT180 0x00100000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_5_LUTOUT180(v) \
+ (((v) << 20) & BM_PXP_WFE_B_STG1_8X1_OUT0_5_LUTOUT180)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_5_LUTOUT179 0x00080000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_5_LUTOUT179(v) \
+ (((v) << 19) & BM_PXP_WFE_B_STG1_8X1_OUT0_5_LUTOUT179)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_5_LUTOUT178 0x00040000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_5_LUTOUT178(v) \
+ (((v) << 18) & BM_PXP_WFE_B_STG1_8X1_OUT0_5_LUTOUT178)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_5_LUTOUT177 0x00020000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_5_LUTOUT177(v) \
+ (((v) << 17) & BM_PXP_WFE_B_STG1_8X1_OUT0_5_LUTOUT177)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_5_LUTOUT176 0x00010000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_5_LUTOUT176(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STG1_8X1_OUT0_5_LUTOUT176)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_5_LUTOUT175 0x00008000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_5_LUTOUT175(v) \
+ (((v) << 15) & BM_PXP_WFE_B_STG1_8X1_OUT0_5_LUTOUT175)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_5_LUTOUT174 0x00004000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_5_LUTOUT174(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STG1_8X1_OUT0_5_LUTOUT174)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_5_LUTOUT173 0x00002000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_5_LUTOUT173(v) \
+ (((v) << 13) & BM_PXP_WFE_B_STG1_8X1_OUT0_5_LUTOUT173)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_5_LUTOUT172 0x00001000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_5_LUTOUT172(v) \
+ (((v) << 12) & BM_PXP_WFE_B_STG1_8X1_OUT0_5_LUTOUT172)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_5_LUTOUT171 0x00000800
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_5_LUTOUT171(v) \
+ (((v) << 11) & BM_PXP_WFE_B_STG1_8X1_OUT0_5_LUTOUT171)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_5_LUTOUT170 0x00000400
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_5_LUTOUT170(v) \
+ (((v) << 10) & BM_PXP_WFE_B_STG1_8X1_OUT0_5_LUTOUT170)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_5_LUTOUT169 0x00000200
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_5_LUTOUT169(v) \
+ (((v) << 9) & BM_PXP_WFE_B_STG1_8X1_OUT0_5_LUTOUT169)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_5_LUTOUT168 0x00000100
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_5_LUTOUT168(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STG1_8X1_OUT0_5_LUTOUT168)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_5_LUTOUT167 0x00000080
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_5_LUTOUT167(v) \
+ (((v) << 7) & BM_PXP_WFE_B_STG1_8X1_OUT0_5_LUTOUT167)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_5_LUTOUT166 0x00000040
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_5_LUTOUT166(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STG1_8X1_OUT0_5_LUTOUT166)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_5_LUTOUT165 0x00000020
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_5_LUTOUT165(v) \
+ (((v) << 5) & BM_PXP_WFE_B_STG1_8X1_OUT0_5_LUTOUT165)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_5_LUTOUT164 0x00000010
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_5_LUTOUT164(v) \
+ (((v) << 4) & BM_PXP_WFE_B_STG1_8X1_OUT0_5_LUTOUT164)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_5_LUTOUT163 0x00000008
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_5_LUTOUT163(v) \
+ (((v) << 3) & BM_PXP_WFE_B_STG1_8X1_OUT0_5_LUTOUT163)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_5_LUTOUT162 0x00000004
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_5_LUTOUT162(v) \
+ (((v) << 2) & BM_PXP_WFE_B_STG1_8X1_OUT0_5_LUTOUT162)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_5_LUTOUT161 0x00000002
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_5_LUTOUT161(v) \
+ (((v) << 1) & BM_PXP_WFE_B_STG1_8X1_OUT0_5_LUTOUT161)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_5_LUTOUT160 0x00000001
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_5_LUTOUT160(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STG1_8X1_OUT0_5_LUTOUT160)
+
+#define HW_PXP_WFE_B_STG1_8X1_OUT0_6 (0x000020f0)
+
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_6_LUTOUT223 0x80000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_6_LUTOUT223(v) \
+ (((v) << 31) & BM_PXP_WFE_B_STG1_8X1_OUT0_6_LUTOUT223)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_6_LUTOUT222 0x40000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_6_LUTOUT222(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STG1_8X1_OUT0_6_LUTOUT222)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_6_LUTOUT221 0x20000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_6_LUTOUT221(v) \
+ (((v) << 29) & BM_PXP_WFE_B_STG1_8X1_OUT0_6_LUTOUT221)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_6_LUTOUT220 0x10000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_6_LUTOUT220(v) \
+ (((v) << 28) & BM_PXP_WFE_B_STG1_8X1_OUT0_6_LUTOUT220)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_6_LUTOUT219 0x08000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_6_LUTOUT219(v) \
+ (((v) << 27) & BM_PXP_WFE_B_STG1_8X1_OUT0_6_LUTOUT219)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_6_LUTOUT218 0x04000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_6_LUTOUT218(v) \
+ (((v) << 26) & BM_PXP_WFE_B_STG1_8X1_OUT0_6_LUTOUT218)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_6_LUTOUT217 0x02000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_6_LUTOUT217(v) \
+ (((v) << 25) & BM_PXP_WFE_B_STG1_8X1_OUT0_6_LUTOUT217)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_6_LUTOUT216 0x01000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_6_LUTOUT216(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STG1_8X1_OUT0_6_LUTOUT216)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_6_LUTOUT215 0x00800000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_6_LUTOUT215(v) \
+ (((v) << 23) & BM_PXP_WFE_B_STG1_8X1_OUT0_6_LUTOUT215)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_6_LUTOUT214 0x00400000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_6_LUTOUT214(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STG1_8X1_OUT0_6_LUTOUT214)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_6_LUTOUT213 0x00200000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_6_LUTOUT213(v) \
+ (((v) << 21) & BM_PXP_WFE_B_STG1_8X1_OUT0_6_LUTOUT213)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_6_LUTOUT212 0x00100000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_6_LUTOUT212(v) \
+ (((v) << 20) & BM_PXP_WFE_B_STG1_8X1_OUT0_6_LUTOUT212)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_6_LUTOUT211 0x00080000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_6_LUTOUT211(v) \
+ (((v) << 19) & BM_PXP_WFE_B_STG1_8X1_OUT0_6_LUTOUT211)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_6_LUTOUT210 0x00040000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_6_LUTOUT210(v) \
+ (((v) << 18) & BM_PXP_WFE_B_STG1_8X1_OUT0_6_LUTOUT210)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_6_LUTOUT209 0x00020000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_6_LUTOUT209(v) \
+ (((v) << 17) & BM_PXP_WFE_B_STG1_8X1_OUT0_6_LUTOUT209)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_6_LUTOUT208 0x00010000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_6_LUTOUT208(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STG1_8X1_OUT0_6_LUTOUT208)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_6_LUTOUT207 0x00008000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_6_LUTOUT207(v) \
+ (((v) << 15) & BM_PXP_WFE_B_STG1_8X1_OUT0_6_LUTOUT207)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_6_LUTOUT206 0x00004000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_6_LUTOUT206(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STG1_8X1_OUT0_6_LUTOUT206)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_6_LUTOUT205 0x00002000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_6_LUTOUT205(v) \
+ (((v) << 13) & BM_PXP_WFE_B_STG1_8X1_OUT0_6_LUTOUT205)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_6_LUTOUT204 0x00001000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_6_LUTOUT204(v) \
+ (((v) << 12) & BM_PXP_WFE_B_STG1_8X1_OUT0_6_LUTOUT204)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_6_LUTOUT203 0x00000800
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_6_LUTOUT203(v) \
+ (((v) << 11) & BM_PXP_WFE_B_STG1_8X1_OUT0_6_LUTOUT203)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_6_LUTOUT202 0x00000400
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_6_LUTOUT202(v) \
+ (((v) << 10) & BM_PXP_WFE_B_STG1_8X1_OUT0_6_LUTOUT202)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_6_LUTOUT201 0x00000200
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_6_LUTOUT201(v) \
+ (((v) << 9) & BM_PXP_WFE_B_STG1_8X1_OUT0_6_LUTOUT201)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_6_LUTOUT200 0x00000100
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_6_LUTOUT200(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STG1_8X1_OUT0_6_LUTOUT200)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_6_LUTOUT199 0x00000080
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_6_LUTOUT199(v) \
+ (((v) << 7) & BM_PXP_WFE_B_STG1_8X1_OUT0_6_LUTOUT199)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_6_LUTOUT198 0x00000040
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_6_LUTOUT198(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STG1_8X1_OUT0_6_LUTOUT198)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_6_LUTOUT197 0x00000020
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_6_LUTOUT197(v) \
+ (((v) << 5) & BM_PXP_WFE_B_STG1_8X1_OUT0_6_LUTOUT197)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_6_LUTOUT196 0x00000010
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_6_LUTOUT196(v) \
+ (((v) << 4) & BM_PXP_WFE_B_STG1_8X1_OUT0_6_LUTOUT196)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_6_LUTOUT195 0x00000008
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_6_LUTOUT195(v) \
+ (((v) << 3) & BM_PXP_WFE_B_STG1_8X1_OUT0_6_LUTOUT195)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_6_LUTOUT194 0x00000004
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_6_LUTOUT194(v) \
+ (((v) << 2) & BM_PXP_WFE_B_STG1_8X1_OUT0_6_LUTOUT194)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_6_LUTOUT193 0x00000002
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_6_LUTOUT193(v) \
+ (((v) << 1) & BM_PXP_WFE_B_STG1_8X1_OUT0_6_LUTOUT193)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_6_LUTOUT192 0x00000001
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_6_LUTOUT192(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STG1_8X1_OUT0_6_LUTOUT192)
+
+#define HW_PXP_WFE_B_STG1_8X1_OUT0_7 (0x00002100)
+
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_7_LUTOUT255 0x80000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_7_LUTOUT255(v) \
+ (((v) << 31) & BM_PXP_WFE_B_STG1_8X1_OUT0_7_LUTOUT255)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_7_LUTOUT254 0x40000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_7_LUTOUT254(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STG1_8X1_OUT0_7_LUTOUT254)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_7_LUTOUT253 0x20000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_7_LUTOUT253(v) \
+ (((v) << 29) & BM_PXP_WFE_B_STG1_8X1_OUT0_7_LUTOUT253)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_7_LUTOUT252 0x10000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_7_LUTOUT252(v) \
+ (((v) << 28) & BM_PXP_WFE_B_STG1_8X1_OUT0_7_LUTOUT252)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_7_LUTOUT251 0x08000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_7_LUTOUT251(v) \
+ (((v) << 27) & BM_PXP_WFE_B_STG1_8X1_OUT0_7_LUTOUT251)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_7_LUTOUT250 0x04000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_7_LUTOUT250(v) \
+ (((v) << 26) & BM_PXP_WFE_B_STG1_8X1_OUT0_7_LUTOUT250)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_7_LUTOUT249 0x02000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_7_LUTOUT249(v) \
+ (((v) << 25) & BM_PXP_WFE_B_STG1_8X1_OUT0_7_LUTOUT249)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_7_LUTOUT248 0x01000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_7_LUTOUT248(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STG1_8X1_OUT0_7_LUTOUT248)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_7_LUTOUT247 0x00800000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_7_LUTOUT247(v) \
+ (((v) << 23) & BM_PXP_WFE_B_STG1_8X1_OUT0_7_LUTOUT247)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_7_LUTOUT246 0x00400000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_7_LUTOUT246(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STG1_8X1_OUT0_7_LUTOUT246)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_7_LUTOUT245 0x00200000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_7_LUTOUT245(v) \
+ (((v) << 21) & BM_PXP_WFE_B_STG1_8X1_OUT0_7_LUTOUT245)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_7_LUTOUT244 0x00100000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_7_LUTOUT244(v) \
+ (((v) << 20) & BM_PXP_WFE_B_STG1_8X1_OUT0_7_LUTOUT244)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_7_LUTOUT243 0x00080000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_7_LUTOUT243(v) \
+ (((v) << 19) & BM_PXP_WFE_B_STG1_8X1_OUT0_7_LUTOUT243)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_7_LUTOUT242 0x00040000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_7_LUTOUT242(v) \
+ (((v) << 18) & BM_PXP_WFE_B_STG1_8X1_OUT0_7_LUTOUT242)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_7_LUTOUT241 0x00020000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_7_LUTOUT241(v) \
+ (((v) << 17) & BM_PXP_WFE_B_STG1_8X1_OUT0_7_LUTOUT241)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_7_LUTOUT240 0x00010000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_7_LUTOUT240(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STG1_8X1_OUT0_7_LUTOUT240)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_7_LUTOUT239 0x00008000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_7_LUTOUT239(v) \
+ (((v) << 15) & BM_PXP_WFE_B_STG1_8X1_OUT0_7_LUTOUT239)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_7_LUTOUT238 0x00004000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_7_LUTOUT238(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STG1_8X1_OUT0_7_LUTOUT238)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_7_LUTOUT237 0x00002000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_7_LUTOUT237(v) \
+ (((v) << 13) & BM_PXP_WFE_B_STG1_8X1_OUT0_7_LUTOUT237)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_7_LUTOUT236 0x00001000
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_7_LUTOUT236(v) \
+ (((v) << 12) & BM_PXP_WFE_B_STG1_8X1_OUT0_7_LUTOUT236)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_7_LUTOUT235 0x00000800
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_7_LUTOUT235(v) \
+ (((v) << 11) & BM_PXP_WFE_B_STG1_8X1_OUT0_7_LUTOUT235)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_7_LUTOUT234 0x00000400
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_7_LUTOUT234(v) \
+ (((v) << 10) & BM_PXP_WFE_B_STG1_8X1_OUT0_7_LUTOUT234)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_7_LUTOUT233 0x00000200
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_7_LUTOUT233(v) \
+ (((v) << 9) & BM_PXP_WFE_B_STG1_8X1_OUT0_7_LUTOUT233)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_7_LUTOUT232 0x00000100
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_7_LUTOUT232(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STG1_8X1_OUT0_7_LUTOUT232)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_7_LUTOUT231 0x00000080
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_7_LUTOUT231(v) \
+ (((v) << 7) & BM_PXP_WFE_B_STG1_8X1_OUT0_7_LUTOUT231)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_7_LUTOUT230 0x00000040
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_7_LUTOUT230(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STG1_8X1_OUT0_7_LUTOUT230)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_7_LUTOUT229 0x00000020
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_7_LUTOUT229(v) \
+ (((v) << 5) & BM_PXP_WFE_B_STG1_8X1_OUT0_7_LUTOUT229)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_7_LUTOUT228 0x00000010
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_7_LUTOUT228(v) \
+ (((v) << 4) & BM_PXP_WFE_B_STG1_8X1_OUT0_7_LUTOUT228)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_7_LUTOUT227 0x00000008
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_7_LUTOUT227(v) \
+ (((v) << 3) & BM_PXP_WFE_B_STG1_8X1_OUT0_7_LUTOUT227)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_7_LUTOUT226 0x00000004
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_7_LUTOUT226(v) \
+ (((v) << 2) & BM_PXP_WFE_B_STG1_8X1_OUT0_7_LUTOUT226)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_7_LUTOUT225 0x00000002
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_7_LUTOUT225(v) \
+ (((v) << 1) & BM_PXP_WFE_B_STG1_8X1_OUT0_7_LUTOUT225)
+#define BM_PXP_WFE_B_STG1_8X1_OUT0_7_LUTOUT224 0x00000001
+#define BF_PXP_WFE_B_STG1_8X1_OUT0_7_LUTOUT224(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STG1_8X1_OUT0_7_LUTOUT224)
+
+#define HW_PXP_WFE_B_STG1_8X1_OUT1_0 (0x00002110)
+
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_0_LUTOUT31 0x80000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_0_LUTOUT31(v) \
+ (((v) << 31) & BM_PXP_WFE_B_STG1_8X1_OUT1_0_LUTOUT31)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_0_LUTOUT30 0x40000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_0_LUTOUT30(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STG1_8X1_OUT1_0_LUTOUT30)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_0_LUTOUT29 0x20000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_0_LUTOUT29(v) \
+ (((v) << 29) & BM_PXP_WFE_B_STG1_8X1_OUT1_0_LUTOUT29)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_0_LUTOUT28 0x10000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_0_LUTOUT28(v) \
+ (((v) << 28) & BM_PXP_WFE_B_STG1_8X1_OUT1_0_LUTOUT28)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_0_LUTOUT27 0x08000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_0_LUTOUT27(v) \
+ (((v) << 27) & BM_PXP_WFE_B_STG1_8X1_OUT1_0_LUTOUT27)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_0_LUTOUT26 0x04000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_0_LUTOUT26(v) \
+ (((v) << 26) & BM_PXP_WFE_B_STG1_8X1_OUT1_0_LUTOUT26)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_0_LUTOUT25 0x02000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_0_LUTOUT25(v) \
+ (((v) << 25) & BM_PXP_WFE_B_STG1_8X1_OUT1_0_LUTOUT25)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_0_LUTOUT24 0x01000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_0_LUTOUT24(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STG1_8X1_OUT1_0_LUTOUT24)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_0_LUTOUT23 0x00800000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_0_LUTOUT23(v) \
+ (((v) << 23) & BM_PXP_WFE_B_STG1_8X1_OUT1_0_LUTOUT23)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_0_LUTOUT22 0x00400000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_0_LUTOUT22(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STG1_8X1_OUT1_0_LUTOUT22)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_0_LUTOUT21 0x00200000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_0_LUTOUT21(v) \
+ (((v) << 21) & BM_PXP_WFE_B_STG1_8X1_OUT1_0_LUTOUT21)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_0_LUTOUT20 0x00100000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_0_LUTOUT20(v) \
+ (((v) << 20) & BM_PXP_WFE_B_STG1_8X1_OUT1_0_LUTOUT20)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_0_LUTOUT19 0x00080000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_0_LUTOUT19(v) \
+ (((v) << 19) & BM_PXP_WFE_B_STG1_8X1_OUT1_0_LUTOUT19)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_0_LUTOUT18 0x00040000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_0_LUTOUT18(v) \
+ (((v) << 18) & BM_PXP_WFE_B_STG1_8X1_OUT1_0_LUTOUT18)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_0_LUTOUT17 0x00020000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_0_LUTOUT17(v) \
+ (((v) << 17) & BM_PXP_WFE_B_STG1_8X1_OUT1_0_LUTOUT17)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_0_LUTOUT16 0x00010000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_0_LUTOUT16(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STG1_8X1_OUT1_0_LUTOUT16)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_0_LUTOUT15 0x00008000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_0_LUTOUT15(v) \
+ (((v) << 15) & BM_PXP_WFE_B_STG1_8X1_OUT1_0_LUTOUT15)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_0_LUTOUT14 0x00004000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_0_LUTOUT14(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STG1_8X1_OUT1_0_LUTOUT14)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_0_LUTOUT13 0x00002000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_0_LUTOUT13(v) \
+ (((v) << 13) & BM_PXP_WFE_B_STG1_8X1_OUT1_0_LUTOUT13)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_0_LUTOUT12 0x00001000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_0_LUTOUT12(v) \
+ (((v) << 12) & BM_PXP_WFE_B_STG1_8X1_OUT1_0_LUTOUT12)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_0_LUTOUT11 0x00000800
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_0_LUTOUT11(v) \
+ (((v) << 11) & BM_PXP_WFE_B_STG1_8X1_OUT1_0_LUTOUT11)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_0_LUTOUT10 0x00000400
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_0_LUTOUT10(v) \
+ (((v) << 10) & BM_PXP_WFE_B_STG1_8X1_OUT1_0_LUTOUT10)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_0_LUTOUT9 0x00000200
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_0_LUTOUT9(v) \
+ (((v) << 9) & BM_PXP_WFE_B_STG1_8X1_OUT1_0_LUTOUT9)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_0_LUTOUT8 0x00000100
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_0_LUTOUT8(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STG1_8X1_OUT1_0_LUTOUT8)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_0_LUTOUT7 0x00000080
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_0_LUTOUT7(v) \
+ (((v) << 7) & BM_PXP_WFE_B_STG1_8X1_OUT1_0_LUTOUT7)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_0_LUTOUT6 0x00000040
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_0_LUTOUT6(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STG1_8X1_OUT1_0_LUTOUT6)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_0_LUTOUT5 0x00000020
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_0_LUTOUT5(v) \
+ (((v) << 5) & BM_PXP_WFE_B_STG1_8X1_OUT1_0_LUTOUT5)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_0_LUTOUT4 0x00000010
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_0_LUTOUT4(v) \
+ (((v) << 4) & BM_PXP_WFE_B_STG1_8X1_OUT1_0_LUTOUT4)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_0_LUTOUT3 0x00000008
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_0_LUTOUT3(v) \
+ (((v) << 3) & BM_PXP_WFE_B_STG1_8X1_OUT1_0_LUTOUT3)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_0_LUTOUT2 0x00000004
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_0_LUTOUT2(v) \
+ (((v) << 2) & BM_PXP_WFE_B_STG1_8X1_OUT1_0_LUTOUT2)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_0_LUTOUT1 0x00000002
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_0_LUTOUT1(v) \
+ (((v) << 1) & BM_PXP_WFE_B_STG1_8X1_OUT1_0_LUTOUT1)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_0_LUTOUT0 0x00000001
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_0_LUTOUT0(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STG1_8X1_OUT1_0_LUTOUT0)
+
+#define HW_PXP_WFE_B_STG1_8X1_OUT1_1 (0x00002120)
+
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_1_LUTOUT63 0x80000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_1_LUTOUT63(v) \
+ (((v) << 31) & BM_PXP_WFE_B_STG1_8X1_OUT1_1_LUTOUT63)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_1_LUTOUT62 0x40000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_1_LUTOUT62(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STG1_8X1_OUT1_1_LUTOUT62)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_1_LUTOUT61 0x20000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_1_LUTOUT61(v) \
+ (((v) << 29) & BM_PXP_WFE_B_STG1_8X1_OUT1_1_LUTOUT61)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_1_LUTOUT60 0x10000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_1_LUTOUT60(v) \
+ (((v) << 28) & BM_PXP_WFE_B_STG1_8X1_OUT1_1_LUTOUT60)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_1_LUTOUT59 0x08000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_1_LUTOUT59(v) \
+ (((v) << 27) & BM_PXP_WFE_B_STG1_8X1_OUT1_1_LUTOUT59)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_1_LUTOUT58 0x04000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_1_LUTOUT58(v) \
+ (((v) << 26) & BM_PXP_WFE_B_STG1_8X1_OUT1_1_LUTOUT58)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_1_LUTOUT57 0x02000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_1_LUTOUT57(v) \
+ (((v) << 25) & BM_PXP_WFE_B_STG1_8X1_OUT1_1_LUTOUT57)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_1_LUTOUT56 0x01000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_1_LUTOUT56(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STG1_8X1_OUT1_1_LUTOUT56)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_1_LUTOUT55 0x00800000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_1_LUTOUT55(v) \
+ (((v) << 23) & BM_PXP_WFE_B_STG1_8X1_OUT1_1_LUTOUT55)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_1_LUTOUT54 0x00400000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_1_LUTOUT54(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STG1_8X1_OUT1_1_LUTOUT54)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_1_LUTOUT53 0x00200000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_1_LUTOUT53(v) \
+ (((v) << 21) & BM_PXP_WFE_B_STG1_8X1_OUT1_1_LUTOUT53)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_1_LUTOUT52 0x00100000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_1_LUTOUT52(v) \
+ (((v) << 20) & BM_PXP_WFE_B_STG1_8X1_OUT1_1_LUTOUT52)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_1_LUTOUT51 0x00080000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_1_LUTOUT51(v) \
+ (((v) << 19) & BM_PXP_WFE_B_STG1_8X1_OUT1_1_LUTOUT51)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_1_LUTOUT50 0x00040000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_1_LUTOUT50(v) \
+ (((v) << 18) & BM_PXP_WFE_B_STG1_8X1_OUT1_1_LUTOUT50)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_1_LUTOUT49 0x00020000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_1_LUTOUT49(v) \
+ (((v) << 17) & BM_PXP_WFE_B_STG1_8X1_OUT1_1_LUTOUT49)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_1_LUTOUT48 0x00010000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_1_LUTOUT48(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STG1_8X1_OUT1_1_LUTOUT48)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_1_LUTOUT47 0x00008000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_1_LUTOUT47(v) \
+ (((v) << 15) & BM_PXP_WFE_B_STG1_8X1_OUT1_1_LUTOUT47)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_1_LUTOUT46 0x00004000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_1_LUTOUT46(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STG1_8X1_OUT1_1_LUTOUT46)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_1_LUTOUT45 0x00002000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_1_LUTOUT45(v) \
+ (((v) << 13) & BM_PXP_WFE_B_STG1_8X1_OUT1_1_LUTOUT45)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_1_LUTOUT44 0x00001000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_1_LUTOUT44(v) \
+ (((v) << 12) & BM_PXP_WFE_B_STG1_8X1_OUT1_1_LUTOUT44)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_1_LUTOUT43 0x00000800
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_1_LUTOUT43(v) \
+ (((v) << 11) & BM_PXP_WFE_B_STG1_8X1_OUT1_1_LUTOUT43)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_1_LUTOUT42 0x00000400
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_1_LUTOUT42(v) \
+ (((v) << 10) & BM_PXP_WFE_B_STG1_8X1_OUT1_1_LUTOUT42)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_1_LUTOUT41 0x00000200
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_1_LUTOUT41(v) \
+ (((v) << 9) & BM_PXP_WFE_B_STG1_8X1_OUT1_1_LUTOUT41)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_1_LUTOUT40 0x00000100
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_1_LUTOUT40(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STG1_8X1_OUT1_1_LUTOUT40)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_1_LUTOUT39 0x00000080
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_1_LUTOUT39(v) \
+ (((v) << 7) & BM_PXP_WFE_B_STG1_8X1_OUT1_1_LUTOUT39)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_1_LUTOUT38 0x00000040
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_1_LUTOUT38(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STG1_8X1_OUT1_1_LUTOUT38)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_1_LUTOUT37 0x00000020
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_1_LUTOUT37(v) \
+ (((v) << 5) & BM_PXP_WFE_B_STG1_8X1_OUT1_1_LUTOUT37)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_1_LUTOUT36 0x00000010
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_1_LUTOUT36(v) \
+ (((v) << 4) & BM_PXP_WFE_B_STG1_8X1_OUT1_1_LUTOUT36)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_1_LUTOUT35 0x00000008
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_1_LUTOUT35(v) \
+ (((v) << 3) & BM_PXP_WFE_B_STG1_8X1_OUT1_1_LUTOUT35)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_1_LUTOUT34 0x00000004
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_1_LUTOUT34(v) \
+ (((v) << 2) & BM_PXP_WFE_B_STG1_8X1_OUT1_1_LUTOUT34)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_1_LUTOUT33 0x00000002
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_1_LUTOUT33(v) \
+ (((v) << 1) & BM_PXP_WFE_B_STG1_8X1_OUT1_1_LUTOUT33)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_1_LUTOUT32 0x00000001
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_1_LUTOUT32(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STG1_8X1_OUT1_1_LUTOUT32)
+
+#define HW_PXP_WFE_B_STG1_8X1_OUT1_2 (0x00002130)
+
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_2_LUTOUT95 0x80000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_2_LUTOUT95(v) \
+ (((v) << 31) & BM_PXP_WFE_B_STG1_8X1_OUT1_2_LUTOUT95)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_2_LUTOUT94 0x40000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_2_LUTOUT94(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STG1_8X1_OUT1_2_LUTOUT94)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_2_LUTOUT93 0x20000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_2_LUTOUT93(v) \
+ (((v) << 29) & BM_PXP_WFE_B_STG1_8X1_OUT1_2_LUTOUT93)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_2_LUTOUT92 0x10000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_2_LUTOUT92(v) \
+ (((v) << 28) & BM_PXP_WFE_B_STG1_8X1_OUT1_2_LUTOUT92)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_2_LUTOUT91 0x08000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_2_LUTOUT91(v) \
+ (((v) << 27) & BM_PXP_WFE_B_STG1_8X1_OUT1_2_LUTOUT91)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_2_LUTOUT90 0x04000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_2_LUTOUT90(v) \
+ (((v) << 26) & BM_PXP_WFE_B_STG1_8X1_OUT1_2_LUTOUT90)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_2_LUTOUT89 0x02000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_2_LUTOUT89(v) \
+ (((v) << 25) & BM_PXP_WFE_B_STG1_8X1_OUT1_2_LUTOUT89)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_2_LUTOUT88 0x01000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_2_LUTOUT88(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STG1_8X1_OUT1_2_LUTOUT88)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_2_LUTOUT87 0x00800000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_2_LUTOUT87(v) \
+ (((v) << 23) & BM_PXP_WFE_B_STG1_8X1_OUT1_2_LUTOUT87)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_2_LUTOUT86 0x00400000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_2_LUTOUT86(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STG1_8X1_OUT1_2_LUTOUT86)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_2_LUTOUT85 0x00200000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_2_LUTOUT85(v) \
+ (((v) << 21) & BM_PXP_WFE_B_STG1_8X1_OUT1_2_LUTOUT85)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_2_LUTOUT84 0x00100000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_2_LUTOUT84(v) \
+ (((v) << 20) & BM_PXP_WFE_B_STG1_8X1_OUT1_2_LUTOUT84)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_2_LUTOUT83 0x00080000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_2_LUTOUT83(v) \
+ (((v) << 19) & BM_PXP_WFE_B_STG1_8X1_OUT1_2_LUTOUT83)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_2_LUTOUT82 0x00040000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_2_LUTOUT82(v) \
+ (((v) << 18) & BM_PXP_WFE_B_STG1_8X1_OUT1_2_LUTOUT82)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_2_LUTOUT81 0x00020000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_2_LUTOUT81(v) \
+ (((v) << 17) & BM_PXP_WFE_B_STG1_8X1_OUT1_2_LUTOUT81)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_2_LUTOUT80 0x00010000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_2_LUTOUT80(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STG1_8X1_OUT1_2_LUTOUT80)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_2_LUTOUT79 0x00008000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_2_LUTOUT79(v) \
+ (((v) << 15) & BM_PXP_WFE_B_STG1_8X1_OUT1_2_LUTOUT79)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_2_LUTOUT78 0x00004000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_2_LUTOUT78(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STG1_8X1_OUT1_2_LUTOUT78)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_2_LUTOUT77 0x00002000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_2_LUTOUT77(v) \
+ (((v) << 13) & BM_PXP_WFE_B_STG1_8X1_OUT1_2_LUTOUT77)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_2_LUTOUT76 0x00001000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_2_LUTOUT76(v) \
+ (((v) << 12) & BM_PXP_WFE_B_STG1_8X1_OUT1_2_LUTOUT76)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_2_LUTOUT75 0x00000800
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_2_LUTOUT75(v) \
+ (((v) << 11) & BM_PXP_WFE_B_STG1_8X1_OUT1_2_LUTOUT75)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_2_LUTOUT74 0x00000400
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_2_LUTOUT74(v) \
+ (((v) << 10) & BM_PXP_WFE_B_STG1_8X1_OUT1_2_LUTOUT74)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_2_LUTOUT73 0x00000200
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_2_LUTOUT73(v) \
+ (((v) << 9) & BM_PXP_WFE_B_STG1_8X1_OUT1_2_LUTOUT73)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_2_LUTOUT72 0x00000100
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_2_LUTOUT72(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STG1_8X1_OUT1_2_LUTOUT72)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_2_LUTOUT71 0x00000080
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_2_LUTOUT71(v) \
+ (((v) << 7) & BM_PXP_WFE_B_STG1_8X1_OUT1_2_LUTOUT71)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_2_LUTOUT70 0x00000040
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_2_LUTOUT70(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STG1_8X1_OUT1_2_LUTOUT70)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_2_LUTOUT69 0x00000020
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_2_LUTOUT69(v) \
+ (((v) << 5) & BM_PXP_WFE_B_STG1_8X1_OUT1_2_LUTOUT69)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_2_LUTOUT68 0x00000010
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_2_LUTOUT68(v) \
+ (((v) << 4) & BM_PXP_WFE_B_STG1_8X1_OUT1_2_LUTOUT68)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_2_LUTOUT67 0x00000008
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_2_LUTOUT67(v) \
+ (((v) << 3) & BM_PXP_WFE_B_STG1_8X1_OUT1_2_LUTOUT67)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_2_LUTOUT66 0x00000004
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_2_LUTOUT66(v) \
+ (((v) << 2) & BM_PXP_WFE_B_STG1_8X1_OUT1_2_LUTOUT66)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_2_LUTOUT65 0x00000002
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_2_LUTOUT65(v) \
+ (((v) << 1) & BM_PXP_WFE_B_STG1_8X1_OUT1_2_LUTOUT65)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_2_LUTOUT64 0x00000001
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_2_LUTOUT64(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STG1_8X1_OUT1_2_LUTOUT64)
+
+#define HW_PXP_WFE_B_STG1_8X1_OUT1_3 (0x00002140)
+
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_3_LUTOUT127 0x80000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_3_LUTOUT127(v) \
+ (((v) << 31) & BM_PXP_WFE_B_STG1_8X1_OUT1_3_LUTOUT127)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_3_LUTOUT126 0x40000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_3_LUTOUT126(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STG1_8X1_OUT1_3_LUTOUT126)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_3_LUTOUT125 0x20000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_3_LUTOUT125(v) \
+ (((v) << 29) & BM_PXP_WFE_B_STG1_8X1_OUT1_3_LUTOUT125)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_3_LUTOUT124 0x10000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_3_LUTOUT124(v) \
+ (((v) << 28) & BM_PXP_WFE_B_STG1_8X1_OUT1_3_LUTOUT124)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_3_LUTOUT123 0x08000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_3_LUTOUT123(v) \
+ (((v) << 27) & BM_PXP_WFE_B_STG1_8X1_OUT1_3_LUTOUT123)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_3_LUTOUT122 0x04000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_3_LUTOUT122(v) \
+ (((v) << 26) & BM_PXP_WFE_B_STG1_8X1_OUT1_3_LUTOUT122)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_3_LUTOUT121 0x02000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_3_LUTOUT121(v) \
+ (((v) << 25) & BM_PXP_WFE_B_STG1_8X1_OUT1_3_LUTOUT121)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_3_LUTOUT120 0x01000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_3_LUTOUT120(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STG1_8X1_OUT1_3_LUTOUT120)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_3_LUTOUT119 0x00800000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_3_LUTOUT119(v) \
+ (((v) << 23) & BM_PXP_WFE_B_STG1_8X1_OUT1_3_LUTOUT119)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_3_LUTOUT118 0x00400000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_3_LUTOUT118(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STG1_8X1_OUT1_3_LUTOUT118)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_3_LUTOUT117 0x00200000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_3_LUTOUT117(v) \
+ (((v) << 21) & BM_PXP_WFE_B_STG1_8X1_OUT1_3_LUTOUT117)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_3_LUTOUT116 0x00100000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_3_LUTOUT116(v) \
+ (((v) << 20) & BM_PXP_WFE_B_STG1_8X1_OUT1_3_LUTOUT116)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_3_LUTOUT115 0x00080000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_3_LUTOUT115(v) \
+ (((v) << 19) & BM_PXP_WFE_B_STG1_8X1_OUT1_3_LUTOUT115)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_3_LUTOUT114 0x00040000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_3_LUTOUT114(v) \
+ (((v) << 18) & BM_PXP_WFE_B_STG1_8X1_OUT1_3_LUTOUT114)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_3_LUTOUT113 0x00020000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_3_LUTOUT113(v) \
+ (((v) << 17) & BM_PXP_WFE_B_STG1_8X1_OUT1_3_LUTOUT113)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_3_LUTOUT112 0x00010000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_3_LUTOUT112(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STG1_8X1_OUT1_3_LUTOUT112)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_3_LUTOUT111 0x00008000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_3_LUTOUT111(v) \
+ (((v) << 15) & BM_PXP_WFE_B_STG1_8X1_OUT1_3_LUTOUT111)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_3_LUTOUT110 0x00004000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_3_LUTOUT110(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STG1_8X1_OUT1_3_LUTOUT110)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_3_LUTOUT109 0x00002000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_3_LUTOUT109(v) \
+ (((v) << 13) & BM_PXP_WFE_B_STG1_8X1_OUT1_3_LUTOUT109)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_3_LUTOUT108 0x00001000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_3_LUTOUT108(v) \
+ (((v) << 12) & BM_PXP_WFE_B_STG1_8X1_OUT1_3_LUTOUT108)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_3_LUTOUT107 0x00000800
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_3_LUTOUT107(v) \
+ (((v) << 11) & BM_PXP_WFE_B_STG1_8X1_OUT1_3_LUTOUT107)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_3_LUTOUT106 0x00000400
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_3_LUTOUT106(v) \
+ (((v) << 10) & BM_PXP_WFE_B_STG1_8X1_OUT1_3_LUTOUT106)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_3_LUTOUT105 0x00000200
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_3_LUTOUT105(v) \
+ (((v) << 9) & BM_PXP_WFE_B_STG1_8X1_OUT1_3_LUTOUT105)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_3_LUTOUT104 0x00000100
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_3_LUTOUT104(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STG1_8X1_OUT1_3_LUTOUT104)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_3_LUTOUT103 0x00000080
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_3_LUTOUT103(v) \
+ (((v) << 7) & BM_PXP_WFE_B_STG1_8X1_OUT1_3_LUTOUT103)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_3_LUTOUT102 0x00000040
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_3_LUTOUT102(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STG1_8X1_OUT1_3_LUTOUT102)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_3_LUTOUT101 0x00000020
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_3_LUTOUT101(v) \
+ (((v) << 5) & BM_PXP_WFE_B_STG1_8X1_OUT1_3_LUTOUT101)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_3_LUTOUT100 0x00000010
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_3_LUTOUT100(v) \
+ (((v) << 4) & BM_PXP_WFE_B_STG1_8X1_OUT1_3_LUTOUT100)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_3_LUTOUT99 0x00000008
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_3_LUTOUT99(v) \
+ (((v) << 3) & BM_PXP_WFE_B_STG1_8X1_OUT1_3_LUTOUT99)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_3_LUTOUT98 0x00000004
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_3_LUTOUT98(v) \
+ (((v) << 2) & BM_PXP_WFE_B_STG1_8X1_OUT1_3_LUTOUT98)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_3_LUTOUT97 0x00000002
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_3_LUTOUT97(v) \
+ (((v) << 1) & BM_PXP_WFE_B_STG1_8X1_OUT1_3_LUTOUT97)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_3_LUTOUT96 0x00000001
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_3_LUTOUT96(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STG1_8X1_OUT1_3_LUTOUT96)
+
+#define HW_PXP_WFE_B_STG1_8X1_OUT1_4 (0x00002150)
+
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_4_LUTOUT159 0x80000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_4_LUTOUT159(v) \
+ (((v) << 31) & BM_PXP_WFE_B_STG1_8X1_OUT1_4_LUTOUT159)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_4_LUTOUT158 0x40000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_4_LUTOUT158(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STG1_8X1_OUT1_4_LUTOUT158)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_4_LUTOUT157 0x20000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_4_LUTOUT157(v) \
+ (((v) << 29) & BM_PXP_WFE_B_STG1_8X1_OUT1_4_LUTOUT157)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_4_LUTOUT156 0x10000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_4_LUTOUT156(v) \
+ (((v) << 28) & BM_PXP_WFE_B_STG1_8X1_OUT1_4_LUTOUT156)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_4_LUTOUT155 0x08000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_4_LUTOUT155(v) \
+ (((v) << 27) & BM_PXP_WFE_B_STG1_8X1_OUT1_4_LUTOUT155)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_4_LUTOUT154 0x04000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_4_LUTOUT154(v) \
+ (((v) << 26) & BM_PXP_WFE_B_STG1_8X1_OUT1_4_LUTOUT154)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_4_LUTOUT153 0x02000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_4_LUTOUT153(v) \
+ (((v) << 25) & BM_PXP_WFE_B_STG1_8X1_OUT1_4_LUTOUT153)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_4_LUTOUT152 0x01000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_4_LUTOUT152(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STG1_8X1_OUT1_4_LUTOUT152)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_4_LUTOUT151 0x00800000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_4_LUTOUT151(v) \
+ (((v) << 23) & BM_PXP_WFE_B_STG1_8X1_OUT1_4_LUTOUT151)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_4_LUTOUT150 0x00400000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_4_LUTOUT150(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STG1_8X1_OUT1_4_LUTOUT150)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_4_LUTOUT149 0x00200000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_4_LUTOUT149(v) \
+ (((v) << 21) & BM_PXP_WFE_B_STG1_8X1_OUT1_4_LUTOUT149)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_4_LUTOUT148 0x00100000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_4_LUTOUT148(v) \
+ (((v) << 20) & BM_PXP_WFE_B_STG1_8X1_OUT1_4_LUTOUT148)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_4_LUTOUT147 0x00080000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_4_LUTOUT147(v) \
+ (((v) << 19) & BM_PXP_WFE_B_STG1_8X1_OUT1_4_LUTOUT147)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_4_LUTOUT146 0x00040000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_4_LUTOUT146(v) \
+ (((v) << 18) & BM_PXP_WFE_B_STG1_8X1_OUT1_4_LUTOUT146)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_4_LUTOUT145 0x00020000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_4_LUTOUT145(v) \
+ (((v) << 17) & BM_PXP_WFE_B_STG1_8X1_OUT1_4_LUTOUT145)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_4_LUTOUT144 0x00010000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_4_LUTOUT144(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STG1_8X1_OUT1_4_LUTOUT144)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_4_LUTOUT143 0x00008000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_4_LUTOUT143(v) \
+ (((v) << 15) & BM_PXP_WFE_B_STG1_8X1_OUT1_4_LUTOUT143)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_4_LUTOUT142 0x00004000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_4_LUTOUT142(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STG1_8X1_OUT1_4_LUTOUT142)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_4_LUTOUT141 0x00002000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_4_LUTOUT141(v) \
+ (((v) << 13) & BM_PXP_WFE_B_STG1_8X1_OUT1_4_LUTOUT141)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_4_LUTOUT140 0x00001000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_4_LUTOUT140(v) \
+ (((v) << 12) & BM_PXP_WFE_B_STG1_8X1_OUT1_4_LUTOUT140)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_4_LUTOUT139 0x00000800
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_4_LUTOUT139(v) \
+ (((v) << 11) & BM_PXP_WFE_B_STG1_8X1_OUT1_4_LUTOUT139)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_4_LUTOUT138 0x00000400
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_4_LUTOUT138(v) \
+ (((v) << 10) & BM_PXP_WFE_B_STG1_8X1_OUT1_4_LUTOUT138)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_4_LUTOUT137 0x00000200
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_4_LUTOUT137(v) \
+ (((v) << 9) & BM_PXP_WFE_B_STG1_8X1_OUT1_4_LUTOUT137)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_4_LUTOUT136 0x00000100
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_4_LUTOUT136(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STG1_8X1_OUT1_4_LUTOUT136)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_4_LUTOUT135 0x00000080
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_4_LUTOUT135(v) \
+ (((v) << 7) & BM_PXP_WFE_B_STG1_8X1_OUT1_4_LUTOUT135)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_4_LUTOUT134 0x00000040
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_4_LUTOUT134(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STG1_8X1_OUT1_4_LUTOUT134)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_4_LUTOUT133 0x00000020
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_4_LUTOUT133(v) \
+ (((v) << 5) & BM_PXP_WFE_B_STG1_8X1_OUT1_4_LUTOUT133)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_4_LUTOUT132 0x00000010
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_4_LUTOUT132(v) \
+ (((v) << 4) & BM_PXP_WFE_B_STG1_8X1_OUT1_4_LUTOUT132)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_4_LUTOUT131 0x00000008
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_4_LUTOUT131(v) \
+ (((v) << 3) & BM_PXP_WFE_B_STG1_8X1_OUT1_4_LUTOUT131)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_4_LUTOUT130 0x00000004
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_4_LUTOUT130(v) \
+ (((v) << 2) & BM_PXP_WFE_B_STG1_8X1_OUT1_4_LUTOUT130)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_4_LUTOUT129 0x00000002
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_4_LUTOUT129(v) \
+ (((v) << 1) & BM_PXP_WFE_B_STG1_8X1_OUT1_4_LUTOUT129)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_4_LUTOUT128 0x00000001
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_4_LUTOUT128(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STG1_8X1_OUT1_4_LUTOUT128)
+
+#define HW_PXP_WFE_B_STG1_8X1_OUT1_5 (0x00002160)
+
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_5_LUTOUT191 0x80000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_5_LUTOUT191(v) \
+ (((v) << 31) & BM_PXP_WFE_B_STG1_8X1_OUT1_5_LUTOUT191)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_5_LUTOUT190 0x40000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_5_LUTOUT190(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STG1_8X1_OUT1_5_LUTOUT190)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_5_LUTOUT189 0x20000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_5_LUTOUT189(v) \
+ (((v) << 29) & BM_PXP_WFE_B_STG1_8X1_OUT1_5_LUTOUT189)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_5_LUTOUT188 0x10000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_5_LUTOUT188(v) \
+ (((v) << 28) & BM_PXP_WFE_B_STG1_8X1_OUT1_5_LUTOUT188)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_5_LUTOUT187 0x08000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_5_LUTOUT187(v) \
+ (((v) << 27) & BM_PXP_WFE_B_STG1_8X1_OUT1_5_LUTOUT187)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_5_LUTOUT186 0x04000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_5_LUTOUT186(v) \
+ (((v) << 26) & BM_PXP_WFE_B_STG1_8X1_OUT1_5_LUTOUT186)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_5_LUTOUT185 0x02000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_5_LUTOUT185(v) \
+ (((v) << 25) & BM_PXP_WFE_B_STG1_8X1_OUT1_5_LUTOUT185)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_5_LUTOUT184 0x01000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_5_LUTOUT184(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STG1_8X1_OUT1_5_LUTOUT184)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_5_LUTOUT183 0x00800000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_5_LUTOUT183(v) \
+ (((v) << 23) & BM_PXP_WFE_B_STG1_8X1_OUT1_5_LUTOUT183)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_5_LUTOUT182 0x00400000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_5_LUTOUT182(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STG1_8X1_OUT1_5_LUTOUT182)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_5_LUTOUT181 0x00200000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_5_LUTOUT181(v) \
+ (((v) << 21) & BM_PXP_WFE_B_STG1_8X1_OUT1_5_LUTOUT181)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_5_LUTOUT180 0x00100000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_5_LUTOUT180(v) \
+ (((v) << 20) & BM_PXP_WFE_B_STG1_8X1_OUT1_5_LUTOUT180)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_5_LUTOUT179 0x00080000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_5_LUTOUT179(v) \
+ (((v) << 19) & BM_PXP_WFE_B_STG1_8X1_OUT1_5_LUTOUT179)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_5_LUTOUT178 0x00040000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_5_LUTOUT178(v) \
+ (((v) << 18) & BM_PXP_WFE_B_STG1_8X1_OUT1_5_LUTOUT178)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_5_LUTOUT177 0x00020000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_5_LUTOUT177(v) \
+ (((v) << 17) & BM_PXP_WFE_B_STG1_8X1_OUT1_5_LUTOUT177)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_5_LUTOUT176 0x00010000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_5_LUTOUT176(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STG1_8X1_OUT1_5_LUTOUT176)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_5_LUTOUT175 0x00008000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_5_LUTOUT175(v) \
+ (((v) << 15) & BM_PXP_WFE_B_STG1_8X1_OUT1_5_LUTOUT175)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_5_LUTOUT174 0x00004000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_5_LUTOUT174(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STG1_8X1_OUT1_5_LUTOUT174)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_5_LUTOUT173 0x00002000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_5_LUTOUT173(v) \
+ (((v) << 13) & BM_PXP_WFE_B_STG1_8X1_OUT1_5_LUTOUT173)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_5_LUTOUT172 0x00001000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_5_LUTOUT172(v) \
+ (((v) << 12) & BM_PXP_WFE_B_STG1_8X1_OUT1_5_LUTOUT172)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_5_LUTOUT171 0x00000800
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_5_LUTOUT171(v) \
+ (((v) << 11) & BM_PXP_WFE_B_STG1_8X1_OUT1_5_LUTOUT171)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_5_LUTOUT170 0x00000400
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_5_LUTOUT170(v) \
+ (((v) << 10) & BM_PXP_WFE_B_STG1_8X1_OUT1_5_LUTOUT170)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_5_LUTOUT169 0x00000200
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_5_LUTOUT169(v) \
+ (((v) << 9) & BM_PXP_WFE_B_STG1_8X1_OUT1_5_LUTOUT169)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_5_LUTOUT168 0x00000100
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_5_LUTOUT168(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STG1_8X1_OUT1_5_LUTOUT168)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_5_LUTOUT167 0x00000080
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_5_LUTOUT167(v) \
+ (((v) << 7) & BM_PXP_WFE_B_STG1_8X1_OUT1_5_LUTOUT167)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_5_LUTOUT166 0x00000040
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_5_LUTOUT166(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STG1_8X1_OUT1_5_LUTOUT166)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_5_LUTOUT165 0x00000020
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_5_LUTOUT165(v) \
+ (((v) << 5) & BM_PXP_WFE_B_STG1_8X1_OUT1_5_LUTOUT165)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_5_LUTOUT164 0x00000010
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_5_LUTOUT164(v) \
+ (((v) << 4) & BM_PXP_WFE_B_STG1_8X1_OUT1_5_LUTOUT164)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_5_LUTOUT163 0x00000008
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_5_LUTOUT163(v) \
+ (((v) << 3) & BM_PXP_WFE_B_STG1_8X1_OUT1_5_LUTOUT163)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_5_LUTOUT162 0x00000004
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_5_LUTOUT162(v) \
+ (((v) << 2) & BM_PXP_WFE_B_STG1_8X1_OUT1_5_LUTOUT162)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_5_LUTOUT161 0x00000002
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_5_LUTOUT161(v) \
+ (((v) << 1) & BM_PXP_WFE_B_STG1_8X1_OUT1_5_LUTOUT161)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_5_LUTOUT160 0x00000001
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_5_LUTOUT160(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STG1_8X1_OUT1_5_LUTOUT160)
+
+#define HW_PXP_WFE_B_STG1_8X1_OUT1_6 (0x00002170)
+
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_6_LUTOUT223 0x80000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_6_LUTOUT223(v) \
+ (((v) << 31) & BM_PXP_WFE_B_STG1_8X1_OUT1_6_LUTOUT223)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_6_LUTOUT222 0x40000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_6_LUTOUT222(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STG1_8X1_OUT1_6_LUTOUT222)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_6_LUTOUT221 0x20000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_6_LUTOUT221(v) \
+ (((v) << 29) & BM_PXP_WFE_B_STG1_8X1_OUT1_6_LUTOUT221)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_6_LUTOUT220 0x10000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_6_LUTOUT220(v) \
+ (((v) << 28) & BM_PXP_WFE_B_STG1_8X1_OUT1_6_LUTOUT220)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_6_LUTOUT219 0x08000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_6_LUTOUT219(v) \
+ (((v) << 27) & BM_PXP_WFE_B_STG1_8X1_OUT1_6_LUTOUT219)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_6_LUTOUT218 0x04000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_6_LUTOUT218(v) \
+ (((v) << 26) & BM_PXP_WFE_B_STG1_8X1_OUT1_6_LUTOUT218)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_6_LUTOUT217 0x02000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_6_LUTOUT217(v) \
+ (((v) << 25) & BM_PXP_WFE_B_STG1_8X1_OUT1_6_LUTOUT217)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_6_LUTOUT216 0x01000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_6_LUTOUT216(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STG1_8X1_OUT1_6_LUTOUT216)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_6_LUTOUT215 0x00800000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_6_LUTOUT215(v) \
+ (((v) << 23) & BM_PXP_WFE_B_STG1_8X1_OUT1_6_LUTOUT215)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_6_LUTOUT214 0x00400000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_6_LUTOUT214(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STG1_8X1_OUT1_6_LUTOUT214)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_6_LUTOUT213 0x00200000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_6_LUTOUT213(v) \
+ (((v) << 21) & BM_PXP_WFE_B_STG1_8X1_OUT1_6_LUTOUT213)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_6_LUTOUT212 0x00100000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_6_LUTOUT212(v) \
+ (((v) << 20) & BM_PXP_WFE_B_STG1_8X1_OUT1_6_LUTOUT212)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_6_LUTOUT211 0x00080000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_6_LUTOUT211(v) \
+ (((v) << 19) & BM_PXP_WFE_B_STG1_8X1_OUT1_6_LUTOUT211)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_6_LUTOUT210 0x00040000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_6_LUTOUT210(v) \
+ (((v) << 18) & BM_PXP_WFE_B_STG1_8X1_OUT1_6_LUTOUT210)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_6_LUTOUT209 0x00020000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_6_LUTOUT209(v) \
+ (((v) << 17) & BM_PXP_WFE_B_STG1_8X1_OUT1_6_LUTOUT209)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_6_LUTOUT208 0x00010000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_6_LUTOUT208(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STG1_8X1_OUT1_6_LUTOUT208)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_6_LUTOUT207 0x00008000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_6_LUTOUT207(v) \
+ (((v) << 15) & BM_PXP_WFE_B_STG1_8X1_OUT1_6_LUTOUT207)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_6_LUTOUT206 0x00004000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_6_LUTOUT206(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STG1_8X1_OUT1_6_LUTOUT206)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_6_LUTOUT205 0x00002000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_6_LUTOUT205(v) \
+ (((v) << 13) & BM_PXP_WFE_B_STG1_8X1_OUT1_6_LUTOUT205)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_6_LUTOUT204 0x00001000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_6_LUTOUT204(v) \
+ (((v) << 12) & BM_PXP_WFE_B_STG1_8X1_OUT1_6_LUTOUT204)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_6_LUTOUT203 0x00000800
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_6_LUTOUT203(v) \
+ (((v) << 11) & BM_PXP_WFE_B_STG1_8X1_OUT1_6_LUTOUT203)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_6_LUTOUT202 0x00000400
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_6_LUTOUT202(v) \
+ (((v) << 10) & BM_PXP_WFE_B_STG1_8X1_OUT1_6_LUTOUT202)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_6_LUTOUT201 0x00000200
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_6_LUTOUT201(v) \
+ (((v) << 9) & BM_PXP_WFE_B_STG1_8X1_OUT1_6_LUTOUT201)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_6_LUTOUT200 0x00000100
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_6_LUTOUT200(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STG1_8X1_OUT1_6_LUTOUT200)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_6_LUTOUT199 0x00000080
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_6_LUTOUT199(v) \
+ (((v) << 7) & BM_PXP_WFE_B_STG1_8X1_OUT1_6_LUTOUT199)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_6_LUTOUT198 0x00000040
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_6_LUTOUT198(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STG1_8X1_OUT1_6_LUTOUT198)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_6_LUTOUT197 0x00000020
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_6_LUTOUT197(v) \
+ (((v) << 5) & BM_PXP_WFE_B_STG1_8X1_OUT1_6_LUTOUT197)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_6_LUTOUT196 0x00000010
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_6_LUTOUT196(v) \
+ (((v) << 4) & BM_PXP_WFE_B_STG1_8X1_OUT1_6_LUTOUT196)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_6_LUTOUT195 0x00000008
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_6_LUTOUT195(v) \
+ (((v) << 3) & BM_PXP_WFE_B_STG1_8X1_OUT1_6_LUTOUT195)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_6_LUTOUT194 0x00000004
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_6_LUTOUT194(v) \
+ (((v) << 2) & BM_PXP_WFE_B_STG1_8X1_OUT1_6_LUTOUT194)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_6_LUTOUT193 0x00000002
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_6_LUTOUT193(v) \
+ (((v) << 1) & BM_PXP_WFE_B_STG1_8X1_OUT1_6_LUTOUT193)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_6_LUTOUT192 0x00000001
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_6_LUTOUT192(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STG1_8X1_OUT1_6_LUTOUT192)
+
+#define HW_PXP_WFE_B_STG1_8X1_OUT1_7 (0x00002180)
+
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_7_LUTOUT255 0x80000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_7_LUTOUT255(v) \
+ (((v) << 31) & BM_PXP_WFE_B_STG1_8X1_OUT1_7_LUTOUT255)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_7_LUTOUT254 0x40000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_7_LUTOUT254(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STG1_8X1_OUT1_7_LUTOUT254)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_7_LUTOUT253 0x20000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_7_LUTOUT253(v) \
+ (((v) << 29) & BM_PXP_WFE_B_STG1_8X1_OUT1_7_LUTOUT253)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_7_LUTOUT252 0x10000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_7_LUTOUT252(v) \
+ (((v) << 28) & BM_PXP_WFE_B_STG1_8X1_OUT1_7_LUTOUT252)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_7_LUTOUT251 0x08000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_7_LUTOUT251(v) \
+ (((v) << 27) & BM_PXP_WFE_B_STG1_8X1_OUT1_7_LUTOUT251)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_7_LUTOUT250 0x04000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_7_LUTOUT250(v) \
+ (((v) << 26) & BM_PXP_WFE_B_STG1_8X1_OUT1_7_LUTOUT250)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_7_LUTOUT249 0x02000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_7_LUTOUT249(v) \
+ (((v) << 25) & BM_PXP_WFE_B_STG1_8X1_OUT1_7_LUTOUT249)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_7_LUTOUT248 0x01000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_7_LUTOUT248(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STG1_8X1_OUT1_7_LUTOUT248)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_7_LUTOUT247 0x00800000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_7_LUTOUT247(v) \
+ (((v) << 23) & BM_PXP_WFE_B_STG1_8X1_OUT1_7_LUTOUT247)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_7_LUTOUT246 0x00400000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_7_LUTOUT246(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STG1_8X1_OUT1_7_LUTOUT246)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_7_LUTOUT245 0x00200000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_7_LUTOUT245(v) \
+ (((v) << 21) & BM_PXP_WFE_B_STG1_8X1_OUT1_7_LUTOUT245)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_7_LUTOUT244 0x00100000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_7_LUTOUT244(v) \
+ (((v) << 20) & BM_PXP_WFE_B_STG1_8X1_OUT1_7_LUTOUT244)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_7_LUTOUT243 0x00080000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_7_LUTOUT243(v) \
+ (((v) << 19) & BM_PXP_WFE_B_STG1_8X1_OUT1_7_LUTOUT243)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_7_LUTOUT242 0x00040000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_7_LUTOUT242(v) \
+ (((v) << 18) & BM_PXP_WFE_B_STG1_8X1_OUT1_7_LUTOUT242)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_7_LUTOUT241 0x00020000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_7_LUTOUT241(v) \
+ (((v) << 17) & BM_PXP_WFE_B_STG1_8X1_OUT1_7_LUTOUT241)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_7_LUTOUT240 0x00010000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_7_LUTOUT240(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STG1_8X1_OUT1_7_LUTOUT240)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_7_LUTOUT239 0x00008000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_7_LUTOUT239(v) \
+ (((v) << 15) & BM_PXP_WFE_B_STG1_8X1_OUT1_7_LUTOUT239)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_7_LUTOUT238 0x00004000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_7_LUTOUT238(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STG1_8X1_OUT1_7_LUTOUT238)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_7_LUTOUT237 0x00002000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_7_LUTOUT237(v) \
+ (((v) << 13) & BM_PXP_WFE_B_STG1_8X1_OUT1_7_LUTOUT237)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_7_LUTOUT236 0x00001000
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_7_LUTOUT236(v) \
+ (((v) << 12) & BM_PXP_WFE_B_STG1_8X1_OUT1_7_LUTOUT236)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_7_LUTOUT235 0x00000800
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_7_LUTOUT235(v) \
+ (((v) << 11) & BM_PXP_WFE_B_STG1_8X1_OUT1_7_LUTOUT235)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_7_LUTOUT234 0x00000400
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_7_LUTOUT234(v) \
+ (((v) << 10) & BM_PXP_WFE_B_STG1_8X1_OUT1_7_LUTOUT234)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_7_LUTOUT233 0x00000200
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_7_LUTOUT233(v) \
+ (((v) << 9) & BM_PXP_WFE_B_STG1_8X1_OUT1_7_LUTOUT233)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_7_LUTOUT232 0x00000100
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_7_LUTOUT232(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STG1_8X1_OUT1_7_LUTOUT232)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_7_LUTOUT231 0x00000080
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_7_LUTOUT231(v) \
+ (((v) << 7) & BM_PXP_WFE_B_STG1_8X1_OUT1_7_LUTOUT231)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_7_LUTOUT230 0x00000040
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_7_LUTOUT230(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STG1_8X1_OUT1_7_LUTOUT230)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_7_LUTOUT229 0x00000020
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_7_LUTOUT229(v) \
+ (((v) << 5) & BM_PXP_WFE_B_STG1_8X1_OUT1_7_LUTOUT229)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_7_LUTOUT228 0x00000010
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_7_LUTOUT228(v) \
+ (((v) << 4) & BM_PXP_WFE_B_STG1_8X1_OUT1_7_LUTOUT228)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_7_LUTOUT227 0x00000008
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_7_LUTOUT227(v) \
+ (((v) << 3) & BM_PXP_WFE_B_STG1_8X1_OUT1_7_LUTOUT227)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_7_LUTOUT226 0x00000004
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_7_LUTOUT226(v) \
+ (((v) << 2) & BM_PXP_WFE_B_STG1_8X1_OUT1_7_LUTOUT226)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_7_LUTOUT225 0x00000002
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_7_LUTOUT225(v) \
+ (((v) << 1) & BM_PXP_WFE_B_STG1_8X1_OUT1_7_LUTOUT225)
+#define BM_PXP_WFE_B_STG1_8X1_OUT1_7_LUTOUT224 0x00000001
+#define BF_PXP_WFE_B_STG1_8X1_OUT1_7_LUTOUT224(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STG1_8X1_OUT1_7_LUTOUT224)
+
+#define HW_PXP_WFE_B_STG1_8X1_OUT2_0 (0x00002190)
+
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_0_LUTOUT31 0x80000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_0_LUTOUT31(v) \
+ (((v) << 31) & BM_PXP_WFE_B_STG1_8X1_OUT2_0_LUTOUT31)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_0_LUTOUT30 0x40000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_0_LUTOUT30(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STG1_8X1_OUT2_0_LUTOUT30)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_0_LUTOUT29 0x20000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_0_LUTOUT29(v) \
+ (((v) << 29) & BM_PXP_WFE_B_STG1_8X1_OUT2_0_LUTOUT29)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_0_LUTOUT28 0x10000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_0_LUTOUT28(v) \
+ (((v) << 28) & BM_PXP_WFE_B_STG1_8X1_OUT2_0_LUTOUT28)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_0_LUTOUT27 0x08000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_0_LUTOUT27(v) \
+ (((v) << 27) & BM_PXP_WFE_B_STG1_8X1_OUT2_0_LUTOUT27)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_0_LUTOUT26 0x04000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_0_LUTOUT26(v) \
+ (((v) << 26) & BM_PXP_WFE_B_STG1_8X1_OUT2_0_LUTOUT26)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_0_LUTOUT25 0x02000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_0_LUTOUT25(v) \
+ (((v) << 25) & BM_PXP_WFE_B_STG1_8X1_OUT2_0_LUTOUT25)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_0_LUTOUT24 0x01000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_0_LUTOUT24(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STG1_8X1_OUT2_0_LUTOUT24)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_0_LUTOUT23 0x00800000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_0_LUTOUT23(v) \
+ (((v) << 23) & BM_PXP_WFE_B_STG1_8X1_OUT2_0_LUTOUT23)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_0_LUTOUT22 0x00400000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_0_LUTOUT22(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STG1_8X1_OUT2_0_LUTOUT22)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_0_LUTOUT21 0x00200000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_0_LUTOUT21(v) \
+ (((v) << 21) & BM_PXP_WFE_B_STG1_8X1_OUT2_0_LUTOUT21)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_0_LUTOUT20 0x00100000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_0_LUTOUT20(v) \
+ (((v) << 20) & BM_PXP_WFE_B_STG1_8X1_OUT2_0_LUTOUT20)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_0_LUTOUT19 0x00080000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_0_LUTOUT19(v) \
+ (((v) << 19) & BM_PXP_WFE_B_STG1_8X1_OUT2_0_LUTOUT19)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_0_LUTOUT18 0x00040000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_0_LUTOUT18(v) \
+ (((v) << 18) & BM_PXP_WFE_B_STG1_8X1_OUT2_0_LUTOUT18)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_0_LUTOUT17 0x00020000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_0_LUTOUT17(v) \
+ (((v) << 17) & BM_PXP_WFE_B_STG1_8X1_OUT2_0_LUTOUT17)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_0_LUTOUT16 0x00010000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_0_LUTOUT16(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STG1_8X1_OUT2_0_LUTOUT16)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_0_LUTOUT15 0x00008000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_0_LUTOUT15(v) \
+ (((v) << 15) & BM_PXP_WFE_B_STG1_8X1_OUT2_0_LUTOUT15)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_0_LUTOUT14 0x00004000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_0_LUTOUT14(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STG1_8X1_OUT2_0_LUTOUT14)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_0_LUTOUT13 0x00002000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_0_LUTOUT13(v) \
+ (((v) << 13) & BM_PXP_WFE_B_STG1_8X1_OUT2_0_LUTOUT13)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_0_LUTOUT12 0x00001000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_0_LUTOUT12(v) \
+ (((v) << 12) & BM_PXP_WFE_B_STG1_8X1_OUT2_0_LUTOUT12)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_0_LUTOUT11 0x00000800
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_0_LUTOUT11(v) \
+ (((v) << 11) & BM_PXP_WFE_B_STG1_8X1_OUT2_0_LUTOUT11)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_0_LUTOUT10 0x00000400
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_0_LUTOUT10(v) \
+ (((v) << 10) & BM_PXP_WFE_B_STG1_8X1_OUT2_0_LUTOUT10)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_0_LUTOUT9 0x00000200
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_0_LUTOUT9(v) \
+ (((v) << 9) & BM_PXP_WFE_B_STG1_8X1_OUT2_0_LUTOUT9)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_0_LUTOUT8 0x00000100
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_0_LUTOUT8(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STG1_8X1_OUT2_0_LUTOUT8)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_0_LUTOUT7 0x00000080
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_0_LUTOUT7(v) \
+ (((v) << 7) & BM_PXP_WFE_B_STG1_8X1_OUT2_0_LUTOUT7)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_0_LUTOUT6 0x00000040
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_0_LUTOUT6(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STG1_8X1_OUT2_0_LUTOUT6)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_0_LUTOUT5 0x00000020
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_0_LUTOUT5(v) \
+ (((v) << 5) & BM_PXP_WFE_B_STG1_8X1_OUT2_0_LUTOUT5)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_0_LUTOUT4 0x00000010
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_0_LUTOUT4(v) \
+ (((v) << 4) & BM_PXP_WFE_B_STG1_8X1_OUT2_0_LUTOUT4)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_0_LUTOUT3 0x00000008
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_0_LUTOUT3(v) \
+ (((v) << 3) & BM_PXP_WFE_B_STG1_8X1_OUT2_0_LUTOUT3)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_0_LUTOUT2 0x00000004
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_0_LUTOUT2(v) \
+ (((v) << 2) & BM_PXP_WFE_B_STG1_8X1_OUT2_0_LUTOUT2)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_0_LUTOUT1 0x00000002
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_0_LUTOUT1(v) \
+ (((v) << 1) & BM_PXP_WFE_B_STG1_8X1_OUT2_0_LUTOUT1)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_0_LUTOUT0 0x00000001
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_0_LUTOUT0(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STG1_8X1_OUT2_0_LUTOUT0)
+
+#define HW_PXP_WFE_B_STG1_8X1_OUT2_1 (0x000021a0)
+
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_1_LUTOUT63 0x80000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_1_LUTOUT63(v) \
+ (((v) << 31) & BM_PXP_WFE_B_STG1_8X1_OUT2_1_LUTOUT63)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_1_LUTOUT62 0x40000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_1_LUTOUT62(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STG1_8X1_OUT2_1_LUTOUT62)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_1_LUTOUT61 0x20000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_1_LUTOUT61(v) \
+ (((v) << 29) & BM_PXP_WFE_B_STG1_8X1_OUT2_1_LUTOUT61)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_1_LUTOUT60 0x10000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_1_LUTOUT60(v) \
+ (((v) << 28) & BM_PXP_WFE_B_STG1_8X1_OUT2_1_LUTOUT60)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_1_LUTOUT59 0x08000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_1_LUTOUT59(v) \
+ (((v) << 27) & BM_PXP_WFE_B_STG1_8X1_OUT2_1_LUTOUT59)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_1_LUTOUT58 0x04000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_1_LUTOUT58(v) \
+ (((v) << 26) & BM_PXP_WFE_B_STG1_8X1_OUT2_1_LUTOUT58)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_1_LUTOUT57 0x02000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_1_LUTOUT57(v) \
+ (((v) << 25) & BM_PXP_WFE_B_STG1_8X1_OUT2_1_LUTOUT57)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_1_LUTOUT56 0x01000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_1_LUTOUT56(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STG1_8X1_OUT2_1_LUTOUT56)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_1_LUTOUT55 0x00800000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_1_LUTOUT55(v) \
+ (((v) << 23) & BM_PXP_WFE_B_STG1_8X1_OUT2_1_LUTOUT55)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_1_LUTOUT54 0x00400000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_1_LUTOUT54(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STG1_8X1_OUT2_1_LUTOUT54)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_1_LUTOUT53 0x00200000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_1_LUTOUT53(v) \
+ (((v) << 21) & BM_PXP_WFE_B_STG1_8X1_OUT2_1_LUTOUT53)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_1_LUTOUT52 0x00100000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_1_LUTOUT52(v) \
+ (((v) << 20) & BM_PXP_WFE_B_STG1_8X1_OUT2_1_LUTOUT52)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_1_LUTOUT51 0x00080000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_1_LUTOUT51(v) \
+ (((v) << 19) & BM_PXP_WFE_B_STG1_8X1_OUT2_1_LUTOUT51)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_1_LUTOUT50 0x00040000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_1_LUTOUT50(v) \
+ (((v) << 18) & BM_PXP_WFE_B_STG1_8X1_OUT2_1_LUTOUT50)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_1_LUTOUT49 0x00020000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_1_LUTOUT49(v) \
+ (((v) << 17) & BM_PXP_WFE_B_STG1_8X1_OUT2_1_LUTOUT49)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_1_LUTOUT48 0x00010000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_1_LUTOUT48(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STG1_8X1_OUT2_1_LUTOUT48)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_1_LUTOUT47 0x00008000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_1_LUTOUT47(v) \
+ (((v) << 15) & BM_PXP_WFE_B_STG1_8X1_OUT2_1_LUTOUT47)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_1_LUTOUT46 0x00004000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_1_LUTOUT46(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STG1_8X1_OUT2_1_LUTOUT46)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_1_LUTOUT45 0x00002000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_1_LUTOUT45(v) \
+ (((v) << 13) & BM_PXP_WFE_B_STG1_8X1_OUT2_1_LUTOUT45)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_1_LUTOUT44 0x00001000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_1_LUTOUT44(v) \
+ (((v) << 12) & BM_PXP_WFE_B_STG1_8X1_OUT2_1_LUTOUT44)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_1_LUTOUT43 0x00000800
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_1_LUTOUT43(v) \
+ (((v) << 11) & BM_PXP_WFE_B_STG1_8X1_OUT2_1_LUTOUT43)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_1_LUTOUT42 0x00000400
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_1_LUTOUT42(v) \
+ (((v) << 10) & BM_PXP_WFE_B_STG1_8X1_OUT2_1_LUTOUT42)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_1_LUTOUT41 0x00000200
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_1_LUTOUT41(v) \
+ (((v) << 9) & BM_PXP_WFE_B_STG1_8X1_OUT2_1_LUTOUT41)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_1_LUTOUT40 0x00000100
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_1_LUTOUT40(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STG1_8X1_OUT2_1_LUTOUT40)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_1_LUTOUT39 0x00000080
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_1_LUTOUT39(v) \
+ (((v) << 7) & BM_PXP_WFE_B_STG1_8X1_OUT2_1_LUTOUT39)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_1_LUTOUT38 0x00000040
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_1_LUTOUT38(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STG1_8X1_OUT2_1_LUTOUT38)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_1_LUTOUT37 0x00000020
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_1_LUTOUT37(v) \
+ (((v) << 5) & BM_PXP_WFE_B_STG1_8X1_OUT2_1_LUTOUT37)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_1_LUTOUT36 0x00000010
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_1_LUTOUT36(v) \
+ (((v) << 4) & BM_PXP_WFE_B_STG1_8X1_OUT2_1_LUTOUT36)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_1_LUTOUT35 0x00000008
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_1_LUTOUT35(v) \
+ (((v) << 3) & BM_PXP_WFE_B_STG1_8X1_OUT2_1_LUTOUT35)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_1_LUTOUT34 0x00000004
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_1_LUTOUT34(v) \
+ (((v) << 2) & BM_PXP_WFE_B_STG1_8X1_OUT2_1_LUTOUT34)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_1_LUTOUT33 0x00000002
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_1_LUTOUT33(v) \
+ (((v) << 1) & BM_PXP_WFE_B_STG1_8X1_OUT2_1_LUTOUT33)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_1_LUTOUT32 0x00000001
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_1_LUTOUT32(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STG1_8X1_OUT2_1_LUTOUT32)
+
+#define HW_PXP_WFE_B_STG1_8X1_OUT2_2 (0x000021b0)
+
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_2_LUTOUT95 0x80000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_2_LUTOUT95(v) \
+ (((v) << 31) & BM_PXP_WFE_B_STG1_8X1_OUT2_2_LUTOUT95)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_2_LUTOUT94 0x40000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_2_LUTOUT94(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STG1_8X1_OUT2_2_LUTOUT94)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_2_LUTOUT93 0x20000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_2_LUTOUT93(v) \
+ (((v) << 29) & BM_PXP_WFE_B_STG1_8X1_OUT2_2_LUTOUT93)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_2_LUTOUT92 0x10000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_2_LUTOUT92(v) \
+ (((v) << 28) & BM_PXP_WFE_B_STG1_8X1_OUT2_2_LUTOUT92)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_2_LUTOUT91 0x08000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_2_LUTOUT91(v) \
+ (((v) << 27) & BM_PXP_WFE_B_STG1_8X1_OUT2_2_LUTOUT91)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_2_LUTOUT90 0x04000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_2_LUTOUT90(v) \
+ (((v) << 26) & BM_PXP_WFE_B_STG1_8X1_OUT2_2_LUTOUT90)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_2_LUTOUT89 0x02000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_2_LUTOUT89(v) \
+ (((v) << 25) & BM_PXP_WFE_B_STG1_8X1_OUT2_2_LUTOUT89)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_2_LUTOUT88 0x01000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_2_LUTOUT88(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STG1_8X1_OUT2_2_LUTOUT88)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_2_LUTOUT87 0x00800000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_2_LUTOUT87(v) \
+ (((v) << 23) & BM_PXP_WFE_B_STG1_8X1_OUT2_2_LUTOUT87)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_2_LUTOUT86 0x00400000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_2_LUTOUT86(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STG1_8X1_OUT2_2_LUTOUT86)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_2_LUTOUT85 0x00200000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_2_LUTOUT85(v) \
+ (((v) << 21) & BM_PXP_WFE_B_STG1_8X1_OUT2_2_LUTOUT85)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_2_LUTOUT84 0x00100000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_2_LUTOUT84(v) \
+ (((v) << 20) & BM_PXP_WFE_B_STG1_8X1_OUT2_2_LUTOUT84)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_2_LUTOUT83 0x00080000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_2_LUTOUT83(v) \
+ (((v) << 19) & BM_PXP_WFE_B_STG1_8X1_OUT2_2_LUTOUT83)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_2_LUTOUT82 0x00040000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_2_LUTOUT82(v) \
+ (((v) << 18) & BM_PXP_WFE_B_STG1_8X1_OUT2_2_LUTOUT82)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_2_LUTOUT81 0x00020000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_2_LUTOUT81(v) \
+ (((v) << 17) & BM_PXP_WFE_B_STG1_8X1_OUT2_2_LUTOUT81)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_2_LUTOUT80 0x00010000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_2_LUTOUT80(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STG1_8X1_OUT2_2_LUTOUT80)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_2_LUTOUT79 0x00008000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_2_LUTOUT79(v) \
+ (((v) << 15) & BM_PXP_WFE_B_STG1_8X1_OUT2_2_LUTOUT79)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_2_LUTOUT78 0x00004000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_2_LUTOUT78(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STG1_8X1_OUT2_2_LUTOUT78)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_2_LUTOUT77 0x00002000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_2_LUTOUT77(v) \
+ (((v) << 13) & BM_PXP_WFE_B_STG1_8X1_OUT2_2_LUTOUT77)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_2_LUTOUT76 0x00001000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_2_LUTOUT76(v) \
+ (((v) << 12) & BM_PXP_WFE_B_STG1_8X1_OUT2_2_LUTOUT76)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_2_LUTOUT75 0x00000800
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_2_LUTOUT75(v) \
+ (((v) << 11) & BM_PXP_WFE_B_STG1_8X1_OUT2_2_LUTOUT75)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_2_LUTOUT74 0x00000400
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_2_LUTOUT74(v) \
+ (((v) << 10) & BM_PXP_WFE_B_STG1_8X1_OUT2_2_LUTOUT74)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_2_LUTOUT73 0x00000200
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_2_LUTOUT73(v) \
+ (((v) << 9) & BM_PXP_WFE_B_STG1_8X1_OUT2_2_LUTOUT73)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_2_LUTOUT72 0x00000100
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_2_LUTOUT72(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STG1_8X1_OUT2_2_LUTOUT72)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_2_LUTOUT71 0x00000080
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_2_LUTOUT71(v) \
+ (((v) << 7) & BM_PXP_WFE_B_STG1_8X1_OUT2_2_LUTOUT71)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_2_LUTOUT70 0x00000040
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_2_LUTOUT70(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STG1_8X1_OUT2_2_LUTOUT70)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_2_LUTOUT69 0x00000020
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_2_LUTOUT69(v) \
+ (((v) << 5) & BM_PXP_WFE_B_STG1_8X1_OUT2_2_LUTOUT69)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_2_LUTOUT68 0x00000010
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_2_LUTOUT68(v) \
+ (((v) << 4) & BM_PXP_WFE_B_STG1_8X1_OUT2_2_LUTOUT68)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_2_LUTOUT67 0x00000008
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_2_LUTOUT67(v) \
+ (((v) << 3) & BM_PXP_WFE_B_STG1_8X1_OUT2_2_LUTOUT67)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_2_LUTOUT66 0x00000004
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_2_LUTOUT66(v) \
+ (((v) << 2) & BM_PXP_WFE_B_STG1_8X1_OUT2_2_LUTOUT66)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_2_LUTOUT65 0x00000002
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_2_LUTOUT65(v) \
+ (((v) << 1) & BM_PXP_WFE_B_STG1_8X1_OUT2_2_LUTOUT65)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_2_LUTOUT64 0x00000001
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_2_LUTOUT64(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STG1_8X1_OUT2_2_LUTOUT64)
+
+#define HW_PXP_WFE_B_STG1_8X1_OUT2_3 (0x000021c0)
+
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_3_LUTOUT127 0x80000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_3_LUTOUT127(v) \
+ (((v) << 31) & BM_PXP_WFE_B_STG1_8X1_OUT2_3_LUTOUT127)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_3_LUTOUT126 0x40000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_3_LUTOUT126(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STG1_8X1_OUT2_3_LUTOUT126)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_3_LUTOUT125 0x20000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_3_LUTOUT125(v) \
+ (((v) << 29) & BM_PXP_WFE_B_STG1_8X1_OUT2_3_LUTOUT125)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_3_LUTOUT124 0x10000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_3_LUTOUT124(v) \
+ (((v) << 28) & BM_PXP_WFE_B_STG1_8X1_OUT2_3_LUTOUT124)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_3_LUTOUT123 0x08000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_3_LUTOUT123(v) \
+ (((v) << 27) & BM_PXP_WFE_B_STG1_8X1_OUT2_3_LUTOUT123)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_3_LUTOUT122 0x04000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_3_LUTOUT122(v) \
+ (((v) << 26) & BM_PXP_WFE_B_STG1_8X1_OUT2_3_LUTOUT122)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_3_LUTOUT121 0x02000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_3_LUTOUT121(v) \
+ (((v) << 25) & BM_PXP_WFE_B_STG1_8X1_OUT2_3_LUTOUT121)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_3_LUTOUT120 0x01000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_3_LUTOUT120(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STG1_8X1_OUT2_3_LUTOUT120)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_3_LUTOUT119 0x00800000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_3_LUTOUT119(v) \
+ (((v) << 23) & BM_PXP_WFE_B_STG1_8X1_OUT2_3_LUTOUT119)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_3_LUTOUT118 0x00400000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_3_LUTOUT118(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STG1_8X1_OUT2_3_LUTOUT118)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_3_LUTOUT117 0x00200000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_3_LUTOUT117(v) \
+ (((v) << 21) & BM_PXP_WFE_B_STG1_8X1_OUT2_3_LUTOUT117)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_3_LUTOUT116 0x00100000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_3_LUTOUT116(v) \
+ (((v) << 20) & BM_PXP_WFE_B_STG1_8X1_OUT2_3_LUTOUT116)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_3_LUTOUT115 0x00080000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_3_LUTOUT115(v) \
+ (((v) << 19) & BM_PXP_WFE_B_STG1_8X1_OUT2_3_LUTOUT115)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_3_LUTOUT114 0x00040000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_3_LUTOUT114(v) \
+ (((v) << 18) & BM_PXP_WFE_B_STG1_8X1_OUT2_3_LUTOUT114)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_3_LUTOUT113 0x00020000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_3_LUTOUT113(v) \
+ (((v) << 17) & BM_PXP_WFE_B_STG1_8X1_OUT2_3_LUTOUT113)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_3_LUTOUT112 0x00010000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_3_LUTOUT112(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STG1_8X1_OUT2_3_LUTOUT112)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_3_LUTOUT111 0x00008000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_3_LUTOUT111(v) \
+ (((v) << 15) & BM_PXP_WFE_B_STG1_8X1_OUT2_3_LUTOUT111)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_3_LUTOUT110 0x00004000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_3_LUTOUT110(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STG1_8X1_OUT2_3_LUTOUT110)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_3_LUTOUT109 0x00002000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_3_LUTOUT109(v) \
+ (((v) << 13) & BM_PXP_WFE_B_STG1_8X1_OUT2_3_LUTOUT109)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_3_LUTOUT108 0x00001000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_3_LUTOUT108(v) \
+ (((v) << 12) & BM_PXP_WFE_B_STG1_8X1_OUT2_3_LUTOUT108)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_3_LUTOUT107 0x00000800
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_3_LUTOUT107(v) \
+ (((v) << 11) & BM_PXP_WFE_B_STG1_8X1_OUT2_3_LUTOUT107)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_3_LUTOUT106 0x00000400
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_3_LUTOUT106(v) \
+ (((v) << 10) & BM_PXP_WFE_B_STG1_8X1_OUT2_3_LUTOUT106)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_3_LUTOUT105 0x00000200
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_3_LUTOUT105(v) \
+ (((v) << 9) & BM_PXP_WFE_B_STG1_8X1_OUT2_3_LUTOUT105)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_3_LUTOUT104 0x00000100
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_3_LUTOUT104(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STG1_8X1_OUT2_3_LUTOUT104)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_3_LUTOUT103 0x00000080
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_3_LUTOUT103(v) \
+ (((v) << 7) & BM_PXP_WFE_B_STG1_8X1_OUT2_3_LUTOUT103)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_3_LUTOUT102 0x00000040
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_3_LUTOUT102(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STG1_8X1_OUT2_3_LUTOUT102)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_3_LUTOUT101 0x00000020
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_3_LUTOUT101(v) \
+ (((v) << 5) & BM_PXP_WFE_B_STG1_8X1_OUT2_3_LUTOUT101)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_3_LUTOUT100 0x00000010
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_3_LUTOUT100(v) \
+ (((v) << 4) & BM_PXP_WFE_B_STG1_8X1_OUT2_3_LUTOUT100)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_3_LUTOUT99 0x00000008
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_3_LUTOUT99(v) \
+ (((v) << 3) & BM_PXP_WFE_B_STG1_8X1_OUT2_3_LUTOUT99)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_3_LUTOUT98 0x00000004
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_3_LUTOUT98(v) \
+ (((v) << 2) & BM_PXP_WFE_B_STG1_8X1_OUT2_3_LUTOUT98)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_3_LUTOUT97 0x00000002
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_3_LUTOUT97(v) \
+ (((v) << 1) & BM_PXP_WFE_B_STG1_8X1_OUT2_3_LUTOUT97)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_3_LUTOUT96 0x00000001
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_3_LUTOUT96(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STG1_8X1_OUT2_3_LUTOUT96)
+
+#define HW_PXP_WFE_B_STG1_8X1_OUT2_4 (0x000021d0)
+
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_4_LUTOUT159 0x80000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_4_LUTOUT159(v) \
+ (((v) << 31) & BM_PXP_WFE_B_STG1_8X1_OUT2_4_LUTOUT159)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_4_LUTOUT158 0x40000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_4_LUTOUT158(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STG1_8X1_OUT2_4_LUTOUT158)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_4_LUTOUT157 0x20000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_4_LUTOUT157(v) \
+ (((v) << 29) & BM_PXP_WFE_B_STG1_8X1_OUT2_4_LUTOUT157)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_4_LUTOUT156 0x10000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_4_LUTOUT156(v) \
+ (((v) << 28) & BM_PXP_WFE_B_STG1_8X1_OUT2_4_LUTOUT156)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_4_LUTOUT155 0x08000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_4_LUTOUT155(v) \
+ (((v) << 27) & BM_PXP_WFE_B_STG1_8X1_OUT2_4_LUTOUT155)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_4_LUTOUT154 0x04000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_4_LUTOUT154(v) \
+ (((v) << 26) & BM_PXP_WFE_B_STG1_8X1_OUT2_4_LUTOUT154)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_4_LUTOUT153 0x02000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_4_LUTOUT153(v) \
+ (((v) << 25) & BM_PXP_WFE_B_STG1_8X1_OUT2_4_LUTOUT153)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_4_LUTOUT152 0x01000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_4_LUTOUT152(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STG1_8X1_OUT2_4_LUTOUT152)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_4_LUTOUT151 0x00800000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_4_LUTOUT151(v) \
+ (((v) << 23) & BM_PXP_WFE_B_STG1_8X1_OUT2_4_LUTOUT151)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_4_LUTOUT150 0x00400000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_4_LUTOUT150(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STG1_8X1_OUT2_4_LUTOUT150)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_4_LUTOUT149 0x00200000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_4_LUTOUT149(v) \
+ (((v) << 21) & BM_PXP_WFE_B_STG1_8X1_OUT2_4_LUTOUT149)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_4_LUTOUT148 0x00100000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_4_LUTOUT148(v) \
+ (((v) << 20) & BM_PXP_WFE_B_STG1_8X1_OUT2_4_LUTOUT148)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_4_LUTOUT147 0x00080000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_4_LUTOUT147(v) \
+ (((v) << 19) & BM_PXP_WFE_B_STG1_8X1_OUT2_4_LUTOUT147)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_4_LUTOUT146 0x00040000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_4_LUTOUT146(v) \
+ (((v) << 18) & BM_PXP_WFE_B_STG1_8X1_OUT2_4_LUTOUT146)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_4_LUTOUT145 0x00020000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_4_LUTOUT145(v) \
+ (((v) << 17) & BM_PXP_WFE_B_STG1_8X1_OUT2_4_LUTOUT145)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_4_LUTOUT144 0x00010000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_4_LUTOUT144(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STG1_8X1_OUT2_4_LUTOUT144)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_4_LUTOUT143 0x00008000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_4_LUTOUT143(v) \
+ (((v) << 15) & BM_PXP_WFE_B_STG1_8X1_OUT2_4_LUTOUT143)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_4_LUTOUT142 0x00004000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_4_LUTOUT142(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STG1_8X1_OUT2_4_LUTOUT142)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_4_LUTOUT141 0x00002000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_4_LUTOUT141(v) \
+ (((v) << 13) & BM_PXP_WFE_B_STG1_8X1_OUT2_4_LUTOUT141)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_4_LUTOUT140 0x00001000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_4_LUTOUT140(v) \
+ (((v) << 12) & BM_PXP_WFE_B_STG1_8X1_OUT2_4_LUTOUT140)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_4_LUTOUT139 0x00000800
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_4_LUTOUT139(v) \
+ (((v) << 11) & BM_PXP_WFE_B_STG1_8X1_OUT2_4_LUTOUT139)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_4_LUTOUT138 0x00000400
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_4_LUTOUT138(v) \
+ (((v) << 10) & BM_PXP_WFE_B_STG1_8X1_OUT2_4_LUTOUT138)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_4_LUTOUT137 0x00000200
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_4_LUTOUT137(v) \
+ (((v) << 9) & BM_PXP_WFE_B_STG1_8X1_OUT2_4_LUTOUT137)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_4_LUTOUT136 0x00000100
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_4_LUTOUT136(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STG1_8X1_OUT2_4_LUTOUT136)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_4_LUTOUT135 0x00000080
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_4_LUTOUT135(v) \
+ (((v) << 7) & BM_PXP_WFE_B_STG1_8X1_OUT2_4_LUTOUT135)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_4_LUTOUT134 0x00000040
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_4_LUTOUT134(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STG1_8X1_OUT2_4_LUTOUT134)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_4_LUTOUT133 0x00000020
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_4_LUTOUT133(v) \
+ (((v) << 5) & BM_PXP_WFE_B_STG1_8X1_OUT2_4_LUTOUT133)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_4_LUTOUT132 0x00000010
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_4_LUTOUT132(v) \
+ (((v) << 4) & BM_PXP_WFE_B_STG1_8X1_OUT2_4_LUTOUT132)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_4_LUTOUT131 0x00000008
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_4_LUTOUT131(v) \
+ (((v) << 3) & BM_PXP_WFE_B_STG1_8X1_OUT2_4_LUTOUT131)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_4_LUTOUT130 0x00000004
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_4_LUTOUT130(v) \
+ (((v) << 2) & BM_PXP_WFE_B_STG1_8X1_OUT2_4_LUTOUT130)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_4_LUTOUT129 0x00000002
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_4_LUTOUT129(v) \
+ (((v) << 1) & BM_PXP_WFE_B_STG1_8X1_OUT2_4_LUTOUT129)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_4_LUTOUT128 0x00000001
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_4_LUTOUT128(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STG1_8X1_OUT2_4_LUTOUT128)
+
+#define HW_PXP_WFE_B_STG1_8X1_OUT2_5 (0x000021e0)
+
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_5_LUTOUT191 0x80000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_5_LUTOUT191(v) \
+ (((v) << 31) & BM_PXP_WFE_B_STG1_8X1_OUT2_5_LUTOUT191)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_5_LUTOUT190 0x40000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_5_LUTOUT190(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STG1_8X1_OUT2_5_LUTOUT190)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_5_LUTOUT189 0x20000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_5_LUTOUT189(v) \
+ (((v) << 29) & BM_PXP_WFE_B_STG1_8X1_OUT2_5_LUTOUT189)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_5_LUTOUT188 0x10000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_5_LUTOUT188(v) \
+ (((v) << 28) & BM_PXP_WFE_B_STG1_8X1_OUT2_5_LUTOUT188)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_5_LUTOUT187 0x08000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_5_LUTOUT187(v) \
+ (((v) << 27) & BM_PXP_WFE_B_STG1_8X1_OUT2_5_LUTOUT187)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_5_LUTOUT186 0x04000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_5_LUTOUT186(v) \
+ (((v) << 26) & BM_PXP_WFE_B_STG1_8X1_OUT2_5_LUTOUT186)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_5_LUTOUT185 0x02000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_5_LUTOUT185(v) \
+ (((v) << 25) & BM_PXP_WFE_B_STG1_8X1_OUT2_5_LUTOUT185)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_5_LUTOUT184 0x01000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_5_LUTOUT184(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STG1_8X1_OUT2_5_LUTOUT184)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_5_LUTOUT183 0x00800000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_5_LUTOUT183(v) \
+ (((v) << 23) & BM_PXP_WFE_B_STG1_8X1_OUT2_5_LUTOUT183)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_5_LUTOUT182 0x00400000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_5_LUTOUT182(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STG1_8X1_OUT2_5_LUTOUT182)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_5_LUTOUT181 0x00200000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_5_LUTOUT181(v) \
+ (((v) << 21) & BM_PXP_WFE_B_STG1_8X1_OUT2_5_LUTOUT181)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_5_LUTOUT180 0x00100000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_5_LUTOUT180(v) \
+ (((v) << 20) & BM_PXP_WFE_B_STG1_8X1_OUT2_5_LUTOUT180)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_5_LUTOUT179 0x00080000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_5_LUTOUT179(v) \
+ (((v) << 19) & BM_PXP_WFE_B_STG1_8X1_OUT2_5_LUTOUT179)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_5_LUTOUT178 0x00040000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_5_LUTOUT178(v) \
+ (((v) << 18) & BM_PXP_WFE_B_STG1_8X1_OUT2_5_LUTOUT178)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_5_LUTOUT177 0x00020000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_5_LUTOUT177(v) \
+ (((v) << 17) & BM_PXP_WFE_B_STG1_8X1_OUT2_5_LUTOUT177)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_5_LUTOUT176 0x00010000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_5_LUTOUT176(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STG1_8X1_OUT2_5_LUTOUT176)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_5_LUTOUT175 0x00008000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_5_LUTOUT175(v) \
+ (((v) << 15) & BM_PXP_WFE_B_STG1_8X1_OUT2_5_LUTOUT175)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_5_LUTOUT174 0x00004000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_5_LUTOUT174(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STG1_8X1_OUT2_5_LUTOUT174)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_5_LUTOUT173 0x00002000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_5_LUTOUT173(v) \
+ (((v) << 13) & BM_PXP_WFE_B_STG1_8X1_OUT2_5_LUTOUT173)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_5_LUTOUT172 0x00001000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_5_LUTOUT172(v) \
+ (((v) << 12) & BM_PXP_WFE_B_STG1_8X1_OUT2_5_LUTOUT172)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_5_LUTOUT171 0x00000800
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_5_LUTOUT171(v) \
+ (((v) << 11) & BM_PXP_WFE_B_STG1_8X1_OUT2_5_LUTOUT171)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_5_LUTOUT170 0x00000400
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_5_LUTOUT170(v) \
+ (((v) << 10) & BM_PXP_WFE_B_STG1_8X1_OUT2_5_LUTOUT170)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_5_LUTOUT169 0x00000200
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_5_LUTOUT169(v) \
+ (((v) << 9) & BM_PXP_WFE_B_STG1_8X1_OUT2_5_LUTOUT169)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_5_LUTOUT168 0x00000100
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_5_LUTOUT168(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STG1_8X1_OUT2_5_LUTOUT168)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_5_LUTOUT167 0x00000080
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_5_LUTOUT167(v) \
+ (((v) << 7) & BM_PXP_WFE_B_STG1_8X1_OUT2_5_LUTOUT167)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_5_LUTOUT166 0x00000040
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_5_LUTOUT166(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STG1_8X1_OUT2_5_LUTOUT166)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_5_LUTOUT165 0x00000020
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_5_LUTOUT165(v) \
+ (((v) << 5) & BM_PXP_WFE_B_STG1_8X1_OUT2_5_LUTOUT165)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_5_LUTOUT164 0x00000010
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_5_LUTOUT164(v) \
+ (((v) << 4) & BM_PXP_WFE_B_STG1_8X1_OUT2_5_LUTOUT164)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_5_LUTOUT163 0x00000008
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_5_LUTOUT163(v) \
+ (((v) << 3) & BM_PXP_WFE_B_STG1_8X1_OUT2_5_LUTOUT163)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_5_LUTOUT162 0x00000004
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_5_LUTOUT162(v) \
+ (((v) << 2) & BM_PXP_WFE_B_STG1_8X1_OUT2_5_LUTOUT162)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_5_LUTOUT161 0x00000002
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_5_LUTOUT161(v) \
+ (((v) << 1) & BM_PXP_WFE_B_STG1_8X1_OUT2_5_LUTOUT161)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_5_LUTOUT160 0x00000001
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_5_LUTOUT160(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STG1_8X1_OUT2_5_LUTOUT160)
+
+#define HW_PXP_WFE_B_STG1_8X1_OUT2_6 (0x000021f0)
+
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_6_LUTOUT223 0x80000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_6_LUTOUT223(v) \
+ (((v) << 31) & BM_PXP_WFE_B_STG1_8X1_OUT2_6_LUTOUT223)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_6_LUTOUT222 0x40000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_6_LUTOUT222(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STG1_8X1_OUT2_6_LUTOUT222)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_6_LUTOUT221 0x20000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_6_LUTOUT221(v) \
+ (((v) << 29) & BM_PXP_WFE_B_STG1_8X1_OUT2_6_LUTOUT221)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_6_LUTOUT220 0x10000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_6_LUTOUT220(v) \
+ (((v) << 28) & BM_PXP_WFE_B_STG1_8X1_OUT2_6_LUTOUT220)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_6_LUTOUT219 0x08000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_6_LUTOUT219(v) \
+ (((v) << 27) & BM_PXP_WFE_B_STG1_8X1_OUT2_6_LUTOUT219)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_6_LUTOUT218 0x04000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_6_LUTOUT218(v) \
+ (((v) << 26) & BM_PXP_WFE_B_STG1_8X1_OUT2_6_LUTOUT218)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_6_LUTOUT217 0x02000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_6_LUTOUT217(v) \
+ (((v) << 25) & BM_PXP_WFE_B_STG1_8X1_OUT2_6_LUTOUT217)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_6_LUTOUT216 0x01000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_6_LUTOUT216(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STG1_8X1_OUT2_6_LUTOUT216)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_6_LUTOUT215 0x00800000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_6_LUTOUT215(v) \
+ (((v) << 23) & BM_PXP_WFE_B_STG1_8X1_OUT2_6_LUTOUT215)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_6_LUTOUT214 0x00400000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_6_LUTOUT214(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STG1_8X1_OUT2_6_LUTOUT214)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_6_LUTOUT213 0x00200000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_6_LUTOUT213(v) \
+ (((v) << 21) & BM_PXP_WFE_B_STG1_8X1_OUT2_6_LUTOUT213)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_6_LUTOUT212 0x00100000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_6_LUTOUT212(v) \
+ (((v) << 20) & BM_PXP_WFE_B_STG1_8X1_OUT2_6_LUTOUT212)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_6_LUTOUT211 0x00080000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_6_LUTOUT211(v) \
+ (((v) << 19) & BM_PXP_WFE_B_STG1_8X1_OUT2_6_LUTOUT211)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_6_LUTOUT210 0x00040000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_6_LUTOUT210(v) \
+ (((v) << 18) & BM_PXP_WFE_B_STG1_8X1_OUT2_6_LUTOUT210)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_6_LUTOUT209 0x00020000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_6_LUTOUT209(v) \
+ (((v) << 17) & BM_PXP_WFE_B_STG1_8X1_OUT2_6_LUTOUT209)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_6_LUTOUT208 0x00010000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_6_LUTOUT208(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STG1_8X1_OUT2_6_LUTOUT208)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_6_LUTOUT207 0x00008000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_6_LUTOUT207(v) \
+ (((v) << 15) & BM_PXP_WFE_B_STG1_8X1_OUT2_6_LUTOUT207)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_6_LUTOUT206 0x00004000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_6_LUTOUT206(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STG1_8X1_OUT2_6_LUTOUT206)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_6_LUTOUT205 0x00002000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_6_LUTOUT205(v) \
+ (((v) << 13) & BM_PXP_WFE_B_STG1_8X1_OUT2_6_LUTOUT205)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_6_LUTOUT204 0x00001000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_6_LUTOUT204(v) \
+ (((v) << 12) & BM_PXP_WFE_B_STG1_8X1_OUT2_6_LUTOUT204)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_6_LUTOUT203 0x00000800
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_6_LUTOUT203(v) \
+ (((v) << 11) & BM_PXP_WFE_B_STG1_8X1_OUT2_6_LUTOUT203)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_6_LUTOUT202 0x00000400
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_6_LUTOUT202(v) \
+ (((v) << 10) & BM_PXP_WFE_B_STG1_8X1_OUT2_6_LUTOUT202)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_6_LUTOUT201 0x00000200
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_6_LUTOUT201(v) \
+ (((v) << 9) & BM_PXP_WFE_B_STG1_8X1_OUT2_6_LUTOUT201)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_6_LUTOUT200 0x00000100
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_6_LUTOUT200(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STG1_8X1_OUT2_6_LUTOUT200)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_6_LUTOUT199 0x00000080
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_6_LUTOUT199(v) \
+ (((v) << 7) & BM_PXP_WFE_B_STG1_8X1_OUT2_6_LUTOUT199)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_6_LUTOUT198 0x00000040
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_6_LUTOUT198(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STG1_8X1_OUT2_6_LUTOUT198)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_6_LUTOUT197 0x00000020
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_6_LUTOUT197(v) \
+ (((v) << 5) & BM_PXP_WFE_B_STG1_8X1_OUT2_6_LUTOUT197)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_6_LUTOUT196 0x00000010
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_6_LUTOUT196(v) \
+ (((v) << 4) & BM_PXP_WFE_B_STG1_8X1_OUT2_6_LUTOUT196)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_6_LUTOUT195 0x00000008
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_6_LUTOUT195(v) \
+ (((v) << 3) & BM_PXP_WFE_B_STG1_8X1_OUT2_6_LUTOUT195)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_6_LUTOUT194 0x00000004
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_6_LUTOUT194(v) \
+ (((v) << 2) & BM_PXP_WFE_B_STG1_8X1_OUT2_6_LUTOUT194)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_6_LUTOUT193 0x00000002
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_6_LUTOUT193(v) \
+ (((v) << 1) & BM_PXP_WFE_B_STG1_8X1_OUT2_6_LUTOUT193)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_6_LUTOUT192 0x00000001
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_6_LUTOUT192(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STG1_8X1_OUT2_6_LUTOUT192)
+
+#define HW_PXP_WFE_B_STG1_8X1_OUT2_7 (0x00002200)
+
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_7_LUTOUT255 0x80000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_7_LUTOUT255(v) \
+ (((v) << 31) & BM_PXP_WFE_B_STG1_8X1_OUT2_7_LUTOUT255)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_7_LUTOUT254 0x40000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_7_LUTOUT254(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STG1_8X1_OUT2_7_LUTOUT254)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_7_LUTOUT253 0x20000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_7_LUTOUT253(v) \
+ (((v) << 29) & BM_PXP_WFE_B_STG1_8X1_OUT2_7_LUTOUT253)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_7_LUTOUT252 0x10000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_7_LUTOUT252(v) \
+ (((v) << 28) & BM_PXP_WFE_B_STG1_8X1_OUT2_7_LUTOUT252)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_7_LUTOUT251 0x08000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_7_LUTOUT251(v) \
+ (((v) << 27) & BM_PXP_WFE_B_STG1_8X1_OUT2_7_LUTOUT251)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_7_LUTOUT250 0x04000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_7_LUTOUT250(v) \
+ (((v) << 26) & BM_PXP_WFE_B_STG1_8X1_OUT2_7_LUTOUT250)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_7_LUTOUT249 0x02000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_7_LUTOUT249(v) \
+ (((v) << 25) & BM_PXP_WFE_B_STG1_8X1_OUT2_7_LUTOUT249)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_7_LUTOUT248 0x01000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_7_LUTOUT248(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STG1_8X1_OUT2_7_LUTOUT248)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_7_LUTOUT247 0x00800000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_7_LUTOUT247(v) \
+ (((v) << 23) & BM_PXP_WFE_B_STG1_8X1_OUT2_7_LUTOUT247)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_7_LUTOUT246 0x00400000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_7_LUTOUT246(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STG1_8X1_OUT2_7_LUTOUT246)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_7_LUTOUT245 0x00200000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_7_LUTOUT245(v) \
+ (((v) << 21) & BM_PXP_WFE_B_STG1_8X1_OUT2_7_LUTOUT245)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_7_LUTOUT244 0x00100000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_7_LUTOUT244(v) \
+ (((v) << 20) & BM_PXP_WFE_B_STG1_8X1_OUT2_7_LUTOUT244)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_7_LUTOUT243 0x00080000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_7_LUTOUT243(v) \
+ (((v) << 19) & BM_PXP_WFE_B_STG1_8X1_OUT2_7_LUTOUT243)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_7_LUTOUT242 0x00040000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_7_LUTOUT242(v) \
+ (((v) << 18) & BM_PXP_WFE_B_STG1_8X1_OUT2_7_LUTOUT242)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_7_LUTOUT241 0x00020000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_7_LUTOUT241(v) \
+ (((v) << 17) & BM_PXP_WFE_B_STG1_8X1_OUT2_7_LUTOUT241)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_7_LUTOUT240 0x00010000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_7_LUTOUT240(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STG1_8X1_OUT2_7_LUTOUT240)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_7_LUTOUT239 0x00008000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_7_LUTOUT239(v) \
+ (((v) << 15) & BM_PXP_WFE_B_STG1_8X1_OUT2_7_LUTOUT239)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_7_LUTOUT238 0x00004000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_7_LUTOUT238(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STG1_8X1_OUT2_7_LUTOUT238)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_7_LUTOUT237 0x00002000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_7_LUTOUT237(v) \
+ (((v) << 13) & BM_PXP_WFE_B_STG1_8X1_OUT2_7_LUTOUT237)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_7_LUTOUT236 0x00001000
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_7_LUTOUT236(v) \
+ (((v) << 12) & BM_PXP_WFE_B_STG1_8X1_OUT2_7_LUTOUT236)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_7_LUTOUT235 0x00000800
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_7_LUTOUT235(v) \
+ (((v) << 11) & BM_PXP_WFE_B_STG1_8X1_OUT2_7_LUTOUT235)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_7_LUTOUT234 0x00000400
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_7_LUTOUT234(v) \
+ (((v) << 10) & BM_PXP_WFE_B_STG1_8X1_OUT2_7_LUTOUT234)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_7_LUTOUT233 0x00000200
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_7_LUTOUT233(v) \
+ (((v) << 9) & BM_PXP_WFE_B_STG1_8X1_OUT2_7_LUTOUT233)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_7_LUTOUT232 0x00000100
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_7_LUTOUT232(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STG1_8X1_OUT2_7_LUTOUT232)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_7_LUTOUT231 0x00000080
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_7_LUTOUT231(v) \
+ (((v) << 7) & BM_PXP_WFE_B_STG1_8X1_OUT2_7_LUTOUT231)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_7_LUTOUT230 0x00000040
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_7_LUTOUT230(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STG1_8X1_OUT2_7_LUTOUT230)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_7_LUTOUT229 0x00000020
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_7_LUTOUT229(v) \
+ (((v) << 5) & BM_PXP_WFE_B_STG1_8X1_OUT2_7_LUTOUT229)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_7_LUTOUT228 0x00000010
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_7_LUTOUT228(v) \
+ (((v) << 4) & BM_PXP_WFE_B_STG1_8X1_OUT2_7_LUTOUT228)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_7_LUTOUT227 0x00000008
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_7_LUTOUT227(v) \
+ (((v) << 3) & BM_PXP_WFE_B_STG1_8X1_OUT2_7_LUTOUT227)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_7_LUTOUT226 0x00000004
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_7_LUTOUT226(v) \
+ (((v) << 2) & BM_PXP_WFE_B_STG1_8X1_OUT2_7_LUTOUT226)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_7_LUTOUT225 0x00000002
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_7_LUTOUT225(v) \
+ (((v) << 1) & BM_PXP_WFE_B_STG1_8X1_OUT2_7_LUTOUT225)
+#define BM_PXP_WFE_B_STG1_8X1_OUT2_7_LUTOUT224 0x00000001
+#define BF_PXP_WFE_B_STG1_8X1_OUT2_7_LUTOUT224(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STG1_8X1_OUT2_7_LUTOUT224)
+
+#define HW_PXP_WFE_B_STG1_8X1_OUT3_0 (0x00002210)
+
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_0_LUTOUT31 0x80000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_0_LUTOUT31(v) \
+ (((v) << 31) & BM_PXP_WFE_B_STG1_8X1_OUT3_0_LUTOUT31)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_0_LUTOUT30 0x40000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_0_LUTOUT30(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STG1_8X1_OUT3_0_LUTOUT30)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_0_LUTOUT29 0x20000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_0_LUTOUT29(v) \
+ (((v) << 29) & BM_PXP_WFE_B_STG1_8X1_OUT3_0_LUTOUT29)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_0_LUTOUT28 0x10000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_0_LUTOUT28(v) \
+ (((v) << 28) & BM_PXP_WFE_B_STG1_8X1_OUT3_0_LUTOUT28)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_0_LUTOUT27 0x08000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_0_LUTOUT27(v) \
+ (((v) << 27) & BM_PXP_WFE_B_STG1_8X1_OUT3_0_LUTOUT27)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_0_LUTOUT26 0x04000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_0_LUTOUT26(v) \
+ (((v) << 26) & BM_PXP_WFE_B_STG1_8X1_OUT3_0_LUTOUT26)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_0_LUTOUT25 0x02000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_0_LUTOUT25(v) \
+ (((v) << 25) & BM_PXP_WFE_B_STG1_8X1_OUT3_0_LUTOUT25)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_0_LUTOUT24 0x01000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_0_LUTOUT24(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STG1_8X1_OUT3_0_LUTOUT24)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_0_LUTOUT23 0x00800000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_0_LUTOUT23(v) \
+ (((v) << 23) & BM_PXP_WFE_B_STG1_8X1_OUT3_0_LUTOUT23)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_0_LUTOUT22 0x00400000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_0_LUTOUT22(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STG1_8X1_OUT3_0_LUTOUT22)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_0_LUTOUT21 0x00200000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_0_LUTOUT21(v) \
+ (((v) << 21) & BM_PXP_WFE_B_STG1_8X1_OUT3_0_LUTOUT21)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_0_LUTOUT20 0x00100000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_0_LUTOUT20(v) \
+ (((v) << 20) & BM_PXP_WFE_B_STG1_8X1_OUT3_0_LUTOUT20)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_0_LUTOUT19 0x00080000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_0_LUTOUT19(v) \
+ (((v) << 19) & BM_PXP_WFE_B_STG1_8X1_OUT3_0_LUTOUT19)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_0_LUTOUT18 0x00040000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_0_LUTOUT18(v) \
+ (((v) << 18) & BM_PXP_WFE_B_STG1_8X1_OUT3_0_LUTOUT18)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_0_LUTOUT17 0x00020000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_0_LUTOUT17(v) \
+ (((v) << 17) & BM_PXP_WFE_B_STG1_8X1_OUT3_0_LUTOUT17)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_0_LUTOUT16 0x00010000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_0_LUTOUT16(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STG1_8X1_OUT3_0_LUTOUT16)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_0_LUTOUT15 0x00008000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_0_LUTOUT15(v) \
+ (((v) << 15) & BM_PXP_WFE_B_STG1_8X1_OUT3_0_LUTOUT15)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_0_LUTOUT14 0x00004000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_0_LUTOUT14(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STG1_8X1_OUT3_0_LUTOUT14)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_0_LUTOUT13 0x00002000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_0_LUTOUT13(v) \
+ (((v) << 13) & BM_PXP_WFE_B_STG1_8X1_OUT3_0_LUTOUT13)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_0_LUTOUT12 0x00001000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_0_LUTOUT12(v) \
+ (((v) << 12) & BM_PXP_WFE_B_STG1_8X1_OUT3_0_LUTOUT12)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_0_LUTOUT11 0x00000800
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_0_LUTOUT11(v) \
+ (((v) << 11) & BM_PXP_WFE_B_STG1_8X1_OUT3_0_LUTOUT11)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_0_LUTOUT10 0x00000400
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_0_LUTOUT10(v) \
+ (((v) << 10) & BM_PXP_WFE_B_STG1_8X1_OUT3_0_LUTOUT10)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_0_LUTOUT9 0x00000200
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_0_LUTOUT9(v) \
+ (((v) << 9) & BM_PXP_WFE_B_STG1_8X1_OUT3_0_LUTOUT9)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_0_LUTOUT8 0x00000100
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_0_LUTOUT8(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STG1_8X1_OUT3_0_LUTOUT8)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_0_LUTOUT7 0x00000080
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_0_LUTOUT7(v) \
+ (((v) << 7) & BM_PXP_WFE_B_STG1_8X1_OUT3_0_LUTOUT7)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_0_LUTOUT6 0x00000040
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_0_LUTOUT6(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STG1_8X1_OUT3_0_LUTOUT6)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_0_LUTOUT5 0x00000020
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_0_LUTOUT5(v) \
+ (((v) << 5) & BM_PXP_WFE_B_STG1_8X1_OUT3_0_LUTOUT5)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_0_LUTOUT4 0x00000010
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_0_LUTOUT4(v) \
+ (((v) << 4) & BM_PXP_WFE_B_STG1_8X1_OUT3_0_LUTOUT4)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_0_LUTOUT3 0x00000008
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_0_LUTOUT3(v) \
+ (((v) << 3) & BM_PXP_WFE_B_STG1_8X1_OUT3_0_LUTOUT3)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_0_LUTOUT2 0x00000004
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_0_LUTOUT2(v) \
+ (((v) << 2) & BM_PXP_WFE_B_STG1_8X1_OUT3_0_LUTOUT2)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_0_LUTOUT1 0x00000002
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_0_LUTOUT1(v) \
+ (((v) << 1) & BM_PXP_WFE_B_STG1_8X1_OUT3_0_LUTOUT1)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_0_LUTOUT0 0x00000001
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_0_LUTOUT0(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STG1_8X1_OUT3_0_LUTOUT0)
+
+#define HW_PXP_WFE_B_STG1_8X1_OUT3_1 (0x00002220)
+
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_1_LUTOUT63 0x80000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_1_LUTOUT63(v) \
+ (((v) << 31) & BM_PXP_WFE_B_STG1_8X1_OUT3_1_LUTOUT63)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_1_LUTOUT62 0x40000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_1_LUTOUT62(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STG1_8X1_OUT3_1_LUTOUT62)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_1_LUTOUT61 0x20000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_1_LUTOUT61(v) \
+ (((v) << 29) & BM_PXP_WFE_B_STG1_8X1_OUT3_1_LUTOUT61)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_1_LUTOUT60 0x10000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_1_LUTOUT60(v) \
+ (((v) << 28) & BM_PXP_WFE_B_STG1_8X1_OUT3_1_LUTOUT60)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_1_LUTOUT59 0x08000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_1_LUTOUT59(v) \
+ (((v) << 27) & BM_PXP_WFE_B_STG1_8X1_OUT3_1_LUTOUT59)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_1_LUTOUT58 0x04000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_1_LUTOUT58(v) \
+ (((v) << 26) & BM_PXP_WFE_B_STG1_8X1_OUT3_1_LUTOUT58)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_1_LUTOUT57 0x02000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_1_LUTOUT57(v) \
+ (((v) << 25) & BM_PXP_WFE_B_STG1_8X1_OUT3_1_LUTOUT57)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_1_LUTOUT56 0x01000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_1_LUTOUT56(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STG1_8X1_OUT3_1_LUTOUT56)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_1_LUTOUT55 0x00800000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_1_LUTOUT55(v) \
+ (((v) << 23) & BM_PXP_WFE_B_STG1_8X1_OUT3_1_LUTOUT55)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_1_LUTOUT54 0x00400000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_1_LUTOUT54(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STG1_8X1_OUT3_1_LUTOUT54)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_1_LUTOUT53 0x00200000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_1_LUTOUT53(v) \
+ (((v) << 21) & BM_PXP_WFE_B_STG1_8X1_OUT3_1_LUTOUT53)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_1_LUTOUT52 0x00100000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_1_LUTOUT52(v) \
+ (((v) << 20) & BM_PXP_WFE_B_STG1_8X1_OUT3_1_LUTOUT52)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_1_LUTOUT51 0x00080000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_1_LUTOUT51(v) \
+ (((v) << 19) & BM_PXP_WFE_B_STG1_8X1_OUT3_1_LUTOUT51)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_1_LUTOUT50 0x00040000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_1_LUTOUT50(v) \
+ (((v) << 18) & BM_PXP_WFE_B_STG1_8X1_OUT3_1_LUTOUT50)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_1_LUTOUT49 0x00020000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_1_LUTOUT49(v) \
+ (((v) << 17) & BM_PXP_WFE_B_STG1_8X1_OUT3_1_LUTOUT49)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_1_LUTOUT48 0x00010000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_1_LUTOUT48(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STG1_8X1_OUT3_1_LUTOUT48)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_1_LUTOUT47 0x00008000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_1_LUTOUT47(v) \
+ (((v) << 15) & BM_PXP_WFE_B_STG1_8X1_OUT3_1_LUTOUT47)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_1_LUTOUT46 0x00004000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_1_LUTOUT46(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STG1_8X1_OUT3_1_LUTOUT46)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_1_LUTOUT45 0x00002000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_1_LUTOUT45(v) \
+ (((v) << 13) & BM_PXP_WFE_B_STG1_8X1_OUT3_1_LUTOUT45)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_1_LUTOUT44 0x00001000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_1_LUTOUT44(v) \
+ (((v) << 12) & BM_PXP_WFE_B_STG1_8X1_OUT3_1_LUTOUT44)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_1_LUTOUT43 0x00000800
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_1_LUTOUT43(v) \
+ (((v) << 11) & BM_PXP_WFE_B_STG1_8X1_OUT3_1_LUTOUT43)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_1_LUTOUT42 0x00000400
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_1_LUTOUT42(v) \
+ (((v) << 10) & BM_PXP_WFE_B_STG1_8X1_OUT3_1_LUTOUT42)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_1_LUTOUT41 0x00000200
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_1_LUTOUT41(v) \
+ (((v) << 9) & BM_PXP_WFE_B_STG1_8X1_OUT3_1_LUTOUT41)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_1_LUTOUT40 0x00000100
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_1_LUTOUT40(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STG1_8X1_OUT3_1_LUTOUT40)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_1_LUTOUT39 0x00000080
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_1_LUTOUT39(v) \
+ (((v) << 7) & BM_PXP_WFE_B_STG1_8X1_OUT3_1_LUTOUT39)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_1_LUTOUT38 0x00000040
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_1_LUTOUT38(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STG1_8X1_OUT3_1_LUTOUT38)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_1_LUTOUT37 0x00000020
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_1_LUTOUT37(v) \
+ (((v) << 5) & BM_PXP_WFE_B_STG1_8X1_OUT3_1_LUTOUT37)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_1_LUTOUT36 0x00000010
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_1_LUTOUT36(v) \
+ (((v) << 4) & BM_PXP_WFE_B_STG1_8X1_OUT3_1_LUTOUT36)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_1_LUTOUT35 0x00000008
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_1_LUTOUT35(v) \
+ (((v) << 3) & BM_PXP_WFE_B_STG1_8X1_OUT3_1_LUTOUT35)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_1_LUTOUT34 0x00000004
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_1_LUTOUT34(v) \
+ (((v) << 2) & BM_PXP_WFE_B_STG1_8X1_OUT3_1_LUTOUT34)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_1_LUTOUT33 0x00000002
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_1_LUTOUT33(v) \
+ (((v) << 1) & BM_PXP_WFE_B_STG1_8X1_OUT3_1_LUTOUT33)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_1_LUTOUT32 0x00000001
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_1_LUTOUT32(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STG1_8X1_OUT3_1_LUTOUT32)
+
+#define HW_PXP_WFE_B_STG1_8X1_OUT3_2 (0x00002230)
+
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_2_LUTOUT95 0x80000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_2_LUTOUT95(v) \
+ (((v) << 31) & BM_PXP_WFE_B_STG1_8X1_OUT3_2_LUTOUT95)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_2_LUTOUT94 0x40000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_2_LUTOUT94(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STG1_8X1_OUT3_2_LUTOUT94)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_2_LUTOUT93 0x20000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_2_LUTOUT93(v) \
+ (((v) << 29) & BM_PXP_WFE_B_STG1_8X1_OUT3_2_LUTOUT93)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_2_LUTOUT92 0x10000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_2_LUTOUT92(v) \
+ (((v) << 28) & BM_PXP_WFE_B_STG1_8X1_OUT3_2_LUTOUT92)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_2_LUTOUT91 0x08000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_2_LUTOUT91(v) \
+ (((v) << 27) & BM_PXP_WFE_B_STG1_8X1_OUT3_2_LUTOUT91)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_2_LUTOUT90 0x04000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_2_LUTOUT90(v) \
+ (((v) << 26) & BM_PXP_WFE_B_STG1_8X1_OUT3_2_LUTOUT90)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_2_LUTOUT89 0x02000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_2_LUTOUT89(v) \
+ (((v) << 25) & BM_PXP_WFE_B_STG1_8X1_OUT3_2_LUTOUT89)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_2_LUTOUT88 0x01000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_2_LUTOUT88(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STG1_8X1_OUT3_2_LUTOUT88)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_2_LUTOUT87 0x00800000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_2_LUTOUT87(v) \
+ (((v) << 23) & BM_PXP_WFE_B_STG1_8X1_OUT3_2_LUTOUT87)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_2_LUTOUT86 0x00400000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_2_LUTOUT86(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STG1_8X1_OUT3_2_LUTOUT86)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_2_LUTOUT85 0x00200000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_2_LUTOUT85(v) \
+ (((v) << 21) & BM_PXP_WFE_B_STG1_8X1_OUT3_2_LUTOUT85)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_2_LUTOUT84 0x00100000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_2_LUTOUT84(v) \
+ (((v) << 20) & BM_PXP_WFE_B_STG1_8X1_OUT3_2_LUTOUT84)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_2_LUTOUT83 0x00080000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_2_LUTOUT83(v) \
+ (((v) << 19) & BM_PXP_WFE_B_STG1_8X1_OUT3_2_LUTOUT83)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_2_LUTOUT82 0x00040000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_2_LUTOUT82(v) \
+ (((v) << 18) & BM_PXP_WFE_B_STG1_8X1_OUT3_2_LUTOUT82)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_2_LUTOUT81 0x00020000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_2_LUTOUT81(v) \
+ (((v) << 17) & BM_PXP_WFE_B_STG1_8X1_OUT3_2_LUTOUT81)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_2_LUTOUT80 0x00010000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_2_LUTOUT80(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STG1_8X1_OUT3_2_LUTOUT80)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_2_LUTOUT79 0x00008000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_2_LUTOUT79(v) \
+ (((v) << 15) & BM_PXP_WFE_B_STG1_8X1_OUT3_2_LUTOUT79)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_2_LUTOUT78 0x00004000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_2_LUTOUT78(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STG1_8X1_OUT3_2_LUTOUT78)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_2_LUTOUT77 0x00002000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_2_LUTOUT77(v) \
+ (((v) << 13) & BM_PXP_WFE_B_STG1_8X1_OUT3_2_LUTOUT77)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_2_LUTOUT76 0x00001000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_2_LUTOUT76(v) \
+ (((v) << 12) & BM_PXP_WFE_B_STG1_8X1_OUT3_2_LUTOUT76)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_2_LUTOUT75 0x00000800
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_2_LUTOUT75(v) \
+ (((v) << 11) & BM_PXP_WFE_B_STG1_8X1_OUT3_2_LUTOUT75)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_2_LUTOUT74 0x00000400
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_2_LUTOUT74(v) \
+ (((v) << 10) & BM_PXP_WFE_B_STG1_8X1_OUT3_2_LUTOUT74)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_2_LUTOUT73 0x00000200
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_2_LUTOUT73(v) \
+ (((v) << 9) & BM_PXP_WFE_B_STG1_8X1_OUT3_2_LUTOUT73)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_2_LUTOUT72 0x00000100
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_2_LUTOUT72(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STG1_8X1_OUT3_2_LUTOUT72)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_2_LUTOUT71 0x00000080
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_2_LUTOUT71(v) \
+ (((v) << 7) & BM_PXP_WFE_B_STG1_8X1_OUT3_2_LUTOUT71)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_2_LUTOUT70 0x00000040
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_2_LUTOUT70(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STG1_8X1_OUT3_2_LUTOUT70)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_2_LUTOUT69 0x00000020
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_2_LUTOUT69(v) \
+ (((v) << 5) & BM_PXP_WFE_B_STG1_8X1_OUT3_2_LUTOUT69)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_2_LUTOUT68 0x00000010
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_2_LUTOUT68(v) \
+ (((v) << 4) & BM_PXP_WFE_B_STG1_8X1_OUT3_2_LUTOUT68)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_2_LUTOUT67 0x00000008
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_2_LUTOUT67(v) \
+ (((v) << 3) & BM_PXP_WFE_B_STG1_8X1_OUT3_2_LUTOUT67)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_2_LUTOUT66 0x00000004
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_2_LUTOUT66(v) \
+ (((v) << 2) & BM_PXP_WFE_B_STG1_8X1_OUT3_2_LUTOUT66)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_2_LUTOUT65 0x00000002
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_2_LUTOUT65(v) \
+ (((v) << 1) & BM_PXP_WFE_B_STG1_8X1_OUT3_2_LUTOUT65)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_2_LUTOUT64 0x00000001
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_2_LUTOUT64(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STG1_8X1_OUT3_2_LUTOUT64)
+
+#define HW_PXP_WFE_B_STG1_8X1_OUT3_3 (0x00002240)
+
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_3_LUTOUT127 0x80000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_3_LUTOUT127(v) \
+ (((v) << 31) & BM_PXP_WFE_B_STG1_8X1_OUT3_3_LUTOUT127)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_3_LUTOUT126 0x40000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_3_LUTOUT126(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STG1_8X1_OUT3_3_LUTOUT126)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_3_LUTOUT125 0x20000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_3_LUTOUT125(v) \
+ (((v) << 29) & BM_PXP_WFE_B_STG1_8X1_OUT3_3_LUTOUT125)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_3_LUTOUT124 0x10000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_3_LUTOUT124(v) \
+ (((v) << 28) & BM_PXP_WFE_B_STG1_8X1_OUT3_3_LUTOUT124)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_3_LUTOUT123 0x08000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_3_LUTOUT123(v) \
+ (((v) << 27) & BM_PXP_WFE_B_STG1_8X1_OUT3_3_LUTOUT123)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_3_LUTOUT122 0x04000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_3_LUTOUT122(v) \
+ (((v) << 26) & BM_PXP_WFE_B_STG1_8X1_OUT3_3_LUTOUT122)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_3_LUTOUT121 0x02000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_3_LUTOUT121(v) \
+ (((v) << 25) & BM_PXP_WFE_B_STG1_8X1_OUT3_3_LUTOUT121)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_3_LUTOUT120 0x01000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_3_LUTOUT120(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STG1_8X1_OUT3_3_LUTOUT120)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_3_LUTOUT119 0x00800000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_3_LUTOUT119(v) \
+ (((v) << 23) & BM_PXP_WFE_B_STG1_8X1_OUT3_3_LUTOUT119)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_3_LUTOUT118 0x00400000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_3_LUTOUT118(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STG1_8X1_OUT3_3_LUTOUT118)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_3_LUTOUT117 0x00200000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_3_LUTOUT117(v) \
+ (((v) << 21) & BM_PXP_WFE_B_STG1_8X1_OUT3_3_LUTOUT117)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_3_LUTOUT116 0x00100000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_3_LUTOUT116(v) \
+ (((v) << 20) & BM_PXP_WFE_B_STG1_8X1_OUT3_3_LUTOUT116)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_3_LUTOUT115 0x00080000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_3_LUTOUT115(v) \
+ (((v) << 19) & BM_PXP_WFE_B_STG1_8X1_OUT3_3_LUTOUT115)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_3_LUTOUT114 0x00040000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_3_LUTOUT114(v) \
+ (((v) << 18) & BM_PXP_WFE_B_STG1_8X1_OUT3_3_LUTOUT114)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_3_LUTOUT113 0x00020000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_3_LUTOUT113(v) \
+ (((v) << 17) & BM_PXP_WFE_B_STG1_8X1_OUT3_3_LUTOUT113)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_3_LUTOUT112 0x00010000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_3_LUTOUT112(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STG1_8X1_OUT3_3_LUTOUT112)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_3_LUTOUT111 0x00008000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_3_LUTOUT111(v) \
+ (((v) << 15) & BM_PXP_WFE_B_STG1_8X1_OUT3_3_LUTOUT111)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_3_LUTOUT110 0x00004000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_3_LUTOUT110(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STG1_8X1_OUT3_3_LUTOUT110)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_3_LUTOUT109 0x00002000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_3_LUTOUT109(v) \
+ (((v) << 13) & BM_PXP_WFE_B_STG1_8X1_OUT3_3_LUTOUT109)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_3_LUTOUT108 0x00001000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_3_LUTOUT108(v) \
+ (((v) << 12) & BM_PXP_WFE_B_STG1_8X1_OUT3_3_LUTOUT108)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_3_LUTOUT107 0x00000800
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_3_LUTOUT107(v) \
+ (((v) << 11) & BM_PXP_WFE_B_STG1_8X1_OUT3_3_LUTOUT107)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_3_LUTOUT106 0x00000400
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_3_LUTOUT106(v) \
+ (((v) << 10) & BM_PXP_WFE_B_STG1_8X1_OUT3_3_LUTOUT106)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_3_LUTOUT105 0x00000200
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_3_LUTOUT105(v) \
+ (((v) << 9) & BM_PXP_WFE_B_STG1_8X1_OUT3_3_LUTOUT105)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_3_LUTOUT104 0x00000100
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_3_LUTOUT104(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STG1_8X1_OUT3_3_LUTOUT104)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_3_LUTOUT103 0x00000080
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_3_LUTOUT103(v) \
+ (((v) << 7) & BM_PXP_WFE_B_STG1_8X1_OUT3_3_LUTOUT103)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_3_LUTOUT102 0x00000040
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_3_LUTOUT102(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STG1_8X1_OUT3_3_LUTOUT102)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_3_LUTOUT101 0x00000020
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_3_LUTOUT101(v) \
+ (((v) << 5) & BM_PXP_WFE_B_STG1_8X1_OUT3_3_LUTOUT101)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_3_LUTOUT100 0x00000010
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_3_LUTOUT100(v) \
+ (((v) << 4) & BM_PXP_WFE_B_STG1_8X1_OUT3_3_LUTOUT100)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_3_LUTOUT99 0x00000008
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_3_LUTOUT99(v) \
+ (((v) << 3) & BM_PXP_WFE_B_STG1_8X1_OUT3_3_LUTOUT99)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_3_LUTOUT98 0x00000004
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_3_LUTOUT98(v) \
+ (((v) << 2) & BM_PXP_WFE_B_STG1_8X1_OUT3_3_LUTOUT98)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_3_LUTOUT97 0x00000002
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_3_LUTOUT97(v) \
+ (((v) << 1) & BM_PXP_WFE_B_STG1_8X1_OUT3_3_LUTOUT97)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_3_LUTOUT96 0x00000001
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_3_LUTOUT96(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STG1_8X1_OUT3_3_LUTOUT96)
+
+#define HW_PXP_WFE_B_STG1_8X1_OUT3_4 (0x00002250)
+
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_4_LUTOUT159 0x80000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_4_LUTOUT159(v) \
+ (((v) << 31) & BM_PXP_WFE_B_STG1_8X1_OUT3_4_LUTOUT159)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_4_LUTOUT158 0x40000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_4_LUTOUT158(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STG1_8X1_OUT3_4_LUTOUT158)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_4_LUTOUT157 0x20000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_4_LUTOUT157(v) \
+ (((v) << 29) & BM_PXP_WFE_B_STG1_8X1_OUT3_4_LUTOUT157)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_4_LUTOUT156 0x10000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_4_LUTOUT156(v) \
+ (((v) << 28) & BM_PXP_WFE_B_STG1_8X1_OUT3_4_LUTOUT156)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_4_LUTOUT155 0x08000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_4_LUTOUT155(v) \
+ (((v) << 27) & BM_PXP_WFE_B_STG1_8X1_OUT3_4_LUTOUT155)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_4_LUTOUT154 0x04000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_4_LUTOUT154(v) \
+ (((v) << 26) & BM_PXP_WFE_B_STG1_8X1_OUT3_4_LUTOUT154)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_4_LUTOUT153 0x02000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_4_LUTOUT153(v) \
+ (((v) << 25) & BM_PXP_WFE_B_STG1_8X1_OUT3_4_LUTOUT153)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_4_LUTOUT152 0x01000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_4_LUTOUT152(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STG1_8X1_OUT3_4_LUTOUT152)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_4_LUTOUT151 0x00800000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_4_LUTOUT151(v) \
+ (((v) << 23) & BM_PXP_WFE_B_STG1_8X1_OUT3_4_LUTOUT151)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_4_LUTOUT150 0x00400000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_4_LUTOUT150(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STG1_8X1_OUT3_4_LUTOUT150)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_4_LUTOUT149 0x00200000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_4_LUTOUT149(v) \
+ (((v) << 21) & BM_PXP_WFE_B_STG1_8X1_OUT3_4_LUTOUT149)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_4_LUTOUT148 0x00100000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_4_LUTOUT148(v) \
+ (((v) << 20) & BM_PXP_WFE_B_STG1_8X1_OUT3_4_LUTOUT148)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_4_LUTOUT147 0x00080000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_4_LUTOUT147(v) \
+ (((v) << 19) & BM_PXP_WFE_B_STG1_8X1_OUT3_4_LUTOUT147)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_4_LUTOUT146 0x00040000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_4_LUTOUT146(v) \
+ (((v) << 18) & BM_PXP_WFE_B_STG1_8X1_OUT3_4_LUTOUT146)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_4_LUTOUT145 0x00020000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_4_LUTOUT145(v) \
+ (((v) << 17) & BM_PXP_WFE_B_STG1_8X1_OUT3_4_LUTOUT145)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_4_LUTOUT144 0x00010000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_4_LUTOUT144(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STG1_8X1_OUT3_4_LUTOUT144)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_4_LUTOUT143 0x00008000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_4_LUTOUT143(v) \
+ (((v) << 15) & BM_PXP_WFE_B_STG1_8X1_OUT3_4_LUTOUT143)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_4_LUTOUT142 0x00004000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_4_LUTOUT142(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STG1_8X1_OUT3_4_LUTOUT142)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_4_LUTOUT141 0x00002000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_4_LUTOUT141(v) \
+ (((v) << 13) & BM_PXP_WFE_B_STG1_8X1_OUT3_4_LUTOUT141)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_4_LUTOUT140 0x00001000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_4_LUTOUT140(v) \
+ (((v) << 12) & BM_PXP_WFE_B_STG1_8X1_OUT3_4_LUTOUT140)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_4_LUTOUT139 0x00000800
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_4_LUTOUT139(v) \
+ (((v) << 11) & BM_PXP_WFE_B_STG1_8X1_OUT3_4_LUTOUT139)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_4_LUTOUT138 0x00000400
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_4_LUTOUT138(v) \
+ (((v) << 10) & BM_PXP_WFE_B_STG1_8X1_OUT3_4_LUTOUT138)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_4_LUTOUT137 0x00000200
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_4_LUTOUT137(v) \
+ (((v) << 9) & BM_PXP_WFE_B_STG1_8X1_OUT3_4_LUTOUT137)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_4_LUTOUT136 0x00000100
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_4_LUTOUT136(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STG1_8X1_OUT3_4_LUTOUT136)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_4_LUTOUT135 0x00000080
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_4_LUTOUT135(v) \
+ (((v) << 7) & BM_PXP_WFE_B_STG1_8X1_OUT3_4_LUTOUT135)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_4_LUTOUT134 0x00000040
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_4_LUTOUT134(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STG1_8X1_OUT3_4_LUTOUT134)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_4_LUTOUT133 0x00000020
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_4_LUTOUT133(v) \
+ (((v) << 5) & BM_PXP_WFE_B_STG1_8X1_OUT3_4_LUTOUT133)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_4_LUTOUT132 0x00000010
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_4_LUTOUT132(v) \
+ (((v) << 4) & BM_PXP_WFE_B_STG1_8X1_OUT3_4_LUTOUT132)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_4_LUTOUT131 0x00000008
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_4_LUTOUT131(v) \
+ (((v) << 3) & BM_PXP_WFE_B_STG1_8X1_OUT3_4_LUTOUT131)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_4_LUTOUT130 0x00000004
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_4_LUTOUT130(v) \
+ (((v) << 2) & BM_PXP_WFE_B_STG1_8X1_OUT3_4_LUTOUT130)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_4_LUTOUT129 0x00000002
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_4_LUTOUT129(v) \
+ (((v) << 1) & BM_PXP_WFE_B_STG1_8X1_OUT3_4_LUTOUT129)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_4_LUTOUT128 0x00000001
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_4_LUTOUT128(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STG1_8X1_OUT3_4_LUTOUT128)
+
+#define HW_PXP_WFE_B_STG1_8X1_OUT3_5 (0x00002260)
+
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_5_LUTOUT191 0x80000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_5_LUTOUT191(v) \
+ (((v) << 31) & BM_PXP_WFE_B_STG1_8X1_OUT3_5_LUTOUT191)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_5_LUTOUT190 0x40000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_5_LUTOUT190(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STG1_8X1_OUT3_5_LUTOUT190)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_5_LUTOUT189 0x20000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_5_LUTOUT189(v) \
+ (((v) << 29) & BM_PXP_WFE_B_STG1_8X1_OUT3_5_LUTOUT189)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_5_LUTOUT188 0x10000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_5_LUTOUT188(v) \
+ (((v) << 28) & BM_PXP_WFE_B_STG1_8X1_OUT3_5_LUTOUT188)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_5_LUTOUT187 0x08000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_5_LUTOUT187(v) \
+ (((v) << 27) & BM_PXP_WFE_B_STG1_8X1_OUT3_5_LUTOUT187)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_5_LUTOUT186 0x04000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_5_LUTOUT186(v) \
+ (((v) << 26) & BM_PXP_WFE_B_STG1_8X1_OUT3_5_LUTOUT186)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_5_LUTOUT185 0x02000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_5_LUTOUT185(v) \
+ (((v) << 25) & BM_PXP_WFE_B_STG1_8X1_OUT3_5_LUTOUT185)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_5_LUTOUT184 0x01000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_5_LUTOUT184(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STG1_8X1_OUT3_5_LUTOUT184)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_5_LUTOUT183 0x00800000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_5_LUTOUT183(v) \
+ (((v) << 23) & BM_PXP_WFE_B_STG1_8X1_OUT3_5_LUTOUT183)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_5_LUTOUT182 0x00400000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_5_LUTOUT182(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STG1_8X1_OUT3_5_LUTOUT182)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_5_LUTOUT181 0x00200000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_5_LUTOUT181(v) \
+ (((v) << 21) & BM_PXP_WFE_B_STG1_8X1_OUT3_5_LUTOUT181)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_5_LUTOUT180 0x00100000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_5_LUTOUT180(v) \
+ (((v) << 20) & BM_PXP_WFE_B_STG1_8X1_OUT3_5_LUTOUT180)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_5_LUTOUT179 0x00080000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_5_LUTOUT179(v) \
+ (((v) << 19) & BM_PXP_WFE_B_STG1_8X1_OUT3_5_LUTOUT179)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_5_LUTOUT178 0x00040000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_5_LUTOUT178(v) \
+ (((v) << 18) & BM_PXP_WFE_B_STG1_8X1_OUT3_5_LUTOUT178)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_5_LUTOUT177 0x00020000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_5_LUTOUT177(v) \
+ (((v) << 17) & BM_PXP_WFE_B_STG1_8X1_OUT3_5_LUTOUT177)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_5_LUTOUT176 0x00010000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_5_LUTOUT176(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STG1_8X1_OUT3_5_LUTOUT176)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_5_LUTOUT175 0x00008000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_5_LUTOUT175(v) \
+ (((v) << 15) & BM_PXP_WFE_B_STG1_8X1_OUT3_5_LUTOUT175)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_5_LUTOUT174 0x00004000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_5_LUTOUT174(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STG1_8X1_OUT3_5_LUTOUT174)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_5_LUTOUT173 0x00002000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_5_LUTOUT173(v) \
+ (((v) << 13) & BM_PXP_WFE_B_STG1_8X1_OUT3_5_LUTOUT173)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_5_LUTOUT172 0x00001000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_5_LUTOUT172(v) \
+ (((v) << 12) & BM_PXP_WFE_B_STG1_8X1_OUT3_5_LUTOUT172)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_5_LUTOUT171 0x00000800
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_5_LUTOUT171(v) \
+ (((v) << 11) & BM_PXP_WFE_B_STG1_8X1_OUT3_5_LUTOUT171)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_5_LUTOUT170 0x00000400
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_5_LUTOUT170(v) \
+ (((v) << 10) & BM_PXP_WFE_B_STG1_8X1_OUT3_5_LUTOUT170)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_5_LUTOUT169 0x00000200
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_5_LUTOUT169(v) \
+ (((v) << 9) & BM_PXP_WFE_B_STG1_8X1_OUT3_5_LUTOUT169)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_5_LUTOUT168 0x00000100
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_5_LUTOUT168(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STG1_8X1_OUT3_5_LUTOUT168)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_5_LUTOUT167 0x00000080
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_5_LUTOUT167(v) \
+ (((v) << 7) & BM_PXP_WFE_B_STG1_8X1_OUT3_5_LUTOUT167)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_5_LUTOUT166 0x00000040
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_5_LUTOUT166(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STG1_8X1_OUT3_5_LUTOUT166)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_5_LUTOUT165 0x00000020
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_5_LUTOUT165(v) \
+ (((v) << 5) & BM_PXP_WFE_B_STG1_8X1_OUT3_5_LUTOUT165)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_5_LUTOUT164 0x00000010
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_5_LUTOUT164(v) \
+ (((v) << 4) & BM_PXP_WFE_B_STG1_8X1_OUT3_5_LUTOUT164)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_5_LUTOUT163 0x00000008
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_5_LUTOUT163(v) \
+ (((v) << 3) & BM_PXP_WFE_B_STG1_8X1_OUT3_5_LUTOUT163)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_5_LUTOUT162 0x00000004
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_5_LUTOUT162(v) \
+ (((v) << 2) & BM_PXP_WFE_B_STG1_8X1_OUT3_5_LUTOUT162)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_5_LUTOUT161 0x00000002
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_5_LUTOUT161(v) \
+ (((v) << 1) & BM_PXP_WFE_B_STG1_8X1_OUT3_5_LUTOUT161)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_5_LUTOUT160 0x00000001
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_5_LUTOUT160(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STG1_8X1_OUT3_5_LUTOUT160)
+
+#define HW_PXP_WFE_B_STG1_8X1_OUT3_6 (0x00002270)
+
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_6_LUTOUT223 0x80000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_6_LUTOUT223(v) \
+ (((v) << 31) & BM_PXP_WFE_B_STG1_8X1_OUT3_6_LUTOUT223)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_6_LUTOUT222 0x40000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_6_LUTOUT222(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STG1_8X1_OUT3_6_LUTOUT222)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_6_LUTOUT221 0x20000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_6_LUTOUT221(v) \
+ (((v) << 29) & BM_PXP_WFE_B_STG1_8X1_OUT3_6_LUTOUT221)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_6_LUTOUT220 0x10000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_6_LUTOUT220(v) \
+ (((v) << 28) & BM_PXP_WFE_B_STG1_8X1_OUT3_6_LUTOUT220)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_6_LUTOUT219 0x08000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_6_LUTOUT219(v) \
+ (((v) << 27) & BM_PXP_WFE_B_STG1_8X1_OUT3_6_LUTOUT219)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_6_LUTOUT218 0x04000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_6_LUTOUT218(v) \
+ (((v) << 26) & BM_PXP_WFE_B_STG1_8X1_OUT3_6_LUTOUT218)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_6_LUTOUT217 0x02000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_6_LUTOUT217(v) \
+ (((v) << 25) & BM_PXP_WFE_B_STG1_8X1_OUT3_6_LUTOUT217)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_6_LUTOUT216 0x01000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_6_LUTOUT216(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STG1_8X1_OUT3_6_LUTOUT216)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_6_LUTOUT215 0x00800000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_6_LUTOUT215(v) \
+ (((v) << 23) & BM_PXP_WFE_B_STG1_8X1_OUT3_6_LUTOUT215)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_6_LUTOUT214 0x00400000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_6_LUTOUT214(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STG1_8X1_OUT3_6_LUTOUT214)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_6_LUTOUT213 0x00200000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_6_LUTOUT213(v) \
+ (((v) << 21) & BM_PXP_WFE_B_STG1_8X1_OUT3_6_LUTOUT213)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_6_LUTOUT212 0x00100000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_6_LUTOUT212(v) \
+ (((v) << 20) & BM_PXP_WFE_B_STG1_8X1_OUT3_6_LUTOUT212)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_6_LUTOUT211 0x00080000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_6_LUTOUT211(v) \
+ (((v) << 19) & BM_PXP_WFE_B_STG1_8X1_OUT3_6_LUTOUT211)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_6_LUTOUT210 0x00040000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_6_LUTOUT210(v) \
+ (((v) << 18) & BM_PXP_WFE_B_STG1_8X1_OUT3_6_LUTOUT210)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_6_LUTOUT209 0x00020000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_6_LUTOUT209(v) \
+ (((v) << 17) & BM_PXP_WFE_B_STG1_8X1_OUT3_6_LUTOUT209)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_6_LUTOUT208 0x00010000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_6_LUTOUT208(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STG1_8X1_OUT3_6_LUTOUT208)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_6_LUTOUT207 0x00008000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_6_LUTOUT207(v) \
+ (((v) << 15) & BM_PXP_WFE_B_STG1_8X1_OUT3_6_LUTOUT207)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_6_LUTOUT206 0x00004000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_6_LUTOUT206(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STG1_8X1_OUT3_6_LUTOUT206)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_6_LUTOUT205 0x00002000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_6_LUTOUT205(v) \
+ (((v) << 13) & BM_PXP_WFE_B_STG1_8X1_OUT3_6_LUTOUT205)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_6_LUTOUT204 0x00001000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_6_LUTOUT204(v) \
+ (((v) << 12) & BM_PXP_WFE_B_STG1_8X1_OUT3_6_LUTOUT204)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_6_LUTOUT203 0x00000800
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_6_LUTOUT203(v) \
+ (((v) << 11) & BM_PXP_WFE_B_STG1_8X1_OUT3_6_LUTOUT203)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_6_LUTOUT202 0x00000400
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_6_LUTOUT202(v) \
+ (((v) << 10) & BM_PXP_WFE_B_STG1_8X1_OUT3_6_LUTOUT202)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_6_LUTOUT201 0x00000200
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_6_LUTOUT201(v) \
+ (((v) << 9) & BM_PXP_WFE_B_STG1_8X1_OUT3_6_LUTOUT201)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_6_LUTOUT200 0x00000100
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_6_LUTOUT200(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STG1_8X1_OUT3_6_LUTOUT200)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_6_LUTOUT199 0x00000080
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_6_LUTOUT199(v) \
+ (((v) << 7) & BM_PXP_WFE_B_STG1_8X1_OUT3_6_LUTOUT199)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_6_LUTOUT198 0x00000040
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_6_LUTOUT198(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STG1_8X1_OUT3_6_LUTOUT198)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_6_LUTOUT197 0x00000020
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_6_LUTOUT197(v) \
+ (((v) << 5) & BM_PXP_WFE_B_STG1_8X1_OUT3_6_LUTOUT197)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_6_LUTOUT196 0x00000010
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_6_LUTOUT196(v) \
+ (((v) << 4) & BM_PXP_WFE_B_STG1_8X1_OUT3_6_LUTOUT196)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_6_LUTOUT195 0x00000008
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_6_LUTOUT195(v) \
+ (((v) << 3) & BM_PXP_WFE_B_STG1_8X1_OUT3_6_LUTOUT195)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_6_LUTOUT194 0x00000004
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_6_LUTOUT194(v) \
+ (((v) << 2) & BM_PXP_WFE_B_STG1_8X1_OUT3_6_LUTOUT194)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_6_LUTOUT193 0x00000002
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_6_LUTOUT193(v) \
+ (((v) << 1) & BM_PXP_WFE_B_STG1_8X1_OUT3_6_LUTOUT193)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_6_LUTOUT192 0x00000001
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_6_LUTOUT192(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STG1_8X1_OUT3_6_LUTOUT192)
+
+#define HW_PXP_WFE_B_STG1_8X1_OUT3_7 (0x00002280)
+
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_7_LUTOUT255 0x80000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_7_LUTOUT255(v) \
+ (((v) << 31) & BM_PXP_WFE_B_STG1_8X1_OUT3_7_LUTOUT255)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_7_LUTOUT254 0x40000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_7_LUTOUT254(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STG1_8X1_OUT3_7_LUTOUT254)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_7_LUTOUT253 0x20000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_7_LUTOUT253(v) \
+ (((v) << 29) & BM_PXP_WFE_B_STG1_8X1_OUT3_7_LUTOUT253)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_7_LUTOUT252 0x10000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_7_LUTOUT252(v) \
+ (((v) << 28) & BM_PXP_WFE_B_STG1_8X1_OUT3_7_LUTOUT252)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_7_LUTOUT251 0x08000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_7_LUTOUT251(v) \
+ (((v) << 27) & BM_PXP_WFE_B_STG1_8X1_OUT3_7_LUTOUT251)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_7_LUTOUT250 0x04000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_7_LUTOUT250(v) \
+ (((v) << 26) & BM_PXP_WFE_B_STG1_8X1_OUT3_7_LUTOUT250)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_7_LUTOUT249 0x02000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_7_LUTOUT249(v) \
+ (((v) << 25) & BM_PXP_WFE_B_STG1_8X1_OUT3_7_LUTOUT249)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_7_LUTOUT248 0x01000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_7_LUTOUT248(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STG1_8X1_OUT3_7_LUTOUT248)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_7_LUTOUT247 0x00800000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_7_LUTOUT247(v) \
+ (((v) << 23) & BM_PXP_WFE_B_STG1_8X1_OUT3_7_LUTOUT247)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_7_LUTOUT246 0x00400000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_7_LUTOUT246(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STG1_8X1_OUT3_7_LUTOUT246)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_7_LUTOUT245 0x00200000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_7_LUTOUT245(v) \
+ (((v) << 21) & BM_PXP_WFE_B_STG1_8X1_OUT3_7_LUTOUT245)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_7_LUTOUT244 0x00100000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_7_LUTOUT244(v) \
+ (((v) << 20) & BM_PXP_WFE_B_STG1_8X1_OUT3_7_LUTOUT244)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_7_LUTOUT243 0x00080000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_7_LUTOUT243(v) \
+ (((v) << 19) & BM_PXP_WFE_B_STG1_8X1_OUT3_7_LUTOUT243)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_7_LUTOUT242 0x00040000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_7_LUTOUT242(v) \
+ (((v) << 18) & BM_PXP_WFE_B_STG1_8X1_OUT3_7_LUTOUT242)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_7_LUTOUT241 0x00020000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_7_LUTOUT241(v) \
+ (((v) << 17) & BM_PXP_WFE_B_STG1_8X1_OUT3_7_LUTOUT241)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_7_LUTOUT240 0x00010000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_7_LUTOUT240(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STG1_8X1_OUT3_7_LUTOUT240)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_7_LUTOUT239 0x00008000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_7_LUTOUT239(v) \
+ (((v) << 15) & BM_PXP_WFE_B_STG1_8X1_OUT3_7_LUTOUT239)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_7_LUTOUT238 0x00004000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_7_LUTOUT238(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STG1_8X1_OUT3_7_LUTOUT238)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_7_LUTOUT237 0x00002000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_7_LUTOUT237(v) \
+ (((v) << 13) & BM_PXP_WFE_B_STG1_8X1_OUT3_7_LUTOUT237)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_7_LUTOUT236 0x00001000
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_7_LUTOUT236(v) \
+ (((v) << 12) & BM_PXP_WFE_B_STG1_8X1_OUT3_7_LUTOUT236)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_7_LUTOUT235 0x00000800
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_7_LUTOUT235(v) \
+ (((v) << 11) & BM_PXP_WFE_B_STG1_8X1_OUT3_7_LUTOUT235)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_7_LUTOUT234 0x00000400
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_7_LUTOUT234(v) \
+ (((v) << 10) & BM_PXP_WFE_B_STG1_8X1_OUT3_7_LUTOUT234)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_7_LUTOUT233 0x00000200
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_7_LUTOUT233(v) \
+ (((v) << 9) & BM_PXP_WFE_B_STG1_8X1_OUT3_7_LUTOUT233)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_7_LUTOUT232 0x00000100
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_7_LUTOUT232(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STG1_8X1_OUT3_7_LUTOUT232)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_7_LUTOUT231 0x00000080
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_7_LUTOUT231(v) \
+ (((v) << 7) & BM_PXP_WFE_B_STG1_8X1_OUT3_7_LUTOUT231)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_7_LUTOUT230 0x00000040
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_7_LUTOUT230(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STG1_8X1_OUT3_7_LUTOUT230)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_7_LUTOUT229 0x00000020
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_7_LUTOUT229(v) \
+ (((v) << 5) & BM_PXP_WFE_B_STG1_8X1_OUT3_7_LUTOUT229)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_7_LUTOUT228 0x00000010
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_7_LUTOUT228(v) \
+ (((v) << 4) & BM_PXP_WFE_B_STG1_8X1_OUT3_7_LUTOUT228)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_7_LUTOUT227 0x00000008
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_7_LUTOUT227(v) \
+ (((v) << 3) & BM_PXP_WFE_B_STG1_8X1_OUT3_7_LUTOUT227)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_7_LUTOUT226 0x00000004
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_7_LUTOUT226(v) \
+ (((v) << 2) & BM_PXP_WFE_B_STG1_8X1_OUT3_7_LUTOUT226)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_7_LUTOUT225 0x00000002
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_7_LUTOUT225(v) \
+ (((v) << 1) & BM_PXP_WFE_B_STG1_8X1_OUT3_7_LUTOUT225)
+#define BM_PXP_WFE_B_STG1_8X1_OUT3_7_LUTOUT224 0x00000001
+#define BF_PXP_WFE_B_STG1_8X1_OUT3_7_LUTOUT224(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STG1_8X1_OUT3_7_LUTOUT224)
+
+#define HW_PXP_WFE_B_STG1_8X1_OUT4_0 (0x00002290)
+
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_0_LUTOUT31 0x80000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_0_LUTOUT31(v) \
+ (((v) << 31) & BM_PXP_WFE_B_STG1_8X1_OUT4_0_LUTOUT31)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_0_LUTOUT30 0x40000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_0_LUTOUT30(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STG1_8X1_OUT4_0_LUTOUT30)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_0_LUTOUT29 0x20000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_0_LUTOUT29(v) \
+ (((v) << 29) & BM_PXP_WFE_B_STG1_8X1_OUT4_0_LUTOUT29)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_0_LUTOUT28 0x10000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_0_LUTOUT28(v) \
+ (((v) << 28) & BM_PXP_WFE_B_STG1_8X1_OUT4_0_LUTOUT28)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_0_LUTOUT27 0x08000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_0_LUTOUT27(v) \
+ (((v) << 27) & BM_PXP_WFE_B_STG1_8X1_OUT4_0_LUTOUT27)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_0_LUTOUT26 0x04000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_0_LUTOUT26(v) \
+ (((v) << 26) & BM_PXP_WFE_B_STG1_8X1_OUT4_0_LUTOUT26)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_0_LUTOUT25 0x02000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_0_LUTOUT25(v) \
+ (((v) << 25) & BM_PXP_WFE_B_STG1_8X1_OUT4_0_LUTOUT25)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_0_LUTOUT24 0x01000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_0_LUTOUT24(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STG1_8X1_OUT4_0_LUTOUT24)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_0_LUTOUT23 0x00800000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_0_LUTOUT23(v) \
+ (((v) << 23) & BM_PXP_WFE_B_STG1_8X1_OUT4_0_LUTOUT23)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_0_LUTOUT22 0x00400000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_0_LUTOUT22(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STG1_8X1_OUT4_0_LUTOUT22)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_0_LUTOUT21 0x00200000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_0_LUTOUT21(v) \
+ (((v) << 21) & BM_PXP_WFE_B_STG1_8X1_OUT4_0_LUTOUT21)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_0_LUTOUT20 0x00100000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_0_LUTOUT20(v) \
+ (((v) << 20) & BM_PXP_WFE_B_STG1_8X1_OUT4_0_LUTOUT20)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_0_LUTOUT19 0x00080000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_0_LUTOUT19(v) \
+ (((v) << 19) & BM_PXP_WFE_B_STG1_8X1_OUT4_0_LUTOUT19)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_0_LUTOUT18 0x00040000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_0_LUTOUT18(v) \
+ (((v) << 18) & BM_PXP_WFE_B_STG1_8X1_OUT4_0_LUTOUT18)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_0_LUTOUT17 0x00020000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_0_LUTOUT17(v) \
+ (((v) << 17) & BM_PXP_WFE_B_STG1_8X1_OUT4_0_LUTOUT17)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_0_LUTOUT16 0x00010000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_0_LUTOUT16(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STG1_8X1_OUT4_0_LUTOUT16)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_0_LUTOUT15 0x00008000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_0_LUTOUT15(v) \
+ (((v) << 15) & BM_PXP_WFE_B_STG1_8X1_OUT4_0_LUTOUT15)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_0_LUTOUT14 0x00004000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_0_LUTOUT14(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STG1_8X1_OUT4_0_LUTOUT14)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_0_LUTOUT13 0x00002000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_0_LUTOUT13(v) \
+ (((v) << 13) & BM_PXP_WFE_B_STG1_8X1_OUT4_0_LUTOUT13)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_0_LUTOUT12 0x00001000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_0_LUTOUT12(v) \
+ (((v) << 12) & BM_PXP_WFE_B_STG1_8X1_OUT4_0_LUTOUT12)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_0_LUTOUT11 0x00000800
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_0_LUTOUT11(v) \
+ (((v) << 11) & BM_PXP_WFE_B_STG1_8X1_OUT4_0_LUTOUT11)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_0_LUTOUT10 0x00000400
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_0_LUTOUT10(v) \
+ (((v) << 10) & BM_PXP_WFE_B_STG1_8X1_OUT4_0_LUTOUT10)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_0_LUTOUT9 0x00000200
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_0_LUTOUT9(v) \
+ (((v) << 9) & BM_PXP_WFE_B_STG1_8X1_OUT4_0_LUTOUT9)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_0_LUTOUT8 0x00000100
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_0_LUTOUT8(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STG1_8X1_OUT4_0_LUTOUT8)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_0_LUTOUT7 0x00000080
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_0_LUTOUT7(v) \
+ (((v) << 7) & BM_PXP_WFE_B_STG1_8X1_OUT4_0_LUTOUT7)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_0_LUTOUT6 0x00000040
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_0_LUTOUT6(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STG1_8X1_OUT4_0_LUTOUT6)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_0_LUTOUT5 0x00000020
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_0_LUTOUT5(v) \
+ (((v) << 5) & BM_PXP_WFE_B_STG1_8X1_OUT4_0_LUTOUT5)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_0_LUTOUT4 0x00000010
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_0_LUTOUT4(v) \
+ (((v) << 4) & BM_PXP_WFE_B_STG1_8X1_OUT4_0_LUTOUT4)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_0_LUTOUT3 0x00000008
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_0_LUTOUT3(v) \
+ (((v) << 3) & BM_PXP_WFE_B_STG1_8X1_OUT4_0_LUTOUT3)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_0_LUTOUT2 0x00000004
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_0_LUTOUT2(v) \
+ (((v) << 2) & BM_PXP_WFE_B_STG1_8X1_OUT4_0_LUTOUT2)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_0_LUTOUT1 0x00000002
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_0_LUTOUT1(v) \
+ (((v) << 1) & BM_PXP_WFE_B_STG1_8X1_OUT4_0_LUTOUT1)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_0_LUTOUT0 0x00000001
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_0_LUTOUT0(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STG1_8X1_OUT4_0_LUTOUT0)
+
+#define HW_PXP_WFE_B_STG1_8X1_OUT4_1 (0x000022a0)
+
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_1_LUTOUT63 0x80000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_1_LUTOUT63(v) \
+ (((v) << 31) & BM_PXP_WFE_B_STG1_8X1_OUT4_1_LUTOUT63)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_1_LUTOUT62 0x40000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_1_LUTOUT62(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STG1_8X1_OUT4_1_LUTOUT62)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_1_LUTOUT61 0x20000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_1_LUTOUT61(v) \
+ (((v) << 29) & BM_PXP_WFE_B_STG1_8X1_OUT4_1_LUTOUT61)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_1_LUTOUT60 0x10000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_1_LUTOUT60(v) \
+ (((v) << 28) & BM_PXP_WFE_B_STG1_8X1_OUT4_1_LUTOUT60)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_1_LUTOUT59 0x08000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_1_LUTOUT59(v) \
+ (((v) << 27) & BM_PXP_WFE_B_STG1_8X1_OUT4_1_LUTOUT59)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_1_LUTOUT58 0x04000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_1_LUTOUT58(v) \
+ (((v) << 26) & BM_PXP_WFE_B_STG1_8X1_OUT4_1_LUTOUT58)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_1_LUTOUT57 0x02000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_1_LUTOUT57(v) \
+ (((v) << 25) & BM_PXP_WFE_B_STG1_8X1_OUT4_1_LUTOUT57)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_1_LUTOUT56 0x01000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_1_LUTOUT56(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STG1_8X1_OUT4_1_LUTOUT56)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_1_LUTOUT55 0x00800000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_1_LUTOUT55(v) \
+ (((v) << 23) & BM_PXP_WFE_B_STG1_8X1_OUT4_1_LUTOUT55)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_1_LUTOUT54 0x00400000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_1_LUTOUT54(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STG1_8X1_OUT4_1_LUTOUT54)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_1_LUTOUT53 0x00200000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_1_LUTOUT53(v) \
+ (((v) << 21) & BM_PXP_WFE_B_STG1_8X1_OUT4_1_LUTOUT53)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_1_LUTOUT52 0x00100000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_1_LUTOUT52(v) \
+ (((v) << 20) & BM_PXP_WFE_B_STG1_8X1_OUT4_1_LUTOUT52)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_1_LUTOUT51 0x00080000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_1_LUTOUT51(v) \
+ (((v) << 19) & BM_PXP_WFE_B_STG1_8X1_OUT4_1_LUTOUT51)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_1_LUTOUT50 0x00040000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_1_LUTOUT50(v) \
+ (((v) << 18) & BM_PXP_WFE_B_STG1_8X1_OUT4_1_LUTOUT50)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_1_LUTOUT49 0x00020000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_1_LUTOUT49(v) \
+ (((v) << 17) & BM_PXP_WFE_B_STG1_8X1_OUT4_1_LUTOUT49)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_1_LUTOUT48 0x00010000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_1_LUTOUT48(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STG1_8X1_OUT4_1_LUTOUT48)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_1_LUTOUT47 0x00008000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_1_LUTOUT47(v) \
+ (((v) << 15) & BM_PXP_WFE_B_STG1_8X1_OUT4_1_LUTOUT47)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_1_LUTOUT46 0x00004000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_1_LUTOUT46(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STG1_8X1_OUT4_1_LUTOUT46)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_1_LUTOUT45 0x00002000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_1_LUTOUT45(v) \
+ (((v) << 13) & BM_PXP_WFE_B_STG1_8X1_OUT4_1_LUTOUT45)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_1_LUTOUT44 0x00001000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_1_LUTOUT44(v) \
+ (((v) << 12) & BM_PXP_WFE_B_STG1_8X1_OUT4_1_LUTOUT44)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_1_LUTOUT43 0x00000800
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_1_LUTOUT43(v) \
+ (((v) << 11) & BM_PXP_WFE_B_STG1_8X1_OUT4_1_LUTOUT43)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_1_LUTOUT42 0x00000400
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_1_LUTOUT42(v) \
+ (((v) << 10) & BM_PXP_WFE_B_STG1_8X1_OUT4_1_LUTOUT42)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_1_LUTOUT41 0x00000200
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_1_LUTOUT41(v) \
+ (((v) << 9) & BM_PXP_WFE_B_STG1_8X1_OUT4_1_LUTOUT41)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_1_LUTOUT40 0x00000100
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_1_LUTOUT40(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STG1_8X1_OUT4_1_LUTOUT40)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_1_LUTOUT39 0x00000080
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_1_LUTOUT39(v) \
+ (((v) << 7) & BM_PXP_WFE_B_STG1_8X1_OUT4_1_LUTOUT39)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_1_LUTOUT38 0x00000040
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_1_LUTOUT38(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STG1_8X1_OUT4_1_LUTOUT38)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_1_LUTOUT37 0x00000020
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_1_LUTOUT37(v) \
+ (((v) << 5) & BM_PXP_WFE_B_STG1_8X1_OUT4_1_LUTOUT37)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_1_LUTOUT36 0x00000010
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_1_LUTOUT36(v) \
+ (((v) << 4) & BM_PXP_WFE_B_STG1_8X1_OUT4_1_LUTOUT36)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_1_LUTOUT35 0x00000008
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_1_LUTOUT35(v) \
+ (((v) << 3) & BM_PXP_WFE_B_STG1_8X1_OUT4_1_LUTOUT35)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_1_LUTOUT34 0x00000004
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_1_LUTOUT34(v) \
+ (((v) << 2) & BM_PXP_WFE_B_STG1_8X1_OUT4_1_LUTOUT34)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_1_LUTOUT33 0x00000002
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_1_LUTOUT33(v) \
+ (((v) << 1) & BM_PXP_WFE_B_STG1_8X1_OUT4_1_LUTOUT33)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_1_LUTOUT32 0x00000001
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_1_LUTOUT32(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STG1_8X1_OUT4_1_LUTOUT32)
+
+#define HW_PXP_WFE_B_STG1_8X1_OUT4_2 (0x000022b0)
+
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_2_LUTOUT95 0x80000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_2_LUTOUT95(v) \
+ (((v) << 31) & BM_PXP_WFE_B_STG1_8X1_OUT4_2_LUTOUT95)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_2_LUTOUT94 0x40000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_2_LUTOUT94(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STG1_8X1_OUT4_2_LUTOUT94)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_2_LUTOUT93 0x20000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_2_LUTOUT93(v) \
+ (((v) << 29) & BM_PXP_WFE_B_STG1_8X1_OUT4_2_LUTOUT93)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_2_LUTOUT92 0x10000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_2_LUTOUT92(v) \
+ (((v) << 28) & BM_PXP_WFE_B_STG1_8X1_OUT4_2_LUTOUT92)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_2_LUTOUT91 0x08000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_2_LUTOUT91(v) \
+ (((v) << 27) & BM_PXP_WFE_B_STG1_8X1_OUT4_2_LUTOUT91)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_2_LUTOUT90 0x04000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_2_LUTOUT90(v) \
+ (((v) << 26) & BM_PXP_WFE_B_STG1_8X1_OUT4_2_LUTOUT90)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_2_LUTOUT89 0x02000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_2_LUTOUT89(v) \
+ (((v) << 25) & BM_PXP_WFE_B_STG1_8X1_OUT4_2_LUTOUT89)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_2_LUTOUT88 0x01000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_2_LUTOUT88(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STG1_8X1_OUT4_2_LUTOUT88)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_2_LUTOUT87 0x00800000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_2_LUTOUT87(v) \
+ (((v) << 23) & BM_PXP_WFE_B_STG1_8X1_OUT4_2_LUTOUT87)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_2_LUTOUT86 0x00400000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_2_LUTOUT86(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STG1_8X1_OUT4_2_LUTOUT86)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_2_LUTOUT85 0x00200000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_2_LUTOUT85(v) \
+ (((v) << 21) & BM_PXP_WFE_B_STG1_8X1_OUT4_2_LUTOUT85)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_2_LUTOUT84 0x00100000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_2_LUTOUT84(v) \
+ (((v) << 20) & BM_PXP_WFE_B_STG1_8X1_OUT4_2_LUTOUT84)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_2_LUTOUT83 0x00080000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_2_LUTOUT83(v) \
+ (((v) << 19) & BM_PXP_WFE_B_STG1_8X1_OUT4_2_LUTOUT83)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_2_LUTOUT82 0x00040000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_2_LUTOUT82(v) \
+ (((v) << 18) & BM_PXP_WFE_B_STG1_8X1_OUT4_2_LUTOUT82)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_2_LUTOUT81 0x00020000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_2_LUTOUT81(v) \
+ (((v) << 17) & BM_PXP_WFE_B_STG1_8X1_OUT4_2_LUTOUT81)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_2_LUTOUT80 0x00010000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_2_LUTOUT80(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STG1_8X1_OUT4_2_LUTOUT80)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_2_LUTOUT79 0x00008000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_2_LUTOUT79(v) \
+ (((v) << 15) & BM_PXP_WFE_B_STG1_8X1_OUT4_2_LUTOUT79)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_2_LUTOUT78 0x00004000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_2_LUTOUT78(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STG1_8X1_OUT4_2_LUTOUT78)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_2_LUTOUT77 0x00002000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_2_LUTOUT77(v) \
+ (((v) << 13) & BM_PXP_WFE_B_STG1_8X1_OUT4_2_LUTOUT77)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_2_LUTOUT76 0x00001000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_2_LUTOUT76(v) \
+ (((v) << 12) & BM_PXP_WFE_B_STG1_8X1_OUT4_2_LUTOUT76)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_2_LUTOUT75 0x00000800
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_2_LUTOUT75(v) \
+ (((v) << 11) & BM_PXP_WFE_B_STG1_8X1_OUT4_2_LUTOUT75)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_2_LUTOUT74 0x00000400
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_2_LUTOUT74(v) \
+ (((v) << 10) & BM_PXP_WFE_B_STG1_8X1_OUT4_2_LUTOUT74)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_2_LUTOUT73 0x00000200
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_2_LUTOUT73(v) \
+ (((v) << 9) & BM_PXP_WFE_B_STG1_8X1_OUT4_2_LUTOUT73)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_2_LUTOUT72 0x00000100
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_2_LUTOUT72(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STG1_8X1_OUT4_2_LUTOUT72)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_2_LUTOUT71 0x00000080
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_2_LUTOUT71(v) \
+ (((v) << 7) & BM_PXP_WFE_B_STG1_8X1_OUT4_2_LUTOUT71)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_2_LUTOUT70 0x00000040
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_2_LUTOUT70(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STG1_8X1_OUT4_2_LUTOUT70)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_2_LUTOUT69 0x00000020
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_2_LUTOUT69(v) \
+ (((v) << 5) & BM_PXP_WFE_B_STG1_8X1_OUT4_2_LUTOUT69)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_2_LUTOUT68 0x00000010
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_2_LUTOUT68(v) \
+ (((v) << 4) & BM_PXP_WFE_B_STG1_8X1_OUT4_2_LUTOUT68)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_2_LUTOUT67 0x00000008
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_2_LUTOUT67(v) \
+ (((v) << 3) & BM_PXP_WFE_B_STG1_8X1_OUT4_2_LUTOUT67)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_2_LUTOUT66 0x00000004
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_2_LUTOUT66(v) \
+ (((v) << 2) & BM_PXP_WFE_B_STG1_8X1_OUT4_2_LUTOUT66)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_2_LUTOUT65 0x00000002
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_2_LUTOUT65(v) \
+ (((v) << 1) & BM_PXP_WFE_B_STG1_8X1_OUT4_2_LUTOUT65)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_2_LUTOUT64 0x00000001
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_2_LUTOUT64(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STG1_8X1_OUT4_2_LUTOUT64)
+
+#define HW_PXP_WFE_B_STG1_8X1_OUT4_3 (0x000022c0)
+
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_3_LUTOUT127 0x80000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_3_LUTOUT127(v) \
+ (((v) << 31) & BM_PXP_WFE_B_STG1_8X1_OUT4_3_LUTOUT127)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_3_LUTOUT126 0x40000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_3_LUTOUT126(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STG1_8X1_OUT4_3_LUTOUT126)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_3_LUTOUT125 0x20000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_3_LUTOUT125(v) \
+ (((v) << 29) & BM_PXP_WFE_B_STG1_8X1_OUT4_3_LUTOUT125)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_3_LUTOUT124 0x10000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_3_LUTOUT124(v) \
+ (((v) << 28) & BM_PXP_WFE_B_STG1_8X1_OUT4_3_LUTOUT124)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_3_LUTOUT123 0x08000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_3_LUTOUT123(v) \
+ (((v) << 27) & BM_PXP_WFE_B_STG1_8X1_OUT4_3_LUTOUT123)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_3_LUTOUT122 0x04000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_3_LUTOUT122(v) \
+ (((v) << 26) & BM_PXP_WFE_B_STG1_8X1_OUT4_3_LUTOUT122)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_3_LUTOUT121 0x02000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_3_LUTOUT121(v) \
+ (((v) << 25) & BM_PXP_WFE_B_STG1_8X1_OUT4_3_LUTOUT121)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_3_LUTOUT120 0x01000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_3_LUTOUT120(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STG1_8X1_OUT4_3_LUTOUT120)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_3_LUTOUT119 0x00800000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_3_LUTOUT119(v) \
+ (((v) << 23) & BM_PXP_WFE_B_STG1_8X1_OUT4_3_LUTOUT119)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_3_LUTOUT118 0x00400000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_3_LUTOUT118(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STG1_8X1_OUT4_3_LUTOUT118)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_3_LUTOUT117 0x00200000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_3_LUTOUT117(v) \
+ (((v) << 21) & BM_PXP_WFE_B_STG1_8X1_OUT4_3_LUTOUT117)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_3_LUTOUT116 0x00100000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_3_LUTOUT116(v) \
+ (((v) << 20) & BM_PXP_WFE_B_STG1_8X1_OUT4_3_LUTOUT116)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_3_LUTOUT115 0x00080000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_3_LUTOUT115(v) \
+ (((v) << 19) & BM_PXP_WFE_B_STG1_8X1_OUT4_3_LUTOUT115)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_3_LUTOUT114 0x00040000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_3_LUTOUT114(v) \
+ (((v) << 18) & BM_PXP_WFE_B_STG1_8X1_OUT4_3_LUTOUT114)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_3_LUTOUT113 0x00020000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_3_LUTOUT113(v) \
+ (((v) << 17) & BM_PXP_WFE_B_STG1_8X1_OUT4_3_LUTOUT113)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_3_LUTOUT112 0x00010000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_3_LUTOUT112(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STG1_8X1_OUT4_3_LUTOUT112)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_3_LUTOUT111 0x00008000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_3_LUTOUT111(v) \
+ (((v) << 15) & BM_PXP_WFE_B_STG1_8X1_OUT4_3_LUTOUT111)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_3_LUTOUT110 0x00004000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_3_LUTOUT110(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STG1_8X1_OUT4_3_LUTOUT110)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_3_LUTOUT109 0x00002000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_3_LUTOUT109(v) \
+ (((v) << 13) & BM_PXP_WFE_B_STG1_8X1_OUT4_3_LUTOUT109)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_3_LUTOUT108 0x00001000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_3_LUTOUT108(v) \
+ (((v) << 12) & BM_PXP_WFE_B_STG1_8X1_OUT4_3_LUTOUT108)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_3_LUTOUT107 0x00000800
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_3_LUTOUT107(v) \
+ (((v) << 11) & BM_PXP_WFE_B_STG1_8X1_OUT4_3_LUTOUT107)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_3_LUTOUT106 0x00000400
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_3_LUTOUT106(v) \
+ (((v) << 10) & BM_PXP_WFE_B_STG1_8X1_OUT4_3_LUTOUT106)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_3_LUTOUT105 0x00000200
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_3_LUTOUT105(v) \
+ (((v) << 9) & BM_PXP_WFE_B_STG1_8X1_OUT4_3_LUTOUT105)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_3_LUTOUT104 0x00000100
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_3_LUTOUT104(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STG1_8X1_OUT4_3_LUTOUT104)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_3_LUTOUT103 0x00000080
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_3_LUTOUT103(v) \
+ (((v) << 7) & BM_PXP_WFE_B_STG1_8X1_OUT4_3_LUTOUT103)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_3_LUTOUT102 0x00000040
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_3_LUTOUT102(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STG1_8X1_OUT4_3_LUTOUT102)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_3_LUTOUT101 0x00000020
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_3_LUTOUT101(v) \
+ (((v) << 5) & BM_PXP_WFE_B_STG1_8X1_OUT4_3_LUTOUT101)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_3_LUTOUT100 0x00000010
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_3_LUTOUT100(v) \
+ (((v) << 4) & BM_PXP_WFE_B_STG1_8X1_OUT4_3_LUTOUT100)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_3_LUTOUT99 0x00000008
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_3_LUTOUT99(v) \
+ (((v) << 3) & BM_PXP_WFE_B_STG1_8X1_OUT4_3_LUTOUT99)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_3_LUTOUT98 0x00000004
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_3_LUTOUT98(v) \
+ (((v) << 2) & BM_PXP_WFE_B_STG1_8X1_OUT4_3_LUTOUT98)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_3_LUTOUT97 0x00000002
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_3_LUTOUT97(v) \
+ (((v) << 1) & BM_PXP_WFE_B_STG1_8X1_OUT4_3_LUTOUT97)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_3_LUTOUT96 0x00000001
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_3_LUTOUT96(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STG1_8X1_OUT4_3_LUTOUT96)
+
+#define HW_PXP_WFE_B_STG1_8X1_OUT4_4 (0x000022d0)
+
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_4_LUTOUT159 0x80000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_4_LUTOUT159(v) \
+ (((v) << 31) & BM_PXP_WFE_B_STG1_8X1_OUT4_4_LUTOUT159)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_4_LUTOUT158 0x40000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_4_LUTOUT158(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STG1_8X1_OUT4_4_LUTOUT158)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_4_LUTOUT157 0x20000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_4_LUTOUT157(v) \
+ (((v) << 29) & BM_PXP_WFE_B_STG1_8X1_OUT4_4_LUTOUT157)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_4_LUTOUT156 0x10000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_4_LUTOUT156(v) \
+ (((v) << 28) & BM_PXP_WFE_B_STG1_8X1_OUT4_4_LUTOUT156)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_4_LUTOUT155 0x08000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_4_LUTOUT155(v) \
+ (((v) << 27) & BM_PXP_WFE_B_STG1_8X1_OUT4_4_LUTOUT155)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_4_LUTOUT154 0x04000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_4_LUTOUT154(v) \
+ (((v) << 26) & BM_PXP_WFE_B_STG1_8X1_OUT4_4_LUTOUT154)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_4_LUTOUT153 0x02000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_4_LUTOUT153(v) \
+ (((v) << 25) & BM_PXP_WFE_B_STG1_8X1_OUT4_4_LUTOUT153)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_4_LUTOUT152 0x01000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_4_LUTOUT152(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STG1_8X1_OUT4_4_LUTOUT152)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_4_LUTOUT151 0x00800000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_4_LUTOUT151(v) \
+ (((v) << 23) & BM_PXP_WFE_B_STG1_8X1_OUT4_4_LUTOUT151)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_4_LUTOUT150 0x00400000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_4_LUTOUT150(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STG1_8X1_OUT4_4_LUTOUT150)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_4_LUTOUT149 0x00200000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_4_LUTOUT149(v) \
+ (((v) << 21) & BM_PXP_WFE_B_STG1_8X1_OUT4_4_LUTOUT149)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_4_LUTOUT148 0x00100000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_4_LUTOUT148(v) \
+ (((v) << 20) & BM_PXP_WFE_B_STG1_8X1_OUT4_4_LUTOUT148)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_4_LUTOUT147 0x00080000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_4_LUTOUT147(v) \
+ (((v) << 19) & BM_PXP_WFE_B_STG1_8X1_OUT4_4_LUTOUT147)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_4_LUTOUT146 0x00040000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_4_LUTOUT146(v) \
+ (((v) << 18) & BM_PXP_WFE_B_STG1_8X1_OUT4_4_LUTOUT146)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_4_LUTOUT145 0x00020000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_4_LUTOUT145(v) \
+ (((v) << 17) & BM_PXP_WFE_B_STG1_8X1_OUT4_4_LUTOUT145)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_4_LUTOUT144 0x00010000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_4_LUTOUT144(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STG1_8X1_OUT4_4_LUTOUT144)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_4_LUTOUT143 0x00008000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_4_LUTOUT143(v) \
+ (((v) << 15) & BM_PXP_WFE_B_STG1_8X1_OUT4_4_LUTOUT143)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_4_LUTOUT142 0x00004000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_4_LUTOUT142(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STG1_8X1_OUT4_4_LUTOUT142)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_4_LUTOUT141 0x00002000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_4_LUTOUT141(v) \
+ (((v) << 13) & BM_PXP_WFE_B_STG1_8X1_OUT4_4_LUTOUT141)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_4_LUTOUT140 0x00001000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_4_LUTOUT140(v) \
+ (((v) << 12) & BM_PXP_WFE_B_STG1_8X1_OUT4_4_LUTOUT140)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_4_LUTOUT139 0x00000800
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_4_LUTOUT139(v) \
+ (((v) << 11) & BM_PXP_WFE_B_STG1_8X1_OUT4_4_LUTOUT139)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_4_LUTOUT138 0x00000400
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_4_LUTOUT138(v) \
+ (((v) << 10) & BM_PXP_WFE_B_STG1_8X1_OUT4_4_LUTOUT138)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_4_LUTOUT137 0x00000200
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_4_LUTOUT137(v) \
+ (((v) << 9) & BM_PXP_WFE_B_STG1_8X1_OUT4_4_LUTOUT137)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_4_LUTOUT136 0x00000100
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_4_LUTOUT136(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STG1_8X1_OUT4_4_LUTOUT136)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_4_LUTOUT135 0x00000080
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_4_LUTOUT135(v) \
+ (((v) << 7) & BM_PXP_WFE_B_STG1_8X1_OUT4_4_LUTOUT135)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_4_LUTOUT134 0x00000040
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_4_LUTOUT134(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STG1_8X1_OUT4_4_LUTOUT134)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_4_LUTOUT133 0x00000020
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_4_LUTOUT133(v) \
+ (((v) << 5) & BM_PXP_WFE_B_STG1_8X1_OUT4_4_LUTOUT133)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_4_LUTOUT132 0x00000010
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_4_LUTOUT132(v) \
+ (((v) << 4) & BM_PXP_WFE_B_STG1_8X1_OUT4_4_LUTOUT132)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_4_LUTOUT131 0x00000008
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_4_LUTOUT131(v) \
+ (((v) << 3) & BM_PXP_WFE_B_STG1_8X1_OUT4_4_LUTOUT131)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_4_LUTOUT130 0x00000004
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_4_LUTOUT130(v) \
+ (((v) << 2) & BM_PXP_WFE_B_STG1_8X1_OUT4_4_LUTOUT130)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_4_LUTOUT129 0x00000002
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_4_LUTOUT129(v) \
+ (((v) << 1) & BM_PXP_WFE_B_STG1_8X1_OUT4_4_LUTOUT129)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_4_LUTOUT128 0x00000001
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_4_LUTOUT128(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STG1_8X1_OUT4_4_LUTOUT128)
+
+#define HW_PXP_WFE_B_STG1_8X1_OUT4_5 (0x000022e0)
+
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_5_LUTOUT191 0x80000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_5_LUTOUT191(v) \
+ (((v) << 31) & BM_PXP_WFE_B_STG1_8X1_OUT4_5_LUTOUT191)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_5_LUTOUT190 0x40000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_5_LUTOUT190(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STG1_8X1_OUT4_5_LUTOUT190)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_5_LUTOUT189 0x20000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_5_LUTOUT189(v) \
+ (((v) << 29) & BM_PXP_WFE_B_STG1_8X1_OUT4_5_LUTOUT189)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_5_LUTOUT188 0x10000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_5_LUTOUT188(v) \
+ (((v) << 28) & BM_PXP_WFE_B_STG1_8X1_OUT4_5_LUTOUT188)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_5_LUTOUT187 0x08000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_5_LUTOUT187(v) \
+ (((v) << 27) & BM_PXP_WFE_B_STG1_8X1_OUT4_5_LUTOUT187)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_5_LUTOUT186 0x04000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_5_LUTOUT186(v) \
+ (((v) << 26) & BM_PXP_WFE_B_STG1_8X1_OUT4_5_LUTOUT186)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_5_LUTOUT185 0x02000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_5_LUTOUT185(v) \
+ (((v) << 25) & BM_PXP_WFE_B_STG1_8X1_OUT4_5_LUTOUT185)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_5_LUTOUT184 0x01000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_5_LUTOUT184(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STG1_8X1_OUT4_5_LUTOUT184)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_5_LUTOUT183 0x00800000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_5_LUTOUT183(v) \
+ (((v) << 23) & BM_PXP_WFE_B_STG1_8X1_OUT4_5_LUTOUT183)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_5_LUTOUT182 0x00400000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_5_LUTOUT182(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STG1_8X1_OUT4_5_LUTOUT182)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_5_LUTOUT181 0x00200000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_5_LUTOUT181(v) \
+ (((v) << 21) & BM_PXP_WFE_B_STG1_8X1_OUT4_5_LUTOUT181)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_5_LUTOUT180 0x00100000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_5_LUTOUT180(v) \
+ (((v) << 20) & BM_PXP_WFE_B_STG1_8X1_OUT4_5_LUTOUT180)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_5_LUTOUT179 0x00080000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_5_LUTOUT179(v) \
+ (((v) << 19) & BM_PXP_WFE_B_STG1_8X1_OUT4_5_LUTOUT179)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_5_LUTOUT178 0x00040000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_5_LUTOUT178(v) \
+ (((v) << 18) & BM_PXP_WFE_B_STG1_8X1_OUT4_5_LUTOUT178)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_5_LUTOUT177 0x00020000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_5_LUTOUT177(v) \
+ (((v) << 17) & BM_PXP_WFE_B_STG1_8X1_OUT4_5_LUTOUT177)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_5_LUTOUT176 0x00010000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_5_LUTOUT176(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STG1_8X1_OUT4_5_LUTOUT176)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_5_LUTOUT175 0x00008000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_5_LUTOUT175(v) \
+ (((v) << 15) & BM_PXP_WFE_B_STG1_8X1_OUT4_5_LUTOUT175)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_5_LUTOUT174 0x00004000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_5_LUTOUT174(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STG1_8X1_OUT4_5_LUTOUT174)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_5_LUTOUT173 0x00002000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_5_LUTOUT173(v) \
+ (((v) << 13) & BM_PXP_WFE_B_STG1_8X1_OUT4_5_LUTOUT173)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_5_LUTOUT172 0x00001000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_5_LUTOUT172(v) \
+ (((v) << 12) & BM_PXP_WFE_B_STG1_8X1_OUT4_5_LUTOUT172)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_5_LUTOUT171 0x00000800
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_5_LUTOUT171(v) \
+ (((v) << 11) & BM_PXP_WFE_B_STG1_8X1_OUT4_5_LUTOUT171)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_5_LUTOUT170 0x00000400
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_5_LUTOUT170(v) \
+ (((v) << 10) & BM_PXP_WFE_B_STG1_8X1_OUT4_5_LUTOUT170)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_5_LUTOUT169 0x00000200
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_5_LUTOUT169(v) \
+ (((v) << 9) & BM_PXP_WFE_B_STG1_8X1_OUT4_5_LUTOUT169)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_5_LUTOUT168 0x00000100
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_5_LUTOUT168(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STG1_8X1_OUT4_5_LUTOUT168)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_5_LUTOUT167 0x00000080
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_5_LUTOUT167(v) \
+ (((v) << 7) & BM_PXP_WFE_B_STG1_8X1_OUT4_5_LUTOUT167)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_5_LUTOUT166 0x00000040
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_5_LUTOUT166(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STG1_8X1_OUT4_5_LUTOUT166)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_5_LUTOUT165 0x00000020
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_5_LUTOUT165(v) \
+ (((v) << 5) & BM_PXP_WFE_B_STG1_8X1_OUT4_5_LUTOUT165)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_5_LUTOUT164 0x00000010
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_5_LUTOUT164(v) \
+ (((v) << 4) & BM_PXP_WFE_B_STG1_8X1_OUT4_5_LUTOUT164)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_5_LUTOUT163 0x00000008
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_5_LUTOUT163(v) \
+ (((v) << 3) & BM_PXP_WFE_B_STG1_8X1_OUT4_5_LUTOUT163)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_5_LUTOUT162 0x00000004
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_5_LUTOUT162(v) \
+ (((v) << 2) & BM_PXP_WFE_B_STG1_8X1_OUT4_5_LUTOUT162)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_5_LUTOUT161 0x00000002
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_5_LUTOUT161(v) \
+ (((v) << 1) & BM_PXP_WFE_B_STG1_8X1_OUT4_5_LUTOUT161)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_5_LUTOUT160 0x00000001
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_5_LUTOUT160(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STG1_8X1_OUT4_5_LUTOUT160)
+
+#define HW_PXP_WFE_B_STG1_8X1_OUT4_6 (0x000022f0)
+
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_6_LUTOUT223 0x80000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_6_LUTOUT223(v) \
+ (((v) << 31) & BM_PXP_WFE_B_STG1_8X1_OUT4_6_LUTOUT223)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_6_LUTOUT222 0x40000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_6_LUTOUT222(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STG1_8X1_OUT4_6_LUTOUT222)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_6_LUTOUT221 0x20000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_6_LUTOUT221(v) \
+ (((v) << 29) & BM_PXP_WFE_B_STG1_8X1_OUT4_6_LUTOUT221)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_6_LUTOUT220 0x10000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_6_LUTOUT220(v) \
+ (((v) << 28) & BM_PXP_WFE_B_STG1_8X1_OUT4_6_LUTOUT220)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_6_LUTOUT219 0x08000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_6_LUTOUT219(v) \
+ (((v) << 27) & BM_PXP_WFE_B_STG1_8X1_OUT4_6_LUTOUT219)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_6_LUTOUT218 0x04000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_6_LUTOUT218(v) \
+ (((v) << 26) & BM_PXP_WFE_B_STG1_8X1_OUT4_6_LUTOUT218)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_6_LUTOUT217 0x02000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_6_LUTOUT217(v) \
+ (((v) << 25) & BM_PXP_WFE_B_STG1_8X1_OUT4_6_LUTOUT217)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_6_LUTOUT216 0x01000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_6_LUTOUT216(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STG1_8X1_OUT4_6_LUTOUT216)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_6_LUTOUT215 0x00800000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_6_LUTOUT215(v) \
+ (((v) << 23) & BM_PXP_WFE_B_STG1_8X1_OUT4_6_LUTOUT215)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_6_LUTOUT214 0x00400000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_6_LUTOUT214(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STG1_8X1_OUT4_6_LUTOUT214)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_6_LUTOUT213 0x00200000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_6_LUTOUT213(v) \
+ (((v) << 21) & BM_PXP_WFE_B_STG1_8X1_OUT4_6_LUTOUT213)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_6_LUTOUT212 0x00100000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_6_LUTOUT212(v) \
+ (((v) << 20) & BM_PXP_WFE_B_STG1_8X1_OUT4_6_LUTOUT212)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_6_LUTOUT211 0x00080000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_6_LUTOUT211(v) \
+ (((v) << 19) & BM_PXP_WFE_B_STG1_8X1_OUT4_6_LUTOUT211)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_6_LUTOUT210 0x00040000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_6_LUTOUT210(v) \
+ (((v) << 18) & BM_PXP_WFE_B_STG1_8X1_OUT4_6_LUTOUT210)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_6_LUTOUT209 0x00020000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_6_LUTOUT209(v) \
+ (((v) << 17) & BM_PXP_WFE_B_STG1_8X1_OUT4_6_LUTOUT209)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_6_LUTOUT208 0x00010000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_6_LUTOUT208(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STG1_8X1_OUT4_6_LUTOUT208)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_6_LUTOUT207 0x00008000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_6_LUTOUT207(v) \
+ (((v) << 15) & BM_PXP_WFE_B_STG1_8X1_OUT4_6_LUTOUT207)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_6_LUTOUT206 0x00004000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_6_LUTOUT206(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STG1_8X1_OUT4_6_LUTOUT206)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_6_LUTOUT205 0x00002000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_6_LUTOUT205(v) \
+ (((v) << 13) & BM_PXP_WFE_B_STG1_8X1_OUT4_6_LUTOUT205)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_6_LUTOUT204 0x00001000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_6_LUTOUT204(v) \
+ (((v) << 12) & BM_PXP_WFE_B_STG1_8X1_OUT4_6_LUTOUT204)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_6_LUTOUT203 0x00000800
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_6_LUTOUT203(v) \
+ (((v) << 11) & BM_PXP_WFE_B_STG1_8X1_OUT4_6_LUTOUT203)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_6_LUTOUT202 0x00000400
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_6_LUTOUT202(v) \
+ (((v) << 10) & BM_PXP_WFE_B_STG1_8X1_OUT4_6_LUTOUT202)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_6_LUTOUT201 0x00000200
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_6_LUTOUT201(v) \
+ (((v) << 9) & BM_PXP_WFE_B_STG1_8X1_OUT4_6_LUTOUT201)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_6_LUTOUT200 0x00000100
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_6_LUTOUT200(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STG1_8X1_OUT4_6_LUTOUT200)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_6_LUTOUT199 0x00000080
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_6_LUTOUT199(v) \
+ (((v) << 7) & BM_PXP_WFE_B_STG1_8X1_OUT4_6_LUTOUT199)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_6_LUTOUT198 0x00000040
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_6_LUTOUT198(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STG1_8X1_OUT4_6_LUTOUT198)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_6_LUTOUT197 0x00000020
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_6_LUTOUT197(v) \
+ (((v) << 5) & BM_PXP_WFE_B_STG1_8X1_OUT4_6_LUTOUT197)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_6_LUTOUT196 0x00000010
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_6_LUTOUT196(v) \
+ (((v) << 4) & BM_PXP_WFE_B_STG1_8X1_OUT4_6_LUTOUT196)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_6_LUTOUT195 0x00000008
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_6_LUTOUT195(v) \
+ (((v) << 3) & BM_PXP_WFE_B_STG1_8X1_OUT4_6_LUTOUT195)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_6_LUTOUT194 0x00000004
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_6_LUTOUT194(v) \
+ (((v) << 2) & BM_PXP_WFE_B_STG1_8X1_OUT4_6_LUTOUT194)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_6_LUTOUT193 0x00000002
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_6_LUTOUT193(v) \
+ (((v) << 1) & BM_PXP_WFE_B_STG1_8X1_OUT4_6_LUTOUT193)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_6_LUTOUT192 0x00000001
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_6_LUTOUT192(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STG1_8X1_OUT4_6_LUTOUT192)
+
+#define HW_PXP_WFE_B_STG1_8X1_OUT4_7 (0x00002300)
+
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_7_LUTOUT255 0x80000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_7_LUTOUT255(v) \
+ (((v) << 31) & BM_PXP_WFE_B_STG1_8X1_OUT4_7_LUTOUT255)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_7_LUTOUT254 0x40000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_7_LUTOUT254(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STG1_8X1_OUT4_7_LUTOUT254)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_7_LUTOUT253 0x20000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_7_LUTOUT253(v) \
+ (((v) << 29) & BM_PXP_WFE_B_STG1_8X1_OUT4_7_LUTOUT253)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_7_LUTOUT252 0x10000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_7_LUTOUT252(v) \
+ (((v) << 28) & BM_PXP_WFE_B_STG1_8X1_OUT4_7_LUTOUT252)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_7_LUTOUT251 0x08000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_7_LUTOUT251(v) \
+ (((v) << 27) & BM_PXP_WFE_B_STG1_8X1_OUT4_7_LUTOUT251)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_7_LUTOUT250 0x04000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_7_LUTOUT250(v) \
+ (((v) << 26) & BM_PXP_WFE_B_STG1_8X1_OUT4_7_LUTOUT250)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_7_LUTOUT249 0x02000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_7_LUTOUT249(v) \
+ (((v) << 25) & BM_PXP_WFE_B_STG1_8X1_OUT4_7_LUTOUT249)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_7_LUTOUT248 0x01000000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_7_LUTOUT248(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STG1_8X1_OUT4_7_LUTOUT248)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_7_LUTOUT247 0x00800000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_7_LUTOUT247(v) \
+ (((v) << 23) & BM_PXP_WFE_B_STG1_8X1_OUT4_7_LUTOUT247)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_7_LUTOUT246 0x00400000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_7_LUTOUT246(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STG1_8X1_OUT4_7_LUTOUT246)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_7_LUTOUT245 0x00200000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_7_LUTOUT245(v) \
+ (((v) << 21) & BM_PXP_WFE_B_STG1_8X1_OUT4_7_LUTOUT245)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_7_LUTOUT244 0x00100000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_7_LUTOUT244(v) \
+ (((v) << 20) & BM_PXP_WFE_B_STG1_8X1_OUT4_7_LUTOUT244)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_7_LUTOUT243 0x00080000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_7_LUTOUT243(v) \
+ (((v) << 19) & BM_PXP_WFE_B_STG1_8X1_OUT4_7_LUTOUT243)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_7_LUTOUT242 0x00040000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_7_LUTOUT242(v) \
+ (((v) << 18) & BM_PXP_WFE_B_STG1_8X1_OUT4_7_LUTOUT242)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_7_LUTOUT241 0x00020000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_7_LUTOUT241(v) \
+ (((v) << 17) & BM_PXP_WFE_B_STG1_8X1_OUT4_7_LUTOUT241)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_7_LUTOUT240 0x00010000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_7_LUTOUT240(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STG1_8X1_OUT4_7_LUTOUT240)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_7_LUTOUT239 0x00008000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_7_LUTOUT239(v) \
+ (((v) << 15) & BM_PXP_WFE_B_STG1_8X1_OUT4_7_LUTOUT239)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_7_LUTOUT238 0x00004000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_7_LUTOUT238(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STG1_8X1_OUT4_7_LUTOUT238)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_7_LUTOUT237 0x00002000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_7_LUTOUT237(v) \
+ (((v) << 13) & BM_PXP_WFE_B_STG1_8X1_OUT4_7_LUTOUT237)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_7_LUTOUT236 0x00001000
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_7_LUTOUT236(v) \
+ (((v) << 12) & BM_PXP_WFE_B_STG1_8X1_OUT4_7_LUTOUT236)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_7_LUTOUT235 0x00000800
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_7_LUTOUT235(v) \
+ (((v) << 11) & BM_PXP_WFE_B_STG1_8X1_OUT4_7_LUTOUT235)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_7_LUTOUT234 0x00000400
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_7_LUTOUT234(v) \
+ (((v) << 10) & BM_PXP_WFE_B_STG1_8X1_OUT4_7_LUTOUT234)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_7_LUTOUT233 0x00000200
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_7_LUTOUT233(v) \
+ (((v) << 9) & BM_PXP_WFE_B_STG1_8X1_OUT4_7_LUTOUT233)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_7_LUTOUT232 0x00000100
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_7_LUTOUT232(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STG1_8X1_OUT4_7_LUTOUT232)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_7_LUTOUT231 0x00000080
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_7_LUTOUT231(v) \
+ (((v) << 7) & BM_PXP_WFE_B_STG1_8X1_OUT4_7_LUTOUT231)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_7_LUTOUT230 0x00000040
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_7_LUTOUT230(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STG1_8X1_OUT4_7_LUTOUT230)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_7_LUTOUT229 0x00000020
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_7_LUTOUT229(v) \
+ (((v) << 5) & BM_PXP_WFE_B_STG1_8X1_OUT4_7_LUTOUT229)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_7_LUTOUT228 0x00000010
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_7_LUTOUT228(v) \
+ (((v) << 4) & BM_PXP_WFE_B_STG1_8X1_OUT4_7_LUTOUT228)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_7_LUTOUT227 0x00000008
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_7_LUTOUT227(v) \
+ (((v) << 3) & BM_PXP_WFE_B_STG1_8X1_OUT4_7_LUTOUT227)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_7_LUTOUT226 0x00000004
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_7_LUTOUT226(v) \
+ (((v) << 2) & BM_PXP_WFE_B_STG1_8X1_OUT4_7_LUTOUT226)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_7_LUTOUT225 0x00000002
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_7_LUTOUT225(v) \
+ (((v) << 1) & BM_PXP_WFE_B_STG1_8X1_OUT4_7_LUTOUT225)
+#define BM_PXP_WFE_B_STG1_8X1_OUT4_7_LUTOUT224 0x00000001
+#define BF_PXP_WFE_B_STG1_8X1_OUT4_7_LUTOUT224(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STG1_8X1_OUT4_7_LUTOUT224)
+
+#define HW_PXP_WFE_B_STG2_5X6_OUT0_0 (0x00002310)
+
+#define BP_PXP_WFE_B_STG2_5X6_OUT0_0_RSVD0 30
+#define BM_PXP_WFE_B_STG2_5X6_OUT0_0_RSVD0 0xC0000000
+#define BF_PXP_WFE_B_STG2_5X6_OUT0_0_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STG2_5X6_OUT0_0_RSVD0)
+#define BP_PXP_WFE_B_STG2_5X6_OUT0_0_LUTOUT3 24
+#define BM_PXP_WFE_B_STG2_5X6_OUT0_0_LUTOUT3 0x3F000000
+#define BF_PXP_WFE_B_STG2_5X6_OUT0_0_LUTOUT3(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STG2_5X6_OUT0_0_LUTOUT3)
+#define BP_PXP_WFE_B_STG2_5X6_OUT0_0_RSVD1 22
+#define BM_PXP_WFE_B_STG2_5X6_OUT0_0_RSVD1 0x00C00000
+#define BF_PXP_WFE_B_STG2_5X6_OUT0_0_RSVD1(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STG2_5X6_OUT0_0_RSVD1)
+#define BP_PXP_WFE_B_STG2_5X6_OUT0_0_LUTOUT2 16
+#define BM_PXP_WFE_B_STG2_5X6_OUT0_0_LUTOUT2 0x003F0000
+#define BF_PXP_WFE_B_STG2_5X6_OUT0_0_LUTOUT2(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STG2_5X6_OUT0_0_LUTOUT2)
+#define BP_PXP_WFE_B_STG2_5X6_OUT0_0_RSVD2 14
+#define BM_PXP_WFE_B_STG2_5X6_OUT0_0_RSVD2 0x0000C000
+#define BF_PXP_WFE_B_STG2_5X6_OUT0_0_RSVD2(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STG2_5X6_OUT0_0_RSVD2)
+#define BP_PXP_WFE_B_STG2_5X6_OUT0_0_LUTOUT1 8
+#define BM_PXP_WFE_B_STG2_5X6_OUT0_0_LUTOUT1 0x00003F00
+#define BF_PXP_WFE_B_STG2_5X6_OUT0_0_LUTOUT1(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STG2_5X6_OUT0_0_LUTOUT1)
+#define BP_PXP_WFE_B_STG2_5X6_OUT0_0_RSVD3 6
+#define BM_PXP_WFE_B_STG2_5X6_OUT0_0_RSVD3 0x000000C0
+#define BF_PXP_WFE_B_STG2_5X6_OUT0_0_RSVD3(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STG2_5X6_OUT0_0_RSVD3)
+#define BP_PXP_WFE_B_STG2_5X6_OUT0_0_LUTOUT0 0
+#define BM_PXP_WFE_B_STG2_5X6_OUT0_0_LUTOUT0 0x0000003F
+#define BF_PXP_WFE_B_STG2_5X6_OUT0_0_LUTOUT0(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STG2_5X6_OUT0_0_LUTOUT0)
+
+#define HW_PXP_WFE_B_STG2_5X6_OUT0_1 (0x00002320)
+
+#define BP_PXP_WFE_B_STG2_5X6_OUT0_1_RSVD0 30
+#define BM_PXP_WFE_B_STG2_5X6_OUT0_1_RSVD0 0xC0000000
+#define BF_PXP_WFE_B_STG2_5X6_OUT0_1_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STG2_5X6_OUT0_1_RSVD0)
+#define BP_PXP_WFE_B_STG2_5X6_OUT0_1_LUTOUT7 24
+#define BM_PXP_WFE_B_STG2_5X6_OUT0_1_LUTOUT7 0x3F000000
+#define BF_PXP_WFE_B_STG2_5X6_OUT0_1_LUTOUT7(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STG2_5X6_OUT0_1_LUTOUT7)
+#define BP_PXP_WFE_B_STG2_5X6_OUT0_1_RSVD1 22
+#define BM_PXP_WFE_B_STG2_5X6_OUT0_1_RSVD1 0x00C00000
+#define BF_PXP_WFE_B_STG2_5X6_OUT0_1_RSVD1(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STG2_5X6_OUT0_1_RSVD1)
+#define BP_PXP_WFE_B_STG2_5X6_OUT0_1_LUTOUT6 16
+#define BM_PXP_WFE_B_STG2_5X6_OUT0_1_LUTOUT6 0x003F0000
+#define BF_PXP_WFE_B_STG2_5X6_OUT0_1_LUTOUT6(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STG2_5X6_OUT0_1_LUTOUT6)
+#define BP_PXP_WFE_B_STG2_5X6_OUT0_1_RSVD2 14
+#define BM_PXP_WFE_B_STG2_5X6_OUT0_1_RSVD2 0x0000C000
+#define BF_PXP_WFE_B_STG2_5X6_OUT0_1_RSVD2(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STG2_5X6_OUT0_1_RSVD2)
+#define BP_PXP_WFE_B_STG2_5X6_OUT0_1_LUTOUT5 8
+#define BM_PXP_WFE_B_STG2_5X6_OUT0_1_LUTOUT5 0x00003F00
+#define BF_PXP_WFE_B_STG2_5X6_OUT0_1_LUTOUT5(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STG2_5X6_OUT0_1_LUTOUT5)
+#define BP_PXP_WFE_B_STG2_5X6_OUT0_1_RSVD3 6
+#define BM_PXP_WFE_B_STG2_5X6_OUT0_1_RSVD3 0x000000C0
+#define BF_PXP_WFE_B_STG2_5X6_OUT0_1_RSVD3(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STG2_5X6_OUT0_1_RSVD3)
+#define BP_PXP_WFE_B_STG2_5X6_OUT0_1_LUTOUT4 0
+#define BM_PXP_WFE_B_STG2_5X6_OUT0_1_LUTOUT4 0x0000003F
+#define BF_PXP_WFE_B_STG2_5X6_OUT0_1_LUTOUT4(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STG2_5X6_OUT0_1_LUTOUT4)
+
+#define HW_PXP_WFE_B_STG2_5X6_OUT0_2 (0x00002330)
+
+#define BP_PXP_WFE_B_STG2_5X6_OUT0_2_RSVD0 30
+#define BM_PXP_WFE_B_STG2_5X6_OUT0_2_RSVD0 0xC0000000
+#define BF_PXP_WFE_B_STG2_5X6_OUT0_2_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STG2_5X6_OUT0_2_RSVD0)
+#define BP_PXP_WFE_B_STG2_5X6_OUT0_2_LUTOUT11 24
+#define BM_PXP_WFE_B_STG2_5X6_OUT0_2_LUTOUT11 0x3F000000
+#define BF_PXP_WFE_B_STG2_5X6_OUT0_2_LUTOUT11(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STG2_5X6_OUT0_2_LUTOUT11)
+#define BP_PXP_WFE_B_STG2_5X6_OUT0_2_RSVD1 22
+#define BM_PXP_WFE_B_STG2_5X6_OUT0_2_RSVD1 0x00C00000
+#define BF_PXP_WFE_B_STG2_5X6_OUT0_2_RSVD1(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STG2_5X6_OUT0_2_RSVD1)
+#define BP_PXP_WFE_B_STG2_5X6_OUT0_2_LUTOUT10 16
+#define BM_PXP_WFE_B_STG2_5X6_OUT0_2_LUTOUT10 0x003F0000
+#define BF_PXP_WFE_B_STG2_5X6_OUT0_2_LUTOUT10(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STG2_5X6_OUT0_2_LUTOUT10)
+#define BP_PXP_WFE_B_STG2_5X6_OUT0_2_RSVD2 14
+#define BM_PXP_WFE_B_STG2_5X6_OUT0_2_RSVD2 0x0000C000
+#define BF_PXP_WFE_B_STG2_5X6_OUT0_2_RSVD2(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STG2_5X6_OUT0_2_RSVD2)
+#define BP_PXP_WFE_B_STG2_5X6_OUT0_2_LUTOUT9 8
+#define BM_PXP_WFE_B_STG2_5X6_OUT0_2_LUTOUT9 0x00003F00
+#define BF_PXP_WFE_B_STG2_5X6_OUT0_2_LUTOUT9(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STG2_5X6_OUT0_2_LUTOUT9)
+#define BP_PXP_WFE_B_STG2_5X6_OUT0_2_RSVD3 6
+#define BM_PXP_WFE_B_STG2_5X6_OUT0_2_RSVD3 0x000000C0
+#define BF_PXP_WFE_B_STG2_5X6_OUT0_2_RSVD3(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STG2_5X6_OUT0_2_RSVD3)
+#define BP_PXP_WFE_B_STG2_5X6_OUT0_2_LUTOUT8 0
+#define BM_PXP_WFE_B_STG2_5X6_OUT0_2_LUTOUT8 0x0000003F
+#define BF_PXP_WFE_B_STG2_5X6_OUT0_2_LUTOUT8(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STG2_5X6_OUT0_2_LUTOUT8)
+
+#define HW_PXP_WFE_B_STG2_5X6_OUT0_3 (0x00002340)
+
+#define BP_PXP_WFE_B_STG2_5X6_OUT0_3_RSVD0 30
+#define BM_PXP_WFE_B_STG2_5X6_OUT0_3_RSVD0 0xC0000000
+#define BF_PXP_WFE_B_STG2_5X6_OUT0_3_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STG2_5X6_OUT0_3_RSVD0)
+#define BP_PXP_WFE_B_STG2_5X6_OUT0_3_LUTOUT15 24
+#define BM_PXP_WFE_B_STG2_5X6_OUT0_3_LUTOUT15 0x3F000000
+#define BF_PXP_WFE_B_STG2_5X6_OUT0_3_LUTOUT15(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STG2_5X6_OUT0_3_LUTOUT15)
+#define BP_PXP_WFE_B_STG2_5X6_OUT0_3_RSVD1 22
+#define BM_PXP_WFE_B_STG2_5X6_OUT0_3_RSVD1 0x00C00000
+#define BF_PXP_WFE_B_STG2_5X6_OUT0_3_RSVD1(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STG2_5X6_OUT0_3_RSVD1)
+#define BP_PXP_WFE_B_STG2_5X6_OUT0_3_LUTOUT14 16
+#define BM_PXP_WFE_B_STG2_5X6_OUT0_3_LUTOUT14 0x003F0000
+#define BF_PXP_WFE_B_STG2_5X6_OUT0_3_LUTOUT14(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STG2_5X6_OUT0_3_LUTOUT14)
+#define BP_PXP_WFE_B_STG2_5X6_OUT0_3_RSVD2 14
+#define BM_PXP_WFE_B_STG2_5X6_OUT0_3_RSVD2 0x0000C000
+#define BF_PXP_WFE_B_STG2_5X6_OUT0_3_RSVD2(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STG2_5X6_OUT0_3_RSVD2)
+#define BP_PXP_WFE_B_STG2_5X6_OUT0_3_LUTOUT13 8
+#define BM_PXP_WFE_B_STG2_5X6_OUT0_3_LUTOUT13 0x00003F00
+#define BF_PXP_WFE_B_STG2_5X6_OUT0_3_LUTOUT13(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STG2_5X6_OUT0_3_LUTOUT13)
+#define BP_PXP_WFE_B_STG2_5X6_OUT0_3_RSVD3 6
+#define BM_PXP_WFE_B_STG2_5X6_OUT0_3_RSVD3 0x000000C0
+#define BF_PXP_WFE_B_STG2_5X6_OUT0_3_RSVD3(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STG2_5X6_OUT0_3_RSVD3)
+#define BP_PXP_WFE_B_STG2_5X6_OUT0_3_LUTOUT12 0
+#define BM_PXP_WFE_B_STG2_5X6_OUT0_3_LUTOUT12 0x0000003F
+#define BF_PXP_WFE_B_STG2_5X6_OUT0_3_LUTOUT12(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STG2_5X6_OUT0_3_LUTOUT12)
+
+#define HW_PXP_WFE_B_STG2_5X6_OUT0_4 (0x00002350)
+
+#define BP_PXP_WFE_B_STG2_5X6_OUT0_4_RSVD0 30
+#define BM_PXP_WFE_B_STG2_5X6_OUT0_4_RSVD0 0xC0000000
+#define BF_PXP_WFE_B_STG2_5X6_OUT0_4_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STG2_5X6_OUT0_4_RSVD0)
+#define BP_PXP_WFE_B_STG2_5X6_OUT0_4_LUTOUT19 24
+#define BM_PXP_WFE_B_STG2_5X6_OUT0_4_LUTOUT19 0x3F000000
+#define BF_PXP_WFE_B_STG2_5X6_OUT0_4_LUTOUT19(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STG2_5X6_OUT0_4_LUTOUT19)
+#define BP_PXP_WFE_B_STG2_5X6_OUT0_4_RSVD1 22
+#define BM_PXP_WFE_B_STG2_5X6_OUT0_4_RSVD1 0x00C00000
+#define BF_PXP_WFE_B_STG2_5X6_OUT0_4_RSVD1(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STG2_5X6_OUT0_4_RSVD1)
+#define BP_PXP_WFE_B_STG2_5X6_OUT0_4_LUTOUT18 16
+#define BM_PXP_WFE_B_STG2_5X6_OUT0_4_LUTOUT18 0x003F0000
+#define BF_PXP_WFE_B_STG2_5X6_OUT0_4_LUTOUT18(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STG2_5X6_OUT0_4_LUTOUT18)
+#define BP_PXP_WFE_B_STG2_5X6_OUT0_4_RSVD2 14
+#define BM_PXP_WFE_B_STG2_5X6_OUT0_4_RSVD2 0x0000C000
+#define BF_PXP_WFE_B_STG2_5X6_OUT0_4_RSVD2(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STG2_5X6_OUT0_4_RSVD2)
+#define BP_PXP_WFE_B_STG2_5X6_OUT0_4_LUTOUT17 8
+#define BM_PXP_WFE_B_STG2_5X6_OUT0_4_LUTOUT17 0x00003F00
+#define BF_PXP_WFE_B_STG2_5X6_OUT0_4_LUTOUT17(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STG2_5X6_OUT0_4_LUTOUT17)
+#define BP_PXP_WFE_B_STG2_5X6_OUT0_4_RSVD3 6
+#define BM_PXP_WFE_B_STG2_5X6_OUT0_4_RSVD3 0x000000C0
+#define BF_PXP_WFE_B_STG2_5X6_OUT0_4_RSVD3(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STG2_5X6_OUT0_4_RSVD3)
+#define BP_PXP_WFE_B_STG2_5X6_OUT0_4_LUTOUT16 0
+#define BM_PXP_WFE_B_STG2_5X6_OUT0_4_LUTOUT16 0x0000003F
+#define BF_PXP_WFE_B_STG2_5X6_OUT0_4_LUTOUT16(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STG2_5X6_OUT0_4_LUTOUT16)
+
+#define HW_PXP_WFE_B_STG2_5X6_OUT0_5 (0x00002360)
+
+#define BP_PXP_WFE_B_STG2_5X6_OUT0_5_RSVD0 30
+#define BM_PXP_WFE_B_STG2_5X6_OUT0_5_RSVD0 0xC0000000
+#define BF_PXP_WFE_B_STG2_5X6_OUT0_5_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STG2_5X6_OUT0_5_RSVD0)
+#define BP_PXP_WFE_B_STG2_5X6_OUT0_5_LUTOUT23 24
+#define BM_PXP_WFE_B_STG2_5X6_OUT0_5_LUTOUT23 0x3F000000
+#define BF_PXP_WFE_B_STG2_5X6_OUT0_5_LUTOUT23(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STG2_5X6_OUT0_5_LUTOUT23)
+#define BP_PXP_WFE_B_STG2_5X6_OUT0_5_RSVD1 22
+#define BM_PXP_WFE_B_STG2_5X6_OUT0_5_RSVD1 0x00C00000
+#define BF_PXP_WFE_B_STG2_5X6_OUT0_5_RSVD1(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STG2_5X6_OUT0_5_RSVD1)
+#define BP_PXP_WFE_B_STG2_5X6_OUT0_5_LUTOUT22 16
+#define BM_PXP_WFE_B_STG2_5X6_OUT0_5_LUTOUT22 0x003F0000
+#define BF_PXP_WFE_B_STG2_5X6_OUT0_5_LUTOUT22(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STG2_5X6_OUT0_5_LUTOUT22)
+#define BP_PXP_WFE_B_STG2_5X6_OUT0_5_RSVD2 14
+#define BM_PXP_WFE_B_STG2_5X6_OUT0_5_RSVD2 0x0000C000
+#define BF_PXP_WFE_B_STG2_5X6_OUT0_5_RSVD2(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STG2_5X6_OUT0_5_RSVD2)
+#define BP_PXP_WFE_B_STG2_5X6_OUT0_5_LUTOUT21 8
+#define BM_PXP_WFE_B_STG2_5X6_OUT0_5_LUTOUT21 0x00003F00
+#define BF_PXP_WFE_B_STG2_5X6_OUT0_5_LUTOUT21(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STG2_5X6_OUT0_5_LUTOUT21)
+#define BP_PXP_WFE_B_STG2_5X6_OUT0_5_RSVD3 6
+#define BM_PXP_WFE_B_STG2_5X6_OUT0_5_RSVD3 0x000000C0
+#define BF_PXP_WFE_B_STG2_5X6_OUT0_5_RSVD3(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STG2_5X6_OUT0_5_RSVD3)
+#define BP_PXP_WFE_B_STG2_5X6_OUT0_5_LUTOUT20 0
+#define BM_PXP_WFE_B_STG2_5X6_OUT0_5_LUTOUT20 0x0000003F
+#define BF_PXP_WFE_B_STG2_5X6_OUT0_5_LUTOUT20(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STG2_5X6_OUT0_5_LUTOUT20)
+
+#define HW_PXP_WFE_B_STG2_5X6_OUT0_6 (0x00002370)
+
+#define BP_PXP_WFE_B_STG2_5X6_OUT0_6_RSVD0 30
+#define BM_PXP_WFE_B_STG2_5X6_OUT0_6_RSVD0 0xC0000000
+#define BF_PXP_WFE_B_STG2_5X6_OUT0_6_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STG2_5X6_OUT0_6_RSVD0)
+#define BP_PXP_WFE_B_STG2_5X6_OUT0_6_LUTOUT27 24
+#define BM_PXP_WFE_B_STG2_5X6_OUT0_6_LUTOUT27 0x3F000000
+#define BF_PXP_WFE_B_STG2_5X6_OUT0_6_LUTOUT27(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STG2_5X6_OUT0_6_LUTOUT27)
+#define BP_PXP_WFE_B_STG2_5X6_OUT0_6_RSVD1 22
+#define BM_PXP_WFE_B_STG2_5X6_OUT0_6_RSVD1 0x00C00000
+#define BF_PXP_WFE_B_STG2_5X6_OUT0_6_RSVD1(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STG2_5X6_OUT0_6_RSVD1)
+#define BP_PXP_WFE_B_STG2_5X6_OUT0_6_LUTOUT26 16
+#define BM_PXP_WFE_B_STG2_5X6_OUT0_6_LUTOUT26 0x003F0000
+#define BF_PXP_WFE_B_STG2_5X6_OUT0_6_LUTOUT26(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STG2_5X6_OUT0_6_LUTOUT26)
+#define BP_PXP_WFE_B_STG2_5X6_OUT0_6_RSVD2 14
+#define BM_PXP_WFE_B_STG2_5X6_OUT0_6_RSVD2 0x0000C000
+#define BF_PXP_WFE_B_STG2_5X6_OUT0_6_RSVD2(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STG2_5X6_OUT0_6_RSVD2)
+#define BP_PXP_WFE_B_STG2_5X6_OUT0_6_LUTOUT25 8
+#define BM_PXP_WFE_B_STG2_5X6_OUT0_6_LUTOUT25 0x00003F00
+#define BF_PXP_WFE_B_STG2_5X6_OUT0_6_LUTOUT25(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STG2_5X6_OUT0_6_LUTOUT25)
+#define BP_PXP_WFE_B_STG2_5X6_OUT0_6_RSVD3 6
+#define BM_PXP_WFE_B_STG2_5X6_OUT0_6_RSVD3 0x000000C0
+#define BF_PXP_WFE_B_STG2_5X6_OUT0_6_RSVD3(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STG2_5X6_OUT0_6_RSVD3)
+#define BP_PXP_WFE_B_STG2_5X6_OUT0_6_LUTOUT24 0
+#define BM_PXP_WFE_B_STG2_5X6_OUT0_6_LUTOUT24 0x0000003F
+#define BF_PXP_WFE_B_STG2_5X6_OUT0_6_LUTOUT24(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STG2_5X6_OUT0_6_LUTOUT24)
+
+#define HW_PXP_WFE_B_STG2_5X6_OUT0_7 (0x00002380)
+
+#define BP_PXP_WFE_B_STG2_5X6_OUT0_7_RSVD0 30
+#define BM_PXP_WFE_B_STG2_5X6_OUT0_7_RSVD0 0xC0000000
+#define BF_PXP_WFE_B_STG2_5X6_OUT0_7_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STG2_5X6_OUT0_7_RSVD0)
+#define BP_PXP_WFE_B_STG2_5X6_OUT0_7_LUTOUT31 24
+#define BM_PXP_WFE_B_STG2_5X6_OUT0_7_LUTOUT31 0x3F000000
+#define BF_PXP_WFE_B_STG2_5X6_OUT0_7_LUTOUT31(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STG2_5X6_OUT0_7_LUTOUT31)
+#define BP_PXP_WFE_B_STG2_5X6_OUT0_7_RSVD1 22
+#define BM_PXP_WFE_B_STG2_5X6_OUT0_7_RSVD1 0x00C00000
+#define BF_PXP_WFE_B_STG2_5X6_OUT0_7_RSVD1(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STG2_5X6_OUT0_7_RSVD1)
+#define BP_PXP_WFE_B_STG2_5X6_OUT0_7_LUTOUT30 16
+#define BM_PXP_WFE_B_STG2_5X6_OUT0_7_LUTOUT30 0x003F0000
+#define BF_PXP_WFE_B_STG2_5X6_OUT0_7_LUTOUT30(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STG2_5X6_OUT0_7_LUTOUT30)
+#define BP_PXP_WFE_B_STG2_5X6_OUT0_7_RSVD2 14
+#define BM_PXP_WFE_B_STG2_5X6_OUT0_7_RSVD2 0x0000C000
+#define BF_PXP_WFE_B_STG2_5X6_OUT0_7_RSVD2(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STG2_5X6_OUT0_7_RSVD2)
+#define BP_PXP_WFE_B_STG2_5X6_OUT0_7_LUTOUT29 8
+#define BM_PXP_WFE_B_STG2_5X6_OUT0_7_LUTOUT29 0x00003F00
+#define BF_PXP_WFE_B_STG2_5X6_OUT0_7_LUTOUT29(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STG2_5X6_OUT0_7_LUTOUT29)
+#define BP_PXP_WFE_B_STG2_5X6_OUT0_7_RSVD3 6
+#define BM_PXP_WFE_B_STG2_5X6_OUT0_7_RSVD3 0x000000C0
+#define BF_PXP_WFE_B_STG2_5X6_OUT0_7_RSVD3(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STG2_5X6_OUT0_7_RSVD3)
+#define BP_PXP_WFE_B_STG2_5X6_OUT0_7_LUTOUT28 0
+#define BM_PXP_WFE_B_STG2_5X6_OUT0_7_LUTOUT28 0x0000003F
+#define BF_PXP_WFE_B_STG2_5X6_OUT0_7_LUTOUT28(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STG2_5X6_OUT0_7_LUTOUT28)
+
+#define HW_PXP_WFE_B_STG2_5X6_OUT1_0 (0x00002390)
+
+#define BP_PXP_WFE_B_STG2_5X6_OUT1_0_RSVD0 30
+#define BM_PXP_WFE_B_STG2_5X6_OUT1_0_RSVD0 0xC0000000
+#define BF_PXP_WFE_B_STG2_5X6_OUT1_0_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STG2_5X6_OUT1_0_RSVD0)
+#define BP_PXP_WFE_B_STG2_5X6_OUT1_0_LUTOUT3 24
+#define BM_PXP_WFE_B_STG2_5X6_OUT1_0_LUTOUT3 0x3F000000
+#define BF_PXP_WFE_B_STG2_5X6_OUT1_0_LUTOUT3(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STG2_5X6_OUT1_0_LUTOUT3)
+#define BP_PXP_WFE_B_STG2_5X6_OUT1_0_RSVD1 22
+#define BM_PXP_WFE_B_STG2_5X6_OUT1_0_RSVD1 0x00C00000
+#define BF_PXP_WFE_B_STG2_5X6_OUT1_0_RSVD1(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STG2_5X6_OUT1_0_RSVD1)
+#define BP_PXP_WFE_B_STG2_5X6_OUT1_0_LUTOUT2 16
+#define BM_PXP_WFE_B_STG2_5X6_OUT1_0_LUTOUT2 0x003F0000
+#define BF_PXP_WFE_B_STG2_5X6_OUT1_0_LUTOUT2(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STG2_5X6_OUT1_0_LUTOUT2)
+#define BP_PXP_WFE_B_STG2_5X6_OUT1_0_RSVD2 14
+#define BM_PXP_WFE_B_STG2_5X6_OUT1_0_RSVD2 0x0000C000
+#define BF_PXP_WFE_B_STG2_5X6_OUT1_0_RSVD2(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STG2_5X6_OUT1_0_RSVD2)
+#define BP_PXP_WFE_B_STG2_5X6_OUT1_0_LUTOUT1 8
+#define BM_PXP_WFE_B_STG2_5X6_OUT1_0_LUTOUT1 0x00003F00
+#define BF_PXP_WFE_B_STG2_5X6_OUT1_0_LUTOUT1(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STG2_5X6_OUT1_0_LUTOUT1)
+#define BP_PXP_WFE_B_STG2_5X6_OUT1_0_RSVD3 6
+#define BM_PXP_WFE_B_STG2_5X6_OUT1_0_RSVD3 0x000000C0
+#define BF_PXP_WFE_B_STG2_5X6_OUT1_0_RSVD3(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STG2_5X6_OUT1_0_RSVD3)
+#define BP_PXP_WFE_B_STG2_5X6_OUT1_0_LUTOUT0 0
+#define BM_PXP_WFE_B_STG2_5X6_OUT1_0_LUTOUT0 0x0000003F
+#define BF_PXP_WFE_B_STG2_5X6_OUT1_0_LUTOUT0(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STG2_5X6_OUT1_0_LUTOUT0)
+
+#define HW_PXP_WFE_B_STG2_5X6_OUT1_1 (0x000023a0)
+
+#define BP_PXP_WFE_B_STG2_5X6_OUT1_1_RSVD0 30
+#define BM_PXP_WFE_B_STG2_5X6_OUT1_1_RSVD0 0xC0000000
+#define BF_PXP_WFE_B_STG2_5X6_OUT1_1_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STG2_5X6_OUT1_1_RSVD0)
+#define BP_PXP_WFE_B_STG2_5X6_OUT1_1_LUTOUT7 24
+#define BM_PXP_WFE_B_STG2_5X6_OUT1_1_LUTOUT7 0x3F000000
+#define BF_PXP_WFE_B_STG2_5X6_OUT1_1_LUTOUT7(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STG2_5X6_OUT1_1_LUTOUT7)
+#define BP_PXP_WFE_B_STG2_5X6_OUT1_1_RSVD1 22
+#define BM_PXP_WFE_B_STG2_5X6_OUT1_1_RSVD1 0x00C00000
+#define BF_PXP_WFE_B_STG2_5X6_OUT1_1_RSVD1(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STG2_5X6_OUT1_1_RSVD1)
+#define BP_PXP_WFE_B_STG2_5X6_OUT1_1_LUTOUT6 16
+#define BM_PXP_WFE_B_STG2_5X6_OUT1_1_LUTOUT6 0x003F0000
+#define BF_PXP_WFE_B_STG2_5X6_OUT1_1_LUTOUT6(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STG2_5X6_OUT1_1_LUTOUT6)
+#define BP_PXP_WFE_B_STG2_5X6_OUT1_1_RSVD2 14
+#define BM_PXP_WFE_B_STG2_5X6_OUT1_1_RSVD2 0x0000C000
+#define BF_PXP_WFE_B_STG2_5X6_OUT1_1_RSVD2(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STG2_5X6_OUT1_1_RSVD2)
+#define BP_PXP_WFE_B_STG2_5X6_OUT1_1_LUTOUT5 8
+#define BM_PXP_WFE_B_STG2_5X6_OUT1_1_LUTOUT5 0x00003F00
+#define BF_PXP_WFE_B_STG2_5X6_OUT1_1_LUTOUT5(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STG2_5X6_OUT1_1_LUTOUT5)
+#define BP_PXP_WFE_B_STG2_5X6_OUT1_1_RSVD3 6
+#define BM_PXP_WFE_B_STG2_5X6_OUT1_1_RSVD3 0x000000C0
+#define BF_PXP_WFE_B_STG2_5X6_OUT1_1_RSVD3(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STG2_5X6_OUT1_1_RSVD3)
+#define BP_PXP_WFE_B_STG2_5X6_OUT1_1_LUTOUT4 0
+#define BM_PXP_WFE_B_STG2_5X6_OUT1_1_LUTOUT4 0x0000003F
+#define BF_PXP_WFE_B_STG2_5X6_OUT1_1_LUTOUT4(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STG2_5X6_OUT1_1_LUTOUT4)
+
+#define HW_PXP_WFE_B_STG2_5X6_OUT1_2 (0x000023b0)
+
+#define BP_PXP_WFE_B_STG2_5X6_OUT1_2_RSVD0 30
+#define BM_PXP_WFE_B_STG2_5X6_OUT1_2_RSVD0 0xC0000000
+#define BF_PXP_WFE_B_STG2_5X6_OUT1_2_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STG2_5X6_OUT1_2_RSVD0)
+#define BP_PXP_WFE_B_STG2_5X6_OUT1_2_LUTOUT11 24
+#define BM_PXP_WFE_B_STG2_5X6_OUT1_2_LUTOUT11 0x3F000000
+#define BF_PXP_WFE_B_STG2_5X6_OUT1_2_LUTOUT11(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STG2_5X6_OUT1_2_LUTOUT11)
+#define BP_PXP_WFE_B_STG2_5X6_OUT1_2_RSVD1 22
+#define BM_PXP_WFE_B_STG2_5X6_OUT1_2_RSVD1 0x00C00000
+#define BF_PXP_WFE_B_STG2_5X6_OUT1_2_RSVD1(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STG2_5X6_OUT1_2_RSVD1)
+#define BP_PXP_WFE_B_STG2_5X6_OUT1_2_LUTOUT10 16
+#define BM_PXP_WFE_B_STG2_5X6_OUT1_2_LUTOUT10 0x003F0000
+#define BF_PXP_WFE_B_STG2_5X6_OUT1_2_LUTOUT10(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STG2_5X6_OUT1_2_LUTOUT10)
+#define BP_PXP_WFE_B_STG2_5X6_OUT1_2_RSVD2 14
+#define BM_PXP_WFE_B_STG2_5X6_OUT1_2_RSVD2 0x0000C000
+#define BF_PXP_WFE_B_STG2_5X6_OUT1_2_RSVD2(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STG2_5X6_OUT1_2_RSVD2)
+#define BP_PXP_WFE_B_STG2_5X6_OUT1_2_LUTOUT9 8
+#define BM_PXP_WFE_B_STG2_5X6_OUT1_2_LUTOUT9 0x00003F00
+#define BF_PXP_WFE_B_STG2_5X6_OUT1_2_LUTOUT9(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STG2_5X6_OUT1_2_LUTOUT9)
+#define BP_PXP_WFE_B_STG2_5X6_OUT1_2_RSVD3 6
+#define BM_PXP_WFE_B_STG2_5X6_OUT1_2_RSVD3 0x000000C0
+#define BF_PXP_WFE_B_STG2_5X6_OUT1_2_RSVD3(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STG2_5X6_OUT1_2_RSVD3)
+#define BP_PXP_WFE_B_STG2_5X6_OUT1_2_LUTOUT8 0
+#define BM_PXP_WFE_B_STG2_5X6_OUT1_2_LUTOUT8 0x0000003F
+#define BF_PXP_WFE_B_STG2_5X6_OUT1_2_LUTOUT8(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STG2_5X6_OUT1_2_LUTOUT8)
+
+#define HW_PXP_WFE_B_STG2_5X6_OUT1_3 (0x000023c0)
+
+#define BP_PXP_WFE_B_STG2_5X6_OUT1_3_RSVD0 30
+#define BM_PXP_WFE_B_STG2_5X6_OUT1_3_RSVD0 0xC0000000
+#define BF_PXP_WFE_B_STG2_5X6_OUT1_3_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STG2_5X6_OUT1_3_RSVD0)
+#define BP_PXP_WFE_B_STG2_5X6_OUT1_3_LUTOUT15 24
+#define BM_PXP_WFE_B_STG2_5X6_OUT1_3_LUTOUT15 0x3F000000
+#define BF_PXP_WFE_B_STG2_5X6_OUT1_3_LUTOUT15(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STG2_5X6_OUT1_3_LUTOUT15)
+#define BP_PXP_WFE_B_STG2_5X6_OUT1_3_RSVD1 22
+#define BM_PXP_WFE_B_STG2_5X6_OUT1_3_RSVD1 0x00C00000
+#define BF_PXP_WFE_B_STG2_5X6_OUT1_3_RSVD1(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STG2_5X6_OUT1_3_RSVD1)
+#define BP_PXP_WFE_B_STG2_5X6_OUT1_3_LUTOUT14 16
+#define BM_PXP_WFE_B_STG2_5X6_OUT1_3_LUTOUT14 0x003F0000
+#define BF_PXP_WFE_B_STG2_5X6_OUT1_3_LUTOUT14(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STG2_5X6_OUT1_3_LUTOUT14)
+#define BP_PXP_WFE_B_STG2_5X6_OUT1_3_RSVD2 14
+#define BM_PXP_WFE_B_STG2_5X6_OUT1_3_RSVD2 0x0000C000
+#define BF_PXP_WFE_B_STG2_5X6_OUT1_3_RSVD2(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STG2_5X6_OUT1_3_RSVD2)
+#define BP_PXP_WFE_B_STG2_5X6_OUT1_3_LUTOUT13 8
+#define BM_PXP_WFE_B_STG2_5X6_OUT1_3_LUTOUT13 0x00003F00
+#define BF_PXP_WFE_B_STG2_5X6_OUT1_3_LUTOUT13(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STG2_5X6_OUT1_3_LUTOUT13)
+#define BP_PXP_WFE_B_STG2_5X6_OUT1_3_RSVD3 6
+#define BM_PXP_WFE_B_STG2_5X6_OUT1_3_RSVD3 0x000000C0
+#define BF_PXP_WFE_B_STG2_5X6_OUT1_3_RSVD3(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STG2_5X6_OUT1_3_RSVD3)
+#define BP_PXP_WFE_B_STG2_5X6_OUT1_3_LUTOUT12 0
+#define BM_PXP_WFE_B_STG2_5X6_OUT1_3_LUTOUT12 0x0000003F
+#define BF_PXP_WFE_B_STG2_5X6_OUT1_3_LUTOUT12(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STG2_5X6_OUT1_3_LUTOUT12)
+
+#define HW_PXP_WFE_B_STG2_5X6_OUT1_4 (0x000023d0)
+
+#define BP_PXP_WFE_B_STG2_5X6_OUT1_4_RSVD0 30
+#define BM_PXP_WFE_B_STG2_5X6_OUT1_4_RSVD0 0xC0000000
+#define BF_PXP_WFE_B_STG2_5X6_OUT1_4_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STG2_5X6_OUT1_4_RSVD0)
+#define BP_PXP_WFE_B_STG2_5X6_OUT1_4_LUTOUT19 24
+#define BM_PXP_WFE_B_STG2_5X6_OUT1_4_LUTOUT19 0x3F000000
+#define BF_PXP_WFE_B_STG2_5X6_OUT1_4_LUTOUT19(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STG2_5X6_OUT1_4_LUTOUT19)
+#define BP_PXP_WFE_B_STG2_5X6_OUT1_4_RSVD1 22
+#define BM_PXP_WFE_B_STG2_5X6_OUT1_4_RSVD1 0x00C00000
+#define BF_PXP_WFE_B_STG2_5X6_OUT1_4_RSVD1(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STG2_5X6_OUT1_4_RSVD1)
+#define BP_PXP_WFE_B_STG2_5X6_OUT1_4_LUTOUT18 16
+#define BM_PXP_WFE_B_STG2_5X6_OUT1_4_LUTOUT18 0x003F0000
+#define BF_PXP_WFE_B_STG2_5X6_OUT1_4_LUTOUT18(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STG2_5X6_OUT1_4_LUTOUT18)
+#define BP_PXP_WFE_B_STG2_5X6_OUT1_4_RSVD2 14
+#define BM_PXP_WFE_B_STG2_5X6_OUT1_4_RSVD2 0x0000C000
+#define BF_PXP_WFE_B_STG2_5X6_OUT1_4_RSVD2(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STG2_5X6_OUT1_4_RSVD2)
+#define BP_PXP_WFE_B_STG2_5X6_OUT1_4_LUTOUT17 8
+#define BM_PXP_WFE_B_STG2_5X6_OUT1_4_LUTOUT17 0x00003F00
+#define BF_PXP_WFE_B_STG2_5X6_OUT1_4_LUTOUT17(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STG2_5X6_OUT1_4_LUTOUT17)
+#define BP_PXP_WFE_B_STG2_5X6_OUT1_4_RSVD3 6
+#define BM_PXP_WFE_B_STG2_5X6_OUT1_4_RSVD3 0x000000C0
+#define BF_PXP_WFE_B_STG2_5X6_OUT1_4_RSVD3(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STG2_5X6_OUT1_4_RSVD3)
+#define BP_PXP_WFE_B_STG2_5X6_OUT1_4_LUTOUT16 0
+#define BM_PXP_WFE_B_STG2_5X6_OUT1_4_LUTOUT16 0x0000003F
+#define BF_PXP_WFE_B_STG2_5X6_OUT1_4_LUTOUT16(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STG2_5X6_OUT1_4_LUTOUT16)
+
+#define HW_PXP_WFE_B_STG2_5X6_OUT1_5 (0x000023e0)
+
+#define BP_PXP_WFE_B_STG2_5X6_OUT1_5_RSVD0 30
+#define BM_PXP_WFE_B_STG2_5X6_OUT1_5_RSVD0 0xC0000000
+#define BF_PXP_WFE_B_STG2_5X6_OUT1_5_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STG2_5X6_OUT1_5_RSVD0)
+#define BP_PXP_WFE_B_STG2_5X6_OUT1_5_LUTOUT23 24
+#define BM_PXP_WFE_B_STG2_5X6_OUT1_5_LUTOUT23 0x3F000000
+#define BF_PXP_WFE_B_STG2_5X6_OUT1_5_LUTOUT23(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STG2_5X6_OUT1_5_LUTOUT23)
+#define BP_PXP_WFE_B_STG2_5X6_OUT1_5_RSVD1 22
+#define BM_PXP_WFE_B_STG2_5X6_OUT1_5_RSVD1 0x00C00000
+#define BF_PXP_WFE_B_STG2_5X6_OUT1_5_RSVD1(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STG2_5X6_OUT1_5_RSVD1)
+#define BP_PXP_WFE_B_STG2_5X6_OUT1_5_LUTOUT22 16
+#define BM_PXP_WFE_B_STG2_5X6_OUT1_5_LUTOUT22 0x003F0000
+#define BF_PXP_WFE_B_STG2_5X6_OUT1_5_LUTOUT22(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STG2_5X6_OUT1_5_LUTOUT22)
+#define BP_PXP_WFE_B_STG2_5X6_OUT1_5_RSVD2 14
+#define BM_PXP_WFE_B_STG2_5X6_OUT1_5_RSVD2 0x0000C000
+#define BF_PXP_WFE_B_STG2_5X6_OUT1_5_RSVD2(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STG2_5X6_OUT1_5_RSVD2)
+#define BP_PXP_WFE_B_STG2_5X6_OUT1_5_LUTOUT21 8
+#define BM_PXP_WFE_B_STG2_5X6_OUT1_5_LUTOUT21 0x00003F00
+#define BF_PXP_WFE_B_STG2_5X6_OUT1_5_LUTOUT21(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STG2_5X6_OUT1_5_LUTOUT21)
+#define BP_PXP_WFE_B_STG2_5X6_OUT1_5_RSVD3 6
+#define BM_PXP_WFE_B_STG2_5X6_OUT1_5_RSVD3 0x000000C0
+#define BF_PXP_WFE_B_STG2_5X6_OUT1_5_RSVD3(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STG2_5X6_OUT1_5_RSVD3)
+#define BP_PXP_WFE_B_STG2_5X6_OUT1_5_LUTOUT20 0
+#define BM_PXP_WFE_B_STG2_5X6_OUT1_5_LUTOUT20 0x0000003F
+#define BF_PXP_WFE_B_STG2_5X6_OUT1_5_LUTOUT20(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STG2_5X6_OUT1_5_LUTOUT20)
+
+#define HW_PXP_WFE_B_STG2_5X6_OUT1_6 (0x000023f0)
+
+#define BP_PXP_WFE_B_STG2_5X6_OUT1_6_RSVD0 30
+#define BM_PXP_WFE_B_STG2_5X6_OUT1_6_RSVD0 0xC0000000
+#define BF_PXP_WFE_B_STG2_5X6_OUT1_6_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STG2_5X6_OUT1_6_RSVD0)
+#define BP_PXP_WFE_B_STG2_5X6_OUT1_6_LUTOUT27 24
+#define BM_PXP_WFE_B_STG2_5X6_OUT1_6_LUTOUT27 0x3F000000
+#define BF_PXP_WFE_B_STG2_5X6_OUT1_6_LUTOUT27(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STG2_5X6_OUT1_6_LUTOUT27)
+#define BP_PXP_WFE_B_STG2_5X6_OUT1_6_RSVD1 22
+#define BM_PXP_WFE_B_STG2_5X6_OUT1_6_RSVD1 0x00C00000
+#define BF_PXP_WFE_B_STG2_5X6_OUT1_6_RSVD1(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STG2_5X6_OUT1_6_RSVD1)
+#define BP_PXP_WFE_B_STG2_5X6_OUT1_6_LUTOUT26 16
+#define BM_PXP_WFE_B_STG2_5X6_OUT1_6_LUTOUT26 0x003F0000
+#define BF_PXP_WFE_B_STG2_5X6_OUT1_6_LUTOUT26(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STG2_5X6_OUT1_6_LUTOUT26)
+#define BP_PXP_WFE_B_STG2_5X6_OUT1_6_RSVD2 14
+#define BM_PXP_WFE_B_STG2_5X6_OUT1_6_RSVD2 0x0000C000
+#define BF_PXP_WFE_B_STG2_5X6_OUT1_6_RSVD2(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STG2_5X6_OUT1_6_RSVD2)
+#define BP_PXP_WFE_B_STG2_5X6_OUT1_6_LUTOUT25 8
+#define BM_PXP_WFE_B_STG2_5X6_OUT1_6_LUTOUT25 0x00003F00
+#define BF_PXP_WFE_B_STG2_5X6_OUT1_6_LUTOUT25(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STG2_5X6_OUT1_6_LUTOUT25)
+#define BP_PXP_WFE_B_STG2_5X6_OUT1_6_RSVD3 6
+#define BM_PXP_WFE_B_STG2_5X6_OUT1_6_RSVD3 0x000000C0
+#define BF_PXP_WFE_B_STG2_5X6_OUT1_6_RSVD3(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STG2_5X6_OUT1_6_RSVD3)
+#define BP_PXP_WFE_B_STG2_5X6_OUT1_6_LUTOUT24 0
+#define BM_PXP_WFE_B_STG2_5X6_OUT1_6_LUTOUT24 0x0000003F
+#define BF_PXP_WFE_B_STG2_5X6_OUT1_6_LUTOUT24(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STG2_5X6_OUT1_6_LUTOUT24)
+
+#define HW_PXP_WFE_B_STG2_5X6_OUT1_7 (0x00002400)
+
+#define BP_PXP_WFE_B_STG2_5X6_OUT1_7_RSVD0 30
+#define BM_PXP_WFE_B_STG2_5X6_OUT1_7_RSVD0 0xC0000000
+#define BF_PXP_WFE_B_STG2_5X6_OUT1_7_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STG2_5X6_OUT1_7_RSVD0)
+#define BP_PXP_WFE_B_STG2_5X6_OUT1_7_LUTOUT31 24
+#define BM_PXP_WFE_B_STG2_5X6_OUT1_7_LUTOUT31 0x3F000000
+#define BF_PXP_WFE_B_STG2_5X6_OUT1_7_LUTOUT31(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STG2_5X6_OUT1_7_LUTOUT31)
+#define BP_PXP_WFE_B_STG2_5X6_OUT1_7_RSVD1 22
+#define BM_PXP_WFE_B_STG2_5X6_OUT1_7_RSVD1 0x00C00000
+#define BF_PXP_WFE_B_STG2_5X6_OUT1_7_RSVD1(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STG2_5X6_OUT1_7_RSVD1)
+#define BP_PXP_WFE_B_STG2_5X6_OUT1_7_LUTOUT30 16
+#define BM_PXP_WFE_B_STG2_5X6_OUT1_7_LUTOUT30 0x003F0000
+#define BF_PXP_WFE_B_STG2_5X6_OUT1_7_LUTOUT30(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STG2_5X6_OUT1_7_LUTOUT30)
+#define BP_PXP_WFE_B_STG2_5X6_OUT1_7_RSVD2 14
+#define BM_PXP_WFE_B_STG2_5X6_OUT1_7_RSVD2 0x0000C000
+#define BF_PXP_WFE_B_STG2_5X6_OUT1_7_RSVD2(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STG2_5X6_OUT1_7_RSVD2)
+#define BP_PXP_WFE_B_STG2_5X6_OUT1_7_LUTOUT29 8
+#define BM_PXP_WFE_B_STG2_5X6_OUT1_7_LUTOUT29 0x00003F00
+#define BF_PXP_WFE_B_STG2_5X6_OUT1_7_LUTOUT29(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STG2_5X6_OUT1_7_LUTOUT29)
+#define BP_PXP_WFE_B_STG2_5X6_OUT1_7_RSVD3 6
+#define BM_PXP_WFE_B_STG2_5X6_OUT1_7_RSVD3 0x000000C0
+#define BF_PXP_WFE_B_STG2_5X6_OUT1_7_RSVD3(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STG2_5X6_OUT1_7_RSVD3)
+#define BP_PXP_WFE_B_STG2_5X6_OUT1_7_LUTOUT28 0
+#define BM_PXP_WFE_B_STG2_5X6_OUT1_7_LUTOUT28 0x0000003F
+#define BF_PXP_WFE_B_STG2_5X6_OUT1_7_LUTOUT28(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STG2_5X6_OUT1_7_LUTOUT28)
+
+#define HW_PXP_WFE_B_STG2_5X6_OUT2_0 (0x00002410)
+
+#define BP_PXP_WFE_B_STG2_5X6_OUT2_0_RSVD0 30
+#define BM_PXP_WFE_B_STG2_5X6_OUT2_0_RSVD0 0xC0000000
+#define BF_PXP_WFE_B_STG2_5X6_OUT2_0_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STG2_5X6_OUT2_0_RSVD0)
+#define BP_PXP_WFE_B_STG2_5X6_OUT2_0_LUTOUT3 24
+#define BM_PXP_WFE_B_STG2_5X6_OUT2_0_LUTOUT3 0x3F000000
+#define BF_PXP_WFE_B_STG2_5X6_OUT2_0_LUTOUT3(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STG2_5X6_OUT2_0_LUTOUT3)
+#define BP_PXP_WFE_B_STG2_5X6_OUT2_0_RSVD1 22
+#define BM_PXP_WFE_B_STG2_5X6_OUT2_0_RSVD1 0x00C00000
+#define BF_PXP_WFE_B_STG2_5X6_OUT2_0_RSVD1(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STG2_5X6_OUT2_0_RSVD1)
+#define BP_PXP_WFE_B_STG2_5X6_OUT2_0_LUTOUT2 16
+#define BM_PXP_WFE_B_STG2_5X6_OUT2_0_LUTOUT2 0x003F0000
+#define BF_PXP_WFE_B_STG2_5X6_OUT2_0_LUTOUT2(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STG2_5X6_OUT2_0_LUTOUT2)
+#define BP_PXP_WFE_B_STG2_5X6_OUT2_0_RSVD2 14
+#define BM_PXP_WFE_B_STG2_5X6_OUT2_0_RSVD2 0x0000C000
+#define BF_PXP_WFE_B_STG2_5X6_OUT2_0_RSVD2(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STG2_5X6_OUT2_0_RSVD2)
+#define BP_PXP_WFE_B_STG2_5X6_OUT2_0_LUTOUT1 8
+#define BM_PXP_WFE_B_STG2_5X6_OUT2_0_LUTOUT1 0x00003F00
+#define BF_PXP_WFE_B_STG2_5X6_OUT2_0_LUTOUT1(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STG2_5X6_OUT2_0_LUTOUT1)
+#define BP_PXP_WFE_B_STG2_5X6_OUT2_0_RSVD3 6
+#define BM_PXP_WFE_B_STG2_5X6_OUT2_0_RSVD3 0x000000C0
+#define BF_PXP_WFE_B_STG2_5X6_OUT2_0_RSVD3(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STG2_5X6_OUT2_0_RSVD3)
+#define BP_PXP_WFE_B_STG2_5X6_OUT2_0_LUTOUT0 0
+#define BM_PXP_WFE_B_STG2_5X6_OUT2_0_LUTOUT0 0x0000003F
+#define BF_PXP_WFE_B_STG2_5X6_OUT2_0_LUTOUT0(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STG2_5X6_OUT2_0_LUTOUT0)
+
+#define HW_PXP_WFE_B_STG2_5X6_OUT2_1 (0x00002420)
+
+#define BP_PXP_WFE_B_STG2_5X6_OUT2_1_RSVD0 30
+#define BM_PXP_WFE_B_STG2_5X6_OUT2_1_RSVD0 0xC0000000
+#define BF_PXP_WFE_B_STG2_5X6_OUT2_1_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STG2_5X6_OUT2_1_RSVD0)
+#define BP_PXP_WFE_B_STG2_5X6_OUT2_1_LUTOUT7 24
+#define BM_PXP_WFE_B_STG2_5X6_OUT2_1_LUTOUT7 0x3F000000
+#define BF_PXP_WFE_B_STG2_5X6_OUT2_1_LUTOUT7(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STG2_5X6_OUT2_1_LUTOUT7)
+#define BP_PXP_WFE_B_STG2_5X6_OUT2_1_RSVD1 22
+#define BM_PXP_WFE_B_STG2_5X6_OUT2_1_RSVD1 0x00C00000
+#define BF_PXP_WFE_B_STG2_5X6_OUT2_1_RSVD1(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STG2_5X6_OUT2_1_RSVD1)
+#define BP_PXP_WFE_B_STG2_5X6_OUT2_1_LUTOUT6 16
+#define BM_PXP_WFE_B_STG2_5X6_OUT2_1_LUTOUT6 0x003F0000
+#define BF_PXP_WFE_B_STG2_5X6_OUT2_1_LUTOUT6(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STG2_5X6_OUT2_1_LUTOUT6)
+#define BP_PXP_WFE_B_STG2_5X6_OUT2_1_RSVD2 14
+#define BM_PXP_WFE_B_STG2_5X6_OUT2_1_RSVD2 0x0000C000
+#define BF_PXP_WFE_B_STG2_5X6_OUT2_1_RSVD2(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STG2_5X6_OUT2_1_RSVD2)
+#define BP_PXP_WFE_B_STG2_5X6_OUT2_1_LUTOUT5 8
+#define BM_PXP_WFE_B_STG2_5X6_OUT2_1_LUTOUT5 0x00003F00
+#define BF_PXP_WFE_B_STG2_5X6_OUT2_1_LUTOUT5(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STG2_5X6_OUT2_1_LUTOUT5)
+#define BP_PXP_WFE_B_STG2_5X6_OUT2_1_RSVD3 6
+#define BM_PXP_WFE_B_STG2_5X6_OUT2_1_RSVD3 0x000000C0
+#define BF_PXP_WFE_B_STG2_5X6_OUT2_1_RSVD3(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STG2_5X6_OUT2_1_RSVD3)
+#define BP_PXP_WFE_B_STG2_5X6_OUT2_1_LUTOUT4 0
+#define BM_PXP_WFE_B_STG2_5X6_OUT2_1_LUTOUT4 0x0000003F
+#define BF_PXP_WFE_B_STG2_5X6_OUT2_1_LUTOUT4(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STG2_5X6_OUT2_1_LUTOUT4)
+
+#define HW_PXP_WFE_B_STG2_5X6_OUT2_2 (0x00002430)
+
+#define BP_PXP_WFE_B_STG2_5X6_OUT2_2_RSVD0 30
+#define BM_PXP_WFE_B_STG2_5X6_OUT2_2_RSVD0 0xC0000000
+#define BF_PXP_WFE_B_STG2_5X6_OUT2_2_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STG2_5X6_OUT2_2_RSVD0)
+#define BP_PXP_WFE_B_STG2_5X6_OUT2_2_LUTOUT11 24
+#define BM_PXP_WFE_B_STG2_5X6_OUT2_2_LUTOUT11 0x3F000000
+#define BF_PXP_WFE_B_STG2_5X6_OUT2_2_LUTOUT11(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STG2_5X6_OUT2_2_LUTOUT11)
+#define BP_PXP_WFE_B_STG2_5X6_OUT2_2_RSVD1 22
+#define BM_PXP_WFE_B_STG2_5X6_OUT2_2_RSVD1 0x00C00000
+#define BF_PXP_WFE_B_STG2_5X6_OUT2_2_RSVD1(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STG2_5X6_OUT2_2_RSVD1)
+#define BP_PXP_WFE_B_STG2_5X6_OUT2_2_LUTOUT10 16
+#define BM_PXP_WFE_B_STG2_5X6_OUT2_2_LUTOUT10 0x003F0000
+#define BF_PXP_WFE_B_STG2_5X6_OUT2_2_LUTOUT10(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STG2_5X6_OUT2_2_LUTOUT10)
+#define BP_PXP_WFE_B_STG2_5X6_OUT2_2_RSVD2 14
+#define BM_PXP_WFE_B_STG2_5X6_OUT2_2_RSVD2 0x0000C000
+#define BF_PXP_WFE_B_STG2_5X6_OUT2_2_RSVD2(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STG2_5X6_OUT2_2_RSVD2)
+#define BP_PXP_WFE_B_STG2_5X6_OUT2_2_LUTOUT9 8
+#define BM_PXP_WFE_B_STG2_5X6_OUT2_2_LUTOUT9 0x00003F00
+#define BF_PXP_WFE_B_STG2_5X6_OUT2_2_LUTOUT9(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STG2_5X6_OUT2_2_LUTOUT9)
+#define BP_PXP_WFE_B_STG2_5X6_OUT2_2_RSVD3 6
+#define BM_PXP_WFE_B_STG2_5X6_OUT2_2_RSVD3 0x000000C0
+#define BF_PXP_WFE_B_STG2_5X6_OUT2_2_RSVD3(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STG2_5X6_OUT2_2_RSVD3)
+#define BP_PXP_WFE_B_STG2_5X6_OUT2_2_LUTOUT8 0
+#define BM_PXP_WFE_B_STG2_5X6_OUT2_2_LUTOUT8 0x0000003F
+#define BF_PXP_WFE_B_STG2_5X6_OUT2_2_LUTOUT8(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STG2_5X6_OUT2_2_LUTOUT8)
+
+#define HW_PXP_WFE_B_STG2_5X6_OUT2_3 (0x00002440)
+
+#define BP_PXP_WFE_B_STG2_5X6_OUT2_3_RSVD0 30
+#define BM_PXP_WFE_B_STG2_5X6_OUT2_3_RSVD0 0xC0000000
+#define BF_PXP_WFE_B_STG2_5X6_OUT2_3_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STG2_5X6_OUT2_3_RSVD0)
+#define BP_PXP_WFE_B_STG2_5X6_OUT2_3_LUTOUT15 24
+#define BM_PXP_WFE_B_STG2_5X6_OUT2_3_LUTOUT15 0x3F000000
+#define BF_PXP_WFE_B_STG2_5X6_OUT2_3_LUTOUT15(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STG2_5X6_OUT2_3_LUTOUT15)
+#define BP_PXP_WFE_B_STG2_5X6_OUT2_3_RSVD1 22
+#define BM_PXP_WFE_B_STG2_5X6_OUT2_3_RSVD1 0x00C00000
+#define BF_PXP_WFE_B_STG2_5X6_OUT2_3_RSVD1(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STG2_5X6_OUT2_3_RSVD1)
+#define BP_PXP_WFE_B_STG2_5X6_OUT2_3_LUTOUT14 16
+#define BM_PXP_WFE_B_STG2_5X6_OUT2_3_LUTOUT14 0x003F0000
+#define BF_PXP_WFE_B_STG2_5X6_OUT2_3_LUTOUT14(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STG2_5X6_OUT2_3_LUTOUT14)
+#define BP_PXP_WFE_B_STG2_5X6_OUT2_3_RSVD2 14
+#define BM_PXP_WFE_B_STG2_5X6_OUT2_3_RSVD2 0x0000C000
+#define BF_PXP_WFE_B_STG2_5X6_OUT2_3_RSVD2(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STG2_5X6_OUT2_3_RSVD2)
+#define BP_PXP_WFE_B_STG2_5X6_OUT2_3_LUTOUT13 8
+#define BM_PXP_WFE_B_STG2_5X6_OUT2_3_LUTOUT13 0x00003F00
+#define BF_PXP_WFE_B_STG2_5X6_OUT2_3_LUTOUT13(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STG2_5X6_OUT2_3_LUTOUT13)
+#define BP_PXP_WFE_B_STG2_5X6_OUT2_3_RSVD3 6
+#define BM_PXP_WFE_B_STG2_5X6_OUT2_3_RSVD3 0x000000C0
+#define BF_PXP_WFE_B_STG2_5X6_OUT2_3_RSVD3(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STG2_5X6_OUT2_3_RSVD3)
+#define BP_PXP_WFE_B_STG2_5X6_OUT2_3_LUTOUT12 0
+#define BM_PXP_WFE_B_STG2_5X6_OUT2_3_LUTOUT12 0x0000003F
+#define BF_PXP_WFE_B_STG2_5X6_OUT2_3_LUTOUT12(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STG2_5X6_OUT2_3_LUTOUT12)
+
+#define HW_PXP_WFE_B_STG2_5X6_OUT2_4 (0x00002450)
+
+#define BP_PXP_WFE_B_STG2_5X6_OUT2_4_RSVD0 30
+#define BM_PXP_WFE_B_STG2_5X6_OUT2_4_RSVD0 0xC0000000
+#define BF_PXP_WFE_B_STG2_5X6_OUT2_4_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STG2_5X6_OUT2_4_RSVD0)
+#define BP_PXP_WFE_B_STG2_5X6_OUT2_4_LUTOUT19 24
+#define BM_PXP_WFE_B_STG2_5X6_OUT2_4_LUTOUT19 0x3F000000
+#define BF_PXP_WFE_B_STG2_5X6_OUT2_4_LUTOUT19(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STG2_5X6_OUT2_4_LUTOUT19)
+#define BP_PXP_WFE_B_STG2_5X6_OUT2_4_RSVD1 22
+#define BM_PXP_WFE_B_STG2_5X6_OUT2_4_RSVD1 0x00C00000
+#define BF_PXP_WFE_B_STG2_5X6_OUT2_4_RSVD1(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STG2_5X6_OUT2_4_RSVD1)
+#define BP_PXP_WFE_B_STG2_5X6_OUT2_4_LUTOUT18 16
+#define BM_PXP_WFE_B_STG2_5X6_OUT2_4_LUTOUT18 0x003F0000
+#define BF_PXP_WFE_B_STG2_5X6_OUT2_4_LUTOUT18(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STG2_5X6_OUT2_4_LUTOUT18)
+#define BP_PXP_WFE_B_STG2_5X6_OUT2_4_RSVD2 14
+#define BM_PXP_WFE_B_STG2_5X6_OUT2_4_RSVD2 0x0000C000
+#define BF_PXP_WFE_B_STG2_5X6_OUT2_4_RSVD2(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STG2_5X6_OUT2_4_RSVD2)
+#define BP_PXP_WFE_B_STG2_5X6_OUT2_4_LUTOUT17 8
+#define BM_PXP_WFE_B_STG2_5X6_OUT2_4_LUTOUT17 0x00003F00
+#define BF_PXP_WFE_B_STG2_5X6_OUT2_4_LUTOUT17(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STG2_5X6_OUT2_4_LUTOUT17)
+#define BP_PXP_WFE_B_STG2_5X6_OUT2_4_RSVD3 6
+#define BM_PXP_WFE_B_STG2_5X6_OUT2_4_RSVD3 0x000000C0
+#define BF_PXP_WFE_B_STG2_5X6_OUT2_4_RSVD3(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STG2_5X6_OUT2_4_RSVD3)
+#define BP_PXP_WFE_B_STG2_5X6_OUT2_4_LUTOUT16 0
+#define BM_PXP_WFE_B_STG2_5X6_OUT2_4_LUTOUT16 0x0000003F
+#define BF_PXP_WFE_B_STG2_5X6_OUT2_4_LUTOUT16(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STG2_5X6_OUT2_4_LUTOUT16)
+
+#define HW_PXP_WFE_B_STG2_5X6_OUT2_5 (0x00002460)
+
+#define BP_PXP_WFE_B_STG2_5X6_OUT2_5_RSVD0 30
+#define BM_PXP_WFE_B_STG2_5X6_OUT2_5_RSVD0 0xC0000000
+#define BF_PXP_WFE_B_STG2_5X6_OUT2_5_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STG2_5X6_OUT2_5_RSVD0)
+#define BP_PXP_WFE_B_STG2_5X6_OUT2_5_LUTOUT23 24
+#define BM_PXP_WFE_B_STG2_5X6_OUT2_5_LUTOUT23 0x3F000000
+#define BF_PXP_WFE_B_STG2_5X6_OUT2_5_LUTOUT23(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STG2_5X6_OUT2_5_LUTOUT23)
+#define BP_PXP_WFE_B_STG2_5X6_OUT2_5_RSVD1 22
+#define BM_PXP_WFE_B_STG2_5X6_OUT2_5_RSVD1 0x00C00000
+#define BF_PXP_WFE_B_STG2_5X6_OUT2_5_RSVD1(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STG2_5X6_OUT2_5_RSVD1)
+#define BP_PXP_WFE_B_STG2_5X6_OUT2_5_LUTOUT22 16
+#define BM_PXP_WFE_B_STG2_5X6_OUT2_5_LUTOUT22 0x003F0000
+#define BF_PXP_WFE_B_STG2_5X6_OUT2_5_LUTOUT22(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STG2_5X6_OUT2_5_LUTOUT22)
+#define BP_PXP_WFE_B_STG2_5X6_OUT2_5_RSVD2 14
+#define BM_PXP_WFE_B_STG2_5X6_OUT2_5_RSVD2 0x0000C000
+#define BF_PXP_WFE_B_STG2_5X6_OUT2_5_RSVD2(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STG2_5X6_OUT2_5_RSVD2)
+#define BP_PXP_WFE_B_STG2_5X6_OUT2_5_LUTOUT21 8
+#define BM_PXP_WFE_B_STG2_5X6_OUT2_5_LUTOUT21 0x00003F00
+#define BF_PXP_WFE_B_STG2_5X6_OUT2_5_LUTOUT21(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STG2_5X6_OUT2_5_LUTOUT21)
+#define BP_PXP_WFE_B_STG2_5X6_OUT2_5_RSVD3 6
+#define BM_PXP_WFE_B_STG2_5X6_OUT2_5_RSVD3 0x000000C0
+#define BF_PXP_WFE_B_STG2_5X6_OUT2_5_RSVD3(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STG2_5X6_OUT2_5_RSVD3)
+#define BP_PXP_WFE_B_STG2_5X6_OUT2_5_LUTOUT20 0
+#define BM_PXP_WFE_B_STG2_5X6_OUT2_5_LUTOUT20 0x0000003F
+#define BF_PXP_WFE_B_STG2_5X6_OUT2_5_LUTOUT20(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STG2_5X6_OUT2_5_LUTOUT20)
+
+#define HW_PXP_WFE_B_STG2_5X6_OUT2_6 (0x00002470)
+
+#define BP_PXP_WFE_B_STG2_5X6_OUT2_6_RSVD0 30
+#define BM_PXP_WFE_B_STG2_5X6_OUT2_6_RSVD0 0xC0000000
+#define BF_PXP_WFE_B_STG2_5X6_OUT2_6_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STG2_5X6_OUT2_6_RSVD0)
+#define BP_PXP_WFE_B_STG2_5X6_OUT2_6_LUTOUT27 24
+#define BM_PXP_WFE_B_STG2_5X6_OUT2_6_LUTOUT27 0x3F000000
+#define BF_PXP_WFE_B_STG2_5X6_OUT2_6_LUTOUT27(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STG2_5X6_OUT2_6_LUTOUT27)
+#define BP_PXP_WFE_B_STG2_5X6_OUT2_6_RSVD1 22
+#define BM_PXP_WFE_B_STG2_5X6_OUT2_6_RSVD1 0x00C00000
+#define BF_PXP_WFE_B_STG2_5X6_OUT2_6_RSVD1(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STG2_5X6_OUT2_6_RSVD1)
+#define BP_PXP_WFE_B_STG2_5X6_OUT2_6_LUTOUT26 16
+#define BM_PXP_WFE_B_STG2_5X6_OUT2_6_LUTOUT26 0x003F0000
+#define BF_PXP_WFE_B_STG2_5X6_OUT2_6_LUTOUT26(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STG2_5X6_OUT2_6_LUTOUT26)
+#define BP_PXP_WFE_B_STG2_5X6_OUT2_6_RSVD2 14
+#define BM_PXP_WFE_B_STG2_5X6_OUT2_6_RSVD2 0x0000C000
+#define BF_PXP_WFE_B_STG2_5X6_OUT2_6_RSVD2(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STG2_5X6_OUT2_6_RSVD2)
+#define BP_PXP_WFE_B_STG2_5X6_OUT2_6_LUTOUT25 8
+#define BM_PXP_WFE_B_STG2_5X6_OUT2_6_LUTOUT25 0x00003F00
+#define BF_PXP_WFE_B_STG2_5X6_OUT2_6_LUTOUT25(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STG2_5X6_OUT2_6_LUTOUT25)
+#define BP_PXP_WFE_B_STG2_5X6_OUT2_6_RSVD3 6
+#define BM_PXP_WFE_B_STG2_5X6_OUT2_6_RSVD3 0x000000C0
+#define BF_PXP_WFE_B_STG2_5X6_OUT2_6_RSVD3(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STG2_5X6_OUT2_6_RSVD3)
+#define BP_PXP_WFE_B_STG2_5X6_OUT2_6_LUTOUT24 0
+#define BM_PXP_WFE_B_STG2_5X6_OUT2_6_LUTOUT24 0x0000003F
+#define BF_PXP_WFE_B_STG2_5X6_OUT2_6_LUTOUT24(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STG2_5X6_OUT2_6_LUTOUT24)
+
+#define HW_PXP_WFE_B_STG2_5X6_OUT2_7 (0x00002480)
+
+#define BP_PXP_WFE_B_STG2_5X6_OUT2_7_RSVD0 30
+#define BM_PXP_WFE_B_STG2_5X6_OUT2_7_RSVD0 0xC0000000
+#define BF_PXP_WFE_B_STG2_5X6_OUT2_7_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STG2_5X6_OUT2_7_RSVD0)
+#define BP_PXP_WFE_B_STG2_5X6_OUT2_7_LUTOUT31 24
+#define BM_PXP_WFE_B_STG2_5X6_OUT2_7_LUTOUT31 0x3F000000
+#define BF_PXP_WFE_B_STG2_5X6_OUT2_7_LUTOUT31(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STG2_5X6_OUT2_7_LUTOUT31)
+#define BP_PXP_WFE_B_STG2_5X6_OUT2_7_RSVD1 22
+#define BM_PXP_WFE_B_STG2_5X6_OUT2_7_RSVD1 0x00C00000
+#define BF_PXP_WFE_B_STG2_5X6_OUT2_7_RSVD1(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STG2_5X6_OUT2_7_RSVD1)
+#define BP_PXP_WFE_B_STG2_5X6_OUT2_7_LUTOUT30 16
+#define BM_PXP_WFE_B_STG2_5X6_OUT2_7_LUTOUT30 0x003F0000
+#define BF_PXP_WFE_B_STG2_5X6_OUT2_7_LUTOUT30(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STG2_5X6_OUT2_7_LUTOUT30)
+#define BP_PXP_WFE_B_STG2_5X6_OUT2_7_RSVD2 14
+#define BM_PXP_WFE_B_STG2_5X6_OUT2_7_RSVD2 0x0000C000
+#define BF_PXP_WFE_B_STG2_5X6_OUT2_7_RSVD2(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STG2_5X6_OUT2_7_RSVD2)
+#define BP_PXP_WFE_B_STG2_5X6_OUT2_7_LUTOUT29 8
+#define BM_PXP_WFE_B_STG2_5X6_OUT2_7_LUTOUT29 0x00003F00
+#define BF_PXP_WFE_B_STG2_5X6_OUT2_7_LUTOUT29(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STG2_5X6_OUT2_7_LUTOUT29)
+#define BP_PXP_WFE_B_STG2_5X6_OUT2_7_RSVD3 6
+#define BM_PXP_WFE_B_STG2_5X6_OUT2_7_RSVD3 0x000000C0
+#define BF_PXP_WFE_B_STG2_5X6_OUT2_7_RSVD3(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STG2_5X6_OUT2_7_RSVD3)
+#define BP_PXP_WFE_B_STG2_5X6_OUT2_7_LUTOUT28 0
+#define BM_PXP_WFE_B_STG2_5X6_OUT2_7_LUTOUT28 0x0000003F
+#define BF_PXP_WFE_B_STG2_5X6_OUT2_7_LUTOUT28(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STG2_5X6_OUT2_7_LUTOUT28)
+
+#define HW_PXP_WFE_B_STG2_5X6_OUT3_0 (0x00002490)
+
+#define BP_PXP_WFE_B_STG2_5X6_OUT3_0_RSVD0 30
+#define BM_PXP_WFE_B_STG2_5X6_OUT3_0_RSVD0 0xC0000000
+#define BF_PXP_WFE_B_STG2_5X6_OUT3_0_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STG2_5X6_OUT3_0_RSVD0)
+#define BP_PXP_WFE_B_STG2_5X6_OUT3_0_LUTOUT3 24
+#define BM_PXP_WFE_B_STG2_5X6_OUT3_0_LUTOUT3 0x3F000000
+#define BF_PXP_WFE_B_STG2_5X6_OUT3_0_LUTOUT3(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STG2_5X6_OUT3_0_LUTOUT3)
+#define BP_PXP_WFE_B_STG2_5X6_OUT3_0_RSVD1 22
+#define BM_PXP_WFE_B_STG2_5X6_OUT3_0_RSVD1 0x00C00000
+#define BF_PXP_WFE_B_STG2_5X6_OUT3_0_RSVD1(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STG2_5X6_OUT3_0_RSVD1)
+#define BP_PXP_WFE_B_STG2_5X6_OUT3_0_LUTOUT2 16
+#define BM_PXP_WFE_B_STG2_5X6_OUT3_0_LUTOUT2 0x003F0000
+#define BF_PXP_WFE_B_STG2_5X6_OUT3_0_LUTOUT2(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STG2_5X6_OUT3_0_LUTOUT2)
+#define BP_PXP_WFE_B_STG2_5X6_OUT3_0_RSVD2 14
+#define BM_PXP_WFE_B_STG2_5X6_OUT3_0_RSVD2 0x0000C000
+#define BF_PXP_WFE_B_STG2_5X6_OUT3_0_RSVD2(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STG2_5X6_OUT3_0_RSVD2)
+#define BP_PXP_WFE_B_STG2_5X6_OUT3_0_LUTOUT1 8
+#define BM_PXP_WFE_B_STG2_5X6_OUT3_0_LUTOUT1 0x00003F00
+#define BF_PXP_WFE_B_STG2_5X6_OUT3_0_LUTOUT1(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STG2_5X6_OUT3_0_LUTOUT1)
+#define BP_PXP_WFE_B_STG2_5X6_OUT3_0_RSVD3 6
+#define BM_PXP_WFE_B_STG2_5X6_OUT3_0_RSVD3 0x000000C0
+#define BF_PXP_WFE_B_STG2_5X6_OUT3_0_RSVD3(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STG2_5X6_OUT3_0_RSVD3)
+#define BP_PXP_WFE_B_STG2_5X6_OUT3_0_LUTOUT0 0
+#define BM_PXP_WFE_B_STG2_5X6_OUT3_0_LUTOUT0 0x0000003F
+#define BF_PXP_WFE_B_STG2_5X6_OUT3_0_LUTOUT0(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STG2_5X6_OUT3_0_LUTOUT0)
+
+#define HW_PXP_WFE_B_STG2_5X6_OUT3_1 (0x000024a0)
+
+#define BP_PXP_WFE_B_STG2_5X6_OUT3_1_RSVD0 30
+#define BM_PXP_WFE_B_STG2_5X6_OUT3_1_RSVD0 0xC0000000
+#define BF_PXP_WFE_B_STG2_5X6_OUT3_1_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STG2_5X6_OUT3_1_RSVD0)
+#define BP_PXP_WFE_B_STG2_5X6_OUT3_1_LUTOUT7 24
+#define BM_PXP_WFE_B_STG2_5X6_OUT3_1_LUTOUT7 0x3F000000
+#define BF_PXP_WFE_B_STG2_5X6_OUT3_1_LUTOUT7(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STG2_5X6_OUT3_1_LUTOUT7)
+#define BP_PXP_WFE_B_STG2_5X6_OUT3_1_RSVD1 22
+#define BM_PXP_WFE_B_STG2_5X6_OUT3_1_RSVD1 0x00C00000
+#define BF_PXP_WFE_B_STG2_5X6_OUT3_1_RSVD1(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STG2_5X6_OUT3_1_RSVD1)
+#define BP_PXP_WFE_B_STG2_5X6_OUT3_1_LUTOUT6 16
+#define BM_PXP_WFE_B_STG2_5X6_OUT3_1_LUTOUT6 0x003F0000
+#define BF_PXP_WFE_B_STG2_5X6_OUT3_1_LUTOUT6(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STG2_5X6_OUT3_1_LUTOUT6)
+#define BP_PXP_WFE_B_STG2_5X6_OUT3_1_RSVD2 14
+#define BM_PXP_WFE_B_STG2_5X6_OUT3_1_RSVD2 0x0000C000
+#define BF_PXP_WFE_B_STG2_5X6_OUT3_1_RSVD2(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STG2_5X6_OUT3_1_RSVD2)
+#define BP_PXP_WFE_B_STG2_5X6_OUT3_1_LUTOUT5 8
+#define BM_PXP_WFE_B_STG2_5X6_OUT3_1_LUTOUT5 0x00003F00
+#define BF_PXP_WFE_B_STG2_5X6_OUT3_1_LUTOUT5(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STG2_5X6_OUT3_1_LUTOUT5)
+#define BP_PXP_WFE_B_STG2_5X6_OUT3_1_RSVD3 6
+#define BM_PXP_WFE_B_STG2_5X6_OUT3_1_RSVD3 0x000000C0
+#define BF_PXP_WFE_B_STG2_5X6_OUT3_1_RSVD3(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STG2_5X6_OUT3_1_RSVD3)
+#define BP_PXP_WFE_B_STG2_5X6_OUT3_1_LUTOUT4 0
+#define BM_PXP_WFE_B_STG2_5X6_OUT3_1_LUTOUT4 0x0000003F
+#define BF_PXP_WFE_B_STG2_5X6_OUT3_1_LUTOUT4(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STG2_5X6_OUT3_1_LUTOUT4)
+
+#define HW_PXP_WFE_B_STG2_5X6_OUT3_2 (0x000024b0)
+
+#define BP_PXP_WFE_B_STG2_5X6_OUT3_2_RSVD0 30
+#define BM_PXP_WFE_B_STG2_5X6_OUT3_2_RSVD0 0xC0000000
+#define BF_PXP_WFE_B_STG2_5X6_OUT3_2_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STG2_5X6_OUT3_2_RSVD0)
+#define BP_PXP_WFE_B_STG2_5X6_OUT3_2_LUTOUT11 24
+#define BM_PXP_WFE_B_STG2_5X6_OUT3_2_LUTOUT11 0x3F000000
+#define BF_PXP_WFE_B_STG2_5X6_OUT3_2_LUTOUT11(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STG2_5X6_OUT3_2_LUTOUT11)
+#define BP_PXP_WFE_B_STG2_5X6_OUT3_2_RSVD1 22
+#define BM_PXP_WFE_B_STG2_5X6_OUT3_2_RSVD1 0x00C00000
+#define BF_PXP_WFE_B_STG2_5X6_OUT3_2_RSVD1(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STG2_5X6_OUT3_2_RSVD1)
+#define BP_PXP_WFE_B_STG2_5X6_OUT3_2_LUTOUT10 16
+#define BM_PXP_WFE_B_STG2_5X6_OUT3_2_LUTOUT10 0x003F0000
+#define BF_PXP_WFE_B_STG2_5X6_OUT3_2_LUTOUT10(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STG2_5X6_OUT3_2_LUTOUT10)
+#define BP_PXP_WFE_B_STG2_5X6_OUT3_2_RSVD2 14
+#define BM_PXP_WFE_B_STG2_5X6_OUT3_2_RSVD2 0x0000C000
+#define BF_PXP_WFE_B_STG2_5X6_OUT3_2_RSVD2(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STG2_5X6_OUT3_2_RSVD2)
+#define BP_PXP_WFE_B_STG2_5X6_OUT3_2_LUTOUT9 8
+#define BM_PXP_WFE_B_STG2_5X6_OUT3_2_LUTOUT9 0x00003F00
+#define BF_PXP_WFE_B_STG2_5X6_OUT3_2_LUTOUT9(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STG2_5X6_OUT3_2_LUTOUT9)
+#define BP_PXP_WFE_B_STG2_5X6_OUT3_2_RSVD3 6
+#define BM_PXP_WFE_B_STG2_5X6_OUT3_2_RSVD3 0x000000C0
+#define BF_PXP_WFE_B_STG2_5X6_OUT3_2_RSVD3(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STG2_5X6_OUT3_2_RSVD3)
+#define BP_PXP_WFE_B_STG2_5X6_OUT3_2_LUTOUT8 0
+#define BM_PXP_WFE_B_STG2_5X6_OUT3_2_LUTOUT8 0x0000003F
+#define BF_PXP_WFE_B_STG2_5X6_OUT3_2_LUTOUT8(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STG2_5X6_OUT3_2_LUTOUT8)
+
+#define HW_PXP_WFE_B_STG2_5X6_OUT3_3 (0x000024c0)
+
+#define BP_PXP_WFE_B_STG2_5X6_OUT3_3_RSVD0 30
+#define BM_PXP_WFE_B_STG2_5X6_OUT3_3_RSVD0 0xC0000000
+#define BF_PXP_WFE_B_STG2_5X6_OUT3_3_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STG2_5X6_OUT3_3_RSVD0)
+#define BP_PXP_WFE_B_STG2_5X6_OUT3_3_LUTOUT15 24
+#define BM_PXP_WFE_B_STG2_5X6_OUT3_3_LUTOUT15 0x3F000000
+#define BF_PXP_WFE_B_STG2_5X6_OUT3_3_LUTOUT15(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STG2_5X6_OUT3_3_LUTOUT15)
+#define BP_PXP_WFE_B_STG2_5X6_OUT3_3_RSVD1 22
+#define BM_PXP_WFE_B_STG2_5X6_OUT3_3_RSVD1 0x00C00000
+#define BF_PXP_WFE_B_STG2_5X6_OUT3_3_RSVD1(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STG2_5X6_OUT3_3_RSVD1)
+#define BP_PXP_WFE_B_STG2_5X6_OUT3_3_LUTOUT14 16
+#define BM_PXP_WFE_B_STG2_5X6_OUT3_3_LUTOUT14 0x003F0000
+#define BF_PXP_WFE_B_STG2_5X6_OUT3_3_LUTOUT14(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STG2_5X6_OUT3_3_LUTOUT14)
+#define BP_PXP_WFE_B_STG2_5X6_OUT3_3_RSVD2 14
+#define BM_PXP_WFE_B_STG2_5X6_OUT3_3_RSVD2 0x0000C000
+#define BF_PXP_WFE_B_STG2_5X6_OUT3_3_RSVD2(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STG2_5X6_OUT3_3_RSVD2)
+#define BP_PXP_WFE_B_STG2_5X6_OUT3_3_LUTOUT13 8
+#define BM_PXP_WFE_B_STG2_5X6_OUT3_3_LUTOUT13 0x00003F00
+#define BF_PXP_WFE_B_STG2_5X6_OUT3_3_LUTOUT13(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STG2_5X6_OUT3_3_LUTOUT13)
+#define BP_PXP_WFE_B_STG2_5X6_OUT3_3_RSVD3 6
+#define BM_PXP_WFE_B_STG2_5X6_OUT3_3_RSVD3 0x000000C0
+#define BF_PXP_WFE_B_STG2_5X6_OUT3_3_RSVD3(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STG2_5X6_OUT3_3_RSVD3)
+#define BP_PXP_WFE_B_STG2_5X6_OUT3_3_LUTOUT12 0
+#define BM_PXP_WFE_B_STG2_5X6_OUT3_3_LUTOUT12 0x0000003F
+#define BF_PXP_WFE_B_STG2_5X6_OUT3_3_LUTOUT12(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STG2_5X6_OUT3_3_LUTOUT12)
+
+#define HW_PXP_WFE_B_STG2_5X6_OUT3_4 (0x000024e0)
+
+#define BP_PXP_WFE_B_STG2_5X6_OUT3_4_RSVD0 30
+#define BM_PXP_WFE_B_STG2_5X6_OUT3_4_RSVD0 0xC0000000
+#define BF_PXP_WFE_B_STG2_5X6_OUT3_4_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STG2_5X6_OUT3_4_RSVD0)
+#define BP_PXP_WFE_B_STG2_5X6_OUT3_4_LUTOUT19 24
+#define BM_PXP_WFE_B_STG2_5X6_OUT3_4_LUTOUT19 0x3F000000
+#define BF_PXP_WFE_B_STG2_5X6_OUT3_4_LUTOUT19(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STG2_5X6_OUT3_4_LUTOUT19)
+#define BP_PXP_WFE_B_STG2_5X6_OUT3_4_RSVD1 22
+#define BM_PXP_WFE_B_STG2_5X6_OUT3_4_RSVD1 0x00C00000
+#define BF_PXP_WFE_B_STG2_5X6_OUT3_4_RSVD1(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STG2_5X6_OUT3_4_RSVD1)
+#define BP_PXP_WFE_B_STG2_5X6_OUT3_4_LUTOUT18 16
+#define BM_PXP_WFE_B_STG2_5X6_OUT3_4_LUTOUT18 0x003F0000
+#define BF_PXP_WFE_B_STG2_5X6_OUT3_4_LUTOUT18(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STG2_5X6_OUT3_4_LUTOUT18)
+#define BP_PXP_WFE_B_STG2_5X6_OUT3_4_RSVD2 14
+#define BM_PXP_WFE_B_STG2_5X6_OUT3_4_RSVD2 0x0000C000
+#define BF_PXP_WFE_B_STG2_5X6_OUT3_4_RSVD2(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STG2_5X6_OUT3_4_RSVD2)
+#define BP_PXP_WFE_B_STG2_5X6_OUT3_4_LUTOUT17 8
+#define BM_PXP_WFE_B_STG2_5X6_OUT3_4_LUTOUT17 0x00003F00
+#define BF_PXP_WFE_B_STG2_5X6_OUT3_4_LUTOUT17(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STG2_5X6_OUT3_4_LUTOUT17)
+#define BP_PXP_WFE_B_STG2_5X6_OUT3_4_RSVD3 6
+#define BM_PXP_WFE_B_STG2_5X6_OUT3_4_RSVD3 0x000000C0
+#define BF_PXP_WFE_B_STG2_5X6_OUT3_4_RSVD3(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STG2_5X6_OUT3_4_RSVD3)
+#define BP_PXP_WFE_B_STG2_5X6_OUT3_4_LUTOUT16 0
+#define BM_PXP_WFE_B_STG2_5X6_OUT3_4_LUTOUT16 0x0000003F
+#define BF_PXP_WFE_B_STG2_5X6_OUT3_4_LUTOUT16(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STG2_5X6_OUT3_4_LUTOUT16)
+
+#define HW_PXP_WFE_B_STG2_5X6_OUT3_5 (0x000024f0)
+
+#define BP_PXP_WFE_B_STG2_5X6_OUT3_5_RSVD0 30
+#define BM_PXP_WFE_B_STG2_5X6_OUT3_5_RSVD0 0xC0000000
+#define BF_PXP_WFE_B_STG2_5X6_OUT3_5_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STG2_5X6_OUT3_5_RSVD0)
+#define BP_PXP_WFE_B_STG2_5X6_OUT3_5_LUTOUT23 24
+#define BM_PXP_WFE_B_STG2_5X6_OUT3_5_LUTOUT23 0x3F000000
+#define BF_PXP_WFE_B_STG2_5X6_OUT3_5_LUTOUT23(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STG2_5X6_OUT3_5_LUTOUT23)
+#define BP_PXP_WFE_B_STG2_5X6_OUT3_5_RSVD1 22
+#define BM_PXP_WFE_B_STG2_5X6_OUT3_5_RSVD1 0x00C00000
+#define BF_PXP_WFE_B_STG2_5X6_OUT3_5_RSVD1(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STG2_5X6_OUT3_5_RSVD1)
+#define BP_PXP_WFE_B_STG2_5X6_OUT3_5_LUTOUT22 16
+#define BM_PXP_WFE_B_STG2_5X6_OUT3_5_LUTOUT22 0x003F0000
+#define BF_PXP_WFE_B_STG2_5X6_OUT3_5_LUTOUT22(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STG2_5X6_OUT3_5_LUTOUT22)
+#define BP_PXP_WFE_B_STG2_5X6_OUT3_5_RSVD2 14
+#define BM_PXP_WFE_B_STG2_5X6_OUT3_5_RSVD2 0x0000C000
+#define BF_PXP_WFE_B_STG2_5X6_OUT3_5_RSVD2(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STG2_5X6_OUT3_5_RSVD2)
+#define BP_PXP_WFE_B_STG2_5X6_OUT3_5_LUTOUT21 8
+#define BM_PXP_WFE_B_STG2_5X6_OUT3_5_LUTOUT21 0x00003F00
+#define BF_PXP_WFE_B_STG2_5X6_OUT3_5_LUTOUT21(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STG2_5X6_OUT3_5_LUTOUT21)
+#define BP_PXP_WFE_B_STG2_5X6_OUT3_5_RSVD3 6
+#define BM_PXP_WFE_B_STG2_5X6_OUT3_5_RSVD3 0x000000C0
+#define BF_PXP_WFE_B_STG2_5X6_OUT3_5_RSVD3(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STG2_5X6_OUT3_5_RSVD3)
+#define BP_PXP_WFE_B_STG2_5X6_OUT3_5_LUTOUT20 0
+#define BM_PXP_WFE_B_STG2_5X6_OUT3_5_LUTOUT20 0x0000003F
+#define BF_PXP_WFE_B_STG2_5X6_OUT3_5_LUTOUT20(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STG2_5X6_OUT3_5_LUTOUT20)
+
+#define HW_PXP_WFE_B_STG2_5X6_OUT3_6 (0x00002500)
+
+#define BP_PXP_WFE_B_STG2_5X6_OUT3_6_RSVD0 30
+#define BM_PXP_WFE_B_STG2_5X6_OUT3_6_RSVD0 0xC0000000
+#define BF_PXP_WFE_B_STG2_5X6_OUT3_6_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STG2_5X6_OUT3_6_RSVD0)
+#define BP_PXP_WFE_B_STG2_5X6_OUT3_6_LUTOUT27 24
+#define BM_PXP_WFE_B_STG2_5X6_OUT3_6_LUTOUT27 0x3F000000
+#define BF_PXP_WFE_B_STG2_5X6_OUT3_6_LUTOUT27(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STG2_5X6_OUT3_6_LUTOUT27)
+#define BP_PXP_WFE_B_STG2_5X6_OUT3_6_RSVD1 22
+#define BM_PXP_WFE_B_STG2_5X6_OUT3_6_RSVD1 0x00C00000
+#define BF_PXP_WFE_B_STG2_5X6_OUT3_6_RSVD1(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STG2_5X6_OUT3_6_RSVD1)
+#define BP_PXP_WFE_B_STG2_5X6_OUT3_6_LUTOUT26 16
+#define BM_PXP_WFE_B_STG2_5X6_OUT3_6_LUTOUT26 0x003F0000
+#define BF_PXP_WFE_B_STG2_5X6_OUT3_6_LUTOUT26(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STG2_5X6_OUT3_6_LUTOUT26)
+#define BP_PXP_WFE_B_STG2_5X6_OUT3_6_RSVD2 14
+#define BM_PXP_WFE_B_STG2_5X6_OUT3_6_RSVD2 0x0000C000
+#define BF_PXP_WFE_B_STG2_5X6_OUT3_6_RSVD2(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STG2_5X6_OUT3_6_RSVD2)
+#define BP_PXP_WFE_B_STG2_5X6_OUT3_6_LUTOUT25 8
+#define BM_PXP_WFE_B_STG2_5X6_OUT3_6_LUTOUT25 0x00003F00
+#define BF_PXP_WFE_B_STG2_5X6_OUT3_6_LUTOUT25(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STG2_5X6_OUT3_6_LUTOUT25)
+#define BP_PXP_WFE_B_STG2_5X6_OUT3_6_RSVD3 6
+#define BM_PXP_WFE_B_STG2_5X6_OUT3_6_RSVD3 0x000000C0
+#define BF_PXP_WFE_B_STG2_5X6_OUT3_6_RSVD3(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STG2_5X6_OUT3_6_RSVD3)
+#define BP_PXP_WFE_B_STG2_5X6_OUT3_6_LUTOUT24 0
+#define BM_PXP_WFE_B_STG2_5X6_OUT3_6_LUTOUT24 0x0000003F
+#define BF_PXP_WFE_B_STG2_5X6_OUT3_6_LUTOUT24(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STG2_5X6_OUT3_6_LUTOUT24)
+
+#define HW_PXP_WFE_B_STG2_5X6_OUT3_7 (0x00002510)
+
+#define BP_PXP_WFE_B_STG2_5X6_OUT3_7_RSVD0 30
+#define BM_PXP_WFE_B_STG2_5X6_OUT3_7_RSVD0 0xC0000000
+#define BF_PXP_WFE_B_STG2_5X6_OUT3_7_RSVD0(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STG2_5X6_OUT3_7_RSVD0)
+#define BP_PXP_WFE_B_STG2_5X6_OUT3_7_LUTOUT31 24
+#define BM_PXP_WFE_B_STG2_5X6_OUT3_7_LUTOUT31 0x3F000000
+#define BF_PXP_WFE_B_STG2_5X6_OUT3_7_LUTOUT31(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STG2_5X6_OUT3_7_LUTOUT31)
+#define BP_PXP_WFE_B_STG2_5X6_OUT3_7_RSVD1 22
+#define BM_PXP_WFE_B_STG2_5X6_OUT3_7_RSVD1 0x00C00000
+#define BF_PXP_WFE_B_STG2_5X6_OUT3_7_RSVD1(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STG2_5X6_OUT3_7_RSVD1)
+#define BP_PXP_WFE_B_STG2_5X6_OUT3_7_LUTOUT30 16
+#define BM_PXP_WFE_B_STG2_5X6_OUT3_7_LUTOUT30 0x003F0000
+#define BF_PXP_WFE_B_STG2_5X6_OUT3_7_LUTOUT30(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STG2_5X6_OUT3_7_LUTOUT30)
+#define BP_PXP_WFE_B_STG2_5X6_OUT3_7_RSVD2 14
+#define BM_PXP_WFE_B_STG2_5X6_OUT3_7_RSVD2 0x0000C000
+#define BF_PXP_WFE_B_STG2_5X6_OUT3_7_RSVD2(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STG2_5X6_OUT3_7_RSVD2)
+#define BP_PXP_WFE_B_STG2_5X6_OUT3_7_LUTOUT29 8
+#define BM_PXP_WFE_B_STG2_5X6_OUT3_7_LUTOUT29 0x00003F00
+#define BF_PXP_WFE_B_STG2_5X6_OUT3_7_LUTOUT29(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STG2_5X6_OUT3_7_LUTOUT29)
+#define BP_PXP_WFE_B_STG2_5X6_OUT3_7_RSVD3 6
+#define BM_PXP_WFE_B_STG2_5X6_OUT3_7_RSVD3 0x000000C0
+#define BF_PXP_WFE_B_STG2_5X6_OUT3_7_RSVD3(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STG2_5X6_OUT3_7_RSVD3)
+#define BP_PXP_WFE_B_STG2_5X6_OUT3_7_LUTOUT28 0
+#define BM_PXP_WFE_B_STG2_5X6_OUT3_7_LUTOUT28 0x0000003F
+#define BF_PXP_WFE_B_STG2_5X6_OUT3_7_LUTOUT28(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STG2_5X6_OUT3_7_LUTOUT28)
+
+#define HW_PXP_WFE_B_STAGE2_5X6_MASKS_0 (0x00002520)
+
+#define BP_PXP_WFE_B_STAGE2_5X6_MASKS_0_RSVD3 29
+#define BM_PXP_WFE_B_STAGE2_5X6_MASKS_0_RSVD3 0xE0000000
+#define BF_PXP_WFE_B_STAGE2_5X6_MASKS_0_RSVD3(v) \
+ (((v) << 29) & BM_PXP_WFE_B_STAGE2_5X6_MASKS_0_RSVD3)
+#define BP_PXP_WFE_B_STAGE2_5X6_MASKS_0_MASK3 24
+#define BM_PXP_WFE_B_STAGE2_5X6_MASKS_0_MASK3 0x1F000000
+#define BF_PXP_WFE_B_STAGE2_5X6_MASKS_0_MASK3(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STAGE2_5X6_MASKS_0_MASK3)
+#define BP_PXP_WFE_B_STAGE2_5X6_MASKS_0_RSVD2 21
+#define BM_PXP_WFE_B_STAGE2_5X6_MASKS_0_RSVD2 0x00E00000
+#define BF_PXP_WFE_B_STAGE2_5X6_MASKS_0_RSVD2(v) \
+ (((v) << 21) & BM_PXP_WFE_B_STAGE2_5X6_MASKS_0_RSVD2)
+#define BP_PXP_WFE_B_STAGE2_5X6_MASKS_0_MASK2 16
+#define BM_PXP_WFE_B_STAGE2_5X6_MASKS_0_MASK2 0x001F0000
+#define BF_PXP_WFE_B_STAGE2_5X6_MASKS_0_MASK2(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STAGE2_5X6_MASKS_0_MASK2)
+#define BP_PXP_WFE_B_STAGE2_5X6_MASKS_0_RSVD1 13
+#define BM_PXP_WFE_B_STAGE2_5X6_MASKS_0_RSVD1 0x0000E000
+#define BF_PXP_WFE_B_STAGE2_5X6_MASKS_0_RSVD1(v) \
+ (((v) << 13) & BM_PXP_WFE_B_STAGE2_5X6_MASKS_0_RSVD1)
+#define BP_PXP_WFE_B_STAGE2_5X6_MASKS_0_MASK1 8
+#define BM_PXP_WFE_B_STAGE2_5X6_MASKS_0_MASK1 0x00001F00
+#define BF_PXP_WFE_B_STAGE2_5X6_MASKS_0_MASK1(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STAGE2_5X6_MASKS_0_MASK1)
+#define BP_PXP_WFE_B_STAGE2_5X6_MASKS_0_RSVD0 5
+#define BM_PXP_WFE_B_STAGE2_5X6_MASKS_0_RSVD0 0x000000E0
+#define BF_PXP_WFE_B_STAGE2_5X6_MASKS_0_RSVD0(v) \
+ (((v) << 5) & BM_PXP_WFE_B_STAGE2_5X6_MASKS_0_RSVD0)
+#define BP_PXP_WFE_B_STAGE2_5X6_MASKS_0_MASK0 0
+#define BM_PXP_WFE_B_STAGE2_5X6_MASKS_0_MASK0 0x0000001F
+#define BF_PXP_WFE_B_STAGE2_5X6_MASKS_0_MASK0(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STAGE2_5X6_MASKS_0_MASK0)
+
+#define HW_PXP_WFE_B_STAGE2_5X6_ADDR_0 (0x00002530)
+
+#define BP_PXP_WFE_B_STAGE2_5X6_ADDR_0_RSVD3 30
+#define BM_PXP_WFE_B_STAGE2_5X6_ADDR_0_RSVD3 0xC0000000
+#define BF_PXP_WFE_B_STAGE2_5X6_ADDR_0_RSVD3(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STAGE2_5X6_ADDR_0_RSVD3)
+#define BP_PXP_WFE_B_STAGE2_5X6_ADDR_0_MUXADDR3 24
+#define BM_PXP_WFE_B_STAGE2_5X6_ADDR_0_MUXADDR3 0x3F000000
+#define BF_PXP_WFE_B_STAGE2_5X6_ADDR_0_MUXADDR3(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STAGE2_5X6_ADDR_0_MUXADDR3)
+#define BP_PXP_WFE_B_STAGE2_5X6_ADDR_0_RSVD2 22
+#define BM_PXP_WFE_B_STAGE2_5X6_ADDR_0_RSVD2 0x00C00000
+#define BF_PXP_WFE_B_STAGE2_5X6_ADDR_0_RSVD2(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STAGE2_5X6_ADDR_0_RSVD2)
+#define BP_PXP_WFE_B_STAGE2_5X6_ADDR_0_MUXADDR2 16
+#define BM_PXP_WFE_B_STAGE2_5X6_ADDR_0_MUXADDR2 0x003F0000
+#define BF_PXP_WFE_B_STAGE2_5X6_ADDR_0_MUXADDR2(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STAGE2_5X6_ADDR_0_MUXADDR2)
+#define BP_PXP_WFE_B_STAGE2_5X6_ADDR_0_RSVD1 14
+#define BM_PXP_WFE_B_STAGE2_5X6_ADDR_0_RSVD1 0x0000C000
+#define BF_PXP_WFE_B_STAGE2_5X6_ADDR_0_RSVD1(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STAGE2_5X6_ADDR_0_RSVD1)
+#define BP_PXP_WFE_B_STAGE2_5X6_ADDR_0_MUXADDR1 8
+#define BM_PXP_WFE_B_STAGE2_5X6_ADDR_0_MUXADDR1 0x00003F00
+#define BF_PXP_WFE_B_STAGE2_5X6_ADDR_0_MUXADDR1(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STAGE2_5X6_ADDR_0_MUXADDR1)
+#define BP_PXP_WFE_B_STAGE2_5X6_ADDR_0_RSVD0 6
+#define BM_PXP_WFE_B_STAGE2_5X6_ADDR_0_RSVD0 0x000000C0
+#define BF_PXP_WFE_B_STAGE2_5X6_ADDR_0_RSVD0(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STAGE2_5X6_ADDR_0_RSVD0)
+#define BP_PXP_WFE_B_STAGE2_5X6_ADDR_0_MUXADDR0 0
+#define BM_PXP_WFE_B_STAGE2_5X6_ADDR_0_MUXADDR0 0x0000003F
+#define BF_PXP_WFE_B_STAGE2_5X6_ADDR_0_MUXADDR0(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STAGE2_5X6_ADDR_0_MUXADDR0)
+
+#define HW_PXP_WFE_B_STG2_5X1_OUT0 (0x00002540)
+
+#define BM_PXP_WFE_B_STG2_5X1_OUT0_LUTOUT31 0x80000000
+#define BF_PXP_WFE_B_STG2_5X1_OUT0_LUTOUT31(v) \
+ (((v) << 31) & BM_PXP_WFE_B_STG2_5X1_OUT0_LUTOUT31)
+#define BM_PXP_WFE_B_STG2_5X1_OUT0_LUTOUT30 0x40000000
+#define BF_PXP_WFE_B_STG2_5X1_OUT0_LUTOUT30(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STG2_5X1_OUT0_LUTOUT30)
+#define BM_PXP_WFE_B_STG2_5X1_OUT0_LUTOUT29 0x20000000
+#define BF_PXP_WFE_B_STG2_5X1_OUT0_LUTOUT29(v) \
+ (((v) << 29) & BM_PXP_WFE_B_STG2_5X1_OUT0_LUTOUT29)
+#define BM_PXP_WFE_B_STG2_5X1_OUT0_LUTOUT28 0x10000000
+#define BF_PXP_WFE_B_STG2_5X1_OUT0_LUTOUT28(v) \
+ (((v) << 28) & BM_PXP_WFE_B_STG2_5X1_OUT0_LUTOUT28)
+#define BM_PXP_WFE_B_STG2_5X1_OUT0_LUTOUT27 0x08000000
+#define BF_PXP_WFE_B_STG2_5X1_OUT0_LUTOUT27(v) \
+ (((v) << 27) & BM_PXP_WFE_B_STG2_5X1_OUT0_LUTOUT27)
+#define BM_PXP_WFE_B_STG2_5X1_OUT0_LUTOUT26 0x04000000
+#define BF_PXP_WFE_B_STG2_5X1_OUT0_LUTOUT26(v) \
+ (((v) << 26) & BM_PXP_WFE_B_STG2_5X1_OUT0_LUTOUT26)
+#define BM_PXP_WFE_B_STG2_5X1_OUT0_LUTOUT25 0x02000000
+#define BF_PXP_WFE_B_STG2_5X1_OUT0_LUTOUT25(v) \
+ (((v) << 25) & BM_PXP_WFE_B_STG2_5X1_OUT0_LUTOUT25)
+#define BM_PXP_WFE_B_STG2_5X1_OUT0_LUTOUT24 0x01000000
+#define BF_PXP_WFE_B_STG2_5X1_OUT0_LUTOUT24(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STG2_5X1_OUT0_LUTOUT24)
+#define BM_PXP_WFE_B_STG2_5X1_OUT0_LUTOUT23 0x00800000
+#define BF_PXP_WFE_B_STG2_5X1_OUT0_LUTOUT23(v) \
+ (((v) << 23) & BM_PXP_WFE_B_STG2_5X1_OUT0_LUTOUT23)
+#define BM_PXP_WFE_B_STG2_5X1_OUT0_LUTOUT22 0x00400000
+#define BF_PXP_WFE_B_STG2_5X1_OUT0_LUTOUT22(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STG2_5X1_OUT0_LUTOUT22)
+#define BM_PXP_WFE_B_STG2_5X1_OUT0_LUTOUT21 0x00200000
+#define BF_PXP_WFE_B_STG2_5X1_OUT0_LUTOUT21(v) \
+ (((v) << 21) & BM_PXP_WFE_B_STG2_5X1_OUT0_LUTOUT21)
+#define BM_PXP_WFE_B_STG2_5X1_OUT0_LUTOUT20 0x00100000
+#define BF_PXP_WFE_B_STG2_5X1_OUT0_LUTOUT20(v) \
+ (((v) << 20) & BM_PXP_WFE_B_STG2_5X1_OUT0_LUTOUT20)
+#define BM_PXP_WFE_B_STG2_5X1_OUT0_LUTOUT19 0x00080000
+#define BF_PXP_WFE_B_STG2_5X1_OUT0_LUTOUT19(v) \
+ (((v) << 19) & BM_PXP_WFE_B_STG2_5X1_OUT0_LUTOUT19)
+#define BM_PXP_WFE_B_STG2_5X1_OUT0_LUTOUT18 0x00040000
+#define BF_PXP_WFE_B_STG2_5X1_OUT0_LUTOUT18(v) \
+ (((v) << 18) & BM_PXP_WFE_B_STG2_5X1_OUT0_LUTOUT18)
+#define BM_PXP_WFE_B_STG2_5X1_OUT0_LUTOUT17 0x00020000
+#define BF_PXP_WFE_B_STG2_5X1_OUT0_LUTOUT17(v) \
+ (((v) << 17) & BM_PXP_WFE_B_STG2_5X1_OUT0_LUTOUT17)
+#define BM_PXP_WFE_B_STG2_5X1_OUT0_LUTOUT16 0x00010000
+#define BF_PXP_WFE_B_STG2_5X1_OUT0_LUTOUT16(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STG2_5X1_OUT0_LUTOUT16)
+#define BM_PXP_WFE_B_STG2_5X1_OUT0_LUTOUT15 0x00008000
+#define BF_PXP_WFE_B_STG2_5X1_OUT0_LUTOUT15(v) \
+ (((v) << 15) & BM_PXP_WFE_B_STG2_5X1_OUT0_LUTOUT15)
+#define BM_PXP_WFE_B_STG2_5X1_OUT0_LUTOUT14 0x00004000
+#define BF_PXP_WFE_B_STG2_5X1_OUT0_LUTOUT14(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STG2_5X1_OUT0_LUTOUT14)
+#define BM_PXP_WFE_B_STG2_5X1_OUT0_LUTOUT13 0x00002000
+#define BF_PXP_WFE_B_STG2_5X1_OUT0_LUTOUT13(v) \
+ (((v) << 13) & BM_PXP_WFE_B_STG2_5X1_OUT0_LUTOUT13)
+#define BM_PXP_WFE_B_STG2_5X1_OUT0_LUTOUT12 0x00001000
+#define BF_PXP_WFE_B_STG2_5X1_OUT0_LUTOUT12(v) \
+ (((v) << 12) & BM_PXP_WFE_B_STG2_5X1_OUT0_LUTOUT12)
+#define BM_PXP_WFE_B_STG2_5X1_OUT0_LUTOUT11 0x00000800
+#define BF_PXP_WFE_B_STG2_5X1_OUT0_LUTOUT11(v) \
+ (((v) << 11) & BM_PXP_WFE_B_STG2_5X1_OUT0_LUTOUT11)
+#define BM_PXP_WFE_B_STG2_5X1_OUT0_LUTOUT10 0x00000400
+#define BF_PXP_WFE_B_STG2_5X1_OUT0_LUTOUT10(v) \
+ (((v) << 10) & BM_PXP_WFE_B_STG2_5X1_OUT0_LUTOUT10)
+#define BM_PXP_WFE_B_STG2_5X1_OUT0_LUTOUT9 0x00000200
+#define BF_PXP_WFE_B_STG2_5X1_OUT0_LUTOUT9(v) \
+ (((v) << 9) & BM_PXP_WFE_B_STG2_5X1_OUT0_LUTOUT9)
+#define BM_PXP_WFE_B_STG2_5X1_OUT0_LUTOUT8 0x00000100
+#define BF_PXP_WFE_B_STG2_5X1_OUT0_LUTOUT8(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STG2_5X1_OUT0_LUTOUT8)
+#define BM_PXP_WFE_B_STG2_5X1_OUT0_LUTOUT7 0x00000080
+#define BF_PXP_WFE_B_STG2_5X1_OUT0_LUTOUT7(v) \
+ (((v) << 7) & BM_PXP_WFE_B_STG2_5X1_OUT0_LUTOUT7)
+#define BM_PXP_WFE_B_STG2_5X1_OUT0_LUTOUT6 0x00000040
+#define BF_PXP_WFE_B_STG2_5X1_OUT0_LUTOUT6(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STG2_5X1_OUT0_LUTOUT6)
+#define BM_PXP_WFE_B_STG2_5X1_OUT0_LUTOUT5 0x00000020
+#define BF_PXP_WFE_B_STG2_5X1_OUT0_LUTOUT5(v) \
+ (((v) << 5) & BM_PXP_WFE_B_STG2_5X1_OUT0_LUTOUT5)
+#define BM_PXP_WFE_B_STG2_5X1_OUT0_LUTOUT4 0x00000010
+#define BF_PXP_WFE_B_STG2_5X1_OUT0_LUTOUT4(v) \
+ (((v) << 4) & BM_PXP_WFE_B_STG2_5X1_OUT0_LUTOUT4)
+#define BM_PXP_WFE_B_STG2_5X1_OUT0_LUTOUT3 0x00000008
+#define BF_PXP_WFE_B_STG2_5X1_OUT0_LUTOUT3(v) \
+ (((v) << 3) & BM_PXP_WFE_B_STG2_5X1_OUT0_LUTOUT3)
+#define BM_PXP_WFE_B_STG2_5X1_OUT0_LUTOUT2 0x00000004
+#define BF_PXP_WFE_B_STG2_5X1_OUT0_LUTOUT2(v) \
+ (((v) << 2) & BM_PXP_WFE_B_STG2_5X1_OUT0_LUTOUT2)
+#define BM_PXP_WFE_B_STG2_5X1_OUT0_LUTOUT1 0x00000002
+#define BF_PXP_WFE_B_STG2_5X1_OUT0_LUTOUT1(v) \
+ (((v) << 1) & BM_PXP_WFE_B_STG2_5X1_OUT0_LUTOUT1)
+#define BM_PXP_WFE_B_STG2_5X1_OUT0_LUTOUT0 0x00000001
+#define BF_PXP_WFE_B_STG2_5X1_OUT0_LUTOUT0(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STG2_5X1_OUT0_LUTOUT0)
+
+#define HW_PXP_WFE_B_STG2_5X1_OUT1 (0x00002550)
+
+#define BM_PXP_WFE_B_STG2_5X1_OUT1_LUTOUT31 0x80000000
+#define BF_PXP_WFE_B_STG2_5X1_OUT1_LUTOUT31(v) \
+ (((v) << 31) & BM_PXP_WFE_B_STG2_5X1_OUT1_LUTOUT31)
+#define BM_PXP_WFE_B_STG2_5X1_OUT1_LUTOUT30 0x40000000
+#define BF_PXP_WFE_B_STG2_5X1_OUT1_LUTOUT30(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STG2_5X1_OUT1_LUTOUT30)
+#define BM_PXP_WFE_B_STG2_5X1_OUT1_LUTOUT29 0x20000000
+#define BF_PXP_WFE_B_STG2_5X1_OUT1_LUTOUT29(v) \
+ (((v) << 29) & BM_PXP_WFE_B_STG2_5X1_OUT1_LUTOUT29)
+#define BM_PXP_WFE_B_STG2_5X1_OUT1_LUTOUT28 0x10000000
+#define BF_PXP_WFE_B_STG2_5X1_OUT1_LUTOUT28(v) \
+ (((v) << 28) & BM_PXP_WFE_B_STG2_5X1_OUT1_LUTOUT28)
+#define BM_PXP_WFE_B_STG2_5X1_OUT1_LUTOUT27 0x08000000
+#define BF_PXP_WFE_B_STG2_5X1_OUT1_LUTOUT27(v) \
+ (((v) << 27) & BM_PXP_WFE_B_STG2_5X1_OUT1_LUTOUT27)
+#define BM_PXP_WFE_B_STG2_5X1_OUT1_LUTOUT26 0x04000000
+#define BF_PXP_WFE_B_STG2_5X1_OUT1_LUTOUT26(v) \
+ (((v) << 26) & BM_PXP_WFE_B_STG2_5X1_OUT1_LUTOUT26)
+#define BM_PXP_WFE_B_STG2_5X1_OUT1_LUTOUT25 0x02000000
+#define BF_PXP_WFE_B_STG2_5X1_OUT1_LUTOUT25(v) \
+ (((v) << 25) & BM_PXP_WFE_B_STG2_5X1_OUT1_LUTOUT25)
+#define BM_PXP_WFE_B_STG2_5X1_OUT1_LUTOUT24 0x01000000
+#define BF_PXP_WFE_B_STG2_5X1_OUT1_LUTOUT24(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STG2_5X1_OUT1_LUTOUT24)
+#define BM_PXP_WFE_B_STG2_5X1_OUT1_LUTOUT23 0x00800000
+#define BF_PXP_WFE_B_STG2_5X1_OUT1_LUTOUT23(v) \
+ (((v) << 23) & BM_PXP_WFE_B_STG2_5X1_OUT1_LUTOUT23)
+#define BM_PXP_WFE_B_STG2_5X1_OUT1_LUTOUT22 0x00400000
+#define BF_PXP_WFE_B_STG2_5X1_OUT1_LUTOUT22(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STG2_5X1_OUT1_LUTOUT22)
+#define BM_PXP_WFE_B_STG2_5X1_OUT1_LUTOUT21 0x00200000
+#define BF_PXP_WFE_B_STG2_5X1_OUT1_LUTOUT21(v) \
+ (((v) << 21) & BM_PXP_WFE_B_STG2_5X1_OUT1_LUTOUT21)
+#define BM_PXP_WFE_B_STG2_5X1_OUT1_LUTOUT20 0x00100000
+#define BF_PXP_WFE_B_STG2_5X1_OUT1_LUTOUT20(v) \
+ (((v) << 20) & BM_PXP_WFE_B_STG2_5X1_OUT1_LUTOUT20)
+#define BM_PXP_WFE_B_STG2_5X1_OUT1_LUTOUT19 0x00080000
+#define BF_PXP_WFE_B_STG2_5X1_OUT1_LUTOUT19(v) \
+ (((v) << 19) & BM_PXP_WFE_B_STG2_5X1_OUT1_LUTOUT19)
+#define BM_PXP_WFE_B_STG2_5X1_OUT1_LUTOUT18 0x00040000
+#define BF_PXP_WFE_B_STG2_5X1_OUT1_LUTOUT18(v) \
+ (((v) << 18) & BM_PXP_WFE_B_STG2_5X1_OUT1_LUTOUT18)
+#define BM_PXP_WFE_B_STG2_5X1_OUT1_LUTOUT17 0x00020000
+#define BF_PXP_WFE_B_STG2_5X1_OUT1_LUTOUT17(v) \
+ (((v) << 17) & BM_PXP_WFE_B_STG2_5X1_OUT1_LUTOUT17)
+#define BM_PXP_WFE_B_STG2_5X1_OUT1_LUTOUT16 0x00010000
+#define BF_PXP_WFE_B_STG2_5X1_OUT1_LUTOUT16(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STG2_5X1_OUT1_LUTOUT16)
+#define BM_PXP_WFE_B_STG2_5X1_OUT1_LUTOUT15 0x00008000
+#define BF_PXP_WFE_B_STG2_5X1_OUT1_LUTOUT15(v) \
+ (((v) << 15) & BM_PXP_WFE_B_STG2_5X1_OUT1_LUTOUT15)
+#define BM_PXP_WFE_B_STG2_5X1_OUT1_LUTOUT14 0x00004000
+#define BF_PXP_WFE_B_STG2_5X1_OUT1_LUTOUT14(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STG2_5X1_OUT1_LUTOUT14)
+#define BM_PXP_WFE_B_STG2_5X1_OUT1_LUTOUT13 0x00002000
+#define BF_PXP_WFE_B_STG2_5X1_OUT1_LUTOUT13(v) \
+ (((v) << 13) & BM_PXP_WFE_B_STG2_5X1_OUT1_LUTOUT13)
+#define BM_PXP_WFE_B_STG2_5X1_OUT1_LUTOUT12 0x00001000
+#define BF_PXP_WFE_B_STG2_5X1_OUT1_LUTOUT12(v) \
+ (((v) << 12) & BM_PXP_WFE_B_STG2_5X1_OUT1_LUTOUT12)
+#define BM_PXP_WFE_B_STG2_5X1_OUT1_LUTOUT11 0x00000800
+#define BF_PXP_WFE_B_STG2_5X1_OUT1_LUTOUT11(v) \
+ (((v) << 11) & BM_PXP_WFE_B_STG2_5X1_OUT1_LUTOUT11)
+#define BM_PXP_WFE_B_STG2_5X1_OUT1_LUTOUT10 0x00000400
+#define BF_PXP_WFE_B_STG2_5X1_OUT1_LUTOUT10(v) \
+ (((v) << 10) & BM_PXP_WFE_B_STG2_5X1_OUT1_LUTOUT10)
+#define BM_PXP_WFE_B_STG2_5X1_OUT1_LUTOUT9 0x00000200
+#define BF_PXP_WFE_B_STG2_5X1_OUT1_LUTOUT9(v) \
+ (((v) << 9) & BM_PXP_WFE_B_STG2_5X1_OUT1_LUTOUT9)
+#define BM_PXP_WFE_B_STG2_5X1_OUT1_LUTOUT8 0x00000100
+#define BF_PXP_WFE_B_STG2_5X1_OUT1_LUTOUT8(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STG2_5X1_OUT1_LUTOUT8)
+#define BM_PXP_WFE_B_STG2_5X1_OUT1_LUTOUT7 0x00000080
+#define BF_PXP_WFE_B_STG2_5X1_OUT1_LUTOUT7(v) \
+ (((v) << 7) & BM_PXP_WFE_B_STG2_5X1_OUT1_LUTOUT7)
+#define BM_PXP_WFE_B_STG2_5X1_OUT1_LUTOUT6 0x00000040
+#define BF_PXP_WFE_B_STG2_5X1_OUT1_LUTOUT6(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STG2_5X1_OUT1_LUTOUT6)
+#define BM_PXP_WFE_B_STG2_5X1_OUT1_LUTOUT5 0x00000020
+#define BF_PXP_WFE_B_STG2_5X1_OUT1_LUTOUT5(v) \
+ (((v) << 5) & BM_PXP_WFE_B_STG2_5X1_OUT1_LUTOUT5)
+#define BM_PXP_WFE_B_STG2_5X1_OUT1_LUTOUT4 0x00000010
+#define BF_PXP_WFE_B_STG2_5X1_OUT1_LUTOUT4(v) \
+ (((v) << 4) & BM_PXP_WFE_B_STG2_5X1_OUT1_LUTOUT4)
+#define BM_PXP_WFE_B_STG2_5X1_OUT1_LUTOUT3 0x00000008
+#define BF_PXP_WFE_B_STG2_5X1_OUT1_LUTOUT3(v) \
+ (((v) << 3) & BM_PXP_WFE_B_STG2_5X1_OUT1_LUTOUT3)
+#define BM_PXP_WFE_B_STG2_5X1_OUT1_LUTOUT2 0x00000004
+#define BF_PXP_WFE_B_STG2_5X1_OUT1_LUTOUT2(v) \
+ (((v) << 2) & BM_PXP_WFE_B_STG2_5X1_OUT1_LUTOUT2)
+#define BM_PXP_WFE_B_STG2_5X1_OUT1_LUTOUT1 0x00000002
+#define BF_PXP_WFE_B_STG2_5X1_OUT1_LUTOUT1(v) \
+ (((v) << 1) & BM_PXP_WFE_B_STG2_5X1_OUT1_LUTOUT1)
+#define BM_PXP_WFE_B_STG2_5X1_OUT1_LUTOUT0 0x00000001
+#define BF_PXP_WFE_B_STG2_5X1_OUT1_LUTOUT0(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STG2_5X1_OUT1_LUTOUT0)
+
+#define HW_PXP_WFE_B_STG2_5X1_OUT2 (0x00002560)
+
+#define BM_PXP_WFE_B_STG2_5X1_OUT2_LUTOUT31 0x80000000
+#define BF_PXP_WFE_B_STG2_5X1_OUT2_LUTOUT31(v) \
+ (((v) << 31) & BM_PXP_WFE_B_STG2_5X1_OUT2_LUTOUT31)
+#define BM_PXP_WFE_B_STG2_5X1_OUT2_LUTOUT30 0x40000000
+#define BF_PXP_WFE_B_STG2_5X1_OUT2_LUTOUT30(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STG2_5X1_OUT2_LUTOUT30)
+#define BM_PXP_WFE_B_STG2_5X1_OUT2_LUTOUT29 0x20000000
+#define BF_PXP_WFE_B_STG2_5X1_OUT2_LUTOUT29(v) \
+ (((v) << 29) & BM_PXP_WFE_B_STG2_5X1_OUT2_LUTOUT29)
+#define BM_PXP_WFE_B_STG2_5X1_OUT2_LUTOUT28 0x10000000
+#define BF_PXP_WFE_B_STG2_5X1_OUT2_LUTOUT28(v) \
+ (((v) << 28) & BM_PXP_WFE_B_STG2_5X1_OUT2_LUTOUT28)
+#define BM_PXP_WFE_B_STG2_5X1_OUT2_LUTOUT27 0x08000000
+#define BF_PXP_WFE_B_STG2_5X1_OUT2_LUTOUT27(v) \
+ (((v) << 27) & BM_PXP_WFE_B_STG2_5X1_OUT2_LUTOUT27)
+#define BM_PXP_WFE_B_STG2_5X1_OUT2_LUTOUT26 0x04000000
+#define BF_PXP_WFE_B_STG2_5X1_OUT2_LUTOUT26(v) \
+ (((v) << 26) & BM_PXP_WFE_B_STG2_5X1_OUT2_LUTOUT26)
+#define BM_PXP_WFE_B_STG2_5X1_OUT2_LUTOUT25 0x02000000
+#define BF_PXP_WFE_B_STG2_5X1_OUT2_LUTOUT25(v) \
+ (((v) << 25) & BM_PXP_WFE_B_STG2_5X1_OUT2_LUTOUT25)
+#define BM_PXP_WFE_B_STG2_5X1_OUT2_LUTOUT24 0x01000000
+#define BF_PXP_WFE_B_STG2_5X1_OUT2_LUTOUT24(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STG2_5X1_OUT2_LUTOUT24)
+#define BM_PXP_WFE_B_STG2_5X1_OUT2_LUTOUT23 0x00800000
+#define BF_PXP_WFE_B_STG2_5X1_OUT2_LUTOUT23(v) \
+ (((v) << 23) & BM_PXP_WFE_B_STG2_5X1_OUT2_LUTOUT23)
+#define BM_PXP_WFE_B_STG2_5X1_OUT2_LUTOUT22 0x00400000
+#define BF_PXP_WFE_B_STG2_5X1_OUT2_LUTOUT22(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STG2_5X1_OUT2_LUTOUT22)
+#define BM_PXP_WFE_B_STG2_5X1_OUT2_LUTOUT21 0x00200000
+#define BF_PXP_WFE_B_STG2_5X1_OUT2_LUTOUT21(v) \
+ (((v) << 21) & BM_PXP_WFE_B_STG2_5X1_OUT2_LUTOUT21)
+#define BM_PXP_WFE_B_STG2_5X1_OUT2_LUTOUT20 0x00100000
+#define BF_PXP_WFE_B_STG2_5X1_OUT2_LUTOUT20(v) \
+ (((v) << 20) & BM_PXP_WFE_B_STG2_5X1_OUT2_LUTOUT20)
+#define BM_PXP_WFE_B_STG2_5X1_OUT2_LUTOUT19 0x00080000
+#define BF_PXP_WFE_B_STG2_5X1_OUT2_LUTOUT19(v) \
+ (((v) << 19) & BM_PXP_WFE_B_STG2_5X1_OUT2_LUTOUT19)
+#define BM_PXP_WFE_B_STG2_5X1_OUT2_LUTOUT18 0x00040000
+#define BF_PXP_WFE_B_STG2_5X1_OUT2_LUTOUT18(v) \
+ (((v) << 18) & BM_PXP_WFE_B_STG2_5X1_OUT2_LUTOUT18)
+#define BM_PXP_WFE_B_STG2_5X1_OUT2_LUTOUT17 0x00020000
+#define BF_PXP_WFE_B_STG2_5X1_OUT2_LUTOUT17(v) \
+ (((v) << 17) & BM_PXP_WFE_B_STG2_5X1_OUT2_LUTOUT17)
+#define BM_PXP_WFE_B_STG2_5X1_OUT2_LUTOUT16 0x00010000
+#define BF_PXP_WFE_B_STG2_5X1_OUT2_LUTOUT16(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STG2_5X1_OUT2_LUTOUT16)
+#define BM_PXP_WFE_B_STG2_5X1_OUT2_LUTOUT15 0x00008000
+#define BF_PXP_WFE_B_STG2_5X1_OUT2_LUTOUT15(v) \
+ (((v) << 15) & BM_PXP_WFE_B_STG2_5X1_OUT2_LUTOUT15)
+#define BM_PXP_WFE_B_STG2_5X1_OUT2_LUTOUT14 0x00004000
+#define BF_PXP_WFE_B_STG2_5X1_OUT2_LUTOUT14(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STG2_5X1_OUT2_LUTOUT14)
+#define BM_PXP_WFE_B_STG2_5X1_OUT2_LUTOUT13 0x00002000
+#define BF_PXP_WFE_B_STG2_5X1_OUT2_LUTOUT13(v) \
+ (((v) << 13) & BM_PXP_WFE_B_STG2_5X1_OUT2_LUTOUT13)
+#define BM_PXP_WFE_B_STG2_5X1_OUT2_LUTOUT12 0x00001000
+#define BF_PXP_WFE_B_STG2_5X1_OUT2_LUTOUT12(v) \
+ (((v) << 12) & BM_PXP_WFE_B_STG2_5X1_OUT2_LUTOUT12)
+#define BM_PXP_WFE_B_STG2_5X1_OUT2_LUTOUT11 0x00000800
+#define BF_PXP_WFE_B_STG2_5X1_OUT2_LUTOUT11(v) \
+ (((v) << 11) & BM_PXP_WFE_B_STG2_5X1_OUT2_LUTOUT11)
+#define BM_PXP_WFE_B_STG2_5X1_OUT2_LUTOUT10 0x00000400
+#define BF_PXP_WFE_B_STG2_5X1_OUT2_LUTOUT10(v) \
+ (((v) << 10) & BM_PXP_WFE_B_STG2_5X1_OUT2_LUTOUT10)
+#define BM_PXP_WFE_B_STG2_5X1_OUT2_LUTOUT9 0x00000200
+#define BF_PXP_WFE_B_STG2_5X1_OUT2_LUTOUT9(v) \
+ (((v) << 9) & BM_PXP_WFE_B_STG2_5X1_OUT2_LUTOUT9)
+#define BM_PXP_WFE_B_STG2_5X1_OUT2_LUTOUT8 0x00000100
+#define BF_PXP_WFE_B_STG2_5X1_OUT2_LUTOUT8(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STG2_5X1_OUT2_LUTOUT8)
+#define BM_PXP_WFE_B_STG2_5X1_OUT2_LUTOUT7 0x00000080
+#define BF_PXP_WFE_B_STG2_5X1_OUT2_LUTOUT7(v) \
+ (((v) << 7) & BM_PXP_WFE_B_STG2_5X1_OUT2_LUTOUT7)
+#define BM_PXP_WFE_B_STG2_5X1_OUT2_LUTOUT6 0x00000040
+#define BF_PXP_WFE_B_STG2_5X1_OUT2_LUTOUT6(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STG2_5X1_OUT2_LUTOUT6)
+#define BM_PXP_WFE_B_STG2_5X1_OUT2_LUTOUT5 0x00000020
+#define BF_PXP_WFE_B_STG2_5X1_OUT2_LUTOUT5(v) \
+ (((v) << 5) & BM_PXP_WFE_B_STG2_5X1_OUT2_LUTOUT5)
+#define BM_PXP_WFE_B_STG2_5X1_OUT2_LUTOUT4 0x00000010
+#define BF_PXP_WFE_B_STG2_5X1_OUT2_LUTOUT4(v) \
+ (((v) << 4) & BM_PXP_WFE_B_STG2_5X1_OUT2_LUTOUT4)
+#define BM_PXP_WFE_B_STG2_5X1_OUT2_LUTOUT3 0x00000008
+#define BF_PXP_WFE_B_STG2_5X1_OUT2_LUTOUT3(v) \
+ (((v) << 3) & BM_PXP_WFE_B_STG2_5X1_OUT2_LUTOUT3)
+#define BM_PXP_WFE_B_STG2_5X1_OUT2_LUTOUT2 0x00000004
+#define BF_PXP_WFE_B_STG2_5X1_OUT2_LUTOUT2(v) \
+ (((v) << 2) & BM_PXP_WFE_B_STG2_5X1_OUT2_LUTOUT2)
+#define BM_PXP_WFE_B_STG2_5X1_OUT2_LUTOUT1 0x00000002
+#define BF_PXP_WFE_B_STG2_5X1_OUT2_LUTOUT1(v) \
+ (((v) << 1) & BM_PXP_WFE_B_STG2_5X1_OUT2_LUTOUT1)
+#define BM_PXP_WFE_B_STG2_5X1_OUT2_LUTOUT0 0x00000001
+#define BF_PXP_WFE_B_STG2_5X1_OUT2_LUTOUT0(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STG2_5X1_OUT2_LUTOUT0)
+
+#define HW_PXP_WFE_B_STG2_5X1_OUT3 (0x00002570)
+
+#define BM_PXP_WFE_B_STG2_5X1_OUT3_LUTOUT31 0x80000000
+#define BF_PXP_WFE_B_STG2_5X1_OUT3_LUTOUT31(v) \
+ (((v) << 31) & BM_PXP_WFE_B_STG2_5X1_OUT3_LUTOUT31)
+#define BM_PXP_WFE_B_STG2_5X1_OUT3_LUTOUT30 0x40000000
+#define BF_PXP_WFE_B_STG2_5X1_OUT3_LUTOUT30(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STG2_5X1_OUT3_LUTOUT30)
+#define BM_PXP_WFE_B_STG2_5X1_OUT3_LUTOUT29 0x20000000
+#define BF_PXP_WFE_B_STG2_5X1_OUT3_LUTOUT29(v) \
+ (((v) << 29) & BM_PXP_WFE_B_STG2_5X1_OUT3_LUTOUT29)
+#define BM_PXP_WFE_B_STG2_5X1_OUT3_LUTOUT28 0x10000000
+#define BF_PXP_WFE_B_STG2_5X1_OUT3_LUTOUT28(v) \
+ (((v) << 28) & BM_PXP_WFE_B_STG2_5X1_OUT3_LUTOUT28)
+#define BM_PXP_WFE_B_STG2_5X1_OUT3_LUTOUT27 0x08000000
+#define BF_PXP_WFE_B_STG2_5X1_OUT3_LUTOUT27(v) \
+ (((v) << 27) & BM_PXP_WFE_B_STG2_5X1_OUT3_LUTOUT27)
+#define BM_PXP_WFE_B_STG2_5X1_OUT3_LUTOUT26 0x04000000
+#define BF_PXP_WFE_B_STG2_5X1_OUT3_LUTOUT26(v) \
+ (((v) << 26) & BM_PXP_WFE_B_STG2_5X1_OUT3_LUTOUT26)
+#define BM_PXP_WFE_B_STG2_5X1_OUT3_LUTOUT25 0x02000000
+#define BF_PXP_WFE_B_STG2_5X1_OUT3_LUTOUT25(v) \
+ (((v) << 25) & BM_PXP_WFE_B_STG2_5X1_OUT3_LUTOUT25)
+#define BM_PXP_WFE_B_STG2_5X1_OUT3_LUTOUT24 0x01000000
+#define BF_PXP_WFE_B_STG2_5X1_OUT3_LUTOUT24(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STG2_5X1_OUT3_LUTOUT24)
+#define BM_PXP_WFE_B_STG2_5X1_OUT3_LUTOUT23 0x00800000
+#define BF_PXP_WFE_B_STG2_5X1_OUT3_LUTOUT23(v) \
+ (((v) << 23) & BM_PXP_WFE_B_STG2_5X1_OUT3_LUTOUT23)
+#define BM_PXP_WFE_B_STG2_5X1_OUT3_LUTOUT22 0x00400000
+#define BF_PXP_WFE_B_STG2_5X1_OUT3_LUTOUT22(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STG2_5X1_OUT3_LUTOUT22)
+#define BM_PXP_WFE_B_STG2_5X1_OUT3_LUTOUT21 0x00200000
+#define BF_PXP_WFE_B_STG2_5X1_OUT3_LUTOUT21(v) \
+ (((v) << 21) & BM_PXP_WFE_B_STG2_5X1_OUT3_LUTOUT21)
+#define BM_PXP_WFE_B_STG2_5X1_OUT3_LUTOUT20 0x00100000
+#define BF_PXP_WFE_B_STG2_5X1_OUT3_LUTOUT20(v) \
+ (((v) << 20) & BM_PXP_WFE_B_STG2_5X1_OUT3_LUTOUT20)
+#define BM_PXP_WFE_B_STG2_5X1_OUT3_LUTOUT19 0x00080000
+#define BF_PXP_WFE_B_STG2_5X1_OUT3_LUTOUT19(v) \
+ (((v) << 19) & BM_PXP_WFE_B_STG2_5X1_OUT3_LUTOUT19)
+#define BM_PXP_WFE_B_STG2_5X1_OUT3_LUTOUT18 0x00040000
+#define BF_PXP_WFE_B_STG2_5X1_OUT3_LUTOUT18(v) \
+ (((v) << 18) & BM_PXP_WFE_B_STG2_5X1_OUT3_LUTOUT18)
+#define BM_PXP_WFE_B_STG2_5X1_OUT3_LUTOUT17 0x00020000
+#define BF_PXP_WFE_B_STG2_5X1_OUT3_LUTOUT17(v) \
+ (((v) << 17) & BM_PXP_WFE_B_STG2_5X1_OUT3_LUTOUT17)
+#define BM_PXP_WFE_B_STG2_5X1_OUT3_LUTOUT16 0x00010000
+#define BF_PXP_WFE_B_STG2_5X1_OUT3_LUTOUT16(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STG2_5X1_OUT3_LUTOUT16)
+#define BM_PXP_WFE_B_STG2_5X1_OUT3_LUTOUT15 0x00008000
+#define BF_PXP_WFE_B_STG2_5X1_OUT3_LUTOUT15(v) \
+ (((v) << 15) & BM_PXP_WFE_B_STG2_5X1_OUT3_LUTOUT15)
+#define BM_PXP_WFE_B_STG2_5X1_OUT3_LUTOUT14 0x00004000
+#define BF_PXP_WFE_B_STG2_5X1_OUT3_LUTOUT14(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STG2_5X1_OUT3_LUTOUT14)
+#define BM_PXP_WFE_B_STG2_5X1_OUT3_LUTOUT13 0x00002000
+#define BF_PXP_WFE_B_STG2_5X1_OUT3_LUTOUT13(v) \
+ (((v) << 13) & BM_PXP_WFE_B_STG2_5X1_OUT3_LUTOUT13)
+#define BM_PXP_WFE_B_STG2_5X1_OUT3_LUTOUT12 0x00001000
+#define BF_PXP_WFE_B_STG2_5X1_OUT3_LUTOUT12(v) \
+ (((v) << 12) & BM_PXP_WFE_B_STG2_5X1_OUT3_LUTOUT12)
+#define BM_PXP_WFE_B_STG2_5X1_OUT3_LUTOUT11 0x00000800
+#define BF_PXP_WFE_B_STG2_5X1_OUT3_LUTOUT11(v) \
+ (((v) << 11) & BM_PXP_WFE_B_STG2_5X1_OUT3_LUTOUT11)
+#define BM_PXP_WFE_B_STG2_5X1_OUT3_LUTOUT10 0x00000400
+#define BF_PXP_WFE_B_STG2_5X1_OUT3_LUTOUT10(v) \
+ (((v) << 10) & BM_PXP_WFE_B_STG2_5X1_OUT3_LUTOUT10)
+#define BM_PXP_WFE_B_STG2_5X1_OUT3_LUTOUT9 0x00000200
+#define BF_PXP_WFE_B_STG2_5X1_OUT3_LUTOUT9(v) \
+ (((v) << 9) & BM_PXP_WFE_B_STG2_5X1_OUT3_LUTOUT9)
+#define BM_PXP_WFE_B_STG2_5X1_OUT3_LUTOUT8 0x00000100
+#define BF_PXP_WFE_B_STG2_5X1_OUT3_LUTOUT8(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STG2_5X1_OUT3_LUTOUT8)
+#define BM_PXP_WFE_B_STG2_5X1_OUT3_LUTOUT7 0x00000080
+#define BF_PXP_WFE_B_STG2_5X1_OUT3_LUTOUT7(v) \
+ (((v) << 7) & BM_PXP_WFE_B_STG2_5X1_OUT3_LUTOUT7)
+#define BM_PXP_WFE_B_STG2_5X1_OUT3_LUTOUT6 0x00000040
+#define BF_PXP_WFE_B_STG2_5X1_OUT3_LUTOUT6(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STG2_5X1_OUT3_LUTOUT6)
+#define BM_PXP_WFE_B_STG2_5X1_OUT3_LUTOUT5 0x00000020
+#define BF_PXP_WFE_B_STG2_5X1_OUT3_LUTOUT5(v) \
+ (((v) << 5) & BM_PXP_WFE_B_STG2_5X1_OUT3_LUTOUT5)
+#define BM_PXP_WFE_B_STG2_5X1_OUT3_LUTOUT4 0x00000010
+#define BF_PXP_WFE_B_STG2_5X1_OUT3_LUTOUT4(v) \
+ (((v) << 4) & BM_PXP_WFE_B_STG2_5X1_OUT3_LUTOUT4)
+#define BM_PXP_WFE_B_STG2_5X1_OUT3_LUTOUT3 0x00000008
+#define BF_PXP_WFE_B_STG2_5X1_OUT3_LUTOUT3(v) \
+ (((v) << 3) & BM_PXP_WFE_B_STG2_5X1_OUT3_LUTOUT3)
+#define BM_PXP_WFE_B_STG2_5X1_OUT3_LUTOUT2 0x00000004
+#define BF_PXP_WFE_B_STG2_5X1_OUT3_LUTOUT2(v) \
+ (((v) << 2) & BM_PXP_WFE_B_STG2_5X1_OUT3_LUTOUT2)
+#define BM_PXP_WFE_B_STG2_5X1_OUT3_LUTOUT1 0x00000002
+#define BF_PXP_WFE_B_STG2_5X1_OUT3_LUTOUT1(v) \
+ (((v) << 1) & BM_PXP_WFE_B_STG2_5X1_OUT3_LUTOUT1)
+#define BM_PXP_WFE_B_STG2_5X1_OUT3_LUTOUT0 0x00000001
+#define BF_PXP_WFE_B_STG2_5X1_OUT3_LUTOUT0(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STG2_5X1_OUT3_LUTOUT0)
+
+#define HW_PXP_WFE_B_STG2_5X1_MASKS (0x00002580)
+
+#define BP_PXP_WFE_B_STG2_5X1_MASKS_RSVD3 29
+#define BM_PXP_WFE_B_STG2_5X1_MASKS_RSVD3 0xE0000000
+#define BF_PXP_WFE_B_STG2_5X1_MASKS_RSVD3(v) \
+ (((v) << 29) & BM_PXP_WFE_B_STG2_5X1_MASKS_RSVD3)
+#define BP_PXP_WFE_B_STG2_5X1_MASKS_MASK3 24
+#define BM_PXP_WFE_B_STG2_5X1_MASKS_MASK3 0x1F000000
+#define BF_PXP_WFE_B_STG2_5X1_MASKS_MASK3(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STG2_5X1_MASKS_MASK3)
+#define BP_PXP_WFE_B_STG2_5X1_MASKS_RSVD2 21
+#define BM_PXP_WFE_B_STG2_5X1_MASKS_RSVD2 0x00E00000
+#define BF_PXP_WFE_B_STG2_5X1_MASKS_RSVD2(v) \
+ (((v) << 21) & BM_PXP_WFE_B_STG2_5X1_MASKS_RSVD2)
+#define BP_PXP_WFE_B_STG2_5X1_MASKS_MASK2 16
+#define BM_PXP_WFE_B_STG2_5X1_MASKS_MASK2 0x001F0000
+#define BF_PXP_WFE_B_STG2_5X1_MASKS_MASK2(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STG2_5X1_MASKS_MASK2)
+#define BP_PXP_WFE_B_STG2_5X1_MASKS_RSVD1 13
+#define BM_PXP_WFE_B_STG2_5X1_MASKS_RSVD1 0x0000E000
+#define BF_PXP_WFE_B_STG2_5X1_MASKS_RSVD1(v) \
+ (((v) << 13) & BM_PXP_WFE_B_STG2_5X1_MASKS_RSVD1)
+#define BP_PXP_WFE_B_STG2_5X1_MASKS_MASK1 8
+#define BM_PXP_WFE_B_STG2_5X1_MASKS_MASK1 0x00001F00
+#define BF_PXP_WFE_B_STG2_5X1_MASKS_MASK1(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STG2_5X1_MASKS_MASK1)
+#define BP_PXP_WFE_B_STG2_5X1_MASKS_RSVD0 5
+#define BM_PXP_WFE_B_STG2_5X1_MASKS_RSVD0 0x000000E0
+#define BF_PXP_WFE_B_STG2_5X1_MASKS_RSVD0(v) \
+ (((v) << 5) & BM_PXP_WFE_B_STG2_5X1_MASKS_RSVD0)
+#define BP_PXP_WFE_B_STG2_5X1_MASKS_MASK0 0
+#define BM_PXP_WFE_B_STG2_5X1_MASKS_MASK0 0x0000001F
+#define BF_PXP_WFE_B_STG2_5X1_MASKS_MASK0(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STG2_5X1_MASKS_MASK0)
+
+#define HW_PXP_WFE_B_STG3_F8X1_OUT0_0 (0x00002590)
+
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_0_LUTOUT31 0x80000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_0_LUTOUT31(v) \
+ (((v) << 31) & BM_PXP_WFE_B_STG3_F8X1_OUT0_0_LUTOUT31)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_0_LUTOUT30 0x40000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_0_LUTOUT30(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STG3_F8X1_OUT0_0_LUTOUT30)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_0_LUTOUT29 0x20000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_0_LUTOUT29(v) \
+ (((v) << 29) & BM_PXP_WFE_B_STG3_F8X1_OUT0_0_LUTOUT29)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_0_LUTOUT28 0x10000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_0_LUTOUT28(v) \
+ (((v) << 28) & BM_PXP_WFE_B_STG3_F8X1_OUT0_0_LUTOUT28)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_0_LUTOUT27 0x08000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_0_LUTOUT27(v) \
+ (((v) << 27) & BM_PXP_WFE_B_STG3_F8X1_OUT0_0_LUTOUT27)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_0_LUTOUT26 0x04000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_0_LUTOUT26(v) \
+ (((v) << 26) & BM_PXP_WFE_B_STG3_F8X1_OUT0_0_LUTOUT26)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_0_LUTOUT25 0x02000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_0_LUTOUT25(v) \
+ (((v) << 25) & BM_PXP_WFE_B_STG3_F8X1_OUT0_0_LUTOUT25)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_0_LUTOUT24 0x01000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_0_LUTOUT24(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STG3_F8X1_OUT0_0_LUTOUT24)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_0_LUTOUT23 0x00800000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_0_LUTOUT23(v) \
+ (((v) << 23) & BM_PXP_WFE_B_STG3_F8X1_OUT0_0_LUTOUT23)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_0_LUTOUT22 0x00400000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_0_LUTOUT22(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STG3_F8X1_OUT0_0_LUTOUT22)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_0_LUTOUT21 0x00200000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_0_LUTOUT21(v) \
+ (((v) << 21) & BM_PXP_WFE_B_STG3_F8X1_OUT0_0_LUTOUT21)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_0_LUTOUT20 0x00100000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_0_LUTOUT20(v) \
+ (((v) << 20) & BM_PXP_WFE_B_STG3_F8X1_OUT0_0_LUTOUT20)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_0_LUTOUT19 0x00080000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_0_LUTOUT19(v) \
+ (((v) << 19) & BM_PXP_WFE_B_STG3_F8X1_OUT0_0_LUTOUT19)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_0_LUTOUT18 0x00040000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_0_LUTOUT18(v) \
+ (((v) << 18) & BM_PXP_WFE_B_STG3_F8X1_OUT0_0_LUTOUT18)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_0_LUTOUT17 0x00020000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_0_LUTOUT17(v) \
+ (((v) << 17) & BM_PXP_WFE_B_STG3_F8X1_OUT0_0_LUTOUT17)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_0_LUTOUT16 0x00010000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_0_LUTOUT16(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STG3_F8X1_OUT0_0_LUTOUT16)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_0_LUTOUT15 0x00008000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_0_LUTOUT15(v) \
+ (((v) << 15) & BM_PXP_WFE_B_STG3_F8X1_OUT0_0_LUTOUT15)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_0_LUTOUT14 0x00004000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_0_LUTOUT14(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STG3_F8X1_OUT0_0_LUTOUT14)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_0_LUTOUT13 0x00002000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_0_LUTOUT13(v) \
+ (((v) << 13) & BM_PXP_WFE_B_STG3_F8X1_OUT0_0_LUTOUT13)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_0_LUTOUT12 0x00001000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_0_LUTOUT12(v) \
+ (((v) << 12) & BM_PXP_WFE_B_STG3_F8X1_OUT0_0_LUTOUT12)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_0_LUTOUT11 0x00000800
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_0_LUTOUT11(v) \
+ (((v) << 11) & BM_PXP_WFE_B_STG3_F8X1_OUT0_0_LUTOUT11)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_0_LUTOUT10 0x00000400
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_0_LUTOUT10(v) \
+ (((v) << 10) & BM_PXP_WFE_B_STG3_F8X1_OUT0_0_LUTOUT10)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_0_LUTOUT9 0x00000200
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_0_LUTOUT9(v) \
+ (((v) << 9) & BM_PXP_WFE_B_STG3_F8X1_OUT0_0_LUTOUT9)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_0_LUTOUT8 0x00000100
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_0_LUTOUT8(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STG3_F8X1_OUT0_0_LUTOUT8)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_0_LUTOUT7 0x00000080
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_0_LUTOUT7(v) \
+ (((v) << 7) & BM_PXP_WFE_B_STG3_F8X1_OUT0_0_LUTOUT7)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_0_LUTOUT6 0x00000040
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_0_LUTOUT6(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STG3_F8X1_OUT0_0_LUTOUT6)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_0_LUTOUT5 0x00000020
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_0_LUTOUT5(v) \
+ (((v) << 5) & BM_PXP_WFE_B_STG3_F8X1_OUT0_0_LUTOUT5)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_0_LUTOUT4 0x00000010
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_0_LUTOUT4(v) \
+ (((v) << 4) & BM_PXP_WFE_B_STG3_F8X1_OUT0_0_LUTOUT4)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_0_LUTOUT3 0x00000008
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_0_LUTOUT3(v) \
+ (((v) << 3) & BM_PXP_WFE_B_STG3_F8X1_OUT0_0_LUTOUT3)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_0_LUTOUT2 0x00000004
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_0_LUTOUT2(v) \
+ (((v) << 2) & BM_PXP_WFE_B_STG3_F8X1_OUT0_0_LUTOUT2)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_0_LUTOUT1 0x00000002
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_0_LUTOUT1(v) \
+ (((v) << 1) & BM_PXP_WFE_B_STG3_F8X1_OUT0_0_LUTOUT1)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_0_LUTOUT0 0x00000001
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_0_LUTOUT0(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STG3_F8X1_OUT0_0_LUTOUT0)
+
+#define HW_PXP_WFE_B_STG3_F8X1_OUT0_1 (0x000025a0)
+
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_1_LUTOUT63 0x80000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_1_LUTOUT63(v) \
+ (((v) << 31) & BM_PXP_WFE_B_STG3_F8X1_OUT0_1_LUTOUT63)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_1_LUTOUT62 0x40000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_1_LUTOUT62(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STG3_F8X1_OUT0_1_LUTOUT62)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_1_LUTOUT61 0x20000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_1_LUTOUT61(v) \
+ (((v) << 29) & BM_PXP_WFE_B_STG3_F8X1_OUT0_1_LUTOUT61)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_1_LUTOUT60 0x10000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_1_LUTOUT60(v) \
+ (((v) << 28) & BM_PXP_WFE_B_STG3_F8X1_OUT0_1_LUTOUT60)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_1_LUTOUT59 0x08000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_1_LUTOUT59(v) \
+ (((v) << 27) & BM_PXP_WFE_B_STG3_F8X1_OUT0_1_LUTOUT59)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_1_LUTOUT58 0x04000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_1_LUTOUT58(v) \
+ (((v) << 26) & BM_PXP_WFE_B_STG3_F8X1_OUT0_1_LUTOUT58)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_1_LUTOUT57 0x02000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_1_LUTOUT57(v) \
+ (((v) << 25) & BM_PXP_WFE_B_STG3_F8X1_OUT0_1_LUTOUT57)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_1_LUTOUT56 0x01000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_1_LUTOUT56(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STG3_F8X1_OUT0_1_LUTOUT56)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_1_LUTOUT55 0x00800000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_1_LUTOUT55(v) \
+ (((v) << 23) & BM_PXP_WFE_B_STG3_F8X1_OUT0_1_LUTOUT55)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_1_LUTOUT54 0x00400000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_1_LUTOUT54(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STG3_F8X1_OUT0_1_LUTOUT54)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_1_LUTOUT53 0x00200000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_1_LUTOUT53(v) \
+ (((v) << 21) & BM_PXP_WFE_B_STG3_F8X1_OUT0_1_LUTOUT53)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_1_LUTOUT52 0x00100000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_1_LUTOUT52(v) \
+ (((v) << 20) & BM_PXP_WFE_B_STG3_F8X1_OUT0_1_LUTOUT52)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_1_LUTOUT51 0x00080000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_1_LUTOUT51(v) \
+ (((v) << 19) & BM_PXP_WFE_B_STG3_F8X1_OUT0_1_LUTOUT51)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_1_LUTOUT50 0x00040000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_1_LUTOUT50(v) \
+ (((v) << 18) & BM_PXP_WFE_B_STG3_F8X1_OUT0_1_LUTOUT50)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_1_LUTOUT49 0x00020000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_1_LUTOUT49(v) \
+ (((v) << 17) & BM_PXP_WFE_B_STG3_F8X1_OUT0_1_LUTOUT49)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_1_LUTOUT48 0x00010000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_1_LUTOUT48(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STG3_F8X1_OUT0_1_LUTOUT48)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_1_LUTOUT47 0x00008000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_1_LUTOUT47(v) \
+ (((v) << 15) & BM_PXP_WFE_B_STG3_F8X1_OUT0_1_LUTOUT47)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_1_LUTOUT46 0x00004000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_1_LUTOUT46(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STG3_F8X1_OUT0_1_LUTOUT46)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_1_LUTOUT45 0x00002000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_1_LUTOUT45(v) \
+ (((v) << 13) & BM_PXP_WFE_B_STG3_F8X1_OUT0_1_LUTOUT45)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_1_LUTOUT44 0x00001000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_1_LUTOUT44(v) \
+ (((v) << 12) & BM_PXP_WFE_B_STG3_F8X1_OUT0_1_LUTOUT44)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_1_LUTOUT43 0x00000800
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_1_LUTOUT43(v) \
+ (((v) << 11) & BM_PXP_WFE_B_STG3_F8X1_OUT0_1_LUTOUT43)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_1_LUTOUT42 0x00000400
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_1_LUTOUT42(v) \
+ (((v) << 10) & BM_PXP_WFE_B_STG3_F8X1_OUT0_1_LUTOUT42)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_1_LUTOUT41 0x00000200
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_1_LUTOUT41(v) \
+ (((v) << 9) & BM_PXP_WFE_B_STG3_F8X1_OUT0_1_LUTOUT41)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_1_LUTOUT40 0x00000100
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_1_LUTOUT40(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STG3_F8X1_OUT0_1_LUTOUT40)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_1_LUTOUT39 0x00000080
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_1_LUTOUT39(v) \
+ (((v) << 7) & BM_PXP_WFE_B_STG3_F8X1_OUT0_1_LUTOUT39)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_1_LUTOUT38 0x00000040
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_1_LUTOUT38(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STG3_F8X1_OUT0_1_LUTOUT38)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_1_LUTOUT37 0x00000020
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_1_LUTOUT37(v) \
+ (((v) << 5) & BM_PXP_WFE_B_STG3_F8X1_OUT0_1_LUTOUT37)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_1_LUTOUT36 0x00000010
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_1_LUTOUT36(v) \
+ (((v) << 4) & BM_PXP_WFE_B_STG3_F8X1_OUT0_1_LUTOUT36)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_1_LUTOUT35 0x00000008
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_1_LUTOUT35(v) \
+ (((v) << 3) & BM_PXP_WFE_B_STG3_F8X1_OUT0_1_LUTOUT35)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_1_LUTOUT34 0x00000004
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_1_LUTOUT34(v) \
+ (((v) << 2) & BM_PXP_WFE_B_STG3_F8X1_OUT0_1_LUTOUT34)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_1_LUTOUT33 0x00000002
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_1_LUTOUT33(v) \
+ (((v) << 1) & BM_PXP_WFE_B_STG3_F8X1_OUT0_1_LUTOUT33)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_1_LUTOUT32 0x00000001
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_1_LUTOUT32(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STG3_F8X1_OUT0_1_LUTOUT32)
+
+#define HW_PXP_WFE_B_STG3_F8X1_OUT0_2 (0x000025b0)
+
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_2_LUTOUT95 0x80000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_2_LUTOUT95(v) \
+ (((v) << 31) & BM_PXP_WFE_B_STG3_F8X1_OUT0_2_LUTOUT95)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_2_LUTOUT94 0x40000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_2_LUTOUT94(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STG3_F8X1_OUT0_2_LUTOUT94)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_2_LUTOUT93 0x20000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_2_LUTOUT93(v) \
+ (((v) << 29) & BM_PXP_WFE_B_STG3_F8X1_OUT0_2_LUTOUT93)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_2_LUTOUT92 0x10000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_2_LUTOUT92(v) \
+ (((v) << 28) & BM_PXP_WFE_B_STG3_F8X1_OUT0_2_LUTOUT92)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_2_LUTOUT91 0x08000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_2_LUTOUT91(v) \
+ (((v) << 27) & BM_PXP_WFE_B_STG3_F8X1_OUT0_2_LUTOUT91)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_2_LUTOUT90 0x04000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_2_LUTOUT90(v) \
+ (((v) << 26) & BM_PXP_WFE_B_STG3_F8X1_OUT0_2_LUTOUT90)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_2_LUTOUT89 0x02000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_2_LUTOUT89(v) \
+ (((v) << 25) & BM_PXP_WFE_B_STG3_F8X1_OUT0_2_LUTOUT89)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_2_LUTOUT88 0x01000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_2_LUTOUT88(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STG3_F8X1_OUT0_2_LUTOUT88)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_2_LUTOUT87 0x00800000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_2_LUTOUT87(v) \
+ (((v) << 23) & BM_PXP_WFE_B_STG3_F8X1_OUT0_2_LUTOUT87)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_2_LUTOUT86 0x00400000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_2_LUTOUT86(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STG3_F8X1_OUT0_2_LUTOUT86)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_2_LUTOUT85 0x00200000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_2_LUTOUT85(v) \
+ (((v) << 21) & BM_PXP_WFE_B_STG3_F8X1_OUT0_2_LUTOUT85)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_2_LUTOUT84 0x00100000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_2_LUTOUT84(v) \
+ (((v) << 20) & BM_PXP_WFE_B_STG3_F8X1_OUT0_2_LUTOUT84)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_2_LUTOUT83 0x00080000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_2_LUTOUT83(v) \
+ (((v) << 19) & BM_PXP_WFE_B_STG3_F8X1_OUT0_2_LUTOUT83)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_2_LUTOUT82 0x00040000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_2_LUTOUT82(v) \
+ (((v) << 18) & BM_PXP_WFE_B_STG3_F8X1_OUT0_2_LUTOUT82)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_2_LUTOUT81 0x00020000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_2_LUTOUT81(v) \
+ (((v) << 17) & BM_PXP_WFE_B_STG3_F8X1_OUT0_2_LUTOUT81)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_2_LUTOUT80 0x00010000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_2_LUTOUT80(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STG3_F8X1_OUT0_2_LUTOUT80)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_2_LUTOUT79 0x00008000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_2_LUTOUT79(v) \
+ (((v) << 15) & BM_PXP_WFE_B_STG3_F8X1_OUT0_2_LUTOUT79)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_2_LUTOUT78 0x00004000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_2_LUTOUT78(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STG3_F8X1_OUT0_2_LUTOUT78)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_2_LUTOUT77 0x00002000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_2_LUTOUT77(v) \
+ (((v) << 13) & BM_PXP_WFE_B_STG3_F8X1_OUT0_2_LUTOUT77)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_2_LUTOUT76 0x00001000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_2_LUTOUT76(v) \
+ (((v) << 12) & BM_PXP_WFE_B_STG3_F8X1_OUT0_2_LUTOUT76)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_2_LUTOUT75 0x00000800
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_2_LUTOUT75(v) \
+ (((v) << 11) & BM_PXP_WFE_B_STG3_F8X1_OUT0_2_LUTOUT75)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_2_LUTOUT74 0x00000400
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_2_LUTOUT74(v) \
+ (((v) << 10) & BM_PXP_WFE_B_STG3_F8X1_OUT0_2_LUTOUT74)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_2_LUTOUT73 0x00000200
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_2_LUTOUT73(v) \
+ (((v) << 9) & BM_PXP_WFE_B_STG3_F8X1_OUT0_2_LUTOUT73)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_2_LUTOUT72 0x00000100
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_2_LUTOUT72(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STG3_F8X1_OUT0_2_LUTOUT72)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_2_LUTOUT71 0x00000080
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_2_LUTOUT71(v) \
+ (((v) << 7) & BM_PXP_WFE_B_STG3_F8X1_OUT0_2_LUTOUT71)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_2_LUTOUT70 0x00000040
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_2_LUTOUT70(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STG3_F8X1_OUT0_2_LUTOUT70)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_2_LUTOUT69 0x00000020
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_2_LUTOUT69(v) \
+ (((v) << 5) & BM_PXP_WFE_B_STG3_F8X1_OUT0_2_LUTOUT69)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_2_LUTOUT68 0x00000010
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_2_LUTOUT68(v) \
+ (((v) << 4) & BM_PXP_WFE_B_STG3_F8X1_OUT0_2_LUTOUT68)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_2_LUTOUT67 0x00000008
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_2_LUTOUT67(v) \
+ (((v) << 3) & BM_PXP_WFE_B_STG3_F8X1_OUT0_2_LUTOUT67)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_2_LUTOUT66 0x00000004
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_2_LUTOUT66(v) \
+ (((v) << 2) & BM_PXP_WFE_B_STG3_F8X1_OUT0_2_LUTOUT66)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_2_LUTOUT65 0x00000002
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_2_LUTOUT65(v) \
+ (((v) << 1) & BM_PXP_WFE_B_STG3_F8X1_OUT0_2_LUTOUT65)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_2_LUTOUT64 0x00000001
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_2_LUTOUT64(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STG3_F8X1_OUT0_2_LUTOUT64)
+
+#define HW_PXP_WFE_B_STG3_F8X1_OUT0_3 (0x000025c0)
+
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_3_LUTOUT127 0x80000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_3_LUTOUT127(v) \
+ (((v) << 31) & BM_PXP_WFE_B_STG3_F8X1_OUT0_3_LUTOUT127)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_3_LUTOUT126 0x40000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_3_LUTOUT126(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STG3_F8X1_OUT0_3_LUTOUT126)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_3_LUTOUT125 0x20000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_3_LUTOUT125(v) \
+ (((v) << 29) & BM_PXP_WFE_B_STG3_F8X1_OUT0_3_LUTOUT125)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_3_LUTOUT124 0x10000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_3_LUTOUT124(v) \
+ (((v) << 28) & BM_PXP_WFE_B_STG3_F8X1_OUT0_3_LUTOUT124)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_3_LUTOUT123 0x08000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_3_LUTOUT123(v) \
+ (((v) << 27) & BM_PXP_WFE_B_STG3_F8X1_OUT0_3_LUTOUT123)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_3_LUTOUT122 0x04000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_3_LUTOUT122(v) \
+ (((v) << 26) & BM_PXP_WFE_B_STG3_F8X1_OUT0_3_LUTOUT122)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_3_LUTOUT121 0x02000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_3_LUTOUT121(v) \
+ (((v) << 25) & BM_PXP_WFE_B_STG3_F8X1_OUT0_3_LUTOUT121)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_3_LUTOUT120 0x01000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_3_LUTOUT120(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STG3_F8X1_OUT0_3_LUTOUT120)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_3_LUTOUT119 0x00800000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_3_LUTOUT119(v) \
+ (((v) << 23) & BM_PXP_WFE_B_STG3_F8X1_OUT0_3_LUTOUT119)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_3_LUTOUT118 0x00400000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_3_LUTOUT118(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STG3_F8X1_OUT0_3_LUTOUT118)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_3_LUTOUT117 0x00200000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_3_LUTOUT117(v) \
+ (((v) << 21) & BM_PXP_WFE_B_STG3_F8X1_OUT0_3_LUTOUT117)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_3_LUTOUT116 0x00100000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_3_LUTOUT116(v) \
+ (((v) << 20) & BM_PXP_WFE_B_STG3_F8X1_OUT0_3_LUTOUT116)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_3_LUTOUT115 0x00080000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_3_LUTOUT115(v) \
+ (((v) << 19) & BM_PXP_WFE_B_STG3_F8X1_OUT0_3_LUTOUT115)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_3_LUTOUT114 0x00040000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_3_LUTOUT114(v) \
+ (((v) << 18) & BM_PXP_WFE_B_STG3_F8X1_OUT0_3_LUTOUT114)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_3_LUTOUT113 0x00020000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_3_LUTOUT113(v) \
+ (((v) << 17) & BM_PXP_WFE_B_STG3_F8X1_OUT0_3_LUTOUT113)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_3_LUTOUT112 0x00010000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_3_LUTOUT112(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STG3_F8X1_OUT0_3_LUTOUT112)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_3_LUTOUT111 0x00008000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_3_LUTOUT111(v) \
+ (((v) << 15) & BM_PXP_WFE_B_STG3_F8X1_OUT0_3_LUTOUT111)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_3_LUTOUT110 0x00004000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_3_LUTOUT110(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STG3_F8X1_OUT0_3_LUTOUT110)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_3_LUTOUT109 0x00002000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_3_LUTOUT109(v) \
+ (((v) << 13) & BM_PXP_WFE_B_STG3_F8X1_OUT0_3_LUTOUT109)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_3_LUTOUT108 0x00001000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_3_LUTOUT108(v) \
+ (((v) << 12) & BM_PXP_WFE_B_STG3_F8X1_OUT0_3_LUTOUT108)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_3_LUTOUT107 0x00000800
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_3_LUTOUT107(v) \
+ (((v) << 11) & BM_PXP_WFE_B_STG3_F8X1_OUT0_3_LUTOUT107)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_3_LUTOUT106 0x00000400
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_3_LUTOUT106(v) \
+ (((v) << 10) & BM_PXP_WFE_B_STG3_F8X1_OUT0_3_LUTOUT106)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_3_LUTOUT105 0x00000200
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_3_LUTOUT105(v) \
+ (((v) << 9) & BM_PXP_WFE_B_STG3_F8X1_OUT0_3_LUTOUT105)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_3_LUTOUT104 0x00000100
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_3_LUTOUT104(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STG3_F8X1_OUT0_3_LUTOUT104)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_3_LUTOUT103 0x00000080
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_3_LUTOUT103(v) \
+ (((v) << 7) & BM_PXP_WFE_B_STG3_F8X1_OUT0_3_LUTOUT103)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_3_LUTOUT102 0x00000040
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_3_LUTOUT102(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STG3_F8X1_OUT0_3_LUTOUT102)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_3_LUTOUT101 0x00000020
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_3_LUTOUT101(v) \
+ (((v) << 5) & BM_PXP_WFE_B_STG3_F8X1_OUT0_3_LUTOUT101)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_3_LUTOUT100 0x00000010
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_3_LUTOUT100(v) \
+ (((v) << 4) & BM_PXP_WFE_B_STG3_F8X1_OUT0_3_LUTOUT100)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_3_LUTOUT99 0x00000008
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_3_LUTOUT99(v) \
+ (((v) << 3) & BM_PXP_WFE_B_STG3_F8X1_OUT0_3_LUTOUT99)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_3_LUTOUT98 0x00000004
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_3_LUTOUT98(v) \
+ (((v) << 2) & BM_PXP_WFE_B_STG3_F8X1_OUT0_3_LUTOUT98)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_3_LUTOUT97 0x00000002
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_3_LUTOUT97(v) \
+ (((v) << 1) & BM_PXP_WFE_B_STG3_F8X1_OUT0_3_LUTOUT97)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_3_LUTOUT96 0x00000001
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_3_LUTOUT96(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STG3_F8X1_OUT0_3_LUTOUT96)
+
+#define HW_PXP_WFE_B_STG3_F8X1_OUT0_4 (0x000025d0)
+
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_4_LUTOUT159 0x80000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_4_LUTOUT159(v) \
+ (((v) << 31) & BM_PXP_WFE_B_STG3_F8X1_OUT0_4_LUTOUT159)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_4_LUTOUT158 0x40000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_4_LUTOUT158(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STG3_F8X1_OUT0_4_LUTOUT158)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_4_LUTOUT157 0x20000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_4_LUTOUT157(v) \
+ (((v) << 29) & BM_PXP_WFE_B_STG3_F8X1_OUT0_4_LUTOUT157)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_4_LUTOUT156 0x10000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_4_LUTOUT156(v) \
+ (((v) << 28) & BM_PXP_WFE_B_STG3_F8X1_OUT0_4_LUTOUT156)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_4_LUTOUT155 0x08000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_4_LUTOUT155(v) \
+ (((v) << 27) & BM_PXP_WFE_B_STG3_F8X1_OUT0_4_LUTOUT155)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_4_LUTOUT154 0x04000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_4_LUTOUT154(v) \
+ (((v) << 26) & BM_PXP_WFE_B_STG3_F8X1_OUT0_4_LUTOUT154)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_4_LUTOUT153 0x02000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_4_LUTOUT153(v) \
+ (((v) << 25) & BM_PXP_WFE_B_STG3_F8X1_OUT0_4_LUTOUT153)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_4_LUTOUT152 0x01000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_4_LUTOUT152(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STG3_F8X1_OUT0_4_LUTOUT152)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_4_LUTOUT151 0x00800000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_4_LUTOUT151(v) \
+ (((v) << 23) & BM_PXP_WFE_B_STG3_F8X1_OUT0_4_LUTOUT151)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_4_LUTOUT150 0x00400000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_4_LUTOUT150(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STG3_F8X1_OUT0_4_LUTOUT150)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_4_LUTOUT149 0x00200000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_4_LUTOUT149(v) \
+ (((v) << 21) & BM_PXP_WFE_B_STG3_F8X1_OUT0_4_LUTOUT149)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_4_LUTOUT148 0x00100000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_4_LUTOUT148(v) \
+ (((v) << 20) & BM_PXP_WFE_B_STG3_F8X1_OUT0_4_LUTOUT148)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_4_LUTOUT147 0x00080000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_4_LUTOUT147(v) \
+ (((v) << 19) & BM_PXP_WFE_B_STG3_F8X1_OUT0_4_LUTOUT147)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_4_LUTOUT146 0x00040000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_4_LUTOUT146(v) \
+ (((v) << 18) & BM_PXP_WFE_B_STG3_F8X1_OUT0_4_LUTOUT146)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_4_LUTOUT145 0x00020000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_4_LUTOUT145(v) \
+ (((v) << 17) & BM_PXP_WFE_B_STG3_F8X1_OUT0_4_LUTOUT145)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_4_LUTOUT144 0x00010000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_4_LUTOUT144(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STG3_F8X1_OUT0_4_LUTOUT144)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_4_LUTOUT143 0x00008000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_4_LUTOUT143(v) \
+ (((v) << 15) & BM_PXP_WFE_B_STG3_F8X1_OUT0_4_LUTOUT143)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_4_LUTOUT142 0x00004000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_4_LUTOUT142(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STG3_F8X1_OUT0_4_LUTOUT142)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_4_LUTOUT141 0x00002000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_4_LUTOUT141(v) \
+ (((v) << 13) & BM_PXP_WFE_B_STG3_F8X1_OUT0_4_LUTOUT141)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_4_LUTOUT140 0x00001000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_4_LUTOUT140(v) \
+ (((v) << 12) & BM_PXP_WFE_B_STG3_F8X1_OUT0_4_LUTOUT140)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_4_LUTOUT139 0x00000800
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_4_LUTOUT139(v) \
+ (((v) << 11) & BM_PXP_WFE_B_STG3_F8X1_OUT0_4_LUTOUT139)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_4_LUTOUT138 0x00000400
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_4_LUTOUT138(v) \
+ (((v) << 10) & BM_PXP_WFE_B_STG3_F8X1_OUT0_4_LUTOUT138)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_4_LUTOUT137 0x00000200
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_4_LUTOUT137(v) \
+ (((v) << 9) & BM_PXP_WFE_B_STG3_F8X1_OUT0_4_LUTOUT137)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_4_LUTOUT136 0x00000100
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_4_LUTOUT136(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STG3_F8X1_OUT0_4_LUTOUT136)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_4_LUTOUT135 0x00000080
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_4_LUTOUT135(v) \
+ (((v) << 7) & BM_PXP_WFE_B_STG3_F8X1_OUT0_4_LUTOUT135)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_4_LUTOUT134 0x00000040
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_4_LUTOUT134(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STG3_F8X1_OUT0_4_LUTOUT134)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_4_LUTOUT133 0x00000020
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_4_LUTOUT133(v) \
+ (((v) << 5) & BM_PXP_WFE_B_STG3_F8X1_OUT0_4_LUTOUT133)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_4_LUTOUT132 0x00000010
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_4_LUTOUT132(v) \
+ (((v) << 4) & BM_PXP_WFE_B_STG3_F8X1_OUT0_4_LUTOUT132)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_4_LUTOUT131 0x00000008
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_4_LUTOUT131(v) \
+ (((v) << 3) & BM_PXP_WFE_B_STG3_F8X1_OUT0_4_LUTOUT131)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_4_LUTOUT130 0x00000004
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_4_LUTOUT130(v) \
+ (((v) << 2) & BM_PXP_WFE_B_STG3_F8X1_OUT0_4_LUTOUT130)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_4_LUTOUT129 0x00000002
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_4_LUTOUT129(v) \
+ (((v) << 1) & BM_PXP_WFE_B_STG3_F8X1_OUT0_4_LUTOUT129)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_4_LUTOUT128 0x00000001
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_4_LUTOUT128(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STG3_F8X1_OUT0_4_LUTOUT128)
+
+#define HW_PXP_WFE_B_STG3_F8X1_OUT0_5 (0x000025e0)
+
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_5_LUTOUT191 0x80000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_5_LUTOUT191(v) \
+ (((v) << 31) & BM_PXP_WFE_B_STG3_F8X1_OUT0_5_LUTOUT191)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_5_LUTOUT190 0x40000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_5_LUTOUT190(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STG3_F8X1_OUT0_5_LUTOUT190)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_5_LUTOUT189 0x20000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_5_LUTOUT189(v) \
+ (((v) << 29) & BM_PXP_WFE_B_STG3_F8X1_OUT0_5_LUTOUT189)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_5_LUTOUT188 0x10000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_5_LUTOUT188(v) \
+ (((v) << 28) & BM_PXP_WFE_B_STG3_F8X1_OUT0_5_LUTOUT188)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_5_LUTOUT187 0x08000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_5_LUTOUT187(v) \
+ (((v) << 27) & BM_PXP_WFE_B_STG3_F8X1_OUT0_5_LUTOUT187)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_5_LUTOUT186 0x04000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_5_LUTOUT186(v) \
+ (((v) << 26) & BM_PXP_WFE_B_STG3_F8X1_OUT0_5_LUTOUT186)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_5_LUTOUT185 0x02000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_5_LUTOUT185(v) \
+ (((v) << 25) & BM_PXP_WFE_B_STG3_F8X1_OUT0_5_LUTOUT185)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_5_LUTOUT184 0x01000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_5_LUTOUT184(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STG3_F8X1_OUT0_5_LUTOUT184)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_5_LUTOUT183 0x00800000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_5_LUTOUT183(v) \
+ (((v) << 23) & BM_PXP_WFE_B_STG3_F8X1_OUT0_5_LUTOUT183)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_5_LUTOUT182 0x00400000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_5_LUTOUT182(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STG3_F8X1_OUT0_5_LUTOUT182)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_5_LUTOUT181 0x00200000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_5_LUTOUT181(v) \
+ (((v) << 21) & BM_PXP_WFE_B_STG3_F8X1_OUT0_5_LUTOUT181)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_5_LUTOUT180 0x00100000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_5_LUTOUT180(v) \
+ (((v) << 20) & BM_PXP_WFE_B_STG3_F8X1_OUT0_5_LUTOUT180)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_5_LUTOUT179 0x00080000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_5_LUTOUT179(v) \
+ (((v) << 19) & BM_PXP_WFE_B_STG3_F8X1_OUT0_5_LUTOUT179)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_5_LUTOUT178 0x00040000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_5_LUTOUT178(v) \
+ (((v) << 18) & BM_PXP_WFE_B_STG3_F8X1_OUT0_5_LUTOUT178)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_5_LUTOUT177 0x00020000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_5_LUTOUT177(v) \
+ (((v) << 17) & BM_PXP_WFE_B_STG3_F8X1_OUT0_5_LUTOUT177)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_5_LUTOUT176 0x00010000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_5_LUTOUT176(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STG3_F8X1_OUT0_5_LUTOUT176)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_5_LUTOUT175 0x00008000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_5_LUTOUT175(v) \
+ (((v) << 15) & BM_PXP_WFE_B_STG3_F8X1_OUT0_5_LUTOUT175)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_5_LUTOUT174 0x00004000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_5_LUTOUT174(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STG3_F8X1_OUT0_5_LUTOUT174)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_5_LUTOUT173 0x00002000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_5_LUTOUT173(v) \
+ (((v) << 13) & BM_PXP_WFE_B_STG3_F8X1_OUT0_5_LUTOUT173)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_5_LUTOUT172 0x00001000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_5_LUTOUT172(v) \
+ (((v) << 12) & BM_PXP_WFE_B_STG3_F8X1_OUT0_5_LUTOUT172)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_5_LUTOUT171 0x00000800
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_5_LUTOUT171(v) \
+ (((v) << 11) & BM_PXP_WFE_B_STG3_F8X1_OUT0_5_LUTOUT171)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_5_LUTOUT170 0x00000400
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_5_LUTOUT170(v) \
+ (((v) << 10) & BM_PXP_WFE_B_STG3_F8X1_OUT0_5_LUTOUT170)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_5_LUTOUT169 0x00000200
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_5_LUTOUT169(v) \
+ (((v) << 9) & BM_PXP_WFE_B_STG3_F8X1_OUT0_5_LUTOUT169)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_5_LUTOUT168 0x00000100
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_5_LUTOUT168(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STG3_F8X1_OUT0_5_LUTOUT168)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_5_LUTOUT167 0x00000080
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_5_LUTOUT167(v) \
+ (((v) << 7) & BM_PXP_WFE_B_STG3_F8X1_OUT0_5_LUTOUT167)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_5_LUTOUT166 0x00000040
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_5_LUTOUT166(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STG3_F8X1_OUT0_5_LUTOUT166)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_5_LUTOUT165 0x00000020
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_5_LUTOUT165(v) \
+ (((v) << 5) & BM_PXP_WFE_B_STG3_F8X1_OUT0_5_LUTOUT165)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_5_LUTOUT164 0x00000010
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_5_LUTOUT164(v) \
+ (((v) << 4) & BM_PXP_WFE_B_STG3_F8X1_OUT0_5_LUTOUT164)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_5_LUTOUT163 0x00000008
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_5_LUTOUT163(v) \
+ (((v) << 3) & BM_PXP_WFE_B_STG3_F8X1_OUT0_5_LUTOUT163)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_5_LUTOUT162 0x00000004
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_5_LUTOUT162(v) \
+ (((v) << 2) & BM_PXP_WFE_B_STG3_F8X1_OUT0_5_LUTOUT162)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_5_LUTOUT161 0x00000002
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_5_LUTOUT161(v) \
+ (((v) << 1) & BM_PXP_WFE_B_STG3_F8X1_OUT0_5_LUTOUT161)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_5_LUTOUT160 0x00000001
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_5_LUTOUT160(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STG3_F8X1_OUT0_5_LUTOUT160)
+
+#define HW_PXP_WFE_B_STG3_F8X1_OUT0_6 (0x000025f0)
+
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_6_LUTOUT223 0x80000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_6_LUTOUT223(v) \
+ (((v) << 31) & BM_PXP_WFE_B_STG3_F8X1_OUT0_6_LUTOUT223)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_6_LUTOUT222 0x40000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_6_LUTOUT222(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STG3_F8X1_OUT0_6_LUTOUT222)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_6_LUTOUT221 0x20000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_6_LUTOUT221(v) \
+ (((v) << 29) & BM_PXP_WFE_B_STG3_F8X1_OUT0_6_LUTOUT221)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_6_LUTOUT220 0x10000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_6_LUTOUT220(v) \
+ (((v) << 28) & BM_PXP_WFE_B_STG3_F8X1_OUT0_6_LUTOUT220)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_6_LUTOUT219 0x08000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_6_LUTOUT219(v) \
+ (((v) << 27) & BM_PXP_WFE_B_STG3_F8X1_OUT0_6_LUTOUT219)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_6_LUTOUT218 0x04000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_6_LUTOUT218(v) \
+ (((v) << 26) & BM_PXP_WFE_B_STG3_F8X1_OUT0_6_LUTOUT218)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_6_LUTOUT217 0x02000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_6_LUTOUT217(v) \
+ (((v) << 25) & BM_PXP_WFE_B_STG3_F8X1_OUT0_6_LUTOUT217)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_6_LUTOUT216 0x01000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_6_LUTOUT216(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STG3_F8X1_OUT0_6_LUTOUT216)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_6_LUTOUT215 0x00800000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_6_LUTOUT215(v) \
+ (((v) << 23) & BM_PXP_WFE_B_STG3_F8X1_OUT0_6_LUTOUT215)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_6_LUTOUT214 0x00400000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_6_LUTOUT214(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STG3_F8X1_OUT0_6_LUTOUT214)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_6_LUTOUT213 0x00200000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_6_LUTOUT213(v) \
+ (((v) << 21) & BM_PXP_WFE_B_STG3_F8X1_OUT0_6_LUTOUT213)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_6_LUTOUT212 0x00100000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_6_LUTOUT212(v) \
+ (((v) << 20) & BM_PXP_WFE_B_STG3_F8X1_OUT0_6_LUTOUT212)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_6_LUTOUT211 0x00080000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_6_LUTOUT211(v) \
+ (((v) << 19) & BM_PXP_WFE_B_STG3_F8X1_OUT0_6_LUTOUT211)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_6_LUTOUT210 0x00040000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_6_LUTOUT210(v) \
+ (((v) << 18) & BM_PXP_WFE_B_STG3_F8X1_OUT0_6_LUTOUT210)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_6_LUTOUT209 0x00020000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_6_LUTOUT209(v) \
+ (((v) << 17) & BM_PXP_WFE_B_STG3_F8X1_OUT0_6_LUTOUT209)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_6_LUTOUT208 0x00010000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_6_LUTOUT208(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STG3_F8X1_OUT0_6_LUTOUT208)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_6_LUTOUT207 0x00008000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_6_LUTOUT207(v) \
+ (((v) << 15) & BM_PXP_WFE_B_STG3_F8X1_OUT0_6_LUTOUT207)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_6_LUTOUT206 0x00004000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_6_LUTOUT206(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STG3_F8X1_OUT0_6_LUTOUT206)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_6_LUTOUT205 0x00002000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_6_LUTOUT205(v) \
+ (((v) << 13) & BM_PXP_WFE_B_STG3_F8X1_OUT0_6_LUTOUT205)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_6_LUTOUT204 0x00001000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_6_LUTOUT204(v) \
+ (((v) << 12) & BM_PXP_WFE_B_STG3_F8X1_OUT0_6_LUTOUT204)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_6_LUTOUT203 0x00000800
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_6_LUTOUT203(v) \
+ (((v) << 11) & BM_PXP_WFE_B_STG3_F8X1_OUT0_6_LUTOUT203)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_6_LUTOUT202 0x00000400
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_6_LUTOUT202(v) \
+ (((v) << 10) & BM_PXP_WFE_B_STG3_F8X1_OUT0_6_LUTOUT202)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_6_LUTOUT201 0x00000200
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_6_LUTOUT201(v) \
+ (((v) << 9) & BM_PXP_WFE_B_STG3_F8X1_OUT0_6_LUTOUT201)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_6_LUTOUT200 0x00000100
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_6_LUTOUT200(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STG3_F8X1_OUT0_6_LUTOUT200)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_6_LUTOUT199 0x00000080
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_6_LUTOUT199(v) \
+ (((v) << 7) & BM_PXP_WFE_B_STG3_F8X1_OUT0_6_LUTOUT199)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_6_LUTOUT198 0x00000040
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_6_LUTOUT198(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STG3_F8X1_OUT0_6_LUTOUT198)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_6_LUTOUT197 0x00000020
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_6_LUTOUT197(v) \
+ (((v) << 5) & BM_PXP_WFE_B_STG3_F8X1_OUT0_6_LUTOUT197)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_6_LUTOUT196 0x00000010
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_6_LUTOUT196(v) \
+ (((v) << 4) & BM_PXP_WFE_B_STG3_F8X1_OUT0_6_LUTOUT196)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_6_LUTOUT195 0x00000008
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_6_LUTOUT195(v) \
+ (((v) << 3) & BM_PXP_WFE_B_STG3_F8X1_OUT0_6_LUTOUT195)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_6_LUTOUT194 0x00000004
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_6_LUTOUT194(v) \
+ (((v) << 2) & BM_PXP_WFE_B_STG3_F8X1_OUT0_6_LUTOUT194)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_6_LUTOUT193 0x00000002
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_6_LUTOUT193(v) \
+ (((v) << 1) & BM_PXP_WFE_B_STG3_F8X1_OUT0_6_LUTOUT193)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_6_LUTOUT192 0x00000001
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_6_LUTOUT192(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STG3_F8X1_OUT0_6_LUTOUT192)
+
+#define HW_PXP_WFE_B_STG3_F8X1_OUT0_7 (0x00002600)
+
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_7_LUTOUT255 0x80000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_7_LUTOUT255(v) \
+ (((v) << 31) & BM_PXP_WFE_B_STG3_F8X1_OUT0_7_LUTOUT255)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_7_LUTOUT254 0x40000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_7_LUTOUT254(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STG3_F8X1_OUT0_7_LUTOUT254)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_7_LUTOUT253 0x20000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_7_LUTOUT253(v) \
+ (((v) << 29) & BM_PXP_WFE_B_STG3_F8X1_OUT0_7_LUTOUT253)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_7_LUTOUT252 0x10000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_7_LUTOUT252(v) \
+ (((v) << 28) & BM_PXP_WFE_B_STG3_F8X1_OUT0_7_LUTOUT252)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_7_LUTOUT251 0x08000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_7_LUTOUT251(v) \
+ (((v) << 27) & BM_PXP_WFE_B_STG3_F8X1_OUT0_7_LUTOUT251)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_7_LUTOUT250 0x04000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_7_LUTOUT250(v) \
+ (((v) << 26) & BM_PXP_WFE_B_STG3_F8X1_OUT0_7_LUTOUT250)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_7_LUTOUT249 0x02000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_7_LUTOUT249(v) \
+ (((v) << 25) & BM_PXP_WFE_B_STG3_F8X1_OUT0_7_LUTOUT249)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_7_LUTOUT248 0x01000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_7_LUTOUT248(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STG3_F8X1_OUT0_7_LUTOUT248)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_7_LUTOUT247 0x00800000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_7_LUTOUT247(v) \
+ (((v) << 23) & BM_PXP_WFE_B_STG3_F8X1_OUT0_7_LUTOUT247)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_7_LUTOUT246 0x00400000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_7_LUTOUT246(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STG3_F8X1_OUT0_7_LUTOUT246)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_7_LUTOUT245 0x00200000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_7_LUTOUT245(v) \
+ (((v) << 21) & BM_PXP_WFE_B_STG3_F8X1_OUT0_7_LUTOUT245)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_7_LUTOUT244 0x00100000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_7_LUTOUT244(v) \
+ (((v) << 20) & BM_PXP_WFE_B_STG3_F8X1_OUT0_7_LUTOUT244)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_7_LUTOUT243 0x00080000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_7_LUTOUT243(v) \
+ (((v) << 19) & BM_PXP_WFE_B_STG3_F8X1_OUT0_7_LUTOUT243)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_7_LUTOUT242 0x00040000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_7_LUTOUT242(v) \
+ (((v) << 18) & BM_PXP_WFE_B_STG3_F8X1_OUT0_7_LUTOUT242)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_7_LUTOUT241 0x00020000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_7_LUTOUT241(v) \
+ (((v) << 17) & BM_PXP_WFE_B_STG3_F8X1_OUT0_7_LUTOUT241)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_7_LUTOUT240 0x00010000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_7_LUTOUT240(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STG3_F8X1_OUT0_7_LUTOUT240)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_7_LUTOUT239 0x00008000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_7_LUTOUT239(v) \
+ (((v) << 15) & BM_PXP_WFE_B_STG3_F8X1_OUT0_7_LUTOUT239)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_7_LUTOUT238 0x00004000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_7_LUTOUT238(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STG3_F8X1_OUT0_7_LUTOUT238)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_7_LUTOUT237 0x00002000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_7_LUTOUT237(v) \
+ (((v) << 13) & BM_PXP_WFE_B_STG3_F8X1_OUT0_7_LUTOUT237)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_7_LUTOUT236 0x00001000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_7_LUTOUT236(v) \
+ (((v) << 12) & BM_PXP_WFE_B_STG3_F8X1_OUT0_7_LUTOUT236)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_7_LUTOUT235 0x00000800
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_7_LUTOUT235(v) \
+ (((v) << 11) & BM_PXP_WFE_B_STG3_F8X1_OUT0_7_LUTOUT235)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_7_LUTOUT234 0x00000400
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_7_LUTOUT234(v) \
+ (((v) << 10) & BM_PXP_WFE_B_STG3_F8X1_OUT0_7_LUTOUT234)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_7_LUTOUT233 0x00000200
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_7_LUTOUT233(v) \
+ (((v) << 9) & BM_PXP_WFE_B_STG3_F8X1_OUT0_7_LUTOUT233)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_7_LUTOUT232 0x00000100
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_7_LUTOUT232(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STG3_F8X1_OUT0_7_LUTOUT232)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_7_LUTOUT231 0x00000080
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_7_LUTOUT231(v) \
+ (((v) << 7) & BM_PXP_WFE_B_STG3_F8X1_OUT0_7_LUTOUT231)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_7_LUTOUT230 0x00000040
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_7_LUTOUT230(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STG3_F8X1_OUT0_7_LUTOUT230)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_7_LUTOUT229 0x00000020
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_7_LUTOUT229(v) \
+ (((v) << 5) & BM_PXP_WFE_B_STG3_F8X1_OUT0_7_LUTOUT229)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_7_LUTOUT228 0x00000010
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_7_LUTOUT228(v) \
+ (((v) << 4) & BM_PXP_WFE_B_STG3_F8X1_OUT0_7_LUTOUT228)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_7_LUTOUT227 0x00000008
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_7_LUTOUT227(v) \
+ (((v) << 3) & BM_PXP_WFE_B_STG3_F8X1_OUT0_7_LUTOUT227)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_7_LUTOUT226 0x00000004
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_7_LUTOUT226(v) \
+ (((v) << 2) & BM_PXP_WFE_B_STG3_F8X1_OUT0_7_LUTOUT226)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_7_LUTOUT225 0x00000002
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_7_LUTOUT225(v) \
+ (((v) << 1) & BM_PXP_WFE_B_STG3_F8X1_OUT0_7_LUTOUT225)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT0_7_LUTOUT224 0x00000001
+#define BF_PXP_WFE_B_STG3_F8X1_OUT0_7_LUTOUT224(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STG3_F8X1_OUT0_7_LUTOUT224)
+
+#define HW_PXP_WFE_B_STG3_F8X1_OUT1_0 (0x00002610)
+
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_0_LUTOUT31 0x80000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_0_LUTOUT31(v) \
+ (((v) << 31) & BM_PXP_WFE_B_STG3_F8X1_OUT1_0_LUTOUT31)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_0_LUTOUT30 0x40000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_0_LUTOUT30(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STG3_F8X1_OUT1_0_LUTOUT30)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_0_LUTOUT29 0x20000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_0_LUTOUT29(v) \
+ (((v) << 29) & BM_PXP_WFE_B_STG3_F8X1_OUT1_0_LUTOUT29)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_0_LUTOUT28 0x10000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_0_LUTOUT28(v) \
+ (((v) << 28) & BM_PXP_WFE_B_STG3_F8X1_OUT1_0_LUTOUT28)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_0_LUTOUT27 0x08000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_0_LUTOUT27(v) \
+ (((v) << 27) & BM_PXP_WFE_B_STG3_F8X1_OUT1_0_LUTOUT27)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_0_LUTOUT26 0x04000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_0_LUTOUT26(v) \
+ (((v) << 26) & BM_PXP_WFE_B_STG3_F8X1_OUT1_0_LUTOUT26)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_0_LUTOUT25 0x02000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_0_LUTOUT25(v) \
+ (((v) << 25) & BM_PXP_WFE_B_STG3_F8X1_OUT1_0_LUTOUT25)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_0_LUTOUT24 0x01000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_0_LUTOUT24(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STG3_F8X1_OUT1_0_LUTOUT24)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_0_LUTOUT23 0x00800000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_0_LUTOUT23(v) \
+ (((v) << 23) & BM_PXP_WFE_B_STG3_F8X1_OUT1_0_LUTOUT23)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_0_LUTOUT22 0x00400000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_0_LUTOUT22(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STG3_F8X1_OUT1_0_LUTOUT22)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_0_LUTOUT21 0x00200000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_0_LUTOUT21(v) \
+ (((v) << 21) & BM_PXP_WFE_B_STG3_F8X1_OUT1_0_LUTOUT21)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_0_LUTOUT20 0x00100000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_0_LUTOUT20(v) \
+ (((v) << 20) & BM_PXP_WFE_B_STG3_F8X1_OUT1_0_LUTOUT20)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_0_LUTOUT19 0x00080000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_0_LUTOUT19(v) \
+ (((v) << 19) & BM_PXP_WFE_B_STG3_F8X1_OUT1_0_LUTOUT19)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_0_LUTOUT18 0x00040000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_0_LUTOUT18(v) \
+ (((v) << 18) & BM_PXP_WFE_B_STG3_F8X1_OUT1_0_LUTOUT18)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_0_LUTOUT17 0x00020000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_0_LUTOUT17(v) \
+ (((v) << 17) & BM_PXP_WFE_B_STG3_F8X1_OUT1_0_LUTOUT17)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_0_LUTOUT16 0x00010000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_0_LUTOUT16(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STG3_F8X1_OUT1_0_LUTOUT16)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_0_LUTOUT15 0x00008000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_0_LUTOUT15(v) \
+ (((v) << 15) & BM_PXP_WFE_B_STG3_F8X1_OUT1_0_LUTOUT15)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_0_LUTOUT14 0x00004000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_0_LUTOUT14(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STG3_F8X1_OUT1_0_LUTOUT14)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_0_LUTOUT13 0x00002000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_0_LUTOUT13(v) \
+ (((v) << 13) & BM_PXP_WFE_B_STG3_F8X1_OUT1_0_LUTOUT13)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_0_LUTOUT12 0x00001000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_0_LUTOUT12(v) \
+ (((v) << 12) & BM_PXP_WFE_B_STG3_F8X1_OUT1_0_LUTOUT12)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_0_LUTOUT11 0x00000800
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_0_LUTOUT11(v) \
+ (((v) << 11) & BM_PXP_WFE_B_STG3_F8X1_OUT1_0_LUTOUT11)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_0_LUTOUT10 0x00000400
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_0_LUTOUT10(v) \
+ (((v) << 10) & BM_PXP_WFE_B_STG3_F8X1_OUT1_0_LUTOUT10)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_0_LUTOUT9 0x00000200
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_0_LUTOUT9(v) \
+ (((v) << 9) & BM_PXP_WFE_B_STG3_F8X1_OUT1_0_LUTOUT9)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_0_LUTOUT8 0x00000100
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_0_LUTOUT8(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STG3_F8X1_OUT1_0_LUTOUT8)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_0_LUTOUT7 0x00000080
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_0_LUTOUT7(v) \
+ (((v) << 7) & BM_PXP_WFE_B_STG3_F8X1_OUT1_0_LUTOUT7)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_0_LUTOUT6 0x00000040
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_0_LUTOUT6(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STG3_F8X1_OUT1_0_LUTOUT6)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_0_LUTOUT5 0x00000020
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_0_LUTOUT5(v) \
+ (((v) << 5) & BM_PXP_WFE_B_STG3_F8X1_OUT1_0_LUTOUT5)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_0_LUTOUT4 0x00000010
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_0_LUTOUT4(v) \
+ (((v) << 4) & BM_PXP_WFE_B_STG3_F8X1_OUT1_0_LUTOUT4)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_0_LUTOUT3 0x00000008
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_0_LUTOUT3(v) \
+ (((v) << 3) & BM_PXP_WFE_B_STG3_F8X1_OUT1_0_LUTOUT3)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_0_LUTOUT2 0x00000004
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_0_LUTOUT2(v) \
+ (((v) << 2) & BM_PXP_WFE_B_STG3_F8X1_OUT1_0_LUTOUT2)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_0_LUTOUT1 0x00000002
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_0_LUTOUT1(v) \
+ (((v) << 1) & BM_PXP_WFE_B_STG3_F8X1_OUT1_0_LUTOUT1)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_0_LUTOUT0 0x00000001
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_0_LUTOUT0(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STG3_F8X1_OUT1_0_LUTOUT0)
+
+#define HW_PXP_WFE_B_STG3_F8X1_OUT1_1 (0x00002620)
+
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_1_LUTOUT63 0x80000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_1_LUTOUT63(v) \
+ (((v) << 31) & BM_PXP_WFE_B_STG3_F8X1_OUT1_1_LUTOUT63)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_1_LUTOUT62 0x40000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_1_LUTOUT62(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STG3_F8X1_OUT1_1_LUTOUT62)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_1_LUTOUT61 0x20000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_1_LUTOUT61(v) \
+ (((v) << 29) & BM_PXP_WFE_B_STG3_F8X1_OUT1_1_LUTOUT61)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_1_LUTOUT60 0x10000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_1_LUTOUT60(v) \
+ (((v) << 28) & BM_PXP_WFE_B_STG3_F8X1_OUT1_1_LUTOUT60)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_1_LUTOUT59 0x08000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_1_LUTOUT59(v) \
+ (((v) << 27) & BM_PXP_WFE_B_STG3_F8X1_OUT1_1_LUTOUT59)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_1_LUTOUT58 0x04000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_1_LUTOUT58(v) \
+ (((v) << 26) & BM_PXP_WFE_B_STG3_F8X1_OUT1_1_LUTOUT58)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_1_LUTOUT57 0x02000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_1_LUTOUT57(v) \
+ (((v) << 25) & BM_PXP_WFE_B_STG3_F8X1_OUT1_1_LUTOUT57)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_1_LUTOUT56 0x01000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_1_LUTOUT56(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STG3_F8X1_OUT1_1_LUTOUT56)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_1_LUTOUT55 0x00800000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_1_LUTOUT55(v) \
+ (((v) << 23) & BM_PXP_WFE_B_STG3_F8X1_OUT1_1_LUTOUT55)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_1_LUTOUT54 0x00400000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_1_LUTOUT54(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STG3_F8X1_OUT1_1_LUTOUT54)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_1_LUTOUT53 0x00200000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_1_LUTOUT53(v) \
+ (((v) << 21) & BM_PXP_WFE_B_STG3_F8X1_OUT1_1_LUTOUT53)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_1_LUTOUT52 0x00100000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_1_LUTOUT52(v) \
+ (((v) << 20) & BM_PXP_WFE_B_STG3_F8X1_OUT1_1_LUTOUT52)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_1_LUTOUT51 0x00080000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_1_LUTOUT51(v) \
+ (((v) << 19) & BM_PXP_WFE_B_STG3_F8X1_OUT1_1_LUTOUT51)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_1_LUTOUT50 0x00040000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_1_LUTOUT50(v) \
+ (((v) << 18) & BM_PXP_WFE_B_STG3_F8X1_OUT1_1_LUTOUT50)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_1_LUTOUT49 0x00020000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_1_LUTOUT49(v) \
+ (((v) << 17) & BM_PXP_WFE_B_STG3_F8X1_OUT1_1_LUTOUT49)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_1_LUTOUT48 0x00010000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_1_LUTOUT48(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STG3_F8X1_OUT1_1_LUTOUT48)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_1_LUTOUT47 0x00008000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_1_LUTOUT47(v) \
+ (((v) << 15) & BM_PXP_WFE_B_STG3_F8X1_OUT1_1_LUTOUT47)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_1_LUTOUT46 0x00004000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_1_LUTOUT46(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STG3_F8X1_OUT1_1_LUTOUT46)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_1_LUTOUT45 0x00002000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_1_LUTOUT45(v) \
+ (((v) << 13) & BM_PXP_WFE_B_STG3_F8X1_OUT1_1_LUTOUT45)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_1_LUTOUT44 0x00001000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_1_LUTOUT44(v) \
+ (((v) << 12) & BM_PXP_WFE_B_STG3_F8X1_OUT1_1_LUTOUT44)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_1_LUTOUT43 0x00000800
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_1_LUTOUT43(v) \
+ (((v) << 11) & BM_PXP_WFE_B_STG3_F8X1_OUT1_1_LUTOUT43)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_1_LUTOUT42 0x00000400
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_1_LUTOUT42(v) \
+ (((v) << 10) & BM_PXP_WFE_B_STG3_F8X1_OUT1_1_LUTOUT42)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_1_LUTOUT41 0x00000200
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_1_LUTOUT41(v) \
+ (((v) << 9) & BM_PXP_WFE_B_STG3_F8X1_OUT1_1_LUTOUT41)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_1_LUTOUT40 0x00000100
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_1_LUTOUT40(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STG3_F8X1_OUT1_1_LUTOUT40)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_1_LUTOUT39 0x00000080
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_1_LUTOUT39(v) \
+ (((v) << 7) & BM_PXP_WFE_B_STG3_F8X1_OUT1_1_LUTOUT39)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_1_LUTOUT38 0x00000040
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_1_LUTOUT38(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STG3_F8X1_OUT1_1_LUTOUT38)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_1_LUTOUT37 0x00000020
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_1_LUTOUT37(v) \
+ (((v) << 5) & BM_PXP_WFE_B_STG3_F8X1_OUT1_1_LUTOUT37)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_1_LUTOUT36 0x00000010
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_1_LUTOUT36(v) \
+ (((v) << 4) & BM_PXP_WFE_B_STG3_F8X1_OUT1_1_LUTOUT36)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_1_LUTOUT35 0x00000008
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_1_LUTOUT35(v) \
+ (((v) << 3) & BM_PXP_WFE_B_STG3_F8X1_OUT1_1_LUTOUT35)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_1_LUTOUT34 0x00000004
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_1_LUTOUT34(v) \
+ (((v) << 2) & BM_PXP_WFE_B_STG3_F8X1_OUT1_1_LUTOUT34)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_1_LUTOUT33 0x00000002
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_1_LUTOUT33(v) \
+ (((v) << 1) & BM_PXP_WFE_B_STG3_F8X1_OUT1_1_LUTOUT33)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_1_LUTOUT32 0x00000001
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_1_LUTOUT32(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STG3_F8X1_OUT1_1_LUTOUT32)
+
+#define HW_PXP_WFE_B_STG3_F8X1_OUT1_2 (0x00002630)
+
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_2_LUTOUT95 0x80000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_2_LUTOUT95(v) \
+ (((v) << 31) & BM_PXP_WFE_B_STG3_F8X1_OUT1_2_LUTOUT95)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_2_LUTOUT94 0x40000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_2_LUTOUT94(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STG3_F8X1_OUT1_2_LUTOUT94)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_2_LUTOUT93 0x20000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_2_LUTOUT93(v) \
+ (((v) << 29) & BM_PXP_WFE_B_STG3_F8X1_OUT1_2_LUTOUT93)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_2_LUTOUT92 0x10000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_2_LUTOUT92(v) \
+ (((v) << 28) & BM_PXP_WFE_B_STG3_F8X1_OUT1_2_LUTOUT92)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_2_LUTOUT91 0x08000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_2_LUTOUT91(v) \
+ (((v) << 27) & BM_PXP_WFE_B_STG3_F8X1_OUT1_2_LUTOUT91)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_2_LUTOUT90 0x04000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_2_LUTOUT90(v) \
+ (((v) << 26) & BM_PXP_WFE_B_STG3_F8X1_OUT1_2_LUTOUT90)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_2_LUTOUT89 0x02000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_2_LUTOUT89(v) \
+ (((v) << 25) & BM_PXP_WFE_B_STG3_F8X1_OUT1_2_LUTOUT89)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_2_LUTOUT88 0x01000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_2_LUTOUT88(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STG3_F8X1_OUT1_2_LUTOUT88)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_2_LUTOUT87 0x00800000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_2_LUTOUT87(v) \
+ (((v) << 23) & BM_PXP_WFE_B_STG3_F8X1_OUT1_2_LUTOUT87)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_2_LUTOUT86 0x00400000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_2_LUTOUT86(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STG3_F8X1_OUT1_2_LUTOUT86)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_2_LUTOUT85 0x00200000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_2_LUTOUT85(v) \
+ (((v) << 21) & BM_PXP_WFE_B_STG3_F8X1_OUT1_2_LUTOUT85)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_2_LUTOUT84 0x00100000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_2_LUTOUT84(v) \
+ (((v) << 20) & BM_PXP_WFE_B_STG3_F8X1_OUT1_2_LUTOUT84)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_2_LUTOUT83 0x00080000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_2_LUTOUT83(v) \
+ (((v) << 19) & BM_PXP_WFE_B_STG3_F8X1_OUT1_2_LUTOUT83)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_2_LUTOUT82 0x00040000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_2_LUTOUT82(v) \
+ (((v) << 18) & BM_PXP_WFE_B_STG3_F8X1_OUT1_2_LUTOUT82)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_2_LUTOUT81 0x00020000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_2_LUTOUT81(v) \
+ (((v) << 17) & BM_PXP_WFE_B_STG3_F8X1_OUT1_2_LUTOUT81)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_2_LUTOUT80 0x00010000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_2_LUTOUT80(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STG3_F8X1_OUT1_2_LUTOUT80)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_2_LUTOUT79 0x00008000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_2_LUTOUT79(v) \
+ (((v) << 15) & BM_PXP_WFE_B_STG3_F8X1_OUT1_2_LUTOUT79)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_2_LUTOUT78 0x00004000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_2_LUTOUT78(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STG3_F8X1_OUT1_2_LUTOUT78)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_2_LUTOUT77 0x00002000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_2_LUTOUT77(v) \
+ (((v) << 13) & BM_PXP_WFE_B_STG3_F8X1_OUT1_2_LUTOUT77)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_2_LUTOUT76 0x00001000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_2_LUTOUT76(v) \
+ (((v) << 12) & BM_PXP_WFE_B_STG3_F8X1_OUT1_2_LUTOUT76)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_2_LUTOUT75 0x00000800
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_2_LUTOUT75(v) \
+ (((v) << 11) & BM_PXP_WFE_B_STG3_F8X1_OUT1_2_LUTOUT75)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_2_LUTOUT74 0x00000400
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_2_LUTOUT74(v) \
+ (((v) << 10) & BM_PXP_WFE_B_STG3_F8X1_OUT1_2_LUTOUT74)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_2_LUTOUT73 0x00000200
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_2_LUTOUT73(v) \
+ (((v) << 9) & BM_PXP_WFE_B_STG3_F8X1_OUT1_2_LUTOUT73)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_2_LUTOUT72 0x00000100
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_2_LUTOUT72(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STG3_F8X1_OUT1_2_LUTOUT72)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_2_LUTOUT71 0x00000080
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_2_LUTOUT71(v) \
+ (((v) << 7) & BM_PXP_WFE_B_STG3_F8X1_OUT1_2_LUTOUT71)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_2_LUTOUT70 0x00000040
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_2_LUTOUT70(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STG3_F8X1_OUT1_2_LUTOUT70)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_2_LUTOUT69 0x00000020
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_2_LUTOUT69(v) \
+ (((v) << 5) & BM_PXP_WFE_B_STG3_F8X1_OUT1_2_LUTOUT69)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_2_LUTOUT68 0x00000010
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_2_LUTOUT68(v) \
+ (((v) << 4) & BM_PXP_WFE_B_STG3_F8X1_OUT1_2_LUTOUT68)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_2_LUTOUT67 0x00000008
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_2_LUTOUT67(v) \
+ (((v) << 3) & BM_PXP_WFE_B_STG3_F8X1_OUT1_2_LUTOUT67)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_2_LUTOUT66 0x00000004
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_2_LUTOUT66(v) \
+ (((v) << 2) & BM_PXP_WFE_B_STG3_F8X1_OUT1_2_LUTOUT66)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_2_LUTOUT65 0x00000002
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_2_LUTOUT65(v) \
+ (((v) << 1) & BM_PXP_WFE_B_STG3_F8X1_OUT1_2_LUTOUT65)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_2_LUTOUT64 0x00000001
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_2_LUTOUT64(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STG3_F8X1_OUT1_2_LUTOUT64)
+
+#define HW_PXP_WFE_B_STG3_F8X1_OUT1_3 (0x00002640)
+
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_3_LUTOUT127 0x80000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_3_LUTOUT127(v) \
+ (((v) << 31) & BM_PXP_WFE_B_STG3_F8X1_OUT1_3_LUTOUT127)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_3_LUTOUT126 0x40000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_3_LUTOUT126(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STG3_F8X1_OUT1_3_LUTOUT126)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_3_LUTOUT125 0x20000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_3_LUTOUT125(v) \
+ (((v) << 29) & BM_PXP_WFE_B_STG3_F8X1_OUT1_3_LUTOUT125)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_3_LUTOUT124 0x10000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_3_LUTOUT124(v) \
+ (((v) << 28) & BM_PXP_WFE_B_STG3_F8X1_OUT1_3_LUTOUT124)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_3_LUTOUT123 0x08000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_3_LUTOUT123(v) \
+ (((v) << 27) & BM_PXP_WFE_B_STG3_F8X1_OUT1_3_LUTOUT123)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_3_LUTOUT122 0x04000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_3_LUTOUT122(v) \
+ (((v) << 26) & BM_PXP_WFE_B_STG3_F8X1_OUT1_3_LUTOUT122)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_3_LUTOUT121 0x02000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_3_LUTOUT121(v) \
+ (((v) << 25) & BM_PXP_WFE_B_STG3_F8X1_OUT1_3_LUTOUT121)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_3_LUTOUT120 0x01000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_3_LUTOUT120(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STG3_F8X1_OUT1_3_LUTOUT120)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_3_LUTOUT119 0x00800000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_3_LUTOUT119(v) \
+ (((v) << 23) & BM_PXP_WFE_B_STG3_F8X1_OUT1_3_LUTOUT119)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_3_LUTOUT118 0x00400000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_3_LUTOUT118(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STG3_F8X1_OUT1_3_LUTOUT118)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_3_LUTOUT117 0x00200000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_3_LUTOUT117(v) \
+ (((v) << 21) & BM_PXP_WFE_B_STG3_F8X1_OUT1_3_LUTOUT117)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_3_LUTOUT116 0x00100000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_3_LUTOUT116(v) \
+ (((v) << 20) & BM_PXP_WFE_B_STG3_F8X1_OUT1_3_LUTOUT116)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_3_LUTOUT115 0x00080000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_3_LUTOUT115(v) \
+ (((v) << 19) & BM_PXP_WFE_B_STG3_F8X1_OUT1_3_LUTOUT115)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_3_LUTOUT114 0x00040000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_3_LUTOUT114(v) \
+ (((v) << 18) & BM_PXP_WFE_B_STG3_F8X1_OUT1_3_LUTOUT114)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_3_LUTOUT113 0x00020000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_3_LUTOUT113(v) \
+ (((v) << 17) & BM_PXP_WFE_B_STG3_F8X1_OUT1_3_LUTOUT113)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_3_LUTOUT112 0x00010000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_3_LUTOUT112(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STG3_F8X1_OUT1_3_LUTOUT112)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_3_LUTOUT111 0x00008000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_3_LUTOUT111(v) \
+ (((v) << 15) & BM_PXP_WFE_B_STG3_F8X1_OUT1_3_LUTOUT111)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_3_LUTOUT110 0x00004000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_3_LUTOUT110(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STG3_F8X1_OUT1_3_LUTOUT110)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_3_LUTOUT109 0x00002000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_3_LUTOUT109(v) \
+ (((v) << 13) & BM_PXP_WFE_B_STG3_F8X1_OUT1_3_LUTOUT109)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_3_LUTOUT108 0x00001000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_3_LUTOUT108(v) \
+ (((v) << 12) & BM_PXP_WFE_B_STG3_F8X1_OUT1_3_LUTOUT108)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_3_LUTOUT107 0x00000800
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_3_LUTOUT107(v) \
+ (((v) << 11) & BM_PXP_WFE_B_STG3_F8X1_OUT1_3_LUTOUT107)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_3_LUTOUT106 0x00000400
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_3_LUTOUT106(v) \
+ (((v) << 10) & BM_PXP_WFE_B_STG3_F8X1_OUT1_3_LUTOUT106)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_3_LUTOUT105 0x00000200
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_3_LUTOUT105(v) \
+ (((v) << 9) & BM_PXP_WFE_B_STG3_F8X1_OUT1_3_LUTOUT105)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_3_LUTOUT104 0x00000100
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_3_LUTOUT104(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STG3_F8X1_OUT1_3_LUTOUT104)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_3_LUTOUT103 0x00000080
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_3_LUTOUT103(v) \
+ (((v) << 7) & BM_PXP_WFE_B_STG3_F8X1_OUT1_3_LUTOUT103)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_3_LUTOUT102 0x00000040
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_3_LUTOUT102(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STG3_F8X1_OUT1_3_LUTOUT102)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_3_LUTOUT101 0x00000020
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_3_LUTOUT101(v) \
+ (((v) << 5) & BM_PXP_WFE_B_STG3_F8X1_OUT1_3_LUTOUT101)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_3_LUTOUT100 0x00000010
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_3_LUTOUT100(v) \
+ (((v) << 4) & BM_PXP_WFE_B_STG3_F8X1_OUT1_3_LUTOUT100)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_3_LUTOUT99 0x00000008
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_3_LUTOUT99(v) \
+ (((v) << 3) & BM_PXP_WFE_B_STG3_F8X1_OUT1_3_LUTOUT99)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_3_LUTOUT98 0x00000004
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_3_LUTOUT98(v) \
+ (((v) << 2) & BM_PXP_WFE_B_STG3_F8X1_OUT1_3_LUTOUT98)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_3_LUTOUT97 0x00000002
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_3_LUTOUT97(v) \
+ (((v) << 1) & BM_PXP_WFE_B_STG3_F8X1_OUT1_3_LUTOUT97)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_3_LUTOUT96 0x00000001
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_3_LUTOUT96(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STG3_F8X1_OUT1_3_LUTOUT96)
+
+#define HW_PXP_WFE_B_STG3_F8X1_OUT1_4 (0x00002650)
+
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_4_LUTOUT159 0x80000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_4_LUTOUT159(v) \
+ (((v) << 31) & BM_PXP_WFE_B_STG3_F8X1_OUT1_4_LUTOUT159)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_4_LUTOUT158 0x40000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_4_LUTOUT158(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STG3_F8X1_OUT1_4_LUTOUT158)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_4_LUTOUT157 0x20000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_4_LUTOUT157(v) \
+ (((v) << 29) & BM_PXP_WFE_B_STG3_F8X1_OUT1_4_LUTOUT157)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_4_LUTOUT156 0x10000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_4_LUTOUT156(v) \
+ (((v) << 28) & BM_PXP_WFE_B_STG3_F8X1_OUT1_4_LUTOUT156)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_4_LUTOUT155 0x08000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_4_LUTOUT155(v) \
+ (((v) << 27) & BM_PXP_WFE_B_STG3_F8X1_OUT1_4_LUTOUT155)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_4_LUTOUT154 0x04000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_4_LUTOUT154(v) \
+ (((v) << 26) & BM_PXP_WFE_B_STG3_F8X1_OUT1_4_LUTOUT154)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_4_LUTOUT153 0x02000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_4_LUTOUT153(v) \
+ (((v) << 25) & BM_PXP_WFE_B_STG3_F8X1_OUT1_4_LUTOUT153)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_4_LUTOUT152 0x01000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_4_LUTOUT152(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STG3_F8X1_OUT1_4_LUTOUT152)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_4_LUTOUT151 0x00800000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_4_LUTOUT151(v) \
+ (((v) << 23) & BM_PXP_WFE_B_STG3_F8X1_OUT1_4_LUTOUT151)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_4_LUTOUT150 0x00400000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_4_LUTOUT150(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STG3_F8X1_OUT1_4_LUTOUT150)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_4_LUTOUT149 0x00200000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_4_LUTOUT149(v) \
+ (((v) << 21) & BM_PXP_WFE_B_STG3_F8X1_OUT1_4_LUTOUT149)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_4_LUTOUT148 0x00100000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_4_LUTOUT148(v) \
+ (((v) << 20) & BM_PXP_WFE_B_STG3_F8X1_OUT1_4_LUTOUT148)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_4_LUTOUT147 0x00080000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_4_LUTOUT147(v) \
+ (((v) << 19) & BM_PXP_WFE_B_STG3_F8X1_OUT1_4_LUTOUT147)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_4_LUTOUT146 0x00040000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_4_LUTOUT146(v) \
+ (((v) << 18) & BM_PXP_WFE_B_STG3_F8X1_OUT1_4_LUTOUT146)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_4_LUTOUT145 0x00020000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_4_LUTOUT145(v) \
+ (((v) << 17) & BM_PXP_WFE_B_STG3_F8X1_OUT1_4_LUTOUT145)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_4_LUTOUT144 0x00010000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_4_LUTOUT144(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STG3_F8X1_OUT1_4_LUTOUT144)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_4_LUTOUT143 0x00008000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_4_LUTOUT143(v) \
+ (((v) << 15) & BM_PXP_WFE_B_STG3_F8X1_OUT1_4_LUTOUT143)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_4_LUTOUT142 0x00004000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_4_LUTOUT142(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STG3_F8X1_OUT1_4_LUTOUT142)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_4_LUTOUT141 0x00002000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_4_LUTOUT141(v) \
+ (((v) << 13) & BM_PXP_WFE_B_STG3_F8X1_OUT1_4_LUTOUT141)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_4_LUTOUT140 0x00001000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_4_LUTOUT140(v) \
+ (((v) << 12) & BM_PXP_WFE_B_STG3_F8X1_OUT1_4_LUTOUT140)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_4_LUTOUT139 0x00000800
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_4_LUTOUT139(v) \
+ (((v) << 11) & BM_PXP_WFE_B_STG3_F8X1_OUT1_4_LUTOUT139)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_4_LUTOUT138 0x00000400
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_4_LUTOUT138(v) \
+ (((v) << 10) & BM_PXP_WFE_B_STG3_F8X1_OUT1_4_LUTOUT138)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_4_LUTOUT137 0x00000200
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_4_LUTOUT137(v) \
+ (((v) << 9) & BM_PXP_WFE_B_STG3_F8X1_OUT1_4_LUTOUT137)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_4_LUTOUT136 0x00000100
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_4_LUTOUT136(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STG3_F8X1_OUT1_4_LUTOUT136)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_4_LUTOUT135 0x00000080
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_4_LUTOUT135(v) \
+ (((v) << 7) & BM_PXP_WFE_B_STG3_F8X1_OUT1_4_LUTOUT135)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_4_LUTOUT134 0x00000040
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_4_LUTOUT134(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STG3_F8X1_OUT1_4_LUTOUT134)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_4_LUTOUT133 0x00000020
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_4_LUTOUT133(v) \
+ (((v) << 5) & BM_PXP_WFE_B_STG3_F8X1_OUT1_4_LUTOUT133)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_4_LUTOUT132 0x00000010
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_4_LUTOUT132(v) \
+ (((v) << 4) & BM_PXP_WFE_B_STG3_F8X1_OUT1_4_LUTOUT132)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_4_LUTOUT131 0x00000008
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_4_LUTOUT131(v) \
+ (((v) << 3) & BM_PXP_WFE_B_STG3_F8X1_OUT1_4_LUTOUT131)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_4_LUTOUT130 0x00000004
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_4_LUTOUT130(v) \
+ (((v) << 2) & BM_PXP_WFE_B_STG3_F8X1_OUT1_4_LUTOUT130)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_4_LUTOUT129 0x00000002
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_4_LUTOUT129(v) \
+ (((v) << 1) & BM_PXP_WFE_B_STG3_F8X1_OUT1_4_LUTOUT129)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_4_LUTOUT128 0x00000001
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_4_LUTOUT128(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STG3_F8X1_OUT1_4_LUTOUT128)
+
+#define HW_PXP_WFE_B_STG3_F8X1_OUT1_5 (0x00002660)
+
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_5_LUTOUT191 0x80000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_5_LUTOUT191(v) \
+ (((v) << 31) & BM_PXP_WFE_B_STG3_F8X1_OUT1_5_LUTOUT191)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_5_LUTOUT190 0x40000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_5_LUTOUT190(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STG3_F8X1_OUT1_5_LUTOUT190)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_5_LUTOUT189 0x20000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_5_LUTOUT189(v) \
+ (((v) << 29) & BM_PXP_WFE_B_STG3_F8X1_OUT1_5_LUTOUT189)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_5_LUTOUT188 0x10000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_5_LUTOUT188(v) \
+ (((v) << 28) & BM_PXP_WFE_B_STG3_F8X1_OUT1_5_LUTOUT188)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_5_LUTOUT187 0x08000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_5_LUTOUT187(v) \
+ (((v) << 27) & BM_PXP_WFE_B_STG3_F8X1_OUT1_5_LUTOUT187)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_5_LUTOUT186 0x04000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_5_LUTOUT186(v) \
+ (((v) << 26) & BM_PXP_WFE_B_STG3_F8X1_OUT1_5_LUTOUT186)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_5_LUTOUT185 0x02000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_5_LUTOUT185(v) \
+ (((v) << 25) & BM_PXP_WFE_B_STG3_F8X1_OUT1_5_LUTOUT185)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_5_LUTOUT184 0x01000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_5_LUTOUT184(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STG3_F8X1_OUT1_5_LUTOUT184)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_5_LUTOUT183 0x00800000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_5_LUTOUT183(v) \
+ (((v) << 23) & BM_PXP_WFE_B_STG3_F8X1_OUT1_5_LUTOUT183)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_5_LUTOUT182 0x00400000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_5_LUTOUT182(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STG3_F8X1_OUT1_5_LUTOUT182)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_5_LUTOUT181 0x00200000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_5_LUTOUT181(v) \
+ (((v) << 21) & BM_PXP_WFE_B_STG3_F8X1_OUT1_5_LUTOUT181)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_5_LUTOUT180 0x00100000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_5_LUTOUT180(v) \
+ (((v) << 20) & BM_PXP_WFE_B_STG3_F8X1_OUT1_5_LUTOUT180)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_5_LUTOUT179 0x00080000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_5_LUTOUT179(v) \
+ (((v) << 19) & BM_PXP_WFE_B_STG3_F8X1_OUT1_5_LUTOUT179)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_5_LUTOUT178 0x00040000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_5_LUTOUT178(v) \
+ (((v) << 18) & BM_PXP_WFE_B_STG3_F8X1_OUT1_5_LUTOUT178)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_5_LUTOUT177 0x00020000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_5_LUTOUT177(v) \
+ (((v) << 17) & BM_PXP_WFE_B_STG3_F8X1_OUT1_5_LUTOUT177)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_5_LUTOUT176 0x00010000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_5_LUTOUT176(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STG3_F8X1_OUT1_5_LUTOUT176)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_5_LUTOUT175 0x00008000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_5_LUTOUT175(v) \
+ (((v) << 15) & BM_PXP_WFE_B_STG3_F8X1_OUT1_5_LUTOUT175)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_5_LUTOUT174 0x00004000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_5_LUTOUT174(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STG3_F8X1_OUT1_5_LUTOUT174)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_5_LUTOUT173 0x00002000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_5_LUTOUT173(v) \
+ (((v) << 13) & BM_PXP_WFE_B_STG3_F8X1_OUT1_5_LUTOUT173)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_5_LUTOUT172 0x00001000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_5_LUTOUT172(v) \
+ (((v) << 12) & BM_PXP_WFE_B_STG3_F8X1_OUT1_5_LUTOUT172)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_5_LUTOUT171 0x00000800
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_5_LUTOUT171(v) \
+ (((v) << 11) & BM_PXP_WFE_B_STG3_F8X1_OUT1_5_LUTOUT171)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_5_LUTOUT170 0x00000400
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_5_LUTOUT170(v) \
+ (((v) << 10) & BM_PXP_WFE_B_STG3_F8X1_OUT1_5_LUTOUT170)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_5_LUTOUT169 0x00000200
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_5_LUTOUT169(v) \
+ (((v) << 9) & BM_PXP_WFE_B_STG3_F8X1_OUT1_5_LUTOUT169)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_5_LUTOUT168 0x00000100
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_5_LUTOUT168(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STG3_F8X1_OUT1_5_LUTOUT168)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_5_LUTOUT167 0x00000080
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_5_LUTOUT167(v) \
+ (((v) << 7) & BM_PXP_WFE_B_STG3_F8X1_OUT1_5_LUTOUT167)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_5_LUTOUT166 0x00000040
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_5_LUTOUT166(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STG3_F8X1_OUT1_5_LUTOUT166)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_5_LUTOUT165 0x00000020
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_5_LUTOUT165(v) \
+ (((v) << 5) & BM_PXP_WFE_B_STG3_F8X1_OUT1_5_LUTOUT165)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_5_LUTOUT164 0x00000010
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_5_LUTOUT164(v) \
+ (((v) << 4) & BM_PXP_WFE_B_STG3_F8X1_OUT1_5_LUTOUT164)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_5_LUTOUT163 0x00000008
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_5_LUTOUT163(v) \
+ (((v) << 3) & BM_PXP_WFE_B_STG3_F8X1_OUT1_5_LUTOUT163)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_5_LUTOUT162 0x00000004
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_5_LUTOUT162(v) \
+ (((v) << 2) & BM_PXP_WFE_B_STG3_F8X1_OUT1_5_LUTOUT162)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_5_LUTOUT161 0x00000002
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_5_LUTOUT161(v) \
+ (((v) << 1) & BM_PXP_WFE_B_STG3_F8X1_OUT1_5_LUTOUT161)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_5_LUTOUT160 0x00000001
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_5_LUTOUT160(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STG3_F8X1_OUT1_5_LUTOUT160)
+
+#define HW_PXP_WFE_B_STG3_F8X1_OUT1_6 (0x00002670)
+
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_6_LUTOUT223 0x80000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_6_LUTOUT223(v) \
+ (((v) << 31) & BM_PXP_WFE_B_STG3_F8X1_OUT1_6_LUTOUT223)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_6_LUTOUT222 0x40000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_6_LUTOUT222(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STG3_F8X1_OUT1_6_LUTOUT222)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_6_LUTOUT221 0x20000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_6_LUTOUT221(v) \
+ (((v) << 29) & BM_PXP_WFE_B_STG3_F8X1_OUT1_6_LUTOUT221)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_6_LUTOUT220 0x10000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_6_LUTOUT220(v) \
+ (((v) << 28) & BM_PXP_WFE_B_STG3_F8X1_OUT1_6_LUTOUT220)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_6_LUTOUT219 0x08000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_6_LUTOUT219(v) \
+ (((v) << 27) & BM_PXP_WFE_B_STG3_F8X1_OUT1_6_LUTOUT219)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_6_LUTOUT218 0x04000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_6_LUTOUT218(v) \
+ (((v) << 26) & BM_PXP_WFE_B_STG3_F8X1_OUT1_6_LUTOUT218)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_6_LUTOUT217 0x02000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_6_LUTOUT217(v) \
+ (((v) << 25) & BM_PXP_WFE_B_STG3_F8X1_OUT1_6_LUTOUT217)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_6_LUTOUT216 0x01000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_6_LUTOUT216(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STG3_F8X1_OUT1_6_LUTOUT216)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_6_LUTOUT215 0x00800000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_6_LUTOUT215(v) \
+ (((v) << 23) & BM_PXP_WFE_B_STG3_F8X1_OUT1_6_LUTOUT215)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_6_LUTOUT214 0x00400000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_6_LUTOUT214(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STG3_F8X1_OUT1_6_LUTOUT214)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_6_LUTOUT213 0x00200000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_6_LUTOUT213(v) \
+ (((v) << 21) & BM_PXP_WFE_B_STG3_F8X1_OUT1_6_LUTOUT213)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_6_LUTOUT212 0x00100000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_6_LUTOUT212(v) \
+ (((v) << 20) & BM_PXP_WFE_B_STG3_F8X1_OUT1_6_LUTOUT212)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_6_LUTOUT211 0x00080000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_6_LUTOUT211(v) \
+ (((v) << 19) & BM_PXP_WFE_B_STG3_F8X1_OUT1_6_LUTOUT211)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_6_LUTOUT210 0x00040000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_6_LUTOUT210(v) \
+ (((v) << 18) & BM_PXP_WFE_B_STG3_F8X1_OUT1_6_LUTOUT210)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_6_LUTOUT209 0x00020000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_6_LUTOUT209(v) \
+ (((v) << 17) & BM_PXP_WFE_B_STG3_F8X1_OUT1_6_LUTOUT209)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_6_LUTOUT208 0x00010000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_6_LUTOUT208(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STG3_F8X1_OUT1_6_LUTOUT208)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_6_LUTOUT207 0x00008000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_6_LUTOUT207(v) \
+ (((v) << 15) & BM_PXP_WFE_B_STG3_F8X1_OUT1_6_LUTOUT207)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_6_LUTOUT206 0x00004000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_6_LUTOUT206(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STG3_F8X1_OUT1_6_LUTOUT206)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_6_LUTOUT205 0x00002000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_6_LUTOUT205(v) \
+ (((v) << 13) & BM_PXP_WFE_B_STG3_F8X1_OUT1_6_LUTOUT205)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_6_LUTOUT204 0x00001000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_6_LUTOUT204(v) \
+ (((v) << 12) & BM_PXP_WFE_B_STG3_F8X1_OUT1_6_LUTOUT204)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_6_LUTOUT203 0x00000800
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_6_LUTOUT203(v) \
+ (((v) << 11) & BM_PXP_WFE_B_STG3_F8X1_OUT1_6_LUTOUT203)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_6_LUTOUT202 0x00000400
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_6_LUTOUT202(v) \
+ (((v) << 10) & BM_PXP_WFE_B_STG3_F8X1_OUT1_6_LUTOUT202)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_6_LUTOUT201 0x00000200
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_6_LUTOUT201(v) \
+ (((v) << 9) & BM_PXP_WFE_B_STG3_F8X1_OUT1_6_LUTOUT201)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_6_LUTOUT200 0x00000100
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_6_LUTOUT200(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STG3_F8X1_OUT1_6_LUTOUT200)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_6_LUTOUT199 0x00000080
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_6_LUTOUT199(v) \
+ (((v) << 7) & BM_PXP_WFE_B_STG3_F8X1_OUT1_6_LUTOUT199)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_6_LUTOUT198 0x00000040
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_6_LUTOUT198(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STG3_F8X1_OUT1_6_LUTOUT198)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_6_LUTOUT197 0x00000020
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_6_LUTOUT197(v) \
+ (((v) << 5) & BM_PXP_WFE_B_STG3_F8X1_OUT1_6_LUTOUT197)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_6_LUTOUT196 0x00000010
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_6_LUTOUT196(v) \
+ (((v) << 4) & BM_PXP_WFE_B_STG3_F8X1_OUT1_6_LUTOUT196)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_6_LUTOUT195 0x00000008
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_6_LUTOUT195(v) \
+ (((v) << 3) & BM_PXP_WFE_B_STG3_F8X1_OUT1_6_LUTOUT195)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_6_LUTOUT194 0x00000004
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_6_LUTOUT194(v) \
+ (((v) << 2) & BM_PXP_WFE_B_STG3_F8X1_OUT1_6_LUTOUT194)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_6_LUTOUT193 0x00000002
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_6_LUTOUT193(v) \
+ (((v) << 1) & BM_PXP_WFE_B_STG3_F8X1_OUT1_6_LUTOUT193)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_6_LUTOUT192 0x00000001
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_6_LUTOUT192(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STG3_F8X1_OUT1_6_LUTOUT192)
+
+#define HW_PXP_WFE_B_STG3_F8X1_OUT1_7 (0x00002680)
+
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_7_LUTOUT255 0x80000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_7_LUTOUT255(v) \
+ (((v) << 31) & BM_PXP_WFE_B_STG3_F8X1_OUT1_7_LUTOUT255)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_7_LUTOUT254 0x40000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_7_LUTOUT254(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STG3_F8X1_OUT1_7_LUTOUT254)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_7_LUTOUT253 0x20000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_7_LUTOUT253(v) \
+ (((v) << 29) & BM_PXP_WFE_B_STG3_F8X1_OUT1_7_LUTOUT253)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_7_LUTOUT252 0x10000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_7_LUTOUT252(v) \
+ (((v) << 28) & BM_PXP_WFE_B_STG3_F8X1_OUT1_7_LUTOUT252)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_7_LUTOUT251 0x08000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_7_LUTOUT251(v) \
+ (((v) << 27) & BM_PXP_WFE_B_STG3_F8X1_OUT1_7_LUTOUT251)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_7_LUTOUT250 0x04000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_7_LUTOUT250(v) \
+ (((v) << 26) & BM_PXP_WFE_B_STG3_F8X1_OUT1_7_LUTOUT250)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_7_LUTOUT249 0x02000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_7_LUTOUT249(v) \
+ (((v) << 25) & BM_PXP_WFE_B_STG3_F8X1_OUT1_7_LUTOUT249)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_7_LUTOUT248 0x01000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_7_LUTOUT248(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STG3_F8X1_OUT1_7_LUTOUT248)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_7_LUTOUT247 0x00800000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_7_LUTOUT247(v) \
+ (((v) << 23) & BM_PXP_WFE_B_STG3_F8X1_OUT1_7_LUTOUT247)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_7_LUTOUT246 0x00400000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_7_LUTOUT246(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STG3_F8X1_OUT1_7_LUTOUT246)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_7_LUTOUT245 0x00200000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_7_LUTOUT245(v) \
+ (((v) << 21) & BM_PXP_WFE_B_STG3_F8X1_OUT1_7_LUTOUT245)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_7_LUTOUT244 0x00100000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_7_LUTOUT244(v) \
+ (((v) << 20) & BM_PXP_WFE_B_STG3_F8X1_OUT1_7_LUTOUT244)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_7_LUTOUT243 0x00080000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_7_LUTOUT243(v) \
+ (((v) << 19) & BM_PXP_WFE_B_STG3_F8X1_OUT1_7_LUTOUT243)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_7_LUTOUT242 0x00040000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_7_LUTOUT242(v) \
+ (((v) << 18) & BM_PXP_WFE_B_STG3_F8X1_OUT1_7_LUTOUT242)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_7_LUTOUT241 0x00020000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_7_LUTOUT241(v) \
+ (((v) << 17) & BM_PXP_WFE_B_STG3_F8X1_OUT1_7_LUTOUT241)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_7_LUTOUT240 0x00010000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_7_LUTOUT240(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STG3_F8X1_OUT1_7_LUTOUT240)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_7_LUTOUT239 0x00008000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_7_LUTOUT239(v) \
+ (((v) << 15) & BM_PXP_WFE_B_STG3_F8X1_OUT1_7_LUTOUT239)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_7_LUTOUT238 0x00004000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_7_LUTOUT238(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STG3_F8X1_OUT1_7_LUTOUT238)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_7_LUTOUT237 0x00002000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_7_LUTOUT237(v) \
+ (((v) << 13) & BM_PXP_WFE_B_STG3_F8X1_OUT1_7_LUTOUT237)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_7_LUTOUT236 0x00001000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_7_LUTOUT236(v) \
+ (((v) << 12) & BM_PXP_WFE_B_STG3_F8X1_OUT1_7_LUTOUT236)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_7_LUTOUT235 0x00000800
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_7_LUTOUT235(v) \
+ (((v) << 11) & BM_PXP_WFE_B_STG3_F8X1_OUT1_7_LUTOUT235)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_7_LUTOUT234 0x00000400
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_7_LUTOUT234(v) \
+ (((v) << 10) & BM_PXP_WFE_B_STG3_F8X1_OUT1_7_LUTOUT234)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_7_LUTOUT233 0x00000200
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_7_LUTOUT233(v) \
+ (((v) << 9) & BM_PXP_WFE_B_STG3_F8X1_OUT1_7_LUTOUT233)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_7_LUTOUT232 0x00000100
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_7_LUTOUT232(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STG3_F8X1_OUT1_7_LUTOUT232)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_7_LUTOUT231 0x00000080
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_7_LUTOUT231(v) \
+ (((v) << 7) & BM_PXP_WFE_B_STG3_F8X1_OUT1_7_LUTOUT231)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_7_LUTOUT230 0x00000040
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_7_LUTOUT230(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STG3_F8X1_OUT1_7_LUTOUT230)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_7_LUTOUT229 0x00000020
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_7_LUTOUT229(v) \
+ (((v) << 5) & BM_PXP_WFE_B_STG3_F8X1_OUT1_7_LUTOUT229)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_7_LUTOUT228 0x00000010
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_7_LUTOUT228(v) \
+ (((v) << 4) & BM_PXP_WFE_B_STG3_F8X1_OUT1_7_LUTOUT228)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_7_LUTOUT227 0x00000008
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_7_LUTOUT227(v) \
+ (((v) << 3) & BM_PXP_WFE_B_STG3_F8X1_OUT1_7_LUTOUT227)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_7_LUTOUT226 0x00000004
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_7_LUTOUT226(v) \
+ (((v) << 2) & BM_PXP_WFE_B_STG3_F8X1_OUT1_7_LUTOUT226)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_7_LUTOUT225 0x00000002
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_7_LUTOUT225(v) \
+ (((v) << 1) & BM_PXP_WFE_B_STG3_F8X1_OUT1_7_LUTOUT225)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT1_7_LUTOUT224 0x00000001
+#define BF_PXP_WFE_B_STG3_F8X1_OUT1_7_LUTOUT224(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STG3_F8X1_OUT1_7_LUTOUT224)
+
+#define HW_PXP_WFE_B_STG3_F8X1_OUT2_0 (0x00002690)
+
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_0_LUTOUT31 0x80000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_0_LUTOUT31(v) \
+ (((v) << 31) & BM_PXP_WFE_B_STG3_F8X1_OUT2_0_LUTOUT31)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_0_LUTOUT30 0x40000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_0_LUTOUT30(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STG3_F8X1_OUT2_0_LUTOUT30)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_0_LUTOUT29 0x20000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_0_LUTOUT29(v) \
+ (((v) << 29) & BM_PXP_WFE_B_STG3_F8X1_OUT2_0_LUTOUT29)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_0_LUTOUT28 0x10000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_0_LUTOUT28(v) \
+ (((v) << 28) & BM_PXP_WFE_B_STG3_F8X1_OUT2_0_LUTOUT28)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_0_LUTOUT27 0x08000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_0_LUTOUT27(v) \
+ (((v) << 27) & BM_PXP_WFE_B_STG3_F8X1_OUT2_0_LUTOUT27)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_0_LUTOUT26 0x04000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_0_LUTOUT26(v) \
+ (((v) << 26) & BM_PXP_WFE_B_STG3_F8X1_OUT2_0_LUTOUT26)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_0_LUTOUT25 0x02000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_0_LUTOUT25(v) \
+ (((v) << 25) & BM_PXP_WFE_B_STG3_F8X1_OUT2_0_LUTOUT25)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_0_LUTOUT24 0x01000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_0_LUTOUT24(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STG3_F8X1_OUT2_0_LUTOUT24)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_0_LUTOUT23 0x00800000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_0_LUTOUT23(v) \
+ (((v) << 23) & BM_PXP_WFE_B_STG3_F8X1_OUT2_0_LUTOUT23)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_0_LUTOUT22 0x00400000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_0_LUTOUT22(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STG3_F8X1_OUT2_0_LUTOUT22)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_0_LUTOUT21 0x00200000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_0_LUTOUT21(v) \
+ (((v) << 21) & BM_PXP_WFE_B_STG3_F8X1_OUT2_0_LUTOUT21)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_0_LUTOUT20 0x00100000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_0_LUTOUT20(v) \
+ (((v) << 20) & BM_PXP_WFE_B_STG3_F8X1_OUT2_0_LUTOUT20)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_0_LUTOUT19 0x00080000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_0_LUTOUT19(v) \
+ (((v) << 19) & BM_PXP_WFE_B_STG3_F8X1_OUT2_0_LUTOUT19)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_0_LUTOUT18 0x00040000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_0_LUTOUT18(v) \
+ (((v) << 18) & BM_PXP_WFE_B_STG3_F8X1_OUT2_0_LUTOUT18)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_0_LUTOUT17 0x00020000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_0_LUTOUT17(v) \
+ (((v) << 17) & BM_PXP_WFE_B_STG3_F8X1_OUT2_0_LUTOUT17)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_0_LUTOUT16 0x00010000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_0_LUTOUT16(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STG3_F8X1_OUT2_0_LUTOUT16)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_0_LUTOUT15 0x00008000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_0_LUTOUT15(v) \
+ (((v) << 15) & BM_PXP_WFE_B_STG3_F8X1_OUT2_0_LUTOUT15)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_0_LUTOUT14 0x00004000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_0_LUTOUT14(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STG3_F8X1_OUT2_0_LUTOUT14)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_0_LUTOUT13 0x00002000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_0_LUTOUT13(v) \
+ (((v) << 13) & BM_PXP_WFE_B_STG3_F8X1_OUT2_0_LUTOUT13)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_0_LUTOUT12 0x00001000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_0_LUTOUT12(v) \
+ (((v) << 12) & BM_PXP_WFE_B_STG3_F8X1_OUT2_0_LUTOUT12)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_0_LUTOUT11 0x00000800
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_0_LUTOUT11(v) \
+ (((v) << 11) & BM_PXP_WFE_B_STG3_F8X1_OUT2_0_LUTOUT11)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_0_LUTOUT10 0x00000400
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_0_LUTOUT10(v) \
+ (((v) << 10) & BM_PXP_WFE_B_STG3_F8X1_OUT2_0_LUTOUT10)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_0_LUTOUT9 0x00000200
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_0_LUTOUT9(v) \
+ (((v) << 9) & BM_PXP_WFE_B_STG3_F8X1_OUT2_0_LUTOUT9)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_0_LUTOUT8 0x00000100
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_0_LUTOUT8(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STG3_F8X1_OUT2_0_LUTOUT8)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_0_LUTOUT7 0x00000080
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_0_LUTOUT7(v) \
+ (((v) << 7) & BM_PXP_WFE_B_STG3_F8X1_OUT2_0_LUTOUT7)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_0_LUTOUT6 0x00000040
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_0_LUTOUT6(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STG3_F8X1_OUT2_0_LUTOUT6)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_0_LUTOUT5 0x00000020
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_0_LUTOUT5(v) \
+ (((v) << 5) & BM_PXP_WFE_B_STG3_F8X1_OUT2_0_LUTOUT5)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_0_LUTOUT4 0x00000010
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_0_LUTOUT4(v) \
+ (((v) << 4) & BM_PXP_WFE_B_STG3_F8X1_OUT2_0_LUTOUT4)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_0_LUTOUT3 0x00000008
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_0_LUTOUT3(v) \
+ (((v) << 3) & BM_PXP_WFE_B_STG3_F8X1_OUT2_0_LUTOUT3)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_0_LUTOUT2 0x00000004
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_0_LUTOUT2(v) \
+ (((v) << 2) & BM_PXP_WFE_B_STG3_F8X1_OUT2_0_LUTOUT2)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_0_LUTOUT1 0x00000002
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_0_LUTOUT1(v) \
+ (((v) << 1) & BM_PXP_WFE_B_STG3_F8X1_OUT2_0_LUTOUT1)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_0_LUTOUT0 0x00000001
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_0_LUTOUT0(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STG3_F8X1_OUT2_0_LUTOUT0)
+
+#define HW_PXP_WFE_B_STG3_F8X1_OUT2_1 (0x000026a0)
+
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_1_LUTOUT63 0x80000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_1_LUTOUT63(v) \
+ (((v) << 31) & BM_PXP_WFE_B_STG3_F8X1_OUT2_1_LUTOUT63)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_1_LUTOUT62 0x40000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_1_LUTOUT62(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STG3_F8X1_OUT2_1_LUTOUT62)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_1_LUTOUT61 0x20000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_1_LUTOUT61(v) \
+ (((v) << 29) & BM_PXP_WFE_B_STG3_F8X1_OUT2_1_LUTOUT61)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_1_LUTOUT60 0x10000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_1_LUTOUT60(v) \
+ (((v) << 28) & BM_PXP_WFE_B_STG3_F8X1_OUT2_1_LUTOUT60)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_1_LUTOUT59 0x08000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_1_LUTOUT59(v) \
+ (((v) << 27) & BM_PXP_WFE_B_STG3_F8X1_OUT2_1_LUTOUT59)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_1_LUTOUT58 0x04000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_1_LUTOUT58(v) \
+ (((v) << 26) & BM_PXP_WFE_B_STG3_F8X1_OUT2_1_LUTOUT58)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_1_LUTOUT57 0x02000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_1_LUTOUT57(v) \
+ (((v) << 25) & BM_PXP_WFE_B_STG3_F8X1_OUT2_1_LUTOUT57)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_1_LUTOUT56 0x01000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_1_LUTOUT56(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STG3_F8X1_OUT2_1_LUTOUT56)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_1_LUTOUT55 0x00800000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_1_LUTOUT55(v) \
+ (((v) << 23) & BM_PXP_WFE_B_STG3_F8X1_OUT2_1_LUTOUT55)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_1_LUTOUT54 0x00400000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_1_LUTOUT54(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STG3_F8X1_OUT2_1_LUTOUT54)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_1_LUTOUT53 0x00200000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_1_LUTOUT53(v) \
+ (((v) << 21) & BM_PXP_WFE_B_STG3_F8X1_OUT2_1_LUTOUT53)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_1_LUTOUT52 0x00100000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_1_LUTOUT52(v) \
+ (((v) << 20) & BM_PXP_WFE_B_STG3_F8X1_OUT2_1_LUTOUT52)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_1_LUTOUT51 0x00080000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_1_LUTOUT51(v) \
+ (((v) << 19) & BM_PXP_WFE_B_STG3_F8X1_OUT2_1_LUTOUT51)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_1_LUTOUT50 0x00040000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_1_LUTOUT50(v) \
+ (((v) << 18) & BM_PXP_WFE_B_STG3_F8X1_OUT2_1_LUTOUT50)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_1_LUTOUT49 0x00020000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_1_LUTOUT49(v) \
+ (((v) << 17) & BM_PXP_WFE_B_STG3_F8X1_OUT2_1_LUTOUT49)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_1_LUTOUT48 0x00010000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_1_LUTOUT48(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STG3_F8X1_OUT2_1_LUTOUT48)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_1_LUTOUT47 0x00008000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_1_LUTOUT47(v) \
+ (((v) << 15) & BM_PXP_WFE_B_STG3_F8X1_OUT2_1_LUTOUT47)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_1_LUTOUT46 0x00004000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_1_LUTOUT46(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STG3_F8X1_OUT2_1_LUTOUT46)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_1_LUTOUT45 0x00002000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_1_LUTOUT45(v) \
+ (((v) << 13) & BM_PXP_WFE_B_STG3_F8X1_OUT2_1_LUTOUT45)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_1_LUTOUT44 0x00001000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_1_LUTOUT44(v) \
+ (((v) << 12) & BM_PXP_WFE_B_STG3_F8X1_OUT2_1_LUTOUT44)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_1_LUTOUT43 0x00000800
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_1_LUTOUT43(v) \
+ (((v) << 11) & BM_PXP_WFE_B_STG3_F8X1_OUT2_1_LUTOUT43)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_1_LUTOUT42 0x00000400
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_1_LUTOUT42(v) \
+ (((v) << 10) & BM_PXP_WFE_B_STG3_F8X1_OUT2_1_LUTOUT42)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_1_LUTOUT41 0x00000200
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_1_LUTOUT41(v) \
+ (((v) << 9) & BM_PXP_WFE_B_STG3_F8X1_OUT2_1_LUTOUT41)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_1_LUTOUT40 0x00000100
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_1_LUTOUT40(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STG3_F8X1_OUT2_1_LUTOUT40)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_1_LUTOUT39 0x00000080
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_1_LUTOUT39(v) \
+ (((v) << 7) & BM_PXP_WFE_B_STG3_F8X1_OUT2_1_LUTOUT39)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_1_LUTOUT38 0x00000040
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_1_LUTOUT38(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STG3_F8X1_OUT2_1_LUTOUT38)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_1_LUTOUT37 0x00000020
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_1_LUTOUT37(v) \
+ (((v) << 5) & BM_PXP_WFE_B_STG3_F8X1_OUT2_1_LUTOUT37)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_1_LUTOUT36 0x00000010
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_1_LUTOUT36(v) \
+ (((v) << 4) & BM_PXP_WFE_B_STG3_F8X1_OUT2_1_LUTOUT36)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_1_LUTOUT35 0x00000008
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_1_LUTOUT35(v) \
+ (((v) << 3) & BM_PXP_WFE_B_STG3_F8X1_OUT2_1_LUTOUT35)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_1_LUTOUT34 0x00000004
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_1_LUTOUT34(v) \
+ (((v) << 2) & BM_PXP_WFE_B_STG3_F8X1_OUT2_1_LUTOUT34)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_1_LUTOUT33 0x00000002
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_1_LUTOUT33(v) \
+ (((v) << 1) & BM_PXP_WFE_B_STG3_F8X1_OUT2_1_LUTOUT33)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_1_LUTOUT32 0x00000001
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_1_LUTOUT32(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STG3_F8X1_OUT2_1_LUTOUT32)
+
+#define HW_PXP_WFE_B_STG3_F8X1_OUT2_2 (0x000026b0)
+
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_2_LUTOUT95 0x80000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_2_LUTOUT95(v) \
+ (((v) << 31) & BM_PXP_WFE_B_STG3_F8X1_OUT2_2_LUTOUT95)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_2_LUTOUT94 0x40000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_2_LUTOUT94(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STG3_F8X1_OUT2_2_LUTOUT94)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_2_LUTOUT93 0x20000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_2_LUTOUT93(v) \
+ (((v) << 29) & BM_PXP_WFE_B_STG3_F8X1_OUT2_2_LUTOUT93)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_2_LUTOUT92 0x10000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_2_LUTOUT92(v) \
+ (((v) << 28) & BM_PXP_WFE_B_STG3_F8X1_OUT2_2_LUTOUT92)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_2_LUTOUT91 0x08000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_2_LUTOUT91(v) \
+ (((v) << 27) & BM_PXP_WFE_B_STG3_F8X1_OUT2_2_LUTOUT91)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_2_LUTOUT90 0x04000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_2_LUTOUT90(v) \
+ (((v) << 26) & BM_PXP_WFE_B_STG3_F8X1_OUT2_2_LUTOUT90)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_2_LUTOUT89 0x02000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_2_LUTOUT89(v) \
+ (((v) << 25) & BM_PXP_WFE_B_STG3_F8X1_OUT2_2_LUTOUT89)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_2_LUTOUT88 0x01000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_2_LUTOUT88(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STG3_F8X1_OUT2_2_LUTOUT88)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_2_LUTOUT87 0x00800000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_2_LUTOUT87(v) \
+ (((v) << 23) & BM_PXP_WFE_B_STG3_F8X1_OUT2_2_LUTOUT87)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_2_LUTOUT86 0x00400000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_2_LUTOUT86(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STG3_F8X1_OUT2_2_LUTOUT86)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_2_LUTOUT85 0x00200000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_2_LUTOUT85(v) \
+ (((v) << 21) & BM_PXP_WFE_B_STG3_F8X1_OUT2_2_LUTOUT85)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_2_LUTOUT84 0x00100000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_2_LUTOUT84(v) \
+ (((v) << 20) & BM_PXP_WFE_B_STG3_F8X1_OUT2_2_LUTOUT84)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_2_LUTOUT83 0x00080000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_2_LUTOUT83(v) \
+ (((v) << 19) & BM_PXP_WFE_B_STG3_F8X1_OUT2_2_LUTOUT83)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_2_LUTOUT82 0x00040000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_2_LUTOUT82(v) \
+ (((v) << 18) & BM_PXP_WFE_B_STG3_F8X1_OUT2_2_LUTOUT82)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_2_LUTOUT81 0x00020000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_2_LUTOUT81(v) \
+ (((v) << 17) & BM_PXP_WFE_B_STG3_F8X1_OUT2_2_LUTOUT81)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_2_LUTOUT80 0x00010000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_2_LUTOUT80(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STG3_F8X1_OUT2_2_LUTOUT80)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_2_LUTOUT79 0x00008000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_2_LUTOUT79(v) \
+ (((v) << 15) & BM_PXP_WFE_B_STG3_F8X1_OUT2_2_LUTOUT79)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_2_LUTOUT78 0x00004000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_2_LUTOUT78(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STG3_F8X1_OUT2_2_LUTOUT78)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_2_LUTOUT77 0x00002000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_2_LUTOUT77(v) \
+ (((v) << 13) & BM_PXP_WFE_B_STG3_F8X1_OUT2_2_LUTOUT77)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_2_LUTOUT76 0x00001000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_2_LUTOUT76(v) \
+ (((v) << 12) & BM_PXP_WFE_B_STG3_F8X1_OUT2_2_LUTOUT76)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_2_LUTOUT75 0x00000800
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_2_LUTOUT75(v) \
+ (((v) << 11) & BM_PXP_WFE_B_STG3_F8X1_OUT2_2_LUTOUT75)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_2_LUTOUT74 0x00000400
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_2_LUTOUT74(v) \
+ (((v) << 10) & BM_PXP_WFE_B_STG3_F8X1_OUT2_2_LUTOUT74)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_2_LUTOUT73 0x00000200
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_2_LUTOUT73(v) \
+ (((v) << 9) & BM_PXP_WFE_B_STG3_F8X1_OUT2_2_LUTOUT73)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_2_LUTOUT72 0x00000100
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_2_LUTOUT72(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STG3_F8X1_OUT2_2_LUTOUT72)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_2_LUTOUT71 0x00000080
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_2_LUTOUT71(v) \
+ (((v) << 7) & BM_PXP_WFE_B_STG3_F8X1_OUT2_2_LUTOUT71)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_2_LUTOUT70 0x00000040
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_2_LUTOUT70(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STG3_F8X1_OUT2_2_LUTOUT70)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_2_LUTOUT69 0x00000020
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_2_LUTOUT69(v) \
+ (((v) << 5) & BM_PXP_WFE_B_STG3_F8X1_OUT2_2_LUTOUT69)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_2_LUTOUT68 0x00000010
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_2_LUTOUT68(v) \
+ (((v) << 4) & BM_PXP_WFE_B_STG3_F8X1_OUT2_2_LUTOUT68)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_2_LUTOUT67 0x00000008
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_2_LUTOUT67(v) \
+ (((v) << 3) & BM_PXP_WFE_B_STG3_F8X1_OUT2_2_LUTOUT67)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_2_LUTOUT66 0x00000004
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_2_LUTOUT66(v) \
+ (((v) << 2) & BM_PXP_WFE_B_STG3_F8X1_OUT2_2_LUTOUT66)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_2_LUTOUT65 0x00000002
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_2_LUTOUT65(v) \
+ (((v) << 1) & BM_PXP_WFE_B_STG3_F8X1_OUT2_2_LUTOUT65)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_2_LUTOUT64 0x00000001
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_2_LUTOUT64(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STG3_F8X1_OUT2_2_LUTOUT64)
+
+#define HW_PXP_WFE_B_STG3_F8X1_OUT2_3 (0x000026c0)
+
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_3_LUTOUT127 0x80000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_3_LUTOUT127(v) \
+ (((v) << 31) & BM_PXP_WFE_B_STG3_F8X1_OUT2_3_LUTOUT127)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_3_LUTOUT126 0x40000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_3_LUTOUT126(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STG3_F8X1_OUT2_3_LUTOUT126)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_3_LUTOUT125 0x20000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_3_LUTOUT125(v) \
+ (((v) << 29) & BM_PXP_WFE_B_STG3_F8X1_OUT2_3_LUTOUT125)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_3_LUTOUT124 0x10000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_3_LUTOUT124(v) \
+ (((v) << 28) & BM_PXP_WFE_B_STG3_F8X1_OUT2_3_LUTOUT124)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_3_LUTOUT123 0x08000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_3_LUTOUT123(v) \
+ (((v) << 27) & BM_PXP_WFE_B_STG3_F8X1_OUT2_3_LUTOUT123)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_3_LUTOUT122 0x04000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_3_LUTOUT122(v) \
+ (((v) << 26) & BM_PXP_WFE_B_STG3_F8X1_OUT2_3_LUTOUT122)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_3_LUTOUT121 0x02000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_3_LUTOUT121(v) \
+ (((v) << 25) & BM_PXP_WFE_B_STG3_F8X1_OUT2_3_LUTOUT121)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_3_LUTOUT120 0x01000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_3_LUTOUT120(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STG3_F8X1_OUT2_3_LUTOUT120)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_3_LUTOUT119 0x00800000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_3_LUTOUT119(v) \
+ (((v) << 23) & BM_PXP_WFE_B_STG3_F8X1_OUT2_3_LUTOUT119)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_3_LUTOUT118 0x00400000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_3_LUTOUT118(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STG3_F8X1_OUT2_3_LUTOUT118)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_3_LUTOUT117 0x00200000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_3_LUTOUT117(v) \
+ (((v) << 21) & BM_PXP_WFE_B_STG3_F8X1_OUT2_3_LUTOUT117)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_3_LUTOUT116 0x00100000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_3_LUTOUT116(v) \
+ (((v) << 20) & BM_PXP_WFE_B_STG3_F8X1_OUT2_3_LUTOUT116)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_3_LUTOUT115 0x00080000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_3_LUTOUT115(v) \
+ (((v) << 19) & BM_PXP_WFE_B_STG3_F8X1_OUT2_3_LUTOUT115)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_3_LUTOUT114 0x00040000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_3_LUTOUT114(v) \
+ (((v) << 18) & BM_PXP_WFE_B_STG3_F8X1_OUT2_3_LUTOUT114)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_3_LUTOUT113 0x00020000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_3_LUTOUT113(v) \
+ (((v) << 17) & BM_PXP_WFE_B_STG3_F8X1_OUT2_3_LUTOUT113)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_3_LUTOUT112 0x00010000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_3_LUTOUT112(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STG3_F8X1_OUT2_3_LUTOUT112)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_3_LUTOUT111 0x00008000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_3_LUTOUT111(v) \
+ (((v) << 15) & BM_PXP_WFE_B_STG3_F8X1_OUT2_3_LUTOUT111)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_3_LUTOUT110 0x00004000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_3_LUTOUT110(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STG3_F8X1_OUT2_3_LUTOUT110)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_3_LUTOUT109 0x00002000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_3_LUTOUT109(v) \
+ (((v) << 13) & BM_PXP_WFE_B_STG3_F8X1_OUT2_3_LUTOUT109)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_3_LUTOUT108 0x00001000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_3_LUTOUT108(v) \
+ (((v) << 12) & BM_PXP_WFE_B_STG3_F8X1_OUT2_3_LUTOUT108)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_3_LUTOUT107 0x00000800
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_3_LUTOUT107(v) \
+ (((v) << 11) & BM_PXP_WFE_B_STG3_F8X1_OUT2_3_LUTOUT107)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_3_LUTOUT106 0x00000400
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_3_LUTOUT106(v) \
+ (((v) << 10) & BM_PXP_WFE_B_STG3_F8X1_OUT2_3_LUTOUT106)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_3_LUTOUT105 0x00000200
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_3_LUTOUT105(v) \
+ (((v) << 9) & BM_PXP_WFE_B_STG3_F8X1_OUT2_3_LUTOUT105)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_3_LUTOUT104 0x00000100
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_3_LUTOUT104(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STG3_F8X1_OUT2_3_LUTOUT104)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_3_LUTOUT103 0x00000080
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_3_LUTOUT103(v) \
+ (((v) << 7) & BM_PXP_WFE_B_STG3_F8X1_OUT2_3_LUTOUT103)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_3_LUTOUT102 0x00000040
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_3_LUTOUT102(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STG3_F8X1_OUT2_3_LUTOUT102)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_3_LUTOUT101 0x00000020
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_3_LUTOUT101(v) \
+ (((v) << 5) & BM_PXP_WFE_B_STG3_F8X1_OUT2_3_LUTOUT101)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_3_LUTOUT100 0x00000010
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_3_LUTOUT100(v) \
+ (((v) << 4) & BM_PXP_WFE_B_STG3_F8X1_OUT2_3_LUTOUT100)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_3_LUTOUT99 0x00000008
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_3_LUTOUT99(v) \
+ (((v) << 3) & BM_PXP_WFE_B_STG3_F8X1_OUT2_3_LUTOUT99)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_3_LUTOUT98 0x00000004
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_3_LUTOUT98(v) \
+ (((v) << 2) & BM_PXP_WFE_B_STG3_F8X1_OUT2_3_LUTOUT98)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_3_LUTOUT97 0x00000002
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_3_LUTOUT97(v) \
+ (((v) << 1) & BM_PXP_WFE_B_STG3_F8X1_OUT2_3_LUTOUT97)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_3_LUTOUT96 0x00000001
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_3_LUTOUT96(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STG3_F8X1_OUT2_3_LUTOUT96)
+
+#define HW_PXP_WFE_B_STG3_F8X1_OUT2_4 (0x000026d0)
+
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_4_LUTOUT159 0x80000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_4_LUTOUT159(v) \
+ (((v) << 31) & BM_PXP_WFE_B_STG3_F8X1_OUT2_4_LUTOUT159)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_4_LUTOUT158 0x40000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_4_LUTOUT158(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STG3_F8X1_OUT2_4_LUTOUT158)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_4_LUTOUT157 0x20000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_4_LUTOUT157(v) \
+ (((v) << 29) & BM_PXP_WFE_B_STG3_F8X1_OUT2_4_LUTOUT157)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_4_LUTOUT156 0x10000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_4_LUTOUT156(v) \
+ (((v) << 28) & BM_PXP_WFE_B_STG3_F8X1_OUT2_4_LUTOUT156)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_4_LUTOUT155 0x08000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_4_LUTOUT155(v) \
+ (((v) << 27) & BM_PXP_WFE_B_STG3_F8X1_OUT2_4_LUTOUT155)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_4_LUTOUT154 0x04000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_4_LUTOUT154(v) \
+ (((v) << 26) & BM_PXP_WFE_B_STG3_F8X1_OUT2_4_LUTOUT154)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_4_LUTOUT153 0x02000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_4_LUTOUT153(v) \
+ (((v) << 25) & BM_PXP_WFE_B_STG3_F8X1_OUT2_4_LUTOUT153)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_4_LUTOUT152 0x01000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_4_LUTOUT152(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STG3_F8X1_OUT2_4_LUTOUT152)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_4_LUTOUT151 0x00800000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_4_LUTOUT151(v) \
+ (((v) << 23) & BM_PXP_WFE_B_STG3_F8X1_OUT2_4_LUTOUT151)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_4_LUTOUT150 0x00400000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_4_LUTOUT150(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STG3_F8X1_OUT2_4_LUTOUT150)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_4_LUTOUT149 0x00200000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_4_LUTOUT149(v) \
+ (((v) << 21) & BM_PXP_WFE_B_STG3_F8X1_OUT2_4_LUTOUT149)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_4_LUTOUT148 0x00100000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_4_LUTOUT148(v) \
+ (((v) << 20) & BM_PXP_WFE_B_STG3_F8X1_OUT2_4_LUTOUT148)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_4_LUTOUT147 0x00080000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_4_LUTOUT147(v) \
+ (((v) << 19) & BM_PXP_WFE_B_STG3_F8X1_OUT2_4_LUTOUT147)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_4_LUTOUT146 0x00040000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_4_LUTOUT146(v) \
+ (((v) << 18) & BM_PXP_WFE_B_STG3_F8X1_OUT2_4_LUTOUT146)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_4_LUTOUT145 0x00020000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_4_LUTOUT145(v) \
+ (((v) << 17) & BM_PXP_WFE_B_STG3_F8X1_OUT2_4_LUTOUT145)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_4_LUTOUT144 0x00010000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_4_LUTOUT144(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STG3_F8X1_OUT2_4_LUTOUT144)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_4_LUTOUT143 0x00008000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_4_LUTOUT143(v) \
+ (((v) << 15) & BM_PXP_WFE_B_STG3_F8X1_OUT2_4_LUTOUT143)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_4_LUTOUT142 0x00004000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_4_LUTOUT142(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STG3_F8X1_OUT2_4_LUTOUT142)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_4_LUTOUT141 0x00002000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_4_LUTOUT141(v) \
+ (((v) << 13) & BM_PXP_WFE_B_STG3_F8X1_OUT2_4_LUTOUT141)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_4_LUTOUT140 0x00001000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_4_LUTOUT140(v) \
+ (((v) << 12) & BM_PXP_WFE_B_STG3_F8X1_OUT2_4_LUTOUT140)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_4_LUTOUT139 0x00000800
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_4_LUTOUT139(v) \
+ (((v) << 11) & BM_PXP_WFE_B_STG3_F8X1_OUT2_4_LUTOUT139)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_4_LUTOUT138 0x00000400
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_4_LUTOUT138(v) \
+ (((v) << 10) & BM_PXP_WFE_B_STG3_F8X1_OUT2_4_LUTOUT138)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_4_LUTOUT137 0x00000200
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_4_LUTOUT137(v) \
+ (((v) << 9) & BM_PXP_WFE_B_STG3_F8X1_OUT2_4_LUTOUT137)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_4_LUTOUT136 0x00000100
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_4_LUTOUT136(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STG3_F8X1_OUT2_4_LUTOUT136)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_4_LUTOUT135 0x00000080
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_4_LUTOUT135(v) \
+ (((v) << 7) & BM_PXP_WFE_B_STG3_F8X1_OUT2_4_LUTOUT135)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_4_LUTOUT134 0x00000040
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_4_LUTOUT134(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STG3_F8X1_OUT2_4_LUTOUT134)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_4_LUTOUT133 0x00000020
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_4_LUTOUT133(v) \
+ (((v) << 5) & BM_PXP_WFE_B_STG3_F8X1_OUT2_4_LUTOUT133)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_4_LUTOUT132 0x00000010
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_4_LUTOUT132(v) \
+ (((v) << 4) & BM_PXP_WFE_B_STG3_F8X1_OUT2_4_LUTOUT132)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_4_LUTOUT131 0x00000008
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_4_LUTOUT131(v) \
+ (((v) << 3) & BM_PXP_WFE_B_STG3_F8X1_OUT2_4_LUTOUT131)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_4_LUTOUT130 0x00000004
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_4_LUTOUT130(v) \
+ (((v) << 2) & BM_PXP_WFE_B_STG3_F8X1_OUT2_4_LUTOUT130)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_4_LUTOUT129 0x00000002
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_4_LUTOUT129(v) \
+ (((v) << 1) & BM_PXP_WFE_B_STG3_F8X1_OUT2_4_LUTOUT129)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_4_LUTOUT128 0x00000001
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_4_LUTOUT128(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STG3_F8X1_OUT2_4_LUTOUT128)
+
+#define HW_PXP_WFE_B_STG3_F8X1_OUT2_5 (0x000026e0)
+
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_5_LUTOUT191 0x80000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_5_LUTOUT191(v) \
+ (((v) << 31) & BM_PXP_WFE_B_STG3_F8X1_OUT2_5_LUTOUT191)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_5_LUTOUT190 0x40000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_5_LUTOUT190(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STG3_F8X1_OUT2_5_LUTOUT190)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_5_LUTOUT189 0x20000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_5_LUTOUT189(v) \
+ (((v) << 29) & BM_PXP_WFE_B_STG3_F8X1_OUT2_5_LUTOUT189)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_5_LUTOUT188 0x10000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_5_LUTOUT188(v) \
+ (((v) << 28) & BM_PXP_WFE_B_STG3_F8X1_OUT2_5_LUTOUT188)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_5_LUTOUT187 0x08000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_5_LUTOUT187(v) \
+ (((v) << 27) & BM_PXP_WFE_B_STG3_F8X1_OUT2_5_LUTOUT187)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_5_LUTOUT186 0x04000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_5_LUTOUT186(v) \
+ (((v) << 26) & BM_PXP_WFE_B_STG3_F8X1_OUT2_5_LUTOUT186)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_5_LUTOUT185 0x02000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_5_LUTOUT185(v) \
+ (((v) << 25) & BM_PXP_WFE_B_STG3_F8X1_OUT2_5_LUTOUT185)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_5_LUTOUT184 0x01000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_5_LUTOUT184(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STG3_F8X1_OUT2_5_LUTOUT184)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_5_LUTOUT183 0x00800000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_5_LUTOUT183(v) \
+ (((v) << 23) & BM_PXP_WFE_B_STG3_F8X1_OUT2_5_LUTOUT183)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_5_LUTOUT182 0x00400000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_5_LUTOUT182(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STG3_F8X1_OUT2_5_LUTOUT182)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_5_LUTOUT181 0x00200000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_5_LUTOUT181(v) \
+ (((v) << 21) & BM_PXP_WFE_B_STG3_F8X1_OUT2_5_LUTOUT181)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_5_LUTOUT180 0x00100000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_5_LUTOUT180(v) \
+ (((v) << 20) & BM_PXP_WFE_B_STG3_F8X1_OUT2_5_LUTOUT180)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_5_LUTOUT179 0x00080000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_5_LUTOUT179(v) \
+ (((v) << 19) & BM_PXP_WFE_B_STG3_F8X1_OUT2_5_LUTOUT179)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_5_LUTOUT178 0x00040000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_5_LUTOUT178(v) \
+ (((v) << 18) & BM_PXP_WFE_B_STG3_F8X1_OUT2_5_LUTOUT178)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_5_LUTOUT177 0x00020000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_5_LUTOUT177(v) \
+ (((v) << 17) & BM_PXP_WFE_B_STG3_F8X1_OUT2_5_LUTOUT177)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_5_LUTOUT176 0x00010000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_5_LUTOUT176(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STG3_F8X1_OUT2_5_LUTOUT176)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_5_LUTOUT175 0x00008000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_5_LUTOUT175(v) \
+ (((v) << 15) & BM_PXP_WFE_B_STG3_F8X1_OUT2_5_LUTOUT175)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_5_LUTOUT174 0x00004000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_5_LUTOUT174(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STG3_F8X1_OUT2_5_LUTOUT174)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_5_LUTOUT173 0x00002000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_5_LUTOUT173(v) \
+ (((v) << 13) & BM_PXP_WFE_B_STG3_F8X1_OUT2_5_LUTOUT173)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_5_LUTOUT172 0x00001000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_5_LUTOUT172(v) \
+ (((v) << 12) & BM_PXP_WFE_B_STG3_F8X1_OUT2_5_LUTOUT172)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_5_LUTOUT171 0x00000800
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_5_LUTOUT171(v) \
+ (((v) << 11) & BM_PXP_WFE_B_STG3_F8X1_OUT2_5_LUTOUT171)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_5_LUTOUT170 0x00000400
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_5_LUTOUT170(v) \
+ (((v) << 10) & BM_PXP_WFE_B_STG3_F8X1_OUT2_5_LUTOUT170)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_5_LUTOUT169 0x00000200
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_5_LUTOUT169(v) \
+ (((v) << 9) & BM_PXP_WFE_B_STG3_F8X1_OUT2_5_LUTOUT169)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_5_LUTOUT168 0x00000100
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_5_LUTOUT168(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STG3_F8X1_OUT2_5_LUTOUT168)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_5_LUTOUT167 0x00000080
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_5_LUTOUT167(v) \
+ (((v) << 7) & BM_PXP_WFE_B_STG3_F8X1_OUT2_5_LUTOUT167)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_5_LUTOUT166 0x00000040
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_5_LUTOUT166(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STG3_F8X1_OUT2_5_LUTOUT166)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_5_LUTOUT165 0x00000020
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_5_LUTOUT165(v) \
+ (((v) << 5) & BM_PXP_WFE_B_STG3_F8X1_OUT2_5_LUTOUT165)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_5_LUTOUT164 0x00000010
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_5_LUTOUT164(v) \
+ (((v) << 4) & BM_PXP_WFE_B_STG3_F8X1_OUT2_5_LUTOUT164)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_5_LUTOUT163 0x00000008
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_5_LUTOUT163(v) \
+ (((v) << 3) & BM_PXP_WFE_B_STG3_F8X1_OUT2_5_LUTOUT163)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_5_LUTOUT162 0x00000004
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_5_LUTOUT162(v) \
+ (((v) << 2) & BM_PXP_WFE_B_STG3_F8X1_OUT2_5_LUTOUT162)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_5_LUTOUT161 0x00000002
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_5_LUTOUT161(v) \
+ (((v) << 1) & BM_PXP_WFE_B_STG3_F8X1_OUT2_5_LUTOUT161)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_5_LUTOUT160 0x00000001
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_5_LUTOUT160(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STG3_F8X1_OUT2_5_LUTOUT160)
+
+#define HW_PXP_WFE_B_STG3_F8X1_OUT2_6 (0x000026f0)
+
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_6_LUTOUT223 0x80000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_6_LUTOUT223(v) \
+ (((v) << 31) & BM_PXP_WFE_B_STG3_F8X1_OUT2_6_LUTOUT223)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_6_LUTOUT222 0x40000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_6_LUTOUT222(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STG3_F8X1_OUT2_6_LUTOUT222)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_6_LUTOUT221 0x20000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_6_LUTOUT221(v) \
+ (((v) << 29) & BM_PXP_WFE_B_STG3_F8X1_OUT2_6_LUTOUT221)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_6_LUTOUT220 0x10000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_6_LUTOUT220(v) \
+ (((v) << 28) & BM_PXP_WFE_B_STG3_F8X1_OUT2_6_LUTOUT220)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_6_LUTOUT219 0x08000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_6_LUTOUT219(v) \
+ (((v) << 27) & BM_PXP_WFE_B_STG3_F8X1_OUT2_6_LUTOUT219)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_6_LUTOUT218 0x04000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_6_LUTOUT218(v) \
+ (((v) << 26) & BM_PXP_WFE_B_STG3_F8X1_OUT2_6_LUTOUT218)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_6_LUTOUT217 0x02000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_6_LUTOUT217(v) \
+ (((v) << 25) & BM_PXP_WFE_B_STG3_F8X1_OUT2_6_LUTOUT217)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_6_LUTOUT216 0x01000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_6_LUTOUT216(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STG3_F8X1_OUT2_6_LUTOUT216)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_6_LUTOUT215 0x00800000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_6_LUTOUT215(v) \
+ (((v) << 23) & BM_PXP_WFE_B_STG3_F8X1_OUT2_6_LUTOUT215)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_6_LUTOUT214 0x00400000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_6_LUTOUT214(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STG3_F8X1_OUT2_6_LUTOUT214)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_6_LUTOUT213 0x00200000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_6_LUTOUT213(v) \
+ (((v) << 21) & BM_PXP_WFE_B_STG3_F8X1_OUT2_6_LUTOUT213)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_6_LUTOUT212 0x00100000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_6_LUTOUT212(v) \
+ (((v) << 20) & BM_PXP_WFE_B_STG3_F8X1_OUT2_6_LUTOUT212)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_6_LUTOUT211 0x00080000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_6_LUTOUT211(v) \
+ (((v) << 19) & BM_PXP_WFE_B_STG3_F8X1_OUT2_6_LUTOUT211)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_6_LUTOUT210 0x00040000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_6_LUTOUT210(v) \
+ (((v) << 18) & BM_PXP_WFE_B_STG3_F8X1_OUT2_6_LUTOUT210)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_6_LUTOUT209 0x00020000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_6_LUTOUT209(v) \
+ (((v) << 17) & BM_PXP_WFE_B_STG3_F8X1_OUT2_6_LUTOUT209)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_6_LUTOUT208 0x00010000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_6_LUTOUT208(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STG3_F8X1_OUT2_6_LUTOUT208)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_6_LUTOUT207 0x00008000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_6_LUTOUT207(v) \
+ (((v) << 15) & BM_PXP_WFE_B_STG3_F8X1_OUT2_6_LUTOUT207)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_6_LUTOUT206 0x00004000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_6_LUTOUT206(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STG3_F8X1_OUT2_6_LUTOUT206)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_6_LUTOUT205 0x00002000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_6_LUTOUT205(v) \
+ (((v) << 13) & BM_PXP_WFE_B_STG3_F8X1_OUT2_6_LUTOUT205)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_6_LUTOUT204 0x00001000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_6_LUTOUT204(v) \
+ (((v) << 12) & BM_PXP_WFE_B_STG3_F8X1_OUT2_6_LUTOUT204)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_6_LUTOUT203 0x00000800
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_6_LUTOUT203(v) \
+ (((v) << 11) & BM_PXP_WFE_B_STG3_F8X1_OUT2_6_LUTOUT203)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_6_LUTOUT202 0x00000400
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_6_LUTOUT202(v) \
+ (((v) << 10) & BM_PXP_WFE_B_STG3_F8X1_OUT2_6_LUTOUT202)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_6_LUTOUT201 0x00000200
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_6_LUTOUT201(v) \
+ (((v) << 9) & BM_PXP_WFE_B_STG3_F8X1_OUT2_6_LUTOUT201)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_6_LUTOUT200 0x00000100
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_6_LUTOUT200(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STG3_F8X1_OUT2_6_LUTOUT200)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_6_LUTOUT199 0x00000080
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_6_LUTOUT199(v) \
+ (((v) << 7) & BM_PXP_WFE_B_STG3_F8X1_OUT2_6_LUTOUT199)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_6_LUTOUT198 0x00000040
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_6_LUTOUT198(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STG3_F8X1_OUT2_6_LUTOUT198)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_6_LUTOUT197 0x00000020
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_6_LUTOUT197(v) \
+ (((v) << 5) & BM_PXP_WFE_B_STG3_F8X1_OUT2_6_LUTOUT197)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_6_LUTOUT196 0x00000010
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_6_LUTOUT196(v) \
+ (((v) << 4) & BM_PXP_WFE_B_STG3_F8X1_OUT2_6_LUTOUT196)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_6_LUTOUT195 0x00000008
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_6_LUTOUT195(v) \
+ (((v) << 3) & BM_PXP_WFE_B_STG3_F8X1_OUT2_6_LUTOUT195)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_6_LUTOUT194 0x00000004
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_6_LUTOUT194(v) \
+ (((v) << 2) & BM_PXP_WFE_B_STG3_F8X1_OUT2_6_LUTOUT194)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_6_LUTOUT193 0x00000002
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_6_LUTOUT193(v) \
+ (((v) << 1) & BM_PXP_WFE_B_STG3_F8X1_OUT2_6_LUTOUT193)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_6_LUTOUT192 0x00000001
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_6_LUTOUT192(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STG3_F8X1_OUT2_6_LUTOUT192)
+
+#define HW_PXP_WFE_B_STG3_F8X1_OUT2_7 (0x00002700)
+
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_7_LUTOUT255 0x80000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_7_LUTOUT255(v) \
+ (((v) << 31) & BM_PXP_WFE_B_STG3_F8X1_OUT2_7_LUTOUT255)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_7_LUTOUT254 0x40000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_7_LUTOUT254(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STG3_F8X1_OUT2_7_LUTOUT254)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_7_LUTOUT253 0x20000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_7_LUTOUT253(v) \
+ (((v) << 29) & BM_PXP_WFE_B_STG3_F8X1_OUT2_7_LUTOUT253)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_7_LUTOUT252 0x10000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_7_LUTOUT252(v) \
+ (((v) << 28) & BM_PXP_WFE_B_STG3_F8X1_OUT2_7_LUTOUT252)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_7_LUTOUT251 0x08000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_7_LUTOUT251(v) \
+ (((v) << 27) & BM_PXP_WFE_B_STG3_F8X1_OUT2_7_LUTOUT251)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_7_LUTOUT250 0x04000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_7_LUTOUT250(v) \
+ (((v) << 26) & BM_PXP_WFE_B_STG3_F8X1_OUT2_7_LUTOUT250)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_7_LUTOUT249 0x02000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_7_LUTOUT249(v) \
+ (((v) << 25) & BM_PXP_WFE_B_STG3_F8X1_OUT2_7_LUTOUT249)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_7_LUTOUT248 0x01000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_7_LUTOUT248(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STG3_F8X1_OUT2_7_LUTOUT248)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_7_LUTOUT247 0x00800000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_7_LUTOUT247(v) \
+ (((v) << 23) & BM_PXP_WFE_B_STG3_F8X1_OUT2_7_LUTOUT247)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_7_LUTOUT246 0x00400000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_7_LUTOUT246(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STG3_F8X1_OUT2_7_LUTOUT246)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_7_LUTOUT245 0x00200000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_7_LUTOUT245(v) \
+ (((v) << 21) & BM_PXP_WFE_B_STG3_F8X1_OUT2_7_LUTOUT245)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_7_LUTOUT244 0x00100000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_7_LUTOUT244(v) \
+ (((v) << 20) & BM_PXP_WFE_B_STG3_F8X1_OUT2_7_LUTOUT244)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_7_LUTOUT243 0x00080000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_7_LUTOUT243(v) \
+ (((v) << 19) & BM_PXP_WFE_B_STG3_F8X1_OUT2_7_LUTOUT243)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_7_LUTOUT242 0x00040000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_7_LUTOUT242(v) \
+ (((v) << 18) & BM_PXP_WFE_B_STG3_F8X1_OUT2_7_LUTOUT242)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_7_LUTOUT241 0x00020000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_7_LUTOUT241(v) \
+ (((v) << 17) & BM_PXP_WFE_B_STG3_F8X1_OUT2_7_LUTOUT241)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_7_LUTOUT240 0x00010000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_7_LUTOUT240(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STG3_F8X1_OUT2_7_LUTOUT240)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_7_LUTOUT239 0x00008000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_7_LUTOUT239(v) \
+ (((v) << 15) & BM_PXP_WFE_B_STG3_F8X1_OUT2_7_LUTOUT239)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_7_LUTOUT238 0x00004000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_7_LUTOUT238(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STG3_F8X1_OUT2_7_LUTOUT238)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_7_LUTOUT237 0x00002000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_7_LUTOUT237(v) \
+ (((v) << 13) & BM_PXP_WFE_B_STG3_F8X1_OUT2_7_LUTOUT237)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_7_LUTOUT236 0x00001000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_7_LUTOUT236(v) \
+ (((v) << 12) & BM_PXP_WFE_B_STG3_F8X1_OUT2_7_LUTOUT236)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_7_LUTOUT235 0x00000800
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_7_LUTOUT235(v) \
+ (((v) << 11) & BM_PXP_WFE_B_STG3_F8X1_OUT2_7_LUTOUT235)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_7_LUTOUT234 0x00000400
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_7_LUTOUT234(v) \
+ (((v) << 10) & BM_PXP_WFE_B_STG3_F8X1_OUT2_7_LUTOUT234)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_7_LUTOUT233 0x00000200
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_7_LUTOUT233(v) \
+ (((v) << 9) & BM_PXP_WFE_B_STG3_F8X1_OUT2_7_LUTOUT233)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_7_LUTOUT232 0x00000100
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_7_LUTOUT232(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STG3_F8X1_OUT2_7_LUTOUT232)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_7_LUTOUT231 0x00000080
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_7_LUTOUT231(v) \
+ (((v) << 7) & BM_PXP_WFE_B_STG3_F8X1_OUT2_7_LUTOUT231)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_7_LUTOUT230 0x00000040
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_7_LUTOUT230(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STG3_F8X1_OUT2_7_LUTOUT230)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_7_LUTOUT229 0x00000020
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_7_LUTOUT229(v) \
+ (((v) << 5) & BM_PXP_WFE_B_STG3_F8X1_OUT2_7_LUTOUT229)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_7_LUTOUT228 0x00000010
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_7_LUTOUT228(v) \
+ (((v) << 4) & BM_PXP_WFE_B_STG3_F8X1_OUT2_7_LUTOUT228)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_7_LUTOUT227 0x00000008
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_7_LUTOUT227(v) \
+ (((v) << 3) & BM_PXP_WFE_B_STG3_F8X1_OUT2_7_LUTOUT227)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_7_LUTOUT226 0x00000004
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_7_LUTOUT226(v) \
+ (((v) << 2) & BM_PXP_WFE_B_STG3_F8X1_OUT2_7_LUTOUT226)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_7_LUTOUT225 0x00000002
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_7_LUTOUT225(v) \
+ (((v) << 1) & BM_PXP_WFE_B_STG3_F8X1_OUT2_7_LUTOUT225)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT2_7_LUTOUT224 0x00000001
+#define BF_PXP_WFE_B_STG3_F8X1_OUT2_7_LUTOUT224(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STG3_F8X1_OUT2_7_LUTOUT224)
+
+#define HW_PXP_WFE_B_STG3_F8X1_OUT3_0 (0x00002710)
+
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_0_LUTOUT31 0x80000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_0_LUTOUT31(v) \
+ (((v) << 31) & BM_PXP_WFE_B_STG3_F8X1_OUT3_0_LUTOUT31)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_0_LUTOUT30 0x40000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_0_LUTOUT30(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STG3_F8X1_OUT3_0_LUTOUT30)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_0_LUTOUT29 0x20000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_0_LUTOUT29(v) \
+ (((v) << 29) & BM_PXP_WFE_B_STG3_F8X1_OUT3_0_LUTOUT29)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_0_LUTOUT28 0x10000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_0_LUTOUT28(v) \
+ (((v) << 28) & BM_PXP_WFE_B_STG3_F8X1_OUT3_0_LUTOUT28)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_0_LUTOUT27 0x08000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_0_LUTOUT27(v) \
+ (((v) << 27) & BM_PXP_WFE_B_STG3_F8X1_OUT3_0_LUTOUT27)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_0_LUTOUT26 0x04000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_0_LUTOUT26(v) \
+ (((v) << 26) & BM_PXP_WFE_B_STG3_F8X1_OUT3_0_LUTOUT26)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_0_LUTOUT25 0x02000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_0_LUTOUT25(v) \
+ (((v) << 25) & BM_PXP_WFE_B_STG3_F8X1_OUT3_0_LUTOUT25)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_0_LUTOUT24 0x01000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_0_LUTOUT24(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STG3_F8X1_OUT3_0_LUTOUT24)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_0_LUTOUT23 0x00800000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_0_LUTOUT23(v) \
+ (((v) << 23) & BM_PXP_WFE_B_STG3_F8X1_OUT3_0_LUTOUT23)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_0_LUTOUT22 0x00400000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_0_LUTOUT22(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STG3_F8X1_OUT3_0_LUTOUT22)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_0_LUTOUT21 0x00200000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_0_LUTOUT21(v) \
+ (((v) << 21) & BM_PXP_WFE_B_STG3_F8X1_OUT3_0_LUTOUT21)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_0_LUTOUT20 0x00100000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_0_LUTOUT20(v) \
+ (((v) << 20) & BM_PXP_WFE_B_STG3_F8X1_OUT3_0_LUTOUT20)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_0_LUTOUT19 0x00080000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_0_LUTOUT19(v) \
+ (((v) << 19) & BM_PXP_WFE_B_STG3_F8X1_OUT3_0_LUTOUT19)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_0_LUTOUT18 0x00040000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_0_LUTOUT18(v) \
+ (((v) << 18) & BM_PXP_WFE_B_STG3_F8X1_OUT3_0_LUTOUT18)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_0_LUTOUT17 0x00020000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_0_LUTOUT17(v) \
+ (((v) << 17) & BM_PXP_WFE_B_STG3_F8X1_OUT3_0_LUTOUT17)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_0_LUTOUT16 0x00010000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_0_LUTOUT16(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STG3_F8X1_OUT3_0_LUTOUT16)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_0_LUTOUT15 0x00008000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_0_LUTOUT15(v) \
+ (((v) << 15) & BM_PXP_WFE_B_STG3_F8X1_OUT3_0_LUTOUT15)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_0_LUTOUT14 0x00004000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_0_LUTOUT14(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STG3_F8X1_OUT3_0_LUTOUT14)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_0_LUTOUT13 0x00002000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_0_LUTOUT13(v) \
+ (((v) << 13) & BM_PXP_WFE_B_STG3_F8X1_OUT3_0_LUTOUT13)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_0_LUTOUT12 0x00001000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_0_LUTOUT12(v) \
+ (((v) << 12) & BM_PXP_WFE_B_STG3_F8X1_OUT3_0_LUTOUT12)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_0_LUTOUT11 0x00000800
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_0_LUTOUT11(v) \
+ (((v) << 11) & BM_PXP_WFE_B_STG3_F8X1_OUT3_0_LUTOUT11)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_0_LUTOUT10 0x00000400
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_0_LUTOUT10(v) \
+ (((v) << 10) & BM_PXP_WFE_B_STG3_F8X1_OUT3_0_LUTOUT10)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_0_LUTOUT9 0x00000200
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_0_LUTOUT9(v) \
+ (((v) << 9) & BM_PXP_WFE_B_STG3_F8X1_OUT3_0_LUTOUT9)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_0_LUTOUT8 0x00000100
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_0_LUTOUT8(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STG3_F8X1_OUT3_0_LUTOUT8)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_0_LUTOUT7 0x00000080
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_0_LUTOUT7(v) \
+ (((v) << 7) & BM_PXP_WFE_B_STG3_F8X1_OUT3_0_LUTOUT7)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_0_LUTOUT6 0x00000040
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_0_LUTOUT6(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STG3_F8X1_OUT3_0_LUTOUT6)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_0_LUTOUT5 0x00000020
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_0_LUTOUT5(v) \
+ (((v) << 5) & BM_PXP_WFE_B_STG3_F8X1_OUT3_0_LUTOUT5)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_0_LUTOUT4 0x00000010
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_0_LUTOUT4(v) \
+ (((v) << 4) & BM_PXP_WFE_B_STG3_F8X1_OUT3_0_LUTOUT4)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_0_LUTOUT3 0x00000008
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_0_LUTOUT3(v) \
+ (((v) << 3) & BM_PXP_WFE_B_STG3_F8X1_OUT3_0_LUTOUT3)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_0_LUTOUT2 0x00000004
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_0_LUTOUT2(v) \
+ (((v) << 2) & BM_PXP_WFE_B_STG3_F8X1_OUT3_0_LUTOUT2)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_0_LUTOUT1 0x00000002
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_0_LUTOUT1(v) \
+ (((v) << 1) & BM_PXP_WFE_B_STG3_F8X1_OUT3_0_LUTOUT1)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_0_LUTOUT0 0x00000001
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_0_LUTOUT0(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STG3_F8X1_OUT3_0_LUTOUT0)
+
+#define HW_PXP_WFE_B_STG3_F8X1_OUT3_1 (0x00002720)
+
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_1_LUTOUT63 0x80000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_1_LUTOUT63(v) \
+ (((v) << 31) & BM_PXP_WFE_B_STG3_F8X1_OUT3_1_LUTOUT63)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_1_LUTOUT62 0x40000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_1_LUTOUT62(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STG3_F8X1_OUT3_1_LUTOUT62)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_1_LUTOUT61 0x20000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_1_LUTOUT61(v) \
+ (((v) << 29) & BM_PXP_WFE_B_STG3_F8X1_OUT3_1_LUTOUT61)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_1_LUTOUT60 0x10000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_1_LUTOUT60(v) \
+ (((v) << 28) & BM_PXP_WFE_B_STG3_F8X1_OUT3_1_LUTOUT60)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_1_LUTOUT59 0x08000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_1_LUTOUT59(v) \
+ (((v) << 27) & BM_PXP_WFE_B_STG3_F8X1_OUT3_1_LUTOUT59)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_1_LUTOUT58 0x04000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_1_LUTOUT58(v) \
+ (((v) << 26) & BM_PXP_WFE_B_STG3_F8X1_OUT3_1_LUTOUT58)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_1_LUTOUT57 0x02000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_1_LUTOUT57(v) \
+ (((v) << 25) & BM_PXP_WFE_B_STG3_F8X1_OUT3_1_LUTOUT57)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_1_LUTOUT56 0x01000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_1_LUTOUT56(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STG3_F8X1_OUT3_1_LUTOUT56)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_1_LUTOUT55 0x00800000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_1_LUTOUT55(v) \
+ (((v) << 23) & BM_PXP_WFE_B_STG3_F8X1_OUT3_1_LUTOUT55)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_1_LUTOUT54 0x00400000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_1_LUTOUT54(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STG3_F8X1_OUT3_1_LUTOUT54)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_1_LUTOUT53 0x00200000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_1_LUTOUT53(v) \
+ (((v) << 21) & BM_PXP_WFE_B_STG3_F8X1_OUT3_1_LUTOUT53)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_1_LUTOUT52 0x00100000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_1_LUTOUT52(v) \
+ (((v) << 20) & BM_PXP_WFE_B_STG3_F8X1_OUT3_1_LUTOUT52)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_1_LUTOUT51 0x00080000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_1_LUTOUT51(v) \
+ (((v) << 19) & BM_PXP_WFE_B_STG3_F8X1_OUT3_1_LUTOUT51)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_1_LUTOUT50 0x00040000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_1_LUTOUT50(v) \
+ (((v) << 18) & BM_PXP_WFE_B_STG3_F8X1_OUT3_1_LUTOUT50)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_1_LUTOUT49 0x00020000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_1_LUTOUT49(v) \
+ (((v) << 17) & BM_PXP_WFE_B_STG3_F8X1_OUT3_1_LUTOUT49)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_1_LUTOUT48 0x00010000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_1_LUTOUT48(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STG3_F8X1_OUT3_1_LUTOUT48)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_1_LUTOUT47 0x00008000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_1_LUTOUT47(v) \
+ (((v) << 15) & BM_PXP_WFE_B_STG3_F8X1_OUT3_1_LUTOUT47)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_1_LUTOUT46 0x00004000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_1_LUTOUT46(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STG3_F8X1_OUT3_1_LUTOUT46)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_1_LUTOUT45 0x00002000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_1_LUTOUT45(v) \
+ (((v) << 13) & BM_PXP_WFE_B_STG3_F8X1_OUT3_1_LUTOUT45)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_1_LUTOUT44 0x00001000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_1_LUTOUT44(v) \
+ (((v) << 12) & BM_PXP_WFE_B_STG3_F8X1_OUT3_1_LUTOUT44)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_1_LUTOUT43 0x00000800
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_1_LUTOUT43(v) \
+ (((v) << 11) & BM_PXP_WFE_B_STG3_F8X1_OUT3_1_LUTOUT43)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_1_LUTOUT42 0x00000400
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_1_LUTOUT42(v) \
+ (((v) << 10) & BM_PXP_WFE_B_STG3_F8X1_OUT3_1_LUTOUT42)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_1_LUTOUT41 0x00000200
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_1_LUTOUT41(v) \
+ (((v) << 9) & BM_PXP_WFE_B_STG3_F8X1_OUT3_1_LUTOUT41)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_1_LUTOUT40 0x00000100
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_1_LUTOUT40(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STG3_F8X1_OUT3_1_LUTOUT40)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_1_LUTOUT39 0x00000080
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_1_LUTOUT39(v) \
+ (((v) << 7) & BM_PXP_WFE_B_STG3_F8X1_OUT3_1_LUTOUT39)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_1_LUTOUT38 0x00000040
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_1_LUTOUT38(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STG3_F8X1_OUT3_1_LUTOUT38)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_1_LUTOUT37 0x00000020
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_1_LUTOUT37(v) \
+ (((v) << 5) & BM_PXP_WFE_B_STG3_F8X1_OUT3_1_LUTOUT37)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_1_LUTOUT36 0x00000010
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_1_LUTOUT36(v) \
+ (((v) << 4) & BM_PXP_WFE_B_STG3_F8X1_OUT3_1_LUTOUT36)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_1_LUTOUT35 0x00000008
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_1_LUTOUT35(v) \
+ (((v) << 3) & BM_PXP_WFE_B_STG3_F8X1_OUT3_1_LUTOUT35)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_1_LUTOUT34 0x00000004
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_1_LUTOUT34(v) \
+ (((v) << 2) & BM_PXP_WFE_B_STG3_F8X1_OUT3_1_LUTOUT34)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_1_LUTOUT33 0x00000002
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_1_LUTOUT33(v) \
+ (((v) << 1) & BM_PXP_WFE_B_STG3_F8X1_OUT3_1_LUTOUT33)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_1_LUTOUT32 0x00000001
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_1_LUTOUT32(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STG3_F8X1_OUT3_1_LUTOUT32)
+
+#define HW_PXP_WFE_B_STG3_F8X1_OUT3_2 (0x00002730)
+
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_2_LUTOUT95 0x80000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_2_LUTOUT95(v) \
+ (((v) << 31) & BM_PXP_WFE_B_STG3_F8X1_OUT3_2_LUTOUT95)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_2_LUTOUT94 0x40000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_2_LUTOUT94(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STG3_F8X1_OUT3_2_LUTOUT94)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_2_LUTOUT93 0x20000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_2_LUTOUT93(v) \
+ (((v) << 29) & BM_PXP_WFE_B_STG3_F8X1_OUT3_2_LUTOUT93)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_2_LUTOUT92 0x10000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_2_LUTOUT92(v) \
+ (((v) << 28) & BM_PXP_WFE_B_STG3_F8X1_OUT3_2_LUTOUT92)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_2_LUTOUT91 0x08000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_2_LUTOUT91(v) \
+ (((v) << 27) & BM_PXP_WFE_B_STG3_F8X1_OUT3_2_LUTOUT91)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_2_LUTOUT90 0x04000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_2_LUTOUT90(v) \
+ (((v) << 26) & BM_PXP_WFE_B_STG3_F8X1_OUT3_2_LUTOUT90)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_2_LUTOUT89 0x02000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_2_LUTOUT89(v) \
+ (((v) << 25) & BM_PXP_WFE_B_STG3_F8X1_OUT3_2_LUTOUT89)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_2_LUTOUT88 0x01000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_2_LUTOUT88(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STG3_F8X1_OUT3_2_LUTOUT88)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_2_LUTOUT87 0x00800000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_2_LUTOUT87(v) \
+ (((v) << 23) & BM_PXP_WFE_B_STG3_F8X1_OUT3_2_LUTOUT87)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_2_LUTOUT86 0x00400000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_2_LUTOUT86(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STG3_F8X1_OUT3_2_LUTOUT86)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_2_LUTOUT85 0x00200000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_2_LUTOUT85(v) \
+ (((v) << 21) & BM_PXP_WFE_B_STG3_F8X1_OUT3_2_LUTOUT85)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_2_LUTOUT84 0x00100000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_2_LUTOUT84(v) \
+ (((v) << 20) & BM_PXP_WFE_B_STG3_F8X1_OUT3_2_LUTOUT84)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_2_LUTOUT83 0x00080000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_2_LUTOUT83(v) \
+ (((v) << 19) & BM_PXP_WFE_B_STG3_F8X1_OUT3_2_LUTOUT83)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_2_LUTOUT82 0x00040000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_2_LUTOUT82(v) \
+ (((v) << 18) & BM_PXP_WFE_B_STG3_F8X1_OUT3_2_LUTOUT82)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_2_LUTOUT81 0x00020000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_2_LUTOUT81(v) \
+ (((v) << 17) & BM_PXP_WFE_B_STG3_F8X1_OUT3_2_LUTOUT81)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_2_LUTOUT80 0x00010000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_2_LUTOUT80(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STG3_F8X1_OUT3_2_LUTOUT80)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_2_LUTOUT79 0x00008000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_2_LUTOUT79(v) \
+ (((v) << 15) & BM_PXP_WFE_B_STG3_F8X1_OUT3_2_LUTOUT79)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_2_LUTOUT78 0x00004000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_2_LUTOUT78(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STG3_F8X1_OUT3_2_LUTOUT78)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_2_LUTOUT77 0x00002000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_2_LUTOUT77(v) \
+ (((v) << 13) & BM_PXP_WFE_B_STG3_F8X1_OUT3_2_LUTOUT77)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_2_LUTOUT76 0x00001000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_2_LUTOUT76(v) \
+ (((v) << 12) & BM_PXP_WFE_B_STG3_F8X1_OUT3_2_LUTOUT76)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_2_LUTOUT75 0x00000800
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_2_LUTOUT75(v) \
+ (((v) << 11) & BM_PXP_WFE_B_STG3_F8X1_OUT3_2_LUTOUT75)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_2_LUTOUT74 0x00000400
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_2_LUTOUT74(v) \
+ (((v) << 10) & BM_PXP_WFE_B_STG3_F8X1_OUT3_2_LUTOUT74)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_2_LUTOUT73 0x00000200
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_2_LUTOUT73(v) \
+ (((v) << 9) & BM_PXP_WFE_B_STG3_F8X1_OUT3_2_LUTOUT73)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_2_LUTOUT72 0x00000100
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_2_LUTOUT72(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STG3_F8X1_OUT3_2_LUTOUT72)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_2_LUTOUT71 0x00000080
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_2_LUTOUT71(v) \
+ (((v) << 7) & BM_PXP_WFE_B_STG3_F8X1_OUT3_2_LUTOUT71)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_2_LUTOUT70 0x00000040
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_2_LUTOUT70(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STG3_F8X1_OUT3_2_LUTOUT70)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_2_LUTOUT69 0x00000020
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_2_LUTOUT69(v) \
+ (((v) << 5) & BM_PXP_WFE_B_STG3_F8X1_OUT3_2_LUTOUT69)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_2_LUTOUT68 0x00000010
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_2_LUTOUT68(v) \
+ (((v) << 4) & BM_PXP_WFE_B_STG3_F8X1_OUT3_2_LUTOUT68)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_2_LUTOUT67 0x00000008
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_2_LUTOUT67(v) \
+ (((v) << 3) & BM_PXP_WFE_B_STG3_F8X1_OUT3_2_LUTOUT67)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_2_LUTOUT66 0x00000004
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_2_LUTOUT66(v) \
+ (((v) << 2) & BM_PXP_WFE_B_STG3_F8X1_OUT3_2_LUTOUT66)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_2_LUTOUT65 0x00000002
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_2_LUTOUT65(v) \
+ (((v) << 1) & BM_PXP_WFE_B_STG3_F8X1_OUT3_2_LUTOUT65)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_2_LUTOUT64 0x00000001
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_2_LUTOUT64(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STG3_F8X1_OUT3_2_LUTOUT64)
+
+#define HW_PXP_WFE_B_STG3_F8X1_OUT3_3 (0x00002740)
+
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_3_LUTOUT127 0x80000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_3_LUTOUT127(v) \
+ (((v) << 31) & BM_PXP_WFE_B_STG3_F8X1_OUT3_3_LUTOUT127)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_3_LUTOUT126 0x40000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_3_LUTOUT126(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STG3_F8X1_OUT3_3_LUTOUT126)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_3_LUTOUT125 0x20000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_3_LUTOUT125(v) \
+ (((v) << 29) & BM_PXP_WFE_B_STG3_F8X1_OUT3_3_LUTOUT125)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_3_LUTOUT124 0x10000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_3_LUTOUT124(v) \
+ (((v) << 28) & BM_PXP_WFE_B_STG3_F8X1_OUT3_3_LUTOUT124)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_3_LUTOUT123 0x08000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_3_LUTOUT123(v) \
+ (((v) << 27) & BM_PXP_WFE_B_STG3_F8X1_OUT3_3_LUTOUT123)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_3_LUTOUT122 0x04000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_3_LUTOUT122(v) \
+ (((v) << 26) & BM_PXP_WFE_B_STG3_F8X1_OUT3_3_LUTOUT122)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_3_LUTOUT121 0x02000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_3_LUTOUT121(v) \
+ (((v) << 25) & BM_PXP_WFE_B_STG3_F8X1_OUT3_3_LUTOUT121)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_3_LUTOUT120 0x01000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_3_LUTOUT120(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STG3_F8X1_OUT3_3_LUTOUT120)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_3_LUTOUT119 0x00800000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_3_LUTOUT119(v) \
+ (((v) << 23) & BM_PXP_WFE_B_STG3_F8X1_OUT3_3_LUTOUT119)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_3_LUTOUT118 0x00400000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_3_LUTOUT118(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STG3_F8X1_OUT3_3_LUTOUT118)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_3_LUTOUT117 0x00200000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_3_LUTOUT117(v) \
+ (((v) << 21) & BM_PXP_WFE_B_STG3_F8X1_OUT3_3_LUTOUT117)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_3_LUTOUT116 0x00100000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_3_LUTOUT116(v) \
+ (((v) << 20) & BM_PXP_WFE_B_STG3_F8X1_OUT3_3_LUTOUT116)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_3_LUTOUT115 0x00080000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_3_LUTOUT115(v) \
+ (((v) << 19) & BM_PXP_WFE_B_STG3_F8X1_OUT3_3_LUTOUT115)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_3_LUTOUT114 0x00040000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_3_LUTOUT114(v) \
+ (((v) << 18) & BM_PXP_WFE_B_STG3_F8X1_OUT3_3_LUTOUT114)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_3_LUTOUT113 0x00020000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_3_LUTOUT113(v) \
+ (((v) << 17) & BM_PXP_WFE_B_STG3_F8X1_OUT3_3_LUTOUT113)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_3_LUTOUT112 0x00010000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_3_LUTOUT112(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STG3_F8X1_OUT3_3_LUTOUT112)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_3_LUTOUT111 0x00008000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_3_LUTOUT111(v) \
+ (((v) << 15) & BM_PXP_WFE_B_STG3_F8X1_OUT3_3_LUTOUT111)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_3_LUTOUT110 0x00004000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_3_LUTOUT110(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STG3_F8X1_OUT3_3_LUTOUT110)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_3_LUTOUT109 0x00002000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_3_LUTOUT109(v) \
+ (((v) << 13) & BM_PXP_WFE_B_STG3_F8X1_OUT3_3_LUTOUT109)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_3_LUTOUT108 0x00001000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_3_LUTOUT108(v) \
+ (((v) << 12) & BM_PXP_WFE_B_STG3_F8X1_OUT3_3_LUTOUT108)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_3_LUTOUT107 0x00000800
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_3_LUTOUT107(v) \
+ (((v) << 11) & BM_PXP_WFE_B_STG3_F8X1_OUT3_3_LUTOUT107)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_3_LUTOUT106 0x00000400
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_3_LUTOUT106(v) \
+ (((v) << 10) & BM_PXP_WFE_B_STG3_F8X1_OUT3_3_LUTOUT106)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_3_LUTOUT105 0x00000200
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_3_LUTOUT105(v) \
+ (((v) << 9) & BM_PXP_WFE_B_STG3_F8X1_OUT3_3_LUTOUT105)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_3_LUTOUT104 0x00000100
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_3_LUTOUT104(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STG3_F8X1_OUT3_3_LUTOUT104)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_3_LUTOUT103 0x00000080
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_3_LUTOUT103(v) \
+ (((v) << 7) & BM_PXP_WFE_B_STG3_F8X1_OUT3_3_LUTOUT103)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_3_LUTOUT102 0x00000040
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_3_LUTOUT102(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STG3_F8X1_OUT3_3_LUTOUT102)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_3_LUTOUT101 0x00000020
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_3_LUTOUT101(v) \
+ (((v) << 5) & BM_PXP_WFE_B_STG3_F8X1_OUT3_3_LUTOUT101)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_3_LUTOUT100 0x00000010
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_3_LUTOUT100(v) \
+ (((v) << 4) & BM_PXP_WFE_B_STG3_F8X1_OUT3_3_LUTOUT100)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_3_LUTOUT99 0x00000008
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_3_LUTOUT99(v) \
+ (((v) << 3) & BM_PXP_WFE_B_STG3_F8X1_OUT3_3_LUTOUT99)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_3_LUTOUT98 0x00000004
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_3_LUTOUT98(v) \
+ (((v) << 2) & BM_PXP_WFE_B_STG3_F8X1_OUT3_3_LUTOUT98)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_3_LUTOUT97 0x00000002
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_3_LUTOUT97(v) \
+ (((v) << 1) & BM_PXP_WFE_B_STG3_F8X1_OUT3_3_LUTOUT97)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_3_LUTOUT96 0x00000001
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_3_LUTOUT96(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STG3_F8X1_OUT3_3_LUTOUT96)
+
+#define HW_PXP_WFE_B_STG3_F8X1_OUT3_4 (0x00002750)
+
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_4_LUTOUT159 0x80000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_4_LUTOUT159(v) \
+ (((v) << 31) & BM_PXP_WFE_B_STG3_F8X1_OUT3_4_LUTOUT159)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_4_LUTOUT158 0x40000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_4_LUTOUT158(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STG3_F8X1_OUT3_4_LUTOUT158)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_4_LUTOUT157 0x20000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_4_LUTOUT157(v) \
+ (((v) << 29) & BM_PXP_WFE_B_STG3_F8X1_OUT3_4_LUTOUT157)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_4_LUTOUT156 0x10000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_4_LUTOUT156(v) \
+ (((v) << 28) & BM_PXP_WFE_B_STG3_F8X1_OUT3_4_LUTOUT156)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_4_LUTOUT155 0x08000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_4_LUTOUT155(v) \
+ (((v) << 27) & BM_PXP_WFE_B_STG3_F8X1_OUT3_4_LUTOUT155)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_4_LUTOUT154 0x04000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_4_LUTOUT154(v) \
+ (((v) << 26) & BM_PXP_WFE_B_STG3_F8X1_OUT3_4_LUTOUT154)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_4_LUTOUT153 0x02000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_4_LUTOUT153(v) \
+ (((v) << 25) & BM_PXP_WFE_B_STG3_F8X1_OUT3_4_LUTOUT153)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_4_LUTOUT152 0x01000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_4_LUTOUT152(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STG3_F8X1_OUT3_4_LUTOUT152)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_4_LUTOUT151 0x00800000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_4_LUTOUT151(v) \
+ (((v) << 23) & BM_PXP_WFE_B_STG3_F8X1_OUT3_4_LUTOUT151)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_4_LUTOUT150 0x00400000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_4_LUTOUT150(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STG3_F8X1_OUT3_4_LUTOUT150)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_4_LUTOUT149 0x00200000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_4_LUTOUT149(v) \
+ (((v) << 21) & BM_PXP_WFE_B_STG3_F8X1_OUT3_4_LUTOUT149)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_4_LUTOUT148 0x00100000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_4_LUTOUT148(v) \
+ (((v) << 20) & BM_PXP_WFE_B_STG3_F8X1_OUT3_4_LUTOUT148)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_4_LUTOUT147 0x00080000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_4_LUTOUT147(v) \
+ (((v) << 19) & BM_PXP_WFE_B_STG3_F8X1_OUT3_4_LUTOUT147)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_4_LUTOUT146 0x00040000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_4_LUTOUT146(v) \
+ (((v) << 18) & BM_PXP_WFE_B_STG3_F8X1_OUT3_4_LUTOUT146)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_4_LUTOUT145 0x00020000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_4_LUTOUT145(v) \
+ (((v) << 17) & BM_PXP_WFE_B_STG3_F8X1_OUT3_4_LUTOUT145)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_4_LUTOUT144 0x00010000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_4_LUTOUT144(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STG3_F8X1_OUT3_4_LUTOUT144)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_4_LUTOUT143 0x00008000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_4_LUTOUT143(v) \
+ (((v) << 15) & BM_PXP_WFE_B_STG3_F8X1_OUT3_4_LUTOUT143)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_4_LUTOUT142 0x00004000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_4_LUTOUT142(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STG3_F8X1_OUT3_4_LUTOUT142)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_4_LUTOUT141 0x00002000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_4_LUTOUT141(v) \
+ (((v) << 13) & BM_PXP_WFE_B_STG3_F8X1_OUT3_4_LUTOUT141)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_4_LUTOUT140 0x00001000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_4_LUTOUT140(v) \
+ (((v) << 12) & BM_PXP_WFE_B_STG3_F8X1_OUT3_4_LUTOUT140)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_4_LUTOUT139 0x00000800
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_4_LUTOUT139(v) \
+ (((v) << 11) & BM_PXP_WFE_B_STG3_F8X1_OUT3_4_LUTOUT139)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_4_LUTOUT138 0x00000400
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_4_LUTOUT138(v) \
+ (((v) << 10) & BM_PXP_WFE_B_STG3_F8X1_OUT3_4_LUTOUT138)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_4_LUTOUT137 0x00000200
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_4_LUTOUT137(v) \
+ (((v) << 9) & BM_PXP_WFE_B_STG3_F8X1_OUT3_4_LUTOUT137)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_4_LUTOUT136 0x00000100
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_4_LUTOUT136(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STG3_F8X1_OUT3_4_LUTOUT136)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_4_LUTOUT135 0x00000080
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_4_LUTOUT135(v) \
+ (((v) << 7) & BM_PXP_WFE_B_STG3_F8X1_OUT3_4_LUTOUT135)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_4_LUTOUT134 0x00000040
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_4_LUTOUT134(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STG3_F8X1_OUT3_4_LUTOUT134)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_4_LUTOUT133 0x00000020
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_4_LUTOUT133(v) \
+ (((v) << 5) & BM_PXP_WFE_B_STG3_F8X1_OUT3_4_LUTOUT133)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_4_LUTOUT132 0x00000010
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_4_LUTOUT132(v) \
+ (((v) << 4) & BM_PXP_WFE_B_STG3_F8X1_OUT3_4_LUTOUT132)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_4_LUTOUT131 0x00000008
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_4_LUTOUT131(v) \
+ (((v) << 3) & BM_PXP_WFE_B_STG3_F8X1_OUT3_4_LUTOUT131)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_4_LUTOUT130 0x00000004
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_4_LUTOUT130(v) \
+ (((v) << 2) & BM_PXP_WFE_B_STG3_F8X1_OUT3_4_LUTOUT130)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_4_LUTOUT129 0x00000002
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_4_LUTOUT129(v) \
+ (((v) << 1) & BM_PXP_WFE_B_STG3_F8X1_OUT3_4_LUTOUT129)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_4_LUTOUT128 0x00000001
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_4_LUTOUT128(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STG3_F8X1_OUT3_4_LUTOUT128)
+
+#define HW_PXP_WFE_B_STG3_F8X1_OUT3_5 (0x00002760)
+
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_5_LUTOUT191 0x80000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_5_LUTOUT191(v) \
+ (((v) << 31) & BM_PXP_WFE_B_STG3_F8X1_OUT3_5_LUTOUT191)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_5_LUTOUT190 0x40000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_5_LUTOUT190(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STG3_F8X1_OUT3_5_LUTOUT190)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_5_LUTOUT189 0x20000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_5_LUTOUT189(v) \
+ (((v) << 29) & BM_PXP_WFE_B_STG3_F8X1_OUT3_5_LUTOUT189)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_5_LUTOUT188 0x10000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_5_LUTOUT188(v) \
+ (((v) << 28) & BM_PXP_WFE_B_STG3_F8X1_OUT3_5_LUTOUT188)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_5_LUTOUT187 0x08000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_5_LUTOUT187(v) \
+ (((v) << 27) & BM_PXP_WFE_B_STG3_F8X1_OUT3_5_LUTOUT187)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_5_LUTOUT186 0x04000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_5_LUTOUT186(v) \
+ (((v) << 26) & BM_PXP_WFE_B_STG3_F8X1_OUT3_5_LUTOUT186)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_5_LUTOUT185 0x02000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_5_LUTOUT185(v) \
+ (((v) << 25) & BM_PXP_WFE_B_STG3_F8X1_OUT3_5_LUTOUT185)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_5_LUTOUT184 0x01000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_5_LUTOUT184(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STG3_F8X1_OUT3_5_LUTOUT184)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_5_LUTOUT183 0x00800000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_5_LUTOUT183(v) \
+ (((v) << 23) & BM_PXP_WFE_B_STG3_F8X1_OUT3_5_LUTOUT183)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_5_LUTOUT182 0x00400000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_5_LUTOUT182(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STG3_F8X1_OUT3_5_LUTOUT182)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_5_LUTOUT181 0x00200000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_5_LUTOUT181(v) \
+ (((v) << 21) & BM_PXP_WFE_B_STG3_F8X1_OUT3_5_LUTOUT181)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_5_LUTOUT180 0x00100000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_5_LUTOUT180(v) \
+ (((v) << 20) & BM_PXP_WFE_B_STG3_F8X1_OUT3_5_LUTOUT180)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_5_LUTOUT179 0x00080000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_5_LUTOUT179(v) \
+ (((v) << 19) & BM_PXP_WFE_B_STG3_F8X1_OUT3_5_LUTOUT179)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_5_LUTOUT178 0x00040000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_5_LUTOUT178(v) \
+ (((v) << 18) & BM_PXP_WFE_B_STG3_F8X1_OUT3_5_LUTOUT178)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_5_LUTOUT177 0x00020000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_5_LUTOUT177(v) \
+ (((v) << 17) & BM_PXP_WFE_B_STG3_F8X1_OUT3_5_LUTOUT177)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_5_LUTOUT176 0x00010000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_5_LUTOUT176(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STG3_F8X1_OUT3_5_LUTOUT176)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_5_LUTOUT175 0x00008000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_5_LUTOUT175(v) \
+ (((v) << 15) & BM_PXP_WFE_B_STG3_F8X1_OUT3_5_LUTOUT175)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_5_LUTOUT174 0x00004000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_5_LUTOUT174(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STG3_F8X1_OUT3_5_LUTOUT174)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_5_LUTOUT173 0x00002000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_5_LUTOUT173(v) \
+ (((v) << 13) & BM_PXP_WFE_B_STG3_F8X1_OUT3_5_LUTOUT173)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_5_LUTOUT172 0x00001000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_5_LUTOUT172(v) \
+ (((v) << 12) & BM_PXP_WFE_B_STG3_F8X1_OUT3_5_LUTOUT172)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_5_LUTOUT171 0x00000800
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_5_LUTOUT171(v) \
+ (((v) << 11) & BM_PXP_WFE_B_STG3_F8X1_OUT3_5_LUTOUT171)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_5_LUTOUT170 0x00000400
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_5_LUTOUT170(v) \
+ (((v) << 10) & BM_PXP_WFE_B_STG3_F8X1_OUT3_5_LUTOUT170)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_5_LUTOUT169 0x00000200
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_5_LUTOUT169(v) \
+ (((v) << 9) & BM_PXP_WFE_B_STG3_F8X1_OUT3_5_LUTOUT169)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_5_LUTOUT168 0x00000100
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_5_LUTOUT168(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STG3_F8X1_OUT3_5_LUTOUT168)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_5_LUTOUT167 0x00000080
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_5_LUTOUT167(v) \
+ (((v) << 7) & BM_PXP_WFE_B_STG3_F8X1_OUT3_5_LUTOUT167)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_5_LUTOUT166 0x00000040
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_5_LUTOUT166(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STG3_F8X1_OUT3_5_LUTOUT166)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_5_LUTOUT165 0x00000020
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_5_LUTOUT165(v) \
+ (((v) << 5) & BM_PXP_WFE_B_STG3_F8X1_OUT3_5_LUTOUT165)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_5_LUTOUT164 0x00000010
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_5_LUTOUT164(v) \
+ (((v) << 4) & BM_PXP_WFE_B_STG3_F8X1_OUT3_5_LUTOUT164)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_5_LUTOUT163 0x00000008
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_5_LUTOUT163(v) \
+ (((v) << 3) & BM_PXP_WFE_B_STG3_F8X1_OUT3_5_LUTOUT163)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_5_LUTOUT162 0x00000004
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_5_LUTOUT162(v) \
+ (((v) << 2) & BM_PXP_WFE_B_STG3_F8X1_OUT3_5_LUTOUT162)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_5_LUTOUT161 0x00000002
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_5_LUTOUT161(v) \
+ (((v) << 1) & BM_PXP_WFE_B_STG3_F8X1_OUT3_5_LUTOUT161)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_5_LUTOUT160 0x00000001
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_5_LUTOUT160(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STG3_F8X1_OUT3_5_LUTOUT160)
+
+#define HW_PXP_WFE_B_STG3_F8X1_OUT3_6 (0x00002770)
+
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_6_LUTOUT223 0x80000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_6_LUTOUT223(v) \
+ (((v) << 31) & BM_PXP_WFE_B_STG3_F8X1_OUT3_6_LUTOUT223)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_6_LUTOUT222 0x40000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_6_LUTOUT222(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STG3_F8X1_OUT3_6_LUTOUT222)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_6_LUTOUT221 0x20000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_6_LUTOUT221(v) \
+ (((v) << 29) & BM_PXP_WFE_B_STG3_F8X1_OUT3_6_LUTOUT221)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_6_LUTOUT220 0x10000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_6_LUTOUT220(v) \
+ (((v) << 28) & BM_PXP_WFE_B_STG3_F8X1_OUT3_6_LUTOUT220)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_6_LUTOUT219 0x08000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_6_LUTOUT219(v) \
+ (((v) << 27) & BM_PXP_WFE_B_STG3_F8X1_OUT3_6_LUTOUT219)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_6_LUTOUT218 0x04000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_6_LUTOUT218(v) \
+ (((v) << 26) & BM_PXP_WFE_B_STG3_F8X1_OUT3_6_LUTOUT218)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_6_LUTOUT217 0x02000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_6_LUTOUT217(v) \
+ (((v) << 25) & BM_PXP_WFE_B_STG3_F8X1_OUT3_6_LUTOUT217)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_6_LUTOUT216 0x01000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_6_LUTOUT216(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STG3_F8X1_OUT3_6_LUTOUT216)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_6_LUTOUT215 0x00800000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_6_LUTOUT215(v) \
+ (((v) << 23) & BM_PXP_WFE_B_STG3_F8X1_OUT3_6_LUTOUT215)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_6_LUTOUT214 0x00400000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_6_LUTOUT214(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STG3_F8X1_OUT3_6_LUTOUT214)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_6_LUTOUT213 0x00200000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_6_LUTOUT213(v) \
+ (((v) << 21) & BM_PXP_WFE_B_STG3_F8X1_OUT3_6_LUTOUT213)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_6_LUTOUT212 0x00100000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_6_LUTOUT212(v) \
+ (((v) << 20) & BM_PXP_WFE_B_STG3_F8X1_OUT3_6_LUTOUT212)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_6_LUTOUT211 0x00080000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_6_LUTOUT211(v) \
+ (((v) << 19) & BM_PXP_WFE_B_STG3_F8X1_OUT3_6_LUTOUT211)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_6_LUTOUT210 0x00040000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_6_LUTOUT210(v) \
+ (((v) << 18) & BM_PXP_WFE_B_STG3_F8X1_OUT3_6_LUTOUT210)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_6_LUTOUT209 0x00020000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_6_LUTOUT209(v) \
+ (((v) << 17) & BM_PXP_WFE_B_STG3_F8X1_OUT3_6_LUTOUT209)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_6_LUTOUT208 0x00010000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_6_LUTOUT208(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STG3_F8X1_OUT3_6_LUTOUT208)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_6_LUTOUT207 0x00008000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_6_LUTOUT207(v) \
+ (((v) << 15) & BM_PXP_WFE_B_STG3_F8X1_OUT3_6_LUTOUT207)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_6_LUTOUT206 0x00004000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_6_LUTOUT206(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STG3_F8X1_OUT3_6_LUTOUT206)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_6_LUTOUT205 0x00002000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_6_LUTOUT205(v) \
+ (((v) << 13) & BM_PXP_WFE_B_STG3_F8X1_OUT3_6_LUTOUT205)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_6_LUTOUT204 0x00001000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_6_LUTOUT204(v) \
+ (((v) << 12) & BM_PXP_WFE_B_STG3_F8X1_OUT3_6_LUTOUT204)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_6_LUTOUT203 0x00000800
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_6_LUTOUT203(v) \
+ (((v) << 11) & BM_PXP_WFE_B_STG3_F8X1_OUT3_6_LUTOUT203)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_6_LUTOUT202 0x00000400
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_6_LUTOUT202(v) \
+ (((v) << 10) & BM_PXP_WFE_B_STG3_F8X1_OUT3_6_LUTOUT202)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_6_LUTOUT201 0x00000200
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_6_LUTOUT201(v) \
+ (((v) << 9) & BM_PXP_WFE_B_STG3_F8X1_OUT3_6_LUTOUT201)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_6_LUTOUT200 0x00000100
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_6_LUTOUT200(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STG3_F8X1_OUT3_6_LUTOUT200)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_6_LUTOUT199 0x00000080
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_6_LUTOUT199(v) \
+ (((v) << 7) & BM_PXP_WFE_B_STG3_F8X1_OUT3_6_LUTOUT199)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_6_LUTOUT198 0x00000040
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_6_LUTOUT198(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STG3_F8X1_OUT3_6_LUTOUT198)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_6_LUTOUT197 0x00000020
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_6_LUTOUT197(v) \
+ (((v) << 5) & BM_PXP_WFE_B_STG3_F8X1_OUT3_6_LUTOUT197)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_6_LUTOUT196 0x00000010
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_6_LUTOUT196(v) \
+ (((v) << 4) & BM_PXP_WFE_B_STG3_F8X1_OUT3_6_LUTOUT196)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_6_LUTOUT195 0x00000008
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_6_LUTOUT195(v) \
+ (((v) << 3) & BM_PXP_WFE_B_STG3_F8X1_OUT3_6_LUTOUT195)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_6_LUTOUT194 0x00000004
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_6_LUTOUT194(v) \
+ (((v) << 2) & BM_PXP_WFE_B_STG3_F8X1_OUT3_6_LUTOUT194)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_6_LUTOUT193 0x00000002
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_6_LUTOUT193(v) \
+ (((v) << 1) & BM_PXP_WFE_B_STG3_F8X1_OUT3_6_LUTOUT193)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_6_LUTOUT192 0x00000001
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_6_LUTOUT192(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STG3_F8X1_OUT3_6_LUTOUT192)
+
+#define HW_PXP_WFE_B_STG3_F8X1_OUT3_7 (0x00002780)
+
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_7_LUTOUT255 0x80000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_7_LUTOUT255(v) \
+ (((v) << 31) & BM_PXP_WFE_B_STG3_F8X1_OUT3_7_LUTOUT255)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_7_LUTOUT254 0x40000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_7_LUTOUT254(v) \
+ (((v) << 30) & BM_PXP_WFE_B_STG3_F8X1_OUT3_7_LUTOUT254)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_7_LUTOUT253 0x20000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_7_LUTOUT253(v) \
+ (((v) << 29) & BM_PXP_WFE_B_STG3_F8X1_OUT3_7_LUTOUT253)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_7_LUTOUT252 0x10000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_7_LUTOUT252(v) \
+ (((v) << 28) & BM_PXP_WFE_B_STG3_F8X1_OUT3_7_LUTOUT252)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_7_LUTOUT251 0x08000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_7_LUTOUT251(v) \
+ (((v) << 27) & BM_PXP_WFE_B_STG3_F8X1_OUT3_7_LUTOUT251)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_7_LUTOUT250 0x04000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_7_LUTOUT250(v) \
+ (((v) << 26) & BM_PXP_WFE_B_STG3_F8X1_OUT3_7_LUTOUT250)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_7_LUTOUT249 0x02000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_7_LUTOUT249(v) \
+ (((v) << 25) & BM_PXP_WFE_B_STG3_F8X1_OUT3_7_LUTOUT249)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_7_LUTOUT248 0x01000000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_7_LUTOUT248(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STG3_F8X1_OUT3_7_LUTOUT248)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_7_LUTOUT247 0x00800000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_7_LUTOUT247(v) \
+ (((v) << 23) & BM_PXP_WFE_B_STG3_F8X1_OUT3_7_LUTOUT247)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_7_LUTOUT246 0x00400000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_7_LUTOUT246(v) \
+ (((v) << 22) & BM_PXP_WFE_B_STG3_F8X1_OUT3_7_LUTOUT246)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_7_LUTOUT245 0x00200000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_7_LUTOUT245(v) \
+ (((v) << 21) & BM_PXP_WFE_B_STG3_F8X1_OUT3_7_LUTOUT245)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_7_LUTOUT244 0x00100000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_7_LUTOUT244(v) \
+ (((v) << 20) & BM_PXP_WFE_B_STG3_F8X1_OUT3_7_LUTOUT244)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_7_LUTOUT243 0x00080000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_7_LUTOUT243(v) \
+ (((v) << 19) & BM_PXP_WFE_B_STG3_F8X1_OUT3_7_LUTOUT243)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_7_LUTOUT242 0x00040000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_7_LUTOUT242(v) \
+ (((v) << 18) & BM_PXP_WFE_B_STG3_F8X1_OUT3_7_LUTOUT242)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_7_LUTOUT241 0x00020000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_7_LUTOUT241(v) \
+ (((v) << 17) & BM_PXP_WFE_B_STG3_F8X1_OUT3_7_LUTOUT241)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_7_LUTOUT240 0x00010000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_7_LUTOUT240(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STG3_F8X1_OUT3_7_LUTOUT240)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_7_LUTOUT239 0x00008000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_7_LUTOUT239(v) \
+ (((v) << 15) & BM_PXP_WFE_B_STG3_F8X1_OUT3_7_LUTOUT239)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_7_LUTOUT238 0x00004000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_7_LUTOUT238(v) \
+ (((v) << 14) & BM_PXP_WFE_B_STG3_F8X1_OUT3_7_LUTOUT238)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_7_LUTOUT237 0x00002000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_7_LUTOUT237(v) \
+ (((v) << 13) & BM_PXP_WFE_B_STG3_F8X1_OUT3_7_LUTOUT237)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_7_LUTOUT236 0x00001000
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_7_LUTOUT236(v) \
+ (((v) << 12) & BM_PXP_WFE_B_STG3_F8X1_OUT3_7_LUTOUT236)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_7_LUTOUT235 0x00000800
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_7_LUTOUT235(v) \
+ (((v) << 11) & BM_PXP_WFE_B_STG3_F8X1_OUT3_7_LUTOUT235)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_7_LUTOUT234 0x00000400
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_7_LUTOUT234(v) \
+ (((v) << 10) & BM_PXP_WFE_B_STG3_F8X1_OUT3_7_LUTOUT234)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_7_LUTOUT233 0x00000200
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_7_LUTOUT233(v) \
+ (((v) << 9) & BM_PXP_WFE_B_STG3_F8X1_OUT3_7_LUTOUT233)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_7_LUTOUT232 0x00000100
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_7_LUTOUT232(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STG3_F8X1_OUT3_7_LUTOUT232)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_7_LUTOUT231 0x00000080
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_7_LUTOUT231(v) \
+ (((v) << 7) & BM_PXP_WFE_B_STG3_F8X1_OUT3_7_LUTOUT231)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_7_LUTOUT230 0x00000040
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_7_LUTOUT230(v) \
+ (((v) << 6) & BM_PXP_WFE_B_STG3_F8X1_OUT3_7_LUTOUT230)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_7_LUTOUT229 0x00000020
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_7_LUTOUT229(v) \
+ (((v) << 5) & BM_PXP_WFE_B_STG3_F8X1_OUT3_7_LUTOUT229)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_7_LUTOUT228 0x00000010
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_7_LUTOUT228(v) \
+ (((v) << 4) & BM_PXP_WFE_B_STG3_F8X1_OUT3_7_LUTOUT228)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_7_LUTOUT227 0x00000008
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_7_LUTOUT227(v) \
+ (((v) << 3) & BM_PXP_WFE_B_STG3_F8X1_OUT3_7_LUTOUT227)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_7_LUTOUT226 0x00000004
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_7_LUTOUT226(v) \
+ (((v) << 2) & BM_PXP_WFE_B_STG3_F8X1_OUT3_7_LUTOUT226)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_7_LUTOUT225 0x00000002
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_7_LUTOUT225(v) \
+ (((v) << 1) & BM_PXP_WFE_B_STG3_F8X1_OUT3_7_LUTOUT225)
+#define BM_PXP_WFE_B_STG3_F8X1_OUT3_7_LUTOUT224 0x00000001
+#define BF_PXP_WFE_B_STG3_F8X1_OUT3_7_LUTOUT224(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STG3_F8X1_OUT3_7_LUTOUT224)
+
+#define HW_PXP_WFE_B_STG3_F8X1_MASKS (0x00002790)
+
+#define BP_PXP_WFE_B_STG3_F8X1_MASKS_MASK3 24
+#define BM_PXP_WFE_B_STG3_F8X1_MASKS_MASK3 0xFF000000
+#define BF_PXP_WFE_B_STG3_F8X1_MASKS_MASK3(v) \
+ (((v) << 24) & BM_PXP_WFE_B_STG3_F8X1_MASKS_MASK3)
+#define BP_PXP_WFE_B_STG3_F8X1_MASKS_MASK2 16
+#define BM_PXP_WFE_B_STG3_F8X1_MASKS_MASK2 0x00FF0000
+#define BF_PXP_WFE_B_STG3_F8X1_MASKS_MASK2(v) \
+ (((v) << 16) & BM_PXP_WFE_B_STG3_F8X1_MASKS_MASK2)
+#define BP_PXP_WFE_B_STG3_F8X1_MASKS_MASK1 8
+#define BM_PXP_WFE_B_STG3_F8X1_MASKS_MASK1 0x0000FF00
+#define BF_PXP_WFE_B_STG3_F8X1_MASKS_MASK1(v) \
+ (((v) << 8) & BM_PXP_WFE_B_STG3_F8X1_MASKS_MASK1)
+#define BP_PXP_WFE_B_STG3_F8X1_MASKS_MASK0 0
+#define BM_PXP_WFE_B_STG3_F8X1_MASKS_MASK0 0x000000FF
+#define BF_PXP_WFE_B_STG3_F8X1_MASKS_MASK0(v) \
+ (((v) << 0) & BM_PXP_WFE_B_STG3_F8X1_MASKS_MASK0)
+
+#define HW_PXP_ALU_A_CTRL (0x00002810)
+#define HW_PXP_ALU_A_CTRL_SET (0x00002814)
+#define HW_PXP_ALU_A_CTRL_CLR (0x00002818)
+#define HW_PXP_ALU_A_CTRL_TOG (0x0000281c)
+
+#define BP_PXP_ALU_A_CTRL_RSVD0 29
+#define BM_PXP_ALU_A_CTRL_RSVD0 0xE0000000
+#define BF_PXP_ALU_A_CTRL_RSVD0(v) \
+ (((v) << 29) & BM_PXP_ALU_A_CTRL_RSVD0)
+#define BM_PXP_ALU_A_CTRL_DONE 0x10000000
+#define BF_PXP_ALU_A_CTRL_DONE(v) \
+ (((v) << 28) & BM_PXP_ALU_A_CTRL_DONE)
+#define BP_PXP_ALU_A_CTRL_RSVD1 21
+#define BM_PXP_ALU_A_CTRL_RSVD1 0x0FE00000
+#define BF_PXP_ALU_A_CTRL_RSVD1(v) \
+ (((v) << 21) & BM_PXP_ALU_A_CTRL_RSVD1)
+#define BM_PXP_ALU_A_CTRL_DONE_IRQ_EN 0x00100000
+#define BF_PXP_ALU_A_CTRL_DONE_IRQ_EN(v) \
+ (((v) << 20) & BM_PXP_ALU_A_CTRL_DONE_IRQ_EN)
+#define BP_PXP_ALU_A_CTRL_RSVD2 17
+#define BM_PXP_ALU_A_CTRL_RSVD2 0x000E0000
+#define BF_PXP_ALU_A_CTRL_RSVD2(v) \
+ (((v) << 17) & BM_PXP_ALU_A_CTRL_RSVD2)
+#define BM_PXP_ALU_A_CTRL_DONE_IRQ_FLAG 0x00010000
+#define BF_PXP_ALU_A_CTRL_DONE_IRQ_FLAG(v) \
+ (((v) << 16) & BM_PXP_ALU_A_CTRL_DONE_IRQ_FLAG)
+#define BP_PXP_ALU_A_CTRL_RSVD3 13
+#define BM_PXP_ALU_A_CTRL_RSVD3 0x0000E000
+#define BF_PXP_ALU_A_CTRL_RSVD3(v) \
+ (((v) << 13) & BM_PXP_ALU_A_CTRL_RSVD3)
+#define BM_PXP_ALU_A_CTRL_BYPASS 0x00001000
+#define BF_PXP_ALU_A_CTRL_BYPASS(v) \
+ (((v) << 12) & BM_PXP_ALU_A_CTRL_BYPASS)
+#define BV_PXP_ALU_A_CTRL_BYPASS__0 0x0
+#define BV_PXP_ALU_A_CTRL_BYPASS__1 0x1
+#define BP_PXP_ALU_A_CTRL_RSVD4 9
+#define BM_PXP_ALU_A_CTRL_RSVD4 0x00000E00
+#define BF_PXP_ALU_A_CTRL_RSVD4(v) \
+ (((v) << 9) & BM_PXP_ALU_A_CTRL_RSVD4)
+#define BM_PXP_ALU_A_CTRL_SW_RESET 0x00000100
+#define BF_PXP_ALU_A_CTRL_SW_RESET(v) \
+ (((v) << 8) & BM_PXP_ALU_A_CTRL_SW_RESET)
+#define BP_PXP_ALU_A_CTRL_RSVD5 5
+#define BM_PXP_ALU_A_CTRL_RSVD5 0x000000E0
+#define BF_PXP_ALU_A_CTRL_RSVD5(v) \
+ (((v) << 5) & BM_PXP_ALU_A_CTRL_RSVD5)
+#define BM_PXP_ALU_A_CTRL_START 0x00000010
+#define BF_PXP_ALU_A_CTRL_START(v) \
+ (((v) << 4) & BM_PXP_ALU_A_CTRL_START)
+#define BP_PXP_ALU_A_CTRL_RSVD6 1
+#define BM_PXP_ALU_A_CTRL_RSVD6 0x0000000E
+#define BF_PXP_ALU_A_CTRL_RSVD6(v) \
+ (((v) << 1) & BM_PXP_ALU_A_CTRL_RSVD6)
+#define BM_PXP_ALU_A_CTRL_ENABLE 0x00000001
+#define BF_PXP_ALU_A_CTRL_ENABLE(v) \
+ (((v) << 0) & BM_PXP_ALU_A_CTRL_ENABLE)
+#define BV_PXP_ALU_A_CTRL_ENABLE__0 0x0
+#define BV_PXP_ALU_A_CTRL_ENABLE__1 0x1
+
+#define HW_PXP_ALU_A_BUF_SIZE (0x00002820)
+
+#define BP_PXP_ALU_A_BUF_SIZE_RSVD0 28
+#define BM_PXP_ALU_A_BUF_SIZE_RSVD0 0xF0000000
+#define BF_PXP_ALU_A_BUF_SIZE_RSVD0(v) \
+ (((v) << 28) & BM_PXP_ALU_A_BUF_SIZE_RSVD0)
+#define BP_PXP_ALU_A_BUF_SIZE_BUF_HEIGHT 16
+#define BM_PXP_ALU_A_BUF_SIZE_BUF_HEIGHT 0x0FFF0000
+#define BF_PXP_ALU_A_BUF_SIZE_BUF_HEIGHT(v) \
+ (((v) << 16) & BM_PXP_ALU_A_BUF_SIZE_BUF_HEIGHT)
+#define BP_PXP_ALU_A_BUF_SIZE_RSVD1 12
+#define BM_PXP_ALU_A_BUF_SIZE_RSVD1 0x0000F000
+#define BF_PXP_ALU_A_BUF_SIZE_RSVD1(v) \
+ (((v) << 12) & BM_PXP_ALU_A_BUF_SIZE_RSVD1)
+#define BP_PXP_ALU_A_BUF_SIZE_BUF_WIDTH 0
+#define BM_PXP_ALU_A_BUF_SIZE_BUF_WIDTH 0x00000FFF
+#define BF_PXP_ALU_A_BUF_SIZE_BUF_WIDTH(v) \
+ (((v) << 0) & BM_PXP_ALU_A_BUF_SIZE_BUF_WIDTH)
+
+#define HW_PXP_ALU_A_INST_ENTRY (0x00002830)
+
+#define BP_PXP_ALU_A_INST_ENTRY_RSVD0 16
+#define BM_PXP_ALU_A_INST_ENTRY_RSVD0 0xFFFF0000
+#define BF_PXP_ALU_A_INST_ENTRY_RSVD0(v) \
+ (((v) << 16) & BM_PXP_ALU_A_INST_ENTRY_RSVD0)
+#define BP_PXP_ALU_A_INST_ENTRY_ENTRY_ADDR 0
+#define BM_PXP_ALU_A_INST_ENTRY_ENTRY_ADDR 0x0000FFFF
+#define BF_PXP_ALU_A_INST_ENTRY_ENTRY_ADDR(v) \
+ (((v) << 0) & BM_PXP_ALU_A_INST_ENTRY_ENTRY_ADDR)
+
+#define HW_PXP_ALU_A_PARAM (0x00002840)
+
+#define BP_PXP_ALU_A_PARAM_RSVD0 16
+#define BM_PXP_ALU_A_PARAM_RSVD0 0xFFFF0000
+#define BF_PXP_ALU_A_PARAM_RSVD0(v) \
+ (((v) << 16) & BM_PXP_ALU_A_PARAM_RSVD0)
+#define BP_PXP_ALU_A_PARAM_PARAM1 8
+#define BM_PXP_ALU_A_PARAM_PARAM1 0x0000FF00
+#define BF_PXP_ALU_A_PARAM_PARAM1(v) \
+ (((v) << 8) & BM_PXP_ALU_A_PARAM_PARAM1)
+#define BP_PXP_ALU_A_PARAM_PARAM0 0
+#define BM_PXP_ALU_A_PARAM_PARAM0 0x000000FF
+#define BF_PXP_ALU_A_PARAM_PARAM0(v) \
+ (((v) << 0) & BM_PXP_ALU_A_PARAM_PARAM0)
+
+#define HW_PXP_ALU_A_CONFIG (0x00002850)
+
+#define BP_PXP_ALU_A_CONFIG_BUF_ADDR 0
+#define BM_PXP_ALU_A_CONFIG_BUF_ADDR 0xFFFFFFFF
+#define BF_PXP_ALU_A_CONFIG_BUF_ADDR(v) (v)
+
+#define HW_PXP_ALU_A_LUT_CONFIG (0x00002860)
+#define HW_PXP_ALU_A_LUT_CONFIG_SET (0x00002864)
+#define HW_PXP_ALU_A_LUT_CONFIG_CLR (0x00002868)
+#define HW_PXP_ALU_A_LUT_CONFIG_TOG (0x0000286c)
+
+#define BP_PXP_ALU_A_LUT_CONFIG_RSVD0 6
+#define BM_PXP_ALU_A_LUT_CONFIG_RSVD0 0xFFFFFFC0
+#define BF_PXP_ALU_A_LUT_CONFIG_RSVD0(v) \
+ (((v) << 6) & BM_PXP_ALU_A_LUT_CONFIG_RSVD0)
+#define BP_PXP_ALU_A_LUT_CONFIG_MODE 4
+#define BM_PXP_ALU_A_LUT_CONFIG_MODE 0x00000030
+#define BF_PXP_ALU_A_LUT_CONFIG_MODE(v) \
+ (((v) << 4) & BM_PXP_ALU_A_LUT_CONFIG_MODE)
+#define BV_PXP_ALU_A_LUT_CONFIG_MODE__0 0x0
+#define BV_PXP_ALU_A_LUT_CONFIG_MODE__1 0x1
+#define BV_PXP_ALU_A_LUT_CONFIG_MODE__2 0x2
+#define BV_PXP_ALU_A_LUT_CONFIG_MODE__3 0x3
+#define BP_PXP_ALU_A_LUT_CONFIG_RSVD1 1
+#define BM_PXP_ALU_A_LUT_CONFIG_RSVD1 0x0000000E
+#define BF_PXP_ALU_A_LUT_CONFIG_RSVD1(v) \
+ (((v) << 1) & BM_PXP_ALU_A_LUT_CONFIG_RSVD1)
+#define BM_PXP_ALU_A_LUT_CONFIG_EN 0x00000001
+#define BF_PXP_ALU_A_LUT_CONFIG_EN(v) \
+ (((v) << 0) & BM_PXP_ALU_A_LUT_CONFIG_EN)
+
+#define HW_PXP_ALU_A_LUT_DATA0 (0x00002870)
+
+#define BP_PXP_ALU_A_LUT_DATA0_LUT_DATA_L 0
+#define BM_PXP_ALU_A_LUT_DATA0_LUT_DATA_L 0xFFFFFFFF
+#define BF_PXP_ALU_A_LUT_DATA0_LUT_DATA_L(v) (v)
+
+#define HW_PXP_ALU_A_LUT_DATA1 (0x00002880)
+
+#define BP_PXP_ALU_A_LUT_DATA1_LUT_DATA_H 0
+#define BM_PXP_ALU_A_LUT_DATA1_LUT_DATA_H 0xFFFFFFFF
+#define BF_PXP_ALU_A_LUT_DATA1_LUT_DATA_H(v) (v)
+
+#define HW_PXP_ALU_A_DBG (0x00002890)
+
+#define BP_PXP_ALU_A_DBG_DEBUG_SEL 24
+#define BM_PXP_ALU_A_DBG_DEBUG_SEL 0xFF000000
+#define BF_PXP_ALU_A_DBG_DEBUG_SEL(v) \
+ (((v) << 24) & BM_PXP_ALU_A_DBG_DEBUG_SEL)
+#define BP_PXP_ALU_A_DBG_DEBUG_VALUE 0
+#define BM_PXP_ALU_A_DBG_DEBUG_VALUE 0x00FFFFFF
+#define BF_PXP_ALU_A_DBG_DEBUG_VALUE(v) \
+ (((v) << 0) & BM_PXP_ALU_A_DBG_DEBUG_VALUE)
+
+#define HW_PXP_ALU_B_CTRL (0x000028a0)
+#define HW_PXP_ALU_B_CTRL_SET (0x000028a4)
+#define HW_PXP_ALU_B_CTRL_CLR (0x000028a8)
+#define HW_PXP_ALU_B_CTRL_TOG (0x000028ac)
+
+#define BP_PXP_ALU_B_CTRL_RSVD0 29
+#define BM_PXP_ALU_B_CTRL_RSVD0 0xE0000000
+#define BF_PXP_ALU_B_CTRL_RSVD0(v) \
+ (((v) << 29) & BM_PXP_ALU_B_CTRL_RSVD0)
+#define BM_PXP_ALU_B_CTRL_DONE 0x10000000
+#define BF_PXP_ALU_B_CTRL_DONE(v) \
+ (((v) << 28) & BM_PXP_ALU_B_CTRL_DONE)
+#define BP_PXP_ALU_B_CTRL_RSVD1 21
+#define BM_PXP_ALU_B_CTRL_RSVD1 0x0FE00000
+#define BF_PXP_ALU_B_CTRL_RSVD1(v) \
+ (((v) << 21) & BM_PXP_ALU_B_CTRL_RSVD1)
+#define BM_PXP_ALU_B_CTRL_DONE_IRQ_EN 0x00100000
+#define BF_PXP_ALU_B_CTRL_DONE_IRQ_EN(v) \
+ (((v) << 20) & BM_PXP_ALU_B_CTRL_DONE_IRQ_EN)
+#define BP_PXP_ALU_B_CTRL_RSVD2 17
+#define BM_PXP_ALU_B_CTRL_RSVD2 0x000E0000
+#define BF_PXP_ALU_B_CTRL_RSVD2(v) \
+ (((v) << 17) & BM_PXP_ALU_B_CTRL_RSVD2)
+#define BM_PXP_ALU_B_CTRL_DONE_IRQ_FLAG 0x00010000
+#define BF_PXP_ALU_B_CTRL_DONE_IRQ_FLAG(v) \
+ (((v) << 16) & BM_PXP_ALU_B_CTRL_DONE_IRQ_FLAG)
+#define BP_PXP_ALU_B_CTRL_RSVD3 13
+#define BM_PXP_ALU_B_CTRL_RSVD3 0x0000E000
+#define BF_PXP_ALU_B_CTRL_RSVD3(v) \
+ (((v) << 13) & BM_PXP_ALU_B_CTRL_RSVD3)
+#define BM_PXP_ALU_B_CTRL_BYPASS 0x00001000
+#define BF_PXP_ALU_B_CTRL_BYPASS(v) \
+ (((v) << 12) & BM_PXP_ALU_B_CTRL_BYPASS)
+#define BV_PXP_ALU_B_CTRL_BYPASS__0 0x0
+#define BV_PXP_ALU_B_CTRL_BYPASS__1 0x1
+#define BP_PXP_ALU_B_CTRL_RSVD4 9
+#define BM_PXP_ALU_B_CTRL_RSVD4 0x00000E00
+#define BF_PXP_ALU_B_CTRL_RSVD4(v) \
+ (((v) << 9) & BM_PXP_ALU_B_CTRL_RSVD4)
+#define BM_PXP_ALU_B_CTRL_SW_RESET 0x00000100
+#define BF_PXP_ALU_B_CTRL_SW_RESET(v) \
+ (((v) << 8) & BM_PXP_ALU_B_CTRL_SW_RESET)
+#define BP_PXP_ALU_B_CTRL_RSVD5 5
+#define BM_PXP_ALU_B_CTRL_RSVD5 0x000000E0
+#define BF_PXP_ALU_B_CTRL_RSVD5(v) \
+ (((v) << 5) & BM_PXP_ALU_B_CTRL_RSVD5)
+#define BM_PXP_ALU_B_CTRL_START 0x00000010
+#define BF_PXP_ALU_B_CTRL_START(v) \
+ (((v) << 4) & BM_PXP_ALU_B_CTRL_START)
+#define BP_PXP_ALU_B_CTRL_RSVD6 1
+#define BM_PXP_ALU_B_CTRL_RSVD6 0x0000000E
+#define BF_PXP_ALU_B_CTRL_RSVD6(v) \
+ (((v) << 1) & BM_PXP_ALU_B_CTRL_RSVD6)
+#define BM_PXP_ALU_B_CTRL_ENABLE 0x00000001
+#define BF_PXP_ALU_B_CTRL_ENABLE(v) \
+ (((v) << 0) & BM_PXP_ALU_B_CTRL_ENABLE)
+#define BV_PXP_ALU_B_CTRL_ENABLE__0 0x0
+#define BV_PXP_ALU_B_CTRL_ENABLE__1 0x1
+
+#define HW_PXP_ALU_B_BUF_SIZE (0x000028b0)
+
+#define BP_PXP_ALU_B_BUF_SIZE_RSVD0 28
+#define BM_PXP_ALU_B_BUF_SIZE_RSVD0 0xF0000000
+#define BF_PXP_ALU_B_BUF_SIZE_RSVD0(v) \
+ (((v) << 28) & BM_PXP_ALU_B_BUF_SIZE_RSVD0)
+#define BP_PXP_ALU_B_BUF_SIZE_BUF_HEIGHT 16
+#define BM_PXP_ALU_B_BUF_SIZE_BUF_HEIGHT 0x0FFF0000
+#define BF_PXP_ALU_B_BUF_SIZE_BUF_HEIGHT(v) \
+ (((v) << 16) & BM_PXP_ALU_B_BUF_SIZE_BUF_HEIGHT)
+#define BP_PXP_ALU_B_BUF_SIZE_RSVD1 12
+#define BM_PXP_ALU_B_BUF_SIZE_RSVD1 0x0000F000
+#define BF_PXP_ALU_B_BUF_SIZE_RSVD1(v) \
+ (((v) << 12) & BM_PXP_ALU_B_BUF_SIZE_RSVD1)
+#define BP_PXP_ALU_B_BUF_SIZE_BUF_WIDTH 0
+#define BM_PXP_ALU_B_BUF_SIZE_BUF_WIDTH 0x00000FFF
+#define BF_PXP_ALU_B_BUF_SIZE_BUF_WIDTH(v) \
+ (((v) << 0) & BM_PXP_ALU_B_BUF_SIZE_BUF_WIDTH)
+
+#define HW_PXP_ALU_B_INST_ENTRY (0x000028c0)
+
+#define BP_PXP_ALU_B_INST_ENTRY_RSVD0 16
+#define BM_PXP_ALU_B_INST_ENTRY_RSVD0 0xFFFF0000
+#define BF_PXP_ALU_B_INST_ENTRY_RSVD0(v) \
+ (((v) << 16) & BM_PXP_ALU_B_INST_ENTRY_RSVD0)
+#define BP_PXP_ALU_B_INST_ENTRY_ENTRY_ADDR 0
+#define BM_PXP_ALU_B_INST_ENTRY_ENTRY_ADDR 0x0000FFFF
+#define BF_PXP_ALU_B_INST_ENTRY_ENTRY_ADDR(v) \
+ (((v) << 0) & BM_PXP_ALU_B_INST_ENTRY_ENTRY_ADDR)
+
+#define HW_PXP_ALU_B_PARAM (0x000028d0)
+
+#define BP_PXP_ALU_B_PARAM_RSVD0 16
+#define BM_PXP_ALU_B_PARAM_RSVD0 0xFFFF0000
+#define BF_PXP_ALU_B_PARAM_RSVD0(v) \
+ (((v) << 16) & BM_PXP_ALU_B_PARAM_RSVD0)
+#define BP_PXP_ALU_B_PARAM_PARAM1 8
+#define BM_PXP_ALU_B_PARAM_PARAM1 0x0000FF00
+#define BF_PXP_ALU_B_PARAM_PARAM1(v) \
+ (((v) << 8) & BM_PXP_ALU_B_PARAM_PARAM1)
+#define BP_PXP_ALU_B_PARAM_PARAM0 0
+#define BM_PXP_ALU_B_PARAM_PARAM0 0x000000FF
+#define BF_PXP_ALU_B_PARAM_PARAM0(v) \
+ (((v) << 0) & BM_PXP_ALU_B_PARAM_PARAM0)
+
+#define HW_PXP_ALU_B_CONFIG (0x000028e0)
+
+#define BP_PXP_ALU_B_CONFIG_BUF_ADDR 0
+#define BM_PXP_ALU_B_CONFIG_BUF_ADDR 0xFFFFFFFF
+#define BF_PXP_ALU_B_CONFIG_BUF_ADDR(v) (v)
+
+#define HW_PXP_ALU_B_LUT_CONFIG (0x000028f0)
+#define HW_PXP_ALU_B_LUT_CONFIG_SET (0x000028f4)
+#define HW_PXP_ALU_B_LUT_CONFIG_CLR (0x000028f8)
+#define HW_PXP_ALU_B_LUT_CONFIG_TOG (0x000028fc)
+
+#define BP_PXP_ALU_B_LUT_CONFIG_RSVD0 6
+#define BM_PXP_ALU_B_LUT_CONFIG_RSVD0 0xFFFFFFC0
+#define BF_PXP_ALU_B_LUT_CONFIG_RSVD0(v) \
+ (((v) << 6) & BM_PXP_ALU_B_LUT_CONFIG_RSVD0)
+#define BP_PXP_ALU_B_LUT_CONFIG_MODE 4
+#define BM_PXP_ALU_B_LUT_CONFIG_MODE 0x00000030
+#define BF_PXP_ALU_B_LUT_CONFIG_MODE(v) \
+ (((v) << 4) & BM_PXP_ALU_B_LUT_CONFIG_MODE)
+#define BV_PXP_ALU_B_LUT_CONFIG_MODE__0 0x0
+#define BV_PXP_ALU_B_LUT_CONFIG_MODE__1 0x1
+#define BV_PXP_ALU_B_LUT_CONFIG_MODE__2 0x2
+#define BV_PXP_ALU_B_LUT_CONFIG_MODE__3 0x3
+#define BP_PXP_ALU_B_LUT_CONFIG_RSVD1 1
+#define BM_PXP_ALU_B_LUT_CONFIG_RSVD1 0x0000000E
+#define BF_PXP_ALU_B_LUT_CONFIG_RSVD1(v) \
+ (((v) << 1) & BM_PXP_ALU_B_LUT_CONFIG_RSVD1)
+#define BM_PXP_ALU_B_LUT_CONFIG_EN 0x00000001
+#define BF_PXP_ALU_B_LUT_CONFIG_EN(v) \
+ (((v) << 0) & BM_PXP_ALU_B_LUT_CONFIG_EN)
+
+#define HW_PXP_ALU_B_LUT_DATA0 (0x00002900)
+
+#define BP_PXP_ALU_B_LUT_DATA0_LUT_DATA_L 0
+#define BM_PXP_ALU_B_LUT_DATA0_LUT_DATA_L 0xFFFFFFFF
+#define BF_PXP_ALU_B_LUT_DATA0_LUT_DATA_L(v) (v)
+
+#define HW_PXP_ALU_B_LUT_DATA1 (0x00002910)
+
+#define BP_PXP_ALU_B_LUT_DATA1_LUT_DATA_H 0
+#define BM_PXP_ALU_B_LUT_DATA1_LUT_DATA_H 0xFFFFFFFF
+#define BF_PXP_ALU_B_LUT_DATA1_LUT_DATA_H(v) (v)
+
+#define HW_PXP_ALU_B_DBG (0x00002920)
+
+#define BP_PXP_ALU_B_DBG_DEBUG_SEL 24
+#define BM_PXP_ALU_B_DBG_DEBUG_SEL 0xFF000000
+#define BF_PXP_ALU_B_DBG_DEBUG_SEL(v) \
+ (((v) << 24) & BM_PXP_ALU_B_DBG_DEBUG_SEL)
+#define BP_PXP_ALU_B_DBG_DEBUG_VALUE 0
+#define BM_PXP_ALU_B_DBG_DEBUG_VALUE 0x00FFFFFF
+#define BF_PXP_ALU_B_DBG_DEBUG_VALUE(v) \
+ (((v) << 0) & BM_PXP_ALU_B_DBG_DEBUG_VALUE)
+
+#define HW_PXP_HIST_A_CTRL (0x00002a00)
+
+#define BP_PXP_HIST_A_CTRL_RSVD4 27
+#define BM_PXP_HIST_A_CTRL_RSVD4 0xF8000000
+#define BF_PXP_HIST_A_CTRL_RSVD4(v) \
+ (((v) << 27) & BM_PXP_HIST_A_CTRL_RSVD4)
+#define BP_PXP_HIST_A_CTRL_PIXEL_WIDTH 24
+#define BM_PXP_HIST_A_CTRL_PIXEL_WIDTH 0x07000000
+#define BF_PXP_HIST_A_CTRL_PIXEL_WIDTH(v) \
+ (((v) << 24) & BM_PXP_HIST_A_CTRL_PIXEL_WIDTH)
+#define BM_PXP_HIST_A_CTRL_RSVD3 0x00800000
+#define BF_PXP_HIST_A_CTRL_RSVD3(v) \
+ (((v) << 23) & BM_PXP_HIST_A_CTRL_RSVD3)
+#define BP_PXP_HIST_A_CTRL_PIXEL_OFFSET 16
+#define BM_PXP_HIST_A_CTRL_PIXEL_OFFSET 0x007F0000
+#define BF_PXP_HIST_A_CTRL_PIXEL_OFFSET(v) \
+ (((v) << 16) & BM_PXP_HIST_A_CTRL_PIXEL_OFFSET)
+#define BP_PXP_HIST_A_CTRL_RSVD2 13
+#define BM_PXP_HIST_A_CTRL_RSVD2 0x0000E000
+#define BF_PXP_HIST_A_CTRL_RSVD2(v) \
+ (((v) << 13) & BM_PXP_HIST_A_CTRL_RSVD2)
+#define BP_PXP_HIST_A_CTRL_STATUS 8
+#define BM_PXP_HIST_A_CTRL_STATUS 0x00001F00
+#define BF_PXP_HIST_A_CTRL_STATUS(v) \
+ (((v) << 8) & BM_PXP_HIST_A_CTRL_STATUS)
+#define BP_PXP_HIST_A_CTRL_RSVD1 5
+#define BM_PXP_HIST_A_CTRL_RSVD1 0x000000E0
+#define BF_PXP_HIST_A_CTRL_RSVD1(v) \
+ (((v) << 5) & BM_PXP_HIST_A_CTRL_RSVD1)
+#define BM_PXP_HIST_A_CTRL_CLEAR 0x00000010
+#define BF_PXP_HIST_A_CTRL_CLEAR(v) \
+ (((v) << 4) & BM_PXP_HIST_A_CTRL_CLEAR)
+#define BP_PXP_HIST_A_CTRL_RSVD0 1
+#define BM_PXP_HIST_A_CTRL_RSVD0 0x0000000E
+#define BF_PXP_HIST_A_CTRL_RSVD0(v) \
+ (((v) << 1) & BM_PXP_HIST_A_CTRL_RSVD0)
+#define BM_PXP_HIST_A_CTRL_ENABLE 0x00000001
+#define BF_PXP_HIST_A_CTRL_ENABLE(v) \
+ (((v) << 0) & BM_PXP_HIST_A_CTRL_ENABLE)
+
+#define HW_PXP_HIST_A_MASK (0x00002a10)
+
+#define BP_PXP_HIST_A_MASK_MASK_VALUE1 24
+#define BM_PXP_HIST_A_MASK_MASK_VALUE1 0xFF000000
+#define BF_PXP_HIST_A_MASK_MASK_VALUE1(v) \
+ (((v) << 24) & BM_PXP_HIST_A_MASK_MASK_VALUE1)
+#define BP_PXP_HIST_A_MASK_MASK_VALUE0 16
+#define BM_PXP_HIST_A_MASK_MASK_VALUE0 0x00FF0000
+#define BF_PXP_HIST_A_MASK_MASK_VALUE0(v) \
+ (((v) << 16) & BM_PXP_HIST_A_MASK_MASK_VALUE0)
+#define BP_PXP_HIST_A_MASK_MASK_WIDTH 13
+#define BM_PXP_HIST_A_MASK_MASK_WIDTH 0x0000E000
+#define BF_PXP_HIST_A_MASK_MASK_WIDTH(v) \
+ (((v) << 13) & BM_PXP_HIST_A_MASK_MASK_WIDTH)
+#define BP_PXP_HIST_A_MASK_MASK_OFFSET 6
+#define BM_PXP_HIST_A_MASK_MASK_OFFSET 0x00001FC0
+#define BF_PXP_HIST_A_MASK_MASK_OFFSET(v) \
+ (((v) << 6) & BM_PXP_HIST_A_MASK_MASK_OFFSET)
+#define BP_PXP_HIST_A_MASK_MASK_MODE 4
+#define BM_PXP_HIST_A_MASK_MASK_MODE 0x00000030
+#define BF_PXP_HIST_A_MASK_MASK_MODE(v) \
+ (((v) << 4) & BM_PXP_HIST_A_MASK_MASK_MODE)
+#define BV_PXP_HIST_A_MASK_MASK_MODE__EQUAL 0x0
+#define BV_PXP_HIST_A_MASK_MASK_MODE__NOT_EQUAL 0x1
+#define BV_PXP_HIST_A_MASK_MASK_MODE__INSIDE 0x2
+#define BV_PXP_HIST_A_MASK_MASK_MODE__OUTSIDE 0x3
+#define BP_PXP_HIST_A_MASK_RSVD0 1
+#define BM_PXP_HIST_A_MASK_RSVD0 0x0000000E
+#define BF_PXP_HIST_A_MASK_RSVD0(v) \
+ (((v) << 1) & BM_PXP_HIST_A_MASK_RSVD0)
+#define BM_PXP_HIST_A_MASK_MASK_EN 0x00000001
+#define BF_PXP_HIST_A_MASK_MASK_EN(v) \
+ (((v) << 0) & BM_PXP_HIST_A_MASK_MASK_EN)
+
+#define HW_PXP_HIST_A_BUF_SIZE (0x00002a20)
+
+#define BP_PXP_HIST_A_BUF_SIZE_RSVD0 28
+#define BM_PXP_HIST_A_BUF_SIZE_RSVD0 0xF0000000
+#define BF_PXP_HIST_A_BUF_SIZE_RSVD0(v) \
+ (((v) << 28) & BM_PXP_HIST_A_BUF_SIZE_RSVD0)
+#define BP_PXP_HIST_A_BUF_SIZE_HEIGHT 16
+#define BM_PXP_HIST_A_BUF_SIZE_HEIGHT 0x0FFF0000
+#define BF_PXP_HIST_A_BUF_SIZE_HEIGHT(v) \
+ (((v) << 16) & BM_PXP_HIST_A_BUF_SIZE_HEIGHT)
+#define BP_PXP_HIST_A_BUF_SIZE_RSVD1 12
+#define BM_PXP_HIST_A_BUF_SIZE_RSVD1 0x0000F000
+#define BF_PXP_HIST_A_BUF_SIZE_RSVD1(v) \
+ (((v) << 12) & BM_PXP_HIST_A_BUF_SIZE_RSVD1)
+#define BP_PXP_HIST_A_BUF_SIZE_WIDTH 0
+#define BM_PXP_HIST_A_BUF_SIZE_WIDTH 0x00000FFF
+#define BF_PXP_HIST_A_BUF_SIZE_WIDTH(v) \
+ (((v) << 0) & BM_PXP_HIST_A_BUF_SIZE_WIDTH)
+
+#define HW_PXP_HIST_A_TOTAL_PIXEL (0x00002a30)
+
+#define BP_PXP_HIST_A_TOTAL_PIXEL_RSVD0 24
+#define BM_PXP_HIST_A_TOTAL_PIXEL_RSVD0 0xFF000000
+#define BF_PXP_HIST_A_TOTAL_PIXEL_RSVD0(v) \
+ (((v) << 24) & BM_PXP_HIST_A_TOTAL_PIXEL_RSVD0)
+#define BP_PXP_HIST_A_TOTAL_PIXEL_TOTAL_PIXEL 0
+#define BM_PXP_HIST_A_TOTAL_PIXEL_TOTAL_PIXEL 0x00FFFFFF
+#define BF_PXP_HIST_A_TOTAL_PIXEL_TOTAL_PIXEL(v) \
+ (((v) << 0) & BM_PXP_HIST_A_TOTAL_PIXEL_TOTAL_PIXEL)
+
+#define HW_PXP_HIST_A_ACTIVE_AREA_X (0x00002a40)
+
+#define BP_PXP_HIST_A_ACTIVE_AREA_X_RSVD1 28
+#define BM_PXP_HIST_A_ACTIVE_AREA_X_RSVD1 0xF0000000
+#define BF_PXP_HIST_A_ACTIVE_AREA_X_RSVD1(v) \
+ (((v) << 28) & BM_PXP_HIST_A_ACTIVE_AREA_X_RSVD1)
+#define BP_PXP_HIST_A_ACTIVE_AREA_X_MAX_X_OFFSET 16
+#define BM_PXP_HIST_A_ACTIVE_AREA_X_MAX_X_OFFSET 0x0FFF0000
+#define BF_PXP_HIST_A_ACTIVE_AREA_X_MAX_X_OFFSET(v) \
+ (((v) << 16) & BM_PXP_HIST_A_ACTIVE_AREA_X_MAX_X_OFFSET)
+#define BP_PXP_HIST_A_ACTIVE_AREA_X_RSVD0 12
+#define BM_PXP_HIST_A_ACTIVE_AREA_X_RSVD0 0x0000F000
+#define BF_PXP_HIST_A_ACTIVE_AREA_X_RSVD0(v) \
+ (((v) << 12) & BM_PXP_HIST_A_ACTIVE_AREA_X_RSVD0)
+#define BP_PXP_HIST_A_ACTIVE_AREA_X_MIN_X_OFFSET 0
+#define BM_PXP_HIST_A_ACTIVE_AREA_X_MIN_X_OFFSET 0x00000FFF
+#define BF_PXP_HIST_A_ACTIVE_AREA_X_MIN_X_OFFSET(v) \
+ (((v) << 0) & BM_PXP_HIST_A_ACTIVE_AREA_X_MIN_X_OFFSET)
+
+#define HW_PXP_HIST_A_ACTIVE_AREA_Y (0x00002a50)
+
+#define BP_PXP_HIST_A_ACTIVE_AREA_Y_RSVD1 28
+#define BM_PXP_HIST_A_ACTIVE_AREA_Y_RSVD1 0xF0000000
+#define BF_PXP_HIST_A_ACTIVE_AREA_Y_RSVD1(v) \
+ (((v) << 28) & BM_PXP_HIST_A_ACTIVE_AREA_Y_RSVD1)
+#define BP_PXP_HIST_A_ACTIVE_AREA_Y_MAX_Y_OFFSET 16
+#define BM_PXP_HIST_A_ACTIVE_AREA_Y_MAX_Y_OFFSET 0x0FFF0000
+#define BF_PXP_HIST_A_ACTIVE_AREA_Y_MAX_Y_OFFSET(v) \
+ (((v) << 16) & BM_PXP_HIST_A_ACTIVE_AREA_Y_MAX_Y_OFFSET)
+#define BP_PXP_HIST_A_ACTIVE_AREA_Y_RSVD0 12
+#define BM_PXP_HIST_A_ACTIVE_AREA_Y_RSVD0 0x0000F000
+#define BF_PXP_HIST_A_ACTIVE_AREA_Y_RSVD0(v) \
+ (((v) << 12) & BM_PXP_HIST_A_ACTIVE_AREA_Y_RSVD0)
+#define BP_PXP_HIST_A_ACTIVE_AREA_Y_MIN_Y_OFFSET 0
+#define BM_PXP_HIST_A_ACTIVE_AREA_Y_MIN_Y_OFFSET 0x00000FFF
+#define BF_PXP_HIST_A_ACTIVE_AREA_Y_MIN_Y_OFFSET(v) \
+ (((v) << 0) & BM_PXP_HIST_A_ACTIVE_AREA_Y_MIN_Y_OFFSET)
+
+#define HW_PXP_HIST_A_RAW_STAT0 (0x00002a60)
+
+#define BP_PXP_HIST_A_RAW_STAT0_STAT0 0
+#define BM_PXP_HIST_A_RAW_STAT0_STAT0 0xFFFFFFFF
+#define BF_PXP_HIST_A_RAW_STAT0_STAT0(v) (v)
+
+#define HW_PXP_HIST_A_RAW_STAT1 (0x00002a70)
+
+#define BP_PXP_HIST_A_RAW_STAT1_STAT1 0
+#define BM_PXP_HIST_A_RAW_STAT1_STAT1 0xFFFFFFFF
+#define BF_PXP_HIST_A_RAW_STAT1_STAT1(v) (v)
+
+#define HW_PXP_HIST_B_CTRL (0x00002a80)
+
+#define BP_PXP_HIST_B_CTRL_RSVD4 27
+#define BM_PXP_HIST_B_CTRL_RSVD4 0xF8000000
+#define BF_PXP_HIST_B_CTRL_RSVD4(v) \
+ (((v) << 27) & BM_PXP_HIST_B_CTRL_RSVD4)
+#define BP_PXP_HIST_B_CTRL_PIXEL_WIDTH 24
+#define BM_PXP_HIST_B_CTRL_PIXEL_WIDTH 0x07000000
+#define BF_PXP_HIST_B_CTRL_PIXEL_WIDTH(v) \
+ (((v) << 24) & BM_PXP_HIST_B_CTRL_PIXEL_WIDTH)
+#define BM_PXP_HIST_B_CTRL_RSVD3 0x00800000
+#define BF_PXP_HIST_B_CTRL_RSVD3(v) \
+ (((v) << 23) & BM_PXP_HIST_B_CTRL_RSVD3)
+#define BP_PXP_HIST_B_CTRL_PIXEL_OFFSET 16
+#define BM_PXP_HIST_B_CTRL_PIXEL_OFFSET 0x007F0000
+#define BF_PXP_HIST_B_CTRL_PIXEL_OFFSET(v) \
+ (((v) << 16) & BM_PXP_HIST_B_CTRL_PIXEL_OFFSET)
+#define BP_PXP_HIST_B_CTRL_RSVD2 13
+#define BM_PXP_HIST_B_CTRL_RSVD2 0x0000E000
+#define BF_PXP_HIST_B_CTRL_RSVD2(v) \
+ (((v) << 13) & BM_PXP_HIST_B_CTRL_RSVD2)
+#define BP_PXP_HIST_B_CTRL_STATUS 8
+#define BM_PXP_HIST_B_CTRL_STATUS 0x00001F00
+#define BF_PXP_HIST_B_CTRL_STATUS(v) \
+ (((v) << 8) & BM_PXP_HIST_B_CTRL_STATUS)
+#define BP_PXP_HIST_B_CTRL_RSVD1 5
+#define BM_PXP_HIST_B_CTRL_RSVD1 0x000000E0
+#define BF_PXP_HIST_B_CTRL_RSVD1(v) \
+ (((v) << 5) & BM_PXP_HIST_B_CTRL_RSVD1)
+#define BM_PXP_HIST_B_CTRL_CLEAR 0x00000010
+#define BF_PXP_HIST_B_CTRL_CLEAR(v) \
+ (((v) << 4) & BM_PXP_HIST_B_CTRL_CLEAR)
+#define BP_PXP_HIST_B_CTRL_RSVD0 1
+#define BM_PXP_HIST_B_CTRL_RSVD0 0x0000000E
+#define BF_PXP_HIST_B_CTRL_RSVD0(v) \
+ (((v) << 1) & BM_PXP_HIST_B_CTRL_RSVD0)
+#define BM_PXP_HIST_B_CTRL_ENABLE 0x00000001
+#define BF_PXP_HIST_B_CTRL_ENABLE(v) \
+ (((v) << 0) & BM_PXP_HIST_B_CTRL_ENABLE)
+
+#define HW_PXP_HIST_B_MASK (0x00002a90)
+
+#define BP_PXP_HIST_B_MASK_MASK_VALUE1 24
+#define BM_PXP_HIST_B_MASK_MASK_VALUE1 0xFF000000
+#define BF_PXP_HIST_B_MASK_MASK_VALUE1(v) \
+ (((v) << 24) & BM_PXP_HIST_B_MASK_MASK_VALUE1)
+#define BP_PXP_HIST_B_MASK_MASK_VALUE0 16
+#define BM_PXP_HIST_B_MASK_MASK_VALUE0 0x00FF0000
+#define BF_PXP_HIST_B_MASK_MASK_VALUE0(v) \
+ (((v) << 16) & BM_PXP_HIST_B_MASK_MASK_VALUE0)
+#define BP_PXP_HIST_B_MASK_MASK_WIDTH 13
+#define BM_PXP_HIST_B_MASK_MASK_WIDTH 0x0000E000
+#define BF_PXP_HIST_B_MASK_MASK_WIDTH(v) \
+ (((v) << 13) & BM_PXP_HIST_B_MASK_MASK_WIDTH)
+#define BP_PXP_HIST_B_MASK_MASK_OFFSET 6
+#define BM_PXP_HIST_B_MASK_MASK_OFFSET 0x00001FC0
+#define BF_PXP_HIST_B_MASK_MASK_OFFSET(v) \
+ (((v) << 6) & BM_PXP_HIST_B_MASK_MASK_OFFSET)
+#define BP_PXP_HIST_B_MASK_MASK_MODE 4
+#define BM_PXP_HIST_B_MASK_MASK_MODE 0x00000030
+#define BF_PXP_HIST_B_MASK_MASK_MODE(v) \
+ (((v) << 4) & BM_PXP_HIST_B_MASK_MASK_MODE)
+#define BV_PXP_HIST_B_MASK_MASK_MODE__EQUAL 0x0
+#define BV_PXP_HIST_B_MASK_MASK_MODE__NOT_EQUAL 0x1
+#define BV_PXP_HIST_B_MASK_MASK_MODE__INSIDE 0x2
+#define BV_PXP_HIST_B_MASK_MASK_MODE__OUTSIDE 0x3
+#define BP_PXP_HIST_B_MASK_RSVD0 1
+#define BM_PXP_HIST_B_MASK_RSVD0 0x0000000E
+#define BF_PXP_HIST_B_MASK_RSVD0(v) \
+ (((v) << 1) & BM_PXP_HIST_B_MASK_RSVD0)
+#define BM_PXP_HIST_B_MASK_MASK_EN 0x00000001
+#define BF_PXP_HIST_B_MASK_MASK_EN(v) \
+ (((v) << 0) & BM_PXP_HIST_B_MASK_MASK_EN)
+
+#define HW_PXP_HIST_B_BUF_SIZE (0x00002aa0)
+
+#define BP_PXP_HIST_B_BUF_SIZE_RSVD0 28
+#define BM_PXP_HIST_B_BUF_SIZE_RSVD0 0xF0000000
+#define BF_PXP_HIST_B_BUF_SIZE_RSVD0(v) \
+ (((v) << 28) & BM_PXP_HIST_B_BUF_SIZE_RSVD0)
+#define BP_PXP_HIST_B_BUF_SIZE_HEIGHT 16
+#define BM_PXP_HIST_B_BUF_SIZE_HEIGHT 0x0FFF0000
+#define BF_PXP_HIST_B_BUF_SIZE_HEIGHT(v) \
+ (((v) << 16) & BM_PXP_HIST_B_BUF_SIZE_HEIGHT)
+#define BP_PXP_HIST_B_BUF_SIZE_RSVD1 12
+#define BM_PXP_HIST_B_BUF_SIZE_RSVD1 0x0000F000
+#define BF_PXP_HIST_B_BUF_SIZE_RSVD1(v) \
+ (((v) << 12) & BM_PXP_HIST_B_BUF_SIZE_RSVD1)
+#define BP_PXP_HIST_B_BUF_SIZE_WIDTH 0
+#define BM_PXP_HIST_B_BUF_SIZE_WIDTH 0x00000FFF
+#define BF_PXP_HIST_B_BUF_SIZE_WIDTH(v) \
+ (((v) << 0) & BM_PXP_HIST_B_BUF_SIZE_WIDTH)
+
+#define HW_PXP_HIST_B_TOTAL_PIXEL (0x00002ab0)
+
+#define BP_PXP_HIST_B_TOTAL_PIXEL_RSVD0 24
+#define BM_PXP_HIST_B_TOTAL_PIXEL_RSVD0 0xFF000000
+#define BF_PXP_HIST_B_TOTAL_PIXEL_RSVD0(v) \
+ (((v) << 24) & BM_PXP_HIST_B_TOTAL_PIXEL_RSVD0)
+#define BP_PXP_HIST_B_TOTAL_PIXEL_TOTAL_PIXEL 0
+#define BM_PXP_HIST_B_TOTAL_PIXEL_TOTAL_PIXEL 0x00FFFFFF
+#define BF_PXP_HIST_B_TOTAL_PIXEL_TOTAL_PIXEL(v) \
+ (((v) << 0) & BM_PXP_HIST_B_TOTAL_PIXEL_TOTAL_PIXEL)
+
+#define HW_PXP_HIST_B_ACTIVE_AREA_X (0x00002ac0)
+
+#define BP_PXP_HIST_B_ACTIVE_AREA_X_RSVD1 28
+#define BM_PXP_HIST_B_ACTIVE_AREA_X_RSVD1 0xF0000000
+#define BF_PXP_HIST_B_ACTIVE_AREA_X_RSVD1(v) \
+ (((v) << 28) & BM_PXP_HIST_B_ACTIVE_AREA_X_RSVD1)
+#define BP_PXP_HIST_B_ACTIVE_AREA_X_MAX_X_OFFSET 16
+#define BM_PXP_HIST_B_ACTIVE_AREA_X_MAX_X_OFFSET 0x0FFF0000
+#define BF_PXP_HIST_B_ACTIVE_AREA_X_MAX_X_OFFSET(v) \
+ (((v) << 16) & BM_PXP_HIST_B_ACTIVE_AREA_X_MAX_X_OFFSET)
+#define BP_PXP_HIST_B_ACTIVE_AREA_X_RSVD0 12
+#define BM_PXP_HIST_B_ACTIVE_AREA_X_RSVD0 0x0000F000
+#define BF_PXP_HIST_B_ACTIVE_AREA_X_RSVD0(v) \
+ (((v) << 12) & BM_PXP_HIST_B_ACTIVE_AREA_X_RSVD0)
+#define BP_PXP_HIST_B_ACTIVE_AREA_X_MIN_X_OFFSET 0
+#define BM_PXP_HIST_B_ACTIVE_AREA_X_MIN_X_OFFSET 0x00000FFF
+#define BF_PXP_HIST_B_ACTIVE_AREA_X_MIN_X_OFFSET(v) \
+ (((v) << 0) & BM_PXP_HIST_B_ACTIVE_AREA_X_MIN_X_OFFSET)
+
+#define HW_PXP_HIST_B_ACTIVE_AREA_Y (0x00002ad0)
+
+#define BP_PXP_HIST_B_ACTIVE_AREA_Y_RSVD1 28
+#define BM_PXP_HIST_B_ACTIVE_AREA_Y_RSVD1 0xF0000000
+#define BF_PXP_HIST_B_ACTIVE_AREA_Y_RSVD1(v) \
+ (((v) << 28) & BM_PXP_HIST_B_ACTIVE_AREA_Y_RSVD1)
+#define BP_PXP_HIST_B_ACTIVE_AREA_Y_MAX_Y_OFFSET 16
+#define BM_PXP_HIST_B_ACTIVE_AREA_Y_MAX_Y_OFFSET 0x0FFF0000
+#define BF_PXP_HIST_B_ACTIVE_AREA_Y_MAX_Y_OFFSET(v) \
+ (((v) << 16) & BM_PXP_HIST_B_ACTIVE_AREA_Y_MAX_Y_OFFSET)
+#define BP_PXP_HIST_B_ACTIVE_AREA_Y_RSVD0 12
+#define BM_PXP_HIST_B_ACTIVE_AREA_Y_RSVD0 0x0000F000
+#define BF_PXP_HIST_B_ACTIVE_AREA_Y_RSVD0(v) \
+ (((v) << 12) & BM_PXP_HIST_B_ACTIVE_AREA_Y_RSVD0)
+#define BP_PXP_HIST_B_ACTIVE_AREA_Y_MIN_Y_OFFSET 0
+#define BM_PXP_HIST_B_ACTIVE_AREA_Y_MIN_Y_OFFSET 0x00000FFF
+#define BF_PXP_HIST_B_ACTIVE_AREA_Y_MIN_Y_OFFSET(v) \
+ (((v) << 0) & BM_PXP_HIST_B_ACTIVE_AREA_Y_MIN_Y_OFFSET)
+
+#define HW_PXP_HIST_B_RAW_STAT0 (0x00002ae0)
+
+#define BP_PXP_HIST_B_RAW_STAT0_STAT0 0
+#define BM_PXP_HIST_B_RAW_STAT0_STAT0 0xFFFFFFFF
+#define BF_PXP_HIST_B_RAW_STAT0_STAT0(v) (v)
+
+#define HW_PXP_HIST_B_RAW_STAT1 (0x00002af0)
+
+#define BP_PXP_HIST_B_RAW_STAT1_STAT1 0
+#define BM_PXP_HIST_B_RAW_STAT1_STAT1 0xFFFFFFFF
+#define BF_PXP_HIST_B_RAW_STAT1_STAT1(v) (v)
+
+#define HW_PXP_HIST2_PARAM (0x00002b00)
+
+#define BP_PXP_HIST2_PARAM_RSVD 16
+#define BM_PXP_HIST2_PARAM_RSVD 0xFFFF0000
+#define BF_PXP_HIST2_PARAM_RSVD(v) \
+ (((v) << 16) & BM_PXP_HIST2_PARAM_RSVD)
+#define BP_PXP_HIST2_PARAM_RSVD1 14
+#define BM_PXP_HIST2_PARAM_RSVD1 0x0000C000
+#define BF_PXP_HIST2_PARAM_RSVD1(v) \
+ (((v) << 14) & BM_PXP_HIST2_PARAM_RSVD1)
+#define BP_PXP_HIST2_PARAM_VALUE1 8
+#define BM_PXP_HIST2_PARAM_VALUE1 0x00003F00
+#define BF_PXP_HIST2_PARAM_VALUE1(v) \
+ (((v) << 8) & BM_PXP_HIST2_PARAM_VALUE1)
+#define BP_PXP_HIST2_PARAM_RSVD0 6
+#define BM_PXP_HIST2_PARAM_RSVD0 0x000000C0
+#define BF_PXP_HIST2_PARAM_RSVD0(v) \
+ (((v) << 6) & BM_PXP_HIST2_PARAM_RSVD0)
+#define BP_PXP_HIST2_PARAM_VALUE0 0
+#define BM_PXP_HIST2_PARAM_VALUE0 0x0000003F
+#define BF_PXP_HIST2_PARAM_VALUE0(v) \
+ (((v) << 0) & BM_PXP_HIST2_PARAM_VALUE0)
+
+#define HW_PXP_HIST4_PARAM (0x00002b10)
+
+#define BP_PXP_HIST4_PARAM_RSVD3 30
+#define BM_PXP_HIST4_PARAM_RSVD3 0xC0000000
+#define BF_PXP_HIST4_PARAM_RSVD3(v) \
+ (((v) << 30) & BM_PXP_HIST4_PARAM_RSVD3)
+#define BP_PXP_HIST4_PARAM_VALUE3 24
+#define BM_PXP_HIST4_PARAM_VALUE3 0x3F000000
+#define BF_PXP_HIST4_PARAM_VALUE3(v) \
+ (((v) << 24) & BM_PXP_HIST4_PARAM_VALUE3)
+#define BP_PXP_HIST4_PARAM_RSVD2 22
+#define BM_PXP_HIST4_PARAM_RSVD2 0x00C00000
+#define BF_PXP_HIST4_PARAM_RSVD2(v) \
+ (((v) << 22) & BM_PXP_HIST4_PARAM_RSVD2)
+#define BP_PXP_HIST4_PARAM_VALUE2 16
+#define BM_PXP_HIST4_PARAM_VALUE2 0x003F0000
+#define BF_PXP_HIST4_PARAM_VALUE2(v) \
+ (((v) << 16) & BM_PXP_HIST4_PARAM_VALUE2)
+#define BP_PXP_HIST4_PARAM_RSVD1 14
+#define BM_PXP_HIST4_PARAM_RSVD1 0x0000C000
+#define BF_PXP_HIST4_PARAM_RSVD1(v) \
+ (((v) << 14) & BM_PXP_HIST4_PARAM_RSVD1)
+#define BP_PXP_HIST4_PARAM_VALUE1 8
+#define BM_PXP_HIST4_PARAM_VALUE1 0x00003F00
+#define BF_PXP_HIST4_PARAM_VALUE1(v) \
+ (((v) << 8) & BM_PXP_HIST4_PARAM_VALUE1)
+#define BP_PXP_HIST4_PARAM_RSVD0 6
+#define BM_PXP_HIST4_PARAM_RSVD0 0x000000C0
+#define BF_PXP_HIST4_PARAM_RSVD0(v) \
+ (((v) << 6) & BM_PXP_HIST4_PARAM_RSVD0)
+#define BP_PXP_HIST4_PARAM_VALUE0 0
+#define BM_PXP_HIST4_PARAM_VALUE0 0x0000003F
+#define BF_PXP_HIST4_PARAM_VALUE0(v) \
+ (((v) << 0) & BM_PXP_HIST4_PARAM_VALUE0)
+
+#define HW_PXP_HIST8_PARAM0 (0x00002b20)
+
+#define BP_PXP_HIST8_PARAM0_RSVD3 30
+#define BM_PXP_HIST8_PARAM0_RSVD3 0xC0000000
+#define BF_PXP_HIST8_PARAM0_RSVD3(v) \
+ (((v) << 30) & BM_PXP_HIST8_PARAM0_RSVD3)
+#define BP_PXP_HIST8_PARAM0_VALUE3 24
+#define BM_PXP_HIST8_PARAM0_VALUE3 0x3F000000
+#define BF_PXP_HIST8_PARAM0_VALUE3(v) \
+ (((v) << 24) & BM_PXP_HIST8_PARAM0_VALUE3)
+#define BP_PXP_HIST8_PARAM0_RSVD2 22
+#define BM_PXP_HIST8_PARAM0_RSVD2 0x00C00000
+#define BF_PXP_HIST8_PARAM0_RSVD2(v) \
+ (((v) << 22) & BM_PXP_HIST8_PARAM0_RSVD2)
+#define BP_PXP_HIST8_PARAM0_VALUE2 16
+#define BM_PXP_HIST8_PARAM0_VALUE2 0x003F0000
+#define BF_PXP_HIST8_PARAM0_VALUE2(v) \
+ (((v) << 16) & BM_PXP_HIST8_PARAM0_VALUE2)
+#define BP_PXP_HIST8_PARAM0_RSVD1 14
+#define BM_PXP_HIST8_PARAM0_RSVD1 0x0000C000
+#define BF_PXP_HIST8_PARAM0_RSVD1(v) \
+ (((v) << 14) & BM_PXP_HIST8_PARAM0_RSVD1)
+#define BP_PXP_HIST8_PARAM0_VALUE1 8
+#define BM_PXP_HIST8_PARAM0_VALUE1 0x00003F00
+#define BF_PXP_HIST8_PARAM0_VALUE1(v) \
+ (((v) << 8) & BM_PXP_HIST8_PARAM0_VALUE1)
+#define BP_PXP_HIST8_PARAM0_RSVD0 6
+#define BM_PXP_HIST8_PARAM0_RSVD0 0x000000C0
+#define BF_PXP_HIST8_PARAM0_RSVD0(v) \
+ (((v) << 6) & BM_PXP_HIST8_PARAM0_RSVD0)
+#define BP_PXP_HIST8_PARAM0_VALUE0 0
+#define BM_PXP_HIST8_PARAM0_VALUE0 0x0000003F
+#define BF_PXP_HIST8_PARAM0_VALUE0(v) \
+ (((v) << 0) & BM_PXP_HIST8_PARAM0_VALUE0)
+
+#define HW_PXP_HIST8_PARAM1 (0x00002b30)
+
+#define BP_PXP_HIST8_PARAM1_RSVD7 30
+#define BM_PXP_HIST8_PARAM1_RSVD7 0xC0000000
+#define BF_PXP_HIST8_PARAM1_RSVD7(v) \
+ (((v) << 30) & BM_PXP_HIST8_PARAM1_RSVD7)
+#define BP_PXP_HIST8_PARAM1_VALUE7 24
+#define BM_PXP_HIST8_PARAM1_VALUE7 0x3F000000
+#define BF_PXP_HIST8_PARAM1_VALUE7(v) \
+ (((v) << 24) & BM_PXP_HIST8_PARAM1_VALUE7)
+#define BP_PXP_HIST8_PARAM1_RSVD6 22
+#define BM_PXP_HIST8_PARAM1_RSVD6 0x00C00000
+#define BF_PXP_HIST8_PARAM1_RSVD6(v) \
+ (((v) << 22) & BM_PXP_HIST8_PARAM1_RSVD6)
+#define BP_PXP_HIST8_PARAM1_VALUE6 16
+#define BM_PXP_HIST8_PARAM1_VALUE6 0x003F0000
+#define BF_PXP_HIST8_PARAM1_VALUE6(v) \
+ (((v) << 16) & BM_PXP_HIST8_PARAM1_VALUE6)
+#define BP_PXP_HIST8_PARAM1_RSVD5 14
+#define BM_PXP_HIST8_PARAM1_RSVD5 0x0000C000
+#define BF_PXP_HIST8_PARAM1_RSVD5(v) \
+ (((v) << 14) & BM_PXP_HIST8_PARAM1_RSVD5)
+#define BP_PXP_HIST8_PARAM1_VALUE5 8
+#define BM_PXP_HIST8_PARAM1_VALUE5 0x00003F00
+#define BF_PXP_HIST8_PARAM1_VALUE5(v) \
+ (((v) << 8) & BM_PXP_HIST8_PARAM1_VALUE5)
+#define BP_PXP_HIST8_PARAM1_RSVD4 6
+#define BM_PXP_HIST8_PARAM1_RSVD4 0x000000C0
+#define BF_PXP_HIST8_PARAM1_RSVD4(v) \
+ (((v) << 6) & BM_PXP_HIST8_PARAM1_RSVD4)
+#define BP_PXP_HIST8_PARAM1_VALUE4 0
+#define BM_PXP_HIST8_PARAM1_VALUE4 0x0000003F
+#define BF_PXP_HIST8_PARAM1_VALUE4(v) \
+ (((v) << 0) & BM_PXP_HIST8_PARAM1_VALUE4)
+
+#define HW_PXP_HIST16_PARAM0 (0x00002b40)
+
+#define BP_PXP_HIST16_PARAM0_RSVD3 30
+#define BM_PXP_HIST16_PARAM0_RSVD3 0xC0000000
+#define BF_PXP_HIST16_PARAM0_RSVD3(v) \
+ (((v) << 30) & BM_PXP_HIST16_PARAM0_RSVD3)
+#define BP_PXP_HIST16_PARAM0_VALUE3 24
+#define BM_PXP_HIST16_PARAM0_VALUE3 0x3F000000
+#define BF_PXP_HIST16_PARAM0_VALUE3(v) \
+ (((v) << 24) & BM_PXP_HIST16_PARAM0_VALUE3)
+#define BP_PXP_HIST16_PARAM0_RSVD2 22
+#define BM_PXP_HIST16_PARAM0_RSVD2 0x00C00000
+#define BF_PXP_HIST16_PARAM0_RSVD2(v) \
+ (((v) << 22) & BM_PXP_HIST16_PARAM0_RSVD2)
+#define BP_PXP_HIST16_PARAM0_VALUE2 16
+#define BM_PXP_HIST16_PARAM0_VALUE2 0x003F0000
+#define BF_PXP_HIST16_PARAM0_VALUE2(v) \
+ (((v) << 16) & BM_PXP_HIST16_PARAM0_VALUE2)
+#define BP_PXP_HIST16_PARAM0_RSVD1 14
+#define BM_PXP_HIST16_PARAM0_RSVD1 0x0000C000
+#define BF_PXP_HIST16_PARAM0_RSVD1(v) \
+ (((v) << 14) & BM_PXP_HIST16_PARAM0_RSVD1)
+#define BP_PXP_HIST16_PARAM0_VALUE1 8
+#define BM_PXP_HIST16_PARAM0_VALUE1 0x00003F00
+#define BF_PXP_HIST16_PARAM0_VALUE1(v) \
+ (((v) << 8) & BM_PXP_HIST16_PARAM0_VALUE1)
+#define BP_PXP_HIST16_PARAM0_RSVD0 6
+#define BM_PXP_HIST16_PARAM0_RSVD0 0x000000C0
+#define BF_PXP_HIST16_PARAM0_RSVD0(v) \
+ (((v) << 6) & BM_PXP_HIST16_PARAM0_RSVD0)
+#define BP_PXP_HIST16_PARAM0_VALUE0 0
+#define BM_PXP_HIST16_PARAM0_VALUE0 0x0000003F
+#define BF_PXP_HIST16_PARAM0_VALUE0(v) \
+ (((v) << 0) & BM_PXP_HIST16_PARAM0_VALUE0)
+
+#define HW_PXP_HIST16_PARAM1 (0x00002b50)
+
+#define BP_PXP_HIST16_PARAM1_RSVD7 30
+#define BM_PXP_HIST16_PARAM1_RSVD7 0xC0000000
+#define BF_PXP_HIST16_PARAM1_RSVD7(v) \
+ (((v) << 30) & BM_PXP_HIST16_PARAM1_RSVD7)
+#define BP_PXP_HIST16_PARAM1_VALUE7 24
+#define BM_PXP_HIST16_PARAM1_VALUE7 0x3F000000
+#define BF_PXP_HIST16_PARAM1_VALUE7(v) \
+ (((v) << 24) & BM_PXP_HIST16_PARAM1_VALUE7)
+#define BP_PXP_HIST16_PARAM1_RSVD6 22
+#define BM_PXP_HIST16_PARAM1_RSVD6 0x00C00000
+#define BF_PXP_HIST16_PARAM1_RSVD6(v) \
+ (((v) << 22) & BM_PXP_HIST16_PARAM1_RSVD6)
+#define BP_PXP_HIST16_PARAM1_VALUE6 16
+#define BM_PXP_HIST16_PARAM1_VALUE6 0x003F0000
+#define BF_PXP_HIST16_PARAM1_VALUE6(v) \
+ (((v) << 16) & BM_PXP_HIST16_PARAM1_VALUE6)
+#define BP_PXP_HIST16_PARAM1_RSVD5 14
+#define BM_PXP_HIST16_PARAM1_RSVD5 0x0000C000
+#define BF_PXP_HIST16_PARAM1_RSVD5(v) \
+ (((v) << 14) & BM_PXP_HIST16_PARAM1_RSVD5)
+#define BP_PXP_HIST16_PARAM1_VALUE5 8
+#define BM_PXP_HIST16_PARAM1_VALUE5 0x00003F00
+#define BF_PXP_HIST16_PARAM1_VALUE5(v) \
+ (((v) << 8) & BM_PXP_HIST16_PARAM1_VALUE5)
+#define BP_PXP_HIST16_PARAM1_RSVD4 6
+#define BM_PXP_HIST16_PARAM1_RSVD4 0x000000C0
+#define BF_PXP_HIST16_PARAM1_RSVD4(v) \
+ (((v) << 6) & BM_PXP_HIST16_PARAM1_RSVD4)
+#define BP_PXP_HIST16_PARAM1_VALUE4 0
+#define BM_PXP_HIST16_PARAM1_VALUE4 0x0000003F
+#define BF_PXP_HIST16_PARAM1_VALUE4(v) \
+ (((v) << 0) & BM_PXP_HIST16_PARAM1_VALUE4)
+
+#define HW_PXP_HIST16_PARAM2 (0x00002b60)
+
+#define BP_PXP_HIST16_PARAM2_RSVD11 30
+#define BM_PXP_HIST16_PARAM2_RSVD11 0xC0000000
+#define BF_PXP_HIST16_PARAM2_RSVD11(v) \
+ (((v) << 30) & BM_PXP_HIST16_PARAM2_RSVD11)
+#define BP_PXP_HIST16_PARAM2_VALUE11 24
+#define BM_PXP_HIST16_PARAM2_VALUE11 0x3F000000
+#define BF_PXP_HIST16_PARAM2_VALUE11(v) \
+ (((v) << 24) & BM_PXP_HIST16_PARAM2_VALUE11)
+#define BP_PXP_HIST16_PARAM2_RSVD10 22
+#define BM_PXP_HIST16_PARAM2_RSVD10 0x00C00000
+#define BF_PXP_HIST16_PARAM2_RSVD10(v) \
+ (((v) << 22) & BM_PXP_HIST16_PARAM2_RSVD10)
+#define BP_PXP_HIST16_PARAM2_VALUE10 16
+#define BM_PXP_HIST16_PARAM2_VALUE10 0x003F0000
+#define BF_PXP_HIST16_PARAM2_VALUE10(v) \
+ (((v) << 16) & BM_PXP_HIST16_PARAM2_VALUE10)
+#define BP_PXP_HIST16_PARAM2_RSVD9 14
+#define BM_PXP_HIST16_PARAM2_RSVD9 0x0000C000
+#define BF_PXP_HIST16_PARAM2_RSVD9(v) \
+ (((v) << 14) & BM_PXP_HIST16_PARAM2_RSVD9)
+#define BP_PXP_HIST16_PARAM2_VALUE9 8
+#define BM_PXP_HIST16_PARAM2_VALUE9 0x00003F00
+#define BF_PXP_HIST16_PARAM2_VALUE9(v) \
+ (((v) << 8) & BM_PXP_HIST16_PARAM2_VALUE9)
+#define BP_PXP_HIST16_PARAM2_RSVD8 6
+#define BM_PXP_HIST16_PARAM2_RSVD8 0x000000C0
+#define BF_PXP_HIST16_PARAM2_RSVD8(v) \
+ (((v) << 6) & BM_PXP_HIST16_PARAM2_RSVD8)
+#define BP_PXP_HIST16_PARAM2_VALUE8 0
+#define BM_PXP_HIST16_PARAM2_VALUE8 0x0000003F
+#define BF_PXP_HIST16_PARAM2_VALUE8(v) \
+ (((v) << 0) & BM_PXP_HIST16_PARAM2_VALUE8)
+
+#define HW_PXP_HIST16_PARAM3 (0x00002b70)
+
+#define BP_PXP_HIST16_PARAM3_RSVD15 30
+#define BM_PXP_HIST16_PARAM3_RSVD15 0xC0000000
+#define BF_PXP_HIST16_PARAM3_RSVD15(v) \
+ (((v) << 30) & BM_PXP_HIST16_PARAM3_RSVD15)
+#define BP_PXP_HIST16_PARAM3_VALUE15 24
+#define BM_PXP_HIST16_PARAM3_VALUE15 0x3F000000
+#define BF_PXP_HIST16_PARAM3_VALUE15(v) \
+ (((v) << 24) & BM_PXP_HIST16_PARAM3_VALUE15)
+#define BP_PXP_HIST16_PARAM3_RSVD14 22
+#define BM_PXP_HIST16_PARAM3_RSVD14 0x00C00000
+#define BF_PXP_HIST16_PARAM3_RSVD14(v) \
+ (((v) << 22) & BM_PXP_HIST16_PARAM3_RSVD14)
+#define BP_PXP_HIST16_PARAM3_VALUE14 16
+#define BM_PXP_HIST16_PARAM3_VALUE14 0x003F0000
+#define BF_PXP_HIST16_PARAM3_VALUE14(v) \
+ (((v) << 16) & BM_PXP_HIST16_PARAM3_VALUE14)
+#define BP_PXP_HIST16_PARAM3_RSVD13 14
+#define BM_PXP_HIST16_PARAM3_RSVD13 0x0000C000
+#define BF_PXP_HIST16_PARAM3_RSVD13(v) \
+ (((v) << 14) & BM_PXP_HIST16_PARAM3_RSVD13)
+#define BP_PXP_HIST16_PARAM3_VALUE13 8
+#define BM_PXP_HIST16_PARAM3_VALUE13 0x00003F00
+#define BF_PXP_HIST16_PARAM3_VALUE13(v) \
+ (((v) << 8) & BM_PXP_HIST16_PARAM3_VALUE13)
+#define BP_PXP_HIST16_PARAM3_RSVD12 6
+#define BM_PXP_HIST16_PARAM3_RSVD12 0x000000C0
+#define BF_PXP_HIST16_PARAM3_RSVD12(v) \
+ (((v) << 6) & BM_PXP_HIST16_PARAM3_RSVD12)
+#define BP_PXP_HIST16_PARAM3_VALUE12 0
+#define BM_PXP_HIST16_PARAM3_VALUE12 0x0000003F
+#define BF_PXP_HIST16_PARAM3_VALUE12(v) \
+ (((v) << 0) & BM_PXP_HIST16_PARAM3_VALUE12)
+
+#define HW_PXP_HIST32_PARAM0 (0x00002b80)
+
+#define BP_PXP_HIST32_PARAM0_RSVD3 30
+#define BM_PXP_HIST32_PARAM0_RSVD3 0xC0000000
+#define BF_PXP_HIST32_PARAM0_RSVD3(v) \
+ (((v) << 30) & BM_PXP_HIST32_PARAM0_RSVD3)
+#define BP_PXP_HIST32_PARAM0_VALUE3 24
+#define BM_PXP_HIST32_PARAM0_VALUE3 0x3F000000
+#define BF_PXP_HIST32_PARAM0_VALUE3(v) \
+ (((v) << 24) & BM_PXP_HIST32_PARAM0_VALUE3)
+#define BP_PXP_HIST32_PARAM0_RSVD2 22
+#define BM_PXP_HIST32_PARAM0_RSVD2 0x00C00000
+#define BF_PXP_HIST32_PARAM0_RSVD2(v) \
+ (((v) << 22) & BM_PXP_HIST32_PARAM0_RSVD2)
+#define BP_PXP_HIST32_PARAM0_VALUE2 16
+#define BM_PXP_HIST32_PARAM0_VALUE2 0x003F0000
+#define BF_PXP_HIST32_PARAM0_VALUE2(v) \
+ (((v) << 16) & BM_PXP_HIST32_PARAM0_VALUE2)
+#define BP_PXP_HIST32_PARAM0_RSVD1 14
+#define BM_PXP_HIST32_PARAM0_RSVD1 0x0000C000
+#define BF_PXP_HIST32_PARAM0_RSVD1(v) \
+ (((v) << 14) & BM_PXP_HIST32_PARAM0_RSVD1)
+#define BP_PXP_HIST32_PARAM0_VALUE1 8
+#define BM_PXP_HIST32_PARAM0_VALUE1 0x00003F00
+#define BF_PXP_HIST32_PARAM0_VALUE1(v) \
+ (((v) << 8) & BM_PXP_HIST32_PARAM0_VALUE1)
+#define BP_PXP_HIST32_PARAM0_RSVD0 6
+#define BM_PXP_HIST32_PARAM0_RSVD0 0x000000C0
+#define BF_PXP_HIST32_PARAM0_RSVD0(v) \
+ (((v) << 6) & BM_PXP_HIST32_PARAM0_RSVD0)
+#define BP_PXP_HIST32_PARAM0_VALUE0 0
+#define BM_PXP_HIST32_PARAM0_VALUE0 0x0000003F
+#define BF_PXP_HIST32_PARAM0_VALUE0(v) \
+ (((v) << 0) & BM_PXP_HIST32_PARAM0_VALUE0)
+
+#define HW_PXP_HIST32_PARAM1 (0x00002b90)
+
+#define BP_PXP_HIST32_PARAM1_RSVD7 30
+#define BM_PXP_HIST32_PARAM1_RSVD7 0xC0000000
+#define BF_PXP_HIST32_PARAM1_RSVD7(v) \
+ (((v) << 30) & BM_PXP_HIST32_PARAM1_RSVD7)
+#define BP_PXP_HIST32_PARAM1_VALUE7 24
+#define BM_PXP_HIST32_PARAM1_VALUE7 0x3F000000
+#define BF_PXP_HIST32_PARAM1_VALUE7(v) \
+ (((v) << 24) & BM_PXP_HIST32_PARAM1_VALUE7)
+#define BP_PXP_HIST32_PARAM1_RSVD6 22
+#define BM_PXP_HIST32_PARAM1_RSVD6 0x00C00000
+#define BF_PXP_HIST32_PARAM1_RSVD6(v) \
+ (((v) << 22) & BM_PXP_HIST32_PARAM1_RSVD6)
+#define BP_PXP_HIST32_PARAM1_VALUE6 16
+#define BM_PXP_HIST32_PARAM1_VALUE6 0x003F0000
+#define BF_PXP_HIST32_PARAM1_VALUE6(v) \
+ (((v) << 16) & BM_PXP_HIST32_PARAM1_VALUE6)
+#define BP_PXP_HIST32_PARAM1_RSVD5 14
+#define BM_PXP_HIST32_PARAM1_RSVD5 0x0000C000
+#define BF_PXP_HIST32_PARAM1_RSVD5(v) \
+ (((v) << 14) & BM_PXP_HIST32_PARAM1_RSVD5)
+#define BP_PXP_HIST32_PARAM1_VALUE5 8
+#define BM_PXP_HIST32_PARAM1_VALUE5 0x00003F00
+#define BF_PXP_HIST32_PARAM1_VALUE5(v) \
+ (((v) << 8) & BM_PXP_HIST32_PARAM1_VALUE5)
+#define BP_PXP_HIST32_PARAM1_RSVD4 6
+#define BM_PXP_HIST32_PARAM1_RSVD4 0x000000C0
+#define BF_PXP_HIST32_PARAM1_RSVD4(v) \
+ (((v) << 6) & BM_PXP_HIST32_PARAM1_RSVD4)
+#define BP_PXP_HIST32_PARAM1_VALUE4 0
+#define BM_PXP_HIST32_PARAM1_VALUE4 0x0000003F
+#define BF_PXP_HIST32_PARAM1_VALUE4(v) \
+ (((v) << 0) & BM_PXP_HIST32_PARAM1_VALUE4)
+
+#define HW_PXP_HIST32_PARAM2 (0x00002ba0)
+
+#define BP_PXP_HIST32_PARAM2_RSVD11 30
+#define BM_PXP_HIST32_PARAM2_RSVD11 0xC0000000
+#define BF_PXP_HIST32_PARAM2_RSVD11(v) \
+ (((v) << 30) & BM_PXP_HIST32_PARAM2_RSVD11)
+#define BP_PXP_HIST32_PARAM2_VALUE11 24
+#define BM_PXP_HIST32_PARAM2_VALUE11 0x3F000000
+#define BF_PXP_HIST32_PARAM2_VALUE11(v) \
+ (((v) << 24) & BM_PXP_HIST32_PARAM2_VALUE11)
+#define BP_PXP_HIST32_PARAM2_RSVD10 22
+#define BM_PXP_HIST32_PARAM2_RSVD10 0x00C00000
+#define BF_PXP_HIST32_PARAM2_RSVD10(v) \
+ (((v) << 22) & BM_PXP_HIST32_PARAM2_RSVD10)
+#define BP_PXP_HIST32_PARAM2_VALUE10 16
+#define BM_PXP_HIST32_PARAM2_VALUE10 0x003F0000
+#define BF_PXP_HIST32_PARAM2_VALUE10(v) \
+ (((v) << 16) & BM_PXP_HIST32_PARAM2_VALUE10)
+#define BP_PXP_HIST32_PARAM2_RSVD9 14
+#define BM_PXP_HIST32_PARAM2_RSVD9 0x0000C000
+#define BF_PXP_HIST32_PARAM2_RSVD9(v) \
+ (((v) << 14) & BM_PXP_HIST32_PARAM2_RSVD9)
+#define BP_PXP_HIST32_PARAM2_VALUE9 8
+#define BM_PXP_HIST32_PARAM2_VALUE9 0x00003F00
+#define BF_PXP_HIST32_PARAM2_VALUE9(v) \
+ (((v) << 8) & BM_PXP_HIST32_PARAM2_VALUE9)
+#define BP_PXP_HIST32_PARAM2_RSVD8 6
+#define BM_PXP_HIST32_PARAM2_RSVD8 0x000000C0
+#define BF_PXP_HIST32_PARAM2_RSVD8(v) \
+ (((v) << 6) & BM_PXP_HIST32_PARAM2_RSVD8)
+#define BP_PXP_HIST32_PARAM2_VALUE8 0
+#define BM_PXP_HIST32_PARAM2_VALUE8 0x0000003F
+#define BF_PXP_HIST32_PARAM2_VALUE8(v) \
+ (((v) << 0) & BM_PXP_HIST32_PARAM2_VALUE8)
+
+#define HW_PXP_HIST32_PARAM3 (0x00002bb0)
+
+#define BP_PXP_HIST32_PARAM3_RSVD15 30
+#define BM_PXP_HIST32_PARAM3_RSVD15 0xC0000000
+#define BF_PXP_HIST32_PARAM3_RSVD15(v) \
+ (((v) << 30) & BM_PXP_HIST32_PARAM3_RSVD15)
+#define BP_PXP_HIST32_PARAM3_VALUE15 24
+#define BM_PXP_HIST32_PARAM3_VALUE15 0x3F000000
+#define BF_PXP_HIST32_PARAM3_VALUE15(v) \
+ (((v) << 24) & BM_PXP_HIST32_PARAM3_VALUE15)
+#define BP_PXP_HIST32_PARAM3_RSVD14 22
+#define BM_PXP_HIST32_PARAM3_RSVD14 0x00C00000
+#define BF_PXP_HIST32_PARAM3_RSVD14(v) \
+ (((v) << 22) & BM_PXP_HIST32_PARAM3_RSVD14)
+#define BP_PXP_HIST32_PARAM3_VALUE14 16
+#define BM_PXP_HIST32_PARAM3_VALUE14 0x003F0000
+#define BF_PXP_HIST32_PARAM3_VALUE14(v) \
+ (((v) << 16) & BM_PXP_HIST32_PARAM3_VALUE14)
+#define BP_PXP_HIST32_PARAM3_RSVD13 14
+#define BM_PXP_HIST32_PARAM3_RSVD13 0x0000C000
+#define BF_PXP_HIST32_PARAM3_RSVD13(v) \
+ (((v) << 14) & BM_PXP_HIST32_PARAM3_RSVD13)
+#define BP_PXP_HIST32_PARAM3_VALUE13 8
+#define BM_PXP_HIST32_PARAM3_VALUE13 0x00003F00
+#define BF_PXP_HIST32_PARAM3_VALUE13(v) \
+ (((v) << 8) & BM_PXP_HIST32_PARAM3_VALUE13)
+#define BP_PXP_HIST32_PARAM3_RSVD12 6
+#define BM_PXP_HIST32_PARAM3_RSVD12 0x000000C0
+#define BF_PXP_HIST32_PARAM3_RSVD12(v) \
+ (((v) << 6) & BM_PXP_HIST32_PARAM3_RSVD12)
+#define BP_PXP_HIST32_PARAM3_VALUE12 0
+#define BM_PXP_HIST32_PARAM3_VALUE12 0x0000003F
+#define BF_PXP_HIST32_PARAM3_VALUE12(v) \
+ (((v) << 0) & BM_PXP_HIST32_PARAM3_VALUE12)
+
+#define HW_PXP_HIST32_PARAM4 (0x00002bc0)
+
+#define BP_PXP_HIST32_PARAM4_RSVD3 30
+#define BM_PXP_HIST32_PARAM4_RSVD3 0xC0000000
+#define BF_PXP_HIST32_PARAM4_RSVD3(v) \
+ (((v) << 30) & BM_PXP_HIST32_PARAM4_RSVD3)
+#define BP_PXP_HIST32_PARAM4_VALUE19 24
+#define BM_PXP_HIST32_PARAM4_VALUE19 0x3F000000
+#define BF_PXP_HIST32_PARAM4_VALUE19(v) \
+ (((v) << 24) & BM_PXP_HIST32_PARAM4_VALUE19)
+#define BP_PXP_HIST32_PARAM4_RSVD2 22
+#define BM_PXP_HIST32_PARAM4_RSVD2 0x00C00000
+#define BF_PXP_HIST32_PARAM4_RSVD2(v) \
+ (((v) << 22) & BM_PXP_HIST32_PARAM4_RSVD2)
+#define BP_PXP_HIST32_PARAM4_VALUE18 16
+#define BM_PXP_HIST32_PARAM4_VALUE18 0x003F0000
+#define BF_PXP_HIST32_PARAM4_VALUE18(v) \
+ (((v) << 16) & BM_PXP_HIST32_PARAM4_VALUE18)
+#define BP_PXP_HIST32_PARAM4_RSVD1 14
+#define BM_PXP_HIST32_PARAM4_RSVD1 0x0000C000
+#define BF_PXP_HIST32_PARAM4_RSVD1(v) \
+ (((v) << 14) & BM_PXP_HIST32_PARAM4_RSVD1)
+#define BP_PXP_HIST32_PARAM4_VALUE17 8
+#define BM_PXP_HIST32_PARAM4_VALUE17 0x00003F00
+#define BF_PXP_HIST32_PARAM4_VALUE17(v) \
+ (((v) << 8) & BM_PXP_HIST32_PARAM4_VALUE17)
+#define BP_PXP_HIST32_PARAM4_RSVD0 6
+#define BM_PXP_HIST32_PARAM4_RSVD0 0x000000C0
+#define BF_PXP_HIST32_PARAM4_RSVD0(v) \
+ (((v) << 6) & BM_PXP_HIST32_PARAM4_RSVD0)
+#define BP_PXP_HIST32_PARAM4_VALUE16 0
+#define BM_PXP_HIST32_PARAM4_VALUE16 0x0000003F
+#define BF_PXP_HIST32_PARAM4_VALUE16(v) \
+ (((v) << 0) & BM_PXP_HIST32_PARAM4_VALUE16)
+
+#define HW_PXP_HIST32_PARAM5 (0x00002bd0)
+
+#define BP_PXP_HIST32_PARAM5_RSVD7 30
+#define BM_PXP_HIST32_PARAM5_RSVD7 0xC0000000
+#define BF_PXP_HIST32_PARAM5_RSVD7(v) \
+ (((v) << 30) & BM_PXP_HIST32_PARAM5_RSVD7)
+#define BP_PXP_HIST32_PARAM5_VALUE23 24
+#define BM_PXP_HIST32_PARAM5_VALUE23 0x3F000000
+#define BF_PXP_HIST32_PARAM5_VALUE23(v) \
+ (((v) << 24) & BM_PXP_HIST32_PARAM5_VALUE23)
+#define BP_PXP_HIST32_PARAM5_RSVD6 22
+#define BM_PXP_HIST32_PARAM5_RSVD6 0x00C00000
+#define BF_PXP_HIST32_PARAM5_RSVD6(v) \
+ (((v) << 22) & BM_PXP_HIST32_PARAM5_RSVD6)
+#define BP_PXP_HIST32_PARAM5_VALUE22 16
+#define BM_PXP_HIST32_PARAM5_VALUE22 0x003F0000
+#define BF_PXP_HIST32_PARAM5_VALUE22(v) \
+ (((v) << 16) & BM_PXP_HIST32_PARAM5_VALUE22)
+#define BP_PXP_HIST32_PARAM5_RSVD5 14
+#define BM_PXP_HIST32_PARAM5_RSVD5 0x0000C000
+#define BF_PXP_HIST32_PARAM5_RSVD5(v) \
+ (((v) << 14) & BM_PXP_HIST32_PARAM5_RSVD5)
+#define BP_PXP_HIST32_PARAM5_VALUE21 8
+#define BM_PXP_HIST32_PARAM5_VALUE21 0x00003F00
+#define BF_PXP_HIST32_PARAM5_VALUE21(v) \
+ (((v) << 8) & BM_PXP_HIST32_PARAM5_VALUE21)
+#define BP_PXP_HIST32_PARAM5_RSVD4 6
+#define BM_PXP_HIST32_PARAM5_RSVD4 0x000000C0
+#define BF_PXP_HIST32_PARAM5_RSVD4(v) \
+ (((v) << 6) & BM_PXP_HIST32_PARAM5_RSVD4)
+#define BP_PXP_HIST32_PARAM5_VALUE20 0
+#define BM_PXP_HIST32_PARAM5_VALUE20 0x0000003F
+#define BF_PXP_HIST32_PARAM5_VALUE20(v) \
+ (((v) << 0) & BM_PXP_HIST32_PARAM5_VALUE20)
+
+#define HW_PXP_HIST32_PARAM6 (0x00002be0)
+
+#define BP_PXP_HIST32_PARAM6_RSVD11 30
+#define BM_PXP_HIST32_PARAM6_RSVD11 0xC0000000
+#define BF_PXP_HIST32_PARAM6_RSVD11(v) \
+ (((v) << 30) & BM_PXP_HIST32_PARAM6_RSVD11)
+#define BP_PXP_HIST32_PARAM6_VALUE27 24
+#define BM_PXP_HIST32_PARAM6_VALUE27 0x3F000000
+#define BF_PXP_HIST32_PARAM6_VALUE27(v) \
+ (((v) << 24) & BM_PXP_HIST32_PARAM6_VALUE27)
+#define BP_PXP_HIST32_PARAM6_RSVD10 22
+#define BM_PXP_HIST32_PARAM6_RSVD10 0x00C00000
+#define BF_PXP_HIST32_PARAM6_RSVD10(v) \
+ (((v) << 22) & BM_PXP_HIST32_PARAM6_RSVD10)
+#define BP_PXP_HIST32_PARAM6_VALUE26 16
+#define BM_PXP_HIST32_PARAM6_VALUE26 0x003F0000
+#define BF_PXP_HIST32_PARAM6_VALUE26(v) \
+ (((v) << 16) & BM_PXP_HIST32_PARAM6_VALUE26)
+#define BP_PXP_HIST32_PARAM6_RSVD9 14
+#define BM_PXP_HIST32_PARAM6_RSVD9 0x0000C000
+#define BF_PXP_HIST32_PARAM6_RSVD9(v) \
+ (((v) << 14) & BM_PXP_HIST32_PARAM6_RSVD9)
+#define BP_PXP_HIST32_PARAM6_VALUE25 8
+#define BM_PXP_HIST32_PARAM6_VALUE25 0x00003F00
+#define BF_PXP_HIST32_PARAM6_VALUE25(v) \
+ (((v) << 8) & BM_PXP_HIST32_PARAM6_VALUE25)
+#define BP_PXP_HIST32_PARAM6_RSVD8 6
+#define BM_PXP_HIST32_PARAM6_RSVD8 0x000000C0
+#define BF_PXP_HIST32_PARAM6_RSVD8(v) \
+ (((v) << 6) & BM_PXP_HIST32_PARAM6_RSVD8)
+#define BP_PXP_HIST32_PARAM6_VALUE24 0
+#define BM_PXP_HIST32_PARAM6_VALUE24 0x0000003F
+#define BF_PXP_HIST32_PARAM6_VALUE24(v) \
+ (((v) << 0) & BM_PXP_HIST32_PARAM6_VALUE24)
+
+#define HW_PXP_HIST32_PARAM7 (0x00002bf0)
+
+#define BP_PXP_HIST32_PARAM7_RSVD15 30
+#define BM_PXP_HIST32_PARAM7_RSVD15 0xC0000000
+#define BF_PXP_HIST32_PARAM7_RSVD15(v) \
+ (((v) << 30) & BM_PXP_HIST32_PARAM7_RSVD15)
+#define BP_PXP_HIST32_PARAM7_VALUE31 24
+#define BM_PXP_HIST32_PARAM7_VALUE31 0x3F000000
+#define BF_PXP_HIST32_PARAM7_VALUE31(v) \
+ (((v) << 24) & BM_PXP_HIST32_PARAM7_VALUE31)
+#define BP_PXP_HIST32_PARAM7_RSVD14 22
+#define BM_PXP_HIST32_PARAM7_RSVD14 0x00C00000
+#define BF_PXP_HIST32_PARAM7_RSVD14(v) \
+ (((v) << 22) & BM_PXP_HIST32_PARAM7_RSVD14)
+#define BP_PXP_HIST32_PARAM7_VALUE30 16
+#define BM_PXP_HIST32_PARAM7_VALUE30 0x003F0000
+#define BF_PXP_HIST32_PARAM7_VALUE30(v) \
+ (((v) << 16) & BM_PXP_HIST32_PARAM7_VALUE30)
+#define BP_PXP_HIST32_PARAM7_RSVD13 14
+#define BM_PXP_HIST32_PARAM7_RSVD13 0x0000C000
+#define BF_PXP_HIST32_PARAM7_RSVD13(v) \
+ (((v) << 14) & BM_PXP_HIST32_PARAM7_RSVD13)
+#define BP_PXP_HIST32_PARAM7_VALUE29 8
+#define BM_PXP_HIST32_PARAM7_VALUE29 0x00003F00
+#define BF_PXP_HIST32_PARAM7_VALUE29(v) \
+ (((v) << 8) & BM_PXP_HIST32_PARAM7_VALUE29)
+#define BP_PXP_HIST32_PARAM7_RSVD2 6
+#define BM_PXP_HIST32_PARAM7_RSVD2 0x000000C0
+#define BF_PXP_HIST32_PARAM7_RSVD2(v) \
+ (((v) << 6) & BM_PXP_HIST32_PARAM7_RSVD2)
+#define BP_PXP_HIST32_PARAM7_VALUE28 0
+#define BM_PXP_HIST32_PARAM7_VALUE28 0x0000003F
+#define BF_PXP_HIST32_PARAM7_VALUE28(v) \
+ (((v) << 0) & BM_PXP_HIST32_PARAM7_VALUE28)
+
+#define HW_PXP_COMP_CTRL (0x00002c00)
+#define HW_PXP_COMP_CTRL_SET (0x00002c04)
+#define HW_PXP_COMP_CTRL_CLR (0x00002c08)
+#define HW_PXP_COMP_CTRL_TOG (0x00002c0c)
+
+#define BP_PXP_COMP_CTRL_RSVD0 9
+#define BM_PXP_COMP_CTRL_RSVD0 0xFFFFFE00
+#define BF_PXP_COMP_CTRL_RSVD0(v) \
+ (((v) << 9) & BM_PXP_COMP_CTRL_RSVD0)
+#define BM_PXP_COMP_CTRL_SW_RESET 0x00000100
+#define BF_PXP_COMP_CTRL_SW_RESET(v) \
+ (((v) << 8) & BM_PXP_COMP_CTRL_SW_RESET)
+#define BP_PXP_COMP_CTRL_RSVD1 1
+#define BM_PXP_COMP_CTRL_RSVD1 0x000000FE
+#define BF_PXP_COMP_CTRL_RSVD1(v) \
+ (((v) << 1) & BM_PXP_COMP_CTRL_RSVD1)
+#define BM_PXP_COMP_CTRL_START 0x00000001
+#define BF_PXP_COMP_CTRL_START(v) \
+ (((v) << 0) & BM_PXP_COMP_CTRL_START)
+
+#define HW_PXP_COMP_FORMAT0 (0x00002c10)
+#define HW_PXP_COMP_FORMAT0_SET (0x00002c14)
+#define HW_PXP_COMP_FORMAT0_CLR (0x00002c18)
+#define HW_PXP_COMP_FORMAT0_TOG (0x00002c1c)
+
+#define BP_PXP_COMP_FORMAT0_RSVD0 28
+#define BM_PXP_COMP_FORMAT0_RSVD0 0xF0000000
+#define BF_PXP_COMP_FORMAT0_RSVD0(v) \
+ (((v) << 28) & BM_PXP_COMP_FORMAT0_RSVD0)
+#define BP_PXP_COMP_FORMAT0_PIXEL_PITCH_64B 16
+#define BM_PXP_COMP_FORMAT0_PIXEL_PITCH_64B 0x0FFF0000
+#define BF_PXP_COMP_FORMAT0_PIXEL_PITCH_64B(v) \
+ (((v) << 16) & BM_PXP_COMP_FORMAT0_PIXEL_PITCH_64B)
+#define BP_PXP_COMP_FORMAT0_RSVD1 10
+#define BM_PXP_COMP_FORMAT0_RSVD1 0x0000FC00
+#define BF_PXP_COMP_FORMAT0_RSVD1(v) \
+ (((v) << 10) & BM_PXP_COMP_FORMAT0_RSVD1)
+#define BP_PXP_COMP_FORMAT0_MASK_INDEX 8
+#define BM_PXP_COMP_FORMAT0_MASK_INDEX 0x00000300
+#define BF_PXP_COMP_FORMAT0_MASK_INDEX(v) \
+ (((v) << 8) & BM_PXP_COMP_FORMAT0_MASK_INDEX)
+#define BP_PXP_COMP_FORMAT0_RSVD2 6
+#define BM_PXP_COMP_FORMAT0_RSVD2 0x000000C0
+#define BF_PXP_COMP_FORMAT0_RSVD2(v) \
+ (((v) << 6) & BM_PXP_COMP_FORMAT0_RSVD2)
+#define BP_PXP_COMP_FORMAT0_FIELD_NUM 4
+#define BM_PXP_COMP_FORMAT0_FIELD_NUM 0x00000030
+#define BF_PXP_COMP_FORMAT0_FIELD_NUM(v) \
+ (((v) << 4) & BM_PXP_COMP_FORMAT0_FIELD_NUM)
+#define BP_PXP_COMP_FORMAT0_RSVD3 1
+#define BM_PXP_COMP_FORMAT0_RSVD3 0x0000000E
+#define BF_PXP_COMP_FORMAT0_RSVD3(v) \
+ (((v) << 1) & BM_PXP_COMP_FORMAT0_RSVD3)
+#define BM_PXP_COMP_FORMAT0_FLAG_32B 0x00000001
+#define BF_PXP_COMP_FORMAT0_FLAG_32B(v) \
+ (((v) << 0) & BM_PXP_COMP_FORMAT0_FLAG_32B)
+
+#define HW_PXP_COMP_FORMAT1 (0x00002c20)
+
+#define BP_PXP_COMP_FORMAT1_D_LEN 29
+#define BM_PXP_COMP_FORMAT1_D_LEN 0xE0000000
+#define BF_PXP_COMP_FORMAT1_D_LEN(v) \
+ (((v) << 29) & BM_PXP_COMP_FORMAT1_D_LEN)
+#define BP_PXP_COMP_FORMAT1_D_OFFSET 24
+#define BM_PXP_COMP_FORMAT1_D_OFFSET 0x1F000000
+#define BF_PXP_COMP_FORMAT1_D_OFFSET(v) \
+ (((v) << 24) & BM_PXP_COMP_FORMAT1_D_OFFSET)
+#define BP_PXP_COMP_FORMAT1_C_LEN 21
+#define BM_PXP_COMP_FORMAT1_C_LEN 0x00E00000
+#define BF_PXP_COMP_FORMAT1_C_LEN(v) \
+ (((v) << 21) & BM_PXP_COMP_FORMAT1_C_LEN)
+#define BP_PXP_COMP_FORMAT1_C_OFFSET 16
+#define BM_PXP_COMP_FORMAT1_C_OFFSET 0x001F0000
+#define BF_PXP_COMP_FORMAT1_C_OFFSET(v) \
+ (((v) << 16) & BM_PXP_COMP_FORMAT1_C_OFFSET)
+#define BP_PXP_COMP_FORMAT1_B_LEN 13
+#define BM_PXP_COMP_FORMAT1_B_LEN 0x0000E000
+#define BF_PXP_COMP_FORMAT1_B_LEN(v) \
+ (((v) << 13) & BM_PXP_COMP_FORMAT1_B_LEN)
+#define BP_PXP_COMP_FORMAT1_B_OFFSET 8
+#define BM_PXP_COMP_FORMAT1_B_OFFSET 0x00001F00
+#define BF_PXP_COMP_FORMAT1_B_OFFSET(v) \
+ (((v) << 8) & BM_PXP_COMP_FORMAT1_B_OFFSET)
+#define BP_PXP_COMP_FORMAT1_A_LEN 5
+#define BM_PXP_COMP_FORMAT1_A_LEN 0x000000E0
+#define BF_PXP_COMP_FORMAT1_A_LEN(v) \
+ (((v) << 5) & BM_PXP_COMP_FORMAT1_A_LEN)
+#define BP_PXP_COMP_FORMAT1_A_OFFSET 0
+#define BM_PXP_COMP_FORMAT1_A_OFFSET 0x0000001F
+#define BF_PXP_COMP_FORMAT1_A_OFFSET(v) \
+ (((v) << 0) & BM_PXP_COMP_FORMAT1_A_OFFSET)
+
+#define HW_PXP_COMP_FORMAT2 (0x00002c30)
+
+#define BP_PXP_COMP_FORMAT2_RSVD 16
+#define BM_PXP_COMP_FORMAT2_RSVD 0xFFFF0000
+#define BF_PXP_COMP_FORMAT2_RSVD(v) \
+ (((v) << 16) & BM_PXP_COMP_FORMAT2_RSVD)
+#define BP_PXP_COMP_FORMAT2_D_RUNLEN 12
+#define BM_PXP_COMP_FORMAT2_D_RUNLEN 0x0000F000
+#define BF_PXP_COMP_FORMAT2_D_RUNLEN(v) \
+ (((v) << 12) & BM_PXP_COMP_FORMAT2_D_RUNLEN)
+#define BP_PXP_COMP_FORMAT2_C_RUNLEN 8
+#define BM_PXP_COMP_FORMAT2_C_RUNLEN 0x00000F00
+#define BF_PXP_COMP_FORMAT2_C_RUNLEN(v) \
+ (((v) << 8) & BM_PXP_COMP_FORMAT2_C_RUNLEN)
+#define BP_PXP_COMP_FORMAT2_B_RUNLEN 4
+#define BM_PXP_COMP_FORMAT2_B_RUNLEN 0x000000F0
+#define BF_PXP_COMP_FORMAT2_B_RUNLEN(v) \
+ (((v) << 4) & BM_PXP_COMP_FORMAT2_B_RUNLEN)
+#define BP_PXP_COMP_FORMAT2_A_RUNLEN 0
+#define BM_PXP_COMP_FORMAT2_A_RUNLEN 0x0000000F
+#define BF_PXP_COMP_FORMAT2_A_RUNLEN(v) \
+ (((v) << 0) & BM_PXP_COMP_FORMAT2_A_RUNLEN)
+
+#define HW_PXP_COMP_MASK0 (0x00002c40)
+
+#define BP_PXP_COMP_MASK0_VLD_MASK_LOW 0
+#define BM_PXP_COMP_MASK0_VLD_MASK_LOW 0xFFFFFFFF
+#define BF_PXP_COMP_MASK0_VLD_MASK_LOW(v) (v)
+
+#define HW_PXP_COMP_MASK1 (0x00002c50)
+
+#define BP_PXP_COMP_MASK1_VLD_MASK_HIGH 0
+#define BM_PXP_COMP_MASK1_VLD_MASK_HIGH 0xFFFFFFFF
+#define BF_PXP_COMP_MASK1_VLD_MASK_HIGH(v) (v)
+
+#define HW_PXP_COMP_BUFFER_SIZE (0x00002c60)
+
+#define BP_PXP_COMP_BUFFER_SIZE_RSVD0 29
+#define BM_PXP_COMP_BUFFER_SIZE_RSVD0 0xE0000000
+#define BF_PXP_COMP_BUFFER_SIZE_RSVD0(v) \
+ (((v) << 29) & BM_PXP_COMP_BUFFER_SIZE_RSVD0)
+#define BP_PXP_COMP_BUFFER_SIZE_PIXEL_WIDTH 16
+#define BM_PXP_COMP_BUFFER_SIZE_PIXEL_WIDTH 0x1FFF0000
+#define BF_PXP_COMP_BUFFER_SIZE_PIXEL_WIDTH(v) \
+ (((v) << 16) & BM_PXP_COMP_BUFFER_SIZE_PIXEL_WIDTH)
+#define BP_PXP_COMP_BUFFER_SIZE_RSVD1 13
+#define BM_PXP_COMP_BUFFER_SIZE_RSVD1 0x0000E000
+#define BF_PXP_COMP_BUFFER_SIZE_RSVD1(v) \
+ (((v) << 13) & BM_PXP_COMP_BUFFER_SIZE_RSVD1)
+#define BP_PXP_COMP_BUFFER_SIZE_PIXEL_LENGTH 0
+#define BM_PXP_COMP_BUFFER_SIZE_PIXEL_LENGTH 0x00001FFF
+#define BF_PXP_COMP_BUFFER_SIZE_PIXEL_LENGTH(v) \
+ (((v) << 0) & BM_PXP_COMP_BUFFER_SIZE_PIXEL_LENGTH)
+
+#define HW_PXP_COMP_SOURCE (0x00002c70)
+
+#define BP_PXP_COMP_SOURCE_SOURCE_ADDR 0
+#define BM_PXP_COMP_SOURCE_SOURCE_ADDR 0xFFFFFFFF
+#define BF_PXP_COMP_SOURCE_SOURCE_ADDR(v) (v)
+
+#define HW_PXP_COMP_TARGET (0x00002c80)
+
+#define BP_PXP_COMP_TARGET_TARGET_ADDR 0
+#define BM_PXP_COMP_TARGET_TARGET_ADDR 0xFFFFFFFF
+#define BF_PXP_COMP_TARGET_TARGET_ADDR(v) (v)
+
+#define HW_PXP_COMP_BUFFER_A (0x00002c90)
+
+#define BP_PXP_COMP_BUFFER_A_A_SRAM_ADDR 0
+#define BM_PXP_COMP_BUFFER_A_A_SRAM_ADDR 0xFFFFFFFF
+#define BF_PXP_COMP_BUFFER_A_A_SRAM_ADDR(v) (v)
+
+#define HW_PXP_COMP_BUFFER_B (0x00002ca0)
+
+#define BP_PXP_COMP_BUFFER_B_B_SRAM_ADDR 0
+#define BM_PXP_COMP_BUFFER_B_B_SRAM_ADDR 0xFFFFFFFF
+#define BF_PXP_COMP_BUFFER_B_B_SRAM_ADDR(v) (v)
+
+#define HW_PXP_COMP_BUFFER_C (0x00002cb0)
+
+#define BP_PXP_COMP_BUFFER_C_C_SRAM_ADDR 0
+#define BM_PXP_COMP_BUFFER_C_C_SRAM_ADDR 0xFFFFFFFF
+#define BF_PXP_COMP_BUFFER_C_C_SRAM_ADDR(v) (v)
+
+#define HW_PXP_COMP_BUFFER_D (0x00002cc0)
+
+#define BP_PXP_COMP_BUFFER_D_D_SRAM_ADDR 0
+#define BM_PXP_COMP_BUFFER_D_D_SRAM_ADDR 0xFFFFFFFF
+#define BF_PXP_COMP_BUFFER_D_D_SRAM_ADDR(v) (v)
+
+#define HW_PXP_COMP_DEBUG (0x00002cd0)
+
+#define BP_PXP_COMP_DEBUG_DEBUG_VALUE 8
+#define BM_PXP_COMP_DEBUG_DEBUG_VALUE 0xFFFFFF00
+#define BF_PXP_COMP_DEBUG_DEBUG_VALUE(v) \
+ (((v) << 8) & BM_PXP_COMP_DEBUG_DEBUG_VALUE)
+#define BP_PXP_COMP_DEBUG_DEBUG_SEL 0
+#define BM_PXP_COMP_DEBUG_DEBUG_SEL 0x000000FF
+#define BF_PXP_COMP_DEBUG_DEBUG_SEL(v) \
+ (((v) << 0) & BM_PXP_COMP_DEBUG_DEBUG_SEL)
+
+#define HW_PXP_BUS_MUX (0x00002ce0)
+
+#define BP_PXP_BUS_MUX_RSVD1 24
+#define BM_PXP_BUS_MUX_RSVD1 0xFF000000
+#define BF_PXP_BUS_MUX_RSVD1(v) \
+ (((v) << 24) & BM_PXP_BUS_MUX_RSVD1)
+#define BP_PXP_BUS_MUX_WR_SEL 16
+#define BM_PXP_BUS_MUX_WR_SEL 0x00FF0000
+#define BF_PXP_BUS_MUX_WR_SEL(v) \
+ (((v) << 16) & BM_PXP_BUS_MUX_WR_SEL)
+#define BP_PXP_BUS_MUX_RSVD0 8
+#define BM_PXP_BUS_MUX_RSVD0 0x0000FF00
+#define BF_PXP_BUS_MUX_RSVD0(v) \
+ (((v) << 8) & BM_PXP_BUS_MUX_RSVD0)
+#define BP_PXP_BUS_MUX_RD_SEL 0
+#define BM_PXP_BUS_MUX_RD_SEL 0x000000FF
+#define BF_PXP_BUS_MUX_RD_SEL(v) \
+ (((v) << 0) & BM_PXP_BUS_MUX_RD_SEL)
+
+#define HW_PXP_HANDSHAKE_READY_MUX0 (0x00002cf0)
+
+#define BP_PXP_HANDSHAKE_READY_MUX0_HSK7 28
+#define BM_PXP_HANDSHAKE_READY_MUX0_HSK7 0xF0000000
+#define BF_PXP_HANDSHAKE_READY_MUX0_HSK7(v) \
+ (((v) << 28) & BM_PXP_HANDSHAKE_READY_MUX0_HSK7)
+#define BP_PXP_HANDSHAKE_READY_MUX0_HSK6 24
+#define BM_PXP_HANDSHAKE_READY_MUX0_HSK6 0x0F000000
+#define BF_PXP_HANDSHAKE_READY_MUX0_HSK6(v) \
+ (((v) << 24) & BM_PXP_HANDSHAKE_READY_MUX0_HSK6)
+#define BP_PXP_HANDSHAKE_READY_MUX0_HSK5 20
+#define BM_PXP_HANDSHAKE_READY_MUX0_HSK5 0x00F00000
+#define BF_PXP_HANDSHAKE_READY_MUX0_HSK5(v) \
+ (((v) << 20) & BM_PXP_HANDSHAKE_READY_MUX0_HSK5)
+#define BP_PXP_HANDSHAKE_READY_MUX0_HSK4 16
+#define BM_PXP_HANDSHAKE_READY_MUX0_HSK4 0x000F0000
+#define BF_PXP_HANDSHAKE_READY_MUX0_HSK4(v) \
+ (((v) << 16) & BM_PXP_HANDSHAKE_READY_MUX0_HSK4)
+#define BP_PXP_HANDSHAKE_READY_MUX0_HSK3 12
+#define BM_PXP_HANDSHAKE_READY_MUX0_HSK3 0x0000F000
+#define BF_PXP_HANDSHAKE_READY_MUX0_HSK3(v) \
+ (((v) << 12) & BM_PXP_HANDSHAKE_READY_MUX0_HSK3)
+#define BP_PXP_HANDSHAKE_READY_MUX0_HSK2 8
+#define BM_PXP_HANDSHAKE_READY_MUX0_HSK2 0x00000F00
+#define BF_PXP_HANDSHAKE_READY_MUX0_HSK2(v) \
+ (((v) << 8) & BM_PXP_HANDSHAKE_READY_MUX0_HSK2)
+#define BP_PXP_HANDSHAKE_READY_MUX0_HSK1 4
+#define BM_PXP_HANDSHAKE_READY_MUX0_HSK1 0x000000F0
+#define BF_PXP_HANDSHAKE_READY_MUX0_HSK1(v) \
+ (((v) << 4) & BM_PXP_HANDSHAKE_READY_MUX0_HSK1)
+#define BP_PXP_HANDSHAKE_READY_MUX0_HSK0 0
+#define BM_PXP_HANDSHAKE_READY_MUX0_HSK0 0x0000000F
+#define BF_PXP_HANDSHAKE_READY_MUX0_HSK0(v) \
+ (((v) << 0) & BM_PXP_HANDSHAKE_READY_MUX0_HSK0)
+
+#define HW_PXP_HANDSHAKE_READY_MUX1 (0x00002d00)
+
+#define BP_PXP_HANDSHAKE_READY_MUX1_HSK15 28
+#define BM_PXP_HANDSHAKE_READY_MUX1_HSK15 0xF0000000
+#define BF_PXP_HANDSHAKE_READY_MUX1_HSK15(v) \
+ (((v) << 28) & BM_PXP_HANDSHAKE_READY_MUX1_HSK15)
+#define BP_PXP_HANDSHAKE_READY_MUX1_HSK14 24
+#define BM_PXP_HANDSHAKE_READY_MUX1_HSK14 0x0F000000
+#define BF_PXP_HANDSHAKE_READY_MUX1_HSK14(v) \
+ (((v) << 24) & BM_PXP_HANDSHAKE_READY_MUX1_HSK14)
+#define BP_PXP_HANDSHAKE_READY_MUX1_HSK13 20
+#define BM_PXP_HANDSHAKE_READY_MUX1_HSK13 0x00F00000
+#define BF_PXP_HANDSHAKE_READY_MUX1_HSK13(v) \
+ (((v) << 20) & BM_PXP_HANDSHAKE_READY_MUX1_HSK13)
+#define BP_PXP_HANDSHAKE_READY_MUX1_HSK12 16
+#define BM_PXP_HANDSHAKE_READY_MUX1_HSK12 0x000F0000
+#define BF_PXP_HANDSHAKE_READY_MUX1_HSK12(v) \
+ (((v) << 16) & BM_PXP_HANDSHAKE_READY_MUX1_HSK12)
+#define BP_PXP_HANDSHAKE_READY_MUX1_HSK11 12
+#define BM_PXP_HANDSHAKE_READY_MUX1_HSK11 0x0000F000
+#define BF_PXP_HANDSHAKE_READY_MUX1_HSK11(v) \
+ (((v) << 12) & BM_PXP_HANDSHAKE_READY_MUX1_HSK11)
+#define BP_PXP_HANDSHAKE_READY_MUX1_HSK10 8
+#define BM_PXP_HANDSHAKE_READY_MUX1_HSK10 0x00000F00
+#define BF_PXP_HANDSHAKE_READY_MUX1_HSK10(v) \
+ (((v) << 8) & BM_PXP_HANDSHAKE_READY_MUX1_HSK10)
+#define BP_PXP_HANDSHAKE_READY_MUX1_HSK9 4
+#define BM_PXP_HANDSHAKE_READY_MUX1_HSK9 0x000000F0
+#define BF_PXP_HANDSHAKE_READY_MUX1_HSK9(v) \
+ (((v) << 4) & BM_PXP_HANDSHAKE_READY_MUX1_HSK9)
+#define BP_PXP_HANDSHAKE_READY_MUX1_HSK8 0
+#define BM_PXP_HANDSHAKE_READY_MUX1_HSK8 0x0000000F
+#define BF_PXP_HANDSHAKE_READY_MUX1_HSK8(v) \
+ (((v) << 0) & BM_PXP_HANDSHAKE_READY_MUX1_HSK8)
+
+#define HW_PXP_HANDSHAKE_DONE_MUX0 (0x00002d10)
+
+#define BP_PXP_HANDSHAKE_DONE_MUX0_HSK7 28
+#define BM_PXP_HANDSHAKE_DONE_MUX0_HSK7 0xF0000000
+#define BF_PXP_HANDSHAKE_DONE_MUX0_HSK7(v) \
+ (((v) << 28) & BM_PXP_HANDSHAKE_DONE_MUX0_HSK7)
+#define BP_PXP_HANDSHAKE_DONE_MUX0_HSK6 24
+#define BM_PXP_HANDSHAKE_DONE_MUX0_HSK6 0x0F000000
+#define BF_PXP_HANDSHAKE_DONE_MUX0_HSK6(v) \
+ (((v) << 24) & BM_PXP_HANDSHAKE_DONE_MUX0_HSK6)
+#define BP_PXP_HANDSHAKE_DONE_MUX0_HSK5 20
+#define BM_PXP_HANDSHAKE_DONE_MUX0_HSK5 0x00F00000
+#define BF_PXP_HANDSHAKE_DONE_MUX0_HSK5(v) \
+ (((v) << 20) & BM_PXP_HANDSHAKE_DONE_MUX0_HSK5)
+#define BP_PXP_HANDSHAKE_DONE_MUX0_HSK4 16
+#define BM_PXP_HANDSHAKE_DONE_MUX0_HSK4 0x000F0000
+#define BF_PXP_HANDSHAKE_DONE_MUX0_HSK4(v) \
+ (((v) << 16) & BM_PXP_HANDSHAKE_DONE_MUX0_HSK4)
+#define BP_PXP_HANDSHAKE_DONE_MUX0_HSK3 12
+#define BM_PXP_HANDSHAKE_DONE_MUX0_HSK3 0x0000F000
+#define BF_PXP_HANDSHAKE_DONE_MUX0_HSK3(v) \
+ (((v) << 12) & BM_PXP_HANDSHAKE_DONE_MUX0_HSK3)
+#define BP_PXP_HANDSHAKE_DONE_MUX0_HSK2 8
+#define BM_PXP_HANDSHAKE_DONE_MUX0_HSK2 0x00000F00
+#define BF_PXP_HANDSHAKE_DONE_MUX0_HSK2(v) \
+ (((v) << 8) & BM_PXP_HANDSHAKE_DONE_MUX0_HSK2)
+#define BP_PXP_HANDSHAKE_DONE_MUX0_HSK1 4
+#define BM_PXP_HANDSHAKE_DONE_MUX0_HSK1 0x000000F0
+#define BF_PXP_HANDSHAKE_DONE_MUX0_HSK1(v) \
+ (((v) << 4) & BM_PXP_HANDSHAKE_DONE_MUX0_HSK1)
+#define BP_PXP_HANDSHAKE_DONE_MUX0_HSK0 0
+#define BM_PXP_HANDSHAKE_DONE_MUX0_HSK0 0x0000000F
+#define BF_PXP_HANDSHAKE_DONE_MUX0_HSK0(v) \
+ (((v) << 0) & BM_PXP_HANDSHAKE_DONE_MUX0_HSK0)
+
+#define HW_PXP_HANDSHAKE_DONE_MUX1 (0x00002d20)
+
+#define BP_PXP_HANDSHAKE_DONE_MUX1_HSK15 28
+#define BM_PXP_HANDSHAKE_DONE_MUX1_HSK15 0xF0000000
+#define BF_PXP_HANDSHAKE_DONE_MUX1_HSK15(v) \
+ (((v) << 28) & BM_PXP_HANDSHAKE_DONE_MUX1_HSK15)
+#define BP_PXP_HANDSHAKE_DONE_MUX1_HSK14 24
+#define BM_PXP_HANDSHAKE_DONE_MUX1_HSK14 0x0F000000
+#define BF_PXP_HANDSHAKE_DONE_MUX1_HSK14(v) \
+ (((v) << 24) & BM_PXP_HANDSHAKE_DONE_MUX1_HSK14)
+#define BP_PXP_HANDSHAKE_DONE_MUX1_HSK13 20
+#define BM_PXP_HANDSHAKE_DONE_MUX1_HSK13 0x00F00000
+#define BF_PXP_HANDSHAKE_DONE_MUX1_HSK13(v) \
+ (((v) << 20) & BM_PXP_HANDSHAKE_DONE_MUX1_HSK13)
+#define BP_PXP_HANDSHAKE_DONE_MUX1_HSK12 16
+#define BM_PXP_HANDSHAKE_DONE_MUX1_HSK12 0x000F0000
+#define BF_PXP_HANDSHAKE_DONE_MUX1_HSK12(v) \
+ (((v) << 16) & BM_PXP_HANDSHAKE_DONE_MUX1_HSK12)
+#define BP_PXP_HANDSHAKE_DONE_MUX1_HSK11 12
+#define BM_PXP_HANDSHAKE_DONE_MUX1_HSK11 0x0000F000
+#define BF_PXP_HANDSHAKE_DONE_MUX1_HSK11(v) \
+ (((v) << 12) & BM_PXP_HANDSHAKE_DONE_MUX1_HSK11)
+#define BP_PXP_HANDSHAKE_DONE_MUX1_HSK10 8
+#define BM_PXP_HANDSHAKE_DONE_MUX1_HSK10 0x00000F00
+#define BF_PXP_HANDSHAKE_DONE_MUX1_HSK10(v) \
+ (((v) << 8) & BM_PXP_HANDSHAKE_DONE_MUX1_HSK10)
+#define BP_PXP_HANDSHAKE_DONE_MUX1_HSK9 4
+#define BM_PXP_HANDSHAKE_DONE_MUX1_HSK9 0x000000F0
+#define BF_PXP_HANDSHAKE_DONE_MUX1_HSK9(v) \
+ (((v) << 4) & BM_PXP_HANDSHAKE_DONE_MUX1_HSK9)
+#define BP_PXP_HANDSHAKE_DONE_MUX1_HSK8 0
+#define BM_PXP_HANDSHAKE_DONE_MUX1_HSK8 0x0000000F
+#define BF_PXP_HANDSHAKE_DONE_MUX1_HSK8(v) \
+ (((v) << 0) & BM_PXP_HANDSHAKE_DONE_MUX1_HSK8)
+
+#define HW_PXP_HANDSHAKE_CPU_FETCH (0x00002d30)
+#define HW_PXP_HANDSHAKE_CPU_FETCH_SET (0x00002d34)
+#define HW_PXP_HANDSHAKE_CPU_FETCH_CLR (0x00002d38)
+#define HW_PXP_HANDSHAKE_CPU_FETCH_TOG (0x00002d3c)
+
+#define BM_PXP_HANDSHAKE_CPU_FETCH_SW1_HSK_EN 0x80000000
+#define BF_PXP_HANDSHAKE_CPU_FETCH_SW1_HSK_EN(v) \
+ (((v) << 31) & BM_PXP_HANDSHAKE_CPU_FETCH_SW1_HSK_EN)
+#define BP_PXP_HANDSHAKE_CPU_FETCH_RSVD1 22
+#define BM_PXP_HANDSHAKE_CPU_FETCH_RSVD1 0x7FC00000
+#define BF_PXP_HANDSHAKE_CPU_FETCH_RSVD1(v) \
+ (((v) << 22) & BM_PXP_HANDSHAKE_CPU_FETCH_RSVD1)
+#define BP_PXP_HANDSHAKE_CPU_FETCH_SW1_BUF_LINES 20
+#define BM_PXP_HANDSHAKE_CPU_FETCH_SW1_BUF_LINES 0x00300000
+#define BF_PXP_HANDSHAKE_CPU_FETCH_SW1_BUF_LINES(v) \
+ (((v) << 20) & BM_PXP_HANDSHAKE_CPU_FETCH_SW1_BUF_LINES)
+#define BV_PXP_HANDSHAKE_CPU_FETCH_SW1_BUF_LINES__LINE_4 0x0
+#define BV_PXP_HANDSHAKE_CPU_FETCH_SW1_BUF_LINES__LINE_8 0x1
+#define BV_PXP_HANDSHAKE_CPU_FETCH_SW1_BUF_LINES__LINE_16 0x2
+#define BM_PXP_HANDSHAKE_CPU_FETCH_SW1_B1_DONE 0x00080000
+#define BF_PXP_HANDSHAKE_CPU_FETCH_SW1_B1_DONE(v) \
+ (((v) << 19) & BM_PXP_HANDSHAKE_CPU_FETCH_SW1_B1_DONE)
+#define BM_PXP_HANDSHAKE_CPU_FETCH_SW1_B0_DONE 0x00040000
+#define BF_PXP_HANDSHAKE_CPU_FETCH_SW1_B0_DONE(v) \
+ (((v) << 18) & BM_PXP_HANDSHAKE_CPU_FETCH_SW1_B0_DONE)
+#define BM_PXP_HANDSHAKE_CPU_FETCH_SW1_B1_READY 0x00020000
+#define BF_PXP_HANDSHAKE_CPU_FETCH_SW1_B1_READY(v) \
+ (((v) << 17) & BM_PXP_HANDSHAKE_CPU_FETCH_SW1_B1_READY)
+#define BM_PXP_HANDSHAKE_CPU_FETCH_SW1_B0_READY 0x00010000
+#define BF_PXP_HANDSHAKE_CPU_FETCH_SW1_B0_READY(v) \
+ (((v) << 16) & BM_PXP_HANDSHAKE_CPU_FETCH_SW1_B0_READY)
+#define BM_PXP_HANDSHAKE_CPU_FETCH_SW0_HSK_EN 0x00008000
+#define BF_PXP_HANDSHAKE_CPU_FETCH_SW0_HSK_EN(v) \
+ (((v) << 15) & BM_PXP_HANDSHAKE_CPU_FETCH_SW0_HSK_EN)
+#define BP_PXP_HANDSHAKE_CPU_FETCH_RSVD0 6
+#define BM_PXP_HANDSHAKE_CPU_FETCH_RSVD0 0x00007FC0
+#define BF_PXP_HANDSHAKE_CPU_FETCH_RSVD0(v) \
+ (((v) << 6) & BM_PXP_HANDSHAKE_CPU_FETCH_RSVD0)
+#define BP_PXP_HANDSHAKE_CPU_FETCH_SW0_BUF_LINES 4
+#define BM_PXP_HANDSHAKE_CPU_FETCH_SW0_BUF_LINES 0x00000030
+#define BF_PXP_HANDSHAKE_CPU_FETCH_SW0_BUF_LINES(v) \
+ (((v) << 4) & BM_PXP_HANDSHAKE_CPU_FETCH_SW0_BUF_LINES)
+#define BV_PXP_HANDSHAKE_CPU_FETCH_SW0_BUF_LINES__LINE_4 0x0
+#define BV_PXP_HANDSHAKE_CPU_FETCH_SW0_BUF_LINES__LINE_8 0x1
+#define BV_PXP_HANDSHAKE_CPU_FETCH_SW0_BUF_LINES__LINE_16 0x2
+#define BM_PXP_HANDSHAKE_CPU_FETCH_SW0_B1_DONE 0x00000008
+#define BF_PXP_HANDSHAKE_CPU_FETCH_SW0_B1_DONE(v) \
+ (((v) << 3) & BM_PXP_HANDSHAKE_CPU_FETCH_SW0_B1_DONE)
+#define BM_PXP_HANDSHAKE_CPU_FETCH_SW0_B0_DONE 0x00000004
+#define BF_PXP_HANDSHAKE_CPU_FETCH_SW0_B0_DONE(v) \
+ (((v) << 2) & BM_PXP_HANDSHAKE_CPU_FETCH_SW0_B0_DONE)
+#define BM_PXP_HANDSHAKE_CPU_FETCH_SW0_B1_READY 0x00000002
+#define BF_PXP_HANDSHAKE_CPU_FETCH_SW0_B1_READY(v) \
+ (((v) << 1) & BM_PXP_HANDSHAKE_CPU_FETCH_SW0_B1_READY)
+#define BM_PXP_HANDSHAKE_CPU_FETCH_SW0_B0_READY 0x00000001
+#define BF_PXP_HANDSHAKE_CPU_FETCH_SW0_B0_READY(v) \
+ (((v) << 0) & BM_PXP_HANDSHAKE_CPU_FETCH_SW0_B0_READY)
+
+#define HW_PXP_HANDSHAKE_CPU_STORE (0x00002d40)
+#define HW_PXP_HANDSHAKE_CPU_STORE_SET (0x00002d44)
+#define HW_PXP_HANDSHAKE_CPU_STORE_CLR (0x00002d48)
+#define HW_PXP_HANDSHAKE_CPU_STORE_TOG (0x00002d4c)
+
+#define BM_PXP_HANDSHAKE_CPU_STORE_SW1_HSK_EN 0x80000000
+#define BF_PXP_HANDSHAKE_CPU_STORE_SW1_HSK_EN(v) \
+ (((v) << 31) & BM_PXP_HANDSHAKE_CPU_STORE_SW1_HSK_EN)
+#define BP_PXP_HANDSHAKE_CPU_STORE_RSVD1 22
+#define BM_PXP_HANDSHAKE_CPU_STORE_RSVD1 0x7FC00000
+#define BF_PXP_HANDSHAKE_CPU_STORE_RSVD1(v) \
+ (((v) << 22) & BM_PXP_HANDSHAKE_CPU_STORE_RSVD1)
+#define BP_PXP_HANDSHAKE_CPU_STORE_SW1_BUF_LINES 20
+#define BM_PXP_HANDSHAKE_CPU_STORE_SW1_BUF_LINES 0x00300000
+#define BF_PXP_HANDSHAKE_CPU_STORE_SW1_BUF_LINES(v) \
+ (((v) << 20) & BM_PXP_HANDSHAKE_CPU_STORE_SW1_BUF_LINES)
+#define BV_PXP_HANDSHAKE_CPU_STORE_SW1_BUF_LINES__LINE_4 0x0
+#define BV_PXP_HANDSHAKE_CPU_STORE_SW1_BUF_LINES__LINE_8 0x1
+#define BV_PXP_HANDSHAKE_CPU_STORE_SW1_BUF_LINES__LINE_16 0x2
+#define BM_PXP_HANDSHAKE_CPU_STORE_SW1_B1_DONE 0x00080000
+#define BF_PXP_HANDSHAKE_CPU_STORE_SW1_B1_DONE(v) \
+ (((v) << 19) & BM_PXP_HANDSHAKE_CPU_STORE_SW1_B1_DONE)
+#define BM_PXP_HANDSHAKE_CPU_STORE_SW1_B0_DONE 0x00040000
+#define BF_PXP_HANDSHAKE_CPU_STORE_SW1_B0_DONE(v) \
+ (((v) << 18) & BM_PXP_HANDSHAKE_CPU_STORE_SW1_B0_DONE)
+#define BM_PXP_HANDSHAKE_CPU_STORE_SW1_B1_READY 0x00020000
+#define BF_PXP_HANDSHAKE_CPU_STORE_SW1_B1_READY(v) \
+ (((v) << 17) & BM_PXP_HANDSHAKE_CPU_STORE_SW1_B1_READY)
+#define BM_PXP_HANDSHAKE_CPU_STORE_SW1_B0_READY 0x00010000
+#define BF_PXP_HANDSHAKE_CPU_STORE_SW1_B0_READY(v) \
+ (((v) << 16) & BM_PXP_HANDSHAKE_CPU_STORE_SW1_B0_READY)
+#define BM_PXP_HANDSHAKE_CPU_STORE_SW0_HSK_EN 0x00008000
+#define BF_PXP_HANDSHAKE_CPU_STORE_SW0_HSK_EN(v) \
+ (((v) << 15) & BM_PXP_HANDSHAKE_CPU_STORE_SW0_HSK_EN)
+#define BP_PXP_HANDSHAKE_CPU_STORE_RSVD0 6
+#define BM_PXP_HANDSHAKE_CPU_STORE_RSVD0 0x00007FC0
+#define BF_PXP_HANDSHAKE_CPU_STORE_RSVD0(v) \
+ (((v) << 6) & BM_PXP_HANDSHAKE_CPU_STORE_RSVD0)
+#define BP_PXP_HANDSHAKE_CPU_STORE_SW0_BUF_LINES 4
+#define BM_PXP_HANDSHAKE_CPU_STORE_SW0_BUF_LINES 0x00000030
+#define BF_PXP_HANDSHAKE_CPU_STORE_SW0_BUF_LINES(v) \
+ (((v) << 4) & BM_PXP_HANDSHAKE_CPU_STORE_SW0_BUF_LINES)
+#define BV_PXP_HANDSHAKE_CPU_STORE_SW0_BUF_LINES__LINE_4 0x0
+#define BV_PXP_HANDSHAKE_CPU_STORE_SW0_BUF_LINES__LINE_8 0x1
+#define BV_PXP_HANDSHAKE_CPU_STORE_SW0_BUF_LINES__LINE_16 0x2
+#define BM_PXP_HANDSHAKE_CPU_STORE_SW0_B1_DONE 0x00000008
+#define BF_PXP_HANDSHAKE_CPU_STORE_SW0_B1_DONE(v) \
+ (((v) << 3) & BM_PXP_HANDSHAKE_CPU_STORE_SW0_B1_DONE)
+#define BM_PXP_HANDSHAKE_CPU_STORE_SW0_B0_DONE 0x00000004
+#define BF_PXP_HANDSHAKE_CPU_STORE_SW0_B0_DONE(v) \
+ (((v) << 2) & BM_PXP_HANDSHAKE_CPU_STORE_SW0_B0_DONE)
+#define BM_PXP_HANDSHAKE_CPU_STORE_SW0_B1_READY 0x00000002
+#define BF_PXP_HANDSHAKE_CPU_STORE_SW0_B1_READY(v) \
+ (((v) << 1) & BM_PXP_HANDSHAKE_CPU_STORE_SW0_B1_READY)
+#define BM_PXP_HANDSHAKE_CPU_STORE_SW0_B0_READY 0x00000001
+#define BF_PXP_HANDSHAKE_CPU_STORE_SW0_B0_READY(v) \
+ (((v) << 0) & BM_PXP_HANDSHAKE_CPU_STORE_SW0_B0_READY)
+#endif /* __ARCH_ARM___PXP_H */
diff --git a/drivers/dma/virt-dma.c b/drivers/dma/virt-dma.c
index 545e97279083..f5ac9e4a914e 100644
--- a/drivers/dma/virt-dma.c
+++ b/drivers/dma/virt-dma.c
@@ -107,12 +107,13 @@ static void vchan_complete(unsigned long arg)
dmaengine_desc_get_callback(&vd->tx, &cb);
list_del(&vd->node);
+
+ dmaengine_desc_callback_invoke(&cb, NULL);
+
if (dmaengine_desc_test_reuse(&vd->tx))
list_add(&vd->node, &vc->desc_allocated);
else
vc->desc_free(vd);
-
- dmaengine_desc_callback_invoke(&cb, NULL);
}
}
diff --git a/drivers/extcon/Kconfig b/drivers/extcon/Kconfig
index a7bca4207f44..05fa891dcd43 100644
--- a/drivers/extcon/Kconfig
+++ b/drivers/extcon/Kconfig
@@ -157,4 +157,12 @@ config EXTCON_USBC_CROS_EC
Say Y here to enable USB Type C cable detection extcon support when
using Chrome OS EC based USB Type-C ports.
+config EXTCON_PTN5150
+ tristate "NXP PTN5150 CC Logic For Type-C Applications"
+ depends on I2C && GPIOLIB
+ select REGMAP_I2C
+ help
+ Say Y here to enable NXP PTN5150 CC logic for Type-C applications,
+ this chip can supply the CC flip, attach and detach detection.
+
endif
diff --git a/drivers/extcon/Makefile b/drivers/extcon/Makefile
index 0888fdeded72..cc36ee05d5bd 100644
--- a/drivers/extcon/Makefile
+++ b/drivers/extcon/Makefile
@@ -22,3 +22,4 @@ obj-$(CONFIG_EXTCON_RT8973A) += extcon-rt8973a.o
obj-$(CONFIG_EXTCON_SM5502) += extcon-sm5502.o
obj-$(CONFIG_EXTCON_USB_GPIO) += extcon-usb-gpio.o
obj-$(CONFIG_EXTCON_USBC_CROS_EC) += extcon-usbc-cros-ec.o
+obj-$(CONFIG_EXTCON_PTN5150) += extcon-ptn5150.o
diff --git a/drivers/extcon/extcon-ptn5150.c b/drivers/extcon/extcon-ptn5150.c
new file mode 100644
index 000000000000..778b427699c0
--- /dev/null
+++ b/drivers/extcon/extcon-ptn5150.c
@@ -0,0 +1,271 @@
+/*
+ * extcon-ptn5150.c - NXP CC logic for USB Type-C applications
+ *
+ * Copyright 2017 NXP
+ * Author: Peter Chen <peter.chen@nxp.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 of
+ * the License 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/err.h>
+#include <linux/i2c.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/regmap.h>
+#include <linux/extcon.h>
+#include <linux/gpio/consumer.h>
+
+/* PTN5150_REG_INT_STATUS */
+#define CABLE_ATTACHED (1 << 0)
+#define CABLE_DETACHED (1 << 1)
+/* PTN5150_REG_CC_STATUS */
+#define IS_DFP_ATTATCHED(val) (((val) & 0x1c) == 0x4)
+#define IS_UFP_ATTATCHED(val) (((val) & 0x1c) == 0x8)
+#define IS_NOT_CONNECTED(val) (((val) & 0x1c) == 0x0)
+/* PTN5150_REG_CON_DET */
+#define DISABLE_CON_DET (1 << 0)
+
+struct ptn5150_info {
+ struct device *dev;
+ struct extcon_dev *edev;
+
+ struct work_struct wq_detect_cable;
+ struct regmap *regmap;
+};
+
+/* List of detectable cables */
+static const unsigned int ptn5150_extcon_cable[] = {
+ EXTCON_USB,
+ EXTCON_USB_HOST,
+ EXTCON_NONE,
+};
+
+enum ptn5150_reg {
+ PTN5150_REG_DEVICE_ID = 0x1,
+ PTN5150_REG_CONTROL,
+ PTN5150_REG_INT_STATUS,
+ PTN5150_REG_CC_STATUS,
+ PTN5150_REG_RSVD_5,
+ PTN5150_REG_RSVD_6,
+ PTN5150_REG_RSVD_7,
+ PTN5150_REG_RSVD_8,
+ PTN5150_REG_CON_DET,
+ PTN5150_REG_VCONN_STATUS,
+ PTN5150_REG_RESET = 0x10,
+ PTN5150_REG_RSVD_11,
+ PTN5150_REG_RSVD_12,
+ PTN5150_REG_RSVD_13,
+ PTN5150_REG_RSVD_14,
+ PTN5150_REG_RSVD_15,
+ PTN5150_REG_RSVD_16,
+ PTN5150_REG_RSVD_17,
+ PTN5150_REG_INT_MASK,
+ PTN5150_REG_INT_REG_STATUS,
+
+ PTN5150_REG_END,
+};
+static const struct regmap_config ptn5150_regmap_config = {
+ .reg_bits = 8,
+ .val_bits = 8,
+ .max_register = PTN5150_REG_END,
+};
+
+static void ptn5150_detect_cable(struct work_struct *work)
+{
+ struct ptn5150_info *info = container_of(work, struct ptn5150_info,
+ wq_detect_cable);
+ int ret;
+ unsigned int val;
+
+ ret = regmap_read(info->regmap, PTN5150_REG_CC_STATUS, &val);
+ if (ret)
+ dev_err(info->dev, "failed to get CC status:%d\n", ret);
+
+ if (IS_UFP_ATTATCHED(val)) {
+ extcon_set_state_sync(info->edev, EXTCON_USB, false);
+ extcon_set_state_sync(info->edev, EXTCON_USB_HOST,
+ true);
+ } else if (IS_DFP_ATTATCHED(val)) {
+ extcon_set_state_sync(info->edev, EXTCON_USB_HOST,
+ false);
+ extcon_set_state_sync(info->edev, EXTCON_USB, true);
+ } else if (IS_NOT_CONNECTED(val)) {
+ extcon_set_state_sync(info->edev, EXTCON_USB, false);
+ extcon_set_state_sync(info->edev, EXTCON_USB_HOST, false);
+ } else {
+ dev_dbg(info->dev, "other CC status is :0x%x", val);
+ }
+}
+
+static int ptn5150_clear_interrupt(struct ptn5150_info *info)
+{
+ unsigned int val;
+ int ret;
+
+ ret = regmap_read(info->regmap, PTN5150_REG_INT_STATUS, &val);
+ if (ret)
+ dev_err(info->dev,
+ "failed to clear interrupt status:%d\n",
+ ret);
+
+ return (ret < 0) ? ret : (int)val;
+}
+
+static irqreturn_t ptn5150_connect_irq_handler(int irq, void *dev_id)
+{
+ struct ptn5150_info *info = dev_id;
+
+ if (ptn5150_clear_interrupt(info) > 0)
+ queue_work(system_power_efficient_wq, &info->wq_detect_cable);
+
+ return IRQ_HANDLED;
+}
+
+static int ptn5150_i2c_probe(struct i2c_client *i2c,
+ const struct i2c_device_id *id)
+{
+ struct device_node *np = i2c->dev.of_node;
+ struct ptn5150_info *info;
+ int ret, connect_irq, gpio_val, count = 1000;
+ unsigned int dev_id;
+ struct gpio_desc *connect_gpiod;
+
+ if (!np)
+ return -EINVAL;
+
+ info = devm_kzalloc(&i2c->dev, sizeof(*info), GFP_KERNEL);
+ if (!info)
+ return -ENOMEM;
+
+ i2c_set_clientdata(i2c, info);
+ info->dev = &i2c->dev;
+ info->regmap = devm_regmap_init_i2c(i2c, &ptn5150_regmap_config);
+ if (IS_ERR(info->regmap)) {
+ ret = PTR_ERR(info->regmap);
+ dev_err(info->dev, "failed to allocate register map: %d\n",
+ ret);
+ return ret;
+ }
+
+ /* Allocate extcon device */
+ info->edev = devm_extcon_dev_allocate(info->dev, ptn5150_extcon_cable);
+ if (IS_ERR(info->edev)) {
+ dev_err(info->dev, "failed to allocate memory for extcon\n");
+ return -ENOMEM;
+ }
+
+ /* Register extcon device */
+ ret = devm_extcon_dev_register(info->dev, info->edev);
+ if (ret) {
+ dev_err(info->dev, "failed to register extcon device\n");
+ return ret;
+ }
+
+ connect_gpiod = devm_gpiod_get(info->dev, "connect", GPIOD_IN);
+ if (IS_ERR(connect_gpiod)) {
+ dev_err(info->dev, "failed to get connect GPIO\n");
+ return PTR_ERR(connect_gpiod);
+ }
+
+ connect_irq = gpiod_to_irq(connect_gpiod);
+ if (connect_irq < 0) {
+ dev_err(info->dev, "failed to get connect IRQ\n");
+ return connect_irq;
+ }
+
+ /* Clear the pending interrupts */
+ ret = ptn5150_clear_interrupt(info);
+ if (ret < 0)
+ return ret;
+
+ gpio_val = gpiod_get_value(connect_gpiod);
+ /* Delay until the GPIO goes to high if it is low before */
+ while (gpio_val == 0 && count >= 0) {
+ gpio_val = gpiod_get_value(connect_gpiod);
+ usleep_range(10, 20);
+ count--;
+ }
+
+ if (count < 0)
+ dev_err(info->dev, "timeout for waiting gpio becoming high\n");
+
+ ret = regmap_read(info->regmap, PTN5150_REG_DEVICE_ID, &dev_id);
+ if (ret) {
+ dev_err(info->dev, "failed to read device id:%d\n", ret);
+ return ret;
+ }
+
+ dev_dbg(info->dev, "NXP PTN5150: Version ID:0x%x, Vendor ID:0x%x\n",
+ (dev_id >> 3), (dev_id & 0x3));
+
+ ret = regmap_update_bits(info->regmap, PTN5150_REG_CON_DET,
+ DISABLE_CON_DET, ~DISABLE_CON_DET);
+ if (ret) {
+ dev_err(info->dev,
+ "failed to enable CON_DET output on pin 5:%d\n",
+ ret);
+ return ret;
+ }
+
+ INIT_WORK(&info->wq_detect_cable, ptn5150_detect_cable);
+
+ ret = devm_request_threaded_irq(info->dev, connect_irq, NULL,
+ ptn5150_connect_irq_handler,
+ IRQF_TRIGGER_LOW | IRQF_ONESHOT,
+ dev_name(info->dev), info);
+ if (ret < 0) {
+ dev_err(info->dev, "failed to request connect IRQ\n");
+ return ret;
+ }
+
+ /* Do cable detect now */
+ ptn5150_detect_cable(&info->wq_detect_cable);
+
+ return ret;
+}
+
+static int ptn5150_i2c_remove(struct i2c_client *i2c)
+{
+ return 0;
+}
+
+static const struct i2c_device_id ptn5150_id[] = {
+ { "ptn5150", 0 },
+ { },
+};
+MODULE_DEVICE_TABLE(i2c, ptn5150_id);
+
+#ifdef CONFIG_OF
+static const struct of_device_id ptn5150_of_match[] = {
+ { .compatible = "nxp,ptn5150", },
+ { .compatible = "nxp,ptn5150a", },
+ {},
+};
+MODULE_DEVICE_TABLE(of, ptn5150_of_match);
+#endif
+
+static struct i2c_driver ptn5150_i2c_driver = {
+ .driver = {
+ .name = "ptn5150",
+ .of_match_table = of_match_ptr(ptn5150_of_match),
+ },
+ .probe = ptn5150_i2c_probe,
+ .remove = ptn5150_i2c_remove,
+ .id_table = ptn5150_id,
+};
+module_i2c_driver(ptn5150_i2c_driver);
+
+MODULE_DESCRIPTION("NXP PTN5150 CC logic driver for USB Type-C");
+MODULE_AUTHOR("Peter Chen <peter.chen@nxp.com>");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 2357d2f73c1a..92b3d3ed5489 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -344,7 +344,7 @@ config GPIO_MVEBU
config GPIO_MXC
def_bool y
- depends on ARCH_MXC
+ depends on ARCH_MXC || ARCH_MXC_ARM64 || COMPILE_TEST
select GPIO_GENERIC
select GENERIC_IRQ_CHIP
@@ -354,6 +354,13 @@ config GPIO_MXS
select GPIO_GENERIC
select GENERIC_IRQ_CHIP
+config GPIO_MXC_PAD_WAKEUP
+ def_bool n
+ depends on ARCH_MXC_ARM64 || COMPILE_TEST
+ select GPIO_MXC
+ help
+ Say Y here to enable the imx8 gpio pad wakeup
+
config GPIO_OCTEON
tristate "Cavium OCTEON GPIO"
depends on GPIOLIB && CAVIUM_OCTEON_SOC
@@ -482,6 +489,12 @@ config GPIO_VF610
help
Say yes here to support Vybrid vf610 GPIOs.
+config GPIO_IMX_RPMSG
+ bool "NXP i.MX7ULP RPMSG GPIO support"
+ depends on ARCH_MXC && RPMSG && GPIOLIB
+ help
+ This driver support i.MX7ULP RPMSG virtual GPIOs.
+
config GPIO_VR41XX
tristate "NEC VR4100 series General-purpose I/O Uint support"
depends on CPU_VR41XX
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 8a2dfba3b231..df630457f5ba 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -133,6 +133,7 @@ obj-$(CONFIG_GPIO_TZ1090) += gpio-tz1090.o
obj-$(CONFIG_GPIO_TZ1090_PDC) += gpio-tz1090-pdc.o
obj-$(CONFIG_GPIO_UCB1400) += gpio-ucb1400.o
obj-$(CONFIG_GPIO_VF610) += gpio-vf610.o
+obj-$(CONFIG_GPIO_IMX_RPMSG) += gpio-imx-rpmsg.o
obj-$(CONFIG_GPIO_VIPERBOARD) += gpio-viperboard.o
obj-$(CONFIG_GPIO_VR41XX) += gpio-vr41xx.o
obj-$(CONFIG_GPIO_VX855) += gpio-vx855.o
diff --git a/drivers/gpio/gpio-74x164.c b/drivers/gpio/gpio-74x164.c
index 15a1f4b348c4..1645e8c327cc 100644
--- a/drivers/gpio/gpio-74x164.c
+++ b/drivers/gpio/gpio-74x164.c
@@ -147,6 +147,9 @@ static int gen_74x164_probe(struct spi_device *spi)
chip->registers = nregs;
chip->gpio_chip.ngpio = GEN_74X164_NUMBER_GPIOS * chip->registers;
+ of_property_read_u8_array(spi->dev.of_node, "registers-default",
+ chip->buffer, chip->registers);
+
chip->gpio_chip.can_sleep = true;
chip->gpio_chip.parent = &spi->dev;
chip->gpio_chip.owner = THIS_MODULE;
diff --git a/drivers/gpio/gpio-imx-rpmsg.c b/drivers/gpio/gpio-imx-rpmsg.c
new file mode 100644
index 000000000000..092c290942ba
--- /dev/null
+++ b/drivers/gpio/gpio-imx-rpmsg.c
@@ -0,0 +1,430 @@
+/*
+ * Copyright 2017 NXP
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/bitops.h>
+#include <linux/err.h>
+#include <linux/gpio.h>
+#include <linux/imx_rpmsg.h>
+#include <linux/init.h>
+#include <linux/irqdomain.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/pm_qos.h>
+#include <linux/rpmsg.h>
+#include <linux/virtio.h>
+
+#define IMX_RPMSG_GPIO_PER_PORT 32
+#define RPMSG_TIMEOUT 1000
+
+enum gpio_input_trigger_type {
+ GPIO_RPMSG_TRI_IGNORE,
+ GPIO_RPMSG_TRI_RISING,
+ GPIO_RPMSG_TRI_FALLING,
+ GPIO_RPMSG_TRI_BOTH_EDGE,
+ GPIO_RPMSG_TRI_LOW_LEVEL,
+ GPIO_RPMSG_TRI_HIGH_LEVEL,
+};
+
+enum gpio_rpmsg_header_type {
+ GPIO_RPMSG_SETUP,
+ GPIO_RPMSG_REPLY,
+ GPIO_RPMSG_NOTIFY,
+};
+
+enum gpio_rpmsg_header_cmd {
+ GPIO_RPMSG_INPUT_INIT,
+ GPIO_RPMSG_OUTPUT_INIT,
+ GPIO_RPMSG_INPUT_GET,
+};
+
+struct gpio_rpmsg_data {
+ struct imx_rpmsg_head header;
+ u8 pin_idx;
+ u8 port_idx;
+ union {
+ u8 event;
+ u8 retcode;
+ u8 value;
+ } out;
+ union {
+ u8 wakeup;
+ u8 value;
+ } in;
+} __packed __aligned(8);
+
+struct imx_rpmsg_gpio_port {
+ struct gpio_chip gc;
+ struct irq_chip chip;
+ struct irq_domain *domain;
+ struct gpio_rpmsg_data msg;
+ u32 irq_type[IMX_RPMSG_GPIO_PER_PORT];
+ int idx;
+};
+
+struct imx_gpio_rpmsg_info {
+ struct rpmsg_device *rpdev;
+ struct gpio_rpmsg_data *notify_msg;
+ struct gpio_rpmsg_data *reply_msg;
+ struct pm_qos_request pm_qos_req;
+ struct completion cmd_complete;
+ struct mutex lock;
+};
+
+static struct imx_gpio_rpmsg_info gpio_rpmsg;
+
+static int gpio_send_message(struct imx_rpmsg_gpio_port *port,
+ struct gpio_rpmsg_data *msg,
+ struct imx_gpio_rpmsg_info *info,
+ bool sync)
+{
+ int err;
+
+ if (!info->rpdev) {
+ dev_dbg(&info->rpdev->dev,
+ "rpmsg channel not ready, m4 image ready?\n");
+ return -EINVAL;
+ }
+
+ mutex_lock(&info->lock);
+ pm_qos_add_request(&info->pm_qos_req,
+ PM_QOS_CPU_DMA_LATENCY, 0);
+
+ reinit_completion(&info->cmd_complete);
+
+ err = rpmsg_send(info->rpdev->ept, (void *)msg,
+ sizeof(struct gpio_rpmsg_data));
+
+ if (err) {
+ dev_err(&info->rpdev->dev, "rpmsg_send failed: %d\n", err);
+ goto err_out;
+ }
+
+ if (sync) {
+ err = wait_for_completion_timeout(&info->cmd_complete,
+ msecs_to_jiffies(RPMSG_TIMEOUT));
+ if (!err) {
+ dev_err(&info->rpdev->dev, "rpmsg_send timeout!\n");
+ err = -ETIMEDOUT;
+ goto err_out;
+ }
+
+ if (info->reply_msg->out.retcode != 0) {
+ dev_err(&info->rpdev->dev, "rpmsg not ack %d!\n",
+ info->reply_msg->out.retcode);
+ err = -EINVAL;
+ goto err_out;
+ }
+
+ /* copy the reply message */
+ memcpy(&port->msg, info->reply_msg, sizeof(*info->reply_msg));
+
+ err = 0;
+ }
+
+err_out:
+ pm_qos_remove_request(&info->pm_qos_req);
+ mutex_unlock(&info->lock);
+
+ return err;
+}
+
+static int gpio_rpmsg_cb(struct rpmsg_device *rpdev,
+ void *data, int len, void *priv, u32 src)
+{
+ struct gpio_rpmsg_data *msg = (struct gpio_rpmsg_data *)data;
+
+ if (msg->header.type == GPIO_RPMSG_REPLY) {
+ gpio_rpmsg.reply_msg = msg;
+ complete(&gpio_rpmsg.cmd_complete);
+ } else if (msg->header.type == GPIO_RPMSG_NOTIFY) {
+ gpio_rpmsg.notify_msg = msg;
+ /* TBD for interrupt handler */
+ } else
+ dev_err(&gpio_rpmsg.rpdev->dev, "wrong command type!\n");
+
+ return 0;
+}
+
+static int imx_rpmsg_gpio_get(struct gpio_chip *gc, unsigned int gpio)
+{
+ struct imx_rpmsg_gpio_port *port = gpiochip_get_data(gc);
+ struct gpio_rpmsg_data msg;
+ int ret;
+
+ memset(&msg, 0, sizeof(struct gpio_rpmsg_data));
+ msg.header.cate = IMX_RPMSG_GPIO;
+ msg.header.major = IMX_RMPSG_MAJOR;
+ msg.header.minor = IMX_RMPSG_MINOR;
+ msg.header.type = GPIO_RPMSG_SETUP;
+ msg.header.cmd = GPIO_RPMSG_INPUT_GET;
+ msg.pin_idx = gpio;
+ msg.port_idx = port->idx;
+
+ ret = gpio_send_message(port, &msg, &gpio_rpmsg, true);
+ if (!ret)
+ return !!port->msg.in.value;
+
+ return ret;
+}
+
+static int imx_rpmsg_gpio_direction_input(struct gpio_chip *gc,
+ unsigned int gpio)
+{
+ struct imx_rpmsg_gpio_port *port = gpiochip_get_data(gc);
+ struct gpio_rpmsg_data msg;
+
+ memset(&msg, 0, sizeof(struct gpio_rpmsg_data));
+ msg.header.cate = IMX_RPMSG_GPIO;
+ msg.header.major = IMX_RMPSG_MAJOR;
+ msg.header.minor = IMX_RMPSG_MINOR;
+ msg.header.type = GPIO_RPMSG_SETUP;
+ msg.header.cmd = GPIO_RPMSG_INPUT_INIT;
+ msg.pin_idx = gpio;
+ msg.port_idx = port->idx;
+
+ /* TBD: get event trigger and wakeup from GPIO descriptor */
+ msg.out.event = GPIO_RPMSG_TRI_IGNORE;
+ msg.in.wakeup = 0;
+
+ return gpio_send_message(port, &msg, &gpio_rpmsg, true);
+}
+
+static inline void imx_rpmsg_gpio_direction_output_init(struct gpio_chip *gc,
+ unsigned int gpio, int val, struct gpio_rpmsg_data *msg)
+{
+ struct imx_rpmsg_gpio_port *port = gpiochip_get_data(gc);
+
+ msg->header.cate = IMX_RPMSG_GPIO;
+ msg->header.major = IMX_RMPSG_MAJOR;
+ msg->header.minor = IMX_RMPSG_MINOR;
+ msg->header.type = GPIO_RPMSG_SETUP;
+ msg->header.cmd = GPIO_RPMSG_OUTPUT_INIT;
+ msg->pin_idx = gpio;
+ msg->port_idx = port->idx;
+ msg->out.value = val;
+}
+
+static void imx_rpmsg_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
+{
+ struct imx_rpmsg_gpio_port *port = gpiochip_get_data(gc);
+ struct gpio_rpmsg_data msg;
+
+ memset(&msg, 0, sizeof(struct gpio_rpmsg_data));
+ imx_rpmsg_gpio_direction_output_init(gc, gpio, val, &msg);
+ gpio_send_message(port, &msg, &gpio_rpmsg, true);
+}
+
+static int imx_rpmsg_gpio_direction_output(struct gpio_chip *gc,
+ unsigned int gpio, int val)
+{
+ struct imx_rpmsg_gpio_port *port = gpiochip_get_data(gc);
+ struct gpio_rpmsg_data msg;
+
+ memset(&msg, 0, sizeof(struct gpio_rpmsg_data));
+ imx_rpmsg_gpio_direction_output_init(gc, gpio, val, &msg);
+ return gpio_send_message(port, &msg, &gpio_rpmsg, true);
+}
+
+static int gpio_rpmsg_probe(struct rpmsg_device *rpdev)
+{
+ gpio_rpmsg.rpdev = rpdev;
+ dev_info(&rpdev->dev, "new channel: 0x%x -> 0x%x!\n",
+ rpdev->src, rpdev->dst);
+
+ init_completion(&gpio_rpmsg.cmd_complete);
+ mutex_init(&gpio_rpmsg.lock);
+
+ return 0;
+}
+
+static struct rpmsg_device_id gpio_rpmsg_id_table[] = {
+ { .name = "rpmsg-io-channel" },
+ {},
+};
+
+static struct rpmsg_driver gpio_rpmsg_driver = {
+ .drv.name = "gpio_rpmsg",
+ .drv.owner = THIS_MODULE,
+ .id_table = gpio_rpmsg_id_table,
+ .probe = gpio_rpmsg_probe,
+ .callback = gpio_rpmsg_cb,
+};
+
+static int imx_rpmsg_irq_set_type(struct irq_data *d, u32 type)
+{
+ struct imx_rpmsg_gpio_port *port = irq_data_get_irq_chip_data(d);
+ u32 gpio_idx = d->hwirq;
+ int edge = 0;
+ int ret = 0;
+
+ switch (type) {
+ case IRQ_TYPE_EDGE_RISING:
+ edge = GPIO_RPMSG_TRI_RISING;
+ break;
+ case IRQ_TYPE_EDGE_FALLING:
+ edge = GPIO_RPMSG_TRI_FALLING;
+ break;
+ case IRQ_TYPE_EDGE_BOTH:
+ edge = GPIO_RPMSG_TRI_BOTH_EDGE;
+ break;
+ case IRQ_TYPE_LEVEL_LOW:
+ edge = GPIO_RPMSG_TRI_LOW_LEVEL;
+ break;
+ case IRQ_TYPE_LEVEL_HIGH:
+ edge = GPIO_RPMSG_TRI_HIGH_LEVEL;
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+
+ port->irq_type[gpio_idx] = edge;
+ return ret;
+}
+
+static int imx_rpmsg_irq_set_wake(struct irq_data *d, u32 enable)
+{
+ struct imx_rpmsg_gpio_port *port = irq_data_get_irq_chip_data(d);
+ struct gpio_rpmsg_data msg;
+ u32 gpio_idx = d->hwirq;
+
+ memset(&msg, 0, sizeof(struct gpio_rpmsg_data));
+ msg.header.cate = IMX_RPMSG_GPIO;
+ msg.header.major = IMX_RMPSG_MAJOR;
+ msg.header.minor = IMX_RMPSG_MINOR;
+ msg.header.type = GPIO_RPMSG_SETUP;
+ msg.header.cmd = GPIO_RPMSG_INPUT_INIT;
+ msg.pin_idx = gpio_idx;
+ msg.port_idx = port->idx;
+
+ /* set wakeup trigger source,
+ * if not set irq type, then use high level as trigger type
+ */
+ msg.out.event = port->irq_type[gpio_idx];
+ if (!msg.out.event)
+ msg.out.event = GPIO_RPMSG_TRI_HIGH_LEVEL;
+
+ msg.in.wakeup = enable;
+
+ /* here should be atomic context */
+ gpio_send_message(port, &msg, &gpio_rpmsg, false);
+
+ return 0;
+}
+
+static void imx_rpmsg_unmask_irq(struct irq_data *d)
+{
+ /* No need to implement the callback */
+}
+
+static void imx_rpmsg_mask_irq(struct irq_data *d)
+{
+ /* No need to implement the callback */
+}
+
+static struct irq_chip imx_rpmsg_irq_chip = {
+ .irq_mask = imx_rpmsg_mask_irq,
+ .irq_unmask = imx_rpmsg_unmask_irq,
+ .irq_set_wake = imx_rpmsg_irq_set_wake,
+ .irq_set_type = imx_rpmsg_irq_set_type,
+};
+
+static int imx_rpmsg_gpio_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct device_node *np = dev->of_node;
+ struct imx_rpmsg_gpio_port *port;
+ struct gpio_chip *gc;
+ int i, irq_base;
+ int ret;
+
+ port = devm_kzalloc(&pdev->dev, sizeof(*port), GFP_KERNEL);
+ if (!port)
+ return -ENOMEM;
+
+ ret = of_property_read_u32(np, "port_idx", &port->idx);
+ if (ret)
+ return ret;
+
+ gc = &port->gc;
+ gc->of_node = np;
+ gc->parent = dev;
+ gc->label = "imx-rpmsg-gpio";
+ gc->ngpio = IMX_RPMSG_GPIO_PER_PORT;
+ gc->base = of_alias_get_id(np, "gpio") * IMX_RPMSG_GPIO_PER_PORT;
+
+ gc->direction_input = imx_rpmsg_gpio_direction_input;
+ gc->direction_output = imx_rpmsg_gpio_direction_output;
+ gc->get = imx_rpmsg_gpio_get;
+ gc->set = imx_rpmsg_gpio_set;
+
+ platform_set_drvdata(pdev, port);
+
+ ret = devm_gpiochip_add_data(dev, gc, port);
+ if (ret < 0)
+ return ret;
+
+ /* generate one new irq domain */
+ port->chip = imx_rpmsg_irq_chip;
+ port->chip.name = kasprintf(GFP_KERNEL, "rpmsg-irq-port-%d", port->idx);
+ port->chip.parent_device = NULL;
+
+ irq_base = irq_alloc_descs(-1, 0, IMX_RPMSG_GPIO_PER_PORT,
+ numa_node_id());
+ WARN_ON(irq_base < 0);
+
+ port->domain = irq_domain_add_legacy(np, IMX_RPMSG_GPIO_PER_PORT,
+ irq_base, 0,
+ &irq_domain_simple_ops, port);
+ WARN_ON(!port->domain);
+ for (i = irq_base; i < irq_base + IMX_RPMSG_GPIO_PER_PORT; i++) {
+ irq_set_chip_and_handler(i, &port->chip, handle_level_irq);
+ irq_set_chip_data(i, port);
+ irq_clear_status_flags(i, IRQ_NOREQUEST);
+ irq_set_probe(i);
+ }
+
+ return 0;
+}
+
+static const struct of_device_id imx_rpmsg_gpio_dt_ids[] = {
+ { .compatible = "fsl,imx-rpmsg-gpio" },
+ { /* sentinel */ }
+};
+
+static struct platform_driver imx_rpmsg_gpio_driver = {
+ .driver = {
+ .name = "gpio-imx-rpmsg",
+ .of_match_table = imx_rpmsg_gpio_dt_ids,
+ },
+ .probe = imx_rpmsg_gpio_probe,
+};
+
+static int __init gpio_imx_rpmsg_init(void)
+{
+ int ret;
+
+ ret = register_rpmsg_driver(&gpio_rpmsg_driver);
+ if (ret)
+ return ret;
+
+ return platform_driver_register(&imx_rpmsg_gpio_driver);
+}
+device_initcall(gpio_imx_rpmsg_init);
+
+MODULE_AUTHOR("NXP Semiconductor");
+MODULE_DESCRIPTION("NXP i.MX7ULP rpmsg gpio driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/gpio/gpio-max732x.c b/drivers/gpio/gpio-max732x.c
index 7f4d26ce5f23..288217991d63 100644
--- a/drivers/gpio/gpio-max732x.c
+++ b/drivers/gpio/gpio-max732x.c
@@ -22,6 +22,7 @@
#include <linux/i2c.h>
#include <linux/platform_data/max732x.h>
#include <linux/of.h>
+#include <linux/reset.h>
/*
@@ -80,6 +81,12 @@
#define INT_CAPS(x) (((uint64_t)(x)) << 32)
enum {
+ OUTPUT_MASK,
+ OUTPUT_VAL,
+ OUTPUT_NUM,
+};
+
+enum {
MAX7319,
MAX7320,
MAX7321,
@@ -625,6 +632,8 @@ static int max732x_probe(struct i2c_client *client,
struct i2c_client *c;
uint16_t addr_a, addr_b;
int ret, nr_port;
+ u16 out_set[OUTPUT_NUM];
+ unsigned long mask, val;
pdata = dev_get_platdata(&client->dev);
node = client->dev.of_node;
@@ -642,6 +651,10 @@ static int max732x_probe(struct i2c_client *client,
return -ENOMEM;
chip->client = client;
+ ret = device_reset(&client->dev);
+ if (ret == -EPROBE_DEFER)
+ return ret;
+
nr_port = max732x_setup_gpio(chip, id, pdata->gpio_base);
chip->gpio_chip.parent = &client->dev;
@@ -706,6 +719,15 @@ static int max732x_probe(struct i2c_client *client,
}
i2c_set_clientdata(client, chip);
+
+ /* set the output IO default voltage */
+ if (!of_property_read_u16_array(node, "out-default", out_set,
+ ARRAY_SIZE(out_set))) {
+ mask = out_set[OUTPUT_MASK] & chip->dir_output;
+ val = out_set[OUTPUT_VAL];
+ max732x_gpio_set_multiple(&chip->gpio_chip, &mask, &val);
+ }
+
return 0;
out_failed:
diff --git a/drivers/gpio/gpio-mxc.c b/drivers/gpio/gpio-mxc.c
index 5245a2fe62ae..10d189072dd3 100644
--- a/drivers/gpio/gpio-mxc.c
+++ b/drivers/gpio/gpio-mxc.c
@@ -20,6 +20,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
+#include <linux/clk.h>
#include <linux/err.h>
#include <linux/init.h>
#include <linux/interrupt.h>
@@ -28,6 +29,7 @@
#include <linux/irqdomain.h>
#include <linux/irqchip/chained_irq.h>
#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
#include <linux/slab.h>
#include <linux/gpio/driver.h>
/* FIXME: for gpio_get_value() replace this with direct register read */
@@ -35,6 +37,10 @@
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/bug.h>
+#ifdef CONFIG_GPIO_MXC_PAD_WAKEUP
+#include <soc/imx8/sc/sci.h>
+#include <soc/imx8/sc/svc/irq/api.h>
+#endif
enum mxc_gpio_hwtype {
IMX1_GPIO, /* runs on i.mx1 */
@@ -59,8 +65,17 @@ struct mxc_gpio_hwdata {
unsigned fall_edge;
};
+#ifdef CONFIG_GPIO_MXC_PAD_WAKEUP
+struct mxc_gpio_pad_wakeup {
+ u32 pin_id;
+ u32 type;
+ u32 line;
+};
+#endif
+
struct mxc_gpio_port {
struct list_head node;
+ struct clk *clk;
void __iomem *base;
int irq;
int irq_high;
@@ -68,8 +83,19 @@ struct mxc_gpio_port {
struct gpio_chip gc;
struct device *dev;
u32 both_edges;
+ int saved_reg[6];
+ int suspend_saved_reg[6];
+ bool gpio_ranges;
+#ifdef CONFIG_GPIO_MXC_PAD_WAKEUP
+ u32 pad_wakeup_num;
+ struct mxc_gpio_pad_wakeup pad_wakeup[32];
+#endif
};
+#ifdef CONFIG_GPIO_MXC_PAD_WAKEUP
+static sc_ipc_t gpio_ipc_handle;
+#endif
+
static struct mxc_gpio_hwdata imx1_imx21_gpio_hwdata = {
.dr_reg = 0x1c,
.gdir_reg = 0x00,
@@ -311,6 +337,67 @@ static void mx2_gpio_irq_handler(struct irq_desc *desc)
chained_irq_exit(chip, desc);
}
+#ifdef CONFIG_GPIO_MXC_PAD_WAKEUP
+static int mxc_gpio_get_pad_wakeup(struct mxc_gpio_port *port)
+{
+ sc_err_t sciErr;
+ u8 wakeup_type;
+ int i;
+
+ for (i = 0; i < port->pad_wakeup_num; i++) {
+ /* get original pad type */
+ wakeup_type = port->pad_wakeup[i].type;
+ sciErr = sc_pad_get_wakeup(gpio_ipc_handle,
+ port->pad_wakeup[i].pin_id, &wakeup_type);
+ if (sciErr)
+ dev_err(port->gc.parent, "sc_pad_get_wakeup failed\n");
+ /* return wakeup gpio pin's line */
+ if (wakeup_type != port->pad_wakeup[i].type)
+ return port->pad_wakeup[i].line;
+ }
+
+ return -EINVAL;
+}
+
+static void mxc_gpio_set_pad_wakeup(struct mxc_gpio_port *port, bool enable)
+{
+ sc_err_t sciErr;
+ int i;
+
+ for (i = 0; i < port->pad_wakeup_num; i++) {
+ sciErr = sc_pad_set_wakeup(gpio_ipc_handle,
+ port->pad_wakeup[i].pin_id,
+ enable ? port->pad_wakeup[i].type :
+ SC_PAD_WAKEUP_OFF);
+ if (sciErr)
+ dev_err(port->gc.parent, "sc_pad_set_wakeup failed\n");
+ }
+}
+
+static void mxc_gpio_handle_pad_wakeup(struct mxc_gpio_port *port, int line)
+{
+ struct irq_desc *desc = irq_to_desc(port->irq);
+ struct irq_chip *chip = irq_desc_get_chip(desc);
+ u32 irq_stat;
+
+ /* skip invalid line */
+ if (line > 31) {
+ dev_err(port->gc.parent, "invalid wakeup line %d\n", line);
+ return;
+ }
+
+ dev_info(port->gc.parent, "wakeup by pad, line %d\n", line);
+
+ chained_irq_enter(chip, desc);
+
+ irq_stat = (1 << line);
+
+ mxc_gpio_irq_handler(port, irq_stat);
+
+ chained_irq_exit(chip, desc);
+}
+#endif
+
/*
* Set interrupt number "irq" in the GPIO as a wake-up source.
* While system is running, all registered GPIO interrupts need to have
@@ -342,7 +429,32 @@ static int gpio_set_wake_irq(struct irq_data *d, u32 enable)
return ret;
}
-static int mxc_gpio_init_gc(struct mxc_gpio_port *port, int irq_base)
+static int mxc_gpio_irq_reqres(struct irq_data *d)
+{
+ struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
+ struct mxc_gpio_port *port = gc->private;
+
+ if (gpiochip_lock_as_irq(&port->gc, d->hwirq)) {
+ dev_err(port->gc.parent,
+ "unable to lock HW IRQ %lu for IRQ\n",
+ d->hwirq);
+ return -EINVAL;
+ }
+
+ return irq_chip_pm_get(d);
+}
+
+static void mxc_gpio_irq_relres(struct irq_data *d)
+{
+ struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
+ struct mxc_gpio_port *port = gc->private;
+
+ gpiochip_unlock_as_irq(&port->gc, d->hwirq);
+ irq_chip_pm_put(d);
+}
+
+static int mxc_gpio_init_gc(struct mxc_gpio_port *port, int irq_base,
+ struct device *dev)
{
struct irq_chip_generic *gc;
struct irq_chip_type *ct;
@@ -355,11 +467,14 @@ static int mxc_gpio_init_gc(struct mxc_gpio_port *port, int irq_base)
gc->private = port;
ct = gc->chip_types;
+ ct->chip.parent_device = dev;
ct->chip.irq_ack = irq_gc_ack_set_bit;
ct->chip.irq_mask = irq_gc_mask_clr_bit;
ct->chip.irq_unmask = irq_gc_mask_set_bit;
ct->chip.irq_set_type = gpio_set_irq_type;
ct->chip.irq_set_wake = gpio_set_wake_irq;
+ ct->chip.irq_request_resources = mxc_gpio_irq_reqres;
+ ct->chip.irq_release_resources = mxc_gpio_irq_relres,
ct->chip.flags = IRQCHIP_MASK_ON_SUSPEND;
ct->regs.ack = GPIO_ISR;
ct->regs.mask = GPIO_IMR;
@@ -408,13 +523,42 @@ static int mxc_gpio_to_irq(struct gpio_chip *gc, unsigned offset)
return irq_find_mapping(port->domain, offset);
}
+static int mxc_gpio_request(struct gpio_chip *chip, unsigned offset)
+{
+ struct mxc_gpio_port *port = gpiochip_get_data(chip);
+ int ret;
+
+ if (port->gpio_ranges) {
+ ret = gpiochip_generic_request(chip, offset);
+ if (ret)
+ return ret;
+ }
+
+ ret = pm_runtime_get_sync(chip->parent);
+ return ret < 0 ? ret : 0;
+}
+
+static void mxc_gpio_free(struct gpio_chip *chip, unsigned offset)
+{
+ struct mxc_gpio_port *port = gpiochip_get_data(chip);
+
+ if (port->gpio_ranges)
+ gpiochip_generic_free(chip, offset);
+ pm_runtime_put(chip->parent);
+}
+
static int mxc_gpio_probe(struct platform_device *pdev)
{
struct device_node *np = pdev->dev.of_node;
struct mxc_gpio_port *port;
struct resource *iores;
- int irq_base;
+ int irq_base = 0;
int err;
+#ifdef CONFIG_GPIO_MXC_PAD_WAKEUP
+ int i;
+ uint32_t mu_id;
+ sc_err_t sciErr;
+#endif
mxc_gpio_get_hw(pdev);
@@ -437,6 +581,58 @@ static int mxc_gpio_probe(struct platform_device *pdev)
if (port->irq < 0)
return port->irq;
+ /* the controller clock is optional */
+ port->clk = devm_clk_get(&pdev->dev, NULL);
+ if (IS_ERR(port->clk))
+ port->clk = NULL;
+
+ err = clk_prepare_enable(port->clk);
+ if (err) {
+ dev_err(&pdev->dev, "Unable to enable clock.\n");
+ return err;
+ }
+
+#ifdef CONFIG_GPIO_MXC_PAD_WAKEUP
+ /*
+ * parse pad wakeup info from dtb, each pad has to provide
+ * <pin_id, type, line>, these info should be put in each
+ * gpio node and with a "pad-wakeup-num" to indicate the
+ * total lines are with pad wakeup enabled.
+ */
+ if (!of_property_read_u32(np, "pad-wakeup-num", &port->pad_wakeup_num)) {
+ if (port->pad_wakeup_num != 0) {
+ if (!gpio_ipc_handle) {
+ sciErr = sc_ipc_getMuID(&mu_id);
+ if (sciErr != SC_ERR_NONE) {
+ dev_err(&pdev->dev,
+ "can not obtain mu id: %d\n", sciErr);
+ return sciErr;
+ }
+ sciErr = sc_ipc_open(&gpio_ipc_handle, mu_id);
+ if (sciErr != SC_ERR_NONE) {
+ dev_err(&pdev->dev,
+ "can not open mu channel to scu: %d\n", sciErr);
+ return sciErr;
+ }
+ }
+ for (i = 0; i < port->pad_wakeup_num; i++) {
+ of_property_read_u32_index(np, "pad-wakeup",
+ i * 3 + 0, &port->pad_wakeup[i].pin_id);
+ of_property_read_u32_index(np, "pad-wakeup",
+ i * 3 + 1, &port->pad_wakeup[i].type);
+ of_property_read_u32_index(np, "pad-wakeup",
+ i * 3 + 2, &port->pad_wakeup[i].line);
+ }
+ }
+ }
+#endif
+
+ pm_runtime_set_active(&pdev->dev);
+ pm_runtime_enable(&pdev->dev);
+ err = pm_runtime_get_sync(&pdev->dev);
+ if (err < 0)
+ goto out_pm_dis;
+
/* disable the interrupt and clear the status */
writel(0, port->base + GPIO_IMR);
writel(~0, port->base + GPIO_ISR);
@@ -467,11 +663,14 @@ static int mxc_gpio_probe(struct platform_device *pdev)
if (err)
goto out_bgio;
- if (of_property_read_bool(np, "gpio-ranges")) {
- port->gc.request = gpiochip_generic_request;
- port->gc.free = gpiochip_generic_free;
- }
+ if (of_property_read_bool(np, "gpio_ranges"))
+ port->gpio_ranges = true;
+ else
+ port->gpio_ranges = false;
+ port->gc.request = mxc_gpio_request;
+ port->gc.free = mxc_gpio_free;
+ port->gc.parent = &pdev->dev;
port->gc.to_irq = mxc_gpio_to_irq;
port->gc.base = (pdev->id < 0) ? of_alias_get_id(np, "gpio") * 32 :
pdev->id * 32;
@@ -494,14 +693,20 @@ static int mxc_gpio_probe(struct platform_device *pdev)
}
/* gpio-mxc can be a generic irq chip */
- err = mxc_gpio_init_gc(port, irq_base);
+ err = mxc_gpio_init_gc(port, irq_base, &pdev->dev);
if (err < 0)
goto out_irqdomain_remove;
list_add_tail(&port->node, &mxc_gpio_ports);
+ platform_set_drvdata(pdev, port);
+ pm_runtime_put(&pdev->dev);
+
return 0;
+out_pm_dis:
+ pm_runtime_disable(&pdev->dev);
+ clk_disable_unprepare(port->clk);
out_irqdomain_remove:
irq_domain_remove(port->domain);
out_bgio:
@@ -509,9 +714,166 @@ out_bgio:
return err;
}
+static void mxc_gpio_save_regs(struct mxc_gpio_port *port)
+{
+ unsigned long flags;
+
+ if (mxc_gpio_hwtype == IMX21_GPIO)
+ return;
+
+ spin_lock_irqsave(&port->gc.bgpio_lock, flags);
+ port->saved_reg[0] = readl(port->base + GPIO_ICR1);
+ port->saved_reg[1] = readl(port->base + GPIO_ICR2);
+ port->saved_reg[2] = readl(port->base + GPIO_IMR);
+ port->saved_reg[3] = readl(port->base + GPIO_GDIR);
+ port->saved_reg[4] = readl(port->base + GPIO_EDGE_SEL);
+ port->saved_reg[5] = readl(port->base + GPIO_DR);
+ spin_unlock_irqrestore(&port->gc.bgpio_lock, flags);
+}
+
+static void mxc_gpio_restore_regs(struct mxc_gpio_port *port)
+{
+ unsigned long flags;
+
+ if (mxc_gpio_hwtype == IMX21_GPIO)
+ return;
+
+ spin_lock_irqsave(&port->gc.bgpio_lock, flags);
+ writel(port->saved_reg[0], port->base + GPIO_ICR1);
+ writel(port->saved_reg[1], port->base + GPIO_ICR2);
+ writel(port->saved_reg[2], port->base + GPIO_IMR);
+ writel(port->saved_reg[3], port->base + GPIO_GDIR);
+ writel(port->saved_reg[4], port->base + GPIO_EDGE_SEL);
+ writel(port->saved_reg[5], port->base + GPIO_DR);
+ spin_unlock_irqrestore(&port->gc.bgpio_lock, flags);
+}
+
+static int __maybe_unused mxc_gpio_runtime_suspend(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct mxc_gpio_port *port = platform_get_drvdata(pdev);
+
+ mxc_gpio_save_regs(port);
+ clk_disable_unprepare(port->clk);
+
+ return 0;
+}
+
+static int __maybe_unused mxc_gpio_runtime_resume(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct mxc_gpio_port *port = platform_get_drvdata(pdev);
+ int ret;
+
+ ret = clk_prepare_enable(port->clk);
+ if (ret)
+ return ret;
+
+ mxc_gpio_restore_regs(port);
+
+ return 0;
+}
+
+static int __maybe_unused mxc_gpio_noirq_suspend(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct mxc_gpio_port *port = platform_get_drvdata(pdev);
+ unsigned long flags;
+ int ret;
+
+#ifdef CONFIG_GPIO_MXC_PAD_WAKEUP
+ mxc_gpio_set_pad_wakeup(port, true);
+#endif
+ if (mxc_gpio_hwtype == IMX21_GPIO)
+ return 0;
+
+ ret = clk_prepare_enable(port->clk);
+ if (ret)
+ return ret;
+
+ spin_lock_irqsave(&port->gc.bgpio_lock, flags);
+ port->suspend_saved_reg[0] = readl(port->base + GPIO_ICR1);
+ port->suspend_saved_reg[1] = readl(port->base + GPIO_ICR2);
+ port->suspend_saved_reg[3] = readl(port->base + GPIO_GDIR);
+ port->suspend_saved_reg[4] = readl(port->base + GPIO_EDGE_SEL);
+ port->suspend_saved_reg[5] = readl(port->base + GPIO_DR);
+ spin_unlock_irqrestore(&port->gc.bgpio_lock, flags);
+
+ clk_disable_unprepare(port->clk);
+
+ return 0;
+}
+
+static int __maybe_unused mxc_gpio_noirq_resume(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct mxc_gpio_port *port = platform_get_drvdata(pdev);
+ unsigned long flags;
+ int ret;
+#ifdef CONFIG_GPIO_MXC_PAD_WAKEUP
+ int wakeup_line = mxc_gpio_get_pad_wakeup(port);
+
+ mxc_gpio_set_pad_wakeup(port, false);
+#endif
+
+ if (mxc_gpio_hwtype == IMX21_GPIO)
+ return 0;
+
+ ret = clk_prepare_enable(port->clk);
+ if (ret)
+ return ret;
+
+ spin_lock_irqsave(&port->gc.bgpio_lock, flags);
+ writel(port->suspend_saved_reg[0], port->base + GPIO_ICR1);
+ writel(port->suspend_saved_reg[1], port->base + GPIO_ICR2);
+ writel(port->suspend_saved_reg[3], port->base + GPIO_GDIR);
+ writel(port->suspend_saved_reg[4], port->base + GPIO_EDGE_SEL);
+ writel(port->suspend_saved_reg[5], port->base + GPIO_DR);
+#ifdef CONFIG_GPIO_MXC_PAD_WAKEUP
+ if (wakeup_line >= 0)
+ mxc_gpio_handle_pad_wakeup(port, wakeup_line);
+#endif
+ spin_unlock_irqrestore(&port->gc.bgpio_lock, flags);
+ clk_disable_unprepare(port->clk);
+
+ return 0;
+}
+
+static int __maybe_unused mxc_gpio_suspend(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ int irq = platform_get_irq(pdev, 0);
+ struct irq_data *data = irq_get_irq_data(irq);
+
+ if (!irqd_is_wakeup_set(data))
+ return pm_runtime_force_suspend(dev);
+
+ return 0;
+}
+
+static int __maybe_unused mxc_gpio_resume(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ int irq = platform_get_irq(pdev, 0);
+ struct irq_data *data = irq_get_irq_data(irq);
+
+ if (!irqd_is_wakeup_set(data))
+ return pm_runtime_force_resume(dev);
+
+ return 0;
+}
+
+static const struct dev_pm_ops mxc_gpio_dev_pm_ops = {
+ SET_SYSTEM_SLEEP_PM_OPS(mxc_gpio_suspend, mxc_gpio_resume)
+ SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(mxc_gpio_noirq_suspend, mxc_gpio_noirq_resume)
+ SET_RUNTIME_PM_OPS(mxc_gpio_runtime_suspend,
+ mxc_gpio_runtime_resume, NULL)
+};
+
static struct platform_driver mxc_gpio_driver = {
.driver = {
.name = "gpio-mxc",
+ .pm = &mxc_gpio_dev_pm_ops,
.of_match_table = mxc_gpio_dt_ids,
.suppress_bind_attrs = true,
},
diff --git a/drivers/gpio/gpio-pca953x.c b/drivers/gpio/gpio-pca953x.c
index 1b9dbf691ae7..efa721d253ad 100644
--- a/drivers/gpio/gpio-pca953x.c
+++ b/drivers/gpio/gpio-pca953x.c
@@ -21,6 +21,7 @@
#include <linux/of_platform.h>
#include <linux/platform_data/pca953x.h>
#include <linux/regulator/consumer.h>
+#include <linux/reset.h>
#include <linux/slab.h>
#include <asm/unaligned.h>
@@ -845,6 +846,10 @@ static int pca953x_probe(struct i2c_client *client,
lockdep_set_subclass(&chip->i2c_lock,
i2c_adapter_depth(client->adapter));
+ ret = device_reset(&client->dev);
+ if (ret == -EPROBE_DEFER)
+ return -EPROBE_DEFER;
+
/* initialize cached registers from their original values.
* we can't share this chip with another i2c master.
*/
diff --git a/drivers/gpio/gpio-vf610.c b/drivers/gpio/gpio-vf610.c
index 3210fba16a9b..379bc36a5b0f 100644
--- a/drivers/gpio/gpio-vf610.c
+++ b/drivers/gpio/gpio-vf610.c
@@ -16,6 +16,7 @@
*/
#include <linux/bitops.h>
+#include <linux/clk.h>
#include <linux/err.h>
#include <linux/gpio.h>
#include <linux/init.h>
@@ -248,6 +249,7 @@ static int vf610_gpio_probe(struct platform_device *pdev)
&pdev->dev);
struct device *dev = &pdev->dev;
struct device_node *np = dev->of_node;
+ struct clk *clk_port, *clk_gpio;
struct vf610_gpio_port *port;
struct resource *iores;
struct gpio_chip *gc;
@@ -274,6 +276,23 @@ static int vf610_gpio_probe(struct platform_device *pdev)
if (port->irq < 0)
return port->irq;
+ clk_port = devm_clk_get(&pdev->dev, "port");
+ clk_gpio = devm_clk_get(&pdev->dev, "gpio");
+ if (PTR_ERR(clk_port) == -EPROBE_DEFER ||
+ PTR_ERR(clk_gpio) == -EPROBE_DEFER)
+ return -EPROBE_DEFER;
+
+ if (!IS_ERR(clk_port) && !IS_ERR(clk_gpio)) {
+ ret = clk_prepare_enable(clk_port);
+ if (ret)
+ return ret;
+ ret = clk_prepare_enable(clk_gpio);
+ if (ret) {
+ clk_disable_unprepare(clk_port);
+ return ret;
+ }
+ }
+
gc = &port->gc;
gc->of_node = np;
gc->parent = dev;
@@ -307,6 +326,14 @@ static int vf610_gpio_probe(struct platform_device *pdev)
/* Clear the interrupt status register for all GPIO's */
vf610_gpio_writel(~0, port->base + PORT_ISFR);
+ /*
+ * At imx7ulp, any interrupts can wake system up from "standby" mode,
+ * so, mask interrupt at suspend mode by default, and the user
+ * can still enable wakeup through /sys entry.
+ */
+ if (of_machine_is_compatible("fsl,imx7ulp"))
+ ic->flags = IRQCHIP_MASK_ON_SUSPEND;
+
ret = gpiochip_irqchip_add(gc, ic, 0, handle_edge_irq, IRQ_TYPE_NONE);
if (ret) {
dev_err(dev, "failed to add irqchip\n");
diff --git a/drivers/gpu/Makefile b/drivers/gpu/Makefile
index e9ed439a5b65..beaa25a03b9e 100644
--- a/drivers/gpu/Makefile
+++ b/drivers/gpu/Makefile
@@ -2,5 +2,5 @@
# 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 += imx/
obj-y += drm/ vga/
-obj-$(CONFIG_IMX_IPUV3_CORE) += ipu-v3/
diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index 83cb2a88c204..484e852162c9 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -148,6 +148,7 @@ config DRM_KMS_CMA_HELPER
config DRM_VM
bool
depends on DRM && MMU
+ default y
source "drivers/gpu/drm/i2c/Kconfig"
@@ -203,6 +204,12 @@ config DRM_VGEM
as used by Mesa's software renderer for enhanced performance.
If M is selected the module will be called vgem.
+config DRM_VIVANTE
+ tristate "Vivante GCCore"
+ depends on DRM
+ help
+ Choose this option if you have a Vivante graphics card.
+ If M is selected, the module will be called vivante.
source "drivers/gpu/drm/exynos/Kconfig"
diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index 8ce07039bb89..c5da7b5a5815 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -18,7 +18,7 @@ drm-y := drm_auth.o drm_bufs.o drm_cache.o \
drm_encoder.o drm_mode_object.o drm_property.o \
drm_plane.o drm_color_mgmt.o drm_print.o \
drm_dumb_buffers.o drm_mode_config.o drm_vblank.o \
- drm_syncobj.o
+ drm_syncobj.o drm_lease.o
drm-$(CONFIG_DRM_LIB_RANDOM) += lib/drm_random.o
drm-$(CONFIG_DRM_VM) += drm_vm.o
@@ -51,6 +51,7 @@ obj-$(CONFIG_DRM) += drm.o
obj-$(CONFIG_DRM_MIPI_DSI) += drm_mipi_dsi.o
obj-$(CONFIG_DRM_ARM) += arm/
obj-$(CONFIG_DRM_TTM) += ttm/
+obj-$(CONFIG_DRM_VIVANTE) += vivante/
obj-$(CONFIG_DRM_TDFX) += tdfx/
obj-$(CONFIG_DRM_R128) += r128/
obj-$(CONFIG_HSA_AMD) += amd/amdkfd/
@@ -87,13 +88,13 @@ obj-$(CONFIG_DRM_MSM) += msm/
obj-$(CONFIG_DRM_TEGRA) += tegra/
obj-$(CONFIG_DRM_STM) += stm/
obj-$(CONFIG_DRM_STI) += sti/
-obj-$(CONFIG_DRM_IMX) += imx/
obj-$(CONFIG_DRM_MEDIATEK) += mediatek/
obj-$(CONFIG_DRM_MESON) += meson/
obj-y += i2c/
obj-y += panel/
obj-y += bridge/
obj-$(CONFIG_DRM_FSL_DCU) += fsl-dcu/
+obj-$(CONFIG_DRM_IMX) += imx/
obj-$(CONFIG_DRM_ETNAVIV) += etnaviv/
obj-$(CONFIG_DRM_ARCPGU)+= arc/
obj-y += hisilicon/
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c
index 1eff36a87595..580d414a4692 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c
@@ -224,7 +224,7 @@ amdgpu_connector_update_scratch_regs(struct drm_connector *connector,
if (connector->encoder_ids[i] == 0)
break;
- encoder = drm_encoder_find(connector->dev,
+ encoder = drm_encoder_find(connector->dev, NULL,
connector->encoder_ids[i]);
if (!encoder)
continue;
@@ -249,7 +249,7 @@ amdgpu_connector_find_encoder(struct drm_connector *connector,
for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
if (connector->encoder_ids[i] == 0)
break;
- encoder = drm_encoder_find(connector->dev,
+ encoder = drm_encoder_find(connector->dev, NULL,
connector->encoder_ids[i]);
if (!encoder)
continue;
@@ -367,7 +367,7 @@ amdgpu_connector_best_single_encoder(struct drm_connector *connector)
/* pick the encoder ids */
if (enc_id)
- return drm_encoder_find(connector->dev, enc_id);
+ return drm_encoder_find(connector->dev, NULL, enc_id);
return NULL;
}
@@ -1084,7 +1084,7 @@ amdgpu_connector_dvi_detect(struct drm_connector *connector, bool force)
if (connector->encoder_ids[i] == 0)
break;
- encoder = drm_encoder_find(connector->dev, connector->encoder_ids[i]);
+ encoder = drm_encoder_find(connector->dev, NULL, connector->encoder_ids[i]);
if (!encoder)
continue;
@@ -1143,7 +1143,7 @@ amdgpu_connector_dvi_encoder(struct drm_connector *connector)
if (connector->encoder_ids[i] == 0)
break;
- encoder = drm_encoder_find(connector->dev, connector->encoder_ids[i]);
+ encoder = drm_encoder_find(connector->dev, NULL, connector->encoder_ids[i]);
if (!encoder)
continue;
@@ -1162,7 +1162,7 @@ amdgpu_connector_dvi_encoder(struct drm_connector *connector)
/* then check use digitial */
/* pick the first one */
if (enc_id)
- return drm_encoder_find(connector->dev, enc_id);
+ return drm_encoder_find(connector->dev, NULL, enc_id);
return NULL;
}
@@ -1303,7 +1303,7 @@ u16 amdgpu_connector_encoder_get_dp_bridge_encoder_id(struct drm_connector *conn
if (connector->encoder_ids[i] == 0)
break;
- encoder = drm_encoder_find(connector->dev,
+ encoder = drm_encoder_find(connector->dev, NULL,
connector->encoder_ids[i]);
if (!encoder)
continue;
@@ -1332,7 +1332,7 @@ static bool amdgpu_connector_encoder_is_hbr2(struct drm_connector *connector)
for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
if (connector->encoder_ids[i] == 0)
break;
- encoder = drm_encoder_find(connector->dev,
+ encoder = drm_encoder_find(connector->dev, NULL,
connector->encoder_ids[i]);
if (!encoder)
continue;
diff --git a/drivers/gpu/drm/amd/amdgpu/dce_virtual.c b/drivers/gpu/drm/amd/amdgpu/dce_virtual.c
index f3f93b6b51ef..39460eb1e71a 100644
--- a/drivers/gpu/drm/amd/amdgpu/dce_virtual.c
+++ b/drivers/gpu/drm/amd/amdgpu/dce_virtual.c
@@ -288,7 +288,7 @@ dce_virtual_encoder(struct drm_connector *connector)
if (connector->encoder_ids[i] == 0)
break;
- encoder = drm_encoder_find(connector->dev, connector->encoder_ids[i]);
+ encoder = drm_encoder_find(connector->dev, NULL, connector->encoder_ids[i]);
if (!encoder)
continue;
@@ -298,7 +298,7 @@ dce_virtual_encoder(struct drm_connector *connector)
/* pick the first one */
if (enc_id)
- return drm_encoder_find(connector->dev, enc_id);
+ return drm_encoder_find(connector->dev, NULL, enc_id);
return NULL;
}
diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c
index a09fafa27082..6ed2124925b5 100644
--- a/drivers/gpu/drm/ast/ast_mode.c
+++ b/drivers/gpu/drm/ast/ast_mode.c
@@ -715,7 +715,7 @@ static struct drm_encoder *ast_best_single_encoder(struct drm_connector *connect
int enc_id = connector->encoder_ids[0];
/* pick the encoder ids */
if (enc_id)
- return drm_encoder_find(connector->dev, enc_id);
+ return drm_encoder_find(connector->dev, NULL, enc_id);
return NULL;
}
diff --git a/drivers/gpu/drm/bochs/bochs_kms.c b/drivers/gpu/drm/bochs/bochs_kms.c
index 6a91e62da2f4..a24a18fbd65a 100644
--- a/drivers/gpu/drm/bochs/bochs_kms.c
+++ b/drivers/gpu/drm/bochs/bochs_kms.c
@@ -213,7 +213,7 @@ bochs_connector_best_encoder(struct drm_connector *connector)
int enc_id = connector->encoder_ids[0];
/* pick the encoder ids */
if (enc_id)
- return drm_encoder_find(connector->dev, enc_id);
+ return drm_encoder_find(connector->dev, NULL, enc_id);
return NULL;
}
diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig
index 85aa824317f0..58db4bbc7ab8 100644
--- a/drivers/gpu/drm/bridge/Kconfig
+++ b/drivers/gpu/drm/bridge/Kconfig
@@ -52,6 +52,26 @@ config DRM_MEGACHIPS_STDPXXXX_GE_B850V3_FW
to DP++. This is used with the i.MX6 imx-ldb
driver. You are likely to say N here.
+config DRM_NWL_DSI
+ tristate
+ select DRM_KMS_HELPER
+ select DRM_MIPI_DSI
+ select DRM_PANEL
+
+config DRM_SEC_MIPI_DSIM
+ tristate "Samsung MIPI DSIM Bridge"
+ depends on OF
+ select DRM_KMS_HELPER
+ select DRM_MIPI_DSI
+ select DRM_PANEL
+ help
+ The Samsung MPI DSIM Bridge driver.
+
+config DRM_NXP_SEIKO_43WVFIG
+ tristate "Legacy Freescale Seiko 43WVFIG panel DPI adapter bridge"
+ select DRM_KMS_HELPER
+ select DRM_PANEL
+
config DRM_NXP_PTN3460
tristate "NXP PTN3460 DP/LVDS bridge"
depends on OF
@@ -107,4 +127,12 @@ source "drivers/gpu/drm/bridge/adv7511/Kconfig"
source "drivers/gpu/drm/bridge/synopsys/Kconfig"
+config DRM_ITE_IT6263
+ tristate "ITE IT6263 LVDS/HDMI bridge"
+ depends on OF
+ select DRM_KMS_HELPER
+ select REGMAP_I2C
+ ---help---
+ ITE IT6263 bridge chip driver.
+
endmenu
diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makefile
index 60dab87e4783..d684dce13256 100644
--- a/drivers/gpu/drm/bridge/Makefile
+++ b/drivers/gpu/drm/bridge/Makefile
@@ -12,3 +12,7 @@ obj-$(CONFIG_DRM_ANALOGIX_DP) += analogix/
obj-$(CONFIG_DRM_I2C_ADV7511) += adv7511/
obj-$(CONFIG_DRM_TI_TFP410) += ti-tfp410.o
obj-y += synopsys/
+obj-$(CONFIG_DRM_ITE_IT6263) += it6263.o
+obj-$(CONFIG_DRM_NWL_DSI) += nwl-dsi.o
+obj-$(CONFIG_DRM_SEC_MIPI_DSIM) += sec-dsim.o
+obj-$(CONFIG_DRM_NXP_SEIKO_43WVFIG) += nxp-seiko-43wvfig.o
diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511.h b/drivers/gpu/drm/bridge/adv7511/adv7511.h
index fe18a5d2d84b..c7db7344026d 100644
--- a/drivers/gpu/drm/bridge/adv7511/adv7511.h
+++ b/drivers/gpu/drm/bridge/adv7511/adv7511.h
@@ -195,6 +195,10 @@
#define ADV7511_PACKET_GM(x) ADV7511_PACKET(5, x)
#define ADV7511_PACKET_SPARE(x) ADV7511_PACKET(6, x)
+#define FORMAT_RATIO(x, y) (((x) * 100) / (y))
+#define RATIO_16_9 FORMAT_RATIO(16, 9)
+#define RATIO_4_3 FORMAT_RATIO(4, 3)
+
enum adv7511_input_clock {
ADV7511_INPUT_CLOCK_1X,
ADV7511_INPUT_CLOCK_2X,
@@ -295,6 +299,7 @@ struct adv7511_video_config {
enum adv7511_type {
ADV7511,
ADV7533,
+ ADV7535,
};
struct adv7511 {
@@ -302,6 +307,10 @@ struct adv7511 {
struct i2c_client *i2c_edid;
struct i2c_client *i2c_cec;
+ u32 addr_cec;
+ u32 addr_edid;
+ u32 addr_pkt;
+
struct regmap *regmap;
struct regmap *regmap_cec;
enum drm_connector_status status;
@@ -339,6 +348,7 @@ struct adv7511 {
struct device_node *host_node;
struct mipi_dsi_device *dsi;
u8 num_dsi_lanes;
+ u8 channel_id;
bool use_timing_gen;
enum adv7511_type type;
@@ -348,7 +358,6 @@ struct adv7511 {
#ifdef CONFIG_DRM_I2C_ADV7533
void adv7533_dsi_power_on(struct adv7511 *adv);
void adv7533_dsi_power_off(struct adv7511 *adv);
-void adv7533_mode_set(struct adv7511 *adv, struct drm_display_mode *mode);
int adv7533_patch_registers(struct adv7511 *adv);
void adv7533_uninit_cec(struct adv7511 *adv);
int adv7533_init_cec(struct adv7511 *adv);
@@ -369,6 +378,12 @@ static inline void adv7533_mode_set(struct adv7511 *adv,
{
}
+static inline bool adv7533_mode_fixup(struct adv7511 *adv,
+ struct drm_display_mode *mode)
+{
+ return true;
+}
+
static inline int adv7533_patch_registers(struct adv7511 *adv)
{
return -ENODEV;
diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
index 3c94d838863e..e84d0ab42c54 100644
--- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
+++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
@@ -9,7 +9,9 @@
#include <linux/device.h>
#include <linux/gpio/consumer.h>
#include <linux/module.h>
+#include <linux/of.h>
#include <linux/of_device.h>
+#include <linux/of_graph.h>
#include <linux/slab.h>
#include <drm/drmP.h>
@@ -329,6 +331,7 @@ static void __adv7511_power_on(struct adv7511 *adv7511)
{
adv7511->current_edid_segment = -1;
+ /* 01-02 Power */
regmap_update_bits(adv7511->regmap, ADV7511_REG_POWER,
ADV7511_POWER_POWER_DOWN, 0);
if (adv7511->i2c_main->irq) {
@@ -344,6 +347,7 @@ static void __adv7511_power_on(struct adv7511 *adv7511)
}
/*
+ * 01-01 HPD Manual Override
* Per spec it is allowed to pulse the HPD signal to indicate that the
* EDID information has changed. Some monitors do this when they wakeup
* from standby or are enabled. When the HPD goes low the adv7511 is
@@ -365,7 +369,7 @@ static void adv7511_power_on(struct adv7511 *adv7511)
*/
regcache_sync(adv7511->regmap);
- if (adv7511->type == ADV7533)
+ if (adv7511->type == ADV7533 || adv7511->type == ADV7535)
adv7533_dsi_power_on(adv7511);
adv7511->powered = true;
}
@@ -382,7 +386,7 @@ static void __adv7511_power_off(struct adv7511 *adv7511)
static void adv7511_power_off(struct adv7511 *adv7511)
{
__adv7511_power_off(adv7511);
- if (adv7511->type == ADV7533)
+ if (adv7511->type == ADV7533 || adv7511->type == ADV7535)
adv7533_dsi_power_off(adv7511);
adv7511->powered = false;
}
@@ -412,17 +416,16 @@ static bool adv7511_hpd(struct adv7511 *adv7511)
static void adv7511_hpd_work(struct work_struct *work)
{
struct adv7511 *adv7511 = container_of(work, struct adv7511, hpd_work);
- enum drm_connector_status status;
+ enum drm_connector_status status = connector_status_disconnected;
unsigned int val;
int ret;
ret = regmap_read(adv7511->regmap, ADV7511_REG_STATUS, &val);
- if (ret < 0)
- status = connector_status_disconnected;
- else if (val & ADV7511_STATUS_HPD)
+ if (ret >= 0 && (val & ADV7511_STATUS_HPD))
status = connector_status_connected;
- else
- status = connector_status_disconnected;
+
+ DRM_DEV_DEBUG_DRIVER(adv7511->connector.kdev, "HDMI HPD event: %s\n",
+ drm_get_connector_status_name(status));
/*
* The bridge resets its registers on unplug. So when we get a plug
@@ -583,6 +586,8 @@ static int adv7511_get_modes(struct adv7511 *adv7511,
{
struct edid *edid;
unsigned int count;
+ u32 bus_format = MEDIA_BUS_FMT_RGB888_1X24;
+ int ret;
/* Reading the EDID only works if the device is powered */
if (!adv7511->powered) {
@@ -611,6 +616,14 @@ static int adv7511_get_modes(struct adv7511 *adv7511,
adv7511_set_config_csc(adv7511, connector, adv7511->rgb);
+ connector->display_info.bus_flags = DRM_BUS_FLAG_DE_LOW |
+ DRM_BUS_FLAG_PIXDATA_NEGEDGE;
+
+ ret = drm_display_info_set_bus_formats(&connector->display_info,
+ &bus_format, 1);
+ if (ret)
+ return ret;
+
return count;
}
@@ -744,14 +757,16 @@ static void adv7511_mode_set(struct adv7511 *adv7511,
else
low_refresh_rate = ADV7511_LOW_REFRESH_RATE_NONE;
- regmap_update_bits(adv7511->regmap, 0xfb,
- 0x6, low_refresh_rate << 1);
+ if (adv7511->type == ADV7535)
+ regmap_update_bits(adv7511->regmap, 0x4a,
+ 0xc, low_refresh_rate << 2);
+ else
+ regmap_update_bits(adv7511->regmap, 0xfb,
+ 0x6, low_refresh_rate << 1);
+
regmap_update_bits(adv7511->regmap, 0x17,
0x60, (vsync_polarity << 6) | (hsync_polarity << 5));
- if (adv7511->type == ADV7533)
- adv7533_mode_set(adv7511, adj_mode);
-
drm_mode_copy(&adv7511->curr_mode, adj_mode);
/*
@@ -858,7 +873,7 @@ static int adv7511_bridge_attach(struct drm_bridge *bridge)
&adv7511_connector_helper_funcs);
drm_mode_connector_attach_encoder(&adv->connector, bridge->encoder);
- if (adv->type == ADV7533)
+ if (adv->type == ADV7533 || adv->type == ADV7535)
ret = adv7533_attach_dsi(adv);
if (adv->i2c_main->irq)
@@ -1019,8 +1034,15 @@ static int adv7511_probe(struct i2c_client *i2c, const struct i2c_device_id *id)
struct adv7511_link_config link_config;
struct adv7511 *adv7511;
struct device *dev = &i2c->dev;
+#if IS_ENABLED(CONFIG_OF_DYNAMIC)
+ struct device_node *remote_node = NULL, *endpoint = NULL;
+ struct of_changeset ocs;
+ struct property *prop;
+#endif
unsigned int main_i2c_addr = i2c->addr << 1;
unsigned int edid_i2c_addr = main_i2c_addr + 4;
+ unsigned int cec_i2c_addr = main_i2c_addr - 2;
+ unsigned int pkt_i2c_addr = main_i2c_addr - 0xa;
unsigned int val;
int ret;
@@ -1055,6 +1077,21 @@ static int adv7511_probe(struct i2c_client *i2c, const struct i2c_device_id *id)
return ret;
}
+ if (adv7511->addr_cec != 0)
+ cec_i2c_addr = adv7511->addr_cec << 1;
+ else
+ adv7511->addr_cec = cec_i2c_addr >> 1;
+
+ if (adv7511->addr_edid != 0)
+ edid_i2c_addr = adv7511->addr_edid << 1;
+ else
+ adv7511->addr_edid = edid_i2c_addr >> 1;
+
+ if (adv7511->addr_pkt != 0)
+ pkt_i2c_addr = adv7511->addr_pkt << 1;
+ else
+ adv7511->addr_pkt = pkt_i2c_addr >> 1;
+
/*
* The power down GPIO is optional. If present, toggle it from active to
* inactive to wake up the encoder.
@@ -1090,11 +1127,12 @@ static int adv7511_probe(struct i2c_client *i2c, const struct i2c_device_id *id)
if (ret)
goto uninit_regulators;
- regmap_write(adv7511->regmap, ADV7511_REG_EDID_I2C_ADDR, edid_i2c_addr);
+ regmap_write(adv7511->regmap, ADV7511_REG_EDID_I2C_ADDR,
+ edid_i2c_addr);
regmap_write(adv7511->regmap, ADV7511_REG_PACKET_I2C_ADDR,
- main_i2c_addr - 0xa);
+ pkt_i2c_addr);
regmap_write(adv7511->regmap, ADV7511_REG_CEC_I2C_ADDR,
- main_i2c_addr - 2);
+ cec_i2c_addr);
adv7511_packet_disable(adv7511, 0xffff);
@@ -1104,7 +1142,7 @@ static int adv7511_probe(struct i2c_client *i2c, const struct i2c_device_id *id)
goto uninit_regulators;
}
- if (adv7511->type == ADV7533) {
+ if (adv7511->type == ADV7533 || adv7511->type == ADV7535) {
ret = adv7533_init_cec(adv7511);
if (ret)
goto err_i2c_unregister_edid;
@@ -1149,6 +1187,44 @@ err_i2c_unregister_edid:
i2c_unregister_device(adv7511->i2c_edid);
uninit_regulators:
adv7511_uninit_regulators(adv7511);
+#if IS_ENABLED(CONFIG_OF_DYNAMIC)
+ endpoint = of_graph_get_next_endpoint(dev->of_node, NULL);
+ if (endpoint)
+ remote_node = of_graph_get_remote_port_parent(endpoint);
+
+ if (remote_node) {
+ int num_endpoints = 0;
+
+ /*
+ * Remote node should have two endpoints (input and output: us)
+ * If remote node has more than two endpoints, probably that it
+ * has more outputs, so there is no need to disable it.
+ */
+ endpoint = NULL;
+ while ((endpoint = of_graph_get_next_endpoint(remote_node,
+ endpoint)))
+ num_endpoints++;
+
+ if (num_endpoints > 2) {
+ of_node_put(remote_node);
+ return ret;
+ }
+
+ prop = devm_kzalloc(dev, sizeof(*prop), GFP_KERNEL);
+ prop->name = devm_kstrdup(dev, "status", GFP_KERNEL);
+ prop->value = devm_kstrdup(dev, "disabled", GFP_KERNEL);
+ prop->length = 9;
+ of_changeset_init(&ocs);
+ of_changeset_update_property(&ocs, remote_node, prop);
+ ret = of_changeset_apply(&ocs);
+ if (!ret)
+ dev_warn(dev,
+ "Probe failed. Remote port '%s' disabled\n",
+ remote_node->full_name);
+
+ of_node_put(remote_node);
+ };
+#endif
return ret;
}
@@ -1157,7 +1233,7 @@ static int adv7511_remove(struct i2c_client *i2c)
{
struct adv7511 *adv7511 = i2c_get_clientdata(i2c);
- if (adv7511->type == ADV7533) {
+ if (adv7511->type == ADV7533 || adv7511->type == ADV7535) {
adv7533_detach_dsi(adv7511);
adv7533_uninit_cec(adv7511);
}
@@ -1168,9 +1244,10 @@ static int adv7511_remove(struct i2c_client *i2c)
adv7511_audio_exit(adv7511);
- i2c_unregister_device(adv7511->i2c_edid);
-
- kfree(adv7511->edid);
+ if (adv7511->i2c_edid) {
+ i2c_unregister_device(adv7511->i2c_edid);
+ kfree(adv7511->edid);
+ }
return 0;
}
@@ -1181,6 +1258,7 @@ static const struct i2c_device_id adv7511_i2c_ids[] = {
{ "adv7513", ADV7511 },
#ifdef CONFIG_DRM_I2C_ADV7533
{ "adv7533", ADV7533 },
+ { "adv7535", ADV7535 },
#endif
{ }
};
@@ -1192,6 +1270,7 @@ static const struct of_device_id adv7511_of_ids[] = {
{ .compatible = "adi,adv7513", .data = (void *)ADV7511 },
#ifdef CONFIG_DRM_I2C_ADV7533
{ .compatible = "adi,adv7533", .data = (void *)ADV7533 },
+ { .compatible = "adi,adv7535", .data = (void *)ADV7535 },
#endif
{ }
};
diff --git a/drivers/gpu/drm/bridge/adv7511/adv7533.c b/drivers/gpu/drm/bridge/adv7511/adv7533.c
index ac804f81e2f6..b03935ab9fa7 100644
--- a/drivers/gpu/drm/bridge/adv7511/adv7533.c
+++ b/drivers/gpu/drm/bridge/adv7511/adv7533.c
@@ -42,10 +42,8 @@ static const struct regmap_config adv7533_cec_regmap_config = {
static void adv7511_dsi_config_timing_gen(struct adv7511 *adv)
{
- struct mipi_dsi_device *dsi = adv->dsi;
struct drm_display_mode *mode = &adv->curr_mode;
unsigned int hsw, hfp, hbp, vsw, vfp, vbp;
- u8 clock_div_by_lanes[] = { 6, 4, 3 }; /* 2, 3, 4 lanes */
hsw = mode->hsync_end - mode->hsync_start;
hfp = mode->hsync_start - mode->hdisplay;
@@ -54,9 +52,10 @@ static void adv7511_dsi_config_timing_gen(struct adv7511 *adv)
vfp = mode->vsync_start - mode->vdisplay;
vbp = mode->vtotal - mode->vsync_end;
- /* set pixel clock divider mode */
- regmap_write(adv->regmap_cec, 0x16,
- clock_div_by_lanes[dsi->lanes - 2] << 3);
+ /* 03-01 Enable Internal Timing Generator */
+ regmap_write(adv->regmap_cec, 0x27, 0xcb);
+
+ /* 03-08 Timing Configuration */
/* horizontal porch params */
regmap_write(adv->regmap_cec, 0x28, mode->htotal >> 4);
@@ -77,35 +76,66 @@ static void adv7511_dsi_config_timing_gen(struct adv7511 *adv)
regmap_write(adv->regmap_cec, 0x35, (vfp << 4) & 0xff);
regmap_write(adv->regmap_cec, 0x36, vbp >> 4);
regmap_write(adv->regmap_cec, 0x37, (vbp << 4) & 0xff);
+
+ /* 03-03 Reset Internal Timing Generator */
+ regmap_write(adv->regmap_cec, 0x27, 0xcb);
+ regmap_write(adv->regmap_cec, 0x27, 0x8b);
+ regmap_write(adv->regmap_cec, 0x27, 0xcb);
+
}
void adv7533_dsi_power_on(struct adv7511 *adv)
{
struct mipi_dsi_device *dsi = adv->dsi;
+ struct drm_display_mode *mode = &adv->curr_mode;
+ u8 clock_div_by_lanes[] = { 6, 4, 3 }; /* 2, 3, 4 lanes */
- if (adv->use_timing_gen)
- adv7511_dsi_config_timing_gen(adv);
+ /* Gate DSI LP Oscillator */
+ regmap_update_bits(adv->regmap_cec, 0x03, 0x02, 0x00);
- /* set number of dsi lanes */
+ /* 01-03 Initialisation (Fixed) Registers */
+ regmap_register_patch(adv->regmap_cec, adv7533_cec_fixed_registers,
+ ARRAY_SIZE(adv7533_cec_fixed_registers));
+
+ /* 02-04 DSI Lanes */
regmap_write(adv->regmap_cec, 0x1c, dsi->lanes << 4);
- if (adv->use_timing_gen) {
- /* reset internal timing generator */
- regmap_write(adv->regmap_cec, 0x27, 0xcb);
- regmap_write(adv->regmap_cec, 0x27, 0x8b);
- regmap_write(adv->regmap_cec, 0x27, 0xcb);
- } else {
- /* disable internal timing generator */
+ /* 02-05 DSI Pixel Clock Divider */
+ regmap_write(adv->regmap_cec, 0x16,
+ clock_div_by_lanes[dsi->lanes - 2] << 3);
+
+ if (adv->use_timing_gen)
+ adv7511_dsi_config_timing_gen(adv);
+ else
regmap_write(adv->regmap_cec, 0x27, 0x0b);
- }
- /* enable hdmi */
+ /* 04-01 HDMI Output */
+ regmap_write(adv->regmap, 0xaf, 0x16);
+
+ /* 09-03 AVI Infoframe - RGB - 16-9 Aspect Ratio */
+ regmap_write(adv->regmap, ADV7511_REG_AVI_INFOFRAME(0), 0x10);
+ if (FORMAT_RATIO(mode->hdisplay, mode->vdisplay) == RATIO_16_9)
+ regmap_write(adv->regmap, ADV7511_REG_AVI_INFOFRAME(1), 0x28);
+ else if (FORMAT_RATIO(mode->hdisplay, mode->vdisplay) == RATIO_4_3)
+ regmap_write(adv->regmap, ADV7511_REG_AVI_INFOFRAME(1), 0x18);
+
+ /* 04-04 GC Packet Enable */
+ regmap_write(adv->regmap, ADV7511_REG_PACKET_ENABLE0, 0x80);
+
+ /* 04-06 GC Colour Depth - 24 Bit */
+ regmap_write(adv->regmap, 0x4c, 0x04);
+
+ /* 04-09 Down Dither Output Colour Depth - 8 Bit (default) */
+ regmap_write(adv->regmap, 0x49, 0x00);
+
+ /* 07-01 CEC Power Mode - Always Active */
+ regmap_write(adv->regmap_cec, 0xbe, 0x3d);
+
+ /* 04-03 HDMI Output Enable */
regmap_write(adv->regmap_cec, 0x03, 0x89);
/* disable test mode */
regmap_write(adv->regmap_cec, 0x55, 0x00);
- regmap_register_patch(adv->regmap_cec, adv7533_cec_fixed_registers,
- ARRAY_SIZE(adv7533_cec_fixed_registers));
}
void adv7533_dsi_power_off(struct adv7511 *adv)
@@ -116,28 +146,6 @@ void adv7533_dsi_power_off(struct adv7511 *adv)
regmap_write(adv->regmap_cec, 0x27, 0x0b);
}
-void adv7533_mode_set(struct adv7511 *adv, struct drm_display_mode *mode)
-{
- struct mipi_dsi_device *dsi = adv->dsi;
- int lanes, ret;
-
- if (adv->num_dsi_lanes != 4)
- return;
-
- if (mode->clock > 80000)
- lanes = 4;
- else
- lanes = 3;
-
- if (lanes != dsi->lanes) {
- mipi_dsi_detach(dsi);
- dsi->lanes = lanes;
- ret = mipi_dsi_attach(dsi);
- if (ret)
- dev_err(&dsi->dev, "failed to change host lanes\n");
- }
-}
-
int adv7533_patch_registers(struct adv7511 *adv)
{
return regmap_register_patch(adv->regmap,
@@ -155,7 +163,7 @@ int adv7533_init_cec(struct adv7511 *adv)
int ret;
adv->i2c_cec = i2c_new_dummy(adv->i2c_main->adapter,
- adv->i2c_main->addr - 1);
+ adv->addr_cec);
if (!adv->i2c_cec)
return -ENOMEM;
@@ -185,7 +193,7 @@ int adv7533_attach_dsi(struct adv7511 *adv)
struct mipi_dsi_device *dsi;
int ret = 0;
const struct mipi_dsi_device_info info = { .type = "adv7533",
- .channel = 0,
+ .channel = adv->channel_id,
.node = NULL,
};
@@ -231,14 +239,24 @@ void adv7533_detach_dsi(struct adv7511 *adv)
int adv7533_parse_dt(struct device_node *np, struct adv7511 *adv)
{
- u32 num_lanes;
+ struct device *dev = &adv->i2c_main->dev;
+ u32 num_lanes = 0, channel_id = 0;
+ of_property_read_u32(np, "adi,dsi-channel", &channel_id);
of_property_read_u32(np, "adi,dsi-lanes", &num_lanes);
- if (num_lanes < 1 || num_lanes > 4)
+ if (num_lanes < 1 || num_lanes > 4) {
+ dev_err(dev, "Invalid dsi-lanes: %d\n", num_lanes);
return -EINVAL;
+ }
+
+ if (channel_id > 3) {
+ dev_err(dev, "Invalid dsi-channel: %d\n", channel_id);
+ return -EINVAL;
+ }
adv->num_dsi_lanes = num_lanes;
+ adv->channel_id = channel_id;
adv->host_node = of_graph_get_remote_node(np, 0, 0);
if (!adv->host_node)
@@ -249,6 +267,10 @@ int adv7533_parse_dt(struct device_node *np, struct adv7511 *adv)
adv->use_timing_gen = !of_property_read_bool(np,
"adi,disable-timing-generator");
+ of_property_read_u32(np, "adi,addr-cec", &adv->addr_cec);
+ of_property_read_u32(np, "adi,addr-edid", &adv->addr_edid);
+ of_property_read_u32(np, "adi,addr-pkt", &adv->addr_pkt);
+
/* TODO: Check if these need to be parsed by DT or not */
adv->rgb = true;
adv->embedded_sync = false;
diff --git a/drivers/gpu/drm/bridge/it6263.c b/drivers/gpu/drm/bridge/it6263.c
new file mode 100644
index 000000000000..2bdafe2da555
--- /dev/null
+++ b/drivers/gpu/drm/bridge/it6263.c
@@ -0,0 +1,1024 @@
+/*
+ * Copyright 2017-2019 NXP
+ *
+ * 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 <drm/drmP.h>
+#include <drm/drm_atomic_helper.h>
+#include <drm/drm_crtc_helper.h>
+#include <drm/drm_edid.h>
+#include <linux/gpio/consumer.h>
+#include <linux/i2c.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_graph.h>
+#include <linux/regmap.h>
+
+#define REG_VENDOR_ID(n) (0x00 + (n)) /* n: 0/1 */
+#define REG_DEVICE_ID(n) (0x02 + (n)) /* n: 0/1 */
+#define LVDS_VENDER_ID_LOW 0x15
+#define LVDS_VENDER_ID_HIGH 0xCA
+#define LVDS_DEVICE_ID_LOW 0x61
+#define LVDS_DEVICE_ID_HIGH 0x62
+#define HDMI_VENDER_ID_LOW 0x01
+#define HDMI_VENDER_ID_HIGH 0xCA
+#define HDMI_DEVICE_ID_LOW 0x13
+#define HDMI_DEVICE_ID_HIGH 0x76
+
+/* LVDS registers */
+#define LVDS_REG_SW_RST 0x05
+#define SOFT_REFCLK_DM_RST BIT(0)
+#define SOFT_PCLK_DM_RST BIT(1)
+
+#define LVDS_REG_MODE 0x2C
+#define LVDS_COLOR_DEPTH 0x3
+enum {
+ LVDS_COLOR_DEPTH_18,
+ LVDS_COLOR_DEPTH_24,
+ LVDS_COLOR_DEPTH_30,
+ LVDS_COLOR_DEPTH_36,
+};
+#define LVDS_OUT_MAP BIT(4)
+#define VESA BIT(4)
+#define JEIDA 0
+#define DMODE BIT(7)
+#define SPLIT_MODE BIT(7)
+#define SINGLE_MODE 0
+
+#define LVDS_REG_STABLE 0x30
+#define VIDEO_STABLE BIT(0)
+#define PCLK_LOCK BIT(1)
+
+#define LVDS_REG_39 0x39
+
+#define LVDS_REG_PLL 0x3C
+#define LVDS_REG_AFE_3E 0x3E
+#define LVDS_REG_AFE_3F 0x3F
+#define LVDS_REG_AFE_47 0x47
+#define LVDS_REG_AFE_48 0x48
+#define LVDS_REG_AFE_4F 0x4F
+#define LVDS_REG_52 0x52
+#define LVDS_REG_PCLK_CNT_HIGH 0x57
+#define LVDS_REG_PCLK_CNT_LOW 0x58
+
+/*
+ * HDMI registers
+ *
+ * Registers are separated into three banks:
+ * 1) common bank: 0x00 ~ 0x2F
+ * 2) bank0: 0x30 ~ 0xFF
+ * 3) bank1: 0x130 ~ 0x1FF (HDMI packet registers)
+ *
+ * Use register HDMI_REG_BANK_CTRL @ 0x0F[1:0] to select bank0/1:
+ * 2b'00 - bank0
+ * 2b'01 - bank1
+ */
+
+/******************************/
+/* HDMI register common bank */
+/******************************/
+
+/* HDMI genernal registers */
+#define HDMI_REG_SW_RST 0x04
+#define SOFTREF_RST BIT(5)
+#define SOFTA_RST BIT(4)
+#define SOFTV_RST BIT(3)
+#define AUD_RST BIT(2)
+#define HDCP_RST BIT(0)
+#define HDMI_RST_ALL (SOFTREF_RST | SOFTA_RST | SOFTV_RST | \
+ AUD_RST | HDCP_RST)
+
+#define HDMI_REG_INT_CTRL 0x05
+#define INTPOL_ACTH BIT(7)
+#define INTPOL_ACTL 0
+#define INTIOMODE_OPENDRAIN BIT(6)
+#define INTIOMODE_PUSHPULL 0
+#define SELXTAL BIT(5) /* REFCLK <= XTALCLK */
+#define SELXTAL_QUARTER 0 /* REFCLK <= OSCCLK/4 */
+#define PDREFCNT(n) (((n) >> 2) << 2) /* REFCLK Div(n) */
+#define PDREFCLK BIT(1)
+#define PDTXCLK_GATED BIT(0)
+#define PDTXCLK_ACTIVE 0
+
+#define HDMI_REG_INT_STAT(n) (0x05 + (n)) /* n: 1/2/3 */
+#define HDMI_REG_INT_MASK(n) (0x08 + (n)) /* n: 1/2/3 */
+
+/* INT1 */
+#define INT_AUD_OVERFLOW BIT(7)
+#define INT_RDDC_NOACK BIT(5)
+#define INT_DDCFIFO_ERR BIT(4)
+#define INT_DDC_BUS_HANG BIT(2)
+#define INT_RX_SENSE BIT(1)
+#define INT_HPD BIT(0)
+
+/* INT2 */
+#define INT_VID_UNSTABLE BIT(6)
+#define INT_PKTACP BIT(5)
+#define INT_PKTNULL BIT(4)
+#define INT_PKTGEN BIT(3)
+#define INT_KSVLIST_CHK BIT(2)
+#define INT_AUTH_DONE BIT(1)
+#define INT_AUTH_FAIL BIT(0)
+
+/* INT3 */
+#define INT_AUD_CTS BIT(6)
+#define INT_VSYNC BIT(5)
+#define INT_VIDSTABLE BIT(4)
+#define INT_PKTMPG BIT(3)
+#define INT_PKTGBD BIT(2)
+#define INT_PKTAUD BIT(1)
+#define INT_PKTAVI BIT(0)
+
+#define INT_MASK_AUD_CTS BIT(5)
+#define INT_MASK_VSYNC BIT(4)
+#define INT_MASK_VIDSTABLE BIT(3)
+#define INT_MASK_PKTMPG BIT(2)
+#define INT_MASK_PKTGBD BIT(1)
+#define INT_MASK_PKTAUD BIT(0)
+
+#define HDMI_REG_INT_CLR(n) (0x0C + (n)) /* n: 0/1 */
+
+/* CLR0 */
+#define INT_CLR_PKTACP BIT(7)
+#define INT_CLR_PKTNULL BIT(6)
+#define INT_CLR_PKTGEN BIT(5)
+#define INT_CLR_KSVLIST_CHK BIT(4)
+#define INT_CLR_AUTH_DONE BIT(3)
+#define INT_CLR_AUTH_FAIL BIT(2)
+#define INT_CLR_RXSENSE BIT(1)
+#define INT_CLR_HPD BIT(0)
+
+/* CLR1 */
+#define INT_CLR_VSYNC BIT(7)
+#define INT_CLR_VIDSTABLE BIT(6)
+#define INT_CLR_PKTMPG BIT(5)
+#define INT_CLR_PKTGBD BIT(4)
+#define INT_CLR_PKTAUD BIT(3)
+#define INT_CLR_PKTAVI BIT(2)
+#define INT_CLR_VID_UNSTABLE BIT(0)
+
+#define HDMI_REG_SYS_STATUS 0x0E
+#define INT_ACTIVE BIT(7)
+#define HPDETECT BIT(6)
+#define RXSENDETECT BIT(5)
+#define TXVIDSTABLE BIT(4)
+#define CTSINTSTEP 0xC
+#define CLR_AUD_CTS BIT(1)
+#define INTACTDONE BIT(0)
+
+#define HDMI_REG_BANK_CTRL 0x0F
+#define BANK_SEL(n) ((n) ? 1 : 0)
+
+/* HDMI System DDC control registers */
+#define HDMI_REG_DDC_MASTER_CTRL 0x10
+#define MASTER_SEL_HOST BIT(0)
+#define MASTER_SEL_HDCP 0
+
+#define HDMI_REG_DDC_HEADER 0x11
+#define DDC_HDCP_ADDRESS 0x74
+
+#define HDMI_REG_DDC_REQOFF 0x12
+#define HDMI_REG_DDC_REQCOUNT 0x13
+#define HDMI_REG_DDC_EDIDSEG 0x14
+
+#define HDMI_REG_DDC_CMD 0x15
+#define DDC_CMD_SEQ_BURSTREAD 0x0
+#define DDC_CMD_LINK_CHKREAD 0x2
+#define DDC_CMD_EDID_READ 0x3
+#define DDC_CMD_FIFO_CLR 0x9
+#define DDC_CMD_GEN_SCLCLK 0xA
+#define DDC_CMD_ABORT 0xF
+
+#define HDMI_REG_DDC_STATUS 0x16
+#define DDC_DONE BIT(7)
+#define DDC_ACT BIT(6)
+#define DDC_NOACK BIT(5)
+#define DDC_WAITBUS BIT(4)
+#define DDC_ARBILOSE BIT(3)
+#define DDC_ERROR (DDC_NOACK | DDC_WAITBUS | DDC_ARBILOSE)
+#define DDC_FIFOFULL BIT(2)
+#define DDC_FIFOEMPTY BIT(1)
+
+#define HDMI_DDC_FIFO_SIZE 32 /* bytes */
+#define HDMI_REG_DDC_READFIFO 0x17
+#define HDMI_REG_ROM_STAT 0x1C
+#define HDMI_REG_LVDS_PORT 0x1D /* LVDS input ctrl i2c addr */
+#define HDMI_REG_LVDS_PORT_EN 0x1E /* and to enable */
+#define LVDS_INPUT_CTRL_I2C_ADDR 0x33
+
+/***********************/
+/* HDMI register bank0 */
+/***********************/
+
+/* HDMI clock control registers */
+#define HDMI_REG_CLK_CTRL1 0x59
+#define EN_TXCLK_COUNT BIT(5)
+#define VDO_LATCH_EDGE BIT(3)
+
+/* HDMI AFE registers */
+#define HDMI_REG_AFE_DRV_CTRL 0x61
+#define AFE_DRV_PWD BIT(5)
+#define AFE_DRV_RST BIT(4)
+#define AFE_DRV_PDRXDET BIT(2)
+#define AFE_DRV_TERMON BIT(1)
+#define AFE_DRV_ENCAL BIT(0)
+
+#define HDMI_REG_AFE_XP_CTRL 0x62
+#define AFE_XP_GAINBIT BIT(7)
+#define AFE_XP_PWDPLL BIT(6)
+#define AFE_XP_ENI BIT(5)
+#define AFE_XP_ER0 BIT(4)
+#define AFE_XP_RESETB BIT(3)
+#define AFE_XP_PWDI BIT(2)
+#define AFE_XP_DEI BIT(1)
+#define AFE_XP_DER BIT(0)
+
+#define HDMI_REG_AFE_ISW_CTRL 0x63
+#define AFE_RTERM_SEL BIT(7)
+#define AFE_IP_BYPASS BIT(6)
+#define AFE_DRV_ISW 0x38
+#define AFE_DRV_ISWK 7
+
+#define HDMI_REG_AFE_IP_CTRL 0x64
+#define AFE_IP_GAINBIT BIT(7)
+#define AFE_IP_PWDPLL BIT(6)
+#define AFE_IP_CKSEL 0x30
+#define AFE_IP_ER0 BIT(3)
+#define AFE_IP_RESETB BIT(2)
+#define AFE_IP_ENC BIT(1)
+#define AFE_IP_EC1 BIT(0)
+
+/* HDMI input data format registers */
+#define HDMI_REG_INPUT_MODE 0x70
+#define IN_RGB 0x00
+#define IN_YUV422 0x40
+#define IN_YUV444 0x80
+
+#define HDMI_REG_TXFIFO_RST 0x71
+#define ENAVMUTERST BIT(0)
+#define TXFFRST BIT(1)
+
+/* HDMI pattern generation SYNC/DE registers */
+#define HDMI_REG_9X(n) (0x90 + (n)) /* n: 0x0 ~ 0xF */
+#define HDMI_REG_AX(n) (0xA0 + (n)) /* n: 0x0 ~ 0xF */
+#define HDMI_REG_B0 0xB0
+
+/* HDMI general control registers */
+#define HDMI_REG_HDMI_MODE 0xC0
+#define TX_HDMI_MODE 1
+#define TX_DVI_MODE 0
+
+#define HDMI_REG_GCP 0xC1
+#define AVMUTE BIT(0)
+#define BLUE_SCR_MUTE BIT(1)
+#define NODEF_PHASE BIT(2)
+#define PHASE_RESYNC BIT(3)
+#define HDMI_COLOR_DEPTH 0x70
+enum {
+ HDMI_COLOR_DEPTH_DEF = 0x0, /* default as 24bit */
+ HDMI_COLOR_DEPTH_24 = 0x40,
+ HDMI_COLOR_DEPTH_30 = 0x50,
+ HDMI_COLOR_DEPTH_36 = 0x60,
+ HDMI_COLOR_DEPTH_48 = 0x70,
+};
+
+#define HDMI_REG_OESS_CYCLE 0xC3
+#define HDMI_REG_ENCRYPTION 0xC4 /* HDCP */
+
+#define HDMI_REG_PKT_SINGLE_CTRL 0xC5
+#define SINGLE_PKT BIT(0)
+#define BURST_PKT 0
+
+#define HDMI_REG_PKT_GENERAL_CTRL 0xC6
+#define HDMI_REG_NULL_CTRL 0xC9
+#define HDMI_REG_ACP_CTRL 0xCA
+#define HDMI_REG_ISRC1_CTRL 0xCB
+#define HDMI_REG_ISRC2_CTRL 0xCC
+#define HDMI_REG_AVI_INFOFRM_CTRL 0xCD
+#define HDMI_REG_AUD_INFOFRM_CTRL 0xCE
+#define HDMI_REG_SPD_INFOFRM_CTRL 0xCF
+#define HDMI_REG_MPG_INFOFRM_CTRL 0xD0
+#define ENABLE_PKT BIT(0)
+#define REPEAT_PKT BIT(1)
+
+/***********************/
+/* HDMI register bank1 */
+/***********************/
+
+/* AVI packet registers */
+#define HDMI_REG_AVI_DB1 0x58
+#define AVI_DB1_COLOR_SPACE 0x60
+enum {
+ AVI_COLOR_SPACE_RGB = 0x00,
+ AVI_COLOR_SPACE_YUV422 = 0x20,
+ AVI_COLOR_SPACE_YUV444 = 0x40,
+};
+
+struct it6263 {
+ struct i2c_client *hdmi_i2c;
+ struct i2c_client *lvds_i2c;
+ struct regmap *hdmi_regmap;
+ struct regmap *lvds_regmap;
+ struct drm_bridge bridge;
+ struct drm_connector connector;
+ struct gpio_desc *reset_gpio;
+ bool is_hdmi;
+ bool split_mode;
+};
+
+struct it6263_minimode {
+ int hdisplay;
+ int vdisplay;
+ int vrefresh;
+};
+
+static const struct it6263_minimode it6263_bad_mode_db[] = {
+ {1600, 900, 60},
+ {1280, 1024, 60},
+ {1280, 720, 30},
+ {1280, 720, 25},
+ {1280, 720, 24},
+ {1152, 864, 75},
+};
+
+static inline struct it6263 *bridge_to_it6263(struct drm_bridge *bridge)
+{
+ return container_of(bridge, struct it6263, bridge);
+}
+
+static inline struct it6263 *connector_to_it6263(struct drm_connector *con)
+{
+ return container_of(con, struct it6263, connector);
+}
+
+static inline void lvds_update_bits(struct it6263 *it6263, unsigned int reg,
+ unsigned int mask, unsigned int val)
+{
+ regmap_update_bits(it6263->lvds_regmap, reg, mask, val);
+}
+
+static inline void hdmi_update_bits(struct it6263 *it6263, unsigned int reg,
+ unsigned int mask, unsigned int val)
+{
+ regmap_update_bits(it6263->hdmi_regmap, reg, mask, val);
+}
+
+static void it6263_reset(struct it6263 *it6263)
+{
+ if (!it6263->reset_gpio)
+ return;
+
+ gpiod_set_value_cansleep(it6263->reset_gpio, 0);
+
+ usleep_range(1000, 2000);
+
+ gpiod_set_value_cansleep(it6263->reset_gpio, 1);
+
+ /*
+ * The chip maker says the low pulse should be at least 40ms,
+ * so 41ms is sure to be enough.
+ */
+ usleep_range(41000, 45000);
+
+ gpiod_set_value_cansleep(it6263->reset_gpio, 0);
+
+ /* somehow, addtional time to wait the high voltage to be stable */
+ usleep_range(5000, 6000);
+}
+
+static void it6263_lvds_reset(struct it6263 *it6263)
+{
+ /* AFE PLL reset */
+ lvds_update_bits(it6263, LVDS_REG_PLL, 0x1, 0x0);
+ usleep_range(1000, 2000);
+ lvds_update_bits(it6263, LVDS_REG_PLL, 0x1, 0x1);
+
+ /* pclk reset */
+ lvds_update_bits(it6263, LVDS_REG_SW_RST,
+ SOFT_PCLK_DM_RST, SOFT_PCLK_DM_RST);
+ usleep_range(1000, 2000);
+ lvds_update_bits(it6263, LVDS_REG_SW_RST, SOFT_PCLK_DM_RST, 0x0);
+
+ usleep_range(1000, 2000);
+}
+
+static void it6263_lvds_set_interface(struct it6263 *it6263)
+{
+ /* color depth */
+ lvds_update_bits(it6263, LVDS_REG_MODE, LVDS_COLOR_DEPTH,
+ LVDS_COLOR_DEPTH_24);
+
+ /* jeida mapping */
+ lvds_update_bits(it6263, LVDS_REG_MODE, LVDS_OUT_MAP, JEIDA);
+
+ if (it6263->split_mode) {
+ lvds_update_bits(it6263, LVDS_REG_MODE, DMODE, SPLIT_MODE);
+ lvds_update_bits(it6263, LVDS_REG_52, BIT(1), BIT(1));
+ } else {
+ lvds_update_bits(it6263, LVDS_REG_MODE, DMODE, SINGLE_MODE);
+ lvds_update_bits(it6263, LVDS_REG_52, BIT(1), 0);
+ }
+}
+
+static void it6263_lvds_set_afe(struct it6263 *it6263)
+{
+ struct regmap *regmap = it6263->lvds_regmap;
+
+ regmap_write(regmap, LVDS_REG_AFE_3E, 0xaa);
+ regmap_write(regmap, LVDS_REG_AFE_3F, 0x02);
+ regmap_write(regmap, LVDS_REG_AFE_47, 0xaa);
+ regmap_write(regmap, LVDS_REG_AFE_48, 0x02);
+ regmap_write(regmap, LVDS_REG_AFE_4F, 0x11);
+
+ lvds_update_bits(it6263, LVDS_REG_PLL, 0x07, 0);
+}
+
+static void it6263_lvds_config(struct it6263 *it6263)
+{
+ it6263_lvds_reset(it6263);
+ it6263_lvds_set_interface(it6263);
+ it6263_lvds_set_afe(it6263);
+}
+
+static void it6263_hdmi_config(struct it6263 *it6263)
+{
+ regmap_write(it6263->hdmi_regmap, HDMI_REG_INPUT_MODE, IN_RGB);
+
+ hdmi_update_bits(it6263, HDMI_REG_GCP, HDMI_COLOR_DEPTH,
+ HDMI_COLOR_DEPTH_24);
+}
+
+static enum drm_connector_status
+it6263_connector_detect(struct drm_connector *connector, bool force)
+{
+ struct it6263 *it6263 = connector_to_it6263(connector);
+ unsigned int status;
+ int i;
+
+ /*
+ * FIXME: We read status tens of times to workaround
+ * cable detection failure issue at boot time on some
+ * platforms.
+ * Spin on this for up to one second.
+ */
+ for (i = 0; i < 100; i++) {
+ regmap_read(it6263->hdmi_regmap, HDMI_REG_SYS_STATUS, &status);
+ if (status & HPDETECT)
+ return connector_status_connected;
+ usleep_range(5000, 10000);
+ }
+
+ return connector_status_disconnected;
+}
+
+static const struct drm_connector_funcs it6263_connector_funcs = {
+ .detect = it6263_connector_detect,
+ .fill_modes = drm_helper_probe_single_connector_modes,
+ .destroy = drm_connector_cleanup,
+ .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 int
+it6263_read_edid(void *data, u8 *buf, unsigned int block, size_t len)
+{
+ struct it6263 *it6263 = data;
+ struct regmap *regmap = it6263->hdmi_regmap;
+ unsigned long timeout;
+ unsigned int status, count, val;
+ unsigned int segment = block >> 1;
+ unsigned int start = (block % 2) * EDID_LENGTH;
+
+ regmap_write(regmap, HDMI_REG_DDC_MASTER_CTRL, MASTER_SEL_HOST);
+ regmap_write(regmap, HDMI_REG_DDC_HEADER, DDC_ADDR << 1);
+ regmap_write(regmap, HDMI_REG_DDC_EDIDSEG, segment);
+
+ while (len) {
+ /* clear DDC FIFO */
+ regmap_write(regmap, HDMI_REG_DDC_CMD, DDC_CMD_FIFO_CLR);
+
+ timeout = jiffies + msecs_to_jiffies(10);
+ do {
+ regmap_read(regmap, HDMI_REG_DDC_STATUS, &status);
+ } while (!(status & DDC_DONE) && time_before(jiffies, timeout));
+
+ if (!(status & DDC_DONE)) {
+ dev_err(&it6263->hdmi_i2c->dev,
+ "failed to clear DDC FIFO\n");
+ return -ETIMEDOUT;
+ }
+
+ count = len > HDMI_DDC_FIFO_SIZE ? HDMI_DDC_FIFO_SIZE : len;
+
+ /* fire the read command */
+ regmap_write(regmap, HDMI_REG_DDC_REQOFF, start);
+ regmap_write(regmap, HDMI_REG_DDC_REQCOUNT, count);
+ regmap_write(regmap, HDMI_REG_DDC_CMD, DDC_CMD_EDID_READ);
+
+ start += count;
+ len -= count;
+
+ /* wait for reading done */
+ timeout = jiffies + msecs_to_jiffies(250);
+ do {
+ regmap_read(regmap, HDMI_REG_DDC_STATUS, &status);
+ if (status & DDC_ERROR) {
+ dev_err(&it6263->hdmi_i2c->dev, "DDC error\n");
+ return -EIO;
+ }
+ } while (!(status & DDC_DONE) && time_before(jiffies, timeout));
+
+ if (!(status & DDC_DONE)) {
+ dev_err(&it6263->hdmi_i2c->dev,
+ "failed to read EDID\n");
+ return -ETIMEDOUT;
+ }
+
+ /* cache to buffer */
+ for (; count > 0; count--) {
+ regmap_read(regmap, HDMI_REG_DDC_READFIFO, &val);
+ *(buf++) = val;
+ }
+ }
+
+ return 0;
+}
+
+static int it6263_get_modes(struct drm_connector *connector)
+{
+ struct it6263 *it6263 = connector_to_it6263(connector);
+ struct regmap *regmap = it6263->hdmi_regmap;
+ u32 bus_format = MEDIA_BUS_FMT_RGB888_1X24;
+ struct edid *edid;
+ int num = 0;
+ int ret;
+
+ regmap_write(regmap, HDMI_REG_DDC_MASTER_CTRL, MASTER_SEL_HOST);
+
+ edid = drm_do_get_edid(connector, it6263_read_edid, it6263);
+ drm_mode_connector_update_edid_property(connector, edid);
+ if (edid) {
+ num = drm_add_edid_modes(connector, edid);
+ it6263->is_hdmi = drm_detect_hdmi_monitor(edid);
+ kfree(edid);
+ }
+
+ ret = drm_display_info_set_bus_formats(&connector->display_info,
+ &bus_format, 1);
+ if (ret)
+ return ret;
+
+ return num;
+}
+
+static enum drm_mode_status it6263_mode_valid(struct drm_connector *connector,
+ struct drm_display_mode *mode)
+{
+ const struct it6263_minimode *m;
+ int i, vrefresh = drm_mode_vrefresh(mode);
+
+ if (mode->clock > 150000)
+ return MODE_CLOCK_HIGH;
+
+ for (i = 0; i < ARRAY_SIZE(it6263_bad_mode_db); i++) {
+ m = &it6263_bad_mode_db[i];
+ if ((mode->hdisplay == m->hdisplay) &&
+ (mode->vdisplay == m->vdisplay) &&
+ (vrefresh == m->vrefresh))
+ return MODE_BAD;
+ }
+
+ return MODE_OK;
+}
+
+static const struct drm_connector_helper_funcs it6263_connector_helper_funcs = {
+ .get_modes = it6263_get_modes,
+ .mode_valid = it6263_mode_valid,
+};
+
+static void it6263_bridge_disable(struct drm_bridge *bridge)
+{
+ struct it6263 *it6263 = bridge_to_it6263(bridge);
+ struct regmap *regmap = it6263->hdmi_regmap;
+
+ /* AV mute */
+ hdmi_update_bits(it6263, HDMI_REG_GCP, AVMUTE, AVMUTE);
+
+ if (it6263->is_hdmi)
+ regmap_write(regmap, HDMI_REG_PKT_GENERAL_CTRL, 0);
+
+ hdmi_update_bits(it6263, HDMI_REG_SW_RST, SOFTV_RST, SOFTV_RST);
+ regmap_write(regmap, HDMI_REG_AFE_DRV_CTRL, AFE_DRV_RST | AFE_DRV_PWD);
+}
+
+static void it6263_bridge_enable(struct drm_bridge *bridge)
+{
+ struct it6263 *it6263 = bridge_to_it6263(bridge);
+ struct regmap *regmap = it6263->hdmi_regmap;
+ unsigned long timeout;
+ unsigned int status;
+ bool is_stable = false;
+ int i;
+
+ regmap_write(it6263->hdmi_regmap, HDMI_REG_BANK_CTRL, BANK_SEL(1));
+ /* set the color space to RGB in the AVI packet */
+ hdmi_update_bits(it6263, HDMI_REG_AVI_DB1, AVI_DB1_COLOR_SPACE,
+ AVI_COLOR_SPACE_RGB);
+ regmap_write(it6263->hdmi_regmap, HDMI_REG_BANK_CTRL, BANK_SEL(0));
+
+ /* software video reset */
+ hdmi_update_bits(it6263, HDMI_REG_SW_RST, SOFTV_RST, SOFTV_RST);
+ usleep_range(1000, 2000);
+ hdmi_update_bits(it6263, HDMI_REG_SW_RST, SOFTV_RST, 0);
+
+ /* reconfigure LVDS and retry several times in case video is instable */
+ for (i = 0; i < 3; i++) {
+ timeout = jiffies + msecs_to_jiffies(500);
+ do {
+ regmap_read(regmap, HDMI_REG_SYS_STATUS, &status);
+ } while (!(status & TXVIDSTABLE) &&
+ time_before(jiffies, timeout));
+
+ if (status & TXVIDSTABLE) {
+ is_stable = true;
+ break;
+ }
+
+ it6263_lvds_config(it6263);
+
+ dev_dbg(&it6263->hdmi_i2c->dev,
+ "retry to lock input video %d\n", i);
+ }
+
+ if (!is_stable)
+ dev_warn(&it6263->hdmi_i2c->dev,
+ "failed to wait for video stable\n");
+
+ regmap_write(regmap, HDMI_REG_AFE_DRV_CTRL, 0);
+
+ /* AV unmute */
+ hdmi_update_bits(it6263, HDMI_REG_GCP, AVMUTE, 0);
+
+ if (it6263->is_hdmi)
+ regmap_write(regmap, HDMI_REG_PKT_GENERAL_CTRL,
+ ENABLE_PKT | REPEAT_PKT);
+}
+
+static void it6263_bridge_mode_set(struct drm_bridge *bridge,
+ struct drm_display_mode *mode,
+ struct drm_display_mode *adj)
+{
+ struct it6263 *it6263 = bridge_to_it6263(bridge);
+ struct regmap *regmap = it6263->hdmi_regmap;
+ bool pclk_high = adj->clock > 80000 ? true : false;
+
+ regmap_write(regmap, HDMI_REG_HDMI_MODE,
+ it6263->is_hdmi ? TX_HDMI_MODE : TX_DVI_MODE);
+
+ dev_dbg(&it6263->hdmi_i2c->dev, "%s mode\n",
+ it6263->is_hdmi ? "HDMI" : "DVI");
+
+ /* setup AFE */
+ regmap_write(regmap, HDMI_REG_AFE_DRV_CTRL, AFE_DRV_RST);
+ if (pclk_high)
+ regmap_write(regmap, HDMI_REG_AFE_XP_CTRL,
+ AFE_XP_GAINBIT | AFE_XP_RESETB);
+ else
+ regmap_write(regmap, HDMI_REG_AFE_XP_CTRL,
+ AFE_XP_ER0 | AFE_XP_RESETB);
+ regmap_write(regmap, HDMI_REG_AFE_ISW_CTRL, 0x10);
+ if (pclk_high)
+ regmap_write(regmap, HDMI_REG_AFE_IP_CTRL,
+ AFE_IP_GAINBIT | AFE_IP_RESETB);
+ else
+ regmap_write(regmap, HDMI_REG_AFE_IP_CTRL,
+ AFE_IP_ER0 | AFE_IP_RESETB);
+}
+
+static int it6263_bridge_attach(struct drm_bridge *bridge)
+{
+ struct it6263 *it6263 = bridge_to_it6263(bridge);
+ struct drm_device *drm = bridge->dev;
+ int ret;
+
+ if (!drm_core_check_feature(drm, DRIVER_ATOMIC)) {
+ dev_err(&it6263->hdmi_i2c->dev,
+ "it6263 driver only copes with atomic updates\n");
+ return -ENOTSUPP;
+ }
+
+ it6263->connector.polled = DRM_CONNECTOR_POLL_CONNECT |
+ DRM_CONNECTOR_POLL_DISCONNECT;
+ ret = drm_connector_init(drm, &it6263->connector,
+ &it6263_connector_funcs,
+ DRM_MODE_CONNECTOR_HDMIA);
+ if (ret) {
+ dev_err(&it6263->hdmi_i2c->dev,
+ "Failed to initialize connector with drm\n");
+ return ret;
+ }
+
+ drm_connector_helper_add(&it6263->connector,
+ &it6263_connector_helper_funcs);
+ drm_mode_connector_attach_encoder(&it6263->connector, bridge->encoder);
+
+ return ret;
+}
+
+static const struct drm_bridge_funcs it6263_bridge_funcs = {
+ .attach = it6263_bridge_attach,
+ .mode_set = it6263_bridge_mode_set,
+ .disable = it6263_bridge_disable,
+ .enable = it6263_bridge_enable,
+};
+
+static int it6263_check_chipid(struct it6263 *it6263)
+{
+ struct device *dev = &it6263->hdmi_i2c->dev;
+ u8 vendor_id[2], device_id[2];
+ int ret;
+
+ ret = regmap_bulk_read(it6263->hdmi_regmap, REG_VENDOR_ID(0),
+ &vendor_id, 2);
+ if (ret) {
+ dev_err(dev, "regmap_bulk_read failed %d\n", ret);
+ return ret;
+ }
+
+ if (vendor_id[0] != HDMI_VENDER_ID_LOW ||
+ vendor_id[1] != HDMI_VENDER_ID_HIGH) {
+ dev_err(dev,
+ "Invalid hdmi vendor id %02x %02x(expect 0x01 0xca)\n",
+ vendor_id[0], vendor_id[1]);
+ return -EINVAL;
+ }
+
+ ret = regmap_bulk_read(it6263->hdmi_regmap, REG_DEVICE_ID(0),
+ &device_id, 2);
+ if (ret) {
+ dev_err(dev, "regmap_bulk_read failed %d\n", ret);
+ return ret;
+ }
+
+ if (device_id[0] != HDMI_DEVICE_ID_LOW ||
+ device_id[1] != HDMI_DEVICE_ID_HIGH) {
+ dev_err(dev,
+ "Invalid hdmi device id %02x %02x(expect 0x13 0x76)\n",
+ device_id[0], device_id[1]);
+ return -EINVAL;
+ }
+
+ ret = regmap_bulk_read(it6263->lvds_regmap, REG_VENDOR_ID(0),
+ &vendor_id, 2);
+ if (ret) {
+ dev_err(dev, "regmap_bulk_read failed %d\n", ret);
+ return ret;
+ }
+
+ if (vendor_id[0] != LVDS_VENDER_ID_LOW ||
+ vendor_id[1] != LVDS_VENDER_ID_HIGH) {
+ dev_err(dev,
+ "Invalid lvds vendor id %02x %02x(expect 0x15 0xca)\n",
+ vendor_id[0], vendor_id[1]);
+ return -EINVAL;
+ }
+
+ ret = regmap_bulk_read(it6263->lvds_regmap, REG_DEVICE_ID(0),
+ &device_id, 2);
+ if (ret) {
+ dev_err(dev, "regmap_bulk_read failed %d\n", ret);
+ return ret;
+ }
+
+ if (device_id[0] != LVDS_DEVICE_ID_LOW ||
+ device_id[1] != LVDS_DEVICE_ID_HIGH) {
+ dev_err(dev,
+ "Invalid lvds device id %02x %02x(expect 0x61 0x62)\n",
+ device_id[0], device_id[1]);
+ return -EINVAL;
+ }
+
+ return ret;
+}
+
+static const struct regmap_range it6263_hdmi_volatile_ranges[] = {
+ { .range_min = 0, .range_max = 0x1ff },
+};
+
+static const struct regmap_access_table it6263_hdmi_volatile_table = {
+ .yes_ranges = it6263_hdmi_volatile_ranges,
+ .n_yes_ranges = ARRAY_SIZE(it6263_hdmi_volatile_ranges),
+};
+
+static const struct regmap_config it6263_hdmi_regmap_config = {
+ .reg_bits = 8,
+ .val_bits = 8,
+ .volatile_table = &it6263_hdmi_volatile_table,
+ .cache_type = REGCACHE_NONE,
+};
+
+static const struct regmap_range it6263_lvds_volatile_ranges[] = {
+ { .range_min = 0, .range_max = 0xff },
+};
+
+static const struct regmap_access_table it6263_lvds_volatile_table = {
+ .yes_ranges = it6263_lvds_volatile_ranges,
+ .n_yes_ranges = ARRAY_SIZE(it6263_lvds_volatile_ranges),
+};
+
+static const struct regmap_config it6263_lvds_regmap_config = {
+ .reg_bits = 8,
+ .val_bits = 8,
+ .volatile_table = &it6263_lvds_volatile_table,
+ .cache_type = REGCACHE_NONE,
+};
+
+static int it6263_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct device *dev = &client->dev;
+ struct device_node *np = dev->of_node;
+#if IS_ENABLED(CONFIG_OF_DYNAMIC)
+ struct device_node *remote_node = NULL, *endpoint = NULL;
+ struct of_changeset ocs;
+ struct property *prop;
+#endif
+ struct it6263 *it6263;
+ int ret;
+
+ it6263 = devm_kzalloc(dev, sizeof(*it6263), GFP_KERNEL);
+ if (!it6263)
+ return -ENOMEM;
+
+ it6263->split_mode = of_property_read_bool(np, "split-mode");
+
+ it6263->hdmi_i2c = client;
+ it6263->lvds_i2c = i2c_new_dummy(client->adapter,
+ LVDS_INPUT_CTRL_I2C_ADDR);
+ if (!it6263->lvds_i2c) {
+ ret = -ENODEV;
+ goto of_reconfig;
+ }
+
+ it6263->hdmi_regmap = devm_regmap_init_i2c(client,
+ &it6263_hdmi_regmap_config);
+ if (IS_ERR(it6263->hdmi_regmap)) {
+ ret = PTR_ERR(it6263->hdmi_regmap);
+ goto unregister_lvds_i2c;
+ }
+
+ it6263->lvds_regmap = devm_regmap_init_i2c(it6263->lvds_i2c,
+ &it6263_lvds_regmap_config);
+ if (IS_ERR(it6263->lvds_regmap)) {
+ ret = PTR_ERR(it6263->lvds_regmap);
+ goto unregister_lvds_i2c;
+ }
+
+ it6263->reset_gpio = devm_gpiod_get_optional(dev, "reset",
+ GPIOD_OUT_LOW);
+ if (IS_ERR(it6263->reset_gpio)) {
+ ret = PTR_ERR(it6263->reset_gpio);
+
+ if (ret != -EPROBE_DEFER)
+ dev_err(dev, "Failed to get reset gpio: %d\n", ret);
+
+ goto unregister_lvds_i2c;
+ }
+
+ it6263_reset(it6263);
+
+ ret = regmap_write(it6263->hdmi_regmap, HDMI_REG_SW_RST, HDMI_RST_ALL);
+ if (ret)
+ goto unregister_lvds_i2c;
+
+ usleep_range(1000, 2000);
+
+ ret = regmap_write(it6263->hdmi_regmap, HDMI_REG_LVDS_PORT,
+ LVDS_INPUT_CTRL_I2C_ADDR << 1);
+ if (ret)
+ goto unregister_lvds_i2c;
+
+ ret = regmap_write(it6263->hdmi_regmap, HDMI_REG_LVDS_PORT_EN, 0x01);
+ if (ret)
+ goto unregister_lvds_i2c;
+
+ /* select HDMI bank0 */
+ ret = regmap_write(it6263->hdmi_regmap, HDMI_REG_BANK_CTRL,
+ BANK_SEL(0));
+ if (ret)
+ goto unregister_lvds_i2c;
+
+ ret = it6263_check_chipid(it6263);
+ if (ret)
+ goto unregister_lvds_i2c;
+
+ it6263_lvds_config(it6263);
+ it6263_hdmi_config(it6263);
+
+ it6263->bridge.funcs = &it6263_bridge_funcs;
+ it6263->bridge.of_node = np;
+ ret = drm_bridge_add(&it6263->bridge);
+ if (ret) {
+ dev_err(dev, "Failed to add drm_bridge\n");
+ return ret;
+ }
+
+ i2c_set_clientdata(client, it6263);
+
+ return ret;
+
+unregister_lvds_i2c:
+ i2c_unregister_device(it6263->lvds_i2c);
+ if (ret == -EPROBE_DEFER)
+ return ret;
+
+of_reconfig:
+#if IS_ENABLED(CONFIG_OF_DYNAMIC)
+ endpoint = of_graph_get_next_endpoint(dev->of_node, NULL);
+ if (endpoint)
+ remote_node = of_graph_get_remote_port_parent(endpoint);
+
+ if (remote_node) {
+ int num_endpoints = 0;
+
+ /*
+ * Remote node should have two endpoints (input and output: us)
+ * If remote node has more than two endpoints, probably that it
+ * has more outputs, so there is no need to disable it.
+ */
+ endpoint = NULL;
+ while ((endpoint = of_graph_get_next_endpoint(remote_node,
+ endpoint)))
+ num_endpoints++;
+
+ if (num_endpoints > 2) {
+ of_node_put(remote_node);
+ return ret;
+ }
+
+ prop = devm_kzalloc(dev, sizeof(*prop), GFP_KERNEL);
+ prop->name = devm_kstrdup(dev, "status", GFP_KERNEL);
+ prop->value = devm_kstrdup(dev, "disabled", GFP_KERNEL);
+ prop->length = 9;
+ of_changeset_init(&ocs);
+ of_changeset_update_property(&ocs, remote_node, prop);
+ ret = of_changeset_apply(&ocs);
+ if (!ret)
+ dev_warn(dev,
+ "Probe failed. Remote port '%s' disabled\n",
+ remote_node->full_name);
+
+ of_node_put(remote_node);
+ };
+#endif
+
+ return ret;
+}
+
+static int it6263_remove(struct i2c_client *client)
+
+{
+ struct it6263 *it6263 = i2c_get_clientdata(client);
+
+ drm_bridge_remove(&it6263->bridge);
+ i2c_unregister_device(it6263->lvds_i2c);
+
+ return 0;
+}
+
+static const struct of_device_id it6263_dt_ids[] = {
+ { .compatible = "ite,it6263", },
+ { }
+};
+MODULE_DEVICE_TABLE(of, it6263_dt_ids);
+
+static const struct i2c_device_id it6263_i2c_ids[] = {
+ { "it6263", 0 },
+ { },
+};
+MODULE_DEVICE_TABLE(i2c, it6263_i2c_ids);
+
+static struct i2c_driver it6263_driver = {
+ .probe = it6263_probe,
+ .remove = it6263_remove,
+ .driver = {
+ .name = "it6263",
+ .of_match_table = it6263_dt_ids,
+ },
+ .id_table = it6263_i2c_ids,
+};
+module_i2c_driver(it6263_driver);
+
+MODULE_AUTHOR("NXP Semiconductor");
+MODULE_DESCRIPTION("ITE Tech. Inc. IT6263 LVDS->HDMI bridge");
+MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/drm/bridge/nwl-dsi.c b/drivers/gpu/drm/bridge/nwl-dsi.c
new file mode 100644
index 000000000000..403228eaddce
--- /dev/null
+++ b/drivers/gpu/drm/bridge/nwl-dsi.c
@@ -0,0 +1,1426 @@
+/*
+ * NWL DSI drm driver - Northwest Logic MIPI DSI bridge
+ *
+ * Copyright (C) 2017 NXP
+ *
+ * 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 <asm/unaligned.h>
+#include <drm/bridge/nwl_dsi.h>
+#include <drm/drmP.h>
+#include <drm/drm_atomic_helper.h>
+#include <drm/drm_crtc_helper.h>
+#include <drm/drm_of.h>
+#include <drm/drm_panel.h>
+#include <linux/clk-provider.h>
+#include <linux/clk.h>
+#include <linux/component.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/of.h>
+#include <linux/of_graph.h>
+#include <linux/of_platform.h>
+#include <linux/phy/phy.h>
+#include <linux/phy/phy-mixel-mipi-dsi.h>
+#include <linux/spinlock.h>
+#include <video/mipi_display.h>
+#include <video/videomode.h>
+
+#define MIPI_FIFO_TIMEOUT msecs_to_jiffies(500)
+
+/* DSI HOST registers */
+#define CFG_NUM_LANES 0x0
+#define CFG_NONCONTINUOUS_CLK 0x4
+#define CFG_T_PRE 0x8
+#define CFG_T_POST 0xc
+#define CFG_TX_GAP 0x10
+#define CFG_AUTOINSERT_EOTP 0x14
+#define CFG_EXTRA_CMDS_AFTER_EOTP 0x18
+#define CFG_HTX_TO_COUNT 0x1c
+#define CFG_LRX_H_TO_COUNT 0x20
+#define CFG_BTA_H_TO_COUNT 0x24
+#define CFG_TWAKEUP 0x28
+#define CFG_STATUS_OUT 0x2c
+#define RX_ERROR_STATUS 0x30
+
+/* DSI DPI registers */
+#define PIXEL_PAYLOAD_SIZE 0x200
+#define PIXEL_FIFO_SEND_LEVEL 0x204
+#define INTERFACE_COLOR_CODING 0x208
+#define PIXEL_FORMAT 0x20c
+#define VSYNC_POLARITY 0x210
+#define HSYNC_POLARITY 0x214
+#define VIDEO_MODE 0x218
+#define HFP 0x21c
+#define HBP 0x220
+#define HSA 0x224
+#define ENABLE_MULT_PKTS 0x228
+#define VBP 0x22c
+#define VFP 0x230
+#define BLLP_MODE 0x234
+#define USE_NULL_PKT_BLLP 0x238
+#define VACTIVE 0x23c
+#define VC 0x240
+
+/* DSI APB PKT control */
+#define TX_PAYLOAD 0x280
+#define PKT_CONTROL 0x284
+#define SEND_PACKET 0x288
+#define PKT_STATUS 0x28c
+#define PKT_FIFO_WR_LEVEL 0x290
+#define PKT_FIFO_RD_LEVEL 0x294
+#define RX_PAYLOAD 0x298
+#define RX_PKT_HEADER 0x29c
+
+/* PKT reg bit manipulation */
+#define REG_MASK(e, s) (((1 << ((e) - (s) + 1)) - 1) << (s))
+#define REG_PUT(x, e, s) (((x) << (s)) & REG_MASK(e, s))
+#define REG_GET(x, e, s) (((x) & REG_MASK(e, s)) >> (s))
+
+/*
+ * PKT_CONTROL format:
+ * [15: 0] - word count
+ * [17:16] - virtual channel
+ * [23:18] - data type
+ * [24] - LP or HS select (0 - LP, 1 - HS)
+ * [25] - perform BTA after packet is sent
+ * [26] - perform BTA only, no packet tx
+ */
+#define WC(x) REG_PUT((x), 15, 0)
+#define TX_VC(x) REG_PUT((x), 17, 16)
+#define TX_DT(x) REG_PUT((x), 23, 18)
+#define HS_SEL(x) REG_PUT((x), 24, 24)
+#define BTA_TX(x) REG_PUT((x), 25, 25)
+#define BTA_NO_TX(x) REG_PUT((x), 26, 26)
+
+/*
+ * RX_PKT_HEADER format:
+ * [15: 0] - word count
+ * [21:16] - data type
+ * [23:22] - virtual channel
+ */
+#define RX_DT(x) REG_GET((x), 21, 16)
+#define RX_VC(x) REG_GET((x), 23, 22)
+
+/* DSI IRQ handling */
+#define IRQ_STATUS 0x2a0
+#define SM_NOT_IDLE BIT(0)
+#define TX_PKT_DONE BIT(1)
+#define DPHY_DIRECTION BIT(2)
+#define TX_FIFO_OVFLW BIT(3)
+#define TX_FIFO_UDFLW BIT(4)
+#define RX_FIFO_OVFLW BIT(5)
+#define RX_FIFO_UDFLW BIT(6)
+#define RX_PKT_HDR_RCVD BIT(7)
+#define RX_PKT_PAYLOAD_DATA_RCVD BIT(8)
+#define BTA_TIMEOUT BIT(29)
+#define LP_RX_TIMEOUT BIT(30)
+#define HS_TX_TIMEOUT BIT(31)
+
+#define IRQ_STATUS2 0x2a4
+#define SINGLE_BIT_ECC_ERR BIT(0)
+#define MULTI_BIT_ECC_ERR BIT(1)
+#define CRC_ERR BIT(2)
+
+#define IRQ_MASK 0x2a8
+#define SM_NOT_IDLE_MASK BIT(0)
+#define TX_PKT_DONE_MASK BIT(1)
+#define DPHY_DIRECTION_MASK BIT(2)
+#define TX_FIFO_OVFLW_MASK BIT(3)
+#define TX_FIFO_UDFLW_MASK BIT(4)
+#define RX_FIFO_OVFLW_MASK BIT(5)
+#define RX_FIFO_UDFLW_MASK BIT(6)
+#define RX_PKT_HDR_RCVD_MASK BIT(7)
+#define RX_PKT_PAYLOAD_DATA_RCVD_MASK BIT(8)
+#define BTA_TIMEOUT_MASK BIT(29)
+#define LP_RX_TIMEOUT_MASK BIT(30)
+#define HS_TX_TIMEOUT_MASK BIT(31)
+
+#define IRQ_MASK2 0x2ac
+#define SINGLE_BIT_ECC_ERR_MASK BIT(0)
+#define MULTI_BIT_ECC_ERR_MASK BIT(1)
+#define CRC_ERR_MASK BIT(2)
+
+static const char IRQ_NAME[] = "nwl-dsi";
+
+/*
+ * TODO: Currently, filter-out unsupported modes by their clocks.
+ * Need to find a better way to do this.
+ * These are the pixel clocks that the controller can handle successfully.
+ */
+static int valid_clocks[] = {
+ 162000,
+ 148500,
+ 135000,
+ 132000,
+ 108000,
+ 74250,
+ 49500,
+ 31500,
+};
+
+/* Possible valid PHY reference clock rates*/
+static u32 phyref_rates[] = {
+ 27000000,
+ 25000000,
+ 24000000,
+};
+
+enum {
+ CLK_PHY_REF = BIT(1),
+ CLK_RX_ESC = BIT(2),
+ CLK_TX_ESC = BIT(3)
+};
+
+enum transfer_direction {
+ DSI_PACKET_SEND,
+ DSI_PACKET_RECEIVE
+};
+
+struct mipi_dsi_transfer {
+ const struct mipi_dsi_msg *msg;
+ struct mipi_dsi_packet packet;
+ struct completion completed;
+
+ int status; /* status of transmission */
+ enum transfer_direction direction;
+ bool need_bta;
+ u8 cmd;
+ u16 rx_word_count;
+ size_t tx_len; /* bytes sent */
+ size_t rx_len; /* bytes received */
+};
+
+struct clk_config {
+ struct clk *clk;
+ unsigned long rate;
+ bool enabled;
+};
+
+struct mode_config {
+ int pixclock;
+ unsigned int lanes;
+ unsigned long bitclock;
+ u32 phyref_rate;
+ struct list_head list;
+};
+
+struct nwl_mipi_dsi {
+ struct device *dev;
+ struct drm_panel *panel;
+ struct drm_bridge *next_bridge;
+ struct drm_bridge bridge;
+ struct drm_connector connector;
+ struct mipi_dsi_host host;
+ struct mipi_dsi_device *dsi_device;
+
+ struct phy *phy;
+
+ /* Mandatory clocks */
+ struct clk_config phy_ref;
+ struct clk_config rx_esc;
+ struct clk_config tx_esc;
+
+ void __iomem *base;
+ int irq;
+
+ struct mipi_dsi_transfer *xfer;
+
+ struct drm_display_mode *curr_mode;
+ struct list_head valid_modes;
+ u32 lanes;
+ bool no_clk_reset;
+ bool enabled;
+};
+
+static inline void nwl_dsi_write(struct nwl_mipi_dsi *dsi, u32 reg, u32 val)
+{
+ writel(val, dsi->base + reg);
+}
+
+static inline u32 nwl_dsi_read(struct nwl_mipi_dsi *dsi, u32 reg)
+{
+ return readl(dsi->base + reg);
+}
+
+static enum mipi_dsi_pixel_format mipi_dsi_format_from_bus_format(
+ u32 bus_format)
+{
+ switch (bus_format) {
+ case MEDIA_BUS_FMT_RGB565_1X16:
+ return MIPI_DSI_FMT_RGB565;
+ case MEDIA_BUS_FMT_RGB666_1X18:
+ return MIPI_DSI_FMT_RGB666;
+ case MEDIA_BUS_FMT_RGB888_1X24:
+ return MIPI_DSI_FMT_RGB888;
+ default:
+ return MIPI_DSI_FMT_RGB888;
+ }
+}
+
+static enum dpi_interface_color_coding nwl_dsi_get_dpi_interface_color_coding(
+ enum mipi_dsi_pixel_format format)
+{
+ switch (format) {
+ case MIPI_DSI_FMT_RGB565:
+ return DPI_16_BIT_565_PACKED;
+ case MIPI_DSI_FMT_RGB666:
+ return DPI_18_BIT_ALIGNED;
+ case MIPI_DSI_FMT_RGB666_PACKED:
+ return DPI_18_BIT_PACKED;
+ case MIPI_DSI_FMT_RGB888:
+ return DPI_24_BIT;
+ default:
+ return DPI_24_BIT;
+ }
+}
+
+static enum dpi_pixel_format nwl_dsi_get_dpi_pixel_format(
+ enum mipi_dsi_pixel_format format)
+{
+ switch (format) {
+ case MIPI_DSI_FMT_RGB565:
+ return DPI_FMT_16_BIT;
+ case MIPI_DSI_FMT_RGB666:
+ return DPI_FMT_18_BIT;
+ case MIPI_DSI_FMT_RGB666_PACKED:
+ return DPI_FMT_18_BIT_LOOSELY_PACKED;
+ case MIPI_DSI_FMT_RGB888:
+ return DPI_FMT_24_BIT;
+ default:
+ return DPI_FMT_24_BIT;
+ }
+}
+
+static unsigned long nwl_dsi_get_bit_clock(struct nwl_mipi_dsi *dsi,
+ unsigned long pixclock)
+{
+ struct mipi_dsi_device *dsi_device = dsi->dsi_device;
+ int bpp;
+ u32 bus_fmt;
+ struct drm_crtc *crtc = 0;
+
+ if (dsi_device->lanes < 1 || dsi_device->lanes > 4)
+ return 0;
+
+ /* if CTRC updated the bus format, update dsi->format */
+ if (dsi->bridge.encoder)
+ crtc = dsi->bridge.encoder->crtc;
+ if (crtc && crtc->mode.private_flags & 0x1) {
+ bus_fmt = (crtc->mode.private_flags & 0x1FFFE) >> 1;
+ /* propagate the format to the attached panel/bridge */
+ dsi_device->format = mipi_dsi_format_from_bus_format(bus_fmt);
+ /* clear bus format change indication*/
+ crtc->mode.private_flags &= ~0x1;
+ }
+
+ bpp = mipi_dsi_pixel_format_to_bpp(dsi_device->format);
+
+ return (pixclock * bpp) / dsi_device->lanes;
+}
+
+static void nwl_dsi_config_host(struct nwl_mipi_dsi *dsi)
+{
+ struct mipi_dsi_device *dsi_device = dsi->dsi_device;
+
+ if (dsi_device->lanes < 1 || dsi_device->lanes > 4)
+ return;
+
+ nwl_dsi_write(dsi, CFG_NUM_LANES, dsi_device->lanes - 1);
+
+ if (dsi_device->mode_flags & MIPI_DSI_CLOCK_NON_CONTINUOUS)
+ nwl_dsi_write(dsi, CFG_NONCONTINUOUS_CLK, 0x01);
+ else
+ nwl_dsi_write(dsi, CFG_NONCONTINUOUS_CLK, 0x00);
+
+ if (dsi_device->mode_flags & MIPI_DSI_MODE_EOT_PACKET)
+ nwl_dsi_write(dsi, CFG_AUTOINSERT_EOTP, 0x00);
+ else
+ nwl_dsi_write(dsi, CFG_AUTOINSERT_EOTP, 0x01);
+
+ nwl_dsi_write(dsi, CFG_T_PRE, 0x01);
+ nwl_dsi_write(dsi, CFG_T_POST, 0x34);
+ nwl_dsi_write(dsi, CFG_TX_GAP, 0x0D);
+ nwl_dsi_write(dsi, CFG_EXTRA_CMDS_AFTER_EOTP, 0x00);
+ nwl_dsi_write(dsi, CFG_HTX_TO_COUNT, 0x00);
+ nwl_dsi_write(dsi, CFG_LRX_H_TO_COUNT, 0x00);
+ nwl_dsi_write(dsi, CFG_BTA_H_TO_COUNT, 0x00);
+ nwl_dsi_write(dsi, CFG_TWAKEUP, 0x3a98);
+}
+
+static void nwl_dsi_config_dpi(struct nwl_mipi_dsi *dsi)
+{
+ struct device *dev = dsi->dev;
+ struct mipi_dsi_device *dsi_device = dsi->dsi_device;
+ struct videomode vm;
+ enum dpi_pixel_format pixel_format =
+ nwl_dsi_get_dpi_pixel_format(dsi_device->format);
+ enum dpi_interface_color_coding color_coding =
+ nwl_dsi_get_dpi_interface_color_coding(dsi_device->format);
+ bool burst_mode;
+
+ drm_display_mode_to_videomode(dsi->curr_mode, &vm);
+
+ nwl_dsi_write(dsi, INTERFACE_COLOR_CODING, color_coding);
+ nwl_dsi_write(dsi, PIXEL_FORMAT, pixel_format);
+ DRM_DEV_DEBUG_DRIVER(dev, "DSI format is: %d (CC=%d, PF=%d)\n",
+ dsi_device->format, color_coding, pixel_format);
+
+ /*TODO: need to make polarity configurable */
+ nwl_dsi_write(dsi, VSYNC_POLARITY, 0x00);
+ nwl_dsi_write(dsi, HSYNC_POLARITY, 0x00);
+
+ burst_mode = (dsi_device->mode_flags & MIPI_DSI_MODE_VIDEO_BURST) &&
+ !(dsi_device->mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE);
+
+ if (burst_mode) {
+ nwl_dsi_write(dsi, VIDEO_MODE, 0x2);
+ nwl_dsi_write(dsi, PIXEL_FIFO_SEND_LEVEL, 256);
+ } else {
+ nwl_dsi_write(dsi, VIDEO_MODE, 0x0);
+ nwl_dsi_write(dsi, PIXEL_FIFO_SEND_LEVEL, vm.hactive);
+ }
+
+ nwl_dsi_write(dsi, HFP, vm.hfront_porch);
+ nwl_dsi_write(dsi, HBP, vm.hback_porch);
+ nwl_dsi_write(dsi, HSA, vm.hsync_len);
+
+ nwl_dsi_write(dsi, ENABLE_MULT_PKTS, 0x0);
+ nwl_dsi_write(dsi, BLLP_MODE, 0x1);
+ nwl_dsi_write(dsi, ENABLE_MULT_PKTS, 0x0);
+ nwl_dsi_write(dsi, USE_NULL_PKT_BLLP, 0x0);
+ nwl_dsi_write(dsi, VC, 0x0);
+
+ nwl_dsi_write(dsi, PIXEL_PAYLOAD_SIZE, vm.hactive);
+ nwl_dsi_write(dsi, VACTIVE, vm.vactive);
+ nwl_dsi_write(dsi, VBP, vm.vback_porch);
+ nwl_dsi_write(dsi, VFP, vm.vfront_porch);
+}
+
+static void nwl_dsi_enable_clocks(struct nwl_mipi_dsi *dsi, u32 clks)
+{
+ struct device *dev = dsi->dev;
+ unsigned long rate;
+
+ if (clks & CLK_PHY_REF && !dsi->phy_ref.enabled) {
+ clk_prepare_enable(dsi->phy_ref.clk);
+ dsi->phy_ref.enabled = true;
+ rate = clk_get_rate(dsi->phy_ref.clk);
+ DRM_DEV_DEBUG_DRIVER(dev,
+ "Enabled phy_ref clk (rate=%lu)\n", rate);
+ }
+
+ if (clks & CLK_RX_ESC && !dsi->rx_esc.enabled) {
+ clk_set_rate(dsi->rx_esc.clk, dsi->rx_esc.rate);
+ clk_prepare_enable(dsi->rx_esc.clk);
+ dsi->rx_esc.enabled = true;
+ rate = clk_get_rate(dsi->rx_esc.clk);
+ }
+
+ if (clks & CLK_TX_ESC && !dsi->tx_esc.enabled) {
+ clk_set_rate(dsi->tx_esc.clk, dsi->tx_esc.rate);
+ clk_prepare_enable(dsi->tx_esc.clk);
+ dsi->tx_esc.enabled = true;
+ rate = clk_get_rate(dsi->tx_esc.clk);
+ DRM_DEV_DEBUG_DRIVER(dev,
+ "Enabled tx_esc clk (rate=%lu)\n", rate);
+ }
+}
+
+static void nwl_dsi_disable_clocks(struct nwl_mipi_dsi *dsi, u32 clks)
+{
+ struct device *dev = dsi->dev;
+
+ if (clks & CLK_PHY_REF && dsi->phy_ref.enabled) {
+ clk_disable_unprepare(dsi->phy_ref.clk);
+ dsi->phy_ref.enabled = false;
+ DRM_DEV_DEBUG_DRIVER(dev, "Disabled phy_ref clk\n");
+ }
+
+ if (clks & CLK_RX_ESC && dsi->rx_esc.enabled) {
+ clk_disable_unprepare(dsi->rx_esc.clk);
+ dsi->rx_esc.enabled = false;
+ }
+
+ if (clks & CLK_TX_ESC && dsi->tx_esc.enabled) {
+ clk_disable_unprepare(dsi->tx_esc.clk);
+ dsi->tx_esc.enabled = false;
+ DRM_DEV_DEBUG_DRIVER(dev, "Disabled tx_esc clk\n");
+ }
+
+}
+
+static void nwl_dsi_init_interrupts(struct nwl_mipi_dsi *dsi)
+{
+ u32 irq_enable;
+
+ nwl_dsi_write(dsi, IRQ_MASK, 0xffffffff);
+ nwl_dsi_write(dsi, IRQ_MASK2, 0x7);
+
+ irq_enable = ~(u32)(TX_PKT_DONE_MASK |
+ RX_PKT_HDR_RCVD_MASK);
+
+ nwl_dsi_write(dsi, IRQ_MASK, irq_enable);
+}
+
+/*
+ * This function will try the required phy speed for current mode
+ * If the phy speed can be achieved, the phy will save the speed
+ * configuration
+ */
+static struct mode_config *nwl_dsi_mode_probe(struct nwl_mipi_dsi *dsi,
+ const struct drm_display_mode *mode)
+{
+ struct device *dev = dsi->dev;
+ struct mode_config *config;
+ unsigned long pixclock = mode->clock * 1000;
+ unsigned long bit_clk = 0;
+ u32 phyref_rate = 0, lanes = dsi->lanes;
+ size_t i = 0, num_rates = ARRAY_SIZE(phyref_rates);
+ int ret = 0;
+
+ list_for_each_entry(config, &dsi->valid_modes, list)
+ if (config->pixclock == pixclock)
+ return config;
+
+ while (i < num_rates) {
+ bit_clk = nwl_dsi_get_bit_clock(dsi, pixclock);
+ phyref_rate = phyref_rates[i];
+ ret = mixel_phy_mipi_set_phy_speed(dsi->phy,
+ bit_clk,
+ phyref_rate,
+ false);
+
+ /* Pick the first non-failing rate */
+ if (!ret)
+ break;
+
+ /* Reached the end of phyref_rates, try another lane config */
+ if ((i++ == num_rates - 1) && (--lanes > 1)) {
+ i = 0;
+ continue;
+ }
+ }
+
+ if (ret < 0) {
+ DRM_DEV_DEBUG_DRIVER(dev,
+ "Cannot setup PHY for mode: %ux%u @%d kHz\n",
+ mode->hdisplay,
+ mode->vdisplay,
+ mode->clock);
+ DRM_DEV_DEBUG_DRIVER(dev, "phy_ref clk: %u, bit clk: %lu\n",
+ phyref_rate, bit_clk);
+
+ return NULL;
+ }
+
+ config = devm_kzalloc(dsi->dev, sizeof(struct mode_config), GFP_KERNEL);
+ config->pixclock = pixclock;
+ config->lanes = lanes;
+ config->bitclock = bit_clk;
+ config->phyref_rate = phyref_rate;
+ list_add(&config->list, &dsi->valid_modes);
+
+ return config;
+}
+
+static enum drm_mode_status nwl_dsi_bridge_mode_valid(struct drm_bridge *bridge,
+ const struct drm_display_mode *mode)
+{
+ struct nwl_mipi_dsi *dsi = bridge->driver_private;
+ size_t i, num_modes = ARRAY_SIZE(valid_clocks);
+ bool clock_ok = false;
+
+ DRM_DEV_DEBUG_DRIVER(dsi->dev, "Validating mode:");
+ drm_mode_debug_printmodeline(mode);
+
+ for (i = 0; i < num_modes; i++)
+ if (mode->clock == valid_clocks[i]) {
+ clock_ok = true;
+ break;
+ }
+
+ if (!clock_ok)
+ return MODE_NOCLOCK;
+
+ if (!nwl_dsi_mode_probe(dsi, mode))
+ return MODE_NOCLOCK;
+
+ return MODE_OK;
+}
+
+static bool nwl_dsi_bridge_mode_fixup(struct drm_bridge *bridge,
+ const struct drm_display_mode *mode,
+ struct drm_display_mode *adjusted)
+{
+ struct nwl_mipi_dsi *dsi = bridge->driver_private;
+ struct mode_config *config;
+
+ DRM_DEV_DEBUG_DRIVER(dsi->dev, "Fixup mode:\n");
+ drm_mode_debug_printmodeline(adjusted);
+
+ config = nwl_dsi_mode_probe(dsi, adjusted);
+ if (!config)
+ return false;
+
+ DRM_DEV_DEBUG_DRIVER(dsi->dev, "lanes=%u, data_rate=%lu\n",
+ config->lanes, config->bitclock);
+ if (config->lanes < 1 || config->lanes > 4)
+ return false;
+
+ /* Max data rate for this controller is 1.5Gbps */
+ if (config->bitclock > 1500000000)
+ return false;
+
+ return true;
+}
+
+static void nwl_dsi_bridge_mode_set(struct drm_bridge *bridge,
+ struct drm_display_mode *mode,
+ struct drm_display_mode *adjusted)
+{
+ struct nwl_mipi_dsi *dsi = bridge->driver_private;
+ struct mode_config *config;
+ u32 actual_phy_rate;
+
+ DRM_DEV_DEBUG_DRIVER(dsi->dev, "Setting mode:\n");
+ drm_mode_debug_printmodeline(adjusted);
+
+ config = nwl_dsi_mode_probe(dsi, adjusted);
+ /* New mode? This should NOT happen */
+ if (!config) {
+ DRM_DEV_ERROR(dsi->dev, "Unsupported mode provided:\n");
+ drm_mode_debug_printmodeline(adjusted);
+ return;
+ }
+
+ mixel_phy_mipi_set_phy_speed(dsi->phy,
+ config->bitclock,
+ config->phyref_rate,
+ false);
+ clk_set_rate(dsi->phy_ref.clk, config->phyref_rate);
+ actual_phy_rate = clk_get_rate(dsi->phy_ref.clk);
+ dsi->dsi_device->lanes = config->lanes;
+ DRM_DEV_DEBUG_DRIVER(dsi->dev,
+ "Using phy_ref rate: %u (actual: %u), "
+ "bitclock: %lu, lanes: %u\n",
+ config->phyref_rate, actual_phy_rate,
+ config->bitclock, config->lanes);
+
+ dsi->curr_mode = drm_mode_duplicate(bridge->dev, adjusted);
+}
+
+static int nwl_dsi_host_attach(struct mipi_dsi_host *host,
+ struct mipi_dsi_device *device)
+{
+ struct nwl_mipi_dsi *dsi = container_of(host,
+ struct nwl_mipi_dsi,
+ host);
+ struct device *dev = dsi->dev;
+
+ DRM_DEV_INFO(dev, "lanes=%u, format=0x%x flags=0x%lx\n",
+ device->lanes, device->format, device->mode_flags);
+
+ if (device->lanes < 1 || device->lanes > 4)
+ return -EINVAL;
+
+ /*
+ * Someone has attached to us; it could be a panel or another bridge.
+ * Check to is if this is a panel or not.
+ */
+ if (!dsi->next_bridge ||
+ device->dev.of_node != dsi->next_bridge->of_node)
+ dsi->panel = of_drm_find_panel(device->dev.of_node);
+
+ /*
+ * Bridge has priority in front of panel.
+ * Since the panel driver cannot tell if there is a physical
+ * panel connected, we'll asume that there is no physical panel if there
+ * is a bridge registered.
+ */
+ if (dsi->next_bridge &&
+ device->dev.of_node != NULL &&
+ device->dev.of_node != dsi->next_bridge->of_node) {
+ dsi->panel = NULL;
+ return -EPERM;
+ }
+
+ if (dsi->panel)
+ DRM_DEV_DEBUG_DRIVER(dsi->dev, "Panel attached\n");
+ else
+ DRM_DEV_DEBUG_DRIVER(dsi->dev, "Bridge attached\n");
+
+ dsi->dsi_device = device;
+ dsi->lanes = device->lanes;
+
+ /*
+ * If this happened right before a mode_set, it means that our
+ * bridge/panel doesn't like the current mode parameters and changed
+ * something on the dsi_device (lanes or format). In this case, we have
+ * to reconfigure the phy.
+ */
+ if (dsi->curr_mode) {
+ unsigned long pixclock = dsi->curr_mode->clock * 1000;
+ struct mode_config *config;
+
+ DRM_DEV_DEBUG_DRIVER(dsi->dev, "Re-setting mode:\n");
+ drm_mode_debug_printmodeline(dsi->curr_mode);
+ drm_mode_destroy(dsi->bridge.dev, dsi->curr_mode);
+ list_for_each_entry(config, &dsi->valid_modes, list)
+ if (config->pixclock == pixclock)
+ break;
+
+ if (device->lanes != config->lanes)
+ return 0;
+
+ clk_set_rate(dsi->phy_ref.clk, config->phyref_rate);
+ device->lanes = config->lanes;
+ DRM_DEV_DEBUG_DRIVER(dsi->dev,
+ "Using phy_ref rate: %d (actual: %ld), "
+ "bitclock: %lu, lanes: %d\n",
+ config->phyref_rate, clk_get_rate(dsi->phy_ref.clk),
+ config->bitclock, config->lanes);
+ }
+
+ if (dsi->connector.dev)
+ drm_helper_hpd_irq_event(dsi->connector.dev);
+
+ return 0;
+}
+
+static int nwl_dsi_host_detach(struct mipi_dsi_host *host,
+ struct mipi_dsi_device *device)
+{
+ struct nwl_mipi_dsi *dsi = container_of(host,
+ struct nwl_mipi_dsi,
+ host);
+ if (dsi->panel)
+ dsi->panel = NULL;
+
+ if (dsi->connector.dev)
+ drm_helper_hpd_irq_event(dsi->connector.dev);
+
+ dsi->dsi_device = NULL;
+
+ return 0;
+}
+
+static void nwl_dsi_print_error(struct device *dev, u16 error)
+{
+ DRM_DEV_DEBUG_DRIVER(dev, "DSI Error Register (detailed report):\n");
+ if (error & BIT(0))
+ DRM_DEV_DEBUG_DRIVER(dev,
+ "SoT Error\n");
+ if (error & BIT(1))
+ DRM_DEV_DEBUG_DRIVER(dev,
+ "SoT Sync Error\n");
+ if (error & BIT(2))
+ DRM_DEV_DEBUG_DRIVER(dev,
+ "EoT Sync Error\n");
+ if (error & BIT(3))
+ DRM_DEV_DEBUG_DRIVER(dev,
+ "Escape Mode Entry Command Error\n");
+ if (error & BIT(4))
+ DRM_DEV_DEBUG_DRIVER(dev,
+ "Low-Power Transmit Sync Error\n");
+ if (error & BIT(5))
+ DRM_DEV_DEBUG_DRIVER(dev,
+ "Peripheral Timeout Error\n");
+ if (error & BIT(6))
+ DRM_DEV_DEBUG_DRIVER(dev,
+ "False Control Error\n");
+ if (error & BIT(7))
+ DRM_DEV_DEBUG_DRIVER(dev,
+ "Contention Detected\n");
+ if (error & BIT(8))
+ DRM_DEV_DEBUG_DRIVER(dev,
+ "ECC Error, single-bit (detected and corrected)\n");
+ if (error & BIT(9))
+ DRM_DEV_DEBUG_DRIVER(dev,
+ "ECC Error, multi-bit (detected, not corrected)\n");
+ if (error & BIT(10))
+ DRM_DEV_DEBUG_DRIVER(dev,
+ "Checksum Error (long packet only)\n");
+ if (error & BIT(11))
+ DRM_DEV_DEBUG_DRIVER(dev,
+ "DSI Data Type Not Recognized\n");
+ if (error & BIT(12))
+ DRM_DEV_DEBUG_DRIVER(dev,
+ "DSI VC ID Invalid\n");
+ if (error & BIT(13))
+ DRM_DEV_DEBUG_DRIVER(dev,
+ "Invalid Transmission Length\n");
+ /* BIT(14) is reserved */
+ if (error & BIT(15))
+ DRM_DEV_DEBUG_DRIVER(dev,
+ "DSI Protocol Violation\n");
+}
+
+static bool nwl_dsi_read_packet(struct nwl_mipi_dsi *dsi, u32 status)
+{
+ struct device *dev = dsi->dev;
+ struct mipi_dsi_transfer *xfer = dsi->xfer;
+ u8 *payload = xfer->msg->rx_buf;
+ u32 val;
+ u16 word_count;
+ u8 channel;
+ u8 data_type;
+
+ xfer->status = 0;
+
+ if (xfer->rx_word_count == 0) {
+ if (!(status & RX_PKT_HDR_RCVD))
+ return false;
+ /* Get the RX header and parse it */
+ val = nwl_dsi_read(dsi, RX_PKT_HEADER);
+ word_count = WC(val);
+ channel = RX_VC(val);
+ data_type = RX_DT(val);
+
+ if (channel != xfer->msg->channel) {
+ DRM_DEV_ERROR(dev,
+ "[%02X] Channel missmatch (%u != %u)\n",
+ xfer->cmd, channel, xfer->msg->channel);
+ return true;
+ }
+
+ switch (data_type) {
+ case MIPI_DSI_RX_GENERIC_SHORT_READ_RESPONSE_2BYTE:
+ /* Fall through */
+ case MIPI_DSI_RX_DCS_SHORT_READ_RESPONSE_2BYTE:
+ if (xfer->msg->rx_len > 1) {
+ /* read second byte */
+ payload[1] = word_count >> 8;
+ ++xfer->rx_len;
+ }
+ /* Fall through */
+ case MIPI_DSI_RX_GENERIC_SHORT_READ_RESPONSE_1BYTE:
+ /* Fall through */
+ case MIPI_DSI_RX_DCS_SHORT_READ_RESPONSE_1BYTE:
+ if (xfer->msg->rx_len > 0) {
+ /* read first byte */
+ payload[0] = word_count & 0xff;
+ ++xfer->rx_len;
+ }
+ xfer->status = xfer->rx_len;
+ return true;
+ case MIPI_DSI_RX_ACKNOWLEDGE_AND_ERROR_REPORT:
+ word_count &= 0xff;
+ DRM_DEV_ERROR(dev,
+ "[%02X] DSI error report: 0x%02x\n",
+ xfer->cmd, word_count);
+ nwl_dsi_print_error(dev, word_count);
+ xfer->status = -EPROTO;
+ return true;
+
+ }
+
+ if (word_count > xfer->msg->rx_len) {
+ DRM_DEV_ERROR(dev,
+ "[%02X] Receive buffer too small: %lu (< %u)\n",
+ xfer->cmd,
+ xfer->msg->rx_len,
+ word_count);
+ return true;
+ }
+
+ xfer->rx_word_count = word_count;
+ } else {
+ /* Set word_count from previous header read */
+ word_count = xfer->rx_word_count;
+ }
+
+ /* If RX payload is not yet received, wait for it */
+ if (!(status & RX_PKT_PAYLOAD_DATA_RCVD))
+ return false;
+
+ /* Read the RX payload */
+ while (word_count >= 4) {
+ val = nwl_dsi_read(dsi, RX_PAYLOAD);
+ payload[0] = (val >> 0) & 0xff;
+ payload[1] = (val >> 8) & 0xff;
+ payload[2] = (val >> 16) & 0xff;
+ payload[3] = (val >> 24) & 0xff;
+ payload += 4;
+ xfer->rx_len += 4;
+ word_count -= 4;
+ }
+
+ if (word_count > 0) {
+ val = nwl_dsi_read(dsi, RX_PAYLOAD);
+ switch (word_count) {
+ case 3:
+ payload[2] = (val >> 16) & 0xff;
+ ++xfer->rx_len;
+ /* Fall through */
+ case 2:
+ payload[1] = (val >> 8) & 0xff;
+ ++xfer->rx_len;
+ /* Fall through */
+ case 1:
+ payload[0] = (val >> 0) & 0xff;
+ ++xfer->rx_len;
+ break;
+ }
+ }
+
+ xfer->status = xfer->rx_len;
+
+ return true;
+}
+
+static void nwl_dsi_finish_transmission(struct nwl_mipi_dsi *dsi, u32 status)
+{
+ struct mipi_dsi_transfer *xfer = dsi->xfer;
+ bool end_packet = false;
+
+ if (!xfer)
+ return;
+
+ if (xfer->direction == DSI_PACKET_SEND && status & TX_PKT_DONE) {
+ xfer->status = xfer->tx_len;
+ end_packet = true;
+ } else if (status & DPHY_DIRECTION && status & RX_PKT_HDR_RCVD)
+ end_packet = nwl_dsi_read_packet(dsi, status);
+
+ if (end_packet)
+ complete(&xfer->completed);
+}
+
+static void nwl_dsi_begin_transmission(struct nwl_mipi_dsi *dsi)
+{
+ struct mipi_dsi_transfer *xfer = dsi->xfer;
+ struct mipi_dsi_packet *pkt = &xfer->packet;
+ const u8 *payload;
+ size_t length;
+ u16 word_count;
+ u8 lp_mode;
+ u32 val;
+
+ /* Send the payload, if any */
+ /* TODO: Need to check the TX FIFO overflow */
+ length = pkt->payload_length;
+ payload = pkt->payload;
+
+ while (length >= 4) {
+ val = get_unaligned_le32(payload);
+ nwl_dsi_write(dsi, TX_PAYLOAD, val);
+ payload += 4;
+ length -= 4;
+ }
+ /* Send the rest of the payload */
+ val = 0;
+ switch (length) {
+ case 3:
+ val |= payload[2] << 16;
+ /* Fall through */
+ case 2:
+ val |= payload[1] << 8;
+ /* Fall through */
+ case 1:
+ val |= payload[0];
+ nwl_dsi_write(dsi, TX_PAYLOAD, val);
+ break;
+ }
+ xfer->tx_len = length;
+
+ /*
+ * Now, send the header
+ * header structure is:
+ * header[0] = Virtual Channel + Data Type
+ * header[1] = Word Count LSB
+ * header[2] = Word Count MSB
+ */
+ word_count = pkt->header[1] | (pkt->header[2] << 8);
+ lp_mode = (xfer->msg->flags & MIPI_DSI_MSG_USE_LPM)?0:1;
+ val = WC(word_count) |
+ TX_VC(xfer->msg->channel) |
+ TX_DT(xfer->msg->type) |
+ HS_SEL(lp_mode) |
+ BTA_TX(xfer->need_bta);
+ nwl_dsi_write(dsi, PKT_CONTROL, val);
+
+ /* Send packet command */
+ nwl_dsi_write(dsi, SEND_PACKET, 0x1);
+}
+
+static ssize_t nwl_dsi_host_transfer(struct mipi_dsi_host *host,
+ const struct mipi_dsi_msg *msg)
+{
+ struct nwl_mipi_dsi *dsi = container_of(host,
+ struct nwl_mipi_dsi,
+ host);
+ struct mipi_dsi_transfer xfer;
+ ssize_t ret = 0;
+
+ /* Create packet to be sent */
+ dsi->xfer = &xfer;
+ ret = mipi_dsi_create_packet(&xfer.packet, msg);
+ if (ret < 0) {
+ dsi->xfer = NULL;
+ return ret;
+ }
+
+ if ((msg->type & MIPI_DSI_GENERIC_READ_REQUEST_0_PARAM ||
+ msg->type & MIPI_DSI_GENERIC_READ_REQUEST_1_PARAM ||
+ msg->type & MIPI_DSI_GENERIC_READ_REQUEST_2_PARAM ||
+ msg->type & MIPI_DSI_DCS_READ) &&
+ msg->rx_len > 0 &&
+ msg->rx_buf != NULL)
+ xfer.direction = DSI_PACKET_RECEIVE;
+ else
+ xfer.direction = DSI_PACKET_SEND;
+
+ xfer.need_bta = (xfer.direction == DSI_PACKET_RECEIVE);
+ xfer.need_bta |= (msg->flags & MIPI_DSI_MSG_REQ_ACK)?1:0;
+ xfer.msg = msg;
+ xfer.status = -ETIMEDOUT;
+ xfer.rx_word_count = 0;
+ xfer.rx_len = 0;
+ xfer.cmd = 0x00;
+ if (msg->tx_len > 0)
+ xfer.cmd = ((u8 *)(msg->tx_buf))[0];
+ init_completion(&xfer.completed);
+
+ nwl_dsi_enable_clocks(dsi, CLK_RX_ESC);
+
+ /* Initiate the DSI packet transmision */
+ nwl_dsi_begin_transmission(dsi);
+
+ wait_for_completion_timeout(&xfer.completed, MIPI_FIFO_TIMEOUT);
+
+ ret = xfer.status;
+ if (xfer.status == -ETIMEDOUT)
+ DRM_DEV_ERROR(host->dev, "[%02X] DSI transfer timed out\n",
+ xfer.cmd);
+
+ nwl_dsi_disable_clocks(dsi, CLK_RX_ESC);
+
+ return ret;
+}
+
+static const struct mipi_dsi_host_ops nwl_dsi_host_ops = {
+ .attach = nwl_dsi_host_attach,
+ .detach = nwl_dsi_host_detach,
+ .transfer = nwl_dsi_host_transfer,
+};
+
+static irqreturn_t nwl_dsi_irq_handler(int irq, void *data)
+{
+ u32 irq_status;
+ struct nwl_mipi_dsi *dsi = data;
+
+ irq_status = nwl_dsi_read(dsi, IRQ_STATUS);
+
+ if (irq_status & TX_PKT_DONE ||
+ irq_status & RX_PKT_HDR_RCVD ||
+ irq_status & RX_PKT_PAYLOAD_DATA_RCVD)
+ nwl_dsi_finish_transmission(dsi, irq_status);
+
+ return IRQ_HANDLED;
+}
+
+static enum drm_connector_status nwl_dsi_connector_detect(
+ struct drm_connector *connector, bool force)
+{
+ struct nwl_mipi_dsi *dsi = container_of(connector,
+ struct nwl_mipi_dsi,
+ connector);
+
+ if (dsi->panel)
+ return connector_status_connected;
+
+ return connector_status_unknown;
+}
+
+static int nwl_dsi_connector_get_modes(struct drm_connector *connector)
+{
+ struct nwl_mipi_dsi *dsi = container_of(connector,
+ struct nwl_mipi_dsi,
+ connector);
+ int num_modes = 0;
+ struct drm_display_mode *mode;
+
+ DRM_DEV_DEBUG_DRIVER(dsi->dev, "\n");
+ if (dsi->panel)
+ num_modes = drm_panel_get_modes(dsi->panel);
+
+ /*
+ * We need to inform the CRTC about the actual bit clock that we need
+ * for each mode
+ */
+ list_for_each_entry(mode, &connector->probed_modes, head) {
+ struct mode_config *config;
+ u32 phy_rate;
+
+ config = nwl_dsi_mode_probe(dsi, mode);
+ /* Unsupported mode */
+ if (!config)
+ continue;
+
+ /* Actual pixel clock that should be used by CRTC */
+ phy_rate = config->phyref_rate / 1000;
+ mode->crtc_clock = phy_rate * (mode->clock / phy_rate);
+ }
+
+ return num_modes;
+}
+
+static const struct drm_connector_funcs nwl_dsi_connector_funcs = {
+ .detect = nwl_dsi_connector_detect,
+ .fill_modes = drm_helper_probe_single_connector_modes,
+ .destroy = drm_connector_cleanup,
+ .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
+ nwl_dsi_connector_helper_funcs = {
+ .get_modes = nwl_dsi_connector_get_modes,
+};
+
+static int nwl_dsi_create_connector(struct drm_device *drm,
+ struct nwl_mipi_dsi *dsi)
+{
+ struct device *dev = dsi->dev;
+ int ret;
+
+ ret = drm_connector_init(drm, &dsi->connector,
+ &nwl_dsi_connector_funcs,
+ DRM_MODE_CONNECTOR_DSI);
+ if (ret) {
+ DRM_DEV_ERROR(dev, "Failed to init drm connector: %d\n", ret);
+ return ret;
+ }
+
+ drm_connector_helper_add(&dsi->connector,
+ &nwl_dsi_connector_helper_funcs);
+
+ dsi->connector.dpms = DRM_MODE_DPMS_OFF;
+ drm_mode_connector_attach_encoder(&dsi->connector, dsi->bridge.encoder);
+
+ ret = drm_panel_attach(dsi->panel, &dsi->connector);
+ if (ret) {
+ DRM_DEV_ERROR(dev, "Failed to attach panel: %d\n", ret);
+ drm_connector_cleanup(&dsi->connector);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int nwl_dsi_bridge_attach(struct drm_bridge *bridge)
+{
+ struct nwl_mipi_dsi *dsi = bridge->driver_private;
+ struct device *dev = dsi->dev;
+ struct drm_encoder *encoder = bridge->encoder;
+ struct device_node *np = dev->of_node;
+ struct device_node *remote_node, *endpoint;
+
+ int ret = 0;
+
+ DRM_DEV_DEBUG_DRIVER(dsi->dev, "\n");
+ if (!encoder) {
+ DRM_DEV_ERROR(dev, "Parent encoder object not found\n");
+ return -ENODEV;
+ }
+
+ dsi->host.ops = &nwl_dsi_host_ops;
+ dsi->host.dev = dev;
+ ret = mipi_dsi_host_register(&dsi->host);
+ if (ret < 0) {
+ dev_err(dev, "failed to register DSI host (%d)\n", ret);
+ return ret;
+ }
+
+ endpoint = of_graph_get_next_endpoint(np, NULL);
+ while (endpoint && !dsi->next_bridge) {
+ remote_node = of_graph_get_remote_port_parent(endpoint);
+ if (!remote_node) {
+ DRM_DEV_ERROR(dev, "No endpoint found!\n");
+ return -ENODEV;
+ }
+
+ dsi->next_bridge = of_drm_find_bridge(remote_node);
+ ret = drm_bridge_attach(encoder, dsi->next_bridge, bridge);
+ if (ret)
+ dsi->next_bridge = NULL;
+ of_node_put(remote_node);
+ endpoint = of_graph_get_next_endpoint(np, endpoint);
+ };
+
+ /*
+ * Create the connector. If we have a bridge, attach it and let the
+ * bridge create the connector.
+ */
+ if (dsi->panel)
+ ret = nwl_dsi_create_connector(encoder->dev, dsi);
+ else if (!dsi->next_bridge)
+ ret = -ENODEV;
+
+ return ret;
+}
+
+static void nwl_dsi_bridge_detach(struct drm_bridge *bridge)
+{
+ struct nwl_mipi_dsi *dsi = bridge->driver_private;
+
+ DRM_DEV_DEBUG_DRIVER(dsi->dev, "\n");
+ if (dsi->panel) {
+ drm_panel_detach(dsi->panel);
+ drm_connector_cleanup(&dsi->connector);
+ dsi->panel = NULL;
+ } else if (dsi->next_bridge) {
+ dsi->next_bridge = NULL;
+ }
+ if (dsi->host.dev)
+ mipi_dsi_host_unregister(&dsi->host);
+}
+
+static void nwl_dsi_bridge_enable(struct drm_bridge *bridge)
+{
+ struct nwl_mipi_dsi *dsi = bridge->driver_private;
+ struct mipi_dsi_device *dsi_device = dsi->dsi_device;
+ struct device *dev = dsi->dev;
+ int ret;
+
+ if (dsi->enabled || (!dsi->panel && !dsi->next_bridge))
+ return;
+
+ if (!dsi_device) {
+ DRM_DEV_ERROR(dev, "Bridge not set up properly!\n");
+ return;
+ }
+
+ pm_runtime_get_sync(dev);
+
+ ret = devm_request_irq(dev, dsi->irq,
+ nwl_dsi_irq_handler, 0, IRQ_NAME, dsi);
+ if (ret < 0) {
+ DRM_DEV_ERROR(dev, "Failed to request IRQ: %d (%d)\n",
+ dsi->irq, ret);
+ return;
+ }
+
+ nwl_dsi_enable_clocks(dsi, CLK_PHY_REF | CLK_TX_ESC);
+
+ phy_init(dsi->phy);
+
+ ret = phy_power_on(dsi->phy);
+ if (ret < 0) {
+ DRM_DEV_ERROR(dev, "Failed to power on DPHY (%d)\n", ret);
+ goto phy_err;
+ }
+
+ nwl_dsi_init_interrupts(dsi);
+ nwl_dsi_config_dpi(dsi);
+
+ if (dsi->panel && drm_panel_prepare(dsi->panel)) {
+ DRM_DEV_ERROR(dev, "Failed to setup panel\n");
+ goto prepare_err;
+ }
+
+ nwl_dsi_config_host(dsi);
+
+ if (dsi->panel && drm_panel_enable(dsi->panel)) {
+ DRM_DEV_ERROR(dev, "Failed to enable panel\n");
+ drm_panel_unprepare(dsi->panel);
+ goto enable_err;
+ }
+
+ if (dsi_device->mode_flags & MIPI_DSI_CLOCK_NON_CONTINUOUS)
+ nwl_dsi_write(dsi, CFG_NONCONTINUOUS_CLK, 0x00);
+
+ dsi->enabled = true;
+
+ return;
+
+enable_err:
+ drm_panel_unprepare(dsi->panel);
+
+prepare_err:
+ phy_power_off(dsi->phy);
+
+phy_err:
+ phy_exit(dsi->phy);
+ nwl_dsi_disable_clocks(dsi, CLK_PHY_REF | CLK_TX_ESC);
+ devm_free_irq(dev, dsi->irq, dsi);
+}
+
+static void nwl_dsi_bridge_disable(struct drm_bridge *bridge)
+{
+ struct nwl_mipi_dsi *dsi = bridge->driver_private;
+ struct device *dev = dsi->dev;
+
+ if (!dsi->enabled)
+ return;
+
+ if (dsi->panel) {
+ if (drm_panel_disable(dsi->panel)) {
+ DRM_DEV_ERROR(dev, "failed to disable panel\n");
+ return;
+ }
+ drm_panel_unprepare(dsi->panel);
+ }
+
+ phy_power_off(dsi->phy);
+ phy_exit(dsi->phy);
+
+ if (!dsi->no_clk_reset)
+ nwl_dsi_disable_clocks(dsi, CLK_PHY_REF | CLK_TX_ESC);
+
+ devm_free_irq(dev, dsi->irq, dsi);
+
+ pm_runtime_put_sync(dev);
+
+ dsi->enabled = false;
+}
+
+static const struct drm_bridge_funcs nwl_dsi_bridge_funcs = {
+ .enable = nwl_dsi_bridge_enable,
+ .disable = nwl_dsi_bridge_disable,
+ .mode_valid = nwl_dsi_bridge_mode_valid,
+ .mode_fixup = nwl_dsi_bridge_mode_fixup,
+ .mode_set = nwl_dsi_bridge_mode_set,
+ .attach = nwl_dsi_bridge_attach,
+ .detach = nwl_dsi_bridge_detach,
+};
+
+static int nwl_dsi_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct nwl_mipi_dsi *dsi;
+ struct clk *clk;
+ struct resource *res;
+ int ret;
+
+ dsi = devm_kzalloc(dev, sizeof(*dsi), GFP_KERNEL);
+ if (!dsi)
+ return -ENOMEM;
+
+ dsi->phy = devm_phy_get(dev, "dphy");
+ if (IS_ERR(dsi->phy)) {
+ ret = PTR_ERR(dsi->phy);
+ dev_err(dev, "Could not get PHY (%d)\n", ret);
+ return ret;
+ }
+
+ clk = devm_clk_get(dev, "phy_ref");
+ if (IS_ERR(clk)) {
+ ret = PTR_ERR(clk);
+ dev_err(dev, "Failed to get phy_ref clock: %d\n", ret);
+ return ret;
+ }
+ dsi->phy_ref.clk = clk;
+ dsi->phy_ref.rate = clk_get_rate(clk);
+ dsi->phy_ref.enabled = false;
+
+ clk = devm_clk_get(dev, "rx_esc");
+ if (IS_ERR(clk)) {
+ ret = PTR_ERR(clk);
+ dev_err(dev, "Failed to get rx_esc clock: %d\n", ret);
+ return ret;
+ }
+ dsi->rx_esc.clk = clk;
+ dsi->rx_esc.rate = clk_get_rate(clk);
+ dsi->rx_esc.enabled = false;
+
+ clk = devm_clk_get(dev, "tx_esc");
+ if (IS_ERR(clk)) {
+ ret = PTR_ERR(clk);
+ dev_err(dev, "Failed to get tx_esc clock: %d\n", ret);
+ return ret;
+ }
+ dsi->tx_esc.clk = clk;
+ dsi->tx_esc.rate = clk_get_rate(clk);
+ dsi->tx_esc.enabled = false;
+ /* TX clk rate must be RX clk rate divided by 4 */
+ if (dsi->tx_esc.rate != (dsi->rx_esc.rate / 4))
+ dsi->tx_esc.rate = dsi->rx_esc.rate / 4;
+
+ dsi->enabled = false;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res)
+ return -EBUSY;
+
+ dsi->base = devm_ioremap_resource(dev, res);
+ if (IS_ERR(dsi->base))
+ return PTR_ERR(dsi->base);
+
+ dsi->irq = platform_get_irq(pdev, 0);
+ if (dsi->irq < 0) {
+ DRM_DEV_ERROR(dev, "Failed to get device IRQ!\n");
+ return -EINVAL;
+ }
+
+ pm_runtime_enable(dev);
+
+ dsi->no_clk_reset = of_property_read_bool(dev->of_node, "no_clk_reset");
+
+ dsi->dev = dev;
+ platform_set_drvdata(pdev, dsi);
+
+ dsi->bridge.driver_private = dsi;
+ dsi->bridge.funcs = &nwl_dsi_bridge_funcs;
+ dsi->bridge.of_node = dev->of_node;
+
+ ret = drm_bridge_add(&dsi->bridge);
+ if (ret < 0)
+ dev_err(dev, "Failed to add nwl-dsi bridge (%d)\n", ret);
+
+ INIT_LIST_HEAD(&dsi->valid_modes);
+
+ return ret;
+}
+
+static int nwl_dsi_remove(struct platform_device *pdev)
+{
+ struct nwl_mipi_dsi *dsi = platform_get_drvdata(pdev);
+ struct mode_config *config;
+ struct list_head *pos, *tmp;
+
+
+ drm_bridge_remove(&dsi->bridge);
+
+ list_for_each_safe(pos, tmp, &dsi->valid_modes) {
+ config = list_entry(pos, struct mode_config, list);
+ list_del(pos);
+ devm_kfree(dsi->dev, config);
+ }
+
+ pm_runtime_disable(&pdev->dev);
+
+ return 0;
+}
+
+static const struct of_device_id nwl_dsi_dt_ids[] = {
+ { .compatible = "nwl,mipi-dsi" },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, nwl_dsi_dt_ids);
+
+static struct platform_driver imx_nwl_dsi_driver = {
+ .probe = nwl_dsi_probe,
+ .remove = nwl_dsi_remove,
+ .driver = {
+ .of_match_table = nwl_dsi_dt_ids,
+ .name = "nwl-mipi-dsi",
+ },
+};
+
+module_platform_driver(imx_nwl_dsi_driver);
+
+MODULE_AUTHOR("NXP Semiconductor");
+MODULE_DESCRIPTION("NWL MIPI-DSI transmitter driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:nwl-dsi");
diff --git a/drivers/gpu/drm/bridge/nxp-seiko-43wvfig.c b/drivers/gpu/drm/bridge/nxp-seiko-43wvfig.c
new file mode 100644
index 000000000000..dd04ee4a3ee4
--- /dev/null
+++ b/drivers/gpu/drm/bridge/nxp-seiko-43wvfig.c
@@ -0,0 +1,247 @@
+/*
+ * DRM driver for the legacy Freescale adapter card holding
+ * Seiko RA169Z20 43WVFIG LCD panel
+ *
+ * Copyright (C) 2018 NXP
+ *
+ * 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 <drm/drmP.h>
+#include <drm/drm_atomic_helper.h>
+#include <drm/drm_crtc_helper.h>
+#include <drm/drm_of.h>
+#include <drm/drm_panel.h>
+#include <linux/of.h>
+#include <linux/of_graph.h>
+#include <linux/of_platform.h>
+
+struct seiko_adapter {
+ struct device *dev;
+ struct drm_panel *panel;
+ struct drm_bridge bridge;
+ struct drm_connector connector;
+
+ u32 bpc;
+ u32 bus_format;
+};
+
+static enum drm_connector_status seiko_adapter_connector_detect(
+ struct drm_connector *connector, bool force)
+{
+ return connector_status_connected;
+}
+
+static int seiko_adapter_connector_get_modes(struct drm_connector *connector)
+{
+ int num_modes;
+
+ struct seiko_adapter *adap = container_of(connector,
+ struct seiko_adapter,
+ connector);
+
+ num_modes = drm_panel_get_modes(adap->panel);
+
+ /*
+ * The panel will populate the connector display_info properties with
+ * fixed numbers, but we need to change them according to our
+ * configuration.
+ */
+ connector->display_info.bpc = adap->bpc;
+ drm_display_info_set_bus_formats(&connector->display_info,
+ &adap->bus_format, 1);
+
+ return num_modes;
+}
+
+static const struct drm_connector_funcs seiko_adapter_connector_funcs = {
+ .detect = seiko_adapter_connector_detect,
+ .fill_modes = drm_helper_probe_single_connector_modes,
+ .destroy = drm_connector_cleanup,
+ .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
+ seiko_adapter_connector_helper_funcs = {
+ .get_modes = seiko_adapter_connector_get_modes,
+};
+
+static int seiko_adapter_bridge_attach(struct drm_bridge *bridge)
+{
+ struct seiko_adapter *adap = bridge->driver_private;
+ struct device *dev = adap->dev;
+ struct drm_encoder *encoder = bridge->encoder;
+ struct drm_device *drm;
+ int ret = 0;
+
+ if (!encoder) {
+ DRM_DEV_ERROR(dev, "Parent encoder object not found\n");
+ return -ENODEV;
+ }
+
+ drm = encoder->dev;
+
+ /*
+ * Create the connector for our panel
+ */
+
+ ret = drm_connector_init(drm, &adap->connector,
+ &seiko_adapter_connector_funcs,
+ DRM_MODE_CONNECTOR_DPI);
+ if (ret) {
+ DRM_DEV_ERROR(dev, "Failed to init drm connector: %d\n", ret);
+ return ret;
+ }
+
+ drm_connector_helper_add(&adap->connector,
+ &seiko_adapter_connector_helper_funcs);
+
+ adap->connector.dpms = DRM_MODE_DPMS_OFF;
+ drm_mode_connector_attach_encoder(&adap->connector, encoder);
+
+ ret = drm_panel_attach(adap->panel, &adap->connector);
+ if (ret) {
+ DRM_DEV_ERROR(dev, "Failed to attach panel: %d\n", ret);
+ drm_connector_cleanup(&adap->connector);
+ return ret;
+ }
+
+ return ret;
+}
+
+static void seiko_adapter_bridge_detach(struct drm_bridge *bridge)
+{
+ struct seiko_adapter *adap = bridge->driver_private;
+
+ drm_panel_detach(adap->panel);
+ drm_connector_cleanup(&adap->connector);
+}
+
+static void seiko_adapter_bridge_enable(struct drm_bridge *bridge)
+{
+ struct seiko_adapter *adap = bridge->driver_private;
+ struct device *dev = adap->dev;
+
+ if (drm_panel_prepare(adap->panel)) {
+ DRM_DEV_ERROR(dev, "Failed to prepare panel\n");
+ return;
+ }
+
+ if (drm_panel_enable(adap->panel)) {
+ DRM_DEV_ERROR(dev, "Failed to enable panel\n");
+ drm_panel_unprepare(adap->panel);
+ }
+}
+
+static void seiko_adapter_bridge_disable(struct drm_bridge *bridge)
+{
+ struct seiko_adapter *adap = bridge->driver_private;
+ struct device *dev = adap->dev;
+
+ if (drm_panel_disable(adap->panel)) {
+ DRM_DEV_ERROR(dev, "failed to disable panel\n");
+ return;
+ }
+
+ if (drm_panel_unprepare(adap->panel))
+ DRM_DEV_ERROR(dev, "failed to unprepare panel\n");
+}
+
+static const struct drm_bridge_funcs seiko_adapter_bridge_funcs = {
+ .enable = seiko_adapter_bridge_enable,
+ .disable = seiko_adapter_bridge_disable,
+ .attach = seiko_adapter_bridge_attach,
+ .detach = seiko_adapter_bridge_detach,
+};
+
+static int seiko_adapter_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct seiko_adapter *adap;
+ struct device_node *remote;
+ u32 bus_mode;
+ int ret, port;
+
+ adap = devm_kzalloc(dev, sizeof(*adap), GFP_KERNEL);
+ if (!adap)
+ return -ENOMEM;
+
+ of_property_read_u32(dev->of_node, "bus_mode", &bus_mode);
+ if (bus_mode != 18 && bus_mode != 24) {
+ dev_err(dev, "Invalid bus_mode: %d\n", bus_mode);
+ return -EINVAL;
+ }
+
+ switch (bus_mode) {
+ case 18:
+ adap->bpc = 6;
+ adap->bus_format = MEDIA_BUS_FMT_RGB666_1X18;
+ break;
+ case 24:
+ adap->bpc = 8;
+ adap->bus_format = MEDIA_BUS_FMT_RGB888_1X24;
+ break;
+ }
+
+ for (port = 0; port < 2; port++) {
+ remote = of_graph_get_remote_node(dev->of_node, port, -1);
+ if (!remote) {
+ pr_info("No remote for port %d\n", port);
+ return -ENODEV;
+ }
+ adap->panel = of_drm_find_panel(remote);
+ if (adap->panel)
+ break;
+ }
+ if (!adap->panel) {
+ dev_err(dev, "No panel found!\n");
+ return -ENODEV;
+ }
+
+ adap->dev = dev;
+ adap->bridge.driver_private = adap;
+ adap->bridge.funcs = &seiko_adapter_bridge_funcs;
+ adap->bridge.of_node = dev->of_node;
+
+ ret = drm_bridge_add(&adap->bridge);
+ if (ret < 0)
+ dev_err(dev, "Failed to add seiko-adapter bridge (%d)\n", ret);
+
+ dev_info(dev, "Seiko adapter driver probed\n");
+ return ret;
+}
+
+static int seiko_adapter_remove(struct platform_device *pdev)
+{
+ return 0;
+}
+
+static const struct of_device_id seiko_adapter_dt_ids[] = {
+ { .compatible = "nxp,seiko-43wvfig" },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, seiko_adapter_dt_ids);
+
+static struct platform_driver seiko_adapter_driver = {
+ .probe = seiko_adapter_probe,
+ .remove = seiko_adapter_remove,
+ .driver = {
+ .of_match_table = seiko_adapter_dt_ids,
+ .name = "nxp-seiko-adapter",
+ },
+};
+
+module_platform_driver(seiko_adapter_driver);
+
+MODULE_AUTHOR("NXP Semiconductor");
+MODULE_DESCRIPTION("Seiko 43WVFIG adapter card driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/drm/bridge/sec-dsim.c b/drivers/gpu/drm/bridge/sec-dsim.c
new file mode 100644
index 000000000000..0fa4e09cab30
--- /dev/null
+++ b/drivers/gpu/drm/bridge/sec-dsim.c
@@ -0,0 +1,1963 @@
+/*
+ * Samsung MIPI DSIM Bridge
+ *
+ * Copyright 2018-2019 NXP
+ *
+ * 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 <asm/unaligned.h>
+#include <linux/clk.h>
+#include <linux/completion.h>
+#include <linux/delay.h>
+#include <linux/gcd.h>
+#include <linux/log2.h>
+#include <linux/module.h>
+#include <linux/of_graph.h>
+#include <drm/bridge/sec_mipi_dsim.h>
+#include <drm/drmP.h>
+#include <drm/drm_atomic_helper.h>
+#include <drm/drm_bridge.h>
+#include <drm/drm_connector.h>
+#include <drm/drm_crtc_helper.h>
+#include <drm/drm_encoder.h>
+#include <drm/drm_fourcc.h>
+#include <drm/drm_mipi_dsi.h>
+#include <drm/drm_panel.h>
+#include <video/videomode.h>
+#include <video/mipi_display.h>
+
+/* dsim registers */
+#define DSIM_VERSION 0x00
+#define DSIM_STATUS 0x04
+#define DSIM_RGB_STATUS 0x08
+#define DSIM_SWRST 0x0c
+#define DSIM_CLKCTRL 0x10
+#define DSIM_TIMEOUT 0x14
+#define DSIM_CONFIG 0x18
+#define DSIM_ESCMODE 0x1c
+#define DSIM_MDRESOL 0x20
+#define DSIM_MVPORCH 0x24
+#define DSIM_MHPORCH 0x28
+#define DSIM_MSYNC 0x2c
+#define DSIM_SDRESOL 0x30
+#define DSIM_INTSRC 0x34
+#define DSIM_INTMSK 0x38
+
+/* packet */
+#define DSIM_PKTHDR 0x3c
+#define DSIM_PAYLOAD 0x40
+#define DSIM_RXFIFO 0x44
+#define DSIM_FIFOTHLD 0x48
+#define DSIM_FIFOCTRL 0x4c
+#define DSIM_MEMACCHR 0x50
+#define DSIM_MULTI_PKT 0x78
+
+/* pll control */
+#define DSIM_PLLCTRL_1G 0x90
+#define DSIM_PLLCTRL 0x94
+#define DSIM_PLLCTRL1 0x98
+#define DSIM_PLLCTRL2 0x9c
+#define DSIM_PLLTMR 0xa0
+
+/* dphy */
+#define DSIM_PHYTIMING 0xb4
+#define DSIM_PHYTIMING1 0xb8
+#define DSIM_PHYTIMING2 0xbc
+
+/* reg bit manipulation */
+#define REG_MASK(e, s) (((1 << ((e) - (s) + 1)) - 1) << (s))
+#define REG_PUT(x, e, s) (((x) << (s)) & REG_MASK(e, s))
+#define REG_GET(x, e, s) (((x) & REG_MASK(e, s)) >> (s))
+
+/* register bit fields */
+#define STATUS_PLLSTABLE BIT(31)
+#define STATUS_SWRSTRLS BIT(20)
+#define STATUS_TXREADYHSCLK BIT(10)
+#define STATUS_ULPSCLK BIT(9)
+#define STATUS_STOPSTATECLK BIT(8)
+#define STATUS_GET_ULPSDAT(x) REG_GET(x, 7, 4)
+#define STATUS_GET_STOPSTATEDAT(x) REG_GET(x, 3, 0)
+
+#define RGB_STATUS_CMDMODE_INSEL BIT(31)
+#define RGB_STATUS_GET_RGBSTATE(x) REG_GET(x, 12, 0)
+
+#define CLKCTRL_TXREQUESTHSCLK BIT(31)
+#define CLKCTRL_DPHY_SEL_1G BIT(29)
+#define CLKCTRL_DPHY_SEL_1P5G (0x0 << 29)
+#define CLKCTRL_ESCCLKEN BIT(28)
+#define CLKCTRL_PLLBYPASS BIT(29)
+#define CLKCTRL_BYTECLKSRC_DPHY_PLL REG_PUT(0, 26, 25)
+#define CLKCTRL_BYTECLKEN BIT(24)
+#define CLKCTRL_SET_LANEESCCLKEN(x) REG_PUT(x, 23, 19)
+#define CLKCTRL_SET_ESCPRESCALER(x) REG_PUT(x, 15, 0)
+
+#define TIMEOUT_SET_BTAOUT(x) REG_PUT(x, 23, 16)
+#define TIMEOUT_SET_LPDRTOUT(x) REG_PUT(x, 15, 0)
+
+#define CONFIG_NON_CONTINUOUS_CLOCK_LANE BIT(31)
+#define CONFIG_CLKLANE_STOP_START BIT(30)
+#define CONFIG_MFLUSH_VS BIT(29)
+#define CONFIG_EOT_R03 BIT(28)
+#define CONFIG_SYNCINFORM BIT(27)
+#define CONFIG_BURSTMODE BIT(26)
+#define CONFIG_VIDEOMODE BIT(25)
+#define CONFIG_AUTOMODE BIT(24)
+#define CONFIG_HSEDISABLEMODE BIT(23)
+#define CONFIG_HFPDISABLEMODE BIT(22)
+#define CONFIG_HBPDISABLEMODE BIT(21)
+#define CONFIG_HSADISABLEMODE BIT(20)
+#define CONFIG_SET_MAINVC(x) REG_PUT(x, 19, 18)
+#define CONFIG_SET_SUBVC(x) REG_PUT(x, 17, 16)
+#define CONFIG_SET_MAINPIXFORMAT(x) REG_PUT(x, 14, 12)
+#define CONFIG_SET_SUBPIXFORMAT(x) REG_PUT(x, 10, 8)
+#define CONFIG_SET_NUMOFDATLANE(x) REG_PUT(x, 6, 5)
+#define CONFIG_SET_LANEEN(x) REG_PUT(x, 4, 0)
+
+#define ESCMODE_SET_STOPSTATE_CNT(X) REG_PUT(x, 31, 21)
+#define ESCMODE_FORCESTOPSTATE BIT(20)
+#define ESCMODE_FORCEBTA BIT(16)
+#define ESCMODE_CMDLPDT BIT(7)
+#define ESCMODE_TXLPDT BIT(6)
+#define ESCMODE_TXTRIGGERRST BIT(5)
+
+#define MDRESOL_MAINSTANDBY BIT(31)
+#define MDRESOL_SET_MAINVRESOL(x) REG_PUT(x, 27, 16)
+#define MDRESOL_SET_MAINHRESOL(x) REG_PUT(x, 11, 0)
+
+#define MVPORCH_SET_CMDALLOW(x) REG_PUT(x, 31, 28)
+#define MVPORCH_SET_STABLEVFP(x) REG_PUT(x, 26, 16)
+#define MVPORCH_SET_MAINVBP(x) REG_PUT(x, 10, 0)
+
+#define MHPORCH_SET_MAINHFP(x) REG_PUT(x, 31, 16)
+#define MHPORCH_SET_MAINHBP(x) REG_PUT(x, 15, 0)
+
+#define MSYNC_SET_MAINVSA(x) REG_PUT(x, 31, 22)
+#define MSYNC_SET_MAINHSA(x) REG_PUT(x, 15, 0)
+
+#define INTSRC_PLLSTABLE BIT(31)
+#define INTSRC_SWRSTRELEASE BIT(30)
+#define INTSRC_SFRPLFIFOEMPTY BIT(29)
+#define INTSRC_SFRPHFIFOEMPTY BIT(28)
+#define INTSRC_FRAMEDONE BIT(24)
+#define INTSRC_LPDRTOUT BIT(21)
+#define INTSRC_TATOUT BIT(20)
+#define INTSRC_RXDATDONE BIT(18)
+#define INTSRC_RXTE BIT(17)
+#define INTSRC_RXACK BIT(16)
+#define INTSRC_MASK (INTSRC_PLLSTABLE | \
+ INTSRC_SWRSTRELEASE | \
+ INTSRC_SFRPLFIFOEMPTY | \
+ INTSRC_SFRPHFIFOEMPTY | \
+ INTSRC_FRAMEDONE | \
+ INTSRC_LPDRTOUT | \
+ INTSRC_TATOUT | \
+ INTSRC_RXDATDONE | \
+ INTSRC_RXTE | \
+ INTSRC_RXACK)
+
+#define INTMSK_MSKPLLSTABLE BIT(31)
+#define INTMSK_MSKSWRELEASE BIT(30)
+#define INTMSK_MSKSFRPLFIFOEMPTY BIT(29)
+#define INTMSK_MSKSFRPHFIFOEMPTY BIT(28)
+#define INTMSK_MSKFRAMEDONE BIT(24)
+#define INTMSK_MSKLPDRTOUT BIT(21)
+#define INTMSK_MSKTATOUT BIT(20)
+#define INTMSK_MSKRXDATDONE BIT(18)
+#define INTMSK_MSKRXTE BIT(17)
+#define INTMSK_MSKRXACK BIT(16)
+
+#define PKTHDR_SET_DATA1(x) REG_PUT(x, 23, 16)
+#define PKTHDR_GET_DATA1(x) REG_GET(x, 23, 16)
+#define PKTHDR_SET_DATA0(x) REG_PUT(x, 15, 8)
+#define PKTHDR_GET_DATA0(x) REG_GET(x, 15, 8)
+#define PKTHDR_GET_WC(x) REG_GET(x, 23, 8)
+#define PKTHDR_SET_DI(x) REG_PUT(x, 7, 0)
+#define PKTHDR_GET_DI(x) REG_GET(x, 7, 0)
+#define PKTHDR_SET_DT(x) REG_PUT(x, 5, 0)
+#define PKTHDR_GET_DT(x) REG_GET(x, 5, 0)
+#define PKTHDR_SET_VC(x) REG_PUT(x, 7, 6)
+#define PKTHDR_GET_VC(x) REG_GET(x, 7, 6)
+
+#define FIFOCTRL_FULLRX BIT(25)
+#define FIFOCTRL_EMPTYRX BIT(24)
+#define FIFOCTRL_FULLHSFR BIT(23)
+#define FIFOCTRL_EMPTYHSFR BIT(22)
+#define FIFOCTRL_FULLLSFR BIT(21)
+#define FIFOCTRL_EMPTYLSFR BIT(20)
+#define FIFOCTRL_FULLHMAIN BIT(11)
+#define FIFOCTRL_EMPTYHMAIN BIT(10)
+#define FIFOCTRL_FULLLMAIN BIT(9)
+#define FIFOCTRL_EMPTYLMAIN BIT(8)
+#define FIFOCTRL_NINITRX BIT(4)
+#define FIFOCTRL_NINITSFR BIT(3)
+#define FIFOCTRL_NINITI80 BIT(2)
+#define FIFOCTRL_NINITSUB BIT(1)
+#define FIFOCTRL_NINITMAIN BIT(0)
+
+#define PLLCTRL_DPDNSWAP_CLK BIT(25)
+#define PLLCTRL_DPDNSWAP_DAT BIT(24)
+#define PLLCTRL_PLLEN BIT(23)
+#define PLLCTRL_SET_PMS(x) REG_PUT(x, 19, 1)
+ #define PLLCTRL_SET_P(x) REG_PUT(x, 18, 13)
+ #define PLLCTRL_SET_M(x) REG_PUT(x, 12, 3)
+ #define PLLCTRL_SET_S(x) REG_PUT(x, 2, 0)
+
+#define PHYTIMING_SET_M_TLPXCTL(x) REG_PUT(x, 15, 8)
+#define PHYTIMING_SET_M_THSEXITCTL(x) REG_PUT(x, 7, 0)
+
+#define PHYTIMING1_SET_M_TCLKPRPRCTL(x) REG_PUT(x, 31, 24)
+#define PHYTIMING1_SET_M_TCLKZEROCTL(x) REG_PUT(x, 23, 16)
+#define PHYTIMING1_SET_M_TCLKPOSTCTL(x) REG_PUT(x, 15, 8)
+#define PHYTIMING1_SET_M_TCLKTRAILCTL(x) REG_PUT(x, 7, 0)
+
+#define PHYTIMING2_SET_M_THSPRPRCTL(x) REG_PUT(x, 23, 16)
+#define PHYTIMING2_SET_M_THSZEROCTL(x) REG_PUT(x, 15, 8)
+#define PHYTIMING2_SET_M_THSTRAILCTL(x) REG_PUT(x, 7, 0)
+
+#define dsim_read(dsim, reg) readl(dsim->base + reg)
+#define dsim_write(dsim, val, reg) writel(val, dsim->base + reg)
+
+/* fixed phy ref clk rate */
+#define PHY_REF_CLK 27000
+
+#define MAX_MAIN_HRESOL 2047
+#define MAX_MAIN_VRESOL 2047
+#define MAX_SUB_HRESOL 1024
+#define MAX_SUB_VRESOL 1024
+
+/* in KHZ */
+#define MAX_ESC_CLK_FREQ 20000
+
+/* dsim all irqs index */
+#define PLLSTABLE 1
+#define SWRSTRELEASE 2
+#define SFRPLFIFOEMPTY 3
+#define SFRPHFIFOEMPTY 4
+#define SYNCOVERRIDE 5
+#define BUSTURNOVER 6
+#define FRAMEDONE 7
+#define LPDRTOUT 8
+#define TATOUT 9
+#define RXDATDONE 10
+#define RXTE 11
+#define RXACK 12
+#define ERRRXECC 13
+#define ERRRXCRC 14
+#define ERRESC3 15
+#define ERRESC2 16
+#define ERRESC1 17
+#define ERRESC0 18
+#define ERRSYNC3 19
+#define ERRSYNC2 20
+#define ERRSYNC1 21
+#define ERRSYNC0 22
+#define ERRCONTROL3 23
+#define ERRCONTROL2 24
+#define ERRCONTROL1 25
+#define ERRCONTROL0 26
+
+#define MIPI_FIFO_TIMEOUT msecs_to_jiffies(250)
+
+#define MIPI_HFP_PKT_OVERHEAD 6
+#define MIPI_HBP_PKT_OVERHEAD 6
+#define MIPI_HSA_PKT_OVERHEAD 6
+
+#define to_sec_mipi_dsim(dsi) container_of(dsi, struct sec_mipi_dsim, dsi_host)
+#define conn_to_sec_mipi_dsim(conn) \
+ container_of(conn, struct sec_mipi_dsim, connector)
+
+/* used for CEA standard modes */
+struct dsim_hblank_par {
+ char *name; /* drm display mode name */
+ int vrefresh;
+ int hfp_wc;
+ int hbp_wc;
+ int hsa_wc;
+ int lanes;
+};
+
+struct dsim_pll_pms {
+ uint32_t bit_clk; /* kHz */
+ uint32_t p;
+ uint32_t m;
+ uint32_t s;
+ uint32_t k;
+};
+
+struct sec_mipi_dsim {
+ struct mipi_dsi_host dsi_host;
+ struct drm_connector connector;
+ struct drm_encoder *encoder;
+ struct drm_bridge *bridge;
+ struct drm_bridge *next;
+ struct drm_panel *panel;
+ struct device *dev;
+
+ void __iomem *base;
+ int irq;
+
+ struct clk *clk_cfg;
+ struct clk *clk_pllref;
+ struct clk *pclk; /* pixel clock */
+
+ /* kHz clocks */
+ uint32_t pix_clk;
+ uint32_t bit_clk;
+ uint32_t pref_clk; /* phy ref clock rate in KHz */
+
+ unsigned int lanes;
+ unsigned int channel; /* virtual channel */
+ enum mipi_dsi_pixel_format format;
+ unsigned long mode_flags;
+ const struct dsim_hblank_par *hpar;
+ unsigned int pms;
+ unsigned int p;
+ unsigned int m;
+ unsigned int s;
+ unsigned long long lp_data_rate;
+ unsigned long long hs_data_rate;
+ struct videomode vmode;
+
+ struct completion pll_stable;
+ struct completion ph_tx_done;
+ struct completion pl_tx_done;
+ struct completion rx_done;
+ const struct sec_mipi_dsim_plat_data *pdata;
+};
+
+#define DSIM_HBLANK_PARAM(nm, vf, hfp, hbp, hsa, num) \
+ .name = (nm), \
+ .vrefresh = (vf), \
+ .hfp_wc = (hfp), \
+ .hbp_wc = (hbp), \
+ .hsa_wc = (hsa), \
+ .lanes = (num)
+
+#define DSIM_PLL_PMS(c, pp, mm, ss) \
+ .bit_clk = (c), \
+ .p = (pp), \
+ .m = (mm), \
+ .s = (ss)
+
+static const struct dsim_hblank_par hblank_4lanes[] = {
+ /* { 88, 148, 44 } */
+ { DSIM_HBLANK_PARAM("1920x1080", 60, 60, 105, 27, 4), },
+ /* { 528, 148, 44 } */
+ { DSIM_HBLANK_PARAM("1920x1080", 50, 390, 105, 27, 4), },
+ /* { 88, 148, 44 } */
+ { DSIM_HBLANK_PARAM("1920x1080", 30, 60, 105, 27, 4), },
+ /* { 110, 220, 40 } */
+ { DSIM_HBLANK_PARAM("1280x720" , 60, 78, 159, 24, 4), },
+ /* { 440, 220, 40 } */
+ { DSIM_HBLANK_PARAM("1280x720" , 50, 324, 159, 24, 4), },
+ /* { 16, 60, 62 } */
+ { DSIM_HBLANK_PARAM("720x480" , 60, 6, 39, 40, 4), },
+ /* { 12, 68, 64 } */
+ { DSIM_HBLANK_PARAM("720x576" , 50, 3, 45, 42, 4), },
+ /* { 16, 48, 96 } */
+ { DSIM_HBLANK_PARAM("640x480" , 60, 6, 30, 66, 4), },
+};
+
+static const struct dsim_hblank_par hblank_2lanes[] = {
+ /* { 88, 148, 44 } */
+ { DSIM_HBLANK_PARAM("1920x1080", 30, 114, 210, 60, 2), },
+ /* { 110, 220, 40 } */
+ { DSIM_HBLANK_PARAM("1280x720" , 60, 159, 320, 40, 2), },
+ /* { 440, 220, 40 } */
+ { DSIM_HBLANK_PARAM("1280x720" , 50, 654, 320, 40, 2), },
+ /* { 16, 60, 62 } */
+ { DSIM_HBLANK_PARAM("720x480" , 60, 16, 66, 88, 2), },
+ /* { 12, 68, 64 } */
+ { DSIM_HBLANK_PARAM("720x576" , 50, 12, 96, 72, 2), },
+ /* { 16, 48, 96 } */
+ { DSIM_HBLANK_PARAM("640x480" , 60, 18, 66, 138, 2), },
+};
+
+static const struct dsim_hblank_par *sec_mipi_dsim_get_hblank_par(const char *name,
+ int vrefresh,
+ int lanes)
+{
+ int i, size;
+ const struct dsim_hblank_par *hpar, *hblank;
+
+ if (unlikely(!name))
+ return NULL;
+
+ switch (lanes) {
+ case 2:
+ hblank = hblank_2lanes;
+ size = ARRAY_SIZE(hblank_2lanes);
+ break;
+ case 4:
+ hblank = hblank_4lanes;
+ size = ARRAY_SIZE(hblank_4lanes);
+ break;
+ default:
+ pr_err("No hblank data for mode %s with %d lanes\n",
+ name, lanes);
+ return NULL;
+ }
+
+ for (i = 0; i < size; i++) {
+ hpar = &hblank[i];
+
+ if (!strcmp(name, hpar->name)) {
+ if (vrefresh != hpar->vrefresh)
+ continue;
+
+ /* found */
+ return hpar;
+ }
+ }
+
+ return NULL;
+}
+
+static int sec_mipi_dsim_set_pref_rate(struct sec_mipi_dsim *dsim)
+{
+ int ret;
+ uint32_t rate;
+ struct device *dev = dsim->dev;
+ const struct sec_mipi_dsim_plat_data *pdata = dsim->pdata;
+ const struct sec_mipi_dsim_pll *dpll = pdata->dphy_pll;
+ const struct sec_mipi_dsim_range *fin_range = &dpll->fin;
+
+ ret = of_property_read_u32(dev->of_node, "pref-rate", &rate);
+ if (ret < 0) {
+ dev_dbg(dev, "no valid rate assigned for pref clock\n");
+ dsim->pref_clk = PHY_REF_CLK;
+ } else {
+ if (unlikely(rate < fin_range->min || rate > fin_range->max)) {
+ dev_warn(dev, "pref-rate get is invalid: %uKHz\n",
+ rate);
+ dsim->pref_clk = PHY_REF_CLK;
+ } else
+ dsim->pref_clk = rate;
+ }
+
+set_rate:
+ ret = clk_set_rate(dsim->clk_pllref,
+ ((unsigned long)dsim->pref_clk) * 1000);
+ if (ret) {
+ dev_err(dev, "failed to set pll ref clock rate\n");
+ return ret;
+ }
+
+ rate = clk_get_rate(dsim->clk_pllref) / 1000;
+ if (unlikely(!rate)) {
+ dev_err(dev, "failed to get pll ref clock rate\n");
+ return -EINVAL;
+ }
+
+ if (rate != dsim->pref_clk) {
+ if (unlikely(dsim->pref_clk == PHY_REF_CLK)) {
+ /* set default rate failed */
+ dev_err(dev, "no valid pll ref clock rate\n");
+ return -EINVAL;
+ }
+
+ dev_warn(dev, "invalid assigned rate for pref: %uKHz\n",
+ dsim->pref_clk);
+ dev_warn(dev, "use default pref rate instead: %uKHz\n",
+ PHY_REF_CLK);
+
+ dsim->pref_clk = PHY_REF_CLK;
+ goto set_rate;
+ }
+
+ return 0;
+}
+
+static void sec_mipi_dsim_irq_init(struct sec_mipi_dsim *dsim);
+
+/* For now, dsim only support one device attached */
+static int sec_mipi_dsim_host_attach(struct mipi_dsi_host *host,
+ struct mipi_dsi_device *dsi)
+{
+ struct sec_mipi_dsim *dsim = to_sec_mipi_dsim(host);
+ const struct sec_mipi_dsim_plat_data *pdata = dsim->pdata;
+ struct device *dev = dsim->dev;
+ struct drm_panel *panel;
+
+ if (!dsi->lanes || dsi->lanes > pdata->max_data_lanes) {
+ dev_err(dev, "invalid data lanes number\n");
+ return -EINVAL;
+ }
+
+ if (dsim->channel)
+ return -EINVAL;
+
+ if (!(dsi->mode_flags & MIPI_DSI_MODE_VIDEO) ||
+ !((dsi->mode_flags & MIPI_DSI_MODE_VIDEO_BURST) ||
+ (dsi->mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE))) {
+ dev_err(dev, "unsupported dsi mode\n");
+ return -EINVAL;
+ }
+
+ if (dsi->format != MIPI_DSI_FMT_RGB888 &&
+ dsi->format != MIPI_DSI_FMT_RGB565 &&
+ dsi->format != MIPI_DSI_FMT_RGB666 &&
+ dsi->format != MIPI_DSI_FMT_RGB666_PACKED) {
+ dev_err(dev, "unsupported pixel format: %#x\n", dsi->format);
+ return -EINVAL;
+ }
+
+ if (!dsim->next) {
+ /* 'dsi' must be panel device */
+ panel = of_drm_find_panel(dsi->dev.of_node);
+
+ if (!panel) {
+ dev_err(dev, "refuse unknown dsi device attach\n");
+ WARN_ON(!panel);
+ return -ENODEV;
+ }
+
+ /* Don't support multiple panels */
+ if (dsim->panel && panel && dsim->panel != panel) {
+ dev_err(dev, "don't support multiple panels\n");
+ return -EBUSY;
+ }
+
+ dsim->panel = panel;
+ }
+
+ /* TODO: DSIM 3 lanes has some display issue, so
+ * avoid 3 lanes enable, and force data lanes to
+ * be 2.
+ */
+ if (dsi->lanes == 3)
+ dsi->lanes = 2;
+
+ dsim->lanes = dsi->lanes;
+ dsim->channel = dsi->channel;
+ dsim->format = dsi->format;
+ dsim->mode_flags = dsi->mode_flags;
+
+ /* TODO: support later */
+#if 0
+ if (dsim->connector.dev)
+ drm_helper_hpd_irq_event(dsim->connector.dev);
+#endif
+
+ return 0;
+}
+
+static int sec_mipi_dsim_host_detach(struct mipi_dsi_host *host,
+ struct mipi_dsi_device *dsi)
+{
+ struct sec_mipi_dsim *dsim = to_sec_mipi_dsim(host);
+
+ if (WARN_ON(!dsim->next && !dsim->panel))
+ return -ENODEV;
+
+ /* clear the saved dsi parameters */
+ dsim->lanes = 0;
+ dsim->channel = 0;
+ dsim->format = 0;
+ dsim->mode_flags = 0;
+
+ return 0;
+}
+
+static void sec_mipi_dsim_config_cmd_lpm(struct sec_mipi_dsim *dsim,
+ bool enable)
+{
+ uint32_t escmode;
+
+ escmode = dsim_read(dsim, DSIM_ESCMODE);
+
+ if (enable)
+ escmode |= ESCMODE_CMDLPDT;
+ else
+ escmode &= ~ESCMODE_CMDLPDT;
+
+ dsim_write(dsim, escmode, DSIM_ESCMODE);
+}
+
+static void sec_mipi_dsim_write_pl_to_sfr_fifo(struct sec_mipi_dsim *dsim,
+ const void *payload,
+ size_t length)
+{
+ uint32_t pl_data;
+
+ if (!length)
+ return;
+
+ while (length >= 4) {
+ pl_data = get_unaligned_le32(payload);
+ dsim_write(dsim, pl_data, DSIM_PAYLOAD);
+ payload += 4;
+ length -= 4;
+ }
+
+ pl_data = 0;
+ switch (length) {
+ case 3:
+ pl_data |= ((u8 *)payload)[2] << 16;
+ case 2:
+ pl_data |= ((u8 *)payload)[1] << 8;
+ case 1:
+ pl_data |= ((u8 *)payload)[0];
+ dsim_write(dsim, pl_data, DSIM_PAYLOAD);
+ break;
+ }
+}
+
+static void sec_mipi_dsim_write_ph_to_sfr_fifo(struct sec_mipi_dsim *dsim,
+ void *header,
+ bool use_lpm)
+{
+ uint32_t pkthdr;
+
+ pkthdr = PKTHDR_SET_DATA1(((u8 *)header)[2]) | /* WC MSB */
+ PKTHDR_SET_DATA0(((u8 *)header)[1]) | /* WC LSB */
+ PKTHDR_SET_DI(((u8 *)header)[0]); /* Data ID */
+
+ dsim_write(dsim, pkthdr, DSIM_PKTHDR);
+}
+
+static int sec_mipi_dsim_read_pl_from_sfr_fifo(struct sec_mipi_dsim *dsim,
+ void *payload,
+ size_t length)
+{
+ uint8_t data_type;
+ uint16_t word_count = 0;
+ uint32_t fifoctrl, ph, pl;
+
+ fifoctrl = dsim_read(dsim, DSIM_FIFOCTRL);
+
+ if (WARN_ON(fifoctrl & FIFOCTRL_EMPTYRX))
+ return -EINVAL;
+
+ ph = dsim_read(dsim, DSIM_RXFIFO);
+ data_type = PKTHDR_GET_DT(ph);
+ switch (data_type) {
+ case MIPI_DSI_RX_ACKNOWLEDGE_AND_ERROR_REPORT:
+ dev_err(dsim->dev, "peripheral report error: (0-7)%x, (8-15)%x\n",
+ PKTHDR_GET_DATA0(ph), PKTHDR_GET_DATA1(ph));
+ return -EPROTO;
+ case MIPI_DSI_RX_DCS_SHORT_READ_RESPONSE_2BYTE:
+ case MIPI_DSI_RX_GENERIC_SHORT_READ_RESPONSE_2BYTE:
+ if (!WARN_ON(length < 2)) {
+ ((u8 *)payload)[1] = PKTHDR_GET_DATA1(ph);
+ word_count++;
+ }
+ /* fall through */
+ case MIPI_DSI_RX_DCS_SHORT_READ_RESPONSE_1BYTE:
+ case MIPI_DSI_RX_GENERIC_SHORT_READ_RESPONSE_1BYTE:
+ ((u8 *)payload)[0] = PKTHDR_GET_DATA0(ph);
+ word_count++;
+ length = word_count;
+ break;
+ case MIPI_DSI_RX_DCS_LONG_READ_RESPONSE:
+ case MIPI_DSI_RX_GENERIC_LONG_READ_RESPONSE:
+ word_count = PKTHDR_GET_WC(ph);
+ if (word_count > length) {
+ dev_err(dsim->dev, "invalid receive buffer length\n");
+ return -EINVAL;
+ }
+
+ length = word_count;
+
+ while (word_count >= 4) {
+ pl = dsim_read(dsim, DSIM_RXFIFO);
+ ((u8 *)payload)[0] = pl & 0xff;
+ ((u8 *)payload)[1] = (pl >> 8) & 0xff;
+ ((u8 *)payload)[2] = (pl >> 16) & 0xff;
+ ((u8 *)payload)[3] = (pl >> 24) & 0xff;
+ payload += 4;
+ word_count -= 4;
+ }
+
+ if (word_count > 0) {
+ pl = dsim_read(dsim, DSIM_RXFIFO);
+
+ switch (word_count) {
+ case 3:
+ ((u8 *)payload)[2] = (pl >> 16) & 0xff;
+ case 2:
+ ((u8 *)payload)[1] = (pl >> 8) & 0xff;
+ case 1:
+ ((u8 *)payload)[0] = pl & 0xff;
+ break;
+ }
+ }
+
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return length;
+}
+
+static ssize_t sec_mipi_dsim_host_transfer(struct mipi_dsi_host *host,
+ const struct mipi_dsi_msg *msg)
+{
+ int ret;
+ bool use_lpm;
+ struct mipi_dsi_packet packet;
+ struct sec_mipi_dsim *dsim = to_sec_mipi_dsim(host);
+
+ if ((msg->rx_buf && !msg->rx_len) || (msg->rx_len && !msg->rx_buf))
+ return -EINVAL;
+
+ ret = mipi_dsi_create_packet(&packet, msg);
+ if (ret) {
+ dev_err(dsim->dev, "failed to create dsi packet: %d\n", ret);
+ return ret;
+ }
+
+ /* need to read data from peripheral */
+ if (unlikely(msg->rx_buf))
+ reinit_completion(&dsim->rx_done);
+
+ /* config LPM for CMD TX */
+ use_lpm = msg->flags & MIPI_DSI_MSG_USE_LPM ? true : false;
+ sec_mipi_dsim_config_cmd_lpm(dsim, use_lpm);
+
+ if (packet.payload_length) { /* Long Packet case */
+ reinit_completion(&dsim->pl_tx_done);
+
+ /* write packet payload */
+ sec_mipi_dsim_write_pl_to_sfr_fifo(dsim,
+ packet.payload,
+ packet.payload_length);
+
+ /* write packet header */
+ sec_mipi_dsim_write_ph_to_sfr_fifo(dsim,
+ packet.header,
+ use_lpm);
+
+ ret = wait_for_completion_timeout(&dsim->ph_tx_done,
+ MIPI_FIFO_TIMEOUT);
+ if (!ret) {
+ dev_err(dsim->dev, "wait payload tx done time out\n");
+ return -EBUSY;
+ }
+ } else {
+ reinit_completion(&dsim->ph_tx_done);
+
+ /* write packet header */
+ sec_mipi_dsim_write_ph_to_sfr_fifo(dsim,
+ packet.header,
+ use_lpm);
+
+ ret = wait_for_completion_timeout(&dsim->ph_tx_done,
+ MIPI_FIFO_TIMEOUT);
+ if (!ret) {
+ dev_err(dsim->dev, "wait pkthdr tx done time out\n");
+ return -EBUSY;
+ }
+ }
+
+ /* read packet payload */
+ if (unlikely(msg->rx_buf)) {
+ ret = wait_for_completion_timeout(&dsim->rx_done,
+ MIPI_FIFO_TIMEOUT);
+ if (!ret) {
+ dev_err(dsim->dev, "wait rx done time out\n");
+ return -EBUSY;
+ }
+
+ ret = sec_mipi_dsim_read_pl_from_sfr_fifo(dsim,
+ msg->rx_buf,
+ msg->rx_len);
+ if (ret < 0)
+ return ret;
+ }
+
+ return 0;
+}
+
+static const struct mipi_dsi_host_ops sec_mipi_dsim_host_ops = {
+ .attach = sec_mipi_dsim_host_attach,
+ .detach = sec_mipi_dsim_host_detach,
+ .transfer = sec_mipi_dsim_host_transfer,
+};
+
+static int sec_mipi_dsim_bridge_attach(struct drm_bridge *bridge)
+{
+ int ret;
+ struct sec_mipi_dsim *dsim = bridge->driver_private;
+ struct device *dev = dsim->dev;
+ struct device_node *np = dev->of_node;
+ struct device_node *endpoint, *remote;
+ struct drm_bridge *next = NULL;
+ struct drm_encoder *encoder = dsim->encoder;
+
+ /* TODO: All bridges and planes should have already been added */
+
+ /* A panel has been found, ignor other dsi devices */
+ if (dsim->panel)
+ return 0;
+
+ /* find next bridge */
+ endpoint = of_graph_get_next_endpoint(np, NULL);
+ /* At least one endpoint should be existed */
+ if (!endpoint)
+ return -ENODEV;
+
+ while(endpoint && !next) {
+ remote = of_graph_get_remote_port_parent(endpoint);
+
+ if (!remote || !of_device_is_available(remote)) {
+ of_node_put(remote);
+ endpoint = of_graph_get_next_endpoint(np, endpoint);
+ continue;
+ }
+
+ next = of_drm_find_bridge(remote);
+ if (next) {
+ /* Found */
+ of_node_put(endpoint);
+ break;
+ }
+
+ endpoint = of_graph_get_next_endpoint(np, endpoint);
+ }
+
+ /* No valid dsi device attached */
+ if (!next)
+ return -ENODEV;
+
+ /* duplicate bridges or next bridge exists */
+ WARN_ON(bridge == next || bridge->next || dsim->next);
+
+ dsim->next = next;
+ next->encoder = encoder;
+ ret = drm_bridge_attach(encoder, next, bridge);
+ if (ret) {
+ dev_err(dev, "Unable to attach bridge %s: %d\n",
+ remote->name, ret);
+ dsim->next = NULL;
+ return ret;
+ }
+
+ /* bridge chains */
+ bridge->next = next;
+
+ return 0;
+}
+
+static int sec_mipi_dsim_config_pll(struct sec_mipi_dsim *dsim)
+{
+ int ret;
+ uint32_t pllctrl = 0, status, data_lanes_en, stop;
+
+ dsim_write(dsim, 0x8000, DSIM_PLLTMR);
+
+ /* TODO: config dp/dn swap if requires */
+
+ pllctrl |= PLLCTRL_SET_PMS(dsim->pms) | PLLCTRL_PLLEN;
+ dsim_write(dsim, pllctrl, DSIM_PLLCTRL);
+
+ ret = wait_for_completion_timeout(&dsim->pll_stable, HZ / 10);
+ if (!ret) {
+ dev_err(dsim->dev, "wait for pll stable time out\n");
+ return -EBUSY;
+ }
+
+ /* wait for clk & data lanes to go to stop state */
+ mdelay(1);
+
+ data_lanes_en = (0x1 << dsim->lanes) - 1;
+ status = dsim_read(dsim, DSIM_STATUS);
+ if (!(status & STATUS_STOPSTATECLK)) {
+ dev_err(dsim->dev, "clock is not in stop state\n");
+ return -EBUSY;
+ }
+
+ stop = STATUS_GET_STOPSTATEDAT(status);
+ if ((stop & data_lanes_en) != data_lanes_en) {
+ dev_err(dsim->dev,
+ "one or more data lanes is not in stop state\n");
+ return -EBUSY;
+ }
+
+ return 0;
+}
+
+static void sec_mipi_dsim_set_main_mode(struct sec_mipi_dsim *dsim)
+{
+ uint32_t bpp, hfp_wc, hbp_wc, hsa_wc, wc;
+ uint32_t mdresol = 0, mvporch = 0, mhporch = 0, msync = 0;
+ struct videomode *vmode = &dsim->vmode;
+
+ mdresol |= MDRESOL_SET_MAINVRESOL(vmode->vactive) |
+ MDRESOL_SET_MAINHRESOL(vmode->hactive);
+ dsim_write(dsim, mdresol, DSIM_MDRESOL);
+
+ mvporch |= MVPORCH_SET_MAINVBP(vmode->vback_porch) |
+ MVPORCH_SET_STABLEVFP(vmode->vfront_porch) |
+ MVPORCH_SET_CMDALLOW(0x0);
+ dsim_write(dsim, mvporch, DSIM_MVPORCH);
+
+ bpp = mipi_dsi_pixel_format_to_bpp(dsim->format);
+
+ /* calculate hfp & hbp word counts */
+ if (!dsim->hpar) {
+ wc = DIV_ROUND_UP(vmode->hfront_porch * (bpp >> 3),
+ dsim->lanes);
+ hfp_wc = wc > MIPI_HFP_PKT_OVERHEAD ?
+ wc - MIPI_HFP_PKT_OVERHEAD : vmode->hfront_porch;
+ wc = DIV_ROUND_UP(vmode->hback_porch * (bpp >> 3),
+ dsim->lanes);
+ hbp_wc = wc > MIPI_HBP_PKT_OVERHEAD ?
+ wc - MIPI_HBP_PKT_OVERHEAD : vmode->hback_porch;
+ } else {
+ hfp_wc = dsim->hpar->hfp_wc;
+ hbp_wc = dsim->hpar->hbp_wc;
+ }
+
+ mhporch |= MHPORCH_SET_MAINHFP(hfp_wc) |
+ MHPORCH_SET_MAINHBP(hbp_wc);
+
+ dsim_write(dsim, mhporch, DSIM_MHPORCH);
+
+ /* calculate hsa word counts */
+ if (!dsim->hpar) {
+ wc = DIV_ROUND_UP(vmode->hsync_len * (bpp >> 3),
+ dsim->lanes);
+ hsa_wc = wc > MIPI_HSA_PKT_OVERHEAD ?
+ wc - MIPI_HSA_PKT_OVERHEAD : vmode->hsync_len;
+ } else
+ hsa_wc = dsim->hpar->hsa_wc;
+
+ msync |= MSYNC_SET_MAINVSA(vmode->vsync_len) |
+ MSYNC_SET_MAINHSA(hsa_wc);
+
+ dsim_write(dsim, msync, DSIM_MSYNC);
+}
+
+static void sec_mipi_dsim_config_dpi(struct sec_mipi_dsim *dsim)
+{
+ uint32_t config = 0, rgb_status = 0, data_lanes_en;
+
+ if (dsim->mode_flags & MIPI_DSI_MODE_VIDEO)
+ rgb_status &= ~RGB_STATUS_CMDMODE_INSEL;
+ else
+ rgb_status |= RGB_STATUS_CMDMODE_INSEL;
+
+ dsim_write(dsim, rgb_status, DSIM_RGB_STATUS);
+
+ if (dsim->mode_flags & MIPI_DSI_CLOCK_NON_CONTINUOUS) {
+ config |= CONFIG_NON_CONTINUOUS_CLOCK_LANE;
+ config |= CONFIG_CLKLANE_STOP_START;
+ }
+
+ if (dsim->mode_flags & MIPI_DSI_MODE_VSYNC_FLUSH)
+ config |= CONFIG_MFLUSH_VS;
+
+ /* disable EoT packets in HS mode */
+ if (dsim->mode_flags & MIPI_DSI_MODE_EOT_PACKET)
+ config |= CONFIG_EOT_R03;
+
+ if (dsim->mode_flags & MIPI_DSI_MODE_VIDEO) {
+ config |= CONFIG_VIDEOMODE;
+
+ if (dsim->mode_flags & MIPI_DSI_MODE_VIDEO_BURST)
+ config |= CONFIG_BURSTMODE;
+
+ else if (dsim->mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE)
+ config |= CONFIG_SYNCINFORM;
+
+ if (dsim->mode_flags & MIPI_DSI_MODE_VIDEO_AUTO_VERT)
+ config |= CONFIG_AUTOMODE;
+
+ if (dsim->mode_flags & MIPI_DSI_MODE_VIDEO_HSE)
+ config |= CONFIG_HSEDISABLEMODE;
+
+ if (dsim->mode_flags & MIPI_DSI_MODE_VIDEO_HFP)
+ config |= CONFIG_HFPDISABLEMODE;
+
+ if (dsim->mode_flags & MIPI_DSI_MODE_VIDEO_HBP)
+ config |= CONFIG_HBPDISABLEMODE;
+
+ if (dsim->mode_flags & MIPI_DSI_MODE_VIDEO_HSA)
+ config |= CONFIG_HSADISABLEMODE;
+ }
+
+ config |= CONFIG_SET_MAINVC(dsim->channel);
+
+ if (dsim->mode_flags & MIPI_DSI_MODE_VIDEO) {
+ switch (dsim->format) {
+ case MIPI_DSI_FMT_RGB565:
+ config |= CONFIG_SET_MAINPIXFORMAT(0x4);
+ break;
+ case MIPI_DSI_FMT_RGB666_PACKED:
+ config |= CONFIG_SET_MAINPIXFORMAT(0x5);
+ break;
+ case MIPI_DSI_FMT_RGB666:
+ config |= CONFIG_SET_MAINPIXFORMAT(0x6);
+ break;
+ case MIPI_DSI_FMT_RGB888:
+ config |= CONFIG_SET_MAINPIXFORMAT(0x7);
+ break;
+ default:
+ config |= CONFIG_SET_MAINPIXFORMAT(0x7);
+ break;
+ }
+ }
+
+ /* config data lanes number and enable lanes */
+ data_lanes_en = (0x1 << dsim->lanes) - 1;
+ config |= CONFIG_SET_NUMOFDATLANE(dsim->lanes - 1);
+ config |= CONFIG_SET_LANEEN(0x1 | data_lanes_en << 1);
+
+ dsim_write(dsim, config, DSIM_CONFIG);
+}
+
+static void sec_mipi_dsim_config_dphy(struct sec_mipi_dsim *dsim)
+{
+ struct sec_mipi_dsim_dphy_timing key = { 0 };
+ const struct sec_mipi_dsim_dphy_timing *match = NULL;
+ const struct sec_mipi_dsim_plat_data *pdata = dsim->pdata;
+ uint32_t phytiming = 0, phytiming1 = 0, phytiming2 = 0, timeout = 0;
+ uint32_t hactive, vactive;
+ struct videomode *vmode = &dsim->vmode;
+ struct drm_display_mode mode;
+
+ key.bit_clk = DIV_ROUND_CLOSEST_ULL(dsim->bit_clk, 1000);
+
+ /* '1280x720@60Hz' mode with 2 data lanes
+ * requires special fine tuning for DPHY
+ * TIMING config according to the tests.
+ */
+ if (dsim->lanes == 2) {
+ hactive = vmode->hactive;
+ vactive = vmode->vactive;
+
+ if (hactive == 1280 && vactive == 720) {
+ memset(&mode, 0x0, sizeof(mode));
+ drm_display_mode_from_videomode(vmode, &mode);
+
+ if (drm_mode_vrefresh(&mode) == 60)
+ key.bit_clk >>= 1;
+ }
+ }
+
+ match = bsearch(&key, pdata->dphy_timing, pdata->num_dphy_timing,
+ sizeof(struct sec_mipi_dsim_dphy_timing),
+ pdata->dphy_timing_cmp);
+ if (WARN_ON(!match))
+ return;
+
+ phytiming |= PHYTIMING_SET_M_TLPXCTL(match->lpx) |
+ PHYTIMING_SET_M_THSEXITCTL(match->hs_exit);
+ dsim_write(dsim, phytiming, DSIM_PHYTIMING);
+
+ phytiming1 |= PHYTIMING1_SET_M_TCLKPRPRCTL(match->clk_prepare) |
+ PHYTIMING1_SET_M_TCLKZEROCTL(match->clk_zero) |
+ PHYTIMING1_SET_M_TCLKPOSTCTL(match->clk_post) |
+ PHYTIMING1_SET_M_TCLKTRAILCTL(match->clk_trail);
+ dsim_write(dsim, phytiming1, DSIM_PHYTIMING1);
+
+ phytiming2 |= PHYTIMING2_SET_M_THSPRPRCTL(match->hs_prepare) |
+ PHYTIMING2_SET_M_THSZEROCTL(match->hs_zero) |
+ PHYTIMING2_SET_M_THSTRAILCTL(match->hs_trail);
+ dsim_write(dsim, phytiming2, DSIM_PHYTIMING2);
+
+ timeout |= TIMEOUT_SET_BTAOUT(0xff) |
+ TIMEOUT_SET_LPDRTOUT(0xff);
+ dsim_write(dsim, timeout, DSIM_TIMEOUT);
+}
+
+static void sec_mipi_dsim_init_fifo_pointers(struct sec_mipi_dsim *dsim)
+{
+ uint32_t fifoctrl, fifo_ptrs;
+
+ fifoctrl = dsim_read(dsim, DSIM_FIFOCTRL);
+
+ fifo_ptrs = FIFOCTRL_NINITRX |
+ FIFOCTRL_NINITSFR |
+ FIFOCTRL_NINITI80 |
+ FIFOCTRL_NINITSUB |
+ FIFOCTRL_NINITMAIN;
+
+ fifoctrl &= ~fifo_ptrs;
+ dsim_write(dsim, fifoctrl, DSIM_FIFOCTRL);
+ udelay(500);
+
+ fifoctrl |= fifo_ptrs;
+ dsim_write(dsim, fifoctrl, DSIM_FIFOCTRL);
+ udelay(500);
+}
+
+static void sec_mipi_dsim_config_clkctrl(struct sec_mipi_dsim *dsim)
+{
+ uint32_t clkctrl = 0, data_lanes_en;
+ uint32_t byte_clk, esc_prescaler;
+
+ clkctrl |= CLKCTRL_TXREQUESTHSCLK;
+
+ /* using 1.5Gbps PHY */
+ clkctrl |= CLKCTRL_DPHY_SEL_1P5G;
+
+ clkctrl |= CLKCTRL_ESCCLKEN;
+
+ clkctrl &= ~CLKCTRL_PLLBYPASS;
+
+ clkctrl |= CLKCTRL_BYTECLKSRC_DPHY_PLL;
+
+ clkctrl |= CLKCTRL_BYTECLKEN;
+
+ data_lanes_en = (0x1 << dsim->lanes) - 1;
+ clkctrl |= CLKCTRL_SET_LANEESCCLKEN(0x1 | data_lanes_en << 1);
+
+ /* calculate esc prescaler from byte clock:
+ * EscClk = ByteClk / EscPrescaler;
+ */
+ byte_clk = dsim->bit_clk >> 3;
+ esc_prescaler = DIV_ROUND_UP(byte_clk, MAX_ESC_CLK_FREQ);
+ clkctrl |= CLKCTRL_SET_ESCPRESCALER(esc_prescaler);
+
+ dsim_write(dsim, clkctrl, DSIM_CLKCTRL);
+}
+
+static void sec_mipi_dsim_set_standby(struct sec_mipi_dsim *dsim,
+ bool standby)
+{
+ uint32_t mdresol = 0;
+
+ mdresol = dsim_read(dsim, DSIM_MDRESOL);
+
+ if (standby)
+ mdresol |= MDRESOL_MAINSTANDBY;
+ else
+ mdresol &= ~MDRESOL_MAINSTANDBY;
+
+ dsim_write(dsim, mdresol, DSIM_MDRESOL);
+}
+
+struct dsim_pll_pms *sec_mipi_dsim_calc_pmsk(struct sec_mipi_dsim *dsim)
+{
+ uint32_t p, m, s;
+ uint32_t best_p, best_m, best_s;
+ uint32_t fin, fout;
+ uint32_t s_pow_2, raw_s;
+ uint64_t mfin, pfvco, pfout, psfout;
+ uint32_t delta, best_delta = ~0U;
+ struct dsim_pll_pms *pll_pms;
+ struct device *dev = dsim->dev;
+ const struct sec_mipi_dsim_plat_data *pdata = dsim->pdata;
+ struct sec_mipi_dsim_pll dpll = *pdata->dphy_pll;
+ struct sec_mipi_dsim_range *prange = &dpll.p;
+ struct sec_mipi_dsim_range *mrange = &dpll.m;
+ struct sec_mipi_dsim_range *srange = &dpll.s;
+ struct sec_mipi_dsim_range *krange = &dpll.k;
+ struct sec_mipi_dsim_range *fvco_range = &dpll.fvco;
+ struct sec_mipi_dsim_range *fpref_range = &dpll.fpref;
+ struct sec_mipi_dsim_range pr_new = *prange;
+ struct sec_mipi_dsim_range sr_new = *srange;
+
+ pll_pms = devm_kzalloc(dev, sizeof(*pll_pms), GFP_KERNEL);
+ if (!pll_pms) {
+ dev_err(dev, "Unable to allocate 'pll_pms'\n");
+ return ERR_PTR(-ENOMEM);
+ }
+
+ fout = dsim->bit_clk;
+ fin = dsim->pref_clk;
+
+ /* TODO: ignore 'k' for PMS calculation,
+ * only use 'p', 'm' and 's' to generate
+ * the requested PLL output clock.
+ */
+ krange->min = 0;
+ krange->max = 0;
+
+ /* narrow 'p' range via 'Fpref' limitation:
+ * Fpref : [2MHz ~ 30MHz] (Fpref = Fin / p)
+ */
+ prange->min = max(prange->min, DIV_ROUND_UP(fin, fpref_range->max));
+ prange->max = min(prange->max, fin / fpref_range->min);
+
+ /* narrow 'm' range via 'Fvco' limitation:
+ * Fvco: [1050MHz ~ 2100MHz] (Fvco = ((m + k / 65536) * Fin) / p)
+ * So, m = Fvco * p / Fin and Fvco > Fin;
+ */
+ pfvco = fvco_range->min * prange->min;
+ mrange->min = max_t(uint32_t, mrange->min,
+ DIV_ROUND_UP_ULL(pfvco, fin));
+ pfvco = fvco_range->max * prange->max;
+ mrange->max = min_t(uint32_t, mrange->max,
+ DIV_ROUND_UP_ULL(pfvco, fin));
+
+ dev_dbg(dev, "p: min = %u, max = %u, "
+ "m: min = %u, max = %u, "
+ "s: min = %u, max = %u\n",
+ prange->min, prange->max, mrange->min,
+ mrange->max, srange->min, srange->max);
+
+ /* first determine 'm', then can determine 'p', last determine 's' */
+ for (m = mrange->min; m <= mrange->max; m++) {
+ /* p = m * Fin / Fvco */
+ mfin = m * fin;
+ pr_new.min = max_t(uint32_t, prange->min,
+ DIV_ROUND_UP_ULL(mfin, fvco_range->max));
+ pr_new.max = min_t(uint32_t, prange->max,
+ (mfin / fvco_range->min));
+
+ if (pr_new.max < pr_new.min || pr_new.min < prange->min)
+ continue;
+
+ for (p = pr_new.min; p <= pr_new.max; p++) {
+ /* s = order_pow_of_two((m * Fin) / (p * Fout)) */
+ pfout = p * fout;
+ raw_s = DIV_ROUND_CLOSEST_ULL(mfin, pfout);
+
+ s_pow_2 = rounddown_pow_of_two(raw_s);
+ sr_new.min = max_t(uint32_t, srange->min,
+ order_base_2(s_pow_2));
+
+ s_pow_2 = roundup_pow_of_two(DIV_ROUND_CLOSEST_ULL(mfin, pfout));
+ sr_new.max = min_t(uint32_t, srange->max,
+ order_base_2(s_pow_2));
+
+ if (sr_new.max < sr_new.min || sr_new.min < srange->min)
+ continue;
+
+ for (s = sr_new.min; s <= sr_new.max; s++) {
+ /* fout = m * Fin / (p * 2^s) */
+ psfout = pfout * (1 << s);
+ delta = abs(psfout - mfin);
+ if (delta < best_delta) {
+ best_p = p;
+ best_m = m;
+ best_s = s;
+ best_delta = delta;
+ }
+ }
+ }
+ }
+
+ if (best_delta == ~0U)
+ return ERR_PTR(-EINVAL);
+
+ pll_pms->p = best_p;
+ pll_pms->m = best_m;
+ pll_pms->s = best_s;
+
+ dev_dbg(dev, "fout = %u, fin = %u, m = %u, "
+ "p = %u, s = %u, best_delta = %u\n",
+ fout, fin, pll_pms->m, pll_pms->p, pll_pms->s, best_delta);
+
+ return pll_pms;
+}
+
+int sec_mipi_dsim_check_pll_out(void *driver_private,
+ const struct drm_display_mode *mode)
+{
+ int bpp;
+ uint32_t pix_clk, bit_clk;
+ struct sec_mipi_dsim *dsim = driver_private;
+ const struct sec_mipi_dsim_plat_data *pdata = dsim->pdata;
+ const struct dsim_hblank_par *hpar;
+ const struct dsim_pll_pms *pmsk;
+
+ bpp = mipi_dsi_pixel_format_to_bpp(dsim->format);
+ if (bpp < 0)
+ return -EINVAL;
+
+ pix_clk = mode->clock;
+ bit_clk = DIV_ROUND_UP(pix_clk * bpp, dsim->lanes);
+
+ if (bit_clk * 1000 > pdata->max_data_rate) {
+ dev_err(dsim->dev,
+ "reuest bit clk freq exceeds lane's maximum value\n");
+ return -EINVAL;
+ }
+
+ dsim->pix_clk = pix_clk;
+ dsim->bit_clk = bit_clk;
+ dsim->hpar = NULL;
+
+ pmsk = sec_mipi_dsim_calc_pmsk(dsim);
+ if (IS_ERR(pmsk)) {
+ dev_err(dsim->dev,
+ "failed to get pmsk for: fin = %u, fout = %u\n",
+ dsim->pref_clk, dsim->bit_clk);
+ return -EINVAL;
+ }
+
+ dsim->pms = PLLCTRL_SET_P(pmsk->p) |
+ PLLCTRL_SET_M(pmsk->m) |
+ PLLCTRL_SET_S(pmsk->s);
+
+ if (dsim->mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE) {
+ hpar = sec_mipi_dsim_get_hblank_par(mode->name,
+ mode->vrefresh,
+ dsim->lanes);
+ dsim->hpar = hpar;
+ if (!hpar)
+ dev_dbg(dsim->dev, "no pre-exist hpar can be used\n");
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL(sec_mipi_dsim_check_pll_out);
+
+static void sec_mipi_dsim_bridge_enable(struct drm_bridge *bridge)
+{
+ int ret;
+ struct sec_mipi_dsim *dsim = bridge->driver_private;
+
+ /* At this moment, the dsim bridge's preceding encoder has
+ * already been enabled. So the dsim can be configed here
+ */
+
+ /* config main display mode */
+ sec_mipi_dsim_set_main_mode(dsim);
+
+ /* config dsim dpi */
+ sec_mipi_dsim_config_dpi(dsim);
+
+ /* config dsim pll */
+ ret = sec_mipi_dsim_config_pll(dsim);
+ if (ret) {
+ dev_err(dsim->dev, "dsim pll config failed: %d\n", ret);
+ return;
+ }
+
+ /* config dphy timings */
+ sec_mipi_dsim_config_dphy(dsim);
+
+ /* initialize FIFO pointers */
+ sec_mipi_dsim_init_fifo_pointers(dsim);
+
+ /* prepare panel if exists */
+ if (dsim->panel) {
+ ret = drm_panel_prepare(dsim->panel);
+ if (unlikely(ret)) {
+ dev_err(dsim->dev, "panel prepare failed: %d\n", ret);
+ return;
+ }
+ }
+
+ /* config esc clock, byte clock and etc */
+ sec_mipi_dsim_config_clkctrl(dsim);
+
+ /* enable panel if exists */
+ if (dsim->panel) {
+ ret = drm_panel_enable(dsim->panel);
+ if (unlikely(ret)) {
+ dev_err(dsim->dev, "panel enable failed: %d\n", ret);
+ goto panel_unprepare;
+ }
+ }
+
+ /* enable data transfer of dsim */
+ sec_mipi_dsim_set_standby(dsim, true);
+
+ return;
+
+panel_unprepare:
+ ret = drm_panel_unprepare(dsim->panel);
+ if (unlikely(ret))
+ dev_err(dsim->dev, "panel unprepare failed: %d\n", ret);
+}
+
+static void sec_mipi_dsim_disable_clkctrl(struct sec_mipi_dsim *dsim)
+{
+ uint32_t clkctrl;
+
+ clkctrl = dsim_read(dsim, DSIM_CLKCTRL);
+
+ clkctrl &= ~CLKCTRL_TXREQUESTHSCLK;
+
+ clkctrl &= ~CLKCTRL_ESCCLKEN;
+
+ clkctrl &= ~CLKCTRL_BYTECLKEN;
+
+ dsim_write(dsim, clkctrl, DSIM_CLKCTRL);
+}
+
+static void sec_mipi_dsim_disable_pll(struct sec_mipi_dsim *dsim)
+{
+ uint32_t pllctrl;
+
+ pllctrl = dsim_read(dsim, DSIM_PLLCTRL);
+
+ pllctrl &= ~PLLCTRL_PLLEN;
+
+ dsim_write(dsim, pllctrl, DSIM_PLLCTRL);
+}
+
+static void sec_mipi_dsim_bridge_disable(struct drm_bridge *bridge)
+{
+ int ret;
+ struct sec_mipi_dsim *dsim = bridge->driver_private;
+
+ /* disable panel if exists */
+ if (dsim->panel) {
+ ret = drm_panel_disable(dsim->panel);
+ if (unlikely(ret))
+ dev_err(dsim->dev, "panel disable failed: %d\n", ret);
+ }
+
+ /* disable data transfer of dsim */
+ sec_mipi_dsim_set_standby(dsim, false);
+
+ /* disable esc clock & byte clock */
+ sec_mipi_dsim_disable_clkctrl(dsim);
+
+ /* disable dsim pll */
+ sec_mipi_dsim_disable_pll(dsim);
+
+ /* unprepare panel if exists */
+ if (dsim->panel) {
+ ret = drm_panel_unprepare(dsim->panel);
+ if (unlikely(ret))
+ dev_err(dsim->dev, "panel unprepare failed: %d\n", ret);
+ }
+}
+
+static bool sec_mipi_dsim_bridge_mode_fixup(struct drm_bridge *bridge,
+ const struct drm_display_mode *mode,
+ struct drm_display_mode *adjusted_mode)
+{
+ int private_flags;
+ struct sec_mipi_dsim *dsim = bridge->driver_private;
+
+ /* Since mipi dsi cannot do color conversion,
+ * so the pixel format output by mipi dsi should
+ * be the same with the pixel format recieved by
+ * mipi dsi. And the pixel format information needs
+ * to be passed to CRTC to be checked with the CRTC
+ * attached plane fb pixel format.
+ */
+ switch (dsim->format) {
+ case MIPI_DSI_FMT_RGB888:
+ private_flags = MEDIA_BUS_FMT_RGB888_1X24;
+ break;
+ case MIPI_DSI_FMT_RGB666:
+ private_flags = MEDIA_BUS_FMT_RGB666_1X24_CPADHI;
+ break;
+ case MIPI_DSI_FMT_RGB666_PACKED:
+ private_flags = MEDIA_BUS_FMT_RGB666_1X18;
+ break;
+ case MIPI_DSI_FMT_RGB565:
+ private_flags = MEDIA_BUS_FMT_RGB565_1X16;
+ break;
+ default:
+ return false;
+ }
+
+ adjusted_mode->private_flags = private_flags;
+
+ /* the 'bus_flags' in connector's display_info is useless
+ * for mipi dsim, since dsim only sends packets with no
+ * polarities information in the packets. But the dsim
+ * host has some polarities requirements for the CRTC:
+ * dsim only can accpet active high Vsync, Hsync and DE
+ * signals.
+ */
+ if (adjusted_mode->flags & DRM_MODE_FLAG_NHSYNC) {
+ adjusted_mode->flags &= ~DRM_MODE_FLAG_NHSYNC;
+ adjusted_mode->flags |= DRM_MODE_FLAG_PHSYNC;
+ }
+
+ if (adjusted_mode->flags & DRM_MODE_FLAG_NVSYNC) {
+ adjusted_mode->flags &= ~DRM_MODE_FLAG_NVSYNC;
+ adjusted_mode->flags |= DRM_MODE_FLAG_PVSYNC;
+ }
+
+ return true;
+}
+
+static void sec_mipi_dsim_bridge_mode_set(struct drm_bridge *bridge,
+ struct drm_display_mode *mode,
+ struct drm_display_mode *adjusted_mode)
+{
+ struct sec_mipi_dsim *dsim = bridge->driver_private;
+
+ /* This hook is called when the display pipe is completely
+ * off. And since the pm runtime is implemented, the dsim
+ * hardware cannot be accessed at this moment. So move all
+ * the mode_set config to ->enable() hook.
+ * And this hook is called only when 'mode_changed' is true,
+ * so it is called not every time atomic commit.
+ */
+
+ /* workaround for CEA standard mode "1280x720@60"
+ * display on 4 data lanes with Non-burst with sync
+ * pulse DSI mode, since use the standard horizontal
+ * timings cannot display correctly. And this code
+ * cannot be put into the dsim Bridge's mode_fixup,
+ * since the DSI device lane number change always
+ * happens after that.
+ */
+ if (!strcmp(mode->name, "1280x720") &&
+ mode->vrefresh == 60 &&
+ dsim->lanes == 4 &&
+ dsim->mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE) {
+ adjusted_mode->hsync_start += 2;
+ adjusted_mode->hsync_end += 2;
+ adjusted_mode->htotal += 2;
+ }
+
+ drm_display_mode_to_videomode(adjusted_mode, &dsim->vmode);
+}
+
+static const struct drm_bridge_funcs sec_mipi_dsim_bridge_funcs = {
+ .attach = sec_mipi_dsim_bridge_attach,
+ .enable = sec_mipi_dsim_bridge_enable,
+ .disable = sec_mipi_dsim_bridge_disable,
+ .mode_set = sec_mipi_dsim_bridge_mode_set,
+ .mode_fixup = sec_mipi_dsim_bridge_mode_fixup,
+};
+
+void sec_mipi_dsim_suspend(struct device *dev)
+{
+ struct sec_mipi_dsim *dsim = dev_get_drvdata(dev);
+
+ /* TODO: add dsim reset */
+
+ clk_disable_unprepare(dsim->clk_cfg);
+
+ clk_disable_unprepare(dsim->clk_pllref);
+}
+EXPORT_SYMBOL(sec_mipi_dsim_suspend);
+
+void sec_mipi_dsim_resume(struct device *dev)
+{
+ struct sec_mipi_dsim *dsim = dev_get_drvdata(dev);
+
+ clk_prepare_enable(dsim->clk_pllref);
+
+ clk_prepare_enable(dsim->clk_cfg);
+
+ sec_mipi_dsim_irq_init(dsim);
+
+ /* TODO: add dsim de-reset */
+}
+EXPORT_SYMBOL(sec_mipi_dsim_resume);
+
+static void __maybe_unused sec_mipi_dsim_irq_mask(struct sec_mipi_dsim *dsim,
+ int irq_idx)
+{
+ uint32_t intmsk;
+
+ intmsk = dsim_read(dsim, DSIM_INTMSK);
+
+ switch (irq_idx) {
+ case PLLSTABLE:
+ intmsk |= INTMSK_MSKPLLSTABLE;
+ break;
+ case SWRSTRELEASE:
+ intmsk |= INTMSK_MSKSWRELEASE;
+ break;
+ case SFRPLFIFOEMPTY:
+ intmsk |= INTMSK_MSKSFRPLFIFOEMPTY;
+ break;
+ case SFRPHFIFOEMPTY:
+ intmsk |= INTMSK_MSKSFRPHFIFOEMPTY;
+ break;
+ case FRAMEDONE:
+ intmsk |= INTMSK_MSKFRAMEDONE;
+ break;
+ case LPDRTOUT:
+ intmsk |= INTMSK_MSKLPDRTOUT;
+ break;
+ case TATOUT:
+ intmsk |= INTMSK_MSKTATOUT;
+ break;
+ case RXDATDONE:
+ intmsk |= INTMSK_MSKRXDATDONE;
+ break;
+ case RXTE:
+ intmsk |= INTMSK_MSKRXTE;
+ break;
+ case RXACK:
+ intmsk |= INTMSK_MSKRXACK;
+ break;
+ default:
+ /* unsupported irq */
+ return;
+ }
+
+ writel(intmsk, dsim->base + DSIM_INTMSK);
+}
+
+static void sec_mipi_dsim_irq_unmask(struct sec_mipi_dsim *dsim,
+ int irq_idx)
+{
+ uint32_t intmsk;
+
+ intmsk = dsim_read(dsim, DSIM_INTMSK);
+
+ switch (irq_idx) {
+ case PLLSTABLE:
+ intmsk &= ~INTMSK_MSKPLLSTABLE;
+ break;
+ case SWRSTRELEASE:
+ intmsk &= ~INTMSK_MSKSWRELEASE;
+ break;
+ case SFRPLFIFOEMPTY:
+ intmsk &= ~INTMSK_MSKSFRPLFIFOEMPTY;
+ break;
+ case SFRPHFIFOEMPTY:
+ intmsk &= ~INTMSK_MSKSFRPHFIFOEMPTY;
+ break;
+ case FRAMEDONE:
+ intmsk &= ~INTMSK_MSKFRAMEDONE;
+ break;
+ case LPDRTOUT:
+ intmsk &= ~INTMSK_MSKLPDRTOUT;
+ break;
+ case TATOUT:
+ intmsk &= ~INTMSK_MSKTATOUT;
+ break;
+ case RXDATDONE:
+ intmsk &= ~INTMSK_MSKRXDATDONE;
+ break;
+ case RXTE:
+ intmsk &= ~INTMSK_MSKRXTE;
+ break;
+ case RXACK:
+ intmsk &= ~INTMSK_MSKRXACK;
+ break;
+ default:
+ /* unsupported irq */
+ return;
+ }
+
+ dsim_write(dsim, intmsk, DSIM_INTMSK);
+}
+
+/* write 1 clear irq */
+static void sec_mipi_dsim_irq_clear(struct sec_mipi_dsim *dsim,
+ int irq_idx)
+{
+ uint32_t intsrc = 0;
+
+ switch (irq_idx) {
+ case PLLSTABLE:
+ intsrc |= INTSRC_PLLSTABLE;
+ break;
+ case SWRSTRELEASE:
+ intsrc |= INTSRC_SWRSTRELEASE;
+ break;
+ case SFRPLFIFOEMPTY:
+ intsrc |= INTSRC_SFRPLFIFOEMPTY;
+ break;
+ case SFRPHFIFOEMPTY:
+ intsrc |= INTSRC_SFRPHFIFOEMPTY;
+ break;
+ case FRAMEDONE:
+ intsrc |= INTSRC_FRAMEDONE;
+ break;
+ case LPDRTOUT:
+ intsrc |= INTSRC_LPDRTOUT;
+ break;
+ case TATOUT:
+ intsrc |= INTSRC_TATOUT;
+ break;
+ case RXDATDONE:
+ intsrc |= INTSRC_RXDATDONE;
+ break;
+ case RXTE:
+ intsrc |= INTSRC_RXTE;
+ break;
+ case RXACK:
+ intsrc |= INTSRC_RXACK;
+ break;
+ default:
+ /* unsupported irq */
+ return;
+ }
+
+ dsim_write(dsim, intsrc, DSIM_INTSRC);
+}
+
+static void sec_mipi_dsim_irq_init(struct sec_mipi_dsim *dsim)
+{
+ sec_mipi_dsim_irq_unmask(dsim, PLLSTABLE);
+ sec_mipi_dsim_irq_unmask(dsim, SWRSTRELEASE);
+
+ if (dsim->panel) {
+ sec_mipi_dsim_irq_unmask(dsim, SFRPLFIFOEMPTY);
+ sec_mipi_dsim_irq_unmask(dsim, SFRPHFIFOEMPTY);
+ sec_mipi_dsim_irq_unmask(dsim, LPDRTOUT);
+ sec_mipi_dsim_irq_unmask(dsim, TATOUT);
+ sec_mipi_dsim_irq_unmask(dsim, RXDATDONE);
+ sec_mipi_dsim_irq_unmask(dsim, RXTE);
+ sec_mipi_dsim_irq_unmask(dsim, RXACK);
+ }
+}
+
+static irqreturn_t sec_mipi_dsim_irq_handler(int irq, void *data)
+{
+ uint32_t intsrc, status;
+ struct sec_mipi_dsim *dsim = data;
+
+ intsrc = dsim_read(dsim, DSIM_INTSRC);
+ status = dsim_read(dsim, DSIM_STATUS);
+
+ if (WARN_ON(!intsrc)) {
+ dev_err(dsim->dev, "interrupt is not from dsim\n");
+ return IRQ_NONE;
+ }
+
+ if (WARN_ON(!(intsrc & INTSRC_MASK))) {
+ dev_warn(dsim->dev, "unenable irq happens: %#x\n", intsrc);
+ /* just clear irqs */
+ dsim_write(dsim, intsrc, DSIM_INTSRC);
+ return IRQ_NONE;
+ }
+
+ if (intsrc & INTSRC_PLLSTABLE) {
+ WARN_ON(!(status & STATUS_PLLSTABLE));
+ sec_mipi_dsim_irq_clear(dsim, PLLSTABLE);
+ complete(&dsim->pll_stable);
+ }
+
+ if (intsrc & INTSRC_SWRSTRELEASE)
+ sec_mipi_dsim_irq_clear(dsim, SWRSTRELEASE);
+
+ if (intsrc & INTSRC_SFRPLFIFOEMPTY) {
+ sec_mipi_dsim_irq_clear(dsim, SFRPLFIFOEMPTY);
+ complete(&dsim->pl_tx_done);
+ }
+
+ if (intsrc & INTSRC_SFRPHFIFOEMPTY) {
+ sec_mipi_dsim_irq_clear(dsim, SFRPHFIFOEMPTY);
+ complete(&dsim->ph_tx_done);
+ }
+
+ if (WARN_ON(intsrc & INTSRC_LPDRTOUT)) {
+ sec_mipi_dsim_irq_clear(dsim, LPDRTOUT);
+ dev_warn(dsim->dev, "LP RX timeout\n");
+ }
+
+ if (WARN_ON(intsrc & INTSRC_TATOUT)) {
+ sec_mipi_dsim_irq_clear(dsim, TATOUT);
+ dev_warn(dsim->dev, "Turns around Acknowledge timeout\n");
+ }
+
+ if (intsrc & INTSRC_RXDATDONE) {
+ sec_mipi_dsim_irq_clear(dsim, RXDATDONE);
+ complete(&dsim->rx_done);
+ }
+
+ if (intsrc & INTSRC_RXTE) {
+ sec_mipi_dsim_irq_clear(dsim, RXTE);
+ dev_dbg(dsim->dev, "TE Rx trigger received\n");
+ }
+
+ if (intsrc & INTSRC_RXACK) {
+ sec_mipi_dsim_irq_clear(dsim, RXACK);
+ dev_dbg(dsim->dev, "ACK Rx trigger received\n");
+ }
+
+ return IRQ_HANDLED;
+}
+
+static int sec_mipi_dsim_connector_get_modes(struct drm_connector *connector)
+{
+ struct sec_mipi_dsim *dsim = conn_to_sec_mipi_dsim(connector);
+
+ if (WARN_ON(!dsim->panel))
+ return -ENODEV;
+
+ return drm_panel_get_modes(dsim->panel);
+}
+
+static const struct drm_connector_helper_funcs
+ sec_mipi_dsim_connector_helper_funcs = {
+ .get_modes = sec_mipi_dsim_connector_get_modes,
+};
+
+static enum drm_connector_status
+ sec_mipi_dsim_connector_detect(struct drm_connector *connector,
+ bool force)
+{
+ /* TODO: add support later */
+
+ return connector_status_connected;
+}
+
+static const struct drm_connector_funcs sec_mipi_dsim_connector_funcs = {
+ .detect = sec_mipi_dsim_connector_detect,
+ .fill_modes = drm_helper_probe_single_connector_modes,
+ .destroy = drm_connector_cleanup,
+ .reset = drm_atomic_helper_connector_reset,
+ .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
+ .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
+};
+
+int sec_mipi_dsim_bind(struct device *dev, struct device *master, void *data,
+ struct drm_encoder *encoder, struct resource *res,
+ int irq, const struct sec_mipi_dsim_plat_data *pdata)
+{
+ int ret, version;
+ struct drm_device *drm_dev = data;
+ struct drm_bridge *bridge;
+ struct drm_connector *connector;
+ struct sec_mipi_dsim *dsim;
+
+ dev_dbg(dev, "sec-dsim bridge bind begin\n");
+
+ dsim = devm_kzalloc(dev, sizeof(*dsim), GFP_KERNEL);
+ if (!dsim) {
+ dev_err(dev, "Unable to allocate 'dsim'\n");
+ return -ENOMEM;
+ }
+
+ dsim->dev = dev;
+ dsim->irq = irq;
+ dsim->pdata = pdata;
+ dsim->encoder = encoder;
+
+ dsim->dsi_host.ops = &sec_mipi_dsim_host_ops;
+ dsim->dsi_host.dev = dev;
+
+ dsim->base = devm_ioremap_resource(dev, res);
+ if (IS_ERR(dsim->base))
+ return PTR_ERR(dsim->base);
+
+ dsim->clk_pllref = devm_clk_get(dev, "pll-ref");
+ if (IS_ERR(dsim->clk_pllref)) {
+ ret = PTR_ERR(dsim->clk_pllref);
+ dev_err(dev, "Unable to get phy pll reference clock: %d\n", ret);
+ return ret;
+ }
+
+ dsim->clk_cfg = devm_clk_get(dev, "cfg");
+ if (IS_ERR(dsim->clk_cfg)) {
+ ret = PTR_ERR(dsim->clk_cfg);
+ dev_err(dev, "Unable to get configuration clock: %d\n", ret);
+ return ret;
+ }
+
+ clk_prepare_enable(dsim->clk_cfg);
+ version = dsim_read(dsim, DSIM_VERSION);
+ WARN_ON(version != pdata->version);
+ clk_disable_unprepare(dsim->clk_cfg);
+
+ dev_info(dev, "version number is %#x\n", version);
+
+ /* set suitable rate for phy ref clock */
+ ret = sec_mipi_dsim_set_pref_rate(dsim);
+ if (ret) {
+ dev_err(dev, "failed to set pll ref clock rate\n");
+ return ret;
+ }
+
+ ret = devm_request_irq(dev, dsim->irq,
+ sec_mipi_dsim_irq_handler,
+ 0, dev_name(dev), dsim);
+ if (ret) {
+ dev_err(dev, "failed to request dsim irq: %d\n", ret);
+ return ret;
+ }
+
+ init_completion(&dsim->pll_stable);
+ init_completion(&dsim->ph_tx_done);
+ init_completion(&dsim->pl_tx_done);
+ init_completion(&dsim->rx_done);
+
+ /* Initialize and attach sec dsim bridge */
+ bridge = devm_kzalloc(dev, sizeof(*bridge), GFP_KERNEL);
+ if (!bridge) {
+ dev_err(dev, "Unable to allocate 'bridge'\n");
+ return -ENOMEM;
+ }
+
+ /* mipi dsi host needs to be registered before bridge attach, since:
+ * 1. Have Panel
+ * The 'mipi_dsi_host_register' will allocate a mipi_dsi_device
+ * if the dsi host node has a panel child node in DTB. And dsi
+ * host ->attach() will be called in panel's probe().
+ *
+ * 2. Have Bridge
+ * The dsi host ->attach() will be called through the below
+ * 'drm_bridge_attach()' which will attach next bridge in a
+ * chain.
+ */
+ ret = mipi_dsi_host_register(&dsim->dsi_host);
+ if (ret) {
+ dev_err(dev, "Unable to register mipi dsi host: %d\n", ret);
+ return ret;
+ }
+
+ dsim->bridge = bridge;
+ bridge->driver_private = dsim;
+ bridge->funcs = &sec_mipi_dsim_bridge_funcs;
+ bridge->of_node = dev->of_node;
+ bridge->encoder = encoder;
+ encoder->bridge = bridge;
+
+ dev_set_drvdata(dev, dsim);
+
+ /* attach sec dsim bridge and its next bridge if exists */
+ ret = drm_bridge_attach(encoder, bridge, NULL);
+ if (ret) {
+ dev_err(dev, "Failed to attach bridge: %s\n", dev_name(dev));
+ mipi_dsi_host_unregister(&dsim->dsi_host);
+ return ret;
+ }
+
+ if (dsim->panel) {
+ /* A panel has been attached */
+ connector = &dsim->connector;
+
+ drm_connector_helper_add(connector,
+ &sec_mipi_dsim_connector_helper_funcs);
+ ret = drm_connector_init(drm_dev, connector,
+ &sec_mipi_dsim_connector_funcs,
+ DRM_MODE_CONNECTOR_DSI);
+ if (ret)
+ goto host_unregister;
+
+ /* TODO */
+ connector->dpms = DRM_MODE_DPMS_OFF;
+
+ ret = drm_mode_connector_attach_encoder(connector, encoder);
+ if (ret)
+ goto cleanup_connector;
+
+ ret = drm_panel_attach(dsim->panel, connector);
+ if (ret)
+ goto cleanup_connector;
+ }
+
+ dev_dbg(dev, "sec-dsim bridge bind end\n");
+
+ return 0;
+
+cleanup_connector:
+ drm_connector_cleanup(connector);
+host_unregister:
+ mipi_dsi_host_unregister(&dsim->dsi_host);
+ return ret;
+}
+EXPORT_SYMBOL(sec_mipi_dsim_bind);
+
+void sec_mipi_dsim_unbind(struct device *dev, struct device *master, void *data)
+{
+ struct sec_mipi_dsim *dsim = dev_get_drvdata(dev);
+
+ if (dsim->panel) {
+ drm_panel_detach(dsim->panel);
+ drm_connector_cleanup(&dsim->connector);
+ dsim->panel = NULL;
+ }
+
+ mipi_dsi_host_unregister(&dsim->dsi_host);
+}
+EXPORT_SYMBOL(sec_mipi_dsim_unbind);
+
+MODULE_DESCRIPTION("Samsung MIPI DSI Host Controller bridge driver");
+MODULE_AUTHOR("Fancy Fang <chen.fang@nxp.com>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/drm/cirrus/cirrus_mode.c b/drivers/gpu/drm/cirrus/cirrus_mode.c
index 130483f2cd7f..c91b9b054e3f 100644
--- a/drivers/gpu/drm/cirrus/cirrus_mode.c
+++ b/drivers/gpu/drm/cirrus/cirrus_mode.c
@@ -463,7 +463,7 @@ static struct drm_encoder *cirrus_connector_best_encoder(struct drm_connector
int enc_id = connector->encoder_ids[0];
/* pick the encoder ids */
if (enc_id)
- return drm_encoder_find(connector->dev, enc_id);
+ return drm_encoder_find(connector->dev, NULL, enc_id);
return NULL;
}
diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index bb5cc15fa0b9..c32c14cf5c60 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -729,7 +729,7 @@ static int drm_atomic_plane_set_property(struct drm_plane *plane,
struct drm_mode_config *config = &dev->mode_config;
if (property == config->prop_fb_id) {
- struct drm_framebuffer *fb = drm_framebuffer_lookup(dev, val);
+ struct drm_framebuffer *fb = drm_framebuffer_lookup(dev, NULL, val);
drm_atomic_set_fb_for_plane(state, fb);
if (fb)
drm_framebuffer_put(fb);
@@ -745,7 +745,7 @@ static int drm_atomic_plane_set_property(struct drm_plane *plane,
return -EINVAL;
} else if (property == config->prop_crtc_id) {
- struct drm_crtc *crtc = drm_crtc_find(dev, val);
+ struct drm_crtc *crtc = drm_crtc_find(dev, NULL, val);
return drm_atomic_set_crtc_for_plane(state, crtc);
} else if (property == config->prop_crtc_x) {
state->crtc_x = U642I64(val);
@@ -1158,9 +1158,11 @@ static int drm_atomic_connector_set_property(struct drm_connector *connector,
{
struct drm_device *dev = connector->dev;
struct drm_mode_config *config = &dev->mode_config;
+ bool replaced = false;
+ int ret;
if (property == config->prop_crtc_id) {
- struct drm_crtc *crtc = drm_crtc_find(dev, val);
+ struct drm_crtc *crtc = drm_crtc_find(dev, NULL, val);
return drm_atomic_set_crtc_for_connector(state, crtc);
} else if (property == config->dpms_property) {
/* setting DPMS property requires special handling, which
@@ -1206,10 +1208,32 @@ static int drm_atomic_connector_set_property(struct drm_connector *connector,
*/
if (state->link_status != DRM_LINK_STATUS_GOOD)
state->link_status = val;
+ } else if (property == config->hdr_source_metadata_property) {
+ ret = drm_atomic_replace_property_blob_from_id(dev,
+ &state->hdr_source_metadata_blob_ptr,
+ val,
+ -1,
+ &replaced);
+ state->hdr_metadata_changed |= replaced;
+ if (ret < 0)
+ return ret;
+
+ if (connector->funcs->atomic_set_property) {
+ return connector->funcs->atomic_set_property(connector,
+ state, property, val);
+ }
} else if (property == config->aspect_ratio_property) {
state->picture_aspect_ratio = val;
+ } else if (property == config->content_type_property) {
+ state->content_type = val;
} else if (property == connector->scaling_mode_property) {
state->scaling_mode = val;
+ } else if (property == connector->content_protection_property) {
+ if (val == DRM_MODE_CONTENT_PROTECTION_ENABLED) {
+ DRM_DEBUG_KMS("only drivers can set CP Enabled\n");
+ return -EINVAL;
+ }
+ state->content_protection = val;
} else if (connector->funcs->atomic_set_property) {
return connector->funcs->atomic_set_property(connector,
state, property, val);
@@ -1287,8 +1311,15 @@ drm_atomic_connector_get_property(struct drm_connector *connector,
*val = state->link_status;
} else if (property == config->aspect_ratio_property) {
*val = state->picture_aspect_ratio;
+ } else if (property == config->content_type_property) {
+ *val = state->content_type;
} else if (property == connector->scaling_mode_property) {
*val = state->scaling_mode;
+ } else if (property == config->hdr_source_metadata_property) {
+ *val = (state->hdr_source_metadata_blob_ptr) ?
+ state->hdr_source_metadata_blob_ptr->base.id : 0;
+ } else if (property == connector->content_protection_property) {
+ *val = state->content_protection;
} else if (connector->funcs->atomic_get_property) {
return connector->funcs->atomic_get_property(connector,
state, property, val);
@@ -2272,7 +2303,7 @@ retry:
goto out;
}
- obj = drm_mode_object_find(dev, obj_id, DRM_MODE_OBJECT_ANY);
+ obj = drm_mode_object_find(dev, file_priv, obj_id, DRM_MODE_OBJECT_ANY);
if (!obj) {
ret = -ENOENT;
goto out;
diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
index 331478bd2ff8..2147a602ecae 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -3129,7 +3129,7 @@ struct drm_encoder *
drm_atomic_helper_best_encoder(struct drm_connector *connector)
{
WARN_ON(connector->encoder_ids[1]);
- return drm_encoder_find(connector->dev, connector->encoder_ids[0]);
+ return drm_encoder_find(connector->dev, NULL, connector->encoder_ids[0]);
}
EXPORT_SYMBOL(drm_atomic_helper_best_encoder);
@@ -3420,6 +3420,10 @@ __drm_atomic_helper_connector_duplicate_state(struct drm_connector *connector,
memcpy(state, connector->state, sizeof(*state));
if (state->crtc)
drm_connector_get(connector);
+ if (state->hdr_source_metadata_blob_ptr)
+ drm_property_reference_blob(state->hdr_source_metadata_blob_ptr);
+
+ state->hdr_metadata_changed = false;
}
EXPORT_SYMBOL(__drm_atomic_helper_connector_duplicate_state);
@@ -3546,6 +3550,8 @@ __drm_atomic_helper_connector_destroy_state(struct drm_connector_state *state)
{
if (state->crtc)
drm_connector_put(state->connector);
+ if (state->hdr_source_metadata_blob_ptr)
+ drm_property_unreference_blob(state->hdr_source_metadata_blob_ptr);
}
EXPORT_SYMBOL(__drm_atomic_helper_connector_destroy_state);
diff --git a/drivers/gpu/drm/drm_auth.c b/drivers/gpu/drm/drm_auth.c
index fe85d041d0ba..1669c42c40ed 100644
--- a/drivers/gpu/drm/drm_auth.c
+++ b/drivers/gpu/drm/drm_auth.c
@@ -31,6 +31,7 @@
#include <drm/drmP.h>
#include "drm_internal.h"
#include "drm_legacy.h"
+#include <drm/drm_lease.h>
/**
* DOC: master and authentication
@@ -93,7 +94,7 @@ int drm_authmagic(struct drm_device *dev, void *data,
return file ? 0 : -EINVAL;
}
-static struct drm_master *drm_master_create(struct drm_device *dev)
+struct drm_master *drm_master_create(struct drm_device *dev)
{
struct drm_master *master;
@@ -107,6 +108,14 @@ static struct drm_master *drm_master_create(struct drm_device *dev)
idr_init(&master->magic_map);
master->dev = dev;
+ /* initialize the tree of output resource lessees */
+ master->lessor = NULL;
+ master->lessee_id = 0;
+ INIT_LIST_HEAD(&master->lessees);
+ INIT_LIST_HEAD(&master->lessee_list);
+ idr_init(&master->leases);
+ idr_init(&master->lessee_idr);
+
return master;
}
@@ -191,6 +200,12 @@ int drm_setmaster_ioctl(struct drm_device *dev, void *data,
goto out_unlock;
}
+ if (file_priv->master->lessor != NULL) {
+ DRM_DEBUG_LEASE("Attempt to set lessee %d as master\n", file_priv->master->lessee_id);
+ ret = -EINVAL;
+ goto out_unlock;
+ }
+
ret = drm_set_master(dev, file_priv, false);
out_unlock:
mutex_unlock(&dev->master_mutex);
@@ -217,6 +232,12 @@ int drm_dropmaster_ioctl(struct drm_device *dev, void *data,
if (!dev->master)
goto out_unlock;
+ if (file_priv->master->lessor != NULL) {
+ DRM_DEBUG_LEASE("Attempt to drop lessee %d as master\n", file_priv->master->lessee_id);
+ ret = -EINVAL;
+ goto out_unlock;
+ }
+
ret = 0;
drm_drop_master(dev, file_priv);
out_unlock:
@@ -272,6 +293,13 @@ void drm_master_release(struct drm_file *file_priv)
if (dev->master == file_priv->master)
drm_drop_master(dev, file_priv);
out:
+ if (drm_core_check_feature(dev, DRIVER_MODESET) && file_priv->is_master) {
+ /* Revoke any leases held by this or lessees, but only if
+ * this is the "real" master
+ */
+ drm_lease_revoke(master);
+ }
+
/* drop the master reference held by the file priv */
if (file_priv->master)
drm_master_put(&file_priv->master);
@@ -290,7 +318,7 @@ out:
*/
bool drm_is_current_master(struct drm_file *fpriv)
{
- return fpriv->is_master && fpriv->master == fpriv->minor->dev->master;
+ return fpriv->is_master && drm_lease_owner(fpriv->master) == fpriv->minor->dev->master;
}
EXPORT_SYMBOL(drm_is_current_master);
@@ -312,12 +340,18 @@ static void drm_master_destroy(struct kref *kref)
struct drm_master *master = container_of(kref, struct drm_master, refcount);
struct drm_device *dev = master->dev;
+ if (drm_core_check_feature(dev, DRIVER_MODESET))
+ drm_lease_destroy(master);
+
if (dev->driver->master_destroy)
dev->driver->master_destroy(dev, master);
drm_legacy_master_rmmaps(dev, master);
idr_destroy(&master->magic_map);
+ idr_destroy(&master->leases);
+ idr_destroy(&master->lessee_idr);
+
kfree(master->unique);
kfree(master);
}
diff --git a/drivers/gpu/drm/drm_bufs.c b/drivers/gpu/drm/drm_bufs.c
index b829fde80f7b..d341c3dc1676 100644
--- a/drivers/gpu/drm/drm_bufs.c
+++ b/drivers/gpu/drm/drm_bufs.c
@@ -179,7 +179,7 @@ static int drm_addmap_core(struct drm_device * dev, resource_size_t offset,
switch (map->type) {
case _DRM_REGISTERS:
case _DRM_FRAME_BUFFER:
-#if !defined(__sparc__) && !defined(__alpha__) && !defined(__ia64__) && !defined(__powerpc64__) && !defined(__x86_64__) && !defined(__arm__)
+#if !defined(__sparc__) && !defined(__alpha__) && !defined(__ia64__) && !defined(__powerpc64__) && !defined(__x86_64__) && !defined(__arm__) && !defined(__aarch64__)
if (map->offset + (map->size-1) < map->offset ||
map->offset < virt_to_phys(high_memory)) {
kfree(map);
diff --git a/drivers/gpu/drm/drm_color_mgmt.c b/drivers/gpu/drm/drm_color_mgmt.c
index fe0982708e95..0d002b045bd2 100644
--- a/drivers/gpu/drm/drm_color_mgmt.c
+++ b/drivers/gpu/drm/drm_color_mgmt.c
@@ -230,7 +230,7 @@ int drm_mode_gamma_set_ioctl(struct drm_device *dev,
if (!drm_core_check_feature(dev, DRIVER_MODESET))
return -EINVAL;
- crtc = drm_crtc_find(dev, crtc_lut->crtc_id);
+ crtc = drm_crtc_find(dev, file_priv, crtc_lut->crtc_id);
if (!crtc)
return -ENOENT;
@@ -308,7 +308,7 @@ int drm_mode_gamma_get_ioctl(struct drm_device *dev,
if (!drm_core_check_feature(dev, DRIVER_MODESET))
return -EINVAL;
- crtc = drm_crtc_find(dev, crtc_lut->crtc_id);
+ crtc = drm_crtc_find(dev, file_priv, crtc_lut->crtc_id);
if (!crtc)
return -ENOENT;
diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index ba9f36cef68c..098644732d66 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -234,6 +234,10 @@ int drm_connector_init(struct drm_device *dev,
config->link_status_property,
0);
+ drm_object_attach_property(&connector->base,
+ config->non_desktop_property,
+ 0);
+
if (drm_core_check_feature(dev, DRIVER_ATOMIC)) {
drm_object_attach_property(&connector->base, config->prop_crtc_id, 0);
}
@@ -665,6 +669,14 @@ static const struct drm_prop_enum_list drm_aspect_ratio_enum_list[] = {
{ DRM_MODE_PICTURE_ASPECT_16_9, "16:9" },
};
+static const struct drm_prop_enum_list drm_content_type_enum_list[] = {
+ { DRM_MODE_CONTENT_TYPE_NO_DATA, "No Data" },
+ { DRM_MODE_CONTENT_TYPE_GRAPHICS, "Graphics" },
+ { DRM_MODE_CONTENT_TYPE_PHOTO, "Photo" },
+ { DRM_MODE_CONTENT_TYPE_CINEMA, "Cinema" },
+ { DRM_MODE_CONTENT_TYPE_GAME, "Game" },
+};
+
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 */
@@ -699,6 +711,13 @@ static const struct drm_prop_enum_list drm_tv_subconnector_enum_list[] = {
DRM_ENUM_NAME_FN(drm_get_tv_subconnector_name,
drm_tv_subconnector_enum_list)
+static struct drm_prop_enum_list drm_cp_enum_list[] = {
+ { DRM_MODE_CONTENT_PROTECTION_UNDESIRED, "Undesired" },
+ { DRM_MODE_CONTENT_PROTECTION_DESIRED, "Desired" },
+ { DRM_MODE_CONTENT_PROTECTION_ENABLED, "Enabled" },
+};
+DRM_ENUM_NAME_FN(drm_get_content_protection_name, drm_cp_enum_list)
+
/**
* DOC: standard connector properties
*
@@ -741,6 +760,41 @@ DRM_ENUM_NAME_FN(drm_get_tv_subconnector_name,
* value of link-status is "GOOD". If something fails during or after modeset,
* the kernel driver may set this to "BAD" and issue a hotplug uevent. Drivers
* should update this value using drm_mode_connector_set_link_status_property().
+ * Content Protection:
+ * This property is used by userspace to request the kernel protect future
+ * content communicated over the link. When requested, kernel will apply
+ * the appropriate means of protection (most often HDCP), and use the
+ * property to tell userspace the protection is active.
+ *
+ * Drivers can set this up by calling
+ * drm_connector_attach_content_protection_property() on initialization.
+ *
+ * The value of this property can be one of the following:
+ *
+ * - DRM_MODE_CONTENT_PROTECTION_UNDESIRED = 0
+ * The link is not protected, content is transmitted in the clear.
+ * - DRM_MODE_CONTENT_PROTECTION_DESIRED = 1
+ * Userspace has requested content protection, but the link is not
+ * currently protected. When in this state, kernel should enable
+ * Content Protection as soon as possible.
+ * - DRM_MODE_CONTENT_PROTECTION_ENABLED = 2
+ * Userspace has requested content protection, and the link is
+ * protected. Only the driver can set the property to this value.
+ * If userspace attempts to set to ENABLED, kernel will return
+ * -EINVAL.
+ *
+ * A few guidelines:
+ *
+ * - DESIRED state should be preserved until userspace de-asserts it by
+ * setting the property to UNDESIRED. This means ENABLED should only
+ * transition to UNDESIRED when the user explicitly requests it.
+ * - If the state is DESIRED, kernel should attempt to re-authenticate the
+ * link whenever possible. This includes across disable/enable, dpms,
+ * hotplug, downstream device changes, link status failures, etc..
+ * - Userspace is responsible for polling the property to determine when
+ * the value transitions from ENABLED to DESIRED. This signifies the link
+ * is no longer protected and userspace should take appropriate action
+ * (whatever that might be).
*
* Connectors also have one standardized atomic property:
*
@@ -789,6 +843,18 @@ int drm_connector_create_standard_properties(struct drm_device *dev)
return -ENOMEM;
dev->mode_config.link_status_property = prop;
+ prop = drm_property_create(dev, DRM_MODE_PROP_BLOB,
+ "HDR_SOURCE_METADATA", 0);
+
+ if (!prop)
+ return -ENOMEM;
+ dev->mode_config.hdr_source_metadata_property = prop;
+
+ prop = drm_property_create_bool(dev, DRM_MODE_PROP_IMMUTABLE, "non-desktop");
+ if (!prop)
+ return -ENOMEM;
+ dev->mode_config.non_desktop_property = prop;
+
return 0;
}
@@ -824,6 +890,84 @@ int drm_mode_create_dvi_i_properties(struct drm_device *dev)
EXPORT_SYMBOL(drm_mode_create_dvi_i_properties);
/**
+ * DOC: HDMI connector properties
+ *
+ * content type (HDMI specific):
+ * Indicates content type setting to be used in HDMI infoframes to indicate
+ * content type for the external device, so that it adjusts it's display
+ * settings accordingly.
+ *
+ * The value of this property can be one of the following:
+ *
+ * No Data:
+ * Content type is unknown
+ * Graphics:
+ * Content type is graphics
+ * Photo:
+ * Content type is photo
+ * Cinema:
+ * Content type is cinema
+ * Game:
+ * Content type is game
+ *
+ * Drivers can set up this property by calling
+ * drm_connector_attach_content_type_property(). Decoding to
+ * infoframe values is done through
+ * drm_hdmi_get_content_type_from_property() and
+ * drm_hdmi_get_itc_bit_from_property().
+ */
+
+/**
+ * drm_connector_attach_content_type_property - attach content-type property
+ * @connector: connector to attach content type property on.
+ *
+ * Called by a driver the first time a HDMI connector is made.
+ */
+int drm_connector_attach_content_type_property(struct drm_connector *connector)
+{
+ if (!drm_mode_create_content_type_property(connector->dev))
+ drm_object_attach_property(&connector->base,
+ connector->dev->mode_config.content_type_property,
+ DRM_MODE_CONTENT_TYPE_NO_DATA);
+ return 0;
+}
+EXPORT_SYMBOL(drm_connector_attach_content_type_property);
+
+
+/**
+ * drm_hdmi_avi_infoframe_content_type() - fill the HDMI AVI infoframe
+ * content type information, based
+ * on correspondent DRM property.
+ * @frame: HDMI AVI infoframe
+ * @conn_state: DRM display connector state
+ *
+ */
+void drm_hdmi_avi_infoframe_content_type(struct hdmi_avi_infoframe *frame,
+ const struct drm_connector_state *conn_state)
+{
+ switch (conn_state->content_type) {
+ case DRM_MODE_CONTENT_TYPE_GRAPHICS:
+ frame->content_type = HDMI_CONTENT_TYPE_GRAPHICS;
+ break;
+ case DRM_MODE_CONTENT_TYPE_CINEMA:
+ frame->content_type = HDMI_CONTENT_TYPE_CINEMA;
+ break;
+ case DRM_MODE_CONTENT_TYPE_GAME:
+ frame->content_type = HDMI_CONTENT_TYPE_GAME;
+ break;
+ case DRM_MODE_CONTENT_TYPE_PHOTO:
+ frame->content_type = HDMI_CONTENT_TYPE_PHOTO;
+ break;
+ default:
+ /* Graphics is the default(0) */
+ frame->content_type = HDMI_CONTENT_TYPE_GRAPHICS;
+ }
+
+ frame->itc = conn_state->content_type != DRM_MODE_CONTENT_TYPE_NO_DATA;
+}
+EXPORT_SYMBOL(drm_hdmi_avi_infoframe_content_type);
+
+/**
* drm_create_tv_properties - create TV specific connector properties
* @dev: DRM device
* @num_modes: number of different TV formats (modes) supported
@@ -1025,6 +1169,42 @@ int drm_connector_attach_scaling_mode_property(struct drm_connector *connector,
EXPORT_SYMBOL(drm_connector_attach_scaling_mode_property);
/**
+ * drm_connector_attach_content_protection_property - attach content protection
+ * property
+ *
+ * @connector: connector to attach CP property on.
+ *
+ * This is used to add support for content protection on select connectors.
+ * Content Protection is intentionally vague to allow for different underlying
+ * technologies, however it is most implemented by HDCP.
+ *
+ * The content protection will be set to &drm_connector_state.content_protection
+ *
+ * Returns:
+ * Zero on success, negative errno on failure.
+ */
+int drm_connector_attach_content_protection_property(
+ struct drm_connector *connector)
+{
+ struct drm_device *dev = connector->dev;
+ struct drm_property *prop;
+
+ prop = drm_property_create_enum(dev, 0, "Content Protection",
+ drm_cp_enum_list,
+ ARRAY_SIZE(drm_cp_enum_list));
+ if (!prop)
+ return -ENOMEM;
+
+ drm_object_attach_property(&connector->base, prop,
+ DRM_MODE_CONTENT_PROTECTION_UNDESIRED);
+
+ connector->content_protection_property = prop;
+
+ return 0;
+}
+EXPORT_SYMBOL(drm_connector_attach_content_protection_property);
+
+/**
* drm_mode_create_aspect_ratio_property - create aspect ratio property
* @dev: DRM device
*
@@ -1052,6 +1232,33 @@ int drm_mode_create_aspect_ratio_property(struct drm_device *dev)
EXPORT_SYMBOL(drm_mode_create_aspect_ratio_property);
/**
+ * drm_mode_create_content_type_property - create content type property
+ * @dev: DRM device
+ *
+ * Called by a driver the first time it's needed, must be attached to desired
+ * connectors.
+ *
+ * Returns:
+ * Zero on success, negative errno on failure.
+ */
+int drm_mode_create_content_type_property(struct drm_device *dev)
+{
+ if (dev->mode_config.content_type_property)
+ return 0;
+
+ dev->mode_config.content_type_property =
+ drm_property_create_enum(dev, 0, "content type",
+ drm_content_type_enum_list,
+ ARRAY_SIZE(drm_content_type_enum_list));
+
+ if (dev->mode_config.content_type_property == NULL)
+ return -ENOMEM;
+
+ return 0;
+}
+EXPORT_SYMBOL(drm_mode_create_content_type_property);
+
+/**
* drm_mode_create_suggested_offset_properties - create suggests offset properties
* @dev: DRM device
*
@@ -1172,6 +1379,10 @@ int drm_mode_connector_update_edid_property(struct drm_connector *connector,
if (edid)
size = EDID_LENGTH * (1 + edid->extensions);
+ drm_object_property_set_value(&connector->base,
+ dev->mode_config.non_desktop_property,
+ connector->display_info.non_desktop);
+
ret = drm_property_replace_global_blob(dev,
&connector->edid_blob_ptr,
size,
@@ -1288,7 +1499,7 @@ int drm_mode_getconnector(struct drm_device *dev, void *data,
memset(&u_mode, 0, sizeof(struct drm_mode_modeinfo));
- connector = drm_connector_lookup(dev, out_resp->connector_id);
+ connector = drm_connector_lookup(dev, file_priv, out_resp->connector_id);
if (!connector)
return -ENOENT;
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 5af25ce5bf7c..5dd2d28dd221 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -402,7 +402,7 @@ int drm_mode_getcrtc(struct drm_device *dev,
if (!drm_core_check_feature(dev, DRIVER_MODESET))
return -EINVAL;
- crtc = drm_crtc_find(dev, crtc_resp->crtc_id);
+ crtc = drm_crtc_find(dev, file_priv, crtc_resp->crtc_id);
if (!crtc)
return -ENOENT;
@@ -569,7 +569,7 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data,
if (crtc_req->x & 0xffff0000 || crtc_req->y & 0xffff0000)
return -ERANGE;
- crtc = drm_crtc_find(dev, crtc_req->crtc_id);
+ crtc = drm_crtc_find(dev, file_priv, crtc_req->crtc_id);
if (!crtc) {
DRM_DEBUG_KMS("Unknown CRTC ID %d\n", crtc_req->crtc_id);
return -ENOENT;
@@ -595,7 +595,7 @@ retry:
/* Make refcounting symmetric with the lookup path. */
drm_framebuffer_get(fb);
} else {
- fb = drm_framebuffer_lookup(dev, crtc_req->fb_id);
+ fb = drm_framebuffer_lookup(dev, file_priv, crtc_req->fb_id);
if (!fb) {
DRM_DEBUG_KMS("Unknown FB ID%d\n",
crtc_req->fb_id);
@@ -680,7 +680,7 @@ retry:
goto out;
}
- connector = drm_connector_lookup(dev, out_id);
+ connector = drm_connector_lookup(dev, file_priv, out_id);
if (!connector) {
DRM_DEBUG_KMS("Connector id %d unknown\n",
out_id);
diff --git a/drivers/gpu/drm/drm_crtc_internal.h b/drivers/gpu/drm/drm_crtc_internal.h
index a43582076b20..9ebb8841778c 100644
--- a/drivers/gpu/drm/drm_crtc_internal.h
+++ b/drivers/gpu/drm/drm_crtc_internal.h
@@ -106,6 +106,7 @@ int drm_mode_object_add(struct drm_device *dev, struct drm_mode_object *obj,
void drm_mode_object_register(struct drm_device *dev,
struct drm_mode_object *obj);
struct drm_mode_object *__drm_mode_object_find(struct drm_device *dev,
+ struct drm_file *file_priv,
uint32_t id, uint32_t type);
void drm_mode_object_unregister(struct drm_device *dev,
struct drm_mode_object *object);
diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
index 340440febf9a..11901e686d18 100644
--- a/drivers/gpu/drm/drm_drv.c
+++ b/drivers/gpu/drm/drm_drv.c
@@ -57,7 +57,8 @@ MODULE_PARM_DESC(debug, "Enable debug output, where each bit enables a debug cat
"\t\tBit 2 (0x04) will enable KMS messages (modesetting code)\n"
"\t\tBit 3 (0x08) will enable PRIME messages (prime code)\n"
"\t\tBit 4 (0x10) will enable ATOMIC messages (atomic code)\n"
-"\t\tBit 5 (0x20) will enable VBL messages (vblank code)");
+"\t\tBit 5 (0x20) will enable VBL messages (vblank code)\n"
+"\t\tBit 7 (0x80) will enable LEASE messages (leasing code)");
module_param_named(debug, drm_debug, int, 0600);
static DEFINE_SPINLOCK(drm_minor_lock);
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index dfdc7d3147fb..c90f8680fb46 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -82,6 +82,8 @@
#define EDID_QUIRK_FORCE_6BPC (1 << 10)
/* Force 10bpc */
#define EDID_QUIRK_FORCE_10BPC (1 << 11)
+/* Non desktop display (i.e. HMD) */
+#define EDID_QUIRK_NON_DESKTOP (1 << 12)
struct detailed_mode_closure {
struct drm_connector *connector;
@@ -172,6 +174,10 @@ static const struct edid_quirk {
/* Rotel RSX-1058 forwards sink's EDID but only does HDMI 1.1*/
{ "ETR", 13896, EDID_QUIRK_FORCE_8BPC },
+
+ /* Quantum data 980 */
+ { "QDI", 980, EDID_QUIRK_PREFER_LARGE_60 },
+ { "QDI", 178, EDID_QUIRK_PREFER_LARGE_60 },
};
/*
@@ -2805,6 +2811,23 @@ add_detailed_modes(struct drm_connector *connector, struct edid *edid,
#define EDID_CEA_YCRCB422 (1 << 4)
#define EDID_CEA_VCDB_QS (1 << 6)
+#define DATA_BLOCK_EXTENDED_TAG 0x07
+#define VIDEO_CAPABILITY_DATA_BLOCK 0x0
+#define VSVD_DATA_BLOCK 0x1
+#define COLORIMETRY_DATA_BLOCK 0x5
+#define HDR_STATIC_METADATA_BLOCK 0x6
+
+/* HDR Metadata Block: Bit fields */
+#define SUPPORTED_EOTF_MASK 0x3f
+#define TRADITIONAL_GAMMA_SDR (0x1 << 0)
+#define TRADITIONAL_GAMMA_HDR (0x1 << 1)
+#define SMPTE_ST2084 (0x1 << 2)
+#define BT_2100_HLG (0x1 << 3)
+#define FUTURE_EOTF (0x1 << 4)
+#define RESERVED_EOTF (0x3 << 5)
+
+#define STATIC_METADATA_TYPE1 (0x1 << 0)
+
/*
* Search EDID for CEA extension block.
*/
@@ -3751,6 +3774,83 @@ static void fixup_detailed_cea_mode_clock(struct drm_display_mode *mode)
mode->clock = clock;
}
+static bool cea_db_is_hdmi_colorimetry_data_block(const u8 *db)
+{
+ if (cea_db_tag(db) != DATA_BLOCK_EXTENDED_TAG)
+ return false;
+
+ if (db[1] != COLORIMETRY_DATA_BLOCK)
+ return false;
+
+ return true;
+}
+
+static void
+drm_parse_colorimetry_data_block(struct drm_connector *connector, const u8 *db)
+{
+ struct drm_hdmi_info *info = &connector->display_info.hdmi;
+ uint16_t len;
+
+ len = cea_db_payload_len(db);
+ info->colorimetry = db[2];
+}
+
+
+static bool cea_db_is_hdmi_hdr_metadata_block(const u8 *db)
+{
+ if (cea_db_tag(db) != DATA_BLOCK_EXTENDED_TAG)
+ return false;
+
+ if (db[1] != HDR_STATIC_METADATA_BLOCK)
+ return false;
+
+ return true;
+}
+
+static uint16_t eotf_supported(const u8 *edid_ext)
+{
+ uint16_t val = 0;
+
+ if (edid_ext[2] & TRADITIONAL_GAMMA_SDR)
+ val |= TRADITIONAL_GAMMA_SDR;
+ if (edid_ext[2] & TRADITIONAL_GAMMA_HDR)
+ val |= TRADITIONAL_GAMMA_HDR;
+ if (edid_ext[2] & SMPTE_ST2084)
+ val |= SMPTE_ST2084;
+ if (edid_ext[2] & BT_2100_HLG)
+ val |= BT_2100_HLG;
+
+ return val;
+}
+
+static uint16_t hdr_metadata_type(const u8 *edid_ext)
+{
+ uint16_t val = 0;
+
+ if (edid_ext[3] & STATIC_METADATA_TYPE1)
+ val |= STATIC_METADATA_TYPE1;
+
+ return val;
+}
+
+static void
+drm_parse_hdr_metadata_block(struct drm_connector *connector, const u8 *db)
+{
+ struct drm_hdmi_info *info = &connector->display_info.hdmi;
+ uint16_t len;
+
+ len = cea_db_payload_len(db);
+ info->hdr_panel_metadata.eotf = eotf_supported(db);
+ info->hdr_panel_metadata.type = hdr_metadata_type(db);
+
+ if (len == 5) {
+ info->hdr_panel_metadata.max_cll = db[4];
+ info->hdr_panel_metadata.max_fall = db[5];
+ } else if (len == 4) {
+ info->hdr_panel_metadata.max_cll = db[4];
+ }
+}
+
static void
drm_parse_hdmi_vsdb_audio(struct drm_connector *connector, const u8 *db)
{
@@ -4394,14 +4494,19 @@ static void drm_parse_cea_ext(struct drm_connector *connector,
drm_parse_hdmi_forum_vsdb(connector, db);
if (cea_db_is_y420cmdb(db))
drm_parse_y420cmdb_bitmap(connector, db);
+ if (cea_db_is_hdmi_hdr_metadata_block(db))
+ drm_parse_hdr_metadata_block(connector, db);
+ if (cea_db_is_hdmi_colorimetry_data_block(db))
+ drm_parse_colorimetry_data_block(connector, db);
}
}
static void drm_add_display_info(struct drm_connector *connector,
- struct edid *edid)
+ struct edid *edid, u32 quirks)
{
struct drm_display_info *info = &connector->display_info;
+ memset(info, 0, sizeof(struct drm_display_info));
info->width_mm = edid->width_cm * 10;
info->height_mm = edid->height_cm * 10;
@@ -4412,6 +4517,8 @@ static void drm_add_display_info(struct drm_connector *connector,
info->max_tmds_clock = 0;
info->dvi_dual = false;
+ info->non_desktop = !!(quirks & EDID_QUIRK_NON_DESKTOP);
+
if (edid->revision < 3)
return;
@@ -4632,7 +4739,7 @@ int drm_add_edid_modes(struct drm_connector *connector, struct edid *edid)
* To avoid multiple parsing of same block, lets parse that map
* from sink info, before parsing CEA modes.
*/
- drm_add_display_info(connector, edid);
+ drm_add_display_info(connector, edid, quirks);
/*
* EDID spec says modes should be preferred in this order:
@@ -4748,6 +4855,58 @@ void drm_set_preferred_mode(struct drm_connector *connector,
EXPORT_SYMBOL(drm_set_preferred_mode);
/**
+ * drm_hdmi_infoframe_set_hdr_metadata() - fill an HDMI AVI infoframe with
+ * HDR metadata from userspace
+ * @frame: HDMI AVI infoframe
+ * @hdr_source_metadata: hdr_source_metadata info from userspace
+ *
+ * Return: 0 on success or a negative error code on failure.
+ */
+int
+drm_hdmi_infoframe_set_hdr_metadata(struct hdmi_drm_infoframe *frame,
+ void *hdr_metadata)
+{
+ struct hdr_static_metadata *hdr_source_metadata;
+ int err, i;
+
+ if (!frame || !hdr_metadata)
+ return -EINVAL;
+
+ err = hdmi_drm_infoframe_init(frame);
+ if (err < 0)
+ return err;
+
+ hdr_source_metadata = (struct hdr_static_metadata *)hdr_metadata;
+
+ frame->length = sizeof(struct hdr_static_metadata);
+
+ frame->eotf = hdr_source_metadata->eotf;
+ frame->metadata_type = hdr_source_metadata->type;
+
+ for (i = 0; i < 3; i++) {
+ frame->display_primaries_x[i] =
+ hdr_source_metadata->display_primaries_x[i];
+ frame->display_primaries_y[i] =
+ hdr_source_metadata->display_primaries_y[i];
+ }
+
+ frame->white_point_x = hdr_source_metadata->white_point_x;
+ frame->white_point_y = hdr_source_metadata->white_point_y;
+
+ frame->max_mastering_display_luminance =
+ hdr_source_metadata->max_mastering_display_luminance;
+ frame->min_mastering_display_luminance =
+ hdr_source_metadata->min_mastering_display_luminance;
+
+ frame->max_cll = hdr_source_metadata->max_cll;
+ frame->max_fall = hdr_source_metadata->max_fall;
+
+ return 0;
+}
+EXPORT_SYMBOL(drm_hdmi_infoframe_set_hdr_metadata);
+
+
+/**
* drm_hdmi_avi_infoframe_from_display_mode() - fill an HDMI AVI infoframe with
* data from a DRM display mode
* @frame: HDMI AVI infoframe
@@ -4800,6 +4959,14 @@ drm_hdmi_avi_infoframe_from_display_mode(struct hdmi_avi_infoframe *frame,
frame->picture_aspect = HDMI_PICTURE_ASPECT_NONE;
/*
+ * As some drivers don't support atomic, we can't use connector state.
+ * So just initialize the frame with default values, just the same way
+ * as it's done with other properties here.
+ */
+ frame->content_type = HDMI_CONTENT_TYPE_GRAPHICS;
+ frame->itc = 0;
+
+ /*
* Populate picture aspect ratio from either
* user input (if specified) or from the CEA mode list.
*/
diff --git a/drivers/gpu/drm/drm_encoder.c b/drivers/gpu/drm/drm_encoder.c
index 0708779840d2..59e0ebe733f8 100644
--- a/drivers/gpu/drm/drm_encoder.c
+++ b/drivers/gpu/drm/drm_encoder.c
@@ -220,13 +220,13 @@ int drm_mode_getencoder(struct drm_device *dev, void *data,
if (!drm_core_check_feature(dev, DRIVER_MODESET))
return -EINVAL;
- encoder = drm_encoder_find(dev, enc_resp->encoder_id);
+ encoder = drm_encoder_find(dev, file_priv, enc_resp->encoder_id);
if (!encoder)
return -ENOENT;
drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
crtc = drm_encoder_get_crtc(encoder);
- if (crtc)
+ if (crtc && drm_lease_held(file_priv, crtc->base.id))
enc_resp->crtc_id = crtc->base.id;
else
enc_resp->crtc_id = 0;
@@ -234,7 +234,8 @@ int drm_mode_getencoder(struct drm_device *dev, void *data,
enc_resp->encoder_type = encoder->encoder_type;
enc_resp->encoder_id = encoder->base.id;
- enc_resp->possible_crtcs = encoder->possible_crtcs;
+ enc_resp->possible_crtcs = drm_lease_filter_crtcs(file_priv,
+ encoder->possible_crtcs);
enc_resp->possible_clones = encoder->possible_clones;
return 0;
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
index f1259a0c2883..8549d5e128db 100644
--- a/drivers/gpu/drm/drm_fb_helper.c
+++ b/drivers/gpu/drm/drm_fb_helper.c
@@ -793,8 +793,10 @@ int drm_fb_helper_init(struct drm_device *dev,
struct drm_mode_config *config = &dev->mode_config;
int i;
- if (!drm_fbdev_emulation)
+ if (!drm_fbdev_emulation) {
+ dev->fb_helper = fb_helper;
return 0;
+ }
if (!max_conn_count)
return -EINVAL;
@@ -829,6 +831,8 @@ int drm_fb_helper_init(struct drm_device *dev,
i++;
}
+ dev->fb_helper = fb_helper;
+
return 0;
out_free:
drm_fb_helper_crtc_free(fb_helper);
@@ -907,7 +911,12 @@ void drm_fb_helper_fini(struct drm_fb_helper *fb_helper)
{
struct fb_info *info;
- if (!drm_fbdev_emulation || !fb_helper)
+ if (!fb_helper)
+ return;
+
+ fb_helper->dev->fb_helper = NULL;
+
+ if (!drm_fbdev_emulation)
return;
info = fb_helper->fbdev;
@@ -2023,6 +2032,9 @@ static bool drm_connector_enabled(struct drm_connector *connector, bool strict)
{
bool enable;
+ if (connector->display_info.non_desktop)
+ return false;
+
if (strict)
enable = connector->status == connector_status_connected;
else
@@ -2042,7 +2054,8 @@ static void drm_enable_connectors(struct drm_fb_helper *fb_helper,
connector = fb_helper->connector_info[i]->connector;
enabled[i] = drm_connector_enabled(connector, true);
DRM_DEBUG_KMS("connector %d enabled? %s\n", connector->base.id,
- enabled[i] ? "yes" : "no");
+ connector->display_info.non_desktop ? "non desktop" : enabled[i] ? "yes" : "no");
+
any_enabled |= enabled[i];
}
diff --git a/drivers/gpu/drm/drm_fourcc.c b/drivers/gpu/drm/drm_fourcc.c
index 9c0152df45ad..f92f18c6fabe 100644
--- a/drivers/gpu/drm/drm_fourcc.c
+++ b/drivers/gpu/drm/drm_fourcc.c
@@ -163,6 +163,7 @@ const struct drm_format_info *__drm_format_info(u32 format)
{ .format = DRM_FORMAT_YUV444, .depth = 0, .num_planes = 3, .cpp = { 1, 1, 1 }, .hsub = 1, .vsub = 1 },
{ .format = DRM_FORMAT_YVU444, .depth = 0, .num_planes = 3, .cpp = { 1, 1, 1 }, .hsub = 1, .vsub = 1 },
{ .format = DRM_FORMAT_NV12, .depth = 0, .num_planes = 2, .cpp = { 1, 2, 0 }, .hsub = 2, .vsub = 2 },
+ { .format = DRM_FORMAT_P010, .depth = 0, .num_planes = 2, .cpp = { 1, 2, 0 }, .hsub = 2, .vsub = 2 },
{ .format = DRM_FORMAT_NV21, .depth = 0, .num_planes = 2, .cpp = { 1, 2, 0 }, .hsub = 2, .vsub = 2 },
{ .format = DRM_FORMAT_NV16, .depth = 0, .num_planes = 2, .cpp = { 1, 2, 0 }, .hsub = 2, .vsub = 1 },
{ .format = DRM_FORMAT_NV61, .depth = 0, .num_planes = 2, .cpp = { 1, 2, 0 }, .hsub = 2, .vsub = 1 },
diff --git a/drivers/gpu/drm/drm_framebuffer.c b/drivers/gpu/drm/drm_framebuffer.c
index af40189cdb60..bf5fff4ee98c 100644
--- a/drivers/gpu/drm/drm_framebuffer.c
+++ b/drivers/gpu/drm/drm_framebuffer.c
@@ -385,7 +385,7 @@ int drm_mode_rmfb(struct drm_device *dev,
if (!drm_core_check_feature(dev, DRIVER_MODESET))
return -EINVAL;
- fb = drm_framebuffer_lookup(dev, *id);
+ fb = drm_framebuffer_lookup(dev, file_priv, *id);
if (!fb)
return -ENOENT;
@@ -454,7 +454,7 @@ int drm_mode_getfb(struct drm_device *dev,
if (!drm_core_check_feature(dev, DRIVER_MODESET))
return -EINVAL;
- fb = drm_framebuffer_lookup(dev, r->fb_id);
+ fb = drm_framebuffer_lookup(dev, file_priv, r->fb_id);
if (!fb)
return -ENOENT;
@@ -526,7 +526,7 @@ int drm_mode_dirtyfb_ioctl(struct drm_device *dev,
if (!drm_core_check_feature(dev, DRIVER_MODESET))
return -EINVAL;
- fb = drm_framebuffer_lookup(dev, r->fb_id);
+ fb = drm_framebuffer_lookup(dev, file_priv, r->fb_id);
if (!fb)
return -ENOENT;
@@ -699,12 +699,13 @@ EXPORT_SYMBOL(drm_framebuffer_init);
* again, using drm_framebuffer_put().
*/
struct drm_framebuffer *drm_framebuffer_lookup(struct drm_device *dev,
+ struct drm_file *file_priv,
uint32_t id)
{
struct drm_mode_object *obj;
struct drm_framebuffer *fb = NULL;
- obj = __drm_mode_object_find(dev, id, DRM_MODE_OBJECT_FB);
+ obj = __drm_mode_object_find(dev, file_priv, id, DRM_MODE_OBJECT_FB);
if (obj)
fb = obj_to_fb(obj);
return fb;
diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c
index 53f319369de5..a2a87bedf27a 100644
--- a/drivers/gpu/drm/drm_ioctl.c
+++ b/drivers/gpu/drm/drm_ioctl.c
@@ -664,6 +664,10 @@ static const struct drm_ioctl_desc drm_ioctls[] = {
DRM_UNLOCKED|DRM_RENDER_ALLOW),
DRM_IOCTL_DEF(DRM_IOCTL_SYNCOBJ_SIGNAL, drm_syncobj_signal_ioctl,
DRM_UNLOCKED|DRM_RENDER_ALLOW),
+ DRM_IOCTL_DEF(DRM_IOCTL_MODE_CREATE_LEASE, drm_mode_create_lease_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_IOCTL_MODE_LIST_LESSEES, drm_mode_list_lessees_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_IOCTL_MODE_GET_LEASE, drm_mode_get_lease_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_IOCTL_MODE_REVOKE_LEASE, drm_mode_revoke_lease_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
};
#define DRM_CORE_IOCTL_COUNT ARRAY_SIZE( drm_ioctls )
diff --git a/drivers/gpu/drm/drm_lease.c b/drivers/gpu/drm/drm_lease.c
new file mode 100644
index 000000000000..1402c0e71b03
--- /dev/null
+++ b/drivers/gpu/drm/drm_lease.c
@@ -0,0 +1,767 @@
+/*
+ * Copyright © 2017 Keith Packard <keithp@keithp.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 <drm/drmP.h>
+#include "drm_internal.h"
+#include "drm_legacy.h"
+#include "drm_crtc_internal.h"
+#include <drm/drm_lease.h>
+#include <drm/drm_auth.h>
+#include <drm/drm_crtc_helper.h>
+
+#define drm_for_each_lessee(lessee, lessor) \
+ list_for_each_entry((lessee), &(lessor)->lessees, lessee_list)
+
+static uint64_t drm_lease_idr_object;
+
+/**
+ * drm_lease_owner - return ancestor owner drm_master
+ * @master: drm_master somewhere within tree of lessees and lessors
+ *
+ * RETURN:
+ *
+ * drm_master at the top of the tree (i.e, with lessor NULL
+ */
+struct drm_master *drm_lease_owner(struct drm_master *master)
+{
+ while (master->lessor != NULL)
+ master = master->lessor;
+ return master;
+}
+EXPORT_SYMBOL(drm_lease_owner);
+
+/**
+ * _drm_find_lessee - find lessee by id (idr_mutex held)
+ * @master: drm_master of lessor
+ * @id: lessee_id
+ *
+ * RETURN:
+ *
+ * drm_master of the lessee if valid, NULL otherwise
+ */
+
+static struct drm_master*
+_drm_find_lessee(struct drm_master *master, int lessee_id)
+{
+ lockdep_assert_held(&master->dev->mode_config.idr_mutex);
+ return idr_find(&drm_lease_owner(master)->lessee_idr, lessee_id);
+}
+
+/**
+ * _drm_lease_held_master - check to see if an object is leased (or owned) by master (idr_mutex held)
+ * @master: the master to check the lease status of
+ * @id: the id to check
+ *
+ * Checks if the specified master holds a lease on the object. Return
+ * value:
+ *
+ * true 'master' holds a lease on (or owns) the object
+ * false 'master' does not hold a lease.
+ */
+static int _drm_lease_held_master(struct drm_master *master, int id)
+{
+ lockdep_assert_held(&master->dev->mode_config.idr_mutex);
+ if (master->lessor)
+ return idr_find(&master->leases, id) != NULL;
+ return true;
+}
+
+/**
+ * _drm_has_leased - check to see if an object has been leased (idr_mutex held)
+ * @master: the master to check the lease status of
+ * @id: the id to check
+ *
+ * Checks if any lessee of 'master' holds a lease on 'id'. Return
+ * value:
+ *
+ * true Some lessee holds a lease on the object.
+ * false No lessee has a lease on the object.
+ */
+static bool _drm_has_leased(struct drm_master *master, int id)
+{
+ struct drm_master *lessee;
+
+ lockdep_assert_held(&master->dev->mode_config.idr_mutex);
+ drm_for_each_lessee(lessee, master)
+ if (_drm_lease_held_master(lessee, id))
+ return true;
+ return false;
+}
+
+/**
+ * _drm_lease_held - check drm_mode_object lease status (idr_mutex held)
+ * @master: the drm_master
+ * @id: the object id
+ *
+ * Checks if the specified master holds a lease on the object. Return
+ * value:
+ *
+ * true 'master' holds a lease on (or owns) the object
+ * false 'master' does not hold a lease.
+ */
+bool _drm_lease_held(struct drm_file *file_priv, int id)
+{
+ if (file_priv == NULL || file_priv->master == NULL)
+ return true;
+
+ return _drm_lease_held_master(file_priv->master, id);
+}
+EXPORT_SYMBOL(_drm_lease_held);
+
+/**
+ * drm_lease_held - check drm_mode_object lease status (idr_mutex not held)
+ * @master: the drm_master
+ * @id: the object id
+ *
+ * Checks if the specified master holds a lease on the object. Return
+ * value:
+ *
+ * true 'master' holds a lease on (or owns) the object
+ * false 'master' does not hold a lease.
+ */
+bool drm_lease_held(struct drm_file *file_priv, int id)
+{
+ struct drm_master *master;
+ bool ret;
+
+ if (file_priv == NULL || file_priv->master == NULL)
+ return true;
+
+ master = file_priv->master;
+ mutex_lock(&master->dev->mode_config.idr_mutex);
+ ret = _drm_lease_held_master(master, id);
+ mutex_unlock(&master->dev->mode_config.idr_mutex);
+ return ret;
+}
+EXPORT_SYMBOL(drm_lease_held);
+
+/**
+ * drm_lease_filter_crtcs - restricted crtc set to leased values (idr_mutex not held)
+ * @file_priv: requestor file
+ * @crtcs: bitmask of crtcs to check
+ *
+ * Reconstructs a crtc mask based on the crtcs which are visible
+ * through the specified file.
+ */
+uint32_t drm_lease_filter_crtcs(struct drm_file *file_priv, uint32_t crtcs_in)
+{
+ struct drm_master *master;
+ struct drm_device *dev;
+ struct drm_crtc *crtc;
+ int count_in, count_out;
+ uint32_t crtcs_out = 0;
+
+ if (file_priv == NULL || file_priv->master == NULL)
+ return crtcs_in;
+
+ master = file_priv->master;
+ dev = master->dev;
+
+ count_in = count_out = 0;
+ mutex_lock(&master->dev->mode_config.idr_mutex);
+ list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
+ if (_drm_lease_held_master(master, crtc->base.id)) {
+ uint32_t mask_in = 1ul << count_in;
+ if ((crtcs_in & mask_in) != 0) {
+ uint32_t mask_out = 1ul << count_out;
+ crtcs_out |= mask_out;
+ }
+ count_out++;
+ }
+ count_in++;
+ }
+ mutex_unlock(&master->dev->mode_config.idr_mutex);
+ return crtcs_out;
+}
+EXPORT_SYMBOL(drm_lease_filter_crtcs);
+
+/*
+ * drm_lease_create - create a new drm_master with leased objects (idr_mutex not held)
+ * @lessor: lease holder (or owner) of objects
+ * @leases: objects to lease to the new drm_master
+ *
+ * Uses drm_master_create to allocate a new drm_master, then checks to
+ * make sure all of the desired objects can be leased, atomically
+ * leasing them to the new drmmaster.
+ *
+ * ERR_PTR(-EACCESS) some other master holds the title to any object
+ * ERR_PTR(-ENOENT) some object is not a valid DRM object for this device
+ * ERR_PTR(-EBUSY) some other lessee holds title to this object
+ * ERR_PTR(-EEXIST) same object specified more than once in the provided list
+ * ERR_PTR(-ENOMEM) allocation failed
+ */
+static struct drm_master *drm_lease_create(struct drm_master *lessor, struct idr *leases)
+{
+ struct drm_device *dev = lessor->dev;
+ int error;
+ struct drm_master *lessee;
+ int object;
+ int id;
+ void *entry;
+
+ DRM_DEBUG_LEASE("lessor %d\n", lessor->lessee_id);
+
+ lessee = drm_master_create(lessor->dev);
+ if (!lessee) {
+ DRM_DEBUG_LEASE("drm_master_create failed\n");
+ return ERR_PTR(-ENOMEM);
+ }
+
+ mutex_lock(&dev->mode_config.idr_mutex);
+
+ idr_for_each_entry(leases, entry, object) {
+ error = 0;
+ if (!idr_find(&dev->mode_config.crtc_idr, object))
+ error = -ENOENT;
+ else if (!_drm_lease_held_master(lessor, object))
+ error = -EACCES;
+ else if (_drm_has_leased(lessor, object))
+ error = -EBUSY;
+
+ if (error != 0) {
+ DRM_DEBUG_LEASE("object %d failed %d\n", object, error);
+ goto out_lessee;
+ }
+ }
+
+ /* Insert the new lessee into the tree */
+ id = idr_alloc(&(drm_lease_owner(lessor)->lessee_idr), lessee, 1, 0, GFP_KERNEL);
+ if (id < 0) {
+ error = id;
+ goto out_lessee;
+ }
+
+ lessee->lessee_id = id;
+ lessee->lessor = drm_master_get(lessor);
+ list_add_tail(&lessee->lessee_list, &lessor->lessees);
+
+ /* Move the leases over */
+ lessee->leases = *leases;
+ DRM_DEBUG_LEASE("new lessee %d %p, lessor %d %p\n", lessee->lessee_id, lessee, lessor->lessee_id, lessor);
+
+ mutex_unlock(&dev->mode_config.idr_mutex);
+ return lessee;
+
+out_lessee:
+ mutex_unlock(&dev->mode_config.idr_mutex);
+
+ drm_master_put(&lessee);
+
+ return ERR_PTR(error);
+}
+
+/**
+ * drm_lease_destroy - a master is going away (idr_mutex not held)
+ * @master: the drm_master being destroyed
+ *
+ * All lessees will have been destroyed as they
+ * hold a reference on their lessor. Notify any
+ * lessor for this master so that it can check
+ * the list of lessees.
+ */
+void drm_lease_destroy(struct drm_master *master)
+{
+ struct drm_device *dev = master->dev;
+
+ mutex_lock(&dev->mode_config.idr_mutex);
+
+ DRM_DEBUG_LEASE("drm_lease_destroy %d\n", master->lessee_id);
+
+ /* This master is referenced by all lessees, hence it cannot be destroyed
+ * until all of them have been
+ */
+ WARN_ON(!list_empty(&master->lessees));
+
+ /* Remove this master from the lessee idr in the owner */
+ if (master->lessee_id != 0) {
+ DRM_DEBUG_LEASE("remove master %d from device list of lessees\n", master->lessee_id);
+ idr_remove(&(drm_lease_owner(master)->lessee_idr), master->lessee_id);
+ }
+
+ /* Remove this master from any lessee list it may be on */
+ list_del(&master->lessee_list);
+
+ mutex_unlock(&dev->mode_config.idr_mutex);
+
+ if (master->lessor) {
+ /* Tell the master to check the lessee list */
+ drm_sysfs_hotplug_event(dev);
+ drm_master_put(&master->lessor);
+ }
+
+ DRM_DEBUG_LEASE("drm_lease_destroy done %d\n", master->lessee_id);
+}
+
+/**
+ * _drm_lease_revoke - revoke access to all leased objects (idr_mutex held)
+ * @master: the master losing its lease
+ */
+static void _drm_lease_revoke(struct drm_master *top)
+{
+ int object;
+ void *entry;
+ struct drm_master *master = top;
+
+ lockdep_assert_held(&top->dev->mode_config.idr_mutex);
+
+ /*
+ * Walk the tree starting at 'top' emptying all leases. Because
+ * the tree is fully connected, we can do this without recursing
+ */
+ for (;;) {
+ DRM_DEBUG_LEASE("revoke leases for %p %d\n", master, master->lessee_id);
+
+ /* Evacuate the lease */
+ idr_for_each_entry(&master->leases, entry, object)
+ idr_remove(&master->leases, object);
+
+ /* Depth-first list walk */
+
+ /* Down */
+ if (!list_empty(&master->lessees)) {
+ master = list_first_entry(&master->lessees, struct drm_master, lessee_list);
+ } else {
+ /* Up */
+ while (master != top && master == list_last_entry(&master->lessor->lessees, struct drm_master, lessee_list))
+ master = master->lessor;
+
+ if (master == top)
+ break;
+
+ /* Over */
+ master = list_entry(master->lessee_list.next, struct drm_master, lessee_list);
+ }
+ }
+}
+
+/**
+ * drm_lease_revoke - revoke access to all leased objects (idr_mutex not held)
+ * @top: the master losing its lease
+ */
+void drm_lease_revoke(struct drm_master *top)
+{
+ mutex_lock(&top->dev->mode_config.idr_mutex);
+ _drm_lease_revoke(top);
+ mutex_unlock(&top->dev->mode_config.idr_mutex);
+}
+
+static int validate_lease(struct drm_device *dev,
+ struct drm_file *lessor_priv,
+ int object_count,
+ struct drm_mode_object **objects)
+{
+ int o;
+ int has_crtc = -1;
+ int has_connector = -1;
+ int has_plane = -1;
+
+ /* we want to confirm that there is at least one crtc, plane
+ connector object. */
+
+ for (o = 0; o < object_count; o++) {
+ if (objects[o]->type == DRM_MODE_OBJECT_CRTC && has_crtc == -1) {
+ has_crtc = o;
+ }
+ if (objects[o]->type == DRM_MODE_OBJECT_CONNECTOR && has_connector == -1)
+ has_connector = o;
+
+ if (lessor_priv->universal_planes) {
+ if (objects[o]->type == DRM_MODE_OBJECT_PLANE && has_plane == -1)
+ has_plane = o;
+ }
+ }
+ if (has_crtc == -1 || has_connector == -1)
+ return -EINVAL;
+ if (lessor_priv->universal_planes && has_plane == -1)
+ return -EINVAL;
+ return 0;
+}
+
+static int fill_object_idr(struct drm_device *dev,
+ struct drm_file *lessor_priv,
+ struct idr *leases,
+ int object_count,
+ u32 *object_ids)
+{
+ struct drm_mode_object **objects;
+ u32 o;
+ int ret;
+ objects = kcalloc(object_count, sizeof(struct drm_mode_object *),
+ GFP_KERNEL);
+ if (!objects)
+ return -ENOMEM;
+
+ /* step one - get references to all the mode objects
+ and check for validity. */
+ for (o = 0; o < object_count; o++) {
+ if ((int) object_ids[o] < 0) {
+ ret = -EINVAL;
+ goto out_free_objects;
+ }
+
+ objects[o] = drm_mode_object_find(dev, lessor_priv,
+ object_ids[o],
+ DRM_MODE_OBJECT_ANY);
+ if (!objects[o]) {
+ ret = -ENOENT;
+ goto out_free_objects;
+ }
+
+ if (!drm_mode_object_lease_required(objects[o]->type)) {
+ ret = -EINVAL;
+ goto out_free_objects;
+ }
+ }
+
+ ret = validate_lease(dev, lessor_priv, object_count, objects);
+ if (ret)
+ goto out_free_objects;
+
+ /* add their IDs to the lease request - taking into account
+ universal planes */
+ for (o = 0; o < object_count; o++) {
+ struct drm_mode_object *obj = objects[o];
+ u32 object_id = objects[o]->id;
+ DRM_DEBUG_LEASE("Adding object %d to lease\n", object_id);
+
+ /*
+ * We're using an IDR to hold the set of leased
+ * objects, but we don't need to point at the object's
+ * data structure from the lease as the main crtc_idr
+ * will be used to actually find that. Instead, all we
+ * really want is a 'leased/not-leased' result, for
+ * which any non-NULL pointer will work fine.
+ */
+ ret = idr_alloc(leases, &drm_lease_idr_object , object_id, object_id + 1, GFP_KERNEL);
+ if (ret < 0) {
+ DRM_DEBUG_LEASE("Object %d cannot be inserted into leases (%d)\n",
+ object_id, ret);
+ goto out_free_objects;
+ }
+ if (obj->type == DRM_MODE_OBJECT_CRTC && !lessor_priv->universal_planes) {
+ struct drm_crtc *crtc = obj_to_crtc(obj);
+ ret = idr_alloc(leases, &drm_lease_idr_object, crtc->primary->base.id, crtc->primary->base.id + 1, GFP_KERNEL);
+ if (ret < 0) {
+ DRM_DEBUG_LEASE("Object primary plane %d cannot be inserted into leases (%d)\n",
+ object_id, ret);
+ goto out_free_objects;
+ }
+ if (crtc->cursor) {
+ ret = idr_alloc(leases, &drm_lease_idr_object, crtc->cursor->base.id, crtc->cursor->base.id + 1, GFP_KERNEL);
+ if (ret < 0) {
+ DRM_DEBUG_LEASE("Object cursor plane %d cannot be inserted into leases (%d)\n",
+ object_id, ret);
+ goto out_free_objects;
+ }
+ }
+ }
+ }
+
+ ret = 0;
+out_free_objects:
+ for (o = 0; o < object_count; o++) {
+ if (objects[o])
+ drm_mode_object_put(objects[o]);
+ }
+ kfree(objects);
+ return ret;
+}
+
+/**
+ * drm_mode_create_lease_ioctl - create a new lease
+ * @dev: the drm device
+ * @data: pointer to struct drm_mode_create_lease
+ * @file_priv: the file being manipulated
+ *
+ * The master associated with the specified file will have a lease
+ * created containing the objects specified in the ioctl structure.
+ * A file descriptor will be allocated for that and returned to the
+ * application.
+ */
+int drm_mode_create_lease_ioctl(struct drm_device *dev,
+ void *data, struct drm_file *lessor_priv)
+{
+ struct drm_mode_create_lease *cl = data;
+ size_t object_count;
+ int ret = 0;
+ struct idr leases;
+ struct drm_master *lessor = lessor_priv->master;
+ struct drm_master *lessee = NULL;
+ struct file *lessee_file = NULL;
+ struct file *lessor_file = lessor_priv->filp;
+ struct drm_file *lessee_priv;
+ int fd = -1;
+ uint32_t *object_ids;
+
+ /* Can't lease without MODESET */
+ if (!drm_core_check_feature(dev, DRIVER_MODESET))
+ return -EINVAL;
+
+ /* Do not allow sub-leases */
+ if (lessor->lessor)
+ return -EINVAL;
+
+ /* need some objects */
+ if (cl->object_count == 0)
+ return -EINVAL;
+
+ if (cl->flags && (cl->flags & ~(O_CLOEXEC | O_NONBLOCK)))
+ return -EINVAL;
+
+ object_count = cl->object_count;
+
+ object_ids = memdup_user(u64_to_user_ptr(cl->object_ids), object_count * sizeof(__u32));
+ if (IS_ERR(object_ids))
+ return PTR_ERR(object_ids);
+
+ idr_init(&leases);
+
+ /* fill and validate the object idr */
+ ret = fill_object_idr(dev, lessor_priv, &leases,
+ object_count, object_ids);
+ kfree(object_ids);
+ if (ret) {
+ idr_destroy(&leases);
+ return ret;
+ }
+
+ /* Allocate a file descriptor for the lease */
+ fd = get_unused_fd_flags(cl->flags & (O_CLOEXEC | O_NONBLOCK));
+ if (fd < 0) {
+ idr_destroy(&leases);
+ return fd;
+ }
+
+ DRM_DEBUG_LEASE("Creating lease\n");
+ lessee = drm_lease_create(lessor, &leases);
+
+ if (IS_ERR(lessee)) {
+ ret = PTR_ERR(lessee);
+ goto out_leases;
+ }
+
+ /* Clone the lessor file to create a new file for us */
+ DRM_DEBUG_LEASE("Allocating lease file\n");
+ path_get(&lessor_file->f_path);
+ lessee_file = alloc_file(&lessor_file->f_path,
+ lessor_file->f_mode,
+ fops_get(lessor_file->f_inode->i_fop));
+
+ if (IS_ERR(lessee_file)) {
+ ret = PTR_ERR(lessee_file);
+ goto out_lessee;
+ }
+
+ /* Initialize the new file for DRM */
+ DRM_DEBUG_LEASE("Initializing the file with %p\n", lessee_file->f_op->open);
+ ret = lessee_file->f_op->open(lessee_file->f_inode, lessee_file);
+ if (ret)
+ goto out_lessee_file;
+
+ lessee_priv = lessee_file->private_data;
+
+ /* Change the file to a master one */
+ drm_master_put(&lessee_priv->master);
+ lessee_priv->master = lessee;
+ lessee_priv->is_master = 1;
+ lessee_priv->authenticated = 1;
+
+ /* Hook up the fd */
+ fd_install(fd, lessee_file);
+
+ /* Pass fd back to userspace */
+ DRM_DEBUG_LEASE("Returning fd %d id %d\n", fd, lessee->lessee_id);
+ cl->fd = fd;
+ cl->lessee_id = lessee->lessee_id;
+
+ DRM_DEBUG_LEASE("drm_mode_create_lease_ioctl succeeded\n");
+ return 0;
+
+out_lessee_file:
+ fput(lessee_file);
+
+out_lessee:
+ drm_master_put(&lessee);
+
+out_leases:
+ put_unused_fd(fd);
+ idr_destroy(&leases);
+
+ DRM_DEBUG_LEASE("drm_mode_create_lease_ioctl failed: %d\n", ret);
+ return ret;
+}
+
+/**
+ * drm_mode_list_lessees_ioctl - list lessee ids
+ * @dev: the drm device
+ * @data: pointer to struct drm_mode_list_lessees
+ * @lessor_priv: the file being manipulated
+ *
+ * Starting from the master associated with the specified file,
+ * the master with the provided lessee_id is found, and then
+ * an array of lessee ids associated with leases from that master
+ * are returned.
+ */
+
+int drm_mode_list_lessees_ioctl(struct drm_device *dev,
+ void *data, struct drm_file *lessor_priv)
+{
+ struct drm_mode_list_lessees *arg = data;
+ __u32 __user *lessee_ids = (__u32 __user *) (uintptr_t) (arg->lessees_ptr);
+ __u32 count_lessees = arg->count_lessees;
+ struct drm_master *lessor = lessor_priv->master, *lessee;
+ int count;
+ int ret = 0;
+
+ if (arg->pad)
+ return -EINVAL;
+
+ /* Can't lease without MODESET */
+ if (!drm_core_check_feature(dev, DRIVER_MODESET))
+ return -EINVAL;
+
+ DRM_DEBUG_LEASE("List lessees for %d\n", lessor->lessee_id);
+
+ mutex_lock(&dev->mode_config.idr_mutex);
+
+ count = 0;
+ drm_for_each_lessee(lessee, lessor) {
+ /* Only list un-revoked leases */
+ if (!idr_is_empty(&lessee->leases)) {
+ if (count_lessees > count) {
+ DRM_DEBUG_LEASE("Add lessee %d\n", lessee->lessee_id);
+ ret = put_user(lessee->lessee_id, lessee_ids + count);
+ if (ret)
+ break;
+ }
+ count++;
+ }
+ }
+
+ DRM_DEBUG_LEASE("Lessor leases to %d\n", count);
+ if (ret == 0)
+ arg->count_lessees = count;
+
+ mutex_unlock(&dev->mode_config.idr_mutex);
+
+ return ret;
+}
+
+/**
+ * drm_mode_get_lease_ioctl - list leased objects
+ * @dev: the drm device
+ * @data: pointer to struct drm_mode_get_lease
+ * @file_priv: the file being manipulated
+ *
+ * Return the list of leased objects for the specified lessee
+ */
+
+int drm_mode_get_lease_ioctl(struct drm_device *dev,
+ void *data, struct drm_file *lessee_priv)
+{
+ struct drm_mode_get_lease *arg = data;
+ __u32 __user *object_ids = (__u32 __user *) (uintptr_t) (arg->objects_ptr);
+ __u32 count_objects = arg->count_objects;
+ struct drm_master *lessee = lessee_priv->master;
+ struct idr *object_idr;
+ int count;
+ void *entry;
+ int object;
+ int ret = 0;
+
+ if (arg->pad)
+ return -EINVAL;
+
+ /* Can't lease without MODESET */
+ if (!drm_core_check_feature(dev, DRIVER_MODESET))
+ return -EINVAL;
+
+ DRM_DEBUG_LEASE("get lease for %d\n", lessee->lessee_id);
+
+ mutex_lock(&dev->mode_config.idr_mutex);
+
+ if (lessee->lessor == NULL)
+ /* owner can use all objects */
+ object_idr = &lessee->dev->mode_config.crtc_idr;
+ else
+ /* lessee can only use allowed object */
+ object_idr = &lessee->leases;
+
+ count = 0;
+ idr_for_each_entry(object_idr, entry, object) {
+ if (count_objects > count) {
+ DRM_DEBUG_LEASE("adding object %d\n", object);
+ ret = put_user(object, object_ids + count);
+ if (ret)
+ break;
+ }
+ count++;
+ }
+
+ DRM_DEBUG("lease holds %d objects\n", count);
+ if (ret == 0)
+ arg->count_objects = count;
+
+ mutex_unlock(&dev->mode_config.idr_mutex);
+
+ return ret;
+}
+
+/**
+ * drm_mode_revoke_lease_ioctl - revoke lease
+ * @dev: the drm device
+ * @data: pointer to struct drm_mode_revoke_lease
+ * @file_priv: the file being manipulated
+ *
+ * This removes all of the objects from the lease without
+ * actually getting rid of the lease itself; that way all
+ * references to it still work correctly
+ */
+int drm_mode_revoke_lease_ioctl(struct drm_device *dev,
+ void *data, struct drm_file *lessor_priv)
+{
+ struct drm_mode_revoke_lease *arg = data;
+ struct drm_master *lessor = lessor_priv->master;
+ struct drm_master *lessee;
+ int ret = 0;
+
+ DRM_DEBUG_LEASE("revoke lease for %d\n", arg->lessee_id);
+
+ /* Can't lease without MODESET */
+ if (!drm_core_check_feature(dev, DRIVER_MODESET))
+ return -EINVAL;
+
+ mutex_lock(&dev->mode_config.idr_mutex);
+
+ lessee = _drm_find_lessee(lessor, arg->lessee_id);
+
+ /* No such lessee */
+ if (!lessee) {
+ ret = -ENOENT;
+ goto fail;
+ }
+
+ /* Lease is not held by lessor */
+ if (lessee->lessor != lessor) {
+ ret = -EACCES;
+ goto fail;
+ }
+
+ _drm_lease_revoke(lessee);
+
+fail:
+ mutex_unlock(&dev->mode_config.idr_mutex);
+
+ return ret;
+}
diff --git a/drivers/gpu/drm/drm_mode_config.c b/drivers/gpu/drm/drm_mode_config.c
index 74f6ff5df656..9b30fc191fb4 100644
--- a/drivers/gpu/drm/drm_mode_config.c
+++ b/drivers/gpu/drm/drm_mode_config.c
@@ -122,10 +122,12 @@ int drm_mode_getresources(struct drm_device *dev, void *data,
count = 0;
crtc_id = u64_to_user_ptr(card_res->crtc_id_ptr);
drm_for_each_crtc(crtc, dev) {
- if (count < card_res->count_crtcs &&
- put_user(crtc->base.id, crtc_id + count))
- return -EFAULT;
- count++;
+ if (drm_lease_held(file_priv, crtc->base.id)) {
+ if (count < card_res->count_crtcs &&
+ put_user(crtc->base.id, crtc_id + count))
+ return -EFAULT;
+ count++;
+ }
}
card_res->count_crtcs = count;
@@ -143,12 +145,14 @@ int drm_mode_getresources(struct drm_device *dev, void *data,
count = 0;
connector_id = u64_to_user_ptr(card_res->connector_id_ptr);
drm_for_each_connector_iter(connector, &conn_iter) {
- if (count < card_res->count_connectors &&
- put_user(connector->base.id, connector_id + count)) {
- drm_connector_list_iter_end(&conn_iter);
- return -EFAULT;
+ if (drm_lease_held(file_priv, connector->base.id)) {
+ if (count < card_res->count_connectors &&
+ put_user(connector->base.id, connector_id + count)) {
+ drm_connector_list_iter_end(&conn_iter);
+ return -EFAULT;
+ }
+ count++;
}
- count++;
}
card_res->count_connectors = count;
drm_connector_list_iter_end(&conn_iter);
diff --git a/drivers/gpu/drm/drm_mode_object.c b/drivers/gpu/drm/drm_mode_object.c
index 5b692ce6a45d..5fb26565e11c 100644
--- a/drivers/gpu/drm/drm_mode_object.c
+++ b/drivers/gpu/drm/drm_mode_object.c
@@ -104,7 +104,27 @@ void drm_mode_object_unregister(struct drm_device *dev,
mutex_unlock(&dev->mode_config.idr_mutex);
}
+/**
+ * drm_lease_required - check types which must be leased to be used
+ * @type: type of object
+ *
+ * Returns whether the provided type of drm_mode_object must
+ * be owned or leased to be used by a process.
+ */
+bool drm_mode_object_lease_required(uint32_t type)
+{
+ switch(type) {
+ case DRM_MODE_OBJECT_CRTC:
+ case DRM_MODE_OBJECT_CONNECTOR:
+ case DRM_MODE_OBJECT_PLANE:
+ return true;
+ default:
+ return false;
+ }
+}
+
struct drm_mode_object *__drm_mode_object_find(struct drm_device *dev,
+ struct drm_file *file_priv,
uint32_t id, uint32_t type)
{
struct drm_mode_object *obj = NULL;
@@ -116,6 +136,10 @@ struct drm_mode_object *__drm_mode_object_find(struct drm_device *dev,
if (obj && obj->id != id)
obj = NULL;
+ if (obj && drm_mode_object_lease_required(obj->type) &&
+ !_drm_lease_held(file_priv, obj->id))
+ obj = NULL;
+
if (obj && obj->free_cb) {
if (!kref_get_unless_zero(&obj->refcount))
obj = NULL;
@@ -127,7 +151,7 @@ struct drm_mode_object *__drm_mode_object_find(struct drm_device *dev,
/**
* drm_mode_object_find - look up a drm object with static lifetime
- * @dev: drm device
+ * @file_priv: drm file
* @id: id of the mode object
* @type: type of the mode object
*
@@ -136,11 +160,12 @@ struct drm_mode_object *__drm_mode_object_find(struct drm_device *dev,
* by callind drm_mode_object_put().
*/
struct drm_mode_object *drm_mode_object_find(struct drm_device *dev,
+ struct drm_file *file_priv,
uint32_t id, uint32_t type)
{
struct drm_mode_object *obj = NULL;
- obj = __drm_mode_object_find(dev, id, type);
+ obj = __drm_mode_object_find(dev, file_priv, id, type);
return obj;
}
EXPORT_SYMBOL(drm_mode_object_find);
@@ -358,7 +383,7 @@ int drm_mode_obj_get_properties_ioctl(struct drm_device *dev, void *data,
drm_modeset_lock_all(dev);
- obj = drm_mode_object_find(dev, arg->obj_id, arg->obj_type);
+ obj = drm_mode_object_find(dev, file_priv, arg->obj_id, arg->obj_type);
if (!obj) {
ret = -ENOENT;
goto out;
@@ -481,7 +506,7 @@ int drm_mode_obj_set_property_ioctl(struct drm_device *dev, void *data,
if (!drm_core_check_feature(dev, DRIVER_MODESET))
return -EINVAL;
- arg_obj = drm_mode_object_find(dev, arg->obj_id, arg->obj_type);
+ arg_obj = drm_mode_object_find(dev, file_priv, arg->obj_id, arg->obj_type);
if (!arg_obj)
return -ENOENT;
diff --git a/drivers/gpu/drm/drm_modeset_helper.c b/drivers/gpu/drm/drm_modeset_helper.c
index 9cb1eede0b4d..f1c24ab0ef09 100644
--- a/drivers/gpu/drm/drm_modeset_helper.c
+++ b/drivers/gpu/drm/drm_modeset_helper.c
@@ -20,6 +20,9 @@
* OF THIS SOFTWARE.
*/
+#include <drm/drm_atomic_helper.h>
+#include <drm/drm_crtc_helper.h>
+#include <drm/drm_fb_helper.h>
#include <drm/drm_modeset_helper.h>
#include <drm/drm_plane_helper.h>
@@ -156,3 +159,76 @@ int drm_crtc_init(struct drm_device *dev, struct drm_crtc *crtc,
NULL);
}
EXPORT_SYMBOL(drm_crtc_init);
+
+/**
+ * drm_mode_config_helper_suspend - Modeset suspend helper
+ * @dev: DRM device
+ *
+ * This helper function takes care of suspending the modeset side. It disables
+ * output polling if initialized, suspends fbdev if used and finally calls
+ * drm_atomic_helper_suspend().
+ * If suspending fails, fbdev and polling is re-enabled.
+ *
+ * Returns:
+ * Zero on success, negative error code on error.
+ *
+ * See also:
+ * drm_kms_helper_poll_disable() and drm_fb_helper_set_suspend_unlocked().
+ */
+int drm_mode_config_helper_suspend(struct drm_device *dev)
+{
+ struct drm_atomic_state *state;
+
+ if (!dev)
+ return 0;
+
+ drm_kms_helper_poll_disable(dev);
+ drm_fb_helper_set_suspend_unlocked(dev->fb_helper, 1);
+ state = drm_atomic_helper_suspend(dev);
+ if (IS_ERR(state)) {
+ drm_fb_helper_set_suspend_unlocked(dev->fb_helper, 0);
+ drm_kms_helper_poll_enable(dev);
+ return PTR_ERR(state);
+ }
+
+ dev->mode_config.suspend_state = state;
+
+ return 0;
+}
+EXPORT_SYMBOL(drm_mode_config_helper_suspend);
+
+/**
+ * drm_mode_config_helper_resume - Modeset resume helper
+ * @dev: DRM device
+ *
+ * This helper function takes care of resuming the modeset side. It calls
+ * drm_atomic_helper_resume(), resumes fbdev if used and enables output polling
+ * if initiaized.
+ *
+ * Returns:
+ * Zero on success, negative error code on error.
+ *
+ * See also:
+ * drm_fb_helper_set_suspend_unlocked() and drm_kms_helper_poll_enable().
+ */
+int drm_mode_config_helper_resume(struct drm_device *dev)
+{
+ int ret;
+
+ if (!dev)
+ return 0;
+
+ if (WARN_ON(!dev->mode_config.suspend_state))
+ return -EINVAL;
+
+ ret = drm_atomic_helper_resume(dev, dev->mode_config.suspend_state);
+ if (ret)
+ DRM_ERROR("Failed to resume (%d)\n", ret);
+ dev->mode_config.suspend_state = NULL;
+
+ drm_fb_helper_set_suspend_unlocked(dev->fb_helper, 0);
+ drm_kms_helper_poll_enable(dev);
+
+ return ret;
+}
+EXPORT_SYMBOL(drm_mode_config_helper_resume);
diff --git a/drivers/gpu/drm/drm_of.c b/drivers/gpu/drm/drm_of.c
index 8dafbdfcd2ea..610540406c94 100644
--- a/drivers/gpu/drm/drm_of.c
+++ b/drivers/gpu/drm/drm_of.c
@@ -90,8 +90,10 @@ void drm_of_component_match_add(struct device *master,
EXPORT_SYMBOL_GPL(drm_of_component_match_add);
/**
- * drm_of_component_probe - Generic probe function for a component based master
+ * drm_of_component_probe_with_match - Generic probe function with match
+ * entries for a component based master
* @dev: master device containing the OF node
+ * @match: component match pointer provided to store matches
* @compare_of: compare function used for matching components
* @master_ops: component master ops to be used
*
@@ -102,12 +104,12 @@ EXPORT_SYMBOL_GPL(drm_of_component_match_add);
*
* Returns zero if successful, or one of the standard error codes if it fails.
*/
-int drm_of_component_probe(struct device *dev,
+int drm_of_component_probe_with_match(struct device *dev,
+ struct component_match *match,
int (*compare_of)(struct device *, void *),
const struct component_master_ops *m_ops)
{
struct device_node *ep, *port, *remote;
- struct component_match *match = NULL;
int i;
if (!dev->of_node)
@@ -175,6 +177,29 @@ int drm_of_component_probe(struct device *dev,
return component_master_add_with_match(dev, m_ops, match);
}
+EXPORT_SYMBOL(drm_of_component_probe_with_match);
+
+/**
+ * drm_of_component_probe - Generic probe function for a component based master
+ * @dev: master device containing the OF node
+ * @compare_of: compare function used for matching components
+ * @master_ops: component master ops to be used
+ *
+ * Parse the platform device OF node and bind all the components associated
+ * with the master. Interface ports are added before the encoders in order to
+ * satisfy their .bind requirements
+ * See Documentation/devicetree/bindings/graph.txt for the bindings.
+ *
+ * Returns zero if successful, or one of the standard error codes if it fails.
+ */
+int drm_of_component_probe(struct device *dev,
+ int (*compare_of)(struct device *, void *),
+ const struct component_master_ops *m_ops)
+{
+ struct component_match *match = NULL;
+
+ return drm_of_component_probe_with_match(dev, match, compare_of, m_ops);
+}
EXPORT_SYMBOL(drm_of_component_probe);
/*
diff --git a/drivers/gpu/drm/drm_plane.c b/drivers/gpu/drm/drm_plane.c
index 71186bf90760..f253b85b9758 100644
--- a/drivers/gpu/drm/drm_plane.c
+++ b/drivers/gpu/drm/drm_plane.c
@@ -496,9 +496,11 @@ int drm_mode_getplane_res(struct drm_device *dev, void *data,
!file_priv->universal_planes)
continue;
- if (put_user(plane->base.id, plane_ptr + copied))
- return -EFAULT;
- copied++;
+ if (drm_lease_held(file_priv, plane->base.id)) {
+ if (put_user(plane->base.id, plane_ptr + copied))
+ return -EFAULT;
+ copied++;
+ }
}
}
plane_resp->count_planes = num_planes;
@@ -516,14 +518,14 @@ int drm_mode_getplane(struct drm_device *dev, void *data,
if (!drm_core_check_feature(dev, DRIVER_MODESET))
return -EINVAL;
- plane = drm_plane_find(dev, plane_resp->plane_id);
+ plane = drm_plane_find(dev, file_priv, plane_resp->plane_id);
if (!plane)
return -ENOENT;
drm_modeset_lock(&plane->mutex, NULL);
- if (plane->state && plane->state->crtc)
+ if (plane->state && plane->state->crtc && drm_lease_held(file_priv, plane->state->crtc->base.id))
plane_resp->crtc_id = plane->state->crtc->base.id;
- else if (!plane->state && plane->crtc)
+ else if (!plane->state && plane->crtc && drm_lease_held(file_priv, plane->crtc->base.id))
plane_resp->crtc_id = plane->crtc->base.id;
else
plane_resp->crtc_id = 0;
@@ -537,7 +539,9 @@ int drm_mode_getplane(struct drm_device *dev, void *data,
drm_modeset_unlock(&plane->mutex);
plane_resp->plane_id = plane->base.id;
- plane_resp->possible_crtcs = plane->possible_crtcs;
+ plane_resp->possible_crtcs = drm_lease_filter_crtcs(file_priv,
+ plane->possible_crtcs);
+
plane_resp->gamma_size = 0;
/*
@@ -705,7 +709,7 @@ int drm_mode_setplane(struct drm_device *dev, void *data,
* First, find the plane, crtc, and fb objects. If not available,
* we don't bother to call the driver.
*/
- plane = drm_plane_find(dev, plane_req->plane_id);
+ plane = drm_plane_find(dev, file_priv, plane_req->plane_id);
if (!plane) {
DRM_DEBUG_KMS("Unknown plane ID %d\n",
plane_req->plane_id);
@@ -713,14 +717,14 @@ int drm_mode_setplane(struct drm_device *dev, void *data,
}
if (plane_req->fb_id) {
- fb = drm_framebuffer_lookup(dev, plane_req->fb_id);
+ fb = drm_framebuffer_lookup(dev, file_priv, plane_req->fb_id);
if (!fb) {
DRM_DEBUG_KMS("Unknown framebuffer ID %d\n",
plane_req->fb_id);
return -ENOENT;
}
- crtc = drm_crtc_find(dev, plane_req->crtc_id);
+ crtc = drm_crtc_find(dev, file_priv, plane_req->crtc_id);
if (!crtc) {
drm_framebuffer_put(fb);
DRM_DEBUG_KMS("Unknown crtc ID %d\n",
@@ -831,7 +835,7 @@ static int drm_mode_cursor_common(struct drm_device *dev,
if (!req->flags || (~DRM_MODE_CURSOR_FLAGS & req->flags))
return -EINVAL;
- crtc = drm_crtc_find(dev, req->crtc_id);
+ crtc = drm_crtc_find(dev, file_priv, req->crtc_id);
if (!crtc) {
DRM_DEBUG_KMS("Unknown CRTC ID %d\n", req->crtc_id);
return -ENOENT;
@@ -945,7 +949,7 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev,
if ((page_flip->flags & DRM_MODE_PAGE_FLIP_ASYNC) && !dev->mode_config.async_page_flip)
return -EINVAL;
- crtc = drm_crtc_find(dev, page_flip->crtc_id);
+ crtc = drm_crtc_find(dev, file_priv, page_flip->crtc_id);
if (!crtc)
return -ENOENT;
@@ -1006,7 +1010,7 @@ retry:
goto out;
}
- fb = drm_framebuffer_lookup(dev, page_flip->fb_id);
+ fb = drm_framebuffer_lookup(dev, file_priv, page_flip->fb_id);
if (!fb) {
ret = -ENOENT;
goto out;
diff --git a/drivers/gpu/drm/drm_probe_helper.c b/drivers/gpu/drm/drm_probe_helper.c
index adbabf16c07b..baddc666d5b2 100644
--- a/drivers/gpu/drm/drm_probe_helper.c
+++ b/drivers/gpu/drm/drm_probe_helper.c
@@ -99,7 +99,7 @@ drm_mode_validate_pipeline(struct drm_display_mode *mode,
/* Step 2: Validate against encoders and crtcs */
for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
- struct drm_encoder *encoder = drm_encoder_find(dev, ids[i]);
+ struct drm_encoder *encoder = drm_encoder_find(dev, NULL, ids[i]);
struct drm_crtc *crtc;
if (!encoder)
diff --git a/drivers/gpu/drm/drm_property.c b/drivers/gpu/drm/drm_property.c
index 78e630771214..d2375cf783d3 100644
--- a/drivers/gpu/drm/drm_property.c
+++ b/drivers/gpu/drm/drm_property.c
@@ -450,7 +450,7 @@ int drm_mode_getproperty_ioctl(struct drm_device *dev,
if (!drm_core_check_feature(dev, DRIVER_MODESET))
return -EINVAL;
- property = drm_property_find(dev, out_resp->prop_id);
+ property = drm_property_find(dev, file_priv, out_resp->prop_id);
if (!property)
return -ENOENT;
@@ -634,7 +634,7 @@ struct drm_property_blob *drm_property_lookup_blob(struct drm_device *dev,
struct drm_mode_object *obj;
struct drm_property_blob *blob = NULL;
- obj = __drm_mode_object_find(dev, id, DRM_MODE_OBJECT_BLOB);
+ obj = __drm_mode_object_find(dev, NULL, id, DRM_MODE_OBJECT_BLOB);
if (obj)
blob = obj_to_blob(obj);
return blob;
@@ -897,7 +897,7 @@ bool drm_property_change_valid_get(struct drm_property *property,
if (value == 0)
return true;
- *ref = __drm_mode_object_find(property->dev, value,
+ *ref = __drm_mode_object_find(property->dev, NULL, value,
property->values[0]);
return *ref != NULL;
}
diff --git a/drivers/gpu/drm/drm_simple_kms_helper.c b/drivers/gpu/drm/drm_simple_kms_helper.c
index dc9fd109de14..b7840cf34808 100644
--- a/drivers/gpu/drm/drm_simple_kms_helper.c
+++ b/drivers/gpu/drm/drm_simple_kms_helper.c
@@ -34,6 +34,20 @@ static const struct drm_encoder_funcs drm_simple_kms_encoder_funcs = {
.destroy = drm_encoder_cleanup,
};
+static enum drm_mode_status
+drm_simple_kms_crtc_mode_valid(struct drm_crtc *crtc,
+ const struct drm_display_mode *mode)
+{
+ struct drm_simple_display_pipe *pipe;
+
+ pipe = container_of(crtc, struct drm_simple_display_pipe, crtc);
+ if (!pipe->funcs || !pipe->funcs->mode_valid)
+ /* Anything goes */
+ return MODE_OK;
+
+ return pipe->funcs->mode_valid(crtc, mode);
+}
+
static int drm_simple_kms_crtc_check(struct drm_crtc *crtc,
struct drm_crtc_state *state)
{
@@ -72,6 +86,7 @@ static void drm_simple_kms_crtc_disable(struct drm_crtc *crtc,
}
static const struct drm_crtc_helper_funcs drm_simple_kms_crtc_helper_funcs = {
+ .mode_valid = drm_simple_kms_crtc_mode_valid,
.atomic_check = drm_simple_kms_crtc_check,
.atomic_enable = drm_simple_kms_crtc_enable,
.atomic_disable = drm_simple_kms_crtc_disable,
diff --git a/drivers/gpu/drm/drm_vblank.c b/drivers/gpu/drm/drm_vblank.c
index 17e8ef9a1c11..c2f23a68da7f 100644
--- a/drivers/gpu/drm/drm_vblank.c
+++ b/drivers/gpu/drm/drm_vblank.c
@@ -1401,10 +1401,11 @@ static bool drm_wait_vblank_is_query(union drm_wait_vblank *vblwait)
int drm_wait_vblank_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_priv)
{
+ struct drm_crtc *crtc;
struct drm_vblank_crtc *vblank;
union drm_wait_vblank *vblwait = data;
int ret;
- unsigned int flags, seq, pipe, high_pipe;
+ unsigned int flags, seq, pipe_index, pipe, high_pipe;
if (!dev->irq_enabled)
return -EINVAL;
@@ -1425,9 +1426,25 @@ int drm_wait_vblank_ioctl(struct drm_device *dev, void *data,
flags = vblwait->request.type & _DRM_VBLANK_FLAGS_MASK;
high_pipe = (vblwait->request.type & _DRM_VBLANK_HIGH_CRTC_MASK);
if (high_pipe)
- pipe = high_pipe >> _DRM_VBLANK_HIGH_CRTC_SHIFT;
+ pipe_index = high_pipe >> _DRM_VBLANK_HIGH_CRTC_SHIFT;
else
- pipe = flags & _DRM_VBLANK_SECONDARY ? 1 : 0;
+ pipe_index = flags & _DRM_VBLANK_SECONDARY ? 1 : 0;
+
+ /* Convert lease-relative crtc index into global crtc index */
+ if (drm_core_check_feature(dev, DRIVER_MODESET)) {
+ pipe = 0;
+ drm_for_each_crtc(crtc, dev) {
+ if (drm_lease_held(file_priv, crtc->base.id)) {
+ if (pipe_index == 0)
+ break;
+ pipe_index--;
+ }
+ pipe++;
+ }
+ } else {
+ pipe = pipe_index;
+ }
+
if (pipe >= dev->num_crtcs)
return -EINVAL;
diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c
index ec4dd9df9150..f4eba87c96f3 100644
--- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c
+++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c
@@ -36,7 +36,7 @@ static int hibmc_connector_mode_valid(struct drm_connector *connector,
static struct drm_encoder *
hibmc_connector_best_encoder(struct drm_connector *connector)
{
- return drm_encoder_find(connector->dev, connector->encoder_ids[0]);
+ return drm_encoder_find(connector->dev, NULL, connector->encoder_ids[0]);
}
static const struct drm_connector_helper_funcs
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 944cb3c2ba5c..26d555f9f4f1 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -13533,7 +13533,7 @@ int intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data,
struct drm_crtc *drmmode_crtc;
struct intel_crtc *crtc;
- drmmode_crtc = drm_crtc_find(dev, pipe_from_crtc_id->crtc_id);
+ drmmode_crtc = drm_crtc_find(dev, file, pipe_from_crtc_id->crtc_id);
if (!drmmode_crtc)
return -ENOENT;
diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c
index aace22e7ccac..1b397b41cb4f 100644
--- a/drivers/gpu/drm/i915/intel_overlay.c
+++ b/drivers/gpu/drm/i915/intel_overlay.c
@@ -1134,7 +1134,7 @@ int intel_overlay_put_image_ioctl(struct drm_device *dev, void *data,
if (!params)
return -ENOMEM;
- drmmode_crtc = drm_crtc_find(dev, put_image_rec->crtc_id);
+ drmmode_crtc = drm_crtc_find(dev, file_priv, put_image_rec->crtc_id);
if (!drmmode_crtc) {
ret = -ENOENT;
goto out_free;
diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
index 41e31a454604..2403e01c9b0d 100644
--- a/drivers/gpu/drm/i915/intel_sprite.c
+++ b/drivers/gpu/drm/i915/intel_sprite.c
@@ -1118,7 +1118,7 @@ int intel_sprite_set_colorkey(struct drm_device *dev, void *data,
set->flags & I915_SET_COLORKEY_DESTINATION)
return -EINVAL;
- plane = drm_plane_find(dev, set->plane_id);
+ plane = drm_plane_find(dev, file_priv, set->plane_id);
if (!plane || plane->type != DRM_PLANE_TYPE_OVERLAY)
return -ENOENT;
diff --git a/drivers/gpu/drm/imx/Kconfig b/drivers/gpu/drm/imx/Kconfig
index c9e439c82241..402d7bee5d67 100644
--- a/drivers/gpu/drm/imx/Kconfig
+++ b/drivers/gpu/drm/imx/Kconfig
@@ -4,8 +4,8 @@ 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 IMX_IPUV3_CORE
+ depends on DRM
+ depends on IMX_IPUV3_CORE || IMX_DPU_CORE || IMX_DCSS_CORE || IMX_LCDIF_CORE
help
enable i.MX graphics support
@@ -29,7 +29,14 @@ config DRM_IMX_LDB
select DRM_PANEL
help
Choose this to enable the internal LVDS Display Bridge (LDB)
- found on i.MX53 and i.MX6 processors.
+ found on i.MX53, i.MX6 and i.MX8 processors.
+
+config DRM_IMX_IPUV3
+ tristate
+ depends on DRM_IMX
+ depends on IMX_IPUV3_CORE
+ default y if DRM_IMX=y
+ default m if DRM_IMX=m
config DRM_IMX_HDMI
tristate "Freescale i.MX DRM HDMI"
@@ -37,3 +44,27 @@ config DRM_IMX_HDMI
depends on DRM_IMX
help
Choose this if you want to use HDMI on i.MX6.
+
+config DRM_IMX_NWL_DSI
+ tristate "Support for Northwest Logic MIPI DSI displays"
+ depends on DRM_IMX
+ select MFD_SYSCON
+ select DRM_NWL_DSI
+ help
+ Choose this to enable the internal NWL MIPI DSI controller
+ found on i.MX8 processors.
+
+config DRM_IMX_SEC_DSIM
+ tristate "Support for Samsung MIPI DSIM displays"
+ depends on DRM_IMX
+ select MFD_SYSCON
+ select DRM_SEC_MIPI_DSIM
+ help
+ Choose this to enable the internal SEC MIPI DSIM controller
+ found on i.MX platform.
+
+source "drivers/gpu/drm/imx/ipuv3/Kconfig"
+source "drivers/gpu/drm/imx/dpu/Kconfig"
+source "drivers/gpu/drm/imx/hdp/Kconfig"
+source "drivers/gpu/drm/imx/dcss/Kconfig"
+source "drivers/gpu/drm/imx/lcdif/Kconfig"
diff --git a/drivers/gpu/drm/imx/Makefile b/drivers/gpu/drm/imx/Makefile
index ab6c83caceb7..9f1a39f39959 100644
--- a/drivers/gpu/drm/imx/Makefile
+++ b/drivers/gpu/drm/imx/Makefile
@@ -1,12 +1,17 @@
# SPDX-License-Identifier: GPL-2.0
-imxdrm-objs := imx-drm-core.o ipuv3-crtc.o ipuv3-plane.o
+imxdrm-objs := imx-drm-core.o
obj-$(CONFIG_DRM_IMX) += imxdrm.o
obj-$(CONFIG_DRM_IMX_PARALLEL_DISPLAY) += parallel-display.o
obj-$(CONFIG_DRM_IMX_TVE) += imx-tve.o
obj-$(CONFIG_DRM_IMX_LDB) += imx-ldb.o
-
-obj-$(CONFIG_DRM_IMX_IPUV3) += imx-ipuv3-crtc.o
obj-$(CONFIG_DRM_IMX_HDMI) += dw_hdmi-imx.o
+obj-$(CONFIG_DRM_IMX_NWL_DSI) += nwl_dsi-imx.o
+obj-$(CONFIG_DRM_IMX_SEC_DSIM) += sec_mipi_dsim-imx.o
+obj-$(CONFIG_DRM_IMX_IPUV3) += ipuv3/
+obj-$(CONFIG_DRM_IMX_DPU) += dpu/
+obj-$(CONFIG_DRM_IMX_HDP) += hdp/
+obj-$(CONFIG_DRM_IMX_DCSS) += dcss/
+obj-$(CONFIG_DRM_IMX_LCDIF) += lcdif/
diff --git a/drivers/gpu/drm/imx/dcss/Kconfig b/drivers/gpu/drm/imx/dcss/Kconfig
new file mode 100644
index 000000000000..f9581556aa3c
--- /dev/null
+++ b/drivers/gpu/drm/imx/dcss/Kconfig
@@ -0,0 +1,6 @@
+config DRM_IMX_DCSS
+ tristate
+ depends on DRM_IMX
+ depends on IMX_DCSS_CORE
+ default y if DRM_IMX=y
+ default m if DRM_IMX=m
diff --git a/drivers/gpu/drm/imx/dcss/Makefile b/drivers/gpu/drm/imx/dcss/Makefile
new file mode 100644
index 000000000000..f7f7e9e9b550
--- /dev/null
+++ b/drivers/gpu/drm/imx/dcss/Makefile
@@ -0,0 +1,4 @@
+ccflags-y += -Idrivers/gpu/drm/imx
+
+imx-dcss-crtc-objs := dcss-crtc.o dcss-plane.o dcss-kms.o
+obj-$(CONFIG_DRM_IMX_DCSS) += imx-dcss-crtc.o
diff --git a/drivers/gpu/drm/imx/dcss/dcss-crtc.c b/drivers/gpu/drm/imx/dcss/dcss-crtc.c
new file mode 100644
index 000000000000..b8ccf2e83b9c
--- /dev/null
+++ b/drivers/gpu/drm/imx/dcss/dcss-crtc.c
@@ -0,0 +1,531 @@
+/*
+ * Copyright 2017-2018 NXP
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/component.h>
+#include <linux/pm_runtime.h>
+#include <drm/drmP.h>
+#include <drm/drm_atomic.h>
+#include <drm/drm_crtc_helper.h>
+#include <drm/drm_atomic_helper.h>
+#include <video/imx-dcss.h>
+
+#include "dcss-kms.h"
+#include "dcss-plane.h"
+#include "imx-drm.h"
+#include "dcss-crtc.h"
+
+#define TRACE_FLUSH 0
+#define TRACE_VBLANK 1
+
+struct dcss_crtc {
+ struct device *dev;
+ struct drm_crtc base;
+
+ struct dcss_plane *plane[3];
+
+ int irq;
+ bool irq_enabled;
+
+ struct drm_property *alpha;
+ struct drm_property *use_global;
+ struct drm_property *dtrc_table_ofs;
+
+ struct completion en_completion;
+ struct completion dis_completion;
+
+ enum dcss_hdr10_nonlinearity opipe_nl;
+ enum dcss_hdr10_gamut opipe_g;
+ enum dcss_hdr10_pixel_range opipe_pr;
+ u32 opipe_pix_format;
+};
+
+static void dcss_crtc_reset(struct drm_crtc *crtc)
+{
+ struct imx_crtc_state *state;
+
+ if (crtc->state) {
+ if (crtc->state->mode_blob)
+ drm_property_unreference_blob(crtc->state->mode_blob);
+
+ state = to_imx_crtc_state(crtc->state);
+ memset(state, 0, sizeof(*state));
+ } else {
+ state = kzalloc(sizeof(*state), GFP_KERNEL);
+ if (!state)
+ return;
+ crtc->state = &state->base;
+ }
+
+ state->base.crtc = crtc;
+}
+
+static struct drm_crtc_state *dcss_crtc_duplicate_state(struct drm_crtc *crtc)
+{
+ struct imx_crtc_state *state;
+
+ if (!crtc->state)
+ return NULL;
+
+ state = kzalloc(sizeof(*state), GFP_KERNEL);
+ if (!state)
+ return NULL;
+
+ __drm_atomic_helper_crtc_duplicate_state(crtc, &state->base);
+
+ WARN_ON(state->base.crtc != crtc);
+ state->base.crtc = crtc;
+
+ return &state->base;
+}
+
+static void dcss_crtc_destroy_state(struct drm_crtc *crtc,
+ struct drm_crtc_state *state)
+{
+ __drm_atomic_helper_crtc_destroy_state(state);
+ kfree(to_imx_crtc_state(state));
+}
+
+static int dcss_enable_vblank(struct drm_crtc *crtc)
+{
+ struct dcss_crtc *dcss_crtc = container_of(crtc, struct dcss_crtc,
+ base);
+ struct dcss_soc *dcss = dev_get_drvdata(dcss_crtc->dev->parent);
+
+ if (dcss_crtc->irq_enabled)
+ return 0;
+
+ dcss_crtc->irq_enabled = true;
+
+ dcss_vblank_irq_enable(dcss, true);
+
+ dcss_dtg_ctxld_kick_irq_enable(dcss, true);
+
+ enable_irq(dcss_crtc->irq);
+
+ return 0;
+}
+
+static void dcss_disable_vblank(struct drm_crtc *crtc)
+{
+ struct dcss_crtc *dcss_crtc = container_of(crtc, struct dcss_crtc,
+ base);
+ struct dcss_soc *dcss = dev_get_drvdata(dcss_crtc->dev->parent);
+
+ disable_irq_nosync(dcss_crtc->irq);
+
+ dcss_vblank_irq_enable(dcss, false);
+
+ dcss_dtg_ctxld_kick_irq_enable(dcss, false);
+
+ dcss_crtc->irq_enabled = false;
+}
+
+static const struct drm_crtc_funcs dcss_crtc_funcs = {
+ .set_config = drm_atomic_helper_set_config,
+ .destroy = drm_crtc_cleanup,
+ .page_flip = drm_atomic_helper_page_flip,
+ .reset = dcss_crtc_reset,
+ .atomic_duplicate_state = dcss_crtc_duplicate_state,
+ .atomic_destroy_state = dcss_crtc_destroy_state,
+ .enable_vblank = dcss_enable_vblank,
+ .disable_vblank = dcss_disable_vblank,
+};
+
+static int dcss_crtc_atomic_check(struct drm_crtc *crtc,
+ struct drm_crtc_state *state)
+{
+ /* TODO: other checks? */
+
+ return 0;
+}
+
+static void dcss_crtc_atomic_begin(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_crtc_state)
+{
+ drm_crtc_vblank_on(crtc);
+
+ spin_lock_irq(&crtc->dev->event_lock);
+ if (crtc->state->event) {
+ WARN_ON(drm_crtc_vblank_get(crtc));
+ drm_crtc_arm_vblank_event(crtc, crtc->state->event);
+ crtc->state->event = NULL;
+ }
+ spin_unlock_irq(&crtc->dev->event_lock);
+}
+
+static void dcss_crtc_atomic_flush(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_crtc_state)
+{
+ struct dcss_crtc *dcss_crtc = container_of(crtc, struct dcss_crtc,
+ base);
+ struct dcss_soc *dcss = dev_get_drvdata(dcss_crtc->dev->parent);
+
+ dcss_trace_module(TRACE_DRM_CRTC, TRACE_FLUSH);
+
+ if (dcss_dtg_is_enabled(dcss))
+ dcss_ctxld_enable(dcss);
+}
+
+#define YUV_MODE BIT(0)
+
+void dcss_crtc_setup_opipe(struct drm_crtc *crtc, struct drm_connector *conn,
+ u32 colorimetry, u32 eotf,
+ enum hdmi_quantization_range qr)
+{
+ struct dcss_crtc *dcss_crtc = container_of(crtc, struct dcss_crtc,
+ base);
+
+ if ((colorimetry & BIT(HDMI_EXTENDED_COLORIMETRY_BT2020)) ||
+ (colorimetry & BIT(HDMI_EXTENDED_COLORIMETRY_BT2020_CONST_LUM)))
+ dcss_crtc->opipe_g = G_REC2020;
+ else if ((colorimetry & BIT(HDMI_EXTENDED_COLORIMETRY_ADOBE_RGB)) &&
+ !(crtc->state->adjusted_mode.private_flags & YUV_MODE))
+ dcss_crtc->opipe_g = G_ADOBE_ARGB;
+ else
+ dcss_crtc->opipe_g = G_REC709;
+
+ if (dcss_crtc->opipe_g == G_REC2020)
+ dcss_crtc->opipe_nl = NL_REC2084;
+ else if (dcss_crtc->opipe_g == G_ADOBE_ARGB)
+ dcss_crtc->opipe_nl = NL_SRGB;
+ else
+ dcss_crtc->opipe_nl = NL_REC709;
+
+ if (qr == HDMI_QUANTIZATION_RANGE_FULL)
+ dcss_crtc->opipe_pr = PR_FULL;
+ else
+ dcss_crtc->opipe_pr = PR_LIMITED;
+
+ /*
+ * private_flags is set in the connector driver in the mode_fixup()
+ * phase. Also, the DCSS HDR10 output pipe color depth is always
+ * 10-bit.
+ */
+ if (crtc->state->adjusted_mode.private_flags & YUV_MODE)
+ dcss_crtc->opipe_pix_format = DRM_FORMAT_P010;
+ else
+ dcss_crtc->opipe_pix_format = DRM_FORMAT_ARGB2101010;
+
+ DRM_DEBUG_KMS("OPIPE_CFG: gamut = %d, nl = %d, pr = %d, pix_fmt = %d\n",
+ dcss_crtc->opipe_g, dcss_crtc->opipe_nl,
+ dcss_crtc->opipe_pr, dcss_crtc->opipe_pix_format);
+}
+
+int dcss_crtc_get_opipe_cfg(struct drm_crtc *crtc,
+ struct dcss_hdr10_pipe_cfg *opipe_cfg)
+{
+ struct dcss_crtc *dcss_crtc = container_of(crtc, struct dcss_crtc,
+ base);
+
+ opipe_cfg->pixel_format = dcss_crtc->opipe_pix_format;
+ opipe_cfg->g = dcss_crtc->opipe_g;
+ opipe_cfg->nl = dcss_crtc->opipe_nl;
+ opipe_cfg->pr = dcss_crtc->opipe_pr;
+
+ return 0;
+}
+
+static void dcss_crtc_atomic_enable(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_crtc_state)
+{
+ struct dcss_crtc *dcss_crtc = container_of(crtc, struct dcss_crtc,
+ base);
+ struct dcss_soc *dcss = dev_get_drvdata(dcss_crtc->dev->parent);
+ struct drm_display_mode *mode = &crtc->state->adjusted_mode;
+ struct videomode vm;
+
+ drm_display_mode_to_videomode(mode, &vm);
+
+ pm_runtime_get_sync(dcss_crtc->dev->parent);
+
+ dcss_dtg_ctxld_kick_irq_enable(dcss, true);
+
+ dcss_dtg_sync_set(dcss, &vm);
+
+ dcss_ss_subsam_set(dcss, dcss_crtc->opipe_pix_format);
+ dcss_ss_sync_set(dcss, &vm, mode->flags & DRM_MODE_FLAG_PHSYNC,
+ mode->flags & DRM_MODE_FLAG_PVSYNC);
+
+ dcss_dtg_css_set(dcss, dcss_crtc->opipe_pix_format);
+
+ dcss_ss_enable(dcss, true);
+ dcss_dtg_enable(dcss, true, NULL);
+ dcss_ctxld_enable(dcss);
+
+ reinit_completion(&dcss_crtc->en_completion);
+ wait_for_completion_timeout(&dcss_crtc->en_completion,
+ msecs_to_jiffies(500));
+
+ crtc->enabled = true;
+}
+
+static void dcss_crtc_atomic_disable(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_crtc_state)
+{
+ struct dcss_crtc *dcss_crtc = container_of(crtc, struct dcss_crtc,
+ base);
+ struct dcss_soc *dcss = dev_get_drvdata(dcss_crtc->dev->parent);
+
+ drm_atomic_helper_disable_planes_on_crtc(old_crtc_state, false);
+
+ spin_lock_irq(&crtc->dev->event_lock);
+ if (crtc->state->event) {
+ drm_crtc_send_vblank_event(crtc, crtc->state->event);
+ crtc->state->event = NULL;
+ }
+ spin_unlock_irq(&crtc->dev->event_lock);
+
+ dcss_dtg_ctxld_kick_irq_enable(dcss, true);
+
+ dcss_ss_enable(dcss, false);
+ dcss_dtg_enable(dcss, false, &dcss_crtc->dis_completion);
+ dcss_ctxld_enable(dcss);
+
+ crtc->enabled = false;
+
+ reinit_completion(&dcss_crtc->dis_completion);
+ wait_for_completion_timeout(&dcss_crtc->dis_completion,
+ msecs_to_jiffies(100));
+
+ drm_crtc_vblank_off(crtc);
+
+ dcss_dtg_ctxld_kick_irq_enable(dcss, false);
+
+ pm_runtime_put_sync(dcss_crtc->dev->parent);
+}
+
+static enum drm_mode_status dcss_crtc_mode_valid(struct drm_crtc *crtc,
+ const struct drm_display_mode *mode)
+{
+ struct dcss_crtc *dcss_crtc = container_of(crtc, struct dcss_crtc,
+ base);
+ struct dcss_soc *dcss = dev_get_drvdata(dcss_crtc->dev->parent);
+
+ DRM_DEV_DEBUG_DRIVER(crtc->dev->dev, "Validating mode:\n");
+ drm_mode_debug_printmodeline(mode);
+ if (!dcss_dtg_mode_valid(dcss, mode->clock, mode->crtc_clock))
+ return MODE_OK;
+
+ return MODE_NOCLOCK;
+}
+
+
+static bool dcss_crtc_mode_fixup(struct drm_crtc *crtc,
+ const struct drm_display_mode *mode,
+ struct drm_display_mode *adjusted)
+{
+ struct dcss_crtc *dcss_crtc = container_of(crtc, struct dcss_crtc,
+ base);
+ struct dcss_soc *dcss = dev_get_drvdata(dcss_crtc->dev->parent);
+ int clock = adjusted->clock, crtc_clock = adjusted->crtc_clock;
+
+ DRM_DEV_DEBUG_DRIVER(crtc->dev->dev, "Fixup mode:\n");
+ DRM_DEV_DEBUG_DRIVER(crtc->dev->dev, "clock=%d, crtc_clock=%d\n",
+ clock, crtc_clock);
+ drm_mode_debug_printmodeline(adjusted);
+
+ return !dcss_dtg_mode_fixup(dcss, clock);
+}
+
+static const struct drm_crtc_helper_funcs dcss_helper_funcs = {
+ .atomic_check = dcss_crtc_atomic_check,
+ .atomic_begin = dcss_crtc_atomic_begin,
+ .atomic_flush = dcss_crtc_atomic_flush,
+ .atomic_enable = dcss_crtc_atomic_enable,
+ .atomic_disable = dcss_crtc_atomic_disable,
+ .mode_valid = dcss_crtc_mode_valid,
+ .mode_fixup = dcss_crtc_mode_fixup,
+};
+
+static irqreturn_t dcss_crtc_irq_handler(int irq, void *dev_id)
+{
+ struct dcss_crtc *dcss_crtc = dev_id;
+ struct dcss_soc *dcss = dev_get_drvdata(dcss_crtc->dev->parent);
+
+ dcss_trace_module(TRACE_DRM_CRTC, TRACE_VBLANK);
+
+ if (!dcss_dtg_vblank_irq_valid(dcss))
+ return IRQ_HANDLED;
+
+ complete(&dcss_crtc->en_completion);
+
+ if (dcss_ctxld_is_flushed(dcss))
+ drm_crtc_handle_vblank(&dcss_crtc->base);
+
+ dcss_vblank_irq_clear(dcss);
+
+ return IRQ_HANDLED;
+}
+
+static int dcss_crtc_init(struct dcss_crtc *crtc,
+ struct dcss_client_platformdata *pdata,
+ struct drm_device *drm)
+{
+ struct dcss_soc *dcss = dev_get_drvdata(crtc->dev->parent);
+ int ret;
+
+ crtc->plane[0] = dcss_plane_init(drm, dcss, drm_crtc_mask(&crtc->base),
+ DRM_PLANE_TYPE_PRIMARY, 2);
+ if (IS_ERR(crtc->plane[0]))
+ return PTR_ERR(crtc->plane[0]);
+
+ crtc->base.port = pdata->of_node;
+ drm_crtc_helper_add(&crtc->base, &dcss_helper_funcs);
+ ret = drm_crtc_init_with_planes(drm, &crtc->base, &crtc->plane[0]->base,
+ NULL, &dcss_crtc_funcs, NULL);
+ if (ret) {
+ dev_err(crtc->dev, "failed to init crtc\n");
+ return ret;
+ }
+
+ crtc->plane[1] = dcss_plane_init(drm, dcss, drm_crtc_mask(&crtc->base),
+ DRM_PLANE_TYPE_OVERLAY, 1);
+ if (IS_ERR(crtc->plane[1]))
+ crtc->plane[1] = NULL;
+
+ crtc->plane[2] = dcss_plane_init(drm, dcss, drm_crtc_mask(&crtc->base),
+ DRM_PLANE_TYPE_OVERLAY, 0);
+ if (IS_ERR(crtc->plane[2]))
+ crtc->plane[2] = NULL;
+
+ crtc->alpha = drm_property_create_range(drm, 0, "alpha", 0, 255);
+ if (!crtc->alpha) {
+ dev_err(crtc->dev, "cannot create alpha property\n");
+ return -ENOMEM;
+ }
+
+ crtc->use_global = drm_property_create_range(drm, 0,
+ "use_global_alpha", 0, 1);
+ if (!crtc->use_global) {
+ dev_err(crtc->dev, "cannot create use_global property\n");
+ return -ENOMEM;
+ }
+
+ crtc->dtrc_table_ofs = drm_property_create_range(drm, 0,
+ "dtrc_table_ofs", 0,
+ ULLONG_MAX);
+ if (!crtc->dtrc_table_ofs) {
+ dev_err(crtc->dev, "cannot create dtrc_table_ofs property\n");
+ return -ENOMEM;
+ }
+
+ /* attach alpha property to channel 0 */
+ drm_object_attach_property(&crtc->plane[0]->base.base,
+ crtc->alpha, 255);
+ crtc->plane[0]->alpha_prop = crtc->alpha;
+
+ drm_object_attach_property(&crtc->plane[0]->base.base,
+ crtc->use_global, 0);
+ crtc->plane[0]->use_global_prop = crtc->use_global;
+
+ /* attach DTRC table offsets property to overlay planes */
+ drm_object_attach_property(&crtc->plane[1]->base.base,
+ crtc->dtrc_table_ofs, 0);
+ crtc->plane[1]->dtrc_table_ofs_prop = crtc->dtrc_table_ofs;
+
+ drm_object_attach_property(&crtc->plane[2]->base.base,
+ crtc->dtrc_table_ofs, 0);
+ crtc->plane[2]->dtrc_table_ofs_prop = crtc->dtrc_table_ofs;
+
+ crtc->irq = dcss_vblank_irq_get(dcss);
+ if (crtc->irq < 0) {
+ dev_err(crtc->dev, "unable to get vblank interrupt\n");
+ return crtc->irq;
+ }
+
+ init_completion(&crtc->en_completion);
+ init_completion(&crtc->dis_completion);
+
+ ret = devm_request_irq(crtc->dev, crtc->irq, dcss_crtc_irq_handler,
+ IRQF_TRIGGER_RISING, "dcss_drm", crtc);
+ if (ret) {
+ dev_err(crtc->dev, "irq request failed with %d.\n", ret);
+ return ret;
+ }
+
+ disable_irq(crtc->irq);
+
+ return 0;
+}
+
+static int dcss_crtc_bind(struct device *dev, struct device *master,
+ void *data)
+{
+ struct dcss_client_platformdata *pdata = dev->platform_data;
+ struct drm_device *drm = data;
+ struct dcss_crtc *crtc;
+ int ret;
+
+ crtc = devm_kzalloc(dev, sizeof(*crtc), GFP_KERNEL);
+ if (!crtc)
+ return -ENOMEM;
+
+ crtc->dev = dev;
+
+ ret = dcss_crtc_init(crtc, pdata, drm);
+ if (ret)
+ return ret;
+
+ if (!drm->mode_config.funcs)
+ drm->mode_config.funcs = &dcss_drm_mode_config_funcs;
+
+ dev_set_drvdata(dev, crtc);
+
+ return 0;
+}
+
+static void dcss_crtc_unbind(struct device *dev, struct device *master,
+ void *data)
+{
+}
+
+static const struct component_ops dcss_crtc_ops = {
+ .bind = dcss_crtc_bind,
+ .unbind = dcss_crtc_unbind,
+};
+
+static int dcss_crtc_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+
+ if (!dev->platform_data) {
+ dev_err(dev, "no platform data\n");
+ return -EINVAL;
+ }
+
+ return component_add(dev, &dcss_crtc_ops);
+}
+
+static int dcss_crtc_remove(struct platform_device *pdev)
+{
+ component_del(&pdev->dev, &dcss_crtc_ops);
+ return 0;
+}
+
+static struct platform_driver dcss_crtc_driver = {
+ .driver = {
+ .name = "imx-dcss-crtc",
+ },
+ .probe = dcss_crtc_probe,
+ .remove = dcss_crtc_remove,
+};
+module_platform_driver(dcss_crtc_driver);
+
+MODULE_AUTHOR("Laurentiu Palcu <laurentiu.palcu@nxp.com>");
+MODULE_DESCRIPTION("i.MX DCSS CRTC");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:imx-dcss-crtc");
diff --git a/drivers/gpu/drm/imx/dcss/dcss-crtc.h b/drivers/gpu/drm/imx/dcss/dcss-crtc.h
new file mode 100644
index 000000000000..fabf1e5c44a6
--- /dev/null
+++ b/drivers/gpu/drm/imx/dcss/dcss-crtc.h
@@ -0,0 +1,12 @@
+#ifndef _DCSS_CRTC_H
+#include <linux/hdmi.h>
+#include <video/imx-dcss.h>
+
+void dcss_crtc_setup_opipe(struct drm_crtc *crtc, struct drm_connector *conn,
+ u32 colorimetry, u32 eotf,
+ enum hdmi_quantization_range qr);
+
+int dcss_crtc_get_opipe_cfg(struct drm_crtc *crtc,
+ struct dcss_hdr10_pipe_cfg *opipe_cfg);
+
+#endif
diff --git a/drivers/gpu/drm/imx/dcss/dcss-kms.c b/drivers/gpu/drm/imx/dcss/dcss-kms.c
new file mode 100644
index 000000000000..40cd4e1391fe
--- /dev/null
+++ b/drivers/gpu/drm/imx/dcss/dcss-kms.c
@@ -0,0 +1,208 @@
+/*
+ * Copyright 2017-2019 NXP
+ *
+ * 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 <drm/drmP.h>
+#include <drm/drm_crtc.h>
+#include <drm/drm_atomic_helper.h>
+#include <drm/drm_fb_cma_helper.h>
+#include <drm/drm_atomic.h>
+#include <drm/drm_gem_cma_helper.h>
+#include <linux/dma-buf.h>
+#include <linux/reservation.h>
+
+#include "imx-drm.h"
+#include "dcss-crtc.h"
+
+static void dcss_drm_output_poll_changed(struct drm_device *drm)
+{
+ struct imx_drm_device *imxdrm = drm->dev_private;
+
+ drm_fbdev_cma_hotplug_event(imxdrm->fbhelper);
+}
+
+static int dcss_drm_atomic_check(struct drm_device *drm,
+ struct drm_atomic_state *state)
+{
+ int ret;
+
+ ret = drm_atomic_helper_check_modeset(drm, state);
+ if (ret)
+ return ret;
+
+ ret = drm_atomic_helper_check_planes(drm, state);
+ if (ret)
+ return ret;
+
+ /*
+ * Check modeset again in case crtc_state->mode_changed is
+ * updated in plane's ->atomic_check callback.
+ */
+ return drm_atomic_helper_check_modeset(drm, state);
+}
+
+static void dcss_kms_setup_output_pipe(struct drm_atomic_state *state)
+{
+ struct drm_crtc *crtc;
+ struct drm_connector *connector;
+ struct drm_connector_state *conn_state;
+ struct drm_display_info *di;
+ int i;
+
+ for_each_connector_in_state(state, connector, conn_state, i) {
+ if (!connector->state->best_encoder)
+ continue;
+
+ if (!connector->state->crtc->state->active ||
+ !drm_atomic_crtc_needs_modeset(connector->state->crtc->state))
+ continue;
+
+ crtc = connector->state->crtc;
+ di = &connector->display_info;
+
+ dcss_crtc_setup_opipe(crtc, connector, di->hdmi.colorimetry,
+ di->hdmi.hdr_panel_metadata.eotf,
+ HDMI_QUANTIZATION_RANGE_FULL);
+ }
+}
+
+struct dcss_drm_commit {
+ struct work_struct work;
+ struct drm_device *dev;
+ struct drm_atomic_state *state;
+};
+
+static void dcss_drm_atomic_commit_tail(struct dcss_drm_commit *commit)
+{
+ struct drm_atomic_state *state = commit->state;
+ struct drm_device *dev = commit->dev;
+ struct imx_drm_device *imxdrm = dev->dev_private;
+
+ drm_atomic_helper_wait_for_fences(dev, state, false);
+
+ drm_atomic_helper_wait_for_dependencies(state);
+
+ drm_atomic_helper_commit_modeset_disables(dev, state);
+
+ dcss_kms_setup_output_pipe(state);
+
+ drm_atomic_helper_commit_modeset_enables(dev, state);
+
+ drm_atomic_helper_commit_planes(dev, state,
+ DRM_PLANE_COMMIT_ACTIVE_ONLY);
+
+ drm_atomic_helper_commit_hw_done(state);
+
+ drm_atomic_helper_wait_for_vblanks(dev, state);
+
+ drm_atomic_helper_cleanup_planes(dev, state);
+
+ drm_atomic_helper_commit_cleanup_done(state);
+
+ drm_atomic_state_put(state);
+
+ spin_lock(&imxdrm->commit.wait.lock);
+ imxdrm->commit.pending = false;
+ wake_up_all_locked(&imxdrm->commit.wait);
+ spin_unlock(&imxdrm->commit.wait.lock);
+
+ kfree(commit);
+}
+
+static void dcss_commit_work(struct work_struct *work)
+{
+ struct dcss_drm_commit *commit = container_of(work,
+ struct dcss_drm_commit,
+ work);
+
+ dcss_drm_atomic_commit_tail(commit);
+}
+
+static int dcss_drm_atomic_commit(struct drm_device *dev,
+ struct drm_atomic_state *state,
+ bool nonblock)
+{
+ int ret;
+ struct imx_drm_device *imxdrm = dev->dev_private;
+ struct dcss_drm_commit *commit;
+
+ if (state->async_update) {
+ ret = drm_atomic_helper_prepare_planes(dev, state);
+ if (ret)
+ return ret;
+
+ drm_atomic_helper_async_commit(dev, state);
+ drm_atomic_helper_cleanup_planes(dev, state);
+
+ return 0;
+ }
+
+ commit = kzalloc(sizeof(*commit), GFP_KERNEL);
+ if (!commit)
+ return -ENOMEM;
+
+ commit->dev = dev;
+ commit->state = state;
+
+ ret = drm_atomic_helper_setup_commit(state, nonblock);
+ if (ret)
+ goto err_free;
+
+ INIT_WORK(&commit->work, dcss_commit_work);
+
+ ret = drm_atomic_helper_prepare_planes(dev, state);
+ if (ret)
+ goto err_free;
+
+ if (!nonblock) {
+ ret = drm_atomic_helper_wait_for_fences(dev, state, true);
+ if (ret)
+ goto err;
+ }
+
+ spin_lock(&imxdrm->commit.wait.lock);
+ ret = wait_event_interruptible_locked(imxdrm->commit.wait,
+ !imxdrm->commit.pending);
+ if (ret == 0)
+ imxdrm->commit.pending = true;
+ spin_unlock(&imxdrm->commit.wait.lock);
+
+ if (ret)
+ goto err;
+
+ ret = drm_atomic_helper_swap_state(state, true);
+ if (ret)
+ goto err;
+
+ drm_atomic_state_get(state);
+ if (nonblock)
+ queue_work(imxdrm->dcss_nonblock_commit_wq, &commit->work);
+ else
+ dcss_drm_atomic_commit_tail(commit);
+
+ return 0;
+
+err:
+ drm_atomic_helper_cleanup_planes(dev, state);
+
+err_free:
+ kfree(commit);
+ return ret;
+}
+
+const struct drm_mode_config_funcs dcss_drm_mode_config_funcs = {
+ .fb_create = drm_fb_cma_create,
+ .output_poll_changed = dcss_drm_output_poll_changed,
+ .atomic_check = dcss_drm_atomic_check,
+ .atomic_commit = dcss_drm_atomic_commit,
+};
diff --git a/drivers/gpu/drm/imx/dcss/dcss-kms.h b/drivers/gpu/drm/imx/dcss/dcss-kms.h
new file mode 100644
index 000000000000..3c5395281e04
--- /dev/null
+++ b/drivers/gpu/drm/imx/dcss/dcss-kms.h
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2017 NXP
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#ifndef _DCSS_KMS_H_
+#define _DCSS_KMS_H_
+
+extern const struct drm_mode_config_funcs dcss_drm_mode_config_funcs;
+
+#endif
diff --git a/drivers/gpu/drm/imx/dcss/dcss-plane.c b/drivers/gpu/drm/imx/dcss/dcss-plane.c
new file mode 100644
index 000000000000..be866ef91582
--- /dev/null
+++ b/drivers/gpu/drm/imx/dcss/dcss-plane.c
@@ -0,0 +1,716 @@
+/*
+ * Copyright 2017-2018 NXP
+ *
+ * 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 <drm/drmP.h>
+#include <drm/drm_plane_helper.h>
+#include <drm/drm_atomic_helper.h>
+#include <drm/drm_fb_cma_helper.h>
+#include <drm/drm_gem_cma_helper.h>
+#include <drm/drm_atomic.h>
+#include <linux/dma-buf.h>
+
+#include "video/imx-dcss.h"
+#include "video/viv-metadata.h"
+#include "dcss-plane.h"
+#include "dcss-crtc.h"
+
+static const u32 dcss_common_formats[] = {
+ /* RGB */
+ DRM_FORMAT_ARGB8888,
+ DRM_FORMAT_XRGB8888,
+ DRM_FORMAT_ABGR8888,
+ DRM_FORMAT_XBGR8888,
+ DRM_FORMAT_RGBA8888,
+ DRM_FORMAT_RGBX8888,
+ DRM_FORMAT_BGRA8888,
+ DRM_FORMAT_BGRX8888,
+ DRM_FORMAT_XRGB2101010,
+ DRM_FORMAT_XBGR2101010,
+ DRM_FORMAT_RGBX1010102,
+ DRM_FORMAT_BGRX1010102,
+ DRM_FORMAT_ARGB2101010,
+ DRM_FORMAT_ABGR2101010,
+ DRM_FORMAT_RGBA1010102,
+ DRM_FORMAT_BGRA1010102,
+
+ /* YUV444 */
+ DRM_FORMAT_AYUV,
+
+ /* YUV422 */
+ DRM_FORMAT_UYVY,
+ DRM_FORMAT_VYUY,
+ DRM_FORMAT_YUYV,
+ DRM_FORMAT_YVYU,
+
+ /* YUV420 */
+ DRM_FORMAT_NV12,
+ DRM_FORMAT_NV21,
+ DRM_FORMAT_P010,
+};
+
+static const u64 dcss_video_format_modifiers[] = {
+ DRM_FORMAT_MOD_VSI_G1_TILED,
+ DRM_FORMAT_MOD_VSI_G2_TILED,
+ DRM_FORMAT_MOD_VSI_G2_TILED_COMPRESSED,
+ DRM_FORMAT_MOD_LINEAR,
+ DRM_FORMAT_MOD_INVALID,
+};
+
+static const u64 dcss_graphics_format_modifiers[] = {
+ DRM_FORMAT_MOD_VIVANTE_TILED,
+ DRM_FORMAT_MOD_VIVANTE_SUPER_TILED,
+ DRM_FORMAT_MOD_VIVANTE_SUPER_TILED_FC,
+ DRM_FORMAT_MOD_LINEAR,
+ DRM_FORMAT_MOD_INVALID,
+};
+
+static inline struct dcss_plane *to_dcss_plane(struct drm_plane *p)
+{
+ return container_of(p, struct dcss_plane, base);
+}
+
+static void dcss_plane_destroy(struct drm_plane *plane)
+{
+ struct dcss_plane *dcss_plane = container_of(plane, struct dcss_plane,
+ base);
+
+ DRM_DEBUG_KMS("destroy plane\n");
+
+ drm_plane_cleanup(plane);
+ kfree(dcss_plane);
+}
+
+static int dcss_plane_atomic_set_property(struct drm_plane *plane,
+ struct drm_plane_state *state,
+ struct drm_property *property,
+ uint64_t val)
+{
+ struct dcss_plane *dcss_plane = to_dcss_plane(plane);
+
+ if (property == dcss_plane->alpha_prop)
+ dcss_plane->alpha_val = val;
+ else if (property == dcss_plane->use_global_prop)
+ dcss_plane->use_global_val = val;
+ else if (property == dcss_plane->dtrc_table_ofs_prop)
+ dcss_plane->dtrc_table_ofs_val = val;
+ else
+ return -EINVAL;
+
+ return 0;
+}
+
+static int dcss_plane_atomic_get_property(struct drm_plane *plane,
+ const struct drm_plane_state *state,
+ struct drm_property *property,
+ uint64_t *val)
+{
+ struct dcss_plane *dcss_plane = to_dcss_plane(plane);
+
+ if (property == dcss_plane->alpha_prop)
+ *val = dcss_plane->alpha_val;
+ else if (property == dcss_plane->use_global_prop)
+ *val = dcss_plane->use_global_val;
+ else if (property == dcss_plane->dtrc_table_ofs_prop)
+ *val = dcss_plane->dtrc_table_ofs_val;
+ else
+ return -EINVAL;
+
+ return 0;
+}
+
+static bool dcss_plane_format_mod_supported(struct drm_plane *plane,
+ uint32_t format,
+ uint64_t modifier)
+{
+ switch (plane->type) {
+ case DRM_PLANE_TYPE_PRIMARY:
+ switch (format) {
+ case DRM_FORMAT_ARGB8888:
+ case DRM_FORMAT_XRGB8888:
+ case DRM_FORMAT_ARGB2101010:
+ return modifier == DRM_FORMAT_MOD_LINEAR ||
+ modifier == DRM_FORMAT_MOD_VIVANTE_TILED ||
+ modifier == DRM_FORMAT_MOD_VIVANTE_SUPER_TILED ||
+ modifier == DRM_FORMAT_MOD_VIVANTE_SUPER_TILED_FC;
+ default:
+ return modifier == DRM_FORMAT_MOD_LINEAR;
+ }
+ break;
+ case DRM_PLANE_TYPE_OVERLAY:
+ switch (format) {
+ case DRM_FORMAT_NV12:
+ case DRM_FORMAT_NV21:
+ case DRM_FORMAT_P010:
+ return modifier == DRM_FORMAT_MOD_LINEAR ||
+ modifier == DRM_FORMAT_MOD_VSI_G1_TILED ||
+ modifier == DRM_FORMAT_MOD_VSI_G2_TILED ||
+ modifier == DRM_FORMAT_MOD_VSI_G2_TILED_COMPRESSED;
+ default:
+ return modifier == DRM_FORMAT_MOD_LINEAR;
+ }
+ break;
+ default:
+ return false;
+ }
+}
+
+static const struct drm_plane_funcs dcss_plane_funcs = {
+ .update_plane = drm_atomic_helper_update_plane,
+ .disable_plane = drm_atomic_helper_disable_plane,
+ .destroy = dcss_plane_destroy,
+ .reset = drm_atomic_helper_plane_reset,
+ .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
+ .atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
+ .atomic_set_property = dcss_plane_atomic_set_property,
+ .atomic_get_property = dcss_plane_atomic_get_property,
+ .format_mod_supported = dcss_plane_format_mod_supported,
+};
+
+static bool dcss_plane_can_rotate(u32 pixel_format, bool mod_present,
+ u64 modifier, unsigned int rotation)
+{
+ enum dcss_color_space cs = dcss_drm_fourcc_to_colorspace(pixel_format);
+ bool linear_format = !mod_present ||
+ (mod_present && modifier == DRM_FORMAT_MOD_LINEAR);
+ u32 supported_rotation = DRM_MODE_ROTATE_0;
+
+ if (cs == DCSS_COLORSPACE_RGB && linear_format)
+ supported_rotation = DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180 |
+ DRM_MODE_REFLECT_MASK;
+ else if (cs == DCSS_COLORSPACE_RGB &&
+ modifier == DRM_FORMAT_MOD_VIVANTE_TILED)
+ supported_rotation = DRM_MODE_ROTATE_MASK |
+ DRM_MODE_REFLECT_MASK;
+ else if (cs == DCSS_COLORSPACE_RGB &&
+ modifier == DRM_FORMAT_MOD_VIVANTE_SUPER_TILED_FC)
+ supported_rotation = DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180 |
+ DRM_MODE_REFLECT_MASK;
+ else if (cs == DCSS_COLORSPACE_YUV && linear_format &&
+ (pixel_format == DRM_FORMAT_NV12 ||
+ pixel_format == DRM_FORMAT_NV21))
+ supported_rotation = DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180 |
+ DRM_MODE_REFLECT_MASK;
+ else if (cs == DCSS_COLORSPACE_YUV && linear_format &&
+ pixel_format == DRM_FORMAT_P010)
+ supported_rotation = DRM_MODE_ROTATE_0 | DRM_MODE_REFLECT_Y;
+
+ return !!(rotation & supported_rotation);
+}
+
+static bool dcss_plane_is_source_size_allowed(u16 src_w, u16 src_h, u32 pix_fmt)
+{
+ if (src_w < 64 &&
+ (pix_fmt == DRM_FORMAT_NV12 || pix_fmt == DRM_FORMAT_NV21 ||
+ pix_fmt == DRM_FORMAT_P010))
+ return false;
+ else if (src_w < 32 &&
+ (pix_fmt == DRM_FORMAT_UYVY || pix_fmt == DRM_FORMAT_VYUY ||
+ pix_fmt == DRM_FORMAT_YUYV || pix_fmt == DRM_FORMAT_YVYU))
+ return false;
+
+ return src_w >= 16 && src_h >= 8;
+}
+
+static int dcss_plane_atomic_check(struct drm_plane *plane,
+ struct drm_plane_state *state)
+{
+ struct dcss_plane *dcss_plane = to_dcss_plane(plane);
+ struct drm_framebuffer *fb = state->fb;
+ struct drm_gem_cma_object *cma_obj;
+ struct drm_crtc_state *crtc_state;
+ int hdisplay, vdisplay;
+ struct drm_rect crtc_rect, disp_rect;
+
+ if (!fb || !state->crtc)
+ return 0;
+
+ cma_obj = drm_fb_cma_get_gem_obj(fb, 0);
+ WARN_ON(!cma_obj);
+
+ crtc_state = drm_atomic_get_existing_crtc_state(state->state,
+ state->crtc);
+
+ hdisplay = crtc_state->adjusted_mode.hdisplay;
+ vdisplay = crtc_state->adjusted_mode.vdisplay;
+
+ crtc_rect.x1 = state->crtc_x;
+ crtc_rect.x2 = state->crtc_x + state->crtc_w;
+ crtc_rect.y1 = state->crtc_y;
+ crtc_rect.y2 = state->crtc_y + state->crtc_h;
+
+ disp_rect.x1 = 0;
+ disp_rect.y1 = 0;
+ disp_rect.x2 = hdisplay;
+ disp_rect.y2 = vdisplay;
+
+ if (!dcss_plane_is_source_size_allowed(state->src_w >> 16,
+ state->src_h >> 16,
+ fb->format->format)) {
+ DRM_DEBUG_KMS("Source plane size is not allowed!\n");
+ return -EINVAL;
+ }
+
+ /* make sure the crtc is visible */
+ if (!drm_rect_intersect(&crtc_rect, &disp_rect)) {
+ state->visible = false;
+ return 0;
+ }
+
+ state->visible = true;
+
+ if (!dcss_plane_can_rotate(fb->format->format,
+ !!(fb->flags & DRM_MODE_FB_MODIFIERS),
+ fb->modifier,
+ state->rotation)) {
+ DRM_ERROR("requested rotation is not allowed!\n");
+ return -EINVAL;
+ }
+
+ /* cropping is only available on overlay planes when DTRC is used */
+ if (state->crtc_x < 0 || state->crtc_y < 0 ||
+ state->crtc_x + state->crtc_w > hdisplay ||
+ state->crtc_y + state->crtc_h > vdisplay) {
+ if (plane->type == DRM_PLANE_TYPE_PRIMARY)
+ return -EINVAL;
+ else if (!(fb->flags & DRM_MODE_FB_MODIFIERS) ||
+ (fb->flags & DRM_MODE_FB_MODIFIERS &&
+ fb->modifier == DRM_FORMAT_MOD_LINEAR))
+ return -EINVAL;
+ }
+
+ if (!dcss_scaler_can_scale(dcss_plane->dcss, dcss_plane->ch_num,
+ state->src_w >> 16, state->src_h >> 16,
+ state->crtc_w, state->crtc_h)) {
+ DRM_DEBUG_KMS("Invalid upscale/downscale ratio.");
+ return -EINVAL;
+ }
+
+ if ((fb->flags & DRM_MODE_FB_MODIFIERS) &&
+ !plane->funcs->format_mod_supported(plane,
+ fb->format->format,
+ fb->modifier)) {
+ DRM_INFO("Invalid modifier: %llx", fb->modifier);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static struct drm_gem_object *dcss_plane_gem_import(struct drm_device *dev,
+ struct dma_buf *dma_buf)
+{
+ struct drm_gem_object *obj;
+
+ if (IS_ERR(dma_buf))
+ return ERR_CAST(dma_buf);
+
+ mutex_lock(&dev->object_name_lock);
+
+ obj = dev->driver->gem_prime_import(dev, dma_buf);
+
+ mutex_unlock(&dev->object_name_lock);
+
+ return obj;
+}
+
+static void dcss_plane_atomic_set_base(struct dcss_plane *dcss_plane)
+{
+ int mod_idx;
+ struct drm_plane *plane = &dcss_plane->base;
+ struct drm_plane_state *state = plane->state;
+ struct drm_framebuffer *fb = state->fb;
+ struct drm_gem_cma_object *cma_obj = drm_fb_cma_get_gem_obj(fb, 0);
+ unsigned long p1_ba, p2_ba;
+ dma_addr_t caddr;
+ bool modifiers_present = !!(fb->flags & DRM_MODE_FB_MODIFIERS);
+ u32 pix_format = state->fb->format->format;
+ bool compressed = true;
+ uint32_t compressed_format = 0;
+
+ BUG_ON(!cma_obj);
+
+ p1_ba = cma_obj->paddr + fb->offsets[0] +
+ fb->pitches[0] * (state->src_y >> 16) +
+ fb->format->cpp[0] * (state->src_x >> 16);
+
+ p2_ba = cma_obj->paddr + fb->offsets[1] +
+ fb->pitches[1] * (state->src_y >> 16) +
+ fb->format->cpp[0] * (state->src_x >> 16);
+
+ dcss_dpr_addr_set(dcss_plane->dcss, dcss_plane->ch_num, p1_ba, p2_ba,
+ fb->pitches[0]);
+
+ switch (plane->type) {
+ case DRM_PLANE_TYPE_PRIMARY:
+ if (!modifiers_present) {
+ /* No modifier: bypass dec400d */
+ dcss_dec400d_bypass(dcss_plane->dcss);
+ return;
+ }
+
+ for (mod_idx = 0; mod_idx < 4; mod_idx++)
+ dcss_dec400d_set_format_mod(dcss_plane->dcss,
+ pix_format,
+ mod_idx,
+ fb->modifier);
+
+ switch (fb->modifier) {
+ case DRM_FORMAT_MOD_LINEAR:
+ case DRM_FORMAT_MOD_VIVANTE_TILED:
+ case DRM_FORMAT_MOD_VIVANTE_SUPER_TILED:
+ /* Bypass dec400d */
+ dcss_dec400d_bypass(dcss_plane->dcss);
+ return;
+ case DRM_FORMAT_MOD_VIVANTE_SUPER_TILED_FC:
+ do {
+ struct dma_buf *dma_buf = cma_obj->base.dma_buf;
+ struct drm_gem_object *gem_obj;
+ _VIV_VIDMEM_METADATA *mdata;
+
+ if (!dma_buf) {
+ caddr = cma_obj->paddr + ALIGN(fb->height, 64) * fb->pitches[0];
+ break;
+ }
+
+ mdata = dma_buf->priv;
+ if (!mdata || mdata->magic != VIV_VIDMEM_METADATA_MAGIC) {
+ return;
+ }
+ compressed = mdata->compressed ? true : false;
+ compressed_format = mdata->compress_format;
+
+ gem_obj = dcss_plane_gem_import(plane->dev, mdata->ts_dma_buf);
+ if (IS_ERR(gem_obj)) {
+ return;
+ }
+
+ caddr = to_drm_gem_cma_obj(gem_obj)->paddr;
+
+ /* release gem_obj */
+ drm_gem_object_unreference_unlocked(gem_obj);
+
+ dcss_dec400d_fast_clear_config(dcss_plane->dcss,
+ mdata->fc_value,
+ mdata->fc_enabled);
+ } while (0);
+ dcss_dec400d_read_config(dcss_plane->dcss, 0, compressed, compressed_format);
+ dcss_dec400d_addr_set(dcss_plane->dcss, p1_ba, caddr);
+ break;
+ default:
+ WARN_ON(1);
+ return;
+ }
+
+ break;
+ case DRM_PLANE_TYPE_OVERLAY:
+ if (!modifiers_present ||
+ (modifiers_present && fb->modifier == DRM_FORMAT_MOD_LINEAR) ||
+ (pix_format != DRM_FORMAT_NV12 &&
+ pix_format != DRM_FORMAT_NV21 &&
+ pix_format != DRM_FORMAT_P010)) {
+ dcss_dtrc_bypass(dcss_plane->dcss, dcss_plane->ch_num);
+ return;
+ }
+
+ dcss_dtrc_set_format_mod(dcss_plane->dcss, dcss_plane->ch_num,
+ fb->modifier);
+ dcss_dtrc_addr_set(dcss_plane->dcss, dcss_plane->ch_num,
+ p1_ba, p2_ba, dcss_plane->dtrc_table_ofs_val);
+ break;
+ default:
+ WARN_ON(1);
+ return;
+ }
+}
+
+static bool dcss_plane_needs_setup(struct drm_plane_state *state,
+ struct drm_plane_state *old_state)
+{
+ struct drm_framebuffer *fb = state->fb;
+ struct drm_framebuffer *old_fb = old_state->fb;
+
+ return state->crtc_x != old_state->crtc_x ||
+ state->crtc_y != old_state->crtc_y ||
+ state->crtc_w != old_state->crtc_w ||
+ state->crtc_h != old_state->crtc_h ||
+ state->src_x != old_state->src_x ||
+ state->src_y != old_state->src_y ||
+ state->src_w != old_state->src_w ||
+ state->src_h != old_state->src_h ||
+ fb->format->format != old_fb->format->format ||
+ fb->modifier != old_fb->modifier ||
+ state->rotation != old_state->rotation;
+}
+
+static void dcss_plane_adjust(struct drm_rect *dis_rect,
+ struct drm_rect *crtc,
+ struct drm_rect *src)
+{
+ struct drm_rect new_crtc = *dis_rect, new_src;
+ u32 hscale, vscale;
+
+ hscale = ((src->x2 - src->x1) << 16) / (crtc->x2 - crtc->x1);
+ vscale = ((src->y2 - src->y1) << 16) / (crtc->y2 - crtc->y1);
+
+ drm_rect_intersect(&new_crtc, crtc);
+
+ new_src.x1 = ((new_crtc.x1 - crtc->x1) * hscale + (1 << 15)) >> 16;
+ new_src.x2 = ((new_crtc.x2 - crtc->x1) * hscale + (1 << 15)) >> 16;
+ new_src.y1 = ((new_crtc.y1 - crtc->y1) * vscale + (1 << 15)) >> 16;
+ new_src.y2 = ((new_crtc.y2 - crtc->y1) * vscale + (1 << 15)) >> 16;
+
+ *crtc = new_crtc;
+ *src = new_src;
+}
+
+static bool dcss_plane_format_has_alpha_channel(u32 pix_format)
+{
+ return pix_format == DRM_FORMAT_ARGB8888 ||
+ pix_format == DRM_FORMAT_ABGR8888 ||
+ pix_format == DRM_FORMAT_RGBA8888 ||
+ pix_format == DRM_FORMAT_BGRA8888 ||
+ pix_format == DRM_FORMAT_BGRA8888 ||
+ pix_format == DRM_FORMAT_ARGB2101010 ||
+ pix_format == DRM_FORMAT_ABGR2101010 ||
+ pix_format == DRM_FORMAT_RGBA1010102 ||
+ pix_format == DRM_FORMAT_BGRA1010102;
+}
+
+static void dcss_plane_atomic_update(struct drm_plane *plane,
+ struct drm_plane_state *old_state)
+{
+ struct drm_plane_state *state = plane->state;
+ struct dcss_plane *dcss_plane = to_dcss_plane(plane);
+ struct drm_framebuffer *fb = state->fb;
+ u32 pixel_format;
+ struct drm_crtc_state *crtc_state;
+ bool modifiers_present;
+ u32 src_w, src_h, adj_w, adj_h;
+ struct drm_rect disp, crtc, src, old_src;
+ u32 scaler_w, scaler_h;
+ struct dcss_hdr10_pipe_cfg ipipe_cfg, opipe_cfg;
+ bool enable = true;
+
+ if (!fb || !state->crtc || !state->visible)
+ return;
+
+ pixel_format = state->fb->format->format;
+ crtc_state = state->crtc->state;
+ modifiers_present = !!(fb->flags & DRM_MODE_FB_MODIFIERS);
+
+ if (old_state->fb && !drm_atomic_crtc_needs_modeset(crtc_state) &&
+ !dcss_plane_needs_setup(state, old_state) &&
+ !dcss_dtg_global_alpha_changed(dcss_plane->dcss, dcss_plane->ch_num,
+ pixel_format, dcss_plane->alpha_val,
+ dcss_plane->use_global_val)) {
+ dcss_plane_atomic_set_base(dcss_plane);
+ if (plane->type == DRM_PLANE_TYPE_PRIMARY)
+ dcss_dec400d_shadow_trig(dcss_plane->dcss);
+ return;
+ }
+
+ disp.x1 = 0;
+ disp.y1 = 0;
+ disp.x2 = crtc_state->adjusted_mode.hdisplay;
+ disp.y2 = crtc_state->adjusted_mode.vdisplay;
+
+ crtc.x1 = state->crtc_x;
+ crtc.y1 = state->crtc_y;
+ crtc.x2 = state->crtc_x + state->crtc_w;
+ crtc.y2 = state->crtc_y + state->crtc_h;
+
+ src.x1 = state->src_x >> 16;
+ src.y1 = state->src_y >> 16;
+ src.x2 = (state->src_x >> 16) + (state->src_w >> 16);
+ src.y2 = (state->src_y >> 16) + (state->src_h >> 16);
+
+ old_src = src;
+
+ dcss_plane_adjust(&disp, &crtc, &src);
+
+ /*
+ * The width and height after clipping, if image was partially
+ * outside the display area.
+ */
+ src_w = src.x2 - src.x1;
+ src_h = src.y2 - src.y1;
+
+ if (plane->type == DRM_PLANE_TYPE_OVERLAY)
+ dcss_dtrc_set_res(dcss_plane->dcss, dcss_plane->ch_num,
+ &src, &old_src, pixel_format);
+
+ /* DTRC has probably aligned the sizes. */
+ adj_w = src.x2 - src.x1;
+ adj_h = src.y2 - src.y1;
+
+ if (plane->type == DRM_PLANE_TYPE_OVERLAY &&
+ modifiers_present && fb->modifier == DRM_FORMAT_MOD_LINEAR)
+ modifiers_present = false;
+
+ dcss_dpr_format_set(dcss_plane->dcss, dcss_plane->ch_num, pixel_format,
+ modifiers_present);
+ if (!modifiers_present)
+ dcss_dpr_tile_derive(dcss_plane->dcss,
+ dcss_plane->ch_num,
+ DRM_FORMAT_MOD_LINEAR);
+ else
+ dcss_dpr_tile_derive(dcss_plane->dcss,
+ dcss_plane->ch_num,
+ fb->modifier);
+
+ dcss_dpr_set_res(dcss_plane->dcss, dcss_plane->ch_num,
+ src_w, src_h, adj_w, adj_h);
+ dcss_dpr_set_rotation(dcss_plane->dcss, dcss_plane->ch_num,
+ state->rotation);
+ dcss_plane_atomic_set_base(dcss_plane);
+
+ if (fb->modifier == DRM_FORMAT_MOD_VSI_G2_TILED_COMPRESSED) {
+ scaler_w = src.x1 ? adj_w : src_w;
+ scaler_h = src.y1 ? adj_h : src_h;
+ } else {
+ scaler_w = src_w;
+ scaler_h = src_h;
+ }
+
+ dcss_scaler_setup(dcss_plane->dcss, dcss_plane->ch_num,
+ pixel_format, scaler_w, scaler_h,
+ crtc.x2 - crtc.x1,
+ crtc.y2 - crtc.y1,
+ drm_mode_vrefresh(&crtc_state->mode));
+
+ ipipe_cfg.pixel_format = pixel_format;
+
+ dcss_crtc_get_opipe_cfg(state->crtc, &opipe_cfg);
+
+ ipipe_cfg.nl = opipe_cfg.nl == NL_REC2084 ? NL_REC2084 : NL_REC709;
+ ipipe_cfg.pr = PR_FULL;
+ ipipe_cfg.g = opipe_cfg.g == G_REC2020 ? G_REC2020 : G_REC709;
+
+ dcss_hdr10_setup(dcss_plane->dcss, dcss_plane->ch_num,
+ &ipipe_cfg, &opipe_cfg);
+
+ dcss_dtg_plane_pos_set(dcss_plane->dcss, dcss_plane->ch_num,
+ crtc.x1, crtc.y1,
+ crtc.x2 - crtc.x1,
+ crtc.y2 - crtc.y1);
+ dcss_dtg_plane_alpha_set(dcss_plane->dcss, dcss_plane->ch_num,
+ pixel_format, dcss_plane->alpha_val,
+ dcss_plane->use_global_val);
+
+ switch (plane->type) {
+ case DRM_PLANE_TYPE_PRIMARY:
+ dcss_dec400d_enable(dcss_plane->dcss);
+ break;
+ case DRM_PLANE_TYPE_OVERLAY:
+ dcss_dtrc_enable(dcss_plane->dcss, dcss_plane->ch_num, true);
+ break;
+ default:
+ WARN_ON(1);
+ break;
+ }
+
+ if (!dcss_plane->ch_num &&
+ ((dcss_plane->alpha_val == 0 &&
+ !dcss_plane_format_has_alpha_channel(pixel_format)) ||
+ (dcss_plane->alpha_val == 0 && dcss_plane->use_global_val &&
+ dcss_plane_format_has_alpha_channel(pixel_format))))
+ enable = false;
+
+ dcss_dpr_enable(dcss_plane->dcss, dcss_plane->ch_num, enable);
+ dcss_scaler_enable(dcss_plane->dcss, dcss_plane->ch_num, enable);
+
+ if (!enable)
+ dcss_dtg_plane_pos_set(dcss_plane->dcss, dcss_plane->ch_num,
+ 0, 0, 0, 0);
+
+ dcss_dtg_ch_enable(dcss_plane->dcss, dcss_plane->ch_num, enable);
+}
+
+static void dcss_plane_atomic_disable(struct drm_plane *plane,
+ struct drm_plane_state *old_state)
+{
+ struct dcss_plane *dcss_plane = to_dcss_plane(plane);
+
+ dcss_dtrc_enable(dcss_plane->dcss, dcss_plane->ch_num, false);
+ dcss_dpr_enable(dcss_plane->dcss, dcss_plane->ch_num, false);
+ dcss_scaler_enable(dcss_plane->dcss, dcss_plane->ch_num, false);
+ dcss_dtg_plane_pos_set(dcss_plane->dcss, dcss_plane->ch_num,
+ 0, 0, 0, 0);
+ dcss_dtg_ch_enable(dcss_plane->dcss, dcss_plane->ch_num, false);
+}
+
+static const struct drm_plane_helper_funcs dcss_plane_helper_funcs = {
+ .prepare_fb = drm_fb_cma_prepare_fb,
+ .atomic_check = dcss_plane_atomic_check,
+ .atomic_update = dcss_plane_atomic_update,
+ .atomic_disable = dcss_plane_atomic_disable,
+};
+
+struct dcss_plane *dcss_plane_init(struct drm_device *drm,
+ struct dcss_soc *dcss,
+ unsigned int possible_crtcs,
+ enum drm_plane_type type,
+ unsigned int zpos)
+{
+ struct dcss_plane *dcss_plane;
+ const u64 *format_modifiers = dcss_video_format_modifiers;
+ int ret;
+
+ if (zpos > 2)
+ return ERR_PTR(-EINVAL);
+
+ dcss_plane = kzalloc(sizeof(*dcss_plane), GFP_KERNEL);
+ if (!dcss_plane) {
+ DRM_ERROR("failed to allocate plane\n");
+ return ERR_PTR(-ENOMEM);
+ }
+
+ dcss_plane->dcss = dcss;
+
+ if (type == DRM_PLANE_TYPE_PRIMARY)
+ format_modifiers = dcss_graphics_format_modifiers;
+
+ ret = drm_universal_plane_init(drm, &dcss_plane->base, possible_crtcs,
+ &dcss_plane_funcs, dcss_common_formats,
+ ARRAY_SIZE(dcss_common_formats),
+ format_modifiers, type, NULL);
+ if (ret) {
+ DRM_ERROR("failed to initialize plane\n");
+ kfree(dcss_plane);
+ return ERR_PTR(ret);
+ }
+
+ if (type == DRM_PLANE_TYPE_OVERLAY)
+ dcss_plane->base.hdr_supported = true;
+
+ drm_plane_helper_add(&dcss_plane->base, &dcss_plane_helper_funcs);
+
+ ret = drm_plane_create_zpos_immutable_property(&dcss_plane->base, zpos);
+ if (ret)
+ return ERR_PTR(ret);
+
+ drm_plane_create_rotation_property(&dcss_plane->base,
+ DRM_MODE_ROTATE_0,
+ DRM_MODE_ROTATE_0 |
+ DRM_MODE_ROTATE_90 |
+ DRM_MODE_ROTATE_180 |
+ DRM_MODE_ROTATE_270 |
+ DRM_MODE_REFLECT_X |
+ DRM_MODE_REFLECT_Y);
+
+ dcss_plane->ch_num = 2 - zpos;
+ dcss_plane->alpha_val = 255;
+
+ return dcss_plane;
+}
diff --git a/drivers/gpu/drm/imx/dcss/dcss-plane.h b/drivers/gpu/drm/imx/dcss/dcss-plane.h
new file mode 100644
index 000000000000..c607551f3927
--- /dev/null
+++ b/drivers/gpu/drm/imx/dcss/dcss-plane.h
@@ -0,0 +1,28 @@
+#ifndef __DCSS_PLANE_H__
+#define __DCSS_PLANE_H__
+
+#include <drm/drm_crtc.h>
+
+struct dcss_plane {
+ struct drm_plane base;
+ struct dcss_soc *dcss;
+
+ int alpha_val;
+ struct drm_property *alpha_prop;
+
+ int use_global_val;
+ struct drm_property *use_global_prop;
+
+ uint64_t dtrc_table_ofs_val;
+ struct drm_property *dtrc_table_ofs_prop;
+
+ int ch_num;
+};
+
+struct dcss_plane *dcss_plane_init(struct drm_device *drm,
+ struct dcss_soc *dcss,
+ unsigned int possible_crtcs,
+ enum drm_plane_type type,
+ unsigned int zpos);
+
+#endif /* __DCSS_PLANE_H__ */
diff --git a/drivers/gpu/drm/imx/dpu/Kconfig b/drivers/gpu/drm/imx/dpu/Kconfig
new file mode 100644
index 000000000000..c5bd97f4f95b
--- /dev/null
+++ b/drivers/gpu/drm/imx/dpu/Kconfig
@@ -0,0 +1,6 @@
+config DRM_IMX_DPU
+ tristate
+ depends on DRM_IMX
+ depends on IMX_DPU_CORE
+ default y if DRM_IMX=y
+ default m if DRM_IMX=m
diff --git a/drivers/gpu/drm/imx/dpu/Makefile b/drivers/gpu/drm/imx/dpu/Makefile
new file mode 100644
index 000000000000..c09e487aa5c2
--- /dev/null
+++ b/drivers/gpu/drm/imx/dpu/Makefile
@@ -0,0 +1,7 @@
+ccflags-y += -Idrivers/gpu/drm/imx
+
+imx-dpu-crtc-objs := dpu-crtc.o dpu-plane.o dpu-kms.o
+obj-$(CONFIG_DRM_IMX_DPU) += imx-dpu-crtc.o
+
+imx-dpu-render-objs := dpu-blit.o
+obj-$(CONFIG_DRM_IMX_DPU) += imx-dpu-render.o
diff --git a/drivers/gpu/drm/imx/dpu/dpu-blit.c b/drivers/gpu/drm/imx/dpu/dpu-blit.c
new file mode 100644
index 000000000000..9d1aa7a3a175
--- /dev/null
+++ b/drivers/gpu/drm/imx/dpu/dpu-blit.c
@@ -0,0 +1,313 @@
+/*
+ * Copyright 2017 NXP
+ *
+ * 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 <drm/drmP.h>
+#include <drm/imx_drm.h>
+#include <linux/component.h>
+#include <linux/device.h>
+#include <linux/errno.h>
+#include <linux/export.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <video/dpu.h>
+
+#include "imx-drm.h"
+
+struct imx_drm_dpu_bliteng {
+ struct dpu_bliteng *dpu_be;
+ struct list_head list;
+};
+
+static DEFINE_MUTEX(imx_drm_dpu_bliteng_lock);
+static LIST_HEAD(imx_drm_dpu_bliteng_list);
+
+static int imx_dpu_num;
+
+static struct imx_drm_dpu_bliteng *imx_drm_dpu_bliteng_find_by_id(s32 id)
+{
+ struct imx_drm_dpu_bliteng *bliteng;
+
+ mutex_lock(&imx_drm_dpu_bliteng_lock);
+
+ list_for_each_entry(bliteng, &imx_drm_dpu_bliteng_list, list) {
+ if (id == dpu_bliteng_get_id(bliteng->dpu_be)) {
+ mutex_unlock(&imx_drm_dpu_bliteng_lock);
+ return bliteng;
+ }
+ }
+
+ mutex_unlock(&imx_drm_dpu_bliteng_lock);
+
+ return NULL;
+}
+
+static int imx_drm_dpu_set_cmdlist_ioctl(struct drm_device *drm_dev, void *data,
+ struct drm_file *file)
+{
+ struct drm_imx_dpu_set_cmdlist *req;
+ struct imx_drm_dpu_bliteng *bliteng;
+ struct dpu_bliteng *dpu_be;
+ u32 cmd_nr, *cmd, *cmd_list;
+ void *user_data;
+ s32 id = 0;
+ struct drm_imx_dpu_frame_info frame_info;
+ int ret;
+
+ req = data;
+ user_data = (void *)(unsigned long)req->user_data;
+ if (copy_from_user(&id, (void __user *)user_data,
+ sizeof(id))) {
+ return -EFAULT;
+ }
+
+ if (id != 0 && id != 1)
+ return -EINVAL;
+
+ user_data += sizeof(id);
+ if (copy_from_user(&frame_info, (void __user *)user_data,
+ sizeof(frame_info))) {
+ return -EFAULT;
+ }
+
+ bliteng = imx_drm_dpu_bliteng_find_by_id(id);
+ if (!bliteng) {
+ DRM_ERROR("Failed to get dpu_bliteng\n");
+ return -ENODEV;
+ }
+
+ dpu_be = bliteng->dpu_be;
+
+ ret = dpu_be_get(dpu_be);
+
+ cmd_nr = req->cmd_nr;
+ cmd = (u32 *)(unsigned long)req->cmd;
+ cmd_list = dpu_bliteng_get_cmd_list(dpu_be);
+
+ if (copy_from_user(cmd_list, (void __user *)cmd,
+ sizeof(*cmd) * cmd_nr)) {
+ ret = -EFAULT;
+ goto err;
+ }
+
+ dpu_be_configure_prefetch(dpu_be, frame_info.width, frame_info.height,
+ frame_info.x_offset, frame_info.y_offset,
+ frame_info.stride, frame_info.format,
+ frame_info.modifier, frame_info.baddr,
+ frame_info.uv_addr);
+
+ ret = dpu_be_blit(dpu_be, cmd_list, cmd_nr);
+
+err:
+ dpu_be_put(dpu_be);
+
+ return ret;
+}
+
+static int imx_drm_dpu_wait_ioctl(struct drm_device *drm_dev, void *data,
+ struct drm_file *file)
+{
+ struct drm_imx_dpu_wait *wait;
+ struct imx_drm_dpu_bliteng *bliteng;
+ struct dpu_bliteng *dpu_be;
+ void *user_data;
+ s32 id = 0;
+ int ret;
+
+ wait = data;
+ user_data = (void *)(unsigned long)wait->user_data;
+ if (copy_from_user(&id, (void __user *)user_data,
+ sizeof(id))) {
+ return -EFAULT;
+ }
+
+ if (id != 0 && id != 1)
+ return -EINVAL;
+
+ bliteng = imx_drm_dpu_bliteng_find_by_id(id);
+ if (!bliteng) {
+ DRM_ERROR("Failed to get dpu_bliteng\n");
+ return -ENODEV;
+ }
+
+ dpu_be = bliteng->dpu_be;
+
+ ret = dpu_be_get(dpu_be);
+
+ dpu_be_wait(dpu_be);
+
+ dpu_be_put(dpu_be);
+
+ return ret;
+}
+
+static int imx_drm_dpu_get_param_ioctl(struct drm_device *drm_dev, void *data,
+ struct drm_file *file)
+{
+ enum drm_imx_dpu_param *param = data;
+ int ret;
+
+ switch (*param) {
+ case (DRM_IMX_MAX_DPUS):
+ ret = imx_dpu_num;
+ break;
+ default:
+ ret = -EINVAL;
+ DRM_ERROR("Unknown param![%d]\n", *param);
+ break;
+ }
+
+ return ret;
+}
+
+static struct drm_ioctl_desc imx_drm_dpu_ioctls[] = {
+ DRM_IOCTL_DEF_DRV(IMX_DPU_SET_CMDLIST, imx_drm_dpu_set_cmdlist_ioctl,
+ DRM_RENDER_ALLOW),
+ DRM_IOCTL_DEF_DRV(IMX_DPU_WAIT, imx_drm_dpu_wait_ioctl,
+ DRM_RENDER_ALLOW),
+ DRM_IOCTL_DEF_DRV(IMX_DPU_GET_PARAM, imx_drm_dpu_get_param_ioctl,
+ DRM_RENDER_ALLOW),
+};
+
+static int dpu_bliteng_bind(struct device *dev, struct device *master,
+ void *data)
+{
+ struct drm_device *drm = (struct drm_device *)data;
+ struct imx_drm_dpu_bliteng *bliteng;
+ struct dpu_bliteng *dpu_bliteng = NULL;
+ int ret;
+
+ bliteng = devm_kzalloc(dev, sizeof(*bliteng), GFP_KERNEL);
+ if (!bliteng)
+ return -ENOMEM;
+
+ INIT_LIST_HEAD(&bliteng->list);
+
+ ret = dpu_bliteng_get_empty_instance(&dpu_bliteng, dev);
+ if (ret)
+ return ret;
+
+ dpu_bliteng_set_id(dpu_bliteng, imx_dpu_num);
+ dpu_bliteng_set_dev(dpu_bliteng, dev);
+
+ ret = dpu_bliteng_init(dpu_bliteng);
+ if (ret)
+ return ret;
+
+ mutex_lock(&imx_drm_dpu_bliteng_lock);
+ bliteng->dpu_be = dpu_bliteng;
+ list_add_tail(&bliteng->list, &imx_drm_dpu_bliteng_list);
+ mutex_unlock(&imx_drm_dpu_bliteng_lock);
+
+ dev_set_drvdata(dev, dpu_bliteng);
+
+ imx_dpu_num++;
+
+ if (drm->driver->num_ioctls == 0) {
+ drm->driver->ioctls = imx_drm_dpu_ioctls;
+ drm->driver->num_ioctls = ARRAY_SIZE(imx_drm_dpu_ioctls);
+ }
+
+ return 0;
+}
+
+static void dpu_bliteng_unbind(struct device *dev, struct device *master,
+ void *data)
+{
+ struct drm_device *drm = (struct drm_device *)data;
+ struct imx_drm_dpu_bliteng *bliteng;
+ struct dpu_bliteng *dpu_bliteng = dev_get_drvdata(dev);
+ s32 id = dpu_bliteng_get_id(dpu_bliteng);
+
+ bliteng = imx_drm_dpu_bliteng_find_by_id(id);
+ list_del(&bliteng->list);
+
+ dpu_bliteng_fini(dpu_bliteng);
+ dev_set_drvdata(dev, NULL);
+
+ imx_dpu_num--;
+
+ if (drm->driver->num_ioctls != 0) {
+ drm->driver->ioctls = NULL;
+ drm->driver->num_ioctls = 0;
+ }
+}
+
+static const struct component_ops dpu_bliteng_ops = {
+ .bind = dpu_bliteng_bind,
+ .unbind = dpu_bliteng_unbind,
+};
+
+static int dpu_bliteng_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+
+ if (!dev->platform_data)
+ return -EINVAL;
+
+ return component_add(dev, &dpu_bliteng_ops);
+}
+
+static int dpu_bliteng_remove(struct platform_device *pdev)
+{
+ component_del(&pdev->dev, &dpu_bliteng_ops);
+ return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int dpu_bliteng_suspend(struct device *dev)
+{
+ struct dpu_bliteng *dpu_bliteng = dev_get_drvdata(dev);
+ int ret;
+
+ if (dpu_bliteng == NULL)
+ return 0;
+
+ ret = dpu_be_get(dpu_bliteng);
+
+ dpu_be_wait(dpu_bliteng);
+
+ dpu_be_put(dpu_bliteng);
+
+ dpu_bliteng_fini(dpu_bliteng);
+
+ return 0;
+}
+
+static int dpu_bliteng_resume(struct device *dev)
+{
+ struct dpu_bliteng *dpu_bliteng = dev_get_drvdata(dev);
+
+ if (dpu_bliteng != NULL)
+ dpu_bliteng_init(dpu_bliteng);
+
+ return 0;
+}
+#endif
+
+static SIMPLE_DEV_PM_OPS(dpu_bliteng_pm_ops,
+ dpu_bliteng_suspend, dpu_bliteng_resume);
+
+struct platform_driver dpu_bliteng_driver = {
+ .driver = {
+ .name = "imx-drm-dpu-bliteng",
+ .pm = &dpu_bliteng_pm_ops,
+ },
+ .probe = dpu_bliteng_probe,
+ .remove = dpu_bliteng_remove,
+};
+
+module_platform_driver(dpu_bliteng_driver);
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("NXP Semiconductor");
+MODULE_DESCRIPTION("i.MX DRM DPU BLITENG");
diff --git a/drivers/gpu/drm/imx/dpu/dpu-crtc.c b/drivers/gpu/drm/imx/dpu/dpu-crtc.c
new file mode 100644
index 000000000000..6ce73c78ca53
--- /dev/null
+++ b/drivers/gpu/drm/imx/dpu/dpu-crtc.c
@@ -0,0 +1,1181 @@
+/*
+ * Copyright 2017-2019 NXP
+ *
+ * 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 <drm/drmP.h>
+#include <drm/drm_atomic.h>
+#include <drm/drm_atomic_helper.h>
+#include <drm/drm_crtc_helper.h>
+#include <drm/drm_fb_cma_helper.h>
+#include <drm/drm_gem_cma_helper.h>
+#include <linux/component.h>
+#include <linux/device.h>
+#include <linux/errno.h>
+#include <linux/export.h>
+#include <linux/irq.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <video/dpu.h>
+#include <video/imx8-pc.h>
+#include "dpu-crtc.h"
+#include "dpu-kms.h"
+#include "dpu-plane.h"
+#include "imx-drm.h"
+
+static inline struct dpu_plane_state **
+alloc_dpu_plane_states(struct dpu_crtc *dpu_crtc)
+{
+ struct dpu_plane_state **states;
+
+ states = kcalloc(dpu_crtc->hw_plane_num, sizeof(*states), GFP_KERNEL);
+ if (!states)
+ return ERR_PTR(-ENOMEM);
+
+ return states;
+}
+
+struct dpu_plane_state **
+crtc_state_get_dpu_plane_states(struct drm_crtc_state *state)
+{
+ struct imx_crtc_state *imx_crtc_state = to_imx_crtc_state(state);
+ struct dpu_crtc_state *dcstate = to_dpu_crtc_state(imx_crtc_state);
+
+ return dcstate->dpu_plane_states;
+}
+
+static struct dpu_crtc *dpu_crtc_get_aux_dpu_crtc(struct dpu_crtc *dpu_crtc)
+{
+ struct drm_crtc *crtc = &dpu_crtc->base, *tmp_crtc;
+ struct drm_device *dev = crtc->dev;
+ struct dpu_crtc *aux_dpu_crtc = NULL;
+
+ drm_for_each_crtc(tmp_crtc, dev) {
+ if (tmp_crtc == crtc)
+ continue;
+
+ aux_dpu_crtc = to_dpu_crtc(tmp_crtc);
+
+ if (dpu_crtc->crtc_grp_id == aux_dpu_crtc->crtc_grp_id)
+ break;
+ }
+
+ BUG_ON(!aux_dpu_crtc);
+
+ return aux_dpu_crtc;
+}
+
+static void dpu_crtc_atomic_enable(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_crtc_state)
+{
+ struct dpu_crtc *dpu_crtc = to_dpu_crtc(crtc);
+ struct dpu_crtc *aux_dpu_crtc = dpu_crtc_get_aux_dpu_crtc(dpu_crtc);
+ struct imx_crtc_state *imx_crtc_state = to_imx_crtc_state(crtc->state);
+ struct dpu_crtc_state *dcstate = to_dpu_crtc_state(imx_crtc_state);
+ struct dpu_plane *dplane = to_dpu_plane(crtc->primary);
+ struct dpu_plane_res *res = &dplane->grp->res;
+ struct dpu_extdst *plane_ed = res->ed[dplane->stream_id];
+ struct dpu_extdst *aux_plane_ed = dpu_aux_ed_peek(plane_ed);
+ struct dpu_extdst *m_plane_ed = NULL, *s_plane_ed;
+ struct completion *shdld_done;
+ struct completion *m_safety_shdld_done, *s_safety_shdld_done;
+ struct completion *m_content_shdld_done, *s_content_shdld_done;
+ struct completion *m_dec_shdld_done, *s_dec_shdld_done;
+ unsigned long ret;
+
+ drm_crtc_vblank_on(crtc);
+
+ if (dcstate->use_pc) {
+ tcon_enable_pc(dpu_crtc->tcon);
+
+ if (extdst_is_master(plane_ed)) {
+ m_plane_ed = plane_ed;
+ s_plane_ed = aux_plane_ed;
+ } else {
+ m_plane_ed = aux_plane_ed;
+ s_plane_ed = plane_ed;
+ }
+ extdst_pixengcfg_syncmode_master(m_plane_ed, true);
+ extdst_pixengcfg_syncmode_master(s_plane_ed, false);
+ } else {
+ extdst_pixengcfg_syncmode_master(plane_ed, false);
+ }
+
+ enable_irq(dpu_crtc->safety_shdld_irq);
+ enable_irq(dpu_crtc->content_shdld_irq);
+ enable_irq(dpu_crtc->dec_shdld_irq);
+ if (dcstate->use_pc) {
+ enable_irq(aux_dpu_crtc->safety_shdld_irq);
+ enable_irq(aux_dpu_crtc->content_shdld_irq);
+ enable_irq(aux_dpu_crtc->dec_shdld_irq);
+ }
+
+ if (dcstate->use_pc) {
+ framegen_enable_clock(dpu_crtc->stream_id ?
+ dpu_crtc->aux_fg : dpu_crtc->fg);
+ extdst_pixengcfg_sync_trigger(m_plane_ed);
+ framegen_shdtokgen(dpu_crtc->m_fg);
+
+ /* First turn on the slave stream, second the master stream. */
+ framegen_enable(dpu_crtc->s_fg);
+ framegen_enable(dpu_crtc->m_fg);
+
+ if (dpu_crtc->aux_is_master) {
+ m_safety_shdld_done = &aux_dpu_crtc->safety_shdld_done;
+ m_content_shdld_done = &aux_dpu_crtc->content_shdld_done;
+ m_dec_shdld_done = &aux_dpu_crtc->dec_shdld_done;
+ s_safety_shdld_done = &dpu_crtc->safety_shdld_done;
+ s_content_shdld_done = &dpu_crtc->content_shdld_done;
+ s_dec_shdld_done = &dpu_crtc->dec_shdld_done;
+ } else {
+ m_safety_shdld_done = &dpu_crtc->safety_shdld_done;
+ m_content_shdld_done = &dpu_crtc->content_shdld_done;
+ m_dec_shdld_done = &dpu_crtc->dec_shdld_done;
+ s_safety_shdld_done = &aux_dpu_crtc->safety_shdld_done;
+ s_content_shdld_done = &aux_dpu_crtc->content_shdld_done;
+ s_dec_shdld_done = &aux_dpu_crtc->dec_shdld_done;
+ }
+
+ ret = wait_for_completion_timeout(m_safety_shdld_done, HZ);
+ if (ret == 0)
+ dev_warn(dpu_crtc->dev,
+ "enable - wait for master safety shdld done timeout\n");
+ ret = wait_for_completion_timeout(m_content_shdld_done, HZ);
+ if (ret == 0)
+ dev_warn(dpu_crtc->dev,
+ "enable - wait for master content shdld done timeout\n");
+ ret = wait_for_completion_timeout(m_dec_shdld_done, HZ);
+ if (ret == 0)
+ dev_warn(dpu_crtc->dev,
+ "enable - wait for master dec shdld done timeout\n");
+
+ ret = wait_for_completion_timeout(s_safety_shdld_done, HZ);
+ if (ret == 0)
+ dev_warn(dpu_crtc->dev,
+ "enable - wait for slave safety shdld done timeout\n");
+ ret = wait_for_completion_timeout(s_content_shdld_done, HZ);
+ if (ret == 0)
+ dev_warn(dpu_crtc->dev,
+ "enable - wait for slave content shdld done timeout\n");
+ ret = wait_for_completion_timeout(s_dec_shdld_done, HZ);
+ if (ret == 0)
+ dev_warn(dpu_crtc->dev,
+ "enable - wait for slave DEC shdld done timeout\n");
+ } else {
+ framegen_enable_clock(dpu_crtc->fg);
+ extdst_pixengcfg_sync_trigger(plane_ed);
+ extdst_pixengcfg_sync_trigger(dpu_crtc->ed);
+ framegen_shdtokgen(dpu_crtc->fg);
+ framegen_enable(dpu_crtc->fg);
+
+ shdld_done = &dpu_crtc->safety_shdld_done;
+ ret = wait_for_completion_timeout(shdld_done, HZ);
+ if (ret == 0)
+ dev_warn(dpu_crtc->dev,
+ "enable - wait for safety shdld done timeout\n");
+ shdld_done = &dpu_crtc->content_shdld_done;
+ ret = wait_for_completion_timeout(shdld_done, HZ);
+ if (ret == 0)
+ dev_warn(dpu_crtc->dev,
+ "enable - wait for content shdld done timeout\n");
+ shdld_done = &dpu_crtc->dec_shdld_done;
+ ret = wait_for_completion_timeout(shdld_done, HZ);
+ if (ret == 0)
+ dev_warn(dpu_crtc->dev,
+ "enable - wait for dec shdld done timeout\n");
+ }
+
+ disable_irq(dpu_crtc->safety_shdld_irq);
+ disable_irq(dpu_crtc->content_shdld_irq);
+ disable_irq(dpu_crtc->dec_shdld_irq);
+ if (dcstate->use_pc) {
+ disable_irq(aux_dpu_crtc->safety_shdld_irq);
+ disable_irq(aux_dpu_crtc->content_shdld_irq);
+ disable_irq(aux_dpu_crtc->dec_shdld_irq);
+ }
+
+ if (crtc->state->event) {
+ spin_lock_irq(&crtc->dev->event_lock);
+ drm_crtc_send_vblank_event(crtc, crtc->state->event);
+ spin_unlock_irq(&crtc->dev->event_lock);
+
+ crtc->state->event = NULL;
+ }
+
+ /*
+ * TKT320590:
+ * Turn TCON into operation mode later after the first dumb frame is
+ * generated by DPU. This makes DPR/PRG be able to evade the frame.
+ * However, it turns out we have to set the TCON into operation mode
+ * first and then wait for Framegen frame counter moving, otherwise,
+ * the display pipeline is likely to broken(If pixel combiner is used,
+ * one of the two display streams cannot be setup correctly sometimes.
+ * If pixel combiner is unused and prefetch engine is used, the first
+ * atomic flush after the enablement is likely to fail - content shadow
+ * load irq doesn't come.). This is a mysterious issue.
+ */
+ if (dcstate->use_pc) {
+ tcon_set_operation_mode(dpu_crtc->m_tcon);
+ tcon_set_operation_mode(dpu_crtc->s_tcon);
+ framegen_wait_for_frame_counter_moving(dpu_crtc->m_fg);
+ framegen_wait_for_frame_counter_moving(dpu_crtc->s_fg);
+
+ framegen_wait_for_secondary_syncup(dpu_crtc->m_fg);
+ framegen_wait_for_secondary_syncup(dpu_crtc->s_fg);
+
+ if (framegen_secondary_requests_to_read_empty_fifo(dpu_crtc->m_fg)) {
+ framegen_secondary_clear_channel_status(dpu_crtc->m_fg);
+ dev_warn(dpu_crtc->dev,
+ "enable - master FrameGen requests to read empty FIFO\n");
+ }
+ if (framegen_secondary_requests_to_read_empty_fifo(dpu_crtc->s_fg)) {
+ framegen_secondary_clear_channel_status(dpu_crtc->s_fg);
+ dev_warn(dpu_crtc->dev,
+ "enable - slave FrameGen requests to read empty FIFO\n");
+ }
+ } else {
+ tcon_set_operation_mode(dpu_crtc->tcon);
+ framegen_wait_for_frame_counter_moving(dpu_crtc->fg);
+
+ framegen_wait_for_secondary_syncup(dpu_crtc->fg);
+
+ if (framegen_secondary_requests_to_read_empty_fifo(dpu_crtc->fg)) {
+ framegen_secondary_clear_channel_status(dpu_crtc->fg);
+ dev_warn(dpu_crtc->dev,
+ "enable - FrameGen requests to read empty FIFO\n");
+ }
+ }
+}
+
+static void dpu_crtc_atomic_disable(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_crtc_state)
+{
+ struct dpu_crtc *dpu_crtc = to_dpu_crtc(crtc);
+ struct imx_crtc_state *imx_crtc_state =
+ to_imx_crtc_state(old_crtc_state);
+ struct dpu_crtc_state *dcstate = to_dpu_crtc_state(imx_crtc_state);
+ struct drm_display_mode *adjusted_mode = &old_crtc_state->adjusted_mode;
+
+ if (dcstate->use_pc) {
+ tcon_disable_pc(dpu_crtc->tcon);
+
+ /* First turn off the master stream, second the slave stream. */
+ framegen_disable(dpu_crtc->m_fg);
+ framegen_disable(dpu_crtc->s_fg);
+
+ framegen_wait_done(dpu_crtc->m_fg, adjusted_mode);
+ framegen_wait_done(dpu_crtc->s_fg, adjusted_mode);
+
+ framegen_disable_clock(dpu_crtc->stream_id ?
+ dpu_crtc->aux_fg : dpu_crtc->fg);
+ } else {
+ framegen_disable(dpu_crtc->fg);
+ framegen_wait_done(dpu_crtc->fg, adjusted_mode);
+ framegen_disable_clock(dpu_crtc->fg);
+ }
+
+ WARN_ON(!crtc->state->event);
+
+ if (crtc->state->event) {
+ spin_lock_irq(&crtc->dev->event_lock);
+ drm_crtc_send_vblank_event(crtc, crtc->state->event);
+ spin_unlock_irq(&crtc->dev->event_lock);
+
+ crtc->state->event = NULL;
+ }
+
+ drm_crtc_vblank_off(crtc);
+}
+
+static void dpu_drm_crtc_reset(struct drm_crtc *crtc)
+{
+ struct dpu_crtc *dpu_crtc = to_dpu_crtc(crtc);
+ struct imx_crtc_state *imx_crtc_state;
+ struct dpu_crtc_state *state;
+
+ if (crtc->state) {
+ __drm_atomic_helper_crtc_destroy_state(crtc->state);
+
+ imx_crtc_state = to_imx_crtc_state(crtc->state);
+ state = to_dpu_crtc_state(imx_crtc_state);
+ kfree(state->dpu_plane_states);
+ kfree(state);
+ crtc->state = NULL;
+ }
+
+ state = kzalloc(sizeof(*state), GFP_KERNEL);
+ if (state) {
+ crtc->state = &state->imx_crtc_state.base;
+ crtc->state->crtc = crtc;
+
+ state->dpu_plane_states = alloc_dpu_plane_states(dpu_crtc);
+ if (IS_ERR(state->dpu_plane_states))
+ kfree(state);
+ }
+}
+
+static struct drm_crtc_state *
+dpu_drm_crtc_duplicate_state(struct drm_crtc *crtc)
+{
+ struct imx_crtc_state *imx_crtc_state;
+ struct dpu_crtc *dpu_crtc = to_dpu_crtc(crtc);
+ struct dpu_crtc_state *state, *copy;
+
+ if (WARN_ON(!crtc->state))
+ return NULL;
+
+ copy = kzalloc(sizeof(*copy), GFP_KERNEL);
+ if (!copy)
+ return NULL;
+
+ copy->dpu_plane_states = alloc_dpu_plane_states(dpu_crtc);
+ if (IS_ERR(copy->dpu_plane_states)) {
+ kfree(copy);
+ return NULL;
+ }
+
+ __drm_atomic_helper_crtc_duplicate_state(crtc,
+ &copy->imx_crtc_state.base);
+ imx_crtc_state = to_imx_crtc_state(crtc->state);
+ state = to_dpu_crtc_state(imx_crtc_state);
+ copy->use_pc = state->use_pc;
+
+ return &copy->imx_crtc_state.base;
+}
+
+static void dpu_drm_crtc_destroy_state(struct drm_crtc *crtc,
+ struct drm_crtc_state *state)
+{
+ struct imx_crtc_state *imx_crtc_state = to_imx_crtc_state(state);
+ struct dpu_crtc_state *dcstate;
+
+ if (state) {
+ __drm_atomic_helper_crtc_destroy_state(state);
+ dcstate = to_dpu_crtc_state(imx_crtc_state);
+ kfree(dcstate->dpu_plane_states);
+ kfree(dcstate);
+ }
+}
+
+static int dpu_enable_vblank(struct drm_crtc *crtc)
+{
+ struct dpu_crtc *dpu_crtc = to_dpu_crtc(crtc);
+
+ enable_irq(dpu_crtc->vbl_irq);
+
+ return 0;
+}
+
+static void dpu_disable_vblank(struct drm_crtc *crtc)
+{
+ struct dpu_crtc *dpu_crtc = to_dpu_crtc(crtc);
+
+ disable_irq_nosync(dpu_crtc->vbl_irq);
+}
+
+static const struct drm_crtc_funcs dpu_crtc_funcs = {
+ .set_config = drm_atomic_helper_set_config,
+ .destroy = drm_crtc_cleanup,
+ .page_flip = drm_atomic_helper_page_flip,
+ .reset = dpu_drm_crtc_reset,
+ .atomic_duplicate_state = dpu_drm_crtc_duplicate_state,
+ .atomic_destroy_state = dpu_drm_crtc_destroy_state,
+ .enable_vblank = dpu_enable_vblank,
+ .disable_vblank = dpu_disable_vblank,
+};
+
+static irqreturn_t dpu_vbl_irq_handler(int irq, void *dev_id)
+{
+ struct dpu_crtc *dpu_crtc = dev_id;
+
+ drm_crtc_handle_vblank(&dpu_crtc->base);
+
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t dpu_safety_shdld_irq_handler(int irq, void *dev_id)
+{
+ struct dpu_crtc *dpu_crtc = dev_id;
+
+ complete(&dpu_crtc->safety_shdld_done);
+
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t dpu_content_shdld_irq_handler(int irq, void *dev_id)
+{
+ struct dpu_crtc *dpu_crtc = dev_id;
+
+ complete(&dpu_crtc->content_shdld_done);
+
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t dpu_dec_shdld_irq_handler(int irq, void *dev_id)
+{
+ struct dpu_crtc *dpu_crtc = dev_id;
+
+ complete(&dpu_crtc->dec_shdld_done);
+
+ return IRQ_HANDLED;
+}
+
+static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
+ struct drm_crtc_state *crtc_state)
+{
+ struct drm_device *dev = crtc->dev;
+ struct drm_encoder *encoder;
+ struct drm_plane *plane;
+ struct drm_plane_state *plane_state;
+ struct dpu_plane_state *dpstate;
+ struct imx_crtc_state *imx_crtc_state = to_imx_crtc_state(crtc_state);
+ struct dpu_crtc_state *dcstate = to_dpu_crtc_state(imx_crtc_state);
+ struct drm_display_mode *mode = &crtc_state->adjusted_mode;
+ struct videomode vm;
+ unsigned long encoder_types = 0;
+ u32 encoder_mask;
+ int i = 0;
+
+ list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
+ encoder_mask = 1 << drm_encoder_index(encoder);
+
+ if (!(crtc_state->encoder_mask & encoder_mask))
+ continue;
+
+ encoder_types |= BIT(encoder->encoder_type);
+ }
+
+ if (crtc_state->enable && dcstate->use_pc) {
+ if (encoder_types & BIT(DRM_MODE_ENCODER_LVDS))
+ return -EINVAL;
+
+ if (encoder_types & BIT(DRM_MODE_ENCODER_DSI))
+ return -EINVAL;
+
+ drm_display_mode_to_videomode(mode, &vm);
+ if ((vm.hactive % 2) || (vm.hfront_porch % 2) ||
+ (vm.hsync_len % 2) || (vm.hback_porch % 2))
+ return -EINVAL;
+ }
+
+ /*
+ * cache the plane states so that the planes can be disabled in
+ * ->atomic_begin.
+ */
+ drm_for_each_plane_mask(plane, crtc->dev, crtc_state->plane_mask) {
+ plane_state =
+ drm_atomic_get_plane_state(crtc_state->state, plane);
+ if (IS_ERR(plane_state))
+ return PTR_ERR(plane_state);
+
+ dpstate = to_dpu_plane_state(plane_state);
+ dcstate->dpu_plane_states[i++] = dpstate;
+ }
+
+ return 0;
+}
+
+static void dpu_crtc_atomic_begin(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_crtc_state)
+{
+ struct dpu_crtc *dpu_crtc = to_dpu_crtc(crtc);
+ struct imx_crtc_state *imx_crtc_state =
+ to_imx_crtc_state(old_crtc_state);
+ struct dpu_crtc_state *old_dcstate = to_dpu_crtc_state(imx_crtc_state);
+ int i;
+
+ /*
+ * Disable all planes' resources in SHADOW only.
+ * Whether any of them would be disabled or kept running depends
+ * on new plane states' commit.
+ */
+ for (i = 0; i < dpu_crtc->hw_plane_num; i++) {
+ struct dpu_plane_state *old_dpstate;
+ struct drm_plane_state *plane_state;
+ struct dpu_plane *dplane;
+ struct drm_plane *plane;
+ struct dpu_plane_res *res;
+ struct dpu_fetchunit *fu;
+ struct dpu_fetchunit *fe = NULL;
+ struct dpu_hscaler *hs = NULL;
+ struct dpu_vscaler *vs = NULL;
+ struct dpu_layerblend *lb;
+ struct dpu_extdst *ed;
+ extdst_src_sel_t ed_src;
+ dpu_block_id_t blend, source;
+ unsigned int stream_id;
+ int lb_id;
+ bool crtc_disabling_on_primary;
+ bool release_aux_source;
+
+ old_dpstate = old_dcstate->dpu_plane_states[i];
+ if (!old_dpstate)
+ continue;
+
+ plane_state = &old_dpstate->base;
+ dplane = to_dpu_plane(plane_state->plane);
+ res = &dplane->grp->res;
+
+ release_aux_source = false;
+again:
+ crtc_disabling_on_primary = false;
+
+ if (old_dcstate->use_pc) {
+ if (release_aux_source) {
+ source = old_dpstate->aux_source;
+ blend = old_dpstate->aux_blend;
+ stream_id = 1;
+ } else {
+ source = old_dpstate->source;
+ blend = old_dpstate->blend;
+ stream_id = old_dpstate->left_src_w ? 0 : 1;
+ }
+ } else {
+ source = old_dpstate->source;
+ blend = old_dpstate->blend;
+ stream_id = dplane->stream_id;
+ }
+
+ fu = source_to_fu(res, source);
+ if (!fu)
+ return;
+
+ lb_id = blend_to_id(blend);
+ if (lb_id < 0)
+ return;
+
+ lb = res->lb[lb_id];
+
+ layerblend_pixengcfg_clken(lb, CLKEN__DISABLE);
+ if (fetchunit_is_fetchdecode(fu)) {
+ fe = fetchdecode_get_fetcheco(fu);
+ hs = fetchdecode_get_hscaler(fu);
+ vs = fetchdecode_get_vscaler(fu);
+ hscaler_pixengcfg_clken(hs, CLKEN__DISABLE);
+ vscaler_pixengcfg_clken(vs, CLKEN__DISABLE);
+ hscaler_mode(hs, SCALER_NEUTRAL);
+ vscaler_mode(vs, SCALER_NEUTRAL);
+ }
+ if (old_dpstate->is_top) {
+ ed = res->ed[stream_id];
+ ed_src = stream_id ?
+ ED_SRC_CONSTFRAME1 : ED_SRC_CONSTFRAME0;
+ extdst_pixengcfg_src_sel(ed, ed_src);
+ }
+
+ plane = old_dpstate->base.plane;
+ if (!crtc->state->enable &&
+ plane->type == DRM_PLANE_TYPE_PRIMARY)
+ crtc_disabling_on_primary = true;
+
+ if (crtc_disabling_on_primary && old_dpstate->use_prefetch) {
+ fu->ops->pin_off(fu);
+ if (fetchunit_is_fetchdecode(fu) &&
+ fe->ops->is_enabled(fe))
+ fe->ops->pin_off(fe);
+ } else {
+ fu->ops->disable_src_buf(fu);
+ fu->ops->unpin_off(fu);
+ if (fetchunit_is_fetchdecode(fu)) {
+ fetchdecode_pixengcfg_dynamic_src_sel(fu,
+ FD_SRC_DISABLE);
+ fe->ops->disable_src_buf(fe);
+ fe->ops->unpin_off(fe);
+ }
+ }
+
+ if (old_dpstate->need_aux_source && !release_aux_source) {
+ release_aux_source = true;
+ goto again;
+ }
+ }
+}
+
+static void dpu_crtc_atomic_flush(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_crtc_state)
+{
+ struct dpu_crtc *dpu_crtc = to_dpu_crtc(crtc), *aux_dpu_crtc = NULL;
+ struct imx_crtc_state *imx_crtc_state = to_imx_crtc_state(crtc->state);
+ struct imx_crtc_state *old_imx_crtc_state =
+ to_imx_crtc_state(old_crtc_state);
+ struct dpu_crtc_state *dcstate = to_dpu_crtc_state(imx_crtc_state);
+ struct dpu_crtc_state *old_dcstate =
+ to_dpu_crtc_state(old_imx_crtc_state);
+ struct dpu_plane *dplane = to_dpu_plane(crtc->primary);
+ struct dpu_plane_res *res = &dplane->grp->res;
+ struct dpu_extdst *ed = res->ed[dplane->stream_id], *aux_ed;
+ struct completion *shdld_done;
+ struct completion *m_content_shdld_done = NULL;
+ struct completion *s_content_shdld_done = NULL;
+ unsigned long ret;
+ int i;
+ bool need_modeset = drm_atomic_crtc_needs_modeset(crtc->state);
+
+ if (!crtc->state->active && !old_crtc_state->active)
+ return;
+
+ if (dcstate->use_pc) {
+ aux_dpu_crtc = dpu_crtc_get_aux_dpu_crtc(dpu_crtc);
+
+ if (dpu_crtc->aux_is_master) {
+ m_content_shdld_done = &aux_dpu_crtc->content_shdld_done;
+ s_content_shdld_done = &dpu_crtc->content_shdld_done;
+ } else {
+ m_content_shdld_done = &dpu_crtc->content_shdld_done;
+ s_content_shdld_done = &aux_dpu_crtc->content_shdld_done;
+ }
+ }
+
+ if (!need_modeset) {
+ enable_irq(dpu_crtc->content_shdld_irq);
+ if (dcstate->use_pc)
+ enable_irq(aux_dpu_crtc->content_shdld_irq);
+
+ if (dcstate->use_pc) {
+ if (extdst_is_master(ed)) {
+ extdst_pixengcfg_sync_trigger(ed);
+ } else {
+ aux_ed = dpu_aux_ed_peek(ed);
+ extdst_pixengcfg_sync_trigger(aux_ed);
+ }
+ } else {
+ extdst_pixengcfg_sync_trigger(ed);
+ }
+
+ if (dcstate->use_pc) {
+ shdld_done = m_content_shdld_done;
+ ret = wait_for_completion_timeout(shdld_done, HZ);
+ if (ret == 0)
+ dev_warn(dpu_crtc->dev,
+ "flush - wait for master content shdld done timeout\n");
+
+ shdld_done = s_content_shdld_done;
+ ret = wait_for_completion_timeout(shdld_done, HZ);
+ if (ret == 0)
+ dev_warn(dpu_crtc->dev,
+ "flush - wait for slave content shdld done timeout\n");
+ } else {
+ shdld_done = &dpu_crtc->content_shdld_done;
+ ret = wait_for_completion_timeout(shdld_done, HZ);
+ if (ret == 0)
+ dev_warn(dpu_crtc->dev,
+ "flush - wait for content shdld done timeout\n");
+ }
+
+ disable_irq(dpu_crtc->content_shdld_irq);
+ if (dcstate->use_pc)
+ disable_irq(aux_dpu_crtc->content_shdld_irq);
+
+ if (dcstate->use_pc) {
+ if (framegen_secondary_requests_to_read_empty_fifo(dpu_crtc->m_fg)) {
+ framegen_secondary_clear_channel_status(dpu_crtc->m_fg);
+ dev_warn(dpu_crtc->dev,
+ "flush - master FrameGen requests to read empty FIFO\n");
+ }
+ if (framegen_secondary_requests_to_read_empty_fifo(dpu_crtc->s_fg)) {
+ framegen_secondary_clear_channel_status(dpu_crtc->s_fg);
+ dev_warn(dpu_crtc->dev,
+ "flush - slave FrameGen requests to read empty FIFO\n");
+ }
+ } else {
+ if (framegen_secondary_requests_to_read_empty_fifo(dpu_crtc->fg)) {
+ framegen_secondary_clear_channel_status(dpu_crtc->fg);
+ dev_warn(dpu_crtc->dev,
+ "flush - FrameGen requests to read empty FIFO\n");
+ }
+ }
+
+ WARN_ON(!crtc->state->event);
+
+ if (crtc->state->event) {
+ spin_lock_irq(&crtc->dev->event_lock);
+ drm_crtc_send_vblank_event(crtc, crtc->state->event);
+ spin_unlock_irq(&crtc->dev->event_lock);
+
+ crtc->state->event = NULL;
+ }
+ } else if (!crtc->state->active) {
+ if (old_dcstate->use_pc) {
+ if (extdst_is_master(ed)) {
+ extdst_pixengcfg_sync_trigger(ed);
+ } else {
+ aux_ed = dpu_aux_ed_peek(ed);
+ extdst_pixengcfg_sync_trigger(aux_ed);
+ }
+ } else {
+ extdst_pixengcfg_sync_trigger(ed);
+ }
+ }
+
+ for (i = 0; i < dpu_crtc->hw_plane_num; i++) {
+ struct dpu_plane_state *old_dpstate;
+ struct dpu_fetchunit *fu;
+ struct dpu_fetchunit *fe;
+ struct dpu_hscaler *hs;
+ struct dpu_vscaler *vs;
+ dpu_block_id_t source;
+ bool aux_source_disable;
+
+ old_dpstate = old_dcstate->dpu_plane_states[i];
+ if (!old_dpstate)
+ continue;
+
+ aux_source_disable = false;
+again:
+ source = aux_source_disable ?
+ old_dpstate->aux_source : old_dpstate->source;
+ fu = source_to_fu(res, source);
+ if (!fu)
+ return;
+
+ if (!fu->ops->is_enabled(fu) || fu->ops->is_pinned_off(fu))
+ fu->ops->set_stream_id(fu, DPU_PLANE_SRC_DISABLED);
+
+ if (fetchunit_is_fetchdecode(fu)) {
+ fe = fetchdecode_get_fetcheco(fu);
+ if (!fe->ops->is_enabled(fe) ||
+ fe->ops->is_pinned_off(fe))
+ fe->ops->set_stream_id(fe,
+ DPU_PLANE_SRC_DISABLED);
+
+ hs = fetchdecode_get_hscaler(fu);
+ if (!hscaler_is_enabled(hs))
+ hscaler_set_stream_id(hs,
+ DPU_PLANE_SRC_DISABLED);
+
+ vs = fetchdecode_get_vscaler(fu);
+ if (!vscaler_is_enabled(vs))
+ vscaler_set_stream_id(vs,
+ DPU_PLANE_SRC_DISABLED);
+ }
+
+ if (old_dpstate->need_aux_source && !aux_source_disable) {
+ aux_source_disable = true;
+ goto again;
+ }
+ }
+}
+
+static void dpu_crtc_mode_set_nofb(struct drm_crtc *crtc)
+{
+ struct drm_device *dev = crtc->dev;
+ struct dpu_crtc *dpu_crtc = to_dpu_crtc(crtc);
+ struct dpu_crtc *aux_dpu_crtc = dpu_crtc_get_aux_dpu_crtc(dpu_crtc);
+ struct imx_crtc_state *imx_crtc_state = to_imx_crtc_state(crtc->state);
+ struct dpu_crtc_state *dcstate = to_dpu_crtc_state(imx_crtc_state);
+ struct drm_display_mode *mode = &crtc->state->adjusted_mode;
+ struct drm_encoder *encoder;
+ struct dpu_plane *dplane = to_dpu_plane(crtc->primary);
+ struct dpu_plane_res *res = &dplane->grp->res;
+ struct dpu_constframe *cf;
+ struct dpu_disengcfg *dec;
+ struct dpu_extdst *ed, *plane_ed;
+ struct dpu_framegen *fg;
+ struct dpu_tcon *tcon;
+ struct dpu_store *st;
+ extdst_src_sel_t ed_src;
+ unsigned long encoder_types = 0;
+ u32 encoder_mask;
+ unsigned int stream_id;
+ int crtc_hdisplay = dcstate->use_pc ?
+ (mode->crtc_hdisplay >> 1) : mode->crtc_hdisplay;
+ bool encoder_type_has_tmds = false;
+ bool encoder_type_has_lvds = false;
+ bool cfg_aux_pipe = false;
+
+ dev_dbg(dpu_crtc->dev, "%s: mode->hdisplay: %d\n", __func__,
+ mode->hdisplay);
+ dev_dbg(dpu_crtc->dev, "%s: mode->vdisplay: %d\n", __func__,
+ mode->vdisplay);
+ dev_dbg(dpu_crtc->dev, "%s: mode->clock: %dKHz\n", __func__,
+ mode->clock);
+ dev_dbg(dpu_crtc->dev, "%s: mode->vrefresh: %dHz\n", __func__,
+ drm_mode_vrefresh(mode));
+ if (dcstate->use_pc)
+ dev_dbg(dpu_crtc->dev, "%s: use pixel combiner\n", __func__);
+
+ list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
+ encoder_mask = 1 << drm_encoder_index(encoder);
+
+ if (!(crtc->state->encoder_mask & encoder_mask))
+ continue;
+
+ encoder_types |= BIT(encoder->encoder_type);
+ }
+
+ if (encoder_types & BIT(DRM_MODE_ENCODER_TMDS)) {
+ encoder_type_has_tmds = true;
+ dev_dbg(dpu_crtc->dev, "%s: encoder type has TMDS\n", __func__);
+ }
+
+ if (encoder_types & BIT(DRM_MODE_ENCODER_LVDS)) {
+ encoder_type_has_lvds = true;
+ dev_dbg(dpu_crtc->dev, "%s: encoder type has LVDS\n", __func__);
+ }
+
+again:
+ if (cfg_aux_pipe) {
+ cf = dpu_crtc->aux_cf;
+ dec = dpu_crtc->aux_dec;
+ ed = dpu_crtc->aux_ed;
+ fg = dpu_crtc->aux_fg;
+ tcon = dpu_crtc->aux_tcon;
+ st = aux_dpu_crtc->st;
+ stream_id = dpu_crtc->stream_id ^ 1;
+ } else {
+ cf = dpu_crtc->cf;
+ dec = dpu_crtc->dec;
+ ed = dpu_crtc->ed;
+ fg = dpu_crtc->fg;
+ tcon = dpu_crtc->tcon;
+ st = dpu_crtc->st;
+ stream_id = dpu_crtc->stream_id;
+ }
+
+ if (dcstate->use_pc) {
+ store_pixengcfg_syncmode_fixup(st, true);
+ framegen_syncmode_fixup(fg,
+ framegen_is_master(fg) ? false : true);
+ framegen_syncmode(fg, framegen_is_master(fg) ?
+ FGSYNCMODE__MASTER : FGSYNCMODE__SLAVE_ONCE);
+ } else {
+ store_pixengcfg_syncmode_fixup(st, false);
+ framegen_syncmode_fixup(fg, false);
+ framegen_syncmode(fg, FGSYNCMODE__OFF);
+ }
+
+ framegen_cfg_videomode(fg, mode, dcstate->use_pc,
+ encoder_type_has_tmds, encoder_type_has_lvds);
+ framegen_displaymode(fg, FGDM__SEC_ON_TOP);
+
+ framegen_panic_displaymode(fg, FGDM__TEST);
+
+ tcon_cfg_videomode(tcon, mode, dcstate->use_pc);
+ tcon_set_fmt(tcon, imx_crtc_state->bus_format);
+ if (dpu_crtc->has_pc)
+ tcon_configure_pc(tcon, stream_id, mode->crtc_hdisplay,
+ dcstate->use_pc ? PC_COMBINE : PC_BYPASS, 0);
+
+ disengcfg_polarity_ctrl(dec, mode->flags);
+
+ constframe_framedimensions(cf, crtc_hdisplay, mode->crtc_vdisplay);
+
+ ed_src = stream_id ? ED_SRC_CONSTFRAME5 : ED_SRC_CONSTFRAME4;
+ extdst_pixengcfg_src_sel(ed, ed_src);
+
+ plane_ed = res->ed[stream_id];
+ ed_src = stream_id ? ED_SRC_CONSTFRAME1 : ED_SRC_CONSTFRAME0;
+ extdst_pixengcfg_src_sel(plane_ed, ed_src);
+
+ if (dcstate->use_pc && !cfg_aux_pipe) {
+ cfg_aux_pipe = true;
+ goto again;
+ }
+}
+
+static const struct drm_crtc_helper_funcs dpu_helper_funcs = {
+ .mode_set_nofb = dpu_crtc_mode_set_nofb,
+ .atomic_check = dpu_crtc_atomic_check,
+ .atomic_begin = dpu_crtc_atomic_begin,
+ .atomic_flush = dpu_crtc_atomic_flush,
+ .atomic_enable = dpu_crtc_atomic_enable,
+ .atomic_disable = dpu_crtc_atomic_disable,
+};
+
+static void dpu_crtc_put_resources(struct dpu_crtc *dpu_crtc)
+{
+ if (!IS_ERR_OR_NULL(dpu_crtc->cf))
+ dpu_cf_put(dpu_crtc->cf);
+ if (!IS_ERR_OR_NULL(dpu_crtc->dec))
+ dpu_dec_put(dpu_crtc->dec);
+ if (!IS_ERR_OR_NULL(dpu_crtc->ed))
+ dpu_ed_put(dpu_crtc->ed);
+ if (!IS_ERR_OR_NULL(dpu_crtc->fg))
+ dpu_fg_put(dpu_crtc->fg);
+ if (!IS_ERR_OR_NULL(dpu_crtc->tcon))
+ dpu_tcon_put(dpu_crtc->tcon);
+}
+
+static int dpu_crtc_get_resources(struct dpu_crtc *dpu_crtc)
+{
+ struct dpu_soc *dpu = dev_get_drvdata(dpu_crtc->dev->parent);
+ unsigned int stream_id = dpu_crtc->stream_id;
+ int ret;
+
+ dpu_crtc->cf = dpu_cf_get(dpu, stream_id + 4);
+ if (IS_ERR(dpu_crtc->cf)) {
+ ret = PTR_ERR(dpu_crtc->cf);
+ goto err_out;
+ }
+ dpu_crtc->aux_cf = dpu_aux_cf_peek(dpu_crtc->cf);
+
+ dpu_crtc->dec = dpu_dec_get(dpu, stream_id);
+ if (IS_ERR(dpu_crtc->dec)) {
+ ret = PTR_ERR(dpu_crtc->dec);
+ goto err_out;
+ }
+ dpu_crtc->aux_dec = dpu_aux_dec_peek(dpu_crtc->dec);
+
+ dpu_crtc->ed = dpu_ed_get(dpu, stream_id + 4);
+ if (IS_ERR(dpu_crtc->ed)) {
+ ret = PTR_ERR(dpu_crtc->ed);
+ goto err_out;
+ }
+ dpu_crtc->aux_ed = dpu_aux_ed_peek(dpu_crtc->ed);
+
+ dpu_crtc->fg = dpu_fg_get(dpu, stream_id);
+ if (IS_ERR(dpu_crtc->fg)) {
+ ret = PTR_ERR(dpu_crtc->fg);
+ goto err_out;
+ }
+ dpu_crtc->aux_fg = dpu_aux_fg_peek(dpu_crtc->fg);
+
+ dpu_crtc->tcon = dpu_tcon_get(dpu, stream_id);
+ if (IS_ERR(dpu_crtc->tcon)) {
+ ret = PTR_ERR(dpu_crtc->tcon);
+ goto err_out;
+ }
+ dpu_crtc->aux_tcon = dpu_aux_tcon_peek(dpu_crtc->tcon);
+
+ if (dpu_crtc->aux_is_master) {
+ dpu_crtc->m_cf = dpu_crtc->aux_cf;
+ dpu_crtc->m_dec = dpu_crtc->aux_dec;
+ dpu_crtc->m_ed = dpu_crtc->aux_ed;
+ dpu_crtc->m_fg = dpu_crtc->aux_fg;
+ dpu_crtc->m_tcon = dpu_crtc->aux_tcon;
+
+ dpu_crtc->s_cf = dpu_crtc->cf;
+ dpu_crtc->s_dec = dpu_crtc->dec;
+ dpu_crtc->s_ed = dpu_crtc->ed;
+ dpu_crtc->s_fg = dpu_crtc->fg;
+ dpu_crtc->s_tcon = dpu_crtc->tcon;
+ } else {
+ dpu_crtc->m_cf = dpu_crtc->cf;
+ dpu_crtc->m_dec = dpu_crtc->dec;
+ dpu_crtc->m_ed = dpu_crtc->ed;
+ dpu_crtc->m_fg = dpu_crtc->fg;
+ dpu_crtc->m_tcon = dpu_crtc->tcon;
+
+ dpu_crtc->s_cf = dpu_crtc->aux_cf;
+ dpu_crtc->s_dec = dpu_crtc->aux_dec;
+ dpu_crtc->s_ed = dpu_crtc->aux_ed;
+ dpu_crtc->s_fg = dpu_crtc->aux_fg;
+ dpu_crtc->s_tcon = dpu_crtc->aux_tcon;
+ }
+
+ return 0;
+err_out:
+ dpu_crtc_put_resources(dpu_crtc);
+
+ return ret;
+}
+
+static int dpu_crtc_init(struct dpu_crtc *dpu_crtc,
+ struct dpu_client_platformdata *pdata, struct drm_device *drm)
+{
+ struct dpu_soc *dpu = dev_get_drvdata(dpu_crtc->dev->parent);
+ struct device *dev = dpu_crtc->dev;
+ struct drm_crtc *crtc = &dpu_crtc->base;
+ struct dpu_plane_grp *plane_grp = pdata->plane_grp;
+ unsigned int stream_id = pdata->stream_id;
+ int i, ret;
+
+ init_completion(&dpu_crtc->safety_shdld_done);
+ init_completion(&dpu_crtc->content_shdld_done);
+ init_completion(&dpu_crtc->dec_shdld_done);
+
+ dpu_crtc->stream_id = stream_id;
+ dpu_crtc->crtc_grp_id = pdata->di_grp_id;
+ dpu_crtc->hw_plane_num = plane_grp->hw_plane_num;
+ dpu_crtc->has_pc = dpu_has_pc(dpu);
+ dpu_crtc->syncmode_min_prate = dpu_get_syncmode_min_prate(dpu);
+ dpu_crtc->singlemode_max_width = dpu_get_singlemode_max_width(dpu);
+ dpu_crtc->master_stream_id = dpu_get_master_stream_id(dpu);
+ dpu_crtc->aux_is_master = dpu_crtc->has_pc ?
+ !(dpu_crtc->master_stream_id == stream_id) : false;
+ dpu_crtc->st = pdata->st9;
+
+ dpu_crtc->plane = devm_kcalloc(dev, dpu_crtc->hw_plane_num,
+ sizeof(*dpu_crtc->plane), GFP_KERNEL);
+ if (!dpu_crtc->plane)
+ return -ENOMEM;
+
+ ret = dpu_crtc_get_resources(dpu_crtc);
+ if (ret) {
+ dev_err(dev, "getting resources failed with %d.\n", ret);
+ return ret;
+ }
+
+ plane_grp->res.fg[stream_id] = dpu_crtc->fg;
+ dpu_crtc->plane[0] = dpu_plane_init(drm, 0, stream_id, plane_grp,
+ DRM_PLANE_TYPE_PRIMARY);
+ if (IS_ERR(dpu_crtc->plane[0])) {
+ ret = PTR_ERR(dpu_crtc->plane[0]);
+ dev_err(dev, "initializing plane0 failed with %d.\n", ret);
+ goto err_put_resources;
+ }
+
+ crtc->port = pdata->of_node;
+ drm_crtc_helper_add(crtc, &dpu_helper_funcs);
+ ret = drm_crtc_init_with_planes(drm, crtc, &dpu_crtc->plane[0]->base, NULL,
+ &dpu_crtc_funcs, NULL);
+ if (ret) {
+ dev_err(dev, "adding crtc failed with %d.\n", ret);
+ goto err_put_resources;
+ }
+
+ for (i = 1; i < dpu_crtc->hw_plane_num; i++) {
+ dpu_crtc->plane[i] = dpu_plane_init(drm,
+ drm_crtc_mask(&dpu_crtc->base),
+ stream_id, plane_grp,
+ DRM_PLANE_TYPE_OVERLAY);
+ if (IS_ERR(dpu_crtc->plane[i])) {
+ ret = PTR_ERR(dpu_crtc->plane[i]);
+ dev_err(dev, "initializing plane%d failed with %d.\n",
+ i, ret);
+ goto err_put_resources;
+ }
+ }
+
+ dpu_crtc->vbl_irq = dpu_map_inner_irq(dpu, stream_id ?
+ IRQ_DISENGCFG_FRAMECOMPLETE1 :
+ IRQ_DISENGCFG_FRAMECOMPLETE0);
+ irq_set_status_flags(dpu_crtc->vbl_irq, IRQ_DISABLE_UNLAZY);
+ ret = devm_request_irq(dev, dpu_crtc->vbl_irq, dpu_vbl_irq_handler, 0,
+ "imx_drm", dpu_crtc);
+ if (ret < 0) {
+ dev_err(dev, "vblank irq request failed with %d.\n", ret);
+ goto err_put_resources;
+ }
+ disable_irq(dpu_crtc->vbl_irq);
+
+ dpu_crtc->safety_shdld_irq = dpu_map_inner_irq(dpu, stream_id ?
+ IRQ_EXTDST5_SHDLOAD : IRQ_EXTDST4_SHDLOAD);
+ irq_set_status_flags(dpu_crtc->safety_shdld_irq, IRQ_DISABLE_UNLAZY);
+ ret = devm_request_irq(dev, dpu_crtc->safety_shdld_irq,
+ dpu_safety_shdld_irq_handler, 0, "imx_drm",
+ dpu_crtc);
+ if (ret < 0) {
+ dev_err(dev,
+ "safety shadow load irq request failed with %d.\n",
+ ret);
+ goto err_put_resources;
+ }
+ disable_irq(dpu_crtc->safety_shdld_irq);
+
+ dpu_crtc->content_shdld_irq = dpu_map_inner_irq(dpu, stream_id ?
+ IRQ_EXTDST1_SHDLOAD : IRQ_EXTDST0_SHDLOAD);
+ irq_set_status_flags(dpu_crtc->content_shdld_irq, IRQ_DISABLE_UNLAZY);
+ ret = devm_request_irq(dev, dpu_crtc->content_shdld_irq,
+ dpu_content_shdld_irq_handler, 0, "imx_drm",
+ dpu_crtc);
+ if (ret < 0) {
+ dev_err(dev,
+ "content shadow load irq request failed with %d.\n",
+ ret);
+ goto err_put_resources;
+ }
+ disable_irq(dpu_crtc->content_shdld_irq);
+
+ dpu_crtc->dec_shdld_irq = dpu_map_inner_irq(dpu, stream_id ?
+ IRQ_DISENGCFG_SHDLOAD1 : IRQ_DISENGCFG_SHDLOAD0);
+ irq_set_status_flags(dpu_crtc->dec_shdld_irq, IRQ_DISABLE_UNLAZY);
+ ret = devm_request_irq(dev, dpu_crtc->dec_shdld_irq,
+ dpu_dec_shdld_irq_handler, 0, "imx_drm",
+ dpu_crtc);
+ if (ret < 0) {
+ dev_err(dev,
+ "DEC shadow load irq request failed with %d.\n",
+ ret);
+ goto err_put_resources;
+ }
+ disable_irq(dpu_crtc->dec_shdld_irq);
+
+ return 0;
+
+err_put_resources:
+ dpu_crtc_put_resources(dpu_crtc);
+
+ return ret;
+}
+
+static int dpu_crtc_bind(struct device *dev, struct device *master, void *data)
+{
+ struct dpu_client_platformdata *pdata = dev->platform_data;
+ struct drm_device *drm = data;
+ struct dpu_crtc *dpu_crtc;
+ int ret;
+
+ dpu_crtc = devm_kzalloc(dev, sizeof(*dpu_crtc), GFP_KERNEL);
+ if (!dpu_crtc)
+ return -ENOMEM;
+
+ dpu_crtc->dev = dev;
+
+ ret = dpu_crtc_init(dpu_crtc, pdata, drm);
+ if (ret)
+ return ret;
+
+ if (!drm->mode_config.funcs)
+ drm->mode_config.funcs = &dpu_drm_mode_config_funcs;
+
+ dev_set_drvdata(dev, dpu_crtc);
+
+ return 0;
+}
+
+static void dpu_crtc_unbind(struct device *dev, struct device *master,
+ void *data)
+{
+ struct dpu_crtc *dpu_crtc = dev_get_drvdata(dev);
+
+ dpu_crtc_put_resources(dpu_crtc);
+
+ /* make sure the crtc exists, and then cleanup */
+ if (dpu_crtc->base.dev)
+ drm_crtc_cleanup(&dpu_crtc->base);
+}
+
+static const struct component_ops dpu_crtc_ops = {
+ .bind = dpu_crtc_bind,
+ .unbind = dpu_crtc_unbind,
+};
+
+static int dpu_crtc_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+
+ if (!dev->platform_data)
+ return -EINVAL;
+
+ return component_add(dev, &dpu_crtc_ops);
+}
+
+static int dpu_crtc_remove(struct platform_device *pdev)
+{
+ component_del(&pdev->dev, &dpu_crtc_ops);
+ return 0;
+}
+
+static struct platform_driver dpu_crtc_driver = {
+ .driver = {
+ .name = "imx-dpu-crtc",
+ },
+ .probe = dpu_crtc_probe,
+ .remove = dpu_crtc_remove,
+};
+module_platform_driver(dpu_crtc_driver);
+
+MODULE_AUTHOR("NXP Semiconductor");
+MODULE_DESCRIPTION("i.MX DPU CRTC");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:imx-dpu-crtc");
diff --git a/drivers/gpu/drm/imx/dpu/dpu-crtc.h b/drivers/gpu/drm/imx/dpu/dpu-crtc.h
new file mode 100644
index 000000000000..d2014c90cf65
--- /dev/null
+++ b/drivers/gpu/drm/imx/dpu/dpu-crtc.h
@@ -0,0 +1,88 @@
+/*
+ * Copyright 2017-2018 NXP
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#ifndef _DPU_CRTC_H_
+#define _DPU_CRTC_H_
+
+#include <video/dpu.h>
+#include "dpu-plane.h"
+#include "imx-drm.h"
+
+struct dpu_crtc {
+ struct device *dev;
+ struct drm_crtc base;
+ struct imx_drm_crtc *imx_crtc;
+ struct dpu_constframe *cf;
+ struct dpu_disengcfg *dec;
+ struct dpu_extdst *ed;
+ struct dpu_framegen *fg;
+ struct dpu_tcon *tcon;
+ struct dpu_store *st;
+ struct dpu_constframe *aux_cf;
+ struct dpu_disengcfg *aux_dec;
+ struct dpu_extdst *aux_ed;
+ struct dpu_framegen *aux_fg;
+ struct dpu_tcon *aux_tcon;
+ /* master */
+ struct dpu_constframe *m_cf;
+ struct dpu_disengcfg *m_dec;
+ struct dpu_extdst *m_ed;
+ struct dpu_framegen *m_fg;
+ struct dpu_tcon *m_tcon;
+ /* slave */
+ struct dpu_constframe *s_cf;
+ struct dpu_disengcfg *s_dec;
+ struct dpu_extdst *s_ed;
+ struct dpu_framegen *s_fg;
+ struct dpu_tcon *s_tcon;
+ struct dpu_plane **plane;
+ unsigned int hw_plane_num;
+ unsigned int stream_id;
+ unsigned int crtc_grp_id;
+ unsigned int syncmode_min_prate;
+ unsigned int singlemode_max_width;
+ unsigned int master_stream_id;
+ int vbl_irq;
+ int safety_shdld_irq;
+ int content_shdld_irq;
+ int dec_shdld_irq;
+
+ bool has_pc;
+ bool aux_is_master;
+
+ struct completion safety_shdld_done;
+ struct completion content_shdld_done;
+ struct completion dec_shdld_done;
+};
+
+struct dpu_crtc_state {
+ struct imx_crtc_state imx_crtc_state;
+ struct dpu_plane_state **dpu_plane_states;
+ bool use_pc;
+};
+
+static inline struct dpu_crtc_state *to_dpu_crtc_state(struct imx_crtc_state *s)
+{
+ return container_of(s, struct dpu_crtc_state, imx_crtc_state);
+}
+
+static inline struct dpu_crtc *to_dpu_crtc(struct drm_crtc *crtc)
+{
+ return container_of(crtc, struct dpu_crtc, base);
+}
+
+struct dpu_plane_state **
+crtc_state_get_dpu_plane_states(struct drm_crtc_state *state);
+
+#endif
diff --git a/drivers/gpu/drm/imx/dpu/dpu-kms.c b/drivers/gpu/drm/imx/dpu/dpu-kms.c
new file mode 100644
index 000000000000..289dc82069c8
--- /dev/null
+++ b/drivers/gpu/drm/imx/dpu/dpu-kms.c
@@ -0,0 +1,860 @@
+/*
+ * Copyright 2017-2019 NXP
+ *
+ * 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 <drm/drmP.h>
+#include <drm/drm_atomic.h>
+#include <drm/drm_atomic_helper.h>
+#include <drm/drm_fb_cma_helper.h>
+#include <drm/drm_gem_cma_helper.h>
+#include <linux/dma-buf.h>
+#include <linux/reservation.h>
+#include <linux/sort.h>
+#include <video/dpu.h>
+#include "dpu-crtc.h"
+#include "dpu-plane.h"
+#include "imx-drm.h"
+
+static void dpu_drm_output_poll_changed(struct drm_device *dev)
+{
+ struct imx_drm_device *imxdrm = dev->dev_private;
+
+ drm_fbdev_cma_hotplug_event(imxdrm->fbhelper);
+}
+
+static struct drm_plane_state **
+dpu_atomic_alloc_tmp_planes_per_crtc(struct drm_device *dev)
+{
+ int total_planes = dev->mode_config.num_total_plane;
+ struct drm_plane_state **states;
+
+ states = kmalloc_array(total_planes, sizeof(*states), GFP_KERNEL);
+ if (!states)
+ return ERR_PTR(-ENOMEM);
+
+ return states;
+}
+
+static int zpos_cmp(const void *a, const void *b)
+{
+ const struct drm_plane_state *sa = *(struct drm_plane_state **)a;
+ const struct drm_plane_state *sb = *(struct drm_plane_state **)b;
+
+ return sa->normalized_zpos - sb->normalized_zpos;
+}
+
+static int dpu_atomic_sort_planes_per_crtc(struct drm_crtc_state *crtc_state,
+ struct drm_plane_state **states)
+{
+ struct drm_atomic_state *state = crtc_state->state;
+ struct drm_device *dev = state->dev;
+ struct drm_plane *plane;
+ int n = 0;
+
+ drm_for_each_plane_mask(plane, dev, crtc_state->plane_mask) {
+ struct drm_plane_state *plane_state =
+ drm_atomic_get_plane_state(state, plane);
+ if (IS_ERR(plane_state))
+ return PTR_ERR(plane_state);
+ states[n++] = plane_state;
+ }
+
+ sort(states, n, sizeof(*states), zpos_cmp, NULL);
+
+ return n;
+}
+
+static int
+dpu_atomic_compute_plane_base_per_crtc(struct drm_crtc_state *crtc_state,
+ struct drm_plane_state **states, int n,
+ bool use_pc)
+{
+ struct dpu_plane_state *dpstate;
+ int i, left, right, top, bottom, tmp;
+ int base_x, base_y, base_w, base_h;
+ int half_hdisplay = crtc_state->adjusted_mode.hdisplay >> 1;
+ bool lo, ro, bo;
+
+ /* compute the plane base */
+ left = states[0]->crtc_x;
+ top = states[0]->crtc_y;
+ right = states[0]->crtc_x + states[0]->crtc_w;
+ bottom = states[0]->crtc_y + states[0]->crtc_h;
+
+ for (i = 1; i < n; i++) {
+ left = min(states[i]->crtc_x, left);
+ top = min(states[i]->crtc_y, top);
+
+ tmp = states[i]->crtc_x + states[i]->crtc_w;
+ right = max(tmp, right);
+
+ tmp = states[i]->crtc_y + states[i]->crtc_h;
+ bottom = max(tmp, bottom);
+ }
+
+ /* BTW, be smart to compute the layer offset */
+ for (i = 0; i < n; i++) {
+ dpstate = to_dpu_plane_state(states[i]);
+ dpstate->layer_x = states[i]->crtc_x - left;
+ dpstate->layer_y = states[i]->crtc_y - top;
+ }
+
+ /* store the base in plane state */
+ dpstate = to_dpu_plane_state(states[0]);
+ base_x = left;
+ base_y = top;
+ base_w = right - left;
+ base_h = bottom - top;
+ dpstate->base_x = base_x;
+ dpstate->base_y = base_y;
+ dpstate->base_w = base_w;
+ dpstate->base_h = base_h;
+
+ if (!use_pc)
+ return 0;
+
+ /* compute left/right_layer/base_x/w if pixel combiner is needed */
+ for (i = 0; i < n; i++) {
+ dpstate = to_dpu_plane_state(states[i]);
+
+ lo = dpstate->left_src_w && !dpstate->right_src_w;
+ ro = !dpstate->left_src_w && dpstate->right_src_w;
+ bo = dpstate->left_src_w && dpstate->right_src_w;
+
+ if (lo || bo) {
+ dpstate->left_layer_x = dpstate->layer_x;
+ dpstate->right_layer_x = 0;
+ } else if (ro) {
+ dpstate->left_layer_x = 0;
+ dpstate->right_layer_x =
+ states[i]->crtc_x - half_hdisplay;
+ }
+
+ if (i)
+ continue;
+
+ if (base_x < half_hdisplay) {
+ dpstate->left_base_x = base_x;
+ dpstate->right_base_x = 0;
+
+ if ((base_x + base_w) < half_hdisplay) {
+ dpstate->left_base_w = base_w;
+ dpstate->right_base_w = 0;
+ } else {
+ dpstate->left_base_w = half_hdisplay - base_x;
+ dpstate->right_base_w =
+ base_x + base_w - half_hdisplay;
+ }
+ } else {
+ dpstate->left_base_x = 0;
+ dpstate->right_base_x = base_x - half_hdisplay;
+
+ dpstate->left_base_w = 0;
+ dpstate->right_base_w = base_w;
+ }
+ }
+
+ return 0;
+}
+
+static void
+dpu_atomic_set_top_plane_per_crtc(struct drm_plane_state **states, int n,
+ bool use_pc)
+{
+ struct dpu_plane_state *dpstate;
+ bool found_l_top = false, found_r_top = false;
+ int i;
+
+ for (i = n - 1; i >= 0; i--) {
+ dpstate = to_dpu_plane_state(states[i]);
+ if (use_pc) {
+ if (dpstate->left_src_w && !found_l_top) {
+ dpstate->is_left_top = true;
+ found_l_top = true;
+ } else {
+ dpstate->is_left_top = false;
+ }
+
+ if (dpstate->right_src_w && !found_r_top) {
+ dpstate->is_right_top = true;
+ found_r_top = true;
+ } else {
+ dpstate->is_right_top = false;
+ }
+ } else {
+ dpstate->is_top = (i == (n - 1)) ? true : false;
+ }
+ }
+}
+
+static int
+dpu_atomic_assign_plane_source_per_crtc(struct drm_plane_state **states,
+ int n, bool use_pc)
+{
+ struct dpu_plane_state *dpstate;
+ struct dpu_plane *dplane;
+ struct dpu_plane_grp *grp;
+ struct drm_framebuffer *fb;
+ struct dpu_fetchunit *fu;
+ struct dpu_fetchunit *fe;
+ struct dpu_hscaler *hs;
+ struct dpu_vscaler *vs;
+ lb_prim_sel_t stage;
+ dpu_block_id_t blend;
+ unsigned int sid, src_sid;
+ unsigned int num_planes;
+ int i, j, k, l, m;
+ int total_asrc_num;
+ int s0_layer_cnt = 0, s1_layer_cnt = 0;
+ int s0_n = 0, s1_n = 0;
+ u32 src_a_mask, cap_mask, fe_mask, hs_mask, vs_mask;
+ bool need_fetcheco, need_hscaler, need_vscaler;
+ bool fmt_is_yuv;
+ bool alloc_aux_source;
+
+ if (use_pc) {
+ for (i = 0; i < n; i++) {
+ dpstate = to_dpu_plane_state(states[i]);
+
+ if (dpstate->left_src_w)
+ s0_n++;
+
+ if (dpstate->right_src_w)
+ s1_n++;
+ }
+ } else {
+ s0_n = n;
+ s1_n = n;
+ }
+
+ /* for active planes only */
+ for (i = 0; i < n; i++) {
+ dpstate = to_dpu_plane_state(states[i]);
+ dplane = to_dpu_plane(states[i]->plane);
+ fb = states[i]->fb;
+ num_planes = drm_format_num_planes(fb->format->format);
+ fmt_is_yuv = drm_format_is_yuv(fb->format->format);
+ grp = dplane->grp;
+ alloc_aux_source = false;
+
+ if (use_pc)
+ sid = dpstate->left_src_w ? 0 : 1;
+ else
+ sid = dplane->stream_id;
+
+again:
+ if (alloc_aux_source)
+ sid ^= 1;
+
+ need_fetcheco = (num_planes > 1);
+ need_hscaler = (states[i]->src_w >> 16 != states[i]->crtc_w);
+ need_vscaler = (states[i]->src_h >> 16 != states[i]->crtc_h);
+
+ total_asrc_num = 0;
+ src_a_mask = grp->src_a_mask;
+ fe_mask = 0;
+ hs_mask = 0;
+ vs_mask = 0;
+
+ for (l = 0; l < (sizeof(grp->src_a_mask) * 8); l++) {
+ if (grp->src_a_mask & BIT(l))
+ total_asrc_num++;
+ }
+
+ /* assign source */
+ mutex_lock(&grp->mutex);
+ for (k = 0; k < total_asrc_num; k++) {
+ m = ffs(src_a_mask) - 1;
+
+ fu = source_to_fu(&grp->res, sources[m]);
+ if (!fu)
+ return -EINVAL;
+
+ /* avoid on-the-fly/hot migration */
+ src_sid = fu->ops->get_stream_id(fu);
+ if (src_sid && src_sid != BIT(sid))
+ goto next;
+
+ if (fetchunit_is_fetchdecode(fu)) {
+ cap_mask = fetchdecode_get_vproc_mask(fu);
+
+ if (need_fetcheco) {
+ fe = fetchdecode_get_fetcheco(fu);
+
+ /* avoid on-the-fly/hot migration */
+ src_sid = fu->ops->get_stream_id(fe);
+ if (src_sid && src_sid != BIT(sid))
+ goto next;
+
+ /* fetch unit has the fetcheco cap? */
+ if (!dpu_vproc_has_fetcheco_cap(cap_mask))
+ goto next;
+
+ fe_mask =
+ dpu_vproc_get_fetcheco_cap(cap_mask);
+
+ /* fetcheco available? */
+ if (grp->src_use_vproc_mask & fe_mask)
+ goto next;
+ }
+
+ if (need_hscaler) {
+ hs = fetchdecode_get_hscaler(fu);
+
+ /* avoid on-the-fly/hot migration */
+ src_sid = hscaler_get_stream_id(hs);
+ if (src_sid && src_sid != BIT(sid))
+ goto next;
+
+ /* fetch unit has the hscale cap */
+ if (!dpu_vproc_has_hscale_cap(cap_mask))
+ goto next;
+
+ hs_mask =
+ dpu_vproc_get_hscale_cap(cap_mask);
+
+ /* hscaler available? */
+ if (grp->src_use_vproc_mask & hs_mask)
+ goto next;
+ }
+
+ if (need_vscaler) {
+ vs = fetchdecode_get_vscaler(fu);
+
+ /* avoid on-the-fly/hot migration */
+ src_sid = vscaler_get_stream_id(vs);
+ if (src_sid && src_sid != BIT(sid))
+ goto next;
+
+ /* fetch unit has the vscale cap? */
+ if (!dpu_vproc_has_vscale_cap(cap_mask))
+ goto next;
+
+ vs_mask =
+ dpu_vproc_get_vscale_cap(cap_mask);
+
+ /* vscaler available? */
+ if (grp->src_use_vproc_mask & vs_mask)
+ goto next;
+ }
+ } else {
+ if (fmt_is_yuv || need_fetcheco ||
+ need_hscaler || need_vscaler)
+ goto next;
+ }
+
+ grp->src_a_mask &= ~BIT(m);
+ grp->src_use_vproc_mask |= fe_mask | hs_mask | vs_mask;
+ break;
+next:
+ src_a_mask &= ~BIT(m);
+ fe_mask = 0;
+ hs_mask = 0;
+ vs_mask = 0;
+ }
+ mutex_unlock(&grp->mutex);
+
+ if (k == total_asrc_num)
+ return -EINVAL;
+
+ if (alloc_aux_source)
+ dpstate->aux_source = sources[m];
+ else
+ dpstate->source = sources[m];
+
+ /* assign stage and blend */
+ if (sid) {
+ j = grp->hw_plane_num - (s1_n - s1_layer_cnt);
+ stage = s1_layer_cnt ? stages[j - 1] : cf_stages[sid];
+ blend = blends[j];
+
+ s1_layer_cnt++;
+ } else {
+ stage = s0_layer_cnt ?
+ stages[s0_layer_cnt - 1] : cf_stages[sid];
+ blend = blends[s0_layer_cnt];
+
+ s0_layer_cnt++;
+ }
+
+ if (alloc_aux_source) {
+ dpstate->aux_stage = stage;
+ dpstate->aux_blend = blend;
+ } else {
+ dpstate->stage = stage;
+ dpstate->blend = blend;
+ }
+
+ if (dpstate->need_aux_source && !alloc_aux_source) {
+ alloc_aux_source = true;
+ goto again;
+ }
+ }
+
+ return 0;
+}
+
+static void
+dpu_atomic_mark_pipe_states_prone_to_put_per_crtc(struct drm_crtc *crtc,
+ u32 crtc_mask,
+ struct drm_atomic_state *state,
+ bool *puts)
+{
+ struct drm_plane *plane;
+ struct drm_plane_state *plane_state;
+ bool found_pstate = false;
+ int i;
+
+ if ((crtc_mask & drm_crtc_mask(crtc)) == 0) {
+ for_each_plane_in_state(state, plane, plane_state, i) {
+ if (plane->possible_crtcs &
+ drm_crtc_mask(crtc)) {
+ found_pstate = true;
+ break;
+ }
+ }
+
+ if (!found_pstate)
+ puts[drm_crtc_index(crtc)] = true;
+ }
+}
+
+static void
+dpu_atomic_put_plane_state(struct drm_atomic_state *state,
+ struct drm_plane *plane)
+{
+ int index = drm_plane_index(plane);
+
+ plane->funcs->atomic_destroy_state(plane, state->planes[index].state);
+ state->planes[index].ptr = NULL;
+ state->planes[index].state = NULL;
+
+ drm_modeset_unlock(&plane->mutex);
+}
+
+static void
+dpu_atomic_put_crtc_state(struct drm_atomic_state *state,
+ struct drm_crtc *crtc)
+{
+ int index = drm_crtc_index(crtc);
+
+ crtc->funcs->atomic_destroy_state(crtc, state->crtcs[index].state);
+ state->crtcs[index].ptr = NULL;
+ state->crtcs[index].state = NULL;
+
+ drm_modeset_unlock(&crtc->mutex);
+}
+
+static void
+dpu_atomic_put_possible_states_per_crtc(struct drm_crtc_state *crtc_state)
+{
+ struct drm_atomic_state *state = crtc_state->state;
+ struct drm_crtc *crtc = crtc_state->crtc;
+ struct drm_crtc_state *old_crtc_state = crtc->state;
+ struct drm_plane *plane;
+ struct drm_plane_state *plane_state;
+ struct dpu_plane *dplane = to_dpu_plane(crtc->primary);
+ struct dpu_plane_state **old_dpstates;
+ struct dpu_plane_state *old_dpstate, *new_dpstate;
+ u32 active_mask = 0;
+ int i;
+
+ old_dpstates = crtc_state_get_dpu_plane_states(old_crtc_state);
+ if (WARN_ON(!old_dpstates))
+ return;
+
+ for (i = 0; i < dplane->grp->hw_plane_num; i++) {
+ old_dpstate = old_dpstates[i];
+ if (!old_dpstate)
+ continue;
+
+ active_mask |= BIT(i);
+
+ drm_atomic_crtc_state_for_each_plane(plane, crtc_state) {
+ if (drm_plane_index(plane) !=
+ drm_plane_index(old_dpstate->base.plane))
+ continue;
+
+ plane_state =
+ drm_atomic_get_existing_plane_state(state,
+ plane);
+ WARN_ON(!plane_state);
+
+ new_dpstate = to_dpu_plane_state(plane_state);
+
+ active_mask &= ~BIT(i);
+
+ /*
+ * Should be enough to check the below real HW plane
+ * resources only.
+ * Vproc resources and things like layer_x/y should
+ * be fine.
+ */
+ if (old_dpstate->stage != new_dpstate->stage ||
+ old_dpstate->source != new_dpstate->source ||
+ old_dpstate->blend != new_dpstate->blend ||
+ old_dpstate->aux_stage != new_dpstate->aux_stage ||
+ old_dpstate->aux_source != new_dpstate->aux_source ||
+ old_dpstate->aux_blend != new_dpstate->aux_blend)
+ return;
+ }
+ }
+
+ /* pure software check */
+ if (WARN_ON(active_mask))
+ return;
+
+ drm_atomic_crtc_state_for_each_plane(plane, crtc_state)
+ dpu_atomic_put_plane_state(state, plane);
+
+ dpu_atomic_put_crtc_state(state, crtc);
+}
+
+static int dpu_drm_atomic_check(struct drm_device *dev,
+ struct drm_atomic_state *state)
+{
+ struct drm_crtc *crtc;
+ struct drm_crtc_state *crtc_state;
+ struct drm_plane *plane;
+ struct dpu_plane *dpu_plane;
+ struct drm_plane_state *plane_state;
+ struct dpu_plane_state *dpstate;
+ struct drm_framebuffer *fb;
+ struct dpu_plane_grp *grp[MAX_DPU_PLANE_GRP];
+ int ret, i, grp_id;
+ int active_plane[MAX_DPU_PLANE_GRP];
+ int active_plane_fetcheco[MAX_DPU_PLANE_GRP];
+ int active_plane_hscale[MAX_DPU_PLANE_GRP];
+ int active_plane_vscale[MAX_DPU_PLANE_GRP];
+ int half_hdisplay = 0;
+ bool pipe_states_prone_to_put[MAX_CRTC];
+ bool use_pc[MAX_DPU_PLANE_GRP];
+ u32 crtc_mask_in_state = 0;
+
+ ret = drm_atomic_helper_check_modeset(dev, state);
+ if (ret)
+ return ret;
+
+ for (i = 0; i < MAX_CRTC; i++)
+ pipe_states_prone_to_put[i] = false;
+
+ for (i = 0; i < MAX_DPU_PLANE_GRP; i++) {
+ active_plane[i] = 0;
+ active_plane_fetcheco[i] = 0;
+ active_plane_hscale[i] = 0;
+ active_plane_vscale[i] = 0;
+ use_pc[i] = false;
+ grp[i] = NULL;
+ }
+
+ for_each_crtc_in_state(state, crtc, crtc_state, i)
+ crtc_mask_in_state |= drm_crtc_mask(crtc);
+
+ drm_for_each_crtc(crtc, dev) {
+ struct dpu_crtc *dpu_crtc = to_dpu_crtc(crtc);
+ struct imx_crtc_state *imx_crtc_state;
+ struct dpu_crtc_state *dcstate;
+ bool need_left, need_right, need_aux_source, use_pc_per_crtc;
+
+ use_pc_per_crtc = false;
+
+ dpu_atomic_mark_pipe_states_prone_to_put_per_crtc(crtc,
+ crtc_mask_in_state, state,
+ pipe_states_prone_to_put);
+
+ crtc_state = drm_atomic_get_crtc_state(state, crtc);
+ if (IS_ERR(crtc_state))
+ return PTR_ERR(crtc_state);
+
+ imx_crtc_state = to_imx_crtc_state(crtc_state);
+ dcstate = to_dpu_crtc_state(imx_crtc_state);
+
+ if (crtc_state->enable) {
+ if (use_pc[dpu_crtc->crtc_grp_id])
+ return -EINVAL;
+
+ if (crtc_state->adjusted_mode.clock >
+ dpu_crtc->syncmode_min_prate ||
+ crtc_state->adjusted_mode.hdisplay >
+ dpu_crtc->singlemode_max_width) {
+ if (!dpu_crtc->has_pc)
+ return -EINVAL;
+
+ use_pc_per_crtc = true;
+ }
+ }
+
+ if (use_pc_per_crtc) {
+ use_pc[dpu_crtc->crtc_grp_id] = true;
+ half_hdisplay = crtc_state->adjusted_mode.hdisplay >> 1;
+ }
+
+ dcstate->use_pc = use_pc_per_crtc;
+
+ drm_for_each_plane_mask(plane, dev, crtc_state->plane_mask) {
+ plane_state = drm_atomic_get_plane_state(state, plane);
+ dpstate = to_dpu_plane_state(plane_state);
+ fb = plane_state->fb;
+ dpu_plane = to_dpu_plane(plane);
+ grp_id = dpu_plane->grp->id;
+ active_plane[grp_id]++;
+
+ need_left = false;
+ need_right = false;
+ need_aux_source = false;
+
+ if (use_pc_per_crtc) {
+ if (plane_state->crtc_x < half_hdisplay)
+ need_left = true;
+
+ if ((plane_state->crtc_w +
+ plane_state->crtc_x) > half_hdisplay)
+ need_right = true;
+
+ if (need_left && need_right) {
+ need_aux_source = true;
+ active_plane[grp_id]++;
+ }
+ }
+
+ if (need_left && need_right) {
+ dpstate->left_crtc_w = half_hdisplay;
+ dpstate->left_crtc_w -= plane_state->crtc_x;
+
+ dpstate->left_src_w = dpstate->left_crtc_w;
+ } else if (need_left) {
+ dpstate->left_crtc_w = plane_state->crtc_w;
+ dpstate->left_src_w = plane_state->src_w >> 16;
+ } else {
+ dpstate->left_crtc_w = 0;
+ dpstate->left_src_w = 0;
+ }
+
+ if (need_right && need_left) {
+ dpstate->right_crtc_w = plane_state->crtc_x +
+ plane_state->crtc_w;
+ dpstate->right_crtc_w -= half_hdisplay;
+
+ dpstate->right_src_w = dpstate->right_crtc_w;
+ } else if (need_right) {
+ dpstate->right_crtc_w = plane_state->crtc_w;
+ dpstate->right_src_w = plane_state->src_w >> 16;
+ } else {
+ dpstate->right_crtc_w = 0;
+ dpstate->right_src_w = 0;
+ }
+
+ if (drm_format_num_planes(fb->format->format) > 1) {
+ active_plane_fetcheco[grp_id]++;
+ if (need_aux_source)
+ active_plane_fetcheco[grp_id]++;
+ }
+
+ if (plane_state->src_w >> 16 != plane_state->crtc_w) {
+ if (use_pc_per_crtc)
+ return -EINVAL;
+
+ active_plane_hscale[grp_id]++;
+ }
+
+ if (plane_state->src_h >> 16 != plane_state->crtc_h) {
+ if (use_pc_per_crtc)
+ return -EINVAL;
+
+ active_plane_vscale[grp_id]++;
+ }
+
+ if (grp[grp_id] == NULL)
+ grp[grp_id] = dpu_plane->grp;
+
+ dpstate->need_aux_source = need_aux_source;
+ }
+ }
+
+ /* enough resources? */
+ for (i = 0; i < MAX_DPU_PLANE_GRP; i++) {
+ if (grp[i]) {
+ if (active_plane[i] > grp[i]->hw_plane_num)
+ return -EINVAL;
+
+ if (active_plane_fetcheco[i] >
+ grp[i]->hw_plane_fetcheco_num)
+ return -EINVAL;
+
+ if (active_plane_hscale[i] >
+ grp[i]->hw_plane_hscaler_num)
+ return -EINVAL;
+
+ if (active_plane_vscale[i] >
+ grp[i]->hw_plane_vscaler_num)
+ return -EINVAL;
+ }
+ }
+
+ /* clear resource mask */
+ for (i = 0; i < MAX_DPU_PLANE_GRP; i++) {
+ if (grp[i]) {
+ mutex_lock(&grp[i]->mutex);
+ grp[i]->src_a_mask = ~grp[i]->src_na_mask;
+ grp[i]->src_use_vproc_mask = 0;
+ mutex_unlock(&grp[i]->mutex);
+ }
+ }
+
+ ret = drm_atomic_normalize_zpos(dev, state);
+ if (ret)
+ return ret;
+
+ for_each_crtc_in_state(state, crtc, crtc_state, i) {
+ struct dpu_crtc *dpu_crtc = to_dpu_crtc(crtc);
+ struct drm_plane_state **states;
+ int n;
+
+ states = dpu_atomic_alloc_tmp_planes_per_crtc(dev);
+ if (IS_ERR(states))
+ return PTR_ERR(states);
+
+ n = dpu_atomic_sort_planes_per_crtc(crtc_state, states);
+ if (n < 0) {
+ kfree(states);
+ return n;
+ }
+
+ /* no active planes? */
+ if (n == 0) {
+ kfree(states);
+ continue;
+ }
+
+ /* 'zpos = 0' means primary plane */
+ if (states[0]->plane->type != DRM_PLANE_TYPE_PRIMARY) {
+ kfree(states);
+ return -EINVAL;
+ }
+
+ ret = dpu_atomic_compute_plane_base_per_crtc(crtc_state, states,
+ n, use_pc[dpu_crtc->crtc_grp_id]);
+ if (ret) {
+ kfree(states);
+ return ret;
+ }
+
+ dpu_atomic_set_top_plane_per_crtc(states, n,
+ use_pc[dpu_crtc->crtc_grp_id]);
+
+ ret = dpu_atomic_assign_plane_source_per_crtc(states, n,
+ use_pc[dpu_crtc->crtc_grp_id]);
+ if (ret) {
+ kfree(states);
+ return ret;
+ }
+
+ kfree(states);
+
+ if (pipe_states_prone_to_put[drm_crtc_index(crtc)])
+ dpu_atomic_put_possible_states_per_crtc(crtc_state);
+ }
+
+ ret = drm_atomic_helper_check_planes(dev, state);
+ if (ret)
+ return ret;
+
+ return ret;
+}
+
+static void dpu_drm_commit_tail(struct drm_atomic_state *old_state)
+{
+ struct drm_device *dev = old_state->dev;
+
+ drm_atomic_helper_wait_for_fences(dev, old_state, false);
+
+ drm_atomic_helper_wait_for_dependencies(old_state);
+
+ drm_atomic_helper_commit_tail(old_state);
+
+ drm_atomic_helper_commit_cleanup_done(old_state);
+
+ drm_atomic_state_put(old_state);
+}
+
+static void dpu_drm_commit_work(struct work_struct *work)
+{
+ struct drm_atomic_state *state = container_of(work,
+ struct drm_atomic_state,
+ commit_work);
+ dpu_drm_commit_tail(state);
+}
+
+/*
+ * This is almost a copy of drm_atomic_helper_commit().
+ * For nonblock commits, we queue the work on a freezable and unbound work queue
+ * of our own instead of system_unbound_wq to make sure work items on the work
+ * queue are drained in the freeze phase of the system suspend operations.
+ */
+static int dpu_drm_atomic_commit(struct drm_device *dev,
+ struct drm_atomic_state *state,
+ bool nonblock)
+{
+ struct imx_drm_device *imxdrm = dev->dev_private;
+ int ret;
+
+ if (state->async_update) {
+ ret = drm_atomic_helper_prepare_planes(dev, state);
+ if (ret)
+ return ret;
+
+ drm_atomic_helper_async_commit(dev, state);
+ drm_atomic_helper_cleanup_planes(dev, state);
+
+ return 0;
+ }
+
+ ret = drm_atomic_helper_setup_commit(state, nonblock);
+ if (ret)
+ return ret;
+
+ INIT_WORK(&state->commit_work, dpu_drm_commit_work);
+
+ ret = drm_atomic_helper_prepare_planes(dev, state);
+ if (ret)
+ return ret;
+
+ if (!nonblock) {
+ ret = drm_atomic_helper_wait_for_fences(dev, state, true);
+ if (ret)
+ goto err;
+ }
+
+ ret = drm_atomic_helper_swap_state(state, true);
+ if (ret)
+ goto err;
+
+ drm_atomic_state_get(state);
+ if (nonblock)
+ queue_work(imxdrm->dpu_nonblock_commit_wq, &state->commit_work);
+ else
+ dpu_drm_commit_tail(state);
+
+ return 0;
+
+err:
+ drm_atomic_helper_cleanup_planes(dev, state);
+ return ret;
+}
+
+const struct drm_mode_config_funcs dpu_drm_mode_config_funcs = {
+ .fb_create = drm_fb_cma_create,
+ .output_poll_changed = dpu_drm_output_poll_changed,
+ .atomic_check = dpu_drm_atomic_check,
+ .atomic_commit = dpu_drm_atomic_commit,
+};
diff --git a/drivers/gpu/drm/imx/dpu/dpu-kms.h b/drivers/gpu/drm/imx/dpu/dpu-kms.h
new file mode 100644
index 000000000000..8c42abbf203b
--- /dev/null
+++ b/drivers/gpu/drm/imx/dpu/dpu-kms.h
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2017 NXP
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#ifndef _DPU_KMS_H_
+#define _DPU_KMS_H_
+
+extern const struct drm_mode_config_funcs dpu_drm_mode_config_funcs;
+
+#endif
diff --git a/drivers/gpu/drm/imx/dpu/dpu-plane.c b/drivers/gpu/drm/imx/dpu/dpu-plane.c
new file mode 100644
index 000000000000..ca49176a7624
--- /dev/null
+++ b/drivers/gpu/drm/imx/dpu/dpu-plane.c
@@ -0,0 +1,977 @@
+/*
+ * Copyright 2017-2018 NXP
+ *
+ * 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 <drm/drmP.h>
+#include <drm/drm_atomic.h>
+#include <drm/drm_atomic_helper.h>
+#include <drm/drm_fb_cma_helper.h>
+#include <drm/drm_gem_cma_helper.h>
+#include <drm/drm_plane_helper.h>
+#include <video/dpu.h>
+#include <video/imx8-prefetch.h>
+#include "dpu-plane.h"
+#include "imx-drm.h"
+
+/*
+ * RGB and packed/2planar YUV formats
+ * are widely supported by many fetch units.
+ */
+static const uint32_t dpu_primary_formats[] = {
+ DRM_FORMAT_ARGB8888,
+ DRM_FORMAT_XRGB8888,
+ DRM_FORMAT_ABGR8888,
+ DRM_FORMAT_XBGR8888,
+ DRM_FORMAT_RGBA8888,
+ DRM_FORMAT_RGBX8888,
+ DRM_FORMAT_BGRA8888,
+ DRM_FORMAT_BGRX8888,
+ DRM_FORMAT_RGB565,
+
+ DRM_FORMAT_YUYV,
+ DRM_FORMAT_UYVY,
+ DRM_FORMAT_NV12,
+ DRM_FORMAT_NV21,
+};
+
+static const uint32_t dpu_overlay_formats[] = {
+ DRM_FORMAT_XRGB8888,
+ DRM_FORMAT_XBGR8888,
+ DRM_FORMAT_RGBX8888,
+ DRM_FORMAT_BGRX8888,
+ DRM_FORMAT_RGB565,
+
+ DRM_FORMAT_YUYV,
+ DRM_FORMAT_UYVY,
+ DRM_FORMAT_NV12,
+ DRM_FORMAT_NV21,
+};
+
+static const uint64_t dpu_format_modifiers[] = {
+ DRM_FORMAT_MOD_VIVANTE_TILED,
+ DRM_FORMAT_MOD_VIVANTE_SUPER_TILED,
+ DRM_FORMAT_MOD_AMPHION_TILED,
+ DRM_FORMAT_MOD_LINEAR,
+ DRM_FORMAT_MOD_INVALID,
+};
+
+static void dpu_plane_destroy(struct drm_plane *plane)
+{
+ struct dpu_plane *dpu_plane = to_dpu_plane(plane);
+
+ drm_plane_cleanup(plane);
+ kfree(dpu_plane);
+}
+
+static void dpu_plane_reset(struct drm_plane *plane)
+{
+ struct dpu_plane_state *state;
+
+ if (plane->state) {
+ __drm_atomic_helper_plane_destroy_state(plane->state);
+ kfree(to_dpu_plane_state(plane->state));
+ plane->state = NULL;
+ }
+
+ state = kzalloc(sizeof(*state), GFP_KERNEL);
+ if (!state)
+ return;
+
+ state->base.zpos = plane->type == DRM_PLANE_TYPE_PRIMARY ? 0 : 1;
+
+ plane->state = &state->base;
+ plane->state->plane = plane;
+ plane->state->rotation = DRM_MODE_ROTATE_0;
+}
+
+static struct drm_plane_state *
+dpu_drm_atomic_plane_duplicate_state(struct drm_plane *plane)
+{
+ struct dpu_plane_state *state, *copy;
+
+ if (WARN_ON(!plane->state))
+ return NULL;
+
+ copy = kmalloc(sizeof(*state), GFP_KERNEL);
+ if (!copy)
+ return NULL;
+
+ __drm_atomic_helper_plane_duplicate_state(plane, &copy->base);
+ state = to_dpu_plane_state(plane->state);
+ copy->stage = state->stage;
+ copy->source = state->source;
+ copy->blend = state->blend;
+ copy->aux_stage = state->aux_stage;
+ copy->aux_source = state->aux_source;
+ copy->aux_blend = state->aux_blend;
+ copy->layer_x = state->layer_x;
+ copy->layer_y = state->layer_y;
+ copy->base_x = state->base_x;
+ copy->base_y = state->base_y;
+ copy->base_w = state->base_w;
+ copy->base_h = state->base_h;
+ copy->is_top = state->is_top;
+ copy->use_prefetch = state->use_prefetch;
+ copy->use_aux_prefetch = state->use_aux_prefetch;
+ copy->need_aux_source = state->need_aux_source;
+ copy->left_layer_x = state->left_layer_x;
+ copy->left_base_x = state->left_base_x;
+ copy->left_base_w = state->left_base_w;
+ copy->left_src_w = state->left_src_w;
+ copy->left_crtc_w = state->left_crtc_w;
+ copy->right_layer_x = state->right_layer_x;
+ copy->right_base_x = state->right_base_x;
+ copy->right_base_w = state->right_base_w;
+ copy->right_src_w = state->right_src_w;
+ copy->right_crtc_w = state->right_crtc_w;
+ copy->is_left_top = state->is_left_top;
+ copy->is_right_top = state->is_right_top;
+
+ return &copy->base;
+}
+
+static void dpu_drm_atomic_plane_destroy_state(struct drm_plane *plane,
+ struct drm_plane_state *state)
+{
+ __drm_atomic_helper_plane_destroy_state(state);
+ kfree(to_dpu_plane_state(state));
+}
+
+static bool dpu_drm_plane_format_mod_supported(struct drm_plane *plane,
+ uint32_t format,
+ uint64_t modifier)
+{
+ if (WARN_ON(modifier == DRM_FORMAT_MOD_INVALID))
+ return false;
+
+ switch (format) {
+ case DRM_FORMAT_YUYV:
+ case DRM_FORMAT_UYVY:
+ return modifier == DRM_FORMAT_MOD_LINEAR;
+ case DRM_FORMAT_ARGB8888:
+ case DRM_FORMAT_XRGB8888:
+ case DRM_FORMAT_ABGR8888:
+ case DRM_FORMAT_XBGR8888:
+ case DRM_FORMAT_RGBA8888:
+ case DRM_FORMAT_RGBX8888:
+ case DRM_FORMAT_BGRA8888:
+ case DRM_FORMAT_BGRX8888:
+ case DRM_FORMAT_RGB565:
+ return modifier == DRM_FORMAT_MOD_LINEAR ||
+ modifier == DRM_FORMAT_MOD_VIVANTE_TILED ||
+ modifier == DRM_FORMAT_MOD_VIVANTE_SUPER_TILED;
+ case DRM_FORMAT_NV12:
+ case DRM_FORMAT_NV21:
+ return modifier == DRM_FORMAT_MOD_LINEAR ||
+ modifier == DRM_FORMAT_MOD_AMPHION_TILED;
+ default:
+ return false;
+ }
+}
+
+static const struct drm_plane_funcs dpu_plane_funcs = {
+ .update_plane = drm_atomic_helper_update_plane,
+ .disable_plane = drm_atomic_helper_disable_plane,
+ .destroy = dpu_plane_destroy,
+ .reset = dpu_plane_reset,
+ .atomic_duplicate_state = dpu_drm_atomic_plane_duplicate_state,
+ .atomic_destroy_state = dpu_drm_atomic_plane_destroy_state,
+ .format_mod_supported = dpu_drm_plane_format_mod_supported,
+};
+
+static inline dma_addr_t
+drm_plane_state_to_baseaddr(struct drm_plane_state *state, bool aux_source)
+{
+ struct drm_framebuffer *fb = state->fb;
+ struct drm_gem_cma_object *cma_obj;
+ struct dpu_plane_state *dpstate = to_dpu_plane_state(state);
+ unsigned int x = (state->src_x >> 16) +
+ (aux_source ? dpstate->left_src_w : 0);
+ unsigned int y = state->src_y >> 16;
+
+ cma_obj = drm_fb_cma_get_gem_obj(fb, 0);
+ BUG_ON(!cma_obj);
+
+ if (fb->modifier)
+ return cma_obj->paddr + fb->offsets[0];
+
+ if (fb->flags & DRM_MODE_FB_INTERLACED)
+ y /= 2;
+
+ return cma_obj->paddr + fb->offsets[0] + fb->pitches[0] * y +
+ drm_format_plane_cpp(fb->format->format, 0) * x;
+}
+
+static inline dma_addr_t
+drm_plane_state_to_uvbaseaddr(struct drm_plane_state *state, bool aux_source)
+{
+ struct drm_framebuffer *fb = state->fb;
+ struct drm_gem_cma_object *cma_obj;
+ struct dpu_plane_state *dpstate = to_dpu_plane_state(state);
+ int x = (state->src_x >> 16) + (aux_source ? dpstate->left_src_w : 0);
+ int y = state->src_y >> 16;
+
+ cma_obj = drm_fb_cma_get_gem_obj(fb, 1);
+ BUG_ON(!cma_obj);
+
+ if (fb->modifier)
+ return cma_obj->paddr + fb->offsets[1];
+
+ x /= drm_format_horz_chroma_subsampling(fb->format->format);
+ y /= drm_format_vert_chroma_subsampling(fb->format->format);
+
+ if (fb->flags & DRM_MODE_FB_INTERLACED)
+ y /= 2;
+
+ return cma_obj->paddr + fb->offsets[1] + fb->pitches[1] * y +
+ drm_format_plane_cpp(fb->format->format, 1) * x;
+}
+
+static int dpu_plane_atomic_check(struct drm_plane *plane,
+ struct drm_plane_state *state)
+{
+ struct dpu_plane *dplane = to_dpu_plane(plane);
+ struct dpu_plane_state *dpstate = to_dpu_plane_state(state);
+ struct dpu_plane_state *old_dpstate = to_dpu_plane_state(plane->state);
+ struct dpu_plane_res *res = &dplane->grp->res;
+ struct drm_crtc_state *crtc_state;
+ struct drm_framebuffer *fb = state->fb;
+ struct dpu_fetchunit *fu;
+ struct dprc *dprc;
+ dma_addr_t baseaddr, uv_baseaddr = 0;
+ u32 src_w = state->src_w >> 16, src_h = state->src_h >> 16,
+ src_x = state->src_x >> 16, src_y = state->src_y >> 16;
+ unsigned int frame_width;
+ int bpp;
+ bool fb_is_interlaced;
+ bool check_aux_source = false;
+
+ /* pure software check */
+ if (plane->type != DRM_PLANE_TYPE_PRIMARY)
+ if (WARN_ON(dpstate->base_x || dpstate->base_y ||
+ dpstate->base_w || dpstate->base_h))
+ return -EINVAL;
+
+ /* ok to disable */
+ if (!fb) {
+ dpstate->stage = LB_PRIM_SEL__DISABLE;
+ dpstate->source = LB_SEC_SEL__DISABLE;
+ dpstate->blend = ID_NONE;
+ dpstate->aux_stage = LB_PRIM_SEL__DISABLE;
+ dpstate->aux_source = LB_SEC_SEL__DISABLE;
+ dpstate->aux_blend = ID_NONE;
+ dpstate->layer_x = 0;
+ dpstate->layer_y = 0;
+ dpstate->base_x = 0;
+ dpstate->base_y = 0;
+ dpstate->base_w = 0;
+ dpstate->base_h = 0;
+ dpstate->is_top = false;
+ dpstate->use_prefetch = false;
+ dpstate->use_aux_prefetch = false;
+ dpstate->need_aux_source = false;
+ dpstate->left_layer_x = 0;
+ dpstate->left_base_x = 0;
+ dpstate->left_base_w = 0;
+ dpstate->left_src_w = 0;
+ dpstate->left_crtc_w = 0;
+ dpstate->right_layer_x = 0;
+ dpstate->right_base_x = 0;
+ dpstate->right_base_w = 0;
+ dpstate->right_src_w = 0;
+ dpstate->right_crtc_w = 0;
+ dpstate->is_left_top = false;
+ dpstate->is_right_top = false;
+ return 0;
+ }
+
+ if (!state->crtc)
+ return -EINVAL;
+
+ fb_is_interlaced = !!(fb->flags & DRM_MODE_FB_INTERLACED);
+
+ if (fb->modifier &&
+ fb->modifier != DRM_FORMAT_MOD_AMPHION_TILED &&
+ fb->modifier != DRM_FORMAT_MOD_VIVANTE_TILED &&
+ fb->modifier != DRM_FORMAT_MOD_VIVANTE_SUPER_TILED)
+ return -EINVAL;
+
+ if (dplane->grp->has_vproc) {
+ /* no down scaling */
+ if (src_w > state->crtc_w || src_h > state->crtc_h)
+ return -EINVAL;
+ } else {
+ /* no scaling */
+ if (src_w != state->crtc_w || src_h != state->crtc_h)
+ return -EINVAL;
+ }
+
+ /* no off screen */
+ if (state->crtc_x < 0 || state->crtc_y < 0)
+ return -EINVAL;
+
+ crtc_state =
+ drm_atomic_get_existing_crtc_state(state->state, state->crtc);
+ if (WARN_ON(!crtc_state))
+ return -EINVAL;
+
+ /* mode set is needed when base x/y is changed */
+ if (plane->type == DRM_PLANE_TYPE_PRIMARY)
+ if ((dpstate->base_x != old_dpstate->base_x) ||
+ (dpstate->base_y != old_dpstate->base_y))
+ crtc_state->mode_changed = true;
+
+ if (state->crtc_x + state->crtc_w >
+ crtc_state->adjusted_mode.hdisplay)
+ return -EINVAL;
+ if (state->crtc_y + state->crtc_h >
+ crtc_state->adjusted_mode.vdisplay)
+ return -EINVAL;
+
+ /* pixel/line count and position parameters check */
+ if (drm_format_horz_chroma_subsampling(fb->format->format) == 2) {
+ if (dpstate->left_src_w || dpstate->right_src_w) {
+ if ((dpstate->left_src_w % 2) ||
+ (dpstate->right_src_w % 2) || (src_x % 2))
+ return -EINVAL;
+ } else {
+ if ((src_w % 2) || (src_x % 2))
+ return -EINVAL;
+ }
+ }
+ if (drm_format_vert_chroma_subsampling(fb->format->format) == 2) {
+ if (src_h % (fb_is_interlaced ? 4 : 2))
+ return -EINVAL;
+ if (src_y % (fb_is_interlaced ? 4 : 2))
+ return -EINVAL;
+ }
+
+ /* for tile formats, framebuffer has to be tile aligned */
+ switch (fb->modifier) {
+ case DRM_FORMAT_MOD_AMPHION_TILED:
+ if (fb->width % 8)
+ return -EINVAL;
+ if (fb->height % 256)
+ return -EINVAL;
+ break;
+ case DRM_FORMAT_MOD_VIVANTE_TILED:
+ if (fb->width % 4)
+ return -EINVAL;
+ if (fb->height % 4)
+ return -EINVAL;
+ break;
+ case DRM_FORMAT_MOD_VIVANTE_SUPER_TILED:
+ if (fb->width % 64)
+ return -EINVAL;
+ if (fb->height % 64)
+ return -EINVAL;
+ break;
+ default:
+ break;
+ }
+
+again:
+ fu = source_to_fu(res,
+ check_aux_source ? dpstate->aux_source : dpstate->source);
+ if (!fu)
+ return -EINVAL;
+
+ dprc = fu->dprc;
+
+ if (dpstate->need_aux_source)
+ frame_width = check_aux_source ?
+ dpstate->right_src_w : dpstate->left_src_w;
+ else
+ frame_width = src_w;
+
+ if (dprc &&
+ dprc_format_supported(dprc, fb->format->format, fb->modifier) &&
+ dprc_stride_supported(dprc, fb->pitches[0], fb->pitches[1],
+ frame_width, fb->format->format)) {
+ if (check_aux_source)
+ dpstate->use_aux_prefetch = true;
+ else
+ dpstate->use_prefetch = true;
+ } else {
+ if (check_aux_source)
+ dpstate->use_aux_prefetch = false;
+ else
+ dpstate->use_prefetch = false;
+ }
+
+ if (fb->modifier) {
+ if (check_aux_source && !dpstate->use_aux_prefetch)
+ return -EINVAL;
+ else if (!check_aux_source && !dpstate->use_prefetch)
+ return -EINVAL;
+ }
+
+ /*
+ * base address alignment check
+ *
+ * The (uv) base address offset introduced by PRG x/y
+ * offset(for tile formats) would not impact the alignment
+ * check, so we don't take the offset into consideration.
+ */
+ baseaddr = drm_plane_state_to_baseaddr(state, check_aux_source);
+ switch (fb->format->format) {
+ case DRM_FORMAT_YUYV:
+ case DRM_FORMAT_UYVY:
+ bpp = 16;
+ break;
+ case DRM_FORMAT_NV12:
+ case DRM_FORMAT_NV21:
+ bpp = 8;
+ break;
+ default:
+ bpp = drm_format_plane_cpp(fb->format->format, 0) * 8;
+ break;
+ }
+ switch (bpp) {
+ case 32:
+ if (baseaddr & 0x3)
+ return -EINVAL;
+ break;
+ case 16:
+ if (fb->modifier) {
+ if (baseaddr & 0x1)
+ return -EINVAL;
+ } else {
+ if (check_aux_source) {
+ if (baseaddr &
+ (dpstate->use_aux_prefetch ? 0x7 : 0x1))
+ return -EINVAL;
+ } else {
+ if (baseaddr &
+ (dpstate->use_prefetch ? 0x7 : 0x1))
+ return -EINVAL;
+ }
+ }
+ break;
+ }
+
+ if (fb->pitches[0] > 0x10000)
+ return -EINVAL;
+
+ /* UV base address alignment check, assuming 16bpp */
+ if (drm_format_num_planes(fb->format->format) > 1) {
+ uv_baseaddr = drm_plane_state_to_uvbaseaddr(state,
+ check_aux_source);
+ if (fb->modifier) {
+ if (uv_baseaddr & 0x1)
+ return -EINVAL;
+ } else {
+ if (check_aux_source) {
+ if (uv_baseaddr &
+ (dpstate->use_aux_prefetch ? 0x7 : 0x1))
+ return -EINVAL;
+ } else {
+ if (uv_baseaddr &
+ (dpstate->use_prefetch ? 0x7 : 0x1))
+ return -EINVAL;
+ }
+ }
+
+ if (fb->pitches[1] > 0x10000)
+ return -EINVAL;
+ }
+
+ if (!check_aux_source && dpstate->use_prefetch &&
+ !dprc_stride_double_check(dprc, frame_width, src_x,
+ fb->format->format,
+ fb->modifier,
+ baseaddr, uv_baseaddr)) {
+ if (fb->modifier)
+ return -EINVAL;
+
+ if (bpp == 16 && (baseaddr & 0x1))
+ return -EINVAL;
+
+ if (uv_baseaddr & 0x1)
+ return -EINVAL;
+
+ dpstate->use_prefetch = false;
+ } else if (check_aux_source && dpstate->use_aux_prefetch &&
+ !dprc_stride_double_check(dprc, frame_width, src_x,
+ fb->format->format,
+ fb->modifier,
+ baseaddr, uv_baseaddr)) {
+ if (fb->modifier)
+ return -EINVAL;
+
+ if (bpp == 16 && (baseaddr & 0x1))
+ return -EINVAL;
+
+ if (uv_baseaddr & 0x1)
+ return -EINVAL;
+
+ dpstate->use_aux_prefetch = false;
+ }
+
+ if (dpstate->need_aux_source && !check_aux_source) {
+ check_aux_source = true;
+ goto again;
+ }
+
+ return 0;
+}
+
+static void dpu_plane_atomic_update(struct drm_plane *plane,
+ struct drm_plane_state *old_state)
+{
+ struct dpu_plane *dplane = to_dpu_plane(plane);
+ struct drm_plane_state *state = plane->state;
+ struct dpu_plane_state *dpstate = to_dpu_plane_state(state);
+ struct drm_framebuffer *fb = state->fb;
+ struct dpu_plane_res *res = &dplane->grp->res;
+ struct dpu_fetchunit *fu;
+ struct dpu_fetchunit *fe = NULL;
+ struct dprc *dprc;
+ struct dpu_hscaler *hs = NULL;
+ struct dpu_vscaler *vs = NULL;
+ struct dpu_layerblend *lb;
+ struct dpu_constframe *cf, *aux_cf;
+ struct dpu_extdst *ed;
+ struct dpu_framegen *fg, *aux_fg;
+ struct device *dev = plane->dev->dev;
+ dma_addr_t baseaddr, uv_baseaddr = 0;
+ dpu_block_id_t blend, fe_id, vs_id = ID_NONE, hs_id;
+ lb_sec_sel_t source;
+ lb_prim_sel_t stage;
+ unsigned int stream_id;
+ unsigned int src_w, src_h, src_x, src_y;
+ unsigned int layer_x;
+ unsigned int mt_w = 0, mt_h = 0; /* w/h in a micro-tile */
+ int bpp, lb_id;
+ bool need_fetcheco, need_hscaler = false, need_vscaler = false;
+ bool prefetch_start, uv_prefetch_start;
+ bool crtc_use_pc = dpstate->left_src_w || dpstate->right_src_w;
+ bool update_aux_source = false;
+ bool use_prefetch;
+ bool need_modeset;
+ bool is_overlay = plane->type == DRM_PLANE_TYPE_OVERLAY;
+ bool fb_is_interlaced;
+
+ /*
+ * Do nothing since the plane is disabled by
+ * crtc_func->atomic_begin/flush.
+ */
+ if (!fb)
+ return;
+
+ need_modeset = drm_atomic_crtc_needs_modeset(state->crtc->state);
+ fb_is_interlaced = !!(fb->flags & DRM_MODE_FB_INTERLACED);
+
+again:
+ need_fetcheco = false;
+ prefetch_start = false;
+ uv_prefetch_start = false;
+
+ source = update_aux_source ? dpstate->aux_source : dpstate->source;
+ blend = update_aux_source ? dpstate->aux_blend : dpstate->blend;
+ stage = update_aux_source ? dpstate->aux_stage : dpstate->stage;
+ use_prefetch = update_aux_source ?
+ dpstate->use_aux_prefetch : dpstate->use_prefetch;
+
+ if (crtc_use_pc) {
+ if (update_aux_source) {
+ stream_id = 1;
+ layer_x = dpstate->right_layer_x;
+ } else {
+ stream_id = dpstate->left_src_w ? 0 : 1;
+ layer_x = dpstate->left_src_w ?
+ dpstate->left_layer_x : dpstate->right_layer_x;
+ }
+ } else {
+ stream_id = dplane->stream_id;
+ layer_x = dpstate->layer_x;
+ }
+
+ fg = res->fg[stream_id];
+
+ fu = source_to_fu(res, source);
+ if (!fu)
+ return;
+
+ dprc = fu->dprc;
+
+ lb_id = blend_to_id(blend);
+ if (lb_id < 0)
+ return;
+
+ lb = res->lb[lb_id];
+
+ if (crtc_use_pc) {
+ if (update_aux_source || !dpstate->left_src_w)
+ src_w = dpstate->right_src_w;
+ else
+ src_w = dpstate->left_src_w;
+ } else {
+ src_w = state->src_w >> 16;
+ }
+ src_h = state->src_h >> 16;
+ if (crtc_use_pc && update_aux_source) {
+ if (fb->modifier)
+ src_x = (state->src_x >> 16) + dpstate->left_src_w;
+ else
+ src_x = 0;
+ } else {
+ src_x = fb->modifier ? (state->src_x >> 16) : 0;
+ }
+ src_y = fb->modifier ? (state->src_y >> 16) : 0;
+
+ if (fetchunit_is_fetchdecode(fu)) {
+ if (fetchdecode_need_fetcheco(fu, fb->format->format)) {
+ need_fetcheco = true;
+ fe = fetchdecode_get_fetcheco(fu);
+ if (IS_ERR(fe))
+ return;
+ }
+
+ /* assume pixel combiner is unused */
+ if ((src_w != state->crtc_w) && !crtc_use_pc) {
+ need_hscaler = true;
+ hs = fetchdecode_get_hscaler(fu);
+ if (IS_ERR(hs))
+ return;
+ }
+
+ if ((src_h != state->crtc_h) || fb_is_interlaced) {
+ need_vscaler = true;
+ vs = fetchdecode_get_vscaler(fu);
+ if (IS_ERR(vs))
+ return;
+ }
+ }
+
+ switch (fb->format->format) {
+ case DRM_FORMAT_YUYV:
+ case DRM_FORMAT_UYVY:
+ bpp = 16;
+ break;
+ case DRM_FORMAT_NV12:
+ case DRM_FORMAT_NV21:
+ bpp = 8;
+ break;
+ default:
+ bpp = drm_format_plane_cpp(fb->format->format, 0) * 8;
+ break;
+ }
+
+ switch (fb->modifier) {
+ case DRM_FORMAT_MOD_AMPHION_TILED:
+ mt_w = 8;
+ mt_h = 8;
+ break;
+ case DRM_FORMAT_MOD_VIVANTE_TILED:
+ case DRM_FORMAT_MOD_VIVANTE_SUPER_TILED:
+ mt_w = (bpp == 16) ? 8 : 4;
+ mt_h = 4;
+ break;
+ default:
+ break;
+ }
+
+ baseaddr = drm_plane_state_to_baseaddr(state, update_aux_source);
+ if (need_fetcheco)
+ uv_baseaddr = drm_plane_state_to_uvbaseaddr(state,
+ update_aux_source);
+
+ if (use_prefetch &&
+ (fu->ops->get_stream_id(fu) == DPU_PLANE_SRC_DISABLED ||
+ need_modeset))
+ prefetch_start = true;
+
+ fu->ops->set_burstlength(fu, src_x, mt_w, bpp, baseaddr, use_prefetch);
+ fu->ops->set_src_bpp(fu, bpp);
+ fu->ops->set_src_stride(fu, src_w, src_x, mt_w, bpp, fb->pitches[0],
+ baseaddr, use_prefetch);
+ fu->ops->set_src_buf_dimensions(fu, src_w, src_h, 0, fb_is_interlaced);
+ fu->ops->set_fmt(fu, fb->format->format, fb_is_interlaced);
+ fu->ops->enable_src_buf(fu);
+ fu->ops->set_framedimensions(fu, src_w, src_h, fb_is_interlaced);
+ fu->ops->set_baseaddress(fu, src_w, src_x, src_y, mt_w, mt_h, bpp,
+ baseaddr);
+ fu->ops->set_stream_id(fu, stream_id ?
+ DPU_PLANE_SRC_TO_DISP_STREAM1 :
+ DPU_PLANE_SRC_TO_DISP_STREAM0);
+ fu->ops->unpin_off(fu);
+
+ dev_dbg(dev, "[PLANE:%d:%s] %s-0x%02x\n",
+ plane->base.id, plane->name, fu->name, fu->id);
+
+ if (need_fetcheco) {
+ fe_id = fetcheco_get_block_id(fe);
+ if (fe_id == ID_NONE)
+ return;
+
+ if (use_prefetch &&
+ (fe->ops->get_stream_id(fe) == DPU_PLANE_SRC_DISABLED ||
+ need_modeset))
+ uv_prefetch_start = true;
+
+ fetchdecode_pixengcfg_dynamic_src_sel(fu,
+ (fd_dynamic_src_sel_t)fe_id);
+ fe->ops->set_burstlength(fe, src_x, mt_w, bpp, uv_baseaddr,
+ use_prefetch);
+ fe->ops->set_src_bpp(fe, 16);
+ fe->ops->set_src_stride(fe, src_w, src_x, mt_w, bpp,
+ fb->pitches[1],
+ uv_baseaddr, use_prefetch);
+ fe->ops->set_fmt(fe, fb->format->format, fb_is_interlaced);
+ fe->ops->set_src_buf_dimensions(fe, src_w, src_h,
+ fb->format->format,
+ fb_is_interlaced);
+ fe->ops->set_framedimensions(fe, src_w, src_h,
+ fb_is_interlaced);
+ fe->ops->set_baseaddress(fe, src_w, src_x, src_y / 2,
+ mt_w, mt_h, bpp, uv_baseaddr);
+ fe->ops->enable_src_buf(fe);
+ fe->ops->set_stream_id(fe, stream_id ?
+ DPU_PLANE_SRC_TO_DISP_STREAM1 :
+ DPU_PLANE_SRC_TO_DISP_STREAM0);
+ fe->ops->unpin_off(fe);
+
+ dev_dbg(dev, "[PLANE:%d:%s] %s-0x%02x\n",
+ plane->base.id, plane->name, fe->name, fe_id);
+ } else {
+ if (fetchunit_is_fetchdecode(fu))
+ fetchdecode_pixengcfg_dynamic_src_sel(fu,
+ FD_SRC_DISABLE);
+ }
+
+ /* vscaler comes first */
+ if (need_vscaler) {
+ vs_id = vscaler_get_block_id(vs);
+ if (vs_id == ID_NONE)
+ return;
+
+ vscaler_pixengcfg_dynamic_src_sel(vs, (vs_src_sel_t)source);
+ vscaler_pixengcfg_clken(vs, CLKEN__AUTOMATIC);
+ vscaler_setup1(vs, src_h, state->crtc_h, fb_is_interlaced);
+ vscaler_setup2(vs, fb_is_interlaced);
+ vscaler_setup3(vs, fb_is_interlaced);
+ vscaler_output_size(vs, state->crtc_h);
+ vscaler_field_mode(vs, fb_is_interlaced ?
+ SCALER_ALWAYS0 : SCALER_INPUT);
+ vscaler_filter_mode(vs, SCALER_LINEAR);
+ vscaler_scale_mode(vs, SCALER_UPSCALE);
+ vscaler_mode(vs, SCALER_ACTIVE);
+ vscaler_set_stream_id(vs, dplane->stream_id ?
+ DPU_PLANE_SRC_TO_DISP_STREAM1 :
+ DPU_PLANE_SRC_TO_DISP_STREAM0);
+
+ source = (lb_sec_sel_t)vs_id;
+
+ dev_dbg(dev, "[PLANE:%d:%s] vscaler-0x%02x\n",
+ plane->base.id, plane->name, vs_id);
+ }
+
+ /* and then, hscaler */
+ if (need_hscaler) {
+ hs_id = hscaler_get_block_id(hs);
+ if (hs_id == ID_NONE)
+ return;
+
+ hscaler_pixengcfg_dynamic_src_sel(hs, need_vscaler ?
+ (hs_src_sel_t)vs_id :
+ (hs_src_sel_t)source);
+ hscaler_pixengcfg_clken(hs, CLKEN__AUTOMATIC);
+ hscaler_setup1(hs, src_w, state->crtc_w);
+ hscaler_output_size(hs, state->crtc_w);
+ hscaler_filter_mode(hs, SCALER_LINEAR);
+ hscaler_scale_mode(hs, SCALER_UPSCALE);
+ hscaler_mode(hs, SCALER_ACTIVE);
+ hscaler_set_stream_id(hs, dplane->stream_id ?
+ DPU_PLANE_SRC_TO_DISP_STREAM1 :
+ DPU_PLANE_SRC_TO_DISP_STREAM0);
+
+ source = (lb_sec_sel_t)hs_id;
+
+ dev_dbg(dev, "[PLANE:%d:%s] hscaler-0x%02x\n",
+ plane->base.id, plane->name, hs_id);
+ }
+
+ if (use_prefetch) {
+ dprc_configure(dprc, stream_id,
+ src_w, src_h, src_x, src_y,
+ fb->pitches[0], fb->format->format,
+ fb->modifier, baseaddr, uv_baseaddr,
+ prefetch_start, uv_prefetch_start,
+ fb_is_interlaced);
+ if (prefetch_start || uv_prefetch_start)
+ dprc_enable(dprc);
+
+ dprc_reg_update(dprc);
+
+ if (prefetch_start || uv_prefetch_start) {
+ dprc_first_frame_handle(dprc);
+
+ if (!need_modeset && is_overlay)
+ framegen_wait_for_frame_counter_moving(fg);
+ }
+
+ if (update_aux_source)
+ dev_dbg(dev, "[PLANE:%d:%s] use aux prefetch\n",
+ plane->base.id, plane->name);
+ else
+ dev_dbg(dev, "[PLANE:%d:%s] use prefetch\n",
+ plane->base.id, plane->name);
+ } else if (dprc) {
+ dprc_disable(dprc);
+
+ if (update_aux_source)
+ dev_dbg(dev, "[PLANE:%d:%s] bypass aux prefetch\n",
+ plane->base.id, plane->name);
+ else
+ dev_dbg(dev, "[PLANE:%d:%s] bypass prefetch\n",
+ plane->base.id, plane->name);
+ }
+
+ layerblend_pixengcfg_dynamic_prim_sel(lb, stage);
+ layerblend_pixengcfg_dynamic_sec_sel(lb, source);
+ layerblend_control(lb, LB_BLEND);
+ layerblend_blendcontrol(lb, need_hscaler || need_vscaler);
+ layerblend_pixengcfg_clken(lb, CLKEN__AUTOMATIC);
+ layerblend_position(lb, layer_x, dpstate->layer_y);
+
+ if (plane->type == DRM_PLANE_TYPE_PRIMARY) {
+ unsigned int base_w, base_x;
+
+ cf = res->cf[stream_id];
+
+ if (crtc_use_pc) {
+ if (update_aux_source || !dpstate->left_crtc_w) {
+ base_w = dpstate->right_base_w;
+ base_x = dpstate->right_base_x;
+ } else {
+ base_w = dpstate->left_base_w;
+ base_x = dpstate->left_base_x;
+ }
+
+ if (!dpstate->left_crtc_w || !dpstate->right_crtc_w) {
+ aux_cf = dpu_aux_cf_peek(cf);
+ aux_fg = dpu_aux_fg_peek(fg);
+
+ constframe_framedimensions_copy_prim(aux_cf);
+ constframe_constantcolor(aux_cf, 0, 0, 0, 0);
+
+ framegen_sacfg(aux_fg, 0, 0);
+ }
+ } else {
+ base_w = dpstate->base_w;
+ base_x = dpstate->base_x;
+ }
+
+ constframe_framedimensions(cf, base_w, dpstate->base_h);
+ constframe_constantcolor(cf, 0, 0, 0, 0);
+
+ framegen_sacfg(fg, base_x, dpstate->base_y);
+ }
+
+ if (crtc_use_pc) {
+ if ((!stream_id && dpstate->is_left_top) ||
+ (stream_id && dpstate->is_right_top)) {
+ ed = res->ed[stream_id];
+ extdst_pixengcfg_src_sel(ed, (extdst_src_sel_t)blend);
+ }
+ } else {
+ if (dpstate->is_top) {
+ ed = res->ed[stream_id];
+ extdst_pixengcfg_src_sel(ed, (extdst_src_sel_t)blend);
+ }
+ }
+
+ if (update_aux_source)
+ dev_dbg(dev, "[PLANE:%d:%s] *aux* source-0x%02x stage-0x%02x blend-0x%02x\n",
+ plane->base.id, plane->name,
+ source, stage, blend);
+ else
+ dev_dbg(dev, "[PLANE:%d:%s] source-0x%02x stage-0x%02x blend-0x%02x\n",
+ plane->base.id, plane->name,
+ source, stage, blend);
+
+ if (dpstate->need_aux_source && !update_aux_source) {
+ update_aux_source = true;
+ goto again;
+ }
+}
+
+static const struct drm_plane_helper_funcs dpu_plane_helper_funcs = {
+ .prepare_fb = drm_fb_cma_prepare_fb,
+ .atomic_check = dpu_plane_atomic_check,
+ .atomic_update = dpu_plane_atomic_update,
+};
+
+struct dpu_plane *dpu_plane_init(struct drm_device *drm,
+ unsigned int possible_crtcs,
+ unsigned int stream_id,
+ struct dpu_plane_grp *grp,
+ enum drm_plane_type type)
+{
+ struct dpu_plane *dpu_plane;
+ struct drm_plane *plane;
+ unsigned int ov_num;
+ int ret;
+
+ dpu_plane = kzalloc(sizeof(*dpu_plane), GFP_KERNEL);
+ if (!dpu_plane)
+ return ERR_PTR(-ENOMEM);
+
+ dpu_plane->stream_id = stream_id;
+ dpu_plane->grp = grp;
+
+ plane = &dpu_plane->base;
+
+ if (type == DRM_PLANE_TYPE_PRIMARY)
+ ret = drm_universal_plane_init(drm, plane, possible_crtcs,
+ &dpu_plane_funcs,
+ dpu_primary_formats,
+ ARRAY_SIZE(dpu_primary_formats),
+ dpu_format_modifiers,
+ type, NULL);
+ else
+ ret = drm_universal_plane_init(drm, plane, possible_crtcs,
+ &dpu_plane_funcs,
+ dpu_overlay_formats,
+ ARRAY_SIZE(dpu_overlay_formats),
+ dpu_format_modifiers,
+ type, NULL);
+ if (ret) {
+ kfree(dpu_plane);
+ return ERR_PTR(ret);
+ }
+
+ drm_plane_helper_add(plane, &dpu_plane_helper_funcs);
+
+ switch (type) {
+ case DRM_PLANE_TYPE_PRIMARY:
+ ret = drm_plane_create_zpos_immutable_property(plane, 0);
+ break;
+ case DRM_PLANE_TYPE_OVERLAY:
+ /* filter out the primary plane */
+ ov_num = grp->hw_plane_num - 1;
+
+ ret = drm_plane_create_zpos_property(plane, 1, 1, ov_num);
+ break;
+ default:
+ ret = -EINVAL;
+ }
+
+ if (ret) {
+ kfree(dpu_plane);
+ return ERR_PTR(ret);
+ }
+
+ return dpu_plane;
+}
diff --git a/drivers/gpu/drm/imx/dpu/dpu-plane.h b/drivers/gpu/drm/imx/dpu/dpu-plane.h
new file mode 100644
index 000000000000..1cc8822e21e3
--- /dev/null
+++ b/drivers/gpu/drm/imx/dpu/dpu-plane.h
@@ -0,0 +1,214 @@
+/*
+ * Copyright 2017-2018 NXP
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#ifndef __DPU_PLANE_H__
+#define __DPU_PLANE_H__
+
+#include <video/dpu.h>
+#include "imx-drm.h"
+
+#define MAX_DPU_PLANE_GRP (MAX_CRTC / 2)
+
+enum dpu_plane_src_type {
+ DPU_PLANE_SRC_FL,
+ DPU_PLANE_SRC_FW,
+ DPU_PLANE_SRC_FD,
+};
+
+struct dpu_plane {
+ struct drm_plane base;
+ struct dpu_plane_grp *grp;
+ struct list_head head;
+ unsigned int stream_id;
+};
+
+struct dpu_plane_state {
+ struct drm_plane_state base;
+ lb_prim_sel_t stage;
+ lb_sec_sel_t source;
+ dpu_block_id_t blend;
+ lb_prim_sel_t aux_stage;
+ lb_sec_sel_t aux_source;
+ dpu_block_id_t aux_blend;
+ unsigned int layer_x;
+ unsigned int layer_y;
+ unsigned int base_x;
+ unsigned int base_y;
+ unsigned int base_w;
+ unsigned int base_h;
+
+ bool is_top;
+ bool use_prefetch;
+ bool use_aux_prefetch;
+ bool need_aux_source;
+
+ /* used when pixel combiner is needed */
+ unsigned int left_layer_x;
+ unsigned int left_base_x;
+ unsigned int left_base_w;
+ unsigned int left_src_w;
+ unsigned int left_crtc_w;
+ unsigned int right_layer_x;
+ unsigned int right_base_x;
+ unsigned int right_base_w;
+ unsigned int right_src_w;
+ unsigned int right_crtc_w;
+
+ bool is_left_top;
+ bool is_right_top;
+};
+
+static const lb_prim_sel_t cf_stages[] = {LB_PRIM_SEL__CONSTFRAME0,
+ LB_PRIM_SEL__CONSTFRAME1};
+static const lb_prim_sel_t stages[] = {LB_PRIM_SEL__LAYERBLEND0,
+ LB_PRIM_SEL__LAYERBLEND1,
+ LB_PRIM_SEL__LAYERBLEND2,
+ LB_PRIM_SEL__LAYERBLEND3,
+ LB_PRIM_SEL__LAYERBLEND4,
+ LB_PRIM_SEL__LAYERBLEND5};
+/* FIXME: Correct the source entries for subsidiary layers. */
+static const lb_sec_sel_t sources[] = {LB_SEC_SEL__FETCHLAYER0,
+ LB_SEC_SEL__FETCHLAYER1,
+ LB_SEC_SEL__FETCHWARP2,
+ LB_SEC_SEL__FETCHDECODE0,
+ LB_SEC_SEL__FETCHDECODE1,
+ LB_SEC_SEL__FETCHDECODE2,
+ LB_SEC_SEL__FETCHDECODE3};
+static const dpu_block_id_t blends[] = {ID_LAYERBLEND0, ID_LAYERBLEND1,
+ ID_LAYERBLEND2, ID_LAYERBLEND3,
+ ID_LAYERBLEND4, ID_LAYERBLEND5};
+
+static inline struct dpu_plane *to_dpu_plane(struct drm_plane *plane)
+{
+ return container_of(plane, struct dpu_plane, base);
+}
+
+static inline struct dpu_plane_state *
+to_dpu_plane_state(struct drm_plane_state *plane_state)
+{
+ return container_of(plane_state, struct dpu_plane_state, base);
+}
+
+static inline int source_to_type(lb_sec_sel_t source)
+{
+ switch (source) {
+ case LB_SEC_SEL__FETCHLAYER0:
+ case LB_SEC_SEL__FETCHLAYER1:
+ return DPU_PLANE_SRC_FL;
+ case LB_SEC_SEL__FETCHWARP2:
+ return DPU_PLANE_SRC_FW;
+ case LB_SEC_SEL__FETCHDECODE0:
+ case LB_SEC_SEL__FETCHDECODE1:
+ case LB_SEC_SEL__FETCHDECODE2:
+ case LB_SEC_SEL__FETCHDECODE3:
+ return DPU_PLANE_SRC_FD;
+ default:
+ break;
+ }
+
+ WARN_ON(1);
+ return -EINVAL;
+}
+
+static inline int source_to_id(lb_sec_sel_t source)
+{
+ int i, offset = 0;
+ int type = source_to_type(source);
+
+ for (i = 0; i < ARRAY_SIZE(sources); i++) {
+ if (source != sources[i])
+ continue;
+
+ /* FetchLayer */
+ if (type == DPU_PLANE_SRC_FL)
+ return i;
+
+ /* FetchWarp or FetchDecode */
+ while (offset < ARRAY_SIZE(sources)) {
+ if (source_to_type(sources[offset]) == type)
+ break;
+ offset++;
+ }
+ return i - offset;
+ }
+
+ WARN_ON(1);
+ return -EINVAL;
+}
+
+static inline struct dpu_fetchunit *
+source_to_fu(struct dpu_plane_res *res, lb_sec_sel_t source)
+{
+ int fu_type = source_to_type(source);
+ int fu_id = source_to_id(source);
+
+ if (fu_type < 0 || fu_id < 0)
+ return NULL;
+
+ switch (fu_type) {
+ case DPU_PLANE_SRC_FD:
+ return res->fd[fu_id];
+ case DPU_PLANE_SRC_FL:
+ return res->fl[fu_id];
+ case DPU_PLANE_SRC_FW:
+ return res->fw[fu_id];
+ }
+
+ return NULL;
+}
+
+static inline struct dpu_fetchunit *
+dpstate_to_fu(struct dpu_plane_state *dpstate)
+{
+ struct drm_plane *plane = dpstate->base.plane;
+ struct dpu_plane *dplane = to_dpu_plane(plane);
+ struct dpu_plane_res *res = &dplane->grp->res;
+
+ return source_to_fu(res, dpstate->source);
+}
+
+static inline int blend_to_id(dpu_block_id_t blend)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(blends); i++) {
+ if (blend == blends[i])
+ return i;
+ }
+
+ WARN_ON(1);
+ return -EINVAL;
+}
+
+static inline bool drm_format_is_yuv(uint32_t format)
+{
+ switch (format) {
+ case DRM_FORMAT_YUYV:
+ case DRM_FORMAT_UYVY:
+ case DRM_FORMAT_NV12:
+ case DRM_FORMAT_NV21:
+ return true;
+ default:
+ break;
+ }
+
+ return false;
+}
+
+struct dpu_plane *dpu_plane_init(struct drm_device *drm,
+ unsigned int possible_crtcs,
+ unsigned int stream_id,
+ struct dpu_plane_grp *grp,
+ enum drm_plane_type type);
+#endif
diff --git a/drivers/gpu/drm/imx/hdp/API_AFE_mcu1_dp.c b/drivers/gpu/drm/imx/hdp/API_AFE_mcu1_dp.c
new file mode 100644
index 000000000000..450d31f68790
--- /dev/null
+++ b/drivers/gpu/drm/imx/hdp/API_AFE_mcu1_dp.c
@@ -0,0 +1,434 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2016-2017 Cadence Design Systems, Inc.
+ * All rights reserved worldwide.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 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.
+ *
+ * Copyright 2017-2018 NXP
+ *
+ ******************************************************************************
+ *
+ * API_AFE_mcu1_dp.c
+ *
+ ******************************************************************************
+ */
+
+#include <linux/delay.h>
+#include "API_AFE_mcu1_dp.h"
+#include "../../../../mxc/hdp/all.h"
+
+/* values of TX_TXCC_MGNFS_MULT_000 register for [voltage_swing][pre_emphasis]
+ * 0xFF means, that the combination is forbidden.
+static u16 mgnfsValues[4][4] = {{0x2B, 0x19, 0x0E, 0x02},
+ {0x21, 0x10, 0x01, 0xFF},
+ {0x18, 0x02, 0xFF, 0xFF},
+ {0x04, 0xFF, 0xFF, 0xFF}};
+
+* values of TX_TXCC_CPOST_MULT_00 register for [voltage_swing][pre_emphasis]
+* 0xFF means, that the combination is forbidden.
+static u16 cpostValues[4][4] = {{0x00, 0x14, 0x21, 0x29},
+ {0x00, 0x15, 0x20, 0xFF},
+ {0x00, 0x15, 0xFF, 0xFF},
+ {0x00, 0xFF, 0xFF, 0xFF}};
+*/
+
+static void AFE_WriteReg(state_struct *state, ENUM_AFE_LINK_RATE link_rate,
+ unsigned int addr,
+ unsigned int val1_6,
+ unsigned int val2_1,
+ unsigned int val2_4,
+ unsigned int val2_7,
+ unsigned int val3_2,
+ unsigned int val4_3,
+ unsigned int val5_4)
+{
+ switch (link_rate) {
+ case AFE_LINK_RATE_1_6:
+ Afe_write(state, addr, val1_6);
+ break;
+ case AFE_LINK_RATE_2_1:
+ Afe_write(state, addr, val2_1);
+ break;
+ case AFE_LINK_RATE_2_4:
+ Afe_write(state, addr, val2_4);
+ break;
+ case AFE_LINK_RATE_2_7:
+ Afe_write(state, addr, val2_7);
+ break;
+ case AFE_LINK_RATE_3_2:
+ Afe_write(state, addr, val3_2);
+ break;
+ case AFE_LINK_RATE_4_3:
+ Afe_write(state, addr, val4_3);
+ break;
+ case AFE_LINK_RATE_5_4:
+ Afe_write(state, addr, val5_4);
+ break;
+ case AFE_LINK_RATE_8_1: /* Not used in MCU1 */
+ default:
+ pr_err("Warning. Unsupported Link Rate!\n");
+ break;
+ }
+}
+
+static void phy_cfg_24mhz(state_struct *state, int num_lanes)
+{
+ int k;
+
+ for (k = 0; k < num_lanes; k++) {
+ Afe_write(state, XCVR_DIAG_LANE_FCM_EN_MGN_TMR | (k << 9), 0x0090);
+ Afe_write(state, TX_RCVDET_EN_TMR | (k << 9), 0x0960);
+ Afe_write(state, TX_RCVDET_ST_TMR | (k << 9), 0x0030);
+ }
+}
+
+/* Valid for 24 MHz only */
+static void phy_cfg_dp_pll0(state_struct *state,
+ int num_lanes,
+ ENUM_AFE_LINK_RATE link_rate)
+{
+ int k;
+ volatile u16 rdata;
+
+ rdata = Afe_read(state, PHY_HDP_CLK_CTL);
+ rdata = rdata & 0x00FF;
+
+ switch (link_rate) {
+ case AFE_LINK_RATE_1_6:
+ case AFE_LINK_RATE_2_1:
+ case AFE_LINK_RATE_2_4:
+ case AFE_LINK_RATE_2_7:
+ rdata = rdata | 0x2400;
+ break;
+
+ case AFE_LINK_RATE_3_2:
+ case AFE_LINK_RATE_4_3:
+ case AFE_LINK_RATE_5_4:
+ rdata = rdata | 0x1200;
+ break;
+
+ case AFE_LINK_RATE_8_1: /* nNot used in MCU1 */
+ default:
+ pr_err("Warning. Unsupported Link Rate!\n");
+ break;
+ }
+
+ Afe_write(state, PHY_HDP_CLK_CTL, rdata);
+ rdata = Afe_read(state, CMN_DIAG_HSCLK_SEL);
+ rdata = rdata & 0xFFCC;
+ switch (link_rate) {
+ case AFE_LINK_RATE_1_6:
+ case AFE_LINK_RATE_2_1:
+ case AFE_LINK_RATE_2_4:
+ case AFE_LINK_RATE_2_7:
+ rdata = rdata | 0x0011;
+ break;
+
+ case AFE_LINK_RATE_3_2:
+ case AFE_LINK_RATE_4_3:
+ case AFE_LINK_RATE_5_4:
+ rdata = rdata | 0x0000;
+ break;
+
+ case AFE_LINK_RATE_8_1: /* Not used in MCU1 */
+ default:
+ pr_err("Warning. Unsupported Link Rate!\n");
+ break;
+ }
+ Afe_write(state, CMN_DIAG_HSCLK_SEL, rdata);
+ for (k = 0; k < num_lanes; k = k + 1) {
+ rdata = Afe_read(state, (XCVR_DIAG_HSCLK_SEL | (k << 9)));
+ rdata = rdata & 0xCFFF;
+ switch (link_rate) {
+ case AFE_LINK_RATE_1_6:
+ case AFE_LINK_RATE_2_1:
+ case AFE_LINK_RATE_2_4:
+ case AFE_LINK_RATE_2_7:
+ rdata = rdata | 0x1000;
+ break;
+
+ case AFE_LINK_RATE_3_2:
+ case AFE_LINK_RATE_4_3:
+ case AFE_LINK_RATE_5_4:
+ rdata = rdata | 0x0000;
+ break;
+
+ case AFE_LINK_RATE_8_1: /* Not used in MCU1 */
+ default:
+ pr_err("Warning. Unsupported Link Rate!\n");
+ break;
+ }
+ Afe_write(state, (XCVR_DIAG_HSCLK_SEL | (k << 9)), rdata);
+ }
+ Afe_write(state, CMN_PLL0_VCOCAL_INIT_TMR, 0x00F0);
+ Afe_write(state, CMN_PLL0_VCOCAL_ITER_TMR, 0x0018);
+ AFE_WriteReg(state, link_rate, CMN_PLL0_VCOCAL_START, 0x3061, 0x3092, 0x30B3, 0x30D0, 0x3061, 0x3092, 0x30D0);
+ AFE_WriteReg(state, link_rate, CMN_PLL0_INTDIV, 0x0086, 0x00B3, 0x00CA, 0x00E0, 0x0086, 0x00B3, 0x00E0);
+ AFE_WriteReg(state, link_rate, CMN_PLL0_FRACDIV, 0xF917, 0xF6C7, 0x75A1, 0xF479, 0xF917, 0xF6C7, 0xF479);
+ AFE_WriteReg(state, link_rate, CMN_PLL0_HIGH_THR, 0x0022, 0x002D, 0x0033, 0x0038, 0x0022, 0x002D, 0x0038);
+#ifdef SSC_ON_INIT
+ AFE_WriteReg(state, link_rate, CMN_PLL0_SS_CTRL1, 0x0140, 0x01AB, 0x01E0, 0x0204, 0x0140, 0x01AB, 0x0204);
+ Afe_write(state, CMN_PLL0_SS_CTRL2, 0x7F03);
+#endif
+ Afe_write(state, CMN_PLL0_DSM_DIAG, 0x0020);
+ AFE_WriteReg(state, link_rate, CMN_PLLSM0_USER_DEF_CTRL, 0x0000, 0x1000, 0x1000, 0x1000, 0x0000, 0x1000, 0x1000);
+ Afe_write(state, CMN_DIAG_PLL0_OVRD, 0x0000);
+ Afe_write(state, CMN_DIAG_PLL0_FBH_OVRD, 0x0000);
+ Afe_write(state, CMN_DIAG_PLL0_FBL_OVRD, 0x0000);
+ AFE_WriteReg(state, link_rate, CMN_DIAG_PLL0_V2I_TUNE, 0x0006, 0x0007, 0x0007, 0x0007, 0x0006, 0x0007, 0x0007);
+ AFE_WriteReg(state, link_rate, CMN_DIAG_PLL0_CP_TUNE, 0x0026, 0x0029, 0x0029, 0x0029, 0x0026, 0x0029, 0x0029);
+ Afe_write(state, CMN_DIAG_PLL0_LF_PROG, 0x0008);
+ Afe_write(state, CMN_DIAG_PLL0_PTATIS_TUNE1, 0x008C);
+ Afe_write(state, CMN_DIAG_PLL0_PTATIS_TUNE2, 0x002E);
+ for (k = 0; k < num_lanes; k = k + 1) {
+ rdata = Afe_read(state, (XCVR_DIAG_PLLDRC_CTRL | (k << 9)));
+ rdata = rdata & 0x8FFF;
+ switch (link_rate) {
+ case AFE_LINK_RATE_1_6:
+ case AFE_LINK_RATE_2_1:
+ case AFE_LINK_RATE_2_4:
+ case AFE_LINK_RATE_2_7:
+ rdata = rdata | 0x2000;
+ break;
+
+ case AFE_LINK_RATE_3_2:
+ case AFE_LINK_RATE_4_3:
+ case AFE_LINK_RATE_5_4:
+ rdata = rdata | 0x1000;
+ break;
+
+ case AFE_LINK_RATE_8_1: /* Not used in MCU1 */
+ default:
+ pr_err("Warning. Unsupported Link Rate!\n");
+ break;
+ }
+ Afe_write(state, (XCVR_DIAG_PLLDRC_CTRL | (k << 9)), rdata);
+ }
+}
+
+static void phy_cfg_dp_ln(state_struct *state, int num_lanes)
+{
+ int k;
+ u16 rdata;
+
+ for (k = 0; k < num_lanes; k = k + 1) {
+ Afe_write(state, (XCVR_PSM_RCTRL | (k << 9)), 0xBEFC);
+ if (state->edp == 0) {
+ Afe_write(state, (TX_PSC_A0 | (k << 9)), 0x6799);
+ Afe_write(state, (TX_PSC_A1 | (k << 9)), 0x6798);
+ Afe_write(state, (TX_PSC_A2 | (k << 9)), 0x0098);
+ Afe_write(state, (TX_PSC_A3 | (k << 9)), 0x0098);
+ } else {
+ Afe_write(state, (TX_PSC_A0 | (k << 9)), 0x279B);
+ Afe_write(state, (TX_PSC_A1 | (k << 9)), 0x2798);
+ Afe_write(state, (TX_PSC_A2 | (k << 9)), 0x0098);
+ Afe_write(state, (TX_PSC_A3 | (k << 9)), 0x0098);
+ rdata = Afe_read(state, TX_DIAG_TX_DRV | (k << 9));
+ rdata &= 0x0600; /* keep bits related to programmable boost */
+ rdata |= 0x00C0;
+ Afe_write(state, (TX_DIAG_TX_DRV | (k << 9)), rdata);
+ }
+ }
+}
+
+static u16 aux_cal_cfg(state_struct *state, u16 prev_calib_code)
+{
+ u16 txpu_calib_code;
+ u16 txpd_calib_code;
+ u16 txpu_adj_calib_code;
+ u16 txpd_adj_calib_code;
+ u16 new_calib_code;
+ u16 rdata;
+
+ txpu_calib_code = Afe_read(state, CMN_TXPUCAL_CTRL);
+ txpd_calib_code = Afe_read(state, CMN_TXPDCAL_CTRL);
+ txpu_adj_calib_code = Afe_read(state, CMN_TXPU_ADJ_CTRL);
+ txpd_adj_calib_code = Afe_read(state, CMN_TXPD_ADJ_CTRL);
+
+ new_calib_code = ((txpu_calib_code + txpd_calib_code) / 2)
+ + txpu_adj_calib_code + txpd_adj_calib_code;
+
+ if (new_calib_code != prev_calib_code) {
+ rdata = Afe_read(state, TX_ANA_CTRL_REG_1);
+ rdata &= 0xDFFF;
+ Afe_write(state, TX_ANA_CTRL_REG_1, rdata);
+ Afe_write(state, TX_DIG_CTRL_REG_2, new_calib_code);
+ udelay(10000);
+ rdata |= 0x2000;
+ Afe_write(state, TX_ANA_CTRL_REG_1, rdata);
+ udelay(150);
+ }
+
+ return new_calib_code;
+}
+
+static void aux_cfg(state_struct *state)
+{
+ volatile u16 rdata;
+
+ Afe_write(state, TX_DIG_CTRL_REG_2, 36);
+
+ Afe_write(state, TX_ANA_CTRL_REG_2, 0x0100);
+ udelay(150);
+ Afe_write(state, TX_ANA_CTRL_REG_2, 0x0300);
+ udelay(150);
+ Afe_write(state, TX_ANA_CTRL_REG_3, 0x0000);
+ udelay(150);
+ Afe_write(state, TX_ANA_CTRL_REG_1, 0x2008);
+ udelay(150);
+ Afe_write(state, TX_ANA_CTRL_REG_1, 0x2018);
+ udelay(150);
+ Afe_write(state, TX_ANA_CTRL_REG_1, 0xA018);
+ udelay(150);
+ Afe_write(state, TX_ANA_CTRL_REG_2, 0x030C);
+ udelay(150);
+ Afe_write(state, TX_ANA_CTRL_REG_5, 0x0000);
+ udelay(150);
+ Afe_write(state, TX_ANA_CTRL_REG_4, 0x1001);
+ udelay(150);
+ Afe_write(state, TX_ANA_CTRL_REG_1, 0xA098);
+ udelay(5000);
+ Afe_write(state, TX_ANA_CTRL_REG_1, 0xA198);
+ udelay(5000);
+ Afe_write(state, TX_ANA_CTRL_REG_2, 0x030D);
+ udelay(5000);
+ Afe_write(state, TX_ANA_CTRL_REG_2, 0x030F);
+ udelay(5000);
+
+ pr_info("TX_ANA_CTRL_REG_1 %x)\n", rdata);
+ rdata = Afe_read(state, TX_ANA_CTRL_REG_2);
+ pr_info("TX_ANA_CTRL_REG_2 %x)\n", rdata);
+ rdata = Afe_read(state, TX_ANA_CTRL_REG_3);
+ pr_info("TX_ANA_CTRL_REG_3 %x)\n", rdata);
+ rdata = Afe_read(state, TX_ANA_CTRL_REG_4);
+ pr_info("TX_ANA_CTRL_REG_4 %x)\n", rdata);
+ rdata = Afe_read(state, TX_ANA_CTRL_REG_5);
+ pr_info("TX_ANA_CTRL_REG_5 %x)\n", rdata);
+}
+
+void AFE_init(state_struct *state, int num_lanes, ENUM_AFE_LINK_RATE link_rate)
+{
+ volatile u16 val;
+
+ if (AFE_check_rate_supported(link_rate) == 0) {
+ pr_info
+ ("AFE_init() *E: Selected link rate not supported: 0x%x\n",
+ link_rate);
+ return;
+ }
+ val = Afe_read(state, PHY_PMA_CMN_CTRL1);
+ val = val & 0xFFF7;
+ val = val | 0x0008;
+ Afe_write(state, PHY_PMA_CMN_CTRL1, val);
+
+ Afe_write(state, CMN_DIAG_PLL0_TEST_MODE, 0x0022);
+ Afe_write(state, CMN_PSM_CLK_CTRL, 0x0016);
+
+ phy_cfg_24mhz(state, num_lanes);
+
+ phy_cfg_dp_pll0(state, num_lanes, link_rate);
+
+ val = Afe_read(state, PHY_PMA_CMN_CTRL1);
+ val = val & 0xFF8F;
+ val = val | 0x0030;
+ Afe_write(state, PHY_PMA_CMN_CTRL1, val);
+
+ if (state->edp != 0)
+ Afe_write(state, CMN_DIAG_CAL_CTRL, 0x0001);
+
+ phy_cfg_dp_ln(state, num_lanes);
+
+ /* Configure PHY in A2 Mode */
+ Afe_write(state, PHY_HDP_MODE_CTRL, 0x0004);
+}
+
+void AFE_power(state_struct *state, int num_lanes,
+ ENUM_AFE_LINK_RATE link_rate)
+{
+ static u16 prev_calib_code;
+
+ volatile u16 val;
+ if (AFE_check_rate_supported(link_rate) == 0) {
+ pr_info
+ ("AFE_power() *E: Selected link rate not supported: 0x%x\n",
+ link_rate);
+ return;
+ }
+
+ Afe_write(state, TX_DIAG_ACYA_0, 1);
+ Afe_write(state, TX_DIAG_ACYA_1, 1);
+ Afe_write(state, TX_DIAG_ACYA_2, 1);
+ Afe_write(state, TX_DIAG_ACYA_3, 1);
+
+ Afe_write(state, TXDA_CYA_AUXDA_CYA, 1);
+
+ /* Wait for A2 ACK (PHY_HDP_MODE_CTL [6] = 1’b1) */
+ do {
+ val = Afe_read(state, PHY_HDP_MODE_CTRL);
+ val = val >> 6;
+ } while ((val & 1) == 0);
+
+ /* to check if PLL has locked (bit 6) */
+ val = Afe_read(state, PHY_PMA_CMN_CTRL2);
+ val = val >> 6;
+
+ if ((val & 1) == 0) {
+ pr_err("ERROR: PLL is not locked\n");
+ } else {
+ pr_info("PHY_PMA_CMN_CTRL2 = %x\n", val);
+ }
+
+ /* to check if cmn_ready is asserted (bit 0) */
+ val = Afe_read(state, PHY_PMA_CMN_CTRL1);
+
+ if ((val & 1) == 0) {
+ pr_err("ERROR: cmn_ready is not asserted\n");
+ } else {
+ pr_info("PHY_PMA_CMN_CTRL1 = %x\n", val);
+ }
+
+ /* Configure PHY in A0 mode (PHY must be in the A0 power state in order to transmit data) */
+ Afe_write(state, PHY_HDP_MODE_CTRL, 0x0101);
+
+ /* Wait for A2 ACK (PHY_HDP_MODE_CTL [4] = 1’b1) */
+ do {
+ val = Afe_read(state, PHY_HDP_MODE_CTRL);
+ val = val >> 4;
+ } while ((val & 1) == 0);
+
+ prev_calib_code = aux_cal_cfg(state, prev_calib_code);
+
+ aux_cfg(state);
+
+}
diff --git a/drivers/gpu/drm/imx/hdp/API_AFE_mcu1_dp.h b/drivers/gpu/drm/imx/hdp/API_AFE_mcu1_dp.h
new file mode 100644
index 000000000000..af71347676ae
--- /dev/null
+++ b/drivers/gpu/drm/imx/hdp/API_AFE_mcu1_dp.h
@@ -0,0 +1,168 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2016-2017 Cadence Design Systems, Inc.
+ * All rights reserved worldwide.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 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.
+ *
+ * Copyright 2017-2018 NXP
+ *
+ ******************************************************************************
+ *
+ * API_AFE_mcu1_dp.h
+ *
+ ******************************************************************************
+ */
+
+#ifndef API_AFE_MCU1_DP_H
+# define API_AFE_MCU1_DP_H
+
+#define PHY_PMA_CMN_CTRL1 0xC800
+#define PHY_PMA_CMN_CTRL2 0xC801
+#define XCVR_DIAG_LANE_FCM_EN_MGN_TMR 0x40F2
+#define XCVR_DIAG_LANE_FCM_EN_MGN_TMR_0 0x40F2
+#define XCVR_DIAG_LANE_FCM_EN_MGN_TMR_1 0x42F2
+#define XCVR_DIAG_LANE_FCM_EN_MGN_TMR_2 0x44F2
+#define XCVR_DIAG_LANE_FCM_EN_MGN_TMR_3 0x46F2
+#define TX_RCVDET_EN_TMR 0x4122
+#define TX_RCVDET_EN_TMR_0 0x4122
+#define TX_RCVDET_EN_TMR_1 0x4322
+#define TX_RCVDET_EN_TMR_2 0x4522
+#define TX_RCVDET_EN_TMR_3 0x4722
+#define TX_RCVDET_ST_TMR 0x4123
+#define TX_RCVDET_ST_TMR_0 0x4123
+#define TX_RCVDET_ST_TMR_1 0x4323
+#define TX_RCVDET_ST_TMR_2 0x4523
+#define TX_RCVDET_ST_TMR_3 0x4723
+#define PHY_HDP_CLK_CTL 0xC009
+#define CMN_DIAG_HSCLK_SEL 0x01E0
+#define XCVR_DIAG_HSCLK_SEL 0x40E1
+#define XCVR_DIAG_HSCLK_SEL_0 0x40E1
+#define XCVR_DIAG_HSCLK_SEL_1 0x42E1
+#define XCVR_DIAG_HSCLK_SEL_2 0x44E1
+#define XCVR_DIAG_HSCLK_SEL_3 0x46E1
+#define CMN_PLL0_VCOCAL_START 0x0081
+#define CMN_PLLSM0_USER_DEF_CTRL 0x002F
+#define CMN_DIAG_PLL0_V2I_TUNE 0x01C5
+#define CMN_DIAG_PLL0_PTATIS_TUNE1 0x01C8
+#define CMN_DIAG_PLL0_PTATIS_TUNE2 0x01C9
+#define CMN_DIAG_PLL0_CP_TUNE 0x01C6
+#define CMN_DIAG_PER_CAL_ADJ 0x01EC
+#define CMN_DIAG_CAL_CTRL 0x01ED
+#define CMN_DIAG_PLL0_LF_PROG 0x01C7
+#define CMN_PLL0_VCOCAL_INIT_TMR 0x0084
+#define CMN_PLL0_VCOCAL_ITER_TMR 0x0085
+#define CMN_PLL0_INTDIV 0x0094
+#define CMN_PLL0_FRACDIV 0x0095
+#define CMN_PLL0_HIGH_THR 0x0096
+#define CMN_PLL0_SS_CTRL1 0x0098
+#define CMN_PLL0_SS_CTRL2 0x0099
+#define CMN_PLL0_DSM_DIAG 0x0097
+#define CMN_DIAG_PLL0_OVRD 0x01C2
+#define CMN_DIAG_PLL0_FBH_OVRD 0x01C0
+#define CMN_DIAG_PLL0_FBL_OVRD 0x01C1
+#define XCVR_DIAG_PLLDRC_CTRL 0x40E0
+#define XCVR_DIAG_PLLDRC_CTRL_0 0x40E0
+#define XCVR_DIAG_PLLDRC_CTRL_1 0x42E0
+#define XCVR_DIAG_PLLDRC_CTRL_2 0x44E0
+#define XCVR_DIAG_PLLDRC_CTRL_3 0x46E0
+#define CMN_DIAG_PLL0_TEST_MODE 0x01C4
+#define PHY_HDP_MODE_CTRL 0xC008
+#define XCVR_PSM_RCTRL 0x4001
+#define XCVR_PSM_RCTRL_0 0x4001
+#define XCVR_PSM_RCTRL_1 0x4201
+#define XCVR_PSM_RCTRL_2 0x4401
+#define XCVR_PSM_RCTRL_3 0x4601
+#define TX_PSC_A0 0x4100
+#define TX_PSC_A0_0 0x4100
+#define TX_PSC_A0_1 0x4300
+#define TX_PSC_A0_2 0x4500
+#define TX_PSC_A0_3 0x4700
+#define TX_PSC_A1 0x4101
+#define TX_PSC_A1_0 0x4101
+#define TX_PSC_A1_1 0x4301
+#define TX_PSC_A1_2 0x4501
+#define TX_PSC_A1_3 0x4701
+#define TX_PSC_A2 0x4102
+#define TX_PSC_A2_0 0x4102
+#define TX_PSC_A2_1 0x4302
+#define TX_PSC_A2_2 0x4502
+#define TX_PSC_A2_3 0x4702
+#define TX_PSC_A3 0x4103
+#define TX_PSC_A3_0 0x4103
+#define TX_PSC_A3_1 0x4303
+#define TX_PSC_A3_2 0x4503
+#define TX_PSC_A3_3 0x4703
+#define TX_DIAG_TX_DRV 0x41E1
+#define TX_DIAG_TX_DRV_0 0x41E1
+#define TX_DIAG_TX_DRV_1 0x43E1
+#define TX_DIAG_TX_DRV_2 0x45E1
+#define TX_DIAG_TX_DRV_3 0x47E1
+#define PHY_HDP_MODE_CTRL 0xC008
+#define TX_DIAG_ACYA_0 0x41ff
+#define TX_DIAG_ACYA_1 0x43ff
+#define TX_DIAG_ACYA_2 0x45ff
+#define TX_DIAG_ACYA_3 0x47ff
+
+#define TX_TXCC_MGNFS_MULT_000_0 0x4050
+#define TX_TXCC_MGNFS_MULT_000_1 0x4250
+#define TX_TXCC_MGNFS_MULT_000_2 0x4450
+#define TX_TXCC_MGNFS_MULT_000_3 0x4650
+
+#define TX_TXCC_CPOST_MULT_00_0 0x404C
+#define TX_TXCC_CPOST_MULT_00_1 0x424C
+#define TX_TXCC_CPOST_MULT_00_2 0x444C
+#define TX_TXCC_CPOST_MULT_00_3 0x464C
+
+#define TX_ANA_CTRL_REG_1 0x5020
+#define TX_ANA_CTRL_REG_2 0x5021
+#define TX_ANA_CTRL_REG_3 0x5026
+#define TX_ANA_CTRL_REG_4 0x5027
+#define TX_ANA_CTRL_REG_5 0x5029
+
+#define TX_DIG_CTRL_REG_2 0x5024
+#define TX_DIG_CTRL_REG_1 0x5023
+#define TXDA_CYA_AUXDA_CYA 0x5025
+#define CMN_TXPUCAL_CTRL 0x00E0
+#define CMN_TXPDCAL_CTRL 0x00F0
+#define CMN_TXPU_ADJ_CTRL 0x0108
+#define CMN_TXPD_ADJ_CTRL 0x010c
+#define TXDA_COEFF_CALC 0x5022
+#define CMN_PSM_CLK_CTRL 0x0061
+
+#define PHY_HDP_TX_CTL_L0 0xC408
+#define PHY_HDP_TX_CTL_L1 0xC448
+#define PHY_HDP_TX_CTL_L2 0xC488
+#define PHY_HDP_TX_CTL_L3 0xC4C8
+
+#endif /*API_AFE_MCU1_DP_H*/
diff --git a/drivers/gpu/drm/imx/hdp/API_AFE_mcu2_dp.c b/drivers/gpu/drm/imx/hdp/API_AFE_mcu2_dp.c
new file mode 100644
index 000000000000..08904cce1262
--- /dev/null
+++ b/drivers/gpu/drm/imx/hdp/API_AFE_mcu2_dp.c
@@ -0,0 +1,711 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2016-2017 Cadence Design Systems, Inc.
+ * All rights reserved worldwide.
+ *
+ * Copyright 2018 NXP
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 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.
+ *
+ ******************************************************************************
+ *
+ * API_AFE_mcu2_dp.c
+ *
+ ******************************************************************************
+ */
+#include <linux/delay.h>
+#include "API_AFE_mcu2_dp.h"
+#include "../../../../mxc/hdp/all.h"
+
+/* values of TX_TXCC_MGNFS_MULT_000 register for [voltage_swing][pre_emphasis]
+ * 0xFF means, that the combination is forbidden.
+static u16 mgnfsValues[4][4] = {{0x2B, 0x19, 0x0E, 0x02},
+ {0x21, 0x10, 0x01, 0xFF},
+ {0x18, 0x02, 0xFF, 0xFF},
+ {0x04, 0xFF, 0xFF, 0xFF}};
+
+* values of TX_TXCC_CPOST_MULT_00 register for [voltage_swing][pre_emphasis]
+* 0xFF means, that the combination is forbidden.
+static u16 cpostValues[4][4] = {{0x00, 0x14, 0x21, 0x29},
+ {0x00, 0x15, 0x20, 0xFF},
+ {0x00, 0x15, 0xFF, 0xFF},
+ {0x00, 0xFF, 0xFF, 0xFF}};
+*/
+
+static void afe_write_reg(state_struct *state,
+ ENUM_AFE_LINK_RATE link_rate,
+ unsigned int addr,
+ unsigned int val1_6,
+ unsigned int val2_1,
+ unsigned int val2_4,
+ unsigned int val2_7,
+ unsigned int val3_2,
+ unsigned int val4_3,
+ unsigned int val5_4)
+{
+ switch (link_rate) {
+ case AFE_LINK_RATE_1_6:
+ Afe_write(state, addr, val1_6); break;
+ case AFE_LINK_RATE_2_1:
+ Afe_write(state, addr, val2_1); break;
+ case AFE_LINK_RATE_2_4:
+ Afe_write(state, addr, val2_4); break;
+ case AFE_LINK_RATE_2_7:
+ Afe_write(state, addr, val2_7); break;
+ case AFE_LINK_RATE_3_2:
+ Afe_write(state, addr, val3_2); break;
+ case AFE_LINK_RATE_4_3:
+ Afe_write(state, addr, val4_3); break;
+ case AFE_LINK_RATE_5_4:
+ Afe_write(state, addr, val5_4); break;
+ default:
+ break;
+ }
+}
+
+static void phy_cfg_24mhz(state_struct *state, int num_lanes)
+{
+ int k;
+
+ for (k = 0; k < num_lanes; k++) {
+ /* Afe_write (XCVR_DIAG_LANE_FCM_EN_TO | (k << 9), 0x01e0); */
+ Afe_write(state, XCVR_DIAG_LANE_FCM_EN_MGN_TMR | (k << 9),
+ 0x0090);
+ Afe_write(state, TX_RCVDET_EN_TMR | (k << 9), 0x0960);
+ Afe_write(state, TX_RCVDET_ST_TMR | (k << 9), 0x0030);
+ }
+}
+
+static void phy_cfg_27mhz(state_struct *state, int num_lanes)
+{
+ int k;
+
+ Afe_write(state, CMN_SSM_BIAS_TMR, 0x0087);
+ Afe_write(state, CMN_PLLSM0_PLLEN_TMR, 0x001B);
+ Afe_write(state, CMN_PLLSM0_PLLPRE_TMR, 0x0036);
+ Afe_write(state, CMN_PLLSM0_PLLVREF_TMR, 0x001B);
+ Afe_write(state, CMN_PLLSM0_PLLLOCK_TMR, 0x006C);
+ Afe_write(state, CMN_ICAL_INIT_TMR, 0x0044);
+ Afe_write(state, CMN_ICAL_ITER_TMR, 0x0006);
+ Afe_write(state, CMN_ICAL_ADJ_INIT_TMR, 0x0022);
+ Afe_write(state, CMN_ICAL_ADJ_ITER_TMR, 0x0006);
+ Afe_write(state, CMN_TXPUCAL_INIT_TMR, 0x0022);
+ Afe_write(state, CMN_TXPUCAL_ITER_TMR, 0x0006);
+ Afe_write(state, CMN_TXPU_ADJ_INIT_TMR, 0x0022);
+ Afe_write(state, CMN_TXPU_ADJ_ITER_TMR, 0x0006);
+ Afe_write(state, CMN_TXPDCAL_INIT_TMR, 0x0022);
+ Afe_write(state, CMN_TXPDCAL_ITER_TMR, 0x0006);
+ Afe_write(state, CMN_TXPD_ADJ_INIT_TMR, 0x0022);
+ Afe_write(state, CMN_TXPD_ADJ_ITER_TMR, 0x0006);
+ Afe_write(state, CMN_RXCAL_INIT_TMR, 0x0022);
+ Afe_write(state, CMN_RXCAL_ITER_TMR, 0x0006);
+ Afe_write(state, CMN_RX_ADJ_INIT_TMR, 0x0022);
+ Afe_write(state, CMN_RX_ADJ_ITER_TMR, 0x0006);
+
+ for (k = 0; k < num_lanes; k++) {
+ Afe_write(state, XCVR_PSM_CAL_TMR | (k << 9), 0x016D);
+ Afe_write(state, XCVR_PSM_A0IN_TMR | (k << 9), 0x016D);
+ Afe_write(state, XCVR_DIAG_LANE_FCM_EN_MGN_TMR | (k << 9),
+ 0x00A2);
+ Afe_write(state, TX_DIAG_BGREF_PREDRV_DELAY | (k << 9),
+ 0x0097);
+ Afe_write(state, TX_RCVDET_EN_TMR | (k << 9), 0x0A8C);
+ Afe_write(state, TX_RCVDET_ST_TMR | (k << 9), 0x0036);
+ }
+}
+
+static void phy_cfg_dp_pll0_24mhz(state_struct *state,
+ int num_lanes,
+ ENUM_AFE_LINK_RATE link_rate)
+{
+ int k;
+ unsigned short rdata;
+
+ rdata = Afe_read(state, PHY_HDP_CLK_CTL);
+ rdata = rdata & 0x00FF;
+ switch (link_rate) {
+ case AFE_LINK_RATE_1_6:
+ case AFE_LINK_RATE_2_1:
+ case AFE_LINK_RATE_2_4:
+ case AFE_LINK_RATE_2_7:
+ rdata = rdata | 0x2400;
+ break;
+ case AFE_LINK_RATE_3_2:
+ case AFE_LINK_RATE_4_3:
+ case AFE_LINK_RATE_5_4:
+ rdata = rdata | 0x1200;
+ break;
+ case AFE_LINK_RATE_8_1: /* Not used in MCU2 */
+ default:
+ pr_info("Warning. Unsupported Link Rate!\n");
+ break;
+ }
+ Afe_write(state, PHY_HDP_CLK_CTL, rdata);
+ rdata = Afe_read(state, CMN_DIAG_HSCLK_SEL);
+ rdata = rdata & 0xFFCC;
+ switch (link_rate) {
+ case AFE_LINK_RATE_1_6:
+ case AFE_LINK_RATE_2_1:
+ case AFE_LINK_RATE_2_4:
+ case AFE_LINK_RATE_2_7:
+ rdata = rdata | 0x0011;
+ break;
+ case AFE_LINK_RATE_3_2:
+ case AFE_LINK_RATE_4_3:
+ case AFE_LINK_RATE_5_4:
+ rdata = rdata | 0x0000;
+ break;
+ default:
+ break;
+ }
+ Afe_write(state, CMN_DIAG_HSCLK_SEL, rdata);
+ for (k = 0; k < num_lanes; k = k + 1) {
+ rdata = Afe_read(state, (XCVR_DIAG_HSCLK_SEL | (k << 9)));
+ rdata = rdata & 0xCFFF;
+ switch (link_rate) {
+ case AFE_LINK_RATE_1_6:
+ case AFE_LINK_RATE_2_1:
+ case AFE_LINK_RATE_2_4:
+ case AFE_LINK_RATE_2_7:
+ rdata = rdata | 0x1000;
+ break;
+ case AFE_LINK_RATE_3_2:
+ case AFE_LINK_RATE_4_3:
+ case AFE_LINK_RATE_5_4:
+ rdata = rdata | 0x0000;
+ break;
+ default:
+ break;
+ }
+ Afe_write(state, (XCVR_DIAG_HSCLK_SEL | (k << 9)), rdata);
+ }
+ /* Gbps 1.62 2.16 2.43 2.7 3.24 4.32 5.4 */
+ Afe_write(state, CMN_PLL0_VCOCAL_INIT_TMR, 0x00F0);
+ Afe_write(state, CMN_PLL0_VCOCAL_ITER_TMR, 0x0018);
+ afe_write_reg(state, link_rate, CMN_PLL0_VCOCAL_START,
+ 0x30B9, 0x3087, 0x3096, 0x30B4, 0x30B9, 0x3087, 0x30B4);
+ afe_write_reg(state, link_rate, CMN_PLL0_INTDIV,
+ 0x0086, 0x00B3, 0x00CA, 0x00E0, 0x0086, 0x00B3, 0x00E0);
+ afe_write_reg(state, link_rate, CMN_PLL0_FRACDIV,
+ 0xF915, 0xF6C7, 0x75A1, 0xF479, 0xF915, 0xF6C7, 0xF479);
+ afe_write_reg(state, link_rate, CMN_PLL0_HIGH_THR,
+ 0x0022, 0x002D, 0x0033, 0x0038, 0x0022, 0x002D, 0x0038);
+#ifdef SSC_ON_INIT
+ /* Following register writes enable SSC on PHY's initialization. */
+ afe_write_reg(state, link_rate, CMN_PLL0_SS_CTRL1,
+ 0x0140, 0x01AB, 0x01E0, 0x0204, 0x0140, 0x01AB, 0x0204);
+ Afe_write(state, CMN_PLL0_SS_CTRL2, 0x7F03);
+#endif
+ Afe_write(state, CMN_PLL0_DSM_DIAG, 0x0020);
+ afe_write_reg(state, link_rate, CMN_PLLSM0_USER_DEF_CTRL,
+ 0x0000, 0x1000, 0x1000, 0x1000, 0x0000, 0x1000, 0x1000);
+ Afe_write(state, CMN_DIAG_PLL0_OVRD, 0x0000);
+ Afe_write(state, CMN_DIAG_PLL0_FBH_OVRD, 0x0000);
+ Afe_write(state, CMN_DIAG_PLL0_FBL_OVRD, 0x0000);
+ afe_write_reg(state, link_rate, CMN_DIAG_PLL0_V2I_TUNE,
+ 0x0006, 0x0007, 0x0007, 0x0007, 0x0006, 0x0007, 0x0007);
+ Afe_write(state, CMN_DIAG_PLL0_CP_TUNE, 0x0045);
+ Afe_write(state, CMN_DIAG_PLL0_LF_PROG, 0x0008);
+ afe_write_reg(state, link_rate, CMN_DIAG_PLL0_PTATIS_TUNE1,
+ 0x0100, 0x0001, 0x0001, 0x0001, 0x0100, 0x0001, 0x0001);
+ afe_write_reg(state, link_rate, CMN_DIAG_PLL0_PTATIS_TUNE2,
+ 0x0007, 0x0001, 0x0001, 0x0001, 0x0007, 0x0001, 0x0001);
+ for (k = 0; k < num_lanes; k = k + 1) {
+ rdata = Afe_read(state, (XCVR_DIAG_PLLDRC_CTRL | (k << 9)));
+ rdata = rdata & 0x8FFF;
+ switch (link_rate) {
+ case AFE_LINK_RATE_1_6:
+ case AFE_LINK_RATE_2_1:
+ case AFE_LINK_RATE_2_4:
+ case AFE_LINK_RATE_2_7:
+ rdata = rdata | 0x2000;
+ break;
+ case AFE_LINK_RATE_3_2:
+ case AFE_LINK_RATE_4_3:
+ case AFE_LINK_RATE_5_4:
+ rdata = rdata | 0x1000;
+ break;
+ default:
+ break;
+ }
+ Afe_write(state, (XCVR_DIAG_PLLDRC_CTRL | (k << 9)), rdata);
+ }
+}
+
+/* Valid for 27 MHz only */
+static void phy_cfg_dp_pll0_27mhz(state_struct *state,
+ int num_lanes,
+ ENUM_AFE_LINK_RATE link_rate)
+{
+ int k;
+ unsigned short rdata;
+
+ rdata = Afe_read(state, PHY_HDP_CLK_CTL);
+ rdata = rdata & 0x00FF;
+ switch (link_rate) {
+ case AFE_LINK_RATE_1_6:
+ case AFE_LINK_RATE_2_1:
+ case AFE_LINK_RATE_2_4:
+ case AFE_LINK_RATE_2_7:
+ rdata = rdata | 0x2400;
+ break;
+ case AFE_LINK_RATE_3_2:
+ case AFE_LINK_RATE_4_3:
+ case AFE_LINK_RATE_5_4:
+ rdata = rdata | 0x1200;
+ break;
+ case AFE_LINK_RATE_8_1: /* Not supported MCU1 or MCU2 */
+ default:
+ pr_info("Warning. Unsupported Link Rate!\n");
+ break;
+ }
+ Afe_write(state, PHY_HDP_CLK_CTL, rdata);
+ rdata = Afe_read(state, CMN_DIAG_HSCLK_SEL);
+ rdata = rdata & 0xFFCC;
+ switch (link_rate) {
+ case AFE_LINK_RATE_1_6:
+ case AFE_LINK_RATE_2_1:
+ case AFE_LINK_RATE_2_4:
+ case AFE_LINK_RATE_2_7:
+ rdata = rdata | 0x0011;
+ break;
+ case AFE_LINK_RATE_3_2:
+ case AFE_LINK_RATE_4_3:
+ case AFE_LINK_RATE_5_4:
+ rdata = rdata | 0x0000;
+ break;
+ default:
+ break;
+ }
+ Afe_write(state, CMN_DIAG_HSCLK_SEL, rdata);
+ for (k = 0; k < num_lanes; k = k + 1) {
+ rdata = Afe_read(state, (XCVR_DIAG_HSCLK_SEL | (k << 9)));
+ rdata = rdata & 0xCFFF;
+ switch (link_rate) {
+ case AFE_LINK_RATE_1_6:
+ case AFE_LINK_RATE_2_1:
+ case AFE_LINK_RATE_2_4:
+ case AFE_LINK_RATE_2_7:
+ rdata = rdata | 0x1000;
+ break;
+ case AFE_LINK_RATE_3_2:
+ case AFE_LINK_RATE_4_3:
+ case AFE_LINK_RATE_5_4:
+ rdata = rdata | 0x0000;
+ break;
+ default:
+ break;
+ }
+ Afe_write(state, (XCVR_DIAG_HSCLK_SEL | (k << 9)), rdata);
+ }
+ /* Gbps 1.62 2.16 2.43 2.7 3.24 4.32 5.4 */
+ Afe_write(state, CMN_PLL0_VCOCAL_INIT_TMR, 0x010E);
+ Afe_write(state, CMN_PLL0_VCOCAL_ITER_TMR, 0x001B);
+ afe_write_reg(state, link_rate, CMN_PLL0_VCOCAL_START,
+ 0x30B9, 0x3087, 0x3096, 0x30B4, 0x30B9, 0x3087, 0x30B4);
+ afe_write_reg(state, link_rate, CMN_PLL0_INTDIV,
+ 0x0077, 0x009F, 0x00B3, 0x00C7, 0x0077, 0x009F, 0x00C7);
+ afe_write_reg(state, link_rate, CMN_PLL0_FRACDIV,
+ 0xF9DA, 0xF7CD, 0xF6C7, 0xF5C1, 0xF9DA, 0xF7CD, 0xF5C1);
+ afe_write_reg(state, link_rate, CMN_PLL0_HIGH_THR,
+ 0x001E, 0x0028, 0x002D, 0x0032, 0x001E, 0x0028, 0x0032);
+#ifdef SSC_ON_INIT
+ /* Following register writes enable SSC on PHY's initialization. */
+ afe_write_reg(state, link_rate, CMN_PLL0_SS_CTRL1,
+ 0x0152, 0x01C2, 0x01FB, 0x0233, 0x0152, 0x01C2, 0x0233);
+ Afe_write(state, CMN_PLL0_SS_CTRL2, 0x6B04);
+#endif
+ Afe_write(state, CMN_PLL0_DSM_DIAG, 0x0020);
+ afe_write_reg(state, link_rate, CMN_PLLSM0_USER_DEF_CTRL,
+ 0x0000, 0x1000, 0x1000, 0x1000, 0x0000, 0x1000, 0x1000);
+ Afe_write(state, CMN_DIAG_PLL0_OVRD, 0x0000);
+ Afe_write(state, CMN_DIAG_PLL0_FBH_OVRD, 0x0000);
+ Afe_write(state, CMN_DIAG_PLL0_FBL_OVRD, 0x0000);
+ afe_write_reg(state, link_rate, CMN_DIAG_PLL0_V2I_TUNE,
+ 0x0006, 0x0007, 0x0007, 0x0007, 0x0006, 0x0007, 0x0007);
+ afe_write_reg(state, link_rate, CMN_DIAG_PLL0_CP_TUNE,
+ 0x0043, 0x0043, 0x0043, 0x0042, 0x0043, 0x0043, 0x0042);
+ Afe_write(state, CMN_DIAG_PLL0_LF_PROG, 0x0008);
+ afe_write_reg(state, link_rate, CMN_DIAG_PLL0_PTATIS_TUNE1,
+ 0x0100, 0x0001, 0x0001, 0x0001, 0x0100, 0x0001, 0x0001);
+ afe_write_reg(state, link_rate, CMN_DIAG_PLL0_PTATIS_TUNE2,
+ 0x0007, 0x0001, 0x0001, 0x0001, 0x0007, 0x0001, 0x0001);
+ for (k = 0; k < num_lanes; k = k + 1) {
+ rdata = Afe_read(state, (XCVR_DIAG_PLLDRC_CTRL | (k << 9)));
+ rdata = rdata & 0x8FFF;
+ switch (link_rate) {
+ case AFE_LINK_RATE_1_6:
+ case AFE_LINK_RATE_2_1:
+ case AFE_LINK_RATE_2_4:
+ case AFE_LINK_RATE_2_7:
+ rdata = rdata | 0x2000;
+ break;
+ case AFE_LINK_RATE_3_2:
+ case AFE_LINK_RATE_4_3:
+ case AFE_LINK_RATE_5_4:
+ rdata = rdata | 0x1000;
+ break;
+ default:
+ break;
+ }
+ Afe_write(state, (XCVR_DIAG_PLLDRC_CTRL | (k << 9)), rdata);
+ }
+}
+
+static void phy_cfg_dp_ln(state_struct *state, int num_lanes)
+{
+ int k;
+ unsigned short rdata;
+
+ for (k = 0; k < num_lanes; k = k + 1) {
+ Afe_write(state, (XCVR_PSM_RCTRL | (k << 9)), 0xBEFC);
+ if (state->edp == 0) {
+ Afe_write(state, (TX_PSC_A0 | (k << 9)), 0x6799);
+ Afe_write(state, (TX_PSC_A1 | (k << 9)), 0x6798);
+ Afe_write(state, (TX_PSC_A2 | (k << 9)), 0x0098);
+ Afe_write(state, (TX_PSC_A3 | (k << 9)), 0x0098);
+ } else {
+ Afe_write(state, (TX_PSC_A0 | (k << 9)), 0x279B);
+ Afe_write(state, (TX_PSC_A1 | (k << 9)), 0x2798);
+ Afe_write(state, (TX_PSC_A2 | (k << 9)), 0x0098);
+ Afe_write(state, (TX_PSC_A3 | (k << 9)), 0x0098);
+
+ rdata = Afe_read(state, TX_DIAG_TX_DRV | (k << 9));
+ /* keep bits related to programmable boost */
+ rdata &= 0x0600;
+ rdata |= 0x00C0;
+ Afe_write(state, (TX_DIAG_TX_DRV | (k << 9)), rdata);
+ }
+ rdata = Afe_read(state, RX_PSC_CAL | (k << 9));
+ rdata = rdata & 0xFFBB;
+ Afe_write(state, (RX_PSC_CAL | (k << 9)), rdata);
+ rdata = Afe_read(state, RX_PSC_A0 | (k << 9));
+ rdata = rdata & 0xFFBB;
+ Afe_write(state, (RX_PSC_A0 | (k << 9)), rdata);
+ }
+}
+
+static void aux_cfg_t28hpc(state_struct *state)
+{
+#ifdef DEBUG
+ unsigned short rdata;
+#endif
+ Afe_write(state, TX_DIG_CTRL_REG_2, 36);
+
+ Afe_write(state, TX_ANA_CTRL_REG_2, 0x0100);
+ cdn_usleep(150);
+ Afe_write(state, TX_ANA_CTRL_REG_2, 0x0300);
+ cdn_usleep(150);
+ Afe_write(state, TX_ANA_CTRL_REG_3, 0x0000);
+ cdn_usleep(150);
+ Afe_write(state, TX_ANA_CTRL_REG_1, 0x2008);
+ cdn_usleep(150);
+ Afe_write(state, TX_ANA_CTRL_REG_1, 0x2018);
+ cdn_usleep(150);
+ Afe_write(state, TX_ANA_CTRL_REG_1, 0xA018);
+ cdn_usleep(150);
+ Afe_write(state, TX_ANA_CTRL_REG_2, 0x030C);
+ cdn_usleep(150);
+ Afe_write(state, TX_ANA_CTRL_REG_5, 0x0000);
+ cdn_usleep(150);
+ Afe_write(state, TX_ANA_CTRL_REG_4, 0x1001);
+ cdn_usleep(150);
+ Afe_write(state, TX_ANA_CTRL_REG_1, 0xA098);
+ cdn_usleep(5000);
+ Afe_write(state, TX_ANA_CTRL_REG_1, 0xA198);
+ cdn_usleep(5000);
+ Afe_write(state, TX_ANA_CTRL_REG_2, 0x030d);
+ cdn_usleep(5000);
+ Afe_write(state, TX_ANA_CTRL_REG_2, 0x030f);
+ cdn_usleep(5000);
+
+#ifdef DEBUG
+ rdata = Afe_read(state, TX_ANA_CTRL_REG_1);
+ pr_info("TX_ANA_CTRL_REG_1 %x)\n", rdata);
+ rdata = Afe_read(state, TX_ANA_CTRL_REG_2);
+ pr_info("TX_ANA_CTRL_REG_2 %x)\n", rdata);
+ rdata = Afe_read(state, TX_ANA_CTRL_REG_3);
+ pr_info("TX_ANA_CTRL_REG_3 %x)\n", rdata);
+ rdata = Afe_read(state, TX_ANA_CTRL_REG_4);
+ pr_info("TX_ANA_CTRL_REG_4 %x)\n", rdata);
+ rdata = Afe_read(state, TX_ANA_CTRL_REG_5);
+ pr_info("TX_ANA_CTRL_REG_5 %x)\n", rdata);
+#endif
+}
+
+static void afe_disable_phy_clocks(state_struct *state);
+static void afe_enable_phy_clocks(state_struct *state);
+
+void afe_init_t28hpc(state_struct *state,
+ int num_lanes,
+ ENUM_AFE_LINK_RATE link_rate)
+{
+ u16 val;
+ const int phy_reset_workaround = 0;
+
+ const REFCLK_FREQ refclk = REFCLK_27MHZ;
+
+ if (AFE_check_rate_supported(link_rate) == 0) {
+ pr_err("afe_init_t28hpc(): Selected link rate not supported: 0x%x\n",
+ link_rate);
+ return;
+ }
+ if (state->phy_init)
+ afe_disable_phy_clocks(state);
+
+ if (phy_reset_workaround) {
+ int k;
+ uint32_t reg_val;
+ /* enable PHY isolation mode only for CMN */
+ /* register PHY_PMA_ISOLATION_CTRL */
+ Afe_write(state, 0xC81F, 0xD000);
+
+ /* set cmn_pll0_clk_datart1_div/cmn_pll0_clk_datart0_div
+ * dividers
+ */
+ /* register PHY_PMA_ISO_PLL_CTRL1 */
+ reg_val = Afe_read(state, 0xC812);
+ reg_val &= 0xFF00;
+ reg_val |= 0x0012;
+ Afe_write(state, 0xC812, reg_val);
+
+ /* assert PHY reset from isolation register */
+ /* register PHY_ISO_CMN_CTRL */
+ Afe_write(state, 0xC010, 0x0000);
+
+ /* assert PMA CMN reset */
+ /* register PHY_PMA_ISO_CMN_CTRL */
+ Afe_write(state, 0xC810, 0x0000);
+
+ for (k = 0; k < num_lanes; k++) {
+ /* register XCVR_DIAG_BIDI_CTRL */
+ Afe_write(state, 0x40E8 | (k << 9), 0x00FF);
+ }
+ }
+
+ val = Afe_read(state, PHY_PMA_CMN_CTRL1);
+ val = val & 0xFFF7;
+ val = val | 0x0008;
+ Afe_write(state, PHY_PMA_CMN_CTRL1, val);
+
+ Afe_write(state, CMN_DIAG_PLL0_TEST_MODE, 0x0020);
+ Afe_write(state, CMN_PSM_CLK_CTRL, 0x0016);
+
+ if (refclk == REFCLK_24MHZ) {
+ phy_cfg_24mhz(state, num_lanes);
+ phy_cfg_dp_pll0_24mhz(state, num_lanes, link_rate);
+ } else if (refclk == REFCLK_27MHZ) {
+ phy_cfg_27mhz(state, num_lanes);
+ phy_cfg_dp_pll0_27mhz(state, num_lanes, link_rate);
+ } else
+ pr_info("AFE_init() *E: Incorrect value of the refclk: %0d\n",
+ refclk);
+
+ val = Afe_read(state, PHY_PMA_CMN_CTRL1);
+ val = val & 0xFF8F;
+ /* for single ended reference clock on the cmn_ref_clk_int pin:
+ * PHY_PMA_CMN_CTRL1[6:4]=3'b011
+ * val |= 0x0030;
+ */
+
+ /* for differential clock on the refclk_p and refclk_m off chip pins:
+ * PHY_PMA_CMN_CTRL1[6:4]=3'b000
+ * val = val | 0x0000;
+ */
+ val = val | 0x0000; /* select external reference */
+ Afe_write(state, PHY_PMA_CMN_CTRL1, val);
+
+ /* for differential clock on the refclk_p and refclk_m off chip pins:
+ * CMN_DIAG_ACYA[8]=1'b1
+ */
+ Afe_write(state, CMN_DIAG_ACYA /*0x01FF*/, 0x0100);
+
+ if (phy_reset_workaround) {
+ int k;
+ /* Deassert PHY reset*/
+ /* register PHY_ISO_CMN_CTRL */
+ Afe_write(state, 0xC010, 0x0001);
+ /* register PHY_PMA_ISO_CMN_CTRL */
+ Afe_write(state, 0xC810, 0x0003);
+ for (k = 0; k < num_lanes; k++) {
+ /* register XCVR_PSM_RCTRL */
+ Afe_write(state, 0x4001 | (k << 9), 0xFEFC);
+ }
+ /* Assert cmn_macro_pwr_en */
+ /* register PHY_PMA_ISO_CMN_CTRL */
+ Afe_write(state, 0xC810, 0x0013);
+
+ /* wait for cmn_macro_pwr_en_ack */
+ /* PHY_PMA_ISO_CMN_CTRL */
+ while (!(Afe_read(state, 0xC810) & (1 << 5)))
+ ;
+
+ /* wait for cmn_ready */
+ /* PHY_PMA_CMN_CTRL1 */
+ while (!(Afe_read(state, 0xC800) & (1 << 0)))
+ ;
+ }
+
+ if (state->edp != 0)
+ Afe_write(state, CMN_DIAG_CAL_CTRL, 0x0001);
+
+ phy_cfg_dp_ln(state, num_lanes);
+
+ /* Configure PHY in A2 Mode */
+ Afe_write(state, PHY_HDP_MODE_CTRL, 0x0004);
+}
+
+void afe_power_t28hpc(state_struct *state,
+ int num_lanes,
+ ENUM_AFE_LINK_RATE link_rate)
+{
+ unsigned short val;
+ int i = 0;
+
+ if (AFE_check_rate_supported(link_rate) == 0) {
+ pr_err("%s() *E: Selected link rate not supported: 0x%x\n",
+ __func__, link_rate);
+ return;
+ }
+ if (state->phy_init)
+ afe_enable_phy_clocks(state);
+ else
+ state->phy_init = 1;
+
+ Afe_write(state, TX_DIAG_ACYA_0, 1);
+ Afe_write(state, TX_DIAG_ACYA_1, 1);
+ Afe_write(state, TX_DIAG_ACYA_2, 1);
+ Afe_write(state, TX_DIAG_ACYA_3, 1);
+
+ Afe_write(state, TXDA_CYA_AUXDA_CYA, 1);
+
+ /* Wait for A2 ACK (PHY_HDP_MODE_CTL [6] = 1’b1) */
+ do {
+ val = Afe_read(state, PHY_HDP_MODE_CTRL);
+ val = val >> 6;
+ if (i++ % 10000 == 0)
+ pr_info("Wait for A2 ACK\n");
+ } while ((val & 1) == 0);
+
+ /* Configure PHY in A0 mode (PHY must be in the A0 power
+ * state in order to transmit data)
+ */
+ Afe_write(state, PHY_HDP_MODE_CTRL, 0x0101);
+ /* Wait for A2 ACK (PHY_HDP_MODE_CTL [4] = 1’b1) */
+ do {
+ val = Afe_read(state, PHY_HDP_MODE_CTRL);
+ val = val >> 4;
+ if (i++ % 10000 == 0)
+ pr_info("Wait for A2 ACK again\n");
+ } while ((val & 1) == 0);
+
+ aux_cfg_t28hpc(state);
+
+}
+
+static void afe_disable_phy_clocks(state_struct *state)
+{
+ unsigned short val;
+ int i = 0;
+
+ /* Write PHY_HDP_MODE_CTL[3:0] with 0b1000. (Place the PHY lanes in
+ * the A3 power state.)
+ */
+ Afe_write(state, PHY_HDP_MODE_CTRL, 0x8);
+
+ /* Wait for PHY_HDP_MODE_CTL[7:4] == 0b1000 */
+ do {
+ val = Afe_read(state, PHY_HDP_MODE_CTRL);
+ val = val >> 7;
+ if (i++ % 10000 == 0)
+ pr_info("Wait for A3 ACK\n");
+ } while ((val & 1) != 1);
+
+ /* gate PLL clocks */
+ val = Afe_read(state, PHY_HDP_CLK_CTL);
+ val &= ~(1 << 2);
+ Afe_write(state, PHY_HDP_CLK_CTL, val);
+
+ /* Wait for PHY_HDP_CLK_CTL[bit 3] == 0 */
+ do {
+ val = Afe_read(state, PHY_HDP_CLK_CTL);
+ val = val >> 3;
+ if (i++ % 10000 == 0)
+ pr_info("Wait for PHY_HDP_CLK_CTL[bit 3] == 0\n");
+ } while ((val & 1) != 0);
+
+ /* disable PLL */
+ val = Afe_read(state, PHY_HDP_CLK_CTL);
+ val &= ~(1 << 0);
+ Afe_write(state, PHY_HDP_CLK_CTL, val);
+
+ /* Wait for PHY_HDP_CLK_CTL[bit 1] == 0 */
+ do {
+ val = Afe_read(state, PHY_HDP_CLK_CTL);
+ val = val >> 1;
+ if (i++ % 10000 == 0)
+ pr_info("Wait for PHY_HDP_CLK_CTL[bit 1] == 0\n");
+ } while ((val & 1) != 0);
+}
+
+static void afe_enable_phy_clocks(state_struct *state)
+{
+ unsigned short val;
+ int i = 0;
+
+ /* enable PLL */
+ val = Afe_read(state, PHY_HDP_CLK_CTL);
+ val |= (1 << 0);
+ Afe_write(state, PHY_HDP_CLK_CTL, val);
+
+ /* Wait for PHY_HDP_CLK_CTL[bit 1] == 0 */
+ do {
+ val = Afe_read(state, PHY_HDP_CLK_CTL);
+ val = val >> 1;
+ if (i++ % 10000 == 0)
+ pr_info("Wait until PHY_HDP_CLK_CTL[bit 1] != 0\n");
+ } while ((val & 1) == 0);
+
+ /* ungate PLL clocks */
+ val = Afe_read(state, PHY_HDP_CLK_CTL);
+ val |= (1 << 2);
+ Afe_write(state, PHY_HDP_CLK_CTL, val);
+
+ /* Wait for PHY_HDP_CLK_CTL[bit 3] == 0 */
+ do {
+ val = Afe_read(state, PHY_HDP_CLK_CTL);
+ val = val >> 3;
+ if (i++ % 10000 == 0)
+ pr_info("Wait until PHY_HDP_CLK_CTL[bit 3] != 0\n");
+ } while ((val & 1) == 0);
+}
diff --git a/drivers/gpu/drm/imx/hdp/API_AFE_mcu2_dp.h b/drivers/gpu/drm/imx/hdp/API_AFE_mcu2_dp.h
new file mode 100644
index 000000000000..1f450b8f4d00
--- /dev/null
+++ b/drivers/gpu/drm/imx/hdp/API_AFE_mcu2_dp.h
@@ -0,0 +1,195 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2016-2017 Cadence Design Systems, Inc.
+ * All rights reserved worldwide.
+ *
+ * Copyright 2018 NXP
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 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.
+ *
+ ******************************************************************************
+ *
+ * API_AFE_mcu2_dp.h
+ *
+ ******************************************************************************
+ */
+
+#ifndef API_AFE_MCU2_DP_H
+# define API_AFE_MCU2_DP_H
+
+#define CMN_SSM_BIAS_TMR 0x0022
+#define CMN_PLLSM0_PLLEN_TMR 0x0029
+#define CMN_PLLSM0_PLLPRE_TMR 0x002A
+#define CMN_PLLSM0_PLLVREF_TMR 0x002B
+#define CMN_PLLSM0_PLLLOCK_TMR 0x002C
+#define CMN_ICAL_INIT_TMR 0x00C4
+#define CMN_ICAL_ITER_TMR 0x00C5
+#define CMN_ICAL_ADJ_INIT_TMR 0x0102
+#define CMN_ICAL_ADJ_ITER_TMR 0x0103
+#define CMN_TXPUCAL_INIT_TMR 0x00E4
+#define CMN_TXPUCAL_ITER_TMR 0x00E5
+#define CMN_TXPU_ADJ_INIT_TMR 0x010A
+#define CMN_TXPU_ADJ_ITER_TMR 0x010B
+#define CMN_TXPDCAL_INIT_TMR 0x00F4
+#define CMN_TXPDCAL_ITER_TMR 0x00F5
+#define CMN_TXPD_ADJ_INIT_TMR 0x010E
+#define CMN_TXPD_ADJ_ITER_TMR 0x010F
+#define CMN_RXCAL_INIT_TMR 0x00D4
+#define CMN_RXCAL_ITER_TMR 0x00D5
+#define CMN_RX_ADJ_INIT_TMR 0x0106
+#define CMN_RX_ADJ_ITER_TMR 0x0107
+#define XCVR_PSM_CAL_TMR 0x4002
+#define XCVR_PSM_A0IN_TMR 0x4003
+
+#define PHY_PMA_CMN_CTRL1 0xC800
+#define XCVR_DIAG_LANE_FCM_EN_MGN_TMR 0x40F2
+#define XCVR_DIAG_LANE_FCM_EN_MGN_TMR_0 0x40F2
+#define XCVR_DIAG_LANE_FCM_EN_MGN_TMR_1 0x42F2
+#define XCVR_DIAG_LANE_FCM_EN_MGN_TMR_2 0x44F2
+#define XCVR_DIAG_LANE_FCM_EN_MGN_TMR_3 0x46F2
+#define TX_RCVDET_EN_TMR 0x4122
+#define TX_RCVDET_EN_TMR_0 0x4122
+#define TX_RCVDET_EN_TMR_1 0x4322
+#define TX_RCVDET_EN_TMR_2 0x4522
+#define TX_RCVDET_EN_TMR_3 0x4722
+#define TX_RCVDET_ST_TMR 0x4123
+#define TX_RCVDET_ST_TMR_0 0x4123
+#define TX_RCVDET_ST_TMR_1 0x4323
+#define TX_RCVDET_ST_TMR_2 0x4523
+#define TX_RCVDET_ST_TMR_3 0x4723
+#define PHY_HDP_CLK_CTL 0xC009
+#define CMN_DIAG_HSCLK_SEL 0x01E0
+#define XCVR_DIAG_HSCLK_SEL 0x40E1
+#define XCVR_DIAG_HSCLK_SEL_0 0x40E1
+#define XCVR_DIAG_HSCLK_SEL_1 0x42E1
+#define XCVR_DIAG_HSCLK_SEL_2 0x44E1
+#define XCVR_DIAG_HSCLK_SEL_3 0x46E1
+#define CMN_PLL0_VCOCAL_START 0x0081
+#define CMN_PLLSM0_USER_DEF_CTRL 0x002F
+#define CMN_DIAG_PLL0_V2I_TUNE 0x01C5
+#define CMN_DIAG_PLL0_PTATIS_TUNE1 0x01C8
+#define CMN_DIAG_PLL0_PTATIS_TUNE2 0x01C9
+#define CMN_DIAG_PLL0_CP_TUNE 0x01C6
+#define CMN_DIAG_PER_CAL_ADJ 0x01EC
+#define CMN_DIAG_CAL_CTRL 0x01ED
+#define CMN_DIAG_ACYA 0x01ff
+#define CMN_DIAG_PLL0_LF_PROG 0x01C7
+#define CMN_PLL0_VCOCAL_INIT_TMR 0x0084
+#define CMN_PLL0_VCOCAL_ITER_TMR 0x0085
+#define CMN_PLL0_INTDIV 0x0094
+#define CMN_PLL0_FRACDIV 0x0095
+#define CMN_PLL0_HIGH_THR 0x0096
+#define CMN_PLL0_SS_CTRL1 0x0098
+#define CMN_PLL0_SS_CTRL2 0x0099
+#define CMN_PLL0_DSM_DIAG 0x0097
+#define CMN_DIAG_PLL0_OVRD 0x01C2
+#define CMN_DIAG_PLL0_FBH_OVRD 0x01C0
+#define CMN_DIAG_PLL0_FBL_OVRD 0x01C1
+#define XCVR_DIAG_PLLDRC_CTRL 0x40E0
+#define XCVR_DIAG_PLLDRC_CTRL_0 0x40E0
+#define XCVR_DIAG_PLLDRC_CTRL_1 0x42E0
+#define XCVR_DIAG_PLLDRC_CTRL_2 0x44E0
+#define XCVR_DIAG_PLLDRC_CTRL_3 0x46E0
+#define CMN_DIAG_PLL0_TEST_MODE 0x01C4
+#define PHY_HDP_MODE_CTRL 0xC008
+#define XCVR_PSM_RCTRL 0x4001
+#define XCVR_PSM_RCTRL_0 0x4001
+#define XCVR_PSM_RCTRL_1 0x4201
+#define XCVR_PSM_RCTRL_2 0x4401
+#define XCVR_PSM_RCTRL_3 0x4601
+#define TX_PSC_A0 0x4100
+#define TX_PSC_A0_0 0x4100
+#define TX_PSC_A0_1 0x4300
+#define TX_PSC_A0_2 0x4500
+#define TX_PSC_A0_3 0x4700
+#define TX_PSC_A1 0x4101
+#define TX_PSC_A1_0 0x4101
+#define TX_PSC_A1_1 0x4301
+#define TX_PSC_A1_2 0x4501
+#define TX_PSC_A1_3 0x4701
+#define TX_PSC_A2 0x4102
+#define TX_PSC_A2_0 0x4102
+#define TX_PSC_A2_1 0x4302
+#define TX_PSC_A2_2 0x4502
+#define TX_PSC_A2_3 0x4702
+#define TX_PSC_A3 0x4103
+#define TX_PSC_A3_0 0x4103
+#define TX_PSC_A3_1 0x4303
+#define TX_PSC_A3_2 0x4503
+#define TX_PSC_A3_3 0x4703
+#define TX_DIAG_TX_DRV 0x41E1
+#define TX_DIAG_TX_DRV_0 0x41E1
+#define TX_DIAG_TX_DRV_1 0x43E1
+#define TX_DIAG_TX_DRV_2 0x45E1
+#define TX_DIAG_TX_DRV_3 0x47E1
+#define TX_DIAG_BGREF_PREDRV_DELAY 0x41E7
+#define PHY_HDP_MODE_CTRL 0xC008
+#define TX_DIAG_ACYA_0 0x41ff
+#define TX_DIAG_ACYA_1 0x43ff
+#define TX_DIAG_ACYA_2 0x45ff
+#define TX_DIAG_ACYA_3 0x47ff
+
+#define RX_PSC_A0 0x8000
+#define RX_PSC_CAL 0x8006
+#define TX_TXCC_MGNFS_MULT_000_0 0x4050
+#define TX_TXCC_MGNFS_MULT_000_1 0x4250
+#define TX_TXCC_MGNFS_MULT_000_2 0x4450
+#define TX_TXCC_MGNFS_MULT_000_3 0x4650
+
+#define TX_TXCC_CPOST_MULT_00_0 0x404C
+#define TX_TXCC_CPOST_MULT_00_1 0x424C
+#define TX_TXCC_CPOST_MULT_00_2 0x444C
+#define TX_TXCC_CPOST_MULT_00_3 0x464C
+
+#define TX_ANA_CTRL_REG_1 0x5020
+#define TX_ANA_CTRL_REG_2 0x5021
+#define TX_ANA_CTRL_REG_3 0x5026
+#define TX_ANA_CTRL_REG_4 0x5027
+#define TX_ANA_CTRL_REG_5 0x5029
+
+#define TX_DIG_CTRL_REG_2 0x5024
+#define TX_DIG_CTRL_REG_1 0x5023
+#define TXDA_CYA_AUXDA_CYA 0x5025
+#define CMN_TXPUCAL_CTRL 0x00E0
+#define CMN_TXPDCAL_CTRL 0x00F0
+#define CMN_TXPU_ADJ_CTRL 0x0108
+#define CMN_TXPD_ADJ_CTRL 0x010c
+#define TXDA_COEFF_CALC 0x5022
+#define CMN_PSM_CLK_CTRL 0x0061
+
+#define PHY_HDP_TX_CTL_L0 0xC408
+#define PHY_HDP_TX_CTL_L1 0xC448
+#define PHY_HDP_TX_CTL_L2 0xC488
+#define PHY_HDP_TX_CTL_L3 0xC4C8
+
+#endif //API_AFE_MCU2_DP_H
diff --git a/drivers/gpu/drm/imx/hdp/API_AFE_ss28fdsoi_kiran_hdmitx.c b/drivers/gpu/drm/imx/hdp/API_AFE_ss28fdsoi_kiran_hdmitx.c
new file mode 100644
index 000000000000..471039fb6a13
--- /dev/null
+++ b/drivers/gpu/drm/imx/hdp/API_AFE_ss28fdsoi_kiran_hdmitx.c
@@ -0,0 +1,550 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2016-2017 Cadence Design Systems, Inc.
+ * All rights reserved worldwide.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 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.
+ *
+ * Copyright 2017-2018 NXP
+ *
+ ******************************************************************************
+ *
+ * API_AFE_ss28fdsoi_kiran_hdmitx.c
+ *
+ ******************************************************************************
+ */
+
+#include <drm/drmP.h>
+#include <linux/io.h>
+#include "API_AFE_ss28fdsoi_kiran_hdmitx.h"
+#include "ss28fdsoi_hdmitx_table.h"
+#include "imx-hdp.h"
+
+int phy_cfg_hdp_ss28fdsoi(state_struct *state,
+ int num_lanes,
+ struct drm_display_mode *mode,
+ int bpp,
+ VIC_PXL_ENCODING_FORMAT format)
+{
+ const int phy_reset_workaround = 0;
+ u32 vco_freq_khz;
+ unsigned char i;
+ u32 feedback_factor;
+ int row;
+ u32 reg_val;
+ int pixel_freq_khz = mode->clock;
+ u32 character_clock_ratio_num = 1;
+ u32 character_clock_ratio_den = 1;
+ int character_freq_khz;
+ u32 ftemp;
+ clk_ratio_t clk_ratio = CLK_RATIO_1_1;
+
+ reg_field_t cmnda_pll0_hs_sym_div_sel;
+ reg_field_t cmnda_pll0_ip_div;
+ reg_field_t cmnda_pll0_fb_div_low;
+ reg_field_t cmnda_pll0_fb_div_high;
+ reg_field_t cmn_ref_clk_dig_div;
+ reg_field_t divider_scaler;
+ reg_field_t cmnda_hs_clk_0_sel;
+ reg_field_t cmnda_hs_clk_1_sel;
+ reg_field_t tx_subrate;
+ reg_field_t vco_ring_select;
+ reg_field_t pll_feedback_divider_total;
+ reg_field_t voltage_to_current_coarse;
+ reg_field_t voltage_to_current;
+ reg_field_t ndac_ctrl;
+ reg_field_t pmos_ctrl;
+ reg_field_t ptat_ndac_ctrl;
+ reg_field_t charge_pump_gain;
+
+ /* Set field position in a target register */
+ cmnda_pll0_fb_div_high.value = 0x00A;
+ cmnda_pll0_hs_sym_div_sel.msb = 9;
+ cmnda_pll0_hs_sym_div_sel.lsb = 8;
+ cmnda_pll0_ip_div.msb = 7;
+ cmnda_pll0_ip_div.lsb = 0;
+ cmnda_pll0_fb_div_low.msb = 9;
+ cmnda_pll0_fb_div_low.lsb = 0;
+ cmnda_pll0_fb_div_high.msb = 9;
+ cmnda_pll0_fb_div_high.lsb = 0;
+ cmn_ref_clk_dig_div.msb = 13;
+ cmn_ref_clk_dig_div.lsb = 12;
+ divider_scaler.msb = 14;
+ divider_scaler.lsb = 12;
+ cmnda_hs_clk_0_sel.msb = 1;
+ cmnda_hs_clk_0_sel.lsb = 0;
+ cmnda_hs_clk_1_sel.msb = 1;
+ cmnda_hs_clk_1_sel.lsb = 0;
+ tx_subrate.msb = 2;
+ tx_subrate.lsb = 0;
+ vco_ring_select.msb = 12;
+ vco_ring_select.lsb = 12;
+ pll_feedback_divider_total.msb = 9;
+ pll_feedback_divider_total.lsb = 0;
+ voltage_to_current_coarse.msb = 2;
+ voltage_to_current_coarse.lsb = 0;
+ voltage_to_current.msb = 5;
+ voltage_to_current.lsb = 4;
+ ndac_ctrl.msb = 11;
+ ndac_ctrl.lsb = 8;
+ pmos_ctrl.msb = 7;
+ pmos_ctrl.lsb = 0;
+ ptat_ndac_ctrl.msb = 5;
+ ptat_ndac_ctrl.lsb = 0;
+ charge_pump_gain.msb = 8;
+ charge_pump_gain.lsb = 0;
+
+ DRM_INFO
+ ("phy_cfg_hdp() num_lanes: %0d, mode:%dx%dp%d, color depth: %0d-bit, encoding: %0d\n",
+ num_lanes, mode->hdisplay, mode->vdisplay, mode->vrefresh, bpp, format);
+
+ /* register PHY_PMA_ISOLATION_CTRL
+ * enable PHY isolation mode only for CMN */
+ if (phy_reset_workaround) {
+ Afe_write(state, 0xC81F, 0xD000);
+ reg_val = Afe_read(state, 0xC812);
+ reg_val &= 0xFF00;
+ reg_val |= 0x0012;
+ /* set cmn_pll0_clk_datart1_div/cmn_pll0_clk_datart0_div dividers */
+ Afe_write(state, 0xC812, reg_val);
+ /* register PHY_ISO_CMN_CTRL */
+ Afe_write(state, 0xC010, 0x0000); /* assert PHY reset from isolation register */
+ /* register PHY_PMA_ISO_CMN_CTRL */
+ Afe_write(state, 0xC810, 0x0000); /* assert PMA CMN reset */
+ /* register XCVR_DIAG_BIDI_CTRL */
+ for (i = 0; i < num_lanes; i++) {
+ Afe_write(state, 0x40E8 | (i << 9), 0x00FF);
+ }
+ } else {
+ /*--------------------------------------------------------------
+ * Describing Task phy_cfg_hdp
+ * ------------------------------------------------------------*/
+ /* register PHY_PMA_CMN_CTRL1 */
+ for (i = 0; i < num_lanes; i++)
+ Afe_write(state, 0x40E8 | (i << 9), 0x007F);
+ }
+ /* register CMN_DIAG_PLL0_TEST_MODE */
+ Afe_write(state, 0x01C4, 0x0022);
+ /* register CMN_PSM_CLK_CTRL */
+ Afe_write(state, 0x0061, 0x0016);
+
+ /* Determine the TMDS/PIXEL clock ratio */
+ switch (format) {
+ case YCBCR_4_2_2:
+ clk_ratio = CLK_RATIO_1_1;
+ character_clock_ratio_num = 1;
+ character_clock_ratio_den = 1;
+ break;
+ case YCBCR_4_2_0:
+ switch (bpp) {
+ case 8:
+ clk_ratio = CLK_RATIO_1_2;
+ character_clock_ratio_num = 1;
+ character_clock_ratio_den = 2;
+ break;
+ case 10:
+ clk_ratio = CLK_RATIO_5_8;
+ character_clock_ratio_num = 5;
+ character_clock_ratio_den = 8;
+ break;
+ case 12:
+ clk_ratio = CLK_RATIO_3_4;
+ character_clock_ratio_num = 3;
+ character_clock_ratio_den = 4;
+ break;
+ case 16:
+ clk_ratio = CLK_RATIO_1_1;
+ character_clock_ratio_num = 1;
+ character_clock_ratio_den = 1;
+ break;
+ default:
+ pr_err("Invalid ColorDepth\n");
+ }
+ break;
+
+ default:
+ switch (bpp) { /* Assume RGB */
+ case 10:
+ clk_ratio = CLK_RATIO_5_4;
+ character_clock_ratio_num = 5;
+ character_clock_ratio_den = 4;
+ break;
+ case 12:
+ clk_ratio = CLK_RATIO_3_2;
+ character_clock_ratio_num = 3;
+ character_clock_ratio_den = 2;
+ break;
+ case 16:
+ clk_ratio = CLK_RATIO_2_1;
+ character_clock_ratio_num = 2;
+ character_clock_ratio_den = 1;
+ break;
+ default:
+ clk_ratio = CLK_RATIO_1_1;
+ character_clock_ratio_num = 1;
+ character_clock_ratio_den = 1;
+ }
+ }
+
+ /* Determine a relevant feedback factor as used
+ * in the ss28fdsoi_hdmitx_clock_control_table table */
+ switch (clk_ratio) {
+ case CLK_RATIO_1_1:
+ feedback_factor = 1000;
+ break;
+ case CLK_RATIO_5_4:
+ feedback_factor = 1250;
+ break;
+ case CLK_RATIO_3_2:
+ feedback_factor = 1500;
+ break;
+ case CLK_RATIO_2_1:
+ feedback_factor = 2000;
+ break;
+ case CLK_RATIO_1_2:
+ feedback_factor = 500;
+ break;
+ case CLK_RATIO_5_8:
+ feedback_factor = 625;
+ break;
+ case CLK_RATIO_3_4:
+ feedback_factor = 750;
+ break;
+ }
+
+ /* Get right row from the ss28fdsoi_hdmitx_clock_control_table table.
+ * Check if 'pixel_freq_khz' falls inside the
+ * <PIXEL_CLK_FREQ_KHZ_MIN, PIXEL_CLK_FREQ_KHZ_MAX> range.
+ * Consider only the rows with FEEDBACK_FACTOR column matching feedback_factor. */
+ row =
+ get_table_row((const u32 *)&ss28fdsoi_hdmitx_clock_control_table,
+ SS28FDSOI_HDMITX_CLOCK_CONTROL_TABLE_ROWS,
+ SS28FDSOI_HDMITX_CLOCK_CONTROL_TABLE_COLS,
+ pixel_freq_khz, PIXEL_CLK_FREQ_KHZ_MIN,
+ PIXEL_CLK_FREQ_KHZ_MAX, FEEDBACK_FACTOR,
+ feedback_factor);
+
+ /* Check if row was found */
+ ftemp = pixel_freq_khz;
+ if (row == -1) {
+ DRM_WARN("Pixel clock frequency (%u kHz) not supported for this color depth (%0d-bit), row=%d\n",
+ ftemp, bpp, row);
+ return 0;
+ }
+ DRM_INFO
+ ("Pixel clock frequency (%u kHz) is supported in this color depth (%0d-bit). Settings found in row %0d\n",
+ ftemp, bpp, row);
+
+ character_freq_khz =
+ pixel_freq_khz * character_clock_ratio_num /
+ character_clock_ratio_den;
+ ftemp = character_freq_khz;
+ DRM_INFO("Character clock frequency: %u kHz.\n", ftemp);
+
+ /* Extract particular values from the ss28fdsoi_hdmitx_clock_control_table table */
+ set_field_value(&cmnda_pll0_hs_sym_div_sel,
+ ss28fdsoi_hdmitx_clock_control_table[row]
+ [CMNDA_PLL0_HS_SYM_DIV_SEL]);
+ set_field_value(&cmnda_pll0_ip_div,
+ ss28fdsoi_hdmitx_clock_control_table[row]
+ [CMNDA_PLL0_IP_DIV]);
+ set_field_value(&cmnda_pll0_fb_div_low,
+ ss28fdsoi_hdmitx_clock_control_table[row]
+ [CMNDA_PLL0_FB_DIV_LOW]);
+ set_field_value(&cmnda_pll0_fb_div_high,
+ ss28fdsoi_hdmitx_clock_control_table[row]
+ [CMNDA_PLL0_FB_DIV_HIGH]);
+ set_field_value(&cmn_ref_clk_dig_div,
+ ss28fdsoi_hdmitx_clock_control_table[row]
+ [CMN_REF_CLK_DIG_DIV]);
+ set_field_value(&divider_scaler,
+ ss28fdsoi_hdmitx_clock_control_table[row]
+ [REF_CLK_DIVIDER_SCALER]);
+ set_field_value(&cmnda_hs_clk_0_sel,
+ ss28fdsoi_hdmitx_clock_control_table[row]
+ [CMNDA_HS_CLK_0_SEL]);
+ set_field_value(&cmnda_hs_clk_1_sel,
+ ss28fdsoi_hdmitx_clock_control_table[row]
+ [CMNDA_HS_CLK_1_SEL]);
+ set_field_value(&tx_subrate, ss28fdsoi_hdmitx_clock_control_table[row]
+ [HSCLK_DIV_TX_SUB_RATE]);
+ set_field_value(&vco_ring_select,
+ ss28fdsoi_hdmitx_clock_control_table[row]
+ [VCO_RING_SELECT]);
+ set_field_value(&pll_feedback_divider_total,
+ ss28fdsoi_hdmitx_clock_control_table[row]
+ [PLL_FB_DIV_TOTAL]);
+
+ /* Display parameters (informative message) */
+ DRM_DEBUG("set_field_value() cmnda_pll0_hs_sym_div_sel : 0x%X\n",
+ cmnda_pll0_hs_sym_div_sel.value);
+ DRM_DEBUG("set_field_value() cmnda_pll0_ip_div : 0x%02X\n",
+ cmnda_pll0_ip_div.value);
+ DRM_DEBUG("set_field_value() cmnda_pll0_fb_div_low : 0x%03X\n",
+ cmnda_pll0_fb_div_low.value);
+ DRM_DEBUG("set_field_value() cmnda_pll0_fb_div_high : 0x%03X\n",
+ cmnda_pll0_fb_div_high.value);
+ DRM_DEBUG("set_field_value() cmn_ref_clk_dig_div : 0x%X\n",
+ cmn_ref_clk_dig_div.value);
+ DRM_DEBUG("set_field_value() divider_scaler : 0x%X\n",
+ divider_scaler.value);
+ DRM_DEBUG("set_field_value() cmnda_hs_clk_0_sel : %0d\n",
+ cmnda_hs_clk_0_sel.value);
+ DRM_DEBUG("set_field_value() cmnda_hs_clk_1_sel : %0d\n",
+ cmnda_hs_clk_1_sel.value);
+ DRM_DEBUG("set_field_value() tx_subrate : %0d\n",
+ tx_subrate.value);
+ DRM_DEBUG("set_field_value() vco_ring_select : %0d\n",
+ vco_ring_select.value);
+ DRM_DEBUG("set_field_value() pll_feedback_divider_total: %0d\n",
+ pll_feedback_divider_total.value);
+
+ vco_freq_khz =
+ pixel_freq_khz * pll_feedback_divider_total.value /
+ cmnda_pll0_ip_div.value;
+
+ /* Get right row from the ss28fdsoi_hdmitx_pll_tuning_table table.
+ * Check if 'vco_freq_mhz' falls inside the
+ * <PLL_VCO_FREQ_MHZ_MIN, PLL_VCO_FREQ_MHZ_MAX> range.
+ * Consider only the rows with PLL_FEEDBACK_DIV_TOTAL.
+ * column matching pll_feedback_divider_total. */
+ row =
+ get_table_row((const u32 *)&ss28fdsoi_hdmitx_pll_tuning_table,
+ SS28FDSOI_HDMITX_PLL_TUNING_TABLE_ROWS,
+ SS28FDSOI_HDMITX_PLL_TUNING_TABLE_COLS, vco_freq_khz,
+ PLL_VCO_FREQ_KHZ_MIN, PLL_VCO_FREQ_KHZ_MAX,
+ PLL_FEEDBACK_DIV_TOTAL,
+ pll_feedback_divider_total.value);
+ ftemp = vco_freq_khz;
+ if (row == -1) {
+ DRM_WARN("VCO frequency (%u kHz) not supported\n", ftemp);
+ return 0;
+ }
+ DRM_INFO
+ ("VCO frequency (%u kHz) is supported. Settings found in row %0d\n",
+ ftemp, row);
+
+ /* Extract particular values from the ss28fdsoi_hdmitx_pll_tuning_table table */
+ set_field_value(&voltage_to_current_coarse,
+ ss28fdsoi_hdmitx_pll_tuning_table[row]
+ [VOLTAGE_TO_CURRENT_COARSE]);
+ set_field_value(&voltage_to_current,
+ ss28fdsoi_hdmitx_pll_tuning_table[row]
+ [VOLTAGE_TO_CURRENT]);
+ set_field_value(&ndac_ctrl,
+ ss28fdsoi_hdmitx_pll_tuning_table[row][NDAC_CTRL]);
+ set_field_value(&pmos_ctrl,
+ ss28fdsoi_hdmitx_pll_tuning_table[row][PMOS_CTRL]);
+ set_field_value(&ptat_ndac_ctrl,
+ ss28fdsoi_hdmitx_pll_tuning_table[row][PTAT_NDAC_CTRL]);
+ set_field_value(&charge_pump_gain,
+ ss28fdsoi_hdmitx_pll_tuning_table[row]
+ [CHARGE_PUMP_GAIN]);
+
+ /* Display parameters (informative message) */
+ DRM_DEBUG("set_field_value() voltage_to_current_coarse : 0x%X\n",
+ voltage_to_current_coarse.value);
+ DRM_DEBUG("set_field_value() voltage_to_current : 0x%X\n",
+ voltage_to_current.value);
+ DRM_DEBUG("set_field_value() ndac_ctrl : 0x%X\n",
+ ndac_ctrl.value);
+ DRM_DEBUG("set_field_value() pmos_ctrl : 0x%02X\n",
+ pmos_ctrl.value);
+ DRM_DEBUG("set_field_value() ptat_ndac_ctrl : 0x%02X\n",
+ ptat_ndac_ctrl.value);
+ DRM_DEBUG("set_field_value() charge_pump_gain : 0x%03X\n",
+ charge_pump_gain.value);
+
+ /* ---------------------------------------------------------------
+ * Describing Task phy_cfg_hdmi_pll0_0pt5736
+ *---------------------------------------------------------------*/
+
+ Afe_write(state, 0x0081, 0x30A0);
+ /* register CMN_PLL0_VCOCAL_INIT_TMR */
+ Afe_write(state, 0x0084, 0x0064);
+ /* register CMN_PLL0_VCOCAL_ITER_TMR */
+ Afe_write(state, 0x0085, 0x000A);
+ /* register PHY_HDP_CLK_CTL */
+ reg_val = Afe_read(state, 0xC009);
+ reg_val &= 0x00FF;
+ reg_val |= 0x1200;
+ Afe_write(state, 0xC009, reg_val);
+ /* register CMN_DIAG_PLL0_INCLK_CTRL */
+ reg_val = set_reg_value(cmnda_pll0_hs_sym_div_sel);
+ reg_val |= set_reg_value(cmnda_pll0_ip_div);
+ Afe_write(state, 0x01CA, reg_val);
+ /* register CMN_DIAG_PLL0_FBL_OVRD */
+ reg_val = set_reg_value(cmnda_pll0_fb_div_low);
+ reg_val |= (1 << 15);
+ Afe_write(state, 0x01C1, reg_val);
+ /* register PHY_PMA_CMN_CTRL1 */
+ reg_val = Afe_read(state, 0xC800);
+ reg_val &= 0xCFFF;
+ reg_val |= set_reg_value(cmn_ref_clk_dig_div);
+ Afe_write(state, 0xC800, reg_val);
+ /* register CMN_CDIAG_REFCLK_CTRL */
+ reg_val = set_reg_value(divider_scaler);
+ Afe_write(state, 0x0062, reg_val);
+ /* register CMN_DIAG_HSCLK_SEL */
+ reg_val = Afe_read(state, 0x01E0);
+ reg_val &= 0xFF00;
+ reg_val |= (cmnda_hs_clk_0_sel.value >> 1) << 0;
+ reg_val |= (cmnda_hs_clk_1_sel.value >> 1) << 4;
+ Afe_write(state, 0x01E0, reg_val);
+
+ /* register XCVR_DIAG_HSCLK_SEL */
+ for (i = 0; i < num_lanes; i++) {
+ reg_val = Afe_read(state, 0x40E1 | (i << 9));
+ reg_val &= 0xCFFF;
+ reg_val |= (cmnda_hs_clk_0_sel.value >> 1) << 12;
+ Afe_write(state, 0x40E1 | (i << 9), reg_val);
+ }
+
+ /* register TX_DIAG_TX_CTRL */
+ for (i = 0; i < num_lanes; i++) {
+ reg_val = Afe_read(state, 0x41E0 | (i << 9));
+ reg_val &= 0xFF3F;
+ reg_val |= (tx_subrate.value >> 1) << 6;
+ Afe_write(state, 0x41E0 | (i << 9), reg_val);
+ }
+
+ /* register CMN_PLLSM0_USER_DEF_CTRL */
+ reg_val = set_reg_value(vco_ring_select);
+ Afe_write(state, 0x002F, reg_val);
+ /* register CMN_DIAG_PLL0_OVRD */
+ Afe_write(state, 0x01C2, 0x0000);
+ /* register CMN_DIAG_PLL0_FBH_OVRD */
+ reg_val = set_reg_value(cmnda_pll0_fb_div_high);
+ reg_val |= (1 << 15);
+ Afe_write(state, 0x01C0, reg_val);
+ /* register CMN_DIAG_PLL0_V2I_TUNE */
+ reg_val = set_reg_value(voltage_to_current_coarse);
+ reg_val |= set_reg_value(voltage_to_current);
+ Afe_write(state, 0x01C5, reg_val);
+ /* register CMN_DIAG_PLL0_PTATIS_TUNE1 */
+ reg_val = set_reg_value(pmos_ctrl);
+ reg_val |= set_reg_value(ndac_ctrl);
+ Afe_write(state, 0x01C8, reg_val);
+ /* register CMN_DIAG_PLL0_PTATIS_TUNE2 */
+ reg_val = set_reg_value(ptat_ndac_ctrl);
+ Afe_write(state, 0x01C9, reg_val);
+ /* register CMN_DIAG_PLL0_CP_TUNE */
+ reg_val = set_reg_value(charge_pump_gain);
+ Afe_write(state, 0x01C6, reg_val);
+ /* register CMN_DIAG_PLL0_LF_PROG */
+ Afe_write(state, 0x01C7, 0x0008);
+
+ /* register XCVR_DIAG_PLLDRC_CTRL */
+ for (i = 0; i < num_lanes; i++) {
+ reg_val = Afe_read(state, 0x40E0 | (i << 9));
+ reg_val &= 0xBFFF;
+ Afe_write(state, 0x40E0 | (i << 9), reg_val);
+ }
+
+ /* register PHY_PMA_CMN_CTRL1 */
+ reg_val = Afe_read(state, 0xC800);
+ reg_val &= 0xFF8F;
+ reg_val |= 0x0030;
+ Afe_write(state, 0xC800, reg_val);
+
+ /*--------------------------------------------------------------------
+ *--------------------Back to task phy_cfg_hdp------------------------
+ *--------------------------------------------------------------------*/
+
+ if (phy_reset_workaround) {
+ /* register PHY_ISO_CMN_CTRL */
+ Afe_write(state, 0xC010, 0x0001); // Deassert PHY reset */
+ for (i = 0; i < num_lanes; i++) {
+ /* register TX_DIAG_ACYA */
+ Afe_write(state, 0x41FF | (i << 9), 0x0001);
+ }
+ /* register PHY_PMA_ISO_CMN_CTRL */
+ Afe_write(state, 0xC810, 0x0003);
+ for (i = 0; i < num_lanes; i++) {
+ /* register XCVR_PSM_RCTRL */
+ Afe_write(state, 0x4001 | (i << 9), 0xFEFC);
+ }
+ /* register PHY_PMA_ISO_CMN_CTRL */
+ Afe_write(state, 0xC810, 0x0013); /* Assert cmn_macro_pwr_en */
+
+ /* PHY_PMA_ISO_CMN_CTRL */
+ while (!(Afe_read(state, 0xC810) & (1 << 5))) ; /* wait for cmn_macro_pwr_en_ack */
+
+ /* PHY_PMA_CMN_CTRL1 */
+ while (!(Afe_read(state, 0xC800) & (1 << 0))) ; /* wait for cmn_ready */
+ } else {
+ for (i = 0; i < num_lanes; i++) {
+ Afe_write(state, 0x41FF | (i << 9), 0x0001);
+ /* register XCVR_PSM_RCTRL */
+ Afe_write(state, 0x4001 | (i << 9), 0xBEFC);
+ }
+ }
+ for (i = 0; i < num_lanes; i++) {
+ /* register TX_PSC_A0 */
+ Afe_write(state, 0x4100 | (i << 9), 0x6791);
+ /* register TX_PSC_A1 */
+ Afe_write(state, 0x4101 | (i << 9), 0x6790);
+ /* register TX_PSC_A2 */
+ Afe_write(state, 0x4102 | (i << 9), 0x0090);
+ /* register TX_PSC_A3 */
+ Afe_write(state, 0x4103 | (i << 9), 0x0090);
+ }
+
+ /* register PHY_HDP_MODE_CTL */
+ Afe_write(state, 0xC008, 0x0004);
+ return character_freq_khz;
+
+}
+
+#define __ARC_CONFIG__
+
+int hdmi_tx_kiran_power_configuration_seq(state_struct *state, int num_lanes)
+{
+ /* Configure the power state. */
+
+ /* PHY_DP_MODE_CTL */
+ while (!(Afe_read(state, 0xC008) & (1 << 6))) ;
+
+#ifdef __ARC_CONFIG__
+ imx_arc_power_up(state);
+ imx_arc_calibrate(state);
+ imx_arc_config(state);
+#endif
+
+ /* PHY_DP_MODE_CTL */
+ Afe_write(state, 0xC008, (((0x0F << num_lanes) & 0x0F) << 12) | 0x0001);
+
+ /* PHY_DP_MODE_CTL */
+ while (!(Afe_read(state, 0xC008) & (1 << 4))) ;
+ return 0;
+}
diff --git a/drivers/gpu/drm/imx/hdp/API_AFE_ss28fdsoi_kiran_hdmitx.h b/drivers/gpu/drm/imx/hdp/API_AFE_ss28fdsoi_kiran_hdmitx.h
new file mode 100644
index 000000000000..410076214f27
--- /dev/null
+++ b/drivers/gpu/drm/imx/hdp/API_AFE_ss28fdsoi_kiran_hdmitx.h
@@ -0,0 +1,56 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2016-2017 Cadence Design Systems, Inc.
+ * All rights reserved worldwide.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 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.
+ *
+ * Copyright 2017-2018 NXP
+ *
+ ******************************************************************************
+ *
+ * API_AFE_ss28fdsoi_kiran_hdmitx.h
+ *
+ ******************************************************************************
+ */
+
+#ifndef API_AFE_SS28FDSOI_KIRAN_HDMITX_H_
+#define API_AFE_SS28FDSOI_KIRAN_HDMITX_H_
+
+#include "../../../../mxc/hdp/all.h"
+
+int phy_cfg_hdp_ss28fdsoi(state_struct *state, int num_lanes,
+ struct drm_display_mode *mode, int bpp, VIC_PXL_ENCODING_FORMAT format);
+int hdmi_tx_kiran_power_configuration_seq(state_struct *state, int num_lanes);
+
+#endif
diff --git a/drivers/gpu/drm/imx/hdp/API_AFE_t28hpc_hdmitx.c b/drivers/gpu/drm/imx/hdp/API_AFE_t28hpc_hdmitx.c
new file mode 100644
index 000000000000..3b11545dad84
--- /dev/null
+++ b/drivers/gpu/drm/imx/hdp/API_AFE_t28hpc_hdmitx.c
@@ -0,0 +1,781 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2016-2017 Cadence Design Systems, Inc.
+ * All rights reserved worldwide.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 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.
+ *
+ * Copyright 2017-2018 NXP
+ *
+ ******************************************************************************
+ *
+ * API_AFE_t28hpc_hdmitx.c
+ *
+ ******************************************************************************
+ */
+
+#include <drm/drmP.h>
+#include "imx-hdp.h"
+#include "API_AFE_t28hpc_hdmitx.h"
+#include "t28hpc_hdmitx_table.h"
+
+/* check pixel clock rate in
+ * Table 8. HDMI TX pixel clock */
+int pixel_clock_range_t28hpc(struct drm_display_mode *mode)
+{
+ int i, row, rate;
+
+ row = T28HPC_HDMITX_CLOCK_CONTROL_TABLE_ROWS_PIXEL_OUT;
+ for (i = 0; i < row; i++) {
+ rate = t28hpc_hdmitx_clock_control_table_pixel_out[i][T8_PIXEL_CLK_FREQ_KHZ];
+ if (rate == mode->clock)
+ return 1;
+ }
+ return 0;
+}
+
+int phy_cfg_hdp_t28hpc(state_struct *state,
+ int num_lanes,
+ struct drm_display_mode *mode,
+ int bpp,
+ VIC_PXL_ENCODING_FORMAT format,
+ bool pixel_clk_from_phy)
+{
+ const int phy_reset_workaround = 1;
+ u32 vco_freq_khz;
+ unsigned char k;
+ int row;
+ u32 feedback_factor;
+ u32 reg_val;
+ u32 pll_feedback_divider_total;
+ int pixel_freq_khz = mode->clock;
+ u32 character_clock_ratio_num = 1;
+ u32 character_clock_ratio_den = 1;
+ u32 character_freq_khz;
+ const u32 refclk_freq_khz = 27000;
+ clk_ratio_t clk_ratio = CLK_RATIO_1_1;
+
+ reg_field_t cmnda_pll0_hs_sym_div_sel;
+ reg_field_t cmnda_pll0_ip_div;
+ reg_field_t cmnda_pll0_fb_div_low;
+ reg_field_t cmnda_pll0_fb_div_high;
+ reg_field_t cmn_ref_clk_dig_div;
+ reg_field_t divider_scaler;
+ reg_field_t cmnda_hs_clk_0_sel;
+ reg_field_t cmnda_hs_clk_1_sel;
+ reg_field_t tx_subrate;
+ reg_field_t voltage_to_current_coarse;
+ reg_field_t voltage_to_current;
+ reg_field_t ndac_ctrl;
+ reg_field_t pmos_ctrl;
+ reg_field_t ptat_ndac_ctrl;
+ reg_field_t charge_pump_gain;
+ reg_field_t vco_ring_select;
+
+ reg_field_t cmnda_pll0_pxdiv_high;
+ reg_field_t cmnda_pll0_pxdiv_low;
+ reg_field_t coarse_code;
+ reg_field_t v2i_code;
+ reg_field_t vco_cal_code;
+
+ /* Set field position */
+ cmnda_pll0_hs_sym_div_sel.msb = 9;
+ cmnda_pll0_hs_sym_div_sel.lsb = 8;
+ cmnda_pll0_ip_div.msb = 7;
+ cmnda_pll0_ip_div.lsb = 0;
+ cmnda_pll0_fb_div_low.msb = 9;
+ cmnda_pll0_fb_div_low.lsb = 0;
+ cmnda_pll0_fb_div_high.msb = 9;
+ cmnda_pll0_fb_div_high.lsb = 0;
+ cmn_ref_clk_dig_div.msb = 13;
+ cmn_ref_clk_dig_div.lsb = 12;
+ divider_scaler.msb = 14;
+ divider_scaler.lsb = 12;
+ cmnda_hs_clk_0_sel.msb = 1;
+ cmnda_hs_clk_0_sel.lsb = 0;
+ cmnda_hs_clk_1_sel.msb = 1;
+ cmnda_hs_clk_1_sel.lsb = 0;
+ tx_subrate.msb = 2;
+ tx_subrate.lsb = 0;
+ voltage_to_current_coarse.msb = 2;
+ voltage_to_current_coarse.lsb = 0;
+ voltage_to_current.msb = 5;
+ voltage_to_current.lsb = 4;
+ ndac_ctrl.msb = 11;
+ ndac_ctrl.lsb = 8;
+ pmos_ctrl.msb = 7;
+ pmos_ctrl.lsb = 0;
+ ptat_ndac_ctrl.msb = 5;
+ ptat_ndac_ctrl.lsb = 0;
+ charge_pump_gain.msb = 8;
+ charge_pump_gain.lsb = 0;
+ vco_ring_select.msb = 12;
+ vco_ring_select.lsb = 12;
+ cmnda_pll0_pxdiv_high.msb = 9;
+ cmnda_pll0_pxdiv_high.lsb = 0;
+ cmnda_pll0_pxdiv_low.msb = 9;
+ cmnda_pll0_pxdiv_low.lsb = 0;
+ coarse_code.msb = 7;
+ coarse_code.lsb = 0;
+ v2i_code.msb = 3;
+ v2i_code.lsb = 0;
+ vco_cal_code.msb = 8;
+ vco_cal_code.lsb = 0;
+
+ switch (format) {
+ case YCBCR_4_2_2:
+ clk_ratio = CLK_RATIO_1_1;
+ character_clock_ratio_num = 1;
+ character_clock_ratio_den = 1;
+ break;
+ case YCBCR_4_2_0:
+ switch (bpp) {
+ case 8:
+ clk_ratio = CLK_RATIO_1_2;
+ character_clock_ratio_num = 1;
+ character_clock_ratio_den = 2;
+ break;
+ case 10:
+ clk_ratio = CLK_RATIO_5_8;
+ character_clock_ratio_num = 5;
+ character_clock_ratio_den = 8;
+ break;
+ case 12:
+ clk_ratio = CLK_RATIO_3_4;
+ character_clock_ratio_num = 3;
+ character_clock_ratio_den = 4;
+ break;
+ case 16:
+ clk_ratio = CLK_RATIO_1_1;
+ character_clock_ratio_num = 1;
+ character_clock_ratio_den = 1;
+ break;
+ default:
+ DRM_WARN("Invalid ColorDepth\n");
+ }
+ break;
+
+ default:
+ switch (bpp) { /* Assume RGB */
+ case 10:
+ clk_ratio = CLK_RATIO_5_4;
+ character_clock_ratio_num = 5;
+ character_clock_ratio_den = 4;
+ break;
+ case 12:
+ clk_ratio = CLK_RATIO_3_2;
+ character_clock_ratio_num = 3;
+ character_clock_ratio_den = 2;
+ break;
+ case 16:
+ clk_ratio = CLK_RATIO_2_1;
+ character_clock_ratio_num = 2;
+ character_clock_ratio_den = 1;
+ break;
+ default:
+ clk_ratio = CLK_RATIO_1_1;
+ character_clock_ratio_num = 1;
+ character_clock_ratio_den = 1;
+ }
+ }
+
+ /* Determine a relevant feedback factor as used in the
+ * t28hpc_hdmitx_clock_control_table table */
+ switch (clk_ratio) {
+ case CLK_RATIO_1_1:
+ feedback_factor = 1000;
+ break;
+ case CLK_RATIO_5_4:
+ feedback_factor = 1250;
+ break;
+ case CLK_RATIO_3_2:
+ feedback_factor = 1500;
+ break;
+ case CLK_RATIO_2_1:
+ feedback_factor = 2000;
+ break;
+ case CLK_RATIO_1_2:
+ feedback_factor = 500;
+ break;
+ case CLK_RATIO_5_8:
+ feedback_factor = 625;
+ break;
+ case CLK_RATIO_3_4:
+ feedback_factor = 750;
+ break;
+ }
+
+ character_freq_khz =
+ pixel_freq_khz * character_clock_ratio_num /
+ character_clock_ratio_den;
+ DRM_INFO
+ ("Pixel clock frequency: %d KHz, character clock frequency: %d, color depth is %0d-bit.\n",
+ pixel_freq_khz, character_freq_khz, bpp);
+
+ if (pixel_clk_from_phy == 0) {
+
+ /* Get right row from the t28hpc_hdmitx_clock_control_table_pixel_in table.
+ * Check if 'pixel_freq_mhz' falls inside
+ * the <PIXEL_CLK_FREQ_MHZ_MIN, PIXEL_CLK_FREQ_MHZ_MAX> range.
+ * Consider only the rows with FEEDBACK_FACTOR column matching feedback_factor. */
+ row =
+ get_table_row((const u32 *)&t28hpc_hdmitx_clock_control_table_pixel_in,
+ T28HPC_HDMITX_CLOCK_CONTROL_TABLE_ROWS_PIXEL_IN,
+ T28HPC_HDMITX_CLOCK_CONTROL_TABLE_COLS_PIXEL_IN,
+ pixel_freq_khz, T6_PIXEL_CLK_FREQ_KHZ_MIN,
+ T6_PIXEL_CLK_FREQ_KHZ_MAX, T6_FEEDBACK_FACTOR,
+ feedback_factor);
+
+ /* Check if row was found */
+ if (row == -1) {
+ DRM_WARN("Pixel clock frequency (%d KHz) not supported for this color depth (%0d-bit)\n",
+ pixel_freq_khz, bpp);
+ return 0;
+ }
+ DRM_INFO
+ ("Pixel clock frequency (%d KHz) is supported in this color depth (%0d-bit). Settings found in row %0d\n",
+ pixel_freq_khz, bpp, row);
+
+ /* Extract particular values from the
+ * t28hpc_hdmitx_clock_control_table_pixel_in table */
+ set_field_value(&cmnda_pll0_ip_div,
+ t28hpc_hdmitx_clock_control_table_pixel_in[row]
+ [T6_CMNDA_PLL0_IP_DIV]);
+ set_field_value(&cmn_ref_clk_dig_div,
+ t28hpc_hdmitx_clock_control_table_pixel_in[row]
+ [T6_CMN_REF_CLK_DIG_DIV]);
+ set_field_value(&divider_scaler,
+ t28hpc_hdmitx_clock_control_table_pixel_in[row]
+ [T6_REF_CLK_DIVIDER_SCALER]);
+ set_field_value(&cmnda_pll0_fb_div_low,
+ t28hpc_hdmitx_clock_control_table_pixel_in[row]
+ [T6_CMNDA_PLL0_FB_DIV_LOW]);
+ set_field_value(&cmnda_pll0_fb_div_high,
+ t28hpc_hdmitx_clock_control_table_pixel_in[row]
+ [T6_CMNDA_PLL0_FB_DIV_HIGH]);
+ set_field_value(&vco_ring_select,
+ t28hpc_hdmitx_clock_control_table_pixel_in[row]
+ [T6_VCO_RING_SELECT]);
+ set_field_value(&cmnda_hs_clk_0_sel,
+ t28hpc_hdmitx_clock_control_table_pixel_in[row]
+ [T6_CMNDA_HS_CLK_0_SEL]);
+ set_field_value(&cmnda_hs_clk_1_sel,
+ t28hpc_hdmitx_clock_control_table_pixel_in[row]
+ [T6_CMNDA_HS_CLK_1_SEL]);
+ set_field_value(&tx_subrate,
+ t28hpc_hdmitx_clock_control_table_pixel_in[row]
+ [T6_HSCLK_DIV_TX_SUB_RATE]);
+ set_field_value(&cmnda_pll0_hs_sym_div_sel,
+ t28hpc_hdmitx_clock_control_table_pixel_in[row]
+ [T6_CMNDA_PLL0_HS_SYM_DIV_SEL]);
+
+ /* Display parameters (informative message) */
+ DRM_DEBUG("set_field_value() cmnda_pll0_ip_div : 0x%02X\n",
+ cmnda_pll0_ip_div.value);
+ DRM_DEBUG("set_field_value() cmn_ref_clk_dig_div : 0x%X\n",
+ cmn_ref_clk_dig_div.value);
+ DRM_DEBUG("set_field_value() divider_scaler : 0x%X\n",
+ divider_scaler.value);
+ DRM_DEBUG("set_field_value() cmnda_pll0_fb_div_low : 0x%03X\n",
+ cmnda_pll0_fb_div_low.value);
+ DRM_DEBUG("set_field_value() cmnda_pll0_fb_div_high : 0x%03X\n",
+ cmnda_pll0_fb_div_high.value);
+ DRM_DEBUG("set_field_value() vco_ring_select : %0d\n",
+ vco_ring_select.value);
+ DRM_DEBUG("set_field_value() cmnda_hs_clk_0_sel : %0d\n",
+ cmnda_hs_clk_0_sel.value);
+ DRM_DEBUG("set_field_value() cmnda_hs_clk_1_sel : %0d\n",
+ cmnda_hs_clk_1_sel.value);
+ DRM_DEBUG("set_field_value() tx_subrate : %0d\n",
+ tx_subrate.value);
+ DRM_DEBUG("set_field_value() cmnda_pll0_hs_sym_div_sel: 0x%X\n",
+ cmnda_pll0_hs_sym_div_sel.value);
+
+ pll_feedback_divider_total =
+ cmnda_pll0_fb_div_low.value + cmnda_pll0_fb_div_high.value + 4;
+ vco_freq_khz =
+ pixel_freq_khz * pll_feedback_divider_total /
+ cmnda_pll0_ip_div.value;
+ DRM_INFO("VCO frequency is %d\n", vco_freq_khz);
+
+ /* Get right row from the t28hpc_hdmitx_pll_tuning_table_pixel_in table.
+ * Check if 'vco_freq_khz' falls inside the
+ * <PLL_VCO_FREQ_KHZ_MIN, PLL_VCO_FREQ_KHZ_MAX> range.
+ * Consider only the rows with PLL_FEEDBACK_DIV_TOTAL
+ * column matching pll_feedback_divider_total. */
+ row =
+ get_table_row((const u32 *)&t28hpc_hdmitx_pll_tuning_table_pixel_in,
+ T28HPC_HDMITX_PLL_TUNING_TABLE_ROWS_PIXEL_IN,
+ T28HPC_HDMITX_PLL_TUNING_TABLE_COLS_PIXEL_IN,
+ vco_freq_khz, T7_PLL_VCO_FREQ_KHZ_MIN,
+ T7_PLL_VCO_FREQ_KHZ_MAX,
+ T7_PLL_FEEDBACK_DIV_TOTAL,
+ pll_feedback_divider_total);
+
+ if (row == -1) {
+ DRM_WARN("VCO frequency (%d KHz) not supported\n",
+ vco_freq_khz);
+ return 0;
+ }
+ DRM_INFO ("VCO frequency (%d KHz) is supported. Settings found in row %0d\n",
+ vco_freq_khz, row);
+
+ /* Extract particular values from
+ * the t28hpc_hdmitx_pll_tuning_table_pixel_in table */
+ set_field_value(&voltage_to_current_coarse,
+ t28hpc_hdmitx_pll_tuning_table_pixel_in[row]
+ [T7_VOLTAGE_TO_CURRENT_COARSE]);
+ set_field_value(&voltage_to_current,
+ t28hpc_hdmitx_pll_tuning_table_pixel_in[row]
+ [T7_VOLTAGE_TO_CURRENT]);
+ set_field_value(&ndac_ctrl,
+ t28hpc_hdmitx_pll_tuning_table_pixel_in[row]
+ [T7_NDAC_CTRL]);
+ set_field_value(&pmos_ctrl,
+ t28hpc_hdmitx_pll_tuning_table_pixel_in[row]
+ [T7_PMOS_CTRL]);
+ set_field_value(&ptat_ndac_ctrl,
+ t28hpc_hdmitx_pll_tuning_table_pixel_in[row]
+ [T7_PTAT_NDAC_CTRL]);
+ set_field_value(&charge_pump_gain,
+ t28hpc_hdmitx_pll_tuning_table_pixel_in[row]
+ [T7_CHARGE_PUMP_GAIN]);
+
+ /* Display parameters (informative message) */
+ DRM_DEBUG("set_field_value() voltage_to_current_coarse : 0x%X\n",
+ voltage_to_current_coarse.value);
+ DRM_DEBUG("set_field_value() voltage_to_current : 0x%X\n",
+ voltage_to_current.value);
+ DRM_DEBUG("set_field_value() ndac_ctrl : 0x%X\n",
+ ndac_ctrl.value);
+ DRM_DEBUG("set_field_value() pmos_ctrl : 0x%02X\n",
+ pmos_ctrl.value);
+ DRM_DEBUG("set_field_value() ptat_ndac_ctrl : 0x%02X\n",
+ ptat_ndac_ctrl.value);
+ DRM_DEBUG("set_field_value() charge_pump_gain : 0x%03X\n",
+ charge_pump_gain.value);
+
+ } else {
+ /* pixel_clk_from_phy == 1 */
+
+ /* Get right row from the t28hpc_hdmitx_clock_control_table_pixel_out table.
+ * Check if 'pixel_freq_khz' value matches the PIXEL_CLK_FREQ_MHZ column.
+ * Consider only the rows with FEEDBACK_FACTOR column matching feedback_factor. */
+ row =
+ get_table_row((const u32 *)&t28hpc_hdmitx_clock_control_table_pixel_out,
+ T28HPC_HDMITX_CLOCK_CONTROL_TABLE_ROWS_PIXEL_OUT,
+ T28HPC_HDMITX_CLOCK_CONTROL_TABLE_COLS_PIXEL_OUT,
+ pixel_freq_khz, T8_PIXEL_CLK_FREQ_KHZ,
+ T8_PIXEL_CLK_FREQ_KHZ, T8_FEEDBACK_FACTOR,
+ feedback_factor);
+
+ /* Check if row was found */
+ if (row == -1) {
+ DRM_WARN("Pixel clock frequency (%d KHz) not supported for this color depth (%0d-bit)\n",
+ pixel_freq_khz, bpp);
+ return 0;
+ }
+ DRM_INFO
+ ("Pixel clock frequency (%d KHz) is supported in this color depth (%0d-bit). Settings found in row %0d\n",
+ pixel_freq_khz, bpp, row);
+
+ /* Extract particular values from
+ * the t28hpc_hdmitx_clock_control_table_pixel_out table */
+ set_field_value(&cmnda_pll0_ip_div,
+ t28hpc_hdmitx_clock_control_table_pixel_out[row]
+ [T8_CMNDA_PLL0_IP_DIV]);
+ set_field_value(&cmn_ref_clk_dig_div,
+ t28hpc_hdmitx_clock_control_table_pixel_out[row]
+ [T8_CMN_REF_CLK_DIG_DIV]);
+ set_field_value(&divider_scaler,
+ t28hpc_hdmitx_clock_control_table_pixel_out[row]
+ [T8_REF_CLK_DIVIDER_SCALER]);
+ set_field_value(&cmnda_pll0_fb_div_low,
+ t28hpc_hdmitx_clock_control_table_pixel_out[row]
+ [T8_CMNDA_PLL0_FB_DIV_LOW]);
+ set_field_value(&cmnda_pll0_fb_div_high,
+ t28hpc_hdmitx_clock_control_table_pixel_out[row]
+ [T8_CMNDA_PLL0_FB_DIV_HIGH]);
+ set_field_value(&cmnda_pll0_pxdiv_low,
+ t28hpc_hdmitx_clock_control_table_pixel_out[row]
+ [T8_CMNDA_PLL0_PXDIV_LOW]);
+ set_field_value(&cmnda_pll0_pxdiv_high,
+ t28hpc_hdmitx_clock_control_table_pixel_out[row]
+ [T8_CMNDA_PLL0_PXDIV_HIGH]);
+ set_field_value(&vco_ring_select,
+ t28hpc_hdmitx_clock_control_table_pixel_out[row]
+ [T8_VCO_RING_SELECT]);
+ set_field_value(&cmnda_hs_clk_0_sel,
+ t28hpc_hdmitx_clock_control_table_pixel_out[row]
+ [T8_CMNDA_HS_CLK_0_SEL]);
+ set_field_value(&cmnda_hs_clk_1_sel,
+ t28hpc_hdmitx_clock_control_table_pixel_out[row]
+ [T8_CMNDA_HS_CLK_1_SEL]);
+ set_field_value(&tx_subrate,
+ t28hpc_hdmitx_clock_control_table_pixel_out[row]
+ [T8_HSCLK_DIV_TX_SUB_RATE]);
+ set_field_value(&cmnda_pll0_hs_sym_div_sel,
+ t28hpc_hdmitx_clock_control_table_pixel_out[row]
+ [T8_CMNDA_PLL0_HS_SYM_DIV_SEL]);
+
+ /* Display parameters (informative message) */
+ DRM_DEBUG("set_field_value() cmnda_pll0_ip_div : 0x%02X\n",
+ cmnda_pll0_ip_div.value);
+ DRM_DEBUG("set_field_value() cmn_ref_clk_dig_div : 0x%X\n",
+ cmn_ref_clk_dig_div.value);
+ DRM_DEBUG("set_field_value() divider_scaler : 0x%X\n",
+ divider_scaler.value);
+ DRM_DEBUG("set_field_value() cmnda_pll0_fb_div_low : 0x%03X\n",
+ cmnda_pll0_fb_div_low.value);
+ DRM_DEBUG("set_field_value() cmnda_pll0_fb_div_high : 0x%03X\n",
+ cmnda_pll0_fb_div_high.value);
+ DRM_DEBUG("set_field_value() cmnda_pll0_pxdiv_low : 0x%03X\n",
+ cmnda_pll0_pxdiv_low.value);
+ DRM_DEBUG("set_field_value() cmnda_pll0_pxdiv_high : 0x%03X\n",
+ cmnda_pll0_pxdiv_high.value);
+ DRM_DEBUG("set_field_value() vco_ring_select : %0d\n",
+ vco_ring_select.value);
+ DRM_DEBUG("set_field_value() cmnda_hs_clk_0_sel : %0d\n",
+ cmnda_hs_clk_0_sel.value);
+ DRM_DEBUG("set_field_value() cmnda_hs_clk_1_sel : %0d\n",
+ cmnda_hs_clk_1_sel.value);
+ DRM_DEBUG("set_field_value() tx_subrate : %0d\n",
+ tx_subrate.value);
+ DRM_DEBUG("set_field_value() cmnda_pll0_hs_sym_div_sel: 0x%X\n",
+ cmnda_pll0_hs_sym_div_sel.value);
+
+ pll_feedback_divider_total =
+ cmnda_pll0_fb_div_low.value + cmnda_pll0_fb_div_high.value + 4;
+ vco_freq_khz =
+ refclk_freq_khz * pll_feedback_divider_total / cmnda_pll0_ip_div.value;
+
+ DRM_INFO("VCO frequency is %d\n", vco_freq_khz);
+
+ /* Get right row from the t28hpc_hdmitx_pll_tuning_table table_pixel_out.
+ * Check if 'vco_freq_khz' falls inside
+ * the <PLL_VCO_FREQ_KH_MIN, PLL_VCO_FREQ_KHZ_MAX> range.
+ * Consider only the rows with PLL_FEEDBACK_DIV_TOTAL
+ * column matching pll_feedback_divider_total. */
+ row =
+ get_table_row((const u32 *)&t28hpc_hdmitx_pll_tuning_table_pixel_out,
+ T28HPC_HDMITX_PLL_TUNING_TABLE_ROWS_PIXEL_OUT,
+ T28HPC_HDMITX_PLL_TUNING_TABLE_COLS_PIXEL_OUT,
+ vco_freq_khz, T9_PLL_VCO_FREQ_KHZ_MIN,
+ T9_PLL_VCO_FREQ_KHZ_MAX,
+ T9_PLL_FEEDBACK_DIV_TOTAL,
+ pll_feedback_divider_total);
+
+ if (row == -1) {
+ DRM_WARN("VCO frequency (%d KHz) not supported\n",
+ vco_freq_khz);
+ return 0;
+ }
+ DRM_INFO("VCO frequency (%d KHz) is supported. Settings found in row %0d\n",
+ vco_freq_khz, row);
+
+ /* Extract particular values from
+ * the t28hpc_hdmitx_pll_tuning_table_pixel_out table. */
+ set_field_value(&voltage_to_current_coarse,
+ t28hpc_hdmitx_pll_tuning_table_pixel_out[row]
+ [T9_VOLTAGE_TO_CURRENT_COARSE]);
+ set_field_value(&voltage_to_current,
+ t28hpc_hdmitx_pll_tuning_table_pixel_out[row]
+ [T9_VOLTAGE_TO_CURRENT]);
+ set_field_value(&ndac_ctrl,
+ t28hpc_hdmitx_pll_tuning_table_pixel_out[row]
+ [T9_NDAC_CTRL]);
+ set_field_value(&pmos_ctrl,
+ t28hpc_hdmitx_pll_tuning_table_pixel_out[row]
+ [T9_PMOS_CTRL]);
+ set_field_value(&ptat_ndac_ctrl,
+ t28hpc_hdmitx_pll_tuning_table_pixel_out[row]
+ [T9_PTAT_NDAC_CTRL]);
+ set_field_value(&charge_pump_gain,
+ t28hpc_hdmitx_pll_tuning_table_pixel_out[row]
+ [T9_CHARGE_PUMP_GAIN]);
+ set_field_value(&coarse_code,
+ t28hpc_hdmitx_pll_tuning_table_pixel_out[row]
+ [T9_COARSE_CODE]);
+ set_field_value(&v2i_code,
+ t28hpc_hdmitx_pll_tuning_table_pixel_out[row]
+ [T9_V2I_CODE]);
+ set_field_value(&vco_cal_code,
+ t28hpc_hdmitx_pll_tuning_table_pixel_out[row]
+ [T9_VCO_CAL_CODE]);
+
+ /* Display parameters (informative message) */
+ DRM_DEBUG("set_field_value() voltage_to_current_coarse : 0x%X\n",
+ voltage_to_current_coarse.value);
+ DRM_DEBUG("set_field_value() voltage_to_current : 0x%X\n",
+ voltage_to_current.value);
+ DRM_DEBUG("set_field_value() ndac_ctrl : 0x%X\n",
+ ndac_ctrl.value);
+ DRM_DEBUG("set_field_value() pmos_ctrl : 0x%02X\n",
+ pmos_ctrl.value);
+ DRM_DEBUG("set_field_value() ptat_ndac_ctrl : 0x%02X\n",
+ ptat_ndac_ctrl.value);
+ DRM_DEBUG("set_field_value() charge_pump_gain : 0x%03X\n",
+ charge_pump_gain.value);
+ DRM_DEBUG("set_field_value() coarse_code : %0d\n",
+ coarse_code.value);
+ DRM_DEBUG("set_field_value() v2i_code : %0d\n",
+ v2i_code.value);
+ DRM_DEBUG("set_field_value() vco_cal_code : %0d\n",
+ vco_cal_code.value);
+ }
+
+ if (phy_reset_workaround) {
+ /* register PHY_PMA_ISOLATION_CTRL */
+ /* enable PHY isolation mode only for CMN */
+ Afe_write(state, 0xC81F, 0xD000);
+ /* register PHY_PMA_ISO_PLL_CTRL1 */
+ reg_val = Afe_read(state, 0xC812);
+ reg_val &= 0xFF00;
+ reg_val |= 0x0012;
+ /* set cmn_pll0_clk_datart1_div/cmn_pll0_clk_datart0_div dividers */
+ Afe_write(state, 0xC812, reg_val);
+ /* register PHY_ISO_CMN_CTRL */
+ /* assert PHY reset from isolation register */
+ Afe_write(state, 0xC010, 0x0000);
+ /* register PHY_PMA_ISO_CMN_CTRL */
+ /* assert PMA CMN reset */
+ Afe_write(state, 0xC810, 0x0000);
+ /* register XCVR_DIAG_BIDI_CTRL */
+ for (k = 0; k < num_lanes; k++) {
+ Afe_write(state, 0x40E8 | (k << 9), 0x00FF);
+ }
+ }
+ /* Describing Task phy_cfg_hdp */
+
+ /* register PHY_PMA_CMN_CTRL1 */
+ reg_val = Afe_read(state, 0xC800);
+ reg_val &= 0xFFF7;
+ reg_val |= 0x0008;
+ Afe_write(state, 0xC800, reg_val);
+
+ /* register CMN_DIAG_PLL0_TEST_MODE */
+ Afe_write(state, 0x01C4, 0x0020);
+ /* register CMN_PSM_CLK_CTRL */
+ Afe_write(state, 0x0061, 0x0016);
+
+ /* Describing Task phy_cfg_hdmi_pll0_0pt5736 */
+
+ /* register CMN_PLL0_VCOCAL_INIT_TMR */
+ Afe_write(state, 0x0084, 0x0064);
+ /* register CMN_PLL0_VCOCAL_ITER_TMR */
+ Afe_write(state, 0x0085, 0x000A);
+ /*register PHY_HDP_CLK_CTL */
+ reg_val = Afe_read(state, 0xC009);
+ reg_val &= 0x00FF;
+ reg_val |= 0x1200;
+ Afe_write(state, 0xC009, reg_val);
+ /* register CMN_DIAG_PLL0_INCLK_CTRL */
+ reg_val = set_reg_value(cmnda_pll0_hs_sym_div_sel);
+ reg_val |= set_reg_value(cmnda_pll0_ip_div);
+ Afe_write(state, 0x01CA, reg_val);
+ /* register CMN_DIAG_PLL0_FBH_OVRD */
+ reg_val = set_reg_value(cmnda_pll0_fb_div_high);
+ reg_val |= (1 << 15);
+ Afe_write(state, 0x01C0, reg_val);
+ /* register CMN_DIAG_PLL0_FBL_OVRD */
+ reg_val = set_reg_value(cmnda_pll0_fb_div_low);
+ reg_val |= (1 << 15);
+ Afe_write(state, 0x01C1, reg_val);
+ /*register PHY_PMA_CMN_CTRL1 */
+ reg_val = Afe_read(state, 0xC800);
+ reg_val &= 0xCFFF;
+ reg_val |= set_reg_value(cmn_ref_clk_dig_div);
+ Afe_write(state, 0xC800, reg_val);
+ /* register CMN_CDIAG_REFCLK_CTRL */
+ reg_val = Afe_read(state, 0x0062);
+ reg_val &= 0x8FFF;
+ reg_val |= set_reg_value(divider_scaler);
+ reg_val |= 0x00C0;
+ Afe_write(state, 0x0062, reg_val);
+ /*register CMN_DIAG_HSCLK_SEL */
+ reg_val = Afe_read(state, 0x01E0);
+ reg_val &= 0xFF00;
+ reg_val |= (cmnda_hs_clk_0_sel.value >> 1) << 0;
+ reg_val |= (cmnda_hs_clk_1_sel.value >> 1) << 4;
+ Afe_write(state, 0x01E0, reg_val);
+ /*register XCVR_DIAG_HSCLK_SEL */
+ for (k = 0; k < num_lanes; k++) {
+ reg_val = Afe_read(state, 0x40E1 | (k << 9));
+ reg_val &= 0xCFFF;
+ reg_val |= (cmnda_hs_clk_0_sel.value >> 1) << 12;
+ Afe_write(state, 0x40E1 | (k << 9), reg_val);
+ }
+ /* register TX_DIAG_TX_CTRL */
+ for (k = 0; k < num_lanes; k++) {
+ reg_val = Afe_read(state, 0x41E0 | (k << 9));
+ reg_val &= 0xFF3F;
+ reg_val |= (tx_subrate.value >> 1) << 6;
+ Afe_write(state, 0x41E0 | (k << 9), reg_val);
+ }
+ /* register CMN_PLLSM0_USER_DEF_CTRL */
+ reg_val = set_reg_value(vco_ring_select);
+ Afe_write(state, 0x002F, reg_val);
+ /* register CMN_DIAG_PLL0_OVRD */
+ Afe_write(state, 0x01C2, 0x0000);
+ /* register CMN_DIAG_PLL0_V2I_TUNE */
+ reg_val = set_reg_value(voltage_to_current_coarse);
+ reg_val |= set_reg_value(voltage_to_current);
+ Afe_write(state, 0x01C5, reg_val);
+ /* register CMN_DIAG_PLL0_PTATIS_TUNE1 */
+ reg_val = set_reg_value(pmos_ctrl);
+ reg_val |= set_reg_value(ndac_ctrl);
+ Afe_write(state, 0x01C8, reg_val);
+ /* register CMN_DIAG_PLL0_PTATIS_TUNE2 */
+ reg_val = set_reg_value(ptat_ndac_ctrl);
+ Afe_write(state, 0x01C9, reg_val);
+ /* register CMN_DIAG_PLL0_CP_TUNE */
+ reg_val = set_reg_value(charge_pump_gain);
+ Afe_write(state, 0x01C6, reg_val);
+ /* register CMN_DIAG_PLL0_LF_PROG */
+ Afe_write(state, 0x01C7, 0x0008);
+ /* register XCVR_DIAG_PLLDRC_CTRL */
+ for (k = 0; k < num_lanes; k++) {
+ reg_val = Afe_read(state, 0x40E0 | (k << 9));
+ reg_val &= 0xBFFF;
+ Afe_write(state, 0x40E0 | (k << 9), reg_val);
+ }
+ if (pixel_clk_from_phy == 1) {
+ /* register CMN_DIAG_PLL0_PXL_DIVL */
+ reg_val = set_reg_value(cmnda_pll0_pxdiv_low);
+ Afe_write(state, 0x01CC, reg_val);
+ /* register CMN_DIAG_PLL0_PXL_DIVH */
+ reg_val = set_reg_value(cmnda_pll0_pxdiv_high);
+ reg_val |= (1 << 15);
+ Afe_write(state, 0x01CB, reg_val);
+
+ /* register CMN_PLL0_VCOCAL_START */
+ reg_val = Afe_read(state, 0x0081);
+ reg_val &= 0xFE00;
+ reg_val |= set_reg_value(vco_cal_code);
+ Afe_write(state, 0x0081, reg_val);
+ }
+
+ /* Back to task phy_cfg_hdp */
+
+ /* register PHY_PMA_CMN_CTRL1 */
+ reg_val = Afe_read(state, 0xC800);
+ reg_val &= 0xFF8F;
+ /* for single ended reference clock
+ * on the cmn_ref_clk_int pin: PHY_PMA_CMN_CTRL1[6:4]=3'b011 */
+ /* for differential clock on the refclk_p and
+ * refclk_m off chip pins: PHY_PMA_CMN_CTRL1[6:4]=3'b000 */
+ reg_val |= 0x0000;
+ Afe_write(state, 0xC800, reg_val);
+
+ /*register CMN_DIAG_ACYA */
+ /* for differential clock on the refclk_p and
+ * refclk_m off chip pins: CMN_DIAG_ACYA[8]=1'b1 */
+ Afe_write(state, 0x01FF, 0x0100);
+
+ if (phy_reset_workaround) {
+ /* register PHY_ISO_CMN_CTRL */
+ /* Deassert PHY reset */
+ Afe_write(state, 0xC010, 0x0001);
+ /* register PHY_PMA_ISO_CMN_CTRL */
+ Afe_write(state, 0xC810, 0x0003);
+ for (k = 0; k < num_lanes; k++) {
+ /* register XCVR_PSM_RCTRL */
+ Afe_write(state, 0x4001 | (k << 9), 0xFEFC);
+ }
+ /* register PHY_PMA_ISO_CMN_CTRL */
+ /* Assert cmn_macro_pwr_en */
+ Afe_write(state, 0xC810, 0x0013);
+
+ /* PHY_PMA_ISO_CMN_CTRL */
+ /* wait for cmn_macro_pwr_en_ack */
+ while (!(Afe_read(state, 0xC810) & (1 << 5)));
+
+ /* PHY_PMA_CMN_CTRL1 */
+ /* wait for cmn_ready */
+ while (!(Afe_read(state, 0xC800) & (1 << 0)));
+ } else {
+ for (k = 0; k < num_lanes; k++)
+ /* register XCVR_PSM_RCTRL */
+ Afe_write(state, 0x4001 | (k << 9), 0xBEFC);
+ }
+ for (k = 0; k < num_lanes; k++) {
+ /* register TX_PSC_A0 */
+ Afe_write(state, 0x4100 | (k << 9), 0x6791);
+ /* register TX_PSC_A1 */
+ Afe_write(state, 0x4101 | (k << 9), 0x6790);
+ /* register TX_PSC_A2 */
+ Afe_write(state, 0x4102 | (k << 9), 0x0090);
+ /* register TX_PSC_A3 */
+ Afe_write(state, 0x4103 | (k << 9), 0x0090);
+ /* register RX_PSC_CAL */
+ reg_val = Afe_read(state, 0x8006 | (k << 9));
+ reg_val &= 0xFFBB;
+ Afe_write(state, 0x8006 | (k << 9), reg_val);
+ /* register RX_PSC_A0 */
+ reg_val = Afe_read(state, 0x8000 | (k << 9));
+ reg_val &= 0xFFBB;
+ Afe_write(state, 0x8000 | (k << 9), reg_val);
+ }
+
+ /* register PHY_HDP_MODE_CTL */
+ Afe_write(state, 0xC008, 0x0004);
+
+ return character_freq_khz;
+}
+
+int hdmi_tx_t28hpc_power_config_seq(state_struct *state, int num_lanes)
+{
+ unsigned char k;
+
+ /* Configure the power state.
+ * register TX_DIAG_ACYA */
+ for (k = 0; k < num_lanes; k++) {
+ /* register XCVR_PSM_CAL_TMR */
+ Afe_write(state, 0x41FF | (k << 9), 0x0001);
+ }
+
+ /* register PHY_DP_MODE_CTL */
+ while (!(Afe_read(state, 0xC008) & (1 << 6)));
+
+ imx_arc_power_up(state);
+ imx_arc_calibrate(state);
+ imx_arc_config(state);
+
+ /* PHY_DP_MODE_CTL */
+ Afe_write(state, 0xC008, (((0x0F << num_lanes) & 0x0F) << 12) | 0x0101);
+
+ /* PHY_DP_MODE_CTL */
+ while (!(Afe_read(state, 0xC008) & (1 << 4)));
+
+ return 0;
+}
diff --git a/drivers/gpu/drm/imx/hdp/API_AFE_t28hpc_hdmitx.h b/drivers/gpu/drm/imx/hdp/API_AFE_t28hpc_hdmitx.h
new file mode 100644
index 000000000000..9475fab164c2
--- /dev/null
+++ b/drivers/gpu/drm/imx/hdp/API_AFE_t28hpc_hdmitx.h
@@ -0,0 +1,60 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2016-2017 Cadence Design Systems, Inc.
+ * All rights reserved worldwide.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 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.
+ *
+ * Copyright 2017-2018 NXP
+ *
+ ******************************************************************************
+ *
+ * API_AFE_t28hpc_hdmitx.h
+ *
+ ******************************************************************************
+ */
+
+#ifndef API_AFE_T28HPC_HDMITX_H_
+#define API_AFE_T28HPC_HDMITX_H_
+
+#include <linux/types.h>
+#include <linux/string.h>
+#include <linux/io.h>
+
+#include "../../../../mxc/hdp/all.h"
+
+int phy_cfg_hdp_t28hpc(state_struct *state, int num_lanes, struct drm_display_mode *mode, int bpp,
+ VIC_PXL_ENCODING_FORMAT format, bool pixel_clk_from_phy);
+int hdmi_tx_t28hpc_power_config_seq(state_struct *state, int num_lanes);
+
+#endif
diff --git a/drivers/gpu/drm/imx/hdp/Kconfig b/drivers/gpu/drm/imx/hdp/Kconfig
new file mode 100644
index 000000000000..098a1a99a70f
--- /dev/null
+++ b/drivers/gpu/drm/imx/hdp/Kconfig
@@ -0,0 +1,19 @@
+config DRM_IMX_HDP
+ tristate "IMX8 HD Display Controller"
+ select DRM_IMX
+ select MX8_HDP
+ select DRM_KMS_HELPER
+ select VIDEOMODE_HELPERS
+ select DRM_GEM_CMA_HELPER
+ select DRM_KMS_CMA_HELPER
+ select DRM_PANEL
+ help
+ Choose this if you want to use DP/HDMI on i.MX8.
+
+config IMX_HDP_CEC
+ bool "Enable IMX HDP CEC support"
+ depends on DRM_IMX_HDP && MEDIA_CEC_SUPPORT
+ select CEC_CORE
+ ---help---
+ When selected the imx hdmi will support the optional
+ HDMI CEC feature.
diff --git a/drivers/gpu/drm/imx/hdp/Makefile b/drivers/gpu/drm/imx/hdp/Makefile
new file mode 100644
index 000000000000..84c7267642fc
--- /dev/null
+++ b/drivers/gpu/drm/imx/hdp/Makefile
@@ -0,0 +1,9 @@
+obj-$(CONFIG_DRM_IMX_HDP) += imx-hdp.o \
+ imx-dp.o imx-hdmi.o imx-arc.o imx-hdcp.o\
+ API_AFE_ss28fdsoi_kiran_hdmitx.o \
+ API_AFE_t28hpc_hdmitx.o \
+ ss28fdsoi_hdmitx_table.o \
+ t28hpc_hdmitx_table.o \
+ API_AFE_mcu1_dp.o \
+ API_AFE_mcu2_dp.o \
+ imx-hdp-audio.o
diff --git a/drivers/gpu/drm/imx/hdp/hdmitx_firmware.h b/drivers/gpu/drm/imx/hdp/hdmitx_firmware.h
new file mode 100644
index 000000000000..e62f9523de00
--- /dev/null
+++ b/drivers/gpu/drm/imx/hdp/hdmitx_firmware.h
@@ -0,0 +1,77 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2016-2017 Cadence Design Systems, Inc.
+ * All rights reserved worldwide.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 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.
+ *
+ ******************************************************************************
+ *
+ * This file was auto-generated from dram0.data and iram0.data firmware images
+ * Do not edit it manually.
+ *
+ ******************************************************************************
+ *
+ * hdmitx_firmware.c
+ *
+ ******************************************************************************
+ */
+#include <linux/io.h>
+
+static u32 const hdmitx_iram0[] = {
+ 0x00000000,
+};
+
+static u32 const hdmitx_dram0[] = {
+ 0x00000000,
+};
+
+u32 const *hdmitx_iram0_get_ptr(void)
+{
+ return (u32 const *)hdmitx_iram0;
+}
+
+u32 const *hdmitx_dram0_get_ptr(void)
+{
+ return (u32 const *)hdmitx_dram0;
+}
+
+size_t hdmitx_iram0_get_size(void)
+{
+ return sizeof(hdmitx_iram0);
+}
+
+size_t hdmitx_dram0_get_size(void)
+{
+ return sizeof(hdmitx_dram0);
+}
diff --git a/drivers/gpu/drm/imx/hdp/imx-arc.c b/drivers/gpu/drm/imx/hdp/imx-arc.c
new file mode 100644
index 000000000000..be94437598cb
--- /dev/null
+++ b/drivers/gpu/drm/imx/hdp/imx-arc.c
@@ -0,0 +1,103 @@
+/*
+ * Copyright 2018 NXP
+ *
+ * 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 "imx-hdp.h"
+
+void imx_arc_power_up(state_struct *state)
+{
+ DRM_DEBUG("arc_power_up()\n");
+
+ /* register CMN_RXCAL_OVRD */
+ Afe_write(state, 0x5025, 0x0001);
+}
+
+void imx_arc_calibrate(state_struct *state)
+{
+ u16 txpu_calib_code;
+ u16 txpd_calib_code;
+ u16 txpu_adj_calib_code;
+ u16 txpd_adj_calib_code;
+ u16 prev_calib_code;
+ u16 new_calib_code;
+ u16 rdata;
+
+ DRM_DEBUG("aux_cal_cfg() ARC programming\n");
+ /* register TX_DIG_CTRL_REG_2 */
+ prev_calib_code = Afe_read(state, 0x5024);
+ /* register CMN_TXPUCAL_CTRL */
+ txpu_calib_code = Afe_read(state, 0x00E0);
+ /* register CMN_TXPDCAL_CTRL */
+ txpd_calib_code = Afe_read(state, 0x00F0);
+ /* register CMN_TXPU_ADJ_CTRL */
+ txpu_adj_calib_code = Afe_read(state, 0x0108);
+ /* register CMN_TXPD_ADJ_CTRL */
+ txpd_adj_calib_code = Afe_read(state, 0x010c);
+
+ new_calib_code = ((txpu_calib_code + txpd_calib_code) / 2)
+ + txpu_adj_calib_code + txpd_adj_calib_code;
+
+ if (new_calib_code != prev_calib_code) {
+ /* register TX_ANA_CTRL_REG_1 */
+ rdata = Afe_read(state, 0x5020);
+ rdata &= 0xDFFF;
+ /* register TX_ANA_CTRL_REG_1 */
+ Afe_write(state, 0x5020, rdata);
+ /* register TX_DIG_CTRL_REG_2 */
+ Afe_write(state, 0x5024, new_calib_code);
+ mdelay(10);
+ rdata |= 0x2000;
+ /* register TX_ANA_CTRL_REG_1 */
+ Afe_write(state, 0x5020, rdata);
+ udelay(150);
+ }
+}
+
+void imx_arc_config(state_struct *state)
+{
+ DRM_DEBUG("arc_config() ARC programming\n");
+
+ /* register TX_ANA_CTRL_REG_2 */
+ Afe_write(state, 0x5021, 0x0100);
+ udelay(100);
+ /* register TX_ANA_CTRL_REG_2 */
+ Afe_write(state, 0x5021, 0x0300);
+ udelay(100);
+ /* register TX_ANA_CTRL_REG_3 */
+ Afe_write(state, 0x5026, 0x0000);
+ udelay(100);
+ /* register TX_ANA_CTRL_REG_1 */
+ Afe_write(state, 0x5020, 0x2008);
+ udelay(100);
+ /* register TX_ANA_CTRL_REG_1 */
+ Afe_write(state, 0x5020, 0x2018);
+ udelay(100);
+ /* register TX_ANA_CTRL_REG_1 */
+ Afe_write(state, 0x5020, 0x2098);
+ /* register TX_ANA_CTRL_REG_2 */
+ Afe_write(state, 0x5021, 0x030C);
+ /* register TX_ANA_CTRL_REG_5 */
+ Afe_write(state, 0x5029, 0x0010);
+ udelay(100);
+ /* register TX_ANA_CTRL_REG_4 */
+ Afe_write(state, 0x5027, 0x4001);
+ mdelay(5);
+ /* register TX_ANA_CTRL_REG_1 */
+ Afe_write(state, 0x5020, 0x2198);
+ mdelay(5);
+ /* register TX_ANA_CTRL_REG_2 */
+ Afe_write(state, 0x5021, 0x030D);
+ udelay(100);
+ Afe_write(state, 0x5021, 0x030F);
+}
+
diff --git a/drivers/gpu/drm/imx/hdp/imx-dp.c b/drivers/gpu/drm/imx/hdp/imx-dp.c
new file mode 100644
index 000000000000..be7f92cc8620
--- /dev/null
+++ b/drivers/gpu/drm/imx/hdp/imx-dp.c
@@ -0,0 +1,661 @@
+/*
+ * Copyright 2017-2018 NXP
+ *
+ * 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/clk.h>
+#include <linux/kernel.h>
+#include <drm/drm_dp_helper.h>
+
+#ifdef DEBUG_FW_LOAD
+#include "mhdp_firmware.h"
+#endif
+
+#include "imx-hdp.h"
+#include "imx-hdmi.h"
+#include "imx-dp.h"
+
+int dp_phy_init(state_struct *state, struct drm_display_mode *mode, int format,
+ int color_depth)
+{
+ struct imx_hdp *hdp = state_to_imx_hdp(state);
+ int max_link_rate = hdp->link_rate;
+ int num_lanes = 4;
+ int ret;
+
+ /* reset phy */
+ imx_hdp_call(hdp, phy_reset, hdp->ipcHndl, NULL, 0);
+
+ /* PHY initialization while phy reset pin is active */
+ AFE_init(state, num_lanes, (ENUM_AFE_LINK_RATE)max_link_rate);
+ DRM_INFO("AFE_init\n");
+
+ /* In this point the phy reset should be deactivated */
+ imx_hdp_call(hdp, phy_reset, hdp->ipcHndl, NULL, 1);
+ DRM_INFO("deasserted reset\n");
+
+ /* PHY power set */
+ AFE_power(state, num_lanes, (ENUM_AFE_LINK_RATE)max_link_rate);
+ DRM_INFO("AFE_power exit\n");
+
+ /* Video off */
+ ret = CDN_API_DPTX_SetVideo_blocking(state, 0);
+ DRM_INFO("CDN_API_DPTX_SetVideo_blocking (ret = %d)\n", ret);
+
+ return true;
+}
+
+#ifdef DEBUG
+
+void print_header(void)
+{
+ /* "0x00000000: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f"*/
+ DRM_INFO(" : 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f\n"
+ );
+ DRM_INFO("-----------------------------------------------------------\n"
+ );
+}
+
+static void print_bytes(unsigned int addr, unsigned char *buf, unsigned int size)
+{
+ int i, index = 0;
+ char line[160];
+
+ if (((size + 11) * 3) > sizeof(line))
+ return;
+
+ index += sprintf(line, "0x%08x:", addr);
+ for (i = 0; i < size; i++)
+ index += sprintf(&line[index], " %02x", buf[i]);
+ DRM_INFO("%s\n", line);
+
+}
+
+static int dump_dpcd(state_struct *state)
+{
+ int ret;
+
+ DPTX_Read_DPCD_response resp_dpcd;
+
+ print_header();
+
+ ret = CDN_API_DPTX_Read_DPCD_blocking(state, 0x10, 0x0, &resp_dpcd,
+ CDN_BUS_TYPE_APB);
+ if (ret) {
+ DRM_INFO("_debug: function returned with status %d\n", ret);
+ return -1;
+ }
+ print_bytes(resp_dpcd.addr, resp_dpcd.buff, resp_dpcd.size);
+
+ ret = CDN_API_DPTX_Read_DPCD_blocking(state, 0x10, 0x100, &resp_dpcd,
+ CDN_BUS_TYPE_APB);
+ if (ret) {
+ DRM_INFO("_debug: function returned with status %d\n", ret);
+ return -1;
+ }
+ print_bytes(resp_dpcd.addr, resp_dpcd.buff, resp_dpcd.size);
+
+ ret = CDN_API_DPTX_Read_DPCD_blocking(state, 0x10, 0x110, &resp_dpcd,
+ CDN_BUS_TYPE_APB);
+ if (ret) {
+ DRM_INFO("_debug: function returned with status %d\n", ret);
+ return -1;
+ }
+ print_bytes(resp_dpcd.addr, resp_dpcd.buff, resp_dpcd.size);
+
+ ret = CDN_API_DPTX_Read_DPCD_blocking(state, 0x10, 0x200, &resp_dpcd,
+ CDN_BUS_TYPE_APB);
+ if (ret) {
+ DRM_INFO("_debug: function returned with status %d\n", ret);
+ return -1;
+ }
+ print_bytes(resp_dpcd.addr, resp_dpcd.buff, resp_dpcd.size);
+
+ ret = CDN_API_DPTX_Read_DPCD_blocking(state, 0x10, 0x210, &resp_dpcd,
+ CDN_BUS_TYPE_APB);
+ if (ret) {
+ DRM_INFO("_debug: function returned with status %d\n", ret);
+ return -1;
+ }
+ print_bytes(resp_dpcd.addr, resp_dpcd.buff, resp_dpcd.size);
+
+ ret = CDN_API_DPTX_Read_DPCD_blocking(state, 0x10, 0x220, &resp_dpcd,
+ CDN_BUS_TYPE_APB);
+ if (ret) {
+ DRM_INFO("_debug: function returned with status %d\n", ret);
+ return -1;
+ }
+ print_bytes(resp_dpcd.addr, resp_dpcd.buff, resp_dpcd.size);
+
+ ret = CDN_API_DPTX_Read_DPCD_blocking(state, 0x10, 0x700, &resp_dpcd,
+ CDN_BUS_TYPE_APB);
+ if (ret) {
+ DRM_INFO("_debug: function returned with status %d\n", ret);
+ return -1;
+ }
+ print_bytes(resp_dpcd.addr, resp_dpcd.buff, resp_dpcd.size);
+
+ ret = CDN_API_DPTX_Read_DPCD_blocking(state, 0x10, 0x710, &resp_dpcd,
+ CDN_BUS_TYPE_APB);
+ if (ret) {
+ DRM_INFO("_debug: function returned with status %d\n", ret);
+ return -1;
+ }
+ print_bytes(resp_dpcd.addr, resp_dpcd.buff, resp_dpcd.size);
+
+ ret = CDN_API_DPTX_Read_DPCD_blocking(state, 0x10, 0x720, &resp_dpcd,
+ CDN_BUS_TYPE_APB);
+ if (ret) {
+ DRM_INFO("_debug: function returned with status %d\n", ret);
+ return -1;
+ }
+ print_bytes(resp_dpcd.addr, resp_dpcd.buff, resp_dpcd.size);
+
+ ret = CDN_API_DPTX_Read_DPCD_blocking(state, 0x10, 0x730, &resp_dpcd,
+ CDN_BUS_TYPE_APB);
+ if (ret) {
+ DRM_INFO("_debug: function returned with status %d\n", ret);
+ return -1;
+ }
+
+ print_bytes(resp_dpcd.addr, resp_dpcd.buff, resp_dpcd.size);
+ return 0;
+}
+#endif
+
+static bool dp_check_link_status(state_struct *state, u8 num_lanes)
+{
+ u8 link_status[DP_LINK_STATUS_SIZE];
+ DPTX_Read_DPCD_response read_resp;
+ CDN_API_STATUS status;
+
+ status = CDN_API_DPTX_Read_DPCD_blocking(state,
+ DP_LINK_STATUS_SIZE,
+ DP_LANE0_1_STATUS,
+ &read_resp,
+ CDN_BUS_TYPE_APB);
+
+ memcpy(link_status, read_resp.buff, DP_LINK_STATUS_SIZE);
+
+ if (status != CDN_OK) {
+ return false;
+ }
+
+ DRM_DEBUG("link status 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n",
+ link_status[0],link_status[1],link_status[2],
+ link_status[3],link_status[4],link_status[5]);
+
+ /* if link training is requested we should perform it always */
+ return drm_dp_channel_eq_ok(link_status, num_lanes);
+}
+
+static int dp_get_training_status(state_struct *state)
+{
+ uint32_t evt;
+ uint8_t eventId;
+ uint8_t HPDevents;
+
+ do {
+ do {
+ CDN_API_Get_Event(state, &evt);
+ if (evt != 0)
+ DRM_DEBUG("_Get_Event %d\n", evt);
+ } while ((evt & 2) == 0);
+ CDN_API_DPTX_ReadEvent_blocking(state, &eventId, &HPDevents);
+ DRM_DEBUG("ReadEvent ID = %d HPD = %d\n", eventId, HPDevents);
+
+ switch (eventId) {
+ case 0x01:
+ DRM_INFO("INFO: Full link training started\n");
+ break;
+ case 0x02:
+ DRM_INFO("INFO: Fast link training started\n");
+ break;
+ case 0x04:
+ DRM_INFO("INFO: Clock recovery phase finished\n");
+ break;
+ case 0x08:
+ DRM_INFO("INFO: Channel equalization phase finished (this is last part meaning training finished)\n");
+ break;
+ case 0x10:
+ DRM_INFO("INFO: Fast link training finished\n");
+ break;
+ case 0x20:
+ DRM_INFO("ERROR: Clock recovery phase failed\n");
+ return -1;
+ case 0x40:
+ DRM_INFO("ERROR: Channel equalization phase failed\n");
+ return -1;
+ case 0x80:
+ DRM_INFO("ERROR: Fast link training failed\n");
+ return -1;
+ default:
+ DRM_INFO("ERROR: Invalid ID:%x\n", eventId);
+ return -1;
+ }
+ } while (eventId != 0x08 && eventId != 0x10);
+
+ return 0;
+}
+
+#define aux_to_hdp(x) container_of(x, struct imx_hdp, aux)
+
+/*
+ * This function only implements native DPDC reads and writes
+ */
+static ssize_t dp_aux_transfer(struct drm_dp_aux *aux,
+ struct drm_dp_aux_msg *msg)
+{
+ struct imx_hdp *hdp = aux_to_hdp(aux);
+ bool native = msg->request & (DP_AUX_NATIVE_WRITE & DP_AUX_NATIVE_READ);
+ CDN_API_STATUS status;
+
+ DRM_DEBUG("\n");
+ DRM_INFO("%s() msg->request 0x%x msg->size 0x%x\n",
+ __func__, msg->request, (unsigned int)msg->size);
+
+
+ /* 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;
+ }
+
+ if (!native) {
+ pr_err("%s: only native messages supported\n",
+ __func__);
+ return -EINVAL;
+ }
+
+ /* msg sanity check */
+ if (msg->size > DP_AUX_MAX_PAYLOAD_BYTES) {
+ pr_err("%s: invalid msg: size(%zu), request(%x)\n",
+ __func__, msg->size, (unsigned int)msg->request);
+ return -EINVAL;
+ }
+
+ if (msg->request == DP_AUX_NATIVE_WRITE) {
+ DPTX_Write_DPCD_response write_resp;
+
+ status = CDN_API_DPTX_Write_DPCD_blocking(&hdp->state,
+ msg->size,
+ msg->address,
+ (u8 *)msg->buffer,
+ &write_resp,
+ CDN_BUS_TYPE_APB);
+
+ if (status != CDN_OK)
+ return -EIO;
+ /* fixme: is this right? */
+ //return msg->size;
+ }
+
+ if (msg->request == DP_AUX_NATIVE_READ) {
+ DPTX_Read_DPCD_response read_resp;
+
+ status = CDN_API_DPTX_Read_DPCD_blocking(&hdp->state,
+ msg->size,
+ msg->address,
+ &read_resp,
+ CDN_BUS_TYPE_APB);
+ if (status != CDN_OK)
+ return -EIO;
+ memcpy(msg->buffer, read_resp.buff, read_resp.size);
+ msg->reply = DP_AUX_NATIVE_REPLY_ACK;
+#ifdef DEBUG
+ print_bytes(read_resp.addr, read_resp.buff, read_resp.size);
+#endif
+ return read_resp.size;
+ }
+ return 0;
+}
+
+/* Max Link Rate: 06h (1.62Gbps), 0Ah (2.7Gbps), 14h (5.4Gbps),
+ * 1Eh (8.1Gbps)--N/A
+ */
+void dp_mode_set(state_struct *state,
+ struct drm_display_mode *mode,
+ int format,
+ int color_depth,
+ int max_link_rate)
+{
+ struct imx_hdp *hdp = state_to_imx_hdp(state);
+ int ret;
+ u8 training_retries = 10, training_restarts = 10;
+ /* Set Host capabilities */
+ /* Number of lanes and SSC */
+ u8 num_lanes = 4;
+ u8 ssc = 0;
+ u8 scrambler = 0;
+ /* Max voltage swing */
+ u8 max_vswing = 3;
+ u8 force_max_vswing = 0;
+ /* Max pre-emphasis */
+ u8 max_preemph = 2;
+ u8 force_max_preemph = 0;
+ /* Supported test patterns mask */
+ u8 supp_test_patterns = 0x0F;
+ /* AUX training? */
+ u8 no_aux_training = 0;
+ /* Lane mapping */
+ u8 lane_mapping = hdp->dp_lane_mapping;
+ /* Extended Host capabilities */
+ u8 ext_host_cap = 1;
+ /* Bits per sub-pixel */
+ u8 bits_per_subpixel = 8;
+ /* Stereoscopic video */
+ STEREO_VIDEO_ATTR stereo = 0;
+ /* B/W Balance Type: 0 no data, 1 IT601, 2 ITU709 */
+ BT_TYPE bt_type = 0;
+ /* Transfer Unit */
+ u8 transfer_unit = 64;
+ VIC_SYMBOL_RATE sym_rate;
+ u8 link_rate = RATE_1_6;
+ struct drm_dp_link link;
+
+#ifdef DEBUG
+ S_LINK_STAT rls;
+#endif
+ char linkid[6];
+
+ DRM_INFO("dp_mode_set()\n");
+
+ ret = drm_dp_downstream_id(&hdp->aux, linkid);
+ if (ret < 0) {
+ DRM_INFO("Failed to Get DP link ID: %d\n", ret);
+ return;
+ }
+ DRM_INFO("DP link id: %s, 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
+ linkid, linkid[0], linkid[1], linkid[2], linkid[3], linkid[4],
+ linkid[5]);
+
+ /* Check dp link */
+ ret = drm_dp_link_probe(&hdp->aux, &link);
+ if (ret < 0) {
+ DRM_INFO("Failed to probe DP link: %d\n", ret);
+ return;
+ }
+ DRM_INFO("DP revision: 0x%x\n", link.revision);
+ DRM_INFO("DP rate: %d Mbps\n", link.rate/100);
+ DRM_INFO("DP number of lanes: %d\n", link.num_lanes);
+ DRM_INFO("DP capabilities: 0x%lx\n", link.capabilities);
+
+ /* always use the number of lanes from the display*/
+ num_lanes = link.num_lanes;
+
+ /* Use the lower link rate if dp_link_rate is set */
+ if (hdp->dp_link_rate != 0) {
+ link_rate = min(hdp->dp_link_rate,
+ (u32)(drm_dp_link_rate_to_bw_code(link.rate)));
+ DRM_INFO("DP actual link rate: 0x%x\n", link_rate);
+ hdp->link_rate = link_rate;
+
+ /* need change the link rate */
+ hdp->ops->phy_init(state,
+ mode,
+ format,
+ color_depth);
+ }
+
+ if (hdp->is_edp) {
+ /* use the eDP supported rates */
+ switch (link_rate) {
+ case AFE_LINK_RATE_1_6:
+ sym_rate = RATE_1_6;
+ break;
+ case AFE_LINK_RATE_2_1:
+ sym_rate = RATE_2_1;
+ break;
+ case AFE_LINK_RATE_2_4:
+ sym_rate = RATE_2_4;
+ break;
+ case AFE_LINK_RATE_2_7:
+ sym_rate = RATE_2_7;
+ break;
+ case AFE_LINK_RATE_3_2:
+ sym_rate = RATE_3_2;
+ break;
+ case AFE_LINK_RATE_4_3:
+ sym_rate = RATE_4_3;
+ break;
+ case AFE_LINK_RATE_5_4:
+ sym_rate = RATE_5_4;
+ break;
+ /*case AFE_LINK_RATE_8_1: sym_rate = RATE_8_1; break; */
+ default:
+ sym_rate = RATE_1_6;
+ }
+ } else {
+ switch (link_rate) {
+ case 0x0a:
+ sym_rate = RATE_2_7;
+ break;
+ case 0x14:
+ sym_rate = RATE_5_4;
+ break;
+ default:
+ sym_rate = RATE_1_6;
+ }
+ }
+
+ ret = CDN_API_DPTX_SetHostCap_blocking(state,
+ link_rate,
+ (num_lanes & 0x7) | ((ssc & 1) << 3) | ((scrambler & 1) << 4),
+ (max_vswing & 0x3) | ((force_max_vswing & 1) << 4),
+ (max_preemph & 0x3) | ((force_max_preemph & 1) << 4),
+ supp_test_patterns,
+ no_aux_training, /* fast link training */
+ lane_mapping,
+ ext_host_cap
+ );
+ DRM_INFO("CDN_API_DPTX_SetHostCap_blocking (ret = %d)\n", ret);
+
+ ret = CDN_API_DPTX_Set_VIC_blocking(state,
+ mode,
+ bits_per_subpixel,
+ num_lanes,
+ sym_rate,
+ format,
+ stereo,
+ bt_type,
+ transfer_unit
+ );
+ DRM_INFO("CDN_API_DPTX_Set_VIC_blocking (ret = %d)\n", ret);
+
+ training_restarts=5;
+ do {
+
+ do {
+ ret = CDN_API_DPTX_TrainingControl_blocking(state, 1);
+ DRM_INFO("CDN_API_DPTX_TrainingControl_* (ret = %d) start\n",
+ ret);
+ if ((dp_get_training_status(state) == 0) /*&&
+ dp_check_link_status(state, num_lanes)*/)
+ break;
+ training_retries--;
+
+ ret = CDN_API_DPTX_TrainingControl_blocking(state, 0);
+ DRM_INFO("CDN_API_DPTX_TrainingControl_* (ret = %d) stop\n",
+ ret);
+ udelay(1000);
+
+ } while (training_retries > 0);
+
+ udelay(1000);
+
+ if (dp_check_link_status(state, num_lanes) == true) {
+ DRM_INFO("Link is good - Training complete\n");
+ break;
+ } else {
+ DRM_INFO("Link is bad - need to restart training\n");
+ training_restarts--;
+ training_retries = 20;
+
+ ret = CDN_API_DPTX_TrainingControl_blocking(state, 0);
+ DRM_INFO("CDN_API_DPTX_TrainingControl_* (ret = %d) stop\n",
+ ret);
+ udelay(1000);
+ }
+
+
+ } while (training_restarts > 0);
+
+ DRM_INFO("dp_check_link_status %d\n", dp_check_link_status(state, num_lanes));
+
+ /* Set video on */
+ ret = CDN_API_DPTX_SetVideo_blocking(state, 1);
+ DRM_INFO("CDN_API_DPTX_SetVideo_blocking (ret = %d)\n", ret);
+
+ udelay(1000);
+
+#ifdef DEBUG
+ ret = CDN_API_DPTX_ReadLinkStat_blocking(state, &rls);
+ DRM_INFO("INFO: Get Read Link Status (ret = %d resp: rate: %d, lanes: %d, vswing 0..3: %d %d %d, preemp 0..3: %d %d %d\n",
+ ret, rls.rate, rls.lanes,
+ rls.swing[0], rls.swing[1], rls.swing[2],
+ rls.preemphasis[0], rls.preemphasis[1],
+ rls.preemphasis[2]);
+ dump_dpcd(state);
+#endif
+}
+
+int dp_get_edid_block(void *data, u8 *buf, unsigned int block, size_t len)
+{
+ DPTX_Read_EDID_response edidResp;
+ state_struct *state = data;
+ CDN_API_STATUS ret = CDN_ERROR_NOT_SUPPORTED;
+
+ if (buf == NULL) {
+ return -EINVAL;
+ }
+
+ memset(&edidResp, 0, sizeof(edidResp));
+ switch (block) {
+ case 0:
+ ret = CDN_API_DPTX_Read_EDID_blocking(state, 0, 0, &edidResp);
+ break;
+ case 1:
+ ret = CDN_API_DPTX_Read_EDID_blocking(state, 0, 1, &edidResp);
+ break;
+ case 2:
+ ret = CDN_API_DPTX_Read_EDID_blocking(state, 1, 0, &edidResp);
+ break;
+ case 3:
+ ret = CDN_API_DPTX_Read_EDID_blocking(state, 1, 1, &edidResp);
+ break;
+ default:
+ DRM_WARN("EDID block %x read not support\n", block);
+ }
+
+ DRM_INFO("dp_get_edid_block (ret = %d) block %d\n", ret, block);
+ if (ret == CDN_OK) {
+ memcpy(buf, edidResp.buff, 128);
+ return 0;
+ }
+
+ memset(buf, 0, 128);
+ return -EIO;
+}
+
+int dp_get_hpd_state(state_struct *state, u8 *hpd)
+{
+ int ret;
+
+ ret = CDN_API_DPTX_GetHpdStatus_blocking(state, hpd);
+ return ret;
+}
+
+void dp_phy_pix_engine_reset_t28hpc(state_struct *state)
+{
+ GENERAL_Read_Register_response regresp;
+
+ CDN_API_General_Read_Register_blocking(state, ADDR_SOURCE_CAR +
+ (SOURCE_HDTX_CAR << 2),
+ &regresp);
+ CDN_API_General_Write_Register_blocking(state, ADDR_SOURCE_CAR +
+ (SOURCE_HDTX_CAR << 2),
+ regresp.val & 0xFD);
+ CDN_API_General_Write_Register_blocking(state, ADDR_SOURCE_CAR +
+ (SOURCE_HDTX_CAR << 2),
+ regresp.val);
+}
+
+
+int dp_phy_init_t28hpc(state_struct *state,
+ struct drm_display_mode *mode,
+ int format,
+ int color_depth)
+{
+ struct imx_hdp *hdp = state_to_imx_hdp(state);
+ int max_link_rate = hdp->link_rate;
+ int num_lanes = 4;
+ int ret;
+ u8 lane_mapping = hdp->dp_lane_mapping;
+
+ /* reset phy */
+ imx_hdp_call(hdp, phy_reset, 0, &hdp->mem, 0);
+ DRM_INFO("asserted HDP PHY reset\n");
+
+ dp_phy_pix_engine_reset_t28hpc(state);
+ DRM_INFO("pixel engine reset\n");
+
+ /* Line swaping */
+ CDN_API_General_Write_Register_blocking(state,
+ ADDR_SOURCD_PHY +
+ (LANES_CONFIG << 2),
+ 0x00400000 | lane_mapping);
+ DRM_INFO("CDN_*_Write_Register_blocking ... setting LANES_CONFIG %x\n",
+ lane_mapping);
+
+ /* PHY initialization while phy reset pin is active */
+ afe_init_t28hpc(state, num_lanes, (ENUM_AFE_LINK_RATE)max_link_rate);
+ DRM_INFO("AFE_init\n");
+
+ /* In this point the phy reset should be deactivated */
+ imx_hdp_call(hdp, phy_reset, 0, &hdp->mem, 1);
+ DRM_INFO("deasserted HDP PHY reset\n");
+
+ /* PHY power set */
+ afe_power_t28hpc(state, num_lanes, (ENUM_AFE_LINK_RATE)max_link_rate);
+ DRM_INFO("AFE_power exit\n");
+
+ /* Video off */
+ ret = CDN_API_DPTX_SetVideo_blocking(state, 0);
+ DRM_INFO("CDN_API_DPTX_SetVideo_blocking (ret = %d)\n", ret);
+
+ return true;
+}
+
+
+int dp_aux_init(state_struct *state,
+ struct device *dev)
+{
+ struct imx_hdp *hdp = state_to_imx_hdp(state);
+ int ret;
+
+ hdp->aux.name = "imx_dp_aux";
+ hdp->aux.dev = dev;
+ hdp->aux.transfer = dp_aux_transfer;
+
+ ret = drm_dp_aux_register(&hdp->aux);
+
+ return ret;
+}
+
+int dp_aux_destroy(state_struct *state)
+{
+ struct imx_hdp *hdp = state_to_imx_hdp(state);
+
+ drm_dp_aux_unregister(&hdp->aux);
+
+ return 0;
+}
diff --git a/drivers/gpu/drm/imx/hdp/imx-dp.h b/drivers/gpu/drm/imx/hdp/imx-dp.h
new file mode 100644
index 000000000000..83177b108bc7
--- /dev/null
+++ b/drivers/gpu/drm/imx/hdp/imx-dp.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2017-2018 NXP
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+#ifndef _IMX_DP_H_
+#define _IMX_DP_H_
+
+void dp_mode_set(state_struct *state,
+ struct drm_display_mode *mode,
+ int format, int color_depth,
+ int max_link_rate);
+int dp_phy_init(state_struct *state,
+ struct drm_display_mode *mode,
+ int format,
+ int color_depth);
+int dp_phy_init_t28hpc(state_struct *state,
+ struct drm_display_mode *mode,
+ int format,
+ int color_depth);
+int dp_get_edid_block(void *data, u8 *buf, u32 block, size_t len);
+int dp_get_hpd_state(state_struct *state, u8 *hpd);
+int dp_aux_init(state_struct *state, struct device *dev);
+
+#endif
diff --git a/drivers/gpu/drm/imx/hdp/imx-hdcp-private.h b/drivers/gpu/drm/imx/hdp/imx-hdcp-private.h
new file mode 100644
index 000000000000..a8aa12d8f865
--- /dev/null
+++ b/drivers/gpu/drm/imx/hdp/imx-hdcp-private.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2017-2019 NXP
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+#ifndef _IMX_HDCP_PRIVATE_H_
+#define _IMX_HDCP_PRIVATE_H_
+
+struct imx_hdcp {
+ struct mutex mutex;
+ u64 value; /* protected by hdcp_mutex */
+ struct delayed_work check_work;
+ struct work_struct prop_work;
+ u8 bus_type;
+ u8 config;
+};
+#endif
diff --git a/drivers/gpu/drm/imx/hdp/imx-hdcp.c b/drivers/gpu/drm/imx/hdp/imx-hdcp.c
new file mode 100644
index 000000000000..4f10737953d9
--- /dev/null
+++ b/drivers/gpu/drm/imx/hdp/imx-hdcp.c
@@ -0,0 +1,689 @@
+/*
+ * Copyright 2019 NXP
+ *
+ * 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 <drm/drmP.h>
+#include <drm/drm_hdcp.h>
+#include <linux/i2c.h>
+#include <linux/random.h>
+#include <linux/of_address.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include "imx-hdp.h"
+#include "imx-hdcp-private.h"
+
+static uint8_t recv_id[] = {
+ 0x8B, 0xA4, 0x47, 0x42, 0xFB
+};
+
+static uint8_t m[] = {
+ 0xF9, 0xF1, 0x30, 0xA8,
+ 0x2D, 0x5B, 0xE5, 0xC3,
+ 0xE1, 0x7A, 0xB0, 0xFD,
+ 0x0F, 0x54, 0x40, 0x52
+};
+
+static uint8_t km[] = {
+ 0xCA, 0x9F, 0x83, 0x95,
+ 0x70, 0xD0, 0xD0, 0xF9,
+ 0xCF, 0xE4, 0xEB, 0x54,
+ 0x7E, 0x09, 0xFA, 0x3B
+};
+
+static uint8_t ekhkm[] = {
+ 0xE6, 0x57, 0x8E, 0xBC,
+ 0xC7, 0x68, 0x44, 0x87,
+ 0x88, 0x8A, 0x9B, 0xD7,
+ 0xD6, 0xAE, 0x38, 0xBE
+};
+
+static char const *g_last_error[16] = {
+ "No Error",
+ "HPD is down",
+ "SRM failure",
+ "Signature verification error",
+ "h tag != h",
+ "V tag diff v",
+ "Locality check",
+ "DDC error",
+ "REAUTH_REQ",
+ "Topology error",
+ "Verify receiver ID list failed",
+ "HDCP_RSVD1 was not 0,0,0",
+ "HDMI capability or mode",
+ "RI result was different than expected",
+ "WatchDog expired",
+ "Repeater integrity failed"
+};
+
+static char const *g_rx_type[4] = {
+ "Unknown", "HDCP 1", "HDCP 2", "Unknown" };
+
+#define HDCP_MAX_RECEIVERS 32
+#define HDCP_RECEIVER_ID_SIZE_BYTES 5
+#define HPD_EVENT 1
+#define HDCP_STATUS_SIZE 0x5
+#define HDCP_PORT_STS_AUTH 0x1
+#define HDCP_PORT_STS_REPEATER 0x2
+#define HDCP_PORT_STS_REPEATER 0x2
+#define HDCP_PORT_STS_TYPE_MASK 0xc
+#define HDCP_PORT_STS_TYPE_SHIFT 0x2
+#define HDCP_PORT_STS_AUTH_STREAM_ID_SHIFT 0x4
+#define HDCP_PORT_STS_AUTH_STREAM_ID_MASK 0x10
+#define HDCP_PORT_STS_LAST_ERR_SHIFT 0x5
+#define HDCP_PORT_STS_LAST_ERR_MASK (0x0F << 5)
+#define GET_HDCP_PORT_STS_LAST_ERR(__sts__) \
+ (((__sts__) & HDCP_PORT_STS_LAST_ERR_MASK) >> \
+ HDCP_PORT_STS_LAST_ERR_SHIFT)
+#define HDCP_PORT_STS_1_1_FEATURES 0x200
+
+#define HDCP_DPCD_CERTRX_ADDRESS 0x6900B
+
+#define HDCP_CONFIG_NONE ((u8) 0)
+#define HDCP_CONFIG_1_4 ((u8) 1) /* use HDCP 1.4 only */
+#define HDCP_CONFIG_2_2 ((u8) 2) /* use HDCP 2.2 only */
+/* use All HDCP versions */
+#define HDCP_CONFIG_ALL (HDCP_CONFIG_1_4 | HDCP_CONFIG_2_2)
+
+static void imx_hdcp_print_port_status(uint16_t sts)
+{
+ DRM_DEBUG_KMS("INFO: HDCP Port Status: 0x%04x\n", sts);
+ DRM_DEBUG_KMS(" Authenticated: %d\n",
+ (bool)(sts & HDCP_PORT_STS_AUTH));
+ DRM_DEBUG_KMS(" Receiver is repeater: %d\n",
+ (bool)(sts & HDCP_PORT_STS_REPEATER));
+ DRM_DEBUG_KMS(" RX Type: %s\n",
+ g_rx_type[((sts & HDCP_PORT_STS_TYPE_MASK)
+ >> HDCP_PORT_STS_TYPE_SHIFT)]);
+ DRM_DEBUG_KMS(" AuthStreamId: %d\n",
+ (bool)(sts & HDCP_PORT_STS_AUTH_STREAM_ID_MASK));
+ DRM_DEBUG_KMS(" Last Error: %s\n",
+ g_last_error[((sts & HDCP_PORT_STS_LAST_ERR_MASK)
+ >> HDCP_PORT_STS_LAST_ERR_SHIFT)]);
+ DRM_DEBUG_KMS(" Enable 1.1 Features: %d\n",
+ (bool)(sts & HDCP_PORT_STS_1_1_FEATURES));
+}
+
+static unsigned int wait4event(struct imx_hdp *hdp,
+ unsigned int *events,
+ unsigned int event_to_wait)
+{
+ unsigned int reg_events;
+ unsigned int returned_events;
+ unsigned int event_mask = 1U << event_to_wait |
+ 1U << EVENT_ID_HDCPTX_STATUS;
+ int timeout = 50000; /* 50000 * 10 u is at least ~500 miliseconds */
+
+ while ((event_mask & *events) == 0) {
+ if (timeout-- == 0)
+ return 0;
+ udelay(10);
+ CDN_API_Get_Event(&hdp->state, &reg_events);
+ *events |= reg_events;
+ }
+
+ returned_events = *events & event_mask;
+ *events &= ~event_mask;
+ return returned_events;
+}
+
+static inline
+uint16_t imx_hdcp_get_port_status(u8 hdcp_status[HDCP_STATUS_SIZE])
+{
+ return (hdcp_status[0] << 8) | hdcp_status[1];
+}
+
+static u16 imx_hdcp_get_status(struct imx_hdp *hdp)
+{
+ CDN_BUS_TYPE bt = hdp->hdcp.bus_type;
+ u8 hdcp_status[HDCP_STATUS_SIZE];
+ u16 hdcp_port_status;
+
+ DRM_DEBUG_KMS("INFO: Reading HDCP TX status\n");
+ CDN_API_HDCP_TX_STATUS_REQ_blocking(&hdp->state, hdcp_status, bt);
+
+ hdcp_port_status = imx_hdcp_get_port_status(hdcp_status);
+
+ return hdcp_port_status;
+}
+
+static inline unsigned char check_event(unsigned int events,
+ unsigned int tested)
+{
+ if ((events & (1 << tested)) == 0)
+ return 0;
+ return 1;
+}
+
+/* Prints status. Returns error code (0 = no error) */
+static unsigned char imx_hdcp_handle_status(unsigned short status)
+{
+ imx_hdcp_print_port_status(status);
+ if (status & HDCP_PORT_STS_LAST_ERR_MASK)
+ DRM_ERROR("ERROR: HDCP error was set to %s\n",
+ g_last_error[((status & HDCP_PORT_STS_LAST_ERR_MASK)
+ >> HDCP_PORT_STS_LAST_ERR_SHIFT)]);
+ return GET_HDCP_PORT_STS_LAST_ERR(status);
+}
+
+static int imx_hdcp_set_config(struct imx_hdp *hdp, u8 hdcp_config)
+{
+ CDN_API_STATUS ret;
+ CDN_BUS_TYPE bt = hdp->hdcp.bus_type;
+ uint8_t apb_cfg_dpcd_sts = 0;
+ uint8_t apb_cfg_hdcp_sts = 0;
+ uint8_t apb_cfg_capb_sts = 0;
+ uint8_t hdcp_cfg;
+
+ unsigned int events = 0;
+ unsigned int retEvents;
+ unsigned short hdcp_port_status;
+
+ if (bt == CDN_BUS_TYPE_SAPB) {
+ DRM_DEBUG_KMS("INFO: Switching HDCP Commands to SAPB.\n");
+ ret = CDN_API_ApbConf_blocking
+ (&hdp->state,
+ 0, 0, /* set DPCD to APB (don't lock) */
+ 1, 0, /* set HDCP to SAPB (don't lock) */
+ 0, 0, /* set CAPB owner CPU (don't lock) */
+ &apb_cfg_dpcd_sts,
+ &apb_cfg_hdcp_sts,
+ &apb_cfg_capb_sts);
+
+ if (ret != CDN_OK) {
+ DRM_ERROR("Failed to set APB configuration.\n");
+ return -1;
+ }
+ if (apb_cfg_hdcp_sts == 1) { /* 1 - locked */
+ DRM_ERROR("Failed to switch HDCP to SAPB Mailbox\n");
+ return -1;
+ }
+ DRM_DEBUG_KMS("INFO: HDCP switched to SAPB\n");
+ } else
+ DRM_DEBUG_KMS("INFO: Leaving HDCP to APB\n");
+
+ /* HDCP 2.2(and/or 1.4) | activate | km-key | 0 */
+ hdcp_cfg = hdcp_config | 0x04 | 0x10 | (HDCP_CONTENT_TYPE_0 << 3);
+
+ DRM_DEBUG_KMS("INFO: Enabling HDCP...\n");
+ CDN_API_HDCP_TX_CONFIGURATION_blocking(&hdp->state, hdcp_cfg, bt);
+
+ /* Wait until HDCP_TX_STATUS EVENT appears */
+ DRM_DEBUG_KMS("INFO: wait4event -> EVENT_ID_HDCPTX_STATUS\n");
+ retEvents = wait4event(hdp, &events, EVENT_ID_HDCPTX_STATUS);
+
+ /* Set TX STATUS REQUEST */
+ DRM_DEBUG_KMS("INFO: Getting port status\n");
+ hdcp_port_status = imx_hdcp_get_status(hdp);
+ if (imx_hdcp_handle_status(hdcp_port_status) != 0)
+ return -1;
+
+ return 0;
+}
+
+static int imx_hdcp_auth_check(struct imx_hdp *hdp)
+{
+ u32 events;
+ u16 hdcp_port_status;
+
+ /* Wait until HDCP_TX_STATUS EVENT appears */
+ events = wait4event(hdp, &events, EVENT_ID_HDCPTX_STATUS);
+ if (events == 0)
+ return -1;
+ DRM_DEBUG_KMS("HDCP: EVENT_ID_HDCPTX_STATUS\n");
+
+ hdcp_port_status = imx_hdcp_get_status(hdp);
+ if (imx_hdcp_handle_status(hdcp_port_status) != 0)
+ return -1;
+
+ if (hdcp_port_status & 1) {
+ DRM_INFO("Authentication completed successfully!\n");
+ return 0;
+ }
+ DRM_ERROR("Authentication failed\n");
+ return -1;
+}
+
+static int imx_hdcp_check_receviers(struct imx_hdp *hdp)
+{
+ CDN_BUS_TYPE bt = hdp->hdcp.bus_type;
+ unsigned int events = 0;
+ unsigned int ret_events;
+ uint8_t hdcp_num_rec;
+ uint8_t hdcp_rec_id[HDCP_MAX_RECEIVERS][HDCP_RECEIVER_ID_SIZE_BYTES];
+ uint8_t i;
+
+ DRM_DEBUG_KMS("INFO: Waiting for Receiver ID valid event\n");
+ ret_events = wait4event(hdp, &events,
+ EVENT_ID_HDCPTX_IS_RECEIVER_ID_VALID);
+ DRM_DEBUG_KMS("INFO: Requesting Receivers ID's\n");
+
+ hdcp_num_rec = 0;
+ memset(&hdcp_rec_id, 0, sizeof(hdcp_rec_id));
+
+ CDN_API_HDCP_TX_IS_RECEIVER_ID_VALID_REQ_blocking
+ (&hdp->state,
+ &hdcp_num_rec,
+ (unsigned char *)
+ hdcp_rec_id,
+ bt
+ );
+
+ DRM_DEBUG_KMS("INFO: Number of Receivers: %d\n", hdcp_num_rec);
+
+ for (i = 0; i < hdcp_num_rec; ++i) {
+ DRM_INFO("\tReveiver ID%2d: %.2X%.2X%.2X%.2X%.2X\n",
+ i,
+ hdcp_rec_id[i][0],
+ hdcp_rec_id[i][1],
+ hdcp_rec_id[i][2],
+ hdcp_rec_id[i][3],
+ hdcp_rec_id[i][4]
+ );
+ }
+
+ /* fixme: Check Receiver ID's against revocation list */
+
+ DRM_DEBUG_KMS("INFO: Responding with Receiver ID's OK!\n");
+ CDN_API_HDCP_TX_RESPOND_RECEIVER_ID_VALID_blocking(&hdp->state, 1,
+ hdp->hdcp.bus_type);
+
+ return 0;
+}
+
+static inline int imx_hdcp_auth_22(struct imx_hdp *hdp)
+{
+ CDN_BUS_TYPE bt = hdp->hdcp.bus_type;
+ unsigned char kmStored = 0;
+ unsigned int events = 0;
+ unsigned int retEvents;
+ unsigned short hdcp_port_status;
+ u8 resp[HDCP_STATUS_SIZE];
+ S_HDCP_TRANS_PAIRING_DATA pairing;
+
+ DRM_DEBUG_KMS("HDCP: Start 2.2 Authentication\n");
+
+ /* Wait until HDCP2_TX_IS_KM_STORED EVENT appears */
+ retEvents = 0;
+ DRM_DEBUG_KMS("INFO: Wait until HDCP2_TX_IS_KM_STORED EVENT appears\n");
+ while (check_event(retEvents, EVENT_ID_HDCPTX_IS_KM_STORED) == 0) {
+ DRM_DEBUG_KMS("INFO: Waiting FOR _IS_KM_STORED EVENT\n");
+ retEvents = wait4event(hdp, &events,
+ EVENT_ID_HDCPTX_IS_KM_STORED);
+ if (retEvents == 0) {
+ /* time out occurred, stop hdcp and return error */
+ CDN_API_HDCP_TX_CONFIGURATION_blocking(&hdp->state,
+ 0, bt);
+ return -1;
+ }
+ if (check_event(retEvents, EVENT_ID_HDCPTX_STATUS) != 0) {
+ hdcp_port_status = imx_hdcp_get_status(hdp);
+ if (imx_hdcp_handle_status(hdcp_port_status) != 0)
+ return -1;
+ }
+ }
+
+ DRM_DEBUG_KMS("HDCP: EVENT_ID_HDCPTX_IS_KM_STORED\n");
+
+ /* Set HDCP2 TX KM STORED REQUEST */
+ CDN_API_HDCP2_TX_IS_KM_STORED_REQ_blocking(&hdp->state, resp, bt);
+ DRM_DEBUG_KMS("HDCP: CDN_API_HDCP2_TX_IS_KM_STORED_REQ_blocking\n");
+ DRM_DEBUG_KMS("HDCP: Receiver ID: 0x%x%x%x%x%x\n",
+ resp[0], resp[1], resp[2], resp[3], resp[4]);
+
+ /* Check if KM is stored */
+ if (kmStored != 0) {
+ DRM_DEBUG_KMS("INFO: KM is stored\n");
+ /* Set HDCP2 TX RESPOND KM with stored KM */
+ memcpy(pairing.receiver_id, recv_id, sizeof(recv_id));
+ memcpy(pairing.m, m, sizeof(m));
+ memcpy(pairing.km, km, sizeof(km));
+ memcpy(pairing.ekh, ekhkm, sizeof(ekhkm));
+ CDN_API_HDCP2_TX_RESPOND_KM_blocking(&hdp->state, &pairing, bt);
+ DRM_DEBUG_KMS("HDCP: CDN_API_HDCP2_TX_RESPOND_KM_blocking\n");
+ } else { /* KM is not stored */
+ DRM_DEBUG_KMS("INFO: KM is not stored\n");
+ /* Set HDCP2 TX RESPOND KM with empty data */
+ CDN_API_HDCP2_TX_RESPOND_KM_blocking(&hdp->state, NULL, bt);
+ }
+
+ imx_hdcp_check_receviers(hdp);
+
+ /* Check if KM is not stored */
+ if (kmStored == 0) {
+ /* Wait until HDCP2_TX_STORE_KM EVENT appears */
+ retEvents = 0;
+ while (check_event(retEvents, EVENT_ID_HDCPTX_STORE_KM) == 0) {
+ retEvents = wait4event(hdp, &events,
+ EVENT_ID_HDCPTX_STORE_KM);
+ if (check_event(retEvents, EVENT_ID_HDCPTX_STATUS)
+ != 0) {
+ hdcp_port_status = imx_hdcp_get_status(hdp);
+ if (imx_hdcp_handle_status(hdcp_port_status)
+ != 0)
+ return -1;
+ }
+ }
+ DRM_DEBUG_KMS("HDCP: EVENT_ID_HDCPTX_STORE_KM\n");
+
+ /* Set HDCP2_TX_STORE_KM REQUEST */
+ CDN_API_HDCP2_TX_STORE_KM_REQ_blocking(&hdp->state, &pairing,
+ bt);
+ DRM_DEBUG_KMS("HDCP: CDN_API_HDCP2_TX_STORE_KM_REQ_blocking");
+ }
+
+ return 0;
+}
+
+static inline int imx_hdcp_auth_14(struct imx_hdp *hdp)
+{
+ DRM_DEBUG_KMS("HDCP: Starting 1.4 Authentication\n");
+ return imx_hdcp_check_receviers(hdp);
+}
+
+static int imx_hdcp_auth(struct imx_hdp *hdp, u8 hdcp_config)
+{
+ int ret;
+
+ DRM_DEBUG_KMS("HDCP: Start Authentication\n");
+ ret = imx_hdcp_set_config(hdp, hdcp_config);
+ if (ret) {
+ DRM_ERROR("imx_hdcp_set_config failed\n");
+ return -1;
+ }
+ if (hdcp_config == HDCP_TX_1)
+ ret = imx_hdcp_auth_14(hdp);
+ else
+ ret = imx_hdcp_auth_22(hdp);
+
+ if (ret) {
+ DRM_ERROR("imx_hdcp_auth_%s failed\n",
+ (hdcp_config == HDCP_TX_1) ? "14" : "22");
+ return -1;
+ }
+
+ ret = imx_hdcp_auth_check(hdp);
+ if (ret)
+ ret = imx_hdcp_auth_check(hdp);
+ return ret;
+}
+
+static int _imx_hdcp_disable(struct imx_hdp *hdp)
+{
+ int ret = 0;
+ uint8_t hdcp_cfg = 0;
+ CDN_BUS_TYPE bt = hdp->hdcp.bus_type;
+
+ DRM_DEBUG_KMS("[%s:%d] HDCP is being disabled...\n",
+ hdp->connector.name, hdp->connector.base.id);
+ DRM_DEBUG_KMS("INFO: Disabling HDCP...\n");
+
+ ret = CDN_API_HDCP_TX_CONFIGURATION_blocking(&hdp->state, hdcp_cfg, bt);
+
+ DRM_DEBUG_KMS("HDCP is disabled\n");
+
+ return ret;
+}
+
+
+static int _imx_hdcp_enable(struct imx_hdp *hdp)
+{
+ int i, ret = 0, tries = 3;
+
+ DRM_DEBUG_KMS("[%s:%d] HDCP is being enabled...\n",
+ hdp->connector.name, hdp->connector.base.id);
+
+ /* Incase of authentication failures, HDCP spec expects reauth. */
+ for (i = 0; i < tries; i++) {
+ if (hdp->hdcp.config & HDCP_CONFIG_2_2) {
+ ret = imx_hdcp_auth(hdp, HDCP_TX_2);
+ if (ret == 0)
+ return 0;
+ }
+ _imx_hdcp_disable(hdp);
+ if (hdp->hdcp.config & HDCP_CONFIG_1_4) {
+ ret = imx_hdcp_auth(hdp, HDCP_TX_1);
+ if (!ret)
+ return 0;
+ }
+ DRM_DEBUG_KMS("HDCP Auth failure (%d)\n", ret);
+
+ /* Ensuring HDCP encryption and signalling are stopped. */
+ _imx_hdcp_disable(hdp);
+ }
+
+ DRM_ERROR("HDCP authentication failed (%d tries/%d)\n", tries, ret);
+ return ret;
+}
+
+static void imx_hdcp_check_work(struct work_struct *work)
+{
+ struct imx_hdcp *hdcp = container_of(work,
+ struct imx_hdcp,
+ check_work.work);
+ struct imx_hdp *hdp = container_of(hdcp,
+ struct imx_hdp,
+ hdcp);
+ if (!imx_hdcp_check_link(hdp))
+ schedule_delayed_work(&hdcp->check_work,
+ DRM_HDCP_CHECK_PERIOD_MS);
+}
+
+
+static void imx_hdcp_prop_work(struct work_struct *work)
+{
+ struct imx_hdcp *hdcp = container_of(work,
+ struct imx_hdcp,
+ prop_work);
+ struct imx_hdp *hdp = container_of(hdcp,
+ struct imx_hdp,
+ hdcp);
+
+ struct drm_device *dev = hdp->drm_dev;
+ struct drm_connector_state *state;
+
+ drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
+ mutex_lock(&hdp->hdcp.mutex);
+
+ /*
+ * This worker is only used to flip between ENABLED/DESIRED. Either of
+ * those to UNDESIRED is handled by core. If hdcp_value == UNDESIRED,
+ * we're running just after hdcp has been disabled, so just exit
+ */
+ if (hdp->hdcp.value != DRM_MODE_CONTENT_PROTECTION_UNDESIRED) {
+ state = hdp->connector.state;
+ state->content_protection = hdp->hdcp.value;
+ }
+
+ mutex_unlock(&hdp->hdcp.mutex);
+ drm_modeset_unlock(&dev->mode_config.connection_mutex);
+}
+
+static void show_hdcp_supported(struct imx_hdp *hdp)
+{
+ if ((hdp->hdcp.config & (HDCP_CONFIG_1_4 | HDCP_CONFIG_2_2)) ==
+ (HDCP_CONFIG_1_4 | HDCP_CONFIG_2_2))
+ DRM_INFO("Both HDCP 1.4 and 2 2 are enabled\n");
+ else if (hdp->hdcp.config & HDCP_CONFIG_1_4)
+ DRM_INFO("Only HDCP 1.4 is enabled\n");
+ else if (hdp->hdcp.config & HDCP_CONFIG_2_2)
+ DRM_INFO("Only HDCP 2.2 is enabled\n");
+ else
+ DRM_INFO("HDCP is disabled\n");
+}
+
+int imx_hdcp_init(struct imx_hdp *hdp, struct device_node *of_node)
+{
+ int ret;
+ const char *compat;
+ u32 temp;
+
+ ret = of_property_read_string(of_node, "compatible", &compat);
+ if (ret) {
+ DRM_ERROR("Failed to compatible dts string\n");
+ return ret;
+ }
+
+ ret = of_property_read_u32(of_node, "hdcp-config", &temp);
+ if (ret) {
+ /* hdp->hdcp_config = HDCP_CONFIG_ALL; */
+ /* using highest level by default */
+ hdp->hdcp.config = HDCP_CONFIG_2_2;
+ DRM_INFO("Failed to get HDCP config - using HDCP 2.2 only\n");
+ } else {
+ hdp->hdcp.config = temp;
+ show_hdcp_supported(hdp);
+ }
+
+ if (!check_hdcp_enabled())
+ return -EPERM;
+
+ if (!strstr(compat, "hdmi"))
+ return -EPERM;
+
+ if (strstr(compat, "imx8mq"))
+ hdp->hdcp.bus_type = CDN_BUS_TYPE_SAPB;
+ else
+ hdp->hdcp.bus_type = CDN_BUS_TYPE_APB;
+
+ ret = drm_connector_attach_content_protection_property(&hdp->connector);
+ if (ret)
+ return ret;
+
+ /*connector->hdcp_shim = hdcp_shim;*/
+ mutex_init(&hdp->hdcp.mutex);
+ INIT_DELAYED_WORK(&hdp->hdcp.check_work, imx_hdcp_check_work);
+ INIT_WORK(&hdp->hdcp.prop_work, imx_hdcp_prop_work);
+ return 0;
+}
+
+int imx_hdcp_enable(struct imx_hdp *hdp)
+{
+ int ret;
+
+ mutex_lock(&hdp->hdcp.mutex);
+
+ ret = _imx_hdcp_enable(hdp);
+ if (ret)
+ goto out;
+
+ hdp->hdcp.value = DRM_MODE_CONTENT_PROTECTION_ENABLED;
+ schedule_work(&hdp->hdcp.prop_work);
+ schedule_delayed_work(&hdp->hdcp.check_work,
+ DRM_HDCP_CHECK_PERIOD_MS);
+out:
+ mutex_unlock(&hdp->hdcp.mutex);
+ return ret;
+}
+
+int imx_hdcp_disable(struct imx_hdp *hdp)
+{
+ int ret = 0;
+
+ mutex_lock(&hdp->hdcp.mutex);
+ if (hdp->hdcp.value != DRM_MODE_CONTENT_PROTECTION_UNDESIRED) {
+ hdp->hdcp.value = DRM_MODE_CONTENT_PROTECTION_UNDESIRED;
+ ret = _imx_hdcp_disable(hdp);
+ }
+ mutex_unlock(&hdp->hdcp.mutex);
+ cancel_delayed_work_sync(&hdp->hdcp.check_work);
+
+ return ret;
+}
+
+void imx_hdcp_atomic_check(struct drm_connector *connector,
+ struct drm_connector_state *old_state,
+ struct drm_connector_state *new_state)
+{
+ uint64_t old_cp = old_state->content_protection;
+ uint64_t new_cp = new_state->content_protection;
+ struct drm_crtc_state *crtc_state;
+
+ if (!new_state->crtc) {
+ /*
+ * If the connector is being disabled with CP enabled, mark it
+ * desired so it's re-enabled when the connector is brought back
+ */
+ if (old_cp == DRM_MODE_CONTENT_PROTECTION_ENABLED)
+ new_state->content_protection =
+ DRM_MODE_CONTENT_PROTECTION_DESIRED;
+ return;
+ }
+
+ /*
+ * Nothing to do if the state didn't change, or HDCP was activated since
+ * the last commit
+ */
+ if (old_cp == new_cp ||
+ (old_cp == DRM_MODE_CONTENT_PROTECTION_DESIRED &&
+ new_cp == DRM_MODE_CONTENT_PROTECTION_ENABLED))
+ return;
+
+ crtc_state = drm_atomic_get_new_crtc_state(new_state->state,
+ new_state->crtc);
+ crtc_state->mode_changed = true;
+}
+
+int imx_hdcp_check_link(struct imx_hdp *hdp)
+{
+ int ret = 0;
+ u16 hdcp_port_status;
+ u8 hdcp_last_error;
+
+ mutex_lock(&hdp->hdcp.mutex);
+
+ if (hdp->hdcp.value == DRM_MODE_CONTENT_PROTECTION_UNDESIRED)
+ goto out;
+
+ /* get port status */
+ hdcp_port_status = imx_hdcp_get_status(hdp);
+ hdcp_last_error = GET_HDCP_PORT_STS_LAST_ERR(hdcp_port_status);
+ if (hdcp_last_error)
+ DRM_ERROR("HDCP error no: %u\n", hdcp_last_error);
+
+ if (hdcp_port_status & HDCP_PORT_STS_AUTH) {
+ if (hdp->hdcp.value !=
+ DRM_MODE_CONTENT_PROTECTION_UNDESIRED) {
+ hdp->hdcp.value =
+ DRM_MODE_CONTENT_PROTECTION_ENABLED;
+ schedule_work(&hdp->hdcp.prop_work);
+ }
+ DRM_DEBUG_KMS("INFO: HDCP authenticated\n");
+ /* HDCP is authenticated*/
+ goto out;
+ }
+
+ DRM_DEBUG_KMS("[%s:%d] HDCP link failed, retrying authentication\n",
+ hdp->connector.name, hdp->connector.base.id);
+
+ ret = _imx_hdcp_disable(hdp);
+ if (ret) {
+ DRM_ERROR("Failed to disable hdcp (%d)\n", ret);
+ hdp->hdcp.value = DRM_MODE_CONTENT_PROTECTION_DESIRED;
+ schedule_work(&hdp->hdcp.prop_work);
+ goto out;
+ }
+
+ ret = _imx_hdcp_enable(hdp);
+ if (ret) {
+ DRM_ERROR("Failed to enable hdcp (%d)\n", ret);
+ hdp->hdcp.value = DRM_MODE_CONTENT_PROTECTION_DESIRED;
+ schedule_work(&hdp->hdcp.prop_work);
+ goto out;
+ }
+
+out:
+ mutex_unlock(&hdp->hdcp.mutex);
+ return ret;
+}
+
diff --git a/drivers/gpu/drm/imx/hdp/imx-hdcp.h b/drivers/gpu/drm/imx/hdp/imx-hdcp.h
new file mode 100644
index 000000000000..4404a4446386
--- /dev/null
+++ b/drivers/gpu/drm/imx/hdp/imx-hdcp.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2017-2019 NXP
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+#ifndef _IMX_HDCP_H_
+#define _IMX_HDCP_H_
+
+bool is_hdcp_supported(struct imx_hdp *hdp);
+int imx_hdcp_init(struct imx_hdp *hdp, struct device_node *of_node);
+int imx_hdcp_enable(struct imx_hdp *hdp);
+int imx_hdcp_disable(struct imx_hdp *hdp);
+void imx_hdcp_atomic_check(struct drm_connector *connector,
+ struct drm_connector_state *old_state,
+ struct drm_connector_state *new_state);
+int imx_hdcp_check_link(struct imx_hdp *hdp);
+
+#endif
diff --git a/drivers/gpu/drm/imx/hdp/imx-hdmi.c b/drivers/gpu/drm/imx/hdp/imx-hdmi.c
new file mode 100644
index 000000000000..c7b29ae56f75
--- /dev/null
+++ b/drivers/gpu/drm/imx/hdp/imx-hdmi.c
@@ -0,0 +1,531 @@
+/*
+ * Copyright 2017-2018 NXP
+ *
+ * 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/clk.h>
+#ifdef DEBUG_FW_LOAD
+#include "hdmitx_firmware.h"
+#endif
+#include "imx-hdp.h"
+#include "imx-hdmi.h"
+#include "API_AFE_ss28fdsoi_kiran_hdmitx.h"
+#include "API_AFE_t28hpc_hdmitx.h"
+
+#define RGB_ALLOWED_COLORIMETRY (BIT(HDMI_EXTENDED_COLORIMETRY_BT2020) |\
+ BIT(HDMI_EXTENDED_COLORIMETRY_ADOBE_RGB))
+#define YCC_ALLOWED_COLORIMETRY (BIT(HDMI_EXTENDED_COLORIMETRY_BT2020) |\
+ BIT(HDMI_EXTENDED_COLORIMETRY_BT2020_CONST_LUM) |\
+ BIT(HDMI_EXTENDED_COLORIMETRY_ADOBE_YCC_601) |\
+ BIT(HDMI_EXTENDED_COLORIMETRY_S_YCC_601) |\
+ BIT(HDMI_EXTENDED_COLORIMETRY_XV_YCC_709) |\
+ BIT(HDMI_EXTENDED_COLORIMETRY_XV_YCC_601))
+
+#define B0_SILICON_ID 0x11
+
+static int hdmi_avi_info_set(struct imx_hdp *hdp,
+ struct drm_display_mode *mode,
+ int format)
+{
+ struct hdmi_avi_infoframe frame;
+ struct drm_display_info *di = &hdp->connector.display_info;
+ enum hdmi_extended_colorimetry ext_colorimetry;
+ u32 sink_colorimetry;
+ u32 allowed_colorimetry;
+ u8 buf[32];
+ int ret;
+
+ /* Initialise info frame from DRM mode */
+ drm_hdmi_avi_infoframe_from_display_mode(&frame, mode, true);
+
+ /* Set up colorimetry */
+ allowed_colorimetry = format == PXL_RGB ? RGB_ALLOWED_COLORIMETRY :
+ YCC_ALLOWED_COLORIMETRY;
+
+ if (hdp->bpc == 8)
+ allowed_colorimetry &= ~(BIT(HDMI_EXTENDED_COLORIMETRY_BT2020) |
+ BIT(HDMI_EXTENDED_COLORIMETRY_BT2020_CONST_LUM));
+
+ sink_colorimetry = di->hdmi.colorimetry & allowed_colorimetry;
+
+ if (sink_colorimetry & BIT(HDMI_EXTENDED_COLORIMETRY_BT2020))
+ ext_colorimetry = HDMI_EXTENDED_COLORIMETRY_BT2020;
+ else if (sink_colorimetry & BIT(HDMI_EXTENDED_COLORIMETRY_BT2020_CONST_LUM))
+ ext_colorimetry = HDMI_EXTENDED_COLORIMETRY_BT2020_CONST_LUM;
+ else if (sink_colorimetry & BIT(HDMI_EXTENDED_COLORIMETRY_ADOBE_RGB))
+ ext_colorimetry = HDMI_EXTENDED_COLORIMETRY_ADOBE_RGB;
+ else if (sink_colorimetry & BIT(HDMI_EXTENDED_COLORIMETRY_XV_YCC_709))
+ ext_colorimetry = HDMI_EXTENDED_COLORIMETRY_XV_YCC_709;
+ else if (sink_colorimetry & BIT(HDMI_EXTENDED_COLORIMETRY_ADOBE_YCC_601))
+ ext_colorimetry = HDMI_EXTENDED_COLORIMETRY_ADOBE_YCC_601;
+ else if (sink_colorimetry & BIT(HDMI_EXTENDED_COLORIMETRY_S_YCC_601))
+ ext_colorimetry = HDMI_EXTENDED_COLORIMETRY_S_YCC_601;
+ else if (sink_colorimetry & BIT(HDMI_EXTENDED_COLORIMETRY_XV_YCC_601))
+ ext_colorimetry = HDMI_EXTENDED_COLORIMETRY_XV_YCC_601;
+ else
+ ext_colorimetry = 0;
+
+ frame.colorimetry = sink_colorimetry ? HDMI_COLORIMETRY_EXTENDED :
+ HDMI_COLORIMETRY_NONE;
+ frame.extended_colorimetry = ext_colorimetry;
+
+ switch (format) {
+ case YCBCR_4_4_4:
+ frame.colorspace = HDMI_COLORSPACE_YUV444;
+ break;
+ case YCBCR_4_2_2:
+ frame.colorspace = HDMI_COLORSPACE_YUV422;
+ break;
+ case YCBCR_4_2_0:
+ frame.colorspace = HDMI_COLORSPACE_YUV420;
+ break;
+ default:
+ frame.colorspace = HDMI_COLORSPACE_RGB;
+ break;
+ }
+
+ ret = hdmi_avi_infoframe_pack(&frame, buf + 1, sizeof(buf) - 1);
+ if (ret < 0) {
+ DRM_ERROR("failed to pack AVI infoframe: %d\n", ret);
+ return -1;
+ }
+
+ buf[0] = 0;
+ return CDN_API_InfoframeSet(&hdp->state, 0, sizeof(buf),
+ buf, HDMI_INFOFRAME_TYPE_AVI);
+
+}
+
+static int hdmi_vendor_info_set(struct imx_hdp *hdp,
+ struct drm_display_mode *mode,
+ int format)
+{
+ struct hdmi_vendor_infoframe frame;
+ u8 buf[32];
+ int ret;
+
+ /* Initialise vendor frame from DRM mode */
+ ret = drm_hdmi_vendor_infoframe_from_display_mode(&frame, mode);
+ if (ret < 0) {
+ DRM_DEBUG("Unable to init vendor infoframe: %d\n", ret);
+ return -1;
+ }
+
+ ret = hdmi_vendor_infoframe_pack(&frame, buf + 1, sizeof(buf) - 1);
+ if (ret < 0) {
+ DRM_DEBUG("Unable to pack vendor infoframe: %d\n", ret);
+ return -1;
+ }
+
+ buf[0] = 0;
+ return CDN_API_InfoframeSet(&hdp->state, 3, sizeof(buf),
+ buf, HDMI_INFOFRAME_TYPE_VENDOR);
+
+}
+
+static void hdmi_mode_set_vswing(state_struct *state)
+{
+ GENERAL_Read_Register_response regresp[12];
+
+ Afe_write(state, 0x41e1, 0x7c0);
+ Afe_write(state, 0x43e1, 0x7c0);
+ Afe_write(state, 0x45e1, 0x7c0);
+ Afe_write(state, 0x47e1, 0x7c0);
+
+ Afe_write(state, 0x404C, 0x0);
+ Afe_write(state, 0x424C, 0x0);
+ Afe_write(state, 0x444C, 0x0);
+ Afe_write(state, 0x464C, 0x0);
+
+ Afe_write(state, 0x4047, 0x120);
+ Afe_write(state, 0x4247, 0x120);
+ Afe_write(state, 0x4447, 0x120);
+ Afe_write(state, 0x4647, 0x120);
+
+ regresp[0].val = Afe_read(state, 0x41e1);
+ regresp[1].val = Afe_read(state, 0x43e1);
+ regresp[2].val = Afe_read(state, 0x45e1);
+ regresp[3].val = Afe_read(state, 0x47e1);
+
+ regresp[4].val = Afe_read(state, 0x404C);
+ regresp[5].val = Afe_read(state, 0x424C);
+ regresp[6].val = Afe_read(state, 0x444C);
+ regresp[7].val = Afe_read(state, 0x464C);
+
+ regresp[8].val = Afe_read(state, 0x4047);
+ regresp[9].val = Afe_read(state, 0x4247);
+ regresp[10].val = Afe_read(state, 0x4447);
+ regresp[11].val = Afe_read(state, 0x4647);
+
+ DRM_DEBUG("LANE0_TX_DIAG_TX_DRV 0x%x \n"
+ "LANE1_TX_DIAG_TX_DRV 0x%x \n"
+ "LANE2_TX_DIAG_TX_DRV 0x%x \n"
+ "LANE3_TX_DIAG_TX_DRV 0x%x \n"
+ "Lane0_TX_TXCC_CPOST_MULT_00 0x%x \n"
+ "Lane1_TX_TXCC_CPOST_MULT_00 0x%x \n"
+ "Lane2_TX_TXCC_CPOST_MULT_00 0x%x \n"
+ "Lane3_TX_TXCC_CPOST_MULT_00 0x%x \n"
+ "Lane0_TX_TXCC_CAL_SCLR_MULT 0x%x \n"
+ "Lane1_TX_TXCC_CAL_SCLR_MULT 0x%x \n"
+ "Lane2_TX_TXCC_CAL_SCLR_MULT 0x%x \n"
+ "Lane3_TX_TXCC_CAL_SCLR_MULT 0x%x \n",
+ regresp[0].val,
+ regresp[1].val,
+ regresp[2].val,
+ regresp[3].val,
+ regresp[4].val,
+ regresp[5].val,
+ regresp[6].val,
+ regresp[7].val,
+ regresp[8].val,
+ regresp[9].val,
+ regresp[10].val,
+ regresp[11].val
+ );
+}
+
+static int hdmi_scdc_tmds_config(struct imx_hdp *hdp)
+{
+ struct drm_scdc *scdc = &hdp->connector.display_info.hdmi.scdc;
+ HDMITX_TRANS_DATA data_in;
+ HDMITX_TRANS_DATA data_out;
+ u8 buff;
+ int ret = 0;
+
+ if (hdp->character_freq_khz > 340000) {
+ /*
+ * TMDS Character Rate above 340MHz should working in HDMI2.0
+ * Enable scrambling and TMDS_Bit_Clock_Ratio
+ */
+ buff = 3;
+ hdp->hdmi_type = HDMI_TX_MODE_HDMI_2_0;
+ } else if (scdc->scrambling.low_rates) {
+ /*
+ * Enable scrambling and work in HDMI2.0 when scrambling capability of sink
+ * be indicated in the HF-VSDB LTE_340Mcsc_scramble bit
+ */
+ buff = 1;
+ hdp->hdmi_type = HDMI_TX_MODE_HDMI_2_0;
+ } else {
+ /* Default work in HDMI1.4 */
+ buff = 0;
+ hdp->hdmi_type = HDMI_TX_MODE_HDMI_1_4;
+ }
+
+ data_in.buff = &buff;
+ data_in.len = 1;
+ data_in.slave = 0x54;
+ /* TMDS config */
+ data_in.offset = 0x20;
+
+ /* Workaround for imx8qm A0 SOC DDC R/W failed issue */
+ if (cpu_is_imx8qm() && (imx8_get_soc_revision() < B0_SILICON_ID))
+ pr_info("Skip DDC Write for iMX8QM A0 SOC\n");
+ else {
+ ret = CDN_API_HDMITX_DDC_WRITE_blocking(&hdp->state, &data_in, &data_out);
+ if (ret != CDN_OK)
+ pr_warn("CDN_API_HDMITX_DDC_WRITE_blocking ret = %d\n", ret);
+ }
+ return ret;
+}
+
+int hdmi_phy_init_ss28fdsoi(state_struct *state, struct drm_display_mode *mode, int format, int color_depth)
+{
+ struct imx_hdp *hdp = state_to_imx_hdp(state);
+ int ret;
+
+ /* reset phy */
+ imx_hdp_call(hdp, phy_reset, hdp->ipcHndl, NULL, 0);
+
+ /* Configure PHY */
+ hdp->character_freq_khz = phy_cfg_hdp_ss28fdsoi(state, 4, mode, color_depth, format);
+ if (hdp->character_freq_khz == 0) {
+ DRM_ERROR("failed to set phy pclock\n");
+ return -EINVAL;
+ }
+
+ imx_hdp_call(hdp, phy_reset, hdp->ipcHndl, NULL, 1);
+
+ hdmi_tx_kiran_power_configuration_seq(state, 4);
+
+ /* Set the lane swapping */
+ ret = CDN_API_General_Write_Register_blocking(state, ADDR_SOURCD_PHY + (LANES_CONFIG << 2),
+ F_SOURCE_PHY_LANE0_SWAP(3) | F_SOURCE_PHY_LANE1_SWAP(0) |
+ F_SOURCE_PHY_LANE2_SWAP(1) | F_SOURCE_PHY_LANE3_SWAP(2) |
+ F_SOURCE_PHY_COMB_BYPASS(0) | F_SOURCE_PHY_20_10(1));
+ DRM_INFO("CDN_API_General_Write_Register_blocking LANES_CONFIG ret = %d\n", ret);
+
+ return true;
+}
+
+void hdmi_mode_set_ss28fdsoi(state_struct *state, struct drm_display_mode *mode, int format, int color_depth, int temp)
+{
+ struct imx_hdp *hdp = container_of(state, struct imx_hdp, state);
+ int ret;
+
+ /* config SCDC TMDS & HDMI type */
+ hdmi_scdc_tmds_config(hdp);
+
+ ret = CDN_API_HDMITX_Init_blocking(state);
+ if (ret != CDN_OK) {
+ DRM_INFO("CDN_API_STATUS CDN_API_HDMITX_Init_blocking ret = %d\n", ret);
+ return;
+ }
+
+ /* force GCP CD to 0 when bpp=24 for pass CTS 7-19 */
+ if (color_depth == 8)
+ CDN_API_HDMITX_Disable_GCP(state);
+
+ /* Set HDMI TX Mode */
+ ret = CDN_API_HDMITX_Set_Mode_blocking(state, hdp->hdmi_type, hdp->character_freq_khz);
+ if (ret != CDN_OK) {
+ DRM_INFO("CDN_API_HDMITX_Set_Mode_blocking ret = %d\n", ret);
+ return;
+ }
+
+ ret = hdmi_avi_info_set(hdp, mode, format);
+ if (ret < 0) {
+ DRM_ERROR("hdmi avi info set ret = %d\n", ret);
+ return;
+ }
+
+ /* vendor info frame is enable only when HDMI1.4 4K mode */
+ hdmi_vendor_info_set(hdp, mode, format);
+
+ ret = CDN_API_HDMITX_SetVic_blocking(state, mode, color_depth, format);
+ if (ret != CDN_OK) {
+ DRM_INFO("CDN_API_HDMITX_SetVic_blocking ret = %d\n", ret);
+ return;
+ }
+
+ hdmi_mode_set_vswing(state);
+}
+
+int hdmi_phy_init_t28hpc(state_struct *state, struct drm_display_mode *mode, int format, int color_depth)
+{
+ struct imx_hdp *hdp = state_to_imx_hdp(state);
+ int ret;
+ /* 0- pixel clock from phy */
+ u32 pixel_clk_from_phy = 1;
+ char echo_msg[] = "echo test";
+ char echo_resp[sizeof(echo_msg) + 1];
+
+ /* Parameterization done */
+
+ ret = CDN_API_CheckAlive_blocking(state);
+ if (ret != 0) {
+ DRM_ERROR("NO HDMI FW running\n");
+ return -ENXIO;
+ }
+
+ ret = CDN_API_General_Test_Echo_Ext_blocking(state, echo_msg, echo_resp,
+ sizeof(echo_msg),
+ CDN_BUS_TYPE_APB);
+ if (ret != 0) {
+ DRM_ERROR("HDMI mailbox access failed\n");
+ return -ENXIO;
+ }
+
+ /* Configure PHY */
+ hdp->character_freq_khz =
+ phy_cfg_hdp_t28hpc(state, 4, mode, color_depth, format, pixel_clk_from_phy);
+ if (hdp->character_freq_khz == 0) {
+ DRM_ERROR("failed to set phy pclock\n");
+ return -EINVAL;
+ }
+
+ hdmi_tx_t28hpc_power_config_seq(state, 4);
+
+ /* Set the lane swapping */
+ ret =
+ CDN_API_General_Write_Register_blocking(state, ADDR_SOURCD_PHY +
+ (LANES_CONFIG << 2),
+ F_SOURCE_PHY_LANE0_SWAP(0) |
+ F_SOURCE_PHY_LANE1_SWAP(1) |
+ F_SOURCE_PHY_LANE2_SWAP(2) |
+ F_SOURCE_PHY_LANE3_SWAP(3) |
+ F_SOURCE_PHY_COMB_BYPASS(0)
+ | F_SOURCE_PHY_20_10(1));
+ DRM_INFO
+ ("CDN_API_General_Write_Register_blocking LANES_CONFIG ret = %d\n",
+ ret);
+
+ return true;
+}
+
+void hdmi_phy_pix_engine_reset_t28hpc(state_struct *state)
+{
+ GENERAL_Read_Register_response regresp;
+
+ CDN_API_General_Read_Register_blocking(state, ADDR_SOURCE_CAR +
+ (SOURCE_HDTX_CAR << 2),
+ &regresp);
+ CDN_API_General_Write_Register_blocking(state, ADDR_SOURCE_CAR +
+ (SOURCE_HDTX_CAR << 2),
+ regresp.val & 0xFD);
+ CDN_API_General_Write_Register_blocking(state, ADDR_SOURCE_CAR +
+ (SOURCE_HDTX_CAR << 2),
+ regresp.val);
+}
+
+void hdmi_mode_set_t28hpc(state_struct *state, struct drm_display_mode *mode, int format, int color_depth, int temp)
+{
+ struct imx_hdp *hdp = container_of(state, struct imx_hdp, state);
+ int ret;
+
+ /* config SCDC TMDS & HDMI type */
+ hdmi_scdc_tmds_config(hdp);
+
+ ret = CDN_API_HDMITX_Init_blocking(state);
+ if (ret != CDN_OK) {
+ DRM_ERROR("CDN_API_STATUS CDN_API_HDMITX_Init_blocking ret = %d\n", ret);
+ return;
+ }
+
+ /* force GCP CD to 0 when bpp=24 for pass CTS 7-19 */
+ if (color_depth == 8)
+ CDN_API_HDMITX_Disable_GCP(state);
+
+ /* Set HDMI TX Mode */
+ ret = CDN_API_HDMITX_Set_Mode_blocking(state, hdp->hdmi_type, hdp->character_freq_khz);
+ if (ret != CDN_OK) {
+ DRM_ERROR("CDN_API_HDMITX_Set_Mode_blocking ret = %d\n", ret);
+ return;
+ }
+
+ ret = hdmi_avi_info_set(hdp, mode, format);
+ if (ret < 0) {
+ DRM_ERROR("hdmi avi info set ret = %d\n", ret);
+ return;
+ }
+
+ /* vendor info frame is enable only when HDMI1.4 4K mode */
+ hdmi_vendor_info_set(hdp, mode, format);
+
+ ret = CDN_API_HDMITX_SetVic_blocking(state, mode, color_depth, format);
+ if (ret != CDN_OK) {
+ DRM_ERROR("CDN_API_HDMITX_SetVic_blocking ret = %d\n", ret);
+ return;
+ }
+
+ hdmi_mode_set_vswing(state);
+
+ msleep(50);
+}
+
+#define YUV_MODE BIT(0)
+
+bool hdmi_mode_fixup_t28hpc(state_struct *state,
+ const struct drm_display_mode *mode,
+ struct drm_display_mode *adjusted_mode)
+{
+ struct imx_hdp *hdp = container_of(state, struct imx_hdp, state);
+ int vic = drm_match_cea_mode(mode);
+ struct drm_display_info *di = &hdp->connector.display_info;
+ u32 max_clock = di->max_tmds_clock;
+
+ hdp->bpc = 8;
+ hdp->format = PXL_RGB;
+
+ if ((vic == VIC_MODE_97_60Hz || vic == VIC_MODE_96_50Hz)) {
+ if (di->hdmi.y420_dc_modes & DRM_EDID_YCBCR420_DC_36)
+ hdp->bpc = 12;
+ else if (di->hdmi.y420_dc_modes & DRM_EDID_YCBCR420_DC_30)
+ hdp->bpc = 10;
+
+ if (drm_mode_is_420_only(di, mode) ||
+ (drm_mode_is_420_also(di, mode) && hdp->bpc > 8)) {
+ hdp->format = YCBCR_4_2_0;
+
+ adjusted_mode->private_flags = YUV_MODE;
+ } else {
+ hdp->bpc = 8;
+ }
+
+ return true;
+ }
+
+ /* Any defined maximum tmds clock limit we must not exceed*/
+ if ((di->edid_hdmi_dc_modes & DRM_EDID_HDMI_DC_36) &&
+ (mode->clock * 3/2 <= max_clock))
+ hdp->bpc = 12;
+ else if ((di->edid_hdmi_dc_modes & DRM_EDID_HDMI_DC_30) &&
+ (mode->clock * 5/4 <= max_clock))
+ hdp->bpc = 10;
+
+ /* 10-bit color depth for the following modes is not supported */
+ if ((vic == VIC_MODE_95_30Hz || vic == VIC_MODE_94_25Hz ||
+ vic == VIC_MODE_93_24Hz) && hdp->bpc == 10)
+ hdp->bpc = 8;
+
+ return true;
+}
+
+int hdmi_get_edid_block(void *data, u8 *buf, u32 block, size_t len)
+{
+ HDMITX_TRANS_DATA edidResp;
+ state_struct *state = data;
+ CDN_API_STATUS ret = 0;
+
+ memset(&edidResp, 0, sizeof(edidResp));
+ switch (block) {
+ case 0:
+ ret = CDN_API_HDMITX_READ_EDID_blocking(state, 0, 0, &edidResp);
+ break;
+ case 1:
+ ret = CDN_API_HDMITX_READ_EDID_blocking(state, 0, 1, &edidResp);
+ break;
+ case 2:
+ ret = CDN_API_HDMITX_READ_EDID_blocking(state, 1, 0, &edidResp);
+ break;
+ case 3:
+ ret = CDN_API_HDMITX_READ_EDID_blocking(state, 1, 1, &edidResp);
+ break;
+ default:
+ pr_warn("EDID block %x read not support\n", block);
+ }
+
+ if (ret == CDN_OK)
+ memcpy(buf, edidResp.buff, 128);
+
+ return ret;
+}
+
+int hdmi_get_hpd_state(state_struct *state, u8 *hpd)
+{
+ int ret;
+
+ ret = CDN_API_HDMITX_GetHpdStatus_blocking(state, hpd);
+ return ret;
+}
+
+int hdmi_write_hdr_metadata(state_struct *state,
+ union hdmi_infoframe *hdr_infoframe)
+{
+ struct imx_hdp *hdp = container_of(state, struct imx_hdp, state);
+ u8 buffer[40];
+ int infoframe_size;
+
+ infoframe_size = hdmi_infoframe_pack(hdr_infoframe,
+ buffer + 1, sizeof(buffer) - 1);
+ if (infoframe_size < 0) {
+ dev_err(hdp->dev, "Wrong metadata infoframe: %d\n",
+ infoframe_size);
+ return infoframe_size;
+ }
+
+ buffer[0] = 0;
+ infoframe_size++;
+
+ return CDN_API_InfoframeSet(state, 2, infoframe_size,
+ buffer, HDMI_INFOFRAME_TYPE_DRM);
+}
diff --git a/drivers/gpu/drm/imx/hdp/imx-hdmi.h b/drivers/gpu/drm/imx/hdp/imx-hdmi.h
new file mode 100644
index 000000000000..88714775e2d3
--- /dev/null
+++ b/drivers/gpu/drm/imx/hdp/imx-hdmi.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2017-2018 NXP
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+#ifndef _IMX_HDMI_H_
+#define _IMX_HDMI_H_
+
+int hdmi_phy_init_ss28fdsoi(state_struct *state,
+ struct drm_display_mode *mode, int format, int color_depth);
+void hdmi_mode_set_ss28fdsoi(state_struct *state,
+ struct drm_display_mode *mode, int format, int color_depth, int temp);
+int hdmi_phy_init_t28hpc(state_struct *state,
+ struct drm_display_mode *mode, int format, int color_depth);
+void hdmi_mode_set_t28hpc(state_struct *state,
+ struct drm_display_mode *mode, int format, int color_depth, int temp);
+bool hdmi_mode_fixup_t28hpc(state_struct *state,
+ const struct drm_display_mode *mode,
+ struct drm_display_mode *adjusted_mode);
+int hdmi_get_edid_block(void *data, u8 *buf, u32 block, size_t len);
+int hdmi_get_hpd_state(state_struct *state, u8 *hpd);
+int hdmi_write_hdr_metadata(state_struct *state,
+ union hdmi_infoframe *hdr_infoframe);
+int pixel_clock_range_t28hpc(struct drm_display_mode *mode);
+void hdmi_phy_pix_engine_reset_t28hpc(state_struct *state);
+
+#endif
diff --git a/drivers/gpu/drm/imx/hdp/imx-hdp-audio.c b/drivers/gpu/drm/imx/hdp/imx-hdp-audio.c
new file mode 100644
index 000000000000..19e9176784a6
--- /dev/null
+++ b/drivers/gpu/drm/imx/hdp/imx-hdp-audio.c
@@ -0,0 +1,241 @@
+/*
+ * Copyright 2018 NXP
+ *
+ * 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/clk.h>
+#include <linux/kthread.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/component.h>
+#include <linux/mfd/syscon.h>
+#include <linux/of.h>
+#include <linux/irq.h>
+#include <linux/of_device.h>
+#include <sound/hdmi-codec.h>
+
+#include "imx-hdp.h"
+#include "imx-hdmi.h"
+#include "imx-dp.h"
+#include "../imx-drm.h"
+
+static u32 TMDS_rate_table[7] = {
+25200, 27000, 54000, 74250, 148500, 297000, 594000,
+};
+
+static u32 N_table_32k[8] = {
+/*25200, 27000, 54000, 74250, 148500, 297000, 594000,*/
+4096, 4096, 4096, 4096, 4096, 3072, 3072, 4096,
+};
+
+static u32 N_table_44k[8] = {
+6272, 6272, 6272, 6272, 6272, 4704, 9408, 6272,
+};
+
+static u32 N_table_48k[8] = {
+6144, 6144, 6144, 6144, 6144, 5120, 6144, 6144,
+};
+
+static int select_N_index(u32 pclk)
+{
+ int i = 0;
+
+ for (i = 0; i < 7; i++) {
+ if (pclk == TMDS_rate_table[i])
+ break;
+ }
+
+ if (i == 7)
+ DRM_WARN("pclkc %d is not supported!\n", pclk);
+
+ return i;
+}
+
+static void imx_hdmi_audio_avi_set(state_struct *state,
+ u32 channels)
+{
+ struct hdmi_audio_infoframe frame;
+ u8 buf[32];
+ int ret;
+
+ hdmi_audio_infoframe_init(&frame);
+
+ frame.channels = channels;
+ frame.coding_type = HDMI_AUDIO_CODING_TYPE_STREAM;
+
+ if (channels == 2)
+ frame.channel_allocation = 0;
+ else if (channels == 4)
+ frame.channel_allocation = 0x3;
+ else if (channels == 8)
+ frame.channel_allocation = 0x13;
+
+ ret = hdmi_audio_infoframe_pack(&frame, buf + 1, sizeof(buf) - 1);
+ if (ret < 0) {
+ DRM_ERROR("failed to pack audio infoframe: %d\n", ret);
+ return;
+ }
+
+ buf[0] = 0;
+
+ CDN_API_InfoframeSet(state, 1, sizeof(buf), buf, HDMI_INFOFRAME_TYPE_AUDIO);
+}
+
+static u32 imx_hdp_audio(struct imx_hdp *hdmi, AUDIO_TYPE type, u32 sample_rate, u32 channels, u32 width)
+{
+ AUDIO_FREQ freq;
+ AUDIO_WIDTH bits;
+ int ncts_n;
+ state_struct *state = &hdmi->state;
+ int idx_n = select_N_index(hdmi->video.cur_mode.clock);
+
+ switch (sample_rate) {
+ case 32000:
+ freq = AUDIO_FREQ_32;
+ ncts_n = N_table_32k[idx_n];
+ break;
+ case 44100:
+ freq = AUDIO_FREQ_44_1;
+ ncts_n = N_table_44k[idx_n];
+ break;
+ case 48000:
+ freq = AUDIO_FREQ_48;
+ ncts_n = N_table_48k[idx_n];
+ break;
+ case 88200:
+ freq = AUDIO_FREQ_88_2;
+ ncts_n = N_table_44k[idx_n] * 2;
+ break;
+ case 96000:
+ freq = AUDIO_FREQ_96;
+ ncts_n = N_table_48k[idx_n] * 2;
+ break;
+ case 176400:
+ freq = AUDIO_FREQ_176_4;
+ ncts_n = N_table_44k[idx_n] * 4;
+ break;
+ case 192000:
+ freq = AUDIO_FREQ_192;
+ ncts_n = N_table_48k[idx_n] * 4;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ switch (width) {
+ case 16:
+ bits = AUDIO_WIDTH_16;
+ break;
+ case 24:
+ bits = AUDIO_WIDTH_24;
+ break;
+ case 32:
+ bits = AUDIO_WIDTH_32;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+
+ CDN_API_AudioOff_blocking(state, type);
+ CDN_API_AudioAutoConfig_blocking(state,
+ type,
+ channels,
+ freq,
+ 0,
+ bits,
+ hdmi->audio_type,
+ ncts_n,
+ AUDIO_MUTE_MODE_UNMUTE);
+
+ if (hdmi->audio_type == CDN_HDMITX_TYPHOON ||
+ hdmi->audio_type == CDN_HDMITX_KIRAN)
+ imx_hdmi_audio_avi_set(state, channels);
+ return 0;
+}
+
+/*
+ * HDMI audio codec callbacks
+ */
+static int imx_hdp_audio_hw_params(struct device *dev, void *data,
+ struct hdmi_codec_daifmt *daifmt,
+ struct hdmi_codec_params *params)
+{
+ struct imx_hdp *hdmi = dev_get_drvdata(dev);
+ unsigned int chan = params->cea.channels;
+
+ dev_dbg(hdmi->dev, "%s: %u Hz, %d bit, %d channels\n", __func__,
+ params->sample_rate, params->sample_width, chan);
+
+ if (!hdmi->bridge.encoder)
+ return -ENODEV;
+
+ if (daifmt->fmt == HDMI_I2S)
+ imx_hdp_audio(hdmi,
+ AUDIO_TYPE_I2S,
+ params->sample_rate,
+ chan,
+ params->sample_width);
+ else if (daifmt->fmt == HDMI_SPDIF)
+ imx_hdp_audio(hdmi,
+ AUDIO_TYPE_SPIDIF_EXTERNAL,
+ params->sample_rate,
+ chan,
+ params->sample_width);
+ else
+ return -EINVAL;
+
+ return 0;
+}
+
+static void imx_hdp_audio_shutdown(struct device *dev, void *data)
+{
+ struct imx_hdp *hdmi = dev_get_drvdata(dev);
+ state_struct *state = &hdmi->state;
+
+ CDN_API_InfoframeRemovePacket(state, 0x1, 0x84);
+}
+
+static int imx_hdp_audio_get_eld(struct device *dev, void *data, uint8_t *buf, size_t len)
+{
+ struct imx_hdp *hdmi = dev_get_drvdata(dev);
+
+ memcpy(buf, hdmi->connector.eld, min(sizeof(hdmi->connector.eld), len));
+
+ return 0;
+}
+
+static const struct hdmi_codec_ops imx_hdp_audio_codec_ops = {
+ .hw_params = imx_hdp_audio_hw_params,
+ .audio_shutdown = imx_hdp_audio_shutdown,
+ .get_eld = imx_hdp_audio_get_eld,
+};
+
+void imx_hdp_register_audio_driver(struct device *dev)
+{
+ struct hdmi_codec_pdata codec_data = {
+ .ops = &imx_hdp_audio_codec_ops,
+ .max_i2s_channels = 8,
+ .i2s = 1,
+ };
+ struct platform_device *pdev;
+
+ pdev = platform_device_register_data(dev, HDMI_CODEC_DRV_NAME,
+ 1, &codec_data,
+ sizeof(codec_data));
+ if (IS_ERR(pdev))
+ return;
+
+ DRM_INFO("%s driver bound to HDMI\n", HDMI_CODEC_DRV_NAME);
+}
+
+
diff --git a/drivers/gpu/drm/imx/hdp/imx-hdp.c b/drivers/gpu/drm/imx/hdp/imx-hdp.c
new file mode 100644
index 000000000000..bcfad522df43
--- /dev/null
+++ b/drivers/gpu/drm/imx/hdp/imx-hdp.c
@@ -0,0 +1,1729 @@
+/*
+ * Copyright 2017-2018 NXP
+ *
+ * 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/clk.h>
+#include <linux/kthread.h>
+#include <linux/mutex.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/component.h>
+#include <linux/mfd/syscon.h>
+#include <linux/of.h>
+#include <linux/irq.h>
+#include <linux/of_device.h>
+
+#include "imx-hdp.h"
+#include "imx-hdmi.h"
+#include "imx-hdcp.h"
+#include "imx-hdcp-private.h"
+#include "imx-dp.h"
+#include "../imx-drm.h"
+
+#define B0_SILICON_ID 0x11
+
+struct drm_display_mode *g_mode;
+uint8_t g_default_mode = 3;
+static struct drm_display_mode edid_cea_modes[] = {
+ /* 3 - 720x480@60Hz */
+ { DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 27000, 720, 736,
+ 798, 858, 0, 480, 489, 495, 525, 0,
+ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
+ .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
+ /* 4 - 1280x720@60Hz */
+ { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 74250, 1280, 1390,
+ 1430, 1650, 0, 720, 725, 730, 750, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
+ .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
+ /* 16 - 1920x1080@60Hz */
+ { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 148500, 1920, 2008,
+ 2052, 2200, 0, 1080, 1084, 1089, 1125, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
+ .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
+ /* 97 - 3840x2160@60Hz */
+ { DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 594000,
+ 3840, 4016, 4104, 4400, 0,
+ 2160, 2168, 2178, 2250, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
+ .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
+ /* 96 - 3840x2160@30Hz */
+ { DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 297000,
+ 3840, 4016, 4104, 4400, 0,
+ 2160, 2168, 2178, 2250, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
+ .vrefresh = 30, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
+};
+
+static inline struct imx_hdp *enc_to_imx_hdp(struct drm_encoder *e)
+{
+ return container_of(e, struct imx_hdp, encoder);
+}
+
+static inline bool imx_hdp_is_dual_mode(struct drm_display_mode *mode)
+{
+ return (mode->clock > HDP_DUAL_MODE_MIN_PCLK_RATE ||
+ mode->hdisplay > HDP_SINGLE_MODE_MAX_WIDTH) ? true : false;
+}
+
+static void imx_hdp_state_init(struct imx_hdp *hdp)
+{
+ state_struct *state = &hdp->state;
+
+ memset(state, 0, sizeof(state_struct));
+ mutex_init(&state->mutex);
+
+ state->mem = &hdp->mem;
+ state->rw = hdp->rw;
+ state->edp = 0;
+}
+
+#ifdef CONFIG_IMX_HDP_CEC
+static void imx_hdp_cec_init(struct imx_hdp *hdp)
+{
+ state_struct *state = &hdp->state;
+ struct imx_cec_dev *cec = &hdp->cec;
+ u32 clk_MHz;
+
+ memset(cec, 0, sizeof(struct imx_cec_dev));
+
+ CDN_API_GetClock(state, &clk_MHz);
+ cec->clk_div = clk_MHz * 10;
+ cec->dev = hdp->dev;
+ cec->mem = &hdp->mem;
+ cec->rw = hdp->rw;
+}
+#endif
+
+#ifdef DEBUG_FW_LOAD
+void hdp_fw_load(state_struct *state)
+{
+ DRM_INFO("loading hdmi firmware\n");
+ CDN_API_LoadFirmware(state,
+ (u8 *)hdmitx_iram0_get_ptr(),
+ hdmitx_iram0_get_size(),
+ (u8 *)hdmitx_dram0_get_ptr(),
+ hdmitx_dram0_get_size());
+}
+#endif
+
+int hdp_fw_check(state_struct *state)
+{
+ u16 ver, verlib;
+ u8 echo_msg[] = "echo test";
+ u8 echo_resp[sizeof(echo_msg) + 1];
+ int ret;
+
+ ret = CDN_API_General_Test_Echo_Ext_blocking(state, echo_msg, echo_resp,
+ sizeof(echo_msg), CDN_BUS_TYPE_APB);
+
+ if (0 != strncmp(echo_msg, echo_resp, sizeof(echo_msg))) {
+ DRM_ERROR("CDN_API_General_Test_Echo_Ext_blocking - echo test failed, check firmware!");
+ return -ENXIO;
+ }
+ DRM_INFO("CDN_API_General_Test_Echo_Ext_blocking - APB(ret = %d echo_resp = %s)\n",
+ ret, echo_resp);
+
+ ret = CDN_API_General_getCurVersion(state, &ver, &verlib);
+ if (ret != 0) {
+ DRM_ERROR("CDN_API_General_getCurVersion - check firmware!\n");
+ return -ENXIO;
+ } else
+ DRM_INFO("CDN_API_General_getCurVersion - ver %d verlib %d\n",
+ ver, verlib);
+ /* we can add a check here to reject older firmware
+ * versions if needed */
+
+ return 0;
+}
+
+int hdp_fw_init(state_struct *state)
+{
+ struct imx_hdp *hdp = state_to_imx_hdp(state);
+ u32 core_rate;
+ int ret;
+ u8 sts;
+
+ core_rate = clk_get_rate(hdp->clks.clk_core);
+
+ /* configure the clock */
+ CDN_API_SetClock(state, core_rate/1000000);
+ pr_info("CDN_API_SetClock completed\n");
+
+ /* moved from CDN_API_LoadFirmware */
+ cdn_apb_write(state, APB_CTRL << 2, 0);
+ DRM_INFO("Started firmware!\n");
+
+ ret = CDN_API_CheckAlive_blocking(state);
+ if (ret != 0) {
+ DRM_ERROR("CDN_API_CheckAlive failed - check firmware!\n");
+ return -ENXIO;
+ } else
+ DRM_INFO("CDN_API_CheckAlive returned ret = %d\n", ret);
+
+ /* turn on IP activity */
+ ret = CDN_API_MainControl_blocking(state, 1, &sts);
+ DRM_INFO("CDN_API_MainControl_blocking ret = %d sts = %u\n", ret, sts);
+
+ ret = hdp_fw_check(state);
+ if (ret != 0) {
+ DRM_ERROR("hdmi_fw_check failed!\n");
+ return -ENXIO;
+ }
+
+ if (hdp->is_dp) {
+ /* Line swaping - DP only */
+ CDN_API_General_Write_Register_blocking(state,
+ ADDR_SOURCD_PHY +
+ (LANES_CONFIG << 2),
+ 0x00400000 |
+ hdp->dp_lane_mapping);
+ DRM_INFO("CDN_API_General_Write_* ... setting LANES_CONFIG\n");
+ }
+ return 0;
+}
+
+static void imx8qm_pixel_link_mux(state_struct *state,
+ struct drm_display_mode *mode)
+{
+ struct imx_hdp *hdp = state_to_imx_hdp(state);
+ u32 val;
+
+ val = 0x4; /* RGB */
+ if (hdp->dual_mode)
+ val |= 0x2; /* pixel link 0 and 1 are active */
+ if (mode->flags & DRM_MODE_FLAG_PVSYNC)
+ val |= 1 << PL_MUX_CTL_VCP_OFFSET;
+ if (mode->flags & DRM_MODE_FLAG_PHSYNC)
+ val |= 1 << PL_MUX_CTL_HCP_OFFSET;
+ if (mode->flags & DRM_MODE_FLAG_INTERLACE)
+ val |= 0x2;
+
+ writel(val, hdp->mem.ss_base + CSR_PIXEL_LINK_MUX_CTL);
+}
+
+static int imx8qm_pixel_link_validate(state_struct *state)
+{
+ struct imx_hdp *hdp = state_to_imx_hdp(state);
+ sc_err_t sciErr;
+
+ sciErr = sc_ipc_getMuID(&hdp->mu_id);
+ if (sciErr != SC_ERR_NONE) {
+ DRM_ERROR("Cannot obtain MU ID\n");
+ return -EINVAL;
+ }
+
+ sciErr = sc_ipc_open(&hdp->ipcHndl, hdp->mu_id);
+ if (sciErr != SC_ERR_NONE) {
+ DRM_ERROR("sc_ipc_open failed! (sciError = %d)\n",
+ sciErr);
+ return -EINVAL;
+ }
+
+ sciErr = sc_misc_set_control(hdp->ipcHndl, SC_R_DC_0,
+ SC_C_PXL_LINK_MST1_VLD, 1);
+ if (sciErr != SC_ERR_NONE) {
+ DRM_ERROR("SC_R_DC_0:SC_C_PXL_LINK_MST1_VLD sc_misc_set_control failed! (sciError = %d)\n",
+ sciErr);
+ return -EINVAL;
+ }
+ if (hdp->dual_mode) {
+ sciErr = sc_misc_set_control(hdp->ipcHndl, SC_R_DC_0,
+ SC_C_PXL_LINK_MST2_VLD, 1);
+ if (sciErr != SC_ERR_NONE) {
+ DRM_ERROR("SC_R_DC_0:SC_C_PXL_LINK_MST2_VLD sc_misc_set_control failed! (sciError = %d)\n", sciErr);
+ return -EINVAL;
+ }
+ }
+
+ sc_ipc_close(hdp->mu_id);
+
+ return 0;
+}
+
+static int imx8qm_pixel_link_invalidate(state_struct *state)
+{
+ struct imx_hdp *hdp = state_to_imx_hdp(state);
+ sc_err_t sciErr;
+
+ sciErr = sc_ipc_getMuID(&hdp->mu_id);
+ if (sciErr != SC_ERR_NONE) {
+ DRM_ERROR("Cannot obtain MU ID\n");
+ return -EINVAL;
+ }
+
+ sciErr = sc_ipc_open(&hdp->ipcHndl, hdp->mu_id);
+ if (sciErr != SC_ERR_NONE) {
+ DRM_ERROR("sc_ipc_open failed! (sciError = %d)\n", sciErr);
+ return -EINVAL;
+ }
+
+ sciErr = sc_misc_set_control(hdp->ipcHndl, SC_R_DC_0,
+ SC_C_PXL_LINK_MST1_VLD, 0);
+ if (sciErr != SC_ERR_NONE) {
+ DRM_ERROR("SC_R_DC_0:SC_C_PXL_LINK_MST1_VLD sc_misc_set_control failed! (sciError = %d)\n", sciErr);
+ return -EINVAL;
+ }
+ if (hdp->dual_mode) {
+ sciErr = sc_misc_set_control(hdp->ipcHndl, SC_R_DC_0,
+ SC_C_PXL_LINK_MST2_VLD, 0);
+ if (sciErr != SC_ERR_NONE) {
+ DRM_ERROR("SC_R_DC_0:SC_C_PXL_LINK_MST2_VLD sc_misc_set_control failed! (sciError = %d)\n", sciErr);
+ return -EINVAL;
+ }
+ }
+
+ sc_ipc_close(hdp->mu_id);
+
+ return 0;
+}
+
+static int imx8qm_pixel_link_sync_ctrl_enable(state_struct *state)
+{
+ struct imx_hdp *hdp = state_to_imx_hdp(state);
+ sc_err_t sciErr;
+
+ sciErr = sc_ipc_getMuID(&hdp->mu_id);
+ if (sciErr != SC_ERR_NONE) {
+ DRM_ERROR("Cannot obtain MU ID\n");
+ return -EINVAL;
+ }
+
+ sciErr = sc_ipc_open(&hdp->ipcHndl, hdp->mu_id);
+ if (sciErr != SC_ERR_NONE) {
+ DRM_ERROR("sc_ipc_open failed! (sciError = %d)\n", sciErr);
+ return -EINVAL;
+ }
+
+ if (hdp->dual_mode) {
+ sciErr = sc_misc_set_control(hdp->ipcHndl, SC_R_DC_0, SC_C_SYNC_CTRL, 3);
+ if (sciErr != SC_ERR_NONE) {
+ DRM_ERROR("SC_R_DC_0:SC_C_SYNC_CTRL sc_misc_set_control failed! (sciError = %d)\n", sciErr);
+ return -EINVAL;
+ }
+ } else {
+ sciErr = sc_misc_set_control(hdp->ipcHndl, SC_R_DC_0, SC_C_SYNC_CTRL0, 1);
+ if (sciErr != SC_ERR_NONE) {
+ DRM_ERROR("SC_R_DC_0:SC_C_SYNC_CTRL0 sc_misc_set_control failed! (sciError = %d)\n", sciErr);
+ return -EINVAL;
+ }
+ }
+
+ sc_ipc_close(hdp->mu_id);
+
+ return 0;
+}
+
+static int imx8qm_pixel_link_sync_ctrl_disable(state_struct *state)
+{
+ struct imx_hdp *hdp = state_to_imx_hdp(state);
+ sc_err_t sciErr;
+
+ sciErr = sc_ipc_getMuID(&hdp->mu_id);
+ if (sciErr != SC_ERR_NONE) {
+ DRM_ERROR("Cannot obtain MU ID\n");
+ return -EINVAL;
+ }
+
+ sciErr = sc_ipc_open(&hdp->ipcHndl, hdp->mu_id);
+ if (sciErr != SC_ERR_NONE) {
+ DRM_ERROR("sc_ipc_open failed! (sciError = %d)\n", sciErr);
+ return -EINVAL;
+ }
+
+
+ if (hdp->dual_mode) {
+ sciErr = sc_misc_set_control(hdp->ipcHndl, SC_R_DC_0, SC_C_SYNC_CTRL, 0);
+ if (sciErr != SC_ERR_NONE) {
+ DRM_ERROR("SC_R_DC_0:SC_C_SYNC_CTRL sc_misc_set_control failed! (sciError = %d)\n", sciErr);
+ return -EINVAL;
+ }
+ } else {
+ sciErr = sc_misc_set_control(hdp->ipcHndl, SC_R_DC_0, SC_C_SYNC_CTRL0, 0);
+ if (sciErr != SC_ERR_NONE) {
+ DRM_ERROR("SC_R_DC_0:SC_C_SYNC_CTRL0 sc_misc_set_control failed! (sciError = %d)\n", sciErr);
+ return -EINVAL;
+ }
+ }
+
+ sc_ipc_close(hdp->mu_id);
+
+ return 0;
+}
+
+void imx8qm_phy_reset(sc_ipc_t ipcHndl, struct hdp_mem *mem, u8 reset)
+{
+ sc_err_t sciErr;
+ /* set the pixel link mode and pixel type */
+ sciErr = sc_misc_set_control(ipcHndl, SC_R_HDMI, SC_C_PHY_RESET, reset);
+ if (sciErr != SC_ERR_NONE)
+ DRM_ERROR("SC_R_HDMI PHY reset failed %d!\n", sciErr);
+}
+
+void imx8mq_phy_reset(sc_ipc_t ipcHndl, struct hdp_mem *mem, u8 reset)
+{
+ void *tmp_addr = mem->rst_base;
+
+ if (reset)
+ __raw_writel(0x8,
+ (volatile unsigned int *)(tmp_addr+0x4)); /*set*/
+ else
+ __raw_writel(0x8,
+ (volatile unsigned int *)(tmp_addr+0x8)); /*clear*/
+
+
+ return;
+}
+
+int imx8qm_clock_init(struct hdp_clks *clks)
+{
+ struct imx_hdp *hdp = clks_to_imx_hdp(clks);
+ struct device *dev = hdp->dev;
+
+ clks->av_pll = devm_clk_get(dev, "av_pll");
+ if (IS_ERR(clks->av_pll)) {
+ dev_warn(dev, "failed to get av pll clk\n");
+ return PTR_ERR(clks->av_pll);
+ }
+
+ clks->dig_pll = devm_clk_get(dev, "dig_pll");
+ if (IS_ERR(clks->dig_pll)) {
+ dev_warn(dev, "failed to get dig pll clk\n");
+ return PTR_ERR(clks->dig_pll);
+ }
+
+ clks->clk_ipg = devm_clk_get(dev, "clk_ipg");
+ if (IS_ERR(clks->clk_ipg)) {
+ dev_warn(dev, "failed to get dp ipg clk\n");
+ return PTR_ERR(clks->clk_ipg);
+ }
+
+ clks->clk_core = devm_clk_get(dev, "clk_core");
+ if (IS_ERR(clks->clk_core)) {
+ dev_warn(dev, "failed to get hdp core clk\n");
+ return PTR_ERR(clks->clk_core);
+ }
+
+ clks->clk_pxl = devm_clk_get(dev, "clk_pxl");
+ if (IS_ERR(clks->clk_pxl)) {
+ dev_warn(dev, "failed to get pxl clk\n");
+ return PTR_ERR(clks->clk_pxl);
+ }
+
+ clks->clk_pxl_mux = devm_clk_get(dev, "clk_pxl_mux");
+ if (IS_ERR(clks->clk_pxl_mux)) {
+ dev_warn(dev, "failed to get pxl mux clk\n");
+ return PTR_ERR(clks->clk_pxl_mux);
+ }
+
+ clks->clk_pxl_link = devm_clk_get(dev, "clk_pxl_link");
+ if (IS_ERR(clks->clk_pxl_mux)) {
+ dev_warn(dev, "failed to get pxl link clk\n");
+ return PTR_ERR(clks->clk_pxl_link);
+ }
+
+ clks->clk_hdp = devm_clk_get(dev, "clk_hdp");
+ if (IS_ERR(clks->clk_hdp)) {
+ dev_warn(dev, "failed to get hdp clk\n");
+ return PTR_ERR(clks->clk_hdp);
+ }
+
+ clks->clk_phy = devm_clk_get(dev, "clk_phy");
+ if (IS_ERR(clks->clk_phy)) {
+ dev_warn(dev, "failed to get phy clk\n");
+ return PTR_ERR(clks->clk_phy);
+ }
+ clks->clk_apb = devm_clk_get(dev, "clk_apb");
+ if (IS_ERR(clks->clk_apb)) {
+ dev_warn(dev, "failed to get apb clk\n");
+ return PTR_ERR(clks->clk_apb);
+ }
+ clks->clk_lis = devm_clk_get(dev, "clk_lis");
+ if (IS_ERR(clks->clk_lis)) {
+ dev_warn(dev, "failed to get lis clk\n");
+ return PTR_ERR(clks->clk_lis);
+ }
+ clks->clk_msi = devm_clk_get(dev, "clk_msi");
+ if (IS_ERR(clks->clk_msi)) {
+ dev_warn(dev, "failed to get msi clk\n");
+ return PTR_ERR(clks->clk_msi);
+ }
+ clks->clk_lpcg = devm_clk_get(dev, "clk_lpcg");
+ if (IS_ERR(clks->clk_lpcg)) {
+ dev_warn(dev, "failed to get lpcg clk\n");
+ return PTR_ERR(clks->clk_lpcg);
+ }
+ clks->clk_even = devm_clk_get(dev, "clk_even");
+ if (IS_ERR(clks->clk_even)) {
+ dev_warn(dev, "failed to get even clk\n");
+ return PTR_ERR(clks->clk_even);
+ }
+ clks->clk_dbl = devm_clk_get(dev, "clk_dbl");
+ if (IS_ERR(clks->clk_dbl)) {
+ dev_warn(dev, "failed to get dbl clk\n");
+ return PTR_ERR(clks->clk_dbl);
+ }
+ clks->clk_vif = devm_clk_get(dev, "clk_vif");
+ if (IS_ERR(clks->clk_vif)) {
+ dev_warn(dev, "failed to get vif clk\n");
+ return PTR_ERR(clks->clk_vif);
+ }
+ clks->clk_apb_csr = devm_clk_get(dev, "clk_apb_csr");
+ if (IS_ERR(clks->clk_apb_csr)) {
+ dev_warn(dev, "failed to get apb csr clk\n");
+ return PTR_ERR(clks->clk_apb_csr);
+ }
+ clks->clk_apb_ctrl = devm_clk_get(dev, "clk_apb_ctrl");
+ if (IS_ERR(clks->clk_apb_ctrl)) {
+ dev_warn(dev, "failed to get apb ctrl clk\n");
+ return PTR_ERR(clks->clk_apb_ctrl);
+ }
+ clks->clk_i2s = devm_clk_get(dev, "clk_i2s");
+ if (IS_ERR(clks->clk_i2s)) {
+ dev_warn(dev, "failed to get i2s clk\n");
+ return PTR_ERR(clks->clk_i2s);
+ }
+ clks->clk_i2s_bypass = devm_clk_get(dev, "clk_i2s_bypass");
+ if (IS_ERR(clks->clk_i2s_bypass)) {
+ dev_err(dev, "failed to get i2s bypass clk\n");
+ return PTR_ERR(clks->clk_i2s_bypass);
+ }
+ return true;
+}
+
+int imx8qm_pixel_clock_enable(struct hdp_clks *clks)
+{
+ struct imx_hdp *hdp = clks_to_imx_hdp(clks);
+ struct device *dev = hdp->dev;
+ int ret;
+
+ ret = clk_prepare_enable(clks->av_pll);
+ if (ret < 0) {
+ dev_err(dev, "%s, pre av pll error\n", __func__);
+ return ret;
+ }
+
+ ret = clk_prepare_enable(clks->clk_pxl);
+ if (ret < 0) {
+ dev_err(dev, "%s, pre clk pxl error\n", __func__);
+ return ret;
+ }
+ ret = clk_prepare_enable(clks->clk_pxl_mux);
+ if (ret < 0) {
+ dev_err(dev, "%s, pre clk pxl mux error\n", __func__);
+ return ret;
+ }
+
+ ret = clk_prepare_enable(clks->clk_pxl_link);
+ if (ret < 0) {
+ dev_err(dev, "%s, pre clk pxl link error\n", __func__);
+ return ret;
+ }
+ ret = clk_prepare_enable(clks->clk_vif);
+ if (ret < 0) {
+ dev_err(dev, "%s, pre clk vif error\n", __func__);
+ return ret;
+ }
+ return ret;
+
+}
+
+void imx8qm_pixel_clock_disable(struct hdp_clks *clks)
+{
+ clk_disable_unprepare(clks->clk_vif);
+ clk_disable_unprepare(clks->clk_pxl);
+ clk_disable_unprepare(clks->clk_pxl_link);
+ clk_disable_unprepare(clks->clk_pxl_mux);
+ clk_disable_unprepare(clks->av_pll);
+}
+
+void imx8qm_dp_pixel_clock_set_rate(struct hdp_clks *clks)
+{
+ struct imx_hdp *hdp = clks_to_imx_hdp(clks);
+ unsigned int pclock = hdp->video.cur_mode.clock * 1000;
+
+ if (!hdp->is_digpll_dp_pclock) {
+ sc_err_t sci_err = 0;
+ sc_ipc_t ipc_handle = 0;
+ u32 mu_id;
+
+ sci_err = sc_ipc_getMuID(&mu_id);
+
+ if (sci_err != SC_ERR_NONE)
+ pr_err("Failed to get MU ID (%d)\n", sci_err);
+ sci_err = sc_ipc_open(&ipc_handle, mu_id);
+
+ if (sci_err != SC_ERR_NONE)
+ pr_err("Failed to open IPC (%d)\n", sci_err);
+
+ clk_set_rate(clks->av_pll, pclock);
+
+ /* Enable the 24MHz for HDP PHY */
+ sc_misc_set_control(ipc_handle, SC_R_HDMI, SC_C_MODE, 1);
+
+ sc_ipc_close(ipc_handle);
+ } else
+ clk_set_rate(clks->av_pll, 24000000);
+
+ if (hdp->dual_mode == true) {
+ clk_set_rate(clks->clk_pxl, pclock/2);
+ clk_set_rate(clks->clk_pxl_link, pclock/2);
+ } else {
+ clk_set_rate(clks->clk_pxl, pclock);
+ clk_set_rate(clks->clk_pxl_link, pclock);
+ }
+ clk_set_rate(clks->clk_pxl_mux, pclock);
+}
+
+void imx8qm_hdmi_pixel_clock_set_rate(struct hdp_clks *clks)
+{
+ struct imx_hdp *hdp = clks_to_imx_hdp(clks);
+ unsigned int pclock = hdp->video.cur_mode.clock * 1000;
+
+ /* pixel clock for HDMI */
+ clk_set_rate(clks->av_pll, pclock);
+
+ if (hdp->dual_mode == true) {
+ clk_set_rate(clks->clk_pxl, pclock/2);
+ clk_set_rate(clks->clk_pxl_link, pclock/2);
+ } else {
+ clk_set_rate(clks->clk_pxl_link, pclock);
+ clk_set_rate(clks->clk_pxl, pclock);
+ }
+ clk_set_rate(clks->clk_pxl_mux, pclock);
+}
+
+int imx8qm_ipg_clock_enable(struct hdp_clks *clks)
+{
+ int ret;
+ struct imx_hdp *hdp = clks_to_imx_hdp(clks);
+ struct device *dev = hdp->dev;
+
+ ret = clk_prepare_enable(clks->dig_pll);
+ if (ret < 0) {
+ dev_err(dev, "%s, pre dig pll error\n", __func__);
+ return ret;
+ }
+
+ ret = clk_prepare_enable(clks->clk_ipg);
+ if (ret < 0) {
+ dev_err(dev, "%s, pre clk_ipg error\n", __func__);
+ return ret;
+ }
+
+ ret = clk_prepare_enable(clks->clk_core);
+ if (ret < 0) {
+ dev_err(dev, "%s, pre clk core error\n", __func__);
+ return ret;
+ }
+
+ ret = clk_prepare_enable(clks->clk_hdp);
+ if (ret < 0) {
+ dev_err(dev, "%s, pre clk hdp error\n", __func__);
+ return ret;
+ }
+
+ ret = clk_prepare_enable(clks->clk_phy);
+ if (ret < 0) {
+ dev_err(dev, "%s, pre clk phy\n", __func__);
+ return ret;
+ }
+
+ ret = clk_prepare_enable(clks->clk_apb);
+ if (ret < 0) {
+ dev_err(dev, "%s, pre clk apb error\n", __func__);
+ return ret;
+ }
+ ret = clk_prepare_enable(clks->clk_lis);
+ if (ret < 0) {
+ dev_err(dev, "%s, pre clk lis error\n", __func__);
+ return ret;
+ }
+ ret = clk_prepare_enable(clks->clk_lpcg);
+ if (ret < 0) {
+ dev_err(dev, "%s, pre clk lpcg error\n", __func__);
+ return ret;
+ }
+ ret = clk_prepare_enable(clks->clk_msi);
+ if (ret < 0) {
+ dev_err(dev, "%s, pre clk msierror\n", __func__);
+ return ret;
+ }
+ ret = clk_prepare_enable(clks->clk_even);
+ if (ret < 0) {
+ dev_err(dev, "%s, pre clk even error\n", __func__);
+ return ret;
+ }
+ ret = clk_prepare_enable(clks->clk_dbl);
+ if (ret < 0) {
+ dev_err(dev, "%s, pre clk dbl error\n", __func__);
+ return ret;
+ }
+ ret = clk_prepare_enable(clks->clk_apb_csr);
+ if (ret < 0) {
+ dev_err(dev, "%s, pre clk apb csr error\n", __func__);
+ return ret;
+ }
+ ret = clk_prepare_enable(clks->clk_apb_ctrl);
+ if (ret < 0) {
+ dev_err(dev, "%s, pre clk apb ctrl error\n", __func__);
+ return ret;
+ }
+ ret = clk_prepare_enable(clks->clk_i2s);
+ if (ret < 0) {
+ dev_err(dev, "%s, pre clk i2s error\n", __func__);
+ return ret;
+ }
+ ret = clk_prepare_enable(clks->clk_i2s_bypass);
+ if (ret < 0) {
+ dev_err(dev, "%s, pre clk i2s bypass error\n", __func__);
+ return ret;
+ }
+ return ret;
+}
+
+void imx8qm_ipg_clock_disable(struct hdp_clks *clks)
+{
+}
+
+void imx8qm_ipg_clock_set_rate(struct hdp_clks *clks)
+{
+ struct imx_hdp *hdp = clks_to_imx_hdp(clks);
+ u32 clk_rate, desired_rate;
+
+ if (hdp->is_digpll_dp_pclock)
+ desired_rate = PLL_1188MHZ;
+ else
+ desired_rate = PLL_800MHZ;
+
+ /* hdmi/dp ipg/core clock */
+ clk_rate = clk_get_rate(clks->dig_pll);
+
+ if (clk_rate != desired_rate) {
+ pr_warn("%s, dig_pll was %u MHz, changing to %u MHz\n",
+ __func__, clk_rate/1000000,
+ desired_rate/1000000);
+ }
+
+ if (hdp->is_digpll_dp_pclock) {
+ clk_set_rate(clks->dig_pll, desired_rate);
+ clk_set_rate(clks->clk_core, desired_rate/10);
+ clk_set_rate(clks->clk_ipg, desired_rate/12);
+ clk_set_rate(clks->av_pll, 24000000);
+ } else {
+ clk_set_rate(clks->dig_pll, desired_rate);
+ clk_set_rate(clks->clk_core, desired_rate/4);
+ clk_set_rate(clks->clk_ipg, desired_rate/8);
+ }
+}
+
+static u8 imx_hdp_link_rate(struct drm_display_mode *mode)
+{
+ if (mode->clock < 297000)
+ return AFE_LINK_RATE_1_6;
+ else if (mode->clock > 297000)
+ return AFE_LINK_RATE_5_4;
+ else
+ return AFE_LINK_RATE_2_7;
+}
+
+static void imx_hdp_mode_setup(struct imx_hdp *hdp,
+ struct drm_display_mode *mode)
+{
+ int ret;
+
+ /* set pixel clock before video mode setup */
+ imx_hdp_call(hdp, pixel_clock_disable, &hdp->clks);
+
+ imx_hdp_call(hdp, pixel_clock_set_rate, &hdp->clks);
+
+ imx_hdp_call(hdp, pixel_clock_enable, &hdp->clks);
+
+ /* Config pixel link mux */
+ imx_hdp_call(hdp, pixel_link_mux, &hdp->state, mode);
+
+ hdp->link_rate = imx_hdp_link_rate(mode);
+ if (hdp->is_dp && hdp->link_rate > hdp->dp_link_rate) {
+ DRM_DEBUG("Lowering DP link rate from %d to %d\n",
+ hdp->link_rate, hdp->dp_link_rate);
+ hdp->link_rate = hdp->dp_link_rate;
+ }
+
+ /* mode set */
+ ret = imx_hdp_call(hdp, phy_init, &hdp->state, mode, hdp->format,
+ hdp->bpc);
+ if (ret < 0) {
+ DRM_ERROR("Failed to initialise HDP PHY\n");
+ return;
+ }
+ imx_hdp_call(hdp, mode_set, &hdp->state, mode,
+ hdp->format, hdp->bpc, hdp->link_rate);
+
+ /* Get vic of CEA-861 */
+ hdp->vic = drm_match_cea_mode(mode);
+}
+
+bool imx_hdp_bridge_mode_fixup(struct drm_bridge *bridge,
+ const struct drm_display_mode *mode,
+ struct drm_display_mode *adjusted_mode)
+{
+ struct imx_hdp *hdp = bridge->driver_private;
+ int vic = drm_match_cea_mode(mode);
+
+ if (vic < 0)
+ return false;
+
+ if (hdp && hdp->ops && hdp->ops->mode_fixup)
+ return hdp->ops->mode_fixup(&hdp->state, mode, adjusted_mode);
+
+ return true;
+}
+
+static void imx_hdp_bridge_mode_set(struct drm_bridge *bridge,
+ struct drm_display_mode *orig_mode,
+ struct drm_display_mode *mode)
+{
+ struct imx_hdp *hdp = bridge->driver_private;
+
+ mutex_lock(&hdp->mutex);
+
+ hdp->dual_mode = imx_hdp_is_dual_mode(mode);
+
+ memcpy(&hdp->video.cur_mode, mode, sizeof(hdp->video.cur_mode));
+ imx_hdp_mode_setup(hdp, mode);
+ /* Store the display mode for plugin/DKMS poweron events */
+ memcpy(&hdp->video.pre_mode, mode, sizeof(hdp->video.pre_mode));
+
+ mutex_unlock(&hdp->mutex);
+}
+
+static void imx_hdp_bridge_disable(struct drm_bridge *bridge)
+{
+}
+
+static void imx_hdp_bridge_enable(struct drm_bridge *bridge)
+{
+ struct imx_hdp *hdp = bridge->driver_private;
+
+ /*
+ * When switching from 10-bit to 8-bit color depths, iMX8MQ needs the
+ * PHY pixel engine to be reset after all clocks are ON, not before.
+ * So, we do it in the enable callback.
+ *
+ * Since the reset does not do any harm when switching from a 8-bit mode
+ * to another 8-bit mode, or from 8-bit to 10-bit, we can safely do it
+ * all the time.
+ */
+ if (cpu_is_imx8mq())
+ imx_hdp_call(hdp, pixel_engine_reset, &hdp->state);
+}
+
+static enum drm_connector_status
+imx_hdp_connector_detect(struct drm_connector *connector, bool force)
+{
+ struct imx_hdp *hdp = container_of(connector,
+ struct imx_hdp, connector);
+ int ret;
+ u8 hpd = 0xf;
+
+ ret = imx_hdp_call(hdp, get_hpd_state, &hdp->state, &hpd);
+ if (ret > 0)
+ return connector_status_unknown;
+
+ if (hpd == 1)
+ /* Cable Connected */
+ return connector_status_connected;
+ else if (hpd == 0)
+ /* Cable Disconnedted */
+ return connector_status_disconnected;
+ else {
+ /* Cable status unknown */
+ DRM_INFO("Unknow cable status, hdp=%u\n", hpd);
+ return connector_status_unknown;
+ }
+}
+
+static int imx_hdp_default_video_modes(struct drm_connector *connector)
+{
+ struct drm_display_mode *mode;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(edid_cea_modes); i++) {
+ mode = drm_mode_create(connector->dev);
+ if (!mode)
+ return -EINVAL;
+ drm_mode_copy(mode, &edid_cea_modes[i]);
+ mode->type |= DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
+ drm_mode_probed_add(connector, mode);
+ }
+ return i;
+}
+
+static int imx_hdp_connector_get_modes(struct drm_connector *connector)
+{
+ struct imx_hdp *hdp = container_of(connector, struct imx_hdp,
+ connector);
+ struct edid *edid;
+ int num_modes = 0;
+
+ if (!hdp->no_edid) {
+ edid = drm_do_get_edid(connector, hdp->ops->get_edid_block,
+ &hdp->state);
+ if (edid) {
+ dev_info(hdp->dev, "%x,%x,%x,%x,%x,%x,%x,%x\n",
+ edid->header[0], edid->header[1],
+ edid->header[2], edid->header[3],
+ edid->header[4], edid->header[5],
+ edid->header[6], edid->header[7]);
+ drm_mode_connector_update_edid_property(connector,
+ edid);
+ num_modes = drm_add_edid_modes(connector, edid);
+ if (num_modes == 0) {
+ dev_warn(hdp->dev, "Invalid edid, use default video modes\n");
+ num_modes =
+ imx_hdp_default_video_modes(connector);
+ } else
+ /* Store the ELD */
+ drm_edid_to_eld(connector, edid);
+ kfree(edid);
+ } else {
+ dev_info(hdp->dev, "failed to get edid, use default video modes\n");
+ num_modes = imx_hdp_default_video_modes(connector);
+ hdp->no_edid = true;
+ }
+ } else {
+ dev_warn(hdp->dev,
+ "No EDID function, use default video mode\n");
+ num_modes = imx_hdp_default_video_modes(connector);
+ }
+
+ return num_modes;
+}
+
+static enum drm_mode_status
+imx_hdp_connector_mode_valid(struct drm_connector *connector,
+ struct drm_display_mode *mode)
+{
+ struct imx_hdp *hdp = container_of(connector, struct imx_hdp,
+ connector);
+ enum drm_mode_status mode_status = MODE_OK;
+ struct drm_cmdline_mode *cmdline_mode;
+ int ret;
+
+ cmdline_mode = &connector->cmdline_mode;
+
+ /* cmdline mode is the max support video mode when edid disabled
+ * Add max support pixel rate to 297MHz in case no DDC function with no EDID */
+ if (hdp->no_edid) {
+ if (cmdline_mode->xres != 0 &&
+ cmdline_mode->xres < mode->hdisplay)
+ return MODE_BAD_HVALUE;
+ if (mode->clock > 297000)
+ return MODE_CLOCK_HIGH;
+ }
+
+ /* For iMX8QM A0 Max support video mode is 4kp30 */
+ if (cpu_is_imx8qm() && (imx8_get_soc_revision() < B0_SILICON_ID))
+ if (mode->clock > 297000)
+ return MODE_CLOCK_HIGH;
+
+ /* MAX support pixel clock rate 594MHz */
+ if (mode->clock > 594000)
+ return MODE_CLOCK_HIGH;
+
+ ret = imx_hdp_call(hdp, pixel_clock_range, mode);
+ if (ret == 0) {
+ DRM_DEBUG("pixel clock %d out of range\n", mode->clock);
+ return MODE_CLOCK_RANGE;
+ }
+
+ /* 4096x2160 is not supported now */
+ if (mode->hdisplay > 3840)
+ return MODE_BAD_HVALUE;
+
+ if (mode->vdisplay > 2160)
+ return MODE_BAD_VVALUE;
+
+ return mode_status;
+}
+
+static void imx_hdp_connector_force(struct drm_connector *connector)
+{
+ struct imx_hdp *hdp = container_of(connector, struct imx_hdp,
+ connector);
+ mutex_lock(&hdp->mutex);
+ hdp->force = connector->force;
+ mutex_unlock(&hdp->mutex);
+}
+
+static int imx_hdp_set_property(struct drm_connector *connector,
+ struct drm_connector_state *state,
+ struct drm_property *property, uint64_t val)
+{
+ struct imx_hdp *hdp = container_of(connector, struct imx_hdp,
+ connector);
+ int ret;
+ union hdmi_infoframe frame;
+ struct hdr_static_metadata *hdr_metadata;
+
+ if (state->hdr_source_metadata_blob_ptr &&
+ state->hdr_source_metadata_blob_ptr->length &&
+ hdp->ops->write_hdr_metadata) {
+ hdr_metadata = (struct hdr_static_metadata *)
+ state->hdr_source_metadata_blob_ptr->data;
+
+ ret = drm_hdmi_infoframe_set_hdr_metadata(&frame.drm,
+ hdr_metadata);
+
+ if (ret < 0) {
+ DRM_ERROR("could not set HDR metadata in infoframe\n");
+ return ret;
+ }
+
+ hdp->ops->write_hdr_metadata(&hdp->state, &frame);
+ }
+
+ return 0;
+}
+
+static int imx_hdp_connector_atomic_check(struct drm_connector *conn,
+ struct drm_connector_state *new_state)
+{
+ struct drm_connector_state *old_state =
+ drm_atomic_get_old_connector_state(new_state->state, conn);
+ struct drm_crtc_state *crtc_state;
+
+ imx_hdcp_atomic_check(conn, old_state, new_state);
+
+ if (!new_state->crtc)
+ return 0;
+
+ crtc_state = drm_atomic_get_new_crtc_state(new_state->state,
+ new_state->crtc);
+
+ /*
+ * These properties are handled by fastset, and might not end up in a
+ * modeset.
+ */
+ if (new_state->picture_aspect_ratio !=
+ old_state->picture_aspect_ratio ||
+ new_state->content_type != old_state->content_type ||
+ new_state->scaling_mode != old_state->scaling_mode)
+ crtc_state->mode_changed = true;
+
+ return 0;
+}
+
+static const struct drm_connector_funcs imx_hdp_connector_funcs = {
+ .fill_modes = drm_helper_probe_single_connector_modes,
+ .detect = imx_hdp_connector_detect,
+ .destroy = drm_connector_cleanup,
+ .force = imx_hdp_connector_force,
+ .reset = drm_atomic_helper_connector_reset,
+ .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
+ .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
+ .atomic_set_property = imx_hdp_set_property,
+};
+
+static const struct drm_connector_helper_funcs
+imx_hdp_connector_helper_funcs = {
+ .get_modes = imx_hdp_connector_get_modes,
+ .mode_valid = imx_hdp_connector_mode_valid,
+ .atomic_check = imx_hdp_connector_atomic_check,
+
+};
+
+static const struct drm_bridge_funcs imx_hdp_bridge_funcs = {
+ .enable = imx_hdp_bridge_enable,
+ .disable = imx_hdp_bridge_disable,
+ .mode_set = imx_hdp_bridge_mode_set,
+ .mode_fixup = imx_hdp_bridge_mode_fixup,
+};
+
+static void imx_hdp_imx_encoder_disable(struct drm_encoder *encoder)
+{
+ struct imx_hdp *hdp = container_of(encoder, struct imx_hdp, encoder);
+
+ imx_hdcp_disable(hdp);
+
+ imx_hdp_call(hdp, pixel_link_sync_ctrl_disable, &hdp->state);
+ imx_hdp_call(hdp, pixel_link_invalidate, &hdp->state);
+}
+
+static void imx_hdp_imx_encoder_enable(struct drm_encoder *encoder)
+{
+ struct imx_hdp *hdp = container_of(encoder, struct imx_hdp, encoder);
+ union hdmi_infoframe frame;
+ struct hdr_static_metadata *hdr_metadata;
+ struct drm_connector_state *conn_state = hdp->connector.state;
+ int ret = 0;
+
+ if (conn_state->content_protection ==
+ DRM_MODE_CONTENT_PROTECTION_DESIRED)
+ imx_hdcp_enable(hdp);
+
+ if (!hdp->ops->write_hdr_metadata)
+ goto out;
+
+ if (hdp->hdr_metadata_present) {
+ hdr_metadata = (struct hdr_static_metadata *)
+ conn_state->hdr_source_metadata_blob_ptr->data;
+
+ ret = drm_hdmi_infoframe_set_hdr_metadata(&frame.drm,
+ hdr_metadata);
+ } else {
+ hdr_metadata = devm_kzalloc(hdp->dev,
+ sizeof(struct hdr_static_metadata),
+ GFP_KERNEL);
+ hdr_metadata->eotf = 0;
+
+ ret = drm_hdmi_infoframe_set_hdr_metadata(&frame.drm,
+ hdr_metadata);
+
+ devm_kfree(hdp->dev, hdr_metadata);
+ }
+
+ if (ret < 0) {
+ DRM_ERROR("could not set HDR metadata in infoframe\n");
+ return;
+ }
+
+ hdp->ops->write_hdr_metadata(&hdp->state, &frame);
+
+out:
+ imx_hdp_call(hdp, pixel_link_validate, &hdp->state);
+ imx_hdp_call(hdp, pixel_link_sync_ctrl_enable, &hdp->state);
+}
+
+static int imx_hdp_imx_encoder_atomic_check(struct drm_encoder *encoder,
+ struct drm_crtc_state *crtc_state,
+ struct drm_connector_state *conn_state)
+{
+ struct imx_crtc_state *imx_crtc_state = to_imx_crtc_state(crtc_state);
+ struct imx_hdp *hdp = container_of(encoder, struct imx_hdp, encoder);
+
+ imx_crtc_state->bus_format = MEDIA_BUS_FMT_RGB101010_1X30;
+
+ if (conn_state->hdr_metadata_changed &&
+ conn_state->hdr_source_metadata_blob_ptr &&
+ conn_state->hdr_source_metadata_blob_ptr->length)
+ hdp->hdr_metadata_present = true;
+
+ return 0;
+}
+
+static const struct drm_encoder_helper_funcs
+imx_hdp_imx_encoder_helper_funcs = {
+ .enable = imx_hdp_imx_encoder_enable,
+ .disable = imx_hdp_imx_encoder_disable,
+ .atomic_check = imx_hdp_imx_encoder_atomic_check,
+};
+
+static const struct drm_encoder_funcs imx_hdp_imx_encoder_funcs = {
+ .destroy = drm_encoder_cleanup,
+};
+
+static int imx8mq_hdp_read(struct hdp_mem *mem,
+ unsigned int addr,
+ unsigned int *value)
+{
+ unsigned int temp;
+ void *tmp_addr;
+
+ mutex_lock(&mem->mutex);
+ tmp_addr = mem->regs_base + addr;
+ temp = __raw_readl((volatile unsigned int *)tmp_addr);
+ *value = temp;
+ mutex_unlock(&mem->mutex);
+ return 0;
+}
+
+static int imx8mq_hdp_write(struct hdp_mem *mem,
+ unsigned int addr,
+ unsigned int value)
+{
+ void *tmp_addr;
+
+ mutex_lock(&mem->mutex);
+ tmp_addr = mem->regs_base + addr;
+ __raw_writel(value, (volatile unsigned int *)tmp_addr);
+ mutex_unlock(&mem->mutex);
+ return 0;
+}
+
+static int imx8mq_hdp_sread(struct hdp_mem *mem,
+ unsigned int addr,
+ unsigned int *value)
+{
+ unsigned int temp;
+ void *tmp_addr;
+
+ mutex_lock(&mem->mutex);
+ tmp_addr = mem->ss_base + addr;
+ temp = __raw_readl((volatile unsigned int *)tmp_addr);
+ *value = temp;
+ mutex_unlock(&mem->mutex);
+ return 0;
+}
+
+static int imx8mq_hdp_swrite(struct hdp_mem *mem,
+ unsigned int addr,
+ unsigned int value)
+{
+ void *tmp_addr;
+
+ mutex_lock(&mem->mutex);
+ tmp_addr = mem->ss_base + addr;
+ __raw_writel(value, (volatile unsigned int *)tmp_addr);
+ mutex_unlock(&mem->mutex);
+ return 0;
+}
+
+static int imx8qm_hdp_read(struct hdp_mem *mem,
+ unsigned int addr,
+ unsigned int *value)
+{
+ unsigned int temp;
+ void *tmp_addr;
+ void *off_addr;
+
+ mutex_lock(&mem->mutex);
+ tmp_addr = (addr & 0xfff) + mem->regs_base;
+ off_addr = 0x8 + mem->ss_base;
+ __raw_writel(addr >> 12, off_addr);
+ temp = __raw_readl((volatile unsigned int *)tmp_addr);
+
+ *value = temp;
+ mutex_unlock(&mem->mutex);
+ return 0;
+}
+
+static int imx8qm_hdp_write(struct hdp_mem *mem,
+ unsigned int addr,
+ unsigned int value)
+{
+ void *tmp_addr;
+ void *off_addr;
+
+ mutex_lock(&mem->mutex);
+ tmp_addr = (addr & 0xfff) + mem->regs_base;
+ off_addr = 0x8 + mem->ss_base;
+ __raw_writel(addr >> 12, off_addr);
+
+ __raw_writel(value, (volatile unsigned int *) tmp_addr);
+ mutex_unlock(&mem->mutex);
+
+ return 0;
+}
+
+static int imx8qm_hdp_sread(struct hdp_mem *mem,
+ unsigned int addr,
+ unsigned int *value)
+{
+ unsigned int temp;
+ void *tmp_addr;
+ void *off_addr;
+
+ mutex_lock(&mem->mutex);
+ tmp_addr = (addr & 0xfff) + mem->regs_base;
+ off_addr = 0xc + mem->ss_base;
+ __raw_writel(addr >> 12, off_addr);
+
+ temp = __raw_readl((volatile unsigned int *)tmp_addr);
+ *value = temp;
+ mutex_unlock(&mem->mutex);
+ return 0;
+}
+
+static int imx8qm_hdp_swrite(struct hdp_mem *mem,
+ unsigned int addr,
+ unsigned int value)
+{
+ void *tmp_addr;
+ void *off_addr;
+
+ mutex_lock(&mem->mutex);
+ tmp_addr = (addr & 0xfff) + mem->regs_base;
+ off_addr = 0xc + mem->ss_base;
+ __raw_writel(addr >> 12, off_addr);
+ __raw_writel(value, (volatile unsigned int *)tmp_addr);
+ mutex_unlock(&mem->mutex);
+
+ return 0;
+}
+
+static struct hdp_rw_func imx8qm_rw = {
+ .read_reg = imx8qm_hdp_read,
+ .write_reg = imx8qm_hdp_write,
+ .sread_reg = imx8qm_hdp_sread,
+ .swrite_reg = imx8qm_hdp_swrite,
+};
+
+static struct hdp_ops imx8qm_dp_ops = {
+#ifdef DEBUG_FW_LOAD
+ .fw_load = hdp_fw_load,
+#endif
+ .fw_init = hdp_fw_init,
+ .phy_init = dp_phy_init,
+ .mode_set = dp_mode_set,
+ .get_edid_block = dp_get_edid_block,
+ .get_hpd_state = dp_get_hpd_state,
+
+ .phy_reset = imx8qm_phy_reset,
+ .pixel_link_validate = imx8qm_pixel_link_validate,
+ .pixel_link_invalidate = imx8qm_pixel_link_invalidate,
+ .pixel_link_sync_ctrl_enable = imx8qm_pixel_link_sync_ctrl_enable,
+ .pixel_link_sync_ctrl_disable = imx8qm_pixel_link_sync_ctrl_disable,
+ .pixel_link_mux = imx8qm_pixel_link_mux,
+
+ .clock_init = imx8qm_clock_init,
+ .ipg_clock_set_rate = imx8qm_ipg_clock_set_rate,
+ .ipg_clock_enable = imx8qm_ipg_clock_enable,
+ .ipg_clock_disable = imx8qm_ipg_clock_disable,
+ .pixel_clock_set_rate = imx8qm_dp_pixel_clock_set_rate,
+ .pixel_clock_enable = imx8qm_pixel_clock_enable,
+ .pixel_clock_disable = imx8qm_pixel_clock_disable,
+};
+
+static struct hdp_ops imx8qm_hdmi_ops = {
+#ifdef DEBUG_FW_LOAD
+ .fw_load = hdp_fw_load,
+#endif
+ .fw_init = hdp_fw_init,
+ .phy_init = hdmi_phy_init_ss28fdsoi,
+ .mode_set = hdmi_mode_set_ss28fdsoi,
+ .get_edid_block = hdmi_get_edid_block,
+ .get_hpd_state = hdmi_get_hpd_state,
+
+ .phy_reset = imx8qm_phy_reset,
+ .pixel_link_validate = imx8qm_pixel_link_validate,
+ .pixel_link_invalidate = imx8qm_pixel_link_invalidate,
+ .pixel_link_sync_ctrl_enable = imx8qm_pixel_link_sync_ctrl_enable,
+ .pixel_link_sync_ctrl_disable = imx8qm_pixel_link_sync_ctrl_disable,
+ .pixel_link_mux = imx8qm_pixel_link_mux,
+
+ .clock_init = imx8qm_clock_init,
+ .ipg_clock_set_rate = imx8qm_ipg_clock_set_rate,
+ .ipg_clock_enable = imx8qm_ipg_clock_enable,
+ .ipg_clock_disable = imx8qm_ipg_clock_disable,
+ .pixel_clock_set_rate = imx8qm_hdmi_pixel_clock_set_rate,
+ .pixel_clock_enable = imx8qm_pixel_clock_enable,
+ .pixel_clock_disable = imx8qm_pixel_clock_disable,
+};
+
+static struct hdp_devtype imx8qm_dp_devtype = {
+ .audio_type = CDN_DPTX,
+ .ops = &imx8qm_dp_ops,
+ .rw = &imx8qm_rw,
+ .connector_type = DRM_MODE_CONNECTOR_DisplayPort,
+};
+
+static struct hdp_devtype imx8qm_hdmi_devtype = {
+ .audio_type = CDN_HDMITX_TYPHOON,
+ .ops = &imx8qm_hdmi_ops,
+ .rw = &imx8qm_rw,
+ .connector_type = DRM_MODE_CONNECTOR_HDMIA,
+};
+
+static struct hdp_rw_func imx8mq_rw = {
+ .read_reg = imx8mq_hdp_read,
+ .write_reg = imx8mq_hdp_write,
+ .sread_reg = imx8mq_hdp_sread,
+ .swrite_reg = imx8mq_hdp_swrite,
+};
+
+static struct hdp_ops imx8mq_ops = {
+ .fw_init = hdp_fw_check,
+ .phy_init = hdmi_phy_init_t28hpc,
+ .mode_set = hdmi_mode_set_t28hpc,
+ .mode_fixup = hdmi_mode_fixup_t28hpc,
+ .get_edid_block = hdmi_get_edid_block,
+ .get_hpd_state = hdmi_get_hpd_state,
+ .write_hdr_metadata = hdmi_write_hdr_metadata,
+ .pixel_clock_range = pixel_clock_range_t28hpc,
+ .pixel_engine_reset = hdmi_phy_pix_engine_reset_t28hpc,
+};
+
+static struct hdp_devtype imx8mq_hdmi_devtype = {
+ .audio_type = CDN_HDMITX_KIRAN,
+ .ops = &imx8mq_ops,
+ .rw = &imx8mq_rw,
+ .connector_type = DRM_MODE_CONNECTOR_HDMIA,
+
+};
+
+static struct hdp_ops imx8mq_dp_ops = {
+ .fw_init = hdp_fw_check,
+ .phy_init = dp_phy_init_t28hpc,
+ .mode_set = dp_mode_set,
+ .get_edid_block = dp_get_edid_block,
+ .get_hpd_state = dp_get_hpd_state,
+ .phy_reset = imx8mq_phy_reset,
+};
+
+static struct hdp_devtype imx8mq_dp_devtype = {
+ .audio_type = CDN_DPTX,
+ .ops = &imx8mq_dp_ops,
+ .rw = &imx8mq_rw,
+ .connector_type = DRM_MODE_CONNECTOR_DisplayPort,
+};
+
+static const struct of_device_id imx_hdp_dt_ids[] = {
+ { .compatible = "fsl,imx8qm-hdmi", .data = &imx8qm_hdmi_devtype},
+ { .compatible = "fsl,imx8qm-dp", .data = &imx8qm_dp_devtype},
+ { .compatible = "fsl,imx8mq-hdmi", .data = &imx8mq_hdmi_devtype},
+ { .compatible = "fsl,imx8mq-dp", .data = &imx8mq_dp_devtype},
+ { }
+};
+MODULE_DEVICE_TABLE(of, imx_hdp_dt_ids);
+
+static void hotplug_work_func(struct work_struct *work)
+{
+ struct imx_hdp *hdp = container_of(work,
+ struct imx_hdp,
+ hotplug_work.work);
+ struct drm_connector *connector = &hdp->connector;
+
+ drm_helper_hpd_irq_event(connector->dev);
+
+ if (connector->status == connector_status_connected) {
+ /* Cable Connected */
+ /* For HDMI2.0 SCDC should setup again.
+ * So recovery pre video mode if it is 4Kp60 */
+ if (drm_mode_equal(&hdp->video.pre_mode,
+ &edid_cea_modes[g_default_mode]))
+ imx_hdp_mode_setup(hdp, &hdp->video.pre_mode);
+ DRM_INFO("HDMI/DP Cable Plug In\n");
+ enable_irq(hdp->irq[HPD_IRQ_OUT]);
+ } else if (connector->status == connector_status_disconnected) {
+ /* Cable Disconnedted */
+ DRM_INFO("HDMI/DP Cable Plug Out\n");
+ enable_irq(hdp->irq[HPD_IRQ_IN]);
+ }
+}
+
+static irqreturn_t imx_hdp_irq_thread(int irq, void *data)
+{
+ struct imx_hdp *hdp = data;
+
+ disable_irq_nosync(irq);
+
+ mod_delayed_work(system_wq, &hdp->hotplug_work,
+ msecs_to_jiffies(HOTPLUG_DEBOUNCE_MS));
+
+ return IRQ_HANDLED;
+}
+
+static int imx_hdp_imx_bind(struct device *dev, struct device *master,
+ void *data)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct drm_device *drm = data;
+ struct imx_hdp *hdp;
+ const struct of_device_id *of_id =
+ of_match_device(imx_hdp_dt_ids, dev);
+ const struct hdp_devtype *devtype = of_id->data;
+ struct drm_encoder *encoder;
+ struct drm_bridge *bridge;
+ struct drm_connector *connector;
+ struct resource *res;
+ u8 hpd;
+ int ret;
+
+ if (!pdev->dev.of_node)
+ return -ENODEV;
+
+ hdp = devm_kzalloc(&pdev->dev, sizeof(*hdp), GFP_KERNEL);
+ if (!hdp)
+ return -ENOMEM;
+
+ hdp->dev = &pdev->dev;
+ hdp->drm_dev = drm;
+ encoder = &hdp->encoder;
+ bridge = &hdp->bridge;
+ connector = &hdp->connector;
+
+ mutex_init(&hdp->mutex);
+
+ hdp->irq[HPD_IRQ_IN] = platform_get_irq_byname(pdev, "plug_in");
+ if (hdp->irq[HPD_IRQ_IN] < 0)
+ dev_info(&pdev->dev, "No plug_in irq number\n");
+
+ hdp->irq[HPD_IRQ_OUT] = platform_get_irq_byname(pdev, "plug_out");
+ if (hdp->irq[HPD_IRQ_OUT] < 0)
+ dev_info(&pdev->dev, "No plug_out irq number\n");
+
+
+ mutex_init(&hdp->mem.mutex);
+ /* register map */
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ hdp->mem.regs_base = devm_ioremap_resource(dev, res);
+ if (IS_ERR(hdp->mem.regs_base)) {
+ dev_err(dev, "Failed to get HDP CTRL base register\n");
+ return -EINVAL;
+ }
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+ hdp->mem.ss_base = devm_ioremap_resource(dev, res);
+ if (IS_ERR(hdp->mem.ss_base)) {
+ dev_err(dev, "Failed to get HDP CRS base register\n");
+ return -EINVAL;
+ }
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 2);
+ hdp->mem.rst_base = devm_ioremap_resource(dev, res);
+ if (IS_ERR(hdp->mem.rst_base))
+ dev_warn(dev, "Failed to get HDP RESET base register\n");
+
+ hdp->is_cec = of_property_read_bool(pdev->dev.of_node, "fsl,cec");
+
+ hdp->is_digpll_dp_pclock =
+ of_property_read_bool(pdev->dev.of_node,
+ "fsl,use_digpll_pclock");
+
+ hdp->no_edid = of_property_read_bool(pdev->dev.of_node, "fsl,no_edid");
+
+ /* EDID function is not supported by iMX8QM A0 */
+ if (cpu_is_imx8qm() && (imx8_get_soc_revision() < B0_SILICON_ID))
+ hdp->no_edid = true;
+
+ if (devtype->connector_type == DRM_MODE_CONNECTOR_DisplayPort) {
+ hdp->is_dp = true;
+ hdp->is_edp = of_property_read_bool(pdev->dev.of_node, "fsl,edp");
+
+ ret = of_property_read_u32(pdev->dev.of_node,
+ "dp-lane-mapping",
+ &hdp->dp_lane_mapping);
+ if (ret) {
+ hdp->dp_lane_mapping = 0x1b;
+ dev_warn(dev, "Failed to get lane_mapping - using default\n");
+ }
+ dev_info(dev, "dp-lane-mapping 0x%02x\n", hdp->dp_lane_mapping);
+
+ ret = of_property_read_u32(pdev->dev.of_node,
+ "dp-link-rate",
+ &hdp->dp_link_rate);
+ if (ret) {
+ hdp->dp_link_rate = AFE_LINK_RATE_1_6;
+ hdp->link_rate = AFE_LINK_RATE_1_6;
+ dev_warn(dev, "Failed to get dp-link-rate - using default\n");
+ } else
+ hdp->link_rate = hdp->dp_link_rate;
+ dev_info(dev, "dp-link-rate 0x%02x\n", hdp->dp_link_rate);
+
+ ret = of_property_read_u32(pdev->dev.of_node,
+ "dp-num-lanes",
+ &hdp->dp_num_lanes);
+ if (ret) {
+ hdp->dp_num_lanes = 4;
+ dev_warn(dev, "Failed to get dp_num_lanes - using default\n");
+ }
+ dev_info(dev, "dp_num_lanes 0x%02x\n", hdp->dp_num_lanes);
+
+ }
+
+ hdp->audio_type = devtype->audio_type;
+ hdp->ops = devtype->ops;
+ hdp->rw = devtype->rw;
+ hdp->bpc = 8;
+ hdp->format = PXL_RGB;
+
+ /* HDP controller init */
+ imx_hdp_state_init(hdp);
+
+ hdp->dual_mode = false;
+ ret = imx_hdp_call(hdp, clock_init, &hdp->clks);
+ if (ret < 0) {
+ DRM_ERROR("Failed to initialize clock\n");
+ return ret;
+ }
+
+ imx_hdp_call(hdp, ipg_clock_set_rate, &hdp->clks);
+
+ ret = imx_hdp_call(hdp, ipg_clock_enable, &hdp->clks);
+ if (ret < 0) {
+ DRM_ERROR("Failed to initialize IPG clock\n");
+ return ret;
+ }
+
+ imx_hdp_call(hdp, pixel_clock_set_rate, &hdp->clks);
+
+ imx_hdp_call(hdp, pixel_clock_enable, &hdp->clks);
+
+ imx_hdp_call(hdp, phy_reset, hdp->ipcHndl, &hdp->mem, 0);
+
+ imx_hdp_call(hdp, fw_load, &hdp->state);
+
+ ret = imx_hdp_call(hdp, fw_init, &hdp->state);
+ if (ret < 0) {
+ DRM_ERROR("Failed to initialise HDP firmware\n");
+ return ret;
+ }
+
+ /* Pixel Format - 1 RGB, 2 YCbCr 444, 3 YCbCr 420 */
+ /* bpp (bits per subpixel) - 8 24bpp, 10 30bpp, 12 36bpp, 16 48bpp */
+ /* default set hdmi to 1080p60 mode */
+ ret = imx_hdp_call(hdp, phy_init, &hdp->state,
+ &edid_cea_modes[g_default_mode],
+ hdp->format, hdp->bpc);
+ if (ret < 0) {
+ DRM_ERROR("Failed to initialise HDP PHY\n");
+ return ret;
+ }
+
+ /* encoder */
+ 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;
+
+ /* encoder */
+ drm_encoder_helper_add(encoder, &imx_hdp_imx_encoder_helper_funcs);
+ drm_encoder_init(drm, encoder, &imx_hdp_imx_encoder_funcs,
+ DRM_MODE_ENCODER_TMDS, NULL);
+
+ /* bridge */
+ bridge->encoder = encoder;
+ bridge->driver_private = hdp;
+ bridge->funcs = &imx_hdp_bridge_funcs;
+ ret = drm_bridge_attach(encoder, bridge, NULL);
+ if (ret) {
+ DRM_ERROR("Failed to initialize bridge with drm\n");
+ return -EINVAL;
+ }
+
+ encoder->bridge = bridge;
+ hdp->connector.polled = DRM_CONNECTOR_POLL_HPD;
+ hdp->connector.ycbcr_420_allowed = true;
+
+ /* connector */
+ drm_connector_helper_add(connector,
+ &imx_hdp_connector_helper_funcs);
+
+ drm_connector_init(drm, connector,
+ &imx_hdp_connector_funcs,
+ devtype->connector_type);
+
+ drm_object_attach_property(&connector->base,
+ connector->dev->mode_config.hdr_source_metadata_property, 0);
+
+ drm_mode_connector_attach_encoder(connector, encoder);
+
+ dev_set_drvdata(dev, hdp);
+
+ if (hdp->is_dp) {
+ dp_aux_init(&hdp->state, dev);
+ }
+
+ ret = imx_hdcp_init(hdp, pdev->dev.of_node);
+ if (ret < 0)
+ DRM_WARN("Failed to initialize HDCP\n");
+
+ INIT_DELAYED_WORK(&hdp->hotplug_work, hotplug_work_func);
+
+ /* Check cable states before enable irq */
+ imx_hdp_call(hdp, get_hpd_state, &hdp->state, &hpd);
+
+ /* Enable Hotplug Detect IRQ thread */
+ if (hdp->irq[HPD_IRQ_IN] > 0) {
+ irq_set_status_flags(hdp->irq[HPD_IRQ_IN], IRQ_NOAUTOEN);
+ ret = devm_request_threaded_irq(dev, hdp->irq[HPD_IRQ_IN],
+ NULL, imx_hdp_irq_thread,
+ IRQF_ONESHOT, dev_name(dev),
+ hdp);
+ if (ret) {
+ dev_err(&pdev->dev, "can't claim irq %d\n",
+ hdp->irq[HPD_IRQ_IN]);
+ goto err_irq;
+ }
+ /* Cable Disconnedted, enable Plug in IRQ */
+ if (hpd == 0)
+ enable_irq(hdp->irq[HPD_IRQ_IN]);
+ }
+ if (hdp->irq[HPD_IRQ_OUT] > 0) {
+ irq_set_status_flags(hdp->irq[HPD_IRQ_OUT], IRQ_NOAUTOEN);
+ ret = devm_request_threaded_irq(dev, hdp->irq[HPD_IRQ_OUT],
+ NULL, imx_hdp_irq_thread,
+ IRQF_ONESHOT, dev_name(dev),
+ hdp);
+ if (ret) {
+ dev_err(&pdev->dev, "can't claim irq %d\n",
+ hdp->irq[HPD_IRQ_OUT]);
+ goto err_irq;
+ }
+ /* Cable Connected, enable Plug out IRQ */
+ if (hpd == 1)
+ enable_irq(hdp->irq[HPD_IRQ_OUT]);
+ }
+#ifdef CONFIG_IMX_HDP_CEC
+ if (hdp->is_cec) {
+ imx_hdp_cec_init(hdp);
+ imx_cec_register(&hdp->cec);
+ }
+#endif
+
+ imx_hdp_register_audio_driver(dev);
+
+ return 0;
+err_irq:
+ drm_encoder_cleanup(encoder);
+ return ret;
+}
+
+static void imx_hdp_imx_unbind(struct device *dev, struct device *master,
+ void *data)
+{
+ struct imx_hdp *hdp = dev_get_drvdata(dev);
+
+#ifdef CONFIG_IMX_HDP_CEC
+ if (hdp->is_cec)
+ imx_cec_unregister(&hdp->cec);
+#endif
+ imx_hdp_call(hdp, pixel_clock_disable, &hdp->clks);
+}
+
+static const struct component_ops imx_hdp_imx_ops = {
+ .bind = imx_hdp_imx_bind,
+ .unbind = imx_hdp_imx_unbind,
+};
+
+static int imx_hdp_imx_probe(struct platform_device *pdev)
+{
+ return component_add(&pdev->dev, &imx_hdp_imx_ops);
+}
+
+static int imx_hdp_imx_remove(struct platform_device *pdev)
+{
+ component_del(&pdev->dev, &imx_hdp_imx_ops);
+
+ return 0;
+}
+
+static struct platform_driver imx_hdp_imx_platform_driver = {
+ .probe = imx_hdp_imx_probe,
+ .remove = imx_hdp_imx_remove,
+ .driver = {
+ .name = "i.mx8-hdp",
+ .of_match_table = imx_hdp_dt_ids,
+ },
+};
+
+module_platform_driver(imx_hdp_imx_platform_driver);
+
+MODULE_AUTHOR("Sandor Yu <Sandor.yu@nxp.com>");
+MODULE_DESCRIPTION("IMX8QM DP Display Driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:dp-hdmi-imx");
diff --git a/drivers/gpu/drm/imx/hdp/imx-hdp.h b/drivers/gpu/drm/imx/hdp/imx-hdp.h
new file mode 100644
index 000000000000..52678a0bc0e3
--- /dev/null
+++ b/drivers/gpu/drm/imx/hdp/imx-hdp.h
@@ -0,0 +1,272 @@
+/*
+ * Copyright 2017-2019 NXP
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+#ifndef _IMX_HDP_H_
+#define _IMX_HDP_H_
+
+#include <linux/regmap.h>
+#include <linux/mutex.h>
+#include <drm/drm_of.h>
+#include <drm/drmP.h>
+#include <drm/drm_atomic_helper.h>
+#include <drm/drm_crtc_helper.h>
+#include <drm/drm_edid.h>
+#include <drm/drm_encoder_slave.h>
+#include <drm/drm_atomic.h>
+#include <soc/imx8/sc/sci.h>
+
+#include <drm/drm_dp_helper.h>
+#include "../../../../mxc/hdp/all.h"
+#include "../../../../mxc/hdp-cec/imx-hdp-cec.h"
+#include "imx-hdcp-private.h"
+
+#define HDP_DUAL_MODE_MIN_PCLK_RATE 300000 /* KHz */
+#define HDP_SINGLE_MODE_MAX_WIDTH 1920
+
+/* For testing hdp firmware define DEBUG_FW_LOAD */
+#undef DEBUG_FW_LOAD
+#define PLL_1188MHZ (1188000000)
+#define PLL_800MHZ (800000000)
+
+#define HDP_TX_SS_LIS_BASE 0x0000
+#define HDP_TX_SS_CSR_BASE 0x1000
+#define HDP_TX_SS_GPIO_BASE 0x2000
+#define HDP_TX_SS_CTRL0_BASE 0x8000
+
+#define CSR_PIXEL_LINK_MUX_CTL 0x00
+#define PL_MUX_CTL_VCP_OFFSET 5
+#define PL_MUX_CTL_HCP_OFFSET 4
+#define PL_MUX_CTL_PL_MUX_OFFSET 2
+#define PL_MUX_CTL_PL_SEL_OFFSET 0
+
+#define CSR_PIXEL_LINK_MUX_STATUS 0x04
+#define PL_MUX_STATUS_PL1_INT_OFFSET 18
+#define PL_MUX_STATUS_PL1_ADD_OFFSET 16
+#define PL_MUX_STATUS_PL1_TYP_OFFSET 11
+#define PL_MUX_STATUS_PL0_INT_OFFSET 9
+#define PL_MUX_STATUS_PL0_ADD_OFFSET 7
+#define PL_MUX_STATUS_PL0_TYP_OFFSET 2
+#define PL_MUX_STATUS_PL_DLY_OFFSET 0
+
+#define CSR_HDP_TX_CTRL_CTRL0 0x08
+#define CSR_HDP_TX_CTRL_CTRL1 0x0c
+
+#define HOTPLUG_DEBOUNCE_MS 200
+
+#define VIC_MODE_97_60Hz 97
+#define VIC_MODE_96_50Hz 96
+#define VIC_MODE_95_30Hz 95
+#define VIC_MODE_94_25Hz 94
+#define VIC_MODE_93_24Hz 93
+
+/**
+ * imx_hdp_call - Calls a struct imx hdp_operations operation on
+ * an entity
+ *
+ * @entity: entity where the @operation will be called
+ * @operation: type of the operation. Should be the name of a member of
+ * struct &media_entity_operations.
+ *
+ * This helper function will check if @operation is not %NULL. On such case,
+ * it will issue a call to @operation\(@args\).
+ */
+
+#define imx_hdp_call(hdp, operation, args...) \
+ (!(hdp) ? -ENODEV : (((hdp)->ops && (hdp)->ops->operation) ? \
+ (hdp)->ops->operation(args) : ENOIOCTLCMD))
+
+#define clks_to_imx_hdp(env) \
+ container_of(env, struct imx_hdp, clks)
+
+#define state_to_imx_hdp(env) \
+ container_of(env, struct imx_hdp, state)
+
+struct hdp_clks;
+
+struct hdp_ops {
+ void (*fw_load)(state_struct *state);
+ int (*fw_init)(state_struct *state);
+ int (*phy_init)(state_struct *state, struct drm_display_mode *mode,
+ int format, int color_depth);
+ void (*mode_set)(state_struct *state, struct drm_display_mode *mode,
+ int format, int color_depth, int max_link);
+ bool (*mode_fixup)(state_struct *state,
+ const struct drm_display_mode *mode,
+ struct drm_display_mode *adjusted_mode);
+ int (*get_edid_block)(void *data, u8 *buf, u32 block, size_t len);
+ int (*get_hpd_state)(state_struct *state, u8 *hpd);
+ int (*write_hdr_metadata)(state_struct *state,
+ union hdmi_infoframe *hdr_infoframe);
+
+ void (*phy_reset)(sc_ipc_t ipcHndl, struct hdp_mem *mem, u8 reset);
+ int (*pixel_link_validate)(state_struct *state);
+ int (*pixel_link_invalidate)(state_struct *state);
+ int (*pixel_link_sync_ctrl_enable)(state_struct *state);
+ int (*pixel_link_sync_ctrl_disable)(state_struct *state);
+ void (*pixel_link_mux)(state_struct *state,
+ struct drm_display_mode *mode);
+ void (*pixel_engine_reset)(state_struct *state);
+
+ int (*clock_init)(struct hdp_clks *clks);
+ int (*ipg_clock_enable)(struct hdp_clks *clks);
+ void (*ipg_clock_disable)(struct hdp_clks *clks);
+ void (*ipg_clock_set_rate)(struct hdp_clks *clks);
+ int (*pixel_clock_enable)(struct hdp_clks *clks);
+ void (*pixel_clock_disable)(struct hdp_clks *clks);
+ void (*pixel_clock_set_rate)(struct hdp_clks *clks);
+ int (*pixel_clock_range)(struct drm_display_mode *mode);
+};
+
+struct hdp_devtype {
+ u8 audio_type;
+ struct hdp_ops *ops;
+ struct hdp_rw_func *rw;
+ u32 connector_type;
+};
+
+struct hdp_video {
+ u32 bpp;
+ u32 format;
+ u32 lanes;
+ u32 color_type; /* bt */
+ u32 color_depth; /* bpc */
+ struct drm_display_mode cur_mode;
+ struct drm_display_mode pre_mode;
+ void __iomem *regs_base;
+};
+
+struct hdp_audio {
+ u32 interface; /* I2S SPDIF */
+ u32 freq;
+ u32 nlanes;
+ u32 nChannels;
+ u32 sample_width;
+ u32 sample_rate;
+ u32 audio_cts;
+ u32 audio_n;
+ bool audio_enable;
+ spinlock_t audio_lock;
+ struct mutex audio_mutex;
+ void __iomem *regs_base;
+};
+
+struct hdp_hdcp {
+ void __iomem *regs_base;
+};
+
+struct hdp_phy {
+ u32 index;
+ u32 number;
+ bool enabled;
+ struct phy *phy;
+ void __iomem *regs_base;
+};
+
+struct hdp_clks {
+ struct clk *av_pll;
+ struct clk *dig_pll;
+ struct clk *clk_ipg;
+ struct clk *clk_core;
+ struct clk *clk_pxl;
+ struct clk *clk_pxl_mux;
+ struct clk *clk_pxl_link;
+
+ struct clk *clk_hdp;
+ struct clk *clk_phy;
+ struct clk *clk_apb;
+
+ struct clk *clk_lis;
+ struct clk *clk_msi;
+ struct clk *clk_lpcg;
+ struct clk *clk_even;
+ struct clk *clk_dbl;
+ struct clk *clk_vif;
+ struct clk *clk_apb_csr;
+ struct clk *clk_apb_ctrl;
+ struct clk *av_pll_div;
+ struct clk *dig_pll_div;
+ struct clk *clk_i2s;
+ struct clk *clk_i2s_bypass;
+};
+
+enum hdp_tx_irq {
+ HPD_IRQ_IN,
+ HPD_IRQ_OUT,
+ HPD_IRQ_NUM,
+};
+
+struct imx_hdp {
+ struct device *dev;
+ struct drm_connector connector;
+ struct drm_encoder encoder;
+ struct drm_bridge bridge;
+ struct drm_device *drm_dev;
+
+ struct edid *edid;
+ char cable_state;
+
+ struct hdp_mem mem;
+ struct imx_hdcp hdcp;
+
+ u8 is_cec;
+ u8 is_edp;
+ u8 is_dp;
+ u8 is_digpll_dp_pclock;
+ u8 no_edid;
+ u8 audio_type;
+ u8 is_hdcp;
+ u32 dp_lane_mapping;
+ u32 dp_link_rate;
+ u32 dp_num_lanes;
+
+ u32 character_freq_khz; /* character clock for hdmi */
+ u32 hdmi_type;
+
+ struct mutex mutex; /* for state below and previous_mode */
+ enum drm_connector_force force; /* mutex-protected force state */
+
+ struct hdp_video video;
+
+ struct drm_dp_aux aux;
+ struct mutex aux_mutex;
+
+ struct drm_dp_link dp_link;
+ S_LINK_STAT lkstat;
+ ENUM_AFE_LINK_RATE link_rate;
+
+ sc_ipc_t ipcHndl;
+ u32 mu_id;
+ u32 dual_mode;
+ struct hdp_ops *ops;
+ struct hdp_rw_func *rw;
+ struct hdp_clks clks;
+ state_struct state;
+ int vic;
+ int irq[HPD_IRQ_NUM];
+ struct delayed_work hotplug_work;
+
+ struct imx_cec_dev cec;
+
+ int bpc;
+ VIC_PXL_ENCODING_FORMAT format;
+ bool hdr_metadata_present;
+ bool hdr_mode;
+};
+
+void imx_hdp_register_audio_driver(struct device *dev);
+void imx_arc_power_up(state_struct *state);
+void imx_arc_calibrate(state_struct *state);
+void imx_arc_config(state_struct *state);
+int imx_hdcp_check_link(struct imx_hdp *hdp);
+
+#endif
diff --git a/drivers/gpu/drm/imx/hdp/mhdp_firmware.h b/drivers/gpu/drm/imx/hdp/mhdp_firmware.h
new file mode 100644
index 000000000000..c52c8e302912
--- /dev/null
+++ b/drivers/gpu/drm/imx/hdp/mhdp_firmware.h
@@ -0,0 +1,77 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2016-2017 Cadence Design Systems, Inc.
+ * All rights reserved worldwide.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 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.
+ *
+ ******************************************************************************
+ *
+ * This file was auto-generated from dram0.data and iram0.data firmware images
+ * Do not edit it manually.
+ *
+ ******************************************************************************
+ *
+ * mhdp_firmware.c
+ *
+ ******************************************************************************
+ */
+#include <linux/io.h>
+
+static u32 const mhdp_iram0[] = {
+ 0x00000000,
+};
+
+static u32 const mhdp_dram0[] = {
+ 0x00000000,
+};
+
+u32 const *mhdp_iram0_get_ptr(void)
+{
+ return (u32 const *)mhdp_iram0;
+}
+
+u32 const *mhdp_dram0_get_ptr(void)
+{
+ return (u32 const *)mhdp_dram0;
+}
+
+size_t mhdp_iram0_get_size(void)
+{
+ return sizeof(mhdp_iram0);
+}
+
+size_t mhdp_dram0_get_size(void)
+{
+ return sizeof(mhdp_dram0);
+}
diff --git a/drivers/gpu/drm/imx/hdp/ss28fdsoi_hdmitx_table.c b/drivers/gpu/drm/imx/hdp/ss28fdsoi_hdmitx_table.c
new file mode 100644
index 000000000000..53f05adf8eb8
--- /dev/null
+++ b/drivers/gpu/drm/imx/hdp/ss28fdsoi_hdmitx_table.c
@@ -0,0 +1,113 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2016-2017 Cadence Design Systems, Inc.
+ * All rights reserved worldwide.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 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.
+ *
+ * Copyright 2018 NXP
+ *
+ ******************************************************************************
+ *
+ * ss28fdsoi_hdmitx_table.c
+ *
+ ******************************************************************************
+ */
+
+#include "ss28fdsoi_hdmitx_table.h"
+
+const u32 ss28fdsoi_hdmitx_clock_control_table[SS28FDSOI_HDMITX_CLOCK_CONTROL_TABLE_ROWS][SS28FDSOI_HDMITX_CLOCK_CONTROL_TABLE_COLS] = {
+ { 25000, 42500, 1000, 250000, 425000, 0x05, 0x01, 0x01, 400, 0x182, 0x00A, 2000000, 3400000, 0, 2, 2, 2, 4, 125000, 212500, 0x03, 25000, 42500},
+ { 42500, 85000, 1000, 425000, 850000, 0x08, 0x03, 0x01, 320, 0x132, 0x00A, 1700000, 3400000, 0, 1, 1, 2, 4, 212500, 425000, 0x02, 42500, 85000},
+ { 85000, 170000, 1000, 850000, 1700000, 0x11, 0x00, 0x07, 340, 0x146, 0x00A, 1700000, 3400000, 0, 1, 1, 2, 2, 425000, 850000, 0x01, 85000, 170000},
+ {170000, 340000, 1000, 1700000, 3400000, 0x22, 0x01, 0x07, 340, 0x146, 0x00A, 1700000, 3400000, 0, 1, 1, 2, 1, 850000, 1700000, 0x00, 170000, 340000},
+ {340000, 600000, 1000, 3400000, 6000000, 0x3C, 0x03, 0x06, 600, 0x24A, 0x00A, 3400000, 6000000, 1, 1, 1, 2, 1, 1700000, 3000000, 0x00, 340000, 600000},
+ { 25000, 34000, 1205, 312500, 425000, 0x04, 0x01, 0x01, 400, 0x182, 0x00A, 2500000, 3400000, 0, 2, 2, 2, 4, 156250, 212500, 0x03, 31250, 42500},
+ { 34000, 68000, 1205, 425000, 850000, 0x06, 0x02, 0x01, 300, 0x11E, 0x00A, 1700000, 3400000, 0, 1, 1, 2, 4, 212500, 425000, 0x02, 42500, 85000},
+ { 68000, 136000, 1205, 850000, 1700000, 0x0D, 0x02, 0x02, 325, 0x137, 0x00A, 1700000, 3400000, 0, 1, 1, 2, 2, 425000, 850000, 0x01, 85000, 170000},
+ {136000, 272000, 1205, 1700000, 3400000, 0x1A, 0x02, 0x04, 325, 0x137, 0x00A, 1700000, 3400000, 0, 1, 1, 2, 1, 850000, 1700000, 0x00, 170000, 340000},
+ {272000, 480000, 1205, 3400000, 6000000, 0x30, 0x03, 0x05, 600, 0x24A, 0x00A, 3400000, 6000000, 1, 1, 1, 2, 1, 1700000, 3000000, 0x00, 340000, 600000},
+ { 25000, 28000, 1500, 375000, 420000, 0x03, 0x01, 0x01, 360, 0x15A, 0x00A, 3000000, 3360000, 0, 2, 2, 2, 4, 187500, 210000, 0x03, 37500, 42000},
+ { 28000, 56000, 1500, 420000, 840000, 0x06, 0x02, 0x01, 360, 0x15A, 0x00A, 1680000, 3360000, 0, 1, 1, 2, 4, 210000, 420000, 0x02, 42000, 84000},
+ { 56000, 113000, 1500, 840000, 1695000, 0x0B, 0x00, 0x05, 330, 0x13C, 0x00A, 1680000, 3390000, 0, 1, 1, 2, 2, 420000, 847500, 0x01, 84000, 169500},
+ {113000, 226000, 1500, 1695000, 3390000, 0x16, 0x01, 0x05, 330, 0x13C, 0x00A, 1695000, 3390000, 0, 1, 1, 2, 1, 847500, 1695000, 0x00, 169500, 339000},
+ {226000, 400000, 1500, 3390000, 6000000, 0x28, 0x03, 0x04, 600, 0x24A, 0x00A, 3390000, 6000000, 1, 1, 1, 2, 1, 1695000, 3000000, 0x00, 339000, 600000},
+ { 25000, 42500, 2000, 500000, 850000, 0x05, 0x01, 0x01, 400, 0x182, 0x00A, 2000000, 3400000, 0, 1, 1, 2, 4, 250000, 425000, 0x02, 50000, 85000},
+ { 42500, 85000, 2000, 850000, 1700000, 0x08, 0x03, 0x01, 320, 0x132, 0x00A, 1700000, 3400000, 0, 1, 1, 2, 2, 425000, 850000, 0x01, 85000, 170000},
+ { 85000, 170000, 2000, 1700000, 3400000, 0x11, 0x00, 0x07, 340, 0x146, 0x00A, 1700000, 3400000, 0, 1, 1, 2, 1, 850000, 1700000, 0x00, 170000, 340000},
+ {170000, 300000, 2000, 3400000, 6000000, 0x22, 0x01, 0x06, 680, 0x29A, 0x00A, 3400000, 6000000, 1, 1, 1, 2, 1, 1700000, 3000000, 0x00, 340000, 600000},
+ {594000, 594000, 5000, 2970000, 2970000, 0x3C, 0x03, 0x06, 600, 0x24A, 0x00A, 5940000, 5940000, 1, 1, 1, 2, 2, 1485000, 1485000, 0x01, 297000, 297000},
+ {594000, 594000, 6250, 3712500, 3712500, 0x3C, 0x03, 0x06, 375, 0x169, 0x00A, 3712500, 3712500, 1, 1, 1, 2, 1, 1856250, 1856250, 0x00, 371250, 371250},
+ {594000, 594000, 7500, 4455000, 4455000, 0x3C, 0x03, 0x06, 450, 0x1B4, 0x00A, 4455000, 4455000, 1, 1, 1, 2, 1, 2227500, 2227500, 0x00, 445500, 445500},
+};
+
+const u32 ss28fdsoi_hdmitx_pll_tuning_table[SS28FDSOI_HDMITX_PLL_TUNING_TABLE_ROWS][SS28FDSOI_HDMITX_PLL_TUNING_TABLE_COLS] = {
+ {0, 1700000, 2000000, 0x3, 0x1, 0x0, 0x8C, 0x2E, 300, 0x08D},
+ {0, 1700000, 2000000, 0x3, 0x1, 0x0, 0x8C, 0x2E, 320, 0x08E},
+ {0, 1700000, 2000000, 0x3, 0x1, 0x0, 0x8C, 0x2E, 325, 0x08E},
+ {0, 1700000, 2000000, 0x3, 0x1, 0x0, 0x8C, 0x2E, 330, 0x08E},
+ {0, 1700000, 2000000, 0x3, 0x1, 0x0, 0x8C, 0x2E, 340, 0x08F},
+ {0, 1700000, 2000000, 0x3, 0x1, 0x0, 0x8C, 0x2E, 360, 0x0A7},
+ {0, 1700000, 2000000, 0x3, 0x1, 0x0, 0x8C, 0x2E, 400, 0x0C5},
+ {1, 2000000, 2400000, 0x3, 0x1, 0x0, 0x8C, 0x2E, 300, 0x086},
+ {1, 2000000, 2400000, 0x3, 0x1, 0x0, 0x8C, 0x2E, 320, 0x087},
+ {1, 2000000, 2400000, 0x3, 0x1, 0x0, 0x8C, 0x2E, 325, 0x087},
+ {1, 2000000, 2400000, 0x3, 0x1, 0x0, 0x8C, 0x2E, 330, 0x104},
+ {1, 2000000, 2400000, 0x3, 0x1, 0x0, 0x8C, 0x2E, 340, 0x08B},
+ {1, 2000000, 2400000, 0x3, 0x1, 0x0, 0x8C, 0x2E, 360, 0x08D},
+ {1, 2000000, 2400000, 0x3, 0x1, 0x0, 0x8C, 0x2E, 400, 0x0A6},
+ {2, 2400000, 2800000, 0x3, 0x1, 0x0, 0x04, 0x0D, 300, 0x04E},
+ {2, 2400000, 2800000, 0x3, 0x1, 0x0, 0x04, 0x0D, 320, 0x04F},
+ {2, 2400000, 2800000, 0x3, 0x1, 0x0, 0x04, 0x0D, 325, 0x04F},
+ {2, 2400000, 2800000, 0x3, 0x1, 0x0, 0x04, 0x0D, 330, 0x085},
+ {2, 2400000, 2800000, 0x3, 0x1, 0x0, 0x04, 0x0D, 340, 0x085},
+ {2, 2400000, 2800000, 0x3, 0x1, 0x0, 0x04, 0x0D, 360, 0x086},
+ {2, 2400000, 2800000, 0x3, 0x1, 0x0, 0x04, 0x0D, 400, 0x08B},
+ {3, 2800000, 3400000, 0x3, 0x1, 0x0, 0x04, 0x0D, 300, 0x047},
+ {3, 2800000, 3400000, 0x3, 0x1, 0x0, 0x04, 0x0D, 320, 0x04B},
+ {3, 2800000, 3400000, 0x3, 0x1, 0x0, 0x04, 0x0D, 325, 0x04B},
+ {3, 2800000, 3400000, 0x3, 0x1, 0x0, 0x04, 0x0D, 330, 0x04B},
+ {3, 2800000, 3400000, 0x3, 0x1, 0x0, 0x04, 0x0D, 340, 0x04D},
+ {3, 2800000, 3400000, 0x3, 0x1, 0x0, 0x04, 0x0D, 360, 0x04E},
+ {3, 2800000, 3400000, 0x3, 0x1, 0x0, 0x04, 0x0D, 400, 0x085},
+ {4, 3400000, 3900000, 0x7, 0x1, 0x0, 0x8E, 0x2F, 375, 0x041},
+ {4, 3400000, 3900000, 0x7, 0x1, 0x0, 0x8E, 0x2F, 600, 0x08D},
+ {4, 3400000, 3900000, 0x7, 0x1, 0x0, 0x8E, 0x2F, 680, 0x0A6},
+ {5, 3900000, 4500000, 0x7, 0x1, 0x0, 0x8E, 0x2F, 450, 0x041},
+ {5, 3900000, 4500000, 0x7, 0x1, 0x0, 0x8E, 0x2F, 600, 0x087},
+ {5, 3900000, 4500000, 0x7, 0x1, 0x0, 0x8E, 0x2F, 680, 0x0A4},
+ {6, 4500000, 5200000, 0x7, 0x1, 0x0, 0x04, 0x0D, 600, 0x04F},
+ {6, 4500000, 5200000, 0x7, 0x1, 0x0, 0x04, 0x0D, 680, 0x086},
+ {7, 5200000, 6000000, 0x7, 0x1, 0x0, 0x04, 0x0D, 600, 0x04D},
+ {7, 5200000, 6000000, 0x7, 0x1, 0x0, 0x04, 0x0D, 680, 0x04F}
+};
diff --git a/drivers/gpu/drm/imx/hdp/ss28fdsoi_hdmitx_table.h b/drivers/gpu/drm/imx/hdp/ss28fdsoi_hdmitx_table.h
new file mode 100644
index 000000000000..b2c2f1a6af79
--- /dev/null
+++ b/drivers/gpu/drm/imx/hdp/ss28fdsoi_hdmitx_table.h
@@ -0,0 +1,104 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2016-2017 Cadence Design Systems, Inc.
+ * All rights reserved worldwide.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 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.
+ *
+ * Copyright 2018 NXP
+ *
+ ******************************************************************************
+ *
+ * ss28fdsoi_hdmitx_table.h
+ *
+ ******************************************************************************
+ */
+
+#ifndef SS28FDSOI_HDMITX_TABLE_H_
+#define SS28FDSOI_HDMITX_TABLE_H_
+
+#include <linux/io.h>
+
+# define SS28FDSOI_HDMITX_CLOCK_CONTROL_TABLE_ROWS 22
+# define SS28FDSOI_HDMITX_CLOCK_CONTROL_TABLE_COLS 23
+
+# define SS28FDSOI_HDMITX_PLL_TUNING_TABLE_ROWS 38
+# define SS28FDSOI_HDMITX_PLL_TUNING_TABLE_COLS 10
+
+typedef enum {
+ PIXEL_CLK_FREQ_KHZ_MIN,
+ PIXEL_CLK_FREQ_KHZ_MAX,
+ FEEDBACK_FACTOR,
+ DATA_RANGE_MBPS_MIN,
+ DATA_RANGE_MBPS_MAX,
+ CMNDA_PLL0_IP_DIV,
+ CMN_REF_CLK_DIG_DIV,
+ REF_CLK_DIVIDER_SCALER,
+ PLL_FB_DIV_TOTAL,
+ CMNDA_PLL0_FB_DIV_LOW,
+ CMNDA_PLL0_FB_DIV_HIGH,
+ VCO_FREQ_KHZ_MIN,
+ VCO_FREQ_KHZ_MAX,
+ VCO_RING_SELECT,
+ CMNDA_HS_CLK_0_SEL,
+ CMNDA_HS_CLK_1_SEL,
+ HSCLK_DIV_AT_XCVR,
+ HSCLK_DIV_TX_SUB_RATE,
+ TX_CLK_KHZ_MIN,
+ TX_CLK_KHZ_MAX,
+ CMNDA_PLL0_HS_SYM_DIV_SEL,
+ CMNDA_PLL0_CLK_FREQ_KHZ_MIN,
+ CMNDA_PLL0_CLK_FREQ_KHZ_MAX
+} CLK_CTRL_PARAM;
+
+typedef enum {
+ VCO_FREQ_BIN,
+ PLL_VCO_FREQ_KHZ_MIN,
+ PLL_VCO_FREQ_KHZ_MAX,
+ VOLTAGE_TO_CURRENT_COARSE,
+ VOLTAGE_TO_CURRENT,
+ NDAC_CTRL,
+ PMOS_CTRL,
+ PTAT_NDAC_CTRL,
+ PLL_FEEDBACK_DIV_TOTAL,
+ CHARGE_PUMP_GAIN
+} PLL_TUNE_PARAM;
+
+extern const u32
+ss28fdsoi_hdmitx_clock_control_table[SS28FDSOI_HDMITX_CLOCK_CONTROL_TABLE_ROWS]
+ [SS28FDSOI_HDMITX_CLOCK_CONTROL_TABLE_COLS];
+extern const u32
+ss28fdsoi_hdmitx_pll_tuning_table[SS28FDSOI_HDMITX_PLL_TUNING_TABLE_ROWS]
+ [SS28FDSOI_HDMITX_PLL_TUNING_TABLE_COLS];
+
+#endif
diff --git a/drivers/gpu/drm/imx/hdp/t28hpc_hdmitx_table.c b/drivers/gpu/drm/imx/hdp/t28hpc_hdmitx_table.c
new file mode 100644
index 000000000000..c269fca055d5
--- /dev/null
+++ b/drivers/gpu/drm/imx/hdp/t28hpc_hdmitx_table.c
@@ -0,0 +1,202 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2016-2017 Cadence Design Systems, Inc.
+ * All rights reserved worldwide.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 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.
+ *
+ * Copyright 2018 NXP
+ *
+ ******************************************************************************
+ *
+ * t28hpc_hdmitx_table.c
+ *
+ ******************************************************************************
+ */
+
+#include "t28hpc_hdmitx_table.h"
+
+/* Table 6. HDMI TX clock control settings (pixel clock is input) */
+const u32 t28hpc_hdmitx_clock_control_table_pixel_in[T28HPC_HDMITX_CLOCK_CONTROL_TABLE_ROWS_PIXEL_IN][T28HPC_HDMITX_CLOCK_CONTROL_TABLE_COLS_PIXEL_IN] = {
+ { 25000, 42500, 1000, 250000, 425000, 0x05, 0x01, 0x01, 400, 0x182, 0x00A, 2000000, 3400000, 0, 2, 2, 2, 4, 125000, 212500, 0x03, 25000, 42500},
+ { 42500, 85000, 1000, 425000, 850000, 0x08, 0x03, 0x01, 320, 0x132, 0x00A, 1700000, 3400000, 0, 1, 1, 2, 4, 212500, 425000, 0x02, 42500, 85000},
+ { 85000, 170000, 1000, 850000, 1700000, 0x11, 0x00, 0x07, 340, 0x146, 0x00A, 1700000, 3400000, 0, 1, 1, 2, 2, 425000, 850000, 0x01, 85000, 170000},
+ {170000, 340000, 1000, 1700000, 3400000, 0x22, 0x01, 0x07, 340, 0x146, 0x00A, 1700000, 3400000, 0, 1, 1, 2, 1, 850000, 1700000, 0x00, 170000, 340000},
+ {340000, 600000, 1000, 3400000, 6000000, 0x3C, 0x03, 0x06, 600, 0x24A, 0x00A, 3400000, 6000000, 1, 1, 1, 2, 1, 1700000, 3000000, 0x00, 340000, 600000},
+ { 25000, 34000, 1250, 312000, 425000, 0x04, 0x01, 0x01, 400, 0x182, 0x00A, 2500000, 3400000, 0, 2, 2, 2, 4, 156250, 212500, 0x03, 31250, 42500},
+ { 34000, 68000, 1250, 425000, 850000, 0x06, 0x02, 0x01, 300, 0x11E, 0x00A, 1700000, 3400000, 0, 1, 1, 2, 4, 212500, 425000, 0x02, 42500, 85000},
+ { 68000, 136000, 1250, 850000, 1700000, 0x0D, 0x02, 0x02, 325, 0x137, 0x00A, 1700000, 3400000, 0, 1, 1, 2, 2, 425000, 850000, 0x01, 85000, 170000},
+ {136000, 272000, 1250, 1700000, 3400000, 0x1A, 0x02, 0x04, 325, 0x137, 0x00A, 1700000, 3400000, 0, 1, 1, 2, 1, 850000, 1700000, 0x00, 170000, 340000},
+ {272000, 480000, 1250, 3400000, 6000000, 0x30, 0x03, 0x05, 600, 0x24A, 0x00A, 3400000, 6000000, 1, 1, 1, 2, 1, 1700000, 3000000, 0x00, 340000, 600000},
+ { 25000, 28000, 1500, 375000, 420000, 0x03, 0x01, 0x01, 360, 0x15A, 0x00A, 3000000, 3360000, 0, 2, 2, 2, 4, 187500, 210000, 0x03, 37500, 42000},
+ { 28000, 56000, 1500, 420000, 840000, 0x06, 0x02, 0x01, 360, 0x15A, 0x00A, 1680000, 3360000, 0, 1, 1, 2, 4, 210000, 420000, 0x02, 42000, 84000},
+ { 56000, 113000, 1500, 840000, 1695000, 0x0B, 0x00, 0x05, 330, 0x13C, 0x00A, 1680000, 3390000, 0, 1, 1, 2, 2, 420000, 847500, 0x01, 84000, 169500},
+ {113000, 226000, 1500, 1695000, 3390000, 0x16, 0x01, 0x05, 330, 0x13C, 0x00A, 1695000, 3390000, 0, 1, 1, 2, 1, 847500, 1695000, 0x00, 169500, 339000},
+ {226000, 400000, 1500, 3390000, 6000000, 0x28, 0x03, 0x04, 600, 0x24A, 0x00A, 3390000, 6000000, 1, 1, 1, 2, 1, 1695000, 3000000, 0x00, 339000, 600000},
+ { 25000, 42500, 2000, 500000, 850000, 0x05, 0x01, 0x01, 400, 0x182, 0x00A, 2000000, 3400000, 0, 1, 1, 2, 4, 250000, 425000, 0x02, 50000, 85000},
+ { 42500, 85000, 2000, 850000, 1700000, 0x08, 0x03, 0x01, 320, 0x132, 0x00A, 1700000, 3400000, 0, 1, 1, 2, 2, 425000, 850000, 0x01, 85000, 170000},
+ { 85000, 170000, 2000, 1700000, 3400000, 0x11, 0x00, 0x07, 340, 0x146, 0x00A, 1700000, 3400000, 0, 1, 1, 2, 1, 850000, 1700000, 0x00, 170000, 340000},
+ {170000, 300000, 2000, 3400000, 6000000, 0x22, 0x01, 0x06, 680, 0x29A, 0x00A, 3400000, 6000000, 1, 1, 1, 2, 1, 1700000, 3000000, 0x00, 340000, 600000},
+ {594000, 594000, 500, 2970000, 2970000, 0x3C, 0x03, 0x06, 600, 0x24A, 0x00A, 5940000, 5940000, 1, 1, 1, 2, 2, 1485000, 1485000, 0x01, 297000, 297000},
+ {594000, 594000, 625, 3712000, 3712000, 0x3C, 0x03, 0x06, 375, 0x169, 0x00A, 3712500, 3712500, 1, 1, 1, 2, 1, 1856250, 1856250, 0x00, 371250, 371250},
+ {594000, 594000, 750, 4455000, 4455000, 0x3C, 0x03, 0x06, 450, 0x1B4, 0x00A, 4455000, 4455000, 1, 1, 1, 2, 1, 2227500, 2227500, 0x00, 445500, 445500}
+};
+
+/* Table 7. HDMI TX PLL tuning settings (pixel clock is input) */
+const u32 t28hpc_hdmitx_pll_tuning_table_pixel_in[T28HPC_HDMITX_PLL_TUNING_TABLE_ROWS_PIXEL_IN][T28HPC_HDMITX_PLL_TUNING_TABLE_COLS_PIXEL_IN] = {
+ {0, 1700000, 2000000, 0x4, 0x3, 0x0, 0x09, 0x09, 300.0, 0x082},
+ {0, 1700000, 2000000, 0x4, 0x3, 0x0, 0x09, 0x09, 320.0, 0x083},
+ {0, 1700000, 2000000, 0x4, 0x3, 0x0, 0x09, 0x09, 325.0, 0x083},
+ {0, 1700000, 2000000, 0x4, 0x3, 0x0, 0x09, 0x09, 330.0, 0x084},
+ {0, 1700000, 2000000, 0x4, 0x3, 0x0, 0x09, 0x09, 340.0, 0x084},
+ {0, 1700000, 2000000, 0x4, 0x3, 0x0, 0x09, 0x09, 360.0, 0x086},
+ {0, 1700000, 2000000, 0x4, 0x3, 0x0, 0x09, 0x09, 400.0, 0x0A2},
+ {1, 2000000, 2400000, 0x4, 0x3, 0x0, 0x09, 0x09, 300.0, 0x047},
+ {1, 2000000, 2400000, 0x4, 0x3, 0x0, 0x09, 0x09, 320.0, 0x04B},
+ {1, 2000000, 2400000, 0x4, 0x3, 0x0, 0x09, 0x09, 325.0, 0x04C},
+ {1, 2000000, 2400000, 0x4, 0x3, 0x0, 0x09, 0x09, 330.0, 0x080},
+ {1, 2000000, 2400000, 0x4, 0x3, 0x0, 0x09, 0x09, 340.0, 0x081},
+ {1, 2000000, 2400000, 0x4, 0x3, 0x0, 0x09, 0x09, 360.0, 0x082},
+ {1, 2000000, 2400000, 0x4, 0x3, 0x0, 0x09, 0x09, 400.0, 0x084},
+ {2, 2400000, 2800000, 0x5, 0x3, 0x1, 0x00, 0x07, 300.0, 0x043},
+ {2, 2400000, 2800000, 0x5, 0x3, 0x1, 0x00, 0x07, 320.0, 0x045},
+ {2, 2400000, 2800000, 0x5, 0x3, 0x1, 0x00, 0x07, 325.0, 0x045},
+ {2, 2400000, 2800000, 0x5, 0x3, 0x1, 0x00, 0x07, 330.0, 0x045},
+ {2, 2400000, 2800000, 0x5, 0x3, 0x1, 0x00, 0x07, 340.0, 0x086},
+ {2, 2400000, 2800000, 0x5, 0x3, 0x1, 0x00, 0x07, 360.0, 0x04A},
+ {2, 2400000, 2800000, 0x5, 0x3, 0x1, 0x00, 0x07, 400.0, 0x081},
+ {3, 2800000, 3400000, 0x6, 0x3, 0x1, 0x00, 0x07, 300.0, 0x03D},
+ {3, 2800000, 3400000, 0x6, 0x3, 0x1, 0x00, 0x07, 320.0, 0x041},
+ {3, 2800000, 3400000, 0x6, 0x3, 0x1, 0x00, 0x07, 325.0, 0x041},
+ {3, 2800000, 3400000, 0x6, 0x3, 0x1, 0x00, 0x07, 330.0, 0x041},
+ {3, 2800000, 3400000, 0x6, 0x3, 0x1, 0x00, 0x07, 340.0, 0x042},
+ {3, 2800000, 3400000, 0x6, 0x3, 0x1, 0x00, 0x07, 360.0, 0x043},
+ {3, 2800000, 3400000, 0x6, 0x3, 0x1, 0x00, 0x07, 400.0, 0x046},
+ {4, 3400000, 3900000, 0x4, 0x3, 0x0, 0x07, 0x0F, 375.0, 0x041},
+ {4, 3400000, 3900000, 0x4, 0x3, 0x0, 0x07, 0x0F, 600.0, 0x082},
+ {4, 3400000, 3900000, 0x4, 0x3, 0x0, 0x07, 0x0F, 680.0, 0x085},
+ {5, 3900000, 4500000, 0x5, 0x3, 0x0, 0x07, 0x0F, 450.0, 0x041},
+ {5, 3900000, 4500000, 0x5, 0x3, 0x0, 0x07, 0x0F, 600.0, 0x04B},
+ {5, 3900000, 4500000, 0x5, 0x3, 0x0, 0x07, 0x0F, 680.0, 0x082},
+ {6, 4500000, 5200000, 0x6, 0x3, 0x1, 0x00, 0x07, 600.0, 0x045},
+ {6, 4500000, 5200000, 0x6, 0x3, 0x1, 0x00, 0x07, 680.0, 0x04A},
+ {7, 5200000, 6000000, 0x7, 0x3, 0x1, 0x00, 0x07, 600.0, 0x042},
+ {7, 5200000, 6000000, 0x7, 0x3, 0x1, 0x00, 0x07, 680.0, 0x045}
+};
+
+
+/* Table 8. HDMI TX clock control settings (pixel clock is output) */
+const u32 t28hpc_hdmitx_clock_control_table_pixel_out[T28HPC_HDMITX_CLOCK_CONTROL_TABLE_ROWS_PIXEL_OUT][T28HPC_HDMITX_CLOCK_CONTROL_TABLE_COLS_PIXEL_OUT] = {
+ { 27000, 1000, 270000, 0x03, 0x1, 0x1, 240, 0x0BC, 0x030, 80, 0x026, 0x026, 2160000, 0, 2, 2, 2, 4, 135000, 0x3, 27000, 1},
+ { 27000, 1250, 337500, 0x03, 0x1, 0x1, 300, 0x0EC, 0x03C, 100, 0x030, 0x030, 2700000, 0, 2, 2, 2, 4, 168750, 0x3, 33750, 1},
+ { 27000, 1500, 405000, 0x03, 0x1, 0x1, 360, 0x11C, 0x048, 120, 0x03A, 0x03A, 3240000, 0, 2, 2, 2, 4, 202500, 0x3, 40500, 1},
+ { 27000, 2000, 540000, 0x03, 0x1, 0x1, 240, 0x0BC, 0x030, 80, 0x026, 0x026, 2160000, 0, 2, 2, 2, 4, 270000, 0x2, 54000, 1},
+ { 54000, 1000, 540000, 0x03, 0x1, 0x1, 480, 0x17C, 0x060, 80, 0x026, 0x026, 4320000, 1, 2, 2, 2, 4, 270000, 0x3, 54000, 1},
+ { 54000, 1250, 675000, 0x04, 0x1, 0x1, 400, 0x13C, 0x050, 50, 0x017, 0x017, 2700000, 0, 1, 1, 2, 4, 337500, 0x2, 67500, 1},
+ { 54000, 1500, 810000, 0x04, 0x1, 0x1, 480, 0x17C, 0x060, 60, 0x01C, 0x01C, 3240000, 0, 2, 2, 2, 2, 405000, 0x2, 81000, 1},
+ { 54000, 2000, 1080000, 0x03, 0x1, 0x1, 240, 0x0BC, 0x030, 40, 0x012, 0x012, 2160000, 0, 2, 2, 2, 1, 540000, 0x1, 108000, 1},
+ { 74250, 1000, 742500, 0x03, 0x1, 0x1, 660, 0x20C, 0x084, 80, 0x026, 0x026, 5940000, 1, 2, 2, 2, 4, 371250, 0x3, 74250, 1},
+ { 74250, 1250, 928125, 0x04, 0x1, 0x1, 550, 0x1B4, 0x06E, 50, 0x017, 0x017, 3712500, 1, 1, 1, 2, 4, 464062, 0x2, 92812, 1},
+ { 74250, 1500, 1113750, 0x04, 0x1, 0x1, 660, 0x20C, 0x084, 60, 0x01C, 0x01C, 4455000, 1, 2, 2, 2, 2, 556875, 0x2, 111375, 1},
+ { 74250, 2000, 1485000, 0x03, 0x1, 0x1, 330, 0x104, 0x042, 40, 0x012, 0x012, 2970000, 0, 2, 2, 2, 1, 742500, 0x1, 148500, 1},
+ { 99000, 1000, 990000, 0x03, 0x1, 0x1, 440, 0x15C, 0x058, 40, 0x012, 0x012, 3960000, 1, 2, 2, 2, 2, 495000, 0x2, 99000, 1},
+ { 99000, 1250, 1237500, 0x03, 0x1, 0x1, 275, 0x0D8, 0x037, 25, 0x00B, 0x00A, 2475000, 0, 1, 1, 2, 2, 618750, 0x1, 123750, 1},
+ { 99000, 1500, 1485000, 0x03, 0x1, 0x1, 330, 0x104, 0x042, 30, 0x00D, 0x00D, 2970000, 0, 2, 2, 2, 1, 742500, 0x1, 148500, 1},
+ { 99000, 2000, 1980000, 0x03, 0x1, 0x1, 440, 0x15C, 0x058, 40, 0x012, 0x012, 3960000, 1, 2, 2, 2, 1, 990000, 0x1, 198000, 1},
+ {148500, 1000, 1485000, 0x03, 0x1, 0x1, 660, 0x20C, 0x084, 40, 0x012, 0x012, 5940000, 1, 2, 2, 2, 2, 742500, 0x2, 148500, 1},
+ {148500, 1250, 1856250, 0x04, 0x1, 0x1, 550, 0x1B4, 0x06E, 25, 0x00B, 0x00A, 3712500, 1, 1, 1, 2, 2, 928125, 0x1, 185625, 1},
+ {148500, 1500, 2227500, 0x03, 0x1, 0x1, 495, 0x188, 0x063, 30, 0x00D, 0x00D, 4455000, 1, 1, 1, 2, 2, 1113750, 0x1, 222750, 1},
+ {148500, 2000, 2970000, 0x03, 0x1, 0x1, 660, 0x20C, 0x084, 40, 0x012, 0x012, 5940000, 1, 2, 2, 2, 1, 1485000, 0x1, 297000, 1},
+ {198000, 1000, 1980000, 0x03, 0x1, 0x1, 220, 0x0AC, 0x02C, 10, 0x003, 0x003, 1980000, 0, 1, 1, 2, 1, 990000, 0x0, 198000, 1},
+ {198000, 1250, 2475000, 0x03, 0x1, 0x1, 550, 0x1B4, 0x06E, 25, 0x00B, 0x00A, 4950000, 1, 1, 1, 2, 2, 1237500, 0x1, 247500, 1},
+ {198000, 1500, 2970000, 0x03, 0x1, 0x1, 330, 0x104, 0x042, 15, 0x006, 0x005, 2970000, 0, 1, 1, 2, 1, 1485000, 0x0, 297000, 1},
+ {198000, 2000, 3960000, 0x03, 0x1, 0x1, 440, 0x15C, 0x058, 20, 0x008, 0x008, 3960000, 1, 1, 1, 2, 1, 1980000, 0x0, 396000, 1},
+ {297000, 1000, 2970000, 0x03, 0x1, 0x1, 330, 0x104, 0x042, 10, 0x003, 0x003, 2970000, 0, 1, 1, 2, 1, 1485000, 0x0, 297000, 1},
+ {297000, 1500, 4455000, 0x03, 0x1, 0x1, 495, 0x188, 0x063, 15, 0x006, 0x005, 4455000, 1, 1, 1, 2, 1, 2227500, 0x0, 445500, 1},
+ {297000, 2000, 5940000, 0x03, 0x1, 0x1, 660, 0x20C, 0x084, 20, 0x008, 0x008, 5940000, 1, 1, 1, 2, 1, 2970000, 0x0, 594000, 1},
+ {594000, 1000, 5940000, 0x03, 0x1, 0x1, 660, 0x20C, 0x084, 10, 0x003, 0x003, 5940000, 1, 1, 1, 2, 1, 2970000, 0x0, 594000, 1},
+ {594000, 750, 4455000, 0x03, 0x1, 0x1, 495, 0x188, 0x063, 10, 0x003, 0x003, 4455000, 1, 1, 1, 2, 1, 2227500, 0x0, 445500, 0},
+ {594000, 625, 3712500, 0x04, 0x1, 0x1, 550, 0x1B4, 0x06E, 10, 0x003, 0x003, 3712500, 1, 1, 1, 2, 1, 1856250, 0x0, 371250, 0},
+ {594000, 500, 2970000, 0x03, 0x1, 0x1, 660, 0x20C, 0x084, 10, 0x003, 0x003, 5940000, 1, 1, 1, 2, 2, 1485000, 0x1, 297000, 1},
+ /* new VESA */
+#if 0 /* VESA pixel clock rate support in debuging */
+ { 40000, 1000, 400275, 0x05, 0x1, 0x1, 593, 0x126, 0x127, 80, 0x026, 0x026, 3202200, 1, 1, 1, 1, 1, 200137, 0x3, 40027, 1},
+ { 40000, 1250, 500175, 0x05, 0x1, 0x1, 741, 0x170, 0x171, 100, 0x030, 0x030, 4001400, 1, 1, 1, 1, 1, 250087, 0x3, 50017, 1},
+ { 40000, 1500, 600075, 0x05, 0x1, 0x1, 889, 0x1BA, 0x1BB, 120, 0x03A, 0x03A, 4800600, 1, 1, 1, 1, 1, 300037, 0x3, 60007, 1},
+ { 40000, 2000, 800550, 0x05, 0x1, 0x1, 593, 0x126, 0x127, 80, 0x026, 0x026, 3202200, 1, 1, 1, 1, 1, 400275, 0x2, 80055, 1},
+ { 65000, 1000, 650025, 0x05, 0x1, 0x1, 963, 0x1DF, 0x1E0, 80, 0x026, 0x026, 5200200, 1, 1, 1, 1, 1, 325012, 0x3, 65002, 1},
+ { 65000, 1250, 812700, 0x05, 0x1, 0x1, 602, 0x12B, 0x12B, 50, 0x017, 0x017, 3250800, 1, 1, 1, 1, 1, 406350, 0x2, 81270, 1},
+ { 65000, 1500, 974700, 0x05, 0x1, 0x1, 722, 0x167, 0x167, 60, 0x01C, 0x01C, 3898800, 1, 1, 1, 1, 1, 487350, 0x2, 97470, 1},
+ { 65000, 2000, 1300050, 0x05, 0x1, 0x1, 963, 0x1DF, 0x1E0, 80, 0x026, 0x026, 5200200, 1, 1, 1, 1, 1, 650025, 0x2, 130005, 1},
+ {108000, 1000, 1080000, 0x05, 0x1, 0x1, 800, 0x18E, 0x18E, 40, 0x012, 0x012, 4320000, 1, 1, 1, 1, 1, 540000, 0x2, 108000, 1},
+ {108000, 1250, 1350000, 0x05, 0x1, 0x1, 1000, 0x1F2, 0x1F2, 50, 0x017, 0x017, 5400000, 1, 1, 1, 1, 1, 675000, 0x2, 135000, 1},
+ {108000, 1500, 1620000, 0x05, 0x1, 0x1, 600, 0x12A, 0x12A, 30, 0x00D, 0x00D, 3240000, 1, 1, 1, 1, 1, 810000, 0x1, 162000, 1},
+ {108000, 2000, 2160000, 0x05, 0x1, 0x1, 800, 0x18E, 0x18E, 40, 0x012, 0x012, 4320000, 1, 1, 1, 1, 1, 1080000, 0x1, 216000, 1},
+ {154000, 1000, 1539000, 0x05, 0x1, 0x1, 570, 0x11B, 0x11B, 20, 0x008, 0x008, 3078000, 1, 1, 1, 1, 1, 769500, 0x1, 153900, 1},
+ {154000, 1250, 1925100, 0x05, 0x1, 0x1, 713, 0x162, 0x163, 25, 0x00A, 0x00B, 3850200, 1, 1, 1, 1, 1, 962550, 0x1, 192510, 1},
+ {154000, 1500, 2311200, 0x05, 0x1, 0x1, 856, 0x1AA, 0x1AA, 30, 0x00D, 0x00D, 4622400, 1, 1, 1, 1, 1, 1155600, 0x1, 231120, 1},
+ {154000, 2000, 3078000, 0x05, 0x1, 0x1, 570, 0x11B, 0x11B, 20, 0x008, 0x008, 3078000, 1, 1, 1, 1, 1, 1539000, 0x0, 307800, 1}
+#endif
+};
+
+/* Table 9. HDMI TX PLL tuning settings (pixel clock is output) */
+const u32 t28hpc_hdmitx_pll_tuning_table_pixel_out[T28HPC_HDMITX_PLL_TUNING_TABLE_ROWS_PIXEL_OUT][T28HPC_HDMITX_PLL_TUNING_TABLE_COLS_PIXEL_OUT] = {
+ { 1, 1980000, 1980000, 0x4, 0x3, 0x0, 0x09, 0x09, 220, 0x42, 160, 5, 183},
+ { 2, 2160000, 2160000, 0x4, 0x3, 0x0, 0x09, 0x09, 240, 0x42, 166, 6, 208},
+ { 3, 2475000, 2475000, 0x5, 0x3, 0x1, 0x00, 0x07, 275, 0x42, 167, 6, 209},
+ { 4, 2700000, 2700000, 0x5, 0x3, 0x1, 0x00, 0x07, 300, 0x42, 188, 6, 230},
+ { 4, 2700000, 2700000, 0x5, 0x3, 0x1, 0x00, 0x07, 400, 0x4C, 188, 6, 230},
+ { 5, 2970000, 2970000, 0x6, 0x3, 0x1, 0x00, 0x07, 330, 0x42, 183, 6, 225},
+ { 6, 3240000, 3240000, 0x6, 0x3, 0x1, 0x00, 0x07, 360, 0x42, 203, 7, 256},
+ { 6, 3240000, 3240000, 0x6, 0x3, 0x1, 0x00, 0x07, 480, 0x4C, 203, 7, 256},
+ { 7, 3712500, 3712500, 0x4, 0x3, 0x0, 0x07, 0x0F, 550, 0x4C, 212, 7, 257},
+ { 8, 3960000, 3960000, 0x5, 0x3, 0x0, 0x07, 0x0F, 440, 0x42, 184, 6, 226},
+ { 9, 4320000, 4320000, 0x5, 0x3, 0x1, 0x07, 0x0F, 480, 0x42, 205, 7, 258},
+ {10, 4455000, 4455000, 0x5, 0x3, 0x0, 0x07, 0x0F, 495, 0x42, 219, 7, 272},
+ {10, 4455000, 4455000, 0x5, 0x3, 0x0, 0x07, 0x0F, 660, 0x4C, 219, 7, 272},
+ {11, 4950000, 4950000, 0x6, 0x3, 0x1, 0x00, 0x07, 550, 0x42, 213, 7, 258},
+ {12, 5940000, 5940000, 0x7, 0x3, 0x1, 0x00, 0x07, 660, 0x42, 244, 8, 292},
+ /* new VESA */
+ {13, 3078000, 3078000, 0x6, 0x3, 0x1, 0x00, 0x07, 570, 0x4C, 183, 6, 225}, /* nominal VCO freq: 3078000 */
+ {14, 3202100, 3202300, 0x6, 0x3, 0x1, 0x00, 0x07, 593, 0x4C, 203, 7, 256}, /* nominal VCO freq: 3202200 */
+ {15, 3240000, 3240000, 0x6, 0x3, 0x1, 0x00, 0x07, 600, 0x4C, 203, 7, 256}, /* nominal VCO freq: 3240000 */
+ {16, 3250700, 3250900, 0x6, 0x3, 0x1, 0x00, 0x07, 602, 0x4C, 203, 7, 256}, /* nominal VCO freq: 3250800 */
+ {17, 3850100, 3850300, 0x5, 0x3, 0x0, 0x07, 0x0F, 713, 0x42, 184, 6, 226}, /* nominal VCO freq: 3850200 */
+ {18, 3898700, 3898900, 0x5, 0x3, 0x0, 0x07, 0x0F, 722, 0x42, 184, 6, 226}, /* nominal VCO freq: 3898800 */
+ {19, 4001300, 4001500, 0x5, 0x3, 0x0, 0x07, 0x0F, 741, 0x42, 184, 6, 226}, /* nominal VCO freq: 4001400 */
+ {20, 4320000, 4320000, 0x5, 0x3, 0x1, 0x07, 0x0F, 800, 0x42, 205, 7, 258}, /* nominal VCO freq: 4320000 */
+ {21, 4622300, 4622500, 0x5, 0x3, 0x0, 0x07, 0x0F, 856, 0x4C, 219, 7, 272}, /* nominal VCO freq: 4622400 */
+ {22, 4800500, 4800700, 0x6, 0x3, 0x1, 0x00, 0x07, 889, 0x42, 213, 7, 258}, /* nominal VCO freq: 4800600 */
+ {23, 5200100, 5200300, 0x6, 0x3, 0x1, 0x00, 0x07, 963, 0x42, 213, 7, 258}, /* nominal VCO freq: 5200200 */
+ {24, 5400000, 5400000, 0x6, 0x3, 0x1, 0x00, 0x07, 1000, 0x42, 213, 7, 258} /* nominal VCO freq: 5400000 */
+};
diff --git a/drivers/gpu/drm/imx/hdp/t28hpc_hdmitx_table.h b/drivers/gpu/drm/imx/hdp/t28hpc_hdmitx_table.h
new file mode 100644
index 000000000000..3c223eceb18e
--- /dev/null
+++ b/drivers/gpu/drm/imx/hdp/t28hpc_hdmitx_table.h
@@ -0,0 +1,156 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2016-2017 Cadence Design Systems, Inc.
+ * All rights reserved worldwide.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 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.
+ *
+ * Copyright 2018 NXP
+ *
+ ******************************************************************************
+ *
+ * t28hpc_hdmitx_table.h
+ *
+ ******************************************************************************
+ */
+
+#ifndef T28HPC_HDMITX_TABLE_H_
+#define T28HPC_HDMITX_TABLE_H_
+
+#include <linux/io.h>
+
+#define T28HPC_HDMITX_CLOCK_CONTROL_TABLE_ROWS_PIXEL_IN 22
+
+#define T28HPC_HDMITX_PLL_TUNING_TABLE_ROWS_PIXEL_IN 38
+
+#define T28HPC_HDMITX_CLOCK_CONTROL_TABLE_ROWS_PIXEL_OUT 47
+
+#define T28HPC_HDMITX_PLL_TUNING_TABLE_ROWS_PIXEL_OUT 27
+
+/* Table 6. HDMI TX clock control settings (pixel clock is input) */
+typedef enum {
+ T6_PIXEL_CLK_FREQ_KHZ_MIN,
+ T6_PIXEL_CLK_FREQ_KHZ_MAX,
+ T6_FEEDBACK_FACTOR,
+ T6_DATA_RANGE_MBPS_MIN,
+ T6_DATA_RANGE_MBPS_MAX,
+ T6_CMNDA_PLL0_IP_DIV,
+ T6_CMN_REF_CLK_DIG_DIV,
+ T6_REF_CLK_DIVIDER_SCALER,
+ T6_PLL_FB_DIV_TOTAL,
+ T6_CMNDA_PLL0_FB_DIV_LOW,
+ T6_CMNDA_PLL0_FB_DIV_HIGH,
+ T6_VCO_FREQ_KHZ_MIN,
+ T6_VCO_FREQ_KHZ_MAX,
+ T6_VCO_RING_SELECT,
+ T6_CMNDA_HS_CLK_0_SEL,
+ T6_CMNDA_HS_CLK_1_SEL,
+ T6_HSCLK_DIV_AT_XCVR,
+ T6_HSCLK_DIV_TX_SUB_RATE,
+ T6_TX_CLK_KHZ_MIN,
+ T6_TX_CLK_KHZ_MAX,
+ T6_CMNDA_PLL0_HS_SYM_DIV_SEL,
+ T6_CMNDA_PLL0_CLK_FREQ_KHZ_MIN,
+ T6_CMNDA_PLL0_CLK_FREQ_KHZ_MAX,
+ T28HPC_HDMITX_CLOCK_CONTROL_TABLE_COLS_PIXEL_IN
+} CLK_CTRL_PARAM_PIXEL_IN;
+
+
+/* Table 7. HDMI TX PLL tuning settings (pixel clock is input) */
+typedef enum {
+ T7_VCO_FREQ_BIN,
+ T7_PLL_VCO_FREQ_KHZ_MIN,
+ T7_PLL_VCO_FREQ_KHZ_MAX,
+ T7_VOLTAGE_TO_CURRENT_COARSE,
+ T7_VOLTAGE_TO_CURRENT,
+ T7_NDAC_CTRL,
+ T7_PMOS_CTRL,
+ T7_PTAT_NDAC_CTRL,
+ T7_PLL_FEEDBACK_DIV_TOTAL,
+ T7_CHARGE_PUMP_GAIN,
+ T28HPC_HDMITX_PLL_TUNING_TABLE_COLS_PIXEL_IN
+} PLL_TUNE_PARAM_PIXEL_IN;
+
+
+/* Table 8. HDMI TX control settings (pixel clock is output) */
+typedef enum {
+ T8_PIXEL_CLK_FREQ_KHZ,
+ T8_FEEDBACK_FACTOR,
+ T8_DATA_RANGE_MBPS,
+ T8_CMNDA_PLL0_IP_DIV,
+ T8_CMN_REF_CLK_DIG_DIV,
+ T8_REF_CLK_DIVIDER_SCALER,
+ T8_PLL_FB_DIV_TOTAL,
+ T8_CMNDA_PLL0_FB_DIV_LOW,
+ T8_CMNDA_PLL0_FB_DIV_HIGH,
+ T8_PIXEL_DIV_TOTAL,
+ T8_CMNDA_PLL0_PXDIV_LOW,
+ T8_CMNDA_PLL0_PXDIV_HIGH,
+ T8_VCO_FREQ_KHZ,
+ T8_VCO_RING_SELECT,
+ T8_CMNDA_HS_CLK_0_SEL,
+ T8_CMNDA_HS_CLK_1_SEL,
+ T8_HSCLK_DIV_AT_XCVR,
+ T8_HSCLK_DIV_TX_SUB_RATE,
+ T8_TX_CLK_KHZ,
+ T8_CMNDA_PLL0_HS_SYM_DIV_SEL,
+ T8_CMNDA_PLL0_CLK_FREQ_KHZ,
+ T8_PIXEL_CLK_OUTPUT_ENABLE,
+ T28HPC_HDMITX_CLOCK_CONTROL_TABLE_COLS_PIXEL_OUT
+} CLK_CTRL_PARAM_PIXEL_OUT;
+
+/* Table 9. HDMI TX PLL tuning settings (pixel clock is output) */
+typedef enum {
+ T9_VCO_FREQ_BIN,
+ T9_PLL_VCO_FREQ_KHZ_MIN,
+ T9_PLL_VCO_FREQ_KHZ_MAX,
+ T9_VOLTAGE_TO_CURRENT_COARSE,
+ T9_VOLTAGE_TO_CURRENT,
+ T9_NDAC_CTRL,
+ T9_PMOS_CTRL,
+ T9_PTAT_NDAC_CTRL,
+ T9_PLL_FEEDBACK_DIV_TOTAL,
+ T9_CHARGE_PUMP_GAIN,
+ T9_COARSE_CODE,
+ T9_V2I_CODE,
+ T9_VCO_CAL_CODE,
+ T28HPC_HDMITX_PLL_TUNING_TABLE_COLS_PIXEL_OUT
+} PLL_TUNE_PARAM_PIXEL_OUT;
+
+extern const u32 t28hpc_hdmitx_clock_control_table_pixel_in[T28HPC_HDMITX_CLOCK_CONTROL_TABLE_ROWS_PIXEL_IN][T28HPC_HDMITX_CLOCK_CONTROL_TABLE_COLS_PIXEL_IN];
+extern const u32 t28hpc_hdmitx_pll_tuning_table_pixel_in[T28HPC_HDMITX_PLL_TUNING_TABLE_ROWS_PIXEL_IN][T28HPC_HDMITX_PLL_TUNING_TABLE_COLS_PIXEL_IN];
+extern const u32 t28hpc_hdmitx_clock_control_table_pixel_out[T28HPC_HDMITX_CLOCK_CONTROL_TABLE_ROWS_PIXEL_OUT][T28HPC_HDMITX_CLOCK_CONTROL_TABLE_COLS_PIXEL_OUT];
+extern const u32 t28hpc_hdmitx_pll_tuning_table_pixel_out[T28HPC_HDMITX_PLL_TUNING_TABLE_ROWS_PIXEL_OUT][T28HPC_HDMITX_PLL_TUNING_TABLE_COLS_PIXEL_OUT];
+
+#endif
+
diff --git a/drivers/gpu/drm/imx/imx-drm-core.c b/drivers/gpu/drm/imx/imx-drm-core.c
index f91cb72d0830..453100d7a0e9 100644
--- a/drivers/gpu/drm/imx/imx-drm-core.c
+++ b/drivers/gpu/drm/imx/imx-drm-core.c
@@ -15,7 +15,6 @@
*/
#include <linux/component.h>
#include <linux/device.h>
-#include <linux/dma-buf.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <drm/drmP.h>
@@ -28,18 +27,12 @@
#include <drm/drm_plane_helper.h>
#include <drm/drm_of.h>
#include <video/imx-ipu-v3.h>
+#include <video/dpu.h>
+#include <video/imx-dcss.h>
+#include <video/imx-lcdif.h>
#include "imx-drm.h"
-#include "ipuv3-plane.h"
-
-#define MAX_CRTC 4
-
-struct imx_drm_device {
- struct drm_device *drm;
- unsigned int pipes;
- struct drm_fbdev_cma *fbhelper;
- struct drm_atomic_state *state;
-};
+#include "ipuv3/ipuv3-plane.h"
#if IS_ENABLED(CONFIG_DRM_FBDEV_EMULATION)
static int legacyfb_depth = 16;
@@ -68,86 +61,6 @@ void imx_drm_encoder_destroy(struct drm_encoder *encoder)
}
EXPORT_SYMBOL_GPL(imx_drm_encoder_destroy);
-static void imx_drm_output_poll_changed(struct drm_device *drm)
-{
- struct imx_drm_device *imxdrm = drm->dev_private;
-
- drm_fbdev_cma_hotplug_event(imxdrm->fbhelper);
-}
-
-static int imx_drm_atomic_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;
-
- /*
- * Check modeset again in case crtc_state->mode_changed is
- * updated in plane's ->atomic_check callback.
- */
- ret = drm_atomic_helper_check_modeset(dev, state);
- if (ret)
- return ret;
-
- /* Assign PRG/PRE channels and check if all constrains are satisfied. */
- ret = ipu_planes_assign_pre(dev, state);
- if (ret)
- return ret;
-
- return ret;
-}
-
-static const struct drm_mode_config_funcs imx_drm_mode_config_funcs = {
- .fb_create = drm_fb_cma_create,
- .output_poll_changed = imx_drm_output_poll_changed,
- .atomic_check = imx_drm_atomic_check,
- .atomic_commit = drm_atomic_helper_commit,
-};
-
-static void imx_drm_atomic_commit_tail(struct drm_atomic_state *state)
-{
- struct drm_device *dev = state->dev;
- struct drm_plane *plane;
- struct drm_plane_state *old_plane_state, *new_plane_state;
- bool plane_disabling = false;
- int i;
-
- drm_atomic_helper_commit_modeset_disables(dev, state);
-
- drm_atomic_helper_commit_planes(dev, state,
- DRM_PLANE_COMMIT_ACTIVE_ONLY |
- DRM_PLANE_COMMIT_NO_DISABLE_AFTER_MODESET);
-
- drm_atomic_helper_commit_modeset_enables(dev, state);
-
- for_each_oldnew_plane_in_state(state, plane, old_plane_state, new_plane_state, i) {
- if (drm_atomic_plane_disabling(old_plane_state, new_plane_state))
- plane_disabling = true;
- }
-
- if (plane_disabling) {
- drm_atomic_helper_wait_for_vblanks(dev, state);
-
- for_each_old_plane_in_state(state, plane, old_plane_state, i)
- ipu_plane_disable_deferred(plane);
-
- }
-
- drm_atomic_helper_commit_hw_done(state);
-}
-
-static const struct drm_mode_config_helper_funcs imx_drm_mode_config_helpers = {
- .atomic_commit_tail = imx_drm_atomic_commit_tail,
-};
-
-
int imx_drm_encoder_parse_of(struct drm_device *drm,
struct drm_encoder *encoder, struct device_node *np)
{
@@ -212,6 +125,33 @@ static int compare_of(struct device *dev, void *data)
struct ipu_client_platformdata *pdata = dev->platform_data;
return pdata->of_node == np;
+ } else if (strcmp(dev->driver->name, "imx-dpu-crtc") == 0) {
+ struct dpu_client_platformdata *pdata = dev->platform_data;
+
+ return pdata->of_node == np;
+ } else if (strcmp(dev->driver->name, "imx-dcss-crtc") == 0) {
+ struct dcss_client_platformdata *pdata = dev->platform_data;
+
+ return pdata->of_node == np;
+ } else if (strcmp(dev->driver->name, "imx-lcdif-crtc") == 0) {
+ struct lcdif_client_platformdata *pdata = dev->platform_data;
+#if IS_ENABLED(CONFIG_DRM_FBDEV_EMULATION)
+ /* set legacyfb_depth to be 32 for lcdif, since
+ * default format of the connectors attached to
+ * lcdif is usually RGB888
+ */
+ if (pdata->of_node == np)
+ legacyfb_depth = 32;
+#endif
+
+ return pdata->of_node == np;
+ }
+
+ /* This is a special case for dpu bliteng. */
+ if (strcmp(dev->driver->name, "imx-drm-dpu-bliteng") == 0) {
+ struct dpu_client_platformdata *pdata = dev->platform_data;
+
+ return pdata->of_node == np;
}
/* Special case for LDB, one device for two channels */
@@ -223,12 +163,115 @@ static int compare_of(struct device *dev, void *data)
return dev->of_node == np;
}
+static const char *const imx_drm_dpu_comp_parents[] = {
+ "fsl,imx8qm-dpu",
+ "fsl,imx8qxp-dpu",
+};
+
+static const char *const imx_drm_dcss_comp_parents[] = {
+ "nxp,imx8mq-dcss",
+};
+
+static bool imx_drm_parent_is_compatible(struct device *dev,
+ const char *const comp_parents[],
+ int comp_parents_size)
+{
+ struct device_node *port, *parent;
+ bool ret = false;
+ int i;
+
+ port = of_parse_phandle(dev->of_node, "ports", 0);
+ if (!port)
+ return ret;
+
+ parent = of_get_parent(port);
+
+ for (i = 0; i < comp_parents_size; i++) {
+ if (of_device_is_compatible(parent, comp_parents[i])) {
+ ret = true;
+ break;
+ }
+ }
+
+ of_node_put(parent);
+
+ of_node_put(port);
+
+ return ret;
+}
+
+static inline bool has_dpu(struct device *dev)
+{
+ return imx_drm_parent_is_compatible(dev, imx_drm_dpu_comp_parents,
+ ARRAY_SIZE(imx_drm_dpu_comp_parents));
+}
+
+static inline bool has_dcss(struct device *dev)
+{
+ return imx_drm_parent_is_compatible(dev, imx_drm_dcss_comp_parents,
+ ARRAY_SIZE(imx_drm_dcss_comp_parents));
+}
+
+static void add_dpu_bliteng_components(struct device *dev,
+ struct component_match **matchptr)
+{
+ /*
+ * As there may be two dpu bliteng device,
+ * so need add something in compare data to distinguish.
+ * Use its parent dpu's of_node as the data here.
+ */
+ struct device_node *port, *parent;
+ /* assume max dpu number is 8 */
+ struct device_node *dpu[8];
+ int num_dpu = 0;
+ int i, j;
+ bool found = false;
+
+ for (i = 0; ; i++) {
+ port = of_parse_phandle(dev->of_node, "ports", i);
+ if (!port)
+ break;
+
+ parent = of_get_parent(port);
+
+ for (j = 0; j < num_dpu; j++) {
+ if (dpu[j] == parent) {
+ found = true;
+ break;
+ }
+ }
+
+ if (found) {
+ found = false;
+ } else {
+ if (num_dpu >= ARRAY_SIZE(dpu)) {
+ dev_err(dev, "The number of found dpu is greater than max [%ld].\n",
+ ARRAY_SIZE(dpu));
+ of_node_put(parent);
+ of_node_put(port);
+ break;
+ }
+
+ dpu[num_dpu] = parent;
+ num_dpu++;
+
+ component_match_add(dev, matchptr, compare_of, parent);
+ }
+
+ of_node_put(parent);
+ of_node_put(port);
+ }
+}
+
static int imx_drm_bind(struct device *dev)
{
struct drm_device *drm;
struct imx_drm_device *imxdrm;
int ret;
+ if (has_dpu(dev))
+ imx_drm_driver.driver_features |= DRIVER_RENDER;
+
drm = drm_dev_alloc(&imx_drm_driver, dev);
if (IS_ERR(drm))
return PTR_ERR(drm);
@@ -242,6 +285,27 @@ static int imx_drm_bind(struct device *dev)
imxdrm->drm = drm;
drm->dev_private = imxdrm;
+ if (has_dpu(dev)) {
+ imxdrm->dpu_nonblock_commit_wq =
+ alloc_workqueue("dpu_nonblock_commit_wq",
+ WQ_UNBOUND | WQ_FREEZABLE, 0);
+ if (!imxdrm->dpu_nonblock_commit_wq) {
+ ret = -ENOMEM;
+ goto err_wq;
+ }
+ }
+
+ if (has_dcss(dev)) {
+ imxdrm->dcss_nonblock_commit_wq =
+ alloc_ordered_workqueue("dcss_nonblock_commit_wq", 0);
+ if (!imxdrm->dcss_nonblock_commit_wq) {
+ ret = -ENOMEM;
+ goto err_wq;
+ }
+ }
+
+ init_waitqueue_head(&imxdrm->commit.wait);
+
/*
* enable drm irq mode.
* - with irq_enabled = true, we can use the vblank feature.
@@ -262,8 +326,11 @@ static int imx_drm_bind(struct device *dev)
drm->mode_config.min_height = 1;
drm->mode_config.max_width = 4096;
drm->mode_config.max_height = 4096;
- drm->mode_config.funcs = &imx_drm_mode_config_funcs;
- drm->mode_config.helper_private = &imx_drm_mode_config_helpers;
+
+ if (has_dpu(dev) || has_dcss(dev)) {
+ drm->mode_config.allow_fb_modifiers = true;
+ dev_dbg(dev, "allow fb modifiers\n");
+ }
drm_mode_config_init(drm);
@@ -290,6 +357,10 @@ static int imx_drm_bind(struct device *dev)
dev_warn(dev, "Invalid legacyfb_depth. Defaulting to 16bpp\n");
legacyfb_depth = 16;
}
+
+ if (legacyfb_depth == 16 && has_dcss(dev))
+ legacyfb_depth = 32;
+
imxdrm->fbhelper = drm_fbdev_cma_init(drm, legacyfb_depth, MAX_CRTC);
if (IS_ERR(imxdrm->fbhelper)) {
ret = PTR_ERR(imxdrm->fbhelper);
@@ -315,7 +386,13 @@ err_unbind:
#endif
component_unbind_all(drm->dev, drm);
err_kms:
+ dev_set_drvdata(dev, NULL);
drm_mode_config_cleanup(drm);
+err_wq:
+ if (imxdrm->dcss_nonblock_commit_wq)
+ destroy_workqueue(imxdrm->dcss_nonblock_commit_wq);
+ if (imxdrm->dpu_nonblock_commit_wq)
+ destroy_workqueue(imxdrm->dpu_nonblock_commit_wq);
err_unref:
drm_dev_unref(drm);
@@ -327,6 +404,14 @@ static void imx_drm_unbind(struct device *dev)
struct drm_device *drm = dev_get_drvdata(dev);
struct imx_drm_device *imxdrm = drm->dev_private;
+ if (has_dpu(dev)) {
+ imx_drm_driver.driver_features &= ~DRIVER_RENDER;
+ flush_workqueue(imxdrm->dpu_nonblock_commit_wq);
+ }
+
+ if (has_dcss(dev))
+ flush_workqueue(imxdrm->dcss_nonblock_commit_wq);
+
drm_dev_unregister(drm);
drm_kms_helper_poll_fini(drm);
@@ -339,6 +424,12 @@ static void imx_drm_unbind(struct device *dev)
component_unbind_all(drm->dev, drm);
dev_set_drvdata(dev, NULL);
+ if (has_dpu(dev))
+ destroy_workqueue(imxdrm->dpu_nonblock_commit_wq);
+
+ if (has_dcss(dev))
+ destroy_workqueue(imxdrm->dcss_nonblock_commit_wq);
+
drm_dev_unref(drm);
}
@@ -349,7 +440,14 @@ static const struct component_master_ops imx_drm_ops = {
static int imx_drm_platform_probe(struct platform_device *pdev)
{
- int ret = drm_of_component_probe(&pdev->dev, compare_of, &imx_drm_ops);
+ struct component_match *match = NULL;
+ int ret;
+
+ if (has_dpu(&pdev->dev))
+ add_dpu_bliteng_components(&pdev->dev, &match);
+
+ ret = drm_of_component_probe_with_match(&pdev->dev, match, compare_of,
+ &imx_drm_ops);
if (!ret)
ret = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
@@ -418,23 +516,7 @@ static struct platform_driver imx_drm_pdrv = {
.of_match_table = imx_drm_dt_ids,
},
};
-
-static struct platform_driver * const drivers[] = {
- &imx_drm_pdrv,
- &ipu_drm_driver,
-};
-
-static int __init imx_drm_init(void)
-{
- return platform_register_drivers(drivers, ARRAY_SIZE(drivers));
-}
-module_init(imx_drm_init);
-
-static void __exit imx_drm_exit(void)
-{
- platform_unregister_drivers(drivers, ARRAY_SIZE(drivers));
-}
-module_exit(imx_drm_exit);
+module_platform_driver(imx_drm_pdrv);
MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de>");
MODULE_DESCRIPTION("i.MX drm driver core");
diff --git a/drivers/gpu/drm/imx/imx-drm.h b/drivers/gpu/drm/imx/imx-drm.h
index f0b7556c0857..a0e0020d4cf3 100644
--- a/drivers/gpu/drm/imx/imx-drm.h
+++ b/drivers/gpu/drm/imx/imx-drm.h
@@ -2,6 +2,8 @@
#ifndef _IMX_DRM_H_
#define _IMX_DRM_H_
+#define MAX_CRTC 4
+
struct device_node;
struct drm_crtc;
struct drm_connector;
@@ -14,6 +16,20 @@ struct drm_plane;
struct imx_drm_crtc;
struct platform_device;
+struct imx_drm_device {
+ struct drm_device *drm;
+ unsigned int pipes;
+ struct drm_fbdev_cma *fbhelper;
+ struct drm_atomic_state *state;
+
+ struct workqueue_struct *dpu_nonblock_commit_wq;
+ struct workqueue_struct *dcss_nonblock_commit_wq;
+ struct {
+ wait_queue_head_t wait;
+ bool pending;
+ } commit;
+};
+
struct imx_crtc_state {
struct drm_crtc_state base;
u32 bus_format;
@@ -30,8 +46,6 @@ int imx_drm_init_drm(struct platform_device *pdev,
int preferred_bpp);
int imx_drm_exit_drm(void);
-extern struct platform_driver ipu_drm_driver;
-
void imx_drm_mode_config_init(struct drm_device *drm);
struct drm_gem_cma_object *imx_drm_fb_get_obj(struct drm_framebuffer *fb);
diff --git a/drivers/gpu/drm/imx/imx-ldb.c b/drivers/gpu/drm/imx/imx-ldb.c
index 4f2e6c7e04c1..5027efd3d8b1 100644
--- a/drivers/gpu/drm/imx/imx-ldb.c
+++ b/drivers/gpu/drm/imx/imx-ldb.c
@@ -29,8 +29,12 @@
#include <linux/of_graph.h>
#include <video/of_display_timing.h>
#include <video/of_videomode.h>
+#include <linux/phy/phy.h>
+#include <linux/phy/phy-mixel-lvds.h>
+#include <linux/phy/phy-mixel-lvds-combo.h>
#include <linux/regmap.h>
#include <linux/videodev2.h>
+#include <soc/imx8/sc/sci.h>
#include "imx-drm.h"
@@ -50,6 +54,13 @@
#define LDB_DI0_VS_POL_ACT_LOW (1 << 9)
#define LDB_DI1_VS_POL_ACT_LOW (1 << 10)
#define LDB_BGREF_RMODE_INT (1 << 15)
+#define LDB_CH0_10BIT_EN (1 << 22)
+#define LDB_CH1_10BIT_EN (1 << 23)
+#define LDB_CH0_DATA_WIDTH_24BIT (1 << 24)
+#define LDB_CH1_DATA_WIDTH_24BIT (1 << 26)
+#define LDB_CH0_DATA_WIDTH_30BIT (2 << 24)
+#define LDB_CH1_DATA_WIDTH_30BIT (2 << 26)
+#define LDB_CH_SEL (1 << 28)
struct imx_ldb;
@@ -62,6 +73,10 @@ struct imx_ldb_channel {
struct drm_panel *panel;
struct drm_bridge *bridge;
+ struct phy *phy;
+ struct phy *aux_phy;
+ bool phy_is_on;
+
struct device_node *child;
struct i2c_adapter *ddc;
int chno;
@@ -89,16 +104,61 @@ struct bus_mux {
int mask;
};
+struct devtype {
+ int ctrl_reg;
+ struct bus_mux *bus_mux;
+ bool capable_10bit;
+ bool visible_phy;
+ bool has_mux;
+ bool has_ch_sel;
+ bool has_aux_ldb;
+ bool is_imx8;
+ bool use_mixel_phy;
+ bool use_mixel_combo_phy;
+ bool padding_quirks;
+ bool pixel_link_init_quirks;
+ bool pixel_link_valid_quirks;
+ bool pixel_link_enable_quirks;
+
+ /* pixel rate in KHz */
+ unsigned int max_prate_single_mode;
+ unsigned int max_prate_dual_mode;
+};
+
struct imx_ldb {
struct regmap *regmap;
+ struct regmap *aux_regmap;
struct device *dev;
struct imx_ldb_channel channel[2];
struct clk *clk[2]; /* our own clock */
struct clk *clk_sel[4]; /* parent of display clock */
struct clk *clk_parent[4]; /* original parent of clk_sel */
struct clk *clk_pll[2]; /* upstream clock we can adjust */
+ struct clk *clk_pixel;
+ struct clk *clk_bypass;
+ struct clk *clk_aux_pixel;
+ struct clk *clk_aux_bypass;
+ u32 ldb_ctrl_reg;
u32 ldb_ctrl;
const struct bus_mux *lvds_mux;
+ bool capable_10bit;
+ bool visible_phy;
+ bool has_mux;
+ bool has_ch_sel;
+ bool has_aux_ldb;
+ bool is_imx8;
+ bool use_mixel_phy;
+ bool use_mixel_combo_phy;
+ bool padding_quirks;
+ bool pixel_link_init_quirks;
+ bool pixel_link_valid_quirks;
+ bool pixel_link_enable_quirks;
+
+ /* pixel rate in KHz */
+ unsigned int max_prate_single_mode;
+ unsigned int max_prate_dual_mode;
+
+ int id;
};
static void imx_ldb_ch_set_bus_format(struct imx_ldb_channel *imx_ldb_ch,
@@ -112,16 +172,38 @@ static void imx_ldb_ch_set_bus_format(struct imx_ldb_channel *imx_ldb_ch,
break;
case MEDIA_BUS_FMT_RGB888_1X7X4_SPWG:
if (imx_ldb_ch->chno == 0 || dual)
- ldb->ldb_ctrl |= LDB_DATA_WIDTH_CH0_24;
+ ldb->ldb_ctrl |= LDB_DATA_WIDTH_CH0_24 |
+ LDB_CH0_DATA_WIDTH_24BIT;
if (imx_ldb_ch->chno == 1 || dual)
- ldb->ldb_ctrl |= LDB_DATA_WIDTH_CH1_24;
+ ldb->ldb_ctrl |= LDB_DATA_WIDTH_CH1_24 |
+ LDB_CH1_DATA_WIDTH_24BIT;
break;
case MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA:
if (imx_ldb_ch->chno == 0 || dual)
ldb->ldb_ctrl |= LDB_DATA_WIDTH_CH0_24 |
+ LDB_CH0_DATA_WIDTH_24BIT |
LDB_BIT_MAP_CH0_JEIDA;
if (imx_ldb_ch->chno == 1 || dual)
ldb->ldb_ctrl |= LDB_DATA_WIDTH_CH1_24 |
+ LDB_CH1_DATA_WIDTH_24BIT |
+ LDB_BIT_MAP_CH1_JEIDA;
+ break;
+ case MEDIA_BUS_FMT_RGB101010_1X7X5_SPWG:
+ if (imx_ldb_ch->chno == 0 || dual)
+ ldb->ldb_ctrl |= LDB_CH0_10BIT_EN |
+ LDB_CH0_DATA_WIDTH_30BIT;
+ if (imx_ldb_ch->chno == 1 || dual)
+ ldb->ldb_ctrl |= LDB_CH1_10BIT_EN |
+ LDB_CH1_DATA_WIDTH_30BIT;
+ break;
+ case MEDIA_BUS_FMT_RGB101010_1X7X5_JEIDA:
+ if (imx_ldb_ch->chno == 0 || dual)
+ ldb->ldb_ctrl |= LDB_CH0_10BIT_EN |
+ LDB_CH0_DATA_WIDTH_30BIT |
+ LDB_BIT_MAP_CH0_JEIDA;
+ if (imx_ldb_ch->chno == 1 || dual)
+ ldb->ldb_ctrl |= LDB_CH1_10BIT_EN |
+ LDB_CH1_DATA_WIDTH_30BIT |
LDB_BIT_MAP_CH1_JEIDA;
break;
}
@@ -174,8 +256,31 @@ static struct drm_encoder *imx_ldb_connector_best_encoder(
static void imx_ldb_set_clock(struct imx_ldb *ldb, int mux, int chno,
unsigned long serial_clk, unsigned long di_clk)
{
+ int dual = ldb->ldb_ctrl & LDB_SPLIT_MODE_EN;
int ret;
+ if (ldb->is_imx8) {
+ /*
+ * To workaround setting clock rate failure issue
+ * when the system resumes back from PM sleep mode,
+ * we need to get the clock rates before setting
+ * their rates, otherwise, setting the clock rates
+ * will fail.
+ */
+ clk_get_rate(ldb->clk_bypass);
+ clk_get_rate(ldb->clk_pixel);
+ clk_set_rate(ldb->clk_bypass, di_clk);
+ clk_set_rate(ldb->clk_pixel, di_clk);
+
+ if (dual && ldb->has_aux_ldb) {
+ clk_get_rate(ldb->clk_aux_bypass);
+ clk_get_rate(ldb->clk_aux_pixel);
+ clk_set_rate(ldb->clk_aux_bypass, di_clk);
+ clk_set_rate(ldb->clk_aux_pixel, di_clk);
+ }
+ return;
+ }
+
dev_dbg(ldb->dev, "%s: now: %ld want: %ld\n", __func__,
clk_get_rate(ldb->clk_pll[chno]), serial_clk);
clk_set_rate(ldb->clk_pll[chno], serial_clk);
@@ -199,6 +304,170 @@ static void imx_ldb_set_clock(struct imx_ldb *ldb, int mux, int chno,
chno);
}
+#ifndef CONFIG_HAVE_IMX8_SOC
+static void dpu_pixel_link_validate(int dpu_id, int stream_id) {}
+static void dpu_pixel_link_invalidate(int dpu_id, int stream_id) {}
+static void dpu_pixel_link_enable(int dpu_id, int stream_id) {}
+static void dpu_pixel_link_disable(int dpu_id, int stream_id) {}
+#else
+/* FIXME: validate pixel link in a proper manner */
+static void dpu_pixel_link_validate(int dpu_id, int stream_id)
+{
+ sc_err_t sciErr;
+ sc_ipc_t ipcHndl = 0;
+ u32 mu_id;
+
+ sciErr = sc_ipc_getMuID(&mu_id);
+ if (sciErr != SC_ERR_NONE) {
+ pr_err("Cannot obtain MU ID\n");
+ return;
+ }
+
+ sciErr = sc_ipc_open(&ipcHndl, mu_id);
+ if (sciErr != SC_ERR_NONE) {
+ pr_err("sc_ipc_open failed! (sciError = %d)\n", sciErr);
+ return;
+ }
+
+ if (dpu_id == 0) {
+ sciErr = sc_misc_set_control(ipcHndl, SC_R_DC_0,
+ stream_id ? SC_C_PXL_LINK_MST2_VLD : SC_C_PXL_LINK_MST1_VLD, 1);
+ if (sciErr != SC_ERR_NONE)
+ pr_err("SC_R_DC_0:SC_C_PXL_LINK_MST%d_VLD sc_misc_set_control failed! (sciError = %d)\n", stream_id + 1, sciErr);
+
+ sciErr = sc_misc_set_control(ipcHndl, SC_R_DC_0,
+ stream_id ? SC_C_SYNC_CTRL1 : SC_C_SYNC_CTRL0, 1);
+ if (sciErr != SC_ERR_NONE)
+ pr_err("SC_R_DC_0:SC_C_SYNC_CTRL%d sc_misc_set_control failed! (sciError = %d)\n", stream_id, sciErr);
+ } else if (dpu_id == 1) {
+ sciErr = sc_misc_set_control(ipcHndl, SC_R_DC_1,
+ stream_id ? SC_C_PXL_LINK_MST2_VLD : SC_C_PXL_LINK_MST1_VLD, 1);
+ if (sciErr != SC_ERR_NONE)
+ pr_err("SC_R_DC_1:SC_C_PXL_LINK_MST%d_VLD sc_misc_set_control failed! (sciError = %d)\n", stream_id + 1, sciErr);
+
+ sciErr = sc_misc_set_control(ipcHndl, SC_R_DC_1,
+ stream_id ? SC_C_SYNC_CTRL1 : SC_C_SYNC_CTRL0, 1);
+ if (sciErr != SC_ERR_NONE)
+ pr_err("SC_R_DC_1:SC_C_SYNC_CTRL%d sc_misc_set_control failed! (sciError = %d)\n", stream_id, sciErr);
+ }
+
+ sc_ipc_close(mu_id);
+}
+
+/* FIXME: invalidate pixel link in a proper manner */
+static void dpu_pixel_link_invalidate(int dpu_id, int stream_id)
+{
+ sc_err_t sciErr;
+ sc_ipc_t ipcHndl = 0;
+ u32 mu_id;
+
+ sciErr = sc_ipc_getMuID(&mu_id);
+ if (sciErr != SC_ERR_NONE) {
+ pr_err("Cannot obtain MU ID\n");
+ return;
+ }
+
+ sciErr = sc_ipc_open(&ipcHndl, mu_id);
+ if (sciErr != SC_ERR_NONE) {
+ pr_err("sc_ipc_open failed! (sciError = %d)\n", sciErr);
+ return;
+ }
+
+ if (dpu_id == 0) {
+ sciErr = sc_misc_set_control(ipcHndl, SC_R_DC_0,
+ stream_id ? SC_C_SYNC_CTRL1 : SC_C_SYNC_CTRL0, 0);
+ if (sciErr != SC_ERR_NONE)
+ pr_err("SC_R_DC_0:SC_C_SYNC_CTRL%d sc_misc_set_control failed! (sciError = %d)\n", stream_id, sciErr);
+
+ sciErr = sc_misc_set_control(ipcHndl, SC_R_DC_0,
+ stream_id ? SC_C_PXL_LINK_MST2_VLD : SC_C_PXL_LINK_MST1_VLD, 0);
+ if (sciErr != SC_ERR_NONE)
+ pr_err("SC_R_DC_0:SC_C_PXL_LINK_MST%d_VLD sc_misc_set_control failed! (sciError = %d)\n", stream_id + 1, sciErr);
+ } else if (dpu_id == 1) {
+ sciErr = sc_misc_set_control(ipcHndl, SC_R_DC_1,
+ stream_id ? SC_C_SYNC_CTRL1 : SC_C_SYNC_CTRL0, 0);
+ if (sciErr != SC_ERR_NONE)
+ pr_err("SC_R_DC_1:SC_C_SYNC_CTRL%d sc_misc_set_control failed! (sciError = %d)\n", stream_id, sciErr);
+
+ sciErr = sc_misc_set_control(ipcHndl, SC_R_DC_1,
+ stream_id ? SC_C_PXL_LINK_MST2_VLD : SC_C_PXL_LINK_MST1_VLD, 0);
+ if (sciErr != SC_ERR_NONE)
+ pr_err("SC_R_DC_1:SC_C_PXL_LINK_MST%d_VLD sc_misc_set_control failed! (sciError = %d)\n", stream_id + 1, sciErr);
+
+ }
+
+ sc_ipc_close(mu_id);
+}
+
+/* FIXME: enable pixel link in a proper manner */
+static void dpu_pixel_link_enable(int dpu_id, int stream_id)
+{
+ sc_err_t sciErr;
+ sc_ipc_t ipcHndl = 0;
+ u32 mu_id;
+
+ sciErr = sc_ipc_getMuID(&mu_id);
+ if (sciErr != SC_ERR_NONE) {
+ pr_err("Cannot obtain MU ID\n");
+ return;
+ }
+
+ sciErr = sc_ipc_open(&ipcHndl, mu_id);
+ if (sciErr != SC_ERR_NONE) {
+ pr_err("sc_ipc_open failed! (sciError = %d)\n", sciErr);
+ return;
+ }
+
+ if (dpu_id == 0) {
+ sciErr = sc_misc_set_control(ipcHndl, SC_R_DC_0,
+ stream_id ? SC_C_PXL_LINK_MST2_ENB : SC_C_PXL_LINK_MST1_ENB, 1);
+ if (sciErr != SC_ERR_NONE)
+ pr_err("SC_R_DC_0:SC_C_PXL_LINK_MST%d_ENB sc_misc_set_control failed! (sciError = %d)\n", stream_id + 1, sciErr);
+ } else if (dpu_id == 1) {
+ sciErr = sc_misc_set_control(ipcHndl, SC_R_DC_1,
+ stream_id ? SC_C_PXL_LINK_MST2_ENB : SC_C_PXL_LINK_MST1_ENB, 1);
+ if (sciErr != SC_ERR_NONE)
+ pr_err("SC_R_DC_1:SC_C_PXL_LINK_MST%d_ENB sc_misc_set_control failed! (sciError = %d)\n", stream_id + 1, sciErr);
+ }
+
+ sc_ipc_close(mu_id);
+}
+
+/* FIXME: disable pixel link in a proper manner */
+static void dpu_pixel_link_disable(int dpu_id, int stream_id)
+{
+ sc_err_t sciErr;
+ sc_ipc_t ipcHndl = 0;
+ u32 mu_id;
+
+ sciErr = sc_ipc_getMuID(&mu_id);
+ if (sciErr != SC_ERR_NONE) {
+ pr_err("Cannot obtain MU ID\n");
+ return;
+ }
+
+ sciErr = sc_ipc_open(&ipcHndl, mu_id);
+ if (sciErr != SC_ERR_NONE) {
+ pr_err("sc_ipc_open failed! (sciError = %d)\n", sciErr);
+ return;
+ }
+
+ if (dpu_id == 0) {
+ sciErr = sc_misc_set_control(ipcHndl, SC_R_DC_0,
+ stream_id ? SC_C_PXL_LINK_MST2_ENB : SC_C_PXL_LINK_MST1_ENB, 0);
+ if (sciErr != SC_ERR_NONE)
+ pr_err("SC_R_DC_0:SC_C_PXL_LINK_MST%d_ENB sc_misc_set_control failed! (sciError = %d)\n", stream_id + 1, sciErr);
+ } else if (dpu_id == 1) {
+ sciErr = sc_misc_set_control(ipcHndl, SC_R_DC_1,
+ stream_id ? SC_C_PXL_LINK_MST2_ENB : SC_C_PXL_LINK_MST1_ENB, 0);
+ if (sciErr != SC_ERR_NONE)
+ pr_err("SC_R_DC_1:SC_C_PXL_LINK_MST%d_ENB sc_misc_set_control failed! (sciError = %d)\n", stream_id + 1, sciErr);
+ }
+
+ sc_ipc_close(mu_id);
+}
+#endif
+
static void imx_ldb_encoder_enable(struct drm_encoder *encoder)
{
struct imx_ldb_channel *imx_ldb_ch = enc_to_imx_ldb_ch(encoder);
@@ -208,29 +477,59 @@ static void imx_ldb_encoder_enable(struct drm_encoder *encoder)
drm_panel_prepare(imx_ldb_ch->panel);
- if (dual) {
- clk_set_parent(ldb->clk_sel[mux], ldb->clk[0]);
- clk_set_parent(ldb->clk_sel[mux], ldb->clk[1]);
+ if (ldb->is_imx8) {
+ clk_prepare_enable(ldb->clk_pixel);
+ clk_prepare_enable(ldb->clk_bypass);
- clk_prepare_enable(ldb->clk[0]);
- clk_prepare_enable(ldb->clk[1]);
- } else {
- clk_set_parent(ldb->clk_sel[mux], ldb->clk[imx_ldb_ch->chno]);
+ if (dual && ldb->has_aux_ldb) {
+ clk_prepare_enable(ldb->clk_aux_pixel);
+ clk_prepare_enable(ldb->clk_aux_bypass);
+ }
}
+ if (ldb->has_mux) {
+ if (dual) {
+ clk_set_parent(ldb->clk_sel[mux], ldb->clk[0]);
+ clk_set_parent(ldb->clk_sel[mux], ldb->clk[1]);
+
+ clk_prepare_enable(ldb->clk[0]);
+ clk_prepare_enable(ldb->clk[1]);
+ } else {
+ clk_set_parent(ldb->clk_sel[mux],
+ ldb->clk[imx_ldb_ch->chno]);
+ }
+ }
+
+ /*
+ * LDB frontend doesn't know if the auxiliary LDB is used or not.
+ * Enable pixel link after dual or single LDB clocks are enabled
+ * so that the dual LDBs are synchronized.
+ */
+ if (ldb->has_aux_ldb && ldb->pixel_link_enable_quirks)
+ dpu_pixel_link_enable(0, ldb->id);
+
if (imx_ldb_ch == &ldb->channel[0] || dual) {
ldb->ldb_ctrl &= ~LDB_CH0_MODE_EN_MASK;
- if (mux == 0 || ldb->lvds_mux)
+ if (ldb->has_mux) {
+ if (mux == 0 || ldb->lvds_mux)
+ ldb->ldb_ctrl |= LDB_CH0_MODE_EN_TO_DI0;
+ else if (mux == 1)
+ ldb->ldb_ctrl |= LDB_CH0_MODE_EN_TO_DI1;
+ } else {
ldb->ldb_ctrl |= LDB_CH0_MODE_EN_TO_DI0;
- else if (mux == 1)
- ldb->ldb_ctrl |= LDB_CH0_MODE_EN_TO_DI1;
+ }
}
if (imx_ldb_ch == &ldb->channel[1] || dual) {
ldb->ldb_ctrl &= ~LDB_CH1_MODE_EN_MASK;
- if (mux == 1 || ldb->lvds_mux)
- ldb->ldb_ctrl |= LDB_CH1_MODE_EN_TO_DI1;
- else if (mux == 0)
- ldb->ldb_ctrl |= LDB_CH1_MODE_EN_TO_DI0;
+ if (ldb->has_mux) {
+ if (mux == 1 || ldb->lvds_mux)
+ ldb->ldb_ctrl |= LDB_CH1_MODE_EN_TO_DI1;
+ else if (mux == 0)
+ ldb->ldb_ctrl |= LDB_CH1_MODE_EN_TO_DI0;
+ } else {
+ ldb->ldb_ctrl |= dual ?
+ LDB_CH1_MODE_EN_TO_DI0 : LDB_CH1_MODE_EN_TO_DI1;
+ }
}
if (ldb->lvds_mux) {
@@ -245,7 +544,33 @@ static void imx_ldb_encoder_enable(struct drm_encoder *encoder)
mux << lvds_mux->shift);
}
- regmap_write(ldb->regmap, IOMUXC_GPR2, ldb->ldb_ctrl);
+ regmap_write(ldb->regmap, ldb->ldb_ctrl_reg, ldb->ldb_ctrl);
+ if (dual && ldb->has_aux_ldb)
+ regmap_write(ldb->aux_regmap, ldb->ldb_ctrl_reg,
+ ldb->ldb_ctrl | LDB_CH_SEL);
+
+ if (dual) {
+ phy_power_on(ldb->channel[0].phy);
+ if (ldb->has_aux_ldb)
+ phy_power_on(ldb->channel[0].aux_phy);
+ else
+ phy_power_on(ldb->channel[1].phy);
+
+ ldb->channel[0].phy_is_on = true;
+ if (!ldb->has_aux_ldb)
+ ldb->channel[1].phy_is_on = true;
+ } else {
+ phy_power_on(imx_ldb_ch->phy);
+
+ imx_ldb_ch->phy_is_on = true;
+ }
+
+ if (ldb->pixel_link_valid_quirks) {
+ if (ldb->use_mixel_phy)
+ dpu_pixel_link_validate(ldb->id, 1);
+ else if (ldb->use_mixel_combo_phy)
+ dpu_pixel_link_validate(0, ldb->id);
+ }
drm_panel_enable(imx_ldb_ch->panel);
}
@@ -264,39 +589,163 @@ imx_ldb_encoder_atomic_mode_set(struct drm_encoder *encoder,
int mux = drm_of_encoder_active_port_id(imx_ldb_ch->child, encoder);
u32 bus_format = imx_ldb_ch->bus_format;
- if (mode->clock > 170000) {
+ if (mode->clock > ldb->max_prate_dual_mode) {
dev_warn(ldb->dev,
- "%s: mode exceeds 170 MHz pixel clock\n", __func__);
+ "%s: mode exceeds %u MHz pixel clock\n", __func__,
+ ldb->max_prate_dual_mode / 1000);
}
- if (mode->clock > 85000 && !dual) {
+ if (mode->clock > ldb->max_prate_single_mode && !dual) {
dev_warn(ldb->dev,
- "%s: mode exceeds 85 MHz pixel clock\n", __func__);
+ "%s: mode exceeds %u MHz pixel clock\n", __func__,
+ ldb->max_prate_single_mode / 1000);
}
if (dual) {
serial_clk = 3500UL * mode->clock;
imx_ldb_set_clock(ldb, mux, 0, serial_clk, di_clk);
imx_ldb_set_clock(ldb, mux, 1, serial_clk, di_clk);
+
+ if (ldb->use_mixel_phy) {
+ mixel_phy_lvds_set_phy_speed(ldb->channel[0].phy,
+ di_clk / 2);
+ mixel_phy_lvds_set_phy_speed(ldb->channel[1].phy,
+ di_clk / 2);
+ } else if (ldb->use_mixel_combo_phy) {
+ mixel_phy_combo_lvds_set_phy_speed(ldb->channel[0].phy,
+ di_clk / 2);
+ mixel_phy_combo_lvds_set_phy_speed(ldb->channel[0].aux_phy,
+ di_clk / 2);
+ }
} else {
serial_clk = 7000UL * mode->clock;
imx_ldb_set_clock(ldb, mux, imx_ldb_ch->chno, serial_clk,
di_clk);
+
+ if (ldb->use_mixel_phy)
+ mixel_phy_lvds_set_phy_speed(imx_ldb_ch->phy, di_clk);
+ else if (ldb->use_mixel_combo_phy)
+ mixel_phy_combo_lvds_set_phy_speed(imx_ldb_ch->phy,
+ di_clk);
+ }
+
+ if (ldb->has_ch_sel) {
+ if (imx_ldb_ch == &ldb->channel[0])
+ ldb->ldb_ctrl &= ~LDB_CH_SEL;
+ if (imx_ldb_ch == &ldb->channel[1])
+ ldb->ldb_ctrl |= LDB_CH_SEL;
}
/* FIXME - assumes straight connections DI0 --> CH0, DI1 --> CH1 */
if (imx_ldb_ch == &ldb->channel[0] || dual) {
if (mode->flags & DRM_MODE_FLAG_NVSYNC)
ldb->ldb_ctrl |= LDB_DI0_VS_POL_ACT_LOW;
- else if (mode->flags & DRM_MODE_FLAG_PVSYNC)
+ else
ldb->ldb_ctrl &= ~LDB_DI0_VS_POL_ACT_LOW;
}
if (imx_ldb_ch == &ldb->channel[1] || dual) {
if (mode->flags & DRM_MODE_FLAG_NVSYNC)
ldb->ldb_ctrl |= LDB_DI1_VS_POL_ACT_LOW;
- else if (mode->flags & DRM_MODE_FLAG_PVSYNC)
+ else
ldb->ldb_ctrl &= ~LDB_DI1_VS_POL_ACT_LOW;
}
+ /* settle vsync polarity and channel selection down early */
+ if (dual && ldb->has_aux_ldb) {
+ regmap_write(ldb->regmap, ldb->ldb_ctrl_reg, ldb->ldb_ctrl);
+ regmap_write(ldb->aux_regmap, ldb->ldb_ctrl_reg,
+ ldb->ldb_ctrl | LDB_CH_SEL);
+ }
+
+ if (dual) {
+ if (ldb->use_mixel_phy) {
+ /* VSYNC */
+ if (mode->flags & DRM_MODE_FLAG_NVSYNC) {
+ mixel_phy_lvds_set_vsync_pol(
+ ldb->channel[0].phy, false);
+ mixel_phy_lvds_set_vsync_pol(
+ ldb->channel[1].phy, false);
+ } else {
+ mixel_phy_lvds_set_vsync_pol(
+ ldb->channel[0].phy, true);
+ mixel_phy_lvds_set_vsync_pol(
+ ldb->channel[1].phy, true);
+ }
+ /* HSYNC */
+ if (mode->flags & DRM_MODE_FLAG_NHSYNC) {
+ mixel_phy_lvds_set_hsync_pol(
+ ldb->channel[0].phy, false);
+ mixel_phy_lvds_set_hsync_pol(
+ ldb->channel[1].phy, false);
+ } else {
+ mixel_phy_lvds_set_hsync_pol(
+ ldb->channel[0].phy, true);
+ mixel_phy_lvds_set_hsync_pol(
+ ldb->channel[1].phy, true);
+ }
+ } else if (ldb->use_mixel_combo_phy) {
+ /* VSYNC */
+ if (mode->flags & DRM_MODE_FLAG_NVSYNC) {
+ mixel_phy_combo_lvds_set_vsync_pol(
+ ldb->channel[0].phy, false);
+ mixel_phy_combo_lvds_set_vsync_pol(
+ ldb->channel[0].aux_phy, false);
+ } else {
+ mixel_phy_combo_lvds_set_vsync_pol(
+ ldb->channel[0].phy, true);
+ mixel_phy_combo_lvds_set_vsync_pol(
+ ldb->channel[0].aux_phy, true);
+ }
+ /* HSYNC */
+ if (mode->flags & DRM_MODE_FLAG_NHSYNC) {
+ mixel_phy_combo_lvds_set_hsync_pol(
+ ldb->channel[0].phy, false);
+ mixel_phy_combo_lvds_set_hsync_pol(
+ ldb->channel[0].aux_phy, false);
+ } else {
+ mixel_phy_combo_lvds_set_hsync_pol(
+ ldb->channel[0].phy, true);
+ mixel_phy_combo_lvds_set_hsync_pol(
+ ldb->channel[0].aux_phy, true);
+ }
+ }
+ } else {
+ if (ldb->use_mixel_phy) {
+ /* VSYNC */
+ if (mode->flags & DRM_MODE_FLAG_NVSYNC)
+ mixel_phy_lvds_set_vsync_pol(imx_ldb_ch->phy,
+ false);
+ else
+ mixel_phy_lvds_set_vsync_pol(imx_ldb_ch->phy,
+ true);
+ /* HSYNC */
+ if (mode->flags & DRM_MODE_FLAG_NHSYNC)
+ mixel_phy_lvds_set_hsync_pol(imx_ldb_ch->phy,
+ false);
+ else
+ mixel_phy_lvds_set_hsync_pol(imx_ldb_ch->phy,
+ true);
+ } else if (ldb->use_mixel_combo_phy) {
+ /* VSYNC */
+ if (mode->flags & DRM_MODE_FLAG_NVSYNC)
+ mixel_phy_combo_lvds_set_vsync_pol(
+ imx_ldb_ch->phy,
+ false);
+ else
+ mixel_phy_combo_lvds_set_vsync_pol(
+ imx_ldb_ch->phy,
+ true);
+ /* HSYNC */
+ if (mode->flags & DRM_MODE_FLAG_NHSYNC)
+ mixel_phy_combo_lvds_set_hsync_pol(
+ imx_ldb_ch->phy,
+ false);
+ else
+ mixel_phy_combo_lvds_set_hsync_pol(
+ imx_ldb_ch->phy,
+ true);
+ }
+ }
+
if (!bus_format) {
struct drm_connector *connector = connector_state->connector;
struct drm_display_info *di = &connector->display_info;
@@ -311,22 +760,64 @@ static void imx_ldb_encoder_disable(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;
+ int dual = ldb->ldb_ctrl & LDB_SPLIT_MODE_EN;
int mux, ret;
drm_panel_disable(imx_ldb_ch->panel);
+ if (ldb->pixel_link_valid_quirks) {
+ if (ldb->use_mixel_phy)
+ dpu_pixel_link_invalidate(ldb->id, 1);
+ else if (ldb->use_mixel_combo_phy)
+ dpu_pixel_link_invalidate(0, ldb->id);
+ }
+
+ if (dual) {
+ phy_power_off(ldb->channel[0].phy);
+ if (ldb->has_aux_ldb)
+ phy_power_off(ldb->channel[0].aux_phy);
+ else
+ phy_power_off(ldb->channel[1].phy);
+
+ ldb->channel[0].phy_is_on = false;
+ if (!ldb->has_aux_ldb)
+ ldb->channel[1].phy_is_on = false;
+ } else {
+ phy_power_off(imx_ldb_ch->phy);
+
+ imx_ldb_ch->phy_is_on = false;
+ }
+
if (imx_ldb_ch == &ldb->channel[0])
ldb->ldb_ctrl &= ~LDB_CH0_MODE_EN_MASK;
else if (imx_ldb_ch == &ldb->channel[1])
ldb->ldb_ctrl &= ~LDB_CH1_MODE_EN_MASK;
- regmap_write(ldb->regmap, IOMUXC_GPR2, ldb->ldb_ctrl);
+ regmap_write(ldb->regmap, ldb->ldb_ctrl_reg, ldb->ldb_ctrl);
+ if (dual && ldb->has_aux_ldb)
+ regmap_write(ldb->aux_regmap, ldb->ldb_ctrl_reg, ldb->ldb_ctrl);
- if (ldb->ldb_ctrl & LDB_SPLIT_MODE_EN) {
- clk_disable_unprepare(ldb->clk[0]);
- clk_disable_unprepare(ldb->clk[1]);
+ if (ldb->is_imx8) {
+ clk_disable_unprepare(ldb->clk_bypass);
+ clk_disable_unprepare(ldb->clk_pixel);
+
+ if (dual && ldb->has_aux_ldb) {
+ clk_disable_unprepare(ldb->clk_aux_bypass);
+ clk_disable_unprepare(ldb->clk_aux_pixel);
+ }
+ } else {
+ if (ldb->ldb_ctrl & LDB_SPLIT_MODE_EN) {
+ clk_disable_unprepare(ldb->clk[0]);
+ clk_disable_unprepare(ldb->clk[1]);
+ }
}
+ if (ldb->has_aux_ldb && ldb->pixel_link_enable_quirks)
+ dpu_pixel_link_disable(0, ldb->id);
+
+ if (!ldb->has_mux)
+ goto unprepare_panel;
+
if (ldb->lvds_mux) {
const struct bus_mux *lvds_mux = NULL;
@@ -349,6 +840,7 @@ static void imx_ldb_encoder_disable(struct drm_encoder *encoder)
"unable to set di%d parent clock to original parent\n",
mux);
+unprepare_panel:
drm_panel_unprepare(imx_ldb_ch->panel);
}
@@ -358,6 +850,7 @@ static int imx_ldb_encoder_atomic_check(struct drm_encoder *encoder,
{
struct imx_crtc_state *imx_crtc_state = to_imx_crtc_state(crtc_state);
struct imx_ldb_channel *imx_ldb_ch = enc_to_imx_ldb_ch(encoder);
+ struct imx_ldb *ldb = imx_ldb_ch->ldb;
struct drm_display_info *di = &conn_state->connector->display_info;
u32 bus_format = imx_ldb_ch->bus_format;
@@ -371,11 +864,23 @@ static int imx_ldb_encoder_atomic_check(struct drm_encoder *encoder,
}
switch (bus_format) {
case MEDIA_BUS_FMT_RGB666_1X7X3_SPWG:
- imx_crtc_state->bus_format = MEDIA_BUS_FMT_RGB666_1X18;
+ if (ldb->padding_quirks)
+ imx_crtc_state->bus_format =
+ MEDIA_BUS_FMT_RGB666_1X30_PADLO;
+ else
+ imx_crtc_state->bus_format = MEDIA_BUS_FMT_RGB666_1X18;
break;
case MEDIA_BUS_FMT_RGB888_1X7X4_SPWG:
case MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA:
- imx_crtc_state->bus_format = MEDIA_BUS_FMT_RGB888_1X24;
+ if (ldb->padding_quirks)
+ imx_crtc_state->bus_format =
+ MEDIA_BUS_FMT_RGB888_1X30_PADLO;
+ else
+ imx_crtc_state->bus_format = MEDIA_BUS_FMT_RGB888_1X24;
+ break;
+ case MEDIA_BUS_FMT_RGB101010_1X7X5_SPWG:
+ case MEDIA_BUS_FMT_RGB101010_1X7X5_JEIDA:
+ imx_crtc_state->bus_format = MEDIA_BUS_FMT_RGB101010_1X30;
break;
default:
return -EINVAL;
@@ -416,6 +921,9 @@ static int imx_ldb_get_clk(struct imx_ldb *ldb, int chno)
{
char clkname[16];
+ if (ldb->is_imx8)
+ return 0;
+
snprintf(clkname, sizeof(clkname), "di%d", chno);
ldb->clk[chno] = devm_clk_get(ldb->dev, clkname);
if (IS_ERR(ldb->clk[chno]))
@@ -497,12 +1005,15 @@ struct imx_ldb_bit_mapping {
};
static const struct imx_ldb_bit_mapping imx_ldb_bit_mappings[] = {
- { MEDIA_BUS_FMT_RGB666_1X7X3_SPWG, 18, "spwg" },
- { MEDIA_BUS_FMT_RGB888_1X7X4_SPWG, 24, "spwg" },
- { MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA, 24, "jeida" },
+ { MEDIA_BUS_FMT_RGB666_1X7X3_SPWG, 18, "spwg" },
+ { MEDIA_BUS_FMT_RGB888_1X7X4_SPWG, 24, "spwg" },
+ { MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA, 24, "jeida" },
+ { MEDIA_BUS_FMT_RGB101010_1X7X5_SPWG, 30, "spwg" },
+ { MEDIA_BUS_FMT_RGB101010_1X7X5_JEIDA, 30, "jeida" },
};
-static u32 of_get_bus_format(struct device *dev, struct device_node *np)
+static u32 of_get_bus_format(struct device *dev, struct imx_ldb *ldb,
+ struct device_node *np)
{
const char *bm;
u32 datawidth = 0;
@@ -514,6 +1025,11 @@ static u32 of_get_bus_format(struct device *dev, struct device_node *np)
of_property_read_u32(np, "fsl,data-width", &datawidth);
+ if (!ldb->capable_10bit && datawidth == 30) {
+ dev_err(dev, "invalid data width: %d-bit\n", datawidth);
+ return -ENOENT;
+ }
+
for (i = 0; i < ARRAY_SIZE(imx_ldb_bit_mappings); i++) {
if (!strcasecmp(bm, imx_ldb_bit_mappings[i].mapping) &&
datawidth == imx_ldb_bit_mappings[i].datawidth)
@@ -525,6 +1041,16 @@ static u32 of_get_bus_format(struct device *dev, struct device_node *np)
return -ENOENT;
}
+static struct devtype imx53_ldb_devtype = {
+ .ctrl_reg = IOMUXC_GPR2,
+ .bus_mux = NULL,
+ .capable_10bit = false,
+ .visible_phy = false,
+ .has_mux = true,
+ .max_prate_single_mode = 85000,
+ .max_prate_dual_mode = 150000,
+};
+
static struct bus_mux imx6q_lvds_mux[2] = {
{
.reg = IOMUXC_GPR3,
@@ -537,15 +1063,57 @@ static struct bus_mux imx6q_lvds_mux[2] = {
}
};
+static struct devtype imx6q_ldb_devtype = {
+ .ctrl_reg = IOMUXC_GPR2,
+ .bus_mux = imx6q_lvds_mux,
+ .capable_10bit = false,
+ .visible_phy = false,
+ .has_mux = true,
+ .max_prate_single_mode = 85000,
+ .max_prate_dual_mode = 170000,
+};
+
+static struct devtype imx8qm_ldb_devtype = {
+ .ctrl_reg = 0x10e0,
+ .bus_mux = NULL,
+ .capable_10bit = true,
+ .visible_phy = true,
+ .is_imx8 = true,
+ .use_mixel_phy = true,
+ .padding_quirks = true,
+ .pixel_link_valid_quirks = true,
+ .max_prate_single_mode = 150000,
+ .max_prate_dual_mode = 300000,
+};
+
+static struct devtype imx8qxp_ldb_devtype = {
+ .ctrl_reg = 0x10e0,
+ .bus_mux = NULL,
+ .visible_phy = true,
+ .has_ch_sel = true,
+ .has_aux_ldb = true,
+ .is_imx8 = true,
+ .use_mixel_combo_phy = true,
+ .padding_quirks = true,
+ .pixel_link_init_quirks = true,
+ .pixel_link_valid_quirks = true,
+ .pixel_link_enable_quirks = true,
+ .max_prate_single_mode = 150000,
+ .max_prate_dual_mode = 300000,
+};
+
/*
- * For a device declaring compatible = "fsl,imx6q-ldb", "fsl,imx53-ldb",
- * of_match_device will walk through this list and take the first entry
- * matching any of its compatible values. Therefore, the more generic
- * entries (in this case fsl,imx53-ldb) need to be ordered last.
+ * For a device declaring compatible = "fsl,imx8qxp-ldb", "fsl,imx8qm-ldb",
+ * "fsl,imx6q-ldb", "fsl,imx53-ldb", of_match_device will walk through this
+ * list and take the first entry matching any of its compatible values.
+ * Therefore, the more generic entries (in this case fsl,imx53-ldb) need to be
+ * ordered last.
*/
static const struct of_device_id imx_ldb_dt_ids[] = {
- { .compatible = "fsl,imx6q-ldb", .data = imx6q_lvds_mux, },
- { .compatible = "fsl,imx53-ldb", .data = NULL, },
+ { .compatible = "fsl,imx8qxp-ldb", .data = &imx8qxp_ldb_devtype, },
+ { .compatible = "fsl,imx8qm-ldb", .data = &imx8qm_ldb_devtype, },
+ { .compatible = "fsl,imx6q-ldb", .data = &imx6q_ldb_devtype, },
+ { .compatible = "fsl,imx53-ldb", .data = &imx53_ldb_devtype, },
{ }
};
MODULE_DEVICE_TABLE(of, imx_ldb_dt_ids);
@@ -590,12 +1158,74 @@ static int imx_ldb_panel_ddc(struct device *dev,
return 0;
}
+#ifndef CONFIG_HAVE_IMX8_SOC
+static void ldb_pixel_link_init(int id, bool dual) {}
+#else
+static void ldb_pixel_link_init(int id, bool dual)
+{
+ sc_err_t sciErr;
+ sc_ipc_t ipcHndl = 0;
+ u32 mu_id;
+ bool is_aux = false;
+
+ sciErr = sc_ipc_getMuID(&mu_id);
+ if (sciErr != SC_ERR_NONE) {
+ pr_err("Cannot obtain MU ID\n");
+ return;
+ }
+
+ sciErr = sc_ipc_open(&ipcHndl, mu_id);
+ if (sciErr != SC_ERR_NONE) {
+ pr_err("sc_ipc_open failed! (sciError = %d)\n", sciErr);
+ return;
+ }
+
+again:
+ if (id == 0) {
+ sciErr = sc_misc_set_control(ipcHndl, SC_R_MIPI_0,
+ SC_C_MODE, 1);
+ if (sciErr != SC_ERR_NONE)
+ pr_err("SC_R_MIPI_%d MODE failed %d!\n", id, sciErr);
+ sciErr = sc_misc_set_control(ipcHndl, SC_R_MIPI_0,
+ SC_C_DUAL_MODE, is_aux);
+ if (sciErr != SC_ERR_NONE)
+ pr_err("SC_R_MIPI_%d DUAL_MODE failed %d!\n", id, sciErr);
+ sciErr = sc_misc_set_control(ipcHndl, SC_R_MIPI_0,
+ SC_C_PXL_LINK_SEL, is_aux);
+ if (sciErr != SC_ERR_NONE)
+ pr_err("SC_R_MIPI_%d PXL_LINK_SEL failed %d!\n", id, sciErr);
+ } else {
+ sciErr = sc_misc_set_control(ipcHndl, SC_R_MIPI_1,
+ SC_C_MODE, 1);
+ if (sciErr != SC_ERR_NONE)
+ pr_err("SC_R_MIPI_%d MODE failed %d!\n", id, sciErr);
+ sciErr = sc_misc_set_control(ipcHndl, SC_R_MIPI_1,
+ SC_C_DUAL_MODE, is_aux);
+ if (sciErr != SC_ERR_NONE)
+ pr_err("SC_R_MIPI_%d DUAL_MODE failed %d!\n", id, sciErr);
+ sciErr = sc_misc_set_control(ipcHndl, SC_R_MIPI_1,
+ SC_C_PXL_LINK_SEL, is_aux);
+ if (sciErr != SC_ERR_NONE)
+ pr_err("SC_R_MIPI_%d PXL_LINK_SEL failed %d!\n", id, sciErr);
+ }
+
+ if (dual && !is_aux) {
+ id ^= 1;
+ is_aux = true;
+ goto again;
+ }
+
+ sc_ipc_close(mu_id);
+}
+#endif
+
static int imx_ldb_bind(struct device *dev, struct device *master, void *data)
{
struct drm_device *drm = data;
struct device_node *np = dev->of_node;
const struct of_device_id *of_id =
of_match_device(imx_ldb_dt_ids, dev);
+ const struct devtype *devtype = of_id->data;
struct device_node *child;
struct imx_ldb *imx_ldb;
int dual;
@@ -612,44 +1242,92 @@ static int imx_ldb_bind(struct device *dev, struct device *master, void *data)
return PTR_ERR(imx_ldb->regmap);
}
- /* disable LDB by resetting the control register to POR default */
- regmap_write(imx_ldb->regmap, IOMUXC_GPR2, 0);
-
imx_ldb->dev = dev;
-
- if (of_id)
- imx_ldb->lvds_mux = of_id->data;
+ imx_ldb->ldb_ctrl_reg = devtype->ctrl_reg;
+ imx_ldb->lvds_mux = devtype->bus_mux;
+ imx_ldb->capable_10bit = devtype->capable_10bit;
+ imx_ldb->visible_phy = devtype->visible_phy;
+ imx_ldb->has_mux = devtype->has_mux;
+ imx_ldb->has_ch_sel = devtype->has_ch_sel;
+ imx_ldb->has_aux_ldb = devtype->has_aux_ldb;
+ imx_ldb->is_imx8 = devtype->is_imx8;
+ imx_ldb->use_mixel_phy = devtype->use_mixel_phy;
+ imx_ldb->use_mixel_combo_phy = devtype->use_mixel_combo_phy;
+ imx_ldb->padding_quirks = devtype->padding_quirks;
+ imx_ldb->pixel_link_init_quirks = devtype->pixel_link_init_quirks;
+ imx_ldb->pixel_link_valid_quirks = devtype->pixel_link_valid_quirks;
+ imx_ldb->pixel_link_enable_quirks = devtype->pixel_link_enable_quirks;
+ imx_ldb->max_prate_single_mode = devtype->max_prate_single_mode;
+ imx_ldb->max_prate_dual_mode = devtype->max_prate_dual_mode;
dual = of_property_read_bool(np, "fsl,dual-channel");
if (dual)
imx_ldb->ldb_ctrl |= LDB_SPLIT_MODE_EN;
- /*
- * There are three different possible clock mux configurations:
- * i.MX53: ipu1_di0_sel, ipu1_di1_sel
- * i.MX6q: ipu1_di0_sel, ipu1_di1_sel, ipu2_di0_sel, ipu2_di1_sel
- * i.MX6dl: ipu1_di0_sel, ipu1_di1_sel, lcdif_sel
- * Map them all to di0_sel...di3_sel.
- */
- for (i = 0; i < 4; i++) {
- char clkname[16];
-
- sprintf(clkname, "di%d_sel", i);
- imx_ldb->clk_sel[i] = devm_clk_get(imx_ldb->dev, clkname);
- if (IS_ERR(imx_ldb->clk_sel[i])) {
- ret = PTR_ERR(imx_ldb->clk_sel[i]);
- imx_ldb->clk_sel[i] = NULL;
- break;
+ if (dual && imx_ldb->has_aux_ldb) {
+ imx_ldb->aux_regmap =
+ syscon_regmap_lookup_by_phandle(np, "aux-gpr");
+ if (IS_ERR(imx_ldb->aux_regmap)) {
+ dev_err(dev, "failed to get parent auxiliary regmap\n");
+ return PTR_ERR(imx_ldb->aux_regmap);
}
+ }
- imx_ldb->clk_parent[i] = clk_get_parent(imx_ldb->clk_sel[i]);
+ if (imx_ldb->is_imx8) {
+ imx_ldb->clk_pixel = devm_clk_get(imx_ldb->dev, "pixel");
+ if (IS_ERR(imx_ldb->clk_pixel))
+ return PTR_ERR(imx_ldb->clk_pixel);
+
+ imx_ldb->clk_bypass = devm_clk_get(imx_ldb->dev, "bypass");
+ if (IS_ERR(imx_ldb->clk_bypass))
+ return PTR_ERR(imx_ldb->clk_bypass);
+
+ if (dual && imx_ldb->has_aux_ldb) {
+ imx_ldb->clk_aux_pixel =
+ devm_clk_get(imx_ldb->dev, "aux_pixel");
+ if (IS_ERR(imx_ldb->clk_aux_pixel))
+ return PTR_ERR(imx_ldb->clk_aux_pixel);
+
+ imx_ldb->clk_aux_bypass =
+ devm_clk_get(imx_ldb->dev, "aux_bypass");
+ if (IS_ERR(imx_ldb->clk_aux_bypass))
+ return PTR_ERR(imx_ldb->clk_aux_bypass);
+ }
+ }
+
+ if (imx_ldb->has_mux) {
+ /*
+ * There are three different possible clock mux configurations:
+ * i.MX53: ipu1_di0_sel, ipu1_di1_sel
+ * i.MX6q: ipu1_di0_sel, ipu1_di1_sel, ipu2_di0_sel,
+ * ipu2_di1_sel
+ * i.MX6dl: ipu1_di0_sel, ipu1_di1_sel, lcdif_sel
+ * Map them all to di0_sel...di3_sel.
+ */
+ for (i = 0; i < 4; i++) {
+ char clkname[16];
+
+ sprintf(clkname, "di%d_sel", i);
+ imx_ldb->clk_sel[i] = devm_clk_get(imx_ldb->dev,
+ clkname);
+ if (IS_ERR(imx_ldb->clk_sel[i])) {
+ ret = PTR_ERR(imx_ldb->clk_sel[i]);
+ imx_ldb->clk_sel[i] = NULL;
+ break;
+ }
+
+ imx_ldb->clk_parent[i] =
+ clk_get_parent(imx_ldb->clk_sel[i]);
+ }
+ if (i == 0)
+ return ret;
}
- if (i == 0)
- return ret;
for_each_child_of_node(np, child) {
struct imx_ldb_channel *channel;
int bus_format;
+ int port_reg;
+ bool auxiliary_ch = false;
ret = of_property_read_u32(child, "reg", &i);
if (ret || i < 0 || i > 1) {
@@ -657,6 +1335,12 @@ static int imx_ldb_bind(struct device *dev, struct device *master, void *data)
goto free_child;
}
+ if (dual && imx_ldb->use_mixel_phy && i > 0) {
+ auxiliary_ch = true;
+ channel = &imx_ldb->channel[i];
+ goto get_phy;
+ }
+
if (!of_device_is_available(child))
continue;
@@ -671,10 +1355,15 @@ static int imx_ldb_bind(struct device *dev, struct device *master, void *data)
/*
* The output port is port@4 with an external 4-port mux or
- * port@2 with the internal 2-port mux.
+ * port@2 with the internal 2-port mux or port@1 without mux.
*/
+ if (imx_ldb->has_mux)
+ port_reg = imx_ldb->lvds_mux ? 4 : 2;
+ else
+ port_reg = 1;
+
ret = drm_of_find_panel_or_bridge(child,
- imx_ldb->lvds_mux ? 4 : 2, 0,
+ port_reg, 0,
&channel->panel, &channel->bridge);
if (ret && ret != -ENODEV)
goto free_child;
@@ -686,7 +1375,7 @@ static int imx_ldb_bind(struct device *dev, struct device *master, void *data)
goto free_child;
}
- bus_format = of_get_bus_format(dev, child);
+ bus_format = of_get_bus_format(dev, imx_ldb, child);
if (bus_format == -EINVAL) {
/*
* If no bus format was specified in the device tree,
@@ -705,6 +1394,57 @@ static int imx_ldb_bind(struct device *dev, struct device *master, void *data)
channel->bus_format = bus_format;
channel->child = child;
+get_phy:
+ if (imx_ldb->visible_phy) {
+ channel->phy = devm_of_phy_get(dev, child, "ldb_phy");
+ if (IS_ERR(channel->phy)) {
+ ret = PTR_ERR(channel->phy);
+ if (ret == -EPROBE_DEFER) {
+ return ret;
+ } else {
+ dev_err(dev,
+ "can't get channel%d phy: %d\n",
+ channel->chno, ret);
+ return ret;
+ }
+ }
+
+ ret = phy_init(channel->phy);
+ if (ret < 0) {
+ dev_err(dev,
+ "failed to initialize channel%d phy: %d\n",
+ channel->chno, ret);
+ return ret;
+ }
+
+ if (dual && imx_ldb->has_aux_ldb) {
+ channel->aux_phy =
+ devm_of_phy_get(dev, child, "aux_ldb_phy");
+ if (IS_ERR(channel->aux_phy)) {
+ ret = PTR_ERR(channel->aux_phy);
+ if (ret == -EPROBE_DEFER) {
+ return ret;
+ } else {
+ dev_err(dev,
+ "can't get channel%d aux phy: %d\n",
+ channel->chno, ret);
+ return ret;
+ }
+ }
+
+ ret = phy_init(channel->aux_phy);
+ if (ret < 0) {
+ dev_err(dev,
+ "failed to initialize channel%d aux phy: %d\n",
+ channel->chno, ret);
+ return ret;
+ }
+ }
+
+ if (auxiliary_ch)
+ continue;
+ }
+
ret = imx_ldb_register(drm, channel);
if (ret) {
channel->child = NULL;
@@ -714,6 +1454,13 @@ static int imx_ldb_bind(struct device *dev, struct device *master, void *data)
dev_set_drvdata(dev, imx_ldb);
+ if (imx_ldb->pixel_link_valid_quirks ||
+ imx_ldb->pixel_link_init_quirks)
+ imx_ldb->id = of_alias_get_id(np, "ldb");
+
+ if (imx_ldb->pixel_link_init_quirks)
+ ldb_pixel_link_init(imx_ldb->id, dual);
+
return 0;
free_child:
@@ -725,17 +1472,38 @@ static void imx_ldb_unbind(struct device *dev, struct device *master,
void *data)
{
struct imx_ldb *imx_ldb = dev_get_drvdata(dev);
+ int dual = imx_ldb->ldb_ctrl & LDB_SPLIT_MODE_EN;
int i;
for (i = 0; i < 2; i++) {
struct imx_ldb_channel *channel = &imx_ldb->channel[i];
+ if (channel->phy_is_on) {
+ phy_power_off(channel->phy);
+ if (dual && imx_ldb->has_aux_ldb)
+ phy_power_off(channel->aux_phy);
+ }
+
+ phy_exit(channel->phy);
+ if (dual && imx_ldb->has_aux_ldb && i == 0)
+ phy_exit(channel->aux_phy);
+
if (channel->panel)
drm_panel_detach(channel->panel);
+ /* make sure the connector exists, and then cleanup */
+ if (channel->connector.dev)
+ imx_drm_connector_destroy(&channel->connector);
+
+ /* make sure the encoder exists, and then cleanup */
+ if (channel->encoder.dev)
+ imx_drm_encoder_destroy(&channel->encoder);
+
kfree(channel->edid);
i2c_put_adapter(channel->ddc);
}
+
+ dev_set_drvdata(dev, NULL);
}
static const struct component_ops imx_ldb_ops = {
@@ -754,12 +1522,72 @@ static int imx_ldb_remove(struct platform_device *pdev)
return 0;
}
+#ifdef CONFIG_PM_SLEEP
+static int imx_ldb_suspend(struct device *dev)
+{
+ struct imx_ldb *imx_ldb = dev_get_drvdata(dev);
+ struct imx_ldb_channel *channel;
+ int i, dual;
+
+ if (imx_ldb == NULL)
+ return 0;
+
+ dual = imx_ldb->ldb_ctrl & LDB_SPLIT_MODE_EN;
+
+ for (i = 0; i < 2; i++) {
+ channel = &imx_ldb->channel[i];
+
+ if (channel->phy_is_on)
+ phy_power_off(channel->phy);
+
+ phy_exit(channel->phy);
+
+ if (dual && imx_ldb->has_aux_ldb && i == 0) {
+ if (channel->phy_is_on)
+ phy_power_off(channel->aux_phy);
+
+ phy_exit(channel->aux_phy);
+ }
+ }
+
+ return 0;
+}
+
+static int imx_ldb_resume(struct device *dev)
+{
+ struct imx_ldb *imx_ldb = dev_get_drvdata(dev);
+ int i, dual;
+
+ if (imx_ldb == NULL)
+ return 0;
+
+ dual = imx_ldb->ldb_ctrl & LDB_SPLIT_MODE_EN;
+
+ if (imx_ldb->visible_phy) {
+ for (i = 0; i < 2; i++) {
+ phy_init(imx_ldb->channel[i].phy);
+
+ if (dual && imx_ldb->has_aux_ldb && i == 0)
+ phy_init(imx_ldb->channel[i].aux_phy);
+ }
+ }
+
+ if (imx_ldb->pixel_link_init_quirks)
+ ldb_pixel_link_init(imx_ldb->id, dual);
+
+ return 0;
+}
+#endif
+
+static SIMPLE_DEV_PM_OPS(imx_ldb_pm_ops, imx_ldb_suspend, imx_ldb_resume);
+
static struct platform_driver imx_ldb_driver = {
.probe = imx_ldb_probe,
.remove = imx_ldb_remove,
.driver = {
.of_match_table = imx_ldb_dt_ids,
.name = DRIVER_NAME,
+ .pm = &imx_ldb_pm_ops,
},
};
diff --git a/drivers/gpu/drm/imx/imx-tve.c b/drivers/gpu/drm/imx/imx-tve.c
index bc27c2699464..9ab7c73dc8e7 100644
--- a/drivers/gpu/drm/imx/imx-tve.c
+++ b/drivers/gpu/drm/imx/imx-tve.c
@@ -293,6 +293,11 @@ static void imx_tve_encoder_mode_set(struct drm_encoder *encoder,
rounded_rate = clk_get_rate(tve->clk);
if (rounded_rate >= rate)
div = 2;
+ if (rounded_rate > 0)
+ clk_set_rate(tve->di_clk, rounded_rate / div);
+ else
+ dev_err(tve->dev,
+ "clk_get_rate(tve->clk) returned 0 for rate\n");
clk_set_rate(tve->di_clk, rounded_rate / div);
ret = clk_set_parent(tve->di_sel_clk, tve->di_clk);
diff --git a/drivers/gpu/drm/imx/ipuv3/Kconfig b/drivers/gpu/drm/imx/ipuv3/Kconfig
new file mode 100644
index 000000000000..718da3784070
--- /dev/null
+++ b/drivers/gpu/drm/imx/ipuv3/Kconfig
@@ -0,0 +1,6 @@
+config DRM_IMX_IPUV3
+ tristate
+ depends on DRM_IMX
+ depends on IMX_IPUV3_CORE
+ default y if DRM_IMX=y
+ default m if DRM_IMX=m
diff --git a/drivers/gpu/drm/imx/ipuv3/Makefile b/drivers/gpu/drm/imx/ipuv3/Makefile
new file mode 100644
index 000000000000..e8ccced92385
--- /dev/null
+++ b/drivers/gpu/drm/imx/ipuv3/Makefile
@@ -0,0 +1,4 @@
+ccflags-y += -Idrivers/gpu/drm/imx
+
+imx-ipuv3-crtc-objs := ipuv3-crtc.o ipuv3-plane.o ipuv3-kms.o
+obj-$(CONFIG_DRM_IMX_IPUV3) += imx-ipuv3-crtc.o
diff --git a/drivers/gpu/drm/imx/ipuv3-crtc.c b/drivers/gpu/drm/imx/ipuv3/ipuv3-crtc.c
index 12dd261fc308..b1d66bc440b5 100644
--- a/drivers/gpu/drm/imx/ipuv3-crtc.c
+++ b/drivers/gpu/drm/imx/ipuv3/ipuv3-crtc.c
@@ -28,6 +28,7 @@
#include <video/imx-ipu-v3.h>
#include "imx-drm.h"
+#include "ipuv3-kms.h"
#include "ipuv3-plane.h"
#define DRIVER_DESC "i.MX IPUv3 Graphics"
@@ -109,7 +110,7 @@ static void ipu_crtc_atomic_disable(struct drm_crtc *crtc,
spin_unlock_irq(&crtc->dev->event_lock);
}
-static void imx_drm_crtc_reset(struct drm_crtc *crtc)
+static void ipu_crtc_reset(struct drm_crtc *crtc)
{
struct imx_crtc_state *state;
@@ -129,7 +130,7 @@ static void imx_drm_crtc_reset(struct drm_crtc *crtc)
state->base.crtc = crtc;
}
-static struct drm_crtc_state *imx_drm_crtc_duplicate_state(struct drm_crtc *crtc)
+static struct drm_crtc_state *ipu_crtc_duplicate_state(struct drm_crtc *crtc)
{
struct imx_crtc_state *state;
@@ -145,8 +146,8 @@ static struct drm_crtc_state *imx_drm_crtc_duplicate_state(struct drm_crtc *crtc
return &state->base;
}
-static void imx_drm_crtc_destroy_state(struct drm_crtc *crtc,
- struct drm_crtc_state *state)
+static void ipu_crtc_destroy_state(struct drm_crtc *crtc,
+ struct drm_crtc_state *state)
{
__drm_atomic_helper_crtc_destroy_state(state);
kfree(to_imx_crtc_state(state));
@@ -172,9 +173,9 @@ static const struct drm_crtc_funcs ipu_crtc_funcs = {
.set_config = drm_atomic_helper_set_config,
.destroy = drm_crtc_cleanup,
.page_flip = drm_atomic_helper_page_flip,
- .reset = imx_drm_crtc_reset,
- .atomic_duplicate_state = imx_drm_crtc_duplicate_state,
- .atomic_destroy_state = imx_drm_crtc_destroy_state,
+ .reset = ipu_crtc_reset,
+ .atomic_duplicate_state = ipu_crtc_duplicate_state,
+ .atomic_destroy_state = ipu_crtc_destroy_state,
.enable_vblank = ipu_enable_vblank,
.disable_vblank = ipu_disable_vblank,
};
@@ -429,6 +430,12 @@ static int ipu_drm_bind(struct device *dev, struct device *master, void *data)
if (ret)
return ret;
+ if (!drm->mode_config.funcs)
+ drm->mode_config.funcs = &ipuv3_drm_mode_config_funcs;
+ if (!drm->mode_config.helper_private)
+ drm->mode_config.helper_private =
+ &ipuv3_drm_mode_config_helpers;
+
dev_set_drvdata(dev, ipu_crtc);
return 0;
@@ -471,10 +478,16 @@ static int ipu_drm_remove(struct platform_device *pdev)
return 0;
}
-struct platform_driver ipu_drm_driver = {
+static struct platform_driver ipu_drm_driver = {
.driver = {
.name = "imx-ipuv3-crtc",
},
.probe = ipu_drm_probe,
.remove = ipu_drm_remove,
};
+module_platform_driver(ipu_drm_driver);
+
+MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de>");
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:imx-ipuv3-crtc");
diff --git a/drivers/gpu/drm/imx/ipuv3/ipuv3-kms.c b/drivers/gpu/drm/imx/ipuv3/ipuv3-kms.c
new file mode 100644
index 000000000000..4eb4953eb257
--- /dev/null
+++ b/drivers/gpu/drm/imx/ipuv3/ipuv3-kms.c
@@ -0,0 +1,98 @@
+/*
+ * Copyright 2017 NXP
+ *
+ * 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 <drm/drmP.h>
+#include <drm/drm_atomic.h>
+#include <drm/drm_atomic_helper.h>
+#include <drm/drm_fb_cma_helper.h>
+#include <drm/drm_gem_cma_helper.h>
+#include <linux/dma-buf.h>
+#include <linux/reservation.h>
+#include "imx-drm.h"
+
+static void imx_drm_output_poll_changed(struct drm_device *drm)
+{
+ struct imx_drm_device *imxdrm = drm->dev_private;
+
+ drm_fbdev_cma_hotplug_event(imxdrm->fbhelper);
+}
+
+static int imx_drm_atomic_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;
+
+ /*
+ * Check modeset again in case crtc_state->mode_changed is
+ * updated in plane's ->atomic_check callback.
+ */
+ ret = drm_atomic_helper_check_modeset(dev, state);
+ if (ret)
+ return ret;
+
+ /* Assign PRG/PRE channels and check if all constrains are satisfied. */
+ ret = ipu_planes_assign_pre(dev, state);
+ if (ret)
+ return ret;
+
+ return ret;
+}
+
+const struct drm_mode_config_funcs ipuv3_drm_mode_config_funcs = {
+ .fb_create = drm_fb_cma_create,
+ .output_poll_changed = imx_drm_output_poll_changed,
+ .atomic_check = imx_drm_atomic_check,
+ .atomic_commit = drm_atomic_helper_commit,
+};
+
+static void ipuv3_drm_atomic_commit_tail(struct drm_atomic_state *state)
+{
+ struct drm_device *dev = state->dev;
+ struct drm_plane *plane;
+ struct drm_plane_state *old_plane_state, *new_plane_state;
+ bool plane_disabling = false;
+ int i;
+
+ drm_atomic_helper_commit_modeset_disables(dev, state);
+
+ drm_atomic_helper_commit_planes(dev, state,
+ DRM_PLANE_COMMIT_ACTIVE_ONLY |
+ DRM_PLANE_COMMIT_NO_DISABLE_AFTER_MODESET);
+
+ drm_atomic_helper_commit_modeset_enables(dev, state);
+
+ for_each_oldnew_plane_in_state(state, plane, old_plane_state, new_plane_state, i) {
+ if (drm_atomic_plane_disabling(old_plane_state, new_plane_state))
+ plane_disabling = true;
+ }
+
+ drm_atomic_helper_commit_hw_done(state);
+
+ drm_atomic_helper_wait_for_vblanks(dev, state);
+
+ drm_atomic_helper_cleanup_planes(dev, state);
+}
+
+struct drm_mode_config_helper_funcs ipuv3_drm_mode_config_helpers = {
+ .atomic_commit_tail = ipuv3_drm_atomic_commit_tail,
+};
+
diff --git a/drivers/gpu/drm/imx/ipuv3/ipuv3-kms.h b/drivers/gpu/drm/imx/ipuv3/ipuv3-kms.h
new file mode 100644
index 000000000000..3968131d11af
--- /dev/null
+++ b/drivers/gpu/drm/imx/ipuv3/ipuv3-kms.h
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2017 NXP
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+#ifndef _IPUV3_KMS_H_
+#define _IPUV3_KMS_H_
+
+extern const struct drm_mode_config_funcs ipuv3_drm_mode_config_funcs;
+extern struct drm_mode_config_helper_funcs ipuv3_drm_mode_config_helpers;
+
+#endif
diff --git a/drivers/gpu/drm/imx/ipuv3-plane.c b/drivers/gpu/drm/imx/ipuv3/ipuv3-plane.c
index d0d7f6adbc89..d0d7f6adbc89 100644
--- a/drivers/gpu/drm/imx/ipuv3-plane.c
+++ b/drivers/gpu/drm/imx/ipuv3/ipuv3-plane.c
diff --git a/drivers/gpu/drm/imx/ipuv3-plane.h b/drivers/gpu/drm/imx/ipuv3/ipuv3-plane.h
index e563ea17a827..e563ea17a827 100644
--- a/drivers/gpu/drm/imx/ipuv3-plane.h
+++ b/drivers/gpu/drm/imx/ipuv3/ipuv3-plane.h
diff --git a/drivers/gpu/drm/imx/lcdif/Kconfig b/drivers/gpu/drm/imx/lcdif/Kconfig
new file mode 100644
index 000000000000..4460ffacd1f7
--- /dev/null
+++ b/drivers/gpu/drm/imx/lcdif/Kconfig
@@ -0,0 +1,8 @@
+config DRM_IMX_LCDIF
+ tristate "i.MX LCDIF controller DRM driver"
+ depends on DRM_IMX
+ depends on IMX_LCDIF_CORE
+ default y if DRM_IMX=y
+ default m if DRM_IMX=m
+ help
+ enable i.MX LCDIF controller DRM driver under DRM_IMX.
diff --git a/drivers/gpu/drm/imx/lcdif/Makefile b/drivers/gpu/drm/imx/lcdif/Makefile
new file mode 100644
index 000000000000..fcdecff9e861
--- /dev/null
+++ b/drivers/gpu/drm/imx/lcdif/Makefile
@@ -0,0 +1,4 @@
+ccflags-y += -Idrivers/gpu/drm/imx
+
+imx-lcdif-crtc-objs := lcdif-crtc.o lcdif-plane.o lcdif-kms.o
+obj-$(CONFIG_DRM_IMX_LCDIF) += imx-lcdif-crtc.o
diff --git a/drivers/gpu/drm/imx/lcdif/lcdif-crtc.c b/drivers/gpu/drm/imx/lcdif/lcdif-crtc.c
new file mode 100644
index 000000000000..9c7642e4a997
--- /dev/null
+++ b/drivers/gpu/drm/imx/lcdif/lcdif-crtc.c
@@ -0,0 +1,389 @@
+/*
+ * Copyright 2018 NXP
+ *
+ * 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/component.h>
+#include <linux/device.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <drm/drmP.h>
+#include <drm/drm_atomic_helper.h>
+#include <video/imx-lcdif.h>
+#include <video/videomode.h>
+
+#include "imx-drm.h"
+#include "lcdif-plane.h"
+#include "lcdif-kms.h"
+
+struct lcdif_crtc {
+ struct device *dev;
+
+ struct drm_crtc base;
+ struct lcdif_plane *plane[2];
+
+ int vbl_irq;
+ u32 pix_fmt; /* drm fourcc */
+};
+
+#define to_lcdif_crtc(crtc) container_of(crtc, struct lcdif_crtc, base)
+
+static void lcdif_crtc_reset(struct drm_crtc *crtc)
+{
+ struct imx_crtc_state *state;
+
+ if (crtc->state) {
+ __drm_atomic_helper_crtc_destroy_state(crtc->state);
+
+ state = to_imx_crtc_state(crtc->state);
+ kfree(state);
+ crtc->state = NULL;
+ }
+
+ state = kzalloc(sizeof(*state), GFP_KERNEL);
+ if (!state)
+ return;
+
+ crtc->state = &state->base;
+ crtc->state->crtc = crtc;
+}
+
+static struct drm_crtc_state *lcdif_crtc_duplicate_state(struct drm_crtc *crtc)
+{
+ struct imx_crtc_state *state, *orig_state;
+
+ if (WARN_ON(!crtc->state))
+ return NULL;
+
+ state = kzalloc(sizeof(*state), GFP_KERNEL);
+ if (!state)
+ return NULL;
+
+ __drm_atomic_helper_crtc_duplicate_state(crtc, &state->base);
+
+ orig_state = to_imx_crtc_state(crtc->state);
+ state->bus_format = orig_state->bus_format;
+ state->bus_flags = orig_state->bus_flags;
+ state->di_hsync_pin = orig_state->di_hsync_pin;
+ state->di_vsync_pin = orig_state->di_vsync_pin;
+
+ return &state->base;
+}
+
+static void lcdif_crtc_destroy_state(struct drm_crtc *crtc,
+ struct drm_crtc_state *state)
+{
+ __drm_atomic_helper_crtc_destroy_state(state);
+ kfree(to_imx_crtc_state(state));
+}
+
+static int lcdif_crtc_atomic_check(struct drm_crtc *crtc,
+ struct drm_crtc_state *state)
+{
+ struct lcdif_crtc *lcdif_crtc = to_lcdif_crtc(crtc);
+ struct imx_crtc_state *imx_crtc_state = to_imx_crtc_state(state);
+
+ /* Don't check 'bus_format' when CRTC is
+ * going to be disabled.
+ */
+ if (!state->enable)
+ return 0;
+
+ /* For the commit that the CRTC is active
+ * without planes attached to it should be
+ * invalid.
+ */
+ if (state->active && !state->plane_mask)
+ return -EINVAL;
+
+ /* check the requested bus format can be
+ * supported by LCDIF CTRC or not
+ */
+ switch (imx_crtc_state->bus_format) {
+ case MEDIA_BUS_FMT_RGB565_1X16:
+ case MEDIA_BUS_FMT_RGB666_1X18:
+ case MEDIA_BUS_FMT_RGB888_1X24:
+ break;
+ default:
+ dev_err(lcdif_crtc->dev,
+ "unsupported bus format: %#x\n",
+ imx_crtc_state->bus_format);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static void lcdif_crtc_atomic_begin(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_crtc_state)
+{
+ drm_crtc_vblank_on(crtc);
+
+ spin_lock_irq(&crtc->dev->event_lock);
+ if (crtc->state->event) {
+ WARN_ON(drm_crtc_vblank_get(crtc));
+ drm_crtc_arm_vblank_event(crtc, crtc->state->event);
+ crtc->state->event = NULL;
+ }
+ spin_unlock_irq(&crtc->dev->event_lock);
+}
+
+static void lcdif_crtc_atomic_flush(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_crtc_state)
+{
+ /* LCDIF doesn't have command buffer */
+ return;
+}
+
+static void lcdif_crtc_atomic_enable(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_crtc_state)
+{
+ struct lcdif_crtc *lcdif_crtc = to_lcdif_crtc(crtc);
+ struct lcdif_soc *lcdif = dev_get_drvdata(lcdif_crtc->dev->parent);
+ struct drm_display_mode *mode = &crtc->state->adjusted_mode;
+ struct imx_crtc_state *imx_crtc_state = to_imx_crtc_state(crtc->state);
+ struct videomode vm;
+
+ drm_display_mode_to_videomode(mode, &vm);
+
+ if (imx_crtc_state->bus_flags & DRM_BUS_FLAG_DE_HIGH)
+ vm.flags |= DISPLAY_FLAGS_DE_HIGH;
+ else
+ vm.flags |= DISPLAY_FLAGS_DE_LOW;
+
+ if (imx_crtc_state->bus_flags & DRM_BUS_FLAG_PIXDATA_POSEDGE)
+ vm.flags |= DISPLAY_FLAGS_PIXDATA_POSEDGE;
+ else
+ vm.flags |= DISPLAY_FLAGS_PIXDATA_NEGEDGE;
+
+ pm_runtime_get_sync(lcdif_crtc->dev->parent);
+
+ lcdif_set_mode(lcdif, &vm);
+
+ /* config LCDIF output bus format */
+ lcdif_set_bus_fmt(lcdif, imx_crtc_state->bus_format);
+
+ /* defer the lcdif controller enable to plane update,
+ * since until then the lcdif config is complete to
+ * enable the controller to run actually.
+ */
+}
+
+static void lcdif_crtc_atomic_disable(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_crtc_state)
+{
+ struct lcdif_crtc *lcdif_crtc = to_lcdif_crtc(crtc);
+ struct lcdif_soc *lcdif = dev_get_drvdata(lcdif_crtc->dev->parent);
+
+ spin_lock_irq(&crtc->dev->event_lock);
+ if (crtc->state->event) {
+ drm_crtc_send_vblank_event(crtc, crtc->state->event);
+ crtc->state->event = NULL;
+ }
+ spin_unlock_irq(&crtc->dev->event_lock);
+
+ drm_crtc_vblank_off(crtc);
+
+ lcdif_disable_controller(lcdif);
+
+ pm_runtime_put(lcdif_crtc->dev->parent);
+}
+
+static const struct drm_crtc_helper_funcs lcdif_helper_funcs = {
+ .atomic_check = lcdif_crtc_atomic_check,
+ .atomic_begin = lcdif_crtc_atomic_begin,
+ .atomic_flush = lcdif_crtc_atomic_flush,
+ .atomic_enable = lcdif_crtc_atomic_enable,
+ .atomic_disable = lcdif_crtc_atomic_disable,
+};
+
+static int lcdif_enable_vblank(struct drm_crtc *crtc)
+{
+ struct lcdif_crtc *lcdif_crtc = to_lcdif_crtc(crtc);
+ struct lcdif_soc *lcdif = dev_get_drvdata(lcdif_crtc->dev->parent);
+
+ lcdif_vblank_irq_enable(lcdif);
+ enable_irq(lcdif_crtc->vbl_irq);
+
+ return 0;
+}
+
+static void lcdif_disable_vblank(struct drm_crtc *crtc)
+{
+ struct lcdif_crtc *lcdif_crtc = to_lcdif_crtc(crtc);
+ struct lcdif_soc *lcdif = dev_get_drvdata(lcdif_crtc->dev->parent);
+
+ disable_irq_nosync(lcdif_crtc->vbl_irq);
+ lcdif_vblank_irq_disable(lcdif);
+}
+
+static const struct drm_crtc_funcs lcdif_crtc_funcs = {
+ .set_config = drm_atomic_helper_set_config,
+ .destroy = drm_crtc_cleanup,
+ .page_flip = drm_atomic_helper_page_flip,
+ .reset = lcdif_crtc_reset,
+ .atomic_duplicate_state = lcdif_crtc_duplicate_state,
+ .atomic_destroy_state = lcdif_crtc_destroy_state,
+ .enable_vblank = lcdif_enable_vblank,
+ .disable_vblank = lcdif_disable_vblank,
+};
+
+static irqreturn_t lcdif_crtc_vblank_irq_handler(int irq, void *dev_id)
+{
+ struct lcdif_crtc *lcdif_crtc = dev_id;
+ struct lcdif_soc *lcdif = dev_get_drvdata(lcdif_crtc->dev->parent);
+
+ drm_crtc_handle_vblank(&lcdif_crtc->base);
+
+ lcdif_vblank_irq_clear(lcdif);
+
+ return IRQ_HANDLED;
+}
+
+static int lcdif_crtc_init(struct lcdif_crtc *lcdif_crtc,
+ struct lcdif_client_platformdata *pdata,
+ struct drm_device *drm)
+{
+ int ret;
+ struct lcdif_plane *primary = lcdif_crtc->plane[0];
+ struct lcdif_soc *lcdif = dev_get_drvdata(lcdif_crtc->dev->parent);
+
+ /* Primary plane
+ * The 'possible_crtcs' of primary plane will be
+ * recalculated during the 'crtc' initialization
+ * later.
+ */
+ primary = lcdif_plane_init(drm, lcdif, 0, DRM_PLANE_TYPE_PRIMARY, 0);
+ if (IS_ERR(primary))
+ return PTR_ERR(primary);
+ lcdif_crtc->plane[0] = primary;
+
+ /* TODO: Overlay plane */
+
+ lcdif_crtc->base.port = pdata->of_node;
+ drm_crtc_helper_add(&lcdif_crtc->base, &lcdif_helper_funcs);
+ ret = drm_crtc_init_with_planes(drm, &lcdif_crtc->base,
+ &lcdif_crtc->plane[0]->base, NULL,
+ &lcdif_crtc_funcs, NULL);
+ if (ret) {
+ dev_err(lcdif_crtc->dev, "failed to init crtc\n");
+ goto primary_plane_deinit;
+ }
+
+ lcdif_crtc->vbl_irq = lcdif_vblank_irq_get(lcdif);
+ WARN_ON(lcdif_crtc->vbl_irq < 0);
+
+ ret = devm_request_irq(lcdif_crtc->dev, lcdif_crtc->vbl_irq,
+ lcdif_crtc_vblank_irq_handler, 0,
+ dev_name(lcdif_crtc->dev), lcdif_crtc);
+ if (ret) {
+ dev_err(lcdif_crtc->dev,
+ "vblank irq request failed: %d\n", ret);
+ goto primary_plane_deinit;
+ }
+
+ disable_irq(lcdif_crtc->vbl_irq);
+
+ return 0;
+
+primary_plane_deinit:
+ lcdif_plane_deinit(drm, primary);
+
+ return ret;
+}
+
+static int lcdif_crtc_bind(struct device *dev, struct device *master,
+ void *data)
+{
+ int ret;
+ struct drm_device *drm = data;
+ struct lcdif_crtc *lcdif_crtc;
+ struct lcdif_client_platformdata *pdata = dev->platform_data;
+
+ dev_dbg(dev, "%s: lcdif crtc bind begin\n", __func__);
+
+ lcdif_crtc = devm_kzalloc(dev, sizeof(*lcdif_crtc), GFP_KERNEL);
+ if (!lcdif_crtc)
+ return -ENOMEM;
+
+ lcdif_crtc->dev = dev;
+
+ ret = lcdif_crtc_init(lcdif_crtc, pdata, drm);
+ if (ret)
+ return ret;
+
+ if (!drm->mode_config.funcs)
+ drm->mode_config.funcs = &lcdif_drm_mode_config_funcs;
+
+ if (!drm->mode_config.helper_private)
+ drm->mode_config.helper_private = &lcdif_drm_mode_config_helpers;
+
+ /* limit the max width and height */
+ drm->mode_config.max_width = 1920;
+ drm->mode_config.max_height = 1920;
+
+ dev_set_drvdata(dev, lcdif_crtc);
+
+ dev_dbg(dev, "%s: lcdif crtc bind end\n", __func__);
+
+ return 0;
+}
+
+static void lcdif_crtc_unbind(struct device *dev, struct device *master,
+ void *data)
+{
+ struct drm_device *drm = data;
+ struct lcdif_crtc *lcdif_crtc = dev_get_drvdata(dev);
+
+ lcdif_plane_deinit(drm, lcdif_crtc->plane[0]);
+}
+
+static const struct component_ops lcdif_crtc_ops = {
+ .bind = lcdif_crtc_bind,
+ .unbind = lcdif_crtc_unbind,
+};
+
+static int lcdif_crtc_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+
+ dev_dbg(&pdev->dev, "%s: lcdif crtc probe begin\n", __func__);
+
+ if (!dev->platform_data) {
+ dev_err(dev, "no platform data\n");
+ return -EINVAL;
+ }
+
+ return component_add(dev, &lcdif_crtc_ops);
+}
+
+static int lcdif_crtc_remove(struct platform_device *pdev)
+{
+ component_del(&pdev->dev, &lcdif_crtc_ops);
+
+ return 0;
+}
+
+static struct platform_driver lcdif_crtc_driver = {
+ .probe = lcdif_crtc_probe,
+ .remove = lcdif_crtc_remove,
+ .driver = {
+ .name = "imx-lcdif-crtc",
+ },
+};
+module_platform_driver(lcdif_crtc_driver);
+
+MODULE_DESCRIPTION("NXP i.MX LCDIF DRM CRTC driver");
+MODULE_AUTHOR("Fancy Fang <chen.fang@nxp.com>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/drm/imx/lcdif/lcdif-kms.c b/drivers/gpu/drm/imx/lcdif/lcdif-kms.c
new file mode 100644
index 000000000000..f013bf0ce7f8
--- /dev/null
+++ b/drivers/gpu/drm/imx/lcdif/lcdif-kms.c
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2018 NXP
+ *
+ * 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 <drm/drmP.h>
+#include <drm/drm_atomic.h>
+#include <drm/drm_atomic_helper.h>
+#include <drm/drm_crtc.h>
+#include <drm/drm_fb_cma_helper.h>
+
+static void lcdif_drm_atomic_commit_tail(struct drm_atomic_state *state)
+{
+ struct drm_device *dev = state->dev;
+
+ drm_atomic_helper_commit_modeset_disables(dev, state);
+
+ drm_atomic_helper_commit_modeset_enables(dev, state);
+
+ drm_atomic_helper_commit_planes(dev, state, DRM_PLANE_COMMIT_ACTIVE_ONLY);
+
+ drm_atomic_helper_commit_hw_done(state);
+
+ drm_atomic_helper_wait_for_vblanks(dev, state);
+
+ drm_atomic_helper_cleanup_planes(dev, state);
+}
+
+const struct drm_mode_config_funcs lcdif_drm_mode_config_funcs = {
+ .fb_create = drm_fb_cma_create,
+ .atomic_check = drm_atomic_helper_check,
+ .atomic_commit = drm_atomic_helper_commit,
+};
+
+struct drm_mode_config_helper_funcs lcdif_drm_mode_config_helpers = {
+ .atomic_commit_tail = lcdif_drm_atomic_commit_tail,
+};
diff --git a/drivers/gpu/drm/imx/lcdif/lcdif-kms.h b/drivers/gpu/drm/imx/lcdif/lcdif-kms.h
new file mode 100644
index 000000000000..fcf7d257c6b7
--- /dev/null
+++ b/drivers/gpu/drm/imx/lcdif/lcdif-kms.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright 2018 NXP
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __LCDIF_KMS_H
+#define __LCDIF_KMS_H
+
+extern const struct drm_mode_config_funcs lcdif_drm_mode_config_funcs;
+extern struct drm_mode_config_helper_funcs lcdif_drm_mode_config_helpers;
+
+#endif
diff --git a/drivers/gpu/drm/imx/lcdif/lcdif-plane.c b/drivers/gpu/drm/imx/lcdif/lcdif-plane.c
new file mode 100644
index 000000000000..a29fd3ddc6f5
--- /dev/null
+++ b/drivers/gpu/drm/imx/lcdif/lcdif-plane.c
@@ -0,0 +1,233 @@
+/*
+ * Copyright 2018 NXP
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/module.h>
+#include <drm/drmP.h>
+#include <drm/drm_atomic.h>
+#include <drm/drm_atomic_helper.h>
+#include <drm/drm_fb_cma_helper.h>
+#include <drm/drm_framebuffer.h>
+#include <drm/drm_gem_cma_helper.h>
+#include <drm/drm_plane.h>
+#include <drm/drm_plane_helper.h>
+#include <drm/drm_rect.h>
+#include <video/imx-lcdif.h>
+
+#include "lcdif-plane.h"
+
+static uint32_t lcdif_pixel_formats[] = {
+ DRM_FORMAT_XRGB8888,
+ DRM_FORMAT_ARGB8888,
+ DRM_FORMAT_RGB565,
+ DRM_FORMAT_XBGR8888,
+ DRM_FORMAT_ABGR8888,
+ DRM_FORMAT_RGBX8888,
+ DRM_FORMAT_RGBA8888,
+ DRM_FORMAT_ARGB1555,
+ DRM_FORMAT_XRGB1555,
+ DRM_FORMAT_ABGR1555,
+ DRM_FORMAT_XBGR1555,
+ DRM_FORMAT_BGR565,
+};
+
+static int lcdif_plane_atomic_check(struct drm_plane *plane,
+ struct drm_plane_state *plane_state)
+{
+ int ret;
+ struct drm_plane_state *old_state = plane->state;
+ struct drm_framebuffer *fb = plane_state->fb;
+ struct drm_framebuffer *old_fb = old_state->fb;
+ struct drm_crtc_state *crtc_state;
+ struct drm_display_mode *mode;
+ struct drm_rect clip = { 0 };
+
+ /* 'fb' should also be NULL which has been checked in
+ * the core sanity check function 'drm_atomic_plane_check()'
+ */
+ if (!plane_state->crtc) {
+ WARN_ON(fb);
+ return 0;
+ }
+
+ /* lcdif crtc can only display from (0,0) for each plane */
+ if (plane_state->crtc_x || plane_state->crtc_y)
+ return -EINVAL;
+
+ crtc_state = drm_atomic_get_existing_crtc_state(plane_state->state,
+ plane_state->crtc);
+ mode = &crtc_state->adjusted_mode;
+
+ clip.x2 = mode->hdisplay;
+ clip.y2 = mode->vdisplay;
+
+ ret = drm_plane_helper_check_state(plane_state, &clip,
+ DRM_PLANE_HELPER_NO_SCALING,
+ DRM_PLANE_HELPER_NO_SCALING,
+ false, true);
+ if (ret)
+ return ret;
+
+ if (!plane_state->visible)
+ return -EINVAL;
+
+ /* force 'mode_changed' when fb pitches changed, since
+ * the pitch related registers configuration of LCDIF
+ * can not be done when LCDIF is running.
+ */
+ if (old_fb && likely(!crtc_state->mode_changed)) {
+ if (old_fb->pitches[0] != fb->pitches[0])
+ crtc_state->mode_changed = true;
+ }
+
+ return 0;
+}
+
+static void lcdif_plane_atomic_update(struct drm_plane *plane,
+ struct drm_plane_state *old_state)
+{
+ struct lcdif_plane *lcdif_plane = to_lcdif_plane(plane);
+ struct lcdif_soc *lcdif = lcdif_plane->lcdif;
+ struct drm_plane_state *state = plane->state;
+ struct drm_framebuffer *fb = state->fb;
+ struct drm_gem_cma_object *gem_obj = NULL;
+ u32 fb_addr, src_off, src_w, fb_idx, cpp, stride;
+ bool crop;
+
+ /* plane and crtc is disabling */
+ if (!fb)
+ return;
+
+ /* TODO: for now we just update the next buf addr
+ * and the fb pixel format, since the mode set will
+ * be done in crtc's ->enable() helper func
+ */
+ if (plane->type == DRM_PLANE_TYPE_PRIMARY)
+ lcdif_set_pix_fmt(lcdif, fb->format->format);
+
+ switch (plane->type) {
+ case DRM_PLANE_TYPE_PRIMARY:
+ /* TODO: only support RGB */
+ gem_obj = drm_fb_cma_get_gem_obj(fb, 0);
+ src_off = (state->src_y >> 16) * fb->pitches[0] +
+ (state->src_x >> 16) * fb->format->cpp[0];
+ fb_addr = gem_obj->paddr + fb->offsets[0] + src_off;
+ fb_idx = 0;
+ break;
+ default:
+ /* TODO: add overlay later */
+ return;
+ }
+
+ lcdif_set_fb_addr(lcdif, fb_idx, fb_addr);
+
+ /* config horizontal cropping if crtc needs modeset */
+ if (unlikely(drm_atomic_crtc_needs_modeset(state->crtc->state))) {
+ cpp = fb->format->cpp[0];
+ stride = DIV_ROUND_UP(fb->pitches[0], cpp);
+
+ src_w = state->src_w >> 16;
+ WARN_ON(src_w > fb->width);
+
+ crop = src_w != stride ? true : false;
+ lcdif_set_fb_hcrop(lcdif, src_w, stride, crop);
+ }
+
+ lcdif_enable_controller(lcdif);
+}
+
+static void lcdif_plane_atomic_disable(struct drm_plane *plane,
+ struct drm_plane_state *old_state)
+{
+ struct drm_plane_state *state = plane->state;
+ struct drm_framebuffer *fb = state->fb;
+
+ WARN_ON(fb);
+
+ /* TODO: CRTC disabled has been done by CRTC helper function,
+ * so it seems that no more required, the only possible thing
+ * is to set next buf addr to 0 in CRTC
+ */
+}
+
+static const struct drm_plane_helper_funcs lcdif_plane_helper_funcs = {
+ .atomic_check = lcdif_plane_atomic_check,
+ .atomic_update = lcdif_plane_atomic_update,
+ .atomic_disable = lcdif_plane_atomic_disable,
+};
+
+static void lcdif_plane_destroy(struct drm_plane *plane)
+{
+ struct lcdif_plane *lcdif_plane = to_lcdif_plane(plane);
+
+ drm_plane_cleanup(plane);
+ kfree(lcdif_plane);
+}
+
+static const struct drm_plane_funcs lcdif_plane_funcs = {
+ .update_plane = drm_atomic_helper_update_plane,
+ .disable_plane = drm_atomic_helper_disable_plane,
+ .destroy = lcdif_plane_destroy,
+ .reset = drm_atomic_helper_plane_reset,
+ .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
+ .atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
+};
+
+struct lcdif_plane *lcdif_plane_init(struct drm_device *dev,
+ struct lcdif_soc *lcdif,
+ unsigned int possible_crtcs,
+ enum drm_plane_type type,
+ unsigned int zpos)
+{
+ int ret;
+ struct lcdif_plane *lcdif_plane;
+
+ /* lcdif doesn't support fb modifiers */
+ if (zpos || dev->mode_config.allow_fb_modifiers)
+ return ERR_PTR(-EINVAL);
+
+ lcdif_plane = kzalloc(sizeof(*lcdif_plane), GFP_KERNEL);
+ if (!lcdif_plane)
+ return ERR_PTR(-ENOMEM);
+
+ lcdif_plane->lcdif = lcdif;
+
+ drm_plane_helper_add(&lcdif_plane->base, &lcdif_plane_helper_funcs);
+ ret = drm_universal_plane_init(dev, &lcdif_plane->base, possible_crtcs,
+ &lcdif_plane_funcs, lcdif_pixel_formats,
+ ARRAY_SIZE(lcdif_pixel_formats), NULL,
+ type, NULL);
+ if (ret) {
+ kfree(lcdif_plane);
+ return ERR_PTR(ret);
+ }
+
+ ret = drm_plane_create_zpos_immutable_property(&lcdif_plane->base, zpos);
+ if (ret) {
+ kfree(lcdif_plane);
+ return ERR_PTR(ret);
+ }
+
+ return lcdif_plane;
+}
+
+void lcdif_plane_deinit(struct drm_device *dev,
+ struct lcdif_plane *lcdif_plane)
+{
+ struct drm_plane *plane = &lcdif_plane->base;
+
+ if (plane->zpos_property)
+ drm_property_destroy(dev, plane->zpos_property);
+
+ lcdif_plane_destroy(plane);
+}
diff --git a/drivers/gpu/drm/imx/lcdif/lcdif-plane.h b/drivers/gpu/drm/imx/lcdif/lcdif-plane.h
new file mode 100644
index 000000000000..acd7aead606a
--- /dev/null
+++ b/drivers/gpu/drm/imx/lcdif/lcdif-plane.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2018 NXP
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __LCDIF_PLANE_H
+#define __LCDIF_PLANE_H
+
+#include <drm/drm_plane.h>
+#include <video/imx-lcdif.h>
+
+struct lcdif_plane {
+ struct drm_plane base;
+ struct lcdif_soc *lcdif;
+};
+
+#define to_lcdif_plane(plane) container_of(plane, struct lcdif_plane, base)
+
+struct lcdif_plane *lcdif_plane_init(struct drm_device *drm,
+ struct lcdif_soc *lcdif,
+ unsigned int possible_crtcs,
+ enum drm_plane_type type,
+ unsigned int zpos);
+
+void lcdif_plane_deinit(struct drm_device *dev,
+ struct lcdif_plane *lcdif_plane);
+
+#endif
diff --git a/drivers/gpu/drm/imx/nwl_dsi-imx.c b/drivers/gpu/drm/imx/nwl_dsi-imx.c
new file mode 100644
index 000000000000..658619936745
--- /dev/null
+++ b/drivers/gpu/drm/imx/nwl_dsi-imx.c
@@ -0,0 +1,1028 @@
+/*
+ * i.MX drm driver - Northwest Logic MIPI DSI display driver
+ *
+ * Copyright (C) 2017 NXP
+ *
+ * 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 <drm/bridge/nwl_dsi.h>
+#include <drm/drmP.h>
+#include <drm/drm_atomic_helper.h>
+#include <drm/drm_crtc_helper.h>
+#include <drm/drm_of.h>
+#include <linux/busfreq-imx.h>
+#include <linux/clk.h>
+#include <linux/component.h>
+#include <linux/err.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/mfd/syscon.h>
+#include <linux/mfd/syscon/imx8mq-iomuxc-gpr.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_graph.h>
+#include <linux/of_platform.h>
+#include <linux/phy/phy.h>
+#include <linux/regmap.h>
+#include <soc/imx8/sc/sci.h>
+#include <video/videomode.h>
+
+#include "imx-drm.h"
+
+#define DRIVER_NAME "nwl_dsi-imx"
+
+/* 8MQ SRC specific registers */
+#define SRC_MIPIPHY_RCR 0x28
+#define RESET_BYTE_N BIT(1)
+#define RESET_N BIT(2)
+#define DPI_RESET_N BIT(3)
+#define ESC_RESET_N BIT(4)
+#define PCLK_RESET_N BIT(5)
+
+#define DC_ID(x) SC_R_DC_ ## x
+#define MIPI_ID(x) SC_R_MIPI_ ## x
+#define SYNC_CTRL(x) SC_C_SYNC_CTRL ## x
+#define PXL_VLD(x) SC_C_PXL_LINK_MST ## x ## _VLD
+#define PXL_ADDR(x) SC_C_PXL_LINK_MST ## x ## _ADDR
+
+/* Possible clocks */
+#define CLK_PIXEL "pixel"
+#define CLK_CORE "core"
+#define CLK_BYPASS "bypass"
+#define CLK_PHYREF "phy_ref"
+
+struct imx_mipi_dsi {
+ struct drm_encoder encoder;
+ struct drm_bridge bridge;
+ struct drm_bridge *next_bridge;
+ struct device *dev;
+ struct phy *phy;
+
+ /* Optional external regs */
+ struct regmap *csr;
+ struct regmap *reset;
+ struct regmap *mux_sel;
+
+ /* Optional clocks */
+ struct clk_config *clk_config;
+ size_t clk_num;
+
+ u32 tx_ulps_reg;
+ u32 pxl2dpi_reg;
+
+ u32 instance;
+ u32 sync_pol;
+ u32 power_on_delay;
+ bool no_clk_reset;
+ bool enabled;
+ bool suspended;
+};
+
+struct clk_config {
+ const char *id;
+ struct clk *clk;
+ bool present;
+ bool enabled;
+ u32 rate;
+};
+
+enum imx_ext_regs {
+ IMX_REG_CSR = BIT(1),
+ IMX_REG_SRC = BIT(2),
+ IMX_REG_GPR = BIT(3),
+};
+
+struct devtype {
+ int (*poweron)(struct imx_mipi_dsi *);
+ void (*poweroff)(struct imx_mipi_dsi *);
+ u32 ext_regs; /* required external registers */
+ u32 tx_ulps_reg;
+ u32 pxl2dpi_reg;
+ u8 max_instances;
+ struct clk_config clk_config[4];
+};
+
+static int imx8qm_dsi_poweron(struct imx_mipi_dsi *dsi);
+static void imx8qm_dsi_poweroff(struct imx_mipi_dsi *dsi);
+static struct devtype imx8qm_dev = {
+ .poweron = &imx8qm_dsi_poweron,
+ .poweroff = &imx8qm_dsi_poweroff,
+ .clk_config = {
+ { .id = CLK_CORE, .present = false },
+ { .id = CLK_PHYREF, .present = true },
+ { .id = CLK_BYPASS, .present = true },
+ { .id = CLK_PIXEL, .present = true },
+ },
+ .ext_regs = IMX_REG_CSR,
+ .tx_ulps_reg = 0x00,
+ .pxl2dpi_reg = 0x04,
+ .max_instances = 2,
+};
+
+static int imx8qxp_dsi_poweron(struct imx_mipi_dsi *dsi);
+static void imx8qxp_dsi_poweroff(struct imx_mipi_dsi *dsi);
+static struct devtype imx8qxp_dev = {
+ .poweron = &imx8qxp_dsi_poweron,
+ .poweroff = &imx8qxp_dsi_poweroff,
+ .clk_config = {
+ { .id = CLK_CORE, .present = false },
+ { .id = CLK_PHYREF, .present = true },
+ { .id = CLK_BYPASS, .present = true },
+ { .id = CLK_PIXEL, .present = true },
+ },
+ .ext_regs = IMX_REG_CSR,
+ .tx_ulps_reg = 0x30,
+ .pxl2dpi_reg = 0x40,
+ .max_instances = 2,
+};
+
+static int imx8mq_dsi_poweron(struct imx_mipi_dsi *dsi);
+static void imx8mq_dsi_poweroff(struct imx_mipi_dsi *dsi);
+static struct devtype imx8mq_dev = {
+ .poweron = &imx8mq_dsi_poweron,
+ .poweroff = &imx8mq_dsi_poweroff,
+ .clk_config = {
+ { .id = CLK_CORE, .present = true },
+ { .id = CLK_PIXEL, .present = false },
+ { .id = CLK_BYPASS, .present = false },
+ { .id = CLK_PHYREF, .present = true },
+ },
+ .ext_regs = IMX_REG_SRC | IMX_REG_GPR,
+ .max_instances = 1,
+};
+
+static const struct of_device_id imx_nwl_dsi_dt_ids[] = {
+ { .compatible = "fsl,imx8qm-mipi-dsi", .data = &imx8qm_dev, },
+ { .compatible = "fsl,imx8qxp-mipi-dsi", .data = &imx8qxp_dev, },
+ { .compatible = "fsl,imx8mq-mipi-dsi_drm", .data = &imx8mq_dev, },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, imx_nwl_dsi_dt_ids);
+
+static inline struct imx_mipi_dsi *encoder_to_dsi(struct drm_encoder *encoder)
+{
+ return container_of(encoder, struct imx_mipi_dsi, encoder);
+}
+
+static void imx_nwl_dsi_set_clocks(struct imx_mipi_dsi *dsi, bool enable)
+{
+ struct device *dev = dsi->dev;
+ const char *id;
+ struct clk *clk;
+ unsigned long new_rate, cur_rate;
+ bool enabled;
+ size_t i;
+
+ for (i = 0; i < dsi->clk_num; i++) {
+ if (!dsi->clk_config[i].present)
+ continue;
+ id = dsi->clk_config[i].id;
+ clk = dsi->clk_config[i].clk;
+ new_rate = dsi->clk_config[i].rate;
+ cur_rate = clk_get_rate(clk);
+ enabled = dsi->clk_config[i].enabled;
+
+ if (enable) {
+ if (enabled && new_rate != cur_rate)
+ clk_disable_unprepare(clk);
+ else if (enabled && new_rate == cur_rate)
+ continue;
+ if (new_rate > 0)
+ clk_set_rate(clk, new_rate);
+ clk_prepare_enable(clk);
+ dsi->clk_config[i].enabled = true;
+ cur_rate = clk_get_rate(clk);
+ DRM_DEV_DEBUG_DRIVER(dev,
+ "Enabled %s clk (rate: req=%lu act=%lu)\n",
+ id, new_rate, cur_rate);
+ } else if (enabled) {
+ clk_disable_unprepare(clk);
+ dsi->clk_config[i].enabled = false;
+ DRM_DEV_DEBUG_DRIVER(dev, "Disabled %s clk\n", id);
+ }
+ }
+}
+
+/*
+ * v2 is true for QXP
+ * On QM, we have 2 DPUs, each one with a MIPI-DSI link
+ * On QXP, we have 1 DPU with two MIPI-DSI links
+ * Because of this, we will have different initialization
+ * paths for MIPI0 and MIPI1 on QM vs QXP
+ */
+static int imx8q_dsi_poweron(struct imx_mipi_dsi *dsi, bool v2)
+{
+ struct device *dev = dsi->dev;
+ int ret = 0;
+ sc_err_t sci_err = 0;
+ sc_ipc_t ipc_handle = 0;
+ u32 inst = dsi->instance;
+ u32 mu_id;
+ sc_rsrc_t mipi_id, dc_id;
+ sc_ctrl_t mipi_ctrl;
+
+ sci_err = sc_ipc_getMuID(&mu_id);
+ if (sci_err != SC_ERR_NONE) {
+ DRM_DEV_ERROR(dev, "Failed to get MU ID (%d)\n", sci_err);
+ return -ENODEV;
+ }
+ sci_err = sc_ipc_open(&ipc_handle, mu_id);
+ if (sci_err != SC_ERR_NONE) {
+ DRM_DEV_ERROR(dev, "Failed to open IPC (%d)\n", sci_err);
+ return -ENODEV;
+ }
+
+ mipi_id = inst?MIPI_ID(1):MIPI_ID(0);
+ dc_id = (!v2 && inst)?DC_ID(1):DC_ID(0);
+ DRM_DEV_DEBUG_DRIVER(dev, "MIPI ID: %d DC ID: %d\n",
+ mipi_id,
+ dc_id);
+
+ /* Assert DPI and MIPI bits */
+ sci_err = sc_misc_set_control(ipc_handle,
+ mipi_id,
+ SC_C_DPI_RESET,
+ 0);
+ if (sci_err != SC_ERR_NONE) {
+ DRM_DEV_ERROR(dev,
+ "Failed to assert DPI reset (%d)\n",
+ sci_err);
+ ret = -ENODEV;
+ goto err_ipc;
+ }
+
+ sci_err = sc_misc_set_control(ipc_handle,
+ mipi_id,
+ SC_C_MIPI_RESET,
+ 0);
+ if (sci_err != SC_ERR_NONE) {
+ DRM_DEV_ERROR(dev,
+ "Failed to assert MIPI reset (%d)\n",
+ sci_err);
+ ret = -ENODEV;
+ goto err_ipc;
+ }
+
+ if (v2) {
+ sci_err = sc_misc_set_control(ipc_handle,
+ mipi_id, SC_C_MODE, 0);
+ if (sci_err != SC_ERR_NONE)
+ DRM_DEV_ERROR(dev,
+ "Failed to set SC_C_MODE (%d)\n",
+ sci_err);
+ sci_err = sc_misc_set_control(ipc_handle,
+ mipi_id, SC_C_DUAL_MODE, 0);
+ if (sci_err != SC_ERR_NONE)
+ DRM_DEV_ERROR(dev,
+ "Failed to set SC_C_DUAL_MODE (%d)\n",
+ sci_err);
+ sci_err = sc_misc_set_control(ipc_handle,
+ mipi_id, SC_C_PXL_LINK_SEL, 0);
+ if (sci_err != SC_ERR_NONE)
+ DRM_DEV_ERROR(dev,
+ "Failed to set SC_C_PXL_LINK_SEL (%d)\n",
+ sci_err);
+ }
+
+ /* Initialize Pixel Link */
+ mipi_ctrl = (v2 && inst)?PXL_ADDR(2):PXL_ADDR(1);
+ sci_err = sc_misc_set_control(ipc_handle,
+ dc_id,
+ mipi_ctrl,
+ 0);
+ if (sci_err != SC_ERR_NONE) {
+ DRM_DEV_ERROR(dev,
+ "Failed to set SC_C_PXL_LINK_MST%d_ADDR (%d)\n",
+ inst,
+ sci_err);
+ ret = -ENODEV;
+ goto err_ipc;
+ }
+
+ mipi_ctrl = (v2 && inst)?PXL_VLD(2):PXL_VLD(1);
+ sci_err = sc_misc_set_control(ipc_handle,
+ dc_id,
+ mipi_ctrl,
+ 1);
+ if (sci_err != SC_ERR_NONE) {
+ DRM_DEV_ERROR(dev,
+ "Failed to set SC_C_PXL_LINK_MST%d_VLD (%d)\n",
+ inst + 1,
+ sci_err);
+ ret = -ENODEV;
+ goto err_ipc;
+ }
+
+ mipi_ctrl = (v2 && inst)?SYNC_CTRL(1):SYNC_CTRL(0);
+ sci_err = sc_misc_set_control(ipc_handle,
+ dc_id,
+ mipi_ctrl,
+ 1);
+ if (sci_err != SC_ERR_NONE) {
+ DRM_DEV_ERROR(dev,
+ "Failed to set SC_C_SYNC_CTRL%d (%d)\n",
+ inst,
+ sci_err);
+ ret = -ENODEV;
+ goto err_ipc;
+ }
+
+ /* De-Assert DPI and MIPI bits */
+ sci_err = sc_misc_set_control(ipc_handle,
+ mipi_id,
+ SC_C_DPI_RESET,
+ 1);
+ if (sci_err != SC_ERR_NONE) {
+ DRM_DEV_ERROR(dev,
+ "Failed to deassert DPI reset (%d)\n",
+ sci_err);
+ ret = -ENODEV;
+ goto err_ipc;
+ }
+
+ sci_err = sc_misc_set_control(ipc_handle,
+ mipi_id,
+ SC_C_MIPI_RESET,
+ 1);
+ if (sci_err != SC_ERR_NONE) {
+ DRM_DEV_ERROR(dev,
+ "Failed to deassert MIPI reset (%d)\n",
+ sci_err);
+ ret = -ENODEV;
+ goto err_ipc;
+ }
+
+ regmap_write(dsi->csr,
+ dsi->tx_ulps_reg,
+ 0);
+ regmap_write(dsi->csr,
+ dsi->pxl2dpi_reg,
+ DPI_24_BIT);
+
+ sc_ipc_close(ipc_handle);
+ return ret;
+
+err_ipc:
+ sc_ipc_close(ipc_handle);
+ return ret;
+}
+
+static void imx8q_dsi_poweroff(struct imx_mipi_dsi *dsi, bool v2)
+{
+ struct device *dev = dsi->dev;
+ sc_err_t sci_err = 0;
+ sc_ipc_t ipc_handle = 0;
+ u32 mu_id;
+ u32 inst = dsi->instance;
+ sc_rsrc_t mipi_id, dc_id;
+ sc_ctrl_t mipi_ctrl;
+
+ mipi_id = inst?MIPI_ID(1):MIPI_ID(0);
+ dc_id = (!v2 && inst)?DC_ID(1):DC_ID(0);
+
+ /* Deassert DPI and MIPI bits */
+ if (sc_ipc_getMuID(&mu_id) != SC_ERR_NONE ||
+ sc_ipc_open(&ipc_handle, mu_id) != SC_ERR_NONE)
+ return;
+
+ sci_err = sc_misc_set_control(ipc_handle,
+ mipi_id, SC_C_DPI_RESET, 0);
+ if (sci_err != SC_ERR_NONE)
+ DRM_DEV_ERROR(dev,
+ "Failed to deassert DPI reset (%d)\n",
+ sci_err);
+
+ sci_err = sc_misc_set_control(ipc_handle,
+ mipi_id, SC_C_MIPI_RESET, 0);
+ if (sci_err != SC_ERR_NONE)
+ DRM_DEV_ERROR(dev,
+ "Failed to deassert MIPI reset (%d)\n",
+ sci_err);
+
+ mipi_ctrl = (v2 && inst)?SYNC_CTRL(1):SYNC_CTRL(0);
+ sci_err = sc_misc_set_control(ipc_handle,
+ dc_id, mipi_ctrl, 0);
+ if (sci_err != SC_ERR_NONE)
+ DRM_DEV_ERROR(dev,
+ "Failed to reset SC_C_SYNC_CTRL0 (%d)\n",
+ sci_err);
+
+ mipi_ctrl = (v2 && inst)?PXL_VLD(2):PXL_VLD(1);
+ sci_err = sc_misc_set_control(ipc_handle,
+ dc_id, mipi_ctrl, 0);
+ if (sci_err != SC_ERR_NONE)
+ DRM_DEV_ERROR(dev,
+ "Failed to reset SC_C_SYNC_CTRL0 (%d)\n",
+ sci_err);
+
+ sc_ipc_close(ipc_handle);
+}
+
+static int imx8qm_dsi_poweron(struct imx_mipi_dsi *dsi)
+{
+ return imx8q_dsi_poweron(dsi, false);
+}
+
+static void imx8qm_dsi_poweroff(struct imx_mipi_dsi *dsi)
+{
+ return imx8q_dsi_poweroff(dsi, false);
+}
+
+static int imx8qxp_dsi_poweron(struct imx_mipi_dsi *dsi)
+{
+ return imx8q_dsi_poweron(dsi, true);
+}
+
+static void imx8qxp_dsi_poweroff(struct imx_mipi_dsi *dsi)
+{
+ return imx8q_dsi_poweroff(dsi, true);
+}
+
+static int imx8mq_dsi_poweron(struct imx_mipi_dsi *dsi)
+{
+ regmap_update_bits(dsi->reset, SRC_MIPIPHY_RCR,
+ PCLK_RESET_N, PCLK_RESET_N);
+ regmap_update_bits(dsi->reset, SRC_MIPIPHY_RCR,
+ ESC_RESET_N, ESC_RESET_N);
+ regmap_update_bits(dsi->reset, SRC_MIPIPHY_RCR,
+ RESET_BYTE_N, RESET_BYTE_N);
+ regmap_update_bits(dsi->reset, SRC_MIPIPHY_RCR,
+ DPI_RESET_N, DPI_RESET_N);
+
+ return 0;
+}
+
+static void imx8mq_dsi_poweroff(struct imx_mipi_dsi *dsi)
+{
+ regmap_update_bits(dsi->reset, SRC_MIPIPHY_RCR,
+ PCLK_RESET_N, 0);
+ regmap_update_bits(dsi->reset, SRC_MIPIPHY_RCR,
+ ESC_RESET_N, 0);
+ regmap_update_bits(dsi->reset, SRC_MIPIPHY_RCR,
+ RESET_BYTE_N, 0);
+ regmap_update_bits(dsi->reset, SRC_MIPIPHY_RCR,
+ DPI_RESET_N, 0);
+}
+
+static void imx_nwl_dsi_enable(struct imx_mipi_dsi *dsi)
+{
+ struct device *dev = dsi->dev;
+ const struct of_device_id *of_id = of_match_device(imx_nwl_dsi_dt_ids,
+ dev);
+ const struct devtype *devtype = of_id->data;
+ unsigned long min_sleep, max_sleep;
+ int ret;
+
+ if (dsi->enabled)
+ return;
+
+ DRM_DEV_DEBUG_DRIVER(dev, "id = %s\n", (dsi->instance)?"DSI1":"DSI0");
+
+ /*
+ * On some systems we need to wait some time before enabling the
+ * phy_ref clock, in order to allow the parent PLL to become stable
+ */
+ if (dsi->power_on_delay > 20) {
+ msleep(dsi->power_on_delay);
+ } else if (dsi->power_on_delay > 0) {
+ max_sleep = dsi->power_on_delay * 1000;
+ min_sleep = 1000;
+ if (max_sleep > 6000)
+ min_sleep = max_sleep - 5000;
+ usleep_range(min_sleep, max_sleep);
+ }
+
+ request_bus_freq(BUS_FREQ_HIGH);
+
+ imx_nwl_dsi_set_clocks(dsi, true);
+
+ ret = devtype->poweron(dsi);
+ if (ret < 0) {
+ DRM_DEV_ERROR(dev, "Failed to power on DSI (%d)\n", ret);
+ return;
+ }
+
+ dsi->enabled = true;
+}
+
+static void imx_nwl_dsi_disable(struct imx_mipi_dsi *dsi)
+{
+ struct device *dev = dsi->dev;
+ const struct of_device_id *of_id = of_match_device(imx_nwl_dsi_dt_ids,
+ dev);
+ const struct devtype *devtype = of_id->data;
+
+ if (!dsi->enabled)
+ return;
+
+ DRM_DEV_DEBUG_DRIVER(dev, "id = %s\n", (dsi->instance)?"DSI1":"DSI0");
+
+ if (!dsi->no_clk_reset)
+ devtype->poweroff(dsi);
+
+ imx_nwl_dsi_set_clocks(dsi, false);
+
+ release_bus_freq(BUS_FREQ_HIGH);
+
+ dsi->enabled = false;
+}
+
+static void imx_nwl_dsi_encoder_enable(struct drm_encoder *encoder)
+{
+ struct imx_mipi_dsi *dsi = encoder_to_dsi(encoder);
+
+ pm_runtime_get_sync(dsi->dev);
+ imx_nwl_dsi_enable(dsi);
+}
+
+static void imx_nwl_dsi_encoder_disable(struct drm_encoder *encoder)
+{
+ struct imx_mipi_dsi *dsi = encoder_to_dsi(encoder);
+
+ imx_nwl_dsi_disable(dsi);
+ pm_runtime_put_sync(dsi->dev);
+}
+
+static bool imx_nwl_dsi_mode_fixup(struct imx_mipi_dsi *dsi,
+ struct drm_display_mode *mode)
+{
+ unsigned int *flags = &mode->flags;
+
+ DRM_DEV_DEBUG_DRIVER(dsi->dev, "Fixup mode:\n");
+ drm_mode_debug_printmodeline(mode);
+
+ /* Make sure all flags are set-up accordingly */
+ if (dsi->sync_pol) {
+ *flags |= DRM_MODE_FLAG_PHSYNC;
+ *flags |= DRM_MODE_FLAG_PVSYNC;
+ *flags &= ~DRM_MODE_FLAG_NHSYNC;
+ *flags &= ~DRM_MODE_FLAG_NVSYNC;
+ } else {
+ *flags &= ~DRM_MODE_FLAG_PHSYNC;
+ *flags &= ~DRM_MODE_FLAG_PVSYNC;
+ *flags |= DRM_MODE_FLAG_NHSYNC;
+ *flags |= DRM_MODE_FLAG_NVSYNC;
+ }
+
+ return true;
+}
+
+static void imx_nwl_dsi_mode_set(struct imx_mipi_dsi *dsi,
+ struct drm_display_mode *mode)
+{ const char *id;
+ struct clk *clk;
+ size_t i;
+
+ for (i = 0; i < dsi->clk_num; i++) {
+ if (!dsi->clk_config[i].present)
+ continue;
+ id = dsi->clk_config[i].id;
+ clk = dsi->clk_config[i].clk;
+
+ /* Set bypass and pixel clocks to mode clock rate */
+ if (!strcmp(id, CLK_BYPASS) || !strcmp(id, CLK_PIXEL))
+ dsi->clk_config[i].rate = mode->crtc_clock * 1000;
+ }
+
+}
+
+static int imx_nwl_dsi_encoder_atomic_check(struct drm_encoder *encoder,
+ struct drm_crtc_state *crtc_state,
+ struct drm_connector_state *conn_state)
+{
+ struct imx_mipi_dsi *dsi = encoder_to_dsi(encoder);
+ struct imx_crtc_state *imx_crtc_state = to_imx_crtc_state(crtc_state);
+
+ imx_crtc_state->bus_format = MEDIA_BUS_FMT_RGB101010_1X30;
+
+ return !imx_nwl_dsi_mode_fixup(dsi, &crtc_state->adjusted_mode);
+}
+
+static void imx_nwl_dsi_encoder_mode_set(struct drm_encoder *encoder,
+ struct drm_display_mode *mode,
+ struct drm_display_mode *adjusted_mode)
+{
+ struct imx_mipi_dsi *dsi = encoder_to_dsi(encoder);
+
+ imx_nwl_dsi_mode_set(dsi, adjusted_mode);
+}
+
+static const struct drm_encoder_helper_funcs
+imx_nwl_dsi_encoder_helper_funcs = {
+ .enable = imx_nwl_dsi_encoder_enable,
+ .disable = imx_nwl_dsi_encoder_disable,
+ .atomic_check = imx_nwl_dsi_encoder_atomic_check,
+ .mode_set = imx_nwl_dsi_encoder_mode_set,
+};
+
+static void imx_nwl_dsi_encoder_destroy(struct drm_encoder *encoder)
+{
+ drm_encoder_cleanup(encoder);
+}
+
+static const struct drm_encoder_funcs imx_nwl_dsi_encoder_funcs = {
+ .destroy = imx_nwl_dsi_encoder_destroy,
+};
+
+
+static void imx_nwl_dsi_bridge_enable(struct drm_bridge *bridge)
+{
+ struct imx_mipi_dsi *dsi = bridge->driver_private;
+
+ imx_nwl_dsi_enable(dsi);
+ pm_runtime_get_sync(dsi->dev);
+}
+
+static void imx_nwl_dsi_bridge_disable(struct drm_bridge *bridge)
+{
+ struct imx_mipi_dsi *dsi = bridge->driver_private;
+
+ imx_nwl_dsi_disable(dsi);
+ pm_runtime_put_sync(dsi->dev);
+}
+
+static bool imx_nwl_dsi_bridge_mode_fixup(struct drm_bridge *bridge,
+ const struct drm_display_mode *mode,
+ struct drm_display_mode *adjusted)
+{
+ struct imx_mipi_dsi *dsi = bridge->driver_private;
+
+ return imx_nwl_dsi_mode_fixup(dsi, adjusted);
+}
+
+static void imx_nwl_dsi_bridge_mode_set(struct drm_bridge *bridge,
+ struct drm_display_mode *mode,
+ struct drm_display_mode *adjusted)
+{
+ struct imx_mipi_dsi *dsi = bridge->driver_private;
+
+ imx_nwl_dsi_mode_set(dsi, adjusted);
+}
+
+static int imx_nwl_dsi_bridge_attach(struct drm_bridge *bridge)
+{
+ struct imx_mipi_dsi *dsi = bridge->driver_private;
+ struct drm_encoder *encoder = bridge->encoder;
+ int ret = 0;
+
+ DRM_DEV_DEBUG_DRIVER(dsi->dev, "id = %s\n",
+ (dsi->instance)?"DSI1":"DSI0");
+ if (!encoder) {
+ DRM_DEV_ERROR(dsi->dev, "Parent encoder object not found\n");
+ return -ENODEV;
+ }
+
+ /* Attach the next bridge in chain */
+ ret = drm_bridge_attach(encoder, dsi->next_bridge, bridge);
+ if (ret)
+ DRM_DEV_ERROR(dsi->dev, "Failed to attach bridge! (%d)\n",
+ ret);
+
+ return ret;
+}
+
+static void imx_nwl_dsi_bridge_detach(struct drm_bridge *bridge)
+{
+ struct imx_mipi_dsi *dsi = bridge->driver_private;
+
+ DRM_DEV_DEBUG_DRIVER(dsi->dev, "id = %s\n",
+ (dsi->instance)?"DSI1":"DSI0");
+ /*
+ * The next bridge in chain will be automatically detached, there is
+ * no need for us to detach it.
+ */
+}
+
+static const struct drm_bridge_funcs imx_nwl_dsi_bridge_funcs = {
+ .enable = imx_nwl_dsi_bridge_enable,
+ .disable = imx_nwl_dsi_bridge_disable,
+ .mode_fixup = imx_nwl_dsi_bridge_mode_fixup,
+ .mode_set = imx_nwl_dsi_bridge_mode_set,
+ .attach = imx_nwl_dsi_bridge_attach,
+ .detach = imx_nwl_dsi_bridge_detach,
+};
+
+static int imx_nwl_dsi_parse_of(struct device *dev, bool as_bridge)
+{
+ struct device_node *np = dev->of_node;
+ const struct of_device_id *of_id = of_match_device(imx_nwl_dsi_dt_ids,
+ dev);
+ const struct devtype *devtype = of_id->data;
+ struct imx_mipi_dsi *dsi = dev_get_drvdata(dev);
+ struct clk *clk;
+ const char *clk_id;
+ size_t i, clk_config_sz;
+ int id;
+ u32 mux_val;
+ int ret = 0;
+
+ id = of_alias_get_id(np, "mipi_dsi");
+ if (id < 0) {
+ dev_err(dev, "No mipi_dsi alias found!");
+ return id;
+ }
+ if (id > devtype->max_instances - 1) {
+ dev_err(dev, "Too many instances! (cur: %d, max: %d)\n",
+ id, devtype->max_instances);
+ return -ENODEV;
+ }
+ dsi->instance = id;
+
+ dsi->phy = devm_phy_get(dev, "dphy");
+ if (IS_ERR(dsi->phy)) {
+ ret = PTR_ERR(dsi->phy);
+ dev_err(dev, "Could not get PHY (%d)\n", ret);
+ return ret;
+ }
+
+ /* Look for optional clocks */
+ dsi->clk_num = ARRAY_SIZE(devtype->clk_config);
+ dsi->clk_config = devm_kcalloc(dev,
+ dsi->clk_num,
+ sizeof(struct clk_config),
+ GFP_KERNEL);
+ clk_config_sz = dsi->clk_num * sizeof(struct clk_config);
+ memcpy(dsi->clk_config, devtype->clk_config, clk_config_sz);
+
+ for (i = 0; i < dsi->clk_num; i++) {
+ if (!dsi->clk_config[i].present)
+ continue;
+
+ clk_id = dsi->clk_config[i].id;
+ clk = devm_clk_get(dev, clk_id);
+ if (IS_ERR(clk)) {
+ ret = PTR_ERR(clk);
+ dev_err(dev, "Failed to get %s clock (%d)\n",
+ clk_id, ret);
+ return ret;
+ }
+ dev_dbg(dev, "Setup clk %s (rate: %lu)\n",
+ clk_id, clk_get_rate(clk));
+ dsi->clk_config[i].clk = clk;
+ }
+
+ dsi->tx_ulps_reg = devtype->tx_ulps_reg;
+ dsi->pxl2dpi_reg = devtype->pxl2dpi_reg;
+
+ of_property_read_u32(np, "sync-pol", &dsi->sync_pol);
+ of_property_read_u32(np, "pwr-delay", &dsi->power_on_delay);
+
+ /* Look for optional regmaps */
+ dsi->csr = syscon_regmap_lookup_by_phandle(np, "csr");
+ if (IS_ERR(dsi->csr) && (devtype->ext_regs & IMX_REG_CSR)) {
+ ret = PTR_ERR(dsi->csr);
+ dev_err(dev, "Failed to get CSR regmap (%d)\n", ret);
+ return ret;
+ }
+ dsi->reset = syscon_regmap_lookup_by_phandle(np, "src");
+ if (IS_ERR(dsi->reset) && (devtype->ext_regs & IMX_REG_SRC)) {
+ ret = PTR_ERR(dsi->reset);
+ dev_err(dev, "Failed to get SRC regmap (%d)\n", ret);
+ return ret;
+ }
+ dsi->mux_sel = syscon_regmap_lookup_by_phandle(np, "mux-sel");
+ if (IS_ERR(dsi->mux_sel) && (devtype->ext_regs & IMX_REG_GPR)) {
+ ret = PTR_ERR(dsi->mux_sel);
+ dev_err(dev, "Failed to get GPR regmap (%d)\n", ret);
+ return ret;
+ }
+ if (IS_ERR(dsi->mux_sel))
+ return 0;
+
+ mux_val = IMX8MQ_GPR13_MIPI_MUX_SEL;
+ if (as_bridge)
+ mux_val = 0;
+ dev_info(dev, "Using %s as input source\n",
+ (mux_val)?"DCSS":"LCDIF");
+ regmap_update_bits(dsi->mux_sel,
+ IOMUXC_GPR13,
+ IMX8MQ_GPR13_MIPI_MUX_SEL,
+ mux_val);
+
+ dsi->no_clk_reset = of_property_read_bool(np, "no_clk_reset");
+
+ return 0;
+}
+
+static int imx_nwl_dsi_bind(struct device *dev,
+ struct device *master,
+ void *data)
+{
+ struct drm_device *drm = data;
+ struct drm_bridge *next_bridge = NULL;
+ struct imx_mipi_dsi *dsi = dev_get_drvdata(dev);
+ int ret = 0;
+
+ ret = imx_nwl_dsi_parse_of(dev, false);
+ if (ret)
+ return ret;
+
+ DRM_DEV_DEBUG_DRIVER(dev, "id = %s\n", (dsi->instance)?"DSI1":"DSI0");
+
+ /* Re-validate the bridge */
+ if (dsi->next_bridge)
+ next_bridge = of_drm_find_bridge(dsi->next_bridge->of_node);
+ dsi->next_bridge = next_bridge;
+
+ if (!dsi->next_bridge) {
+ dev_warn(dev, "No bridge found, skipping encoder creation\n");
+ return ret;
+ }
+
+ ret = imx_drm_encoder_parse_of(drm, &dsi->encoder, dev->of_node);
+ if (ret)
+ return ret;
+
+ drm_encoder_helper_add(&dsi->encoder,
+ &imx_nwl_dsi_encoder_helper_funcs);
+ ret = drm_encoder_init(drm,
+ &dsi->encoder,
+ &imx_nwl_dsi_encoder_funcs,
+ DRM_MODE_ENCODER_DSI,
+ NULL);
+ if (ret) {
+ DRM_DEV_ERROR(dev, "failed to init DSI encoder (%d)\n", ret);
+ return ret;
+ }
+
+ dsi->next_bridge->encoder = &dsi->encoder;
+ dsi->encoder.bridge = dsi->next_bridge;
+ ret = drm_bridge_attach(&dsi->encoder, dsi->next_bridge, NULL);
+ if (ret)
+ drm_encoder_cleanup(&dsi->encoder);
+
+ return ret;
+}
+
+static void imx_nwl_dsi_unbind(struct device *dev,
+ struct device *master,
+ void *data)
+{
+ struct imx_mipi_dsi *dsi = dev_get_drvdata(dev);
+ struct drm_bridge *next_bridge = NULL;
+
+ DRM_DEV_DEBUG_DRIVER(dev, "id = %s\n", (dsi->instance)?"DSI1":"DSI0");
+
+ /*
+ * At this point, our next bridge in chain might be already removed,
+ * so update it's status.
+ */
+ if (dsi->next_bridge)
+ next_bridge = of_drm_find_bridge(dsi->next_bridge->of_node);
+ dsi->next_bridge = next_bridge;
+
+ if (dsi->enabled)
+ imx_nwl_dsi_encoder_disable(&dsi->encoder);
+
+ if (dsi->encoder.dev)
+ drm_encoder_cleanup(&dsi->encoder);
+
+ pm_runtime_disable(dev);
+}
+
+static const struct component_ops imx_nwl_dsi_component_ops = {
+ .bind = imx_nwl_dsi_bind,
+ .unbind = imx_nwl_dsi_unbind,
+};
+
+static int imx_nwl_dsi_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct device_node *np = dev->of_node;
+ struct device_node *remote_node, *endpoint;
+ int remote_ports = 0;
+ struct imx_mipi_dsi *dsi;
+ int ret = 0;
+
+ if (!np)
+ return -ENODEV;
+
+ dsi = devm_kzalloc(dev, sizeof(*dsi), GFP_KERNEL);
+ if (!dsi)
+ return -ENOMEM;
+
+ /* Search for next bridge (usually the DSI HOST bridge) */
+ endpoint = of_graph_get_next_endpoint(np, NULL);
+ while (endpoint && !dsi->next_bridge) {
+ remote_node = of_graph_get_remote_port_parent(endpoint);
+ if (!remote_node) {
+ dev_err(dev, "No endpoint found!\n");
+ return -ENODEV;
+ }
+
+ dsi->next_bridge = of_drm_find_bridge(remote_node);
+ of_node_put(remote_node);
+ endpoint = of_graph_get_next_endpoint(np, endpoint);
+ if (!of_device_is_available(remote_node))
+ continue;
+ remote_ports++;
+ };
+
+ /*
+ * Normally, we should have two remote ports: one is our input source,
+ * while the second is the NWL host bridge. This bridge can be disabled
+ * if the connector fails to find a physical device. In this case, we
+ * should continue and do nothing, so that DRM master can bind all the
+ * components.
+ */
+ if (!dsi->next_bridge && remote_ports == 2) {
+ dev_warn(dev, "Waiting for DSI host bridge\n");
+ return -EPROBE_DEFER;
+ }
+
+ dsi->dev = dev;
+ dev_set_drvdata(dev, dsi);
+
+ pm_runtime_enable(dev);
+
+ if (of_property_read_bool(dev->of_node, "as_bridge")) {
+ ret = imx_nwl_dsi_parse_of(dev, true);
+ if (ret)
+ return ret;
+ /* Create our bridge */
+ dsi->bridge.driver_private = dsi;
+ dsi->bridge.funcs = &imx_nwl_dsi_bridge_funcs;
+ dsi->bridge.of_node = np;
+
+ ret = drm_bridge_add(&dsi->bridge);
+ if (ret) {
+ dev_err(dev, "Failed to add imx-nwl-dsi bridge (%d)\n",
+ ret);
+ return ret;
+ }
+ dev_info(dev, "Added drm bridge!");
+ return 0;
+ }
+
+ return component_add(&pdev->dev, &imx_nwl_dsi_component_ops);
+}
+
+static int imx_nwl_dsi_remove(struct platform_device *pdev)
+{
+ component_del(&pdev->dev, &imx_nwl_dsi_component_ops);
+
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int imx_nwl_suspend(struct device *dev)
+{
+ struct imx_mipi_dsi *dsi = dev_get_drvdata(dev);
+
+ if (!dsi->enabled)
+ return 0;
+
+ if (dsi->next_bridge)
+ drm_bridge_disable(dsi->next_bridge);
+ imx_nwl_dsi_disable(dsi);
+ dsi->suspended = true;
+
+ return 0;
+}
+
+static int imx_nwl_resume(struct device *dev)
+{
+ struct imx_mipi_dsi *dsi = dev_get_drvdata(dev);
+
+ if (!dsi->suspended)
+ return 0;
+
+ imx_nwl_dsi_enable(dsi);
+ if (dsi->next_bridge)
+ drm_bridge_enable(dsi->next_bridge);
+ dsi->suspended = false;
+
+ return 0;
+}
+
+#endif
+
+static const struct dev_pm_ops imx_nwl_pm_ops = {
+ SET_RUNTIME_PM_OPS(imx_nwl_suspend, imx_nwl_resume, NULL)
+ SET_SYSTEM_SLEEP_PM_OPS(imx_nwl_suspend, imx_nwl_resume)
+};
+
+static struct platform_driver imx_nwl_dsi_driver = {
+ .probe = imx_nwl_dsi_probe,
+ .remove = imx_nwl_dsi_remove,
+ .driver = {
+ .of_match_table = imx_nwl_dsi_dt_ids,
+ .name = DRIVER_NAME,
+ .pm = &imx_nwl_pm_ops,
+ },
+};
+
+module_platform_driver(imx_nwl_dsi_driver);
+
+MODULE_AUTHOR("NXP Semiconductor");
+MODULE_DESCRIPTION("i.MX Northwest Logic MIPI-DSI driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:" DRIVER_NAME);
diff --git a/drivers/gpu/drm/imx/sec_mipi_dphy_ln14lpp.h b/drivers/gpu/drm/imx/sec_mipi_dphy_ln14lpp.h
new file mode 100644
index 000000000000..b302ed064e25
--- /dev/null
+++ b/drivers/gpu/drm/imx/sec_mipi_dphy_ln14lpp.h
@@ -0,0 +1,227 @@
+/*
+ * Copyright 2018 NXP
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __SEC_DSIM_DPHY_LN14LPP_H__
+#define __SEC_DSIM_DPHY_LN14LPP_H__
+
+#include <drm/bridge/sec_mipi_dsim.h>
+
+/* descending order based on 'bit_clk' value */
+static const struct sec_mipi_dsim_dphy_timing dphy_timing_ln14lpp_v1p2[] = {
+ { DSIM_DPHY_TIMING(2100, 19, 91, 22, 19, 20, 35, 22, 15, 26), },
+ { DSIM_DPHY_TIMING(2090, 19, 91, 22, 19, 19, 35, 22, 15, 26), },
+ { DSIM_DPHY_TIMING(2080, 19, 91, 21, 18, 19, 35, 22, 15, 26), },
+ { DSIM_DPHY_TIMING(2070, 18, 90, 21, 18, 19, 35, 22, 15, 25), },
+ { DSIM_DPHY_TIMING(2060, 18, 90, 21, 18, 19, 34, 22, 15, 25), },
+ { DSIM_DPHY_TIMING(2050, 18, 89, 21, 18, 19, 34, 22, 15, 25), },
+ { DSIM_DPHY_TIMING(2040, 18, 89, 21, 18, 19, 34, 21, 15, 25), },
+ { DSIM_DPHY_TIMING(2030, 18, 88, 21, 18, 19, 34, 21, 15, 25), },
+ { DSIM_DPHY_TIMING(2020, 18, 88, 21, 18, 19, 34, 21, 15, 25), },
+ { DSIM_DPHY_TIMING(2010, 18, 87, 21, 18, 19, 34, 21, 15, 25), },
+ { DSIM_DPHY_TIMING(2000, 18, 87, 21, 18, 19, 33, 21, 15, 25), },
+ { DSIM_DPHY_TIMING(1990, 18, 87, 21, 18, 18, 33, 21, 14, 24), },
+ { DSIM_DPHY_TIMING(1980, 18, 86, 21, 18, 18, 33, 21, 14, 24), },
+ { DSIM_DPHY_TIMING(1970, 17, 86, 21, 17, 18, 33, 21, 14, 24), },
+ { DSIM_DPHY_TIMING(1960, 17, 85, 21, 17, 18, 33, 21, 14, 24), },
+ { DSIM_DPHY_TIMING(1950, 17, 85, 21, 17, 18, 32, 21, 14, 24), },
+ { DSIM_DPHY_TIMING(1940, 17, 84, 20, 17, 18, 32, 21, 14, 24), },
+ { DSIM_DPHY_TIMING(1930, 17, 84, 20, 17, 18, 32, 20, 14, 24), },
+ { DSIM_DPHY_TIMING(1920, 17, 84, 20, 17, 18, 32, 20, 14, 24), },
+ { DSIM_DPHY_TIMING(1910, 17, 83, 20, 17, 18, 32, 20, 14, 23), },
+ { DSIM_DPHY_TIMING(1900, 17, 83, 20, 17, 18, 32, 20, 14, 23), },
+ { DSIM_DPHY_TIMING(1890, 17, 82, 20, 17, 18, 31, 20, 14, 23), },
+ { DSIM_DPHY_TIMING(1880, 17, 82, 20, 17, 17, 31, 20, 14, 23), },
+ { DSIM_DPHY_TIMING(1870, 17, 81, 20, 17, 17, 31, 20, 14, 23), },
+ { DSIM_DPHY_TIMING(1860, 16, 81, 20, 17, 17, 31, 20, 13, 23), },
+ { DSIM_DPHY_TIMING(1850, 16, 80, 20, 16, 17, 31, 20, 13, 23), },
+ { DSIM_DPHY_TIMING(1840, 16, 80, 20, 16, 17, 30, 20, 13, 23), },
+ { DSIM_DPHY_TIMING(1830, 16, 80, 20, 16, 17, 30, 20, 13, 22), },
+ { DSIM_DPHY_TIMING(1820, 16, 79, 20, 16, 17, 30, 19, 13, 22), },
+ { DSIM_DPHY_TIMING(1810, 16, 79, 19, 16, 17, 30, 19, 13, 22), },
+ { DSIM_DPHY_TIMING(1800, 16, 78, 19, 16, 17, 30, 19, 13, 22), },
+ { DSIM_DPHY_TIMING(1790, 16, 78, 19, 16, 17, 30, 19, 13, 22), },
+ { DSIM_DPHY_TIMING(1780, 16, 77, 19, 16, 16, 29, 19, 13, 22), },
+ { DSIM_DPHY_TIMING(1770, 16, 77, 19, 16, 16, 29, 19, 13, 22), },
+ { DSIM_DPHY_TIMING(1760, 16, 77, 19, 16, 16, 29, 19, 13, 22), },
+ { DSIM_DPHY_TIMING(1750, 15, 76, 19, 16, 16, 29, 19, 13, 21), },
+ { DSIM_DPHY_TIMING(1740, 15, 76, 19, 15, 16, 29, 19, 13, 21), },
+ { DSIM_DPHY_TIMING(1730, 15, 75, 19, 15, 16, 28, 19, 12, 21), },
+ { DSIM_DPHY_TIMING(1720, 15, 75, 19, 15, 16, 28, 19, 12, 21), },
+ { DSIM_DPHY_TIMING(1710, 15, 74, 19, 15, 16, 28, 18, 12, 21), },
+ { DSIM_DPHY_TIMING(1700, 15, 74, 19, 15, 16, 28, 18, 12, 21), },
+ { DSIM_DPHY_TIMING(1690, 15, 73, 19, 15, 16, 28, 18, 12, 21), },
+ { DSIM_DPHY_TIMING(1680, 15, 73, 18, 15, 16, 28, 18, 12, 21), },
+ { DSIM_DPHY_TIMING(1670, 15, 73, 18, 15, 15, 27, 18, 12, 20), },
+ { DSIM_DPHY_TIMING(1660, 15, 72, 18, 15, 15, 27, 18, 12, 20), },
+ { DSIM_DPHY_TIMING(1650, 14, 72, 18, 15, 15, 27, 18, 12, 20), },
+ { DSIM_DPHY_TIMING(1640, 14, 71, 18, 15, 15, 27, 18, 12, 20), },
+ { DSIM_DPHY_TIMING(1630, 14, 71, 18, 15, 15, 27, 18, 12, 20), },
+ { DSIM_DPHY_TIMING(1620, 14, 70, 18, 14, 15, 26, 18, 12, 20), },
+ { DSIM_DPHY_TIMING(1610, 14, 70, 18, 14, 15, 26, 17, 12, 20), },
+ { DSIM_DPHY_TIMING(1600, 14, 70, 18, 14, 15, 26, 17, 12, 20), },
+ { DSIM_DPHY_TIMING(1590, 14, 69, 18, 14, 15, 26, 17, 11, 19), },
+ { DSIM_DPHY_TIMING(1580, 14, 69, 18, 14, 15, 26, 17, 11, 19), },
+ { DSIM_DPHY_TIMING(1570, 14, 68, 18, 14, 15, 26, 17, 11, 19), },
+ { DSIM_DPHY_TIMING(1560, 14, 68, 18, 14, 14, 25, 17, 11, 19), },
+ { DSIM_DPHY_TIMING(1550, 14, 67, 18, 14, 14, 25, 17, 11, 19), },
+ { DSIM_DPHY_TIMING(1540, 13, 67, 17, 14, 14, 25, 17, 11, 19), },
+ { DSIM_DPHY_TIMING(1530, 13, 66, 17, 14, 14, 25, 17, 11, 19), },
+ { DSIM_DPHY_TIMING(1520, 13, 66, 17, 14, 14, 25, 17, 11, 19), },
+ { DSIM_DPHY_TIMING(1510, 13, 66, 17, 13, 14, 24, 17, 11, 18), },
+ { DSIM_DPHY_TIMING(1500, 13, 65, 17, 13, 14, 24, 16, 11, 18), },
+ { DSIM_DPHY_TIMING(1490, 13, 65, 17, 13, 14, 24, 16, 11, 18), },
+ { DSIM_DPHY_TIMING(1480, 13, 64, 17, 13, 14, 24, 16, 11, 18), },
+ { DSIM_DPHY_TIMING(1470, 13, 64, 17, 13, 14, 24, 16, 11, 18), },
+ { DSIM_DPHY_TIMING(1460, 13, 63, 17, 13, 13, 24, 16, 10, 18), },
+ { DSIM_DPHY_TIMING(1450, 13, 63, 17, 13, 13, 23, 16, 10, 18), },
+ { DSIM_DPHY_TIMING(1440, 13, 63, 17, 13, 13, 23, 16, 10, 18), },
+ { DSIM_DPHY_TIMING(1430, 12, 62, 17, 13, 13, 23, 16, 10, 17), },
+ { DSIM_DPHY_TIMING(1420, 12, 62, 17, 13, 13, 23, 16, 10, 17), },
+ { DSIM_DPHY_TIMING(1410, 12, 61, 16, 13, 13, 23, 16, 10, 17), },
+ { DSIM_DPHY_TIMING(1400, 12, 61, 16, 13, 13, 23, 16, 10, 17), },
+ { DSIM_DPHY_TIMING(1390, 12, 60, 16, 12, 13, 22, 15, 10, 17), },
+ { DSIM_DPHY_TIMING(1380, 12, 60, 16, 12, 13, 22, 15, 10, 17), },
+ { DSIM_DPHY_TIMING(1370, 12, 59, 16, 12, 13, 22, 15, 10, 17), },
+ { DSIM_DPHY_TIMING(1360, 12, 59, 16, 12, 13, 22, 15, 10, 17), },
+ { DSIM_DPHY_TIMING(1350, 12, 59, 16, 12, 12, 22, 15, 10, 16), },
+ { DSIM_DPHY_TIMING(1340, 12, 58, 16, 12, 12, 21, 15, 10, 16), },
+ { DSIM_DPHY_TIMING(1330, 11, 58, 16, 12, 12, 21, 15, 9, 16), },
+ { DSIM_DPHY_TIMING(1320, 11, 57, 16, 12, 12, 21, 15, 9, 16), },
+ { DSIM_DPHY_TIMING(1310, 11, 57, 16, 12, 12, 21, 15, 9, 16), },
+ { DSIM_DPHY_TIMING(1300, 11, 56, 16, 12, 12, 21, 15, 9, 16), },
+ { DSIM_DPHY_TIMING(1290, 11, 56, 16, 12, 12, 21, 15, 9, 16), },
+ { DSIM_DPHY_TIMING(1280, 11, 56, 15, 11, 12, 20, 14, 9, 16), },
+ { DSIM_DPHY_TIMING(1270, 11, 55, 15, 11, 12, 20, 14, 9, 15), },
+ { DSIM_DPHY_TIMING(1260, 11, 55, 15, 11, 12, 20, 14, 9, 15), },
+ { DSIM_DPHY_TIMING(1250, 11, 54, 15, 11, 11, 20, 14, 9, 15), },
+ { DSIM_DPHY_TIMING(1240, 11, 54, 15, 11, 11, 20, 14, 9, 15), },
+ { DSIM_DPHY_TIMING(1230, 11, 53, 15, 11, 11, 19, 14, 9, 15), },
+ { DSIM_DPHY_TIMING(1220, 10, 53, 15, 11, 11, 19, 14, 9, 15), },
+ { DSIM_DPHY_TIMING(1210, 10, 52, 15, 11, 11, 19, 14, 9, 15), },
+ { DSIM_DPHY_TIMING(1200, 10, 52, 15, 11, 11, 19, 14, 9, 15), },
+ { DSIM_DPHY_TIMING(1190, 10, 52, 15, 11, 11, 19, 14, 8, 14), },
+ { DSIM_DPHY_TIMING(1180, 10, 51, 15, 11, 11, 19, 13, 8, 14), },
+ { DSIM_DPHY_TIMING(1170, 10, 51, 15, 10, 11, 18, 13, 8, 14), },
+ { DSIM_DPHY_TIMING(1160, 10, 50, 15, 10, 11, 18, 13, 8, 14), },
+ { DSIM_DPHY_TIMING(1150, 10, 50, 15, 10, 11, 18, 13, 8, 14), },
+ { DSIM_DPHY_TIMING(1140, 10, 49, 14, 10, 10, 18, 13, 8, 14), },
+ { DSIM_DPHY_TIMING(1130, 10, 49, 14, 10, 10, 18, 13, 8, 14), },
+ { DSIM_DPHY_TIMING(1120, 10, 49, 14, 10, 10, 17, 13, 8, 14), },
+ { DSIM_DPHY_TIMING(1110, 9, 48, 14, 10, 10, 17, 13, 8, 13), },
+ { DSIM_DPHY_TIMING(1100, 9, 48, 14, 10, 10, 17, 13, 8, 13), },
+ { DSIM_DPHY_TIMING(1090, 9, 47, 14, 10, 10, 17, 13, 8, 13), },
+ { DSIM_DPHY_TIMING(1080, 9, 47, 14, 10, 10, 17, 13, 8, 13), },
+ { DSIM_DPHY_TIMING(1070, 9, 46, 14, 10, 10, 17, 12, 8, 13), },
+ { DSIM_DPHY_TIMING(1060, 9, 46, 14, 10, 10, 16, 12, 7, 13), },
+ { DSIM_DPHY_TIMING(1050, 9, 45, 14, 9, 10, 16, 12, 7, 13), },
+ { DSIM_DPHY_TIMING(1040, 9, 45, 14, 9, 10, 16, 12, 7, 13), },
+ { DSIM_DPHY_TIMING(1030, 9, 45, 14, 9, 9, 16, 12, 7, 12), },
+ { DSIM_DPHY_TIMING(1020, 9, 44, 14, 9, 9, 16, 12, 7, 12), },
+ { DSIM_DPHY_TIMING(1010, 8, 44, 13, 9, 9, 15, 12, 7, 12), },
+ { DSIM_DPHY_TIMING(1000, 8, 43, 13, 9, 9, 15, 12, 7, 12), },
+ { DSIM_DPHY_TIMING( 990, 8, 43, 13, 9, 9, 15, 12, 7, 12), },
+ { DSIM_DPHY_TIMING( 980, 8, 42, 13, 9, 9, 15, 12, 7, 12), },
+ { DSIM_DPHY_TIMING( 970, 8, 42, 13, 9, 9, 15, 12, 7, 12), },
+ { DSIM_DPHY_TIMING( 960, 8, 42, 13, 9, 9, 15, 11, 7, 12), },
+ { DSIM_DPHY_TIMING( 950, 8, 41, 13, 9, 9, 14, 11, 7, 11), },
+ { DSIM_DPHY_TIMING( 940, 8, 41, 13, 8, 9, 14, 11, 7, 11), },
+ { DSIM_DPHY_TIMING( 930, 8, 40, 13, 8, 8, 14, 11, 6, 11), },
+ { DSIM_DPHY_TIMING( 920, 8, 40, 13, 8, 8, 14, 11, 6, 11), },
+ { DSIM_DPHY_TIMING( 910, 8, 39, 13, 8, 8, 14, 11, 6, 11), },
+ { DSIM_DPHY_TIMING( 900, 7, 39, 13, 8, 8, 13, 11, 6, 11), },
+ { DSIM_DPHY_TIMING( 890, 7, 38, 13, 8, 8, 13, 11, 6, 11), },
+ { DSIM_DPHY_TIMING( 880, 7, 38, 12, 8, 8, 13, 11, 6, 11), },
+ { DSIM_DPHY_TIMING( 870, 7, 38, 12, 8, 8, 13, 11, 6, 10), },
+ { DSIM_DPHY_TIMING( 860, 7, 37, 12, 8, 8, 13, 11, 6, 10), },
+ { DSIM_DPHY_TIMING( 850, 7, 37, 12, 8, 8, 13, 10, 6, 10), },
+ { DSIM_DPHY_TIMING( 840, 7, 36, 12, 8, 8, 12, 10, 6, 10), },
+ { DSIM_DPHY_TIMING( 830, 7, 36, 12, 8, 8, 12, 10, 6, 10), },
+ { DSIM_DPHY_TIMING( 820, 7, 35, 12, 7, 7, 12, 10, 6, 10), },
+ { DSIM_DPHY_TIMING( 810, 7, 35, 12, 7, 7, 12, 10, 6, 10), },
+ { DSIM_DPHY_TIMING( 800, 7, 35, 12, 7, 7, 12, 10, 6, 10), },
+ { DSIM_DPHY_TIMING( 790, 6, 34, 12, 7, 7, 11, 10, 5, 9), },
+ { DSIM_DPHY_TIMING( 780, 6, 34, 12, 7, 7, 11, 10, 5, 9), },
+ { DSIM_DPHY_TIMING( 770, 6, 33, 12, 7, 7, 11, 10, 5, 9), },
+ { DSIM_DPHY_TIMING( 760, 6, 33, 12, 7, 7, 11, 10, 5, 9), },
+ { DSIM_DPHY_TIMING( 750, 6, 32, 12, 7, 7, 11, 9, 5, 9), },
+ { DSIM_DPHY_TIMING( 740, 6, 32, 11, 7, 7, 11, 9, 5, 9), },
+ { DSIM_DPHY_TIMING( 730, 6, 31, 11, 7, 7, 10, 9, 5, 9), },
+ { DSIM_DPHY_TIMING( 720, 6, 31, 11, 7, 6, 10, 9, 5, 9), },
+ { DSIM_DPHY_TIMING( 710, 6, 31, 11, 6, 6, 10, 9, 5, 8), },
+ { DSIM_DPHY_TIMING( 700, 6, 30, 11, 6, 6, 10, 9, 5, 8), },
+ { DSIM_DPHY_TIMING( 690, 5, 30, 11, 6, 6, 10, 9, 5, 8), },
+ { DSIM_DPHY_TIMING( 680, 5, 29, 11, 6, 6, 9, 9, 5, 8), },
+ { DSIM_DPHY_TIMING( 670, 5, 29, 11, 6, 6, 9, 9, 5, 8), },
+ { DSIM_DPHY_TIMING( 660, 5, 28, 11, 6, 6, 9, 9, 4, 8), },
+ { DSIM_DPHY_TIMING( 650, 5, 28, 11, 6, 6, 9, 9, 4, 8), },
+ { DSIM_DPHY_TIMING( 640, 5, 28, 11, 6, 6, 9, 8, 4, 8), },
+ { DSIM_DPHY_TIMING( 630, 5, 27, 11, 6, 6, 9, 8, 4, 7), },
+ { DSIM_DPHY_TIMING( 620, 5, 27, 11, 6, 6, 8, 8, 4, 7), },
+ { DSIM_DPHY_TIMING( 610, 5, 26, 10, 6, 5, 8, 8, 4, 7), },
+ { DSIM_DPHY_TIMING( 600, 5, 26, 10, 6, 5, 8, 8, 4, 7), },
+ { DSIM_DPHY_TIMING( 590, 5, 25, 10, 5, 5, 8, 8, 4, 7), },
+ { DSIM_DPHY_TIMING( 580, 4, 25, 10, 5, 5, 8, 8, 4, 7), },
+ { DSIM_DPHY_TIMING( 570, 4, 24, 10, 5, 5, 7, 8, 4, 7), },
+ { DSIM_DPHY_TIMING( 560, 4, 24, 10, 5, 5, 7, 8, 4, 7), },
+ { DSIM_DPHY_TIMING( 550, 4, 24, 10, 5, 5, 7, 8, 4, 6), },
+ { DSIM_DPHY_TIMING( 540, 4, 23, 10, 5, 5, 7, 8, 4, 6), },
+ { DSIM_DPHY_TIMING( 530, 4, 23, 10, 5, 5, 7, 7, 3, 6), },
+ { DSIM_DPHY_TIMING( 520, 4, 22, 10, 5, 5, 7, 7, 3, 6), },
+ { DSIM_DPHY_TIMING( 510, 4, 22, 10, 5, 5, 6, 7, 3, 6), },
+ { DSIM_DPHY_TIMING( 500, 4, 21, 10, 5, 4, 6, 7, 3, 6), },
+ { DSIM_DPHY_TIMING( 490, 4, 21, 10, 5, 4, 6, 7, 3, 6), },
+ { DSIM_DPHY_TIMING( 480, 4, 21, 9, 4, 4, 6, 7, 3, 6), },
+ { DSIM_DPHY_TIMING( 470, 3, 20, 9, 4, 4, 6, 7, 3, 5), },
+ { DSIM_DPHY_TIMING( 460, 3, 20, 9, 4, 4, 5, 7, 3, 5), },
+ { DSIM_DPHY_TIMING( 450, 3, 19, 9, 4, 4, 5, 7, 3, 5), },
+ { DSIM_DPHY_TIMING( 440, 3, 19, 9, 4, 4, 5, 7, 3, 5), },
+ { DSIM_DPHY_TIMING( 430, 3, 18, 9, 4, 4, 5, 7, 3, 5), },
+ { DSIM_DPHY_TIMING( 420, 3, 18, 9, 4, 4, 5, 6, 3, 5), },
+ { DSIM_DPHY_TIMING( 410, 3, 17, 9, 4, 4, 5, 6, 3, 5), },
+ { DSIM_DPHY_TIMING( 400, 3, 17, 9, 4, 3, 4, 6, 3, 5), },
+ { DSIM_DPHY_TIMING( 390, 3, 17, 9, 4, 3, 4, 6, 2, 4), },
+ { DSIM_DPHY_TIMING( 380, 3, 16, 9, 4, 3, 4, 6, 2, 4), },
+ { DSIM_DPHY_TIMING( 370, 2, 16, 9, 3, 3, 4, 6, 2, 4), },
+ { DSIM_DPHY_TIMING( 360, 2, 15, 9, 3, 3, 4, 6, 2, 4), },
+ { DSIM_DPHY_TIMING( 350, 2, 15, 9, 3, 3, 3, 6, 2, 4), },
+ { DSIM_DPHY_TIMING( 340, 2, 14, 8, 3, 3, 3, 6, 2, 4), },
+ { DSIM_DPHY_TIMING( 330, 2, 14, 8, 3, 3, 3, 6, 2, 4), },
+ { DSIM_DPHY_TIMING( 320, 2, 14, 8, 3, 3, 3, 5, 2, 4), },
+ { DSIM_DPHY_TIMING( 310, 2, 13, 8, 3, 3, 3, 5, 2, 3), },
+ { DSIM_DPHY_TIMING( 300, 2, 13, 8, 3, 3, 3, 5, 2, 3), },
+ { DSIM_DPHY_TIMING( 290, 2, 12, 8, 3, 2, 2, 5, 2, 3), },
+ { DSIM_DPHY_TIMING( 280, 2, 12, 8, 3, 2, 2, 5, 2, 3), },
+ { DSIM_DPHY_TIMING( 270, 2, 11, 8, 3, 2, 2, 5, 2, 3), },
+ { DSIM_DPHY_TIMING( 260, 1, 11, 8, 3, 2, 2, 5, 1, 3), },
+ { DSIM_DPHY_TIMING( 250, 1, 10, 8, 2, 2, 2, 5, 1, 3), },
+ { DSIM_DPHY_TIMING( 240, 1, 9, 8, 2, 2, 1, 5, 1, 3), },
+ { DSIM_DPHY_TIMING( 230, 1, 8, 8, 2, 2, 1, 5, 1, 2), },
+ { DSIM_DPHY_TIMING( 220, 1, 8, 8, 2, 2, 1, 5, 1, 2), },
+ { DSIM_DPHY_TIMING( 210, 1, 7, 7, 2, 2, 1, 4, 1, 2), },
+ { DSIM_DPHY_TIMING( 200, 1, 7, 7, 2, 2, 1, 4, 1, 2), },
+ { DSIM_DPHY_TIMING( 190, 1, 7, 7, 2, 1, 1, 4, 1, 2), },
+ { DSIM_DPHY_TIMING( 180, 1, 6, 7, 2, 1, 0, 4, 1, 2), },
+ { DSIM_DPHY_TIMING( 170, 1, 6, 7, 2, 1, 0, 4, 1, 2), },
+ { DSIM_DPHY_TIMING( 160, 1, 6, 7, 2, 1, 0, 4, 1, 2), },
+ { DSIM_DPHY_TIMING( 150, 0, 5, 7, 2, 1, 0, 4, 1, 1), },
+ { DSIM_DPHY_TIMING( 140, 0, 5, 7, 1, 1, 0, 4, 1, 1), },
+ { DSIM_DPHY_TIMING( 130, 0, 4, 7, 1, 1, 0, 4, 0, 1), },
+ { DSIM_DPHY_TIMING( 120, 0, 4, 7, 1, 1, 0, 4, 0, 1), },
+ { DSIM_DPHY_TIMING( 110, 0, 3, 7, 1, 0, 0, 4, 0, 1), },
+ { DSIM_DPHY_TIMING( 100, 0, 3, 7, 1, 0, 0, 3, 0, 1), },
+ { DSIM_DPHY_TIMING( 90, 0, 2, 7, 1, 0, 0, 3, 0, 1), },
+ { DSIM_DPHY_TIMING( 80, 0, 2, 6, 1, 0, 0, 3, 0, 1), },
+};
+
+#endif
diff --git a/drivers/gpu/drm/imx/sec_mipi_dsim-imx.c b/drivers/gpu/drm/imx/sec_mipi_dsim-imx.c
new file mode 100644
index 000000000000..427fb1aa39dc
--- /dev/null
+++ b/drivers/gpu/drm/imx/sec_mipi_dsim-imx.c
@@ -0,0 +1,390 @@
+/*
+ * Samsung MIPI DSI Host Controller on IMX
+ *
+ * Copyright 2018-2019 NXP
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/busfreq-imx.h>
+#include <linux/clk.h>
+#include <linux/component.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/mfd/syscon.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/regmap.h>
+#include <drm/bridge/sec_mipi_dsim.h>
+#include <drm/drm_bridge.h>
+#include <drm/drm_encoder.h>
+#include <drm/drm_modeset_helper_vtables.h>
+
+#include "imx-drm.h"
+#include "sec_mipi_dphy_ln14lpp.h"
+#include "sec_mipi_pll_1432x.h"
+
+#define DRIVER_NAME "imx_sec_dsim_drv"
+
+/* Dispmix Control & GPR Registers */
+#define DISPLAY_MIX_SFT_RSTN_CSR 0X00
+ #define MIPI_DSI_I_PRESETn_SFT_EN BIT(5)
+#define DISPLAY_MIX_CLK_EN_CSR 0x04
+ #define MIPI_DSI_PCLK_SFT_EN BIT(8)
+ #define MIPI_DSI_CLKREF_SFT_EN BIT(9)
+#define GPR_MIPI_RESET_DIV 0x08
+ /* Clock & Data lanes reset: Active Low */
+ #define GPR_MIPI_S_RESETN BIT(16)
+ #define GPR_MIPI_M_RESETN BIT(17)
+
+struct imx_sec_dsim_device {
+ struct device *dev;
+ struct drm_encoder encoder;
+ struct regmap *gpr;
+
+ atomic_t rpm_suspended;
+};
+
+#define enc_to_dsim(enc) container_of(enc, struct imx_sec_dsim_device, encoder)
+
+static struct imx_sec_dsim_device *dsim_dev;
+
+#if CONFIG_PM
+static int imx_sec_dsim_runtime_suspend(struct device *dev);
+static int imx_sec_dsim_runtime_resume(struct device *dev);
+#else
+static int imx_sec_dsim_runtime_suspend(struct device *dev)
+{
+ return 0;
+}
+static int imx_sec_dsim_runtime_resume(struct device *dev)
+{
+ return 0;
+}
+#endif
+
+static void disp_mix_dsim_soft_reset_release(struct regmap *gpr, bool release)
+{
+ if (release)
+ /* release dsi blk reset */
+ regmap_update_bits(gpr, DISPLAY_MIX_SFT_RSTN_CSR,
+ MIPI_DSI_I_PRESETn_SFT_EN,
+ MIPI_DSI_I_PRESETn_SFT_EN);
+ else
+ regmap_update_bits(gpr, DISPLAY_MIX_SFT_RSTN_CSR,
+ MIPI_DSI_I_PRESETn_SFT_EN,
+ 0x0);
+}
+
+static void disp_mix_dsim_clks_enable(struct regmap *gpr, bool enable)
+{
+ if (enable)
+ regmap_update_bits(gpr, DISPLAY_MIX_CLK_EN_CSR,
+ MIPI_DSI_PCLK_SFT_EN | MIPI_DSI_CLKREF_SFT_EN,
+ MIPI_DSI_PCLK_SFT_EN | MIPI_DSI_CLKREF_SFT_EN);
+ else
+ regmap_update_bits(gpr, DISPLAY_MIX_CLK_EN_CSR,
+ MIPI_DSI_PCLK_SFT_EN | MIPI_DSI_CLKREF_SFT_EN,
+ 0x0);
+}
+
+static void imx_sec_dsim_lanes_reset(struct regmap *gpr, bool reset)
+{
+ if (!reset)
+ /* release lanes reset */
+ regmap_update_bits(gpr, GPR_MIPI_RESET_DIV,
+ GPR_MIPI_M_RESETN,
+ GPR_MIPI_M_RESETN);
+ else
+ /* reset lanes */
+ regmap_update_bits(gpr, GPR_MIPI_RESET_DIV,
+ GPR_MIPI_M_RESETN,
+ 0x0);
+}
+
+static void imx_sec_dsim_encoder_helper_enable(struct drm_encoder *encoder)
+{
+ struct imx_sec_dsim_device *dsim_dev = enc_to_dsim(encoder);
+
+ pm_runtime_get_sync(dsim_dev->dev);
+
+ imx_sec_dsim_lanes_reset(dsim_dev->gpr, false);
+}
+
+static void imx_sec_dsim_encoder_helper_disable(struct drm_encoder *encoder)
+{
+ struct imx_sec_dsim_device *dsim_dev = enc_to_dsim(encoder);
+
+ imx_sec_dsim_lanes_reset(dsim_dev->gpr, true);
+
+ pm_runtime_put_sync(dsim_dev->dev);
+}
+
+static int imx_sec_dsim_encoder_helper_atomic_check(struct drm_encoder *encoder,
+ struct drm_crtc_state *crtc_state,
+ struct drm_connector_state *conn_state)
+{
+ int i, ret;
+ u32 bus_format;
+ unsigned int num_bus_formats;
+ struct imx_sec_dsim_device *dsim_dev = enc_to_dsim(encoder);
+ struct drm_bridge *bridge = encoder->bridge;
+ struct drm_display_mode *adjusted_mode = &crtc_state->adjusted_mode;
+ struct imx_crtc_state *imx_crtc_state = to_imx_crtc_state(crtc_state);
+ struct drm_display_info *display_info = &conn_state->connector->display_info;
+
+ num_bus_formats = display_info->num_bus_formats;
+ if (unlikely(!num_bus_formats))
+ dev_warn(dsim_dev->dev, "no bus formats assigned by connector\n");
+
+ bus_format = adjusted_mode->private_flags & 0xffff;
+
+ for (i = 0; i < num_bus_formats; i++) {
+ if (display_info->bus_formats[i] != bus_format)
+ continue;
+ break;
+ }
+
+ if (i && i == num_bus_formats) {
+ dev_err(dsim_dev->dev, "invalid bus format for connector\n");
+ return -EINVAL;
+ }
+
+ /* check pll out */
+ ret = sec_mipi_dsim_check_pll_out(bridge->driver_private,
+ adjusted_mode);
+ if (ret)
+ return ret;
+
+ /* sec dsim can only accept active hight DE */
+ imx_crtc_state->bus_flags |= DRM_BUS_FLAG_DE_HIGH;
+
+ /* For the dotclock polarity, default is neg edge;
+ * and in the dsim spec, there is no explict words
+ * to illustrate the dotclock polarity requirement.
+ */
+ imx_crtc_state->bus_flags |= DRM_BUS_FLAG_PIXDATA_NEGEDGE;
+
+ /* set the bus format for CRTC output which should be
+ * the same as the bus format between dsim and connector,
+ * since dsim cannot do any pixel conversions.
+ */
+ imx_crtc_state->bus_format = bus_format;
+
+ return 0;
+}
+
+static const struct drm_encoder_helper_funcs imx_sec_dsim_encoder_helper_funcs = {
+ .enable = imx_sec_dsim_encoder_helper_enable,
+ .disable = imx_sec_dsim_encoder_helper_disable,
+ .atomic_check = imx_sec_dsim_encoder_helper_atomic_check,
+};
+
+static const struct drm_encoder_funcs imx_sec_dsim_encoder_funcs = {
+ .destroy = imx_drm_encoder_destroy,
+};
+
+static const struct sec_mipi_dsim_plat_data imx8mm_mipi_dsim_plat_data = {
+ .version = 0x1060200,
+ .max_data_lanes = 4,
+ .max_data_rate = 1500000000ULL,
+ .dphy_pll = &pll_1432x,
+ .dphy_timing = dphy_timing_ln14lpp_v1p2,
+ .num_dphy_timing = ARRAY_SIZE(dphy_timing_ln14lpp_v1p2),
+ .dphy_timing_cmp = dphy_timing_default_cmp,
+ .mode_valid = NULL,
+};
+
+static const struct of_device_id imx_sec_dsim_dt_ids[] = {
+ {
+ .compatible = "fsl,imx8mm-mipi-dsim",
+ .data = &imx8mm_mipi_dsim_plat_data,
+ },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, imx_sec_dsim_dt_ids);
+
+static int imx_sec_dsim_bind(struct device *dev, struct device *master,
+ void *data)
+{
+ int ret, irq;
+ struct resource *res;
+ struct drm_device *drm_dev = data;
+ struct platform_device *pdev = to_platform_device(dev);
+ struct device_node *np = dev->of_node;
+ const struct of_device_id *of_id = of_match_device(imx_sec_dsim_dt_ids,
+ dev);
+ const struct sec_mipi_dsim_plat_data *pdata = of_id->data;
+ struct drm_encoder *encoder;
+
+ dev_dbg(dev, "%s: dsim bind begin\n", __func__);
+ dsim_dev = devm_kzalloc(dev, sizeof(*dsim_dev), GFP_KERNEL);
+ if (!dsim_dev) {
+ dev_err(dev, "Unable to allocate 'dsim_dev'\n");
+ return -ENOMEM;
+ }
+
+ dsim_dev->dev = &pdev->dev;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res)
+ return -ENODEV;
+
+ irq = platform_get_irq(pdev, 0);
+ if (irq < 0)
+ return -ENODEV;
+
+ dsim_dev->gpr = syscon_regmap_lookup_by_phandle(np, "dsi-gpr");
+ if (IS_ERR(dsim_dev->gpr))
+ return PTR_ERR(dsim_dev->gpr);
+
+ encoder = &dsim_dev->encoder;
+ ret = imx_drm_encoder_parse_of(drm_dev, encoder, np);
+ if (ret)
+ return ret;
+
+ drm_encoder_helper_add(encoder, &imx_sec_dsim_encoder_helper_funcs);
+
+ ret = drm_encoder_init(drm_dev, encoder,
+ &imx_sec_dsim_encoder_funcs,
+ DRM_MODE_ENCODER_DSI, dev_name(dev));
+ if (ret)
+ return ret;
+
+ /* bind sec dsim bridge */
+ ret = sec_mipi_dsim_bind(dev, master, data, encoder, res, irq, pdata);
+ if (ret) {
+ dev_err(dev, "failed to bind sec dsim bridge: %d\n", ret);
+ drm_encoder_cleanup(encoder);
+ return ret;
+ }
+
+ atomic_set(&dsim_dev->rpm_suspended, 0);
+ pm_runtime_enable(dev);
+ atomic_inc(&dsim_dev->rpm_suspended);
+
+ dev_dbg(dev, "%s: dsim bind end\n", __func__);
+
+ return 0;
+}
+
+static void imx_sec_dsim_unbind(struct device *dev, struct device *master,
+ void *data)
+{
+ pm_runtime_disable(dev);
+
+ sec_mipi_dsim_unbind(dev, master, data);
+
+ drm_encoder_cleanup(&dsim_dev->encoder);
+}
+
+static const struct component_ops imx_sec_dsim_ops = {
+ .bind = imx_sec_dsim_bind,
+ .unbind = imx_sec_dsim_unbind,
+};
+
+static int imx_sec_dsim_probe(struct platform_device *pdev)
+{
+ dev_dbg(&pdev->dev, "%s: dsim probe begin\n", __func__);
+
+ return component_add(&pdev->dev, &imx_sec_dsim_ops);
+}
+
+static int imx_sec_dsim_remove(struct platform_device *pdev)
+{
+ component_del(&pdev->dev, &imx_sec_dsim_ops);
+ return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int imx_sec_dsim_suspend(struct device *dev)
+{
+ return imx_sec_dsim_runtime_suspend(dev);
+}
+
+static int imx_sec_dsim_resume(struct device *dev)
+{
+ return imx_sec_dsim_runtime_resume(dev);
+}
+#else
+static int imx_sec_dsim_suspend(struct device *dev)
+{
+ return 0;
+}
+
+static int imx_sec_dsim_resume(struct device *dev)
+{
+ return 0;
+}
+#endif
+
+#ifdef CONFIG_PM
+static int imx_sec_dsim_runtime_suspend(struct device *dev)
+{
+ if (atomic_inc_return(&dsim_dev->rpm_suspended) > 1)
+ return 0;
+
+ sec_mipi_dsim_suspend(dev);
+
+ release_bus_freq(BUS_FREQ_HIGH);
+
+ return 0;
+}
+
+static int imx_sec_dsim_runtime_resume(struct device *dev)
+{
+ if (unlikely(!atomic_read(&dsim_dev->rpm_suspended))) {
+ dev_warn(dsim_dev->dev,
+ "Unbalanced %s!\n", __func__);
+ return 0;
+ }
+
+ if (!atomic_dec_and_test(&dsim_dev->rpm_suspended))
+ return 0;
+
+ request_bus_freq(BUS_FREQ_HIGH);
+
+ /* Pull dsim out of reset */
+ disp_mix_dsim_soft_reset_release(dsim_dev->gpr, true);
+ disp_mix_dsim_clks_enable(dsim_dev->gpr, true);
+ imx_sec_dsim_lanes_reset(dsim_dev->gpr, false);
+
+ sec_mipi_dsim_resume(dev);
+
+ return 0;
+}
+#endif
+
+static const struct dev_pm_ops imx_sec_dsim_pm_ops = {
+ SET_SYSTEM_SLEEP_PM_OPS(imx_sec_dsim_suspend,
+ imx_sec_dsim_resume)
+ SET_RUNTIME_PM_OPS(imx_sec_dsim_runtime_suspend,
+ imx_sec_dsim_runtime_resume,
+ NULL)
+};
+
+struct platform_driver imx_sec_dsim_driver = {
+ .probe = imx_sec_dsim_probe,
+ .remove = imx_sec_dsim_remove,
+ .driver = {
+ .name = DRIVER_NAME,
+ .of_match_table = imx_sec_dsim_dt_ids,
+ .pm = &imx_sec_dsim_pm_ops,
+ },
+};
+
+module_platform_driver(imx_sec_dsim_driver);
+
+MODULE_DESCRIPTION("NXP i.MX MIPI DSI Host Controller driver");
+MODULE_AUTHOR("Fancy Fang <chen.fang@nxp.com>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/drm/imx/sec_mipi_pll_1432x.h b/drivers/gpu/drm/imx/sec_mipi_pll_1432x.h
new file mode 100644
index 000000000000..c387b2facd59
--- /dev/null
+++ b/drivers/gpu/drm/imx/sec_mipi_pll_1432x.h
@@ -0,0 +1,49 @@
+/*
+ * Samsung MIPI DSIM PLL_1432X
+ *
+ * Copyright 2019 NXP
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __SEC_DSIM_PLL_1432X_H__
+#define __SEC_DSIM_PLL_1432X_H__
+
+#include <drm/bridge/sec_mipi_dsim.h>
+/*
+ * DSIM PLL_1432X setting guide from spec:
+ *
+ * Fout(bitclk) = ((m + k / 65536) * Fin) / (p * 2^s), and
+ * p = P[5:0], m = M[9:0], s = S[2:0], k = K[15:0];
+ *
+ * Fpref = Fin / p
+ * Fin: [6MHz ~ 300MHz], Fpref: [2MHz ~ 30MHz]
+ *
+ * Fvco = ((m + k / 65536) * Fin) / p
+ * Fvco: [1050MHz ~ 2100MHz]
+ *
+ * 1 <= P[5:0] <= 63, 64 <= M[9:0] <= 1023,
+ * 0 <= S[2:0] <= 5, -32768 <= K[15:0] <= 32767
+ *
+ */
+
+const struct sec_mipi_dsim_pll pll_1432x = {
+ .p = { .min = 1, .max = 63, },
+ .m = { .min = 64, .max = 1023, },
+ .s = { .min = 0, .max = 5, },
+ .k = { .min = 0, .max = 32768, }, /* abs(k) */
+ .fin = { .min = 6000, .max = 300000, }, /* in KHz */
+ .fpref = { .min = 2000, .max = 30000, }, /* in KHz */
+ .fvco = { .min = 1050000, .max = 2100000, }, /* in KHz */
+};
+
+#endif
+
diff --git a/drivers/gpu/drm/mgag200/mgag200_mode.c b/drivers/gpu/drm/mgag200/mgag200_mode.c
index 5e9cd4c0e8b6..68e5d9c94475 100644
--- a/drivers/gpu/drm/mgag200/mgag200_mode.c
+++ b/drivers/gpu/drm/mgag200/mgag200_mode.c
@@ -1670,7 +1670,7 @@ static struct drm_encoder *mga_connector_best_encoder(struct drm_connector
int enc_id = connector->encoder_ids[0];
/* pick the encoder ids */
if (enc_id)
- return drm_encoder_find(connector->dev, enc_id);
+ return drm_encoder_find(connector->dev, NULL, enc_id);
return NULL;
}
diff --git a/drivers/gpu/drm/mxsfb/mxsfb_crtc.c b/drivers/gpu/drm/mxsfb/mxsfb_crtc.c
index 0abe77675b76..94a6d16d469c 100644
--- a/drivers/gpu/drm/mxsfb/mxsfb_crtc.c
+++ b/drivers/gpu/drm/mxsfb/mxsfb_crtc.c
@@ -26,7 +26,9 @@
#include <drm/drm_of.h>
#include <drm/drm_plane_helper.h>
#include <drm/drm_simple_kms_helper.h>
+#include <linux/busfreq-imx.h>
#include <linux/clk.h>
+#include <linux/clk-provider.h>
#include <linux/iopoll.h>
#include <linux/of_graph.h>
#include <linux/platform_data/simplefb.h>
@@ -49,14 +51,17 @@ static u32 set_hsync_pulse_width(struct mxsfb_drm_private *mxsfb, u32 val)
}
/* Setup the MXSFB registers for decoding the pixels out of the framebuffer */
-static int mxsfb_set_pixel_fmt(struct mxsfb_drm_private *mxsfb)
+static int mxsfb_set_pixel_fmt(struct mxsfb_drm_private *mxsfb, bool update)
{
struct drm_crtc *crtc = &mxsfb->pipe.crtc;
struct drm_device *drm = crtc->dev;
const u32 format = crtc->primary->state->fb->format->format;
- u32 ctrl, ctrl1;
+ u32 ctrl = 0, ctrl1 = 0;
+ bool bgr_format = true;
+ struct drm_format_name_buf format_name_buf;
- ctrl = CTRL_BYPASS_COUNT | CTRL_MASTER;
+ if (!update)
+ ctrl = CTRL_BYPASS_COUNT | CTRL_MASTER;
/*
* WARNING: The bus width, CTRL_SET_BUS_WIDTH(), is configured to
@@ -65,61 +70,158 @@ static int mxsfb_set_pixel_fmt(struct mxsfb_drm_private *mxsfb)
* to arbitrary value. This limitation should not pose an issue.
*/
- /* CTRL1 contains IRQ config and status bits, preserve those. */
- ctrl1 = readl(mxsfb->base + LCDC_CTRL1);
- ctrl1 &= CTRL1_CUR_FRAME_DONE_IRQ_EN | CTRL1_CUR_FRAME_DONE_IRQ;
+ if (!update) {
+ /* CTRL1 contains IRQ config and status bits, preserve those. */
+ ctrl1 = readl(mxsfb->base + LCDC_CTRL1);
+ ctrl1 &= CTRL1_CUR_FRAME_DONE_IRQ_EN | CTRL1_CUR_FRAME_DONE_IRQ;
+ }
+
+ DRM_DEV_DEBUG_DRIVER(drm->dev, "Setting up %s mode\n",
+ drm_get_format_name(format, &format_name_buf));
+
+ /* Do some clean-up that we might have from a previous mode */
+ ctrl &= ~CTRL_SHIFT_DIR(1);
+ ctrl &= ~CTRL_SHIFT_NUM(0x3f);
+ if (mxsfb->devdata->ipversion >= 4)
+ writel(CTRL2_ODD_LINE_PATTERN(0x7) |
+ CTRL2_EVEN_LINE_PATTERN(0x7),
+ mxsfb->base + LCDC_V4_CTRL2 + REG_CLR);
switch (format) {
- case DRM_FORMAT_RGB565:
- dev_dbg(drm->dev, "Setting up RGB565 mode\n");
+ case DRM_FORMAT_BGR565: /* BG16 */
+ if (mxsfb->devdata->ipversion < 4)
+ goto err;
+ writel(CTRL2_ODD_LINE_PATTERN(0x5) |
+ CTRL2_EVEN_LINE_PATTERN(0x5),
+ mxsfb->base + LCDC_V4_CTRL2 + REG_SET);
+ /* Fall through */
+ case DRM_FORMAT_RGB565: /* RG16 */
+ ctrl |= CTRL_SET_WORD_LENGTH(0);
+ ctrl &= ~CTRL_DF16;
+ ctrl1 |= CTRL1_SET_BYTE_PACKAGING(0xf);
+ break;
+ case DRM_FORMAT_XBGR1555: /* XB15 */
+ case DRM_FORMAT_ABGR1555: /* AB15 */
+ if (mxsfb->devdata->ipversion < 4)
+ goto err;
+ writel(CTRL2_ODD_LINE_PATTERN(0x5) |
+ CTRL2_EVEN_LINE_PATTERN(0x5),
+ mxsfb->base + LCDC_V4_CTRL2 + REG_SET);
+ /* Fall through */
+ case DRM_FORMAT_XRGB1555: /* XR15 */
+ case DRM_FORMAT_ARGB1555: /* AR15 */
ctrl |= CTRL_SET_WORD_LENGTH(0);
+ ctrl |= CTRL_DF16;
ctrl1 |= CTRL1_SET_BYTE_PACKAGING(0xf);
break;
- case DRM_FORMAT_XRGB8888:
- dev_dbg(drm->dev, "Setting up XRGB8888 mode\n");
+ case DRM_FORMAT_RGBX8888: /* RX24 */
+ case DRM_FORMAT_RGBA8888: /* RA24 */
+ /* RGBX - > 0RGB */
+ ctrl |= CTRL_SHIFT_DIR(1);
+ ctrl |= CTRL_SHIFT_NUM(8);
+ bgr_format = false;
+ /* Fall through */
+ case DRM_FORMAT_XBGR8888: /* XB24 */
+ case DRM_FORMAT_ABGR8888: /* AB24 */
+ if (bgr_format) {
+ if (mxsfb->devdata->ipversion < 4)
+ goto err;
+ writel(CTRL2_ODD_LINE_PATTERN(0x5) |
+ CTRL2_EVEN_LINE_PATTERN(0x5),
+ mxsfb->base + LCDC_V4_CTRL2 + REG_SET);
+ }
+ /* Fall through */
+ case DRM_FORMAT_XRGB8888: /* XR24 */
+ case DRM_FORMAT_ARGB8888: /* AR24 */
ctrl |= CTRL_SET_WORD_LENGTH(3);
/* Do not use packed pixels = one pixel per word instead. */
ctrl1 |= CTRL1_SET_BYTE_PACKAGING(0x7);
break;
default:
- dev_err(drm->dev, "Unhandled pixel format %08x\n", format);
- return -EINVAL;
+ goto err;
}
- writel(ctrl1, mxsfb->base + LCDC_CTRL1);
- writel(ctrl, mxsfb->base + LCDC_CTRL);
+ if (update) {
+ writel(ctrl, mxsfb->base + LCDC_CTRL + REG_SET);
+ writel(ctrl1, mxsfb->base + LCDC_CTRL1 + REG_SET);
+ } else {
+ writel(ctrl, mxsfb->base + LCDC_CTRL);
+ writel(ctrl1, mxsfb->base + LCDC_CTRL1);
+ }
return 0;
+
+err:
+ DRM_DEV_ERROR(drm->dev, "Unhandled pixel format: %s\n",
+ drm_get_format_name(format, &format_name_buf));
+
+ return -EINVAL;
+}
+
+static u32 get_bus_format_from_bpp(u32 bpp)
+{
+ switch (bpp) {
+ case 16:
+ return MEDIA_BUS_FMT_RGB565_1X16;
+ case 18:
+ return MEDIA_BUS_FMT_RGB666_1X18;
+ case 24:
+ return MEDIA_BUS_FMT_RGB888_1X24;
+ default:
+ return MEDIA_BUS_FMT_RGB888_1X24;
+ }
}
static void mxsfb_set_bus_fmt(struct mxsfb_drm_private *mxsfb)
{
struct drm_crtc *crtc = &mxsfb->pipe.crtc;
+ unsigned int bits_per_pixel = crtc->primary->state->fb->format->depth;
struct drm_device *drm = crtc->dev;
u32 bus_format = MEDIA_BUS_FMT_RGB888_1X24;
- u32 reg;
+ int num_bus_formats = mxsfb->connector->display_info.num_bus_formats;
+ const u32 *bus_formats = mxsfb->connector->display_info.bus_formats;
+ u32 reg = 0;
+ int i = 0;
+
+ /* match the user requested bus_format to one supported by the panel */
+ if (num_bus_formats) {
+ u32 user_bus_format = get_bus_format_from_bpp(bits_per_pixel);
+
+ bus_format = bus_formats[0];
+ for (i = 0; i < num_bus_formats; i++) {
+ if (user_bus_format == bus_formats[i]) {
+ bus_format = user_bus_format;
+ break;
+ }
+ }
+ }
- reg = readl(mxsfb->base + LCDC_CTRL);
+ /*
+ * CRTC will dictate the bus format via private_flags[16:1]
+ * and private_flags[0] will signal a bus format change
+ */
+ crtc->mode.private_flags &= ~0x1FFFF; /* clear bus format */
+ crtc->mode.private_flags |= (bus_format << 1); /* set bus format */
+ crtc->mode.private_flags |= 0x1; /* bus format change indication*/
- if (mxsfb->connector.display_info.num_bus_formats)
- bus_format = mxsfb->connector.display_info.bus_formats[0];
+ DRM_DEV_DEBUG_DRIVER(mxsfb->dev,
+ "Using bus_format: 0x%08X\n", bus_format);
- reg &= ~CTRL_BUS_WIDTH_MASK;
switch (bus_format) {
case MEDIA_BUS_FMT_RGB565_1X16:
- reg |= CTRL_SET_BUS_WIDTH(STMLCDIF_16BIT);
+ reg = CTRL_SET_BUS_WIDTH(STMLCDIF_16BIT);
break;
case MEDIA_BUS_FMT_RGB666_1X18:
- reg |= CTRL_SET_BUS_WIDTH(STMLCDIF_18BIT);
+ reg = CTRL_SET_BUS_WIDTH(STMLCDIF_18BIT);
break;
case MEDIA_BUS_FMT_RGB888_1X24:
- reg |= CTRL_SET_BUS_WIDTH(STMLCDIF_24BIT);
+ reg = CTRL_SET_BUS_WIDTH(STMLCDIF_24BIT);
break;
default:
dev_err(drm->dev, "Unknown media bus format %d\n", bus_format);
break;
}
- writel(reg, mxsfb->base + LCDC_CTRL);
+ writel(reg, mxsfb->base + LCDC_CTRL + REG_SET);
}
static void mxsfb_enable_controller(struct mxsfb_drm_private *mxsfb)
@@ -129,7 +231,20 @@ static void mxsfb_enable_controller(struct mxsfb_drm_private *mxsfb)
if (mxsfb->clk_disp_axi)
clk_prepare_enable(mxsfb->clk_disp_axi);
clk_prepare_enable(mxsfb->clk);
- mxsfb_enable_axi_clk(mxsfb);
+
+ if (mxsfb->devdata->ipversion >= 4) {
+ /*
+ * On some platforms, bit 21 is defaulted to 1, which may alter
+ * the below setting. So, to make sure we have the right setting
+ * clear all the bits for CTRL2_OUTSTANDING_REQS.
+ */
+ writel(CTRL2_OUTSTANDING_REQS(0x7),
+ mxsfb->base + LCDC_V4_CTRL2 + REG_CLR);
+ writel(CTRL2_OUTSTANDING_REQS(REQ_16),
+ mxsfb->base + LCDC_V4_CTRL2 + REG_SET);
+ /* Assert LCD Reset bit */
+ writel(CTRL2_LCD_RESET, mxsfb->base + LCDC_V4_CTRL2 + REG_SET);
+ }
/* If it was disabled, re-enable the mode again */
writel(CTRL_DOTCLK_MODE, mxsfb->base + LCDC_CTRL + REG_SET);
@@ -139,13 +254,25 @@ static void mxsfb_enable_controller(struct mxsfb_drm_private *mxsfb)
reg |= VDCTRL4_SYNC_SIGNALS_ON;
writel(reg, mxsfb->base + LCDC_VDCTRL4);
+ writel(CTRL_MASTER, mxsfb->base + LCDC_CTRL + REG_SET);
writel(CTRL_RUN, mxsfb->base + LCDC_CTRL + REG_SET);
+
+ writel(CTRL1_RECOVERY_ON_UNDERFLOW, mxsfb->base + LCDC_CTRL1 + REG_SET);
}
static void mxsfb_disable_controller(struct mxsfb_drm_private *mxsfb)
{
u32 reg;
+ if (mxsfb->devdata->ipversion >= 4) {
+ writel(CTRL2_OUTSTANDING_REQS(0x7),
+ mxsfb->base + LCDC_V4_CTRL2 + REG_CLR);
+ /* De-assert LCD Reset bit */
+ writel(CTRL2_LCD_RESET, mxsfb->base + LCDC_V4_CTRL2 + REG_CLR);
+ }
+
+ writel(CTRL_RUN, mxsfb->base + LCDC_CTRL + REG_CLR);
+
/*
* Even if we disable the controller here, it will still continue
* until its FIFOs are running out of data
@@ -155,12 +282,12 @@ static void mxsfb_disable_controller(struct mxsfb_drm_private *mxsfb)
readl_poll_timeout(mxsfb->base + LCDC_CTRL, reg, !(reg & CTRL_RUN),
0, 1000);
+ writel(CTRL_MASTER, mxsfb->base + LCDC_CTRL + REG_CLR);
+
reg = readl(mxsfb->base + LCDC_VDCTRL4);
reg &= ~VDCTRL4_SYNC_SIGNALS_ON;
writel(reg, mxsfb->base + LCDC_VDCTRL4);
- mxsfb_disable_axi_clk(mxsfb);
-
clk_disable_unprepare(mxsfb->clk);
if (mxsfb->clk_disp_axi)
clk_disable_unprepare(mxsfb->clk_disp_axi);
@@ -196,33 +323,77 @@ static int mxsfb_reset_block(void __iomem *reset_addr)
return clear_poll_bit(reset_addr, MODULE_CLKGATE);
}
+static dma_addr_t mxsfb_get_fb_paddr(struct mxsfb_drm_private *mxsfb)
+{
+ struct drm_framebuffer *fb = mxsfb->pipe.plane.state->fb;
+ struct drm_gem_cma_object *gem;
+
+ if (!fb)
+ return 0;
+
+ gem = drm_fb_cma_get_gem_obj(fb, 0);
+ if (!gem)
+ return 0;
+
+ return gem->paddr;
+}
+
static void mxsfb_crtc_mode_set_nofb(struct mxsfb_drm_private *mxsfb)
{
struct drm_display_mode *m = &mxsfb->pipe.crtc.state->adjusted_mode;
- const u32 bus_flags = mxsfb->connector.display_info.bus_flags;
+ const u32 bus_flags = mxsfb->connector->display_info.bus_flags;
u32 vdctrl0, vsync_pulse_len, hsync_pulse_len;
int err;
+ u32 pixclock = m->clock * 1000;
+ struct mode_config *config;
/*
* It seems, you can't re-program the controller if it is still
* running. This may lead to shifted pictures (FIFO issue?), so
* first stop the controller and drain its FIFOs.
*/
- mxsfb_enable_axi_clk(mxsfb);
/* Mandatory eLCDIF reset as per the Reference Manual */
err = mxsfb_reset_block(mxsfb->base);
if (err)
return;
+ /*
+ * Before setting the clock rate, we need to be sure that the clock
+ * has the right source to output the required rate.
+ */
+ list_for_each_entry(config, &mxsfb->valid_modes, list) {
+ if (config->clock == pixclock) {
+ struct clk *src;
+
+ src = clk_get_parent(mxsfb->clk_sel);
+ if (!clk_is_match(src, config->clk_src))
+ clk_set_parent(mxsfb->clk_sel, config->clk_src);
+ if (clk_get_rate(mxsfb->clk_pll) != config->out_rate)
+ clk_set_rate(mxsfb->clk_pll, config->out_rate);
+ DRM_DEV_DEBUG_DRIVER(mxsfb->dev,
+ "pll rate: %ld (actual %ld)\n",
+ config->out_rate, clk_get_rate(mxsfb->clk_pll));
+ pixclock = config->mode_clock;
+ break;
+ }
+ }
+
/* Clear the FIFOs */
writel(CTRL1_FIFO_CLEAR, mxsfb->base + LCDC_CTRL1 + REG_SET);
- err = mxsfb_set_pixel_fmt(mxsfb);
+ err = mxsfb_set_pixel_fmt(mxsfb, false);
if (err)
return;
- clk_set_rate(mxsfb->clk, m->crtc_clock * 1000);
+ clk_set_rate(mxsfb->clk, pixclock);
+ DRM_DEV_DEBUG_DRIVER(mxsfb->dev, "Pixel clock: %dkHz (actual: %dkHz)\n",
+ pixclock / 1000, (int)(clk_get_rate(mxsfb->clk) / 1000));
+
+ DRM_DEV_DEBUG_DRIVER(mxsfb->dev,
+ "Connector bus_flags: 0x%08X\n", bus_flags);
+ DRM_DEV_DEBUG_DRIVER(mxsfb->dev,
+ "Mode flags: 0x%08X\n", m->flags);
writel(TRANSFER_COUNT_SET_VCOUNT(m->crtc_vdisplay) |
TRANSFER_COUNT_SET_HCOUNT(m->crtc_hdisplay),
@@ -269,32 +440,47 @@ static void mxsfb_crtc_mode_set_nofb(struct mxsfb_drm_private *mxsfb)
writel(SET_DOTCLK_H_VALID_DATA_CNT(m->hdisplay),
mxsfb->base + LCDC_VDCTRL4);
-
- mxsfb_disable_axi_clk(mxsfb);
}
void mxsfb_crtc_enable(struct mxsfb_drm_private *mxsfb)
{
+ dma_addr_t paddr;
+
+ if (mxsfb->devdata->flags & MXSFB_FLAG_BUSFREQ)
+ request_bus_freq(BUS_FREQ_HIGH);
+
+ clk_prepare_enable(mxsfb->clk_axi);
+ writel(0, mxsfb->base + LCDC_CTRL);
mxsfb_crtc_mode_set_nofb(mxsfb);
+
+ /* Write cur_buf as well to avoid an initial corrupt frame */
+ paddr = mxsfb_get_fb_paddr(mxsfb);
+ if (paddr) {
+ writel(paddr, mxsfb->base + mxsfb->devdata->cur_buf);
+ writel(paddr, mxsfb->base + mxsfb->devdata->next_buf);
+ }
+
mxsfb_enable_controller(mxsfb);
}
void mxsfb_crtc_disable(struct mxsfb_drm_private *mxsfb)
{
mxsfb_disable_controller(mxsfb);
+ clk_disable_unprepare(mxsfb->clk_axi);
+
+ if (mxsfb->devdata->flags & MXSFB_FLAG_BUSFREQ)
+ release_bus_freq(BUS_FREQ_HIGH);
}
void mxsfb_plane_atomic_update(struct mxsfb_drm_private *mxsfb,
- struct drm_plane_state *state)
+ struct drm_plane_state *old_state)
{
struct drm_simple_display_pipe *pipe = &mxsfb->pipe;
struct drm_crtc *crtc = &pipe->crtc;
struct drm_framebuffer *fb = pipe->plane.state->fb;
+ struct drm_framebuffer *old_fb = old_state->fb;
struct drm_pending_vblank_event *event;
- struct drm_gem_cma_object *gem;
-
- if (!crtc)
- return;
+ dma_addr_t paddr;
spin_lock_irq(&crtc->dev->event_lock);
event = crtc->state->event;
@@ -309,12 +495,27 @@ void mxsfb_plane_atomic_update(struct mxsfb_drm_private *mxsfb,
}
spin_unlock_irq(&crtc->dev->event_lock);
- if (!fb)
- return;
+ paddr = mxsfb_get_fb_paddr(mxsfb);
+ if (paddr) {
+ clk_prepare_enable(mxsfb->clk_axi);
+ writel(paddr, mxsfb->base + mxsfb->devdata->next_buf);
+ clk_disable_unprepare(mxsfb->clk_axi);
+ }
- gem = drm_fb_cma_get_gem_obj(fb, 0);
+ if (!fb || !old_fb)
+ return;
- mxsfb_enable_axi_clk(mxsfb);
- writel(gem->paddr, mxsfb->base + mxsfb->devdata->next_buf);
- mxsfb_disable_axi_clk(mxsfb);
+ /*
+ * TODO: Currently, we only support pixel format change, but we need
+ * also to care about size changes too
+ */
+ if (old_fb->format->format != fb->format->format) {
+ struct drm_format_name_buf old_fmt_buf;
+ struct drm_format_name_buf new_fmt_buf;
+ DRM_DEV_DEBUG_DRIVER(mxsfb->dev,
+ "Switching pixel format: %s -> %s\n",
+ drm_get_format_name(old_fb->format->format, &old_fmt_buf),
+ drm_get_format_name(fb->format->format, &new_fmt_buf));
+ mxsfb_set_pixel_fmt(mxsfb, true);
+ }
}
diff --git a/drivers/gpu/drm/mxsfb/mxsfb_drv.c b/drivers/gpu/drm/mxsfb/mxsfb_drv.c
index 7fbad9cb656e..24bb09fdc5fd 100644
--- a/drivers/gpu/drm/mxsfb/mxsfb_drv.c
+++ b/drivers/gpu/drm/mxsfb/mxsfb_drv.c
@@ -19,6 +19,7 @@
#include <linux/module.h>
#include <linux/spinlock.h>
#include <linux/clk.h>
+#include <linux/clk-provider.h>
#include <linux/component.h>
#include <linux/list.h>
#include <linux/of_device.h>
@@ -26,6 +27,7 @@
#include <linux/of_reserved_mem.h>
#include <linux/pm_runtime.h>
#include <linux/reservation.h>
+#include <linux/version.h>
#include <drm/drmP.h>
#include <drm/drm_atomic.h>
@@ -42,11 +44,39 @@
#include "mxsfb_drv.h"
#include "mxsfb_regs.h"
+/* The eLCDIF max possible CRTCs */
+#define MAX_CRTCS 1
+
+/* Maximum Video PLL frequency */
+#define MAX_PLL_FREQ 1200000000
+/* Mininum pixel clock in Hz */
+#define MIN_PIX_CLK 74250000
enum mxsfb_devtype {
MXSFB_V3,
MXSFB_V4,
};
+/*
+ * When adding new formats, make sure to update the num_formats from
+ * mxsfb_devdata below.
+ */
+static const uint32_t mxsfb_formats[] = {
+ /* MXSFB_V3 */
+ DRM_FORMAT_XRGB8888,
+ DRM_FORMAT_ARGB8888,
+ DRM_FORMAT_RGB565,
+ /* MXSFB_V4 */
+ DRM_FORMAT_XBGR8888,
+ DRM_FORMAT_ABGR8888,
+ DRM_FORMAT_RGBX8888,
+ DRM_FORMAT_RGBA8888,
+ DRM_FORMAT_ARGB1555,
+ DRM_FORMAT_XRGB1555,
+ DRM_FORMAT_ABGR1555,
+ DRM_FORMAT_XBGR1555,
+ DRM_FORMAT_BGR565
+};
+
static const struct mxsfb_devdata mxsfb_devdata[] = {
[MXSFB_V3] = {
.transfer_count = LCDC_V3_TRANSFER_COUNT,
@@ -56,6 +86,8 @@ static const struct mxsfb_devdata mxsfb_devdata[] = {
.hs_wdth_mask = 0xff,
.hs_wdth_shift = 24,
.ipversion = 3,
+ .flags = MXSFB_FLAG_NULL,
+ .num_formats = 3,
},
[MXSFB_V4] = {
.transfer_count = LCDC_V4_TRANSFER_COUNT,
@@ -65,43 +97,245 @@ static const struct mxsfb_devdata mxsfb_devdata[] = {
.hs_wdth_mask = 0x3fff,
.hs_wdth_shift = 18,
.ipversion = 4,
+ .flags = MXSFB_FLAG_BUSFREQ,
+ .num_formats = ARRAY_SIZE(mxsfb_formats),
},
};
-static const uint32_t mxsfb_formats[] = {
- DRM_FORMAT_XRGB8888,
- DRM_FORMAT_RGB565
-};
-
static struct mxsfb_drm_private *
drm_pipe_to_mxsfb_drm_private(struct drm_simple_display_pipe *pipe)
{
return container_of(pipe, struct mxsfb_drm_private, pipe);
}
-void mxsfb_enable_axi_clk(struct mxsfb_drm_private *mxsfb)
+/**
+ * mxsfb_atomic_helper_check - validate state object
+ * @dev: DRM device
+ * @state: the driver state object
+ *
+ * On top of the drm imlementation drm_atomic_helper_check,
+ * check if the bpp is changed, if so, signal mode_changed,
+ * this will trigger disable/enable
+ *
+ * RETURNS:
+ * Zero for success or -errno
+ */
+static int mxsfb_atomic_helper_check(struct drm_device *dev,
+ struct drm_atomic_state *state)
{
- if (mxsfb->clk_axi)
- clk_prepare_enable(mxsfb->clk_axi);
-}
+ struct drm_crtc *crtc;
+ struct drm_crtc_state *crtc_state;
+ int i, ret;
-void mxsfb_disable_axi_clk(struct mxsfb_drm_private *mxsfb)
-{
- if (mxsfb->clk_axi)
- clk_disable_unprepare(mxsfb->clk_axi);
+ ret = drm_atomic_helper_check(dev, state);
+ if (ret)
+ return ret;
+
+ for_each_crtc_in_state(state, crtc, crtc_state, i) {
+ struct drm_plane_state *primary_state;
+ int old_bpp = 0;
+ int new_bpp = 0;
+
+ if (!crtc->primary || !crtc->primary->old_fb)
+ continue;
+ primary_state =
+ drm_atomic_get_plane_state(state, crtc->primary);
+ if (!primary_state || !primary_state->fb)
+ continue;
+ old_bpp = crtc->primary->old_fb->format->depth;
+ new_bpp = primary_state->fb->format->depth;
+ if (old_bpp != new_bpp) {
+ crtc_state->mode_changed = true;
+ DRM_DEBUG_ATOMIC(
+ "[CRTC:%d:%s] mode changed, bpp %d->%d\n",
+ crtc->base.id, crtc->name, old_bpp, new_bpp);
+ }
+ }
+ return ret;
}
static const struct drm_mode_config_funcs mxsfb_mode_config_funcs = {
.fb_create = drm_fb_cma_create,
- .atomic_check = drm_atomic_helper_check,
+ .atomic_check = mxsfb_atomic_helper_check,
.atomic_commit = drm_atomic_helper_commit,
};
+static const struct drm_mode_config_helper_funcs mxsfb_mode_config_helpers = {
+ .atomic_commit_tail = drm_atomic_helper_commit_tail_rpm,
+};
+
+static struct clk *mxsfb_find_src_clk(struct mxsfb_drm_private *mxsfb,
+ int crtc_clock,
+ unsigned long *out_rate)
+{
+ struct clk *src = NULL;
+ struct clk *p = mxsfb->clk;
+ struct clk *src_clk[MAX_CLK_SRC];
+ int num_src_clk = ARRAY_SIZE(mxsfb->clk_src);
+ unsigned long src_rate;
+ int i;
+
+ for (i = 0; i < num_src_clk; i++)
+ src_clk[i] = mxsfb->clk_src[i];
+
+ /*
+ * First, check the current clock source and find the clock
+ * selector
+ */
+ while (p) {
+ struct clk *pp = clk_get_parent(p);
+
+ for (i = 0; i < num_src_clk; i++)
+ if (src_clk[i] && clk_is_match(pp, src_clk[i])) {
+ src = pp;
+ mxsfb->clk_sel = p;
+ src_clk[i] = NULL;
+ break;
+ }
+
+ if (src)
+ break;
+
+ p = pp;
+ }
+
+ while (!IS_ERR_OR_NULL(src)) {
+ /* Check if current rate satisfies our needs */
+ src_rate = clk_get_rate(src);
+ *out_rate = clk_get_rate(mxsfb->clk_pll);
+ if (!(*out_rate % crtc_clock))
+ break;
+
+ /* Find the highest rate that fits our needs */
+ *out_rate = crtc_clock * (MAX_PLL_FREQ / crtc_clock);
+ if (!(*out_rate % src_rate))
+ break;
+
+ /* Get the next clock source available */
+ src = NULL;
+ for (i = 0; i < num_src_clk; i++) {
+ if (IS_ERR_OR_NULL(src_clk[i]))
+ continue;
+ src = src_clk[i];
+ src_clk[i] = NULL;
+ break;
+ }
+ }
+
+ return src;
+}
+
+static enum drm_mode_status
+mxsfb_pipe_mode_valid(struct drm_crtc *crtc,
+ const struct drm_display_mode *mode)
+{
+ struct drm_simple_display_pipe *pipe =
+ container_of(crtc, struct drm_simple_display_pipe, crtc);
+ struct mxsfb_drm_private *mxsfb = drm_pipe_to_mxsfb_drm_private(pipe);
+ struct clk *src = NULL;
+ int clock = mode->clock * 1000;
+ int crtc_clock = mode->crtc_clock * 1000;
+ unsigned long out_rate;
+ struct mode_config *config;
+
+ /*
+ * In order to verify possible clock sources we need to have at least
+ * two of them.
+ */
+ if (!mxsfb->clk_src[0] || !mxsfb->clk_src[1])
+ return MODE_OK;
+
+ /*
+ * TODO: Currently, only modes with pixel clock higher or equal to
+ * 74250kHz are working. Limit to these modes until we figure out how
+ * to handle the rest of the display modes.
+ */
+ if (clock < MIN_PIX_CLK)
+ return MODE_NOCLOCK;
+
+ if (!crtc_clock)
+ crtc_clock = clock;
+
+ DRM_DEV_DEBUG_DRIVER(mxsfb->dev, "Validating mode:\n");
+ drm_mode_debug_printmodeline(mode);
+ /* Skip saving the config again */
+ list_for_each_entry(config, &mxsfb->valid_modes, list)
+ if (config->clock == clock)
+ return MODE_OK;
+
+ src = mxsfb_find_src_clk(mxsfb, crtc_clock, &out_rate);
+
+ if (IS_ERR_OR_NULL(src))
+ return MODE_NOCLOCK;
+
+ clk_set_rate(mxsfb->clk_pll, out_rate);
+
+ /* Save this configuration for later use */
+ config = devm_kzalloc(mxsfb->dev,
+ sizeof(struct mode_config), GFP_KERNEL);
+ config->clk_src = src;
+ config->out_rate = out_rate;
+ config->clock = clock;
+ config->mode_clock = crtc_clock;
+ list_add(&config->list, &mxsfb->valid_modes);
+
+ return MODE_OK;
+}
+
+static int mxsfb_pipe_check(struct drm_simple_display_pipe *pipe,
+ struct drm_plane_state *plane_state,
+ struct drm_crtc_state *crtc_state)
+{
+ struct mxsfb_drm_private *mxsfb = drm_pipe_to_mxsfb_drm_private(pipe);
+ struct drm_display_mode *mode = &crtc_state->mode;
+ struct mode_config *config;
+ struct clk *src;
+
+ DRM_DEV_DEBUG_DRIVER(mxsfb->dev, "Checking mode:\n");
+ drm_mode_debug_printmodeline(mode);
+
+ /* Make sure that current mode can get the required clock */
+ list_for_each_entry(config, &mxsfb->valid_modes, list)
+ if (config->clock == mode->clock * 1000) {
+ src = clk_get_parent(mxsfb->clk_sel);
+ if (!clk_is_match(src, config->clk_src))
+ clk_set_parent(mxsfb->clk_sel, config->clk_src);
+ if (clk_get_rate(mxsfb->clk_pll) != config->out_rate)
+ clk_set_rate(mxsfb->clk_pll, config->out_rate);
+ DRM_DEV_DEBUG_DRIVER(mxsfb->dev,
+ "pll rate: %ld (actual %ld)\n",
+ config->out_rate, clk_get_rate(mxsfb->clk_pll));
+ break;
+ }
+
+ return 0;
+}
+
static void mxsfb_pipe_enable(struct drm_simple_display_pipe *pipe,
struct drm_crtc_state *crtc_state)
{
+ struct drm_device *drm = pipe->encoder.dev;
+ struct drm_connector *connector;
struct mxsfb_drm_private *mxsfb = drm_pipe_to_mxsfb_drm_private(pipe);
+ if (!mxsfb->connector) {
+ list_for_each_entry(connector,
+ &drm->mode_config.connector_list,
+ head)
+ if (connector->encoder == &(mxsfb->pipe.encoder)) {
+ mxsfb->connector = connector;
+ break;
+ }
+ }
+
+ if (!mxsfb->connector) {
+ dev_warn(drm->dev, "No connector attached, using default\n");
+ mxsfb->connector = &mxsfb->panel_connector;
+ }
+
+ drm_crtc_vblank_on(&mxsfb->pipe.crtc);
+
+ pm_runtime_get_sync(drm->dev);
drm_panel_prepare(mxsfb->panel);
mxsfb_crtc_enable(mxsfb);
drm_panel_enable(mxsfb->panel);
@@ -110,10 +344,25 @@ static void mxsfb_pipe_enable(struct drm_simple_display_pipe *pipe,
static void mxsfb_pipe_disable(struct drm_simple_display_pipe *pipe)
{
struct mxsfb_drm_private *mxsfb = drm_pipe_to_mxsfb_drm_private(pipe);
+ struct drm_device *drm = pipe->plane.dev;
+ struct drm_crtc *crtc = &pipe->crtc;
+ struct drm_pending_vblank_event *event;
drm_panel_disable(mxsfb->panel);
mxsfb_crtc_disable(mxsfb);
drm_panel_unprepare(mxsfb->panel);
+ pm_runtime_put_sync(drm->dev);
+
+ spin_lock_irq(&drm->event_lock);
+ event = crtc->state->event;
+ if (event) {
+ crtc->state->event = NULL;
+ drm_crtc_send_vblank_event(crtc, event);
+ }
+ spin_unlock_irq(&drm->event_lock);
+
+ if (mxsfb->connector != &mxsfb->panel_connector)
+ mxsfb->connector = NULL;
}
static void mxsfb_pipe_update(struct drm_simple_display_pipe *pipe,
@@ -124,17 +373,23 @@ static void mxsfb_pipe_update(struct drm_simple_display_pipe *pipe,
mxsfb_plane_atomic_update(mxsfb, plane_state);
}
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0)
static int mxsfb_pipe_prepare_fb(struct drm_simple_display_pipe *pipe,
struct drm_plane_state *plane_state)
{
return drm_fb_cma_prepare_fb(&pipe->plane, plane_state);
}
+#endif
static struct drm_simple_display_pipe_funcs mxsfb_funcs = {
+ .mode_valid = mxsfb_pipe_mode_valid,
+ .check = mxsfb_pipe_check,
.enable = mxsfb_pipe_enable,
.disable = mxsfb_pipe_disable,
.update = mxsfb_pipe_update,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0)
.prepare_fb = mxsfb_pipe_prepare_fb,
+#endif
};
static int mxsfb_load(struct drm_device *drm, unsigned long flags)
@@ -142,6 +397,7 @@ static int mxsfb_load(struct drm_device *drm, unsigned long flags)
struct platform_device *pdev = to_platform_device(drm->dev);
struct mxsfb_drm_private *mxsfb;
struct resource *res;
+ u32 max_res[2] = {0, 0};
int ret;
mxsfb = devm_kzalloc(&pdev->dev, sizeof(*mxsfb), GFP_KERNEL);
@@ -150,13 +406,16 @@ static int mxsfb_load(struct drm_device *drm, unsigned long flags)
drm->dev_private = mxsfb;
mxsfb->devdata = &mxsfb_devdata[pdev->id_entry->driver_data];
+ mxsfb->dev = &pdev->dev;
+
+ platform_set_drvdata(pdev, drm);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
mxsfb->base = devm_ioremap_resource(drm->dev, res);
if (IS_ERR(mxsfb->base))
return PTR_ERR(mxsfb->base);
- mxsfb->clk = devm_clk_get(drm->dev, NULL);
+ mxsfb->clk = devm_clk_get(drm->dev, "pix");
if (IS_ERR(mxsfb->clk))
return PTR_ERR(mxsfb->clk);
@@ -168,16 +427,28 @@ static int mxsfb_load(struct drm_device *drm, unsigned long flags)
if (IS_ERR(mxsfb->clk_disp_axi))
mxsfb->clk_disp_axi = NULL;
+ mxsfb->clk_pll = devm_clk_get(drm->dev, "video_pll");
+ if (IS_ERR(mxsfb->clk_pll))
+ mxsfb->clk_pll = NULL;
+
+ mxsfb->clk_src[0] = devm_clk_get(drm->dev, "osc_25");
+ if (IS_ERR(mxsfb->clk_src[0]))
+ mxsfb->clk_src[0] = NULL;
+
+ mxsfb->clk_src[1] = devm_clk_get(drm->dev, "osc_27");
+ if (IS_ERR(mxsfb->clk_src[1]))
+ mxsfb->clk_src[1] = NULL;
+
+ INIT_LIST_HEAD(&mxsfb->valid_modes);
+
ret = dma_set_mask_and_coherent(drm->dev, DMA_BIT_MASK(32));
if (ret)
return ret;
- pm_runtime_enable(drm->dev);
-
- ret = drm_vblank_init(drm, drm->mode_config.num_crtc);
+ ret = drm_vblank_init(drm, MAX_CRTCS);
if (ret < 0) {
dev_err(drm->dev, "Failed to initialise vblank\n");
- goto err_vblank;
+ return ret;
}
/* Modeset init */
@@ -186,34 +457,59 @@ static int mxsfb_load(struct drm_device *drm, unsigned long flags)
ret = mxsfb_create_output(drm);
if (ret < 0) {
dev_err(drm->dev, "Failed to create outputs\n");
- goto err_vblank;
+ return ret;
}
ret = drm_simple_display_pipe_init(drm, &mxsfb->pipe, &mxsfb_funcs,
- mxsfb_formats, ARRAY_SIZE(mxsfb_formats), NULL,
- &mxsfb->connector);
+ mxsfb_formats, mxsfb->devdata->num_formats, NULL,
+ mxsfb->connector);
if (ret < 0) {
dev_err(drm->dev, "Cannot setup simple display pipe\n");
- goto err_vblank;
+ return ret;
}
- ret = drm_panel_attach(mxsfb->panel, &mxsfb->connector);
- if (ret) {
- dev_err(drm->dev, "Cannot connect panel\n");
- goto err_vblank;
+ drm_crtc_vblank_off(&mxsfb->pipe.crtc);
+
+ /*
+ * Attach panel only if there is one.
+ * If there is no panel attach, it must be a bridge. In this case, we
+ * need a reference to its connector for a proper initialization.
+ * We will do this check in pipe->enable(), since the connector won't
+ * be attached to an encoder until then.
+ */
+
+ if (mxsfb->panel) {
+ ret = drm_panel_attach(mxsfb->panel, mxsfb->connector);
+ if (ret) {
+ dev_err(drm->dev, "Cannot connect panel\n");
+ return ret;
+ }
+ } else if (mxsfb->bridge) {
+ ret = drm_simple_display_pipe_attach_bridge(&mxsfb->pipe,
+ mxsfb->bridge);
+ if (ret) {
+ dev_err(drm->dev, "Cannot connect bridge\n");
+ return ret;
+ }
}
+ of_property_read_u32_array(drm->dev->of_node, "max-res",
+ &max_res[0], 2);
+ if (!max_res[0])
+ max_res[0] = MXSFB_MAX_XRES;
+ if (!max_res[1])
+ max_res[1] = MXSFB_MAX_YRES;
+
drm->mode_config.min_width = MXSFB_MIN_XRES;
drm->mode_config.min_height = MXSFB_MIN_YRES;
- drm->mode_config.max_width = MXSFB_MAX_XRES;
- drm->mode_config.max_height = MXSFB_MAX_YRES;
+ drm->mode_config.max_width = max_res[0];
+ drm->mode_config.max_height = max_res[1];
drm->mode_config.funcs = &mxsfb_mode_config_funcs;
+ drm->mode_config.helper_private = &mxsfb_mode_config_helpers;
drm_mode_config_reset(drm);
- pm_runtime_get_sync(drm->dev);
ret = drm_irq_install(drm, platform_get_irq(pdev, 0));
- pm_runtime_put_sync(drm->dev);
if (ret < 0) {
dev_err(drm->dev, "Failed to install IRQ handler\n");
@@ -231,18 +527,17 @@ static int mxsfb_load(struct drm_device *drm, unsigned long flags)
goto err_cma;
}
- platform_set_drvdata(pdev, drm);
drm_helper_hpd_irq_event(drm);
+ pm_runtime_enable(drm->dev);
+
return 0;
err_cma:
drm_irq_uninstall(drm);
err_irq:
drm_panel_detach(mxsfb->panel);
-err_vblank:
- pm_runtime_disable(drm->dev);
return ret;
}
@@ -250,6 +545,8 @@ err_vblank:
static void mxsfb_unload(struct drm_device *drm)
{
struct mxsfb_drm_private *mxsfb = drm->dev_private;
+ struct mode_config *config;
+ struct list_head *pos, *tmp;
if (mxsfb->fbdev)
drm_fbdev_cma_fini(mxsfb->fbdev);
@@ -261,6 +558,12 @@ static void mxsfb_unload(struct drm_device *drm)
drm_irq_uninstall(drm);
pm_runtime_put_sync(drm->dev);
+ list_for_each_safe(pos, tmp, &mxsfb->valid_modes) {
+ config = list_entry(pos, struct mode_config, list);
+ list_del(pos);
+ devm_kfree(mxsfb->dev, config);
+ }
+
drm->dev_private = NULL;
pm_runtime_disable(drm->dev);
@@ -276,25 +579,31 @@ static void mxsfb_lastclose(struct drm_device *drm)
static int mxsfb_enable_vblank(struct drm_device *drm, unsigned int crtc)
{
struct mxsfb_drm_private *mxsfb = drm->dev_private;
+ int ret = 0;
+
+ ret = clk_prepare_enable(mxsfb->clk_axi);
+ if (ret)
+ return ret;
/* Clear and enable VBLANK IRQ */
- mxsfb_enable_axi_clk(mxsfb);
writel(CTRL1_CUR_FRAME_DONE_IRQ, mxsfb->base + LCDC_CTRL1 + REG_CLR);
writel(CTRL1_CUR_FRAME_DONE_IRQ_EN, mxsfb->base + LCDC_CTRL1 + REG_SET);
- mxsfb_disable_axi_clk(mxsfb);
+ clk_disable_unprepare(mxsfb->clk_axi);
- return 0;
+ return ret;
}
static void mxsfb_disable_vblank(struct drm_device *drm, unsigned int crtc)
{
struct mxsfb_drm_private *mxsfb = drm->dev_private;
+ if (clk_prepare_enable(mxsfb->clk_axi))
+ return;
+
/* Disable and clear VBLANK IRQ */
- mxsfb_enable_axi_clk(mxsfb);
writel(CTRL1_CUR_FRAME_DONE_IRQ_EN, mxsfb->base + LCDC_CTRL1 + REG_CLR);
writel(CTRL1_CUR_FRAME_DONE_IRQ, mxsfb->base + LCDC_CTRL1 + REG_CLR);
- mxsfb_disable_axi_clk(mxsfb);
+ clk_disable_unprepare(mxsfb->clk_axi);
}
static void mxsfb_irq_preinstall(struct drm_device *drm)
@@ -308,7 +617,7 @@ static irqreturn_t mxsfb_irq_handler(int irq, void *data)
struct mxsfb_drm_private *mxsfb = drm->dev_private;
u32 reg;
- mxsfb_enable_axi_clk(mxsfb);
+ clk_prepare_enable(mxsfb->clk_axi);
reg = readl(mxsfb->base + LCDC_CTRL1);
@@ -317,7 +626,7 @@ static irqreturn_t mxsfb_irq_handler(int irq, void *data)
writel(CTRL1_CUR_FRAME_DONE_IRQ, mxsfb->base + LCDC_CTRL1 + REG_CLR);
- mxsfb_disable_axi_clk(mxsfb);
+ clk_disable_unprepare(mxsfb->clk_axi);
return IRQ_HANDLED;
}
@@ -416,13 +725,34 @@ static int mxsfb_remove(struct platform_device *pdev)
return 0;
}
+#ifdef CONFIG_PM_SLEEP
+static int mxsfb_suspend(struct device *dev)
+{
+ struct drm_device *drm = dev_get_drvdata(dev);
+
+ return drm_mode_config_helper_suspend(drm);
+}
+
+static int mxsfb_resume(struct device *dev)
+{
+ struct drm_device *drm = dev_get_drvdata(dev);
+
+ return drm_mode_config_helper_resume(drm);
+}
+#endif
+
+static const struct dev_pm_ops mxsfb_pm_ops = {
+ SET_SYSTEM_SLEEP_PM_OPS(mxsfb_suspend, mxsfb_resume)
+};
+
static struct platform_driver mxsfb_platform_driver = {
.probe = mxsfb_probe,
.remove = mxsfb_remove,
.id_table = mxsfb_devtype,
.driver = {
- .name = "mxsfb",
+ .name = "mxsfb_drm",
.of_match_table = mxsfb_dt_ids,
+ .pm = &mxsfb_pm_ops,
},
};
diff --git a/drivers/gpu/drm/mxsfb/mxsfb_drv.h b/drivers/gpu/drm/mxsfb/mxsfb_drv.h
index 5d0883fc805b..24d573fe5aee 100644
--- a/drivers/gpu/drm/mxsfb/mxsfb_drv.h
+++ b/drivers/gpu/drm/mxsfb/mxsfb_drv.h
@@ -16,6 +16,8 @@
#ifndef __MXSFB_DRV_H__
#define __MXSFB_DRV_H__
+#define MAX_CLK_SRC 2
+
struct mxsfb_devdata {
unsigned int transfer_count;
unsigned int cur_buf;
@@ -24,31 +26,45 @@ struct mxsfb_devdata {
unsigned int hs_wdth_mask;
unsigned int hs_wdth_shift;
unsigned int ipversion;
+ unsigned int flags;
+ unsigned int num_formats;
+};
+
+struct mode_config {
+ struct clk *clk_src;
+ unsigned long out_rate;
+ int clock;
+ int mode_clock;
+ struct list_head list;
};
struct mxsfb_drm_private {
+ struct device *dev;
const struct mxsfb_devdata *devdata;
void __iomem *base; /* registers */
struct clk *clk;
struct clk *clk_axi;
struct clk *clk_disp_axi;
+ struct clk *clk_src[MAX_CLK_SRC];
+ struct clk *clk_sel, *clk_pll;
struct drm_simple_display_pipe pipe;
- struct drm_connector connector;
+ struct drm_connector panel_connector;
+ struct drm_connector *connector;
struct drm_panel *panel;
+ struct drm_bridge *bridge;
struct drm_fbdev_cma *fbdev;
+
+ struct list_head valid_modes;
};
int mxsfb_setup_crtc(struct drm_device *dev);
int mxsfb_create_output(struct drm_device *dev);
-void mxsfb_enable_axi_clk(struct mxsfb_drm_private *mxsfb);
-void mxsfb_disable_axi_clk(struct mxsfb_drm_private *mxsfb);
-
void mxsfb_crtc_enable(struct mxsfb_drm_private *mxsfb);
void mxsfb_crtc_disable(struct mxsfb_drm_private *mxsfb);
void mxsfb_plane_atomic_update(struct mxsfb_drm_private *mxsfb,
- struct drm_plane_state *state);
+ struct drm_plane_state *old_state);
#endif /* __MXSFB_DRV_H__ */
diff --git a/drivers/gpu/drm/mxsfb/mxsfb_out.c b/drivers/gpu/drm/mxsfb/mxsfb_out.c
index e5edf016a439..044d5fbfbce5 100644
--- a/drivers/gpu/drm/mxsfb/mxsfb_out.c
+++ b/drivers/gpu/drm/mxsfb/mxsfb_out.c
@@ -30,7 +30,8 @@
static struct mxsfb_drm_private *
drm_connector_to_mxsfb_drm_private(struct drm_connector *connector)
{
- return container_of(connector, struct mxsfb_drm_private, connector);
+ return container_of(connector, struct mxsfb_drm_private,
+ panel_connector);
}
static int mxsfb_panel_get_modes(struct drm_connector *connector)
@@ -85,22 +86,22 @@ static const struct drm_connector_funcs mxsfb_panel_connector_funcs = {
int mxsfb_create_output(struct drm_device *drm)
{
struct mxsfb_drm_private *mxsfb = drm->dev_private;
- struct drm_panel *panel;
int ret;
- ret = drm_of_find_panel_or_bridge(drm->dev->of_node, 0, 0, &panel, NULL);
+ ret = drm_of_find_panel_or_bridge(drm->dev->of_node, 0, 0, &mxsfb->panel, &mxsfb->bridge);
if (ret)
return ret;
- mxsfb->connector.dpms = DRM_MODE_DPMS_OFF;
- mxsfb->connector.polled = 0;
- drm_connector_helper_add(&mxsfb->connector,
- &mxsfb_panel_connector_helper_funcs);
- ret = drm_connector_init(drm, &mxsfb->connector,
- &mxsfb_panel_connector_funcs,
- DRM_MODE_CONNECTOR_Unknown);
- if (!ret)
- mxsfb->panel = panel;
+ if (mxsfb->panel) {
+ mxsfb->connector = &mxsfb->panel_connector;
+ mxsfb->connector->dpms = DRM_MODE_DPMS_OFF;
+ mxsfb->connector->polled = 0;
+ drm_connector_helper_add(mxsfb->connector,
+ &mxsfb_panel_connector_helper_funcs);
+ ret = drm_connector_init(drm, mxsfb->connector,
+ &mxsfb_panel_connector_funcs,
+ DRM_MODE_CONNECTOR_Unknown);
+ }
return ret;
}
diff --git a/drivers/gpu/drm/mxsfb/mxsfb_regs.h b/drivers/gpu/drm/mxsfb/mxsfb_regs.h
index 66a6ba9ec533..0a4c76dcf229 100644
--- a/drivers/gpu/drm/mxsfb/mxsfb_regs.h
+++ b/drivers/gpu/drm/mxsfb/mxsfb_regs.h
@@ -22,65 +22,103 @@
#define LCDC_CTRL 0x00
#define LCDC_CTRL1 0x10
+#define LCDC_V4_CTRL2 0x20
#define LCDC_V3_TRANSFER_COUNT 0x20
#define LCDC_V4_TRANSFER_COUNT 0x30
#define LCDC_V4_CUR_BUF 0x40
#define LCDC_V4_NEXT_BUF 0x50
#define LCDC_V3_CUR_BUF 0x30
#define LCDC_V3_NEXT_BUF 0x40
+#define LCDC_TIMING 0x60
#define LCDC_VDCTRL0 0x70
#define LCDC_VDCTRL1 0x80
#define LCDC_VDCTRL2 0x90
#define LCDC_VDCTRL3 0xa0
#define LCDC_VDCTRL4 0xb0
+#define LCDC_DVICTRL0 0xc0
+#define LCDC_DVICTRL1 0xd0
+#define LCDC_DVICTRL2 0xe0
+#define LCDC_DVICTRL3 0xf0
+#define LCDC_DVICTRL4 0x100
+#define LCDC_V4_DATA 0x180
+#define LCDC_V3_DATA 0x1b0
#define LCDC_V4_DEBUG0 0x1d0
#define LCDC_V3_DEBUG0 0x1f0
-
-#define CTRL_SFTRST (1 << 31)
-#define CTRL_CLKGATE (1 << 30)
-#define CTRL_BYPASS_COUNT (1 << 19)
-#define CTRL_VSYNC_MODE (1 << 18)
-#define CTRL_DOTCLK_MODE (1 << 17)
-#define CTRL_DATA_SELECT (1 << 16)
-#define CTRL_SET_BUS_WIDTH(x) (((x) & 0x3) << 10)
-#define CTRL_GET_BUS_WIDTH(x) (((x) >> 10) & 0x3)
-#define CTRL_BUS_WIDTH_MASK (0x3 << 10)
-#define CTRL_SET_WORD_LENGTH(x) (((x) & 0x3) << 8)
-#define CTRL_GET_WORD_LENGTH(x) (((x) >> 8) & 0x3)
-#define CTRL_MASTER (1 << 5)
-#define CTRL_DF16 (1 << 3)
-#define CTRL_DF18 (1 << 2)
-#define CTRL_DF24 (1 << 1)
-#define CTRL_RUN (1 << 0)
-
-#define CTRL1_FIFO_CLEAR (1 << 21)
-#define CTRL1_SET_BYTE_PACKAGING(x) (((x) & 0xf) << 16)
-#define CTRL1_GET_BYTE_PACKAGING(x) (((x) >> 16) & 0xf)
-#define CTRL1_CUR_FRAME_DONE_IRQ_EN (1 << 13)
-#define CTRL1_CUR_FRAME_DONE_IRQ (1 << 9)
+#define LCDC_AS_CTRL 0x210
+#define LCDC_AS_BUF 0x220
+#define LCDC_AS_NEXT_BUF 0x230
+
+/* reg bit manipulation */
+#define REG_MASK(e, s) (((1 << ((e) - (s) + 1)) - 1) << (s))
+#define REG_PUT(x, e, s) (((x) << (s)) & REG_MASK(e, s))
+#define REG_GET(x, e, s) (((x) & REG_MASK(e, s)) >> (s))
+
+#define SWIZZLE_LE 0 /* Little-Endian or No swap */
+#define SWIZZLE_BE 1 /* Big-Endian or swap all */
+#define SWIZZLE_HWD 2 /* Swap half-words */
+#define SWIZZLE_HWD_BYTE 3 /* Swap bytes within each half-word */
+
+#define CTRL_SFTRST BIT(31)
+#define CTRL_CLKGATE BIT(30)
+#define CTRL_SHIFT_DIR(x) REG_PUT((x), 26, 26)
+#define CTRL_SHIFT_NUM(x) REG_PUT((x), 25, 21)
+#define CTRL_BYPASS_COUNT BIT(19)
+#define CTRL_VSYNC_MODE BIT(18)
+#define CTRL_DOTCLK_MODE BIT(17)
+#define CTRL_DATA_SELECT BIT(16)
+#define CTRL_INPUT_SWIZZLE(x) REG_PUT((x), 15, 14)
+#define CTRL_CSC_SWIZZLE(x) REG_PUT((x), 13, 12)
+#define CTRL_SET_BUS_WIDTH(x) REG_PUT((x), 11, 10)
+#define CTRL_GET_BUS_WIDTH(x) REG_GET((x), 11, 10)
+#define CTRL_BUS_WIDTH_MASK REG_PUT((0x3), 11, 10)
+#define CTRL_SET_WORD_LENGTH(x) REG_PUT((x), 9, 8)
+#define CTRL_GET_WORD_LENGTH(x) REG_GET((x), 9, 8)
+#define CTRL_MASTER BIT(5)
+#define CTRL_DF16 BIT(3)
+#define CTRL_DF18 BIT(2)
+#define CTRL_DF24 BIT(1)
+#define CTRL_RUN BIT(0)
+
+#define CTRL1_RECOVERY_ON_UNDERFLOW BIT(24)
+#define CTRL1_FIFO_CLEAR BIT(21)
+#define CTRL1_SET_BYTE_PACKAGING(x) REG_PUT((x), 19, 16)
+#define CTRL1_GET_BYTE_PACKAGING(x) REG_GET((x), 19, 16)
+#define CTRL1_CUR_FRAME_DONE_IRQ_EN BIT(13)
+#define CTRL1_CUR_FRAME_DONE_IRQ BIT(9)
+
+#define REQ_1 0
+#define REQ_2 1
+#define REQ_4 2
+#define REQ_8 3
+#define REQ_16 4
+
+#define CTRL2_OUTSTANDING_REQS(x) REG_PUT((x), 23, 21)
+#define CTRL2_ODD_LINE_PATTERN(x) REG_PUT((x), 18, 16)
+#define CTRL2_EVEN_LINE_PATTERN(x) REG_PUT((x), 14, 12)
+#define CTRL2_LCD_RESET BIT(0)
#define TRANSFER_COUNT_SET_VCOUNT(x) (((x) & 0xffff) << 16)
#define TRANSFER_COUNT_GET_VCOUNT(x) (((x) >> 16) & 0xffff)
#define TRANSFER_COUNT_SET_HCOUNT(x) ((x) & 0xffff)
#define TRANSFER_COUNT_GET_HCOUNT(x) ((x) & 0xffff)
-#define VDCTRL0_ENABLE_PRESENT (1 << 28)
-#define VDCTRL0_VSYNC_ACT_HIGH (1 << 27)
-#define VDCTRL0_HSYNC_ACT_HIGH (1 << 26)
-#define VDCTRL0_DOTCLK_ACT_FALLING (1 << 25)
-#define VDCTRL0_ENABLE_ACT_HIGH (1 << 24)
-#define VDCTRL0_VSYNC_PERIOD_UNIT (1 << 21)
-#define VDCTRL0_VSYNC_PULSE_WIDTH_UNIT (1 << 20)
-#define VDCTRL0_HALF_LINE (1 << 19)
-#define VDCTRL0_HALF_LINE_MODE (1 << 18)
+#define VDCTRL0_ENABLE_PRESENT BIT(28)
+#define VDCTRL0_VSYNC_ACT_HIGH BIT(27)
+#define VDCTRL0_HSYNC_ACT_HIGH BIT(26)
+#define VDCTRL0_DOTCLK_ACT_FALLING BIT(25)
+#define VDCTRL0_ENABLE_ACT_HIGH BIT(24)
+#define VDCTRL0_VSYNC_PERIOD_UNIT BIT(21)
+#define VDCTRL0_VSYNC_PULSE_WIDTH_UNIT BIT(20)
+#define VDCTRL0_HALF_LINE BIT(19)
+#define VDCTRL0_HALF_LINE_MODE BIT(18)
#define VDCTRL0_SET_VSYNC_PULSE_WIDTH(x) ((x) & 0x3ffff)
#define VDCTRL0_GET_VSYNC_PULSE_WIDTH(x) ((x) & 0x3ffff)
#define VDCTRL2_SET_HSYNC_PERIOD(x) ((x) & 0x3ffff)
#define VDCTRL2_GET_HSYNC_PERIOD(x) ((x) & 0x3ffff)
-#define VDCTRL3_MUX_SYNC_SIGNALS (1 << 29)
-#define VDCTRL3_VSYNC_ONLY (1 << 28)
+#define VDCTRL3_MUX_SYNC_SIGNALS BIT(29)
+#define VDCTRL3_VSYNC_ONLY BIT(28)
#define SET_HOR_WAIT_CNT(x) (((x) & 0xfff) << 16)
#define GET_HOR_WAIT_CNT(x) (((x) >> 16) & 0xfff)
#define SET_VERT_WAIT_CNT(x) ((x) & 0xffff)
@@ -88,7 +126,7 @@
#define VDCTRL4_SET_DOTCLK_DLY(x) (((x) & 0x7) << 29) /* v4 only */
#define VDCTRL4_GET_DOTCLK_DLY(x) (((x) >> 29) & 0x7) /* v4 only */
-#define VDCTRL4_SYNC_SIGNALS_ON (1 << 18)
+#define VDCTRL4_SYNC_SIGNALS_ON BIT(18)
#define SET_DOTCLK_H_VALID_DATA_CNT(x) ((x) & 0x3ffff)
#define DEBUG0_HSYNC (1 < 26)
@@ -109,7 +147,10 @@
#define STMLCDIF_18BIT 2 /* pixel data bus to the display is of 18 bit width */
#define STMLCDIF_24BIT 3 /* pixel data bus to the display is of 24 bit width */
-#define MXSFB_SYNC_DATA_ENABLE_HIGH_ACT (1 << 6)
-#define MXSFB_SYNC_DOTCLK_FALLING_ACT (1 << 7) /* negative edge sampling */
+#define MXSFB_SYNC_DATA_ENABLE_HIGH_ACT BIT(6)
+#define MXSFB_SYNC_DOTCLK_FALLING_ACT BIT(7) /* negative edge sampling */
+
+#define MXSFB_FLAG_NULL BIT(0)
+#define MXSFB_FLAG_BUSFREQ BIT(1)
#endif /* __MXSFB_REGS_H__ */
diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c
index 4a7d50a96d36..b32c0c93b71f 100644
--- a/drivers/gpu/drm/nouveau/nouveau_connector.c
+++ b/drivers/gpu/drm/nouveau/nouveau_connector.c
@@ -373,7 +373,7 @@ find_encoder(struct drm_connector *connector, int type)
if (!id)
break;
- enc = drm_encoder_find(dev, id);
+ enc = drm_encoder_find(dev, NULL, id);
if (!enc)
continue;
nv_encoder = nouveau_encoder(enc);
@@ -441,7 +441,7 @@ nouveau_connector_ddc_detect(struct drm_connector *connector)
if (id == 0)
break;
- encoder = drm_encoder_find(dev, id);
+ encoder = drm_encoder_find(dev, NULL, id);
if (!encoder)
continue;
nv_encoder = nouveau_encoder(encoder);
diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig
index d84a031fae24..eb2a74629a4b 100644
--- a/drivers/gpu/drm/panel/Kconfig
+++ b/drivers/gpu/drm/panel/Kconfig
@@ -86,6 +86,15 @@ config DRM_PANEL_SAMSUNG_S6E8AA0
select DRM_MIPI_DSI
select VIDEOMODE_HELPERS
+config DRM_PANEL_SEIKO_43WVF1G
+ tristate "Seiko 43WVF1G panel"
+ depends on OF
+ depends on BACKLIGHT_CLASS_DEVICE
+ select VIDEOMODE_HELPERS
+ help
+ Say Y here if you want to enable support for the Seiko
+ 43WVF1G controller for 800x480 LCD panels
+
config DRM_PANEL_SHARP_LQ101R1SX01
tristate "Sharp LQ101R1SX01 panel"
depends on OF
@@ -117,4 +126,13 @@ config DRM_PANEL_SITRONIX_ST7789V
Say Y here if you want to enable support for the Sitronix
ST7789V controller for 240x320 LCD panels
+config DRM_PANEL_RAYDIUM_RM67191
+ tristate "Raydium RM67191 FHD 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 Raydium RM67191 FHD
+ (1080x1920) DSI panel.
+
endmenu
diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile
index d73d3e661cec..68a80b13403f 100644
--- a/drivers/gpu/drm/panel/Makefile
+++ b/drivers/gpu/drm/panel/Makefile
@@ -8,6 +8,8 @@ obj-$(CONFIG_DRM_PANEL_PANASONIC_VVX10F034N00) += panel-panasonic-vvx10f034n00.o
obj-$(CONFIG_DRM_PANEL_SAMSUNG_LD9040) += panel-samsung-ld9040.o
obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6E3HA2) += panel-samsung-s6e3ha2.o
obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6E8AA0) += panel-samsung-s6e8aa0.o
+obj-$(CONFIG_DRM_PANEL_SEIKO_43WVF1G) += panel-seiko-43wvf1g.o
obj-$(CONFIG_DRM_PANEL_SHARP_LQ101R1SX01) += panel-sharp-lq101r1sx01.o
obj-$(CONFIG_DRM_PANEL_SHARP_LS043T1LE01) += panel-sharp-ls043t1le01.o
obj-$(CONFIG_DRM_PANEL_SITRONIX_ST7789V) += panel-sitronix-st7789v.o
+obj-$(CONFIG_DRM_PANEL_RAYDIUM_RM67191) += panel-raydium-rm67191.o
diff --git a/drivers/gpu/drm/panel/panel-raydium-rm67191.c b/drivers/gpu/drm/panel/panel-raydium-rm67191.c
new file mode 100644
index 000000000000..7e9682af063b
--- /dev/null
+++ b/drivers/gpu/drm/panel/panel-raydium-rm67191.c
@@ -0,0 +1,731 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * i.MX drm driver - Raydium MIPI-DSI panel driver
+ *
+ * Copyright (C) 2017 NXP
+ *
+ * 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 <drm/drmP.h>
+#include <drm/drm_crtc.h>
+#include <drm/drm_mipi_dsi.h>
+#include <drm/drm_panel.h>
+#include <linux/gpio/consumer.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/regulator/consumer.h>
+#include <video/mipi_display.h>
+#include <video/of_videomode.h>
+#include <video/videomode.h>
+
+/* Write Manufacture Command Set Control */
+#define WRMAUCCTR 0xFE
+
+/* Manufacturer Command Set pages (CMD2) */
+struct cmd_set_entry {
+ u8 cmd;
+ u8 param;
+};
+
+/*
+ * There is no description in the Reference Manual about these commands.
+ * We received them from vendor, so just use them as is.
+ */
+static const struct cmd_set_entry manufacturer_cmd_set[] = {
+ {0xFE, 0x0B},
+ {0x28, 0x40},
+ {0x29, 0x4F},
+ {0xFE, 0x0E},
+ {0x4B, 0x00},
+ {0x4C, 0x0F},
+ {0x4D, 0x20},
+ {0x4E, 0x40},
+ {0x4F, 0x60},
+ {0x50, 0xA0},
+ {0x51, 0xC0},
+ {0x52, 0xE0},
+ {0x53, 0xFF},
+ {0xFE, 0x0D},
+ {0x18, 0x08},
+ {0x42, 0x00},
+ {0x08, 0x41},
+ {0x46, 0x02},
+ {0x72, 0x09},
+ {0xFE, 0x0A},
+ {0x24, 0x17},
+ {0x04, 0x07},
+ {0x1A, 0x0C},
+ {0x0F, 0x44},
+ {0xFE, 0x04},
+ {0x00, 0x0C},
+ {0x05, 0x08},
+ {0x06, 0x08},
+ {0x08, 0x08},
+ {0x09, 0x08},
+ {0x0A, 0xE6},
+ {0x0B, 0x8C},
+ {0x1A, 0x12},
+ {0x1E, 0xE0},
+ {0x29, 0x93},
+ {0x2A, 0x93},
+ {0x2F, 0x02},
+ {0x31, 0x02},
+ {0x33, 0x05},
+ {0x37, 0x2D},
+ {0x38, 0x2D},
+ {0x3A, 0x1E},
+ {0x3B, 0x1E},
+ {0x3D, 0x27},
+ {0x3F, 0x80},
+ {0x40, 0x40},
+ {0x41, 0xE0},
+ {0x4F, 0x2F},
+ {0x50, 0x1E},
+ {0xFE, 0x06},
+ {0x00, 0xCC},
+ {0x05, 0x05},
+ {0x07, 0xA2},
+ {0x08, 0xCC},
+ {0x0D, 0x03},
+ {0x0F, 0xA2},
+ {0x32, 0xCC},
+ {0x37, 0x05},
+ {0x39, 0x83},
+ {0x3A, 0xCC},
+ {0x41, 0x04},
+ {0x43, 0x83},
+ {0x44, 0xCC},
+ {0x49, 0x05},
+ {0x4B, 0xA2},
+ {0x4C, 0xCC},
+ {0x51, 0x03},
+ {0x53, 0xA2},
+ {0x75, 0xCC},
+ {0x7A, 0x03},
+ {0x7C, 0x83},
+ {0x7D, 0xCC},
+ {0x82, 0x02},
+ {0x84, 0x83},
+ {0x85, 0xEC},
+ {0x86, 0x0F},
+ {0x87, 0xFF},
+ {0x88, 0x00},
+ {0x8A, 0x02},
+ {0x8C, 0xA2},
+ {0x8D, 0xEA},
+ {0x8E, 0x01},
+ {0x8F, 0xE8},
+ {0xFE, 0x06},
+ {0x90, 0x0A},
+ {0x92, 0x06},
+ {0x93, 0xA0},
+ {0x94, 0xA8},
+ {0x95, 0xEC},
+ {0x96, 0x0F},
+ {0x97, 0xFF},
+ {0x98, 0x00},
+ {0x9A, 0x02},
+ {0x9C, 0xA2},
+ {0xAC, 0x04},
+ {0xFE, 0x06},
+ {0xB1, 0x12},
+ {0xB2, 0x17},
+ {0xB3, 0x17},
+ {0xB4, 0x17},
+ {0xB5, 0x17},
+ {0xB6, 0x11},
+ {0xB7, 0x08},
+ {0xB8, 0x09},
+ {0xB9, 0x06},
+ {0xBA, 0x07},
+ {0xBB, 0x17},
+ {0xBC, 0x17},
+ {0xBD, 0x17},
+ {0xBE, 0x17},
+ {0xBF, 0x17},
+ {0xC0, 0x17},
+ {0xC1, 0x17},
+ {0xC2, 0x17},
+ {0xC3, 0x17},
+ {0xC4, 0x0F},
+ {0xC5, 0x0E},
+ {0xC6, 0x00},
+ {0xC7, 0x01},
+ {0xC8, 0x10},
+ {0xFE, 0x06},
+ {0x95, 0xEC},
+ {0x8D, 0xEE},
+ {0x44, 0xEC},
+ {0x4C, 0xEC},
+ {0x32, 0xEC},
+ {0x3A, 0xEC},
+ {0x7D, 0xEC},
+ {0x75, 0xEC},
+ {0x00, 0xEC},
+ {0x08, 0xEC},
+ {0x85, 0xEC},
+ {0xA6, 0x21},
+ {0xA7, 0x05},
+ {0xA9, 0x06},
+ {0x82, 0x06},
+ {0x41, 0x06},
+ {0x7A, 0x07},
+ {0x37, 0x07},
+ {0x05, 0x06},
+ {0x49, 0x06},
+ {0x0D, 0x04},
+ {0x51, 0x04},
+};
+
+static const u32 rad_bus_formats[] = {
+ MEDIA_BUS_FMT_RGB888_1X24,
+ MEDIA_BUS_FMT_RGB666_1X18,
+ MEDIA_BUS_FMT_RGB565_1X16,
+};
+
+struct rad_panel {
+ struct drm_panel base;
+ struct mipi_dsi_device *dsi;
+
+ struct gpio_desc *reset;
+ struct backlight_device *backlight;
+
+ bool prepared;
+ bool enabled;
+
+ struct videomode vm;
+ u32 width_mm;
+ u32 height_mm;
+};
+
+static inline struct rad_panel *to_rad_panel(struct drm_panel *panel)
+{
+ return container_of(panel, struct rad_panel, base);
+}
+
+static int rad_panel_push_cmd_list(struct mipi_dsi_device *dsi)
+{
+ size_t i;
+ size_t count = ARRAY_SIZE(manufacturer_cmd_set);
+ int ret = 0;
+
+ for (i = 0; i < count; i++) {
+ const struct cmd_set_entry *entry = &manufacturer_cmd_set[i];
+ u8 buffer[2] = { entry->cmd, entry->param };
+
+ ret = mipi_dsi_generic_write(dsi, &buffer, sizeof(buffer));
+ if (ret < 0)
+ return ret;
+ }
+
+ return ret;
+};
+
+static int color_format_from_dsi_format(enum mipi_dsi_pixel_format format)
+{
+ switch (format) {
+ case MIPI_DSI_FMT_RGB565:
+ return 0x55;
+ case MIPI_DSI_FMT_RGB666:
+ case MIPI_DSI_FMT_RGB666_PACKED:
+ return 0x66;
+ case MIPI_DSI_FMT_RGB888:
+ return 0x77;
+ default:
+ return 0x77; /* for backward compatibility */
+ }
+};
+
+static int rad_panel_prepare(struct drm_panel *panel)
+{
+ struct rad_panel *rad = to_rad_panel(panel);
+
+ if (rad->prepared)
+ return 0;
+
+ if (rad->reset != NULL) {
+ gpiod_set_value(rad->reset, 0);
+ usleep_range(5000, 10000);
+ gpiod_set_value(rad->reset, 1);
+ usleep_range(20000, 25000);
+ }
+
+ rad->prepared = true;
+
+ return 0;
+}
+
+static int rad_panel_unprepare(struct drm_panel *panel)
+{
+ struct rad_panel *rad = to_rad_panel(panel);
+ struct device *dev = &rad->dsi->dev;
+
+ if (!rad->prepared)
+ return 0;
+
+ if (rad->enabled) {
+ DRM_DEV_ERROR(dev, "Panel still enabled!\n");
+ return -EPERM;
+ }
+
+ if (rad->reset != NULL) {
+ gpiod_set_value(rad->reset, 0);
+ usleep_range(15000, 17000);
+ gpiod_set_value(rad->reset, 1);
+ }
+
+ rad->prepared = false;
+
+ return 0;
+}
+
+static int rad_panel_enable(struct drm_panel *panel)
+{
+ struct rad_panel *rad = to_rad_panel(panel);
+ struct mipi_dsi_device *dsi = rad->dsi;
+ struct device *dev = &dsi->dev;
+ int color_format = color_format_from_dsi_format(dsi->format);
+ u16 brightness;
+ int ret;
+
+ if (rad->enabled)
+ return 0;
+
+ if (!rad->prepared) {
+ DRM_DEV_ERROR(dev, "Panel not prepared!\n");
+ return -EPERM;
+ }
+
+ dsi->mode_flags |= MIPI_DSI_MODE_LPM;
+
+ ret = rad_panel_push_cmd_list(dsi);
+ if (ret < 0) {
+ DRM_DEV_ERROR(dev, "Failed to send MCS (%d)\n", ret);
+ goto fail;
+ }
+
+ /* Select User Command Set table (CMD1) */
+ ret = mipi_dsi_generic_write(dsi, (u8[]){ WRMAUCCTR, 0x00 }, 2);
+ if (ret < 0)
+ goto fail;
+
+ /* Software reset */
+ ret = mipi_dsi_dcs_soft_reset(dsi);
+ if (ret < 0) {
+ DRM_DEV_ERROR(dev, "Failed to do Software Reset (%d)\n", ret);
+ goto fail;
+ }
+
+ usleep_range(15000, 17000);
+
+ /* Set DSI mode */
+ ret = mipi_dsi_generic_write(dsi, (u8[]){ 0xC2, 0x0B }, 2);
+ if (ret < 0) {
+ DRM_DEV_ERROR(dev, "Failed to set DSI mode (%d)\n", ret);
+ goto fail;
+ }
+ /* Set tear ON */
+ ret = mipi_dsi_dcs_set_tear_on(dsi, MIPI_DSI_DCS_TEAR_MODE_VBLANK);
+ if (ret < 0) {
+ DRM_DEV_ERROR(dev, "Failed to set tear ON (%d)\n", ret);
+ goto fail;
+ }
+ /* Set tear scanline */
+ ret = mipi_dsi_dcs_set_tear_scanline(dsi, 0x380);
+ if (ret < 0) {
+ DRM_DEV_ERROR(dev, "Failed to set tear scanline (%d)\n", ret);
+ goto fail;
+ }
+ /* Set pixel format */
+ ret = mipi_dsi_dcs_set_pixel_format(dsi, color_format);
+ DRM_DEV_DEBUG_DRIVER(dev, "Interface color format set to 0x%x\n",
+ color_format);
+ if (ret < 0) {
+ DRM_DEV_ERROR(dev, "Failed to set pixel format (%d)\n", ret);
+ goto fail;
+ }
+ /* Set display brightness */
+ brightness = rad->backlight->props.brightness;
+ ret = mipi_dsi_dcs_set_display_brightness(dsi, brightness);
+ if (ret < 0) {
+ DRM_DEV_ERROR(dev, "Failed to set display brightness (%d)\n",
+ ret);
+ goto fail;
+ }
+ /* Exit sleep mode */
+ ret = mipi_dsi_dcs_exit_sleep_mode(dsi);
+ if (ret < 0) {
+ DRM_DEV_ERROR(dev, "Failed to exit sleep mode (%d)\n", ret);
+ goto fail;
+ }
+
+ usleep_range(5000, 10000);
+
+ ret = mipi_dsi_dcs_set_display_on(dsi);
+ if (ret < 0) {
+ DRM_DEV_ERROR(dev, "Failed to set display ON (%d)\n", ret);
+ goto fail;
+ }
+
+ backlight_enable(rad->backlight);
+
+ rad->enabled = true;
+
+ return 0;
+
+fail:
+ if (rad->reset != NULL)
+ gpiod_set_value(rad->reset, 0);
+
+ return ret;
+}
+
+static int rad_panel_disable(struct drm_panel *panel)
+{
+ struct rad_panel *rad = to_rad_panel(panel);
+ struct mipi_dsi_device *dsi = rad->dsi;
+ struct device *dev = &dsi->dev;
+ int ret;
+
+ if (!rad->enabled)
+ return 0;
+
+ dsi->mode_flags |= MIPI_DSI_MODE_LPM;
+
+ backlight_disable(rad->backlight);
+
+ usleep_range(10000, 15000);
+
+ ret = mipi_dsi_dcs_set_display_off(dsi);
+ if (ret < 0) {
+ DRM_DEV_ERROR(dev, "Failed to set display OFF (%d)\n", ret);
+ return ret;
+ }
+
+ usleep_range(5000, 10000);
+
+ ret = mipi_dsi_dcs_enter_sleep_mode(dsi);
+ if (ret < 0) {
+ DRM_DEV_ERROR(dev, "Failed to enter sleep mode (%d)\n", ret);
+ return ret;
+ }
+
+ rad->enabled = false;
+
+ return 0;
+}
+
+static int rad_panel_get_modes(struct drm_panel *panel)
+{
+ struct rad_panel *rad = to_rad_panel(panel);
+ struct device *dev = &rad->dsi->dev;
+ struct drm_connector *connector = panel->connector;
+ struct drm_display_mode *mode;
+ u32 *bus_flags = &connector->display_info.bus_flags;
+ int ret;
+
+ mode = drm_mode_create(connector->dev);
+ if (!mode) {
+ DRM_DEV_ERROR(dev, "Failed to create display mode!\n");
+ return 0;
+ }
+
+ drm_display_mode_from_videomode(&rad->vm, mode);
+ mode->width_mm = rad->width_mm;
+ mode->height_mm = rad->height_mm;
+ connector->display_info.width_mm = rad->width_mm;
+ connector->display_info.height_mm = rad->height_mm;
+ mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
+
+ if (rad->vm.flags & DISPLAY_FLAGS_DE_HIGH)
+ *bus_flags |= DRM_BUS_FLAG_DE_HIGH;
+ if (rad->vm.flags & DISPLAY_FLAGS_DE_LOW)
+ *bus_flags |= DRM_BUS_FLAG_DE_LOW;
+ if (rad->vm.flags & DISPLAY_FLAGS_PIXDATA_NEGEDGE)
+ *bus_flags |= DRM_BUS_FLAG_PIXDATA_NEGEDGE;
+ if (rad->vm.flags & DISPLAY_FLAGS_PIXDATA_POSEDGE)
+ *bus_flags |= DRM_BUS_FLAG_PIXDATA_POSEDGE;
+
+ ret = drm_display_info_set_bus_formats(&connector->display_info,
+ rad_bus_formats, ARRAY_SIZE(rad_bus_formats));
+ if (ret)
+ return ret;
+
+ drm_mode_probed_add(panel->connector, mode);
+
+ return 1;
+}
+
+static int rad_bl_get_brightness(struct backlight_device *bl)
+{
+ struct mipi_dsi_device *dsi = bl_get_data(bl);
+ struct rad_panel *rad = mipi_dsi_get_drvdata(dsi);
+ struct device *dev = &dsi->dev;
+ u16 brightness;
+ int ret;
+
+ if (!rad->prepared)
+ return 0;
+
+ DRM_DEV_DEBUG_DRIVER(dev, "\n");
+
+ dsi->mode_flags &= ~MIPI_DSI_MODE_LPM;
+
+ ret = mipi_dsi_dcs_get_display_brightness(dsi, &brightness);
+ if (ret < 0)
+ return ret;
+
+ bl->props.brightness = brightness;
+
+ return brightness & 0xff;
+}
+
+static int rad_bl_update_status(struct backlight_device *bl)
+{
+ struct mipi_dsi_device *dsi = bl_get_data(bl);
+ struct rad_panel *rad = mipi_dsi_get_drvdata(dsi);
+ struct device *dev = &dsi->dev;
+ int ret = 0;
+
+ if (!rad->prepared)
+ return 0;
+
+ DRM_DEV_DEBUG_DRIVER(dev, "New brightness: %d\n", bl->props.brightness);
+
+ dsi->mode_flags &= ~MIPI_DSI_MODE_LPM;
+
+ ret = mipi_dsi_dcs_set_display_brightness(dsi, bl->props.brightness);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
+static const struct backlight_ops rad_bl_ops = {
+ .update_status = rad_bl_update_status,
+ .get_brightness = rad_bl_get_brightness,
+};
+
+static const struct drm_panel_funcs rad_panel_funcs = {
+ .prepare = rad_panel_prepare,
+ .unprepare = rad_panel_unprepare,
+ .enable = rad_panel_enable,
+ .disable = rad_panel_disable,
+ .get_modes = rad_panel_get_modes,
+};
+
+/*
+ * The clock might range from 66MHz (30Hz refresh rate)
+ * to 132MHz (60Hz refresh rate)
+ */
+static const struct display_timing rad_default_timing = {
+ .pixelclock = { 66000000, 132000000, 132000000 },
+ .hactive = { 1080, 1080, 1080 },
+ .hfront_porch = { 20, 20, 20 },
+ .hsync_len = { 2, 2, 2 },
+ .hback_porch = { 34, 34, 34 },
+ .vactive = { 1920, 1920, 1920 },
+ .vfront_porch = { 10, 10, 10 },
+ .vsync_len = { 2, 2, 2 },
+ .vback_porch = { 4, 4, 4 },
+ .flags = DISPLAY_FLAGS_HSYNC_LOW |
+ DISPLAY_FLAGS_VSYNC_LOW |
+ DISPLAY_FLAGS_DE_LOW |
+ DISPLAY_FLAGS_PIXDATA_NEGEDGE,
+};
+
+static int rad_panel_probe(struct mipi_dsi_device *dsi)
+{
+ struct device *dev = &dsi->dev;
+ struct device_node *np = dev->of_node;
+ struct device_node *timings;
+ struct rad_panel *panel;
+ struct backlight_properties bl_props;
+ int ret;
+ u32 video_mode;
+
+ panel = devm_kzalloc(&dsi->dev, sizeof(*panel), GFP_KERNEL);
+ if (!panel)
+ return -ENOMEM;
+
+ mipi_dsi_set_drvdata(dsi, panel);
+
+ panel->dsi = dsi;
+
+ dsi->format = MIPI_DSI_FMT_RGB888;
+ dsi->mode_flags = MIPI_DSI_MODE_VIDEO_HSE | MIPI_DSI_MODE_VIDEO |
+ MIPI_DSI_CLOCK_NON_CONTINUOUS;
+
+ ret = of_property_read_u32(np, "video-mode", &video_mode);
+ if (!ret) {
+ switch (video_mode) {
+ case 0:
+ /* burst mode */
+ dsi->mode_flags |= MIPI_DSI_MODE_VIDEO_BURST;
+ break;
+ case 1:
+ /* non-burst mode with sync event */
+ break;
+ case 2:
+ /* non-burst mode with sync pulse */
+ dsi->mode_flags |= MIPI_DSI_MODE_VIDEO_SYNC_PULSE;
+ break;
+ default:
+ dev_warn(dev, "invalid video mode %d\n", video_mode);
+ break;
+
+ }
+ }
+
+ ret = of_property_read_u32(np, "dsi-lanes", &dsi->lanes);
+ if (ret < 0) {
+ dev_err(dev, "Failed to get dsi-lanes property (%d)\n", ret);
+ return ret;
+ }
+
+ /*
+ * 'display-timings' is optional, so verify if the node is present
+ * before calling of_get_videomode so we won't get console error
+ * messages
+ */
+ timings = of_get_child_by_name(np, "display-timings");
+ if (timings) {
+ of_node_put(timings);
+ ret = of_get_videomode(np, &panel->vm, 0);
+ } else {
+ videomode_from_timing(&rad_default_timing, &panel->vm);
+ }
+ if (ret < 0)
+ return ret;
+
+ of_property_read_u32(np, "panel-width-mm", &panel->width_mm);
+ of_property_read_u32(np, "panel-height-mm", &panel->height_mm);
+
+ panel->reset = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH);
+
+ if (IS_ERR(panel->reset))
+ panel->reset = NULL;
+ else
+ gpiod_set_value(panel->reset, 0);
+
+
+ memset(&bl_props, 0, sizeof(bl_props));
+ bl_props.type = BACKLIGHT_RAW;
+ bl_props.brightness = 255;
+ bl_props.max_brightness = 255;
+
+ panel->backlight = devm_backlight_device_register(
+ dev, dev_name(dev),
+ dev, dsi,
+ &rad_bl_ops, &bl_props);
+ if (IS_ERR(panel->backlight)) {
+ ret = PTR_ERR(panel->backlight);
+ dev_err(dev, "Failed to register backlight (%d)\n", ret);
+ return ret;
+ }
+
+ drm_panel_init(&panel->base);
+ panel->base.funcs = &rad_panel_funcs;
+ panel->base.dev = dev;
+ dev_set_drvdata(dev, panel);
+
+ ret = drm_panel_add(&panel->base);
+
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_attach(dsi);
+ if (ret < 0)
+ drm_panel_remove(&panel->base);
+
+ return ret;
+}
+
+static int rad_panel_remove(struct mipi_dsi_device *dsi)
+{
+ struct rad_panel *rad = mipi_dsi_get_drvdata(dsi);
+ struct device *dev = &dsi->dev;
+ int ret;
+
+ ret = mipi_dsi_detach(dsi);
+ if (ret < 0)
+ DRM_DEV_ERROR(dev, "Failed to detach from host (%d)\n",
+ ret);
+
+ drm_panel_remove(&rad->base);
+
+ return 0;
+}
+
+static void rad_panel_shutdown(struct mipi_dsi_device *dsi)
+{
+ struct rad_panel *rad = mipi_dsi_get_drvdata(dsi);
+
+ rad_panel_disable(&rad->base);
+ rad_panel_unprepare(&rad->base);
+}
+
+#ifdef CONFIG_PM
+static int rad_panel_suspend(struct device *dev)
+{
+ struct rad_panel *rad = dev_get_drvdata(dev);
+
+ if (!rad->reset)
+ return 0;
+
+ devm_gpiod_put(dev, rad->reset);
+ rad->reset = NULL;
+
+ return 0;
+}
+
+static int rad_panel_resume(struct device *dev)
+{
+ struct rad_panel *rad = dev_get_drvdata(dev);
+
+ if (rad->reset)
+ return 0;
+
+ rad->reset = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH);
+ if (IS_ERR(rad->reset))
+ rad->reset = NULL;
+
+ return PTR_ERR_OR_ZERO(rad->reset);
+}
+
+#endif
+
+static const struct dev_pm_ops rad_pm_ops = {
+ SET_RUNTIME_PM_OPS(rad_panel_suspend, rad_panel_resume, NULL)
+ SET_SYSTEM_SLEEP_PM_OPS(rad_panel_suspend, rad_panel_resume)
+};
+
+static const struct of_device_id rad_of_match[] = {
+ { .compatible = "raydium,rm67191", },
+ { }
+};
+MODULE_DEVICE_TABLE(of, rad_of_match);
+
+static struct mipi_dsi_driver rad_panel_driver = {
+ .driver = {
+ .name = "panel-raydium-rm67191",
+ .of_match_table = rad_of_match,
+ .pm = &rad_pm_ops,
+ },
+ .probe = rad_panel_probe,
+ .remove = rad_panel_remove,
+ .shutdown = rad_panel_shutdown,
+};
+module_mipi_dsi_driver(rad_panel_driver);
+
+MODULE_AUTHOR("Robert Chiras <robert.chiras@nxp.com>");
+MODULE_DESCRIPTION("DRM Driver for Raydium RM67191 MIPI DSI panel");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/gpu/drm/panel/panel-seiko-43wvf1g.c b/drivers/gpu/drm/panel/panel-seiko-43wvf1g.c
new file mode 100644
index 000000000000..71c09ed436ae
--- /dev/null
+++ b/drivers/gpu/drm/panel/panel-seiko-43wvf1g.c
@@ -0,0 +1,372 @@
+/*
+ * Copyright (C) 2017 NXP Semiconductors.
+ * Author: Marco Franchi <marco.franchi@nxp.com>
+ *
+ * Based on Panel Simple driver by Thierry Reding <treding@nvidia.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/backlight.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/regulator/consumer.h>
+
+#include <drm/drmP.h>
+#include <drm/drm_crtc.h>
+#include <drm/drm_panel.h>
+
+#include <video/display_timing.h>
+#include <video/videomode.h>
+
+struct seiko_panel_desc {
+ const struct drm_display_mode *modes;
+ unsigned int num_modes;
+ const struct display_timing *timings;
+ unsigned int num_timings;
+
+ unsigned int bpc;
+
+ /**
+ * @width: width (in millimeters) of the panel's active display area
+ * @height: height (in millimeters) of the panel's active display area
+ */
+ struct {
+ unsigned int width;
+ unsigned int height;
+ } size;
+
+ u32 bus_format;
+ u32 bus_flags;
+};
+
+struct seiko_panel {
+ struct drm_panel base;
+ bool prepared;
+ bool enabled;
+ const struct seiko_panel_desc *desc;
+ struct backlight_device *backlight;
+ struct regulator *dvdd;
+ struct regulator *avdd;
+};
+
+static inline struct seiko_panel *to_seiko_panel(struct drm_panel *panel)
+{
+ return container_of(panel, struct seiko_panel, base);
+}
+
+static int seiko_panel_get_fixed_modes(struct seiko_panel *panel)
+{
+ struct drm_connector *connector = panel->base.connector;
+ struct drm_device *drm = panel->base.drm;
+ struct drm_display_mode *mode;
+ unsigned int i, num = 0;
+
+ if (!panel->desc)
+ return 0;
+
+ for (i = 0; i < panel->desc->num_timings; i++) {
+ const struct display_timing *dt = &panel->desc->timings[i];
+ struct videomode vm;
+
+ videomode_from_timing(dt, &vm);
+ mode = drm_mode_create(drm);
+ if (!mode) {
+ dev_err(drm->dev, "failed to add mode %ux%u\n",
+ dt->hactive.typ, dt->vactive.typ);
+ continue;
+ }
+
+ drm_display_mode_from_videomode(&vm, mode);
+
+ mode->type |= DRM_MODE_TYPE_DRIVER;
+
+ if (panel->desc->num_timings == 1)
+ mode->type |= DRM_MODE_TYPE_PREFERRED;
+
+ drm_mode_probed_add(connector, mode);
+ num++;
+ }
+
+ for (i = 0; i < panel->desc->num_modes; i++) {
+ const struct drm_display_mode *m = &panel->desc->modes[i];
+
+ mode = drm_mode_duplicate(drm, m);
+ if (!mode) {
+ dev_err(drm->dev, "failed to add mode %ux%u@%u\n",
+ m->hdisplay, m->vdisplay, m->vrefresh);
+ continue;
+ }
+
+ mode->type |= DRM_MODE_TYPE_DRIVER;
+
+ if (panel->desc->num_modes == 1)
+ mode->type |= DRM_MODE_TYPE_PREFERRED;
+
+ drm_mode_set_name(mode);
+
+ drm_mode_probed_add(connector, mode);
+ num++;
+ }
+
+ 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);
+ connector->display_info.bus_flags = panel->desc->bus_flags;
+
+ return num;
+}
+
+static int seiko_panel_disable(struct drm_panel *panel)
+{
+ struct seiko_panel *p = to_seiko_panel(panel);
+
+ if (!p->enabled)
+ return 0;
+
+ if (p->backlight) {
+ p->backlight->props.power = FB_BLANK_POWERDOWN;
+ p->backlight->props.state |= BL_CORE_FBBLANK;
+ backlight_update_status(p->backlight);
+ }
+
+ p->enabled = false;
+
+ return 0;
+}
+
+static int seiko_panel_unprepare(struct drm_panel *panel)
+{
+ struct seiko_panel *p = to_seiko_panel(panel);
+
+ if (!p->prepared)
+ return 0;
+
+ regulator_disable(p->avdd);
+
+ /* Add a 100ms delay as per the panel datasheet */
+ msleep(100);
+
+ regulator_disable(p->dvdd);
+
+ p->prepared = false;
+
+ return 0;
+}
+
+static int seiko_panel_prepare(struct drm_panel *panel)
+{
+ struct seiko_panel *p = to_seiko_panel(panel);
+ int err;
+
+ if (p->prepared)
+ return 0;
+
+ err = regulator_enable(p->dvdd);
+ if (err < 0) {
+ dev_err(panel->dev, "failed to enable dvdd: %d\n", err);
+ return err;
+ }
+
+ /* Add a 100ms delay as per the panel datasheet */
+ msleep(100);
+
+ err = regulator_enable(p->avdd);
+ if (err < 0) {
+ dev_err(panel->dev, "failed to enable avdd: %d\n", err);
+ goto disable_dvdd;
+ }
+
+ p->prepared = true;
+
+ return 0;
+
+disable_dvdd:
+ regulator_disable(p->dvdd);
+ return err;
+}
+
+static int seiko_panel_enable(struct drm_panel *panel)
+{
+ struct seiko_panel *p = to_seiko_panel(panel);
+
+ if (p->enabled)
+ return 0;
+
+ if (p->backlight) {
+ p->backlight->props.state &= ~BL_CORE_FBBLANK;
+ p->backlight->props.power = FB_BLANK_UNBLANK;
+ backlight_update_status(p->backlight);
+ }
+
+ p->enabled = true;
+
+ return 0;
+}
+
+static int seiko_panel_get_modes(struct drm_panel *panel)
+{
+ struct seiko_panel *p = to_seiko_panel(panel);
+
+ /* add hard-coded panel modes */
+ return seiko_panel_get_fixed_modes(p);
+}
+
+static int seiko_panel_get_timings(struct drm_panel *panel,
+ unsigned int num_timings,
+ struct display_timing *timings)
+{
+ struct seiko_panel *p = to_seiko_panel(panel);
+ unsigned int i;
+
+ if (p->desc->num_timings < num_timings)
+ num_timings = p->desc->num_timings;
+
+ if (timings)
+ for (i = 0; i < num_timings; i++)
+ timings[i] = p->desc->timings[i];
+
+ return p->desc->num_timings;
+}
+
+static const struct drm_panel_funcs seiko_panel_funcs = {
+ .disable = seiko_panel_disable,
+ .unprepare = seiko_panel_unprepare,
+ .prepare = seiko_panel_prepare,
+ .enable = seiko_panel_enable,
+ .get_modes = seiko_panel_get_modes,
+ .get_timings = seiko_panel_get_timings,
+};
+
+static int seiko_panel_probe(struct device *dev,
+ const struct seiko_panel_desc *desc)
+{
+ struct device_node *backlight;
+ struct seiko_panel *panel;
+ int err;
+
+ panel = devm_kzalloc(dev, sizeof(*panel), GFP_KERNEL);
+ if (!panel)
+ return -ENOMEM;
+
+ panel->enabled = false;
+ panel->prepared = false;
+ panel->desc = desc;
+
+ panel->dvdd = devm_regulator_get(dev, "dvdd");
+ if (IS_ERR(panel->dvdd))
+ return PTR_ERR(panel->dvdd);
+
+ panel->avdd = devm_regulator_get(dev, "avdd");
+ if (IS_ERR(panel->avdd))
+ return PTR_ERR(panel->avdd);
+
+ backlight = of_parse_phandle(dev->of_node, "backlight", 0);
+ if (backlight) {
+ panel->backlight = of_find_backlight_by_node(backlight);
+ of_node_put(backlight);
+
+ if (!panel->backlight)
+ return -EPROBE_DEFER;
+ }
+
+ drm_panel_init(&panel->base);
+ panel->base.dev = dev;
+ panel->base.funcs = &seiko_panel_funcs;
+
+ err = drm_panel_add(&panel->base);
+ if (err < 0)
+ return err;
+
+ dev_set_drvdata(dev, panel);
+
+ return 0;
+}
+
+static int seiko_panel_remove(struct platform_device *pdev)
+{
+ struct seiko_panel *panel = dev_get_drvdata(&pdev->dev);
+
+ drm_panel_detach(&panel->base);
+ drm_panel_remove(&panel->base);
+
+ seiko_panel_disable(&panel->base);
+
+ if (panel->backlight)
+ put_device(&panel->backlight->dev);
+
+ return 0;
+}
+
+static void seiko_panel_shutdown(struct platform_device *pdev)
+{
+ struct seiko_panel *panel = dev_get_drvdata(&pdev->dev);
+
+ seiko_panel_disable(&panel->base);
+}
+
+static const struct display_timing seiko_43wvf1g_timing = {
+ .pixelclock = { 33500000, 33500000, 33500000 },
+ .hactive = { 800, 800, 800 },
+ .hfront_porch = { 164, 164, 164 },
+ .hback_porch = { 89, 89, 89 },
+ .hsync_len = { 10, 10, 10 },
+ .vactive = { 480, 480, 480 },
+ .vfront_porch = { 10, 10, 10 },
+ .vback_porch = { 23, 23, 23 },
+ .vsync_len = { 10, 10, 10 },
+ .flags = DISPLAY_FLAGS_DE_LOW,
+};
+
+static const struct seiko_panel_desc seiko_43wvf1g = {
+ .timings = &seiko_43wvf1g_timing,
+ .num_timings = 1,
+ .bpc = 8,
+ .size = {
+ .width = 93,
+ .height = 57,
+ },
+ .bus_format = MEDIA_BUS_FMT_RGB888_1X24,
+ .bus_flags = DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_PIXDATA_NEGEDGE,
+};
+
+static const struct of_device_id platform_of_match[] = {
+ {
+ .compatible = "sii,43wvf1g",
+ .data = &seiko_43wvf1g,
+ }, {
+ /* sentinel */
+ }
+};
+MODULE_DEVICE_TABLE(of, platform_of_match);
+
+static int seiko_panel_platform_probe(struct platform_device *pdev)
+{
+ const struct of_device_id *id;
+
+ id = of_match_node(platform_of_match, pdev->dev.of_node);
+ if (!id)
+ return -ENODEV;
+
+ return seiko_panel_probe(&pdev->dev, id->data);
+}
+
+static struct platform_driver seiko_panel_platform_driver = {
+ .driver = {
+ .name = "seiko_panel",
+ .of_match_table = platform_of_match,
+ },
+ .probe = seiko_panel_platform_probe,
+ .remove = seiko_panel_remove,
+ .shutdown = seiko_panel_shutdown,
+};
+module_platform_driver(seiko_panel_platform_driver);
+
+MODULE_AUTHOR("Marco Franchi <marco.franchi@nxp.com");
+MODULE_DESCRIPTION("Seiko 43WVF1G panel driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c
index c1daed3fe842..2813933b666e 100644
--- a/drivers/gpu/drm/panel/panel-simple.c
+++ b/drivers/gpu/drm/panel/panel-simple.c
@@ -1213,6 +1213,42 @@ static const struct panel_desc innolux_zj070na_01p = {
},
};
+static const struct display_timing jdi_tx26d202vm0bwa_timing = {
+ .pixelclock = { 151820000, 156720000, 159780000 },
+ .hactive = { 1920, 1920, 1920 },
+ .hfront_porch = { 76, 100, 112 },
+ .hback_porch = { 74, 100, 112 },
+ .hsync_len = { 30, 30, 30 },
+ .vactive = { 1200, 1200, 1200},
+ .vfront_porch = { 3, 5, 10 },
+ .vback_porch = { 2, 5, 10 },
+ .vsync_len = { 5, 5, 5 },
+ .flags = DISPLAY_FLAGS_DE_HIGH,
+};
+
+static const struct panel_desc jdi_tx26d202vm0bwa = {
+ .timings = &jdi_tx26d202vm0bwa_timing,
+ .num_timings = 1,
+ .bpc = 8,
+ .size = {
+ .width = 217,
+ .height = 136,
+ },
+ .delay = {
+ /*
+ * The panel spec recommends one second delay
+ * to the below items. However, it's a bit too
+ * long in practice. Based on tests, it turns
+ * out 100 milliseconds is fine.
+ */
+ .prepare = 100,
+ .enable = 100,
+ .unprepare = 100,
+ .disable = 100,
+ },
+ .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG,
+};
+
static const struct display_timing kyo_tcg121xglp_timing = {
.pixelclock = { 52000000, 65000000, 71000000 },
.hactive = { 1024, 1024, 1024 },
@@ -2040,6 +2076,9 @@ static const struct of_device_id platform_of_match[] = {
.compatible = "innolux,zj070na-01p",
.data = &innolux_zj070na_01p,
}, {
+ .compatible = "jdi,tx26d202vm0bwa",
+ .data = &jdi_tx26d202vm0bwa,
+ }, {
.compatible = "kyo,tcg121xglp",
.data = &kyo_tcg121xglp,
}, {
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c
index c31e660e35db..7d39ed63e5be 100644
--- a/drivers/gpu/drm/radeon/r100.c
+++ b/drivers/gpu/drm/radeon/r100.c
@@ -1456,7 +1456,7 @@ int r100_cs_packet_parse_vline(struct radeon_cs_parser *p)
header = radeon_get_ib_value(p, h_idx);
crtc_id = radeon_get_ib_value(p, h_idx + 5);
reg = R100_CP_PACKET0_GET_REG(header);
- crtc = drm_crtc_find(p->rdev->ddev, crtc_id);
+ crtc = drm_crtc_find(p->rdev->ddev, p->filp, crtc_id);
if (!crtc) {
DRM_ERROR("cannot find crtc %d\n", crtc_id);
return -ENOENT;
diff --git a/drivers/gpu/drm/radeon/r600_cs.c b/drivers/gpu/drm/radeon/r600_cs.c
index 97fd58e97043..c96b31950ca7 100644
--- a/drivers/gpu/drm/radeon/r600_cs.c
+++ b/drivers/gpu/drm/radeon/r600_cs.c
@@ -887,7 +887,7 @@ int r600_cs_common_vline_parse(struct radeon_cs_parser *p,
crtc_id = radeon_get_ib_value(p, h_idx + 2 + 7 + 1);
reg = R600_CP_PACKET0_GET_REG(header);
- crtc = drm_crtc_find(p->rdev->ddev, crtc_id);
+ crtc = drm_crtc_find(p->rdev->ddev, p->filp, crtc_id);
if (!crtc) {
DRM_ERROR("cannot find crtc %d\n", crtc_id);
return -ENOENT;
diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c
index 48f752cf7a92..ff59d4b762ef 100644
--- a/drivers/gpu/drm/radeon/radeon_connectors.c
+++ b/drivers/gpu/drm/radeon/radeon_connectors.c
@@ -256,7 +256,7 @@ radeon_connector_update_scratch_regs(struct drm_connector *connector, enum drm_c
if (connector->encoder_ids[i] == 0)
break;
- encoder = drm_encoder_find(connector->dev,
+ encoder = drm_encoder_find(connector->dev, NULL,
connector->encoder_ids[i]);
if (!encoder)
continue;
@@ -283,7 +283,7 @@ static struct drm_encoder *radeon_find_encoder(struct drm_connector *connector,
if (connector->encoder_ids[i] == 0)
break;
- encoder = drm_encoder_find(connector->dev, connector->encoder_ids[i]);
+ encoder = drm_encoder_find(connector->dev, NULL, connector->encoder_ids[i]);
if (!encoder)
continue;
@@ -397,7 +397,7 @@ static struct drm_encoder *radeon_best_single_encoder(struct drm_connector *conn
int enc_id = connector->encoder_ids[0];
/* pick the encoder ids */
if (enc_id)
- return drm_encoder_find(connector->dev, enc_id);
+ return drm_encoder_find(connector->dev, NULL, enc_id);
return NULL;
}
@@ -1379,7 +1379,7 @@ radeon_dvi_detect(struct drm_connector *connector, bool force)
if (connector->encoder_ids[i] == 0)
break;
- encoder = drm_encoder_find(connector->dev,
+ encoder = drm_encoder_find(connector->dev, NULL,
connector->encoder_ids[i]);
if (!encoder)
continue;
@@ -1467,7 +1467,7 @@ static struct drm_encoder *radeon_dvi_encoder(struct drm_connector *connector)
if (connector->encoder_ids[i] == 0)
break;
- encoder = drm_encoder_find(connector->dev, connector->encoder_ids[i]);
+ encoder = drm_encoder_find(connector->dev, NULL, connector->encoder_ids[i]);
if (!encoder)
continue;
@@ -1486,7 +1486,7 @@ static struct drm_encoder *radeon_dvi_encoder(struct drm_connector *connector)
/* then check use digitial */
/* pick the first one */
if (enc_id)
- return drm_encoder_find(connector->dev, enc_id);
+ return drm_encoder_find(connector->dev, NULL, enc_id);
return NULL;
}
@@ -1633,7 +1633,7 @@ u16 radeon_connector_encoder_get_dp_bridge_encoder_id(struct drm_connector *conn
if (connector->encoder_ids[i] == 0)
break;
- encoder = drm_encoder_find(connector->dev, connector->encoder_ids[i]);
+ encoder = drm_encoder_find(connector->dev, NULL, connector->encoder_ids[i]);
if (!encoder)
continue;
@@ -1662,7 +1662,7 @@ static bool radeon_connector_encoder_is_hbr2(struct drm_connector *connector)
if (connector->encoder_ids[i] == 0)
break;
- encoder = drm_encoder_find(connector->dev, connector->encoder_ids[i]);
+ encoder = drm_encoder_find(connector->dev, NULL, connector->encoder_ids[i]);
if (!encoder)
continue;
diff --git a/drivers/gpu/drm/udl/udl_connector.c b/drivers/gpu/drm/udl/udl_connector.c
index 9f9a49748d17..091ca81658eb 100644
--- a/drivers/gpu/drm/udl/udl_connector.c
+++ b/drivers/gpu/drm/udl/udl_connector.c
@@ -105,7 +105,7 @@ static struct drm_encoder*
udl_best_single_encoder(struct drm_connector *connector)
{
int enc_id = connector->encoder_ids[0];
- return drm_encoder_find(connector->dev, enc_id);
+ return drm_encoder_find(connector->dev, NULL, enc_id);
}
static int udl_connector_set_property(struct drm_connector *connector,
diff --git a/drivers/gpu/drm/vivante/Makefile b/drivers/gpu/drm/vivante/Makefile
new file mode 100644
index 000000000000..d87c8e8752a6
--- /dev/null
+++ b/drivers/gpu/drm/vivante/Makefile
@@ -0,0 +1,29 @@
+##############################################################################
+#
+# Copyright (C) 2005 - 2013 by Vivante Corp.
+#
+# 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.
+#
+##############################################################################
+
+
+#
+# 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
+vivante-y := vivante_drv.o
+
+obj-$(CONFIG_DRM_VIVANTE) += vivante.o
diff --git a/drivers/gpu/drm/vivante/vivante_drv.c b/drivers/gpu/drm/vivante/vivante_drv.c
new file mode 100644
index 000000000000..f4d9abb894fe
--- /dev/null
+++ b/drivers/gpu/drm/vivante/vivante_drv.c
@@ -0,0 +1,140 @@
+/****************************************************************************
+*
+* Copyright (C) 2005 - 2013 by Vivante Corp.
+*
+* 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.
+*
+*****************************************************************************/
+
+
+/* vivante_drv.c -- vivante driver -*- linux-c -*-
+ *
+ *
+ * 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
+ * PRECISION INSIGHT 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.
+ *
+ * Authors:
+ * Rickard E. (Rik) Faith <faith@valinux.com>
+ * Daryll Strauss <daryll@valinux.com>
+ * Gareth Hughes <gareth@valinux.com>
+ */
+#include <linux/component.h>
+#include <linux/version.h>
+#include <linux/module.h>
+#include <drm/drmP.h>
+#include <drm/drm_pciids.h>
+#include <drm/drm_legacy.h>
+
+#include "vivante_drv.h"
+
+static char platformdevicename[] = "platform:Vivante GCCore";
+static struct platform_device *pplatformdev;
+
+static const struct file_operations viv_driver_fops = {
+ .owner = THIS_MODULE,
+ .open = drm_open,
+ .release = drm_release,
+ .unlocked_ioctl = drm_ioctl,
+ .mmap = drm_legacy_mmap,
+ .poll = drm_poll,
+ .llseek = noop_llseek,
+};
+
+static struct drm_driver driver = {
+ .fops = &viv_driver_fops,
+ .name = DRIVER_NAME,
+ .desc = DRIVER_DESC,
+ .date = DRIVER_DATE,
+ .major = DRIVER_MAJOR,
+ .minor = DRIVER_MINOR,
+ .patchlevel = DRIVER_PATCHLEVEL,
+ .driver_features = DRIVER_LEGACY,
+};
+
+static int drm_get_platform_dev(struct platform_device *platdev,
+ struct drm_driver *driver)
+{
+ struct drm_device *dev;
+ int ret;
+
+ DRM_DEBUG("\n");
+
+ dev = drm_dev_alloc(driver, &platdev->dev);
+ if (IS_ERR(dev))
+ return PTR_ERR(dev);
+
+ dev_set_drvdata(&platdev->dev, dev);
+
+ ret = drm_dev_register(dev, 0);
+ if (ret)
+ goto err_free;
+
+ DRM_INFO("Initialized %s %d.%d.%d %s on minor %d\n",
+ driver->name, driver->major, driver->minor, driver->patchlevel,
+ driver->date, dev->primary->index);
+
+ return 0;
+
+err_free:
+ drm_dev_unref(dev);
+ return ret;
+}
+
+static int __init vivante_init(void)
+{
+ int retcode;
+
+ pplatformdev = platform_device_register_simple(platformdevicename,
+ -1, NULL, 0);
+ if (pplatformdev == NULL)
+ printk(KERN_ERR"Platform device is null\n");
+
+ retcode = drm_get_platform_dev(pplatformdev, &driver);
+
+ return retcode;
+}
+module_init(vivante_init);
+
+static void __exit vivante_exit(void)
+{
+ if (pplatformdev) {
+ /* The drvdata is set in drm_get_platform_dev() */
+ drm_put_dev(platform_get_drvdata(pplatformdev));
+ platform_device_unregister(pplatformdev);
+ pplatformdev = NULL;
+ }
+}
+module_exit(vivante_exit);
+
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL and additional rights");
+MODULE_ALIAS("platform:Vivante GCCore");
diff --git a/drivers/gpu/drm/vivante/vivante_drv.h b/drivers/gpu/drm/vivante/vivante_drv.h
new file mode 100644
index 000000000000..03f5884ce19b
--- /dev/null
+++ b/drivers/gpu/drm/vivante/vivante_drv.h
@@ -0,0 +1,66 @@
+/****************************************************************************
+*
+* Copyright (C) 2005 - 2013 by Vivante Corp.
+*
+* 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.
+*
+*****************************************************************************/
+
+
+/* vivante_drv.h -- Vivante DRM template customization -*- linux-c -*-
+ * Created: Wed Feb 14 12:32:32 2012 by John Zhao
+ */
+/*
+ *
+ * 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
+ * VA LINUX SYSTEMS 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.
+ *
+ * Authors:
+ * Gareth Hughes <gareth@valinux.com>
+ */
+
+#ifndef __VIVANTE_DRV_H__
+#define __VIVANTE_DRV_H__
+
+/* General customization:
+ */
+
+#define DRIVER_AUTHOR "Vivante Inc."
+
+#define DRIVER_NAME "vivante"
+#define DRIVER_DESC "Vivante GCCore"
+#define DRIVER_DATE "20120216"
+
+#define DRIVER_MAJOR 1
+#define DRIVER_MINOR 0
+#define DRIVER_PATCHLEVEL 0
+
+#endif
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c
index 5ec24fd801cd..01be355525e4 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c
@@ -286,7 +286,7 @@ int vmw_present_ioctl(struct drm_device *dev, void *data,
drm_modeset_lock_all(dev);
- fb = drm_framebuffer_lookup(dev, arg->fb_id);
+ fb = drm_framebuffer_lookup(dev, file_priv, arg->fb_id);
if (!fb) {
DRM_ERROR("Invalid framebuffer id.\n");
ret = -ENOENT;
@@ -369,7 +369,7 @@ int vmw_present_readback_ioctl(struct drm_device *dev, void *data,
drm_modeset_lock_all(dev);
- fb = drm_framebuffer_lookup(dev, arg->fb_id);
+ fb = drm_framebuffer_lookup(dev, file_priv, arg->fb_id);
if (!fb) {
DRM_ERROR("Invalid framebuffer id.\n");
ret = -ENOENT;
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
index 11f1c30ead54..2cb39189139f 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
@@ -1719,7 +1719,7 @@ int vmw_kms_cursor_bypass_ioctl(struct drm_device *dev, void *data,
return 0;
}
- crtc = drm_crtc_find(dev, arg->crtc_id);
+ crtc = drm_crtc_find(dev, file_priv, arg->crtc_id);
if (!crtc) {
ret = -ENOENT;
goto out;
diff --git a/drivers/gpu/imx/Kconfig b/drivers/gpu/imx/Kconfig
new file mode 100644
index 000000000000..f886fab4310c
--- /dev/null
+++ b/drivers/gpu/imx/Kconfig
@@ -0,0 +1,20 @@
+config IMX8_PC
+ tristate
+ default y if IMX_DPU_CORE=y
+ default m if IMX_DPU_CORE=m
+
+config IMX8_PRG
+ tristate
+ default y if IMX_DPU_CORE=y
+ default m if IMX_DPU_CORE=m
+
+config IMX8_DPRC
+ tristate
+ default y if IMX_DPU_CORE=y
+ default m if IMX_DPU_CORE=m
+
+source drivers/gpu/imx/ipu-v3/Kconfig
+source drivers/gpu/imx/dpu/Kconfig
+source drivers/gpu/imx/dpu-blit/Kconfig
+source drivers/gpu/imx/dcss/Kconfig
+source drivers/gpu/imx/lcdif/Kconfig
diff --git a/drivers/gpu/imx/Makefile b/drivers/gpu/imx/Makefile
new file mode 100644
index 000000000000..51542651182f
--- /dev/null
+++ b/drivers/gpu/imx/Makefile
@@ -0,0 +1,9 @@
+obj-$(CONFIG_IMX8_PC) += imx8_pc.o
+obj-$(CONFIG_IMX8_PRG) += imx8_prg.o
+obj-$(CONFIG_IMX8_DPRC) += imx8_dprc.o
+
+obj-$(CONFIG_IMX_IPUV3_CORE) += ipu-v3/
+obj-$(CONFIG_IMX_DPU_CORE) += dpu/
+obj-$(CONFIG_IMX_DPU_BLIT) += dpu-blit/
+obj-$(CONFIG_IMX_DCSS_CORE) += dcss/
+obj-$(CONFIG_IMX_LCDIF_CORE) += lcdif/
diff --git a/drivers/gpu/imx/dcss/Kconfig b/drivers/gpu/imx/dcss/Kconfig
new file mode 100644
index 000000000000..57b0b6765d43
--- /dev/null
+++ b/drivers/gpu/imx/dcss/Kconfig
@@ -0,0 +1,9 @@
+config IMX_DCSS_CORE
+ tristate "i.MX DCSS core support"
+ depends on ARCH_FSL_IMX8MQ
+ select RESET_CONTROLLER
+ select IMX_IRQSTEER
+ help
+ Choose this if you have a Freescale i.MX8MQ system and want to use the
+ Display Controller Sub System. This option only enables DCSS base
+ support.
diff --git a/drivers/gpu/imx/dcss/Makefile b/drivers/gpu/imx/dcss/Makefile
new file mode 100644
index 000000000000..70d05d35c5d5
--- /dev/null
+++ b/drivers/gpu/imx/dcss/Makefile
@@ -0,0 +1,6 @@
+obj-$(CONFIG_IMX_DCSS_CORE) += imx-dcss-core.o
+
+imx-dcss-core-objs := dcss-common.o dcss-blkctl.o dcss-ctxld.o \
+ dcss-dpr.o dcss-dtg.o dcss-ss.o dcss-hdr10.o \
+ dcss-scaler.o dcss-dtrc.o dcss-dec400d.o dcss-wrscl.o \
+ dcss-rdsrc.o
diff --git a/drivers/gpu/imx/dcss/dcss-blkctl.c b/drivers/gpu/imx/dcss/dcss-blkctl.c
new file mode 100644
index 000000000000..2f13b33dba35
--- /dev/null
+++ b/drivers/gpu/imx/dcss/dcss-blkctl.c
@@ -0,0 +1,143 @@
+/*
+ * Copyright 2017 NXP
+ *
+ * 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/device.h>
+#include <linux/io.h>
+#include <linux/bitops.h>
+#include <linux/of.h>
+#include <linux/delay.h>
+#include <soc/imx8/soc.h>
+
+#include "dcss-prv.h"
+#include <video/imx-dcss.h>
+
+#define DCSS_BLKCTL_RESET_CTRL 0x00
+#define B_CLK_RESETN BIT(0)
+#define APB_CLK_RESETN BIT(1)
+#define P_CLK_RESETN BIT(2)
+#define RTR_CLK_RESETN BIT(3)
+#define HDMI_RESETN BIT(4)
+#define DCSS_BLKCTL_CONTROL0 0x10
+#define HDMI_MIPI_CLK_SEL BIT(0)
+#define DISPMIX_REFCLK_SEL_POS 4
+#define DISPMIX_REFCLK_SEL_MASK GENMASK(5, 4)
+#define DISPMIX_PIXCLK_SEL BIT(8)
+#define HDMI_SRC_SECURE_EN BIT(16)
+
+#define B0_SILICON_ID 0x20
+
+static struct dcss_debug_reg blkctl_debug_reg[] = {
+ DCSS_DBG_REG(DCSS_BLKCTL_RESET_CTRL),
+ DCSS_DBG_REG(DCSS_BLKCTL_CONTROL0),
+};
+
+struct dcss_blkctl_priv {
+ struct dcss_soc *dcss;
+ void __iomem *base_reg;
+
+ bool hdmi_output;
+ u32 clk_setting;
+};
+
+#ifdef CONFIG_DEBUG_FS
+void dcss_blkctl_dump_regs(struct seq_file *s, void *data)
+{
+ struct dcss_soc *dcss = data;
+ int j;
+
+ seq_puts(s, ">> Dumping BLKCTL:\n");
+ for (j = 0; j < ARRAY_SIZE(blkctl_debug_reg); j++)
+ seq_printf(s, "%-35s(0x%04x) -> 0x%08x\n",
+ blkctl_debug_reg[j].name,
+ blkctl_debug_reg[j].ofs,
+ dcss_readl(dcss->blkctl_priv->base_reg +
+ blkctl_debug_reg[j].ofs));
+}
+#endif
+
+static void dcss_blkctl_clk_reset(struct dcss_blkctl_priv *blkctl,
+ u32 assert, u32 deassert)
+{
+ if (assert)
+ dcss_clr(assert, blkctl->base_reg + DCSS_BLKCTL_RESET_CTRL);
+
+ if (deassert)
+ dcss_set(deassert, blkctl->base_reg + DCSS_BLKCTL_RESET_CTRL);
+}
+
+void dcss_blkctl_cfg(struct dcss_soc *dcss)
+{
+ struct dcss_blkctl_priv *blkctl = dcss->blkctl_priv;
+
+ if (blkctl->hdmi_output)
+ dcss_writel((blkctl->clk_setting ^ HDMI_MIPI_CLK_SEL),
+ blkctl->base_reg + DCSS_BLKCTL_CONTROL0);
+ else
+ dcss_writel((blkctl->clk_setting ^ HDMI_MIPI_CLK_SEL) |
+ DISPMIX_PIXCLK_SEL,
+ blkctl->base_reg + DCSS_BLKCTL_CONTROL0);
+
+ /* deassert clock domains resets */
+ dcss_blkctl_clk_reset(blkctl, 0, 0xffffff);
+}
+
+int dcss_blkctl_init(struct dcss_soc *dcss, unsigned long blkctl_base)
+{
+ struct device_node *node = dcss->dev->of_node;
+ int len;
+ const char *disp_dev;
+ struct dcss_blkctl_priv *blkctl;
+
+ blkctl = devm_kzalloc(dcss->dev, sizeof(*blkctl), GFP_KERNEL);
+ if (!blkctl)
+ return -ENOMEM;
+
+ blkctl->base_reg = devm_ioremap(dcss->dev, blkctl_base, SZ_4K);
+ if (!blkctl->base_reg) {
+ dev_err(dcss->dev, "unable to remap BLK CTRL base\n");
+ return -ENOMEM;
+ }
+
+ blkctl->dcss = dcss;
+ dcss->blkctl_priv = blkctl;
+
+ disp_dev = of_get_property(node, "disp-dev", &len);
+ if (!disp_dev || !strncmp(disp_dev, "hdmi_disp", 9))
+ blkctl->hdmi_output = true;
+
+ if (imx8_get_soc_revision() >= B0_SILICON_ID)
+ blkctl->clk_setting = HDMI_MIPI_CLK_SEL;
+
+ dcss_blkctl_cfg(dcss);
+
+ return 0;
+}
+
+void dcss_blkctl_exit(struct dcss_soc *dcss)
+{
+ /* assert clock domains resets */
+ dcss_blkctl_clk_reset(dcss->blkctl_priv,
+ B_CLK_RESETN | APB_CLK_RESETN | P_CLK_RESETN |
+ HDMI_RESETN | RTR_CLK_RESETN, 0);
+}
+
+/* disabled only by cold reset/reboot */
+void dcss_blkctl_hdmi_secure_src_en(struct dcss_soc *dcss)
+{
+ struct dcss_blkctl_priv *blkctl = dcss->blkctl_priv;
+
+ dcss_set(HDMI_SRC_SECURE_EN, blkctl->base_reg + DCSS_BLKCTL_CONTROL0);
+}
+EXPORT_SYMBOL(dcss_blkctl_hdmi_secure_src_en);
+
diff --git a/drivers/gpu/imx/dcss/dcss-common.c b/drivers/gpu/imx/dcss/dcss-common.c
new file mode 100644
index 000000000000..cb15533e73bc
--- /dev/null
+++ b/drivers/gpu/imx/dcss/dcss-common.c
@@ -0,0 +1,728 @@
+/*
+ * Copyright (C) 2017-2018 NXP
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/of_device.h>
+#include <linux/of_graph.h>
+#include <linux/clk.h>
+#include <linux/pm_runtime.h>
+#include <linux/busfreq-imx.h>
+#include <linux/pm_qos.h>
+#include <video/imx-dcss.h>
+
+#include <drm/drm_fourcc.h>
+
+#include <video/imx-dcss.h>
+#include "dcss-prv.h"
+
+struct dcss_devtype {
+ const char *name;
+ u32 blkctl_ofs;
+ u32 ctxld_ofs;
+ u32 rdsrc_ofs;
+ u32 wrscl_ofs;
+ u32 dtg_ofs;
+ u32 scaler_ofs;
+ u32 ss_ofs;
+ u32 dpr_ofs;
+ u32 dtrc_ofs;
+ u32 dec400d_ofs;
+ u32 hdr10_ofs;
+ u32 pll_base;
+};
+
+static struct dcss_devtype dcss_type_imx8m = {
+ .name = "DCSS_imx8m",
+ .blkctl_ofs = 0x2F000,
+ .ctxld_ofs = 0x23000,
+ .rdsrc_ofs = 0x22000,
+ .wrscl_ofs = 0x21000,
+ .dtg_ofs = 0x20000,
+ .scaler_ofs = 0x1C000,
+ .ss_ofs = 0x1B000,
+ .dpr_ofs = 0x18000,
+ .dtrc_ofs = 0x16000,
+ .dec400d_ofs = 0x15000,
+ .hdr10_ofs = 0x00000,
+ .pll_base = 0x30360000,
+};
+
+enum dcss_color_space dcss_drm_fourcc_to_colorspace(u32 drm_fourcc)
+{
+ switch (drm_fourcc) {
+ case DRM_FORMAT_ARGB1555:
+ case DRM_FORMAT_ABGR1555:
+ case DRM_FORMAT_RGBA5551:
+ case DRM_FORMAT_BGRA5551:
+ case DRM_FORMAT_RGB565:
+ case DRM_FORMAT_BGR565:
+ case DRM_FORMAT_RGB888:
+ case DRM_FORMAT_BGR888:
+ case DRM_FORMAT_ARGB4444:
+ case DRM_FORMAT_XRGB8888:
+ case DRM_FORMAT_XBGR8888:
+ case DRM_FORMAT_RGBX8888:
+ case DRM_FORMAT_BGRX8888:
+ case DRM_FORMAT_ARGB8888:
+ case DRM_FORMAT_ABGR8888:
+ case DRM_FORMAT_RGBA8888:
+ case DRM_FORMAT_BGRA8888:
+ case DRM_FORMAT_XRGB2101010:
+ case DRM_FORMAT_XBGR2101010:
+ case DRM_FORMAT_RGBX1010102:
+ case DRM_FORMAT_BGRX1010102:
+ case DRM_FORMAT_ARGB2101010:
+ case DRM_FORMAT_ABGR2101010:
+ case DRM_FORMAT_RGBA1010102:
+ case DRM_FORMAT_BGRA1010102:
+ return DCSS_COLORSPACE_RGB;
+ case DRM_FORMAT_YUYV:
+ case DRM_FORMAT_UYVY:
+ case DRM_FORMAT_YVYU:
+ case DRM_FORMAT_VYUY:
+ case DRM_FORMAT_YUV420:
+ case DRM_FORMAT_YVU420:
+ case DRM_FORMAT_YUV422:
+ case DRM_FORMAT_YVU422:
+ case DRM_FORMAT_NV12:
+ case DRM_FORMAT_NV21:
+ case DRM_FORMAT_NV16:
+ case DRM_FORMAT_NV61:
+ case DRM_FORMAT_P010:
+ return DCSS_COLORSPACE_YUV;
+ default:
+ return DCSS_COLORSPACE_UNKNOWN;
+ }
+}
+EXPORT_SYMBOL_GPL(dcss_drm_fourcc_to_colorspace);
+
+int dcss_vblank_irq_get(struct dcss_soc *dcss)
+{
+ struct platform_device *pdev = to_platform_device(dcss->dev);
+
+ return platform_get_irq_byname(pdev, "dtg_prg1");
+}
+EXPORT_SYMBOL(dcss_vblank_irq_get);
+
+void dcss_vblank_irq_enable(struct dcss_soc *dcss, bool en)
+{
+ dcss_dtg_vblank_irq_enable(dcss, en);
+}
+EXPORT_SYMBOL(dcss_vblank_irq_enable);
+
+void dcss_vblank_irq_clear(struct dcss_soc *dcss)
+{
+ dcss_dtg_vblank_irq_clear(dcss);
+}
+EXPORT_SYMBOL(dcss_vblank_irq_clear);
+
+static int dcss_submodules_init(struct dcss_soc *dcss)
+{
+ int ret;
+ u32 dcss_base = dcss->start_addr;
+
+ ret = dcss_blkctl_init(dcss, dcss_base + dcss->devtype->blkctl_ofs);
+ if (ret)
+ goto blkctl_err;
+
+ ret = dcss_ctxld_init(dcss, dcss_base + dcss->devtype->ctxld_ofs);
+ if (ret)
+ goto ctxld_err;
+
+ ret = dcss_dtrc_init(dcss, dcss_base + dcss->devtype->dtrc_ofs);
+ if (ret)
+ goto dtrc_err;
+
+ ret = dcss_dec400d_init(dcss, dcss_base + dcss->devtype->dec400d_ofs);
+ if (ret)
+ goto dec400d_err;
+
+ ret = dcss_dtg_init(dcss, dcss_base + dcss->devtype->dtg_ofs);
+ if (ret)
+ goto dtg_err;
+
+ ret = dcss_ss_init(dcss, dcss_base + dcss->devtype->ss_ofs);
+ if (ret)
+ goto ss_err;
+
+ ret = dcss_dpr_init(dcss, dcss_base + dcss->devtype->dpr_ofs);
+ if (ret)
+ goto dpr_err;
+
+ ret = dcss_scaler_init(dcss, dcss_base + dcss->devtype->scaler_ofs);
+ if (ret)
+ goto scaler_err;
+
+ ret = dcss_hdr10_init(dcss, dcss_base + dcss->devtype->hdr10_ofs);
+ if (ret)
+ goto hdr10_err;
+
+ ret = dcss_wrscl_init(dcss, dcss_base + dcss->devtype->wrscl_ofs);
+ if (ret)
+ goto wrscl_err;
+
+ ret = dcss_rdsrc_init(dcss, dcss_base + dcss->devtype->rdsrc_ofs);
+ if (ret)
+ goto rdsrc_err;
+
+ return 0;
+
+rdsrc_err:
+ dcss_rdsrc_exit(dcss);
+
+wrscl_err:
+ dcss_wrscl_exit(dcss);
+
+hdr10_err:
+ dcss_hdr10_exit(dcss);
+
+scaler_err:
+ dcss_scaler_exit(dcss);
+
+dpr_err:
+ dcss_dpr_exit(dcss);
+
+ss_err:
+ dcss_ss_exit(dcss);
+
+dtg_err:
+ dcss_dtg_exit(dcss);
+
+dec400d_err:
+ dcss_dec400d_exit(dcss);
+
+dtrc_err:
+ dcss_dtrc_exit(dcss);
+
+ctxld_err:
+ dcss_ctxld_exit(dcss);
+
+blkctl_err:
+ dcss_blkctl_exit(dcss);
+
+ return ret;
+}
+
+struct dcss_platform_reg {
+ struct dcss_client_platformdata pdata;
+ const char *name;
+};
+
+static struct dcss_platform_reg client_reg = {
+ .pdata = { },
+ .name = "imx-dcss-crtc",
+};
+
+static int dcss_add_client_devices(struct dcss_soc *dcss)
+{
+ struct device *dev = dcss->dev;
+ struct platform_device *pdev;
+ struct device_node *of_node;
+ int ret;
+
+ of_node = of_graph_get_port_by_id(dev->of_node, 0);
+ if (!of_node) {
+ dev_err(dev, "no port@0 node in %s\n", dev->of_node->full_name);
+ return -ENODEV;
+ }
+
+ pdev = platform_device_alloc(client_reg.name, 0);
+ if (!pdev) {
+ dev_err(dev, "cannot allocate platform device\n");
+ return -ENOMEM;
+ }
+
+ pdev->dev.parent = dev;
+
+ client_reg.pdata.of_node = of_node;
+ ret = platform_device_add_data(pdev, &client_reg.pdata,
+ sizeof(client_reg.pdata));
+ if (!ret)
+ ret = platform_device_add(pdev);
+ if (ret) {
+ platform_device_put(pdev);
+ goto err_register;
+ }
+
+ pdev->dev.of_node = of_node;
+
+ return 0;
+
+err_register:
+ platform_device_unregister(pdev);
+ return ret;
+}
+
+static int dcss_clks_init(struct dcss_soc *dcss)
+{
+ int ret, i, j;
+ struct {
+ const char *id;
+ struct clk **clk;
+ bool optional;
+ } clks[] = {
+ {"apb", &dcss->apb_clk, false},
+ {"axi", &dcss->axi_clk, false},
+ {"pix", &dcss->pix_clk, false},
+ {"rtrm", &dcss->rtrm_clk, false},
+ {"dtrc", &dcss->dtrc_clk, false},
+ {"pll", &dcss->pll_clk, true},
+ {"pll_src1", &dcss->src_clk[0], true},
+ {"pll_src2", &dcss->src_clk[1], true},
+ {"pll_src3", &dcss->src_clk[2], true},
+ };
+
+ for (i = 0; i < ARRAY_SIZE(clks); i++) {
+ *clks[i].clk = devm_clk_get(dcss->dev, clks[i].id);
+ if (IS_ERR(*clks[i].clk) && !clks[i].optional) {
+ dev_err(dcss->dev, "failed to get %s clock\n",
+ clks[i].id);
+ ret = PTR_ERR(*clks[i].clk);
+ goto err;
+ }
+
+ if (!clks[i].optional)
+ clk_prepare_enable(*clks[i].clk);
+ }
+
+ dcss->clks_on = true;
+
+ return 0;
+
+err:
+ for (j = 0; j < i; j++)
+ clk_disable_unprepare(*clks[j].clk);
+
+ return ret;
+}
+
+static void dcss_clocks_enable(struct dcss_soc *dcss, bool en)
+{
+ if (en && !dcss->clks_on) {
+ clk_prepare_enable(dcss->axi_clk);
+ clk_prepare_enable(dcss->apb_clk);
+ clk_prepare_enable(dcss->rtrm_clk);
+ clk_prepare_enable(dcss->dtrc_clk);
+ clk_prepare_enable(dcss->pix_clk);
+ }
+
+ if (!en && dcss->clks_on) {
+ clk_disable_unprepare(dcss->pix_clk);
+ clk_disable_unprepare(dcss->dtrc_clk);
+ clk_disable_unprepare(dcss->rtrm_clk);
+ clk_disable_unprepare(dcss->apb_clk);
+ clk_disable_unprepare(dcss->axi_clk);
+ }
+
+ dcss->clks_on = en;
+}
+
+#ifdef CONFIG_DEBUG_FS
+#include <linux/debugfs.h>
+#include <linux/slab.h>
+#include <linux/sched/clock.h>
+
+static unsigned int dcss_tracing;
+EXPORT_SYMBOL(dcss_tracing);
+
+module_param_named(tracing, dcss_tracing, int, 0600);
+
+struct dcss_trace {
+ u64 seq;
+ u64 time_ns;
+ u64 tag;
+ struct list_head node;
+};
+
+static LIST_HEAD(dcss_trace_list);
+static spinlock_t lock;
+static u64 seq;
+
+void dcss_trace_write(u64 tag)
+{
+ struct dcss_trace *trace;
+ unsigned long flags;
+
+ if (!dcss_tracing)
+ return;
+
+ trace = kzalloc(sizeof(*trace), GFP_ATOMIC);
+ if (!trace)
+ return;
+
+ trace->time_ns = local_clock();
+ trace->tag = tag;
+ trace->seq = seq;
+
+ spin_lock_irqsave(&lock, flags);
+ list_add_tail(&trace->node, &dcss_trace_list);
+ seq++;
+ spin_unlock_irqrestore(&lock, flags);
+}
+EXPORT_SYMBOL(dcss_trace_write);
+
+static int dcss_trace_dump_show(struct seq_file *s, void *data)
+{
+ struct dcss_trace *trace = data;
+
+ if (trace)
+ seq_printf(s, "%lld %lld %lld\n",
+ trace->seq, trace->time_ns, trace->tag);
+
+ return 0;
+}
+
+static void *dcss_trace_dump_start(struct seq_file *s, loff_t *pos)
+{
+ unsigned long flags;
+ struct dcss_trace *trace = NULL;
+
+ spin_lock_irqsave(&lock, flags);
+ if (!list_empty(&dcss_trace_list)) {
+ trace = list_first_entry(&dcss_trace_list,
+ struct dcss_trace, node);
+ goto exit;
+ }
+
+exit:
+ spin_unlock_irqrestore(&lock, flags);
+ return trace;
+}
+
+static void *dcss_trace_dump_next(struct seq_file *s, void *v, loff_t *pos)
+{
+ unsigned long flags;
+ struct dcss_trace *next_trace = NULL;
+ struct dcss_trace *trace = v;
+
+ ++*pos;
+ spin_lock_irqsave(&lock, flags);
+ if (!list_is_last(&trace->node, &dcss_trace_list)) {
+ next_trace = list_entry(trace->node.next,
+ struct dcss_trace, node);
+ goto exit;
+ }
+
+exit:
+ spin_unlock_irqrestore(&lock, flags);
+ return next_trace;
+}
+
+static void dcss_trace_dump_stop(struct seq_file *s, void *v)
+{
+ unsigned long flags;
+ struct dcss_trace *trace, *tmp;
+ struct dcss_trace *last_trace = v;
+
+ spin_lock_irqsave(&lock, flags);
+ if (!list_empty(&dcss_trace_list)) {
+ list_for_each_entry_safe(trace, tmp, &dcss_trace_list, node) {
+ if (last_trace && trace->seq >= last_trace->seq)
+ break;
+
+ list_del(&trace->node);
+ kfree(trace);
+ }
+ }
+ spin_unlock_irqrestore(&lock, flags);
+}
+
+static const struct seq_operations dcss_trace_seq_ops = {
+ .start = dcss_trace_dump_start,
+ .next = dcss_trace_dump_next,
+ .stop = dcss_trace_dump_stop,
+ .show = dcss_trace_dump_show,
+};
+
+static int dcss_trace_dump_open(struct inode *inode, struct file *file)
+{
+ return seq_open(file, &dcss_trace_seq_ops);
+}
+
+static int dcss_dump_regs_show(struct seq_file *s, void *data)
+{
+ struct dcss_soc *dcss = s->private;
+
+ pm_runtime_get_sync(dcss->dev);
+
+ dcss_blkctl_dump_regs(s, s->private);
+ dcss_dtrc_dump_regs(s, s->private);
+ dcss_dpr_dump_regs(s, s->private);
+ dcss_scaler_dump_regs(s, s->private);
+ dcss_wrscl_dump_regs(s, s->private);
+ dcss_rdsrc_dump_regs(s, s->private);
+ dcss_dtg_dump_regs(s, s->private);
+ dcss_ss_dump_regs(s, s->private);
+ dcss_hdr10_dump_regs(s, s->private);
+ dcss_ctxld_dump_regs(s, s->private);
+
+ pm_runtime_put_sync(dcss->dev);
+
+ return 0;
+}
+
+static int dcss_dump_ctx_show(struct seq_file *s, void *data)
+{
+ dcss_ctxld_dump(s, s->private);
+
+ return 0;
+}
+
+static int dcss_dump_regs_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, dcss_dump_regs_show, inode->i_private);
+}
+
+static int dcss_dump_ctx_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, dcss_dump_ctx_show, inode->i_private);
+}
+
+static const struct file_operations dcss_dump_regs_fops = {
+ .open = dcss_dump_regs_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
+static const struct file_operations dcss_dump_ctx_fops = {
+ .open = dcss_dump_ctx_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
+static const struct file_operations dcss_dump_trace_fops = {
+ .open = dcss_trace_dump_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = seq_release,
+};
+
+static void dcss_debugfs_init(struct dcss_soc *dcss)
+{
+ struct dentry *d, *root;
+
+ root = debugfs_create_dir("imx-dcss", NULL);
+ if (IS_ERR(root) || !root)
+ goto err;
+
+ d = debugfs_create_file("dump_registers", 0444, root, dcss,
+ &dcss_dump_regs_fops);
+ if (!d)
+ goto err;
+
+ d = debugfs_create_file("dump_context", 0444, root, dcss,
+ &dcss_dump_ctx_fops);
+ if (!d)
+ goto err;
+
+ d = debugfs_create_file("dump_trace_log", 0444, root, dcss,
+ &dcss_dump_trace_fops);
+ if (!d)
+ goto err;
+
+ return;
+
+err:
+ dev_err(dcss->dev, "Unable to create debugfs entries\n");
+}
+#else
+static void dcss_debugfs_init(struct dcss_soc *dcss)
+{
+}
+
+void dcss_trace_write(u64 tag)
+{
+}
+EXPORT_SYMBOL(dcss_trace_write);
+#endif
+
+static void dcss_bus_freq(struct dcss_soc *dcss, bool en)
+{
+ if (en && !dcss->bus_freq_req)
+ request_bus_freq(BUS_FREQ_HIGH);
+
+ if (!en && dcss->bus_freq_req)
+ release_bus_freq(BUS_FREQ_HIGH);
+
+ dcss->bus_freq_req = en;
+}
+
+static int dcss_probe(struct platform_device *pdev)
+{
+ int ret;
+ struct resource *res;
+ struct dcss_soc *dcss;
+ const struct dcss_devtype *devtype;
+
+ devtype = of_device_get_match_data(&pdev->dev);
+ if (!devtype) {
+ dev_err(&pdev->dev, "no device match found\n");
+ return -ENODEV;
+ }
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ dev_err(&pdev->dev, "cannot get memory resource\n");
+ return -EINVAL;
+ }
+
+ dcss = devm_kzalloc(&pdev->dev, sizeof(struct dcss_soc), GFP_KERNEL);
+ if (!dcss)
+ return -ENOMEM;
+
+ dcss->dev = &pdev->dev;
+ dcss->devtype = devtype;
+
+ platform_set_drvdata(pdev, dcss);
+
+ ret = dcss_clks_init(dcss);
+ if (ret) {
+ dev_err(&pdev->dev, "clocks initialization failed\n");
+ return ret;
+ }
+
+ dcss->start_addr = res->start;
+
+ ret = dcss_submodules_init(dcss);
+ if (ret) {
+ dev_err(&pdev->dev, "submodules initialization failed\n");
+ return ret;
+ }
+
+ dcss_debugfs_init(dcss);
+
+ pm_runtime_enable(&pdev->dev);
+
+ dcss_bus_freq(dcss, true);
+
+ return dcss_add_client_devices(dcss);
+}
+
+static int dcss_remove(struct platform_device *pdev)
+{
+ struct dcss_soc *dcss = platform_get_drvdata(pdev);
+
+ dcss_bus_freq(dcss, false);
+
+ pm_runtime_disable(&pdev->dev);
+
+ return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int dcss_suspend(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct dcss_soc *dcss = platform_get_drvdata(pdev);
+ int ret;
+
+ if (pm_runtime_suspended(dev))
+ return 0;
+
+ ret = dcss_ctxld_suspend(dcss);
+ if (ret)
+ return ret;
+
+ dcss_clocks_enable(dcss, false);
+
+ dcss_bus_freq(dcss, false);
+
+ return 0;
+}
+
+static int dcss_resume(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct dcss_soc *dcss = platform_get_drvdata(pdev);
+
+ if (pm_runtime_suspended(dev))
+ return 0;
+
+ dcss_bus_freq(dcss, true);
+
+ dcss_clocks_enable(dcss, true);
+
+ dcss_blkctl_cfg(dcss);
+
+ dcss_ctxld_resume(dcss);
+
+ return 0;
+}
+#endif
+
+#ifdef CONFIG_PM
+static int dcss_runtime_suspend(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct dcss_soc *dcss = platform_get_drvdata(pdev);
+ int ret;
+
+ ret = dcss_ctxld_suspend(dcss);
+ if (ret)
+ return ret;
+
+ dcss_clocks_enable(dcss, false);
+
+ dcss_bus_freq(dcss, false);
+
+ return 0;
+}
+
+static int dcss_runtime_resume(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct dcss_soc *dcss = platform_get_drvdata(pdev);
+
+ dcss_bus_freq(dcss, true);
+
+ dcss_clocks_enable(dcss, true);
+
+ dcss_blkctl_cfg(dcss);
+
+ dcss_ctxld_resume(dcss);
+
+ return 0;
+}
+#endif /* CONFIG_PM */
+
+static const struct dev_pm_ops dcss_pm = {
+ SET_SYSTEM_SLEEP_PM_OPS(dcss_suspend, dcss_resume)
+ SET_RUNTIME_PM_OPS(dcss_runtime_suspend,
+ dcss_runtime_resume, NULL)
+};
+
+static const struct of_device_id dcss_dt_ids[] = {
+ { .compatible = "nxp,imx8mq-dcss", .data = &dcss_type_imx8m, },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, dcss_dt_ids);
+
+static struct platform_driver dcss_driver = {
+ .driver = {
+ .name = "dcss-core",
+ .of_match_table = dcss_dt_ids,
+ .pm = &dcss_pm,
+ },
+ .probe = dcss_probe,
+ .remove = dcss_remove,
+};
+
+module_platform_driver(dcss_driver);
+
+MODULE_DESCRIPTION("i.MX DCSS driver");
+MODULE_AUTHOR("Laurentiu Palcu <laurentiu.palcu@nxp.com>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/imx/dcss/dcss-ctxld.c b/drivers/gpu/imx/dcss/dcss-ctxld.c
new file mode 100644
index 000000000000..377a102ad55f
--- /dev/null
+++ b/drivers/gpu/imx/dcss/dcss-ctxld.c
@@ -0,0 +1,517 @@
+/*
+ * Copyright (C) 2017 NXP
+ *
+ * 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/device.h>
+#include <linux/bitops.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/sizes.h>
+#include <linux/io.h>
+#include <linux/dma-mapping.h>
+#include <linux/delay.h>
+#include <asm/cacheflush.h>
+
+#include "video/imx-dcss.h"
+#include "dcss-prv.h"
+
+#define DCSS_CTXLD_DEVNAME "dcss_ctxld"
+
+#define DCSS_CTXLD_CONTROL_STATUS 0x0
+#define CTXLD_ENABLE BIT(0)
+#define ARB_SEL BIT(1)
+#define RD_ERR_EN BIT(2)
+#define DB_COMP_EN BIT(3)
+#define SB_HP_COMP_EN BIT(4)
+#define SB_LP_COMP_EN BIT(5)
+#define DB_PEND_SB_REC_EN BIT(6)
+#define SB_PEND_DISP_ACTIVE_EN BIT(7)
+#define AHB_ERR_EN BIT(8)
+#define RD_ERR BIT(16)
+#define DB_COMP BIT(17)
+#define SB_HP_COMP BIT(18)
+#define SB_LP_COMP BIT(19)
+#define DB_PEND_SB_REC BIT(20)
+#define SB_PEND_DISP_ACTIVE BIT(21)
+#define AHB_ERR BIT(22)
+#define DCSS_CTXLD_DB_BASE_ADDR 0x10
+#define DCSS_CTXLD_DB_COUNT 0x14
+#define DCSS_CTXLD_SB_BASE_ADDR 0x18
+#define DCSS_CTXLD_SB_COUNT 0x1C
+#define SB_HP_COUNT_POS 0
+#define SB_HP_COUNT_MASK 0xffff
+#define SB_LP_COUNT_POS 16
+#define SB_LP_COUNT_MASK 0xffff0000
+#define DCSS_AHB_ERR_ADDR 0x20
+
+#define CTXLD_IRQ_NAME "ctx_ld" /* irq steer irq name */
+#define CTXLD_IRQ_COMPLETION (DB_COMP | SB_HP_COMP | SB_LP_COMP)
+#define CTXLD_IRQ_ERROR (RD_ERR | DB_PEND_SB_REC | AHB_ERR)
+
+/* The following sizes are in entries, 8 bytes each */
+#define CTXLD_DB_CTX_ENTRIES 1024 /* max 65536 */
+#define CTXLD_SB_LP_CTX_ENTRIES 10240 /* max 65536 */
+#define CTXLD_SB_HP_CTX_ENTRIES 20000 /* max 65536 */
+#define CTXLD_SB_CTX_ENTRIES (CTXLD_SB_LP_CTX_ENTRIES + \
+ CTXLD_SB_HP_CTX_ENTRIES)
+
+#define TRACE_ARM (1LL << 48)
+#define TRACE_IRQ (2LL << 48)
+#define TRACE_KICK (3LL << 48)
+
+static struct dcss_debug_reg ctxld_debug_reg[] = {
+ DCSS_DBG_REG(DCSS_CTXLD_CONTROL_STATUS),
+ DCSS_DBG_REG(DCSS_CTXLD_DB_BASE_ADDR),
+ DCSS_DBG_REG(DCSS_CTXLD_DB_COUNT),
+ DCSS_DBG_REG(DCSS_CTXLD_SB_BASE_ADDR),
+ DCSS_DBG_REG(DCSS_CTXLD_SB_COUNT),
+ DCSS_DBG_REG(DCSS_AHB_ERR_ADDR),
+};
+
+/* Sizes, in entries, of the DB, SB_HP and SB_LP context regions. */
+static u16 dcss_ctxld_ctx_size[3] = {
+ CTXLD_DB_CTX_ENTRIES,
+ CTXLD_SB_HP_CTX_ENTRIES,
+ CTXLD_SB_LP_CTX_ENTRIES
+};
+
+/* this represents an entry in the context loader map */
+struct dcss_ctxld_item {
+ u32 val;
+ u32 ofs;
+};
+
+#define CTX_ITEM_SIZE sizeof(struct dcss_ctxld_item)
+
+struct dcss_ctxld_priv {
+ struct dcss_soc *dcss;
+ void __iomem *ctxld_reg;
+ int irq;
+ bool irq_en;
+
+ struct dcss_ctxld_item *db[2];
+ struct dcss_ctxld_item *sb_hp[2];
+ struct dcss_ctxld_item *sb_lp[2];
+
+ dma_addr_t db_paddr[2];
+ dma_addr_t sb_paddr[2];
+
+ u16 ctx_size[2][3]; /* holds the sizes of DB, SB_HP and SB_LP ctx */
+ u8 current_ctx;
+
+ bool in_use;
+ bool armed;
+
+ spinlock_t lock; /* protects concurent access to private data */
+};
+
+#ifdef CONFIG_DEBUG_FS
+void dcss_ctxld_dump_regs(struct seq_file *s, void *data)
+{
+ struct dcss_soc *dcss = data;
+ int j;
+
+ seq_puts(s, ">> Dumping CTXLD:\n");
+ for (j = 0; j < ARRAY_SIZE(ctxld_debug_reg); j++) {
+ seq_printf(s, "%-35s(0x%04x) -> 0x%08x\n",
+ ctxld_debug_reg[j].name,
+ ctxld_debug_reg[j].ofs,
+ dcss_readl(dcss->ctxld_priv->ctxld_reg +
+ ctxld_debug_reg[j].ofs));
+ }
+}
+#endif
+
+static int __dcss_ctxld_enable(struct dcss_ctxld_priv *ctxld);
+
+static irqreturn_t dcss_ctxld_irq_handler(int irq, void *data)
+{
+ struct dcss_ctxld_priv *priv = data;
+ u32 irq_status;
+
+ irq_status = dcss_readl(priv->ctxld_reg + DCSS_CTXLD_CONTROL_STATUS);
+
+ if (irq_status & CTXLD_IRQ_COMPLETION &&
+ !(irq_status & CTXLD_ENABLE) && priv->in_use) {
+ priv->in_use = false;
+
+ dcss_trace_module(TRACE_CTXLD,
+ TRACE_IRQ | (priv->current_ctx ^ 1));
+
+ if (priv->dcss->dcss_disable_callback) {
+ struct dcss_dtg_priv *dtg = priv->dcss->dtg_priv;
+
+ priv->dcss->dcss_disable_callback(dtg);
+ }
+ } else if (irq_status & CTXLD_IRQ_ERROR) {
+ /*
+ * Except for throwing an error message and clearing the status
+ * register, there's not much we can do here.
+ */
+ dev_err(priv->dcss->dev, "ctxld: error encountered: %08x\n",
+ irq_status);
+ dev_err(priv->dcss->dev, "ctxld: db=%d, sb_hp=%d, sb_lp=%d\n",
+ priv->ctx_size[priv->current_ctx ^ 1][CTX_DB],
+ priv->ctx_size[priv->current_ctx ^ 1][CTX_SB_HP],
+ priv->ctx_size[priv->current_ctx ^ 1][CTX_SB_LP]);
+ }
+
+ dcss_clr(irq_status & (CTXLD_IRQ_ERROR | CTXLD_IRQ_COMPLETION),
+ priv->ctxld_reg + DCSS_CTXLD_CONTROL_STATUS);
+
+ return IRQ_HANDLED;
+}
+
+static int dcss_ctxld_irq_config(struct dcss_ctxld_priv *ctxld)
+{
+ struct dcss_soc *dcss = ctxld->dcss;
+ struct platform_device *pdev = to_platform_device(dcss->dev);
+ int ret;
+
+ ctxld->irq = platform_get_irq_byname(pdev, CTXLD_IRQ_NAME);
+ if (ctxld->irq < 0) {
+ dev_err(dcss->dev, "ctxld: can't get irq number\n");
+ return ctxld->irq;
+ }
+
+ ret = devm_request_irq(dcss->dev, ctxld->irq,
+ dcss_ctxld_irq_handler,
+ IRQF_ONESHOT | IRQF_TRIGGER_RISING,
+ DCSS_CTXLD_DEVNAME, ctxld);
+ if (ret) {
+ dev_err(dcss->dev, "ctxld: irq request failed.\n");
+ return ret;
+ }
+
+ ctxld->irq_en = true;
+
+ return 0;
+}
+
+void dcss_ctxld_hw_cfg(struct dcss_soc *dcss)
+{
+ struct dcss_ctxld_priv *ctxld = dcss->ctxld_priv;
+
+ dcss_writel(RD_ERR_EN | SB_HP_COMP_EN |
+ DB_PEND_SB_REC_EN | AHB_ERR_EN | RD_ERR | AHB_ERR,
+ ctxld->ctxld_reg + DCSS_CTXLD_CONTROL_STATUS);
+}
+
+/**
+ * dcss_ctxld_alloc_ctx - Allocate context memory.
+ *
+ * @ctxld: Pointer to ctxld.
+ *
+ * Returns:
+ * Zeron on success, negative errno on failure.
+ */
+static int dcss_ctxld_alloc_ctx(struct dcss_ctxld_priv *ctxld)
+{
+ struct dcss_soc *dcss = ctxld->dcss;
+ struct dcss_ctxld_item *ctx;
+ int i;
+ dma_addr_t dma_handle;
+
+ for (i = 0; i < 2; i++) {
+ ctx = dmam_alloc_coherent(dcss->dev,
+ CTXLD_DB_CTX_ENTRIES * sizeof(*ctx),
+ &dma_handle, GFP_KERNEL);
+ if (!ctx)
+ return -ENOMEM;
+
+ ctxld->db[i] = ctx;
+ ctxld->db_paddr[i] = dma_handle;
+
+ ctx = dmam_alloc_coherent(dcss->dev,
+ CTXLD_SB_CTX_ENTRIES * sizeof(*ctx),
+ &dma_handle, GFP_KERNEL);
+ if (!ctx)
+ return -ENOMEM;
+
+ ctxld->sb_hp[i] = ctx;
+ ctxld->sb_lp[i] = ctx + CTXLD_SB_HP_CTX_ENTRIES;
+
+ ctxld->sb_paddr[i] = dma_handle;
+ }
+
+ return 0;
+}
+
+int dcss_ctxld_init(struct dcss_soc *dcss, unsigned long ctxld_base)
+{
+ struct dcss_ctxld_priv *priv;
+ int ret;
+
+ priv = devm_kzalloc(dcss->dev, sizeof(struct dcss_ctxld_priv),
+ GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ dcss->ctxld_priv = priv;
+ priv->dcss = dcss;
+
+ spin_lock_init(&priv->lock);
+
+ ret = dcss_ctxld_alloc_ctx(priv);
+ if (ret) {
+ dev_err(dcss->dev, "ctxld: cannot allocate context memory.\n");
+ return ret;
+ }
+
+ priv->ctxld_reg = devm_ioremap(dcss->dev, ctxld_base, SZ_4K);
+ if (!priv->ctxld_reg) {
+ dev_err(dcss->dev, "ctxld: unable to remap ctxld base\n");
+ return -ENOMEM;
+ }
+
+ ret = dcss_ctxld_irq_config(priv);
+ if (!ret)
+ return ret;
+
+ dcss_ctxld_hw_cfg(dcss);
+
+ return 0;
+}
+
+void dcss_ctxld_exit(struct dcss_soc *dcss)
+{
+}
+
+static int __dcss_ctxld_enable(struct dcss_ctxld_priv *ctxld)
+{
+ int curr_ctx = ctxld->current_ctx;
+ u32 db_base, sb_base, sb_count;
+ u32 sb_hp_cnt, sb_lp_cnt, db_cnt;
+
+ dcss_dpr_write_sysctrl(ctxld->dcss);
+ dcss_scaler_write_sclctrl(ctxld->dcss);
+
+ if (dcss_dtrc_is_running(ctxld->dcss, 1) ||
+ dcss_dtrc_is_running(ctxld->dcss, 2)) {
+ dcss_dtrc_switch_banks(ctxld->dcss);
+ ctxld->armed = true;
+ }
+
+ sb_hp_cnt = ctxld->ctx_size[curr_ctx][CTX_SB_HP];
+ sb_lp_cnt = ctxld->ctx_size[curr_ctx][CTX_SB_LP];
+ db_cnt = ctxld->ctx_size[curr_ctx][CTX_DB];
+
+ /* make sure SB_LP context area comes after SB_HP */
+ if (sb_lp_cnt &&
+ ctxld->sb_lp[curr_ctx] != ctxld->sb_hp[curr_ctx] + sb_hp_cnt) {
+ struct dcss_ctxld_item *sb_lp_adjusted;
+
+ sb_lp_adjusted = ctxld->sb_hp[curr_ctx] + sb_hp_cnt;
+
+ memcpy(sb_lp_adjusted, ctxld->sb_lp[curr_ctx],
+ sb_lp_cnt * CTX_ITEM_SIZE);
+ }
+
+ db_base = db_cnt ? ctxld->db_paddr[curr_ctx] : 0;
+
+ dcss_writel(db_base, ctxld->ctxld_reg + DCSS_CTXLD_DB_BASE_ADDR);
+ dcss_writel(db_cnt, ctxld->ctxld_reg + DCSS_CTXLD_DB_COUNT);
+
+ if (sb_hp_cnt)
+ sb_count = ((sb_hp_cnt << SB_HP_COUNT_POS) & SB_HP_COUNT_MASK) |
+ ((sb_lp_cnt << SB_LP_COUNT_POS) & SB_LP_COUNT_MASK);
+ else
+ sb_count = (sb_lp_cnt << SB_HP_COUNT_POS) & SB_HP_COUNT_MASK;
+
+ sb_base = sb_count ? ctxld->sb_paddr[curr_ctx] : 0;
+
+ dcss_writel(sb_base, ctxld->ctxld_reg + DCSS_CTXLD_SB_BASE_ADDR);
+ dcss_writel(sb_count, ctxld->ctxld_reg + DCSS_CTXLD_SB_COUNT);
+
+ dcss_trace_module(TRACE_CTXLD,
+ TRACE_ARM | db_cnt | (sb_count << 16) |
+ ((u64)ctxld->current_ctx << 32));
+
+ /* enable the context loader */
+ dcss_set(CTXLD_ENABLE, ctxld->ctxld_reg + DCSS_CTXLD_CONTROL_STATUS);
+
+ ctxld->in_use = true;
+
+ /*
+ * Toggle the current context to the alternate one so that any updates
+ * in the modules' settings take place there.
+ */
+ ctxld->current_ctx ^= 1;
+
+ ctxld->ctx_size[ctxld->current_ctx][CTX_DB] = 0;
+ ctxld->ctx_size[ctxld->current_ctx][CTX_SB_HP] = 0;
+ ctxld->ctx_size[ctxld->current_ctx][CTX_SB_LP] = 0;
+
+ return 0;
+}
+
+/**
+ * dcss_ctxld_enable - Enable context loader module.
+ *
+ * @dcss: pointer to dcss_soc.
+ *
+ * Returns:
+ * Zero on success, negative errno on failure.
+ */
+int dcss_ctxld_enable(struct dcss_soc *dcss)
+{
+ struct dcss_ctxld_priv *ctxld = dcss->ctxld_priv;
+ unsigned long flags;
+
+ spin_lock_irqsave(&ctxld->lock, flags);
+ ctxld->armed = true;
+ spin_unlock_irqrestore(&ctxld->lock, flags);
+
+ return 0;
+}
+EXPORT_SYMBOL(dcss_ctxld_enable);
+
+void dcss_ctxld_kick(struct dcss_soc *dcss)
+{
+ struct dcss_ctxld_priv *ctxld = dcss->ctxld_priv;
+ unsigned long flags;
+
+ dcss_trace_module(TRACE_CTXLD, TRACE_KICK);
+
+ spin_lock_irqsave(&ctxld->lock, flags);
+ if (ctxld->armed && !ctxld->in_use) {
+ ctxld->armed = false;
+ __dcss_ctxld_enable(dcss->ctxld_priv);
+ }
+ spin_unlock_irqrestore(&ctxld->lock, flags);
+}
+EXPORT_SYMBOL(dcss_ctxld_kick);
+
+void dcss_ctxld_write_irqsafe(struct dcss_soc *dcss, u32 ctx_id, u32 val,
+ u32 reg_ofs)
+{
+ struct dcss_ctxld_priv *ctxld = dcss->ctxld_priv;
+ int curr_ctx = ctxld->current_ctx;
+ struct dcss_ctxld_item *ctx[] = {
+ [CTX_DB] = ctxld->db[curr_ctx],
+ [CTX_SB_HP] = ctxld->sb_hp[curr_ctx],
+ [CTX_SB_LP] = ctxld->sb_lp[curr_ctx]
+ };
+ int item_idx = ctxld->ctx_size[curr_ctx][ctx_id];
+
+ /* if we hit this, we've got to increase the maximum context size */
+ BUG_ON(dcss_ctxld_ctx_size[ctx_id] - 1 < item_idx);
+
+ ctx[ctx_id][item_idx].val = val;
+ ctx[ctx_id][item_idx].ofs = reg_ofs;
+ ctxld->ctx_size[curr_ctx][ctx_id] += 1;
+}
+
+void dcss_ctxld_write(struct dcss_soc *dcss, u32 ctx_id, u32 val, u32 reg_ofs)
+{
+ struct dcss_ctxld_priv *ctxld = dcss->ctxld_priv;
+ unsigned long flags;
+
+ spin_lock_irqsave(&ctxld->lock, flags);
+ dcss_ctxld_write_irqsafe(dcss, ctx_id, val, reg_ofs);
+ spin_unlock_irqrestore(&ctxld->lock, flags);
+}
+
+bool dcss_ctxld_is_flushed(struct dcss_soc *dcss)
+{
+ struct dcss_ctxld_priv *ctxld = dcss->ctxld_priv;
+
+ return ctxld->ctx_size[ctxld->current_ctx][CTX_DB] == 0 &&
+ ctxld->ctx_size[ctxld->current_ctx][CTX_SB_HP] == 0 &&
+ ctxld->ctx_size[ctxld->current_ctx][CTX_SB_LP] == 0;
+}
+EXPORT_SYMBOL(dcss_ctxld_is_flushed);
+
+int dcss_ctxld_resume(struct dcss_soc *dcss)
+{
+ struct dcss_ctxld_priv *ctxld = dcss->ctxld_priv;
+
+ dcss_ctxld_hw_cfg(dcss);
+
+ if (!ctxld->irq_en) {
+ enable_irq(dcss->ctxld_priv->irq);
+ ctxld->irq_en = true;
+ }
+
+ return 0;
+}
+
+int dcss_ctxld_suspend(struct dcss_soc *dcss)
+{
+ int ret = 0;
+ struct dcss_ctxld_priv *ctxld = dcss->ctxld_priv;
+ int wait_time_ms = 0;
+ unsigned long flags;
+
+ dcss_ctxld_kick(dcss);
+
+ while (ctxld->in_use && wait_time_ms < 500) {
+ msleep(20);
+ wait_time_ms += 20;
+ }
+
+ if (wait_time_ms > 500)
+ return -ETIMEDOUT;
+
+ spin_lock_irqsave(&ctxld->lock, flags);
+
+ if (ctxld->irq_en) {
+ disable_irq_nosync(dcss->ctxld_priv->irq);
+ ctxld->irq_en = false;
+ }
+
+ /* reset context region and sizes */
+ ctxld->current_ctx = 0;
+ ctxld->ctx_size[0][CTX_DB] = 0;
+ ctxld->ctx_size[0][CTX_SB_HP] = 0;
+ ctxld->ctx_size[0][CTX_SB_LP] = 0;
+
+ spin_unlock_irqrestore(&ctxld->lock, flags);
+ return ret;
+}
+
+#ifdef CONFIG_DEBUG_FS
+void dcss_ctxld_dump(struct seq_file *s, void *data)
+{
+ struct dcss_soc *dcss = data;
+ struct dcss_ctxld_priv *ctxld = dcss->ctxld_priv;
+ int curr_ctx = ctxld->current_ctx;
+ int i;
+ struct dcss_ctxld_item *ctx_db, *ctx_sb_hp, *ctx_sb_lp;
+ u32 ctx_db_size, ctx_sb_hp_size, ctx_sb_lp_size;
+
+ ctx_db_size = ctxld->ctx_size[curr_ctx ^ 1][CTX_DB];
+ ctx_sb_hp_size = ctxld->ctx_size[curr_ctx ^ 1][CTX_SB_HP];
+ ctx_sb_lp_size = ctxld->ctx_size[curr_ctx ^ 1][CTX_SB_LP];
+
+ ctx_db = ctxld->db[curr_ctx ^ 1];
+ ctx_sb_hp = ctxld->sb_hp[curr_ctx ^ 1];
+ ctx_sb_lp = ctxld->sb_hp[curr_ctx ^ 1] + ctx_sb_hp_size;
+
+ seq_puts(s, ">> Dumping loaded context:\n");
+ seq_puts(s, "\t>>Dumping CTX_DB:\n");
+ for (i = 0; i < ctx_db_size; i++)
+ seq_printf(s, "\t0x%16llx -> 0x%08x : 0x%08x\n",
+ (u64)&ctx_db[i], ctx_db[i].ofs, ctx_db[i].val);
+ seq_puts(s, "\t>>Dumping CTX_SB_HP:\n");
+ for (i = 0; i < ctx_sb_hp_size; i++)
+ seq_printf(s, "\t0x%16llx -> 0x%08x : 0x%08x\n",
+ (u64)&ctx_sb_hp[i], ctx_sb_hp[i].ofs,
+ ctx_sb_hp[i].val);
+ seq_puts(s, "\t>>Dumping CTX_SB_LP:\n");
+ for (i = 0; i < ctx_sb_lp_size; i++)
+ seq_printf(s, "\t0x%16llx -> 0x%08x : 0x%08x\n",
+ (u64)&ctx_sb_lp[i], ctx_sb_lp[i].ofs,
+ ctx_sb_lp[i].val);
+}
+#endif
diff --git a/drivers/gpu/imx/dcss/dcss-dec400d.c b/drivers/gpu/imx/dcss/dcss-dec400d.c
new file mode 100644
index 000000000000..b37e7578e383
--- /dev/null
+++ b/drivers/gpu/imx/dcss/dcss-dec400d.c
@@ -0,0 +1,321 @@
+/*
+ * Copyright (C) 2017 NXP
+ *
+ * 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/device.h>
+#include <linux/bitops.h>
+#include <linux/io.h>
+#include <drm/drm_fourcc.h>
+
+#include <video/imx-dcss.h>
+#include <video/viv-metadata.h>
+#include "dcss-prv.h"
+
+#define USE_CTXLD 1
+
+/* DEC400D registers offsets */
+#define DEC400D_READCONFIG_BASE 0x800
+#define DEC400D_READCONFIG(i) (DEC400D_READCONFIG_BASE + ((i) << 2))
+#define DEC400D_READCONFIG_BASE 0x800
+#define DEC400D_READBUFFERBASE0 0x900
+#define DEC400D_READCACHEBASE0 0x980
+#define DEC400D_CONTROL 0xB00
+#define DEC400D_CLEAR 0xB80
+#define COMPRESSION_ENABLE_BIT 0
+#define COMPRESSION_FORMAT_BIT 3
+#define COMPRESSION_ALIGN_MODE_BIT 16
+#define TILE_ALIGN_MODE_BIT 22
+#define TILE_MODE_BIT 25
+#define DEC400D_READBUFFERBASE0 0x900
+#define DEC400D_READCACHEBASE0 0x980
+#define DEC400D_CONTROL 0xB00
+#define DISABLE_COMPRESSION_BIT 1
+#define SHADOW_TRIGGER_BIT 29
+#define DEC400_CFMT_ARGB8 0x0
+#define DEC400_CFMT_XRGB8 0x1
+#define DEC400_CFMT_AYUV 0x2
+#define DEC400_CFMT_UYVY 0x3
+#define DEC400_CFMT_YUY2 0x4
+#define DEC400_CFMT_YUV_ONLY 0x5
+#define DEC400_CFMT_UV_MIX 0x6
+#define DEC400_CFMT_ARGB4 0x7
+#define DEC400_CFMT_XRGB4 0x8
+#define DEC400_CFMT_A1R5G5B5 0x9
+#define DEC400_CFMT_X1R5G5B5 0xA
+#define DEC400_CFMT_R5G6B5 0xB
+#define DEC400_CFMT_Z24S8 0xC
+#define DEC400_CFMT_Z24 0xD
+#define DEC400_CFMT_Z16 0xE
+#define DEC400_CFMT_A2R10G10B10 0xF
+#define DEC400_CFMT_BAYER 0x10
+#define DEC400_CFMT_SIGNED_BAYER 0x11
+
+struct dcss_dec400d_priv {
+ struct dcss_soc *dcss;
+ void __iomem *dec400d_reg;
+ uint32_t dec400d_reg_base;
+ uint64_t modifier[4];
+ uint32_t pixel_format;
+ uint32_t ctx_id;
+ bool bypass; /* bypass or decompress */
+};
+
+static void dcss_dec400d_write(struct dcss_dec400d_priv *dec400d,
+ uint32_t value,
+ uint32_t offset)
+{
+#if !USE_CTXLD
+ dcss_writel(value, dec400d->dec400d_reg + offset);
+#else
+ dcss_ctxld_write(dec400d->dcss, dec400d->ctx_id,
+ value, dec400d->dec400d_reg_base + offset);
+#endif
+}
+
+int dcss_dec400d_init(struct dcss_soc *dcss, unsigned long dec400d_base)
+{
+ struct dcss_dec400d_priv *dec400d;
+
+ dec400d = devm_kzalloc(dcss->dev, sizeof(*dec400d), GFP_KERNEL);
+ if (!dec400d)
+ return -ENOMEM;
+
+ dcss->dec400d_priv = dec400d;
+ dec400d->dcss = dcss;
+
+ dec400d->dec400d_reg = devm_ioremap(dcss->dev, dec400d_base, SZ_4K);
+ if (!dec400d->dec400d_reg) {
+ dev_err(dcss->dev, "dec400d: unable to remap dec400d base\n");
+ return -ENOMEM;
+ }
+
+ dec400d->dec400d_reg_base = dec400d_base;
+
+#if USE_CTXLD
+ dec400d->ctx_id = CTX_SB_HP;
+#endif
+
+ return 0;
+}
+
+void dcss_dec400d_exit(struct dcss_soc *dcss)
+{
+ struct dcss_dec400d_priv *dec400d = dcss->dec400d_priv;
+
+ if (!IS_ERR(dec400d)) {
+ devm_kfree(dcss->dev, dec400d);
+ dcss->dec400d_priv = NULL;
+ }
+}
+
+void dcss_dec400d_set_format_mod(struct dcss_soc *dcss,
+ uint32_t fourcc,
+ uint32_t mod_idx,
+ uint64_t modifier)
+{
+ struct dcss_dec400d_priv *dec400d = dcss->dec400d_priv;
+
+ if (mod_idx > 3) {
+ WARN_ON(1);
+ return;
+ }
+
+ if (mod_idx == 0)
+ dec400d->pixel_format = fourcc;
+
+ dec400d->modifier[mod_idx] = modifier;
+}
+EXPORT_SYMBOL(dcss_dec400d_set_format_mod);
+
+void dcss_dec400d_bypass(struct dcss_soc *dcss)
+{
+ uint32_t control;
+ struct dcss_dec400d_priv *dec400d = dcss->dec400d_priv;
+
+ dcss_dec400d_read_config(dcss, 0, false, 0);
+
+ control = dcss_readl(dec400d->dec400d_reg + DEC400D_CONTROL);
+ pr_debug("%s: dec400d control = %#x\n", __func__, control);
+
+ control |= 0x1 << DISABLE_COMPRESSION_BIT;
+ dcss_dec400d_write(dec400d, control, DEC400D_CONTROL);
+
+ /* Trigger shadow registers */
+ control |= 0x1 << SHADOW_TRIGGER_BIT;
+ dcss_dec400d_write(dec400d, control, DEC400D_CONTROL);
+
+ dec400d->bypass = true;
+}
+EXPORT_SYMBOL(dcss_dec400d_bypass);
+
+void dcss_dec400d_shadow_trig(struct dcss_soc *dcss)
+{
+ uint32_t control;
+ struct dcss_dec400d_priv *dec400d = dcss->dec400d_priv;
+
+ /* do nothing */
+ if (dec400d->bypass == true)
+ return;
+
+ control = dcss_readl(dec400d->dec400d_reg + DEC400D_CONTROL);
+
+ /* Trigger shadow registers */
+ control |= 0x1 << SHADOW_TRIGGER_BIT;
+ dcss_dec400d_write(dec400d, control, DEC400D_CONTROL);
+}
+EXPORT_SYMBOL(dcss_dec400d_shadow_trig);
+
+void dcss_dec400d_addr_set(struct dcss_soc *dcss,
+ uint32_t baddr,
+ uint32_t caddr)
+{
+ struct dcss_dec400d_priv *dec400d = dcss->dec400d_priv;
+
+ /* set frame buffer base addr */
+ dcss_dec400d_write(dec400d, baddr, DEC400D_READBUFFERBASE0);
+
+ /* set tile status cache addr */
+ dcss_dec400d_write(dec400d, caddr, DEC400D_READCACHEBASE0);
+
+ dec400d->bypass = false;
+}
+EXPORT_SYMBOL(dcss_dec400d_addr_set);
+
+void dcss_dec400d_read_config(struct dcss_soc *dcss,
+ uint32_t read_id,
+ bool compress_en,
+ uint32_t compress_format)
+{
+ uint32_t cformat = 0;
+ uint32_t read_config = 0x0;
+ struct dcss_dec400d_priv *dec400d = dcss->dec400d_priv;
+
+ /* TODO: using 'read_id' 0 by default */
+ if (read_id) {
+ WARN_ON(1);
+ return;
+ }
+
+ if (compress_en == false)
+ goto config;
+
+ switch (compress_format) {
+ case _VIV_CFMT_ARGB8:
+ cformat = DEC400_CFMT_ARGB8;
+ break;
+ case _VIV_CFMT_XRGB8:
+ cformat = DEC400_CFMT_XRGB8;
+ break;
+ case _VIV_CFMT_AYUV:
+ cformat = DEC400_CFMT_AYUV;
+ break;
+ case _VIV_CFMT_UYVY:
+ cformat = DEC400_CFMT_UYVY;
+ break;
+ case _VIV_CFMT_YUY2:
+ cformat = DEC400_CFMT_YUY2;
+ break;
+ case _VIV_CFMT_YUV_ONLY:
+ cformat = DEC400_CFMT_YUV_ONLY;
+ break;
+ case _VIV_CFMT_UV_MIX:
+ cformat = DEC400_CFMT_UV_MIX;
+ break;
+ case _VIV_CFMT_ARGB4:
+ cformat = DEC400_CFMT_ARGB4;
+ break;
+ case _VIV_CFMT_XRGB4:
+ cformat = DEC400_CFMT_XRGB4;
+ break;
+ case _VIV_CFMT_A1R5G5B5:
+ cformat = DEC400_CFMT_A1R5G5B5;
+ break;
+ case _VIV_CFMT_X1R5G5B5:
+ cformat = DEC400_CFMT_X1R5G5B5;
+ break;
+ case _VIV_CFMT_R5G6B5:
+ cformat = DEC400_CFMT_R5G6B5;
+ break;
+ case _VIV_CFMT_Z24S8:
+ cformat = DEC400_CFMT_Z24S8;
+ break;
+ case _VIV_CFMT_Z24:
+ cformat = DEC400_CFMT_Z24;
+ break;
+ case _VIV_CFMT_Z16:
+ cformat = DEC400_CFMT_Z16;
+ break;
+ case _VIV_CFMT_A2R10G10B10:
+ cformat = DEC400_CFMT_A2R10G10B10;
+ break;
+ case _VIV_CFMT_BAYER:
+ cformat = DEC400_CFMT_BAYER;
+ break;
+ case _VIV_CFMT_SIGNED_BAYER:
+ cformat = DEC400_CFMT_SIGNED_BAYER;
+ break;
+ default:
+ /* TODO: not support yet */
+ WARN_ON(1);
+ return;
+ }
+
+ /* Dec compress format */
+ read_config |= cformat << COMPRESSION_FORMAT_BIT;
+
+ /* ALIGN32_BYTE */
+ read_config |= 0x2 << COMPRESSION_ALIGN_MODE_BIT;
+
+ /* TILE1_ALIGN */
+ read_config |= 0x0 << TILE_ALIGN_MODE_BIT;
+
+ /* TILE8x4 */
+ read_config |= 0x3 << TILE_MODE_BIT;
+
+ /* Compression Enable */
+ read_config |= 0x1 << COMPRESSION_ENABLE_BIT;
+
+config:
+ dcss_dec400d_write(dec400d, read_config, DEC400D_READCONFIG(read_id));
+}
+EXPORT_SYMBOL(dcss_dec400d_read_config);
+
+void dcss_dec400d_fast_clear_config(struct dcss_soc *dcss,
+ uint32_t fc_value,
+ bool enable)
+{
+ struct dcss_dec400d_priv *dec400d = dcss->dec400d_priv;
+
+ dcss_dec400d_write(dec400d, fc_value, DEC400D_CLEAR);
+}
+EXPORT_SYMBOL(dcss_dec400d_fast_clear_config);
+
+void dcss_dec400d_enable(struct dcss_soc *dcss)
+{
+ uint32_t control;
+ struct dcss_dec400d_priv *dec400d = dcss->dec400d_priv;
+
+ if (dec400d->bypass)
+ return;
+
+ control = dcss_readl(dec400d->dec400d_reg + DEC400D_CONTROL);
+
+ /* enable compression */
+ control &= ~(0x1 << DISABLE_COMPRESSION_BIT);
+ dcss_dec400d_write(dec400d, control, DEC400D_CONTROL);
+
+ /* Trigger shadow registers */
+ control |= 0x1 << SHADOW_TRIGGER_BIT;
+ dcss_dec400d_write(dec400d, control, DEC400D_CONTROL);
+}
+EXPORT_SYMBOL(dcss_dec400d_enable);
diff --git a/drivers/gpu/imx/dcss/dcss-dpr.c b/drivers/gpu/imx/dcss/dcss-dpr.c
new file mode 100644
index 000000000000..0b6bcd4079b7
--- /dev/null
+++ b/drivers/gpu/imx/dcss/dcss-dpr.c
@@ -0,0 +1,771 @@
+/*
+ * Copyright (C) 2017-2018 NXP
+ *
+ * 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/device.h>
+#include <linux/bitops.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/sizes.h>
+#include <linux/io.h>
+#include <drm/drmP.h>
+#include <drm/drm_fourcc.h>
+
+#include <video/imx-dcss.h>
+#include "dcss-prv.h"
+
+#define USE_CTXLD
+
+#define DCSS_DPR_DEV_NAME "dcss_dpr"
+
+#define DCSS_DPR_SYSTEM_CTRL0 0x000
+#define RUN_EN BIT(0)
+#define SOFT_RESET BIT(1)
+#define REPEAT_EN BIT(2)
+#define SHADOW_LOAD_EN BIT(3)
+#define SW_SHADOW_LOAD_SEL BIT(4)
+#define BCMD2AXI_MSTR_ID_CTRL BIT(16)
+#define DCSS_DPR_IRQ_MASK 0x020
+#define DCSS_DPR_IRQ_MASK_STATUS 0x030
+#define DCSS_DPR_IRQ_NONMASK_STATUS 0x040
+#define IRQ_DPR_CTRL_DONE BIT(0)
+#define IRQ_DPR_RUN BIT(1)
+#define IRQ_DPR_SHADOW_LOADED BIT(2)
+#define IRQ_AXI_READ_ERR BIT(3)
+#define DPR2RTR_YRGB_FIFO_OVFL BIT(4)
+#define DPR2RTR_UV_FIFO_OVFL BIT(5)
+#define DPR2RTR_FIFO_LD_BUF_RDY_YRGB_ERR BIT(6)
+#define DPR2RTR_FIFO_LD_BUF_RDY_UV_ERR BIT(7)
+#define DCSS_DPR_MODE_CTRL0 0x050
+#define RTR_3BUF_EN BIT(0)
+#define RTR_4LINE_BUF_EN BIT(1)
+#define TILE_TYPE_POS 2
+#define TILE_TYPE_MASK GENMASK(4, 2)
+#define YUV_EN BIT(6)
+#define COMP_2PLANE_EN BIT(7)
+#define PIX_SIZE_POS 8
+#define PIX_SIZE_MASK GENMASK(9, 8)
+#define PIX_LUMA_UV_SWAP BIT(10)
+#define PIX_UV_SWAP BIT(11)
+#define B_COMP_SEL_POS 12
+#define B_COMP_SEL_MASK GENMASK(13, 12)
+#define G_COMP_SEL_POS 14
+#define G_COMP_SEL_MASK GENMASK(15, 14)
+#define R_COMP_SEL_POS 16
+#define R_COMP_SEL_MASK GENMASK(17, 16)
+#define A_COMP_SEL_POS 18
+#define A_COMP_SEL_MASK GENMASK(19, 18)
+#define DCSS_DPR_FRAME_CTRL0 0x070
+#define HFLIP_EN BIT(0)
+#define VFLIP_EN BIT(1)
+#define ROT_ENC_POS 2
+#define ROT_ENC_MASK GENMASK(3, 2)
+#define ROT_FLIP_ORDER_EN BIT(4)
+#define PITCH_POS 16
+#define PITCH_MASK GENMASK(31, 16)
+#define DCSS_DPR_FRAME_1P_CTRL0 0x090
+#define DCSS_DPR_FRAME_1P_PIX_X_CTRL 0x0A0
+#define DCSS_DPR_FRAME_1P_PIX_Y_CTRL 0x0B0
+#define DCSS_DPR_FRAME_1P_BASE_ADDR 0x0C0
+#define DCSS_DPR_FRAME_2P_CTRL0 0x0E0
+#define DCSS_DPR_FRAME_2P_PIX_X_CTRL 0x0F0
+#define DCSS_DPR_FRAME_2P_PIX_Y_CTRL 0x100
+#define DCSS_DPR_FRAME_2P_BASE_ADDR 0x110
+#define DCSS_DPR_STATUS_CTRL0 0x130
+#define STATUS_MUX_SEL_MASK GENMASK(2, 0)
+#define STATUS_SRC_SEL_POS 16
+#define STATUS_SRC_SEL_MASK GENMASK(18, 16)
+#define DCSS_DPR_STATUS_CTRL1 0x140
+#define DCSS_DPR_RTRAM_CTRL0 0x200
+#define NUM_ROWS_ACTIVE BIT(0)
+#define THRES_HIGH_POS 1
+#define THRES_HIGH_MASK GENMASK(3, 1)
+#define THRES_LOW_POS 4
+#define THRES_LOW_MASK GENMASK(6, 4)
+#define ABORT_SEL BIT(7)
+
+#define TRACE_COMPLETION (1LL << 48)
+#define TRACE_BUF_SUBMISSION (2LL << 48)
+
+struct dcss_dpr_ch {
+ void __iomem *base_reg;
+ u32 base_ofs;
+ u32 ctx_id; /* an ID to the allocated region in context loader */
+
+ u32 pix_format;
+ u32 bpp;
+ u32 planes;
+ enum dcss_pix_size pix_size;
+ enum dcss_tile_type tile;
+ bool rtram_4line_en;
+ bool rtram_3buf_en;
+
+ u32 frame_ctrl;
+ u32 mode_ctrl;
+ u32 sys_ctrl;
+ u32 rtram_ctrl;
+
+ bool sys_ctrl_chgd;
+
+ u32 pitch;
+
+ bool use_dtrc;
+
+ int ch_num;
+ int irq;
+};
+
+struct dcss_dpr_priv {
+ struct dcss_soc *dcss;
+ struct dcss_dpr_ch ch[3];
+};
+
+static void dcss_dpr_write(struct dcss_dpr_priv *dpr, int ch_num,
+ u32 val, u32 ofs)
+{
+#if !defined(USE_CTXLD)
+ dcss_writel(val, dpr->ch[ch_num].base_reg + ofs);
+#else
+ dcss_ctxld_write(dpr->dcss, dpr->ch[ch_num].ctx_id,
+ val, dpr->ch[ch_num].base_ofs + ofs);
+#endif
+}
+
+#ifdef CONFIG_DEBUG_FS
+static struct dcss_debug_reg dpr_debug_reg[] = {
+ DCSS_DBG_REG(DCSS_DPR_SYSTEM_CTRL0),
+ DCSS_DBG_REG(DCSS_DPR_IRQ_MASK),
+ DCSS_DBG_REG(DCSS_DPR_IRQ_MASK_STATUS),
+ DCSS_DBG_REG(DCSS_DPR_IRQ_NONMASK_STATUS),
+ DCSS_DBG_REG(DCSS_DPR_MODE_CTRL0),
+ DCSS_DBG_REG(DCSS_DPR_FRAME_CTRL0),
+ DCSS_DBG_REG(DCSS_DPR_FRAME_1P_CTRL0),
+ DCSS_DBG_REG(DCSS_DPR_FRAME_1P_PIX_X_CTRL),
+ DCSS_DBG_REG(DCSS_DPR_FRAME_1P_PIX_Y_CTRL),
+ DCSS_DBG_REG(DCSS_DPR_FRAME_1P_BASE_ADDR),
+ DCSS_DBG_REG(DCSS_DPR_FRAME_2P_CTRL0),
+ DCSS_DBG_REG(DCSS_DPR_FRAME_2P_PIX_X_CTRL),
+ DCSS_DBG_REG(DCSS_DPR_FRAME_2P_PIX_Y_CTRL),
+ DCSS_DBG_REG(DCSS_DPR_FRAME_2P_BASE_ADDR),
+ DCSS_DBG_REG(DCSS_DPR_STATUS_CTRL0),
+ DCSS_DBG_REG(DCSS_DPR_STATUS_CTRL1),
+ DCSS_DBG_REG(DCSS_DPR_RTRAM_CTRL0),
+};
+
+void dcss_dpr_dump_regs(struct seq_file *s, void *data)
+{
+ struct dcss_soc *dcss = data;
+ int i, j;
+
+ for (i = 0; i < 3; i++) {
+ seq_printf(s, ">> Dumping DPR CH %d:\n", i);
+ for (j = 0; j < ARRAY_SIZE(dpr_debug_reg); j++)
+ seq_printf(s, "%-35s(0x%04x) -> 0x%08x\n",
+ dpr_debug_reg[j].name,
+ dpr_debug_reg[j].ofs,
+ dcss_readl(dcss->dpr_priv->ch[i].base_reg +
+ dpr_debug_reg[j].ofs));
+ }
+}
+#endif
+
+static irqreturn_t dcss_dpr_irq_handler(int irq, void *data)
+{
+ struct dcss_dpr_ch *ch = data;
+
+ dcss_trace_module(TRACE_DPR, TRACE_COMPLETION | ch->ch_num);
+
+ dcss_clr(1, ch->base_reg + DCSS_DPR_IRQ_NONMASK_STATUS);
+
+ return IRQ_HANDLED;
+}
+
+static int dcss_dpr_irq_config(struct dcss_soc *dcss, int ch_num)
+{
+ struct platform_device *pdev = to_platform_device(dcss->dev);
+ struct dcss_dpr_priv *dpr = dcss->dpr_priv;
+ struct dcss_dpr_ch *ch = &dpr->ch[ch_num];
+ int ret;
+ char irq_name[20];
+
+ sprintf(irq_name, "dpr_dc_ch%d", ch_num);
+ irq_name[10] = 0;
+
+ ch->irq = platform_get_irq_byname(pdev, irq_name);
+ if (ch->irq < 0) {
+ dev_err(dcss->dev, "dpr: can't get DPR irq\n");
+ return ch->irq;
+ }
+
+ /* mask interrupts off */
+ dcss_set(0xff, ch->base_reg + DCSS_DPR_IRQ_MASK);
+
+ ret = devm_request_irq(dcss->dev, ch->irq,
+ dcss_dpr_irq_handler,
+ IRQF_TRIGGER_HIGH,
+ "dcss-dpr", ch);
+ if (ret) {
+ dev_err(dcss->dev, "dpr: irq request failed.\n");
+ return ret;
+ }
+
+ disable_irq(ch->irq);
+
+ dcss_writel(0xfe, ch->base_reg + DCSS_DPR_IRQ_MASK);
+
+ return 0;
+}
+
+static int dcss_dpr_ch_init_all(struct dcss_soc *dcss, unsigned long dpr_base)
+{
+ struct dcss_dpr_priv *priv = dcss->dpr_priv;
+ struct dcss_dpr_ch *ch;
+ int i;
+
+ for (i = 0; i < 3; i++) {
+ ch = &priv->ch[i];
+
+ ch->base_ofs = dpr_base + i * 0x1000;
+
+ ch->base_reg = devm_ioremap(dcss->dev, ch->base_ofs, SZ_4K);
+ if (!ch->base_reg) {
+ dev_err(dcss->dev, "dpr: unable to remap ch %d base\n",
+ i);
+ return -ENOMEM;
+ }
+
+ ch->ch_num = i;
+
+ dcss_dpr_irq_config(dcss, i);
+
+#if defined(USE_CTXLD)
+ ch->ctx_id = CTX_SB_HP;
+#endif
+ }
+
+ return 0;
+}
+
+int dcss_dpr_init(struct dcss_soc *dcss, unsigned long dpr_base)
+{
+ struct dcss_dpr_priv *priv;
+
+ priv = devm_kzalloc(dcss->dev, sizeof(struct dcss_dpr_priv),
+ GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ dcss->dpr_priv = priv;
+ priv->dcss = dcss;
+
+ return dcss_dpr_ch_init_all(dcss, dpr_base);
+}
+
+void dcss_dpr_exit(struct dcss_soc *dcss)
+{
+ struct dcss_dpr_priv *dpr = dcss->dpr_priv;
+ int ch_no;
+
+ /* stop DPR on all channels */
+ for (ch_no = 0; ch_no < 3; ch_no++) {
+ struct dcss_dpr_ch *ch = &dpr->ch[ch_no];
+
+ dcss_writel(0, ch->base_reg + DCSS_DPR_SYSTEM_CTRL0);
+ }
+}
+
+static u32 dcss_dpr_x_pix_wide_adjust(struct dcss_dpr_ch *ch, u32 pix_wide,
+ u32 pix_format)
+{
+ u8 pix_in_64byte_map[3][5] = {
+ /* LIN, GPU_STD, GPU_SUP, VPU_YUV420, VPU_VP9 */
+ { 64, 8, 8, 8, 16}, /* PIX_SIZE_8 */
+ { 32, 8, 8, 8, 8}, /* PIX_SIZE_16 */
+ { 16, 4, 4, 8, 8}, /* PIX_SIZE_32 */
+ };
+ u32 offset;
+ u32 div_64byte_mod, pix_in_64byte;
+
+ pix_in_64byte = pix_in_64byte_map[ch->pix_size][ch->tile];
+
+ if (pix_format == DRM_FORMAT_P010)
+ pix_wide = pix_wide * 10 / 8;
+
+ div_64byte_mod = pix_wide % pix_in_64byte;
+ offset = (div_64byte_mod == 0) ? 0 : (pix_in_64byte - div_64byte_mod);
+
+ return pix_wide + offset;
+}
+
+static u32 dcss_dpr_y_pix_high_adjust(struct dcss_dpr_ch *ch, u32 pix_high,
+ u32 pix_format)
+{
+ u8 num_rows_buf = ch->rtram_4line_en ? 4 : 8;
+ u32 offset, pix_y_mod;
+
+ pix_y_mod = pix_high % num_rows_buf;
+ offset = pix_y_mod ? (num_rows_buf - pix_y_mod) : 0;
+
+ return pix_high + offset;
+}
+
+void dcss_dpr_set_res(struct dcss_soc *dcss, int ch_num, u32 xres, u32 yres,
+ u32 adj_w, u32 adj_h)
+{
+ struct dcss_dpr_priv *dpr = dcss->dpr_priv;
+ struct dcss_dpr_ch *ch = &dpr->ch[ch_num];
+ u32 pix_x_wide, pix_y_high;
+ int plane, max_planes = 1;
+ u32 gap = DCSS_DPR_FRAME_2P_BASE_ADDR - DCSS_DPR_FRAME_1P_BASE_ADDR;
+ u32 pix_format = dpr->ch[ch_num].pix_format;
+
+ if (pix_format == DRM_FORMAT_NV12 ||
+ pix_format == DRM_FORMAT_NV21 ||
+ pix_format == DRM_FORMAT_P010)
+ max_planes = 2;
+
+ if (pix_format == DRM_FORMAT_P010)
+ adj_w = adj_w * 10 / 8;
+
+ for (plane = 0; plane < max_planes; plane++) {
+ yres = plane == 1 ? yres >> 1 : yres;
+ adj_h = plane == 1 ? adj_h >> 1 : adj_h;
+
+ pix_x_wide = dcss_dpr_x_pix_wide_adjust(ch, xres, pix_format);
+ pix_y_high = dcss_dpr_y_pix_high_adjust(ch, yres, pix_format);
+
+ /* DTRC may need another width alignment. If it does, use it. */
+ if (pix_x_wide < adj_w)
+ pix_x_wide = adj_w;
+
+ if (pix_y_high < adj_h)
+ pix_y_high = adj_h;
+
+ if (plane == 0)
+ ch->pitch = pix_x_wide;
+
+ dcss_dpr_write(dpr, ch_num, pix_x_wide,
+ DCSS_DPR_FRAME_1P_PIX_X_CTRL + plane * gap);
+ dcss_dpr_write(dpr, ch_num, pix_y_high,
+ DCSS_DPR_FRAME_1P_PIX_Y_CTRL + plane * gap);
+
+ dcss_dpr_write(dpr, ch_num, ch->use_dtrc ? 7 : 2,
+ DCSS_DPR_FRAME_1P_CTRL0 + plane * gap);
+ }
+}
+EXPORT_SYMBOL(dcss_dpr_set_res);
+
+void dcss_dpr_addr_set(struct dcss_soc *dcss, int ch_num, u32 luma_base_addr,
+ u32 chroma_base_addr, u16 pitch)
+{
+ struct dcss_dpr_ch *ch = &dcss->dpr_priv->ch[ch_num];
+
+ dcss_trace_module(TRACE_DPR, TRACE_BUF_SUBMISSION |
+ ((u64)ch_num << 32) | luma_base_addr);
+
+ if (ch->use_dtrc) {
+ luma_base_addr = 0x0;
+ chroma_base_addr = 0x10000000;
+ }
+
+ if (!dcss_dtrc_is_running(dcss, ch_num)) {
+ dcss_dpr_write(dcss->dpr_priv, ch_num, luma_base_addr,
+ DCSS_DPR_FRAME_1P_BASE_ADDR);
+
+ dcss_dpr_write(dcss->dpr_priv, ch_num, chroma_base_addr,
+ DCSS_DPR_FRAME_2P_BASE_ADDR);
+ }
+
+ if (ch->use_dtrc)
+ pitch = ch->pitch;
+
+ ch->frame_ctrl &= ~PITCH_MASK;
+ ch->frame_ctrl |= (((u32)pitch << PITCH_POS) & PITCH_MASK);
+}
+EXPORT_SYMBOL(dcss_dpr_addr_set);
+
+static void dcss_dpr_argb_comp_sel(struct dcss_soc *dcss, int ch_num,
+ int a_sel, int r_sel, int g_sel, int b_sel)
+{
+ struct dcss_dpr_ch *ch = &dcss->dpr_priv->ch[ch_num];
+ u32 sel;
+
+ sel = ((a_sel << A_COMP_SEL_POS) & A_COMP_SEL_MASK) |
+ ((r_sel << R_COMP_SEL_POS) & R_COMP_SEL_MASK) |
+ ((g_sel << G_COMP_SEL_POS) & G_COMP_SEL_MASK) |
+ ((b_sel << B_COMP_SEL_POS) & B_COMP_SEL_MASK);
+
+ ch->mode_ctrl &= ~(A_COMP_SEL_MASK | R_COMP_SEL_MASK |
+ G_COMP_SEL_MASK | B_COMP_SEL_MASK);
+ ch->mode_ctrl |= sel;
+}
+
+static void dcss_dpr_pix_size_set(struct dcss_soc *dcss, int ch_num,
+ int pix_size)
+{
+ u32 val;
+ struct dcss_dpr_ch *ch = &dcss->dpr_priv->ch[ch_num];
+
+ switch (pix_size) {
+ case 8:
+ val = 0;
+ break;
+ case 16:
+ val = 1;
+ break;
+ case 32:
+ val = 2;
+ break;
+ default:
+ val = 2;
+ break;
+ }
+
+ ch->pix_size = val;
+
+ ch->mode_ctrl &= ~PIX_SIZE_MASK;
+ ch->mode_ctrl |= ((val << PIX_SIZE_POS) & PIX_SIZE_MASK);
+}
+
+static void dcss_dpr_uv_swap(struct dcss_soc *dcss, int ch_num, bool swap)
+{
+ struct dcss_dpr_ch *ch = &dcss->dpr_priv->ch[ch_num];
+
+ ch->mode_ctrl &= ~PIX_UV_SWAP;
+ ch->mode_ctrl |= (swap ? PIX_UV_SWAP : 0);
+}
+
+static void dcss_dpr_y_uv_swap(struct dcss_soc *dcss, int ch_num, bool swap)
+{
+ struct dcss_dpr_ch *ch = &dcss->dpr_priv->ch[ch_num];
+
+ ch->mode_ctrl &= ~PIX_LUMA_UV_SWAP;
+ ch->mode_ctrl |= (swap ? PIX_LUMA_UV_SWAP : 0);
+}
+
+static void dcss_dpr_2plane_en(struct dcss_soc *dcss, int ch_num, bool en)
+{
+ struct dcss_dpr_ch *ch = &dcss->dpr_priv->ch[ch_num];
+
+ ch->mode_ctrl &= ~COMP_2PLANE_EN;
+ ch->mode_ctrl |= (en ? COMP_2PLANE_EN : 0);
+}
+
+static void dcss_dpr_yuv_en(struct dcss_soc *dcss, int ch_num, bool en)
+{
+ struct dcss_dpr_ch *ch = &dcss->dpr_priv->ch[ch_num];
+
+ ch->mode_ctrl &= ~YUV_EN;
+ ch->mode_ctrl |= (en ? YUV_EN : 0);
+}
+
+static void dcss_dpr_tile_set(struct dcss_soc *dcss, int ch_num,
+ enum dcss_tile_type tile)
+{
+ struct dcss_dpr_ch *ch = &dcss->dpr_priv->ch[ch_num];
+
+ ch->mode_ctrl &= ~TILE_TYPE_MASK;
+ ch->mode_ctrl |= ((tile << TILE_TYPE_POS) & TILE_TYPE_MASK);
+}
+
+void dcss_dpr_enable(struct dcss_soc *dcss, int ch_num, bool en)
+{
+ struct dcss_dpr_priv *dpr = dcss->dpr_priv;
+ struct dcss_dpr_ch *ch = &dpr->ch[ch_num];
+ u32 sys_ctrl;
+
+ sys_ctrl = (en ? REPEAT_EN | RUN_EN : 0);
+
+ if (en) {
+ dcss_dpr_write(dpr, ch_num, ch->mode_ctrl, DCSS_DPR_MODE_CTRL0);
+ dcss_dpr_write(dpr, ch_num, ch->frame_ctrl,
+ DCSS_DPR_FRAME_CTRL0);
+ dcss_dpr_write(dpr, ch_num, ch->rtram_ctrl,
+ DCSS_DPR_RTRAM_CTRL0);
+ }
+
+ if (ch->sys_ctrl != sys_ctrl)
+ ch->sys_ctrl_chgd = true;
+
+ ch->sys_ctrl = sys_ctrl;
+}
+EXPORT_SYMBOL(dcss_dpr_enable);
+
+struct rgb_comp_sel {
+ u32 drm_format;
+ int a_sel;
+ int r_sel;
+ int g_sel;
+ int b_sel;
+};
+
+static struct rgb_comp_sel comp_sel_map[] = {
+ {DRM_FORMAT_ARGB8888, 3, 2, 1, 0},
+ {DRM_FORMAT_XRGB8888, 3, 2, 1, 0},
+ {DRM_FORMAT_ABGR8888, 3, 0, 1, 2},
+ {DRM_FORMAT_XBGR8888, 3, 0, 1, 2},
+ {DRM_FORMAT_RGBA8888, 0, 3, 2, 1},
+ {DRM_FORMAT_RGBX8888, 0, 3, 2, 1},
+ {DRM_FORMAT_BGRA8888, 0, 1, 2, 3},
+ {DRM_FORMAT_BGRX8888, 0, 1, 2, 3},
+};
+
+static int to_comp_sel(u32 pix_fmt, int *a_sel, int *r_sel, int *g_sel,
+ int *b_sel)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(comp_sel_map); i++) {
+ if (comp_sel_map[i].drm_format == pix_fmt) {
+ *a_sel = comp_sel_map[i].a_sel;
+ *r_sel = comp_sel_map[i].r_sel;
+ *g_sel = comp_sel_map[i].g_sel;
+ *b_sel = comp_sel_map[i].b_sel;
+
+ return 0;
+ }
+ }
+
+ return -1;
+}
+
+static void dcss_dpr_rtram_set(struct dcss_soc *dcss, int ch_num,
+ u32 pix_format)
+{
+ u32 val, mask;
+ struct dcss_dpr_ch *ch = &dcss->dpr_priv->ch[ch_num];
+
+ switch (pix_format) {
+ case DRM_FORMAT_NV21:
+ case DRM_FORMAT_NV12:
+ case DRM_FORMAT_P010:
+ ch->rtram_3buf_en = 1;
+ ch->rtram_4line_en = 0;
+ break;
+
+ default:
+ ch->rtram_3buf_en = 1;
+ ch->rtram_4line_en = 1;
+ break;
+ }
+
+ val = (ch->rtram_4line_en ? RTR_4LINE_BUF_EN : 0);
+ val |= (ch->rtram_3buf_en ? RTR_3BUF_EN : 0);
+ mask = RTR_4LINE_BUF_EN | RTR_3BUF_EN;
+
+ ch->mode_ctrl &= ~mask;
+ ch->mode_ctrl |= (val & mask);
+
+ /* TODO: Should the thresholds be hardcoded? */
+ val = (ch->rtram_4line_en ? 0 : NUM_ROWS_ACTIVE);
+ val |= (3 << THRES_LOW_POS) & THRES_LOW_MASK;
+ val |= (4 << THRES_HIGH_POS) & THRES_HIGH_MASK;
+ mask = THRES_LOW_MASK | THRES_HIGH_MASK | NUM_ROWS_ACTIVE;
+
+ ch->rtram_ctrl &= ~mask;
+ ch->rtram_ctrl |= (val & mask);
+}
+
+static void dcss_dpr_setup_components(struct dcss_soc *dcss, int ch_num,
+ u32 pix_format)
+{
+ enum dcss_color_space cs = dcss_drm_fourcc_to_colorspace(pix_format);
+ int a_sel, r_sel, g_sel, b_sel;
+ bool uv_swap, y_uv_swap;
+
+ switch (pix_format) {
+ case DRM_FORMAT_YVYU:
+ uv_swap = true;
+ y_uv_swap = true;
+ break;
+
+ case DRM_FORMAT_VYUY:
+ case DRM_FORMAT_NV21:
+ uv_swap = true;
+ y_uv_swap = false;
+ break;
+
+ case DRM_FORMAT_YUYV:
+ uv_swap = false;
+ y_uv_swap = true;
+ break;
+
+ default:
+ uv_swap = false;
+ y_uv_swap = false;
+ break;
+ }
+
+ dcss_dpr_uv_swap(dcss, ch_num, uv_swap);
+
+ dcss_dpr_y_uv_swap(dcss, ch_num, y_uv_swap);
+
+ if (cs == DCSS_COLORSPACE_RGB) {
+ if (!to_comp_sel(pix_format, &a_sel, &r_sel, &g_sel, &b_sel)) {
+ dcss_dpr_argb_comp_sel(dcss, ch_num, a_sel, r_sel,
+ g_sel, b_sel);
+ } else {
+ dcss_dpr_argb_comp_sel(dcss, ch_num, 3, 2, 1, 0);
+ }
+ } else {
+ dcss_dpr_argb_comp_sel(dcss, ch_num, 0, 0, 0, 0);
+ }
+}
+
+static int dcss_dpr_get_bpp(u32 pix_format)
+{
+ int bpp;
+
+ switch (pix_format) {
+ case DRM_FORMAT_NV12:
+ case DRM_FORMAT_NV21:
+ case DRM_FORMAT_P010:
+ bpp = 8;
+ break;
+
+ case DRM_FORMAT_UYVY:
+ case DRM_FORMAT_VYUY:
+ case DRM_FORMAT_YUYV:
+ case DRM_FORMAT_YVYU:
+ bpp = 16;
+ break;
+
+ default:
+ bpp = drm_format_plane_cpp(pix_format, 0) * 8;
+ break;
+ }
+
+ return bpp;
+}
+
+void dcss_dpr_tile_derive(struct dcss_soc *dcss,
+ int ch_num,
+ uint64_t modifier)
+{
+ struct dcss_dpr_ch *ch = &dcss->dpr_priv->ch[ch_num];
+
+ switch (ch_num) {
+ case 0:
+ switch (modifier) {
+ case DRM_FORMAT_MOD_LINEAR:
+ dcss_dpr_tile_set(dcss, ch_num, TILE_LINEAR);
+ ch->tile = TILE_LINEAR;
+ break;
+ case DRM_FORMAT_MOD_VIVANTE_TILED:
+ dcss_dpr_tile_set(dcss, ch_num, TILE_GPU_STANDARD);
+ ch->tile = TILE_GPU_STANDARD;
+ break;
+ case DRM_FORMAT_MOD_VIVANTE_SUPER_TILED:
+ case DRM_FORMAT_MOD_VIVANTE_SUPER_TILED_FC:
+ dcss_dpr_tile_set(dcss, ch_num, TILE_GPU_SUPER);
+ ch->tile = TILE_GPU_SUPER;
+ break;
+ default:
+ WARN_ON(1);
+ break;
+ }
+ break;
+ case 1:
+ case 2:
+ dcss_dpr_tile_set(dcss, ch_num, TILE_LINEAR);
+ ch->tile = TILE_LINEAR;
+ break;
+ default:
+ WARN_ON(1);
+ return;
+ }
+}
+EXPORT_SYMBOL(dcss_dpr_tile_set);
+
+void dcss_dpr_format_set(struct dcss_soc *dcss, int ch_num, u32 pix_format,
+ bool modifiers_present)
+{
+ struct dcss_dpr_ch *ch = &dcss->dpr_priv->ch[ch_num];
+ struct drm_format_name_buf format_name;
+ enum dcss_color_space dcss_cs;
+
+ dcss_cs = dcss_drm_fourcc_to_colorspace(pix_format);
+ ch->planes = drm_format_num_planes(pix_format);
+ ch->bpp = dcss_dpr_get_bpp(pix_format);
+ ch->pix_format = pix_format;
+ ch->use_dtrc = ch_num && modifiers_present;
+
+ dev_dbg(dcss->dev, "pix_format = %s, colorspace = %d, bpp = %d\n",
+ drm_get_format_name(pix_format, &format_name), dcss_cs, ch->bpp);
+
+ dcss_dpr_yuv_en(dcss, ch_num, dcss_cs == DCSS_COLORSPACE_YUV);
+
+ dcss_dpr_pix_size_set(dcss, ch_num, ch->bpp);
+
+ dcss_dpr_setup_components(dcss, ch_num, pix_format);
+
+ dcss_dpr_2plane_en(dcss, ch_num, ch->planes == 2 ? true : false);
+
+ dcss_dpr_rtram_set(dcss, ch_num, pix_format);
+}
+EXPORT_SYMBOL(dcss_dpr_format_set);
+
+void dcss_dpr_write_sysctrl(struct dcss_soc *dcss)
+{
+ int chnum;
+
+ for (chnum = 0; chnum < 3; chnum++) {
+ struct dcss_dpr_ch *ch = &dcss->dpr_priv->ch[chnum];
+
+ if (ch->sys_ctrl_chgd) {
+ dcss_ctxld_write_irqsafe(dcss, ch->ctx_id, ch->sys_ctrl,
+ ch->base_ofs +
+ DCSS_DPR_SYSTEM_CTRL0);
+ ch->sys_ctrl_chgd = false;
+ }
+ }
+}
+
+void dcss_dpr_irq_enable(struct dcss_soc *dcss, bool en)
+{
+ struct dcss_dpr_priv *dpr = dcss->dpr_priv;
+
+ if (!en) {
+ disable_irq_nosync(dpr->ch[0].irq);
+ disable_irq_nosync(dpr->ch[1].irq);
+ disable_irq_nosync(dpr->ch[2].irq);
+
+ return;
+ }
+
+ dcss_clr(1, dpr->ch[0].base_reg + DCSS_DPR_IRQ_NONMASK_STATUS);
+ dcss_clr(1, dpr->ch[1].base_reg + DCSS_DPR_IRQ_NONMASK_STATUS);
+ dcss_clr(1, dpr->ch[2].base_reg + DCSS_DPR_IRQ_NONMASK_STATUS);
+
+ enable_irq(dpr->ch[0].irq);
+ enable_irq(dpr->ch[1].irq);
+ enable_irq(dpr->ch[2].irq);
+}
+
+void dcss_dpr_set_rotation(struct dcss_soc *dcss, int ch_num, u32 rotation)
+{
+ struct dcss_dpr_ch *ch = &dcss->dpr_priv->ch[ch_num];
+
+ ch->frame_ctrl &= ~(HFLIP_EN | VFLIP_EN | ROT_ENC_MASK);
+
+ ch->frame_ctrl |= rotation & DRM_MODE_REFLECT_X ? HFLIP_EN : 0;
+ ch->frame_ctrl |= rotation & DRM_MODE_REFLECT_Y ? VFLIP_EN : 0;
+
+ if (rotation & DRM_MODE_ROTATE_90)
+ ch->frame_ctrl |= 1 << ROT_ENC_POS;
+ else if (rotation & DRM_MODE_ROTATE_180)
+ ch->frame_ctrl |= 2 << ROT_ENC_POS;
+ else if (rotation & DRM_MODE_ROTATE_270)
+ ch->frame_ctrl |= 3 << ROT_ENC_POS;
+}
+EXPORT_SYMBOL(dcss_dpr_set_rotation);
diff --git a/drivers/gpu/imx/dcss/dcss-dtg.c b/drivers/gpu/imx/dcss/dcss-dtg.c
new file mode 100644
index 000000000000..0bcf18f828ce
--- /dev/null
+++ b/drivers/gpu/imx/dcss/dcss-dtg.c
@@ -0,0 +1,771 @@
+/*
+ * Copyright (C) 2017-2018 NXP
+ *
+ * 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/device.h>
+#include <linux/bitops.h>
+#include <linux/io.h>
+#include <linux/clk.h>
+#include <linux/of.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <drm/drm_fourcc.h>
+
+#include <video/imx-dcss.h>
+#include "dcss-prv.h"
+
+#define USE_CTXLD
+
+#define DCSS_DTG_TC_CONTROL_STATUS 0x00
+#define CH3_EN BIT(0)
+#define CH2_EN BIT(1)
+#define CH1_EN BIT(2)
+#define OVL_DATA_MODE BIT(3)
+#define BLENDER_VIDEO_ALPHA_SEL BIT(7)
+#define DTG_START BIT(8)
+#define DBY_MODE_EN BIT(9)
+#define CH1_ALPHA_SEL BIT(10)
+#define CSS_PIX_COMP_SWAP_POS 12
+#define CSS_PIX_COMP_SWAP_MASK GENMASK(14, 12)
+#define DEFAULT_FG_ALPHA_POS 24
+#define DEFAULT_FG_ALPHA_MASK GENMASK(31, 24)
+#define DCSS_DTG_TC_DTG 0x04
+#define DCSS_DTG_TC_DISP_TOP 0x08
+#define DCSS_DTG_TC_DISP_BOT 0x0C
+#define DCSS_DTG_TC_CH1_TOP 0x10
+#define DCSS_DTG_TC_CH1_BOT 0x14
+#define DCSS_DTG_TC_CH2_TOP 0x18
+#define DCSS_DTG_TC_CH2_BOT 0x1C
+#define DCSS_DTG_TC_CH3_TOP 0x20
+#define DCSS_DTG_TC_CH3_BOT 0x24
+#define TC_X_POS 0
+#define TC_X_MASK GENMASK(12, 0)
+#define TC_Y_POS 16
+#define TC_Y_MASK GENMASK(28, 16)
+#define DCSS_DTG_TC_CTXLD 0x28
+#define TC_CTXLD_DB_Y_POS 0
+#define TC_CTXLD_DB_Y_MASK GENMASK(12, 0)
+#define TC_CTXLD_SB_Y_POS 16
+#define TC_CTXLD_SB_Y_MASK GENMASK(28, 16)
+#define DCSS_DTG_TC_CH1_BKRND 0x2C
+#define DCSS_DTG_TC_CH2_BKRND 0x30
+#define BKRND_R_Y_COMP_POS 20
+#define BKRND_R_Y_COMP_MASK GENMASK(29, 20)
+#define BKRND_G_U_COMP_POS 10
+#define BKRND_G_U_COMP_MASK GENMASK(19, 10)
+#define BKRND_B_V_COMP_POS 0
+#define BKRND_B_V_COMP_MASK GENMASK(9, 0)
+#define DCSS_DTG_BLENDER_DBY_RANGEINV 0x38
+#define DCSS_DTG_BLENDER_DBY_RANGEMIN 0x3C
+#define DCSS_DTG_BLENDER_DBY_BDP 0x40
+#define DCSS_DTG_BLENDER_BKRND_I 0x44
+#define DCSS_DTG_BLENDER_BKRND_P 0x48
+#define DCSS_DTG_BLENDER_BKRND_T 0x4C
+#define DCSS_DTG_LINE0_INT 0x50
+#define DCSS_DTG_LINE1_INT 0x54
+#define DCSS_DTG_BG_ALPHA_DEFAULT 0x58
+#define DCSS_DTG_INT_STATUS 0x5C
+#define DCSS_DTG_INT_CONTROL 0x60
+#define DCSS_DTG_TC_CH3_BKRND 0x64
+#define DCSS_DTG_INT_MASK 0x68
+#define LINE0_IRQ BIT(0)
+#define LINE1_IRQ BIT(1)
+#define LINE2_IRQ BIT(2)
+#define LINE3_IRQ BIT(3)
+#define DCSS_DTG_LINE2_INT 0x6C
+#define DCSS_DTG_LINE3_INT 0x70
+#define DCSS_DTG_DBY_OL 0x74
+#define DCSS_DTG_DBY_BL 0x78
+#define DCSS_DTG_DBY_EL 0x7C
+
+/* Maximum Video PLL frequency */
+#define MAX_PLL_FREQ 1200000000
+/* Mininum pixel clock in kHz */
+#define MIN_PIX_CLK 74250
+
+static struct dcss_debug_reg dtg_debug_reg[] = {
+ DCSS_DBG_REG(DCSS_DTG_TC_CONTROL_STATUS),
+ DCSS_DBG_REG(DCSS_DTG_TC_DTG),
+ DCSS_DBG_REG(DCSS_DTG_TC_DISP_TOP),
+ DCSS_DBG_REG(DCSS_DTG_TC_DISP_BOT),
+ DCSS_DBG_REG(DCSS_DTG_TC_CH1_TOP),
+ DCSS_DBG_REG(DCSS_DTG_TC_CH1_BOT),
+ DCSS_DBG_REG(DCSS_DTG_TC_CH2_TOP),
+ DCSS_DBG_REG(DCSS_DTG_TC_CH2_BOT),
+ DCSS_DBG_REG(DCSS_DTG_TC_CH3_TOP),
+ DCSS_DBG_REG(DCSS_DTG_TC_CH3_BOT),
+ DCSS_DBG_REG(DCSS_DTG_TC_CTXLD),
+ DCSS_DBG_REG(DCSS_DTG_TC_CH1_BKRND),
+ DCSS_DBG_REG(DCSS_DTG_TC_CH2_BKRND),
+ DCSS_DBG_REG(DCSS_DTG_BLENDER_DBY_RANGEINV),
+ DCSS_DBG_REG(DCSS_DTG_BLENDER_DBY_RANGEMIN),
+ DCSS_DBG_REG(DCSS_DTG_BLENDER_DBY_BDP),
+ DCSS_DBG_REG(DCSS_DTG_BLENDER_BKRND_I),
+ DCSS_DBG_REG(DCSS_DTG_BLENDER_BKRND_P),
+ DCSS_DBG_REG(DCSS_DTG_BLENDER_BKRND_T),
+ DCSS_DBG_REG(DCSS_DTG_LINE0_INT),
+ DCSS_DBG_REG(DCSS_DTG_LINE1_INT),
+ DCSS_DBG_REG(DCSS_DTG_BG_ALPHA_DEFAULT),
+ DCSS_DBG_REG(DCSS_DTG_INT_STATUS),
+ DCSS_DBG_REG(DCSS_DTG_INT_CONTROL),
+ DCSS_DBG_REG(DCSS_DTG_TC_CH3_BKRND),
+ DCSS_DBG_REG(DCSS_DTG_INT_MASK),
+ DCSS_DBG_REG(DCSS_DTG_LINE2_INT),
+ DCSS_DBG_REG(DCSS_DTG_LINE3_INT),
+ DCSS_DBG_REG(DCSS_DTG_DBY_OL),
+ DCSS_DBG_REG(DCSS_DTG_DBY_BL),
+ DCSS_DBG_REG(DCSS_DTG_DBY_EL),
+};
+
+struct mode_config {
+ struct clk *clk_src;
+ unsigned long out_rate;
+ int clock;
+ int mode_clock;
+ struct list_head list;
+};
+
+struct dcss_dtg_priv {
+ struct dcss_soc *dcss;
+ void __iomem *base_reg;
+ u32 base_ofs;
+
+ u32 ctx_id;
+
+ bool in_use;
+ bool hdmi_output;
+
+ u32 dis_ulc_x;
+ u32 dis_ulc_y;
+
+ u32 control_status;
+ u32 alpha;
+ u32 use_global;
+
+ int ctxld_kick_irq;
+ bool ctxld_kick_irq_en;
+ struct list_head valid_modes;
+
+ /*
+ * This will be passed on by DRM CRTC so that we can signal when DTG has
+ * been successfully stopped. Otherwise, any modesetting while DTG is
+ * still on may result in unpredictable behavior.
+ */
+ struct completion *dis_completion;
+};
+
+static void dcss_dtg_write(struct dcss_dtg_priv *dtg, u32 val, u32 ofs)
+{
+ if (!dtg->in_use)
+ dcss_writel(val, dtg->base_reg + ofs);
+#if defined(USE_CTXLD)
+ dcss_ctxld_write(dtg->dcss, dtg->ctx_id, val, dtg->base_ofs + ofs);
+#endif
+}
+
+#ifdef CONFIG_DEBUG_FS
+void dcss_dtg_dump_regs(struct seq_file *s, void *data)
+{
+ struct dcss_soc *dcss = data;
+ int j;
+
+ seq_puts(s, ">> Dumping DTG:\n");
+ for (j = 0; j < ARRAY_SIZE(dtg_debug_reg); j++)
+ seq_printf(s, "%-35s(0x%04x) -> 0x%08x\n",
+ dtg_debug_reg[j].name,
+ dtg_debug_reg[j].ofs,
+ dcss_readl(dcss->dtg_priv->base_reg +
+ dtg_debug_reg[j].ofs));
+}
+#endif
+
+static irqreturn_t dcss_dtg_irq_handler(int irq, void *data)
+{
+ struct dcss_dtg_priv *dtg = data;
+ u32 status;
+
+ status = dcss_readl(dtg->base_reg + DCSS_DTG_INT_STATUS);
+
+ if (!(status & LINE0_IRQ))
+ return IRQ_HANDLED;
+
+ dcss_ctxld_kick(dtg->dcss);
+
+ dcss_writel(status & LINE0_IRQ, dtg->base_reg + DCSS_DTG_INT_CONTROL);
+
+ return IRQ_HANDLED;
+}
+
+static int dcss_dtg_irq_config(struct dcss_dtg_priv *dtg)
+{
+ struct dcss_soc *dcss = dtg->dcss;
+ struct platform_device *pdev = to_platform_device(dcss->dev);
+ int ret;
+
+ dtg->ctxld_kick_irq = platform_get_irq_byname(pdev, "ctxld_kick");
+ if (dtg->ctxld_kick_irq < 0) {
+ dev_err(dcss->dev, "dtg: can't get line2 irq number\n");
+ return dtg->ctxld_kick_irq;
+ }
+
+ ret = devm_request_irq(dcss->dev, dtg->ctxld_kick_irq,
+ dcss_dtg_irq_handler,
+ IRQF_TRIGGER_HIGH,
+ "dcss_ctxld_kick", dtg);
+ if (ret) {
+ dev_err(dcss->dev, "dtg: irq request failed.\n");
+ return ret;
+ }
+
+ disable_irq(dtg->ctxld_kick_irq);
+
+ dtg->ctxld_kick_irq_en = false;
+
+ dcss_update(LINE0_IRQ, LINE0_IRQ, dtg->base_reg + DCSS_DTG_INT_MASK);
+
+ return 0;
+}
+
+int dcss_dtg_init(struct dcss_soc *dcss, unsigned long dtg_base)
+{
+ struct device_node *node = dcss->dev->of_node;
+ struct dcss_dtg_priv *dtg;
+ int len;
+ const char *disp_dev;
+
+ dtg = devm_kzalloc(dcss->dev, sizeof(*dtg), GFP_KERNEL);
+ if (!dtg)
+ return -ENOMEM;
+
+ dcss->dtg_priv = dtg;
+ dtg->dcss = dcss;
+
+ dtg->base_reg = devm_ioremap(dcss->dev, dtg_base, SZ_4K);
+ if (!dtg->base_reg) {
+ dev_err(dcss->dev, "dtg: unable to remap dtg base\n");
+ return -ENOMEM;
+ }
+
+ dtg->base_ofs = dtg_base;
+
+#if defined(USE_CTXLD)
+ dtg->ctx_id = CTX_DB;
+#endif
+
+ disp_dev = of_get_property(node, "disp-dev", &len);
+ if (!disp_dev || !strncmp(disp_dev, "hdmi_disp", 9))
+ dtg->hdmi_output = true;
+
+ dtg->alpha = 255;
+ dtg->use_global = 0;
+
+ dtg->control_status |= OVL_DATA_MODE | BLENDER_VIDEO_ALPHA_SEL |
+ ((dtg->alpha << DEFAULT_FG_ALPHA_POS) & DEFAULT_FG_ALPHA_MASK);
+
+ INIT_LIST_HEAD(&dtg->valid_modes);
+
+ return dcss_dtg_irq_config(dtg);
+}
+
+void dcss_dtg_exit(struct dcss_soc *dcss)
+{
+ struct dcss_dtg_priv *dtg = dcss->dtg_priv;
+ struct mode_config *config;
+ struct list_head *pos, *tmp;
+
+ /* stop DTG */
+ dcss_writel(DTG_START, dtg->base_reg + DCSS_DTG_TC_CONTROL_STATUS);
+
+ list_for_each_safe(pos, tmp, &dtg->valid_modes) {
+ config = list_entry(pos, struct mode_config, list);
+ list_del(pos);
+ devm_kfree(dcss->dev, config);
+ }
+}
+
+static struct clk *dcss_dtg_find_src_clk(struct dcss_soc *dcss, int crtc_clock,
+ unsigned long *out_rate)
+{
+ struct clk *src = NULL;
+ struct clk *p = dcss->pix_clk;
+ struct clk *src_clk[MAX_CLK_SRC];
+ int num_src_clk = ARRAY_SIZE(dcss->src_clk);
+ unsigned long src_rate;
+ int i;
+
+ for (i = 0; i < num_src_clk; i++)
+ src_clk[i] = dcss->src_clk[i];
+
+ /*
+ * First, check the current clock source and find the clock
+ * selector
+ */
+ while (p) {
+ struct clk *pp = clk_get_parent(p);
+
+ for (i = 0; i < num_src_clk; i++)
+ if (src_clk[i] && clk_is_match(pp, src_clk[i])) {
+ src = pp;
+ dcss->sel_clk = p;
+ src_clk[i] = NULL;
+ break;
+ }
+
+ if (src)
+ break;
+
+ p = pp;
+ }
+
+ while (!IS_ERR_OR_NULL(src)) {
+ /* Check if current rate satisfies our needs */
+ src_rate = clk_get_rate(src);
+ *out_rate = clk_get_rate(dcss->pll_clk);
+ if (!(*out_rate % crtc_clock))
+ break;
+
+ /* Find the highest rate that fits our needs */
+ *out_rate = crtc_clock * (MAX_PLL_FREQ / crtc_clock);
+ if (!(*out_rate % src_rate))
+ break;
+
+ /* Get the next clock source available */
+ src = NULL;
+ for (i = 0; i < num_src_clk; i++) {
+ if (IS_ERR_OR_NULL(src_clk[i]))
+ continue;
+ src = src_clk[i];
+ src_clk[i] = NULL;
+ break;
+ }
+ }
+
+ return src;
+}
+
+int dcss_dtg_mode_valid(struct dcss_soc *dcss, int clock, int crtc_clock)
+{
+ struct dcss_dtg_priv *dtg = dcss->dtg_priv;
+ struct clk *src = NULL;
+ unsigned long out_rate;
+ struct mode_config *config;
+
+ /*
+ * In order to verify possible clock sources we need to have at least
+ * two of them. Also, do not check the clock if the output is hdmi.
+ */
+ if (dtg->hdmi_output || !dcss->src_clk[0] || !dcss->src_clk[1])
+ return 0;
+
+ /*
+ * TODO: Currently, only modes with pixel clock higher or equal to
+ * 74250kHz are working. Limit to these modes until we figure out how
+ * to handle the rest of the display modes.
+ */
+ if (clock < MIN_PIX_CLK)
+ return 1;
+
+ /* Transform clocks in Hz */
+ clock *= 1000;
+ crtc_clock *= 1000;
+
+ if (!crtc_clock)
+ crtc_clock = clock;
+
+ /* Skip saving the config again */
+ list_for_each_entry(config, &dtg->valid_modes, list)
+ if (config->clock == clock)
+ return 0;
+
+ src = dcss_dtg_find_src_clk(dcss, crtc_clock, &out_rate);
+
+ if (IS_ERR_OR_NULL(src))
+ return 1;
+
+ clk_set_rate(dcss->pll_clk, out_rate);
+
+ /* Save this configuration for later use */
+ config = devm_kzalloc(dcss->dev,
+ sizeof(struct mode_config), GFP_KERNEL);
+ list_add(&config->list, &dtg->valid_modes);
+ config->clk_src = src;
+ config->out_rate = out_rate;
+ config->clock = clock;
+ config->mode_clock = crtc_clock;
+
+ return 0;
+}
+EXPORT_SYMBOL(dcss_dtg_mode_valid);
+
+int dcss_dtg_mode_fixup(struct dcss_soc *dcss, int clock)
+{
+ struct dcss_dtg_priv *dtg = dcss->dtg_priv;
+ struct mode_config *config;
+ struct clk *src;
+
+ /* Make sure that current mode can get the required clock */
+ list_for_each_entry(config, &dtg->valid_modes, list)
+ if (config->clock == clock * 1000) {
+ if (dcss->clks_on)
+ clk_disable_unprepare(dcss->pix_clk);
+ src = clk_get_parent(dcss->sel_clk);
+ if (!clk_is_match(src, config->clk_src))
+ clk_set_parent(dcss->sel_clk, config->clk_src);
+ if (clk_get_rate(dcss->pll_clk) != config->out_rate)
+ clk_set_rate(dcss->pll_clk, config->out_rate);
+ dev_dbg(dcss->dev, "pll rate: %ld (actual %ld)\n",
+ config->out_rate, clk_get_rate(dcss->pll_clk));
+ if (dcss->clks_on)
+ clk_prepare_enable(dcss->pix_clk);
+ break;
+ }
+
+ return 0;
+
+}
+EXPORT_SYMBOL(dcss_dtg_mode_fixup);
+
+static void dcss_dtg_set_clock(struct dcss_soc *dcss, unsigned long clock)
+{
+ struct dcss_dtg_priv *dtg = dcss->dtg_priv;
+ struct mode_config *config;
+
+ /*
+ * Before setting the clock rate, we need to be sure that the clock
+ * has the right source to output the required rate.
+ */
+ list_for_each_entry(config, &dtg->valid_modes, list) {
+ if (config->clock == clock) {
+ struct clk *src;
+
+ src = clk_get_parent(dcss->sel_clk);
+ if (!clk_is_match(src, config->clk_src))
+ clk_set_parent(dcss->sel_clk, config->clk_src);
+ if (clk_get_rate(dcss->pll_clk) != config->out_rate)
+ clk_set_rate(dcss->pll_clk, config->out_rate);
+ dev_dbg(dcss->dev, "pll rate: %ld (actual %ld)\n",
+ config->out_rate, clk_get_rate(dcss->pll_clk));
+ clock = config->mode_clock;
+ break;
+ }
+ }
+
+ clk_set_rate(dcss->pix_clk, clock);
+}
+
+void dcss_dtg_sync_set(struct dcss_soc *dcss, struct videomode *vm)
+{
+ struct dcss_dtg_priv *dtg = dcss->dtg_priv;
+ u16 dtg_lrc_x, dtg_lrc_y;
+ u16 dis_ulc_x, dis_ulc_y;
+ u16 dis_lrc_x, dis_lrc_y;
+ u32 sb_ctxld_trig, db_ctxld_trig;
+ u32 pixclock = vm->pixelclock;
+ u32 actual_clk;
+
+ dev_dbg(dcss->dev, "hfront_porch = %d\n", vm->hfront_porch);
+ dev_dbg(dcss->dev, "hback_porch = %d\n", vm->hback_porch);
+ dev_dbg(dcss->dev, "hsync_len = %d\n", vm->hsync_len);
+ dev_dbg(dcss->dev, "hactive = %d\n", vm->hactive);
+ dev_dbg(dcss->dev, "vfront_porch = %d\n", vm->vfront_porch);
+ dev_dbg(dcss->dev, "vback_porch = %d\n", vm->vback_porch);
+ dev_dbg(dcss->dev, "vsync_len = %d\n", vm->vsync_len);
+ dev_dbg(dcss->dev, "vactive = %d\n", vm->vactive);
+ dev_dbg(dcss->dev, "pixelclock = %lu\n", vm->pixelclock);
+
+ dtg_lrc_x = vm->hfront_porch + vm->hback_porch + vm->hsync_len +
+ vm->hactive - 1;
+ dtg_lrc_y = vm->vfront_porch + vm->vback_porch + vm->vsync_len +
+ vm->vactive - 1;
+ dis_ulc_x = vm->hsync_len + vm->hback_porch - 1;
+ dis_ulc_y = vm->vsync_len + vm->vfront_porch + vm->vback_porch - 1;
+ dis_lrc_x = vm->hsync_len + vm->hback_porch + vm->hactive - 1;
+ dis_lrc_y = vm->vsync_len + vm->vfront_porch + vm->vback_porch +
+ vm->vactive - 1;
+
+ clk_disable_unprepare(dcss->pix_clk);
+ if (dtg->hdmi_output) {
+ int err;
+ /*
+ * At this point, since pix_clk is disabled, the pll_clk
+ * should also be disabled, so re-parenting should be safe
+ */
+ err = clk_set_parent(dcss->pll_clk, dcss->src_clk[0]);
+ if (err < 0)
+ dev_warn(dcss->dev, "clk_set_parent() returned %d",
+ err);
+ clk_set_rate(dcss->pix_clk, vm->pixelclock);
+ } else {
+ dcss_dtg_set_clock(dcss, pixclock);
+ }
+ clk_prepare_enable(dcss->pix_clk);
+
+ actual_clk = clk_get_rate(dcss->pix_clk);
+ if (pixclock != actual_clk) {
+ dev_info(dcss->dev,
+ "Pixel clock set to %u kHz instead of %u kHz, "
+ "difference is %d Hz\n",
+ (actual_clk / 1000), (pixclock / 1000),
+ (int)(actual_clk - pixclock));
+ }
+
+ msleep(50);
+
+ dcss_dtg_write(dtg, ((dtg_lrc_y << TC_Y_POS) | dtg_lrc_x),
+ DCSS_DTG_TC_DTG);
+ dcss_dtg_write(dtg, ((dis_ulc_y << TC_Y_POS) | dis_ulc_x),
+ DCSS_DTG_TC_DISP_TOP);
+ dcss_dtg_write(dtg, ((dis_lrc_y << TC_Y_POS) | dis_lrc_x),
+ DCSS_DTG_TC_DISP_BOT);
+
+ dtg->dis_ulc_x = dis_ulc_x;
+ dtg->dis_ulc_y = dis_ulc_y;
+
+ sb_ctxld_trig = ((0 * dis_lrc_y / 100) << TC_CTXLD_SB_Y_POS) &
+ TC_CTXLD_SB_Y_MASK;
+ db_ctxld_trig = ((99 * dis_lrc_y / 100) << TC_CTXLD_DB_Y_POS) &
+ TC_CTXLD_DB_Y_MASK;
+
+ dcss_dtg_write(dtg, sb_ctxld_trig | db_ctxld_trig, DCSS_DTG_TC_CTXLD);
+
+ /* vblank trigger */
+ dcss_dtg_write(dtg, 0, DCSS_DTG_LINE1_INT);
+
+ /* CTXLD trigger */
+ dcss_dtg_write(dtg, ((90 * dis_lrc_y) / 100) << 16, DCSS_DTG_LINE0_INT);
+}
+EXPORT_SYMBOL(dcss_dtg_sync_set);
+
+void dcss_dtg_plane_pos_set(struct dcss_soc *dcss, int ch_num,
+ int px, int py, int pw, int ph)
+{
+ struct dcss_dtg_priv *dtg = dcss->dtg_priv;
+ u16 p_ulc_x, p_ulc_y;
+ u16 p_lrc_x, p_lrc_y;
+
+ p_ulc_x = dtg->dis_ulc_x + px;
+ p_ulc_y = dtg->dis_ulc_y + py;
+ p_lrc_x = p_ulc_x + pw;
+ p_lrc_y = p_ulc_y + ph;
+
+ if (!px && !py && !pw && !ph) {
+ dcss_dtg_write(dtg, 0, DCSS_DTG_TC_CH1_TOP + 0x8 * ch_num);
+ dcss_dtg_write(dtg, 0, DCSS_DTG_TC_CH1_BOT + 0x8 * ch_num);
+ } else {
+ dcss_dtg_write(dtg, ((p_ulc_y << TC_Y_POS) | p_ulc_x),
+ DCSS_DTG_TC_CH1_TOP + 0x8 * ch_num);
+ dcss_dtg_write(dtg, ((p_lrc_y << TC_Y_POS) | p_lrc_x),
+ DCSS_DTG_TC_CH1_BOT + 0x8 * ch_num);
+ }
+}
+EXPORT_SYMBOL(dcss_dtg_plane_pos_set);
+
+static bool dcss_dtg_global_alpha_needed(u32 pix_format)
+{
+ return pix_format == DRM_FORMAT_XRGB8888 ||
+ pix_format == DRM_FORMAT_XBGR8888 ||
+ pix_format == DRM_FORMAT_RGBX8888 ||
+ pix_format == DRM_FORMAT_BGRX8888 ||
+ pix_format == DRM_FORMAT_XRGB2101010 ||
+ pix_format == DRM_FORMAT_XBGR2101010 ||
+ pix_format == DRM_FORMAT_RGBX1010102 ||
+ pix_format == DRM_FORMAT_BGRX1010102 ||
+ pix_format == DRM_FORMAT_UYVY ||
+ pix_format == DRM_FORMAT_VYUY ||
+ pix_format == DRM_FORMAT_YUYV ||
+ pix_format == DRM_FORMAT_YVYU ||
+ pix_format == DRM_FORMAT_NV12 ||
+ pix_format == DRM_FORMAT_NV21 ||
+ pix_format == DRM_FORMAT_P010;
+}
+
+bool dcss_dtg_global_alpha_changed(struct dcss_soc *dcss, int ch_num,
+ u32 pix_format, int alpha,
+ int use_global_alpha)
+{
+ struct dcss_dtg_priv *dtg = dcss->dtg_priv;
+
+ if (ch_num)
+ return false;
+
+ return alpha != dtg->alpha || use_global_alpha != dtg->use_global;
+}
+EXPORT_SYMBOL(dcss_dtg_global_alpha_changed);
+
+void dcss_dtg_plane_alpha_set(struct dcss_soc *dcss, int ch_num,
+ u32 pix_format, int alpha, bool use_global_alpha)
+{
+ struct dcss_dtg_priv *dtg = dcss->dtg_priv;
+ u32 alpha_val;
+
+ /* we care about alpha only when channel 0 is concerned */
+ if (ch_num)
+ return;
+
+ alpha_val = (alpha << DEFAULT_FG_ALPHA_POS) & DEFAULT_FG_ALPHA_MASK;
+
+ /*
+ * Use global alpha if pixel format does not have alpha channel or the
+ * user explicitly chose to use global alpha.
+ */
+ if (dcss_dtg_global_alpha_needed(pix_format) || use_global_alpha) {
+ dtg->control_status &= ~(CH1_ALPHA_SEL | DEFAULT_FG_ALPHA_MASK);
+ dtg->control_status |= alpha_val;
+ } else {
+ dtg->control_status |= CH1_ALPHA_SEL;
+ }
+
+ dtg->alpha = alpha;
+ dtg->use_global = use_global_alpha;
+}
+EXPORT_SYMBOL(dcss_dtg_plane_alpha_set);
+
+void dcss_dtg_css_set(struct dcss_soc *dcss, u32 pix_format)
+{
+ struct dcss_dtg_priv *dtg = dcss->dtg_priv;
+
+ if (pix_format == DRM_FORMAT_P010) {
+ dtg->control_status &= ~CSS_PIX_COMP_SWAP_MASK;
+ return;
+ }
+
+ dtg->control_status |=
+ (0x5 << CSS_PIX_COMP_SWAP_POS) & CSS_PIX_COMP_SWAP_MASK;
+}
+EXPORT_SYMBOL(dcss_dtg_css_set);
+
+static void dcss_dtg_disable_callback(void *data)
+{
+ struct dcss_dtg_priv *dtg = data;
+
+ dtg->control_status &= ~DTG_START;
+
+ dcss_writel(dtg->control_status,
+ dtg->base_reg + DCSS_DTG_TC_CONTROL_STATUS);
+
+ dtg->in_use = false;
+
+ complete(dtg->dis_completion);
+}
+
+void dcss_dtg_enable(struct dcss_soc *dcss, bool en,
+ struct completion *dis_completion)
+{
+ struct dcss_dtg_priv *dtg = dcss->dtg_priv;
+
+ if (!en) {
+ dcss->dcss_disable_callback = dcss_dtg_disable_callback;
+ dtg->dis_completion = dis_completion;
+ return;
+ }
+
+ dcss->dcss_disable_callback = NULL;
+ dtg->dis_completion = NULL;
+
+ dtg->control_status |= DTG_START;
+
+ dcss_dtg_write(dtg, dtg->control_status, DCSS_DTG_TC_CONTROL_STATUS);
+
+ dtg->in_use = true;
+}
+EXPORT_SYMBOL(dcss_dtg_enable);
+
+bool dcss_dtg_is_enabled(struct dcss_soc *dcss)
+{
+ return dcss->dtg_priv->in_use;
+}
+EXPORT_SYMBOL(dcss_dtg_is_enabled);
+
+void dcss_dtg_ch_enable(struct dcss_soc *dcss, int ch_num, bool en)
+{
+ struct dcss_dtg_priv *dtg = dcss->dtg_priv;
+ u32 ch_en_map[] = {CH1_EN, CH2_EN, CH3_EN};
+ u32 control_status;
+
+ control_status = dtg->control_status & ~ch_en_map[ch_num];
+ control_status |= en ? ch_en_map[ch_num] : 0;
+
+ if (dtg->control_status != control_status)
+ dcss_dtg_write(dtg, control_status, DCSS_DTG_TC_CONTROL_STATUS);
+
+ dtg->control_status = control_status;
+}
+EXPORT_SYMBOL(dcss_dtg_ch_enable);
+
+void dcss_dtg_vblank_irq_enable(struct dcss_soc *dcss, bool en)
+{
+ struct dcss_dtg_priv *dtg = dcss->dtg_priv;
+ u32 status;
+
+ dcss_update(LINE1_IRQ, LINE1_IRQ, dtg->base_reg + DCSS_DTG_INT_MASK);
+
+ dcss_dpr_irq_enable(dcss, en);
+
+ if (en) {
+ status = dcss_readl(dtg->base_reg + DCSS_DTG_INT_STATUS);
+ dcss_writel(status & LINE1_IRQ,
+ dtg->base_reg + DCSS_DTG_INT_CONTROL);
+ }
+}
+
+void dcss_dtg_ctxld_kick_irq_enable(struct dcss_soc *dcss, bool en)
+{
+ struct dcss_dtg_priv *dtg = dcss->dtg_priv;
+ u32 status;
+
+ /* need to keep the CTXLD kick interrupt ON if DTRC is used */
+ if (!en && (dcss_dtrc_is_running(dcss, 1) ||
+ dcss_dtrc_is_running(dcss, 2)))
+ return;
+
+ if (en) {
+ status = dcss_readl(dtg->base_reg + DCSS_DTG_INT_STATUS);
+
+ if (!dtg->ctxld_kick_irq_en) {
+ dcss_writel(status & LINE0_IRQ,
+ dtg->base_reg + DCSS_DTG_INT_CONTROL);
+ enable_irq(dtg->ctxld_kick_irq);
+ dtg->ctxld_kick_irq_en = true;
+ return;
+ }
+
+ return;
+ }
+
+ if (!dtg->ctxld_kick_irq_en)
+ return;
+
+ disable_irq_nosync(dtg->ctxld_kick_irq);
+ dtg->ctxld_kick_irq_en = false;
+}
+EXPORT_SYMBOL(dcss_dtg_ctxld_kick_irq_enable);
+
+void dcss_dtg_vblank_irq_clear(struct dcss_soc *dcss)
+{
+ void __iomem *reg;
+ struct dcss_dtg_priv *dtg = dcss->dtg_priv;
+
+ reg = dtg->base_reg + DCSS_DTG_INT_CONTROL;
+
+ dcss_update(LINE1_IRQ, LINE1_IRQ, reg);
+}
+
+bool dcss_dtg_vblank_irq_valid(struct dcss_soc *dcss)
+{
+ struct dcss_dtg_priv *dtg = dcss->dtg_priv;
+
+ return !!(dcss_readl(dtg->base_reg + DCSS_DTG_INT_STATUS) & LINE1_IRQ);
+}
+EXPORT_SYMBOL(dcss_dtg_vblank_irq_valid);
+
diff --git a/drivers/gpu/imx/dcss/dcss-dtrc.c b/drivers/gpu/imx/dcss/dcss-dtrc.c
new file mode 100644
index 000000000000..6245e2bd883a
--- /dev/null
+++ b/drivers/gpu/imx/dcss/dcss-dtrc.c
@@ -0,0 +1,612 @@
+/*
+ * Copyright (C) 2017 NXP
+ *
+ * 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/device.h>
+#include <linux/bitops.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <drm/drm_fourcc.h>
+#include <linux/delay.h>
+
+#include <video/imx-dcss.h>
+#include "dcss-prv.h"
+
+#define USE_CTXLD
+
+#define DTRC_F0_OFS 0x00
+#define DTRC_F1_OFS 0x60
+
+#define DCSS_DTRC_DYDSADDR 0x00
+#define DCSS_DTRC_DCDSADDR 0x04
+#define DCSS_DTRC_DYTSADDR 0x08
+#define DCSS_DTRC_DCTSADDR 0x0C
+#define DCSS_DTRC_SIZE 0x10
+#define FRAME_WIDTH_POS 0
+#define FRAME_WIDTH_MASK GENMASK(9, 0)
+#define FRAME_HEIGHT_POS 16
+#define FRAME_HEIGHT_MASK GENMASK(25, 16)
+#define DCSS_DTRC_SYSSA 0x14
+#define DCSS_DTRC_SYSEA 0x18
+#define DCSS_DTRC_SUVSSA 0x1C
+#define DCSS_DTRC_SUVSEA 0x20
+#define DCSS_DTRC_CROPORIG 0x24
+#define DCSS_DTRC_CROPSIZE 0x28
+#define CROP_HEIGHT_POS 16
+#define CROP_HEIGHT_MASK GENMASK(28, 16)
+#define CROP_WIDTH_POS 0
+#define CROP_WIDTH_MASK GENMASK(12, 0)
+#define DCSS_DTRC_DCTL 0x2C
+#define CROPPING_EN BIT(18)
+#define COMPRESSION_DIS BIT(17)
+#define PIX_DEPTH_8BIT_EN BIT(1)
+#define CONFIG_READY BIT(0)
+#define DCSS_DTRC_DYDSADDR_EXT 0x30
+#define DCSS_DTRC_DCDSADDR_EXT 0x34
+#define DCSS_DTRC_DYTSADDR_EXT 0x38
+#define DCSS_DTRC_DCTSADDR_EXT 0x3C
+#define DCSS_DTRC_SYSSA_EXT 0x40
+#define DCSS_DTRC_SYSEA_EXT 0x44
+#define DCSS_DTRC_SUVSSA_EXT 0x48
+#define DCSS_DTRC_SUVSEA_EXT 0x4C
+
+#define DCSS_DTRC_INTEN 0xC0
+#define DCSS_DTRC_FDINTR 0xC4
+#define DCSS_DTRC_DTCTRL 0xC8
+#define CURRENT_FRAME BIT(31)
+#define ADDRESS_ID_ENABLE BIT(30)
+#define ENDIANNESS_10BIT BIT(29)
+#define MERGE_ARID_ENABLE BIT(28)
+#define NON_G1_2_SWAP_MODE_POS 24
+#define NON_G1_2_SWAP_MODE_MASK GENMASK(27, 24)
+#define TABLE_DATA_SWAP_POS 20
+#define TABLE_DATA_SWAP_MASK GENMASK(23, 20)
+#define TILED_SWAP_POS 16
+#define TILED_SWAP_MASK GENMASK(19, 16)
+#define RASTER_SWAP_POS 12
+#define RASTER_SWAP_MASK GENMASK(15, 12)
+#define BURST_LENGTH_POS 4
+#define BURST_LENGTH_MASK GENMASK(11, 4)
+#define G1_TILED_DATA_EN BIT(3)
+#define HOT_RESET BIT(2)
+#define ARIDR_MODE_DETILE 0
+#define ARIDR_MODE_BYPASS 2
+#define DCSS_DTRC_ARIDR 0xCC
+#define DCSS_DTRC_DTID2DDR 0xD0
+#define DCSS_DTRC_CONFIG 0xD4
+#define DCSS_DTRC_VER 0xD8
+#define DCSS_DTRC_PFCTRL 0xF0
+#define DCSS_DTRC_PFCR 0xF4
+#define DCSS_DTRC_TOCR 0xF8
+
+#define TRACE_IRQ (1LL << 48)
+#define TRACE_SWITCH_BANKS (2LL << 48)
+
+struct dcss_dtrc_ch {
+ void __iomem *base_reg;
+ u32 base_ofs;
+
+ u32 xres;
+ u32 yres;
+ u32 pix_format;
+ u64 format_modifier;
+ u32 y_dec_ofs;
+ u32 uv_dec_ofs;
+
+ int curr_frame;
+
+ u32 dctl;
+
+ u32 ctx_id;
+
+ bool bypass;
+ bool running;
+
+ int irq;
+ int ch_num;
+};
+
+struct dcss_dtrc_priv {
+ struct dcss_soc *dcss;
+ void __iomem *dtrc_reg;
+
+ struct dcss_dtrc_ch ch[2];
+};
+
+#ifdef CONFIG_DEBUG_FS
+static struct dcss_debug_reg dtrc_frame_debug_reg[] = {
+ DCSS_DBG_REG(DCSS_DTRC_DYDSADDR),
+ DCSS_DBG_REG(DCSS_DTRC_DCDSADDR),
+ DCSS_DBG_REG(DCSS_DTRC_DYTSADDR),
+ DCSS_DBG_REG(DCSS_DTRC_DCTSADDR),
+ DCSS_DBG_REG(DCSS_DTRC_SIZE),
+ DCSS_DBG_REG(DCSS_DTRC_SYSSA),
+ DCSS_DBG_REG(DCSS_DTRC_SYSEA),
+ DCSS_DBG_REG(DCSS_DTRC_SUVSSA),
+ DCSS_DBG_REG(DCSS_DTRC_SUVSEA),
+ DCSS_DBG_REG(DCSS_DTRC_CROPORIG),
+ DCSS_DBG_REG(DCSS_DTRC_CROPSIZE),
+ DCSS_DBG_REG(DCSS_DTRC_DCTL),
+ DCSS_DBG_REG(DCSS_DTRC_DYDSADDR_EXT),
+ DCSS_DBG_REG(DCSS_DTRC_DCDSADDR_EXT),
+ DCSS_DBG_REG(DCSS_DTRC_DYTSADDR_EXT),
+ DCSS_DBG_REG(DCSS_DTRC_DCTSADDR_EXT),
+ DCSS_DBG_REG(DCSS_DTRC_SYSSA_EXT),
+ DCSS_DBG_REG(DCSS_DTRC_SYSEA_EXT),
+ DCSS_DBG_REG(DCSS_DTRC_SUVSSA_EXT),
+ DCSS_DBG_REG(DCSS_DTRC_SUVSEA_EXT),
+};
+
+static struct dcss_debug_reg dtrc_ctrl_debug_reg[] = {
+ DCSS_DBG_REG(DCSS_DTRC_INTEN),
+ DCSS_DBG_REG(DCSS_DTRC_FDINTR),
+ DCSS_DBG_REG(DCSS_DTRC_DTCTRL),
+ DCSS_DBG_REG(DCSS_DTRC_ARIDR),
+ DCSS_DBG_REG(DCSS_DTRC_DTID2DDR),
+ DCSS_DBG_REG(DCSS_DTRC_CONFIG),
+ DCSS_DBG_REG(DCSS_DTRC_VER),
+ DCSS_DBG_REG(DCSS_DTRC_PFCTRL),
+ DCSS_DBG_REG(DCSS_DTRC_PFCR),
+ DCSS_DBG_REG(DCSS_DTRC_TOCR),
+};
+
+static void dcss_dtrc_dump_frame_regs(struct seq_file *s, void *data,
+ int ch, int frame)
+{
+ struct dcss_soc *dcss = data;
+ int i;
+
+ seq_printf(s, "\t>> Dumping F%d regs:\n", frame);
+ for (i = 0; i < ARRAY_SIZE(dtrc_frame_debug_reg); i++)
+ seq_printf(s, "\t%-35s(0x%04x) -> 0x%08x\n",
+ dtrc_frame_debug_reg[i].name,
+ dtrc_frame_debug_reg[i].ofs + frame * DTRC_F1_OFS,
+ dcss_readl(dcss->dtrc_priv->ch[ch].base_reg +
+ dtrc_frame_debug_reg[i].ofs +
+ frame * DTRC_F1_OFS));
+}
+
+void dcss_dtrc_dump_regs(struct seq_file *s, void *data)
+{
+ struct dcss_soc *dcss = data;
+ int ch, fr, i;
+
+ for (ch = 0; ch < 2; ch++) {
+ seq_printf(s, ">> Dumping DTRC for CH %d:\n", ch + 1);
+ for (fr = 0; fr < 2; fr++)
+ dcss_dtrc_dump_frame_regs(s, data, ch, fr);
+
+ seq_printf(s, "\t>> Dumping DTRC CTRL regs for CH %d:\n",
+ ch + 1);
+ for (i = 0; i < ARRAY_SIZE(dtrc_ctrl_debug_reg); i++)
+ seq_printf(s, "\t%-35s(0x%04x) -> 0x%08x\n",
+ dtrc_ctrl_debug_reg[i].name,
+ dtrc_ctrl_debug_reg[i].ofs,
+ dcss_readl(dcss->dtrc_priv->ch[ch].base_reg +
+ dtrc_ctrl_debug_reg[i].ofs));
+ }
+}
+#endif
+
+static irqreturn_t dcss_dtrc_irq_handler(int irq, void *data)
+{
+ struct dcss_dtrc_ch *ch = data;
+ u32 b0, b1, curr_bank;
+
+ b0 = dcss_readl(ch->base_reg + DCSS_DTRC_DCTL) & 0x1;
+ b1 = dcss_readl(ch->base_reg + DTRC_F1_OFS + DCSS_DTRC_DCTL) & 0x1;
+ curr_bank = dcss_readl(ch->base_reg + DCSS_DTRC_DTCTRL) >> 31;
+
+ dcss_trace_module(TRACE_DTRC, TRACE_IRQ | (ch->ch_num + 1) << 3 |
+ curr_bank << 2 | b0 << 0 | b1 << 1);
+
+ dcss_update(1, 1, ch->base_reg + DCSS_DTRC_FDINTR);
+
+ return IRQ_HANDLED;
+}
+
+static int dcss_dtrc_irq_config(struct dcss_soc *dcss, int ch_num)
+{
+ struct platform_device *pdev = to_platform_device(dcss->dev);
+ struct dcss_dtrc_priv *dtrc = dcss->dtrc_priv;
+ struct dcss_dtrc_ch *ch = &dtrc->ch[ch_num];
+ char irq_name[20];
+ int ret;
+
+ sprintf(irq_name, "dtrc_ch%d", ch_num + 1);
+ irq_name[8] = 0;
+
+ ch->irq = platform_get_irq_byname(pdev, irq_name);
+ if (ch->irq < 0) {
+ dev_err(dcss->dev, "dtrc: can't get DTRC irq\n");
+ return ch->irq;
+ }
+
+ ret = devm_request_irq(dcss->dev, ch->irq,
+ dcss_dtrc_irq_handler,
+ IRQF_TRIGGER_HIGH,
+ "dcss-dtrc", ch);
+ if (ret) {
+ dev_err(dcss->dev, "dtrc: irq request failed.\n");
+ return ret;
+ }
+
+ dcss_writel(1, ch->base_reg + DCSS_DTRC_INTEN);
+
+ return 0;
+}
+
+static int dcss_dtrc_ch_init_all(struct dcss_soc *dcss, unsigned long dtrc_base)
+{
+ struct dcss_dtrc_priv *dtrc = dcss->dtrc_priv;
+ struct dcss_dtrc_ch *ch;
+ int i;
+
+ for (i = 0; i < 2; i++) {
+ ch = &dtrc->ch[i];
+
+ ch->base_ofs = dtrc_base + i * 0x1000;
+
+ ch->base_reg = devm_ioremap(dcss->dev, ch->base_ofs, SZ_4K);
+ if (!ch->base_reg) {
+ dev_err(dcss->dev, "dtrc: unable to remap ch base\n");
+ return -ENOMEM;
+ }
+
+ ch->ch_num = i;
+
+ dcss_dtrc_irq_config(dcss, i);
+
+#if defined(USE_CTXLD)
+ ch->ctx_id = CTX_SB_HP;
+#endif
+ }
+
+ return 0;
+}
+
+static void dcss_dtrc_write(struct dcss_dtrc_priv *dtrc, int ch_num,
+ u32 val, u32 ofs)
+{
+#if !defined(USE_CTXLD)
+ dcss_writel(val, dtrc->ch[ch_num].base_reg + ofs);
+#else
+ dcss_ctxld_write(dtrc->dcss, dtrc->ch[ch_num].ctx_id,
+ val, dtrc->ch[ch_num].base_ofs + ofs);
+#endif
+}
+
+static void dcss_dtrc_write_irqsafe(struct dcss_dtrc_priv *dtrc, int ch_num,
+ u32 val, u32 ofs)
+{
+#if !defined(USE_CTXLD)
+ dcss_writel(val, dtrc->ch[ch_num].base_reg + ofs);
+#else
+ dcss_ctxld_write_irqsafe(dtrc->dcss, dtrc->ch[ch_num].ctx_id,
+ val, dtrc->ch[ch_num].base_ofs + ofs);
+#endif
+}
+
+int dcss_dtrc_init(struct dcss_soc *dcss, unsigned long dtrc_base)
+{
+ struct dcss_dtrc_priv *dtrc;
+
+ dtrc = devm_kzalloc(dcss->dev, sizeof(*dtrc), GFP_KERNEL);
+ if (!dtrc)
+ return -ENOMEM;
+
+ dcss->dtrc_priv = dtrc;
+ dtrc->dcss = dcss;
+
+ return dcss_dtrc_ch_init_all(dcss, dtrc_base);
+}
+
+void dcss_dtrc_exit(struct dcss_soc *dcss)
+{
+ struct dcss_dtrc_priv *dtrc = dcss->dtrc_priv;
+
+ /* reset the module to default */
+ dcss_writel(HOT_RESET, dtrc->dtrc_reg + DCSS_DTRC_DTCTRL);
+}
+
+void dcss_dtrc_bypass(struct dcss_soc *dcss, int ch_num)
+{
+ struct dcss_dtrc_priv *dtrc = dcss->dtrc_priv;
+
+ if (ch_num == 0)
+ return;
+
+ ch_num -= 1;
+
+ if (dtrc->ch[ch_num].bypass)
+ return;
+
+ dcss_dtrc_write(dtrc, ch_num, ARIDR_MODE_BYPASS, DCSS_DTRC_DTCTRL);
+ dcss_dtrc_write(dtrc, ch_num, 0, DCSS_DTRC_DYTSADDR);
+ dcss_dtrc_write(dtrc, ch_num, 0, DCSS_DTRC_DCTSADDR);
+ dcss_dtrc_write(dtrc, ch_num, 0x0f0e0100, DCSS_DTRC_ARIDR);
+ dcss_dtrc_write(dtrc, ch_num, 0x0f0e, DCSS_DTRC_DTID2DDR);
+
+ dtrc->ch[ch_num].bypass = true;
+}
+EXPORT_SYMBOL(dcss_dtrc_bypass);
+
+void dcss_dtrc_addr_set(struct dcss_soc *dcss, int ch_num, u32 p1_ba, u32 p2_ba,
+ uint64_t dec_table_ofs)
+{
+ struct dcss_dtrc_priv *dtrc = dcss->dtrc_priv;
+ struct dcss_dtrc_ch *ch;
+
+ if (ch_num == 0)
+ return;
+
+ ch_num -= 1;
+
+ ch = &dtrc->ch[ch_num];
+
+ dcss_dtrc_write(dtrc, ch_num, p1_ba, DCSS_DTRC_DYDSADDR);
+ dcss_dtrc_write(dtrc, ch_num, p2_ba, DCSS_DTRC_DCDSADDR);
+
+ dcss_dtrc_write(dtrc, ch_num, p1_ba, DTRC_F1_OFS + DCSS_DTRC_DYDSADDR);
+ dcss_dtrc_write(dtrc, ch_num, p2_ba, DTRC_F1_OFS + DCSS_DTRC_DCDSADDR);
+
+ if (ch->format_modifier == DRM_FORMAT_MOD_VSI_G2_TILED_COMPRESSED) {
+ ch->y_dec_ofs = dec_table_ofs & 0xFFFFFFFF;
+ ch->uv_dec_ofs = dec_table_ofs >> 32;
+
+ dcss_dtrc_write(dtrc, ch_num, p1_ba + ch->y_dec_ofs,
+ DCSS_DTRC_DYTSADDR);
+ dcss_dtrc_write(dtrc, ch_num, p1_ba + ch->uv_dec_ofs,
+ DCSS_DTRC_DCTSADDR);
+ dcss_dtrc_write(dtrc, ch_num, p1_ba + ch->y_dec_ofs,
+ DTRC_F1_OFS + DCSS_DTRC_DYTSADDR);
+ dcss_dtrc_write(dtrc, ch_num, p1_ba + ch->uv_dec_ofs,
+ DTRC_F1_OFS + DCSS_DTRC_DCTSADDR);
+ }
+
+ dtrc->ch[ch_num].bypass = false;
+}
+EXPORT_SYMBOL(dcss_dtrc_addr_set);
+
+void dcss_dtrc_set_res(struct dcss_soc *dcss, int ch_num, struct drm_rect *src,
+ struct drm_rect *old_src, u32 pixel_format)
+{
+ struct dcss_dtrc_priv *dtrc = dcss->dtrc_priv;
+ struct dcss_dtrc_ch *ch;
+ u32 frame_height, frame_width;
+ u32 crop_w, crop_h, crop_orig_w, crop_orig_h;
+ int bank;
+ u32 old_xres, old_yres, xres, yres;
+ u32 pix_depth;
+ u16 width_align = 0;
+
+ if (ch_num == 0)
+ return;
+
+ ch_num -= 1;
+
+ ch = &dtrc->ch[ch_num];
+
+ bank = dcss_readl(ch->base_reg + DCSS_DTRC_DTCTRL) >> 31;
+
+ ch->pix_format = pixel_format;
+
+ pix_depth = ch->pix_format == DRM_FORMAT_P010 ? 10 : 8;
+ old_xres = old_src->x2 - old_src->x1;
+ old_yres = old_src->y2 - old_src->y1;
+ xres = src->x2 - src->x1;
+ yres = src->y2 - src->y1;
+
+ frame_height = ((old_yres >> 3) << FRAME_HEIGHT_POS) & FRAME_HEIGHT_MASK;
+ frame_width = ((old_xres >> 3) << FRAME_WIDTH_POS) & FRAME_WIDTH_MASK;
+
+ dcss_dtrc_write(dcss->dtrc_priv, ch_num, frame_height | frame_width,
+ DTRC_F1_OFS * bank + DCSS_DTRC_SIZE);
+
+ dcss_dtrc_write(dcss->dtrc_priv, ch_num, frame_height | frame_width,
+ DTRC_F1_OFS * (bank ^ 1) + DCSS_DTRC_SIZE);
+
+ /*
+ * Image original size is aligned:
+ * - 128 pixels for width (8-bit) or 256 (10-bit);
+ * - 8 lines for height;
+ */
+ width_align = ch->pix_format == DRM_FORMAT_P010 ? 0xff : 0x7f;
+ if (xres == old_xres && !(xres & width_align) &&
+ yres == old_yres && !(yres & 0xf)) {
+ ch->dctl &= ~CROPPING_EN;
+ goto exit;
+ }
+
+ /* align the image size: down align for compressed formats */
+ if (ch->format_modifier == DRM_FORMAT_MOD_VSI_G2_TILED_COMPRESSED && src->x1)
+ xres = xres & ~width_align;
+ else
+ xres = (xres - 1 + width_align) & ~width_align;
+
+ if (ch->format_modifier == DRM_FORMAT_MOD_VSI_G2_TILED_COMPRESSED && src->y1)
+ yres = yres & ~0xf;
+ else
+ yres = (yres - 1 + 0xf) & ~0xf;
+
+ src->x1 &= ~1;
+ src->x2 &= ~1;
+
+ crop_orig_w = (src->x1 << CROP_WIDTH_POS) & CROP_WIDTH_MASK;
+ crop_orig_h = (src->y1 << CROP_HEIGHT_POS) & CROP_HEIGHT_MASK;
+
+ dcss_dtrc_write(dcss->dtrc_priv, ch_num, crop_orig_w | crop_orig_h,
+ DCSS_DTRC_CROPORIG);
+ dcss_dtrc_write(dcss->dtrc_priv, ch_num, crop_orig_w | crop_orig_h,
+ DTRC_F1_OFS + DCSS_DTRC_CROPORIG);
+
+ crop_w = (xres << CROP_WIDTH_POS) & CROP_WIDTH_MASK;
+ crop_h = (yres << CROP_HEIGHT_POS) & CROP_HEIGHT_MASK;
+
+ dcss_dtrc_write(dcss->dtrc_priv, ch_num, crop_w | crop_h,
+ DTRC_F1_OFS * bank + DCSS_DTRC_CROPSIZE);
+ dcss_dtrc_write(dcss->dtrc_priv, ch_num, crop_w | crop_h,
+ DTRC_F1_OFS * (bank ^ 1) + DCSS_DTRC_CROPSIZE);
+
+ ch->dctl |= CROPPING_EN;
+
+exit:
+ dcss_dtrc_write(dtrc, ch_num, xres * yres * pix_depth / 8,
+ DCSS_DTRC_SYSEA);
+ dcss_dtrc_write(dtrc, ch_num, xres * yres * pix_depth / 8,
+ DTRC_F1_OFS + DCSS_DTRC_SYSEA);
+
+ dcss_dtrc_write(dtrc, ch_num, 0x10000000 + xres * yres * pix_depth / 8 / 2,
+ DCSS_DTRC_SUVSEA);
+ dcss_dtrc_write(dtrc, ch_num, 0x10000000 + xres * yres * pix_depth / 8 / 2,
+ DTRC_F1_OFS + DCSS_DTRC_SUVSEA);
+
+ src->x2 = src->x1 + xres;
+ src->y2 = src->y1 + yres;
+
+ if (ch->running)
+ return;
+
+ dcss_dtrc_write(dtrc, ch_num, 0x0, DCSS_DTRC_SYSSA);
+ dcss_dtrc_write(dtrc, ch_num, 0x0,
+ DTRC_F1_OFS + DCSS_DTRC_SYSSA);
+
+ dcss_dtrc_write(dtrc, ch_num, 0x10000000, DCSS_DTRC_SUVSSA);
+ dcss_dtrc_write(dtrc, ch_num, 0x10000000,
+ DTRC_F1_OFS + DCSS_DTRC_SUVSSA);
+}
+EXPORT_SYMBOL(dcss_dtrc_set_res);
+
+void dcss_dtrc_enable(struct dcss_soc *dcss, int ch_num, bool enable)
+{
+ struct dcss_dtrc_priv *dtrc = dcss->dtrc_priv;
+ struct dcss_dtrc_ch *ch;
+ int curr_frame;
+ u32 fdctl, dtctrl;
+
+ if (ch_num == 0)
+ return;
+
+ ch_num -= 1;
+
+ ch = &dtrc->ch[ch_num];
+
+ if (ch->bypass)
+ return;
+
+ if (!enable) {
+ ch->running = false;
+ return;
+ }
+
+ if (ch->running)
+ return;
+
+ dcss_update(HOT_RESET, HOT_RESET, ch->base_reg + DCSS_DTRC_DTCTRL);
+ while (dcss_readl(ch->base_reg + DCSS_DTRC_DTCTRL) & HOT_RESET)
+ usleep_range(100, 200);
+
+ dcss_dtrc_write(dcss->dtrc_priv, ch_num, 0x0f0e0100,
+ DCSS_DTRC_ARIDR);
+ dcss_dtrc_write(dcss->dtrc_priv, ch_num, 0x0f0e,
+ DCSS_DTRC_DTID2DDR);
+
+ dtctrl = ADDRESS_ID_ENABLE | MERGE_ARID_ENABLE |
+ ((0xF << TABLE_DATA_SWAP_POS) & TABLE_DATA_SWAP_MASK) |
+ ((0x10 << BURST_LENGTH_POS) & BURST_LENGTH_MASK);
+
+ if (ch->format_modifier == DRM_FORMAT_MOD_VSI_G1_TILED)
+ dtctrl |= G1_TILED_DATA_EN;
+
+ dcss_dtrc_write(dtrc, ch_num, dtctrl, DCSS_DTRC_DTCTRL);
+
+ curr_frame = dcss_readl(ch->base_reg + DCSS_DTRC_DTCTRL) >> 31;
+
+ fdctl = ch->dctl & ~(PIX_DEPTH_8BIT_EN | COMPRESSION_DIS);
+
+ fdctl |= ch->pix_format == DRM_FORMAT_P010 ? 0 : PIX_DEPTH_8BIT_EN;
+
+ if (ch->format_modifier != DRM_FORMAT_MOD_VSI_G2_TILED_COMPRESSED)
+ fdctl |= COMPRESSION_DIS;
+
+ dcss_dtrc_write(dtrc, ch_num, fdctl,
+ (curr_frame ^ 1) * DTRC_F1_OFS + DCSS_DTRC_DCTL);
+ dcss_dtrc_write(dtrc, ch_num, fdctl | CONFIG_READY,
+ curr_frame * DTRC_F1_OFS + DCSS_DTRC_DCTL);
+
+ ch->curr_frame = curr_frame;
+ ch->dctl = fdctl;
+ ch->running = true;
+}
+EXPORT_SYMBOL(dcss_dtrc_enable);
+
+bool dcss_dtrc_is_running(struct dcss_soc *dcss, int ch_num)
+{
+ struct dcss_dtrc_priv *dtrc = dcss->dtrc_priv;
+ struct dcss_dtrc_ch *ch;
+
+ if (!ch_num)
+ return false;
+
+ ch_num -= 1;
+
+ ch = &dtrc->ch[ch_num];
+
+ return ch->running;
+}
+
+void dcss_dtrc_set_format_mod(struct dcss_soc *dcss, int ch_num, u64 modifier)
+{
+ struct dcss_dtrc_priv *dtrc = dcss->dtrc_priv;
+ struct dcss_dtrc_ch *ch;
+
+ if (!ch_num)
+ return;
+
+ ch_num -= 1;
+
+ ch = &dtrc->ch[ch_num];
+
+ ch->format_modifier = modifier;
+}
+EXPORT_SYMBOL(dcss_dtrc_set_format_mod);
+
+static void dcss_dtrc_ch_switch_banks(struct dcss_dtrc_priv *dtrc, int dtrc_ch)
+{
+ struct dcss_dtrc_ch *ch = &dtrc->ch[dtrc_ch];
+ u32 b0, b1;
+
+ if (!ch->running)
+ return;
+
+ b0 = dcss_readl(ch->base_reg + DCSS_DTRC_DCTL) & 0x1;
+ b1 = dcss_readl(ch->base_reg + DTRC_F1_OFS + DCSS_DTRC_DCTL) & 0x1;
+
+ ch->curr_frame = dcss_readl(ch->base_reg + DCSS_DTRC_DTCTRL) >> 31;
+
+ dcss_trace_module(TRACE_DTRC, TRACE_SWITCH_BANKS |
+ (dtrc_ch + 1) << 3 | ch->curr_frame << 2 |
+ b0 << 0 | b1 << 1);
+
+ dcss_dtrc_write_irqsafe(dtrc, dtrc_ch, ch->dctl | CONFIG_READY,
+ (ch->curr_frame ^ 1) * DTRC_F1_OFS + DCSS_DTRC_DCTL);
+}
+
+void dcss_dtrc_switch_banks(struct dcss_soc *dcss)
+{
+ struct dcss_dtrc_priv *dtrc = dcss->dtrc_priv;
+
+ dcss_dtrc_ch_switch_banks(dtrc, 0);
+ dcss_dtrc_ch_switch_banks(dtrc, 1);
+}
diff --git a/drivers/gpu/imx/dcss/dcss-hdr10-tables.h b/drivers/gpu/imx/dcss/dcss-hdr10-tables.h
new file mode 100644
index 000000000000..edf9fe17fe9b
--- /dev/null
+++ b/drivers/gpu/imx/dcss/dcss-hdr10-tables.h
@@ -0,0 +1,1541 @@
+/*
+ * Copyright (C) 2018 NXP
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+
+#ifndef __DCSS_HDR10_TABLES_H__
+#define __DCSS_HDR10_TABLES_H__
+
+/*
+ * Table descriptor (64 bit) contains flags with identify to which
+ * input/output configurations' combinations the table is applied. Choosing the
+ * right CSC depends on both output/input pipe configuration.
+ *
+ * Bit 0-2: Table type
+ * * LUT - bit 0
+ * * CSCA - bit 1 (CSC for output pipe)
+ * * CSCB - bit 2 (not used for output pipe)
+ * Bit 3: Pipe type
+ * * Input - unset
+ * * Output - set
+ * Bit 4-5: Input pipe bits-per-component
+ * * 8 bpc - bit 4
+ * * 10 bpc - bit 5
+ * Bit 6-7: Input pipe colorspace
+ * * RGB - bit 6
+ * * YUV - bit 7
+ * Bit 8-12: Input pipe nonlinearity
+ * * REC2084 - bit 8
+ * * REC709 - bit 9
+ * * BT1886 - bit 10
+ * * REC2100HLG - bit 11
+ * * SRGB - bit 12
+ * Bit 13-14: Input pipe pixel range
+ * * Limited - bit 13
+ * * Full - bit 14
+ * Bit 15-19: Input pipe gamut
+ * * REC2020 - bit 15
+ * * REC709 - bit 16
+ * * REC601_NTSC - bit 17
+ * * REC601_PAL - bit 18
+ * * ADOBE_RGB - bit 19
+ * Bit 20-21: Output pipe bits-per-component (see above)
+ * Bit 22-23: Output pipe colorspace (see above)
+ * Bit 24-28: Output pipe nonlinearity (see above)
+ * Bit 29-30: Ouptut pipe pixel range (see above)
+ * Bit 31-35: Output pipe gamut (see above)
+ */
+
+static u32 dcss_hdr10_tables[] = {
+ /* table descriptor */
+ 0xe1ffffe9, 0xf,
+ /* table length */
+ 0x400,
+ /* table data */
+ 0x2c59, 0x2416, 0x3322, 0x1dd0, 0x287e, 0x2ff0, 0x3679, 0x188b, 0x2131,
+ 0x2661, 0x2a78, 0x2e2b, 0x3186, 0x34c8, 0x3836, 0x141d, 0x1b81, 0x1fa3,
+ 0x22a3, 0x2531, 0x277a, 0x2988, 0x2b6b, 0x2d33, 0x2eed, 0x30a3, 0x325a,
+ 0x3416, 0x35b5, 0x374e, 0x38f8, 0xff8, 0x1698, 0x1a32, 0x1ca3, 0x1eab,
+ 0x206e, 0x2210, 0x2355, 0x2497, 0x25e9, 0x26e2, 0x2816, 0x28f9, 0x2a17,
+ 0x2ae8, 0x2c01, 0x2cbe, 0x2dbb, 0x2e85, 0x2f65, 0x3047, 0x310d, 0x3209,
+ 0x32b7, 0x339e, 0x3469, 0x3536, 0x3624, 0x36db, 0x37d2, 0x388f, 0x3971,
+ 0xbe0, 0x124a, 0x1572, 0x17b5, 0x1962, 0x1acc, 0x1c29, 0x1d30, 0x1e43,
+ 0x1f20, 0x201b, 0x20ca, 0x21a2, 0x2256, 0x22f8, 0x23bc, 0x2454, 0x24e1,
+ 0x2589, 0x2629, 0x269f, 0x272b, 0x27d0, 0x2848, 0x28b9, 0x293d, 0x29d8,
+ 0x2a45, 0x2aae, 0x2b27, 0x2bb4, 0x2c2b, 0x2c89, 0x2cf6, 0x2d74, 0x2e03,
+ 0x2e57, 0x2eb8, 0x2f27, 0x2fa8, 0x301e, 0x3073, 0x30d6, 0x3147, 0x31ca,
+ 0x3230, 0x3287, 0x32eb, 0x335e, 0x33e3, 0x343e, 0x3497, 0x34fd, 0x3573,
+ 0x35fc, 0x364d, 0x36a8, 0x3712, 0x378d, 0x380e, 0x3861, 0x38c1, 0x3932,
+ 0x39b5, 0x700, 0xe30, 0x1120, 0x132c, 0x14bb, 0x1621, 0x171f, 0x182e,
+ 0x18f2, 0x19de, 0x1a7c, 0x1b23, 0x1be6, 0x1c64, 0x1ce7, 0x1d7d, 0x1e14,
+ 0x1e75, 0x1ee3, 0x1f60, 0x1feb, 0x2043, 0x209b, 0x20fc, 0x2168, 0x21e0,
+ 0x2232, 0x227b, 0x22cc, 0x2325, 0x2387, 0x23f3, 0x2434, 0x2475, 0x24bb,
+ 0x2508, 0x255d, 0x25b8, 0x260e, 0x2644, 0x2680, 0x26c0, 0x2706, 0x2752,
+ 0x27a4, 0x27fd, 0x282f, 0x2863, 0x289b, 0x28d8, 0x291a, 0x2962, 0x29af,
+ 0x2a01, 0x2a2e, 0x2a5e, 0x2a92, 0x2aca, 0x2b07, 0x2b48, 0x2b8f, 0x2bda,
+ 0x2c16, 0x2c41, 0x2c70, 0x2ca3, 0x2cda, 0x2d14, 0x2d53, 0x2d97, 0x2de0,
+ 0x2e17, 0x2e41, 0x2e6e, 0x2e9e, 0x2ed2, 0x2f0a, 0x2f46, 0x2f86, 0x2fcb,
+ 0x300a, 0x3032, 0x305d, 0x308b, 0x30bc, 0x30f1, 0x3129, 0x3166, 0x31a8,
+ 0x31ee, 0x321c, 0x3245, 0x3270, 0x329f, 0x32d1, 0x3306, 0x3340, 0x337e,
+ 0x33c0, 0x3404, 0x342a, 0x3453, 0x347f, 0x34af, 0x34e2, 0x3519, 0x3554,
+ 0x3593, 0x35d8, 0x3610, 0x3638, 0x3662, 0x3690, 0x36c1, 0x36f6, 0x372f,
+ 0x376d, 0x37af, 0x37f7, 0x3821, 0x384b, 0x3878, 0x38a8, 0x38dc, 0x3914,
+ 0x3951, 0x3992, 0x39d9, 0x200, 0xa20, 0xd00, 0xf00, 0x1084, 0x11d0,
+ 0x12b6, 0x13ae, 0x1469, 0x1513, 0x15d7, 0x165b, 0x16da, 0x1768, 0x1803,
+ 0x185b, 0x18bd, 0x1929, 0x199f, 0x1a10, 0x1a56, 0x1aa3, 0x1af6, 0x1b51,
+ 0x1bb2, 0x1c0e, 0x1c46, 0x1c83, 0x1cc5, 0x1d0b, 0x1d56, 0x1da6, 0x1dfc,
+ 0x1e2b, 0x1e5c, 0x1e90, 0x1ec7, 0x1f01, 0x1f3f, 0x1f81, 0x1fc7, 0x2008,
+ 0x202f, 0x2058, 0x2084, 0x20b2, 0x20e3, 0x2116, 0x214c, 0x2185, 0x21c1,
+ 0x2200, 0x2221, 0x2244, 0x2268, 0x228f, 0x22b7, 0x22e2, 0x230e, 0x233d,
+ 0x236e, 0x23a1, 0x23d7, 0x2407, 0x2425, 0x2444, 0x2464, 0x2486, 0x24a9,
+ 0x24ce, 0x24f4, 0x251d, 0x2547, 0x2573, 0x25a1, 0x25d1, 0x2601, 0x261b,
+ 0x2636, 0x2653, 0x2670, 0x268f, 0x26af, 0x26d1, 0x26f4, 0x2718, 0x273e,
+ 0x2766, 0x278f, 0x27b9, 0x27e6, 0x280a, 0x2822, 0x283b, 0x2855, 0x2870,
+ 0x288d, 0x28aa, 0x28c9, 0x28e8, 0x2909, 0x292c, 0x294f, 0x2975, 0x299b,
+ 0x29c3, 0x29ed, 0x2a0c, 0x2a22, 0x2a39, 0x2a52, 0x2a6b, 0x2a85, 0x2aa0,
+ 0x2abc, 0x2ad9, 0x2af7, 0x2b17, 0x2b38, 0x2b59, 0x2b7d, 0x2ba1, 0x2bc7,
+ 0x2bee, 0x2c0b, 0x2c20, 0x2c36, 0x2c4d, 0x2c64, 0x2c7d, 0x2c96, 0x2cb0,
+ 0x2ccc, 0x2ce8, 0x2d05, 0x2d24, 0x2d43, 0x2d64, 0x2d85, 0x2da9, 0x2dcd,
+ 0x2df3, 0x2e0d, 0x2e21, 0x2e36, 0x2e4c, 0x2e62, 0x2e79, 0x2e92, 0x2eab,
+ 0x2ec5, 0x2ee0, 0x2efb, 0x2f18, 0x2f36, 0x2f55, 0x2f76, 0x2f97, 0x2fb9,
+ 0x2fdd, 0x3001, 0x3014, 0x3028, 0x303d, 0x3052, 0x3068, 0x307f, 0x3097,
+ 0x30af, 0x30c9, 0x30e3, 0x30ff, 0x311b, 0x3138, 0x3157, 0x3176, 0x3197,
+ 0x31b9, 0x31dc, 0x3200, 0x3213, 0x3226, 0x323a, 0x324f, 0x3265, 0x327b,
+ 0x3293, 0x32ab, 0x32c4, 0x32de, 0x32f8, 0x3314, 0x3331, 0x334f, 0x336e,
+ 0x338e, 0x33af, 0x33d2, 0x33f5, 0x340d, 0x3420, 0x3434, 0x3448, 0x345e,
+ 0x3474, 0x348b, 0x34a3, 0x34bb, 0x34d5, 0x34ef, 0x350b, 0x3527, 0x3545,
+ 0x3563, 0x3583, 0x35a4, 0x35c6, 0x35ea, 0x3607, 0x361a, 0x362e, 0x3642,
+ 0x3657, 0x366d, 0x3684, 0x369c, 0x36b5, 0x36ce, 0x36e9, 0x3704, 0x3721,
+ 0x373e, 0x375d, 0x377d, 0x379e, 0x37c1, 0x37e4, 0x3804, 0x3818, 0x382c,
+ 0x3840, 0x3856, 0x386c, 0x3883, 0x389b, 0x38b5, 0x38cf, 0x38ea, 0x3906,
+ 0x3923, 0x3941, 0x3961, 0x3981, 0x39a3, 0x39c7, 0x39ec, 0x0, 0x500,
+ 0x8c0, 0xae0, 0xc70, 0xdb0, 0xe98, 0xf78, 0x103c, 0x10d0, 0x1178,
+ 0x1218, 0x127e, 0x12f0, 0x136c, 0x13f2, 0x1442, 0x1491, 0x14e6, 0x1542,
+ 0x15a4, 0x1606, 0x163e, 0x1679, 0x16b9, 0x16fc, 0x1743, 0x178e, 0x17dd,
+ 0x1818, 0x1844, 0x1873, 0x18a4, 0x18d7, 0x190d, 0x1945, 0x1980, 0x19be,
+ 0x19ff, 0x1a21, 0x1a44, 0x1a69, 0x1a8f, 0x1ab7, 0x1ae1, 0x1b0c, 0x1b39,
+ 0x1b68, 0x1b99, 0x1bcc, 0x1c00, 0x1c1b, 0x1c38, 0x1c55, 0x1c74, 0x1c93,
+ 0x1cb4, 0x1cd6, 0x1cf9, 0x1d1d, 0x1d42, 0x1d69, 0x1d91, 0x1dbb, 0x1de6,
+ 0x1e09, 0x1e20, 0x1e37, 0x1e4f, 0x1e69, 0x1e82, 0x1e9d, 0x1eb9, 0x1ed5,
+ 0x1ef2, 0x1f10, 0x1f2f, 0x1f4f, 0x1f70, 0x1f92, 0x1fb5, 0x1fd9, 0x1ffe,
+ 0x2012, 0x2025, 0x2039, 0x204e, 0x2063, 0x2079, 0x208f, 0x20a6, 0x20be,
+ 0x20d6, 0x20ef, 0x2109, 0x2123, 0x213e, 0x215a, 0x2176, 0x2194, 0x21b2,
+ 0x21d0, 0x21f0, 0x2208, 0x2218, 0x2229, 0x223b, 0x224d, 0x225f, 0x2272,
+ 0x2285, 0x2299, 0x22ad, 0x22c2, 0x22d7, 0x22ed, 0x2303, 0x231a, 0x2331,
+ 0x2349, 0x2361, 0x237a, 0x2394, 0x23ae, 0x23c9, 0x23e5, 0x2400, 0x240f,
+ 0x241d, 0x242c, 0x243c, 0x244c, 0x245c, 0x246c, 0x247d, 0x248e, 0x24a0,
+ 0x24b2, 0x24c4, 0x24d7, 0x24eb, 0x24fe, 0x2512, 0x2527, 0x253c, 0x2552,
+ 0x2568, 0x257e, 0x2595, 0x25ac, 0x25c4, 0x25dd, 0x25f6, 0x2607, 0x2614,
+ 0x2622, 0x262f, 0x263d, 0x264c, 0x265a, 0x2669, 0x2678, 0x2687, 0x2697,
+ 0x26a7, 0x26b8, 0x26c8, 0x26d9, 0x26eb, 0x26fd, 0x270f, 0x2722, 0x2734,
+ 0x2748, 0x275c, 0x2770, 0x2784, 0x2799, 0x27af, 0x27c4, 0x27db, 0x27f1,
+ 0x2804, 0x2810, 0x281c, 0x2828, 0x2835, 0x2842, 0x284f, 0x285c, 0x286a,
+ 0x2877, 0x2886, 0x2894, 0x28a3, 0x28b2, 0x28c1, 0x28d0, 0x28e0, 0x28f1,
+ 0x2901, 0x2912, 0x2923, 0x2935, 0x2946, 0x2959, 0x296b, 0x297e, 0x2991,
+ 0x29a5, 0x29b9, 0x29cd, 0x29e2, 0x29f7, 0x2a06, 0x2a11, 0x2a1c, 0x2a28,
+ 0x2a33, 0x2a3f, 0x2a4b, 0x2a58, 0x2a64, 0x2a71, 0x2a7e, 0x2a8b, 0x2a99,
+ 0x2aa7, 0x2ab5, 0x2ac3, 0x2ad2, 0x2ae1, 0x2af0, 0x2aff, 0x2b0f, 0x2b1f,
+ 0x2b2f, 0x2b40, 0x2b51, 0x2b62, 0x2b74, 0x2b86, 0x2b98, 0x2baa, 0x2bbd,
+ 0x2bd0, 0x2be4, 0x2bf8, 0x2c06, 0x2c10, 0x2c1b, 0x2c26, 0x2c31, 0x2c3c,
+ 0x2c47, 0x2c53, 0x2c5e, 0x2c6a, 0x2c77, 0x2c83, 0x2c90, 0x2c9d, 0x2caa,
+ 0x2cb7, 0x2cc5, 0x2cd3, 0x2ce1, 0x2cef, 0x2cfe, 0x2d0d, 0x2d1c, 0x2d2b,
+ 0x2d3b, 0x2d4b, 0x2d5b, 0x2d6c, 0x2d7d, 0x2d8e, 0x2da0, 0x2db2, 0x2dc4,
+ 0x2dd6, 0x2de9, 0x2dfc, 0x2e08, 0x2e12, 0x2e1c, 0x2e26, 0x2e30, 0x2e3b,
+ 0x2e46, 0x2e51, 0x2e5c, 0x2e68, 0x2e73, 0x2e7f, 0x2e8b, 0x2e98, 0x2ea4,
+ 0x2eb1, 0x2ebe, 0x2ecb, 0x2ed9, 0x2ee6, 0x2ef4, 0x2f03, 0x2f11, 0x2f20,
+ 0x2f2f, 0x2f3e, 0x2f4e, 0x2f5d, 0x2f6d, 0x2f7e, 0x2f8e, 0x2f9f, 0x2fb1,
+ 0x2fc2, 0x2fd4, 0x2fe6, 0x2ff9, 0x3006, 0x300f, 0x3019, 0x3023, 0x302d,
+ 0x3037, 0x3042, 0x304d, 0x3057, 0x3062, 0x306e, 0x3079, 0x3085, 0x3091,
+ 0x309d, 0x30a9, 0x30b6, 0x30c2, 0x30cf, 0x30dd, 0x30ea, 0x30f8, 0x3106,
+ 0x3114, 0x3122, 0x3131, 0x3140, 0x314f, 0x315e, 0x316e, 0x317e, 0x318f,
+ 0x319f, 0x31b0, 0x31c1, 0x31d3, 0x31e5, 0x31f7, 0x3204, 0x320e, 0x3217,
+ 0x3221, 0x322b, 0x3235, 0x323f, 0x324a, 0x3255, 0x325f, 0x326a, 0x3276,
+ 0x3281, 0x328d, 0x3299, 0x32a5, 0x32b1, 0x32bd, 0x32ca, 0x32d7, 0x32e4,
+ 0x32f2, 0x32ff, 0x330d, 0x331b, 0x332a, 0x3338, 0x3347, 0x3357, 0x3366,
+ 0x3376, 0x3386, 0x3396, 0x33a7, 0x33b8, 0x33c9, 0x33da, 0x33ec, 0x33fe,
+ 0x3408, 0x3412, 0x341b, 0x3425, 0x342f, 0x3439, 0x3443, 0x344e, 0x3458,
+ 0x3463, 0x346e, 0x347a, 0x3485, 0x3491, 0x349d, 0x34a9, 0x34b5, 0x34c2,
+ 0x34ce, 0x34db, 0x34e9, 0x34f6, 0x3504, 0x3512, 0x3520, 0x352f, 0x353d,
+ 0x354c, 0x355c, 0x356b, 0x357b, 0x358b, 0x359c, 0x35ad, 0x35be, 0x35cf,
+ 0x35e1, 0x35f3, 0x3602, 0x360c, 0x3615, 0x361f, 0x3629, 0x3633, 0x363d,
+ 0x3647, 0x3652, 0x365d, 0x3668, 0x3673, 0x367f, 0x368a, 0x3696, 0x36a2,
+ 0x36ae, 0x36bb, 0x36c8, 0x36d5, 0x36e2, 0x36f0, 0x36fd, 0x370b, 0x371a,
+ 0x3728, 0x3737, 0x3746, 0x3755, 0x3765, 0x3775, 0x3785, 0x3796, 0x37a7,
+ 0x37b8, 0x37c9, 0x37db, 0x37ed, 0x3800, 0x3809, 0x3813, 0x381d, 0x3826,
+ 0x3831, 0x383b, 0x3846, 0x3850, 0x385b, 0x3866, 0x3872, 0x387d, 0x3889,
+ 0x3895, 0x38a2, 0x38ae, 0x38bb, 0x38c8, 0x38d5, 0x38e3, 0x38f1, 0x38ff,
+ 0x390d, 0x391b, 0x392a, 0x3939, 0x3949, 0x3959, 0x3969, 0x3979, 0x398a,
+ 0x399b, 0x39ac, 0x39be, 0x39d0, 0x39e2, 0x39f5, 0xc,
+ /* table descriptor */
+ 0xe2ffffe9, 0xf,
+ /* table length */
+ 0x400,
+ /* table data */
+ 0x3612, 0x327c, 0x3840, 0x2fb2, 0x3475, 0x3728, 0x390e, 0x2d7f, 0x3134,
+ 0x3397, 0x353d, 0x3695, 0x37cb, 0x38a2, 0x3982, 0x2b71, 0x2ea4, 0x3079,
+ 0x3204, 0x3302, 0x341c, 0x34d5, 0x35ad, 0x3651, 0x36dc, 0x3778, 0x3811,
+ 0x3870, 0x38d7, 0x3946, 0x39bf, 0x2955, 0x2c9c, 0x2e31, 0x2f25, 0x3026,
+ 0x30d3, 0x319b, 0x323e, 0x32bd, 0x334b, 0x33e6, 0x3448, 0x34a4, 0x3508,
+ 0x3574, 0x35e7, 0x3631, 0x3672, 0x36b8, 0x3702, 0x374f, 0x37a1, 0x37f7,
+ 0x3828, 0x3857, 0x3889, 0x38bc, 0x38f2, 0x392a, 0x3964, 0x39a0, 0x39de,
+ 0x271c, 0x2a8e, 0x2c2a, 0x2d0e, 0x2df1, 0x2e69, 0x2ee3, 0x2f6a, 0x2ffe,
+ 0x304f, 0x30a5, 0x3102, 0x3166, 0x31d1, 0x3221, 0x325d, 0x329c, 0x32df,
+ 0x3326, 0x3370, 0x33be, 0x3407, 0x3432, 0x345e, 0x348c, 0x34bd, 0x34ef,
+ 0x3522, 0x3558, 0x3590, 0x35ca, 0x3602, 0x3621, 0x3641, 0x3662, 0x3683,
+ 0x36a6, 0x36ca, 0x36ef, 0x3715, 0x373b, 0x3763, 0x378c, 0x37b6, 0x37e1,
+ 0x3806, 0x381d, 0x3834, 0x384b, 0x3864, 0x387c, 0x3895, 0x38af, 0x38c9,
+ 0x38e4, 0x3900, 0x391c, 0x3938, 0x3955, 0x3973, 0x3991, 0x39af, 0x39cf,
+ 0x39ee, 0x24aa, 0x2871, 0x2a1c, 0x2aff, 0x2be3, 0x2c63, 0x2cd5, 0x2d47,
+ 0x2db8, 0x2e15, 0x2e4c, 0x2e86, 0x2ec4, 0x2f04, 0x2f47, 0x2f8e, 0x2fd8,
+ 0x3012, 0x303a, 0x3064, 0x308f, 0x30bc, 0x30eb, 0x311b, 0x314d, 0x3180,
+ 0x31b5, 0x31ec, 0x3212, 0x322f, 0x324d, 0x326c, 0x328c, 0x32ad, 0x32ce,
+ 0x32f1, 0x3314, 0x3338, 0x335d, 0x3383, 0x33aa, 0x33d2, 0x33fb, 0x3412,
+ 0x3427, 0x343d, 0x3453, 0x346a, 0x3481, 0x3498, 0x34b0, 0x34c9, 0x34e2,
+ 0x34fb, 0x3515, 0x3530, 0x354b, 0x3566, 0x3582, 0x359e, 0x35bb, 0x35d8,
+ 0x35f6, 0x360a, 0x3619, 0x3629, 0x3639, 0x3649, 0x3659, 0x366a, 0x367b,
+ 0x368c, 0x369d, 0x36af, 0x36c1, 0x36d3, 0x36e6, 0x36f8, 0x370b, 0x371e,
+ 0x3732, 0x3745, 0x3759, 0x376d, 0x3782, 0x3797, 0x37ac, 0x37c1, 0x37d6,
+ 0x37ec, 0x3801, 0x380c, 0x3817, 0x3823, 0x382e, 0x383a, 0x3846, 0x3851,
+ 0x385e, 0x386a, 0x3876, 0x3883, 0x388f, 0x389c, 0x38a9, 0x38b6, 0x38c3,
+ 0x38d0, 0x38de, 0x38eb, 0x38f9, 0x3907, 0x3915, 0x3923, 0x3931, 0x393f,
+ 0x394e, 0x395c, 0x396b, 0x397a, 0x3989, 0x3998, 0x39a8, 0x39b7, 0x39c7,
+ 0x39d6, 0x39e6, 0x39f6, 0x218e, 0x2638, 0x27ff, 0x28e3, 0x29c7, 0x2a55,
+ 0x2ac7, 0x2b38, 0x2baa, 0x2c0e, 0x2c47, 0x2c7f, 0x2cb8, 0x2cf1, 0x2d2a,
+ 0x2d63, 0x2d9c, 0x2dd5, 0x2e07, 0x2e23, 0x2e3f, 0x2e5a, 0x2e77, 0x2e95,
+ 0x2eb4, 0x2ed3, 0x2ef4, 0x2f14, 0x2f36, 0x2f59, 0x2f7c, 0x2fa0, 0x2fc5,
+ 0x2feb, 0x3008, 0x301c, 0x3030, 0x3044, 0x3059, 0x306e, 0x3084, 0x309a,
+ 0x30b1, 0x30c7, 0x30df, 0x30f6, 0x310f, 0x3127, 0x3140, 0x3159, 0x3173,
+ 0x318d, 0x31a8, 0x31c3, 0x31de, 0x31fa, 0x320b, 0x3219, 0x3228, 0x3237,
+ 0x3246, 0x3255, 0x3265, 0x3274, 0x3284, 0x3294, 0x32a5, 0x32b5, 0x32c6,
+ 0x32d7, 0x32e8, 0x32f9, 0x330b, 0x331d, 0x332f, 0x3341, 0x3354, 0x3367,
+ 0x337a, 0x338d, 0x33a0, 0x33b4, 0x33c8, 0x33dc, 0x33f0, 0x3402, 0x340d,
+ 0x3417, 0x3422, 0x342c, 0x3437, 0x3442, 0x344d, 0x3459, 0x3464, 0x346f,
+ 0x347b, 0x3487, 0x3492, 0x349e, 0x34aa, 0x34b6, 0x34c3, 0x34cf, 0x34dc,
+ 0x34e8, 0x34f5, 0x3502, 0x350f, 0x351c, 0x3529, 0x3536, 0x3544, 0x3551,
+ 0x355f, 0x356d, 0x357b, 0x3589, 0x3597, 0x35a5, 0x35b4, 0x35c2, 0x35d1,
+ 0x35e0, 0x35ef, 0x35fe, 0x3606, 0x360e, 0x3616, 0x361d, 0x3625, 0x362d,
+ 0x3635, 0x363d, 0x3645, 0x364d, 0x3655, 0x365e, 0x3666, 0x366e, 0x3677,
+ 0x367f, 0x3688, 0x3690, 0x3699, 0x36a2, 0x36ab, 0x36b4, 0x36bc, 0x36c5,
+ 0x36cf, 0x36d8, 0x36e1, 0x36ea, 0x36f3, 0x36fd, 0x3706, 0x3710, 0x3719,
+ 0x3723, 0x372d, 0x3737, 0x3740, 0x374a, 0x3754, 0x375e, 0x3768, 0x3772,
+ 0x377d, 0x3787, 0x3791, 0x379c, 0x37a6, 0x37b1, 0x37bb, 0x37c6, 0x37d1,
+ 0x37dc, 0x37e7, 0x37f1, 0x37fc, 0x3804, 0x3809, 0x380f, 0x3814, 0x381a,
+ 0x3820, 0x3825, 0x382b, 0x3831, 0x3837, 0x383d, 0x3843, 0x3848, 0x384e,
+ 0x3854, 0x385a, 0x3861, 0x3867, 0x386d, 0x3873, 0x3879, 0x387f, 0x3886,
+ 0x388c, 0x3892, 0x3899, 0x389f, 0x38a5, 0x38ac, 0x38b2, 0x38b9, 0x38c0,
+ 0x38c6, 0x38cd, 0x38d3, 0x38da, 0x38e1, 0x38e8, 0x38ee, 0x38f5, 0x38fc,
+ 0x3903, 0x390a, 0x3911, 0x3918, 0x391f, 0x3926, 0x392d, 0x3934, 0x393c,
+ 0x3943, 0x394a, 0x3951, 0x3959, 0x3960, 0x3967, 0x396f, 0x3976, 0x397e,
+ 0x3985, 0x398d, 0x3995, 0x399c, 0x39a4, 0x39ac, 0x39b3, 0x39bb, 0x39c3,
+ 0x39cb, 0x39d3, 0x39da, 0x39e2, 0x39ea, 0x39f2, 0x39fa, 0x0, 0x238e,
+ 0x258e, 0x26aa, 0x278e, 0x2838, 0x28aa, 0x291c, 0x298e, 0x29ff, 0x2a38,
+ 0x2a71, 0x2aaa, 0x2ae3, 0x2b1c, 0x2b55, 0x2b8e, 0x2bc7, 0x2bff, 0x2c1c,
+ 0x2c38, 0x2c55, 0x2c71, 0x2c8e, 0x2caa, 0x2cc7, 0x2ce3, 0x2cff, 0x2d1c,
+ 0x2d38, 0x2d55, 0x2d71, 0x2d8e, 0x2daa, 0x2dc7, 0x2de3, 0x2dff, 0x2e0e,
+ 0x2e1c, 0x2e2a, 0x2e38, 0x2e47, 0x2e53, 0x2e61, 0x2e70, 0x2e7f, 0x2e8e,
+ 0x2e9d, 0x2eac, 0x2ebc, 0x2ecb, 0x2edb, 0x2eeb, 0x2efc, 0x2f0c, 0x2f1d,
+ 0x2f2e, 0x2f3f, 0x2f50, 0x2f61, 0x2f73, 0x2f85, 0x2f97, 0x2fa9, 0x2fbc,
+ 0x2fce, 0x2fe1, 0x2ff4, 0x3003, 0x300d, 0x3017, 0x3021, 0x302b, 0x3035,
+ 0x303f, 0x304a, 0x3054, 0x305f, 0x3069, 0x3074, 0x307f, 0x308a, 0x3095,
+ 0x30a0, 0x30ab, 0x30b6, 0x30c2, 0x30cd, 0x30d9, 0x30e5, 0x30f1, 0x30fc,
+ 0x3109, 0x3115, 0x3121, 0x312d, 0x313a, 0x3146, 0x3153, 0x3160, 0x316d,
+ 0x317a, 0x3187, 0x3194, 0x31a1, 0x31af, 0x31bc, 0x31ca, 0x31d8, 0x31e5,
+ 0x31f3, 0x3200, 0x3208, 0x320f, 0x3216, 0x321d, 0x3224, 0x322c, 0x3233,
+ 0x323b, 0x3242, 0x324a, 0x3251, 0x3259, 0x3261, 0x3268, 0x3270, 0x3278,
+ 0x3280, 0x3288, 0x3290, 0x3298, 0x32a0, 0x32a9, 0x32b1, 0x32b9, 0x32c2,
+ 0x32ca, 0x32d3, 0x32db, 0x32e4, 0x32ec, 0x32f5, 0x32fe, 0x3307, 0x3310,
+ 0x3318, 0x3321, 0x332a, 0x3334, 0x333d, 0x3346, 0x334f, 0x3359, 0x3362,
+ 0x336b, 0x3375, 0x337e, 0x3388, 0x3392, 0x339b, 0x33a5, 0x33af, 0x33b9,
+ 0x33c3, 0x33cd, 0x33d7, 0x33e1, 0x33eb, 0x33f5, 0x3400, 0x3405, 0x340a,
+ 0x340f, 0x3414, 0x341a, 0x341f, 0x3424, 0x342a, 0x342f, 0x3435, 0x343a,
+ 0x3440, 0x3445, 0x344b, 0x3450, 0x3456, 0x345b, 0x3461, 0x3467, 0x346d,
+ 0x3472, 0x3478, 0x347e, 0x3484, 0x348a, 0x348f, 0x3495, 0x349b, 0x34a1,
+ 0x34a7, 0x34ad, 0x34b3, 0x34ba, 0x34c0, 0x34c6, 0x34cc, 0x34d2, 0x34d8,
+ 0x34df, 0x34e5, 0x34eb, 0x34f2, 0x34f8, 0x34ff, 0x3505, 0x350c, 0x3512,
+ 0x3519, 0x351f, 0x3526, 0x352c, 0x3533, 0x353a, 0x3540, 0x3547, 0x354e,
+ 0x3555, 0x355c, 0x3563, 0x3569, 0x3570, 0x3577, 0x357e, 0x3585, 0x358c,
+ 0x3594, 0x359b, 0x35a2, 0x35a9, 0x35b0, 0x35b7, 0x35bf, 0x35c6, 0x35cd,
+ 0x35d5, 0x35dc, 0x35e4, 0x35eb, 0x35f2, 0x35fa, 0x3600, 0x3604, 0x3608,
+ 0x360c, 0x3610, 0x3614, 0x3617, 0x361b, 0x361f, 0x3623, 0x3627, 0x362b,
+ 0x362f, 0x3633, 0x3637, 0x363b, 0x363f, 0x3643, 0x3647, 0x364b, 0x364f,
+ 0x3653, 0x3657, 0x365b, 0x3660, 0x3664, 0x3668, 0x366c, 0x3670, 0x3675,
+ 0x3679, 0x367d, 0x3681, 0x3686, 0x368a, 0x368e, 0x3693, 0x3697, 0x369b,
+ 0x36a0, 0x36a4, 0x36a8, 0x36ad, 0x36b1, 0x36b6, 0x36ba, 0x36bf, 0x36c3,
+ 0x36c8, 0x36cc, 0x36d1, 0x36d5, 0x36da, 0x36df, 0x36e3, 0x36e8, 0x36ec,
+ 0x36f1, 0x36f6, 0x36fb, 0x36ff, 0x3704, 0x3709, 0x370d, 0x3712, 0x3717,
+ 0x371c, 0x3721, 0x3725, 0x372a, 0x372f, 0x3734, 0x3739, 0x373e, 0x3743,
+ 0x3748, 0x374d, 0x3752, 0x3757, 0x375c, 0x3761, 0x3766, 0x376b, 0x3770,
+ 0x3775, 0x377a, 0x377f, 0x3784, 0x378a, 0x378f, 0x3794, 0x3799, 0x379e,
+ 0x37a4, 0x37a9, 0x37ae, 0x37b3, 0x37b9, 0x37be, 0x37c3, 0x37c9, 0x37ce,
+ 0x37d4, 0x37d9, 0x37de, 0x37e4, 0x37e9, 0x37ef, 0x37f4, 0x37fa, 0x37ff,
+ 0x3802, 0x3805, 0x3808, 0x380a, 0x380d, 0x3810, 0x3813, 0x3816, 0x3819,
+ 0x381b, 0x381e, 0x3821, 0x3824, 0x3827, 0x382a, 0x382d, 0x3830, 0x3832,
+ 0x3835, 0x3838, 0x383b, 0x383e, 0x3841, 0x3844, 0x3847, 0x384a, 0x384d,
+ 0x3850, 0x3853, 0x3856, 0x3859, 0x385c, 0x385f, 0x3862, 0x3865, 0x3868,
+ 0x386b, 0x386e, 0x3871, 0x3874, 0x3878, 0x387b, 0x387e, 0x3881, 0x3884,
+ 0x3887, 0x388a, 0x388e, 0x3891, 0x3894, 0x3897, 0x389a, 0x389d, 0x38a1,
+ 0x38a4, 0x38a7, 0x38aa, 0x38ae, 0x38b1, 0x38b4, 0x38b7, 0x38bb, 0x38be,
+ 0x38c1, 0x38c4, 0x38c8, 0x38cb, 0x38ce, 0x38d2, 0x38d5, 0x38d8, 0x38dc,
+ 0x38df, 0x38e3, 0x38e6, 0x38e9, 0x38ed, 0x38f0, 0x38f4, 0x38f7, 0x38fa,
+ 0x38fe, 0x3901, 0x3905, 0x3908, 0x390c, 0x390f, 0x3913, 0x3916, 0x391a,
+ 0x391d, 0x3921, 0x3924, 0x3928, 0x392b, 0x392f, 0x3933, 0x3936, 0x393a,
+ 0x393d, 0x3941, 0x3945, 0x3948, 0x394c, 0x3950, 0x3953, 0x3957, 0x395b,
+ 0x395e, 0x3962, 0x3966, 0x3969, 0x396d, 0x3971, 0x3974, 0x3978, 0x397c,
+ 0x3980, 0x3983, 0x3987, 0x398b, 0x398f, 0x3993, 0x3996, 0x399a, 0x399e,
+ 0x39a2, 0x39a6, 0x39aa, 0x39ad, 0x39b1, 0x39b5, 0x39b9, 0x39bd, 0x39c1,
+ 0x39c5, 0x39c9, 0x39cd, 0x39d1, 0x39d5, 0x39d8, 0x39dc, 0x39e0, 0x39e4,
+ 0x39e8, 0x39ec, 0x39f0, 0x39f4, 0x39f8, 0x39fc, 0xc,
+ /* table descriptor */
+ 0xe4ffffe9, 0xf,
+ /* table length */
+ 0x400,
+ /* table data */
+ 0x3505, 0x3047, 0x3800, 0x2b6c, 0x3306, 0x3695, 0x38e6, 0x268b, 0x2e47,
+ 0x31e6, 0x3431, 0x3601, 0x373f, 0x386d, 0x396c, 0x21b6, 0x2968, 0x2cef,
+ 0x2f4d, 0x3106, 0x3274, 0x33aa, 0x3496, 0x357e, 0x3648, 0x36e7, 0x379d,
+ 0x3835, 0x38a8, 0x3927, 0x39b3, 0x1c99, 0x2484, 0x2830, 0x2a7a, 0x2c46,
+ 0x2db1, 0x2ec3, 0x2fe6, 0x30a3, 0x3172, 0x3231, 0x32ba, 0x3356, 0x3402,
+ 0x3462, 0x34cc, 0x3540, 0x35bf, 0x3624, 0x366e, 0x36bd, 0x3712, 0x376d,
+ 0x37ce, 0x381a, 0x3850, 0x388a, 0x38c6, 0x3906, 0x3949, 0x398f, 0x39d9,
+ 0x1756, 0x1fa0, 0x2338, 0x25ac, 0x2763, 0x28c2, 0x2a11, 0x2aed, 0x2bf6,
+ 0x2c97, 0x2d4d, 0x2e0e, 0x2e83, 0x2f06, 0x2f98, 0x301c, 0x3074, 0x30d4,
+ 0x313b, 0x31ab, 0x3211, 0x3252, 0x3296, 0x32e0, 0x332d, 0x337f, 0x33d6,
+ 0x3419, 0x3449, 0x347c, 0x34b1, 0x34e8, 0x3522, 0x355f, 0x359e, 0x35e0,
+ 0x3612, 0x3636, 0x365b, 0x3681, 0x36a9, 0x36d2, 0x36fd, 0x3729, 0x3756,
+ 0x3785, 0x37b5, 0x37e7, 0x380d, 0x3827, 0x3842, 0x385e, 0x387b, 0x3899,
+ 0x38b7, 0x38d6, 0x38f6, 0x3916, 0x3938, 0x395a, 0x397d, 0x39a1, 0x39c6,
+ 0x39eb, 0x117c, 0x1a78, 0x1e4a, 0x20aa, 0x227b, 0x2408, 0x2510, 0x262c,
+ 0x26f3, 0x27dd, 0x2877, 0x2913, 0x29c3, 0x2a44, 0x2ab2, 0x2b2b, 0x2baf,
+ 0x2c1f, 0x2c6e, 0x2cc2, 0x2d1d, 0x2d7e, 0x2de6, 0x2e2a, 0x2e64, 0x2ea3,
+ 0x2ee4, 0x2f29, 0x2f72, 0x2fbf, 0x3007, 0x3031, 0x305d, 0x308b, 0x30bb,
+ 0x30ed, 0x3121, 0x3156, 0x318e, 0x31c8, 0x3202, 0x3221, 0x3241, 0x3263,
+ 0x3285, 0x32a8, 0x32cd, 0x32f3, 0x3319, 0x3341, 0x336a, 0x3395, 0x33c0,
+ 0x33ed, 0x340d, 0x3425, 0x343d, 0x3455, 0x346f, 0x3489, 0x34a3, 0x34be,
+ 0x34da, 0x34f7, 0x3514, 0x3531, 0x3550, 0x356f, 0x358e, 0x35af, 0x35d0,
+ 0x35f1, 0x3609, 0x361b, 0x362d, 0x363f, 0x3651, 0x3664, 0x3677, 0x368b,
+ 0x369f, 0x36b3, 0x36c8, 0x36dd, 0x36f2, 0x3707, 0x371d, 0x3734, 0x374a,
+ 0x3762, 0x3779, 0x3791, 0x37a9, 0x37c1, 0x37da, 0x37f4, 0x3806, 0x3813,
+ 0x3821, 0x382e, 0x383c, 0x3849, 0x3857, 0x3866, 0x3874, 0x3882, 0x3891,
+ 0x38a0, 0x38af, 0x38bf, 0x38ce, 0x38de, 0x38ee, 0x38fe, 0x390e, 0x391f,
+ 0x392f, 0x3940, 0x3951, 0x3963, 0x3974, 0x3986, 0x3998, 0x39aa, 0x39bd,
+ 0x39cf, 0x39e2, 0x39f5, 0x9c0, 0x14fa, 0x190d, 0x1bb0, 0x1d82, 0x1eea,
+ 0x2037, 0x2129, 0x2227, 0x22d6, 0x23a1, 0x2445, 0x24c8, 0x255c, 0x2600,
+ 0x265a, 0x26be, 0x272a, 0x279f, 0x280f, 0x2853, 0x289c, 0x28ea, 0x293d,
+ 0x2995, 0x29f3, 0x2a2a, 0x2a5f, 0x2a95, 0x2acf, 0x2b0b, 0x2b4b, 0x2b8d,
+ 0x2bd2, 0x2c0d, 0x2c32, 0x2c5a, 0x2c82, 0x2cac, 0x2cd8, 0x2d05, 0x2d34,
+ 0x2d65, 0x2d97, 0x2dcb, 0x2e00, 0x2e1c, 0x2e38, 0x2e55, 0x2e74, 0x2e93,
+ 0x2eb3, 0x2ed3, 0x2ef5, 0x2f18, 0x2f3b, 0x2f60, 0x2f85, 0x2fab, 0x2fd2,
+ 0x2ffa, 0x3012, 0x3027, 0x303c, 0x3052, 0x3068, 0x307f, 0x3097, 0x30af,
+ 0x30c7, 0x30e0, 0x30f9, 0x3113, 0x312e, 0x3149, 0x3164, 0x3180, 0x319d,
+ 0x31ba, 0x31d7, 0x31f5, 0x320a, 0x3219, 0x3229, 0x3239, 0x3249, 0x325a,
+ 0x326b, 0x327c, 0x328e, 0x329f, 0x32b1, 0x32c4, 0x32d6, 0x32e9, 0x32fc,
+ 0x3310, 0x3323, 0x3337, 0x334c, 0x3360, 0x3375, 0x338a, 0x339f, 0x33b5,
+ 0x33cb, 0x33e2, 0x33f8, 0x3407, 0x3413, 0x341f, 0x342b, 0x3437, 0x3443,
+ 0x344f, 0x345c, 0x3468, 0x3475, 0x3482, 0x348f, 0x349c, 0x34aa, 0x34b7,
+ 0x34c5, 0x34d3, 0x34e1, 0x34ef, 0x34fe, 0x350c, 0x351b, 0x352a, 0x3539,
+ 0x3548, 0x3557, 0x3567, 0x3576, 0x3586, 0x3596, 0x35a6, 0x35b7, 0x35c7,
+ 0x35d8, 0x35e9, 0x35fa, 0x3605, 0x360e, 0x3617, 0x361f, 0x3628, 0x3631,
+ 0x363a, 0x3643, 0x364d, 0x3656, 0x365f, 0x3669, 0x3673, 0x367c, 0x3686,
+ 0x3690, 0x369a, 0x36a4, 0x36ae, 0x36b8, 0x36c2, 0x36cd, 0x36d7, 0x36e2,
+ 0x36ec, 0x36f7, 0x3702, 0x370d, 0x3718, 0x3723, 0x372e, 0x3739, 0x3745,
+ 0x3750, 0x375c, 0x3767, 0x3773, 0x377f, 0x378b, 0x3797, 0x37a3, 0x37af,
+ 0x37bb, 0x37c8, 0x37d4, 0x37e1, 0x37ed, 0x37fa, 0x3803, 0x380a, 0x3810,
+ 0x3817, 0x381d, 0x3824, 0x382b, 0x3831, 0x3838, 0x383f, 0x3846, 0x384d,
+ 0x3854, 0x385b, 0x3862, 0x3869, 0x3870, 0x3877, 0x387f, 0x3886, 0x388d,
+ 0x3895, 0x389c, 0x38a4, 0x38ab, 0x38b3, 0x38bb, 0x38c2, 0x38ca, 0x38d2,
+ 0x38da, 0x38e2, 0x38ea, 0x38f2, 0x38fa, 0x3902, 0x390a, 0x3912, 0x391b,
+ 0x3923, 0x392b, 0x3934, 0x393c, 0x3945, 0x394d, 0x3956, 0x395e, 0x3967,
+ 0x3970, 0x3979, 0x3982, 0x398b, 0x3994, 0x399d, 0x39a6, 0x39af, 0x39b8,
+ 0x39c1, 0x39ca, 0x39d4, 0x39dd, 0x39e7, 0x39f0, 0x39fa, 0x0, 0xea0,
+ 0x137c, 0x164e, 0x184c, 0x19ee, 0x1b0b, 0x1c34, 0x1d09, 0x1e03, 0x1e97,
+ 0x1f42, 0x2002, 0x206e, 0x20e8, 0x216e, 0x2200, 0x2250, 0x22a8, 0x2306,
+ 0x236b, 0x23d8, 0x2426, 0x2464, 0x24a6, 0x24ec, 0x2536, 0x2583, 0x25d6,
+ 0x2616, 0x2643, 0x2672, 0x26a4, 0x26d8, 0x270e, 0x2746, 0x2781, 0x27be,
+ 0x27fd, 0x281f, 0x2841, 0x2865, 0x2889, 0x28af, 0x28d6, 0x28fe, 0x2928,
+ 0x2952, 0x297f, 0x29ac, 0x29db, 0x2a05, 0x2a1e, 0x2a37, 0x2a51, 0x2a6c,
+ 0x2a87, 0x2aa4, 0x2ac0, 0x2ade, 0x2afc, 0x2b1b, 0x2b3b, 0x2b5b, 0x2b7c,
+ 0x2b9e, 0x2bc1, 0x2be4, 0x2c04, 0x2c16, 0x2c29, 0x2c3c, 0x2c50, 0x2c64,
+ 0x2c78, 0x2c8d, 0x2ca2, 0x2cb7, 0x2ccd, 0x2ce3, 0x2cfa, 0x2d11, 0x2d29,
+ 0x2d40, 0x2d59, 0x2d71, 0x2d8b, 0x2da4, 0x2dbe, 0x2dd8, 0x2df3, 0x2e07,
+ 0x2e15, 0x2e23, 0x2e31, 0x2e3f, 0x2e4e, 0x2e5d, 0x2e6c, 0x2e7b, 0x2e8b,
+ 0x2e9b, 0x2eab, 0x2ebb, 0x2ecb, 0x2edc, 0x2eed, 0x2efe, 0x2f0f, 0x2f20,
+ 0x2f32, 0x2f44, 0x2f56, 0x2f69, 0x2f7c, 0x2f8e, 0x2fa2, 0x2fb5, 0x2fc8,
+ 0x2fdc, 0x2ff0, 0x3002, 0x300c, 0x3017, 0x3021, 0x302c, 0x3037, 0x3041,
+ 0x304c, 0x3058, 0x3063, 0x306e, 0x307a, 0x3085, 0x3091, 0x309d, 0x30a9,
+ 0x30b5, 0x30c1, 0x30cd, 0x30da, 0x30e6, 0x30f3, 0x3100, 0x310d, 0x311a,
+ 0x3127, 0x3134, 0x3142, 0x3150, 0x315d, 0x316b, 0x3179, 0x3187, 0x3195,
+ 0x31a4, 0x31b2, 0x31c1, 0x31d0, 0x31df, 0x31ee, 0x31fd, 0x3206, 0x320e,
+ 0x3215, 0x321d, 0x3225, 0x322d, 0x3235, 0x323d, 0x3245, 0x324e, 0x3256,
+ 0x325e, 0x3267, 0x326f, 0x3278, 0x3281, 0x3289, 0x3292, 0x329b, 0x32a4,
+ 0x32ad, 0x32b6, 0x32bf, 0x32c8, 0x32d2, 0x32db, 0x32e4, 0x32ee, 0x32f7,
+ 0x3301, 0x330b, 0x3314, 0x331e, 0x3328, 0x3332, 0x333c, 0x3346, 0x3351,
+ 0x335b, 0x3365, 0x3370, 0x337a, 0x3385, 0x338f, 0x339a, 0x33a5, 0x33b0,
+ 0x33bb, 0x33c6, 0x33d1, 0x33dc, 0x33e7, 0x33f2, 0x33fe, 0x3404, 0x340a,
+ 0x3410, 0x3416, 0x341c, 0x3422, 0x3428, 0x342e, 0x3434, 0x343a, 0x3440,
+ 0x3446, 0x344c, 0x3452, 0x3458, 0x345f, 0x3465, 0x346b, 0x3472, 0x3478,
+ 0x347f, 0x3485, 0x348c, 0x3492, 0x3499, 0x34a0, 0x34a6, 0x34ad, 0x34b4,
+ 0x34bb, 0x34c2, 0x34c9, 0x34d0, 0x34d7, 0x34de, 0x34e5, 0x34ec, 0x34f3,
+ 0x34fa, 0x3501, 0x3509, 0x3510, 0x3517, 0x351f, 0x3526, 0x352e, 0x3535,
+ 0x353d, 0x3544, 0x354c, 0x3553, 0x355b, 0x3563, 0x356b, 0x3573, 0x357a,
+ 0x3582, 0x358a, 0x3592, 0x359a, 0x35a2, 0x35aa, 0x35b3, 0x35bb, 0x35c3,
+ 0x35cb, 0x35d4, 0x35dc, 0x35e4, 0x35ed, 0x35f5, 0x35fe, 0x3603, 0x3607,
+ 0x360c, 0x3610, 0x3614, 0x3619, 0x361d, 0x3622, 0x3626, 0x362a, 0x362f,
+ 0x3634, 0x3638, 0x363d, 0x3641, 0x3646, 0x364a, 0x364f, 0x3654, 0x3658,
+ 0x365d, 0x3662, 0x3667, 0x366b, 0x3670, 0x3675, 0x367a, 0x367f, 0x3684,
+ 0x3688, 0x368d, 0x3692, 0x3697, 0x369c, 0x36a1, 0x36a6, 0x36ab, 0x36b0,
+ 0x36b6, 0x36bb, 0x36c0, 0x36c5, 0x36ca, 0x36cf, 0x36d5, 0x36da, 0x36df,
+ 0x36e4, 0x36ea, 0x36ef, 0x36f4, 0x36fa, 0x36ff, 0x3705, 0x370a, 0x3710,
+ 0x3715, 0x371b, 0x3720, 0x3726, 0x372b, 0x3731, 0x3737, 0x373c, 0x3742,
+ 0x3748, 0x374d, 0x3753, 0x3759, 0x375f, 0x3764, 0x376a, 0x3770, 0x3776,
+ 0x377c, 0x3782, 0x3788, 0x378e, 0x3794, 0x379a, 0x37a0, 0x37a6, 0x37ac,
+ 0x37b2, 0x37b8, 0x37be, 0x37c5, 0x37cb, 0x37d1, 0x37d7, 0x37de, 0x37e4,
+ 0x37ea, 0x37f1, 0x37f7, 0x37fd, 0x3802, 0x3805, 0x3808, 0x380b, 0x380f,
+ 0x3812, 0x3815, 0x3818, 0x381c, 0x381f, 0x3822, 0x3826, 0x3829, 0x382c,
+ 0x3830, 0x3833, 0x3837, 0x383a, 0x383d, 0x3841, 0x3844, 0x3848, 0x384b,
+ 0x384f, 0x3852, 0x3856, 0x3859, 0x385d, 0x3860, 0x3864, 0x3867, 0x386b,
+ 0x386e, 0x3872, 0x3876, 0x3879, 0x387d, 0x3881, 0x3884, 0x3888, 0x388c,
+ 0x388f, 0x3893, 0x3897, 0x389a, 0x389e, 0x38a2, 0x38a6, 0x38aa, 0x38ad,
+ 0x38b1, 0x38b5, 0x38b9, 0x38bd, 0x38c0, 0x38c4, 0x38c8, 0x38cc, 0x38d0,
+ 0x38d4, 0x38d8, 0x38dc, 0x38e0, 0x38e4, 0x38e8, 0x38ec, 0x38f0, 0x38f4,
+ 0x38f8, 0x38fc, 0x3900, 0x3904, 0x3908, 0x390c, 0x3910, 0x3914, 0x3918,
+ 0x391d, 0x3921, 0x3925, 0x3929, 0x392d, 0x3932, 0x3936, 0x393a, 0x393e,
+ 0x3942, 0x3947, 0x394b, 0x394f, 0x3954, 0x3958, 0x395c, 0x3961, 0x3965,
+ 0x3969, 0x396e, 0x3972, 0x3977, 0x397b, 0x397f, 0x3984, 0x3988, 0x398d,
+ 0x3991, 0x3996, 0x399a, 0x399f, 0x39a3, 0x39a8, 0x39ad, 0x39b1, 0x39b6,
+ 0x39ba, 0x39bf, 0x39c4, 0x39c8, 0x39cd, 0x39d1, 0x39d6, 0x39db, 0x39e0,
+ 0x39e4, 0x39e9, 0x39ee, 0x39f3, 0x39f7, 0x39fc, 0xc,
+ /* table descriptor */
+ 0xe8ffffe9, 0xf,
+ /* table length */
+ 0x400,
+ /* table data */
+ 0x32a8, 0x2ea6, 0x361d, 0x2aa0, 0x30fc, 0x344a, 0x3808, 0x2696, 0x2cf8,
+ 0x3012, 0x3208, 0x3374, 0x3517, 0x36eb, 0x38d8, 0x2281, 0x28f0, 0x2c0f,
+ 0x2e06, 0x2f5a, 0x3082, 0x3181, 0x3256, 0x3305, 0x33f8, 0x34a8, 0x359c,
+ 0x367b, 0x3771, 0x3867, 0x395e, 0x1e58, 0x24e1, 0x2808, 0x2a01, 0x2b54,
+ 0x2c7e, 0x2d7d, 0x2e53, 0x2efd, 0x2fbd, 0x3049, 0x30be, 0x313d, 0x31c8,
+ 0x322e, 0x327e, 0x32d5, 0x333a, 0x33b3, 0x3421, 0x3477, 0x34dd, 0x3557,
+ 0x35e8, 0x364a, 0x36b1, 0x372b, 0x37bd, 0x3835, 0x389d, 0x3918, 0x39ab,
+ 0x1a0b, 0x20c2, 0x23f6, 0x25f1, 0x2748, 0x2877, 0x2974, 0x2a4e, 0x2af8,
+ 0x2bb6, 0x2c45, 0x2cba, 0x2d39, 0x2dc3, 0x2e2c, 0x2e7c, 0x2ed1, 0x2f2b,
+ 0x2f8b, 0x2ff0, 0x302d, 0x3065, 0x309f, 0x30dd, 0x311d, 0x315f, 0x31a4,
+ 0x31ec, 0x321b, 0x3242, 0x326a, 0x3293, 0x32be, 0x32ec, 0x331f, 0x3356,
+ 0x3393, 0x33d5, 0x340e, 0x3435, 0x3460, 0x348f, 0x34c2, 0x34fa, 0x3536,
+ 0x3579, 0x35c1, 0x3608, 0x3633, 0x3662, 0x3695, 0x36cd, 0x370b, 0x374d,
+ 0x3796, 0x37e6, 0x381e, 0x384d, 0x3881, 0x38ba, 0x38f7, 0x393a, 0x3984,
+ 0x39d4, 0x1500, 0x1c85, 0x1fc3, 0x21cc, 0x2331, 0x2468, 0x2563, 0x2644,
+ 0x26ec, 0x27aa, 0x283e, 0x28b2, 0x2931, 0x29bb, 0x2a27, 0x2a76, 0x2acb,
+ 0x2b25, 0x2b85, 0x2bea, 0x2c2a, 0x2c61, 0x2c9c, 0x2cd9, 0x2d18, 0x2d5b,
+ 0x2da0, 0x2de8, 0x2e19, 0x2e3f, 0x2e67, 0x2e90, 0x2ebb, 0x2ee7, 0x2f14,
+ 0x2f43, 0x2f72, 0x2fa4, 0x2fd6, 0x3005, 0x301f, 0x303b, 0x3057, 0x3073,
+ 0x3091, 0x30ae, 0x30cd, 0x30ec, 0x310c, 0x312d, 0x314e, 0x3170, 0x3193,
+ 0x31b6, 0x31da, 0x31ff, 0x3212, 0x3225, 0x3238, 0x324c, 0x3260, 0x3274,
+ 0x3289, 0x329e, 0x32b3, 0x32c9, 0x32e0, 0x32f9, 0x3312, 0x332c, 0x3348,
+ 0x3365, 0x3383, 0x33a3, 0x33c4, 0x33e6, 0x3405, 0x3418, 0x342b, 0x3440,
+ 0x3455, 0x346b, 0x3483, 0x349b, 0x34b5, 0x34cf, 0x34eb, 0x3508, 0x3527,
+ 0x3546, 0x3568, 0x358a, 0x35ae, 0x35d4, 0x35fc, 0x3612, 0x3628, 0x363e,
+ 0x3656, 0x366e, 0x3688, 0x36a3, 0x36bf, 0x36dc, 0x36fb, 0x371b, 0x373c,
+ 0x375f, 0x3783, 0x37aa, 0x37d1, 0x37fb, 0x3813, 0x382a, 0x3841, 0x385a,
+ 0x3874, 0x388f, 0x38ab, 0x38c8, 0x38e7, 0x3907, 0x3929, 0x394c, 0x3971,
+ 0x3997, 0x39bf, 0x39e9, 0xea8, 0x1815, 0x1b60, 0x1d86, 0x1f03, 0x204c,
+ 0x2142, 0x2231, 0x22d6, 0x2391, 0x2430, 0x24a3, 0x2521, 0x25a9, 0x261e,
+ 0x266c, 0x26c0, 0x271a, 0x2779, 0x27dd, 0x2823, 0x285a, 0x2894, 0x28d1,
+ 0x2910, 0x2952, 0x2997, 0x29df, 0x2a14, 0x2a3a, 0x2a62, 0x2a8b, 0x2ab6,
+ 0x2ae1, 0x2b0e, 0x2b3d, 0x2b6c, 0x2b9d, 0x2bd0, 0x2c02, 0x2c1c, 0x2c37,
+ 0x2c53, 0x2c70, 0x2c8d, 0x2cab, 0x2cc9, 0x2ce8, 0x2d08, 0x2d29, 0x2d4a,
+ 0x2d6c, 0x2d8e, 0x2db2, 0x2dd5, 0x2dfa, 0x2e0f, 0x2e22, 0x2e36, 0x2e49,
+ 0x2e5d, 0x2e71, 0x2e86, 0x2e9b, 0x2eb0, 0x2ec6, 0x2edc, 0x2ef2, 0x2f09,
+ 0x2f20, 0x2f37, 0x2f4e, 0x2f66, 0x2f7f, 0x2f97, 0x2fb0, 0x2fc9, 0x2fe3,
+ 0x2ffd, 0x300b, 0x3019, 0x3026, 0x3034, 0x3042, 0x3050, 0x305e, 0x306c,
+ 0x307b, 0x3089, 0x3098, 0x30a7, 0x30b6, 0x30c5, 0x30d5, 0x30e4, 0x30f4,
+ 0x3104, 0x3114, 0x3125, 0x3135, 0x3146, 0x3157, 0x3168, 0x3179, 0x318a,
+ 0x319c, 0x31ad, 0x31bf, 0x31d1, 0x31e3, 0x31f5, 0x3204, 0x320d, 0x3216,
+ 0x3220, 0x3229, 0x3233, 0x323d, 0x3247, 0x3251, 0x325b, 0x3265, 0x326f,
+ 0x3279, 0x3283, 0x328e, 0x3298, 0x32a3, 0x32ae, 0x32b8, 0x32c4, 0x32cf,
+ 0x32da, 0x32e6, 0x32f2, 0x32ff, 0x330c, 0x3318, 0x3326, 0x3333, 0x3341,
+ 0x334f, 0x335e, 0x336c, 0x337c, 0x338b, 0x339b, 0x33ab, 0x33bb, 0x33cc,
+ 0x33dd, 0x33ef, 0x3400, 0x3409, 0x3413, 0x341c, 0x3426, 0x3430, 0x343a,
+ 0x3445, 0x3450, 0x345b, 0x3466, 0x3471, 0x347d, 0x3489, 0x3495, 0x34a2,
+ 0x34ae, 0x34bb, 0x34c9, 0x34d6, 0x34e4, 0x34f2, 0x3501, 0x3510, 0x351f,
+ 0x352f, 0x353e, 0x354f, 0x355f, 0x3570, 0x3581, 0x3593, 0x35a5, 0x35b8,
+ 0x35cb, 0x35de, 0x35f2, 0x3603, 0x360d, 0x3618, 0x3622, 0x362d, 0x3639,
+ 0x3644, 0x3650, 0x365c, 0x3668, 0x3675, 0x3682, 0x368f, 0x369c, 0x36aa,
+ 0x36b8, 0x36c6, 0x36d5, 0x36e4, 0x36f3, 0x3703, 0x3713, 0x3723, 0x3734,
+ 0x3745, 0x3756, 0x3768, 0x377a, 0x378d, 0x37a0, 0x37b3, 0x37c7, 0x37dc,
+ 0x37f0, 0x3802, 0x380d, 0x3818, 0x3824, 0x382f, 0x383b, 0x3847, 0x3854,
+ 0x3860, 0x386d, 0x387a, 0x3888, 0x3896, 0x38a4, 0x38b2, 0x38c1, 0x38d0,
+ 0x38df, 0x38ef, 0x38ff, 0x3910, 0x3920, 0x3932, 0x3943, 0x3955, 0x3967,
+ 0x397a, 0x398d, 0x39a1, 0x39b5, 0x39c9, 0x39de, 0x39f4, 0x0, 0x12aa,
+ 0x16ab, 0x1900, 0x1aab, 0x1c15, 0x1d00, 0x1e0b, 0x1eab, 0x1f60, 0x2015,
+ 0x2085, 0x2100, 0x2186, 0x220b, 0x2258, 0x22ab, 0x2303, 0x2360, 0x23c3,
+ 0x2415, 0x244c, 0x2485, 0x24c2, 0x2500, 0x2542, 0x2586, 0x25cc, 0x260b,
+ 0x2631, 0x2658, 0x2681, 0x26ab, 0x26d6, 0x2703, 0x2731, 0x2760, 0x2791,
+ 0x27c3, 0x27f6, 0x2815, 0x2830, 0x284c, 0x2868, 0x2885, 0x28a3, 0x28c2,
+ 0x28e1, 0x2900, 0x2921, 0x2942, 0x2963, 0x2986, 0x29a9, 0x29cc, 0x29f1,
+ 0x2a0b, 0x2a1e, 0x2a31, 0x2a44, 0x2a58, 0x2a6c, 0x2a81, 0x2a96, 0x2aab,
+ 0x2ac0, 0x2ad6, 0x2aec, 0x2b03, 0x2b1a, 0x2b31, 0x2b48, 0x2b60, 0x2b79,
+ 0x2b91, 0x2baa, 0x2bc3, 0x2bdd, 0x2bf6, 0x2c08, 0x2c15, 0x2c23, 0x2c30,
+ 0x2c3e, 0x2c4c, 0x2c5a, 0x2c68, 0x2c77, 0x2c85, 0x2c94, 0x2ca3, 0x2cb2,
+ 0x2cc2, 0x2cd1, 0x2ce1, 0x2cf0, 0x2d00, 0x2d10, 0x2d21, 0x2d31, 0x2d42,
+ 0x2d52, 0x2d63, 0x2d74, 0x2d86, 0x2d97, 0x2da9, 0x2dbb, 0x2dcc, 0x2ddf,
+ 0x2df1, 0x2e01, 0x2e0b, 0x2e14, 0x2e1e, 0x2e27, 0x2e31, 0x2e3a, 0x2e44,
+ 0x2e4e, 0x2e58, 0x2e62, 0x2e6c, 0x2e76, 0x2e81, 0x2e8b, 0x2e96, 0x2ea0,
+ 0x2eab, 0x2eb6, 0x2ec0, 0x2ecb, 0x2ed6, 0x2ee1, 0x2eec, 0x2ef8, 0x2f03,
+ 0x2f0e, 0x2f1a, 0x2f25, 0x2f31, 0x2f3d, 0x2f48, 0x2f54, 0x2f60, 0x2f6c,
+ 0x2f79, 0x2f85, 0x2f91, 0x2f9d, 0x2faa, 0x2fb6, 0x2fc3, 0x2fd0, 0x2fdd,
+ 0x2fea, 0x2ff6, 0x3002, 0x3008, 0x300f, 0x3015, 0x301c, 0x3023, 0x302a,
+ 0x3030, 0x3037, 0x303e, 0x3045, 0x304c, 0x3053, 0x305a, 0x3061, 0x3068,
+ 0x3070, 0x3077, 0x307e, 0x3085, 0x308d, 0x3094, 0x309c, 0x30a3, 0x30ab,
+ 0x30b2, 0x30ba, 0x30c2, 0x30c9, 0x30d1, 0x30d9, 0x30e1, 0x30e8, 0x30f0,
+ 0x30f8, 0x3100, 0x3108, 0x3110, 0x3118, 0x3121, 0x3129, 0x3131, 0x3139,
+ 0x3142, 0x314a, 0x3152, 0x315b, 0x3163, 0x316c, 0x3174, 0x317d, 0x3186,
+ 0x318e, 0x3197, 0x31a0, 0x31a9, 0x31b2, 0x31bb, 0x31c3, 0x31cc, 0x31d5,
+ 0x31df, 0x31e8, 0x31f1, 0x31fa, 0x3201, 0x3206, 0x320b, 0x320f, 0x3214,
+ 0x3219, 0x321e, 0x3222, 0x3227, 0x322c, 0x3231, 0x3236, 0x323a, 0x323f,
+ 0x3244, 0x3249, 0x324e, 0x3253, 0x3258, 0x325d, 0x3262, 0x3267, 0x326c,
+ 0x3271, 0x3276, 0x327c, 0x3281, 0x3286, 0x328b, 0x3290, 0x3296, 0x329b,
+ 0x32a0, 0x32a6, 0x32ab, 0x32b0, 0x32b6, 0x32bb, 0x32c1, 0x32c6, 0x32cc,
+ 0x32d2, 0x32d8, 0x32dd, 0x32e3, 0x32e9, 0x32ef, 0x32f6, 0x32fc, 0x3302,
+ 0x3308, 0x330f, 0x3315, 0x331c, 0x3322, 0x3329, 0x3330, 0x3337, 0x333e,
+ 0x3345, 0x334c, 0x3353, 0x335a, 0x3361, 0x3369, 0x3370, 0x3378, 0x337f,
+ 0x3387, 0x338f, 0x3397, 0x339f, 0x33a7, 0x33af, 0x33b7, 0x33bf, 0x33c8,
+ 0x33d0, 0x33d9, 0x33e2, 0x33eb, 0x33f3, 0x33fc, 0x3402, 0x3407, 0x340c,
+ 0x3410, 0x3415, 0x341a, 0x341f, 0x3424, 0x3429, 0x342e, 0x3433, 0x3438,
+ 0x343d, 0x3442, 0x3448, 0x344d, 0x3452, 0x3458, 0x345d, 0x3463, 0x3469,
+ 0x346e, 0x3474, 0x347a, 0x3480, 0x3486, 0x348c, 0x3492, 0x3498, 0x349e,
+ 0x34a5, 0x34ab, 0x34b2, 0x34b8, 0x34bf, 0x34c5, 0x34cc, 0x34d3, 0x34da,
+ 0x34e1, 0x34e8, 0x34ef, 0x34f6, 0x34fd, 0x3505, 0x350c, 0x3514, 0x351b,
+ 0x3523, 0x352b, 0x3532, 0x353a, 0x3542, 0x354b, 0x3553, 0x355b, 0x3563,
+ 0x356c, 0x3574, 0x357d, 0x3586, 0x358f, 0x3598, 0x35a1, 0x35aa, 0x35b3,
+ 0x35bc, 0x35c6, 0x35cf, 0x35d9, 0x35e3, 0x35ed, 0x35f7, 0x3600, 0x3605,
+ 0x360a, 0x3610, 0x3615, 0x361a, 0x3620, 0x3625, 0x362b, 0x3630, 0x3636,
+ 0x363b, 0x3641, 0x3647, 0x364d, 0x3653, 0x3659, 0x365f, 0x3665, 0x366b,
+ 0x3672, 0x3678, 0x367e, 0x3685, 0x368b, 0x3692, 0x3699, 0x36a0, 0x36a6,
+ 0x36ad, 0x36b4, 0x36bb, 0x36c3, 0x36ca, 0x36d1, 0x36d9, 0x36e0, 0x36e8,
+ 0x36ef, 0x36f7, 0x36ff, 0x3707, 0x370f, 0x3717, 0x371f, 0x3727, 0x372f,
+ 0x3738, 0x3740, 0x3749, 0x3752, 0x375b, 0x3764, 0x376d, 0x3776, 0x377f,
+ 0x3788, 0x3792, 0x379b, 0x37a5, 0x37ae, 0x37b8, 0x37c2, 0x37cc, 0x37d6,
+ 0x37e1, 0x37eb, 0x37f6, 0x3800, 0x3805, 0x380b, 0x3810, 0x3816, 0x381b,
+ 0x3821, 0x3827, 0x382c, 0x3832, 0x3838, 0x383e, 0x3844, 0x384a, 0x3851,
+ 0x3857, 0x385d, 0x3864, 0x386a, 0x3870, 0x3877, 0x387e, 0x3885, 0x388b,
+ 0x3892, 0x3899, 0x38a0, 0x38a7, 0x38af, 0x38b6, 0x38bd, 0x38c5, 0x38cc,
+ 0x38d4, 0x38dc, 0x38e3, 0x38eb, 0x38f3, 0x38fb, 0x3903, 0x390c, 0x3914,
+ 0x391c, 0x3925, 0x392d, 0x3936, 0x393f, 0x3948, 0x3951, 0x395a, 0x3963,
+ 0x396c, 0x3975, 0x397f, 0x3989, 0x3992, 0x399c, 0x39a6, 0x39b0, 0x39ba,
+ 0x39c4, 0x39cf, 0x39d9, 0x39e4, 0x39ee, 0x39f9, 0xc,
+ /* table descriptor */
+ 0xf0ffffe9, 0xf,
+ /* table length */
+ 0x400,
+ /* table data */
+ 0x356a, 0x313b, 0x3816, 0x2da0, 0x33b2, 0x36c8, 0x38f3, 0x2a96, 0x2fb9,
+ 0x3288, 0x348f, 0x3634, 0x376f, 0x387f, 0x3973, 0x2866, 0x2c4a, 0x2eab,
+ 0x307e, 0x320b, 0x3315, 0x3430, 0x34f8, 0x35e5, 0x367b, 0x3719, 0x37cb,
+ 0x3849, 0x38b8, 0x3932, 0x39b7, 0x2652, 0x29a9, 0x2b80, 0x2ce9, 0x2e37,
+ 0x2f2b, 0x3029, 0x30d9, 0x31a5, 0x3248, 0x32cc, 0x3361, 0x3403, 0x345e,
+ 0x34c2, 0x3530, 0x35a6, 0x3613, 0x3657, 0x36a1, 0x36f0, 0x3743, 0x379c,
+ 0x37fb, 0x382f, 0x3863, 0x389b, 0x38d5, 0x3912, 0x3952, 0x3995, 0x39da,
+ 0x242a, 0x278f, 0x2904, 0x2a30, 0x2b06, 0x2c02, 0x2c97, 0x2d42, 0x2e02,
+ 0x2e6f, 0x2ee9, 0x2f70, 0x3002, 0x3053, 0x30aa, 0x3109, 0x316f, 0x31dd,
+ 0x3229, 0x3267, 0x32aa, 0x32f0, 0x333a, 0x3389, 0x33dc, 0x3419, 0x3447,
+ 0x3477, 0x34a9, 0x34dd, 0x3513, 0x354c, 0x3587, 0x35c5, 0x3602, 0x3623,
+ 0x3646, 0x3669, 0x368e, 0x36b4, 0x36db, 0x3704, 0x372e, 0x3759, 0x3786,
+ 0x37b3, 0x37e3, 0x3809, 0x3822, 0x383c, 0x3856, 0x3871, 0x388d, 0x38a9,
+ 0x38c6, 0x38e4, 0x3902, 0x3922, 0x3942, 0x3962, 0x3984, 0x39a6, 0x39c9,
+ 0x39ec, 0x21b7, 0x2567, 0x26f0, 0x2816, 0x28b5, 0x2954, 0x2a01, 0x2a62,
+ 0x2acd, 0x2b41, 0x2bc1, 0x2c25, 0x2c6f, 0x2cbf, 0x2d15, 0x2d70, 0x2dd2,
+ 0x2e1c, 0x2e53, 0x2e8d, 0x2eca, 0x2f0a, 0x2f4d, 0x2f94, 0x2fde, 0x3015,
+ 0x303e, 0x3068, 0x3094, 0x30c1, 0x30f1, 0x3122, 0x3155, 0x318a, 0x31c1,
+ 0x31fa, 0x321a, 0x3238, 0x3257, 0x3277, 0x3299, 0x32bb, 0x32de, 0x3302,
+ 0x3327, 0x334e, 0x3375, 0x339d, 0x33c7, 0x33f1, 0x340e, 0x3424, 0x343b,
+ 0x3452, 0x346a, 0x3483, 0x349c, 0x34b5, 0x34d0, 0x34ea, 0x3506, 0x3521,
+ 0x353e, 0x355b, 0x3578, 0x3597, 0x35b5, 0x35d5, 0x35f5, 0x360a, 0x361b,
+ 0x362c, 0x363d, 0x364e, 0x3660, 0x3672, 0x3685, 0x3697, 0x36aa, 0x36be,
+ 0x36d2, 0x36e5, 0x36fa, 0x370e, 0x3723, 0x3739, 0x374e, 0x3764, 0x377a,
+ 0x3791, 0x37a8, 0x37bf, 0x37d7, 0x37ef, 0x3803, 0x380f, 0x381c, 0x3829,
+ 0x3835, 0x3842, 0x384f, 0x385d, 0x386a, 0x3878, 0x3886, 0x3894, 0x38a2,
+ 0x38b0, 0x38bf, 0x38ce, 0x38dc, 0x38eb, 0x38fb, 0x390a, 0x391a, 0x392a,
+ 0x393a, 0x394a, 0x395a, 0x396b, 0x397b, 0x398c, 0x399d, 0x39af, 0x39c0,
+ 0x39d2, 0x39e3, 0x39f5, 0x1e7a, 0x2318, 0x24c9, 0x2603, 0x26a1, 0x2740,
+ 0x27de, 0x283e, 0x288d, 0x28dd, 0x292c, 0x297e, 0x29d5, 0x2a18, 0x2a49,
+ 0x2a7c, 0x2ab1, 0x2ae9, 0x2b23, 0x2b60, 0x2ba0, 0x2be2, 0x2c13, 0x2c37,
+ 0x2c5c, 0x2c83, 0x2cab, 0x2cd4, 0x2cff, 0x2d2b, 0x2d59, 0x2d88, 0x2db9,
+ 0x2deb, 0x2e0f, 0x2e2a, 0x2e45, 0x2e61, 0x2e7e, 0x2e9c, 0x2eba, 0x2ed9,
+ 0x2efa, 0x2f1a, 0x2f3c, 0x2f5f, 0x2f82, 0x2fa6, 0x2fcb, 0x2ff1, 0x300c,
+ 0x301f, 0x3034, 0x3048, 0x305d, 0x3073, 0x3089, 0x309f, 0x30b6, 0x30cd,
+ 0x30e5, 0x30fd, 0x3116, 0x312f, 0x3148, 0x3162, 0x317d, 0x3198, 0x31b3,
+ 0x31cf, 0x31eb, 0x3204, 0x3212, 0x3221, 0x3230, 0x3240, 0x324f, 0x325f,
+ 0x326f, 0x3280, 0x3290, 0x32a1, 0x32b2, 0x32c4, 0x32d5, 0x32e7, 0x32f9,
+ 0x330b, 0x331e, 0x3331, 0x3344, 0x3357, 0x336b, 0x337f, 0x3393, 0x33a7,
+ 0x33bc, 0x33d1, 0x33e6, 0x33fc, 0x3408, 0x3413, 0x341f, 0x342a, 0x3435,
+ 0x3441, 0x344d, 0x3458, 0x3464, 0x3470, 0x347d, 0x3489, 0x3496, 0x34a2,
+ 0x34af, 0x34bc, 0x34c9, 0x34d6, 0x34e4, 0x34f1, 0x34ff, 0x350c, 0x351a,
+ 0x3528, 0x3537, 0x3545, 0x3553, 0x3562, 0x3571, 0x3580, 0x358f, 0x359e,
+ 0x35ae, 0x35bd, 0x35cd, 0x35dd, 0x35ed, 0x35fd, 0x3606, 0x360e, 0x3617,
+ 0x361f, 0x3628, 0x3630, 0x3639, 0x3641, 0x364a, 0x3653, 0x365c, 0x3665,
+ 0x366e, 0x3677, 0x3680, 0x3689, 0x3693, 0x369c, 0x36a6, 0x36af, 0x36b9,
+ 0x36c3, 0x36cd, 0x36d6, 0x36e0, 0x36eb, 0x36f5, 0x36ff, 0x3709, 0x3714,
+ 0x371e, 0x3729, 0x3733, 0x373e, 0x3749, 0x3754, 0x375f, 0x376a, 0x3775,
+ 0x3780, 0x378b, 0x3797, 0x37a2, 0x37ae, 0x37b9, 0x37c5, 0x37d1, 0x37dd,
+ 0x37e9, 0x37f5, 0x3800, 0x3806, 0x380c, 0x3813, 0x3819, 0x381f, 0x3825,
+ 0x382c, 0x3832, 0x3839, 0x383f, 0x3846, 0x384c, 0x3853, 0x3859, 0x3860,
+ 0x3867, 0x386e, 0x3874, 0x387b, 0x3882, 0x3889, 0x3890, 0x3897, 0x389e,
+ 0x38a5, 0x38ad, 0x38b4, 0x38bb, 0x38c2, 0x38ca, 0x38d1, 0x38d9, 0x38e0,
+ 0x38e8, 0x38ef, 0x38f7, 0x38ff, 0x3906, 0x390e, 0x3916, 0x391e, 0x3926,
+ 0x392e, 0x3936, 0x393e, 0x3946, 0x394e, 0x3956, 0x395e, 0x3966, 0x396f,
+ 0x3977, 0x397f, 0x3988, 0x3990, 0x3999, 0x39a2, 0x39aa, 0x39b3, 0x39bc,
+ 0x39c4, 0x39cd, 0x39d6, 0x39df, 0x39e8, 0x39f1, 0x39fa, 0x0, 0x207a,
+ 0x227a, 0x23b7, 0x247a, 0x2518, 0x25b7, 0x262a, 0x267a, 0x26c9, 0x2718,
+ 0x2767, 0x27b7, 0x2803, 0x282a, 0x2852, 0x287a, 0x28a1, 0x28c9, 0x28f0,
+ 0x2918, 0x2940, 0x2969, 0x2994, 0x29bf, 0x29ec, 0x2a0d, 0x2a24, 0x2a3d,
+ 0x2a55, 0x2a6f, 0x2a89, 0x2aa3, 0x2abf, 0x2adb, 0x2af7, 0x2b14, 0x2b32,
+ 0x2b51, 0x2b70, 0x2b90, 0x2bb0, 0x2bd1, 0x2bf3, 0x2c0b, 0x2c1c, 0x2c2e,
+ 0x2c40, 0x2c53, 0x2c66, 0x2c79, 0x2c8d, 0x2ca1, 0x2cb5, 0x2cca, 0x2cdf,
+ 0x2cf4, 0x2d0a, 0x2d20, 0x2d37, 0x2d4d, 0x2d65, 0x2d7c, 0x2d94, 0x2dad,
+ 0x2dc5, 0x2dde, 0x2df8, 0x2e09, 0x2e16, 0x2e23, 0x2e30, 0x2e3e, 0x2e4c,
+ 0x2e5a, 0x2e68, 0x2e77, 0x2e85, 0x2e94, 0x2ea3, 0x2eb3, 0x2ec2, 0x2ed2,
+ 0x2ee1, 0x2ef1, 0x2f02, 0x2f12, 0x2f23, 0x2f34, 0x2f45, 0x2f56, 0x2f67,
+ 0x2f79, 0x2f8b, 0x2f9d, 0x2faf, 0x2fc2, 0x2fd5, 0x2fe7, 0x2ffb, 0x3007,
+ 0x3010, 0x301a, 0x3024, 0x302e, 0x3039, 0x3043, 0x304d, 0x3058, 0x3063,
+ 0x306d, 0x3078, 0x3083, 0x308e, 0x3099, 0x30a5, 0x30b0, 0x30bc, 0x30c7,
+ 0x30d3, 0x30df, 0x30eb, 0x30f7, 0x3103, 0x310f, 0x311c, 0x3128, 0x3135,
+ 0x3142, 0x314f, 0x315c, 0x3169, 0x3176, 0x3183, 0x3191, 0x319e, 0x31ac,
+ 0x31ba, 0x31c8, 0x31d6, 0x31e4, 0x31f2, 0x3200, 0x3207, 0x320f, 0x3216,
+ 0x321e, 0x3225, 0x322d, 0x3234, 0x323c, 0x3244, 0x324b, 0x3253, 0x325b,
+ 0x3263, 0x326b, 0x3273, 0x327c, 0x3284, 0x328c, 0x3294, 0x329d, 0x32a5,
+ 0x32ae, 0x32b6, 0x32bf, 0x32c8, 0x32d1, 0x32da, 0x32e2, 0x32eb, 0x32f4,
+ 0x32fe, 0x3307, 0x3310, 0x3319, 0x3323, 0x332c, 0x3336, 0x333f, 0x3349,
+ 0x3352, 0x335c, 0x3366, 0x3370, 0x337a, 0x3384, 0x338e, 0x3398, 0x33a2,
+ 0x33ad, 0x33b7, 0x33c1, 0x33cc, 0x33d6, 0x33e1, 0x33ec, 0x33f6, 0x3400,
+ 0x3406, 0x340b, 0x3411, 0x3416, 0x341c, 0x3421, 0x3427, 0x342d, 0x3432,
+ 0x3438, 0x343e, 0x3444, 0x344a, 0x344f, 0x3455, 0x345b, 0x3461, 0x3467,
+ 0x346d, 0x3473, 0x347a, 0x3480, 0x3486, 0x348c, 0x3492, 0x3499, 0x349f,
+ 0x34a5, 0x34ac, 0x34b2, 0x34b9, 0x34bf, 0x34c6, 0x34cc, 0x34d3, 0x34d9,
+ 0x34e0, 0x34e7, 0x34ee, 0x34f4, 0x34fb, 0x3502, 0x3509, 0x3510, 0x3517,
+ 0x351e, 0x3525, 0x352c, 0x3533, 0x353a, 0x3541, 0x3549, 0x3550, 0x3557,
+ 0x355e, 0x3566, 0x356d, 0x3575, 0x357c, 0x3584, 0x358b, 0x3593, 0x359a,
+ 0x35a2, 0x35aa, 0x35b1, 0x35b9, 0x35c1, 0x35c9, 0x35d1, 0x35d9, 0x35e1,
+ 0x35e9, 0x35f1, 0x35f9, 0x3600, 0x3604, 0x3608, 0x360c, 0x3610, 0x3615,
+ 0x3619, 0x361d, 0x3621, 0x3625, 0x362a, 0x362e, 0x3632, 0x3636, 0x363b,
+ 0x363f, 0x3643, 0x3648, 0x364c, 0x3651, 0x3655, 0x365a, 0x365e, 0x3662,
+ 0x3667, 0x366b, 0x3670, 0x3675, 0x3679, 0x367e, 0x3682, 0x3687, 0x368c,
+ 0x3690, 0x3695, 0x369a, 0x369f, 0x36a3, 0x36a8, 0x36ad, 0x36b2, 0x36b7,
+ 0x36bb, 0x36c0, 0x36c5, 0x36ca, 0x36cf, 0x36d4, 0x36d9, 0x36de, 0x36e3,
+ 0x36e8, 0x36ed, 0x36f2, 0x36f7, 0x36fc, 0x3701, 0x3707, 0x370c, 0x3711,
+ 0x3716, 0x371b, 0x3721, 0x3726, 0x372b, 0x3731, 0x3736, 0x373b, 0x3741,
+ 0x3746, 0x374b, 0x3751, 0x3756, 0x375c, 0x3761, 0x3767, 0x376c, 0x3772,
+ 0x3778, 0x377d, 0x3783, 0x3788, 0x378e, 0x3794, 0x379a, 0x379f, 0x37a5,
+ 0x37ab, 0x37b1, 0x37b6, 0x37bc, 0x37c2, 0x37c8, 0x37ce, 0x37d4, 0x37da,
+ 0x37e0, 0x37e6, 0x37ec, 0x37f2, 0x37f8, 0x37fe, 0x3802, 0x3805, 0x3808,
+ 0x380b, 0x380e, 0x3811, 0x3814, 0x3817, 0x381a, 0x381d, 0x3821, 0x3824,
+ 0x3827, 0x382a, 0x382d, 0x3831, 0x3834, 0x3837, 0x383a, 0x383d, 0x3841,
+ 0x3844, 0x3847, 0x384a, 0x384e, 0x3851, 0x3854, 0x3858, 0x385b, 0x385e,
+ 0x3862, 0x3865, 0x3869, 0x386c, 0x386f, 0x3873, 0x3876, 0x387a, 0x387d,
+ 0x3881, 0x3884, 0x3887, 0x388b, 0x388e, 0x3892, 0x3895, 0x3899, 0x389d,
+ 0x38a0, 0x38a4, 0x38a7, 0x38ab, 0x38ae, 0x38b2, 0x38b6, 0x38b9, 0x38bd,
+ 0x38c1, 0x38c4, 0x38c8, 0x38cc, 0x38cf, 0x38d3, 0x38d7, 0x38db, 0x38de,
+ 0x38e2, 0x38e6, 0x38ea, 0x38ed, 0x38f1, 0x38f5, 0x38f9, 0x38fd, 0x3901,
+ 0x3904, 0x3908, 0x390c, 0x3910, 0x3914, 0x3918, 0x391c, 0x3920, 0x3924,
+ 0x3928, 0x392c, 0x3930, 0x3934, 0x3938, 0x393c, 0x3940, 0x3944, 0x3948,
+ 0x394c, 0x3950, 0x3954, 0x3958, 0x395c, 0x3960, 0x3964, 0x3968, 0x396d,
+ 0x3971, 0x3975, 0x3979, 0x397d, 0x3982, 0x3986, 0x398a, 0x398e, 0x3993,
+ 0x3997, 0x399b, 0x399f, 0x39a4, 0x39a8, 0x39ac, 0x39b1, 0x39b5, 0x39b9,
+ 0x39be, 0x39c2, 0x39c7, 0x39cb, 0x39cf, 0x39d4, 0x39d8, 0x39dd, 0x39e1,
+ 0x39e6, 0x39ea, 0x39ef, 0x39f3, 0x39f8, 0x39fc, 0xc,
+ /* table descriptor */
+ 0xbf7fffea, 0xf,
+ /* table length */
+ 0x1d,
+ /* table data */
+ 0x3, 0x36ce, 0x0, 0x0, 0x0, 0x36ce, 0x0, 0x0, 0x0, 0x36ce, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x3ff, 0x3ff, 0x3ff, 0xe, 0x40, 0x40, 0x40, 0x40,
+ 0x40, 0x40, 0x3ac, 0x3ac, 0x3ac,
+ /* table descriptor */
+ 0xdf7fffea, 0xf,
+ /* table length */
+ 0x1d,
+ /* table data */
+ 0x8000, 0x4000, 0x0, 0x0, 0x0, 0x4000, 0x0, 0x0, 0x0, 0x4000, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x3ff, 0x3ff, 0x3ff, 0xe, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x3ff, 0x3ff, 0x3ff,
+ /* table descriptor */
+ 0xbfbfffea, 0x0,
+ /* table length */
+ 0x1d,
+ /* table data */
+ 0x3, 0xe66, 0x2528, 0x340, 0xfffff82c, 0xffffebcd, 0x1c07, 0x1c07,
+ 0xffffe63a, 0xfffffdbf, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3ff, 0x3ff,
+ 0x3ff, 0xe, 0x40, 0x200, 0x200, 0x40, 0x40, 0x40, 0x3ac, 0x3c0, 0x3c0,
+ /* table descriptor */
+ 0x3fbfffea, 0x1,
+ /* table length */
+ 0x1d,
+ /* table data */
+ 0x3, 0xba7, 0x2732, 0x3f5, 0xfffff994, 0xffffea65, 0x1c07, 0x1c07,
+ 0xffffe68b, 0xfffffd6e, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3ff, 0x3ff,
+ 0x3ff, 0xe, 0x40, 0x200, 0x200, 0x40, 0x40, 0x40, 0x3ac, 0x3c0, 0x3c0,
+ /* table descriptor */
+ 0x3fbfffea, 0x6,
+ /* table length */
+ 0x1d,
+ /* table data */
+ 0x3, 0x1063, 0x202b, 0x63f, 0xfffff68b, 0xffffed6e, 0x1c07, 0x1c07,
+ 0xffffe888, 0xfffffb71, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3ff, 0x3ff,
+ 0x3ff, 0xe, 0x40, 0x200, 0x200, 0x40, 0x40, 0x40, 0x3ac, 0x3c0, 0x3c0,
+ /* table descriptor */
+ 0x3fbfffea, 0x8,
+ /* table length */
+ 0x1d,
+ /* table data */
+ 0x3, 0x36ce, 0x0, 0x0, 0x0, 0x380e, 0x0, 0x0, 0x0, 0x380e, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x3ff, 0x3ff, 0x3ff, 0xe, 0x40, 0x200, 0x200, 0x40,
+ 0x40, 0x40, 0x3ac, 0x3c0, 0x3c0,
+ /* table descriptor */
+ 0xdfbfffea, 0x0,
+ /* table length */
+ 0x1d,
+ /* table data */
+ 0x3, 0x10d0, 0x2b64, 0x3cc, 0xfffff710, 0xffffe8f0, 0x2000, 0x2000,
+ 0xffffe293, 0xfffffd6d, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3ff, 0x3ff,
+ 0x3ff, 0xe, 0x0, 0x200, 0x200, 0x0, 0x0, 0x0, 0x3ff, 0x3ff, 0x3ff,
+ /* table descriptor */
+ 0x5fbfffea, 0x1,
+ /* table length */
+ 0x1d,
+ /* table data */
+ 0x3, 0xd9b, 0x2dc6, 0x49f, 0xfffff8ab, 0xffffe755, 0x2000, 0x2000,
+ 0xffffe2ef, 0xfffffd11, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3ff, 0x3ff,
+ 0x3ff, 0xe, 0x0, 0x200, 0x200, 0x0, 0x0, 0x0, 0x3ff, 0x3ff, 0x3ff,
+ /* table descriptor */
+ 0x5fbfffea, 0x6,
+ /* table length */
+ 0x1d,
+ /* table data */
+ 0x3, 0x1323, 0x2591, 0x74c, 0xfffff533, 0xffffeacd, 0x2000, 0x2000,
+ 0xffffe534, 0xfffffacc, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3ff, 0x3ff,
+ 0x3ff, 0xe, 0x0, 0x200, 0x200, 0x0, 0x0, 0x0, 0x3ff, 0x3ff, 0x3ff,
+ /* table descriptor */
+ 0x5fbfffea, 0x8,
+ /* table length */
+ 0x1d,
+ /* table data */
+ 0x3, 0x4000, 0x0, 0x0, 0x0, 0x4000, 0x0, 0x0, 0x0, 0x4000, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x3ff, 0x3ff, 0x3ff, 0xe, 0x0, 0x200, 0x200, 0x0,
+ 0x0, 0x0, 0x3ff, 0x3ff, 0x3ff,
+ /* table descriptor */
+ 0xfff0e1e1, 0xf,
+ /* table length */
+ 0x402,
+ /* table data */
+ 0x3, 0x0, 0x200, 0x500, 0x700, 0x8c0, 0xa20, 0xae0, 0xbe0, 0xc70,
+ 0xd00, 0xdb0, 0xe30, 0xe98, 0xf00, 0xf78, 0xff8, 0x103c, 0x1084,
+ 0x10d0, 0x1120, 0x1178, 0x11d0, 0x1218, 0x124a, 0x127e, 0x12b6, 0x12f0,
+ 0x132c, 0x136c, 0x13ae, 0x13f2, 0x141d, 0x1442, 0x1469, 0x1491, 0x14bb,
+ 0x14e6, 0x1513, 0x1542, 0x1572, 0x15a4, 0x15d7, 0x1606, 0x1621, 0x163e,
+ 0x165b, 0x1679, 0x1698, 0x16b9, 0x16da, 0x16fc, 0x171f, 0x1743, 0x1768,
+ 0x178e, 0x17b5, 0x17dd, 0x1803, 0x1818, 0x182e, 0x1844, 0x185b, 0x1873,
+ 0x188b, 0x18a4, 0x18bd, 0x18d7, 0x18f2, 0x190d, 0x1929, 0x1945, 0x1962,
+ 0x1980, 0x199f, 0x19be, 0x19de, 0x19ff, 0x1a10, 0x1a21, 0x1a32, 0x1a44,
+ 0x1a56, 0x1a69, 0x1a7c, 0x1a8f, 0x1aa3, 0x1ab7, 0x1acc, 0x1ae1, 0x1af6,
+ 0x1b0c, 0x1b23, 0x1b39, 0x1b51, 0x1b68, 0x1b81, 0x1b99, 0x1bb2, 0x1bcc,
+ 0x1be6, 0x1c00, 0x1c0e, 0x1c1b, 0x1c29, 0x1c38, 0x1c46, 0x1c55, 0x1c64,
+ 0x1c74, 0x1c83, 0x1c93, 0x1ca3, 0x1cb4, 0x1cc5, 0x1cd6, 0x1ce7, 0x1cf9,
+ 0x1d0b, 0x1d1d, 0x1d30, 0x1d42, 0x1d56, 0x1d69, 0x1d7d, 0x1d91, 0x1da6,
+ 0x1dbb, 0x1dd0, 0x1de6, 0x1dfc, 0x1e09, 0x1e14, 0x1e20, 0x1e2b, 0x1e37,
+ 0x1e43, 0x1e4f, 0x1e5c, 0x1e69, 0x1e75, 0x1e82, 0x1e90, 0x1e9d, 0x1eab,
+ 0x1eb9, 0x1ec7, 0x1ed5, 0x1ee3, 0x1ef2, 0x1f01, 0x1f10, 0x1f20, 0x1f2f,
+ 0x1f3f, 0x1f4f, 0x1f60, 0x1f70, 0x1f81, 0x1f92, 0x1fa3, 0x1fb5, 0x1fc7,
+ 0x1fd9, 0x1feb, 0x1ffe, 0x2008, 0x2012, 0x201b, 0x2025, 0x202f, 0x2039,
+ 0x2043, 0x204e, 0x2058, 0x2063, 0x206e, 0x2079, 0x2084, 0x208f, 0x209b,
+ 0x20a6, 0x20b2, 0x20be, 0x20ca, 0x20d6, 0x20e3, 0x20ef, 0x20fc, 0x2109,
+ 0x2116, 0x2123, 0x2131, 0x213e, 0x214c, 0x215a, 0x2168, 0x2176, 0x2185,
+ 0x2194, 0x21a2, 0x21b2, 0x21c1, 0x21d0, 0x21e0, 0x21f0, 0x2200, 0x2208,
+ 0x2210, 0x2218, 0x2221, 0x2229, 0x2232, 0x223b, 0x2244, 0x224d, 0x2256,
+ 0x225f, 0x2268, 0x2272, 0x227b, 0x2285, 0x228f, 0x2299, 0x22a3, 0x22ad,
+ 0x22b7, 0x22c2, 0x22cc, 0x22d7, 0x22e2, 0x22ed, 0x22f8, 0x2303, 0x230e,
+ 0x231a, 0x2325, 0x2331, 0x233d, 0x2349, 0x2355, 0x2361, 0x236e, 0x237a,
+ 0x2387, 0x2394, 0x23a1, 0x23ae, 0x23bc, 0x23c9, 0x23d7, 0x23e5, 0x23f3,
+ 0x2400, 0x2407, 0x240f, 0x2416, 0x241d, 0x2425, 0x242c, 0x2434, 0x243c,
+ 0x2444, 0x244c, 0x2454, 0x245c, 0x2464, 0x246c, 0x2475, 0x247d, 0x2486,
+ 0x248e, 0x2497, 0x24a0, 0x24a9, 0x24b2, 0x24bb, 0x24c4, 0x24ce, 0x24d7,
+ 0x24e1, 0x24eb, 0x24f4, 0x24fe, 0x2508, 0x2512, 0x251d, 0x2527, 0x2531,
+ 0x253c, 0x2547, 0x2552, 0x255d, 0x2568, 0x2573, 0x257e, 0x2589, 0x2595,
+ 0x25a1, 0x25ac, 0x25b8, 0x25c4, 0x25d1, 0x25dd, 0x25e9, 0x25f6, 0x2601,
+ 0x2607, 0x260e, 0x2614, 0x261b, 0x2622, 0x2629, 0x262f, 0x2636, 0x263d,
+ 0x2644, 0x264c, 0x2653, 0x265a, 0x2661, 0x2669, 0x2670, 0x2678, 0x2680,
+ 0x2687, 0x268f, 0x2697, 0x269f, 0x26a7, 0x26af, 0x26b8, 0x26c0, 0x26c8,
+ 0x26d1, 0x26d9, 0x26e2, 0x26eb, 0x26f4, 0x26fd, 0x2706, 0x270f, 0x2718,
+ 0x2722, 0x272b, 0x2734, 0x273e, 0x2748, 0x2752, 0x275c, 0x2766, 0x2770,
+ 0x277a, 0x2784, 0x278f, 0x2799, 0x27a4, 0x27af, 0x27b9, 0x27c4, 0x27d0,
+ 0x27db, 0x27e6, 0x27f1, 0x27fd, 0x2804, 0x280a, 0x2810, 0x2816, 0x281c,
+ 0x2822, 0x2828, 0x282f, 0x2835, 0x283b, 0x2842, 0x2848, 0x284f, 0x2855,
+ 0x285c, 0x2863, 0x286a, 0x2870, 0x2877, 0x287e, 0x2886, 0x288d, 0x2894,
+ 0x289b, 0x28a3, 0x28aa, 0x28b2, 0x28b9, 0x28c1, 0x28c9, 0x28d0, 0x28d8,
+ 0x28e0, 0x28e8, 0x28f1, 0x28f9, 0x2901, 0x2909, 0x2912, 0x291a, 0x2923,
+ 0x292c, 0x2935, 0x293d, 0x2946, 0x294f, 0x2959, 0x2962, 0x296b, 0x2975,
+ 0x297e, 0x2988, 0x2991, 0x299b, 0x29a5, 0x29af, 0x29b9, 0x29c3, 0x29cd,
+ 0x29d8, 0x29e2, 0x29ed, 0x29f7, 0x2a01, 0x2a06, 0x2a0c, 0x2a11, 0x2a17,
+ 0x2a1c, 0x2a22, 0x2a28, 0x2a2e, 0x2a33, 0x2a39, 0x2a3f, 0x2a45, 0x2a4b,
+ 0x2a52, 0x2a58, 0x2a5e, 0x2a64, 0x2a6b, 0x2a71, 0x2a78, 0x2a7e, 0x2a85,
+ 0x2a8b, 0x2a92, 0x2a99, 0x2aa0, 0x2aa7, 0x2aae, 0x2ab5, 0x2abc, 0x2ac3,
+ 0x2aca, 0x2ad2, 0x2ad9, 0x2ae1, 0x2ae8, 0x2af0, 0x2af7, 0x2aff, 0x2b07,
+ 0x2b0f, 0x2b17, 0x2b1f, 0x2b27, 0x2b2f, 0x2b38, 0x2b40, 0x2b48, 0x2b51,
+ 0x2b59, 0x2b62, 0x2b6b, 0x2b74, 0x2b7d, 0x2b86, 0x2b8f, 0x2b98, 0x2ba1,
+ 0x2baa, 0x2bb4, 0x2bbd, 0x2bc7, 0x2bd0, 0x2bda, 0x2be4, 0x2bee, 0x2bf8,
+ 0x2c01, 0x2c06, 0x2c0b, 0x2c10, 0x2c16, 0x2c1b, 0x2c20, 0x2c26, 0x2c2b,
+ 0x2c31, 0x2c36, 0x2c3c, 0x2c41, 0x2c47, 0x2c4d, 0x2c53, 0x2c59, 0x2c5e,
+ 0x2c64, 0x2c6a, 0x2c70, 0x2c77, 0x2c7d, 0x2c83, 0x2c89, 0x2c90, 0x2c96,
+ 0x2c9d, 0x2ca3, 0x2caa, 0x2cb0, 0x2cb7, 0x2cbe, 0x2cc5, 0x2ccc, 0x2cd3,
+ 0x2cda, 0x2ce1, 0x2ce8, 0x2cef, 0x2cf6, 0x2cfe, 0x2d05, 0x2d0d, 0x2d14,
+ 0x2d1c, 0x2d24, 0x2d2b, 0x2d33, 0x2d3b, 0x2d43, 0x2d4b, 0x2d53, 0x2d5b,
+ 0x2d64, 0x2d6c, 0x2d74, 0x2d7d, 0x2d85, 0x2d8e, 0x2d97, 0x2da0, 0x2da9,
+ 0x2db2, 0x2dbb, 0x2dc4, 0x2dcd, 0x2dd6, 0x2de0, 0x2de9, 0x2df3, 0x2dfc,
+ 0x2e03, 0x2e08, 0x2e0d, 0x2e12, 0x2e17, 0x2e1c, 0x2e21, 0x2e26, 0x2e2b,
+ 0x2e30, 0x2e36, 0x2e3b, 0x2e41, 0x2e46, 0x2e4c, 0x2e51, 0x2e57, 0x2e5c,
+ 0x2e62, 0x2e68, 0x2e6e, 0x2e73, 0x2e79, 0x2e7f, 0x2e85, 0x2e8b, 0x2e92,
+ 0x2e98, 0x2e9e, 0x2ea4, 0x2eab, 0x2eb1, 0x2eb8, 0x2ebe, 0x2ec5, 0x2ecb,
+ 0x2ed2, 0x2ed9, 0x2ee0, 0x2ee6, 0x2eed, 0x2ef4, 0x2efb, 0x2f03, 0x2f0a,
+ 0x2f11, 0x2f18, 0x2f20, 0x2f27, 0x2f2f, 0x2f36, 0x2f3e, 0x2f46, 0x2f4e,
+ 0x2f55, 0x2f5d, 0x2f65, 0x2f6d, 0x2f76, 0x2f7e, 0x2f86, 0x2f8e, 0x2f97,
+ 0x2f9f, 0x2fa8, 0x2fb1, 0x2fb9, 0x2fc2, 0x2fcb, 0x2fd4, 0x2fdd, 0x2fe6,
+ 0x2ff0, 0x2ff9, 0x3001, 0x3006, 0x300a, 0x300f, 0x3014, 0x3019, 0x301e,
+ 0x3023, 0x3028, 0x302d, 0x3032, 0x3037, 0x303d, 0x3042, 0x3047, 0x304d,
+ 0x3052, 0x3057, 0x305d, 0x3062, 0x3068, 0x306e, 0x3073, 0x3079, 0x307f,
+ 0x3085, 0x308b, 0x3091, 0x3097, 0x309d, 0x30a3, 0x30a9, 0x30af, 0x30b6,
+ 0x30bc, 0x30c2, 0x30c9, 0x30cf, 0x30d6, 0x30dd, 0x30e3, 0x30ea, 0x30f1,
+ 0x30f8, 0x30ff, 0x3106, 0x310d, 0x3114, 0x311b, 0x3122, 0x3129, 0x3131,
+ 0x3138, 0x3140, 0x3147, 0x314f, 0x3157, 0x315e, 0x3166, 0x316e, 0x3176,
+ 0x317e, 0x3186, 0x318f, 0x3197, 0x319f, 0x31a8, 0x31b0, 0x31b9, 0x31c1,
+ 0x31ca, 0x31d3, 0x31dc, 0x31e5, 0x31ee, 0x31f7, 0x3200, 0x3204, 0x3209,
+ 0x320e, 0x3213, 0x3217, 0x321c, 0x3221, 0x3226, 0x322b, 0x3230, 0x3235,
+ 0x323a, 0x323f, 0x3245, 0x324a, 0x324f, 0x3255, 0x325a, 0x325f, 0x3265,
+ 0x326a, 0x3270, 0x3276, 0x327b, 0x3281, 0x3287, 0x328d, 0x3293, 0x3299,
+ 0x329f, 0x32a5, 0x32ab, 0x32b1, 0x32b7, 0x32bd, 0x32c4, 0x32ca, 0x32d1,
+ 0x32d7, 0x32de, 0x32e4, 0x32eb, 0x32f2, 0x32f8, 0x32ff, 0x3306, 0x330d,
+ 0x3314, 0x331b, 0x3322, 0x332a, 0x3331, 0x3338, 0x3340, 0x3347, 0x334f,
+ 0x3357, 0x335e, 0x3366, 0x336e, 0x3376, 0x337e, 0x3386, 0x338e, 0x3396,
+ 0x339e, 0x33a7, 0x33af, 0x33b8, 0x33c0, 0x33c9, 0x33d2, 0x33da, 0x33e3,
+ 0x33ec, 0x33f5, 0x33fe, 0x3404, 0x3408, 0x340d, 0x3412, 0x3416, 0x341b,
+ 0x3420, 0x3425, 0x342a, 0x342f, 0x3434, 0x3439, 0x343e, 0x3443, 0x3448,
+ 0x344e, 0x3453, 0x3458, 0x345e, 0x3463, 0x3469, 0x346e, 0x3474, 0x347a,
+ 0x347f, 0x3485, 0x348b, 0x3491, 0x3497, 0x349d, 0x34a3, 0x34a9, 0x34af,
+ 0x34b5, 0x34bb, 0x34c2, 0x34c8, 0x34ce, 0x34d5, 0x34db, 0x34e2, 0x34e9,
+ 0x34ef, 0x34f6, 0x34fd, 0x3504, 0x350b, 0x3512, 0x3519, 0x3520, 0x3527,
+ 0x352f, 0x3536, 0x353d, 0x3545, 0x354c, 0x3554, 0x355c, 0x3563, 0x356b,
+ 0x3573, 0x357b, 0x3583, 0x358b, 0x3593, 0x359c, 0x35a4, 0x35ad, 0x35b5,
+ 0x35be, 0x35c6, 0x35cf, 0x35d8, 0x35e1, 0x35ea, 0x35f3, 0x35fc, 0x3602,
+ 0x3607, 0x360c, 0x3610, 0x3615, 0x361a, 0x361f, 0x3624, 0x3629, 0x362e,
+ 0x3633, 0x3638, 0x363d, 0x3642, 0x3647, 0x364d, 0x3652, 0x3657, 0x365d,
+ 0x3662, 0x3668, 0x366d, 0x3673, 0x3679, 0x367f, 0x3684, 0x368a, 0x3690,
+ 0x3696, 0x369c, 0x36a2, 0x36a8, 0x36ae, 0x36b5, 0x36bb, 0x36c1, 0x36c8,
+ 0x36ce, 0x36d5, 0x36db, 0x36e2, 0x36e9, 0x36f0, 0x36f6, 0x36fd, 0x3704,
+ 0x370b, 0x3712, 0x371a, 0x3721, 0x3728, 0x372f, 0x3737, 0x373e, 0x3746,
+ 0x374e, 0x3755, 0x375d, 0x3765, 0x376d, 0x3775, 0x377d, 0x3785, 0x378d,
+ 0x3796, 0x379e, 0x37a7, 0x37af, 0x37b8, 0x37c1, 0x37c9, 0x37d2, 0x37db,
+ 0x37e4, 0x37ed, 0x37f7, 0x3800, 0x3804, 0x3809, 0x380e, 0x3813, 0x3818,
+ 0x381d, 0x3821, 0x3826, 0x382c, 0x3831, 0x3836, 0x383b, 0x3840, 0x3846,
+ 0x384b, 0x3850, 0x3856, 0x385b, 0x3861, 0x3866, 0x386c, 0x3872, 0x3878,
+ 0x387d, 0x3883, 0x3889, 0x388f, 0x3895, 0x389b, 0x38a2, 0x38a8, 0x38ae,
+ 0x38b5, 0x38bb, 0x38c1, 0x38c8, 0x38cf, 0x38d5, 0x38dc, 0x38e3, 0x38ea,
+ 0x38f1, 0x38f8, 0x38ff, 0x3906, 0x390d, 0x3914, 0x391b, 0x3923, 0x392a,
+ 0x3932, 0x3939, 0x3941, 0x3949, 0x3951, 0x3959, 0x3961, 0x3969, 0x3971,
+ 0x3979, 0x3981, 0x398a, 0x3992, 0x399b, 0x39a3, 0x39ac, 0x39b5, 0x39be,
+ 0x39c7, 0x39d0, 0x39d9, 0x39e2, 0x39ec, 0x39f5, 0x39ff, 0x3,
+ /* table descriptor */
+ 0xffffe2e1, 0xf,
+ /* table length */
+ 0x402,
+ /* table data */
+ 0x3, 0x0, 0x3, 0x7, 0xa, 0xe, 0x11, 0x15, 0x18, 0x1c, 0x20, 0x23, 0x27,
+ 0x2a, 0x2e, 0x31, 0x35, 0x38, 0x3c, 0x40, 0x43, 0x47, 0x4a, 0x4e, 0x51,
+ 0x55, 0x58, 0x5c, 0x60, 0x63, 0x67, 0x6a, 0x6e, 0x71, 0x75, 0x78, 0x7c,
+ 0x80, 0x83, 0x87, 0x8a, 0x8e, 0x91, 0x95, 0x99, 0x9c, 0xa0, 0xa3, 0xa7,
+ 0xaa, 0xae, 0xb1, 0xb5, 0xb9, 0xbc, 0xc0, 0xc3, 0xc7, 0xca, 0xce, 0xd1,
+ 0xd5, 0xd9, 0xdc, 0xe0, 0xe3, 0xe7, 0xea, 0xee, 0xf1, 0xf5, 0xf9, 0xfc,
+ 0x100, 0x103, 0x107, 0x10a, 0x10e, 0x112, 0x115, 0x119, 0x11c, 0x120,
+ 0x123, 0x126, 0x12a, 0x12d, 0x131, 0x134, 0x138, 0x13c, 0x13f, 0x143,
+ 0x147, 0x14b, 0x14e, 0x152, 0x156, 0x15a, 0x15e, 0x162, 0x166, 0x16a,
+ 0x16e, 0x172, 0x176, 0x17a, 0x17e, 0x182, 0x186, 0x18a, 0x18f, 0x193,
+ 0x197, 0x19b, 0x1a0, 0x1a4, 0x1a8, 0x1ad, 0x1b1, 0x1b5, 0x1ba, 0x1be,
+ 0x1c3, 0x1c7, 0x1cc, 0x1d0, 0x1d5, 0x1d9, 0x1de, 0x1e3, 0x1e7, 0x1ec,
+ 0x1f1, 0x1f6, 0x1fa, 0x1ff, 0x204, 0x209, 0x20e, 0x213, 0x217, 0x21c,
+ 0x221, 0x226, 0x22b, 0x230, 0x236, 0x23b, 0x240, 0x245, 0x24a, 0x24f,
+ 0x255, 0x25a, 0x25f, 0x264, 0x26a, 0x26f, 0x274, 0x27a, 0x27f, 0x285,
+ 0x28a, 0x290, 0x295, 0x29b, 0x2a0, 0x2a6, 0x2ac, 0x2b1, 0x2b7, 0x2bd,
+ 0x2c2, 0x2c8, 0x2ce, 0x2d4, 0x2da, 0x2df, 0x2e5, 0x2eb, 0x2f1, 0x2f7,
+ 0x2fd, 0x303, 0x309, 0x30f, 0x315, 0x31c, 0x322, 0x328, 0x32e, 0x334,
+ 0x33b, 0x341, 0x347, 0x34d, 0x354, 0x35a, 0x361, 0x367, 0x36d, 0x374,
+ 0x37a, 0x381, 0x388, 0x38e, 0x395, 0x39b, 0x3a2, 0x3a9, 0x3b0, 0x3b6,
+ 0x3bd, 0x3c4, 0x3cb, 0x3d2, 0x3d8, 0x3df, 0x3e6, 0x3ed, 0x3f4, 0x3fb,
+ 0x402, 0x409, 0x411, 0x418, 0x41f, 0x426, 0x42d, 0x434, 0x43c, 0x443,
+ 0x44a, 0x452, 0x459, 0x460, 0x468, 0x46f, 0x477, 0x47e, 0x486, 0x48d,
+ 0x495, 0x49c, 0x4a4, 0x4ac, 0x4b3, 0x4bb, 0x4c3, 0x4cb, 0x4d3, 0x4da,
+ 0x4e2, 0x4ea, 0x4f2, 0x4fa, 0x502, 0x50a, 0x512, 0x51a, 0x522, 0x52a,
+ 0x532, 0x53a, 0x543, 0x54b, 0x553, 0x55b, 0x564, 0x56c, 0x574, 0x57d,
+ 0x585, 0x58d, 0x596, 0x59e, 0x5a7, 0x5af, 0x5b8, 0x5c1, 0x5c9, 0x5d2,
+ 0x5db, 0x5e3, 0x5ec, 0x5f5, 0x5fe, 0x606, 0x60f, 0x618, 0x621, 0x62a,
+ 0x633, 0x63c, 0x645, 0x64e, 0x657, 0x660, 0x669, 0x672, 0x67b, 0x685,
+ 0x68e, 0x697, 0x6a0, 0x6aa, 0x6b3, 0x6bd, 0x6c6, 0x6cf, 0x6d9, 0x6e2,
+ 0x6ec, 0x6f5, 0x6ff, 0x709, 0x712, 0x71c, 0x726, 0x72f, 0x739, 0x743,
+ 0x74d, 0x756, 0x760, 0x76a, 0x774, 0x77e, 0x788, 0x792, 0x79c, 0x7a6,
+ 0x7b0, 0x7ba, 0x7c4, 0x7cf, 0x7d9, 0x7e3, 0x7ed, 0x7f7, 0x802, 0x80c,
+ 0x816, 0x821, 0x82b, 0x836, 0x840, 0x84b, 0x855, 0x860, 0x86a, 0x875,
+ 0x880, 0x88a, 0x895, 0x8a0, 0x8ab, 0x8b5, 0x8c0, 0x8cb, 0x8d6, 0x8e1,
+ 0x8ec, 0x8f7, 0x902, 0x90d, 0x918, 0x923, 0x92e, 0x939, 0x944, 0x950,
+ 0x95b, 0x966, 0x971, 0x97d, 0x988, 0x993, 0x99f, 0x9aa, 0x9b6, 0x9c1,
+ 0x9cd, 0x9d8, 0x9e4, 0x9f0, 0x9fb, 0xa07, 0xa13, 0xa1e, 0xa2a, 0xa36,
+ 0xa42, 0xa4e, 0xa59, 0xa65, 0xa71, 0xa7d, 0xa89, 0xa95, 0xaa1, 0xaad,
+ 0xab9, 0xac6, 0xad2, 0xade, 0xaea, 0xaf6, 0xb03, 0xb0f, 0xb1b, 0xb28,
+ 0xb34, 0xb41, 0xb4d, 0xb5a, 0xb66, 0xb73, 0xb7f, 0xb8c, 0xb98, 0xba5,
+ 0xbb2, 0xbbf, 0xbcb, 0xbd8, 0xbe5, 0xbf2, 0xbff, 0xc0c, 0xc19, 0xc25,
+ 0xc32, 0xc40, 0xc4d, 0xc5a, 0xc67, 0xc74, 0xc81, 0xc8e, 0xc9c, 0xca9,
+ 0xcb6, 0xcc3, 0xcd1, 0xcde, 0xcec, 0xcf9, 0xd07, 0xd14, 0xd22, 0xd2f,
+ 0xd3d, 0xd4a, 0xd58, 0xd66, 0xd73, 0xd81, 0xd8f, 0xd9d, 0xdab, 0xdb8,
+ 0xdc6, 0xdd4, 0xde2, 0xdf0, 0xdfe, 0xe0c, 0xe1a, 0xe29, 0xe37, 0xe45,
+ 0xe53, 0xe61, 0xe70, 0xe7e, 0xe8c, 0xe9a, 0xea9, 0xeb7, 0xec6, 0xed4,
+ 0xee3, 0xef1, 0xf00, 0xf0e, 0xf1d, 0xf2c, 0xf3a, 0xf49, 0xf58, 0xf67,
+ 0xf75, 0xf84, 0xf93, 0xfa2, 0xfb1, 0xfc0, 0xfcf, 0xfde, 0xfed, 0xffc,
+ 0x100b, 0x101a, 0x102a, 0x1039, 0x1048, 0x1057, 0x1067, 0x1076, 0x1085,
+ 0x1095, 0x10a4, 0x10b4, 0x10c3, 0x10d3, 0x10e2, 0x10f2, 0x1101, 0x1111,
+ 0x1121, 0x1130, 0x1140, 0x1150, 0x1160, 0x116f, 0x117f, 0x118f, 0x119f,
+ 0x11af, 0x11bf, 0x11cf, 0x11df, 0x11ef, 0x11ff, 0x120f, 0x121f, 0x1230,
+ 0x1240, 0x1250, 0x1260, 0x1271, 0x1281, 0x1291, 0x12a2, 0x12b2, 0x12c3,
+ 0x12d3, 0x12e4, 0x12f4, 0x1305, 0x1316, 0x1326, 0x1337, 0x1348, 0x1359,
+ 0x1369, 0x137a, 0x138b, 0x139c, 0x13ad, 0x13be, 0x13cf, 0x13e0, 0x13f1,
+ 0x1402, 0x1413, 0x1424, 0x1435, 0x1446, 0x1458, 0x1469, 0x147a, 0x148b,
+ 0x149d, 0x14ae, 0x14c0, 0x14d1, 0x14e3, 0x14f4, 0x1506, 0x1517, 0x1529,
+ 0x153a, 0x154c, 0x155e, 0x156f, 0x1581, 0x1593, 0x15a5, 0x15b7, 0x15c9,
+ 0x15db, 0x15ec, 0x15fe, 0x1610, 0x1623, 0x1635, 0x1647, 0x1659, 0x166b,
+ 0x167d, 0x168f, 0x16a2, 0x16b4, 0x16c6, 0x16d9, 0x16eb, 0x16fe, 0x1710,
+ 0x1722, 0x1735, 0x1748, 0x175a, 0x176d, 0x177f, 0x1792, 0x17a5, 0x17b8,
+ 0x17ca, 0x17dd, 0x17f0, 0x1803, 0x1816, 0x1829, 0x183c, 0x184f, 0x1862,
+ 0x1875, 0x1888, 0x189b, 0x18ae, 0x18c1, 0x18d5, 0x18e8, 0x18fb, 0x190e,
+ 0x1922, 0x1935, 0x1949, 0x195c, 0x196f, 0x1983, 0x1996, 0x19aa, 0x19be,
+ 0x19d1, 0x19e5, 0x19f9, 0x1a0c, 0x1a20, 0x1a34, 0x1a48, 0x1a5c, 0x1a70,
+ 0x1a84, 0x1a97, 0x1aab, 0x1ac0, 0x1ad4, 0x1ae8, 0x1afc, 0x1b10, 0x1b24,
+ 0x1b38, 0x1b4d, 0x1b61, 0x1b75, 0x1b8a, 0x1b9e, 0x1bb2, 0x1bc7, 0x1bdb,
+ 0x1bf0, 0x1c04, 0x1c19, 0x1c2e, 0x1c42, 0x1c57, 0x1c6c, 0x1c80, 0x1c95,
+ 0x1caa, 0x1cbf, 0x1cd4, 0x1ce8, 0x1cfd, 0x1d12, 0x1d27, 0x1d3c, 0x1d51,
+ 0x1d67, 0x1d7c, 0x1d91, 0x1da6, 0x1dbb, 0x1dd1, 0x1de6, 0x1dfb, 0x1e10,
+ 0x1e26, 0x1e3b, 0x1e51, 0x1e66, 0x1e7c, 0x1e91, 0x1ea7, 0x1ebd, 0x1ed2,
+ 0x1ee8, 0x1efe, 0x1f13, 0x1f29, 0x1f3f, 0x1f55, 0x1f6b, 0x1f81, 0x1f96,
+ 0x1fac, 0x1fc2, 0x1fd9, 0x1fef, 0x2005, 0x201b, 0x2031, 0x2047, 0x205d,
+ 0x2074, 0x208a, 0x20a0, 0x20b7, 0x20cd, 0x20e4, 0x20fa, 0x2111, 0x2127,
+ 0x213e, 0x2154, 0x216b, 0x2182, 0x2198, 0x21af, 0x21c6, 0x21dd, 0x21f3,
+ 0x220a, 0x2221, 0x2238, 0x224f, 0x2266, 0x227d, 0x2294, 0x22ab, 0x22c2,
+ 0x22da, 0x22f1, 0x2308, 0x231f, 0x2337, 0x234e, 0x2365, 0x237d, 0x2394,
+ 0x23ac, 0x23c3, 0x23db, 0x23f2, 0x240a, 0x2421, 0x2439, 0x2451, 0x2469,
+ 0x2480, 0x2498, 0x24b0, 0x24c8, 0x24e0, 0x24f8, 0x2510, 0x2528, 0x2540,
+ 0x2558, 0x2570, 0x2588, 0x25a0, 0x25b8, 0x25d0, 0x25e9, 0x2601, 0x2619,
+ 0x2632, 0x264a, 0x2663, 0x267b, 0x2693, 0x26ac, 0x26c5, 0x26dd, 0x26f6,
+ 0x270e, 0x2727, 0x2740, 0x2759, 0x2771, 0x278a, 0x27a3, 0x27bc, 0x27d5,
+ 0x27ee, 0x2807, 0x2820, 0x2839, 0x2852, 0x286b, 0x2884, 0x289e, 0x28b7,
+ 0x28d0, 0x28e9, 0x2903, 0x291c, 0x2936, 0x294f, 0x2968, 0x2982, 0x299c,
+ 0x29b5, 0x29cf, 0x29e8, 0x2a02, 0x2a1c, 0x2a35, 0x2a4f, 0x2a69, 0x2a83,
+ 0x2a9d, 0x2ab7, 0x2ad1, 0x2aeb, 0x2b05, 0x2b1f, 0x2b39, 0x2b53, 0x2b6d,
+ 0x2b87, 0x2ba1, 0x2bbc, 0x2bd6, 0x2bf0, 0x2c0b, 0x2c25, 0x2c3f, 0x2c5a,
+ 0x2c74, 0x2c8f, 0x2ca9, 0x2cc4, 0x2cdf, 0x2cf9, 0x2d14, 0x2d2f, 0x2d49,
+ 0x2d64, 0x2d7f, 0x2d9a, 0x2db5, 0x2dd0, 0x2deb, 0x2e06, 0x2e21, 0x2e3c,
+ 0x2e57, 0x2e72, 0x2e8d, 0x2ea8, 0x2ec4, 0x2edf, 0x2efa, 0x2f16, 0x2f31,
+ 0x2f4c, 0x2f68, 0x2f83, 0x2f9f, 0x2fba, 0x2fd6, 0x2ff1, 0x300d, 0x3029,
+ 0x3044, 0x3060, 0x307c, 0x3098, 0x30b4, 0x30d0, 0x30eb, 0x3107, 0x3123,
+ 0x313f, 0x315b, 0x3178, 0x3194, 0x31b0, 0x31cc, 0x31e8, 0x3205, 0x3221,
+ 0x323d, 0x325a, 0x3276, 0x3292, 0x32af, 0x32cb, 0x32e8, 0x3304, 0x3321,
+ 0x333e, 0x335a, 0x3377, 0x3394, 0x33b1, 0x33cd, 0x33ea, 0x3407, 0x3424,
+ 0x3441, 0x345e, 0x347b, 0x3498, 0x34b5, 0x34d2, 0x34ef, 0x350d, 0x352a,
+ 0x3547, 0x3564, 0x3582, 0x359f, 0x35bc, 0x35da, 0x35f7, 0x3615, 0x3632,
+ 0x3650, 0x366e, 0x368b, 0x36a9, 0x36c7, 0x36e4, 0x3702, 0x3720, 0x373e,
+ 0x375c, 0x377a, 0x3798, 0x37b6, 0x37d4, 0x37f2, 0x3810, 0x382e, 0x384c,
+ 0x386a, 0x3888, 0x38a7, 0x38c5, 0x38e3, 0x3902, 0x3920, 0x393f, 0x395d,
+ 0x397c, 0x399a, 0x39b9, 0x39d7, 0x39f6, 0x3a15, 0x3a33, 0x3a52, 0x3a71,
+ 0x3a90, 0x3aaf, 0x3acd, 0x3aec, 0x3b0b, 0x3b2a, 0x3b49, 0x3b68, 0x3b87,
+ 0x3ba7, 0x3bc6, 0x3be5, 0x3c04, 0x3c24, 0x3c43, 0x3c62, 0x3c82, 0x3ca1,
+ 0x3cc0, 0x3ce0, 0x3cff, 0x3d1f, 0x3d3f, 0x3d5e, 0x3d7e, 0x3d9e, 0x3dbd,
+ 0x3ddd, 0x3dfd, 0x3e1d, 0x3e3d, 0x3e5d, 0x3e7c, 0x3e9c, 0x3ebc, 0x3edc,
+ 0x3efd, 0x3f1d, 0x3f3d, 0x3f5d, 0x3f7d, 0x3f9e, 0x3fbe, 0x3fde, 0x3fff,
+ 0x0,
+ /* table descriptor */
+ 0xffffe4e1, 0xf,
+ /* table length */
+ 0x402,
+ /* table data */
+ 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x2, 0x2, 0x2,
+ 0x2, 0x2, 0x3, 0x3, 0x3, 0x4, 0x4, 0x4, 0x4, 0x5, 0x5, 0x6, 0x6, 0x6,
+ 0x7, 0x7, 0x8, 0x8, 0x9, 0x9, 0xa, 0xa, 0xb, 0xb, 0xc, 0xc, 0xd, 0xe,
+ 0xe, 0xf, 0x10, 0x10, 0x11, 0x12, 0x12, 0x13, 0x14, 0x15, 0x15, 0x16,
+ 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1d, 0x1e, 0x1f, 0x20, 0x22,
+ 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
+ 0x31, 0x32, 0x33, 0x35, 0x36, 0x37, 0x39, 0x3a, 0x3c, 0x3d, 0x3f, 0x40,
+ 0x42, 0x43, 0x45, 0x47, 0x48, 0x4a, 0x4b, 0x4d, 0x4f, 0x51, 0x52, 0x54,
+ 0x56, 0x58, 0x5a, 0x5b, 0x5d, 0x5f, 0x61, 0x63, 0x65, 0x67, 0x69, 0x6b,
+ 0x6d, 0x6f, 0x71, 0x73, 0x76, 0x78, 0x7a, 0x7c, 0x7e, 0x81, 0x83, 0x85,
+ 0x88, 0x8a, 0x8c, 0x8f, 0x91, 0x94, 0x96, 0x99, 0x9b, 0x9e, 0xa0, 0xa3,
+ 0xa6, 0xa8, 0xab, 0xae, 0xb0, 0xb3, 0xb6, 0xb9, 0xbb, 0xbe, 0xc1, 0xc4,
+ 0xc7, 0xca, 0xcd, 0xd0, 0xd3, 0xd6, 0xd9, 0xdc, 0xdf, 0xe2, 0xe6, 0xe9,
+ 0xec, 0xef, 0xf3, 0xf6, 0xf9, 0xfd, 0x100, 0x103, 0x107, 0x10a, 0x10e,
+ 0x111, 0x115, 0x118, 0x11c, 0x120, 0x123, 0x127, 0x12b, 0x12e, 0x132,
+ 0x136, 0x13a, 0x13e, 0x142, 0x145, 0x149, 0x14d, 0x151, 0x155, 0x159,
+ 0x15d, 0x162, 0x166, 0x16a, 0x16e, 0x172, 0x176, 0x17b, 0x17f, 0x183,
+ 0x188, 0x18c, 0x190, 0x195, 0x199, 0x19e, 0x1a2, 0x1a7, 0x1ab, 0x1b0,
+ 0x1b5, 0x1b9, 0x1be, 0x1c3, 0x1c7, 0x1cc, 0x1d1, 0x1d6, 0x1db, 0x1e0,
+ 0x1e4, 0x1e9, 0x1ee, 0x1f3, 0x1f8, 0x1fd, 0x203, 0x208, 0x20d, 0x212,
+ 0x217, 0x21c, 0x222, 0x227, 0x22c, 0x232, 0x237, 0x23d, 0x242, 0x247,
+ 0x24d, 0x253, 0x258, 0x25e, 0x263, 0x269, 0x26f, 0x274, 0x27a, 0x280,
+ 0x286, 0x28c, 0x291, 0x297, 0x29d, 0x2a3, 0x2a9, 0x2af, 0x2b5, 0x2bb,
+ 0x2c2, 0x2c8, 0x2ce, 0x2d4, 0x2da, 0x2e1, 0x2e7, 0x2ed, 0x2f4, 0x2fa,
+ 0x301, 0x307, 0x30e, 0x314, 0x31b, 0x321, 0x328, 0x32f, 0x335, 0x33c,
+ 0x343, 0x349, 0x350, 0x357, 0x35e, 0x365, 0x36c, 0x373, 0x37a, 0x381,
+ 0x388, 0x38f, 0x396, 0x39d, 0x3a5, 0x3ac, 0x3b3, 0x3ba, 0x3c2, 0x3c9,
+ 0x3d1, 0x3d8, 0x3e0, 0x3e7, 0x3ef, 0x3f6, 0x3fe, 0x405, 0x40d, 0x415,
+ 0x41c, 0x424, 0x42c, 0x434, 0x43c, 0x444, 0x44c, 0x454, 0x45c, 0x464,
+ 0x46c, 0x474, 0x47c, 0x484, 0x48c, 0x495, 0x49d, 0x4a5, 0x4ad, 0x4b6,
+ 0x4be, 0x4c7, 0x4cf, 0x4d8, 0x4e0, 0x4e9, 0x4f1, 0x4fa, 0x503, 0x50b,
+ 0x514, 0x51d, 0x526, 0x52f, 0x538, 0x540, 0x549, 0x552, 0x55b, 0x565,
+ 0x56e, 0x577, 0x580, 0x589, 0x592, 0x59c, 0x5a5, 0x5ae, 0x5b8, 0x5c1,
+ 0x5cb, 0x5d4, 0x5de, 0x5e7, 0x5f1, 0x5fa, 0x604, 0x60e, 0x617, 0x621,
+ 0x62b, 0x635, 0x63f, 0x649, 0x653, 0x65c, 0x666, 0x671, 0x67b, 0x685,
+ 0x68f, 0x699, 0x6a3, 0x6ae, 0x6b8, 0x6c2, 0x6cd, 0x6d7, 0x6e2, 0x6ec,
+ 0x6f7, 0x701, 0x70c, 0x716, 0x721, 0x72c, 0x736, 0x741, 0x74c, 0x757,
+ 0x762, 0x76d, 0x778, 0x783, 0x78e, 0x799, 0x7a4, 0x7af, 0x7ba, 0x7c5,
+ 0x7d1, 0x7dc, 0x7e7, 0x7f3, 0x7fe, 0x809, 0x815, 0x820, 0x82c, 0x838,
+ 0x843, 0x84f, 0x85b, 0x866, 0x872, 0x87e, 0x88a, 0x896, 0x8a2, 0x8ae,
+ 0x8ba, 0x8c6, 0x8d2, 0x8de, 0x8ea, 0x8f6, 0x902, 0x90f, 0x91b, 0x927,
+ 0x934, 0x940, 0x94d, 0x959, 0x966, 0x972, 0x97f, 0x98b, 0x998, 0x9a5,
+ 0x9b2, 0x9be, 0x9cb, 0x9d8, 0x9e5, 0x9f2, 0x9ff, 0xa0c, 0xa19, 0xa26,
+ 0xa33, 0xa41, 0xa4e, 0xa5b, 0xa68, 0xa76, 0xa83, 0xa90, 0xa9e, 0xaab,
+ 0xab9, 0xac7, 0xad4, 0xae2, 0xaf0, 0xafd, 0xb0b, 0xb19, 0xb27, 0xb35,
+ 0xb43, 0xb50, 0xb5f, 0xb6d, 0xb7b, 0xb89, 0xb97, 0xba5, 0xbb3, 0xbc2,
+ 0xbd0, 0xbde, 0xbed, 0xbfb, 0xc0a, 0xc18, 0xc27, 0xc35, 0xc44, 0xc53,
+ 0xc61, 0xc70, 0xc7f, 0xc8e, 0xc9d, 0xcac, 0xcbb, 0xcca, 0xcd9, 0xce8,
+ 0xcf7, 0xd06, 0xd15, 0xd25, 0xd34, 0xd43, 0xd52, 0xd62, 0xd71, 0xd81,
+ 0xd90, 0xda0, 0xdb0, 0xdbf, 0xdcf, 0xddf, 0xdee, 0xdfe, 0xe0e, 0xe1e,
+ 0xe2e, 0xe3e, 0xe4e, 0xe5e, 0xe6e, 0xe7e, 0xe8e, 0xe9f, 0xeaf, 0xebf,
+ 0xed0, 0xee0, 0xef0, 0xf01, 0xf11, 0xf22, 0xf32, 0xf43, 0xf54, 0xf65,
+ 0xf75, 0xf86, 0xf97, 0xfa8, 0xfb9, 0xfca, 0xfdb, 0xfec, 0xffd, 0x100e,
+ 0x101f, 0x1030, 0x1042, 0x1053, 0x1064, 0x1076, 0x1087, 0x1099, 0x10aa,
+ 0x10bc, 0x10cd, 0x10df, 0x10f1, 0x1102, 0x1114, 0x1126, 0x1138, 0x114a,
+ 0x115c, 0x116e, 0x1180, 0x1192, 0x11a4, 0x11b6, 0x11c8, 0x11da, 0x11ed,
+ 0x11ff, 0x1211, 0x1224, 0x1236, 0x1249, 0x125b, 0x126e, 0x1280, 0x1293,
+ 0x12a6, 0x12b8, 0x12cb, 0x12de, 0x12f1, 0x1304, 0x1317, 0x132a, 0x133d,
+ 0x1350, 0x1363, 0x1376, 0x1389, 0x139d, 0x13b0, 0x13c3, 0x13d7, 0x13ea,
+ 0x13fe, 0x1411, 0x1425, 0x1438, 0x144c, 0x1460, 0x1473, 0x1487, 0x149b,
+ 0x14af, 0x14c3, 0x14d7, 0x14eb, 0x14ff, 0x1513, 0x1527, 0x153b, 0x154f,
+ 0x1564, 0x1578, 0x158c, 0x15a1, 0x15b5, 0x15ca, 0x15de, 0x15f3, 0x1607,
+ 0x161c, 0x1631, 0x1645, 0x165a, 0x166f, 0x1684, 0x1699, 0x16ae, 0x16c3,
+ 0x16d8, 0x16ed, 0x1702, 0x1717, 0x172c, 0x1742, 0x1757, 0x176c, 0x1782,
+ 0x1797, 0x17ad, 0x17c2, 0x17d8, 0x17ee, 0x1803, 0x1819, 0x182f, 0x1845,
+ 0x185a, 0x1870, 0x1886, 0x189c, 0x18b2, 0x18c8, 0x18de, 0x18f5, 0x190b,
+ 0x1921, 0x1937, 0x194e, 0x1964, 0x197b, 0x1991, 0x19a8, 0x19be, 0x19d5,
+ 0x19eb, 0x1a02, 0x1a19, 0x1a30, 0x1a47, 0x1a5d, 0x1a74, 0x1a8b, 0x1aa2,
+ 0x1ab9, 0x1ad1, 0x1ae8, 0x1aff, 0x1b16, 0x1b2d, 0x1b45, 0x1b5c, 0x1b74,
+ 0x1b8b, 0x1ba3, 0x1bba, 0x1bd2, 0x1bea, 0x1c01, 0x1c19, 0x1c31, 0x1c49,
+ 0x1c61, 0x1c78, 0x1c90, 0x1ca8, 0x1cc1, 0x1cd9, 0x1cf1, 0x1d09, 0x1d21,
+ 0x1d3a, 0x1d52, 0x1d6a, 0x1d83, 0x1d9b, 0x1db4, 0x1dcc, 0x1de5, 0x1dfe,
+ 0x1e17, 0x1e2f, 0x1e48, 0x1e61, 0x1e7a, 0x1e93, 0x1eac, 0x1ec5, 0x1ede,
+ 0x1ef7, 0x1f10, 0x1f2a, 0x1f43, 0x1f5c, 0x1f76, 0x1f8f, 0x1fa8, 0x1fc2,
+ 0x1fdc, 0x1ff5, 0x200f, 0x2029, 0x2042, 0x205c, 0x2076, 0x2090, 0x20aa,
+ 0x20c4, 0x20de, 0x20f8, 0x2112, 0x212c, 0x2146, 0x2161, 0x217b, 0x2195,
+ 0x21b0, 0x21ca, 0x21e5, 0x21ff, 0x221a, 0x2234, 0x224f, 0x226a, 0x2285,
+ 0x22a0, 0x22ba, 0x22d5, 0x22f0, 0x230b, 0x2326, 0x2342, 0x235d, 0x2378,
+ 0x2393, 0x23af, 0x23ca, 0x23e5, 0x2401, 0x241c, 0x2438, 0x2453, 0x246f,
+ 0x248b, 0x24a7, 0x24c2, 0x24de, 0x24fa, 0x2516, 0x2532, 0x254e, 0x256a,
+ 0x2586, 0x25a2, 0x25bf, 0x25db, 0x25f7, 0x2614, 0x2630, 0x264c, 0x2669,
+ 0x2685, 0x26a2, 0x26bf, 0x26db, 0x26f8, 0x2715, 0x2732, 0x274f, 0x276c,
+ 0x2789, 0x27a6, 0x27c3, 0x27e0, 0x27fd, 0x281a, 0x2838, 0x2855, 0x2872,
+ 0x2890, 0x28ad, 0x28cb, 0x28e8, 0x2906, 0x2924, 0x2942, 0x295f, 0x297d,
+ 0x299b, 0x29b9, 0x29d7, 0x29f5, 0x2a13, 0x2a31, 0x2a4f, 0x2a6d, 0x2a8c,
+ 0x2aaa, 0x2ac8, 0x2ae7, 0x2b05, 0x2b24, 0x2b42, 0x2b61, 0x2b80, 0x2b9e,
+ 0x2bbd, 0x2bdc, 0x2bfb, 0x2c1a, 0x2c39, 0x2c58, 0x2c77, 0x2c96, 0x2cb5,
+ 0x2cd4, 0x2cf3, 0x2d13, 0x2d32, 0x2d51, 0x2d71, 0x2d90, 0x2db0, 0x2dd0,
+ 0x2def, 0x2e0f, 0x2e2f, 0x2e4f, 0x2e6e, 0x2e8e, 0x2eae, 0x2ece, 0x2eee,
+ 0x2f0e, 0x2f2f, 0x2f4f, 0x2f6f, 0x2f8f, 0x2fb0, 0x2fd0, 0x2ff0, 0x3011,
+ 0x3032, 0x3052, 0x3073, 0x3093, 0x30b4, 0x30d5, 0x30f6, 0x3117, 0x3138,
+ 0x3159, 0x317a, 0x319b, 0x31bc, 0x31dd, 0x31fe, 0x3220, 0x3241, 0x3263,
+ 0x3284, 0x32a6, 0x32c7, 0x32e9, 0x330a, 0x332c, 0x334e, 0x3370, 0x3392,
+ 0x33b3, 0x33d5, 0x33f7, 0x3419, 0x343c, 0x345e, 0x3480, 0x34a2, 0x34c5,
+ 0x34e7, 0x3509, 0x352c, 0x354e, 0x3571, 0x3594, 0x35b6, 0x35d9, 0x35fc,
+ 0x361f, 0x3641, 0x3664, 0x3687, 0x36aa, 0x36cd, 0x36f1, 0x3714, 0x3737,
+ 0x375a, 0x377e, 0x37a1, 0x37c5, 0x37e8, 0x380c, 0x382f, 0x3853, 0x3876,
+ 0x389a, 0x38be, 0x38e2, 0x3906, 0x392a, 0x394e, 0x3972, 0x3996, 0x39ba,
+ 0x39de, 0x3a03, 0x3a27, 0x3a4b, 0x3a70, 0x3a94, 0x3ab9, 0x3add, 0x3b02,
+ 0x3b27, 0x3b4b, 0x3b70, 0x3b95, 0x3bba, 0x3bdf, 0x3c04, 0x3c29, 0x3c4e,
+ 0x3c73, 0x3c98, 0x3cbe, 0x3ce3, 0x3d08, 0x3d2e, 0x3d53, 0x3d79, 0x3d9e,
+ 0x3dc4, 0x3dea, 0x3e0f, 0x3e35, 0x3e5b, 0x3e81, 0x3ea7, 0x3ecd, 0x3ef3,
+ 0x3f19, 0x3f3f, 0x3f65, 0x3f8b, 0x3fb2, 0x3fd8, 0x3fff, 0x0,
+ /* table descriptor */
+ 0xfff0e8e1, 0xf,
+ /* table length */
+ 0x402,
+ /* table data */
+ 0x3, 0x0, 0xea8, 0x12aa, 0x1500, 0x16ab, 0x1815, 0x1900, 0x1a0b,
+ 0x1aab, 0x1b60, 0x1c15, 0x1c85, 0x1d00, 0x1d86, 0x1e0b, 0x1e58, 0x1eab,
+ 0x1f03, 0x1f60, 0x1fc3, 0x2015, 0x204c, 0x2085, 0x20c2, 0x2100, 0x2142,
+ 0x2186, 0x21cc, 0x220b, 0x2231, 0x2258, 0x2281, 0x22ab, 0x22d6, 0x2303,
+ 0x2331, 0x2360, 0x2391, 0x23c3, 0x23f6, 0x2415, 0x2430, 0x244c, 0x2468,
+ 0x2485, 0x24a3, 0x24c2, 0x24e1, 0x2500, 0x2521, 0x2542, 0x2563, 0x2586,
+ 0x25a9, 0x25cc, 0x25f1, 0x260b, 0x261e, 0x2631, 0x2644, 0x2658, 0x266c,
+ 0x2681, 0x2696, 0x26ab, 0x26c0, 0x26d6, 0x26ec, 0x2703, 0x271a, 0x2731,
+ 0x2748, 0x2760, 0x2779, 0x2791, 0x27aa, 0x27c3, 0x27dd, 0x27f6, 0x2808,
+ 0x2815, 0x2823, 0x2830, 0x283e, 0x284c, 0x285a, 0x2868, 0x2877, 0x2885,
+ 0x2894, 0x28a3, 0x28b2, 0x28c2, 0x28d1, 0x28e1, 0x28f0, 0x2900, 0x2910,
+ 0x2921, 0x2931, 0x2942, 0x2952, 0x2963, 0x2974, 0x2986, 0x2997, 0x29a9,
+ 0x29bb, 0x29cc, 0x29df, 0x29f1, 0x2a01, 0x2a0b, 0x2a14, 0x2a1e, 0x2a27,
+ 0x2a31, 0x2a3a, 0x2a44, 0x2a4e, 0x2a58, 0x2a62, 0x2a6c, 0x2a76, 0x2a81,
+ 0x2a8b, 0x2a96, 0x2aa0, 0x2aab, 0x2ab6, 0x2ac0, 0x2acb, 0x2ad6, 0x2ae1,
+ 0x2aec, 0x2af8, 0x2b03, 0x2b0e, 0x2b1a, 0x2b25, 0x2b31, 0x2b3d, 0x2b48,
+ 0x2b54, 0x2b60, 0x2b6c, 0x2b79, 0x2b85, 0x2b91, 0x2b9d, 0x2baa, 0x2bb6,
+ 0x2bc3, 0x2bd0, 0x2bdd, 0x2bea, 0x2bf6, 0x2c02, 0x2c08, 0x2c0f, 0x2c15,
+ 0x2c1c, 0x2c23, 0x2c2a, 0x2c30, 0x2c37, 0x2c3e, 0x2c45, 0x2c4c, 0x2c53,
+ 0x2c5a, 0x2c61, 0x2c68, 0x2c70, 0x2c77, 0x2c7e, 0x2c85, 0x2c8d, 0x2c94,
+ 0x2c9c, 0x2ca3, 0x2cab, 0x2cb2, 0x2cba, 0x2cc2, 0x2cc9, 0x2cd1, 0x2cd9,
+ 0x2ce1, 0x2ce8, 0x2cf0, 0x2cf8, 0x2d00, 0x2d08, 0x2d10, 0x2d18, 0x2d21,
+ 0x2d29, 0x2d31, 0x2d39, 0x2d42, 0x2d4a, 0x2d52, 0x2d5b, 0x2d63, 0x2d6c,
+ 0x2d74, 0x2d7d, 0x2d86, 0x2d8e, 0x2d97, 0x2da0, 0x2da9, 0x2db2, 0x2dbb,
+ 0x2dc3, 0x2dcc, 0x2dd5, 0x2ddf, 0x2de8, 0x2df1, 0x2dfa, 0x2e01, 0x2e06,
+ 0x2e0b, 0x2e0f, 0x2e14, 0x2e19, 0x2e1e, 0x2e22, 0x2e27, 0x2e2c, 0x2e31,
+ 0x2e36, 0x2e3a, 0x2e3f, 0x2e44, 0x2e49, 0x2e4e, 0x2e53, 0x2e58, 0x2e5d,
+ 0x2e62, 0x2e67, 0x2e6c, 0x2e71, 0x2e76, 0x2e7c, 0x2e81, 0x2e86, 0x2e8b,
+ 0x2e90, 0x2e96, 0x2e9b, 0x2ea0, 0x2ea6, 0x2eab, 0x2eb0, 0x2eb6, 0x2ebb,
+ 0x2ec0, 0x2ec6, 0x2ecb, 0x2ed1, 0x2ed6, 0x2edc, 0x2ee1, 0x2ee7, 0x2eec,
+ 0x2ef2, 0x2ef8, 0x2efd, 0x2f03, 0x2f09, 0x2f0e, 0x2f14, 0x2f1a, 0x2f20,
+ 0x2f25, 0x2f2b, 0x2f31, 0x2f37, 0x2f3d, 0x2f43, 0x2f48, 0x2f4e, 0x2f54,
+ 0x2f5a, 0x2f60, 0x2f66, 0x2f6c, 0x2f72, 0x2f79, 0x2f7f, 0x2f85, 0x2f8b,
+ 0x2f91, 0x2f97, 0x2f9d, 0x2fa4, 0x2faa, 0x2fb0, 0x2fb6, 0x2fbd, 0x2fc3,
+ 0x2fc9, 0x2fd0, 0x2fd6, 0x2fdd, 0x2fe3, 0x2fea, 0x2ff0, 0x2ff6, 0x2ffd,
+ 0x3002, 0x3005, 0x3008, 0x300b, 0x300f, 0x3012, 0x3015, 0x3019, 0x301c,
+ 0x301f, 0x3023, 0x3026, 0x302a, 0x302d, 0x3030, 0x3034, 0x3037, 0x303b,
+ 0x303e, 0x3042, 0x3045, 0x3049, 0x304c, 0x3050, 0x3053, 0x3057, 0x305a,
+ 0x305e, 0x3061, 0x3065, 0x3068, 0x306c, 0x3070, 0x3073, 0x3077, 0x307b,
+ 0x307e, 0x3082, 0x3085, 0x3089, 0x308d, 0x3091, 0x3094, 0x3098, 0x309c,
+ 0x309f, 0x30a3, 0x30a7, 0x30ab, 0x30ae, 0x30b2, 0x30b6, 0x30ba, 0x30be,
+ 0x30c2, 0x30c5, 0x30c9, 0x30cd, 0x30d1, 0x30d5, 0x30d9, 0x30dd, 0x30e1,
+ 0x30e4, 0x30e8, 0x30ec, 0x30f0, 0x30f4, 0x30f8, 0x30fc, 0x3100, 0x3104,
+ 0x3108, 0x310c, 0x3110, 0x3114, 0x3118, 0x311d, 0x3121, 0x3125, 0x3129,
+ 0x312d, 0x3131, 0x3135, 0x3139, 0x313d, 0x3142, 0x3146, 0x314a, 0x314e,
+ 0x3152, 0x3157, 0x315b, 0x315f, 0x3163, 0x3168, 0x316c, 0x3170, 0x3174,
+ 0x3179, 0x317d, 0x3181, 0x3186, 0x318a, 0x318e, 0x3193, 0x3197, 0x319c,
+ 0x31a0, 0x31a4, 0x31a9, 0x31ad, 0x31b2, 0x31b6, 0x31bb, 0x31bf, 0x31c3,
+ 0x31c8, 0x31cc, 0x31d1, 0x31d5, 0x31da, 0x31df, 0x31e3, 0x31e8, 0x31ec,
+ 0x31f1, 0x31f5, 0x31fa, 0x31ff, 0x3201, 0x3204, 0x3206, 0x3208, 0x320b,
+ 0x320d, 0x320f, 0x3212, 0x3214, 0x3216, 0x3219, 0x321b, 0x321e, 0x3220,
+ 0x3222, 0x3225, 0x3227, 0x3229, 0x322c, 0x322e, 0x3231, 0x3233, 0x3236,
+ 0x3238, 0x323a, 0x323d, 0x323f, 0x3242, 0x3244, 0x3247, 0x3249, 0x324c,
+ 0x324e, 0x3251, 0x3253, 0x3256, 0x3258, 0x325b, 0x325d, 0x3260, 0x3262,
+ 0x3265, 0x3267, 0x326a, 0x326c, 0x326f, 0x3271, 0x3274, 0x3276, 0x3279,
+ 0x327c, 0x327e, 0x3281, 0x3283, 0x3286, 0x3289, 0x328b, 0x328e, 0x3290,
+ 0x3293, 0x3296, 0x3298, 0x329b, 0x329e, 0x32a0, 0x32a3, 0x32a6, 0x32a8,
+ 0x32ab, 0x32ae, 0x32b0, 0x32b3, 0x32b6, 0x32b8, 0x32bb, 0x32be, 0x32c1,
+ 0x32c4, 0x32c6, 0x32c9, 0x32cc, 0x32cf, 0x32d2, 0x32d5, 0x32d8, 0x32da,
+ 0x32dd, 0x32e0, 0x32e3, 0x32e6, 0x32e9, 0x32ec, 0x32ef, 0x32f2, 0x32f6,
+ 0x32f9, 0x32fc, 0x32ff, 0x3302, 0x3305, 0x3308, 0x330c, 0x330f, 0x3312,
+ 0x3315, 0x3318, 0x331c, 0x331f, 0x3322, 0x3326, 0x3329, 0x332c, 0x3330,
+ 0x3333, 0x3337, 0x333a, 0x333e, 0x3341, 0x3345, 0x3348, 0x334c, 0x334f,
+ 0x3353, 0x3356, 0x335a, 0x335e, 0x3361, 0x3365, 0x3369, 0x336c, 0x3370,
+ 0x3374, 0x3378, 0x337c, 0x337f, 0x3383, 0x3387, 0x338b, 0x338f, 0x3393,
+ 0x3397, 0x339b, 0x339f, 0x33a3, 0x33a7, 0x33ab, 0x33af, 0x33b3, 0x33b7,
+ 0x33bb, 0x33bf, 0x33c4, 0x33c8, 0x33cc, 0x33d0, 0x33d5, 0x33d9, 0x33dd,
+ 0x33e2, 0x33e6, 0x33eb, 0x33ef, 0x33f3, 0x33f8, 0x33fc, 0x3400, 0x3402,
+ 0x3405, 0x3407, 0x3409, 0x340c, 0x340e, 0x3410, 0x3413, 0x3415, 0x3418,
+ 0x341a, 0x341c, 0x341f, 0x3421, 0x3424, 0x3426, 0x3429, 0x342b, 0x342e,
+ 0x3430, 0x3433, 0x3435, 0x3438, 0x343a, 0x343d, 0x3440, 0x3442, 0x3445,
+ 0x3448, 0x344a, 0x344d, 0x3450, 0x3452, 0x3455, 0x3458, 0x345b, 0x345d,
+ 0x3460, 0x3463, 0x3466, 0x3469, 0x346b, 0x346e, 0x3471, 0x3474, 0x3477,
+ 0x347a, 0x347d, 0x3480, 0x3483, 0x3486, 0x3489, 0x348c, 0x348f, 0x3492,
+ 0x3495, 0x3498, 0x349b, 0x349e, 0x34a2, 0x34a5, 0x34a8, 0x34ab, 0x34ae,
+ 0x34b2, 0x34b5, 0x34b8, 0x34bb, 0x34bf, 0x34c2, 0x34c5, 0x34c9, 0x34cc,
+ 0x34cf, 0x34d3, 0x34d6, 0x34da, 0x34dd, 0x34e1, 0x34e4, 0x34e8, 0x34eb,
+ 0x34ef, 0x34f2, 0x34f6, 0x34fa, 0x34fd, 0x3501, 0x3505, 0x3508, 0x350c,
+ 0x3510, 0x3514, 0x3517, 0x351b, 0x351f, 0x3523, 0x3527, 0x352b, 0x352f,
+ 0x3532, 0x3536, 0x353a, 0x353e, 0x3542, 0x3546, 0x354b, 0x354f, 0x3553,
+ 0x3557, 0x355b, 0x355f, 0x3563, 0x3568, 0x356c, 0x3570, 0x3574, 0x3579,
+ 0x357d, 0x3581, 0x3586, 0x358a, 0x358f, 0x3593, 0x3598, 0x359c, 0x35a1,
+ 0x35a5, 0x35aa, 0x35ae, 0x35b3, 0x35b8, 0x35bc, 0x35c1, 0x35c6, 0x35cb,
+ 0x35cf, 0x35d4, 0x35d9, 0x35de, 0x35e3, 0x35e8, 0x35ed, 0x35f2, 0x35f7,
+ 0x35fc, 0x3600, 0x3603, 0x3605, 0x3608, 0x360a, 0x360d, 0x3610, 0x3612,
+ 0x3615, 0x3618, 0x361a, 0x361d, 0x3620, 0x3622, 0x3625, 0x3628, 0x362b,
+ 0x362d, 0x3630, 0x3633, 0x3636, 0x3639, 0x363b, 0x363e, 0x3641, 0x3644,
+ 0x3647, 0x364a, 0x364d, 0x3650, 0x3653, 0x3656, 0x3659, 0x365c, 0x365f,
+ 0x3662, 0x3665, 0x3668, 0x366b, 0x366e, 0x3672, 0x3675, 0x3678, 0x367b,
+ 0x367e, 0x3682, 0x3685, 0x3688, 0x368b, 0x368f, 0x3692, 0x3695, 0x3699,
+ 0x369c, 0x36a0, 0x36a3, 0x36a6, 0x36aa, 0x36ad, 0x36b1, 0x36b4, 0x36b8,
+ 0x36bb, 0x36bf, 0x36c3, 0x36c6, 0x36ca, 0x36cd, 0x36d1, 0x36d5, 0x36d9,
+ 0x36dc, 0x36e0, 0x36e4, 0x36e8, 0x36eb, 0x36ef, 0x36f3, 0x36f7, 0x36fb,
+ 0x36ff, 0x3703, 0x3707, 0x370b, 0x370f, 0x3713, 0x3717, 0x371b, 0x371f,
+ 0x3723, 0x3727, 0x372b, 0x372f, 0x3734, 0x3738, 0x373c, 0x3740, 0x3745,
+ 0x3749, 0x374d, 0x3752, 0x3756, 0x375b, 0x375f, 0x3764, 0x3768, 0x376d,
+ 0x3771, 0x3776, 0x377a, 0x377f, 0x3783, 0x3788, 0x378d, 0x3792, 0x3796,
+ 0x379b, 0x37a0, 0x37a5, 0x37aa, 0x37ae, 0x37b3, 0x37b8, 0x37bd, 0x37c2,
+ 0x37c7, 0x37cc, 0x37d1, 0x37d6, 0x37dc, 0x37e1, 0x37e6, 0x37eb, 0x37f0,
+ 0x37f6, 0x37fb, 0x3800, 0x3802, 0x3805, 0x3808, 0x380b, 0x380d, 0x3810,
+ 0x3813, 0x3816, 0x3818, 0x381b, 0x381e, 0x3821, 0x3824, 0x3827, 0x382a,
+ 0x382c, 0x382f, 0x3832, 0x3835, 0x3838, 0x383b, 0x383e, 0x3841, 0x3844,
+ 0x3847, 0x384a, 0x384d, 0x3851, 0x3854, 0x3857, 0x385a, 0x385d, 0x3860,
+ 0x3864, 0x3867, 0x386a, 0x386d, 0x3870, 0x3874, 0x3877, 0x387a, 0x387e,
+ 0x3881, 0x3885, 0x3888, 0x388b, 0x388f, 0x3892, 0x3896, 0x3899, 0x389d,
+ 0x38a0, 0x38a4, 0x38a7, 0x38ab, 0x38af, 0x38b2, 0x38b6, 0x38ba, 0x38bd,
+ 0x38c1, 0x38c5, 0x38c8, 0x38cc, 0x38d0, 0x38d4, 0x38d8, 0x38dc, 0x38df,
+ 0x38e3, 0x38e7, 0x38eb, 0x38ef, 0x38f3, 0x38f7, 0x38fb, 0x38ff, 0x3903,
+ 0x3907, 0x390c, 0x3910, 0x3914, 0x3918, 0x391c, 0x3920, 0x3925, 0x3929,
+ 0x392d, 0x3932, 0x3936, 0x393a, 0x393f, 0x3943, 0x3948, 0x394c, 0x3951,
+ 0x3955, 0x395a, 0x395e, 0x3963, 0x3967, 0x396c, 0x3971, 0x3975, 0x397a,
+ 0x397f, 0x3984, 0x3989, 0x398d, 0x3992, 0x3997, 0x399c, 0x39a1, 0x39a6,
+ 0x39ab, 0x39b0, 0x39b5, 0x39ba, 0x39bf, 0x39c4, 0x39c9, 0x39cf, 0x39d4,
+ 0x39d9, 0x39de, 0x39e4, 0x39e9, 0x39ee, 0x39f4, 0x39f9, 0x39ff, 0x3,
+ /* table descriptor */
+ 0xfffff0e1, 0xf,
+ /* table length */
+ 0x402,
+ /* table data */
+ 0x3, 0x0, 0x1, 0x2, 0x3, 0x4, 0x6, 0x7, 0x8, 0x9, 0xb, 0xc, 0xd, 0xe,
+ 0x10, 0x11, 0x12, 0x13, 0x15, 0x16, 0x17, 0x18, 0x1a, 0x1b, 0x1c, 0x1d,
+ 0x1e, 0x20, 0x21, 0x22, 0x23, 0x25, 0x26, 0x27, 0x28, 0x2a, 0x2b, 0x2c,
+ 0x2d, 0x2f, 0x30, 0x31, 0x32, 0x34, 0x35, 0x36, 0x37, 0x39, 0x3a, 0x3c,
+ 0x3d, 0x3e, 0x40, 0x41, 0x43, 0x44, 0x46, 0x47, 0x49, 0x4a, 0x4c, 0x4d,
+ 0x4f, 0x51, 0x52, 0x54, 0x56, 0x57, 0x59, 0x5b, 0x5d, 0x5f, 0x60, 0x62,
+ 0x64, 0x66, 0x68, 0x6a, 0x6c, 0x6e, 0x70, 0x72, 0x74, 0x76, 0x78, 0x7a,
+ 0x7c, 0x7e, 0x80, 0x82, 0x85, 0x87, 0x89, 0x8b, 0x8e, 0x90, 0x92, 0x94,
+ 0x97, 0x99, 0x9c, 0x9e, 0xa0, 0xa3, 0xa5, 0xa8, 0xaa, 0xad, 0xb0, 0xb2,
+ 0xb5, 0xb7, 0xba, 0xbd, 0xc0, 0xc2, 0xc5, 0xc8, 0xcb, 0xcd, 0xd0, 0xd3,
+ 0xd6, 0xd9, 0xdc, 0xdf, 0xe2, 0xe5, 0xe8, 0xeb, 0xee, 0xf1, 0xf4, 0xf7,
+ 0xfb, 0xfe, 0x101, 0x104, 0x108, 0x10b, 0x10e, 0x111, 0x115, 0x118,
+ 0x11c, 0x11f, 0x123, 0x126, 0x12a, 0x12d, 0x131, 0x134, 0x138, 0x13b,
+ 0x13f, 0x143, 0x146, 0x14a, 0x14e, 0x152, 0x155, 0x159, 0x15d, 0x161,
+ 0x165, 0x169, 0x16d, 0x171, 0x175, 0x179, 0x17d, 0x181, 0x185, 0x189,
+ 0x18d, 0x192, 0x196, 0x19a, 0x19e, 0x1a2, 0x1a7, 0x1ab, 0x1af, 0x1b4,
+ 0x1b8, 0x1bd, 0x1c1, 0x1c6, 0x1ca, 0x1cf, 0x1d3, 0x1d8, 0x1dc, 0x1e1,
+ 0x1e6, 0x1ea, 0x1ef, 0x1f4, 0x1f9, 0x1fe, 0x202, 0x207, 0x20c, 0x211,
+ 0x216, 0x21b, 0x220, 0x225, 0x22a, 0x22f, 0x234, 0x239, 0x23e, 0x244,
+ 0x249, 0x24e, 0x253, 0x258, 0x25e, 0x263, 0x269, 0x26e, 0x273, 0x279,
+ 0x27e, 0x284, 0x289, 0x28f, 0x294, 0x29a, 0x2a0, 0x2a5, 0x2ab, 0x2b1,
+ 0x2b7, 0x2bc, 0x2c2, 0x2c8, 0x2ce, 0x2d4, 0x2da, 0x2e0, 0x2e6, 0x2ec,
+ 0x2f2, 0x2f8, 0x2fe, 0x304, 0x30a, 0x310, 0x316, 0x31d, 0x323, 0x329,
+ 0x32f, 0x336, 0x33c, 0x343, 0x349, 0x350, 0x356, 0x35d, 0x363, 0x36a,
+ 0x370, 0x377, 0x37e, 0x384, 0x38b, 0x392, 0x398, 0x39f, 0x3a6, 0x3ad,
+ 0x3b4, 0x3bb, 0x3c2, 0x3c9, 0x3d0, 0x3d7, 0x3de, 0x3e5, 0x3ec, 0x3f3,
+ 0x3fb, 0x402, 0x409, 0x410, 0x418, 0x41f, 0x426, 0x42e, 0x435, 0x43d,
+ 0x444, 0x44c, 0x453, 0x45b, 0x462, 0x46a, 0x472, 0x479, 0x481, 0x489,
+ 0x491, 0x499, 0x4a0, 0x4a8, 0x4b0, 0x4b8, 0x4c0, 0x4c8, 0x4d0, 0x4d8,
+ 0x4e0, 0x4e8, 0x4f1, 0x4f9, 0x501, 0x509, 0x512, 0x51a, 0x522, 0x52b,
+ 0x533, 0x53b, 0x544, 0x54c, 0x555, 0x55e, 0x566, 0x56f, 0x577, 0x580,
+ 0x589, 0x592, 0x59a, 0x5a3, 0x5ac, 0x5b5, 0x5be, 0x5c7, 0x5d0, 0x5d9,
+ 0x5e2, 0x5eb, 0x5f4, 0x5fd, 0x606, 0x60f, 0x619, 0x622, 0x62b, 0x635,
+ 0x63e, 0x647, 0x651, 0x65a, 0x664, 0x66d, 0x677, 0x680, 0x68a, 0x694,
+ 0x69d, 0x6a7, 0x6b1, 0x6bb, 0x6c4, 0x6ce, 0x6d8, 0x6e2, 0x6ec, 0x6f6,
+ 0x700, 0x70a, 0x714, 0x71e, 0x728, 0x732, 0x73d, 0x747, 0x751, 0x75b,
+ 0x766, 0x770, 0x77a, 0x785, 0x78f, 0x79a, 0x7a4, 0x7af, 0x7ba, 0x7c4,
+ 0x7cf, 0x7da, 0x7e4, 0x7ef, 0x7fa, 0x805, 0x810, 0x81a, 0x825, 0x830,
+ 0x83b, 0x846, 0x851, 0x85d, 0x868, 0x873, 0x87e, 0x889, 0x895, 0x8a0,
+ 0x8ab, 0x8b7, 0x8c2, 0x8cd, 0x8d9, 0x8e4, 0x8f0, 0x8fb, 0x907, 0x913,
+ 0x91e, 0x92a, 0x936, 0x942, 0x94d, 0x959, 0x965, 0x971, 0x97d, 0x989,
+ 0x995, 0x9a1, 0x9ad, 0x9b9, 0x9c5, 0x9d2, 0x9de, 0x9ea, 0x9f6, 0xa03,
+ 0xa0f, 0xa1c, 0xa28, 0xa34, 0xa41, 0xa4d, 0xa5a, 0xa67, 0xa73, 0xa80,
+ 0xa8d, 0xa99, 0xaa6, 0xab3, 0xac0, 0xacd, 0xada, 0xae7, 0xaf4, 0xb01,
+ 0xb0e, 0xb1b, 0xb28, 0xb35, 0xb42, 0xb50, 0xb5d, 0xb6a, 0xb77, 0xb85,
+ 0xb92, 0xba0, 0xbad, 0xbbb, 0xbc8, 0xbd6, 0xbe4, 0xbf1, 0xbff, 0xc0d,
+ 0xc1a, 0xc28, 0xc36, 0xc44, 0xc52, 0xc60, 0xc6e, 0xc7c, 0xc8a, 0xc98,
+ 0xca6, 0xcb4, 0xcc3, 0xcd1, 0xcdf, 0xced, 0xcfc, 0xd0a, 0xd19, 0xd27,
+ 0xd35, 0xd44, 0xd53, 0xd61, 0xd70, 0xd7e, 0xd8d, 0xd9c, 0xdab, 0xdba,
+ 0xdc8, 0xdd7, 0xde6, 0xdf5, 0xe04, 0xe13, 0xe22, 0xe31, 0xe41, 0xe50,
+ 0xe5f, 0xe6e, 0xe7e, 0xe8d, 0xe9c, 0xeac, 0xebb, 0xecb, 0xeda, 0xeea,
+ 0xef9, 0xf09, 0xf19, 0xf28, 0xf38, 0xf48, 0xf58, 0xf68, 0xf77, 0xf87,
+ 0xf97, 0xfa7, 0xfb7, 0xfc7, 0xfd8, 0xfe8, 0xff8, 0x1008, 0x1018,
+ 0x1029, 0x1039, 0x1049, 0x105a, 0x106a, 0x107b, 0x108b, 0x109c, 0x10ad,
+ 0x10bd, 0x10ce, 0x10df, 0x10ef, 0x1100, 0x1111, 0x1122, 0x1133, 0x1144,
+ 0x1155, 0x1166, 0x1177, 0x1188, 0x1199, 0x11aa, 0x11bb, 0x11cd, 0x11de,
+ 0x11ef, 0x1201, 0x1212, 0x1223, 0x1235, 0x1246, 0x1258, 0x126a, 0x127b,
+ 0x128d, 0x129f, 0x12b0, 0x12c2, 0x12d4, 0x12e6, 0x12f8, 0x130a, 0x131c,
+ 0x132e, 0x1340, 0x1352, 0x1364, 0x1376, 0x1388, 0x139b, 0x13ad, 0x13bf,
+ 0x13d2, 0x13e4, 0x13f6, 0x1409, 0x141c, 0x142e, 0x1441, 0x1453, 0x1466,
+ 0x1479, 0x148b, 0x149e, 0x14b1, 0x14c4, 0x14d7, 0x14ea, 0x14fd, 0x1510,
+ 0x1523, 0x1536, 0x1549, 0x155c, 0x1570, 0x1583, 0x1596, 0x15aa, 0x15bd,
+ 0x15d0, 0x15e4, 0x15f7, 0x160b, 0x161e, 0x1632, 0x1646, 0x1659, 0x166d,
+ 0x1681, 0x1695, 0x16a9, 0x16bd, 0x16d1, 0x16e4, 0x16f9, 0x170d, 0x1721,
+ 0x1735, 0x1749, 0x175d, 0x1771, 0x1786, 0x179a, 0x17af, 0x17c3, 0x17d7,
+ 0x17ec, 0x1800, 0x1815, 0x182a, 0x183e, 0x1853, 0x1868, 0x187d, 0x1891,
+ 0x18a6, 0x18bb, 0x18d0, 0x18e5, 0x18fa, 0x190f, 0x1924, 0x1939, 0x194f,
+ 0x1964, 0x1979, 0x198e, 0x19a4, 0x19b9, 0x19cf, 0x19e4, 0x19fa, 0x1a0f,
+ 0x1a25, 0x1a3a, 0x1a50, 0x1a66, 0x1a7b, 0x1a91, 0x1aa7, 0x1abd, 0x1ad3,
+ 0x1ae9, 0x1aff, 0x1b15, 0x1b2b, 0x1b41, 0x1b57, 0x1b6d, 0x1b84, 0x1b9a,
+ 0x1bb0, 0x1bc7, 0x1bdd, 0x1bf4, 0x1c0a, 0x1c21, 0x1c37, 0x1c4e, 0x1c64,
+ 0x1c7b, 0x1c92, 0x1ca9, 0x1cbf, 0x1cd6, 0x1ced, 0x1d04, 0x1d1b, 0x1d32,
+ 0x1d49, 0x1d60, 0x1d78, 0x1d8f, 0x1da6, 0x1dbd, 0x1dd5, 0x1dec, 0x1e03,
+ 0x1e1b, 0x1e32, 0x1e4a, 0x1e61, 0x1e79, 0x1e91, 0x1ea8, 0x1ec0, 0x1ed8,
+ 0x1ef0, 0x1f07, 0x1f1f, 0x1f37, 0x1f4f, 0x1f67, 0x1f7f, 0x1f98, 0x1fb0,
+ 0x1fc8, 0x1fe0, 0x1ff8, 0x2011, 0x2029, 0x2042, 0x205a, 0x2072, 0x208b,
+ 0x20a4, 0x20bc, 0x20d5, 0x20ee, 0x2106, 0x211f, 0x2138, 0x2151, 0x216a,
+ 0x2183, 0x219c, 0x21b5, 0x21ce, 0x21e7, 0x2200, 0x2219, 0x2233, 0x224c,
+ 0x2265, 0x227f, 0x2298, 0x22b2, 0x22cb, 0x22e5, 0x22fe, 0x2318, 0x2331,
+ 0x234b, 0x2365, 0x237f, 0x2399, 0x23b3, 0x23cc, 0x23e6, 0x2401, 0x241b,
+ 0x2435, 0x244f, 0x2469, 0x2483, 0x249e, 0x24b8, 0x24d2, 0x24ed, 0x2507,
+ 0x2522, 0x253c, 0x2557, 0x2571, 0x258c, 0x25a7, 0x25c2, 0x25dc, 0x25f7,
+ 0x2612, 0x262d, 0x2648, 0x2663, 0x267e, 0x2699, 0x26b4, 0x26cf, 0x26eb,
+ 0x2706, 0x2721, 0x273d, 0x2758, 0x2774, 0x278f, 0x27ab, 0x27c6, 0x27e2,
+ 0x27fd, 0x2819, 0x2835, 0x2851, 0x286d, 0x2888, 0x28a4, 0x28c0, 0x28dc,
+ 0x28f8, 0x2915, 0x2931, 0x294d, 0x2969, 0x2985, 0x29a2, 0x29be, 0x29db,
+ 0x29f7, 0x2a14, 0x2a30, 0x2a4d, 0x2a69, 0x2a86, 0x2aa3, 0x2ac0, 0x2adc,
+ 0x2af9, 0x2b16, 0x2b33, 0x2b50, 0x2b6d, 0x2b8a, 0x2ba7, 0x2bc4, 0x2be2,
+ 0x2bff, 0x2c1c, 0x2c3a, 0x2c57, 0x2c74, 0x2c92, 0x2caf, 0x2ccd, 0x2ceb,
+ 0x2d08, 0x2d26, 0x2d44, 0x2d61, 0x2d7f, 0x2d9d, 0x2dbb, 0x2dd9, 0x2df7,
+ 0x2e15, 0x2e33, 0x2e51, 0x2e70, 0x2e8e, 0x2eac, 0x2eca, 0x2ee9, 0x2f07,
+ 0x2f26, 0x2f44, 0x2f63, 0x2f81, 0x2fa0, 0x2fbf, 0x2fdd, 0x2ffc, 0x301b,
+ 0x303a, 0x3059, 0x3078, 0x3097, 0x30b6, 0x30d5, 0x30f4, 0x3113, 0x3132,
+ 0x3152, 0x3171, 0x3190, 0x31b0, 0x31cf, 0x31ef, 0x320e, 0x322e, 0x324e,
+ 0x326d, 0x328d, 0x32ad, 0x32cd, 0x32ec, 0x330c, 0x332c, 0x334c, 0x336c,
+ 0x338c, 0x33ac, 0x33cd, 0x33ed, 0x340d, 0x342e, 0x344e, 0x346e, 0x348f,
+ 0x34af, 0x34d0, 0x34f0, 0x3511, 0x3532, 0x3552, 0x3573, 0x3594, 0x35b5,
+ 0x35d6, 0x35f7, 0x3618, 0x3639, 0x365a, 0x367b, 0x369c, 0x36bd, 0x36df,
+ 0x3700, 0x3721, 0x3743, 0x3764, 0x3786, 0x37a7, 0x37c9, 0x37eb, 0x380c,
+ 0x382e, 0x3850, 0x3872, 0x3894, 0x38b6, 0x38d8, 0x38fa, 0x391c, 0x393e,
+ 0x3960, 0x3982, 0x39a4, 0x39c7, 0x39e9, 0x3a0b, 0x3a2e, 0x3a50, 0x3a73,
+ 0x3a95, 0x3ab8, 0x3adb, 0x3afd, 0x3b20, 0x3b43, 0x3b66, 0x3b89, 0x3bac,
+ 0x3bcf, 0x3bf2, 0x3c15, 0x3c38, 0x3c5b, 0x3c7e, 0x3ca2, 0x3cc5, 0x3ce8,
+ 0x3d0c, 0x3d2f, 0x3d53, 0x3d76, 0x3d9a, 0x3dbe, 0x3de1, 0x3e05, 0x3e29,
+ 0x3e4d, 0x3e71, 0x3e95, 0x3eb9, 0x3edd, 0x3f01, 0x3f25, 0x3f49, 0x3f6d,
+ 0x3f91, 0x3fb6, 0x3fda, 0x3fff, 0x0,
+ /* table descriptor */
+ 0xffffbf62, 0xf,
+ /* table length */
+ 0x1d,
+ /* table data */
+ 0x3, 0x4abd, 0x0, 0x0, 0x0, 0x4abd, 0x0, 0x0, 0x0, 0x4abd, 0xffffffc0,
+ 0xffffffc0, 0xffffffc0, 0x0, 0x0, 0x0, 0x36c, 0x36c, 0x36c, 0xe, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x3ff, 0x3ff, 0x3ff,
+ /* table descriptor */
+ 0xffffdf62, 0xf,
+ /* table length */
+ 0x1d,
+ /* table data */
+ 0x3, 0x4000, 0x0, 0x0, 0x0, 0x4000, 0x0, 0x0, 0x0, 0x4000, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x3ff, 0x3ff, 0x3ff, 0xe, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x3ff, 0x3ff, 0x3ff,
+ /* table descriptor */
+ 0xfff0bfa2, 0xf,
+ /* table length */
+ 0x1d,
+ /* table data */
+ 0x3, 0x255f, 0x0, 0x35e0, 0x255f, 0xfffff9fd, 0xffffeb20, 0x255f,
+ 0x44bd, 0x0, 0xffffffc0, 0xfffffe00, 0xfffffe00, 0x0, 0xfffffe40,
+ 0xfffffe40, 0x36c, 0x1c0, 0x1c0, 0xd, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x3ff, 0x3ff, 0x3ff,
+ /* table descriptor */
+ 0xfff136a2, 0xf,
+ /* table length */
+ 0x1d,
+ /* table data */
+ 0x3, 0x255f, 0x0, 0x3989, 0x255f, 0xfffff928, 0xffffeee6, 0x255f,
+ 0x43cc, 0x0, 0xffffffc0, 0xfffffe00, 0xfffffe00, 0x0, 0xfffffe40,
+ 0xfffffe40, 0x36c, 0x1c0, 0x1c0, 0xd, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x3ff, 0x3ff, 0x3ff,
+ /* table descriptor */
+ 0xfff636a2, 0xf,
+ /* table length */
+ 0x1d,
+ /* table data */
+ 0x3, 0x255f, 0x0, 0x3339, 0x255f, 0xfffff36d, 0xffffe5e9, 0x255f,
+ 0x40be, 0x0, 0xffffffc0, 0xfffffe00, 0xfffffe00, 0x0, 0xfffffe40,
+ 0xfffffe40, 0x36c, 0x1c0, 0x1c0, 0xd, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x3ff, 0x3ff, 0x3ff,
+ /* table descriptor */
+ 0xfff836a2, 0xf,
+ /* table length */
+ 0x1d,
+ /* table data */
+ 0x3, 0x4abd, 0x0, 0x0, 0x0, 0x4912, 0x0, 0x0, 0x0, 0x4912, 0xffffffc0,
+ 0xfffffe00, 0xfffffe00, 0x0, 0xfffffe40, 0xfffffe40, 0x36c, 0x1c0,
+ 0x1c0, 0xe, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3ff, 0x3ff, 0x3ff,
+ /* table descriptor */
+ 0xfff0dfa2, 0xf,
+ /* table length */
+ 0x1d,
+ /* table data */
+ 0x3, 0x4000, 0x0, 0x5e60, 0x4000, 0xfffff578, 0xffffdb6f, 0x4000,
+ 0x7869, 0x0, 0x0, 0xfffffe00, 0xfffffe00, 0x0, 0xfffffe00, 0xfffffe00,
+ 0x3ff, 0x1ff, 0x1ff, 0xe, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3ff, 0x3ff,
+ 0x3ff,
+ /* table descriptor */
+ 0xfff156a2, 0xf,
+ /* table length */
+ 0x1d,
+ /* table data */
+ 0x3, 0x4000, 0x0, 0x64ca, 0x4000, 0xfffff403, 0xffffe20a, 0x4000,
+ 0x76c2, 0x0, 0x0, 0xfffffe00, 0xfffffe00, 0x0, 0xfffffe00, 0xfffffe00,
+ 0x3ff, 0x1ff, 0x1ff, 0xe, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3ff, 0x3ff,
+ 0x3ff,
+ /* table descriptor */
+ 0xfff656a2, 0xf,
+ /* table length */
+ 0x1d,
+ /* table data */
+ 0x3, 0x4000, 0x0, 0x59ba, 0x4000, 0xffffe9fa, 0xffffd24c, 0x4000,
+ 0x7168, 0x0, 0x0, 0xfffffe00, 0xfffffe00, 0x0, 0xfffffe00, 0xfffffe00,
+ 0x3ff, 0x1ff, 0x1ff, 0xe, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3ff, 0x3ff,
+ 0x3ff,
+ /* table descriptor */
+ 0xfff856a2, 0xf,
+ /* table length */
+ 0x1d,
+ /* table data */
+ 0x3, 0x4000, 0x0, 0x0, 0x0, 0x4000, 0x0, 0x0, 0x0, 0x4000, 0x0,
+ 0xfffffe00, 0xfffffe00, 0x0, 0xfffffe00, 0xfffffe00, 0x3ff, 0x1ff,
+ 0x1ff, 0xe, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3ff, 0x3ff, 0x3ff,
+ /* table descriptor */
+ 0xfff176e4, 0x0,
+ /* table length */
+ 0x1d,
+ /* table data */
+ 0x3, 0x503c, 0x2a1c, 0x58a, 0x8d6, 0x7598, 0x174, 0x219, 0xb41, 0x7288,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3fff, 0x3fff, 0x3fff, 0x1, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0xffc0000, 0xffc0000, 0xffc0000,
+ /* table descriptor */
+ 0xfff276e4, 0x0,
+ /* table length */
+ 0x1d,
+ /* table data */
+ 0x3, 0x53c5, 0x26a4, 0x579, 0x93a, 0x7539, 0x170, 0x230, 0xc84, 0x712e,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3fff, 0x3fff, 0x3fff, 0x1, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0xffc0000, 0xffc0000, 0xffc0000,
+ /* table descriptor */
+ 0xfff476e4, 0x0,
+ /* table length */
+ 0x1d,
+ /* table data */
+ 0x3, 0x4e04, 0x2c5e, 0x57f, 0xaa6, 0x713c, 0x400, 0x208, 0xa67, 0x7372,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3fff, 0x3fff, 0x3fff, 0x1, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0xffc0000, 0xffc0000, 0xffc0000,
+ /* table descriptor */
+ 0xfff876e4, 0x0,
+ /* table length */
+ 0x1d,
+ /* table data */
+ 0x3, 0x7057, 0x9d1, 0x5b9, 0xd6e, 0x70f3, 0x180, 0x416, 0x574, 0x7659,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3fff, 0x3fff, 0x3fff, 0x1, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0xffc0000, 0xffc0000, 0xffc0000,
+ /* table descriptor */
+ 0x7ff276e4, 0x1,
+ /* table length */
+ 0x1d,
+ /* table data */
+ 0x3, 0x42c2, 0xfffffd2f, 0x0, 0x0, 0x3ff1, 0x0, 0x0, 0xc1, 0x3f30, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x3fff, 0x3fff, 0x3fff, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0xffc0000, 0xffc0000, 0xffc0000,
+ /* table descriptor */
+ 0x7ff476e4, 0x1,
+ /* table length */
+ 0x1d,
+ /* table data */
+ 0x3, 0x3d92, 0x330, 0xffffff2f, 0x12a, 0x3d56, 0x171, 0xffffffe5,
+ 0xffffffb9, 0x4053, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3fff, 0x3fff,
+ 0x3fff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffc0000, 0xffc0000,
+ 0xffc0000,
+ /* table descriptor */
+ 0x7ff876e4, 0x1,
+ /* table length */
+ 0x1d,
+ /* table data */
+ 0x3, 0x592d, 0xffffe6c4, 0x0, 0x98, 0x3f59, 0x0, 0x97, 0xfffffd48,
+ 0x4212, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3fff, 0x3fff, 0x3fff, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0xffc0000, 0xffc0000, 0xffc0000,
+ /* table descriptor */
+ 0x7ff176e4, 0x2,
+ /* table length */
+ 0x1d,
+ /* table data */
+ 0x3, 0x3d3e, 0x2b3, 0x0, 0x0, 0x3ff1, 0x0, 0x0, 0xffffff3d, 0x40b4,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3fff, 0x3fff, 0x3fff, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0xffc0000, 0xffc0000, 0xffc0000,
+ /* table descriptor */
+ 0x7ff476e4, 0x2,
+ /* table length */
+ 0x1d,
+ /* table data */
+ 0x3, 0x3b06, 0x5a4, 0xffffff47, 0x12a, 0x3d56, 0x171, 0xffffffe1,
+ 0xfffffefd, 0x4113, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3fff, 0x3fff,
+ 0x3fff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffc0000, 0xffc0000,
+ 0xffc0000,
+ /* table descriptor */
+ 0x7ff876e4, 0x2,
+ /* table length */
+ 0x1d,
+ /* table data */
+ 0x3, 0x5570, 0xffffea81, 0x0, 0x98, 0x3f59, 0x0, 0x97, 0xfffffc7e,
+ 0x42dc, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3fff, 0x3fff, 0x3fff, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0xffc0000, 0xffc0000, 0xffc0000,
+ /* table descriptor */
+ 0x7ff176e4, 0x4,
+ /* table length */
+ 0x1d,
+ /* table data */
+ 0x3, 0x4278, 0xfffffc8d, 0xec, 0xfffffebc, 0x42b8, 0xfffffe7d, 0x1b,
+ 0x48, 0x3f8e, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3fff, 0x3fff, 0x3fff,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffc0000, 0xffc0000, 0xffc0000,
+ /* table descriptor */
+ 0x7ff276e4, 0x4,
+ /* table length */
+ 0x1d,
+ /* table data */
+ 0x3, 0x4566, 0xfffff9a2, 0xe9, 0xfffffeae, 0x42c1, 0xfffffe82, 0x1c,
+ 0x107, 0x3ece, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3fff, 0x3fff, 0x3fff,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffc0000, 0xffc0000, 0xffc0000,
+ /* table descriptor */
+ 0x7ff876e4, 0x4,
+ /* table length */
+ 0x1d,
+ /* table data */
+ 0x3, 0x5cae, 0xffffe250, 0xf4, 0xfffffed8, 0x42a9, 0xfffffe70, 0xbc,
+ 0xfffffd89, 0x41ac, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3fff, 0x3fff,
+ 0x3fff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffc0000, 0xffc0000,
+ 0xffc0000,
+ /* table descriptor */
+ 0xfff0ffe4, 0xf,
+ /* table length */
+ 0x1d,
+ /* table data */
+ 0x8000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0,
+ /* table descriptor */
+ 0x7ff176e4, 0x8,
+ /* table length */
+ 0x1d,
+ /* table data */
+ 0x3, 0x2dba, 0x1237, 0x0, 0xffffff92, 0x405f, 0x0, 0xffffff93, 0x27d,
+ 0x3de1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3fff, 0x3fff, 0x3fff, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0xffc0000, 0xffc0000, 0xffc0000,
+ /* table descriptor */
+ 0x7ff276e4, 0x8,
+ /* table length */
+ 0x1d,
+ /* table data */
+ 0x3, 0x2fbd, 0x1034, 0x0, 0xffffff8d, 0x4064, 0x0, 0xffffff8e, 0x33c,
+ 0x3d27, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3fff, 0x3fff, 0x3fff, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0xffc0000, 0xffc0000, 0xffc0000,
+ /* table descriptor */
+ 0x7ff476e4, 0x8,
+ /* table length */
+ 0x1d,
+ /* table data */
+ 0x3, 0x58ba, 0x2781, 0xffffffa7, 0x185, 0x7b74, 0x2ea, 0xffffff11,
+ 0x431, 0x7ca0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3fff, 0x3fff, 0x3fff,
+ 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffc0000, 0xffc0000, 0xffc0000,
+ /* table descriptor */
+ 0x7fff76e4, 0xf,
+ /* table length */
+ 0x1d,
+ /* table data */
+ 0x3, 0x7fe2, 0x0, 0x0, 0x0, 0x7fe2, 0x0, 0x0, 0x0, 0x7fe2, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x3fff, 0x3fff, 0x3fff, 0x1, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0xffc0000, 0xffc0000, 0xffc0000,
+};
+
+#endif /* __DCSS_HDR10_TABLES_H__ */
diff --git a/drivers/gpu/imx/dcss/dcss-hdr10.c b/drivers/gpu/imx/dcss/dcss-hdr10.c
new file mode 100644
index 000000000000..7dad29acf2e1
--- /dev/null
+++ b/drivers/gpu/imx/dcss/dcss-hdr10.c
@@ -0,0 +1,655 @@
+/*
+ * Copyright (C) 2017 NXP
+ *
+ * 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/device.h>
+#include <linux/bitops.h>
+#include <linux/io.h>
+#include <linux/firmware.h>
+#include <drm/drm_fourcc.h>
+
+#include <video/imx-dcss.h>
+#include "dcss-prv.h"
+
+#define USE_TBL_HEADER
+
+#ifdef USE_TBL_HEADER
+#include "dcss-hdr10-tables.h"
+#endif
+
+#define USE_CTXLD
+
+#define DCSS_HDR10_A0_LUT 0x0000
+#define DCSS_HDR10_A1_LUT 0x1000
+#define DCSS_HDR10_A2_LUT 0x2000
+/* one CSCA and CSCB for each channel(pipe) */
+#define DCSS_HDR10_CSCA_BASE 0x3000
+#define DCSS_HDR10_CSCB_BASE 0x3800
+
+/* one CSCO for all channels(pipes) */
+#define DCSS_HDR10_CSCO_BASE 0x3000
+
+#define DCSS_HDR10_LUT_CONTROL (DCSS_HDR10_CSCA_BASE + 0x80)
+#define LUT_ENABLE BIT(0)
+#define LUT_EN_FOR_ALL_PELS BIT(1)
+#define LUT_BYPASS BIT(15)
+#define DCSS_HDR10_FL2FX (DCSS_HDR10_CSCB_BASE + 0x74)
+#define DCSS_HDR10_LTNL (DCSS_HDR10_CSCO_BASE + 0x74)
+#define LTNL_PASS_THRU BIT(0)
+#define FIX2FLT_DISABLE BIT(1)
+#define LTNL_EN_FOR_ALL_PELS BIT(2)
+#define FIX2FLT_EN_FOR_ALL_PELS BIT(3)
+
+/* following offsets are relative to CSC(A|B|O)_BASE */
+#define DCSS_HDR10_CSC_CONTROL 0x00
+#define CSC_EN BIT(0)
+#define CSC_ALL_PIX_EN BIT(1)
+#define CSC_BYPASS BIT(15)
+#define DCSS_HDR10_CSC_H00 0x04
+#define DCSS_HDR10_CSC_H10 0x08
+#define DCSS_HDR10_CSC_H20 0x0C
+#define DCSS_HDR10_CSC_H01 0x10
+#define DCSS_HDR10_CSC_H11 0x14
+#define DCSS_HDR10_CSC_H21 0x18
+#define DCSS_HDR10_CSC_H02 0x1C
+#define DCSS_HDR10_CSC_H12 0x20
+#define DCSS_HDR10_CSC_H22 0x24
+#define H_COEF_MASK GENMASK(15, 0)
+#define DCSS_HDR10_CSC_IO0 0x28
+#define DCSS_HDR10_CSC_IO1 0x2C
+#define DCSS_HDR10_CSC_IO2 0x30
+#define PRE_OFFSET_MASK GENMASK(9, 0)
+#define DCSS_HDR10_CSC_IO_MIN0 0x34
+#define DCSS_HDR10_CSC_IO_MIN1 0x38
+#define DCSS_HDR10_CSC_IO_MIN2 0x3C
+#define DCSS_HDR10_CSC_IO_MAX0 0x40
+#define DCSS_HDR10_CSC_IO_MAX1 0x44
+#define DCSS_HDR10_CSC_IO_MAX2 0x48
+#define IO_CLIP_MASK GENMASK(9, 0)
+#define DCSS_HDR10_CSC_NORM 0x4C
+#define NORM_MASK GENMASK(4, 0)
+#define DCSS_HDR10_CSC_OO0 0x50
+#define DCSS_HDR10_CSC_OO1 0x54
+#define DCSS_HDR10_CSC_OO2 0x58
+#define POST_OFFSET_MASK GENMASK(27, 0)
+#define DCSS_HDR10_CSC_OMIN0 0x5C
+#define DCSS_HDR10_CSC_OMIN1 0x60
+#define DCSS_HDR10_CSC_OMIN2 0x64
+#define DCSS_HDR10_CSC_OMAX0 0x68
+#define DCSS_HDR10_CSC_OMAX1 0x6C
+#define DCSS_HDR10_CSC_OMAX2 0x70
+#define POST_CLIP_MASK GENMASK(9, 0)
+
+#define HDR10_IPIPE_LUT_MAX_ENTRIES 1024
+#define HDR10_OPIPE_LUT_MAX_ENTRIES 1023
+#define HDR10_CSC_MAX_REGS 29
+
+#define OPIPE_CH_NO 3
+
+/* Pipe config descriptor */
+
+/* bits per component */
+#define HDR10_BPC_POS 0
+#define HDR10_BPC_MASK GENMASK(1, 0)
+/* colorspace */
+#define HDR10_CS_POS 2
+#define HDR10_CS_MASK GENMASK(3, 2)
+/* nonlinearity type */
+#define HDR10_NL_POS 4
+#define HDR10_NL_MASK GENMASK(8, 4)
+/* pixel range */
+#define HDR10_PR_POS 9
+#define HDR10_PR_MASK GENMASK(10, 9)
+/* gamut type */
+#define HDR10_G_POS 11
+#define HDR10_G_MASK GENMASK(15, 11)
+
+/* FW Table Descriptor */
+#define HDR10_TT_LUT BIT(0)
+#define HDR10_TT_CSCA BIT(1)
+#define HDR10_TT_CSCB BIT(2)
+/* Pipe type */
+#define HDR10_PT_OUTPUT BIT(3)
+/* Output pipe config descriptor */
+#define HDR10_IPIPE_DESC_POS 4
+#define HDR10_IPIPE_DESC_MASK GENMASK(19, 4)
+/* Input pipe config descriptor */
+#define HDR10_OPIPE_DESC_POS 20
+#define HDR10_OPIPE_DESC_MASK GENMASK(35, 20)
+
+/* config invalid */
+#define HDR10_DESC_INVALID BIT(63)
+
+enum dcss_hdr10_csc {
+ HDR10_CSCA,
+ HDR10_CSCB,
+};
+
+struct dcss_hdr10_tbl_node {
+ u64 tbl_descriptor;
+ u32 *tbl_data;
+
+ struct list_head node;
+};
+
+struct dcss_hdr10_opipe_tbls {
+ struct list_head lut;
+ struct list_head csc;
+};
+
+struct dcss_hdr10_ipipe_tbls {
+ struct list_head lut;
+ struct list_head csca;
+ struct list_head cscb;
+};
+
+struct dcss_hdr10_ch {
+ void __iomem *base_reg;
+ u32 base_ofs;
+
+ u32 ctx_id;
+
+ u64 old_cfg_desc;
+};
+
+struct dcss_hdr10_priv {
+ struct dcss_soc *dcss;
+
+ struct dcss_hdr10_ch ch[4]; /* 4th channel is, actually, OPIPE */
+
+ struct dcss_hdr10_ipipe_tbls *ipipe_tbls;
+ struct dcss_hdr10_opipe_tbls *opipe_tbls;
+
+ u8 *fw_data;
+ u32 fw_size;
+};
+
+static struct dcss_debug_reg hdr10_debug_reg[] = {
+ DCSS_DBG_REG(DCSS_HDR10_CSC_CONTROL),
+ DCSS_DBG_REG(DCSS_HDR10_CSC_H00),
+ DCSS_DBG_REG(DCSS_HDR10_CSC_H10),
+ DCSS_DBG_REG(DCSS_HDR10_CSC_H20),
+ DCSS_DBG_REG(DCSS_HDR10_CSC_H01),
+ DCSS_DBG_REG(DCSS_HDR10_CSC_H11),
+ DCSS_DBG_REG(DCSS_HDR10_CSC_H21),
+ DCSS_DBG_REG(DCSS_HDR10_CSC_H02),
+ DCSS_DBG_REG(DCSS_HDR10_CSC_H12),
+ DCSS_DBG_REG(DCSS_HDR10_CSC_H22),
+ DCSS_DBG_REG(DCSS_HDR10_CSC_IO0),
+ DCSS_DBG_REG(DCSS_HDR10_CSC_IO1),
+ DCSS_DBG_REG(DCSS_HDR10_CSC_IO2),
+ DCSS_DBG_REG(DCSS_HDR10_CSC_IO_MIN0),
+ DCSS_DBG_REG(DCSS_HDR10_CSC_IO_MIN1),
+ DCSS_DBG_REG(DCSS_HDR10_CSC_IO_MIN2),
+ DCSS_DBG_REG(DCSS_HDR10_CSC_IO_MAX0),
+ DCSS_DBG_REG(DCSS_HDR10_CSC_IO_MAX1),
+ DCSS_DBG_REG(DCSS_HDR10_CSC_IO_MAX2),
+ DCSS_DBG_REG(DCSS_HDR10_CSC_NORM),
+ DCSS_DBG_REG(DCSS_HDR10_CSC_OO0),
+ DCSS_DBG_REG(DCSS_HDR10_CSC_OO1),
+ DCSS_DBG_REG(DCSS_HDR10_CSC_OO2),
+ DCSS_DBG_REG(DCSS_HDR10_CSC_OMIN0),
+ DCSS_DBG_REG(DCSS_HDR10_CSC_OMIN1),
+ DCSS_DBG_REG(DCSS_HDR10_CSC_OMIN2),
+ DCSS_DBG_REG(DCSS_HDR10_CSC_OMAX0),
+ DCSS_DBG_REG(DCSS_HDR10_CSC_OMAX1),
+ DCSS_DBG_REG(DCSS_HDR10_CSC_OMAX2),
+};
+
+static void dcss_hdr10_write(struct dcss_soc *dcss, u32 ch_num,
+ u32 val, u32 ofs)
+{
+ struct dcss_hdr10_priv *hdr10 = dcss->hdr10_priv;
+
+#if !defined(USE_CTXLD)
+ dcss_writel(val, hdr10->ch[ch_num].base_reg + ofs);
+#else
+ dcss_ctxld_write(dcss, hdr10->ch[ch_num].ctx_id, val,
+ hdr10->ch[ch_num].base_ofs + ofs);
+#endif
+}
+
+#ifdef CONFIG_DEBUG_FS
+void dcss_hdr10_dump_regs(struct seq_file *s, void *data)
+{
+ struct dcss_soc *dcss = data;
+ int ch, csc, r;
+ int csc_no;
+
+ for (ch = 0; ch < 4; ch++) {
+ void __iomem *csc_base = dcss->hdr10_priv->ch[ch].base_reg +
+ DCSS_HDR10_CSCA_BASE;
+
+ if (ch < 3) {
+ seq_printf(s, ">> Dumping HDR10 CH %d:\n", ch);
+ csc_no = 2;
+ } else {
+ seq_puts(s, ">> Dumping HDR10 OPIPE:\n");
+ csc_no = 1;
+ }
+
+ for (csc = 0; csc < csc_no; csc++) {
+ csc_base += csc * 0x800;
+
+ if (ch < 3)
+ seq_printf(s, "\t>> Dumping CSC%s of CH %d:\n",
+ csc ? "B" : "A", ch);
+ else
+ seq_puts(s, "\t>> Dumping CSC of OPIPE:\n");
+
+ for (r = 0; r < ARRAY_SIZE(hdr10_debug_reg); r++)
+ seq_printf(s, "\t%-35s(0x%04x) -> 0x%08x\n",
+ hdr10_debug_reg[r].name,
+ hdr10_debug_reg[r].ofs,
+ dcss_readl(csc_base +
+ hdr10_debug_reg[r].ofs));
+
+ if (csc == 0 && ch != 3)
+ seq_printf(s, "\t%-35s(0x%04x) -> 0x%08x\n",
+ "DCSS_HDR10_LUT_CONTROL",
+ 0x80, dcss_readl(csc_base + 0x80));
+
+ if (csc == 1 || ch == 3)
+ seq_printf(s, "\t%-35s(0x%04x) -> 0x%08x\n",
+ ch == 3 ? "DCSS_HDR10_LTNL" :
+ "DCSS_HDR10_FL2FX",
+ 0x74, dcss_readl(csc_base + 0x74));
+ }
+ }
+}
+#endif
+
+static void dcss_hdr10_csc_fill(struct dcss_soc *dcss, int ch_num,
+ enum dcss_hdr10_csc csc_to_use,
+ u32 *map)
+{
+ int i;
+ u32 csc_base_ofs[] = {
+ DCSS_HDR10_CSCA_BASE + DCSS_HDR10_CSC_CONTROL,
+ DCSS_HDR10_CSCB_BASE + DCSS_HDR10_CSC_CONTROL,
+ };
+
+ for (i = 0; i < HDR10_CSC_MAX_REGS; i++) {
+ u32 reg_ofs = csc_base_ofs[csc_to_use] + i * sizeof(u32);
+
+ dcss_hdr10_write(dcss, ch_num, map[i], reg_ofs);
+ }
+}
+
+static void dcss_hdr10_lut_fill(struct dcss_soc *dcss, int ch_num, u32 *map)
+{
+ int i, comp;
+ u32 lut_base_ofs, ctrl_ofs, lut_entries;
+
+ if (ch_num == OPIPE_CH_NO) {
+ ctrl_ofs = DCSS_HDR10_LTNL;
+ lut_entries = HDR10_OPIPE_LUT_MAX_ENTRIES;
+ } else {
+ ctrl_ofs = DCSS_HDR10_LUT_CONTROL;
+ lut_entries = HDR10_IPIPE_LUT_MAX_ENTRIES;
+ }
+
+ if (ch_num != OPIPE_CH_NO)
+ dcss_hdr10_write(dcss, ch_num, *map++, ctrl_ofs);
+
+ for (comp = 0; comp < 3; comp++) {
+ lut_base_ofs = DCSS_HDR10_A0_LUT + comp * 0x1000;
+
+ if (ch_num == OPIPE_CH_NO) {
+ dcss_hdr10_write(dcss, ch_num, map[0], lut_base_ofs);
+ lut_base_ofs += 4;
+ }
+
+ for (i = 0; i < lut_entries; i++) {
+ u32 reg_ofs = lut_base_ofs + i * sizeof(u32);
+
+ dcss_hdr10_write(dcss, ch_num, map[i], reg_ofs);
+ }
+ }
+
+ map += lut_entries;
+
+ if (ch_num != OPIPE_CH_NO)
+ dcss_hdr10_write(dcss, ch_num, *map, DCSS_HDR10_FL2FX);
+ else
+ dcss_hdr10_write(dcss, ch_num, *map, ctrl_ofs);
+}
+
+static int dcss_hdr10_ch_init_all(struct dcss_soc *dcss,
+ unsigned long hdr10_base)
+{
+ struct dcss_hdr10_priv *hdr10 = dcss->hdr10_priv;
+ struct dcss_hdr10_ch *ch;
+ int i;
+
+ for (i = 0; i < 4; i++) {
+ ch = &hdr10->ch[i];
+
+ ch->base_ofs = hdr10_base + i * 0x4000;
+
+ ch->base_reg = devm_ioremap(dcss->dev, ch->base_ofs, SZ_16K);
+ if (!ch->base_reg) {
+ dev_err(dcss->dev, "hdr10: unable to remap ch base\n");
+ return -ENOMEM;
+ }
+
+ ch->old_cfg_desc = HDR10_DESC_INVALID;
+
+#if defined(USE_CTXLD)
+ ch->ctx_id = CTX_SB_HP;
+#endif
+ }
+
+ return 0;
+}
+
+static u32 *dcss_hdr10_find_tbl(u64 desc, struct list_head *head)
+{
+ struct list_head *node;
+ struct dcss_hdr10_tbl_node *tbl_node;
+
+ list_for_each(node, head) {
+ tbl_node = container_of(node, struct dcss_hdr10_tbl_node, node);
+
+ if ((tbl_node->tbl_descriptor & desc) == desc)
+ return tbl_node->tbl_data;
+ }
+
+ return NULL;
+}
+
+static int dcss_hdr10_get_tbls(struct dcss_hdr10_priv *hdr10, bool input,
+ u64 desc, u32 **lut, u32 **csca, u32 **cscb)
+{
+ struct list_head *lut_list, *csca_list, *cscb_list;
+
+ lut_list = input ? &hdr10->ipipe_tbls->lut : &hdr10->opipe_tbls->lut;
+ csca_list = input ? &hdr10->ipipe_tbls->csca : &hdr10->opipe_tbls->csc;
+ cscb_list = input ? &hdr10->ipipe_tbls->cscb : NULL;
+
+ *lut = dcss_hdr10_find_tbl(desc, lut_list);
+ *csca = dcss_hdr10_find_tbl(desc, csca_list);
+
+ *cscb = NULL;
+ if (cscb_list)
+ *cscb = dcss_hdr10_find_tbl(desc, cscb_list);
+
+ return 0;
+}
+
+static void dcss_hdr10_write_pipe_tbls(struct dcss_soc *dcss, int ch_num,
+ u32 *lut, u32 *csca, u32 *cscb)
+{
+ if (csca)
+ dcss_hdr10_csc_fill(dcss, ch_num, HDR10_CSCA, csca);
+
+ if (ch_num != OPIPE_CH_NO && cscb)
+ dcss_hdr10_csc_fill(dcss, ch_num, HDR10_CSCB, cscb);
+
+ if (lut)
+ dcss_hdr10_lut_fill(dcss, ch_num, lut);
+}
+
+static void dcss_hdr10_tbl_add(struct dcss_hdr10_priv *hdr10, u64 desc, u32 sz,
+ u32 *data)
+{
+ struct device *dev = hdr10->dcss->dev;
+ struct dcss_hdr10_tbl_node *node;
+
+ node = devm_kzalloc(dev, sizeof(*node), GFP_KERNEL);
+ if (!node) {
+ dev_err(dev, "hdr10: cannot alloc memory for table node.\n");
+ return;
+ }
+
+ /* we don't need to store the table type and pipe type */
+ node->tbl_descriptor = desc >> 4;
+ node->tbl_data = data;
+
+ if (!(desc & HDR10_PT_OUTPUT)) {
+ if (desc & HDR10_TT_LUT)
+ list_add(&node->node, &hdr10->ipipe_tbls->lut);
+ else if (desc & HDR10_TT_CSCA)
+ list_add(&node->node, &hdr10->ipipe_tbls->csca);
+ else if (desc & HDR10_TT_CSCB)
+ list_add(&node->node, &hdr10->ipipe_tbls->cscb);
+
+ return;
+ }
+
+ if (desc & HDR10_TT_LUT)
+ list_add(&node->node, &hdr10->opipe_tbls->lut);
+ else if (desc & HDR10_TT_CSCA)
+ list_add(&node->node, &hdr10->opipe_tbls->csc);
+}
+
+static void dcss_hdr10_parse_fw_data(struct dcss_hdr10_priv *hdr10)
+{
+ u32 *data = (u32 *)hdr10->fw_data;
+ u32 remaining = hdr10->fw_size / sizeof(u32);
+ u64 tbl_desc;
+ u32 tbl_size;
+
+ while (remaining) {
+ tbl_desc = *((u64 *)data);
+ data += 2;
+ tbl_size = *data++;
+
+ dcss_hdr10_tbl_add(hdr10, tbl_desc, tbl_size, data);
+
+ data += tbl_size;
+ remaining -= tbl_size + 3;
+ }
+}
+
+#ifndef USE_TBL_HEADER
+static void dcss_hdr10_fw_handler(const struct firmware *fw, void *context)
+{
+ struct dcss_hdr10_priv *hdr10 = context;
+ int i;
+
+ if (!fw) {
+ dev_err(hdr10->dcss->dev, "hdr10: DCSS FW load failed.\n");
+ return;
+ }
+
+ /* we need to keep the tables for the entire life of the driver */
+ hdr10->fw_data = devm_kzalloc(hdr10->dcss->dev, fw->size, GFP_KERNEL);
+ if (!hdr10->fw_data) {
+ dev_err(hdr10->dcss->dev, "hdr10: cannot alloc FW memory.\n");
+ return;
+ }
+
+ memcpy(hdr10->fw_data, fw->data, fw->size);
+ hdr10->fw_size = fw->size;
+
+ release_firmware(fw);
+
+ dcss_hdr10_parse_fw_data(hdr10);
+
+ for (i = 0; i < 4; i++) {
+ u32 *lut, *csca, *cscb;
+ struct dcss_hdr10_ch *ch = &hdr10->ch[i];
+ bool is_input_pipe = i != OPIPE_CH_NO ? true : false;
+
+ if (ch->old_cfg_desc != HDR10_DESC_INVALID) {
+ dcss_hdr10_get_tbls(hdr10, is_input_pipe,
+ ch->old_cfg_desc, &lut,
+ &csca, &cscb);
+ dcss_hdr10_write_pipe_tbls(hdr10->dcss, i, lut,
+ csca, cscb);
+ }
+ }
+
+ dev_info(hdr10->dcss->dev, "hdr10: DCSS FW loaded successfully\n");
+}
+#endif
+
+static int dcss_hdr10_tbls_init(struct dcss_hdr10_priv *hdr10)
+{
+ struct device *dev = hdr10->dcss->dev;
+
+ hdr10->ipipe_tbls = devm_kzalloc(dev, sizeof(*hdr10->ipipe_tbls),
+ GFP_KERNEL);
+ if (!hdr10->ipipe_tbls)
+ return -ENOMEM;
+
+ INIT_LIST_HEAD(&hdr10->ipipe_tbls->lut);
+ INIT_LIST_HEAD(&hdr10->ipipe_tbls->csca);
+ INIT_LIST_HEAD(&hdr10->ipipe_tbls->cscb);
+
+ hdr10->opipe_tbls = devm_kzalloc(dev, sizeof(*hdr10->opipe_tbls),
+ GFP_KERNEL);
+ if (!hdr10->opipe_tbls)
+ return -ENOMEM;
+
+ INIT_LIST_HEAD(&hdr10->opipe_tbls->lut);
+ INIT_LIST_HEAD(&hdr10->opipe_tbls->csc);
+
+ return 0;
+}
+
+int dcss_hdr10_init(struct dcss_soc *dcss, unsigned long hdr10_base)
+{
+ int ret;
+ struct dcss_hdr10_priv *hdr10;
+
+ hdr10 = devm_kzalloc(dcss->dev, sizeof(*hdr10), GFP_KERNEL);
+ if (!hdr10)
+ return -ENOMEM;
+
+ dcss->hdr10_priv = hdr10;
+ hdr10->dcss = dcss;
+
+ ret = dcss_hdr10_tbls_init(hdr10);
+ if (ret < 0) {
+ dev_err(dcss->dev, "hdr10: Cannot init table lists.\n");
+ return ret;
+ }
+
+#ifndef USE_TBL_HEADER
+ ret = request_firmware_nowait(THIS_MODULE, FW_ACTION_HOTPLUG, "dcss.fw",
+ dcss->dev, GFP_KERNEL, hdr10,
+ dcss_hdr10_fw_handler);
+ if (ret < 0) {
+ dev_err(dcss->dev, "hdr10: Cannot async load DCSS FW.\n");
+ return ret;
+ }
+#else
+ hdr10->fw_data = (u8 *)dcss_hdr10_tables;
+ hdr10->fw_size = sizeof(dcss_hdr10_tables);
+
+ dcss_hdr10_parse_fw_data(hdr10);
+#endif
+
+ return dcss_hdr10_ch_init_all(dcss, hdr10_base);
+}
+
+void dcss_hdr10_exit(struct dcss_soc *dcss)
+{
+}
+
+static u32 dcss_hdr10_get_bpc(u32 pix_format)
+{
+ u32 depth, bpc;
+
+ switch (pix_format) {
+ case DRM_FORMAT_NV12:
+ case DRM_FORMAT_NV21:
+ bpc = 8;
+ break;
+
+ case DRM_FORMAT_UYVY:
+ case DRM_FORMAT_VYUY:
+ case DRM_FORMAT_YUYV:
+ case DRM_FORMAT_YVYU:
+ bpc = 8;
+ break;
+
+ case DRM_FORMAT_P010:
+ bpc = 10;
+ break;
+
+ default:
+ depth = drm_format_info(pix_format)->depth;
+ bpc = depth == 30 ? 10 : 8;
+ break;
+ }
+
+ return bpc;
+}
+
+static u32 dcss_hdr10_pipe_desc(struct dcss_hdr10_pipe_cfg *pipe_cfg)
+{
+ u32 bpc, cs, desc;
+
+ bpc = dcss_hdr10_get_bpc(pipe_cfg->pixel_format);
+ cs = dcss_drm_fourcc_to_colorspace(pipe_cfg->pixel_format);
+
+ desc = bpc == 10 ? 2 << HDR10_BPC_POS : 1 << HDR10_BPC_POS;
+ desc |= cs == DCSS_COLORSPACE_YUV ? 2 << HDR10_CS_POS :
+ 1 << HDR10_CS_POS;
+ desc |= ((1 << pipe_cfg->nl) << HDR10_NL_POS) & HDR10_NL_MASK;
+ desc |= ((1 << pipe_cfg->pr) << HDR10_PR_POS) & HDR10_PR_MASK;
+ desc |= ((1 << pipe_cfg->g) << HDR10_G_POS) & HDR10_G_MASK;
+
+ return desc;
+}
+
+static u64 dcss_hdr10_get_desc(struct dcss_hdr10_pipe_cfg *ipipe_cfg,
+ struct dcss_hdr10_pipe_cfg *opipe_cfg)
+{
+ u32 ipipe_desc, opipe_desc;
+
+ ipipe_desc = dcss_hdr10_pipe_desc(ipipe_cfg) & (~HDR10_BPC_MASK);
+ ipipe_desc |= 2 << HDR10_BPC_POS;
+ opipe_desc = dcss_hdr10_pipe_desc(opipe_cfg);
+
+ return (ipipe_desc & 0xFFFF) |
+ (opipe_desc & 0xFFFF) << 16;
+}
+
+static void dcss_hdr10_pipe_setup(struct dcss_soc *dcss, int ch_num,
+ u64 desc)
+{
+ struct dcss_hdr10_ch *ch = &dcss->hdr10_priv->ch[ch_num];
+ bool pipe_cfg_chgd;
+ u32 *csca, *cscb, *lut;
+
+ pipe_cfg_chgd = ch->old_cfg_desc != desc;
+
+ if (!pipe_cfg_chgd)
+ return;
+
+ dcss_hdr10_get_tbls(dcss->hdr10_priv, ch_num != OPIPE_CH_NO,
+ desc, &lut, &csca, &cscb);
+ dcss_hdr10_write_pipe_tbls(dcss, ch_num, lut, csca, cscb);
+
+ ch->old_cfg_desc = desc;
+}
+
+void dcss_hdr10_setup(struct dcss_soc *dcss, int ch_num,
+ struct dcss_hdr10_pipe_cfg *ipipe_cfg,
+ struct dcss_hdr10_pipe_cfg *opipe_cfg)
+{
+ u64 desc = dcss_hdr10_get_desc(ipipe_cfg, opipe_cfg);
+
+ dcss_hdr10_pipe_setup(dcss, ch_num, desc);
+
+ /*
+ * Input pipe configuration doesn't matter for configuring the output
+ * pipe. So, will just mask off the input part of the descriptor.
+ */
+ dcss_hdr10_pipe_setup(dcss, OPIPE_CH_NO, desc | 0xfffe);
+}
+EXPORT_SYMBOL(dcss_hdr10_setup);
diff --git a/drivers/gpu/imx/dcss/dcss-prv.h b/drivers/gpu/imx/dcss/dcss-prv.h
new file mode 100644
index 000000000000..db6fc6687b65
--- /dev/null
+++ b/drivers/gpu/imx/dcss/dcss-prv.h
@@ -0,0 +1,199 @@
+/*
+ * Copyright (C) 2017-2018 NXP
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#ifndef __DCSS_PRV_H__
+#define __DCSS_PRV_H__
+
+#include <linux/pm_qos.h>
+
+#define SET 0x04
+#define CLR 0x08
+#define TGL 0x0C
+
+#define MAX_CLK_SRC 3
+
+#define dcss_writel(v, c) writel((v), (c))
+#define dcss_readl(c) readl(c)
+#define dcss_set(v, c) writel((v), (c) + SET)
+#define dcss_clr(v, c) writel((v), (c) + CLR)
+#define dcss_toggle(v, c) writel((v), (c) + TGL)
+#define dcss_update(v, m, c) writel((readl(c) & ~(m)) | (v), (c))
+
+#define DCSS_DBG_REG(reg) {.name = #reg, .ofs = reg}
+
+struct dcss_debug_reg {
+ char *name;
+ u32 ofs;
+};
+
+enum dcss_ctxld_ctx_type {
+ CTX_DB,
+ CTX_SB_HP, /* high-priority */
+ CTX_SB_LP, /* low-priority */
+};
+
+struct dcss_soc;
+struct dcss_devtype;
+
+struct dcss_soc {
+ struct device *dev;
+ const struct dcss_devtype *devtype;
+
+ u32 start_addr;
+
+ struct dcss_blkctl_priv *blkctl_priv;
+ struct dcss_ctxld_priv *ctxld_priv;
+ struct dcss_dpr_priv *dpr_priv;
+ struct dcss_dtg_priv *dtg_priv;
+ struct dcss_ss_priv *ss_priv;
+ struct dcss_hdr10_priv *hdr10_priv;
+ struct dcss_scaler_priv *scaler_priv;
+ struct dcss_dtrc_priv *dtrc_priv;
+ struct dcss_dec400d_priv *dec400d_priv;
+ struct dcss_wrscl_priv *wrscl_priv;
+ struct dcss_rdsrc_priv *rdsrc_priv;
+ struct dcss_pll_priv *pll_priv;
+
+ struct clk *apb_clk;
+ struct clk *axi_clk;
+ struct clk *pix_clk;
+ struct clk *rtrm_clk;
+ struct clk *dtrc_clk;
+ struct clk *sel_clk;
+ struct clk *pll_clk;
+ struct clk *src_clk[MAX_CLK_SRC];
+
+ void (*dcss_disable_callback)(void *data);
+
+ bool bus_freq_req;
+ bool clks_on;
+
+ struct pm_qos_request pm_qos_req;
+};
+
+/* BLKCTL */
+int dcss_blkctl_init(struct dcss_soc *dcss, unsigned long blkctl_base);
+void dcss_blkctl_cfg(struct dcss_soc *dcss);
+void dcss_blkctl_exit(struct dcss_soc *dcss);
+
+/* CTXLD */
+int dcss_ctxld_init(struct dcss_soc *dcss, unsigned long ctxld_base);
+void dcss_ctxld_hw_cfg(struct dcss_soc *dcss);
+void dcss_ctxld_exit(struct dcss_soc *dcss);
+void dcss_ctxld_write(struct dcss_soc *dcss, u32 ctx_id, u32 val, u32 reg_idx);
+void dcss_ctxld_update(struct dcss_soc *dcss, u32 ctx_id, u32 val, u32 mask,
+ u32 reg_idx);
+void dcss_ctxld_dump(struct seq_file *s, void *data);
+int dcss_ctxld_resume(struct dcss_soc *dcss);
+int dcss_ctxld_suspend(struct dcss_soc *dcss);
+void dcss_ctxld_write_irqsafe(struct dcss_soc *dcss, u32 ctx_id, u32 val,
+ u32 reg_ofs);
+void dcss_ctxld_kick(struct dcss_soc *dcss);
+
+/* DPR */
+int dcss_dpr_init(struct dcss_soc *dcss, unsigned long dpr_base);
+void dcss_dpr_exit(struct dcss_soc *dcss);
+void dcss_dpr_write_sysctrl(struct dcss_soc *dcss);
+void dcss_dpr_irq_enable(struct dcss_soc *dcss, bool en);
+
+/* DTG */
+int dcss_dtg_init(struct dcss_soc *dcss, unsigned long dtg_base);
+void dcss_dtg_exit(struct dcss_soc *dcss);
+void dcss_dtg_vblank_irq_enable(struct dcss_soc *dcss, bool en);
+void dcss_dtg_vblank_irq_clear(struct dcss_soc *dcss);
+
+/* SUBSAM */
+int dcss_ss_init(struct dcss_soc *dcss, unsigned long subsam_base);
+void dcss_ss_exit(struct dcss_soc *dcss);
+
+/* HDR10 */
+int dcss_hdr10_init(struct dcss_soc *dcss, unsigned long hdr10_base);
+void dcss_hdr10_exit(struct dcss_soc *dcss);
+void dcss_hdr10_cfg(struct dcss_soc *dcss);
+
+/* SCALER */
+int dcss_scaler_init(struct dcss_soc *dcss, unsigned long scaler_base);
+void dcss_scaler_exit(struct dcss_soc *dcss);
+void dcss_scaler_write_sclctrl(struct dcss_soc *dcss);
+
+/* DTRC */
+int dcss_dtrc_init(struct dcss_soc *dcss, unsigned long dtrc_base);
+void dcss_dtrc_exit(struct dcss_soc *dcss);
+void dcss_dtrc_switch_banks(struct dcss_soc *dcss);
+bool dcss_dtrc_is_running(struct dcss_soc *dcss, int ch_num);
+
+/* DEC400d */
+int dcss_dec400d_init(struct dcss_soc *dcss, unsigned long dec400d_base);
+void dcss_dec400d_exit(struct dcss_soc *dcss);
+
+/* enums common to both WRSCL and RDSRC */
+enum dcss_wrscl_rdsrc_psize {
+ PSIZE_64,
+ PSIZE_128,
+ PSIZE_256,
+ PSIZE_512,
+ PSIZE_1024,
+ PSIZE_2048,
+ PSIZE_4096,
+};
+
+enum dcss_wrscl_rdsrc_tsize {
+ TSIZE_64,
+ TSIZE_128,
+ TSIZE_256,
+ TSIZE_512,
+};
+
+enum dcss_wrscl_rdsrc_fifo_size {
+ FIFO_512,
+ FIFO_1024,
+ FIFO_2048,
+ FIFO_4096,
+};
+
+enum dcss_wrscl_rdsrc_bpp {
+ BPP_38, /* 38 bit unpacked components */
+ BPP_32_UPCONVERT,
+ BPP_32_10BIT_OUTPUT,
+ BPP_20, /* 10-bit YUV422 */
+ BPP_16, /* 8-bit YUV422 */
+};
+
+/* WRSCL */
+int dcss_wrscl_init(struct dcss_soc *dcss, unsigned long wrscl_base);
+void dcss_wrscl_exit(struct dcss_soc *dcss);
+u32 dcss_wrscl_setup(struct dcss_soc *dcss, u32 pix_format, u32 pix_clk_hz,
+ u32 dst_xres, u32 dst_yres);
+void dcss_wrscl_enable(struct dcss_soc *dcss, bool en);
+
+/* RDSRC */
+int dcss_rdsrc_init(struct dcss_soc *dcss, unsigned long rdsrc_base);
+void dcss_rdsrc_exit(struct dcss_soc *dcss);
+void dcss_rdsrc_setup(struct dcss_soc *dcss, u32 pix_format, u32 dst_xres,
+ u32 dst_yres, u32 base_addr);
+void dcss_rdsrc_enable(struct dcss_soc *dcss, bool en);
+
+/* debug: dump registers routines */
+void dcss_blkctl_dump_regs(struct seq_file *s, void *data);
+void dcss_dtrc_dump_regs(struct seq_file *s, void *data);
+void dcss_dpr_dump_regs(struct seq_file *s, void *data);
+void dcss_dtg_dump_regs(struct seq_file *s, void *data);
+void dcss_ss_dump_regs(struct seq_file *s, void *data);
+void dcss_scaler_dump_regs(struct seq_file *s, void *data);
+void dcss_ctxld_dump_regs(struct seq_file *s, void *data);
+void dcss_hdr10_dump_regs(struct seq_file *s, void *data);
+void dcss_wrscl_dump_regs(struct seq_file *s, void *data);
+void dcss_rdsrc_dump_regs(struct seq_file *s, void *data);
+
+#endif /* __DCSS_PRV_H__ */
diff --git a/drivers/gpu/imx/dcss/dcss-rdsrc.c b/drivers/gpu/imx/dcss/dcss-rdsrc.c
new file mode 100644
index 000000000000..1fa9c099dfc7
--- /dev/null
+++ b/drivers/gpu/imx/dcss/dcss-rdsrc.c
@@ -0,0 +1,155 @@
+/*
+ * Copyright (C) 2017 NXP
+ *
+ * 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/device.h>
+#include <linux/io.h>
+#include <linux/dma-mapping.h>
+
+#include <video/imx-dcss.h>
+#include "dcss-prv.h"
+
+#define USE_CTXLD
+
+#define DCSS_RDSRC_CTRL_STATUS 0x00
+#define RDSRC_RD_ERR BIT(31)
+#define RDSRC_FRAME_COMP BIT(30)
+#define RDSRC_FIFO_SIZE_POS 16
+#define RDSRC_FIFO_SIZE_MASK GENMASK(22, 16)
+#define RDSRC_RD_ERR_EN BIT(15)
+#define RDSRC_FRAME_COMP_EN BIT(14)
+#define RDSRC_P_SIZE_POS 7
+#define RDSRC_P_SIZE_MASK GENMASK(9, 7)
+#define RDSRC_T_SIZE_POS 5
+#define RDSRC_T_SIZE_MASK GENMASK(6, 5)
+#define RDSRC_BPP_POS 2
+#define RDSRC_BPP_MASK GENMASK(4, 2)
+#define RDSRC_ENABLE BIT(0)
+#define DCSS_RDSRC_BASE_ADDR 0x10
+#define DCSS_RDSRC_PITCH 0x14
+#define DCSS_RDSRC_WIDTH 0x18
+#define DCSS_RDSRC_HEIGHT 0x1C
+
+struct dcss_rdsrc_priv {
+ void __iomem *base_reg;
+ u32 base_ofs;
+ struct dcss_soc *dcss;
+
+ u32 ctx_id;
+
+ u32 buf_addr;
+
+ u32 ctrl_status;
+};
+
+#ifdef CONFIG_DEBUG_FS
+static struct dcss_debug_reg rdsrc_debug_reg[] = {
+ DCSS_DBG_REG(DCSS_RDSRC_CTRL_STATUS),
+ DCSS_DBG_REG(DCSS_RDSRC_BASE_ADDR),
+ DCSS_DBG_REG(DCSS_RDSRC_PITCH),
+ DCSS_DBG_REG(DCSS_RDSRC_WIDTH),
+ DCSS_DBG_REG(DCSS_RDSRC_HEIGHT),
+};
+
+void dcss_rdsrc_dump_regs(struct seq_file *s, void *data)
+{
+ struct dcss_soc *dcss = data;
+ int i;
+
+ seq_puts(s, ">> Dumping RD_SRC:\n");
+ for (i = 0; i < ARRAY_SIZE(rdsrc_debug_reg); i++) {
+ seq_printf(s, "%-35s(0x%04x) -> 0x%08x\n",
+ rdsrc_debug_reg[i].name,
+ rdsrc_debug_reg[i].ofs,
+ dcss_readl(dcss->rdsrc_priv->base_reg +
+ rdsrc_debug_reg[i].ofs));
+ }
+}
+#endif
+
+static void dcss_rdsrc_write(struct dcss_rdsrc_priv *rdsrc, u32 val, u32 ofs)
+{
+#if !defined(USE_CTXLD)
+ dcss_writel(val, rdsrc->base_reg + ofs);
+#else
+ dcss_ctxld_write(rdsrc->dcss, rdsrc->ctx_id,
+ val, rdsrc->base_ofs + ofs);
+#endif
+}
+
+int dcss_rdsrc_init(struct dcss_soc *dcss, unsigned long rdsrc_base)
+{
+ struct dcss_rdsrc_priv *rdsrc;
+
+ rdsrc = devm_kzalloc(dcss->dev, sizeof(*rdsrc), GFP_KERNEL);
+ if (!rdsrc)
+ return -ENOMEM;
+
+ rdsrc->base_reg = devm_ioremap(dcss->dev, rdsrc_base, SZ_4K);
+ if (!rdsrc->base_reg) {
+ dev_err(dcss->dev, "rdsrc: unable to remap base\n");
+ return -ENOMEM;
+ }
+
+ dcss->rdsrc_priv = rdsrc;
+ rdsrc->base_ofs = rdsrc_base;
+ rdsrc->dcss = dcss;
+
+#if defined(USE_CTXLD)
+ rdsrc->ctx_id = CTX_SB_HP;
+#endif
+
+ return 0;
+}
+
+void dcss_rdsrc_exit(struct dcss_soc *dcss)
+{
+}
+
+void dcss_rdsrc_setup(struct dcss_soc *dcss, u32 pix_format, u32 dst_xres,
+ u32 dst_yres, u32 base_addr)
+{
+ struct dcss_rdsrc_priv *rdsrc = dcss->rdsrc_priv;
+ u32 buf_size, pitch, bpp;
+
+ /* since the scaler output is YUV444, the RDSRC output has to match */
+ bpp = 4;
+
+ rdsrc->ctrl_status = FIFO_512 << RDSRC_FIFO_SIZE_POS;
+ rdsrc->ctrl_status |= PSIZE_256 << RDSRC_P_SIZE_POS;
+ rdsrc->ctrl_status |= TSIZE_256 << RDSRC_T_SIZE_POS;
+ rdsrc->ctrl_status |= BPP_32_10BIT_OUTPUT << RDSRC_BPP_POS;
+
+ buf_size = dst_xres * dst_yres * bpp;
+ pitch = dst_xres * bpp;
+
+ rdsrc->buf_addr = base_addr;
+
+ dcss_rdsrc_write(rdsrc, rdsrc->buf_addr, DCSS_RDSRC_BASE_ADDR);
+ dcss_rdsrc_write(rdsrc, pitch, DCSS_RDSRC_PITCH);
+ dcss_rdsrc_write(rdsrc, dst_xres, DCSS_RDSRC_WIDTH);
+ dcss_rdsrc_write(rdsrc, dst_yres, DCSS_RDSRC_HEIGHT);
+}
+
+void dcss_rdsrc_enable(struct dcss_soc *dcss, bool en)
+{
+ struct dcss_rdsrc_priv *rdsrc = dcss->rdsrc_priv;
+
+ /* RDSRC is turned off by setting the width and height to 0 */
+ if (!en) {
+ dcss_rdsrc_write(rdsrc, 0, DCSS_RDSRC_WIDTH);
+ dcss_rdsrc_write(rdsrc, 0, DCSS_RDSRC_HEIGHT);
+ }
+
+ dcss_rdsrc_write(rdsrc, rdsrc->ctrl_status, DCSS_RDSRC_CTRL_STATUS);
+}
diff --git a/drivers/gpu/imx/dcss/dcss-scaler.c b/drivers/gpu/imx/dcss/dcss-scaler.c
new file mode 100644
index 000000000000..051bc4b03f88
--- /dev/null
+++ b/drivers/gpu/imx/dcss/dcss-scaler.c
@@ -0,0 +1,996 @@
+/*
+ * Copyright (C) 2017 NXP
+ *
+ * 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/device.h>
+#include <linux/bitops.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <drm/drm_fourcc.h>
+
+#include <video/imx-dcss.h>
+#include "dcss-prv.h"
+
+#define USE_CTXLD
+
+#define DCSS_SCALER_CTRL 0x00
+#define SCALER_EN BIT(0)
+#define REPEAT_EN BIT(4)
+#define SCALE2MEM_EN BIT(8)
+#define MEM2OFIFO_EN BIT(12)
+#define DCSS_SCALER_OFIFO_CTRL 0x04
+#define OFIFO_LOW_THRES_POS 0
+#define OFIFO_LOW_THRES_MASK GENMASK(9, 0)
+#define OFIFO_HIGH_THRES_POS 16
+#define OFIFO_HIGH_THRES_MASK GENMASK(25, 16)
+#define UNDERRUN_DETECT_CLR BIT(26)
+#define LOW_THRES_DETECT_CLR BIT(27)
+#define HIGH_THRES_DETECT_CLR BIT(28)
+#define UNDERRUN_DETECT_EN BIT(29)
+#define LOW_THRES_DETECT_EN BIT(30)
+#define HIGH_THRES_DETECT_EN BIT(31)
+#define DCSS_SCALER_SDATA_CTRL 0x08
+#define YUV_EN BIT(0)
+#define RTRAM_8LINES BIT(1)
+#define Y_UV_BYTE_SWAP BIT(4)
+#define A2R10G10B10_FORMAT_POS 8
+#define A2R10G10B10_FORMAT_MASK GENMASK(11, 8)
+#define DCSS_SCALER_BIT_DEPTH 0x0C
+#define LUM_BIT_DEPTH_POS 0
+#define LUM_BIT_DEPTH_MASK GENMASK(1, 0)
+#define CHR_BIT_DEPTH_POS 4
+#define CHR_BIT_DEPTH_MASK GENMASK(5, 4)
+#define DCSS_SCALER_SRC_FORMAT 0x10
+#define DCSS_SCALER_DST_FORMAT 0x14
+#define FORMAT_MASK GENMASK(1, 0)
+#define DCSS_SCALER_SRC_LUM_RES 0x18
+#define DCSS_SCALER_SRC_CHR_RES 0x1C
+#define DCSS_SCALER_DST_LUM_RES 0x20
+#define DCSS_SCALER_DST_CHR_RES 0x24
+#define WIDTH_POS 0
+#define WIDTH_MASK GENMASK(11, 0)
+#define HEIGHT_POS 16
+#define HEIGHT_MASK GENMASK(27, 16)
+#define DCSS_SCALER_V_LUM_START 0x48
+#define V_START_MASK GENMASK(15, 0)
+#define DCSS_SCALER_V_LUM_INC 0x4C
+#define V_INC_MASK GENMASK(15, 0)
+#define DCSS_SCALER_H_LUM_START 0x50
+#define H_START_MASK GENMASK(18, 0)
+#define DCSS_SCALER_H_LUM_INC 0x54
+#define H_INC_MASK GENMASK(15, 0)
+#define DCSS_SCALER_V_CHR_START 0x58
+#define DCSS_SCALER_V_CHR_INC 0x5C
+#define DCSS_SCALER_H_CHR_START 0x60
+#define DCSS_SCALER_H_CHR_INC 0x64
+#define DCSS_SCALER_COEF_VLUM 0x80
+#define DCSS_SCALER_COEF_HLUM 0x140
+#define DCSS_SCALER_COEF_VCHR 0x200
+#define DCSS_SCALER_COEF_HCHR 0x300
+
+static struct dcss_debug_reg scaler_debug_reg[] = {
+ DCSS_DBG_REG(DCSS_SCALER_CTRL),
+ DCSS_DBG_REG(DCSS_SCALER_OFIFO_CTRL),
+ DCSS_DBG_REG(DCSS_SCALER_SDATA_CTRL),
+ DCSS_DBG_REG(DCSS_SCALER_BIT_DEPTH),
+ DCSS_DBG_REG(DCSS_SCALER_SRC_FORMAT),
+ DCSS_DBG_REG(DCSS_SCALER_DST_FORMAT),
+ DCSS_DBG_REG(DCSS_SCALER_SRC_LUM_RES),
+ DCSS_DBG_REG(DCSS_SCALER_SRC_CHR_RES),
+ DCSS_DBG_REG(DCSS_SCALER_DST_LUM_RES),
+ DCSS_DBG_REG(DCSS_SCALER_DST_CHR_RES),
+ DCSS_DBG_REG(DCSS_SCALER_V_LUM_START),
+ DCSS_DBG_REG(DCSS_SCALER_V_LUM_INC),
+ DCSS_DBG_REG(DCSS_SCALER_H_LUM_START),
+ DCSS_DBG_REG(DCSS_SCALER_H_LUM_INC),
+ DCSS_DBG_REG(DCSS_SCALER_V_CHR_START),
+ DCSS_DBG_REG(DCSS_SCALER_V_CHR_INC),
+ DCSS_DBG_REG(DCSS_SCALER_H_CHR_START),
+ DCSS_DBG_REG(DCSS_SCALER_H_CHR_INC),
+};
+
+struct dcss_scaler_ch {
+ void __iomem *base_reg;
+ u32 base_ofs;
+
+ u32 ctx_id;
+
+ u32 sdata_ctrl;
+ u32 scaler_ctrl;
+
+ bool scaler_ctrl_chgd;
+
+ u32 c_vstart;
+ u32 c_hstart;
+};
+
+struct dcss_scaler_priv {
+ struct dcss_soc *dcss;
+ struct dcss_scaler_ch ch[3];
+
+ int ch_using_wrscl;
+};
+
+/* scaler coefficients generator */
+#define PSC_FRAC_BITS 30
+#define PSC_FRAC_SCALE BIT(PSC_FRAC_BITS)
+#define PSC_BITS_FOR_PHASE 4
+#define PSC_NUM_PHASES 16
+#define PSC_STORED_PHASES (PSC_NUM_PHASES / 2 + 1)
+#define PSC_NUM_TAPS 7
+#define PSC_NUM_TAPS_RGBA 5
+#define PSC_COEFF_PRECISION 10
+#define PSC_PHASE_FRACTION_BITS 13
+#define PSC_PHASE_MASK (PSC_NUM_PHASES - 1)
+#define PSC_Q_FRACTION 19
+#define PSC_Q_ROUND_OFFSET (1 << (PSC_Q_FRACTION - 1))
+
+/**
+ * mult_q() - Performs fixed-point multiplication.
+ * @A: multiplier
+ * @B: multiplicand
+ */
+static int mult_q(int A, int B)
+{
+ int result;
+ s64 temp;
+
+ temp = (int64_t)A * (int64_t)B;
+ temp += PSC_Q_ROUND_OFFSET;
+ result = (int)(temp >> PSC_Q_FRACTION);
+ return result;
+}
+
+/**
+ * div_q() - Performs fixed-point division.
+ * @A: dividend
+ * @B: divisor
+ */
+static int div_q(int A, int B)
+{
+ int result;
+ s64 temp;
+
+ temp = (int64_t)A << PSC_Q_FRACTION;
+ if ((temp >= 0 && B >= 0) || (temp < 0 && B < 0))
+ temp += B / 2;
+ else
+ temp -= B / 2;
+
+ result = (int)(temp / B);
+ return result;
+}
+
+/**
+ * exp_approx_q() - Compute approximation to exp(x) function using Taylor
+ * series.
+ * @x: fixed-point argument of exp function
+ */
+static int exp_approx_q(int x)
+{
+ int sum = 1 << PSC_Q_FRACTION;
+ int term = 1 << PSC_Q_FRACTION;
+
+ term = mult_q(term, div_q(x, 1 << PSC_Q_FRACTION));
+ sum += term;
+ term = mult_q(term, div_q(x, 2 << PSC_Q_FRACTION));
+ sum += term;
+ term = mult_q(term, div_q(x, 3 << PSC_Q_FRACTION));
+ sum += term;
+ term = mult_q(term, div_q(x, 4 << PSC_Q_FRACTION));
+ sum += term;
+
+ return sum;
+}
+
+/**
+ * dcss_scaler_gaussian_filter() -Generate gaussian prototype filter.
+ * @fc_q: fixed-point cutoff frequency normalized to range [0, 1]
+ * @use_5_taps: indicates whether to use 5 taps or 7 taps
+ * @coef: output filter coefficients
+ */
+static void dcss_scaler_gaussian_filter(int fc_q, bool use_5_taps,
+ bool phase0_identity,
+ int coef[][PSC_NUM_TAPS])
+{
+ int sigma_q, g0_q, g1_q, g2_q;
+ int tap_cnt1, tap_cnt2, phase_cnt;
+ int mid;
+ int phase;
+ int i;
+
+ if (use_5_taps)
+ for (phase = 0; phase < PSC_STORED_PHASES; phase++) {
+ coef[phase][0] = 0;
+ coef[phase][PSC_NUM_TAPS - 1] = 0;
+ }
+
+ /* seed coefficient scanner */
+ mid = (PSC_NUM_PHASES * (use_5_taps ? PSC_NUM_TAPS_RGBA : PSC_NUM_TAPS)) / 2 - 1;
+ phase_cnt = (PSC_NUM_PHASES * (PSC_NUM_TAPS + 1)) / 2;
+ tap_cnt1 = (PSC_NUM_PHASES * PSC_NUM_TAPS) / 2;
+ tap_cnt2 = (PSC_NUM_PHASES * PSC_NUM_TAPS) / 2;
+
+ /* seed gaussian filter generator */
+ sigma_q = div_q(PSC_Q_ROUND_OFFSET, fc_q);
+ g0_q = 1 << PSC_Q_FRACTION;
+ g1_q = exp_approx_q(div_q(-PSC_Q_ROUND_OFFSET, mult_q(sigma_q, sigma_q)));
+ g2_q = mult_q(g1_q, g1_q);
+ coef[phase_cnt & PSC_PHASE_MASK][tap_cnt1 >> PSC_BITS_FOR_PHASE] = g0_q;
+
+ for (i = 0; i < mid; i++) {
+ phase_cnt++;
+ tap_cnt1--;
+ tap_cnt2++;
+
+ g0_q = mult_q(g0_q, g1_q);
+ g1_q = mult_q(g1_q, g2_q);
+
+ if ((phase_cnt & PSC_PHASE_MASK) <= 8)
+ coef[phase_cnt & PSC_PHASE_MASK][tap_cnt1 >> PSC_BITS_FOR_PHASE] = g0_q;
+ if (((-phase_cnt) & PSC_PHASE_MASK) <= 8)
+ coef[(-phase_cnt) & PSC_PHASE_MASK][tap_cnt2 >> PSC_BITS_FOR_PHASE] = g0_q;
+ }
+
+ phase_cnt++;
+ tap_cnt1--;
+ coef[phase_cnt & PSC_PHASE_MASK][tap_cnt1 >> PSC_BITS_FOR_PHASE] = 0;
+
+ /* override phase 0 with identity filter if specified */
+ if (phase0_identity)
+ for (i = 0; i < PSC_NUM_TAPS; i++)
+ coef[0][i] = i == (PSC_NUM_TAPS >> 1) ? (1 << PSC_COEFF_PRECISION) : 0;
+
+ /* normalize coef */
+ for (phase = 0; phase < PSC_STORED_PHASES; phase++) {
+ int sum = 0;
+ s64 ll_temp;
+
+ for (i = 0; i < PSC_NUM_TAPS; i++)
+ sum += coef[phase][i];
+ for (i = 0; i < PSC_NUM_TAPS; i++) {
+ ll_temp = coef[phase][i];
+ ll_temp <<= PSC_COEFF_PRECISION;
+ ll_temp += sum >> 1;
+ ll_temp /= sum;
+ coef[phase][i] = (int)ll_temp;
+ }
+ }
+}
+
+/**
+ * dcss_scaler_filter_design() - Compute filter coefficients using Gaussian filter.
+ * @src_length: length of input
+ * @dst_length: length of output
+ * @use_5_taps: 0 for 7 taps per phase, 1 for 5 taps
+ * @coef: output coefficients
+ */
+static void dcss_scaler_filter_design(int src_length, int dst_length,
+ bool use_5_taps, bool phase0_identity,
+ int coef[][PSC_NUM_TAPS])
+{
+ int fc_q;
+
+ /* compute cutoff frequency */
+ if (dst_length >= src_length)
+ fc_q = div_q(1, PSC_NUM_PHASES);
+ else
+ fc_q = div_q(dst_length, src_length * PSC_NUM_PHASES);
+
+ /* compute gaussian filter coefficients */
+ dcss_scaler_gaussian_filter(fc_q, use_5_taps, phase0_identity, coef);
+}
+
+static void dcss_scaler_write(struct dcss_scaler_priv *scl, int ch_num,
+ u32 val, u32 ofs)
+{
+#if !defined(USE_CTXLD)
+ dcss_writel(val, scl->ch[ch_num].base_reg + ofs);
+#else
+ dcss_ctxld_write(scl->dcss, scl->ch[ch_num].ctx_id,
+ val, scl->ch[ch_num].base_ofs + ofs);
+#endif
+}
+
+#ifdef CONFIG_DEBUG_FS
+void dcss_scaler_dump_regs(struct seq_file *s, void *data)
+{
+ struct dcss_soc *dcss = data;
+ int i, j;
+
+ for (i = 0; i < 3; i++) {
+ seq_printf(s, ">> Dumping SCALER CH %d:\n", i);
+ for (j = 0; j < ARRAY_SIZE(scaler_debug_reg); j++) {
+ seq_printf(s, "%-35s(0x%04x) -> 0x%08x\n",
+ scaler_debug_reg[j].name,
+ scaler_debug_reg[j].ofs,
+ dcss_readl(dcss->scaler_priv->ch[i].base_reg +
+ scaler_debug_reg[j].ofs));
+ }
+ }
+}
+#endif
+
+static int dcss_scaler_ch_init_all(struct dcss_soc *dcss,
+ unsigned long scaler_base)
+{
+ struct dcss_scaler_priv *scaler = dcss->scaler_priv;
+ struct dcss_scaler_ch *ch;
+ int i;
+
+ for (i = 0; i < 3; i++) {
+ ch = &scaler->ch[i];
+
+ ch->base_ofs = scaler_base + i * 0x400;
+
+ ch->base_reg = devm_ioremap(dcss->dev, ch->base_ofs, SZ_4K);
+ if (!ch->base_reg) {
+ dev_err(dcss->dev, "scaler: unable to remap ch base\n");
+ return -ENOMEM;
+ }
+
+#if defined(USE_CTXLD)
+ ch->ctx_id = CTX_SB_HP;
+#endif
+ }
+
+ return 0;
+}
+
+int dcss_scaler_init(struct dcss_soc *dcss, unsigned long scaler_base)
+{
+ struct dcss_scaler_priv *scaler;
+
+ scaler = devm_kzalloc(dcss->dev, sizeof(*scaler), GFP_KERNEL);
+ if (!scaler)
+ return -ENOMEM;
+
+ dcss->scaler_priv = scaler;
+ scaler->dcss = dcss;
+
+ scaler->ch_using_wrscl = -1;
+
+ return dcss_scaler_ch_init_all(dcss, scaler_base);
+}
+
+void dcss_scaler_exit(struct dcss_soc *dcss)
+{
+ struct dcss_scaler_priv *scaler = dcss->scaler_priv;
+ int ch_no;
+
+ for (ch_no = 0; ch_no < 3; ch_no++) {
+ struct dcss_scaler_ch *ch = &scaler->ch[ch_no];
+
+ dcss_writel(0, ch->base_reg + DCSS_SCALER_CTRL);
+ }
+}
+
+void dcss_scaler_enable(struct dcss_soc *dcss, int ch_num, bool en)
+{
+ struct dcss_scaler_priv *scaler = dcss->scaler_priv;
+ struct dcss_scaler_ch *ch = &scaler->ch[ch_num];
+ u32 scaler_ctrl;
+
+ if (scaler->ch_using_wrscl == ch_num) {
+ if (en) {
+ scaler_ctrl = SCALE2MEM_EN | MEM2OFIFO_EN | REPEAT_EN;
+ } else {
+ dcss_wrscl_enable(dcss, false);
+ dcss_rdsrc_enable(dcss, false);
+
+ scaler->ch_using_wrscl = -1;
+ scaler_ctrl = 0;
+ }
+ } else {
+ scaler_ctrl = en ? SCALER_EN | REPEAT_EN : 0;
+ }
+
+ if (en)
+ dcss_scaler_write(dcss->scaler_priv, ch_num, ch->sdata_ctrl,
+ DCSS_SCALER_SDATA_CTRL);
+
+ if (ch->scaler_ctrl != scaler_ctrl)
+ ch->scaler_ctrl_chgd = true;
+
+ ch->scaler_ctrl = scaler_ctrl;
+}
+EXPORT_SYMBOL(dcss_scaler_enable);
+
+static void dcss_scaler_yuv_enable(struct dcss_soc *dcss, int ch_num, bool en)
+{
+ struct dcss_scaler_ch *ch = &dcss->scaler_priv->ch[ch_num];
+
+ ch->sdata_ctrl &= ~YUV_EN;
+ ch->sdata_ctrl |= en ? YUV_EN : 0;
+}
+
+static void dcss_scaler_rtr_8lines_enable(struct dcss_soc *dcss, int ch_num,
+ bool en)
+{
+ struct dcss_scaler_ch *ch = &dcss->scaler_priv->ch[ch_num];
+
+ ch->sdata_ctrl &= ~RTRAM_8LINES;
+ ch->sdata_ctrl |= en ? RTRAM_8LINES : 0;
+}
+
+static void dcss_scaler_bit_depth_set(struct dcss_soc *dcss, int ch_num,
+ int depth)
+{
+ u32 val;
+
+ val = depth == 30 ? 2 : 0;
+
+ dcss_scaler_write(dcss->scaler_priv, ch_num,
+ ((val << CHR_BIT_DEPTH_POS) & CHR_BIT_DEPTH_MASK) |
+ ((val << LUM_BIT_DEPTH_POS) & LUM_BIT_DEPTH_MASK),
+ DCSS_SCALER_BIT_DEPTH);
+}
+
+enum buffer_format {
+ BUF_FMT_YUV420,
+ BUF_FMT_YUV422,
+ BUF_FMT_ARGB8888_YUV444,
+};
+
+enum chroma_location {
+ PSC_LOC_HORZ_0_VERT_1_OVER_4 = 0,
+ PSC_LOC_HORZ_1_OVER_4_VERT_1_OVER_4 = 1,
+ PSC_LOC_HORZ_0_VERT_0 = 2,
+ PSC_LOC_HORZ_1_OVER_4_VERT_0 = 3,
+ PSC_LOC_HORZ_0_VERT_1_OVER_2 = 4,
+ PSC_LOC_HORZ_1_OVER_4_VERT_1_OVER_2 = 5
+};
+
+static void dcss_scaler_format_set(struct dcss_soc *dcss, int ch_num,
+ enum buffer_format src_fmt,
+ enum buffer_format dst_fmt)
+{
+ dcss_scaler_write(dcss->scaler_priv, ch_num, src_fmt,
+ DCSS_SCALER_SRC_FORMAT);
+ dcss_scaler_write(dcss->scaler_priv, ch_num, dst_fmt,
+ DCSS_SCALER_DST_FORMAT);
+}
+
+static void dcss_scaler_res_set(struct dcss_soc *dcss, int ch_num,
+ int src_xres, int src_yres,
+ int dst_xres, int dst_yres,
+ u32 pix_format, enum buffer_format dst_format)
+{
+ u32 lsrc_xres, lsrc_yres, csrc_xres, csrc_yres;
+ u32 ldst_xres, ldst_yres, cdst_xres, cdst_yres;
+ bool src_is_444 = true;
+
+ lsrc_xres = csrc_xres = src_xres;
+ lsrc_yres = csrc_yres = src_yres;
+ ldst_xres = cdst_xres = dst_xres;
+ ldst_yres = cdst_yres = dst_yres;
+
+ if (pix_format == DRM_FORMAT_UYVY || pix_format == DRM_FORMAT_VYUY ||
+ pix_format == DRM_FORMAT_YUYV || pix_format == DRM_FORMAT_YVYU) {
+ csrc_xres >>= 1;
+ src_is_444 = false;
+ } else if (pix_format == DRM_FORMAT_NV12 ||
+ pix_format == DRM_FORMAT_NV21 ||
+ pix_format == DRM_FORMAT_P010) {
+ csrc_xres >>= 1;
+ csrc_yres >>= 1;
+ src_is_444 = false;
+ }
+
+ if (dst_format == BUF_FMT_YUV422)
+ cdst_xres >>= 1;
+
+ /* for 4:4:4 to 4:2:2 conversion, source height should be 1 less */
+ if (src_is_444 && dst_format == BUF_FMT_YUV422) {
+ lsrc_yres--;
+ csrc_yres--;
+ }
+
+ dcss_scaler_write(dcss->scaler_priv, ch_num,
+ (((lsrc_yres - 1) << HEIGHT_POS) & HEIGHT_MASK) |
+ (((lsrc_xres - 1) << WIDTH_POS) & WIDTH_MASK),
+ DCSS_SCALER_SRC_LUM_RES);
+ dcss_scaler_write(dcss->scaler_priv, ch_num,
+ (((csrc_yres - 1) << HEIGHT_POS) & HEIGHT_MASK) |
+ (((csrc_xres - 1) << WIDTH_POS) & WIDTH_MASK),
+ DCSS_SCALER_SRC_CHR_RES);
+ dcss_scaler_write(dcss->scaler_priv, ch_num,
+ (((ldst_yres - 1) << HEIGHT_POS) & HEIGHT_MASK) |
+ (((ldst_xres - 1) << WIDTH_POS) & WIDTH_MASK),
+ DCSS_SCALER_DST_LUM_RES);
+ dcss_scaler_write(dcss->scaler_priv, ch_num,
+ (((cdst_yres - 1) << HEIGHT_POS) & HEIGHT_MASK) |
+ (((cdst_xres - 1) << WIDTH_POS) & WIDTH_MASK),
+ DCSS_SCALER_DST_CHR_RES);
+}
+
+#define max_downscale(ratio) ((ratio) << 13)
+#define max_upscale(ratio) ((1 << 13) / (ratio))
+
+struct dcss_scaler_ratios {
+ u16 downscale;
+ u16 upscale;
+};
+
+static const struct dcss_scaler_ratios dcss_scaler_ratios[] = {
+ {max_downscale(3), max_upscale(8)},
+ {max_downscale(5), max_upscale(8)},
+ {max_downscale(5), max_upscale(8)},
+};
+
+static const struct dcss_scaler_ratios dcss_scaler_wrscl_ratios[] = {
+ {max_downscale(5), max_upscale(8)},
+ {max_downscale(7), max_upscale(8)},
+ {max_downscale(7), max_upscale(8)},
+};
+
+static bool dcss_scaler_fractions_set(struct dcss_soc *dcss, int ch_num,
+ int src_xres, int src_yres,
+ int dst_xres, int dst_yres,
+ u32 src_format, u32 dst_format,
+ enum chroma_location src_chroma_loc)
+{
+ struct dcss_scaler_ch *ch = &dcss->scaler_priv->ch[ch_num];
+ int src_c_xres, src_c_yres, dst_c_xres, dst_c_yres;
+ u32 l_vinc, l_hinc, c_vinc, c_hinc;
+ u32 c_vstart, c_hstart;
+
+ src_c_xres = src_xres;
+ src_c_yres = src_yres;
+ dst_c_xres = dst_xres;
+ dst_c_yres = dst_yres;
+
+ c_vstart = 0;
+ c_hstart = 0;
+
+ /* adjustments for source chroma location */
+ if (src_format == BUF_FMT_YUV420) {
+ /* vertical input chroma position adjustment */
+ switch (src_chroma_loc) {
+ case PSC_LOC_HORZ_0_VERT_1_OVER_4:
+ case PSC_LOC_HORZ_1_OVER_4_VERT_1_OVER_4:
+ /*
+ * move chroma up to first luma line
+ * (1/4 chroma input line spacing)
+ */
+ c_vstart -= (1 << (PSC_PHASE_FRACTION_BITS - 2));
+ break;
+ case PSC_LOC_HORZ_0_VERT_1_OVER_2:
+ case PSC_LOC_HORZ_1_OVER_4_VERT_1_OVER_2:
+ /*
+ * move chroma up to first luma line
+ * (1/2 chroma input line spacing)
+ */
+ c_vstart -= (1 << (PSC_PHASE_FRACTION_BITS - 1));
+ break;
+ default:
+ break;
+ }
+ /* horizontal input chroma position adjustment */
+ switch (src_chroma_loc) {
+ case PSC_LOC_HORZ_1_OVER_4_VERT_1_OVER_4:
+ case PSC_LOC_HORZ_1_OVER_4_VERT_0:
+ case PSC_LOC_HORZ_1_OVER_4_VERT_1_OVER_2:
+ /* move chroma left 1/4 chroma input sample spacing */
+ c_hstart -= (1 << (PSC_PHASE_FRACTION_BITS - 2));
+ break;
+ default:
+ break;
+ }
+ }
+
+ /* adjustments to chroma resolution */
+ if (src_format == BUF_FMT_YUV420) {
+ src_c_xres >>= 1;
+ src_c_yres >>= 1;
+ } else if (src_format == BUF_FMT_YUV422) {
+ src_c_xres >>= 1;
+ }
+
+ if (dst_format == BUF_FMT_YUV422)
+ dst_c_xres >>= 1;
+
+ l_vinc = ((src_yres << 13) + (dst_yres >> 1)) / dst_yres;
+ c_vinc = ((src_c_yres << 13) + (dst_c_yres >> 1)) / dst_c_yres;
+ l_hinc = ((src_xres << 13) + (dst_xres >> 1)) / dst_xres;
+ c_hinc = ((src_c_xres << 13) + (dst_c_xres >> 1)) / dst_c_xres;
+
+ /* save chroma start phase */
+ ch->c_vstart = c_vstart;
+ ch->c_hstart = c_hstart;
+
+ dcss_scaler_write(dcss->scaler_priv, ch_num, 0,
+ DCSS_SCALER_V_LUM_START);
+ dcss_scaler_write(dcss->scaler_priv, ch_num, l_vinc,
+ DCSS_SCALER_V_LUM_INC);
+
+ dcss_scaler_write(dcss->scaler_priv, ch_num, 0,
+ DCSS_SCALER_H_LUM_START);
+ dcss_scaler_write(dcss->scaler_priv, ch_num, l_hinc,
+ DCSS_SCALER_H_LUM_INC);
+
+ dcss_scaler_write(dcss->scaler_priv, ch_num, c_vstart,
+ DCSS_SCALER_V_CHR_START);
+ dcss_scaler_write(dcss->scaler_priv, ch_num, c_vinc,
+ DCSS_SCALER_V_CHR_INC);
+
+ dcss_scaler_write(dcss->scaler_priv, ch_num, c_hstart,
+ DCSS_SCALER_H_CHR_START);
+ dcss_scaler_write(dcss->scaler_priv, ch_num, c_hinc,
+ DCSS_SCALER_H_CHR_INC);
+
+ /* return if WR_SCL is needed to scale */
+ return l_vinc > dcss_scaler_ratios[ch_num].downscale ||
+ l_vinc < dcss_scaler_ratios[ch_num].upscale ||
+ l_hinc > dcss_scaler_ratios[ch_num].downscale ||
+ l_hinc < dcss_scaler_ratios[ch_num].upscale;
+}
+
+bool dcss_scaler_can_scale(struct dcss_soc *dcss, int ch_num,
+ int src_xres, int src_yres,
+ int dst_xres, int dst_yres)
+{
+ struct dcss_scaler_priv *scaler = dcss->scaler_priv;
+ u32 vscale_fp, hscale_fp;
+ const struct dcss_scaler_ratios *ratios_map = dcss_scaler_ratios;
+
+ /* Convert to fixed point. Easier to work with. */
+ vscale_fp = ((src_yres << 13) + (dst_yres >> 1)) / dst_yres;
+ hscale_fp = ((src_xres << 13) + (dst_xres >> 1)) / dst_xres;
+
+ if (scaler->ch_using_wrscl == -1 || scaler->ch_using_wrscl == ch_num)
+ ratios_map = dcss_scaler_wrscl_ratios;
+
+ return vscale_fp <= ratios_map[ch_num].downscale &&
+ vscale_fp >= ratios_map[ch_num].upscale &&
+ hscale_fp <= ratios_map[ch_num].downscale &&
+ hscale_fp >= ratios_map[ch_num].upscale;
+}
+EXPORT_SYMBOL(dcss_scaler_can_scale);
+
+static void dcss_scaler_program_5_coef_set(struct dcss_soc *dcss, int ch_num,
+ int base_addr,
+ int coef[][PSC_NUM_TAPS])
+{
+ int i, phase;
+
+ for (i = 0; i < PSC_STORED_PHASES; i++) {
+ dcss_scaler_write(dcss->scaler_priv, ch_num,
+ ((coef[i][1] & 0xfff) << 16 |
+ (coef[i][2] & 0xfff) << 4 |
+ (coef[i][3] & 0xf00) >> 8),
+ base_addr + i * sizeof(u32));
+ dcss_scaler_write(dcss->scaler_priv, ch_num,
+ ((coef[i][3] & 0x0ff) << 20 |
+ (coef[i][4] & 0xfff) << 8 |
+ (coef[i][5] & 0xff0) >> 4),
+ base_addr + 0x40 + i * sizeof(u32));
+ dcss_scaler_write(dcss->scaler_priv, ch_num,
+ ((coef[i][5] & 0x00f) << 24),
+ base_addr + 0x80 + i * sizeof(u32));
+ }
+
+ /* reverse both phase and tap orderings */
+ for (phase = (PSC_NUM_PHASES >> 1) - 1; i < PSC_NUM_PHASES; i++, phase--) {
+ dcss_scaler_write(dcss->scaler_priv, ch_num,
+ ((coef[phase][5] & 0xfff) << 16 |
+ (coef[phase][4] & 0xfff) << 4 |
+ (coef[phase][3] & 0xf00) >> 8),
+ base_addr + i * sizeof(u32));
+ dcss_scaler_write(dcss->scaler_priv, ch_num,
+ ((coef[phase][3] & 0x0ff) << 20 |
+ (coef[phase][2] & 0xfff) << 8 |
+ (coef[phase][1] & 0xff0) >> 4),
+ base_addr + 0x40 + i * sizeof(u32));
+ dcss_scaler_write(dcss->scaler_priv, ch_num,
+ ((coef[phase][1] & 0x00f) << 24),
+ base_addr + 0x80 + i * sizeof(u32));
+ }
+}
+
+static void dcss_scaler_program_7_coef_set(struct dcss_soc *dcss, int ch_num,
+ int base_addr,
+ int coef[][PSC_NUM_TAPS])
+{
+ int i, phase;
+
+ for (i = 0; i < PSC_STORED_PHASES; i++) {
+ dcss_scaler_write(dcss->scaler_priv, ch_num,
+ ((coef[i][0] & 0xfff) << 16 |
+ (coef[i][1] & 0xfff) << 4 |
+ (coef[i][2] & 0xf00) >> 8),
+ base_addr + i * sizeof(u32));
+ dcss_scaler_write(dcss->scaler_priv, ch_num,
+ ((coef[i][2] & 0x0ff) << 20 |
+ (coef[i][3] & 0xfff) << 8 |
+ (coef[i][4] & 0xff0) >> 4),
+ base_addr + 0x40 + i * sizeof(u32));
+ dcss_scaler_write(dcss->scaler_priv, ch_num,
+ ((coef[i][4] & 0x00f) << 24 |
+ (coef[i][5] & 0xfff) << 12 |
+ (coef[i][6] & 0xfff)),
+ base_addr + 0x80 + i * sizeof(u32));
+ }
+
+ /* reverse both phase and tap orderings */
+ for (phase = (PSC_NUM_PHASES >> 1) - 1; i < PSC_NUM_PHASES; i++, phase--) {
+ dcss_scaler_write(dcss->scaler_priv, ch_num,
+ ((coef[phase][6] & 0xfff) << 16 |
+ (coef[phase][5] & 0xfff) << 4 |
+ (coef[phase][4] & 0xf00) >> 8),
+ base_addr + i * sizeof(u32));
+ dcss_scaler_write(dcss->scaler_priv, ch_num,
+ ((coef[phase][4] & 0x0ff) << 20 |
+ (coef[phase][3] & 0xfff) << 8 |
+ (coef[phase][2] & 0xff0) >> 4),
+ base_addr + 0x40 + i * sizeof(u32));
+ dcss_scaler_write(dcss->scaler_priv, ch_num,
+ ((coef[phase][2] & 0x00f) << 24 |
+ (coef[phase][1] & 0xfff) << 12 |
+ (coef[phase][0] & 0xfff)),
+ base_addr + 0x80 + i * sizeof(u32));
+ }
+}
+
+static void dcss_scaler_yuv_coef_set(struct dcss_soc *dcss, int ch_num,
+ enum buffer_format src_format,
+ enum buffer_format dst_format,
+ bool use_5_taps,
+ int src_xres, int src_yres, int dst_xres,
+ int dst_yres)
+{
+ struct dcss_scaler_ch *ch = &dcss->scaler_priv->ch[ch_num];
+ int coef[PSC_STORED_PHASES][PSC_NUM_TAPS];
+ bool program_5_taps = use_5_taps ||
+ (dst_format == BUF_FMT_YUV422 &&
+ src_format == BUF_FMT_ARGB8888_YUV444);
+
+ /* horizontal luma */
+ dcss_scaler_filter_design(src_xres, dst_xres, false,
+ src_xres == dst_xres, coef);
+ dcss_scaler_program_7_coef_set(dcss, ch_num,
+ DCSS_SCALER_COEF_HLUM, coef);
+
+ /* vertical luma */
+ dcss_scaler_filter_design(src_yres, dst_yres, program_5_taps,
+ src_yres == dst_yres, coef);
+
+ if (program_5_taps)
+ dcss_scaler_program_5_coef_set(dcss, ch_num,
+ DCSS_SCALER_COEF_VLUM, coef);
+ else
+ dcss_scaler_program_7_coef_set(dcss, ch_num,
+ DCSS_SCALER_COEF_VLUM, coef);
+
+ /* adjust chroma resolution */
+ if (src_format != BUF_FMT_ARGB8888_YUV444)
+ src_xres >>= 1;
+ if (src_format == BUF_FMT_YUV420)
+ src_yres >>= 1;
+ if (dst_format != BUF_FMT_ARGB8888_YUV444)
+ dst_xres >>= 1;
+ if (dst_format == BUF_FMT_YUV420) /* should not happen */
+ dst_yres >>= 1;
+
+ /* horizontal chroma */
+ dcss_scaler_filter_design(src_xres, dst_xres, false,
+ (src_xres == dst_xres) && (ch->c_hstart == 0),
+ coef);
+
+ dcss_scaler_program_7_coef_set(dcss, ch_num,
+ DCSS_SCALER_COEF_HCHR, coef);
+
+ /* vertical chroma */
+ dcss_scaler_filter_design(src_yres, dst_yres, program_5_taps,
+ (src_yres == dst_yres) && (ch->c_vstart == 0),
+ coef);
+ if (program_5_taps)
+ dcss_scaler_program_5_coef_set(dcss, ch_num,
+ DCSS_SCALER_COEF_VCHR, coef);
+ else
+ dcss_scaler_program_7_coef_set(dcss, ch_num,
+ DCSS_SCALER_COEF_VCHR, coef);
+}
+
+static void dcss_scaler_rgb_coef_set(struct dcss_soc *dcss, int ch_num,
+ int src_xres, int src_yres, int dst_xres,
+ int dst_yres)
+{
+ int coef[PSC_STORED_PHASES][PSC_NUM_TAPS];
+
+ /* horizontal RGB */
+ dcss_scaler_filter_design(src_xres, dst_xres, false,
+ src_xres == dst_xres, coef);
+ dcss_scaler_program_7_coef_set(dcss, ch_num,
+ DCSS_SCALER_COEF_HLUM, coef);
+
+ /* vertical RGB */
+ dcss_scaler_filter_design(src_yres, dst_yres, false,
+ src_yres == dst_yres, coef);
+ dcss_scaler_program_7_coef_set(dcss, ch_num,
+ DCSS_SCALER_COEF_VLUM, coef);
+}
+
+static void dcss_scaler_set_rgb10_order(struct dcss_soc *dcss, int ch_num,
+ u32 pix_format)
+{
+ struct dcss_scaler_ch *ch = &dcss->scaler_priv->ch[ch_num];
+ enum dcss_color_space dcss_cs;
+ const struct drm_format_info *format;
+ unsigned int pixel_depth;
+ u32 a2r10g10b10_format;
+
+ dcss_cs = dcss_drm_fourcc_to_colorspace(pix_format);
+
+ if (dcss_cs != DCSS_COLORSPACE_RGB)
+ return;
+
+ format = drm_format_info(pix_format);
+ pixel_depth = format->depth;
+
+ ch->sdata_ctrl &= ~A2R10G10B10_FORMAT_MASK;
+
+ if (pixel_depth != 30)
+ return;
+
+ switch (pix_format) {
+ case DRM_FORMAT_ARGB2101010:
+ case DRM_FORMAT_XRGB2101010:
+ a2r10g10b10_format = 0;
+ break;
+
+ case DRM_FORMAT_ABGR2101010:
+ case DRM_FORMAT_XBGR2101010:
+ a2r10g10b10_format = 5;
+ break;
+
+ case DRM_FORMAT_RGBA1010102:
+ case DRM_FORMAT_RGBX1010102:
+ a2r10g10b10_format = 6;
+ break;
+
+ case DRM_FORMAT_BGRA1010102:
+ case DRM_FORMAT_BGRX1010102:
+ a2r10g10b10_format = 11;
+ break;
+
+ default:
+ a2r10g10b10_format = 0;
+ break;
+ }
+
+ ch->sdata_ctrl |= a2r10g10b10_format << A2R10G10B10_FORMAT_POS;
+}
+
+static void dcss_scaler_setup_path(struct dcss_soc *dcss, int ch_num,
+ u32 pix_format, int dst_xres,
+ int dst_yres, u32 vrefresh_hz,
+ bool wrscl_needed)
+{
+ struct dcss_scaler_priv *scaler = dcss->scaler_priv;
+ u32 base_addr;
+
+ /* nothing to do if WRSCL path is needed but it's already used */
+ if (wrscl_needed && scaler->ch_using_wrscl != -1 &&
+ scaler->ch_using_wrscl != ch_num)
+ return;
+
+ if (!wrscl_needed) {
+ /* Channel has finished using WRSCL. Release WRSCL/RDSRC. */
+ if (scaler->ch_using_wrscl == ch_num) {
+ dcss_wrscl_enable(dcss, false);
+ dcss_rdsrc_enable(dcss, false);
+
+ scaler->ch_using_wrscl = -1;
+ }
+
+ return;
+ }
+
+ base_addr = dcss_wrscl_setup(dcss, pix_format, vrefresh_hz,
+ dst_xres, dst_yres);
+
+ dcss_rdsrc_setup(dcss, pix_format, dst_xres, dst_yres,
+ base_addr);
+
+ dcss_wrscl_enable(dcss, true);
+ dcss_rdsrc_enable(dcss, true);
+
+ scaler->ch_using_wrscl = ch_num;
+}
+
+void dcss_scaler_setup(struct dcss_soc *dcss, int ch_num, u32 pix_format,
+ int src_xres, int src_yres, int dst_xres, int dst_yres,
+ u32 vrefresh_hz)
+{
+ enum dcss_color_space dcss_cs;
+ int planes;
+ const struct drm_format_info *format;
+ unsigned int pixel_depth = 0;
+ bool rtr_8line_en = false;
+ bool use_5_taps = false;
+ enum buffer_format src_format = BUF_FMT_ARGB8888_YUV444;
+ enum buffer_format dst_format = BUF_FMT_ARGB8888_YUV444;
+ bool wrscl_needed = false;
+
+ dcss_cs = dcss_drm_fourcc_to_colorspace(pix_format);
+ planes = drm_format_num_planes(pix_format);
+
+ if (dcss_cs == DCSS_COLORSPACE_YUV) {
+ dcss_scaler_yuv_enable(dcss, ch_num, true);
+
+ if (pix_format == DRM_FORMAT_NV12 ||
+ pix_format == DRM_FORMAT_NV21 ||
+ pix_format == DRM_FORMAT_P010) {
+ rtr_8line_en = true;
+ src_format = BUF_FMT_YUV420;
+ } else if (pix_format == DRM_FORMAT_UYVY ||
+ pix_format == DRM_FORMAT_VYUY ||
+ pix_format == DRM_FORMAT_YUYV ||
+ pix_format == DRM_FORMAT_YVYU) {
+ src_format = BUF_FMT_YUV422;
+ }
+
+ use_5_taps = !rtr_8line_en;
+ if (pix_format == DRM_FORMAT_P010)
+ pixel_depth = 30;
+
+ } else if (dcss_cs == DCSS_COLORSPACE_RGB) {
+ dcss_scaler_yuv_enable(dcss, ch_num, false);
+
+ format = drm_format_info(pix_format);
+ pixel_depth = format->depth;
+ }
+
+ /* TODO: get src_chroma_loc from VPU metadata */
+ wrscl_needed = dcss_scaler_fractions_set(dcss, ch_num, src_xres,
+ src_yres, dst_xres,
+ dst_yres, src_format,
+ dst_format,
+ 0 /* src_chroma_loc */);
+
+ if (dcss_cs == DCSS_COLORSPACE_YUV) {
+ dcss_scaler_yuv_coef_set(dcss, ch_num, src_format, dst_format,
+ use_5_taps, src_xres, src_yres,
+ dst_xres, dst_yres);
+ } else if (dcss_cs == DCSS_COLORSPACE_RGB) {
+ dcss_scaler_rgb_coef_set(dcss, ch_num, src_xres, src_yres,
+ dst_xres, dst_yres);
+ }
+
+ dcss_scaler_rtr_8lines_enable(dcss, ch_num, rtr_8line_en);
+ dcss_scaler_bit_depth_set(dcss, ch_num, pixel_depth);
+ dcss_scaler_set_rgb10_order(dcss, ch_num, pix_format);
+ dcss_scaler_format_set(dcss, ch_num, src_format, dst_format);
+ dcss_scaler_res_set(dcss, ch_num, src_xres, src_yres,
+ dst_xres, dst_yres, pix_format, dst_format);
+
+ dcss_scaler_setup_path(dcss, ch_num, pix_format, dst_xres,
+ dst_yres, vrefresh_hz, wrscl_needed);
+}
+EXPORT_SYMBOL(dcss_scaler_setup);
+
+void dcss_scaler_write_sclctrl(struct dcss_soc *dcss)
+{
+ int chnum;
+
+ for (chnum = 0; chnum < 3; chnum++) {
+ struct dcss_scaler_ch *ch = &dcss->scaler_priv->ch[chnum];
+
+ if (ch->scaler_ctrl_chgd) {
+ dcss_ctxld_write_irqsafe(dcss, ch->ctx_id,
+ ch->scaler_ctrl,
+ ch->base_ofs + DCSS_SCALER_CTRL);
+ ch->scaler_ctrl_chgd = false;
+ }
+ }
+}
diff --git a/drivers/gpu/imx/dcss/dcss-ss.c b/drivers/gpu/imx/dcss/dcss-ss.c
new file mode 100644
index 000000000000..66df49e565df
--- /dev/null
+++ b/drivers/gpu/imx/dcss/dcss-ss.c
@@ -0,0 +1,227 @@
+/*
+ * Copyright (C) 2017 NXP
+ *
+ * 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/device.h>
+#include <linux/bitops.h>
+#include <linux/io.h>
+#include <video/videomode.h>
+#include <drm/drm_fourcc.h>
+
+#include <video/imx-dcss.h>
+#include "dcss-prv.h"
+
+#define USE_CTXLD
+
+#define DCSS_SS_SYS_CTRL 0x00
+#define RUN_EN BIT(0)
+#define DCSS_SS_DISPLAY 0x10
+#define LRC_X_POS 0
+#define LRC_X_MASK GENMASK(12, 0)
+#define LRC_Y_POS 16
+#define LRC_Y_MASK GENMASK(28, 16)
+#define DCSS_SS_HSYNC 0x20
+#define DCSS_SS_VSYNC 0x30
+#define SYNC_START_POS 0
+#define SYNC_START_MASK GENMASK(12, 0)
+#define SYNC_END_POS 16
+#define SYNC_END_MASK GENMASK(28, 16)
+#define SYNC_POL BIT(31)
+#define DCSS_SS_DE_ULC 0x40
+#define ULC_X_POS 0
+#define ULC_X_MASK GENMASK(12, 0)
+#define ULC_Y_POS 16
+#define ULC_Y_MASK GENMASK(28, 16)
+#define ULC_POL BIT(31)
+#define DCSS_SS_DE_LRC 0x50
+#define DCSS_SS_MODE 0x60
+#define PIPE_MODE_POS 0
+#define PIPE_MODE_MASK GENMASK(1, 0)
+#define DCSS_SS_COEFF 0x70
+#define HORIZ_A_POS 0
+#define HORIZ_A_MASK GENMASK(3, 0)
+#define HORIZ_B_POS 4
+#define HORIZ_B_MASK GENMASK(7, 4)
+#define HORIZ_C_POS 8
+#define HORIZ_C_MASK GENMASK(11, 8)
+#define HORIZ_H_NORM_POS 12
+#define HORIZ_H_NORM_MASK GENMASK(14, 12)
+#define VERT_A_POS 16
+#define VERT_A_MASK GENMASK(19, 16)
+#define VERT_B_POS 20
+#define VERT_B_MASK GENMASK(23, 20)
+#define VERT_C_POS 24
+#define VERT_C_MASK GENMASK(27, 24)
+#define VERT_H_NORM_POS 28
+#define VERT_H_NORM_MASK GENMASK(30, 28)
+#define DCSS_SS_CLIP_CB 0x80
+#define DCSS_SS_CLIP_CR 0x90
+#define CLIP_MIN_POS 0
+#define CLIP_MIN_MASK GENMASK(9, 0)
+#define CLIP_MAX_POS 0
+#define CLIP_MAX_MASK GENMASK(23, 16)
+#define DCSS_SS_INTER_MODE 0xA0
+#define INT_EN BIT(0)
+#define VSYNC_SHIFT BIT(1)
+
+static struct dcss_debug_reg ss_debug_reg[] = {
+ DCSS_DBG_REG(DCSS_SS_SYS_CTRL),
+ DCSS_DBG_REG(DCSS_SS_DISPLAY),
+ DCSS_DBG_REG(DCSS_SS_HSYNC),
+ DCSS_DBG_REG(DCSS_SS_VSYNC),
+ DCSS_DBG_REG(DCSS_SS_DE_ULC),
+ DCSS_DBG_REG(DCSS_SS_DE_LRC),
+ DCSS_DBG_REG(DCSS_SS_MODE),
+ DCSS_DBG_REG(DCSS_SS_COEFF),
+ DCSS_DBG_REG(DCSS_SS_CLIP_CB),
+ DCSS_DBG_REG(DCSS_SS_CLIP_CR),
+ DCSS_DBG_REG(DCSS_SS_INTER_MODE),
+};
+
+struct dcss_ss_priv {
+ struct dcss_soc *dcss;
+ void __iomem *base_reg;
+ u32 base_ofs;
+
+ u32 ctx_id;
+
+ bool in_use;
+};
+
+static void dcss_ss_write(struct dcss_ss_priv *ss, u32 val, u32 ofs)
+{
+ if (!ss->in_use)
+ dcss_writel(val, ss->base_reg + ofs);
+#if defined(USE_CTXLD)
+ dcss_ctxld_write(ss->dcss, ss->ctx_id, val,
+ ss->base_ofs + ofs);
+#endif
+}
+
+#ifdef CONFIG_DEBUG_FS
+void dcss_ss_dump_regs(struct seq_file *s, void *data)
+{
+ struct dcss_soc *dcss = data;
+ int j;
+
+ seq_puts(s, ">> Dumping SUBSAM:\n");
+ for (j = 0; j < ARRAY_SIZE(ss_debug_reg); j++)
+ seq_printf(s, "%-35s(0x%04x) -> 0x%08x\n",
+ ss_debug_reg[j].name,
+ ss_debug_reg[j].ofs,
+ dcss_readl(dcss->ss_priv->base_reg +
+ ss_debug_reg[j].ofs));
+}
+#endif
+
+int dcss_ss_init(struct dcss_soc *dcss, unsigned long ss_base)
+{
+ struct dcss_ss_priv *ss;
+
+ ss = devm_kzalloc(dcss->dev, sizeof(*ss), GFP_KERNEL);
+ if (!ss)
+ return -ENOMEM;
+
+ dcss->ss_priv = ss;
+ ss->dcss = dcss;
+
+ ss->base_reg = devm_ioremap(dcss->dev, ss_base, SZ_4K);
+ if (!ss->base_reg) {
+ dev_err(dcss->dev, "ss: unable to remap ss base\n");
+ return -ENOMEM;
+ }
+
+ ss->base_ofs = ss_base;
+
+#if defined(USE_CTXLD)
+ ss->ctx_id = CTX_SB_HP;
+#endif
+
+ return 0;
+}
+
+void dcss_ss_exit(struct dcss_soc *dcss)
+{
+ dcss_writel(0, dcss->ss_priv->base_reg + DCSS_SS_SYS_CTRL);
+}
+
+void dcss_ss_subsam_set(struct dcss_soc *dcss, u32 pix_format)
+{
+ if (pix_format == DRM_FORMAT_P010) {
+ dcss_ss_write(dcss->ss_priv, 0x21612161, DCSS_SS_COEFF);
+ dcss_ss_write(dcss->ss_priv, 2, DCSS_SS_MODE);
+ dcss_ss_write(dcss->ss_priv, 0x03c00040, DCSS_SS_CLIP_CB);
+ dcss_ss_write(dcss->ss_priv, 0x03c00040, DCSS_SS_CLIP_CR);
+
+ return;
+ }
+
+ dcss_ss_write(dcss->ss_priv, 0x41614161, DCSS_SS_COEFF);
+ dcss_ss_write(dcss->ss_priv, 0, DCSS_SS_MODE);
+ dcss_ss_write(dcss->ss_priv, 0x03ff0000, DCSS_SS_CLIP_CB);
+ dcss_ss_write(dcss->ss_priv, 0x03ff0000, DCSS_SS_CLIP_CR);
+}
+
+void dcss_ss_sync_set(struct dcss_soc *dcss, struct videomode *vm,
+ bool phsync, bool pvsync)
+{
+ struct dcss_ss_priv *ss = dcss->ss_priv;
+ u16 lrc_x, lrc_y;
+ u16 hsync_start, hsync_end;
+ u16 vsync_start, vsync_end;
+ u16 de_ulc_x, de_ulc_y;
+ u16 de_lrc_x, de_lrc_y;
+
+ lrc_x = vm->hfront_porch + vm->hback_porch + vm->hsync_len +
+ vm->hactive - 1;
+ lrc_y = vm->vfront_porch + vm->vback_porch + vm->vsync_len +
+ vm->vactive - 1;
+
+ dcss_ss_write(ss, (lrc_y << LRC_Y_POS) | lrc_x, DCSS_SS_DISPLAY);
+
+ hsync_start = vm->hfront_porch + vm->hback_porch + vm->hsync_len +
+ vm->hactive - 1;
+ hsync_end = vm->hsync_len - 1;
+
+ dcss_ss_write(ss, (phsync ? SYNC_POL : 0) |
+ ((u32)hsync_end << SYNC_END_POS) | hsync_start,
+ DCSS_SS_HSYNC);
+
+ vsync_start = vm->vfront_porch - 1;
+ vsync_end = vm->vfront_porch + vm->vsync_len - 1;
+
+ dcss_ss_write(ss, (pvsync ? SYNC_POL : 0) |
+ ((u32)vsync_end << SYNC_END_POS) | vsync_start,
+ DCSS_SS_VSYNC);
+
+ de_ulc_x = vm->hsync_len + vm->hback_porch - 1;
+ de_ulc_y = vm->vsync_len + vm->vfront_porch + vm->vback_porch;
+
+ dcss_ss_write(ss, SYNC_POL | ((u32)de_ulc_y << ULC_Y_POS) | de_ulc_x,
+ DCSS_SS_DE_ULC);
+
+ de_lrc_x = vm->hsync_len + vm->hback_porch + vm->hactive - 1;
+ de_lrc_y = vm->vsync_len + vm->vfront_porch + vm->vback_porch +
+ vm->vactive - 1;
+
+ dcss_ss_write(ss, (de_lrc_y << LRC_Y_POS) | de_lrc_x, DCSS_SS_DE_LRC);
+}
+EXPORT_SYMBOL(dcss_ss_sync_set);
+
+void dcss_ss_enable(struct dcss_soc *dcss, bool en)
+{
+ struct dcss_ss_priv *ss = dcss->ss_priv;
+
+ dcss_ss_write(ss, en ? RUN_EN : 0, DCSS_SS_SYS_CTRL);
+}
+EXPORT_SYMBOL(dcss_ss_enable);
diff --git a/drivers/gpu/imx/dcss/dcss-wrscl.c b/drivers/gpu/imx/dcss/dcss-wrscl.c
new file mode 100644
index 000000000000..30b225958cf7
--- /dev/null
+++ b/drivers/gpu/imx/dcss/dcss-wrscl.c
@@ -0,0 +1,189 @@
+/*
+ * Copyright (C) 2017 NXP
+ *
+ * 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/device.h>
+#include <linux/io.h>
+#include <linux/clk.h>
+#include <linux/dma-mapping.h>
+
+#include <video/imx-dcss.h>
+#include "dcss-prv.h"
+
+#define USE_CTXLD
+
+#define DCSS_WRSCL_CTRL_STATUS 0x00
+#define WRSCL_ERR BIT(31)
+#define WRSCL_ERR_EN BIT(30)
+#define WRSCL_FRAME_COMP BIT(29)
+#define WRSCL_FRAME_COMP_EN BIT(28)
+#define WRSCL_FIFO_SIZE_POS 18
+#define WRSCL_FIFO_SIZE_MASK GENMAK(24, 18)
+#define WRSCL_P_FREQ_POS 10
+#define WRSCL_P_FREQ_MASK GENMASK(17, 10)
+#define WRSCL_P_SIZE_POS 7
+#define WRSCL_P_SIZE_MASK GENMASK(9, 7)
+#define WRSCL_T_SIZE_POS 5
+#define WRSCL_T_SIZE_MASK GENMASK(6, 5)
+#define WRSCL_BPP_POS 2
+#define WRSCL_BPP_MASK GENMASK(4, 2)
+#define WRSCL_REPEAT BIT(1)
+#define WRSCL_ENABLE BIT(0)
+#define DCSS_WRSCL_BASE_ADDR 0x10
+#define DCSS_WRSCL_PITCH 0x14
+
+struct dcss_wrscl_priv {
+ void __iomem *base_reg;
+ u32 base_ofs;
+ struct dcss_soc *dcss;
+
+ u32 ctx_id;
+
+ u32 buf_size;
+ u32 buf_addr;
+ void *buf_vaddr;
+
+ u32 ctrl_status;
+};
+
+#ifdef CONFIG_DEBUG_FS
+static struct dcss_debug_reg wrscl_debug_reg[] = {
+ DCSS_DBG_REG(DCSS_WRSCL_CTRL_STATUS),
+ DCSS_DBG_REG(DCSS_WRSCL_BASE_ADDR),
+ DCSS_DBG_REG(DCSS_WRSCL_PITCH),
+};
+
+void dcss_wrscl_dump_regs(struct seq_file *s, void *data)
+{
+ struct dcss_soc *dcss = data;
+ int i;
+
+ seq_puts(s, ">> Dumping WR_SCL:\n");
+ for (i = 0; i < ARRAY_SIZE(wrscl_debug_reg); i++) {
+ seq_printf(s, "%-35s(0x%04x) -> 0x%08x\n",
+ wrscl_debug_reg[i].name,
+ wrscl_debug_reg[i].ofs,
+ dcss_readl(dcss->wrscl_priv->base_reg +
+ wrscl_debug_reg[i].ofs));
+ }
+}
+#endif
+
+static void dcss_wrscl_write(struct dcss_wrscl_priv *wrscl, u32 val, u32 ofs)
+{
+#if !defined(USE_CTXLD)
+ dcss_writel(val, wrscl->base_reg + ofs);
+#else
+ dcss_ctxld_write(wrscl->dcss, wrscl->ctx_id,
+ val, wrscl->base_ofs + ofs);
+#endif
+}
+
+int dcss_wrscl_init(struct dcss_soc *dcss, unsigned long wrscl_base)
+{
+ struct dcss_wrscl_priv *wrscl;
+
+ wrscl = devm_kzalloc(dcss->dev, sizeof(*wrscl), GFP_KERNEL);
+ if (!wrscl)
+ return -ENOMEM;
+
+ wrscl->base_reg = devm_ioremap(dcss->dev, wrscl_base, SZ_4K);
+ if (!wrscl->base_reg) {
+ dev_err(dcss->dev, "wrscl: unable to remap base\n");
+ return -ENOMEM;
+ }
+
+ dcss->wrscl_priv = wrscl;
+ wrscl->base_ofs = wrscl_base;
+ wrscl->dcss = dcss;
+
+#if defined(USE_CTXLD)
+ wrscl->ctx_id = CTX_SB_HP;
+#endif
+
+ return 0;
+}
+
+void dcss_wrscl_exit(struct dcss_soc *dcss)
+{
+}
+
+static const u16 dcss_wrscl_psize_map[] = {64, 128, 256, 512, 1024, 2048, 4096};
+
+u32 dcss_wrscl_setup(struct dcss_soc *dcss, u32 pix_format, u32 vrefresh_hz,
+ u32 dst_xres, u32 dst_yres)
+{
+ struct dcss_wrscl_priv *wrscl = dcss->wrscl_priv;
+ u32 pitch, p_size, p_freq, bpp;
+ dma_addr_t dma_handle;
+ u32 b_clk = clk_get_rate(dcss->axi_clk);
+
+ /* we'd better release the old buffer */
+ if (wrscl->buf_addr)
+ dmam_free_coherent(dcss->dev, wrscl->buf_size,
+ wrscl->buf_vaddr, wrscl->buf_addr);
+
+ p_size = PSIZE_256;
+
+ /* scaler output is YUV444 */
+ bpp = 4;
+
+ /* spread the load over the entire frame */
+ p_freq = ((u64)b_clk * dcss_wrscl_psize_map[p_size]) /
+ ((u64)dst_xres * dst_yres * vrefresh_hz * bpp * 8);
+
+ /* choose a slightly smaller p_freq */
+ p_freq = p_freq - 3 > 255 ? 255 : p_freq - 3;
+
+ wrscl->ctrl_status = FIFO_512 << WRSCL_FIFO_SIZE_POS;
+ wrscl->ctrl_status |= p_size << WRSCL_P_SIZE_POS;
+ wrscl->ctrl_status |= TSIZE_256 << WRSCL_T_SIZE_POS;
+ wrscl->ctrl_status |= BPP_32_10BIT_OUTPUT << WRSCL_BPP_POS;
+ wrscl->ctrl_status |= p_freq << WRSCL_P_FREQ_POS;
+
+ wrscl->buf_size = dst_xres * dst_yres * bpp;
+ pitch = dst_xres * bpp;
+
+ wrscl->buf_vaddr = dmam_alloc_coherent(dcss->dev, wrscl->buf_size,
+ &dma_handle, GFP_KERNEL);
+ if (!wrscl->buf_vaddr) {
+ dev_err(dcss->dev, "wrscl: cannot alloc buf mem\n");
+ return 0;
+ }
+
+ wrscl->buf_addr = dma_handle;
+
+ dcss_wrscl_write(wrscl, wrscl->buf_addr, DCSS_WRSCL_BASE_ADDR);
+ dcss_wrscl_write(wrscl, pitch, DCSS_WRSCL_PITCH);
+
+ return wrscl->buf_addr;
+}
+
+void dcss_wrscl_enable(struct dcss_soc *dcss, bool en)
+{
+ struct dcss_wrscl_priv *wrscl = dcss->wrscl_priv;
+
+ if (en)
+ wrscl->ctrl_status |= WRSCL_ENABLE | WRSCL_REPEAT;
+ else
+ wrscl->ctrl_status &= ~(WRSCL_ENABLE | WRSCL_REPEAT);
+
+ dcss_wrscl_write(wrscl, wrscl->ctrl_status, DCSS_WRSCL_CTRL_STATUS);
+
+ if (!en && wrscl->buf_addr) {
+ dmam_free_coherent(dcss->dev, wrscl->buf_size,
+ wrscl->buf_vaddr, wrscl->buf_addr);
+ wrscl->buf_addr = 0;
+ }
+}
+
diff --git a/drivers/gpu/imx/dpu-blit/Kconfig b/drivers/gpu/imx/dpu-blit/Kconfig
new file mode 100644
index 000000000000..d71d9a7f9515
--- /dev/null
+++ b/drivers/gpu/imx/dpu-blit/Kconfig
@@ -0,0 +1,5 @@
+config IMX_DPU_BLIT
+ tristate
+ depends on IMX_DPU_CORE
+ default y if IMX_DPU_CORE=y
+ default m if IMX_DPU_CORE=m
diff --git a/drivers/gpu/imx/dpu-blit/Makefile b/drivers/gpu/imx/dpu-blit/Makefile
new file mode 100644
index 000000000000..a1c760d36ad8
--- /dev/null
+++ b/drivers/gpu/imx/dpu-blit/Makefile
@@ -0,0 +1,5 @@
+ccflags-y += -Idrivers/gpu/imx/dpu
+
+imx-dpu-blit-objs := dpu-blit.o
+
+obj-$(CONFIG_IMX_DPU_BLIT) += imx-dpu-blit.o
diff --git a/drivers/gpu/imx/dpu-blit/dpu-blit-registers.h b/drivers/gpu/imx/dpu-blit/dpu-blit-registers.h
new file mode 100644
index 000000000000..3d86b272e281
--- /dev/null
+++ b/drivers/gpu/imx/dpu-blit/dpu-blit-registers.h
@@ -0,0 +1,283 @@
+/*
+ * Copyright 2017 NXP
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#ifndef __DPU_BLIT_REGISTERS_H__
+#define __DPU_BLIT_REGISTERS_H__
+
+/* Registers Defination */
+#define COMCTRL_IPIDENTIFIER ((uint32_t)(0))
+
+#define PIXENGCFG_STORE9_TRIGGER ((uint32_t)(0x954))
+
+#define COMCTRL_USERINTERRUPTMASK0 ((uint32_t)(0x48))
+#define COMCTRL_USERINTERRUPTMASK0_USERINTERRUPTMASK0_MASK 0xFFFFFFFFU
+#define COMCTRL_USERINTERRUPTENABLE0 ((uint32_t)(0x80))
+
+#define COMCTRL_INTERRUPTENABLE0 ((uint32_t)(0x50))
+
+#define COMCTRL_INTERRUPTSTATUS0 ((uint32_t)(0x68))
+#define COMCTRL_USERINTERRUPTSTATUS0 ((uint32_t)(0x98))
+
+#define COMCTRL_USERINTERRUPTCLEAR0 ((uint32_t)(0x90))
+#define COMCTRL_USERINTERRUPTCLEAR0_USERINTERRUPTCLEAR0_MASK 0xFFFFFFFFU
+
+#define COMCTRL_INTERRUPTCLEAR0 ((uint32_t)(0x60))
+#define COMCTRL_INTERRUPTCLEAR0_INTERRUPTCLEAR0_MASK 0xFFFFFFFFU
+
+
+#define PIXENGCFG_FETCHDECODE9_DYNAMIC ((uint32_t)(0x828))
+#define PIXENGCFG_FETCHDECODE9_DYNAMIC_RESET_VALUE 0U
+
+#define PIXENGCFG_FETCHWARP9_DYNAMIC ((uint32_t)(0x848))
+#define PIXENGCFG_FETCHWARP9_DYNAMIC_RESET_VALUE 0U
+
+#define PIXENGCFG_ROP9_DYNAMIC ((uint32_t)(0x868))
+#define PIXENGCFG_ROP9_DYNAMIC_RESET_VALUE 0x1000000U
+
+#define PIXENGCFG_MATRIX9_DYNAMIC ((uint32_t)(0x8A8))
+#define PIXENGCFG_MATRIX9_DYNAMIC_RESET_VALUE 0x1000000U
+
+#define PIXENGCFG_HSCALER9_DYNAMIC ((uint32_t)(0x8C8))
+#define PIXENGCFG_HSCALER9_DYNAMIC_RESET_VALUE 0x1000000U
+
+#define PIXENGCFG_VSCALER9_DYNAMIC ((uint32_t)(0x8E8))
+#define PIXENGCFG_VSCALER9_DYNAMIC_RESET_VALUE 0x1000000U
+
+#define PIXENGCFG_BLITBLEND9_DYNAMIC ((uint32_t)(0x928))
+#define PIXENGCFG_BLITBLEND9_DYNAMIC_RESET_VALUE 0x1000000U
+
+#define PIXENGCFG_STORE9_STATIC ((uint32_t)(0x948))
+#define PIXENGCFG_STORE9_STATIC_RESET_VALUE 0x800010U
+#define PIXENGCFG_STORE9_STATIC_RESET_MASK 0xFFFFFFFFU
+#define PIXENGCFG_STORE9_STATIC_STORE9_SHDEN_MASK 0x1U
+#define PIXENGCFG_STORE9_STATIC_STORE9_SHDEN_SHIFT 0U
+#define PIXENGCFG_STORE9_STATIC_STORE9_POWERDOWN_MASK 0x10U
+#define PIXENGCFG_STORE9_STATIC_STORE9_POWERDOWN_SHIFT 4U
+#define PIXENGCFG_STORE9_STATIC_STORE9_SYNC_MODE_MASK 0x100U
+#define PIXENGCFG_STORE9_STATIC_STORE9_SYNC_MODE_SHIFT 8U
+#define PIXENGCFG_STORE9_STATIC_STORE9_SYNC_MODE__SINGLE 0U
+#define PIXENGCFG_STORE9_STATIC_STORE9_SYNC_MODE__AUTO 0x1U
+#define PIXENGCFG_STORE9_STATIC_STORE9_SW_RESET_MASK 0x800U
+#define PIXENGCFG_STORE9_STATIC_STORE9_SW_RESET_SHIFT 11U
+/* Field Value: STORE9_SW_RESET__OPERATION, Normal Operation */
+#define PIXENGCFG_STORE9_STATIC_STORE9_SW_RESET__OPERATION 0U
+/* Field Value: STORE9_SW_RESET__SWRESET, Software Reset */
+#define PIXENGCFG_STORE9_STATIC_STORE9_SW_RESET__SWRESET 0x1U
+#define PIXENGCFG_STORE9_STATIC_STORE9_DIV_MASK 0xFF0000U
+#define PIXENGCFG_STORE9_STATIC_STORE9_DIV_SHIFT 16U
+
+#define PIXENGCFG_STORE9_DYNAMIC ((uint32_t)(0x94C))
+
+#define FETCHDECODE9_STATICCONTROL ((uint32_t)(0x1008))
+#define FETCHDECODE9_STATICCONTROL_OFFSET ((uint32_t)(0x8))
+#define FETCHDECODE9_STATICCONTROL_RESET_VALUE 0U
+#define FETCHDECODE9_STATICCONTROL_SHDEN_MASK 0x1U
+#define FETCHDECODE9_STATICCONTROL_SHDEN_SHIFT 0U
+#define FETCHDECODE9_STATICCONTROL_BASEADDRESSAUTOUPDATE_MASK 0xFF0000U
+#define FETCHDECODE9_STATICCONTROL_BASEADDRESSAUTOUPDATE_SHIFT 16U
+
+#define FETCHDECODE9_BURSTBUFFERMANAGEMENT ((uint32_t)(0x100C))
+#define FETCHDECODE9_BASEADDRESS0 ((uint32_t)(0x101C))
+#define FETCHDECODE9_SOURCEBUFFERATTRIBUTES0 ((uint32_t)(0x1020))
+#define FETCHDECODE9_SOURCEBUFFERDIMENSION0 ((uint32_t)(0x1024))
+#define FETCHDECODE9_COLORCOMPONENTBITS0 ((uint32_t)(0x1028))
+#define FETCHDECODE9_COLORCOMPONENTSHIFT0 ((uint32_t)(0x102C))
+#define FETCHDECODE9_LAYEROFFSET0 ((uint32_t)(0x1030))
+#define FETCHDECODE9_CLIPWINDOWOFFSET0 ((uint32_t)(0x1034))
+#define FETCHDECODE9_CLIPWINDOWDIMENSIONS0 ((uint32_t)(0x1038))
+#define FETCHDECODE9_CONSTANTCOLOR0 ((uint32_t)(0x103C))
+#define FETCHDECODE9_LAYERPROPERTY0 ((uint32_t)(0x1040))
+#define FETCHDECODE9_FRAMEDIMENSIONS ((uint32_t)(0x1044))
+#define FETCHDECODE9_FRAMERESAMPLING ((uint32_t)(0x1048))
+#define FETCHDECODE9_CONTROL ((uint32_t)(0x1054))
+
+#define FETCHWARP9_STATICCONTROL ((uint32_t)(0x1808))
+#define FETCHWARP9_STATICCONTROL_OFFSET ((uint32_t)(0x8))
+#define FETCHWARP9_STATICCONTROL_RESET_VALUE 0xFF000000U
+#define FETCHWARP9_STATICCONTROL_RESET_MASK 0xFFFFFFFFU
+#define FETCHWARP9_STATICCONTROL_SHDEN_MASK 0x1U
+#define FETCHWARP9_STATICCONTROL_SHDEN_SHIFT 0U
+#define FETCHWARP9_STATICCONTROL_BASEADDRESSAUTOUPDATE_MASK 0xFF0000U
+#define FETCHWARP9_STATICCONTROL_BASEADDRESSAUTOUPDATE_SHIFT 16U
+#define FETCHWARP9_STATICCONTROL_SHDLDREQSTICKY_MASK 0xFF000000U
+#define FETCHWARP9_STATICCONTROL_SHDLDREQSTICKY_SHIFT 24U
+
+#define FETCHWARP9_BURSTBUFFERMANAGEMENT ((uint32_t)(0x180C))
+#define FETCHWARP9_BASEADDRESS0 ((uint32_t)(0x1810))
+#define FETCHWARP9_SOURCEBUFFERATTRIBUTES0 ((uint32_t)(0x1814))
+#define FETCHWARP9_SOURCEBUFFERDIMENSION0 ((uint32_t)(0x1818))
+#define FETCHWARP9_COLORCOMPONENTBITS0 ((uint32_t)(0x181C))
+#define FETCHWARP9_COLORCOMPONENTSHIFT0 ((uint32_t)(0x1820))
+#define FETCHWARP9_LAYEROFFSET0 ((uint32_t)(0x1824))
+#define FETCHWARP9_CLIPWINDOWOFFSET0 ((uint32_t)(0x1828))
+#define FETCHWARP9_CLIPWINDOWDIMENSIONS0 ((uint32_t)(0x182C))
+#define FETCHWARP9_CONSTANTCOLOR0 ((uint32_t)(0x1830))
+#define FETCHWARP9_LAYERPROPERTY0 ((uint32_t)(0x1834))
+#define FETCHWARP9_FRAMEDIMENSIONS ((uint32_t)(0x1950))
+#define FETCHWARP9_FRAMERESAMPLING ((uint32_t)(0x1954))
+#define FETCHWARP9_CONTROL ((uint32_t)(0x1970))
+
+
+#define FETCHECO9_STATICCONTROL ((uint32_t)(0x1C08))
+#define FETCHECO9_STATICCONTROL_OFFSET ((uint32_t)(0x8))
+#define FETCHECO9_STATICCONTROL_RESET_VALUE 0U
+#define FETCHECO9_STATICCONTROL_RESET_MASK 0xFFFFFFFFU
+#define FETCHECO9_STATICCONTROL_SHDEN_MASK 0x1U
+#define FETCHECO9_STATICCONTROL_SHDEN_SHIFT 0U
+#define FETCHECO9_STATICCONTROL_BASEADDRESSAUTOUPDATE_MASK 0xFF0000U
+#define FETCHECO9_STATICCONTROL_BASEADDRESSAUTOUPDATE_SHIFT 16U
+
+#define FETCHECO9_BURSTBUFFERMANAGEMENT ((uint32_t)(0x1C0C))
+#define FETCHECO9_BASEADDRESS0 ((uint32_t)(0x1C10))
+#define FETCHECO9_SOURCEBUFFERATTRIBUTES0 ((uint32_t)(0x1C14))
+#define FETCHECO9_SOURCEBUFFERDIMENSION0 ((uint32_t)(0x1C18))
+#define FETCHECO9_COLORCOMPONENTBITS0 ((uint32_t)(0x1C1C))
+#define FETCHECO9_COLORCOMPONENTSHIFT0 ((uint32_t)(0x1C20))
+#define FETCHECO9_LAYEROFFSET0 ((uint32_t)(0x1C24))
+#define FETCHECO9_CLIPWINDOWOFFSET0 ((uint32_t)(0x1C28))
+#define FETCHECO9_CLIPWINDOWDIMENSIONS0 ((uint32_t)(0x1C2C))
+#define FETCHECO9_CONSTANTCOLOR0 ((uint32_t)(0x1C30))
+#define FETCHECO9_LAYERPROPERTY0 ((uint32_t)(0x1C34))
+#define FETCHECO9_FRAMEDIMENSIONS ((uint32_t)(0x1C38))
+#define FETCHECO9_FRAMERESAMPLING ((uint32_t)(0x1C3C))
+#define FETCHECO9_CONTROL ((uint32_t)(0x1C40))
+
+
+#define ROP9_STATICCONTROL ((uint32_t)(0x2008))
+#define ROP9_STATICCONTROL_OFFSET ((uint32_t)(0x8))
+#define ROP9_STATICCONTROL_RESET_VALUE 0U
+#define ROP9_STATICCONTROL_RESET_MASK 0xFFFFFFFFU
+#define ROP9_STATICCONTROL_SHDEN_MASK 0x1U
+#define ROP9_STATICCONTROL_SHDEN_SHIFT 0U
+
+#define ROP9_CONTROL ((uint32_t)(0x200C))
+
+#define MATRIX9_STATICCONTROL ((uint32_t)(0x2C08))
+#define MATRIX9_STATICCONTROL_OFFSET ((uint32_t)(0x8))
+#define MATRIX9_STATICCONTROL_RESET_VALUE 0U
+#define MATRIX9_STATICCONTROL_RESET_MASK 0xFFFFFFFFU
+#define MATRIX9_STATICCONTROL_SHDEN_MASK 0x1U
+#define MATRIX9_STATICCONTROL_SHDEN_SHIFT 0U
+
+#define MATRIX9_CONTROL ((uint32_t)(0x2C0C))
+
+#define HSCALER9_SETUP1 ((uint32_t)(0x300C))
+#define HSCALER9_SETUP2 ((uint32_t)(0x3010))
+#define HSCALER9_CONTROL ((uint32_t)(0x3014))
+
+#define VSCALER9_STATICCONTROL ((uint32_t)(0x3408))
+#define VSCALER9_STATICCONTROL_OFFSET ((uint32_t)(0x8))
+#define VSCALER9_STATICCONTROL_RESET_VALUE 0U
+#define VSCALER9_STATICCONTROL_RESET_MASK 0xFFFFFFFFU
+#define VSCALER9_STATICCONTROL_SHDEN_MASK 0x1U
+#define VSCALER9_STATICCONTROL_SHDEN_SHIFT 0U
+
+#define VSCALER9_SETUP1 ((uint32_t)(0x340C))
+#define VSCALER9_SETUP2 ((uint32_t)(0x3410))
+#define VSCALER9_SETUP3 ((uint32_t)(0x3414))
+#define VSCALER9_SETUP4 ((uint32_t)(0x3418))
+#define VSCALER9_SETUP5 ((uint32_t)(0x341C))
+#define VSCALER9_CONTROL ((uint32_t)(0x3420))
+
+#define HSCALER9_STATICCONTROL ((uint32_t)(0x3008))
+#define HSCALER9_STATICCONTROL_OFFSET ((uint32_t)(0x8))
+#define HSCALER9_STATICCONTROL_RESET_VALUE 0U
+#define HSCALER9_STATICCONTROL_RESET_MASK 0xFFFFFFFFU
+#define HSCALER9_STATICCONTROL_SHDEN_MASK 0x1U
+#define HSCALER9_STATICCONTROL_SHDEN_SHIFT 0U
+
+#define BLITBLEND9_STATICCONTROL ((uint32_t)(0x3C08))
+#define BLITBLEND9_STATICCONTROL_OFFSET ((uint32_t)(0x8))
+#define BLITBLEND9_STATICCONTROL_RESET_VALUE 0U
+#define BLITBLEND9_STATICCONTROL_RESET_MASK 0xFFFFFFFFU
+#define BLITBLEND9_STATICCONTROL_SHDEN_MASK 0x1U
+#define BLITBLEND9_STATICCONTROL_SHDEN_SHIFT 0U
+
+#define BLITBLEND9_CONTROL ((uint32_t)(0x3C0C))
+#define BLITBLEND9_CONSTANTCOLOR ((uint32_t)(0x3C14))
+#define BLITBLEND9_COLORREDBLENDFUNCTION ((uint32_t)(0x3C18))
+#define BLITBLEND9_COLORGREENBLENDFUNCTION ((uint32_t)(0x3C1C))
+#define BLITBLEND9_COLORBLUEBLENDFUNCTION ((uint32_t)(0x3C20))
+#define BLITBLEND9_ALPHABLENDFUNCTION ((uint32_t)(0x3C24))
+#define BLITBLEND9_BLENDMODE1 ((uint32_t)(0x3C28))
+#define BLITBLEND9_BLENDMODE2 ((uint32_t)(0x3C2C))
+
+
+#define STORE9_STATICCONTROL ((uint32_t)(0x4008))
+#define STORE9_STATICCONTROL_OFFSET ((uint32_t)(0x8))
+#define STORE9_STATICCONTROL_RESET_VALUE 0U
+#define STORE9_STATICCONTROL_RESET_MASK 0xFFFFFFFFU
+#define STORE9_STATICCONTROL_SHDEN_MASK 0x1U
+#define STORE9_STATICCONTROL_SHDEN_SHIFT 0U
+#define STORE9_STATICCONTROL_BASEADDRESSAUTOUPDATE_MASK 0x100U
+#define STORE9_STATICCONTROL_BASEADDRESSAUTOUPDATE_SHIFT 8U
+
+#define STORE9_BURSTBUFFERMANAGEMENT ((uint32_t)(0x400C))
+#define STORE9_BASEADDRESS ((uint32_t)(0x4018))
+#define STORE9_DESTINATIONBUFFERATTRIBUTES ((uint32_t)(0x401C))
+#define STORE9_DESTINATIONBUFFERDIMENSION ((uint32_t)(0x4020))
+#define STORE9_FRAMEOFFSET ((uint32_t)(0x4024))
+#define STORE9_COLORCOMPONENTBITS ((uint32_t)(0x4028))
+#define STORE9_COLORCOMPONENTSHIFT ((uint32_t)(0x402C))
+#define STORE9_CONTROL ((uint32_t)(0x4030))
+
+#define STORE9_START ((uint32_t)(0x403C))
+
+/* pixengcfg */
+#define PIXENGCFG_CLKEN_MASK 0x3000000U
+#define PIXENGCFG_CLKEN_SHIFT 24U
+/* Field Value: _CLKEN__DISABLE, Clock for block is disabled */
+#define PIXENGCFG_CLKEN__DISABLE 0U
+#define PIXENGCFG_CLKEN__AUTOMATIC 0x1U
+/* Field Value: _CLKEN__FULL, Clock for block is without gating */
+#define PIXENGCFG_CLKEN__FULL 0x3U
+
+#define PIXENGCFG_DIVIDER_RESET 0x80
+
+
+/* command sequencer */
+#define CMDSEQ_HIF ((uint32_t)(0x400))
+
+#define CMDSEQ_LOCKUNLOCKHIF ((uint32_t)(0x500))
+#define CMDSEQ_LOCKUNLOCKHIF_LOCKUNLOCKHIF__LOCK_KEY 0x5651F763U
+#define CMDSEQ_LOCKUNLOCKHIF_LOCKUNLOCKHIF__UNLOCK_KEY 0x691DB936U
+
+#define CMDSEQ_LOCKUNLOCK ((uint32_t)(0x580))
+#define CMDSEQ_LOCKUNLOCK_LOCKUNLOCK__LOCK_KEY 0x5651F763U
+#define CMDSEQ_LOCKUNLOCK_LOCKUNLOCK__UNLOCK_KEY 0x691DB936U
+
+#define CMDSEQ_BUFFERADDRESS ((uint32_t)(0x588))
+#define CMDSEQ_BUFFERSIZE ((uint32_t)(0x58C))
+
+#define CMDSEQ_CONTROL ((uint32_t)(0x594))
+#define CMDSEQ_CONTROL_OFFSET ((uint32_t)(0x194))
+#define CMDSEQ_CONTROL_RESET_VALUE 0U
+#define CMDSEQ_CONTROL_RESET_MASK 0xFFFFFFFFU
+#define CMDSEQ_CONTROL_CLRAXIW_MASK 0x1U
+#define CMDSEQ_CONTROL_CLRAXIW_SHIFT 0U
+#define CMDSEQ_CONTROL_CLRRBUF_MASK 0x4U
+#define CMDSEQ_CONTROL_CLRRBUF_SHIFT 2U
+#define CMDSEQ_CONTROL_CLRCMDBUF_MASK 0x8U
+#define CMDSEQ_CONTROL_CLRCMDBUF_SHIFT 3U
+#define CMDSEQ_CONTROL_CLEAR_MASK 0x80000000U
+#define CMDSEQ_CONTROL_CLEAR_SHIFT 31U
+
+#define CMDSEQ_STATUS ((uint32_t)(0x598))
+#define CMDSEQ_STATUS_OFFSET ((uint32_t)(0x198))
+#define CMDSEQ_STATUS_RESET_VALUE 0x41000080U
+#define CMDSEQ_STATUS_RESET_MASK 0xFFFFFFFFU
+#define CMDSEQ_STATUS_FIFOSPACE_MASK 0x1FFFFU
+#define CMDSEQ_STATUS_IDLE_MASK 0x40000000U
+
+#endif
diff --git a/drivers/gpu/imx/dpu-blit/dpu-blit.c b/drivers/gpu/imx/dpu-blit/dpu-blit.c
new file mode 100644
index 000000000000..550a9cec6861
--- /dev/null
+++ b/drivers/gpu/imx/dpu-blit/dpu-blit.c
@@ -0,0 +1,440 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017-2018 NXP
+ *
+ * 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/delay.h>
+#include <linux/dma-mapping.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/platform_device.h>
+#include <linux/types.h>
+#include <video/dpu.h>
+#include <video/imx8-prefetch.h>
+
+#include "dpu-blit.h"
+#include "dpu-blit-registers.h"
+#include "dpu-prv.h"
+
+static inline u32 dpu_be_read(struct dpu_bliteng *dpu_be, unsigned int offset)
+{
+ return readl(dpu_be->base + offset);
+}
+
+static inline void dpu_be_write(struct dpu_bliteng *dpu_be, u32 value,
+ unsigned int offset)
+{
+ writel(value, dpu_be->base + offset);
+}
+
+static void dpu_cs_wait_fifo_space(struct dpu_bliteng *dpu_be)
+{
+ while ((dpu_be_read(dpu_be, CMDSEQ_STATUS) &
+ CMDSEQ_STATUS_FIFOSPACE_MASK) < CMDSEQ_FIFO_SPACE_THRESHOLD)
+ usleep_range(30, 50);
+}
+
+static void dpu_cs_wait_idle(struct dpu_bliteng *dpu_be)
+{
+ while ((dpu_be_read(dpu_be, CMDSEQ_STATUS) &
+ CMDSEQ_STATUS_IDLE_MASK) == 0x0)
+ mdelay(1);
+}
+
+static int dpu_cs_alloc_command_buffer(struct dpu_bliteng *dpu_be)
+{
+ /* command buffer need 32 bit address */
+ dpu_be->buffer_addr_virt =
+ alloc_pages_exact(COMMAND_BUFFER_SIZE,
+ GFP_KERNEL | GFP_DMA | GFP_DMA32 | __GFP_ZERO);
+ if (!dpu_be->buffer_addr_virt) {
+ dev_err(dpu_be->dev, "memory alloc failed for dpu command buffer\n");
+ return -ENOMEM;
+ }
+
+ dpu_be->buffer_addr_phy =
+ (u32)virt_to_phys(dpu_be->buffer_addr_virt);
+
+ return 0;
+}
+
+static void dpu_cs_static_setup(struct dpu_bliteng *dpu_be)
+{
+ dpu_cs_wait_idle(dpu_be);
+
+ /* LockUnlock and LockUnlockHIF */
+ dpu_be_write(dpu_be, CMDSEQ_LOCKUNLOCKHIF_LOCKUNLOCKHIF__UNLOCK_KEY,
+ CMDSEQ_LOCKUNLOCKHIF);
+ dpu_be_write(dpu_be, CMDSEQ_LOCKUNLOCK_LOCKUNLOCK__UNLOCK_KEY,
+ CMDSEQ_LOCKUNLOCK);
+
+ /* Control */
+ dpu_be_write(dpu_be, 1 << CMDSEQ_CONTROL_CLEAR_SHIFT,
+ CMDSEQ_CONTROL);
+
+ /* BufferAddress and BufferSize */
+ dpu_be_write(dpu_be, dpu_be->buffer_addr_phy, CMDSEQ_BUFFERADDRESS);
+ dpu_be_write(dpu_be, COMMAND_BUFFER_SIZE / WORD_SIZE,
+ CMDSEQ_BUFFERSIZE);
+}
+
+static struct dprc *
+dpu_be_dprc_get(struct dpu_soc *dpu, int dprc_id)
+{
+ struct dprc *dprc;
+
+ dprc = dprc_lookup_by_phandle(dpu->dev,
+ "fsl,dpr-channels",
+ dprc_id);
+
+ return dprc;
+}
+
+void dpu_be_configure_prefetch(struct dpu_bliteng *dpu_be,
+ u32 width, u32 height,
+ u32 x_offset, u32 y_offset,
+ u32 stride, u32 format, u64 modifier,
+ u64 baddr, u64 uv_addr)
+{
+ struct dprc *dprc;
+ bool dprc_en=false;
+
+ /* Enable DPR, dprc1 is connected to plane0 */
+ dprc = dpu_be->dprc[1];
+
+ /*
+ * Force sync command sequncer in conditions:
+ * 1. tile work with dprc/prg (baddr)
+ * 2. switch tile to linear (!start)
+ */
+ if (!dpu_be->start || baddr) {
+ dpu_be_wait(dpu_be);
+ }
+
+ dpu_be->sync = true;
+
+ if (baddr == 0x0) {
+ if (!dpu_be->start) {
+ dprc_disable(dprc);
+ dpu_be->start = true;
+ }
+ return;
+ }
+
+ if (dpu_be->modifier != modifier && !dpu_be->start) {
+ dprc_disable(dprc);
+ dprc_en = true;
+ }
+
+ dpu_be->modifier = modifier;
+
+ dprc_configure(dprc, 0,
+ width, height,
+ x_offset, y_offset,
+ stride, format, modifier,
+ baddr, uv_addr,
+ dpu_be->start,
+ dpu_be->start,
+ false);
+
+ if (dpu_be->start || dprc_en) {
+ dprc_enable(dprc);
+ }
+
+ dprc_reg_update(dprc);
+
+ dpu_be->start = false;
+}
+EXPORT_SYMBOL(dpu_be_configure_prefetch);
+
+int dpu_bliteng_get_empty_instance(struct dpu_bliteng **dpu_be,
+ struct device *dev)
+{
+ if (!dpu_be || !dev)
+ return -EINVAL;
+
+ *dpu_be = devm_kzalloc(dev, sizeof(struct dpu_bliteng), GFP_KERNEL);
+ if (!(*dpu_be))
+ return -ENOMEM;
+
+ return 0;
+}
+EXPORT_SYMBOL(dpu_bliteng_get_empty_instance);
+
+u32 *dpu_bliteng_get_cmd_list(struct dpu_bliteng *dpu_be)
+{
+ return dpu_be->cmd_list;
+}
+EXPORT_SYMBOL(dpu_bliteng_get_cmd_list);
+
+s32 dpu_bliteng_get_id(struct dpu_bliteng *dpu_be)
+{
+ return dpu_be->id;
+}
+EXPORT_SYMBOL(dpu_bliteng_get_id);
+
+void dpu_bliteng_set_id(struct dpu_bliteng *dpu_be, int id)
+{
+ dpu_be->id = id;
+}
+EXPORT_SYMBOL(dpu_bliteng_set_id);
+
+void dpu_bliteng_set_dev(struct dpu_bliteng *dpu_be, struct device *dev)
+{
+ dpu_be->dev = dev;
+}
+EXPORT_SYMBOL(dpu_bliteng_set_dev);
+
+int dpu_be_get(struct dpu_bliteng *dpu_be)
+{
+ mutex_lock(&dpu_be->mutex);
+
+ return 0;
+}
+EXPORT_SYMBOL(dpu_be_get);
+
+void dpu_be_put(struct dpu_bliteng *dpu_be)
+{
+ mutex_unlock(&dpu_be->mutex);
+}
+EXPORT_SYMBOL(dpu_be_put);
+
+int dpu_be_blit(struct dpu_bliteng *dpu_be,
+ u32 *cmdlist, u32 cmdnum)
+{
+ int i;
+
+ if (cmdnum > CMDSEQ_FIFO_SPACE_THRESHOLD) {
+ dev_err(dpu_be->dev, "dpu blit cmdnum[%d] should be less than %d !\n",
+ cmdnum, CMDSEQ_FIFO_SPACE_THRESHOLD);
+ return -EINVAL;
+ }
+ dpu_cs_wait_fifo_space(dpu_be);
+
+ for (i = 0; i < cmdnum; i++)
+ dpu_be_write(dpu_be, cmdlist[i], CMDSEQ_HIF);
+
+ return 0;
+}
+EXPORT_SYMBOL(dpu_be_blit);
+
+#define STORE9_SEQCOMPLETE_IRQ 2U
+#define STORE9_SEQCOMPLETE_IRQ_MASK (1U<<STORE9_SEQCOMPLETE_IRQ)
+void dpu_be_wait(struct dpu_bliteng *dpu_be)
+{
+ if (!dpu_be->sync) return;
+
+ dpu_cs_wait_fifo_space(dpu_be);
+
+ dpu_be_write(dpu_be, 0x14000001, CMDSEQ_HIF);
+ dpu_be_write(dpu_be, PIXENGCFG_STORE9_TRIGGER, CMDSEQ_HIF);
+ dpu_be_write(dpu_be, 0x10, CMDSEQ_HIF);
+
+ while ((dpu_be_read(dpu_be, COMCTRL_INTERRUPTSTATUS0) &
+ STORE9_SEQCOMPLETE_IRQ_MASK) == 0)
+ usleep_range(30, 50);
+
+ dpu_be_write(dpu_be, STORE9_SEQCOMPLETE_IRQ_MASK,
+ COMCTRL_INTERRUPTCLEAR0);
+
+ dpu_be->sync = false;
+}
+EXPORT_SYMBOL(dpu_be_wait);
+
+static void dpu_be_init_units(struct dpu_bliteng *dpu_be)
+{
+ u32 staticcontrol;
+ u32 pixengcfg_unit_static, pixengcfg_unit_dynamic;
+
+ staticcontrol =
+ 1 << FETCHDECODE9_STATICCONTROL_SHDEN_SHIFT |
+ 0 << FETCHDECODE9_STATICCONTROL_BASEADDRESSAUTOUPDATE_SHIFT |
+ FETCHDECODE9_STATICCONTROL_RESET_VALUE;
+ dpu_be_write(dpu_be, staticcontrol, FETCHDECODE9_STATICCONTROL);
+
+ staticcontrol =
+ 1 << FETCHWARP9_STATICCONTROL_SHDEN_SHIFT |
+ 0 << FETCHWARP9_STATICCONTROL_BASEADDRESSAUTOUPDATE_SHIFT |
+ FETCHWARP9_STATICCONTROL_RESET_VALUE;
+ dpu_be_write(dpu_be, staticcontrol, FETCHWARP9_STATICCONTROL);
+
+ staticcontrol =
+ 1 << FETCHECO9_STATICCONTROL_SHDEN_SHIFT |
+ 0 << FETCHECO9_STATICCONTROL_BASEADDRESSAUTOUPDATE_SHIFT |
+ FETCHECO9_STATICCONTROL_RESET_VALUE;
+ dpu_be_write(dpu_be, staticcontrol, FETCHECO9_STATICCONTROL);
+
+ staticcontrol =
+ 1 << HSCALER9_STATICCONTROL_SHDEN_SHIFT |
+ HSCALER9_STATICCONTROL_RESET_VALUE;
+ dpu_be_write(dpu_be, staticcontrol, HSCALER9_STATICCONTROL);
+
+ staticcontrol =
+ 1 << VSCALER9_STATICCONTROL_SHDEN_SHIFT |
+ VSCALER9_STATICCONTROL_RESET_VALUE;
+ dpu_be_write(dpu_be, staticcontrol, VSCALER9_STATICCONTROL);
+
+ staticcontrol =
+ 1 << ROP9_STATICCONTROL_SHDEN_SHIFT |
+ ROP9_STATICCONTROL_RESET_VALUE;
+ dpu_be_write(dpu_be, staticcontrol, ROP9_STATICCONTROL);
+
+ staticcontrol =
+ 1 << MATRIX9_STATICCONTROL_SHDEN_SHIFT |
+ MATRIX9_STATICCONTROL_RESET_VALUE;
+ dpu_be_write(dpu_be, staticcontrol, MATRIX9_STATICCONTROL);
+
+ staticcontrol =
+ 1 << BLITBLEND9_STATICCONTROL_SHDEN_SHIFT |
+ BLITBLEND9_STATICCONTROL_RESET_VALUE;
+ dpu_be_write(dpu_be, staticcontrol, BLITBLEND9_STATICCONTROL);
+
+ staticcontrol =
+ 1 << STORE9_STATICCONTROL_SHDEN_SHIFT |
+ 0 << STORE9_STATICCONTROL_BASEADDRESSAUTOUPDATE_SHIFT |
+ STORE9_STATICCONTROL_RESET_VALUE;
+ dpu_be_write(dpu_be, staticcontrol, STORE9_STATICCONTROL);
+
+ /* Safety_Pixengcfg Static */
+ pixengcfg_unit_static =
+ 1 << PIXENGCFG_STORE9_STATIC_STORE9_SHDEN_SHIFT |
+ 0 << PIXENGCFG_STORE9_STATIC_STORE9_POWERDOWN_SHIFT |
+ PIXENGCFG_STORE9_STATIC_STORE9_SYNC_MODE__SINGLE <<
+ PIXENGCFG_STORE9_STATIC_STORE9_SYNC_MODE_SHIFT |
+ PIXENGCFG_STORE9_STATIC_STORE9_SW_RESET__OPERATION <<
+ PIXENGCFG_STORE9_STATIC_STORE9_SW_RESET_SHIFT |
+ PIXENGCFG_DIVIDER_RESET <<
+ PIXENGCFG_STORE9_STATIC_STORE9_DIV_SHIFT;
+ dpu_be_write(dpu_be, pixengcfg_unit_static, PIXENGCFG_STORE9_STATIC);
+
+ /* Safety_Pixengcfg Dynamic */
+ pixengcfg_unit_dynamic =
+ PIXENGCFG_CLKEN__AUTOMATIC << PIXENGCFG_CLKEN_SHIFT |
+ PIXENGCFG_FETCHDECODE9_DYNAMIC_RESET_VALUE;
+ dpu_be_write(dpu_be, pixengcfg_unit_dynamic,
+ PIXENGCFG_FETCHDECODE9_DYNAMIC);
+
+ pixengcfg_unit_dynamic =
+ PIXENGCFG_CLKEN__AUTOMATIC << PIXENGCFG_CLKEN_SHIFT |
+ PIXENGCFG_FETCHWARP9_DYNAMIC_RESET_VALUE;
+ dpu_be_write(dpu_be, pixengcfg_unit_dynamic,
+ PIXENGCFG_FETCHWARP9_DYNAMIC);
+
+ pixengcfg_unit_dynamic =
+ PIXENGCFG_CLKEN__AUTOMATIC << PIXENGCFG_CLKEN_SHIFT |
+ PIXENGCFG_ROP9_DYNAMIC_RESET_VALUE;
+ dpu_be_write(dpu_be, pixengcfg_unit_dynamic,
+ PIXENGCFG_ROP9_DYNAMIC);
+
+ pixengcfg_unit_dynamic =
+ PIXENGCFG_CLKEN__AUTOMATIC << PIXENGCFG_CLKEN_SHIFT |
+ PIXENGCFG_MATRIX9_DYNAMIC_RESET_VALUE;
+ dpu_be_write(dpu_be, pixengcfg_unit_dynamic,
+ PIXENGCFG_MATRIX9_DYNAMIC);
+
+ pixengcfg_unit_dynamic =
+ PIXENGCFG_CLKEN__AUTOMATIC << PIXENGCFG_CLKEN_SHIFT |
+ PIXENGCFG_HSCALER9_DYNAMIC_RESET_VALUE;
+ dpu_be_write(dpu_be, pixengcfg_unit_dynamic,
+ PIXENGCFG_HSCALER9_DYNAMIC);
+
+ pixengcfg_unit_dynamic =
+ PIXENGCFG_CLKEN__AUTOMATIC << PIXENGCFG_CLKEN_SHIFT |
+ PIXENGCFG_VSCALER9_DYNAMIC_RESET_VALUE;
+ dpu_be_write(dpu_be, pixengcfg_unit_dynamic,
+ PIXENGCFG_VSCALER9_DYNAMIC);
+
+ pixengcfg_unit_dynamic =
+ PIXENGCFG_CLKEN__AUTOMATIC << PIXENGCFG_CLKEN_SHIFT |
+ PIXENGCFG_BLITBLEND9_DYNAMIC_RESET_VALUE;
+ dpu_be_write(dpu_be, pixengcfg_unit_dynamic,
+ PIXENGCFG_BLITBLEND9_DYNAMIC);
+}
+
+int dpu_bliteng_init(struct dpu_bliteng *dpu_bliteng)
+{
+ struct dpu_soc *dpu = dev_get_drvdata(dpu_bliteng->dev->parent);
+ struct platform_device *dpu_pdev =
+ container_of(dpu->dev, struct platform_device, dev);
+ struct resource *res;
+ unsigned long dpu_base;
+ void __iomem *base;
+ u32 *cmd_list;
+ int ret;
+
+ cmd_list = kzalloc(sizeof(*cmd_list) * CMDSEQ_FIFO_SPACE_THRESHOLD,
+ GFP_KERNEL);
+ if (!cmd_list)
+ return -ENOMEM;
+ dpu_bliteng->cmd_list = cmd_list;
+
+ res = platform_get_resource(dpu_pdev, IORESOURCE_MEM, 0);
+ if (!res)
+ return -ENODEV;
+ dpu_base = res->start;
+
+ /* remap with bigger size */
+ base = devm_ioremap(dpu->dev, dpu_base, COMMAND_BUFFER_SIZE);
+ dpu_bliteng->base = base;
+ dpu_bliteng->dpu = dpu;
+
+ mutex_init(&dpu_bliteng->mutex);
+
+ /* Init the uints used by blit engine */
+ /* Maybe this should be in dpu-common.c */
+ dpu_be_init_units(dpu_bliteng);
+
+ /* Init for command sequencer */
+ ret = dpu_cs_alloc_command_buffer(dpu_bliteng);
+ if (ret)
+ return ret;
+
+ dpu_cs_static_setup(dpu_bliteng);
+
+ /* DPR, each blit engine has two dprc, 0 & 1 */
+ dpu_bliteng->dprc[0] = dpu_be_dprc_get(dpu, 0);
+ dpu_bliteng->dprc[1] = dpu_be_dprc_get(dpu, 1);
+
+ dprc_disable(dpu_bliteng->dprc[0]);
+ dprc_disable(dpu_bliteng->dprc[1]);
+
+ dpu_bliteng->start = true;
+ dpu_bliteng->sync = false;
+
+ dpu_bliteng->modifier = 0;
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(dpu_bliteng_init);
+
+void dpu_bliteng_fini(struct dpu_bliteng *dpu_bliteng)
+{
+ /* LockUnlock and LockUnlockHIF */
+ dpu_be_write(dpu_bliteng, CMDSEQ_LOCKUNLOCKHIF_LOCKUNLOCKHIF__LOCK_KEY,
+ CMDSEQ_LOCKUNLOCKHIF);
+ dpu_be_write(dpu_bliteng, CMDSEQ_LOCKUNLOCK_LOCKUNLOCK__LOCK_KEY,
+ CMDSEQ_LOCKUNLOCK);
+
+ kfree(dpu_bliteng->cmd_list);
+
+ if (dpu_bliteng->buffer_addr_virt)
+ free_pages_exact(dpu_bliteng->buffer_addr_virt,
+ COMMAND_BUFFER_SIZE);
+}
+EXPORT_SYMBOL_GPL(dpu_bliteng_fini);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("NXP Semiconductor");
+MODULE_DESCRIPTION("i.MX DPU BLITENG");
+MODULE_ALIAS("platform:imx-dpu-bliteng");
diff --git a/drivers/gpu/imx/dpu-blit/dpu-blit.h b/drivers/gpu/imx/dpu-blit/dpu-blit.h
new file mode 100644
index 000000000000..a3fe17276a9c
--- /dev/null
+++ b/drivers/gpu/imx/dpu-blit/dpu-blit.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017-2018 NXP
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#ifndef __DPU_BLIT_H__
+#define __DPU_BLIT_H__
+
+#define COMMAND_BUFFER_SIZE 65536 /* up to 64k bytes */
+#define CMDSEQ_FIFO_SPACE_THRESHOLD 192
+#define WORD_SIZE 4
+
+struct dpu_bliteng {
+ struct device *dev;
+ void __iomem *base;
+ s32 id;
+ struct mutex mutex;
+ s32 irq_store9_shdload;
+ s32 irq_store9_framecomplete;
+ s32 irq_store9_seqcomplete;
+
+ void *buffer_addr_virt;
+ u32 buffer_addr_phy;
+
+ u32 *cmd_list;
+
+ struct dpu_soc *dpu;
+
+ struct dprc *dprc[2];
+
+ bool start;
+ bool sync;
+
+ u64 modifier;
+};
+
+#endif
diff --git a/drivers/gpu/imx/dpu/Kconfig b/drivers/gpu/imx/dpu/Kconfig
new file mode 100644
index 000000000000..7ccba746d6d6
--- /dev/null
+++ b/drivers/gpu/imx/dpu/Kconfig
@@ -0,0 +1,12 @@
+config IMX_DPU_CORE
+ tristate "i.MX DPU core support"
+ depends on ARCH_FSL_IMX8QM || ARCH_FSL_IMX8QXP
+ select RESET_CONTROLLER
+ select GENERIC_IRQ_CHIP
+ select IMX8_PC
+ select IMX8_PRG
+ select IMX8_DPRC
+ help
+ Choose this if you have a Freescale i.MX8QM or i.MX8QXP system and
+ want to use the Display Processing Unit. This option only enables
+ DPU base support.
diff --git a/drivers/gpu/imx/dpu/Makefile b/drivers/gpu/imx/dpu/Makefile
new file mode 100644
index 000000000000..4563bacf6398
--- /dev/null
+++ b/drivers/gpu/imx/dpu/Makefile
@@ -0,0 +1,7 @@
+obj-$(CONFIG_IMX_DPU_CORE) += imx-dpu-core.o
+
+imx-dpu-core-objs := dpu-common.o dpu-constframe.o dpu-disengcfg.o \
+ dpu-extdst.o dpu-fetchdecode.o dpu-fetcheco.o \
+ dpu-fetchlayer.o dpu-fetchwarp.o dpu-fetchunit.o \
+ dpu-framegen.o dpu-hscaler.o dpu-layerblend.o \
+ dpu-store.o dpu-tcon.o dpu-vscaler.o
diff --git a/drivers/gpu/imx/dpu/dpu-common.c b/drivers/gpu/imx/dpu/dpu-common.c
new file mode 100644
index 000000000000..4a1e78b27f2d
--- /dev/null
+++ b/drivers/gpu/imx/dpu/dpu-common.c
@@ -0,0 +1,1917 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017-2018 NXP
+ *
+ * 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/clk.h>
+#include <linux/fb.h>
+#include <linux/io.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/irqchip/chained_irq.h>
+#include <linux/irqdomain.h>
+#include <linux/mfd/syscon.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/of_graph.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <soc/imx8/sc/sci.h>
+#include <video/dpu.h>
+#include <video/imx8-pc.h>
+#include <video/imx8-prefetch.h>
+#include "dpu-prv.h"
+
+static bool display_plane_video_proc = true;
+module_param(display_plane_video_proc, bool, 0444);
+MODULE_PARM_DESC(display_plane_video_proc,
+ "Enable video processing for display [default=true]");
+
+#define DPU_CM_REG_DEFINE1(name1, name2) \
+static inline u32 name1(const struct cm_reg_ofs *ofs) \
+{ \
+ return ofs->name2; \
+}
+
+#define DPU_CM_REG_DEFINE2(name1, name2) \
+static inline u32 name1(const struct cm_reg_ofs *ofs, \
+ unsigned int n) \
+{ \
+ return ofs->name2 + (4 * n); \
+}
+
+DPU_CM_REG_DEFINE1(IPIDENTIFIER, ipidentifier);
+
+#define DESIGNDELIVERYID_MASK 0xF0U
+#define DESIGNDELIVERYID_SHIFT 4U
+
+#define DESIGNMATURITYLEVEL_MASK 0xF00U
+#define DESIGNMATURITYLEVEL_SHIFT 8U
+enum design_maturity_level {
+ /* Pre feasibility study. */
+ DESIGNMATURITYLEVEL__PREFS = 1 << DESIGNMATURITYLEVEL_SHIFT,
+ /* Feasibility study. */
+ DESIGNMATURITYLEVEL__FS = 2 << DESIGNMATURITYLEVEL_SHIFT,
+ /* Functionality complete. */
+ DESIGNMATURITYLEVEL__R0 = 3 << DESIGNMATURITYLEVEL_SHIFT,
+ /* Verification complete. */
+ DESIGNMATURITYLEVEL__R1 = 4 << DESIGNMATURITYLEVEL_SHIFT,
+};
+
+#define IPEVOLUTION_MASK 0xF000U
+#define IPEVOLUTION_SHIFT 12U
+
+#define IPFEATURESET_MASK 0xF0000U
+#define IPFEATURESET_SHIFT 16U
+enum ip_feature_set {
+ /* Minimal functionality (Eco). */
+ IPFEATURESET__E = 1 << IPFEATURESET_SHIFT,
+ /* Reduced functionality (Light). */
+ IPFEATURESET__L = 2 << IPFEATURESET_SHIFT,
+ /* Advanced functionality (Plus). */
+ IPFEATURESET__P = 4 << IPFEATURESET_SHIFT,
+ /* Extensive functionality (eXtensive). */
+ IPFEATURESET__X = 5 << IPFEATURESET_SHIFT,
+};
+
+#define IPAPPLICATION_MASK 0xF00000U
+#define IPAPPLICATION_SHIFT 20U
+enum ip_application {
+ /* Blit Engine only. */
+ IPAPPLICATION__B = 1 << IPAPPLICATION_SHIFT,
+ /* Blit Engine and Display Controller. */
+ IPAPPLICATION__D = 2 << IPAPPLICATION_SHIFT,
+ /* Display Controller only (with direct capture). */
+ IPAPPLICATION__V = 3 << IPAPPLICATION_SHIFT,
+ /*
+ * Blit Engine, Display Controller (with direct capture),
+ * Capture Controller (buffered capture) and Drawing Engine.
+ */
+ IPAPPLICATION__G = 4 << IPAPPLICATION_SHIFT,
+ /* Display Controller only. */
+ IPAPPLICATION__C = 5 << IPAPPLICATION_SHIFT,
+};
+
+#define IPCONFIGURATION_MASK 0xF000000U
+#define IPCONFIGURATION_SHIFT 24U
+enum ip_configuration {
+ /* Graphics core only (Module). */
+ IPCONFIGURATION__M = 1 << IPCONFIGURATION_SHIFT,
+ /* Subsystem including a graphics core (System). */
+ IPCONFIGURATION__S = 2 << IPCONFIGURATION_SHIFT,
+};
+
+#define IPFAMILY_MASK 0xF0000000U
+#define IPFAMILY_SHIFT 28U
+enum ip_family {
+ /* IMXDPU building block generation 2010. */
+ IPFAMILY__IMXDPU2010 = 0,
+ /* IMXDPU building block generation 2012. */
+ IPFAMILY__IMXDPU2012 = 1 << IPFAMILY_SHIFT,
+ /* IMXDPU building block generation 2013. */
+ IPFAMILY__IMXDPU2013 = 2 << IPFAMILY_SHIFT,
+};
+
+DPU_CM_REG_DEFINE1(LOCKUNLOCK, lockunlock);
+DPU_CM_REG_DEFINE1(LOCKSTATUS, lockstatus);
+DPU_CM_REG_DEFINE2(USERINTERRUPTMASK, userinterruptmask);
+DPU_CM_REG_DEFINE2(INTERRUPTENABLE, interruptenable);
+DPU_CM_REG_DEFINE2(INTERRUPTPRESET, interruptpreset);
+DPU_CM_REG_DEFINE2(INTERRUPTCLEAR, interruptclear);
+DPU_CM_REG_DEFINE2(INTERRUPTSTATUS, interruptstatus);
+DPU_CM_REG_DEFINE2(USERINTERRUPTENABLE, userinterruptenable);
+DPU_CM_REG_DEFINE2(USERINTERRUPTPRESET, userinterruptpreset);
+DPU_CM_REG_DEFINE2(USERINTERRUPTCLEAR, userinterruptclear);
+DPU_CM_REG_DEFINE2(USERINTERRUPTSTATUS, userinterruptstatus);
+DPU_CM_REG_DEFINE1(GENERALPURPOSE, generalpurpose);
+
+static inline u32 dpu_cm_read(struct dpu_soc *dpu, unsigned int offset)
+{
+ return readl(dpu->cm_reg + offset);
+}
+
+static inline void dpu_cm_write(struct dpu_soc *dpu, u32 value,
+ unsigned int offset)
+{
+ writel(value, dpu->cm_reg + offset);
+}
+
+/* Constant Frame Unit */
+static const unsigned long cf_ofss[] = {0x4400, 0x5400, 0x4c00, 0x5c00};
+static const unsigned long cf_pec_ofss_v1[] = {0x980, 0xa00, 0x9c0, 0xa40};
+static const unsigned long cf_pec_ofss_v2[] = {0x960, 0x9e0, 0x9a0, 0xa20};
+
+/* Display Engine Configuration Unit */
+static const unsigned long dec_ofss_v1[] = {0x10000, 0x10020};
+static const unsigned long dec_ofss_v2[] = {0xb400, 0xb420};
+
+/* External Destination Unit */
+static const unsigned long ed_ofss[] = {0x4800, 0x5800, 0x5000, 0x6000};
+static const unsigned long ed_pec_ofss_v1[] = {0x9a0, 0xa20, 0x9e0, 0xa60};
+static const unsigned long ed_pec_ofss_v2[] = {0x980, 0xa00, 0x9c0, 0xa40};
+
+/* Fetch Decode Unit */
+static const unsigned long fd_ofss_v1[] = {0x8c00, 0x9800, 0x7400, 0x7c00};
+static const unsigned long fd_ofss_v2[] = {0x6c00, 0x7800};
+static const unsigned long fd_pec_ofss_v1[] = {0xb60, 0xb80, 0xb00, 0xb20};
+static const unsigned long fd_pec_ofss_v2[] = {0xa80, 0xaa0};
+
+/* Fetch ECO Unit */
+static const unsigned long fe_ofss_v1[] = {0x9400, 0xa000, 0x8800, 0x1c00};
+static const unsigned long fe_ofss_v2[] = {0x7400, 0x8000, 0x6800, 0x1c00};
+static const unsigned long fe_pec_ofss_v1[] = {0xb70, 0xb90, 0xb50, 0x870};
+static const unsigned long fe_pec_ofss_v2[] = {0xa90, 0xab0, 0xa70, 0x850};
+
+/* Frame Generator Unit */
+static const unsigned long fg_ofss_v1[] = {0x10c00, 0x12800};
+static const unsigned long fg_ofss_v2[] = {0xb800, 0xd400};
+
+/* Fetch Layer Unit */
+static const unsigned long fl_ofss_v1[] = {0xa400, 0xac00};
+static const unsigned long fl_ofss_v2[] = {0x8400};
+static const unsigned long fl_pec_ofss_v1[] = {0xba0, 0xbb0};
+static const unsigned long fl_pec_ofss_v2[] = {0xac0};
+
+/* Fetch Warp Unit */
+static const unsigned long fw_ofss_v1[] = {0x8400};
+static const unsigned long fw_ofss_v2[] = {0x6400};
+static const unsigned long fw_pec_ofss_v1[] = {0xb40};
+static const unsigned long fw_pec_ofss_v2[] = {0xa60};
+
+/* Horizontal Scaler Unit */
+static const unsigned long hs_ofss_v1[] = {0xbc00, 0xd000, 0x3000};
+static const unsigned long hs_ofss_v2[] = {0x9000, 0x9c00, 0x3000};
+static const unsigned long hs_pec_ofss_v1[] = {0xc00, 0xca0, 0x8e0};
+static const unsigned long hs_pec_ofss_v2[] = {0xb00, 0xb60, 0x8c0};
+
+/* Layer Blend Unit */
+static const unsigned long lb_ofss_v1[] = {0xdc00, 0xe000, 0xe400, 0xe800,
+ 0xec00, 0xf000, 0xf400};
+static const unsigned long lb_ofss_v2[] = {0xa400, 0xa800, 0xac00, 0xb000};
+static const unsigned long lb_pec_ofss_v1[] = {0xd00, 0xd20, 0xd40, 0xd60,
+ 0xd80, 0xda0, 0xdc0};
+static const unsigned long lb_pec_ofss_v2[] = {0xba0, 0xbc0, 0xbe0, 0xc00};
+
+/* Store Unit */
+static const unsigned long st_ofss_v1[] = {0x4000};
+static const unsigned long st_ofss_v2[] = {0x4000};
+static const unsigned long st_pec_ofss_v1[] = {0x960};
+static const unsigned long st_pec_ofss_v2[] = {0x940};
+
+/* Timing Controller Unit */
+static const unsigned long tcon_ofss_v1[] = {0x12000, 0x13c00};
+static const unsigned long tcon_ofss_v2[] = {0xcc00, 0xe800};
+
+/* Vertical Scaler Unit */
+static const unsigned long vs_ofss_v1[] = {0xc000, 0xd400, 0x3400};
+static const unsigned long vs_ofss_v2[] = {0x9400, 0xa000, 0x3400};
+static const unsigned long vs_pec_ofss_v1[] = {0xc20, 0xcc0, 0x900};
+static const unsigned long vs_pec_ofss_v2[] = {0xb20, 0xb80, 0x8e0};
+
+static const struct dpu_unit cfs_v1 = {
+ .name = "ConstFrame",
+ .num = ARRAY_SIZE(cf_ids),
+ .ids = cf_ids,
+ .pec_ofss = cf_pec_ofss_v1,
+ .ofss = cf_ofss,
+};
+
+static const struct dpu_unit cfs_v2 = {
+ .name = "ConstFrame",
+ .num = ARRAY_SIZE(cf_ids),
+ .ids = cf_ids,
+ .pec_ofss = cf_pec_ofss_v2,
+ .ofss = cf_ofss,
+};
+
+static const struct dpu_unit decs_v1 = {
+ .name = "DisEngCfg",
+ .num = ARRAY_SIZE(dec_ids),
+ .ids = dec_ids,
+ .pec_ofss = NULL,
+ .ofss = dec_ofss_v1,
+};
+
+static const struct dpu_unit decs_v2 = {
+ .name = "DisEngCfg",
+ .num = ARRAY_SIZE(dec_ids),
+ .ids = dec_ids,
+ .pec_ofss = NULL,
+ .ofss = dec_ofss_v2,
+};
+
+static const struct dpu_unit eds_v1 = {
+ .name = "ExtDst",
+ .num = ARRAY_SIZE(ed_ids),
+ .ids = ed_ids,
+ .pec_ofss = ed_pec_ofss_v1,
+ .ofss = ed_ofss,
+};
+
+static const struct dpu_unit eds_v2 = {
+ .name = "ExtDst",
+ .num = ARRAY_SIZE(ed_ids),
+ .ids = ed_ids,
+ .pec_ofss = ed_pec_ofss_v2,
+ .ofss = ed_ofss,
+};
+
+static const struct dpu_unit fds_v1 = {
+ .name = "FetchDecode",
+ .num = ARRAY_SIZE(fd_ids),
+ .ids = fd_ids,
+ .pec_ofss = fd_pec_ofss_v1,
+ .ofss = fd_ofss_v1,
+};
+
+static const struct dpu_unit fds_v2 = {
+ .name = "FetchDecode",
+ .num = 2,
+ .ids = fd_ids,
+ .pec_ofss = fd_pec_ofss_v2,
+ .ofss = fd_ofss_v2,
+ .dprc_ids = fd_dprc_ids,
+};
+
+static const struct dpu_unit fes_v1 = {
+ .name = "FetchECO",
+ .num = ARRAY_SIZE(fe_ids),
+ .ids = fe_ids,
+ .pec_ofss = fe_pec_ofss_v1,
+ .ofss = fe_ofss_v1,
+};
+
+static const struct dpu_unit fes_v2 = {
+ .name = "FetchECO",
+ .num = ARRAY_SIZE(fe_ids),
+ .ids = fe_ids,
+ .pec_ofss = fe_pec_ofss_v2,
+ .ofss = fe_ofss_v2,
+};
+
+static const struct dpu_unit fgs_v1 = {
+ .name = "FrameGen",
+ .num = ARRAY_SIZE(fg_ids),
+ .ids = fg_ids,
+ .pec_ofss = NULL,
+ .ofss = fg_ofss_v1,
+};
+
+static const struct dpu_unit fgs_v2 = {
+ .name = "FrameGen",
+ .num = ARRAY_SIZE(fg_ids),
+ .ids = fg_ids,
+ .pec_ofss = NULL,
+ .ofss = fg_ofss_v2,
+};
+
+static const struct dpu_unit fls_v1 = {
+ .name = "FetchLayer",
+ .num = ARRAY_SIZE(fl_ids),
+ .ids = fl_ids,
+ .pec_ofss = fl_pec_ofss_v1,
+ .ofss = fl_ofss_v1,
+};
+
+static const struct dpu_unit fls_v2 = {
+ .name = "FetchLayer",
+ .num = 1,
+ .ids = fl_ids,
+ .pec_ofss = fl_pec_ofss_v2,
+ .ofss = fl_ofss_v2,
+ .dprc_ids = fl_dprc_ids,
+};
+
+static const struct dpu_unit fws_v1 = {
+ .name = "FetchWarp",
+ .num = ARRAY_SIZE(fw_ids),
+ .ids = fw_ids,
+ .pec_ofss = fw_pec_ofss_v1,
+ .ofss = fw_ofss_v1,
+};
+
+static const struct dpu_unit fws_v2 = {
+ .name = "FetchWarp",
+ .num = ARRAY_SIZE(fw_ids),
+ .ids = fw_ids,
+ .pec_ofss = fw_pec_ofss_v2,
+ .ofss = fw_ofss_v2,
+ .dprc_ids = fw_dprc_ids,
+};
+
+static const struct dpu_unit hss_v1 = {
+ .name = "HScaler",
+ .num = ARRAY_SIZE(hs_ids),
+ .ids = hs_ids,
+ .pec_ofss = hs_pec_ofss_v1,
+ .ofss = hs_ofss_v1,
+};
+
+static const struct dpu_unit hss_v2 = {
+ .name = "HScaler",
+ .num = ARRAY_SIZE(hs_ids),
+ .ids = hs_ids,
+ .pec_ofss = hs_pec_ofss_v2,
+ .ofss = hs_ofss_v2,
+};
+
+static const struct dpu_unit lbs_v1 = {
+ .name = "LayerBlend",
+ .num = ARRAY_SIZE(lb_ids),
+ .ids = lb_ids,
+ .pec_ofss = lb_pec_ofss_v1,
+ .ofss = lb_ofss_v1,
+};
+
+static const struct dpu_unit lbs_v2 = {
+ .name = "LayerBlend",
+ .num = 4,
+ .ids = lb_ids,
+ .pec_ofss = lb_pec_ofss_v2,
+ .ofss = lb_ofss_v2,
+};
+
+static const struct dpu_unit sts_v1 = {
+ .name = "Store",
+ .num = ARRAY_SIZE(st_ids),
+ .ids = st_ids,
+ .pec_ofss = st_pec_ofss_v1,
+ .ofss = st_ofss_v1,
+};
+
+static const struct dpu_unit sts_v2 = {
+ .name = "Store",
+ .num = ARRAY_SIZE(st_ids),
+ .ids = st_ids,
+ .pec_ofss = st_pec_ofss_v2,
+ .ofss = st_ofss_v2,
+};
+
+static const struct dpu_unit tcons_v1 = {
+ .name = "TCon",
+ .num = ARRAY_SIZE(tcon_ids),
+ .ids = tcon_ids,
+ .pec_ofss = NULL,
+ .ofss = tcon_ofss_v1,
+};
+
+static const struct dpu_unit tcons_v2 = {
+ .name = "TCon",
+ .num = ARRAY_SIZE(tcon_ids),
+ .ids = tcon_ids,
+ .pec_ofss = NULL,
+ .ofss = tcon_ofss_v2,
+};
+
+static const struct dpu_unit vss_v1 = {
+ .name = "VScaler",
+ .num = ARRAY_SIZE(vs_ids),
+ .ids = vs_ids,
+ .pec_ofss = vs_pec_ofss_v1,
+ .ofss = vs_ofss_v1,
+};
+
+static const struct dpu_unit vss_v2 = {
+ .name = "VScaler",
+ .num = ARRAY_SIZE(vs_ids),
+ .ids = vs_ids,
+ .pec_ofss = vs_pec_ofss_v2,
+ .ofss = vs_ofss_v2,
+};
+
+static const struct cm_reg_ofs cm_reg_ofs_v1 = {
+ .ipidentifier = 0,
+ .lockunlock = 0x80,
+ .lockstatus = 0x84,
+ .userinterruptmask = 0x88,
+ .interruptenable = 0x94,
+ .interruptpreset = 0xa0,
+ .interruptclear = 0xac,
+ .interruptstatus = 0xb8,
+ .userinterruptenable = 0x100,
+ .userinterruptpreset = 0x10c,
+ .userinterruptclear = 0x118,
+ .userinterruptstatus = 0x124,
+ .generalpurpose = 0x200,
+};
+
+static const struct cm_reg_ofs cm_reg_ofs_v2 = {
+ .ipidentifier = 0,
+ .lockunlock = 0x40,
+ .lockstatus = 0x44,
+ .userinterruptmask = 0x48,
+ .interruptenable = 0x50,
+ .interruptpreset = 0x58,
+ .interruptclear = 0x60,
+ .interruptstatus = 0x68,
+ .userinterruptenable = 0x80,
+ .userinterruptpreset = 0x88,
+ .userinterruptclear = 0x90,
+ .userinterruptstatus = 0x98,
+ .generalpurpose = 0x100,
+};
+
+static const unsigned int intsteer_map_v1[] = {
+ /* 0 1 2 3 4 5 6 7 */ /* 0~31: int0 */
+ 448, 449, 450, 64, 65, 66, 67, 68,
+ /* 8 9 10 11 12 13 14 15 */
+ 69, 70, 193, 194, 195, 196, 197, 320,
+ /* 16 17 18 19 20 21 22 23 */
+ 321, 322, 384, 385, 386, NA, 323, NA,
+ /* 24 25 26 27 28 29 30 31 */
+ 387, 71, 198, 72, 73, 74, 75, 76,
+ /* 32 33 34 35 36 37 38 39 */ /* 32~63: int1 */
+ 77, 78, 79, 80, 81, 199, 200, 201,
+ /* 40 41 42 43 44 45 46 47 */
+ 202, 203, 204, 205, 206, 207, 208, 324,
+ /* 48 49 50 51 52 53 54 55 */
+ 389, NA, 0, 1, 2, 3, 4, 82,
+ /* 56 57 58 59 60 61 62 63 */
+ 83, 84, 85, 209, 210, 211, 212, 325,
+ /* 64 65 66 */ /* 64+: int2 */
+ 326, 390, 391,
+};
+static const unsigned long unused_irq_v1[] = {0x00a00000, 0x00020000,
+ 0xfffffff8};
+
+static const unsigned int intsteer_map_v2[] = {
+ /* 0 1 2 3 4 5 6 7 */ /* 0~31: int0 */
+ 448, 449, 450, 64, 65, 66, 67, 68,
+ /* 8 9 10 11 12 13 14 15 */
+ 69, 70, 193, 194, 195, 196, 197, 72,
+ /* 16 17 18 19 20 21 22 23 */
+ 73, 74, 75, 76, 77, 78, 79, 80,
+ /* 24 25 26 27 28 29 30 31 */
+ 81, 199, 200, 201, 202, 203, 204, 205,
+ /* 32 33 34 35 36 37 38 39 */ /* 32+: int1 */
+ 206, 207, 208, NA, 0, 1, 2, 3,
+ /* 40 41 42 43 44 45 46 47 */
+ 4, 82, 83, 84, 85, 209, 210, 211,
+ /* 48 */
+ 212,
+};
+static const unsigned long unused_irq_v2[] = {0x00000000, 0xfffe0008};
+
+static const unsigned int sw2hw_irq_map_v2[] = {
+ /* 0 1 2 3 4 5 6 7 */
+ 0, 1, 2, 3, 4, 5, 6, 7,
+ /* 8 9 10 11 12 13 14 15 */
+ 8, 9, 10, 11, 12, 13, 14, NA,
+ /* 16 17 18 19 20 21 22 23 */
+ NA, NA, NA, NA, NA, NA, NA, NA,
+ /* 24 25 26 27 28 29 30 31 */
+ NA, NA, NA, 15, 16, 17, 18, 19,
+ /* 32 33 34 35 36 37 38 39 */
+ 20, 21, 22, 23, 24, 25, 26, 27,
+ /* 40 41 42 43 44 45 46 47 */
+ 28, 29, 30, 31, 32, 33, 34, NA,
+ /* 48 49 50 51 52 53 54 55 */
+ NA, NA, 36, 37, 38, 39, 40, 41,
+ /* 56 57 58 59 60 61 62 63 */
+ 42, 43, 44, 45, 46, 47, 48, NA,
+ /* 64 65 66 */
+ NA, NA, NA,
+};
+
+/* FIXME: overkill for some N/As, revive them when needed */
+static const unsigned int sw2hw_block_id_map_v2[] = {
+ /* 0 1 2 3 4 5 6 7 */
+ 0x00, NA, NA, 0x03, NA, NA, NA, 0x07,
+ /* 8 9 10 11 12 13 14 15 */
+ 0x08, NA, 0x0a, NA, 0x0c, NA, 0x0e, NA,
+ /* 16 17 18 19 20 21 22 23 */
+ 0x10, NA, 0x12, NA, NA, NA, NA, NA,
+ /* 24 25 26 27 28 29 30 31 */
+ NA, NA, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19,
+ /* 32 33 34 35 36 37 38 39 */
+ 0x1a, NA, NA, 0x1b, 0x1c, 0x1d, NA, NA,
+ /* 40 41 42 43 44 45 46 47 */
+ 0x1e, 0x1f, 0x20, NA, 0x21, 0x22, 0x23, 0x24,
+ /* 48 49 50 51 52 53 54 55 */
+ NA, NA, NA, NA, NA, NA, NA, NA,
+ /* 56 57 58 59 60 61 62 63 */
+ NA, NA, NA, NA, NA, NA, NA, NA,
+ /* 64 65 66 67 */
+ NA, NA, NA, NA,
+};
+
+static const struct dpu_devtype dpu_type_v1 = {
+ .cm_ofs = 0x0,
+ .cfs = &cfs_v1,
+ .decs = &decs_v1,
+ .eds = &eds_v1,
+ .fds = &fds_v1,
+ .fes = &fes_v1,
+ .fgs = &fgs_v1,
+ .fls = &fls_v1,
+ .fws = &fws_v1,
+ .hss = &hss_v1,
+ .lbs = &lbs_v1,
+ .sts = &sts_v1,
+ .tcons = &tcons_v1,
+ .vss = &vss_v1,
+ .cm_reg_ofs = &cm_reg_ofs_v1,
+ .intsteer_map = intsteer_map_v1,
+ .intsteer_map_size = ARRAY_SIZE(intsteer_map_v1),
+ .unused_irq = unused_irq_v1,
+ .plane_src_na_mask = 0xffffff80,
+ .has_capture = true,
+ .has_prefetch = false,
+ .has_disp_sel_clk = false,
+ .has_dual_ldb = false,
+ .has_pc = false,
+ .has_syncmode_fixup = false,
+ .pixel_link_quirks = false,
+ .pixel_link_nhvsync = false,
+ .version = DPU_V1,
+};
+
+static const struct dpu_devtype dpu_type_v2_qm = {
+ .cm_ofs = 0x0,
+ .cfs = &cfs_v2,
+ .decs = &decs_v2,
+ .eds = &eds_v2,
+ .fds = &fds_v2,
+ .fes = &fes_v2,
+ .fgs = &fgs_v2,
+ .fls = &fls_v2,
+ .fws = &fws_v2,
+ .hss = &hss_v2,
+ .lbs = &lbs_v2,
+ .sts = &sts_v2,
+ .tcons = &tcons_v2,
+ .vss = &vss_v2,
+ .cm_reg_ofs = &cm_reg_ofs_v2,
+ .intsteer_map = intsteer_map_v2,
+ .intsteer_map_size = ARRAY_SIZE(intsteer_map_v2),
+ .unused_irq = unused_irq_v2,
+ .sw2hw_irq_map = sw2hw_irq_map_v2,
+ .sw2hw_block_id_map = sw2hw_block_id_map_v2,
+ .plane_src_na_mask = 0xffffffe2,
+ .has_capture = false,
+ .has_prefetch = true,
+ .has_disp_sel_clk = true,
+ .has_dual_ldb = false,
+ .has_pc = true,
+ .has_syncmode_fixup = true,
+ .syncmode_min_prate = 300000,
+ .singlemode_max_width = 1920,
+ .master_stream_id = 1,
+ .pixel_link_quirks = true,
+ .pixel_link_nhvsync = true,
+ .version = DPU_V2,
+};
+
+static const struct dpu_devtype dpu_type_v2_qxp = {
+ .cm_ofs = 0x0,
+ .cfs = &cfs_v2,
+ .decs = &decs_v2,
+ .eds = &eds_v2,
+ .fds = &fds_v2,
+ .fes = &fes_v2,
+ .fgs = &fgs_v2,
+ .fls = &fls_v2,
+ .fws = &fws_v2,
+ .hss = &hss_v2,
+ .lbs = &lbs_v2,
+ .sts = &sts_v2,
+ .tcons = &tcons_v2,
+ .vss = &vss_v2,
+ .cm_reg_ofs = &cm_reg_ofs_v2,
+ .intsteer_map = intsteer_map_v2,
+ .intsteer_map_size = ARRAY_SIZE(intsteer_map_v2),
+ .unused_irq = unused_irq_v2,
+ .sw2hw_irq_map = sw2hw_irq_map_v2,
+ .sw2hw_block_id_map = sw2hw_block_id_map_v2,
+ .plane_src_na_mask = 0xffffffe2,
+ .has_capture = false,
+ .has_prefetch = true,
+ .has_disp_sel_clk = false,
+ .has_dual_ldb = true,
+ .has_pc = true,
+ .has_syncmode_fixup = false,
+ .syncmode_min_prate = UINT_MAX, /* pc is unused */
+ .singlemode_max_width = UINT_MAX, /* pc is unused */
+ .pixel_link_quirks = true,
+ .pixel_link_nhvsync = true,
+ .version = DPU_V2,
+};
+
+static const struct of_device_id dpu_dt_ids[] = {
+ {
+ .compatible = "fsl,imx8qm-dpu",
+ .data = &dpu_type_v2_qm,
+ }, {
+ .compatible = "fsl,imx8qxp-dpu",
+ .data = &dpu_type_v2_qxp,
+ }, {
+ /* sentinel */
+ }
+};
+MODULE_DEVICE_TABLE(of, dpu_dt_ids);
+
+bool dpu_has_pc(struct dpu_soc *dpu)
+{
+ return dpu->devtype->has_pc;
+}
+EXPORT_SYMBOL_GPL(dpu_has_pc);
+
+unsigned int dpu_get_syncmode_min_prate(struct dpu_soc *dpu)
+{
+ if (dpu->devtype->has_pc)
+ return dpu->devtype->syncmode_min_prate;
+ else
+ return UINT_MAX;
+}
+EXPORT_SYMBOL_GPL(dpu_get_syncmode_min_prate);
+
+unsigned int dpu_get_singlemode_max_width(struct dpu_soc *dpu)
+{
+ if (dpu->devtype->has_pc)
+ return dpu->devtype->singlemode_max_width;
+ else
+ return UINT_MAX;
+}
+EXPORT_SYMBOL_GPL(dpu_get_singlemode_max_width);
+
+unsigned int dpu_get_master_stream_id(struct dpu_soc *dpu)
+{
+ if (dpu->devtype->has_pc)
+ return dpu->devtype->master_stream_id;
+ else
+ return UINT_MAX;
+}
+EXPORT_SYMBOL_GPL(dpu_get_master_stream_id);
+
+bool dpu_vproc_has_fetcheco_cap(u32 cap_mask)
+{
+ return !!(cap_mask & DPU_VPROC_CAP_FETCHECO);
+}
+EXPORT_SYMBOL_GPL(dpu_vproc_has_fetcheco_cap);
+
+bool dpu_vproc_has_hscale_cap(u32 cap_mask)
+{
+ return !!(cap_mask & DPU_VPROC_CAP_HSCALE);
+}
+EXPORT_SYMBOL_GPL(dpu_vproc_has_hscale_cap);
+
+bool dpu_vproc_has_vscale_cap(u32 cap_mask)
+{
+ return !!(cap_mask & DPU_VPROC_CAP_VSCALE);
+}
+EXPORT_SYMBOL_GPL(dpu_vproc_has_vscale_cap);
+
+u32 dpu_vproc_get_fetcheco_cap(u32 cap_mask)
+{
+ return cap_mask & DPU_VPROC_CAP_FETCHECO;
+}
+EXPORT_SYMBOL_GPL(dpu_vproc_get_fetcheco_cap);
+
+u32 dpu_vproc_get_hscale_cap(u32 cap_mask)
+{
+ return cap_mask & DPU_VPROC_CAP_HSCALE;
+}
+EXPORT_SYMBOL_GPL(dpu_vproc_get_hscale_cap);
+
+u32 dpu_vproc_get_vscale_cap(u32 cap_mask)
+{
+ return cap_mask & DPU_VPROC_CAP_VSCALE;
+}
+EXPORT_SYMBOL_GPL(dpu_vproc_get_vscale_cap);
+
+int dpu_format_horz_chroma_subsampling(u32 format)
+{
+ switch (format) {
+ case DRM_FORMAT_YUYV:
+ case DRM_FORMAT_UYVY:
+ case DRM_FORMAT_NV12:
+ case DRM_FORMAT_NV21:
+ case DRM_FORMAT_NV16:
+ case DRM_FORMAT_NV61:
+ return 2;
+ default:
+ return 1;
+ }
+}
+
+int dpu_format_vert_chroma_subsampling(u32 format)
+{
+ switch (format) {
+ case DRM_FORMAT_NV12:
+ case DRM_FORMAT_NV21:
+ return 2;
+ default:
+ return 1;
+ }
+}
+
+int dpu_format_num_planes(u32 format)
+{
+ switch (format) {
+ case DRM_FORMAT_NV12:
+ case DRM_FORMAT_NV21:
+ case DRM_FORMAT_NV16:
+ case DRM_FORMAT_NV61:
+ case DRM_FORMAT_NV24:
+ case DRM_FORMAT_NV42:
+ return 2;
+ default:
+ return 1;
+ }
+}
+
+int dpu_format_plane_width(int width, u32 format, int plane)
+{
+ if (plane >= dpu_format_num_planes(format))
+ return 0;
+
+ if (plane == 0)
+ return width;
+
+ return width / dpu_format_horz_chroma_subsampling(format);
+}
+
+int dpu_format_plane_height(int height, u32 format, int plane)
+{
+ if (plane >= dpu_format_num_planes(format))
+ return 0;
+
+ if (plane == 0)
+ return height;
+
+ return height / dpu_format_vert_chroma_subsampling(format);
+}
+
+#define _DPU_UNITS_INIT(unit) \
+{ \
+ const struct dpu_unit *us = devtype->unit##s; \
+ int i; \
+ \
+ /* software check */ \
+ if (WARN_ON(us->num > ARRAY_SIZE(unit##_ids))) \
+ return -EINVAL; \
+ \
+ for (i = 0; i < us->num; i++) \
+ _dpu_##unit##_init(dpu, us->ids[i]); \
+}
+
+static int
+_dpu_submodules_init(struct dpu_soc *dpu, struct platform_device *pdev)
+{
+ const struct dpu_devtype *devtype = dpu->devtype;
+
+ _DPU_UNITS_INIT(cf);
+ _DPU_UNITS_INIT(dec);
+ _DPU_UNITS_INIT(ed);
+ _DPU_UNITS_INIT(fd);
+ _DPU_UNITS_INIT(fe);
+ _DPU_UNITS_INIT(fg);
+ _DPU_UNITS_INIT(fl);
+ _DPU_UNITS_INIT(fw);
+ _DPU_UNITS_INIT(hs);
+ _DPU_UNITS_INIT(lb);
+ _DPU_UNITS_INIT(tcon);
+ _DPU_UNITS_INIT(vs);
+
+ return 0;
+}
+
+#define DPU_UNIT_INIT(dpu, base, unit, name, id, pec_ofs, ofs) \
+{ \
+ int ret; \
+ ret = dpu_##unit##_init((dpu), (id), \
+ (pec_ofs) ? (base) + (pec_ofs) : 0, \
+ (base) + (ofs)); \
+ if (ret) { \
+ dev_err((dpu)->dev, "init %s%d failed with %d\n", \
+ (name), (id), ret); \
+ return ret; \
+ } \
+}
+
+#define DPU_UNITS_INIT(unit) \
+{ \
+ const struct dpu_unit *us = devtype->unit##s; \
+ int i; \
+ \
+ /* software check */ \
+ if (WARN_ON(us->num > ARRAY_SIZE(unit##_ids))) \
+ return -EINVAL; \
+ \
+ for (i = 0; i < us->num; i++) \
+ DPU_UNIT_INIT(dpu, dpu_base, unit, us->name, \
+ us->ids[i], \
+ us->pec_ofss ? us->pec_ofss[i] : 0, \
+ us->ofss[i]); \
+}
+
+static int dpu_submodules_init(struct dpu_soc *dpu,
+ struct platform_device *pdev, unsigned long dpu_base)
+{
+ const struct dpu_devtype *devtype = dpu->devtype;
+ const struct dpu_unit *fds = devtype->fds;
+ const struct dpu_unit *fls = devtype->fls;
+ const struct dpu_unit *fws = devtype->fws;
+ const struct dpu_unit *tcons = devtype->tcons;
+
+ DPU_UNITS_INIT(cf);
+ DPU_UNITS_INIT(dec);
+ DPU_UNITS_INIT(ed);
+ DPU_UNITS_INIT(fd);
+ DPU_UNITS_INIT(fe);
+ DPU_UNITS_INIT(fg);
+ DPU_UNITS_INIT(fl);
+ DPU_UNITS_INIT(fw);
+ DPU_UNITS_INIT(hs);
+ DPU_UNITS_INIT(lb);
+ DPU_UNITS_INIT(st);
+ DPU_UNITS_INIT(tcon);
+ DPU_UNITS_INIT(vs);
+
+ /* get DPR channel for submodules */
+ if (devtype->has_prefetch) {
+ struct dpu_fetchunit *fu;
+ struct dprc *dprc;
+ int i;
+
+ for (i = 0; i < fds->num; i++) {
+ dprc = dprc_lookup_by_phandle(dpu->dev,
+ "fsl,dpr-channels",
+ fds->dprc_ids[i]);
+ if (!dprc)
+ return -EPROBE_DEFER;
+
+ fu = dpu_fd_get(dpu, i);
+ fetchunit_get_dprc(fu, dprc);
+ dpu_fd_put(fu);
+ }
+
+ for (i = 0; i < fls->num; i++) {
+ dprc = dprc_lookup_by_phandle(dpu->dev,
+ "fsl,dpr-channels",
+ fls->dprc_ids[i]);
+ if (!dprc)
+ return -EPROBE_DEFER;
+
+ fu = dpu_fl_get(dpu, i);
+ fetchunit_get_dprc(fu, dprc);
+ dpu_fl_put(fu);
+ }
+
+ for (i = 0; i < fws->num; i++) {
+ dprc = dprc_lookup_by_phandle(dpu->dev,
+ "fsl,dpr-channels",
+ fws->dprc_ids[i]);
+ if (!dprc)
+ return -EPROBE_DEFER;
+
+ fu = dpu_fw_get(dpu, fw_ids[i]);
+ fetchunit_get_dprc(fu, dprc);
+ dpu_fw_put(fu);
+ }
+ }
+
+ /* get pixel combiner */
+ if (devtype->has_pc) {
+ struct dpu_tcon *tcon;
+ struct pc *pc =
+ pc_lookup_by_phandle(dpu->dev, "fsl,pixel-combiner");
+ int i;
+
+ if (!pc)
+ return -EPROBE_DEFER;
+
+ for (i = 0; i < tcons->num; i++) {
+ tcon = dpu_tcon_get(dpu, i);
+ tcon_get_pc(tcon, pc);
+ dpu_tcon_put(tcon);
+ }
+ }
+
+ return 0;
+}
+
+#define DPU_UNITS_ADDR_DBG(unit) \
+{ \
+ const struct dpu_unit *us = devtype->unit##s; \
+ int i; \
+ for (i = 0; i < us->num; i++) { \
+ if (us->pec_ofss) { \
+ dev_dbg(&pdev->dev, "%s%d: pixengcfg @ 0x%08lx,"\
+ " unit @ 0x%08lx\n", us->name, \
+ us->ids[i], \
+ dpu_base + us->pec_ofss[i], \
+ dpu_base + us->ofss[i]); \
+ } else { \
+ dev_dbg(&pdev->dev, \
+ "%s%d: unit @ 0x%08lx\n", us->name, \
+ us->ids[i], dpu_base + us->ofss[i]); \
+ } \
+ } \
+}
+
+enum dpu_irq_line {
+ DPU_IRQ_LINE_CM = 0,
+ DPU_IRQ_LINE_STREAM0A = 1,
+ DPU_IRQ_LINE_STREAM1A = 3,
+ DPU_IRQ_LINE_RESERVED0 = 5,
+ DPU_IRQ_LINE_RESERVED1 = 6,
+ DPU_IRQ_LINE_BLIT = 7,
+};
+
+static inline unsigned int dpu_get_max_intsteer_num(enum dpu_irq_line irq_line)
+{
+ return 64 * (++irq_line) - 1;
+}
+
+static inline unsigned int dpu_get_min_intsteer_num(enum dpu_irq_line irq_line)
+{
+ return 64 * irq_line;
+}
+
+static void
+dpu_inner_irq_handle(struct irq_desc *desc, enum dpu_irq_line irq_line)
+{
+ struct dpu_soc *dpu = irq_desc_get_handler_data(desc);
+ const struct dpu_devtype *devtype = dpu->devtype;
+ const struct cm_reg_ofs *ofs = devtype->cm_reg_ofs;
+ struct irq_chip *chip = irq_desc_get_chip(desc);
+ unsigned int i, virq, min_intsteer_num, max_intsteer_num;
+ u32 status;
+
+ chained_irq_enter(chip, desc);
+
+ min_intsteer_num = dpu_get_min_intsteer_num(irq_line);
+ max_intsteer_num = dpu_get_max_intsteer_num(irq_line);
+
+ for (i = 0; i < devtype->intsteer_map_size; i++) {
+ if (devtype->intsteer_map[i] >= min_intsteer_num &&
+ devtype->intsteer_map[i] <= max_intsteer_num) {
+ status = dpu_cm_read(dpu,
+ USERINTERRUPTSTATUS(ofs, i / 32));
+ status &= dpu_cm_read(dpu,
+ USERINTERRUPTENABLE(ofs, i / 32));
+
+ if (status & BIT(i % 32)) {
+ virq = irq_linear_revmap(dpu->domain, i);
+ if (virq) {
+ generic_handle_irq(virq);
+ }
+ }
+ }
+ }
+
+ chained_irq_exit(chip, desc);
+}
+
+#define DPU_INNER_IRQ_HANDLER_DEFINE(name1, name2) \
+static void dpu_##name1##_irq_handler(struct irq_desc *desc) \
+{ \
+ dpu_inner_irq_handle(desc, DPU_IRQ_LINE_##name2); \
+}
+
+DPU_INNER_IRQ_HANDLER_DEFINE(cm, CM)
+DPU_INNER_IRQ_HANDLER_DEFINE(stream0a, STREAM0A)
+DPU_INNER_IRQ_HANDLER_DEFINE(stream1a, STREAM1A)
+DPU_INNER_IRQ_HANDLER_DEFINE(reserved0, RESERVED0)
+DPU_INNER_IRQ_HANDLER_DEFINE(reserved1, RESERVED1)
+DPU_INNER_IRQ_HANDLER_DEFINE(blit, BLIT)
+
+int dpu_map_inner_irq(struct dpu_soc *dpu, int irq)
+{
+ const unsigned int *sw2hw_irq_map = dpu->devtype->sw2hw_irq_map;
+ int virq, mapped_irq;
+
+ mapped_irq = sw2hw_irq_map ? sw2hw_irq_map[irq] : irq;
+ if (WARN_ON(mapped_irq == NA))
+ return -EINVAL;
+
+ virq = irq_linear_revmap(dpu->domain, mapped_irq);
+ if (!virq)
+ virq = irq_create_mapping(dpu->domain, mapped_irq);
+
+ return virq;
+}
+EXPORT_SYMBOL_GPL(dpu_map_inner_irq);
+
+static int platform_remove_devices_fn(struct device *dev, void *unused)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+
+ platform_device_unregister(pdev);
+
+ return 0;
+}
+
+static void platform_device_unregister_children(struct platform_device *pdev)
+{
+ device_for_each_child(&pdev->dev, NULL, platform_remove_devices_fn);
+}
+
+struct dpu_platform_reg {
+ struct dpu_client_platformdata pdata;
+ const char *name;
+};
+
+static struct dpu_platform_reg client_reg[] = {
+ {
+ /* placeholder */
+ .pdata = { },
+ .name = "imx-dpu-csi",
+ }, {
+ /* placeholder */
+ .pdata = { },
+ .name = "imx-dpu-csi",
+ }, {
+ .pdata = {
+ .stream_id = 0,
+ },
+ .name = "imx-dpu-crtc",
+ }, {
+ .pdata = {
+ .stream_id = 1,
+ },
+ .name = "imx-dpu-crtc",
+ }, {
+ .pdata = { },
+ .name = "imx-drm-dpu-bliteng",
+ },
+};
+
+static DEFINE_MUTEX(dpu_client_id_mutex);
+static int dpu_client_id;
+
+static int dpu_get_plane_resource(struct dpu_soc *dpu,
+ struct dpu_plane_res *res)
+{
+ const struct dpu_unit *fds = dpu->devtype->fds;
+ const struct dpu_unit *fls = dpu->devtype->fls;
+ const struct dpu_unit *fws = dpu->devtype->fws;
+ const struct dpu_unit *lbs = dpu->devtype->lbs;
+ struct dpu_plane_grp *grp = plane_res_to_grp(res);
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(res->cf); i++) {
+ res->cf[i] = dpu_cf_get(dpu, i);
+ if (IS_ERR(res->cf[i]))
+ return PTR_ERR(res->cf[i]);
+ }
+ for (i = 0; i < ARRAY_SIZE(res->ed); i++) {
+ res->ed[i] = dpu_ed_get(dpu, i);
+ if (IS_ERR(res->ed[i]))
+ return PTR_ERR(res->ed[i]);
+ }
+ for (i = 0; i < fds->num; i++) {
+ res->fd[i] = dpu_fd_get(dpu, i);
+ if (IS_ERR(res->fd[i]))
+ return PTR_ERR(res->fd[i]);
+ }
+ for (i = 0; i < ARRAY_SIZE(res->fe); i++) {
+ res->fe[i] = dpu_fe_get(dpu, i);
+ if (IS_ERR(res->fe[i]))
+ return PTR_ERR(res->fe[i]);
+ grp->hw_plane_fetcheco_num = ARRAY_SIZE(res->fe);
+ }
+ for (i = 0; i < fls->num; i++) {
+ res->fl[i] = dpu_fl_get(dpu, i);
+ if (IS_ERR(res->fl[i]))
+ return PTR_ERR(res->fl[i]);
+ }
+ for (i = 0; i < fws->num; i++) {
+ res->fw[i] = dpu_fw_get(dpu, fw_ids[i]);
+ if (IS_ERR(res->fw[i]))
+ return PTR_ERR(res->fw[i]);
+ }
+ /* HScaler could be shared with capture. */
+ if (display_plane_video_proc) {
+ for (i = 0; i < ARRAY_SIZE(res->hs); i++) {
+ res->hs[i] = dpu_hs_get(dpu, hs_ids[i]);
+ if (IS_ERR(res->hs[i]))
+ return PTR_ERR(res->hs[i]);
+ }
+ grp->hw_plane_hscaler_num = ARRAY_SIZE(res->hs);
+ }
+ for (i = 0; i < lbs->num; i++) {
+ res->lb[i] = dpu_lb_get(dpu, i);
+ if (IS_ERR(res->lb[i]))
+ return PTR_ERR(res->lb[i]);
+ }
+ /* VScaler could be shared with capture. */
+ if (display_plane_video_proc) {
+ for (i = 0; i < ARRAY_SIZE(res->vs); i++) {
+ res->vs[i] = dpu_vs_get(dpu, vs_ids[i]);
+ if (IS_ERR(res->vs[i]))
+ return PTR_ERR(res->vs[i]);
+ }
+ grp->hw_plane_vscaler_num = ARRAY_SIZE(res->vs);
+ }
+
+ grp->hw_plane_num = fds->num + fls->num + fws->num;
+
+ return 0;
+}
+
+static void dpu_put_plane_resource(struct dpu_plane_res *res)
+{
+ struct dpu_plane_grp *grp = plane_res_to_grp(res);
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(res->cf); i++) {
+ if (!IS_ERR_OR_NULL(res->cf[i]))
+ dpu_cf_put(res->cf[i]);
+ }
+ for (i = 0; i < ARRAY_SIZE(res->ed); i++) {
+ if (!IS_ERR_OR_NULL(res->ed[i]))
+ dpu_ed_put(res->ed[i]);
+ }
+ for (i = 0; i < ARRAY_SIZE(res->fd); i++) {
+ if (!IS_ERR_OR_NULL(res->fd[i]))
+ dpu_fd_put(res->fd[i]);
+ }
+ for (i = 0; i < ARRAY_SIZE(res->fe); i++) {
+ if (!IS_ERR_OR_NULL(res->fe[i]))
+ dpu_fe_put(res->fe[i]);
+ }
+ for (i = 0; i < ARRAY_SIZE(res->fl); i++) {
+ if (!IS_ERR_OR_NULL(res->fl[i]))
+ dpu_fl_put(res->fl[i]);
+ }
+ for (i = 0; i < ARRAY_SIZE(res->fw); i++) {
+ if (!IS_ERR_OR_NULL(res->fw[i]))
+ dpu_fw_put(res->fw[i]);
+ }
+ for (i = 0; i < ARRAY_SIZE(res->hs); i++) {
+ if (!IS_ERR_OR_NULL(res->hs[i]))
+ dpu_hs_put(res->hs[i]);
+ }
+ for (i = 0; i < ARRAY_SIZE(res->lb); i++) {
+ if (!IS_ERR_OR_NULL(res->lb[i]))
+ dpu_lb_put(res->lb[i]);
+ }
+ for (i = 0; i < ARRAY_SIZE(res->vs); i++) {
+ if (!IS_ERR_OR_NULL(res->vs[i]))
+ dpu_vs_put(res->vs[i]);
+ }
+
+ grp->hw_plane_num = 0;
+}
+
+static int dpu_add_client_devices(struct dpu_soc *dpu)
+{
+ const struct dpu_devtype *devtype = dpu->devtype;
+ struct device *dev = dpu->dev;
+ struct dpu_platform_reg *reg;
+ struct dpu_plane_grp *plane_grp;
+ struct dpu_store *st9 = NULL;
+ size_t client_num, reg_size;
+ int i, id, ret;
+
+ client_num = ARRAY_SIZE(client_reg);
+ if (!devtype->has_capture)
+ client_num -= 2;
+
+ reg = devm_kcalloc(dev, client_num, sizeof(*reg), GFP_KERNEL);
+ if (!reg)
+ return -ENODEV;
+
+ plane_grp = devm_kzalloc(dev, sizeof(*plane_grp), GFP_KERNEL);
+ if (!plane_grp)
+ return -ENODEV;
+
+ mutex_init(&plane_grp->mutex);
+
+ mutex_lock(&dpu_client_id_mutex);
+ id = dpu_client_id;
+ dpu_client_id += client_num;
+ mutex_unlock(&dpu_client_id_mutex);
+
+ reg_size = client_num * sizeof(struct dpu_platform_reg);
+ if (devtype->has_capture)
+ memcpy(reg, client_reg, reg_size);
+ else
+ memcpy(reg, &client_reg[2], reg_size);
+
+ plane_grp->src_na_mask = devtype->plane_src_na_mask;
+ plane_grp->id = id / client_num;
+ plane_grp->has_vproc = display_plane_video_proc;
+
+ ret = dpu_get_plane_resource(dpu, &plane_grp->res);
+ if (ret)
+ goto err_get_plane_res;
+
+ /*
+ * Store9 is shared bewteen display engine(for sync mode
+ * fixup) and blit engine.
+ */
+ if (devtype->has_syncmode_fixup) {
+ st9 = dpu_st_get(dpu, 9);
+ if (IS_ERR(st9)) {
+ ret = PTR_ERR(st9);
+ goto err_get_plane_res;
+ }
+ }
+
+ for (i = 0; i < client_num; i++) {
+ struct platform_device *pdev;
+ struct device_node *of_node = NULL;
+ bool is_disp, is_bliteng;
+
+ if (devtype->has_capture) {
+ is_bliteng = (i == 4) ? true : false;
+ is_disp = (!is_bliteng) && ((i / 2) ? true : false);
+ } else {
+ is_bliteng = (i == 2) ? true : false;
+ is_disp = !is_bliteng;
+ }
+
+ if (is_bliteng) {
+ /* As bliteng has no of_node, so to use dpu's. */
+ of_node = dev->of_node;
+ } else {
+ /*
+ * Associate subdevice with the
+ * corresponding port node.
+ */
+ of_node = of_graph_get_port_by_id(dev->of_node, i);
+ if (!of_node) {
+ dev_info(dev, "no port@%d node in %s, not using %s%d\n",
+ i, dev->of_node->full_name,
+ is_disp ? "DISP" : "CSI", i % 2);
+ continue;
+ }
+ }
+
+ if (is_disp) {
+ reg[i].pdata.plane_grp = plane_grp;
+ reg[i].pdata.di_grp_id = plane_grp->id;
+ reg[i].pdata.st9 = st9;
+ }
+
+ pdev = platform_device_alloc(reg[i].name, id++);
+ if (!pdev) {
+ ret = -ENOMEM;
+ goto err_register;
+ }
+
+ pdev->dev.parent = dev;
+
+ reg[i].pdata.of_node = of_node;
+ ret = platform_device_add_data(pdev, &reg[i].pdata,
+ sizeof(reg[i].pdata));
+ if (!ret)
+ ret = platform_device_add(pdev);
+ if (ret) {
+ platform_device_put(pdev);
+ goto err_register;
+ }
+ }
+
+ return 0;
+
+err_register:
+ platform_device_unregister_children(to_platform_device(dev));
+ if (devtype->has_syncmode_fixup)
+ dpu_st_put(st9);
+err_get_plane_res:
+ dpu_put_plane_resource(&plane_grp->res);
+
+ return ret;
+}
+
+#define IRQSTEER_CHANnCTL 0x0
+#define IRQSTEER_CHANnCTL_CH(n) BIT(n)
+#define IRQSTEER_CHANnMASK(n) ((n) + 4)
+#define LINE_TO_MASK_OFFSET(n) ((15 - ((n) / 32)) * 4)
+#define LINE_TO_MASK_SHIFT(n) ((n) % 32)
+
+static void dpu_inner_irq_gc_mask_set_bit(struct irq_data *d)
+{
+ struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
+ struct irq_chip_type *ct = irq_data_get_chip_type(d);
+ struct dpu_soc *dpu = gc->domain->host_data;
+ unsigned long flags;
+ u32 mask = d->mask;
+
+ irq_gc_lock(gc);
+ spin_lock_irqsave(&dpu->intsteer_lock, flags);
+ if (++dpu->intsteer_usecount == 1)
+ /* assuming fast I/O regmap */
+ regmap_write(dpu->intsteer_regmap, IRQSTEER_CHANnCTL,
+ IRQSTEER_CHANnCTL_CH(0));
+ spin_unlock_irqrestore(&dpu->intsteer_lock, flags);
+ *ct->mask_cache |= mask;
+ irq_reg_writel(gc, *ct->mask_cache, ct->regs.mask);
+ irq_gc_unlock(gc);
+}
+
+static void dpu_inner_irq_gc_mask_clr_bit(struct irq_data *d)
+{
+ struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
+ struct irq_chip_type *ct = irq_data_get_chip_type(d);
+ struct dpu_soc *dpu = gc->domain->host_data;
+ unsigned long flags;
+ u32 mask = d->mask;
+
+ irq_gc_lock(gc);
+ spin_lock_irqsave(&dpu->intsteer_lock, flags);
+ if (!--dpu->intsteer_usecount) {
+ WARN(dpu->intsteer_usecount < 0,
+ "intsteer usecount %d is less than zero",
+ dpu->intsteer_usecount);
+ regmap_write(dpu->intsteer_regmap, IRQSTEER_CHANnCTL, 0);
+ }
+ spin_unlock_irqrestore(&dpu->intsteer_lock, flags);
+ *ct->mask_cache &= ~mask;
+ irq_reg_writel(gc, *ct->mask_cache, ct->regs.mask);
+ irq_gc_unlock(gc);
+}
+
+static void
+dpu_inner_intsteer_enable_line(struct dpu_soc *dpu, unsigned int line)
+{
+ unsigned int offset = LINE_TO_MASK_OFFSET(line);
+ unsigned int shift = LINE_TO_MASK_SHIFT(line);
+
+ regmap_update_bits(dpu->intsteer_regmap, IRQSTEER_CHANnMASK(offset),
+ BIT(shift), BIT(shift));
+}
+
+static void dpu_inner_intsteer_enable_lines(struct dpu_soc *dpu)
+{
+ const struct dpu_devtype *devtype = dpu->devtype;
+ int i;
+
+ for (i = 0; i < devtype->intsteer_map_size; i++) {
+ if (devtype->intsteer_map[i] == NA)
+ continue;
+
+ dpu_inner_intsteer_enable_line(dpu, devtype->intsteer_map[i]);
+ }
+}
+
+static int dpu_inner_irq_init(struct dpu_soc *dpu)
+{
+ const struct dpu_devtype *devtype = dpu->devtype;
+ const struct cm_reg_ofs *ofs = devtype->cm_reg_ofs;
+ struct irq_chip_generic *gc;
+ struct irq_chip_type *ct;
+ int ret, i;
+
+ dpu_inner_intsteer_enable_lines(dpu);
+
+ dpu->domain = irq_domain_add_linear(dpu->dev->of_node,
+ devtype->intsteer_map_size,
+ &irq_generic_chip_ops, dpu);
+ if (!dpu->domain) {
+ dev_err(dpu->dev, "failed to add irq domain\n");
+ return -ENODEV;
+ }
+
+ ret = irq_alloc_domain_generic_chips(dpu->domain, 32, 1, "DPU",
+ handle_level_irq, 0, 0, 0);
+ if (ret < 0) {
+ dev_err(dpu->dev, "failed to alloc generic irq chips\n");
+ irq_domain_remove(dpu->domain);
+ return ret;
+ }
+
+ for (i = 0; i < devtype->intsteer_map_size; i += 32) {
+ /* Mask and clear all interrupts */
+ dpu_cm_write(dpu, 0,
+ USERINTERRUPTENABLE(ofs, i / 32));
+ dpu_cm_write(dpu, ~devtype->unused_irq[i / 32],
+ USERINTERRUPTCLEAR(ofs, i / 32));
+ dpu_cm_write(dpu, 0,
+ INTERRUPTENABLE(ofs, i / 32));
+ dpu_cm_write(dpu, ~devtype->unused_irq[i / 32],
+ INTERRUPTCLEAR(ofs, i / 32));
+
+ /* Set all interrupts to user mode */
+ dpu_cm_write(dpu, ~devtype->unused_irq[i / 32],
+ USERINTERRUPTMASK(ofs, i / 32));
+
+ gc = irq_get_domain_generic_chip(dpu->domain, i);
+ gc->reg_base = dpu->cm_reg;
+ gc->unused = devtype->unused_irq[i / 32];
+ ct = gc->chip_types;
+ ct->chip.irq_ack = irq_gc_ack_set_bit;
+ ct->chip.irq_mask = dpu_inner_irq_gc_mask_clr_bit;
+ ct->chip.irq_unmask = dpu_inner_irq_gc_mask_set_bit;
+ ct->regs.ack = USERINTERRUPTCLEAR(ofs, i / 32);
+ ct->regs.mask = USERINTERRUPTENABLE(ofs, i / 32);
+ }
+
+#define DPU_INNER_IRQ_SET_CHAINED_HANDLER_AND_DATA1(name) \
+irq_set_chained_handler_and_data(dpu->irq_##name, dpu_##name##_irq_handler, dpu)
+
+ DPU_INNER_IRQ_SET_CHAINED_HANDLER_AND_DATA1(cm);
+ DPU_INNER_IRQ_SET_CHAINED_HANDLER_AND_DATA1(stream0a);
+ DPU_INNER_IRQ_SET_CHAINED_HANDLER_AND_DATA1(stream1a);
+ DPU_INNER_IRQ_SET_CHAINED_HANDLER_AND_DATA1(reserved0);
+ DPU_INNER_IRQ_SET_CHAINED_HANDLER_AND_DATA1(reserved1);
+ DPU_INNER_IRQ_SET_CHAINED_HANDLER_AND_DATA1(blit);
+
+ return 0;
+}
+
+static void dpu_inner_irq_exit(struct dpu_soc *dpu)
+{
+ const struct dpu_devtype *devtype = dpu->devtype;
+ unsigned int i, irq;
+
+#define DPU_INNER_IRQ_SET_CHAINED_HANDLER_AND_DATA2(name) \
+irq_set_chained_handler_and_data(dpu->irq_##name, NULL, NULL)
+
+ DPU_INNER_IRQ_SET_CHAINED_HANDLER_AND_DATA2(cm);
+ DPU_INNER_IRQ_SET_CHAINED_HANDLER_AND_DATA2(stream0a);
+ DPU_INNER_IRQ_SET_CHAINED_HANDLER_AND_DATA2(stream1a);
+ DPU_INNER_IRQ_SET_CHAINED_HANDLER_AND_DATA2(reserved0);
+ DPU_INNER_IRQ_SET_CHAINED_HANDLER_AND_DATA2(reserved1);
+ DPU_INNER_IRQ_SET_CHAINED_HANDLER_AND_DATA2(blit);
+
+ for (i = 0; i < devtype->intsteer_map_size; i++) {
+ irq = irq_linear_revmap(dpu->domain, i);
+ if (irq)
+ irq_dispose_mapping(irq);
+ }
+
+ irq_domain_remove(dpu->domain);
+}
+
+static irqreturn_t dpu_dpr0_irq_handler(int irq, void *desc)
+{
+ struct dpu_soc *dpu = desc;
+ const struct dpu_unit *fls = dpu->devtype->fls;
+ struct dpu_fetchunit *fu;
+ int i;
+
+ for (i = 0; i < fls->num; i++) {
+ fu = dpu->fl_priv[i];
+ dprc_irq_handle(fu->dprc);
+ }
+
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t dpu_dpr1_irq_handler(int irq, void *desc)
+{
+ struct dpu_soc *dpu = desc;
+ const struct dpu_unit *fds = dpu->devtype->fds;
+ const struct dpu_unit *fws = dpu->devtype->fws;
+ struct dpu_fetchunit *fu;
+ int i;
+
+ for (i = 0; i < fds->num; i++) {
+ fu = dpu->fd_priv[i];
+ dprc_irq_handle(fu->dprc);
+ }
+
+ for (i = 0; i < fws->num; i++) {
+ fu = dpu->fw_priv[i];
+ dprc_irq_handle(fu->dprc);
+ }
+
+ return IRQ_HANDLED;
+}
+
+static void dpu_debug_ip_identity(struct dpu_soc *dpu)
+{
+ struct device *dev = dpu->dev;
+ const struct cm_reg_ofs *ofs = dpu->devtype->cm_reg_ofs;
+ u32 reg;
+ int id = 0;
+
+ reg = dpu_cm_read(dpu, IPIDENTIFIER(ofs));
+
+ dev_dbg(dev, "%d) Maturatiy level:\n", ++id);
+ switch (reg & DESIGNMATURITYLEVEL_MASK) {
+ case DESIGNMATURITYLEVEL__PREFS:
+ dev_dbg(dev, "\tPre feasibility study.\n");
+ break;
+ case DESIGNMATURITYLEVEL__FS:
+ dev_dbg(dev, "\tFeasibility study.\n");
+ break;
+ case DESIGNMATURITYLEVEL__R0:
+ dev_dbg(dev, "\tFunctionality complete.\n");
+ break;
+ case DESIGNMATURITYLEVEL__R1:
+ dev_dbg(dev, "\tVerification complete.\n");
+ break;
+ default:
+ dev_dbg(dev, "\tUnknown.\n");
+ break;
+ }
+
+ dev_dbg(dev, "%d) IP feature set:\n", ++id);
+ switch (reg & IPFEATURESET_MASK) {
+ case IPFEATURESET__E:
+ dev_dbg(dev, "\tMinimal functionality (Eco).\n");
+ break;
+ case IPFEATURESET__L:
+ dev_dbg(dev, "\tReduced functionality (Light).\n");
+ break;
+ case IPFEATURESET__P:
+ dev_dbg(dev, "\tAdvanced functionality (Plus).\n");
+ break;
+ case IPFEATURESET__X:
+ dev_dbg(dev, "\tExtensive functionality (eXtensive).\n");
+ break;
+ default:
+ dev_dbg(dev, "\tUnknown.\n");
+ break;
+ }
+
+ dev_dbg(dev, "%d) IP application:\n", ++id);
+ switch (reg & IPAPPLICATION_MASK) {
+ case IPAPPLICATION__B:
+ dev_dbg(dev, "\tBlit engine only.\n");
+ break;
+ case IPAPPLICATION__D:
+ dev_dbg(dev, "\tBlit engine and display controller.\n");
+ break;
+ case IPAPPLICATION__V:
+ dev_dbg(dev, "\tDisplay controller only "
+ "(with direct capture).\n");
+ break;
+ case IPAPPLICATION__G:
+ dev_dbg(dev, "\tBlit engine, display controller "
+ "(with direct capture),\n"
+ "\tcapture controller (buffered capture) "
+ "and drawing engine.\n");
+ break;
+ case IPAPPLICATION__C:
+ dev_dbg(dev, "\tDisplay controller only.\n");
+ break;
+ default:
+ dev_dbg(dev, "\tUnknown.\n");
+ break;
+ }
+
+ dev_dbg(dev, "%d) IP configuration:\n", ++id);
+ switch (reg & IPCONFIGURATION_MASK) {
+ case IPCONFIGURATION__M:
+ dev_dbg(dev, "\tGraphics core only (Module).\n");
+ break;
+ case IPCONFIGURATION__S:
+ dev_dbg(dev, "\tSubsystem including a graphics core "
+ "(System).\n");
+ break;
+ default:
+ dev_dbg(dev, "\tUnknown.\n");
+ break;
+ }
+
+ dev_dbg(dev, "%d) IP family:\n", ++id);
+ switch (reg & IPFAMILY_MASK) {
+ case IPFAMILY__IMXDPU2010:
+ dev_dbg(dev, "\tBuilding block generation 2010.\n");
+ break;
+ case IPFAMILY__IMXDPU2012:
+ dev_dbg(dev, "\tBuilding block generation 2012.\n");
+ break;
+ case IPFAMILY__IMXDPU2013:
+ dev_dbg(dev, "\tBuilding block generation 2013.\n");
+ break;
+ default:
+ dev_dbg(dev, "\tUnknown.\n");
+ break;
+ }
+}
+
+/* FIXME: initialize pixel link in a proper manner */
+static void dpu_pixel_link_init(int id)
+{
+ sc_err_t sciErr;
+ sc_ipc_t ipcHndl = 0;
+ u32 mu_id;
+
+ sciErr = sc_ipc_getMuID(&mu_id);
+ if (sciErr != SC_ERR_NONE) {
+ pr_err("Cannot obtain MU ID\n");
+ return;
+ }
+
+ sciErr = sc_ipc_open(&ipcHndl, mu_id);
+ if (sciErr != SC_ERR_NONE) {
+ pr_err("sc_ipc_open failed! (sciError = %d)\n", sciErr);
+ return;
+ }
+
+ if (id == 0) {
+ /* SC_C_KACHUNK_CNT is for blit */
+ sciErr = sc_misc_set_control(ipcHndl, SC_R_DC_0, SC_C_KACHUNK_CNT, 32);
+ if (sciErr != SC_ERR_NONE)
+ pr_err("SC_R_DC_0:SC_C_KACHUNK_CNT sc_misc_set_control failed! (sciError = %d)\n", sciErr);
+
+ sciErr = sc_misc_set_control(ipcHndl, SC_R_DC_0, SC_C_PXL_LINK_MST1_ADDR, 0);
+ if (sciErr != SC_ERR_NONE)
+ pr_err("SC_R_DC_0:SC_C_PXL_LINK_MST1_ADDR sc_misc_set_control failed! (sciError = %d)\n", sciErr);
+
+ sciErr = sc_misc_set_control(ipcHndl, SC_R_DC_0, SC_C_PXL_LINK_MST1_ENB, 0);
+ if (sciErr != SC_ERR_NONE)
+ pr_err("SC_R_DC_0:SC_C_PXL_LINK_MST1_ENB sc_misc_set_control failed! (sciError = %d)\n", sciErr);
+
+ sciErr = sc_misc_set_control(ipcHndl, SC_R_DC_0, SC_C_PXL_LINK_MST1_VLD, 0);
+ if (sciErr != SC_ERR_NONE)
+ pr_err("SC_R_DC_0:SC_C_PXL_LINK_MST1_VLD sc_misc_set_control failed! (sciError = %d)\n", sciErr);
+
+ sciErr = sc_misc_set_control(ipcHndl, SC_R_DC_0, SC_C_PXL_LINK_MST2_ADDR, 0);
+ if (sciErr != SC_ERR_NONE)
+ pr_err("SC_R_DC_0:SC_C_PXL_LINK_MST2_ADDR sc_misc_set_control failed! (sciError = %d)\n", sciErr);
+
+ sciErr = sc_misc_set_control(ipcHndl, SC_R_DC_0, SC_C_PXL_LINK_MST2_ENB, 0);
+ if (sciErr != SC_ERR_NONE)
+ pr_err("SC_R_DC_0:SC_C_PXL_LINK_MST2_ENB sc_misc_set_control failed! (sciError = %d)\n", sciErr);
+
+ sciErr = sc_misc_set_control(ipcHndl, SC_R_DC_0, SC_C_PXL_LINK_MST2_VLD, 0);
+ if (sciErr != SC_ERR_NONE)
+ pr_err("SC_R_DC_0:SC_C_PXL_LINK_MST2_VLD sc_misc_set_control failed! (sciError = %d)\n", sciErr);
+
+ sciErr = sc_misc_set_control(ipcHndl, SC_R_DC_0, SC_C_SYNC_CTRL0, 0);
+ if (sciErr != SC_ERR_NONE)
+ pr_err("SC_R_DC_0:SC_C_SYNC_CTRL0 sc_misc_set_control failed! (sciError = %d)\n", sciErr);
+
+ sciErr = sc_misc_set_control(ipcHndl, SC_R_DC_0, SC_C_SYNC_CTRL1, 0);
+ if (sciErr != SC_ERR_NONE)
+ pr_err("SC_R_DC_0:SC_C_SYNC_CTRL1 sc_misc_set_control failed! (sciError = %d)\n", sciErr);
+ } else if (id == 1) {
+ /* SC_C_KACHUNK_CNT is for blit */
+ sciErr = sc_misc_set_control(ipcHndl, SC_R_DC_1, SC_C_KACHUNK_CNT, 32);
+ if (sciErr != SC_ERR_NONE)
+ pr_err("SC_R_DC_1:SC_C_KACHUNK_CNT sc_misc_set_control failed! (sciError = %d)\n", sciErr);
+ sciErr = sc_misc_set_control(ipcHndl, SC_R_DC_1, SC_C_PXL_LINK_MST1_ADDR, 0);
+ if (sciErr != SC_ERR_NONE)
+ pr_err("SC_R_DC_1:SC_C_PXL_LINK_MST1_ADDR sc_misc_set_control failed! (sciError = %d)\n", sciErr);
+
+ sciErr = sc_misc_set_control(ipcHndl, SC_R_DC_1, SC_C_PXL_LINK_MST1_ENB, 0);
+ if (sciErr != SC_ERR_NONE)
+ pr_err("SC_R_DC_1:SC_C_PXL_LINK_MST1_ENB sc_misc_set_control failed! (sciError = %d)\n", sciErr);
+
+ sciErr = sc_misc_set_control(ipcHndl, SC_R_DC_1, SC_C_PXL_LINK_MST1_VLD, 0);
+ if (sciErr != SC_ERR_NONE)
+ pr_err("SC_R_DC_1:SC_C_PXL_LINK_MST1_VLD sc_misc_set_control failed! (sciError = %d)\n", sciErr);
+
+ sciErr = sc_misc_set_control(ipcHndl, SC_R_DC_1, SC_C_PXL_LINK_MST2_ADDR, 0);
+ if (sciErr != SC_ERR_NONE)
+ pr_err("SC_R_DC_1:SC_C_PXL_LINK_MST2_ADDR sc_misc_set_control failed! (sciError = %d)\n", sciErr);
+
+ sciErr = sc_misc_set_control(ipcHndl, SC_R_DC_1, SC_C_PXL_LINK_MST2_ENB, 0);
+ if (sciErr != SC_ERR_NONE)
+ pr_err("SC_R_DC_1:SC_C_PXL_LINK_MST2_ENB sc_misc_set_control failed! (sciError = %d)\n", sciErr);
+
+ sciErr = sc_misc_set_control(ipcHndl, SC_R_DC_1, SC_C_PXL_LINK_MST2_VLD, 0);
+ if (sciErr != SC_ERR_NONE)
+ pr_err("SC_R_DC_1:SC_C_PXL_LINK_MST2_VLD sc_misc_set_control failed! (sciError = %d)\n", sciErr);
+
+ sciErr = sc_misc_set_control(ipcHndl, SC_R_DC_1, SC_C_SYNC_CTRL0, 0);
+ if (sciErr != SC_ERR_NONE)
+ pr_err("SC_R_DC_1:SC_C_SYNC_CTRL0 sc_misc_set_control failed! (sciError = %d)\n", sciErr);
+
+ sciErr = sc_misc_set_control(ipcHndl, SC_R_DC_1, SC_C_SYNC_CTRL1, 0);
+ if (sciErr != SC_ERR_NONE)
+ pr_err("SC_R_DC_1:SC_C_SYNC_CTRL1 sc_misc_set_control failed! (sciError = %d)\n", sciErr);
+ }
+
+ sc_ipc_close(mu_id);
+}
+
+static int dpu_probe(struct platform_device *pdev)
+{
+ const struct of_device_id *of_id =
+ of_match_device(dpu_dt_ids, &pdev->dev);
+ struct device_node *np = pdev->dev.of_node;
+ struct dpu_soc *dpu;
+ struct resource *res;
+ unsigned long dpu_base;
+ const struct dpu_devtype *devtype;
+ int ret;
+
+ devtype = of_id->data;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res)
+ return -ENODEV;
+
+ dpu_base = res->start;
+
+ dpu = devm_kzalloc(&pdev->dev, sizeof(*dpu), GFP_KERNEL);
+ if (!dpu)
+ return -ENODEV;
+
+ dpu->dev = &pdev->dev;
+ dpu->devtype = devtype;
+ dpu->id = of_alias_get_id(np, "dpu");
+
+ /* inner irqs */
+ dpu->irq_cm = platform_get_irq(pdev, 0);
+ dpu->irq_stream0a = platform_get_irq(pdev, 1);
+ dpu->irq_stream1a = platform_get_irq(pdev, 3);
+ dpu->irq_reserved0 = platform_get_irq(pdev, 5);
+ dpu->irq_reserved1 = platform_get_irq(pdev, 6);
+ dpu->irq_blit = platform_get_irq(pdev, 7);
+
+ dev_dbg(dpu->dev, "irq_cm: %d\n", dpu->irq_cm);
+ dev_dbg(dpu->dev, "irq_stream0a: %d, irq_stream1a: %d\n",
+ dpu->irq_stream0a, dpu->irq_stream1a);
+ dev_dbg(dpu->dev, "irq_reserved0: %d, irq_reserved1: %d\n",
+ dpu->irq_reserved0, dpu->irq_reserved1);
+ dev_dbg(dpu->dev, "irq_blit: %d\n", dpu->irq_blit);
+
+ if (dpu->irq_cm < 0 ||
+ dpu->irq_stream0a < 0 || dpu->irq_stream1a < 0 ||
+ dpu->irq_reserved0 < 0 || dpu->irq_reserved1 < 0 ||
+ dpu->irq_blit < 0)
+ return -ENODEV;
+
+ dpu->intsteer_regmap = syscon_regmap_lookup_by_phandle(np, "intsteer");
+ if (IS_ERR(dpu->intsteer_regmap)) {
+ dev_err(dpu->dev, "failed to get intsteer regmap\n");
+ return PTR_ERR(dpu->intsteer_regmap);
+ }
+
+ /* DPR irqs */
+ if (dpu->devtype->has_prefetch) {
+ dpu->irq_dpr0 = platform_get_irq(pdev, 8);
+ dpu->irq_dpr1 = platform_get_irq(pdev, 9);
+
+ dev_dbg(dpu->dev, "irq_dpr0: %d\n", dpu->irq_dpr0);
+ dev_dbg(dpu->dev, "irq_dpr1: %d\n", dpu->irq_dpr1);
+
+ if (dpu->irq_dpr0 < 0 || dpu->irq_dpr1 < 0)
+ return -ENODEV;
+
+ ret = devm_request_irq(dpu->dev, dpu->irq_dpr0,
+ dpu_dpr0_irq_handler, 0, pdev->name, dpu);
+ if (ret) {
+ dev_err(dpu->dev, "request dpr0 interrupt failed\n");
+ return ret;
+ }
+
+ ret = devm_request_irq(dpu->dev, dpu->irq_dpr1,
+ dpu_dpr1_irq_handler, 0, pdev->name, dpu);
+ if (ret) {
+ dev_err(dpu->dev, "request dpr1 interrupt failed\n");
+ return ret;
+ }
+ }
+
+ spin_lock_init(&dpu->lock);
+ spin_lock_init(&dpu->intsteer_lock);
+
+ dev_dbg(dpu->dev, "Common: 0x%08lx\n", dpu_base + devtype->cm_ofs);
+ DPU_UNITS_ADDR_DBG(cf);
+ DPU_UNITS_ADDR_DBG(dec);
+ DPU_UNITS_ADDR_DBG(ed);
+ DPU_UNITS_ADDR_DBG(fd);
+ DPU_UNITS_ADDR_DBG(fe);
+ DPU_UNITS_ADDR_DBG(fg);
+ DPU_UNITS_ADDR_DBG(fl);
+ DPU_UNITS_ADDR_DBG(fw);
+ DPU_UNITS_ADDR_DBG(hs);
+ DPU_UNITS_ADDR_DBG(lb);
+ DPU_UNITS_ADDR_DBG(st);
+ DPU_UNITS_ADDR_DBG(tcon);
+ DPU_UNITS_ADDR_DBG(vs);
+
+ dpu->cm_reg = devm_ioremap(dpu->dev, dpu_base + devtype->cm_ofs, SZ_1K);
+ if (!dpu->cm_reg)
+ return -ENOMEM;
+
+ platform_set_drvdata(pdev, dpu);
+
+ ret = dpu_inner_irq_init(dpu);
+ if (ret)
+ goto failed_inner_irq;
+
+ ret = dpu_submodules_init(dpu, pdev, dpu_base);
+ if (ret)
+ goto failed_submodules_init;
+
+ ret = dpu_add_client_devices(dpu);
+ if (ret) {
+ dev_err(dpu->dev, "adding client devices failed with %d\n",
+ ret);
+ goto failed_add_clients;
+ }
+
+ dpu_debug_ip_identity(dpu);
+
+ if (devtype->pixel_link_quirks)
+ dpu_pixel_link_init(dpu->id);
+
+ dev_info(dpu->dev, "driver probed\n");
+
+ return 0;
+
+failed_add_clients:
+failed_submodules_init:
+ dpu_inner_irq_exit(dpu);
+failed_inner_irq:
+ return ret;
+}
+
+static int dpu_remove(struct platform_device *pdev)
+{
+ struct dpu_soc *dpu = platform_get_drvdata(pdev);
+
+ platform_device_unregister_children(pdev);
+ dpu_inner_irq_exit(dpu);
+
+ return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int dpu_suspend(struct device *dev)
+{
+ /*
+ * The dpu core driver currently depends on the client drivers
+ * to do suspend operations to leave dpu a cleaned up state
+ * machine status before the system enters sleep mode.
+ */
+ return 0;
+}
+
+static int dpu_resume(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct dpu_soc *dpu = platform_get_drvdata(pdev);
+
+ dpu_inner_intsteer_enable_lines(dpu);
+
+ if (dpu->devtype->pixel_link_quirks)
+ dpu_pixel_link_init(dpu->id);
+
+ _dpu_submodules_init(dpu, pdev);
+
+ return 0;
+}
+#endif
+
+static const struct dev_pm_ops dpu_pm_ops = {
+ SET_LATE_SYSTEM_SLEEP_PM_OPS(dpu_suspend, dpu_resume)
+};
+
+static struct platform_driver dpu_driver = {
+ .driver = {
+ .pm = &dpu_pm_ops,
+ .name = "dpu-core",
+ .of_match_table = dpu_dt_ids,
+ },
+ .probe = dpu_probe,
+ .remove = dpu_remove,
+};
+
+module_platform_driver(dpu_driver);
+
+MODULE_DESCRIPTION("i.MX DPU driver");
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/imx/dpu/dpu-constframe.c b/drivers/gpu/imx/dpu/dpu-constframe.c
new file mode 100644
index 000000000000..f82224a9c90f
--- /dev/null
+++ b/drivers/gpu/imx/dpu/dpu-constframe.c
@@ -0,0 +1,283 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017-2018 NXP
+ *
+ * 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/io.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/platform_device.h>
+#include <linux/types.h>
+#include <video/dpu.h>
+#include "dpu-prv.h"
+
+static unsigned int safety_stream_cf_color = 0x0;
+module_param(safety_stream_cf_color, uint, 0444);
+MODULE_PARM_DESC(safety_stream_cf_color,
+"Safety stream constframe color in hex(0xRRGGBBAA) [default=0x00000000]");
+
+#define FRAMEDIMENSIONS 0xC
+#define WIDTH(w) (((w) - 1) & 0x3FFF)
+#define HEIGHT(h) ((((h) - 1) & 0x3FFF) << 16)
+#define CONSTANTCOLOR 0x10
+#define RED(r) (((r) & 0xFF) << 24)
+#define GREEN(g) (((g) & 0xFF) << 16)
+#define BLUE(b) (((b) & 0xFF) << 8)
+#define ALPHA(a) ((a) & 0xFF)
+#define CONTROLTRIGGER 0x14
+#define START 0x18
+#define STATUS 0x1C
+
+static const shadow_load_req_t cf_shdlreqs[] = {
+ SHLDREQID_CONSTFRAME0, SHLDREQID_CONSTFRAME1,
+ SHLDREQID_CONSTFRAME4, SHLDREQID_CONSTFRAME5,
+};
+
+struct dpu_constframe {
+ void __iomem *pec_base;
+ void __iomem *base;
+ struct mutex mutex;
+ int id;
+ bool inuse;
+ struct dpu_soc *dpu;
+ shadow_load_req_t shdlreq;
+};
+
+static inline u32 dpu_cf_read(struct dpu_constframe *cf, unsigned int offset)
+{
+ return readl(cf->base + offset);
+}
+
+static inline void dpu_cf_write(struct dpu_constframe *cf, u32 value,
+ unsigned int offset)
+{
+ writel(value, cf->base + offset);
+}
+
+void constframe_shden(struct dpu_constframe *cf, bool enable)
+{
+ u32 val;
+
+ val = enable ? SHDEN : 0;
+
+ mutex_lock(&cf->mutex);
+ dpu_cf_write(cf, val, STATICCONTROL);
+ mutex_unlock(&cf->mutex);
+}
+EXPORT_SYMBOL_GPL(constframe_shden);
+
+void constframe_framedimensions(struct dpu_constframe *cf, unsigned int w,
+ unsigned int h)
+{
+ u32 val;
+
+ val = WIDTH(w) | HEIGHT(h);
+
+ mutex_lock(&cf->mutex);
+ dpu_cf_write(cf, val, FRAMEDIMENSIONS);
+ mutex_unlock(&cf->mutex);
+}
+EXPORT_SYMBOL_GPL(constframe_framedimensions);
+
+void constframe_framedimensions_copy_prim(struct dpu_constframe *cf)
+{
+ struct dpu_constframe *prim_cf = NULL;
+ unsigned int prim_id;
+ int i;
+ u32 val;
+
+ if (cf->id != 0 && cf->id != 1) {
+ dev_warn(cf->dpu->dev, "ConstFrame%d is not a secondary one\n",
+ cf->id);
+ return;
+ }
+
+ prim_id = cf->id + 4;
+
+ for (i = 0; i < ARRAY_SIZE(cf_ids); i++)
+ if (cf_ids[i] == prim_id)
+ prim_cf = cf->dpu->cf_priv[i];
+
+ if (!prim_cf) {
+ dev_warn(cf->dpu->dev, "cannot find ConstFrame%d's primary peer\n",
+ cf->id);
+ return;
+ }
+
+ mutex_lock(&cf->mutex);
+ val = dpu_cf_read(prim_cf, FRAMEDIMENSIONS);
+ dpu_cf_write(cf, val, FRAMEDIMENSIONS);
+ mutex_unlock(&cf->mutex);
+}
+EXPORT_SYMBOL_GPL(constframe_framedimensions_copy_prim);
+
+void constframe_constantcolor(struct dpu_constframe *cf, unsigned int r,
+ unsigned int g, unsigned int b, unsigned int a)
+{
+ u32 val;
+
+ val = RED(r) | GREEN(g) | BLUE(b) | ALPHA(a);
+
+ mutex_lock(&cf->mutex);
+ dpu_cf_write(cf, val, CONSTANTCOLOR);
+ mutex_unlock(&cf->mutex);
+}
+EXPORT_SYMBOL_GPL(constframe_constantcolor);
+
+void constframe_controltrigger(struct dpu_constframe *cf, bool trigger)
+{
+ u32 val;
+
+ val = trigger ? SHDTOKGEN : 0;
+
+ mutex_lock(&cf->mutex);
+ dpu_cf_write(cf, val, CONTROLTRIGGER);
+ mutex_unlock(&cf->mutex);
+}
+EXPORT_SYMBOL_GPL(constframe_controltrigger);
+
+shadow_load_req_t constframe_to_shdldreq_t(struct dpu_constframe *cf)
+{
+ shadow_load_req_t t = 0;
+
+ switch (cf->id) {
+ case 0:
+ t = SHLDREQID_CONSTFRAME0;
+ break;
+ case 1:
+ t = SHLDREQID_CONSTFRAME1;
+ break;
+ case 4:
+ t = SHLDREQID_CONSTFRAME4;
+ break;
+ case 5:
+ t = SHLDREQID_CONSTFRAME5;
+ break;
+ }
+
+ return t;
+}
+EXPORT_SYMBOL_GPL(constframe_to_shdldreq_t);
+
+struct dpu_constframe *dpu_cf_get(struct dpu_soc *dpu, int id)
+{
+ struct dpu_constframe *cf;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(cf_ids); i++)
+ if (cf_ids[i] == id)
+ break;
+
+ if (i == ARRAY_SIZE(cf_ids))
+ return ERR_PTR(-EINVAL);
+
+ cf = dpu->cf_priv[i];
+
+ mutex_lock(&cf->mutex);
+
+ if (cf->inuse) {
+ mutex_unlock(&cf->mutex);
+ return ERR_PTR(-EBUSY);
+ }
+
+ cf->inuse = true;
+
+ mutex_unlock(&cf->mutex);
+
+ return cf;
+}
+EXPORT_SYMBOL_GPL(dpu_cf_get);
+
+void dpu_cf_put(struct dpu_constframe *cf)
+{
+ mutex_lock(&cf->mutex);
+
+ cf->inuse = false;
+
+ mutex_unlock(&cf->mutex);
+}
+EXPORT_SYMBOL_GPL(dpu_cf_put);
+
+struct dpu_constframe *dpu_aux_cf_peek(struct dpu_constframe *cf)
+{
+ unsigned int aux_id = cf->id ^ 1;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(cf_ids); i++)
+ if (cf_ids[i] == aux_id)
+ return cf->dpu->cf_priv[i];
+
+ return NULL;
+}
+EXPORT_SYMBOL_GPL(dpu_aux_cf_peek);
+
+void _dpu_cf_init(struct dpu_soc *dpu, unsigned int id)
+{
+ struct dpu_constframe *cf;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(cf_ids); i++)
+ if (cf_ids[i] == id)
+ break;
+
+ if (WARN_ON(i == ARRAY_SIZE(cf_ids)))
+ return;
+
+ cf = dpu->cf_priv[i];
+
+ constframe_shden(cf, true);
+
+ if (id == 4 || id == 5) {
+ mutex_lock(&cf->mutex);
+ dpu_cf_write(cf, safety_stream_cf_color, CONSTANTCOLOR);
+ mutex_unlock(&cf->mutex);
+ }
+}
+
+int dpu_cf_init(struct dpu_soc *dpu, unsigned int id,
+ unsigned long pec_base, unsigned long base)
+{
+ struct dpu_constframe *cf;
+ int i;
+
+ cf = devm_kzalloc(dpu->dev, sizeof(*cf), GFP_KERNEL);
+ if (!cf)
+ return -ENOMEM;
+
+ for (i = 0; i < ARRAY_SIZE(cf_ids); i++)
+ if (cf_ids[i] == id)
+ break;
+
+ if (i == ARRAY_SIZE(cf_ids))
+ return -EINVAL;
+
+ dpu->cf_priv[i] = cf;
+
+ cf->pec_base = devm_ioremap(dpu->dev, pec_base, SZ_16);
+ if (!cf->pec_base)
+ return -ENOMEM;
+
+ cf->base = devm_ioremap(dpu->dev, base, SZ_32);
+ if (!cf->base)
+ return -ENOMEM;
+
+ cf->dpu = dpu;
+ cf->id = id;
+ cf->shdlreq = cf_shdlreqs[i];
+
+ mutex_init(&cf->mutex);
+
+ _dpu_cf_init(dpu, id);
+
+ return 0;
+}
diff --git a/drivers/gpu/imx/dpu/dpu-disengcfg.c b/drivers/gpu/imx/dpu/dpu-disengcfg.c
new file mode 100644
index 000000000000..58b65c2c0cd1
--- /dev/null
+++ b/drivers/gpu/imx/dpu/dpu-disengcfg.c
@@ -0,0 +1,148 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017-2018 NXP
+ *
+ * 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 <drm/drm_mode.h>
+#include <linux/io.h>
+#include <linux/mutex.h>
+#include <linux/platform_device.h>
+#include <linux/types.h>
+#include "dpu-prv.h"
+
+#define CLOCKCTRL 0x8
+typedef enum {
+ DSPCLKDIVIDE__DIV1, /* Ext disp clk signal has pix clk freq. */
+ DSPCLKDIVIDE__DIV2, /* Ext disp clk signal has 2x the pix clk freq. */
+} clkdivide_t;
+#define POLARITYCTRL 0xC
+#define POLHS_HIGH BIT(0)
+#define POLVS_HIGH BIT(1)
+#define POLEN_HIGH BIT(2)
+#define PIXINV_INV BIT(3)
+#define SRCSELECT 0x10
+
+struct dpu_disengcfg {
+ void __iomem *base;
+ struct mutex mutex;
+ int id;
+ bool inuse;
+ struct dpu_soc *dpu;
+};
+
+static inline u32 dpu_dec_read(struct dpu_disengcfg *dec, unsigned int offset)
+{
+ return readl(dec->base + offset);
+}
+
+static inline void dpu_dec_write(struct dpu_disengcfg *dec, u32 value,
+ unsigned int offset)
+{
+ writel(value, dec->base + offset);
+}
+
+void disengcfg_polarity_ctrl(struct dpu_disengcfg *dec, unsigned int flags)
+{
+ const struct dpu_devtype *devtype = dec->dpu->devtype;
+ u32 val;
+
+ mutex_lock(&dec->mutex);
+ val = dpu_dec_read(dec, POLARITYCTRL);
+ if (devtype->pixel_link_nhvsync) {
+ val &= ~POLHS_HIGH;
+ val &= ~POLVS_HIGH;
+ } else {
+ if (flags & DRM_MODE_FLAG_PHSYNC)
+ val |= POLHS_HIGH;
+ if (flags & DRM_MODE_FLAG_NHSYNC)
+ val &= ~POLHS_HIGH;
+ if (flags & DRM_MODE_FLAG_PVSYNC)
+ val |= POLVS_HIGH;
+ if (flags & DRM_MODE_FLAG_NVSYNC)
+ val &= ~POLVS_HIGH;
+ }
+ dpu_dec_write(dec, val, POLARITYCTRL);
+ mutex_unlock(&dec->mutex);
+}
+EXPORT_SYMBOL_GPL(disengcfg_polarity_ctrl);
+
+struct dpu_disengcfg *dpu_dec_get(struct dpu_soc *dpu, int id)
+{
+ struct dpu_disengcfg *dec;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(dec_ids); i++)
+ if (dec_ids[i] == id)
+ break;
+
+ if (i == ARRAY_SIZE(dec_ids))
+ return ERR_PTR(-EINVAL);
+
+ dec = dpu->dec_priv[i];
+
+ mutex_lock(&dec->mutex);
+
+ if (dec->inuse) {
+ mutex_unlock(&dec->mutex);
+ return ERR_PTR(-EBUSY);
+ }
+
+ dec->inuse = true;
+
+ mutex_unlock(&dec->mutex);
+
+ return dec;
+}
+EXPORT_SYMBOL_GPL(dpu_dec_get);
+
+void dpu_dec_put(struct dpu_disengcfg *dec)
+{
+ mutex_lock(&dec->mutex);
+
+ dec->inuse = false;
+
+ mutex_unlock(&dec->mutex);
+}
+EXPORT_SYMBOL_GPL(dpu_dec_put);
+
+struct dpu_disengcfg *dpu_aux_dec_peek(struct dpu_disengcfg *dec)
+{
+ return dec->dpu->dec_priv[dec->id ^ 1];
+}
+EXPORT_SYMBOL_GPL(dpu_aux_dec_peek);
+
+void _dpu_dec_init(struct dpu_soc *dpu, unsigned int id)
+{
+}
+
+int dpu_dec_init(struct dpu_soc *dpu, unsigned int id,
+ unsigned long unused, unsigned long base)
+{
+ struct dpu_disengcfg *dec;
+
+ dec = devm_kzalloc(dpu->dev, sizeof(*dec), GFP_KERNEL);
+ if (!dec)
+ return -ENOMEM;
+
+ dpu->dec_priv[id] = dec;
+
+ dec->base = devm_ioremap(dpu->dev, base, SZ_16);
+ if (!dec->base)
+ return -ENOMEM;
+
+ dec->dpu = dpu;
+ dec->id = id;
+ mutex_init(&dec->mutex);
+
+ return 0;
+}
diff --git a/drivers/gpu/imx/dpu/dpu-extdst.c b/drivers/gpu/imx/dpu/dpu-extdst.c
new file mode 100644
index 000000000000..fe44db2851c8
--- /dev/null
+++ b/drivers/gpu/imx/dpu/dpu-extdst.c
@@ -0,0 +1,546 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017-2018 NXP
+ *
+ * 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/io.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/platform_device.h>
+#include <linux/types.h>
+#include <video/dpu.h>
+#include "dpu-prv.h"
+
+#define PIXENGCFG_STATIC 0x8
+#define POWERDOWN BIT(4)
+#define SYNC_MODE BIT(8)
+#define SW_RESET BIT(11)
+#define DIV(n) (((n) & 0xFF) << 16)
+#define DIV_RESET 0x80
+#define PIXENGCFG_DYNAMIC 0xC
+#define PIXENGCFG_REQUEST 0x10
+#define SHDLDREQ(n) BIT(n)
+#define SEL_SHDLDREQ BIT(0)
+#define PIXENGCFG_TRIGGER 0x14
+#define SYNC_TRIGGER BIT(0)
+#define TRIGGER_SEQUENCE_COMPLETE BIT(4)
+#define PIXENGCFG_STATUS 0x18
+#define SYNC_BUSY BIT(8)
+#define KICK_MODE BIT(8)
+#define PERFCOUNTMODE BIT(12)
+#define CONTROL 0xC
+#define GAMMAAPPLYENABLE BIT(0)
+#define SOFTWAREKICK 0x10
+#define KICK BIT(0)
+#define STATUS 0x14
+#define CNT_ERR_STS BIT(0)
+#define CONTROLWORD 0x18
+#define CURPIXELCNT 0x1C
+static u16 get_xval(u32 pixel_cnt)
+{
+ return pixel_cnt & 0xFFFF;
+}
+
+static u16 get_yval(u32 pixel_cnt)
+{
+ return pixel_cnt >> 16;
+}
+#define LASTPIXELCNT 0x20
+#define PERFCOUNTER 0x24
+
+struct dpu_extdst {
+ void __iomem *pec_base;
+ void __iomem *base;
+ struct mutex mutex;
+ int id;
+ bool inuse;
+ struct dpu_soc *dpu;
+};
+
+static inline u32 dpu_pec_ed_read(struct dpu_extdst *ed, unsigned int offset)
+{
+ return readl(ed->pec_base + offset);
+}
+
+static inline void dpu_pec_ed_write(struct dpu_extdst *ed, u32 value,
+ unsigned int offset)
+{
+ writel(value, ed->pec_base + offset);
+}
+
+static inline u32 dpu_ed_read(struct dpu_extdst *ed, unsigned int offset)
+{
+ return readl(ed->base + offset);
+}
+
+static inline void dpu_ed_write(struct dpu_extdst *ed, u32 value,
+ unsigned int offset)
+{
+ writel(value, ed->base + offset);
+}
+
+static inline bool dpu_ed_is_safety_stream(struct dpu_extdst *ed)
+{
+ if (ed->id == 4 || ed->id == 5)
+ return true;
+
+ return false;
+}
+
+static inline bool dpu_ed_src_sel_is_extsrc(extdst_src_sel_t src)
+{
+ if (src == ED_SRC_EXTSRC4 || src == ED_SRC_EXTSRC5)
+ return true;
+
+ return false;
+}
+
+void extdst_pixengcfg_shden(struct dpu_extdst *ed, bool enable)
+{
+ u32 val;
+
+ mutex_lock(&ed->mutex);
+ val = dpu_pec_ed_read(ed, PIXENGCFG_STATIC);
+ if (enable)
+ val |= SHDEN;
+ else
+ val &= ~SHDEN;
+ dpu_pec_ed_write(ed, val, PIXENGCFG_STATIC);
+ mutex_unlock(&ed->mutex);
+}
+EXPORT_SYMBOL_GPL(extdst_pixengcfg_shden);
+
+void extdst_pixengcfg_powerdown(struct dpu_extdst *ed, bool powerdown)
+{
+ u32 val;
+
+ mutex_lock(&ed->mutex);
+ val = dpu_pec_ed_read(ed, PIXENGCFG_STATIC);
+ if (powerdown)
+ val |= POWERDOWN;
+ else
+ val &= ~POWERDOWN;
+ dpu_pec_ed_write(ed, val, PIXENGCFG_STATIC);
+ mutex_unlock(&ed->mutex);
+}
+EXPORT_SYMBOL_GPL(extdst_pixengcfg_powerdown);
+
+void extdst_pixengcfg_sync_mode(struct dpu_extdst *ed, ed_sync_mode_t mode)
+{
+ u32 val;
+
+ mutex_lock(&ed->mutex);
+ val = dpu_pec_ed_read(ed, PIXENGCFG_STATIC);
+ if (mode == AUTO)
+ val |= SYNC_MODE;
+ else
+ val &= ~SYNC_MODE;
+ dpu_pec_ed_write(ed, val, PIXENGCFG_STATIC);
+ mutex_unlock(&ed->mutex);
+}
+EXPORT_SYMBOL_GPL(extdst_pixengcfg_sync_mode);
+
+void extdst_pixengcfg_reset(struct dpu_extdst *ed, bool reset)
+{
+ u32 val;
+
+ mutex_lock(&ed->mutex);
+ val = dpu_pec_ed_read(ed, PIXENGCFG_STATIC);
+ if (reset)
+ val |= SW_RESET;
+ else
+ val &= ~SW_RESET;
+ dpu_pec_ed_write(ed, val, PIXENGCFG_STATIC);
+ mutex_unlock(&ed->mutex);
+}
+EXPORT_SYMBOL_GPL(extdst_pixengcfg_reset);
+
+void extdst_pixengcfg_div(struct dpu_extdst *ed, u16 div)
+{
+ u32 val;
+
+ mutex_lock(&ed->mutex);
+ val = dpu_pec_ed_read(ed, PIXENGCFG_STATIC);
+ val &= ~0xFF0000;
+ val |= DIV(div);
+ dpu_pec_ed_write(ed, val, PIXENGCFG_STATIC);
+ mutex_unlock(&ed->mutex);
+}
+EXPORT_SYMBOL_GPL(extdst_pixengcfg_div);
+
+void extdst_pixengcfg_syncmode_master(struct dpu_extdst *ed, bool enable)
+{
+ struct dpu_soc *dpu = ed->dpu;
+ u32 val;
+
+ if (!dpu->devtype->has_syncmode_fixup)
+ return;
+
+ mutex_lock(&ed->mutex);
+ val = dpu_pec_ed_read(ed, PIXENGCFG_STATIC);
+ if (enable)
+ val |= BIT(16);
+ else
+ val &= ~BIT(16);
+ dpu_pec_ed_write(ed, val, PIXENGCFG_STATIC);
+ mutex_unlock(&ed->mutex);
+}
+EXPORT_SYMBOL_GPL(extdst_pixengcfg_syncmode_master);
+
+int extdst_pixengcfg_src_sel(struct dpu_extdst *ed, extdst_src_sel_t src)
+{
+ struct dpu_soc *dpu = ed->dpu;
+ const unsigned int *block_id_map = dpu->devtype->sw2hw_block_id_map;
+ u32 mapped_src;
+
+ mapped_src = block_id_map ? block_id_map[src] : src;
+ if (WARN_ON(mapped_src == NA))
+ return -EINVAL;
+
+ if (dpu_ed_is_safety_stream(ed) && dpu_ed_src_sel_is_extsrc(src)) {
+ dev_err(dpu->dev, "ExtDst%d source cannot be ExtSrc\n", ed->id);
+ return -EINVAL;
+ }
+
+ mutex_lock(&ed->mutex);
+ dpu_pec_ed_write(ed, mapped_src, PIXENGCFG_DYNAMIC);
+ mutex_unlock(&ed->mutex);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(extdst_pixengcfg_src_sel);
+
+void extdst_pixengcfg_sel_shdldreq(struct dpu_extdst *ed)
+{
+ u32 val;
+
+ mutex_lock(&ed->mutex);
+ val = dpu_pec_ed_read(ed, PIXENGCFG_REQUEST);
+ val |= SEL_SHDLDREQ;
+ dpu_pec_ed_write(ed, val, PIXENGCFG_REQUEST);
+ mutex_unlock(&ed->mutex);
+}
+EXPORT_SYMBOL_GPL(extdst_pixengcfg_sel_shdldreq);
+
+void extdst_pixengcfg_shdldreq(struct dpu_extdst *ed, u32 req_mask)
+{
+ u32 val;
+
+ mutex_lock(&ed->mutex);
+ val = dpu_pec_ed_read(ed, PIXENGCFG_REQUEST);
+ val |= req_mask;
+ dpu_pec_ed_write(ed, val, PIXENGCFG_REQUEST);
+ mutex_unlock(&ed->mutex);
+}
+EXPORT_SYMBOL_GPL(extdst_pixengcfg_shdldreq);
+
+void extdst_pixengcfg_sync_trigger(struct dpu_extdst *ed)
+{
+ mutex_lock(&ed->mutex);
+ dpu_pec_ed_write(ed, SYNC_TRIGGER, PIXENGCFG_TRIGGER);
+ mutex_unlock(&ed->mutex);
+}
+EXPORT_SYMBOL_GPL(extdst_pixengcfg_sync_trigger);
+
+void extdst_pixengcfg_trigger_sequence_complete(struct dpu_extdst *ed)
+{
+ mutex_lock(&ed->mutex);
+ dpu_pec_ed_write(ed, TRIGGER_SEQUENCE_COMPLETE, PIXENGCFG_TRIGGER);
+ mutex_unlock(&ed->mutex);
+}
+EXPORT_SYMBOL_GPL(extdst_pixengcfg_trigger_sequence_complete);
+
+bool extdst_pixengcfg_is_sync_busy(struct dpu_extdst *ed)
+{
+ u32 val;
+
+ mutex_lock(&ed->mutex);
+ val = dpu_pec_ed_read(ed, PIXENGCFG_STATUS);
+ mutex_unlock(&ed->mutex);
+
+ return val & SYNC_BUSY;
+}
+EXPORT_SYMBOL_GPL(extdst_pixengcfg_is_sync_busy);
+
+ed_pipeline_status_t extdst_pixengcfg_pipeline_status(struct dpu_extdst *ed)
+{
+ u32 val;
+
+ mutex_lock(&ed->mutex);
+ val = dpu_pec_ed_read(ed, PIXENGCFG_STATUS);
+ mutex_unlock(&ed->mutex);
+
+ return val & 0x3;
+}
+EXPORT_SYMBOL_GPL(extdst_pixengcfg_pipeline_status);
+
+void extdst_shden(struct dpu_extdst *ed, bool enable)
+{
+ u32 val;
+
+ mutex_lock(&ed->mutex);
+ val = dpu_ed_read(ed, STATICCONTROL);
+ if (enable)
+ val |= SHDEN;
+ else
+ val &= ~SHDEN;
+ dpu_ed_write(ed, val, STATICCONTROL);
+ mutex_unlock(&ed->mutex);
+}
+EXPORT_SYMBOL_GPL(extdst_shden);
+
+void extdst_kick_mode(struct dpu_extdst *ed, ed_kick_mode_t mode)
+{
+ u32 val;
+
+ mutex_lock(&ed->mutex);
+ val = dpu_ed_read(ed, STATICCONTROL);
+ val &= ~KICK_MODE;
+ val |= mode;
+ dpu_ed_write(ed, val, STATICCONTROL);
+ mutex_unlock(&ed->mutex);
+}
+EXPORT_SYMBOL_GPL(extdst_kick_mode);
+
+void extdst_perfcountmode(struct dpu_extdst *ed, bool enable)
+{
+ u32 val;
+
+ mutex_lock(&ed->mutex);
+ val = dpu_ed_read(ed, STATICCONTROL);
+ if (enable)
+ val |= PERFCOUNTMODE;
+ else
+ val &= ~PERFCOUNTMODE;
+ dpu_ed_write(ed, val, STATICCONTROL);
+ mutex_unlock(&ed->mutex);
+}
+EXPORT_SYMBOL_GPL(extdst_perfcountmode);
+
+void extdst_gamma_apply_enable(struct dpu_extdst *ed, bool enable)
+{
+ u32 val;
+
+ mutex_lock(&ed->mutex);
+ val = dpu_ed_read(ed, CONTROL);
+ if (enable)
+ val |= GAMMAAPPLYENABLE;
+ else
+ val &= ~GAMMAAPPLYENABLE;
+ dpu_ed_write(ed, val, CONTROL);
+ mutex_unlock(&ed->mutex);
+}
+EXPORT_SYMBOL_GPL(extdst_gamma_apply_enable);
+
+void extdst_kick(struct dpu_extdst *ed)
+{
+ mutex_lock(&ed->mutex);
+ dpu_ed_write(ed, KICK, SOFTWAREKICK);
+ mutex_unlock(&ed->mutex);
+}
+EXPORT_SYMBOL_GPL(extdst_kick);
+
+void extdst_cnt_err_clear(struct dpu_extdst *ed)
+{
+ mutex_lock(&ed->mutex);
+ dpu_ed_write(ed, CNT_ERR_STS, STATUS);
+ mutex_unlock(&ed->mutex);
+}
+EXPORT_SYMBOL_GPL(extdst_cnt_err_clear);
+
+bool extdst_cnt_err_status(struct dpu_extdst *ed)
+{
+ u32 val;
+
+ mutex_lock(&ed->mutex);
+ val = dpu_ed_read(ed, STATUS);
+ mutex_unlock(&ed->mutex);
+
+ return val & CNT_ERR_STS;
+}
+EXPORT_SYMBOL_GPL(extdst_cnt_err_status);
+
+u32 extdst_last_control_word(struct dpu_extdst *ed)
+{
+ u32 val;
+
+ mutex_lock(&ed->mutex);
+ val = dpu_ed_read(ed, CONTROLWORD);
+ mutex_unlock(&ed->mutex);
+
+ return val;
+}
+EXPORT_SYMBOL_GPL(extdst_last_control_word);
+
+void extdst_pixel_cnt(struct dpu_extdst *ed, u16 *x, u16 *y)
+{
+ u32 val;
+
+ mutex_lock(&ed->mutex);
+ val = dpu_ed_read(ed, CURPIXELCNT);
+ mutex_unlock(&ed->mutex);
+
+ *x = get_xval(val);
+ *y = get_yval(val);
+}
+EXPORT_SYMBOL_GPL(extdst_pixel_cnt);
+
+void extdst_last_pixel_cnt(struct dpu_extdst *ed, u16 *x, u16 *y)
+{
+ u32 val;
+
+ mutex_lock(&ed->mutex);
+ val = dpu_ed_read(ed, LASTPIXELCNT);
+ mutex_unlock(&ed->mutex);
+
+ *x = get_xval(val);
+ *y = get_yval(val);
+}
+EXPORT_SYMBOL_GPL(extdst_last_pixel_cnt);
+
+u32 extdst_perfresult(struct dpu_extdst *ed)
+{
+ u32 val;
+
+ mutex_lock(&ed->mutex);
+ val = dpu_ed_read(ed, PERFCOUNTER);
+ mutex_unlock(&ed->mutex);
+
+ return val;
+}
+EXPORT_SYMBOL_GPL(extdst_perfresult);
+
+bool extdst_is_master(struct dpu_extdst *ed)
+{
+ const struct dpu_devtype *devtype = ed->dpu->devtype;
+
+ return ed->id == devtype->master_stream_id;
+}
+EXPORT_SYMBOL_GPL(extdst_is_master);
+
+struct dpu_extdst *dpu_ed_get(struct dpu_soc *dpu, int id)
+{
+ struct dpu_extdst *ed;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(ed_ids); i++)
+ if (ed_ids[i] == id)
+ break;
+
+ if (i == ARRAY_SIZE(ed_ids))
+ return ERR_PTR(-EINVAL);
+
+ ed = dpu->ed_priv[i];
+
+ mutex_lock(&ed->mutex);
+
+ if (ed->inuse) {
+ mutex_unlock(&ed->mutex);
+ return ERR_PTR(-EBUSY);
+ }
+
+ ed->inuse = true;
+
+ mutex_unlock(&ed->mutex);
+
+ return ed;
+}
+EXPORT_SYMBOL_GPL(dpu_ed_get);
+
+void dpu_ed_put(struct dpu_extdst *ed)
+{
+ mutex_lock(&ed->mutex);
+
+ ed->inuse = false;
+
+ mutex_unlock(&ed->mutex);
+}
+EXPORT_SYMBOL_GPL(dpu_ed_put);
+
+struct dpu_extdst *dpu_aux_ed_peek(struct dpu_extdst *ed)
+{
+ unsigned int aux_id = ed->id ^ 1;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(ed_ids); i++)
+ if (ed_ids[i] == aux_id)
+ return ed->dpu->ed_priv[i];
+
+ return NULL;
+}
+EXPORT_SYMBOL_GPL(dpu_aux_ed_peek);
+
+void _dpu_ed_init(struct dpu_soc *dpu, unsigned int id)
+{
+ struct dpu_extdst *ed;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(ed_ids); i++)
+ if (ed_ids[i] == id)
+ break;
+
+ if (WARN_ON(i == ARRAY_SIZE(ed_ids)))
+ return;
+
+ ed = dpu->ed_priv[i];
+
+ extdst_pixengcfg_src_sel(ed, ED_SRC_DISABLE);
+ extdst_pixengcfg_shden(ed, true);
+ extdst_pixengcfg_powerdown(ed, false);
+ extdst_pixengcfg_sync_mode(ed, SINGLE);
+ extdst_pixengcfg_reset(ed, false);
+ extdst_pixengcfg_div(ed, DIV_RESET);
+ extdst_shden(ed, true);
+ extdst_perfcountmode(ed, false);
+ extdst_kick_mode(ed, EXTERNAL);
+}
+
+int dpu_ed_init(struct dpu_soc *dpu, unsigned int id,
+ unsigned long pec_base, unsigned long base)
+{
+ struct dpu_extdst *ed;
+ int ret, i;
+
+ ed = devm_kzalloc(dpu->dev, sizeof(*ed), GFP_KERNEL);
+ if (!ed)
+ return -ENOMEM;
+
+ for (i = 0; i < ARRAY_SIZE(ed_ids); i++)
+ if (ed_ids[i] == id)
+ break;
+
+ if (i == ARRAY_SIZE(ed_ids))
+ return -EINVAL;
+
+ dpu->ed_priv[i] = ed;
+
+ ed->pec_base = devm_ioremap(dpu->dev, pec_base, SZ_32);
+ if (!ed->pec_base)
+ return -ENOMEM;
+
+ ed->base = devm_ioremap(dpu->dev, base, SZ_64);
+ if (!ed->base)
+ return -ENOMEM;
+
+ ed->dpu = dpu;
+ ed->id = id;
+ mutex_init(&ed->mutex);
+
+ ret = extdst_pixengcfg_src_sel(ed, ED_SRC_DISABLE);
+ if (ret < 0)
+ return ret;
+
+ _dpu_ed_init(dpu, id);
+
+ return 0;
+}
diff --git a/drivers/gpu/imx/dpu/dpu-fetchdecode.c b/drivers/gpu/imx/dpu/dpu-fetchdecode.c
new file mode 100644
index 000000000000..b329ab600f45
--- /dev/null
+++ b/drivers/gpu/imx/dpu/dpu-fetchdecode.c
@@ -0,0 +1,778 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017-2018 NXP
+ *
+ * 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/io.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/platform_device.h>
+#include <linux/types.h>
+#include <video/dpu.h>
+#include "dpu-prv.h"
+
+#define FD_NUM_V1 4
+#define FD_NUM_V2 2
+
+static const u32 fd_vproc_cap_v1[FD_NUM_V1] = {
+ DPU_VPROC_CAP_HSCALER4 | DPU_VPROC_CAP_VSCALER4 |
+ DPU_VPROC_CAP_FETCHECO0,
+ DPU_VPROC_CAP_HSCALER5 | DPU_VPROC_CAP_VSCALER5 |
+ DPU_VPROC_CAP_FETCHECO1,
+ DPU_VPROC_CAP_HSCALER4 | DPU_VPROC_CAP_VSCALER4 |
+ DPU_VPROC_CAP_FETCHECO0,
+ DPU_VPROC_CAP_HSCALER5 | DPU_VPROC_CAP_VSCALER5 |
+ DPU_VPROC_CAP_FETCHECO1,
+};
+
+static const u32 fd_vproc_cap_v2[FD_NUM_V2] = {
+ DPU_VPROC_CAP_HSCALER4 | DPU_VPROC_CAP_VSCALER4 |
+ DPU_VPROC_CAP_FETCHECO0,
+ DPU_VPROC_CAP_HSCALER5 | DPU_VPROC_CAP_VSCALER5 |
+ DPU_VPROC_CAP_FETCHECO1,
+};
+
+#define PIXENGCFG_DYNAMIC 0x8
+#define SRC_NUM_V1 3
+#define SRC_NUM_V2 4
+static const fd_dynamic_src_sel_t fd_srcs_v1[FD_NUM_V1][SRC_NUM_V1] = {
+ { FD_SRC_DISABLE, FD_SRC_FETCHECO0, FD_SRC_FETCHDECODE2 },
+ { FD_SRC_DISABLE, FD_SRC_FETCHECO1, FD_SRC_FETCHDECODE3 },
+ { FD_SRC_DISABLE, FD_SRC_FETCHECO0, FD_SRC_FETCHECO2 },
+ { FD_SRC_DISABLE, FD_SRC_FETCHECO1, FD_SRC_FETCHECO2 },
+};
+
+static const fd_dynamic_src_sel_t fd_srcs_v2[FD_NUM_V2][SRC_NUM_V2] = {
+ {
+ FD_SRC_DISABLE, FD_SRC_FETCHECO0,
+ FD_SRC_FETCHDECODE1, FD_SRC_FETCHWARP2
+ }, {
+ FD_SRC_DISABLE, FD_SRC_FETCHECO1,
+ FD_SRC_FETCHDECODE0, FD_SRC_FETCHWARP2
+ },
+};
+
+#define PIXENGCFG_STATUS 0xC
+
+#define RINGBUFSTARTADDR0 0x10
+#define RINGBUFWRAPADDR0 0x14
+#define FRAMEPROPERTIES0 0x18
+#define BASEADDRESS0 0x1C
+#define SOURCEBUFFERATTRIBUTES0 0x20
+#define SOURCEBUFFERDIMENSION0 0x24
+#define COLORCOMPONENTBITS0 0x28
+#define COLORCOMPONENTSHIFT0 0x2C
+#define LAYEROFFSET0 0x30
+#define CLIPWINDOWOFFSET0 0x34
+#define CLIPWINDOWDIMENSIONS0 0x38
+#define CONSTANTCOLOR0 0x3C
+#define LAYERPROPERTY0 0x40
+#define FRAMEDIMENSIONS 0x44
+#define FRAMERESAMPLING 0x48
+#define DECODECONTROL 0x4C
+#define SOURCEBUFFERLENGTH 0x50
+#define CONTROL 0x54
+#define CONTROLTRIGGER 0x58
+#define START 0x5C
+#define FETCHTYPE 0x60
+#define DECODERSTATUS 0x64
+#define READADDRESS0 0x68
+#define BURSTBUFFERPROPERTIES 0x6C
+#define STATUS 0x70
+#define HIDDENSTATUS 0x74
+
+static const shadow_load_req_t fd_shdlreqs[] = {
+ SHLDREQID_FETCHDECODE0, SHLDREQID_FETCHDECODE1,
+ SHLDREQID_FETCHDECODE2, SHLDREQID_FETCHDECODE3,
+};
+
+struct dpu_fetchdecode {
+ struct dpu_fetchunit fu;
+ fetchtype_t fetchtype;
+ shadow_load_req_t shdlreq;
+};
+
+int fetchdecode_pixengcfg_dynamic_src_sel(struct dpu_fetchunit *fu,
+ fd_dynamic_src_sel_t src)
+{
+ struct dpu_soc *dpu = fu->dpu;
+ const struct dpu_devtype *devtype = dpu->devtype;
+ int i;
+
+ mutex_lock(&fu->mutex);
+ if (devtype->version == DPU_V1) {
+ for (i = 0; i < SRC_NUM_V1; i++) {
+ if (fd_srcs_v1[fu->id][i] == src) {
+ dpu_pec_fu_write(fu, src, PIXENGCFG_DYNAMIC);
+ mutex_unlock(&fu->mutex);
+ return 0;
+ }
+ }
+ } else if (devtype->version == DPU_V2) {
+ const unsigned int *block_id_map = devtype->sw2hw_block_id_map;
+ u32 mapped_src;
+
+ if (WARN_ON(!block_id_map))
+ return -EINVAL;
+
+ for (i = 0; i < SRC_NUM_V2; i++) {
+ if (fd_srcs_v2[fu->id][i] == src) {
+ mapped_src = block_id_map[src];
+ if (WARN_ON(mapped_src == NA))
+ return -EINVAL;
+
+ dpu_pec_fu_write(fu, mapped_src,
+ PIXENGCFG_DYNAMIC);
+ mutex_unlock(&fu->mutex);
+ return 0;
+ }
+ }
+ } else {
+ WARN_ON(1);
+ }
+ mutex_unlock(&fu->mutex);
+
+ return -EINVAL;
+}
+EXPORT_SYMBOL_GPL(fetchdecode_pixengcfg_dynamic_src_sel);
+
+static void
+fetchdecode_set_baseaddress(struct dpu_fetchunit *fu, unsigned int width,
+ unsigned int x_offset, unsigned int y_offset,
+ unsigned int mt_w, unsigned int mt_h,
+ int bpp, dma_addr_t baddr)
+{
+ unsigned int burst_size, stride;
+ bool nonzero_mod = !!mt_w;
+
+ if (nonzero_mod) {
+ /* consider PRG x offset to calculate buffer address */
+ baddr += (x_offset % mt_w) * (bpp / 8);
+
+ /*
+ * address TKT343664:
+ * fetch unit base address has to align to burst size
+ */
+ burst_size = 1 << (ffs(baddr) - 1);
+ burst_size = round_up(burst_size, 8);
+ burst_size = min(burst_size, 128U);
+
+ stride = width * (bpp >> 3);
+ /*
+ * address TKT339017:
+ * fixup for burst size vs stride mismatch
+ */
+ stride = round_up(stride + round_up(baddr % 8, 8), burst_size);
+
+ /* consider PRG y offset to calculate buffer address */
+ baddr += (y_offset % mt_h) * stride;
+ }
+
+ mutex_lock(&fu->mutex);
+ dpu_fu_write(fu, baddr, BASEADDRESS0);
+ mutex_unlock(&fu->mutex);
+}
+
+static void fetchdecode_set_src_bpp(struct dpu_fetchunit *fu, int bpp)
+{
+ u32 val;
+
+ mutex_lock(&fu->mutex);
+ val = dpu_fu_read(fu, SOURCEBUFFERATTRIBUTES0);
+ val &= ~0x3f0000;
+ val |= BITSPERPIXEL(bpp);
+ dpu_fu_write(fu, val, SOURCEBUFFERATTRIBUTES0);
+ mutex_unlock(&fu->mutex);
+}
+
+static void
+fetchdecode_set_src_stride(struct dpu_fetchunit *fu,
+ unsigned int width, unsigned int x_offset,
+ unsigned int mt_w, int bpp, unsigned int stride,
+ dma_addr_t baddr, bool use_prefetch)
+{
+ unsigned int burst_size;
+ bool nonzero_mod = !!mt_w;
+ u32 val;
+
+ if (use_prefetch) {
+ /* consider PRG x offset to calculate buffer address */
+ if (nonzero_mod)
+ baddr += (x_offset % mt_w) * (bpp / 8);
+
+ /*
+ * address TKT343664:
+ * fetch unit base address has to align to burst size
+ */
+ burst_size = 1 << (ffs(baddr) - 1);
+ burst_size = round_up(burst_size, 8);
+ burst_size = min(burst_size, 128U);
+
+ stride = width * (bpp >> 3);
+ /*
+ * address TKT339017:
+ * fixup for burst size vs stride mismatch
+ */
+ if (nonzero_mod)
+ stride = round_up(stride + round_up(baddr % 8, 8),
+ burst_size);
+ else
+ stride = round_up(stride, burst_size);
+ }
+
+ mutex_lock(&fu->mutex);
+ val = dpu_fu_read(fu, SOURCEBUFFERATTRIBUTES0);
+ val &= ~0xffff;
+ val |= STRIDE(stride);
+ dpu_fu_write(fu, val, SOURCEBUFFERATTRIBUTES0);
+ mutex_unlock(&fu->mutex);
+}
+
+static void
+fetchdecode_set_src_buf_dimensions(struct dpu_fetchunit *fu,
+ unsigned int w, unsigned int h,
+ u32 unused, bool deinterlace)
+{
+ u32 val;
+
+ if (deinterlace)
+ h /= 2;
+
+ val = LINEWIDTH(w) | LINECOUNT(h);
+
+ mutex_lock(&fu->mutex);
+ dpu_fu_write(fu, val, SOURCEBUFFERDIMENSION0);
+ mutex_unlock(&fu->mutex);
+}
+
+static void
+fetchdecode_set_fmt(struct dpu_fetchunit *fu, u32 fmt, bool deinterlace)
+{
+ u32 val, bits, shift;
+ bool is_planar_yuv = false, is_rastermode_yuv422 = false;
+ bool is_yuv422upsamplingmode_interpolate = false;
+ bool is_inputselect_compact = false;
+ bool need_csc = false;
+ int i;
+
+ switch (fmt) {
+ case DRM_FORMAT_YUYV:
+ case DRM_FORMAT_UYVY:
+ is_rastermode_yuv422 = true;
+ is_yuv422upsamplingmode_interpolate = true;
+ need_csc = true;
+ break;
+ case DRM_FORMAT_NV16:
+ case DRM_FORMAT_NV61:
+ is_yuv422upsamplingmode_interpolate = true;
+ /* fall-through */
+ case DRM_FORMAT_NV12:
+ case DRM_FORMAT_NV21:
+ if (deinterlace)
+ is_yuv422upsamplingmode_interpolate = true;
+ is_planar_yuv = true;
+ is_rastermode_yuv422 = true;
+ is_inputselect_compact = true;
+ need_csc = true;
+ break;
+ case DRM_FORMAT_NV24:
+ case DRM_FORMAT_NV42:
+ is_planar_yuv = true;
+ is_yuv422upsamplingmode_interpolate = true;
+ is_inputselect_compact = true;
+ need_csc = true;
+ break;
+ default:
+ break;
+ }
+
+ mutex_lock(&fu->mutex);
+ val = dpu_fu_read(fu, CONTROL);
+ val &= ~YUV422UPSAMPLINGMODE_MASK;
+ val &= ~INPUTSELECT_MASK;
+ val &= ~RASTERMODE_MASK;
+ if (is_yuv422upsamplingmode_interpolate)
+ val |= YUV422UPSAMPLINGMODE(YUV422UPSAMPLINGMODE__INTERPOLATE);
+ else
+ val |= YUV422UPSAMPLINGMODE(YUV422UPSAMPLINGMODE__REPLICATE);
+ if (is_inputselect_compact)
+ val |= INPUTSELECT(INPUTSELECT__COMPPACK);
+ else
+ val |= INPUTSELECT(INPUTSELECT__INACTIVE);
+ if (is_rastermode_yuv422)
+ val |= RASTERMODE(RASTERMODE__YUV422);
+ else
+ val |= RASTERMODE(RASTERMODE__NORMAL);
+ dpu_fu_write(fu, val, CONTROL);
+
+ val = dpu_fu_read(fu, LAYERPROPERTY0);
+ val &= ~YUVCONVERSIONMODE_MASK;
+ if (need_csc)
+ /*
+ * assuming fetchdecode always ouputs RGB pixel formats
+ *
+ * FIXME:
+ * determine correct standard here - ITU601 or ITU601_FR
+ * or ITU709
+ */
+ val |= YUVCONVERSIONMODE(YUVCONVERSIONMODE__ITU601_FR);
+ else
+ val |= YUVCONVERSIONMODE(YUVCONVERSIONMODE__OFF);
+ dpu_fu_write(fu, val, LAYERPROPERTY0);
+ mutex_unlock(&fu->mutex);
+
+ for (i = 0; i < ARRAY_SIZE(dpu_pixel_format_matrix); i++) {
+ if (dpu_pixel_format_matrix[i].pixel_format == fmt) {
+ bits = dpu_pixel_format_matrix[i].bits;
+ shift = dpu_pixel_format_matrix[i].shift;
+
+ if (is_planar_yuv) {
+ bits &= ~(U_BITS_MASK | V_BITS_MASK);
+ shift &= ~(U_SHIFT_MASK | V_SHIFT_MASK);
+ }
+
+ mutex_lock(&fu->mutex);
+ dpu_fu_write(fu, bits, COLORCOMPONENTBITS0);
+ dpu_fu_write(fu, shift, COLORCOMPONENTSHIFT0);
+ mutex_unlock(&fu->mutex);
+ return;
+ }
+ }
+
+ WARN_ON(1);
+}
+
+void fetchdecode_layeroffset(struct dpu_fetchunit *fu, unsigned int x,
+ unsigned int y)
+{
+ u32 val;
+
+ val = LAYERXOFFSET(x) | LAYERYOFFSET(y);
+
+ mutex_lock(&fu->mutex);
+ dpu_fu_write(fu, val, LAYEROFFSET0);
+ mutex_unlock(&fu->mutex);
+}
+EXPORT_SYMBOL_GPL(fetchdecode_layeroffset);
+
+void fetchdecode_clipoffset(struct dpu_fetchunit *fu, unsigned int x,
+ unsigned int y)
+{
+ u32 val;
+
+ val = CLIPWINDOWXOFFSET(x) | CLIPWINDOWYOFFSET(y);
+
+ mutex_lock(&fu->mutex);
+ dpu_fu_write(fu, val, CLIPWINDOWOFFSET0);
+ mutex_unlock(&fu->mutex);
+}
+EXPORT_SYMBOL_GPL(fetchdecode_clipoffset);
+
+static void fetchdecode_enable_src_buf(struct dpu_fetchunit *fu)
+{
+ u32 val;
+
+ mutex_lock(&fu->mutex);
+ val = dpu_fu_read(fu, LAYERPROPERTY0);
+ val |= SOURCEBUFFERENABLE;
+ dpu_fu_write(fu, val, LAYERPROPERTY0);
+ mutex_unlock(&fu->mutex);
+}
+
+static void fetchdecode_disable_src_buf(struct dpu_fetchunit *fu)
+{
+ u32 val;
+
+ mutex_lock(&fu->mutex);
+ val = dpu_fu_read(fu, LAYERPROPERTY0);
+ val &= ~SOURCEBUFFERENABLE;
+ dpu_fu_write(fu, val, LAYERPROPERTY0);
+ mutex_unlock(&fu->mutex);
+}
+
+static bool fetchdecode_is_enabled(struct dpu_fetchunit *fu)
+{
+ u32 val;
+
+ mutex_lock(&fu->mutex);
+ val = dpu_fu_read(fu, LAYERPROPERTY0);
+ mutex_unlock(&fu->mutex);
+
+ return !!(val & SOURCEBUFFERENABLE);
+}
+
+void fetchdecode_clipdimensions(struct dpu_fetchunit *fu, unsigned int w,
+ unsigned int h)
+{
+ u32 val;
+
+ val = CLIPWINDOWWIDTH(w) | CLIPWINDOWHEIGHT(h);
+
+ mutex_lock(&fu->mutex);
+ dpu_fu_write(fu, val, CLIPWINDOWDIMENSIONS0);
+ mutex_unlock(&fu->mutex);
+}
+EXPORT_SYMBOL_GPL(fetchdecode_clipdimensions);
+
+static void
+fetchdecode_set_framedimensions(struct dpu_fetchunit *fu,
+ unsigned int w, unsigned int h,
+ bool deinterlace)
+{
+ u32 val;
+
+ if (deinterlace)
+ h /= 2;
+
+ val = FRAMEWIDTH(w) | FRAMEHEIGHT(h);
+
+ mutex_lock(&fu->mutex);
+ dpu_fu_write(fu, val, FRAMEDIMENSIONS);
+ mutex_unlock(&fu->mutex);
+}
+
+void fetchdecode_rgb_constantcolor(struct dpu_fetchunit *fu,
+ u8 r, u8 g, u8 b, u8 a)
+{
+ u32 val;
+
+ val = rgb_color(r, g, b, a);
+
+ mutex_lock(&fu->mutex);
+ dpu_fu_write(fu, val, CONSTANTCOLOR0);
+ mutex_unlock(&fu->mutex);
+}
+EXPORT_SYMBOL_GPL(fetchdecode_rgb_constantcolor);
+
+void fetchdecode_yuv_constantcolor(struct dpu_fetchunit *fu, u8 y, u8 u, u8 v)
+{
+ u32 val;
+
+ val = yuv_color(y, u, v);
+
+ mutex_lock(&fu->mutex);
+ dpu_fu_write(fu, val, CONSTANTCOLOR0);
+ mutex_unlock(&fu->mutex);
+}
+EXPORT_SYMBOL_GPL(fetchdecode_yuv_constantcolor);
+
+static void fetchdecode_set_controltrigger(struct dpu_fetchunit *fu)
+{
+ mutex_lock(&fu->mutex);
+ dpu_fu_write(fu, SHDTOKGEN, CONTROLTRIGGER);
+ mutex_unlock(&fu->mutex);
+}
+
+int fetchdecode_fetchtype(struct dpu_fetchunit *fu, fetchtype_t *type)
+{
+ struct dpu_soc *dpu = fu->dpu;
+ u32 val;
+
+ mutex_lock(&fu->mutex);
+ val = dpu_fu_read(fu, FETCHTYPE);
+ val &= FETCHTYPE_MASK;
+ mutex_unlock(&fu->mutex);
+
+ switch (val) {
+ case FETCHTYPE__DECODE:
+ dev_dbg(dpu->dev, "FetchDecode%d with RL and RLAD decoder\n",
+ fu->id);
+ break;
+ case FETCHTYPE__LAYER:
+ dev_dbg(dpu->dev, "FetchDecode%d with fractional "
+ "plane(8 layers)\n", fu->id);
+ break;
+ case FETCHTYPE__WARP:
+ dev_dbg(dpu->dev, "FetchDecode%d with arbitrary warping and "
+ "fractional plane(8 layers)\n", fu->id);
+ break;
+ case FETCHTYPE__ECO:
+ dev_dbg(dpu->dev, "FetchDecode%d with minimum feature set for "
+ "alpha, chroma and coordinate planes\n",
+ fu->id);
+ break;
+ case FETCHTYPE__PERSP:
+ dev_dbg(dpu->dev, "FetchDecode%d with affine, perspective and "
+ "arbitrary warping\n", fu->id);
+ break;
+ case FETCHTYPE__ROT:
+ dev_dbg(dpu->dev, "FetchDecode%d with affine and arbitrary "
+ "warping\n", fu->id);
+ break;
+ case FETCHTYPE__DECODEL:
+ dev_dbg(dpu->dev, "FetchDecode%d with RL and RLAD decoder, "
+ "reduced feature set\n", fu->id);
+ break;
+ case FETCHTYPE__LAYERL:
+ dev_dbg(dpu->dev, "FetchDecode%d with fractional "
+ "plane(8 layers), reduced feature set\n",
+ fu->id);
+ break;
+ case FETCHTYPE__ROTL:
+ dev_dbg(dpu->dev, "FetchDecode%d with affine and arbitrary "
+ "warping, reduced feature set\n", fu->id);
+ break;
+ default:
+ dev_warn(dpu->dev, "Invalid fetch type %u for FetchDecode%d\n",
+ val, fu->id);
+ return -EINVAL;
+ }
+
+ *type = val;
+ return 0;
+}
+EXPORT_SYMBOL_GPL(fetchdecode_fetchtype);
+
+shadow_load_req_t fetchdecode_to_shdldreq_t(struct dpu_fetchunit *fu)
+{
+ shadow_load_req_t t = 0;
+
+ switch (fu->id) {
+ case 0:
+ t = SHLDREQID_FETCHDECODE0;
+ break;
+ case 1:
+ t = SHLDREQID_FETCHDECODE1;
+ break;
+ case 2:
+ t = SHLDREQID_FETCHDECODE2;
+ break;
+ case 3:
+ t = SHLDREQID_FETCHDECODE3;
+ break;
+ default:
+ break;
+ }
+
+ return t;
+}
+EXPORT_SYMBOL_GPL(fetchdecode_to_shdldreq_t);
+
+u32 fetchdecode_get_vproc_mask(struct dpu_fetchunit *fu)
+{
+ struct dpu_soc *dpu = fu->dpu;
+ const struct dpu_devtype *devtype = dpu->devtype;
+
+ return devtype->version == DPU_V1 ?
+ fd_vproc_cap_v1[fu->id] : fd_vproc_cap_v2[fu->id];
+}
+EXPORT_SYMBOL_GPL(fetchdecode_get_vproc_mask);
+
+struct dpu_fetchunit *fetchdecode_get_fetcheco(struct dpu_fetchunit *fu)
+{
+ struct dpu_soc *dpu = fu->dpu;
+
+ switch (fu->id) {
+ case 0:
+ case 1:
+ return dpu->fe_priv[fu->id];
+ case 2:
+ case 3:
+ /* TODO: for DPU v1, add FetchEco2 support */
+ return dpu->fe_priv[fu->id - 2];
+ default:
+ WARN_ON(1);
+ }
+
+ return ERR_PTR(-EINVAL);
+}
+EXPORT_SYMBOL_GPL(fetchdecode_get_fetcheco);
+
+bool fetchdecode_need_fetcheco(struct dpu_fetchunit *fu, u32 fmt)
+{
+ struct dpu_fetchunit *fe = fetchdecode_get_fetcheco(fu);
+
+ if (IS_ERR_OR_NULL(fe))
+ return false;
+
+ switch (fmt) {
+ case DRM_FORMAT_NV12:
+ case DRM_FORMAT_NV21:
+ case DRM_FORMAT_NV16:
+ case DRM_FORMAT_NV61:
+ case DRM_FORMAT_NV24:
+ case DRM_FORMAT_NV42:
+ return true;
+ }
+
+ return false;
+}
+EXPORT_SYMBOL_GPL(fetchdecode_need_fetcheco);
+
+struct dpu_hscaler *fetchdecode_get_hscaler(struct dpu_fetchunit *fu)
+{
+ struct dpu_soc *dpu = fu->dpu;
+
+ switch (fu->id) {
+ case 0:
+ case 2:
+ return dpu->hs_priv[0];
+ case 1:
+ case 3:
+ return dpu->hs_priv[1];
+ default:
+ WARN_ON(1);
+ }
+
+ return ERR_PTR(-EINVAL);
+}
+EXPORT_SYMBOL_GPL(fetchdecode_get_hscaler);
+
+struct dpu_vscaler *fetchdecode_get_vscaler(struct dpu_fetchunit *fu)
+{
+ struct dpu_soc *dpu = fu->dpu;
+
+ switch (fu->id) {
+ case 0:
+ case 2:
+ return dpu->vs_priv[0];
+ case 1:
+ case 3:
+ return dpu->vs_priv[1];
+ default:
+ WARN_ON(1);
+ }
+
+ return ERR_PTR(-EINVAL);
+}
+EXPORT_SYMBOL_GPL(fetchdecode_get_vscaler);
+
+struct dpu_fetchunit *dpu_fd_get(struct dpu_soc *dpu, int id)
+{
+ struct dpu_fetchunit *fu;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(fd_ids); i++)
+ if (fd_ids[i] == id)
+ break;
+
+ if (i == ARRAY_SIZE(fd_ids))
+ return ERR_PTR(-EINVAL);
+
+ fu = dpu->fd_priv[i];
+
+ mutex_lock(&fu->mutex);
+
+ if (fu->inuse) {
+ mutex_unlock(&fu->mutex);
+ return ERR_PTR(-EBUSY);
+ }
+
+ fu->inuse = true;
+
+ mutex_unlock(&fu->mutex);
+
+ return fu;
+}
+EXPORT_SYMBOL_GPL(dpu_fd_get);
+
+void dpu_fd_put(struct dpu_fetchunit *fu)
+{
+ mutex_lock(&fu->mutex);
+
+ fu->inuse = false;
+
+ mutex_unlock(&fu->mutex);
+}
+EXPORT_SYMBOL_GPL(dpu_fd_put);
+
+static const struct dpu_fetchunit_ops fd_ops = {
+ .set_burstlength = fetchunit_set_burstlength,
+ .set_baseaddress = fetchdecode_set_baseaddress,
+ .set_src_bpp = fetchdecode_set_src_bpp,
+ .set_src_stride = fetchdecode_set_src_stride,
+ .set_src_buf_dimensions = fetchdecode_set_src_buf_dimensions,
+ .set_fmt = fetchdecode_set_fmt,
+ .enable_src_buf = fetchdecode_enable_src_buf,
+ .disable_src_buf = fetchdecode_disable_src_buf,
+ .is_enabled = fetchdecode_is_enabled,
+ .set_framedimensions = fetchdecode_set_framedimensions,
+ .set_controltrigger = fetchdecode_set_controltrigger,
+ .get_stream_id = fetchunit_get_stream_id,
+ .set_stream_id = fetchunit_set_stream_id,
+ .pin_off = fetchunit_pin_off,
+ .unpin_off = fetchunit_unpin_off,
+ .is_pinned_off = fetchunit_is_pinned_off,
+};
+
+void _dpu_fd_init(struct dpu_soc *dpu, unsigned int id)
+{
+ struct dpu_fetchunit *fu;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(fd_ids); i++)
+ if (fd_ids[i] == id)
+ break;
+
+ if (WARN_ON(i == ARRAY_SIZE(fd_ids)))
+ return;
+
+ fu = dpu->fd_priv[i];
+
+ fetchdecode_pixengcfg_dynamic_src_sel(fu, FD_SRC_DISABLE);
+ fetchunit_baddr_autoupdate(fu, 0x0);
+ fetchunit_shden(fu, true);
+
+ mutex_lock(&fu->mutex);
+ dpu_fu_write(fu, SETNUMBUFFERS(16) | SETBURSTLENGTH(16),
+ BURSTBUFFERMANAGEMENT);
+ mutex_unlock(&fu->mutex);
+}
+
+int dpu_fd_init(struct dpu_soc *dpu, unsigned int id,
+ unsigned long pec_base, unsigned long base)
+{
+ struct dpu_fetchdecode *fd;
+ struct dpu_fetchunit *fu;
+ int ret, i;
+
+ fd = devm_kzalloc(dpu->dev, sizeof(*fd), GFP_KERNEL);
+ if (!fd)
+ return -ENOMEM;
+
+ fu = &fd->fu;
+ dpu->fd_priv[id] = fu;
+
+ fu->pec_base = devm_ioremap(dpu->dev, pec_base, SZ_16);
+ if (!fu->pec_base)
+ return -ENOMEM;
+
+ fu->base = devm_ioremap(dpu->dev, base, SZ_1K);
+ if (!fu->base)
+ return -ENOMEM;
+
+ fu->dpu = dpu;
+ fu->id = id;
+ fu->type = FU_T_FD;
+ fu->ops = &fd_ops;
+ fu->name = "fetchdecode";
+ for (i = 0; i < ARRAY_SIZE(fd_ids); i++) {
+ if (fd_ids[i] == id) {
+ fd->shdlreq = fd_shdlreqs[i];
+ break;
+ }
+ }
+ mutex_init(&fu->mutex);
+
+ ret = fetchdecode_pixengcfg_dynamic_src_sel(fu, FD_SRC_DISABLE);
+ if (ret < 0)
+ return ret;
+
+ ret = fetchdecode_fetchtype(fu, &fd->fetchtype);
+ if (ret < 0)
+ return ret;
+
+ _dpu_fd_init(dpu, id);
+
+ return 0;
+}
diff --git a/drivers/gpu/imx/dpu/dpu-fetcheco.c b/drivers/gpu/imx/dpu/dpu-fetcheco.c
new file mode 100644
index 000000000000..e1f3708a6b80
--- /dev/null
+++ b/drivers/gpu/imx/dpu/dpu-fetcheco.c
@@ -0,0 +1,434 @@
+/*
+ * Copyright 2017-2018 NXP
+ *
+ * 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/io.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/platform_device.h>
+#include <linux/types.h>
+#include <video/dpu.h>
+#include "dpu-prv.h"
+
+#define BASEADDRESS0 0x10
+#define SOURCEBUFFERATTRIBUTES0 0x14
+#define SOURCEBUFFERDIMENSION0 0x18
+#define COLORCOMPONENTBITS0 0x1C
+#define COLORCOMPONENTSHIFT0 0x20
+#define LAYEROFFSET0 0x24
+#define CLIPWINDOWOFFSET0 0x28
+#define CLIPWINDOWDIMENSIONS0 0x2C
+#define CONSTANTCOLOR0 0x30
+#define LAYERPROPERTY0 0x34
+#define FRAMEDIMENSIONS 0x38
+#define FRAMERESAMPLING 0x3C
+#define CONTROL 0x40
+#define CONTROLTRIGGER 0x44
+#define START 0x48
+#define FETCHTYPE 0x4C
+#define BURSTBUFFERPROPERTIES 0x50
+#define HIDDENSTATUS 0x54
+
+struct dpu_fetcheco {
+ struct dpu_fetchunit fu;
+};
+
+static void
+fetcheco_set_src_buf_dimensions(struct dpu_fetchunit *fu,
+ unsigned int w, unsigned int h,
+ u32 fmt, bool deinterlace)
+{
+ int width, height;
+ u32 val;
+
+ if (deinterlace) {
+ width = w;
+ height = h / 2;
+ } else {
+ width = dpu_format_plane_width(w, fmt, 1);
+ height = dpu_format_plane_height(h, fmt, 1);
+ }
+
+ switch (fmt) {
+ case DRM_FORMAT_NV12:
+ case DRM_FORMAT_NV21:
+ case DRM_FORMAT_NV16:
+ case DRM_FORMAT_NV61:
+ case DRM_FORMAT_NV24:
+ case DRM_FORMAT_NV42:
+ break;
+ default:
+ WARN(1, "Unsupported FetchEco pixel format 0x%08x\n", fmt);
+ return;
+ }
+
+ val = LINEWIDTH(width) | LINECOUNT(height);
+
+ mutex_lock(&fu->mutex);
+ dpu_fu_write(fu, val, SOURCEBUFFERDIMENSION0);
+ mutex_unlock(&fu->mutex);
+}
+
+static void fetcheco_set_fmt(struct dpu_fetchunit *fu, u32 fmt, bool unused)
+{
+ u32 val, bits, shift;
+ int i, hsub, vsub;
+ unsigned int x, y;
+
+ switch (fmt) {
+ case DRM_FORMAT_NV12:
+ case DRM_FORMAT_NV21:
+ case DRM_FORMAT_NV16:
+ case DRM_FORMAT_NV61:
+ case DRM_FORMAT_NV24:
+ case DRM_FORMAT_NV42:
+ break;
+ default:
+ WARN(1, "Unsupported FetchEco pixel format 0x%08x\n", fmt);
+ return;
+ }
+
+ hsub = dpu_format_horz_chroma_subsampling(fmt);
+ switch (hsub) {
+ case 1:
+ x = 0x4;
+ break;
+ case 2:
+ x = 0x2;
+ break;
+ default:
+ WARN_ON(1);
+ return;
+ }
+
+ vsub = dpu_format_vert_chroma_subsampling(fmt);
+ switch (vsub) {
+ case 1:
+ y = 0x4;
+ break;
+ case 2:
+ y = 0x2;
+ break;
+ default:
+ WARN_ON(1);
+ return;
+ }
+
+ mutex_lock(&fu->mutex);
+ val = dpu_fu_read(fu, FRAMERESAMPLING);
+ val &= ~(DELTAX_MASK | DELTAY_MASK);
+ val |= DELTAX(x) | DELTAY(y);
+ dpu_fu_write(fu, val, FRAMERESAMPLING);
+
+ val = dpu_fu_read(fu, CONTROL);
+ val &= ~RASTERMODE_MASK;
+ val |= RASTERMODE(RASTERMODE__NORMAL);
+ dpu_fu_write(fu, val, CONTROL);
+ mutex_unlock(&fu->mutex);
+
+ for (i = 0; i < ARRAY_SIZE(dpu_pixel_format_matrix); i++) {
+ if (dpu_pixel_format_matrix[i].pixel_format == fmt) {
+ bits = dpu_pixel_format_matrix[i].bits;
+ shift = dpu_pixel_format_matrix[i].shift;
+
+ bits &= ~Y_BITS_MASK;
+ shift &= ~Y_SHIFT_MASK;
+
+ mutex_lock(&fu->mutex);
+ dpu_fu_write(fu, bits, COLORCOMPONENTBITS0);
+ dpu_fu_write(fu, shift, COLORCOMPONENTSHIFT0);
+ mutex_unlock(&fu->mutex);
+ return;
+ }
+ }
+
+ WARN_ON(1);
+}
+
+void fetcheco_layeroffset(struct dpu_fetchunit *fu, unsigned int x,
+ unsigned int y)
+{
+ u32 val;
+
+ val = LAYERXOFFSET(x) | LAYERYOFFSET(y);
+
+ mutex_lock(&fu->mutex);
+ dpu_fu_write(fu, val, LAYEROFFSET0);
+ mutex_unlock(&fu->mutex);
+}
+EXPORT_SYMBOL_GPL(fetcheco_layeroffset);
+
+void fetcheco_clipoffset(struct dpu_fetchunit *fu, unsigned int x,
+ unsigned int y)
+{
+ u32 val;
+
+ val = CLIPWINDOWXOFFSET(x) | CLIPWINDOWYOFFSET(y);
+
+ mutex_lock(&fu->mutex);
+ dpu_fu_write(fu, val, CLIPWINDOWOFFSET0);
+ mutex_unlock(&fu->mutex);
+}
+EXPORT_SYMBOL_GPL(fetcheco_clipoffset);
+
+void fetcheco_clipdimensions(struct dpu_fetchunit *fu, unsigned int w,
+ unsigned int h)
+{
+ u32 val;
+
+ val = CLIPWINDOWWIDTH(w) | CLIPWINDOWHEIGHT(h);
+
+ mutex_lock(&fu->mutex);
+ dpu_fu_write(fu, val, CLIPWINDOWDIMENSIONS0);
+ mutex_unlock(&fu->mutex);
+}
+EXPORT_SYMBOL_GPL(fetcheco_clipdimensions);
+
+static void
+fetcheco_set_framedimensions(struct dpu_fetchunit *fu,
+ unsigned int w, unsigned int h,
+ bool deinterlace)
+{
+ u32 val;
+
+ if (deinterlace)
+ h /= 2;
+
+ val = FRAMEWIDTH(w) | FRAMEHEIGHT(h);
+
+ mutex_lock(&fu->mutex);
+ dpu_fu_write(fu, val, FRAMEDIMENSIONS);
+ mutex_unlock(&fu->mutex);
+}
+
+void fetcheco_frameresampling(struct dpu_fetchunit *fu, unsigned int x,
+ unsigned int y)
+{
+ u32 val;
+
+ mutex_lock(&fu->mutex);
+ val = dpu_fu_read(fu, FRAMERESAMPLING);
+ val &= ~(DELTAX_MASK | DELTAY_MASK);
+ val |= DELTAX(x) | DELTAY(y);
+ dpu_fu_write(fu, val, FRAMERESAMPLING);
+ mutex_unlock(&fu->mutex);
+}
+EXPORT_SYMBOL_GPL(fetcheco_frameresampling);
+
+static void fetcheco_set_controltrigger(struct dpu_fetchunit *fu)
+{
+ mutex_lock(&fu->mutex);
+ dpu_fu_write(fu, SHDTOKGEN, CONTROLTRIGGER);
+ mutex_unlock(&fu->mutex);
+}
+
+int fetcheco_fetchtype(struct dpu_fetchunit *fu, fetchtype_t *type)
+{
+ struct dpu_soc *dpu = fu->dpu;
+ u32 val;
+
+ mutex_lock(&fu->mutex);
+ val = dpu_fu_read(fu, FETCHTYPE);
+ val &= FETCHTYPE_MASK;
+ mutex_unlock(&fu->mutex);
+
+ switch (val) {
+ case FETCHTYPE__DECODE:
+ dev_dbg(dpu->dev, "FetchEco%d with RL and RLAD decoder\n",
+ fu->id);
+ break;
+ case FETCHTYPE__LAYER:
+ dev_dbg(dpu->dev, "FetchEco%d with fractional "
+ "plane(8 layers)\n", fu->id);
+ break;
+ case FETCHTYPE__WARP:
+ dev_dbg(dpu->dev, "FetchEco%d with arbitrary warping and "
+ "fractional plane(8 layers)\n", fu->id);
+ break;
+ case FETCHTYPE__ECO:
+ dev_dbg(dpu->dev, "FetchEco%d with minimum feature set for "
+ "alpha, chroma and coordinate planes\n",
+ fu->id);
+ break;
+ case FETCHTYPE__PERSP:
+ dev_dbg(dpu->dev, "FetchEco%d with affine, perspective and "
+ "arbitrary warping\n", fu->id);
+ break;
+ case FETCHTYPE__ROT:
+ dev_dbg(dpu->dev, "FetchEco%d with affine and arbitrary "
+ "warping\n", fu->id);
+ break;
+ case FETCHTYPE__DECODEL:
+ dev_dbg(dpu->dev, "FetchEco%d with RL and RLAD decoder, "
+ "reduced feature set\n", fu->id);
+ break;
+ case FETCHTYPE__LAYERL:
+ dev_dbg(dpu->dev, "FetchEco%d with fractional "
+ "plane(8 layers), reduced feature set\n",
+ fu->id);
+ break;
+ case FETCHTYPE__ROTL:
+ dev_dbg(dpu->dev, "FetchEco%d with affine and arbitrary "
+ "warping, reduced feature set\n", fu->id);
+ break;
+ default:
+ dev_warn(dpu->dev, "Invalid fetch type %u for FetchEco%d\n",
+ val, fu->id);
+ return -EINVAL;
+ }
+
+ *type = val;
+ return 0;
+}
+EXPORT_SYMBOL_GPL(fetcheco_fetchtype);
+
+dpu_block_id_t fetcheco_get_block_id(struct dpu_fetchunit *fu)
+{
+ switch (fu->id) {
+ case 0:
+ return ID_FETCHECO0;
+ case 1:
+ return ID_FETCHECO1;
+ case 2:
+ return ID_FETCHECO2;
+ case 9:
+ return ID_FETCHECO9;
+ default:
+ WARN_ON(1);
+ }
+
+ return ID_NONE;
+}
+EXPORT_SYMBOL_GPL(fetcheco_get_block_id);
+
+struct dpu_fetchunit *dpu_fe_get(struct dpu_soc *dpu, int id)
+{
+ struct dpu_fetchunit *fu;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(fe_ids); i++)
+ if (fe_ids[i] == id)
+ break;
+
+ if (i == ARRAY_SIZE(fe_ids))
+ return ERR_PTR(-EINVAL);
+
+ fu = dpu->fe_priv[i];
+
+ mutex_lock(&fu->mutex);
+
+ if (fu->inuse) {
+ mutex_unlock(&fu->mutex);
+ return ERR_PTR(-EBUSY);
+ }
+
+ fu->inuse = true;
+
+ mutex_unlock(&fu->mutex);
+
+ return fu;
+}
+EXPORT_SYMBOL_GPL(dpu_fe_get);
+
+void dpu_fe_put(struct dpu_fetchunit *fu)
+{
+ mutex_lock(&fu->mutex);
+
+ fu->inuse = false;
+
+ mutex_unlock(&fu->mutex);
+}
+EXPORT_SYMBOL_GPL(dpu_fe_put);
+
+static const struct dpu_fetchunit_ops fe_ops = {
+ .set_burstlength = fetchunit_set_burstlength,
+ .set_baseaddress = fetchunit_set_baseaddress,
+ .set_src_bpp = fetchunit_set_src_bpp,
+ .set_src_stride = fetchunit_set_src_stride,
+ .set_src_buf_dimensions = fetcheco_set_src_buf_dimensions,
+ .set_fmt = fetcheco_set_fmt,
+ .enable_src_buf = fetchunit_enable_src_buf,
+ .disable_src_buf = fetchunit_disable_src_buf,
+ .is_enabled = fetchunit_is_enabled,
+ .set_framedimensions = fetcheco_set_framedimensions,
+ .set_controltrigger = fetcheco_set_controltrigger,
+ .get_stream_id = fetchunit_get_stream_id,
+ .set_stream_id = fetchunit_set_stream_id,
+ .pin_off = fetchunit_pin_off,
+ .unpin_off = fetchunit_unpin_off,
+ .is_pinned_off = fetchunit_is_pinned_off,
+};
+
+void _dpu_fe_init(struct dpu_soc *dpu, unsigned int id)
+{
+ struct dpu_fetchunit *fu;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(fe_ids); i++)
+ if (fe_ids[i] == id)
+ break;
+
+ if (WARN_ON(i == ARRAY_SIZE(fe_ids)))
+ return;
+
+ fu = dpu->fe_priv[i];
+
+ fetchunit_shden(fu, true);
+
+ mutex_lock(&fu->mutex);
+ dpu_fu_write(fu, SETNUMBUFFERS(16) | SETBURSTLENGTH(16),
+ BURSTBUFFERMANAGEMENT);
+ mutex_unlock(&fu->mutex);
+}
+
+int dpu_fe_init(struct dpu_soc *dpu, unsigned int id,
+ unsigned long pec_base, unsigned long base)
+{
+ struct dpu_fetcheco *fe;
+ struct dpu_fetchunit *fu;
+ int i;
+
+ fe = devm_kzalloc(dpu->dev, sizeof(*fe), GFP_KERNEL);
+ if (!fe)
+ return -ENOMEM;
+
+ for (i = 0; i < ARRAY_SIZE(fe_ids); i++)
+ if (fe_ids[i] == id)
+ break;
+
+ if (i == ARRAY_SIZE(fe_ids))
+ return -EINVAL;
+
+ fu = &fe->fu;
+ dpu->fe_priv[i] = fu;
+
+ fu->pec_base = devm_ioremap(dpu->dev, pec_base, SZ_16);
+ if (!fu->pec_base)
+ return -ENOMEM;
+
+ fu->base = devm_ioremap(dpu->dev, base, SZ_128);
+ if (!fu->base)
+ return -ENOMEM;
+
+ fu->dpu = dpu;
+ fu->id = id;
+ fu->type = FU_T_FE;
+ fu->ops = &fe_ops;
+ fu->name = "fetcheco";
+
+ mutex_init(&fu->mutex);
+
+ _dpu_fe_init(dpu, id);
+
+ return 0;
+}
diff --git a/drivers/gpu/imx/dpu/dpu-fetchlayer.c b/drivers/gpu/imx/dpu/dpu-fetchlayer.c
new file mode 100644
index 000000000000..74624136312d
--- /dev/null
+++ b/drivers/gpu/imx/dpu/dpu-fetchlayer.c
@@ -0,0 +1,330 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017-2018 NXP
+ *
+ * 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/io.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/platform_device.h>
+#include <linux/types.h>
+#include <video/dpu.h>
+#include "dpu-prv.h"
+
+#define PIXENGCFG_STATUS 0x8
+#define BASEADDRESS(n) (0x10 + (n) * 0x28)
+#define SOURCEBUFFERATTRIBUTES(n) (0x14 + (n) * 0x28)
+#define SOURCEBUFFERDIMENSION(n) (0x18 + (n) * 0x28)
+#define COLORCOMPONENTBITS(n) (0x1C + (n) * 0x28)
+#define COLORCOMPONENTSHIFT(n) (0x20 + (n) * 0x28)
+#define LAYEROFFSET(n) (0x24 + (n) * 0x28)
+#define CLIPWINDOWOFFSET(n) (0x28 + (n) * 0x28)
+#define CLIPWINDOWDIMENSIONS(n) (0x2C + (n) * 0x28)
+#define CONSTANTCOLOR(n) (0x30 + (n) * 0x28)
+#define LAYERPROPERTY(n) (0x34 + (n) * 0x28)
+#define FRAMEDIMENSIONS 0x150
+#define FRAMERESAMPLING 0x154
+#define CONTROL 0x158
+#define TRIGGERENABLE 0x15C
+#define SHDLDREQ(lm) ((lm) & 0xFF)
+#define CONTROLTRIGGER 0x160
+#define START 0x164
+#define FETCHTYPE 0x168
+#define BURSTBUFFERPROPERTIES 0x16C
+#define STATUS 0x170
+#define HIDDENSTATUS 0x174
+
+static const shadow_load_req_t fl_shdlreqs[] = {
+ SHLDREQID_FETCHLAYER0, SHLDREQID_FETCHLAYER1,
+};
+
+struct dpu_fetchlayer {
+ struct dpu_fetchunit fu;
+ fetchtype_t fetchtype;
+ shadow_load_req_t shdlreq;
+};
+
+static void
+fetchlayer_set_src_buf_dimensions(struct dpu_fetchunit *fu,
+ unsigned int w, unsigned int h,
+ u32 unused1, bool unused2)
+{
+ u32 val;
+
+ val = LINEWIDTH(w) | LINECOUNT(h);
+
+ mutex_lock(&fu->mutex);
+ dpu_fu_write(fu, val, SOURCEBUFFERDIMENSION(fu->sub_id));
+ mutex_unlock(&fu->mutex);
+}
+
+static void fetchlayer_set_fmt(struct dpu_fetchunit *fu, u32 fmt, bool unused)
+{
+ u32 val, bits, shift;
+ int i, sub_id = fu->sub_id;
+
+ mutex_lock(&fu->mutex);
+ val = dpu_fu_read(fu, LAYERPROPERTY(sub_id));
+ val &= ~YUVCONVERSIONMODE_MASK;
+ val |= YUVCONVERSIONMODE(YUVCONVERSIONMODE__OFF);
+ dpu_fu_write(fu, val, LAYERPROPERTY(sub_id));
+ mutex_unlock(&fu->mutex);
+
+ for (i = 0; i < ARRAY_SIZE(dpu_pixel_format_matrix); i++) {
+ if (dpu_pixel_format_matrix[i].pixel_format == fmt) {
+ bits = dpu_pixel_format_matrix[i].bits;
+ shift = dpu_pixel_format_matrix[i].shift;
+
+ mutex_lock(&fu->mutex);
+ dpu_fu_write(fu, bits, COLORCOMPONENTBITS(sub_id));
+ dpu_fu_write(fu, shift, COLORCOMPONENTSHIFT(sub_id));
+ mutex_unlock(&fu->mutex);
+ return;
+ }
+ }
+
+ WARN_ON(1);
+}
+
+static void
+fetchlayer_set_framedimensions(struct dpu_fetchunit *fu, unsigned int w,
+ unsigned int h, bool unused)
+{
+ u32 val;
+
+ val = FRAMEWIDTH(w) | FRAMEHEIGHT(h);
+
+ mutex_lock(&fu->mutex);
+ dpu_fu_write(fu, val, FRAMEDIMENSIONS);
+ mutex_unlock(&fu->mutex);
+}
+
+void fetchlayer_rgb_constantcolor(struct dpu_fetchunit *fu,
+ u8 r, u8 g, u8 b, u8 a)
+{
+ u32 val;
+
+ val = rgb_color(r, g, b, a);
+
+ mutex_lock(&fu->mutex);
+ dpu_fu_write(fu, val, CONSTANTCOLOR(fu->id));
+ mutex_unlock(&fu->mutex);
+}
+EXPORT_SYMBOL_GPL(fetchlayer_rgb_constantcolor);
+
+void fetchlayer_yuv_constantcolor(struct dpu_fetchunit *fu, u8 y, u8 u, u8 v)
+{
+ u32 val;
+
+ val = yuv_color(y, u, v);
+
+ mutex_lock(&fu->mutex);
+ dpu_fu_write(fu, val, CONSTANTCOLOR(fu->id));
+ mutex_unlock(&fu->mutex);
+}
+EXPORT_SYMBOL_GPL(fetchlayer_yuv_constantcolor);
+
+static void fetchlayer_set_controltrigger(struct dpu_fetchunit *fu)
+{
+ mutex_lock(&fu->mutex);
+ dpu_fu_write(fu, SHDTOKGEN, CONTROLTRIGGER);
+ mutex_unlock(&fu->mutex);
+}
+
+int fetchlayer_fetchtype(struct dpu_fetchunit *fu, fetchtype_t *type)
+{
+ struct dpu_soc *dpu = fu->dpu;
+ u32 val;
+
+ mutex_lock(&fu->mutex);
+ val = dpu_fu_read(fu, FETCHTYPE);
+ val &= FETCHTYPE_MASK;
+ mutex_unlock(&fu->mutex);
+
+ switch (val) {
+ case FETCHTYPE__DECODE:
+ dev_dbg(dpu->dev, "FetchLayer%d with RL and RLAD decoder\n",
+ fu->id);
+ break;
+ case FETCHTYPE__LAYER:
+ dev_dbg(dpu->dev, "FetchLayer%d with fractional "
+ "plane(8 layers)\n", fu->id);
+ break;
+ case FETCHTYPE__WARP:
+ dev_dbg(dpu->dev, "FetchLayer%d with arbitrary warping and "
+ "fractional plane(8 layers)\n", fu->id);
+ break;
+ case FETCHTYPE__ECO:
+ dev_dbg(dpu->dev, "FetchLayer%d with minimum feature set for "
+ "alpha, chroma and coordinate planes\n",
+ fu->id);
+ break;
+ case FETCHTYPE__PERSP:
+ dev_dbg(dpu->dev, "FetchLayer%d with affine, perspective and "
+ "arbitrary warping\n", fu->id);
+ break;
+ case FETCHTYPE__ROT:
+ dev_dbg(dpu->dev, "FetchLayer%d with affine and arbitrary "
+ "warping\n", fu->id);
+ break;
+ case FETCHTYPE__DECODEL:
+ dev_dbg(dpu->dev, "FetchLayer%d with RL and RLAD decoder, "
+ "reduced feature set\n", fu->id);
+ break;
+ case FETCHTYPE__LAYERL:
+ dev_dbg(dpu->dev, "FetchLayer%d with fractional "
+ "plane(8 layers), reduced feature set\n",
+ fu->id);
+ break;
+ case FETCHTYPE__ROTL:
+ dev_dbg(dpu->dev, "FetchLayer%d with affine and arbitrary "
+ "warping, reduced feature set\n", fu->id);
+ break;
+ default:
+ dev_warn(dpu->dev, "Invalid fetch type %u for FetchLayer%d\n",
+ val, fu->id);
+ return -EINVAL;
+ }
+
+ *type = val;
+ return 0;
+}
+EXPORT_SYMBOL_GPL(fetchlayer_fetchtype);
+
+struct dpu_fetchunit *dpu_fl_get(struct dpu_soc *dpu, int id)
+{
+ struct dpu_fetchunit *fu;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(fl_ids); i++)
+ if (fl_ids[i] == id)
+ break;
+
+ if (i == ARRAY_SIZE(fl_ids))
+ return ERR_PTR(-EINVAL);
+
+ fu = dpu->fl_priv[i];
+
+ mutex_lock(&fu->mutex);
+
+ if (fu->inuse) {
+ mutex_unlock(&fu->mutex);
+ return ERR_PTR(-EBUSY);
+ }
+
+ fu->inuse = true;
+
+ mutex_unlock(&fu->mutex);
+
+ return fu;
+}
+EXPORT_SYMBOL_GPL(dpu_fl_get);
+
+void dpu_fl_put(struct dpu_fetchunit *fu)
+{
+ mutex_lock(&fu->mutex);
+
+ fu->inuse = false;
+
+ mutex_unlock(&fu->mutex);
+}
+EXPORT_SYMBOL_GPL(dpu_fl_put);
+
+static const struct dpu_fetchunit_ops fl_ops = {
+ .set_burstlength = fetchunit_set_burstlength,
+ .set_baseaddress = fetchunit_set_baseaddress,
+ .set_src_bpp = fetchunit_set_src_bpp,
+ .set_src_stride = fetchunit_set_src_stride,
+ .set_src_buf_dimensions = fetchlayer_set_src_buf_dimensions,
+ .set_fmt = fetchlayer_set_fmt,
+ .enable_src_buf = fetchunit_enable_src_buf,
+ .disable_src_buf = fetchunit_disable_src_buf,
+ .is_enabled = fetchunit_is_enabled,
+ .set_framedimensions = fetchlayer_set_framedimensions,
+ .set_controltrigger = fetchlayer_set_controltrigger,
+ .get_stream_id = fetchunit_get_stream_id,
+ .set_stream_id = fetchunit_set_stream_id,
+ .pin_off = fetchunit_pin_off,
+ .unpin_off = fetchunit_unpin_off,
+ .is_pinned_off = fetchunit_is_pinned_off,
+};
+
+void _dpu_fl_init(struct dpu_soc *dpu, unsigned int id)
+{
+ struct dpu_fetchunit *fu;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(fl_ids); i++)
+ if (fl_ids[i] == id)
+ break;
+
+ if (WARN_ON(i == ARRAY_SIZE(fl_ids)))
+ return;
+
+ fu = dpu->fl_priv[i];
+
+ fetchunit_baddr_autoupdate(fu, 0x0);
+ fetchunit_shden(fu, true);
+ fetchunit_shdldreq_sticky(fu, 0xFF);
+ fetchunit_disable_src_buf(fu);
+
+ mutex_lock(&fu->mutex);
+ dpu_fu_write(fu, SETNUMBUFFERS(16) | SETBURSTLENGTH(16),
+ BURSTBUFFERMANAGEMENT);
+ mutex_unlock(&fu->mutex);
+}
+
+int dpu_fl_init(struct dpu_soc *dpu, unsigned int id,
+ unsigned long pec_base, unsigned long base)
+{
+ struct dpu_fetchlayer *fl;
+ struct dpu_fetchunit *fu;
+ int ret, i;
+
+ fl = devm_kzalloc(dpu->dev, sizeof(*fl), GFP_KERNEL);
+ if (!fl)
+ return -ENOMEM;
+
+ fu = &fl->fu;
+ dpu->fl_priv[id] = fu;
+
+ fu->pec_base = devm_ioremap(dpu->dev, base, SZ_16);
+ if (!fu->pec_base)
+ return -ENOMEM;
+
+ fu->base = devm_ioremap(dpu->dev, base, SZ_512);
+ if (!fu->base)
+ return -ENOMEM;
+
+ fu->dpu = dpu;
+ fu->id = id;
+ fu->sub_id = 0;
+ fu->type = FU_T_FL;
+ fu->ops = &fl_ops;
+ fu->name = "fetchlayer";
+ for (i = 0; i < ARRAY_SIZE(fl_ids); i++) {
+ if (fl_ids[i] == id) {
+ fl->shdlreq = fl_shdlreqs[i];
+ break;
+ }
+ }
+ mutex_init(&fu->mutex);
+
+ ret = fetchlayer_fetchtype(fu, &fl->fetchtype);
+ if (ret < 0)
+ return ret;
+
+ _dpu_fl_init(dpu, id);
+
+ return 0;
+}
diff --git a/drivers/gpu/imx/dpu/dpu-fetchunit.c b/drivers/gpu/imx/dpu/dpu-fetchunit.c
new file mode 100644
index 000000000000..b482b2e75e7f
--- /dev/null
+++ b/drivers/gpu/imx/dpu/dpu-fetchunit.c
@@ -0,0 +1,339 @@
+/*
+ * Copyright 2018 NXP
+ *
+ * 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 <video/dpu.h>
+#include "dpu-prv.h"
+
+#define BASEADDRESS(n) (0x10 + (n) * 0x28)
+#define SOURCEBUFFERATTRIBUTES(n) (0x14 + (n) * 0x28)
+#define SOURCEBUFFERDIMENSION(n) (0x18 + (n) * 0x28)
+#define COLORCOMPONENTBITS(n) (0x1C + (n) * 0x28)
+#define COLORCOMPONENTSHIFT(n) (0x20 + (n) * 0x28)
+#define LAYEROFFSET(n) (0x24 + (n) * 0x28)
+#define CLIPWINDOWOFFSET(n) (0x28 + (n) * 0x28)
+#define CLIPWINDOWDIMENSIONS(n) (0x2C + (n) * 0x28)
+#define CONSTANTCOLOR(n) (0x30 + (n) * 0x28)
+#define LAYERPROPERTY(n) (0x34 + (n) * 0x28)
+
+void fetchunit_get_dprc(struct dpu_fetchunit *fu, void *data)
+{
+ if (WARN_ON(!fu))
+ return;
+
+ fu->dprc = data;
+}
+EXPORT_SYMBOL_GPL(fetchunit_get_dprc);
+
+void fetchunit_shden(struct dpu_fetchunit *fu, bool enable)
+{
+ u32 val;
+
+ mutex_lock(&fu->mutex);
+ val = dpu_fu_read(fu, STATICCONTROL);
+ if (enable)
+ val |= SHDEN;
+ else
+ val &= ~SHDEN;
+ dpu_fu_write(fu, val, STATICCONTROL);
+ mutex_unlock(&fu->mutex);
+}
+EXPORT_SYMBOL_GPL(fetchunit_shden);
+
+void fetchunit_baddr_autoupdate(struct dpu_fetchunit *fu, u8 layer_mask)
+{
+ u32 val;
+
+ mutex_lock(&fu->mutex);
+ val = dpu_fu_read(fu, STATICCONTROL);
+ val &= ~BASEADDRESSAUTOUPDATE_MASK;
+ val |= BASEADDRESSAUTOUPDATE(layer_mask);
+ dpu_fu_write(fu, val, STATICCONTROL);
+ mutex_unlock(&fu->mutex);
+}
+EXPORT_SYMBOL_GPL(fetchunit_baddr_autoupdate);
+
+void fetchunit_shdldreq_sticky(struct dpu_fetchunit *fu, u8 layer_mask)
+{
+ u32 val;
+
+ mutex_lock(&fu->mutex);
+ val = dpu_fu_read(fu, STATICCONTROL);
+ val &= ~SHDLDREQSTICKY_MASK;
+ val |= SHDLDREQSTICKY(layer_mask);
+ dpu_fu_write(fu, val, STATICCONTROL);
+ mutex_unlock(&fu->mutex);
+}
+EXPORT_SYMBOL_GPL(fetchunit_shdldreq_sticky);
+
+void fetchunit_set_burstlength(struct dpu_fetchunit *fu,
+ unsigned int x_offset, unsigned int mt_w,
+ int bpp, dma_addr_t baddr, bool use_prefetch)
+{
+ struct dpu_soc *dpu = fu->dpu;
+ unsigned int burst_size, burst_length;
+ bool nonzero_mod = !!mt_w;
+ u32 val;
+
+ if (use_prefetch) {
+ /* consider PRG x offset to calculate buffer address */
+ if (nonzero_mod)
+ baddr += (x_offset % mt_w) * (bpp / 8);
+
+ /*
+ * address TKT343664:
+ * fetch unit base address has to align to burst size
+ */
+ burst_size = 1 << (ffs(baddr) - 1);
+ burst_size = round_up(burst_size, 8);
+ burst_size = min(burst_size, 128U);
+ burst_length = burst_size / 8;
+ } else {
+ burst_length = 16;
+ }
+
+ mutex_lock(&fu->mutex);
+ val = dpu_fu_read(fu, BURSTBUFFERMANAGEMENT);
+ val &= ~SETBURSTLENGTH_MASK;
+ val |= SETBURSTLENGTH(burst_length);
+ dpu_fu_write(fu, val, BURSTBUFFERMANAGEMENT);
+ mutex_unlock(&fu->mutex);
+
+ dev_dbg(dpu->dev, "%s%d burst length is %u\n",
+ fu->name, fu->id, burst_length);
+}
+EXPORT_SYMBOL_GPL(fetchunit_set_burstlength);
+
+void fetchunit_set_baseaddress(struct dpu_fetchunit *fu, unsigned int width,
+ unsigned int x_offset, unsigned int y_offset,
+ unsigned int mt_w, unsigned int mt_h,
+ int bpp, dma_addr_t baddr)
+{
+ unsigned int burst_size, stride;
+ bool nonzero_mod = !!mt_w;
+
+ if (nonzero_mod) {
+ /* consider PRG x offset to calculate buffer address */
+ baddr += (x_offset % mt_w) * (bpp / 8);
+
+ /*
+ * address TKT343664:
+ * fetch unit base address has to align to burst size
+ */
+ burst_size = 1 << (ffs(baddr) - 1);
+ burst_size = round_up(burst_size, 8);
+ burst_size = min(burst_size, 128U);
+
+ stride = width * (bpp >> 3);
+ /*
+ * address TKT339017:
+ * fixup for burst size vs stride mismatch
+ */
+ stride = round_up(stride + round_up(baddr % 8, 8), burst_size);
+
+ /* consider PRG y offset to calculate buffer address */
+ baddr += (y_offset % mt_h) * stride;
+ }
+
+ mutex_lock(&fu->mutex);
+ dpu_fu_write(fu, baddr, BASEADDRESS(fu->sub_id));
+ mutex_unlock(&fu->mutex);
+}
+EXPORT_SYMBOL_GPL(fetchunit_set_baseaddress);
+
+void fetchunit_set_src_bpp(struct dpu_fetchunit *fu, int bpp)
+{
+ u32 val;
+
+ mutex_lock(&fu->mutex);
+ val = dpu_fu_read(fu, SOURCEBUFFERATTRIBUTES(fu->sub_id));
+ val &= ~0x3f0000;
+ val |= BITSPERPIXEL(bpp);
+ dpu_fu_write(fu, val, SOURCEBUFFERATTRIBUTES(fu->sub_id));
+ mutex_unlock(&fu->mutex);
+}
+EXPORT_SYMBOL_GPL(fetchunit_set_src_bpp);
+
+/*
+ * The arguments width and bpp are valid only when use_prefetch is true.
+ * For fetcheco, since the pixel format has to be NV12 or NV21 when
+ * use_prefetch is true, we assume width stands for how many UV we have
+ * in bytes for one line, while bpp should be 8bits for every U or V component.
+ */
+void fetchunit_set_src_stride(struct dpu_fetchunit *fu,
+ unsigned int width, unsigned int x_offset,
+ unsigned int mt_w, int bpp, unsigned int stride,
+ dma_addr_t baddr, bool use_prefetch)
+{
+ unsigned int burst_size;
+ bool nonzero_mod = !!mt_w;
+ u32 val;
+
+ if (use_prefetch) {
+ /* consider PRG x offset to calculate buffer address */
+ if (nonzero_mod)
+ baddr += (x_offset % mt_w) * (bpp / 8);
+
+ /*
+ * address TKT343664:
+ * fetch unit base address has to align to burst size
+ */
+ burst_size = 1 << (ffs(baddr) - 1);
+ burst_size = round_up(burst_size, 8);
+ burst_size = min(burst_size, 128U);
+
+ stride = width * (bpp >> 3);
+ /*
+ * address TKT339017:
+ * fixup for burst size vs stride mismatch
+ */
+ if (nonzero_mod)
+ stride = round_up(stride + round_up(baddr % 8, 8),
+ burst_size);
+ else
+ stride = round_up(stride, burst_size);
+ }
+
+ mutex_lock(&fu->mutex);
+ val = dpu_fu_read(fu, SOURCEBUFFERATTRIBUTES(fu->sub_id));
+ val &= ~0xffff;
+ val |= STRIDE(stride);
+ dpu_fu_write(fu, val, SOURCEBUFFERATTRIBUTES(fu->sub_id));
+ mutex_unlock(&fu->mutex);
+}
+EXPORT_SYMBOL_GPL(fetchunit_set_src_stride);
+
+void fetchunit_enable_src_buf(struct dpu_fetchunit *fu)
+{
+ u32 val;
+
+ mutex_lock(&fu->mutex);
+ val = dpu_fu_read(fu, LAYERPROPERTY(fu->sub_id));
+ val |= SOURCEBUFFERENABLE;
+ dpu_fu_write(fu, val, LAYERPROPERTY(fu->sub_id));
+ mutex_unlock(&fu->mutex);
+}
+EXPORT_SYMBOL_GPL(fetchunit_enable_src_buf);
+
+void fetchunit_disable_src_buf(struct dpu_fetchunit *fu)
+{
+ u32 val;
+
+ mutex_lock(&fu->mutex);
+ val = dpu_fu_read(fu, LAYERPROPERTY(fu->sub_id));
+ val &= ~SOURCEBUFFERENABLE;
+ dpu_fu_write(fu, val, LAYERPROPERTY(fu->sub_id));
+ mutex_unlock(&fu->mutex);
+}
+EXPORT_SYMBOL_GPL(fetchunit_disable_src_buf);
+
+bool fetchunit_is_enabled(struct dpu_fetchunit *fu)
+{
+ u32 val;
+
+ mutex_lock(&fu->mutex);
+ val = dpu_fu_read(fu, LAYERPROPERTY(fu->sub_id));
+ mutex_unlock(&fu->mutex);
+
+ return !!(val & SOURCEBUFFERENABLE);
+}
+EXPORT_SYMBOL_GPL(fetchunit_is_enabled);
+
+unsigned int fetchunit_get_stream_id(struct dpu_fetchunit *fu)
+{
+ if (WARN_ON(!fu))
+ return DPU_PLANE_SRC_DISABLED;
+
+ return fu->stream_id;
+}
+EXPORT_SYMBOL_GPL(fetchunit_get_stream_id);
+
+void fetchunit_set_stream_id(struct dpu_fetchunit *fu, unsigned int id)
+{
+ if (WARN_ON(!fu))
+ return;
+
+ switch (id) {
+ case DPU_PLANE_SRC_TO_DISP_STREAM0:
+ case DPU_PLANE_SRC_TO_DISP_STREAM1:
+ case DPU_PLANE_SRC_DISABLED:
+ fu->stream_id = id;
+ break;
+ default:
+ WARN_ON(1);
+ }
+}
+EXPORT_SYMBOL_GPL(fetchunit_set_stream_id);
+
+void fetchunit_pin_off(struct dpu_fetchunit *fu)
+{
+ if (WARN_ON(!fu))
+ return;
+
+ fu->pin_off = true;
+}
+EXPORT_SYMBOL_GPL(fetchunit_pin_off);
+
+void fetchunit_unpin_off(struct dpu_fetchunit *fu)
+{
+ if (WARN_ON(!fu))
+ return;
+
+ fu->pin_off = false;
+}
+EXPORT_SYMBOL_GPL(fetchunit_unpin_off);
+
+bool fetchunit_is_pinned_off(struct dpu_fetchunit *fu)
+{
+ if (WARN_ON(!fu))
+ return false;
+
+ return fu->pin_off;
+}
+EXPORT_SYMBOL_GPL(fetchunit_is_pinned_off);
+
+bool fetchunit_is_fetchdecode(struct dpu_fetchunit *fu)
+{
+ if (WARN_ON(!fu))
+ return false;
+
+ return fu->type == FU_T_FD;
+}
+EXPORT_SYMBOL_GPL(fetchunit_is_fetchdecode);
+
+bool fetchunit_is_fetcheco(struct dpu_fetchunit *fu)
+{
+ if (WARN_ON(!fu))
+ return false;
+
+ return fu->type == FU_T_FE;
+}
+EXPORT_SYMBOL_GPL(fetchunit_is_fetcheco);
+
+bool fetchunit_is_fetchlayer(struct dpu_fetchunit *fu)
+{
+ if (WARN_ON(!fu))
+ return false;
+
+ return fu->type == FU_T_FL;
+}
+EXPORT_SYMBOL_GPL(fetchunit_is_fetchlayer);
+
+bool fetchunit_is_fetchwarp(struct dpu_fetchunit *fu)
+{
+ if (WARN_ON(!fu))
+ return false;
+
+ return fu->type == FU_T_FW;
+}
+EXPORT_SYMBOL_GPL(fetchunit_is_fetchwarp);
diff --git a/drivers/gpu/imx/dpu/dpu-fetchwarp.c b/drivers/gpu/imx/dpu/dpu-fetchwarp.c
new file mode 100644
index 000000000000..e4b0916cb35b
--- /dev/null
+++ b/drivers/gpu/imx/dpu/dpu-fetchwarp.c
@@ -0,0 +1,332 @@
+/*
+ * Copyright 2018 NXP
+ *
+ * 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/io.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/platform_device.h>
+#include <linux/types.h>
+#include <video/dpu.h>
+#include "dpu-prv.h"
+
+#define PIXENGCFG_STATUS 0x8
+#define BASEADDRESS(n) (0x10 + (n) * 0x28)
+#define SOURCEBUFFERATTRIBUTES(n) (0x14 + (n) * 0x28)
+#define SOURCEBUFFERDIMENSION(n) (0x18 + (n) * 0x28)
+#define COLORCOMPONENTBITS(n) (0x1C + (n) * 0x28)
+#define COLORCOMPONENTSHIFT(n) (0x20 + (n) * 0x28)
+#define LAYEROFFSET(n) (0x24 + (n) * 0x28)
+#define CLIPWINDOWOFFSET(n) (0x28 + (n) * 0x28)
+#define CLIPWINDOWDIMENSIONS(n) (0x2C + (n) * 0x28)
+#define CONSTANTCOLOR(n) (0x30 + (n) * 0x28)
+#define LAYERPROPERTY(n) (0x34 + (n) * 0x28)
+#define FRAMEDIMENSIONS 0x150
+#define FRAMERESAMPLING 0x154
+#define WARPCONTROL 0x158
+#define ARBSTARTX 0x15c
+#define ARBSTARTY 0x160
+#define ARBDELTA 0x164
+#define FIRPOSITIONS 0x168
+#define FIRCOEFFICIENTS 0x16c
+#define CONTROL 0x170
+#define TRIGGERENABLE 0x174
+#define SHDLDREQ(lm) ((lm) & 0xFF)
+#define CONTROLTRIGGER 0x178
+#define START 0x17c
+#define FETCHTYPE 0x180
+#define BURSTBUFFERPROPERTIES 0x184
+#define STATUS 0x188
+#define HIDDENSTATUS 0x18c
+
+struct dpu_fetchwarp {
+ struct dpu_fetchunit fu;
+ fetchtype_t fetchtype;
+};
+
+static void
+fetchwarp_set_src_buf_dimensions(struct dpu_fetchunit *fu,
+ unsigned int w, unsigned int h,
+ u32 unused1, bool unused2)
+{
+ u32 val;
+
+ val = LINEWIDTH(w) | LINECOUNT(h);
+
+ mutex_lock(&fu->mutex);
+ dpu_fu_write(fu, val, SOURCEBUFFERDIMENSION(fu->sub_id));
+ mutex_unlock(&fu->mutex);
+}
+
+static void fetchwarp_set_fmt(struct dpu_fetchunit *fu,
+ u32 fmt, bool unused)
+{
+ u32 val, bits, shift;
+ int i, sub_id = fu->sub_id;
+
+ mutex_lock(&fu->mutex);
+ val = dpu_fu_read(fu, LAYERPROPERTY(sub_id));
+ val &= ~YUVCONVERSIONMODE_MASK;
+ dpu_fu_write(fu, val, LAYERPROPERTY(sub_id));
+ mutex_unlock(&fu->mutex);
+
+ for (i = 0; i < ARRAY_SIZE(dpu_pixel_format_matrix); i++) {
+ if (dpu_pixel_format_matrix[i].pixel_format == fmt) {
+ bits = dpu_pixel_format_matrix[i].bits;
+ shift = dpu_pixel_format_matrix[i].shift;
+
+ mutex_lock(&fu->mutex);
+ dpu_fu_write(fu, bits, COLORCOMPONENTBITS(sub_id));
+ dpu_fu_write(fu, shift, COLORCOMPONENTSHIFT(sub_id));
+ mutex_unlock(&fu->mutex);
+ return;
+ }
+ }
+
+ WARN_ON(1);
+}
+
+static void
+fetchwarp_set_framedimensions(struct dpu_fetchunit *fu,
+ unsigned int w, unsigned int h, bool unused)
+{
+ u32 val;
+
+ val = FRAMEWIDTH(w) | FRAMEHEIGHT(h);
+
+ mutex_lock(&fu->mutex);
+ dpu_fu_write(fu, val, FRAMEDIMENSIONS);
+ mutex_unlock(&fu->mutex);
+}
+
+void fetchwarp_rgb_constantcolor(struct dpu_fetchunit *fu,
+ u8 r, u8 g, u8 b, u8 a)
+{
+ u32 val;
+
+ val = rgb_color(r, g, b, a);
+
+ mutex_lock(&fu->mutex);
+ dpu_fu_write(fu, val, CONSTANTCOLOR(fu->id));
+ mutex_unlock(&fu->mutex);
+}
+EXPORT_SYMBOL_GPL(fetchwarp_rgb_constantcolor);
+
+void fetchwarp_yuv_constantcolor(struct dpu_fetchunit *fu, u8 y, u8 u, u8 v)
+{
+ u32 val;
+
+ val = yuv_color(y, u, v);
+
+ mutex_lock(&fu->mutex);
+ dpu_fu_write(fu, val, CONSTANTCOLOR(fu->id));
+ mutex_unlock(&fu->mutex);
+}
+EXPORT_SYMBOL_GPL(fetchwarp_yuv_constantcolor);
+
+static void fetchwarp_set_controltrigger(struct dpu_fetchunit *fu)
+{
+ mutex_lock(&fu->mutex);
+ dpu_fu_write(fu, SHDTOKGEN, CONTROLTRIGGER);
+ mutex_unlock(&fu->mutex);
+}
+
+int fetchwarp_fetchtype(struct dpu_fetchunit *fu, fetchtype_t *type)
+{
+ struct dpu_soc *dpu = fu->dpu;
+ u32 val;
+
+ mutex_lock(&fu->mutex);
+ val = dpu_fu_read(fu, FETCHTYPE);
+ val &= FETCHTYPE_MASK;
+ mutex_unlock(&fu->mutex);
+
+ switch (val) {
+ case FETCHTYPE__DECODE:
+ dev_dbg(dpu->dev, "FetchWarp%d with RL and RLAD decoder\n",
+ fu->id);
+ break;
+ case FETCHTYPE__LAYER:
+ dev_dbg(dpu->dev, "FetchWarp%d with fractional "
+ "plane(8 layers)\n", fu->id);
+ break;
+ case FETCHTYPE__WARP:
+ dev_dbg(dpu->dev, "FetchWarp%d with arbitrary warping and "
+ "fractional plane(8 layers)\n", fu->id);
+ break;
+ case FETCHTYPE__ECO:
+ dev_dbg(dpu->dev, "FetchWarp%d with minimum feature set for "
+ "alpha, chroma and coordinate planes\n",
+ fu->id);
+ break;
+ case FETCHTYPE__PERSP:
+ dev_dbg(dpu->dev, "FetchWarp%d with affine, perspective and "
+ "arbitrary warping\n", fu->id);
+ break;
+ case FETCHTYPE__ROT:
+ dev_dbg(dpu->dev, "FetchWarp%d with affine and arbitrary "
+ "warping\n", fu->id);
+ break;
+ case FETCHTYPE__DECODEL:
+ dev_dbg(dpu->dev, "FetchWarp%d with RL and RLAD decoder, "
+ "reduced feature set\n", fu->id);
+ break;
+ case FETCHTYPE__LAYERL:
+ dev_dbg(dpu->dev, "FetchWarp%d with fractional "
+ "plane(8 layers), reduced feature set\n",
+ fu->id);
+ break;
+ case FETCHTYPE__ROTL:
+ dev_dbg(dpu->dev, "FetchWarp%d with affine and arbitrary "
+ "warping, reduced feature set\n", fu->id);
+ break;
+ default:
+ dev_warn(dpu->dev, "Invalid fetch type %u for FetchWarp%d\n",
+ val, fu->id);
+ return -EINVAL;
+ }
+
+ *type = val;
+ return 0;
+}
+EXPORT_SYMBOL_GPL(fetchwarp_fetchtype);
+
+struct dpu_fetchunit *dpu_fw_get(struct dpu_soc *dpu, int id)
+{
+ struct dpu_fetchunit *fu;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(fw_ids); i++)
+ if (fw_ids[i] == id)
+ break;
+
+ if (i == ARRAY_SIZE(fw_ids))
+ return ERR_PTR(-EINVAL);
+
+ fu = dpu->fw_priv[i];
+
+ mutex_lock(&fu->mutex);
+
+ if (fu->inuse) {
+ mutex_unlock(&fu->mutex);
+ return ERR_PTR(-EBUSY);
+ }
+
+ fu->inuse = true;
+
+ mutex_unlock(&fu->mutex);
+
+ return fu;
+}
+EXPORT_SYMBOL_GPL(dpu_fw_get);
+
+void dpu_fw_put(struct dpu_fetchunit *fu)
+{
+ mutex_lock(&fu->mutex);
+
+ fu->inuse = false;
+
+ mutex_unlock(&fu->mutex);
+}
+EXPORT_SYMBOL_GPL(dpu_fw_put);
+
+static const struct dpu_fetchunit_ops fw_ops = {
+ .set_burstlength = fetchunit_set_burstlength,
+ .set_baseaddress = fetchunit_set_baseaddress,
+ .set_src_bpp = fetchunit_set_src_bpp,
+ .set_src_stride = fetchunit_set_src_stride,
+ .set_src_buf_dimensions = fetchwarp_set_src_buf_dimensions,
+ .set_fmt = fetchwarp_set_fmt,
+ .enable_src_buf = fetchunit_enable_src_buf,
+ .disable_src_buf = fetchunit_disable_src_buf,
+ .is_enabled = fetchunit_is_enabled,
+ .set_framedimensions = fetchwarp_set_framedimensions,
+ .set_controltrigger = fetchwarp_set_controltrigger,
+ .get_stream_id = fetchunit_get_stream_id,
+ .set_stream_id = fetchunit_set_stream_id,
+ .pin_off = fetchunit_pin_off,
+ .unpin_off = fetchunit_unpin_off,
+ .is_pinned_off = fetchunit_is_pinned_off,
+};
+
+void _dpu_fw_init(struct dpu_soc *dpu, unsigned int id)
+{
+ struct dpu_fetchunit *fu;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(fw_ids); i++)
+ if (fw_ids[i] == id)
+ break;
+
+ if (WARN_ON(i == ARRAY_SIZE(fw_ids)))
+ return;
+
+ fu = dpu->fw_priv[i];
+
+ fetchunit_baddr_autoupdate(fu, 0x0);
+ fetchunit_shden(fu, true);
+ fetchunit_shdldreq_sticky(fu, 0xFF);
+ fetchunit_disable_src_buf(fu);
+
+ mutex_lock(&fu->mutex);
+ dpu_fu_write(fu, SETNUMBUFFERS(16) | SETBURSTLENGTH(16),
+ BURSTBUFFERMANAGEMENT);
+ mutex_unlock(&fu->mutex);
+}
+
+int dpu_fw_init(struct dpu_soc *dpu, unsigned int id,
+ unsigned long pec_base, unsigned long base)
+{
+ struct dpu_fetchwarp *fw;
+ struct dpu_fetchunit *fu;
+ int i, ret;
+
+ fw = devm_kzalloc(dpu->dev, sizeof(*fw), GFP_KERNEL);
+ if (!fw)
+ return -ENOMEM;
+
+ for (i = 0; i < ARRAY_SIZE(fw_ids); i++)
+ if (fw_ids[i] == id)
+ break;
+
+ if (i == ARRAY_SIZE(fw_ids))
+ return -EINVAL;
+
+ fu = &fw->fu;
+ dpu->fw_priv[i] = fu;
+
+ fu->pec_base = devm_ioremap(dpu->dev, base, SZ_16);
+ if (!fu->pec_base)
+ return -ENOMEM;
+
+ fu->base = devm_ioremap(dpu->dev, base, SZ_512);
+ if (!fu->base)
+ return -ENOMEM;
+
+ fu->dpu = dpu;
+ fu->id = id;
+ fu->sub_id = 0;
+ fu->type = FU_T_FW;
+ fu->ops = &fw_ops;
+ fu->name = "fetchwarp";
+
+ mutex_init(&fu->mutex);
+
+ ret = fetchwarp_fetchtype(fu, &fw->fetchtype);
+ if (ret < 0)
+ return ret;
+
+ _dpu_fw_init(dpu, id);
+
+ return 0;
+}
diff --git a/drivers/gpu/imx/dpu/dpu-framegen.c b/drivers/gpu/imx/dpu/dpu-framegen.c
new file mode 100644
index 000000000000..994d6ac0c0e5
--- /dev/null
+++ b/drivers/gpu/imx/dpu/dpu-framegen.c
@@ -0,0 +1,778 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017-2019 NXP
+ *
+ * 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/clk.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/platform_device.h>
+#include <linux/types.h>
+#include <soc/imx8/sc/sci.h>
+#include <video/dpu.h>
+#include "dpu-prv.h"
+
+#define FGSTCTRL 0x8
+#define FGSYNCMODE_MASK 0x6
+#define HTCFG1 0xC
+#define HTOTAL(n) ((((n) - 1) & 0x3FFF) << 16)
+#define HACT(n) ((n) & 0x3FFF)
+#define HTCFG2 0x10
+#define HSEN BIT(31)
+#define HSBP(n) ((((n) - 1) & 0x3FFF) << 16)
+#define HSYNC(n) (((n) - 1) & 0x3FFF)
+#define VTCFG1 0x14
+#define VTOTAL(n) ((((n) - 1) & 0x3FFF) << 16)
+#define VACT(n) ((n) & 0x3FFF)
+#define VTCFG2 0x18
+#define VSEN BIT(31)
+#define VSBP(n) ((((n) - 1) & 0x3FFF) << 16)
+#define VSYNC(n) (((n) - 1) & 0x3FFF)
+#define INTCONFIG(n) (0x1C + 4 * (n))
+#define EN BIT(31)
+#define ROW(n) (((n) & 0x3FFF) << 16)
+#define COL(n) ((n) & 0x3FFF)
+#define PKICKCONFIG 0x2C
+#define SKICKCONFIG 0x30
+#define SECSTATCONFIG 0x34
+#define FGSRCR1 0x38
+#define FGSRCR2 0x3C
+#define FGSRCR3 0x40
+#define FGSRCR4 0x44
+#define FGSRCR5 0x48
+#define FGSRCR6 0x4C
+#define FGKSDR 0x50
+#define PACFG 0x54
+#define STARTX(n) (((n) + 1) & 0x3FFF)
+#define STARTY(n) (((((n) + 1) & 0x3FFF)) << 16)
+#define SACFG 0x58
+#define FGINCTRL 0x5C
+#define FGDM_MASK 0x7
+#define ENPRIMALPHA BIT(3)
+#define ENSECALPHA BIT(4)
+#define FGINCTRLPANIC 0x60
+#define FGCCR 0x64
+#define CCALPHA(a) (((a) & 0x1) << 30)
+#define CCRED(r) (((r) & 0x3FF) << 20)
+#define CCGREEN(g) (((g) & 0x3FF) << 10)
+#define CCBLUE(b) ((b) & 0x3FF)
+#define FGENABLE 0x68
+#define FGEN BIT(0)
+#define FGSLR 0x6C
+#define FGENSTS 0x70
+#define ENSTS BIT(0)
+#define FGTIMESTAMP 0x74
+#define LINEINDEX_MASK 0x3FFF
+#define LINEINDEX_SHIFT 0
+#define FRAMEINDEX_MASK 0xFFFFC000
+#define FRAMEINDEX_SHIFT 14
+#define FGCHSTAT 0x78
+#define SECSYNCSTAT BIT(24)
+#define SFIFOEMPTY BIT(16)
+#define FGCHSTATCLR 0x7C
+#define CLRSECSTAT BIT(16)
+#define FGSKEWMON 0x80
+#define FGSFIFOMIN 0x84
+#define FGSFIFOMAX 0x88
+#define FGSFIFOFILLCLR 0x8C
+#define FGSREPD 0x90
+#define FGSRFTD 0x94
+
+#define KHZ 1000
+#define PLL_MIN_FREQ_HZ 648000000
+
+struct dpu_framegen {
+ void __iomem *base;
+ struct clk *clk_pll;
+ struct clk *clk_bypass;
+ struct clk *clk_disp_sel;
+ struct clk *clk_disp;
+ struct mutex mutex;
+ int id;
+ bool inuse;
+ bool use_bypass_clk;
+ bool encoder_type_has_lvds;
+ bool side_by_side;
+ struct dpu_soc *dpu;
+};
+
+static inline u32 dpu_fg_read(struct dpu_framegen *fg, unsigned int offset)
+{
+ return readl(fg->base + offset);
+}
+
+static inline void dpu_fg_write(struct dpu_framegen *fg, u32 value,
+ unsigned int offset)
+{
+ writel(value, fg->base + offset);
+}
+
+/* FIXME: enable pixel link in a proper manner */
+static void dpu_pixel_link_enable(int dpu_id, int stream_id)
+{
+ sc_err_t sciErr;
+ sc_ipc_t ipcHndl = 0;
+ u32 mu_id;
+
+ sciErr = sc_ipc_getMuID(&mu_id);
+ if (sciErr != SC_ERR_NONE) {
+ pr_err("Cannot obtain MU ID\n");
+ return;
+ }
+
+ sciErr = sc_ipc_open(&ipcHndl, mu_id);
+ if (sciErr != SC_ERR_NONE) {
+ pr_err("sc_ipc_open failed! (sciError = %d)\n", sciErr);
+ return;
+ }
+
+ if (dpu_id == 0) {
+ sciErr = sc_misc_set_control(ipcHndl, SC_R_DC_0,
+ stream_id ? SC_C_PXL_LINK_MST2_ENB : SC_C_PXL_LINK_MST1_ENB, 1);
+ if (sciErr != SC_ERR_NONE)
+ pr_err("SC_R_DC_0:SC_C_PXL_LINK_MST%d_ENB sc_misc_set_control failed! (sciError = %d)\n", stream_id + 1, sciErr);
+ } else if (dpu_id == 1) {
+ sciErr = sc_misc_set_control(ipcHndl, SC_R_DC_1,
+ stream_id ? SC_C_PXL_LINK_MST2_ENB : SC_C_PXL_LINK_MST1_ENB, 1);
+ if (sciErr != SC_ERR_NONE)
+ pr_err("SC_R_DC_1:SC_C_PXL_LINK_MST%d_ENB sc_misc_set_control failed! (sciError = %d)\n", stream_id + 1, sciErr);
+ }
+
+ sc_ipc_close(mu_id);
+}
+
+/* FIXME: disable pixel link in a proper manner */
+static void dpu_pixel_link_disable(int dpu_id, int stream_id)
+{
+ sc_err_t sciErr;
+ sc_ipc_t ipcHndl = 0;
+ u32 mu_id;
+
+ sciErr = sc_ipc_getMuID(&mu_id);
+ if (sciErr != SC_ERR_NONE) {
+ pr_err("Cannot obtain MU ID\n");
+ return;
+ }
+
+ sciErr = sc_ipc_open(&ipcHndl, mu_id);
+ if (sciErr != SC_ERR_NONE) {
+ pr_err("sc_ipc_open failed! (sciError = %d)\n", sciErr);
+ return;
+ }
+
+ if (dpu_id == 0) {
+ sciErr = sc_misc_set_control(ipcHndl, SC_R_DC_0,
+ stream_id ? SC_C_PXL_LINK_MST2_ENB : SC_C_PXL_LINK_MST1_ENB, 0);
+ if (sciErr != SC_ERR_NONE)
+ pr_err("SC_R_DC_0:SC_C_PXL_LINK_MST%d_ENB sc_misc_set_control failed! (sciError = %d)\n", stream_id + 1, sciErr);
+ } else if (dpu_id == 1) {
+ sciErr = sc_misc_set_control(ipcHndl, SC_R_DC_1,
+ stream_id ? SC_C_PXL_LINK_MST2_ENB : SC_C_PXL_LINK_MST1_ENB, 0);
+ if (sciErr != SC_ERR_NONE)
+ pr_err("SC_R_DC_1:SC_C_PXL_LINK_MST%d_ENB sc_misc_set_control failed! (sciError = %d)\n", stream_id + 1, sciErr);
+ }
+
+ sc_ipc_close(mu_id);
+}
+
+/* FIXME: set MST address for pixel link in a proper manner */
+static void dpu_pixel_link_set_mst_addr(int dpu_id, int stream_id, int mst_addr)
+{
+ sc_err_t sciErr;
+ sc_ipc_t ipcHndl = 0;
+ u32 mu_id;
+
+ sciErr = sc_ipc_getMuID(&mu_id);
+ if (sciErr != SC_ERR_NONE) {
+ pr_err("Cannot obtain MU ID\n");
+ return;
+ }
+
+ sciErr = sc_ipc_open(&ipcHndl, mu_id);
+ if (sciErr != SC_ERR_NONE) {
+ pr_err("sc_ipc_open failed! (sciError = %d)\n", sciErr);
+ return;
+ }
+
+ if (dpu_id == 0) {
+ sciErr = sc_misc_set_control(ipcHndl, SC_R_DC_0, stream_id ?
+ SC_C_PXL_LINK_MST2_ADDR : SC_C_PXL_LINK_MST1_ADDR,
+ mst_addr);
+ if (sciErr != SC_ERR_NONE)
+ pr_err("SC_R_DC_0:SC_C_PXL_LINK_MST%d_ADDR sc_misc_set_control failed! (sciError = %d)\n", stream_id + 1, sciErr);
+ } else if (dpu_id == 1) {
+ sciErr = sc_misc_set_control(ipcHndl, SC_R_DC_1, stream_id ?
+ SC_C_PXL_LINK_MST2_ADDR : SC_C_PXL_LINK_MST1_ADDR,
+ mst_addr);
+ if (sciErr != SC_ERR_NONE)
+ pr_err("SC_R_DC_1:SC_C_PXL_LINK_MST%d_ADDR sc_misc_set_control failed! (sciError = %d)\n", stream_id + 1, sciErr);
+ }
+
+ sc_ipc_close(mu_id);
+}
+
+/* FIXME: set dc sync mode for pixel link in a proper manner */
+static void dpu_pixel_link_set_dc_sync_mode(int dpu_id, bool enable)
+{
+ sc_err_t sciErr;
+ sc_ipc_t ipcHndl = 0;
+ u32 mu_id;
+
+ sciErr = sc_ipc_getMuID(&mu_id);
+ if (sciErr != SC_ERR_NONE) {
+ pr_err("Cannot obtain MU ID\n");
+ return;
+ }
+
+ sciErr = sc_ipc_open(&ipcHndl, mu_id);
+ if (sciErr != SC_ERR_NONE) {
+ pr_err("sc_ipc_open failed! (sciError = %d)\n", sciErr);
+ return;
+ }
+
+ if (dpu_id == 0) {
+ sciErr = sc_misc_set_control(ipcHndl,
+ SC_R_DC_0, SC_C_MODE, enable);
+ if (sciErr != SC_ERR_NONE)
+ pr_err("SC_R_DC_0:SC_C_MODE sc_misc_set_control failed! (sciError = %d)\n", sciErr);
+ } else if (dpu_id == 1) {
+ sciErr = sc_misc_set_control(ipcHndl,
+ SC_R_DC_1, SC_C_MODE, enable);
+ if (sciErr != SC_ERR_NONE)
+ pr_err("SC_R_DC_1:SC_C_MODE sc_misc_set_control failed! (sciError = %d)\n", sciErr);
+ }
+
+ sc_ipc_close(mu_id);
+}
+
+void framegen_enable(struct dpu_framegen *fg)
+{
+ struct dpu_soc *dpu = fg->dpu;
+ const struct dpu_devtype *devtype = dpu->devtype;
+
+ mutex_lock(&fg->mutex);
+ dpu_fg_write(fg, FGEN, FGENABLE);
+ mutex_unlock(&fg->mutex);
+
+ if (!(devtype->has_dual_ldb && fg->encoder_type_has_lvds))
+ dpu_pixel_link_enable(dpu->id, fg->id);
+}
+EXPORT_SYMBOL_GPL(framegen_enable);
+
+void framegen_disable(struct dpu_framegen *fg)
+{
+ struct dpu_soc *dpu = fg->dpu;
+ const struct dpu_devtype *devtype = dpu->devtype;
+
+ if (!(devtype->has_dual_ldb && fg->encoder_type_has_lvds))
+ dpu_pixel_link_disable(dpu->id, fg->id);
+
+ mutex_lock(&fg->mutex);
+ dpu_fg_write(fg, 0, FGENABLE);
+ mutex_unlock(&fg->mutex);
+}
+EXPORT_SYMBOL_GPL(framegen_disable);
+
+void framegen_shdtokgen(struct dpu_framegen *fg)
+{
+ mutex_lock(&fg->mutex);
+ dpu_fg_write(fg, SHDTOKGEN, FGSLR);
+ mutex_unlock(&fg->mutex);
+}
+EXPORT_SYMBOL_GPL(framegen_shdtokgen);
+
+void framegen_syncmode(struct dpu_framegen *fg, fgsyncmode_t mode)
+{
+ struct dpu_soc *dpu = fg->dpu;
+ u32 val;
+
+ mutex_lock(&fg->mutex);
+ val = dpu_fg_read(fg, FGSTCTRL);
+ val &= ~FGSYNCMODE_MASK;
+ val |= mode;
+ dpu_fg_write(fg, val, FGSTCTRL);
+ mutex_unlock(&fg->mutex);
+
+ dpu_pixel_link_set_dc_sync_mode(dpu->id, mode != FGSYNCMODE__OFF);
+}
+EXPORT_SYMBOL_GPL(framegen_syncmode);
+
+void
+framegen_cfg_videomode(struct dpu_framegen *fg,
+ struct drm_display_mode *m, bool side_by_side,
+ bool encoder_type_has_tmds, bool encoder_type_has_lvds)
+{
+ struct dpu_soc *dpu = fg->dpu;
+ const struct dpu_devtype *devtype = dpu->devtype;
+ u32 hact, htotal, hsync, hsbp;
+ u32 vact, vtotal, vsync, vsbp;
+ u32 kick_row, kick_col;
+ u32 val;
+ unsigned long disp_clock_rate, pll_clock_rate = 0;
+ int div = 0;
+
+ fg->side_by_side = side_by_side;
+ fg->encoder_type_has_lvds = encoder_type_has_lvds;
+
+ hact = m->crtc_hdisplay;
+ htotal = m->crtc_htotal;
+ hsync = m->crtc_hsync_end - m->crtc_hsync_start;
+ hsbp = m->crtc_htotal - m->crtc_hsync_start;
+
+ if (side_by_side) {
+ hact /= 2;
+ htotal /= 2;
+ hsync /= 2;
+ hsbp /= 2;
+ }
+
+ vact = m->crtc_vdisplay;
+ vtotal = m->crtc_vtotal;
+ vsync = m->crtc_vsync_end - m->crtc_vsync_start;
+ vsbp = m->crtc_vtotal - m->crtc_vsync_start;
+
+ mutex_lock(&fg->mutex);
+ /* video mode */
+ dpu_fg_write(fg, HACT(hact) | HTOTAL(htotal), HTCFG1);
+ dpu_fg_write(fg, HSYNC(hsync) | HSBP(hsbp) | HSEN, HTCFG2);
+ dpu_fg_write(fg, VACT(vact) | VTOTAL(vtotal), VTCFG1);
+ dpu_fg_write(fg, VSYNC(vsync) | VSBP(vsbp) | VSEN, VTCFG2);
+
+ kick_col = hact + 1;
+ kick_row = vact;
+ /*
+ * FrameGen as slave needs to be kicked later for
+ * one line comparing to the master.
+ */
+ if (side_by_side && framegen_is_slave(fg) &&
+ devtype->has_syncmode_fixup)
+ kick_row++;
+
+ /* pkickconfig */
+ dpu_fg_write(fg, COL(kick_col) | ROW(kick_row) | EN, PKICKCONFIG);
+
+ /* skikconfig */
+ dpu_fg_write(fg, COL(kick_col) | ROW(kick_row) | EN, SKICKCONFIG);
+
+ /* primary position config */
+ dpu_fg_write(fg, STARTX(0) | STARTY(0), PACFG);
+
+ /* alpha */
+ val = dpu_fg_read(fg, FGINCTRL);
+ val &= ~(ENPRIMALPHA | ENSECALPHA);
+ dpu_fg_write(fg, val, FGINCTRL);
+
+ val = dpu_fg_read(fg, FGINCTRLPANIC);
+ val &= ~(ENPRIMALPHA | ENSECALPHA);
+ dpu_fg_write(fg, val, FGINCTRLPANIC);
+
+ /* constant color */
+ dpu_fg_write(fg, 0, FGCCR);
+ mutex_unlock(&fg->mutex);
+
+ disp_clock_rate = m->clock * 1000;
+
+ /*
+ * To workaround setting clock rate failure issue
+ * when the system resumes back from PM sleep mode,
+ * we need to get the clock rates before setting
+ * their rates, otherwise, setting the clock rates
+ * will fail.
+ */
+ if (devtype->has_disp_sel_clk && encoder_type_has_tmds) {
+ if (side_by_side)
+ dpu_pixel_link_set_mst_addr(dpu->id, fg->id,
+ fg->id ? 2 : 1);
+ else
+ dpu_pixel_link_set_mst_addr(dpu->id, fg->id, 1);
+
+ clk_set_parent(fg->clk_disp_sel, fg->clk_bypass);
+
+ fg->use_bypass_clk = true;
+ } else {
+ dpu_pixel_link_set_mst_addr(dpu->id, fg->id, 0);
+
+ /* find an even divisor for PLL */
+ do {
+ div += 2;
+ pll_clock_rate = disp_clock_rate * div;
+ } while (pll_clock_rate < PLL_MIN_FREQ_HZ);
+
+ if (devtype->has_disp_sel_clk)
+ clk_set_parent(fg->clk_disp_sel, fg->clk_pll);
+
+ clk_get_rate(fg->clk_pll);
+ clk_get_rate(fg->clk_disp);
+ clk_set_rate(fg->clk_pll, pll_clock_rate);
+ clk_set_rate(fg->clk_disp, disp_clock_rate);
+
+ fg->use_bypass_clk = false;
+ }
+}
+EXPORT_SYMBOL_GPL(framegen_cfg_videomode);
+
+void framegen_pkickconfig(struct dpu_framegen *fg, bool enable)
+{
+ u32 val;
+
+ mutex_lock(&fg->mutex);
+ val = dpu_fg_read(fg, PKICKCONFIG);
+ if (enable)
+ val |= EN;
+ else
+ val &= ~EN;
+ dpu_fg_write(fg, val, PKICKCONFIG);
+ mutex_unlock(&fg->mutex);
+}
+EXPORT_SYMBOL_GPL(framegen_pkickconfig);
+
+void framegen_syncmode_fixup(struct dpu_framegen *fg, bool enable)
+{
+ struct dpu_soc *dpu = fg->dpu;
+ u32 val;
+
+ if (!dpu->devtype->has_syncmode_fixup)
+ return;
+
+ mutex_lock(&fg->mutex);
+ val = dpu_fg_read(fg, SECSTATCONFIG);
+ if (enable)
+ val |= BIT(7);
+ else
+ val &= ~BIT(7);
+ dpu_fg_write(fg, val, SECSTATCONFIG);
+ mutex_unlock(&fg->mutex);
+}
+EXPORT_SYMBOL_GPL(framegen_syncmode_fixup);
+
+void framegen_sacfg(struct dpu_framegen *fg, unsigned int x, unsigned int y)
+{
+ mutex_lock(&fg->mutex);
+ dpu_fg_write(fg, STARTX(x) | STARTY(y), SACFG);
+ mutex_unlock(&fg->mutex);
+}
+EXPORT_SYMBOL_GPL(framegen_sacfg);
+
+void framegen_displaymode(struct dpu_framegen *fg, fgdm_t mode)
+{
+ u32 val;
+
+ mutex_lock(&fg->mutex);
+ val = dpu_fg_read(fg, FGINCTRL);
+ val &= ~FGDM_MASK;
+ val |= mode;
+ dpu_fg_write(fg, val, FGINCTRL);
+ mutex_unlock(&fg->mutex);
+}
+EXPORT_SYMBOL_GPL(framegen_displaymode);
+
+void framegen_panic_displaymode(struct dpu_framegen *fg, fgdm_t mode)
+{
+ u32 val;
+
+ mutex_lock(&fg->mutex);
+ val = dpu_fg_read(fg, FGINCTRLPANIC);
+ val &= ~FGDM_MASK;
+ val |= mode;
+ dpu_fg_write(fg, val, FGINCTRLPANIC);
+ mutex_unlock(&fg->mutex);
+}
+EXPORT_SYMBOL_GPL(framegen_panic_displaymode);
+
+void framegen_wait_done(struct dpu_framegen *fg, struct drm_display_mode *m)
+{
+ unsigned long timeout, pending_framedur_jiffies;
+ int frame_size = m->crtc_htotal * m->crtc_vtotal;
+ int dotclock, pending_framedur_ns;
+ u32 val;
+
+ dotclock = clk_get_rate(fg->clk_disp) / KHZ;
+ if (dotclock == 0) {
+ /* fall back to display mode's clock */
+ dotclock = m->crtc_clock;
+
+ if (!(fg->side_by_side && fg->id == 1))
+ dev_warn(fg->dpu->dev,
+ "pixel clock for FrameGen%d is zero\n", fg->id);
+ }
+
+ /*
+ * The SoC designer indicates that there are two pending frames
+ * to complete in the worst case.
+ * So, three pending frames are enough for sure.
+ */
+ pending_framedur_ns = div_u64((u64) 3 * frame_size * 1000000, dotclock);
+ pending_framedur_jiffies = nsecs_to_jiffies(pending_framedur_ns);
+ if (pending_framedur_jiffies > (3 * HZ)) {
+ pending_framedur_jiffies = 3 * HZ;
+
+ dev_warn(fg->dpu->dev,
+ "truncate FrameGen%d pending frame duration to 3sec\n",
+ fg->id);
+ }
+ timeout = jiffies + pending_framedur_jiffies;
+
+ mutex_lock(&fg->mutex);
+ do {
+ val = dpu_fg_read(fg, FGENSTS);
+ } while ((val & ENSTS) && time_before(jiffies, timeout));
+ mutex_unlock(&fg->mutex);
+
+ dev_dbg(fg->dpu->dev, "FrameGen%d pending frame duration is %ums\n",
+ fg->id, jiffies_to_msecs(pending_framedur_jiffies));
+
+ if (val & ENSTS)
+ dev_err(fg->dpu->dev, "failed to wait for FrameGen%d done\n",
+ fg->id);
+}
+EXPORT_SYMBOL_GPL(framegen_wait_done);
+
+static inline u32 framegen_frame_index(u32 stamp)
+{
+ return (stamp & FRAMEINDEX_MASK) >> FRAMEINDEX_SHIFT;
+}
+
+static inline u32 framegen_line_index(u32 stamp)
+{
+ return (stamp & LINEINDEX_MASK) >> LINEINDEX_SHIFT;
+}
+
+void framegen_read_timestamp(struct dpu_framegen *fg,
+ u32 *frame_index, u32 *line_index)
+{
+ u32 stamp;
+
+ mutex_lock(&fg->mutex);
+ stamp = dpu_fg_read(fg, FGTIMESTAMP);
+ *frame_index = framegen_frame_index(stamp);
+ *line_index = framegen_line_index(stamp);
+ mutex_unlock(&fg->mutex);
+}
+EXPORT_SYMBOL_GPL(framegen_read_timestamp);
+
+void framegen_wait_for_frame_counter_moving(struct dpu_framegen *fg)
+{
+ u32 frame_index, line_index, last_frame_index;
+ unsigned long timeout = jiffies + msecs_to_jiffies(50);
+
+ framegen_read_timestamp(fg, &frame_index, &line_index);
+ do {
+ last_frame_index = frame_index;
+ framegen_read_timestamp(fg, &frame_index, &line_index);
+ } while (last_frame_index == frame_index &&
+ time_before(jiffies, timeout));
+
+ if (last_frame_index == frame_index)
+ dev_err(fg->dpu->dev,
+ "failed to wait for FrameGen%d frame counter moving\n",
+ fg->id);
+ else
+ dev_dbg(fg->dpu->dev,
+ "FrameGen%d frame counter moves - last %u, curr %d\n",
+ fg->id, last_frame_index, frame_index);
+}
+EXPORT_SYMBOL_GPL(framegen_wait_for_frame_counter_moving);
+
+bool framegen_secondary_requests_to_read_empty_fifo(struct dpu_framegen *fg)
+{
+ u32 val;
+ bool empty;
+
+ mutex_lock(&fg->mutex);
+ val = dpu_fg_read(fg, FGCHSTAT);
+ mutex_unlock(&fg->mutex);
+
+ empty = !!(val & SFIFOEMPTY);
+
+ if (empty)
+ dev_dbg(fg->dpu->dev,
+ "FrameGen%d secondary requests to read empty FIFO\n",
+ fg->id);
+
+ return empty;
+}
+EXPORT_SYMBOL_GPL(framegen_secondary_requests_to_read_empty_fifo);
+
+void framegen_secondary_clear_channel_status(struct dpu_framegen *fg)
+{
+ mutex_lock(&fg->mutex);
+ dpu_fg_write(fg, CLRSECSTAT, FGCHSTATCLR);
+ mutex_unlock(&fg->mutex);
+}
+EXPORT_SYMBOL_GPL(framegen_secondary_clear_channel_status);
+
+bool framegen_secondary_is_syncup(struct dpu_framegen *fg)
+{
+ u32 val;
+
+ mutex_lock(&fg->mutex);
+ val = dpu_fg_read(fg, FGCHSTAT);
+ mutex_unlock(&fg->mutex);
+
+ return val & SECSYNCSTAT;
+}
+EXPORT_SYMBOL_GPL(framegen_secondary_is_syncup);
+
+void framegen_wait_for_secondary_syncup(struct dpu_framegen *fg)
+{
+ unsigned long timeout = jiffies + msecs_to_jiffies(100);
+ bool syncup;
+
+ do {
+ syncup = framegen_secondary_is_syncup(fg);
+ } while (!syncup && time_before(jiffies, timeout));
+
+ if (syncup)
+ dev_dbg(fg->dpu->dev, "FrameGen%d secondary syncup\n", fg->id);
+ else
+ dev_err(fg->dpu->dev,
+ "failed to wait for FrameGen%d secondary syncup\n",
+ fg->id);
+}
+EXPORT_SYMBOL_GPL(framegen_wait_for_secondary_syncup);
+
+void framegen_enable_clock(struct dpu_framegen *fg)
+{
+ if (!fg->use_bypass_clk)
+ clk_prepare_enable(fg->clk_pll);
+ clk_prepare_enable(fg->clk_disp);
+}
+EXPORT_SYMBOL_GPL(framegen_enable_clock);
+
+void framegen_disable_clock(struct dpu_framegen *fg)
+{
+ if (!fg->use_bypass_clk)
+ clk_disable_unprepare(fg->clk_pll);
+ clk_disable_unprepare(fg->clk_disp);
+}
+EXPORT_SYMBOL_GPL(framegen_disable_clock);
+
+bool framegen_is_master(struct dpu_framegen *fg)
+{
+ const struct dpu_devtype *devtype = fg->dpu->devtype;
+
+ return fg->id == devtype->master_stream_id;
+}
+EXPORT_SYMBOL_GPL(framegen_is_master);
+
+bool framegen_is_slave(struct dpu_framegen *fg)
+{
+ return !framegen_is_master(fg);
+}
+EXPORT_SYMBOL_GPL(framegen_is_slave);
+
+struct dpu_framegen *dpu_fg_get(struct dpu_soc *dpu, int id)
+{
+ struct dpu_framegen *fg;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(fg_ids); i++)
+ if (fg_ids[i] == id)
+ break;
+
+ if (i == ARRAY_SIZE(fg_ids))
+ return ERR_PTR(-EINVAL);
+
+ fg = dpu->fg_priv[i];
+
+ mutex_lock(&fg->mutex);
+
+ if (fg->inuse) {
+ mutex_unlock(&fg->mutex);
+ return ERR_PTR(-EBUSY);
+ }
+
+ fg->inuse = true;
+
+ mutex_unlock(&fg->mutex);
+
+ return fg;
+}
+EXPORT_SYMBOL_GPL(dpu_fg_get);
+
+void dpu_fg_put(struct dpu_framegen *fg)
+{
+ mutex_lock(&fg->mutex);
+
+ fg->inuse = false;
+
+ mutex_unlock(&fg->mutex);
+}
+EXPORT_SYMBOL_GPL(dpu_fg_put);
+
+struct dpu_framegen *dpu_aux_fg_peek(struct dpu_framegen *fg)
+{
+ return fg->dpu->fg_priv[fg->id ^ 1];
+}
+EXPORT_SYMBOL_GPL(dpu_aux_fg_peek);
+
+void _dpu_fg_init(struct dpu_soc *dpu, unsigned int id)
+{
+ struct dpu_framegen *fg;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(fg_ids); i++)
+ if (fg_ids[i] == id)
+ break;
+
+ if (WARN_ON(i == ARRAY_SIZE(fg_ids)))
+ return;
+
+ fg = dpu->fg_priv[i];
+
+ framegen_syncmode(fg, FGSYNCMODE__OFF);
+}
+
+int dpu_fg_init(struct dpu_soc *dpu, unsigned int id,
+ unsigned long unused, unsigned long base)
+{
+ struct dpu_framegen *fg;
+
+ fg = devm_kzalloc(dpu->dev, sizeof(*fg), GFP_KERNEL);
+ if (!fg)
+ return -ENOMEM;
+
+ dpu->fg_priv[id] = fg;
+
+ fg->base = devm_ioremap(dpu->dev, base, SZ_256);
+ if (!fg->base)
+ return -ENOMEM;
+
+ fg->clk_pll = devm_clk_get(dpu->dev, id ? "pll1" : "pll0");
+ if (IS_ERR(fg->clk_pll))
+ return PTR_ERR(fg->clk_pll);
+
+ if (dpu->devtype->has_disp_sel_clk) {
+ fg->clk_bypass = devm_clk_get(dpu->dev, "bypass0");
+ if (IS_ERR(fg->clk_bypass))
+ return PTR_ERR(fg->clk_bypass);
+
+ fg->clk_disp_sel = devm_clk_get(dpu->dev,
+ id ? "disp1_sel" : "disp0_sel");
+ if (IS_ERR(fg->clk_disp_sel))
+ return PTR_ERR(fg->clk_disp_sel);
+ }
+
+ fg->clk_disp = devm_clk_get(dpu->dev, id ? "disp1" : "disp0");
+ if (IS_ERR(fg->clk_disp))
+ return PTR_ERR(fg->clk_disp);
+
+ fg->dpu = dpu;
+ fg->id = id;
+ mutex_init(&fg->mutex);
+
+ _dpu_fg_init(dpu, id);
+
+ return 0;
+}
diff --git a/drivers/gpu/imx/dpu/dpu-hscaler.c b/drivers/gpu/imx/dpu/dpu-hscaler.c
new file mode 100644
index 000000000000..c3fc63d5ef3b
--- /dev/null
+++ b/drivers/gpu/imx/dpu/dpu-hscaler.c
@@ -0,0 +1,395 @@
+/*
+ * Copyright 2017-2018 NXP
+ *
+ * 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/io.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/platform_device.h>
+#include <linux/types.h>
+#include <video/dpu.h>
+#include "dpu-prv.h"
+
+#define PIXENGCFG_DYNAMIC 0x8
+#define PIXENGCFG_DYNAMIC_SRC_SEL_MASK 0x3F
+
+#define SETUP1 0xC
+#define SCALE_FACTOR_MASK 0xFFFFF
+#define SCALE_FACTOR(n) ((n) & 0xFFFFF)
+#define SETUP2 0x10
+#define PHASE_OFFSET_MASK 0x1FFFFF
+#define PHASE_OFFSET(n) ((n) & 0x1FFFFF)
+#define CONTROL 0x14
+#define OUTPUT_SIZE_MASK 0x3FFF0000
+#define OUTPUT_SIZE(n) ((((n) - 1) << 16) & OUTPUT_SIZE_MASK)
+#define FILTER_MODE 0x100
+#define SCALE_MODE 0x10
+#define MODE 0x1
+
+static const hs_src_sel_t src_sels[3][6] = {
+ {
+ HS_SRC_SEL__DISABLE,
+ HS_SRC_SEL__EXTSRC4,
+ HS_SRC_SEL__FETCHDECODE0,
+ HS_SRC_SEL__FETCHDECODE2,
+ HS_SRC_SEL__MATRIX4,
+ HS_SRC_SEL__VSCALER4,
+ }, {
+ HS_SRC_SEL__DISABLE,
+ HS_SRC_SEL__EXTSRC5,
+ HS_SRC_SEL__FETCHDECODE1,
+ HS_SRC_SEL__FETCHDECODE3,
+ HS_SRC_SEL__MATRIX5,
+ HS_SRC_SEL__VSCALER5,
+ }, {
+ HS_SRC_SEL__DISABLE,
+ HS_SRC_SEL__MATRIX9,
+ HS_SRC_SEL__VSCALER9,
+ HS_SRC_SEL__FILTER9,
+ },
+};
+
+struct dpu_hscaler {
+ void __iomem *pec_base;
+ void __iomem *base;
+ struct mutex mutex;
+ int id;
+ bool inuse;
+ struct dpu_soc *dpu;
+ /* see DPU_PLANE_SRC_xxx */
+ unsigned int stream_id;
+};
+
+static inline u32 dpu_pec_hs_read(struct dpu_hscaler *hs,
+ unsigned int offset)
+{
+ return readl(hs->pec_base + offset);
+}
+
+static inline void dpu_pec_hs_write(struct dpu_hscaler *hs, u32 value,
+ unsigned int offset)
+{
+ writel(value, hs->pec_base + offset);
+}
+
+static inline u32 dpu_hs_read(struct dpu_hscaler *hs, unsigned int offset)
+{
+ return readl(hs->base + offset);
+}
+
+static inline void dpu_hs_write(struct dpu_hscaler *hs, u32 value,
+ unsigned int offset)
+{
+ writel(value, hs->base + offset);
+}
+
+int hscaler_pixengcfg_dynamic_src_sel(struct dpu_hscaler *hs, hs_src_sel_t src)
+{
+ struct dpu_soc *dpu = hs->dpu;
+ const unsigned int *block_id_map = dpu->devtype->sw2hw_block_id_map;
+ const unsigned int hs_id_array[] = {4, 5, 9};
+ int i, j;
+ u32 val, mapped_src;
+
+ for (i = 0; i < ARRAY_SIZE(hs_id_array); i++)
+ if (hs_id_array[i] == hs->id)
+ break;
+
+ if (WARN_ON(i == ARRAY_SIZE(hs_id_array)))
+ return -EINVAL;
+
+ mutex_lock(&hs->mutex);
+ for (j = 0; j < ARRAY_SIZE(src_sels[0]); j++) {
+ if (src_sels[i][j] == src) {
+ mapped_src = block_id_map ? block_id_map[src] : src;
+ if (WARN_ON(mapped_src == NA))
+ return -EINVAL;
+
+ val = dpu_pec_hs_read(hs, PIXENGCFG_DYNAMIC);
+ val &= ~PIXENGCFG_DYNAMIC_SRC_SEL_MASK;
+ val |= mapped_src;
+ dpu_pec_hs_write(hs, val, PIXENGCFG_DYNAMIC);
+ mutex_unlock(&hs->mutex);
+ return 0;
+ }
+ }
+ mutex_unlock(&hs->mutex);
+
+ dev_err(dpu->dev, "Invalid source for HScaler%d\n", hs->id);
+
+ return -EINVAL;
+}
+EXPORT_SYMBOL_GPL(hscaler_pixengcfg_dynamic_src_sel);
+
+void hscaler_pixengcfg_clken(struct dpu_hscaler *hs, pixengcfg_clken_t clken)
+{
+ u32 val;
+
+ mutex_lock(&hs->mutex);
+ val = dpu_pec_hs_read(hs, PIXENGCFG_DYNAMIC);
+ val &= ~CLKEN_MASK;
+ val |= clken << CLKEN_MASK_SHIFT;
+ dpu_pec_hs_write(hs, val, PIXENGCFG_DYNAMIC);
+ mutex_unlock(&hs->mutex);
+}
+EXPORT_SYMBOL_GPL(hscaler_pixengcfg_clken);
+
+void hscaler_shden(struct dpu_hscaler *hs, bool enable)
+{
+ u32 val;
+
+ mutex_lock(&hs->mutex);
+ val = dpu_hs_read(hs, STATICCONTROL);
+ if (enable)
+ val |= SHDEN;
+ else
+ val &= ~SHDEN;
+ dpu_hs_write(hs, val, STATICCONTROL);
+ mutex_unlock(&hs->mutex);
+}
+EXPORT_SYMBOL_GPL(hscaler_shden);
+
+void hscaler_setup1(struct dpu_hscaler *hs, u32 src, u32 dst)
+{
+ struct dpu_soc *dpu = hs->dpu;
+ u32 scale_factor;
+ u64 tmp64;
+
+ if (src == dst) {
+ scale_factor = 0x80000;
+ } else {
+ if (src > dst) {
+ tmp64 = (u64)((u64)dst * 0x80000);
+ do_div(tmp64, src);
+
+ } else {
+ tmp64 = (u64)((u64)src * 0x80000);
+ do_div(tmp64, dst);
+ }
+ scale_factor = (u32)tmp64;
+ }
+
+ WARN_ON(scale_factor > 0x80000);
+
+ mutex_lock(&hs->mutex);
+ dpu_hs_write(hs, SCALE_FACTOR(scale_factor), SETUP1);
+ mutex_unlock(&hs->mutex);
+
+ dev_dbg(dpu->dev, "Hscaler%d scale factor 0x%08x\n",
+ hs->id, scale_factor);
+}
+EXPORT_SYMBOL_GPL(hscaler_setup1);
+
+void hscaler_setup2(struct dpu_hscaler *hs, u32 phase_offset)
+{
+ mutex_lock(&hs->mutex);
+ dpu_hs_write(hs, PHASE_OFFSET(phase_offset), SETUP2);
+ mutex_unlock(&hs->mutex);
+}
+EXPORT_SYMBOL_GPL(hscaler_setup2);
+
+void hscaler_output_size(struct dpu_hscaler *hs, u32 line_num)
+{
+ u32 val;
+
+ mutex_lock(&hs->mutex);
+ val = dpu_hs_read(hs, CONTROL);
+ val &= ~OUTPUT_SIZE_MASK;
+ val |= OUTPUT_SIZE(line_num);
+ dpu_hs_write(hs, val, CONTROL);
+ mutex_unlock(&hs->mutex);
+}
+EXPORT_SYMBOL_GPL(hscaler_output_size);
+
+void hscaler_filter_mode(struct dpu_hscaler *hs, scaler_filter_mode_t m)
+{
+ u32 val;
+
+ mutex_lock(&hs->mutex);
+ val = dpu_hs_read(hs, CONTROL);
+ val &= ~FILTER_MODE;
+ val |= m;
+ dpu_hs_write(hs, val, CONTROL);
+ mutex_unlock(&hs->mutex);
+}
+EXPORT_SYMBOL_GPL(hscaler_filter_mode);
+
+void hscaler_scale_mode(struct dpu_hscaler *hs, scaler_scale_mode_t m)
+{
+ u32 val;
+
+ mutex_lock(&hs->mutex);
+ val = dpu_hs_read(hs, CONTROL);
+ val &= ~SCALE_MODE;
+ val |= m;
+ dpu_hs_write(hs, val, CONTROL);
+ mutex_unlock(&hs->mutex);
+}
+EXPORT_SYMBOL_GPL(hscaler_scale_mode);
+
+void hscaler_mode(struct dpu_hscaler *hs, scaler_mode_t m)
+{
+ u32 val;
+
+ mutex_lock(&hs->mutex);
+ val = dpu_hs_read(hs, CONTROL);
+ val &= ~MODE;
+ val |= m;
+ dpu_hs_write(hs, val, CONTROL);
+ mutex_unlock(&hs->mutex);
+}
+EXPORT_SYMBOL_GPL(hscaler_mode);
+
+bool hscaler_is_enabled(struct dpu_hscaler *hs)
+{
+ u32 val;
+
+ mutex_lock(&hs->mutex);
+ val = dpu_hs_read(hs, CONTROL);
+ mutex_unlock(&hs->mutex);
+
+ return (val & MODE) == SCALER_ACTIVE;
+}
+EXPORT_SYMBOL_GPL(hscaler_is_enabled);
+
+dpu_block_id_t hscaler_get_block_id(struct dpu_hscaler *hs)
+{
+ switch (hs->id) {
+ case 4:
+ return ID_HSCALER4;
+ case 5:
+ return ID_HSCALER5;
+ case 9:
+ return ID_HSCALER9;
+ default:
+ WARN_ON(1);
+ }
+
+ return ID_NONE;
+}
+EXPORT_SYMBOL_GPL(hscaler_get_block_id);
+
+unsigned int hscaler_get_stream_id(struct dpu_hscaler *hs)
+{
+ return hs->stream_id;
+}
+EXPORT_SYMBOL_GPL(hscaler_get_stream_id);
+
+void hscaler_set_stream_id(struct dpu_hscaler *hs, unsigned int id)
+{
+ switch (id) {
+ case DPU_PLANE_SRC_TO_DISP_STREAM0:
+ case DPU_PLANE_SRC_TO_DISP_STREAM1:
+ case DPU_PLANE_SRC_DISABLED:
+ hs->stream_id = id;
+ break;
+ default:
+ WARN_ON(1);
+ }
+}
+EXPORT_SYMBOL_GPL(hscaler_set_stream_id);
+
+struct dpu_hscaler *dpu_hs_get(struct dpu_soc *dpu, int id)
+{
+ struct dpu_hscaler *hs;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(hs_ids); i++)
+ if (hs_ids[i] == id)
+ break;
+
+ if (i == ARRAY_SIZE(hs_ids))
+ return ERR_PTR(-EINVAL);
+
+ hs = dpu->hs_priv[i];
+
+ mutex_lock(&hs->mutex);
+
+ if (hs->inuse) {
+ mutex_unlock(&hs->mutex);
+ return ERR_PTR(-EBUSY);
+ }
+
+ hs->inuse = true;
+
+ mutex_unlock(&hs->mutex);
+
+ return hs;
+}
+EXPORT_SYMBOL_GPL(dpu_hs_get);
+
+void dpu_hs_put(struct dpu_hscaler *hs)
+{
+ mutex_lock(&hs->mutex);
+
+ hs->inuse = false;
+
+ mutex_unlock(&hs->mutex);
+}
+EXPORT_SYMBOL_GPL(dpu_hs_put);
+
+void _dpu_hs_init(struct dpu_soc *dpu, unsigned int id)
+{
+ struct dpu_hscaler *hs;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(hs_ids); i++)
+ if (hs_ids[i] == id)
+ break;
+
+ if (WARN_ON(i == ARRAY_SIZE(hs_ids)))
+ return;
+
+ hs = dpu->hs_priv[i];
+
+ hscaler_shden(hs, true);
+ hscaler_setup2(hs, 0);
+ hscaler_pixengcfg_dynamic_src_sel(hs, HS_SRC_SEL__DISABLE);
+}
+
+int dpu_hs_init(struct dpu_soc *dpu, unsigned int id,
+ unsigned long pec_base, unsigned long base)
+{
+ struct dpu_hscaler *hs;
+ int i;
+
+ hs = devm_kzalloc(dpu->dev, sizeof(*hs), GFP_KERNEL);
+ if (!hs)
+ return -ENOMEM;
+
+ for (i = 0; i < ARRAY_SIZE(hs_ids); i++)
+ if (hs_ids[i] == id)
+ break;
+
+ if (i == ARRAY_SIZE(hs_ids))
+ return -EINVAL;
+
+ dpu->hs_priv[i] = hs;
+
+ hs->pec_base = devm_ioremap(dpu->dev, pec_base, SZ_8);
+ if (!hs->pec_base)
+ return -ENOMEM;
+
+ hs->base = devm_ioremap(dpu->dev, base, SZ_1K);
+ if (!hs->base)
+ return -ENOMEM;
+
+ hs->dpu = dpu;
+ hs->id = id;
+
+ mutex_init(&hs->mutex);
+
+ _dpu_hs_init(dpu, id);
+
+ return 0;
+}
diff --git a/drivers/gpu/imx/dpu/dpu-layerblend.c b/drivers/gpu/imx/dpu/dpu-layerblend.c
new file mode 100644
index 000000000000..0ca322155bd8
--- /dev/null
+++ b/drivers/gpu/imx/dpu/dpu-layerblend.c
@@ -0,0 +1,343 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017-2018 NXP
+ *
+ * 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/io.h>
+#include <linux/mutex.h>
+#include <linux/platform_device.h>
+#include <linux/types.h>
+#include <video/dpu.h>
+#include "dpu-prv.h"
+
+#define PIXENGCFG_DYNAMIC 0x8
+#define PIXENGCFG_DYNAMIC_PRIM_SEL_MASK 0x3F
+#define PIXENGCFG_DYNAMIC_SEC_SEL_MASK 0x3F00
+#define PIXENGCFG_DYNAMIC_SEC_SEL_SHIFT 8
+
+static const lb_prim_sel_t prim_sels[] = {
+ LB_PRIM_SEL__DISABLE,
+ LB_PRIM_SEL__BLITBLEND9,
+ LB_PRIM_SEL__CONSTFRAME0,
+ LB_PRIM_SEL__CONSTFRAME1,
+ LB_PRIM_SEL__CONSTFRAME4,
+ LB_PRIM_SEL__CONSTFRAME5,
+ LB_PRIM_SEL__MATRIX4,
+ LB_PRIM_SEL__HSCALER4,
+ LB_PRIM_SEL__VSCALER4,
+ LB_PRIM_SEL__EXTSRC4,
+ LB_PRIM_SEL__MATRIX5,
+ LB_PRIM_SEL__HSCALER5,
+ LB_PRIM_SEL__VSCALER5,
+ LB_PRIM_SEL__EXTSRC5,
+ LB_PRIM_SEL__LAYERBLEND0,
+ LB_PRIM_SEL__LAYERBLEND1,
+ LB_PRIM_SEL__LAYERBLEND2,
+ LB_PRIM_SEL__LAYERBLEND3,
+ LB_PRIM_SEL__LAYERBLEND4,
+ LB_PRIM_SEL__LAYERBLEND5,
+};
+
+#define PIXENGCFG_STATUS 0xC
+#define SHDTOKSEL (0x3 << 3)
+#define SHDTOKSEL_SHIFT 3
+#define SHDLDSEL (0x3 << 1)
+#define SHDLDSEL_SHIFT 1
+#define CONTROL 0xC
+#define MODE_MASK BIT(0)
+#define BLENDCONTROL 0x10
+#define ALPHA(a) (((a) & 0xFF) << 16)
+#define PRIM_C_BLD_FUNC__ONE_MINUS_SEC_ALPHA 0x5
+#define PRIM_C_BLD_FUNC__PRIM_ALPHA 0x2
+#define SEC_C_BLD_FUNC__CONST_ALPHA (0x6 << 4)
+#define SEC_C_BLD_FUNC__ONE_MINUS_PRIM_ALPHA (0x3 << 4)
+#define PRIM_A_BLD_FUNC__ONE_MINUS_SEC_ALPHA (0x5 << 8)
+#define PRIM_A_BLD_FUNC__ZERO (0x0 << 8)
+#define SEC_A_BLD_FUNC__ONE (0x1 << 12)
+#define SEC_A_BLD_FUNC__ZERO (0x0 << 12)
+#define POSITION 0x14
+#define XPOS(x) ((x) & 0x7FFF)
+#define YPOS(y) (((y) & 0x7FFF) << 16)
+#define PRIMCONTROLWORD 0x18
+#define SECCONTROLWORD 0x1C
+
+struct dpu_layerblend {
+ void __iomem *pec_base;
+ void __iomem *base;
+ struct mutex mutex;
+ int id;
+ bool inuse;
+ struct dpu_soc *dpu;
+};
+
+static inline u32 dpu_pec_lb_read(struct dpu_layerblend *lb,
+ unsigned int offset)
+{
+ return readl(lb->pec_base + offset);
+}
+
+static inline void dpu_pec_lb_write(struct dpu_layerblend *lb, u32 value,
+ unsigned int offset)
+{
+ writel(value, lb->pec_base + offset);
+}
+
+static inline u32 dpu_lb_read(struct dpu_layerblend *lb, unsigned int offset)
+{
+ return readl(lb->base + offset);
+}
+
+static inline void dpu_lb_write(struct dpu_layerblend *lb, u32 value,
+ unsigned int offset)
+{
+ writel(value, lb->base + offset);
+}
+
+int layerblend_pixengcfg_dynamic_prim_sel(struct dpu_layerblend *lb,
+ lb_prim_sel_t prim)
+{
+ struct dpu_soc *dpu = lb->dpu;
+ const unsigned int *block_id_map = dpu->devtype->sw2hw_block_id_map;
+ int fixed_sels_num = ARRAY_SIZE(prim_sels) - 6;
+ int i;
+ u32 val, mapped_prim;
+
+ mutex_lock(&lb->mutex);
+ for (i = 0; i < fixed_sels_num + lb->id; i++) {
+ if (prim_sels[i] == prim) {
+ mapped_prim = block_id_map ? block_id_map[prim] : prim;
+ if (WARN_ON(mapped_prim == NA))
+ return -EINVAL;
+
+ val = dpu_pec_lb_read(lb, PIXENGCFG_DYNAMIC);
+ val &= ~PIXENGCFG_DYNAMIC_PRIM_SEL_MASK;
+ val |= mapped_prim;
+ dpu_pec_lb_write(lb, val, PIXENGCFG_DYNAMIC);
+ mutex_unlock(&lb->mutex);
+ return 0;
+ }
+ }
+ mutex_unlock(&lb->mutex);
+
+ dev_err(dpu->dev, "Invalid primary source for LayerBlend%d\n", lb->id);
+
+ return -EINVAL;
+}
+EXPORT_SYMBOL_GPL(layerblend_pixengcfg_dynamic_prim_sel);
+
+void layerblend_pixengcfg_dynamic_sec_sel(struct dpu_layerblend *lb,
+ lb_sec_sel_t sec)
+{
+ struct dpu_soc *dpu = lb->dpu;
+ const unsigned int *block_id_map = dpu->devtype->sw2hw_block_id_map;
+ u32 val, mapped_sec;
+
+ mapped_sec = block_id_map ? block_id_map[sec] : sec;
+ if (WARN_ON(mapped_sec == NA))
+ return;
+
+ mutex_lock(&lb->mutex);
+ val = dpu_pec_lb_read(lb, PIXENGCFG_DYNAMIC);
+ val &= ~PIXENGCFG_DYNAMIC_SEC_SEL_MASK;
+ val |= mapped_sec << PIXENGCFG_DYNAMIC_SEC_SEL_SHIFT;
+ dpu_pec_lb_write(lb, val, PIXENGCFG_DYNAMIC);
+ mutex_unlock(&lb->mutex);
+}
+EXPORT_SYMBOL_GPL(layerblend_pixengcfg_dynamic_sec_sel);
+
+void layerblend_pixengcfg_clken(struct dpu_layerblend *lb,
+ pixengcfg_clken_t clken)
+{
+ u32 val;
+
+ mutex_lock(&lb->mutex);
+ val = dpu_pec_lb_read(lb, PIXENGCFG_DYNAMIC);
+ val &= ~CLKEN_MASK;
+ val |= clken << CLKEN_MASK_SHIFT;
+ dpu_pec_lb_write(lb, val, PIXENGCFG_DYNAMIC);
+ mutex_unlock(&lb->mutex);
+}
+EXPORT_SYMBOL_GPL(layerblend_pixengcfg_clken);
+
+void layerblend_shden(struct dpu_layerblend *lb, bool enable)
+{
+ u32 val;
+
+ mutex_lock(&lb->mutex);
+ val = dpu_lb_read(lb, STATICCONTROL);
+ if (enable)
+ val |= SHDEN;
+ else
+ val &= ~SHDEN;
+ dpu_lb_write(lb, val, STATICCONTROL);
+ mutex_unlock(&lb->mutex);
+}
+EXPORT_SYMBOL_GPL(layerblend_shden);
+
+void layerblend_shdtoksel(struct dpu_layerblend *lb, lb_shadow_sel_t sel)
+{
+ u32 val;
+
+ mutex_lock(&lb->mutex);
+ val = dpu_lb_read(lb, STATICCONTROL);
+ val &= ~SHDTOKSEL;
+ val |= (sel << SHDTOKSEL_SHIFT);
+ dpu_lb_write(lb, val, STATICCONTROL);
+ mutex_unlock(&lb->mutex);
+}
+EXPORT_SYMBOL_GPL(layerblend_shdtoksel);
+
+void layerblend_shdldsel(struct dpu_layerblend *lb, lb_shadow_sel_t sel)
+{
+ u32 val;
+
+ mutex_lock(&lb->mutex);
+ val = dpu_lb_read(lb, STATICCONTROL);
+ val &= ~SHDLDSEL;
+ val |= (sel << SHDLDSEL_SHIFT);
+ dpu_lb_write(lb, val, STATICCONTROL);
+ mutex_unlock(&lb->mutex);
+}
+EXPORT_SYMBOL_GPL(layerblend_shdldsel);
+
+void layerblend_control(struct dpu_layerblend *lb, lb_mode_t mode)
+{
+ u32 val;
+
+ mutex_lock(&lb->mutex);
+ val = dpu_lb_read(lb, CONTROL);
+ val &= ~MODE_MASK;
+ val |= mode;
+ dpu_lb_write(lb, val, CONTROL);
+ mutex_unlock(&lb->mutex);
+}
+EXPORT_SYMBOL_GPL(layerblend_control);
+
+void layerblend_blendcontrol(struct dpu_layerblend *lb, bool sec_from_scaler)
+{
+ u32 val;
+
+ val = ALPHA(0xff) |
+ PRIM_C_BLD_FUNC__PRIM_ALPHA |
+ SEC_C_BLD_FUNC__ONE_MINUS_PRIM_ALPHA |
+ PRIM_A_BLD_FUNC__ZERO;
+
+ val |= sec_from_scaler ? SEC_A_BLD_FUNC__ZERO : SEC_A_BLD_FUNC__ONE;
+
+ mutex_lock(&lb->mutex);
+ dpu_lb_write(lb, val, BLENDCONTROL);
+ mutex_unlock(&lb->mutex);
+}
+EXPORT_SYMBOL_GPL(layerblend_blendcontrol);
+
+void layerblend_position(struct dpu_layerblend *lb, int x, int y)
+{
+ mutex_lock(&lb->mutex);
+ dpu_lb_write(lb, XPOS(x) | YPOS(y), POSITION);
+ mutex_unlock(&lb->mutex);
+}
+EXPORT_SYMBOL_GPL(layerblend_position);
+
+struct dpu_layerblend *dpu_lb_get(struct dpu_soc *dpu, int id)
+{
+ struct dpu_layerblend *lb;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(lb_ids); i++)
+ if (lb_ids[i] == id)
+ break;
+
+ if (i == ARRAY_SIZE(lb_ids))
+ return ERR_PTR(-EINVAL);
+
+ lb = dpu->lb_priv[i];
+
+ mutex_lock(&lb->mutex);
+
+ if (lb->inuse) {
+ mutex_unlock(&lb->mutex);
+ return ERR_PTR(-EBUSY);
+ }
+
+ lb->inuse = true;
+
+ mutex_unlock(&lb->mutex);
+
+ return lb;
+}
+EXPORT_SYMBOL_GPL(dpu_lb_get);
+
+void dpu_lb_put(struct dpu_layerblend *lb)
+{
+ mutex_lock(&lb->mutex);
+
+ lb->inuse = false;
+
+ mutex_unlock(&lb->mutex);
+}
+EXPORT_SYMBOL_GPL(dpu_lb_put);
+
+void _dpu_lb_init(struct dpu_soc *dpu, unsigned int id)
+{
+ struct dpu_layerblend *lb;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(lb_ids); i++)
+ if (lb_ids[i] == id)
+ break;
+
+ if (WARN_ON(i == ARRAY_SIZE(lb_ids)))
+ return;
+
+ lb = dpu->lb_priv[i];
+
+ layerblend_pixengcfg_dynamic_prim_sel(lb, LB_PRIM_SEL__DISABLE);
+ layerblend_pixengcfg_dynamic_sec_sel(lb, LB_SEC_SEL__DISABLE);
+ layerblend_pixengcfg_clken(lb, CLKEN__AUTOMATIC);
+ layerblend_shdldsel(lb, BOTH);
+ layerblend_shdtoksel(lb, BOTH);
+ layerblend_shden(lb, true);
+}
+
+int dpu_lb_init(struct dpu_soc *dpu, unsigned int id,
+ unsigned long pec_base, unsigned long base)
+{
+ struct dpu_layerblend *lb;
+ int ret;
+
+ lb = devm_kzalloc(dpu->dev, sizeof(*lb), GFP_KERNEL);
+ if (!lb)
+ return -ENOMEM;
+
+ dpu->lb_priv[id] = lb;
+
+ lb->pec_base = devm_ioremap(dpu->dev, pec_base, SZ_16);
+ if (!lb->pec_base)
+ return -ENOMEM;
+
+ lb->base = devm_ioremap(dpu->dev, base, SZ_32);
+ if (!lb->base)
+ return -ENOMEM;
+
+ lb->dpu = dpu;
+ lb->id = id;
+ mutex_init(&lb->mutex);
+
+ ret = layerblend_pixengcfg_dynamic_prim_sel(lb, LB_PRIM_SEL__DISABLE);
+ if (ret < 0)
+ return ret;
+
+ _dpu_lb_init(dpu, id);
+
+ return 0;
+}
diff --git a/drivers/gpu/imx/dpu/dpu-prv.h b/drivers/gpu/imx/dpu/dpu-prv.h
new file mode 100644
index 000000000000..a7da1ed8f843
--- /dev/null
+++ b/drivers/gpu/imx/dpu/dpu-prv.h
@@ -0,0 +1,441 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017-2018 NXP
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+#ifndef __DPU_PRV_H__
+#define __DPU_PRV_H__
+
+#include <drm/drm_fourcc.h>
+#include <video/dpu.h>
+
+#define NA 0xDEADBEEF /* not available */
+
+#define STATICCONTROL 0x8
+#define SHDLDREQSTICKY(lm) (((lm) & 0xFF) << 24)
+#define SHDLDREQSTICKY_MASK (0xFF << 24)
+#define BASEADDRESSAUTOUPDATE(lm) (((lm) & 0xFF) << 16)
+#define BASEADDRESSAUTOUPDATE_MASK (0xFF << 16)
+#define SHDEN BIT(0)
+#define BURSTBUFFERMANAGEMENT 0xC
+#define SETNUMBUFFERS(n) ((n) & 0xFF)
+#define SETBURSTLENGTH(n) (((n) & 0x1F) << 8)
+#define SETBURSTLENGTH_MASK 0x1F00
+#define LINEMODE_MASK 0x80000000U
+#define LINEMODE_SHIFT 31U
+enum linemode {
+ /*
+ * Mandatory setting for operation in the Display Controller.
+ * Works also for Blit Engine with marginal performance impact.
+ */
+ LINEMODE__DISPLAY = 0,
+ /* Recommended setting for operation in the Blit Engine. */
+ LINEMODE__BLIT = 1 << LINEMODE_SHIFT,
+};
+
+#define BITSPERPIXEL(bpp) (((bpp) & 0x3F) << 16)
+#define STRIDE(n) (((n) - 1) & 0xFFFF)
+#define LINEWIDTH(w) (((w) - 1) & 0x3FFF)
+#define LINECOUNT(h) ((((h) - 1) & 0x3FFF) << 16)
+#define ITUFORMAT BIT(31)
+#define R_BITS(n) (((n) & 0xF) << 24)
+#define G_BITS(n) (((n) & 0xF) << 16)
+#define B_BITS(n) (((n) & 0xF) << 8)
+#define A_BITS(n) ((n) & 0xF)
+#define R_SHIFT(n) (((n) & 0x1F) << 24)
+#define G_SHIFT(n) (((n) & 0x1F) << 16)
+#define B_SHIFT(n) (((n) & 0x1F) << 8)
+#define A_SHIFT(n) ((n) & 0x1F)
+#define Y_BITS(n) R_BITS(n)
+#define Y_BITS_MASK 0xF000000
+#define U_BITS(n) G_BITS(n)
+#define U_BITS_MASK 0xF0000
+#define V_BITS(n) B_BITS(n)
+#define V_BITS_MASK 0xF00
+#define Y_SHIFT(n) R_SHIFT(n)
+#define Y_SHIFT_MASK 0x1F000000
+#define U_SHIFT(n) G_SHIFT(n)
+#define U_SHIFT_MASK 0x1F0000
+#define V_SHIFT(n) B_SHIFT(n)
+#define V_SHIFT_MASK 0x1F00
+#define LAYERXOFFSET(x) ((x) & 0x7FFF)
+#define LAYERYOFFSET(y) (((y) & 0x7FFF) << 16)
+#define CLIPWINDOWXOFFSET(x) ((x) & 0x7FFF)
+#define CLIPWINDOWYOFFSET(y) (((y) & 0x7FFF) << 16)
+#define CLIPWINDOWWIDTH(w) (((w) - 1) & 0x3FFF)
+#define CLIPWINDOWHEIGHT(h) ((((h) - 1) & 0x3FFF) << 16)
+#define PALETTEENABLE BIT(0)
+typedef enum {
+ TILE_FILL_ZERO,
+ TILE_FILL_CONSTANT,
+ TILE_PAD,
+ TILE_PAD_ZERO,
+} tilemode_t;
+#define ALPHASRCENABLE BIT(8)
+#define ALPHACONSTENABLE BIT(9)
+#define ALPHAMASKENABLE BIT(10)
+#define ALPHATRANSENABLE BIT(11)
+#define RGBALPHASRCENABLE BIT(12)
+#define RGBALPHACONSTENABLE BIT(13)
+#define RGBALPHAMASKENABLE BIT(14)
+#define RGBALPHATRANSENABLE BIT(15)
+#define PREMULCONSTRGB BIT(16)
+typedef enum {
+ YUVCONVERSIONMODE__OFF,
+ YUVCONVERSIONMODE__ITU601,
+ YUVCONVERSIONMODE__ITU601_FR,
+ YUVCONVERSIONMODE__ITU709,
+} yuvconversionmode_t;
+#define YUVCONVERSIONMODE_MASK 0x60000
+#define YUVCONVERSIONMODE(m) (((m) & 0x3) << 17)
+#define GAMMAREMOVEENABLE BIT(20)
+#define CLIPWINDOWENABLE BIT(30)
+#define SOURCEBUFFERENABLE BIT(31)
+#define EMPTYFRAME BIT(31)
+#define FRAMEWIDTH(w) (((w) - 1) & 0x3FFF)
+#define FRAMEHEIGHT(h) ((((h) - 1) & 0x3FFF) << 16)
+#define DELTAX_MASK 0x3F000
+#define DELTAY_MASK 0xFC0000
+#define DELTAX(x) (((x) & 0x3F) << 12)
+#define DELTAY(y) (((y) & 0x3F) << 18)
+#define YUV422UPSAMPLINGMODE_MASK BIT(5)
+#define YUV422UPSAMPLINGMODE(m) (((m) & 0x1) << 5)
+typedef enum {
+ YUV422UPSAMPLINGMODE__REPLICATE,
+ YUV422UPSAMPLINGMODE__INTERPOLATE,
+} yuv422upsamplingmode_t;
+#define INPUTSELECT_MASK 0x18
+#define INPUTSELECT(s) (((s) & 0x3) << 3)
+typedef enum {
+ INPUTSELECT__INACTIVE,
+ INPUTSELECT__COMPPACK,
+ INPUTSELECT__ALPHAMASK,
+ INPUTSELECT__COORDINATE,
+} inputselect_t;
+#define RASTERMODE_MASK 0x7
+#define RASTERMODE(m) ((m) & 0x7)
+typedef enum {
+ RASTERMODE__NORMAL,
+ RASTERMODE__DECODE,
+ RASTERMODE__ARBITRARY,
+ RASTERMODE__PERSPECTIVE,
+ RASTERMODE__YUV422,
+ RASTERMODE__AFFINE,
+} rastermode_t;
+#define SHDTOKGEN BIT(0)
+#define FETCHTYPE_MASK 0xF
+
+#define DPU_FRAC_PLANE_LAYER_NUM 8
+
+enum {
+ DPU_V1,
+ DPU_V2,
+};
+
+#define DPU_VPROC_CAP_HSCALER4 BIT(0)
+#define DPU_VPROC_CAP_VSCALER4 BIT(1)
+#define DPU_VPROC_CAP_HSCALER5 BIT(2)
+#define DPU_VPROC_CAP_VSCALER5 BIT(3)
+#define DPU_VPROC_CAP_FETCHECO0 BIT(4)
+#define DPU_VPROC_CAP_FETCHECO1 BIT(5)
+
+#define DPU_VPROC_CAP_HSCALE (DPU_VPROC_CAP_HSCALER4 | \
+ DPU_VPROC_CAP_HSCALER5)
+#define DPU_VPROC_CAP_VSCALE (DPU_VPROC_CAP_VSCALER4 | \
+ DPU_VPROC_CAP_VSCALER5)
+#define DPU_VPROC_CAP_FETCHECO (DPU_VPROC_CAP_FETCHECO0 | \
+ DPU_VPROC_CAP_FETCHECO1)
+
+struct dpu_unit {
+ char *name;
+ unsigned int num;
+ const unsigned int *ids;
+ const unsigned long *pec_ofss; /* PixEngCFG */
+ const unsigned long *ofss;
+ const unsigned int *dprc_ids;
+};
+
+struct cm_reg_ofs {
+ u32 ipidentifier;
+ u32 lockunlock;
+ u32 lockstatus;
+ u32 userinterruptmask;
+ u32 interruptenable;
+ u32 interruptpreset;
+ u32 interruptclear;
+ u32 interruptstatus;
+ u32 userinterruptenable;
+ u32 userinterruptpreset;
+ u32 userinterruptclear;
+ u32 userinterruptstatus;
+ u32 generalpurpose;
+};
+
+struct dpu_devtype {
+ unsigned long cm_ofs; /* common */
+ const struct dpu_unit *cfs;
+ const struct dpu_unit *decs;
+ const struct dpu_unit *eds;
+ const struct dpu_unit *fds;
+ const struct dpu_unit *fes;
+ const struct dpu_unit *fgs;
+ const struct dpu_unit *fls;
+ const struct dpu_unit *fws;
+ const struct dpu_unit *hss;
+ const struct dpu_unit *lbs;
+ const struct dpu_unit *sts;
+ const struct dpu_unit *tcons;
+ const struct dpu_unit *vss;
+ const struct cm_reg_ofs *cm_reg_ofs;
+ const unsigned int *intsteer_map;
+ unsigned int intsteer_map_size;
+ const unsigned long *unused_irq;
+ const unsigned int *sw2hw_irq_map; /* NULL means linear */
+ const unsigned int *sw2hw_block_id_map; /* NULL means linear */
+
+ unsigned int syncmode_min_prate; /* need pixel combiner, KHz */
+ unsigned int singlemode_max_width;
+ unsigned int master_stream_id;
+
+ /*
+ * index: 0 1 2 3 4 5 6
+ * source: fl0(sub0) fl1(sub0) fw2(sub0) fd0 fd1 fd2 fd3
+ */
+ u32 plane_src_na_mask;
+ bool has_capture;
+ bool has_prefetch;
+ bool has_disp_sel_clk;
+ bool has_dual_ldb;
+ bool has_pc;
+ bool has_syncmode_fixup;
+ bool pixel_link_quirks;
+ bool pixel_link_nhvsync; /* HSYNC and VSYNC high active */
+ unsigned int version;
+};
+
+struct dpu_soc {
+ struct device *dev;
+ const struct dpu_devtype *devtype;
+ spinlock_t lock;
+
+ void __iomem *cm_reg;
+
+ int id;
+ int usecount;
+
+ struct regmap *intsteer_regmap;
+ int intsteer_usecount;
+ spinlock_t intsteer_lock;
+ int irq_cm; /* irq common */
+ int irq_stream0a;
+ int irq_stream1a;
+ int irq_reserved0;
+ int irq_reserved1;
+ int irq_blit;
+ int irq_dpr0;
+ int irq_dpr1;
+ struct irq_domain *domain;
+
+ struct dpu_constframe *cf_priv[4];
+ struct dpu_disengcfg *dec_priv[2];
+ struct dpu_extdst *ed_priv[4];
+ struct dpu_fetchunit *fd_priv[4];
+ struct dpu_fetchunit *fe_priv[4];
+ struct dpu_framegen *fg_priv[2];
+ struct dpu_fetchunit *fl_priv[2];
+ struct dpu_fetchunit *fw_priv[1];
+ struct dpu_hscaler *hs_priv[3];
+ struct dpu_layerblend *lb_priv[7];
+ struct dpu_store *st_priv[1];
+ struct dpu_tcon *tcon_priv[2];
+ struct dpu_vscaler *vs_priv[3];
+};
+
+int dpu_format_horz_chroma_subsampling(u32 format);
+int dpu_format_vert_chroma_subsampling(u32 format);
+int dpu_format_num_planes(u32 format);
+int dpu_format_plane_width(int width, u32 format, int plane);
+int dpu_format_plane_height(int height, u32 format, int plane);
+
+#define _DECLARE_DPU_UNIT_INIT_FUNC(block) \
+void _dpu_##block##_init(struct dpu_soc *dpu, unsigned int id) \
+
+_DECLARE_DPU_UNIT_INIT_FUNC(cf);
+_DECLARE_DPU_UNIT_INIT_FUNC(dec);
+_DECLARE_DPU_UNIT_INIT_FUNC(ed);
+_DECLARE_DPU_UNIT_INIT_FUNC(fd);
+_DECLARE_DPU_UNIT_INIT_FUNC(fe);
+_DECLARE_DPU_UNIT_INIT_FUNC(fg);
+_DECLARE_DPU_UNIT_INIT_FUNC(fl);
+_DECLARE_DPU_UNIT_INIT_FUNC(fw);
+_DECLARE_DPU_UNIT_INIT_FUNC(hs);
+_DECLARE_DPU_UNIT_INIT_FUNC(lb);
+_DECLARE_DPU_UNIT_INIT_FUNC(tcon);
+_DECLARE_DPU_UNIT_INIT_FUNC(vs);
+
+#define DECLARE_DPU_UNIT_INIT_FUNC(block) \
+int dpu_##block##_init(struct dpu_soc *dpu, unsigned int id, \
+ unsigned long pec_base, unsigned long base)
+
+DECLARE_DPU_UNIT_INIT_FUNC(cf);
+DECLARE_DPU_UNIT_INIT_FUNC(dec);
+DECLARE_DPU_UNIT_INIT_FUNC(ed);
+DECLARE_DPU_UNIT_INIT_FUNC(fd);
+DECLARE_DPU_UNIT_INIT_FUNC(fe);
+DECLARE_DPU_UNIT_INIT_FUNC(fg);
+DECLARE_DPU_UNIT_INIT_FUNC(fl);
+DECLARE_DPU_UNIT_INIT_FUNC(fw);
+DECLARE_DPU_UNIT_INIT_FUNC(hs);
+DECLARE_DPU_UNIT_INIT_FUNC(lb);
+DECLARE_DPU_UNIT_INIT_FUNC(st);
+DECLARE_DPU_UNIT_INIT_FUNC(tcon);
+DECLARE_DPU_UNIT_INIT_FUNC(vs);
+
+static inline u32 dpu_pec_fu_read(struct dpu_fetchunit *fu, unsigned int offset)
+{
+ return readl(fu->pec_base + offset);
+}
+
+static inline void dpu_pec_fu_write(struct dpu_fetchunit *fu, u32 value,
+ unsigned int offset)
+{
+ writel(value, fu->pec_base + offset);
+}
+
+static inline u32 dpu_fu_read(struct dpu_fetchunit *fu, unsigned int offset)
+{
+ return readl(fu->base + offset);
+}
+
+static inline void dpu_fu_write(struct dpu_fetchunit *fu, u32 value,
+ unsigned int offset)
+{
+ writel(value, fu->base + offset);
+}
+
+static inline u32 rgb_color(u8 r, u8 g, u8 b, u8 a)
+{
+ return (r << 24) | (g << 16) | (b << 8) | a;
+}
+
+static inline u32 yuv_color(u8 y, u8 u, u8 v)
+{
+ return (y << 24) | (u << 16) | (v << 8);
+}
+
+void tcon_get_pc(struct dpu_tcon *tcon, void *data);
+
+static const unsigned int cf_ids[] = {0, 1, 4, 5};
+static const unsigned int dec_ids[] = {0, 1};
+static const unsigned int ed_ids[] = {0, 1, 4, 5};
+static const unsigned int fd_ids[] = {0, 1, 2, 3};
+static const unsigned int fe_ids[] = {0, 1, 2, 9};
+static const unsigned int fg_ids[] = {0, 1};
+static const unsigned int fl_ids[] = {0, 1};
+static const unsigned int fw_ids[] = {2};
+static const unsigned int hs_ids[] = {4, 5, 9};
+static const unsigned int lb_ids[] = {0, 1, 2, 3, 4, 5, 6};
+static const unsigned int st_ids[] = {9};
+static const unsigned int tcon_ids[] = {0, 1};
+static const unsigned int vs_ids[] = {4, 5, 9};
+
+static const unsigned int fd_dprc_ids[] = {3, 4};
+static const unsigned int fl_dprc_ids[] = {2};
+static const unsigned int fw_dprc_ids[] = {5};
+
+struct dpu_pixel_format {
+ u32 pixel_format;
+ u32 bits;
+ u32 shift;
+};
+
+static const struct dpu_pixel_format dpu_pixel_format_matrix[] = {
+ {
+ DRM_FORMAT_ARGB8888,
+ R_BITS(8) | G_BITS(8) | B_BITS(8) | A_BITS(8),
+ R_SHIFT(16) | G_SHIFT(8) | B_SHIFT(0) | A_SHIFT(24),
+ }, {
+ DRM_FORMAT_XRGB8888,
+ R_BITS(8) | G_BITS(8) | B_BITS(8) | A_BITS(0),
+ R_SHIFT(16) | G_SHIFT(8) | B_SHIFT(0) | A_SHIFT(0),
+ }, {
+ DRM_FORMAT_ABGR8888,
+ R_BITS(8) | G_BITS(8) | B_BITS(8) | A_BITS(8),
+ R_SHIFT(0) | G_SHIFT(8) | B_SHIFT(16) | A_SHIFT(24),
+ }, {
+ DRM_FORMAT_XBGR8888,
+ R_BITS(8) | G_BITS(8) | B_BITS(8) | A_BITS(0),
+ R_SHIFT(0) | G_SHIFT(8) | B_SHIFT(16) | A_SHIFT(0),
+ }, {
+ DRM_FORMAT_RGBA8888,
+ R_BITS(8) | G_BITS(8) | B_BITS(8) | A_BITS(8),
+ R_SHIFT(24) | G_SHIFT(16) | B_SHIFT(8) | A_SHIFT(0),
+ }, {
+ DRM_FORMAT_RGBX8888,
+ R_BITS(8) | G_BITS(8) | B_BITS(8) | A_BITS(0),
+ R_SHIFT(24) | G_SHIFT(16) | B_SHIFT(8) | A_SHIFT(0),
+ }, {
+ DRM_FORMAT_BGRA8888,
+ R_BITS(8) | G_BITS(8) | B_BITS(8) | A_BITS(8),
+ R_SHIFT(8) | G_SHIFT(16) | B_SHIFT(24) | A_SHIFT(0),
+ }, {
+ DRM_FORMAT_BGRX8888,
+ R_BITS(8) | G_BITS(8) | B_BITS(8) | A_BITS(0),
+ R_SHIFT(8) | G_SHIFT(16) | B_SHIFT(24) | A_SHIFT(0),
+ }, {
+ DRM_FORMAT_RGB888,
+ R_BITS(8) | G_BITS(8) | B_BITS(8) | A_BITS(0),
+ R_SHIFT(16) | G_SHIFT(8) | B_SHIFT(0) | A_SHIFT(0),
+ }, {
+ DRM_FORMAT_BGR888,
+ R_BITS(8) | G_BITS(8) | B_BITS(8) | A_BITS(0),
+ R_SHIFT(0) | G_SHIFT(8) | B_SHIFT(16) | A_SHIFT(0),
+ }, {
+ DRM_FORMAT_RGB565,
+ R_BITS(5) | G_BITS(6) | B_BITS(5) | A_BITS(0),
+ R_SHIFT(11) | G_SHIFT(5) | B_SHIFT(0) | A_SHIFT(0),
+ }, {
+ DRM_FORMAT_YUYV,
+ Y_BITS(8) | U_BITS(8) | V_BITS(8) | A_BITS(0),
+ Y_SHIFT(0) | U_SHIFT(8) | V_SHIFT(8) | A_SHIFT(0),
+ }, {
+ DRM_FORMAT_UYVY,
+ Y_BITS(8) | U_BITS(8) | V_BITS(8) | A_BITS(0),
+ Y_SHIFT(8) | U_SHIFT(0) | V_SHIFT(0) | A_SHIFT(0),
+ }, {
+ DRM_FORMAT_NV12,
+ Y_BITS(8) | U_BITS(8) | V_BITS(8) | A_BITS(0),
+ Y_SHIFT(0) | U_SHIFT(0) | V_SHIFT(8) | A_SHIFT(0),
+ }, {
+ DRM_FORMAT_NV21,
+ Y_BITS(8) | U_BITS(8) | V_BITS(8) | A_BITS(0),
+ Y_SHIFT(0) | U_SHIFT(8) | V_SHIFT(0) | A_SHIFT(0),
+ }, {
+ DRM_FORMAT_NV16,
+ Y_BITS(8) | U_BITS(8) | V_BITS(8) | A_BITS(0),
+ Y_SHIFT(0) | U_SHIFT(0) | V_SHIFT(8) | A_SHIFT(0),
+ }, {
+ DRM_FORMAT_NV61,
+ Y_BITS(8) | U_BITS(8) | V_BITS(8) | A_BITS(0),
+ Y_SHIFT(0) | U_SHIFT(8) | V_SHIFT(0) | A_SHIFT(0),
+ }, {
+ DRM_FORMAT_NV24,
+ Y_BITS(8) | U_BITS(8) | V_BITS(8) | A_BITS(0),
+ Y_SHIFT(0) | U_SHIFT(0) | V_SHIFT(8) | A_SHIFT(0),
+ }, {
+ DRM_FORMAT_NV42,
+ Y_BITS(8) | U_BITS(8) | V_BITS(8) | A_BITS(0),
+ Y_SHIFT(0) | U_SHIFT(8) | V_SHIFT(0) | A_SHIFT(0),
+ },
+};
+
+#endif /* __DPU_PRV_H__ */
diff --git a/drivers/gpu/imx/dpu/dpu-store.c b/drivers/gpu/imx/dpu/dpu-store.c
new file mode 100644
index 000000000000..8e7e305a3ddc
--- /dev/null
+++ b/drivers/gpu/imx/dpu/dpu-store.c
@@ -0,0 +1,140 @@
+/*
+ * Copyright 2018 NXP
+ *
+ * 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/io.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/platform_device.h>
+#include <linux/types.h>
+#include "dpu-prv.h"
+
+#define PIXENGCFG_STATIC 0x8
+
+struct dpu_store {
+ void __iomem *pec_base;
+ void __iomem *base;
+ struct mutex mutex;
+ int id;
+ bool inuse;
+ struct dpu_soc *dpu;
+};
+
+static inline u32 dpu_pec_st_read(struct dpu_store *st, unsigned int offset)
+{
+ return readl(st->pec_base + offset);
+}
+
+static inline void dpu_pec_st_write(struct dpu_store *st, u32 value,
+ unsigned int offset)
+{
+ writel(value, st->pec_base + offset);
+}
+
+void store_pixengcfg_syncmode_fixup(struct dpu_store *st, bool enable)
+{
+ struct dpu_soc *dpu;
+ u32 val;
+
+ if (!st)
+ return;
+
+ dpu = st->dpu;
+
+ if (!dpu->devtype->has_syncmode_fixup)
+ return;
+
+ mutex_lock(&st->mutex);
+ val = dpu_pec_st_read(st, PIXENGCFG_STATIC);
+ if (enable)
+ val |= BIT(16);
+ else
+ val &= ~BIT(16);
+ dpu_pec_st_write(st, val, PIXENGCFG_STATIC);
+ mutex_unlock(&st->mutex);
+}
+EXPORT_SYMBOL_GPL(store_pixengcfg_syncmode_fixup);
+
+struct dpu_store *dpu_st_get(struct dpu_soc *dpu, int id)
+{
+ struct dpu_store *st;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(st_ids); i++)
+ if (st_ids[i] == id)
+ break;
+
+ if (i == ARRAY_SIZE(st_ids))
+ return ERR_PTR(-EINVAL);
+
+ st = dpu->st_priv[i];
+
+ mutex_lock(&st->mutex);
+
+ if (st->inuse) {
+ mutex_unlock(&st->mutex);
+ return ERR_PTR(-EBUSY);
+ }
+
+ st->inuse = true;
+
+ mutex_unlock(&st->mutex);
+
+ return st;
+}
+EXPORT_SYMBOL_GPL(dpu_st_get);
+
+void dpu_st_put(struct dpu_store *st)
+{
+ mutex_lock(&st->mutex);
+
+ st->inuse = false;
+
+ mutex_unlock(&st->mutex);
+}
+EXPORT_SYMBOL_GPL(dpu_st_put);
+
+int dpu_st_init(struct dpu_soc *dpu, unsigned int id,
+ unsigned long pec_base, unsigned long base)
+{
+ struct dpu_store *st;
+ int i;
+
+ st = devm_kzalloc(dpu->dev, sizeof(*st), GFP_KERNEL);
+ if (!st)
+ return -ENOMEM;
+
+ for (i = 0; i < ARRAY_SIZE(st_ids); i++)
+ if (st_ids[i] == id)
+ break;
+
+ if (i == ARRAY_SIZE(st_ids))
+ return -EINVAL;
+
+ dpu->st_priv[i] = st;
+
+ st->pec_base = devm_ioremap(dpu->dev, pec_base, SZ_32);
+ if (!st->pec_base)
+ return -ENOMEM;
+
+ st->base = devm_ioremap(dpu->dev, base, SZ_256);
+ if (!st->base)
+ return -ENOMEM;
+
+ st->dpu = dpu;
+ st->id = id;
+
+ mutex_init(&st->mutex);
+
+ return 0;
+}
diff --git a/drivers/gpu/imx/dpu/dpu-tcon.c b/drivers/gpu/imx/dpu/dpu-tcon.c
new file mode 100644
index 000000000000..42dfc7acac55
--- /dev/null
+++ b/drivers/gpu/imx/dpu/dpu-tcon.c
@@ -0,0 +1,339 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017-2019 NXP
+ *
+ * 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/io.h>
+#include <linux/media-bus-format.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/platform_device.h>
+#include <linux/types.h>
+#include <video/dpu.h>
+#include <video/imx8-pc.h>
+#include "dpu-prv.h"
+
+#define SSQCNTS 0
+#define SSQCYCLE 0x8
+#define SWRESET 0xC
+#define TCON_CTRL 0x10
+#define BYPASS BIT(3)
+#define RSDSINVCTRL 0x14
+#define MAPBIT3_0 0x18
+#define MAPBIT7_4 0x1C
+#define MAPBIT11_8 0x20
+#define MAPBIT15_12 0x24
+#define MAPBIT19_16 0x28
+#define MAPBIT23_20 0x2C
+#define MAPBIT27_24 0x30
+#define MAPBIT31_28 0x34
+#define MAPBIT34_32 0x38
+#define MAPBIT3_0_DUAL 0x3C
+#define MAPBIT7_4_DUAL 0x40
+#define MAPBIT11_8_DUAL 0x44
+#define MAPBIT15_12_DUAL 0x48
+#define MAPBIT19_16_DUAL 0x4C
+#define MAPBIT23_20_DUAL 0x50
+#define MAPBIT27_24_DUAL 0x54
+#define MAPBIT31_28_DUAL 0x58
+#define MAPBIT34_32_DUAL 0x5C
+#define SPGPOSON(n) (0x60 + (n) * 16)
+#define X(n) (((n) & 0x7FFF) << 16)
+#define Y(n) ((n) & 0x7FFF)
+#define SPGMASKON(n) (0x64 + (n) * 16)
+#define SPGPOSOFF(n) (0x68 + (n) * 16)
+#define SPGMASKOFF(n) (0x6C + (n) * 16)
+#define SMXSIGS(n) (0x120 + (n) * 8)
+#define SMXFCTTABLE(n) (0x124 + (n) * 8)
+#define RESET_OVER_UNFERFLOW 0x180
+#define DUAL_DEBUG 0x184
+
+struct dpu_tcon {
+ void __iomem *base;
+ struct mutex mutex;
+ int id;
+ bool inuse;
+ struct dpu_soc *dpu;
+ struct pc *pc;
+};
+
+static inline u32 dpu_tcon_read(struct dpu_tcon *tcon, unsigned int offset)
+{
+ return readl(tcon->base + offset);
+}
+
+static inline void dpu_tcon_write(struct dpu_tcon *tcon, u32 value,
+ unsigned int offset)
+{
+ writel(value, tcon->base + offset);
+}
+
+int tcon_set_fmt(struct dpu_tcon *tcon, u32 bus_format)
+{
+ mutex_lock(&tcon->mutex);
+ switch (bus_format) {
+ case MEDIA_BUS_FMT_RGB888_1X24:
+ dpu_tcon_write(tcon, 0x19181716, MAPBIT3_0);
+ dpu_tcon_write(tcon, 0x1d1c1b1a, MAPBIT7_4);
+ dpu_tcon_write(tcon, 0x0f0e0d0c, MAPBIT11_8);
+ dpu_tcon_write(tcon, 0x13121110, MAPBIT15_12);
+ dpu_tcon_write(tcon, 0x05040302, MAPBIT19_16);
+ dpu_tcon_write(tcon, 0x09080706, MAPBIT23_20);
+ break;
+ case MEDIA_BUS_FMT_RGB101010_1X30:
+ case MEDIA_BUS_FMT_RGB888_1X30_PADLO:
+ case MEDIA_BUS_FMT_RGB666_1X30_PADLO:
+ dpu_tcon_write(tcon, 0x17161514, MAPBIT3_0);
+ dpu_tcon_write(tcon, 0x1b1a1918, MAPBIT7_4);
+ dpu_tcon_write(tcon, 0x0b0a1d1c, MAPBIT11_8);
+ dpu_tcon_write(tcon, 0x0f0e0d0c, MAPBIT15_12);
+ dpu_tcon_write(tcon, 0x13121110, MAPBIT19_16);
+ dpu_tcon_write(tcon, 0x03020100, MAPBIT23_20);
+ dpu_tcon_write(tcon, 0x07060504, MAPBIT27_24);
+ dpu_tcon_write(tcon, 0x00000908, MAPBIT31_28);
+ break;
+ default:
+ mutex_unlock(&tcon->mutex);
+ return -EINVAL;
+ }
+ mutex_unlock(&tcon->mutex);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(tcon_set_fmt);
+
+/* This function is used to workaround TKT320590 which is related to DPR/PRG. */
+void tcon_set_operation_mode(struct dpu_tcon *tcon)
+{
+ u32 val;
+
+ mutex_lock(&tcon->mutex);
+ val = dpu_tcon_read(tcon, TCON_CTRL);
+ val &= ~BYPASS;
+ dpu_tcon_write(tcon, val, TCON_CTRL);
+ mutex_unlock(&tcon->mutex);
+}
+EXPORT_SYMBOL_GPL(tcon_set_operation_mode);
+
+void tcon_cfg_videomode(struct dpu_tcon *tcon,
+ struct drm_display_mode *m, bool side_by_side)
+{
+ struct dpu_soc *dpu = tcon->dpu;
+ const struct dpu_devtype *devtype = dpu->devtype;
+ u32 val;
+ int hdisplay, hsync_start, hsync_end;
+ int vdisplay, vsync_start, vsync_end;
+ int y;
+
+ hdisplay = m->hdisplay;
+ vdisplay = m->vdisplay;
+ hsync_start = m->hsync_start;
+ vsync_start = m->vsync_start;
+ hsync_end = m->hsync_end;
+ vsync_end = m->vsync_end;
+
+ if (side_by_side) {
+ hdisplay /= 2;
+ hsync_start /= 2;
+ hsync_end /= 2;
+ }
+
+ mutex_lock(&tcon->mutex);
+ /*
+ * TKT320590:
+ * Turn TCON into operation mode later after the first dumb frame is
+ * generated by DPU. This makes DPR/PRG be able to evade the frame.
+ */
+ val = dpu_tcon_read(tcon, TCON_CTRL);
+ val |= BYPASS;
+ dpu_tcon_write(tcon, val, TCON_CTRL);
+
+ /* dsp_control[0]: hsync */
+ dpu_tcon_write(tcon, X(hsync_start), SPGPOSON(0));
+ dpu_tcon_write(tcon, 0xffff, SPGMASKON(0));
+
+ dpu_tcon_write(tcon, X(hsync_end), SPGPOSOFF(0));
+ dpu_tcon_write(tcon, 0xffff, SPGMASKOFF(0));
+
+ dpu_tcon_write(tcon, 0x2, SMXSIGS(0));
+ dpu_tcon_write(tcon, 0x1, SMXFCTTABLE(0));
+
+ /* dsp_control[1]: vsync */
+ dpu_tcon_write(tcon, X(hsync_start) | Y(vsync_start - 1), SPGPOSON(1));
+ dpu_tcon_write(tcon, 0x0, SPGMASKON(1));
+
+ dpu_tcon_write(tcon, X(hsync_start) | Y(vsync_end - 1), SPGPOSOFF(1));
+ dpu_tcon_write(tcon, 0x0, SPGMASKOFF(1));
+
+ dpu_tcon_write(tcon, 0x3, SMXSIGS(1));
+ dpu_tcon_write(tcon, 0x1, SMXFCTTABLE(1));
+
+ /* dsp_control[2]: data enable */
+ /* horizontal */
+ dpu_tcon_write(tcon, 0x0, SPGPOSON(2));
+ dpu_tcon_write(tcon, 0xffff, SPGMASKON(2));
+
+ dpu_tcon_write(tcon, X(hdisplay), SPGPOSOFF(2));
+ dpu_tcon_write(tcon, 0xffff, SPGMASKOFF(2));
+
+ /* vertical */
+ dpu_tcon_write(tcon, 0x0, SPGPOSON(3));
+ dpu_tcon_write(tcon, 0x7fff0000, SPGMASKON(3));
+
+ dpu_tcon_write(tcon, Y(vdisplay), SPGPOSOFF(3));
+ dpu_tcon_write(tcon, 0x7fff0000, SPGMASKOFF(3));
+
+ dpu_tcon_write(tcon, 0x2c, SMXSIGS(2));
+ dpu_tcon_write(tcon, 0x8, SMXFCTTABLE(2));
+
+ /* dsp_control[3]: kachuck */
+ y = vdisplay + 1;
+ /*
+ * If sync mode fixup is present, the kachuck signal from slave tcon
+ * should be one line later than the one from master tcon.
+ */
+ if (side_by_side && tcon_is_slave(tcon) && devtype->has_syncmode_fixup)
+ y++;
+
+ dpu_tcon_write(tcon, X(0x0) | Y(y), SPGPOSON(4));
+ dpu_tcon_write(tcon, 0x0, SPGMASKON(4));
+
+ dpu_tcon_write(tcon, X(0x20) | Y(y), SPGPOSOFF(4));
+ dpu_tcon_write(tcon, 0x0, SPGMASKOFF(4));
+
+ dpu_tcon_write(tcon, 0x6, SMXSIGS(3));
+ dpu_tcon_write(tcon, 0x2, SMXFCTTABLE(3));
+ mutex_unlock(&tcon->mutex);
+}
+EXPORT_SYMBOL_GPL(tcon_cfg_videomode);
+
+bool tcon_is_master(struct dpu_tcon *tcon)
+{
+ const struct dpu_devtype *devtype = tcon->dpu->devtype;
+
+ return tcon->id == devtype->master_stream_id;
+}
+EXPORT_SYMBOL_GPL(tcon_is_master);
+
+bool tcon_is_slave(struct dpu_tcon *tcon)
+{
+ return !tcon_is_master(tcon);
+}
+EXPORT_SYMBOL_GPL(tcon_is_slave);
+
+void tcon_configure_pc(struct dpu_tcon *tcon, unsigned int di,
+ unsigned int frame_width, u32 mode, u32 format)
+{
+ if (WARN_ON(!tcon || !tcon->pc))
+ return;
+
+ pc_configure(tcon->pc, di, frame_width, mode, format);
+}
+EXPORT_SYMBOL_GPL(tcon_configure_pc);
+
+void tcon_enable_pc(struct dpu_tcon *tcon)
+{
+ if (WARN_ON(!tcon || !tcon->pc))
+ return;
+
+ pc_enable(tcon->pc);
+}
+EXPORT_SYMBOL_GPL(tcon_enable_pc);
+
+void tcon_disable_pc(struct dpu_tcon *tcon)
+{
+ if (WARN_ON(!tcon || !tcon->pc))
+ return;
+
+ pc_disable(tcon->pc);
+}
+EXPORT_SYMBOL_GPL(tcon_disable_pc);
+
+struct dpu_tcon *dpu_tcon_get(struct dpu_soc *dpu, int id)
+{
+ struct dpu_tcon *tcon;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(tcon_ids); i++)
+ if (tcon_ids[i] == id)
+ break;
+
+ if (i == ARRAY_SIZE(tcon_ids))
+ return ERR_PTR(-EINVAL);
+
+ tcon = dpu->tcon_priv[i];
+
+ mutex_lock(&tcon->mutex);
+
+ if (tcon->inuse) {
+ mutex_unlock(&tcon->mutex);
+ return ERR_PTR(-EBUSY);
+ }
+
+ tcon->inuse = true;
+
+ mutex_unlock(&tcon->mutex);
+
+ return tcon;
+}
+EXPORT_SYMBOL_GPL(dpu_tcon_get);
+
+void dpu_tcon_put(struct dpu_tcon *tcon)
+{
+ mutex_lock(&tcon->mutex);
+
+ tcon->inuse = false;
+
+ mutex_unlock(&tcon->mutex);
+}
+EXPORT_SYMBOL_GPL(dpu_tcon_put);
+
+struct dpu_tcon *dpu_aux_tcon_peek(struct dpu_tcon *tcon)
+{
+ return tcon->dpu->tcon_priv[tcon->id ^ 1];
+}
+EXPORT_SYMBOL_GPL(dpu_aux_tcon_peek);
+
+void _dpu_tcon_init(struct dpu_soc *dpu, unsigned int id)
+{
+}
+
+int dpu_tcon_init(struct dpu_soc *dpu, unsigned int id,
+ unsigned long unused, unsigned long base)
+{
+ struct dpu_tcon *tcon;
+
+ tcon = devm_kzalloc(dpu->dev, sizeof(*tcon), GFP_KERNEL);
+ if (!tcon)
+ return -ENOMEM;
+
+ dpu->tcon_priv[id] = tcon;
+
+ tcon->base = devm_ioremap(dpu->dev, base, SZ_512);
+ if (!tcon->base)
+ return -ENOMEM;
+
+ tcon->dpu = dpu;
+ tcon->id = id;
+ mutex_init(&tcon->mutex);
+
+ return 0;
+}
+
+void tcon_get_pc(struct dpu_tcon *tcon, void *data)
+{
+ if (WARN_ON(!tcon))
+ return;
+
+ tcon->pc = data;
+}
diff --git a/drivers/gpu/imx/dpu/dpu-vscaler.c b/drivers/gpu/imx/dpu/dpu-vscaler.c
new file mode 100644
index 000000000000..f8309b637572
--- /dev/null
+++ b/drivers/gpu/imx/dpu/dpu-vscaler.c
@@ -0,0 +1,447 @@
+/*
+ * Copyright 2017-2018 NXP
+ *
+ * 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/io.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/platform_device.h>
+#include <linux/types.h>
+#include <video/dpu.h>
+#include "dpu-prv.h"
+
+#define PIXENGCFG_DYNAMIC 0x8
+#define PIXENGCFG_DYNAMIC_SRC_SEL_MASK 0x3F
+
+#define SETUP1 0xC
+#define SCALE_FACTOR_MASK 0xFFFFF
+#define SCALE_FACTOR(n) ((n) & 0xFFFFF)
+#define SETUP2 0x10
+#define SETUP3 0x14
+#define SETUP4 0x18
+#define SETUP5 0x1C
+#define PHASE_OFFSET_MASK 0x1FFFFF
+#define PHASE_OFFSET(n) ((n) & 0x1FFFFF)
+#define CONTROL 0x20
+#define OUTPUT_SIZE_MASK 0x3FFF0000
+#define OUTPUT_SIZE(n) ((((n) - 1) << 16) & OUTPUT_SIZE_MASK)
+#define FIELD_MODE 0x3000
+#define FILTER_MODE 0x100
+#define SCALE_MODE 0x10
+#define MODE 0x1
+
+static const vs_src_sel_t src_sels[3][6] = {
+ {
+ VS_SRC_SEL__DISABLE,
+ VS_SRC_SEL__EXTSRC4,
+ VS_SRC_SEL__FETCHDECODE0,
+ VS_SRC_SEL__FETCHDECODE2,
+ VS_SRC_SEL__MATRIX4,
+ VS_SRC_SEL__HSCALER4,
+ }, {
+ VS_SRC_SEL__DISABLE,
+ VS_SRC_SEL__EXTSRC5,
+ VS_SRC_SEL__FETCHDECODE1,
+ VS_SRC_SEL__FETCHDECODE3,
+ VS_SRC_SEL__MATRIX5,
+ VS_SRC_SEL__HSCALER5,
+ }, {
+ VS_SRC_SEL__DISABLE,
+ VS_SRC_SEL__MATRIX9,
+ VS_SRC_SEL__HSCALER9,
+ },
+};
+
+struct dpu_vscaler {
+ void __iomem *pec_base;
+ void __iomem *base;
+ struct mutex mutex;
+ int id;
+ bool inuse;
+ struct dpu_soc *dpu;
+ /* see DPU_PLANE_SRC_xxx */
+ unsigned int stream_id;
+};
+
+static inline u32 dpu_pec_vs_read(struct dpu_vscaler *vs,
+ unsigned int offset)
+{
+ return readl(vs->pec_base + offset);
+}
+
+static inline void dpu_pec_vs_write(struct dpu_vscaler *vs, u32 value,
+ unsigned int offset)
+{
+ writel(value, vs->pec_base + offset);
+}
+
+static inline u32 dpu_vs_read(struct dpu_vscaler *vs, unsigned int offset)
+{
+ return readl(vs->base + offset);
+}
+
+static inline void dpu_vs_write(struct dpu_vscaler *vs, u32 value,
+ unsigned int offset)
+{
+ writel(value, vs->base + offset);
+}
+
+int vscaler_pixengcfg_dynamic_src_sel(struct dpu_vscaler *vs, vs_src_sel_t src)
+{
+ struct dpu_soc *dpu = vs->dpu;
+ const unsigned int *block_id_map = dpu->devtype->sw2hw_block_id_map;
+ const unsigned int vs_id_array[] = {4, 5, 9};
+ int i, j;
+ u32 val, mapped_src;
+
+ for (i = 0; i < ARRAY_SIZE(vs_id_array); i++)
+ if (vs_id_array[i] == vs->id)
+ break;
+
+ if (WARN_ON(i == ARRAY_SIZE(vs_id_array)))
+ return -EINVAL;
+
+ mutex_lock(&vs->mutex);
+ for (j = 0; j < ARRAY_SIZE(src_sels[0]); j++) {
+ if (src_sels[i][j] == src) {
+ mapped_src = block_id_map ? block_id_map[src] : src;
+ if (WARN_ON(mapped_src == NA))
+ return -EINVAL;
+
+ val = dpu_pec_vs_read(vs, PIXENGCFG_DYNAMIC);
+ val &= ~PIXENGCFG_DYNAMIC_SRC_SEL_MASK;
+ val |= mapped_src;
+ dpu_pec_vs_write(vs, val, PIXENGCFG_DYNAMIC);
+ mutex_unlock(&vs->mutex);
+ return 0;
+ }
+ }
+ mutex_unlock(&vs->mutex);
+
+ dev_err(dpu->dev, "Invalid source for VScaler%d\n", vs->id);
+
+ return -EINVAL;
+}
+EXPORT_SYMBOL_GPL(vscaler_pixengcfg_dynamic_src_sel);
+
+void vscaler_pixengcfg_clken(struct dpu_vscaler *vs, pixengcfg_clken_t clken)
+{
+ u32 val;
+
+ mutex_lock(&vs->mutex);
+ val = dpu_pec_vs_read(vs, PIXENGCFG_DYNAMIC);
+ val &= ~CLKEN_MASK;
+ val |= clken << CLKEN_MASK_SHIFT;
+ dpu_pec_vs_write(vs, val, PIXENGCFG_DYNAMIC);
+ mutex_unlock(&vs->mutex);
+}
+EXPORT_SYMBOL_GPL(vscaler_pixengcfg_clken);
+
+void vscaler_shden(struct dpu_vscaler *vs, bool enable)
+{
+ u32 val;
+
+ mutex_lock(&vs->mutex);
+ val = dpu_vs_read(vs, STATICCONTROL);
+ if (enable)
+ val |= SHDEN;
+ else
+ val &= ~SHDEN;
+ dpu_vs_write(vs, val, STATICCONTROL);
+ mutex_unlock(&vs->mutex);
+}
+EXPORT_SYMBOL_GPL(vscaler_shden);
+
+void vscaler_setup1(struct dpu_vscaler *vs, u32 src, u32 dst, bool deinterlace)
+{
+ struct dpu_soc *dpu = vs->dpu;
+ u32 scale_factor;
+ u64 tmp64;
+
+ if (deinterlace)
+ dst *= 2;
+
+ if (src == dst) {
+ scale_factor = 0x80000;
+ } else {
+ if (src > dst) {
+ tmp64 = (u64)((u64)dst * 0x80000);
+ do_div(tmp64, src);
+
+ } else {
+ tmp64 = (u64)((u64)src * 0x80000);
+ do_div(tmp64, dst);
+ }
+ scale_factor = (u32)tmp64;
+ }
+
+ WARN_ON(scale_factor > 0x80000);
+
+ mutex_lock(&vs->mutex);
+ dpu_vs_write(vs, SCALE_FACTOR(scale_factor), SETUP1);
+ mutex_unlock(&vs->mutex);
+
+ dev_dbg(dpu->dev, "Vscaler%d scale factor 0x%08x\n",
+ vs->id, scale_factor);
+}
+EXPORT_SYMBOL_GPL(vscaler_setup1);
+
+void vscaler_setup2(struct dpu_vscaler *vs, bool deinterlace)
+{
+ /* 0x20000: +0.25 phase offset for deinterlace */
+ u32 phase_offset = deinterlace ? 0x20000 : 0;
+
+ mutex_lock(&vs->mutex);
+ dpu_vs_write(vs, PHASE_OFFSET(phase_offset), SETUP2);
+ mutex_unlock(&vs->mutex);
+}
+EXPORT_SYMBOL_GPL(vscaler_setup2);
+
+void vscaler_setup3(struct dpu_vscaler *vs, bool deinterlace)
+{
+ /* 0x1e0000: -0.25 phase offset for deinterlace */
+ u32 phase_offset = deinterlace ? 0x1e0000 : 0;
+
+ mutex_lock(&vs->mutex);
+ dpu_vs_write(vs, PHASE_OFFSET(phase_offset), SETUP3);
+ mutex_unlock(&vs->mutex);
+}
+EXPORT_SYMBOL_GPL(vscaler_setup3);
+
+void vscaler_setup4(struct dpu_vscaler *vs, u32 phase_offset)
+{
+ mutex_lock(&vs->mutex);
+ dpu_vs_write(vs, PHASE_OFFSET(phase_offset), SETUP4);
+ mutex_unlock(&vs->mutex);
+}
+EXPORT_SYMBOL_GPL(vscaler_setup4);
+
+void vscaler_setup5(struct dpu_vscaler *vs, u32 phase_offset)
+{
+ mutex_lock(&vs->mutex);
+ dpu_vs_write(vs, PHASE_OFFSET(phase_offset), SETUP5);
+ mutex_unlock(&vs->mutex);
+}
+EXPORT_SYMBOL_GPL(vscaler_setup5);
+
+void vscaler_output_size(struct dpu_vscaler *vs, u32 line_num)
+{
+ u32 val;
+
+ mutex_lock(&vs->mutex);
+ val = dpu_vs_read(vs, CONTROL);
+ val &= ~OUTPUT_SIZE_MASK;
+ val |= OUTPUT_SIZE(line_num);
+ dpu_vs_write(vs, val, CONTROL);
+ mutex_unlock(&vs->mutex);
+}
+EXPORT_SYMBOL_GPL(vscaler_output_size);
+
+void vscaler_field_mode(struct dpu_vscaler *vs, scaler_field_mode_t m)
+{
+ u32 val;
+
+ mutex_lock(&vs->mutex);
+ val = dpu_vs_read(vs, CONTROL);
+ val &= ~FIELD_MODE;
+ val |= m;
+ dpu_vs_write(vs, val, CONTROL);
+ mutex_unlock(&vs->mutex);
+}
+EXPORT_SYMBOL_GPL(vscaler_field_mode);
+
+void vscaler_filter_mode(struct dpu_vscaler *vs, scaler_filter_mode_t m)
+{
+ u32 val;
+
+ mutex_lock(&vs->mutex);
+ val = dpu_vs_read(vs, CONTROL);
+ val &= ~FILTER_MODE;
+ val |= m;
+ dpu_vs_write(vs, val, CONTROL);
+ mutex_unlock(&vs->mutex);
+}
+EXPORT_SYMBOL_GPL(vscaler_filter_mode);
+
+void vscaler_scale_mode(struct dpu_vscaler *vs, scaler_scale_mode_t m)
+{
+ u32 val;
+
+ mutex_lock(&vs->mutex);
+ val = dpu_vs_read(vs, CONTROL);
+ val &= ~SCALE_MODE;
+ val |= m;
+ dpu_vs_write(vs, val, CONTROL);
+ mutex_unlock(&vs->mutex);
+}
+EXPORT_SYMBOL_GPL(vscaler_scale_mode);
+
+void vscaler_mode(struct dpu_vscaler *vs, scaler_mode_t m)
+{
+ u32 val;
+
+ mutex_lock(&vs->mutex);
+ val = dpu_vs_read(vs, CONTROL);
+ val &= ~MODE;
+ val |= m;
+ dpu_vs_write(vs, val, CONTROL);
+ mutex_unlock(&vs->mutex);
+}
+EXPORT_SYMBOL_GPL(vscaler_mode);
+
+bool vscaler_is_enabled(struct dpu_vscaler *vs)
+{
+ u32 val;
+
+ mutex_lock(&vs->mutex);
+ val = dpu_vs_read(vs, CONTROL);
+ mutex_unlock(&vs->mutex);
+
+ return (val & MODE) == SCALER_ACTIVE;
+}
+EXPORT_SYMBOL_GPL(vscaler_is_enabled);
+
+dpu_block_id_t vscaler_get_block_id(struct dpu_vscaler *vs)
+{
+ switch (vs->id) {
+ case 4:
+ return ID_VSCALER4;
+ case 5:
+ return ID_VSCALER5;
+ case 9:
+ return ID_VSCALER9;
+ default:
+ WARN_ON(1);
+ }
+
+ return ID_NONE;
+}
+EXPORT_SYMBOL_GPL(vscaler_get_block_id);
+
+unsigned int vscaler_get_stream_id(struct dpu_vscaler *vs)
+{
+ return vs->stream_id;
+}
+EXPORT_SYMBOL_GPL(vscaler_get_stream_id);
+
+void vscaler_set_stream_id(struct dpu_vscaler *vs, unsigned int id)
+{
+ switch (id) {
+ case DPU_PLANE_SRC_TO_DISP_STREAM0:
+ case DPU_PLANE_SRC_TO_DISP_STREAM1:
+ case DPU_PLANE_SRC_DISABLED:
+ vs->stream_id = id;
+ break;
+ default:
+ WARN_ON(1);
+ }
+}
+EXPORT_SYMBOL_GPL(vscaler_set_stream_id);
+
+struct dpu_vscaler *dpu_vs_get(struct dpu_soc *dpu, int id)
+{
+ struct dpu_vscaler *vs;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(vs_ids); i++)
+ if (vs_ids[i] == id)
+ break;
+
+ if (i == ARRAY_SIZE(vs_ids))
+ return ERR_PTR(-EINVAL);
+
+ vs = dpu->vs_priv[i];
+
+ mutex_lock(&vs->mutex);
+
+ if (vs->inuse) {
+ mutex_unlock(&vs->mutex);
+ return ERR_PTR(-EBUSY);
+ }
+
+ vs->inuse = true;
+
+ mutex_unlock(&vs->mutex);
+
+ return vs;
+}
+EXPORT_SYMBOL_GPL(dpu_vs_get);
+
+void dpu_vs_put(struct dpu_vscaler *vs)
+{
+ mutex_lock(&vs->mutex);
+
+ vs->inuse = false;
+
+ mutex_unlock(&vs->mutex);
+}
+EXPORT_SYMBOL_GPL(dpu_vs_put);
+
+void _dpu_vs_init(struct dpu_soc *dpu, unsigned int id)
+{
+ struct dpu_vscaler *vs;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(vs_ids); i++)
+ if (vs_ids[i] == id)
+ break;
+
+ if (WARN_ON(i == ARRAY_SIZE(vs_ids)))
+ return;
+
+ vs = dpu->vs_priv[i];
+
+ vscaler_shden(vs, true);
+ vscaler_setup2(vs, false);
+ vscaler_setup3(vs, false);
+ vscaler_setup4(vs, 0);
+ vscaler_setup5(vs, 0);
+ vscaler_pixengcfg_dynamic_src_sel(vs, VS_SRC_SEL__DISABLE);
+}
+
+int dpu_vs_init(struct dpu_soc *dpu, unsigned int id,
+ unsigned long pec_base, unsigned long base)
+{
+ struct dpu_vscaler *vs;
+ int i;
+
+ vs = devm_kzalloc(dpu->dev, sizeof(*vs), GFP_KERNEL);
+ if (!vs)
+ return -ENOMEM;
+
+ for (i = 0; i < ARRAY_SIZE(vs_ids); i++)
+ if (vs_ids[i] == id)
+ break;
+
+ if (i == ARRAY_SIZE(vs_ids))
+ return -EINVAL;
+
+ dpu->vs_priv[i] = vs;
+
+ vs->pec_base = devm_ioremap(dpu->dev, pec_base, SZ_8);
+ if (!vs->pec_base)
+ return -ENOMEM;
+
+ vs->base = devm_ioremap(dpu->dev, base, SZ_1K);
+ if (!vs->base)
+ return -ENOMEM;
+
+ vs->dpu = dpu;
+ vs->id = id;
+
+ mutex_init(&vs->mutex);
+
+ _dpu_vs_init(dpu, id);
+
+ return 0;
+}
diff --git a/drivers/gpu/imx/imx8_dprc.c b/drivers/gpu/imx/imx8_dprc.c
new file mode 100644
index 000000000000..166c214c0154
--- /dev/null
+++ b/drivers/gpu/imx/imx8_dprc.c
@@ -0,0 +1,908 @@
+/*
+ * Copyright 2017-2018 NXP
+ *
+ * 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 <drm/drm_fourcc.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <soc/imx8/sc/sci.h>
+#include <video/imx8-prefetch.h>
+
+#define SET 0x4
+#define CLR 0x8
+#define TOG 0xc
+
+#define SYSTEM_CTRL0 0x00
+#define BCMD2AXI_MASTR_ID_CTRL BIT(16)
+#define SW_SHADOW_LOAD_SEL BIT(4)
+#define SHADOW_LOAD_EN BIT(3)
+#define REPEAT_EN BIT(2)
+#define SOFT_RESET BIT(1)
+#define RUN_EN BIT(0) /* self-clearing */
+
+#define IRQ_MASK 0x20
+#define IRQ_MASK_STATUS 0x30
+#define IRQ_NONMASK_STATUS 0x40
+#define DPR2RTR_FIFO_LOAD_BUF_RDY_UV_ERROR BIT(7)
+#define DPR2RTR_FIFO_LOAD_BUF_RDY_YRGB_ERROR BIT(6)
+#define DPR2RTR_UV_FIFO_OVFL BIT(5)
+#define DPR2RTR_YRGB_FIFO_OVFL BIT(4)
+#define IRQ_AXI_READ_ERROR BIT(3)
+#define IRQ_DPR_SHADOW_LOADED_MASK BIT(2)
+#define IRQ_DPR_RUN BIT(1)
+#define IRQ_DPR_CRTL_DONE BIT(0)
+#define IRQ_ERROR_MASK 0xf8
+#define IRQ_CTRL_MASK 0x7
+
+#define MODE_CTRL0 0x50
+#define PIX_COMP_SEL_MASK 0x3fc00
+#define A_COMP_SEL(byte) (((byte) & 0x3) << 16)
+#define R_COMP_SEL(byte) (((byte) & 0x3) << 14)
+#define G_COMP_SEL(byte) (((byte) & 0x3) << 12)
+#define B_COMP_SEL(byte) (((byte) & 0x3) << 10)
+#define PIX_UV_SWAP BIT(9)
+#define VU BIT(9)
+#define UV 0
+#define PIXEL_LUMA_UV_SWAP BIT(8)
+#define UYVY BIT(8)
+#define YUYV 0
+#define PIX_SIZE 0xc0
+enum {
+ PIX_SIZE_8BIT = (0 << 6),
+ PIX_SIZE_16BIT = (1 << 6),
+ PIX_SIZE_32BIT = (2 << 6),
+ PIX_SIZE_RESERVED = (3 << 6),
+};
+#define COMP_2PLANE_EN BIT(5)
+#define YUV_EN BIT(4)
+#define TILE_TYPE 0xc
+enum {
+ LINEAR_TILE = (0 << 2),
+ GPU_STANDARD_TILE = (1 << 2),
+ GPU_SUPER_TILE = (2 << 2),
+ VPU_TILE = (3 << 2),
+};
+#define RTR_4LINE_BUF_EN BIT(1)
+#define LINE4 BIT(1)
+#define LINE8 0
+#define RTR_3BUF_EN BIT(0)
+#define BUF3 BIT(0)
+#define BUF2 0
+
+#define FRAME_CTRL0 0x70
+#define PITCH(n) (((n) & 0xffff) << 16)
+#define ROT_FLIP_ORDER_EN BIT(4)
+#define ROT_FIRST BIT(4)
+#define FLIP_FIRST 0
+#define ROT_ENC 0xc
+#define DEGREE(n) ((((n) / 90) & 0x3) << 2)
+#define VFLIP_EN BIT(1)
+#define HFLIP_EN BIT(0)
+
+#define FRAME_1P_CTRL0 0x90
+#define FRAME_2P_CTRL0 0xe0
+#define MAX_BYTES_PREQ 0x7
+enum {
+ BYTE_64 = 0x0,
+ BYTE_128 = 0x1,
+ BYTE_256 = 0x2,
+ BYTE_512 = 0x3,
+ BYTE_1K = 0x4,
+ BYTE_2K = 0x5,
+ BYTE_4K = 0x6,
+};
+
+#define FRAME_1P_PIX_X_CTRL 0xa0
+#define FRAME_2P_PIX_X_CTRL 0xf0
+#define NUM_X_PIX_WIDE(n) ((n) & 0xffff)
+#define FRAME_PIX_X_ULC_CTRL 0xf0
+#define CROP_ULC_X(n) ((n) & 0xffff)
+
+#define FRAME_1P_PIX_Y_CTRL 0xb0
+#define FRAME_2P_PIX_Y_CTRL 0x100
+#define NUM_Y_PIX_HIGH(n) ((n) & 0xffff)
+#define FRAME_PIX_Y_ULC_CTRL 0x100
+#define CROP_ULC_Y(n) ((n) & 0xffff)
+
+#define FRAME_1P_BASE_ADDR_CTRL0 0xc0
+#define FRAME_2P_BASE_ADDR_CTRL0 0x110
+
+#define STATUS_CTRL0 0x130
+#define STATUS_SRC_SEL 0x70000
+enum {
+ DPR_CTRL = 0x0,
+ PREFETCH_1PLANE = 0x1,
+ RESPONSE_1PLANE = 0x2,
+ PREFETCH_2PLANE = 0x3,
+ RESPONSE_2PLANE = 0x4,
+};
+#define STATUS_MUX_SEL 0x7
+
+#define STATUS_CTRL1 0x140
+
+#define RTRAM_CTRL0 0x200
+#define ABORT_SEL BIT(7)
+#define ABORT BIT(7)
+#define STALL 0
+#define THRES_LOW_MASK 0x70
+#define THRES_LOW(n) (((n) & 0x7) << 4)
+#define THRES_HIGH_MASK 0xe
+#define THRES_HIGH(n) (((n) & 0x7) << 1)
+#define NUM_ROWS_ACTIVE BIT(0)
+#define ROWS_0_6 BIT(0)
+#define ROWS_0_4 0
+
+struct dprc {
+ struct device *dev;
+ void __iomem *base;
+ struct list_head list;
+ struct clk *clk_apb;
+ struct clk *clk_b;
+ struct clk *clk_rtram;
+ spinlock_t spin_lock;
+ u32 sc_resource;
+ bool is_blit_chan;
+
+ /* The second one, if non-NULL, is auxiliary for UV buffer. */
+ struct prg *prgs[2];
+ bool has_aux_prg;
+ bool use_aux_prg;
+};
+
+struct dprc_format_info {
+ u32 format;
+ u8 depth;
+ u8 num_planes;
+ u8 cpp[3];
+ u8 hsub;
+ u8 vsub;
+};
+
+static const struct dprc_format_info formats[] = {
+ {
+ .format = DRM_FORMAT_RGB565,
+ .depth = 16, .num_planes = 1, .cpp = { 2, 0, 0 },
+ .hsub = 1, .vsub = 1,
+ }, {
+ .format = DRM_FORMAT_ARGB8888,
+ .depth = 32, .num_planes = 1, .cpp = { 4, 0, 0 },
+ .hsub = 1, .vsub = 1,
+ }, {
+ .format = DRM_FORMAT_XRGB8888,
+ .depth = 24, .num_planes = 1, .cpp = { 4, 0, 0 },
+ .hsub = 1, .vsub = 1,
+ }, {
+ .format = DRM_FORMAT_ABGR8888,
+ .depth = 32, .num_planes = 1, .cpp = { 4, 0, 0 },
+ .hsub = 1, .vsub = 1,
+ }, {
+ .format = DRM_FORMAT_XBGR8888,
+ .depth = 24, .num_planes = 1, .cpp = { 4, 0, 0 },
+ .hsub = 1, .vsub = 1,
+ }, {
+ .format = DRM_FORMAT_RGBA8888,
+ .depth = 32, .num_planes = 1, .cpp = { 4, 0, 0 },
+ .hsub = 1, .vsub = 1,
+ }, {
+ .format = DRM_FORMAT_RGBX8888,
+ .depth = 24, .num_planes = 1, .cpp = { 4, 0, 0 },
+ .hsub = 1, .vsub = 1,
+ }, {
+ .format = DRM_FORMAT_BGRA8888,
+ .depth = 32, .num_planes = 1, .cpp = { 4, 0, 0 },
+ .hsub = 1, .vsub = 1,
+ }, {
+ .format = DRM_FORMAT_BGRX8888,
+ .depth = 24, .num_planes = 1, .cpp = { 4, 0, 0 },
+ .hsub = 1, .vsub = 1,
+ }, {
+ .format = DRM_FORMAT_NV12,
+ .depth = 0, .num_planes = 2, .cpp = { 1, 2, 0 },
+ .hsub = 2, .vsub = 2,
+ }, {
+ .format = DRM_FORMAT_NV21,
+ .depth = 0, .num_planes = 2, .cpp = { 1, 2, 0 },
+ .hsub = 2, .vsub = 2,
+ }, {
+ .format = DRM_FORMAT_YUYV,
+ .depth = 0, .num_planes = 1, .cpp = { 2, 0, 0 },
+ .hsub = 2, .vsub = 1,
+ }, {
+ .format = DRM_FORMAT_UYVY,
+ .depth = 0, .num_planes = 1, .cpp = { 2, 0, 0 },
+ .hsub = 2, .vsub = 1,
+ }
+};
+
+static const struct dprc_format_info *dprc_format_info(u32 format)
+{
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE(formats); ++i) {
+ if (formats[i].format == format)
+ return &formats[i];
+ }
+
+ return NULL;
+}
+
+static DEFINE_MUTEX(dprc_list_mutex);
+static LIST_HEAD(dprc_list);
+
+static inline u32 dprc_read(struct dprc *dprc, unsigned int offset)
+{
+ return readl(dprc->base + offset);
+}
+
+static inline void dprc_write(struct dprc *dprc, u32 value, unsigned int offset)
+{
+ writel(value, dprc->base + offset);
+}
+
+static void dprc_reset(struct dprc *dprc)
+{
+ dprc_write(dprc, SOFT_RESET, SYSTEM_CTRL0 + SET);
+
+ if (dprc->is_blit_chan)
+ usleep_range(10, 20);
+ else
+ usleep_range(1000, 2000);
+
+ dprc_write(dprc, SOFT_RESET, SYSTEM_CTRL0 + CLR);
+}
+
+void dprc_enable(struct dprc *dprc)
+{
+ if (WARN_ON(!dprc))
+ return;
+
+ prg_enable(dprc->prgs[0]);
+ if (dprc->use_aux_prg)
+ prg_enable(dprc->prgs[1]);
+}
+EXPORT_SYMBOL_GPL(dprc_enable);
+
+void dprc_disable(struct dprc *dprc)
+{
+ if (WARN_ON(!dprc))
+ return;
+
+ dprc_write(dprc, SHADOW_LOAD_EN | SW_SHADOW_LOAD_SEL, SYSTEM_CTRL0);
+
+ prg_disable(dprc->prgs[0]);
+ if (dprc->has_aux_prg)
+ prg_disable(dprc->prgs[1]);
+
+ prg_reg_update(dprc->prgs[0]);
+ if (dprc->has_aux_prg)
+ prg_reg_update(dprc->prgs[1]);
+}
+EXPORT_SYMBOL_GPL(dprc_disable);
+
+static void dprc_dpu_gpr_configure(struct dprc *dprc, unsigned int stream_id)
+{
+ sc_err_t sciErr;
+ sc_ipc_t ipcHndl = 0;
+ u32 mu_id;
+
+ if (WARN_ON(!dprc))
+ return;
+
+ sciErr = sc_ipc_getMuID(&mu_id);
+ if (sciErr != SC_ERR_NONE) {
+ dev_err(dprc->dev, "cannot obtain MU ID %d\n", sciErr);
+ return;
+ }
+
+ sciErr = sc_ipc_open(&ipcHndl, mu_id);
+ if (sciErr != SC_ERR_NONE) {
+ dev_err(dprc->dev, "sc_ipc_open failed %d\n", sciErr);
+ return;
+ }
+
+ sciErr = sc_misc_set_control(ipcHndl, dprc->sc_resource,
+ SC_C_KACHUNK_SEL, stream_id);
+ if (sciErr != SC_ERR_NONE)
+ dev_err(dprc->dev, "sc_misc_set_control failed %d\n", sciErr);
+
+ sc_ipc_close(mu_id);
+}
+
+static void dprc_prg_sel_configure(struct dprc *dprc, u32 resource, bool enable)
+{
+ sc_err_t sciErr;
+ sc_ipc_t ipcHndl = 0;
+ u32 mu_id;
+
+ if (WARN_ON(!dprc))
+ return;
+
+ sciErr = sc_ipc_getMuID(&mu_id);
+ if (sciErr != SC_ERR_NONE) {
+ dev_err(dprc->dev, "cannot obtain MU ID %d\n", sciErr);
+ return;
+ }
+
+ sciErr = sc_ipc_open(&ipcHndl, mu_id);
+ if (sciErr != SC_ERR_NONE) {
+ dev_err(dprc->dev, "sc_ipc_open failed %d\n", sciErr);
+ return;
+ }
+
+ sciErr = sc_misc_set_control(ipcHndl, resource, SC_C_SEL0, enable);
+ if (sciErr != SC_ERR_NONE)
+ dev_err(dprc->dev, "sc_misc_set_control failed %d\n", sciErr);
+
+ sc_ipc_close(mu_id);
+}
+
+void dprc_configure(struct dprc *dprc, unsigned int stream_id,
+ unsigned int width, unsigned int height,
+ unsigned int x_offset, unsigned int y_offset,
+ unsigned int stride, u32 format, u64 modifier,
+ unsigned long baddr, unsigned long uv_baddr,
+ bool start, bool aux_start, bool interlace_frame)
+{
+ const struct dprc_format_info *info = dprc_format_info(format);
+ unsigned int dprc_width = width + x_offset;
+ unsigned int dprc_height;
+ unsigned int p1_w, p1_h, p2_w, p2_h;
+ unsigned int prg_stride = width * info->cpp[0];
+ unsigned int bpp = 8 * info->cpp[0];
+ unsigned int preq;
+ unsigned int mt_w = 0, mt_h = 0; /* w/h in a micro-tile */
+ u32 val;
+
+ if (WARN_ON(!dprc))
+ return;
+
+ dprc->use_aux_prg = false;
+
+ if (start) {
+ dprc_reset(dprc);
+
+ if (!dprc->is_blit_chan)
+ dprc_dpu_gpr_configure(dprc, stream_id);
+ }
+
+ if (interlace_frame) {
+ height /= 2;
+ y_offset /= 2;
+ }
+
+ dprc_height = height + y_offset;
+
+ /* disable all control irqs and enable all error irqs */
+ dprc_write(dprc, IRQ_CTRL_MASK, IRQ_MASK);
+
+ if (info->num_planes > 1) {
+ p1_w = round_up(dprc_width, modifier ? 8 : 64);
+ p1_h = round_up(dprc_height, 8);
+
+ p2_w = p1_w;
+ if (modifier)
+ p2_h = dprc_height / info->vsub;
+ else
+ p2_h = round_up((dprc_height / info->vsub), 8);
+
+ preq = modifier ? BYTE_64 : BYTE_1K;
+
+ dprc_write(dprc, preq, FRAME_2P_CTRL0);
+ if (dprc->sc_resource == SC_R_DC_0_BLIT1 ||
+ dprc->sc_resource == SC_R_DC_1_BLIT1) {
+ dprc_prg_sel_configure(dprc,
+ dprc->sc_resource == SC_R_DC_0_BLIT1 ?
+ SC_R_DC_0_BLIT0 : SC_R_DC_1_BLIT0,
+ true);
+ prg_set_auxiliary(dprc->prgs[1]);
+ dprc->has_aux_prg = true;
+ }
+ dprc_write(dprc, uv_baddr, FRAME_2P_BASE_ADDR_CTRL0);
+ } else {
+ switch (dprc->sc_resource) {
+ case SC_R_DC_0_BLIT0:
+ case SC_R_DC_1_BLIT0:
+ dprc_prg_sel_configure(dprc, dprc->sc_resource, false);
+ prg_set_primary(dprc->prgs[0]);
+ break;
+ case SC_R_DC_0_BLIT1:
+ case SC_R_DC_1_BLIT1:
+ dprc->has_aux_prg = false;
+ break;
+ default:
+ break;
+ }
+
+ switch (modifier) {
+ case DRM_FORMAT_MOD_VIVANTE_TILED:
+ p1_w = round_up(dprc_width, info->cpp[0] == 2 ? 8 : 4);
+ break;
+ case DRM_FORMAT_MOD_VIVANTE_SUPER_TILED:
+ if (dprc->is_blit_chan)
+ p1_w = round_up(dprc_width,
+ info->cpp[0] == 2 ? 8 : 4);
+ else
+ p1_w = round_up(dprc_width, 64);
+ break;
+ default:
+ p1_w = round_up(dprc_width,
+ info->cpp[0] == 2 ? 32 : 16);
+ break;
+ }
+ p1_h = round_up(dprc_height, 4);
+ }
+
+ dprc_write(dprc, PITCH(stride), FRAME_CTRL0);
+ switch (modifier) {
+ case DRM_FORMAT_MOD_AMPHION_TILED:
+ preq = BYTE_64;
+ mt_w = 8;
+ mt_h = 8;
+ break;
+ case DRM_FORMAT_MOD_VIVANTE_TILED:
+ case DRM_FORMAT_MOD_VIVANTE_SUPER_TILED:
+ if (bpp == 16) {
+ preq = BYTE_64;
+ mt_w = 8;
+ } else {
+ preq = (x_offset % 8) ? BYTE_64 : BYTE_128;
+ mt_w = 4;
+ }
+ mt_h = 4;
+ break;
+ default:
+ preq = BYTE_1K;
+ break;
+ }
+ dprc_write(dprc, preq, FRAME_1P_CTRL0);
+ dprc_write(dprc, NUM_X_PIX_WIDE(p1_w), FRAME_1P_PIX_X_CTRL);
+ dprc_write(dprc, NUM_Y_PIX_HIGH(p1_h), FRAME_1P_PIX_Y_CTRL);
+ dprc_write(dprc, baddr, FRAME_1P_BASE_ADDR_CTRL0);
+ if (modifier) {
+ dprc_write(dprc, CROP_ULC_X(round_down(x_offset, mt_w)),
+ FRAME_PIX_X_ULC_CTRL);
+ dprc_write(dprc, CROP_ULC_Y(round_down(y_offset, mt_h)),
+ FRAME_PIX_Y_ULC_CTRL);
+ } else {
+ dprc_write(dprc, CROP_ULC_X(0), FRAME_PIX_X_ULC_CTRL);
+ dprc_write(dprc, CROP_ULC_Y(0), FRAME_PIX_Y_ULC_CTRL);
+ }
+
+ val = dprc_read(dprc, RTRAM_CTRL0);
+ val &= ~THRES_LOW_MASK;
+ val |= THRES_LOW(3);
+ val &= ~THRES_HIGH_MASK;
+ val |= THRES_HIGH(7);
+ dprc_write(dprc, val, RTRAM_CTRL0);
+
+ val = dprc_read(dprc, MODE_CTRL0);
+ val &= ~PIX_UV_SWAP;
+ val &= ~PIXEL_LUMA_UV_SWAP;
+ val &= ~COMP_2PLANE_EN;
+ val &= ~YUV_EN;
+ val &= ~TILE_TYPE;
+ switch (modifier) {
+ case DRM_FORMAT_MOD_NONE:
+ break;
+ case DRM_FORMAT_MOD_AMPHION_TILED:
+ val |= VPU_TILE;
+ break;
+ case DRM_FORMAT_MOD_VIVANTE_TILED:
+ val |= GPU_STANDARD_TILE;
+ break;
+ case DRM_FORMAT_MOD_VIVANTE_SUPER_TILED:
+ val |= GPU_SUPER_TILE;
+ break;
+ default:
+ dev_err(dprc->dev, "unsupported modifier 0x%016llx\n",
+ modifier);
+ return;
+ }
+ val &= ~RTR_4LINE_BUF_EN;
+ val |= info->num_planes > 1 ? LINE8 : LINE4;
+ val &= ~RTR_3BUF_EN;
+ val |= BUF2;
+ val &= ~(PIX_COMP_SEL_MASK | PIX_SIZE);
+ switch (format) {
+ case DRM_FORMAT_ARGB8888:
+ case DRM_FORMAT_XRGB8888:
+ case DRM_FORMAT_ABGR8888:
+ case DRM_FORMAT_XBGR8888:
+ case DRM_FORMAT_RGBA8888:
+ case DRM_FORMAT_RGBX8888:
+ case DRM_FORMAT_BGRA8888:
+ case DRM_FORMAT_BGRX8888:
+ /*
+ * It turns out pixel components are mapped directly
+ * without position change via DPR processing with
+ * the following color component configurations.
+ * Leave the pixel format to be handled by the
+ * display controllers.
+ */
+ val |= A_COMP_SEL(3) | R_COMP_SEL(2) |
+ G_COMP_SEL(1) | B_COMP_SEL(0);
+ val |= PIX_SIZE_32BIT;
+ break;
+ case DRM_FORMAT_YUYV:
+ case DRM_FORMAT_UYVY:
+ val |= YUV_EN;
+ /* fall-through */
+ case DRM_FORMAT_RGB565:
+ val |= PIX_SIZE_16BIT;
+ break;
+ case DRM_FORMAT_NV12:
+ case DRM_FORMAT_NV21:
+ dprc->use_aux_prg = true;
+
+ val |= COMP_2PLANE_EN;
+ val |= YUV_EN;
+ val |= PIX_SIZE_8BIT;
+ break;
+ default:
+ dev_err(dprc->dev, "unsupported format 0x%08x\n", format);
+ return;
+ }
+ dprc_write(dprc, val, MODE_CTRL0);
+
+ if (dprc->is_blit_chan) {
+ val = SW_SHADOW_LOAD_SEL | RUN_EN | SHADOW_LOAD_EN;
+ dprc_write(dprc, val, SYSTEM_CTRL0);
+ } else if (start) {
+ /* software shadow load for the first frame */
+ val = SW_SHADOW_LOAD_SEL | SHADOW_LOAD_EN;
+ dprc_write(dprc, val, SYSTEM_CTRL0);
+
+ /* and then, run... */
+ val |= RUN_EN | REPEAT_EN;
+ dprc_write(dprc, val, SYSTEM_CTRL0);
+ }
+
+ prg_configure(dprc->prgs[0], width, height, x_offset, y_offset,
+ prg_stride, bpp, baddr, format, modifier, start);
+ if (dprc->use_aux_prg)
+ prg_configure(dprc->prgs[1], width, height, x_offset, y_offset,
+ prg_stride, 8, uv_baddr, format, modifier, aux_start);
+
+ dev_dbg(dprc->dev, "w-%u, h-%u, s-%u, fmt-0x%08x, mod-0x%016llx\n",
+ width, height, stride, format, modifier);
+}
+EXPORT_SYMBOL_GPL(dprc_configure);
+
+void dprc_reg_update(struct dprc *dprc)
+{
+ if (WARN_ON(!dprc))
+ return;
+
+ prg_reg_update(dprc->prgs[0]);
+ if (dprc->use_aux_prg)
+ prg_reg_update(dprc->prgs[1]);
+}
+EXPORT_SYMBOL_GPL(dprc_reg_update);
+
+void dprc_first_frame_handle(struct dprc *dprc)
+{
+ if (WARN_ON(!dprc))
+ return;
+
+ if (dprc->is_blit_chan)
+ return;
+
+ dprc_write(dprc, REPEAT_EN, SYSTEM_CTRL0);
+
+ prg_shadow_enable(dprc->prgs[0]);
+ if (dprc->use_aux_prg)
+ prg_shadow_enable(dprc->prgs[1]);
+}
+EXPORT_SYMBOL_GPL(dprc_first_frame_handle);
+
+void dprc_irq_handle(struct dprc *dprc)
+{
+ u32 mask, status;
+
+ if (WARN_ON(!dprc))
+ return;
+
+ spin_lock(&dprc->spin_lock);
+
+ mask = dprc_read(dprc, IRQ_MASK);
+ mask = ~mask;
+ status = dprc_read(dprc, IRQ_MASK_STATUS);
+ status &= mask;
+
+ /* disable irqs to be handled */
+ dprc_write(dprc, status, IRQ_MASK + SET);
+
+ /* clear status */
+ dprc_write(dprc, status, IRQ_MASK_STATUS);
+
+ if (status & DPR2RTR_FIFO_LOAD_BUF_RDY_UV_ERROR)
+ dev_err(dprc->dev,
+ "DPR to RTRAM FIFO load UV buffer ready error\n");
+
+ if (status & DPR2RTR_FIFO_LOAD_BUF_RDY_YRGB_ERROR)
+ dev_err(dprc->dev,
+ "DPR to RTRAM FIFO load YRGB buffer ready error\n");
+
+ if (status & DPR2RTR_UV_FIFO_OVFL)
+ dev_err(dprc->dev, "DPR to RTRAM FIFO UV FIFO overflow\n");
+
+ if (status & DPR2RTR_YRGB_FIFO_OVFL)
+ dev_err(dprc->dev, "DPR to RTRAM FIFO YRGB FIFO overflow\n");
+
+ if (status & IRQ_AXI_READ_ERROR)
+ dev_err(dprc->dev, "AXI read error\n");
+
+ if (status & IRQ_DPR_CRTL_DONE)
+ dprc_first_frame_handle(dprc);
+
+ spin_unlock(&dprc->spin_lock);
+}
+EXPORT_SYMBOL_GPL(dprc_irq_handle);
+
+void dprc_enable_ctrl_done_irq(struct dprc *dprc)
+{
+ unsigned long lock_flags;
+
+ if (WARN_ON(!dprc))
+ return;
+
+ spin_lock_irqsave(&dprc->spin_lock, lock_flags);
+ dprc_write(dprc, IRQ_DPR_CRTL_DONE, IRQ_MASK + CLR);
+ spin_unlock_irqrestore(&dprc->spin_lock, lock_flags);
+}
+EXPORT_SYMBOL_GPL(dprc_enable_ctrl_done_irq);
+
+bool dprc_format_supported(struct dprc *dprc, u32 format, u64 modifier)
+{
+ if (WARN_ON(!dprc))
+ return false;
+
+ switch (format) {
+ case DRM_FORMAT_ARGB8888:
+ case DRM_FORMAT_XRGB8888:
+ case DRM_FORMAT_ABGR8888:
+ case DRM_FORMAT_XBGR8888:
+ case DRM_FORMAT_RGBA8888:
+ case DRM_FORMAT_RGBX8888:
+ case DRM_FORMAT_BGRA8888:
+ case DRM_FORMAT_BGRX8888:
+ case DRM_FORMAT_RGB565:
+ return (modifier == DRM_FORMAT_MOD_NONE ||
+ modifier == DRM_FORMAT_MOD_VIVANTE_TILED ||
+ modifier == DRM_FORMAT_MOD_VIVANTE_SUPER_TILED);
+ case DRM_FORMAT_YUYV:
+ case DRM_FORMAT_UYVY:
+ switch (dprc->sc_resource) {
+ case SC_R_DC_0_FRAC0:
+ case SC_R_DC_1_FRAC0:
+ case SC_R_DC_0_WARP:
+ case SC_R_DC_1_WARP:
+ return false;
+ }
+ return modifier == DRM_FORMAT_MOD_NONE;
+ case DRM_FORMAT_NV12:
+ case DRM_FORMAT_NV21:
+ switch (dprc->sc_resource) {
+ case SC_R_DC_0_FRAC0:
+ case SC_R_DC_1_FRAC0:
+ case SC_R_DC_0_WARP:
+ case SC_R_DC_1_WARP:
+ return false;
+ case SC_R_DC_0_BLIT1:
+ case SC_R_DC_1_BLIT1:
+ return (modifier == DRM_FORMAT_MOD_NONE ||
+ modifier == DRM_FORMAT_MOD_AMPHION_TILED);
+ }
+ return (dprc->has_aux_prg &&
+ (modifier == DRM_FORMAT_MOD_NONE ||
+ modifier == DRM_FORMAT_MOD_AMPHION_TILED));
+ }
+
+ return false;
+}
+EXPORT_SYMBOL_GPL(dprc_format_supported);
+
+bool dprc_stride_supported(struct dprc *dprc,
+ unsigned int stride, unsigned int uv_stride,
+ unsigned int width, u32 format)
+{
+ const struct dprc_format_info *info = dprc_format_info(format);
+ unsigned int prg_stride = width * info->cpp[0];
+
+ if (WARN_ON(!dprc))
+ return false;
+
+ if (stride > 0xffff)
+ return false;
+
+ if (info->num_planes > 1 && stride != uv_stride)
+ return false;
+
+ return prg_stride_supported(dprc->prgs[0], prg_stride);
+}
+EXPORT_SYMBOL_GPL(dprc_stride_supported);
+
+bool dprc_stride_double_check(struct dprc *dprc,
+ unsigned int width, unsigned int x_offset,
+ u32 format, u64 modifier,
+ dma_addr_t baddr, dma_addr_t uv_baddr)
+{
+ const struct dprc_format_info *info = dprc_format_info(format);
+ unsigned int bpp = 8 * info->cpp[0];
+ unsigned int prg_stride = width * info->cpp[0];
+
+ if (WARN_ON(!dprc))
+ return false;
+
+ if (!prg_stride_double_check(dprc->prgs[0], width, x_offset,
+ bpp, modifier, prg_stride, baddr))
+ return false;
+
+ if (info->num_planes > 1 &&
+ !prg_stride_double_check(dprc->prgs[1], width, x_offset,
+ bpp, modifier, prg_stride, uv_baddr))
+ return false;
+
+ return true;
+}
+EXPORT_SYMBOL_GPL(dprc_stride_double_check);
+
+struct dprc *
+dprc_lookup_by_phandle(struct device *dev, const char *name, int index)
+{
+ struct device_node *dprc_node = of_parse_phandle(dev->of_node,
+ name, index);
+ struct dprc *dprc;
+
+ mutex_lock(&dprc_list_mutex);
+ list_for_each_entry(dprc, &dprc_list, list) {
+ if (dprc_node == dprc->dev->of_node) {
+ mutex_unlock(&dprc_list_mutex);
+ device_link_add(dev, dprc->dev, DL_FLAG_AUTOREMOVE);
+ return dprc;
+ }
+ }
+ mutex_unlock(&dprc_list_mutex);
+
+ return NULL;
+}
+EXPORT_SYMBOL_GPL(dprc_lookup_by_phandle);
+
+static const struct of_device_id dprc_dt_ids[] = {
+ { .compatible = "fsl,imx8qm-dpr-channel", },
+ { .compatible = "fsl,imx8qxp-dpr-channel", },
+ { /* sentinel */ },
+};
+
+static int dprc_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct resource *res;
+ struct dprc *dprc;
+ int ret, i;
+
+ dprc = devm_kzalloc(dev, sizeof(*dprc), GFP_KERNEL);
+ if (!dprc)
+ return -ENOMEM;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ dprc->base = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(dprc->base))
+ return PTR_ERR(dprc->base);
+
+ dprc->clk_apb = devm_clk_get(dev, "apb");
+ if (IS_ERR(dprc->clk_apb))
+ return PTR_ERR(dprc->clk_apb);
+ clk_prepare_enable(dprc->clk_apb);
+
+ dprc->clk_b = devm_clk_get(dev, "b");
+ if (IS_ERR(dprc->clk_b))
+ return PTR_ERR(dprc->clk_b);
+ clk_prepare_enable(dprc->clk_b);
+
+ dprc->clk_rtram = devm_clk_get(dev, "rtram");
+ if (IS_ERR(dprc->clk_rtram))
+ return PTR_ERR(dprc->clk_rtram);
+ clk_prepare_enable(dprc->clk_rtram);
+
+ ret = of_property_read_u32(pdev->dev.of_node,
+ "fsl,sc-resource", &dprc->sc_resource);
+ if (ret) {
+ dev_err(dev, "cannot get SC resource %d\n", ret);
+ return ret;
+ }
+
+ switch (dprc->sc_resource) {
+ case SC_R_DC_0_BLIT1:
+ case SC_R_DC_1_BLIT1:
+ dprc->has_aux_prg = true;
+ /* fall-through */
+ case SC_R_DC_0_BLIT0:
+ case SC_R_DC_1_BLIT0:
+ dprc->is_blit_chan = true;
+ /* fall-through */
+ case SC_R_DC_0_FRAC0:
+ case SC_R_DC_1_FRAC0:
+ break;
+ case SC_R_DC_0_VIDEO0:
+ case SC_R_DC_0_VIDEO1:
+ case SC_R_DC_1_VIDEO0:
+ case SC_R_DC_1_VIDEO1:
+ case SC_R_DC_0_WARP:
+ case SC_R_DC_1_WARP:
+ dprc->has_aux_prg = true;
+ break;
+ default:
+ dev_err(dev, "wrong SC resource %u\n", dprc->sc_resource);
+ return -EINVAL;
+ }
+
+ for (i = 0; i < 2; i++) {
+ if (i == 1 && !dprc->has_aux_prg)
+ break;
+
+ dprc->prgs[i] = prg_lookup_by_phandle(dev, "fsl,prgs", i);
+ if (!dprc->prgs[i])
+ return -EPROBE_DEFER;
+
+ if (i == 1)
+ prg_set_auxiliary(dprc->prgs[i]);
+
+ if (dprc->is_blit_chan)
+ prg_set_blit(dprc->prgs[i]);
+ }
+
+ dprc->dev = dev;
+ spin_lock_init(&dprc->spin_lock);
+ platform_set_drvdata(pdev, dprc);
+ mutex_lock(&dprc_list_mutex);
+ list_add(&dprc->list, &dprc_list);
+ mutex_unlock(&dprc_list_mutex);
+
+ dprc_reset(dprc);
+
+ return 0;
+}
+
+static int dprc_remove(struct platform_device *pdev)
+{
+ struct dprc *dprc = platform_get_drvdata(pdev);
+
+ mutex_lock(&dprc_list_mutex);
+ list_del(&dprc->list);
+ mutex_unlock(&dprc_list_mutex);
+
+ clk_disable_unprepare(dprc->clk_rtram);
+ clk_disable_unprepare(dprc->clk_b);
+ clk_disable_unprepare(dprc->clk_apb);
+
+ return 0;
+}
+
+struct platform_driver dprc_drv = {
+ .probe = dprc_probe,
+ .remove = dprc_remove,
+ .driver = {
+ .name = "imx8-dpr-channel",
+ .of_match_table = dprc_dt_ids,
+ },
+};
+module_platform_driver(dprc_drv);
+
+MODULE_DESCRIPTION("i.MX8 DPRC driver");
+MODULE_AUTHOR("NXP Semiconductor");
+MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/imx/imx8_pc.c b/drivers/gpu/imx/imx8_pc.c
new file mode 100644
index 000000000000..a41e6c7213ba
--- /dev/null
+++ b/drivers/gpu/imx/imx8_pc.c
@@ -0,0 +1,217 @@
+/*
+ * Copyright 2018 NXP
+ *
+ * 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/delay.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <video/imx8-pc.h>
+
+#define REG0 0x0
+#define PIX_COMBINE_ENABLE BIT(0)
+#define DISP_PIX_COMBINE_BYPASS(n) BIT(1 + 21 * (n))
+#define DISP_HSYNC_POLARITY(n) BIT(2 + 11 * (n))
+#define DISP_HSYNC_POLARITY_POS(n) DISP_HSYNC_POLARITY(n)
+#define DISP_VSYNC_POLARITY(n) BIT(3 + 11 * (n))
+#define DISP_VSYNC_POLARITY_POS(n) DISP_VSYNC_POLARITY(n)
+#define DISP_DVALID_POLARITY(n) BIT(4 + 11 * (n))
+#define DISP_DVALID_POLARITY_POS(n) DISP_DVALID_POLARITY(n)
+#define VSYNC_MASK_ENABLE BIT(5)
+#define SKIP_MODE BIT(6)
+#define SKIP_NUMBER(n) (((n) & 0x3F) << 7)
+#define DISP_PIX_DATA_FORMAT_MASK(n) (0x7 << (16 + (n) * 3))
+#define DISP_PIX_DATA_FORMAT_SHIFT(n) (16 + (n) * 3)
+enum {
+ RGB = 0,
+ YUV444,
+ YUV422,
+ SPLIT_RGB,
+};
+
+#define REG1 0x10
+#define BUF_ACTIVE_DEPTH(n) ((n) & 0x7FF)
+
+#define REG2 0x20
+#define PC_SW_RESET_N BIT(0)
+#define DISP_SW_RESET_N(n) BIT(1 + (n))
+#define PC_FULL_RESET_N (PC_SW_RESET_N | \
+ DISP_SW_RESET_N(0) | \
+ DISP_SW_RESET_N(1))
+
+struct pc {
+ struct device *dev;
+ void __iomem *base;
+ struct list_head list;
+};
+
+static DEFINE_MUTEX(pc_list_mutex);
+static LIST_HEAD(pc_list);
+
+static inline u32 pc_read(struct pc *pc, unsigned int offset)
+{
+ return readl(pc->base + offset);
+}
+
+static inline void pc_write(struct pc *pc, u32 value, unsigned int offset)
+{
+ writel(value, pc->base + offset);
+}
+
+static void pc_reset(struct pc *pc)
+{
+ pc_write(pc, 0, REG2);
+ usleep_range(1000, 2000);
+ pc_write(pc, PC_FULL_RESET_N, REG2);
+}
+
+void pc_enable(struct pc *pc)
+{
+ u32 val;
+
+ if (WARN_ON(!pc))
+ return;
+
+ val = pc_read(pc, REG0);
+ val |= PIX_COMBINE_ENABLE;
+ pc_write(pc, val, REG0);
+
+ dev_dbg(pc->dev, "enable\n");
+}
+EXPORT_SYMBOL_GPL(pc_enable);
+
+void pc_disable(struct pc *pc)
+{
+ if (WARN_ON(!pc))
+ return;
+
+ pc_reset(pc);
+
+ dev_dbg(pc->dev, "disable\n");
+}
+EXPORT_SYMBOL_GPL(pc_disable);
+
+void pc_configure(struct pc *pc, unsigned int di, unsigned int frame_width,
+ u32 mode, u32 format)
+{
+ u32 val;
+
+ if (WARN_ON(!pc))
+ return;
+
+ if (WARN_ON(di != 0 && di != 1))
+ return;
+
+ dev_dbg(pc->dev, "configure mode-0x%08x frame_width-%u\n",
+ mode, frame_width);
+
+ val = pc_read(pc, REG0);
+ if (mode == PC_BYPASS) {
+ val |= DISP_PIX_COMBINE_BYPASS(di);
+ } else if (mode == PC_COMBINE) {
+ val &= ~DISP_PIX_COMBINE_BYPASS(di);
+ frame_width /= 4;
+ }
+
+ pc_write(pc, val, REG0);
+ pc_write(pc, BUF_ACTIVE_DEPTH(frame_width), REG1);
+}
+EXPORT_SYMBOL_GPL(pc_configure);
+
+struct pc *pc_lookup_by_phandle(struct device *dev, const char *name)
+{
+ struct device_node *pc_node = of_parse_phandle(dev->of_node,
+ name, 0);
+ struct pc *pc;
+
+ mutex_lock(&pc_list_mutex);
+ list_for_each_entry(pc, &pc_list, list) {
+ if (pc_node == pc->dev->of_node) {
+ mutex_unlock(&pc_list_mutex);
+ device_link_add(dev, pc->dev, DL_FLAG_AUTOREMOVE);
+ return pc;
+ }
+ }
+ mutex_unlock(&pc_list_mutex);
+
+ return NULL;
+}
+EXPORT_SYMBOL_GPL(pc_lookup_by_phandle);
+
+static int pc_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct resource *res;
+ struct pc *pc;
+ u32 val;
+
+ pc = devm_kzalloc(dev, sizeof(*pc), GFP_KERNEL);
+ if (!pc)
+ return -ENOMEM;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ pc->base = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(pc->base))
+ return PTR_ERR(pc->base);
+
+ pc->dev = dev;
+ platform_set_drvdata(pdev, pc);
+ mutex_lock(&pc_list_mutex);
+ list_add(&pc->list, &pc_list);
+ mutex_unlock(&pc_list_mutex);
+
+ pc_reset(pc);
+
+ /*
+ * assume data enable is active high and HSYNC/VSYNC are active low
+ * also, bypass combine at startup
+ */
+ val = DISP_DVALID_POLARITY_POS(0) | DISP_DVALID_POLARITY_POS(1) |
+ DISP_PIX_COMBINE_BYPASS(0) | DISP_PIX_COMBINE_BYPASS(1) |
+ VSYNC_MASK_ENABLE;
+
+ pc_write(pc, val, REG0);
+
+ return 0;
+}
+
+static int pc_remove(struct platform_device *pdev)
+{
+ struct pc *pc = platform_get_drvdata(pdev);
+
+ mutex_lock(&pc_list_mutex);
+ list_del(&pc->list);
+ mutex_unlock(&pc_list_mutex);
+
+ return 0;
+}
+
+static const struct of_device_id pc_dt_ids[] = {
+ { .compatible = "fsl,imx8qm-pixel-combiner", },
+ { .compatible = "fsl,imx8qxp-pixel-combiner", },
+ { /* sentinel */ },
+};
+
+struct platform_driver pc_drv = {
+ .probe = pc_probe,
+ .remove = pc_remove,
+ .driver = {
+ .name = "imx8-pixel-combiner",
+ .of_match_table = pc_dt_ids,
+ },
+};
+module_platform_driver(pc_drv);
+
+MODULE_DESCRIPTION("i.MX8 Pixel Combiner driver");
+MODULE_AUTHOR("NXP Semiconductor");
+MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/imx/imx8_prg.c b/drivers/gpu/imx/imx8_prg.c
new file mode 100644
index 000000000000..b113483db90b
--- /dev/null
+++ b/drivers/gpu/imx/imx8_prg.c
@@ -0,0 +1,451 @@
+/*
+ * Copyright 2017-2018 NXP
+ *
+ * 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 <drm/drm_fourcc.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <video/imx8-prefetch.h>
+
+#define SET 0x4
+#define CLR 0x8
+#define TOG 0xc
+
+#define PRG_CTRL 0x00
+#define BYPASS BIT(0)
+#define SC_DATA_TYPE BIT(2)
+#define SC_DATA_TYPE_8BIT 0
+#define SC_DATA_TYPE_10BIT BIT(2)
+#define UV_EN BIT(3)
+#define HANDSHAKE_MODE BIT(4)
+#define HANDSHAKE_MODE_4LINES 0
+#define HANDSHAKE_MODE_8LINES BIT(4)
+#define SHADOW_LOAD_MODE BIT(5)
+#define DES_DATA_TYPE 0x30000
+enum {
+ DES_DATA_TYPE_32BPP = (0 << 16),
+ DES_DATA_TYPE_24BPP = (1 << 16),
+ DES_DATA_TYPE_16BPP = (2 << 16),
+ DES_DATA_TYPE_8BPP = (3 << 16),
+};
+#define SOFTRST BIT(30)
+#define SHADOW_EN BIT(31)
+
+#define PRG_STATUS 0x10
+#define BUFFER_VALID_B BIT(1)
+#define BUFFER_VALID_A BIT(0)
+
+#define PRG_REG_UPDATE 0x20
+#define REG_UPDATE BIT(0)
+
+#define PRG_STRIDE 0x30
+#define STRIDE(n) (((n) - 1) & 0xffff)
+
+#define PRG_HEIGHT 0x40
+#define HEIGHT(n) (((n) - 1) & 0xffff)
+
+#define PRG_BADDR 0x50
+
+#define PRG_OFFSET 0x60
+#define Y(n) (((n) & 0x7) << 16)
+#define X(n) ((n) & 0xffff)
+
+#define PRG_WIDTH 0x70
+#define WIDTH(n) (((n) - 1) & 0xffff)
+
+struct prg {
+ struct device *dev;
+ void __iomem *base;
+ struct list_head list;
+ struct clk *clk_apb;
+ struct clk *clk_rtram;
+ bool is_auxiliary;
+ bool is_blit;
+};
+
+static DEFINE_MUTEX(prg_list_mutex);
+static LIST_HEAD(prg_list);
+
+static inline u32 prg_read(struct prg *prg, unsigned int offset)
+{
+ return readl(prg->base + offset);
+}
+
+static inline void prg_write(struct prg *prg, u32 value, unsigned int offset)
+{
+ writel(value, prg->base + offset);
+}
+
+static void prg_reset(struct prg *prg)
+{
+ if (prg->is_blit)
+ usleep_range(10, 20);
+
+ prg_write(prg, SOFTRST, PRG_CTRL + SET);
+
+ if (prg->is_blit)
+ usleep_range(10, 20);
+ else
+ usleep_range(1000, 2000);
+
+ prg_write(prg, SOFTRST, PRG_CTRL + CLR);
+}
+
+void prg_enable(struct prg *prg)
+{
+ if (WARN_ON(!prg))
+ return;
+
+ prg_write(prg, BYPASS, PRG_CTRL + CLR);
+}
+EXPORT_SYMBOL_GPL(prg_enable);
+
+void prg_disable(struct prg *prg)
+{
+ if (WARN_ON(!prg))
+ return;
+
+ prg_write(prg, BYPASS, PRG_CTRL);
+}
+EXPORT_SYMBOL_GPL(prg_disable);
+
+void prg_configure(struct prg *prg, unsigned int width, unsigned int height,
+ unsigned int x_offset, unsigned int y_offset,
+ unsigned int stride, unsigned int bits_per_pixel,
+ unsigned long baddr, u32 format, u64 modifier,
+ bool start)
+{
+ unsigned int burst_size;
+ unsigned int mt_w = 0, mt_h = 0; /* w/h in a micro-tile */
+ unsigned long _baddr;
+ u32 val;
+
+ if (WARN_ON(!prg))
+ return;
+
+ if (start)
+ prg_reset(prg);
+
+ /* prg finer cropping into micro-tile block - top/left start point */
+ switch (modifier) {
+ case DRM_FORMAT_MOD_NONE:
+ break;
+ case DRM_FORMAT_MOD_AMPHION_TILED:
+ mt_w = 8;
+ mt_h = 8;
+ break;
+ case DRM_FORMAT_MOD_VIVANTE_TILED:
+ case DRM_FORMAT_MOD_VIVANTE_SUPER_TILED:
+ mt_w = (bits_per_pixel == 16) ? 8 : 4;
+ mt_h = 4;
+ break;
+ default:
+ dev_err(prg->dev, "unsupported modifier 0x%016llx\n", modifier);
+ return;
+ }
+
+ if (modifier) {
+ x_offset %= mt_w;
+ y_offset %= mt_h;
+
+ /* consider x offset to calculate stride */
+ _baddr = baddr + (x_offset * (bits_per_pixel / 8));
+ } else {
+ x_offset = 0;
+ y_offset = 0;
+ _baddr = baddr;
+ }
+
+ /*
+ * address TKT343664:
+ * fetch unit base address has to align to burst_size
+ */
+ burst_size = 1 << (ffs(_baddr) - 1);
+ burst_size = round_up(burst_size, 8);
+ burst_size = min(burst_size, 128U);
+
+ /*
+ * address TKT339017:
+ * fixup for burst size vs stride mismatch
+ */
+ if (modifier)
+ stride = round_up(stride + round_up(_baddr % 8, 8), burst_size);
+ else
+ stride = round_up(stride, burst_size);
+
+ /*
+ * address TKT342628(part 1):
+ * when prg stride is less or equals to burst size,
+ * the auxiliary prg height needs to be a half
+ */
+ if (prg->is_auxiliary && stride <= burst_size) {
+ height /= 2;
+ if (modifier)
+ y_offset /= 2;
+ }
+
+ prg_write(prg, STRIDE(stride), PRG_STRIDE);
+ prg_write(prg, WIDTH(width), PRG_WIDTH);
+ prg_write(prg, HEIGHT(height), PRG_HEIGHT);
+ prg_write(prg, X(x_offset) | Y(y_offset), PRG_OFFSET);
+ prg_write(prg, baddr, PRG_BADDR);
+
+ val = prg_read(prg, PRG_CTRL);
+ val &= ~SC_DATA_TYPE;
+ val |= SC_DATA_TYPE_8BIT;
+ val &= ~HANDSHAKE_MODE;
+ if (format == DRM_FORMAT_NV21 || format == DRM_FORMAT_NV12) {
+ val |= HANDSHAKE_MODE_8LINES;
+ /*
+ * address TKT342628(part 2):
+ * when prg stride is less or equals to burst size,
+ * we disable UV_EN bit for the auxiliary prg
+ */
+ if (prg->is_auxiliary && stride > burst_size)
+ val |= UV_EN;
+ else
+ val &= ~UV_EN;
+ } else {
+ val |= HANDSHAKE_MODE_4LINES;
+ val &= ~UV_EN;
+ }
+ val |= SHADOW_LOAD_MODE;
+ val &= ~DES_DATA_TYPE;
+ switch (bits_per_pixel) {
+ case 32:
+ val |= DES_DATA_TYPE_32BPP;
+ break;
+ case 24:
+ val |= DES_DATA_TYPE_24BPP;
+ break;
+ case 16:
+ val |= DES_DATA_TYPE_16BPP;
+ break;
+ case 8:
+ val |= DES_DATA_TYPE_8BPP;
+ break;
+ }
+ if (start)
+ /* no shadow for the first frame */
+ val &= ~SHADOW_EN;
+ else
+ val |= SHADOW_EN;
+ prg_write(prg, val, PRG_CTRL);
+
+ dev_dbg(prg->dev, "bits per pixel %u\n", bits_per_pixel);
+}
+EXPORT_SYMBOL_GPL(prg_configure);
+
+void prg_reg_update(struct prg *prg)
+{
+ if (WARN_ON(!prg))
+ return;
+
+ prg_write(prg, REG_UPDATE, PRG_REG_UPDATE);
+}
+EXPORT_SYMBOL_GPL(prg_reg_update);
+
+void prg_shadow_enable(struct prg *prg)
+{
+ if (WARN_ON(!prg))
+ return;
+
+ prg_write(prg, SHADOW_EN, PRG_CTRL + SET);
+}
+EXPORT_SYMBOL_GPL(prg_shadow_enable);
+
+bool prg_stride_supported(struct prg *prg, unsigned int stride)
+{
+ return stride < 0x10000;
+}
+EXPORT_SYMBOL_GPL(prg_stride_supported);
+
+bool prg_stride_double_check(struct prg *prg,
+ unsigned int width, unsigned int x_offset,
+ unsigned int bits_per_pixel, u64 modifier,
+ unsigned int stride, dma_addr_t baddr)
+{
+ unsigned int burst_size;
+ unsigned int mt_w = 0; /* w in a micro-tile */
+ dma_addr_t _baddr;
+
+ if (WARN_ON(!prg))
+ return false;
+
+ /* prg finer cropping into micro-tile block - top/left start point */
+ switch (modifier) {
+ case DRM_FORMAT_MOD_NONE:
+ break;
+ case DRM_FORMAT_MOD_AMPHION_TILED:
+ mt_w = 8;
+ break;
+ case DRM_FORMAT_MOD_VIVANTE_TILED:
+ case DRM_FORMAT_MOD_VIVANTE_SUPER_TILED:
+ mt_w = (bits_per_pixel == 16) ? 8 : 4;
+ break;
+ default:
+ dev_err(prg->dev, "unsupported modifier 0x%016llx\n", modifier);
+ return false;
+ }
+
+ if (modifier) {
+ x_offset %= mt_w;
+
+ /* consider x offset to calculate stride */
+ _baddr = baddr + (x_offset * (bits_per_pixel / 8));
+ } else {
+ _baddr = baddr;
+ }
+
+ /*
+ * address TKT343664:
+ * fetch unit base address has to align to burst size
+ */
+ burst_size = 1 << (ffs(_baddr) - 1);
+ burst_size = round_up(burst_size, 8);
+ burst_size = min(burst_size, 128U);
+
+ /*
+ * address TKT339017:
+ * fixup for burst size vs stride mismatch
+ */
+ if (modifier)
+ stride = round_up(stride + round_up(_baddr % 8, 8), burst_size);
+ else
+ stride = round_up(stride, burst_size);
+
+ return stride < 0x10000;
+}
+EXPORT_SYMBOL_GPL(prg_stride_double_check);
+
+void prg_set_auxiliary(struct prg *prg)
+{
+ if (WARN_ON(!prg))
+ return;
+
+ prg->is_auxiliary = true;
+}
+EXPORT_SYMBOL_GPL(prg_set_auxiliary);
+
+void prg_set_primary(struct prg *prg)
+{
+ if (WARN_ON(!prg))
+ return;
+
+ prg->is_auxiliary = false;
+}
+EXPORT_SYMBOL_GPL(prg_set_primary);
+
+void prg_set_blit(struct prg *prg)
+{
+ if (WARN_ON(!prg))
+ return;
+
+ prg->is_blit = true;
+}
+EXPORT_SYMBOL_GPL(prg_set_blit);
+
+struct prg *
+prg_lookup_by_phandle(struct device *dev, const char *name, int index)
+{
+ struct device_node *prg_node = of_parse_phandle(dev->of_node,
+ name, index);
+ struct prg *prg;
+
+ mutex_lock(&prg_list_mutex);
+ list_for_each_entry(prg, &prg_list, list) {
+ if (prg_node == prg->dev->of_node) {
+ mutex_unlock(&prg_list_mutex);
+ device_link_add(dev, prg->dev, DL_FLAG_AUTOREMOVE);
+ return prg;
+ }
+ }
+ mutex_unlock(&prg_list_mutex);
+
+ return NULL;
+}
+EXPORT_SYMBOL_GPL(prg_lookup_by_phandle);
+
+static const struct of_device_id prg_dt_ids[] = {
+ { .compatible = "fsl,imx8qm-prg", },
+ { .compatible = "fsl,imx8qxp-prg", },
+ { /* sentinel */ },
+};
+
+static int prg_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct resource *res;
+ struct prg *prg;
+
+ prg = devm_kzalloc(dev, sizeof(*prg), GFP_KERNEL);
+ if (!prg)
+ return -ENOMEM;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ prg->base = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(prg->base))
+ return PTR_ERR(prg->base);
+
+ prg->clk_apb = devm_clk_get(dev, "apb");
+ if (IS_ERR(prg->clk_apb))
+ return PTR_ERR(prg->clk_apb);
+ clk_prepare_enable(prg->clk_apb);
+
+ prg->clk_rtram = devm_clk_get(dev, "rtram");
+ if (IS_ERR(prg->clk_rtram))
+ return PTR_ERR(prg->clk_rtram);
+ clk_prepare_enable(prg->clk_rtram);
+
+ prg->dev = dev;
+ platform_set_drvdata(pdev, prg);
+ mutex_lock(&prg_list_mutex);
+ list_add(&prg->list, &prg_list);
+ mutex_unlock(&prg_list_mutex);
+
+ prg_reset(prg);
+
+ return 0;
+}
+
+static int prg_remove(struct platform_device *pdev)
+{
+ struct prg *prg = platform_get_drvdata(pdev);
+
+ mutex_lock(&prg_list_mutex);
+ list_del(&prg->list);
+ mutex_unlock(&prg_list_mutex);
+
+ clk_disable_unprepare(prg->clk_rtram);
+ clk_disable_unprepare(prg->clk_apb);
+
+ return 0;
+}
+
+struct platform_driver prg_drv = {
+ .probe = prg_probe,
+ .remove = prg_remove,
+ .driver = {
+ .name = "imx8-prg",
+ .of_match_table = prg_dt_ids,
+ },
+};
+module_platform_driver(prg_drv);
+
+MODULE_DESCRIPTION("i.MX8 PRG driver");
+MODULE_AUTHOR("NXP Semiconductor");
+MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/ipu-v3/Kconfig b/drivers/gpu/imx/ipu-v3/Kconfig
index 87a20b3dcf7a..87a20b3dcf7a 100644
--- a/drivers/gpu/ipu-v3/Kconfig
+++ b/drivers/gpu/imx/ipu-v3/Kconfig
diff --git a/drivers/gpu/ipu-v3/Makefile b/drivers/gpu/imx/ipu-v3/Makefile
index 7cc8b47e488b..7cc8b47e488b 100644
--- a/drivers/gpu/ipu-v3/Makefile
+++ b/drivers/gpu/imx/ipu-v3/Makefile
diff --git a/drivers/gpu/ipu-v3/ipu-common.c b/drivers/gpu/imx/ipu-v3/ipu-common.c
index f3a57c0500f3..f3a57c0500f3 100644
--- a/drivers/gpu/ipu-v3/ipu-common.c
+++ b/drivers/gpu/imx/ipu-v3/ipu-common.c
diff --git a/drivers/gpu/ipu-v3/ipu-cpmem.c b/drivers/gpu/imx/ipu-v3/ipu-cpmem.c
index 1cb82f445f91..1cb82f445f91 100644
--- a/drivers/gpu/ipu-v3/ipu-cpmem.c
+++ b/drivers/gpu/imx/ipu-v3/ipu-cpmem.c
diff --git a/drivers/gpu/ipu-v3/ipu-csi.c b/drivers/gpu/imx/ipu-v3/ipu-csi.c
index 2bc51d4d3f1e..2bc51d4d3f1e 100644
--- a/drivers/gpu/ipu-v3/ipu-csi.c
+++ b/drivers/gpu/imx/ipu-v3/ipu-csi.c
diff --git a/drivers/gpu/ipu-v3/ipu-dc.c b/drivers/gpu/imx/ipu-v3/ipu-dc.c
index 7a4b8362dda8..7a4b8362dda8 100644
--- a/drivers/gpu/ipu-v3/ipu-dc.c
+++ b/drivers/gpu/imx/ipu-v3/ipu-dc.c
diff --git a/drivers/gpu/ipu-v3/ipu-di.c b/drivers/gpu/imx/ipu-v3/ipu-di.c
index d2f1bd9d3deb..d2f1bd9d3deb 100644
--- a/drivers/gpu/ipu-v3/ipu-di.c
+++ b/drivers/gpu/imx/ipu-v3/ipu-di.c
diff --git a/drivers/gpu/ipu-v3/ipu-dmfc.c b/drivers/gpu/imx/ipu-v3/ipu-dmfc.c
index a40f211f382f..a40f211f382f 100644
--- a/drivers/gpu/ipu-v3/ipu-dmfc.c
+++ b/drivers/gpu/imx/ipu-v3/ipu-dmfc.c
diff --git a/drivers/gpu/ipu-v3/ipu-dp.c b/drivers/gpu/imx/ipu-v3/ipu-dp.c
index 5e44ff1f2085..5e44ff1f2085 100644
--- a/drivers/gpu/ipu-v3/ipu-dp.c
+++ b/drivers/gpu/imx/ipu-v3/ipu-dp.c
diff --git a/drivers/gpu/ipu-v3/ipu-ic.c b/drivers/gpu/imx/ipu-v3/ipu-ic.c
index 65d7daf944b0..65d7daf944b0 100644
--- a/drivers/gpu/ipu-v3/ipu-ic.c
+++ b/drivers/gpu/imx/ipu-v3/ipu-ic.c
diff --git a/drivers/gpu/ipu-v3/ipu-image-convert.c b/drivers/gpu/imx/ipu-v3/ipu-image-convert.c
index a5e33d58e02f..a5e33d58e02f 100644
--- a/drivers/gpu/ipu-v3/ipu-image-convert.c
+++ b/drivers/gpu/imx/ipu-v3/ipu-image-convert.c
diff --git a/drivers/gpu/ipu-v3/ipu-pre.c b/drivers/gpu/imx/ipu-v3/ipu-pre.c
index 6fd4af647f59..6fd4af647f59 100644
--- a/drivers/gpu/ipu-v3/ipu-pre.c
+++ b/drivers/gpu/imx/ipu-v3/ipu-pre.c
diff --git a/drivers/gpu/ipu-v3/ipu-prg.c b/drivers/gpu/imx/ipu-v3/ipu-prg.c
index 1c36fa3a90e2..1c36fa3a90e2 100644
--- a/drivers/gpu/ipu-v3/ipu-prg.c
+++ b/drivers/gpu/imx/ipu-v3/ipu-prg.c
diff --git a/drivers/gpu/ipu-v3/ipu-prv.h b/drivers/gpu/imx/ipu-v3/ipu-prv.h
index ac4b8d658500..ac4b8d658500 100644
--- a/drivers/gpu/ipu-v3/ipu-prv.h
+++ b/drivers/gpu/imx/ipu-v3/ipu-prv.h
diff --git a/drivers/gpu/ipu-v3/ipu-smfc.c b/drivers/gpu/imx/ipu-v3/ipu-smfc.c
index 4ef910991413..4ef910991413 100644
--- a/drivers/gpu/ipu-v3/ipu-smfc.c
+++ b/drivers/gpu/imx/ipu-v3/ipu-smfc.c
diff --git a/drivers/gpu/ipu-v3/ipu-vdi.c b/drivers/gpu/imx/ipu-v3/ipu-vdi.c
index a66389366af7..a66389366af7 100644
--- a/drivers/gpu/ipu-v3/ipu-vdi.c
+++ b/drivers/gpu/imx/ipu-v3/ipu-vdi.c
diff --git a/drivers/gpu/imx/lcdif/Kconfig b/drivers/gpu/imx/lcdif/Kconfig
new file mode 100644
index 000000000000..5736a90117af
--- /dev/null
+++ b/drivers/gpu/imx/lcdif/Kconfig
@@ -0,0 +1,8 @@
+config IMX_LCDIF_CORE
+ tristate "i.MX LCDIF core support"
+ depends on ARCH_FSL_IMX8MM
+ select RESET_CONTROLLER
+ help
+ Choose this if you have a NXP i.MX8MM platform and want to use the
+ LCDIF display controller. This option only enables LCDIF base support.
+
diff --git a/drivers/gpu/imx/lcdif/Makefile b/drivers/gpu/imx/lcdif/Makefile
new file mode 100644
index 000000000000..8c7ce5ccce95
--- /dev/null
+++ b/drivers/gpu/imx/lcdif/Makefile
@@ -0,0 +1,3 @@
+obj-$(CONFIG_IMX_LCDIF_CORE) += imx-lcdif-core.o
+
+imx-lcdif-core-objs := lcdif-common.o
diff --git a/drivers/gpu/imx/lcdif/lcdif-common.c b/drivers/gpu/imx/lcdif/lcdif-common.c
new file mode 100644
index 000000000000..86b106956e65
--- /dev/null
+++ b/drivers/gpu/imx/lcdif/lcdif-common.c
@@ -0,0 +1,800 @@
+/*
+ * Copyright 2018 NXP
+ *
+ * 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/busfreq-imx.h>
+#include <linux/clk.h>
+#include <linux/iopoll.h>
+#include <linux/media-bus-format.h>
+#include <linux/mfd/syscon.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/of_graph.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/regmap.h>
+#include <linux/types.h>
+#include <drm/drm_fourcc.h>
+#include <video/imx-lcdif.h>
+#include <video/videomode.h>
+
+#include "lcdif-regs.h"
+
+#define DRIVER_NAME "imx-lcdif"
+
+/* TODO: add this to platform data later */
+#define DISP_MIX_SFT_RSTN_CSR 0x00
+#define DISP_MIX_CLK_EN_CSR 0x04
+
+/* 'DISP_MIX_SFT_RSTN_CSR' bit fields */
+#define BUS_RSTN_BLK_SYNC_SFT_EN BIT(6)
+
+/* 'DISP_MIX_CLK_EN_CSR' bit fields */
+#define BUS_BLK_CLK_SFT_EN BIT(12)
+#define LCDIF_PIXEL_CLK_SFT_EN BIT(7)
+#define LCDIF_APB_CLK_SFT_EN BIT(6)
+
+struct lcdif_soc {
+ struct device *dev;
+
+ int irq;
+ void __iomem *base;
+ struct regmap *gpr;
+ atomic_t rpm_suspended;
+
+ struct clk *clk_pix;
+ struct clk *clk_disp_axi;
+ struct clk *clk_disp_apb;
+};
+
+struct lcdif_soc_pdata {
+ bool hsync_invert;
+ bool vsync_invert;
+ bool de_invert;
+};
+
+struct lcdif_platform_reg {
+ struct lcdif_client_platformdata pdata;
+ char *name;
+};
+
+struct lcdif_platform_reg client_reg[] = {
+ {
+ .pdata = { },
+ .name = "imx-lcdif-crtc",
+ },
+};
+
+struct lcdif_soc_pdata imx8mm_pdata = {
+ .hsync_invert = true,
+ .vsync_invert = true,
+ .de_invert = true,
+};
+
+static const struct of_device_id imx_lcdif_dt_ids[] = {
+ { .compatible = "fsl,imx8mm-lcdif", .data = &imx8mm_pdata, },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, lcdif_dt_ids);
+
+#ifdef CONFIG_PM
+static int imx_lcdif_runtime_suspend(struct device *dev);
+static int imx_lcdif_runtime_resume(struct device *dev);
+#else
+static int imx_lcdif_runtime_suspend(struct device *dev)
+{
+ return 0;
+}
+static int imx_lcdif_runtime_resume(struct device *dev)
+{
+ return 0;
+}
+#endif
+
+void disp_mix_bus_rstn_reset(struct regmap *gpr, bool reset)
+{
+ if (!reset)
+ /* release reset */
+ regmap_update_bits(gpr, DISP_MIX_SFT_RSTN_CSR,
+ BUS_RSTN_BLK_SYNC_SFT_EN,
+ BUS_RSTN_BLK_SYNC_SFT_EN);
+ else
+ /* hold reset */
+ regmap_update_bits(gpr, DISP_MIX_SFT_RSTN_CSR,
+ BUS_RSTN_BLK_SYNC_SFT_EN,
+ 0x0);
+}
+
+void disp_mix_lcdif_clks_enable(struct regmap *gpr, bool enable)
+{
+ if (enable)
+ /* enable lcdif clks */
+ regmap_update_bits(gpr, DISP_MIX_CLK_EN_CSR,
+ LCDIF_PIXEL_CLK_SFT_EN | LCDIF_APB_CLK_SFT_EN,
+ LCDIF_PIXEL_CLK_SFT_EN | LCDIF_APB_CLK_SFT_EN);
+ else
+ /* disable lcdif clks */
+ regmap_update_bits(gpr, DISP_MIX_CLK_EN_CSR,
+ LCDIF_PIXEL_CLK_SFT_EN | LCDIF_APB_CLK_SFT_EN,
+ 0x0);
+}
+
+static int lcdif_enable_clocks(struct lcdif_soc *lcdif)
+{
+ int ret;
+
+ if (lcdif->clk_disp_axi) {
+ ret = clk_prepare_enable(lcdif->clk_disp_axi);
+ if (ret)
+ return ret;
+ }
+
+ if (lcdif->clk_disp_apb) {
+ ret = clk_prepare_enable(lcdif->clk_disp_apb);
+ if (ret)
+ goto disable_disp_axi;
+ }
+
+ ret = clk_prepare_enable(lcdif->clk_pix);
+ if (ret)
+ goto disable_disp_apb;
+
+ return 0;
+
+disable_disp_apb:
+ if (lcdif->clk_disp_apb)
+ clk_disable_unprepare(lcdif->clk_disp_apb);
+disable_disp_axi:
+ if (lcdif->clk_disp_axi)
+ clk_disable_unprepare(lcdif->clk_disp_axi);
+
+ return ret;
+}
+
+static void lcdif_disable_clocks(struct lcdif_soc *lcdif)
+{
+ clk_disable_unprepare(lcdif->clk_pix);
+
+ if (lcdif->clk_disp_axi)
+ clk_disable_unprepare(lcdif->clk_disp_axi);
+
+ if (lcdif->clk_disp_apb)
+ clk_disable_unprepare(lcdif->clk_disp_apb);
+}
+
+int lcdif_vblank_irq_get(struct lcdif_soc *lcdif)
+{
+ return lcdif->irq;
+}
+EXPORT_SYMBOL(lcdif_vblank_irq_get);
+
+void lcdif_dump_registers(struct lcdif_soc *lcdif)
+{
+ pr_info("%#x : %#x\n", LCDIF_CTRL,
+ readl(lcdif->base + LCDIF_CTRL));
+ pr_info("%#x : %#x\n", LCDIF_CTRL1,
+ readl(lcdif->base + LCDIF_CTRL1));
+ pr_info("%#x : %#x\n", LCDIF_CTRL2,
+ readl(lcdif->base + LCDIF_CTRL2));
+ pr_info("%#x : %#x\n", LCDIF_TRANSFER_COUNT,
+ readl(lcdif->base + LCDIF_TRANSFER_COUNT));
+ pr_info("%#x : %#x\n", LCDIF_CUR_BUF,
+ readl(lcdif->base + LCDIF_CUR_BUF));
+ pr_info("%#x : %#x\n", LCDIF_NEXT_BUF,
+ readl(lcdif->base + LCDIF_NEXT_BUF));
+ pr_info("%#x : %#x\n", LCDIF_VDCTRL0,
+ readl(lcdif->base + LCDIF_VDCTRL0));
+ pr_info("%#x : %#x\n", LCDIF_VDCTRL1,
+ readl(lcdif->base + LCDIF_VDCTRL1));
+ pr_info("%#x : %#x\n", LCDIF_VDCTRL2,
+ readl(lcdif->base + LCDIF_VDCTRL2));
+ pr_info("%#x : %#x\n", LCDIF_VDCTRL3,
+ readl(lcdif->base + LCDIF_VDCTRL3));
+ pr_info("%#x : %#x\n", LCDIF_VDCTRL4,
+ readl(lcdif->base + LCDIF_VDCTRL4));
+}
+EXPORT_SYMBOL(lcdif_dump_registers);
+
+void lcdif_vblank_irq_enable(struct lcdif_soc *lcdif)
+{
+ writel(CTRL1_CUR_FRAME_DONE_IRQ, lcdif->base + LCDIF_CTRL1 + REG_CLR);
+ writel(CTRL1_CUR_FRAME_DONE_IRQ_EN, lcdif->base + LCDIF_CTRL1 + REG_SET);
+}
+EXPORT_SYMBOL(lcdif_vblank_irq_enable);
+
+void lcdif_vblank_irq_disable(struct lcdif_soc *lcdif)
+{
+ writel(CTRL1_CUR_FRAME_DONE_IRQ_EN, lcdif->base + LCDIF_CTRL1 + REG_CLR);
+ writel(CTRL1_CUR_FRAME_DONE_IRQ, lcdif->base + LCDIF_CTRL1 + REG_CLR);
+}
+EXPORT_SYMBOL(lcdif_vblank_irq_disable);
+
+void lcdif_vblank_irq_clear(struct lcdif_soc *lcdif)
+{
+ writel(CTRL1_CUR_FRAME_DONE_IRQ, lcdif->base + LCDIF_CTRL1 + REG_CLR);
+}
+EXPORT_SYMBOL(lcdif_vblank_irq_clear);
+
+static uint32_t lcdif_get_bpp_from_fmt(uint32_t format)
+{
+ /* TODO: only support RGB for now */
+
+ switch (format) {
+ case DRM_FORMAT_RGB565:
+ case DRM_FORMAT_BGR565:
+ case DRM_FORMAT_ARGB1555:
+ case DRM_FORMAT_XRGB1555:
+ case DRM_FORMAT_ABGR1555:
+ case DRM_FORMAT_XBGR1555:
+ return 16;
+ case DRM_FORMAT_ARGB8888:
+ case DRM_FORMAT_XRGB8888:
+ case DRM_FORMAT_ABGR8888:
+ case DRM_FORMAT_XBGR8888:
+ case DRM_FORMAT_RGBA8888:
+ case DRM_FORMAT_RGBX8888:
+ return 32;
+ default:
+ /* unsupported format */
+ return 0;
+ }
+}
+
+/*
+ * Get the bus format supported by LCDIF
+ * according to drm fourcc format
+ */
+int lcdif_get_bus_fmt_from_pix_fmt(struct lcdif_soc *lcdif,
+ uint32_t format)
+{
+ uint32_t bpp;
+
+ bpp = lcdif_get_bpp_from_fmt(format);
+ if (!bpp)
+ return -EINVAL;
+
+ switch (bpp) {
+ case 16:
+ return MEDIA_BUS_FMT_RGB565_1X16;
+ case 18:
+ return MEDIA_BUS_FMT_RGB666_1X18;
+ case 24:
+ case 32:
+ return MEDIA_BUS_FMT_RGB888_1X24;
+ default:
+ return -EINVAL;
+ }
+}
+EXPORT_SYMBOL(lcdif_get_bus_fmt_from_pix_fmt);
+
+int lcdif_set_pix_fmt(struct lcdif_soc *lcdif, u32 format)
+{
+ struct drm_format_name_buf format_name;
+ u32 ctrl = 0, ctrl1 = 0;
+
+ /* TODO: lcdif should be disabled to set pixel format */
+
+ ctrl = readl(lcdif->base + LCDIF_CTRL);
+ ctrl1 = readl(lcdif->base + LCDIF_CTRL1);
+
+ /* clear pixel format related bits */
+ ctrl &= ~(CTRL_SHIFT_NUM(0x3f) | CTRL_INPUT_SWIZZLE(0x3) |
+ CTRL_CSC_SWIZZLE(0x3) | CTRL_SET_WORD_LENGTH(0x3));
+
+ ctrl1 &= ~CTRL1_SET_BYTE_PACKAGING(0xf);
+
+ /* default is 'RGB' order */
+ writel(CTRL2_ODD_LINE_PATTERN(0x7) |
+ CTRL2_EVEN_LINE_PATTERN(0x7),
+ lcdif->base + LCDIF_CTRL2 + REG_CLR);
+
+ switch (format) {
+ /* bpp 16 */
+ case DRM_FORMAT_RGB565:
+ case DRM_FORMAT_BGR565:
+ case DRM_FORMAT_ARGB1555:
+ case DRM_FORMAT_XRGB1555:
+ case DRM_FORMAT_ABGR1555:
+ case DRM_FORMAT_XBGR1555:
+ /* Data format */
+ ctrl = (format == DRM_FORMAT_RGB565 ||
+ format == DRM_FORMAT_BGR565) ?
+ (ctrl & ~CTRL_DF16) : (ctrl | CTRL_DF16);
+
+ ctrl |= CTRL_SET_WORD_LENGTH(0x0);
+
+ /* Byte packing */
+ ctrl1 |= CTRL1_SET_BYTE_PACKAGING(0xf);
+
+ /* 'BGR' order */
+ if (format == DRM_FORMAT_BGR565 ||
+ format == DRM_FORMAT_ABGR1555 ||
+ format == DRM_FORMAT_XBGR1555)
+ writel(CTRL2_ODD_LINE_PATTERN(0x5) |
+ CTRL2_EVEN_LINE_PATTERN(0x5),
+ lcdif->base + LCDIF_CTRL2 + REG_SET);
+ break;
+ /* bpp 32 */
+ case DRM_FORMAT_ARGB8888:
+ case DRM_FORMAT_XRGB8888:
+ case DRM_FORMAT_ABGR8888:
+ case DRM_FORMAT_XBGR8888:
+ case DRM_FORMAT_RGBA8888:
+ case DRM_FORMAT_RGBX8888:
+ /*Data format */
+ ctrl &= ~CTRL_DF24;
+ ctrl |= CTRL_SET_WORD_LENGTH(3);
+
+ if (format == DRM_FORMAT_RGBA8888 ||
+ format == DRM_FORMAT_RGBX8888)
+ ctrl |= CTRL_SHIFT_DIR(1) | CTRL_SHIFT_NUM(8);
+
+ /* Byte packing */
+ ctrl1 |= CTRL1_SET_BYTE_PACKAGING(0x7);
+
+ /* 'BGR' order */
+ if (format == DRM_FORMAT_ABGR8888 ||
+ format == DRM_FORMAT_XBGR8888)
+ writel(CTRL2_ODD_LINE_PATTERN(0x5) |
+ CTRL2_EVEN_LINE_PATTERN(0x5),
+ lcdif->base + LCDIF_CTRL2 + REG_SET);
+ break;
+ default:
+ dev_err(lcdif->dev, "unsupported pixel format: %s\n",
+ drm_get_format_name(format, &format_name));
+ return -EINVAL;
+ }
+
+ writel(ctrl, lcdif->base + LCDIF_CTRL);
+ writel(ctrl1, lcdif->base + LCDIF_CTRL1);
+
+ return 0;
+}
+EXPORT_SYMBOL(lcdif_set_pix_fmt);
+
+void lcdif_set_bus_fmt(struct lcdif_soc *lcdif, u32 bus_format)
+{
+ u32 bus_width;
+
+ switch (bus_format) {
+ case MEDIA_BUS_FMT_RGB565_1X16:
+ bus_width = CTRL_SET_BUS_WIDTH(STMLCDIF_16BIT);
+ break;
+ case MEDIA_BUS_FMT_RGB666_1X18:
+ bus_width = CTRL_SET_BUS_WIDTH(STMLCDIF_18BIT);
+ break;
+ case MEDIA_BUS_FMT_RGB888_1X24:
+ bus_width = CTRL_SET_BUS_WIDTH(STMLCDIF_24BIT);
+ break;
+ default:
+ dev_err(lcdif->dev, "unknown bus format: %#x\n", bus_format);
+ return;
+ }
+
+ writel(CTRL_SET_BUS_WIDTH(0x3), lcdif->base + LCDIF_CTRL + REG_CLR);
+ writel(bus_width, lcdif->base + LCDIF_CTRL + REG_SET);
+}
+EXPORT_SYMBOL(lcdif_set_bus_fmt);
+
+void lcdif_set_fb_addr(struct lcdif_soc *lcdif, int id, u32 addr)
+{
+ switch (id) {
+ case 0:
+ /* primary plane */
+ writel(addr, lcdif->base + LCDIF_NEXT_BUF);
+ break;
+ default:
+ /* TODO: add overlay support */
+ return;
+ }
+}
+EXPORT_SYMBOL(lcdif_set_fb_addr);
+
+void lcdif_set_fb_hcrop(struct lcdif_soc *lcdif, u32 src_w,
+ u32 fb_w, bool crop)
+{
+ u32 mask_cnt, htotal, hcount;
+ u32 vdctrl2, vdctrl3, vdctrl4, transfer_count;
+ u32 pigeon_12_0, pigeon_12_1, pigeon_12_2;
+
+ if (!crop) {
+ writel(0x0, lcdif->base + HW_EPDC_PIGEON_12_0);
+ writel(0x0, lcdif->base + HW_EPDC_PIGEON_12_1);
+
+ return;
+ }
+
+ /* transfer_count's hcount, vdctrl2's htotal and vdctrl4's
+ * H_VALID_DATA_CNT should use fb width instead of hactive
+ * when requires cropping.
+ * */
+ transfer_count = readl(lcdif->base + LCDIF_TRANSFER_COUNT);
+ hcount = TRANSFER_COUNT_GET_HCOUNT(transfer_count);
+
+ transfer_count &= ~TRANSFER_COUNT_SET_HCOUNT(0xffff);
+ transfer_count |= TRANSFER_COUNT_SET_HCOUNT(fb_w);
+ writel(transfer_count, lcdif->base + LCDIF_TRANSFER_COUNT);
+
+ vdctrl2 = readl(lcdif->base + LCDIF_VDCTRL2);
+ htotal = VDCTRL2_GET_HSYNC_PERIOD(vdctrl2);
+ htotal += fb_w - hcount;
+ vdctrl2 &= ~VDCTRL2_SET_HSYNC_PERIOD(0x3ffff);
+ vdctrl2 |= VDCTRL2_SET_HSYNC_PERIOD(htotal);
+ writel(vdctrl2, lcdif->base + LCDIF_VDCTRL2);
+
+ vdctrl4 = readl(lcdif->base + LCDIF_VDCTRL4);
+ vdctrl4 &= ~SET_DOTCLK_H_VALID_DATA_CNT(0x3ffff);
+ vdctrl4 |= SET_DOTCLK_H_VALID_DATA_CNT(fb_w);
+ writel(vdctrl4, lcdif->base + LCDIF_VDCTRL4);
+
+ /* configure related pigeon registers */
+ vdctrl3 = readl(lcdif->base + LCDIF_VDCTRL3);
+ mask_cnt = GET_HOR_WAIT_CNT(vdctrl3) - 5;
+
+ pigeon_12_0 = PIGEON_12_0_SET_STATE_MASK(0x24) |
+ PIGEON_12_0_SET_MASK_CNT(mask_cnt) |
+ PIGEON_12_0_SET_MASK_CNT_SEL(0x6) |
+ PIGEON_12_0_POL_ACTIVE_LOW |
+ PIGEON_12_0_EN;
+ writel(pigeon_12_0, lcdif->base + HW_EPDC_PIGEON_12_0);
+
+ pigeon_12_1 = PIGEON_12_1_SET_CLR_CNT(src_w) |
+ PIGEON_12_1_SET_SET_CNT(0x0);
+ writel(pigeon_12_1, lcdif->base + HW_EPDC_PIGEON_12_1);
+
+ pigeon_12_2 = 0x0;
+ writel(pigeon_12_2, lcdif->base + HW_EPDC_PIGEON_12_2);
+}
+EXPORT_SYMBOL(lcdif_set_fb_hcrop);
+
+
+void lcdif_set_mode(struct lcdif_soc *lcdif, struct videomode *vmode)
+{
+ const struct of_device_id *of_id =
+ of_match_device(imx_lcdif_dt_ids, lcdif->dev);
+ const struct lcdif_soc_pdata *soc_pdata = of_id->data;
+ u32 vdctrl0, vdctrl1, vdctrl2, vdctrl3, vdctrl4, htotal;
+
+ /* Clear the FIFO */
+ writel(CTRL1_FIFO_CLEAR, lcdif->base + LCDIF_CTRL1 + REG_SET);
+ writel(CTRL1_FIFO_CLEAR, lcdif->base + LCDIF_CTRL1 + REG_CLR);
+
+ /* set pixel clock rate */
+ clk_disable_unprepare(lcdif->clk_pix);
+ clk_set_rate(lcdif->clk_pix, vmode->pixelclock);
+ clk_prepare_enable(lcdif->clk_pix);
+
+ /* config display timings */
+ writel(TRANSFER_COUNT_SET_VCOUNT(vmode->vactive) |
+ TRANSFER_COUNT_SET_HCOUNT(vmode->hactive),
+ lcdif->base + LCDIF_TRANSFER_COUNT);
+
+ vdctrl0 = VDCTRL0_ENABLE_PRESENT |
+ VDCTRL0_VSYNC_PERIOD_UNIT |
+ VDCTRL0_VSYNC_PULSE_WIDTH_UNIT |
+ VDCTRL0_SET_VSYNC_PULSE_WIDTH(vmode->vsync_len);
+
+ /* Polarities */
+ if (soc_pdata) {
+ if ((soc_pdata->hsync_invert &&
+ vmode->flags & DISPLAY_FLAGS_HSYNC_LOW) ||
+ (!soc_pdata->hsync_invert &&
+ vmode->flags & DISPLAY_FLAGS_HSYNC_HIGH))
+ vdctrl0 |= VDCTRL0_HSYNC_ACT_HIGH;
+
+ if ((soc_pdata->vsync_invert &&
+ vmode->flags & DISPLAY_FLAGS_VSYNC_LOW) ||
+ (!soc_pdata->vsync_invert &&
+ vmode->flags & DISPLAY_FLAGS_VSYNC_HIGH))
+ vdctrl0 |= VDCTRL0_VSYNC_ACT_HIGH;
+
+ if ((soc_pdata->de_invert &&
+ vmode->flags & DISPLAY_FLAGS_DE_LOW) ||
+ (!soc_pdata->de_invert &&
+ vmode->flags & DISPLAY_FLAGS_DE_HIGH))
+ vdctrl0 |= VDCTRL0_ENABLE_ACT_HIGH;
+ } else {
+ if (vmode->flags & DISPLAY_FLAGS_HSYNC_HIGH)
+ vdctrl0 |= VDCTRL0_HSYNC_ACT_HIGH;
+ if (vmode->flags & DISPLAY_FLAGS_VSYNC_HIGH)
+ vdctrl0 |= VDCTRL0_VSYNC_ACT_HIGH;
+ if (vmode->flags & DISPLAY_FLAGS_DE_HIGH)
+ vdctrl0 |= VDCTRL0_ENABLE_ACT_HIGH;
+ }
+
+ if (vmode->flags & DISPLAY_FLAGS_PIXDATA_POSEDGE)
+ vdctrl0 |= VDCTRL0_DOTCLK_ACT_FALLING;
+
+ writel(vdctrl0, lcdif->base + LCDIF_VDCTRL0);
+
+ vdctrl1 = vmode->vactive + vmode->vsync_len +
+ vmode->vfront_porch + vmode->vback_porch;
+ writel(vdctrl1, lcdif->base + LCDIF_VDCTRL1);
+
+ htotal = vmode->hactive + vmode->hsync_len +
+ vmode->hfront_porch + vmode->hback_porch;
+ vdctrl2 = VDCTRL2_SET_HSYNC_PULSE_WIDTH(vmode->hsync_len) |
+ VDCTRL2_SET_HSYNC_PERIOD(htotal);
+ writel(vdctrl2, lcdif->base + LCDIF_VDCTRL2);
+
+ vdctrl3 = SET_HOR_WAIT_CNT(vmode->hsync_len + vmode->hback_porch) |
+ SET_VERT_WAIT_CNT(vmode->vsync_len + vmode->vback_porch);
+ writel(vdctrl3, lcdif->base + LCDIF_VDCTRL3);
+
+ vdctrl4 = SET_DOTCLK_H_VALID_DATA_CNT(vmode->hactive);
+ writel(vdctrl4, lcdif->base + LCDIF_VDCTRL4);
+}
+EXPORT_SYMBOL(lcdif_set_mode);
+
+void lcdif_enable_controller(struct lcdif_soc *lcdif)
+{
+ u32 ctrl2, vdctrl4;
+
+ ctrl2 = readl(lcdif->base + LCDIF_CTRL2);
+ vdctrl4 = readl(lcdif->base + LCDIF_VDCTRL4);
+
+ ctrl2 &= ~CTRL2_OUTSTANDING_REQS(0x7);
+ ctrl2 |= CTRL2_OUTSTANDING_REQS(REQ_16);
+ writel(ctrl2, lcdif->base + LCDIF_CTRL2);
+
+ /* Continous dotclock mode */
+ writel(CTRL_BYPASS_COUNT | CTRL_DOTCLK_MODE,
+ lcdif->base + LCDIF_CTRL + REG_SET);
+
+ /* enable the SYNC signals first, then the DMA engine */
+ vdctrl4 |= VDCTRL4_SYNC_SIGNALS_ON;
+ writel(vdctrl4, lcdif->base + LCDIF_VDCTRL4);
+
+ /* enable underflow recovery */
+ writel(CTRL1_RECOVERY_ON_UNDERFLOW,
+ lcdif->base + LCDIF_CTRL1 + REG_SET);
+
+ /* run lcdif */
+ writel(CTRL_MASTER, lcdif->base + LCDIF_CTRL + REG_SET);
+ writel(CTRL_RUN, lcdif->base + LCDIF_CTRL + REG_SET);
+}
+EXPORT_SYMBOL(lcdif_enable_controller);
+
+void lcdif_disable_controller(struct lcdif_soc *lcdif)
+{
+ int ret;
+ u32 ctrl, vdctrl4;
+
+ writel(CTRL_RUN, lcdif->base + LCDIF_CTRL + REG_CLR);
+ writel(CTRL_DOTCLK_MODE, lcdif->base + LCDIF_CTRL + REG_CLR);
+
+ ret = readl_poll_timeout(lcdif->base + LCDIF_CTRL, ctrl,
+ !(ctrl & CTRL_RUN), 0, 1000);
+ if (WARN_ON(ret))
+ dev_err(lcdif->dev, "disable lcdif run timeout\n");
+
+ writel(CTRL_MASTER, lcdif->base + LCDIF_CTRL + REG_CLR);
+
+ vdctrl4 = readl(lcdif->base + LCDIF_VDCTRL4);
+ vdctrl4 &= ~VDCTRL4_SYNC_SIGNALS_ON;
+ writel(vdctrl4, lcdif->base + LCDIF_VDCTRL4);
+}
+EXPORT_SYMBOL(lcdif_disable_controller);
+
+static int platform_remove_device_fn(struct device *dev, void *data)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+
+ platform_device_unregister(pdev);
+
+ return 0;
+}
+
+static void platform_device_unregister_children(struct platform_device *pdev)
+{
+ device_for_each_child(&pdev->dev, NULL, platform_remove_device_fn);
+}
+
+static int lcdif_add_client_devices(struct lcdif_soc *lcdif)
+{
+ int ret = 0, i;
+ struct device *dev = lcdif->dev;
+ struct platform_device *pdev = NULL;
+ struct device_node *of_node;
+
+ for (i = 0; i < ARRAY_SIZE(client_reg); i++) {
+ of_node = of_graph_get_port_by_id(dev->of_node, i);
+ if (!of_node) {
+ dev_info(dev, "no port@%d node in %s\n",
+ i, dev->of_node->full_name);
+ continue;
+ }
+ of_node_put(of_node);
+
+ pdev = platform_device_alloc(client_reg[i].name, i);
+ if (!pdev) {
+ dev_err(dev, "Can't allocate port pdev\n");
+ ret = -ENOMEM;
+ goto err_register;
+ }
+
+ pdev->dev.parent = dev;
+ client_reg[i].pdata.of_node = of_node;
+
+ ret = platform_device_add_data(pdev, &client_reg[i].pdata,
+ sizeof(client_reg[i].pdata));
+ if (!ret)
+ ret = platform_device_add(pdev);
+ if (ret) {
+ platform_device_put(pdev);
+ goto err_register;
+ }
+
+ pdev->dev.of_node = of_node;
+ }
+
+ if (!pdev)
+ return -ENODEV;
+
+ return 0;
+
+err_register:
+ platform_device_unregister_children(to_platform_device(dev));
+ return ret;
+}
+
+static int imx_lcdif_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct device_node *np = dev->of_node;
+ struct lcdif_soc *lcdif;
+ struct resource *res;
+
+ dev_dbg(dev, "%s: probe begin\n", __func__);
+
+ lcdif = devm_kzalloc(dev, sizeof(*lcdif), GFP_KERNEL);
+ if (!lcdif) {
+ dev_err(dev, "Can't allocate 'lcdif_soc' structure\n");
+ return -ENOMEM;
+ }
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res)
+ return -ENODEV;
+
+ lcdif->irq = platform_get_irq(pdev, 0);
+ if (lcdif->irq < 0)
+ return -ENODEV;
+
+ lcdif->clk_pix = devm_clk_get(dev, "pix");
+ if (IS_ERR(lcdif->clk_pix))
+ return PTR_ERR(lcdif->clk_pix);
+
+ lcdif->clk_disp_axi = devm_clk_get(dev, "disp-axi");
+ if (IS_ERR(lcdif->clk_disp_axi))
+ lcdif->clk_disp_axi = NULL;
+
+ lcdif->clk_disp_apb = devm_clk_get(dev, "disp-apb");
+ if (IS_ERR(lcdif->clk_disp_apb))
+ lcdif->clk_disp_apb = NULL;
+
+ lcdif->base = devm_ioremap_resource(dev, res);
+ if (IS_ERR(lcdif->base))
+ return PTR_ERR(lcdif->base);
+
+ lcdif->gpr = syscon_regmap_lookup_by_phandle(np, "lcdif-gpr");
+ if (IS_ERR(lcdif->gpr))
+ return PTR_ERR(lcdif->gpr);
+
+ lcdif->dev = dev;
+ platform_set_drvdata(pdev, lcdif);
+
+ atomic_set(&lcdif->rpm_suspended, 0);
+ pm_runtime_enable(dev);
+ atomic_inc(&lcdif->rpm_suspended);
+
+ dev_dbg(dev, "%s: probe end\n", __func__);
+
+ return lcdif_add_client_devices(lcdif);
+}
+
+static int imx_lcdif_remove(struct platform_device *pdev)
+{
+ pm_runtime_disable(&pdev->dev);
+
+ return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int imx_lcdif_suspend(struct device *dev)
+{
+ return imx_lcdif_runtime_suspend(dev);
+}
+
+static int imx_lcdif_resume(struct device *dev)
+{
+ return imx_lcdif_runtime_resume(dev);
+}
+#else
+static int imx_lcdif_suspend(struct device *dev)
+{
+ return 0;
+}
+static int imx_lcdif_resume(struct device *dev)
+{
+ return 0;
+}
+#endif
+
+#ifdef CONFIG_PM
+static int imx_lcdif_runtime_suspend(struct device *dev)
+{
+ struct lcdif_soc *lcdif = dev_get_drvdata(dev);
+
+ if (atomic_inc_return(&lcdif->rpm_suspended) > 1)
+ return 0;
+
+ lcdif_disable_clocks(lcdif);
+
+ release_bus_freq(BUS_FREQ_HIGH);
+
+ return 0;
+}
+
+static int imx_lcdif_runtime_resume(struct device *dev)
+{
+ int ret = 0;
+ struct lcdif_soc *lcdif = dev_get_drvdata(dev);
+
+ if (unlikely(!atomic_read(&lcdif->rpm_suspended))) {
+ dev_warn(lcdif->dev, "Unbalanced %s!\n", __func__);
+ return 0;
+ }
+
+ if (!atomic_dec_and_test(&lcdif->rpm_suspended))
+ return 0;
+
+ request_bus_freq(BUS_FREQ_HIGH);
+
+ ret = lcdif_enable_clocks(lcdif);
+ if (ret) {
+ release_bus_freq(BUS_FREQ_HIGH);
+ return ret;
+ }
+
+ disp_mix_bus_rstn_reset(lcdif->gpr, false);
+ disp_mix_lcdif_clks_enable(lcdif->gpr, true);
+
+ /* Pull LCDIF out of reset */
+ writel(0x0, lcdif->base + LCDIF_CTRL);
+
+ return ret;
+}
+#endif
+
+static const struct dev_pm_ops imx_lcdif_pm_ops = {
+ SET_SYSTEM_SLEEP_PM_OPS(imx_lcdif_suspend, imx_lcdif_resume)
+ SET_RUNTIME_PM_OPS(imx_lcdif_runtime_suspend,
+ imx_lcdif_runtime_resume, NULL)
+};
+
+struct platform_driver imx_lcdif_driver = {
+ .probe = imx_lcdif_probe,
+ .remove = imx_lcdif_remove,
+ .driver = {
+ .name = DRIVER_NAME,
+ .of_match_table = imx_lcdif_dt_ids,
+ .pm = &imx_lcdif_pm_ops,
+ },
+};
+
+module_platform_driver(imx_lcdif_driver);
+
+MODULE_DESCRIPTION("NXP i.MX LCDIF Display Controller driver");
+MODULE_AUTHOR("Fancy Fang <chen.fang@nxp.com>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/imx/lcdif/lcdif-regs.h b/drivers/gpu/imx/lcdif/lcdif-regs.h
new file mode 100644
index 000000000000..de2f1c55591c
--- /dev/null
+++ b/drivers/gpu/imx/lcdif/lcdif-regs.h
@@ -0,0 +1,144 @@
+/*
+ * Copyright 2018 NXP
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __LCDIF_REGS_H
+#define __LCDIF_REGS_H
+
+#define REG_SET 4
+#define REG_CLR 8
+
+/* regs offset */
+#define LCDIF_CTRL 0x00
+#define LCDIF_CTRL1 0X10
+#define LCDIF_CTRL2 0X20
+#define LCDIF_TRANSFER_COUNT 0x30
+#define LCDIF_CUR_BUF 0x40
+#define LCDIF_NEXT_BUF 0x50
+#define LCDIF_TIMING 0x60
+#define LCDIF_VDCTRL0 0x70
+#define LCDIF_VDCTRL1 0x80
+#define LCDIF_VDCTRL2 0x90
+#define LCDIF_VDCTRL3 0xa0
+#define LCDIF_VDCTRL4 0xb0
+
+/* pigeon registers for crop */
+#define HW_EPDC_PIGEON_12_0 0xb00
+#define HW_EPDC_PIGEON_12_1 0xb10
+#define HW_EPDC_PIGEON_12_2 0xb20
+
+/* reg bit manipulation */
+#define REG_MASK(e, s) (((1 << ((e) - (s) + 1)) - 1) << (s))
+#define REG_PUT(x, e, s) (((x) << (s)) & REG_MASK(e, s))
+#define REG_GET(x, e, s) (((x) & REG_MASK(e, s)) >> (s))
+
+#define SWIZZLE_LE 0 /* Little-Endian or No swap */
+#define SWIZZLE_BE 1 /* Big-Endian or swap all */
+#define SWIZZLE_HWD 2 /* Swap half-words */
+#define SWIZZLE_HWD_BYTE 3 /* Swap bytes within each half-word */
+
+/* regs bit fields */
+#define CTRL_SFTRST BIT(31)
+#define CTRL_CLKGATE BIT(30)
+#define CTRL_SHIFT_DIR(x) REG_PUT((x), 26, 26)
+#define CTRL_SHIFT_NUM(x) REG_PUT((x), 25, 21)
+#define CTRL_BYPASS_COUNT BIT(19)
+#define CTRL_VSYNC_MODE BIT(18)
+#define CTRL_DOTCLK_MODE BIT(17)
+#define CTRL_DATA_SELECT BIT(16)
+#define CTRL_INPUT_SWIZZLE(x) REG_PUT((x), 15, 14)
+#define CTRL_CSC_SWIZZLE(x) REG_PUT((x), 13, 12)
+#define CTRL_SET_BUS_WIDTH(x) REG_PUT((x), 11, 10)
+#define CTRL_GET_BUS_WIDTH(x) REG_GET((x), 11, 10)
+#define CTRL_BUS_WIDTH_MASK REG_PUT((0x3), 11, 10)
+#define CTRL_SET_WORD_LENGTH(x) REG_PUT((x), 9, 8)
+#define CTRL_GET_WORD_LENGTH(x) REG_GET((x), 9, 8)
+#define CTRL_MASTER BIT(5)
+#define CTRL_DF16 BIT(3)
+#define CTRL_DF18 BIT(2)
+#define CTRL_DF24 BIT(1)
+#define CTRL_RUN BIT(0)
+
+#define CTRL1_RECOVERY_ON_UNDERFLOW BIT(24)
+#define CTRL1_FIFO_CLEAR BIT(21)
+#define CTRL1_SET_BYTE_PACKAGING(x) REG_PUT((x), 19, 16)
+#define CTRL1_GET_BYTE_PACKAGING(x) REG_GET((x), 19, 16)
+#define CTRL1_CUR_FRAME_DONE_IRQ_EN BIT(13)
+#define CTRL1_CUR_FRAME_DONE_IRQ BIT(9)
+
+#define REQ_1 0
+#define REQ_2 1
+#define REQ_4 2
+#define REQ_8 3
+#define REQ_16 4
+
+#define CTRL2_OUTSTANDING_REQS(x) REG_PUT((x), 23, 21)
+#define CTRL2_ODD_LINE_PATTERN(x) REG_PUT((x), 18, 16)
+#define CTRL2_EVEN_LINE_PATTERN(x) REG_PUT((x), 14, 12)
+
+#define TRANSFER_COUNT_SET_VCOUNT(x) (((x) & 0xffff) << 16)
+#define TRANSFER_COUNT_GET_VCOUNT(x) (((x) >> 16) & 0xffff)
+#define TRANSFER_COUNT_SET_HCOUNT(x) ((x) & 0xffff)
+#define TRANSFER_COUNT_GET_HCOUNT(x) ((x) & 0xffff)
+
+#define VDCTRL0_ENABLE_PRESENT BIT(28)
+#define VDCTRL0_VSYNC_ACT_HIGH BIT(27)
+#define VDCTRL0_HSYNC_ACT_HIGH BIT(26)
+#define VDCTRL0_DOTCLK_ACT_FALLING BIT(25)
+#define VDCTRL0_ENABLE_ACT_HIGH BIT(24)
+#define VDCTRL0_VSYNC_PERIOD_UNIT BIT(21)
+#define VDCTRL0_VSYNC_PULSE_WIDTH_UNIT BIT(20)
+#define VDCTRL0_HALF_LINE BIT(19)
+#define VDCTRL0_HALF_LINE_MODE BIT(18)
+#define VDCTRL0_SET_VSYNC_PULSE_WIDTH(x) ((x) & 0x3ffff)
+#define VDCTRL0_GET_VSYNC_PULSE_WIDTH(x) ((x) & 0x3ffff)
+
+#define VDCTRL2_SET_HSYNC_PULSE_WIDTH(x) (((x) & 0x3fff) << 18)
+#define VDCTRL2_GET_HSYNC_PULSE_WIDTH(x) (((x) >> 18) & 0x3fff)
+#define VDCTRL2_SET_HSYNC_PERIOD(x) ((x) & 0x3ffff)
+#define VDCTRL2_GET_HSYNC_PERIOD(x) ((x) & 0x3ffff)
+
+#define VDCTRL3_MUX_SYNC_SIGNALS BIT(29)
+#define VDCTRL3_VSYNC_ONLY BIT(28)
+#define SET_HOR_WAIT_CNT(x) (((x) & 0xfff) << 16)
+#define GET_HOR_WAIT_CNT(x) (((x) >> 16) & 0xfff)
+#define SET_VERT_WAIT_CNT(x) ((x) & 0xffff)
+#define GET_VERT_WAIT_CNT(x) ((x) & 0xffff)
+
+#define VDCTRL4_SET_DOTCLK_DLY(x) (((x) & 0x7) << 29) /* v4 only */
+#define VDCTRL4_GET_DOTCLK_DLY(x) (((x) >> 29) & 0x7) /* v4 only */
+#define VDCTRL4_SYNC_SIGNALS_ON BIT(18)
+#define SET_DOTCLK_H_VALID_DATA_CNT(x) ((x) & 0x3ffff)
+
+#define PIGEON_12_0_SET_STATE_MASK(x) REG_PUT((x), 31, 24)
+#define PIGEON_12_0_SET_MASK_CNT(x) REG_PUT((x), 23, 12)
+#define PIGEON_12_0_SET_MASK_CNT_SEL(x) REG_PUT((x), 11, 8)
+#define PIGEON_12_0_SET_OFFSET(x) REG_PUT((x), 7, 4)
+#define PIGEON_12_0_SET_INC_SEL(x) REG_PUT((x), 3, 2)
+#define PIGEON_12_0_POL_ACTIVE_LOW BIT(1)
+#define PIGEON_12_0_EN BIT(0)
+
+#define PIGEON_12_1_SET_CLR_CNT(x) REG_PUT((x), 31, 16)
+#define PIGEON_12_1_SET_SET_CNT(x) REG_PUT((x), 15, 0)
+
+#define STMLCDIF_8BIT 1 /* pixel data bus to the display is of 8 bit width */
+#define STMLCDIF_16BIT 0 /* pixel data bus to the display is of 16 bit width */
+#define STMLCDIF_18BIT 2 /* pixel data bus to the display is of 18 bit width */
+#define STMLCDIF_24BIT 3 /* pixel data bus to the display is of 24 bit width */
+
+#define MIN_XRES 120
+#define MIN_YRES 120
+#define MAX_XRES 0xffff
+#define MAX_YRES 0xffff
+
+#endif
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index d65431417b17..da9da563347e 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -843,6 +843,15 @@ config SENSORS_MAX1668
This driver can also be built as a module. If so, the module
will be called max1668.
+config SENSORS_MAX17135
+ tristate "Maxim MAX17135 EPD temperature sensor"
+ depends on I2C
+ help
+ If you say yes here you get support for MAX17135 PMIC sensor.
+
+ This driver can also be built as a module. If so, the module
+ will be called max17135_sensor.
+
config SENSORS_MAX197
tristate "Maxim MAX197 and compatibles"
help
@@ -1545,7 +1554,7 @@ config SENSORS_ADS7871
config SENSORS_AMC6821
tristate "Texas Instruments AMC6821"
- depends on I2C
+ depends on I2C
help
If you say yes here you get support for the Texas Instruments
AMC6821 hardware monitoring chips.
@@ -1897,4 +1906,19 @@ config SENSORS_ATK0110
endif # ACPI
+config SENSORS_MAG3110
+ tristate "Freescale MAG3110 e-compass sensor"
+ depends on I2C && SYSFS
+ help
+ If you say yes here you get support for the Freescale MAG3110
+ e-compass sensor.
+ This driver can also be built as a module. If so, the module
+ will be called mag3110.
+
+config MXC_MMA8451
+ tristate "MMA8451 device driver"
+ depends on I2C
+ select INPUT_POLLDEV
+ default y
+
endif # HWMON
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
index 23e195a5a2f3..6f15184758d7 100644
--- a/drivers/hwmon/Makefile
+++ b/drivers/hwmon/Makefile
@@ -116,6 +116,7 @@ obj-$(CONFIG_SENSORS_MAX1111) += max1111.o
obj-$(CONFIG_SENSORS_MAX16065) += max16065.o
obj-$(CONFIG_SENSORS_MAX1619) += max1619.o
obj-$(CONFIG_SENSORS_MAX1668) += max1668.o
+obj-$(CONFIG_SENSORS_MAX17135) += max17135-hwmon.o
obj-$(CONFIG_SENSORS_MAX197) += max197.o
obj-$(CONFIG_SENSORS_MAX31722) += max31722.o
obj-$(CONFIG_SENSORS_MAX6639) += max6639.o
@@ -171,6 +172,8 @@ obj-$(CONFIG_SENSORS_W83L786NG) += w83l786ng.o
obj-$(CONFIG_SENSORS_WM831X) += wm831x-hwmon.o
obj-$(CONFIG_SENSORS_WM8350) += wm8350-hwmon.o
obj-$(CONFIG_SENSORS_XGENE) += xgene-hwmon.o
+obj-$(CONFIG_SENSORS_MAG3110) += mag3110.o
+obj-$(CONFIG_MXC_MMA8451) += mxc_mma8451.o
obj-$(CONFIG_PMBUS) += pmbus/
diff --git a/drivers/hwmon/mag3110.c b/drivers/hwmon/mag3110.c
new file mode 100644
index 000000000000..c38fd6e0da52
--- /dev/null
+++ b/drivers/hwmon/mag3110.c
@@ -0,0 +1,654 @@
+/*
+ *
+ * Copyright (C) 2011-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 as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/i2c.h>
+#include <linux/irq.h>
+#include <linux/platform_device.h>
+#include <linux/input-polldev.h>
+#include <linux/hwmon.h>
+#include <linux/input.h>
+#include <linux/wait.h>
+#include <linux/workqueue.h>
+#include <linux/of.h>
+#include <linux/regulator/consumer.h>
+
+#define MAG3110_DRV_NAME "mag3110"
+#define MAG3110_ID (0xC4)
+#define MAG3110_XYZ_DATA_LEN (6)
+#define MAG3110_STATUS_ZYXDR (0x08)
+#define MAG3110_AC_MASK (0x01)
+#define MAG3110_AC_OFFSET (0)
+#define MAG3110_DR_MODE_MASK (0x7 << 5)
+#define MAG3110_DR_MODE_OFFSET (5)
+
+#define POLL_INTERVAL_MAX (500)
+#define POLL_INTERVAL (100)
+#define INT_TIMEOUT (1000)
+#define DEFAULT_POSITION (2)
+
+/* register enum for mag3110 registers */
+enum {
+ MAG3110_DR_STATUS = 0x00,
+ MAG3110_OUT_X_MSB,
+ MAG3110_OUT_X_LSB,
+ MAG3110_OUT_Y_MSB,
+ MAG3110_OUT_Y_LSB,
+ MAG3110_OUT_Z_MSB,
+ MAG3110_OUT_Z_LSB,
+ MAG3110_WHO_AM_I,
+
+ MAG3110_OFF_X_MSB,
+ MAG3110_OFF_X_LSB,
+ MAG3110_OFF_Y_MSB,
+ MAG3110_OFF_Y_LSB,
+ MAG3110_OFF_Z_MSB,
+ MAG3110_OFF_Z_LSB,
+
+ MAG3110_DIE_TEMP,
+
+ MAG3110_CTRL_REG1 = 0x10,
+ MAG3110_CTRL_REG2,
+};
+
+enum {
+ MAG_STANDBY,
+ MAG_ACTIVED
+};
+
+struct mag3110_data {
+ struct i2c_client *client;
+ struct input_polled_dev *poll_dev;
+ struct device *hwmon_dev;
+ wait_queue_head_t waitq;
+ bool data_ready;
+ u8 ctl_reg1;
+ int active;
+ int position;
+ int use_irq;
+};
+
+static short MAGHAL[8][3][3] = {
+ { {0, 1, 0}, {-1, 0, 0}, {0, 0, 1} },
+ { {1, 0, 0}, {0, 1, 0}, {0, 0, 1} },
+ { {0, -1, 0}, {1, 0, 0}, {0, 0, 1} },
+ { {-1, 0, 0}, {0, -1, 0}, {0, 0, 1} },
+
+ { {0, 1, 0}, {1, 0, 0}, {0, 0, -1} },
+ { {1, 0, 0}, {0, -1, 0}, {0, 0, -1} },
+ { {0, -1, 0}, {-1, 0, 0}, {0, 0, -1} },
+ { {-1, 0, 0}, {0, 1, 0}, {0, 0, -1} },
+};
+
+static struct mag3110_data *mag3110_pdata;
+static DEFINE_MUTEX(mag3110_lock);
+
+/*
+ * This function do one mag3110 register read.
+ */
+static int mag3110_adjust_position(short *x, short *y, short *z)
+{
+ short rawdata[3], data[3];
+ int i, j;
+ int position = mag3110_pdata->position;
+ if (position < 0 || position > 7)
+ position = 0;
+ rawdata[0] = *x;
+ rawdata[1] = *y;
+ rawdata[2] = *z;
+ for (i = 0; i < 3; i++) {
+ data[i] = 0;
+ for (j = 0; j < 3; j++)
+ data[i] += rawdata[j] * MAGHAL[position][i][j];
+ }
+ *x = data[0];
+ *y = data[1];
+ *z = data[2];
+ return 0;
+}
+
+static int mag3110_read_reg(struct i2c_client *client, u8 reg)
+{
+ return i2c_smbus_read_byte_data(client, reg);
+}
+
+/*
+ * This function do one mag3110 register write.
+ */
+static int mag3110_write_reg(struct i2c_client *client, u8 reg, char value)
+{
+ int ret;
+
+ ret = i2c_smbus_write_byte_data(client, reg, value);
+ if (ret < 0)
+ dev_err(&client->dev, "i2c write failed\n");
+ return ret;
+}
+
+/*
+ * This function do multiple mag3110 registers read.
+ */
+static int mag3110_read_block_data(struct i2c_client *client, u8 reg,
+ int count, u8 *addr)
+{
+ if (i2c_smbus_read_i2c_block_data(client, reg, count, addr) < count) {
+ dev_err(&client->dev, "i2c block read failed\n");
+ return -1;
+ }
+
+ return count;
+}
+
+/*
+ * Initialization function
+ */
+static int mag3110_init_client(struct i2c_client *client)
+{
+ int val, ret;
+
+ /* enable automatic resets */
+ val = 0x80;
+ ret = mag3110_write_reg(client, MAG3110_CTRL_REG2, val);
+
+ /* set default data rate to 10HZ */
+ val = mag3110_read_reg(client, MAG3110_CTRL_REG1);
+ val |= (0x0 << MAG3110_DR_MODE_OFFSET);
+ ret = mag3110_write_reg(client, MAG3110_CTRL_REG1, val);
+
+ return ret;
+}
+
+/*
+ * read sensor data from mag3110
+ */
+static int mag3110_read_data(short *x, short *y, short *z)
+{
+ struct mag3110_data *data;
+ u8 tmp_data[MAG3110_XYZ_DATA_LEN];
+ int retry = 3;
+ int result;
+
+ if (!mag3110_pdata || mag3110_pdata->active == MAG_STANDBY)
+ return -EINVAL;
+
+ data = mag3110_pdata;
+ if (data->use_irq && !wait_event_interruptible_timeout
+ (data->waitq, data->data_ready != 0,
+ msecs_to_jiffies(INT_TIMEOUT))) {
+ dev_dbg(&data->client->dev, "interrupt not received\n");
+ return -ETIME;
+ }
+
+ do {
+ msleep(1);
+ result = i2c_smbus_read_byte_data(data->client,
+ MAG3110_DR_STATUS);
+ retry--;
+ } while (!(result & MAG3110_STATUS_ZYXDR) && retry > 0);
+ /* Clear data_ready flag after data is read out */
+ if (retry == 0)
+ return -EINVAL;
+
+ data->data_ready = 0;
+
+ while (i2c_smbus_read_byte_data(data->client, MAG3110_DR_STATUS)) {
+ if (mag3110_read_block_data(data->client,
+ MAG3110_OUT_X_MSB, MAG3110_XYZ_DATA_LEN,
+ tmp_data) < 0)
+ return -1;
+ }
+
+ *x = ((tmp_data[0] << 8) & 0xff00) | tmp_data[1];
+ *y = ((tmp_data[2] << 8) & 0xff00) | tmp_data[3];
+ *z = ((tmp_data[4] << 8) & 0xff00) | tmp_data[5];
+
+ return 0;
+}
+
+static void report_abs(void)
+{
+ struct input_dev *idev;
+ short x, y, z;
+
+ mutex_lock(&mag3110_lock);
+ if (mag3110_read_data(&x, &y, &z) != 0)
+ goto out;
+ mag3110_adjust_position(&x, &y, &z);
+ idev = mag3110_pdata->poll_dev->input;
+ input_report_abs(idev, ABS_X, x);
+ input_report_abs(idev, ABS_Y, y);
+ input_report_abs(idev, ABS_Z, z);
+ input_sync(idev);
+out:
+ mutex_unlock(&mag3110_lock);
+}
+
+static void mag3110_dev_poll(struct input_polled_dev *dev)
+{
+ report_abs();
+}
+
+static irqreturn_t mag3110_irq_handler(int irq, void *dev_id)
+{
+ int result;
+ u8 tmp_data[MAG3110_XYZ_DATA_LEN];
+ result = i2c_smbus_read_byte_data(mag3110_pdata->client,
+ MAG3110_DR_STATUS);
+ if (!(result & MAG3110_STATUS_ZYXDR))
+ return IRQ_NONE;
+
+ mag3110_pdata->data_ready = 1;
+
+ if (mag3110_pdata->active == MAG_STANDBY)
+ /*
+ * Since the mode will be changed, sometimes irq will
+ * be handled in StandBy mode because of interrupt latency.
+ * So just clear the interrutp flag via reading block data.
+ */
+ mag3110_read_block_data(mag3110_pdata->client,
+ MAG3110_OUT_X_MSB,
+ MAG3110_XYZ_DATA_LEN, tmp_data);
+ else
+ wake_up_interruptible(&mag3110_pdata->waitq);
+
+ return IRQ_HANDLED;
+}
+
+static ssize_t mag3110_enable_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct i2c_client *client;
+ int val;
+ mutex_lock(&mag3110_lock);
+ client = mag3110_pdata->client;
+ val = mag3110_read_reg(client, MAG3110_CTRL_REG1) & MAG3110_AC_MASK;
+
+ mutex_unlock(&mag3110_lock);
+ return sprintf(buf, "%d\n", val);
+}
+
+static ssize_t mag3110_enable_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct i2c_client *client;
+ int reg, ret;
+ long enable;
+ u8 tmp_data[MAG3110_XYZ_DATA_LEN];
+
+ ret = kstrtol(buf, 10, &enable);
+ if (ret) {
+ dev_err(dev, "string to long error\n");
+ return ret;
+ }
+
+ mutex_lock(&mag3110_lock);
+ client = mag3110_pdata->client;
+
+ reg = mag3110_read_reg(client, MAG3110_CTRL_REG1);
+ if (enable && mag3110_pdata->active == MAG_STANDBY) {
+ reg |= MAG3110_AC_MASK;
+ ret = mag3110_write_reg(client, MAG3110_CTRL_REG1, reg);
+ if (!ret)
+ mag3110_pdata->active = MAG_ACTIVED;
+ } else if (!enable && mag3110_pdata->active == MAG_ACTIVED) {
+ reg &= ~MAG3110_AC_MASK;
+ ret = mag3110_write_reg(client, MAG3110_CTRL_REG1, reg);
+ if (!ret)
+ mag3110_pdata->active = MAG_STANDBY;
+ }
+
+ /* Read out MSB data to clear interrupt flag */
+ msleep(100);
+ mag3110_read_block_data(mag3110_pdata->client, MAG3110_OUT_X_MSB,
+ MAG3110_XYZ_DATA_LEN, tmp_data);
+ mutex_unlock(&mag3110_lock);
+ return count;
+}
+
+static DEVICE_ATTR(enable, S_IWUSR | S_IRUGO,
+ mag3110_enable_show, mag3110_enable_store);
+
+static ssize_t mag3110_dr_mode_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct i2c_client *client;
+ int val;
+
+ client = mag3110_pdata->client;
+ val = (mag3110_read_reg(client, MAG3110_CTRL_REG1)
+ & MAG3110_DR_MODE_MASK) >> MAG3110_DR_MODE_OFFSET;
+
+ return sprintf(buf, "%d\n", val);
+}
+
+static ssize_t mag3110_dr_mode_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct i2c_client *client;
+ int reg, ret;
+ unsigned long val;
+
+ /* This must be done when mag3110 is disabled */
+ if ((kstrtoul(buf, 10, &val) < 0) || (val > 7))
+ return -EINVAL;
+
+ client = mag3110_pdata->client;
+ reg = mag3110_read_reg(client, MAG3110_CTRL_REG1) &
+ ~MAG3110_DR_MODE_MASK;
+ reg |= (val << MAG3110_DR_MODE_OFFSET);
+ /* MAG3110_CTRL_REG1 bit 5-7: data rate mode */
+ ret = mag3110_write_reg(client, MAG3110_CTRL_REG1, reg);
+ if (ret < 0)
+ return ret;
+
+ return count;
+}
+
+static DEVICE_ATTR(dr_mode, S_IWUSR | S_IRUGO,
+ mag3110_dr_mode_show, mag3110_dr_mode_store);
+
+static ssize_t mag3110_position_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int val;
+ mutex_lock(&mag3110_lock);
+ val = mag3110_pdata->position;
+ mutex_unlock(&mag3110_lock);
+ return sprintf(buf, "%d\n", val);
+}
+
+static ssize_t mag3110_position_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ long position;
+ int ret;
+ ret = kstrtol(buf, 10, &position);
+ if (ret) {
+ dev_err(dev, "string to long error\n");
+ return ret;
+ }
+
+ mutex_lock(&mag3110_lock);
+ mag3110_pdata->position = (int)position;
+ mutex_unlock(&mag3110_lock);
+ return count;
+}
+
+static DEVICE_ATTR(position, S_IWUSR | S_IRUGO,
+ mag3110_position_show, mag3110_position_store);
+
+static struct attribute *mag3110_attributes[] = {
+ &dev_attr_enable.attr,
+ &dev_attr_dr_mode.attr,
+ &dev_attr_position.attr,
+ NULL
+};
+
+static const struct attribute_group mag3110_attr_group = {
+ .attrs = mag3110_attributes,
+};
+
+static int mag3110_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct i2c_adapter *adapter;
+ struct input_dev *idev = NULL;
+ struct mag3110_data *data;
+ int ret = 0;
+ struct regulator *vdd, *vdd_io;
+ u32 pos = 0;
+ struct device_node *of_node = client->dev.of_node;
+ u32 irq_flag;
+ struct irq_data *irq_data = NULL;
+ bool shared_irq = of_property_read_bool(of_node, "shared-interrupt");
+
+ vdd = NULL;
+ vdd_io = NULL;
+
+ vdd = devm_regulator_get(&client->dev, "vdd");
+ if (!IS_ERR(vdd)) {
+ ret = regulator_enable(vdd);
+ if (ret) {
+ dev_err(&client->dev, "vdd set voltage error\n");
+ return ret;
+ }
+ }
+
+ vdd_io = devm_regulator_get(&client->dev, "vddio");
+ if (!IS_ERR(vdd_io)) {
+ ret = regulator_enable(vdd_io);
+ if (ret) {
+ dev_err(&client->dev, "vddio set voltage error\n");
+ return ret;
+ }
+ }
+
+ adapter = to_i2c_adapter(client->dev.parent);
+ if (!i2c_check_functionality(adapter,
+ I2C_FUNC_SMBUS_BYTE |
+ I2C_FUNC_SMBUS_BYTE_DATA |
+ I2C_FUNC_SMBUS_I2C_BLOCK))
+ return -EIO;
+
+ dev_info(&client->dev, "check mag3110 chip ID\n");
+ ret = mag3110_read_reg(client, MAG3110_WHO_AM_I);
+
+ if (MAG3110_ID != ret) {
+ dev_err(&client->dev,
+ "read chip ID 0x%x is not equal to 0x%x!\n", ret,
+ MAG3110_ID);
+ return -EINVAL;
+ }
+ data = kzalloc(sizeof(struct mag3110_data), GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
+ data->client = client;
+ i2c_set_clientdata(client, data);
+ /* Init queue */
+ init_waitqueue_head(&data->waitq);
+
+ data->hwmon_dev = hwmon_device_register(&client->dev);
+ if (IS_ERR(data->hwmon_dev)) {
+ dev_err(&client->dev, "hwmon register failed!\n");
+ ret = PTR_ERR(data->hwmon_dev);
+ goto error_rm_dev_sysfs;
+ }
+
+ if (client->irq > 0) {
+ data->use_irq = 1;
+ irq_data = irq_get_irq_data(client->irq);
+ }
+
+ /*input poll device register */
+ data->poll_dev = input_allocate_polled_device();
+ if (!data->poll_dev) {
+ dev_err(&client->dev, "alloc poll device failed!\n");
+ ret = -ENOMEM;
+ goto error_rm_hwmon_dev;
+ }
+ data->poll_dev->poll = mag3110_dev_poll;
+ data->poll_dev->poll_interval = POLL_INTERVAL;
+ data->poll_dev->poll_interval_max = POLL_INTERVAL_MAX;
+ idev = data->poll_dev->input;
+ idev->name = MAG3110_DRV_NAME;
+ idev->id.bustype = BUS_I2C;
+ idev->evbit[0] = BIT_MASK(EV_ABS);
+ input_set_abs_params(idev, ABS_X, -15000, 15000, 0, 0);
+ input_set_abs_params(idev, ABS_Y, -15000, 15000, 0, 0);
+ input_set_abs_params(idev, ABS_Z, -15000, 15000, 0, 0);
+ ret = input_register_polled_device(data->poll_dev);
+ if (ret) {
+ dev_err(&client->dev, "register poll device failed!\n");
+ goto error_free_poll_dev;
+ }
+
+ /*create device group in sysfs as user interface */
+ ret = sysfs_create_group(&idev->dev.kobj, &mag3110_attr_group);
+ if (ret) {
+ dev_err(&client->dev, "create device file failed!\n");
+ ret = -EINVAL;
+ goto error_rm_poll_dev;
+ }
+
+ if (data->use_irq) {
+ irq_flag = irqd_get_trigger_type(irq_data);
+ irq_flag |= IRQF_ONESHOT;
+ if (shared_irq)
+ irq_flag |= IRQF_SHARED;
+ ret = request_threaded_irq(client->irq, NULL, mag3110_irq_handler,
+ irq_flag, client->dev.driver->name, idev);
+ if (ret < 0) {
+ dev_err(&client->dev, "failed to register irq %d!\n",
+ client->irq);
+ goto error_rm_dev_sysfs;
+ }
+ }
+
+ /* Initialize mag3110 chip */
+ mag3110_init_client(client);
+ mag3110_pdata = data;
+ mag3110_pdata->active = MAG_STANDBY;
+ ret = of_property_read_u32(of_node, "position", &pos);
+ if (ret)
+ pos = DEFAULT_POSITION;
+ mag3110_pdata->position = (int)pos;
+ dev_info(&client->dev, "mag3110 is probed\n");
+ return 0;
+error_rm_dev_sysfs:
+ sysfs_remove_group(&client->dev.kobj, &mag3110_attr_group);
+error_rm_poll_dev:
+ input_unregister_polled_device(data->poll_dev);
+error_free_poll_dev:
+ input_free_polled_device(data->poll_dev);
+error_rm_hwmon_dev:
+ hwmon_device_unregister(data->hwmon_dev);
+
+ kfree(data);
+ mag3110_pdata = NULL;
+
+ return ret;
+}
+
+static int mag3110_remove(struct i2c_client *client)
+{
+ struct mag3110_data *data;
+ int ret;
+
+ data = i2c_get_clientdata(client);
+
+ data->ctl_reg1 = mag3110_read_reg(client, MAG3110_CTRL_REG1);
+ ret = mag3110_write_reg(client, MAG3110_CTRL_REG1,
+ data->ctl_reg1 & ~MAG3110_AC_MASK);
+
+ free_irq(client->irq, data);
+ input_unregister_polled_device(data->poll_dev);
+ input_free_polled_device(data->poll_dev);
+ hwmon_device_unregister(data->hwmon_dev);
+ sysfs_remove_group(&client->dev.kobj, &mag3110_attr_group);
+ kfree(data);
+ mag3110_pdata = NULL;
+
+ return ret;
+}
+
+#ifdef CONFIG_PM
+static int mag3110_suspend(struct device *dev)
+{
+ int ret = 0;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct mag3110_data *data = i2c_get_clientdata(client);
+
+ if (data->active == MAG_ACTIVED) {
+ data->ctl_reg1 = mag3110_read_reg(client, MAG3110_CTRL_REG1);
+ ret = mag3110_write_reg(client, MAG3110_CTRL_REG1,
+ data->ctl_reg1 & ~MAG3110_AC_MASK);
+ }
+ return ret;
+}
+
+static int mag3110_resume(struct device *dev)
+{
+ int ret = 0;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct mag3110_data *data = i2c_get_clientdata(client);
+ u8 tmp_data[MAG3110_XYZ_DATA_LEN];
+
+ if (data->active == MAG_ACTIVED) {
+ ret = mag3110_write_reg(client, MAG3110_CTRL_REG1,
+ data->ctl_reg1);
+
+ if (data->ctl_reg1 & MAG3110_AC_MASK) {
+ /* Read out MSB data to clear interrupt
+ flag automatically */
+ mag3110_read_block_data(client, MAG3110_OUT_X_MSB,
+ MAG3110_XYZ_DATA_LEN, tmp_data);
+ }
+ }
+ return ret;
+}
+
+static const struct dev_pm_ops mag3110_dev_pm_ops = {
+ .suspend = mag3110_suspend,
+ .resume = mag3110_resume,
+};
+#define MAG3110_DEV_PM_OPS (&mag3110_dev_pm_ops)
+
+#else
+#define MAG3110_DEV_PM_OPS NULL
+#endif /* CONFIG_PM */
+
+static const struct i2c_device_id mag3110_id[] = {
+ {MAG3110_DRV_NAME, 0},
+ {}
+};
+
+MODULE_DEVICE_TABLE(i2c, mag3110_id);
+static struct i2c_driver mag3110_driver = {
+ .driver = {
+ .name = MAG3110_DRV_NAME,
+ .owner = THIS_MODULE,
+ .pm = MAG3110_DEV_PM_OPS,
+ },
+ .probe = mag3110_probe,
+ .remove = mag3110_remove,
+ .id_table = mag3110_id,
+};
+
+static int __init mag3110_init(void)
+{
+ return i2c_add_driver(&mag3110_driver);
+}
+
+static void __exit mag3110_exit(void)
+{
+ i2c_del_driver(&mag3110_driver);
+}
+
+module_init(mag3110_init);
+module_exit(mag3110_exit);
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("Freescale mag3110 3-axis magnetometer driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/hwmon/max17135-hwmon.c b/drivers/hwmon/max17135-hwmon.c
new file mode 100644
index 000000000000..c8ddb252a616
--- /dev/null
+++ b/drivers/hwmon/max17135-hwmon.c
@@ -0,0 +1,176 @@
+/*
+ * Copyright (C) 2010-2015 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.
+ *
+ * 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
+ *
+ */
+/*
+ * max17135.c
+ *
+ * Based on the MAX1619 driver.
+ * Copyright (C) 2003-2004 Alexey Fisher <fishor@mail.ru>
+ * Jean Delvare <khali@linux-fr.org>
+ *
+ * The MAX17135 is a sensor chip made by Maxim.
+ * It reports up to two temperatures (its own plus up to
+ * one external one).
+ */
+
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/jiffies.h>
+#include <linux/hwmon.h>
+#include <linux/hwmon-sysfs.h>
+#include <linux/err.h>
+#include <linux/sysfs.h>
+#include <linux/platform_device.h>
+#include <linux/mfd/max17135.h>
+
+/*
+ * Conversions
+ */
+static int temp_from_reg(int val)
+{
+ return val >> 8;
+}
+
+/*
+ * Functions declaration
+ */
+static int max17135_sensor_probe(struct platform_device *pdev);
+static int max17135_sensor_remove(struct platform_device *pdev);
+
+static const struct platform_device_id max17135_sns_id[] = {
+ { "max17135-sns", 0},
+ { /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(platform, max17135_sns_id);
+
+/*
+ * Driver data (common to all clients)
+ */
+static struct platform_driver max17135_sensor_driver = {
+ .probe = max17135_sensor_probe,
+ .remove = max17135_sensor_remove,
+ .id_table = max17135_sns_id,
+ .driver = {
+ .name = "max17135_sensor",
+ },
+};
+
+/*
+ * Client data (each client gets its own)
+ */
+struct max17135_data {
+ struct device *hwmon_dev;
+};
+
+/*
+ * Sysfs stuff
+ */
+static ssize_t show_temp_input1(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ unsigned int reg_val;
+ max17135_reg_read(REG_MAX17135_INT_TEMP, &reg_val);
+ return snprintf(buf, PAGE_SIZE, "%d\n", temp_from_reg(reg_val));
+}
+
+static ssize_t show_temp_input2(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ unsigned int reg_val;
+ max17135_reg_read(REG_MAX17135_EXT_TEMP, &reg_val);
+ return snprintf(buf, PAGE_SIZE, "%d\n", temp_from_reg(reg_val));
+}
+
+static DEVICE_ATTR(temp1_input, S_IRUGO, show_temp_input1, NULL);
+static DEVICE_ATTR(temp2_input, S_IRUGO, show_temp_input2, NULL);
+
+static struct attribute *max17135_attributes[] = {
+ &dev_attr_temp1_input.attr,
+ &dev_attr_temp2_input.attr,
+ NULL
+};
+
+static const struct attribute_group max17135_group = {
+ .attrs = max17135_attributes,
+};
+
+/*
+ * Real code
+ */
+static int max17135_sensor_probe(struct platform_device *pdev)
+{
+ struct max17135_data *data;
+ int err;
+
+ data = kzalloc(sizeof(struct max17135_data), GFP_KERNEL);
+ if (!data) {
+ err = -ENOMEM;
+ goto exit;
+ }
+
+ /* Register sysfs hooks */
+ err = sysfs_create_group(&pdev->dev.kobj, &max17135_group);
+ if (err)
+ goto exit_free;
+
+ data->hwmon_dev = hwmon_device_register(&pdev->dev);
+ if (IS_ERR(data->hwmon_dev)) {
+ err = PTR_ERR(data->hwmon_dev);
+ goto exit_remove_files;
+ }
+
+ platform_set_drvdata(pdev, data);
+
+ return 0;
+
+exit_remove_files:
+ sysfs_remove_group(&pdev->dev.kobj, &max17135_group);
+exit_free:
+ kfree(data);
+exit:
+ return err;
+}
+
+static int max17135_sensor_remove(struct platform_device *pdev)
+{
+ struct max17135_data *data = platform_get_drvdata(pdev);
+
+ hwmon_device_unregister(data->hwmon_dev);
+ sysfs_remove_group(&pdev->dev.kobj, &max17135_group);
+
+ kfree(data);
+ return 0;
+}
+
+static int __init sensors_max17135_init(void)
+{
+ return platform_driver_register(&max17135_sensor_driver);
+}
+module_init(sensors_max17135_init);
+
+static void __exit sensors_max17135_exit(void)
+{
+ platform_driver_unregister(&max17135_sensor_driver);
+}
+module_exit(sensors_max17135_exit);
+
+MODULE_DESCRIPTION("MAX17135 sensor driver");
+MODULE_LICENSE("GPL");
+
diff --git a/drivers/hwmon/mxc_mma8451.c b/drivers/hwmon/mxc_mma8451.c
new file mode 100644
index 000000000000..9d6c53927757
--- /dev/null
+++ b/drivers/hwmon/mxc_mma8451.c
@@ -0,0 +1,599 @@
+/*
+ * mma8451.c - Linux kernel modules for 3-Axis Orientation/Motion
+ * Detection Sensor
+ *
+ * Copyright (C) 2010-2014 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/pm.h>
+#include <linux/mutex.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/hwmon-sysfs.h>
+#include <linux/err.h>
+#include <linux/hwmon.h>
+#include <linux/input-polldev.h>
+#include <linux/of.h>
+#include <linux/regulator/consumer.h>
+
+#define MMA8451_I2C_ADDR 0x1C
+#define MMA8451_ID 0x1A
+#define MMA8452_ID 0x2A
+#define MMA8453_ID 0x3A
+
+#define POLL_INTERVAL_MIN 1
+#define POLL_INTERVAL_MAX 500
+#define POLL_INTERVAL 100 /* msecs */
+#define INPUT_FUZZ 32
+#define INPUT_FLAT 32
+#define MODE_CHANGE_DELAY_MS 100
+
+#define MMA8451_STATUS_ZYXDR 0x08
+#define MMA8451_BUF_SIZE 7
+#define DEFAULT_POSITION 0
+
+/* register enum for mma8451 registers */
+enum {
+ MMA8451_STATUS = 0x00,
+ MMA8451_OUT_X_MSB,
+ MMA8451_OUT_X_LSB,
+ MMA8451_OUT_Y_MSB,
+ MMA8451_OUT_Y_LSB,
+ MMA8451_OUT_Z_MSB,
+ MMA8451_OUT_Z_LSB,
+
+ MMA8451_F_SETUP = 0x09,
+ MMA8451_TRIG_CFG,
+ MMA8451_SYSMOD,
+ MMA8451_INT_SOURCE,
+ MMA8451_WHO_AM_I,
+ MMA8451_XYZ_DATA_CFG,
+ MMA8451_HP_FILTER_CUTOFF,
+
+ MMA8451_PL_STATUS,
+ MMA8451_PL_CFG,
+ MMA8451_PL_COUNT,
+ MMA8451_PL_BF_ZCOMP,
+ MMA8451_P_L_THS_REG,
+
+ MMA8451_FF_MT_CFG,
+ MMA8451_FF_MT_SRC,
+ MMA8451_FF_MT_THS,
+ MMA8451_FF_MT_COUNT,
+
+ MMA8451_TRANSIENT_CFG = 0x1D,
+ MMA8451_TRANSIENT_SRC,
+ MMA8451_TRANSIENT_THS,
+ MMA8451_TRANSIENT_COUNT,
+
+ MMA8451_PULSE_CFG,
+ MMA8451_PULSE_SRC,
+ MMA8451_PULSE_THSX,
+ MMA8451_PULSE_THSY,
+ MMA8451_PULSE_THSZ,
+ MMA8451_PULSE_TMLT,
+ MMA8451_PULSE_LTCY,
+ MMA8451_PULSE_WIND,
+
+ MMA8451_ASLP_COUNT,
+ MMA8451_CTRL_REG1,
+ MMA8451_CTRL_REG2,
+ MMA8451_CTRL_REG3,
+ MMA8451_CTRL_REG4,
+ MMA8451_CTRL_REG5,
+
+ MMA8451_OFF_X,
+ MMA8451_OFF_Y,
+ MMA8451_OFF_Z,
+
+ MMA8451_REG_END,
+};
+
+/* The sensitivity is represented in counts/g. In 2g mode the
+sensitivity is 1024 counts/g. In 4g mode the sensitivity is 512
+counts/g and in 8g mode the sensitivity is 256 counts/g.
+ */
+enum {
+ MODE_2G = 0,
+ MODE_4G,
+ MODE_8G,
+};
+
+enum {
+ MMA_STANDBY = 0,
+ MMA_ACTIVED,
+};
+
+/* mma8451 status */
+struct mma8451_status {
+ u8 mode;
+ u8 ctl_reg1;
+ int active;
+ int position;
+};
+
+static struct mma8451_status mma_status;
+static struct input_polled_dev *mma8451_idev;
+static struct device *hwmon_dev;
+static struct i2c_client *mma8451_i2c_client;
+
+static int senstive_mode = MODE_2G;
+static int ACCHAL[8][3][3] = {
+ { {0, -1, 0}, {1, 0, 0}, {0, 0, 1} },
+ { {-1, 0, 0}, {0, -1, 0}, {0, 0, 1} },
+ { {0, 1, 0}, {-1, 0, 0}, {0, 0, 1} },
+ { {1, 0, 0}, {0, 1, 0}, {0, 0, 1} },
+
+ { {0, -1, 0}, {-1, 0, 0}, {0, 0, -1} },
+ { {-1, 0, 0}, {0, 1, 0}, {0, 0, -1} },
+ { {0, 1, 0}, {1, 0, 0}, {0, 0, -1} },
+ { {1, 0, 0}, {0, -1, 0}, {0, 0, -1} },
+};
+
+static DEFINE_MUTEX(mma8451_lock);
+static int mma8451_adjust_position(short *x, short *y, short *z)
+{
+ short rawdata[3], data[3];
+ int i, j;
+ int position = mma_status.position;
+ if (position < 0 || position > 7)
+ position = 0;
+ rawdata[0] = *x;
+ rawdata[1] = *y;
+ rawdata[2] = *z;
+ for (i = 0; i < 3; i++) {
+ data[i] = 0;
+ for (j = 0; j < 3; j++)
+ data[i] += rawdata[j] * ACCHAL[position][i][j];
+ }
+ *x = data[0];
+ *y = data[1];
+ *z = data[2];
+ return 0;
+}
+
+static int mma8451_change_mode(struct i2c_client *client, int mode)
+{
+ int result;
+
+ mma_status.ctl_reg1 = 0;
+ result = i2c_smbus_write_byte_data(client, MMA8451_CTRL_REG1, 0);
+ if (result < 0)
+ goto out;
+ mma_status.active = MMA_STANDBY;
+
+ result = i2c_smbus_write_byte_data(client, MMA8451_XYZ_DATA_CFG,
+ mode);
+ if (result < 0)
+ goto out;
+ mdelay(MODE_CHANGE_DELAY_MS);
+ mma_status.mode = mode;
+
+ return 0;
+out:
+ dev_err(&client->dev, "error when init mma8451:(%d)", result);
+ return result;
+}
+
+static int mma8451_read_data(short *x, short *y, short *z)
+{
+ u8 tmp_data[MMA8451_BUF_SIZE];
+ int ret;
+
+ ret = i2c_smbus_read_i2c_block_data(mma8451_i2c_client,
+ MMA8451_OUT_X_MSB, 7, tmp_data);
+ if (ret < MMA8451_BUF_SIZE) {
+ dev_err(&mma8451_i2c_client->dev, "i2c block read failed\n");
+ return -EIO;
+ }
+
+ *x = ((tmp_data[0] << 8) & 0xff00) | tmp_data[1];
+ *y = ((tmp_data[2] << 8) & 0xff00) | tmp_data[3];
+ *z = ((tmp_data[4] << 8) & 0xff00) | tmp_data[5];
+ return 0;
+}
+
+static void report_abs(void)
+{
+ short x, y, z;
+ int result;
+ int retry = 3;
+
+ mutex_lock(&mma8451_lock);
+ if (mma_status.active == MMA_STANDBY)
+ goto out;
+ /* wait for the data ready */
+ do {
+ result = i2c_smbus_read_byte_data(mma8451_i2c_client,
+ MMA8451_STATUS);
+ retry--;
+ msleep(1);
+ } while (!(result & MMA8451_STATUS_ZYXDR) && retry > 0);
+ if (retry == 0)
+ goto out;
+ if (mma8451_read_data(&x, &y, &z) != 0)
+ goto out;
+ mma8451_adjust_position(&x, &y, &z);
+ input_report_abs(mma8451_idev->input, ABS_X, x);
+ input_report_abs(mma8451_idev->input, ABS_Y, y);
+ input_report_abs(mma8451_idev->input, ABS_Z, z);
+ input_sync(mma8451_idev->input);
+out:
+ mutex_unlock(&mma8451_lock);
+}
+
+static void mma8451_dev_poll(struct input_polled_dev *dev)
+{
+ report_abs();
+}
+
+static ssize_t mma8451_enable_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct i2c_client *client;
+ u8 val;
+ int enable;
+
+ mutex_lock(&mma8451_lock);
+ client = mma8451_i2c_client;
+ val = i2c_smbus_read_byte_data(client, MMA8451_CTRL_REG1);
+ if ((val & 0x01) && mma_status.active == MMA_ACTIVED)
+ enable = 1;
+ else
+ enable = 0;
+ mutex_unlock(&mma8451_lock);
+ return sprintf(buf, "%d\n", enable);
+}
+
+static ssize_t mma8451_enable_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct i2c_client *client;
+ int ret;
+ unsigned long enable;
+ u8 val = 0;
+
+ ret = kstrtoul(buf, 10, &enable);
+ if (ret) {
+ dev_err(dev, "string transform error\n");
+ return ret;
+ }
+
+ mutex_lock(&mma8451_lock);
+ client = mma8451_i2c_client;
+ enable = (enable > 0) ? 1 : 0;
+ if (enable && mma_status.active == MMA_STANDBY) {
+ val = i2c_smbus_read_byte_data(client, MMA8451_CTRL_REG1);
+ ret =
+ i2c_smbus_write_byte_data(client, MMA8451_CTRL_REG1,
+ val | 0x01);
+ if (!ret)
+ mma_status.active = MMA_ACTIVED;
+
+ } else if (enable == 0 && mma_status.active == MMA_ACTIVED) {
+ val = i2c_smbus_read_byte_data(client, MMA8451_CTRL_REG1);
+ ret =
+ i2c_smbus_write_byte_data(client, MMA8451_CTRL_REG1,
+ val & 0xFE);
+ if (!ret)
+ mma_status.active = MMA_STANDBY;
+
+ }
+ mutex_unlock(&mma8451_lock);
+ return count;
+}
+
+static ssize_t mma8451_position_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int position = 0;
+ mutex_lock(&mma8451_lock);
+ position = mma_status.position;
+ mutex_unlock(&mma8451_lock);
+ return sprintf(buf, "%d\n", position);
+}
+
+static ssize_t mma8451_position_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned long position;
+ int ret;
+ ret = kstrtoul(buf, 10, &position);
+ if (ret) {
+ dev_err(dev, "string transform error\n");
+ return ret;
+ }
+
+ mutex_lock(&mma8451_lock);
+ mma_status.position = (int)position;
+ mutex_unlock(&mma8451_lock);
+ return count;
+}
+
+static ssize_t mma8451_scalemode_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ int mode = 0;
+ mutex_lock(&mma8451_lock);
+ mode = (int)mma_status.mode;
+ mutex_unlock(&mma8451_lock);
+
+ return sprintf(buf, "%d\n", mode);
+}
+
+static ssize_t mma8451_scalemode_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned long mode;
+ int ret, active_save;
+ struct i2c_client *client = mma8451_i2c_client;
+
+ ret = kstrtoul(buf, 10, &mode);
+ if (ret) {
+ dev_err(dev, "string transform error\n");
+ goto out;
+ }
+
+ if (mode > MODE_8G) {
+ dev_warn(dev, "not supported mode\n");
+ ret = count;
+ goto out;
+ }
+
+ mutex_lock(&mma8451_lock);
+ if (mode == mma_status.mode) {
+ ret = count;
+ goto out_unlock;
+ }
+
+ active_save = mma_status.active;
+ ret = mma8451_change_mode(client, mode);
+ if (ret)
+ goto out_unlock;
+
+ if (active_save == MMA_ACTIVED) {
+ ret = i2c_smbus_write_byte_data(client, MMA8451_CTRL_REG1, 1);
+
+ if (ret)
+ goto out_unlock;
+ mma_status.active = active_save;
+ }
+
+out_unlock:
+ mutex_unlock(&mma8451_lock);
+out:
+ return ret;
+}
+
+static DEVICE_ATTR(enable, S_IWUSR | S_IRUGO,
+ mma8451_enable_show, mma8451_enable_store);
+static DEVICE_ATTR(position, S_IWUSR | S_IRUGO,
+ mma8451_position_show, mma8451_position_store);
+static DEVICE_ATTR(scalemode, S_IWUSR | S_IRUGO,
+ mma8451_scalemode_show, mma8451_scalemode_store);
+
+static struct attribute *mma8451_attributes[] = {
+ &dev_attr_enable.attr,
+ &dev_attr_position.attr,
+ &dev_attr_scalemode.attr,
+ NULL
+};
+
+static const struct attribute_group mma8451_attr_group = {
+ .attrs = mma8451_attributes,
+};
+
+static int mma8451_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ int result, client_id;
+ struct input_dev *idev;
+ struct i2c_adapter *adapter;
+ u32 pos;
+ struct device_node *of_node = client->dev.of_node;
+ struct regulator *vdd, *vdd_io;
+
+ mma8451_i2c_client = client;
+
+ vdd = devm_regulator_get(&client->dev, "vdd");
+ if (!IS_ERR(vdd)) {
+ result = regulator_enable(vdd);
+ if (result) {
+ dev_err(&client->dev, "vdd set voltage error\n");
+ return result;
+ }
+ }
+
+ vdd_io = devm_regulator_get(&client->dev, "vddio");
+ if (!IS_ERR(vdd_io)) {
+ result = regulator_enable(vdd_io);
+ if (result) {
+ dev_err(&client->dev, "vddio set voltage error\n");
+ return result;
+ }
+ }
+
+ adapter = to_i2c_adapter(client->dev.parent);
+ result = i2c_check_functionality(adapter,
+ I2C_FUNC_SMBUS_BYTE |
+ I2C_FUNC_SMBUS_BYTE_DATA);
+ if (!result)
+ goto err_out;
+
+ client_id = i2c_smbus_read_byte_data(client, MMA8451_WHO_AM_I);
+ if (client_id != MMA8451_ID && client_id != MMA8452_ID
+ && client_id != MMA8453_ID) {
+ dev_err(&client->dev,
+ "read chip ID 0x%x is not equal to 0x%x or 0x%x!\n",
+ result, MMA8451_ID, MMA8452_ID);
+ result = -EINVAL;
+ goto err_out;
+ }
+
+ /* Initialize the MMA8451 chip */
+ result = mma8451_change_mode(client, senstive_mode);
+ if (result) {
+ dev_err(&client->dev,
+ "error when init mma8451 chip:(%d)\n", result);
+ goto err_out;
+ }
+
+ hwmon_dev = hwmon_device_register(&client->dev);
+ if (!hwmon_dev) {
+ result = -ENOMEM;
+ dev_err(&client->dev, "error when register hwmon device\n");
+ goto err_out;
+ }
+
+ mma8451_idev = input_allocate_polled_device();
+ if (!mma8451_idev) {
+ result = -ENOMEM;
+ dev_err(&client->dev, "alloc poll device failed!\n");
+ goto err_alloc_poll_device;
+ }
+ mma8451_idev->poll = mma8451_dev_poll;
+ mma8451_idev->poll_interval = POLL_INTERVAL;
+ mma8451_idev->poll_interval_min = POLL_INTERVAL_MIN;
+ mma8451_idev->poll_interval_max = POLL_INTERVAL_MAX;
+ idev = mma8451_idev->input;
+ idev->name = "mma845x";
+ idev->id.bustype = BUS_I2C;
+ idev->evbit[0] = BIT_MASK(EV_ABS);
+
+ input_set_abs_params(idev, ABS_X, -8192, 8191, INPUT_FUZZ, INPUT_FLAT);
+ input_set_abs_params(idev, ABS_Y, -8192, 8191, INPUT_FUZZ, INPUT_FLAT);
+ input_set_abs_params(idev, ABS_Z, -8192, 8191, INPUT_FUZZ, INPUT_FLAT);
+
+ result = input_register_polled_device(mma8451_idev);
+ if (result) {
+ dev_err(&client->dev, "register poll device failed!\n");
+ goto err_register_polled_device;
+ }
+ result = sysfs_create_group(&idev->dev.kobj, &mma8451_attr_group);
+ if (result) {
+ dev_err(&client->dev, "create device file failed!\n");
+ result = -EINVAL;
+ goto err_register_polled_device;
+ }
+
+ result = of_property_read_u32(of_node, "position", &pos);
+ if (result)
+ pos = DEFAULT_POSITION;
+ mma_status.position = (int)pos;
+
+ return 0;
+err_register_polled_device:
+ input_free_polled_device(mma8451_idev);
+err_alloc_poll_device:
+ hwmon_device_unregister(&client->dev);
+err_out:
+ return result;
+}
+
+static int mma8451_stop_chip(struct i2c_client *client)
+{
+ int ret = 0;
+ if (mma_status.active == MMA_ACTIVED) {
+ mma_status.ctl_reg1 = i2c_smbus_read_byte_data(client,
+ MMA8451_CTRL_REG1);
+ ret = i2c_smbus_write_byte_data(client, MMA8451_CTRL_REG1,
+ mma_status.ctl_reg1 & 0xFE);
+ }
+ return ret;
+}
+
+static int mma8451_remove(struct i2c_client *client)
+{
+ int ret;
+ ret = mma8451_stop_chip(client);
+ hwmon_device_unregister(hwmon_dev);
+
+ return ret;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int mma8451_suspend(struct device *dev)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+
+ return mma8451_stop_chip(client);
+}
+
+static int mma8451_resume(struct device *dev)
+{
+ int ret = 0;
+ struct i2c_client *client = to_i2c_client(dev);
+ if (mma_status.active == MMA_ACTIVED)
+ ret = i2c_smbus_write_byte_data(client, MMA8451_CTRL_REG1,
+ mma_status.ctl_reg1);
+ return ret;
+
+}
+#endif
+
+static const struct i2c_device_id mma8451_id[] = {
+ {"mma8451", 0},
+ { /* sentinel */ }
+};
+
+MODULE_DEVICE_TABLE(i2c, mma8451_id);
+
+static SIMPLE_DEV_PM_OPS(mma8451_pm_ops, mma8451_suspend, mma8451_resume);
+static struct i2c_driver mma8451_driver = {
+ .driver = {
+ .name = "mma8451",
+ .owner = THIS_MODULE,
+ .pm = &mma8451_pm_ops,
+ },
+ .probe = mma8451_probe,
+ .remove = mma8451_remove,
+ .id_table = mma8451_id,
+};
+
+static int __init mma8451_init(void)
+{
+ /* register driver */
+ int res;
+
+ res = i2c_add_driver(&mma8451_driver);
+ if (res < 0) {
+ printk(KERN_INFO "add mma8451 i2c driver failed\n");
+ return -ENODEV;
+ }
+ return res;
+}
+
+static void __exit mma8451_exit(void)
+{
+ i2c_del_driver(&mma8451_driver);
+}
+
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("MMA8451 3-Axis Orientation/Motion Detection Sensor driver");
+MODULE_LICENSE("GPL");
+
+module_init(mma8451_init);
+module_exit(mma8451_exit);
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
index b72a25585d52..ed9781111956 100644
--- a/drivers/i2c/busses/Kconfig
+++ b/drivers/i2c/busses/Kconfig
@@ -633,7 +633,7 @@ config I2C_IMG
config I2C_IMX
tristate "IMX I2C interface"
- depends on ARCH_MXC || ARCH_LAYERSCAPE || COLDFIRE
+ depends on ARCH_MXC || ARCH_LAYERSCAPE || COLDFIRE || ARCH_MXC_ARM64
help
Say Y here if you want to use the IIC bus controller on
the Freescale i.MX/MXC, Layerscape or ColdFire processors.
@@ -643,7 +643,7 @@ config I2C_IMX
config I2C_IMX_LPI2C
tristate "IMX Low Power I2C interface"
- depends on ARCH_MXC || COMPILE_TEST
+ depends on ARCH_MXC || COMPILE_TEST || ARCH_MXC_ARM64
help
Say Y here if you want to use the Low Power IIC bus controller
on the Freescale i.MX processors.
@@ -864,6 +864,12 @@ config I2C_RK3X
This driver can also be built as a module. If so, the module will
be called i2c-rk3x.
+config I2C_RPBUS
+ tristate "I2C proxy bus over RPMSG"
+ depends on I2C && RPMSG
+ help
+ This driver can support virtual i2c-rpmsg function.
+
config HAVE_S3C2410_I2C
bool
help
@@ -1327,4 +1333,24 @@ config I2C_ZX2967
This driver can also be built as a module. If so, the module will be
called i2c-zx2967.
+config XEN_I2C_FRONTEND
+ tristate "Xen virtual i2c device support"
+ depends on XEN
+ default y
+ select XEN_XENBUS_FRONTEND
+ help
+ This driver implements the front-end of the Xen virtual
+ i2c device driver. It communicates with a back-end driver
+ in another domain which drives the actual i2c device.
+
+config XEN_I2C_BACKEND
+ tristate "Xen i2c-device backend driver"
+ depends on XEN_BACKEND
+ help
+ The i2c-device backend driver allows the kernel to export its
+ block devices to other guests.
+
+ The corresponding Linux frontend driver is enabled by the
+ CONFIG_XEN_I2C_FRONTEND configuration option.
+
endmenu
diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile
index 2ce8576540a2..85c2bf496ecf 100644
--- a/drivers/i2c/busses/Makefile
+++ b/drivers/i2c/busses/Makefile
@@ -120,6 +120,7 @@ obj-$(CONFIG_I2C_DLN2) += i2c-dln2.o
obj-$(CONFIG_I2C_PARPORT) += i2c-parport.o
obj-$(CONFIG_I2C_PARPORT_LIGHT) += i2c-parport-light.o
obj-$(CONFIG_I2C_ROBOTFUZZ_OSIF) += i2c-robotfuzz-osif.o
+obj-$(CONFIG_I2C_RPBUS) += i2c-rpmsg-imx.o
obj-$(CONFIG_I2C_TAOS_EVM) += i2c-taos-evm.o
obj-$(CONFIG_I2C_TINY_USB) += i2c-tiny-usb.o
obj-$(CONFIG_I2C_VIPERBOARD) += i2c-viperboard.o
@@ -137,4 +138,7 @@ obj-$(CONFIG_I2C_SIBYTE) += i2c-sibyte.o
obj-$(CONFIG_I2C_XGENE_SLIMPRO) += i2c-xgene-slimpro.o
obj-$(CONFIG_SCx200_ACB) += scx200_acb.o
+obj-$(CONFIG_XEN_I2C_FRONTEND) += xen-i2cfront.o
+obj-$(CONFIG_XEN_I2C_BACKEND) += xen-i2cback.o
+
ccflags-$(CONFIG_I2C_DEBUG_BUS) := -DDEBUG
diff --git a/drivers/i2c/busses/i2c-imx-lpi2c.c b/drivers/i2c/busses/i2c-imx-lpi2c.c
index e86801a63120..e46284d8b035 100644
--- a/drivers/i2c/busses/i2c-imx-lpi2c.c
+++ b/drivers/i2c/busses/i2c-imx-lpi2c.c
@@ -30,6 +30,7 @@
#include <linux/of_device.h>
#include <linux/pinctrl/consumer.h>
#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
#include <linux/sched.h>
#include <linux/slab.h>
@@ -84,12 +85,14 @@
#define I2C_CLK_RATIO 2
#define CHUNK_DATA 256
-#define LPI2C_DEFAULT_RATE 100000
+#define LPI2C_DEFAULT_RATE 200000
#define STARDARD_MAX_BITRATE 400000
#define FAST_MAX_BITRATE 1000000
#define FAST_PLUS_MAX_BITRATE 3400000
#define HIGHSPEED_MAX_BITRATE 5000000
+#define I2C_PM_TIMEOUT 10 /* ms */
+
enum lpi2c_imx_mode {
STANDARD, /* 100+Kbps */
FAST, /* 400+Kbps */
@@ -107,7 +110,9 @@ enum lpi2c_imx_pincfg {
struct lpi2c_imx_struct {
struct i2c_adapter adapter;
- struct clk *clk;
+ int irq;
+ struct clk *clk_per;
+ struct clk *clk_ipg;
void __iomem *base;
__u8 *rx_buf;
__u8 *tx_buf;
@@ -222,7 +227,12 @@ static int lpi2c_imx_config(struct lpi2c_imx_struct *lpi2c_imx)
lpi2c_imx_set_mode(lpi2c_imx);
- clk_rate = clk_get_rate(lpi2c_imx->clk);
+ clk_rate = clk_get_rate(lpi2c_imx->clk_per);
+ if (!clk_rate) {
+ dev_dbg(&lpi2c_imx->adapter.dev, "clk_per rate is 0\n");
+ return -EINVAL;
+ }
+
if (lpi2c_imx->mode == HS || lpi2c_imx->mode == ULTRA_FAST)
filt = 0;
else
@@ -274,8 +284,8 @@ static int lpi2c_imx_master_enable(struct lpi2c_imx_struct *lpi2c_imx)
unsigned int temp;
int ret;
- ret = clk_enable(lpi2c_imx->clk);
- if (ret)
+ ret = pm_runtime_get_sync(lpi2c_imx->adapter.dev.parent);
+ if (ret < 0)
return ret;
temp = MCR_RST;
@@ -284,7 +294,7 @@ static int lpi2c_imx_master_enable(struct lpi2c_imx_struct *lpi2c_imx)
ret = lpi2c_imx_config(lpi2c_imx);
if (ret)
- goto clk_disable;
+ goto rpm_put;
temp = readl(lpi2c_imx->base + LPI2C_MCR);
temp |= MCR_MEN;
@@ -292,8 +302,9 @@ static int lpi2c_imx_master_enable(struct lpi2c_imx_struct *lpi2c_imx)
return 0;
-clk_disable:
- clk_disable(lpi2c_imx->clk);
+rpm_put:
+ pm_runtime_mark_last_busy(lpi2c_imx->adapter.dev.parent);
+ pm_runtime_put_autosuspend(lpi2c_imx->adapter.dev.parent);
return ret;
}
@@ -306,7 +317,8 @@ static int lpi2c_imx_master_disable(struct lpi2c_imx_struct *lpi2c_imx)
temp &= ~MCR_MEN;
writel(temp, lpi2c_imx->base + LPI2C_MCR);
- clk_disable(lpi2c_imx->clk);
+ pm_runtime_mark_last_busy(lpi2c_imx->adapter.dev.parent);
+ pm_runtime_put_autosuspend(lpi2c_imx->adapter.dev.parent);
return 0;
}
@@ -520,15 +532,17 @@ static irqreturn_t lpi2c_imx_isr(int irq, void *dev_id)
lpi2c_imx_intctrl(lpi2c_imx, 0);
temp = readl(lpi2c_imx->base + LPI2C_MSR);
+ if (temp & MSR_NDF) {
+ complete(&lpi2c_imx->complete);
+ goto ret;
+ }
+
if (temp & MSR_RDF)
lpi2c_imx_read_rxfifo(lpi2c_imx);
-
- if (temp & MSR_TDF)
+ else if (temp & MSR_TDF)
lpi2c_imx_write_txfifo(lpi2c_imx);
- if (temp & MSR_NDF)
- complete(&lpi2c_imx->complete);
-
+ret:
return IRQ_HANDLED;
}
@@ -545,7 +559,7 @@ static const struct i2c_algorithm lpi2c_imx_algo = {
static const struct of_device_id lpi2c_imx_of_match[] = {
{ .compatible = "fsl,imx7ulp-lpi2c" },
- { .compatible = "fsl,imx8dv-lpi2c" },
+ { .compatible = "fsl,imx8qm-lpi2c" },
{ },
};
MODULE_DEVICE_TABLE(of, lpi2c_imx_of_match);
@@ -555,7 +569,7 @@ static int lpi2c_imx_probe(struct platform_device *pdev)
struct lpi2c_imx_struct *lpi2c_imx;
struct resource *res;
unsigned int temp;
- int irq, ret;
+ int ret;
lpi2c_imx = devm_kzalloc(&pdev->dev, sizeof(*lpi2c_imx), GFP_KERNEL);
if (!lpi2c_imx)
@@ -566,10 +580,10 @@ static int lpi2c_imx_probe(struct platform_device *pdev)
if (IS_ERR(lpi2c_imx->base))
return PTR_ERR(lpi2c_imx->base);
- irq = platform_get_irq(pdev, 0);
- if (irq < 0) {
+ lpi2c_imx->irq = platform_get_irq(pdev, 0);
+ if (lpi2c_imx->irq < 0) {
dev_err(&pdev->dev, "can't get irq number\n");
- return irq;
+ return lpi2c_imx->irq;
}
lpi2c_imx->adapter.owner = THIS_MODULE;
@@ -579,10 +593,16 @@ static int lpi2c_imx_probe(struct platform_device *pdev)
strlcpy(lpi2c_imx->adapter.name, pdev->name,
sizeof(lpi2c_imx->adapter.name));
- lpi2c_imx->clk = devm_clk_get(&pdev->dev, NULL);
- if (IS_ERR(lpi2c_imx->clk)) {
+ lpi2c_imx->clk_per = devm_clk_get(&pdev->dev, "per");
+ if (IS_ERR(lpi2c_imx->clk_per)) {
dev_err(&pdev->dev, "can't get I2C peripheral clock\n");
- return PTR_ERR(lpi2c_imx->clk);
+ return PTR_ERR(lpi2c_imx->clk_per);
+ }
+
+ lpi2c_imx->clk_ipg = devm_clk_get(&pdev->dev, "ipg");
+ if (IS_ERR(lpi2c_imx->clk_ipg)) {
+ dev_err(&pdev->dev, "can't get I2C ipg clock\n");
+ return PTR_ERR(lpi2c_imx->clk_ipg);
}
ret = of_property_read_u32(pdev->dev.of_node,
@@ -590,38 +610,30 @@ static int lpi2c_imx_probe(struct platform_device *pdev)
if (ret)
lpi2c_imx->bitrate = LPI2C_DEFAULT_RATE;
- ret = devm_request_irq(&pdev->dev, irq, lpi2c_imx_isr, 0,
- pdev->name, lpi2c_imx);
- if (ret) {
- dev_err(&pdev->dev, "can't claim irq %d\n", irq);
- return ret;
- }
-
i2c_set_adapdata(&lpi2c_imx->adapter, lpi2c_imx);
platform_set_drvdata(pdev, lpi2c_imx);
- ret = clk_prepare_enable(lpi2c_imx->clk);
- if (ret) {
- dev_err(&pdev->dev, "clk enable failed %d\n", ret);
- return ret;
- }
+ pm_runtime_set_autosuspend_delay(&pdev->dev, I2C_PM_TIMEOUT);
+ pm_runtime_use_autosuspend(&pdev->dev);
+ pm_runtime_enable(&pdev->dev);
+ pm_runtime_get_sync(&pdev->dev);
temp = readl(lpi2c_imx->base + LPI2C_PARAM);
lpi2c_imx->txfifosize = 1 << (temp & 0x0f);
lpi2c_imx->rxfifosize = 1 << ((temp >> 8) & 0x0f);
-
- clk_disable(lpi2c_imx->clk);
+ pm_runtime_put(&pdev->dev);
ret = i2c_add_adapter(&lpi2c_imx->adapter);
if (ret)
- goto clk_unprepare;
+ goto rpm_disable;
dev_info(&lpi2c_imx->adapter.dev, "LPI2C adapter registered\n");
return 0;
-clk_unprepare:
- clk_unprepare(lpi2c_imx->clk);
+rpm_disable:
+ pm_runtime_disable(&pdev->dev);
+ pm_runtime_dont_use_autosuspend(&pdev->dev);
return ret;
}
@@ -632,28 +644,82 @@ static int lpi2c_imx_remove(struct platform_device *pdev)
i2c_del_adapter(&lpi2c_imx->adapter);
- clk_unprepare(lpi2c_imx->clk);
+ pm_runtime_disable(&pdev->dev);
+ pm_runtime_dont_use_autosuspend(&pdev->dev);
return 0;
}
#ifdef CONFIG_PM_SLEEP
-static int lpi2c_imx_suspend(struct device *dev)
+static int lpi2c_runtime_suspend(struct device *dev)
{
- pinctrl_pm_select_sleep_state(dev);
+ struct lpi2c_imx_struct *lpi2c_imx = dev_get_drvdata(dev);
+
+ devm_free_irq(dev, lpi2c_imx->irq, lpi2c_imx);
+ clk_disable_unprepare(lpi2c_imx->clk_ipg);
+ clk_disable_unprepare(lpi2c_imx->clk_per);
+ pinctrl_pm_select_idle_state(dev);
return 0;
}
-static int lpi2c_imx_resume(struct device *dev)
+static int lpi2c_runtime_resume(struct device *dev)
{
+ struct lpi2c_imx_struct *lpi2c_imx = dev_get_drvdata(dev);
+ int ret;
+
pinctrl_pm_select_default_state(dev);
+ ret = clk_prepare_enable(lpi2c_imx->clk_per);
+ if (ret) {
+ dev_err(dev, "can't enable I2C per clock, ret=%d\n", ret);
+ return ret;
+ }
+
+ ret = clk_prepare_enable(lpi2c_imx->clk_ipg);
+ if (ret) {
+ clk_disable_unprepare(lpi2c_imx->clk_per);
+ dev_err(dev, "can't enable I2C ipg clock, ret=%d\n", ret);
+ }
+
+ ret = devm_request_irq(dev, lpi2c_imx->irq, lpi2c_imx_isr,
+ IRQF_NO_SUSPEND,
+ dev_name(dev), lpi2c_imx);
+ if (ret) {
+ dev_err(dev, "can't claim irq %d\n", lpi2c_imx->irq);
+ return ret;
+ }
+
+ return ret;
+}
+
+static int lpi2c_suspend_noirq(struct device *dev)
+{
+ int ret;
+
+ ret = pm_runtime_force_suspend(dev);
+ if (ret)
+ return ret;
+
+ pinctrl_pm_select_sleep_state(dev);
return 0;
}
-#endif
-static SIMPLE_DEV_PM_OPS(imx_lpi2c_pm, lpi2c_imx_suspend, lpi2c_imx_resume);
+static int lpi2c_resume_noirq(struct device *dev)
+{
+ return pm_runtime_force_resume(dev);
+}
+
+static const struct dev_pm_ops lpi2c_pm_ops = {
+ SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(lpi2c_suspend_noirq,
+ lpi2c_resume_noirq)
+ SET_RUNTIME_PM_OPS(lpi2c_runtime_suspend,
+ lpi2c_runtime_resume, NULL)
+};
+#define IMX_LPI2C_PM (&lpi2c_pm_ops)
+#else
+#define IMX_LPI2C_PM NULL
+#endif
static struct platform_driver lpi2c_imx_driver = {
.probe = lpi2c_imx_probe,
@@ -661,11 +727,21 @@ static struct platform_driver lpi2c_imx_driver = {
.driver = {
.name = DRIVER_NAME,
.of_match_table = lpi2c_imx_of_match,
- .pm = &imx_lpi2c_pm,
+ .pm = IMX_LPI2C_PM,
},
};
-module_platform_driver(lpi2c_imx_driver);
+static int __init lpi2c_imx_init(void)
+{
+ return platform_driver_register(&lpi2c_imx_driver);
+}
+subsys_initcall(lpi2c_imx_init);
+
+static void __exit lpi2c_imx_exit(void)
+{
+ platform_driver_unregister(&lpi2c_imx_driver);
+}
+module_exit(lpi2c_imx_exit);
MODULE_AUTHOR("Gao Pan <pandy.gao@nxp.com>");
MODULE_DESCRIPTION("I2C adapter driver for LPI2C bus");
diff --git a/drivers/i2c/busses/i2c-imx.c b/drivers/i2c/busses/i2c-imx.c
index 26f83029f64a..9c2552f08269 100644
--- a/drivers/i2c/busses/i2c-imx.c
+++ b/drivers/i2c/busses/i2c-imx.c
@@ -59,6 +59,7 @@
/* Default value */
#define IMX_I2C_BIT_RATE 100000 /* 100kHz */
+#define IMX_I2C_MAX_E_BIT_RATE 384000 /* 384kHz from e7805 errata*/
/*
* Enable DMA if transfer byte size is bigger than this threshold.
@@ -169,6 +170,7 @@ enum imx_i2c_type {
IMX1_I2C,
IMX21_I2C,
VF610_I2C,
+ IMX7D_I2C,
};
struct imx_i2c_hwdata {
@@ -242,6 +244,16 @@ static struct imx_i2c_hwdata vf610_i2c_hwdata = {
};
+static const struct imx_i2c_hwdata imx7d_i2c_hwdata = {
+ .devtype = IMX7D_I2C,
+ .regshift = IMX_I2C_REGSHIFT,
+ .clk_div = imx_i2c_clk_div,
+ .ndivs = ARRAY_SIZE(imx_i2c_clk_div),
+ .i2sr_clr_opcode = I2SR_CLR_OPCODE_W0C,
+ .i2cr_ien_opcode = I2CR_IEN_OPCODE_1,
+
+};
+
static const struct platform_device_id imx_i2c_devtype[] = {
{
.name = "imx1-i2c",
@@ -259,6 +271,7 @@ static const struct of_device_id i2c_imx_dt_ids[] = {
{ .compatible = "fsl,imx1-i2c", .data = &imx1_i2c_hwdata, },
{ .compatible = "fsl,imx21-i2c", .data = &imx21_i2c_hwdata, },
{ .compatible = "fsl,vf610-i2c", .data = &vf610_i2c_hwdata, },
+ { .compatible = "fsl,imx7d-i2c", .data = &imx7d_i2c_hwdata, },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, i2c_imx_dt_ids);
@@ -268,6 +281,11 @@ static inline int is_imx1_i2c(struct imx_i2c_struct *i2c_imx)
return i2c_imx->hwdata->devtype == IMX1_I2C;
}
+static inline int is_imx7d_i2c(struct imx_i2c_struct *i2c_imx)
+{
+ return i2c_imx->hwdata->devtype == IMX7D_I2C;
+}
+
static inline void imx_i2c_write_reg(unsigned int val,
struct imx_i2c_struct *i2c_imx, unsigned int reg)
{
@@ -468,7 +486,7 @@ static int i2c_imx_acked(struct imx_i2c_struct *i2c_imx)
return 0;
}
-static void i2c_imx_set_clk(struct imx_i2c_struct *i2c_imx)
+static int i2c_imx_set_clk(struct imx_i2c_struct *i2c_imx)
{
struct imx_i2c_clk_pair *i2c_clk_div = i2c_imx->hwdata->clk_div;
unsigned int i2c_clk_rate;
@@ -477,8 +495,15 @@ static void i2c_imx_set_clk(struct imx_i2c_struct *i2c_imx)
/* Divider value calculation */
i2c_clk_rate = clk_get_rate(i2c_imx->clk);
+ /*
+ * Keep the denominator of the following program
+ * always NOT equal to 0.
+ */
+ if (!(i2c_clk_rate / 2))
+ return -EINVAL;
+
if (i2c_imx->cur_clk == i2c_clk_rate)
- return;
+ return 0;
i2c_imx->cur_clk = i2c_clk_rate;
@@ -509,6 +534,8 @@ static void i2c_imx_set_clk(struct imx_i2c_struct *i2c_imx)
dev_dbg(&i2c_imx->adapter.dev, "IFDR[IC]=0x%x, REAL DIV=%d\n",
i2c_clk_div[i].val, i2c_clk_div[i].div);
#endif
+
+ return 0;
}
static int i2c_imx_start(struct imx_i2c_struct *i2c_imx)
@@ -518,7 +545,9 @@ static int i2c_imx_start(struct imx_i2c_struct *i2c_imx)
dev_dbg(&i2c_imx->adapter.dev, "<%s>\n", __func__);
- i2c_imx_set_clk(i2c_imx);
+ result = i2c_imx_set_clk(i2c_imx);
+ if (result)
+ return result;
imx_i2c_write_reg(i2c_imx->ifdr, i2c_imx, IMX_I2C_IFDR);
/* Enable I2C controller */
@@ -884,10 +913,17 @@ static int i2c_imx_xfer(struct i2c_adapter *adapter,
unsigned int i, temp;
int result;
bool is_lastmsg = false;
+ bool enable_runtime_pm = false;
struct imx_i2c_struct *i2c_imx = i2c_get_adapdata(adapter);
dev_dbg(&i2c_imx->adapter.dev, "<%s>\n", __func__);
+
+ if (!pm_runtime_enabled(i2c_imx->adapter.dev.parent)) {
+ pm_runtime_enable(i2c_imx->adapter.dev.parent);
+ enable_runtime_pm = true;
+ }
+
result = pm_runtime_get_sync(i2c_imx->adapter.dev.parent);
if (result < 0)
goto out;
@@ -959,6 +995,9 @@ fail0:
pm_runtime_put_autosuspend(i2c_imx->adapter.dev.parent);
out:
+ if (enable_runtime_pm)
+ pm_runtime_disable(i2c_imx->adapter.dev.parent);
+
dev_dbg(&i2c_imx->adapter.dev, "<%s> exit with: %s: %d\n", __func__,
(result < 0) ? "error" : "success msg",
(result < 0) ? result : num);
@@ -1100,7 +1139,8 @@ static int i2c_imx_probe(struct platform_device *pdev)
}
/* Request IRQ */
- ret = devm_request_irq(&pdev->dev, irq, i2c_imx_isr, IRQF_SHARED,
+ ret = devm_request_irq(&pdev->dev, irq, i2c_imx_isr,
+ IRQF_SHARED | IRQF_NO_SUSPEND,
pdev->name, i2c_imx);
if (ret) {
dev_err(&pdev->dev, "can't claim irq %d\n", irq);
@@ -1132,6 +1172,14 @@ static int i2c_imx_probe(struct platform_device *pdev)
if (ret < 0 && pdata && pdata->bitrate)
i2c_imx->bitrate = pdata->bitrate;
+ /*
+ * This limit caused by an i.MX7D hardware issue(e7805 in Errata).
+ * If there is no limit, when the bitrate set up to 400KHz, it will
+ * cause the SCK low level period less than 1.3us.
+ */
+ if (is_imx7d_i2c(i2c_imx) && i2c_imx->bitrate > IMX_I2C_MAX_E_BIT_RATE)
+ i2c_imx->bitrate = IMX_I2C_MAX_E_BIT_RATE;
+
/* Set up chip registers to defaults */
imx_i2c_write_reg(i2c_imx->hwdata->i2cr_ien_opcode ^ I2CR_IEN,
i2c_imx, IMX_I2C_I2CR);
@@ -1209,6 +1257,7 @@ static int i2c_imx_runtime_suspend(struct device *dev)
struct imx_i2c_struct *i2c_imx = dev_get_drvdata(dev);
clk_disable_unprepare(i2c_imx->clk);
+ pinctrl_pm_select_sleep_state(dev);
return 0;
}
@@ -1218,6 +1267,7 @@ static int i2c_imx_runtime_resume(struct device *dev)
struct imx_i2c_struct *i2c_imx = dev_get_drvdata(dev);
int ret;
+ pinctrl_pm_select_default_state(dev);
ret = clk_prepare_enable(i2c_imx->clk);
if (ret)
dev_err(dev, "can't enable I2C clock, ret=%d\n", ret);
@@ -1225,7 +1275,20 @@ static int i2c_imx_runtime_resume(struct device *dev)
return ret;
}
+static int i2c_imx_suspend(struct device *dev)
+{
+ pinctrl_pm_select_sleep_state(dev);
+ return 0;
+}
+
+static int i2c_imx_resume(struct device *dev)
+{
+ pinctrl_pm_select_default_state(dev);
+ return 0;
+}
+
static const struct dev_pm_ops i2c_imx_pm_ops = {
+ SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(i2c_imx_suspend, i2c_imx_resume)
SET_RUNTIME_PM_OPS(i2c_imx_runtime_suspend,
i2c_imx_runtime_resume, NULL)
};
diff --git a/drivers/i2c/busses/i2c-rpmsg-imx.c b/drivers/i2c/busses/i2c-rpmsg-imx.c
new file mode 100644
index 000000000000..9d0561f8cb19
--- /dev/null
+++ b/drivers/i2c/busses/i2c-rpmsg-imx.c
@@ -0,0 +1,459 @@
+/*
+ * Copyright 2019 NXP
+ *
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/* The i2c-rpmsg transfer protocol:
+ *
+ * +---------------+-------------------------------+
+ * | Byte Offset | Content |
+ * +---------------+---+---+---+---+---+---+---+---+
+ * | 0 | Category |
+ * +---------------+---+---+---+---+---+---+---+---+
+ * | 1 ~ 2 | Version |
+ * +---------------+---+---+---+---+---+---+---+---+
+ * | 3 | Type |
+ * +---------------+---+---+---+---+---+---+---+---+
+ * | 4 | Command |
+ * +---------------+---+---+---+---+---+---+---+---+
+ * | 5 | Priority |
+ * +---------------+---+---+---+---+---+---+---+---+
+ * | 6 | Reserved1 |
+ * +---------------+---+---+---+---+---+---+---+---+
+ * | 7 | Reserved2 |
+ * +---------------+---+---+---+---+---+---+---+---+
+ * | 8 | Reserved3 |
+ * +---------------+---+---+---+---+---+---+---+---+
+ * | 9 | Reserved4 |
+ * +---------------+---+---+---+---+---+---+---+---+
+ * | 10 | BUS ID |
+ * +---------------+---+---+---+---+---+---+---+---+
+ * | 11 | Return Value |
+ * +---------------+---+---+---+---+---+---+---+---+
+ * | 12 ~ 13 | BUS ID |
+ * +---------------+---+---+---+---+---+---+---+---+
+ * | 14 ~ 15 | Address |
+ * +---------------+---+---+---+---+---+---+---+---+
+ * | 16 ~ 17 | Data Len |
+ * +---------------+---+---+---+---+---+---+---+---+
+ * | 18 ~ 33 | 16 Bytes Data |
+ * +---------------+---+---+---+---+---+---+---+---+
+ *
+ * The definition of Return Value:
+ * 0x00 = Success
+ * 0x01 = Failed
+ * 0x02 = Invalid parameter
+ * 0x03 = Invalid message
+ * 0x04 = Operate in invalid state
+ * 0x05 = Memory allocation failed
+ * 0x06 = Timeout when waiting for an event
+ * 0x07 = Cannot add to list as node already in another list
+ * 0x08 = Cannot remove from list as node not in list
+ * 0x09 = Transfer timeout
+ * 0x0A = Transfer failed due to peer core not ready
+ * 0x0B = Transfer failed due to communication failure
+ * 0x0C = Cannot find service for a request/notification
+ * 0x0D = Service version cannot support the request/notification
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/imx_rpmsg.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/i2c.h>
+#include <linux/platform_device.h>
+#include <linux/time.h>
+#include <linux/delay.h>
+#include <linux/rpmsg.h>
+
+#define I2C_RPMSG_MAX_BUF_SIZE 16
+#define I2C_RPMSG_TIMEOUT 500 /* unit: ms */
+
+#define I2C_RPMSG_CATEGORY 0x09
+#define I2C_RPMSG_VERSION 0x0001
+#define I2C_RPMSG_TYPE_REQUEST 0x00
+#define I2C_RPMSG_TYPE_RESPONSE 0x01
+#define I2C_RPMSG_COMMAND_READ 0x00
+#define I2C_RPMSG_COMMAND_WRITE 0x01
+#define I2C_RPMSG_PRIORITY 0x01
+
+#define I2C_RPMSG_M_STOP 0x0200
+
+struct i2c_rpmsg_msg {
+ struct imx_rpmsg_head header;
+
+ /* Payload Start*/
+ u8 bus_id;
+ u8 ret_val;
+ u16 addr;
+ u16 flags;
+ u16 len;
+ u8 buf[I2C_RPMSG_MAX_BUF_SIZE];
+} __packed __aligned(1);
+
+struct i2c_rpmsg_info {
+ struct rpmsg_device *rpdev;
+ struct device *dev;
+ struct i2c_rpmsg_msg *msg;
+ struct completion cmd_complete;
+ struct mutex lock;
+
+ u8 bus_id;
+ u16 addr;
+};
+
+static struct i2c_rpmsg_info i2c_rpmsg;
+
+struct imx_rpmsg_i2c_data {
+ struct i2c_adapter adapter;
+};
+
+static int i2c_rpmsg_cb(struct rpmsg_device *rpdev, void *data, int len,
+ void *priv, u32 src)
+{
+ struct i2c_rpmsg_msg *msg = (struct i2c_rpmsg_msg *)data;
+
+ if (msg->header.type != I2C_RPMSG_TYPE_RESPONSE)
+ return -EINVAL;
+
+ if (msg->bus_id != i2c_rpmsg.bus_id || msg->addr != i2c_rpmsg.addr) {
+ dev_err(&rpdev->dev,
+ "expected bus_id:%d, addr:%2x, received bus_id:%d, addr:%2x\n",
+ i2c_rpmsg.bus_id, i2c_rpmsg.addr, msg->bus_id, msg->addr);
+ return -EINVAL;
+ }
+
+ if (msg->len > I2C_RPMSG_MAX_BUF_SIZE) {
+ dev_err(&rpdev->dev,
+ "%s failed: data length greater than %d, len=%d\n",
+ __func__, I2C_RPMSG_MAX_BUF_SIZE, msg->len);
+ return -EINVAL;
+ }
+
+ /* Receive Success */
+ i2c_rpmsg.msg = msg;
+
+ complete(&i2c_rpmsg.cmd_complete);
+
+ return 0;
+}
+
+static int rpmsg_xfer(struct i2c_rpmsg_msg *rmsg, struct i2c_rpmsg_info *info)
+{
+ int ret = 0;
+
+ ret = rpmsg_send(info->rpdev->ept, (void *)rmsg,
+ sizeof(struct i2c_rpmsg_msg));
+ if (ret < 0) {
+ dev_err(&info->rpdev->dev, "rpmsg_send failed: %d\n", ret);
+ return ret;
+ }
+
+ ret = wait_for_completion_timeout(&info->cmd_complete,
+ msecs_to_jiffies(I2C_RPMSG_TIMEOUT));
+ if (!ret) {
+ dev_err(&info->rpdev->dev, "%s failed: timeout\n", __func__);
+ return -ETIMEDOUT;
+ }
+
+ if (info->msg->ret_val) {
+ dev_dbg(&info->rpdev->dev,
+ "%s failed: %d\n", __func__, info->msg->ret_val);
+ return -(info->msg->ret_val);
+ }
+
+ return 0;
+}
+
+static int i2c_rpmsg_read(struct i2c_msg *msg, struct i2c_rpmsg_info *info,
+ int bus_id, bool is_last)
+{
+ int ret;
+ struct i2c_rpmsg_msg rmsg;
+
+ if (!info->rpdev)
+ return -EINVAL;
+
+ if (msg->len > I2C_RPMSG_MAX_BUF_SIZE) {
+ dev_err(&info->rpdev->dev,
+ "%s failed: data length greater than %d, len=%d\n",
+ __func__, I2C_RPMSG_MAX_BUF_SIZE, msg->len);
+ return -EINVAL;
+ }
+
+ memset(&rmsg, 0, sizeof(struct i2c_rpmsg_msg));
+ rmsg.header.cate = I2C_RPMSG_CATEGORY;
+ rmsg.header.major = I2C_RPMSG_VERSION;
+ rmsg.header.minor = I2C_RPMSG_VERSION >> 8;
+ rmsg.header.type = I2C_RPMSG_TYPE_REQUEST;
+ rmsg.header.cmd = I2C_RPMSG_COMMAND_READ;
+ rmsg.header.reserved[0] = I2C_RPMSG_PRIORITY;
+ rmsg.bus_id = bus_id;
+ rmsg.ret_val = 0;
+ rmsg.addr = msg->addr;
+ if (is_last)
+ rmsg.flags = msg->flags | I2C_RPMSG_M_STOP;
+ else
+ rmsg.flags = msg->flags;
+ rmsg.len = (msg->len);
+
+ reinit_completion(&info->cmd_complete);
+
+ ret = rpmsg_xfer(&rmsg, info);
+ if (ret)
+ return ret;
+
+ if (!info->msg ||
+ (info->msg->len != msg->len)) {
+ dev_err(&info->rpdev->dev,
+ "%s failed: %d\n", __func__, -EPROTO);
+ return -EPROTO;
+ }
+
+ memcpy(msg->buf, info->msg->buf, info->msg->len);
+
+ return msg->len;
+}
+
+int i2c_rpmsg_write(struct i2c_msg *msg, struct i2c_rpmsg_info *info,
+ int bus_id, bool is_last)
+{
+ int i, ret;
+ struct i2c_rpmsg_msg rmsg;
+
+ if (!info || !info->rpdev)
+ return -EINVAL;
+
+ if (msg->len > I2C_RPMSG_MAX_BUF_SIZE) {
+ dev_err(&info->rpdev->dev,
+ "%s failed: data length greater than %d, len=%d\n",
+ __func__, I2C_RPMSG_MAX_BUF_SIZE, msg->len);
+ return -EINVAL;
+ }
+
+ memset(&rmsg, 0, sizeof(struct i2c_rpmsg_msg));
+ rmsg.header.cate = I2C_RPMSG_CATEGORY;
+ rmsg.header.major = I2C_RPMSG_VERSION;
+ rmsg.header.minor = I2C_RPMSG_VERSION >> 8;
+ rmsg.header.type = I2C_RPMSG_TYPE_REQUEST;
+ rmsg.header.cmd = I2C_RPMSG_COMMAND_WRITE;
+ rmsg.header.reserved[0] = I2C_RPMSG_PRIORITY;
+ rmsg.bus_id = bus_id;
+ rmsg.ret_val = 0;
+ rmsg.addr = msg->addr;
+ if (is_last)
+ rmsg.flags = msg->flags | I2C_RPMSG_M_STOP;
+ else
+ rmsg.flags = msg->flags;
+ rmsg.len = msg->len;
+
+ for (i = 0; i < rmsg.len; i++)
+ rmsg.buf[i] = msg->buf[i];
+
+ reinit_completion(&info->cmd_complete);
+
+ ret = rpmsg_xfer(&rmsg, info);
+ if (ret)
+ return ret;
+
+ return ret;
+}
+
+static int i2c_rpmsg_probe(struct rpmsg_device *rpdev)
+{
+ int ret = 0;
+
+ if (!rpdev) {
+ dev_info(&rpdev->dev, "%s failed, rpdev=NULL\n", __func__);
+ return -EINVAL;
+ }
+
+ i2c_rpmsg.rpdev = rpdev;
+
+ mutex_init(&i2c_rpmsg.lock);
+ init_completion(&i2c_rpmsg.cmd_complete);
+
+ dev_info(&rpdev->dev, "new channel: 0x%x -> 0x%x!\n",
+ rpdev->src, rpdev->dst);
+
+ return ret;
+}
+
+static void i2c_rpmsg_remove(struct rpmsg_device *rpdev)
+{
+ i2c_rpmsg.rpdev = NULL;
+ dev_info(&rpdev->dev, "i2c rpmsg driver is removed\n");
+}
+
+static struct rpmsg_device_id i2c_rpmsg_id_table[] = {
+ { .name = "rpmsg-i2c-channel" },
+ { },
+};
+
+static struct rpmsg_driver i2c_rpmsg_driver = {
+ .drv.name = "i2c-rpmsg",
+ .drv.owner = THIS_MODULE,
+ .id_table = i2c_rpmsg_id_table,
+ .probe = i2c_rpmsg_probe,
+ .remove = i2c_rpmsg_remove,
+ .callback = i2c_rpmsg_cb,
+};
+
+
+static int i2c_rpbus_xfer(struct i2c_adapter *adapter,
+ struct i2c_msg *msgs, int num)
+{
+ struct imx_rpmsg_i2c_data *rdata =
+ container_of(adapter, struct imx_rpmsg_i2c_data, adapter);
+ struct i2c_msg *pmsg;
+ int i, ret;
+ bool is_last = false;
+
+ mutex_lock(&i2c_rpmsg.lock);
+
+ for (i = 0; i < num; i++) {
+ if (i == num - 1)
+ is_last = true;
+
+ pmsg = &msgs[i];
+
+ i2c_rpmsg.bus_id = rdata->adapter.nr;
+ i2c_rpmsg.addr = pmsg->addr;
+
+ if (pmsg->flags & I2C_M_RD) {
+ ret = i2c_rpmsg_read(pmsg, &i2c_rpmsg,
+ rdata->adapter.nr, is_last);
+ if (ret < 0) {
+ mutex_unlock(&i2c_rpmsg.lock);
+ return ret;
+ }
+
+ pmsg->len = ret;
+ } else {
+ ret = i2c_rpmsg_write(pmsg, &i2c_rpmsg,
+ rdata->adapter.nr, is_last);
+ if (ret < 0) {
+ mutex_unlock(&i2c_rpmsg.lock);
+ return ret;
+ }
+ }
+ }
+
+ mutex_unlock(&i2c_rpmsg.lock);
+ return num;
+}
+
+static u32 i2c_rpbus_func(struct i2c_adapter *a)
+{
+ return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL
+ | I2C_FUNC_SMBUS_READ_BLOCK_DATA;
+}
+
+static const struct i2c_algorithm i2c_rpbus_algorithm = {
+ .master_xfer = i2c_rpbus_xfer,
+ .functionality = i2c_rpbus_func,
+};
+
+static const struct i2c_adapter_quirks i2c_rpbus_quirks = {
+ .max_write_len = I2C_RPMSG_MAX_BUF_SIZE,
+ .max_read_len = I2C_RPMSG_MAX_BUF_SIZE,
+};
+
+static int i2c_rpbus_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct device_node *np = dev->of_node;
+ struct imx_rpmsg_i2c_data *rdata;
+ struct i2c_adapter *adapter;
+ int ret;
+
+ rdata = devm_kzalloc(&pdev->dev, sizeof(*rdata), GFP_KERNEL);
+ if (!rdata)
+ return -ENOMEM;
+
+ adapter = &rdata->adapter;
+ /* setup i2c adapter description */
+ adapter->owner = THIS_MODULE;
+ adapter->class = I2C_CLASS_HWMON;
+ adapter->algo = &i2c_rpbus_algorithm;
+ adapter->dev.parent = dev;
+ adapter->dev.of_node = np;
+ adapter->nr = of_alias_get_id(np, "i2c");
+ /*
+ * The driver will send the adapter->nr as BUS ID to the other
+ * side, and the other side will check the BUS ID to see whether
+ * the BUS has been registered. If there is alias id for this
+ * virtual adapter, linux kernel will automatically allocate one
+ * id which might be not the same number used in the other side,
+ * cause i2c slave probe failure under this virtual I2C bus.
+ * So let's add a BUG_ON to catch this issue earlier.
+ */
+ BUG_ON(adapter->nr < 0);
+ adapter->quirks = &i2c_rpbus_quirks;
+ snprintf(rdata->adapter.name, sizeof(rdata->adapter.name), "%s",
+ "i2c-rpmsg-adapter");
+ platform_set_drvdata(pdev, rdata);
+
+ ret = i2c_add_adapter(&rdata->adapter);
+ if (ret < 0) {
+ dev_err(dev, "failed to add I2C adapter: %d\n", ret);
+ return ret;
+ }
+
+ dev_info(dev, "add I2C adapter %s successfully\n", rdata->adapter.name);
+
+ return 0;
+}
+
+static int i2c_rpbus_remove(struct platform_device *pdev)
+{
+ struct imx_rpmsg_i2c_data *rdata = platform_get_drvdata(pdev);
+
+ i2c_del_adapter(&rdata->adapter);
+
+ return 0;
+}
+
+static const struct of_device_id imx_rpmsg_i2c_dt_ids[] = {
+ { .compatible = "fsl,i2c-rpbus", },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, imx_rpmsg_i2c_dt_ids);
+
+static struct platform_driver imx_rpmsg_i2c_driver = {
+ .driver = {
+ .name = "imx_rpmsg_i2c",
+ .of_match_table = imx_rpmsg_i2c_dt_ids,
+ },
+ .probe = i2c_rpbus_probe,
+ .remove = i2c_rpbus_remove
+};
+
+static int __init imx_rpmsg_i2c_driver_init(void)
+{
+ int ret = 0;
+
+ ret = register_rpmsg_driver(&i2c_rpmsg_driver);
+ if (ret < 0)
+ return ret;
+
+ return platform_driver_register(&(imx_rpmsg_i2c_driver));
+}
+subsys_initcall(imx_rpmsg_i2c_driver_init);
+
+MODULE_AUTHOR("Clark Wang<xiaoning.wang@nxp.com>");
+MODULE_DESCRIPTION("Driver for i2c over rpmsg");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:i2c-rpbus");
diff --git a/drivers/i2c/busses/xen-i2cback.c b/drivers/i2c/busses/xen-i2cback.c
new file mode 100644
index 000000000000..cdb418aadd99
--- /dev/null
+++ b/drivers/i2c/busses/xen-i2cback.c
@@ -0,0 +1,494 @@
+/*
+ * Copyright 2018 NXP
+ *
+ * Peng Fan <peng.fan@nxp.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/module.h>
+#include <linux/interrupt.h>
+#include <linux/i2c.h>
+#include <linux/slab.h>
+
+#include <xen/xen.h>
+#include <xen/events.h>
+#include <xen/xenbus.h>
+#include <xen/grant_table.h>
+#include <xen/page.h>
+
+#include <xen/interface/grant_table.h>
+#include <xen/interface/io/i2cif.h>
+
+struct i2cback_info {
+ domid_t domid;
+ u32 irq;
+ u64 handle;
+ struct xenbus_device *i2cdev;
+ spinlock_t i2c_ring_lock;
+ struct i2cif_back_ring i2c_ring;
+ int is_connected;
+ int ring_error;
+ struct i2c_adapter *adapter;
+ u32 num_slaves;
+ u32 *allowed_slaves;
+};
+
+static bool i2cback_access_allowed(struct i2cback_info *info,
+ struct i2cif_request *req)
+{
+ int i;
+
+ if (req->is_smbus) {/*check for smbus access permission*/
+ for (i = 0; i < info->num_slaves; i++)
+ if (req->addr == info->allowed_slaves[i])
+ return true;
+
+ return false;
+ }
+
+ /*check for master_xfer access permission*/
+ if (req->num_msg == I2CIF_MAX_MSG) {
+ if (req->msg[0].addr != req->msg[1].addr)
+ return false;
+ }
+
+ for (i = 0; i < info->num_slaves; i++) {
+ if (req->msg[0].addr == info->allowed_slaves[i])
+ return true;
+ }
+
+ return false;
+}
+
+static bool i2cback_handle_int(struct i2cback_info *info)
+{
+ struct i2cif_back_ring *i2c_ring = &info->i2c_ring;
+ struct i2cif_request req;
+ struct i2cif_response *res;
+ RING_IDX rc, rp;
+ int more_to_do, notify, num_msg = 0, ret;
+ struct i2c_msg msg[I2CIF_MAX_MSG];
+ union i2c_smbus_data smbus_data;
+ char tmp_buf[I2CIF_BUF_LEN];
+ unsigned long flags;
+ bool allow_access;
+ int i;
+
+ rc = i2c_ring->req_cons;
+ rp = i2c_ring->sring->req_prod;
+ rmb(); /* req_cons is written by frontend. */
+
+ if (RING_REQUEST_PROD_OVERFLOW(i2c_ring, rp)) {
+ rc = i2c_ring->rsp_prod_pvt;
+ dev_err(&info->i2cdev->dev, "ring overflow\n");
+ info->ring_error = 1;
+ return 0;
+ }
+
+ while (rc != rp) {
+ if (RING_REQUEST_CONS_OVERFLOW(i2c_ring, rc)) {
+ dev_err(&info->i2cdev->dev, "%s overflow\n", __func__);
+ break;
+ }
+
+ req = *RING_GET_REQUEST(i2c_ring, rc);
+ allow_access = i2cback_access_allowed(info, &req);
+ if (allow_access && !req.is_smbus) {
+ /* Write/Read sequence */
+ num_msg = req.num_msg;
+ if (num_msg > I2CIF_MAX_MSG)
+ num_msg = I2CIF_MAX_MSG;
+
+ for (i = 0; i < num_msg; i++) {
+ msg[i].addr = req.msg[i].addr;
+ msg[i].len = req.msg[i].len;
+ msg[i].flags = 0;
+ if (req.msg[i].flags & I2CIF_M_RD)
+ msg[i].flags |= I2C_M_RD;
+ if (req.msg[i].flags & I2CIF_M_TEN)
+ msg[i].flags |= I2C_M_TEN;
+ if (req.msg[i].flags & I2CIF_M_RECV_LEN)
+ msg[i].flags |= I2C_M_RECV_LEN;
+ if (req.msg[i].flags & I2CIF_M_NO_RD_ACK)
+ msg[i].flags |= I2C_M_NO_RD_ACK;
+ if (req.msg[i].flags & I2CIF_M_IGNORE_NAK)
+ msg[i].flags |= I2C_M_IGNORE_NAK;
+ if (req.msg[i].flags & I2CIF_M_REV_DIR_ADDR)
+ msg[i].flags |= I2C_M_REV_DIR_ADDR;
+ if (req.msg[i].flags & I2CIF_M_NOSTART)
+ msg[i].flags |= I2C_M_NOSTART;
+ if (req.msg[i].flags & I2CIF_M_STOP)
+ msg[i].flags |= I2C_M_STOP;
+ }
+
+ if ((num_msg == 2) &&
+ (!(msg[0].flags & I2C_M_RD)) &&
+ (msg[1].flags & I2C_M_RD)) {
+
+ /* overwrite the remote buf with local buf */
+ msg[0].buf = tmp_buf;
+ msg[1].buf = tmp_buf;
+
+ /* msg[0] write buf */
+ memcpy(tmp_buf, req.write_buf, I2CIF_BUF_LEN);
+ ret = i2c_transfer(info->adapter, msg,
+ num_msg);
+ } else if (num_msg == 1) {
+ msg[0].buf = tmp_buf;
+ if (!(msg[0].flags & I2C_M_RD))
+ memcpy(tmp_buf, req.write_buf,
+ I2CIF_BUF_LEN);
+ ret = i2c_transfer(info->adapter, msg,
+ req.num_msg);
+ } else {
+ dev_dbg(&info->i2cdev->dev, "too many msgs\n");
+
+ ret = -EIO;
+ }
+ } else if (allow_access && req.is_smbus) {
+ memcpy(&smbus_data, &req.write_buf, sizeof(smbus_data));
+
+ ret = i2c_smbus_xfer(info->adapter,
+ req.addr,
+ req.flags,
+ req.read_write,
+ req.command,
+ req.protocol,
+ &smbus_data);
+ }
+
+ spin_lock_irqsave(&info->i2c_ring_lock, flags);
+ res = RING_GET_RESPONSE(&info->i2c_ring,
+ info->i2c_ring.rsp_prod_pvt);
+
+ if (allow_access && !req.is_smbus) {
+ res->result = ret;
+
+ if ((req.num_msg == 2) &&
+ (!(msg[0].flags & I2C_M_RD)) &&
+ (msg[1].flags & I2C_M_RD) && (ret >= 0)) {
+ memcpy(res->read_buf, tmp_buf, I2CIF_BUF_LEN);
+ } else if (req.num_msg == 1) {
+ if ((msg[0].flags & I2C_M_RD) && (ret >= 0))
+ memcpy(res->read_buf, tmp_buf,
+ I2CIF_BUF_LEN);
+ }
+ } else if (allow_access && req.is_smbus) {
+ if (req.read_write == I2C_SMBUS_READ)
+ memcpy(&res->read_buf, &smbus_data, sizeof(smbus_data));
+ res->result = ret;
+ } else
+ res->result = -EPERM;
+
+ info->i2c_ring.rsp_prod_pvt++;
+
+ barrier();
+ RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(&info->i2c_ring,
+ notify);
+ spin_unlock_irqrestore(&info->i2c_ring_lock, flags);
+
+ if (notify)
+ notify_remote_via_irq(info->irq);
+
+ i2c_ring->req_cons = ++rc;
+
+ cond_resched();
+ }
+
+ RING_FINAL_CHECK_FOR_REQUESTS(i2c_ring, more_to_do);
+
+ return !!more_to_do;
+}
+
+static irqreturn_t i2cback_be_int(int irq, void *dev_id)
+{
+ struct i2cback_info *info = dev_id;
+
+ if (info->ring_error)
+ return IRQ_HANDLED;
+
+ while (i2cback_handle_int(info))
+ cond_resched();
+
+ return IRQ_HANDLED;
+}
+
+static int i2cback_map(struct i2cback_info *info, grant_ref_t *i2c_ring_ref,
+ evtchn_port_t evtchn)
+{
+ int err;
+ void *addr;
+ struct i2cif_sring *i2c_sring;
+
+ if (info->irq)
+ return 0;
+
+ err = xenbus_map_ring_valloc(info->i2cdev, i2c_ring_ref, 1, &addr);
+ if (err)
+ return err;
+
+ i2c_sring = addr;
+
+ BACK_RING_INIT(&info->i2c_ring, i2c_sring, PAGE_SIZE);
+
+ err = bind_interdomain_evtchn_to_irq(info->domid, evtchn);
+ if (err < 0)
+ goto fail_evtchn;
+ info->irq = err;
+
+ err = request_threaded_irq(info->irq, NULL, i2cback_be_int,
+ IRQF_ONESHOT, "xen-i2cback", info);
+ if (err) {
+ dev_err(&info->i2cdev->dev, "bind evtchn to irq failure!\n");
+ goto free_irq;
+ }
+
+ return 0;
+free_irq:
+ unbind_from_irqhandler(info->irq, info);
+ info->irq = 0;
+ info->i2c_ring.sring = NULL;
+fail_evtchn:
+ xenbus_unmap_ring_vfree(info->i2cdev, i2c_sring);
+ return err;
+}
+
+static int i2cback_connect_rings(struct i2cback_info *info)
+{
+ struct xenbus_device *dev = info->i2cdev;
+ unsigned int i2c_ring_ref, evtchn;
+ int i, err;
+ char *buf;
+ u32 adapter_id;
+
+ err = xenbus_scanf(XBT_NIL, dev->nodename,
+ "adapter", "%u", &adapter_id);
+ if (err != 1) {
+ xenbus_dev_fatal(dev, err, "%s reading adapter", dev->nodename);
+ return err;
+ }
+
+ info->adapter = i2c_get_adapter(adapter_id);
+ if (!info->adapter)
+ return -ENODEV;
+
+ err = xenbus_scanf(XBT_NIL, dev->nodename,
+ "num-slaves", "%u", &info->num_slaves);
+ if (err != 1) {
+ xenbus_dev_fatal(dev, err, "%s reading num-slaves",
+ dev->nodename);
+ return err;
+ }
+
+ info->allowed_slaves = devm_kmalloc(&dev->dev,
+ info->num_slaves * sizeof(u32),
+ GFP_KERNEL);
+ if (!info->allowed_slaves)
+ return -ENOMEM;
+
+ /* 128 bytes is enough */
+ buf = kmalloc(128, GFP_KERNEL);
+
+ for (i = 0; i < info->num_slaves; i++) {
+ snprintf(buf, 128, "%s/%d", dev->nodename, i);
+ err = xenbus_scanf(XBT_NIL, buf, "addr", "%x",
+ &info->allowed_slaves[i]);
+ if (err != 1) {
+ kfree(buf);
+ return err;
+ }
+ }
+
+ kfree(buf);
+
+ err = xenbus_gather(XBT_NIL, dev->otherend,
+ "ring-ref", "%u", &i2c_ring_ref,
+ "event-channel", "%u", &evtchn, NULL);
+ if (err) {
+ xenbus_dev_fatal(dev, err,
+ "reading %s/ring-ref and event-channel",
+ dev->otherend);
+ return err;
+ }
+
+ dev_info(&info->i2cdev->dev,
+ "xen-pvi2c: ring-ref %u, event-channel %u\n",
+ i2c_ring_ref, evtchn);
+
+ err = i2cback_map(info, &i2c_ring_ref, evtchn);
+ if (err)
+ xenbus_dev_fatal(dev, err, "mapping ring-ref %u evtchn %u",
+ i2c_ring_ref, evtchn);
+
+ return err;
+}
+
+static void i2cback_disconnect(struct i2cback_info *info)
+{
+ if (info->irq) {
+ unbind_from_irqhandler(info->irq, info);
+ info->irq = 0;
+ }
+
+ if (info->i2c_ring.sring) {
+ xenbus_unmap_ring_vfree(info->i2cdev, info->i2c_ring.sring);
+ info->i2c_ring.sring = NULL;
+ }
+}
+
+static void i2cback_frontend_changed(struct xenbus_device *dev,
+ enum xenbus_state frontend_state)
+{
+ struct i2cback_info *info = dev_get_drvdata(&dev->dev);
+ int ret;
+
+ switch (frontend_state) {
+ case XenbusStateInitialised:
+ case XenbusStateReconfiguring:
+ case XenbusStateReconfigured:
+ break;
+
+ case XenbusStateInitialising:
+ if (dev->state == XenbusStateClosed) {
+ dev_info(&dev->dev,
+ "xen-pvi2c: %s: prepare for reconnect\n",
+ dev->nodename);
+ xenbus_switch_state(dev, XenbusStateInitWait);
+ }
+ break;
+ case XenbusStateConnected:
+ if (dev->state == XenbusStateConnected)
+ break;
+
+ xenbus_switch_state(dev, XenbusStateConnected);
+
+ ret = i2cback_connect_rings(info);
+ if (ret) {
+ xenbus_dev_fatal(dev, ret, "connect ring fail");
+ }
+ break;
+ case XenbusStateClosing:
+ i2cback_disconnect(info);
+ xenbus_switch_state(dev, XenbusStateClosing);
+ break;
+ case XenbusStateClosed:
+ xenbus_switch_state(dev, XenbusStateClosed);
+ if (xenbus_dev_is_online(dev))
+ break;
+ /* fall through if not online */
+ case XenbusStateUnknown:
+ device_unregister(&dev->dev);
+ break;
+
+ default:
+ xenbus_dev_fatal(dev, -EINVAL, "saw state %d at frontend",
+ frontend_state);
+ break;
+ }
+}
+
+static struct i2cback_info *i2cback_alloc(domid_t domid, u64 handle)
+{
+ struct i2cback_info *info;
+
+ info = kzalloc(sizeof(struct i2cback_info), GFP_KERNEL);
+ if (!info)
+ return NULL;
+
+ info->domid = domid;
+ info->handle = handle;
+ spin_lock_init(&info->i2c_ring_lock);
+ info->ring_error = 0;
+
+ return info;
+}
+
+static int i2cback_probe(struct xenbus_device *dev,
+ const struct xenbus_device_id *id)
+{
+ struct i2cback_info *info;
+ unsigned long handle;
+ int err;
+
+ if (kstrtoul(strrchr(dev->otherend, '/') + 1, 0, &handle))
+ return -EINVAL;
+
+ info = i2cback_alloc(dev->otherend_id, handle);
+ if (!info) {
+ xenbus_dev_fatal(dev, -ENOMEM, "Allocating backend interface");
+ return -ENOMEM;
+ }
+
+ info->i2cdev = dev;
+ dev_set_drvdata(&dev->dev, info);
+
+ err = xenbus_switch_state(dev, XenbusStateInitWait);
+ if (err)
+ return err;
+
+ return 0;
+}
+
+static int i2cback_remove(struct xenbus_device *dev)
+{
+ struct i2cback_info *info = dev_get_drvdata(&dev->dev);
+
+ if (!info)
+ return 0;
+
+ i2cback_disconnect(info);
+
+ kfree(info);
+ dev_set_drvdata(&dev->dev, NULL);
+
+ dev_info(&dev->dev, "%s\n", __func__);
+
+ return 0;
+}
+
+static const struct xenbus_device_id i2cback_ids[] = {
+ { "vi2c" },
+ { "" },
+};
+
+static struct xenbus_driver i2cback_driver = {
+ .ids = i2cback_ids,
+ .probe = i2cback_probe,
+ .otherend_changed = i2cback_frontend_changed,
+ .remove = i2cback_remove,
+};
+
+static int __init i2cback_init(void)
+{
+ int err;
+
+ if (!xen_domain())
+ return -ENODEV;
+
+ err = xenbus_register_backend(&i2cback_driver);
+ if (err)
+ return err;
+
+ return 0;
+}
+module_init(i2cback_init);
+
+static void __exit i2cback_exit(void)
+{
+ xenbus_unregister_driver(&i2cback_driver);
+}
+module_exit(i2cback_exit);
+
+MODULE_ALIAS("xen-i2cback:vi2c");
+MODULE_AUTHOR("Peng Fan <peng.fan@nxp.com>");
+MODULE_DESCRIPTION("Xen I2C backend driver (i2cback)");
+MODULE_LICENSE("GPL");
diff --git a/drivers/i2c/busses/xen-i2cfront.c b/drivers/i2c/busses/xen-i2cfront.c
new file mode 100644
index 000000000000..8a18a7982aaf
--- /dev/null
+++ b/drivers/i2c/busses/xen-i2cfront.c
@@ -0,0 +1,515 @@
+/*
+ * Copyright 2018 NXP
+ *
+ * Peng Fan <peng.fan@nxp.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/module.h>
+#include <linux/i2c.h>
+#include <linux/list.h>
+#include <linux/io.h>
+
+#include <xen/xen.h>
+#include <xen/xenbus.h>
+#include <xen/grant_table.h>
+#include <xen/events.h>
+#include <xen/page.h>
+
+#include <xen/interface/io/i2cif.h>
+
+#define GRANT_INVALID_REF 0
+
+struct i2cfront_info {
+ spinlock_t lock;
+ struct mutex xferlock;
+ struct i2c_adapter adapter;
+ struct xenbus_device *i2cdev;
+ int i2c_ring_ref;
+ struct i2cif_front_ring i2c_ring;
+ unsigned int evtchn;
+ unsigned int irq;
+ struct completion completion;
+ struct i2cif_request *req;
+ struct i2cif_response *res;
+};
+
+static void i2cfront_destroy_rings(struct i2cfront_info *info)
+{
+ if (info->irq)
+ unbind_from_irqhandler(info->irq, info);
+ info->irq = 0;
+
+ if (info->i2c_ring_ref != GRANT_INVALID_REF) {
+ gnttab_end_foreign_access(info->i2c_ring_ref, 0,
+ (unsigned long)info->i2c_ring.sring);
+ info->i2c_ring_ref = GRANT_INVALID_REF;
+ }
+ info->i2c_ring.sring = NULL;
+}
+
+static int i2cfront_do_req(struct i2c_adapter *adapter, struct i2c_msg *msg,
+ int num)
+{
+ struct i2cfront_info *info = i2c_get_adapdata(adapter);
+ struct i2cif_request *req;
+ struct i2cif_response *res;
+ int notify;
+ int ret;
+ RING_IDX i, rp;
+ int more_to_do = 0;
+ unsigned long flags;
+ int index;
+
+ mutex_lock(&info->xferlock);
+ req = RING_GET_REQUEST(&info->i2c_ring, info->i2c_ring.req_prod_pvt);
+
+ for (index = 0; index < num; index++) {
+ req->msg[index].addr = msg[index].addr;
+ req->msg[index].len = msg[index].len;
+ req->msg[index].flags = 0;
+ if (msg[index].flags & I2C_M_RD)
+ req->msg[index].flags |= I2CIF_M_RD;
+ if (msg[index].flags & I2C_M_TEN)
+ req->msg[index].flags |= I2CIF_M_TEN;
+ if (msg[index].flags & I2C_M_RECV_LEN)
+ req->msg[index].flags |= I2CIF_M_RECV_LEN;
+ if (msg[index].flags & I2C_M_NO_RD_ACK)
+ req->msg[index].flags |= I2CIF_M_NO_RD_ACK;
+ if (msg[index].flags & I2C_M_IGNORE_NAK)
+ req->msg[index].flags |= I2CIF_M_IGNORE_NAK;
+ if (msg[index].flags & I2C_M_REV_DIR_ADDR)
+ req->msg[index].flags |= I2CIF_M_REV_DIR_ADDR;
+ if (msg[index].flags & I2C_M_NOSTART)
+ req->msg[index].flags |= I2CIF_M_NOSTART;
+ if (msg[index].flags & I2C_M_STOP)
+ req->msg[index].flags |= I2CIF_M_STOP;
+ }
+
+ req->num_msg = num;
+ req->is_smbus = false;
+
+ if ((num == 2) && !(msg[0].flags & I2C_M_RD) &&
+ (msg[1].flags & I2C_M_RD)) {
+ memcpy(req->write_buf, msg[0].buf,
+ min_t(int, msg[0].len, I2CIF_BUF_LEN));
+ } else if (num == 1) {
+ if (!(msg->flags & I2C_M_RD))
+ memcpy(req->write_buf, msg->buf,
+ min_t(int, msg->len, I2CIF_BUF_LEN));
+ } else {
+ dev_err(&adapter->dev, "%s not supported\n", __func__);
+ return -EIO;
+ }
+
+ spin_lock(&info->lock);
+ info->i2c_ring.req_prod_pvt++;
+ RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&info->i2c_ring, notify);
+ spin_unlock(&info->lock);
+ if (notify)
+ notify_remote_via_irq(info->irq);
+
+ wait_for_completion(&info->completion);
+
+ spin_lock_irqsave(&info->lock, flags);
+ rp = info->i2c_ring.sring->rsp_prod;
+ rmb(); /* ensure we see queued responses up to "rp" */
+
+ ret = -EIO;
+ for (i = info->i2c_ring.rsp_cons; i != rp; i++) {
+ res = RING_GET_RESPONSE(&info->i2c_ring, i);
+ if ((num == 2) && !(msg[0].flags & I2C_M_RD) &&
+ (msg[1].flags & I2C_M_RD)) {
+ memcpy(msg[1].buf, res->read_buf,
+ min_t(int, msg[1].len, I2CIF_BUF_LEN));
+ } else if (num == 1) {
+ if (!(msg->flags & I2C_M_RD))
+ memcpy(msg->buf, res->read_buf,
+ min_t(int, msg->len, I2CIF_BUF_LEN));
+ }
+
+ ret = res->result;
+ }
+
+ info->i2c_ring.rsp_cons = i;
+
+ if (i != info->i2c_ring.req_prod_pvt)
+ RING_FINAL_CHECK_FOR_RESPONSES(&info->i2c_ring, more_to_do);
+ else
+ info->i2c_ring.sring->rsp_event = i + 1;
+
+ spin_unlock_irqrestore(&info->lock, flags);
+
+ mutex_unlock(&info->xferlock);
+
+ return ret;
+}
+
+int i2cfront_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num)
+{
+ struct i2cfront_info *info = i2c_get_adapdata(adapter);
+ int ret, i;
+
+ if (!info || !info->i2cdev) {
+ dev_err(&adapter->dev, "Not initialized\n");
+ return -EIO;
+ }
+
+ if (info->i2cdev->state != XenbusStateConnected) {
+ dev_err(&adapter->dev, "Not connected\n");
+ return -EIO;
+ }
+
+ for (i = 0; i < num; i++) {
+ if (msgs[i].flags & I2C_M_RD) {
+ ret = i2cfront_do_req(adapter, &msgs[i], 1);
+ } else if ((i + 1 < num) && (msgs[i + 1].flags & I2C_M_RD) &&
+ (msgs[i].addr == msgs[i + 1].addr)) {
+ ret = i2cfront_do_req(adapter, &msgs[i], 2);
+ i++;
+ } else {
+ ret = i2cfront_do_req(adapter, &msgs[i], 1);
+ }
+
+ if (ret < 0)
+ goto err;
+ }
+err:
+ return (ret < 0) ? ret : num;
+}
+
+static int i2cfront_smbus_xfer(struct i2c_adapter *adapter, u16 addr,
+ unsigned short flags, char read_write,
+ u8 command, int size, union i2c_smbus_data *data)
+{
+ struct i2cfront_info *info = i2c_get_adapdata(adapter);
+ struct i2cif_response *res;
+ struct i2cif_request *req;
+ unsigned long lock_flags;
+ int more_to_do = 0;
+ RING_IDX i, rp;
+ int notify;
+ int ret;
+
+ if (!info || !info->i2cdev) {
+ dev_err(&adapter->dev, "Not initialized\n");
+ return -EIO;
+ }
+
+ if (info->i2cdev->state != XenbusStateConnected) {
+ dev_err(&adapter->dev, "Not connected\n");
+ return -EIO;
+ }
+
+ mutex_lock(&info->xferlock);
+ req = RING_GET_REQUEST(&info->i2c_ring, info->i2c_ring.req_prod_pvt);
+
+ req->is_smbus = true;
+ req->addr = addr;
+ req->flags = flags;
+ req->read_write = read_write;
+ req->command = command;
+ req->protocol = size;
+ if (data != NULL)
+ memcpy(&req->write_buf, data, sizeof(union i2c_smbus_data));
+
+ spin_lock(&info->lock);
+ info->i2c_ring.req_prod_pvt++;
+ RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&info->i2c_ring, notify);
+ spin_unlock(&info->lock);
+ if (notify)
+ notify_remote_via_irq(info->irq);
+
+ wait_for_completion(&info->completion);
+
+ spin_lock_irqsave(&info->lock, lock_flags);
+ rp = info->i2c_ring.sring->rsp_prod;
+ rmb(); /* ensure we see queued responses up to "rp" */
+
+ ret = -EIO;
+ for (i = info->i2c_ring.rsp_cons; i != rp; i++) {
+ res = RING_GET_RESPONSE(&info->i2c_ring, i);
+
+ if (data != NULL && read_write == I2C_SMBUS_READ)
+ memcpy(data, &res->read_buf, sizeof(union i2c_smbus_data));
+
+ ret = res->result;
+ }
+
+ info->i2c_ring.rsp_cons = i;
+
+ if (i != info->i2c_ring.req_prod_pvt)
+ RING_FINAL_CHECK_FOR_RESPONSES(&info->i2c_ring, more_to_do);
+ else
+ info->i2c_ring.sring->rsp_event = i + 1;
+
+ spin_unlock_irqrestore(&info->lock, lock_flags);
+
+ mutex_unlock(&info->xferlock);
+
+ return ret;
+}
+
+static u32 i2cfront_func(struct i2c_adapter *adapter)
+{
+ return I2C_FUNC_I2C | I2C_FUNC_SMBUS_BYTE_DATA |
+ I2C_FUNC_SMBUS_BYTE | I2C_FUNC_SMBUS_WORD_DATA | I2C_FUNC_SMBUS_QUICK |
+ I2C_FUNC_SMBUS_BLOCK_DATA | I2C_FUNC_SMBUS_I2C_BLOCK;
+}
+
+static const struct i2c_algorithm i2cfront_algo = {
+ .master_xfer = i2cfront_xfer,
+ .smbus_xfer = i2cfront_smbus_xfer,
+ .functionality = i2cfront_func,
+};
+
+static int i2cfront_probe(struct xenbus_device *dev,
+ const struct xenbus_device_id *id)
+{
+ struct i2cfront_info *info;
+
+ info = kzalloc(sizeof(struct i2cfront_info), GFP_KERNEL);
+ if (!info)
+ return -ENOMEM;
+
+ info->i2cdev = dev;
+ dev_set_drvdata(&dev->dev, info);
+ info->adapter.owner = THIS_MODULE;
+ info->adapter.algo = &i2cfront_algo;
+ info->adapter.dev.parent = &dev->dev;
+ strlcpy(info->adapter.name, dev->nodename, sizeof(info->adapter.name));
+ i2c_set_adapdata(&info->adapter, info);
+ spin_lock_init(&info->lock);
+ mutex_init(&info->xferlock);
+ init_completion(&info->completion);
+
+ return 0;
+}
+
+static int i2cfront_handle_int(struct i2cfront_info *info)
+{
+ complete(&info->completion);
+
+ return 0;
+}
+
+static irqreturn_t i2cfront_int(int irq, void *dev_id)
+{
+ struct i2cfront_info *info = dev_id;
+
+ while (i2cfront_handle_int(info))
+ cond_resched();
+
+ return IRQ_HANDLED;
+}
+
+static int i2cfront_setup_rings(struct xenbus_device *dev,
+ struct i2cfront_info *info)
+{
+ struct i2cif_sring *i2c_sring;
+ grant_ref_t gref;
+ int err;
+
+ info->i2c_ring_ref = GRANT_INVALID_REF;
+ i2c_sring = (struct i2cif_sring *)get_zeroed_page(GFP_NOIO |
+ __GFP_HIGH);
+ if (!i2c_sring) {
+ xenbus_dev_fatal(dev, -ENOMEM, "allocating i2c sring");
+ return -ENOMEM;
+ }
+
+ SHARED_RING_INIT(i2c_sring);
+ FRONT_RING_INIT(&info->i2c_ring, i2c_sring, PAGE_SIZE);
+
+ err = xenbus_grant_ring(dev, i2c_sring, 1, &gref);
+ if (err < 0) {
+ free_page((unsigned long)i2c_sring);
+ info->i2c_ring.sring = NULL;
+ goto fail;
+ }
+ info->i2c_ring_ref = gref;
+
+ err = xenbus_alloc_evtchn(dev, &info->evtchn);
+ if (err) {
+ xenbus_dev_fatal(dev, err, "xenbus_alloc_evtchn");
+ goto fail;
+ }
+
+ err = bind_evtchn_to_irqhandler(info->evtchn, i2cfront_int, 0,
+ "xen_i2cif", info);
+ if (err <= 0) {
+ xenbus_dev_fatal(dev, err, "bind_evtchn_to_irqhandler failed");
+ goto fail;
+ }
+
+ info->irq = err;
+
+ return 0;
+
+fail:
+ i2cfront_destroy_rings(info);
+ return err;
+}
+
+static int i2cfront_connect(struct xenbus_device *dev)
+{
+ struct i2cfront_info *info = dev_get_drvdata(&dev->dev);
+ struct xenbus_transaction xbt;
+ struct device_node *np;
+ const char *be_adapter;
+ char xenstore_adapter[I2CIF_ADAPTER_NAME_LEN];
+ char *message;
+ int err;
+
+ err = i2cfront_setup_rings(dev, info);
+ if (err) {
+ dev_err(&dev->dev, "%s:failure....", __func__);
+ return err;
+ }
+again:
+ err = xenbus_transaction_start(&xbt);
+ if (err) {
+ xenbus_dev_fatal(dev, err, "starting transaction");
+ goto destroy_ring;
+ }
+
+ err = xenbus_printf(xbt, dev->nodename, "ring-ref", "%u",
+ info->i2c_ring_ref);
+ if (err) {
+ message = "writing i2c ring-ref";
+ goto abort_transaction;
+ }
+
+ err = xenbus_printf(xbt, dev->nodename, "event-channel", "%u",
+ info->evtchn);
+ if (err) {
+ message = "writing event-channel";
+ goto abort_transaction;
+ }
+
+ err = xenbus_scanf(xbt, dev->nodename,
+ "be-adapter", "%32s", xenstore_adapter);
+ if (err != 1) {
+ message = "getting be-adapter";
+ goto abort_transaction;
+ }
+
+ err = xenbus_transaction_end(xbt, 0);
+ if (err) {
+ if (err == -EAGAIN)
+ goto again;
+ xenbus_dev_fatal(dev, err, "completing transaction");
+ goto destroy_ring;
+ }
+
+ for_each_compatible_node(np, NULL, "xen,i2c") {
+ err = of_property_read_string(np, "be-adapter", &be_adapter);
+ if (err)
+ continue;
+ if (!strncmp(xenstore_adapter, be_adapter,
+ I2CIF_ADAPTER_NAME_LEN)) {
+ info->adapter.dev.of_node = np;
+ break;
+ }
+ }
+
+ err = i2c_add_adapter(&info->adapter);
+ if (err)
+ return err;
+
+ dev_info(&info->adapter.dev, "XEN I2C adapter registered\n");
+
+ return 0;
+
+abort_transaction:
+ xenbus_transaction_end(xbt, 1);
+ xenbus_dev_fatal(dev, err, "%s", message);
+
+destroy_ring:
+ i2cfront_destroy_rings(info);
+
+ return err;
+}
+
+static void i2cfront_disconnect(struct xenbus_device *dev)
+{
+ pr_info("%s\n", __func__);
+ xenbus_frontend_closed(dev);
+}
+
+static void i2cfront_backend_changed(struct xenbus_device *dev,
+ enum xenbus_state backend_state)
+{
+ switch (backend_state) {
+ case XenbusStateInitialising:
+ case XenbusStateReconfiguring:
+ case XenbusStateReconfigured:
+ case XenbusStateUnknown:
+ break;
+
+ case XenbusStateInitWait:
+ case XenbusStateInitialised:
+ case XenbusStateConnected:
+ if (dev->state != XenbusStateInitialising)
+ break;
+ if (!i2cfront_connect(dev))
+ xenbus_switch_state(dev, XenbusStateConnected);
+ break;
+
+ case XenbusStateClosed:
+ if (dev->state == XenbusStateClosed)
+ break;
+ /* Missed the backend's Closing state -- fallthrough */
+ case XenbusStateClosing:
+ i2cfront_disconnect(dev);
+ break;
+
+ default:
+ xenbus_dev_fatal(dev, -EINVAL, "saw state %d at frontend",
+ backend_state);
+ break;
+ }
+}
+
+static int i2cfront_remove(struct xenbus_device *dev)
+{
+ struct i2cfront_info *info = dev_get_drvdata(&dev->dev);
+
+ i2c_del_adapter(&info->adapter);
+ i2cfront_destroy_rings(info);
+
+ kfree(info);
+
+ dev_info(&dev->dev, "Remove");
+ return 0;
+}
+
+static const struct xenbus_device_id i2cfront_ids[] = {
+ { "vi2c" },
+ { "" },
+};
+
+static struct xenbus_driver i2cfront_driver = {
+ .ids = i2cfront_ids,
+ .probe = i2cfront_probe,
+ .otherend_changed = i2cfront_backend_changed,
+ .remove = i2cfront_remove,
+};
+
+static int __init i2cfront_init(void)
+{
+ if (!xen_domain())
+ return -ENODEV;
+
+ return xenbus_register_frontend(&i2cfront_driver);
+}
+subsys_initcall(i2cfront_init);
diff --git a/drivers/i2c/muxes/i2c-mux-pca954x.c b/drivers/i2c/muxes/i2c-mux-pca954x.c
index 7b992db38021..d7ba07b32546 100644
--- a/drivers/i2c/muxes/i2c-mux-pca954x.c
+++ b/drivers/i2c/muxes/i2c-mux-pca954x.c
@@ -63,6 +63,7 @@ enum pca_type {
pca_9546,
pca_9547,
pca_9548,
+ pca_9646,
};
struct chip_desc {
@@ -129,6 +130,10 @@ static const struct chip_desc chips[] = {
.nchans = 8,
.muxtype = pca954x_isswi,
},
+ [pca_9646] = {
+ .nchans = 4,
+ .muxtype = pca954x_isswi,
+ },
};
static const struct i2c_device_id pca954x_id[] = {
@@ -140,6 +145,7 @@ static const struct i2c_device_id pca954x_id[] = {
{ "pca9546", pca_9546 },
{ "pca9547", pca_9547 },
{ "pca9548", pca_9548 },
+ { "pca9646", pca_9646 },
{ }
};
MODULE_DEVICE_TABLE(i2c, pca954x_id);
@@ -154,6 +160,7 @@ static const struct of_device_id pca954x_of_match[] = {
{ .compatible = "nxp,pca9546", .data = &chips[pca_9546] },
{ .compatible = "nxp,pca9547", .data = &chips[pca_9547] },
{ .compatible = "nxp,pca9548", .data = &chips[pca_9548] },
+ { .compatible = "nxp,pca9646", .data = &chips[pca_9646] },
{}
};
MODULE_DEVICE_TABLE(of, pca954x_of_match);
diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig
index 369a2c632e46..79567542595b 100644
--- a/drivers/iio/adc/Kconfig
+++ b/drivers/iio/adc/Kconfig
@@ -355,6 +355,16 @@ config IMX7D_ADC
This driver can also be built as a module. If so, the module will be
called imx7d_adc.
+config IMX8QXP_ADC
+ tristate "IMX8QXP ADC driver"
+ depends on ARCH_MXC_ARM64 || COMPILE_TEST
+ depends on HAS_IOMEM
+ help
+ Say yes here to build support for IMX8QXP ADC.
+
+ This driver can also be built as a module. If so, the module will be
+ called imx8qxp_adc.
+
config LP8788_ADC
tristate "LP8788 ADC driver"
depends on MFD_LP8788
diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile
index 9572c1090f35..8a2c01d24767 100644
--- a/drivers/iio/adc/Makefile
+++ b/drivers/iio/adc/Makefile
@@ -33,6 +33,7 @@ obj-$(CONFIG_FSL_MX25_ADC) += fsl-imx25-gcq.o
obj-$(CONFIG_HI8435) += hi8435.o
obj-$(CONFIG_HX711) += hx711.o
obj-$(CONFIG_IMX7D_ADC) += imx7d_adc.o
+obj-$(CONFIG_IMX8QXP_ADC) += imx8qxp_adc.o
obj-$(CONFIG_INA2XX_ADC) += ina2xx-adc.o
obj-$(CONFIG_LP8788_ADC) += lp8788_adc.o
obj-$(CONFIG_LPC18XX_ADC) += lpc18xx_adc.o
diff --git a/drivers/iio/adc/imx8qxp_adc.c b/drivers/iio/adc/imx8qxp_adc.c
new file mode 100644
index 000000000000..7408fce6cdd8
--- /dev/null
+++ b/drivers/iio/adc/imx8qxp_adc.c
@@ -0,0 +1,724 @@
+/*
+ * NXP i.MX8QXP ADC driver
+ *
+ * Copyright (C) 2018 NXP
+ *
+ * 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/clk.h>
+#include <linux/completion.h>
+#include <linux/err.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/module.h>
+#include <linux/pm_runtime.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/consumer.h>
+
+#include <linux/iio/iio.h>
+#include <linux/iio/driver.h>
+#include <linux/iio/sysfs.h>
+
+/* ADC register */
+#define IMX8QXP_REG_ADC_VERID 0x00
+#define IMX8QXP_REG_ADC_PARAM 0x04
+#define IMX8QXP_REG_ADC_CTRL 0x10
+#define IMX8QXP_REG_ADC_STAT 0x14
+#define IMX8QXP_REG_ADC_IE 0x18
+#define IMX8QXP_REG_ADC_DE 0x1c
+#define IMX8QXP_REG_ADC_CFG 0x20
+#define IMX8QXP_REG_ADC_PAUSE 0x24
+#define IMX8QXP_REG_ADC_FCTRL 0x30
+#define IMX8QXP_REG_ADC_SWTRIG 0x34
+#define IMX8QXP_REG_ADC_TCTRL0 0xc0
+#define IMX8QXP_REG_ADC_TCTRL1 0xc4
+#define IMX8QXP_REG_ADC_TCTRL2 0xc8
+#define IMX8QXP_REG_ADC_TCTRL3 0xcc
+#define IMX8QXP_REG_ADC_TCTRL4 0xd0
+#define IMX8QXP_REG_ADC_TCTRL5 0xd4
+#define IMX8QXP_REG_ADC_TCTRL6 0xd8
+#define IMX8QXP_REG_ADC_TCTRL7 0xdc
+#define IMX8QXP_REG_ADC_CMDL1 0x100
+#define IMX8QXP_REG_ADC_CMDH1 0x104
+#define IMX8QXP_REG_ADC_CMDL2 0x108
+#define IMX8QXP_REG_ADC_CMDH2 0x10c
+#define IMX8QXP_REG_ADC_CMDL3 0x110
+#define IMX8QXP_REG_ADC_CMDH3 0x114
+#define IMX8QXP_REG_ADC_CMDL4 0x118
+#define IMX8QXP_REG_ADC_CMDH4 0x11c
+#define IMX8QXP_REG_ADC_CMDL5 0x120
+#define IMX8QXP_REG_ADC_CMDH5 0x124
+#define IMX8QXP_REG_ADC_CMDL6 0x128
+#define IMX8QXP_REG_ADC_CMDH6 0x12c
+#define IMX8QXP_REG_ADC_CMDL7 0x130
+#define IMX8QXP_REG_ADC_CMDH7 0x134
+#define IMX8QXP_REG_ADC_CMDL8 0x138
+#define IMX8QXP_REG_ADC_CMDH8 0x13c
+#define IMX8QXP_REG_ADC_CV1 0x200
+#define IMX8QXP_REG_ADC_CV2 0x204
+#define IMX8QXP_REG_ADC_CV3 0x208
+#define IMX8QXP_REG_ADC_CV4 0x20c
+#define IMX8QXP_REG_ADC_RESFIFO 0x300
+#define IMX8QXP_REG_ADC_TST 0xffc
+
+/* ADC IE bit shift */
+#define IMX8QXP_REG_ADC_IE_FOFIE_SHIFT (1)
+#define IMX8QXP_REG_ADC_IE_FWMIE_SHIFT (0)
+/* ADC CTRL bit shift*/
+#define IMX8QXP_REG_ADC_CTRL_FIFO_RESET_SHIFT (8)
+#define IMX8QXP_REG_ADC_CTRL_SOFTWARE_RESET_SHIFT (1)
+#define IMX8QXP_REG_ADC_CTRL_ADC_ENABLE (0)
+/* ADC TCTRL bit shift*/
+#define IMX8QXP_REG_ADC_TCTRL_TCMD_SHIFT (24)
+#define IMX8QXP_REG_ADC_TCTRL_TDLY_SHIFT (16)
+#define IMX8QXP_REG_ADC_TCTRL_TPRI_SHIFT (8)
+#define IMX8QXP_REG_ADC_TCTRL_HTEN_SHIFT (0)
+/* ADC CMDL bit shift*/
+#define IMX8QXP_REG_ADC_CMDL_CSCALE_SHIFT (8)
+#define IMX8QXP_REG_ADC_CMDL_MODE_SHIFT (7)
+#define IMX8QXP_REG_ADC_CMDL_DIFF_SHIFT (6)
+#define IMX8QXP_REG_ADC_CMDL_ABSEL_SHIFT (5)
+#define IMX8QXP_REG_ADC_CMDL_ADCH_SHIFT (0)
+/* ADC CMDH bit shift*/
+#define IMX8QXP_REG_ADC_CMDH_NEXT_SHIFT (24)
+#define IMX8QXP_REG_ADC_CMDH_LOOP_SHIFT (16)
+#define IMX8QXP_REG_ADC_CMDH_AVGS_SHIFT (12)
+#define IMX8QXP_REG_ADC_CMDH_STS_SHIFT (8)
+#define IMX8QXP_REG_ADC_CMDH_LWI_SHIFT (7)
+#define IMX8QXP_REG_ADC_CMDH_CMPEN_SHIFT (0)
+/* ADC CFG bit shift*/
+#define IMX8QXP_REG_ADC_CFG_PWREN_SHIFT (28)
+#define IMX8QXP_REG_ADC_CFG_PUDLY_SHIFT (16)
+#define IMX8QXP_REG_ADC_CFG_REFSEL_SHIFT (6)
+#define IMX8QXP_REG_ADC_CFG_PWRSEL_SHIFT (4)
+#define IMX8QXP_REG_ADC_CFG_TPRICTRL_SHIFT (0)
+/* ADC FCTRL bit shift*/
+#define IMX8QXP_ADC_FCTRL_FWMARK_SHIFT (16)
+#define IMX8QXP_ADC_FCTRL_FWMARK_MASK (0x1f << 16)
+#define IMX8QXP_ADC_FCTRL_FCOUNT_MASK (0x1f)
+/* ADC STAT bit shift*/
+#define IMX8QXP_REG_ADC_STAT_CMDACT_SHIFT (24)
+#define IMX8QXP_REG_ADC_STAT_TRGACT_SHIFT (16)
+#define IMX8QXP_REG_ADC_STAT_FOF_SHIFT (1)
+#define IMX8QXP_REG_ADC_STAT_RDY_SHIFT (0)
+
+/* ADC CMD PARAMETER*/
+#define IMX8QXP_REG_ADC_CMDL_CNANNEL_SCALE_DOWN (0)
+#define IMX8QXP_REG_ADC_CMDL_CHANNEL_SCALE_FULL (0x3f)
+#define IMX8QXP_REG_ADC_CMDL_SEL_A_A_B_CHANNEL (0)
+#define IMX8QXP_REG_ADC_CMDL_SEL_B_B_A_CHANNEL (1)
+#define IMX8QXP_REG_ADC_CMDL_STANDARD_RESOLUTION (0)
+#define IMX8QXP_REG_ADC_CMDL_HIGH_RESOLUTION (1)
+#define IMX8QXP_REG_ADC_CMDL_MODE_SINGLE (0)
+#define IMX8QXP_REG_ADC_CMDL_MODE_DIFF (1)
+
+#define IMX8QXP_REG_ADC_CMDH_LWI_INCREMENT_ENABLE (1)
+#define IMX8QXP_REG_ADC_CMDH_LWI_INCREMENT_DISABLE (0)
+#define IMX8QXP_REG_ADC_CMDH_CMPEN_DISABLE (0)
+#define IMX8QXP_REG_ADC_CMDH_CMPEN_ENABLE_TRUE (2)
+#define IMX8QXP_REG_ADC_CMDH_CMPEN_ENABLE_UNTILE_TRUE (0x3)
+
+/* ADC PAUSE PARAMETER*/
+#define IMX8QXP_REG_ADC_PAUSE_ENABLE (0x80000000)
+/* ADC TRIGGER PARAMETER*/
+#define IMX8QXP_REG_ADC_TCTRL_TPRI_PRIORITY_HIGH (0)
+#define IMX8QXP_REG_ADC_TCTRL_TPRI_PRIORITY_LOW (1)
+
+#define IMX8QXP_REG_ADC_TCTRL_HTEN_HARDWARE_TIRGGER_DISABLE (0)
+#define IMX8QXP_REG_ADC_TCTRC_HTEN_HARDWARE_TIRGGER_ENABLE (1)
+
+#define MAX_CMD (8)
+#define MAX_TRIG (8)
+
+#define IMX8QXP_ADC_TIMEOUT msecs_to_jiffies(100)
+
+struct imx8qxp_adc_trigger_ctrl {
+ u32 tcmd;
+ u32 tdly;
+ u32 tpri;
+ u32 hten;
+};
+
+struct imx8qxp_adc_cmd_l {
+ u32 scale;
+ u32 mode;
+ u32 diff;
+ u32 absel;
+ u32 adch;
+};
+
+struct imx8qxp_adc_cmd_h {
+ u32 next;
+ u32 loop;
+ u32 avgs;
+ u32 sts;
+ u32 lwi;
+ u32 cmpen;
+};
+
+struct imx8qxp_adc_cfg {
+ u32 pwren;
+ u32 pudly;
+ u32 refsel;
+ u32 pwrsel;
+ u32 tprictrl;
+};
+
+struct imx8qxp_adc {
+ struct device *dev;
+ void __iomem *regs;
+ struct clk *clk;
+ struct clk *ipg_clk;
+
+ u32 vref_uv;
+ u32 value;
+ u32 channel_id;
+ u32 trigger_id;
+ u32 cmd_id;
+
+ struct regulator *vref;
+ struct imx8qxp_adc_cmd_l adc_cmd_l[MAX_CMD + 1];
+ struct imx8qxp_adc_cmd_h adc_cmd_h[MAX_CMD + 1];
+ struct imx8qxp_adc_trigger_ctrl adc_trigger_ctrl[MAX_TRIG + 1];
+ struct imx8qxp_adc_cfg adc_cfg;
+ struct completion completion;
+};
+
+#define IMX8QXP_ADC_CHAN(_idx) { \
+ .type = IIO_VOLTAGE, \
+ .indexed = 1, \
+ .channel = (_idx), \
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
+ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | \
+ BIT(IIO_CHAN_INFO_SAMP_FREQ), \
+}
+
+static const struct iio_chan_spec imx8qxp_adc_iio_channels[] = {
+ IMX8QXP_ADC_CHAN(0),
+ IMX8QXP_ADC_CHAN(1),
+ IMX8QXP_ADC_CHAN(2),
+ IMX8QXP_ADC_CHAN(3),
+ IMX8QXP_ADC_CHAN(4),
+ IMX8QXP_ADC_CHAN(5),
+ IMX8QXP_ADC_CHAN(6),
+ IMX8QXP_ADC_CHAN(7),
+};
+
+static void imx8qxp_adc_feature_prepare(struct imx8qxp_adc *adc)
+{
+ u32 i;
+
+ adc->trigger_id = 0;
+ adc->cmd_id = 0;
+ adc->channel_id = 0;
+
+ for (i = 0; i < MAX_CMD + 1; i++) {
+ adc->adc_cmd_l[i].scale = 1;
+ adc->adc_cmd_l[i].mode = 0;
+ adc->adc_cmd_l[i].diff = 0;
+ adc->adc_cmd_l[i].absel = 0;
+ adc->adc_cmd_l[i].adch = 0;
+ adc->adc_cmd_h[i].next = 0;
+ adc->adc_cmd_h[i].loop = 0;
+ adc->adc_cmd_h[i].avgs = 0;
+ adc->adc_cmd_h[i].sts = 0;
+ adc->adc_cmd_h[i].lwi = 0;
+ adc->adc_cmd_h[i].cmpen = 0;
+ }
+
+ for (i = 0; i < MAX_TRIG; i++) {
+ adc->adc_trigger_ctrl[i].tcmd = 0;
+ adc->adc_trigger_ctrl[i].tdly = 0;
+ adc->adc_trigger_ctrl[i].tpri = 0;
+ adc->adc_trigger_ctrl[i].hten = 0;
+ }
+
+ adc->adc_cfg.pwren = 0;
+ adc->adc_cfg.pudly = 0;
+ adc->adc_cfg.refsel = 0;
+ adc->adc_cfg.pwrsel = 0;
+ adc->adc_cfg.tprictrl = 0;
+}
+
+static void imx8qxp_adc_reset(struct imx8qxp_adc *adc)
+{
+ u32 ctrl;
+
+ /*software reset, need to clear the set bit*/
+ ctrl = readl(adc->regs + IMX8QXP_REG_ADC_CTRL);
+ ctrl |= 1 << IMX8QXP_REG_ADC_CTRL_SOFTWARE_RESET_SHIFT;
+ writel(ctrl, adc->regs + IMX8QXP_REG_ADC_CTRL);
+ udelay(10);
+ ctrl &= ~(1 << IMX8QXP_REG_ADC_CTRL_SOFTWARE_RESET_SHIFT);
+ writel(ctrl, adc->regs + IMX8QXP_REG_ADC_CTRL);
+
+ /* reset the fifo */
+ ctrl |= 1 << IMX8QXP_REG_ADC_CTRL_FIFO_RESET_SHIFT;
+ writel(ctrl, adc->regs + IMX8QXP_REG_ADC_CTRL);
+}
+
+static void imx8qxp_adc_reg_config(struct imx8qxp_adc *adc)
+{
+ u32 adc_cfg, adc_tctrl, adc_cmdl, adc_cmdh;
+ u32 t_id, c_id;
+
+ adc_cfg = adc->adc_cfg.pwren << IMX8QXP_REG_ADC_CFG_PWREN_SHIFT
+ | adc->adc_cfg.pudly << IMX8QXP_REG_ADC_CFG_PUDLY_SHIFT
+ | adc->adc_cfg.refsel << IMX8QXP_REG_ADC_CFG_REFSEL_SHIFT
+ | adc->adc_cfg.pwrsel << IMX8QXP_REG_ADC_CFG_PWRSEL_SHIFT
+ | adc->adc_cfg.tprictrl << IMX8QXP_REG_ADC_CFG_TPRICTRL_SHIFT;
+ writel(adc_cfg, adc->regs + IMX8QXP_REG_ADC_CFG);
+
+ t_id = adc->trigger_id;
+ adc_tctrl = adc->adc_trigger_ctrl[t_id].tcmd << IMX8QXP_REG_ADC_TCTRL_TCMD_SHIFT
+ | adc->adc_trigger_ctrl[t_id].tdly << IMX8QXP_REG_ADC_TCTRL_TDLY_SHIFT
+ | adc->adc_trigger_ctrl[t_id].tpri << IMX8QXP_REG_ADC_TCTRL_TPRI_SHIFT
+ | adc->adc_trigger_ctrl[t_id].hten << IMX8QXP_REG_ADC_TCTRL_HTEN_SHIFT;
+ writel(adc_tctrl, adc->regs + IMX8QXP_REG_ADC_TCTRL0 + t_id * 4);
+
+ c_id = adc->cmd_id - 1;
+ adc_cmdl = adc->adc_cmd_l[c_id].scale << IMX8QXP_REG_ADC_CMDL_CSCALE_SHIFT
+ | adc->adc_cmd_l[c_id].mode << IMX8QXP_REG_ADC_CMDL_MODE_SHIFT
+ | adc->adc_cmd_l[c_id].diff << IMX8QXP_REG_ADC_CMDL_DIFF_SHIFT
+ | adc->adc_cmd_l[c_id].absel << IMX8QXP_REG_ADC_CMDL_ABSEL_SHIFT
+ | adc->adc_cmd_l[c_id].adch << IMX8QXP_REG_ADC_CMDL_ADCH_SHIFT;
+ writel(adc_cmdl, adc->regs + IMX8QXP_REG_ADC_CMDL1 + c_id * 8);
+
+ adc_cmdh = adc->adc_cmd_h[c_id].next << IMX8QXP_REG_ADC_CMDH_NEXT_SHIFT
+ | adc->adc_cmd_h[c_id].loop << IMX8QXP_REG_ADC_CMDH_LOOP_SHIFT
+ | adc->adc_cmd_h[c_id].avgs << IMX8QXP_REG_ADC_CMDH_AVGS_SHIFT
+ | adc->adc_cmd_h[c_id].sts << IMX8QXP_REG_ADC_CMDH_STS_SHIFT
+ | adc->adc_cmd_h[c_id].lwi << IMX8QXP_REG_ADC_CMDH_LWI_SHIFT
+ | adc->adc_cmd_h[c_id].cmpen << IMX8QXP_REG_ADC_CMDH_CMPEN_SHIFT;
+ writel(adc_cmdh, adc->regs + IMX8QXP_REG_ADC_CMDH1 + c_id * 8);
+}
+
+static void imx8qxp_adc_mode_config(struct imx8qxp_adc *adc)
+{
+ u32 cmd_id, trigger_id, channel_id;
+
+ channel_id = adc->channel_id;
+ cmd_id = adc->cmd_id - 1;
+ trigger_id = adc->trigger_id;
+
+ /* config the cmd */
+ adc->adc_cmd_l[cmd_id].scale = IMX8QXP_REG_ADC_CMDL_CHANNEL_SCALE_FULL;
+ adc->adc_cmd_l[cmd_id].mode = IMX8QXP_REG_ADC_CMDL_STANDARD_RESOLUTION;
+ adc->adc_cmd_l[cmd_id].diff = IMX8QXP_REG_ADC_CMDL_MODE_SINGLE;
+ adc->adc_cmd_l[cmd_id].absel = IMX8QXP_REG_ADC_CMDL_SEL_A_A_B_CHANNEL;
+ adc->adc_cmd_l[cmd_id].adch = channel_id;
+
+ adc->adc_cmd_h[cmd_id].next = 0;
+ adc->adc_cmd_h[cmd_id].loop = 0;
+ adc->adc_cmd_h[cmd_id].avgs = 7; // 128 times conversion
+ adc->adc_cmd_h[cmd_id].sts = 0;
+ adc->adc_cmd_h[cmd_id].lwi = IMX8QXP_REG_ADC_CMDH_LWI_INCREMENT_DISABLE;
+ adc->adc_cmd_h[cmd_id].cmpen = IMX8QXP_REG_ADC_CMDH_CMPEN_DISABLE;
+
+ /* config the trigger control */
+ adc->adc_trigger_ctrl[trigger_id].tcmd = adc->cmd_id; //point to cmd1
+ adc->adc_trigger_ctrl[trigger_id].tdly = 0;
+ adc->adc_trigger_ctrl[trigger_id].tpri = IMX8QXP_REG_ADC_TCTRL_TPRI_PRIORITY_HIGH;
+ adc->adc_trigger_ctrl[trigger_id].hten = IMX8QXP_REG_ADC_TCTRL_HTEN_HARDWARE_TIRGGER_DISABLE;
+
+ /* ADC configuration */
+ adc->adc_cfg.pwren = 1;
+ adc->adc_cfg.pudly = 0x80;
+ adc->adc_cfg.refsel = 0;
+ adc->adc_cfg.pwrsel = 3;
+ adc->adc_cfg.tprictrl = 0;
+
+ imx8qxp_adc_reg_config(adc);
+}
+
+static void imx8qxp_adc_fifo_config(struct imx8qxp_adc *adc)
+{
+ u32 fifo_ctrl, interrupt_en;
+
+ fifo_ctrl = readl(adc->regs + IMX8QXP_REG_ADC_FCTRL);
+ fifo_ctrl &= ~IMX8QXP_ADC_FCTRL_FWMARK_MASK;
+ /* set the watermark level to 1 */
+ fifo_ctrl |= 0 << IMX8QXP_ADC_FCTRL_FWMARK_SHIFT;
+ writel(fifo_ctrl, adc->regs + IMX8QXP_REG_ADC_FCTRL);
+
+ /* FIFO Watermark Interrupt Enable */
+ interrupt_en = readl(adc->regs + IMX8QXP_REG_ADC_IE);
+ interrupt_en |= 1 << IMX8QXP_REG_ADC_IE_FWMIE_SHIFT;
+ writel(interrupt_en, adc->regs + IMX8QXP_REG_ADC_IE);
+}
+
+static void imx8qxp_adc_disable(struct imx8qxp_adc *adc)
+{
+ u32 ctrl;
+
+ ctrl = readl(adc->regs + IMX8QXP_REG_ADC_CTRL);
+ ctrl &= ~(1 << IMX8QXP_REG_ADC_CTRL_ADC_ENABLE);
+ writel(ctrl, adc->regs + IMX8QXP_REG_ADC_CTRL);
+}
+
+static void imx8qxp_adc_enable(struct imx8qxp_adc *adc)
+{
+ u32 ctrl;
+
+ ctrl = readl(adc->regs + IMX8QXP_REG_ADC_CTRL);
+ ctrl |= 1 << IMX8QXP_REG_ADC_CTRL_ADC_ENABLE;
+ writel(ctrl, adc->regs + IMX8QXP_REG_ADC_CTRL);
+
+}
+
+static void imx8qxp_adc_start_trigger(struct imx8qxp_adc *adc)
+{
+ writel(1 << adc->trigger_id, adc->regs + IMX8QXP_REG_ADC_SWTRIG);
+}
+
+static u32 imx8qxp_adc_get_sample_rate(struct imx8qxp_adc *adc)
+{
+
+ u32 input_clk;
+
+ input_clk = clk_get_rate(adc->clk);
+
+ return input_clk / 3;
+}
+
+static int imx8qxp_adc_read_raw(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan,
+ int *val,
+ int *val2,
+ long mask)
+{
+
+ struct imx8qxp_adc *adc = iio_priv(indio_dev);
+
+ u32 channel;
+ long ret;
+
+ switch (mask) {
+ case IIO_CHAN_INFO_RAW:
+ pm_runtime_get_sync(adc->dev);
+
+ mutex_lock(&indio_dev->mlock);
+ reinit_completion(&adc->completion);
+
+ channel = chan->channel & 0x07;
+ adc->channel_id = channel;
+ adc->cmd_id = 1;
+ adc->trigger_id = 0;
+ imx8qxp_adc_mode_config(adc);
+
+ imx8qxp_adc_fifo_config(adc);
+
+ imx8qxp_adc_enable(adc);
+
+ imx8qxp_adc_start_trigger(adc);
+
+ ret = wait_for_completion_interruptible_timeout
+ (&adc->completion, IMX8QXP_ADC_TIMEOUT);
+
+ pm_runtime_mark_last_busy(adc->dev);
+ pm_runtime_put_sync_autosuspend(adc->dev);
+
+ if (ret == 0) {
+ mutex_unlock(&indio_dev->mlock);
+ return -ETIMEDOUT;
+ }
+ if (ret < 0) {
+ mutex_unlock(&indio_dev->mlock);
+ return ret;
+ }
+
+ *val = adc->value;
+ mutex_unlock(&indio_dev->mlock);
+ return IIO_VAL_INT;
+
+ case IIO_CHAN_INFO_SCALE:
+ adc->vref_uv = regulator_get_voltage(adc->vref);
+ *val = adc->vref_uv / 1000;
+ *val2 = 12;
+ return IIO_VAL_FRACTIONAL_LOG2;
+
+ case IIO_CHAN_INFO_SAMP_FREQ:
+ *val = imx8qxp_adc_get_sample_rate(adc);
+ return IIO_VAL_INT;
+
+ default:
+ return -EINVAL;
+ }
+}
+
+static int imx8qxp_adc_read_data(struct imx8qxp_adc *adc)
+{
+ u32 value;
+
+ value = readl(adc->regs + IMX8QXP_REG_ADC_RESFIFO);
+ value &= 0xffff;
+ return (value >> 3);
+}
+
+static irqreturn_t imx8qxp_adc_isr(int irq, void *dev_id)
+{
+ struct imx8qxp_adc *adc = (struct imx8qxp_adc *)dev_id;
+
+ u32 fifo_count;
+
+ fifo_count = readl(adc->regs + IMX8QXP_REG_ADC_FCTRL)
+ & IMX8QXP_ADC_FCTRL_FCOUNT_MASK;
+
+ if (fifo_count) {
+ adc->value = imx8qxp_adc_read_data(adc);
+ complete(&adc->completion);
+ }
+
+ return IRQ_HANDLED;
+}
+
+static int imx8qxp_adc_reg_access(struct iio_dev *indio_dev,
+ unsigned int reg, unsigned int writeval,
+ unsigned int *readval)
+{
+ struct imx8qxp_adc *adc = iio_priv(indio_dev);
+
+ if (!readval || reg % 4 || reg > IMX8QXP_REG_ADC_TST)
+ return -EINVAL;
+
+ pm_runtime_get_sync(adc->dev);
+
+ *readval = readl(adc->regs + reg);
+
+ pm_runtime_mark_last_busy(adc->dev);
+ pm_runtime_put_sync_autosuspend(adc->dev);
+
+ return 0;
+}
+
+static const struct iio_info imx8qxp_adc_iio_info = {
+ .driver_module = THIS_MODULE,
+ .read_raw = &imx8qxp_adc_read_raw,
+ .debugfs_reg_access = &imx8qxp_adc_reg_access,
+};
+
+static const struct of_device_id imx8qxp_adc_match[] = {
+ { .compatible = "fsl,imx8qxp-adc", },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, imx8qxp_adc_match);
+
+static int imx8qxp_adc_probe(struct platform_device *pdev)
+{
+ struct imx8qxp_adc *adc;
+ struct iio_dev *indio_dev;
+ struct resource *mem;
+ int irq;
+ int ret;
+
+ indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*adc));
+ if (!indio_dev) {
+ dev_err(&pdev->dev, "Failed allocating iio device\n");
+ return -ENOMEM;
+ }
+
+ adc = iio_priv(indio_dev);
+ adc->dev = &pdev->dev;
+
+ mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ adc->regs = devm_ioremap_resource(&pdev->dev, mem);
+ if (IS_ERR(adc->regs)) {
+ ret = PTR_ERR(adc->regs);
+ dev_err(&pdev->dev,
+ "Failed to remap adc memory, err = %d\n", ret);
+ return ret;
+ }
+
+ irq = platform_get_irq(pdev, 0);
+ if (irq < 0) {
+ dev_err(&pdev->dev, "No irq resource?\n");
+ return irq;
+ }
+
+ adc->clk = devm_clk_get(&pdev->dev, "per");
+ if (IS_ERR(adc->clk)) {
+ ret = PTR_ERR(adc->clk);
+ dev_err(&pdev->dev, "Failed getting clock, err = %d\n", ret);
+ return ret;
+ }
+
+ adc->ipg_clk = devm_clk_get(&pdev->dev, "ipg");
+ if (IS_ERR(adc->ipg_clk)) {
+ ret = PTR_ERR(adc->ipg_clk);
+ dev_err(&pdev->dev, "Failed getting clock, err = %d\n", ret);
+ return ret;
+ }
+
+ adc->vref = devm_regulator_get(&pdev->dev, "vref");
+ if (IS_ERR(adc->vref)) {
+ ret = PTR_ERR(adc->vref);
+ dev_err(&pdev->dev,
+ "Failed getting reference voltage, err = %d\n", ret);
+ return ret;
+ }
+
+ ret = regulator_enable(adc->vref);
+ if (ret) {
+ dev_err(&pdev->dev,
+ "Can't enable adc reference top voltage, err = %d\n",
+ ret);
+ return ret;
+ }
+
+ platform_set_drvdata(pdev, indio_dev);
+
+ init_completion(&adc->completion);
+
+ indio_dev->name = dev_name(&pdev->dev);
+ indio_dev->dev.parent = &pdev->dev;
+ indio_dev->info = &imx8qxp_adc_iio_info;
+ indio_dev->modes = INDIO_DIRECT_MODE;
+ indio_dev->channels = imx8qxp_adc_iio_channels;
+ indio_dev->num_channels = ARRAY_SIZE(imx8qxp_adc_iio_channels);
+
+ ret = clk_prepare_enable(adc->clk);
+ if (ret) {
+ dev_err(&pdev->dev,
+ "Could not prepare or enable the clock.\n");
+ goto error_adc_clk_enable;
+ }
+
+ ret = clk_prepare_enable(adc->ipg_clk);
+ if (ret) {
+ dev_err(&pdev->dev,
+ "Could not prepare or enable the clock.\n");
+ goto error_adc_ipg_clk_enable;
+ }
+
+ ret = devm_request_irq(adc->dev, irq,
+ imx8qxp_adc_isr, 0,
+ dev_name(&pdev->dev), adc);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "Failed requesting irq, irq = %d\n", irq);
+ goto error_iio_device_register;
+ }
+
+ imx8qxp_adc_feature_prepare(adc);
+ imx8qxp_adc_reset(adc);
+
+ ret = iio_device_register(indio_dev);
+ if (ret) {
+ imx8qxp_adc_disable(adc);
+ dev_err(&pdev->dev, "Couldn't register the device.\n");
+ goto error_iio_device_register;
+ }
+
+ pm_runtime_set_active(&pdev->dev);
+ pm_runtime_set_autosuspend_delay(&pdev->dev, 50);
+ pm_runtime_use_autosuspend(&pdev->dev);
+ pm_runtime_enable(&pdev->dev);
+
+ return 0;
+
+error_iio_device_register:
+ clk_disable_unprepare(adc->ipg_clk);
+error_adc_ipg_clk_enable:
+ clk_disable_unprepare(adc->clk);
+error_adc_clk_enable:
+ regulator_disable(adc->vref);
+
+ return ret;
+}
+
+static int imx8qxp_adc_remove(struct platform_device *pdev)
+{
+ struct iio_dev *indio_dev = platform_get_drvdata(pdev);
+ struct imx8qxp_adc *adc = iio_priv(indio_dev);
+
+ pm_runtime_get_sync(&pdev->dev);
+
+ iio_device_unregister(indio_dev);
+
+ imx8qxp_adc_disable(adc);
+
+ clk_disable_unprepare(adc->clk);
+ clk_disable_unprepare(adc->ipg_clk);
+ regulator_disable(adc->vref);
+
+ pm_runtime_disable(&pdev->dev);
+ pm_runtime_put_noidle(&pdev->dev);
+
+
+ return 0;
+}
+
+static int imx8qxp_adc_runtime_suspend(struct device *dev)
+{
+ struct iio_dev *indio_dev = dev_get_drvdata(dev);
+ struct imx8qxp_adc *adc = iio_priv(indio_dev);
+
+ imx8qxp_adc_disable(adc);
+
+ clk_disable_unprepare(adc->clk);
+ clk_disable_unprepare(adc->ipg_clk);
+ regulator_disable(adc->vref);
+
+ return 0;
+}
+
+static int imx8qxp_adc_runtime_resume(struct device *dev)
+{
+ struct iio_dev *indio_dev = dev_get_drvdata(dev);
+ struct imx8qxp_adc *adc = iio_priv(indio_dev);
+ int ret;
+
+ ret = regulator_enable(adc->vref);
+ if (ret) {
+ dev_err(adc->dev,
+ "Can't enable adc reference top voltage, err = %d\n",
+ ret);
+ return ret;
+ }
+
+ ret = clk_prepare_enable(adc->clk);
+ if (ret) {
+ dev_err(adc->dev,
+ "Could not prepare or enable clock.\n");
+ regulator_disable(adc->vref);
+ return ret;
+ }
+
+ ret = clk_prepare_enable(adc->ipg_clk);
+ if (ret) {
+ dev_err(adc->dev,
+ "Could not prepare or enable clock.\n");
+ clk_disable_unprepare(adc->clk);
+ regulator_disable(adc->vref);
+ return ret;
+ }
+ imx8qxp_adc_reset(adc);
+
+ return 0;
+}
+
+static const struct dev_pm_ops imx8qxp_adc_pm_ops = {
+ SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, pm_runtime_force_resume)
+ SET_RUNTIME_PM_OPS(imx8qxp_adc_runtime_suspend, imx8qxp_adc_runtime_resume, NULL)
+};
+
+static struct platform_driver imx8qxp_adc_driver = {
+ .probe = imx8qxp_adc_probe,
+ .remove = imx8qxp_adc_remove,
+ .driver = {
+ .name = "imx8qxp_adc",
+ .of_match_table = imx8qxp_adc_match,
+ .pm = &imx8qxp_adc_pm_ops,
+ },
+};
+
+module_platform_driver(imx8qxp_adc_driver);
+
+MODULE_AUTHOR("Haibo Chen <haibo.chen@nxp.com>");
+MODULE_DESCRIPTION("NXP IMX8QXP ADC driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/iio/adc/vf610_adc.c b/drivers/iio/adc/vf610_adc.c
index c168e0db329a..1c5428f85362 100644
--- a/drivers/iio/adc/vf610_adc.c
+++ b/drivers/iio/adc/vf610_adc.c
@@ -1,7 +1,7 @@
/*
* Freescale Vybrid vf610 ADC driver
*
- * Copyright 2013 Freescale Semiconductor, Inc.
+ * Copyright 2013-2015 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
@@ -819,6 +819,7 @@ static int vf610_adc_probe(struct platform_device *pdev)
struct resource *mem;
int irq;
int ret;
+ u32 channels;
indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(struct vf610_adc));
if (!indio_dev) {
@@ -877,13 +878,18 @@ static int vf610_adc_probe(struct platform_device *pdev)
init_completion(&info->completion);
+ ret = of_property_read_u32(pdev->dev.of_node,
+ "num-channels", &channels);
+ if (ret)
+ channels = ARRAY_SIZE(vf610_adc_iio_channels);
+
indio_dev->name = dev_name(&pdev->dev);
indio_dev->dev.parent = &pdev->dev;
indio_dev->dev.of_node = pdev->dev.of_node;
indio_dev->info = &vf610_adc_iio_info;
indio_dev->modes = INDIO_DIRECT_MODE;
indio_dev->channels = vf610_adc_iio_channels;
- indio_dev->num_channels = ARRAY_SIZE(vf610_adc_iio_channels);
+ indio_dev->num_channels = (int)channels;
ret = clk_prepare_enable(info->clk);
if (ret) {
diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig
index 4c4ab1ced235..2779b3ceeb14 100644
--- a/drivers/input/keyboard/Kconfig
+++ b/drivers/input/keyboard/Kconfig
@@ -427,9 +427,18 @@ config KEYBOARD_MPR121
To compile this driver as a module, choose M here: the
module will be called mpr121_touchkey.
+config KEYBOARD_RPMSG
+ tristate "i.MX Rpmsg Keys Driver"
+ depends on (SOC_IMX7ULP)
+ depends on RPMSG
+ depends on OF
+ help
+ This is rpmsg keys driver on i.mx7ulp, because some keys located
+ in M4 side.
+
config KEYBOARD_SNVS_PWRKEY
tristate "IMX SNVS Power Key Driver"
- depends on SOC_IMX6SX
+ depends on (SOC_IMX6SX || SOC_IMX6UL || SOC_IMX7 || ARCH_FSL_IMX8MQ)
depends on OF
help
This is the snvs powerkey driver for the Freescale i.MX application
@@ -438,6 +447,21 @@ config KEYBOARD_SNVS_PWRKEY
To compile this driver as a module, choose M here; the
module will be called snvs_pwrkey.
+config KEYBOARD_IMX_SC_PWRKEY
+ tristate "IMX SC Power Key Driver"
+ depends on (ARCH_FSL_IMX8QM || ARCH_FSL_IMX8QXP)
+ help
+ This is the virtual snvs powerkey driver for NXP i.mx8Q/QXP family
+ whose SCU hold snvs inside.
+
+config KEYBOARD_PF1550_ONKEY
+ tristate "PF1550 OnKey Driver"
+ depends on MFD_PF1550
+ depends on OF
+ help
+ This is onkey driver for PF1550 pmic, onkey can trigger release
+ and 1s(push hold), 2s, 3s, 4s, 8s interrupt for long press detect
+
config KEYBOARD_IMX
tristate "IMX keypad support"
depends on ARCH_MXC
diff --git a/drivers/input/keyboard/Makefile b/drivers/input/keyboard/Makefile
index 526e68294e6e..96a90981a37e 100644
--- a/drivers/input/keyboard/Makefile
+++ b/drivers/input/keyboard/Makefile
@@ -52,9 +52,12 @@ obj-$(CONFIG_KEYBOARD_PXA27x) += pxa27x_keypad.o
obj-$(CONFIG_KEYBOARD_PXA930_ROTARY) += pxa930_rotary.o
obj-$(CONFIG_KEYBOARD_QT1070) += qt1070.o
obj-$(CONFIG_KEYBOARD_QT2160) += qt2160.o
+obj-$(CONFIG_KEYBOARD_RPMSG) += rpmsg-keys.o
obj-$(CONFIG_KEYBOARD_SAMSUNG) += samsung-keypad.o
obj-$(CONFIG_KEYBOARD_SH_KEYSC) += sh_keysc.o
obj-$(CONFIG_KEYBOARD_SNVS_PWRKEY) += snvs_pwrkey.o
+obj-$(CONFIG_KEYBOARD_IMX_SC_PWRKEY) += imx_sc_pwrkey.o
+obj-$(CONFIG_KEYBOARD_PF1550_ONKEY) += pf1550_onkey.o
obj-$(CONFIG_KEYBOARD_SPEAR) += spear-keyboard.o
obj-$(CONFIG_KEYBOARD_STMPE) += stmpe-keypad.o
obj-$(CONFIG_KEYBOARD_STOWAWAY) += stowaway.o
diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c
index 7e75835e220f..4511a17f8d9f 100644
--- a/drivers/input/keyboard/atkbd.c
+++ b/drivers/input/keyboard/atkbd.c
@@ -1807,7 +1807,8 @@ static const struct dmi_system_id atkbd_dmi_quirk_table[] __initconst = {
static int __init atkbd_init(void)
{
- dmi_check_system(atkbd_dmi_quirk_table);
+ if (!dmi_check_system(atkbd_dmi_quirk_table))
+ return -ENODEV;
return serio_register_driver(&atkbd_drv);
}
diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c
index e9f0ebf3267a..a3b2311474d8 100644
--- a/drivers/input/keyboard/gpio_keys.c
+++ b/drivers/input/keyboard/gpio_keys.c
@@ -866,6 +866,8 @@ static int __maybe_unused gpio_keys_suspend(struct device *dev)
mutex_unlock(&input->mutex);
}
+ pinctrl_pm_select_sleep_state(dev);
+
return 0;
}
@@ -876,6 +878,8 @@ static int __maybe_unused gpio_keys_resume(struct device *dev)
int error = 0;
int i;
+ pinctrl_pm_select_default_state(dev);
+
if (device_may_wakeup(dev)) {
for (i = 0; i < ddata->pdata->nbuttons; i++) {
struct gpio_button_data *bdata = &ddata->data[i];
diff --git a/drivers/input/keyboard/imx_keypad.c b/drivers/input/keyboard/imx_keypad.c
index 842c0235471d..9d3971818e05 100644
--- a/drivers/input/keyboard/imx_keypad.c
+++ b/drivers/input/keyboard/imx_keypad.c
@@ -1,6 +1,7 @@
/*
* Driver for the IMX keypad port.
* Copyright (C) 2009 Alberto Panizzo <maramaopercheseimorto@gmail.com>
+ * Copyright (C) 2015 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
@@ -267,6 +268,7 @@ static void imx_keypad_check_for_events(unsigned long data)
reg_val |= KBD_STAT_KDIE;
reg_val &= ~KBD_STAT_KRIE;
writew(reg_val, keypad->mmio_base + KPSR);
+ pm_relax(keypad->input_dev->dev.parent);
} else {
/*
* Some keys are still pressed. Schedule a rescan in
@@ -280,11 +282,6 @@ static void imx_keypad_check_for_events(unsigned long data)
reg_val = readw(keypad->mmio_base + KPSR);
reg_val |= KBD_STAT_KPKR | KBD_STAT_KRSS;
writew(reg_val, keypad->mmio_base + KPSR);
-
- reg_val = readw(keypad->mmio_base + KPSR);
- reg_val |= KBD_STAT_KRIE;
- reg_val &= ~KBD_STAT_KDIE;
- writew(reg_val, keypad->mmio_base + KPSR);
}
}
@@ -302,6 +299,7 @@ static irqreturn_t imx_keypad_irq_handler(int irq, void *dev_id)
writew(reg_val, keypad->mmio_base + KPSR);
if (keypad->enabled) {
+ pm_stay_awake(keypad->input_dev->dev.parent);
/* The matrix is supposed to be changed */
keypad->stable_count = 0;
diff --git a/drivers/input/keyboard/imx_sc_pwrkey.c b/drivers/input/keyboard/imx_sc_pwrkey.c
new file mode 100644
index 000000000000..c89ca93b8446
--- /dev/null
+++ b/drivers/input/keyboard/imx_sc_pwrkey.c
@@ -0,0 +1,173 @@
+/*
+ * Driver for the IMX SNVS ON/OFF Power Key over sc api
+ * Copyright (C) 2017 NXP. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/input.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/jiffies.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include <soc/imx8/sc/sci.h>
+#include <soc/imx8/sc/svc/irq/api.h>
+
+#define DEBOUNCE_TIME 100
+#define REPEAT_INTERVAL 60
+
+struct pwrkey_drv_data {
+ int keycode;
+ bool keystate; /* 1: pressed, 0: release */
+ bool delay_check;
+ sc_ipc_t ipcHandle;
+ int wakeup;
+ struct delayed_work check_work;
+ struct input_dev *input;
+};
+
+static struct pwrkey_drv_data *pdata;
+
+static int imx_sc_pwrkey_notify(struct notifier_block *nb,
+ unsigned long event, void *group)
+{
+ /* ignore other irqs */
+ if (!(pdata && pdata->ipcHandle && (event & SC_IRQ_BUTTON) &&
+ (*(sc_irq_group_t *)group == SC_IRQ_GROUP_WAKE)))
+ return 0;
+
+ if (!pdata->delay_check) {
+ pdata->delay_check = 1;
+ schedule_delayed_work(&pdata->check_work,
+ msecs_to_jiffies(REPEAT_INTERVAL));
+ }
+
+ return 0;
+}
+
+static void imx_sc_check_for_events(struct work_struct *work)
+{
+ struct input_dev *input = pdata->input;
+ sc_bool_t state;
+
+ sc_misc_get_button_status(pdata->ipcHandle, &state);
+ /*
+ * restore status back if press interrupt received but pin's status
+ * released, which caused by pressing so quickly.
+ */
+ if (!state && !pdata->keystate)
+ state = true;
+
+ if (state ^ pdata->keystate) {
+ pm_wakeup_event(input->dev.parent, 0);
+ pdata->keystate = !!state;
+ input_event(input, EV_KEY, pdata->keycode, !!state);
+ input_sync(input);
+ if (!state)
+ pdata->delay_check = 0;
+ pm_relax(pdata->input->dev.parent);
+ }
+ /* repeat check if pressed long */
+ if (state)
+ schedule_delayed_work(&pdata->check_work,
+ msecs_to_jiffies(DEBOUNCE_TIME));
+}
+
+static struct notifier_block imx_sc_pwrkey_notifier = {
+ .notifier_call = imx_sc_pwrkey_notify,
+};
+
+static int imx_sc_pwrkey_probe(struct platform_device *pdev)
+{
+ struct input_dev *input = NULL;
+ struct device_node *np = pdev->dev.of_node;
+ int error;
+ uint32_t mu_id;
+ sc_err_t sciErr;
+
+ pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
+ if (!pdata)
+ return -ENOMEM;
+
+ if (of_property_read_u32(np, "linux,keycode", &pdata->keycode)) {
+ pdata->keycode = KEY_POWER;
+ dev_warn(&pdev->dev, "KEY_POWER without setting in dts\n");
+ }
+
+ sciErr = sc_ipc_getMuID(&mu_id);
+ if (sciErr != SC_ERR_NONE) {
+ dev_err(&pdev->dev, "can not obtain mu id: %d\n", sciErr);
+ return sciErr;
+ }
+
+ sciErr = sc_ipc_open(&pdata->ipcHandle, mu_id);
+
+ if (sciErr != SC_ERR_NONE) {
+ dev_err(&pdev->dev, "can not get ipc handler: %d\n", sciErr);
+ return sciErr;
+ };
+
+ INIT_DELAYED_WORK(&pdata->check_work, imx_sc_check_for_events);
+
+ pdata->wakeup = of_property_read_bool(np, "wakeup-source");
+
+ input = devm_input_allocate_device(&pdev->dev);
+
+ if (!input) {
+ dev_err(&pdev->dev, "failed to allocate the input device\n");
+ return -ENOMEM;
+ }
+
+ input->name = pdev->name;
+ input->phys = "imx-sc-pwrkey/input0";
+ input->id.bustype = BUS_HOST;
+
+ input_set_capability(input, EV_KEY, pdata->keycode);
+
+ error = input_register_device(input);
+ if (error < 0) {
+ dev_err(&pdev->dev, "failed to register input device\n");
+ return error;
+ }
+
+ pdata->input = input;
+ platform_set_drvdata(pdev, pdata);
+
+ device_init_wakeup(&pdev->dev, !!(pdata->wakeup));
+
+ return register_scu_notifier(&imx_sc_pwrkey_notifier);
+}
+
+static const struct of_device_id imx_sc_pwrkey_ids[] = {
+ { .compatible = "fsl,imx8-pwrkey" },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, imx_sc_pwrkey_ids);
+
+static struct platform_driver imx_sc_pwrkey_driver = {
+ .driver = {
+ .name = "imx8-pwrkey",
+ .of_match_table = imx_sc_pwrkey_ids,
+ },
+ .probe = imx_sc_pwrkey_probe,
+};
+module_platform_driver(imx_sc_pwrkey_driver);
+
+MODULE_AUTHOR("Robin Gong <yibin.gong@nxp.com>");
+MODULE_DESCRIPTION("i.MX8 power key driver based on scu");
+MODULE_LICENSE("GPL");
diff --git a/drivers/input/keyboard/pf1550_onkey.c b/drivers/input/keyboard/pf1550_onkey.c
new file mode 100644
index 000000000000..2ba0d155ef99
--- /dev/null
+++ b/drivers/input/keyboard/pf1550_onkey.c
@@ -0,0 +1,206 @@
+/*
+ * Driver for the PF1550 ON_KEY
+ * Copyright (C) 2016 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/input.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/jiffies.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/mfd/pf1550.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+struct onkey_drv_data {
+ struct device *dev;
+ struct pf1550_dev *pf1550;
+ int irq;
+ int keycode;
+ int wakeup;
+ struct input_dev *input;
+};
+
+static struct pf1550_irq_info pf1550_onkey_irqs[] = {
+ { PF1550_ONKEY_IRQ_PUSHI, "release" },
+ { PF1550_ONKEY_IRQ_1SI, "1S" },
+ { PF1550_ONKEY_IRQ_2SI, "2S" },
+ { PF1550_ONKEY_IRQ_3SI, "3S" },
+ { PF1550_ONKEY_IRQ_4SI, "4S" },
+ { PF1550_ONKEY_IRQ_8SI, "8S" },
+};
+
+static irqreturn_t pf1550_onkey_irq_handler(int irq, void *data)
+{
+ struct onkey_drv_data *onkey = data;
+ int i, state, irq_type = -1;
+
+ onkey->irq = irq;
+
+ for (i = 0; i < ARRAY_SIZE(pf1550_onkey_irqs); i++)
+ if (onkey->irq == pf1550_onkey_irqs[i].virq)
+ irq_type = pf1550_onkey_irqs[i].irq;
+ switch (irq_type) {
+ case PF1550_ONKEY_IRQ_PUSHI:
+ state = 0;
+ break;
+ case PF1550_ONKEY_IRQ_1SI:
+ case PF1550_ONKEY_IRQ_2SI:
+ case PF1550_ONKEY_IRQ_3SI:
+ case PF1550_ONKEY_IRQ_4SI:
+ case PF1550_ONKEY_IRQ_8SI:
+ state = 1;
+ break;
+ default:
+ dev_err(onkey->dev, "onkey interrupt: irq %d occurred\n",
+ irq_type);
+ return IRQ_HANDLED;
+ }
+
+ input_event(onkey->input, EV_KEY, onkey->keycode, state);
+ input_sync(onkey->input);
+
+ return IRQ_HANDLED;
+}
+
+static int pf1550_onkey_probe(struct platform_device *pdev)
+{
+ struct onkey_drv_data *onkey;
+ struct input_dev *input = NULL;
+ struct device_node *np = pdev->dev.of_node;
+ struct pf1550_dev *pf1550 = dev_get_drvdata(pdev->dev.parent);
+ int i, error;
+
+ if (!np)
+ return -ENODEV;
+
+ onkey = devm_kzalloc(&pdev->dev, sizeof(*onkey), GFP_KERNEL);
+ if (!onkey)
+ return -ENOMEM;
+
+ if (of_property_read_u32(np, "linux,keycode", &onkey->keycode)) {
+ onkey->keycode = KEY_POWER;
+ dev_warn(&pdev->dev, "KEY_POWER without setting in dts\n");
+ }
+
+ onkey->wakeup = of_property_read_bool(np, "wakeup");
+
+ input = devm_input_allocate_device(&pdev->dev);
+ if (!input) {
+ dev_err(&pdev->dev, "failed to allocate the input device\n");
+ return -ENOMEM;
+ }
+
+ input->name = pdev->name;
+ input->phys = "pf1550-onkey/input0";
+ input->id.bustype = BUS_HOST;
+
+ input_set_capability(input, EV_KEY, onkey->keycode);
+
+ for (i = 0; i < ARRAY_SIZE(pf1550_onkey_irqs); i++) {
+ struct pf1550_irq_info *onkey_irq =
+ &pf1550_onkey_irqs[i];
+ unsigned int virq = 0;
+
+ virq = regmap_irq_get_virq(pf1550->irq_data_onkey,
+ onkey_irq->irq);
+ if (!virq)
+ return -EINVAL;
+
+ onkey_irq->virq = virq;
+
+ error = devm_request_threaded_irq(&pdev->dev, virq, NULL,
+ pf1550_onkey_irq_handler,
+ IRQF_NO_SUSPEND,
+ onkey_irq->name, onkey);
+ if (error) {
+ dev_err(&pdev->dev,
+ "failed: irq request (IRQ: %d, error :%d)\n",
+ onkey_irq->irq, error);
+ return error;
+ }
+ }
+
+ error = input_register_device(input);
+ if (error < 0) {
+ dev_err(&pdev->dev, "failed to register input device\n");
+ input_free_device(input);
+ return error;
+ }
+
+ onkey->input = input;
+ onkey->pf1550 = pf1550;
+ platform_set_drvdata(pdev, onkey);
+
+ device_init_wakeup(&pdev->dev, onkey->wakeup);
+
+ return 0;
+}
+
+static int pf1550_onkey_suspend(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct onkey_drv_data *onkey = platform_get_drvdata(pdev);
+
+ if (!device_may_wakeup(&pdev->dev))
+ regmap_write(onkey->pf1550->regmap,
+ PF1550_PMIC_REG_ONKEY_INT_MASK0,
+ ONKEY_IRQ_PUSHI | ONKEY_IRQ_1SI | ONKEY_IRQ_2SI |
+ ONKEY_IRQ_3SI | ONKEY_IRQ_4SI | ONKEY_IRQ_8SI);
+ else
+ enable_irq_wake(onkey->pf1550->irq);
+
+ return 0;
+}
+
+static int pf1550_onkey_resume(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct onkey_drv_data *onkey = platform_get_drvdata(pdev);
+
+ if (!device_may_wakeup(&pdev->dev))
+ regmap_write(onkey->pf1550->regmap,
+ PF1550_PMIC_REG_ONKEY_INT_MASK0,
+ ~(ONKEY_IRQ_PUSHI | ONKEY_IRQ_1SI | ONKEY_IRQ_2SI |
+ ONKEY_IRQ_3SI | ONKEY_IRQ_4SI | ONKEY_IRQ_8SI));
+ else
+ disable_irq_wake(onkey->pf1550->irq);
+
+ return 0;
+}
+
+static const struct of_device_id pf1550_onkey_ids[] = {
+ { .compatible = "fsl,pf1550-onkey" },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, pf1550_onkey_ids);
+
+static SIMPLE_DEV_PM_OPS(pf1550_onkey_pm_ops, pf1550_onkey_suspend,
+ pf1550_onkey_resume);
+
+static struct platform_driver pf1550_onkey_driver = {
+ .driver = {
+ .name = "pf1550-onkey",
+ .pm = &pf1550_onkey_pm_ops,
+ .of_match_table = pf1550_onkey_ids,
+ },
+ .probe = pf1550_onkey_probe,
+};
+module_platform_driver(pf1550_onkey_driver);
+
+MODULE_AUTHOR("Freescale Semiconductor");
+MODULE_DESCRIPTION(" PF1550 onkey Driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/input/keyboard/rpmsg-keys.c b/drivers/input/keyboard/rpmsg-keys.c
new file mode 100644
index 000000000000..f6012e87f9a6
--- /dev/null
+++ b/drivers/input/keyboard/rpmsg-keys.c
@@ -0,0 +1,310 @@
+/*
+ * Copyright 2017 NXP
+ *
+ * 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/err.h>
+#include <linux/slab.h>
+#include <linux/imx_rpmsg.h>
+#include <linux/input.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/pm_qos.h>
+#include <linux/rpmsg.h>
+#include <linux/uaccess.h>
+#include <linux/virtio.h>
+
+#define RPMSG_TIMEOUT 1000
+
+enum key_cmd_type {
+ KEY_RPMSG_SETUP,
+ KEY_RPMSG_REPLY,
+ KEY_RPMSG_NOTIFY,
+};
+
+enum keys_type {
+ KEY_PRESS = 1,
+ KEY_RELEASE,
+ KEY_BOTH,
+};
+
+struct key_rpmsg_data {
+ struct imx_rpmsg_head header;
+ u8 key_index;
+ union {
+ u8 event;
+ u8 retcode;
+ };
+ u8 wakeup;
+} __attribute__((packed));
+
+struct rpmsg_keys_button {
+ unsigned int code;
+ enum keys_type type;
+ int wakeup;
+ struct input_dev *input;
+};
+
+struct rpmsg_keys_drvdata {
+ struct input_dev *input;
+ struct rpmsg_device *rpdev;
+ struct device *dev;
+ struct key_rpmsg_data *msg;
+ bool ack;
+ struct pm_qos_request pm_qos_req;
+ struct delayed_work keysetup_work;
+ struct completion cmd_complete;
+ int nbuttons;
+ struct rpmsg_keys_button buttons[0];
+};
+
+static struct rpmsg_keys_drvdata *keys_rpmsg;
+
+static int key_send_message(struct key_rpmsg_data *msg,
+ struct rpmsg_keys_drvdata *info, bool ack)
+{
+ int err;
+
+ if (!info->rpdev) {
+ dev_dbg(info->dev,
+ "rpmsg channel not ready, m4 image ready?\n");
+ return -EINVAL;
+ }
+
+ pm_qos_add_request(&info->pm_qos_req,
+ PM_QOS_CPU_DMA_LATENCY, 0);
+
+ if (ack) {
+ info->ack = true;
+ reinit_completion(&info->cmd_complete);
+ }
+
+ err = rpmsg_send(info->rpdev->ept, (void *)msg,
+ sizeof(struct key_rpmsg_data));
+ if (err) {
+ dev_err(&info->rpdev->dev, "rpmsg_send failed: %d\n", err);
+ goto err_out;
+ }
+
+ if (ack) {
+ err = wait_for_completion_timeout(&info->cmd_complete,
+ msecs_to_jiffies(RPMSG_TIMEOUT));
+ if (!err) {
+ dev_err(&info->rpdev->dev, "rpmsg_send timeout!\n");
+ err = -ETIMEDOUT;
+ goto err_out;
+ }
+
+ if (info->msg->retcode != 0) {
+ dev_err(&info->rpdev->dev, "rpmsg not ack %d!\n",
+ info->msg->retcode);
+ err = -EINVAL;
+ goto err_out;
+ }
+
+ err = 0;
+ }
+
+err_out:
+ info->ack = true;
+ pm_qos_remove_request(&info->pm_qos_req);
+
+ return err;
+}
+
+static int keys_rpmsg_cb(struct rpmsg_device *rpdev,
+ void *data, int len, void *priv, u32 src)
+{
+ struct key_rpmsg_data *msg = (struct key_rpmsg_data *)data;
+
+ if (msg->header.type == KEY_RPMSG_REPLY) {
+ keys_rpmsg->msg = msg;
+ complete(&keys_rpmsg->cmd_complete);
+ return 0;
+ } else if (msg->header.type == KEY_RPMSG_NOTIFY) {
+ keys_rpmsg->msg = msg;
+ keys_rpmsg->ack = false;
+ } else
+ dev_err(&keys_rpmsg->rpdev->dev, "wrong command type!\n");
+
+ input_event(keys_rpmsg->input, EV_KEY, msg->key_index, msg->event);
+ input_sync(keys_rpmsg->input);
+
+ return 0;
+}
+
+static void keys_init_handler(struct work_struct *work)
+{
+ struct key_rpmsg_data msg;
+ int i;
+
+ /* setup keys */
+ for (i = 0; i < keys_rpmsg->nbuttons; i++) {
+ struct rpmsg_keys_button *button = &keys_rpmsg->buttons[i];
+
+ msg.header.cate = IMX_RPMSG_KEY;
+ msg.header.major = IMX_RMPSG_MAJOR;
+ msg.header.minor = IMX_RMPSG_MINOR;
+ msg.header.type = KEY_RPMSG_SETUP;
+ msg.header.cmd = 0;
+ msg.key_index = button->code;
+ msg.wakeup = button->wakeup;
+ msg.event = button->type;
+ if (key_send_message(&msg, keys_rpmsg, true))
+ dev_err(&keys_rpmsg->rpdev->dev,
+ "key %d setup failed!\n", button->code);
+ }
+}
+
+static int keys_rpmsg_probe(struct rpmsg_device *rpdev)
+{
+ keys_rpmsg->rpdev = rpdev;
+
+ dev_info(&rpdev->dev, "new channel: 0x%x -> 0x%x!\n",
+ rpdev->src, rpdev->dst);
+
+ init_completion(&keys_rpmsg->cmd_complete);
+
+ INIT_DELAYED_WORK(&keys_rpmsg->keysetup_work,
+ keys_init_handler);
+ schedule_delayed_work(&keys_rpmsg->keysetup_work,
+ msecs_to_jiffies(100));
+
+ return 0;
+}
+
+static struct rpmsg_device_id keys_rpmsg_id_table[] = {
+ { .name = "rpmsg-keypad-channel" },
+ { },
+};
+
+static struct rpmsg_driver keys_rpmsg_driver = {
+ .drv.name = "key_rpmsg",
+ .drv.owner = THIS_MODULE,
+ .id_table = keys_rpmsg_id_table,
+ .probe = keys_rpmsg_probe,
+ .callback = keys_rpmsg_cb,
+};
+
+static struct rpmsg_keys_drvdata *
+rpmsg_keys_get_devtree_pdata(struct device *dev)
+{
+ struct device_node *node, *pp;
+ struct rpmsg_keys_drvdata *ddata;
+ struct rpmsg_keys_button *button;
+ int nbuttons;
+ int i;
+
+ node = dev->of_node;
+ if (!node)
+ return ERR_PTR(-ENODEV);
+
+ nbuttons = of_get_child_count(node);
+ if (nbuttons == 0)
+ return ERR_PTR(-ENODEV);
+
+ ddata = devm_kzalloc(dev,
+ sizeof(*ddata) + nbuttons *
+ sizeof(struct rpmsg_keys_button),
+ GFP_KERNEL);
+ if (!ddata)
+ return ERR_PTR(-ENOMEM);
+
+ ddata->nbuttons = nbuttons;
+
+ i = 0;
+ for_each_child_of_node(node, pp) {
+ button = &ddata->buttons[i++];
+
+ if (of_property_read_u32(pp, "linux,code", &button->code)) {
+ dev_err(dev, "Button without keycode: 0x%x\n",
+ button->code);
+ return ERR_PTR(-EINVAL);
+ }
+
+ button->wakeup = !!of_get_property(pp, "rpmsg-key,wakeup",
+ NULL);
+ button->type = KEY_BOTH;
+ }
+
+ return ddata;
+}
+
+static int rpmsg_keys_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct rpmsg_keys_drvdata *ddata;
+ int i, error;
+ struct input_dev *input;
+
+ ddata = rpmsg_keys_get_devtree_pdata(dev);
+ if (IS_ERR(ddata))
+ return PTR_ERR(ddata);
+
+ input = devm_input_allocate_device(dev);
+ if (!input) {
+ dev_err(dev, "failed to allocate input device\n");
+ return -ENOMEM;
+ }
+
+ ddata->input = input;
+
+ keys_rpmsg = ddata;
+ platform_set_drvdata(pdev, ddata);
+
+ input->name = pdev->name;
+ input->phys = "rpmsg-keys/input0";
+ input->dev.parent = &pdev->dev;
+
+ input->id.bustype = BUS_HOST;
+
+ for (i = 0; i < ddata->nbuttons; i++) {
+ struct rpmsg_keys_button *button = &ddata->buttons[i];
+
+ input_set_capability(input, EV_KEY, button->code);
+ }
+
+ error = input_register_device(input);
+ if (error) {
+ dev_err(dev, "Unable to register input device, error: %d\n",
+ error);
+ goto err_out;
+ }
+
+ return register_rpmsg_driver(&keys_rpmsg_driver);
+err_out:
+ return error;
+}
+
+static const struct of_device_id rpmsg_keys_of_match[] = {
+ { .compatible = "fsl,rpmsg-keys", },
+ { },
+};
+
+MODULE_DEVICE_TABLE(of, rpmsg_keys_of_match);
+
+static struct platform_driver rpmsg_keys_device_driver = {
+ .probe = rpmsg_keys_probe,
+ .driver = {
+ .name = "rpmsg-keys",
+ .of_match_table = of_match_ptr(rpmsg_keys_of_match)
+ }
+};
+
+module_platform_driver(rpmsg_keys_device_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Robin Gong <yibin.gong@nxp.com>");
+MODULE_DESCRIPTION("Keyboard driver based on rpmsg");
diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
index 9f082a388388..f81b4224e95b 100644
--- a/drivers/input/misc/Kconfig
+++ b/drivers/input/misc/Kconfig
@@ -855,4 +855,39 @@ config INPUT_HISI_POWERKEY
To compile this driver as a module, choose M here: the
module will be called hisi_powerkey.
+config INPUT_MPL3115
+ tristate "MPL3115 pressure temperature sensor"
+ depends on I2C && SYSFS
+ help
+ If you say yes here you get support for the Freescale MPL3115
+ pressure temperature sensor.
+
+ This driver can also be built as a module. If so, the module
+ will be called mpl3115
+
+config SENSOR_FXLS8471
+ tristate "FXLS8471 motion sensor device driver"
+ depends on I2C
+ default n
+
+config SENSOR_IMX_RPMSG
+ tristate "NXP IMX rpmsg virtual sensor device driver"
+ depends on (SOC_IMX7ULP)
+ depends on RPMSG && SYSFS
+ depends on OF
+ default n
+ help
+ This is rpmsg virtual sensor driver on i.mx7ulp, because some
+ sensors connect with M4 core.
+
+config INPUT_ISL29023
+ tristate "Intersil ISL29023 ambient light sensor"
+ depends on I2C && SYSFS
+ help
+ If you say yes here you get support for the Intersil ISL29023
+ ambient light sensor.
+
+ This driver can also be built as a module. If so, the module
+ will be called isl29023.
+
endif
diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile
index 4b6118d313fe..34a877d4a09c 100644
--- a/drivers/input/misc/Makefile
+++ b/drivers/input/misc/Makefile
@@ -81,3 +81,7 @@ obj-$(CONFIG_INPUT_WM831X_ON) += wm831x-on.o
obj-$(CONFIG_INPUT_XEN_KBDDEV_FRONTEND) += xen-kbdfront.o
obj-$(CONFIG_INPUT_YEALINK) += yealink.o
obj-$(CONFIG_INPUT_IDEAPAD_SLIDEBAR) += ideapad_slidebar.o
+obj-$(CONFIG_INPUT_MPL3115) += mpl3115.o
+obj-$(CONFIG_SENSOR_FXLS8471) += fxls8471.o fxls8471_i2c.o
+obj-$(CONFIG_INPUT_ISL29023) += isl29023.o
+obj-$(CONFIG_SENSOR_IMX_RPMSG) += rpmsg_input.o
diff --git a/drivers/input/misc/fxls8471.c b/drivers/input/misc/fxls8471.c
new file mode 100644
index 000000000000..ef7368bb519b
--- /dev/null
+++ b/drivers/input/misc/fxls8471.c
@@ -0,0 +1,583 @@
+/*
+ * fxls8471.c - Linux kernel modules for 3-Axis Accel sensor
+ * Copyright (C) 2014-2015 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/pm.h>
+#include <linux/mutex.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/hwmon-sysfs.h>
+#include <linux/err.h>
+#include <linux/hwmon.h>
+#include <linux/input-polldev.h>
+#include <linux/miscdevice.h>
+#include <linux/poll.h>
+#include "fxls8471.h"
+
+#define SENSOR_IOCTL_BASE 'S'
+#define SENSOR_GET_MODEL_NAME _IOR(SENSOR_IOCTL_BASE, 0, char *)
+#define SENSOR_GET_POWER_STATUS _IOR(SENSOR_IOCTL_BASE, 2, int)
+#define SENSOR_SET_POWER_STATUS _IOR(SENSOR_IOCTL_BASE, 3, int)
+#define SENSOR_GET_DELAY_TIME _IOR(SENSOR_IOCTL_BASE, 4, int)
+#define SENSOR_SET_DELAY_TIME _IOR(SENSOR_IOCTL_BASE, 5, int)
+#define SENSOR_GET_RAW_DATA _IOR(SENSOR_IOCTL_BASE, 6, short[3])
+
+#define FXLS8471_POSITION_DEFAULT 2
+#define FXLS8471_DELAY_DEFAULT 200
+
+#define FXLS8471_STATUS_ZYXDR 0x08
+#define FXLS8471_BUF_SIZE 6
+
+struct fxls8471_data fxls8471_dev;
+EXPORT_SYMBOL(fxls8471_dev);
+
+static int fxls8471_position_setting[8][3][3] = {
+ {{0, -1, 0}, {1, 0, 0}, {0, 0, 1} },
+ {{-1, 0, 0}, {0, -1, 0}, {0, 0, 1} },
+ {{0, 1, 0}, {-1, 0, 0}, {0, 0, 1} },
+ {{1, 0, 0}, {0, 1, 0}, {0, 0, 1} },
+
+ {{0, -1, 0}, {-1, 0, 0}, {0, 0, -1} },
+ {{-1, 0, 0}, {0, 1, 0}, {0, 0, -1} },
+ {{0, 1, 0}, {1, 0, 0}, {0, 0, -1} },
+ {{1, 0, 0}, {0, -1, 0}, {0, 0, -1} },
+};
+
+static int fxls8471_bus_write(struct fxls8471_data *pdata, u8 reg, u8 val)
+{
+ if (pdata && pdata->write)
+ return pdata->write(pdata, reg, val);
+ return -EIO;
+}
+
+static int fxls8471_bus_read(struct fxls8471_data *pdata, u8 reg)
+{
+ if (pdata && pdata->read)
+ return pdata->read(pdata, reg);
+ return -EIO;
+}
+
+static int fxls8471_bus_read_block(struct fxls8471_data *pdata, u8 reg, u8 len,
+ u8 *val)
+{
+ if (pdata && pdata->read_block)
+ return pdata->read_block(pdata, reg, len, val);
+ return -EIO;
+}
+
+static int fxls8471_data_convert(struct fxls8471_data *pdata,
+ struct fxls8471_data_axis *axis_data)
+{
+ short rawdata[3], data[3];
+ int i, j;
+ int position = atomic_read(&pdata->position);
+
+ if (position < 0 || position > 7)
+ position = 0;
+ rawdata[0] = axis_data->x;
+ rawdata[1] = axis_data->y;
+ rawdata[2] = axis_data->z;
+ for (i = 0; i < 3; i++) {
+ data[i] = 0;
+ for (j = 0; j < 3; j++)
+ data[i] +=
+ rawdata[j] *
+ fxls8471_position_setting[position][i][j];
+ }
+ axis_data->x = data[0];
+ axis_data->y = data[1];
+ axis_data->z = data[2];
+ return 0;
+}
+
+static int fxls8471_device_init(struct fxls8471_data *pdata)
+{
+ int result;
+ result = fxls8471_bus_write(pdata, FXLS8471_CTRL_REG1, 0);
+ if (result < 0)
+ goto out;
+
+ result = fxls8471_bus_write(pdata, FXLS8471_XYZ_DATA_CFG, MODE_2G);
+ if (result < 0)
+ goto out;
+
+ if (pdata->irq) {
+ result = fxls8471_bus_write(pdata, FXLS8471_CTRL_REG5, 0x01);
+ if (result < 0)
+ goto out;
+ result = fxls8471_bus_write(pdata, FXLS8471_CTRL_REG4, 0x01);
+ if (result < 0)
+ goto out;
+ }
+ atomic_set(&pdata->active, STANDBY);
+ return 0;
+out:
+ printk("FXLS8471 device init error\n");
+ return result;
+
+}
+
+static int fxls8471_change_mode(struct fxls8471_data *pdata, int mode)
+{
+ u8 val;
+ int ret;
+ val = fxls8471_bus_read(pdata, FXLS8471_CTRL_REG1);
+ if (mode == ACTIVED)
+ val |= 0x01;
+ else
+ val &= (~0x01);
+ ret = fxls8471_bus_write(pdata, FXLS8471_CTRL_REG1, val);
+ return ret;
+}
+
+static int fxls8471_set_delay(struct fxls8471_data *pdata, int delay)
+{
+ u8 val;
+ val = fxls8471_bus_read(pdata, FXLS8471_CTRL_REG1);
+ /* set sensor standby */
+ fxls8471_bus_write(pdata, FXLS8471_CTRL_REG1, (val & ~0x01));
+ val &= ~(0x7 << 3);
+ if (delay <= 10)
+ val |= 0x02 << 3;
+ else if (delay <= 20)
+ val |= 0x03 << 3;
+ else if (delay <= 67)
+ val |= 0x04 << 3;
+ else
+ val |= 0x05 << 3;
+ /* set sensor standby */
+ fxls8471_bus_write(pdata, FXLS8471_CTRL_REG1, val);
+ return 0;
+}
+
+static int fxls8471_change_range(struct fxls8471_data *pdata, int range)
+{
+ int ret;
+
+ ret = fxls8471_bus_write(pdata, FXLS8471_XYZ_DATA_CFG, range);
+
+ return ret;
+}
+
+static int fxls8471_read_data(struct fxls8471_data *pdata,
+ struct fxls8471_data_axis *data)
+{
+ u8 tmp_data[FXLS8471_BUF_SIZE];
+ int ret;
+ ret = fxls8471_bus_read_block(pdata, FXLS8471_OUT_X_MSB,
+ FXLS8471_BUF_SIZE, tmp_data);
+ if (ret < FXLS8471_BUF_SIZE) {
+ printk(KERN_ERR "FXLS8471 read sensor block data error\n");
+ return -EIO;
+ }
+ data->x = ((tmp_data[0] << 8) & 0xff00) | tmp_data[1];
+ data->y = ((tmp_data[2] << 8) & 0xff00) | tmp_data[3];
+ data->z = ((tmp_data[4] << 8) & 0xff00) | tmp_data[5];
+ return 0;
+}
+
+/* fxls8471 miscdevice */
+static long fxls8471_ioctl(struct file *file, unsigned int reg,
+ unsigned long arg)
+{
+ struct fxls8471_data *pdata = file->private_data;
+ void __user *argp = (void __user *)arg;
+ long ret = 0;
+ short sdata[3];
+ int enable;
+ int delay;
+ struct fxls8471_data_axis data;
+ if (!pdata) {
+ printk(KERN_ERR "FXLS8471 struct datt point is NULL.");
+ return -EFAULT;
+ }
+ switch (reg) {
+ case SENSOR_GET_MODEL_NAME:
+ if (copy_to_user(argp, "fxls8471", strlen("fxls8471") + 1)) {
+ printk(KERN_ERR
+ "SENSOR_GET_MODEL_NAME copy_to_user failed.");
+ ret = -EFAULT;
+ }
+ break;
+ case SENSOR_GET_POWER_STATUS:
+ enable = atomic_read(&pdata->active);
+ if (copy_to_user(argp, &enable, sizeof(int))) {
+ printk(KERN_ERR
+ "SENSOR_SET_POWER_STATUS copy_to_user failed.");
+ ret = -EFAULT;
+ }
+ break;
+ case SENSOR_SET_POWER_STATUS:
+ if (copy_from_user(&enable, argp, sizeof(int))) {
+ printk(KERN_ERR
+ "SENSOR_SET_POWER_STATUS copy_to_user failed.");
+ ret = -EFAULT;
+ }
+ if (pdata) {
+ ret =
+ fxls8471_change_mode(pdata,
+ enable ? ACTIVED : STANDBY);
+ if (!ret)
+ atomic_set(&pdata->active, enable);
+ }
+ break;
+ case SENSOR_GET_DELAY_TIME:
+ delay = atomic_read(&pdata->delay);
+ if (copy_to_user(argp, &delay, sizeof(delay))) {
+ printk(KERN_ERR
+ "SENSOR_GET_DELAY_TIME copy_to_user failed.");
+ return -EFAULT;
+ }
+ break;
+ case SENSOR_SET_DELAY_TIME:
+ if (copy_from_user(&delay, argp, sizeof(int))) {
+ printk(KERN_ERR
+ "SENSOR_GET_DELAY_TIME copy_to_user failed.");
+ ret = -EFAULT;
+ }
+ if (pdata && delay > 0 && delay <= 500) {
+ ret = fxls8471_set_delay(pdata, delay);
+ if (!ret)
+ atomic_set(&pdata->delay, delay);
+ }
+ break;
+ case SENSOR_GET_RAW_DATA:
+ ret = fxls8471_read_data(pdata, &data);
+ if (!ret) {
+ fxls8471_data_convert(pdata, &data);
+ sdata[0] = data.x;
+ sdata[1] = data.y;
+ sdata[2] = data.z;
+ if (copy_to_user(argp, sdata, sizeof(sdata))) {
+ printk(KERN_ERR
+ "SENSOR_GET_RAW_DATA copy_to_user failed.");
+ ret = -EFAULT;
+ }
+ }
+ break;
+ default:
+ ret = -1;
+ }
+ return ret;
+}
+
+static int fxls8471_open(struct inode *inode, struct file *file)
+{
+ file->private_data = &fxls8471_dev;
+ return nonseekable_open(inode, file);
+}
+
+static int fxls8471_release(struct inode *inode, struct file *file)
+{
+ /* note: releasing the wdt in NOWAYOUT-mode does not stop it */
+ return 0;
+}
+
+static const struct file_operations fxls8471_fops = {
+ .owner = THIS_MODULE,
+ .open = fxls8471_open,
+ .release = fxls8471_release,
+ .unlocked_ioctl = fxls8471_ioctl,
+};
+
+static struct miscdevice fxls8471_device = {
+ .minor = MISC_DYNAMIC_MINOR,
+ .name = "FreescaleAccelerometer",
+ .fops = &fxls8471_fops,
+};
+
+static ssize_t fxls8471_enable_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct fxls8471_data *pdata = &fxls8471_dev;
+ int enable = 0;
+ enable = atomic_read(&pdata->active);
+ return sprintf(buf, "%d\n", enable);
+}
+
+static ssize_t fxls8471_enable_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct fxls8471_data *pdata = &fxls8471_dev;
+ int ret;
+ unsigned long enable;
+
+ if (kstrtoul(buf, 10, &enable) < 0)
+ return -EINVAL;
+ enable = (enable > 0) ? 1 : 0;
+ ret = fxls8471_change_mode(pdata, (enable > 0 ? ACTIVED : STANDBY));
+ if (!ret) {
+ atomic_set(&pdata->active, enable);
+ if (enable)
+ printk(KERN_INFO "mma enable setting actived\n");
+ else
+ printk(KERN_INFO "mma enable setting standby\n");
+ }
+ return count;
+}
+
+static ssize_t fxls8471_poll_delay_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct fxls8471_data *pdata = &fxls8471_dev;
+ int delay = 0;
+ delay = atomic_read(&pdata->delay);
+ return sprintf(buf, "%d\n", delay);
+}
+
+static ssize_t fxls8471_poll_delay_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct fxls8471_data *pdata = &fxls8471_dev;
+ int ret;
+ unsigned long delay;
+
+ if (kstrtoul(buf, 10, &delay) < 0)
+ return -EINVAL;
+ ret = fxls8471_set_delay(pdata, delay);
+ if (!ret)
+ atomic_set(&pdata->delay, delay);
+
+ return count;
+}
+
+static ssize_t fxls8471_position_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct fxls8471_data *pdata = &fxls8471_dev;
+ int position = 0;
+ position = atomic_read(&pdata->position);
+ return sprintf(buf, "%d\n", position);
+}
+
+static ssize_t fxls8471_position_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct fxls8471_data *pdata = &fxls8471_dev;
+ unsigned long position;
+
+ if (kstrtoul(buf, 10, &position) < 0)
+ return -EINVAL;
+ atomic_set(&pdata->position, position);
+
+ return count;
+}
+
+static ssize_t fxls8471_data_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct fxls8471_data *pdata = &fxls8471_dev;
+ int ret = 0;
+ struct fxls8471_data_axis data;
+ ret = fxls8471_read_data(pdata, &data);
+ if (!ret)
+ fxls8471_data_convert(pdata, &data);
+ return sprintf(buf, "%d,%d,%d\n", data.x, data.y, data.z);
+}
+
+static ssize_t fxls8471_range_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct fxls8471_data *pdata = &fxls8471_dev;
+ int range = 0;
+
+ range = atomic_read(&pdata->range);
+ return sprintf(buf, "%d\n", range);
+}
+
+static ssize_t fxls8471_range_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct fxls8471_data *pdata = &fxls8471_dev;
+ int ret;
+ unsigned long range;
+
+ if (kstrtoul(buf, 10, &range) < 0)
+ return -EINVAL;
+
+ if (range == atomic_read(&pdata->range))
+ return count;
+
+ if (atomic_read(&pdata->active))
+ printk(KERN_INFO "Pls set the sensor standby and then actived\n");
+ ret = fxls8471_change_range(pdata, range);
+ if (!ret)
+ atomic_set(&pdata->range, range);
+
+ return count;
+}
+
+static DEVICE_ATTR(enable, S_IWUSR | S_IRUGO, fxls8471_enable_show, fxls8471_enable_store);
+static DEVICE_ATTR(poll_delay, S_IWUSR | S_IRUGO, fxls8471_poll_delay_show,
+ fxls8471_poll_delay_store);
+
+static DEVICE_ATTR(position, S_IWUSR | S_IRUGO, fxls8471_position_show,
+ fxls8471_position_store);
+
+static DEVICE_ATTR(data, S_IWUSR | S_IRUGO, fxls8471_data_show, NULL);
+
+static DEVICE_ATTR(range, S_IWUSR | S_IRUGO, fxls8471_range_show, fxls8471_range_store);
+
+static struct attribute *fxls8471_attributes[] = {
+ &dev_attr_enable.attr,
+ &dev_attr_poll_delay.attr,
+ &dev_attr_position.attr,
+ &dev_attr_data.attr,
+ &dev_attr_range.attr,
+ NULL
+};
+
+static const struct attribute_group fxls8471_attr_group = {
+ .attrs = fxls8471_attributes,
+};
+
+static irqreturn_t fxls8471_irq_handler(int irq, void *dev)
+{
+ int ret;
+ u8 int_src;
+ struct fxls8471_data *pdata = (struct fxls8471_data *)dev;
+ struct fxls8471_data_axis data;
+ int_src = fxls8471_bus_read(pdata, FXLS8471_INT_SOURCE);
+ /* data ready interrupt */
+ if (int_src & 0x01) {
+ ret = fxls8471_read_data(pdata, &data);
+ if (!ret) {
+ fxls8471_data_convert(pdata, &data);
+ input_report_abs(pdata->idev, ABS_X, data.x);
+ input_report_abs(pdata->idev, ABS_Y, data.y);
+ input_report_abs(pdata->idev, ABS_Z, data.z);
+ input_sync(pdata->idev);
+ }
+
+ }
+ return IRQ_HANDLED;
+}
+
+int fxls8471_driver_init(struct fxls8471_data *pdata)
+{
+ int result, chip_id;
+
+ chip_id = fxls8471_bus_read(pdata, FXLS8471_WHO_AM_I);
+
+ if (chip_id != FXSL8471_ID) {
+ printk(KERN_ERR "read sensor who am i (0x%x)error !\n",
+ chip_id);
+ result = -EINVAL;
+ goto err_out;
+ }
+ /* Initialize the FXLS8471 chip */
+ pdata->chip_id = chip_id;
+ atomic_set(&pdata->delay, FXLS8471_DELAY_DEFAULT);
+ atomic_set(&pdata->position, FXLS8471_POSITION_DEFAULT);
+ result = misc_register(&fxls8471_device);
+ if (result != 0) {
+ printk(KERN_ERR "register acc miscdevice error");
+ goto err_out;
+ }
+
+ result =
+ sysfs_create_group(&fxls8471_device.this_device->kobj,
+ &fxls8471_attr_group);
+ if (result) {
+ printk(KERN_ERR "create device file failed!\n");
+ result = -EINVAL;
+ goto err_create_sysfs;
+ }
+ /*create data input device */
+ pdata->idev = input_allocate_device();
+ if (!pdata->idev) {
+ result = -ENOMEM;
+ printk(KERN_ERR "alloc fxls8471 input device failed!\n");
+ goto err_alloc_input_device;
+ }
+ pdata->idev->name = "FreescaleAccelerometer";
+ pdata->idev->id.bustype = BUS_I2C;
+ pdata->idev->evbit[0] = BIT_MASK(EV_ABS);
+ input_set_abs_params(pdata->idev, ABS_X, -0x7fff, 0x7fff, 0, 0);
+ input_set_abs_params(pdata->idev, ABS_Y, -0x7fff, 0x7fff, 0, 0);
+ input_set_abs_params(pdata->idev, ABS_Z, -0x7fff, 0x7fff, 0, 0);
+ result = input_register_device(pdata->idev);
+ if (result) {
+ printk(KERN_ERR "register fxls8471 input device failed!\n");
+ goto err_register_input_device;
+ }
+ if (pdata->irq) {
+ result =
+ request_threaded_irq(pdata->irq, NULL, fxls8471_irq_handler,
+ IRQF_TRIGGER_LOW | IRQF_ONESHOT,
+ pdata->idev->name, pdata);
+ if (result < 0) {
+ printk(KERN_ERR "failed to register MMA8x5x irq %d!\n",
+ pdata->irq);
+ goto err_register_irq;
+ }
+ }
+ fxls8471_device_init(pdata);
+ printk("fxls8471 device driver probe successfully\n");
+ return 0;
+err_register_irq:
+ input_unregister_device(pdata->idev);
+err_register_input_device:
+ input_free_device(pdata->idev);
+err_alloc_input_device:
+ sysfs_remove_group(&fxls8471_device.this_device->kobj,
+ &fxls8471_attr_group);
+err_create_sysfs:
+ misc_deregister(&fxls8471_device);
+err_out:
+ return result;
+}
+EXPORT_SYMBOL_GPL(fxls8471_driver_init);
+
+int fxls8471_driver_remove(struct fxls8471_data *pdata)
+{
+ fxls8471_change_mode(pdata, STANDBY);
+ misc_deregister(&fxls8471_device);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(fxls8471_driver_remove);
+
+#ifdef CONFIG_PM_SLEEP
+int fxls8471_driver_suspend(struct fxls8471_data *pdata)
+{
+ if (atomic_read(&pdata->active))
+ fxls8471_change_mode(pdata, STANDBY);
+ return 0;
+}
+EXPORT_SYMBOL_GPL(fxls8471_driver_suspend);
+
+int fxls8471_driver_resume(struct fxls8471_data *pdata)
+{
+ if (atomic_read(&pdata->active))
+ fxls8471_change_mode(pdata, ACTIVED);
+ return 0;
+}
+EXPORT_SYMBOL_GPL(fxls8471_driver_resume);
+
+#endif
diff --git a/drivers/input/misc/fxls8471.h b/drivers/input/misc/fxls8471.h
new file mode 100644
index 000000000000..6820ad1c0517
--- /dev/null
+++ b/drivers/input/misc/fxls8471.h
@@ -0,0 +1,94 @@
+/*
+ * fxls8471.h - Linux kernel modules for 3-Axis Accel sensor
+ * Copyright (C) 2014-2015 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#ifndef _FXSL8471_H
+#define _FXSL8471_H
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/mutex.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/hwmon-sysfs.h>
+#include <linux/err.h>
+#include <linux/input.h>
+
+#define FXSL8471_ID 0x6a
+
+/* register enum for fxls8471 registers */
+enum { FXLS8471_STATUS = 0x00, FXLS8471_OUT_X_MSB, FXLS8471_OUT_X_LSB,
+ FXLS8471_OUT_Y_MSB, FXLS8471_OUT_Y_LSB, FXLS8471_OUT_Z_MSB,
+ FXLS8471_OUT_Z_LSB, FXLS8471_F_SETUP =
+ 0x09, FXLS8471_TRIG_CFG, FXLS8471_SYSMOD,
+ FXLS8471_INT_SOURCE, FXLS8471_WHO_AM_I,
+ FXLS8471_XYZ_DATA_CFG, FXLS8471_HP_FILTER_CUTOFF,
+ FXLS8471_PL_STATUS, FXLS8471_PL_CFG, FXLS8471_PL_COUNT,
+ FXLS8471_PL_BF_ZCOMP, FXLS8471_P_L_THS_REG,
+ FXLS8471_FF_MT_CFG, FXLS8471_FF_MT_SRC, FXLS8471_FF_MT_THS,
+ FXLS8471_FF_MT_COUNT, FXLS8471_TRANSIENT_CFG =
+ 0x1D, FXLS8471_TRANSIENT_SRC, FXLS8471_TRANSIENT_THS,
+ FXLS8471_TRANSIENT_COUNT, FXLS8471_PULSE_CFG,
+ FXLS8471_PULSE_SRC, FXLS8471_PULSE_THSX, FXLS8471_PULSE_THSY,
+ FXLS8471_PULSE_THSZ, FXLS8471_PULSE_TMLT,
+ FXLS8471_PULSE_LTCY, FXLS8471_PULSE_WIND,
+ FXLS8471_ASLP_COUNT, FXLS8471_CTRL_REG1, FXLS8471_CTRL_REG2,
+ FXLS8471_CTRL_REG3, FXLS8471_CTRL_REG4, FXLS8471_CTRL_REG5,
+ FXLS8471_OFF_X, FXLS8471_OFF_Y, FXLS8471_OFF_Z,
+ FXLS8471_REG_END,
+};
+
+enum { STANDBY = 0, ACTIVED,
+};
+
+enum { MODE_2G = 0, MODE_4G, MODE_8G,
+};
+
+struct fxls8471_data_axis {
+ short x;
+ short y;
+ short z;
+};
+
+struct fxls8471_data {
+ void *bus_priv;
+ u16 bus_type;
+ int irq;
+ s32 (*write)(struct fxls8471_data *pdata, u8 reg, u8 val);
+ s32 (*read)(struct fxls8471_data *pdata, u8 reg);
+ s32 (*read_block)(struct fxls8471_data *pdata, u8 reg, u8 len,
+ u8 *val);
+ struct input_dev *idev;
+ atomic_t active;
+ atomic_t delay;
+ atomic_t position;
+ atomic_t range;
+ u8 chip_id;
+};
+
+extern struct fxls8471_data fxls8471_dev;
+
+int fxls8471_driver_init(struct fxls8471_data *pdata);
+int fxls8471_driver_remove(struct fxls8471_data *pdata);
+int fxls8471_driver_suspend(struct fxls8471_data *pdata);
+int fxls8471_driver_resume(struct fxls8471_data *pdata);
+
+#endif /* */
diff --git a/drivers/input/misc/fxls8471_i2c.c b/drivers/input/misc/fxls8471_i2c.c
new file mode 100644
index 000000000000..f752ddd0d14b
--- /dev/null
+++ b/drivers/input/misc/fxls8471_i2c.c
@@ -0,0 +1,111 @@
+/*
+ * fxls8471-i2c.c - Linux kernel modules for 3-Axis Smart Orientation
+ * /Motion Sensor
+ * Version : 01.00
+ * Time : Dec.26, 2012
+ * Author : rick zhang <rick.zhang@freescale.com>
+ *
+ * Copyright (C) 2010-2011 Freescale Semiconductor.
+ *
+ * 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.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/err.h>
+#include <linux/i2c.h>
+#include "fxls8471.h"
+
+static s32 fxls8471_i2c_write(struct fxls8471_data *pdata, u8 reg, u8 val)
+{
+ struct i2c_client *client = (struct i2c_client *)pdata->bus_priv;
+ return i2c_smbus_write_byte_data(client, reg, val);
+}
+
+static int fxls8471_i2c_read(struct fxls8471_data *pdata, u8 reg)
+{
+ struct i2c_client *client = (struct i2c_client *)pdata->bus_priv;
+ return i2c_smbus_read_byte_data(client, reg);
+}
+
+static int fxls8471_i2c_read_block(struct fxls8471_data *pdata, u8 reg, u8 len,
+ u8 *val)
+{
+ struct i2c_client *client = (struct i2c_client *)pdata->bus_priv;
+ return i2c_smbus_read_i2c_block_data(client, reg, len, val);
+}
+
+static int fxls8471_i2c_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ fxls8471_dev.bus_priv = client;
+ fxls8471_dev.bus_type = BUS_I2C;
+ fxls8471_dev.irq = client->irq;
+ fxls8471_dev.read = fxls8471_i2c_read;
+ fxls8471_dev.write = fxls8471_i2c_write;
+ fxls8471_dev.read_block = fxls8471_i2c_read_block;
+ i2c_set_clientdata(client, &fxls8471_dev);
+ return fxls8471_driver_init(&fxls8471_dev);
+}
+
+static int fxls8471_i2c_remove(struct i2c_client *client)
+{
+ return fxls8471_driver_remove(&fxls8471_dev);
+}
+
+#ifdef CONFIG_PM
+static int fxls8471_i2c_suspend(struct device *dev)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ return fxls8471_driver_suspend(i2c_get_clientdata(client));
+}
+
+static int fxls8471_i2c_resume(struct device *dev)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ return fxls8471_driver_resume(i2c_get_clientdata(client));
+}
+
+#else /* */
+#define fxls8471_i2c_suspend NULL
+#define fxls8471_i2c_resume NULL
+#endif /* */
+static const struct i2c_device_id fxls8471_i2c_id[] = {
+ {"fxls8471", 0},
+ {}
+};
+
+MODULE_DEVICE_TABLE(i2c, fxls8471_i2c_id);
+
+static SIMPLE_DEV_PM_OPS(fxls8471_pm_ops, fxls8471_i2c_suspend,
+ fxls8471_i2c_resume);
+
+static struct i2c_driver fxls8471_i2c_driver = {
+ .driver = {
+ .name = "fxls8471",
+ .owner = THIS_MODULE,
+ .pm = &fxls8471_pm_ops,
+ },
+ .probe = fxls8471_i2c_probe,
+ .remove = fxls8471_i2c_remove,
+ .id_table = fxls8471_i2c_id,
+};
+
+module_i2c_driver(fxls8471_i2c_driver);
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("FXLS8471 3-Axis Acc Sensor driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/input/misc/isl29023.c b/drivers/input/misc/isl29023.c
new file mode 100644
index 000000000000..851a0fa177b6
--- /dev/null
+++ b/drivers/input/misc/isl29023.c
@@ -0,0 +1,1075 @@
+/*
+ * Copyright (C) 2011-2014 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/input.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/mutex.h>
+#include <linux/delay.h>
+#include <linux/of.h>
+#include <linux/regulator/consumer.h>
+#include <linux/isl29023.h>
+
+#define ISL29023_DRV_NAME "isl29023"
+#define DRIVER_VERSION "1.0"
+
+#define ISL29023_COMMAND1 (0x00)
+#define ISL29023_MODE_SHIFT (5)
+#define ISL29023_MODE_MASK (0x7 << ISL29023_MODE_SHIFT)
+#define ISL29023_INT_FLAG_SHIFT (2)
+#define ISL29023_INT_FLAG_MASK (0x1 << ISL29023_INT_FLAG_SHIFT)
+#define ISL29023_INT_PERSISTS_SHIFT (0)
+#define ISL29023_INT_PERSISTS_MASK (0x3 << ISL29023_INT_PERSISTS_SHIFT)
+
+#define ISL29023_COMMAND2 (0x01)
+#define ISL29023_RES_SHIFT (2)
+#define ISL29023_RES_MASK (0x3 << ISL29023_RES_SHIFT)
+#define ISL29023_RANGE_SHIFT (0)
+#define ISL29023_RANGE_MASK (0x3 << ISL29023_RANGE_SHIFT)
+
+#define ISL29023_REG_LSB_SENSOR (0x02)
+#define ISL29023_REG_MSB_SENSOR (0x03)
+#define ISL29023_REG_IRQ_TH_LO_LSB (0x04)
+#define ISL29023_REG_IRQ_TH_LO_MSB (0x05)
+#define ISL29023_REG_IRQ_TH_HI_LSB (0x06)
+#define ISL29023_REG_IRQ_TH_HI_MSB (0x07)
+
+#define ISL29023_NUM_CACHABLE_REGS 8
+#define DEF_RANGE 2
+#define DEFAULT_REGISTOR_VAL 499
+
+struct isl29023_data {
+ struct i2c_client *client;
+ struct mutex lock;
+ struct input_dev *input;
+ struct work_struct work;
+ struct workqueue_struct *workqueue;
+ char phys[32];
+ u8 reg_cache[ISL29023_NUM_CACHABLE_REGS];
+ u8 mode_before_suspend;
+ u8 mode_before_interrupt;
+ u16 rext;
+};
+
+static int gain_range[] = {
+ 1000, 4000, 16000, 64000
+};
+
+/*
+ * register access helpers
+ */
+static int __isl29023_read_reg(struct i2c_client *client,
+ u32 reg, u8 mask, u8 shift)
+{
+ struct isl29023_data *data = i2c_get_clientdata(client);
+ return (data->reg_cache[reg] & mask) >> shift;
+}
+
+static int __isl29023_write_reg(struct i2c_client *client,
+ u32 reg, u8 mask, u8 shift, u8 val)
+{
+ struct isl29023_data *data = i2c_get_clientdata(client);
+ int ret = 0;
+ u8 tmp;
+
+ if (reg >= ISL29023_NUM_CACHABLE_REGS)
+ return -EINVAL;
+
+ mutex_lock(&data->lock);
+
+ tmp = data->reg_cache[reg];
+ tmp &= ~mask;
+ tmp |= val << shift;
+
+ ret = i2c_smbus_write_byte_data(client, reg, tmp);
+ if (!ret)
+ data->reg_cache[reg] = tmp;
+
+ mutex_unlock(&data->lock);
+ return ret;
+}
+
+/*
+ * internally used functions
+ */
+static int isl29023_get_int_persists(struct i2c_client *client)
+{
+ return __isl29023_read_reg(client, ISL29023_COMMAND1,
+ ISL29023_INT_PERSISTS_MASK, ISL29023_INT_PERSISTS_SHIFT);
+}
+
+static int isl29023_set_int_persists(struct i2c_client *client,
+ int int_persists)
+{
+ return __isl29023_write_reg(client, ISL29023_COMMAND1,
+ ISL29023_INT_PERSISTS_MASK, ISL29023_INT_PERSISTS_SHIFT,
+ int_persists);
+}
+
+/*
+ * interrupt flag
+ */
+static int isl29023_get_int_flag(struct i2c_client *client)
+{
+ return __isl29023_read_reg(client, ISL29023_COMMAND1,
+ ISL29023_INT_FLAG_MASK, ISL29023_INT_FLAG_SHIFT);
+}
+
+static int isl29023_set_int_flag(struct i2c_client *client, int flag)
+{
+ return __isl29023_write_reg(client, ISL29023_COMMAND1,
+ ISL29023_INT_FLAG_MASK, ISL29023_INT_FLAG_SHIFT, flag);
+}
+
+/*
+ * interrupt lt
+ */
+static int isl29023_get_int_lt(struct i2c_client *client)
+{
+ struct isl29023_data *data = i2c_get_clientdata(client);
+ int lsb, msb, lt;
+
+ mutex_lock(&data->lock);
+ lsb = i2c_smbus_read_byte_data(client, ISL29023_REG_IRQ_TH_LO_LSB);
+
+ if (lsb < 0) {
+ mutex_unlock(&data->lock);
+ return lsb;
+ }
+
+ msb = i2c_smbus_read_byte_data(client, ISL29023_REG_IRQ_TH_LO_MSB);
+ mutex_unlock(&data->lock);
+
+ if (msb < 0)
+ return msb;
+
+ lt = ((msb << 8) | lsb);
+
+ return lt;
+}
+
+static int isl29023_set_int_lt(struct i2c_client *client, int lt)
+{
+ int ret = 0;
+ struct isl29023_data *data = i2c_get_clientdata(client);
+
+ mutex_lock(&data->lock);
+ ret = i2c_smbus_write_byte_data(client, ISL29023_REG_IRQ_TH_LO_LSB,
+ lt & 0xff);
+ if (ret < 0) {
+ mutex_unlock(&data->lock);
+ return ret;
+ }
+
+ ret = i2c_smbus_write_byte_data(client, ISL29023_REG_IRQ_TH_LO_MSB,
+ (lt >> 8) & 0xff);
+ if (ret < 0) {
+ mutex_unlock(&data->lock);
+ return ret;
+ }
+
+ data->reg_cache[ISL29023_REG_IRQ_TH_LO_MSB] = (lt >> 8) & 0xff;
+ data->reg_cache[ISL29023_REG_IRQ_TH_LO_LSB] = lt & 0xff;
+ mutex_unlock(&data->lock);
+
+ return ret;
+}
+
+/*
+ * interrupt ht
+ */
+static int isl29023_get_int_ht(struct i2c_client *client)
+{
+ struct isl29023_data *data = i2c_get_clientdata(client);
+ int lsb, msb, ht;
+
+ mutex_lock(&data->lock);
+ lsb = i2c_smbus_read_byte_data(client, ISL29023_REG_IRQ_TH_HI_LSB);
+
+ if (lsb < 0) {
+ mutex_unlock(&data->lock);
+ return lsb;
+ }
+
+ msb = i2c_smbus_read_byte_data(client, ISL29023_REG_IRQ_TH_HI_MSB);
+ mutex_unlock(&data->lock);
+
+ if (msb < 0)
+ return msb;
+
+ ht = ((msb << 8) | lsb);
+
+ return ht;
+}
+
+static int isl29023_set_int_ht(struct i2c_client *client, int ht)
+{
+ int ret = 0;
+ struct isl29023_data *data = i2c_get_clientdata(client);
+
+ mutex_lock(&data->lock);
+ ret = i2c_smbus_write_byte_data(client, ISL29023_REG_IRQ_TH_HI_LSB,
+ ht & 0xff);
+ if (ret < 0) {
+ mutex_unlock(&data->lock);
+ return ret;
+ }
+
+ ret = i2c_smbus_write_byte_data(client, ISL29023_REG_IRQ_TH_HI_MSB,
+ (ht >> 8) & 0xff);
+ if (ret < 0) {
+ mutex_unlock(&data->lock);
+ return ret;
+ }
+
+ data->reg_cache[ISL29023_REG_IRQ_TH_HI_MSB] = (ht >> 8) & 0xff;
+ data->reg_cache[ISL29023_REG_IRQ_TH_HI_LSB] = ht & 0xff;
+ mutex_unlock(&data->lock);
+
+ return ret;
+}
+
+/*
+ * range
+ */
+static int isl29023_get_range(struct i2c_client *client)
+{
+ return __isl29023_read_reg(client, ISL29023_COMMAND2,
+ ISL29023_RANGE_MASK, ISL29023_RANGE_SHIFT);
+}
+
+static int isl29023_set_range(struct i2c_client *client, int range)
+{
+ return __isl29023_write_reg(client, ISL29023_COMMAND2,
+ ISL29023_RANGE_MASK, ISL29023_RANGE_SHIFT, range);
+}
+
+/*
+ * resolution
+ */
+static int isl29023_get_resolution(struct i2c_client *client)
+{
+ return __isl29023_read_reg(client, ISL29023_COMMAND2,
+ ISL29023_RES_MASK, ISL29023_RES_SHIFT);
+}
+
+static int isl29023_set_resolution(struct i2c_client *client, int res)
+{
+ return __isl29023_write_reg(client, ISL29023_COMMAND2,
+ ISL29023_RES_MASK, ISL29023_RES_SHIFT, res);
+}
+
+/*
+ * mode
+ */
+static int isl29023_get_mode(struct i2c_client *client)
+{
+ return __isl29023_read_reg(client, ISL29023_COMMAND1,
+ ISL29023_MODE_MASK, ISL29023_MODE_SHIFT);
+}
+
+static int isl29023_set_mode(struct i2c_client *client, int mode)
+{
+ return __isl29023_write_reg(client, ISL29023_COMMAND1,
+ ISL29023_MODE_MASK, ISL29023_MODE_SHIFT, mode);
+}
+
+/*
+ * power_state
+ */
+static int isl29023_set_power_state(struct i2c_client *client, int state)
+{
+ return __isl29023_write_reg(client, ISL29023_COMMAND1,
+ ISL29023_MODE_MASK, ISL29023_MODE_SHIFT,
+ state ?
+ ISL29023_ALS_ONCE_MODE : ISL29023_PD_MODE);
+}
+
+static int isl29023_get_power_state(struct i2c_client *client)
+{
+ struct isl29023_data *data = i2c_get_clientdata(client);
+ u8 cmdreg = data->reg_cache[ISL29023_COMMAND1];
+
+ if (cmdreg & ISL29023_MODE_MASK)
+ return 1;
+ else
+ return 0;
+}
+
+static int isl29023_get_adc_value(struct i2c_client *client)
+{
+ struct isl29023_data *data = i2c_get_clientdata(client);
+ int lsb, msb, range, bitdepth;
+
+ mutex_lock(&data->lock);
+ lsb = i2c_smbus_read_byte_data(client, ISL29023_REG_LSB_SENSOR);
+
+ if (lsb < 0) {
+ mutex_unlock(&data->lock);
+ return lsb;
+ }
+
+ msb = i2c_smbus_read_byte_data(client, ISL29023_REG_MSB_SENSOR);
+ mutex_unlock(&data->lock);
+
+ if (msb < 0)
+ return msb;
+
+ range = isl29023_get_range(client);
+ bitdepth = (4 - isl29023_get_resolution(client)) * 4;
+ return (((msb << 8) | lsb) * ((gain_range[range] * 499) / data->rext))
+ >> bitdepth;
+}
+
+static int isl29023_get_int_lt_value(struct i2c_client *client)
+{
+ struct isl29023_data *data = i2c_get_clientdata(client);
+ int lsb, msb, range, bitdepth;
+
+ mutex_lock(&data->lock);
+ lsb = i2c_smbus_read_byte_data(client, ISL29023_REG_IRQ_TH_LO_LSB);
+
+ if (lsb < 0) {
+ mutex_unlock(&data->lock);
+ return lsb;
+ }
+
+ msb = i2c_smbus_read_byte_data(client, ISL29023_REG_IRQ_TH_LO_MSB);
+ mutex_unlock(&data->lock);
+
+ if (msb < 0)
+ return msb;
+
+ range = isl29023_get_range(client);
+ bitdepth = (4 - isl29023_get_resolution(client)) * 4;
+ return (((msb << 8) | lsb) * ((gain_range[range] * 499) / data->rext))
+ >> bitdepth;
+}
+
+static int isl29023_get_int_ht_value(struct i2c_client *client)
+{
+ struct isl29023_data *data = i2c_get_clientdata(client);
+ int lsb, msb, range, bitdepth;
+
+ mutex_lock(&data->lock);
+ lsb = i2c_smbus_read_byte_data(client, ISL29023_REG_IRQ_TH_HI_LSB);
+
+ if (lsb < 0) {
+ mutex_unlock(&data->lock);
+ return lsb;
+ }
+
+ msb = i2c_smbus_read_byte_data(client, ISL29023_REG_IRQ_TH_HI_MSB);
+ mutex_unlock(&data->lock);
+
+ if (msb < 0)
+ return msb;
+
+ range = isl29023_get_range(client);
+ bitdepth = (4 - isl29023_get_resolution(client)) * 4;
+ return (((msb << 8) | lsb) * ((gain_range[range] * 499) / data->rext))
+ >> bitdepth;
+}
+
+/*
+ * sysfs layer
+ */
+
+/*
+ * interrupt persists
+ */
+static ssize_t isl29023_show_int_persists(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ return sprintf(buf, "%i\n", isl29023_get_int_persists(client));
+}
+
+static ssize_t isl29023_store_int_persists(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ unsigned long val;
+ int ret;
+
+ if ((kstrtoul(buf, 10, &val) < 0) ||
+ (val > ISL29023_INT_PERSISTS_16))
+ return -EINVAL;
+
+ ret = isl29023_set_int_persists(client, val);
+ if (ret < 0)
+ return ret;
+
+ return count;
+}
+
+static DEVICE_ATTR(int_persists, S_IWUSR | S_IRUGO,
+ isl29023_show_int_persists, isl29023_store_int_persists);
+
+/*
+ *interrupt flag
+ */
+static ssize_t isl29023_show_int_flag(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ return sprintf(buf, "%i\n", isl29023_get_int_flag(client));
+}
+
+static ssize_t isl29023_store_int_flag(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ unsigned long val;
+ int ret;
+
+ if ((kstrtoul(buf, 10, &val) < 0) || (val > 1))
+ return -EINVAL;
+
+ ret = isl29023_set_int_flag(client, val);
+ if (ret < 0)
+ return ret;
+
+ return count;
+}
+
+static DEVICE_ATTR(int_flag, S_IWUSR | S_IRUGO,
+ isl29023_show_int_flag, isl29023_store_int_flag);
+
+/*
+ * interrupt lt
+ */
+static ssize_t isl29023_show_int_lt(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ return sprintf(buf, "%i\n", isl29023_get_int_lt(client));
+}
+
+static ssize_t isl29023_store_int_lt(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ unsigned long val;
+ int ret;
+
+ if ((kstrtoul(buf, 16, &val) < 0) || (val > 0xffff))
+ return -EINVAL;
+
+ ret = isl29023_set_int_lt(client, val);
+ if (ret < 0)
+ return ret;
+
+ return count;
+}
+
+static DEVICE_ATTR(int_lt, S_IWUSR | S_IRUGO,
+ isl29023_show_int_lt, isl29023_store_int_lt);
+
+/*
+ *interrupt ht
+ */
+static ssize_t isl29023_show_int_ht(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ return sprintf(buf, "%i\n", isl29023_get_int_ht(client));
+}
+
+static ssize_t isl29023_store_int_ht(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ unsigned long val;
+ int ret;
+
+ if ((kstrtoul(buf, 16, &val) < 0) || (val > 0xffff))
+ return -EINVAL;
+
+ ret = isl29023_set_int_ht(client, val);
+ if (ret < 0)
+ return ret;
+
+ return count;
+}
+
+static DEVICE_ATTR(int_ht, S_IWUSR | S_IRUGO,
+ isl29023_show_int_ht, isl29023_store_int_ht);
+
+/*
+ * range
+ */
+static ssize_t isl29023_show_range(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ return sprintf(buf, "%i\n", isl29023_get_range(client));
+}
+
+static ssize_t isl29023_store_range(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ unsigned long val;
+ int ret;
+
+ if ((kstrtoul(buf, 10, &val) < 0) || (val > ISL29023_RANGE_64K))
+ return -EINVAL;
+
+ ret = isl29023_set_range(client, val);
+ if (ret < 0)
+ return ret;
+
+ return count;
+}
+
+static DEVICE_ATTR(range, S_IWUSR | S_IRUGO,
+ isl29023_show_range, isl29023_store_range);
+
+
+/*
+ * resolution
+ */
+static ssize_t isl29023_show_resolution(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ return sprintf(buf, "%d\n", isl29023_get_resolution(client));
+}
+
+static ssize_t isl29023_store_resolution(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ unsigned long val;
+ int ret;
+
+ if ((kstrtoul(buf, 10, &val) < 0) || (val > ISL29023_RES_4))
+ return -EINVAL;
+
+ ret = isl29023_set_resolution(client, val);
+ if (ret < 0)
+ return ret;
+
+ return count;
+}
+
+static DEVICE_ATTR(resolution, S_IWUSR | S_IRUGO,
+ isl29023_show_resolution, isl29023_store_resolution);
+
+/*
+ *mode
+ */
+static ssize_t isl29023_show_mode(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ return sprintf(buf, "%d\n", isl29023_get_mode(client));
+}
+
+static ssize_t isl29023_store_mode(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ unsigned long val;
+ int ret;
+
+ if ((kstrtoul(buf, 10, &val) < 0) ||
+ (val > ISL29023_IR_CONT_MODE))
+ return -EINVAL;
+
+ /* clear the interrupt flag */
+ i2c_smbus_read_byte_data(client, ISL29023_COMMAND1);
+ ret = isl29023_set_mode(client, val);
+ if (ret < 0)
+ return ret;
+
+ return count;
+}
+
+static DEVICE_ATTR(mode, S_IWUSR | S_IRUGO,
+ isl29023_show_mode, isl29023_store_mode);
+
+
+/*
+ *power state
+ */
+static ssize_t isl29023_show_power_state(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ return sprintf(buf, "%d\n", isl29023_get_power_state(client));
+}
+
+static ssize_t isl29023_store_power_state(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ unsigned long val;
+ int ret;
+
+ if ((kstrtoul(buf, 10, &val) < 0) || (val > 1))
+ return -EINVAL;
+
+ ret = isl29023_set_power_state(client, val);
+ return ret ? ret : count;
+}
+
+static DEVICE_ATTR(power_state, S_IWUSR | S_IRUGO,
+ isl29023_show_power_state, isl29023_store_power_state);
+
+/*
+ * lux
+ */
+static ssize_t isl29023_show_lux(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+
+ /* No LUX data if not operational */
+ if (!isl29023_get_power_state(client))
+ return -EBUSY;
+
+ return sprintf(buf, "%d\n", isl29023_get_adc_value(client));
+}
+
+static DEVICE_ATTR(lux, S_IRUGO, isl29023_show_lux, NULL);
+
+/*
+ * lux interrupt low threshold
+ */
+static ssize_t isl29023_show_int_lt_lux(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+
+ /* No LUX data if not operational */
+ if (isl29023_get_mode(client) != ISL29023_ALS_ONCE_MODE &&
+ isl29023_get_mode(client) != ISL29023_ALS_CONT_MODE)
+ return -EIO;
+
+ return sprintf(buf, "%d\n", isl29023_get_int_lt_value(client));
+}
+
+static ssize_t isl29023_store_int_lt_lux(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct isl29023_data *data = i2c_get_clientdata(client);
+ unsigned long val, lux_data;
+ int range, bitdepth, ret;
+ u8 lsb, msb;
+
+ if ((kstrtoul(buf, 10, &val) < 0))
+ return -EINVAL;
+
+ /* No LUX data if not operational */
+ if (isl29023_get_mode(client) != ISL29023_ALS_ONCE_MODE &&
+ isl29023_get_mode(client) != ISL29023_ALS_CONT_MODE)
+ return -EIO;
+
+ if (val > (gain_range[isl29023_get_range(client)]*499/data->rext))
+ return -EINVAL;
+
+ range = isl29023_get_range(client);
+ bitdepth = (4 - isl29023_get_resolution(client)) * 4;
+ lux_data = ((unsigned long)(val << bitdepth)) /
+ ((gain_range[range] * 499) / data->rext);
+ lux_data &= 0xffff;
+
+ msb = lux_data >> 8;
+ lsb = lux_data & 0xff;
+
+ mutex_lock(&data->lock);
+ ret = i2c_smbus_write_byte_data(client, ISL29023_REG_IRQ_TH_LO_LSB,
+ lsb);
+ if (ret < 0) {
+ mutex_unlock(&data->lock);
+ return ret;
+ }
+
+ ret = i2c_smbus_write_byte_data(client, ISL29023_REG_IRQ_TH_LO_MSB,
+ msb);
+ if (ret < 0) {
+ mutex_unlock(&data->lock);
+ return ret;
+ }
+
+ data->reg_cache[ISL29023_REG_IRQ_TH_LO_MSB] = msb;
+ data->reg_cache[ISL29023_REG_IRQ_TH_LO_LSB] = lsb;
+ mutex_unlock(&data->lock);
+
+ return count;
+}
+
+static DEVICE_ATTR(int_lt_lux, S_IWUSR | S_IRUGO,
+ isl29023_show_int_lt_lux, isl29023_store_int_lt_lux);
+
+/*
+ * lux interrupt high threshold
+ */
+static ssize_t isl29023_show_int_ht_lux(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+
+ /* No LUX data if not operational */
+ if (isl29023_get_mode(client) != ISL29023_ALS_ONCE_MODE &&
+ isl29023_get_mode(client) != ISL29023_ALS_CONT_MODE)
+ return -EIO;
+
+ return sprintf(buf, "%d\n", isl29023_get_int_ht_value(client));
+}
+
+static ssize_t isl29023_store_int_ht_lux(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct isl29023_data *data = i2c_get_clientdata(client);
+ unsigned long val, lux_data;
+ int range, bitdepth, ret;
+ u8 lsb, msb;
+
+ if ((kstrtoul(buf, 10, &val) < 0))
+ return -EINVAL;
+
+ /* No LUX data if not operational */
+ if (isl29023_get_mode(client) != ISL29023_ALS_ONCE_MODE &&
+ isl29023_get_mode(client) != ISL29023_ALS_CONT_MODE)
+ return -EIO;
+
+ if (val > (gain_range[isl29023_get_range(client)]*499/data->rext))
+ return -EINVAL;
+
+ range = isl29023_get_range(client);
+ bitdepth = (4 - isl29023_get_resolution(client)) * 4;
+ lux_data = ((unsigned long)(val << bitdepth)) /
+ ((gain_range[range] * 499) / data->rext);
+ lux_data &= 0xffff;
+
+ msb = lux_data >> 8;
+ lsb = lux_data & 0xff;
+
+ mutex_lock(&data->lock);
+ ret = i2c_smbus_write_byte_data(client, ISL29023_REG_IRQ_TH_HI_LSB,
+ lsb);
+ if (ret < 0) {
+ mutex_unlock(&data->lock);
+ return ret;
+ }
+
+ ret = i2c_smbus_write_byte_data(client, ISL29023_REG_IRQ_TH_HI_MSB,
+ msb);
+ if (ret < 0) {
+ mutex_unlock(&data->lock);
+ return ret;
+ }
+
+ data->reg_cache[ISL29023_REG_IRQ_TH_HI_MSB] = msb;
+ data->reg_cache[ISL29023_REG_IRQ_TH_HI_LSB] = lsb;
+ mutex_unlock(&data->lock);
+
+ return count;
+}
+
+static DEVICE_ATTR(int_ht_lux, S_IWUSR | S_IRUGO,
+ isl29023_show_int_ht_lux, isl29023_store_int_ht_lux);
+
+static struct attribute *isl29023_attributes[] = {
+ &dev_attr_int_persists.attr,
+ &dev_attr_range.attr,
+ &dev_attr_resolution.attr,
+ &dev_attr_mode.attr,
+ &dev_attr_power_state.attr,
+ &dev_attr_lux.attr,
+ &dev_attr_int_lt_lux.attr,
+ &dev_attr_int_ht_lux.attr,
+ &dev_attr_int_lt.attr,
+ &dev_attr_int_ht.attr,
+ &dev_attr_int_flag.attr,
+ NULL
+};
+
+static const struct attribute_group isl29023_attr_group = {
+ .attrs = isl29023_attributes,
+};
+
+static int isl29023_init_client(struct i2c_client *client)
+{
+ struct isl29023_data *data = i2c_get_clientdata(client);
+ int i;
+
+ /* read all the registers once to fill the cache.
+ * if one of the reads fails, we consider the init failed */
+ for (i = 0; i < ARRAY_SIZE(data->reg_cache); i++) {
+ int v = i2c_smbus_read_byte_data(client, i);
+ if (v < 0)
+ return -ENODEV;
+
+ data->reg_cache[i] = v;
+ }
+
+ /* set defaults */
+ isl29023_set_int_persists(client, ISL29023_INT_PERSISTS_8);
+ isl29023_set_int_ht(client, 0xffff);
+ isl29023_set_int_lt(client, 0x0);
+ isl29023_set_range(client, ISL29023_RANGE_16K);
+ isl29023_set_resolution(client, ISL29023_RES_16);
+ isl29023_set_mode(client, ISL29023_ALS_ONCE_MODE);
+ isl29023_set_int_flag(client, 0);
+ isl29023_set_power_state(client, 0);
+
+ return 0;
+}
+
+static void isl29023_work(struct work_struct *work)
+{
+ struct isl29023_data *data =
+ container_of(work, struct isl29023_data, work);
+ struct i2c_client *client = data->client;
+ int lux;
+
+ /* Clear interrupt flag */
+ isl29023_set_int_flag(client, 0);
+
+ data->mode_before_interrupt = isl29023_get_mode(client);
+ lux = isl29023_get_adc_value(client);
+
+ /* To clear the interrpt status */
+ isl29023_set_power_state(client, ISL29023_PD_MODE);
+ isl29023_set_mode(client, data->mode_before_interrupt);
+
+ msleep(100);
+
+ input_report_abs(data->input, ABS_MISC, lux);
+ input_sync(data->input);
+}
+
+static irqreturn_t isl29023_irq_handler(int irq, void *handle)
+{
+ struct isl29023_data *data = handle;
+ int cmd_1;
+ cmd_1 = i2c_smbus_read_byte_data(data->client, ISL29023_COMMAND1);
+ if (!(cmd_1 & ISL29023_INT_FLAG_MASK))
+ return IRQ_NONE;
+
+ queue_work(data->workqueue, &data->work);
+ return IRQ_HANDLED;
+}
+
+/*
+ * I2C layer
+ */
+static int isl29023_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
+ struct isl29023_data *data;
+ struct input_dev *input_dev;
+ int err = 0;
+ struct regulator *vdd = NULL;
+ u32 rext = 0;
+ struct device_node *of_node = client->dev.of_node;
+ struct irq_data *irq_data = irq_get_irq_data(client->irq);
+ u32 irq_flag;
+ bool shared_irq;
+
+ vdd = devm_regulator_get(&client->dev, "vdd");
+ if (!IS_ERR(vdd)) {
+ err = regulator_enable(vdd);
+ if (err) {
+ dev_err(&client->dev, "vdd set voltage error\n");
+ return err;
+ }
+ }
+
+ err = of_property_read_u32(of_node, "rext", &rext);
+ if (err || rext == 0)
+ rext = DEFAULT_REGISTOR_VAL;
+ shared_irq = of_property_read_bool(of_node, "shared-interrupt");
+
+ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE))
+ return -EIO;
+
+ data = kzalloc(sizeof(struct isl29023_data), GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
+
+ data->client = client;
+ data->rext = (u16)rext;
+ snprintf(data->phys, sizeof(data->phys),
+ "%s", dev_name(&client->dev));
+ i2c_set_clientdata(client, data);
+ mutex_init(&data->lock);
+
+ /* initialize the ISL29023 chip */
+ err = isl29023_init_client(client);
+ if (err)
+ goto exit_kfree;
+
+ /* register sysfs hooks */
+ err = sysfs_create_group(&client->dev.kobj, &isl29023_attr_group);
+ if (err)
+ goto exit_kfree;
+
+ input_dev = input_allocate_device();
+ if (!input_dev) {
+ err = -ENOMEM;
+ goto exit_kfree;
+ }
+
+ data->input = input_dev;
+ input_dev->name = "isl29023 light sensor";
+ input_dev->id.bustype = BUS_I2C;
+ input_dev->phys = data->phys;
+
+ __set_bit(EV_ABS, input_dev->evbit);
+ input_set_abs_params(input_dev, ABS_MISC, 0,
+ gain_range[DEF_RANGE]*499/data->rext, 0, 0);
+
+ err = input_register_device(input_dev);
+ if (err)
+ goto exit_free_input;
+
+ irq_flag = irqd_get_trigger_type(irq_data);
+ irq_flag |= IRQF_ONESHOT;
+ if (shared_irq)
+ irq_flag |= IRQF_SHARED;
+ err = request_threaded_irq(client->irq, NULL,
+ isl29023_irq_handler, irq_flag,
+ client->dev.driver->name, data);
+ if (err < 0) {
+ dev_err(&client->dev, "failed to register irq %d!\n",
+ client->irq);
+ goto exit_free_input;
+ }
+
+ data->workqueue = create_singlethread_workqueue("isl29023");
+ INIT_WORK(&data->work, isl29023_work);
+ if (data->workqueue == NULL) {
+ dev_err(&client->dev, "couldn't create workqueue\n");
+ err = -ENOMEM;
+ goto exit_free_interrupt;
+ }
+
+ dev_info(&client->dev, "driver version %s enabled\n", DRIVER_VERSION);
+ return 0;
+
+exit_free_interrupt:
+ free_irq(client->irq, data);
+exit_free_input:
+ input_free_device(input_dev);
+exit_kfree:
+ kfree(data);
+ return err;
+}
+
+static int isl29023_remove(struct i2c_client *client)
+{
+ struct isl29023_data *data = i2c_get_clientdata(client);
+
+ cancel_work_sync(&data->work);
+ destroy_workqueue(data->workqueue);
+ free_irq(client->irq, data);
+ input_unregister_device(data->input);
+ input_free_device(data->input);
+ sysfs_remove_group(&client->dev.kobj, &isl29023_attr_group);
+ isl29023_set_power_state(client, 0);
+ kfree(i2c_get_clientdata(client));
+
+ return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int isl29023_suspend(struct device *dev)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct isl29023_data *data = i2c_get_clientdata(client);
+
+ data->mode_before_suspend = isl29023_get_mode(client);
+ return isl29023_set_power_state(client, ISL29023_PD_MODE);
+}
+
+static int isl29023_resume(struct device *dev)
+{
+ int i;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct isl29023_data *data = i2c_get_clientdata(client);
+
+ /* restore registers from cache */
+ for (i = 0; i < ARRAY_SIZE(data->reg_cache); i++)
+ if (i2c_smbus_write_byte_data(client, i, data->reg_cache[i]))
+ return -EIO;
+
+ return isl29023_set_mode(client, data->mode_before_suspend);
+}
+#endif
+
+static SIMPLE_DEV_PM_OPS(isl29023_pm_ops, isl29023_suspend, isl29023_resume);
+
+static const struct i2c_device_id isl29023_id[] = {
+ { ISL29023_DRV_NAME, 0 },
+ {}
+};
+MODULE_DEVICE_TABLE(i2c, isl29023_id);
+
+static struct i2c_driver isl29023_driver = {
+ .driver = {
+ .name = ISL29023_DRV_NAME,
+ .owner = THIS_MODULE,
+ .pm = &isl29023_pm_ops,
+ },
+ .probe = isl29023_probe,
+ .remove = isl29023_remove,
+ .id_table = isl29023_id,
+};
+
+static int __init isl29023_init(void)
+{
+ return i2c_add_driver(&isl29023_driver);
+}
+
+static void __exit isl29023_exit(void)
+{
+ i2c_del_driver(&isl29023_driver);
+}
+
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("ISL29023 ambient light sensor driver");
+MODULE_LICENSE("GPL");
+MODULE_VERSION(DRIVER_VERSION);
+
+module_init(isl29023_init);
+module_exit(isl29023_exit);
diff --git a/drivers/input/misc/mma8450.c b/drivers/input/misc/mma8450.c
index b60cdea73826..7df8e6d1f337 100644
--- a/drivers/input/misc/mma8450.c
+++ b/drivers/input/misc/mma8450.c
@@ -1,7 +1,7 @@
/*
* Driver for Freescale's 3-Axis Accelerometer MMA8450
*
- * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright (C) 2011-2015 Freescale Semiconductor, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -25,6 +25,7 @@
#include <linux/i2c.h>
#include <linux/input-polldev.h>
#include <linux/of_device.h>
+#include <linux/mutex.h>
#define MMA8450_DRV_NAME "mma8450"
@@ -51,11 +52,22 @@
#define MMA8450_CTRL_REG1 0x38
#define MMA8450_CTRL_REG2 0x39
+#define MMA8450_ID 0xC6
+#define MMA8450_WHO_AM_I 0x0F
+
+enum {
+ MODE_STANDBY = 0,
+ MODE_2G,
+ MODE_4G,
+ MODE_8G,
+};
/* mma8450 status */
struct mma8450 {
struct i2c_client *client;
struct input_polled_dev *idev;
+ struct mutex mma8450_lock;
+ u8 mode;
};
static int mma8450_read(struct mma8450 *m, unsigned off)
@@ -112,16 +124,19 @@ static void mma8450_poll(struct input_polled_dev *dev)
int ret;
u8 buf[6];
- ret = mma8450_read(m, MMA8450_STATUS);
- if (ret < 0)
- return;
+ mutex_lock(&m->mma8450_lock);
- if (!(ret & MMA8450_STATUS_ZXYDR))
+ ret = mma8450_read(m, MMA8450_STATUS);
+ if (ret < 0 || !(ret & MMA8450_STATUS_ZXYDR)) {
+ mutex_unlock(&m->mma8450_lock);
return;
+ }
ret = mma8450_read_block(m, MMA8450_OUT_X_LSB, buf, sizeof(buf));
- if (ret < 0)
+ if (ret < 0) {
+ mutex_unlock(&m->mma8450_lock);
return;
+ }
x = ((int)(s8)buf[1] << 4) | (buf[0] & 0xf);
y = ((int)(s8)buf[3] << 4) | (buf[2] & 0xf);
@@ -131,10 +146,12 @@ static void mma8450_poll(struct input_polled_dev *dev)
input_report_abs(dev->input, ABS_Y, y);
input_report_abs(dev->input, ABS_Z, z);
input_sync(dev->input);
+
+ mutex_unlock(&m->mma8450_lock);
}
/* Initialize the MMA8450 chip */
-static void mma8450_open(struct input_polled_dev *dev)
+static s32 mma8450_open(struct input_polled_dev *dev)
{
struct mma8450 *m = dev->private;
int err;
@@ -142,18 +159,20 @@ static void mma8450_open(struct input_polled_dev *dev)
/* enable all events from X/Y/Z, no FIFO */
err = mma8450_write(m, MMA8450_XYZ_DATA_CFG, 0x07);
if (err)
- return;
+ return err;
/*
* Sleep mode poll rate - 50Hz
* System output data rate - 400Hz
- * Full scale selection - Active, +/- 2G
+ * Standby mode
*/
- err = mma8450_write(m, MMA8450_CTRL_REG1, 0x01);
- if (err < 0)
- return;
-
+ err = mma8450_write(m, MMA8450_CTRL_REG1, MODE_STANDBY);
+ if (err)
+ return err;
+ m->mode = MODE_STANDBY;
msleep(MODE_CHANGE_DELAY_MS);
+
+ return 0;
}
static void mma8450_close(struct input_polled_dev *dev)
@@ -164,6 +183,76 @@ static void mma8450_close(struct input_polled_dev *dev)
mma8450_write(m, MMA8450_CTRL_REG2, 0x01);
}
+static ssize_t mma8450_scalemode_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ int mode = 0;
+ struct mma8450 *m;
+ struct i2c_client *client = to_i2c_client(dev);
+
+ m = i2c_get_clientdata(client);
+
+ mutex_lock(&m->mma8450_lock);
+ mode = (int)m->mode;
+ mutex_unlock(&m->mma8450_lock);
+
+ return sprintf(buf, "%d\n", mode);
+}
+
+static ssize_t mma8450_scalemode_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned long mode;
+ int ret;
+ struct mma8450 *m = NULL;
+ struct i2c_client *client = to_i2c_client(dev);
+
+ ret = kstrtoul(buf, 10, &mode);
+ if (ret) {
+ dev_err(dev, "string transform error\n");
+ return ret;
+ }
+
+ if (mode > MODE_8G) {
+ dev_warn(dev, "not supported mode %d\n", (int)mode);
+ return count;
+ }
+
+ m = i2c_get_clientdata(client);
+
+ mutex_lock(&m->mma8450_lock);
+ if (mode == m->mode) {
+ mutex_unlock(&m->mma8450_lock);
+ return count;
+ }
+
+ ret = mma8450_write(m, MMA8450_CTRL_REG1, mode);
+ if (ret < 0) {
+ mutex_unlock(&m->mma8450_lock);
+ return ret;
+ }
+
+ msleep(MODE_CHANGE_DELAY_MS);
+ m->mode = (u8)mode;
+ mutex_unlock(&m->mma8450_lock);
+
+ return count;
+}
+
+static DEVICE_ATTR(scalemode, S_IWUSR | S_IRUGO,
+ mma8450_scalemode_show, mma8450_scalemode_store);
+
+static struct attribute *mma8450_attributes[] = {
+ &dev_attr_scalemode.attr,
+ NULL
+};
+
+static const struct attribute_group mma8450_attr_group = {
+ .attrs = mma8450_attributes,
+};
+
/*
* I2C init/probing/exit functions
*/
@@ -172,7 +261,24 @@ static int mma8450_probe(struct i2c_client *c,
{
struct input_polled_dev *idev;
struct mma8450 *m;
- int err;
+ int err, client_id;
+ struct i2c_adapter *adapter = NULL;
+
+ adapter = to_i2c_adapter(c->dev.parent);
+ err = i2c_check_functionality(adapter,
+ I2C_FUNC_SMBUS_BYTE |
+ I2C_FUNC_SMBUS_BYTE_DATA);
+ if (!err)
+ return err;
+
+ client_id = i2c_smbus_read_byte_data(c, MMA8450_WHO_AM_I);
+
+ if (MMA8450_ID != client_id) {
+ dev_err(&c->dev,
+ "read chip ID 0x%x is not equal to 0x%x!\n", client_id,
+ MMA8450_ID);
+ return -EINVAL;
+ }
m = devm_kzalloc(&c->dev, sizeof(*m), GFP_KERNEL);
if (!m)
@@ -184,6 +290,7 @@ static int mma8450_probe(struct i2c_client *c,
m->client = c;
m->idev = idev;
+ i2c_set_clientdata(c, m);
idev->private = m;
idev->input->name = MMA8450_DRV_NAME;
@@ -191,8 +298,6 @@ static int mma8450_probe(struct i2c_client *c,
idev->poll = mma8450_poll;
idev->poll_interval = POLL_INTERVAL;
idev->poll_interval_max = POLL_INTERVAL_MAX;
- idev->open = mma8450_open;
- idev->close = mma8450_close;
__set_bit(EV_ABS, idev->input->evbit);
input_set_abs_params(idev->input, ABS_X, -2048, 2047, 32, 32);
@@ -205,6 +310,41 @@ static int mma8450_probe(struct i2c_client *c,
return err;
}
+ mutex_init(&m->mma8450_lock);
+
+ err = mma8450_open(idev);
+ if (err) {
+ dev_err(&c->dev, "failed to initialize mma8450\n");
+ goto err_unreg_dev;
+ }
+
+ err = sysfs_create_group(&c->dev.kobj, &mma8450_attr_group);
+ if (err) {
+ dev_err(&c->dev, "create device file failed!\n");
+ err = -EINVAL;
+ goto err_close;
+ }
+
+ return 0;
+
+err_close:
+ mma8450_close(idev);
+err_unreg_dev:
+ mutex_destroy(&m->mma8450_lock);
+ input_unregister_polled_device(idev);
+ return err;
+}
+
+static int mma8450_remove(struct i2c_client *c)
+{
+ struct mma8450 *m = i2c_get_clientdata(c);
+ struct input_polled_dev *idev = m->idev;
+
+ sysfs_remove_group(&c->dev.kobj, &mma8450_attr_group);
+ mma8450_close(idev);
+ mutex_destroy(&m->mma8450_lock);
+ input_unregister_polled_device(idev);
+
return 0;
}
@@ -226,6 +366,7 @@ static struct i2c_driver mma8450_driver = {
.of_match_table = mma8450_dt_ids,
},
.probe = mma8450_probe,
+ .remove = mma8450_remove,
.id_table = mma8450_id,
};
diff --git a/drivers/input/misc/mpl3115.c b/drivers/input/misc/mpl3115.c
new file mode 100644
index 000000000000..4bd5420e4e93
--- /dev/null
+++ b/drivers/input/misc/mpl3115.c
@@ -0,0 +1,356 @@
+/*
+ * Copyright (C) 2010-2015 Freescale , Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/pm.h>
+#include <linux/mutex.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/hwmon-sysfs.h>
+#include <linux/err.h>
+#include <linux/hwmon.h>
+#include <linux/input-polldev.h>
+
+#define MPL3115_DRV_NAME "mpl3115"
+#define ABS_TEMPTERAURE ABS_MISC
+
+#define INPUT_FUZZ 32
+#define INPUT_FLAT 32
+#define MPL_ACTIVED 1
+#define MPL_STANDBY 0
+#define POLL_INTERVAL_MAX 500
+#define POLL_INTERVAL 100
+#define POLL_INTERVAL_MIN 1
+#define MPL3115_ID 0xc4
+#define MPLL_ACTIVE_MASK 0x01
+#define MPL3115_STATUS_DR 0x08
+
+/* MPL3115A register address */
+#define MPL3115_STATUS 0x00
+#define MPL3115_PRESSURE_DATA 0x01
+#define MPL3115_DR_STATUS 0x06
+#define MPL3115_DELTA_DATA 0x07
+#define MPL3115_WHO_AM_I 0x0c
+#define MPL3115_FIFO_STATUS 0x0d
+#define MPL3115_FIFO_DATA 0x0e
+#define MPL3115_FIFO_SETUP 0x0e
+#define MPL3115_TIME_DELAY 0x10
+#define MPL3115_SYS_MODE 0x11
+#define MPL3115_INT_SORCE 0x12
+#define MPL3115_PT_DATA_CFG 0x13
+#define MPL3115_BAR_IN_MSB 0x14
+#define MPL3115_P_ARLARM_MSB 0x16
+#define MPL3115_T_ARLARM 0x18
+#define MPL3115_P_ARLARM_WND_MSB 0x19
+#define MPL3115_T_ARLARM_WND 0x1b
+#define MPL3115_P_MIN_DATA 0x1c
+#define MPL3115_T_MIN_DATA 0x1f
+#define MPL3115_P_MAX_DATA 0x21
+#define MPL3115_T_MAX_DATA 0x24
+#define MPL3115_CTRL_REG1 0x26
+#define MPL3115_CTRL_REG2 0x27
+#define MPL3115_CTRL_REG3 0x28
+#define MPL3115_CTRL_REG4 0x29
+#define MPL3115_CTRL_REG5 0x2a
+#define MPL3115_OFFSET_P 0x2b
+#define MPL3115_OFFSET_T 0x2c
+#define MPL3115_OFFSET_H 0x2d
+
+#define DATA_SHIFT_BIT(data, bit) ((data << bit) & (0xff << bit))
+
+struct mpl3115_data {
+ struct i2c_client *client;
+ struct input_polled_dev *poll_dev;
+ struct mutex data_lock;
+ int active;
+};
+
+static int mpl3115_i2c_read(struct i2c_client *client, u8 reg, u8 *values, u8 length)
+{
+ return i2c_smbus_read_i2c_block_data(client, reg, length, values);
+}
+
+static int mpl3115_i2c_write(struct i2c_client *client, u8 reg, const u8 *values, u8 length)
+{
+ return i2c_smbus_write_i2c_block_data(client, reg, length, values);
+}
+
+static ssize_t mpl3115_enable_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int val;
+ u8 sysmode;
+
+ struct input_polled_dev *poll_dev = dev_get_drvdata(dev);
+ struct mpl3115_data *pdata = (struct mpl3115_data *)(poll_dev->private);
+ struct i2c_client *client = pdata->client;
+ mutex_lock(&pdata->data_lock);
+ mpl3115_i2c_read(client, MPL3115_CTRL_REG1, &sysmode, 1);
+ sysmode &= MPLL_ACTIVE_MASK;
+ val = (sysmode ? 1 : 0);
+ mutex_unlock(&pdata->data_lock);
+
+ return sprintf(buf, "%d\n", val);
+}
+
+static ssize_t mpl3115_enable_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int ret, enable;
+ u8 val;
+ struct input_polled_dev *poll_dev = dev_get_drvdata(dev);
+ struct mpl3115_data *pdata = (struct mpl3115_data *)(poll_dev->private);
+ struct i2c_client *client = pdata->client;
+
+ enable = simple_strtoul(buf, NULL, 10);
+ mutex_lock(&pdata->data_lock);
+ mpl3115_i2c_read(client, MPL3115_CTRL_REG1, &val, 1);
+ if (enable && pdata->active == MPL_STANDBY) {
+ val |= MPLL_ACTIVE_MASK;
+ ret = mpl3115_i2c_write(client, MPL3115_CTRL_REG1, &val, 1);
+ if (!ret)
+ pdata->active = MPL_ACTIVED;
+ printk("mpl3115 set active\n");
+ } else if (!enable && pdata->active == MPL_ACTIVED) {
+ val &= ~MPLL_ACTIVE_MASK;
+ ret = mpl3115_i2c_write(client, MPL3115_CTRL_REG1, &val, 1);
+ if (!ret)
+ pdata->active = MPL_STANDBY;
+ printk("mpl3115 set inactive\n");
+ }
+ mutex_unlock(&pdata->data_lock);
+
+ return count;
+}
+
+static DEVICE_ATTR(enable, S_IWUSR | S_IRUGO, mpl3115_enable_show, mpl3115_enable_store);
+
+static struct attribute *mpl3115_attributes[] = {
+ &dev_attr_enable.attr,
+ NULL
+};
+
+static const struct attribute_group mpl3115_attr_group = {
+ .attrs = mpl3115_attributes,
+};
+
+static void mpl3115_device_init(struct i2c_client *client)
+{
+ u8 val[8];
+ struct device_node *np = client->dev.of_node;
+
+ /* set interrupt pin as open-drain */
+ if (of_get_property(np, "interrupt-open-drain", NULL)) {
+ val[0] = 0x11;
+ mpl3115_i2c_write(client, MPL3115_CTRL_REG3, val, 1);
+ }
+
+ val[0] = 0x28;
+ mpl3115_i2c_write(client, MPL3115_CTRL_REG1, val, 1);
+}
+
+static int mpl3115_read_data(struct i2c_client *client, int *pres, short *temp)
+{
+ u8 tmp[5];
+
+ mpl3115_i2c_read(client, MPL3115_PRESSURE_DATA, tmp, 5);
+ *pres = (DATA_SHIFT_BIT(tmp[0], 24) | DATA_SHIFT_BIT(tmp[1], 16) | DATA_SHIFT_BIT(tmp[2], 8)) >> 12;
+ *temp = (DATA_SHIFT_BIT(tmp[3], 8) | DATA_SHIFT_BIT(tmp[4], 0)) >> 4;
+ return 0;
+}
+
+static void report_abs(struct mpl3115_data *pdata)
+{
+ struct input_dev *idev;
+ int pressure = 0;
+ short temperature = 0;
+
+ mutex_lock(&pdata->data_lock);
+ if (pdata->active == MPL_STANDBY)
+ goto out;
+ idev = pdata->poll_dev->input;
+ mpl3115_read_data(pdata->client, &pressure, &temperature);
+ input_report_abs(idev, ABS_PRESSURE, pressure);
+ input_report_abs(idev, ABS_TEMPTERAURE, temperature);
+ input_sync(idev);
+out:
+ mutex_unlock(&pdata->data_lock);
+}
+
+static void mpl3115_dev_poll(struct input_polled_dev *dev)
+{
+ struct mpl3115_data *pdata = (struct mpl3115_data *)dev->private;
+
+ report_abs(pdata);
+}
+
+static int mpl3115_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ int result, client_id;
+ struct input_dev *idev;
+ struct i2c_adapter *adapter;
+ struct mpl3115_data *pdata;
+
+ adapter = to_i2c_adapter(client->dev.parent);
+ result = i2c_check_functionality(adapter,
+ I2C_FUNC_SMBUS_BYTE |
+ I2C_FUNC_SMBUS_BYTE_DATA);
+ if (!result)
+ goto err_out;
+
+ client_id = i2c_smbus_read_byte_data(client, MPL3115_WHO_AM_I);
+ printk("read mpl3115 chip id 0x%x\n", client_id);
+ if (client_id != MPL3115_ID) {
+ dev_err(&client->dev,
+ "read chip ID 0x%x is not equal to 0x%x!\n",
+ result, MPL3115_ID);
+ result = -EINVAL;
+ goto err_out;
+ }
+ pdata = kzalloc(sizeof(struct mpl3115_data), GFP_KERNEL);
+ if (!pdata)
+ goto err_out;
+ pdata->client = client;
+ i2c_set_clientdata(client, pdata);
+ mutex_init(&pdata->data_lock);
+ pdata->poll_dev = input_allocate_polled_device();
+ if (!pdata->poll_dev) {
+ result = -ENOMEM;
+ dev_err(&client->dev, "alloc poll device failed!\n");
+ goto err_alloc_data;
+ }
+ pdata->poll_dev->poll = mpl3115_dev_poll;
+ pdata->poll_dev->private = pdata;
+ pdata->poll_dev->poll_interval = POLL_INTERVAL;
+ pdata->poll_dev->poll_interval_min = POLL_INTERVAL_MIN;
+ pdata->poll_dev->poll_interval_max = POLL_INTERVAL_MAX;
+ idev = pdata->poll_dev->input;
+ idev->name = MPL3115_DRV_NAME;
+ idev->id.bustype = BUS_I2C;
+ idev->evbit[0] = BIT_MASK(EV_ABS);
+
+ input_set_abs_params(idev, ABS_PRESSURE, -0x7FFFFFFF, 0x7FFFFFFF, 0, 0);
+ input_set_abs_params(idev, ABS_TEMPTERAURE, -0x7FFFFFFF, 0x7FFFFFFF, 0, 0);
+ result = input_register_polled_device(pdata->poll_dev);
+ if (result) {
+ dev_err(&client->dev, "register poll device failed!\n");
+ goto error_free_poll_dev;
+ }
+ result = sysfs_create_group(&idev->dev.kobj, &mpl3115_attr_group);
+ if (result) {
+ dev_err(&client->dev, "create device file failed!\n");
+ result = -EINVAL;
+ goto error_register_polled_device;
+ }
+ mpl3115_device_init(client);
+ printk("mpl3115 device driver probe successfully");
+ return 0;
+error_register_polled_device:
+ input_unregister_polled_device(pdata->poll_dev);
+error_free_poll_dev:
+ input_free_polled_device(pdata->poll_dev);
+err_alloc_data:
+ kfree(pdata);
+err_out:
+ return result;
+}
+
+static int mpl3115_stop_chip(struct i2c_client *client)
+{
+ u8 val;
+ int ret;
+
+ mpl3115_i2c_read(client, MPL3115_CTRL_REG1, &val, 1);
+ val &= ~MPLL_ACTIVE_MASK;
+ ret = mpl3115_i2c_write(client, MPL3115_CTRL_REG1, &val, 1);
+
+ return 0;
+}
+static int mpl3115_start_chip(struct i2c_client *client)
+{
+ u8 val;
+ int ret;
+
+ mpl3115_i2c_read(client, MPL3115_CTRL_REG1, &val, 1);
+ val |= MPLL_ACTIVE_MASK;
+ ret = mpl3115_i2c_write(client, MPL3115_CTRL_REG1, &val, 1);
+
+ return 0;
+}
+static int mpl3115_remove(struct i2c_client *client)
+{
+ struct mpl3115_data *pdata = i2c_get_clientdata(client);
+ struct input_dev *idev = pdata->poll_dev->input;
+
+ mpl3115_stop_chip(client);
+ sysfs_remove_group(&idev->dev.kobj, &mpl3115_attr_group);
+ input_unregister_polled_device(pdata->poll_dev);
+ kfree(pdata);
+
+ return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int mpl3115_suspend(struct device *dev)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct mpl3115_data *pdata = i2c_get_clientdata(client);
+ if (pdata->active == MPL_ACTIVED)
+ mpl3115_stop_chip(client);
+ return 0;
+}
+
+static int mpl3115_resume(struct device *dev)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct mpl3115_data *pdata = i2c_get_clientdata(client);
+ if (pdata->active == MPL_ACTIVED)
+ mpl3115_start_chip(client);
+ return 0;
+}
+#endif
+
+static const struct i2c_device_id mpl3115_id[] = {
+ {MPL3115_DRV_NAME, 0},
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(i2c, mpl3115_id);
+
+static SIMPLE_DEV_PM_OPS(mpl3115_pm_ops, mpl3115_suspend, mpl3115_resume);
+static struct i2c_driver mpl3115_driver = {
+ .driver = {
+ .name = MPL3115_DRV_NAME,
+ .owner = THIS_MODULE,
+ .pm = &mpl3115_pm_ops,
+ },
+ .probe = mpl3115_probe,
+ .remove = mpl3115_remove,
+ .id_table = mpl3115_id,
+};
+
+module_i2c_driver(mpl3115_driver);
+
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("MPL3115 Smart Pressure Sensor driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/input/misc/rpmsg_input.c b/drivers/input/misc/rpmsg_input.c
new file mode 100644
index 000000000000..8f3d07b59ef0
--- /dev/null
+++ b/drivers/input/misc/rpmsg_input.c
@@ -0,0 +1,528 @@
+/*
+ * Copyright 2018 NXP
+ *
+ * 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/err.h>
+#include <linux/slab.h>
+#include <linux/imx_rpmsg.h>
+#include <linux/input.h>
+#include <linux/interrupt.h>
+#include <linux/hwmon-sysfs.h>
+#include <linux/miscdevice.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/pm_qos.h>
+#include <linux/rpmsg.h>
+#include <linux/uaccess.h>
+#include <linux/virtio.h>
+
+#define RPMSG_INPUT_DEV_STANDBY 0x00
+#define RPMSG_INPUT_DEV_ACTIVED 0x01
+#define DETECTOR_DEVICE "step_detector"
+#define COUNTER_DEVICE "step_counter"
+
+#define PEDOMETER_TYPE 0x0
+#define PEDOMETER_IDX 0x0
+
+#define RPMSG_TIMEOUT 1000
+
+enum rpmsg_input_header_type {
+ RPMSG_INPUT_SETUP,
+ RPMSG_INPUT_REPLY,
+ RPMSG_INPUT_NOTIFY,
+};
+
+enum rpmsg_input_header_cmd {
+ RPMSG_INPUT_DETECTOR_CMD,
+ RPMSG_INPUT_COUNTER_CMD,
+ RPMSG_INPUT_POLL_DELAY_CMD,
+};
+
+struct rpmsg_input_msg {
+ struct imx_rpmsg_head header;
+ u8 sensor_type;
+ u8 sensor_index;
+ union {
+ union {
+ u8 enable;
+ u8 retcode;
+ } inout;
+
+ u32 val;
+ } instruct;
+} __packed __aligned(8);
+
+struct rpmsg_input_data {
+ struct device *dev;
+ struct miscdevice *detector_miscdev;
+ struct miscdevice *counter_miscdev;
+ struct input_dev *detector_input;
+ struct input_dev *counter_input;
+ atomic_t detector_active;
+ atomic_t counter_active;
+ atomic_t counter_delay;
+
+ struct rpmsg_device *rpdev;
+ struct rpmsg_input_msg *reply_msg;
+ struct rpmsg_input_msg *notify_msg;
+ struct pm_qos_request pm_qos_req;
+ struct completion cmd_complete;
+ struct mutex lock;
+};
+
+static struct rpmsg_input_data *input_rpmsg;
+
+static int input_send_message(struct rpmsg_input_msg *msg,
+ struct rpmsg_input_data *info)
+{
+ int err;
+
+ if (!info->rpdev) {
+ dev_dbg(info->dev,
+ "rpmsg channel not ready, m4 image ready?\n");
+ return -EINVAL;
+ }
+
+ mutex_lock(&info->lock);
+ pm_qos_add_request(&info->pm_qos_req,
+ PM_QOS_CPU_DMA_LATENCY, 0);
+
+ reinit_completion(&info->cmd_complete);
+
+ err = rpmsg_send(info->rpdev->ept, (void *)msg,
+ sizeof(struct rpmsg_input_msg));
+ if (err) {
+ dev_err(&info->rpdev->dev, "rpmsg_send failed: %d\n", err);
+ goto err_out;
+ }
+
+ err = wait_for_completion_timeout(&info->cmd_complete,
+ msecs_to_jiffies(RPMSG_TIMEOUT));
+ if (!err) {
+ dev_err(&info->rpdev->dev, "rpmsg_send timeout!\n");
+ err = -ETIMEDOUT;
+ goto err_out;
+ }
+
+ err = info->reply_msg->instruct.inout.retcode;
+ if (err != 0) {
+ dev_err(&info->rpdev->dev, "rpmsg not ack %d!\n", err);
+ err = -EINVAL;
+ goto err_out;
+ }
+
+ err = 0;
+
+err_out:
+ pm_qos_remove_request(&info->pm_qos_req);
+ mutex_unlock(&info->lock);
+
+ return err;
+}
+
+static inline void rpmsg_input_evt_report(struct rpmsg_input_msg *msg)
+{
+ int val = 0x1;
+
+ if (msg->header.cmd == RPMSG_INPUT_DETECTOR_CMD) {
+ input_report_rel(input_rpmsg->detector_input, REL_MISC, val);
+ input_sync(input_rpmsg->detector_input);
+ } else if (msg->header.cmd == RPMSG_INPUT_COUNTER_CMD) {
+ val = msg->instruct.val;
+ input_report_abs(input_rpmsg->counter_input, ABS_MISC, val);
+ input_sync(input_rpmsg->counter_input);
+ }
+}
+
+static int rpmsg_input_cb(struct rpmsg_device *rpdev,
+ void *data, int len, void *priv, u32 src)
+{
+ struct rpmsg_input_msg *msg = (struct rpmsg_input_msg *)data;
+
+ if (msg->header.type == RPMSG_INPUT_REPLY) {
+ input_rpmsg->reply_msg = msg;
+ complete(&input_rpmsg->cmd_complete);
+ return 0;
+ } else if (msg->header.type == RPMSG_INPUT_NOTIFY) {
+ input_rpmsg->notify_msg = msg;
+ rpmsg_input_evt_report(msg);
+ } else
+ dev_err(&input_rpmsg->rpdev->dev, "wrong command type!\n");
+
+ return 0;
+}
+
+static int rpmsg_input_probe(struct rpmsg_device *rpdev)
+{
+ input_rpmsg->rpdev = rpdev;
+
+ dev_info(&rpdev->dev, "new channel: 0x%x -> 0x%x!\n",
+ rpdev->src, rpdev->dst);
+
+ init_completion(&input_rpmsg->cmd_complete);
+ mutex_init(&input_rpmsg->lock);
+
+ return 0;
+}
+
+static struct rpmsg_device_id rpmsg_input_id_table[] = {
+ { .name = "rpmsg-sensor-channel" },
+ { },
+};
+
+static struct rpmsg_driver rpmsg_input_driver = {
+ .drv.name = "input_rpmsg",
+ .drv.owner = THIS_MODULE,
+ .id_table = rpmsg_input_id_table,
+ .probe = rpmsg_input_probe,
+ .callback = rpmsg_input_cb,
+};
+
+static int rpmsg_input_open(struct inode *inode, struct file *file)
+{
+ file->private_data = input_rpmsg;
+ return nonseekable_open(inode, file);
+}
+
+static int rpmsg_input_release(struct inode *inode, struct file *file)
+{
+ return 0;
+}
+
+static long
+rpmsg_input_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+ /* TBD: for future sensor interfaces support */
+ return 0;
+}
+
+static const struct file_operations rpmsg_input_fops = {
+ .owner = THIS_MODULE,
+ .open = rpmsg_input_open,
+ .release = rpmsg_input_release,
+ .unlocked_ioctl = rpmsg_input_ioctl,
+};
+
+static struct miscdevice step_detector_device = {
+ .minor = MISC_DYNAMIC_MINOR,
+ .name = "step_detector",
+ .fops = &rpmsg_input_fops,
+};
+
+static struct miscdevice step_counter_device = {
+ .minor = MISC_DYNAMIC_MINOR,
+ .name = "step_counter",
+ .fops = &rpmsg_input_fops,
+};
+
+static int rpmsg_input_change_mode(int cmd, int enable)
+{
+
+ struct rpmsg_input_msg msg;
+
+ memset(&msg, 0, sizeof(struct rpmsg_input_msg));
+ msg.header.cate = IMX_RPMSG_SENSOR;
+ msg.header.major = IMX_RMPSG_MAJOR;
+ msg.header.minor = IMX_RMPSG_MINOR;
+ msg.header.type = RPMSG_INPUT_SETUP;
+ msg.header.cmd = cmd;
+ msg.sensor_type = PEDOMETER_TYPE;
+ msg.sensor_index = PEDOMETER_IDX;
+ msg.instruct.inout.enable = enable;
+
+ return input_send_message(&msg, input_rpmsg);
+}
+
+static int rpmsg_input_set_poll_delay(int cmd, int delay)
+{
+ struct rpmsg_input_msg msg;
+
+ memset(&msg, 0, sizeof(struct rpmsg_input_msg));
+ msg.header.cate = IMX_RPMSG_SENSOR;
+ msg.header.major = IMX_RMPSG_MAJOR;
+ msg.header.minor = IMX_RMPSG_MINOR;
+ msg.header.type = RPMSG_INPUT_SETUP;
+ msg.header.cmd = cmd;
+ msg.sensor_type = PEDOMETER_TYPE;
+ msg.sensor_index = PEDOMETER_IDX;
+ msg.instruct.val = delay;
+
+ return input_send_message(&msg, input_rpmsg);
+}
+
+static ssize_t rpmsg_input_enable_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct miscdevice *misc_dev = dev_get_drvdata(dev);
+ struct rpmsg_input_data *pdata = input_rpmsg;
+ int enable = 0;
+
+ if (pdata->detector_miscdev == misc_dev)
+ enable = atomic_read(&pdata->detector_active);
+ if (pdata->counter_miscdev == misc_dev)
+ enable = atomic_read(&pdata->counter_active);
+
+ return sprintf(buf, "%d\n", enable);
+}
+
+static ssize_t rpmsg_input_enable_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct miscdevice *misc_dev = dev_get_drvdata(dev);
+ struct rpmsg_input_data *pdata = input_rpmsg;
+ unsigned long enable;
+ int cmd;
+ int ret;
+
+ if (kstrtoul(buf, 10, &enable) < 0)
+ return -EINVAL;
+
+ if (misc_dev == pdata->detector_miscdev)
+ cmd = RPMSG_INPUT_DETECTOR_CMD;
+ if (misc_dev == pdata->counter_miscdev)
+ cmd = RPMSG_INPUT_COUNTER_CMD;
+
+ enable = enable > 0 ? RPMSG_INPUT_DEV_ACTIVED :
+ RPMSG_INPUT_DEV_STANDBY;
+ ret = rpmsg_input_change_mode(cmd, enable);
+ if (!ret) {
+ if (cmd == RPMSG_INPUT_DETECTOR_CMD)
+ atomic_set(&pdata->detector_active, enable);
+ else if (cmd == RPMSG_INPUT_COUNTER_CMD)
+ atomic_set(&pdata->counter_active, enable);
+ }
+
+ return count;
+}
+
+static ssize_t rpmsg_input_poll_delay_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct miscdevice *misc_dev = dev_get_drvdata(dev);
+ struct rpmsg_input_data *pdata = input_rpmsg;
+ int poll_delay = 0;
+
+ if (pdata->detector_miscdev == misc_dev)
+ return -ENOTSUPP;
+
+ if (pdata->counter_miscdev == misc_dev)
+ poll_delay = atomic_read(&pdata->counter_delay);
+
+ return sprintf(buf, "%d\n", poll_delay);
+}
+
+
+static ssize_t rpmsg_input_poll_delay_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct miscdevice *misc_dev = dev_get_drvdata(dev);
+ struct rpmsg_input_data *pdata = input_rpmsg;
+ unsigned long delay;
+ int cmd;
+ int ret;
+
+ if (kstrtoul(buf, 10, &delay) < 0)
+ return -EINVAL;
+
+ if (pdata->detector_miscdev == misc_dev)
+ return -ENOTSUPP;
+
+ if (pdata->counter_miscdev == misc_dev)
+ cmd = RPMSG_INPUT_POLL_DELAY_CMD;
+
+ ret = rpmsg_input_set_poll_delay(cmd, delay);
+ if (!ret) {
+ if (cmd == RPMSG_INPUT_POLL_DELAY_CMD)
+ atomic_set(&pdata->counter_delay, delay);
+ }
+
+ return count;
+}
+
+static DEVICE_ATTR(enable, S_IWUSR | S_IRUGO,
+ rpmsg_input_enable_show,
+ rpmsg_input_enable_store);
+static DEVICE_ATTR(poll_delay, S_IWUSR | S_IRUGO,
+ rpmsg_input_poll_delay_show,
+ rpmsg_input_poll_delay_store);
+
+static struct attribute *rpmsg_input_attributes[] = {
+ &dev_attr_enable.attr,
+ &dev_attr_poll_delay.attr,
+ NULL
+};
+
+static const struct attribute_group rpmsg_input_attr_group = {
+ .attrs = rpmsg_input_attributes,
+};
+
+static int rpmsg_input_register_sysfs_device(struct rpmsg_input_data *pdata)
+{
+ struct miscdevice *misc_dev = NULL;
+ int err = 0;
+
+ /* register sysfs for detector */
+ misc_dev = pdata->detector_miscdev;
+ err = sysfs_create_group(&misc_dev->this_device->kobj,
+ &rpmsg_input_attr_group);
+ if (err)
+ goto out;
+
+ /* register sysfs for counter */
+ misc_dev = pdata->counter_miscdev;
+ err = sysfs_create_group(&misc_dev->this_device->kobj,
+ &rpmsg_input_attr_group);
+ if (err)
+ goto err_register_sysfs;
+
+ return 0;
+
+err_register_sysfs:
+ misc_dev = pdata->detector_miscdev;
+ sysfs_remove_group(&misc_dev->this_device->kobj, &rpmsg_input_attr_group);
+out:
+ return err;
+}
+
+static int rpmsg_input_device_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct rpmsg_input_data *pdata;
+ struct input_dev *detector_input;
+ struct input_dev *counter_input;
+ int ret = 0;
+
+ pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
+ if (!pdata)
+ return -ENOMEM;
+
+ detector_input = devm_input_allocate_device(dev);
+ if (!detector_input) {
+ dev_err(dev, "failed to allocate detector device\n");
+ return -ENOMEM;
+ }
+
+ counter_input = devm_input_allocate_device(dev);
+ if (!counter_input) {
+ dev_err(dev, "failed to allocate counter device\n");
+ return -ENOMEM;
+ }
+
+ detector_input->name = DETECTOR_DEVICE;
+ detector_input->phys = "rpmsg-input/input0";
+ detector_input->dev.parent = &pdev->dev;
+ detector_input->id.bustype = BUS_HOST;
+ detector_input->evbit[0] = BIT_MASK(EV_REL);
+ detector_input->relbit[0] = BIT_MASK(REL_MISC);
+ pdata->detector_input = detector_input;
+
+ counter_input->name = COUNTER_DEVICE;
+ counter_input->phys = "rpmsg-input/input1";
+ counter_input->dev.parent = &pdev->dev;
+ counter_input->id.bustype = BUS_HOST;
+ counter_input->evbit[0] = BIT_MASK(EV_ABS);
+ input_set_abs_params(counter_input, ABS_MISC, 0, 0xFFFFFFFF, 0, 0);
+ pdata->counter_input = counter_input;
+
+ input_rpmsg = pdata;
+ platform_set_drvdata(pdev, pdata);
+
+ ret = misc_register(&step_detector_device);
+ if (ret != 0) {
+ dev_err(dev, "register acc miscdevice error");
+ goto err_register_detector_misc;
+ }
+ pdata->detector_miscdev = &step_detector_device;
+
+ ret = misc_register(&step_counter_device);
+ if (ret != 0) {
+ dev_err(dev, "register acc miscdevice error");
+ goto err_register_counter_misc;
+ }
+ pdata->counter_miscdev = &step_counter_device;
+
+ ret = rpmsg_input_register_sysfs_device(pdata);
+ if (ret) {
+ dev_err(dev, "Unable to register input sysfs, error: %d\n",
+ ret);
+ goto err_register_sysfs;
+ }
+
+ ret = input_register_device(detector_input);
+ if (ret) {
+ dev_err(dev, "Unable to register detector device, error: %d\n",
+ ret);
+ goto err_register_detector_input;
+ }
+
+ ret = input_register_device(counter_input);
+ if (ret) {
+ dev_err(dev, "Unable to register counter device, error: %d\n",
+ ret);
+ goto err_register_counter_input;
+ }
+
+ ret = register_rpmsg_driver(&rpmsg_input_driver);
+ if (ret) {
+ dev_err(dev, "Unable to register rpmsg driver, error: %d\n",
+ ret);
+ goto err_register_rmpsg_driver;
+ }
+
+ return ret;
+
+err_register_rmpsg_driver:
+ input_unregister_device(counter_input);
+err_register_counter_input:
+ input_unregister_device(detector_input);
+err_register_detector_input:
+err_register_sysfs:
+ misc_deregister(&step_counter_device);
+ pdata->counter_miscdev = NULL;
+err_register_counter_misc:
+ misc_deregister(&step_detector_device);
+ pdata->detector_miscdev = NULL;
+err_register_detector_misc:
+ pdata->detector_input = NULL;
+ pdata->counter_input = NULL;
+ platform_set_drvdata(pdev, NULL);
+ return ret;
+}
+
+static const struct of_device_id rpmsg_input_of_match[] = {
+ { .compatible = "fsl,rpmsg-input", },
+ { },
+};
+
+MODULE_DEVICE_TABLE(of, rpmsg_input_of_match);
+
+static struct platform_driver rpmsg_input_device_driver = {
+ .probe = rpmsg_input_device_probe,
+ .driver = {
+ .name = "rpmsg-input",
+ .of_match_table = of_match_ptr(rpmsg_input_of_match)
+ }
+};
+
+module_platform_driver(rpmsg_input_device_driver);
+
+MODULE_AUTHOR("NXP Semiconductor");
+MODULE_DESCRIPTION("NXP i.MX7ULP rpmsg sensor input driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
index 64b30fe273fd..538a0fca990e 100644
--- a/drivers/input/touchscreen/Kconfig
+++ b/drivers/input/touchscreen/Kconfig
@@ -46,6 +46,19 @@ config TOUCHSCREEN_ADS7846
To compile this driver as a module, choose M here: the
module will be called ads7846.
+config TOUCHSCREEN_CT36X_WLD
+ default y
+ tristate "CT36X based touchscreens for WLD"
+ help
+ Say Y here if you have a touchscreen interface using the
+ CT36X controller, i2c touchscreen
+ controller.
+
+ If unsure, say N (but it's safe to say "Y").
+
+ To compile this driver as a module, choose M here: the
+ module will be called vtl_ts.
+
config TOUCHSCREEN_AD7877
tristate "AD7877 based touchscreens"
depends on SPI_MASTER
@@ -316,6 +329,18 @@ config TOUCHSCREEN_EGALAX_SERIAL
To compile this driver as a module, choose M here: the
module will be called egalax_ts_serial.
+config TOUCHSCREEN_ELAN_TS
+ tristate "ELAN touchscreen input driver"
+ depends on I2C
+ help
+ Say Y here if you have an I2C ELAN touchscreen
+ attached.
+
+ If unsure, say N.
+
+ To compile this driver as a module, choose M here: the
+ module will be called elan-touch.
+
config TOUCHSCREEN_FUJITSU
tristate "Fujitsu serial touchscreen"
select SERIO
@@ -1246,4 +1271,7 @@ config TOUCHSCREEN_ROHM_BU21023
To compile this driver as a module, choose M here: the
module will be called bu21023_ts.
+source "drivers/input/touchscreen/synaptics_dsx/Kconfig"
endif
+
+source "drivers/input/touchscreen/focaltech_touch/Kconfig"
diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile
index 850c1562555a..63a95ebb0afd 100644
--- a/drivers/input/touchscreen/Makefile
+++ b/drivers/input/touchscreen/Makefile
@@ -19,6 +19,7 @@ obj-$(CONFIG_TOUCHSCREEN_ATMEL_MXT) += atmel_mxt_ts.o
obj-$(CONFIG_TOUCHSCREEN_AUO_PIXCIR) += auo-pixcir-ts.o
obj-$(CONFIG_TOUCHSCREEN_BU21013) += bu21013_ts.o
obj-$(CONFIG_TOUCHSCREEN_CHIPONE_ICN8318) += chipone_icn8318.o
+obj-$(CONFIG_TOUCHSCREEN_CT36X_WLD) += vtl/
obj-$(CONFIG_TOUCHSCREEN_CY8CTMG110) += cy8ctmg110_ts.o
obj-$(CONFIG_TOUCHSCREEN_CYTTSP_CORE) += cyttsp_core.o
obj-$(CONFIG_TOUCHSCREEN_CYTTSP_I2C) += cyttsp_i2c.o cyttsp_i2c_common.o
@@ -36,8 +37,11 @@ obj-$(CONFIG_TOUCHSCREEN_EETI) += eeti_ts.o
obj-$(CONFIG_TOUCHSCREEN_EKTF2127) += ektf2127.o
obj-$(CONFIG_TOUCHSCREEN_ELAN) += elants_i2c.o
obj-$(CONFIG_TOUCHSCREEN_ELO) += elo.o
+obj-$(CONFIG_TOUCHSCREEN_ELAN_TS) += elan_ts.o
obj-$(CONFIG_TOUCHSCREEN_EGALAX) += egalax_ts.o
obj-$(CONFIG_TOUCHSCREEN_EGALAX_SERIAL) += egalax_ts_serial.o
+obj-$(CONFIG_TOUCHSCREEN_FTS) += focaltech_touch/
+obj-$(CONFIG_TOUCHSCREEN_SYNAPTICS_DSX) += synaptics_dsx/
obj-$(CONFIG_TOUCHSCREEN_FUJITSU) += fujitsu_ts.o
obj-$(CONFIG_TOUCHSCREEN_GOODIX) += goodix.o
obj-$(CONFIG_TOUCHSCREEN_ILI210X) += ili210x.o
diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c
index a2f45aefce08..ed0b48420beb 100644
--- a/drivers/input/touchscreen/ads7846.c
+++ b/drivers/input/touchscreen/ads7846.c
@@ -1188,6 +1188,7 @@ static const struct ads7846_platform_data *ads7846_probe_dt(struct device *dev)
struct ads7846_platform_data *pdata;
struct device_node *node = dev->of_node;
const struct of_device_id *match;
+ int ret;
if (!node) {
dev_err(dev, "Device does not have associated DT data\n");
@@ -1233,8 +1234,11 @@ static const struct ads7846_platform_data *ads7846_probe_dt(struct device *dev)
of_property_read_u16(node, "ti,debounce-tol", &pdata->debounce_tol);
of_property_read_u16(node, "ti,debounce-rep", &pdata->debounce_rep);
- of_property_read_u32(node, "ti,pendown-gpio-debounce",
+ ret = of_property_read_u32(node, "ti,pendown-gpio-debounce",
&pdata->gpio_pendown_debounce);
+ if (!ret)
+ dev_info(dev, "Set pendown gpio debounce time to %d microseconds\n",
+ pdata->gpio_pendown_debounce);
pdata->wakeup = of_property_read_bool(node, "wakeup-source") ||
of_property_read_bool(node, "linux,wakeup");
@@ -1365,7 +1369,7 @@ static int ads7846_probe(struct spi_device *spi)
pdata->y_max ? : MAX_12BIT,
0, 0);
input_set_abs_params(input_dev, ABS_PRESSURE,
- pdata->pressure_min, pdata->pressure_max, 0, 0);
+ pdata->pressure_min, ts->pressure_max, 0, 0);
ads7846_setup_spi_msg(ts, pdata);
diff --git a/drivers/input/touchscreen/egalax_ts.c b/drivers/input/touchscreen/egalax_ts.c
index 752ae9cf4514..94fbd158a997 100644
--- a/drivers/input/touchscreen/egalax_ts.c
+++ b/drivers/input/touchscreen/egalax_ts.c
@@ -119,6 +119,26 @@ static irqreturn_t egalax_ts_interrupt(int irq, void *dev_id)
return IRQ_HANDLED;
}
+static int egalax_irq_request(struct egalax_ts *ts)
+{
+ int ret;
+ struct i2c_client *client = ts->client;
+
+ ret = devm_request_threaded_irq(&client->dev, client->irq, NULL,
+ egalax_ts_interrupt,
+ IRQF_TRIGGER_LOW | IRQF_ONESHOT,
+ "egalax_ts", ts);
+ if (ret < 0)
+ dev_err(&client->dev, "Failed to register interrupt\n");
+
+ return ret;
+}
+
+static void egalax_free_irq(struct egalax_ts *ts)
+{
+ devm_free_irq(&ts->client->dev, ts->client->irq, ts);
+}
+
/* wake up controller by an falling edge of interrupt gpio. */
static int egalax_wake_up_device(struct i2c_client *client)
{
@@ -186,6 +206,20 @@ static int egalax_ts_probe(struct i2c_client *client,
ts->client = client;
ts->input_dev = input_dev;
+ /* HannStar (HSD100PXN1 Rev: 1-A00C11 F/W:0634) LVDS touch
+ * screen needs to trigger I2C event to device FW at booting
+ * first, and then the FW can switch to I2C interface.
+ * Otherwise, the FW can’t work with I2C interface. So here
+ * just use the exist function egalax_firmware_version() to
+ * send a I2C command to the device, make sure the device FW
+ * switch to I2C interface.
+ */
+ error = egalax_firmware_version(client);
+ if (error) {
+ dev_err(&client->dev, "Failed to switch to I2C interface\n");
+ return error;
+ }
+
/* controller may be in sleep, wake it up. */
error = egalax_wake_up_device(client);
if (error) {
@@ -214,19 +248,16 @@ static int egalax_ts_probe(struct i2c_client *client,
ABS_MT_POSITION_Y, 0, EGALAX_MAX_Y, 0, 0);
input_mt_init_slots(input_dev, MAX_SUPPORT_POINTS, 0);
- error = devm_request_threaded_irq(&client->dev, client->irq, NULL,
- egalax_ts_interrupt,
- IRQF_TRIGGER_LOW | IRQF_ONESHOT,
- "egalax_ts", ts);
- if (error < 0) {
- dev_err(&client->dev, "Failed to register interrupt\n");
+ error = egalax_irq_request(ts);
+ if (error)
return error;
- }
error = input_register_device(ts->input_dev);
if (error)
return error;
+ i2c_set_clientdata(client, ts);
+
return 0;
}
@@ -242,8 +273,10 @@ static int __maybe_unused egalax_ts_suspend(struct device *dev)
0x3, 0x6, 0xa, 0x3, 0x36, 0x3f, 0x2, 0, 0, 0
};
struct i2c_client *client = to_i2c_client(dev);
+ struct egalax_ts *ts = i2c_get_clientdata(client);
int ret;
+ egalax_free_irq(ts);
ret = i2c_master_send(client, suspend_cmd, MAX_I2C_DATA_LEN);
return ret > 0 ? 0 : ret;
}
@@ -251,8 +284,14 @@ static int __maybe_unused egalax_ts_suspend(struct device *dev)
static int __maybe_unused egalax_ts_resume(struct device *dev)
{
struct i2c_client *client = to_i2c_client(dev);
+ struct egalax_ts *ts = i2c_get_clientdata(client);
+ int ret;
+
+ ret = egalax_wake_up_device(client);
+ if (!ret)
+ ret = egalax_irq_request(ts);
- return egalax_wake_up_device(client);
+ return ret;
}
static SIMPLE_DEV_PM_OPS(egalax_ts_pm_ops, egalax_ts_suspend, egalax_ts_resume);
diff --git a/drivers/input/touchscreen/elan_ts.c b/drivers/input/touchscreen/elan_ts.c
new file mode 100644
index 000000000000..8590a947b624
--- /dev/null
+++ b/drivers/input/touchscreen/elan_ts.c
@@ -0,0 +1,472 @@
+/*
+ * Copyright (C) 2007-2008 HTC Corporation.
+ *
+ * Copyright (C) 2013-2015 Freescale Semiconductor, Inc.
+ *
+ * This driver is adapted from elan8232_i2c.c written by Shan-Fu Chiou
+ * <sfchiou@gmail.com> and Jay Tu <jay_tu@htc.com>.
+ * This driver is also adapted from the ELAN Touch Screen driver
+ * written by Stanley Zeng <stanley.zeng@emc.com.tw>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/input.h>
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/jiffies.h>
+#include <linux/interrupt.h>
+#include <linux/i2c.h>
+#include <linux/delay.h>
+#include <linux/hrtimer.h>
+#include <linux/of_gpio.h>
+#include <linux/regulator/consumer.h>
+#include <linux/gpio.h>
+
+static const char ELAN_TS_NAME[] = "elan-touch";
+
+#define ELAN_TS_X_MAX 1088
+#define ELAN_TS_Y_MAX 768
+#define ELAN_USER_X_MAX 800
+#define ELAN_USER_Y_MAX 600
+#define IDX_PACKET_SIZE 8
+
+enum {
+ hello_packet = 0x55,
+ idx_coordinate_packet = 0x5a,
+};
+
+enum {
+ idx_finger_state = 7,
+};
+
+static struct workqueue_struct *elan_wq;
+
+static struct elan_data {
+ int intr_gpio;
+ int use_irq;
+ struct hrtimer timer;
+ struct work_struct work;
+ struct i2c_client *client;
+ struct input_dev *input;
+ wait_queue_head_t wait;
+} elan_touch_data;
+
+/*--------------------------------------------------------------*/
+static int elan_touch_detect_int_level(void)
+{
+ int v;
+ v = gpio_get_value(elan_touch_data.intr_gpio);
+
+ return v;
+}
+
+static int __elan_touch_poll(struct i2c_client *client)
+{
+ int status = 0, retry = 20;
+
+ do {
+ status = elan_touch_detect_int_level();
+ retry--;
+ mdelay(20);
+ } while (status == 1 && retry > 0);
+
+ return status == 0 ? 0 : -ETIMEDOUT;
+}
+
+static int elan_touch_poll(struct i2c_client *client)
+{
+ return __elan_touch_poll(client);
+}
+
+static int __hello_packet_handler(struct i2c_client *client)
+{
+ int rc;
+ uint8_t buf_recv[4] = { 0 };
+
+ rc = elan_touch_poll(client);
+
+ if (rc < 0)
+ return -EINVAL;
+
+ rc = i2c_master_recv(client, buf_recv, 4);
+
+ if (rc != 4) {
+ return rc;
+ } else {
+ int i;
+ pr_info("hello packet: [0x%02x 0x%02x 0x%02x 0x%02x]\n",
+ buf_recv[0], buf_recv[1], buf_recv[2], buf_recv[3]);
+
+ for (i = 0; i < 4; i++)
+ if (buf_recv[i] != hello_packet)
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static inline int elan_touch_parse_xy(uint8_t *data, uint16_t *x,
+ uint16_t *y)
+{
+ *x = (data[0] & 0xf0);
+ *x <<= 4;
+ *x |= data[1];
+ if (*x >= ELAN_TS_X_MAX)
+ *x = ELAN_TS_X_MAX;
+ *x = ((((ELAN_TS_X_MAX -
+ *x) * 1000) / ELAN_TS_X_MAX) * ELAN_USER_X_MAX) / 1000;
+
+ *y = (data[0] & 0x0f);
+ *y <<= 8;
+ *y |= data[2];
+ if (*y >= ELAN_TS_Y_MAX)
+ *y = ELAN_TS_Y_MAX;
+ *y = ((((ELAN_TS_Y_MAX -
+ *y) * 1000) / ELAN_TS_Y_MAX) * ELAN_USER_Y_MAX) / 1000;
+
+ return 0;
+}
+
+/* __elan_touch_init -- hand shaking with touch panel
+ *
+ * 1.recv hello packet
+ */
+static int __elan_touch_init(struct i2c_client *client)
+{
+ int rc;
+ rc = __hello_packet_handler(client);
+ if (rc < 0)
+ goto hand_shake_failed;
+
+hand_shake_failed:
+ return rc;
+}
+
+static int elan_touch_recv_data(struct i2c_client *client, uint8_t *buf)
+{
+ int rc, bytes_to_recv = IDX_PACKET_SIZE;
+
+ if (buf == NULL)
+ return -EINVAL;
+
+ memset(buf, 0, bytes_to_recv);
+ rc = i2c_master_recv(client, buf, bytes_to_recv);
+ if (rc != bytes_to_recv)
+ return -EINVAL;
+
+ return rc;
+}
+
+static void elan_touch_report_data(struct i2c_client *client, uint8_t *buf)
+{
+ switch (buf[0]) {
+ case idx_coordinate_packet:
+ {
+ uint16_t x1, x2, y1, y2;
+ uint8_t finger_stat;
+
+ finger_stat = (buf[idx_finger_state] & 0x06) >> 1;
+
+ if (finger_stat == 0) {
+ input_report_key(elan_touch_data.input, BTN_TOUCH, 0);
+ input_report_key(elan_touch_data.input, BTN_2, 0);
+ } else if (finger_stat == 1) {
+ elan_touch_parse_xy(&buf[1], &x1, &y1);
+ input_report_abs(elan_touch_data.input, ABS_X, x1);
+ input_report_abs(elan_touch_data.input, ABS_Y, y1);
+ input_report_key(elan_touch_data.input, BTN_TOUCH, 1);
+ input_report_key(elan_touch_data.input, BTN_2, 0);
+ } else if (finger_stat == 2) {
+ elan_touch_parse_xy(&buf[1], &x1, &y1);
+ input_report_abs(elan_touch_data.input, ABS_X, x1);
+ input_report_abs(elan_touch_data.input, ABS_Y, y1);
+ input_report_key(elan_touch_data.input, BTN_TOUCH, 1);
+ elan_touch_parse_xy(&buf[4], &x2, &y2);
+ input_report_abs(elan_touch_data.input, ABS_HAT0X, x2);
+ input_report_abs(elan_touch_data.input, ABS_HAT0Y, y2);
+ input_report_key(elan_touch_data.input, BTN_2, 1);
+ }
+ input_sync(elan_touch_data.input);
+ break;
+ }
+
+ default:
+ break;
+ }
+}
+
+static void elan_touch_work_func(struct work_struct *work)
+{
+ int rc;
+ uint8_t buf[IDX_PACKET_SIZE] = { 0 };
+ struct i2c_client *client = elan_touch_data.client;
+
+ if (elan_touch_detect_int_level())
+ return;
+
+ rc = elan_touch_recv_data(client, buf);
+ if (rc < 0)
+ return;
+
+ elan_touch_report_data(client, buf);
+}
+
+static irqreturn_t elan_touch_ts_interrupt(int irq, void *dev_id)
+{
+ queue_work(elan_wq, &elan_touch_data.work);
+
+ return IRQ_HANDLED;
+}
+
+static enum hrtimer_restart elan_touch_timer_func(struct hrtimer *timer)
+{
+ queue_work(elan_wq, &elan_touch_data.work);
+ hrtimer_start(&elan_touch_data.timer, ktime_set(0, 12500000),
+ HRTIMER_MODE_REL);
+
+ return HRTIMER_NORESTART;
+}
+
+static int elan_touch_register_interrupt(struct i2c_client *client)
+{
+ int err = 0;
+
+ if (client->irq) {
+ elan_touch_data.use_irq = 1;
+ err =
+ request_irq(client->irq, elan_touch_ts_interrupt,
+ IRQF_TRIGGER_FALLING, ELAN_TS_NAME,
+ &elan_touch_data);
+
+ if (err < 0) {
+ pr_info("%s(%s): Can't allocate irq %d\n", __FILE__,
+ __func__, client->irq);
+ elan_touch_data.use_irq = 0;
+ }
+ }
+
+ if (!elan_touch_data.use_irq) {
+ hrtimer_init(&elan_touch_data.timer, CLOCK_MONOTONIC,
+ HRTIMER_MODE_REL);
+ elan_touch_data.timer.function = elan_touch_timer_func;
+ hrtimer_start(&elan_touch_data.timer, ktime_set(1, 0),
+ HRTIMER_MODE_REL);
+ }
+
+ pr_info("elan ts starts in %s mode.\n",
+ elan_touch_data.use_irq == 1 ? "interrupt" : "polling");
+
+ return 0;
+}
+
+static int elan_touch_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct device_node *np = client->dev.of_node;
+ int gpio_elan_cs, gpio_elan_rst, err = 0;
+
+ if (!np)
+ return -ENODEV;
+
+ elan_touch_data.intr_gpio = of_get_named_gpio(np, "gpio_intr", 0);
+ if (!gpio_is_valid(elan_touch_data.intr_gpio))
+ return -ENODEV;
+
+ err = devm_gpio_request_one(&client->dev, elan_touch_data.intr_gpio,
+ GPIOF_IN, "gpio_elan_intr");
+ if (err < 0) {
+ dev_err(&client->dev,
+ "request gpio failed: %d\n", err);
+ return err;
+ }
+
+ /* elan touch init */
+ gpio_elan_cs = of_get_named_gpio(np, "gpio_elan_cs", 0);
+ if (!gpio_is_valid(gpio_elan_cs))
+ return -ENODEV;
+
+ err = devm_gpio_request_one(&client->dev, gpio_elan_cs,
+ GPIOF_OUT_INIT_HIGH, "gpio_elan_cs");
+ if (err < 0) {
+ dev_err(&client->dev,
+ "request gpio failed: %d\n", err);
+ return err;
+ }
+ gpio_set_value(gpio_elan_cs, 0);
+
+ gpio_elan_rst = of_get_named_gpio(np, "gpio_elan_rst", 0);
+ if (!gpio_is_valid(gpio_elan_rst))
+ return -ENODEV;
+
+ err = devm_gpio_request_one(&client->dev, gpio_elan_rst,
+ GPIOF_OUT_INIT_HIGH, "gpio_elan_rst");
+ if (err < 0) {
+ dev_err(&client->dev,
+ "request gpio failed: %d\n", err);
+ return err;
+ }
+ gpio_set_value(gpio_elan_rst, 0);
+ msleep(10);
+ gpio_set_value(gpio_elan_rst, 1);
+
+ gpio_set_value(gpio_elan_cs, 1);
+ msleep(100);
+
+ elan_wq = create_singlethread_workqueue("elan_wq");
+ if (!elan_wq) {
+ err = -ENOMEM;
+ goto fail;
+ }
+
+ elan_touch_data.client = client;
+ strlcpy(client->name, ELAN_TS_NAME, I2C_NAME_SIZE);
+
+ INIT_WORK(&elan_touch_data.work, elan_touch_work_func);
+
+ elan_touch_data.input = input_allocate_device();
+ if (elan_touch_data.input == NULL) {
+ err = -ENOMEM;
+ goto fail;
+ }
+
+ err = __elan_touch_init(client);
+ if (err < 0) {
+ dev_err(&client->dev, "elan - Read Hello Packet Failed\n");
+ goto fail;
+ }
+
+ elan_touch_data.input->name = ELAN_TS_NAME;
+ elan_touch_data.input->id.bustype = BUS_I2C;
+
+ set_bit(EV_SYN, elan_touch_data.input->evbit);
+
+ set_bit(EV_KEY, elan_touch_data.input->evbit);
+ set_bit(BTN_TOUCH, elan_touch_data.input->keybit);
+ set_bit(BTN_2, elan_touch_data.input->keybit);
+
+ set_bit(EV_ABS, elan_touch_data.input->evbit);
+ set_bit(ABS_X, elan_touch_data.input->absbit);
+ set_bit(ABS_Y, elan_touch_data.input->absbit);
+ set_bit(ABS_HAT0X, elan_touch_data.input->absbit);
+ set_bit(ABS_HAT0Y, elan_touch_data.input->absbit);
+
+ input_set_abs_params(elan_touch_data.input, ABS_X, 0, ELAN_USER_X_MAX,
+ 0, 0);
+ input_set_abs_params(elan_touch_data.input, ABS_Y, 0, ELAN_USER_Y_MAX,
+ 0, 0);
+ input_set_abs_params(elan_touch_data.input, ABS_HAT0X, 0,
+ ELAN_USER_X_MAX, 0, 0);
+ input_set_abs_params(elan_touch_data.input, ABS_HAT0Y, 0,
+ ELAN_USER_Y_MAX, 0, 0);
+
+ err = input_register_device(elan_touch_data.input);
+ if (err < 0)
+ goto fail;
+
+ elan_touch_register_interrupt(elan_touch_data.client);
+
+ return 0;
+
+fail:
+ input_free_device(elan_touch_data.input);
+ if (elan_wq)
+ destroy_workqueue(elan_wq);
+ return err;
+}
+
+static int elan_touch_remove(struct i2c_client *client)
+{
+ if (elan_wq)
+ destroy_workqueue(elan_wq);
+
+ input_unregister_device(elan_touch_data.input);
+
+ if (elan_touch_data.use_irq)
+ free_irq(client->irq, client);
+ else
+ hrtimer_cancel(&elan_touch_data.timer);
+ return 0;
+}
+
+/* -------------------------------------------------------------------- */
+static const struct i2c_device_id elan_touch_id[] = {
+ {"elan-touch", 0},
+ {}
+};
+
+static const struct of_device_id elan_dt_ids[] = {
+ {
+ .compatible = "elan,elan-touch",
+ }, {
+ /* sentinel */
+ }
+};
+MODULE_DEVICE_TABLE(of, elan_dt_ids);
+
+static int elan_suspend(struct device *dev)
+{
+ return 0;
+}
+
+static int elan_resume(struct device *dev)
+{
+ uint8_t buf[IDX_PACKET_SIZE] = { 0 };
+
+ if (0 == elan_touch_detect_int_level()) {
+ dev_dbg(dev, "Got touch during suspend period.\n");
+ /*
+ * if touch screen during suspend, recv and drop the
+ * data, then touch interrupt pin will return high after
+ * receving data.
+ */
+ elan_touch_recv_data(elan_touch_data.client, buf);
+ }
+
+ return 0;
+}
+
+static const struct dev_pm_ops elan_dev_pm_ops = {
+ .suspend = elan_suspend,
+ .resume = elan_resume,
+};
+
+static struct i2c_driver elan_touch_driver = {
+ .probe = elan_touch_probe,
+ .remove = elan_touch_remove,
+ .id_table = elan_touch_id,
+ .driver = {
+ .name = "elan-touch",
+ .owner = THIS_MODULE,
+ .of_match_table = elan_dt_ids,
+#ifdef CONFIG_PM
+ .pm = &elan_dev_pm_ops,
+#endif
+ },
+};
+
+static int __init elan_touch_init(void)
+{
+ return i2c_add_driver(&elan_touch_driver);
+}
+
+static void __exit elan_touch_exit(void)
+{
+ i2c_del_driver(&elan_touch_driver);
+}
+
+module_init(elan_touch_init);
+module_exit(elan_touch_exit);
+
+MODULE_AUTHOR("Stanley Zeng <stanley.zeng@emc.com.tw>");
+MODULE_DESCRIPTION("ELAN Touch Screen driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/input/touchscreen/focaltech_touch/Kconfig b/drivers/input/touchscreen/focaltech_touch/Kconfig
new file mode 100644
index 000000000000..e1ec3b91202e
--- /dev/null
+++ b/drivers/input/touchscreen/focaltech_touch/Kconfig
@@ -0,0 +1,16 @@
+#
+# Focaltech Touchscreen driver configuration
+#
+
+config TOUCHSCREEN_FTS
+ bool "Focaltech Touchscreen"
+ depends on I2C
+ default n
+ help
+ Say Y here if you have Focaltech touch panel.
+ If unsure, say N.
+
+config TOUCHSCREEN_FTS_DIRECTORY
+ string "Focaltech ts directory name"
+ default "focaltech_touch"
+ depends on TOUCHSCREEN_FTS
diff --git a/drivers/input/touchscreen/focaltech_touch/Makefile b/drivers/input/touchscreen/focaltech_touch/Makefile
new file mode 100644
index 000000000000..1b2b8ec8acd4
--- /dev/null
+++ b/drivers/input/touchscreen/focaltech_touch/Makefile
@@ -0,0 +1,13 @@
+#
+# Makefile for the focaltech touchscreen drivers.
+#
+
+# Each configuration option enables a list of files.
+
+obj-$(CONFIG_TOUCHSCREEN_FTS) += focaltech_core.o
+obj-$(CONFIG_TOUCHSCREEN_FTS) += focaltech_esdcheck.o
+obj-$(CONFIG_TOUCHSCREEN_FTS) += focaltech_ex_mode.o
+obj-$(CONFIG_TOUCHSCREEN_FTS) += focaltech_gesture.o
+obj-$(CONFIG_TOUCHSCREEN_FTS) += focaltech_point_report_check.o
+obj-$(CONFIG_TOUCHSCREEN_FTS) += focaltech_i2c.o
+obj-$(CONFIG_TOUCHSCREEN_FTS) += focaltech_sensor.o
diff --git a/drivers/input/touchscreen/focaltech_touch/focaltech_common.h b/drivers/input/touchscreen/focaltech_touch/focaltech_common.h
new file mode 100644
index 000000000000..ae4807c7b700
--- /dev/null
+++ b/drivers/input/touchscreen/focaltech_touch/focaltech_common.h
@@ -0,0 +1,211 @@
+/*
+ *
+ * FocalTech fts TouchScreen driver.
+ *
+ * Copyright (c) 2010-2016, Focaltech Ltd. All rights reserved.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+/*****************************************************************************
+*
+* File Name: focaltech_common.h
+*
+* Author: Focaltech Driver Team
+*
+* Created: 2016-08-16
+*
+* Abstract:
+*
+* Reference:
+*
+*****************************************************************************/
+
+#ifndef __LINUX_FOCALTECH_COMMON_H__
+#define __LINUX_FOCALTECH_COMMON_H__
+
+#include "focaltech_config.h"
+
+/*****************************************************************************
+* Macro definitions using #define
+*****************************************************************************/
+#define FTS_DRIVER_VERSION "Focaltech V1.2 20161229"
+
+#define FLAGBIT(x) (0x00000001 << (x))
+#define FLAGBITS(x, y) ((0xFFFFFFFF >> (32 - (y) - 1)) << (x))
+
+#define FLAG_ICSERIALS_LEN 5
+#define FLAG_IDC_BIT 11
+
+#define FTS_CHIP_TYPE_MAPPING { \
+ {0x01, 0x58, 0x22, 0x58, 0x22, 0x00, 0x00, 0x58, 0x2C}, \
+ {0x02, 0x54, 0x22, 0x54, 0x22, 0x00, 0x00, 0x54, 0x2C}, \
+ {0x03, 0x64, 0x26, 0x64, 0x26, 0x00, 0x00, 0x79, 0x1C}, \
+ {0x04, 0x33, 0x67, 0x64, 0x26, 0x00, 0x00, 0x79, 0x1C}, \
+ {0x05, 0x87, 0x16, 0x87, 0x16, 0x87, 0xA6, 0x00, 0x00}, \
+ {0x06, 0x87, 0x36, 0x87, 0x36, 0x87, 0xC6, 0x00, 0x00}, \
+ {0x07, 0x80, 0x06, 0x80, 0x06, 0x80, 0xC6, 0x80, 0xB6}, \
+ {0x08, 0x86, 0x06, 0x86, 0x06, 0x86, 0xA6, 0x00, 0x00}, \
+ {0x09, 0x86, 0x07, 0x86, 0x07, 0x86, 0xA7, 0x00, 0x00}, \
+ {0x0A, 0xE7, 0x16, 0x87, 0x16, 0xE7, 0xA6, 0x87, 0xB6}, \
+}
+
+#define I2C_BUFFER_LENGTH_MAXINUM 256
+#define FILE_NAME_LENGTH 128
+#define ENABLE 1
+#define DISABLE 0
+/*register address*/
+#define FTS_REG_INT_CNT 0x8F
+#define FTS_REG_FLOW_WORK_CNT 0x91
+#define FTS_REG_WORKMODE 0x00
+#define FTS_REG_WORKMODE_FACTORY_VALUE 0x40
+#define FTS_REG_WORKMODE_WORK_VALUE 0x00
+#define FTS_REG_CHIP_ID 0xA3
+#define FTS_REG_CHIP_ID2 0x9F
+#define FTS_REG_POWER_MODE 0xA5
+#define FTS_REG_POWER_MODE_SLEEP_VALUE 0x03
+#define FTS_REG_FW_VER 0xA6
+#define FTS_REG_VENDOR_ID 0xA8
+#define FTS_REG_LCD_BUSY_NUM 0xAB
+#define FTS_REG_FACE_DEC_MODE_EN 0xB0
+#define FTS_REG_GLOVE_MODE_EN 0xC0
+#define FTS_REG_COVER_MODE_EN 0xC1
+#define FTS_REG_CHARGER_MODE_EN 0x8B
+#define FTS_REG_GESTURE_EN 0xD0
+#define FTS_REG_GESTURE_OUTPUT_ADDRESS 0xD3
+#define FTS_REG_ESD_SATURATE 0xED
+
+/*****************************************************************************
+* Alternative mode (When something goes wrong, the modules may be able to solve the problem.)
+*****************************************************************************/
+/*
+ * point report check
+ * default: disable
+ */
+#define FTS_POINT_REPORT_CHECK_EN 0
+
+/*****************************************************************************
+* Global variable or extern global variabls/functions
+*****************************************************************************/
+struct ft_chip_t {
+ unsigned long type;
+ unsigned char chip_idh;
+ unsigned char chip_idl;
+ unsigned char rom_idh;
+ unsigned char rom_idl;
+ unsigned char pramboot_idh;
+ unsigned char pramboot_idl;
+ unsigned char bootloader_idh;
+ unsigned char bootloader_idl;
+};
+
+/* i2c communication*/
+int fts_i2c_write_reg(struct i2c_client *client, u8 regaddr, u8 regvalue);
+int fts_i2c_read_reg(struct i2c_client *client, u8 regaddr, u8 *regvalue);
+int fts_i2c_read(struct i2c_client *client, char *writebuf, int writelen,
+ char *readbuf, int readlen);
+int fts_i2c_write(struct i2c_client *client, char *writebuf, int writelen);
+int fts_i2c_init(void);
+int fts_i2c_exit(void);
+
+/* Gesture functions */
+#if FTS_GESTURE_EN
+int fts_gesture_init(struct input_dev *input_dev, struct i2c_client *client);
+int fts_gesture_exit(struct i2c_client *client);
+void fts_gesture_recovery(struct i2c_client *client);
+int fts_gesture_readdata(struct i2c_client *client);
+int fts_gesture_suspend(struct i2c_client *i2c_client);
+int fts_gesture_resume(struct i2c_client *client);
+#endif
+
+/* Apk and functions */
+#if FTS_APK_NODE_EN
+int fts_create_apk_debug_channel(struct i2c_client *client);
+void fts_release_apk_debug_channel(void);
+#endif
+
+/* ADB functions */
+#if FTS_SYSFS_NODE_EN
+int fts_create_sysfs(struct i2c_client *client);
+int fts_remove_sysfs(struct i2c_client *client);
+#endif
+
+/* ESD */
+#if FTS_ESDCHECK_EN
+int fts_esdcheck_init(void);
+int fts_esdcheck_exit(void);
+int fts_esdcheck_switch(bool enable);
+int fts_esdcheck_proc_busy(bool proc_debug);
+int fts_esdcheck_set_intr(bool intr);
+int fts_esdcheck_suspend(void);
+int fts_esdcheck_resume(void);
+int fts_esdcheck_get_status(void);
+#endif
+
+/* Production test */
+#if FTS_TEST_EN
+int fts_test_init(struct i2c_client *client);
+int fts_test_exit(struct i2c_client *client);
+#endif
+
+/* Point Report Check*/
+#if FTS_POINT_REPORT_CHECK_EN
+int fts_point_report_check_init(void);
+int fts_point_report_check_exit(void);
+void fts_point_report_check_queue_work(void);
+#endif
+
+/* Other */
+extern int g_show_log;
+int fts_reset_proc(int hdelayms);
+int fts_wait_tp_to_valid(struct i2c_client *client);
+void fts_tp_state_recovery(struct i2c_client *client);
+int fts_ex_mode_init(struct i2c_client *client);
+int fts_ex_mode_exit(struct i2c_client *client);
+int fts_ex_mode_recovery(struct i2c_client *client);
+
+void fts_irq_disable(void);
+void fts_irq_enable(void);
+
+/*****************************************************************************
+* DEBUG function define here
+*****************************************************************************/
+#if FTS_DEBUG_EN
+#define FTS_DEBUG_LEVEL 1
+
+#if (FTS_DEBUG_LEVEL == 2)
+#define FTS_DEBUG(fmt, args...) \
+ printk(KERN_ERR "[FTS][%s]"fmt"\n", __func__, ##args)
+#else
+#define FTS_DEBUG(fmt, args...) \
+ printk(KERN_ERR "[FTS]"fmt"\n", ##args)
+#endif
+
+#define FTS_FUNC_ENTER() \
+ printk(KERN_ERR "[FTS]%s: Enter\n", __func__)
+#define FTS_FUNC_EXIT() \
+ printk(KERN_ERR "[FTS]%s: Exit(%d)\n", __func__, __LINE__)
+#else
+#define FTS_DEBUG(fmt, args...)
+#define FTS_FUNC_ENTER()
+#define FTS_FUNC_EXIT()
+#endif
+
+#define FTS_INFO(fmt, args...) do { \
+ if (g_show_log) \
+ printk(KERN_ERR "[FTS][Info]"fmt"\n", ##args); \
+ } while (0)
+
+#define FTS_ERROR(fmt, args...) do { \
+ if (g_show_log) \
+ printk(KERN_ERR "[FTS][Error]"fmt"\n", ##args); \
+ } while (0)
+
+#endif /* __LINUX_FOCALTECH_COMMON_H__ */
diff --git a/drivers/input/touchscreen/focaltech_touch/focaltech_config.h b/drivers/input/touchscreen/focaltech_touch/focaltech_config.h
new file mode 100644
index 000000000000..87b622e77942
--- /dev/null
+++ b/drivers/input/touchscreen/focaltech_touch/focaltech_config.h
@@ -0,0 +1,219 @@
+/*
+ *
+ * FocalTech TouchScreen driver.
+ *
+ * Copyright (c) 2010-2016, FocalTech Systems, Ltd., all rights reserved.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+/************************************************************************
+*
+* File Name: focaltech_config.h
+*
+* Author: Focaltech Driver Team
+*
+* Created: 2016-08-08
+*
+* Abstract: global configurations
+*
+* Version: v1.0
+*
+************************************************************************/
+#ifndef _LINUX_FOCLATECH_CONFIG_H_
+#define _LINUX_FOCLATECH_CONFIG_H_
+
+/**************************************************/
+/****** G: A, I: B, S: C, U: D ******************/
+/****** chip type defines, do not modify *********/
+#define _FT8716 0x87160805
+#define _FT8736 0x87360806
+#define _FT8006 0x80060807
+#define _FT8606 0x86060808
+#define _FT8607 0x86070809
+#define _FTE716 0xE716080a
+
+#define _FT5416 0x54160002
+#define _FT5426 0x54260002
+#define _FT5435 0x54350002
+#define _FT5436 0x54360002
+#define _FT5526 0x55260002
+#define _FT5526I 0x5526B002
+#define _FT5446 0x54460002
+#define _FT5346 0x53460002
+#define _FT5446I 0x5446B002
+#define _FT5346I 0x5346B002
+#define _FT7661 0x76610002
+#define _FT7511 0x75110002
+#define _FT7421 0x74210002
+#define _FT7681 0x76810002
+#define _FT3C47U 0x3C47D002
+#define _FT3417 0x34170002
+#define _FT3517 0x35170002
+#define _FT3327 0x33270002
+#define _FT3427 0x34270002
+
+#define _FT5626 0x56260001
+#define _FT5726 0x57260001
+#define _FT5826B 0x5826B001
+#define _FT5826S 0x5826C001
+#define _FT7811 0x78110001
+#define _FT3D47 0x3D470001
+#define _FT3617 0x36170001
+#define _FT3717 0x37170001
+#define _FT3817B 0x3817B001
+
+#define _FT6236U 0x6236D003
+#define _FT6336G 0x6336A003
+#define _FT6336U 0x6336D003
+#define _FT6436U 0x6436D003
+
+#define _FT3267 0x32670004
+#define _FT3367 0x33670004
+
+/******************* Enables *********************/
+/*********** 1 to enable, 0 to disable ***********/
+
+/*
+ * show debug log info
+ * enable it for debug, disable it for release
+ */
+#define FTS_DEBUG_EN 0
+
+/*
+ * Linux MultiTouch Protocol
+ * 1: Protocol B(default), 0: Protocol A
+ */
+#define FTS_MT_PROTOCOL_B_EN 1
+
+/*
+ * Report Pressure in multitouch
+ * 1:enable(default),0:disable
+*/
+#define FTS_REPORT_PRESSURE_EN 1
+
+/*
+ * Force touch support
+ * different pressure for multitouch
+ * 1: true pressure for force touch
+ * 0: constant pressure(default)
+ */
+#define FTS_FORCE_TOUCH_EN 0
+
+/*
+ * Gesture function enable
+ * default: disable
+ */
+#define FTS_GESTURE_EN 0
+
+/*
+ * ESD check & protection
+ * default: disable
+ */
+#define FTS_ESDCHECK_EN 0
+
+/*
+ * Production test enable
+ * 1: enable, 0:disable(default)
+ */
+#define FTS_TEST_EN 0
+
+/*
+ * Glove mode enable
+ * 1: enable, 0:disable(default)
+ */
+#define FTS_GLOVE_EN 0
+/*
+ * cover enable
+ * 1: enable, 0:disable(default)
+ */
+#define FTS_COVER_EN 0
+/*
+ * Charger enable
+ * 1: enable, 0:disable(default)
+ */
+#define FTS_CHARGER_EN 0
+
+/*
+ * Proximity sensor
+ * default: disable
+ */
+#define FTS_PSENSOR_EN 0
+
+/*
+ * Nodes for tools, please keep enable
+ */
+#define FTS_SYSFS_NODE_EN 1
+#define FTS_APK_NODE_EN 1
+
+/*
+ * Customer power enable
+ * enable it when customer need control TP power
+ * default: disable
+ */
+#define FTS_POWER_SOURCE_CUST_EN 0
+
+/****************************************************/
+
+/********************** Upgrade ****************************/
+/*
+ * auto upgrade, please keep enable
+ */
+#define FTS_AUTO_UPGRADE_EN 1
+
+/*
+ * auto upgrade for lcd cfg
+ * default: 0
+ */
+#define FTS_AUTO_UPGRADE_FOR_LCD_CFG_EN 0
+
+/* auto cb check
+ * default: disable
+ */
+#define FTS_AUTO_CLB_EN 0
+
+/*
+ * FW_APP.i file for upgrade
+ * define your own fw_app, the sample one is invalid
+ */
+#define FTS_UPGRADE_FW_APP "include/firmware/FT8716_app_sample.i"
+
+/*
+ * lcd_cfg.i file for lcd cfg upgrade
+ * define your own lcd_cfg.i, the sample one is invalid
+ */
+#define FTS_UPGRADE_LCD_CFG "include/firmware/lcd_cfg.i"
+
+/* get vedor id from flash
+ * default: enable
+ */
+#define FTS_GET_VENDOR_ID 0
+
+/*
+ * vendor_id(s) for the ic
+ * you need confirm vendor_id for upgrade
+ * if only one vendor, ignore vendor_2_id, otherwise
+ * you need define both of them
+ */
+#define FTS_VENDOR_1_ID 0x8d
+#define FTS_VENDOR_2_ID 0x8d
+
+/*
+ * upgrade stress test for debug
+ * enable it for upgrade debug if needed
+ * default: disable
+ */
+#define FTS_UPGRADE_STRESS_TEST 0
+/* stress test times, default: 1000 */
+#define FTS_UPGRADE_TEST_NUMBER 1000
+
+/*********************************************************/
+
+#endif /* _LINUX_FOCLATECH_CONFIG_H_ */
diff --git a/drivers/input/touchscreen/focaltech_touch/focaltech_core.c b/drivers/input/touchscreen/focaltech_touch/focaltech_core.c
new file mode 100644
index 000000000000..3c180d2189b7
--- /dev/null
+++ b/drivers/input/touchscreen/focaltech_touch/focaltech_core.c
@@ -0,0 +1,1439 @@
+/*
+ *
+ * FocalTech TouchScreen driver.
+ *
+ * Copyright (c) 2010-2016, FocalTech Systems, Ltd., all rights reserved.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+/*****************************************************************************
+*
+* File Name: focaltech_core.c
+*
+* Author: Focaltech Driver Team
+*
+* Created: 2016-08-08
+*
+* Abstract:
+*
+* Reference:
+*
+*****************************************************************************/
+
+/*****************************************************************************
+* Included header files
+*****************************************************************************/
+#include "focaltech_core.h"
+
+#if defined(CONFIG_FB)
+#include <linux/notifier.h>
+#include <linux/fb.h>
+#elif defined(CONFIG_HAS_EARLYSUSPEND)
+#include <linux/earlysuspend.h>
+#define FTS_SUSPEND_LEVEL 1 /* Early-suspend level */
+#endif
+
+/*****************************************************************************
+* Private constant and macro definitions using #define
+*****************************************************************************/
+#define FTS_DRIVER_NAME "fts_ts"
+#define INTERVAL_READ_REG 20
+#define TIMEOUT_READ_REG 300
+#if FTS_POWER_SOURCE_CUST_EN
+#define FTS_VTG_MIN_UV 2600000
+#define FTS_VTG_MAX_UV 3300000
+#define FTS_I2C_VTG_MIN_UV 1800000
+#define FTS_I2C_VTG_MAX_UV 1800000
+#endif
+#define FTS_READ_TOUCH_BUFFER_DIVIDED 0
+/*****************************************************************************
+* Global variable or extern global variabls/functions
+******************************************************************************/
+struct i2c_client *fts_i2c_client;
+struct fts_ts_data *fts_wq_data;
+struct input_dev *fts_input_dev;
+
+#if FTS_DEBUG_EN
+int g_show_log = 1;
+#else
+int g_show_log;
+#endif
+
+#if (FTS_DEBUG_EN && (FTS_DEBUG_LEVEL == 2))
+char g_sz_debug[1024] = { 0 };
+#endif
+
+/*****************************************************************************
+* Static function prototypes
+*****************************************************************************/
+static void fts_release_all_finger(void);
+static int fts_ts_suspend(struct device *dev);
+static int fts_ts_resume(struct device *dev);
+
+static bool fts_chip_idc(struct fts_ts_data *data)
+{
+ return ((data->pdata->fts_chip_type & FLAGBIT(FLAG_IDC_BIT)) ==
+ FLAGBIT(FLAG_IDC_BIT));
+}
+
+/*****************************************************************************
+* Name: fts_wait_tp_to_valid
+* Brief: Read chip id until TP FW become valid,
+* need call when reset/power on/resume...
+* 1. Read Chip ID per INTERVAL_READ_REG(20ms)
+* 2. Timeout: TIMEOUT_READ_REG(300ms)
+* Input:
+* Output:
+* Return: 0 - Get correct Device ID
+*****************************************************************************/
+int fts_wait_tp_to_valid(struct i2c_client *client)
+{
+ int ret = 0;
+ int cnt = 0;
+ u8 reg_value = 0;
+
+ do {
+ ret = fts_i2c_read_reg(client, FTS_REG_CHIP_ID, &reg_value);
+ if (ret < 0)
+ FTS_INFO("TP Not Ready, ReadData = 0x%x", reg_value);
+ else {
+ FTS_INFO("TP Ready, Device ID = 0x%x", reg_value);
+ return 0;
+ }
+ cnt++;
+ msleep(INTERVAL_READ_REG);
+ } while ((cnt * INTERVAL_READ_REG) < TIMEOUT_READ_REG);
+
+ /* error: not get correct reg data */
+ return -1;
+}
+
+/*****************************************************************************
+* Name: fts_recover_state
+* Brief: Need execute this function when reset
+* Input:
+* Output:
+* Return:
+*****************************************************************************/
+void fts_tp_state_recovery(struct i2c_client *client)
+{
+ /* wait tp stable */
+ fts_wait_tp_to_valid(client);
+ /* recover TP charger state 0x8B */
+ /* recover TP glove state 0xC0 */
+ /* recover TP cover state 0xC1 */
+ fts_ex_mode_recovery(client);
+ /* recover TP gesture state 0xD0 */
+#if FTS_GESTURE_EN
+ fts_gesture_recovery(client);
+#endif
+
+ fts_release_all_finger();
+}
+
+/*****************************************************************************
+* Name: fts_reset_proc
+* Brief: Execute reset operation
+* Input: hdelayms - delay time unit:ms
+* Output:
+* Return:
+*****************************************************************************/
+int fts_reset_proc(int hdelayms)
+{
+ gpio_direction_output(fts_wq_data->pdata->reset_gpio, 0);
+ msleep(20);
+ gpio_direction_output(fts_wq_data->pdata->reset_gpio, 1);
+ msleep(hdelayms);
+
+ return 0;
+}
+
+/*****************************************************************************
+* Name: fts_irq_disable
+* Brief: disable irq
+* Input:
+* sync:
+* Output:
+* Return:
+*****************************************************************************/
+void fts_irq_disable(void)
+{
+ unsigned long irqflags;
+
+ spin_lock_irqsave(&fts_wq_data->irq_lock, irqflags);
+
+ if (!fts_wq_data->irq_disable) {
+ disable_irq_nosync(fts_wq_data->client->irq);
+ fts_wq_data->irq_disable = 1;
+ }
+
+ spin_unlock_irqrestore(&fts_wq_data->irq_lock, irqflags);
+}
+
+/*****************************************************************************
+* Name: fts_irq_enable
+* Brief: enable irq
+* Input:
+* Output:
+* Return:
+*****************************************************************************/
+void fts_irq_enable(void)
+{
+ unsigned long irqflags = 0;
+
+ spin_lock_irqsave(&fts_wq_data->irq_lock, irqflags);
+
+ if (fts_wq_data->irq_disable) {
+ enable_irq(fts_wq_data->client->irq);
+ fts_wq_data->irq_disable = 0;
+ }
+
+ spin_unlock_irqrestore(&fts_wq_data->irq_lock, irqflags);
+}
+
+/*****************************************************************************
+* Name: fts_input_dev_init
+* Brief: input dev init
+* Input:
+* Output:
+* Return:
+*****************************************************************************/
+static int fts_input_dev_init(struct i2c_client *client,
+ struct fts_ts_data *data,
+ struct input_dev *input_dev,
+ struct fts_ts_platform_data *pdata)
+{
+ int err, len;
+
+ FTS_FUNC_ENTER();
+
+ /* Init and register Input device */
+ input_dev->name = FTS_DRIVER_NAME;
+ input_dev->id.bustype = BUS_I2C;
+ input_dev->dev.parent = &client->dev;
+
+ input_set_drvdata(input_dev, data);
+ i2c_set_clientdata(client, data);
+
+ __set_bit(EV_KEY, input_dev->evbit);
+ if (data->pdata->have_key) {
+ FTS_DEBUG("set key capabilities");
+ for (len = 0; len < data->pdata->key_number; len++) {
+ input_set_capability(input_dev, EV_KEY,
+ data->pdata->keys[len]);
+ }
+ }
+ __set_bit(EV_ABS, input_dev->evbit);
+ __set_bit(BTN_TOUCH, input_dev->keybit);
+ __set_bit(INPUT_PROP_DIRECT, input_dev->propbit);
+
+#if FTS_MT_PROTOCOL_B_EN
+ input_mt_init_slots(input_dev, pdata->max_touch_number,
+ INPUT_MT_DIRECT);
+#else
+ input_set_abs_params(input_dev, ABS_MT_TRACKING_ID, 0, 0x0f, 0, 0);
+#endif
+ input_set_abs_params(input_dev, ABS_MT_POSITION_X, pdata->x_min,
+ pdata->x_max, 0, 0);
+ input_set_abs_params(input_dev, ABS_MT_POSITION_Y, pdata->y_min,
+ pdata->y_max, 0, 0);
+ input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, 0, 0xFF, 0, 0);
+#if FTS_REPORT_PRESSURE_EN
+ input_set_abs_params(input_dev, ABS_MT_PRESSURE, 0, 0xFF, 0, 0);
+#endif
+
+ err = input_register_device(input_dev);
+ if (err) {
+ FTS_ERROR("Input device registration failed");
+ goto free_inputdev;
+ }
+
+ FTS_FUNC_EXIT();
+
+ return 0;
+
+free_inputdev:
+ input_free_device(input_dev);
+ FTS_FUNC_EXIT();
+ return err;
+
+}
+
+/*****************************************************************************
+* Power Control
+*****************************************************************************/
+#if FTS_POWER_SOURCE_CUST_EN
+static int fts_power_source_init(struct fts_ts_data *data)
+{
+ int rc;
+
+ FTS_FUNC_ENTER();
+
+ data->vdd = regulator_get(&data->client->dev, "vdd");
+ if (IS_ERR(data->vdd)) {
+ rc = PTR_ERR(data->vdd);
+ FTS_ERROR("Regulator get failed vdd rc=%d", rc);
+ }
+
+ if (regulator_count_voltages(data->vdd) > 0) {
+ rc = regulator_set_voltage(data->vdd, FTS_VTG_MIN_UV,
+ FTS_VTG_MAX_UV);
+ if (rc) {
+ FTS_ERROR("Regulator set_vtg failed vdd rc=%d", rc);
+ goto reg_vdd_put;
+ }
+ }
+
+ data->vcc_i2c = regulator_get(&data->client->dev, "vcc_i2c");
+ if (IS_ERR(data->vcc_i2c)) {
+ rc = PTR_ERR(data->vcc_i2c);
+ FTS_ERROR("Regulator get failed vcc_i2c rc=%d", rc);
+ goto reg_vdd_set_vtg;
+ }
+
+ if (regulator_count_voltages(data->vcc_i2c) > 0) {
+ rc = regulator_set_voltage(data->vcc_i2c, FTS_I2C_VTG_MIN_UV,
+ FTS_I2C_VTG_MAX_UV);
+ if (rc) {
+ FTS_ERROR("Regulator set_vtg failed vcc_i2c rc=%d", rc);
+ goto reg_vcc_i2c_put;
+ }
+ }
+
+ FTS_FUNC_EXIT();
+ return 0;
+
+reg_vcc_i2c_put:
+ regulator_put(data->vcc_i2c);
+reg_vdd_set_vtg:
+ if (regulator_count_voltages(data->vdd) > 0)
+ regulator_set_voltage(data->vdd, 0, FTS_VTG_MAX_UV);
+reg_vdd_put:
+ regulator_put(data->vdd);
+ FTS_FUNC_EXIT();
+ return rc;
+}
+
+static int fts_power_source_ctrl(struct fts_ts_data *data, int enable)
+{
+ int rc;
+
+ FTS_FUNC_ENTER();
+ if (enable) {
+ rc = regulator_enable(data->vdd);
+ if (rc)
+ FTS_ERROR("Regulator vdd enable failed rc=%d", rc);
+
+ rc = regulator_enable(data->vcc_i2c);
+ if (rc)
+ FTS_ERROR("Regulator vcc_i2c enable failed rc=%d", rc);
+ } else {
+ rc = regulator_disable(data->vdd);
+ if (rc)
+ FTS_ERROR("Regulator vdd disable failed rc=%d", rc);
+ rc = regulator_disable(data->vcc_i2c);
+ if (rc)
+ FTS_ERROR("Regulator vcc_i2c disable failed rc=%d", rc);
+ }
+ FTS_FUNC_EXIT();
+ return 0;
+}
+
+#endif
+
+/*****************************************************************************
+* Reprot related
+*****************************************************************************/
+/*****************************************************************************
+* Name: fts_release_all_finger
+* Brief:
+* Input:
+* Output:
+* Return:
+*****************************************************************************/
+static void fts_release_all_finger(void)
+{
+#if FTS_MT_PROTOCOL_B_EN
+ unsigned int finger_count = 0;
+
+ for (finger_count = 0;
+ finger_count < fts_wq_data->pdata->max_touch_number;
+ finger_count++) {
+ input_mt_slot(fts_input_dev, finger_count);
+ input_mt_report_slot_state(fts_input_dev, MT_TOOL_FINGER,
+ false);
+ }
+#else
+ input_mt_sync(fts_input_dev);
+#endif
+ input_report_key(fts_input_dev, BTN_TOUCH, 0);
+ input_sync(fts_input_dev);
+}
+
+#if (FTS_DEBUG_EN && (FTS_DEBUG_LEVEL == 2))
+static void fts_show_touch_buffer(u8 *buf, int point_num)
+{
+ int len = point_num * FTS_ONE_TCH_LEN;
+ int count = 0;
+ int i;
+
+ memset(g_sz_debug, 0, 1024);
+ if (len > (POINT_READ_BUF - 3))
+ len = POINT_READ_BUF - 3;
+ else if (len == 0) {
+ len += FTS_ONE_TCH_LEN;
+
+ count += sprintf(g_sz_debug, "%02X,%02X,%02X", buf[0], buf[1], buf[2]);
+ for (i = 0; i < len; i++)
+ count += sprintf(g_sz_debug + count, ",%02X", buf[i + 3]);
+
+ FTS_DEBUG("buffer: %s", g_sz_debug);
+}
+#endif
+
+static int fts_input_dev_report_key_event(struct ts_event *event,
+ struct fts_ts_data *data)
+{
+ int i;
+
+ if (data->pdata->have_key) {
+ if ((1 == event->touch_point || 1 == event->point_num)
+ && (event->au16_y[0] == data->pdata->key_y_coord)) {
+
+ if (event->point_num == 0) {
+ FTS_DEBUG("Keys All Up!");
+ for (i = 0; i < data->pdata->key_number; i++) {
+ input_report_key(data->input_dev,
+ data->pdata->keys[i],
+ 0);
+ }
+ } else {
+ for (i = 0; i < data->pdata->key_number; i++) {
+ if (event->au16_x[0] >
+ (data->pdata->key_x_coords[i] -
+ FTS_KEY_WIDTH)
+ && event->au16_x[0] <
+ (data->pdata->key_x_coords[i] +
+ FTS_KEY_WIDTH)) {
+
+ if (event->au8_touch_event[i] ==
+ 0
+ || event->au8_touch_event[i]
+ == 2) {
+ input_report_key
+ (data->input_dev,
+ data->pdata->keys
+ [i], 1);
+ FTS_DEBUG
+ ("Key%d(%d, %d) DOWN!",
+ i,
+ event->au16_x[0],
+ event->au16_y[0]);
+ } else {
+ input_report_key
+ (data->input_dev,
+ data->pdata->keys
+ [i], 0);
+ FTS_DEBUG
+ ("Key%d(%d, %d) Up!",
+ i,
+ event->au16_x[0],
+ event->au16_y[0]);
+ }
+ break;
+ }
+ }
+ }
+ input_sync(data->input_dev);
+ return 0;
+ }
+ }
+
+ return -1;
+}
+
+#if FTS_MT_PROTOCOL_B_EN
+static int fts_input_dev_report_b(struct ts_event *event,
+ struct fts_ts_data *data)
+{
+ int i = 0;
+ int uppoint = 0;
+ int touchs = 0;
+
+ for (i = 0; i < event->touch_point; i++) {
+ input_mt_slot(data->input_dev, event->au8_finger_id[i]);
+
+ if (event->au8_touch_event[i] == FTS_TOUCH_DOWN
+ || event->au8_touch_event[i] == FTS_TOUCH_CONTACT) {
+ input_mt_report_slot_state(data->input_dev,
+ MT_TOOL_FINGER, true);
+
+#if FTS_REPORT_PRESSURE_EN
+#if FTS_FORCE_TOUCH_EN
+ if (event->pressure[i] <= 0) {
+ FTS_ERROR("[B]Illegal pressure: %d",
+ event->pressure[i]);
+ event->pressure[i] = 1;
+ }
+#else
+ event->pressure[i] = 0x3f;
+#endif
+ input_report_abs(data->input_dev, ABS_MT_PRESSURE,
+ event->pressure[i]);
+#endif
+
+ if (event->area[i] <= 0) {
+ FTS_ERROR("[B]Illegal touch-major: %d",
+ event->area[i]);
+ event->area[i] = 1;
+ }
+ input_report_abs(data->input_dev, ABS_MT_TOUCH_MAJOR,
+ event->area[i]);
+
+ input_report_abs(data->input_dev, ABS_MT_POSITION_X,
+ event->au16_x[i]);
+ input_report_abs(data->input_dev, ABS_MT_POSITION_Y,
+ event->au16_y[i]);
+ touchs |= BIT(event->au8_finger_id[i]);
+ data->touchs |= BIT(event->au8_finger_id[i]);
+
+#if FTS_REPORT_PRESSURE_EN
+ FTS_DEBUG("[B]P%d(%d, %d)[p:%d,tm:%d] DOWN!",
+ event->au8_finger_id[i], event->au16_x[i],
+ event->au16_y[i], event->pressure[i],
+ event->area[i]);
+#else
+ FTS_DEBUG("[B]P%d(%d, %d)[tm:%d] DOWN!",
+ event->au8_finger_id[i], event->au16_x[i],
+ event->au16_y[i], event->area[i]);
+#endif
+ } else {
+ uppoint++;
+ input_mt_report_slot_state(data->input_dev,
+ MT_TOOL_FINGER, false);
+#if FTS_REPORT_PRESSURE_EN
+ input_report_abs(data->input_dev, ABS_MT_PRESSURE, 0);
+#endif
+ data->touchs &= ~BIT(event->au8_finger_id[i]);
+ FTS_DEBUG("[B]P%d UP!", event->au8_finger_id[i]);
+ }
+ }
+
+ if (unlikely(data->touchs ^ touchs)) {
+ for (i = 0; i < data->pdata->max_touch_number; i++) {
+ if (BIT(i) & (data->touchs ^ touchs)) {
+ FTS_DEBUG("[B]P%d UP!", i);
+ input_mt_slot(data->input_dev, i);
+ input_mt_report_slot_state(data->input_dev,
+ MT_TOOL_FINGER,
+ false);
+#if FTS_REPORT_PRESSURE_EN
+ input_report_abs(data->input_dev,
+ ABS_MT_PRESSURE, 0);
+#endif
+ }
+ }
+ }
+
+ data->touchs = touchs;
+ if (event->touch_point == uppoint) {
+ FTS_DEBUG("Points All Up!");
+ input_report_key(data->input_dev, BTN_TOUCH, 0);
+ } else {
+ input_report_key(data->input_dev, BTN_TOUCH,
+ event->touch_point > 0);
+ }
+
+ input_sync(data->input_dev);
+
+ return 0;
+
+}
+
+#else
+static int fts_input_dev_report_a(struct ts_event *event,
+ struct fts_ts_data *data)
+{
+ int i = 0;
+ int uppoint = 0;
+ int touchs = 0;
+
+ for (i = 0; i < event->touch_point; i++) {
+
+ if (event->au8_touch_event[i] == FTS_TOUCH_DOWN
+ || event->au8_touch_event[i] == FTS_TOUCH_CONTACT) {
+ input_report_abs(data->input_dev, ABS_MT_TRACKING_ID,
+ event->au8_finger_id[i]);
+#if FTS_REPORT_PRESSURE_EN
+#if FTS_FORCE_TOUCH_EN
+ if (event->pressure[i] <= 0) {
+ FTS_ERROR("[B]Illegal pressure: %d",
+ event->pressure[i]);
+ event->pressure[i] = 1;
+ }
+#else
+ event->pressure[i] = 0x3f;
+#endif
+ input_report_abs(data->input_dev, ABS_MT_PRESSURE,
+ event->pressure[i]);
+#endif
+
+ if (event->area[i] <= 0) {
+ FTS_ERROR("[B]Illegal touch-major: %d",
+ event->area[i]);
+ event->area[i] = 1;
+ }
+ input_report_abs(data->input_dev, ABS_MT_TOUCH_MAJOR,
+ event->area[i]);
+
+ input_report_abs(data->input_dev, ABS_MT_POSITION_X,
+ event->au16_x[i]);
+ input_report_abs(data->input_dev, ABS_MT_POSITION_Y,
+ event->au16_y[i]);
+
+ input_mt_sync(data->input_dev);
+
+#if FTS_REPORT_PRESSURE_EN
+ FTS_DEBUG("[B]P%d(%d, %d)[p:%d,tm:%d] DOWN!",
+ event->au8_finger_id[i], event->au16_x[i],
+ event->au16_y[i], event->pressure[i],
+ event->area[i]);
+#else
+ FTS_DEBUG("[B]P%d(%d, %d)[tm:%d] DOWN!",
+ event->au8_finger_id[i], event->au16_x[i],
+ event->au16_y[i], event->area[i]);
+#endif
+ } else {
+ uppoint++;
+ }
+ }
+
+ data->touchs = touchs;
+ if (event->touch_point == uppoint) {
+ FTS_DEBUG("Points All Up!");
+ input_report_key(data->input_dev, BTN_TOUCH, 0);
+ input_mt_sync(data->input_dev);
+ } else {
+ input_report_key(data->input_dev, BTN_TOUCH,
+ event->touch_point > 0);
+ }
+
+ input_sync(data->input_dev);
+
+ return 0;
+}
+#endif
+
+/*****************************************************************************
+* Name: fts_read_touchdata
+* Brief:
+* Input:
+* Output:
+* Return:
+*****************************************************************************/
+static int fts_read_touchdata(struct fts_ts_data *data)
+{
+ u8 buf[POINT_READ_BUF] = { 0 };
+ u8 pointid = FTS_MAX_ID;
+ int ret = -1;
+ int i;
+ struct ts_event *event = &(data->event);
+
+#if FTS_GESTURE_EN
+ {
+ u8 state;
+
+ if (data->suspended) {
+ fts_i2c_read_reg(data->client, FTS_REG_GESTURE_EN,
+ &state);
+ if (state == 1) {
+ fts_gesture_readdata(data->client);
+ return 1;
+ }
+ }
+ }
+#endif
+
+#if FTS_PSENSOR_EN
+ if ((fts_sensor_read_data(data) != 0) && (data->suspended == 1))
+ return 1;
+#endif
+
+#if FTS_READ_TOUCH_BUFFER_DIVIDED
+ memset(buf, 0xFF, POINT_READ_BUF);
+ memset(event, 0, sizeof(struct ts_event));
+
+ buf[0] = 0x00;
+ ret = fts_i2c_read(data->client, buf, 1, buf, (3 + FTS_ONE_TCH_LEN));
+ if (ret < 0) {
+ FTS_ERROR("%s read touchdata failed.", __func__);
+ return ret;
+ }
+ event->touch_point = 0;
+ event->point_num = buf[FTS_TOUCH_POINT_NUM] & 0x0F;
+ if (event->point_num > data->pdata->max_touch_number)
+ event->point_num = data->pdata->max_touch_number;
+
+ if (event->point_num > 1) {
+ buf[9] = 0x09;
+ fts_i2c_read(data->client, buf + 9, 1, buf + 9,
+ (event->point_num - 1) * FTS_ONE_TCH_LEN);
+ }
+#else
+ ret = fts_i2c_read(data->client, buf, 1, buf, POINT_READ_BUF);
+ if (ret < 0) {
+ FTS_ERROR("[B]Read touchdata failed, ret: %d", ret);
+ return ret;
+ }
+#if FTS_POINT_REPORT_CHECK_EN
+ fts_point_report_check_queue_work();
+#endif
+
+ memset(event, 0, sizeof(struct ts_event));
+ event->point_num = buf[FTS_TOUCH_POINT_NUM] & 0x0F;
+ if (event->point_num > data->pdata->max_touch_number)
+ event->point_num = data->pdata->max_touch_number;
+ event->touch_point = 0;
+#endif
+
+#if (FTS_DEBUG_EN && (FTS_DEBUG_LEVEL == 2))
+ fts_show_touch_buffer(buf, event->point_num);
+#endif
+
+ for (i = 0; i < data->pdata->max_touch_number; i++) {
+ pointid = (buf[FTS_TOUCH_ID_POS + FTS_ONE_TCH_LEN * i]) >> 4;
+ if (pointid >= FTS_MAX_ID)
+ break;
+
+ event->touch_point++;
+ event->au16_x[i] =
+ (s16) (buf[FTS_TOUCH_X_H_POS + FTS_ONE_TCH_LEN * i] & 0x0F)
+ << 8 | (s16) buf[FTS_TOUCH_X_L_POS + FTS_ONE_TCH_LEN * i];
+ event->au16_y[i] =
+ (s16) (buf[FTS_TOUCH_Y_H_POS + FTS_ONE_TCH_LEN * i] & 0x0F)
+ << 8 | (s16) buf[FTS_TOUCH_Y_L_POS + FTS_ONE_TCH_LEN * i];
+ event->au8_touch_event[i] =
+ buf[FTS_TOUCH_EVENT_POS + FTS_ONE_TCH_LEN * i] >> 6;
+
+ if (data->pdata->swap)
+ swap(event->au16_x[i], event->au16_y[i]);
+
+ if (data->pdata->scaling_down_half) {
+ event->au16_x[i] = event->au16_x[i] >> 1;
+ event->au16_y[i] = event->au16_y[i] >> 1;
+ }
+
+ event->au8_finger_id[i] =
+ (buf[FTS_TOUCH_ID_POS + FTS_ONE_TCH_LEN * i]) >> 4;
+ event->area[i] =
+ (buf[FTS_TOUCH_AREA_POS + FTS_ONE_TCH_LEN * i]) >> 4;
+ event->pressure[i] =
+ (s16) buf[FTS_TOUCH_PRE_POS + FTS_ONE_TCH_LEN * i];
+
+ if (0 == event->area[i])
+ event->area[i] = 0x09;
+
+ if (0 == event->pressure[i])
+ event->pressure[i] = 0x3f;
+
+ if ((event->au8_touch_event[i] == 0
+ || event->au8_touch_event[i] == 2)
+ && (event->point_num == 0))
+ break;
+ }
+ return 0;
+}
+
+/*****************************************************************************
+* Name: fts_report_value
+* Brief:
+* Input:
+* Output:
+* Return:
+*****************************************************************************/
+static void fts_report_value(struct fts_ts_data *data)
+{
+ struct ts_event *event = &data->event;
+
+ FTS_DEBUG("point number: %d, touch point: %d", event->point_num,
+ event->touch_point);
+
+ if (0 == fts_input_dev_report_key_event(event, data))
+ return;
+#if FTS_MT_PROTOCOL_B_EN
+ fts_input_dev_report_b(event, data);
+#else
+ fts_input_dev_report_a(event, data);
+#endif
+
+ return;
+
+}
+
+/*****************************************************************************
+* Name: fts_ts_interrupt
+* Brief:
+* Input:
+* Output:
+* Return:
+*****************************************************************************/
+static irqreturn_t fts_ts_interrupt(int irq, void *dev_id)
+{
+ struct fts_ts_data *fts_ts = dev_id;
+ int ret = -1;
+
+ if (!fts_ts) {
+ FTS_ERROR("[INTR]: Invalid fts_ts");
+ return IRQ_HANDLED;
+ }
+#if FTS_ESDCHECK_EN
+ fts_esdcheck_set_intr(1);
+#endif
+
+ ret = fts_read_touchdata(fts_wq_data);
+
+ if (ret == 0)
+ fts_report_value(fts_wq_data);
+#if FTS_ESDCHECK_EN
+ fts_esdcheck_set_intr(0);
+#endif
+
+ return IRQ_HANDLED;
+}
+
+/*****************************************************************************
+* Name: fts_gpio_configure
+* Brief: Configure IRQ&RESET GPIO
+* Input:
+* Output:
+* Return:
+*****************************************************************************/
+static int fts_gpio_configure(struct fts_ts_data *data)
+{
+ int err = 0;
+
+ FTS_FUNC_ENTER();
+ /* request irq gpio */
+ if (gpio_is_valid(data->pdata->irq_gpio)) {
+ err = gpio_request(data->pdata->irq_gpio, "fts_irq_gpio");
+ if (err) {
+ FTS_ERROR("[GPIO]irq gpio request failed");
+ goto err_irq_gpio_req;
+ }
+
+ err = gpio_direction_input(data->pdata->irq_gpio);
+ if (err) {
+ FTS_ERROR("[GPIO]set_direction for irq gpio failed");
+ goto err_irq_gpio_dir;
+ }
+ }
+ /* request reset gpio */
+ if (gpio_is_valid(data->pdata->reset_gpio)) {
+ err = gpio_request(data->pdata->reset_gpio, "fts_reset_gpio");
+ if (err) {
+ FTS_ERROR("[GPIO]reset gpio request failed");
+ goto err_irq_gpio_dir;
+ }
+
+ err = gpio_direction_output(data->pdata->reset_gpio, 1);
+ if (err) {
+ FTS_ERROR("[GPIO]set_direction for reset gpio failed");
+ goto err_reset_gpio_dir;
+ }
+ }
+
+ FTS_FUNC_EXIT();
+ return 0;
+
+err_reset_gpio_dir:
+ if (gpio_is_valid(data->pdata->reset_gpio))
+ gpio_free(data->pdata->reset_gpio);
+err_irq_gpio_dir:
+ if (gpio_is_valid(data->pdata->irq_gpio))
+ gpio_free(data->pdata->irq_gpio);
+err_irq_gpio_req:
+ FTS_FUNC_EXIT();
+ return err;
+}
+
+/*****************************************************************************
+* Name: fts_get_dt_coords
+* Brief:
+* Input:
+* Output:
+* Return:
+*****************************************************************************/
+static int fts_get_dt_coords(struct device *dev, char *name,
+ struct fts_ts_platform_data *pdata)
+{
+ u32 coords[FTS_COORDS_ARR_SIZE];
+ struct property *prop;
+ struct device_node *np = dev->of_node;
+ int coords_size, rc;
+
+ prop = of_find_property(np, name, NULL);
+ if (!prop)
+ return -EINVAL;
+ if (!prop->value)
+ return -ENODATA;
+
+ coords_size = prop->length / sizeof(u32);
+ if (coords_size != FTS_COORDS_ARR_SIZE) {
+ FTS_ERROR("invalid %s", name);
+ return -EINVAL;
+ }
+
+ rc = of_property_read_u32_array(np, name, coords, coords_size);
+ if (rc && (rc != -EINVAL)) {
+ FTS_ERROR("Unable to read %s", name);
+ return rc;
+ }
+
+ if (!strcmp(name, "focaltech,display-coords")) {
+ pdata->x_min = coords[0];
+ pdata->y_min = coords[1];
+ pdata->x_max = coords[2];
+ pdata->y_max = coords[3];
+ } else {
+ FTS_ERROR("unsupported property %s", name);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+/*****************************************************************************
+* Name: fts_parse_dt
+* Brief:
+* Input:
+* Output:
+* Return:
+*****************************************************************************/
+static int fts_parse_dt(struct device *dev, struct fts_ts_platform_data *pdata)
+{
+ int rc;
+ struct device_node *np = dev->of_node;
+ u32 temp_val;
+
+ FTS_FUNC_ENTER();
+
+ pdata->fts_chip_type = _FT5416;
+ rc = of_property_read_u32(np, "focaltech,panel-type",
+ &pdata->fts_chip_type);
+ if (rc)
+ FTS_ERROR("Panel type is undefined, use default panel FT5416");
+
+ rc = fts_get_dt_coords(dev, "focaltech,display-coords", pdata);
+ if (rc)
+ FTS_ERROR("Unable to get display-coords");
+
+ /* key */
+ pdata->have_key = of_property_read_bool(np, "focaltech,have-key");
+ if (pdata->have_key) {
+ rc = of_property_read_u32(np, "focaltech,key-number",
+ &pdata->key_number);
+ if (rc)
+ FTS_ERROR("Key number undefined!");
+ rc = of_property_read_u32_array(np, "focaltech,keys",
+ pdata->keys, pdata->key_number);
+ if (rc)
+ FTS_ERROR("Keys undefined!");
+ rc = of_property_read_u32(np, "focaltech,key-y-coord",
+ &pdata->key_y_coord);
+ if (rc)
+ FTS_ERROR("Key Y Coord undefined!");
+ rc = of_property_read_u32_array(np, "focaltech,key-x-coords",
+ pdata->key_x_coords,
+ pdata->key_number);
+ if (rc)
+ FTS_ERROR("Key X Coords undefined!");
+
+ FTS_DEBUG("%d: (%d, %d, %d), [%d, %d, %d][%d]",
+ pdata->key_number, pdata->keys[0], pdata->keys[1],
+ pdata->keys[2], pdata->key_x_coords[0],
+ pdata->key_x_coords[1], pdata->key_x_coords[2],
+ pdata->key_y_coord);
+ }
+
+ /* reset, irq gpio info */
+ pdata->reset_gpio =
+ of_get_named_gpio_flags(np, "focaltech,reset-gpio", 0,
+ &pdata->reset_gpio_flags);
+ if (pdata->reset_gpio < 0)
+ FTS_ERROR("Unable to get reset_gpio");
+
+ pdata->irq_gpio =
+ of_get_named_gpio_flags(np, "focaltech,irq-gpio", 0,
+ &pdata->irq_gpio_flags);
+ if (pdata->irq_gpio < 0)
+ FTS_ERROR("Unable to get irq_gpio");
+
+ rc = of_property_read_u32(np, "focaltech,max-touch-number", &temp_val);
+ if (!rc) {
+ pdata->max_touch_number = temp_val;
+ FTS_DEBUG("max_touch_number=%d", pdata->max_touch_number);
+ } else {
+ FTS_ERROR("Unable to get max-touch-number");
+ pdata->max_touch_number = FTS_MAX_POINTS;
+ }
+
+ pdata->swap = of_property_read_bool(np, "focaltech,swap-xy");
+ pdata->scaling_down_half = of_property_read_bool(np,
+ "focaltech,scaling-down-half");
+
+ FTS_FUNC_EXIT();
+ return 0;
+}
+
+#if defined(CONFIG_FB)
+/*****************************************************************************
+* Name: fb_notifier_callback
+* Brief:
+* Input:
+* Output:
+* Return:
+*****************************************************************************/
+static int fb_notifier_callback(struct notifier_block *self,
+ unsigned long event, void *data)
+{
+ struct fb_event *evdata = data;
+ int *blank;
+ struct fts_ts_data *fts_data =
+ container_of(self, struct fts_ts_data, fb_notif);
+
+ if (evdata && evdata->data && event == FB_EVENT_BLANK && fts_data
+ && fts_data->client) {
+ blank = evdata->data;
+ if (*blank == FB_BLANK_UNBLANK)
+ fts_ts_resume(&fts_data->client->dev);
+ else if (*blank == FB_BLANK_POWERDOWN)
+ fts_ts_suspend(&fts_data->client->dev);
+ }
+
+ return 0;
+}
+#elif defined(CONFIG_HAS_EARLYSUSPEND)
+/*****************************************************************************
+* Name: fts_ts_early_suspend
+* Brief:
+* Input:
+* Output:
+* Return:
+*****************************************************************************/
+static void fts_ts_early_suspend(struct early_suspend *handler)
+{
+ struct fts_ts_data *data = container_of(handler,
+ struct fts_ts_data,
+ early_suspend);
+
+ fts_ts_suspend(&data->client->dev);
+}
+
+/*****************************************************************************
+* Name: fts_ts_late_resume
+* Brief:
+* Input:
+* Output:
+* Return:
+*****************************************************************************/
+static void fts_ts_late_resume(struct early_suspend *handler)
+{
+ struct fts_ts_data *data = container_of(handler,
+ struct fts_ts_data,
+ early_suspend);
+
+ fts_ts_resume(&data->client->dev);
+}
+#endif
+
+/*****************************************************************************
+* Name: fts_ts_probe
+* Brief:
+* Input:
+* Output:
+* Return:
+*****************************************************************************/
+static int fts_ts_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct fts_ts_platform_data *pdata;
+ struct fts_ts_data *data;
+ struct input_dev *input_dev;
+ int err;
+
+ FTS_FUNC_ENTER();
+ /* 1. Get Platform data */
+ if (client->dev.of_node) {
+ pdata =
+ devm_kzalloc(&client->dev,
+ sizeof(struct fts_ts_platform_data),
+ GFP_KERNEL);
+ if (!pdata) {
+ FTS_ERROR("[MEMORY]Failed to allocate memory");
+ FTS_FUNC_EXIT();
+ return -ENOMEM;
+ }
+ err = fts_parse_dt(&client->dev, pdata);
+ if (err)
+ FTS_ERROR("[DTS]DT parsing failed");
+ } else
+ pdata = client->dev.platform_data;
+
+ if (!pdata) {
+ FTS_ERROR("Invalid pdata");
+ FTS_FUNC_EXIT();
+ return -EINVAL;
+ }
+
+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
+ FTS_ERROR("I2C not supported");
+ FTS_FUNC_EXIT();
+ return -ENODEV;
+ }
+
+ data =
+ devm_kzalloc(&client->dev, sizeof(struct fts_ts_data), GFP_KERNEL);
+ if (!data) {
+ FTS_ERROR("[MEMORY]Failed to allocate memory");
+ FTS_FUNC_EXIT();
+ return -ENOMEM;
+ }
+
+ input_dev = input_allocate_device();
+ if (!input_dev) {
+ FTS_ERROR("[INPUT]Failed to allocate input device");
+ FTS_FUNC_EXIT();
+ return -ENOMEM;
+ }
+
+ data->input_dev = input_dev;
+ data->client = client;
+ data->pdata = pdata;
+
+ fts_wq_data = data;
+ fts_i2c_client = client;
+ fts_input_dev = input_dev;
+
+ spin_lock_init(&fts_wq_data->irq_lock);
+
+ fts_input_dev_init(client, data, input_dev, pdata);
+
+#if FTS_POWER_SOURCE_CUST_EN
+ fts_power_source_init(data);
+ fts_power_source_ctrl(data, 1);
+#endif
+
+ err = fts_gpio_configure(data);
+ if (err < 0) {
+ FTS_ERROR("[GPIO]Failed to configure the gpios");
+ goto free_gpio;
+ }
+
+ fts_reset_proc(200);
+ fts_wait_tp_to_valid(client);
+
+ err =
+ request_threaded_irq(client->irq, NULL, fts_ts_interrupt,
+ pdata->irq_gpio_flags | IRQF_ONESHOT |
+ IRQF_TRIGGER_FALLING, client->dev.driver->name,
+ data);
+ if (err) {
+ FTS_ERROR("Request irq failed!");
+ goto free_gpio;
+ }
+
+ fts_irq_disable();
+
+#if FTS_PSENSOR_EN
+ if (fts_sensor_init(data) != 0) {
+ FTS_ERROR("fts_sensor_init failed!");
+ FTS_FUNC_EXIT();
+ return 0;
+ }
+#endif
+
+#if FTS_POINT_REPORT_CHECK_EN
+ fts_point_report_check_init();
+#endif
+
+ fts_ex_mode_init(client);
+
+#if FTS_GESTURE_EN
+ fts_gesture_init(input_dev, client);
+#endif
+
+#if FTS_ESDCHECK_EN
+ fts_esdcheck_init();
+#endif
+
+ fts_irq_enable();
+
+#if FTS_TEST_EN
+ fts_test_init(client);
+#endif
+
+#if defined(CONFIG_FB)
+ data->fb_notif.notifier_call = fb_notifier_callback;
+ err = fb_register_client(&data->fb_notif);
+ if (err)
+ FTS_ERROR("[FB]Unable to register fb_notifier: %d", err);
+#elif defined(CONFIG_HAS_EARLYSUSPEND)
+ data->early_suspend.level =
+ EARLY_SUSPEND_LEVEL_BLANK_SCREEN + FTS_SUSPEND_LEVEL;
+ data->early_suspend.suspend = fts_ts_early_suspend;
+ data->early_suspend.resume = fts_ts_late_resume;
+ register_early_suspend(&data->early_suspend);
+#endif
+
+ FTS_FUNC_EXIT();
+ return 0;
+
+free_gpio:
+ if (gpio_is_valid(pdata->reset_gpio))
+ gpio_free(pdata->reset_gpio);
+ if (gpio_is_valid(pdata->irq_gpio))
+ gpio_free(pdata->irq_gpio);
+ return err;
+
+}
+
+/*****************************************************************************
+* Name: fts_ts_remove
+* Brief:
+* Input:
+* Output:
+* Return:
+*****************************************************************************/
+static int fts_ts_remove(struct i2c_client *client)
+{
+ struct fts_ts_data *data = i2c_get_clientdata(client);
+
+ FTS_FUNC_ENTER();
+ cancel_work_sync(&data->touch_event_work);
+
+#if FTS_PSENSOR_EN
+ fts_sensor_remove(data);
+#endif
+
+#if FTS_POINT_REPORT_CHECK_EN
+ fts_point_report_check_exit();
+#endif
+
+ fts_ex_mode_exit(client);
+
+#if defined(CONFIG_FB)
+ if (fb_unregister_client(&data->fb_notif))
+ FTS_ERROR("Error occurred while unregistering fb_notifier.");
+#elif defined(CONFIG_HAS_EARLYSUSPEND)
+ unregister_early_suspend(&data->early_suspend);
+#endif
+ free_irq(client->irq, data);
+
+ if (gpio_is_valid(data->pdata->reset_gpio))
+ gpio_free(data->pdata->reset_gpio);
+
+ if (gpio_is_valid(data->pdata->irq_gpio))
+ gpio_free(data->pdata->irq_gpio);
+
+ input_unregister_device(data->input_dev);
+
+#if FTS_TEST_EN
+ fts_test_exit(client);
+#endif
+
+#if FTS_ESDCHECK_EN
+ fts_esdcheck_exit();
+#endif
+
+ FTS_FUNC_EXIT();
+ return 0;
+}
+
+/*****************************************************************************
+* Name: fts_ts_suspend
+* Brief:
+* Input:
+* Output:
+* Return:
+*****************************************************************************/
+static int fts_ts_suspend(struct device *dev)
+{
+ struct fts_ts_data *data = dev_get_drvdata(dev);
+ int retval = 0;
+
+ FTS_FUNC_ENTER();
+ if (data->suspended) {
+ FTS_INFO("Already in suspend state");
+ FTS_FUNC_EXIT();
+ return -1;
+ }
+
+ fts_release_all_finger();
+
+#if FTS_GESTURE_EN
+ retval = fts_gesture_suspend(data->client);
+ if (retval == 0) {
+ /* Enter into gesture mode(suspend) */
+ retval = enable_irq_wake(fts_wq_data->client->irq);
+ if (retval)
+ FTS_ERROR("%s: set_irq_wake failed", __func__);
+ data->suspended = true;
+ FTS_FUNC_EXIT();
+ return 0;
+ }
+#endif
+
+#if FTS_PSENSOR_EN
+ if (fts_sensor_suspend(data) != 0) {
+ enable_irq_wake(data->client->irq);
+ data->suspended = true;
+ return 0;
+ }
+#endif
+
+#if FTS_ESDCHECK_EN
+ fts_esdcheck_suspend();
+#endif
+
+ fts_irq_disable();
+
+ /* TP enter sleep mode */
+ retval =
+ fts_i2c_write_reg(data->client, FTS_REG_POWER_MODE,
+ FTS_REG_POWER_MODE_SLEEP_VALUE);
+ if (retval < 0)
+ FTS_ERROR("Set TP to sleep mode fail, ret=%d!", retval);
+ data->suspended = true;
+
+ FTS_FUNC_EXIT();
+
+ return 0;
+}
+
+/*****************************************************************************
+* Name: fts_ts_resume
+* Brief:
+* Input:
+* Output:
+* Return:
+*****************************************************************************/
+static int fts_ts_resume(struct device *dev)
+{
+ struct fts_ts_data *data = dev_get_drvdata(dev);
+
+ FTS_FUNC_ENTER();
+ if (!data->suspended) {
+ FTS_DEBUG("Already in awake state");
+ FTS_FUNC_EXIT();
+ return -1;
+ }
+
+ if (!fts_chip_idc(data))
+ fts_reset_proc(200);
+
+ fts_tp_state_recovery(data->client);
+
+#if FTS_GESTURE_EN
+ if (fts_gesture_resume(data->client) == 0) {
+ int err;
+
+ err = disable_irq_wake(data->client->irq);
+ if (err)
+ FTS_ERROR("%s: disable_irq_wake failed", __func__);
+ data->suspended = false;
+ FTS_FUNC_EXIT();
+ return 0;
+ }
+#endif
+
+#if FTS_PSENSOR_EN
+ if (fts_sensor_resume(data) != 0) {
+ disable_irq_wake(data->client->irq);
+ data->suspended = false;
+ FTS_FUNC_EXIT();
+ return 0;
+ }
+#endif
+
+ data->suspended = false;
+
+ fts_irq_enable();
+
+#if FTS_ESDCHECK_EN
+ fts_esdcheck_resume();
+#endif
+ FTS_FUNC_EXIT();
+ return 0;
+}
+
+/*****************************************************************************
+* I2C Driver
+*****************************************************************************/
+static const struct i2c_device_id fts_ts_id[] = {
+ {FTS_DRIVER_NAME, 0},
+ {},
+};
+
+MODULE_DEVICE_TABLE(i2c, fts_ts_id);
+
+static struct of_device_id fts_match_table[] = {
+ {.compatible = "focaltech,fts",},
+ {},
+};
+
+static struct i2c_driver fts_ts_driver = {
+ .probe = fts_ts_probe,
+ .remove = fts_ts_remove,
+ .driver = {
+ .name = FTS_DRIVER_NAME,
+ .owner = THIS_MODULE,
+ .of_match_table = fts_match_table,
+ },
+ .id_table = fts_ts_id,
+};
+
+/*****************************************************************************
+* Name: fts_ts_init
+* Brief:
+* Input:
+* Output:
+* Return:
+*****************************************************************************/
+static int __init fts_ts_init(void)
+{
+ int ret = 0;
+
+ FTS_FUNC_ENTER();
+ ret = i2c_add_driver(&fts_ts_driver);
+ if (ret != 0)
+ FTS_ERROR("Focaltech touch screen driver init failed!");
+ FTS_FUNC_EXIT();
+ return ret;
+}
+
+/*****************************************************************************
+* Name: fts_ts_exit
+* Brief:
+* Input:
+* Output:
+* Return:
+*****************************************************************************/
+static void __exit fts_ts_exit(void)
+{
+ i2c_del_driver(&fts_ts_driver);
+}
+
+module_init(fts_ts_init);
+module_exit(fts_ts_exit);
+
+MODULE_AUTHOR("FocalTech Driver Team");
+MODULE_DESCRIPTION("FocalTech Touchscreen Driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/input/touchscreen/focaltech_touch/focaltech_core.h b/drivers/input/touchscreen/focaltech_touch/focaltech_core.h
new file mode 100644
index 000000000000..b8ef41f58420
--- /dev/null
+++ b/drivers/input/touchscreen/focaltech_touch/focaltech_core.h
@@ -0,0 +1,189 @@
+/*
+ *
+ * FocalTech TouchScreen driver.
+ *
+ * Copyright (c) 2010-2016, Focaltech Ltd. All rights reserved.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+/*****************************************************************************
+*
+* File Name: focaltech_core.h
+
+* Author: Focaltech Driver Team
+*
+* Created: 2016-08-08
+*
+* Abstract:
+*
+* Reference:
+*
+*****************************************************************************/
+
+#ifndef __LINUX_FOCALTECH_CORE_H__
+#define __LINUX_FOCALTECH_CORE_H__
+/*****************************************************************************
+* Included header files
+*****************************************************************************/
+#include <linux/i2c.h>
+#include <linux/input.h>
+#include <linux/input/mt.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/gpio.h>
+#include <linux/of_gpio.h>
+#include <linux/regulator/consumer.h>
+#include <linux/firmware.h>
+#include <linux/debugfs.h>
+#include <linux/mutex.h>
+#include <linux/wait.h>
+#include <linux/time.h>
+#include <linux/workqueue.h>
+#include <linux/fs.h>
+#include <linux/proc_fs.h>
+#include <asm/uaccess.h>
+#include <linux/version.h>
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/kthread.h>
+#include <linux/init.h>
+#include <linux/cdev.h>
+#include <linux/device.h>
+#include <linux/mount.h>
+#include <linux/netdevice.h>
+#include <linux/unistd.h>
+#include <linux/ioctl.h>
+#include "focaltech_common.h"
+
+/*****************************************************************************
+* Private constant and macro definitions using #define
+*****************************************************************************/
+#define LEN_FLASH_ECC_MAX 0xFFFE
+
+#define FTS_WORKQUEUE_NAME "fts_wq"
+
+#define FTS_MAX_POINTS 10
+#define FTS_KEY_WIDTH 50
+#define FTS_ONE_TCH_LEN 6
+#define POINT_READ_BUF (3 + FTS_ONE_TCH_LEN * FTS_MAX_POINTS)
+
+#define FTS_MAX_ID 0x0F
+#define FTS_TOUCH_X_H_POS 3
+#define FTS_TOUCH_X_L_POS 4
+#define FTS_TOUCH_Y_H_POS 5
+#define FTS_TOUCH_Y_L_POS 6
+#define FTS_TOUCH_PRE_POS 7
+#define FTS_TOUCH_AREA_POS 8
+#define FTS_TOUCH_POINT_NUM 2
+#define FTS_TOUCH_EVENT_POS 3
+#define FTS_TOUCH_ID_POS 5
+#define FTS_COORDS_ARR_SIZE 4
+
+#define FTS_TOUCH_DOWN 0
+#define FTS_TOUCH_UP 1
+#define FTS_TOUCH_CONTACT 2
+
+#define FTS_SYSFS_ECHO_ON(buf) ((strnicmp(buf, "1", 1) == 0) || \
+ (strnicmp(buf, "on", 2) == 0))
+#define FTS_SYSFS_ECHO_OFF(buf) ((strnicmp(buf, "0", 1) == 0) || \
+ (strnicmp(buf, "off", 3) == 0))
+
+/*****************************************************************************
+* Private enumerations, structures and unions using typedef
+*****************************************************************************/
+
+struct fts_ts_platform_data {
+ u32 fts_chip_type;
+ u32 irq_gpio;
+ u32 irq_gpio_flags;
+ u32 reset_gpio;
+ u32 reset_gpio_flags;
+ bool have_key;
+ u32 key_number;
+ u32 keys[4];
+ u32 key_y_coord;
+ u32 key_x_coords[4];
+ u32 x_max;
+ u32 y_max;
+ u32 x_min;
+ u32 y_min;
+ u32 max_touch_number;
+
+ bool swap;
+ bool scaling_down_half;
+};
+
+struct ts_event {
+ u16 au16_x[FTS_MAX_POINTS]; /*x coordinate */
+ u16 au16_y[FTS_MAX_POINTS]; /*y coordinate */
+ u16 pressure[FTS_MAX_POINTS];
+ /* touch event: 0 -- down; 1-- up; 2 -- contact */
+ u8 au8_touch_event[FTS_MAX_POINTS];
+ u8 au8_finger_id[FTS_MAX_POINTS]; /*touch ID */
+ u8 area[FTS_MAX_POINTS];
+ u8 touch_point;
+ u8 point_num;
+};
+
+struct fts_ts_data {
+ struct i2c_client *client;
+ struct input_dev *input_dev;
+ struct ts_event event;
+ const struct fts_ts_platform_data *pdata;
+#if FTS_PSENSOR_EN
+ struct fts_psensor_platform_data *psensor_pdata;
+#endif
+ struct work_struct touch_event_work;
+ struct workqueue_struct *ts_workqueue;
+ struct regulator *vdd;
+ struct regulator *vcc_i2c;
+ spinlock_t irq_lock;
+ u16 addr;
+ bool suspended;
+ u8 fw_ver[3];
+ u8 fw_vendor_id;
+ int touchs;
+ int irq_disable;
+
+#if defined(CONFIG_FB)
+ struct notifier_block fb_notif;
+#elif defined(CONFIG_HAS_EARLYSUSPEND)
+ struct early_suspend early_suspend;
+#endif
+};
+
+#if FTS_PSENSOR_EN
+struct fts_psensor_platform_data {
+ struct input_dev *input_psensor_dev;
+ struct sensors_classdev ps_cdev;
+ int tp_psensor_opened;
+ char tp_psensor_data; /* 0 near, 1 far */
+ struct fts_ts_data *data;
+};
+
+int fts_sensor_init(struct fts_ts_data *data);
+int fts_sensor_read_data(struct fts_ts_data *data);
+int fts_sensor_suspend(struct fts_ts_data *data);
+int fts_sensor_resume(struct fts_ts_data *data);
+int fts_sensor_remove(struct fts_ts_data *data);
+#endif
+
+/*****************************************************************************
+* Static variables
+*****************************************************************************/
+extern struct i2c_client *fts_i2c_client;
+extern struct fts_ts_data *fts_wq_data;
+extern struct input_dev *fts_input_dev;
+
+#endif /* __LINUX_FOCALTECH_CORE_H__ */
diff --git a/drivers/input/touchscreen/focaltech_touch/focaltech_esdcheck.c b/drivers/input/touchscreen/focaltech_touch/focaltech_esdcheck.c
new file mode 100644
index 000000000000..565507d02523
--- /dev/null
+++ b/drivers/input/touchscreen/focaltech_touch/focaltech_esdcheck.c
@@ -0,0 +1,473 @@
+/*
+ *
+ * FocalTech TouchScreen driver.
+ *
+ * Copyright (c) 2010-2016, FocalTech Systems, Ltd., all rights reserved.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+/*****************************************************************************
+*
+* File Name: focaltech_esdcheck.c
+*
+* Author: luoguojin
+*
+* Created: 2016-08-03
+*
+* Abstract: ESD check function
+*
+* Version: v1.0
+*
+* Revision History:
+* v1.0:
+* First release. By luougojin 2016-08-03
+*****************************************************************************/
+
+/*****************************************************************************
+* Included header files
+*****************************************************************************/
+#include "focaltech_core.h"
+
+#if FTS_ESDCHECK_EN
+/*****************************************************************************
+* Private constant and macro definitions using #define
+*****************************************************************************/
+#define ESDCHECK_WAIT_TIME 1000
+
+/*****************************************************************************
+* Private enumerations, structures and unions using typedef
+*****************************************************************************/
+struct fts_esdcheck_st {
+ u8 active:1;
+ u8 suspend:1;
+ u8 proc_debug:1; /* apk or adb is accessing I2C */
+ u8 intr:1; /* 1- Interrupt trigger */
+ u8 unused:4;
+ u8 flow_work_hold_cnt;
+ u8 flow_work_cnt_last;
+ u32 hardware_reset_cnt;
+ u32 i2c_nack_cnt;
+ u32 i2c_dataerror_cnt;
+};
+
+/*****************************************************************************
+* Static variables
+*****************************************************************************/
+static struct delayed_work fts_esdcheck_work;
+static struct workqueue_struct *fts_esdcheck_workqueue;
+static struct fts_esdcheck_st fts_esdcheck_data;
+
+/*****************************************************************************
+* Global variable or extern global variabls/functions
+*****************************************************************************/
+
+/*****************************************************************************
+* Static function prototypes
+*****************************************************************************/
+
+/*****************************************************************************
+* functions body
+*****************************************************************************/
+/*****************************************************************************
+* Name: lcd_esdcheck
+* Brief:
+* Input:
+* Output:
+* Return:
+*****************************************************************************/
+int lcd_need_reset;
+static int tp_need_recovery; /* LCD reset cause Tp reset */
+int idc_esdcheck_lcderror(void)
+{
+ u8 val;
+ int ret;
+
+ FTS_DEBUG("[ESD]Check LCD ESD");
+ if ((tp_need_recovery == 1) && (lcd_need_reset == 0)) {
+ tp_need_recovery = 0;
+ /* LCD reset, need recover TP state */
+ fts_tp_state_recovery(fts_i2c_client);
+ }
+
+ ret = fts_i2c_read_reg(fts_i2c_client, FTS_REG_ESD_SATURATE, &val);
+ if (ret < 0) {
+ FTS_ERROR("[ESD]: Read ESD_SATURATE(0xED) failed ret=%d!", ret);
+ return -EIO;
+ }
+
+ if (val == 0xAA) {
+ /*
+ * 1. Set flag lcd_need_reset = 1;
+ * 2. LCD driver need reset(recovery) LCD and
+ * set lcd_need_reset to 0
+ * 3. recover TP state
+ */
+ FTS_INFO("LCD ESD, Execute LCD reset!");
+ lcd_need_reset = 1;
+ tp_need_recovery = 1;
+ }
+
+ return 0;
+}
+
+/*****************************************************************************
+* Name: fts_esdcheck_tp_reset
+* Brief: esd check algorithm
+* Input:
+* Output:
+* Return:
+*****************************************************************************/
+static int fts_esdcheck_tp_reset(void)
+{
+ FTS_FUNC_ENTER();
+
+ fts_esdcheck_data.flow_work_hold_cnt = 0;
+ fts_esdcheck_data.hardware_reset_cnt++;
+
+ fts_reset_proc(200);
+ fts_tp_state_recovery(fts_i2c_client);
+
+ FTS_FUNC_EXIT();
+ return 0;
+}
+
+/*****************************************************************************
+* Name: get_chip_id
+* Brief: Read Chip Id 3 times
+* Input:
+* Output:
+* Return: 1 - Read Chip Id 3 times failed
+* 0 - Read Chip Id pass
+*****************************************************************************/
+static bool get_chip_id(void)
+{
+ int err = 0;
+ int i = 0;
+ u8 reg_value = 0;
+ u8 reg_addr = 0;
+
+ for (i = 0; i < 3; i++) {
+ reg_addr = FTS_REG_CHIP_ID;
+ err = fts_i2c_read(fts_i2c_client, &reg_addr, 1, &reg_value, 1);
+
+ if (err < 0) {
+ FTS_ERROR("[ESD]: Read Reg 0xA3 failed ret = %d!!",
+ err);
+ fts_esdcheck_data.i2c_nack_cnt++;
+ } else {
+ /* Upgrade sometimes can't detect */
+ if ((reg_value == chip_types.chip_idh)
+ || (reg_value == 0xEF))
+ break;
+ else
+ fts_esdcheck_data.i2c_dataerror_cnt++;
+ }
+ }
+
+ /* if can't get correct data in 3 times, then need hardware reset */
+ if (i >= 3) {
+ FTS_ERROR
+ ("[ESD]: Read Chip id 3 times failed,"
+ "need execute TP reset!!");
+ return 1;
+ }
+
+ return 0;
+}
+
+/*****************************************************************************
+* Name: get_flow_cnt
+* Brief: Read flow cnt(0x91)
+* Input:
+* Output:
+* Return: 1 - Reg 0x91(flow cnt) abnormal: hold a value for 5 times
+* 0 - Reg 0x91(flow cnt) normal
+*****************************************************************************/
+static bool get_flow_cnt(void)
+{
+ int err = 0;
+ u8 reg_value = 0;
+ u8 reg_addr = 0;
+
+ reg_addr = FTS_REG_FLOW_WORK_CNT;
+ err = fts_i2c_read(fts_i2c_client, &reg_addr, 1, &reg_value, 1);
+ if (err < 0) {
+ FTS_ERROR("[ESD]: Read Reg 0x91 failed ret = %d!!", err);
+ fts_esdcheck_data.i2c_nack_cnt++;
+ } else {
+ if (reg_value == fts_esdcheck_data.flow_work_cnt_last)
+ fts_esdcheck_data.flow_work_hold_cnt++;
+ else
+ fts_esdcheck_data.flow_work_hold_cnt = 0;
+
+ fts_esdcheck_data.flow_work_cnt_last = reg_value;
+ }
+
+ /*
+ * if read flow work cnt 5 times and the value are
+ * all the same, then need hardware_reset
+ */
+ if (fts_esdcheck_data.flow_work_hold_cnt >= 5) {
+ FTS_DEBUG("[ESD]: Flow Work Cnt(reg0x91) keep a value"
+ "for 5 times, need execute TP reset!!");
+ return 1;
+ }
+
+ return 0;
+}
+
+/*****************************************************************************
+* Name: esdcheck_algorithm
+* Brief: esd check algorithm
+* Input:
+* Output:
+* Return:
+*****************************************************************************/
+static int esdcheck_algorithm(void)
+{
+ int err = 0;
+ u8 reg_value = 0;
+ u8 reg_addr = 0;
+ bool hardware_reset = 0;
+
+ /* 1. esdcheck is interrupt, then return */
+ if (fts_esdcheck_data.intr == 1) {
+ FTS_INFO("[ESD]: In interrupt state,"
+ "not check esd, return immediately!!");
+ return 0;
+ }
+
+ /* 2. check power state, if suspend, no need check esd */
+ if (fts_esdcheck_data.suspend == 1) {
+ FTS_INFO("[ESD]: In suspend, not check esd,"
+ "return immediately!!");
+ /* because in suspend state, adb can be used,
+ * when upgrade FW, will active ESD check(active = 1)
+ * But in suspend, then will don't queue_delayed_work,
+ * when resume, don't check ESD again
+ */
+ fts_esdcheck_data.active = 0;
+ return 0;
+ }
+
+ /*
+ * 3. check fts_esdcheck_data.proc_debug state,
+ * if 1-proc busy, no need check esd
+ */
+ if (fts_esdcheck_data.proc_debug == 1) {
+ FTS_INFO("[ESD]: In apk or adb command mode,"
+ "not check esd, return immediately!!");
+ return 0;
+ }
+
+ /* 4. In factory mode, can't check esd */
+ reg_addr = FTS_REG_WORKMODE;
+ err = fts_i2c_read(fts_i2c_client, &reg_addr, 1, &reg_value, 1);
+ if (err < 0) {
+ fts_esdcheck_data.i2c_nack_cnt++;
+ } else if ((reg_value & 0x70) == FTS_REG_WORKMODE_FACTORY_VALUE) {
+ FTS_INFO("[ESD]: In factory mode,"
+ "not check esd, return immediately!!");
+ return 0;
+ }
+
+ /* 5. Get Chip ID */
+ hardware_reset = get_chip_id();
+
+ /*
+ * 6. get Flow work cnt: 0x91 If no change for 5 times,
+ * then ESD and reset
+ */
+ if (!hardware_reset)
+ hardware_reset = get_flow_cnt();
+
+ /* 7. If need hardware reset, then handle it here */
+ if (hardware_reset == 1)
+ fts_esdcheck_tp_reset();
+
+ FTS_INFO("[ESD]: NoACK=%d, Error Data=%d, Hardware Reset=%d\n",
+ fts_esdcheck_data.i2c_nack_cnt,
+ fts_esdcheck_data.i2c_dataerror_cnt,
+ fts_esdcheck_data.hardware_reset_cnt);
+ return 0;
+}
+
+/*****************************************************************************
+* Name: fts_esdcheck_func
+* Brief: fts_esdcheck_func
+* Input:
+* Output:
+* Return:
+*****************************************************************************/
+static void esdcheck_func(struct work_struct *work)
+{
+ FTS_FUNC_ENTER();
+
+ idc_esdcheck_lcderror();
+
+ esdcheck_algorithm();
+
+ if (fts_esdcheck_data.suspend == 0) {
+ queue_delayed_work(fts_esdcheck_workqueue, &fts_esdcheck_work,
+ msecs_to_jiffies(ESDCHECK_WAIT_TIME));
+ }
+
+ FTS_FUNC_EXIT();
+}
+
+/*****************************************************************************
+* Name: fts_esdcheck_set_intr
+* Brief: interrupt flag (main used in interrupt tp report)
+* Input:
+* Output:
+* Return:
+*****************************************************************************/
+int fts_esdcheck_set_intr(bool intr)
+{
+ /* interrupt don't add debug message */
+ fts_esdcheck_data.intr = intr;
+ return 0;
+}
+
+/*****************************************************************************
+* Name: fts_esdcheck_get_status(void)
+* Brief: get current status
+* Input:
+* Output:
+* Return:
+*****************************************************************************/
+int fts_esdcheck_get_status(void)
+{
+ /* interrupt don't add debug message */
+ return fts_esdcheck_data.active;
+}
+
+/*****************************************************************************
+* Name: fts_esdcheck_proc_busy
+* Brief: When APK or ADB command access TP via driver,
+* then need set proc_debug,
+* then will not check ESD.
+* Input:
+* Output:
+* Return:
+*****************************************************************************/
+int fts_esdcheck_proc_busy(bool proc_debug)
+{
+ fts_esdcheck_data.proc_debug = proc_debug;
+ return 0;
+}
+
+/*****************************************************************************
+* Name: fts_esdcheck_switch
+* Brief: FTS esd check function switch.
+* Input: enable: 1 - Enable esd check
+* 0 - Disable esd check
+* Output:
+* Return:
+*****************************************************************************/
+int fts_esdcheck_switch(bool enable)
+{
+ FTS_FUNC_ENTER();
+ if (enable == 1) {
+ if (fts_esdcheck_data.active == 0) {
+ FTS_INFO("[ESD]: ESD check start!!");
+ fts_esdcheck_data.active = 1;
+ queue_delayed_work(fts_esdcheck_workqueue,
+ &fts_esdcheck_work,
+ msecs_to_jiffies
+ (ESDCHECK_WAIT_TIME));
+ }
+ } else {
+ if (fts_esdcheck_data.active == 1) {
+ FTS_INFO("[ESD]: ESD check stop!!");
+ fts_esdcheck_data.active = 0;
+ cancel_delayed_work_sync(&fts_esdcheck_work);
+ }
+ }
+
+ FTS_FUNC_EXIT();
+ return 0;
+}
+
+/*****************************************************************************
+* Name: fts_esdcheck_suspend
+* Brief: Run when tp enter into suspend
+* Input:
+* Output:
+* Return:
+*****************************************************************************/
+int fts_esdcheck_suspend(void)
+{
+ FTS_FUNC_ENTER();
+ fts_esdcheck_switch(DISABLE);
+ fts_esdcheck_data.suspend = 1;
+ FTS_FUNC_EXIT();
+ return 0;
+}
+
+/*****************************************************************************
+* Name: fts_esdcheck_resume
+* Brief: Run when tp resume
+* Input:
+* Output:
+* Return:
+*****************************************************************************/
+int fts_esdcheck_resume(void)
+{
+ FTS_FUNC_ENTER();
+ fts_esdcheck_switch(ENABLE);
+ fts_esdcheck_data.suspend = 0;
+ FTS_FUNC_EXIT();
+ return 0;
+}
+
+/*****************************************************************************
+* Name: fts_esdcheck_init
+* Brief: Init and create a queue work to check esd
+* Input:
+* Output:
+* Return: < 0: Fail to create esd check queue
+*****************************************************************************/
+int fts_esdcheck_init(void)
+{
+ FTS_FUNC_ENTER();
+
+ INIT_DELAYED_WORK(&fts_esdcheck_work, esdcheck_func);
+ fts_esdcheck_workqueue = create_workqueue("fts_esdcheck_wq");
+ if (fts_esdcheck_workqueue == NULL)
+ FTS_INFO("[ESD]: Failed to create esd work queue!!");
+
+ memset((u8 *) &fts_esdcheck_data, 0, sizeof(struct fts_esdcheck_st));
+
+ fts_esdcheck_switch(ENABLE);
+ FTS_FUNC_EXIT();
+ return 0;
+}
+
+/*****************************************************************************
+* Name: fts_esdcheck_exit
+* Brief: When FTS TP driver is removed,
+* then call this function to destroy work queue
+* Input:
+* Output:
+* Return:
+*****************************************************************************/
+int fts_esdcheck_exit(void)
+{
+ FTS_FUNC_ENTER();
+
+ destroy_workqueue(fts_esdcheck_workqueue);
+
+ FTS_FUNC_EXIT();
+ return 0;
+}
+#endif /* FTS_ESDCHECK_EN */
diff --git a/drivers/input/touchscreen/focaltech_touch/focaltech_ex_mode.c b/drivers/input/touchscreen/focaltech_touch/focaltech_ex_mode.c
new file mode 100644
index 000000000000..6ab5d47170cc
--- /dev/null
+++ b/drivers/input/touchscreen/focaltech_touch/focaltech_ex_mode.c
@@ -0,0 +1,357 @@
+/*
+ *
+ * FocalTech ftxxxx TouchScreen driver.
+ *
+ * Copyright (c) 2010-2016, Focaltech Ltd. All rights reserved.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+/*****************************************************************************
+*
+* File Name: focaltech_ex_mode.c
+*
+* Author: Liu WeiGuang
+*
+* Created: 2016-08-31
+*
+* Abstract:
+*
+* Reference:
+*
+*****************************************************************************/
+
+/*****************************************************************************
+* 1.Included header files
+*****************************************************************************/
+#include "focaltech_core.h"
+
+/*****************************************************************************
+* 2.Private constant and macro definitions using #define
+*****************************************************************************/
+
+/*****************************************************************************
+* 3.Private enumerations, structures and unions using typedef
+*****************************************************************************/
+struct fts_mode_flag {
+ int fts_glove_mode_flag;
+ int fts_cover_mode_flag;
+ int fts_charger_mode_flag;
+};
+
+struct fts_mode_flag g_fts_mode_flag;
+
+/*****************************************************************************
+* 4.Static variables
+*****************************************************************************/
+
+/*****************************************************************************
+* 5.Global variable or extern global variabls/functions
+*****************************************************************************/
+int fts_enter_glove_mode(struct i2c_client *client, int mode);
+int fts_glove_init(struct i2c_client *client);
+int fts_glove_exit(struct i2c_client *client);
+
+int fts_enter_cover_mode(struct i2c_client *client, int mode);
+int fts_cover_init(struct i2c_client *client);
+int fts_cover_exit(struct i2c_client *client);
+
+int fts_enter_charger_mode(struct i2c_client *client, int mode);
+int fts_charger_init(struct i2c_client *client);
+int fts_charger_exit(struct i2c_client *client);
+
+/*****************************************************************************
+* 6.Static function prototypes
+*******************************************************************************/
+
+#if FTS_GLOVE_EN
+static ssize_t fts_touch_glove_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ return snprintf(buf, PAGE_SIZE, "Glove: %s\n",
+ g_fts_mode_flag.fts_glove_mode_flag ? "On" : "Off");
+}
+
+static ssize_t fts_touch_glove_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int ret;
+
+ if (FTS_SYSFS_ECHO_ON(buf)) {
+ if (!g_fts_mode_flag.fts_glove_mode_flag) {
+ FTS_INFO("[Mode]enter glove mode");
+ ret = fts_enter_glove_mode(fts_i2c_client, true);
+ if (ret >= 0)
+ g_fts_mode_flag.fts_glove_mode_flag = true;
+ }
+ } else if (FTS_SYSFS_ECHO_OFF(buf)) {
+ if (g_fts_mode_flag.fts_glove_mode_flag) {
+ FTS_INFO("[Mode]exit glove mode");
+ ret = fts_enter_glove_mode(fts_i2c_client, false);
+ if (ret >= 0)
+ g_fts_mode_flag.fts_glove_mode_flag = false;
+ }
+ }
+ FTS_INFO("[Mode]glove mode status: %d",
+ g_fts_mode_flag.fts_glove_mode_flag);
+ return count;
+}
+
+/************************************************************************
+* Name: fts_enter_glove_mode
+* Brief: change glove mode
+* Input: glove mode
+* Output: no
+* Return: success >=0, otherwise failed
+***********************************************************************/
+int fts_enter_glove_mode(struct i2c_client *client, int mode)
+{
+ int ret = 0;
+ static u8 buf_addr[2] = { 0 };
+ static u8 buf_value[2] = { 0 };
+
+ buf_addr[0] = FTS_REG_GLOVE_MODE_EN;
+
+ if (mode)
+ buf_value[0] = 0x01;
+ else
+ buf_value[0] = 0x00;
+
+ ret = fts_i2c_write_reg(client, buf_addr[0], buf_value[0]);
+ if (ret < 0)
+ FTS_ERROR("[Mode]fts_enter_glove_mode write value fail");
+
+ return ret;
+
+}
+
+/* read and write glove mode
+* read example: cat fts_touch_glove_mode---read glove mode
+* write example:echo 01 > fts_touch_glove_mode ---write glove mode to 01
+*
+*/
+static DEVICE_ATTR(fts_glove_mode, S_IRUGO | S_IWUSR, fts_touch_glove_show,
+ fts_touch_glove_store);
+
+#endif
+
+#if FTS_COVER_EN
+static ssize_t fts_touch_cover_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ return snprintf(buf, PAGE_SIZE, "Cover: %s\n",
+ g_fts_mode_flag.fts_cover_mode_flag ? "On" : "Off");
+}
+
+static ssize_t fts_touch_cover_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int ret;
+
+ if (FTS_SYSFS_ECHO_ON(buf)) {
+ if (!g_fts_mode_flag.fts_cover_mode_flag) {
+ FTS_INFO("[Mode]enter cover mode");
+ ret = fts_enter_cover_mode(fts_i2c_client, true);
+ if (ret >= 0)
+ g_fts_mode_flag.fts_cover_mode_flag = true;
+ }
+ } else if (FTS_SYSFS_ECHO_OFF(buf)) {
+ if (g_fts_mode_flag.fts_cover_mode_flag) {
+ FTS_INFO("[Mode]exit cover mode");
+ ret = fts_enter_cover_mode(fts_i2c_client, false);
+ if (ret >= 0)
+ g_fts_mode_flag.fts_cover_mode_flag = false;
+ }
+ }
+ FTS_INFO("[Mode]cover mode status: %d",
+ g_fts_mode_flag.fts_cover_mode_flag);
+ return count;
+}
+
+/************************************************************************
+* Name: fts_enter_cover_mode
+* Brief: change cover mode
+* Input: cover mode
+* Output: no
+* Return: success >=0, otherwise failed
+***********************************************************************/
+int fts_enter_cover_mode(struct i2c_client *client, int mode)
+{
+ int ret = 0;
+ static u8 buf_addr[2] = { 0 };
+ static u8 buf_value[2] = { 0 };
+
+ buf_addr[0] = FTS_REG_COVER_MODE_EN;
+
+ if (mode)
+ buf_value[0] = 0x01;
+ else
+ buf_value[0] = 0x00;
+
+ ret = fts_i2c_write_reg(client, buf_addr[0], buf_value[0]);
+ if (ret < 0)
+ FTS_ERROR("[Mode] fts_enter_cover_mode write value fail\n");
+
+ return ret;
+
+}
+
+/* read and write cover mode
+* read example: cat fts_touch_cover_mode---read cover mode
+* write example:echo 01 > fts_touch_cover_mode ---write cover mode to 01
+*
+*/
+static DEVICE_ATTR(fts_cover_mode, S_IRUGO | S_IWUSR, fts_touch_cover_show,
+ fts_touch_cover_store);
+
+#endif
+
+#if FTS_CHARGER_EN
+static ssize_t fts_touch_charger_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ return snprintf(buf, PAGE_SIZE, "Charger: %s\n",
+ g_fts_mode_flag.fts_charger_mode_flag ? "On" : "Off");
+}
+
+static ssize_t fts_touch_charger_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int ret;
+
+ if (FTS_SYSFS_ECHO_ON(buf)) {
+ if (!g_fts_mode_flag.fts_charger_mode_flag) {
+ FTS_INFO("[Mode]enter charger mode");
+ ret = fts_enter_charger_mode(fts_i2c_client, true);
+ if (ret >= 0)
+ g_fts_mode_flag.fts_charger_mode_flag = true;
+ }
+ } else if (FTS_SYSFS_ECHO_OFF(buf)) {
+ if (g_fts_mode_flag.fts_charger_mode_flag) {
+ FTS_INFO("[Mode]exit charger mode");
+ ret = fts_enter_charger_mode(fts_i2c_client, false);
+ if (ret >= 0)
+ g_fts_mode_flag.fts_charger_mode_flag = false;
+ }
+ }
+ FTS_INFO("[Mode]charger mode status: %d",
+ g_fts_mode_flag.fts_charger_mode_flag);
+ return count;
+}
+
+/************************************************************************
+* Name: fts_enter_charger_mode
+* Brief: change charger mode
+* Input: charger mode
+* Output: no
+* Return: success >=0, otherwise failed
+***********************************************************************/
+int fts_enter_charger_mode(struct i2c_client *client, int mode)
+{
+ int ret = 0;
+ static u8 buf_addr[2] = { 0 };
+ static u8 buf_value[2] = { 0 };
+
+ buf_addr[0] = FTS_REG_CHARGER_MODE_EN;
+
+ if (mode)
+ buf_value[0] = 0x01;
+ else
+ buf_value[0] = 0x00;
+
+ ret = fts_i2c_write_reg(client, buf_addr[0], buf_value[0]);
+ if (ret < 0)
+ FTS_DEBUG("[Mode]fts_enter_charger_mode write value fail");
+
+ return ret;
+
+}
+
+/* read and write charger mode
+* read example: cat fts_touch_charger_mode---read charger mode
+* write example:echo 01 > fts_touch_charger_mode ---write charger mode to 01
+*
+*/
+static DEVICE_ATTR(fts_charger_mode, S_IRUGO | S_IWUSR, fts_touch_charger_show,
+ fts_touch_charger_store);
+
+#endif
+
+static struct attribute *fts_touch_mode_attrs[] = {
+#if FTS_GLOVE_EN
+ &dev_attr_fts_glove_mode.attr,
+#endif
+
+#if FTS_COVER_EN
+ &dev_attr_fts_cover_mode.attr,
+#endif
+
+#if FTS_CHARGER_EN
+ &dev_attr_fts_charger_mode.attr,
+#endif
+
+ NULL,
+};
+
+static struct attribute_group fts_touch_mode_group = {
+ .attrs = fts_touch_mode_attrs,
+};
+
+int fts_ex_mode_init(struct i2c_client *client)
+{
+ int err = 0;
+
+ g_fts_mode_flag.fts_glove_mode_flag = false;
+ g_fts_mode_flag.fts_cover_mode_flag = false;
+ g_fts_mode_flag.fts_charger_mode_flag = false;
+
+ err = sysfs_create_group(&client->dev.kobj, &fts_touch_mode_group);
+ if (0 != err) {
+ FTS_ERROR("[Mode]create sysfs failed.");
+ sysfs_remove_group(&client->dev.kobj, &fts_touch_mode_group);
+ return -EIO;
+ }
+
+ FTS_DEBUG("[Mode]create sysfs succeeded");
+
+ return err;
+
+}
+
+int fts_ex_mode_exit(struct i2c_client *client)
+{
+ sysfs_remove_group(&client->dev.kobj, &fts_touch_mode_group);
+ return 0;
+}
+
+int fts_ex_mode_recovery(struct i2c_client *client)
+{
+ int ret = 0;
+#if FTS_GLOVE_EN
+ if (g_fts_mode_flag.fts_glove_mode_flag)
+ ret = fts_enter_glove_mode(client, true);
+#endif
+
+#if FTS_COVER_EN
+ if (g_fts_mode_flag.fts_cover_mode_flag)
+ ret = fts_enter_cover_mode(client, true);
+#endif
+
+#if FTS_CHARGER_EN
+ if (g_fts_mode_flag.fts_charger_mode_flag)
+ ret = fts_enter_charger_mode(client, true);
+#endif
+
+ return ret;
+}
diff --git a/drivers/input/touchscreen/focaltech_touch/focaltech_gesture.c b/drivers/input/touchscreen/focaltech_touch/focaltech_gesture.c
new file mode 100644
index 000000000000..9faabb8681bb
--- /dev/null
+++ b/drivers/input/touchscreen/focaltech_touch/focaltech_gesture.c
@@ -0,0 +1,652 @@
+/*
+ *
+ * FocalTech TouchScreen driver.
+ *
+ * Copyright (c) 2010-2016, Focaltech Ltd. All rights reserved.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+/*****************************************************************************
+*
+* File Name: focaltech_gestrue.c
+*
+* Author: Focaltech Driver Team
+*
+* Created: 2016-08-08
+*
+* Abstract:
+*
+* Reference:
+*
+*****************************************************************************/
+
+/*****************************************************************************
+* 1.Included header files
+*****************************************************************************/
+#include "focaltech_core.h"
+#if FTS_GESTURE_EN
+/******************************************************************************
+* Private constant and macro definitions using #define
+*****************************************************************************/
+#define KEY_GESTURE_U KEY_U
+#define KEY_GESTURE_UP KEY_UP
+#define KEY_GESTURE_DOWN KEY_DOWN
+#define KEY_GESTURE_LEFT KEY_LEFT
+#define KEY_GESTURE_RIGHT KEY_RIGHT
+#define KEY_GESTURE_O KEY_O
+#define KEY_GESTURE_E KEY_E
+#define KEY_GESTURE_M KEY_M
+#define KEY_GESTURE_L KEY_L
+#define KEY_GESTURE_W KEY_W
+#define KEY_GESTURE_S KEY_S
+#define KEY_GESTURE_V KEY_V
+#define KEY_GESTURE_C KEY_C
+#define KEY_GESTURE_Z KEY_Z
+
+#define GESTURE_LEFT 0x20
+#define GESTURE_RIGHT 0x21
+#define GESTURE_UP 0x22
+#define GESTURE_DOWN 0x23
+#define GESTURE_DOUBLECLICK 0x24
+#define GESTURE_O 0x30
+#define GESTURE_W 0x31
+#define GESTURE_M 0x32
+#define GESTURE_E 0x33
+#define GESTURE_L 0x44
+#define GESTURE_S 0x46
+#define GESTURE_V 0x54
+#define GESTURE_Z 0x41
+#define GESTURE_C 0x34
+#define FTS_GESTRUE_POINTS 255
+#define FTS_GESTRUE_POINTS_HEADER 8
+#define FTS_GESTURE_OUTPUT_ADRESS 0xD3
+/*****************************************************************************
+* Private enumerations, structures and unions using typedef
+*****************************************************************************/
+struct fts_gesture_st {
+ u8 header[FTS_GESTRUE_POINTS_HEADER];
+ u16 coordinate_x[FTS_GESTRUE_POINTS];
+ u16 coordinate_y[FTS_GESTRUE_POINTS];
+ u8 mode;
+ u8 active;
+};
+
+/*****************************************************************************
+* Static variables
+*****************************************************************************/
+static struct fts_gesture_st fts_gesture_data;
+extern struct fts_ts_data *fts_wq_data;
+
+/*****************************************************************************
+* Global variable or extern global variabls/functions
+*****************************************************************************/
+
+/*****************************************************************************
+* Static function prototypes
+*****************************************************************************/
+static ssize_t fts_gesture_show(struct device *dev,
+ struct device_attribute *attr, char *buf);
+static ssize_t fts_gesture_store(struct device *dev,
+ struct device_attribute *attr, const char *buf,
+ size_t count);
+static ssize_t fts_gesture_buf_show(struct device *dev,
+ struct device_attribute *attr, char *buf);
+static ssize_t fts_gesture_buf_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count);
+
+/* sysfs gesture node
+ * read example: cat fts_gesture_mode ---read gesture mode
+ * write example:echo 01 > fts_gesture_mode ---write gesture mode to 01
+ *
+ */
+static DEVICE_ATTR(fts_gesture_mode, S_IRUGO | S_IWUSR, fts_gesture_show,
+ fts_gesture_store);
+/*
+ * read example: cat fts_gesture_buf ---read gesture buf
+ */
+static DEVICE_ATTR(fts_gesture_buf, S_IRUGO | S_IWUSR, fts_gesture_buf_show,
+ fts_gesture_buf_store);
+static struct attribute *fts_gesture_mode_attrs[] = {
+
+ &dev_attr_fts_gesture_mode.attr,
+ &dev_attr_fts_gesture_buf.attr,
+ NULL,
+};
+
+static struct attribute_group fts_gesture_group = {
+ .attrs = fts_gesture_mode_attrs,
+};
+
+/************************************************************************
+* Name: fts_gesture_show
+* Brief: no
+* Input: device, device attribute, char buf
+* Output: no
+* Return:
+***********************************************************************/
+static ssize_t fts_gesture_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int count;
+ u8 val;
+ struct i2c_client *client = container_of(dev, struct i2c_client, dev);
+
+ mutex_lock(&fts_input_dev->mutex);
+ fts_i2c_read_reg(client, FTS_REG_GESTURE_EN, &val);
+ count =
+ sprintf(buf, "Gesture Mode: %s\n",
+ fts_gesture_data.mode ? "On" : "Off");
+ count += sprintf(buf + count, "Reg(0xD0) = %d\n", val);
+ mutex_unlock(&fts_input_dev->mutex);
+
+ return count;
+}
+
+/************************************************************************
+* Name: fts_gesture_store
+* Brief: no
+* Input: device, device attribute, char buf, char count
+* Output: no
+* Return:
+***********************************************************************/
+static ssize_t fts_gesture_store(struct device *dev,
+ struct device_attribute *attr, const char *buf,
+ size_t count)
+{
+ mutex_lock(&fts_input_dev->mutex);
+
+ if (FTS_SYSFS_ECHO_ON(buf)) {
+ FTS_INFO("[GESTURE]enable gesture");
+ fts_gesture_data.mode = ENABLE;
+ } else if (FTS_SYSFS_ECHO_OFF(buf)) {
+ FTS_INFO("[GESTURE]disable gesture");
+ fts_gesture_data.mode = DISABLE;
+ }
+
+ mutex_unlock(&fts_input_dev->mutex);
+
+ return count;
+}
+
+/************************************************************************
+* Name: fts_gesture_buf_show
+* Brief: no
+* Input: device, device attribute, char buf
+* Output: no
+* Return:
+***********************************************************************/
+static ssize_t fts_gesture_buf_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int count;
+ int i = 0;
+
+ mutex_lock(&fts_input_dev->mutex);
+ count =
+ snprintf(buf, PAGE_SIZE, "Gesture ID: 0x%x\n",
+ fts_gesture_data.header[0]);
+ count +=
+ snprintf(buf + count, PAGE_SIZE, "Gesture PointNum: %d\n",
+ fts_gesture_data.header[1]);
+ count += snprintf(buf + count, PAGE_SIZE, "Gesture Point Buf:\n");
+ for (i = 0; i < fts_gesture_data.header[1]; i++) {
+ count +=
+ snprintf(buf + count, PAGE_SIZE, "%3d(%4d,%4d) ", i,
+ fts_gesture_data.coordinate_x[i],
+ fts_gesture_data.coordinate_y[i]);
+ if ((i + 1) % 4 == 0)
+ count += snprintf(buf + count, PAGE_SIZE, "\n");
+ }
+ count += snprintf(buf + count, PAGE_SIZE, "\n");
+ mutex_unlock(&fts_input_dev->mutex);
+
+ return count;
+}
+
+/************************************************************************
+* Name: fts_gesture_buf_store
+* Brief: no
+* Input: device, device attribute, char buf, char count
+* Output: no
+* Return:
+***********************************************************************/
+static ssize_t fts_gesture_buf_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ /* place holder for future use */
+ return -EPERM;
+}
+
+/*****************************************************************************
+* Name: fts_create_gesture_sysfs
+* Brief:
+* Input:
+* Output: None
+* Return: 0-success or error
+*****************************************************************************/
+int fts_create_gesture_sysfs(struct i2c_client *client)
+{
+ int ret = 0;
+
+ ret = sysfs_create_group(&client->dev.kobj, &fts_gesture_group);
+ if (ret != 0) {
+ FTS_ERROR
+ ("[GESTURE]fts_gesture_mode_group(sysfs) create failed!");
+ sysfs_remove_group(&client->dev.kobj, &fts_gesture_group);
+ return ret;
+ }
+ return 0;
+}
+
+/*****************************************************************************
+* Name: fts_gesture_recovery
+* Brief: recovery gesture state when reset
+* Input:
+* Output: None
+* Return:
+*****************************************************************************/
+void fts_gesture_recovery(struct i2c_client *client)
+{
+ if (fts_gesture_data.mode && fts_gesture_data.active) {
+ fts_i2c_write_reg(client, 0xD1, 0xff);
+ fts_i2c_write_reg(client, 0xD2, 0xff);
+ fts_i2c_write_reg(client, 0xD5, 0xff);
+ fts_i2c_write_reg(client, 0xD6, 0xff);
+ fts_i2c_write_reg(client, 0xD7, 0xff);
+ fts_i2c_write_reg(client, 0xD8, 0xff);
+ fts_i2c_write_reg(client, FTS_REG_GESTURE_EN, ENABLE);
+ }
+}
+
+/*****************************************************************************
+* Name: fts_gesture_init
+* Brief:
+* Input:
+* Output: None
+* Return: None
+*****************************************************************************/
+int fts_gesture_init(struct input_dev *input_dev, struct i2c_client *client)
+{
+ FTS_FUNC_ENTER();
+ input_set_capability(input_dev, EV_KEY, KEY_POWER);
+ input_set_capability(input_dev, EV_KEY, KEY_GESTURE_U);
+ input_set_capability(input_dev, EV_KEY, KEY_GESTURE_UP);
+ input_set_capability(input_dev, EV_KEY, KEY_GESTURE_DOWN);
+ input_set_capability(input_dev, EV_KEY, KEY_GESTURE_LEFT);
+ input_set_capability(input_dev, EV_KEY, KEY_GESTURE_RIGHT);
+ input_set_capability(input_dev, EV_KEY, KEY_GESTURE_O);
+ input_set_capability(input_dev, EV_KEY, KEY_GESTURE_E);
+ input_set_capability(input_dev, EV_KEY, KEY_GESTURE_M);
+ input_set_capability(input_dev, EV_KEY, KEY_GESTURE_L);
+ input_set_capability(input_dev, EV_KEY, KEY_GESTURE_W);
+ input_set_capability(input_dev, EV_KEY, KEY_GESTURE_S);
+ input_set_capability(input_dev, EV_KEY, KEY_GESTURE_V);
+ input_set_capability(input_dev, EV_KEY, KEY_GESTURE_Z);
+ input_set_capability(input_dev, EV_KEY, KEY_GESTURE_C);
+
+ __set_bit(KEY_GESTURE_RIGHT, input_dev->keybit);
+ __set_bit(KEY_GESTURE_LEFT, input_dev->keybit);
+ __set_bit(KEY_GESTURE_UP, input_dev->keybit);
+ __set_bit(KEY_GESTURE_DOWN, input_dev->keybit);
+ __set_bit(KEY_GESTURE_U, input_dev->keybit);
+ __set_bit(KEY_GESTURE_O, input_dev->keybit);
+ __set_bit(KEY_GESTURE_E, input_dev->keybit);
+ __set_bit(KEY_GESTURE_M, input_dev->keybit);
+ __set_bit(KEY_GESTURE_W, input_dev->keybit);
+ __set_bit(KEY_GESTURE_L, input_dev->keybit);
+ __set_bit(KEY_GESTURE_S, input_dev->keybit);
+ __set_bit(KEY_GESTURE_V, input_dev->keybit);
+ __set_bit(KEY_GESTURE_C, input_dev->keybit);
+ __set_bit(KEY_GESTURE_Z, input_dev->keybit);
+
+ fts_create_gesture_sysfs(client);
+ fts_gesture_data.mode = 0;
+ fts_gesture_data.active = 0;
+ FTS_FUNC_EXIT();
+ return 0;
+}
+
+/************************************************************************
+* Name: fts_gesture_exit
+* Brief: remove sys
+* Input: i2c info
+* Output: no
+* Return: no
+***********************************************************************/
+int fts_gesture_exit(struct i2c_client *client)
+{
+ sysfs_remove_group(&client->dev.kobj, &fts_gesture_group);
+ return 0;
+}
+
+/*****************************************************************************
+* Name: fts_check_gesture
+* Brief:
+* Input:
+* Output: None
+* Return: None
+*****************************************************************************/
+static void fts_check_gesture(struct input_dev *input_dev, int gesture_id)
+{
+ char *envp[2];
+ int gesture;
+
+ FTS_FUNC_ENTER();
+ switch (gesture_id) {
+ case GESTURE_LEFT:
+ envp[0] = "GESTURE=LEFT";
+ gesture = KEY_GESTURE_LEFT;
+ break;
+ case GESTURE_RIGHT:
+ envp[0] = "GESTURE=RIGHT";
+ gesture = KEY_GESTURE_RIGHT;
+ break;
+ case GESTURE_UP:
+ envp[0] = "GESTURE=UP";
+ gesture = KEY_GESTURE_UP;
+ break;
+ case GESTURE_DOWN:
+ envp[0] = "GESTURE=DOWN";
+ gesture = KEY_GESTURE_DOWN;
+ break;
+ case GESTURE_DOUBLECLICK:
+ envp[0] = "GESTURE=DOUBLE_CLICK";
+ gesture = KEY_POWER;
+ break;
+ case GESTURE_O:
+ envp[0] = "GESTURE=O";
+ gesture = KEY_GESTURE_O;
+ break;
+ case GESTURE_W:
+ envp[0] = "GESTURE=W";
+ gesture = KEY_GESTURE_W;
+ break;
+ case GESTURE_M:
+ envp[0] = "GESTURE=M";
+ gesture = KEY_GESTURE_M;
+ break;
+ case GESTURE_E:
+ envp[0] = "GESTURE=E";
+ gesture = KEY_GESTURE_E;
+ break;
+ case GESTURE_L:
+ envp[0] = "GESTURE=L";
+ gesture = KEY_GESTURE_L;
+ break;
+ case GESTURE_S:
+ envp[0] = "GESTURE=S";
+ gesture = KEY_GESTURE_S;
+ break;
+ case GESTURE_V:
+ envp[0] = "GESTURE=V";
+ gesture = KEY_GESTURE_V;
+ break;
+ case GESTURE_Z:
+ envp[0] = "GESTURE=Z";
+ gesture = KEY_GESTURE_Z;
+ break;
+ case GESTURE_C:
+ envp[0] = "GESTURE=C";
+ gesture = KEY_GESTURE_C;
+ break;
+ default:
+ envp[0] = "GESTURE=NONE";
+ gesture = -1;
+ break;
+ }
+ FTS_DEBUG("envp[0]: %s", envp[0]);
+ /* report event key */
+ /*if (gesture != -1)
+ {
+ input_report_key(input_dev, gesture, 1);
+ input_sync(input_dev);
+ input_report_key(input_dev, gesture, 0);
+ input_sync(input_dev);
+ } */
+
+ envp[1] = NULL;
+ kobject_uevent_env(&fts_wq_data->client->dev.kobj, KOBJ_CHANGE, envp);
+ sysfs_notify(&fts_wq_data->client->dev.kobj, NULL, "GESTURE_ID");
+
+ FTS_FUNC_EXIT();
+}
+
+/************************************************************************
+* Name: fts_gesture_readdata
+* Brief: read data from TP register
+* Input: no
+* Output: no
+* Return: fail <0
+***********************************************************************/
+static int fts_gesture_read_buffer(struct i2c_client *client, u8 *buf,
+ int read_bytes)
+{
+ int remain_bytes;
+ int ret;
+ int i;
+
+ if (read_bytes <= I2C_BUFFER_LENGTH_MAXINUM) {
+ ret = fts_i2c_read(client, buf, 1, buf, read_bytes);
+ } else {
+ ret =
+ fts_i2c_read(client, buf, 1, buf,
+ I2C_BUFFER_LENGTH_MAXINUM);
+ remain_bytes = read_bytes - I2C_BUFFER_LENGTH_MAXINUM;
+ for (i = 1; remain_bytes > 0; i++) {
+ if (remain_bytes <= I2C_BUFFER_LENGTH_MAXINUM)
+ ret =
+ fts_i2c_read(client, buf, 0,
+ buf +
+ I2C_BUFFER_LENGTH_MAXINUM * i,
+ remain_bytes);
+ else
+ ret =
+ fts_i2c_read(client, buf, 0,
+ buf +
+ I2C_BUFFER_LENGTH_MAXINUM * i,
+ I2C_BUFFER_LENGTH_MAXINUM);
+ remain_bytes -= I2C_BUFFER_LENGTH_MAXINUM;
+ }
+ }
+
+ return ret;
+}
+
+/************************************************************************
+* Name: fts_gesture_readdata
+* Brief: read data from TP register
+* Input: no
+* Output: no
+* Return: fail <0
+***********************************************************************/
+int fts_gesture_readdata(struct i2c_client *client)
+{
+ u8 buf[FTS_GESTRUE_POINTS * 4] = { 0 };
+ int ret = -1;
+ int i = 0;
+ int gestrue_id = 0;
+ int read_bytes = 0;
+ u8 pointnum;
+
+ FTS_FUNC_ENTER();
+ /* init variable before read gesture point */
+ memset(fts_gesture_data.header, 0, FTS_GESTRUE_POINTS_HEADER);
+ memset(fts_gesture_data.coordinate_x, 0,
+ FTS_GESTRUE_POINTS * sizeof(u16));
+ memset(fts_gesture_data.coordinate_y, 0,
+ FTS_GESTRUE_POINTS * sizeof(u16));
+
+ buf[0] = FTS_REG_GESTURE_OUTPUT_ADDRESS;
+ ret = fts_i2c_read(client, buf, 1, buf, FTS_GESTRUE_POINTS_HEADER);
+ if (ret < 0) {
+ FTS_ERROR("[GESTURE]Read gesture header data failed!!");
+ FTS_FUNC_EXIT();
+ return ret;
+ }
+
+ /* FW recognize gesture */
+ if (chip_types.chip_idh == 0x54 || chip_types.chip_idh == 0x58
+ || chip_types.chip_idh == 0x86 || chip_types.chip_idh == 0x87
+ || chip_types.chip_idh == 0x64) {
+ memcpy(fts_gesture_data.header, buf, FTS_GESTRUE_POINTS_HEADER);
+ gestrue_id = buf[0];
+ pointnum = buf[1];
+ read_bytes = ((int)pointnum) * 4 + 2;
+ buf[0] = FTS_REG_GESTURE_OUTPUT_ADDRESS;
+ FTS_DEBUG("[GESTURE]PointNum=%d", pointnum);
+ ret = fts_gesture_read_buffer(client, buf, read_bytes);
+ if (ret < 0) {
+ FTS_ERROR("[GESTURE]Read gesture touch data failed!!");
+ FTS_FUNC_EXIT();
+ return ret;
+ }
+
+ fts_check_gesture(fts_input_dev, gestrue_id);
+ for (i = 0; i < pointnum; i++) {
+ fts_gesture_data.coordinate_x[i] =
+ (((s16) buf[0 + (4 * i + 2)]) & 0x0F) << 8 |
+ (((s16) buf[1 + (4 * i + 2)]) & 0xFF);
+ fts_gesture_data.coordinate_y[i] =
+ (((s16) buf[2 + (4 * i + 2)]) & 0x0F) << 8 |
+ (((s16) buf[3 + (4 * i + 2)]) & 0xFF);
+ }
+ FTS_FUNC_EXIT();
+ return 0;
+ }
+ /* other IC's gestrue in driver */
+ if (0x24 == buf[0]) {
+ gestrue_id = 0x24;
+ fts_check_gesture(fts_input_dev, gestrue_id);
+ FTS_DEBUG("[GESTURE]%d check_gesture gestrue_id", gestrue_id);
+ FTS_FUNC_EXIT();
+ return -1;
+ }
+
+ /* Host Driver recognize gesture */
+ pointnum = buf[1];
+ read_bytes = ((int)pointnum) * 4 + 2;
+ buf[0] = FTS_REG_GESTURE_OUTPUT_ADDRESS;
+ ret = fts_gesture_read_buffer(client, buf, read_bytes);
+ if (ret < 0) {
+ FTS_ERROR ("[GESTURE]Driver recognize gesture -"
+ "Read gesture touch data failed!!");
+ FTS_FUNC_EXIT();
+ return ret;
+ }
+
+ /*
+ * Host Driver recognize gesture, need gesture lib.a
+ * Not use now for compatibility
+ gestrue_id = fetch_object_sample(buf, pointnum);
+ */
+ gestrue_id = 0x24;
+ fts_check_gesture(fts_input_dev, gestrue_id);
+ FTS_DEBUG("[GESTURE]%d read gestrue_id", gestrue_id);
+
+ for (i = 0; i < pointnum; i++) {
+ fts_gesture_data.coordinate_x[i] =
+ (((s16) buf[0 + (4 * i + 8)]) & 0x0F) << 8 |
+ (((s16) buf[1 + (4 * i + 8)]) & 0xFF);
+ fts_gesture_data.coordinate_y[i] =
+ (((s16) buf[2 + (4 * i + 8)]) & 0x0F) << 8 |
+ (((s16) buf[3 + (4 * i + 8)]) & 0xFF);
+ }
+ FTS_FUNC_EXIT();
+ return -1;
+}
+
+/*****************************************************************************
+* Name: fts_gesture_suspend
+* Brief:
+* Input:
+* Output: None
+* Return: None
+*****************************************************************************/
+int fts_gesture_suspend(struct i2c_client *i2c_client)
+{
+ int i;
+ u8 state;
+
+ FTS_FUNC_ENTER();
+
+ /* gesture not enable, return immediately */
+ if (fts_gesture_data.mode == 0) {
+ FTS_DEBUG("gesture is disabled");
+ FTS_FUNC_EXIT();
+ return -1;
+ }
+
+ for (i = 0; i < 5; i++) {
+ fts_i2c_write_reg(i2c_client, 0xd1, 0xff);
+ fts_i2c_write_reg(i2c_client, 0xd2, 0xff);
+ fts_i2c_write_reg(i2c_client, 0xd5, 0xff);
+ fts_i2c_write_reg(i2c_client, 0xd6, 0xff);
+ fts_i2c_write_reg(i2c_client, 0xd7, 0xff);
+ fts_i2c_write_reg(i2c_client, 0xd8, 0xff);
+ fts_i2c_write_reg(i2c_client, FTS_REG_GESTURE_EN, 0x01);
+ msleep(1);
+ fts_i2c_read_reg(i2c_client, FTS_REG_GESTURE_EN, &state);
+ if (state == 1)
+ break;
+ }
+
+ if (i >= 5) {
+ FTS_ERROR("[GESTURE]Enter into gesture(suspend) failed!\n");
+ FTS_FUNC_EXIT();
+ return -1;
+ }
+
+ fts_gesture_data.active = 1;
+ FTS_DEBUG("[GESTURE]Enter into gesture(suspend) successfully!");
+ FTS_FUNC_EXIT();
+ return 0;
+}
+
+/*****************************************************************************
+* Name: fts_gesture_resume
+* Brief:
+* Input:
+* Output: None
+* Return: None
+*****************************************************************************/
+int fts_gesture_resume(struct i2c_client *client)
+{
+ int i;
+ u8 state;
+
+ FTS_FUNC_ENTER();
+
+ /* gesture not enable, return immediately */
+ if (fts_gesture_data.mode == 0) {
+ FTS_DEBUG("gesture is disabled");
+ FTS_FUNC_EXIT();
+ return -1;
+ }
+
+ fts_gesture_data.active = 0;
+ for (i = 0; i < 5; i++) {
+ fts_i2c_write_reg(client, FTS_REG_GESTURE_EN, 0x00);
+ msleep(1);
+ fts_i2c_read_reg(client, FTS_REG_GESTURE_EN, &state);
+ if (state == 0)
+ break;
+ }
+
+ if (i >= 5)
+ FTS_ERROR("[GESTURE]Clear gesture(resume) failed!\n");
+
+ FTS_FUNC_EXIT();
+ return 0;
+}
+#endif
diff --git a/drivers/input/touchscreen/focaltech_touch/focaltech_i2c.c b/drivers/input/touchscreen/focaltech_touch/focaltech_i2c.c
new file mode 100644
index 000000000000..75cd917eae2b
--- /dev/null
+++ b/drivers/input/touchscreen/focaltech_touch/focaltech_i2c.c
@@ -0,0 +1,209 @@
+/*
+ *
+ * FocalTech TouchScreen driver.
+ *
+ * Copyright (c) 2010-2016, FocalTech Systems, Ltd., all rights reserved.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+/************************************************************************
+*
+* File Name: focaltech_i2c.c
+*
+* Author: fupeipei
+*
+* Created: 2016-08-04
+*
+* Abstract: i2c communication with TP
+*
+* Version: v1.0
+*
+* Revision History:
+* v1.0:
+* First release. By fupeipei 2016-08-04
+************************************************************************/
+
+/*****************************************************************************
+* Included header files
+*****************************************************************************/
+#include "focaltech_core.h"
+
+/*****************************************************************************
+* Private constant and macro definitions using #define
+*****************************************************************************/
+
+/*****************************************************************************
+* Private enumerations, structures and unions using typedef
+*****************************************************************************/
+
+/*****************************************************************************
+* Static variables
+*****************************************************************************/
+static DEFINE_MUTEX(i2c_rw_access);
+
+/*****************************************************************************
+* Global variable or extern global variabls/functions
+*****************************************************************************/
+
+/*****************************************************************************
+* Static function prototypes
+*****************************************************************************/
+
+/*****************************************************************************
+* functions body
+*****************************************************************************/
+
+/************************************************************************
+* Name: fts_i2c_read
+* Brief: i2c read
+* Input: i2c info, write buf, write len, read buf, read len
+* Output: get data in the 3rd buf
+* Return: fail <0
+***********************************************************************/
+int fts_i2c_read(struct i2c_client *client, char *writebuf, int writelen,
+ char *readbuf, int readlen)
+{
+ int ret = 0;
+
+ mutex_lock(&i2c_rw_access);
+
+ if (readlen > 0) {
+ if (writelen > 0) {
+ struct i2c_msg msgs[] = {
+ {
+ .addr = client->addr,
+ .flags = 0,
+ .len = writelen,
+ .buf = writebuf,
+ },
+ {
+ .addr = client->addr,
+ .flags = I2C_M_RD,
+ .len = readlen,
+ .buf = readbuf,
+ },
+ };
+ ret = i2c_transfer(client->adapter, msgs, 2);
+ if (ret < 0) {
+ FTS_ERROR("[IIC]: i2c_transfer(write)"
+ "error,ret=%d!!", ret);
+ }
+ } else {
+ struct i2c_msg msgs[] = {
+ {
+ .addr = client->addr,
+ .flags = I2C_M_RD,
+ .len = readlen,
+ .buf = readbuf,
+ },
+ };
+ ret = i2c_transfer(client->adapter, msgs, 1);
+ if (ret < 0) {
+ FTS_ERROR("[IIC]: i2c_transfer(read)"
+ "error, ret=%d!!", ret);
+ }
+ }
+ }
+
+ mutex_unlock(&i2c_rw_access);
+ return ret;
+}
+
+/************************************************************************
+* Name: fts_i2c_write
+* Brief: i2c write
+* Input: i2c info, write buf, write len
+* Output: no
+* Return: fail <0
+***********************************************************************/
+int fts_i2c_write(struct i2c_client *client, char *writebuf, int writelen)
+{
+ int ret = 0;
+
+ mutex_lock(&i2c_rw_access);
+ if (writelen > 0) {
+ struct i2c_msg msgs[] = {
+ {
+ .addr = client->addr,
+ .flags = 0,
+ .len = writelen,
+ .buf = writebuf,
+ },
+ };
+ ret = i2c_transfer(client->adapter, msgs, 1);
+ if (ret < 0) {
+ FTS_ERROR("%s: i2c_transfer(write) error, ret=%d",
+ __func__, ret);
+ }
+ }
+ mutex_unlock(&i2c_rw_access);
+
+ return ret;
+}
+
+/************************************************************************
+* Name: fts_i2c_write_reg
+* Brief: write register
+* Input: i2c info, reg address, reg value
+* Output: no
+* Return: fail <0
+***********************************************************************/
+int fts_i2c_write_reg(struct i2c_client *client, u8 regaddr, u8 regvalue)
+{
+ u8 buf[2] = { 0 };
+
+ buf[0] = regaddr;
+ buf[1] = regvalue;
+ return fts_i2c_write(client, buf, sizeof(buf));
+}
+
+/************************************************************************
+* Name: fts_i2c_read_reg
+* Brief: read register
+* Input: i2c info, reg address, reg value
+* Output: get reg value
+* Return: fail <0
+***********************************************************************/
+int fts_i2c_read_reg(struct i2c_client *client, u8 regaddr, u8 *regvalue)
+{
+ return fts_i2c_read(client, &regaddr, 1, regvalue, 1);
+}
+
+/************************************************************************
+* Name: fts_i2c_init
+* Brief: fts i2c init
+* Input:
+* Output:
+* Return:
+***********************************************************************/
+int fts_i2c_init(void)
+{
+ FTS_FUNC_ENTER();
+
+ FTS_FUNC_EXIT();
+ return 0;
+}
+
+/************************************************************************
+* Name: fts_i2c_exit
+* Brief: fts i2c exit
+* Input:
+* Output:
+* Return:
+***********************************************************************/
+int fts_i2c_exit(void)
+{
+ FTS_FUNC_ENTER();
+
+ FTS_FUNC_EXIT();
+ return 0;
+}
diff --git a/drivers/input/touchscreen/focaltech_touch/focaltech_point_report_check.c b/drivers/input/touchscreen/focaltech_touch/focaltech_point_report_check.c
new file mode 100644
index 000000000000..0fa561748f75
--- /dev/null
+++ b/drivers/input/touchscreen/focaltech_touch/focaltech_point_report_check.c
@@ -0,0 +1,151 @@
+/*
+ *
+ * FocalTech TouchScreen driver.
+ *
+ * Copyright (c) 2010-2016, FocalTech Systems, Ltd., all rights reserved.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+/*****************************************************************************
+*
+* File Name: focaltech_point_report_check.c
+*
+* Author: WangTao
+*
+* Created: 2016-11-16
+*
+* Abstract: point report check function
+*
+* Version: v1.0
+*
+* Revision History:
+* v1.0:
+* First release. By WangTao 2016-11-16
+*****************************************************************************/
+
+/*****************************************************************************
+* Included header files
+*****************************************************************************/
+#include "focaltech_core.h"
+
+#if FTS_POINT_REPORT_CHECK_EN
+/*****************************************************************************
+* Private constant and macro definitions using #define
+*****************************************************************************/
+#define POINT_REPORT_CHECK_WAIT_TIME 200
+
+/*****************************************************************************
+* Private enumerations, structures and unions using typedef
+*****************************************************************************/
+
+/*****************************************************************************
+* Static variables
+*****************************************************************************/
+static struct delayed_work fts_point_report_check_work;
+static struct workqueue_struct *fts_point_report_check_workqueue;
+
+/*****************************************************************************
+* Global variable or extern global variabls/functions
+*****************************************************************************/
+
+/*****************************************************************************
+* Static function prototypes
+*****************************************************************************/
+
+/*****************************************************************************
+* functions body
+*****************************************************************************/
+
+/*****************************************************************************
+* Name: fts_point_report_check_func
+* Brief:
+* Input:
+* Output:
+* Return:
+*****************************************************************************/
+static void fts_point_report_check_func(struct work_struct *work)
+{
+
+#if FTS_MT_PROTOCOL_B_EN
+ unsigned int finger_count = 0;
+
+ FTS_FUNC_ENTER();
+
+ for (finger_count = 0; finger_count < FTS_MAX_POINTS; finger_count++) {
+ input_mt_slot(fts_input_dev, finger_count);
+ input_mt_report_slot_state(fts_input_dev, MT_TOOL_FINGER,
+ false);
+ }
+#else
+ input_mt_sync(fts_input_dev);
+#endif
+ input_report_key(fts_input_dev, BTN_TOUCH, 0);
+ input_sync(fts_input_dev);
+
+ FTS_FUNC_EXIT();
+}
+
+void fts_point_report_check_queue_work(void)
+{
+
+ cancel_delayed_work(&fts_point_report_check_work);
+ queue_delayed_work(fts_point_report_check_workqueue,
+ &fts_point_report_check_work,
+ msecs_to_jiffies(POINT_REPORT_CHECK_WAIT_TIME));
+
+}
+
+/*****************************************************************************
+* Name: fts_point_report_check_init
+* Brief:
+* Input:
+* Output:
+* Return: < 0: Fail to create esd check queue
+*****************************************************************************/
+int fts_point_report_check_init(void)
+{
+ FTS_FUNC_ENTER();
+
+ INIT_DELAYED_WORK(&fts_point_report_check_work,
+ fts_point_report_check_func);
+ fts_point_report_check_workqueue =
+ create_workqueue("fts_point_report_check_func_wq");
+ if (fts_point_report_check_workqueue == NULL) {
+ FTS_ERROR("[POINT_REPORT]: Failed to create"
+ "fts_point_report_check_workqueue!!");
+ } else {
+ FTS_DEBUG("[POINT_REPORT]: Success to create"
+ "fts_point_report_check_workqueue!!");
+ }
+
+ FTS_FUNC_EXIT();
+
+ return 0;
+}
+
+/*****************************************************************************
+* Name: fts_point_report_check_exit
+* Brief:
+* Input:
+* Output:
+* Return:
+*****************************************************************************/
+int fts_point_report_check_exit(void)
+{
+ FTS_FUNC_ENTER();
+
+ destroy_workqueue(fts_point_report_check_workqueue);
+
+ FTS_FUNC_EXIT();
+ return 0;
+}
+#endif /* FTS_POINT_REPORT_CHECK_EN */
diff --git a/drivers/input/touchscreen/focaltech_touch/focaltech_sensor.c b/drivers/input/touchscreen/focaltech_touch/focaltech_sensor.c
new file mode 100644
index 000000000000..4a62ee65eaa6
--- /dev/null
+++ b/drivers/input/touchscreen/focaltech_touch/focaltech_sensor.c
@@ -0,0 +1,311 @@
+/*
+ *
+ * FocalTech TouchScreen driver.
+ *
+ * Copyright (c) 2010-2016, FocalTech Systems, Ltd., all rights reserved.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+/*****************************************************************************
+*
+* File Name: focaltech_esdcheck.c
+*
+* Author: Focaltech Driver Team
+*
+* Created: 2016-08-03
+*
+* Abstract: Sensor
+*
+* Version: v1.0
+*
+* Revision History:
+* v1.0:
+* First release. By luougojin 2016-08-03
+*****************************************************************************/
+
+/*****************************************************************************
+* Included header files
+*****************************************************************************/
+#include "focaltech_core.h"
+
+#if FTS_PSENSOR_EN
+/*****************************************************************************
+* Private constant and macro definitions using #define
+*****************************************************************************/
+/* psensor register address*/
+#define FTS_REG_PSENSOR_ENABLE 0xB0
+#define FTS_REG_PSENSOR_STATUS 0x01
+
+/* psensor register bits*/
+#define FTS_PSENSOR_ENABLE_MASK 0x01
+#define FTS_PSENSOR_STATUS_NEAR 0xC0
+#define FTS_PSENSOR_STATUS_FAR 0xE0
+#define FTS_PSENSOR_FAR_TO_NEAR 0
+#define FTS_PSENSOR_NEAR_TO_FAR 1
+#define FTS_PSENSOR_ORIGINAL_STATE_FAR 1
+#define FTS_PSENSOR_WAKEUP_TIMEOUT 500
+
+/*****************************************************************************
+* Static variables
+*****************************************************************************/
+static struct sensors_classdev __maybe_unused sensors_proximity_cdev = {
+ .name = "fts-proximity",
+ .vendor = "FocalTech",
+ .version = 1,
+ .handle = SENSORS_PROXIMITY_HANDLE,
+ .type = SENSOR_TYPE_PROXIMITY,
+ .max_range = "5.0",
+ .resolution = "5.0",
+ .sensor_power = "0.1",
+ .min_delay = 0,
+ .fifo_reserved_event_count = 0,
+ .fifo_max_event_count = 0,
+ .enabled = 0,
+ .delay_msec = 200,
+ .sensors_enable = NULL,
+ .sensors_poll_delay = NULL,
+};
+
+/*****************************************************************************
+* functions body
+*****************************************************************************/
+/*****************************************************************************
+* Name: fts_psensor_support_enabled
+* Brief:
+* Input:
+* Output:
+* Return:
+*****************************************************************************/
+static inline bool fts_psensor_support_enabled(void)
+{
+ /*return config_enabled(CONFIG_TOUCHSCREEN_FTS_PSENSOR); */
+ return FTS_PSENSOR_EN;
+}
+
+/*****************************************************************************
+* Name: fts_psensor_enable
+* Brief:
+* Input:
+* Output:
+* Return:
+*****************************************************************************/
+static void fts_psensor_enable(struct fts_ts_data *data, int enable)
+{
+ u8 state;
+ int ret = -1;
+
+ if (data->client == NULL)
+ return;
+
+ fts_i2c_read_reg(data->client, FTS_REG_PSENSOR_ENABLE, &state);
+ if (enable)
+ state |= FTS_PSENSOR_ENABLE_MASK;
+ else
+ state &= ~FTS_PSENSOR_ENABLE_MASK;
+
+ ret = fts_i2c_write_reg(data->client, FTS_REG_PSENSOR_ENABLE, state);
+ if (ret < 0)
+ FTS_ERROR("write psensor switch command failed");
+}
+
+/*****************************************************************************
+* Name: fts_psensor_enable_set
+* Brief:
+* Input:
+* Output:
+* Return:
+*****************************************************************************/
+static int fts_psensor_enable_set(struct sensors_classdev *sensors_cdev,
+ unsigned int enable)
+{
+ struct fts_psensor_platform_data *psensor_pdata =
+ container_of(sensors_cdev,
+ struct fts_psensor_platform_data, ps_cdev);
+ struct fts_ts_data *data = psensor_pdata->data;
+ struct input_dev *input_dev = data->psensor_pdata->input_psensor_dev;
+
+ mutex_lock(&input_dev->mutex);
+ fts_psensor_enable(data, enable);
+ psensor_pdata->tp_psensor_data = FTS_PSENSOR_ORIGINAL_STATE_FAR;
+ if (enable)
+ psensor_pdata->tp_psensor_opened = 1;
+ else
+ psensor_pdata->tp_psensor_opened = 0;
+ mutex_unlock(&input_dev->mutex);
+ return enable;
+}
+
+/*****************************************************************************
+* Name: fts_read_tp_psensor_data
+* Brief:
+* Input:
+* Output:
+* Return:
+*****************************************************************************/
+static int fts_read_tp_psensor_data(struct fts_ts_data *data)
+{
+ u8 psensor_status;
+ char tmp;
+ int ret = 1;
+
+ fts_i2c_read_reg(data->client, FTS_REG_PSENSOR_STATUS, &psensor_status);
+
+ tmp = data->psensor_pdata->tp_psensor_data;
+ if (psensor_status == FTS_PSENSOR_STATUS_NEAR)
+ data->psensor_pdata->tp_psensor_data = FTS_PSENSOR_FAR_TO_NEAR;
+ else if (psensor_status == FTS_PSENSOR_STATUS_FAR)
+ data->psensor_pdata->tp_psensor_data = FTS_PSENSOR_NEAR_TO_FAR;
+
+ if (tmp != data->psensor_pdata->tp_psensor_data) {
+ FTS_ERROR("%s sensor data changed", __func__);
+ ret = 0;
+ }
+ return ret;
+}
+
+int fts_sensor_read_data(struct fts_ts_data *data)
+{
+ int ret = 0;
+
+ if (fts_psensor_support_enabled()
+ && data->psensor_pdata->tp_psensor_opened) {
+ ret = fts_read_tp_psensor_data(data);
+ if (!ret) {
+ if (data->suspended) {
+ pm_wakeup_event(&data->client->dev,
+ FTS_PSENSOR_WAKEUP_TIMEOUT);
+ }
+ input_report_abs(data->psensor_pdata->input_psensor_dev,
+ ABS_DISTANCE,
+ data->psensor_pdata->tp_psensor_data);
+ input_sync(data->psensor_pdata->input_psensor_dev);
+ }
+ return 1;
+ }
+ return 0;
+}
+
+int fts_sensor_suspend(struct fts_ts_data *data)
+{
+ int ret = 0;
+
+ if (fts_psensor_support_enabled()
+ && device_may_wakeup(&data->client->dev)
+ && data->psensor_pdata->tp_psensor_opened) {
+ ret = enable_irq_wake(data->client->irq);
+ if (ret != 0)
+ FTS_ERROR("%s: set_irq_wake failed", __func__);
+ data->suspended = true;
+ return 1;
+ }
+
+ return 0;
+}
+
+int fts_sensor_resume(struct fts_ts_data *data)
+{
+ int ret = 0;
+
+ if (fts_psensor_support_enabled()
+ && device_may_wakeup(&data->client->dev)
+ && data->psensor_pdata->tp_psensor_opened) {
+ ret = disable_irq_wake(data->client->irq);
+ if (ret)
+ FTS_ERROR("%s: disable_irq_wake failed", __func__);
+ data->suspended = false;
+ return 1;
+ }
+
+ return 0;
+}
+
+int fts_sensor_init(struct fts_ts_data *data)
+{
+ struct fts_psensor_platform_data *psensor_pdata;
+ struct input_dev *psensor_input_dev;
+ int err;
+
+ if (fts_psensor_support_enabled()) {
+ device_init_wakeup(&data->client->dev, 1);
+ psensor_pdata =
+ devm_kzalloc(&data->client->dev,
+ sizeof(struct fts_psensor_platform_data),
+ GFP_KERNEL);
+ if (!psensor_pdata) {
+ FTS_ERROR("Failed to allocate memory");
+ goto irq_free;
+ }
+ data->psensor_pdata = psensor_pdata;
+
+ psensor_input_dev = input_allocate_device();
+ if (!psensor_input_dev) {
+ FTS_ERROR("Failed to allocate device");
+ goto free_psensor_pdata;
+ }
+
+ __set_bit(EV_ABS, psensor_input_dev->evbit);
+ input_set_abs_params(psensor_input_dev, ABS_DISTANCE, 0, 1, 0,
+ 0);
+ psensor_input_dev->name = "proximity";
+ psensor_input_dev->id.bustype = BUS_I2C;
+ psensor_input_dev->dev.parent = &data->client->dev;
+ data->psensor_pdata->input_psensor_dev = psensor_input_dev;
+
+ err = input_register_device(psensor_input_dev);
+ if (err) {
+ FTS_ERROR("Unable to register device, err=%d", err);
+ goto free_psensor_input_dev;
+ }
+
+ psensor_pdata->ps_cdev = sensors_proximity_cdev;
+ psensor_pdata->ps_cdev.sensors_enable = fts_psensor_enable_set;
+ psensor_pdata->data = data;
+
+ err =
+ sensors_classdev_register(&data->client->dev,
+ &psensor_pdata->ps_cdev);
+ if (err)
+ goto unregister_psensor_input_device;
+ }
+
+ return 0;
+unregister_psensor_input_device:
+ if (fts_psensor_support_enabled())
+ input_unregister_device(data->psensor_pdata->input_psensor_dev);
+free_psensor_input_dev:
+ if (fts_psensor_support_enabled())
+ input_free_device(data->psensor_pdata->input_psensor_dev);
+free_psensor_pdata:
+ if (fts_psensor_support_enabled()) {
+ devm_kfree(&data->client->dev, psensor_pdata);
+ data->psensor_pdata = NULL;
+ }
+irq_free:
+ if (fts_psensor_support_enabled())
+ device_init_wakeup(&data->client->dev, 0);
+ free_irq(data->client->irq, data);
+
+ return 1;
+}
+
+int fts_sensor_remove(struct fts_ts_data *data)
+{
+ if (fts_psensor_support_enabled()) {
+ device_init_wakeup(&data->client->dev, 0);
+ sensors_classdev_unregister(&data->psensor_pdata->ps_cdev);
+ input_unregister_device(data->psensor_pdata->input_psensor_dev);
+ devm_kfree(&data->client->dev, data->psensor_pdata);
+ data->psensor_pdata = NULL;
+ }
+ return 0;
+}
+#endif /* FTS_PSENSOR_EN */
diff --git a/drivers/input/touchscreen/focaltech_touch/include/firmware/FT8716_app_sample.i b/drivers/input/touchscreen/focaltech_touch/include/firmware/FT8716_app_sample.i
new file mode 100644
index 000000000000..e69de29bb2d1
--- /dev/null
+++ b/drivers/input/touchscreen/focaltech_touch/include/firmware/FT8716_app_sample.i
diff --git a/drivers/input/touchscreen/focaltech_touch/include/firmware/lcd_cfg.i b/drivers/input/touchscreen/focaltech_touch/include/firmware/lcd_cfg.i
new file mode 100644
index 000000000000..e69de29bb2d1
--- /dev/null
+++ b/drivers/input/touchscreen/focaltech_touch/include/firmware/lcd_cfg.i
diff --git a/drivers/input/touchscreen/focaltech_touch/include/pramboot/FT8606_Pramboot_V0.7_20150507.i b/drivers/input/touchscreen/focaltech_touch/include/pramboot/FT8606_Pramboot_V0.7_20150507.i
new file mode 100644
index 000000000000..f031758e0207
--- /dev/null
+++ b/drivers/input/touchscreen/focaltech_touch/include/pramboot/FT8606_Pramboot_V0.7_20150507.i
@@ -0,0 +1,244 @@
+0x2, 0x9, 0x9b, 0xca, 0x39, 0x12, 0xc, 0x4b, 0xda, 0x39, 0x32, 0x2, 0x0, 0x3,
+ 0x6d, 0x22, 0x80, 0x13, 0x75, 0xb5, 0x0, 0xa9, 0x36, 0xb3, 0xfc, 0xa9, 0xc6,
+ 0xb3, 0xe5, 0xb5, 0x7a, 0xb, 0xb0, 0xb, 0x14, 0xb, 0x24, 0xbd, 0x32, 0x38,
+ 0xe9, 0x22, 0xff, 0x2, 0xa, 0x70, 0xa9, 0xc2, 0xb4, 0x74, 0x5, 0x12, 0xc,
+ 0x36, 0x12, 0xc, 0x1d, 0xa9, 0xd2, 0xb4, 0x30, 0xe0, 0x2, 0xd3, 0x22, 0xc3,
+ 0x22, 0x2, 0x0, 0xf9, 0xca, 0x3b, 0x7a, 0xd, 0x8, 0x7f, 0x31, 0xe5, 0x23,
+ 0xb4, 0x80, 0x2, 0x80, 0x3, 0x2, 0x0, 0xdc, 0x7f, 0x13, 0x5e, 0x34, 0x0,
+ 0x7f, 0x7d, 0x23, 0x7e, 0x34, 0x0, 0x80, 0x9d, 0x32, 0x7a, 0x35, 0xe, 0x7e,
+ 0x35, 0xc, 0xbe, 0x35, 0xe, 0x38, 0x2, 0x80, 0x5d, 0x7e, 0x35, 0xe, 0x7a,
+ 0x35, 0x10, 0x7f, 0x13, 0x7e, 0xd, 0x8, 0x12, 0x8, 0xf3, 0x7e, 0x35, 0xc,
+ 0x9e, 0x35, 0xe, 0x7a, 0x35, 0xc, 0x7e, 0x35, 0xe, 0x6d, 0x22, 0x2f, 0x31,
+ 0x7e, 0x1d, 0x8, 0x2e, 0x35, 0xe, 0x7a, 0x1d, 0x8, 0x80, 0x27, 0x7e, 0x34,
+ 0x0, 0x80, 0x7a, 0x35, 0x10, 0x7f, 0x13, 0x7e, 0xd, 0x8, 0x12, 0x8, 0xf3,
+ 0x7e, 0x35, 0xc, 0x9e, 0x34, 0x0, 0x80, 0x7a, 0x35, 0xc, 0x7e, 0x1d, 0x8,
+ 0x2e, 0x34, 0x0, 0x80, 0x7a, 0x1d, 0x8, 0x2e, 0x38, 0x0, 0x80, 0x7e, 0x35,
+ 0xc, 0xbe, 0x34, 0x0, 0x80, 0x50, 0xd0, 0x4d, 0x33, 0x68, 0x26, 0x7a, 0x35,
+ 0x10, 0x7f, 0x13, 0x7e, 0xd, 0x8, 0x12, 0x8, 0xf3, 0x80, 0x19, 0x74, 0x2,
+ 0x12, 0x8, 0x3d, 0x5e, 0x70, 0xf4, 0x12, 0x9, 0xe7, 0x7e, 0x35, 0xc, 0x7a,
+ 0x35, 0x10, 0x7f, 0x13, 0x7e, 0xd, 0x8, 0x12, 0x6, 0x42, 0xd3, 0xda, 0x3b,
+ 0x22, 0xa9, 0xc0, 0x93, 0x75, 0x38, 0x0, 0x32, 0xc, 0x60, 0xf3, 0x9f, 0x46,
+ 0xb9, 0x2, 0xfd, 0xff, 0x0, 0xff, 0x0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0x7c, 0x6b, 0xc2, 0x2, 0xe5, 0x21, 0x14, 0x78, 0x3, 0x2, 0x2,
+ 0xbf, 0x1b, 0xb1, 0x78, 0x3, 0x2, 0x2, 0x30, 0x1b, 0xb1, 0x78, 0x3, 0x2,
+ 0x2, 0x7c, 0x1b, 0xb1, 0x78, 0x3, 0x2, 0x2, 0x8d, 0x1b, 0xb1, 0x78, 0x3,
+ 0x2, 0x2, 0xa6, 0x24, 0xf9, 0x78, 0x3, 0x2, 0x2, 0xbb, 0x24, 0xaf, 0x78,
+ 0x3, 0x2, 0x3, 0x29, 0x24, 0xfd, 0x68, 0x2d, 0x14, 0x78, 0x3, 0x2, 0x2,
+ 0xc2, 0x14, 0x78, 0x3, 0x2, 0x2, 0xbf, 0x1b, 0xb2, 0x78, 0x3, 0x2, 0x2,
+ 0xbf, 0x24, 0xda, 0x68, 0x19, 0x24, 0xe6, 0x68, 0x12, 0x24, 0xeb, 0x68,
+ 0x2e, 0x24, 0xf3, 0x78, 0x3, 0x2, 0x2, 0xbf, 0x24, 0x77, 0x68, 0x3, 0x2,
+ 0x3, 0x33, 0x2, 0x3, 0x30, 0xbe, 0x60, 0x4, 0x50, 0xc, 0x75, 0x16, 0x0,
+ 0x7c, 0x16, 0x2e, 0x10, 0x24, 0x7c, 0xb7, 0xa5, 0xf7, 0xa5, 0xbe, 0x0, 0x2,
+ 0x80, 0x3, 0x2, 0x3, 0x33, 0xd2, 0x2, 0x22, 0x7c, 0xb6, 0x24, 0x0, 0x78,
+ 0x3, 0x2, 0x3, 0x33, 0x1b, 0xb1, 0x68, 0x1e, 0x14, 0x68, 0x1e, 0x14, 0x68,
+ 0x1e, 0x14, 0x68, 0x1e, 0xb, 0xb2, 0x78, 0x33, 0x30, 0x1, 0x7, 0x7e, 0x8,
+ 0x0, 0x3e, 0x2, 0x2, 0x4d, 0x7e, 0x8, 0x1, 0x4a, 0x2, 0x2, 0x4d, 0x2, 0x2,
+ 0xe7, 0x2, 0x2, 0xee, 0x2, 0x3, 0x6, 0xa, 0x27, 0x7e, 0xd, 0x39, 0xb, 0x16,
+ 0xb, 0xa, 0x30, 0x2d, 0x32, 0x1b, 0xa, 0x30, 0x6d, 0x33, 0x7e, 0xd, 0x39,
+ 0x79, 0x30, 0x0, 0x6, 0x22, 0x7c, 0xb7, 0x62, 0x16, 0x7e, 0x2d, 0x39, 0x2e,
+ 0x54, 0x0, 0x6, 0xb, 0x2a, 0x20, 0x7d, 0x12, 0xb, 0x14, 0x1b, 0x2a, 0x10,
+ 0x7e, 0xd, 0x39, 0x2d, 0x12, 0x39, 0x70, 0x0, 0x8, 0x7e, 0xd, 0x39, 0x69,
+ 0x50, 0x0, 0x4, 0x69, 0x20, 0x0, 0x6, 0xbd, 0x25, 0x50, 0x3, 0x2, 0x3, 0x33,
+ 0xb2, 0x1, 0x7a, 0xd, 0x33, 0x7e, 0x34, 0x0, 0x2, 0x2, 0x3, 0x25, 0x7c,
+ 0xb6, 0x1b, 0xb1, 0x68, 0x1d, 0x14, 0x68, 0x1d, 0xb, 0xb1, 0x68, 0x3, 0x2,
+ 0x3, 0x33, 0x30, 0x1, 0x6, 0x7e, 0x8, 0x0, 0x3e, 0x80, 0x4, 0x7e, 0x8, 0x1,
+ 0x4a, 0x7a, 0xd, 0x39, 0x2, 0x2, 0xd6, 0x2, 0x2, 0xe7, 0xa, 0x57, 0x6d,
+ 0x44, 0x7e, 0xd, 0x39, 0x69, 0x30, 0x0, 0x2, 0xb, 0xa, 0x20, 0x2f, 0x12,
+ 0x79, 0x30, 0x0, 0x2, 0x1b, 0xa, 0x20, 0x7e, 0x1d, 0x39, 0x7a, 0x1d, 0x33,
+ 0xd2, 0x2, 0x7e, 0x34, 0x0, 0x1, 0x2, 0x3, 0x25, 0xbe, 0x60, 0x1, 0x68, 0x9,
+ 0xa5, 0xbe, 0x2, 0x5, 0x7a, 0x71, 0x3d, 0xd2, 0x3, 0xd2, 0x2, 0x22, 0x75,
+ 0xe6, 0x0, 0xe4, 0x7e, 0x34, 0x1, 0x4, 0x7e, 0x24, 0x0, 0xff, 0x7a, 0x1b,
+ 0xb0, 0x7e, 0x34, 0x1, 0x5, 0x7a, 0x1b, 0xb0, 0xd2, 0x4, 0x22, 0xa5, 0xbe,
+ 0x1, 0x4, 0x7a, 0x71, 0x37, 0x22, 0xa5, 0xbe, 0x2, 0x2, 0x80, 0x3, 0x2, 0x3,
+ 0x33, 0x7a, 0x71, 0x22, 0x22, 0x7a, 0x71, 0x32, 0x22, 0xd2, 0x2, 0x22, 0x1b,
+ 0x61, 0x68, 0x21, 0x1b, 0x60, 0x68, 0x24, 0x1b, 0x60, 0x68, 0x38, 0x1b,
+ 0x60, 0x68, 0x40, 0xb, 0x62, 0x78, 0x5d, 0xa, 0x37, 0x7d, 0x3, 0x6d, 0x11,
+ 0x7e, 0x1d, 0x39, 0x79, 0x11, 0x0, 0x2, 0x1b, 0x1a, 0x0, 0x22, 0xa, 0x57,
+ 0x7c, 0xab, 0xe4, 0x80, 0x2, 0xa, 0x57, 0x6d, 0x44, 0x7e, 0xd, 0x39, 0x69,
+ 0x30, 0x0, 0x2, 0xb, 0xa, 0x20, 0x2f, 0x12, 0x79, 0x30, 0x0, 0x2, 0x1b, 0xa,
+ 0x20, 0x22, 0x7c, 0x67, 0x6c, 0x77, 0x7e, 0xd, 0x39, 0x79, 0x30, 0x0, 0x4,
+ 0x22, 0xa, 0x27, 0x7e, 0xd, 0x39, 0xb, 0x16, 0xb, 0xa, 0x30, 0x2d, 0x32,
+ 0x1b, 0xa, 0x30, 0x7e, 0x34, 0x0, 0x3, 0x7a, 0x35, 0x2e, 0x22, 0x7e, 0x34,
+ 0x0, 0x4, 0x7a, 0x35, 0x2e, 0x75, 0x16, 0x0, 0x22, 0xca, 0x3b, 0x7a, 0x15,
+ 0x8, 0x7f, 0x31, 0x7e, 0x35, 0x8, 0xbe, 0x34, 0x0, 0x0, 0x38, 0x4f, 0x7e,
+ 0x34, 0xff, 0xff, 0x7a, 0x35, 0x8, 0x75, 0xe, 0x1, 0x80, 0x43, 0x7e, 0x34,
+ 0x0, 0x80, 0x7a, 0x35, 0x11, 0x7f, 0x13, 0x7e, 0x8, 0x2, 0x56, 0x12, 0xc,
+ 0x1, 0x7e, 0x35, 0x8, 0x9e, 0x34, 0x0, 0x80, 0x7a, 0x35, 0x8, 0x2e, 0x38,
+ 0x0, 0x80, 0x6d, 0x33, 0x7a, 0x35, 0xf, 0x7e, 0x35, 0xf, 0x9, 0x63, 0x2,
+ 0x56, 0x7e, 0xd, 0xa, 0x7e, 0xb, 0x70, 0x6c, 0x76, 0x7a, 0xb, 0x70, 0x7e,
+ 0x35, 0xf, 0xb, 0x34, 0x7a, 0x35, 0xf, 0xbe, 0x34, 0x0, 0x80, 0x78, 0xe0,
+ 0x7e, 0x35, 0x8, 0xbe, 0x34, 0x0, 0x80, 0x38, 0xb4, 0xe5, 0xe, 0x60, 0x5,
+ 0xb, 0x34, 0x7a, 0x35, 0x8, 0x7e, 0x35, 0x8, 0x7a, 0x35, 0x11, 0x7f, 0x13,
+ 0x7e, 0x8, 0x2, 0x56, 0x12, 0xc, 0x1, 0x6d, 0x33, 0x80, 0x17, 0x7e, 0x35,
+ 0xf, 0x9, 0x63, 0x2, 0x56, 0x7e, 0xd, 0xa, 0x7e, 0xb, 0x70, 0x6c, 0x76,
+ 0x7a, 0xb, 0x70, 0x7e, 0x35, 0xf, 0xb, 0x34, 0x7a, 0x35, 0xf, 0x7e, 0x35,
+ 0x8, 0xbe, 0x35, 0xf, 0x38, 0xde, 0xda, 0x3b, 0x22, 0x80, 0x18, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe5, 0x3d, 0x70, 0xa, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7d, 0x23, 0x1b, 0x34, 0x4d, 0x22,
+ 0x78, 0xe0, 0x22, 0x56, 0x30, 0x2e, 0x36, 0x4d, 0x61, 0x79, 0x20, 0x30,
+ 0x37, 0x20, 0x32, 0x30, 0x31, 0x35, 0x0, 0x46, 0x54, 0x53, 0x38, 0x36, 0x30,
+ 0x36, 0x5f, 0x70, 0x72, 0x61, 0x6d, 0x62, 0x6f, 0x6f, 0x74, 0x12, 0xb, 0xbd,
+ 0x2, 0x5, 0x66, 0x7e, 0x35, 0x2e, 0x1b, 0x34, 0x68, 0x57, 0x1b, 0x35, 0x78,
+ 0x3, 0x2, 0x4, 0xb3, 0x1b, 0x34, 0x78, 0x3, 0x2, 0x4, 0xdd, 0xb, 0x35, 0x68,
+ 0x3, 0x2, 0x5, 0x52, 0x6d, 0x33, 0x7a, 0x35, 0x2e, 0x7a, 0x35, 0x30, 0x30,
+ 0x5, 0x5, 0x12, 0xb, 0xf0, 0xc2, 0x5, 0x7e, 0xd, 0x33, 0x69, 0x30, 0x0, 0x4,
+ 0x7a, 0x35, 0xc, 0x69, 0x30, 0x0, 0x2, 0xb, 0xa, 0x20, 0x2e, 0x14, 0x0, 0x8,
+ 0x12, 0x0, 0x46, 0xd2, 0x5, 0x7e, 0x2d, 0x33, 0x69, 0x12, 0x0, 0x4, 0x69,
+ 0x32, 0x0, 0x2, 0xb, 0x2a, 0x20, 0x12, 0x9, 0x48, 0x2e, 0x34, 0x10, 0x0,
+ 0x2, 0x5, 0x4f, 0x6d, 0x33, 0x7a, 0x35, 0x2e, 0x7e, 0x34, 0x1, 0x0, 0x7a,
+ 0x35, 0x11, 0x7e, 0xd, 0x33, 0x69, 0x30, 0x0, 0x2, 0xb, 0xa, 0x20, 0x2e,
+ 0x14, 0x0, 0x8, 0x12, 0xc, 0x1, 0x20, 0x0, 0x3, 0x2, 0x5, 0x52, 0x7e, 0x1d,
+ 0x33, 0x29, 0xb1, 0x0, 0x8, 0xf5, 0x91, 0x2, 0x5, 0x52, 0x6d, 0x33, 0x7a,
+ 0x35, 0x2e, 0x7a, 0x35, 0x30, 0x7e, 0x18, 0x0, 0x16, 0x7a, 0x1d, 0xa, 0x7e,
+ 0xd, 0x33, 0x69, 0x30, 0x0, 0x2, 0xb, 0xa, 0x20, 0x69, 0x10, 0x0, 0x4, 0x12,
+ 0x3, 0x34, 0x12, 0xb, 0xf0, 0x7e, 0x34, 0xf0, 0x55, 0x2, 0x5, 0x4f, 0x6d,
+ 0x33, 0x7a, 0x35, 0x2e, 0x7a, 0x35, 0x30, 0xe5, 0x37, 0xb4, 0xa, 0x15, 0xe5,
+ 0x23, 0xb4, 0x80, 0xb, 0xe4, 0x12, 0xa, 0x32, 0x74, 0x1, 0x12, 0xa, 0x32,
+ 0x80, 0x4e, 0x12, 0x6, 0xd8, 0x80, 0x49, 0xe5, 0x37, 0xb4, 0xb, 0x27, 0xe5,
+ 0x23, 0xb4, 0x80, 0x11, 0x7e, 0xf0, 0x1, 0x7c, 0xbf, 0x12, 0x5, 0x6d, 0xb,
+ 0xf0, 0xbe, 0xf0, 0x11, 0x78, 0xf4, 0x80, 0x2e, 0x7e, 0xf0, 0x4, 0x7c, 0xbf,
+ 0x12, 0x5, 0x6d, 0xb, 0xf0, 0xbe, 0xf0, 0x40, 0x78, 0xf4, 0x80, 0x1d, 0xe5,
+ 0x37, 0xa, 0x3b, 0x9e, 0x34, 0x0, 0x80, 0x7c, 0xe7, 0x6c, 0xdd, 0x80, 0x9,
+ 0x7c, 0xbe, 0x12, 0x5, 0x6d, 0xb, 0xe0, 0xb, 0xd0, 0xe5, 0x22, 0xbc, 0xbd,
+ 0x38, 0xf1, 0x12, 0xb, 0xf0, 0x7e, 0x34, 0xf0, 0xaa, 0x7a, 0x35, 0x30, 0x30,
+ 0x4, 0x11, 0x7e, 0x34, 0x13, 0x88, 0x12, 0x3, 0xdd, 0x7e, 0x34, 0x13, 0x88,
+ 0x12, 0x3, 0xdd, 0x75, 0xe9, 0xff, 0x30, 0x6, 0x3, 0x2, 0x4, 0x26, 0x22,
+ 0xca, 0xf8, 0x7c, 0xfb, 0xe5, 0x23, 0xb4, 0x80, 0x4a, 0xd2, 0x7, 0x12, 0xb,
+ 0xdd, 0x74, 0x20, 0xca, 0xb8, 0xa, 0x3f, 0x6d, 0x22, 0x74, 0xc, 0x2f, 0x11,
+ 0x14, 0x78, 0xfb, 0xda, 0xb8, 0x12, 0xb, 0x44, 0xa9, 0xd2, 0xb4, 0x12, 0xc,
+ 0x41, 0x12, 0x0, 0x2e, 0x50, 0x9, 0x7e, 0x35, 0x17, 0xbe, 0x34, 0x1, 0xf4,
+ 0x28, 0xf2, 0x7e, 0x35, 0x17, 0xbe, 0x34, 0x1, 0xf4, 0x38, 0x6, 0x12, 0xc,
+ 0x5c, 0x2, 0x6, 0x3f, 0xc2, 0x86, 0x7e, 0x34, 0x13, 0x88, 0x12, 0x3, 0xdd,
+ 0xd2, 0x86, 0x2, 0x6, 0x3f, 0x74, 0x1, 0x12, 0x7, 0xd5, 0x74, 0x1, 0x6d,
+ 0x33, 0x12, 0x9, 0xe7, 0xe4, 0x12, 0x8, 0x3d, 0x5e, 0x34, 0x80, 0x0, 0x7c,
+ 0x4f, 0x6c, 0x55, 0x3e, 0x24, 0x4d, 0x32, 0x12, 0x9, 0xe7, 0x74, 0x4, 0x6d,
+ 0x33, 0x12, 0x9, 0xe7, 0x7e, 0x34, 0x0, 0x50, 0x12, 0x9, 0xe7, 0x7e, 0x34,
+ 0x0, 0x19, 0x12, 0x3, 0xdd, 0x74, 0x4, 0x7e, 0x34, 0x0, 0x51, 0x12, 0x9,
+ 0xe7, 0x7e, 0x34, 0xa2, 0x1c, 0x12, 0x3, 0xdd, 0x74, 0x4, 0x7e, 0x34, 0x0,
+ 0x11, 0x12, 0x9, 0xe7, 0x7e, 0x34, 0x0, 0x19, 0x12, 0x3, 0xdd, 0x74, 0x4,
+ 0x7e, 0x34, 0x0, 0x10, 0x12, 0x9, 0xe7, 0x7e, 0x34, 0x0, 0x19, 0x12, 0x3,
+ 0xdd, 0x74, 0x4, 0x6d, 0x33, 0x12, 0x9, 0xe7, 0x7e, 0x34, 0x0, 0x5, 0x12,
+ 0x3, 0xdd, 0xe4, 0x12, 0x7, 0xd5, 0x74, 0x4, 0x7e, 0x34, 0xff, 0xf7, 0x12,
+ 0x9, 0xe7, 0xda, 0xf8, 0x22, 0xca, 0x3b, 0x7f, 0x30, 0x7c, 0xb6, 0xf5, 0x12,
+ 0x7c, 0xb7, 0xf5, 0x13, 0x74, 0x1, 0x7e, 0x35, 0x10, 0x1e, 0x34, 0x1b, 0x34,
+ 0x4e, 0x60, 0x80, 0x12, 0x9, 0xe7, 0x12, 0x7, 0xd5, 0xa9, 0xc2, 0xb4, 0xa9,
+ 0xc6, 0xb3, 0x75, 0xb5, 0x2, 0xa9, 0x36, 0xb3, 0xfc, 0xa9, 0xc6, 0xb3, 0x75,
+ 0xb5, 0x0, 0xa9, 0x36, 0xb3, 0xfc, 0xa9, 0xc6, 0xb3, 0x85, 0x12, 0xb5, 0xa9,
+ 0x36, 0xb3, 0xfc, 0xa9, 0xc6, 0xb3, 0x85, 0x13, 0xb5, 0xa9, 0x36, 0xb3,
+ 0xfc, 0xa9, 0xc6, 0xb3, 0x6d, 0x33, 0x80, 0x2a, 0x7f, 0x13, 0x2e, 0x35,
+ 0x14, 0x7e, 0x1b, 0xb0, 0xf5, 0xb5, 0xa9, 0x36, 0xb3, 0xfc, 0xa9, 0xc6,
+ 0xb3, 0x7e, 0x35, 0x14, 0x5e, 0x34, 0x0, 0x1, 0xbe, 0x34, 0x0, 0x1, 0x78,
+ 0x7, 0x7e, 0x34, 0x0, 0x78, 0x12, 0x3, 0xdd, 0x7e, 0x35, 0x14, 0xb, 0x34,
+ 0x7a, 0x35, 0x14, 0x7e, 0x35, 0x10, 0xbe, 0x35, 0x14, 0x38, 0xcb, 0xa9,
+ 0xd2, 0xb4, 0x7e, 0x34, 0x0, 0x5, 0x12, 0x3, 0xdd, 0xe4, 0x12, 0x7, 0xd5,
+ 0xda, 0x3b, 0x22, 0xe5, 0x23, 0xb4, 0x80, 0x16, 0xd2, 0x7, 0x12, 0xb, 0xdd,
+ 0xa9, 0xc2, 0xb4, 0x74, 0x60, 0x12, 0xc, 0x36, 0xa9, 0xd2, 0xb4, 0x12, 0x0,
+ 0x2e, 0x40, 0xfb, 0x22, 0x74, 0x1, 0x12, 0x7, 0xd5, 0xe4, 0x6d, 0x33, 0x12,
+ 0x9, 0xe7, 0x74, 0x1, 0x6d, 0x33, 0x12, 0x9, 0xe7, 0x74, 0x4, 0x6d, 0x33,
+ 0x12, 0x9, 0xe7, 0x7e, 0x34, 0x0, 0x54, 0x12, 0x9, 0xe7, 0x7e, 0x34, 0x0,
+ 0x19, 0x12, 0x3, 0xdd, 0x74, 0x4, 0x7e, 0x34, 0x0, 0x55, 0x12, 0x9, 0xe7,
+ 0x7e, 0x34, 0xa2, 0x1c, 0x12, 0x3, 0xdd, 0x74, 0x4, 0x7e, 0x34, 0x0, 0x15,
+ 0x12, 0x9, 0xe7, 0x7e, 0x34, 0x0, 0xa0, 0x12, 0x3, 0xdd, 0x74, 0x4, 0x7e,
+ 0x34, 0x0, 0x14, 0x12, 0x9, 0xe7, 0x7e, 0x34, 0x0, 0x19, 0x12, 0x3, 0xdd,
+ 0x74, 0x4, 0x7e, 0x34, 0x0, 0x4, 0x12, 0x9, 0xe7, 0x7e, 0x34, 0x0, 0x5,
+ 0x12, 0x3, 0xdd, 0xe4, 0x12, 0x7, 0xd5, 0x74, 0x4, 0x7e, 0x34, 0xff, 0xf7,
+ 0x2, 0x9, 0xe7, 0x7c, 0x7b, 0x7e, 0xa0, 0xef, 0xe5, 0x21, 0x24, 0xfd, 0x68,
+ 0x38, 0x1b, 0xb1, 0x68, 0x22, 0x24, 0x9f, 0x68, 0x3d, 0x1b, 0xb2, 0x68,
+ 0x3e, 0x24, 0x9e, 0x68, 0x35, 0x24, 0x3c, 0x78, 0x4c, 0xa5, 0xbf, 0x0, 0x5,
+ 0x7e, 0xa0, 0x86, 0x80, 0x43, 0xa5, 0xbf, 0x1, 0x3f, 0x7e, 0xa0, 0xa6, 0x80,
+ 0x3a, 0xa5, 0xbf, 0x0, 0x5, 0x7e, 0xa1, 0x23, 0x80, 0x31, 0xa5, 0xbf, 0x1,
+ 0x2d, 0x7e, 0xa1, 0x3d, 0x80, 0x28, 0xa, 0x17, 0x7e, 0x1d, 0x39, 0x2d, 0x31,
+ 0x29, 0xa1, 0x0, 0x8, 0x80, 0x1b, 0x7e, 0xa1, 0x16, 0x80, 0x16, 0xa5, 0xbf,
+ 0x0, 0x9, 0x7e, 0x35, 0x30, 0xa, 0x56, 0x7c, 0xab, 0x80, 0x9, 0xa5, 0xbf,
+ 0x1, 0x5, 0x7e, 0x55, 0x30, 0x7c, 0xab, 0x7c, 0xba, 0x22, 0xca, 0x79, 0xbe,
+ 0xb0, 0x0, 0x28, 0x2e, 0x74, 0x6, 0x12, 0x8, 0x3d, 0x7d, 0x73, 0x6c, 0xff,
+ 0x7e, 0xf0, 0xa5, 0x7d, 0x37, 0x12, 0x9, 0xe7, 0x6c, 0xff, 0x7e, 0xf0, 0xf,
+ 0x7d, 0x37, 0x12, 0x9, 0xe7, 0x6c, 0xff, 0x7e, 0xf0, 0x6a, 0x7d, 0x37, 0x12,
+ 0x9, 0xe7, 0x7e, 0x34, 0x0, 0x5, 0x12, 0x3, 0xdd, 0x80, 0x30, 0x74, 0x1,
+ 0x7e, 0x34, 0xdf, 0xff, 0x12, 0x9, 0xe7, 0x74, 0x6, 0x12, 0x8, 0x3d, 0x7d,
+ 0x73, 0x6c, 0xff, 0x7d, 0x37, 0x12, 0x9, 0xe7, 0x7d, 0x37, 0x12, 0x9, 0xe7,
+ 0x7d, 0x37, 0x12, 0x9, 0xe7, 0x74, 0x2, 0x12, 0x8, 0x3d, 0x7d, 0x73, 0x4e,
+ 0xf0, 0x1, 0x7d, 0x37, 0x12, 0x9, 0xe7, 0xda, 0x79, 0x22, 0xa9, 0xc2, 0xb4,
+ 0xa9, 0xc6, 0xb3, 0x75, 0xb5, 0x5, 0xa9, 0x36, 0xb3, 0xfc, 0xa9, 0xc6, 0xb3,
+ 0x75, 0xb5, 0x0, 0xa9, 0x36, 0xb3, 0xfc, 0xa9, 0xc6, 0xb3, 0x75, 0xb5, 0x0,
+ 0xa9, 0x36, 0xb3, 0xfc, 0xa9, 0xc6, 0xb3, 0xf5, 0xb5, 0xa9, 0x36, 0xb3,
+ 0xfc, 0xa9, 0xc6, 0xb3, 0x75, 0xb5, 0x0, 0xa9, 0x36, 0xb3, 0xfc, 0xa9, 0xc6,
+ 0xb3, 0x75, 0xb5, 0x0, 0xa9, 0x36, 0xb3, 0xfc, 0xa9, 0xc6, 0xb3, 0x7e, 0x71,
+ 0xb5, 0x75, 0xb5, 0x0, 0xa9, 0x36, 0xb3, 0xfc, 0xa9, 0xc6, 0xb3, 0x7e, 0xa1,
+ 0xb5, 0xa9, 0xd2, 0xb4, 0x7c, 0x47, 0x6c, 0x55, 0xa, 0x3a, 0x4d, 0x32, 0x22,
+ 0xca, 0xf8, 0x7e, 0xf0, 0x70, 0x75, 0x91, 0x0, 0xc2, 0x90, 0xc2, 0x91, 0x20,
+ 0x87, 0x3, 0x7e, 0xf1, 0xe4, 0x30, 0x6, 0x30, 0x7e, 0x34, 0x0, 0x2, 0x7a,
+ 0x35, 0x11, 0x7e, 0x18, 0x7, 0x80, 0x7e, 0x8, 0x0, 0x8, 0x12, 0xc, 0x1,
+ 0xe5, 0x8, 0xbe, 0xb0, 0xff, 0x68, 0x17, 0xe5, 0x8, 0x60, 0x13, 0xe5, 0x9,
+ 0xa, 0x2b, 0xe5, 0x8, 0xa, 0x3b, 0x2d, 0x32, 0xbe, 0x34, 0x0, 0xff, 0x78,
+ 0x3, 0x7e, 0xf1, 0x8, 0x5e, 0xf0, 0xfe, 0x7a, 0xf1, 0x92, 0xd2, 0xe8, 0xc2,
+ 0xc0, 0xa9, 0xd5, 0xb7, 0xd2, 0xbd, 0xd2, 0xad, 0xda, 0xf8, 0x22, 0x7f,
+ 0x70, 0xd2, 0x7, 0x12, 0xb, 0xdd, 0x74, 0x2, 0x12, 0xb, 0x44, 0x6d, 0x33,
+ 0x80, 0x12, 0x7f, 0x7, 0x2d, 0x13, 0x7e, 0xb, 0xb0, 0xf5, 0xb5, 0xa9, 0x36,
+ 0xb3, 0xfc, 0xa9, 0xc6, 0xb3, 0xb, 0x34, 0x7e, 0x25, 0x10, 0xbd, 0x23, 0x38,
+ 0xe7, 0xa9, 0xd2, 0xb4, 0x12, 0xc, 0x41, 0x12, 0x0, 0x2e, 0x50, 0x9, 0x7e,
+ 0x35, 0x17, 0xbe, 0x34, 0x1, 0xf4, 0x28, 0xf2, 0x7e, 0x35, 0x17, 0xbe, 0x34,
+ 0x1, 0xf4, 0x38, 0x3, 0x2, 0xc, 0x5c, 0xc2, 0x86, 0x7e, 0x34, 0x13, 0x88,
+ 0x12, 0x3, 0xdd, 0xd2, 0x86, 0x22, 0x6d, 0x0, 0x74, 0x10, 0x4d, 0x0, 0x78,
+ 0xb, 0x4d, 0x22, 0x78, 0x27, 0x8d, 0x31, 0x7d, 0x12, 0x6d, 0x22, 0x22, 0x7d,
+ 0x43, 0x7d, 0x32, 0x6d, 0x22, 0x2f, 0x11, 0x2d, 0x44, 0x50, 0x2, 0xa5, 0xf,
+ 0xbf, 0x10, 0x40, 0x4, 0x9f, 0x10, 0xb, 0x90, 0x14, 0x78, 0xed, 0x7f, 0x1,
+ 0x6d, 0x22, 0x7d, 0x34, 0x22, 0x7d, 0x41, 0x7d, 0x13, 0x8d, 0x24, 0x7d, 0x2,
+ 0x2f, 0x0, 0x40, 0x4, 0xbd, 0x4, 0x40, 0x4, 0x9d, 0x4, 0xb, 0x14, 0x14,
+ 0x78, 0xf1, 0x7d, 0x23, 0x7d, 0x31, 0x7d, 0x10, 0x6d, 0x0, 0x22, 0x75, 0x84,
+ 0x1, 0x7e, 0x44, 0x1f, 0xff, 0xe4, 0x7a, 0x49, 0xb0, 0x1b, 0x44, 0x78, 0xf9,
+ 0x7e, 0xf8, 0x2, 0xd5, 0xd2, 0x5, 0xc2, 0x6, 0x75, 0x16, 0x0, 0x75, 0x17,
+ 0x0, 0x75, 0x18, 0x0, 0xd2, 0x0, 0xc2, 0x2, 0xc2, 0x3, 0xc2, 0x4, 0x75,
+ 0x21, 0x0, 0x75, 0x22, 0x0, 0x75, 0x23, 0x80, 0x75, 0x2e, 0x0, 0x75, 0x2f,
+ 0x0, 0x75, 0x30, 0x0, 0x75, 0x31, 0x0, 0x75, 0x32, 0x0, 0x75, 0x37, 0xb,
+ 0x75, 0x38, 0x0, 0x75, 0x3d, 0x1, 0x2, 0x4, 0x20, 0x7d, 0x23, 0xa, 0x36,
+ 0x7c, 0xa5, 0xa9, 0xc2, 0xb4, 0xa9, 0xc6, 0xb3, 0x75, 0xb5, 0x1, 0xa9, 0x36,
+ 0xb3, 0xfc, 0xa9, 0xc6, 0xb3, 0x75, 0xb5, 0x0, 0xa9, 0x36, 0xb3, 0xfc, 0xa9,
+ 0xc6, 0xb3, 0x75, 0xb5, 0x0, 0xa9, 0x36, 0xb3, 0xfc, 0xa9, 0xc6, 0xb3, 0xf5,
+ 0xb5, 0xa9, 0x36, 0xb3, 0xfc, 0xa9, 0xc6, 0xb3, 0x7a, 0x71, 0xb5, 0xa9,
+ 0x36, 0xb3, 0xfc, 0xa9, 0xc6, 0xb3, 0x7a, 0xa1, 0xb5, 0xa9, 0x36, 0xb3,
+ 0xfc, 0xa9, 0xc6, 0xb3, 0xa9, 0xd2, 0xb4, 0x22, 0x7c, 0xab, 0xd2, 0x7, 0x12,
+ 0xb, 0xdd, 0x74, 0xd8, 0xa, 0x3a, 0x7d, 0x23, 0x6d, 0x33, 0x12, 0xb, 0x44,
+ 0xa9, 0xd2, 0xb4, 0x12, 0xc, 0x41, 0x12, 0x0, 0x2e, 0x50, 0x9, 0x7e, 0x35,
+ 0x17, 0xbe, 0x34, 0x5, 0xdc, 0x28, 0xf2, 0x7e, 0x35, 0x17, 0xbe, 0x34, 0x5,
+ 0xdc, 0x38, 0x3, 0x2, 0xc, 0x5c, 0xc2, 0x86, 0x7e, 0x34, 0x13, 0x88, 0x12,
+ 0x3, 0xdd, 0xd2, 0x86, 0x22, 0xca, 0x2b, 0xca, 0x1b, 0xca, 0xb, 0xd2, 0x0,
+ 0x30, 0x90, 0x1c, 0xc2, 0x90, 0x7e, 0x71, 0x91, 0xe5, 0x38, 0x70, 0x3, 0x7a,
+ 0x71, 0x21, 0xe5, 0x38, 0x12, 0x1, 0x20, 0x5, 0x38, 0x30, 0x2, 0x6, 0xe4,
+ 0x12, 0x7, 0x67, 0xf5, 0x91, 0x30, 0x91, 0xb, 0xc2, 0x91, 0x5, 0x38, 0xe5,
+ 0x38, 0x12, 0x7, 0x67, 0xf5, 0x91, 0xda, 0xb, 0xda, 0x1b, 0xda, 0x2b, 0x32,
+ 0xca, 0xf8, 0x7c, 0xfb, 0xe5, 0x23, 0xb4, 0x81, 0x23, 0x74, 0x2, 0x12, 0x8,
+ 0x3d, 0x4c, 0xff, 0x78, 0x8, 0xa9, 0xc0, 0xca, 0x5e, 0x70, 0xdf, 0x80, 0x6,
+ 0xa9, 0xd0, 0xca, 0x4e, 0x70, 0x20, 0x74, 0x2, 0x12, 0x9, 0xe7, 0x74, 0x2,
+ 0x12, 0x8, 0x3d, 0x80, 0x8, 0xe5, 0x23, 0xb4, 0x80, 0x3, 0x12, 0xb, 0x16,
+ 0xda, 0xf8, 0x22, 0xd2, 0x7, 0x12, 0xb, 0xdd, 0xa9, 0xc2, 0xb4, 0x74, 0x9f,
+ 0x12, 0xc, 0x36, 0x12, 0xc, 0x1d, 0xa9, 0xd2, 0xb4, 0x60, 0x3, 0xb4, 0xff,
+ 0x1a, 0x75, 0x23, 0x81, 0xa9, 0xd5, 0xca, 0xa9, 0xd0, 0xca, 0x75, 0xed,
+ 0x9f, 0x75, 0xad, 0x20, 0xa9, 0xd1, 0xea, 0xa9, 0xc1, 0xea, 0x74, 0x1, 0x2,
+ 0xa, 0xac, 0x22, 0xd2, 0x7, 0x12, 0xb, 0xdd, 0xa9, 0xc2, 0xb4, 0x74, 0x5,
+ 0x12, 0xc, 0x36, 0x12, 0xc, 0x1d, 0x7c, 0xab, 0xa9, 0xd2, 0xb4, 0x5e, 0xa0,
+ 0xe3, 0xa9, 0xc2, 0xb4, 0x74, 0x1, 0x12, 0xc, 0x36, 0x7c, 0xba, 0x12, 0xc,
+ 0x36, 0xa9, 0xd2, 0xb4, 0x12, 0x0, 0x2e, 0x40, 0xfb, 0x22, 0x7c, 0xab, 0x7d,
+ 0x12, 0x7c, 0xb3, 0xf5, 0x14, 0x7c, 0x36, 0x7c, 0x25, 0xa, 0x4, 0x7c, 0xb3,
+ 0xf5, 0x13, 0x7c, 0xb7, 0xf5, 0x12, 0xa9, 0xc2, 0xb4, 0x7c, 0xba, 0x12, 0xc,
+ 0x36, 0xe5, 0x14, 0x12, 0xc, 0x36, 0xe5, 0x13, 0x12, 0xc, 0x36, 0xe5, 0x12,
+ 0x2, 0xc, 0x36, 0x7d, 0x52, 0xf5, 0x15, 0x7c, 0xb6, 0x7c, 0xa5, 0xa, 0x44,
+ 0xf5, 0x14, 0x7f, 0x21, 0xf5, 0x13, 0xa9, 0xc2, 0xb4, 0x74, 0xb, 0x12, 0xc,
+ 0x36, 0xe5, 0x15, 0x12, 0xc, 0x36, 0xe5, 0x14, 0x12, 0xc, 0x36, 0xe5, 0x13,
+ 0x12, 0xc, 0x36, 0xe4, 0x2, 0xc, 0x36, 0xd2, 0xcf, 0x85, 0x3d, 0xcc, 0x75,
+ 0xec, 0xff, 0x75, 0xee, 0xff, 0x75, 0xeb, 0x3, 0x75, 0xac, 0x40, 0xa9, 0xc5,
+ 0xca, 0x75, 0xed, 0xf, 0x75, 0xad, 0xb0, 0xa9, 0xd7, 0x94, 0xa9, 0xd4, 0x94,
+ 0x22, 0x12, 0xb, 0x9c, 0xa9, 0xa6, 0x94, 0xb3, 0x92, 0x6, 0x30, 0x6, 0x6,
+ 0x12, 0xc, 0x2a, 0x12, 0xa, 0xe3, 0x12, 0x8, 0x9a, 0x12, 0xc, 0xf, 0xd2,
+ 0xaf, 0x30, 0x3, 0xfd, 0x2, 0xc, 0x54, 0xa9, 0xc2, 0xb4, 0x30, 0x7, 0x4,
+ 0x74, 0x6, 0x80, 0x2, 0x74, 0x4, 0x12, 0xc, 0x36, 0xa9, 0xd2, 0xb4, 0x22,
+ 0xe5, 0x32, 0xb4, 0xc, 0xb, 0xc2, 0x86, 0x7e, 0x34, 0x0, 0x64, 0x12, 0x3,
+ 0xdd, 0xd2, 0x86, 0x22, 0x12, 0xb, 0x71, 0x7e, 0x35, 0x11, 0x12, 0x0, 0xe,
+ 0xa9, 0xd2, 0xb4, 0xd3, 0x22, 0xc2, 0x8c, 0x43, 0x89, 0x2, 0x75, 0x8c, 0x1,
+ 0x75, 0x8a, 0x0, 0xd2, 0xa9, 0x22, 0x75, 0xb5, 0x0, 0xa9, 0x36, 0xb3, 0xfc,
+ 0xa9, 0xc6, 0xb3, 0xe5, 0xb5, 0x22, 0xd2, 0xc8, 0x75, 0xb3, 0x13, 0xa9,
+ 0xd1, 0xb4, 0xa9, 0xc0, 0xb4, 0x22, 0xf5, 0xb5, 0xa9, 0x36, 0xb3, 0xfc,
+ 0xa9, 0xc6, 0xb3, 0xd3, 0x22, 0xc2, 0x8c, 0x6d, 0x33, 0x7a, 0x35, 0x17,
+ 0xd2, 0x8c, 0x22, 0x7e, 0x35, 0x17, 0xb, 0x34, 0x7a, 0x35, 0x17, 0x22, 0x85,
+ 0x3d, 0xcc, 0xe5, 0x3d, 0x2, 0xa, 0xac, 0x2, 0xc, 0x4b, 0xff,
diff --git a/drivers/input/touchscreen/focaltech_touch/include/pramboot/FT8607_Pramboot_V0.3_20160727.i b/drivers/input/touchscreen/focaltech_touch/include/pramboot/FT8607_Pramboot_V0.3_20160727.i
new file mode 100644
index 000000000000..ebb31f1ebc7c
--- /dev/null
+++ b/drivers/input/touchscreen/focaltech_touch/include/pramboot/FT8607_Pramboot_V0.3_20160727.i
@@ -0,0 +1,248 @@
+0x2, 0x9, 0xb2, 0xca, 0x39, 0x12, 0xc, 0x71, 0xda, 0x39, 0x32, 0x2, 0x0, 0x3,
+ 0x6d, 0x22, 0x80, 0x13, 0x75, 0xb5, 0x0, 0xa9, 0x36, 0xb3, 0xfc, 0xa9, 0xc6,
+ 0xb3, 0xe5, 0xb5, 0x7a, 0xb, 0xb0, 0xb, 0x14, 0xb, 0x24, 0xbd, 0x32, 0x38,
+ 0xe9, 0x22, 0xff, 0x2, 0xa, 0x87, 0xa9, 0xc2, 0xb4, 0x74, 0x5, 0x12, 0xc,
+ 0x5c, 0x12, 0xc, 0x43, 0xa9, 0xd2, 0xb4, 0x30, 0xe0, 0x2, 0xd3, 0x22, 0xc3,
+ 0x22, 0x2, 0x0, 0xf9, 0xca, 0x3b, 0x7a, 0xd, 0x8, 0x7f, 0x31, 0xe5, 0x23,
+ 0xb4, 0x80, 0x2, 0x80, 0x3, 0x2, 0x0, 0xdc, 0x7f, 0x13, 0x5e, 0x34, 0x0,
+ 0x7f, 0x7d, 0x23, 0x7e, 0x34, 0x0, 0x80, 0x9d, 0x32, 0x7a, 0x35, 0xe, 0x7e,
+ 0x35, 0xc, 0xbe, 0x35, 0xe, 0x38, 0x2, 0x80, 0x5d, 0x7e, 0x35, 0xe, 0x7a,
+ 0x35, 0x10, 0x7f, 0x13, 0x7e, 0xd, 0x8, 0x12, 0x9, 0xa, 0x7e, 0x35, 0xc,
+ 0x9e, 0x35, 0xe, 0x7a, 0x35, 0xc, 0x7e, 0x35, 0xe, 0x6d, 0x22, 0x2f, 0x31,
+ 0x7e, 0x1d, 0x8, 0x2e, 0x35, 0xe, 0x7a, 0x1d, 0x8, 0x80, 0x27, 0x7e, 0x34,
+ 0x0, 0x80, 0x7a, 0x35, 0x10, 0x7f, 0x13, 0x7e, 0xd, 0x8, 0x12, 0x9, 0xa,
+ 0x7e, 0x35, 0xc, 0x9e, 0x34, 0x0, 0x80, 0x7a, 0x35, 0xc, 0x7e, 0x1d, 0x8,
+ 0x2e, 0x34, 0x0, 0x80, 0x7a, 0x1d, 0x8, 0x2e, 0x38, 0x0, 0x80, 0x7e, 0x35,
+ 0xc, 0xbe, 0x34, 0x0, 0x80, 0x50, 0xd0, 0x4d, 0x33, 0x68, 0x26, 0x7a, 0x35,
+ 0x10, 0x7f, 0x13, 0x7e, 0xd, 0x8, 0x12, 0x9, 0xa, 0x80, 0x19, 0x74, 0x2,
+ 0x12, 0x8, 0xad, 0x5e, 0x70, 0xf4, 0x12, 0x9, 0xfe, 0x7e, 0x35, 0xc, 0x7a,
+ 0x35, 0x10, 0x7f, 0x13, 0x7e, 0xd, 0x8, 0x12, 0x6, 0x42, 0xd3, 0xda, 0x3b,
+ 0x22, 0xa9, 0xc0, 0x93, 0x75, 0x38, 0x0, 0x32, 0xc, 0x86, 0xf3, 0x79, 0x96,
+ 0x69, 0x34, 0xcb, 0xff, 0x0, 0xff, 0x0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0x7c, 0x6b, 0xc2, 0x2, 0xe5, 0x21, 0x14, 0x78, 0x3, 0x2, 0x2,
+ 0xcd, 0x1b, 0xb1, 0x78, 0x3, 0x2, 0x2, 0x30, 0x1b, 0xb1, 0x78, 0x3, 0x2,
+ 0x2, 0x7c, 0x1b, 0xb1, 0x78, 0x3, 0x2, 0x2, 0x8d, 0x1b, 0xb1, 0x78, 0x3,
+ 0x2, 0x2, 0xb4, 0x24, 0xf9, 0x78, 0x3, 0x2, 0x2, 0xc9, 0x24, 0xaf, 0x78,
+ 0x3, 0x2, 0x3, 0x37, 0x24, 0xfd, 0x68, 0x2d, 0x14, 0x78, 0x3, 0x2, 0x2,
+ 0xd0, 0x14, 0x78, 0x3, 0x2, 0x2, 0xcd, 0x1b, 0xb2, 0x78, 0x3, 0x2, 0x2,
+ 0xcd, 0x24, 0xda, 0x68, 0x19, 0x24, 0xe6, 0x68, 0x12, 0x24, 0xeb, 0x68,
+ 0x2e, 0x24, 0xf3, 0x78, 0x3, 0x2, 0x2, 0xcd, 0x24, 0x77, 0x68, 0x3, 0x2,
+ 0x3, 0x41, 0x2, 0x3, 0x3e, 0xbe, 0x60, 0x4, 0x50, 0xc, 0x75, 0x16, 0x0,
+ 0x7c, 0x16, 0x2e, 0x10, 0x24, 0x7c, 0xb7, 0xa5, 0xf7, 0xa5, 0xbe, 0x0, 0x2,
+ 0x80, 0x3, 0x2, 0x3, 0x41, 0xd2, 0x2, 0x22, 0x7c, 0xb6, 0x24, 0x0, 0x78,
+ 0x3, 0x2, 0x3, 0x41, 0x1b, 0xb1, 0x68, 0x1e, 0x14, 0x68, 0x1e, 0x14, 0x68,
+ 0x1e, 0x14, 0x68, 0x1e, 0xb, 0xb2, 0x78, 0x33, 0x30, 0x1, 0x7, 0x7e, 0x8,
+ 0x0, 0x3e, 0x2, 0x2, 0x4d, 0x7e, 0x8, 0x1, 0x4a, 0x2, 0x2, 0x4d, 0x2, 0x2,
+ 0xf5, 0x2, 0x2, 0xfc, 0x2, 0x3, 0x14, 0xa, 0x27, 0x7e, 0xd, 0x39, 0xb, 0x16,
+ 0xb, 0xa, 0x30, 0x2d, 0x32, 0x1b, 0xa, 0x30, 0x6d, 0x33, 0x7e, 0xd, 0x39,
+ 0x79, 0x30, 0x0, 0x6, 0x22, 0x7c, 0xb7, 0x62, 0x16, 0x7e, 0x2d, 0x39, 0x2e,
+ 0x54, 0x0, 0x6, 0xb, 0x2a, 0x20, 0x7d, 0x12, 0xb, 0x14, 0x1b, 0x2a, 0x10,
+ 0x7e, 0xd, 0x39, 0x2d, 0x12, 0x39, 0x70, 0x0, 0x8, 0x7e, 0xd, 0x39, 0x69,
+ 0x50, 0x0, 0x4, 0x69, 0x20, 0x0, 0x6, 0xbd, 0x25, 0x50, 0x3, 0x2, 0x3, 0x41,
+ 0xb2, 0x1, 0x7a, 0xd, 0x33, 0x7e, 0x34, 0x0, 0x2, 0x2, 0x3, 0x33, 0x7c,
+ 0xb6, 0x1b, 0xb1, 0x68, 0x1d, 0x14, 0x68, 0x1d, 0xb, 0xb1, 0x68, 0x3, 0x2,
+ 0x3, 0x41, 0x30, 0x1, 0x6, 0x7e, 0x8, 0x0, 0x3e, 0x80, 0x4, 0x7e, 0x8, 0x1,
+ 0x4a, 0x7a, 0xd, 0x39, 0x2, 0x2, 0xe4, 0x2, 0x2, 0xf5, 0xa, 0x57, 0x6d,
+ 0x44, 0x7e, 0xd, 0x39, 0x69, 0x30, 0x0, 0x2, 0xb, 0xa, 0x20, 0x2f, 0x12,
+ 0x79, 0x30, 0x0, 0x2, 0x1b, 0xa, 0x20, 0x7e, 0x1d, 0x39, 0x7a, 0x1d, 0x33,
+ 0xd2, 0x2, 0x7e, 0x34, 0x0, 0x1, 0x2, 0x3, 0x33, 0xbe, 0x60, 0x1, 0x68, 0x9,
+ 0xa5, 0xbe, 0x2, 0x5, 0x7a, 0x71, 0x3d, 0xd2, 0x3, 0xd2, 0x2, 0x22, 0x75,
+ 0xe6, 0x0, 0xe4, 0x7e, 0x34, 0x1, 0x4, 0x7e, 0x24, 0x0, 0xff, 0x7a, 0x1b,
+ 0xb0, 0x7e, 0x34, 0x1, 0x5, 0x7a, 0x1b, 0xb0, 0x7e, 0x34, 0x1, 0x8, 0x7a,
+ 0x1b, 0xb0, 0x7e, 0x34, 0x1, 0x9, 0x7a, 0x1b, 0xb0, 0xd2, 0x4, 0x22, 0xa5,
+ 0xbe, 0x1, 0x4, 0x7a, 0x71, 0x37, 0x22, 0xa5, 0xbe, 0x2, 0x2, 0x80, 0x3,
+ 0x2, 0x3, 0x41, 0x7a, 0x71, 0x22, 0x22, 0x7a, 0x71, 0x32, 0x22, 0xd2, 0x2,
+ 0x22, 0x1b, 0x61, 0x68, 0x21, 0x1b, 0x60, 0x68, 0x24, 0x1b, 0x60, 0x68,
+ 0x38, 0x1b, 0x60, 0x68, 0x40, 0xb, 0x62, 0x78, 0x5d, 0xa, 0x37, 0x7d, 0x3,
+ 0x6d, 0x11, 0x7e, 0x1d, 0x39, 0x79, 0x11, 0x0, 0x2, 0x1b, 0x1a, 0x0, 0x22,
+ 0xa, 0x57, 0x7c, 0xab, 0xe4, 0x80, 0x2, 0xa, 0x57, 0x6d, 0x44, 0x7e, 0xd,
+ 0x39, 0x69, 0x30, 0x0, 0x2, 0xb, 0xa, 0x20, 0x2f, 0x12, 0x79, 0x30, 0x0,
+ 0x2, 0x1b, 0xa, 0x20, 0x22, 0x7c, 0x67, 0x6c, 0x77, 0x7e, 0xd, 0x39, 0x79,
+ 0x30, 0x0, 0x4, 0x22, 0xa, 0x27, 0x7e, 0xd, 0x39, 0xb, 0x16, 0xb, 0xa, 0x30,
+ 0x2d, 0x32, 0x1b, 0xa, 0x30, 0x7e, 0x34, 0x0, 0x3, 0x7a, 0x35, 0x2e, 0x22,
+ 0x7e, 0x34, 0x0, 0x4, 0x7a, 0x35, 0x2e, 0x75, 0x16, 0x0, 0x22, 0xca, 0x3b,
+ 0x7a, 0x15, 0x8, 0x7f, 0x31, 0x75, 0xe, 0x0, 0x7e, 0x35, 0x8, 0xbe, 0x34,
+ 0x0, 0x0, 0x38, 0x4f, 0x7e, 0x34, 0xff, 0xff, 0x7a, 0x35, 0x8, 0x75, 0xe,
+ 0x1, 0x80, 0x43, 0x7e, 0x34, 0x0, 0x80, 0x7a, 0x35, 0x11, 0x7f, 0x13, 0x7e,
+ 0x8, 0x2, 0x56, 0x12, 0xc, 0x27, 0x7e, 0x35, 0x8, 0x9e, 0x34, 0x0, 0x80,
+ 0x7a, 0x35, 0x8, 0x2e, 0x38, 0x0, 0x80, 0x6d, 0x33, 0x7a, 0x35, 0xf, 0x7e,
+ 0x35, 0xf, 0x9, 0x63, 0x2, 0x56, 0x7e, 0xd, 0xa, 0x7e, 0xb, 0x70, 0x6c,
+ 0x76, 0x7a, 0xb, 0x70, 0x7e, 0x35, 0xf, 0xb, 0x34, 0x7a, 0x35, 0xf, 0xbe,
+ 0x34, 0x0, 0x80, 0x78, 0xe0, 0x7e, 0x35, 0x8, 0xbe, 0x34, 0x0, 0x80, 0x38,
+ 0xb4, 0xe5, 0xe, 0x60, 0x5, 0xb, 0x34, 0x7a, 0x35, 0x8, 0x7e, 0x35, 0x8,
+ 0x7a, 0x35, 0x11, 0x7f, 0x13, 0x7e, 0x8, 0x2, 0x56, 0x12, 0xc, 0x27, 0x6d,
+ 0x33, 0x80, 0x17, 0x7e, 0x35, 0xf, 0x9, 0x63, 0x2, 0x56, 0x7e, 0xd, 0xa,
+ 0x7e, 0xb, 0x70, 0x6c, 0x76, 0x7a, 0xb, 0x70, 0x7e, 0x35, 0xf, 0xb, 0x34,
+ 0x7a, 0x35, 0xf, 0x7e, 0x35, 0x8, 0xbe, 0x35, 0xf, 0x38, 0xde, 0xda, 0x3b,
+ 0x22, 0xe5, 0x32, 0xb4, 0xc, 0xb, 0xc2, 0x86, 0x7e, 0x34, 0x0, 0x64, 0x12,
+ 0xb, 0xb0, 0xd2, 0x86, 0x22, 0xff, 0x56, 0x30, 0x2e, 0x33, 0x4a, 0x75, 0x6c,
+ 0x20, 0x32, 0x37, 0x20, 0x32, 0x30, 0x31, 0x36, 0x0, 0x46, 0x54, 0x53, 0x38,
+ 0x36, 0x30, 0x37, 0x5f, 0x70, 0x72, 0x61, 0x6d, 0x62, 0x6f, 0x6f, 0x74,
+ 0x12, 0xb, 0xf4, 0x2, 0x5, 0x66, 0x7e, 0x35, 0x2e, 0x1b, 0x34, 0x68, 0x57,
+ 0x1b, 0x35, 0x78, 0x3, 0x2, 0x4, 0xb3, 0x1b, 0x34, 0x78, 0x3, 0x2, 0x4,
+ 0xdd, 0xb, 0x35, 0x68, 0x3, 0x2, 0x5, 0x52, 0x6d, 0x33, 0x7a, 0x35, 0x2e,
+ 0x7a, 0x35, 0x30, 0x30, 0x5, 0x5, 0x12, 0x3, 0xee, 0xc2, 0x5, 0x7e, 0xd,
+ 0x33, 0x69, 0x30, 0x0, 0x4, 0x7a, 0x35, 0xc, 0x69, 0x30, 0x0, 0x2, 0xb, 0xa,
+ 0x20, 0x2e, 0x14, 0x0, 0x8, 0x12, 0x0, 0x46, 0xd2, 0x5, 0x7e, 0x2d, 0x33,
+ 0x69, 0x12, 0x0, 0x4, 0x69, 0x32, 0x0, 0x2, 0xb, 0x2a, 0x20, 0x12, 0x9,
+ 0x5f, 0x2e, 0x34, 0x10, 0x0, 0x2, 0x5, 0x4f, 0x6d, 0x33, 0x7a, 0x35, 0x2e,
+ 0x7e, 0x34, 0x1, 0x0, 0x7a, 0x35, 0x11, 0x7e, 0xd, 0x33, 0x69, 0x30, 0x0,
+ 0x2, 0xb, 0xa, 0x20, 0x2e, 0x14, 0x0, 0x8, 0x12, 0xc, 0x27, 0x20, 0x0, 0x3,
+ 0x2, 0x5, 0x52, 0x7e, 0x1d, 0x33, 0x29, 0xb1, 0x0, 0x8, 0xf5, 0x91, 0x2,
+ 0x5, 0x52, 0x6d, 0x33, 0x7a, 0x35, 0x2e, 0x7a, 0x35, 0x30, 0x7e, 0x18, 0x0,
+ 0x16, 0x7a, 0x1d, 0xa, 0x7e, 0xd, 0x33, 0x69, 0x30, 0x0, 0x2, 0xb, 0xa,
+ 0x20, 0x69, 0x10, 0x0, 0x4, 0x12, 0x3, 0x42, 0x12, 0x3, 0xee, 0x7e, 0x34,
+ 0xf0, 0x55, 0x2, 0x5, 0x4f, 0x6d, 0x33, 0x7a, 0x35, 0x2e, 0x7a, 0x35, 0x30,
+ 0xe5, 0x37, 0xb4, 0xa, 0x15, 0xe5, 0x23, 0xb4, 0x80, 0xb, 0xe4, 0x12, 0xa,
+ 0x49, 0x74, 0x1, 0x12, 0xa, 0x49, 0x80, 0x4e, 0x12, 0x6, 0xd8, 0x80, 0x49,
+ 0xe5, 0x37, 0xb4, 0xb, 0x27, 0xe5, 0x23, 0xb4, 0x80, 0x11, 0x7e, 0xf0, 0x1,
+ 0x7c, 0xbf, 0x12, 0x5, 0x6d, 0xb, 0xf0, 0xbe, 0xf0, 0x11, 0x78, 0xf4, 0x80,
+ 0x2e, 0x7e, 0xf0, 0x4, 0x7c, 0xbf, 0x12, 0x5, 0x6d, 0xb, 0xf0, 0xbe, 0xf0,
+ 0x40, 0x78, 0xf4, 0x80, 0x1d, 0xe5, 0x37, 0xa, 0x3b, 0x9e, 0x34, 0x0, 0x80,
+ 0x7c, 0xe7, 0x6c, 0xdd, 0x80, 0x9, 0x7c, 0xbe, 0x12, 0x5, 0x6d, 0xb, 0xe0,
+ 0xb, 0xd0, 0xe5, 0x22, 0xbc, 0xbd, 0x38, 0xf1, 0x12, 0x3, 0xee, 0x7e, 0x34,
+ 0xf0, 0xaa, 0x7a, 0x35, 0x30, 0x30, 0x4, 0x11, 0x7e, 0x34, 0x13, 0x88, 0x12,
+ 0xb, 0xb0, 0x7e, 0x34, 0x13, 0x88, 0x12, 0xb, 0xb0, 0x75, 0xe9, 0xff, 0x30,
+ 0x6, 0x3, 0x2, 0x4, 0x26, 0x22, 0xca, 0xf8, 0x7c, 0xfb, 0xe5, 0x23, 0xb4,
+ 0x80, 0x4a, 0xd2, 0x7, 0x12, 0xc, 0x14, 0x74, 0x20, 0xca, 0xb8, 0xa, 0x3f,
+ 0x6d, 0x22, 0x74, 0xc, 0x2f, 0x11, 0x14, 0x78, 0xfb, 0xda, 0xb8, 0x12, 0xb,
+ 0x2b, 0xa9, 0xd2, 0xb4, 0x12, 0xc, 0x67, 0x12, 0x0, 0x2e, 0x50, 0x9, 0x7e,
+ 0x35, 0x17, 0xbe, 0x34, 0x1, 0xf4, 0x28, 0xf2, 0x7e, 0x35, 0x17, 0xbe, 0x34,
+ 0x1, 0xf4, 0x38, 0x6, 0x12, 0xc, 0x82, 0x2, 0x6, 0x3f, 0xc2, 0x86, 0x7e,
+ 0x34, 0x13, 0x88, 0x12, 0xb, 0xb0, 0xd2, 0x86, 0x2, 0x6, 0x3f, 0x74, 0x1,
+ 0x12, 0x8, 0x45, 0x74, 0x1, 0x6d, 0x33, 0x12, 0x9, 0xfe, 0xe4, 0x12, 0x8,
+ 0xad, 0x5e, 0x34, 0x80, 0x0, 0x7c, 0x4f, 0x6c, 0x55, 0x3e, 0x24, 0x4d, 0x32,
+ 0x12, 0x9, 0xfe, 0x74, 0x4, 0x6d, 0x33, 0x12, 0x9, 0xfe, 0x7e, 0x34, 0x0,
+ 0x50, 0x12, 0x9, 0xfe, 0x7e, 0x34, 0x0, 0x19, 0x12, 0xb, 0xb0, 0x74, 0x4,
+ 0x7e, 0x34, 0x0, 0x51, 0x12, 0x9, 0xfe, 0x7e, 0x34, 0xa2, 0x1c, 0x12, 0xb,
+ 0xb0, 0x74, 0x4, 0x7e, 0x34, 0x0, 0x11, 0x12, 0x9, 0xfe, 0x7e, 0x34, 0x0,
+ 0x19, 0x12, 0xb, 0xb0, 0x74, 0x4, 0x7e, 0x34, 0x0, 0x10, 0x12, 0x9, 0xfe,
+ 0x7e, 0x34, 0x0, 0x19, 0x12, 0xb, 0xb0, 0x74, 0x4, 0x6d, 0x33, 0x12, 0x9,
+ 0xfe, 0x7e, 0x34, 0x0, 0x5, 0x12, 0xb, 0xb0, 0xe4, 0x12, 0x8, 0x45, 0x74,
+ 0x4, 0x7e, 0x34, 0xff, 0xf7, 0x12, 0x9, 0xfe, 0xda, 0xf8, 0x22, 0xca, 0x3b,
+ 0x7f, 0x30, 0x7c, 0xb6, 0xf5, 0x12, 0x7c, 0xb7, 0xf5, 0x13, 0x74, 0x1, 0x7e,
+ 0x35, 0x10, 0x1e, 0x34, 0x1b, 0x34, 0x4e, 0x60, 0x80, 0x12, 0x9, 0xfe, 0x12,
+ 0x8, 0x45, 0xa9, 0xc2, 0xb4, 0xa9, 0xc6, 0xb3, 0x75, 0xb5, 0x2, 0xa9, 0x36,
+ 0xb3, 0xfc, 0xa9, 0xc6, 0xb3, 0x75, 0xb5, 0x0, 0xa9, 0x36, 0xb3, 0xfc, 0xa9,
+ 0xc6, 0xb3, 0x85, 0x12, 0xb5, 0xa9, 0x36, 0xb3, 0xfc, 0xa9, 0xc6, 0xb3,
+ 0x85, 0x13, 0xb5, 0xa9, 0x36, 0xb3, 0xfc, 0xa9, 0xc6, 0xb3, 0x6d, 0x33,
+ 0x80, 0x2a, 0x7f, 0x13, 0x2e, 0x35, 0x14, 0x7e, 0x1b, 0xb0, 0xf5, 0xb5,
+ 0xa9, 0x36, 0xb3, 0xfc, 0xa9, 0xc6, 0xb3, 0x7e, 0x35, 0x14, 0x5e, 0x34, 0x0,
+ 0x1, 0xbe, 0x34, 0x0, 0x1, 0x78, 0x7, 0x7e, 0x34, 0x0, 0x78, 0x12, 0xb,
+ 0xb0, 0x7e, 0x35, 0x14, 0xb, 0x34, 0x7a, 0x35, 0x14, 0x7e, 0x35, 0x10, 0xbe,
+ 0x35, 0x14, 0x38, 0xcb, 0xa9, 0xd2, 0xb4, 0x7e, 0x34, 0x0, 0x5, 0x12, 0xb,
+ 0xb0, 0xe4, 0x12, 0x8, 0x45, 0xda, 0x3b, 0x22, 0xe5, 0x23, 0xb4, 0x80, 0x16,
+ 0xd2, 0x7, 0x12, 0xc, 0x14, 0xa9, 0xc2, 0xb4, 0x74, 0x60, 0x12, 0xc, 0x5c,
+ 0xa9, 0xd2, 0xb4, 0x12, 0x0, 0x2e, 0x40, 0xfb, 0x22, 0x74, 0x1, 0x12, 0x8,
+ 0x45, 0xe4, 0x6d, 0x33, 0x12, 0x9, 0xfe, 0x74, 0x1, 0x6d, 0x33, 0x12, 0x9,
+ 0xfe, 0x74, 0x4, 0x6d, 0x33, 0x12, 0x9, 0xfe, 0x7e, 0x34, 0x0, 0x54, 0x12,
+ 0x9, 0xfe, 0x7e, 0x34, 0x0, 0x19, 0x12, 0xb, 0xb0, 0x74, 0x4, 0x7e, 0x34,
+ 0x0, 0x55, 0x12, 0x9, 0xfe, 0x7e, 0x34, 0xa2, 0x1c, 0x12, 0xb, 0xb0, 0x74,
+ 0x4, 0x7e, 0x34, 0x0, 0x15, 0x12, 0x9, 0xfe, 0x7e, 0x34, 0x0, 0xa0, 0x12,
+ 0xb, 0xb0, 0x74, 0x4, 0x7e, 0x34, 0x0, 0x14, 0x12, 0x9, 0xfe, 0x7e, 0x34,
+ 0x0, 0x19, 0x12, 0xb, 0xb0, 0x74, 0x4, 0x7e, 0x34, 0x0, 0x4, 0x12, 0x9,
+ 0xfe, 0x7e, 0x34, 0x0, 0x5, 0x12, 0xb, 0xb0, 0xe4, 0x12, 0x8, 0x45, 0x74,
+ 0x4, 0x7e, 0x34, 0xff, 0xf7, 0x2, 0x9, 0xfe, 0xca, 0xf8, 0xc2, 0x7, 0x7e,
+ 0xf0, 0x70, 0x75, 0x91, 0x0, 0xc2, 0x90, 0xc2, 0x91, 0x20, 0x7, 0x10, 0x7e,
+ 0xf1, 0xe4, 0xbe, 0xf0, 0x2, 0x40, 0x5, 0xbe, 0xf0, 0xfd, 0x28, 0x3, 0x7e,
+ 0xf0, 0x70, 0x30, 0x6, 0x38, 0x7e, 0x34, 0x0, 0x2, 0x7a, 0x35, 0x11, 0x7e,
+ 0x18, 0x7, 0x80, 0x7e, 0x8, 0x0, 0x8, 0x12, 0xc, 0x27, 0xe5, 0x8, 0xbe,
+ 0xb0, 0xff, 0x68, 0x19, 0xe5, 0x8, 0x60, 0x15, 0xe5, 0x9, 0xa, 0x2b, 0xe5,
+ 0x8, 0xa, 0x3b, 0x2d, 0x32, 0xbe, 0x34, 0x0, 0xff, 0x78, 0x5, 0x7e, 0xf1,
+ 0x8, 0xd2, 0x7, 0x20, 0x7, 0x3, 0x7e, 0xf0, 0x70, 0x5e, 0xf0, 0xfe, 0x7a,
+ 0xf1, 0x92, 0xd2, 0xe8, 0xc2, 0xc0, 0xa9, 0xd5, 0xb7, 0xd2, 0xbd, 0xd2,
+ 0xad, 0xda, 0xf8, 0x22, 0x7c, 0x7b, 0x7e, 0xa0, 0xef, 0xe5, 0x21, 0x24,
+ 0xfd, 0x68, 0x38, 0x1b, 0xb1, 0x68, 0x22, 0x24, 0x9f, 0x68, 0x3d, 0x1b,
+ 0xb2, 0x68, 0x3e, 0x24, 0x9e, 0x68, 0x35, 0x24, 0x3c, 0x78, 0x4c, 0xa5,
+ 0xbf, 0x0, 0x5, 0x7e, 0xa0, 0x86, 0x80, 0x43, 0xa5, 0xbf, 0x1, 0x3f, 0x7e,
+ 0xa0, 0xa7, 0x80, 0x3a, 0xa5, 0xbf, 0x0, 0x5, 0x7e, 0xa1, 0x23, 0x80, 0x31,
+ 0xa5, 0xbf, 0x1, 0x2d, 0x7e, 0xa1, 0x3d, 0x80, 0x28, 0xa, 0x17, 0x7e, 0x1d,
+ 0x39, 0x2d, 0x31, 0x29, 0xa1, 0x0, 0x8, 0x80, 0x1b, 0x7e, 0xa1, 0x16, 0x80,
+ 0x16, 0xa5, 0xbf, 0x0, 0x9, 0x7e, 0x35, 0x30, 0xa, 0x56, 0x7c, 0xab, 0x80,
+ 0x9, 0xa5, 0xbf, 0x1, 0x5, 0x7e, 0x55, 0x30, 0x7c, 0xab, 0x7c, 0xba, 0x22,
+ 0xca, 0x79, 0xbe, 0xb0, 0x0, 0x28, 0x2e, 0x74, 0x6, 0x12, 0x8, 0xad, 0x7d,
+ 0x73, 0x6c, 0xff, 0x7e, 0xf0, 0xa5, 0x7d, 0x37, 0x12, 0x9, 0xfe, 0x6c, 0xff,
+ 0x7e, 0xf0, 0xf, 0x7d, 0x37, 0x12, 0x9, 0xfe, 0x6c, 0xff, 0x7e, 0xf0, 0x6a,
+ 0x7d, 0x37, 0x12, 0x9, 0xfe, 0x7e, 0x34, 0x0, 0x5, 0x12, 0xb, 0xb0, 0x80,
+ 0x30, 0x74, 0x1, 0x7e, 0x34, 0xdf, 0xff, 0x12, 0x9, 0xfe, 0x74, 0x6, 0x12,
+ 0x8, 0xad, 0x7d, 0x73, 0x6c, 0xff, 0x7d, 0x37, 0x12, 0x9, 0xfe, 0x7d, 0x37,
+ 0x12, 0x9, 0xfe, 0x7d, 0x37, 0x12, 0x9, 0xfe, 0x74, 0x2, 0x12, 0x8, 0xad,
+ 0x7d, 0x73, 0x4e, 0xf0, 0x1, 0x7d, 0x37, 0x12, 0x9, 0xfe, 0xda, 0x79, 0x22,
+ 0xa9, 0xc2, 0xb4, 0xa9, 0xc6, 0xb3, 0x75, 0xb5, 0x5, 0xa9, 0x36, 0xb3, 0xfc,
+ 0xa9, 0xc6, 0xb3, 0x75, 0xb5, 0x0, 0xa9, 0x36, 0xb3, 0xfc, 0xa9, 0xc6, 0xb3,
+ 0x75, 0xb5, 0x0, 0xa9, 0x36, 0xb3, 0xfc, 0xa9, 0xc6, 0xb3, 0xf5, 0xb5, 0xa9,
+ 0x36, 0xb3, 0xfc, 0xa9, 0xc6, 0xb3, 0x75, 0xb5, 0x0, 0xa9, 0x36, 0xb3, 0xfc,
+ 0xa9, 0xc6, 0xb3, 0x75, 0xb5, 0x0, 0xa9, 0x36, 0xb3, 0xfc, 0xa9, 0xc6, 0xb3,
+ 0x7e, 0x71, 0xb5, 0x75, 0xb5, 0x0, 0xa9, 0x36, 0xb3, 0xfc, 0xa9, 0xc6, 0xb3,
+ 0x7e, 0xa1, 0xb5, 0xa9, 0xd2, 0xb4, 0x7c, 0x47, 0x6c, 0x55, 0xa, 0x3a, 0x4d,
+ 0x32, 0x22, 0x7f, 0x70, 0xd2, 0x7, 0x12, 0xc, 0x14, 0x74, 0x2, 0x12, 0xb,
+ 0x2b, 0x6d, 0x33, 0x80, 0x12, 0x7f, 0x7, 0x2d, 0x13, 0x7e, 0xb, 0xb0, 0xf5,
+ 0xb5, 0xa9, 0x36, 0xb3, 0xfc, 0xa9, 0xc6, 0xb3, 0xb, 0x34, 0x7e, 0x25, 0x10,
+ 0xbd, 0x23, 0x38, 0xe7, 0xa9, 0xd2, 0xb4, 0x12, 0xc, 0x67, 0x12, 0x0, 0x2e,
+ 0x50, 0x9, 0x7e, 0x35, 0x17, 0xbe, 0x34, 0x1, 0xf4, 0x28, 0xf2, 0x7e, 0x35,
+ 0x17, 0xbe, 0x34, 0x1, 0xf4, 0x38, 0x3, 0x2, 0xc, 0x82, 0xc2, 0x86, 0x7e,
+ 0x34, 0x13, 0x88, 0x12, 0xb, 0xb0, 0xd2, 0x86, 0x22, 0x6d, 0x0, 0x74, 0x10,
+ 0x4d, 0x0, 0x78, 0xb, 0x4d, 0x22, 0x78, 0x27, 0x8d, 0x31, 0x7d, 0x12, 0x6d,
+ 0x22, 0x22, 0x7d, 0x43, 0x7d, 0x32, 0x6d, 0x22, 0x2f, 0x11, 0x2d, 0x44,
+ 0x50, 0x2, 0xa5, 0xf, 0xbf, 0x10, 0x40, 0x4, 0x9f, 0x10, 0xb, 0x90, 0x14,
+ 0x78, 0xed, 0x7f, 0x1, 0x6d, 0x22, 0x7d, 0x34, 0x22, 0x7d, 0x41, 0x7d, 0x13,
+ 0x8d, 0x24, 0x7d, 0x2, 0x2f, 0x0, 0x40, 0x4, 0xbd, 0x4, 0x40, 0x4, 0x9d,
+ 0x4, 0xb, 0x14, 0x14, 0x78, 0xf1, 0x7d, 0x23, 0x7d, 0x31, 0x7d, 0x10, 0x6d,
+ 0x0, 0x22, 0x75, 0x84, 0x1, 0x7e, 0x44, 0x1f, 0xff, 0xe4, 0x7a, 0x49, 0xb0,
+ 0x1b, 0x44, 0x78, 0xf9, 0x7e, 0xf8, 0x2, 0xd5, 0xd2, 0x5, 0xc2, 0x6, 0x75,
+ 0x16, 0x0, 0x75, 0x17, 0x0, 0x75, 0x18, 0x0, 0xd2, 0x0, 0xc2, 0x2, 0xc2,
+ 0x3, 0xc2, 0x4, 0x75, 0x21, 0x0, 0x75, 0x22, 0x0, 0x75, 0x23, 0x80, 0x75,
+ 0x2e, 0x0, 0x75, 0x2f, 0x0, 0x75, 0x30, 0x0, 0x75, 0x31, 0x0, 0x75, 0x32,
+ 0x0, 0x75, 0x37, 0xb, 0x75, 0x38, 0x0, 0x75, 0x3d, 0x1, 0x2, 0x4, 0x20,
+ 0x7d, 0x23, 0xa, 0x36, 0x7c, 0xa5, 0xa9, 0xc2, 0xb4, 0xa9, 0xc6, 0xb3, 0x75,
+ 0xb5, 0x1, 0xa9, 0x36, 0xb3, 0xfc, 0xa9, 0xc6, 0xb3, 0x75, 0xb5, 0x0, 0xa9,
+ 0x36, 0xb3, 0xfc, 0xa9, 0xc6, 0xb3, 0x75, 0xb5, 0x0, 0xa9, 0x36, 0xb3, 0xfc,
+ 0xa9, 0xc6, 0xb3, 0xf5, 0xb5, 0xa9, 0x36, 0xb3, 0xfc, 0xa9, 0xc6, 0xb3,
+ 0x7a, 0x71, 0xb5, 0xa9, 0x36, 0xb3, 0xfc, 0xa9, 0xc6, 0xb3, 0x7a, 0xa1,
+ 0xb5, 0xa9, 0x36, 0xb3, 0xfc, 0xa9, 0xc6, 0xb3, 0xa9, 0xd2, 0xb4, 0x22,
+ 0x7c, 0xab, 0xd2, 0x7, 0x12, 0xc, 0x14, 0x74, 0xd8, 0xa, 0x3a, 0x7d, 0x23,
+ 0x6d, 0x33, 0x12, 0xb, 0x2b, 0xa9, 0xd2, 0xb4, 0x12, 0xc, 0x67, 0x12, 0x0,
+ 0x2e, 0x50, 0x9, 0x7e, 0x35, 0x17, 0xbe, 0x34, 0x5, 0xdc, 0x28, 0xf2, 0x7e,
+ 0x35, 0x17, 0xbe, 0x34, 0x5, 0xdc, 0x38, 0x3, 0x2, 0xc, 0x82, 0xc2, 0x86,
+ 0x7e, 0x34, 0x13, 0x88, 0x12, 0xb, 0xb0, 0xd2, 0x86, 0x22, 0xca, 0x2b, 0xca,
+ 0x1b, 0xca, 0xb, 0xd2, 0x0, 0x30, 0x90, 0x1c, 0xc2, 0x90, 0x7e, 0x71, 0x91,
+ 0xe5, 0x38, 0x70, 0x3, 0x7a, 0x71, 0x21, 0xe5, 0x38, 0x12, 0x1, 0x20, 0x5,
+ 0x38, 0x30, 0x2, 0x6, 0xe4, 0x12, 0x7, 0xd7, 0xf5, 0x91, 0x30, 0x91, 0xb,
+ 0xc2, 0x91, 0x5, 0x38, 0xe5, 0x38, 0x12, 0x7, 0xd7, 0xf5, 0x91, 0xda, 0xb,
+ 0xda, 0x1b, 0xda, 0x2b, 0x32, 0xd2, 0x7, 0x12, 0xc, 0x14, 0xa9, 0xc2, 0xb4,
+ 0x74, 0x9f, 0x12, 0xc, 0x5c, 0x12, 0xc, 0x43, 0xa9, 0xd2, 0xb4, 0x60, 0x3,
+ 0xb4, 0xff, 0x1a, 0x75, 0x23, 0x81, 0xa9, 0xd5, 0xca, 0xa9, 0xd0, 0xca,
+ 0x75, 0xed, 0x9f, 0x75, 0xad, 0x20, 0xa9, 0xd1, 0xea, 0xa9, 0xc1, 0xea,
+ 0x74, 0x1, 0x2, 0xb, 0x58, 0x2, 0xa, 0xf8, 0xd2, 0x7, 0x12, 0xc, 0x14, 0xa9,
+ 0xc2, 0xb4, 0x74, 0x5, 0x12, 0xc, 0x5c, 0x12, 0xc, 0x43, 0x7c, 0xab, 0xa9,
+ 0xd2, 0xb4, 0xd2, 0x7, 0x12, 0xc, 0x14, 0x5e, 0xa0, 0xe3, 0xa9, 0xc2, 0xb4,
+ 0x74, 0x1, 0x12, 0xc, 0x5c, 0x7c, 0xba, 0x12, 0xc, 0x5c, 0xa9, 0xd2, 0xb4,
+ 0x12, 0x0, 0x2e, 0x40, 0xfb, 0x22, 0x7c, 0xab, 0x7d, 0x12, 0x7c, 0xb3, 0xf5,
+ 0x14, 0x7c, 0x36, 0x7c, 0x25, 0xa, 0x4, 0x7c, 0xb3, 0xf5, 0x13, 0x7c, 0xb7,
+ 0xf5, 0x12, 0xa9, 0xc2, 0xb4, 0x7c, 0xba, 0x12, 0xc, 0x5c, 0xe5, 0x14, 0x12,
+ 0xc, 0x5c, 0xe5, 0x13, 0x12, 0xc, 0x5c, 0xe5, 0x12, 0x2, 0xc, 0x5c, 0xca,
+ 0xf8, 0x7c, 0xfb, 0xe5, 0x23, 0xb4, 0x81, 0x21, 0x74, 0x2, 0x12, 0x8, 0xad,
+ 0x4c, 0xff, 0x78, 0x8, 0xa9, 0xc0, 0xca, 0x5e, 0x70, 0xdf, 0x80, 0x6, 0xa9,
+ 0xd0, 0xca, 0x4e, 0x70, 0x20, 0x74, 0x2, 0x12, 0x9, 0xfe, 0x74, 0x2, 0x12,
+ 0x8, 0xad, 0xda, 0xf8, 0x22, 0x7d, 0x52, 0xf5, 0x15, 0x7c, 0xb6, 0x7c, 0xa5,
+ 0xa, 0x44, 0xf5, 0x14, 0x7f, 0x21, 0xf5, 0x13, 0xa9, 0xc2, 0xb4, 0x74, 0xb,
+ 0x12, 0xc, 0x5c, 0xe5, 0x15, 0x12, 0xc, 0x5c, 0xe5, 0x14, 0x12, 0xc, 0x5c,
+ 0xe5, 0x13, 0x12, 0xc, 0x5c, 0xe4, 0x2, 0xc, 0x5c, 0x80, 0x18, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe5, 0x3d, 0x70, 0xa, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7d, 0x23, 0x1b, 0x34, 0x4d, 0x22,
+ 0x78, 0xe0, 0x22, 0xd2, 0xcf, 0x85, 0x3d, 0xcc, 0x75, 0xec, 0xff, 0x75,
+ 0xee, 0xff, 0x75, 0xeb, 0x3, 0x75, 0xac, 0x40, 0xa9, 0xc5, 0xca, 0x75, 0xed,
+ 0xf, 0x75, 0xad, 0xb0, 0xa9, 0xd7, 0x94, 0xa9, 0xd4, 0x94, 0x22, 0x12, 0xb,
+ 0xd3, 0xa9, 0xa6, 0x94, 0xb3, 0x92, 0x6, 0x30, 0x6, 0x6, 0x12, 0xc, 0x50,
+ 0x12, 0xa, 0xc3, 0x12, 0x7, 0x67, 0x12, 0xc, 0x35, 0xd2, 0xaf, 0x30, 0x3,
+ 0xfd, 0x2, 0xc, 0x7a, 0xa9, 0xc2, 0xb4, 0x30, 0x7, 0x4, 0x74, 0x6, 0x80,
+ 0x2, 0x74, 0x4, 0x12, 0xc, 0x5c, 0xa9, 0xd2, 0xb4, 0x22, 0x12, 0xb, 0x85,
+ 0x7e, 0x35, 0x11, 0x12, 0x0, 0xe, 0xa9, 0xd2, 0xb4, 0xd3, 0x22, 0xc2, 0x8c,
+ 0x43, 0x89, 0x2, 0x75, 0x8c, 0x1, 0x75, 0x8a, 0x0, 0xd2, 0xa9, 0x22, 0x75,
+ 0xb5, 0x0, 0xa9, 0x36, 0xb3, 0xfc, 0xa9, 0xc6, 0xb3, 0xe5, 0xb5, 0x22, 0xd2,
+ 0xc8, 0x75, 0xb3, 0x13, 0xa9, 0xd1, 0xb4, 0xa9, 0xc0, 0xb4, 0x22, 0xf5,
+ 0xb5, 0xa9, 0x36, 0xb3, 0xfc, 0xa9, 0xc6, 0xb3, 0xd3, 0x22, 0xc2, 0x8c,
+ 0x6d, 0x33, 0x7a, 0x35, 0x17, 0xd2, 0x8c, 0x22, 0x7e, 0x35, 0x17, 0xb, 0x34,
+ 0x7a, 0x35, 0x17, 0x22, 0x85, 0x3d, 0xcc, 0xe5, 0x3d, 0x2, 0xb, 0x58, 0x2,
+ 0xc, 0x71, 0xff,
diff --git a/drivers/input/touchscreen/focaltech_touch/include/pramboot/FT8716_Pramboot_V0.5_20160723.i b/drivers/input/touchscreen/focaltech_touch/include/pramboot/FT8716_Pramboot_V0.5_20160723.i
new file mode 100644
index 000000000000..805c8bfaf191
--- /dev/null
+++ b/drivers/input/touchscreen/focaltech_touch/include/pramboot/FT8716_Pramboot_V0.5_20160723.i
@@ -0,0 +1,303 @@
+0x2, 0x3, 0x83, 0xca, 0x39, 0x12, 0xf, 0x3c, 0xda, 0x39, 0x32, 0x2, 0x0, 0x3,
+ 0x6d, 0x22, 0x80, 0x13, 0x75, 0xb5, 0x0, 0xa9, 0x36, 0xb3, 0xfc, 0xa9, 0xc6,
+ 0xb3, 0xe5, 0xb5, 0x7a, 0xb, 0xb0, 0xb, 0x14, 0xb, 0x24, 0xbd, 0x32, 0x38,
+ 0xe9, 0x22, 0xff, 0x2, 0xd, 0xf, 0xe5, 0x33, 0xb4, 0xc, 0xf, 0xc2, 0x86,
+ 0xc2, 0x87, 0x7e, 0x34, 0x0, 0x64, 0x12, 0xe, 0x86, 0xd2, 0x86, 0xd2, 0x87,
+ 0x22, 0x2, 0x0, 0xf9, 0xca, 0x3b, 0x7a, 0xd, 0x10, 0x7f, 0x31, 0xe5, 0x24,
+ 0xb4, 0x80, 0x2, 0x80, 0x3, 0x2, 0x0, 0xdc, 0x7f, 0x13, 0x5e, 0x34, 0x0,
+ 0x7f, 0x7d, 0x23, 0x7e, 0x34, 0x0, 0x80, 0x9d, 0x32, 0x7a, 0x35, 0x16, 0x7e,
+ 0x35, 0x14, 0xbe, 0x35, 0x16, 0x38, 0x2, 0x80, 0x5d, 0x7e, 0x35, 0x16, 0x7a,
+ 0x35, 0x18, 0x7f, 0x13, 0x7e, 0xd, 0x10, 0x12, 0xa, 0xe6, 0x7e, 0x35, 0x14,
+ 0x9e, 0x35, 0x16, 0x7a, 0x35, 0x14, 0x7e, 0x35, 0x16, 0x6d, 0x22, 0x2f,
+ 0x31, 0x7e, 0x1d, 0x10, 0x2e, 0x35, 0x16, 0x7a, 0x1d, 0x10, 0x80, 0x27,
+ 0x7e, 0x34, 0x0, 0x80, 0x7a, 0x35, 0x18, 0x7f, 0x13, 0x7e, 0xd, 0x10, 0x12,
+ 0xa, 0xe6, 0x7e, 0x35, 0x14, 0x9e, 0x34, 0x0, 0x80, 0x7a, 0x35, 0x14, 0x7e,
+ 0x1d, 0x10, 0x2e, 0x34, 0x0, 0x80, 0x7a, 0x1d, 0x10, 0x2e, 0x38, 0x0, 0x80,
+ 0x7e, 0x35, 0x14, 0xbe, 0x34, 0x0, 0x80, 0x50, 0xd0, 0x4d, 0x33, 0x68, 0x26,
+ 0x7a, 0x35, 0x18, 0x7f, 0x13, 0x7e, 0xd, 0x10, 0x12, 0xa, 0xe6, 0x80, 0x19,
+ 0x74, 0x2, 0x12, 0xa, 0x89, 0x5e, 0x70, 0xf4, 0x12, 0xc, 0x86, 0x7e, 0x35,
+ 0x14, 0x7a, 0x35, 0x18, 0x7f, 0x13, 0x7e, 0xd, 0x10, 0x12, 0x8, 0xe, 0xd3,
+ 0xda, 0x3b, 0x22, 0xa9, 0xc0, 0x93, 0x75, 0x39, 0x0, 0x32, 0xf, 0x60, 0xf0,
+ 0x9f, 0x4c, 0xf1, 0xb3, 0xe, 0xce, 0xb9, 0x31, 0x46, 0xff, 0x0, 0xff, 0x0,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0x7c, 0x6b, 0xc2, 0x2, 0xe5, 0x22, 0x14, 0x78, 0x3,
+ 0x2, 0x2, 0xda, 0x1b, 0xb1, 0x78, 0x3, 0x2, 0x2, 0x3d, 0x1b, 0xb1, 0x78,
+ 0x3, 0x2, 0x2, 0x89, 0x1b, 0xb1, 0x78, 0x3, 0x2, 0x2, 0x9a, 0x1b, 0xb1,
+ 0x78, 0x3, 0x2, 0x2, 0xc1, 0x24, 0xf9, 0x78, 0x3, 0x2, 0x2, 0xd6, 0x24,
+ 0xaf, 0x78, 0x3, 0x2, 0x3, 0x3b, 0x24, 0xfd, 0x68, 0x3a, 0x14, 0x78, 0x3,
+ 0x2, 0x2, 0xdd, 0x14, 0x78, 0x3, 0x2, 0x2, 0xda, 0x1b, 0xb2, 0x78, 0x3, 0x2,
+ 0x2, 0xda, 0x24, 0xda, 0x68, 0x26, 0x24, 0xe6, 0x68, 0x1f, 0x24, 0xeb, 0x68,
+ 0x3b, 0x24, 0xf3, 0x78, 0x3, 0x2, 0x2, 0xda, 0x24, 0xe4, 0x78, 0x3, 0x2,
+ 0x3, 0x46, 0x14, 0x78, 0x3, 0x2, 0x2, 0xda, 0x24, 0x94, 0x68, 0x3, 0x2, 0x3,
+ 0x82, 0x2, 0x3, 0x42, 0xbe, 0x60, 0x4, 0x50, 0xc, 0x75, 0x3f, 0x0, 0x7c,
+ 0x16, 0x2e, 0x10, 0x25, 0x7c, 0xb7, 0xa5, 0xf7, 0xa5, 0xbe, 0x0, 0x2, 0x80,
+ 0x3, 0x2, 0x3, 0x82, 0xd2, 0x2, 0x22, 0x7c, 0xb6, 0x24, 0x0, 0x78, 0x3, 0x2,
+ 0x3, 0x82, 0x1b, 0xb1, 0x68, 0x1e, 0x14, 0x68, 0x1e, 0x14, 0x68, 0x1e, 0x14,
+ 0x68, 0x1e, 0xb, 0xb2, 0x78, 0x33, 0x30, 0x1, 0x7, 0x7e, 0x8, 0x0, 0x44,
+ 0x2, 0x2, 0x5a, 0x7e, 0x8, 0x1, 0x50, 0x2, 0x2, 0x5a, 0x2, 0x2, 0xfb, 0x2,
+ 0x3, 0x2, 0x2, 0x3, 0x1a, 0xa, 0x27, 0x7e, 0xd, 0x3a, 0xb, 0x16, 0xb, 0xa,
+ 0x30, 0x2d, 0x32, 0x1b, 0xa, 0x30, 0x6d, 0x33, 0x7e, 0xd, 0x3a, 0x79, 0x30,
+ 0x0, 0x6, 0x22, 0x7c, 0xb7, 0x62, 0x3f, 0x7e, 0x2d, 0x3a, 0x2e, 0x54, 0x0,
+ 0x6, 0xb, 0x2a, 0x20, 0x7d, 0x12, 0xb, 0x14, 0x1b, 0x2a, 0x10, 0x7e, 0xd,
+ 0x3a, 0x2d, 0x12, 0x39, 0x70, 0x0, 0x8, 0x7e, 0xd, 0x3a, 0x69, 0x50, 0x0,
+ 0x4, 0x69, 0x20, 0x0, 0x6, 0xbd, 0x25, 0x50, 0x3, 0x2, 0x3, 0x82, 0xb2, 0x1,
+ 0x7a, 0xd, 0x34, 0x7e, 0x34, 0x0, 0x2, 0x2, 0x3, 0x7f, 0x7c, 0xb6, 0x1b,
+ 0xb1, 0x68, 0x1d, 0x14, 0x68, 0x1d, 0xb, 0xb1, 0x68, 0x3, 0x2, 0x3, 0x82,
+ 0x30, 0x1, 0x6, 0x7e, 0x8, 0x0, 0x44, 0x80, 0x4, 0x7e, 0x8, 0x1, 0x50, 0x7a,
+ 0xd, 0x3a, 0x2, 0x2, 0xf3, 0x2, 0x2, 0xfb, 0xa, 0x57, 0x6d, 0x44, 0x7e, 0xd,
+ 0x3a, 0x69, 0x30, 0x0, 0x2, 0xb, 0xa, 0x20, 0x2f, 0x12, 0x79, 0x30, 0x0,
+ 0x2, 0x1b, 0xa, 0x20, 0x7e, 0x1d, 0x3a, 0x7a, 0x1d, 0x34, 0xd2, 0x2, 0x7e,
+ 0x34, 0x0, 0x1, 0x2, 0x3, 0x7f, 0xbe, 0x60, 0x1, 0x68, 0x9, 0xa5, 0xbe, 0x2,
+ 0x5, 0x7a, 0x71, 0x3e, 0xd2, 0x3, 0xd2, 0x2, 0x22, 0x75, 0xe6, 0x0, 0xe4,
+ 0x7e, 0x34, 0x1, 0x4, 0x7e, 0x24, 0x0, 0xff, 0x7a, 0x1b, 0xb0, 0x7e, 0x34,
+ 0x1, 0x5, 0x7a, 0x1b, 0xb0, 0x7e, 0x34, 0x1, 0x8, 0x7a, 0x1b, 0xb0, 0x7e,
+ 0x34, 0x1, 0x9, 0x7a, 0x1b, 0xb0, 0xd2, 0x4, 0x22, 0xa5, 0xbe, 0x1, 0x4,
+ 0x7a, 0x71, 0x38, 0x22, 0xa5, 0xbe, 0x2, 0x2, 0x80, 0x3, 0x2, 0x3, 0x82,
+ 0x7a, 0x71, 0x23, 0x22, 0x7a, 0x71, 0x33, 0x22, 0xd2, 0x2, 0x22, 0x7c, 0xb6,
+ 0x1b, 0xb1, 0x68, 0x18, 0x14, 0x68, 0x1c, 0x14, 0x68, 0x31, 0x14, 0x68,
+ 0x3a, 0xb, 0xb2, 0x68, 0x3, 0x2, 0x3, 0x82, 0xa, 0x37, 0x7d, 0x3, 0x6d,
+ 0x11, 0x80, 0x59, 0xa, 0x57, 0x7c, 0xab, 0xe4, 0x80, 0x2, 0xa, 0x57, 0x6d,
+ 0x44, 0x7e, 0xd, 0x3a, 0x69, 0x30, 0x0, 0x2, 0xb, 0xa, 0x20, 0x2f, 0x12,
+ 0x79, 0x30, 0x0, 0x2, 0x1b, 0xa, 0x20, 0x22, 0x7c, 0x67, 0x6c, 0x77, 0x7e,
+ 0xd, 0x3a, 0x79, 0x30, 0x0, 0x4, 0x22, 0xa, 0x27, 0x7e, 0xd, 0x3a, 0xb,
+ 0x16, 0xb, 0xa, 0x30, 0x2d, 0x32, 0x1b, 0xa, 0x30, 0x7e, 0x34, 0x0, 0x3,
+ 0x80, 0x44, 0x7e, 0x34, 0x0, 0x4, 0x7a, 0x35, 0x2f, 0x75, 0x3f, 0x0, 0x22,
+ 0x1b, 0x61, 0x68, 0x15, 0xb, 0x60, 0x78, 0x34, 0x7c, 0x27, 0x6c, 0x33, 0x6d,
+ 0x0, 0x7e, 0x1d, 0x3a, 0x79, 0x11, 0x0, 0x2, 0x1b, 0x1a, 0x0, 0x22, 0xa,
+ 0x57, 0x6d, 0x44, 0x7e, 0xd, 0x3a, 0x69, 0x30, 0x0, 0x2, 0xb, 0xa, 0x20,
+ 0x2f, 0x12, 0x79, 0x30, 0x0, 0x2, 0x1b, 0xa, 0x20, 0xe4, 0x7a, 0xb3, 0x2,
+ 0xe4, 0x7e, 0x34, 0x0, 0x5, 0x7a, 0x35, 0x2f, 0x22, 0x75, 0x84, 0x1, 0x7e,
+ 0x44, 0x1f, 0xff, 0xe4, 0x7a, 0x49, 0xb0, 0x1b, 0x44, 0x78, 0xf9, 0x7e,
+ 0xf8, 0x2, 0xe8, 0xd2, 0x7, 0xc2, 0x8, 0x75, 0x3f, 0x0, 0x75, 0x40, 0x87,
+ 0x75, 0x41, 0xa6, 0x75, 0x42, 0x0, 0x75, 0x43, 0x0, 0xd2, 0x0, 0xc2, 0x2,
+ 0xc2, 0x3, 0xc2, 0x4, 0x75, 0x22, 0x0, 0x75, 0x23, 0x0, 0x75, 0x24, 0x80,
+ 0x75, 0x2f, 0x0, 0x75, 0x30, 0x0, 0x75, 0x31, 0x0, 0x75, 0x32, 0x0, 0x75,
+ 0x33, 0x0, 0x75, 0x38, 0xb, 0x75, 0x39, 0x0, 0x75, 0x3e, 0x1, 0x7e, 0x4,
+ 0x0, 0xff, 0x7e, 0x14, 0xf, 0x50, 0xb, 0xa, 0x40, 0x5d, 0x44, 0x68, 0x1a,
+ 0x69, 0x20, 0x0, 0x2, 0xb, 0xe, 0xb, 0x44, 0x80, 0xa, 0x7e, 0xb, 0xb0, 0x7a,
+ 0x29, 0xb0, 0xb, 0x24, 0xb, 0xc, 0x1b, 0x44, 0x78, 0xf2, 0x80, 0xdf, 0x2,
+ 0x4, 0x20, 0xff, 0xff, 0x56, 0x30, 0x2e, 0x35, 0x4a, 0x75, 0x6c, 0x20, 0x32,
+ 0x33, 0x20, 0x32, 0x30, 0x31, 0x36, 0x0, 0x46, 0x54, 0x53, 0x38, 0x37, 0x31,
+ 0x36, 0x5f, 0x70, 0x72, 0x61, 0x6d, 0x62, 0x6f, 0x6f, 0x74, 0x12, 0xe, 0x63,
+ 0x2, 0x5, 0xbc, 0x7e, 0x35, 0x2f, 0x1b, 0x34, 0x68, 0x60, 0x1b, 0x35, 0x78,
+ 0x3, 0x2, 0x4, 0xbc, 0x1b, 0x34, 0x78, 0x3, 0x2, 0x4, 0xe6, 0x1b, 0x34,
+ 0x78, 0x3, 0x2, 0x5, 0x96, 0x2e, 0x34, 0x0, 0x3, 0x68, 0x3, 0x2, 0x5, 0xa8,
+ 0x6d, 0x33, 0x7a, 0x35, 0x2f, 0x7a, 0x35, 0x31, 0x30, 0x7, 0x5, 0x12, 0x0,
+ 0x2e, 0xc2, 0x7, 0x7e, 0xd, 0x34, 0x69, 0x30, 0x0, 0x4, 0x7a, 0x35, 0x14,
+ 0x69, 0x30, 0x0, 0x2, 0xb, 0xa, 0x20, 0x2e, 0x14, 0x0, 0x8, 0x12, 0x0, 0x46,
+ 0xd2, 0x7, 0x7e, 0x2d, 0x34, 0x69, 0x12, 0x0, 0x4, 0x69, 0x32, 0x0, 0x2,
+ 0xb, 0x2a, 0x20, 0x12, 0xb, 0xe2, 0x2e, 0x34, 0x10, 0x0, 0x2, 0x5, 0x91,
+ 0x6d, 0x33, 0x7a, 0x35, 0x2f, 0x7e, 0x34, 0x1, 0x0, 0x7a, 0x35, 0x15, 0x7e,
+ 0xd, 0x34, 0x69, 0x30, 0x0, 0x2, 0xb, 0xa, 0x20, 0x2e, 0x14, 0x0, 0x8, 0x12,
+ 0xe, 0xf2, 0x20, 0x0, 0x3, 0x2, 0x5, 0xa8, 0x7e, 0x1d, 0x34, 0x29, 0xb1,
+ 0x0, 0x8, 0xf5, 0x91, 0x2, 0x5, 0xa8, 0x6d, 0x33, 0x7a, 0x35, 0x2f, 0x7a,
+ 0x35, 0x31, 0x7e, 0x18, 0x0, 0x3f, 0x7a, 0x1d, 0xe, 0x7e, 0xd, 0x34, 0x69,
+ 0x30, 0x0, 0x2, 0xb, 0xa, 0x20, 0x69, 0x10, 0x0, 0x4, 0x12, 0x7, 0x62, 0x12,
+ 0x0, 0x2e, 0x7e, 0x34, 0xf0, 0x55, 0x2, 0x5, 0x91, 0x7e, 0x18, 0x10, 0x0,
+ 0x7a, 0x1d, 0x8, 0xd2, 0x5, 0x6d, 0x33, 0x7a, 0x35, 0x2f, 0x7a, 0x35, 0x31,
+ 0xe5, 0x38, 0xb4, 0xa, 0x17, 0xe5, 0x24, 0xb4, 0x80, 0xc, 0xe4, 0x12, 0xc,
+ 0xd1, 0x74, 0x1, 0x12, 0xc, 0xd1, 0x2, 0x5, 0x7f, 0x12, 0x8, 0xa4, 0x2, 0x5,
+ 0x7f, 0xe5, 0x38, 0xb4, 0xb, 0x27, 0xe5, 0x24, 0xb4, 0x80, 0x11, 0x7e, 0xf0,
+ 0x1, 0x7c, 0xbf, 0x12, 0x5, 0xc3, 0xb, 0xf0, 0xbe, 0xf0, 0x11, 0x78, 0xf4,
+ 0x80, 0x51, 0x7e, 0xf0, 0x4, 0x7c, 0xbf, 0x12, 0x5, 0xc3, 0xb, 0xf0, 0xbe,
+ 0xf0, 0x40, 0x78, 0xf4, 0x80, 0x40, 0xe5, 0x38, 0xa, 0x3b, 0x9e, 0x34, 0x0,
+ 0x80, 0x7c, 0xe7, 0xe5, 0x24, 0xb4, 0x80, 0x10, 0xa, 0x3e, 0x6d, 0x22, 0x74,
+ 0xc, 0x2f, 0x11, 0x14, 0x78, 0xfb, 0x7a, 0x1d, 0x8, 0x80, 0xe, 0xa, 0x3e,
+ 0x6d, 0x22, 0x74, 0xa, 0x2f, 0x11, 0x14, 0x78, 0xfb, 0x7a, 0x1d, 0x8, 0x6c,
+ 0xdd, 0x80, 0x9, 0x7c, 0xbe, 0x12, 0x5, 0xc3, 0xb, 0xe0, 0xb, 0xd0, 0xe5,
+ 0x23, 0xbc, 0xbd, 0x38, 0xf1, 0x7e, 0x1d, 0x8, 0x12, 0xe, 0xd, 0x92, 0x5,
+ 0x12, 0x0, 0x2e, 0x30, 0x5, 0x1b, 0x7e, 0x34, 0xf0, 0xaa, 0x7a, 0x35, 0x31,
+ 0x80, 0x12, 0x6d, 0x33, 0x7a, 0x35, 0x2f, 0x7a, 0x35, 0x31, 0x7e, 0xd, 0x34,
+ 0x69, 0x30, 0x0, 0x2, 0x12, 0x6, 0x98, 0x30, 0x4, 0x11, 0x7e, 0x34, 0x13,
+ 0x88, 0x12, 0xe, 0x86, 0x7e, 0x34, 0x13, 0x88, 0x12, 0xe, 0x86, 0x75, 0xe9,
+ 0xff, 0x30, 0x8, 0x3, 0x2, 0x4, 0x26, 0x22, 0xca, 0xf8, 0x7c, 0xfb, 0xe5,
+ 0x24, 0xb4, 0x80, 0x4a, 0xd2, 0x6, 0x12, 0xe, 0xdf, 0x74, 0x20, 0xca, 0xb8,
+ 0xa, 0x3f, 0x6d, 0x22, 0x74, 0xc, 0x2f, 0x11, 0x14, 0x78, 0xfb, 0xda, 0xb8,
+ 0x12, 0xd, 0xb3, 0xa9, 0xd2, 0xb4, 0x12, 0xf, 0x32, 0x12, 0xe, 0xca, 0x50,
+ 0x9, 0x7e, 0x35, 0x42, 0xbe, 0x34, 0x1, 0xf4, 0x28, 0xf2, 0x7e, 0x35, 0x42,
+ 0xbe, 0x34, 0x1, 0xf4, 0x38, 0x6, 0x12, 0xf, 0x4d, 0x2, 0x6, 0x95, 0xc2,
+ 0x86, 0x7e, 0x34, 0x13, 0x88, 0x12, 0xe, 0x86, 0xd2, 0x86, 0x2, 0x6, 0x95,
+ 0x74, 0x1, 0x12, 0xa, 0x21, 0x74, 0x1, 0x6d, 0x33, 0x12, 0xc, 0x86, 0xe4,
+ 0x12, 0xa, 0x89, 0x5e, 0x34, 0x80, 0x0, 0x7c, 0x4f, 0x6c, 0x55, 0x3e, 0x24,
+ 0x4d, 0x32, 0x12, 0xc, 0x86, 0x74, 0x4, 0x6d, 0x33, 0x12, 0xc, 0x86, 0x7e,
+ 0x34, 0x0, 0x50, 0x12, 0xc, 0x86, 0x7e, 0x34, 0x0, 0x19, 0x12, 0xe, 0x86,
+ 0x74, 0x4, 0x7e, 0x34, 0x0, 0x51, 0x12, 0xc, 0x86, 0x7e, 0x34, 0xa2, 0x1c,
+ 0x12, 0xe, 0x86, 0x74, 0x4, 0x7e, 0x34, 0x0, 0x11, 0x12, 0xc, 0x86, 0x7e,
+ 0x34, 0x0, 0x19, 0x12, 0xe, 0x86, 0x74, 0x4, 0x7e, 0x34, 0x0, 0x10, 0x12,
+ 0xc, 0x86, 0x7e, 0x34, 0x0, 0x19, 0x12, 0xe, 0x86, 0x74, 0x4, 0x6d, 0x33,
+ 0x12, 0xc, 0x86, 0x7e, 0x34, 0x0, 0x5, 0x12, 0xe, 0x86, 0xe4, 0x12, 0xa,
+ 0x21, 0x74, 0x4, 0x7e, 0x34, 0xff, 0xf7, 0x12, 0xc, 0x86, 0xda, 0xf8, 0x22,
+ 0xca, 0xf8, 0xe4, 0x7a, 0xb3, 0x2, 0xe4, 0xe5, 0x24, 0xbe, 0xb0, 0x80, 0x68,
+ 0x9, 0x74, 0x1, 0x7a, 0xb3, 0x2, 0xe4, 0x2, 0x7, 0x5f, 0xbe, 0x34, 0xff,
+ 0xff, 0x68, 0x6, 0xbe, 0x34, 0x0, 0x12, 0x50, 0x4, 0x7e, 0x34, 0x0, 0x12,
+ 0x7d, 0x13, 0x6d, 0x0, 0x74, 0xc, 0x2f, 0x0, 0x14, 0x78, 0xfb, 0x7a, 0xd,
+ 0xc, 0x7c, 0xb7, 0x12, 0x5, 0xc3, 0x7e, 0x1d, 0xc, 0x12, 0xe, 0xd, 0xe4,
+ 0x33, 0x7c, 0xfb, 0xbe, 0xf0, 0x1, 0x78, 0xa, 0x7e, 0xb3, 0x2, 0xe4, 0x44,
+ 0x2, 0x7a, 0xb3, 0x2, 0xe4, 0x6c, 0xaa, 0xa, 0x3a, 0x19, 0xa3, 0x2, 0xdc,
+ 0xb, 0xa0, 0xbe, 0xa0, 0x8, 0x78, 0xf3, 0x7e, 0x34, 0x0, 0x8, 0x7a, 0x35,
+ 0x14, 0x7e, 0x1d, 0xc, 0x7e, 0x8, 0x2, 0xdc, 0x12, 0x0, 0x46, 0x6c, 0xaa,
+ 0xe4, 0xa, 0x4a, 0x19, 0xb4, 0x2, 0xdc, 0xb, 0xa0, 0xbe, 0xa0, 0x8, 0x78,
+ 0xf3, 0x7e, 0x34, 0x0, 0x8, 0x7a, 0x35, 0x15, 0x7e, 0x1d, 0xc, 0x7e, 0x8,
+ 0x2, 0xdc, 0x12, 0xe, 0xf2, 0x7e, 0xf0, 0x1, 0x6c, 0xaa, 0xa, 0x3a, 0x9,
+ 0xb3, 0x2, 0xdc, 0xbc, 0xba, 0x68, 0x4, 0x6c, 0xff, 0x80, 0x7, 0xb, 0xa0,
+ 0xbe, 0xa0, 0x8, 0x40, 0xeb, 0xbe, 0xf0, 0x1, 0x78, 0xa, 0x7e, 0xb3, 0x2,
+ 0xe4, 0x44, 0x4, 0x7a, 0xb3, 0x2, 0xe4, 0x7e, 0xb3, 0x2, 0xe4, 0x44, 0x1,
+ 0x7a, 0xb3, 0x2, 0xe4, 0xda, 0xf8, 0x22, 0xca, 0x3b, 0x7a, 0x15, 0xc, 0x7f,
+ 0x31, 0x75, 0x12, 0x0, 0x7e, 0x35, 0xc, 0xbe, 0x34, 0x0, 0x0, 0x38, 0x4f,
+ 0x7e, 0x34, 0xff, 0xff, 0x7a, 0x35, 0xc, 0x75, 0x12, 0x1, 0x80, 0x43, 0x7e,
+ 0x34, 0x0, 0x80, 0x7a, 0x35, 0x15, 0x7f, 0x13, 0x7e, 0x8, 0x2, 0x5c, 0x12,
+ 0xe, 0xf2, 0x7e, 0x35, 0xc, 0x9e, 0x34, 0x0, 0x80, 0x7a, 0x35, 0xc, 0x2e,
+ 0x38, 0x0, 0x80, 0x6d, 0x33, 0x7a, 0x35, 0x13, 0x7e, 0x35, 0x13, 0x9, 0x63,
+ 0x2, 0x5c, 0x7e, 0xd, 0xe, 0x7e, 0xb, 0x70, 0x6c, 0x76, 0x7a, 0xb, 0x70,
+ 0x7e, 0x35, 0x13, 0xb, 0x34, 0x7a, 0x35, 0x13, 0xbe, 0x34, 0x0, 0x80, 0x78,
+ 0xe0, 0x7e, 0x35, 0xc, 0xbe, 0x34, 0x0, 0x80, 0x38, 0xb4, 0xe5, 0x12, 0x60,
+ 0x5, 0xb, 0x34, 0x7a, 0x35, 0xc, 0x7e, 0x35, 0xc, 0x7a, 0x35, 0x15, 0x7f,
+ 0x13, 0x7e, 0x8, 0x2, 0x5c, 0x12, 0xe, 0xf2, 0x6d, 0x33, 0x80, 0x17, 0x7e,
+ 0x35, 0x13, 0x9, 0x63, 0x2, 0x5c, 0x7e, 0xd, 0xe, 0x7e, 0xb, 0x70, 0x6c,
+ 0x76, 0x7a, 0xb, 0x70, 0x7e, 0x35, 0x13, 0xb, 0x34, 0x7a, 0x35, 0x13, 0x7e,
+ 0x35, 0xc, 0xbe, 0x35, 0x13, 0x38, 0xde, 0xda, 0x3b, 0x22, 0xca, 0x3b, 0x7f,
+ 0x30, 0x7c, 0xb6, 0xf5, 0x1a, 0x7c, 0xb7, 0xf5, 0x1b, 0x74, 0x1, 0x7e, 0x35,
+ 0x18, 0x1e, 0x34, 0x1b, 0x34, 0x4e, 0x60, 0x80, 0x12, 0xc, 0x86, 0x12, 0xa,
+ 0x21, 0xa9, 0xc2, 0xb4, 0xa9, 0xc6, 0xb3, 0x75, 0xb5, 0x2, 0xa9, 0x36, 0xb3,
+ 0xfc, 0xa9, 0xc6, 0xb3, 0x75, 0xb5, 0x0, 0xa9, 0x36, 0xb3, 0xfc, 0xa9, 0xc6,
+ 0xb3, 0x85, 0x1a, 0xb5, 0xa9, 0x36, 0xb3, 0xfc, 0xa9, 0xc6, 0xb3, 0x85,
+ 0x1b, 0xb5, 0xa9, 0x36, 0xb3, 0xfc, 0xa9, 0xc6, 0xb3, 0x6d, 0x33, 0x80,
+ 0x2a, 0x7f, 0x13, 0x2e, 0x35, 0x1c, 0x7e, 0x1b, 0xb0, 0xf5, 0xb5, 0xa9,
+ 0x36, 0xb3, 0xfc, 0xa9, 0xc6, 0xb3, 0x7e, 0x35, 0x1c, 0x5e, 0x34, 0x0, 0x1,
+ 0xbe, 0x34, 0x0, 0x1, 0x78, 0x7, 0x7e, 0x34, 0x0, 0x78, 0x12, 0xe, 0x86,
+ 0x7e, 0x35, 0x1c, 0xb, 0x34, 0x7a, 0x35, 0x1c, 0x7e, 0x35, 0x18, 0xbe, 0x35,
+ 0x1c, 0x38, 0xcb, 0xa9, 0xd2, 0xb4, 0x7e, 0x34, 0x0, 0x5, 0x12, 0xe, 0x86,
+ 0xe4, 0x12, 0xa, 0x21, 0xda, 0x3b, 0x22, 0xe5, 0x24, 0xb4, 0x80, 0x16, 0xd2,
+ 0x6, 0x12, 0xe, 0xdf, 0xa9, 0xc2, 0xb4, 0x74, 0x60, 0x12, 0xf, 0x27, 0xa9,
+ 0xd2, 0xb4, 0x12, 0xe, 0xca, 0x40, 0xfb, 0x22, 0x74, 0x1, 0x12, 0xa, 0x21,
+ 0xe4, 0x6d, 0x33, 0x12, 0xc, 0x86, 0x74, 0x1, 0x6d, 0x33, 0x12, 0xc, 0x86,
+ 0x74, 0x4, 0x6d, 0x33, 0x12, 0xc, 0x86, 0x7e, 0x34, 0x0, 0x54, 0x12, 0xc,
+ 0x86, 0x7e, 0x34, 0x0, 0x19, 0x12, 0xe, 0x86, 0x74, 0x4, 0x7e, 0x34, 0x0,
+ 0x55, 0x12, 0xc, 0x86, 0x7e, 0x34, 0xa2, 0x1c, 0x12, 0xe, 0x86, 0x74, 0x4,
+ 0x7e, 0x34, 0x0, 0x15, 0x12, 0xc, 0x86, 0x7e, 0x34, 0x0, 0xa0, 0x12, 0xe,
+ 0x86, 0x74, 0x4, 0x7e, 0x34, 0x0, 0x14, 0x12, 0xc, 0x86, 0x7e, 0x34, 0x0,
+ 0x19, 0x12, 0xe, 0x86, 0x74, 0x4, 0x7e, 0x34, 0x0, 0x4, 0x12, 0xc, 0x86,
+ 0x7e, 0x34, 0x0, 0x5, 0x12, 0xe, 0x86, 0xe4, 0x12, 0xa, 0x21, 0x74, 0x4,
+ 0x7e, 0x34, 0xff, 0xf7, 0x2, 0xc, 0x86, 0x7c, 0x7b, 0x7e, 0xa0, 0xef, 0xe5,
+ 0x22, 0x24, 0xfd, 0x68, 0x3c, 0x1b, 0xb1, 0x68, 0x26, 0x24, 0x9f, 0x68,
+ 0x41, 0x1b, 0xb2, 0x68, 0x42, 0x24, 0x9e, 0x68, 0x39, 0x24, 0xe3, 0x68,
+ 0x52, 0x24, 0x59, 0x78, 0x52, 0xa5, 0xbf, 0x0, 0x5, 0x7e, 0xa1, 0x40, 0x80,
+ 0x49, 0xa5, 0xbf, 0x1, 0x45, 0x7e, 0xa1, 0x41, 0x80, 0x40, 0xa5, 0xbf, 0x0,
+ 0x5, 0x7e, 0xa1, 0x24, 0x80, 0x37, 0xa5, 0xbf, 0x1, 0x33, 0x7e, 0xa1, 0x3e,
+ 0x80, 0x2e, 0xa, 0x17, 0x7e, 0x1d, 0x3a, 0x2d, 0x31, 0x29, 0xa1, 0x0, 0x8,
+ 0x80, 0x21, 0x7e, 0xa1, 0x3f, 0x80, 0x1c, 0xa5, 0xbf, 0x0, 0x9, 0x7e, 0x35,
+ 0x31, 0xa, 0x56, 0x7c, 0xab, 0x80, 0xf, 0xa5, 0xbf, 0x1, 0xb, 0x7e, 0x55,
+ 0x31, 0x7c, 0xab, 0x80, 0x4, 0x7e, 0xa3, 0x2, 0xe4, 0x7c, 0xba, 0x22, 0xca,
+ 0x79, 0x6c, 0xee, 0x7e, 0xf0, 0x70, 0x75, 0x91, 0x0, 0xc2, 0x90, 0xc2, 0x91,
+ 0x30, 0x8, 0x31, 0x7e, 0x34, 0x0, 0x2, 0x7a, 0x35, 0x15, 0x9f, 0x11, 0x7e,
+ 0x8, 0x0, 0xc, 0x12, 0xe, 0xf2, 0xe5, 0xc, 0xbe, 0xb0, 0xff, 0x68, 0x1a,
+ 0xe5, 0xc, 0x60, 0x16, 0xe5, 0xd, 0xa, 0x2b, 0xe5, 0xc, 0xa, 0x3b, 0x2d,
+ 0x32, 0xbe, 0x34, 0x0, 0xff, 0x78, 0x6, 0x7e, 0xf1, 0xc, 0x7e, 0xe0, 0x1,
+ 0x4c, 0xee, 0x78, 0x1c, 0xa9, 0xd1, 0xcb, 0xd2, 0xcc, 0x12, 0xc, 0x35, 0x7c,
+ 0xfb, 0xc2, 0xcc, 0xa9, 0xc1, 0xcb, 0xbe, 0xf0, 0x2, 0x40, 0x5, 0xbe, 0xf0,
+ 0xfd, 0x28, 0x3, 0x7e, 0xf0, 0x70, 0x7c, 0xbf, 0x54, 0xfe, 0xf5, 0x92, 0xd2,
+ 0xe8, 0xc2, 0xc0, 0xa9, 0xd5, 0xb7, 0xd2, 0xbd, 0xd2, 0xad, 0xda, 0x79,
+ 0x22, 0xca, 0x79, 0xbe, 0xb0, 0x0, 0x28, 0x2e, 0x74, 0x6, 0x12, 0xa, 0x89,
+ 0x7d, 0x73, 0x6c, 0xff, 0x7e, 0xf0, 0xa5, 0x7d, 0x37, 0x12, 0xc, 0x86, 0x6c,
+ 0xff, 0x7e, 0xf0, 0xf, 0x7d, 0x37, 0x12, 0xc, 0x86, 0x6c, 0xff, 0x7e, 0xf0,
+ 0x6a, 0x7d, 0x37, 0x12, 0xc, 0x86, 0x7e, 0x34, 0x0, 0x5, 0x12, 0xe, 0x86,
+ 0x80, 0x30, 0x74, 0x1, 0x7e, 0x34, 0xdf, 0xff, 0x12, 0xc, 0x86, 0x74, 0x6,
+ 0x12, 0xa, 0x89, 0x7d, 0x73, 0x6c, 0xff, 0x7d, 0x37, 0x12, 0xc, 0x86, 0x7d,
+ 0x37, 0x12, 0xc, 0x86, 0x7d, 0x37, 0x12, 0xc, 0x86, 0x74, 0x2, 0x12, 0xa,
+ 0x89, 0x7d, 0x73, 0x4e, 0xf0, 0x1, 0x7d, 0x37, 0x12, 0xc, 0x86, 0xda, 0x79,
+ 0x22, 0xa9, 0xc2, 0xb4, 0xa9, 0xc6, 0xb3, 0x75, 0xb5, 0x5, 0xa9, 0x36, 0xb3,
+ 0xfc, 0xa9, 0xc6, 0xb3, 0x75, 0xb5, 0x0, 0xa9, 0x36, 0xb3, 0xfc, 0xa9, 0xc6,
+ 0xb3, 0x75, 0xb5, 0x0, 0xa9, 0x36, 0xb3, 0xfc, 0xa9, 0xc6, 0xb3, 0xf5, 0xb5,
+ 0xa9, 0x36, 0xb3, 0xfc, 0xa9, 0xc6, 0xb3, 0x75, 0xb5, 0x0, 0xa9, 0x36, 0xb3,
+ 0xfc, 0xa9, 0xc6, 0xb3, 0x75, 0xb5, 0x0, 0xa9, 0x36, 0xb3, 0xfc, 0xa9, 0xc6,
+ 0xb3, 0x7e, 0x71, 0xb5, 0x75, 0xb5, 0x0, 0xa9, 0x36, 0xb3, 0xfc, 0xa9, 0xc6,
+ 0xb3, 0x7e, 0xa1, 0xb5, 0xa9, 0xd2, 0xb4, 0x7c, 0x47, 0x6c, 0x55, 0xa, 0x3a,
+ 0x4d, 0x32, 0x22, 0x7f, 0x70, 0xd2, 0x6, 0x12, 0xe, 0xdf, 0x74, 0x2, 0x12,
+ 0xd, 0xb3, 0x6d, 0x33, 0x80, 0x12, 0x7f, 0x7, 0x2d, 0x13, 0x7e, 0xb, 0xb0,
+ 0xf5, 0xb5, 0xa9, 0x36, 0xb3, 0xfc, 0xa9, 0xc6, 0xb3, 0xb, 0x34, 0x7e, 0x25,
+ 0x18, 0xbd, 0x23, 0x38, 0xe7, 0xa9, 0xd2, 0xb4, 0x12, 0xf, 0x32, 0x12, 0xe,
+ 0xca, 0x50, 0x9, 0x7e, 0x35, 0x42, 0xbe, 0x34, 0x1, 0xf4, 0x28, 0xf2, 0x7e,
+ 0x35, 0x42, 0xbe, 0x34, 0x1, 0xf4, 0x38, 0x3, 0x2, 0xf, 0x4d, 0xc2, 0x86,
+ 0x7e, 0x34, 0x13, 0x88, 0x12, 0xe, 0x86, 0xd2, 0x86, 0x22, 0xa9, 0xd1, 0xcb,
+ 0xd2, 0xcc, 0x7e, 0x34, 0x0, 0x4, 0x7e, 0x8, 0x2, 0x5c, 0x74, 0xc, 0x12,
+ 0xb, 0x8f, 0xa9, 0xd1, 0xcb, 0xc2, 0xcc, 0x6c, 0xaa, 0x7e, 0x70, 0x2, 0xac,
+ 0x7a, 0x7e, 0x8, 0x2, 0x5c, 0x2d, 0x13, 0xb, 0xa, 0x30, 0x7d, 0x23, 0x7c,
+ 0x45, 0x6c, 0x55, 0xa, 0x36, 0x4d, 0x32, 0x1b, 0xa, 0x30, 0xb, 0xa0, 0xbe,
+ 0xa0, 0xc, 0x78, 0xde, 0x7e, 0x37, 0x2, 0x6c, 0x7d, 0x23, 0xa, 0x54, 0x7c,
+ 0xa7, 0xb4, 0xe7, 0xb, 0xbe, 0xa0, 0x16, 0x78, 0x6, 0x75, 0x40, 0xe7, 0x75,
+ 0x41, 0xa6, 0x22, 0x7e, 0x24, 0x0, 0x1, 0x7e, 0x7f, 0x2, 0xe5, 0x79, 0x27,
+ 0x0, 0x6, 0x7e, 0x7f, 0x2, 0xe5, 0x69, 0x27, 0x0, 0x6, 0x4d, 0x22, 0x78,
+ 0xf4, 0x5e, 0x60, 0x7f, 0x1b, 0x7a, 0x30, 0x7e, 0x1f, 0x2, 0xe5, 0x69, 0x31,
+ 0x0, 0x8, 0x4d, 0x33, 0x68, 0xf4, 0x6c, 0xaa, 0x80, 0x20, 0x6d, 0x44, 0x7e,
+ 0x1f, 0x2, 0xe5, 0x1b, 0x1a, 0x40, 0x7e, 0x1f, 0x2, 0xe5, 0x69, 0x41, 0x0,
+ 0x8, 0x4d, 0x44, 0x68, 0xf4, 0x69, 0x41, 0x0, 0x2, 0x1b, 0xa, 0x40, 0xb,
+ 0x15, 0xb, 0xa0, 0xbc, 0xba, 0x38, 0xdc, 0x22, 0x6d, 0x0, 0x74, 0x10, 0x4d,
+ 0x0, 0x78, 0xb, 0x4d, 0x22, 0x78, 0x27, 0x8d, 0x31, 0x7d, 0x12, 0x6d, 0x22,
+ 0x22, 0x7d, 0x43, 0x7d, 0x32, 0x6d, 0x22, 0x2f, 0x11, 0x2d, 0x44, 0x50, 0x2,
+ 0xa5, 0xf, 0xbf, 0x10, 0x40, 0x4, 0x9f, 0x10, 0xb, 0x90, 0x14, 0x78, 0xed,
+ 0x7f, 0x1, 0x6d, 0x22, 0x7d, 0x34, 0x22, 0x7d, 0x41, 0x7d, 0x13, 0x8d, 0x24,
+ 0x7d, 0x2, 0x2f, 0x0, 0x40, 0x4, 0xbd, 0x4, 0x40, 0x4, 0x9d, 0x4, 0xb, 0x14,
+ 0x14, 0x78, 0xf1, 0x7d, 0x23, 0x7d, 0x31, 0x7d, 0x10, 0x6d, 0x0, 0x22, 0x7e,
+ 0x34, 0x0, 0x2, 0x7e, 0xf, 0x2, 0xe5, 0x79, 0x30, 0x0, 0x4, 0x7e, 0x34, 0x0,
+ 0x1, 0x7e, 0xf, 0x2, 0xe5, 0x79, 0x30, 0x0, 0x6, 0x7e, 0xf, 0x2, 0xe5, 0x69,
+ 0x30, 0x0, 0x6, 0x4d, 0x33, 0x78, 0xf4, 0x7e, 0x34, 0x0, 0x4, 0x1b, 0xa,
+ 0x30, 0x7e, 0xf, 0x2, 0xe5, 0x69, 0x30, 0x0, 0x8, 0x4d, 0x33, 0x68, 0xf4,
+ 0x6d, 0x33, 0x1b, 0xa, 0x30, 0x7e, 0x1f, 0x2, 0xe5, 0x69, 0x11, 0x0, 0x8,
+ 0x4d, 0x11, 0x68, 0xf4, 0x69, 0x51, 0x0, 0x2, 0x5e, 0x54, 0x0, 0xfe, 0x22,
+ 0x7d, 0x23, 0xa, 0x36, 0x7c, 0xa5, 0xa9, 0xc2, 0xb4, 0xa9, 0xc6, 0xb3, 0x75,
+ 0xb5, 0x1, 0xa9, 0x36, 0xb3, 0xfc, 0xa9, 0xc6, 0xb3, 0x75, 0xb5, 0x0, 0xa9,
+ 0x36, 0xb3, 0xfc, 0xa9, 0xc6, 0xb3, 0x75, 0xb5, 0x0, 0xa9, 0x36, 0xb3, 0xfc,
+ 0xa9, 0xc6, 0xb3, 0xf5, 0xb5, 0xa9, 0x36, 0xb3, 0xfc, 0xa9, 0xc6, 0xb3,
+ 0x7a, 0x71, 0xb5, 0xa9, 0x36, 0xb3, 0xfc, 0xa9, 0xc6, 0xb3, 0x7a, 0xa1,
+ 0xb5, 0xa9, 0x36, 0xb3, 0xfc, 0xa9, 0xc6, 0xb3, 0xa9, 0xd2, 0xb4, 0x22,
+ 0x7c, 0xab, 0xd2, 0x6, 0x12, 0xe, 0xdf, 0x74, 0xd8, 0xa, 0x3a, 0x7d, 0x23,
+ 0x6d, 0x33, 0x12, 0xd, 0xb3, 0xa9, 0xd2, 0xb4, 0x12, 0xf, 0x32, 0x12, 0xe,
+ 0xca, 0x50, 0x9, 0x7e, 0x35, 0x42, 0xbe, 0x34, 0x5, 0xdc, 0x28, 0xf2, 0x7e,
+ 0x35, 0x42, 0xbe, 0x34, 0x5, 0xdc, 0x38, 0x3, 0x2, 0xf, 0x4d, 0xc2, 0x86,
+ 0x7e, 0x34, 0x13, 0x88, 0x12, 0xe, 0x86, 0xd2, 0x86, 0x22, 0xca, 0x2b, 0xca,
+ 0x1b, 0xca, 0xb, 0xd2, 0x0, 0x30, 0x90, 0x1c, 0xc2, 0x90, 0x7e, 0x71, 0x91,
+ 0xe5, 0x39, 0x70, 0x3, 0x7a, 0x71, 0x22, 0xe5, 0x39, 0x12, 0x1, 0x20, 0x5,
+ 0x39, 0x30, 0x2, 0x6, 0xe4, 0x12, 0x9, 0x33, 0xf5, 0x91, 0x30, 0x91, 0xb,
+ 0xc2, 0x91, 0x5, 0x39, 0xe5, 0x39, 0x12, 0x9, 0x33, 0xf5, 0x91, 0xda, 0xb,
+ 0xda, 0x1b, 0xda, 0x2b, 0x32, 0xd2, 0x6, 0x12, 0xe, 0xdf, 0xa9, 0xc2, 0xb4,
+ 0x74, 0x9f, 0x12, 0xf, 0x27, 0x12, 0xf, 0xe, 0xa9, 0xd2, 0xb4, 0x60, 0x3,
+ 0xb4, 0xff, 0x1a, 0x75, 0x24, 0x81, 0xa9, 0xd5, 0xca, 0xa9, 0xd0, 0xca,
+ 0x75, 0xed, 0x9f, 0x75, 0xad, 0x20, 0xa9, 0xd1, 0xea, 0xa9, 0xc1, 0xea,
+ 0x74, 0x1, 0x2, 0xd, 0xe0, 0x2, 0xd, 0x80, 0xd2, 0x6, 0x12, 0xe, 0xdf, 0xa9,
+ 0xc2, 0xb4, 0x74, 0x5, 0x12, 0xf, 0x27, 0x12, 0xf, 0xe, 0x7c, 0xab, 0xa9,
+ 0xd2, 0xb4, 0xd2, 0x6, 0x12, 0xe, 0xdf, 0x5e, 0xa0, 0xe3, 0xa9, 0xc2, 0xb4,
+ 0x74, 0x1, 0x12, 0xf, 0x27, 0x7c, 0xba, 0x12, 0xf, 0x27, 0xa9, 0xd2, 0xb4,
+ 0x12, 0xe, 0xca, 0x40, 0xfb, 0x22, 0x7c, 0xab, 0x7d, 0x12, 0x7c, 0xb3, 0xf5,
+ 0x1c, 0x7c, 0x36, 0x7c, 0x25, 0xa, 0x4, 0x7c, 0xb3, 0xf5, 0x1b, 0x7c, 0xb7,
+ 0xf5, 0x1a, 0xa9, 0xc2, 0xb4, 0x7c, 0xba, 0x12, 0xf, 0x27, 0xe5, 0x1c, 0x12,
+ 0xf, 0x27, 0xe5, 0x1b, 0x12, 0xf, 0x27, 0xe5, 0x1a, 0x2, 0xf, 0x27, 0xca,
+ 0xf8, 0x7c, 0xfb, 0xe5, 0x24, 0xb4, 0x81, 0x21, 0x74, 0x2, 0x12, 0xa, 0x89,
+ 0x4c, 0xff, 0x78, 0x8, 0xa9, 0xc0, 0xca, 0x5e, 0x70, 0xdf, 0x80, 0x6, 0xa9,
+ 0xd0, 0xca, 0x4e, 0x70, 0x20, 0x74, 0x2, 0x12, 0xc, 0x86, 0x74, 0x2, 0x12,
+ 0xa, 0x89, 0xda, 0xf8, 0x22, 0xd2, 0x6, 0x7e, 0x14, 0x0, 0x8, 0x7a, 0x15,
+ 0x15, 0x7e, 0x8, 0x2, 0xdc, 0x12, 0xe, 0xf2, 0x6c, 0xaa, 0xa, 0x3a, 0x9,
+ 0xb3, 0x2, 0xdc, 0xbe, 0xb0, 0xff, 0x68, 0x4, 0xc2, 0x6, 0x80, 0x7, 0xb,
+ 0xa0, 0xbe, 0xa0, 0x8, 0x40, 0xea, 0xa2, 0x6, 0x22, 0x7d, 0x52, 0xf5, 0x19,
+ 0x7c, 0xb6, 0x7c, 0xa5, 0xa, 0x44, 0xf5, 0x18, 0x7f, 0x21, 0xf5, 0x17, 0xa9,
+ 0xc2, 0xb4, 0x74, 0xb, 0x12, 0xf, 0x27, 0xe5, 0x19, 0x12, 0xf, 0x27, 0xe5,
+ 0x18, 0x12, 0xf, 0x27, 0xe5, 0x17, 0x12, 0xf, 0x27, 0xe4, 0x2, 0xf, 0x27,
+ 0x12, 0xe, 0xa9, 0x12, 0xb, 0x3b, 0xa9, 0xa6, 0x94, 0xb3, 0x92, 0x8, 0x30,
+ 0x8, 0x6, 0x12, 0xf, 0x1b, 0x12, 0xd, 0x4b, 0x12, 0x9, 0xab, 0x12, 0xf, 0x0,
+ 0xd2, 0xaf, 0x30, 0x3, 0xfd, 0x2, 0xf, 0x45, 0x80, 0x18, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe5, 0x3e, 0x70, 0xa, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7d, 0x23, 0x1b, 0x34, 0x4d, 0x22, 0x78,
+ 0xe0, 0x22, 0xd2, 0xcf, 0x85, 0x3e, 0xcc, 0x75, 0xec, 0xff, 0x75, 0xee,
+ 0xff, 0x75, 0xeb, 0x3, 0x75, 0xac, 0xc0, 0xa9, 0xc5, 0xca, 0x75, 0xed, 0xf,
+ 0x75, 0xad, 0xb0, 0xa9, 0xd7, 0x94, 0xa9, 0xd4, 0x94, 0x22, 0xa9, 0xc2,
+ 0xb4, 0x74, 0x5, 0x12, 0xf, 0x27, 0x12, 0xf, 0xe, 0xa9, 0xd2, 0xb4, 0x30,
+ 0xe0, 0x2, 0xd3, 0x22, 0xc3, 0x22, 0xa9, 0xc2, 0xb4, 0x30, 0x6, 0x4, 0x74,
+ 0x6, 0x80, 0x2, 0x74, 0x4, 0x12, 0xf, 0x27, 0xa9, 0xd2, 0xb4, 0x22, 0x12,
+ 0xe, 0x38, 0x7e, 0x35, 0x15, 0x12, 0x0, 0xe, 0xa9, 0xd2, 0xb4, 0xd3, 0x22,
+ 0xc2, 0x8c, 0x43, 0x89, 0x2, 0x75, 0x8c, 0x1, 0x75, 0x8a, 0x0, 0xd2, 0xa9,
+ 0x22, 0x75, 0xb5, 0x0, 0xa9, 0x36, 0xb3, 0xfc, 0xa9, 0xc6, 0xb3, 0xe5, 0xb5,
+ 0x22, 0xd2, 0xc8, 0x75, 0xb3, 0x13, 0xa9, 0xd1, 0xb4, 0xa9, 0xc0, 0xb4,
+ 0x22, 0xf5, 0xb5, 0xa9, 0x36, 0xb3, 0xfc, 0xa9, 0xc6, 0xb3, 0xd3, 0x22,
+ 0xc2, 0x8c, 0x6d, 0x33, 0x7a, 0x35, 0x42, 0xd2, 0x8c, 0x22, 0x7e, 0x35,
+ 0x42, 0xb, 0x34, 0x7a, 0x35, 0x42, 0x22, 0x85, 0x3e, 0xcc, 0xe5, 0x3e, 0x2,
+ 0xd, 0xe0, 0x2, 0xf, 0x3c, 0x0, 0x1, 0x2, 0xe4, 0x0, 0x0, 0x4, 0x2, 0xe5,
+ 0x0, 0x0, 0x9c, 0x0, 0x0, 0x0, 0xff,
diff --git a/drivers/input/touchscreen/focaltech_touch/include/pramboot/FT8736_Pramboot_V0.4_20160627.i b/drivers/input/touchscreen/focaltech_touch/include/pramboot/FT8736_Pramboot_V0.4_20160627.i
new file mode 100644
index 000000000000..b1e3b1c08564
--- /dev/null
+++ b/drivers/input/touchscreen/focaltech_touch/include/pramboot/FT8736_Pramboot_V0.4_20160627.i
@@ -0,0 +1,288 @@
+0x2, 0x8, 0x9e, 0xca, 0x39, 0x12, 0xe, 0x6c, 0xda, 0x39, 0x32, 0x2, 0x0, 0x3,
+ 0x6d, 0x22, 0x80, 0x13, 0x75, 0xb5, 0x0, 0xa9, 0x36, 0xb3, 0xfc, 0xa9, 0xc6,
+ 0xb3, 0xe5, 0xb5, 0x7a, 0xb, 0xb0, 0xb, 0x14, 0xb, 0x24, 0xbd, 0x32, 0x38,
+ 0xe9, 0x22, 0xff, 0x2, 0xc, 0x47, 0xa9, 0xc2, 0xb4, 0x74, 0x5, 0x12, 0xe,
+ 0x4d, 0x12, 0xe, 0x34, 0xa9, 0xd2, 0xb4, 0x30, 0xe0, 0x2, 0xd3, 0x22, 0xc3,
+ 0x22, 0x2, 0x0, 0xf9, 0xca, 0x3b, 0x7a, 0xd, 0x8, 0x7f, 0x31, 0xe5, 0x23,
+ 0xb4, 0x80, 0x2, 0x80, 0x3, 0x2, 0x0, 0xdc, 0x7f, 0x13, 0x5e, 0x34, 0x0,
+ 0x7f, 0x7d, 0x23, 0x7e, 0x34, 0x0, 0x80, 0x9d, 0x32, 0x7a, 0x35, 0xe, 0x7e,
+ 0x35, 0xc, 0xbe, 0x35, 0xe, 0x38, 0x2, 0x80, 0x5d, 0x7e, 0x35, 0xe, 0x7a,
+ 0x35, 0x10, 0x7f, 0x13, 0x7e, 0xd, 0x8, 0x12, 0xa, 0xba, 0x7e, 0x35, 0xc,
+ 0x9e, 0x35, 0xe, 0x7a, 0x35, 0xc, 0x7e, 0x35, 0xe, 0x6d, 0x22, 0x2f, 0x31,
+ 0x7e, 0x1d, 0x8, 0x2e, 0x35, 0xe, 0x7a, 0x1d, 0x8, 0x80, 0x27, 0x7e, 0x34,
+ 0x0, 0x80, 0x7a, 0x35, 0x10, 0x7f, 0x13, 0x7e, 0xd, 0x8, 0x12, 0xa, 0xba,
+ 0x7e, 0x35, 0xc, 0x9e, 0x34, 0x0, 0x80, 0x7a, 0x35, 0xc, 0x7e, 0x1d, 0x8,
+ 0x2e, 0x34, 0x0, 0x80, 0x7a, 0x1d, 0x8, 0x2e, 0x38, 0x0, 0x80, 0x7e, 0x35,
+ 0xc, 0xbe, 0x34, 0x0, 0x80, 0x50, 0xd0, 0x4d, 0x33, 0x68, 0x26, 0x7a, 0x35,
+ 0x10, 0x7f, 0x13, 0x7e, 0xd, 0x8, 0x12, 0xa, 0xba, 0x80, 0x19, 0x74, 0x2,
+ 0x12, 0xa, 0x5d, 0x5e, 0x70, 0xf4, 0x12, 0x3, 0xb4, 0x7e, 0x35, 0xc, 0x7a,
+ 0x35, 0x10, 0x7f, 0x13, 0x7e, 0xd, 0x8, 0x12, 0x6, 0xeb, 0xd3, 0xda, 0x3b,
+ 0x22, 0xa9, 0xc0, 0x93, 0x75, 0x38, 0x0, 0x32, 0xe, 0x8a, 0xf1, 0x75, 0xf4,
+ 0xf8, 0xb, 0x7, 0xca, 0xca, 0x35, 0x35, 0xff, 0xff, 0xff, 0x0, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0x70, 0x8f, 0x0, 0xff, 0xff, 0x0, 0xff, 0xac, 0xff, 0xac, 0x1,
+ 0xaa, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0x0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7c, 0x6b, 0xc2, 0x2, 0xe5, 0x21,
+ 0x14, 0x78, 0x3, 0x2, 0x3, 0x3f, 0x1b, 0xb1, 0x78, 0x3, 0x2, 0x2, 0xb0,
+ 0x1b, 0xb1, 0x78, 0x3, 0x2, 0x2, 0xfc, 0x1b, 0xb1, 0x78, 0x3, 0x2, 0x3, 0xd,
+ 0x1b, 0xb1, 0x78, 0x3, 0x2, 0x3, 0x26, 0x24, 0xf9, 0x78, 0x3, 0x2, 0x3,
+ 0x3b, 0x24, 0xaf, 0x78, 0x3, 0x2, 0x3, 0xa9, 0x24, 0xfd, 0x68, 0x2d, 0x14,
+ 0x78, 0x3, 0x2, 0x3, 0x42, 0x14, 0x78, 0x3, 0x2, 0x3, 0x3f, 0x1b, 0xb2,
+ 0x78, 0x3, 0x2, 0x3, 0x3f, 0x24, 0xda, 0x68, 0x19, 0x24, 0xe6, 0x68, 0x12,
+ 0x24, 0xeb, 0x68, 0x2e, 0x24, 0xf3, 0x78, 0x3, 0x2, 0x3, 0x3f, 0x24, 0x77,
+ 0x68, 0x3, 0x2, 0x3, 0xb3, 0x2, 0x3, 0xb0, 0xbe, 0x60, 0x4, 0x50, 0xc, 0x75,
+ 0x16, 0x0, 0x7c, 0x16, 0x2e, 0x10, 0x24, 0x7c, 0xb7, 0xa5, 0xf7, 0xa5, 0xbe,
+ 0x0, 0x2, 0x80, 0x3, 0x2, 0x3, 0xb3, 0xd2, 0x2, 0x22, 0x7c, 0xb6, 0x24, 0x0,
+ 0x78, 0x3, 0x2, 0x3, 0xb3, 0x1b, 0xb1, 0x68, 0x1e, 0x14, 0x68, 0x1e, 0x14,
+ 0x68, 0x1e, 0x14, 0x68, 0x1e, 0xb, 0xb2, 0x78, 0x33, 0x30, 0x1, 0x7, 0x7e,
+ 0x8, 0x0, 0x3e, 0x2, 0x2, 0xcd, 0x7e, 0x8, 0x1, 0x4a, 0x2, 0x2, 0xcd, 0x2,
+ 0x3, 0x67, 0x2, 0x3, 0x6e, 0x2, 0x3, 0x86, 0xa, 0x27, 0x7e, 0xd, 0x39, 0xb,
+ 0x16, 0xb, 0xa, 0x30, 0x2d, 0x32, 0x1b, 0xa, 0x30, 0x6d, 0x33, 0x7e, 0xd,
+ 0x39, 0x79, 0x30, 0x0, 0x6, 0x22, 0x7c, 0xb7, 0x62, 0x16, 0x7e, 0x2d, 0x39,
+ 0x2e, 0x54, 0x0, 0x6, 0xb, 0x2a, 0x20, 0x7d, 0x12, 0xb, 0x14, 0x1b, 0x2a,
+ 0x10, 0x7e, 0xd, 0x39, 0x2d, 0x12, 0x39, 0x70, 0x0, 0x8, 0x7e, 0xd, 0x39,
+ 0x69, 0x50, 0x0, 0x4, 0x69, 0x20, 0x0, 0x6, 0xbd, 0x25, 0x50, 0x3, 0x2, 0x3,
+ 0xb3, 0xb2, 0x1, 0x7a, 0xd, 0x33, 0x7e, 0x34, 0x0, 0x2, 0x2, 0x3, 0xa5,
+ 0x7c, 0xb6, 0x1b, 0xb1, 0x68, 0x1d, 0x14, 0x68, 0x1d, 0xb, 0xb1, 0x68, 0x3,
+ 0x2, 0x3, 0xb3, 0x30, 0x1, 0x6, 0x7e, 0x8, 0x0, 0x3e, 0x80, 0x4, 0x7e, 0x8,
+ 0x1, 0x4a, 0x7a, 0xd, 0x39, 0x2, 0x3, 0x56, 0x2, 0x3, 0x67, 0xa, 0x57, 0x6d,
+ 0x44, 0x7e, 0xd, 0x39, 0x69, 0x30, 0x0, 0x2, 0xb, 0xa, 0x20, 0x2f, 0x12,
+ 0x79, 0x30, 0x0, 0x2, 0x1b, 0xa, 0x20, 0x7e, 0x1d, 0x39, 0x7a, 0x1d, 0x33,
+ 0xd2, 0x2, 0x7e, 0x34, 0x0, 0x1, 0x2, 0x3, 0xa5, 0xbe, 0x60, 0x1, 0x68, 0x9,
+ 0xa5, 0xbe, 0x2, 0x5, 0x7a, 0x71, 0x3d, 0xd2, 0x3, 0xd2, 0x2, 0x22, 0x75,
+ 0xe6, 0x0, 0xe4, 0x7e, 0x34, 0x1, 0x4, 0x7e, 0x24, 0x0, 0xff, 0x7a, 0x1b,
+ 0xb0, 0x7e, 0x34, 0x1, 0x5, 0x7a, 0x1b, 0xb0, 0xd2, 0x4, 0x22, 0xa5, 0xbe,
+ 0x1, 0x4, 0x7a, 0x71, 0x37, 0x22, 0xa5, 0xbe, 0x2, 0x2, 0x80, 0x3, 0x2, 0x3,
+ 0xb3, 0x7a, 0x71, 0x22, 0x22, 0x7a, 0x71, 0x32, 0x22, 0xd2, 0x2, 0x22, 0x1b,
+ 0x61, 0x68, 0x21, 0x1b, 0x60, 0x68, 0x24, 0x1b, 0x60, 0x68, 0x38, 0x1b,
+ 0x60, 0x68, 0x40, 0xb, 0x62, 0x78, 0x5d, 0xa, 0x37, 0x7d, 0x3, 0x6d, 0x11,
+ 0x7e, 0x1d, 0x39, 0x79, 0x11, 0x0, 0x2, 0x1b, 0x1a, 0x0, 0x22, 0xa, 0x57,
+ 0x7c, 0xab, 0xe4, 0x80, 0x2, 0xa, 0x57, 0x6d, 0x44, 0x7e, 0xd, 0x39, 0x69,
+ 0x30, 0x0, 0x2, 0xb, 0xa, 0x20, 0x2f, 0x12, 0x79, 0x30, 0x0, 0x2, 0x1b, 0xa,
+ 0x20, 0x22, 0x7c, 0x67, 0x6c, 0x77, 0x7e, 0xd, 0x39, 0x79, 0x30, 0x0, 0x4,
+ 0x22, 0xa, 0x27, 0x7e, 0xd, 0x39, 0xb, 0x16, 0xb, 0xa, 0x30, 0x2d, 0x32,
+ 0x1b, 0xa, 0x30, 0x7e, 0x34, 0x0, 0x3, 0x7a, 0x35, 0x2e, 0x22, 0x7e, 0x34,
+ 0x0, 0x4, 0x7a, 0x35, 0x2e, 0x75, 0x16, 0x0, 0x22, 0x7d, 0x23, 0xa, 0x36,
+ 0x7c, 0xa5, 0xa9, 0xc2, 0xb4, 0xa9, 0xc6, 0xb3, 0x75, 0xb5, 0x1, 0xa9, 0x36,
+ 0xb3, 0xfc, 0xa9, 0xc6, 0xb3, 0x75, 0xb5, 0x0, 0xa9, 0x36, 0xb3, 0xfc, 0xa9,
+ 0xc6, 0xb3, 0x75, 0xb5, 0x0, 0xa9, 0x36, 0xb3, 0xfc, 0xa9, 0xc6, 0xb3, 0xf5,
+ 0xb5, 0xa9, 0x36, 0xb3, 0xfc, 0xa9, 0xc6, 0xb3, 0x7a, 0x71, 0xb5, 0xa9,
+ 0x36, 0xb3, 0xfc, 0xa9, 0xc6, 0xb3, 0x7a, 0xa1, 0xb5, 0xa9, 0x36, 0xb3,
+ 0xfc, 0xa9, 0xc6, 0xb3, 0xa9, 0xd2, 0xb4, 0x22, 0xff, 0x56, 0x30, 0x2e,
+ 0x32, 0x5f, 0x4a, 0x75, 0x6e, 0x20, 0x32, 0x37, 0x20, 0x32, 0x30, 0x31,
+ 0x36, 0x46, 0x54, 0x53, 0x38, 0x37, 0x33, 0x36, 0x5f, 0x50, 0x72, 0x61,
+ 0x6d, 0x62, 0x6f, 0x6f, 0x74, 0x12, 0xd, 0x73, 0x2, 0x5, 0x66, 0x7e, 0x35,
+ 0x2e, 0x1b, 0x34, 0x68, 0x57, 0x1b, 0x35, 0x78, 0x3, 0x2, 0x4, 0xb3, 0x1b,
+ 0x34, 0x78, 0x3, 0x2, 0x4, 0xdd, 0xb, 0x35, 0x68, 0x3, 0x2, 0x5, 0x52, 0x6d,
+ 0x33, 0x7a, 0x35, 0x2e, 0x7a, 0x35, 0x30, 0x30, 0x5, 0x5, 0x12, 0xe, 0x7,
+ 0xc2, 0x5, 0x7e, 0xd, 0x33, 0x69, 0x30, 0x0, 0x4, 0x7a, 0x35, 0xc, 0x69,
+ 0x30, 0x0, 0x2, 0xb, 0xa, 0x20, 0x2e, 0x14, 0x0, 0x8, 0x12, 0x0, 0x46, 0xd2,
+ 0x5, 0x7e, 0x2d, 0x33, 0x69, 0x12, 0x0, 0x4, 0x69, 0x32, 0x0, 0x2, 0xb,
+ 0x2a, 0x20, 0x12, 0xb, 0xb6, 0x2e, 0x34, 0x10, 0x0, 0x2, 0x5, 0x4f, 0x6d,
+ 0x33, 0x7a, 0x35, 0x2e, 0x7e, 0x34, 0x1, 0x0, 0x7a, 0x35, 0x11, 0x7e, 0xd,
+ 0x33, 0x69, 0x30, 0x0, 0x2, 0xb, 0xa, 0x20, 0x2e, 0x14, 0x0, 0x8, 0x12, 0xe,
+ 0x18, 0x20, 0x0, 0x3, 0x2, 0x5, 0x52, 0x7e, 0x1d, 0x33, 0x29, 0xb1, 0x0,
+ 0x8, 0xf5, 0x91, 0x2, 0x5, 0x52, 0x6d, 0x33, 0x7a, 0x35, 0x2e, 0x7a, 0x35,
+ 0x30, 0x7e, 0x18, 0x0, 0x16, 0x7a, 0x1d, 0xa, 0x7e, 0xd, 0x33, 0x69, 0x30,
+ 0x0, 0x2, 0xb, 0xa, 0x20, 0x69, 0x10, 0x0, 0x4, 0x12, 0x6, 0x42, 0x12, 0xe,
+ 0x7, 0x7e, 0x34, 0xf0, 0x55, 0x2, 0x5, 0x4f, 0x6d, 0x33, 0x7a, 0x35, 0x2e,
+ 0x7a, 0x35, 0x30, 0xe5, 0x37, 0xb4, 0xa, 0x15, 0xe5, 0x23, 0xb4, 0x80, 0xb,
+ 0xe4, 0x12, 0xc, 0x9, 0x74, 0x1, 0x12, 0xc, 0x9, 0x80, 0x4e, 0x12, 0x7,
+ 0x81, 0x80, 0x49, 0xe5, 0x37, 0xb4, 0xb, 0x27, 0xe5, 0x23, 0xb4, 0x80, 0x11,
+ 0x7e, 0xf0, 0x1, 0x7c, 0xbf, 0x12, 0x5, 0x6d, 0xb, 0xf0, 0xbe, 0xf0, 0x11,
+ 0x78, 0xf4, 0x80, 0x2e, 0x7e, 0xf0, 0x4, 0x7c, 0xbf, 0x12, 0x5, 0x6d, 0xb,
+ 0xf0, 0xbe, 0xf0, 0x40, 0x78, 0xf4, 0x80, 0x1d, 0xe5, 0x37, 0xa, 0x3b, 0x9e,
+ 0x34, 0x0, 0x80, 0x7c, 0xe7, 0x6c, 0xdd, 0x80, 0x9, 0x7c, 0xbe, 0x12, 0x5,
+ 0x6d, 0xb, 0xe0, 0xb, 0xd0, 0xe5, 0x22, 0xbc, 0xbd, 0x38, 0xf1, 0x12, 0xe,
+ 0x7, 0x7e, 0x34, 0xf0, 0xaa, 0x7a, 0x35, 0x30, 0x30, 0x4, 0x11, 0x7e, 0x34,
+ 0x13, 0x88, 0x12, 0xd, 0x96, 0x7e, 0x34, 0x13, 0x88, 0x12, 0xd, 0x96, 0x75,
+ 0xe9, 0xff, 0x30, 0x6, 0x3, 0x2, 0x4, 0x26, 0x22, 0xca, 0xf8, 0x7c, 0xfb,
+ 0xe5, 0x23, 0xb4, 0x80, 0x4a, 0xd2, 0x7, 0x12, 0xd, 0xf4, 0x74, 0x20, 0xca,
+ 0xb8, 0xa, 0x3f, 0x6d, 0x22, 0x74, 0xc, 0x2f, 0x11, 0x14, 0x78, 0xfb, 0xda,
+ 0xb8, 0x12, 0xd, 0x1b, 0xa9, 0xd2, 0xb4, 0x12, 0xe, 0x62, 0x12, 0x0, 0x2e,
+ 0x50, 0x9, 0x7e, 0x35, 0x19, 0xbe, 0x34, 0x1, 0xf4, 0x28, 0xf2, 0x7e, 0x35,
+ 0x19, 0xbe, 0x34, 0x1, 0xf4, 0x38, 0x6, 0x12, 0xe, 0x7d, 0x2, 0x6, 0x3f,
+ 0xc2, 0x86, 0x7e, 0x34, 0x13, 0x88, 0x12, 0xd, 0x96, 0xd2, 0x86, 0x2, 0x6,
+ 0x3f, 0x74, 0x1, 0x12, 0x9, 0xf5, 0x74, 0x1, 0x6d, 0x33, 0x12, 0x3, 0xb4,
+ 0xe4, 0x12, 0xa, 0x5d, 0x5e, 0x34, 0x80, 0x0, 0x7c, 0x4f, 0x6c, 0x55, 0x3e,
+ 0x24, 0x4d, 0x32, 0x12, 0x3, 0xb4, 0x74, 0x4, 0x6d, 0x33, 0x12, 0x3, 0xb4,
+ 0x7e, 0x34, 0x0, 0x50, 0x12, 0x3, 0xb4, 0x7e, 0x34, 0x0, 0x19, 0x12, 0xd,
+ 0x96, 0x74, 0x4, 0x7e, 0x34, 0x0, 0x51, 0x12, 0x3, 0xb4, 0x7e, 0x34, 0xa2,
+ 0x1c, 0x12, 0xd, 0x96, 0x74, 0x4, 0x7e, 0x34, 0x0, 0x11, 0x12, 0x3, 0xb4,
+ 0x7e, 0x34, 0x0, 0x19, 0x12, 0xd, 0x96, 0x74, 0x4, 0x7e, 0x34, 0x0, 0x10,
+ 0x12, 0x3, 0xb4, 0x7e, 0x34, 0x0, 0x19, 0x12, 0xd, 0x96, 0x74, 0x4, 0x6d,
+ 0x33, 0x12, 0x3, 0xb4, 0x7e, 0x34, 0x0, 0x5, 0x12, 0xd, 0x96, 0xe4, 0x12,
+ 0x9, 0xf5, 0x74, 0x4, 0x7e, 0x34, 0xff, 0xf7, 0x12, 0x3, 0xb4, 0xda, 0xf8,
+ 0x22, 0xca, 0x3b, 0x7a, 0x15, 0x8, 0x7f, 0x31, 0x7e, 0x35, 0x8, 0xbe, 0x34,
+ 0x0, 0x0, 0x38, 0x4f, 0x7e, 0x34, 0xff, 0xff, 0x7a, 0x35, 0x8, 0x75, 0xe,
+ 0x1, 0x80, 0x43, 0x7e, 0x34, 0x0, 0x80, 0x7a, 0x35, 0x11, 0x7f, 0x13, 0x7e,
+ 0x8, 0x2, 0x56, 0x12, 0xe, 0x18, 0x7e, 0x35, 0x8, 0x9e, 0x34, 0x0, 0x80,
+ 0x7a, 0x35, 0x8, 0x2e, 0x38, 0x0, 0x80, 0x6d, 0x33, 0x7a, 0x35, 0xf, 0x7e,
+ 0x35, 0xf, 0x9, 0x63, 0x2, 0x56, 0x7e, 0xd, 0xa, 0x7e, 0xb, 0x70, 0x6c,
+ 0x76, 0x7a, 0xb, 0x70, 0x7e, 0x35, 0xf, 0xb, 0x34, 0x7a, 0x35, 0xf, 0xbe,
+ 0x34, 0x0, 0x80, 0x78, 0xe0, 0x7e, 0x35, 0x8, 0xbe, 0x34, 0x0, 0x80, 0x38,
+ 0xb4, 0xe5, 0xe, 0x60, 0x5, 0xb, 0x34, 0x7a, 0x35, 0x8, 0x7e, 0x35, 0x8,
+ 0x7a, 0x35, 0x11, 0x7f, 0x13, 0x7e, 0x8, 0x2, 0x56, 0x12, 0xe, 0x18, 0x6d,
+ 0x33, 0x80, 0x17, 0x7e, 0x35, 0xf, 0x9, 0x63, 0x2, 0x56, 0x7e, 0xd, 0xa,
+ 0x7e, 0xb, 0x70, 0x6c, 0x76, 0x7a, 0xb, 0x70, 0x7e, 0x35, 0xf, 0xb, 0x34,
+ 0x7a, 0x35, 0xf, 0x7e, 0x35, 0x8, 0xbe, 0x35, 0xf, 0x38, 0xde, 0xda, 0x3b,
+ 0x22, 0xca, 0x3b, 0x7f, 0x30, 0x7c, 0xb6, 0xf5, 0x12, 0x7c, 0xb7, 0xf5,
+ 0x13, 0x74, 0x1, 0x7e, 0x35, 0x10, 0x1e, 0x34, 0x1b, 0x34, 0x4e, 0x60, 0x80,
+ 0x12, 0x3, 0xb4, 0x12, 0x9, 0xf5, 0xa9, 0xc2, 0xb4, 0xa9, 0xc6, 0xb3, 0x75,
+ 0xb5, 0x2, 0xa9, 0x36, 0xb3, 0xfc, 0xa9, 0xc6, 0xb3, 0x75, 0xb5, 0x0, 0xa9,
+ 0x36, 0xb3, 0xfc, 0xa9, 0xc6, 0xb3, 0x85, 0x12, 0xb5, 0xa9, 0x36, 0xb3,
+ 0xfc, 0xa9, 0xc6, 0xb3, 0x85, 0x13, 0xb5, 0xa9, 0x36, 0xb3, 0xfc, 0xa9,
+ 0xc6, 0xb3, 0x6d, 0x33, 0x80, 0x2a, 0x7f, 0x13, 0x2e, 0x35, 0x14, 0x7e,
+ 0x1b, 0xb0, 0xf5, 0xb5, 0xa9, 0x36, 0xb3, 0xfc, 0xa9, 0xc6, 0xb3, 0x7e,
+ 0x35, 0x14, 0x5e, 0x34, 0x0, 0x1, 0xbe, 0x34, 0x0, 0x1, 0x78, 0x7, 0x7e,
+ 0x34, 0x0, 0x78, 0x12, 0xd, 0x96, 0x7e, 0x35, 0x14, 0xb, 0x34, 0x7a, 0x35,
+ 0x14, 0x7e, 0x35, 0x10, 0xbe, 0x35, 0x14, 0x38, 0xcb, 0xa9, 0xd2, 0xb4,
+ 0x7e, 0x34, 0x0, 0x5, 0x12, 0xd, 0x96, 0xe4, 0x12, 0x9, 0xf5, 0xda, 0x3b,
+ 0x22, 0xe5, 0x23, 0xb4, 0x80, 0x16, 0xd2, 0x7, 0x12, 0xd, 0xf4, 0xa9, 0xc2,
+ 0xb4, 0x74, 0x60, 0x12, 0xe, 0x4d, 0xa9, 0xd2, 0xb4, 0x12, 0x0, 0x2e, 0x40,
+ 0xfb, 0x22, 0x74, 0x1, 0x12, 0x9, 0xf5, 0xe4, 0x6d, 0x33, 0x12, 0x3, 0xb4,
+ 0x74, 0x1, 0x6d, 0x33, 0x12, 0x3, 0xb4, 0x74, 0x4, 0x6d, 0x33, 0x12, 0x3,
+ 0xb4, 0x7e, 0x34, 0x0, 0x54, 0x12, 0x3, 0xb4, 0x7e, 0x34, 0x0, 0x19, 0x12,
+ 0xd, 0x96, 0x74, 0x4, 0x7e, 0x34, 0x0, 0x55, 0x12, 0x3, 0xb4, 0x7e, 0x34,
+ 0xa2, 0x1c, 0x12, 0xd, 0x96, 0x74, 0x4, 0x7e, 0x34, 0x0, 0x15, 0x12, 0x3,
+ 0xb4, 0x7e, 0x34, 0x0, 0xa0, 0x12, 0xd, 0x96, 0x74, 0x4, 0x7e, 0x34, 0x0,
+ 0x14, 0x12, 0x3, 0xb4, 0x7e, 0x34, 0x0, 0x19, 0x12, 0xd, 0x96, 0x74, 0x4,
+ 0x7e, 0x34, 0x0, 0x4, 0x12, 0x3, 0xb4, 0x7e, 0x34, 0x0, 0x5, 0x12, 0xd,
+ 0x96, 0xe4, 0x12, 0x9, 0xf5, 0x74, 0x4, 0x7e, 0x34, 0xff, 0xf7, 0x2, 0x3,
+ 0xb4, 0xca, 0xf8, 0x7e, 0xf0, 0x70, 0xc2, 0x7, 0x75, 0x91, 0x0, 0xc2, 0x90,
+ 0xc2, 0x91, 0x30, 0x6, 0x4e, 0x7e, 0x34, 0x0, 0x6, 0x7a, 0x35, 0x11, 0x7e,
+ 0x18, 0xf, 0x80, 0x7e, 0x8, 0x2, 0xd6, 0x12, 0xe, 0x18, 0x7e, 0xb3, 0x2,
+ 0xd6, 0x7e, 0x73, 0x2, 0xd7, 0x12, 0xd, 0xda, 0x92, 0x7, 0x30, 0x7, 0x6,
+ 0x7e, 0xf3, 0x2, 0xd6, 0x80, 0x26, 0x7e, 0x34, 0x0, 0x6, 0x7a, 0x35, 0x11,
+ 0x7e, 0x18, 0x11, 0x20, 0x7e, 0x8, 0x2, 0xf6, 0x12, 0xe, 0x18, 0x7e, 0xb3,
+ 0x2, 0xf6, 0x7e, 0x73, 0x2, 0xf7, 0x12, 0xd, 0xda, 0x92, 0x7, 0x30, 0x7,
+ 0x4, 0x7e, 0xf3, 0x2, 0xf6, 0x20, 0x6, 0x18, 0xd2, 0xcc, 0x12, 0xe, 0x58,
+ 0x7c, 0xab, 0xc2, 0xcc, 0x7c, 0x7a, 0x6e, 0x70, 0xff, 0x12, 0xd, 0xda, 0x92,
+ 0x7, 0x30, 0x7, 0x2, 0x7c, 0xfa, 0x5e, 0xf0, 0xfe, 0x7a, 0xf1, 0x92, 0xd2,
+ 0xe8, 0xc2, 0xc0, 0xa9, 0xd5, 0xb7, 0xd2, 0xbd, 0xd2, 0xad, 0xda, 0xf8,
+ 0x22, 0x75, 0x84, 0x1, 0x7e, 0x44, 0x1f, 0xff, 0xe4, 0x7a, 0x49, 0xb0, 0x1b,
+ 0x44, 0x78, 0xf9, 0x7e, 0xf8, 0x3, 0x19, 0xd2, 0x5, 0xc2, 0x6, 0x75, 0x16,
+ 0x0, 0x75, 0x17, 0x87, 0x75, 0x18, 0xc6, 0x75, 0x19, 0x0, 0x75, 0x1a, 0x0,
+ 0xd2, 0x0, 0xc2, 0x2, 0xc2, 0x3, 0xc2, 0x4, 0x75, 0x21, 0x0, 0x75, 0x22,
+ 0x0, 0x75, 0x23, 0x80, 0x75, 0x2e, 0x0, 0x75, 0x2f, 0x0, 0x75, 0x30, 0x0,
+ 0x75, 0x31, 0x0, 0x75, 0x32, 0x0, 0x75, 0x37, 0xb, 0x75, 0x38, 0x0, 0x75,
+ 0x3d, 0x1, 0x7e, 0x4, 0x0, 0xff, 0x7e, 0x14, 0xe, 0x80, 0xb, 0xa, 0x40,
+ 0x5d, 0x44, 0x68, 0x1a, 0x69, 0x20, 0x0, 0x2, 0xb, 0xe, 0xb, 0x44, 0x80,
+ 0xa, 0x7e, 0xb, 0xb0, 0x7a, 0x29, 0xb0, 0xb, 0x24, 0xb, 0xc, 0x1b, 0x44,
+ 0x78, 0xf2, 0x80, 0xdf, 0x2, 0x4, 0x20, 0xca, 0x79, 0x7d, 0x73, 0x12, 0xe,
+ 0x62, 0x7e, 0x34, 0x0, 0x1, 0x7e, 0xf, 0x3, 0x16, 0x79, 0x30, 0x0, 0x4,
+ 0x7e, 0xf, 0x3, 0x16, 0x79, 0x30, 0x0, 0x6, 0x7e, 0x1f, 0x3, 0x16, 0x69,
+ 0x11, 0x0, 0x6, 0x4d, 0x11, 0x68, 0x9, 0x7e, 0x15, 0x19, 0xbe, 0x14, 0x0,
+ 0x3c, 0x28, 0xeb, 0x1b, 0x1a, 0x70, 0x7e, 0xf, 0x3, 0x16, 0x69, 0x30, 0x0,
+ 0x8, 0x4d, 0x33, 0x78, 0x9, 0x7e, 0x35, 0x19, 0xbe, 0x34, 0x0, 0x3c, 0x28,
+ 0xeb, 0x6d, 0x33, 0x1b, 0xa, 0x30, 0x7e, 0x1f, 0x3, 0x16, 0x69, 0x11, 0x0,
+ 0x8, 0x4d, 0x11, 0x78, 0x9, 0x7e, 0x15, 0x19, 0xbe, 0x14, 0x0, 0x3c, 0x28,
+ 0xeb, 0x69, 0x71, 0x0, 0x2, 0x12, 0xe, 0x7d, 0x7d, 0x37, 0xda, 0x79, 0x22,
+ 0x7c, 0x7b, 0x7e, 0xa0, 0xef, 0xe5, 0x21, 0x24, 0xfd, 0x68, 0x38, 0x1b,
+ 0xb1, 0x68, 0x22, 0x24, 0x9f, 0x68, 0x3d, 0x1b, 0xb2, 0x68, 0x3e, 0x24,
+ 0x9e, 0x68, 0x35, 0x24, 0x3c, 0x78, 0x4c, 0xa5, 0xbf, 0x0, 0x5, 0x7e, 0xa1,
+ 0x17, 0x80, 0x43, 0xa5, 0xbf, 0x1, 0x3f, 0x7e, 0xa1, 0x18, 0x80, 0x3a, 0xa5,
+ 0xbf, 0x0, 0x5, 0x7e, 0xa1, 0x23, 0x80, 0x31, 0xa5, 0xbf, 0x1, 0x2d, 0x7e,
+ 0xa1, 0x3d, 0x80, 0x28, 0xa, 0x17, 0x7e, 0x1d, 0x39, 0x2d, 0x31, 0x29, 0xa1,
+ 0x0, 0x8, 0x80, 0x1b, 0x7e, 0xa1, 0x16, 0x80, 0x16, 0xa5, 0xbf, 0x0, 0x9,
+ 0x7e, 0x35, 0x30, 0xa, 0x56, 0x7c, 0xab, 0x80, 0x9, 0xa5, 0xbf, 0x1, 0x5,
+ 0x7e, 0x55, 0x30, 0x7c, 0xab, 0x7c, 0xba, 0x22, 0xca, 0x79, 0xbe, 0xb0, 0x0,
+ 0x28, 0x2e, 0x74, 0x6, 0x12, 0xa, 0x5d, 0x7d, 0x73, 0x6c, 0xff, 0x7e, 0xf0,
+ 0xa5, 0x7d, 0x37, 0x12, 0x3, 0xb4, 0x6c, 0xff, 0x7e, 0xf0, 0xf, 0x7d, 0x37,
+ 0x12, 0x3, 0xb4, 0x6c, 0xff, 0x7e, 0xf0, 0x6a, 0x7d, 0x37, 0x12, 0x3, 0xb4,
+ 0x7e, 0x34, 0x0, 0x5, 0x12, 0xd, 0x96, 0x80, 0x30, 0x74, 0x1, 0x7e, 0x34,
+ 0xdf, 0xff, 0x12, 0x3, 0xb4, 0x74, 0x6, 0x12, 0xa, 0x5d, 0x7d, 0x73, 0x6c,
+ 0xff, 0x7d, 0x37, 0x12, 0x3, 0xb4, 0x7d, 0x37, 0x12, 0x3, 0xb4, 0x7d, 0x37,
+ 0x12, 0x3, 0xb4, 0x74, 0x2, 0x12, 0xa, 0x5d, 0x7d, 0x73, 0x4e, 0xf0, 0x1,
+ 0x7d, 0x37, 0x12, 0x3, 0xb4, 0xda, 0x79, 0x22, 0xa9, 0xc2, 0xb4, 0xa9, 0xc6,
+ 0xb3, 0x75, 0xb5, 0x5, 0xa9, 0x36, 0xb3, 0xfc, 0xa9, 0xc6, 0xb3, 0x75, 0xb5,
+ 0x0, 0xa9, 0x36, 0xb3, 0xfc, 0xa9, 0xc6, 0xb3, 0x75, 0xb5, 0x0, 0xa9, 0x36,
+ 0xb3, 0xfc, 0xa9, 0xc6, 0xb3, 0xf5, 0xb5, 0xa9, 0x36, 0xb3, 0xfc, 0xa9,
+ 0xc6, 0xb3, 0x75, 0xb5, 0x0, 0xa9, 0x36, 0xb3, 0xfc, 0xa9, 0xc6, 0xb3, 0x75,
+ 0xb5, 0x0, 0xa9, 0x36, 0xb3, 0xfc, 0xa9, 0xc6, 0xb3, 0x7e, 0x71, 0xb5, 0x75,
+ 0xb5, 0x0, 0xa9, 0x36, 0xb3, 0xfc, 0xa9, 0xc6, 0xb3, 0x7e, 0xa1, 0xb5, 0xa9,
+ 0xd2, 0xb4, 0x7c, 0x47, 0x6c, 0x55, 0xa, 0x3a, 0x4d, 0x32, 0x22, 0x7f, 0x70,
+ 0xd2, 0x7, 0x12, 0xd, 0xf4, 0x74, 0x2, 0x12, 0xd, 0x1b, 0x6d, 0x33, 0x80,
+ 0x12, 0x7f, 0x7, 0x2d, 0x13, 0x7e, 0xb, 0xb0, 0xf5, 0xb5, 0xa9, 0x36, 0xb3,
+ 0xfc, 0xa9, 0xc6, 0xb3, 0xb, 0x34, 0x7e, 0x25, 0x10, 0xbd, 0x23, 0x38, 0xe7,
+ 0xa9, 0xd2, 0xb4, 0x12, 0xe, 0x62, 0x12, 0x0, 0x2e, 0x50, 0x9, 0x7e, 0x35,
+ 0x19, 0xbe, 0x34, 0x1, 0xf4, 0x28, 0xf2, 0x7e, 0x35, 0x19, 0xbe, 0x34, 0x1,
+ 0xf4, 0x38, 0x3, 0x2, 0xe, 0x7d, 0xc2, 0x86, 0x7e, 0x34, 0x13, 0x88, 0x12,
+ 0xd, 0x96, 0xd2, 0x86, 0x22, 0xa9, 0xd1, 0xcb, 0xd2, 0xcc, 0x7e, 0x34, 0x0,
+ 0x4, 0x7e, 0x8, 0x2, 0x56, 0x74, 0xc, 0x12, 0xb, 0x63, 0xa9, 0xd1, 0xcb,
+ 0xc2, 0xcc, 0x6c, 0xaa, 0x7e, 0x70, 0x2, 0xac, 0x7a, 0x7e, 0x8, 0x2, 0x56,
+ 0x2d, 0x13, 0xb, 0xa, 0x30, 0x7d, 0x23, 0x7c, 0x45, 0x6c, 0x55, 0xa, 0x36,
+ 0x4d, 0x32, 0x1b, 0xa, 0x30, 0xb, 0xa0, 0xbe, 0xa0, 0xc, 0x78, 0xde, 0x7e,
+ 0x37, 0x2, 0x66, 0x7d, 0x23, 0xa, 0x54, 0x7c, 0xa7, 0xb4, 0xe7, 0xb, 0xbe,
+ 0xa0, 0x36, 0x78, 0x6, 0x75, 0x17, 0xe7, 0x75, 0x18, 0xc6, 0x22, 0x7e, 0x24,
+ 0x0, 0x1, 0x7e, 0x7f, 0x3, 0x16, 0x79, 0x27, 0x0, 0x6, 0x7e, 0x7f, 0x3,
+ 0x16, 0x69, 0x27, 0x0, 0x6, 0x4d, 0x22, 0x78, 0xf4, 0x5e, 0x60, 0x7f, 0x1b,
+ 0x7a, 0x30, 0x7e, 0x1f, 0x3, 0x16, 0x69, 0x31, 0x0, 0x8, 0x4d, 0x33, 0x68,
+ 0xf4, 0x6c, 0xaa, 0x80, 0x20, 0x6d, 0x44, 0x7e, 0x1f, 0x3, 0x16, 0x1b, 0x1a,
+ 0x40, 0x7e, 0x1f, 0x3, 0x16, 0x69, 0x41, 0x0, 0x8, 0x4d, 0x44, 0x68, 0xf4,
+ 0x69, 0x41, 0x0, 0x2, 0x1b, 0xa, 0x40, 0xb, 0x15, 0xb, 0xa0, 0xbc, 0xba,
+ 0x38, 0xdc, 0x22, 0x6d, 0x0, 0x74, 0x10, 0x4d, 0x0, 0x78, 0xb, 0x4d, 0x22,
+ 0x78, 0x27, 0x8d, 0x31, 0x7d, 0x12, 0x6d, 0x22, 0x22, 0x7d, 0x43, 0x7d,
+ 0x32, 0x6d, 0x22, 0x2f, 0x11, 0x2d, 0x44, 0x50, 0x2, 0xa5, 0xf, 0xbf, 0x10,
+ 0x40, 0x4, 0x9f, 0x10, 0xb, 0x90, 0x14, 0x78, 0xed, 0x7f, 0x1, 0x6d, 0x22,
+ 0x7d, 0x34, 0x22, 0x7d, 0x41, 0x7d, 0x13, 0x8d, 0x24, 0x7d, 0x2, 0x2f, 0x0,
+ 0x40, 0x4, 0xbd, 0x4, 0x40, 0x4, 0x9d, 0x4, 0xb, 0x14, 0x14, 0x78, 0xf1,
+ 0x7d, 0x23, 0x7d, 0x31, 0x7d, 0x10, 0x6d, 0x0, 0x22, 0x7c, 0xab, 0xd2, 0x7,
+ 0x12, 0xd, 0xf4, 0x74, 0xd8, 0xa, 0x3a, 0x7d, 0x23, 0x6d, 0x33, 0x12, 0xd,
+ 0x1b, 0xa9, 0xd2, 0xb4, 0x12, 0xe, 0x62, 0x12, 0x0, 0x2e, 0x50, 0x9, 0x7e,
+ 0x35, 0x19, 0xbe, 0x34, 0x5, 0xdc, 0x28, 0xf2, 0x7e, 0x35, 0x19, 0xbe, 0x34,
+ 0x5, 0xdc, 0x38, 0x3, 0x2, 0xe, 0x7d, 0xc2, 0x86, 0x7e, 0x34, 0x13, 0x88,
+ 0x12, 0xd, 0x96, 0xd2, 0x86, 0x22, 0xca, 0x2b, 0xca, 0x1b, 0xca, 0xb, 0xd2,
+ 0x0, 0x30, 0x90, 0x1c, 0xc2, 0x90, 0x7e, 0x71, 0x91, 0xe5, 0x38, 0x70, 0x3,
+ 0x7a, 0x71, 0x21, 0xe5, 0x38, 0x12, 0x1, 0xa0, 0x5, 0x38, 0x30, 0x2, 0x6,
+ 0xe4, 0x12, 0x9, 0x87, 0xf5, 0x91, 0x30, 0x91, 0xb, 0xc2, 0x91, 0x5, 0x38,
+ 0xe5, 0x38, 0x12, 0x9, 0x87, 0xf5, 0x91, 0xda, 0xb, 0xda, 0x1b, 0xda, 0x2b,
+ 0x32, 0xca, 0xf8, 0x7c, 0xfb, 0xe5, 0x23, 0xb4, 0x81, 0x23, 0x74, 0x2, 0x12,
+ 0xa, 0x5d, 0x4c, 0xff, 0x78, 0x8, 0xa9, 0xc0, 0xca, 0x5e, 0x70, 0xdf, 0x80,
+ 0x6, 0xa9, 0xd0, 0xca, 0x4e, 0x70, 0x20, 0x74, 0x2, 0x12, 0x3, 0xb4, 0x74,
+ 0x2, 0x12, 0xa, 0x5d, 0x80, 0x8, 0xe5, 0x23, 0xb4, 0x80, 0x3, 0x12, 0xc,
+ 0xed, 0xda, 0xf8, 0x22, 0xd2, 0x7, 0x12, 0xd, 0xf4, 0xa9, 0xc2, 0xb4, 0x74,
+ 0x9f, 0x12, 0xe, 0x4d, 0x12, 0xe, 0x34, 0xa9, 0xd2, 0xb4, 0x60, 0x3, 0xb4,
+ 0xff, 0x1a, 0x75, 0x23, 0x81, 0xa9, 0xd5, 0xca, 0xa9, 0xd0, 0xca, 0x75,
+ 0xed, 0x9f, 0x75, 0xad, 0x20, 0xa9, 0xd1, 0xea, 0xa9, 0xc1, 0xea, 0x74, 0x1,
+ 0x2, 0xc, 0x83, 0x22, 0xd2, 0x7, 0x12, 0xd, 0xf4, 0xa9, 0xc2, 0xb4, 0x74,
+ 0x5, 0x12, 0xe, 0x4d, 0x12, 0xe, 0x34, 0x7c, 0xab, 0xa9, 0xd2, 0xb4, 0x5e,
+ 0xa0, 0xe3, 0xa9, 0xc2, 0xb4, 0x74, 0x1, 0x12, 0xe, 0x4d, 0x7c, 0xba, 0x12,
+ 0xe, 0x4d, 0xa9, 0xd2, 0xb4, 0x12, 0x0, 0x2e, 0x40, 0xfb, 0x22, 0x7c, 0xab,
+ 0x7d, 0x12, 0x7c, 0xb3, 0xf5, 0x14, 0x7c, 0x36, 0x7c, 0x25, 0xa, 0x4, 0x7c,
+ 0xb3, 0xf5, 0x13, 0x7c, 0xb7, 0xf5, 0x12, 0xa9, 0xc2, 0xb4, 0x7c, 0xba,
+ 0x12, 0xe, 0x4d, 0xe5, 0x14, 0x12, 0xe, 0x4d, 0xe5, 0x13, 0x12, 0xe, 0x4d,
+ 0xe5, 0x12, 0x2, 0xe, 0x4d, 0x7d, 0x52, 0xf5, 0x15, 0x7c, 0xb6, 0x7c, 0xa5,
+ 0xa, 0x44, 0xf5, 0x14, 0x7f, 0x21, 0xf5, 0x13, 0xa9, 0xc2, 0xb4, 0x74, 0xb,
+ 0x12, 0xe, 0x4d, 0xe5, 0x15, 0x12, 0xe, 0x4d, 0xe5, 0x14, 0x12, 0xe, 0x4d,
+ 0xe5, 0x13, 0x12, 0xe, 0x4d, 0xe4, 0x2, 0xe, 0x4d, 0x12, 0xd, 0xb9, 0x12,
+ 0xb, 0xf, 0xa9, 0xa6, 0x94, 0xb3, 0x92, 0x6, 0x30, 0x6, 0x6, 0x12, 0xe,
+ 0x41, 0x12, 0xc, 0xba, 0x12, 0x8, 0x10, 0x12, 0xe, 0x26, 0xd2, 0xaf, 0x30,
+ 0x3, 0xfd, 0x2, 0xe, 0x75, 0x80, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0xe5, 0x3d, 0x70, 0xa, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x7d, 0x23, 0x1b, 0x34, 0x4d, 0x22, 0x78, 0xe0, 0x22, 0xd2,
+ 0xcf, 0x85, 0x3d, 0xcc, 0x75, 0xec, 0xff, 0x75, 0xee, 0xff, 0x75, 0xeb, 0x3,
+ 0x75, 0xac, 0x40, 0xa9, 0xc5, 0xca, 0x75, 0xed, 0xf, 0x75, 0xad, 0xb0, 0xa9,
+ 0xd7, 0x94, 0xa9, 0xd4, 0x94, 0x22, 0xa, 0x27, 0xa, 0x3b, 0x2d, 0x32, 0xbe,
+ 0x34, 0x0, 0xff, 0x78, 0xc, 0xbe, 0xb0, 0x2, 0x40, 0x7, 0xbe, 0xb0, 0xfe,
+ 0x38, 0x2, 0xd3, 0x22, 0xc3, 0x22, 0xa9, 0xc2, 0xb4, 0x30, 0x7, 0x4, 0x74,
+ 0x6, 0x80, 0x2, 0x74, 0x4, 0x12, 0xe, 0x4d, 0xa9, 0xd2, 0xb4, 0x22, 0xe5,
+ 0x32, 0xb4, 0xc, 0xb, 0xc2, 0x86, 0x7e, 0x34, 0x0, 0x64, 0x12, 0xd, 0x96,
+ 0xd2, 0x86, 0x22, 0x12, 0xd, 0x48, 0x7e, 0x35, 0x11, 0x12, 0x0, 0xe, 0xa9,
+ 0xd2, 0xb4, 0xd3, 0x22, 0xc2, 0x8c, 0x43, 0x89, 0x2, 0x75, 0x8c, 0x1, 0x75,
+ 0x8a, 0x0, 0xd2, 0xa9, 0x22, 0x75, 0xb5, 0x0, 0xa9, 0x36, 0xb3, 0xfc, 0xa9,
+ 0xc6, 0xb3, 0xe5, 0xb5, 0x22, 0xd2, 0xc8, 0x75, 0xb3, 0x13, 0xa9, 0xd1,
+ 0xb4, 0xa9, 0xc0, 0xb4, 0x22, 0xf5, 0xb5, 0xa9, 0x36, 0xb3, 0xfc, 0xa9,
+ 0xc6, 0xb3, 0xd3, 0x22, 0x7e, 0x34, 0x0, 0x4, 0x12, 0x9, 0x19, 0x7d, 0x53,
+ 0x22, 0xc2, 0x8c, 0x6d, 0x33, 0x7a, 0x35, 0x19, 0xd2, 0x8c, 0x22, 0x7e,
+ 0x35, 0x19, 0xb, 0x34, 0x7a, 0x35, 0x19, 0x22, 0x85, 0x3d, 0xcc, 0xe5, 0x3d,
+ 0x2, 0xc, 0x83, 0x2, 0xe, 0x6c, 0x0, 0x4, 0x3, 0x16, 0x0, 0x0, 0x9c, 0x0,
+ 0x0, 0x0,
diff --git a/drivers/input/touchscreen/max11801_ts.c b/drivers/input/touchscreen/max11801_ts.c
index 72ca3efb5781..03ac81b7419a 100644
--- a/drivers/input/touchscreen/max11801_ts.c
+++ b/drivers/input/touchscreen/max11801_ts.c
@@ -2,7 +2,7 @@
* Driver for MAXI MAX11801 - A Resistive touch screen controller with
* i2c interface
*
- * Copyright (C) 2011 Freescale Semiconductor, Inc.
+ * Copyright (C) 2011-2015 Freescale Semiconductor, Inc.
* Author: Zhang Jiejing <jiejing.zhang@freescale.com>
*
* Based on mcs5000_ts.c
@@ -38,6 +38,10 @@
#include <linux/input.h>
#include <linux/slab.h>
#include <linux/bitops.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
/* Register Address define */
#define GENERNAL_STATUS_REG 0x00
@@ -53,13 +57,30 @@
#define AUX_MESURE_CONF_REG 0x0a
#define OP_MODE_CONF_REG 0x0b
+#define Panel_Setup_X (0x69 << 1)
+#define Panel_Setup_Y (0x6b << 1)
+
+#define XY_combined_measurement (0x70 << 1)
+#define X_measurement (0x78 << 1)
+#define Y_measurement (0x7a << 1)
+#define AUX_measurement (0x76 << 1)
+
/* FIFO is found only in max11800 and max11801 */
#define FIFO_RD_CMD (0x50 << 1)
#define MAX11801_FIFO_INT (1 << 2)
#define MAX11801_FIFO_OVERFLOW (1 << 3)
+#define MAX11801_EDGE_INT (1 << 1)
+
+#define FIFO_RD_X_MSB (0x52 << 1)
+#define FIFO_RD_X_LSB (0x53 << 1)
+#define FIFO_RD_Y_MSB (0x54 << 1)
+#define FIFO_RD_Y_LSB (0x55 << 1)
+#define FIFO_RD_AUX_MSB (0x5a << 1)
+#define FIFO_RD_AUX_LSB (0x5b << 1)
#define XY_BUFSIZE 4
#define XY_BUF_OFFSET 4
+#define AUX_BUFSIZE 2
#define MAX11801_MAX_X 0xfff
#define MAX11801_MAX_Y 0xfff
@@ -84,6 +105,64 @@ struct max11801_data {
struct input_dev *input_dev;
};
+static struct i2c_client *max11801_client;
+static unsigned int max11801_workmode;
+static u8 aux_buf[AUX_BUFSIZE];
+
+static int max11801_dcm_write_command(struct i2c_client *client, int command)
+{
+ return i2c_smbus_write_byte(client, command);
+}
+
+static int max11801_dcm_sample_aux(struct i2c_client *client)
+{
+ int ret;
+ int aux = 0;
+ int sample_data;
+
+ /* AUX_measurement */
+ max11801_dcm_write_command(client, AUX_measurement);
+ mdelay(5);
+ ret = i2c_smbus_read_i2c_block_data(client, FIFO_RD_AUX_MSB,
+ 1, &aux_buf[0]);
+ if (ret < 0) {
+ dev_err(&client->dev, "FIFO_RD_AUX_MSB read failed (%d)\n",
+ ret);
+ return ret;
+ }
+ mdelay(5);
+ ret = i2c_smbus_read_i2c_block_data(client, FIFO_RD_AUX_LSB,
+ 1, &aux_buf[1]);
+ if (ret < 0) {
+ dev_err(&client->dev, "FIFO_RD_AUX_LSB read failed (%d)\n",
+ ret);
+ return ret;
+ }
+
+ aux = (aux_buf[0] << 4) + (aux_buf[1] >> 4);
+ /*
+ * voltage = (9170*aux)/7371;
+ * voltage is (26.2*3150*aux)/(16.2*0xFFF)
+ * V(aux)=3150*sample/0xFFF,V(battery)=212*V(aux)/81
+ * sample_data = (14840*aux)/7371-1541;
+ */
+ sample_data = (14840 * aux) / 7371;
+
+ return sample_data;
+}
+
+int max11801_read_adc(void)
+{
+ int adc_data;
+
+ if (!max11801_client)
+ return -ENODEV;
+ adc_data = max11801_dcm_sample_aux(max11801_client);
+
+ return adc_data;
+}
+EXPORT_SYMBOL_GPL(max11801_read_adc);
+
static u8 read_register(struct i2c_client *client, int addr)
{
/* XXX: The chip ignores LSB of register address */
@@ -104,21 +183,52 @@ static irqreturn_t max11801_ts_interrupt(int irq, void *dev_id)
u8 buf[XY_BUFSIZE];
int x = -1;
int y = -1;
+ u8 command = FIFO_RD_X_MSB;
status = read_register(data->client, GENERNAL_STATUS_REG);
-
- if (status & (MAX11801_FIFO_INT | MAX11801_FIFO_OVERFLOW)) {
+ if ((!max11801_workmode && (status & (MAX11801_FIFO_INT |
+ MAX11801_FIFO_OVERFLOW))) || (max11801_workmode && (status &
+ MAX11801_EDGE_INT))) {
status = read_register(data->client, GENERNAL_STATUS_REG);
-
- ret = i2c_smbus_read_i2c_block_data(client, FIFO_RD_CMD,
- XY_BUFSIZE, buf);
-
- /*
- * We should get 4 bytes buffer that contains X,Y
- * and event tag
- */
- if (ret < XY_BUFSIZE)
- goto out;
+ if (!max11801_workmode) {
+ /* ACM mode */
+ ret = i2c_smbus_read_i2c_block_data(client, FIFO_RD_CMD,
+ XY_BUFSIZE, buf);
+ /*
+ * We should get 4 bytes buffer that contains X,Y
+ * and event tag
+ */
+ if (ret < XY_BUFSIZE)
+ goto out;
+ } else {
+ /* DCM mode */
+ /* X = panel setup */
+ max11801_dcm_write_command(client, Panel_Setup_X);
+ /* X_measurement */
+ max11801_dcm_write_command(client, X_measurement);
+ for (i = 0; i < 2; i++) {
+ ret = i2c_smbus_read_i2c_block_data(client,
+ command, 1, &buf[i]);
+ if (ret < 1)
+ goto out;
+
+ command = FIFO_RD_X_LSB;
+ }
+
+ /* Y = panel setup */
+ max11801_dcm_write_command(client, Panel_Setup_Y);
+ /* Y_measurement */
+ max11801_dcm_write_command(client, Y_measurement);
+ command = FIFO_RD_Y_MSB;
+ for (i = 2; i < XY_BUFSIZE; i++) {
+ ret = i2c_smbus_read_i2c_block_data(client,
+ command, 1, &buf[i]);
+ if (ret < 1)
+ goto out;
+
+ command = FIFO_RD_Y_LSB;
+ }
+ }
for (i = 0; i < XY_BUFSIZE; i += XY_BUFSIZE / 2) {
if ((buf[i + 1] & MEASURE_TAG_MASK) == MEASURE_X_TAG)
@@ -137,6 +247,7 @@ static irqreturn_t max11801_ts_interrupt(int irq, void *dev_id)
/* fall through */
case EVENT_MIDDLE:
input_report_abs(data->input_dev, ABS_X, x);
+ y = MAX11801_MAX_Y - y; /* Calibration */
input_report_abs(data->input_dev, ABS_Y, y);
input_event(data->input_dev, EV_KEY, BTN_TOUCH, 1);
input_sync(data->input_dev);
@@ -159,7 +270,8 @@ static void max11801_ts_phy_init(struct max11801_data *data)
{
struct i2c_client *client = data->client;
- /* Average X,Y, take 16 samples, average eight media sample */
+ max11801_client = client;
+ /* Average X,Y, take 16 samples average eight media sample */
max11801_write_reg(client, MESURE_AVER_CONF_REG, 0xff);
/* X,Y panel setup time set to 20us */
max11801_write_reg(client, PANEL_SETUPTIME_CONF_REG, 0x11);
@@ -170,7 +282,22 @@ static void max11801_ts_phy_init(struct max11801_data *data)
/* Aperture X,Y set to +- 4LSB */
max11801_write_reg(client, APERTURE_CONF_REG, 0x33);
/* Enable Power, enable Automode, enable Aperture, enable Average X,Y */
- max11801_write_reg(client, OP_MODE_CONF_REG, 0x36);
+ if (!max11801_workmode)
+ max11801_write_reg(client, OP_MODE_CONF_REG, 0x36);
+ else {
+ max11801_write_reg(client, OP_MODE_CONF_REG, 0x16);
+ /*
+ * Delay initial=1ms, Sampling time 2us
+ * Averaging sample depth 2
+ * samples, Resolution 12bit
+ */
+ max11801_write_reg(client, AUX_MESURE_CONF_REG, 0x76);
+ /*
+ * Use edge interrupt with
+ * direct conversion mode
+ */
+ max11801_write_reg(client, GENERNAL_CONF_REG, 0xf3);
+ }
}
static int max11801_ts_probe(struct i2c_client *client,
@@ -179,6 +306,7 @@ static int max11801_ts_probe(struct i2c_client *client,
struct max11801_data *data;
struct input_dev *input_dev;
int error;
+ struct device_node *of_node = client->dev.of_node;
data = devm_kzalloc(&client->dev, sizeof(*data), GFP_KERNEL);
input_dev = devm_input_allocate_device(&client->dev);
@@ -200,6 +328,9 @@ static int max11801_ts_probe(struct i2c_client *client,
input_set_abs_params(input_dev, ABS_X, 0, MAX11801_MAX_X, 0, 0);
input_set_abs_params(input_dev, ABS_Y, 0, MAX11801_MAX_Y, 0, 0);
+ if (of_property_read_u32(of_node, "work-mode", &max11801_workmode))
+ max11801_workmode = *(int *)(client->dev).platform_data;
+
max11801_ts_phy_init(data);
error = devm_request_threaded_irq(&client->dev, client->irq, NULL,
diff --git a/drivers/input/touchscreen/synaptics_dsx/Kconfig b/drivers/input/touchscreen/synaptics_dsx/Kconfig
new file mode 100644
index 000000000000..6410f7ec7cd1
--- /dev/null
+++ b/drivers/input/touchscreen/synaptics_dsx/Kconfig
@@ -0,0 +1,27 @@
+#
+# Synaptics DSX touchscreen driver configuration
+#
+menuconfig TOUCHSCREEN_SYNAPTICS_DSX
+ bool "Synaptics DSX touchscreen"
+ default y
+ help
+ Say Y here if you have a Synaptics DSX I2C touchscreen
+ connected to your system
+
+ if unsure, say N.
+
+if TOUCHSCREEN_SYNAPTICS_DSX
+
+config TOUCHSCREEN_SYNAPTICS_DSX_I2C
+ tristate "Synaptics DSX core driver module"
+ depends on I2C
+ help
+ Say Y here if you have a Synaptics DSX I2C touchscreen
+ connected to your system
+
+ If unsure, say N.
+
+ To compile this driver as a module, choose M here: the
+ module will be called synaptics_dsx_i2c.
+
+endif
diff --git a/drivers/input/touchscreen/synaptics_dsx/Makefile b/drivers/input/touchscreen/synaptics_dsx/Makefile
new file mode 100644
index 000000000000..b46f3df6d9d5
--- /dev/null
+++ b/drivers/input/touchscreen/synaptics_dsx/Makefile
@@ -0,0 +1,2 @@
+obj-$(CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_I2C) += synaptics_dsx_i2c.o
+
diff --git a/drivers/input/touchscreen/synaptics_dsx/synaptics_dsx.h b/drivers/input/touchscreen/synaptics_dsx/synaptics_dsx.h
new file mode 100644
index 000000000000..5adeb65b6b3f
--- /dev/null
+++ b/drivers/input/touchscreen/synaptics_dsx/synaptics_dsx.h
@@ -0,0 +1,86 @@
+/*
+ * Synaptics DSX touchscreen driver
+ *
+ * Copyright (C) 2012-2015 Synaptics Incorporated. All rights reserved.
+ *
+ * Copyright (C) 2012 Alexandra Chin <alexandra.chin@tw.synaptics.com>
+ * Copyright (C) 2012 Scott Lin <scott.lin@tw.synaptics.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.
+ *
+ * INFORMATION CONTAINED IN THIS DOCUMENT IS PROVIDED "AS-IS," AND SYNAPTICS
+ * EXPRESSLY DISCLAIMS ALL EXPRESS AND IMPLIED WARRANTIES, INCLUDING ANY
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE,
+ * AND ANY WARRANTIES OF NON-INFRINGEMENT OF ANY INTELLECTUAL PROPERTY RIGHTS.
+ * IN NO EVENT SHALL SYNAPTICS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, PUNITIVE, OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OF THE INFORMATION CONTAINED IN THIS DOCUMENT, HOWEVER CAUSED
+ * AND BASED ON ANY THEORY OF LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, AND EVEN IF SYNAPTICS WAS ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE. IF A TRIBUNAL OF COMPETENT JURISDICTION DOES
+ * NOT PERMIT THE DISCLAIMER OF DIRECT DAMAGES OR ANY OTHER DAMAGES, SYNAPTICS'
+ * TOTAL CUMULATIVE LIABILITY TO ANY PARTY SHALL NOT EXCEED ONE HUNDRED U.S.
+ * DOLLARS.
+ */
+
+#ifndef _SYNAPTICS_DSX_H_
+#define _SYNAPTICS_DSX_H_
+
+/*
+ * synaptics_dsx_cap_button_map - 0d button map
+ * @nbuttons: number of 0d buttons
+ * @map: pointer to array of button types
+ */
+struct synaptics_dsx_cap_button_map {
+ unsigned int nbuttons;
+ unsigned int *map;
+};
+
+/*
+ * struct synaptics_dsx_platform_data - dsx platform data
+ * @x_flip: x flip flag
+ * @y_flip: y flip flag
+ * @irq_gpio: attention interrupt gpio
+ * @power_gpio: power switch gpio
+ * @power_on_state: power switch active state
+ * @reset_gpio: reset gpio
+ * @reset_on_state: reset active state
+ * @irq_flags: irq flags
+ * @panel_x: x-axis resolution of display panel
+ * @panel_y: y-axis resolution of display panel
+ * @power_delay_ms: delay time to wait after power-on
+ * @reset_delay_ms: delay time to wait after reset
+ * @reset_active_ms: reset active time
+ * @regulator_name: pointer to name of regulator
+ * @gpio_config: pointer to gpio configuration function
+ * @cap_button_map: pointer to 0d button map
+ */
+struct synaptics_dsx_platform_data {
+ bool x_flip;
+ bool y_flip;
+ bool swap_axes;
+ int irq_gpio;
+ int power_gpio;
+ int power_on_state;
+ int reset_gpio;
+ int reset_on_state;
+ unsigned long irq_flags;
+ unsigned int panel_x;
+ unsigned int panel_y;
+ unsigned int power_delay_ms;
+ unsigned int reset_delay_ms;
+ unsigned int reset_active_ms;
+ unsigned char *regulator_name;
+ int (*gpio_config)(int gpio, bool configure, int dir, int state);
+ struct synaptics_dsx_cap_button_map *cap_button_map;
+};
+
+#endif
diff --git a/drivers/input/touchscreen/synaptics_dsx/synaptics_dsx_i2c.c b/drivers/input/touchscreen/synaptics_dsx/synaptics_dsx_i2c.c
new file mode 100644
index 000000000000..c31c13ab407e
--- /dev/null
+++ b/drivers/input/touchscreen/synaptics_dsx/synaptics_dsx_i2c.c
@@ -0,0 +1,3622 @@
+/*
+ * Synaptics DSX touchscreen driver
+ *
+ * Copyright (C) 2012-2015 Synaptics Incorporated. All rights reserved.
+ *
+ * Copyright (C) 2012 Alexandra Chin <alexandra.chin@tw.synaptics.com>
+ * Copyright (C) 2012 Scott Lin <scott.lin@tw.synaptics.com>
+ * Copyright 2018 NXP
+ *
+ * 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.
+ *
+ * INFORMATION CONTAINED IN THIS DOCUMENT IS PROVIDED "AS-IS," AND SYNAPTICS
+ * EXPRESSLY DISCLAIMS ALL EXPRESS AND IMPLIED WARRANTIES, INCLUDING ANY
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE,
+ * AND ANY WARRANTIES OF NON-INFRINGEMENT OF ANY INTELLECTUAL PROPERTY RIGHTS.
+ * IN NO EVENT SHALL SYNAPTICS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, PUNITIVE, OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OF THE INFORMATION CONTAINED IN THIS DOCUMENT, HOWEVER CAUSED
+ * AND BASED ON ANY THEORY OF LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, AND EVEN IF SYNAPTICS WAS ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE. IF A TRIBUNAL OF COMPETENT JURISDICTION DOES
+ * NOT PERMIT THE DISCLAIMER OF DIRECT DAMAGES OR ANY OTHER DAMAGES, SYNAPTICS'
+ * TOTAL CUMULATIVE LIABILITY TO ANY PARTY SHALL NOT EXCEED ONE HUNDRED U.S.
+ * DOLLARS.
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/input.h>
+#include <linux/stringify.h>
+#include <linux/gpio.h>
+#include <linux/regulator/consumer.h>
+#include <linux/dma-mapping.h>
+#include <linux/kthread.h>
+#include <linux/device.h>
+#include <linux/fs.h>
+#include <linux/gpio.h>
+
+#include "synaptics_dsx_i2c.h"
+#include "synaptics_dsx.h"
+
+#include <linux/of.h>
+#include <linux/of_irq.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/of_gpio.h>
+
+#include <linux/input/mt.h>
+
+
+#define DRIVER_NAME "synaptics_dsx_i2c"
+#define INPUT_PHYS_NAME "synaptics_dsx_i2c/input0"
+
+#define TYPE_B_PROTOCOL
+
+#define UBL_I2C_ADDR 0x2c
+
+#define SENSOR_MAX_X 1080
+#define SENSOR_MAX_Y 1920
+
+#define WAKEUP_GESTURE false
+
+#define NO_0D_WHILE_2D
+#define REPORT_2D_W
+
+#define F12_DATA_15_WORKAROUND
+
+#define RPT_TYPE (1 << 0)
+#define RPT_X_LSB (1 << 1)
+#define RPT_X_MSB (1 << 2)
+#define RPT_Y_LSB (1 << 3)
+#define RPT_Y_MSB (1 << 4)
+#define RPT_Z (1 << 5)
+#define RPT_WX (1 << 6)
+#define RPT_WY (1 << 7)
+#define RPT_DEFAULT (RPT_TYPE | RPT_X_LSB | RPT_X_MSB | RPT_Y_LSB | RPT_Y_MSB)
+#define attrify(propname) (&dev_attr_##propname.attr)
+
+#define EXP_FN_WORK_DELAY_MS 1000 /* ms */
+#define SYN_I2C_RETRY_TIMES 5
+#define MAX_F11_TOUCH_WIDTH 15
+
+#define CHECK_STATUS_TIMEOUT_MS 100
+#define DELAY_BOOT_READY 200
+#define DELAY_RESET_LOW 20
+#define DELAY_UI_READY 200
+
+#define F01_STD_QUERY_LEN 21
+#define F01_BUID_ID_OFFSET 18
+#define F11_STD_QUERY_LEN 9
+#define F11_STD_CTRL_LEN 10
+#define F11_STD_DATA_LEN 12
+
+#define STATUS_NO_ERROR 0x00
+#define STATUS_RESET_OCCURRED 0x01
+#define STATUS_INVALID_CONFIG 0x02
+#define STATUS_DEVICE_FAILURE 0x03
+#define STATUS_CONFIG_CRC_FAILURE 0x04
+#define STATUS_FIRMWARE_CRC_FAILURE 0x05
+#define STATUS_CRC_IN_PROGRESS 0x06
+
+#define NORMAL_OPERATION (0 << 0)
+#define SENSOR_SLEEP (1 << 0)
+#define NO_SLEEP_OFF (0 << 2)
+#define NO_SLEEP_ON (1 << 2)
+#define CONFIGURED (1 << 7)
+
+
+#define F11_CONTINUOUS_MODE 0x00
+#define F11_WAKEUP_GESTURE_MODE 0x04
+#define F12_CONTINUOUS_MODE 0x00
+#define F12_WAKEUP_GESTURE_MODE 0x02
+
+#define F12_UDG_DETECT 0x0f
+
+#ifdef USE_I2C_DMA
+#include <linux/dma-mapping.h>
+static unsigned char *wDMABuf_va;
+static dma_addr_t wDMABuf_pa;
+#endif
+
+static struct task_struct *thread;
+static DECLARE_WAIT_QUEUE_HEAD(waiter);
+static int tpd_flag;
+DEFINE_MUTEX(rmi4_report_mutex);
+static struct device *g_dev;
+
+/* for 0D button */
+static unsigned int cap_button_codes[] = {KEY_APPSELECT, KEY_HOMEPAGE, KEY_BACK};
+static struct synaptics_dsx_cap_button_map cap_button_map = {
+ .nbuttons = ARRAY_SIZE(cap_button_codes),
+ .map = cap_button_codes,
+};
+
+#ifdef CONFIG_OF_TOUCH
+unsigned int touch_irq;
+#endif
+
+#ifdef CONFIG_OF_TOUCH
+static irqreturn_t tpd_eint_handler(unsigned int irq, struct irq_desc *desc);
+#else
+static void tpd_eint_handler(void);
+#endif
+
+static int touch_event_handler(void *data);
+
+static int synaptics_rmi4_i2c_read(struct synaptics_rmi4_data *rmi4_data,
+ unsigned short addr, unsigned char *data,
+ unsigned short length);
+
+static int synaptics_rmi4_i2c_write(struct synaptics_rmi4_data *rmi4_data,
+ unsigned short addr, unsigned char *data,
+ unsigned short length);
+
+static int synaptics_rmi4_f12_set_enables(struct synaptics_rmi4_data *rmi4_data,
+ unsigned short ctrl28);
+
+static int synaptics_rmi4_free_fingers(struct synaptics_rmi4_data *rmi4_data);
+static int synaptics_rmi4_reinit_device(struct synaptics_rmi4_data *rmi4_data);
+static int synaptics_rmi4_reset_device(struct synaptics_rmi4_data *rmi4_data);
+
+
+static int __maybe_unused synaptics_rmi4_suspend(struct device *dev);
+
+static int __maybe_unused synaptics_rmi4_resume(struct device *dev);
+
+static ssize_t synaptics_rmi4_f01_reset_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count);
+
+static ssize_t synaptics_rmi4_f01_productinfo_show(struct device *dev,
+ struct device_attribute *attr, char *buf);
+
+static ssize_t synaptics_rmi4_f01_buildid_show(struct device *dev,
+ struct device_attribute *attr, char *buf);
+
+static ssize_t synaptics_rmi4_f01_flashprog_show(struct device *dev,
+ struct device_attribute *attr, char *buf);
+
+static ssize_t synaptics_rmi4_0dbutton_show(struct device *dev,
+ struct device_attribute *attr, char *buf);
+
+static ssize_t synaptics_rmi4_0dbutton_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count);
+
+static ssize_t synaptics_rmi4_suspend_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count);
+
+static ssize_t synaptics_rmi4_wake_gesture_show(struct device *dev,
+ struct device_attribute *attr, char *buf);
+
+static ssize_t synaptics_rmi4_wake_gesture_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count);
+struct synaptics_rmi4_f01_device_status {
+ union {
+ struct {
+ unsigned char status_code:4;
+ unsigned char reserved:2;
+ unsigned char flash_prog:1;
+ unsigned char unconfigured:1;
+ } __packed;
+ unsigned char data[1];
+ };
+};
+
+struct synaptics_rmi4_f11_query_0_5 {
+ union {
+ struct {
+ /* query 0 */
+ unsigned char f11_query0_b0__2:3;
+ unsigned char has_query_9:1;
+ unsigned char has_query_11:1;
+ unsigned char has_query_12:1;
+ unsigned char has_query_27:1;
+ unsigned char has_query_28:1;
+
+ /* query 1 */
+ unsigned char num_of_fingers:3;
+ unsigned char has_rel:1;
+ unsigned char has_abs:1;
+ unsigned char has_gestures:1;
+ unsigned char has_sensitibity_adjust:1;
+ unsigned char f11_query1_b7:1;
+
+ /* query 2 */
+ unsigned char num_of_x_electrodes;
+
+ /* query 3 */
+ unsigned char num_of_y_electrodes;
+
+ /* query 4 */
+ unsigned char max_electrodes:7;
+ unsigned char f11_query4_b7:1;
+
+ /* query 5 */
+ unsigned char abs_data_size:2;
+ unsigned char has_anchored_finger:1;
+ unsigned char has_adj_hyst:1;
+ unsigned char has_dribble:1;
+ unsigned char has_bending_correction:1;
+ unsigned char has_large_object_suppression:1;
+ unsigned char has_jitter_filter:1;
+ } __packed;
+ unsigned char data[6];
+ };
+};
+
+struct synaptics_rmi4_f11_query_7_8 {
+ union {
+ struct {
+ /* query 7 */
+ unsigned char has_single_tap:1;
+ unsigned char has_tap_and_hold:1;
+ unsigned char has_double_tap:1;
+ unsigned char has_early_tap:1;
+ unsigned char has_flick:1;
+ unsigned char has_press:1;
+ unsigned char has_pinch:1;
+ unsigned char has_chiral_scroll:1;
+
+ /* query 8 */
+ unsigned char has_palm_detect:1;
+ unsigned char has_rotate:1;
+ unsigned char has_touch_shapes:1;
+ unsigned char has_scroll_zones:1;
+ unsigned char individual_scroll_zones:1;
+ unsigned char has_multi_finger_scroll:1;
+ unsigned char has_multi_finger_scroll_edge_motion:1;
+ unsigned char has_multi_finger_scroll_inertia:1;
+ } __packed;
+ unsigned char data[2];
+ };
+};
+
+struct synaptics_rmi4_f11_query_9 {
+ union {
+ struct {
+ unsigned char has_pen:1;
+ unsigned char has_proximity:1;
+ unsigned char has_large_object_sensitivity:1;
+ unsigned char has_suppress_on_large_object_detect:1;
+ unsigned char has_two_pen_thresholds:1;
+ unsigned char has_contact_geometry:1;
+ unsigned char has_pen_hover_discrimination:1;
+ unsigned char has_pen_hover_and_edge_filters:1;
+ } __packed;
+ unsigned char data[1];
+ };
+};
+
+struct synaptics_rmi4_f11_query_12 {
+ union {
+ struct {
+ unsigned char has_small_object_detection:1;
+ unsigned char has_small_object_detection_tuning:1;
+ unsigned char has_8bit_w:1;
+ unsigned char has_2d_adjustable_mapping:1;
+ unsigned char has_general_information_2:1;
+ unsigned char has_physical_properties:1;
+ unsigned char has_finger_limit:1;
+ unsigned char has_linear_cofficient_2:1;
+ } __packed;
+ unsigned char data[1];
+ };
+};
+
+struct synaptics_rmi4_f11_query_27 {
+ union {
+ struct {
+ unsigned char f11_query27_b0:1;
+ unsigned char has_pen_position_correction:1;
+ unsigned char has_pen_jitter_filter_coefficient:1;
+ unsigned char has_group_decomposition:1;
+ unsigned char has_wakeup_gesture:1;
+ unsigned char has_small_finger_correction:1;
+ unsigned char has_data_37:1;
+ unsigned char f11_query27_b7:1;
+ } __packed;
+ unsigned char data[1];
+ };
+};
+
+struct synaptics_rmi4_f11_ctrl_6_9 {
+ union {
+ struct {
+ unsigned char sensor_max_x_pos_7_0;
+ unsigned char sensor_max_x_pos_11_8:4;
+ unsigned char f11_ctrl7_b4__7:4;
+ unsigned char sensor_max_y_pos_7_0;
+ unsigned char sensor_max_y_pos_11_8:4;
+ unsigned char f11_ctrl9_b4__7:4;
+ } __packed;
+ unsigned char data[4];
+ };
+};
+
+struct synaptics_rmi4_f11_data_1_5 {
+ union {
+ struct {
+ unsigned char x_position_11_4;
+ unsigned char y_position_11_4;
+ unsigned char x_position_3_0:4;
+ unsigned char y_position_3_0:4;
+ unsigned char wx:4;
+ unsigned char wy:4;
+ unsigned char z;
+ } __packed;
+ unsigned char data[5];
+ };
+};
+
+struct synaptics_rmi4_f12_query_5 {
+ union {
+ struct {
+ unsigned char size_of_query6;
+ struct {
+ unsigned char ctrl0_is_present:1;
+ unsigned char ctrl1_is_present:1;
+ unsigned char ctrl2_is_present:1;
+ unsigned char ctrl3_is_present:1;
+ unsigned char ctrl4_is_present:1;
+ unsigned char ctrl5_is_present:1;
+ unsigned char ctrl6_is_present:1;
+ unsigned char ctrl7_is_present:1;
+ } __packed;
+ struct {
+ unsigned char ctrl8_is_present:1;
+ unsigned char ctrl9_is_present:1;
+ unsigned char ctrl10_is_present:1;
+ unsigned char ctrl11_is_present:1;
+ unsigned char ctrl12_is_present:1;
+ unsigned char ctrl13_is_present:1;
+ unsigned char ctrl14_is_present:1;
+ unsigned char ctrl15_is_present:1;
+ } __packed;
+ struct {
+ unsigned char ctrl16_is_present:1;
+ unsigned char ctrl17_is_present:1;
+ unsigned char ctrl18_is_present:1;
+ unsigned char ctrl19_is_present:1;
+ unsigned char ctrl20_is_present:1;
+ unsigned char ctrl21_is_present:1;
+ unsigned char ctrl22_is_present:1;
+ unsigned char ctrl23_is_present:1;
+ } __packed;
+ struct {
+ unsigned char ctrl24_is_present:1;
+ unsigned char ctrl25_is_present:1;
+ unsigned char ctrl26_is_present:1;
+ unsigned char ctrl27_is_present:1;
+ unsigned char ctrl28_is_present:1;
+ unsigned char ctrl29_is_present:1;
+ unsigned char ctrl30_is_present:1;
+ unsigned char ctrl31_is_present:1;
+ } __packed;
+ };
+ unsigned char data[5];
+ };
+};
+
+struct synaptics_rmi4_f12_query_8 {
+ union {
+ struct {
+ unsigned char size_of_query9;
+ struct {
+ unsigned char data0_is_present:1;
+ unsigned char data1_is_present:1;
+ unsigned char data2_is_present:1;
+ unsigned char data3_is_present:1;
+ unsigned char data4_is_present:1;
+ unsigned char data5_is_present:1;
+ unsigned char data6_is_present:1;
+ unsigned char data7_is_present:1;
+ } __packed;
+ struct {
+ unsigned char data8_is_present:1;
+ unsigned char data9_is_present:1;
+ unsigned char data10_is_present:1;
+ unsigned char data11_is_present:1;
+ unsigned char data12_is_present:1;
+ unsigned char data13_is_present:1;
+ unsigned char data14_is_present:1;
+ unsigned char data15_is_present:1;
+ } __packed;
+ };
+ unsigned char data[3];
+ };
+};
+
+struct synaptics_rmi4_f12_ctrl_8 {
+ union {
+ struct {
+ unsigned char max_x_coord_lsb;
+ unsigned char max_x_coord_msb;
+ unsigned char max_y_coord_lsb;
+ unsigned char max_y_coord_msb;
+ unsigned char rx_pitch_lsb;
+ unsigned char rx_pitch_msb;
+ unsigned char tx_pitch_lsb;
+ unsigned char tx_pitch_msb;
+ unsigned char low_rx_clip;
+ unsigned char high_rx_clip;
+ unsigned char low_tx_clip;
+ unsigned char high_tx_clip;
+ unsigned char num_of_rx;
+ unsigned char num_of_tx;
+ };
+ unsigned char data[14];
+ };
+};
+
+struct synaptics_rmi4_f12_ctrl_23 {
+ union {
+ struct {
+ unsigned char obj_type_enable;
+ unsigned char max_reported_objects;
+ };
+ unsigned char data[2];
+ };
+};
+
+struct synaptics_rmi4_f12_finger_data {
+ unsigned char object_type_and_status;
+ unsigned char x_lsb;
+ unsigned char x_msb;
+ unsigned char y_lsb;
+ unsigned char y_msb;
+#ifdef REPORT_2D_Z
+ unsigned char z;
+#endif
+#ifdef REPORT_2D_W
+ unsigned char wx;
+ unsigned char wy;
+#endif
+};
+
+struct synaptics_rmi4_f1a_query {
+ union {
+ struct {
+ unsigned char max_button_count:3;
+ unsigned char reserved:5;
+ unsigned char has_general_control:1;
+ unsigned char has_interrupt_enable:1;
+ unsigned char has_multibutton_select:1;
+ unsigned char has_tx_rx_map:1;
+ unsigned char has_perbutton_threshold:1;
+ unsigned char has_release_threshold:1;
+ unsigned char has_strongestbtn_hysteresis:1;
+ unsigned char has_filter_strength:1;
+ } __packed;
+ unsigned char data[2];
+ };
+};
+
+struct synaptics_rmi4_f1a_control_0 {
+ union {
+ struct {
+ unsigned char multibutton_report:2;
+ unsigned char filter_mode:2;
+ unsigned char reserved:4;
+ } __packed;
+ unsigned char data[1];
+ };
+};
+
+struct synaptics_rmi4_f1a_control {
+ struct synaptics_rmi4_f1a_control_0 general_control;
+ unsigned char button_int_enable;
+ unsigned char multi_button;
+ unsigned char *txrx_map;
+ unsigned char *button_threshold;
+ unsigned char button_release_threshold;
+ unsigned char strongest_button_hysteresis;
+ unsigned char filter_strength;
+};
+
+struct synaptics_rmi4_f1a_handle {
+ int button_bitmask_size;
+ unsigned int max_count;
+ unsigned char valid_button_count;
+ unsigned char *button_data_buffer;
+ unsigned int *button_map;
+ struct synaptics_rmi4_f1a_query button_query;
+ struct synaptics_rmi4_f1a_control button_control;
+};
+
+struct synaptics_rmi4_exp_fhandler {
+ struct synaptics_rmi4_exp_fn *exp_fn;
+ bool insert;
+ bool remove;
+ struct list_head link;
+};
+
+struct synaptics_rmi4_exp_fn_data {
+ bool initialized;
+ bool queue_work;
+ struct mutex mutex;
+ struct list_head list;
+ struct delayed_work work;
+ struct workqueue_struct *workqueue;
+ struct synaptics_rmi4_data *rmi4_data;
+};
+
+static struct synaptics_rmi4_exp_fn_data exp_data;
+
+static struct device_attribute attrs[] = {
+ __ATTR(reset, 0660,
+ synaptics_rmi4_show_error,
+ synaptics_rmi4_f01_reset_store),
+ __ATTR(productinfo, 0444,
+ synaptics_rmi4_f01_productinfo_show,
+ synaptics_rmi4_store_error),
+ __ATTR(buildid, 0444,
+ synaptics_rmi4_f01_buildid_show,
+ synaptics_rmi4_store_error),
+ __ATTR(flashprog, 0444,
+ synaptics_rmi4_f01_flashprog_show,
+ synaptics_rmi4_store_error),
+ __ATTR(0dbutton, 0660,
+ synaptics_rmi4_0dbutton_show,
+ synaptics_rmi4_0dbutton_store),
+ __ATTR(suspend, 0660,
+ synaptics_rmi4_show_error,
+ synaptics_rmi4_suspend_store),
+ __ATTR(wake_gesture, 0660,
+ synaptics_rmi4_wake_gesture_show,
+ synaptics_rmi4_wake_gesture_store),
+};
+
+static ssize_t synaptics_rmi4_f01_reset_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ int retval;
+ unsigned int reset;
+ struct synaptics_rmi4_data *rmi4_data = dev_get_drvdata(dev);
+
+ if (sscanf(buf, "%u", &reset) != 1)
+ return -EINVAL;
+
+ if (reset != 1)
+ return -EINVAL;
+
+ retval = synaptics_rmi4_reset_device(rmi4_data);
+ if (retval < 0) {
+ dev_err(dev,
+ "%s: Failed to issue reset command, error = %d\n",
+ __func__, retval);
+ return retval;
+ }
+
+ return count;
+}
+
+static ssize_t synaptics_rmi4_f01_productinfo_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct synaptics_rmi4_data *rmi4_data = dev_get_drvdata(dev);
+
+ return snprintf(buf, PAGE_SIZE, "0x%02x 0x%02x\n",
+ (rmi4_data->rmi4_mod_info.product_info[0]),
+ (rmi4_data->rmi4_mod_info.product_info[1]));
+}
+
+static ssize_t synaptics_rmi4_f01_buildid_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct synaptics_rmi4_data *rmi4_data = dev_get_drvdata(dev);
+
+ return snprintf(buf, PAGE_SIZE, "%u\n",
+ rmi4_data->firmware_id);
+}
+
+static ssize_t synaptics_rmi4_f01_flashprog_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int retval;
+ struct synaptics_rmi4_f01_device_status device_status;
+ struct synaptics_rmi4_data *rmi4_data = dev_get_drvdata(dev);
+
+ retval = synaptics_rmi4_i2c_read(rmi4_data,
+ rmi4_data->f01_data_base_addr,
+ device_status.data,
+ sizeof(device_status.data));
+ if (retval < 0) {
+ dev_err(dev,
+ "%s: Failed to read device status, error = %d\n",
+ __func__, retval);
+ return retval;
+ }
+
+ return snprintf(buf, PAGE_SIZE, "%u\n",
+ device_status.flash_prog);
+}
+
+static ssize_t synaptics_rmi4_0dbutton_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct synaptics_rmi4_data *rmi4_data = dev_get_drvdata(dev);
+
+ return snprintf(buf, PAGE_SIZE, "%u\n",
+ rmi4_data->button_0d_enabled);
+}
+
+static ssize_t synaptics_rmi4_0dbutton_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ int retval;
+ unsigned int input;
+ unsigned char ii;
+ unsigned char intr_enable;
+ struct synaptics_rmi4_fn *fhandler;
+ struct synaptics_rmi4_data *rmi4_data = dev_get_drvdata(dev);
+ struct synaptics_rmi4_device_info *rmi;
+
+ rmi = &(rmi4_data->rmi4_mod_info);
+
+ if (sscanf(buf, "%u", &input) != 1)
+ return -EINVAL;
+
+ input = input > 0 ? 1 : 0;
+
+ if (rmi4_data->button_0d_enabled == input)
+ return count;
+
+ if (list_empty(&rmi->support_fn_list))
+ return -ENODEV;
+
+ list_for_each_entry(fhandler, &rmi->support_fn_list, link) {
+ if (fhandler->fn_number == SYNAPTICS_RMI4_F1A) {
+ ii = fhandler->intr_reg_num;
+
+ retval = synaptics_rmi4_i2c_read(rmi4_data,
+ rmi4_data->f01_ctrl_base_addr + 1 + ii,
+ &intr_enable,
+ sizeof(intr_enable));
+ if (retval < 0)
+ return retval;
+
+ if (input == 1)
+ intr_enable |= fhandler->intr_mask;
+ else
+ intr_enable &= ~fhandler->intr_mask;
+
+ retval = synaptics_rmi4_i2c_write(rmi4_data,
+ rmi4_data->f01_ctrl_base_addr + 1 + ii,
+ &intr_enable,
+ sizeof(intr_enable));
+ if (retval < 0)
+ return retval;
+ }
+ }
+
+ rmi4_data->button_0d_enabled = input;
+
+ return count;
+}
+
+static ssize_t synaptics_rmi4_suspend_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ unsigned int input;
+
+ if (sscanf(buf, "%u", &input) != 1)
+ return -EINVAL;
+
+ if (input == 1)
+ synaptics_rmi4_suspend(dev);
+ else if (input == 0)
+ synaptics_rmi4_resume(dev);
+ else
+ return -EINVAL;
+
+ return count;
+}
+
+
+static ssize_t synaptics_rmi4_wake_gesture_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct synaptics_rmi4_data *rmi4_data = dev_get_drvdata(dev);
+
+ return snprintf(buf, PAGE_SIZE, "%u\n",
+ rmi4_data->enable_wakeup_gesture);
+}
+
+static ssize_t synaptics_rmi4_wake_gesture_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ unsigned int input;
+ struct synaptics_rmi4_data *rmi4_data = dev_get_drvdata(dev);
+
+ if (sscanf(buf, "%u", &input) != 1)
+ return -EINVAL;
+
+ input = input > 0 ? 1 : 0;
+
+ if (rmi4_data->f11_wakeup_gesture || rmi4_data->f12_wakeup_gesture)
+ rmi4_data->enable_wakeup_gesture = input;
+
+ return count;
+}
+
+static int tpd_set_page(struct synaptics_rmi4_data *rmi4_data,
+ unsigned short addr)
+{
+ int retval = 0;
+ unsigned char retry;
+ unsigned char buf[PAGE_SELECT_LEN];
+ unsigned char page;
+ struct i2c_client *i2c = rmi4_data->i2c_client;
+
+ page = ((addr >> 8) & MASK_8BIT);
+ if (page != rmi4_data->current_page) {
+ buf[0] = MASK_8BIT;
+ buf[1] = page;
+ for (retry = 0; retry < SYN_I2C_RETRY_TIMES; retry++) {
+ retval = i2c_master_send(i2c, buf, PAGE_SELECT_LEN);
+ if (retval != PAGE_SELECT_LEN) {
+ dev_err(&rmi4_data->i2c_client->dev,
+ "%s: I2C retry %d\n", __func__, retry + 1);
+ msleep(20);
+ if (retry == (SYN_I2C_RETRY_TIMES / 2)) {
+ if (i2c->addr == rmi4_data->i2c_addr)
+ i2c->addr = UBL_I2C_ADDR;
+ else
+ i2c->addr = rmi4_data->i2c_addr;
+ }
+ } else {
+ rmi4_data->current_page = page;
+ break;
+ }
+ }
+ } else {
+ retval = PAGE_SELECT_LEN;
+ }
+
+ return retval;
+}
+
+
+int tpd_i2c_read_data(struct synaptics_rmi4_data *rmi4_data, struct i2c_client *client,
+ unsigned short addr, unsigned char *data, unsigned short length)
+{
+
+ unsigned char retry = 0;
+ unsigned char *pData = data;
+ unsigned char tmp_addr = (unsigned char)addr;
+ int retval = 0;
+ int left_len = length;
+
+ /* u16 old_flag; */
+ mutex_lock(&(rmi4_data->rmi4_io_ctrl_mutex));
+
+ retval = tpd_set_page(rmi4_data, addr);
+ if (retval != PAGE_SELECT_LEN) {
+ retval = -EIO;
+ goto exit;
+ }
+
+ retval = i2c_master_send(client, &tmp_addr, 1);
+ while (left_len > 0) {
+ for (retry = 0; retry < SYN_I2C_RETRY_TIMES; retry++) {
+ if (left_len > 8)
+ retval = i2c_master_recv(client, pData, 8);
+ else
+ retval = i2c_master_recv(client, pData, left_len);
+ if (retval <= 0) {
+ dev_err(&client->dev, "%s: I2C retry %d\n", __func__, retry + 1);
+ msleep(20);
+ if (retry == (SYN_I2C_RETRY_TIMES / 2)) {
+ if (client->addr == rmi4_data->i2c_addr)
+ client->addr = UBL_I2C_ADDR;
+ else
+ client->addr = rmi4_data->i2c_addr;
+ }
+ left_len = length;
+ pData = data;
+ retval = i2c_master_send(client, &tmp_addr, 1);
+ continue;
+ } else {
+ break;
+ }
+ }
+ if (retry == SYN_I2C_RETRY_TIMES) {
+ retval = -EIO;
+ goto exit;
+ }
+ left_len -= 8;
+ pData += 8;
+ }
+exit:
+ mutex_unlock(&(rmi4_data->rmi4_io_ctrl_mutex));
+
+ return retval;
+}
+EXPORT_SYMBOL(tpd_i2c_read_data);
+
+#ifdef USE_I2C_DMA
+int tpd_i2c_write_data_dma(struct synaptics_rmi4_data *rmi4_data, struct i2c_client *client,
+ unsigned short addr, unsigned char *data, unsigned short length)
+{
+ int retval = 0;
+ unsigned char retry;
+ unsigned char *buf_va = NULL;
+ struct i2c_msg msg[1];
+
+ mutex_lock(&(rmi4_data->rmi4_io_ctrl_mutex));
+
+ msg[0].addr = rmi4_data->i2c_client->addr;
+ msg[0].flags = 0;
+ msg[0].len = length + 1;
+ msg[0].ext_flag = (rmi4_data->i2c_client->ext_flag | I2C_ENEXT_FLAG | I2C_DMA_FLAG),
+ msg[0].buf = (unsigned char *)(uintptr_t)wDMABuf_pa;
+ msg[0].timing = 400;
+
+ retval = tpd_set_page(rmi4_data, addr);
+ if (retval != PAGE_SELECT_LEN) {
+ retval = -EIO;
+ goto exit;
+ }
+
+ buf_va = wDMABuf_va;
+ buf_va[0] = addr & MASK_8BIT;
+ memcpy(&buf_va[1], &data[0], length);
+
+ for (retry = 0; retry < SYN_I2C_RETRY_TIMES; retry++) {
+ if (i2c_transfer(rmi4_data->i2c_client->adapter, msg, 1) == 1) {
+ retval = length;
+ break;
+ }
+ dev_err(&rmi4_data->i2c_client->dev,
+ "%s: I2C retry %d\n",
+ __func__, retry + 1);
+ msleep(20);
+
+ if (retry == (SYN_I2C_RETRY_TIMES / 2)) {
+ if (rmi4_data->i2c_client->addr == rmi4_data->i2c_addr)
+ rmi4_data->i2c_client->addr = UBL_I2C_ADDR;
+ else
+ rmi4_data->i2c_client->addr = rmi4_data->i2c_addr;
+ msg[0].addr = rmi4_data->i2c_client->addr;
+ }
+ }
+
+ if (retry == SYN_I2C_RETRY_TIMES) {
+ dev_err(&rmi4_data->i2c_client->dev,
+ "%s: I2C write over retry limit\n",
+ __func__);
+ retval = -EIO;
+ }
+
+exit:
+ mutex_unlock(&(rmi4_data->rmi4_io_ctrl_mutex));
+
+ return retval;
+}
+EXPORT_SYMBOL(tpd_i2c_write_data_dma);
+
+#else
+int tpd_i2c_write_data(struct synaptics_rmi4_data *rmi4_data, struct i2c_client *client,
+ unsigned short addr, unsigned char *data, unsigned short length)
+{
+ int retval = 0;
+ u8 retry = 0;
+ u8 *buf;
+ int tmp_addr = addr;
+
+
+ mutex_lock(&(rmi4_data->rmi4_io_ctrl_mutex));
+
+ retval = tpd_set_page(rmi4_data, addr);
+ if (retval != PAGE_SELECT_LEN) {
+ pr_err("tpd_set_page fail, retval = %d\n", retval);
+ retval = -EIO;
+ goto exit;
+ }
+
+ buf = kzalloc(sizeof(unsigned char) * (length + 1), GFP_KERNEL);
+ *buf = tmp_addr;
+ memcpy(buf + 1, data, length);
+ for (retry = 0; retry < SYN_I2C_RETRY_TIMES; retry++) {
+ retval = i2c_master_send(client, buf, (length + 1));
+ if (retval <= 0) {
+ dev_err(&client->dev, "%s: I2C retry %d\n", __func__, retry + 1);
+ msleep(20);
+ continue;
+ } else {
+ break;
+ }
+ }
+ kfree(buf);
+
+exit:
+ mutex_unlock(&(rmi4_data->rmi4_io_ctrl_mutex));
+
+ return retval;
+}
+EXPORT_SYMBOL(tpd_i2c_write_data);
+
+#endif
+
+ /**
+ * synaptics_rmi4_i2c_read()
+ *
+ * Called by various functions in this driver, and also exported to
+ * other expansion Function modules such as rmi_dev.
+ *
+ * This function reads data of an arbitrary length from the sensor,
+ * starting from an assigned register address of the sensor, via I2C
+ * with a retry mechanism.
+ */
+static int synaptics_rmi4_i2c_read(struct synaptics_rmi4_data *rmi4_data,
+ unsigned short addr, unsigned char *data, unsigned short length)
+{
+ return tpd_i2c_read_data(rmi4_data, rmi4_data->i2c_client, addr, data, length);
+}
+
+ /**
+ * synaptics_rmi4_i2c_write()
+ *
+ * Called by various functions in this driver, and also exported to
+ * other expansion Function modules such as rmi_dev.
+ *
+ * This function writes data of an arbitrary length to the sensor,
+ * starting from an assigned register address of the sensor, via I2C with
+ * a retry mechanism.
+ */
+static int synaptics_rmi4_i2c_write(struct synaptics_rmi4_data *rmi4_data,
+ unsigned short addr, unsigned char *data, unsigned short length)
+{
+#ifdef USE_I2C_DMA
+ return tpd_i2c_write_data_dma(rmi4_data, rmi4_data->i2c_client, addr, data, length);
+#else
+ return tpd_i2c_write_data(rmi4_data, rmi4_data->i2c_client, addr, data, length);
+#endif
+}
+
+ /**
+ * synaptics_rmi4_f11_abs_report()
+ *
+ * Called by synaptics_rmi4_report_touch() when valid Function $11
+ * finger data has been detected.
+ *
+ * This function reads the Function $11 data registers, determines the
+ * status of each finger supported by the Function, processes any
+ * necessary coordinate manipulation, reports the finger data to
+ * the input subsystem, and returns the number of fingers detected.
+ */
+static int synaptics_rmi4_f11_abs_report(struct synaptics_rmi4_data *rmi4_data,
+ struct synaptics_rmi4_fn *fhandler)
+{
+ int retval;
+ unsigned char touch_count = 0; /* number of touch points */
+ unsigned char reg_index;
+ unsigned char finger;
+ unsigned char fingers_supported;
+ unsigned char num_of_finger_status_regs;
+ unsigned char finger_shift;
+ unsigned char finger_status;
+ unsigned char finger_status_reg[3];
+ unsigned char detected_gestures;
+ unsigned short data_addr;
+ unsigned short data_offset;
+ int x;
+ int y;
+ int wx;
+ int wy;
+ //int temp;
+ struct synaptics_rmi4_f11_data_1_5 data;
+ struct synaptics_rmi4_f11_extra_data *extra_data;
+
+ /*
+ * The number of finger status registers is determined by the
+ * maximum number of fingers supported - 2 bits per finger. So
+ * the number of finger status registers to read is:
+ * register_count = ceil(max_num_of_fingers / 4)
+ */
+ fingers_supported = fhandler->num_of_data_points;
+ num_of_finger_status_regs = (fingers_supported + 3) / 4;
+ data_addr = fhandler->full_addr.data_base;
+
+ extra_data = (struct synaptics_rmi4_f11_extra_data *)fhandler->extra;
+
+ if (rmi4_data->sensor_sleep && rmi4_data->enable_wakeup_gesture) {
+ retval = synaptics_rmi4_i2c_read(rmi4_data,
+ data_addr + extra_data->data38_offset,
+ &detected_gestures,
+ sizeof(detected_gestures));
+ if (retval < 0)
+ return 0;
+
+ if (detected_gestures) {
+ input_report_key(rmi4_data->input_dev, KEY_POWER, 1);
+ input_sync(rmi4_data->input_dev);
+ input_report_key(rmi4_data->input_dev, KEY_POWER, 0);
+ input_sync(rmi4_data->input_dev);
+ rmi4_data->sensor_sleep = false;
+ }
+
+ return 0;
+ }
+
+ retval = synaptics_rmi4_i2c_read(rmi4_data,
+ data_addr,
+ finger_status_reg,
+ num_of_finger_status_regs);
+ if (retval < 0)
+ return 0;
+ mutex_lock(&rmi4_report_mutex);
+ for (finger = 0; finger < fingers_supported; finger++) {
+ reg_index = finger / 4;
+ finger_shift = (finger % 4) * 2;
+ finger_status = (finger_status_reg[reg_index] >> finger_shift)
+ & MASK_2BIT;
+
+ /*
+ * Each 2-bit finger status field represents the following:
+ * 00 = finger not present
+ * 01 = finger present and data accurate
+ * 10 = finger present but data may be inaccurate
+ * 11 = reserved
+ */
+#ifdef TYPE_B_PROTOCOL
+ input_mt_slot(rmi4_data->input_dev, finger);
+ input_mt_report_slot_state(rmi4_data->input_dev,
+ MT_TOOL_FINGER, finger_status);
+#endif
+
+ if (finger_status) {
+ data_offset = data_addr +
+ num_of_finger_status_regs +
+ (finger * sizeof(data.data));
+ retval = synaptics_rmi4_i2c_read(rmi4_data,
+ data_offset,
+ data.data,
+ sizeof(data.data));
+ if (retval < 0) {
+ touch_count = 0;
+ goto exit;
+ }
+
+ x = (data.x_position_11_4 << 4) | data.x_position_3_0;
+ y = (data.y_position_11_4 << 4) | data.y_position_3_0;
+ if (rmi4_data->diagonal_rotation) {
+ x = rmi4_data->sensor_max_x - x;
+ y = rmi4_data->sensor_max_y - y;
+ }
+
+ wx = data.wx;
+ wy = data.wy;
+
+ input_report_key(rmi4_data->input_dev,
+ BTN_TOUCH, 1);
+ input_report_key(rmi4_data->input_dev,
+ BTN_TOOL_FINGER, 1);
+ input_report_abs(rmi4_data->input_dev,
+ ABS_MT_POSITION_X, x);
+ input_report_abs(rmi4_data->input_dev,
+ ABS_MT_POSITION_Y, y);
+#ifdef REPORT_2D_W
+ input_report_abs(rmi4_data->input_dev,
+ ABS_MT_TOUCH_MAJOR, max(wx, wy));
+ input_report_abs(rmi4_data->input_dev,
+ ABS_MT_TOUCH_MINOR, min(wx, wy));
+#endif
+#ifndef TYPE_B_PROTOCOL
+ input_mt_sync(rmi4_data->input_dev);
+#endif
+
+ dev_dbg(&rmi4_data->i2c_client->dev,
+ "%s: Finger %d:\n"
+ "status = 0x%02x\n"
+ "x = %d\n"
+ "y = %d\n"
+ "wx = %d\n"
+ "wy = %d\n",
+ __func__, finger,
+ finger_status,
+ x, y, wx, wy);
+
+ touch_count++;
+ }
+ }
+
+ if (touch_count == 0) {
+ input_report_key(rmi4_data->input_dev,
+ BTN_TOUCH, 0);
+ input_report_key(rmi4_data->input_dev,
+ BTN_TOOL_FINGER, 0);
+#ifndef TYPE_B_PROTOCOL
+ input_mt_sync(rmi4_data->input_dev);
+#endif
+ }
+
+ input_sync(rmi4_data->input_dev);
+exit:
+ mutex_unlock(&(rmi4_report_mutex));
+ return touch_count;
+}
+
+ /**
+ * synaptics_rmi4_f12_abs_report()
+ *
+ * Called by synaptics_rmi4_report_touch() when valid Function $12
+ * finger data has been detected.
+ *
+ * This function reads the Function $12 data registers, determines the
+ * status of each finger supported by the Function, processes any
+ * necessary coordinate manipulation, reports the finger data to
+ * the input subsystem, and returns the number of fingers detected.
+ */
+static int synaptics_rmi4_f12_abs_report(struct synaptics_rmi4_data *rmi4_data,
+ struct synaptics_rmi4_fn *fhandler)
+{
+ int retval;
+ unsigned char touch_count = 0; /* number of touch points */
+ unsigned char finger;
+ unsigned char fingers_to_process;
+ unsigned char finger_status;
+ unsigned char size_of_2d_data;
+ unsigned char detected_gestures[F12_GESTURE_DETECTION_LEN]; // byte0 indicate gesture type, byte1~byte4 are gesture parameter
+ unsigned short data_addr;
+ int x;
+ int y;
+ int wx;
+ int wy;
+ int temp;
+ struct synaptics_rmi4_f12_extra_data *extra_data;
+ struct synaptics_rmi4_f12_finger_data *data;
+ struct synaptics_rmi4_f12_finger_data *finger_data;
+#ifdef F12_DATA_15_WORKAROUND
+ static unsigned char fingers_already_present;
+#endif
+
+ fingers_to_process = fhandler->num_of_data_points;
+ data_addr = fhandler->full_addr.data_base;
+ extra_data = (struct synaptics_rmi4_f12_extra_data *)fhandler->extra;
+ size_of_2d_data = sizeof(struct synaptics_rmi4_f12_finger_data);
+
+
+ if (rmi4_data->sensor_sleep && rmi4_data->enable_wakeup_gesture) {
+ retval = synaptics_rmi4_i2c_read(rmi4_data,
+ data_addr + extra_data->data4_offset,
+ detected_gestures,
+ sizeof(detected_gestures));
+ if (retval < 0)
+ return 0;
+
+ if (detected_gestures[0] && (detected_gestures[0] != F12_UDG_DETECT)) { // here is demo only, customer could decode gesture data and do whatever they want
+ input_report_key(rmi4_data->input_dev, KEY_POWER, 1);
+ input_sync(rmi4_data->input_dev);
+ input_report_key(rmi4_data->input_dev, KEY_POWER, 0);
+ input_sync(rmi4_data->input_dev);
+ rmi4_data->sensor_sleep = false;
+ }
+
+ return 0;
+ }
+
+
+ /* Determine the total number of fingers to process */
+ if (extra_data->data15_size) {
+ retval = synaptics_rmi4_i2c_read(rmi4_data,
+ data_addr + extra_data->data15_offset,
+ extra_data->data15_data,
+ extra_data->data15_size);
+ if (retval < 0)
+ return 0;
+
+ /* Start checking from the highest bit */
+ temp = extra_data->data15_size - 1; /* Highest byte */
+ finger = (fingers_to_process - 1) % 8; /* Highest bit */
+ do {
+ if (extra_data->data15_data[temp] & (1 << finger))
+ break;
+
+ if (finger) {
+ finger--;
+ } else {
+ temp--; /* Move to the next lower byte */
+ finger = 7;
+ }
+
+ fingers_to_process--;
+ } while (fingers_to_process);
+
+ dev_dbg(&rmi4_data->i2c_client->dev,
+ "%s: Number of fingers to process = %d\n",
+ __func__, fingers_to_process);
+ }
+
+#ifdef F12_DATA_15_WORKAROUND
+ fingers_to_process = max(fingers_to_process, fingers_already_present);
+#endif
+
+ if (!fingers_to_process) {
+ synaptics_rmi4_free_fingers(rmi4_data);
+ return 0;
+ }
+
+ retval = synaptics_rmi4_i2c_read(rmi4_data,
+ data_addr + extra_data->data1_offset,
+ (unsigned char *)fhandler->data,
+ fingers_to_process * size_of_2d_data);
+ if (retval < 0)
+ return 0;
+
+ data = (struct synaptics_rmi4_f12_finger_data *)fhandler->data;
+ mutex_lock(&rmi4_report_mutex);
+ for (finger = 0; finger < fingers_to_process; finger++) {
+ finger_data = data + finger;
+ finger_status = finger_data->object_type_and_status & MASK_1BIT;
+
+#ifdef TYPE_B_PROTOCOL
+ input_mt_slot(rmi4_data->input_dev, finger);
+ input_mt_report_slot_state(rmi4_data->input_dev,
+ MT_TOOL_FINGER, finger_status);
+#endif
+
+ if (finger_status) {
+#ifdef F12_DATA_15_WORKAROUND
+ fingers_already_present = finger + 1;
+#endif
+
+ x = (finger_data->x_msb << 8) | (finger_data->x_lsb);
+ y = (finger_data->y_msb << 8) | (finger_data->y_lsb);
+ if (rmi4_data->diagonal_rotation) {
+ x = rmi4_data->sensor_max_x - x;
+ y = rmi4_data->sensor_max_y - y;
+ }
+
+#ifdef REPORT_2D_W
+ wx = finger_data->wx;
+ wy = finger_data->wy;
+#endif
+
+ input_report_key(rmi4_data->input_dev,
+ BTN_TOUCH, 1);
+ input_report_key(rmi4_data->input_dev,
+ BTN_TOOL_FINGER, 1);
+ input_report_abs(rmi4_data->input_dev,
+ ABS_MT_POSITION_X, x);
+ input_report_abs(rmi4_data->input_dev,
+ ABS_MT_POSITION_Y, y);
+#ifdef REPORT_2D_W
+ input_report_abs(rmi4_data->input_dev,
+ ABS_MT_TOUCH_MAJOR, max(wx, wy));
+ input_report_abs(rmi4_data->input_dev,
+ ABS_MT_TOUCH_MINOR, min(wx, wy));
+#endif
+#ifndef TYPE_B_PROTOCOL
+ input_mt_sync(rmi4_data->input_dev);
+#endif
+
+ dev_dbg(&rmi4_data->i2c_client->dev,
+ "%s: Finger %d:\n"
+ "status = 0x%02x\n"
+ "x = %d\n"
+ "y = %d\n"
+ "wx = %d\n"
+ "wy = %d\n",
+ __func__, finger,
+ finger_status,
+ x, y, wx, wy);
+
+ touch_count++;
+ }
+ }
+
+ if (touch_count == 0) {
+ input_report_key(rmi4_data->input_dev,
+ BTN_TOUCH, 0);
+ input_report_key(rmi4_data->input_dev,
+ BTN_TOOL_FINGER, 0);
+#ifndef TYPE_B_PROTOCOL
+ input_mt_sync(rmi4_data->input_dev);
+#endif
+ }
+
+ input_sync(rmi4_data->input_dev);
+ mutex_unlock(&rmi4_report_mutex);
+ return touch_count;
+}
+
+static void synaptics_rmi4_f1a_report(struct synaptics_rmi4_data *rmi4_data,
+ struct synaptics_rmi4_fn *fhandler)
+{
+ int retval;
+ unsigned char touch_count = 0;
+ unsigned char button;
+ unsigned char index;
+ unsigned char shift;
+ unsigned char status;
+ unsigned char *data;
+ unsigned short data_addr = fhandler->full_addr.data_base;
+ struct synaptics_rmi4_f1a_handle *f1a = fhandler->data;
+ static unsigned char do_once = 1;
+ static bool current_status[MAX_NUMBER_OF_BUTTONS];
+#ifdef NO_0D_WHILE_2D
+ static bool before_2d_status[MAX_NUMBER_OF_BUTTONS];
+ static bool while_2d_status[MAX_NUMBER_OF_BUTTONS];
+#endif
+
+ if (do_once) {
+ memset(current_status, 0, sizeof(current_status));
+#ifdef NO_0D_WHILE_2D
+ memset(before_2d_status, 0, sizeof(before_2d_status));
+ memset(while_2d_status, 0, sizeof(while_2d_status));
+#endif
+ do_once = 0;
+ }
+
+ retval = synaptics_rmi4_i2c_read(rmi4_data,
+ data_addr,
+ f1a->button_data_buffer,
+ f1a->button_bitmask_size);
+ if (retval < 0) {
+ dev_err(&rmi4_data->i2c_client->dev,
+ "%s: Failed to read button data registers\n",
+ __func__);
+ return;
+ }
+
+ data = f1a->button_data_buffer;
+ mutex_lock(&rmi4_report_mutex);
+ for (button = 0; button < f1a->valid_button_count; button++) {
+ index = button / 8;
+ shift = button % 8;
+ status = ((data[index] >> shift) & MASK_1BIT);
+
+ if (current_status[button] == status)
+ continue;
+ else
+ current_status[button] = status;
+
+ dev_dbg(&rmi4_data->i2c_client->dev,
+ "%s: Button %d (code %d) ->%d\n",
+ __func__, button,
+ f1a->button_map[button],
+ status);
+#ifdef NO_0D_WHILE_2D
+ if (rmi4_data->fingers_on_2d == false) {
+ if (status == 1) {
+ before_2d_status[button] = 1;
+ } else {
+ if (while_2d_status[button] == 1) {
+ while_2d_status[button] = 0;
+ continue;
+ } else {
+ before_2d_status[button] = 0;
+ }
+ }
+ touch_count++;
+ input_report_key(rmi4_data->input_dev,
+ f1a->button_map[button],
+ status);
+ } else {
+ if (before_2d_status[button] == 1) {
+ before_2d_status[button] = 0;
+ touch_count++;
+ input_report_key(rmi4_data->input_dev,
+ f1a->button_map[button],
+ status);
+ } else {
+ if (status == 1)
+ while_2d_status[button] = 1;
+ else
+ while_2d_status[button] = 0;
+ }
+ }
+#else
+ touch_count++;
+ input_report_key(rmi4_data->input_dev,
+ f1a->button_map[button],
+ status);
+#endif
+ }
+
+ if (touch_count)
+ input_sync(rmi4_data->input_dev);
+ mutex_unlock(&rmi4_report_mutex);
+ return;
+}
+
+ /**
+ * synaptics_rmi4_report_touch()
+ *
+ * Called by synaptics_rmi4_sensor_report().
+ *
+ * This function calls the appropriate finger data reporting function
+ * based on the function handler it receives and returns the number of
+ * fingers detected.
+ */
+static void synaptics_rmi4_report_touch(struct synaptics_rmi4_data *rmi4_data,
+ struct synaptics_rmi4_fn *fhandler)
+{
+ unsigned char touch_count_2d;
+
+ dev_dbg(&rmi4_data->i2c_client->dev,
+ "%s: Function %02x reporting\n",
+ __func__, fhandler->fn_number);
+
+ switch (fhandler->fn_number) {
+ case SYNAPTICS_RMI4_F11:
+ touch_count_2d = synaptics_rmi4_f11_abs_report(rmi4_data,
+ fhandler);
+
+ if (touch_count_2d)
+ rmi4_data->fingers_on_2d = true;
+ else
+ rmi4_data->fingers_on_2d = false;
+ break;
+ case SYNAPTICS_RMI4_F12:
+ touch_count_2d = synaptics_rmi4_f12_abs_report(rmi4_data,
+ fhandler);
+ if (touch_count_2d)
+ rmi4_data->fingers_on_2d = true;
+ else
+ rmi4_data->fingers_on_2d = false;
+ break;
+ case SYNAPTICS_RMI4_F1A:
+ synaptics_rmi4_f1a_report(rmi4_data, fhandler);
+ break;
+ default:
+ break;
+ }
+
+ return;
+}
+
+ /**
+ * synaptics_rmi4_sensor_report()
+ *
+ * Called by synaptics_rmi4_irq().
+ *
+ * This function determines the interrupt source(s) from the sensor
+ * and calls synaptics_rmi4_report_touch() with the appropriate
+ * function handler for each function with valid data inputs.
+ */
+static void synaptics_rmi4_sensor_report(struct synaptics_rmi4_data *rmi4_data)
+{
+ int retval;
+ unsigned char data[MAX_INTR_REGISTERS + 1];
+ unsigned char *intr = &data[1];
+ struct synaptics_rmi4_f01_device_status status;
+ struct synaptics_rmi4_fn *fhandler;
+ struct synaptics_rmi4_exp_fhandler *exp_fhandler;
+ struct synaptics_rmi4_device_info *rmi;
+
+ rmi = &(rmi4_data->rmi4_mod_info);
+
+ /*
+ * Get interrupt status information from F01 Data1 register to
+ * determine the source(s) that are flagging the interrupt.
+ */
+ retval = synaptics_rmi4_i2c_read(rmi4_data,
+ rmi4_data->f01_data_base_addr,
+ data,
+ rmi4_data->num_of_intr_regs + 1);
+ if (retval < 0) {
+ dev_err(&rmi4_data->i2c_client->dev,
+ "%s: Failed to read interrupt status\n",
+ __func__);
+ return;
+ }
+
+ status.data[0] = data[0];
+ if (status.unconfigured && !status.flash_prog) {
+ pr_notice("%s: spontaneous reset detected\n", __func__);
+ retval = synaptics_rmi4_reinit_device(rmi4_data);
+ if (retval < 0) {
+ dev_err(&rmi4_data->i2c_client->dev,
+ "%s: Failed to reinit device\n",
+ __func__);
+ }
+ return;
+ }
+
+ /*
+ * Traverse the function handler list and service the source(s)
+ * of the interrupt accordingly.
+ */
+ if (!list_empty(&rmi->support_fn_list)) {
+ list_for_each_entry(fhandler, &rmi->support_fn_list, link) {
+ if (fhandler->num_of_data_sources) {
+ if (fhandler->intr_mask &
+ intr[fhandler->intr_reg_num]) {
+ synaptics_rmi4_report_touch(rmi4_data,
+ fhandler);
+ }
+ }
+ }
+ }
+
+ mutex_lock(&exp_data.mutex);
+ if (!list_empty(&exp_data.list)) {
+ list_for_each_entry(exp_fhandler, &exp_data.list, link) {
+ if (!exp_fhandler->insert &&
+ !exp_fhandler->remove &&
+ (exp_fhandler->exp_fn->attn != NULL))
+ exp_fhandler->exp_fn->attn(rmi4_data, intr[0]);
+ }
+ }
+ mutex_unlock(&exp_data.mutex);
+
+ return;
+}
+
+ /**
+ * synaptics_rmi4_irq()
+ *
+ * Called by the kernel when an interrupt occurs (when the sensor
+ * asserts the attention irq).
+ *
+ * This function is the ISR thread and handles the acquisition
+ * and the reporting of finger data when the presence of fingers
+ * is detected.
+ */
+#ifdef CONFIG_OF_TOUCH
+static irqreturn_t tpd_eint_handler(unsigned int irq, struct irq_desc *desc)
+{
+ disable_irq_nosync(touch_irq);
+
+ tpd_flag = 1;
+ wake_up_interruptible(&waiter);
+ return IRQ_HANDLED;
+}
+#else
+static void tpd_eint_handler(void)
+{
+ tpd_flag = 1;
+ wake_up_interruptible(&waiter);
+}
+#endif
+
+static int touch_event_handler(void *data)
+{
+ struct synaptics_rmi4_data *rmi4_data = data;
+
+ do {
+ set_current_state(TASK_INTERRUPTIBLE);
+
+ wait_event_interruptible(waiter, tpd_flag != 0);
+
+ tpd_flag = 0;
+ set_current_state(TASK_RUNNING);
+
+ if (!rmi4_data->touch_stopped)
+ synaptics_rmi4_sensor_report(rmi4_data);
+#ifdef CONFIG_OF_TOUCH
+ enable_irq(touch_irq);
+#else
+ mt_eint_unmask(CUST_EINT_TOUCH_PANEL_NUM);
+#endif
+
+ } while (1);
+
+ return 0;
+}
+
+ /**
+ * synaptics_rmi4_irq_enable()
+ *
+ * Called by synaptics_rmi4_probe() and the power management functions
+ * in this driver and also exported to other expansion Function modules
+ * such as rmi_dev.
+ *
+ * This function handles the enabling and disabling of the attention
+ * irq including the setting up of the ISR thread.
+ */
+static int synaptics_rmi4_irq_enable(struct synaptics_rmi4_data *rmi4_data,
+ bool enable)
+{
+ int retval = 0;
+
+ if (enable) {
+ /* set up irq */
+ if (!rmi4_data->irq_enabled) {
+#ifdef CONFIG_OF_TOUCH
+ enable_irq(touch_irq);
+#else
+ mt_eint_unmask(CUST_EINT_TOUCH_PANEL_NUM);
+#endif
+ rmi4_data->irq_enabled = true;
+
+ }
+
+ } else {
+ if (rmi4_data->irq_enabled) {
+#ifdef CONFIG_OF_TOUCH
+ disable_irq_nosync(touch_irq);
+#else
+ mt_eint_mask(CUST_EINT_TOUCH_PANEL_NUM);
+#endif
+ rmi4_data->irq_enabled = false;
+ }
+ }
+
+ return retval;
+}
+
+static void synaptics_rmi4_set_intr_mask(struct synaptics_rmi4_fn *fhandler,
+ struct synaptics_rmi4_fn_desc *fd,
+ unsigned int intr_count)
+{
+ unsigned char ii;
+ unsigned char intr_offset;
+
+ fhandler->intr_reg_num = (intr_count + 7) / 8;
+ if (fhandler->intr_reg_num != 0)
+ fhandler->intr_reg_num -= 1;
+
+ /* Set an enable bit for each data source */
+ intr_offset = intr_count % 8;
+ fhandler->intr_mask = 0;
+ for (ii = intr_offset;
+ ii < ((fd->intr_src_count & MASK_3BIT) +
+ intr_offset);
+ ii++)
+ fhandler->intr_mask |= 1 << ii;
+
+ return;
+}
+
+static int synaptics_rmi4_f01_init(struct synaptics_rmi4_data *rmi4_data,
+ struct synaptics_rmi4_fn *fhandler,
+ struct synaptics_rmi4_fn_desc *fd,
+ unsigned int intr_count)
+{
+ fhandler->fn_number = fd->fn_number;
+ fhandler->num_of_data_sources = fd->intr_src_count;
+ fhandler->data = NULL;
+ fhandler->extra = NULL;
+
+ synaptics_rmi4_set_intr_mask(fhandler, fd, intr_count);
+
+ rmi4_data->f01_query_base_addr = fd->query_base_addr;
+ rmi4_data->f01_ctrl_base_addr = fd->ctrl_base_addr;
+ rmi4_data->f01_data_base_addr = fd->data_base_addr;
+ rmi4_data->f01_cmd_base_addr = fd->cmd_base_addr;
+
+ return 0;
+}
+
+ /**
+ * synaptics_rmi4_f11_init()
+ *
+ * Called by synaptics_rmi4_query_device().
+ *
+ * This function parses information from the Function 11 registers
+ * and determines the number of fingers supported, x and y data ranges,
+ * offset to the associated interrupt status register, interrupt bit
+ * mask, and gathers finger data acquisition capabilities from the query
+ * registers.
+ */
+static int synaptics_rmi4_f11_init(struct synaptics_rmi4_data *rmi4_data,
+ struct synaptics_rmi4_fn *fhandler,
+ struct synaptics_rmi4_fn_desc *fd,
+ unsigned int intr_count)
+{
+ int retval;
+ unsigned char offset;
+ unsigned char fingers_supported;
+ struct synaptics_rmi4_f11_extra_data *extra_data;
+ struct synaptics_rmi4_f11_query_0_5 query_0_5;
+ struct synaptics_rmi4_f11_query_7_8 query_7_8;
+ struct synaptics_rmi4_f11_query_9 query_9;
+ struct synaptics_rmi4_f11_query_12 query_12;
+ struct synaptics_rmi4_f11_query_27 query_27;
+ struct synaptics_rmi4_f11_ctrl_6_9 control_6_9;
+
+ fhandler->fn_number = fd->fn_number;
+ fhandler->num_of_data_sources = fd->intr_src_count;
+ fhandler->extra = kmalloc(sizeof(*extra_data), GFP_KERNEL);
+ if (!fhandler->extra) {
+ dev_err(&rmi4_data->i2c_client->dev,
+ "%s: Failed to alloc mem for fhandle->extra\n",
+ __func__);
+ return -ENOMEM;
+ }
+ extra_data = (struct synaptics_rmi4_f11_extra_data *)fhandler->extra;
+
+ retval = synaptics_rmi4_i2c_read(rmi4_data,
+ fhandler->full_addr.query_base,
+ query_0_5.data,
+ sizeof(query_0_5.data));
+ if (retval < 0)
+ return retval;
+
+ /* Maximum number of fingers supported */
+ if (query_0_5.num_of_fingers <= 4)
+ fhandler->num_of_data_points = query_0_5.num_of_fingers + 1;
+ else if (query_0_5.num_of_fingers == 5)
+ fhandler->num_of_data_points = 10;
+
+ rmi4_data->num_of_fingers = fhandler->num_of_data_points;
+
+ retval = synaptics_rmi4_i2c_read(rmi4_data,
+ fhandler->full_addr.ctrl_base + 6,
+ control_6_9.data,
+ sizeof(control_6_9.data));
+ if (retval < 0)
+ return retval;
+
+ /* Maximum x and y */
+ rmi4_data->sensor_max_x = SENSOR_MAX_X;
+ rmi4_data->sensor_max_y = SENSOR_MAX_Y; //control_6_9.sensor_max_y_pos_7_0 |
+ //(control_6_9.sensor_max_y_pos_11_8 << 8);
+
+ /* It's recommended to parse max_x and max_y from contrel register, but this does not match MTK's mtk-tpd.c */
+
+ dev_dbg(&rmi4_data->i2c_client->dev,
+ "%s: Function %02x max x = %d max y = %d\n",
+ __func__, fhandler->fn_number,
+ rmi4_data->sensor_max_x,
+ rmi4_data->sensor_max_y);
+
+ rmi4_data->max_touch_width = MAX_F11_TOUCH_WIDTH;
+
+ synaptics_rmi4_set_intr_mask(fhandler, fd, intr_count);
+
+ fhandler->data = NULL;
+
+ offset = sizeof(query_0_5.data);
+
+ /* query 6 */
+ if (query_0_5.has_rel)
+ offset += 1;
+
+ /* queries 7 8 */
+ if (query_0_5.has_gestures) {
+ retval = synaptics_rmi4_i2c_read(rmi4_data,
+ fhandler->full_addr.query_base + offset,
+ query_7_8.data,
+ sizeof(query_7_8.data));
+ if (retval < 0)
+ return retval;
+
+ offset += sizeof(query_7_8.data);
+ }
+
+ /* query 9 */
+ if (query_0_5.has_query_9) {
+ retval = synaptics_rmi4_i2c_read(rmi4_data,
+ fhandler->full_addr.query_base + offset,
+ query_9.data,
+ sizeof(query_9.data));
+ if (retval < 0)
+ return retval;
+
+ offset += sizeof(query_9.data);
+ }
+
+ /* query 10 */
+ if (query_0_5.has_gestures && query_7_8.has_touch_shapes)
+ offset += 1;
+
+ /* query 11 */
+ if (query_0_5.has_query_11)
+ offset += 1;
+
+ /* query 12 */
+ if (query_0_5.has_query_12) {
+ retval = synaptics_rmi4_i2c_read(rmi4_data,
+ fhandler->full_addr.query_base + offset,
+ query_12.data,
+ sizeof(query_12.data));
+ if (retval < 0)
+ return retval;
+
+ offset += sizeof(query_12.data);
+ }
+
+ /* query 13 */
+ if (query_0_5.has_jitter_filter)
+ offset += 1;
+
+ /* query 14 */
+ if (query_0_5.has_query_12 && query_12.has_general_information_2)
+ offset += 1;
+
+ /* queries 15 16 17 18 19 20 21 22 23 24 25 26*/
+ if (query_0_5.has_query_12 && query_12.has_physical_properties)
+ offset += 12;
+
+ /* query 27 */
+ if (query_0_5.has_query_27) {
+ retval = synaptics_rmi4_i2c_read(rmi4_data,
+ fhandler->full_addr.query_base + offset,
+ query_27.data,
+ sizeof(query_27.data));
+ if (retval < 0)
+ return retval;
+
+ rmi4_data->f11_wakeup_gesture = query_27.has_wakeup_gesture;
+ }
+
+ if (!rmi4_data->f11_wakeup_gesture)
+ return retval;
+
+ /* data 0 */
+ fingers_supported = fhandler->num_of_data_points;
+ offset = (fingers_supported + 3) / 4;
+
+ /* data 1 2 3 4 5 */
+ offset += 5 * fingers_supported;
+
+ /* data 6 7 */
+ if (query_0_5.has_rel)
+ offset += 2 * fingers_supported;
+
+ /* data 8 */
+ if (query_0_5.has_gestures && query_7_8.data[0])
+ offset += 1;
+
+ /* data 9 */
+ if (query_0_5.has_gestures && (query_7_8.data[0] || query_7_8.data[1]))
+ offset += 1;
+
+ /* data 10 */
+ if (query_0_5.has_gestures &&
+ (query_7_8.has_pinch || query_7_8.has_flick))
+ offset += 1;
+
+ /* data 11 12 */
+ if (query_0_5.has_gestures &&
+ (query_7_8.has_flick || query_7_8.has_rotate))
+ offset += 2;
+
+ /* data 13 */
+ if (query_0_5.has_gestures && query_7_8.has_touch_shapes)
+ offset += (fingers_supported + 3) / 4;
+
+ /* data 14 15 */
+ if (query_0_5.has_gestures &&
+ (query_7_8.has_scroll_zones ||
+ query_7_8.has_multi_finger_scroll ||
+ query_7_8.has_chiral_scroll))
+ offset += 2;
+
+ /* data 16 17 */
+ if (query_0_5.has_gestures &&
+ (query_7_8.has_scroll_zones &&
+ query_7_8.individual_scroll_zones))
+ offset += 2;
+
+ /* data 18 19 20 21 22 23 24 25 26 27 */
+ if (query_0_5.has_query_9 && query_9.has_contact_geometry)
+ offset += 10 * fingers_supported;
+
+ /* data 28 */
+ if (query_0_5.has_bending_correction ||
+ query_0_5.has_large_object_suppression)
+ offset += 1;
+
+ /* data 29 30 31 */
+ if (query_0_5.has_query_9 && query_9.has_pen_hover_discrimination)
+ offset += 3;
+
+ /* data 32 */
+ if (query_0_5.has_query_12 &&
+ query_12.has_small_object_detection_tuning)
+ offset += 1;
+
+ /* data 33 34 */
+ if (query_0_5.has_query_27 && query_27.f11_query27_b0)
+ offset += 2;
+
+ /* data 35 */
+ if (query_0_5.has_query_12 && query_12.has_8bit_w)
+ offset += fingers_supported;
+
+ /* data 36 */
+ if (query_0_5.has_bending_correction)
+ offset += 1;
+
+ /* data 37 */
+ if (query_0_5.has_query_27 && query_27.has_data_37)
+ offset += 1;
+
+ /* data 38 */
+ if (query_0_5.has_query_27 && query_27.has_wakeup_gesture)
+ extra_data->data38_offset = offset;
+
+ return retval;
+}
+
+static int synaptics_rmi4_f12_set_enables(struct synaptics_rmi4_data *rmi4_data,
+ unsigned short ctrl28)
+{
+ int retval;
+ static unsigned short ctrl_28_address;
+
+ if (ctrl28)
+ ctrl_28_address = ctrl28;
+
+ retval = synaptics_rmi4_i2c_write(rmi4_data,
+ ctrl_28_address,
+ &rmi4_data->report_enable,
+ sizeof(rmi4_data->report_enable));
+ if (retval < 0)
+ return retval;
+
+ return retval;
+}
+
+ /**
+ * synaptics_rmi4_f12_init()
+ *
+ * Called by synaptics_rmi4_query_device().
+ *
+ * This function parses information from the Function 12 registers and
+ * determines the number of fingers supported, offset to the data1
+ * register, x and y data ranges, offset to the associated interrupt
+ * status register, interrupt bit mask, and allocates memory resources
+ * for finger data acquisition.
+ */
+static int synaptics_rmi4_f12_init(struct synaptics_rmi4_data *rmi4_data,
+ struct synaptics_rmi4_fn *fhandler,
+ struct synaptics_rmi4_fn_desc *fd,
+ unsigned int intr_count)
+{
+ int retval;
+ unsigned char size_of_2d_data;
+ unsigned char size_of_query8;
+ unsigned char ctrl_8_offset;
+ unsigned char ctrl_20_offset;
+ unsigned char ctrl_23_offset;
+ unsigned char ctrl_27_offset;
+ unsigned char ctrl_28_offset;
+ unsigned char num_of_fingers;
+ struct synaptics_rmi4_f12_extra_data *extra_data;
+ struct synaptics_rmi4_f12_query_5 query_5;
+ struct synaptics_rmi4_f12_query_8 query_8;
+ struct synaptics_rmi4_f12_ctrl_8 ctrl_8;
+ struct synaptics_rmi4_f12_ctrl_23 ctrl_23;
+
+ fhandler->fn_number = fd->fn_number;
+ fhandler->num_of_data_sources = fd->intr_src_count;
+ fhandler->extra = kmalloc(sizeof(*extra_data), GFP_KERNEL);
+ if (!fhandler->extra) {
+ dev_err(&rmi4_data->i2c_client->dev,
+ "%s: Failed to alloc mem for fhandler->extra\n",
+ __func__);
+ return -ENOMEM;
+ }
+ extra_data = (struct synaptics_rmi4_f12_extra_data *)fhandler->extra;
+ size_of_2d_data = sizeof(struct synaptics_rmi4_f12_finger_data);
+
+ retval = synaptics_rmi4_i2c_read(rmi4_data,
+ fhandler->full_addr.query_base + 5,
+ query_5.data,
+ sizeof(query_5.data));
+ if (retval < 0)
+ return retval;
+
+ ctrl_8_offset = query_5.ctrl0_is_present +
+ query_5.ctrl1_is_present +
+ query_5.ctrl2_is_present +
+ query_5.ctrl3_is_present +
+ query_5.ctrl4_is_present +
+ query_5.ctrl5_is_present +
+ query_5.ctrl6_is_present +
+ query_5.ctrl7_is_present;
+
+ ctrl_20_offset = ctrl_8_offset +
+ query_5.ctrl8_is_present +
+ query_5.ctrl9_is_present +
+ query_5.ctrl10_is_present +
+ query_5.ctrl11_is_present +
+ query_5.ctrl12_is_present +
+ query_5.ctrl13_is_present +
+ query_5.ctrl14_is_present +
+ query_5.ctrl15_is_present +
+ query_5.ctrl16_is_present +
+ query_5.ctrl17_is_present +
+ query_5.ctrl18_is_present +
+ query_5.ctrl19_is_present;
+
+ ctrl_23_offset = ctrl_20_offset +
+ query_5.ctrl20_is_present +
+ query_5.ctrl21_is_present +
+ query_5.ctrl22_is_present;
+ ctrl_27_offset = ctrl_23_offset +
+ query_5.ctrl23_is_present +
+ query_5.ctrl24_is_present +
+ query_5.ctrl25_is_present +
+ query_5.ctrl26_is_present;
+ ctrl_28_offset = ctrl_27_offset +
+ query_5.ctrl27_is_present;
+
+ retval = synaptics_rmi4_i2c_read(rmi4_data,
+ fhandler->full_addr.ctrl_base + ctrl_23_offset,
+ ctrl_23.data,
+ sizeof(ctrl_23.data));
+ if (retval < 0)
+ return retval;
+
+ /* Maximum number of fingers supported */
+ fhandler->num_of_data_points = min(ctrl_23.max_reported_objects,
+ (unsigned char)F12_FINGERS_TO_SUPPORT);
+
+ num_of_fingers = fhandler->num_of_data_points;
+ rmi4_data->num_of_fingers = num_of_fingers;
+
+ retval = synaptics_rmi4_i2c_read(rmi4_data,
+ fhandler->full_addr.query_base + 7,
+ &size_of_query8,
+ sizeof(size_of_query8));
+ if (retval < 0)
+ return retval;
+
+ retval = synaptics_rmi4_i2c_read(rmi4_data,
+ fhandler->full_addr.query_base + 8,
+ query_8.data,
+ size_of_query8);
+ if (retval < 0)
+ return retval;
+
+ /* Determine the presence of the Data0 register */
+ extra_data->data1_offset = query_8.data0_is_present;
+
+ if ((size_of_query8 >= 3) && (query_8.data15_is_present)) {
+ extra_data->data15_offset = query_8.data0_is_present +
+ query_8.data1_is_present +
+ query_8.data2_is_present +
+ query_8.data3_is_present +
+ query_8.data4_is_present +
+ query_8.data5_is_present +
+ query_8.data6_is_present +
+ query_8.data7_is_present +
+ query_8.data8_is_present +
+ query_8.data9_is_present +
+ query_8.data10_is_present +
+ query_8.data11_is_present +
+ query_8.data12_is_present +
+ query_8.data13_is_present +
+ query_8.data14_is_present;
+ extra_data->data15_size = (num_of_fingers + 7) / 8;
+ } else {
+ extra_data->data15_size = 0;
+ }
+
+ rmi4_data->report_enable = RPT_DEFAULT;
+#ifdef REPORT_2D_Z
+ rmi4_data->report_enable |= RPT_Z;
+#endif
+#ifdef REPORT_2D_W
+ rmi4_data->report_enable |= (RPT_WX | RPT_WY);
+#endif
+
+ retval = synaptics_rmi4_f12_set_enables(rmi4_data,
+ fhandler->full_addr.ctrl_base + ctrl_28_offset);
+ if (retval < 0)
+ return retval;
+
+ retval = synaptics_rmi4_i2c_read(rmi4_data,
+ fhandler->full_addr.ctrl_base + ctrl_8_offset,
+ ctrl_8.data,
+ sizeof(ctrl_8.data));
+ if (retval < 0)
+ return retval;
+
+ /* Maximum x and y */
+ rmi4_data->sensor_max_x = SENSOR_MAX_X;
+ rmi4_data->sensor_max_y = SENSOR_MAX_Y;
+
+ /* It's recommended to parse max_x and max_y from contrel register, but this does not match MTK's mtk-tpd.c */
+
+ dev_dbg(&rmi4_data->i2c_client->dev,
+ "%s: Function %02x max x = %d max y = %d\n",
+ __func__, fhandler->fn_number,
+ rmi4_data->sensor_max_x,
+ rmi4_data->sensor_max_y);
+
+ rmi4_data->num_of_rx = ctrl_8.num_of_rx;
+ rmi4_data->num_of_tx = ctrl_8.num_of_tx;
+ rmi4_data->max_touch_width = max(rmi4_data->num_of_rx,
+ rmi4_data->num_of_tx);
+ rmi4_data->f12_wakeup_gesture = query_5.ctrl27_is_present;
+ if (rmi4_data->f12_wakeup_gesture) {
+ extra_data->ctrl20_offset = ctrl_20_offset;
+ extra_data->data4_offset = query_8.data0_is_present +
+ query_8.data1_is_present +
+ query_8.data2_is_present +
+ query_8.data3_is_present;
+ extra_data->ctrl27_offset = ctrl_27_offset;
+ }
+
+ synaptics_rmi4_set_intr_mask(fhandler, fd, intr_count);
+
+ /* Allocate memory for finger data storage space */
+ fhandler->data_size = num_of_fingers * size_of_2d_data;
+ fhandler->data = kmalloc(fhandler->data_size, GFP_KERNEL);
+ if (!fhandler->data) {
+ dev_err(&rmi4_data->i2c_client->dev,
+ "%s: Failed to alloc mem for fhandler->data\n",
+ __func__);
+ return -ENOMEM;
+ }
+
+ return retval;
+}
+
+static int synaptics_rmi4_f1a_alloc_mem(struct synaptics_rmi4_data *rmi4_data,
+ struct synaptics_rmi4_fn *fhandler)
+{
+ int retval;
+ struct synaptics_rmi4_f1a_handle *f1a;
+
+ f1a = kzalloc(sizeof(*f1a), GFP_KERNEL);
+ if (!f1a) {
+ dev_err(&rmi4_data->i2c_client->dev,
+ "%s: Failed to alloc mem for function handle\n",
+ __func__);
+ return -ENOMEM;
+ }
+
+ fhandler->data = (void *)f1a;
+ fhandler->extra = NULL;
+
+ retval = synaptics_rmi4_i2c_read(rmi4_data,
+ fhandler->full_addr.query_base,
+ f1a->button_query.data,
+ sizeof(f1a->button_query.data));
+ if (retval < 0) {
+ dev_err(&rmi4_data->i2c_client->dev,
+ "%s: Failed to read query registers\n",
+ __func__);
+ return retval;
+ }
+
+ f1a->max_count = f1a->button_query.max_button_count + 1;
+
+ f1a->button_control.txrx_map = kzalloc(f1a->max_count * 2, GFP_KERNEL);
+ if (!f1a->button_control.txrx_map) {
+ dev_err(&rmi4_data->i2c_client->dev,
+ "%s: Failed to alloc mem for tx rx mapping\n",
+ __func__);
+ return -ENOMEM;
+ }
+
+ f1a->button_bitmask_size = (f1a->max_count + 7) / 8;
+
+ f1a->button_data_buffer = kcalloc(f1a->button_bitmask_size,
+ sizeof(*(f1a->button_data_buffer)), GFP_KERNEL);
+ if (!f1a->button_data_buffer) {
+ dev_err(&rmi4_data->i2c_client->dev,
+ "%s: Failed to alloc mem for data buffer\n",
+ __func__);
+ return -ENOMEM;
+ }
+
+ f1a->button_map = kcalloc(f1a->max_count,
+ sizeof(*(f1a->button_map)), GFP_KERNEL);
+ if (!f1a->button_map) {
+ dev_err(&rmi4_data->i2c_client->dev,
+ "%s: Failed to alloc mem for button map\n",
+ __func__);
+ return -ENOMEM;
+ }
+
+ return 0;
+}
+
+static int synaptics_rmi4_f1a_button_map(struct synaptics_rmi4_data *rmi4_data,
+ struct synaptics_rmi4_fn *fhandler)
+{
+ int retval;
+ unsigned char ii;
+ unsigned char mapping_offset = 0;
+ struct synaptics_rmi4_f1a_handle *f1a = fhandler->data;
+
+ mapping_offset = f1a->button_query.has_general_control +
+ f1a->button_query.has_interrupt_enable +
+ f1a->button_query.has_multibutton_select;
+
+ if (f1a->button_query.has_tx_rx_map) {
+ retval = synaptics_rmi4_i2c_read(rmi4_data,
+ fhandler->full_addr.ctrl_base + mapping_offset,
+ f1a->button_control.txrx_map,
+ sizeof(*(f1a->button_control.txrx_map)));
+ if (retval < 0) {
+ dev_err(&rmi4_data->i2c_client->dev,
+ "%s: Failed to read tx rx mapping\n",
+ __func__);
+ return retval;
+ }
+
+ rmi4_data->button_txrx_mapping = f1a->button_control.txrx_map;
+ }
+
+ if (cap_button_map.map) {
+ if (cap_button_map.nbuttons != f1a->max_count) {
+ f1a->valid_button_count = min(f1a->max_count,
+ cap_button_map.nbuttons);
+ } else {
+ f1a->valid_button_count = f1a->max_count;
+ }
+
+ for (ii = 0; ii < f1a->valid_button_count; ii++)
+ f1a->button_map[ii] = cap_button_map.map[ii];
+ }
+ return 0;
+}
+
+static void synaptics_rmi4_f1a_kfree(struct synaptics_rmi4_fn *fhandler)
+{
+ struct synaptics_rmi4_f1a_handle *f1a = fhandler->data;
+
+ if (f1a) {
+ kfree(f1a->button_control.txrx_map);
+ kfree(f1a->button_data_buffer);
+ kfree(f1a->button_map);
+ kfree(f1a);
+ fhandler->data = NULL;
+ }
+
+ return;
+}
+
+static int synaptics_rmi4_f1a_init(struct synaptics_rmi4_data *rmi4_data,
+ struct synaptics_rmi4_fn *fhandler,
+ struct synaptics_rmi4_fn_desc *fd,
+ unsigned int intr_count)
+{
+ int retval;
+
+ fhandler->fn_number = fd->fn_number;
+ fhandler->num_of_data_sources = fd->intr_src_count;
+
+ synaptics_rmi4_set_intr_mask(fhandler, fd, intr_count);
+
+ retval = synaptics_rmi4_f1a_alloc_mem(rmi4_data, fhandler);
+ if (retval < 0)
+ goto error_exit;
+
+ retval = synaptics_rmi4_f1a_button_map(rmi4_data, fhandler);
+ if (retval < 0)
+ goto error_exit;
+
+ rmi4_data->button_0d_enabled = 1;
+
+ return 0;
+
+error_exit:
+ synaptics_rmi4_f1a_kfree(fhandler);
+
+ return retval;
+}
+
+static void synaptics_rmi4_empty_fn_list(struct synaptics_rmi4_data *rmi4_data)
+{
+ struct synaptics_rmi4_fn *fhandler;
+ struct synaptics_rmi4_fn *fhandler_temp;
+ struct synaptics_rmi4_device_info *rmi;
+
+ rmi = &(rmi4_data->rmi4_mod_info);
+
+ if (!list_empty(&rmi->support_fn_list)) {
+ list_for_each_entry_safe(fhandler,
+ fhandler_temp,
+ &rmi->support_fn_list,
+ link) {
+ if (fhandler->fn_number == SYNAPTICS_RMI4_F1A) {
+ synaptics_rmi4_f1a_kfree(fhandler);
+ } else {
+ kfree(fhandler->extra);
+ kfree(fhandler->data);
+ }
+ list_del(&fhandler->link);
+ kfree(fhandler);
+ }
+ }
+ INIT_LIST_HEAD(&rmi->support_fn_list);
+
+ return;
+}
+
+static int synaptics_rmi4_check_status(struct synaptics_rmi4_data *rmi4_data,
+ bool *was_in_bl_mode)
+{
+ int retval;
+ int timeout = CHECK_STATUS_TIMEOUT_MS;
+ unsigned char command = 0x01;
+ unsigned char intr_status;
+ struct synaptics_rmi4_f01_device_status status;
+
+ /* Do a device reset first */
+ retval = synaptics_rmi4_i2c_write(rmi4_data,
+ rmi4_data->f01_cmd_base_addr,
+ &command,
+ sizeof(command));
+ if (retval < 0)
+ return retval;
+
+ msleep(DELAY_UI_READY);
+
+ retval = synaptics_rmi4_i2c_read(rmi4_data,
+ rmi4_data->f01_data_base_addr,
+ status.data,
+ sizeof(status.data));
+ if (retval < 0)
+ return retval;
+
+ while (status.status_code == STATUS_CRC_IN_PROGRESS) {
+ if (timeout > 0)
+ msleep(20);
+ else
+ return -1;
+
+ retval = synaptics_rmi4_i2c_read(rmi4_data,
+ rmi4_data->f01_data_base_addr,
+ status.data,
+ sizeof(status.data));
+ if (retval < 0)
+ return retval;
+
+ timeout -= 20;
+ }
+
+ if (timeout != CHECK_STATUS_TIMEOUT_MS)
+ *was_in_bl_mode = true;
+
+ if (status.flash_prog == 1) {
+ rmi4_data->flash_prog_mode = true;
+ pr_notice("%s: In flash prog mode, status = 0x%02x\n",
+ __func__,
+ status.status_code);
+ } else {
+ rmi4_data->flash_prog_mode = false;
+ }
+
+ retval = synaptics_rmi4_i2c_read(rmi4_data,
+ rmi4_data->f01_data_base_addr + 1,
+ &intr_status,
+ sizeof(intr_status));
+ if (retval < 0) {
+ dev_err(&rmi4_data->i2c_client->dev,
+ "%s: Failed to read interrupt status\n",
+ __func__);
+ return retval;
+ }
+
+ return 0;
+}
+
+static void synaptics_rmi4_set_configured(struct synaptics_rmi4_data *rmi4_data)
+{
+ int retval;
+ unsigned char device_ctrl;
+
+ retval = synaptics_rmi4_i2c_read(rmi4_data,
+ rmi4_data->f01_ctrl_base_addr,
+ &device_ctrl,
+ sizeof(device_ctrl));
+ if (retval < 0) {
+ dev_err(&(rmi4_data->input_dev->dev),
+ "%s: Failed to set configured\n",
+ __func__);
+ return;
+ }
+
+ rmi4_data->no_sleep_setting = device_ctrl & NO_SLEEP_ON;
+ device_ctrl |= CONFIGURED;
+
+ retval = synaptics_rmi4_i2c_write(rmi4_data,
+ rmi4_data->f01_ctrl_base_addr,
+ &device_ctrl,
+ sizeof(device_ctrl));
+ if (retval < 0) {
+ dev_err(&(rmi4_data->input_dev->dev),
+ "%s: Failed to set configured\n",
+ __func__);
+ }
+
+ return;
+}
+
+static int synaptics_rmi4_alloc_fh(struct synaptics_rmi4_fn **fhandler,
+ struct synaptics_rmi4_fn_desc *rmi_fd, int page_number)
+{
+ *fhandler = kmalloc(sizeof(**fhandler), GFP_KERNEL);
+ if (!(*fhandler))
+ return -ENOMEM;
+
+ (*fhandler)->full_addr.data_base =
+ (rmi_fd->data_base_addr |
+ (page_number << 8));
+ (*fhandler)->full_addr.ctrl_base =
+ (rmi_fd->ctrl_base_addr |
+ (page_number << 8));
+ (*fhandler)->full_addr.cmd_base =
+ (rmi_fd->cmd_base_addr |
+ (page_number << 8));
+ (*fhandler)->full_addr.query_base =
+ (rmi_fd->query_base_addr |
+ (page_number << 8));
+
+ return 0;
+}
+
+ /**
+ * synaptics_rmi4_query_device()
+ *
+ * Called by synaptics_rmi4_probe().
+ *
+ * This function scans the page description table, records the offsets
+ * to the register types of Function $01, sets up the function handlers
+ * for Function $11 and Function $12, determines the number of interrupt
+ * sources from the sensor, adds valid Functions with data inputs to the
+ * Function linked list, parses information from the query registers of
+ * Function $01, and enables the interrupt sources from the valid Functions
+ * with data inputs.
+ */
+static int synaptics_rmi4_query_device(struct synaptics_rmi4_data *rmi4_data)
+{
+ int retval;
+ unsigned char ii;
+ unsigned char page_number;
+ unsigned char intr_count;
+ unsigned char f01_query[F01_STD_QUERY_LEN];
+ unsigned short pdt_entry_addr;
+ unsigned short intr_addr;
+ bool was_in_bl_mode;
+ struct synaptics_rmi4_fn_desc rmi_fd;
+ struct synaptics_rmi4_fn *fhandler;
+ struct synaptics_rmi4_device_info *rmi;
+
+ rmi = &(rmi4_data->rmi4_mod_info);
+
+rescan_pdt:
+ was_in_bl_mode = false;
+ intr_count = 0;
+ INIT_LIST_HEAD(&rmi->support_fn_list);
+
+ /* Scan the page description tables of the pages to service */
+ for (page_number = 0; page_number < PAGES_TO_SERVICE; page_number++) {
+ for (pdt_entry_addr = PDT_START; pdt_entry_addr > PDT_END;
+ pdt_entry_addr -= PDT_ENTRY_SIZE) {
+ pdt_entry_addr |= (page_number << 8);
+
+ retval = synaptics_rmi4_i2c_read(rmi4_data,
+ pdt_entry_addr,
+ (unsigned char *)&rmi_fd,
+ sizeof(rmi_fd));
+ if (retval < 0)
+ return retval;
+
+ fhandler = NULL;
+
+ if (rmi_fd.fn_number == 0) {
+ dev_dbg(&rmi4_data->i2c_client->dev,
+ "%s: Reached end of PDT\n",
+ __func__);
+ break;
+ }
+
+ dev_dbg(&rmi4_data->i2c_client->dev,
+ "%s: F%02x found (page %d)\n",
+ __func__, rmi_fd.fn_number,
+ page_number);
+
+ switch (rmi_fd.fn_number) {
+ case SYNAPTICS_RMI4_F01:
+ if (rmi_fd.intr_src_count == 0)
+ break;
+
+ retval = synaptics_rmi4_alloc_fh(&fhandler,
+ &rmi_fd, page_number);
+ if (retval < 0) {
+ dev_err(&rmi4_data->i2c_client->dev,
+ "%s: Failed to alloc for F%d\n",
+ __func__,
+ rmi_fd.fn_number);
+ return retval;
+ }
+
+ retval = synaptics_rmi4_f01_init(rmi4_data,
+ fhandler, &rmi_fd, intr_count);
+ if (retval < 0) {
+ kfree(fhandler);
+ fhandler = NULL;
+ return retval;
+ }
+
+ retval = synaptics_rmi4_check_status(rmi4_data,
+ &was_in_bl_mode);
+ if (retval < 0) {
+ dev_err(&rmi4_data->i2c_client->dev,
+ "%s: Failed to check status\n",
+ __func__);
+ kfree(fhandler);
+ fhandler = NULL;
+ return retval;
+ }
+
+ if (was_in_bl_mode) {
+ kfree(fhandler);
+ fhandler = NULL;
+ goto rescan_pdt;
+ }
+
+ if (rmi4_data->flash_prog_mode) {
+ kfree(fhandler);
+ fhandler = NULL;
+ goto flash_prog_mode;
+ }
+
+ break;
+ case SYNAPTICS_RMI4_F11:
+ if (rmi_fd.intr_src_count == 0)
+ break;
+
+ retval = synaptics_rmi4_alloc_fh(&fhandler,
+ &rmi_fd, page_number);
+ if (retval < 0) {
+ dev_err(&rmi4_data->i2c_client->dev,
+ "%s: Failed to alloc for F%d\n",
+ __func__,
+ rmi_fd.fn_number);
+ return retval;
+ }
+
+ retval = synaptics_rmi4_f11_init(rmi4_data,
+ fhandler, &rmi_fd, intr_count);
+ if (retval < 0) {
+ kfree(fhandler);
+ fhandler = NULL;
+ return retval;
+ }
+
+ break;
+ case SYNAPTICS_RMI4_F12:
+ if (rmi_fd.intr_src_count == 0)
+ break;
+
+ retval = synaptics_rmi4_alloc_fh(&fhandler,
+ &rmi_fd, page_number);
+ if (retval < 0) {
+ dev_err(&rmi4_data->i2c_client->dev,
+ "%s: Failed to alloc for F%d\n",
+ __func__,
+ rmi_fd.fn_number);
+ return retval;
+ }
+
+ retval = synaptics_rmi4_f12_init(rmi4_data,
+ fhandler, &rmi_fd, intr_count);
+ if (retval < 0) {
+ kfree(fhandler);
+ fhandler = NULL;
+ return retval;
+ }
+
+ break;
+ case SYNAPTICS_RMI4_F1A:
+ if (rmi_fd.intr_src_count == 0)
+ break;
+
+ retval = synaptics_rmi4_alloc_fh(&fhandler,
+ &rmi_fd, page_number);
+ if (retval < 0) {
+ dev_err(&rmi4_data->i2c_client->dev,
+ "%s: Failed to alloc for F%d\n",
+ __func__,
+ rmi_fd.fn_number);
+ return retval;
+ }
+
+ retval = synaptics_rmi4_f1a_init(rmi4_data,
+ fhandler, &rmi_fd, intr_count);
+ if (retval < 0) {
+ kfree(fhandler);
+ fhandler = NULL;
+ return retval;
+ }
+
+ break;
+ }
+
+ /* Accumulate the interrupt count */
+ intr_count += (rmi_fd.intr_src_count & MASK_3BIT);
+
+ if (fhandler && rmi_fd.intr_src_count) {
+ list_add_tail(&fhandler->link,
+ &rmi->support_fn_list);
+ }
+ }
+ }
+
+flash_prog_mode:
+ rmi4_data->num_of_intr_regs = (intr_count + 7) / 8;
+ dev_dbg(&rmi4_data->i2c_client->dev,
+ "%s: Number of interrupt registers = %d\n",
+ __func__, rmi4_data->num_of_intr_regs);
+
+ retval = synaptics_rmi4_i2c_read(rmi4_data,
+ rmi4_data->f01_query_base_addr,
+ f01_query,
+ sizeof(f01_query));
+ if (retval < 0)
+ return retval;
+
+ /* RMI Version 4.0 currently supported */
+ rmi->version_major = 4;
+ rmi->version_minor = 0;
+
+ rmi->manufacturer_id = f01_query[0];
+ rmi->product_props = f01_query[1];
+ rmi->product_info[0] = f01_query[2] & MASK_7BIT;
+ rmi->product_info[1] = f01_query[3] & MASK_7BIT;
+ rmi->date_code[0] = f01_query[4] & MASK_5BIT;
+ rmi->date_code[1] = f01_query[5] & MASK_4BIT;
+ rmi->date_code[2] = f01_query[6] & MASK_5BIT;
+ rmi->tester_id = ((f01_query[7] & MASK_7BIT) << 8) |
+ (f01_query[8] & MASK_7BIT);
+ rmi->serial_number = ((f01_query[9] & MASK_7BIT) << 8) |
+ (f01_query[10] & MASK_7BIT);
+ memcpy(rmi->product_id_string, &f01_query[11], 10);
+
+ if (rmi->manufacturer_id != 1) {
+ dev_err(&rmi4_data->i2c_client->dev,
+ "%s: Non-Synaptics device found, manufacturer ID = %d\n",
+ __func__, rmi->manufacturer_id);
+ }
+
+ retval = synaptics_rmi4_i2c_read(rmi4_data,
+ rmi4_data->f01_query_base_addr + F01_BUID_ID_OFFSET,
+ rmi->build_id,
+ sizeof(rmi->build_id));
+ if (retval < 0)
+ return retval;
+
+ rmi4_data->firmware_id = (unsigned int)rmi->build_id[0] +
+ (unsigned int)rmi->build_id[1] * 0x100 +
+ (unsigned int)rmi->build_id[2] * 0x10000;
+
+ memset(rmi4_data->intr_mask, 0x00, sizeof(rmi4_data->intr_mask));
+
+ /*
+ * Map out the interrupt bit masks for the interrupt sources
+ * from the registered function handlers.
+ */
+ if (!list_empty(&rmi->support_fn_list)) {
+ list_for_each_entry(fhandler, &rmi->support_fn_list, link) {
+ if (fhandler->num_of_data_sources) {
+ rmi4_data->intr_mask[fhandler->intr_reg_num] |=
+ fhandler->intr_mask;
+ }
+ }
+ }
+
+ if (rmi4_data->f11_wakeup_gesture || rmi4_data->f12_wakeup_gesture)
+ rmi4_data->enable_wakeup_gesture = WAKEUP_GESTURE;
+ else
+ rmi4_data->enable_wakeup_gesture = false;
+
+ /* Enable the interrupt sources */
+ for (ii = 0; ii < rmi4_data->num_of_intr_regs; ii++) {
+ if (rmi4_data->intr_mask[ii] != 0x00) {
+ dev_dbg(&rmi4_data->i2c_client->dev,
+ "%s: Interrupt enable mask %d = 0x%02x\n",
+ __func__, ii, rmi4_data->intr_mask[ii]);
+ intr_addr = rmi4_data->f01_ctrl_base_addr + 1 + ii;
+ retval = synaptics_rmi4_i2c_write(rmi4_data,
+ intr_addr,
+ &(rmi4_data->intr_mask[ii]),
+ sizeof(rmi4_data->intr_mask[ii]));
+ if (retval < 0)
+ return retval;
+ }
+ }
+
+ synaptics_rmi4_set_configured(rmi4_data);
+
+ return 0;
+}
+
+static void synaptics_rmi4_set_params(struct synaptics_rmi4_data *rmi4_data)
+{
+ unsigned char ii;
+ struct synaptics_rmi4_f1a_handle *f1a;
+ struct synaptics_rmi4_fn *fhandler;
+ struct synaptics_rmi4_device_info *rmi;
+
+ rmi = &(rmi4_data->rmi4_mod_info);
+
+ input_set_abs_params(rmi4_data->input_dev,
+ ABS_MT_POSITION_X, 0,
+ rmi4_data->sensor_max_x, 0, 0);
+ input_set_abs_params(rmi4_data->input_dev,
+ ABS_MT_POSITION_Y, 0,
+ rmi4_data->sensor_max_y, 0, 0);
+#ifdef REPORT_2D_W
+ input_set_abs_params(rmi4_data->input_dev,
+ ABS_MT_TOUCH_MAJOR, 0,
+ rmi4_data->max_touch_width, 0, 0);
+ input_set_abs_params(rmi4_data->input_dev,
+ ABS_MT_TOUCH_MINOR, 0,
+ rmi4_data->max_touch_width, 0, 0);
+#endif
+
+#ifdef TYPE_B_PROTOCOL
+ input_mt_init_slots(rmi4_data->input_dev,
+ rmi4_data->num_of_fingers, 0);
+#endif
+
+ f1a = NULL;
+ if (!list_empty(&rmi->support_fn_list)) {
+ list_for_each_entry(fhandler, &rmi->support_fn_list, link) {
+ if (fhandler->fn_number == SYNAPTICS_RMI4_F1A)
+ f1a = fhandler->data;
+ }
+ }
+
+ if (f1a) {
+ for (ii = 0; ii < f1a->valid_button_count; ii++) {
+ set_bit(f1a->button_map[ii],
+ rmi4_data->input_dev->keybit);
+ input_set_capability(rmi4_data->input_dev,
+ EV_KEY, f1a->button_map[ii]);
+ }
+ }
+
+ if (rmi4_data->f11_wakeup_gesture || rmi4_data->f12_wakeup_gesture) {
+ set_bit(KEY_POWER, rmi4_data->input_dev->keybit);
+ input_set_capability(rmi4_data->input_dev, EV_KEY, KEY_POWER);
+ }
+ return;
+}
+
+static int synaptics_rmi4_set_input_dev(struct synaptics_rmi4_data *rmi4_data)
+{
+ int retval;
+
+ rmi4_data->input_dev = input_allocate_device();
+ if (rmi4_data->input_dev == NULL) {
+ dev_err(&rmi4_data->i2c_client->dev,
+ "%s: Failed to allocate input device\n",
+ __func__);
+ retval = -ENOMEM;
+ goto err_input_device;
+ }
+
+ retval = synaptics_rmi4_query_device(rmi4_data);
+ if (retval < 0) {
+ dev_err(&rmi4_data->i2c_client->dev,
+ "%s: Failed to query device\n",
+ __func__);
+ goto err_query_device;
+ }
+
+ rmi4_data->input_dev->name = DRIVER_NAME;
+ rmi4_data->input_dev->phys = INPUT_PHYS_NAME;
+ rmi4_data->input_dev->id.product = SYNAPTICS_DSX_DRIVER_PRODUCT;
+ rmi4_data->input_dev->id.version = SYNAPTICS_DSX_DRIVER_VERSION;
+ rmi4_data->input_dev->id.bustype = BUS_I2C;
+ rmi4_data->input_dev->dev.parent = &rmi4_data->i2c_client->dev;
+ input_set_drvdata(rmi4_data->input_dev, rmi4_data);
+
+ set_bit(EV_SYN, rmi4_data->input_dev->evbit);
+ set_bit(EV_KEY, rmi4_data->input_dev->evbit);
+ set_bit(EV_ABS, rmi4_data->input_dev->evbit);
+ set_bit(BTN_TOUCH, rmi4_data->input_dev->keybit);
+ set_bit(BTN_TOOL_FINGER, rmi4_data->input_dev->keybit);
+#ifdef INPUT_PROP_DIRECT
+ set_bit(INPUT_PROP_DIRECT, rmi4_data->input_dev->propbit);
+#endif
+
+ synaptics_rmi4_set_params(rmi4_data);
+
+ retval = input_register_device(rmi4_data->input_dev);
+ if (retval) {
+ dev_err(&rmi4_data->i2c_client->dev,
+ "%s: Failed to register input device\n",
+ __func__);
+ goto err_register_input;
+ }
+
+ return 0;
+
+err_register_input:
+err_query_device:
+ synaptics_rmi4_empty_fn_list(rmi4_data);
+ input_free_device(rmi4_data->input_dev);
+
+err_input_device:
+ return retval;
+}
+
+static int synaptics_rmi4_free_fingers(struct synaptics_rmi4_data *rmi4_data)
+{
+ unsigned char ii;
+ mutex_lock(&rmi4_report_mutex);
+
+#ifdef TYPE_B_PROTOCOL
+ for (ii = 0; ii < rmi4_data->num_of_fingers; ii++) {
+ input_mt_slot(rmi4_data->input_dev, ii);
+ input_mt_report_slot_state(rmi4_data->input_dev,
+ MT_TOOL_FINGER, 0);
+ }
+#endif
+ input_report_key(rmi4_data->input_dev,
+ BTN_TOUCH, 0);
+ input_report_key(rmi4_data->input_dev,
+ BTN_TOOL_FINGER, 0);
+#ifndef TYPE_B_PROTOCOL
+ input_mt_sync(rmi4_data->input_dev);
+#endif
+ input_sync(rmi4_data->input_dev);
+ mutex_unlock(&rmi4_report_mutex);
+ rmi4_data->fingers_on_2d = false;
+
+ return 0;
+}
+
+static int synaptics_rmi4_reinit_device(struct synaptics_rmi4_data *rmi4_data)
+{
+ int retval;
+ unsigned char ii;
+ unsigned short intr_addr;
+ struct synaptics_rmi4_fn *fhandler;
+ struct synaptics_rmi4_exp_fhandler *exp_fhandler;
+ struct synaptics_rmi4_device_info *rmi;
+
+ rmi = &(rmi4_data->rmi4_mod_info);
+
+ mutex_lock(&(rmi4_data->rmi4_reset_mutex));
+
+ synaptics_rmi4_free_fingers(rmi4_data);
+
+ if (!list_empty(&rmi->support_fn_list)) {
+ list_for_each_entry(fhandler, &rmi->support_fn_list, link) {
+ if (fhandler->fn_number == SYNAPTICS_RMI4_F12) {
+ synaptics_rmi4_f12_set_enables(rmi4_data, 0);
+ break;
+ }
+ }
+ }
+
+ for (ii = 0; ii < rmi4_data->num_of_intr_regs; ii++) {
+ if (rmi4_data->intr_mask[ii] != 0x00) {
+ dev_dbg(&rmi4_data->i2c_client->dev,
+ "%s: Interrupt enable mask %d = 0x%02x\n",
+ __func__, ii, rmi4_data->intr_mask[ii]);
+ intr_addr = rmi4_data->f01_ctrl_base_addr + 1 + ii;
+ retval = synaptics_rmi4_i2c_write(rmi4_data,
+ intr_addr,
+ &(rmi4_data->intr_mask[ii]),
+ sizeof(rmi4_data->intr_mask[ii]));
+ if (retval < 0)
+ goto exit;
+ }
+ }
+
+ mutex_lock(&exp_data.mutex);
+ if (!list_empty(&exp_data.list)) {
+ list_for_each_entry(exp_fhandler, &exp_data.list, link)
+ if (exp_fhandler->exp_fn->reinit != NULL)
+ exp_fhandler->exp_fn->reinit(rmi4_data);
+ }
+ mutex_unlock(&exp_data.mutex);
+
+ synaptics_rmi4_set_configured(rmi4_data);
+
+ retval = 0;
+
+exit:
+ mutex_unlock(&(rmi4_data->rmi4_reset_mutex));
+ return retval;
+}
+
+static int synaptics_rmi4_reset_device(struct synaptics_rmi4_data *rmi4_data)
+{
+ int retval;
+ unsigned char command = 0x01;
+ struct synaptics_rmi4_exp_fhandler *exp_fhandler;
+
+ mutex_lock(&(rmi4_data->rmi4_reset_mutex));
+
+ rmi4_data->touch_stopped = true;
+
+ synaptics_rmi4_irq_enable(rmi4_data, false);
+
+ retval = synaptics_rmi4_i2c_write(rmi4_data,
+ rmi4_data->f01_cmd_base_addr,
+ &command,
+ sizeof(command));
+ if (retval < 0) {
+ dev_err(&rmi4_data->i2c_client->dev,
+ "%s: Failed to issue reset command, error = %d\n",
+ __func__, retval);
+ mutex_unlock(&(rmi4_data->rmi4_reset_mutex));
+ return retval;
+ }
+
+ msleep(DELAY_UI_READY);
+
+ synaptics_rmi4_free_fingers(rmi4_data);
+
+ synaptics_rmi4_empty_fn_list(rmi4_data);
+
+ retval = synaptics_rmi4_query_device(rmi4_data);
+ if (retval < 0) {
+ dev_err(&rmi4_data->i2c_client->dev,
+ "%s: Failed to query device\n",
+ __func__);
+ mutex_unlock(&(rmi4_data->rmi4_reset_mutex));
+ return retval;
+ }
+
+ synaptics_rmi4_set_params(rmi4_data);
+
+ mutex_lock(&exp_data.mutex);
+ if (!list_empty(&exp_data.list)) {
+ list_for_each_entry(exp_fhandler, &exp_data.list, link)
+ if (exp_fhandler->exp_fn->reset != NULL)
+ exp_fhandler->exp_fn->reset(rmi4_data);
+ }
+ mutex_unlock(&exp_data.mutex);
+
+ rmi4_data->touch_stopped = false;
+
+ synaptics_rmi4_irq_enable(rmi4_data, true);
+
+ mutex_unlock(&(rmi4_data->rmi4_reset_mutex));
+
+ return 0;
+}
+
+
+static void synaptics_rmi4_sleep_enable(struct synaptics_rmi4_data *rmi4_data,
+ bool enable)
+{
+ int retval;
+ unsigned char device_ctrl;
+ unsigned char no_sleep_setting = rmi4_data->no_sleep_setting;
+
+ retval = synaptics_rmi4_i2c_read(rmi4_data,
+ rmi4_data->f01_ctrl_base_addr,
+ &device_ctrl,
+ sizeof(device_ctrl));
+ if (retval < 0) {
+ dev_err(&rmi4_data->i2c_client->dev,
+ "%s: Failed to read device control\n",
+ __func__);
+ return;
+ }
+
+ device_ctrl = device_ctrl & ~MASK_3BIT;
+ if (enable)
+ device_ctrl = device_ctrl | NO_SLEEP_OFF | SENSOR_SLEEP;
+ else
+ device_ctrl = device_ctrl | no_sleep_setting | NORMAL_OPERATION;
+
+ retval = synaptics_rmi4_i2c_write(rmi4_data,
+ rmi4_data->f01_ctrl_base_addr,
+ &device_ctrl,
+ sizeof(device_ctrl));
+ if (retval < 0) {
+ dev_err(&rmi4_data->i2c_client->dev,
+ "%s: Failed to write device control\n",
+ __func__);
+ return;
+ }
+
+ rmi4_data->sensor_sleep = enable;
+
+ return;
+}
+
+
+
+
+/**
+ * synaptics_rmi4_exp_fn_work()
+ *
+ * Called by the kernel at the scheduled time.
+ *
+ * This function is a work thread that checks for the insertion and
+ * removal of other expansion Function modules such as rmi_dev and calls
+ * their initialization and removal callback functions accordingly.
+ */
+static void synaptics_rmi4_exp_fn_work(struct work_struct *work)
+{
+ int retval;
+ struct synaptics_rmi4_exp_fhandler *exp_fhandler;
+ struct synaptics_rmi4_exp_fhandler *exp_fhandler_temp;
+ struct synaptics_rmi4_data *rmi4_data = exp_data.rmi4_data;
+
+ mutex_lock(&exp_data.mutex);
+ if (!list_empty(&exp_data.list)) {
+ list_for_each_entry_safe(exp_fhandler,
+ exp_fhandler_temp,
+ &exp_data.list,
+ link) {
+ if ((exp_fhandler->exp_fn->init != NULL) &&
+ exp_fhandler->insert) {
+ retval = exp_fhandler->exp_fn->init(rmi4_data);
+ if (retval < 0) {
+ list_del(&exp_fhandler->link);
+ kfree(exp_fhandler);
+ } else {
+ exp_fhandler->insert = false;
+ }
+ } else if ((exp_fhandler->exp_fn->remove != NULL) &&
+ exp_fhandler->remove) {
+ exp_fhandler->exp_fn->remove(rmi4_data);
+ list_del(&exp_fhandler->link);
+ kfree(exp_fhandler);
+ }
+ }
+ }
+ mutex_unlock(&exp_data.mutex);
+
+ return;
+}
+
+/**
+ * synaptics_rmi4_new_function()
+ *
+ * Called by other expansion Function modules in their module init and
+ * module exit functions.
+ *
+ * This function is used by other expansion Function modules such as
+ * rmi_dev to register themselves with the driver by providing their
+ * initialization and removal callback function pointers so that they
+ * can be inserted or removed dynamically at module init and exit times,
+ * respectively.
+ */
+void synaptics_rmi4_new_function(struct synaptics_rmi4_exp_fn *exp_fn,
+ bool insert)
+{
+ struct synaptics_rmi4_exp_fhandler *exp_fhandler;
+
+ if (!exp_data.initialized) {
+ mutex_init(&exp_data.mutex);
+ INIT_LIST_HEAD(&exp_data.list);
+ exp_data.initialized = true;
+ }
+
+ mutex_lock(&exp_data.mutex);
+ if (insert) {
+ exp_fhandler = kzalloc(sizeof(*exp_fhandler), GFP_KERNEL);
+ if (!exp_fhandler) {
+ pr_err("%s: Failed to alloc mem for expansion function\n",
+ __func__);
+ goto exit;
+ }
+ exp_fhandler->exp_fn = exp_fn;
+ exp_fhandler->insert = true;
+ exp_fhandler->remove = false;
+ list_add_tail(&exp_fhandler->link, &exp_data.list);
+ } else if (!list_empty(&exp_data.list)) {
+ list_for_each_entry(exp_fhandler, &exp_data.list, link) {
+ if (exp_fhandler->exp_fn->fn_type == exp_fn->fn_type) {
+ exp_fhandler->insert = false;
+ exp_fhandler->remove = true;
+ goto exit;
+ }
+ }
+ }
+
+exit:
+ mutex_unlock(&exp_data.mutex);
+
+ if (exp_data.queue_work) {
+ queue_delayed_work(exp_data.workqueue,
+ &exp_data.work,
+ msecs_to_jiffies(EXP_FN_WORK_DELAY_MS));
+ }
+
+ return;
+}
+EXPORT_SYMBOL(synaptics_rmi4_new_function);
+
+
+static ssize_t synaptics_rmi4_f34_configid_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct synaptics_rmi4_data *rmi4_data = dev_get_drvdata(dev);
+
+ return snprintf(buf, PAGE_SIZE, "0x%x\n", rmi4_data->config_id);
+}
+
+
+
+static ssize_t synaptics_rmi4_f01_product_id_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct synaptics_rmi4_data *rmi4_data = dev_get_drvdata(dev);
+
+ return snprintf(buf, PAGE_SIZE, "%s\n",
+ (rmi4_data->rmi4_mod_info.product_id_string));
+}
+
+
+static DEVICE_ATTR(tp_firmware_version, 0664, synaptics_rmi4_f34_configid_show, synaptics_rmi4_store_error);
+static DEVICE_ATTR(product_id, 0664, synaptics_rmi4_f01_product_id_show, synaptics_rmi4_store_error);
+
+static struct attribute *synaptics_rmi4_attrs[] = {
+ attrify(tp_firmware_version),
+ attrify(product_id),
+ NULL,
+};
+
+static struct attribute_group attr_group = {
+ .attrs = synaptics_rmi4_attrs,
+};
+ /**
+ * synaptics_rmi4_probe()
+ *
+ * Called by the kernel when an association with an I2C device of the
+ * same name is made (after doing i2c_add_driver).
+ *
+ * This function allocates and initializes the resources for the driver
+ * as an input driver, turns on the power to the sensor, queries the
+ * sensor for its supported Functions and characteristics, registers
+ * the driver to the input subsystem, sets up the interrupt, handles
+ * the registration of the early_suspend and late_resume functions,
+ * and creates a work queue for detection of other expansion Function
+ * modules.
+ */
+static int synaptics_rmi4_probe(struct i2c_client *client,
+ const struct i2c_device_id *dev_id)
+{
+ int retval, ret;
+ signed char attr_count;
+ struct synaptics_rmi4_data *rmi4_data;
+ struct device_node *np = client->dev.of_node;
+#if 0
+ int rst_gpio;
+#endif
+
+ if (!i2c_check_functionality(client->adapter,
+ I2C_FUNC_SMBUS_BYTE_DATA)) {
+ dev_err(&client->dev,
+ "%s: SMBus byte data not supported\n",
+ __func__);
+ return -EIO;
+ }
+
+#ifdef USE_I2C_DMA
+ wDMABuf_va = (unsigned char *)dma_zalloc_coherent(&client->dev, WRITE_SIZE_LIMIT,
+ &wDMABuf_pa, GFP_KERNEL);
+ if (!wDMABuf_va) {
+ dev_err(&client->dev, "Allocate DMA I2C Buffer failed, exit\n");
+ return -ENOMEM;
+ }
+#endif
+
+ if (!np)
+ return -ENODEV;
+#if 0
+ rst_gpio = of_get_named_gpio(np, "rest-gpios", 0);
+ if (!gpio_is_valid(rst_gpio))
+ return -ENODEV;
+
+ ret = gpio_request(rst_gpio, "synaptics_rmi4_rest");
+ if (ret < 0) {
+ dev_err(&client->dev,
+ "request rest gpio failed, cannot wake up controller: %d\n",
+ ret);
+ return ret;
+ }
+
+ gpio_direction_output(rst_gpio, 0);
+ gpio_set_value(rst_gpio, 1);
+ msleep(DELAY_BOOT_READY);
+ gpio_set_value(rst_gpio, 0);
+ msleep(DELAY_RESET_LOW);
+ gpio_set_value(rst_gpio, 1);
+ msleep(DELAY_UI_READY);
+#endif
+
+ rmi4_data = kzalloc(sizeof(*rmi4_data), GFP_KERNEL);
+ if (!rmi4_data) {
+ dev_err(&client->dev,
+ "%s: Failed to alloc mem for rmi4_data\n",
+ __func__);
+ return -ENOMEM;
+ }
+
+ rmi4_data->i2c_client = client;
+ rmi4_data->current_page = MASK_8BIT;
+ rmi4_data->touch_stopped = false;
+ rmi4_data->sensor_sleep = false;
+ rmi4_data->irq_enabled = false;
+ rmi4_data->fingers_on_2d = false;
+
+ rmi4_data->i2c_read = synaptics_rmi4_i2c_read;
+ rmi4_data->i2c_write = synaptics_rmi4_i2c_write;
+ rmi4_data->irq_enable = synaptics_rmi4_irq_enable;
+ rmi4_data->reset_device = synaptics_rmi4_reset_device;
+ rmi4_data->sleep_enable = synaptics_rmi4_sleep_enable;
+
+ rmi4_data->i2c_addr = client->addr;
+ rmi4_data->diagonal_rotation = of_property_read_bool(np,
+ "synaptics,diagonal-rotation");
+
+ mutex_init(&(rmi4_data->rmi4_io_ctrl_mutex));
+ mutex_init(&(rmi4_data->rmi4_reset_mutex));
+ mutex_init(&(rmi4_data->rmi4_exp_init_mutex));
+
+ i2c_set_clientdata(client, rmi4_data);
+ retval = synaptics_rmi4_set_input_dev(rmi4_data);
+ if (retval < 0) {
+ dev_err(&client->dev,
+ "%s: Failed to set up input device\n",
+ __func__);
+ goto err_set_input_dev;
+ }
+
+ thread = kthread_run(touch_event_handler, rmi4_data, "synaptics_dsx");
+ if (IS_ERR(thread)) {
+ retval = PTR_ERR(thread);
+ pr_err(" %s: failed to create kernel thread: %d\n", __func__, retval);
+ }
+
+ touch_irq = client->irq;
+ ret = devm_request_irq(&client->dev, touch_irq, (irq_handler_t) tpd_eint_handler,
+ IRQF_TRIGGER_LOW, "synaptics_rmi4_touch", rmi4_data);
+ if (ret < 0) {
+ dev_err(&client->dev,
+ "%s: Failed to register attention interrupt\n",
+ __func__);
+ goto err_enable_irq;
+ }
+ rmi4_data->irq_enabled = true;
+
+ if (!exp_data.initialized) {
+ mutex_init(&exp_data.mutex);
+ INIT_LIST_HEAD(&exp_data.list);
+ exp_data.initialized = true;
+ }
+
+
+ exp_data.workqueue = create_singlethread_workqueue("dsx_exp_workqueue");
+ INIT_DELAYED_WORK(&exp_data.work, synaptics_rmi4_exp_fn_work);
+ exp_data.rmi4_data = rmi4_data;
+ exp_data.queue_work = true;
+ queue_delayed_work(exp_data.workqueue,
+ &exp_data.work,
+ msecs_to_jiffies(EXP_FN_WORK_DELAY_MS));
+
+ for (attr_count = 0; attr_count < ARRAY_SIZE(attrs); attr_count++) {
+ retval = sysfs_create_file(&rmi4_data->input_dev->dev.kobj,
+ &attrs[attr_count].attr);
+ if (retval < 0) {
+ dev_err(&client->dev,
+ "%s: Failed to create sysfs attributes\n",
+ __func__);
+ goto err_sysfs;
+ }
+ }
+
+ retval = sysfs_create_group(&client->dev.kobj, &attr_group);
+ if (retval < 0) {
+ dev_err(&rmi4_data->i2c_client->dev,
+ "%s: Failed to create sysfs attributes\n",
+ __func__);
+ goto err_sysfs;
+ }
+
+ g_dev = &rmi4_data->input_dev->dev;
+
+ return retval;
+
+err_sysfs:
+ sysfs_remove_group(&client->dev.kobj, &attr_group);
+ for (attr_count--; attr_count >= 0; attr_count--) {
+ sysfs_remove_file(&rmi4_data->input_dev->dev.kobj,
+ &attrs[attr_count].attr);
+ }
+
+ cancel_delayed_work_sync(&exp_data.work);
+ flush_workqueue(exp_data.workqueue);
+ destroy_workqueue(exp_data.workqueue);
+
+ synaptics_rmi4_irq_enable(rmi4_data, false);
+
+err_enable_irq:
+
+ synaptics_rmi4_empty_fn_list(rmi4_data);
+ input_unregister_device(rmi4_data->input_dev);
+ rmi4_data->input_dev = NULL;
+
+err_set_input_dev:
+ kfree(rmi4_data);
+
+ return retval;
+}
+
+ /**
+ * synaptics_rmi4_remove()
+ *
+ * Called by the kernel when the association with an I2C device of the
+ * same name is broken (when the driver is unloaded).
+ *
+ * This function terminates the work queue, stops sensor data acquisition,
+ * frees the interrupt, unregisters the driver from the input subsystem,
+ * turns off the power to the sensor, and frees other allocated resources.
+ */
+static int synaptics_rmi4_remove(struct i2c_client *client)
+{
+ unsigned char attr_count;
+ struct synaptics_rmi4_data *rmi4_data = i2c_get_clientdata(client);
+
+ for (attr_count = 0; attr_count < ARRAY_SIZE(attrs); attr_count++) {
+ sysfs_remove_file(&rmi4_data->input_dev->dev.kobj,
+ &attrs[attr_count].attr);
+ }
+
+ cancel_delayed_work_sync(&exp_data.work);
+ flush_workqueue(exp_data.workqueue);
+ destroy_workqueue(exp_data.workqueue);
+
+ synaptics_rmi4_irq_enable(rmi4_data, false);
+
+ synaptics_rmi4_empty_fn_list(rmi4_data);
+ input_unregister_device(rmi4_data->input_dev);
+ rmi4_data->input_dev = NULL;
+
+#ifdef USE_I2C_DMA
+ if (wDMABuf_va)
+ dma_free_coherent(&client->dev, WRITE_SIZE_LIMIT, wDMABuf_va, wDMABuf_pa);
+#endif
+
+ kfree(rmi4_data);
+
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static void synaptics_rmi4_f11_wg(struct synaptics_rmi4_data *rmi4_data,
+ bool enable)
+{
+ int retval;
+ unsigned char reporting_control;
+ struct synaptics_rmi4_fn *fhandler;
+ struct synaptics_rmi4_device_info *rmi;
+
+ rmi = &(rmi4_data->rmi4_mod_info);
+
+ list_for_each_entry(fhandler, &rmi->support_fn_list, link) {
+ if (fhandler->fn_number == SYNAPTICS_RMI4_F11)
+ break;
+ }
+
+ retval = synaptics_rmi4_i2c_read(rmi4_data,
+ fhandler->full_addr.ctrl_base,
+ &reporting_control,
+ sizeof(reporting_control));
+ if (retval < 0) {
+ dev_err(&(rmi4_data->input_dev->dev),
+ "%s: Failed to change reporting mode\n",
+ __func__);
+ return;
+ }
+
+ reporting_control = (reporting_control & ~MASK_3BIT);
+ if (enable)
+ reporting_control |= F11_WAKEUP_GESTURE_MODE;
+ else
+ reporting_control |= F11_CONTINUOUS_MODE;
+
+ retval = synaptics_rmi4_i2c_write(rmi4_data,
+ fhandler->full_addr.ctrl_base,
+ &reporting_control,
+ sizeof(reporting_control));
+ if (retval < 0) {
+ dev_err(&(rmi4_data->input_dev->dev),
+ "%s: Failed to change reporting mode\n",
+ __func__);
+ return;
+ }
+
+ return;
+}
+
+static void synaptics_rmi4_f12_wg(struct synaptics_rmi4_data *rmi4_data,
+ bool enable)
+{
+ int retval;
+ unsigned char offset;
+ unsigned char reporting_control[3];
+ struct synaptics_rmi4_f12_extra_data *extra_data;
+ struct synaptics_rmi4_fn *fhandler;
+ struct synaptics_rmi4_device_info *rmi;
+
+ rmi = &(rmi4_data->rmi4_mod_info);
+
+ list_for_each_entry(fhandler, &rmi->support_fn_list, link) {
+ if (fhandler->fn_number == SYNAPTICS_RMI4_F12)
+ break;
+ }
+
+ extra_data = (struct synaptics_rmi4_f12_extra_data *)fhandler->extra;
+ offset = extra_data->ctrl20_offset;
+
+ retval = synaptics_rmi4_i2c_read(rmi4_data,
+ fhandler->full_addr.ctrl_base + offset,
+ reporting_control,
+ sizeof(reporting_control));
+ if (retval < 0) {
+ dev_err(&(rmi4_data->input_dev->dev),
+ "%s: Failed to change reporting mode\n",
+ __func__);
+ return;
+ }
+
+ if (enable)
+ reporting_control[2] = F12_WAKEUP_GESTURE_MODE;
+ else
+ reporting_control[2] = F12_CONTINUOUS_MODE;
+
+ retval = synaptics_rmi4_i2c_write(rmi4_data,
+ fhandler->full_addr.ctrl_base + offset,
+ reporting_control,
+ sizeof(reporting_control));
+ if (retval < 0) {
+ dev_err(&(rmi4_data->input_dev->dev),
+ "%s: Failed to change reporting mode\n",
+ __func__);
+ return;
+ }
+
+ return;
+}
+
+static void synaptics_rmi4_wakeup_gesture(struct synaptics_rmi4_data *rmi4_data,
+ bool enable)
+{
+ if (rmi4_data->f11_wakeup_gesture)
+ synaptics_rmi4_f11_wg(rmi4_data, enable);
+ else if (rmi4_data->f12_wakeup_gesture)
+ synaptics_rmi4_f12_wg(rmi4_data, enable);
+
+ return;
+}
+
+ /**
+ * synaptics_rmi4_suspend()
+ *
+ * Called by the kernel during the suspend phase when the system
+ * enters suspend.
+ *
+ * This function stops finger data acquisition and puts the sensor to
+ * sleep (if not already done so during the early suspend phase),
+ * disables the interrupt, and turns off the power to the sensor.
+ */
+static int __maybe_unused synaptics_rmi4_suspend(struct device *dev)
+{
+ struct synaptics_rmi4_exp_fhandler *exp_fhandler;
+ struct synaptics_rmi4_data *rmi4_data = dev_get_drvdata(g_dev);
+
+ if (rmi4_data->staying_awake)
+ return 0;
+
+ if (rmi4_data->enable_wakeup_gesture) {
+ synaptics_rmi4_wakeup_gesture(rmi4_data, true);
+ goto exit;
+ }
+
+ if (!rmi4_data->sensor_sleep) {
+ rmi4_data->touch_stopped = true;
+ synaptics_rmi4_sleep_enable(rmi4_data, true);
+ synaptics_rmi4_free_fingers(rmi4_data);
+ rmi4_data->irq_enabled = false;
+ free_irq(touch_irq, rmi4_data);
+ }
+
+exit:
+ mutex_lock(&exp_data.mutex);
+ if (!list_empty(&exp_data.list)) {
+ list_for_each_entry(exp_fhandler, &exp_data.list, link)
+ if (exp_fhandler->exp_fn->suspend != NULL)
+ exp_fhandler->exp_fn->suspend(rmi4_data);
+ }
+ mutex_unlock(&exp_data.mutex);
+
+
+ rmi4_data->sensor_sleep = true;
+
+ return 0;
+}
+
+ /**
+ * synaptics_rmi4_resume()
+ *
+ * Called by the kernel during the resume phase when the system
+ * wakes up from suspend.
+ *
+ * This function turns on the power to the sensor, wakes the sensor
+ * from sleep, enables the interrupt, and starts finger data
+ * acquisition.
+ */
+static int __maybe_unused synaptics_rmi4_resume(struct device *dev)
+{
+ int retval;
+ struct synaptics_rmi4_exp_fhandler *exp_fhandler;
+ struct synaptics_rmi4_data *rmi4_data = dev_get_drvdata(g_dev);
+
+ if (rmi4_data->staying_awake)
+ return 0;
+
+ if (rmi4_data->enable_wakeup_gesture) {
+ synaptics_rmi4_wakeup_gesture(rmi4_data, false);
+ goto exit;
+ }
+
+ retval = devm_request_irq(dev, touch_irq, (irq_handler_t) tpd_eint_handler,
+ IRQF_TRIGGER_LOW, "synaptics_rmi4_touch", rmi4_data);
+ rmi4_data->irq_enabled = true;
+
+ synaptics_rmi4_sleep_enable(rmi4_data, false);
+ retval = synaptics_rmi4_reinit_device(rmi4_data);
+ if (retval < 0) {
+ dev_err(&rmi4_data->i2c_client->dev,
+ "%s: Failed to reinit device\n",
+ __func__);
+ return 0;
+ }
+exit:
+ mutex_lock(&exp_data.mutex);
+ if (!list_empty(&exp_data.list)) {
+ list_for_each_entry(exp_fhandler, &exp_data.list, link)
+ if (exp_fhandler->exp_fn->resume != NULL)
+ exp_fhandler->exp_fn->resume(rmi4_data);
+ }
+ mutex_unlock(&exp_data.mutex);
+
+
+ rmi4_data->sensor_sleep = false;
+ rmi4_data->touch_stopped = false;
+
+ return 0;
+}
+
+#endif
+
+static const struct i2c_device_id synaptics_rmi4_id_table[] = {
+ {"synaptics_dsx", 0},
+ {},
+};
+MODULE_DEVICE_TABLE(i2c, synaptics_rmi4_id_table);
+
+static SIMPLE_DEV_PM_OPS(synaptics_rmi4_pm_ops, synaptics_rmi4_suspend, synaptics_rmi4_resume);
+
+
+static const struct of_device_id synaptics_rmi4_dt_ids[] = {
+ { .compatible = "synaptics_dsx" },
+ { /* sentinel */},
+};
+
+static struct i2c_driver synaptics_rmi4_driver = {
+ .driver = {
+ .name = "synaptics_dsx",
+ .pm = &synaptics_rmi4_pm_ops,
+ .of_match_table = synaptics_rmi4_dt_ids,
+ },
+ .id_table = synaptics_rmi4_id_table,
+ .probe = synaptics_rmi4_probe,
+ .remove = synaptics_rmi4_remove,
+};
+
+module_i2c_driver(synaptics_rmi4_driver);
+
+MODULE_AUTHOR("Synaptics, Inc.");
+MODULE_DESCRIPTION("Synaptics DSX I2C Touch Driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/input/touchscreen/synaptics_dsx/synaptics_dsx_i2c.h b/drivers/input/touchscreen/synaptics_dsx/synaptics_dsx_i2c.h
new file mode 100644
index 000000000000..12d7bf4ca225
--- /dev/null
+++ b/drivers/input/touchscreen/synaptics_dsx/synaptics_dsx_i2c.h
@@ -0,0 +1,421 @@
+/*
+ * Synaptics DSX touchscreen driver
+ *
+ * Copyright (C) 2012-2015 Synaptics Incorporated. All rights reserved.
+ *
+ * Copyright (C) 2012 Alexandra Chin <alexandra.chin@tw.synaptics.com>
+ * Copyright (C) 2012 Scott Lin <scott.lin@tw.synaptics.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.
+ *
+ * INFORMATION CONTAINED IN THIS DOCUMENT IS PROVIDED "AS-IS," AND SYNAPTICS
+ * EXPRESSLY DISCLAIMS ALL EXPRESS AND IMPLIED WARRANTIES, INCLUDING ANY
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE,
+ * AND ANY WARRANTIES OF NON-INFRINGEMENT OF ANY INTELLECTUAL PROPERTY RIGHTS.
+ * IN NO EVENT SHALL SYNAPTICS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, PUNITIVE, OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OF THE INFORMATION CONTAINED IN THIS DOCUMENT, HOWEVER CAUSED
+ * AND BASED ON ANY THEORY OF LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, AND EVEN IF SYNAPTICS WAS ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE. IF A TRIBUNAL OF COMPETENT JURISDICTION DOES
+ * NOT PERMIT THE DISCLAIMER OF DIRECT DAMAGES OR ANY OTHER DAMAGES, SYNAPTICS'
+ * TOTAL CUMULATIVE LIABILITY TO ANY PARTY SHALL NOT EXCEED ONE HUNDRED U.S.
+ * DOLLARS.
+ */
+#ifndef _SYNAPTICS_DSX_RMI4_H_
+#define _SYNAPTICS_DSX_RMI4_H_
+
+#define SYNAPTICS_DS4 (1 << 0)
+#define SYNAPTICS_DS5 (1 << 1)
+#define SYNAPTICS_DSX_DRIVER_PRODUCT (SYNAPTICS_DS4 | SYNAPTICS_DS5)
+#define SYNAPTICS_DSX_DRIVER_VERSION 0x2000
+#define SYNAPTICS_MTK_DRIVER_VERSION 0x6043
+
+#include <linux/version.h>
+#ifdef CONFIG_HAS_EARLYSUSPEND
+#include <linux/earlysuspend.h>
+#endif
+
+#ifdef CONFIG_OF
+#define CONFIG_OF_TOUCH
+#endif
+
+
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 38))
+#define KERNEL_ABOVE_2_6_38
+#endif
+
+#ifdef KERNEL_ABOVE_2_6_38
+#define sstrtoul(...) kstrtoul(__VA_ARGS__)
+#else
+#define sstrtoul(...) strict_strtoul(__VA_ARGS__)
+#endif
+
+#define WRITE_SIZE_LIMIT 1024
+
+extern unsigned char g_log_enable;
+#define TP_DEBUG(fmt, arg...) do {\
+ if (g_log_enable)\
+ printk("%s %d " fmt, __func__, __LINE__, ##arg);\
+ } while (0)
+#define PDT_PROPS (0X00EF)
+#define PDT_START (0x00E9)
+#define PDT_END (0x00D0)
+#define PDT_ENTRY_SIZE (0x0006)
+#define PAGES_TO_SERVICE (10)
+#define PAGE_SELECT_LEN (2)
+#define ADDRESS_WORD_LEN (2)
+
+#define SYNAPTICS_RMI4_F01 (0x01)
+#define SYNAPTICS_RMI4_F11 (0x11)
+#define SYNAPTICS_RMI4_F12 (0x12)
+#define SYNAPTICS_RMI4_F1A (0x1a)
+#define SYNAPTICS_RMI4_F34 (0x34)
+#define SYNAPTICS_RMI4_F35 (0x35)
+#define SYNAPTICS_RMI4_F38 (0x38)
+#define SYNAPTICS_RMI4_F51 (0x51)
+#define SYNAPTICS_RMI4_F54 (0x54)
+#define SYNAPTICS_RMI4_F55 (0x55)
+#define SYNAPTICS_RMI4_FDB (0xdb)
+
+#define SYNAPTICS_RMI4_DATE_CODE_SIZE 3
+#define PRODUCT_INFO_SIZE 2
+#define PRODUCT_ID_SIZE 10
+#define BUILD_ID_SIZE 3
+
+#define F12_FINGERS_TO_SUPPORT 10
+#define F12_NO_OBJECT_STATUS 0x00
+#define F12_FINGER_STATUS 0x01
+#define F12_STYLUS_STATUS 0x02
+#define F12_PALM_STATUS 0x03
+#define F12_HOVERING_FINGER_STATUS 0x05
+#define F12_GLOVED_FINGER_STATUS 0x06
+
+#define F12_GESTURE_DETECTION_LEN 5
+
+
+#define MAX_NUMBER_OF_BUTTONS 4
+#define MAX_INTR_REGISTERS 4
+
+#define MASK_16BIT 0xFFFF
+#define MASK_8BIT 0xFF
+#define MASK_7BIT 0x7F
+#define MASK_6BIT 0x3F
+#define MASK_5BIT 0x1F
+#define MASK_4BIT 0x0F
+#define MASK_3BIT 0x07
+#define MASK_2BIT 0x03
+#define MASK_1BIT 0x01
+
+enum exp_fn {
+ RMI_DEV = 0,
+ RMI_F54,
+ RMI_FW_UPDATER,
+ RMI_PROXIMITY,
+ RMI_ACTIVE_PEN,
+ RMI_GESTURE,
+ RMI_LAST,
+};
+
+/*
+ * struct synaptics_rmi4_fn_desc - function descriptor fields in PDT entry
+ * @query_base_addr: base address for query registers
+ * @cmd_base_addr: base address for command registers
+ * @ctrl_base_addr: base address for control registers
+ * @data_base_addr: base address for data registers
+ * @intr_src_count: number of interrupt sources
+ * @fn_version: version of function
+ * @fn_number: function number
+ */
+struct synaptics_rmi4_fn_desc {
+ union {
+ struct {
+ unsigned char query_base_addr;
+ unsigned char cmd_base_addr;
+ unsigned char ctrl_base_addr;
+ unsigned char data_base_addr;
+ unsigned char intr_src_count:3;
+ unsigned char reserved_1:2;
+ unsigned char fn_version:2;
+ unsigned char reserved_2:1;
+ unsigned char fn_number;
+ } __packed;
+ unsigned char data[6];
+ };
+};
+
+/*
+ * synaptics_rmi4_fn_full_addr - full 16-bit base addresses
+ * @query_base: 16-bit base address for query registers
+ * @cmd_base: 16-bit base address for command registers
+ * @ctrl_base: 16-bit base address for control registers
+ * @data_base: 16-bit base address for data registers
+ */
+struct synaptics_rmi4_fn_full_addr {
+ unsigned short query_base;
+ unsigned short cmd_base;
+ unsigned short ctrl_base;
+ unsigned short data_base;
+};
+
+/*
+ * struct synaptics_rmi4_f11_extra_data - extra data of F$11
+ * @data38_offset: offset to F11_2D_DATA38 register
+ */
+struct synaptics_rmi4_f11_extra_data {
+ unsigned char data38_offset;
+};
+
+/*
+ * struct synaptics_rmi4_f12_extra_data - extra data of F$12
+ * @data1_offset: offset to F12_2D_DATA01 register
+ * @data4_offset: offset to F12_2D_DATA04 register
+ * @data15_offset: offset to F12_2D_DATA15 register
+ * @data15_size: size of F12_2D_DATA15 register
+ * @data15_data: buffer for reading F12_2D_DATA15 register
+ * @ctrl20_offset: offset to F12_2D_CTRL20 register
+ */
+struct synaptics_rmi4_f12_extra_data {
+ unsigned char data1_offset;
+ unsigned char data4_offset;
+ unsigned char data15_offset;
+ unsigned char data15_size;
+ unsigned char data15_data[(F12_FINGERS_TO_SUPPORT + 7) / 8];
+ unsigned char ctrl20_offset;
+ unsigned char ctrl27_offset;
+};
+
+/*
+ * struct synaptics_rmi4_fn - RMI function handler
+ * @fn_number: function number
+ * @num_of_data_sources: number of data sources
+ * @num_of_data_points: maximum number of fingers supported
+ * @intr_reg_num: index to associated interrupt register
+ * @intr_mask: interrupt mask
+ * @full_addr: full 16-bit base addresses of function registers
+ * @link: linked list for function handlers
+ * @data_size: size of private data
+ * @data: pointer to private data
+ * @extra: pointer to extra data
+ */
+struct synaptics_rmi4_fn {
+ unsigned char fn_number;
+ unsigned char num_of_data_sources;
+ unsigned char num_of_data_points;
+ unsigned char intr_reg_num;
+ unsigned char intr_mask;
+ struct synaptics_rmi4_fn_full_addr full_addr;
+ struct list_head link;
+ int data_size;
+ void *data;
+ void *extra;
+};
+
+/*
+ * struct synaptics_rmi4_device_info - device information
+ * @version_major: RMI protocol major version number
+ * @version_minor: RMI protocol minor version number
+ * @manufacturer_id: manufacturer ID
+ * @product_props: product properties
+ * @product_info: product information
+ * @product_id_string: product ID
+ * @build_id: firmware build ID
+ * @support_fn_list: linked list for function handlers
+ */
+struct synaptics_rmi4_device_info {
+ unsigned int version_major;
+ unsigned int version_minor;
+ unsigned char manufacturer_id;
+ unsigned char product_props;
+ unsigned char product_info[PRODUCT_INFO_SIZE];
+ unsigned char date_code[SYNAPTICS_RMI4_DATE_CODE_SIZE];
+ unsigned short tester_id;
+ unsigned short serial_number;
+ unsigned char product_id_string[PRODUCT_ID_SIZE + 1];
+ unsigned char build_id[BUILD_ID_SIZE];
+ struct list_head support_fn_list;
+};
+
+/*
+ * struct synaptics_rmi4_data - rmi4 device instance data
+ * @i2c_client: pointer to associated i2c client
+ * @input_dev: pointer to associated input device
+ * @board: constant pointer to platform data
+ * @rmi4_mod_info: device information
+ * @regulator: pointer to associated regulator
+ * @rmi4_io_ctrl_mutex: mutex for i2c i/o control
+ * @early_suspend: instance to support early suspend power management
+ * @current_page: current page in sensor to access
+ * @button_0d_enabled: flag for 0d button support
+ * @full_pm_cycle: flag for full power management cycle in early suspend stage
+ * @num_of_intr_regs: number of interrupt registers
+ * @f01_query_base_addr: query base address for f01
+ * @f01_cmd_base_addr: command base address for f01
+ * @f01_ctrl_base_addr: control base address for f01
+ * @f01_data_base_addr: data base address for f01
+ * @irq: attention interrupt
+ * @sensor_max_x: sensor maximum x value
+ * @sensor_max_y: sensor maximum y value
+ * @irq_enabled: flag for indicating interrupt enable status
+ * @fingers_on_2d: flag to indicate presence of fingers in 2d area
+ * @sensor_sleep: flag to indicate sleep state of sensor
+ * @wait: wait queue for touch data polling in interrupt thread
+ * @i2c_read: pointer to i2c read function
+ * @i2c_write: pointer to i2c write function
+ * @irq_enable: pointer to irq enable function
+ */
+struct synaptics_rmi4_data {
+ struct i2c_client *i2c_client;
+ struct input_dev *input_dev;
+ const struct synaptics_dsx_platform_data *board;
+ struct synaptics_rmi4_device_info rmi4_mod_info;
+ struct regulator *regulator;
+ struct mutex rmi4_reset_mutex;
+ struct mutex rmi4_io_ctrl_mutex;
+ struct mutex rmi4_exp_init_mutex;
+#ifdef CONFIG_HAS_EARLYSUSPEND
+ struct early_suspend early_suspend;
+#endif
+ unsigned char i2c_addr;
+ unsigned char current_page;
+ unsigned char button_0d_enabled;
+ unsigned char full_pm_cycle;
+ unsigned char num_of_rx;
+ unsigned char num_of_tx;
+ unsigned char num_of_fingers;
+ unsigned char max_touch_width;
+ unsigned char report_enable;
+ unsigned char no_sleep_setting;
+ unsigned char intr_mask[MAX_INTR_REGISTERS];
+ unsigned char *button_txrx_mapping;
+ unsigned short num_of_intr_regs;
+ unsigned short f01_query_base_addr;
+ unsigned short f01_cmd_base_addr;
+ unsigned short f01_ctrl_base_addr;
+ unsigned short f01_data_base_addr;
+ unsigned int firmware_id;
+ unsigned int config_id;
+ int irq;
+ int sensor_max_x;
+ int sensor_max_y;
+ bool diagonal_rotation;
+ bool flash_prog_mode;
+ bool irq_enabled;
+ bool touch_stopped;
+ bool fingers_on_2d;
+ bool sensor_sleep;
+ bool stay_awake;
+ bool f11_wakeup_gesture;
+ bool f12_wakeup_gesture;
+ bool enable_wakeup_gesture;
+ bool staying_awake;
+ bool ext_afe_button;
+ unsigned char gesture_detection[F12_GESTURE_DETECTION_LEN];
+ int (*i2c_read)(struct synaptics_rmi4_data *pdata, unsigned short addr,
+ unsigned char *data, unsigned short length);
+ int (*i2c_write)(struct synaptics_rmi4_data *pdata, unsigned short addr,
+ unsigned char *data, unsigned short length);
+ int (*irq_enable)(struct synaptics_rmi4_data *rmi4_data, bool enable);
+ int (*reset_device)(struct synaptics_rmi4_data *rmi4_data);
+ void (*sleep_enable)(struct synaptics_rmi4_data *rmi4_data,
+ bool enable);
+};
+
+struct synaptics_rmi4_exp_fn {
+ enum exp_fn fn_type;
+ int (*init)(struct synaptics_rmi4_data *rmi4_data);
+ void (*remove)(struct synaptics_rmi4_data *rmi4_data);
+ void (*reset)(struct synaptics_rmi4_data *rmi4_data);
+ void (*reinit)(struct synaptics_rmi4_data *rmi4_data);
+ void (*early_suspend)(struct synaptics_rmi4_data *rmi4_data);
+ void (*suspend)(struct synaptics_rmi4_data *rmi4_data);
+ void (*resume)(struct synaptics_rmi4_data *rmi4_data);
+ void (*late_resume)(struct synaptics_rmi4_data *rmi4_data);
+ void (*attn)(struct synaptics_rmi4_data *rmi4_data,
+ unsigned char intr_mask);
+};
+
+struct synaptics_rmi4_access_ptr {
+ int (*read)(struct synaptics_rmi4_data *rmi4_data, unsigned short addr,
+ unsigned char *data, unsigned short length);
+ int (*write)(struct synaptics_rmi4_data *rmi4_data, unsigned short addr,
+ unsigned char *data, unsigned short length);
+ int (*enable)(struct synaptics_rmi4_data *rmi4_data, bool enable);
+};
+
+static inline int synaptics_rmi4_reg_read(
+ struct synaptics_rmi4_data *rmi4_data,
+ unsigned short addr,
+ unsigned char *data,
+ unsigned short len)
+{
+ return rmi4_data->i2c_read(rmi4_data, addr, data, len);
+}
+
+static inline int synaptics_rmi4_reg_write(
+ struct synaptics_rmi4_data *rmi4_data,
+ unsigned short addr,
+ unsigned char *data,
+ unsigned short len)
+{
+ return rmi4_data->i2c_write(rmi4_data, addr, data, len);
+}
+
+
+
+void synaptics_rmi4_new_function(struct synaptics_rmi4_exp_fn *exp_fn_module,
+ bool insert);
+
+int synaptics_fw_updater(const unsigned char *fw_data);
+
+static inline ssize_t synaptics_rmi4_show_error(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ dev_warn(dev, "%s Attempted to read from write-only attribute %s\n",
+ __func__, attr->attr.name);
+ return -EPERM;
+}
+
+static inline ssize_t synaptics_rmi4_store_error(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ dev_warn(dev, "%s Attempted to write to read-only attribute %s\n",
+ __func__, attr->attr.name);
+ return -EPERM;
+}
+
+static inline int secure_memcpy(unsigned char *dest, unsigned int dest_size,
+ const unsigned char *src, unsigned int src_size,
+ unsigned int count)
+{
+ if (dest == NULL || src == NULL)
+ return -EINVAL;
+
+ if (count > dest_size || count > src_size)
+ return -EINVAL;
+
+ memcpy((void *)dest, (const void *)src, count);
+
+ return 0;
+}
+
+static inline void batohs(unsigned short *dest, unsigned char *src)
+{
+ *dest = src[1] * 0x100 + src[0];
+}
+
+static inline void hstoba(unsigned char *dest, unsigned short src)
+{
+ dest[0] = src % 0x100;
+ dest[1] = src / 0x100;
+}
+
+#endif
diff --git a/drivers/input/touchscreen/vtl/Makefile b/drivers/input/touchscreen/vtl/Makefile
new file mode 100644
index 000000000000..2ee7f7aefe43
--- /dev/null
+++ b/drivers/input/touchscreen/vtl/Makefile
@@ -0,0 +1,5 @@
+#
+# Makefile for the VTL touchscreen driver.
+#
+
+obj-y += vtl_ts.o
diff --git a/drivers/input/touchscreen/vtl/vtl_ts.c b/drivers/input/touchscreen/vtl/vtl_ts.c
new file mode 100644
index 000000000000..f7bef9e81158
--- /dev/null
+++ b/drivers/input/touchscreen/vtl/vtl_ts.c
@@ -0,0 +1,496 @@
+/*
+ * VTL CTP driver
+ *
+ * Copyright (C) 2013 VTL Corporation
+ * Copyright (C) 2016 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.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/version.h>
+#include <linux/fs.h>
+#include <linux/proc_fs.h>
+#include <linux/uaccess.h>
+#include <linux/i2c.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/input.h>
+#include <linux/input/mt.h>
+#include <linux/gpio.h>
+#include <linux/of.h>
+#include <linux/of_gpio.h>
+#include <linux/pm_qos.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+
+#define FORCE_SINGLE_EVENT 1
+
+#include "vtl_ts.h"
+
+#define MIN_X 0x00
+#define MIN_Y 0x00
+#define MAX_X 1023
+#define MAX_Y 767
+#define MAX_AREA 0xff
+#define MAX_FINGERS 2
+
+
+/* Global or static variables */
+struct ts_driver g_driver;
+
+static struct ts_info g_ts = {
+ .driver = &g_driver,
+};
+static struct ts_info *pg_ts = &g_ts;
+
+static struct i2c_device_id vtl_ts_id[] = {
+ { DRIVER_NAME, 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, vtl_ts_id);
+
+
+static int vtl_ts_config(struct ts_info *ts)
+{
+ struct device *dev;
+
+ DEBUG();
+
+ dev = &ts->driver->client->dev;
+
+ /* ts config */
+ ts->config_info.touch_point_number = TOUCH_POINT_NUM;
+
+ pr_info("Configuring vtl\n");
+ ts->config_info.screen_max_x = SCREEN_MAX_X;
+ ts->config_info.screen_max_y = SCREEN_MAX_y;
+ return 0;
+}
+
+void vtl_ts_free_gpio(void)
+{
+ struct ts_info *ts;
+
+ ts = pg_ts;
+ DEBUG();
+
+ gpio_free(ts->config_info.irq_gpio_number);
+}
+
+void vtl_ts_hw_reset(void)
+{
+ struct ts_info *ts;
+
+ ts = pg_ts;
+ DEBUG();
+
+ gpio_set_value(ts->config_info.rst_gpio_number, 0);
+ mdelay(50);
+ gpio_set_value(ts->config_info.rst_gpio_number, 1);
+}
+
+static irqreturn_t vtl_ts_irq(int irq, void *dev)
+{
+ struct ts_info *ts;
+
+ ts = pg_ts;
+ DEBUG();
+
+ queue_work(ts->driver->workqueue, &ts->driver->event_work);
+
+ return IRQ_HANDLED;
+}
+
+static union ts_xy_data *vtl_read_xy_data(struct ts_info *ts)
+{
+ struct i2c_msg msgs;
+ int err;
+
+ DEBUG();
+
+ msgs.addr = ts->driver->client->addr;
+ msgs.flags = 0x01;
+ msgs.len = sizeof(ts->xy_data.buf);
+ msgs.buf = ts->xy_data.buf;
+
+ err = i2c_transfer(ts->driver->client->adapter, &msgs, 1);
+ if (err != 1) {
+ pr_err("___%s:i2c read err___\n", __func__);
+ return NULL;
+ }
+ return &ts->xy_data;
+}
+
+static void vtl_report_xy_coord(struct input_dev *input_dev,
+ union ts_xy_data *xy_data,
+ unsigned char touch_point_number)
+{
+ struct ts_info *ts;
+ int id;
+ int sync;
+ int x, y;
+ unsigned int press;
+ static unsigned int release;
+
+ ts = pg_ts;
+ DEBUG();
+
+ /* report points */
+ sync = 0; press = 0;
+ for (id = 0; id < touch_point_number; id++) {
+ if ((xy_data->point[id].xhi != 0xFF) &&
+ (xy_data->point[id].yhi != 0xFF) &&
+ ((xy_data->point[id].status == 1) ||
+ (xy_data->point[id].status == 2))) {
+ x = (xy_data->point[id].xhi<<4) |
+ (xy_data->point[id].xlo&0xF);
+ y = (xy_data->point[id].yhi<<4) |
+ (xy_data->point[id].ylo&0xF);
+
+ if (ts->config_info.exchange_x_y_flag)
+ swap(x, y);
+
+ if (ts->config_info.revert_x_flag)
+ x = ts->config_info.screen_max_x - x;
+
+ if (ts->config_info.revert_y_flag)
+ y = ts->config_info.screen_max_y - y;
+#ifndef FORCE_SINGLE_EVENT
+ input_mt_slot(input_dev, xy_data->point[id].id - 1);
+ input_mt_report_slot_state(input_dev,
+ MT_TOOL_FINGER, true);
+ input_report_abs(input_dev, ABS_MT_POSITION_X, x);
+ input_report_abs(input_dev, ABS_MT_POSITION_Y, y);
+ input_report_abs(input_dev, ABS_MT_TOUCH_MAJOR, 30);
+ input_report_abs(input_dev, ABS_MT_WIDTH_MAJOR, 128);
+#else
+ input_report_abs(input_dev, ABS_X, x);
+ input_report_abs(input_dev, ABS_Y, y);
+ input_report_key(input_dev, BTN_TOUCH, 1);
+ input_report_abs(input_dev, ABS_PRESSURE, 1);
+#endif
+ sync = 1;
+ press |= 0x01 << (xy_data->point[id].id - 1);
+ }
+ }
+
+ release &= (release ^ press); /*release point flag */
+ for (id = 0; id < touch_point_number; id++) {
+ if (release & (0x01 << id)) {
+#ifndef FORCE_SINGLE_EVENT
+ input_mt_slot(input_dev, id);
+ input_mt_report_slot_state(input_dev,
+ MT_TOOL_FINGER, false);
+#else
+ input_report_key(input_dev, BTN_TOUCH, 0);
+ input_report_abs(input_dev, ABS_PRESSURE, 0);
+#endif
+ sync = 1;
+ }
+
+ }
+ release = press;
+
+ if (sync)
+ input_sync(input_dev);
+}
+
+static void vtl_ts_workfunc(struct work_struct *work)
+{
+
+ union ts_xy_data *xy_data;
+ struct input_dev *input_dev;
+ unsigned char touch_point_number;
+
+ DEBUG();
+
+ input_dev = pg_ts->driver->input_dev;
+ touch_point_number = pg_ts->config_info.touch_point_number;
+
+ xy_data = vtl_read_xy_data(pg_ts);
+ if (xy_data != NULL)
+ vtl_report_xy_coord(input_dev, xy_data, touch_point_number);
+ else
+ pr_err("____xy_data error___\n");
+}
+
+#ifdef CONFIG_PM_SLEEP
+int vtl_ts_suspend(struct device *dev)
+{
+ struct ts_info *ts;
+
+ ts = pg_ts;
+ DEBUG();
+
+ disable_irq(ts->config_info.irq_number);
+ cancel_work_sync(&ts->driver->event_work);
+
+ return 0;
+}
+
+int vtl_ts_resume(struct device *dev)
+{
+ struct ts_info *ts;
+
+ ts = pg_ts;
+ DEBUG();
+
+ /* Hardware reset */
+ vtl_ts_hw_reset();
+ enable_irq(ts->config_info.irq_number);
+
+ return 0;
+}
+#endif
+
+#ifdef CONFIG_HAS_EARLYSUSPEND
+static void vtl_ts_early_suspend(struct early_suspend *handler)
+{
+ struct ts_info *ts;
+
+ ts = pg_ts;
+ DEBUG();
+
+ vtl_ts_suspend(ts->driver->client, PMSG_SUSPEND);
+}
+
+static void vtl_ts_early_resume(struct early_suspend *handler)
+{
+ struct ts_info *ts;
+
+ ts = pg_ts;
+ DEBUG();
+
+ vtl_ts_resume(ts->driver->client);
+}
+#endif
+
+int vtl_ts_remove(struct i2c_client *client)
+{
+ struct ts_info *ts;
+
+ ts = pg_ts;
+ DEBUG();
+
+ /* Driver clean up */
+
+ free_irq(ts->config_info.irq_number, ts);
+ vtl_ts_free_gpio();
+
+#ifdef CONFIG_HAS_EARLYSUSPEND
+ unregister_early_suspend(&ts->driver->early_suspend);
+#endif
+
+ cancel_work_sync(&ts->driver->event_work);
+ destroy_workqueue(ts->driver->workqueue);
+
+ input_unregister_device(ts->driver->input_dev);
+ input_free_device(ts->driver->input_dev);
+
+ if (ts->driver->proc_entry != NULL)
+ remove_proc_entry(DRIVER_NAME, NULL);
+
+ return 0;
+}
+
+static int init_input_dev(struct ts_info *ts)
+{
+ struct input_dev *input_dev;
+ struct device *dev;
+ int err;
+
+ DEBUG();
+
+ dev = &ts->driver->client->dev;
+
+ /* allocate input device */
+ ts->driver->input_dev = devm_input_allocate_device(dev);
+ if (ts->driver->input_dev == NULL) {
+ dev_err(dev, "Unable to allocate input device for device %s\n",
+ DRIVER_NAME);
+ return -1;
+ }
+
+ input_dev = ts->driver->input_dev;
+
+ input_dev->name = "VTL for wld";
+ input_dev->phys = "I2C";
+ input_dev->id.bustype = BUS_I2C;
+ input_dev->id.vendor = 0xaaaa;
+ input_dev->id.product = 0x5555;
+ input_dev->id.version = 0x0001;
+ input_dev->dev.parent = dev;
+
+ /* config input device */
+ __set_bit(EV_SYN, input_dev->evbit);
+ __set_bit(EV_KEY, input_dev->evbit);
+ __set_bit(EV_ABS, input_dev->evbit);
+
+#ifdef FORCE_SINGLE_EVENT
+ input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
+ input_set_abs_params(input_dev, ABS_PRESSURE, 0, 1, 0, 0);
+ input_set_abs_params(input_dev, ABS_X, MIN_X, MAX_X, 0, 0);
+ input_set_abs_params(input_dev, ABS_Y, MIN_Y, MAX_Y, 0, 0);
+#else
+ __set_bit(INPUT_PROP_DIRECT, input_dev->propbit);
+
+ input_mt_init_slots(input_dev, TOUCH_POINT_NUM, 0);
+ input_set_abs_params(input_dev, ABS_MT_POSITION_X, 0,
+ ts->config_info.screen_max_x, 0, 0);
+ input_set_abs_params(input_dev, ABS_MT_POSITION_Y, 0,
+ ts->config_info.screen_max_y, 0, 0);
+ input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0);
+ input_set_abs_params(input_dev, ABS_MT_WIDTH_MAJOR, 0, 255, 0, 0);
+#endif
+ /* register input device */
+ err = input_register_device(input_dev);
+ if (err) {
+ dev_err(dev, "Unable to register input device for device %s\n",
+ DRIVER_NAME);
+ return -1;
+ }
+
+ return 0;
+}
+
+int ct36x_test_tp(struct i2c_client *client)
+{
+ struct i2c_msg msgs;
+ char buf;
+
+ msgs.addr = 0x7F;
+ msgs.flags = 0x01;
+ msgs.len = 1;
+ msgs.buf = &buf;
+
+ if (i2c_transfer(client->adapter, &msgs, 1) != 1)
+ return -1;
+
+ return 0;
+}
+
+int vtl_ts_probe(struct i2c_client *client, const struct i2c_device_id *id)
+{
+ int err = -1;
+ struct ts_info *ts;
+ struct device *dev;
+
+ ts = pg_ts;
+ ts->driver->client = client;
+ dev = &ts->driver->client->dev;
+
+ /*Probing TouchScreen*/
+ pr_info("Probing vtl touchscreen, touchscreen node found\n");
+ if (ct36x_test_tp(client) < 0) {
+ pr_err("vtl tp not found\n");
+ goto ERR_TS_CONFIG;
+ }
+
+ /* Request platform resources (gpio/interrupt pins) */
+ err = vtl_ts_config(ts);
+ if (err) {
+ dev_err(dev, "VTL touch screen config Failed.\n");
+ goto ERR_TS_CONFIG;
+ }
+
+ /*Requestion GPIO*/
+ ts->config_info.rst_gpio_number = of_get_gpio(client->dev.of_node, 0);
+ if (gpio_is_valid(ts->config_info.rst_gpio_number)) {
+ err = devm_gpio_request(dev,
+ ts->config_info.rst_gpio_number, NULL);
+ if (err) {
+ dev_err(dev, "Unable to request GPIO %d\n",
+ ts->config_info.rst_gpio_number);
+ return err;
+ }
+ }
+
+ /* Check I2C Functionality */
+ err = i2c_check_functionality(client->adapter, I2C_FUNC_I2C);
+ if (!err) {
+ dev_err(dev, "Check I2C Functionality Failed.\n");
+ return -ENODEV;
+ }
+
+ err = devm_request_threaded_irq(dev, client->irq,
+ NULL, vtl_ts_irq,
+ IRQF_ONESHOT,
+ client->name, ts);
+ if (err) {
+ dev_err(&client->dev, "VTL Failed to register interrupt\n");
+
+ goto ERR_IRQ_REQ;
+ }
+
+ vtl_ts_hw_reset();
+
+ /*init input dev*/
+ err = init_input_dev(ts);
+ if (err) {
+
+ dev_err(dev, "init input dev failed.\n");
+ goto ERR_INIT_INPUT;
+ }
+
+ /* register early suspend */
+#ifdef CONFIG_HAS_EARLYSUSPEND
+ ts->driver->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1;
+ ts->driver->early_suspend.suspend = vtl_ts_early_suspend;
+ ts->driver->early_suspend.resume = vtl_ts_early_resume;
+ register_early_suspend(&ts->driver->early_suspend);
+#endif
+ /* Create work queue */
+ INIT_WORK(&ts->driver->event_work, vtl_ts_workfunc);
+ ts->driver->workqueue = create_singlethread_workqueue(DRIVER_NAME);
+
+ return 0;
+
+ERR_IRQ_REQ:
+ cancel_work_sync(&ts->driver->event_work);
+ destroy_workqueue(ts->driver->workqueue);
+
+ERR_INIT_INPUT:
+ input_free_device(ts->driver->input_dev);
+ gpio_free(ts->config_info.rst_gpio_number);
+ERR_TS_CONFIG:
+
+ return err;
+}
+
+
+static SIMPLE_DEV_PM_OPS(vtl_ts_pm_ops, vtl_ts_suspend, vtl_ts_resume);
+
+static const struct of_device_id vtl_ts_dt_ids[] = {
+ { .compatible = "vtl,ct365", },
+ { }
+};
+MODULE_DEVICE_TABLE(of, vtl_ts_dt_ids);
+
+
+static struct i2c_driver vtl_ts_driver = {
+ .probe = vtl_ts_probe,
+ .remove = vtl_ts_remove,
+ .id_table = vtl_ts_id,
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = DRIVER_NAME,
+ .pm = &vtl_ts_pm_ops,
+ .of_match_table = of_match_ptr(vtl_ts_dt_ids),
+ },
+};
+
+module_i2c_driver(vtl_ts_driver);
+
+MODULE_AUTHOR("VTL");
+MODULE_DESCRIPTION("VTL TouchScreen driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/input/touchscreen/vtl/vtl_ts.h b/drivers/input/touchscreen/vtl/vtl_ts.h
new file mode 100644
index 000000000000..9f61565d6639
--- /dev/null
+++ b/drivers/input/touchscreen/vtl/vtl_ts.h
@@ -0,0 +1,181 @@
+/*
+ * VTL CTP driver
+ *
+ * Copyright (C) 2016 Freescale Semiconductor, Inc
+ *
+ * Using code from:
+ * - github.com/qdk0901/q98_source:drivers/input/touchscreen/vtl/vtl_ts.h
+ *
+ * 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.
+ *
+ */
+
+#ifndef _TS_CORE_H_
+#define _TS_CORE_H_
+
+#include <linux/gpio.h>
+#ifdef CONFIG_HAS_EARLYSUSPEND
+#include <linux/earlysuspend.h>
+#endif
+
+
+#ifdef TS_DEBUG
+#define DEBUG() pr_debug("___%s___\n", __func__)
+#else
+#define DEBUG()
+#endif
+
+
+/* platform define */
+#define COMMON 0x01 /* Samsung,Freescale,Amlogic,actions */
+#define ROCKCHIP 0X02
+#define ALLWINER 0X03
+#define MTK 0X04
+
+/* vtl touch IC define */
+#define CT36X 0x01
+#define CT360 0x02
+
+/* xy data protocol */
+#define OLD_PROTOCOL 0x01
+#define NEW_PROTOCOL 0x02
+
+
+/* vtl ts driver config */
+
+/*platform config*/
+#define PLATFORM COMMON
+
+/*vtl ts driver name*/
+#define DRIVER_NAME "vtl_ts"
+
+/*vtl chip ID*/
+#define CHIP_ID CT36X
+
+#define XY_DATA_PROTOCOL NEW_PROTOCOL
+
+
+/* maybe not use,please refer to the function
+ * vtl_ts_config() in the file "vtl_ts.c"
+ */
+#define SCREEN_MAX_X 1024
+#define SCREEN_MAX_y 600
+
+#define TS_IRQ_GPIO_NUM /* RK30_PIN4_PC2 */
+#define TS_RST_GPIO_NUM /* RK30_PIN4_PD0 */
+#define TS_I2C_SPEED 400000 /* for rockchip */
+
+
+/* priate define and declare */
+#if (CHIP_ID == CT360)
+#define TOUCH_POINT_NUM 1
+#elif (CHIP_ID == CT36X)
+#define TOUCH_POINT_NUM 1
+#endif
+
+
+#if (CHIP_ID == CT360)
+struct xy_data {
+#if (XY_DATA_PROTOCOL == OLD_PROTOCOL)
+ unsigned char status:4; /* Action information, 1:Down;
+ 2: Move; 3: Up */
+ unsigned char id:4; /* ID information, from 1 to
+ CFG_MAX_POINT_NUM */
+#endif
+ unsigned char xhi; /* X coordinate Hi */
+ unsigned char yhi; /* Y coordinate Hi */
+ unsigned char ylo:4; /* Y coordinate Lo */
+ unsigned char xlo:4; /* X coordinate Lo */
+#if (XY_DATA_PROTOCOL == NEW_PROTOCOL)
+ unsigned char status:4; /* Action information, 1: Down;
+ 2: Move; 3: Up */
+ unsigned char id:4; /* ID information, from 1 to
+ CFG_MAX_POINT_NUM */
+#endif
+};
+#else
+struct xy_data {
+#if (XY_DATA_PROTOCOL == OLD_PROTOCOL)
+ unsigned char status:3; /* Action information, 1: Down;
+ 2: Move; 3: Up */
+ unsigned char id:5; /* ID information, from 1 to
+ CFG_MAX_POINT_NUM */
+#endif
+ unsigned char xhi; /* X coordinate Hi */
+ unsigned char yhi; /* Y coordinate Hi */
+ unsigned char ylo:4; /* Y coordinate Lo */
+ unsigned char xlo:4; /* X coordinate Lo */
+#if (XY_DATA_PROTOCOL == NEW_PROTOCOL)
+ unsigned char status:3; /* Action information, 1: Down;
+ 2: Move; 3: Up */
+ unsigned char id:5; /* ID information, from 1 to
+ CFG_MAX_POINT_NUM */
+#endif
+ unsigned char area; /* Touch area */
+ unsigned char pressure; /* Touch Pressure */
+};
+#endif
+
+
+union ts_xy_data {
+ struct xy_data point[TOUCH_POINT_NUM];
+ unsigned char buf[TOUCH_POINT_NUM * sizeof(struct xy_data)];
+};
+
+
+struct ts_driver {
+
+ struct i2c_client *client;
+
+ /* input devices */
+ struct input_dev *input_dev;
+
+ struct proc_dir_entry *proc_entry;
+
+ /* Work thread settings */
+ struct work_struct event_work;
+ struct workqueue_struct *workqueue;
+
+#ifdef CONFIG_HAS_EARLYSUSPEND
+ struct early_suspend early_suspend;
+#endif
+};
+
+struct ts_config_info {
+
+ unsigned int screen_max_x;
+ unsigned int screen_max_y;
+ unsigned int irq_gpio_number;
+ unsigned int irq_number;
+ unsigned int rst_gpio_number;
+ unsigned char touch_point_number;
+ unsigned char ctp_used;
+ unsigned char i2c_bus_number;
+ unsigned char revert_x_flag;
+ unsigned char revert_y_flag;
+ unsigned char exchange_x_y_flag;
+ int (*tp_enter_init)(void);
+ void (*tp_exit_init)(int state);
+};
+
+
+struct ts_chip_info {
+ unsigned char chip_id;
+};
+
+struct ts_info {
+
+ struct ts_driver *driver;
+ struct ts_config_info config_info;
+ struct ts_chip_info chip_info;
+ union ts_xy_data xy_data;
+};
+
+#endif
diff --git a/drivers/iommu/io-pgtable-arm.c b/drivers/iommu/io-pgtable-arm.c
index 17a9225283dd..a8c9da60d7c8 100644
--- a/drivers/iommu/io-pgtable-arm.c
+++ b/drivers/iommu/io-pgtable-arm.c
@@ -14,6 +14,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* Copyright (C) 2014 ARM Limited
+ * Copyright 2017 NXP
*
* Author: Will Deacon <will.deacon@arm.com>
*/
@@ -215,7 +216,7 @@ static void *__arm_lpae_alloc_pages(size_t size, gfp_t gfp,
{
struct device *dev = cfg->iommu_dev;
dma_addr_t dma;
- void *pages = alloc_pages_exact(size, gfp | __GFP_ZERO);
+ void *pages = alloc_pages_exact(size, gfp | __GFP_ZERO | __GFP_DMA);
if (!pages)
return NULL;
diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
index 9d8a1dd2e2c2..2df72036f1ef 100644
--- a/drivers/irqchip/Kconfig
+++ b/drivers/irqchip/Kconfig
@@ -269,6 +269,18 @@ config IMX_GPCV2
help
Enables the wakeup IRQs for IMX platforms with GPCv2 block
+config IMX_IRQSTEER
+ def_bool y if ARCH_MXC_ARM64
+ select IRQ_DOMAIN
+ help
+ Enables the IRQ Steer for NXP IMX platforms
+
+config IMX_INTMUX
+ def_bool y if ARCH_MXC_ARM64
+ select IRQ_DOMAIN
+ help
+ Enables the IRQ MUX for NXP IMX platforms
+
config IRQ_MXS
def_bool y if MACH_ASM9260 || ARCH_MXS
select IRQ_DOMAIN
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index b842dfdc903f..5bd184abaed1 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -69,6 +69,8 @@ obj-$(CONFIG_RENESAS_H8S_INTC) += irq-renesas-h8s.o
obj-$(CONFIG_ARCH_SA1100) += irq-sa11x0.o
obj-$(CONFIG_INGENIC_IRQ) += irq-ingenic.o
obj-$(CONFIG_IMX_GPCV2) += irq-imx-gpcv2.o
+obj-$(CONFIG_IMX_IRQSTEER) += irq-imx-irqsteer.o
+obj-$(CONFIG_IMX_INTMUX) += irq-imx-intmux.o
obj-$(CONFIG_PIC32_EVIC) += irq-pic32-evic.o
obj-$(CONFIG_MVEBU_GICP) += irq-mvebu-gicp.o
obj-$(CONFIG_MVEBU_ICU) += irq-mvebu-icu.o
diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
index 3d7374655587..9fe8fc032e99 100644
--- a/drivers/irqchip/irq-gic-v3.c
+++ b/drivers/irqchip/irq-gic-v3.c
@@ -62,6 +62,8 @@ struct gic_chip_data {
static struct gic_chip_data gic_data __read_mostly;
static struct static_key supports_deactivate = STATIC_KEY_INIT_TRUE;
+static void __iomem *iomuxc_gpr_base;
+
static struct gic_kvm_info gic_v3_kvm_info;
#define gic_data_rdist() (this_cpu_ptr(gic_data.rdists.rdist))
@@ -652,6 +654,7 @@ static void gic_send_sgi(u64 cluster_id, u16 tlist, unsigned int irq)
static void gic_raise_softirq(const struct cpumask *mask, unsigned int irq)
{
int cpu;
+ u32 val;
if (WARN_ON(irq >= 16))
return;
@@ -668,8 +671,18 @@ static void gic_raise_softirq(const struct cpumask *mask, unsigned int irq)
tlist = gic_compute_target_list(&cpu, mask, cluster_id);
gic_send_sgi(cluster_id, tlist, irq);
- }
+ if (iomuxc_gpr_base) {
+ /* pending the IRQ32 to wakeup the core */
+ val = readl_relaxed(iomuxc_gpr_base + 0x4);
+ val |= (1 << 12);
+ writel_relaxed(val, iomuxc_gpr_base + 0x4);
+ /* delay for a while to make sure cores wakeup done */
+ udelay(50);
+ val &= ~(1 << 12);
+ writel_relaxed(val, iomuxc_gpr_base + 0x4);
+ }
+ }
/* Force the above writes to ICC_SGI1R_EL1 to be executed */
isb();
}
@@ -772,7 +785,9 @@ static struct irq_chip gic_chip = {
.irq_set_affinity = gic_set_affinity,
.irq_get_irqchip_state = gic_irq_get_irqchip_state,
.irq_set_irqchip_state = gic_irq_set_irqchip_state,
- .flags = IRQCHIP_SET_TYPE_MASKED,
+ .flags = IRQCHIP_SET_TYPE_MASKED |
+ IRQCHIP_SKIP_SET_WAKE |
+ IRQCHIP_MASK_ON_SUSPEND,
};
static struct irq_chip gic_eoimode1_chip = {
@@ -785,7 +800,9 @@ static struct irq_chip gic_eoimode1_chip = {
.irq_get_irqchip_state = gic_irq_get_irqchip_state,
.irq_set_irqchip_state = gic_irq_set_irqchip_state,
.irq_set_vcpu_affinity = gic_irq_set_vcpu_affinity,
- .flags = IRQCHIP_SET_TYPE_MASKED,
+ .flags = IRQCHIP_SET_TYPE_MASKED |
+ IRQCHIP_SKIP_SET_WAKE |
+ IRQCHIP_MASK_ON_SUSPEND,
};
#define GIC_ID_NR (1U << gic_data.rdists.id_bits)
@@ -1222,6 +1239,12 @@ static int __init gic_of_init(struct device_node *node, struct device_node *pare
rdist_regs[i].phys_base = res.start;
}
+ if (of_machine_is_compatible("fsl,imx8mq")) {
+ /* sw workaround for IPI can't wakeup CORE
+ ERRATA(ERR011171) on i.MX8MQ */
+ iomuxc_gpr_base = of_iomap(node, 2);
+ }
+
if (of_property_read_u64(node, "redistributor-stride", &redist_stride))
redist_stride = 0;
diff --git a/drivers/irqchip/irq-imx-intmux.c b/drivers/irqchip/irq-imx-intmux.c
new file mode 100644
index 000000000000..72959d096074
--- /dev/null
+++ b/drivers/irqchip/irq-imx-intmux.c
@@ -0,0 +1,237 @@
+/*
+ * Copyright 2017 NXP
+ *
+ * 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/module.h>
+#include <linux/clk.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/irqchip/chained_irq.h>
+#include <linux/irqdomain.h>
+#include <linux/of_platform.h>
+#include <linux/spinlock.h>
+
+#define CHANCSR(n) (0x0 + 0x40 * n)
+#define CHANVEC(n) (0x4 + 0x40 * n)
+#define CHANIER(n) (0x10 + (0x40 * n))
+#define CHANIPR(n) (0x20 + (0x40 * n))
+
+struct intmux_irqchip_data {
+ int chanidx;
+ int irq;
+ struct irq_domain *domain;
+ unsigned int irqstat;
+};
+
+
+struct intmux_data {
+ spinlock_t lock;
+ struct platform_device *pdev;
+ void __iomem *regs;
+ struct clk *ipg_clk;
+ int channum;
+ struct intmux_irqchip_data irqchip_data[];
+};
+
+static void imx_intmux_irq_unmask(struct irq_data *d)
+{
+ struct intmux_irqchip_data *irqchip_data = d->chip_data;
+ u32 idx = irqchip_data->chanidx;
+ struct intmux_data *intmux_data = container_of(irqchip_data, struct intmux_data, irqchip_data[idx]);
+ void __iomem *reg;
+ u32 val;
+
+ spin_lock(&intmux_data->lock);
+ reg = intmux_data->regs + CHANIER(idx);
+ val = readl_relaxed(reg);
+ val |= 1 << d->hwirq;
+ writel_relaxed(val, reg);
+ spin_unlock(&intmux_data->lock);
+}
+
+static void imx_intmux_irq_mask(struct irq_data *d)
+{
+ struct intmux_irqchip_data *irqchip_data = d->chip_data;
+ u32 idx = irqchip_data->chanidx;
+ struct intmux_data *intmux_data = container_of(irqchip_data, struct intmux_data, irqchip_data[idx]);
+ void __iomem *reg;
+ u32 val;
+
+ spin_lock(&intmux_data->lock);
+ reg = intmux_data->regs + CHANIER(idx);
+ val = readl_relaxed(reg);
+ val &= ~(1 << d->hwirq);
+ writel_relaxed(val, reg);
+ spin_unlock(&intmux_data->lock);
+}
+
+static void imx_intmux_irq_ack(struct irq_data *d)
+{
+ /* the irqchip has no ack */
+}
+
+static struct irq_chip imx_intmux_irq_chip = {
+ .name = "intmux",
+ .irq_eoi = irq_chip_eoi_parent,
+ .irq_mask = imx_intmux_irq_mask,
+ .irq_unmask = imx_intmux_irq_unmask,
+ .irq_ack = imx_intmux_irq_ack,
+};
+
+static int imx_intmux_irq_map(struct irq_domain *h, unsigned int irq,
+ irq_hw_number_t hwirq)
+{
+ irq_set_chip_data(irq, h->host_data);
+ irq_set_chip_and_handler(irq, &imx_intmux_irq_chip, handle_edge_irq);
+
+ return 0;
+}
+
+static const struct irq_domain_ops imx_intmux_domain_ops = {
+ .map = imx_intmux_irq_map,
+ .xlate = irq_domain_xlate_twocell,
+};
+
+static void imx_intmux_update_irqstat(struct intmux_irqchip_data *irqchip_data)
+{
+ int i = irqchip_data->chanidx;
+ struct intmux_data *intmux_data = container_of(irqchip_data, struct intmux_data, irqchip_data[i]);
+
+ irqchip_data->irqstat = readl_relaxed(intmux_data->regs + CHANIPR(i));
+}
+
+static void imx_intmux_irq_handler(struct irq_desc *desc)
+{
+ struct intmux_irqchip_data *irqchip_data = irq_desc_get_handler_data(desc);
+ int pos, virq;
+
+ chained_irq_enter(irq_desc_get_chip(desc), desc);
+
+ imx_intmux_update_irqstat(irqchip_data);
+
+ for_each_set_bit(pos, (unsigned long *)&irqchip_data->irqstat, 32) {
+ virq = irq_find_mapping(irqchip_data->domain, pos);
+ if (virq)
+ generic_handle_irq(virq);
+ }
+
+ chained_irq_exit(irq_desc_get_chip(desc), desc);
+}
+
+static int imx_intmux_probe(struct platform_device *pdev)
+{
+ struct device_node *np = pdev->dev.of_node;
+ struct intmux_data *intmux_data;
+ struct resource *res;
+ int i;
+ int channum;
+ int ret;
+
+ ret = of_property_read_u32(np, "nxp,intmux_chans", &channum);
+ if (ret)
+ channum = 1;
+
+ intmux_data = devm_kzalloc(&pdev->dev, sizeof(*intmux_data) +
+ channum *
+ sizeof(intmux_data->irqchip_data[0]),
+ GFP_KERNEL);
+ if (!intmux_data)
+ return -ENOMEM;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ intmux_data->regs = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(intmux_data->regs)) {
+ dev_err(&pdev->dev, "failed to initialize reg\n");
+ return PTR_ERR(intmux_data->regs);
+ }
+
+ intmux_data->ipg_clk = devm_clk_get(&pdev->dev, "ipg");
+ if (IS_ERR(intmux_data->ipg_clk)) {
+ ret = PTR_ERR(intmux_data->ipg_clk);
+ dev_err(&pdev->dev, "failed to get ipg clk: %d\n", ret);
+ return ret;
+ }
+
+ intmux_data->channum = channum;
+ intmux_data->pdev = pdev;
+ spin_lock_init(&intmux_data->lock);
+
+ ret = clk_prepare_enable(intmux_data->ipg_clk);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to enable ipg clk: %d\n", ret);
+ return ret;
+ }
+
+ for (i = 0; i < channum; i++) {
+ intmux_data->irqchip_data[i].chanidx = i;
+ intmux_data->irqchip_data[i].irq = platform_get_irq(pdev, i);
+ if (intmux_data->irqchip_data[i].irq <= 0) {
+ dev_err(&pdev->dev, "failed to get irq\n");
+ return -ENODEV;
+ }
+
+ intmux_data->irqchip_data[i].domain = irq_domain_add_linear(np,
+ 32,
+ &imx_intmux_domain_ops,
+ &intmux_data->irqchip_data[i]);
+ if (!intmux_data->irqchip_data[i].domain) {
+ dev_err(&intmux_data->pdev->dev,
+ "failed to create IRQ domain\n");
+ return -ENOMEM;
+ }
+
+ irq_set_chained_handler_and_data(intmux_data->irqchip_data[i].irq,
+ imx_intmux_irq_handler,
+ &intmux_data->irqchip_data[i]);
+ }
+
+ platform_set_drvdata(pdev, intmux_data);
+
+ return 0;
+}
+
+static int imx_intmux_remove(struct platform_device *pdev)
+{
+ struct intmux_data *intmux_data = platform_get_drvdata(pdev);
+ int i;
+
+ for (i = 0; i < intmux_data->channum; i++) {
+ irq_set_chained_handler_and_data(intmux_data->irqchip_data[i].irq, NULL, NULL);
+
+ irq_domain_remove(intmux_data->irqchip_data[i].domain);
+ }
+
+ platform_set_drvdata(pdev, NULL);
+ clk_disable_unprepare(intmux_data->ipg_clk);
+
+ return 0;
+}
+
+static const struct of_device_id imx_intmux_id[] = {
+ { .compatible = "nxp,imx-intmux", },
+ {},
+};
+
+static struct platform_driver imx_intmux_driver = {
+ .driver = {
+ .name = "imx-intmux",
+ .of_match_table = imx_intmux_id,
+ },
+ .probe = imx_intmux_probe,
+ .remove = imx_intmux_remove,
+};
+
+static int __init irq_imx_intmux_init(void)
+{
+ return platform_driver_register(&imx_intmux_driver);
+}
+arch_initcall(irq_imx_intmux_init);
+
+MODULE_AUTHOR("NXP Semiconductor");
+MODULE_DESCRIPTION("NXP i.MX8 irq steering driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/irqchip/irq-imx-irqsteer.c b/drivers/irqchip/irq-imx-irqsteer.c
new file mode 100644
index 000000000000..e26d242e1c66
--- /dev/null
+++ b/drivers/irqchip/irq-imx-irqsteer.c
@@ -0,0 +1,337 @@
+/*
+ * Copyright 2017 NXP
+ *
+ * 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/module.h>
+#include <linux/clk.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/irqchip/chained_irq.h>
+#include <linux/irqdomain.h>
+#include <linux/of_platform.h>
+#include <linux/spinlock.h>
+#include <linux/pm_runtime.h>
+
+#define CHANREG_OFF (irqsteer_data->channum * 4)
+#define CHANCTRL 0x0
+#define CHANMASK(n) (0x4 + 0x4 * (n))
+#define CHANSET(n) (0x4 + (0x4 * (n)) + CHANREG_OFF)
+#define CHANSTATUS(n) (0x4 + (0x4 * (n)) + (CHANREG_OFF * 2))
+#define CHAN_MINTDIS (0x4 + (CHANREG_OFF * 3))
+#define CHAN_MASTRSTAT (CHAN_MINTDIS + 0x4)
+
+struct irqsteer_irqchip_data {
+ struct irq_chip chip;
+ spinlock_t lock;
+ struct platform_device *pdev;
+ void __iomem *regs;
+ struct clk *ipg_clk;
+ int irq;
+ int channum;
+ int endian; /* 0: littel endian; 1: big endian */
+ struct irq_domain *domain;
+ int *saved_reg;
+ bool inited;
+ unsigned int irqstat[];
+};
+
+static void imx_irqsteer_irq_unmask(struct irq_data *d)
+{
+ struct irqsteer_irqchip_data *irqsteer_data = d->chip_data;
+ void __iomem *reg;
+ u32 val, idx;
+
+ spin_lock(&irqsteer_data->lock);
+ idx = irqsteer_data->endian ?
+ (irqsteer_data->channum - d->hwirq / 32 - 1) : d->hwirq / 32;
+ reg = irqsteer_data->regs + CHANMASK(idx);
+ val = readl_relaxed(reg);
+ val |= 1 << (d->hwirq % 32);
+ writel_relaxed(val, reg);
+ spin_unlock(&irqsteer_data->lock);
+}
+
+static void imx_irqsteer_irq_mask(struct irq_data *d)
+{
+ struct irqsteer_irqchip_data *irqsteer_data = d->chip_data;
+ void __iomem *reg;
+ u32 val, idx;
+
+ spin_lock(&irqsteer_data->lock);
+ idx = irqsteer_data->endian ?
+ (irqsteer_data->channum - d->hwirq / 32 - 1) : d->hwirq / 32;
+ reg = irqsteer_data->regs + CHANMASK(idx);
+ val = readl_relaxed(reg);
+ val &= ~(1 << (d->hwirq % 32));
+ writel_relaxed(val, reg);
+ spin_unlock(&irqsteer_data->lock);
+}
+
+static void imx_irqsteer_irq_ack(struct irq_data *d)
+{
+ /* the irqchip has no ack */
+}
+
+static struct irq_chip imx_irqsteer_irq_chip = {
+ .name = "irqsteer",
+ .irq_eoi = irq_chip_eoi_parent,
+ .irq_mask = imx_irqsteer_irq_mask,
+ .irq_unmask = imx_irqsteer_irq_unmask,
+ .irq_ack = imx_irqsteer_irq_ack,
+};
+
+static int imx_irqsteer_irq_map(struct irq_domain *h, unsigned int irq,
+ irq_hw_number_t hwirq)
+{
+ struct irqsteer_irqchip_data *irqsteer_data = h->host_data;
+
+ irq_set_chip_data(irq, h->host_data);
+ irq_set_chip_and_handler(irq, &irqsteer_data->chip, handle_level_irq);
+
+ return 0;
+}
+
+static const struct irq_domain_ops imx_irqsteer_domain_ops = {
+ .map = imx_irqsteer_irq_map,
+ .xlate = irq_domain_xlate_twocell,
+};
+
+static void imx_irqsteer_init(struct irqsteer_irqchip_data *irqsteer_data)
+{
+ /* enable channel 1 in default */
+ writel_relaxed(1, irqsteer_data->regs + CHANCTRL);
+
+ /* read back CHANCTRL register cannot reflact on HW register
+ * real value due to the HW action, so add one flag here.
+ */
+ irqsteer_data->inited = true;
+}
+
+static void imx_irqsteer_update_irqstat(struct irqsteer_irqchip_data *irqsteer_data)
+{
+ int i;
+
+ /*
+ * From irq steering doc, there have one mapping:
+ * word[0] bit 31 -> irq 31 ... word[0] bit 0 -> irq 0
+ * word[1] bit 31 -> irq 63 ... word[1] bit 0 -> irq 32
+ * ......
+ * word[15] bit 31 -> irq 511 ... word[15] bit 0 -> irq 480
+ */
+ for (i = 0; i < irqsteer_data->channum; i++)
+ irqsteer_data->irqstat[i] = readl_relaxed(irqsteer_data->regs +
+ CHANSTATUS(irqsteer_data->endian ?
+ (irqsteer_data->channum - i - 1) :
+ i));
+}
+
+static void imx_irqsteer_irq_handler(struct irq_desc *desc)
+{
+ struct irqsteer_irqchip_data *irqsteer_data = irq_desc_get_handler_data(desc);
+ unsigned long val;
+ int irqnum;
+ int pos, virq;
+
+ chained_irq_enter(irq_desc_get_chip(desc), desc);
+
+ val = readl_relaxed(irqsteer_data->regs + CHAN_MASTRSTAT);
+ if (!val)
+ goto out;
+
+ imx_irqsteer_update_irqstat(irqsteer_data);
+
+ irqnum = irqsteer_data->channum * 32;
+ for_each_set_bit(pos, (unsigned long *)irqsteer_data->irqstat, irqnum) {
+ virq = irq_find_mapping(irqsteer_data->domain, pos);
+ if (virq)
+ generic_handle_irq(virq);
+ }
+
+out:
+ chained_irq_exit(irq_desc_get_chip(desc), desc);
+}
+
+static int imx_irqsteer_probe(struct platform_device *pdev)
+{
+ struct device_node *np = pdev->dev.of_node;
+ struct irqsteer_irqchip_data *irqsteer_data;
+ struct resource *res;
+ int channum, endian;
+ int ret;
+
+ ret = of_property_read_u32(np, "nxp,irqsteer_chans", &channum);
+ if (ret)
+ channum = 1;
+
+ ret = of_property_read_u32(np, "nxp,endian", &endian);
+ if (ret)
+ /* default is LSB */
+ endian = 0;
+
+ irqsteer_data = devm_kzalloc(&pdev->dev, sizeof(*irqsteer_data) +
+ channum *
+ sizeof(irqsteer_data->irqstat[0]),
+ GFP_KERNEL);
+ if (!irqsteer_data)
+ return -ENOMEM;
+
+ irqsteer_data->saved_reg = devm_kzalloc(&pdev->dev, sizeof(int) *
+ (channum + 1), GFP_KERNEL);
+ if (!irqsteer_data->saved_reg)
+ return -ENOMEM;
+
+ irqsteer_data->chip = imx_irqsteer_irq_chip;
+ irqsteer_data->chip.parent_device = &pdev->dev;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ irqsteer_data->regs = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(irqsteer_data->regs)) {
+ dev_err(&pdev->dev, "failed to initialize reg\n");
+ return PTR_ERR(irqsteer_data->regs);
+ }
+
+ irqsteer_data->irq = platform_get_irq(pdev, 0);
+ if (irqsteer_data->irq <= 0) {
+ dev_err(&pdev->dev, "failed to get irq\n");
+ return -ENODEV;
+ }
+
+ irqsteer_data->ipg_clk = devm_clk_get(&pdev->dev, "ipg");
+ if (IS_ERR(irqsteer_data->ipg_clk)) {
+ ret = PTR_ERR(irqsteer_data->ipg_clk);
+ dev_err(&pdev->dev, "failed to get ipg clk: %d\n", ret);
+ return ret;
+ }
+
+ irqsteer_data->channum = channum;
+ irqsteer_data->endian = endian;
+ irqsteer_data->pdev = pdev;
+ irqsteer_data->inited = false;
+ spin_lock_init(&irqsteer_data->lock);
+
+ irqsteer_data->domain = irq_domain_add_linear(np,
+ irqsteer_data->channum * 32,
+ &imx_irqsteer_domain_ops,
+ irqsteer_data);
+ if (!irqsteer_data->domain) {
+ dev_err(&irqsteer_data->pdev->dev,
+ "failed to create IRQ domain\n");
+ return -ENOMEM;
+ }
+
+ irq_set_chained_handler_and_data(irqsteer_data->irq,
+ imx_irqsteer_irq_handler,
+ irqsteer_data);
+
+ platform_set_drvdata(pdev, irqsteer_data);
+
+ pm_runtime_enable(&pdev->dev);
+ return 0;
+}
+
+static int imx_irqsteer_remove(struct platform_device *pdev)
+{
+ struct irqsteer_irqchip_data *irqsteer_data = platform_get_drvdata(pdev);
+
+ irq_set_chained_handler_and_data(irqsteer_data->irq, NULL, NULL);
+
+ irq_domain_remove(irqsteer_data->domain);
+
+ return pm_runtime_force_suspend(&pdev->dev);
+}
+
+#ifdef CONFIG_PM_SLEEP
+static void imx_irqsteer_save_regs(struct irqsteer_irqchip_data *data)
+{
+ int num;
+
+ data->saved_reg[0] = readl_relaxed(data->regs + CHANCTRL);
+ for (num = 0; num < data->channum; num++)
+ data->saved_reg[num + 1] = readl_relaxed(data->regs + CHANMASK(num));
+}
+
+static void imx_irqsteer_restore_regs(struct irqsteer_irqchip_data *data)
+{
+ int num;
+
+ writel_relaxed(data->saved_reg[0], data->regs + CHANCTRL);
+ for (num = 0; num < data->channum; num++)
+ writel_relaxed(data->saved_reg[num + 1], data->regs + CHANMASK(num));
+}
+
+static int imx_irqsteer_runtime_suspend(struct device *dev)
+{
+ struct irqsteer_irqchip_data *irqsteer_data = dev_get_drvdata(dev);
+
+ /* After device's runtime suspended, device's power domain maybe off,
+ * if some sub_irqs resouces are not freed, it needs to save registers
+ * when device's suspend force runtime suspend. And even if all sub_irqs
+ * are freed, it also needs to save CHANCTRL register.
+ */
+ imx_irqsteer_save_regs(irqsteer_data);
+
+ clk_disable_unprepare(irqsteer_data->ipg_clk);
+
+ return 0;
+}
+
+static int imx_irqsteer_runtime_resume(struct device *dev)
+{
+ struct irqsteer_irqchip_data *irqsteer_data = dev_get_drvdata(dev);
+ int ret;
+
+ ret = clk_prepare_enable(irqsteer_data->ipg_clk);
+ if (ret) {
+ dev_err(dev, "failed to enable ipg clk: %d\n", ret);
+ return ret;
+ }
+
+ /* don't need restore registers when first sub_irq requested */
+ if (!irqsteer_data->inited)
+ imx_irqsteer_init(irqsteer_data);
+ else
+ imx_irqsteer_restore_regs(irqsteer_data);
+
+ return 0;
+}
+
+static const struct dev_pm_ops imx_irqsteer_pm_ops = {
+ SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
+ pm_runtime_force_resume)
+ SET_RUNTIME_PM_OPS(imx_irqsteer_runtime_suspend,
+ imx_irqsteer_runtime_resume, NULL)
+};
+#define IMX_IRQSTEER_PM (&imx_irqsteer_pm_ops)
+#else
+#define IMX_IRQSTEER_PM NULL
+#endif
+
+static const struct of_device_id imx_irqsteer_id[] = {
+ { .compatible = "nxp,imx-irqsteer", },
+ {},
+};
+
+static struct platform_driver imx_irqsteer_driver = {
+ .driver = {
+ .name = "imx-irqsteer",
+ .of_match_table = imx_irqsteer_id,
+ .pm = IMX_IRQSTEER_PM,
+ },
+ .probe = imx_irqsteer_probe,
+ .remove = imx_irqsteer_remove,
+};
+
+static int __init irq_imx_irqsteer_init(void)
+{
+ return platform_driver_register(&imx_irqsteer_driver);
+}
+arch_initcall(irq_imx_irqsteer_init);
+
+MODULE_AUTHOR("NXP Semiconductor");
+MODULE_DESCRIPTION("NXP i.MX8 irq steering driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig
index 3c4f7fa7b9d8..1be11898ae04 100644
--- a/drivers/media/platform/Kconfig
+++ b/drivers/media/platform/Kconfig
@@ -144,6 +144,28 @@ config VIDEO_STM32_DCMI
To compile this driver as a module, choose M here: the module
will be called stm32-dcmi.
+config VIDEO_MXC_OUTPUT
+ tristate "MXC Video For Linux Video Output"
+ depends on VIDEO_DEV && ARCH_MXC && FB_MXC
+ select VIDEOBUF_DMA_CONTIG
+ ---help---
+ This is the video4linux2 output driver based on MXC module.
+
+config VIDEO_MXC_CAPTURE
+ tristate "MXC Video For Linux Video Capture"
+ depends on VIDEO_V4L2
+ ---help---
+ This is the video4linux2 capture driver based on i.MX video-in module.
+
+config VIDEO_MX8_CAPTURE
+ tristate "MX8 Video For Linux Video Capture"
+ depends on VIDEO_V4L2
+ ---help---
+ This is the video4linux2 capture driver based on i.MX8 module.
+
+source "drivers/media/platform/imx8/Kconfig"
+source "drivers/media/platform/mxc/capture/Kconfig"
+source "drivers/media/platform/mxc/output/Kconfig"
source "drivers/media/platform/soc_camera/Kconfig"
source "drivers/media/platform/exynos4-is/Kconfig"
source "drivers/media/platform/am437x/Kconfig"
@@ -165,6 +187,7 @@ config VIDEO_TI_CAL
In TI Technical Reference Manual this module is referred as
Camera Interface Subsystem (CAMSS).
+
endif # V4L_PLATFORM_DRIVERS
menuconfig V4L_MEM2MEM_DRIVERS
diff --git a/drivers/media/platform/Makefile b/drivers/media/platform/Makefile
index 327f80a6f82c..d25b862cf7eb 100644
--- a/drivers/media/platform/Makefile
+++ b/drivers/media/platform/Makefile
@@ -76,6 +76,12 @@ obj-$(CONFIG_VIDEO_ATMEL_ISI) += atmel/
obj-$(CONFIG_VIDEO_STM32_DCMI) += stm32/
+obj-$(CONFIG_VIDEO_MXC_OUTPUT) += mxc/output/
+
+obj-$(CONFIG_VIDEO_MXC_CAPTURE) += mxc/capture/
+obj-$(CONFIG_VIDEO_MXC_OUTPUT) += mxc/output/
+obj-$(CONFIG_VIDEO_MX8_CAPTURE) += imx8/
+
ccflags-y += -I$(srctree)/drivers/media/i2c
obj-$(CONFIG_VIDEO_MEDIATEK_VPU) += mtk-vpu/
diff --git a/drivers/media/platform/imx8/Kconfig b/drivers/media/platform/imx8/Kconfig
new file mode 100644
index 000000000000..bf3a0a8e2850
--- /dev/null
+++ b/drivers/media/platform/imx8/Kconfig
@@ -0,0 +1,57 @@
+if VIDEO_MX8_CAPTURE
+menu "IMX8 Camera ISI/MIPI Features support"
+
+config IMX8_MEDIA_DEVICE
+ tristate "IMX8 Media Device Driver"
+ select V4L2_FWNODE
+ default y
+
+config IMX8_CAPTURE_DRIVER
+ tristate "IMX8 Camera Controller"
+ depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
+ select V4L2_MEM2MEM_DEV
+ select VIDEOBUF2_DMA_CONTIG
+ default y
+
+config IMX8_MIPI_CSI2
+ tristate "IMX8 MIPI CSI2 Controller"
+ default y
+
+config IMX8_PARALLEL_CSI
+ tristate "IMX8 PARALLEL CSI Controller"
+ default y
+
+config IMX8_MIPI_CSI2_YAV
+ tristate "IMX8 MIPI CSI2 Controller Yet Another Version"
+ select V4L2_FWNODE
+ default y
+
+config MXC_CAMERA_OV5640_V3
+ tristate "Maxim OV5640_V3 driver support"
+ depends on I2C
+ default y
+
+config MXC_CAMERA_OV5640_MIPI_V3
+ tristate "Maxim OV5640_MIPI_V3 driver support"
+ depends on I2C
+ default y
+
+config GMSL_MAX9286
+ tristate "Maxim max9286 GMSL Deserializer Input support"
+ select SENSOR_OV10635
+ depends on I2C
+ ---help---
+ If you plan to use the max9286 GMSL Deserializer with your capture system, say Y here.
+
+config IMX8_JPEG
+ tristate "IMX8 JPEG Encoder/Decoder"
+ depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
+ select V4L2_MEM2MEM_DEV
+ select VIDEOBUF2_DMA_CONTIG
+ default y
+
+source "drivers/media/platform/imx8/hdmi/Kconfig"
+
+endmenu
+endif #VIDEO_MX8_CAPTURE
+
diff --git a/drivers/media/platform/imx8/Makefile b/drivers/media/platform/imx8/Makefile
new file mode 100644
index 000000000000..097a91b3c639
--- /dev/null
+++ b/drivers/media/platform/imx8/Makefile
@@ -0,0 +1,15 @@
+mxc-capture-objs := mxc-isi-core.o mxc-isi-cap.o mxc-isi-hw.o mxc-isi-m2m.o
+
+obj-$(CONFIG_IMX8_CAPTURE_DRIVER) += mxc-capture.o
+obj-$(CONFIG_IMX8_MIPI_CSI2) += mxc-mipi-csi2.o
+obj-$(CONFIG_IMX8_PARALLEL_CSI) += mxc-parallel-csi.o
+obj-$(CONFIG_IMX8_MIPI_CSI2_YAV) += mxc-mipi-csi2_yav.o
+ov5640_camera_v3-objs := ov5640_v3.o
+obj-$(CONFIG_MXC_CAMERA_OV5640_V3) += ov5640_camera_v3.o
+obj-$(CONFIG_MXC_CAMERA_OV5640_MIPI_V3) += ov5640_mipi_v3.o
+max9286_gmsl-objs := max9286.o
+obj-$(CONFIG_GMSL_MAX9286) += max9286_gmsl.o
+obj-$(CONFIG_IMX8_MEDIA_DEVICE) += mxc-media-dev.o
+mxc-jpeg-enc-dec-objs := mxc-jpeg-hw.o mxc-jpeg.o
+obj-$(CONFIG_IMX8_JPEG) += mxc-jpeg-enc-dec.o
+obj-$(CONFIG_IMX8_HDMI_RX) += hdmi/
diff --git a/drivers/media/platform/imx8/hdmi/API_AFE_ss28fdsoi_hdmirx.c b/drivers/media/platform/imx8/hdmi/API_AFE_ss28fdsoi_hdmirx.c
new file mode 100644
index 000000000000..e09a64e5f5dc
--- /dev/null
+++ b/drivers/media/platform/imx8/hdmi/API_AFE_ss28fdsoi_hdmirx.c
@@ -0,0 +1,1233 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2016-2017 Cadence Design Systems, Inc.
+ * All rights reserved worldwide.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 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.
+ *
+ * Copyright 2018 NXP
+ *
+ ******************************************************************************
+ *
+ * API_AFE_ss28fdsoi_hdmirx.c
+ *
+ ******************************************************************************
+ */
+
+#include "API_AFE_ss28fdsoi_hdmirx.h"
+
+static inline void write16(state_struct *state, u32 addr, u16 val)
+{
+ Afe_write(state, addr, val);
+}
+
+static inline void multi_write16(state_struct *state, u32 addr,
+ u16 val)
+{
+ u16 addr_tmp = addr;
+
+ if ((addr & 0x1E00) == LINK_ID << 9) {
+ addr_tmp |= LINK_WRITE;
+ Afe_write(state, addr_tmp, val);
+ } else {
+ Afe_write(state, addr_tmp, val);
+ }
+}
+
+static inline u16 read16(state_struct *state, u32 addr)
+{
+ u16 reg_val;
+
+ reg_val = Afe_read(state, addr);
+ return reg_val;
+}
+
+u16 inside_i(u16 value, u16 left_sharp_corner,
+ u16 right_sharp_corner)
+{
+ if (value < left_sharp_corner)
+ return 0;
+ if (value > right_sharp_corner)
+ return 0;
+ return 1;
+}
+
+u16 inside_f(u32 value, u32 left_sharp_corner, u32 right_sharp_corner)
+{
+ if (value < left_sharp_corner)
+ return 0;
+ if (value > right_sharp_corner)
+ return 0;
+ return 1;
+}
+
+void arc_config(state_struct *state)
+{
+ u16 reg_val;
+
+ write16(state, TXDA_CYA_AUXDA_CYA_ADDR, 0x0001);
+
+ write16(state, TX_DIG_CTRL_REG_1_ADDR, 0x3);
+ write16(state, TX_DIG_CTRL_REG_2_ADDR, 0x0024);
+
+ reg_val = read16(state, TX_ANA_CTRL_REG_1_ADDR);
+ reg_val |= 0x2000;
+ write16(state, TX_ANA_CTRL_REG_1_ADDR, reg_val);
+
+ write16(state, TX_ANA_CTRL_REG_2_ADDR, 0x0100);
+ write16(state, TX_ANA_CTRL_REG_2_ADDR, 0x0300);
+ write16(state, TX_ANA_CTRL_REG_3_ADDR, 0x0000);
+ write16(state, TX_ANA_CTRL_REG_1_ADDR, 0x2008);
+ write16(state, TX_ANA_CTRL_REG_1_ADDR, 0x2018);
+ write16(state, TX_ANA_CTRL_REG_1_ADDR, 0x2098);
+ write16(state, TX_ANA_CTRL_REG_2_ADDR, 0x030C);
+ write16(state, TX_ANA_CTRL_REG_5_ADDR, 0x0010);
+ write16(state, TX_ANA_CTRL_REG_4_ADDR, 0x4001);
+ write16(state, TX_ANA_CTRL_REG_1_ADDR, 0x2198);
+ write16(state, TX_ANA_CTRL_REG_2_ADDR, 0x030D);
+ write16(state, TX_ANA_CTRL_REG_2_ADDR, 0x030F);
+}
+
+void pma_config(state_struct *state)
+{
+ int i;
+ u16 reg_val = 0;
+ pr_info("pma_config() Configuring PMA\n");
+
+ write16(state, CMN_CMSMT_REF_CLK_TMR_VALUE_ADDR, 0x0801);
+ write16(state, RX_CLK_SLICER_CAL_INIT_TMR_ADDR, 0x00FF);
+ write16(state, CMN_RXCAL_INIT_TMR_ADDR, 0x003F);
+ write16(state, CMN_DIAG_PLL0_TEST_MODE_ADDR, 0x0022);
+ multi_write16(state, XCVR_PSM_CAL_TMR_ADDR, 0x0160);
+
+ /* Drives the rx_differential_invert PMA input for the associated lane */
+ for (i = 0; i < 3; i++) {
+ reg_val = 0x0c61;
+ write16(state, (PHY_PMA_XCVR_CTRL_ADDR | (i << 6)), reg_val);
+ }
+}
+
+void pre_data_rate_change(state_struct *state)
+{
+ u16 reg_val;
+
+ pr_info("pre_data_rate_change() Set the A3 power mode\n");
+ reg_val = read16(state, PHY_MODE_CTL_ADDR);
+ reg_val &= 0xFFF0;
+ reg_val |= 0x0008;
+ write16(state, PHY_MODE_CTL_ADDR, reg_val);
+
+ msleep(20);
+
+ /* Disable PLL */
+ pr_info("pre_data_rate_change() Disable PLL0\n");
+ reg_val = read16(state, PHY_MODE_CTL_ADDR);
+ reg_val &= 0xEFFF;
+ write16(state, PHY_MODE_CTL_ADDR, reg_val);
+
+ msleep(20);
+}
+
+int pma_cmn_ready(state_struct *state)
+{
+ u32 i;
+
+ for (i = 0; i < 20; i++) {
+ if (read16(state, PHY_PMA_CMN_CTRL1_ADDR) & (1 << 0))
+ break;
+ msleep(10);
+ }
+ if (i == 20)
+ return -1;
+ return 0;
+}
+
+int pma_rx_clk_signal_detect(state_struct *state)
+{
+ u32 i;
+
+ for (i = 0; i < 20; i++) {
+ if (read16(state, PHY_MODE_CTL_ADDR) & (1 << 8))
+ break;
+ msleep(10);
+ }
+ if (i == 20)
+ return -1;
+ return 0;
+}
+
+int pma_rx_clk_freq_detect(state_struct *state)
+{
+ u16 reg_val;
+ u32 rx_clk_freq;
+ u32 i;
+
+ pr_info("pma_rx_clk_freq_detect() Starting Rx clock frequency detection...\n");
+
+ /* Start frequency detection: */
+ write16(state, CMN_CMSMT_CLK_FREQ_MSMT_CTRL_ADDR, 0x8000);
+
+ /* Wait for pma_rx_clk_freq_detect_done */
+ for (i = 0; i < 20; i++) {
+ if (read16(state, CMN_CMSMT_CLK_FREQ_MSMT_CTRL_ADDR) & (1 << 14))
+ break;
+ msleep(10);
+ }
+ if (i == 20)
+ return -1;
+
+ /* Read the measured value */
+ reg_val = read16(state, CMN_CMSMT_TEST_CLK_CNT_VALUE_ADDR);
+
+ /* Calculate TMDS clock frequency */
+ rx_clk_freq = reg_val * REFCLK_FREQ_KHZ / 2048;
+
+ /* Turn off frequency measurement: */
+ write16(state, CMN_CMSMT_CLK_FREQ_MSMT_CTRL_ADDR, 0x0000);
+ pr_info("pma_rx_clk_freq_detect() Starting Rx clock frequency detection... DONE (TMDS clock freq: %d kHz)\n",
+ rx_clk_freq);
+ return rx_clk_freq;
+}
+
+int pma_pll_config(state_struct *state,
+ u32 rx_clk_freq,
+ clk_ratio_t clk_ratio,
+ tmds_bit_clock_ratio_t tmds_bit_clk_ratio,
+ unsigned char data_rate_change)
+{
+ int i, loop;
+ u16 reg_val;
+ u64 vco_freq_khz;
+
+ reg_field_t cmnda_pll0_ip_div;
+ reg_field_t cmnda_pll0_hs_sym_div_sel;
+ reg_field_t cmn_pll0_fb_div_high_ovrd_en;
+ reg_field_t cmnda_pll0_fb_div_high_out;
+ reg_field_t cmn_pll0_fb_div_low_ovrd_en;
+ reg_field_t cmnda_pll0_fb_div_low_out;
+ reg_field_t cmn_pll_clk_osr;
+ reg_field_t cmn_pll_clk_div2_ratio;
+ reg_field_t cmn_pll_clk_div2_sel;
+ reg_field_t rx_diag_smplr_osr;
+ reg_field_t rx_psc_a0;
+ reg_field_t rx_ree_pergcsm_eqenm_ph1;
+ reg_field_t rx_ree_pergcsm_eqenm_ph2;
+ reg_field_t vga_gain_accum_override_en;
+ reg_field_t vga_gain_accum_override;
+ reg_field_t vga_gain_tgt_adj_override_en;
+ reg_field_t vga_gain_tgt_adj_override;
+ reg_field_t ree_gen_sm_en_usb;
+ reg_field_t ree_gen_sm_en_periodic;
+ reg_field_t ana_en_epath_gen_ctrl_sm_usb;
+ reg_field_t ana_en_epath_gen_ctrl_sm_periodic;
+ reg_field_t rxda_eq_range_sel;
+ reg_field_t rxda_vga_sa_range_sel;
+ reg_field_t vco_ring_select;
+ reg_field_t cmnda_pll0_v2i_prog;
+ reg_field_t cmnda_pll0_coarse_prog;
+ reg_field_t cmnda_pll0_cp_gain;
+ reg_field_t cmnda_pll0_const_ndac_cntrl;
+ reg_field_t cmnda_pll0_const_pmos_cntrl;
+ reg_field_t cmnda_pll0_ptat_ndac_cntrl;
+ reg_field_t rxda_pi_iq_bias_trim;
+ reg_field_t rxda_pi_iq_pload_bias_trim;
+ reg_field_t rxda_pi_iq_pload_trim;
+ reg_field_t rxda_pi_e_bias_trim;
+ reg_field_t rxda_pi_e_pload_bias_trim;
+ reg_field_t rxda_pi_e_pload_trim;
+ reg_field_t rxda_pi_range_sel;
+ reg_field_t rxda_pi_cal_cm_trim;
+ reg_field_t xcvr_pll_en;
+ reg_field_t xcvr_link_reset_n;
+ reg_field_t xcvr_power_state_req;
+ reg_field_t xcvr_power_state_ack;
+ reg_field_t iso_pma_cmn_pll0_clk_datart1_div;
+ reg_field_t iso_pma_cmn_pll0_clk_datart0_div;
+ reg_field_t iso_pma_cmn_pll0_clk_en;
+
+ /* Set fields' labels */
+ cmnda_pll0_ip_div.label = "cmnda_pll0_ip_div";
+ cmnda_pll0_hs_sym_div_sel.label = "cmnda_pll0_hs_sym_div_sel";
+ cmn_pll0_fb_div_high_ovrd_en.label = "cmn_pll0_fb_div_high_ovrd_en";
+ cmnda_pll0_fb_div_high_out.label = "cmnda_pll0_fb_div_high_out";
+ cmn_pll0_fb_div_low_ovrd_en.label = "cmn_pll0_fb_div_low_ovrd_en";
+ cmnda_pll0_fb_div_low_out.label = "cmnda_pll0_fb_div_low_out";
+ cmn_pll_clk_osr.label = "cmn_pll_clk_osr";
+ cmn_pll_clk_div2_ratio.label = "cmn_pll_clk_div2_ratio";
+ cmn_pll_clk_div2_sel.label = "cmn_pll_clk_div2_sel";
+ rx_diag_smplr_osr.label = "rx_diag_smplr_osr";
+ rx_psc_a0.label = "rx_psc_a0";
+ rx_ree_pergcsm_eqenm_ph1.label = "rx_ree_pergcsm_eqenm_ph1";
+ rx_ree_pergcsm_eqenm_ph2.label = "rx_ree_pergcsm_eqenm_ph2";
+ vga_gain_accum_override_en.label = "vga_gain_accum_override_en";
+ vga_gain_accum_override.label = "vga_gain_accum_override";
+ vga_gain_tgt_adj_override_en.label = "vga_gain_tgt_adj_override_en";
+ vga_gain_tgt_adj_override.label = "vga_gain_tgt_adj_override";
+ ree_gen_sm_en_usb.label = "ree_gen_sm_en_usb";
+ ree_gen_sm_en_periodic.label = "ree_gen_sm_en_periodic";
+ ana_en_epath_gen_ctrl_sm_usb.label = "ana_en_epath_gen_ctrl_sm_usb";
+ ana_en_epath_gen_ctrl_sm_periodic.label =
+ "ana_en_epath_gen_ctrl_sm_periodic";
+ rxda_eq_range_sel.label = "rxda_eq_range_sel";
+ rxda_vga_sa_range_sel.label = "rxda_vga_sa_range_sel";
+ vco_ring_select.label = "vco_ring_select";
+ cmnda_pll0_v2i_prog.label = "cmnda_pll0_v2i_prog";
+ cmnda_pll0_coarse_prog.label = "cmnda_pll0_coarse_prog";
+ cmnda_pll0_cp_gain.label = "cmnda_pll0_cp_gain";
+ cmnda_pll0_const_ndac_cntrl.label = "cmnda_pll0_const_ndac_cntrl";
+ cmnda_pll0_const_pmos_cntrl.label = "cmnda_pll0_const_pmos_cntrl";
+ cmnda_pll0_ptat_ndac_cntrl.label = "cmnda_pll0_ptat_ndac_cntrl";
+ rxda_pi_iq_bias_trim.label = "rxda_pi_iq_bias_trim";
+ rxda_pi_iq_pload_bias_trim.label = "rxda_pi_iq_pload_bias_trim";
+ rxda_pi_iq_pload_trim.label = "rxda_pi_iq_pload_trim";
+ rxda_pi_e_bias_trim.label = "rxda_pi_e_bias_trim";
+ rxda_pi_e_pload_bias_trim.label = "rxda_pi_e_pload_bias_trim";
+ rxda_pi_e_pload_trim.label = "rxda_pi_e_pload_trim";
+ rxda_pi_range_sel.label = "rxda_pi_range_sel";
+ rxda_pi_cal_cm_trim.label = "rxda_pi_cal_cm_trim";
+ xcvr_pll_en.label = "xcvr_pll_en";
+ xcvr_link_reset_n.label = "xcvr_link_reset_n";
+ xcvr_power_state_req.label = "xcvr_power_state_req";
+ xcvr_power_state_ack.label = "xcvr_power_state_ack";
+ iso_pma_cmn_pll0_clk_datart1_div.label = "iso_pma_cmn_pll0_clk_datart1_div";
+ iso_pma_cmn_pll0_clk_datart0_div.label = "iso_pma_cmn_pll0_clk_datart0_div";
+ iso_pma_cmn_pll0_clk_en.label = "iso_pma_cmn_pll0_clk_en";
+
+ /* Set field position in a target register */
+ cmnda_pll0_ip_div.msb = 7;
+ cmnda_pll0_ip_div.lsb = 0;
+ cmnda_pll0_hs_sym_div_sel.msb = 9;
+ cmnda_pll0_hs_sym_div_sel.lsb = 8;
+ cmn_pll0_fb_div_high_ovrd_en.msb = 15;
+ cmn_pll0_fb_div_high_ovrd_en.lsb = 15;
+ cmnda_pll0_fb_div_high_out.msb = 9;
+ cmnda_pll0_fb_div_high_out.lsb = 0;
+ cmn_pll0_fb_div_low_ovrd_en.msb = 15;
+ cmn_pll0_fb_div_low_ovrd_en.lsb = 15;
+ cmnda_pll0_fb_div_low_out.msb = 9;
+ cmnda_pll0_fb_div_low_out.lsb = 0;
+ cmn_pll_clk_osr.msb = 2;
+ cmn_pll_clk_osr.lsb = 0;
+ cmn_pll_clk_div2_ratio.msb = 6;
+ cmn_pll_clk_div2_ratio.lsb = 4;
+ cmn_pll_clk_div2_sel.msb = 9;
+ cmn_pll_clk_div2_sel.lsb = 8;
+ rx_diag_smplr_osr.msb = 2;
+ rx_diag_smplr_osr.lsb = 0;
+ rx_psc_a0.msb = 15;
+ rx_psc_a0.lsb = 0;
+ rx_ree_pergcsm_eqenm_ph1.msb = 15;
+ rx_ree_pergcsm_eqenm_ph1.lsb = 0;
+ rx_ree_pergcsm_eqenm_ph2.msb = 15;
+ rx_ree_pergcsm_eqenm_ph2.lsb = 0;
+ vga_gain_accum_override_en.msb = 7;
+ vga_gain_accum_override_en.lsb = 7;
+ vga_gain_accum_override.msb = 4;
+ vga_gain_accum_override.lsb = 0;
+ vga_gain_tgt_adj_override_en.msb = 15;
+ vga_gain_tgt_adj_override_en.lsb = 15;
+ vga_gain_tgt_adj_override.msb = 12;
+ vga_gain_tgt_adj_override.lsb = 8;
+ ree_gen_sm_en_usb.msb = 3;
+ ree_gen_sm_en_usb.lsb = 0;
+ ree_gen_sm_en_periodic.msb = 11;
+ ree_gen_sm_en_periodic.lsb = 8;
+ ana_en_epath_gen_ctrl_sm_usb.msb = 7;
+ ana_en_epath_gen_ctrl_sm_usb.lsb = 4;
+ ana_en_epath_gen_ctrl_sm_periodic.msb = 15;
+ ana_en_epath_gen_ctrl_sm_periodic.lsb = 12;
+ rxda_eq_range_sel.msb = 2;
+ rxda_eq_range_sel.lsb = 0;
+ rxda_vga_sa_range_sel.msb = 6;
+ rxda_vga_sa_range_sel.lsb = 4;
+ vco_ring_select.msb = 12;
+ vco_ring_select.lsb = 12;
+ cmnda_pll0_v2i_prog.msb = 5;
+ cmnda_pll0_v2i_prog.lsb = 4;
+ cmnda_pll0_coarse_prog.msb = 2;
+ cmnda_pll0_coarse_prog.lsb = 0;
+ cmnda_pll0_cp_gain.msb = 8;
+ cmnda_pll0_cp_gain.lsb = 0;
+ cmnda_pll0_const_ndac_cntrl.msb = 11;
+ cmnda_pll0_const_ndac_cntrl.lsb = 8;
+ cmnda_pll0_const_pmos_cntrl.msb = 7;
+ cmnda_pll0_const_pmos_cntrl.lsb = 0;
+ cmnda_pll0_ptat_ndac_cntrl.msb = 5;
+ cmnda_pll0_ptat_ndac_cntrl.lsb = 0;
+ rxda_pi_iq_bias_trim.msb = 14;
+ rxda_pi_iq_bias_trim.lsb = 12;
+ rxda_pi_iq_pload_bias_trim.msb = 10;
+ rxda_pi_iq_pload_bias_trim.lsb = 8;
+ rxda_pi_iq_pload_trim.msb = 7;
+ rxda_pi_iq_pload_trim.lsb = 0;
+ rxda_pi_e_bias_trim.msb = 14;
+ rxda_pi_e_bias_trim.lsb = 12;
+ rxda_pi_e_pload_bias_trim.msb = 10;
+ rxda_pi_e_pload_bias_trim.lsb = 8;
+ rxda_pi_e_pload_trim.msb = 7;
+ rxda_pi_e_pload_trim.lsb = 0;
+ rxda_pi_range_sel.msb = 11;
+ rxda_pi_range_sel.lsb = 8;
+ rxda_pi_cal_cm_trim.msb = 7;
+ rxda_pi_cal_cm_trim.lsb = 0;
+ xcvr_pll_en.msb = 12;
+ xcvr_pll_en.lsb = 12;
+ xcvr_link_reset_n.msb = 13;
+ xcvr_link_reset_n.lsb = 13;
+ xcvr_power_state_req.msb = 3;
+ xcvr_power_state_req.lsb = 0;
+ xcvr_power_state_ack.msb = 7;
+ xcvr_power_state_ack.lsb = 4;
+ iso_pma_cmn_pll0_clk_datart1_div.msb = 14;
+ iso_pma_cmn_pll0_clk_datart1_div.lsb = 11;
+ iso_pma_cmn_pll0_clk_datart0_div.msb = 10;
+ iso_pma_cmn_pll0_clk_datart0_div.lsb = 7;
+ iso_pma_cmn_pll0_clk_en.msb = 5;
+ iso_pma_cmn_pll0_clk_en.lsb = 5;
+
+ pr_info("pma_pll_config() Configuring PLL0 ...\n");
+
+ if (tmds_bit_clk_ratio == TMDS_BIT_CLOCK_RATIO_1_10) {
+ if (inside_f(rx_clk_freq, 18750, 37500)) {
+ set_field_value(&cmnda_pll0_ip_div, 0x1);
+ set_field_value(&cmnda_pll0_hs_sym_div_sel, 0x0);
+ set_field_value(&cmn_pll0_fb_div_high_ovrd_en, 0x1);
+ set_field_value(&cmnda_pll0_fb_div_high_out, 0x1E);
+ set_field_value(&cmn_pll0_fb_div_low_ovrd_en, 0x1);
+ set_field_value(&cmnda_pll0_fb_div_low_out, 0x7E);
+ set_field_value(&rx_diag_smplr_osr, 0x4);
+ set_field_value(&rx_psc_a0, 0x8BF5);
+ set_field_value(&rx_ree_pergcsm_eqenm_ph1, 0x0080);
+ set_field_value(&rx_ree_pergcsm_eqenm_ph2, 0x0080);
+ set_field_value(&vga_gain_accum_override_en, 0x1);
+ set_field_value(&vga_gain_accum_override, 0x1A);
+ set_field_value(&vga_gain_tgt_adj_override_en, 0x0);
+ set_field_value(&vga_gain_tgt_adj_override, 0x00);
+ set_field_value(&ree_gen_sm_en_usb, 0x1);
+ set_field_value(&ree_gen_sm_en_periodic, 0x1);
+ set_field_value(&ana_en_epath_gen_ctrl_sm_usb, 0x0);
+ set_field_value(&ana_en_epath_gen_ctrl_sm_periodic,
+ 0x0);
+ set_field_value(&rxda_eq_range_sel, 0x1);
+ set_field_value(&rxda_vga_sa_range_sel, 0x2);
+ switch (clk_ratio) {
+ case CLK_RATIO_1_1:
+ set_field_value(&cmn_pll_clk_osr, 0x4);
+ set_field_value(&cmn_pll_clk_div2_ratio, 0x0);
+ set_field_value(&cmn_pll_clk_div2_sel, 0x0);
+ break;
+ case CLK_RATIO_5_4:
+ set_field_value(&cmn_pll_clk_osr, 0x4);
+ set_field_value(&cmn_pll_clk_div2_ratio, 0x4);
+ set_field_value(&cmn_pll_clk_div2_sel, 0x1);
+ break;
+ case CLK_RATIO_3_2:
+ set_field_value(&cmn_pll_clk_osr, 0x4);
+ set_field_value(&cmn_pll_clk_div2_ratio, 0x5);
+ set_field_value(&cmn_pll_clk_div2_sel, 0x1);
+ break;
+ case CLK_RATIO_2_1:
+ set_field_value(&cmn_pll_clk_osr, 0x4);
+ set_field_value(&cmn_pll_clk_div2_ratio, 0x0);
+ set_field_value(&cmn_pll_clk_div2_sel, 0x3);
+ break;
+ case CLK_RATIO_1_2:
+ set_field_value(&cmn_pll_clk_osr, 0x4);
+ set_field_value(&cmn_pll_clk_div2_ratio, 0x0);
+ set_field_value(&cmn_pll_clk_div2_sel, 0x1);
+ break;
+ case CLK_RATIO_5_8:
+ set_field_value(&cmn_pll_clk_osr, 0x4);
+ set_field_value(&cmn_pll_clk_div2_ratio, 0x1);
+ set_field_value(&cmn_pll_clk_div2_sel, 0x1);
+ break;
+ case CLK_RATIO_3_4:
+ set_field_value(&cmn_pll_clk_osr, 0x4);
+ set_field_value(&cmn_pll_clk_div2_ratio, 0x2);
+ set_field_value(&cmn_pll_clk_div2_sel, 0x1);
+ break;
+ }
+ } else if (inside_f(rx_clk_freq, 37500, 75000)) {
+ set_field_value(&cmnda_pll0_ip_div, 0x1);
+ set_field_value(&cmnda_pll0_hs_sym_div_sel, 0x0);
+ set_field_value(&cmn_pll0_fb_div_high_ovrd_en, 0x1);
+ set_field_value(&cmnda_pll0_fb_div_high_out, 0x0E);
+ set_field_value(&cmn_pll0_fb_div_low_ovrd_en, 0x1);
+ set_field_value(&cmnda_pll0_fb_div_low_out, 0x3E);
+ set_field_value(&rx_diag_smplr_osr, 0x3);
+ set_field_value(&rx_psc_a0, 0x8BF5);
+ set_field_value(&rx_ree_pergcsm_eqenm_ph1, 0x0080);
+ set_field_value(&rx_ree_pergcsm_eqenm_ph2, 0x0080);
+ set_field_value(&vga_gain_accum_override_en, 0x1);
+ set_field_value(&vga_gain_accum_override, 0x1A);
+ set_field_value(&vga_gain_tgt_adj_override_en, 0x0);
+ set_field_value(&vga_gain_tgt_adj_override, 0x00);
+ set_field_value(&ree_gen_sm_en_usb, 0x1);
+ set_field_value(&ree_gen_sm_en_periodic, 0x1);
+ set_field_value(&ana_en_epath_gen_ctrl_sm_usb, 0x0);
+ set_field_value(&ana_en_epath_gen_ctrl_sm_periodic,
+ 0x0);
+ set_field_value(&rxda_eq_range_sel, 0x1);
+ set_field_value(&rxda_vga_sa_range_sel, 0x2);
+ switch (clk_ratio) {
+ case CLK_RATIO_1_1:
+ set_field_value(&cmn_pll_clk_osr, 0x3);
+ set_field_value(&cmn_pll_clk_div2_ratio, 0x0);
+ set_field_value(&cmn_pll_clk_div2_sel, 0x0);
+ break;
+ case CLK_RATIO_5_4:
+ set_field_value(&cmn_pll_clk_osr, 0x3);
+ set_field_value(&cmn_pll_clk_div2_ratio, 0x4);
+ set_field_value(&cmn_pll_clk_div2_sel, 0x1);
+ break;
+ case CLK_RATIO_3_2:
+ set_field_value(&cmn_pll_clk_osr, 0x3);
+ set_field_value(&cmn_pll_clk_div2_ratio, 0x5);
+ set_field_value(&cmn_pll_clk_div2_sel, 0x1);
+ break;
+ case CLK_RATIO_2_1:
+ set_field_value(&cmn_pll_clk_osr, 0x3);
+ set_field_value(&cmn_pll_clk_div2_ratio, 0x0);
+ set_field_value(&cmn_pll_clk_div2_sel, 0x3);
+ break;
+ case CLK_RATIO_1_2:
+ set_field_value(&cmn_pll_clk_osr, 0x3);
+ set_field_value(&cmn_pll_clk_div2_ratio, 0x0);
+ set_field_value(&cmn_pll_clk_div2_sel, 0x1);
+ break;
+ case CLK_RATIO_5_8:
+ set_field_value(&cmn_pll_clk_osr, 0x3);
+ set_field_value(&cmn_pll_clk_div2_ratio, 0x1);
+ set_field_value(&cmn_pll_clk_div2_sel, 0x1);
+ break;
+ case CLK_RATIO_3_4:
+ set_field_value(&cmn_pll_clk_osr, 0x3);
+ set_field_value(&cmn_pll_clk_div2_ratio, 0x2);
+ set_field_value(&cmn_pll_clk_div2_sel, 0x1);
+ break;
+ }
+ } else if (inside_f(rx_clk_freq, 75000, 150000)) {
+ set_field_value(&cmnda_pll0_ip_div, 0x1);
+ set_field_value(&cmnda_pll0_hs_sym_div_sel, 0x0);
+ set_field_value(&cmn_pll0_fb_div_high_ovrd_en, 0x1);
+ set_field_value(&cmnda_pll0_fb_div_high_out, 0x0A);
+ set_field_value(&cmn_pll0_fb_div_low_ovrd_en, 0x1);
+ set_field_value(&cmnda_pll0_fb_div_low_out, 0x1A);
+ set_field_value(&rx_diag_smplr_osr, 0x2);
+ set_field_value(&rx_psc_a0, 0x8BF5);
+ set_field_value(&rx_ree_pergcsm_eqenm_ph1, 0x0080);
+ set_field_value(&rx_ree_pergcsm_eqenm_ph2, 0x0080);
+ set_field_value(&vga_gain_accum_override_en, 0x1);
+ set_field_value(&vga_gain_accum_override, 0x1A);
+ set_field_value(&vga_gain_tgt_adj_override_en, 0x0);
+ set_field_value(&vga_gain_tgt_adj_override, 0x00);
+ set_field_value(&ree_gen_sm_en_usb, 0x1);
+ set_field_value(&ree_gen_sm_en_periodic, 0x1);
+ set_field_value(&ana_en_epath_gen_ctrl_sm_usb, 0x0);
+ set_field_value(&ana_en_epath_gen_ctrl_sm_periodic,
+ 0x0);
+ set_field_value(&rxda_eq_range_sel, 0x1);
+ set_field_value(&rxda_vga_sa_range_sel, 0x2);
+ switch (clk_ratio) {
+ case CLK_RATIO_1_1:
+ set_field_value(&cmn_pll_clk_osr, 0x2);
+ set_field_value(&cmn_pll_clk_div2_ratio, 0x0);
+ set_field_value(&cmn_pll_clk_div2_sel, 0x0);
+ break;
+ case CLK_RATIO_5_4:
+ set_field_value(&cmn_pll_clk_osr, 0x2);
+ set_field_value(&cmn_pll_clk_div2_ratio, 0x4);
+ set_field_value(&cmn_pll_clk_div2_sel, 0x1);
+ break;
+ case CLK_RATIO_3_2:
+ set_field_value(&cmn_pll_clk_osr, 0x2);
+ set_field_value(&cmn_pll_clk_div2_ratio, 0x5);
+ set_field_value(&cmn_pll_clk_div2_sel, 0x1);
+ break;
+ case CLK_RATIO_2_1:
+ set_field_value(&cmn_pll_clk_osr, 0x2);
+ set_field_value(&cmn_pll_clk_div2_ratio, 0x0);
+ set_field_value(&cmn_pll_clk_div2_sel, 0x3);
+ break;
+ case CLK_RATIO_1_2:
+ set_field_value(&cmn_pll_clk_osr, 0x2);
+ set_field_value(&cmn_pll_clk_div2_ratio, 0x0);
+ set_field_value(&cmn_pll_clk_div2_sel, 0x1);
+ break;
+ case CLK_RATIO_5_8:
+ set_field_value(&cmn_pll_clk_osr, 0x2);
+ set_field_value(&cmn_pll_clk_div2_ratio, 0x1);
+ set_field_value(&cmn_pll_clk_div2_sel, 0x1);
+ break;
+ case CLK_RATIO_3_4:
+ set_field_value(&cmn_pll_clk_osr, 0x2);
+ set_field_value(&cmn_pll_clk_div2_ratio, 0x2);
+ set_field_value(&cmn_pll_clk_div2_sel, 0x1);
+ break;
+ }
+ } else if (inside_f(rx_clk_freq, 150000, 300000)) {
+ set_field_value(&cmnda_pll0_ip_div, 0x2);
+ set_field_value(&cmnda_pll0_hs_sym_div_sel, 0x0);
+ set_field_value(&cmn_pll0_fb_div_high_ovrd_en, 0x1);
+ set_field_value(&cmnda_pll0_fb_div_high_out, 0x0A);
+ set_field_value(&cmn_pll0_fb_div_low_ovrd_en, 0x1);
+ set_field_value(&cmnda_pll0_fb_div_low_out, 0x1A);
+ set_field_value(&rx_diag_smplr_osr, 0x1);
+ set_field_value(&rx_psc_a0, 0x8BF5);
+ set_field_value(&rx_ree_pergcsm_eqenm_ph1, 0x0080);
+ set_field_value(&rx_ree_pergcsm_eqenm_ph2, 0x0080);
+ set_field_value(&vga_gain_accum_override_en, 0x1);
+ set_field_value(&vga_gain_accum_override, 0x1A);
+ set_field_value(&vga_gain_tgt_adj_override_en, 0x0);
+ set_field_value(&vga_gain_tgt_adj_override, 0x00);
+ set_field_value(&ree_gen_sm_en_usb, 0x1);
+ set_field_value(&ree_gen_sm_en_periodic, 0x1);
+ set_field_value(&ana_en_epath_gen_ctrl_sm_usb, 0x0);
+ set_field_value(&ana_en_epath_gen_ctrl_sm_periodic,
+ 0x0);
+ set_field_value(&rxda_eq_range_sel, 0x2);
+ set_field_value(&rxda_vga_sa_range_sel, 0x3);
+ switch (clk_ratio) {
+ case CLK_RATIO_1_1:
+ set_field_value(&cmn_pll_clk_osr, 0x1);
+ set_field_value(&cmn_pll_clk_div2_ratio, 0x0);
+ set_field_value(&cmn_pll_clk_div2_sel, 0x0);
+ break;
+ case CLK_RATIO_5_4:
+ set_field_value(&cmn_pll_clk_osr, 0x1);
+ set_field_value(&cmn_pll_clk_div2_ratio, 0x4);
+ set_field_value(&cmn_pll_clk_div2_sel, 0x1);
+ break;
+ case CLK_RATIO_3_2:
+ set_field_value(&cmn_pll_clk_osr, 0x1);
+ set_field_value(&cmn_pll_clk_div2_ratio, 0x5);
+ set_field_value(&cmn_pll_clk_div2_sel, 0x1);
+ break;
+ case CLK_RATIO_2_1:
+ set_field_value(&cmn_pll_clk_osr, 0x1);
+ set_field_value(&cmn_pll_clk_div2_ratio, 0x0);
+ set_field_value(&cmn_pll_clk_div2_sel, 0x3);
+ break;
+ case CLK_RATIO_1_2:
+ set_field_value(&cmn_pll_clk_osr, 0x1);
+ set_field_value(&cmn_pll_clk_div2_ratio, 0x0);
+ set_field_value(&cmn_pll_clk_div2_sel, 0x1);
+ break;
+ case CLK_RATIO_5_8:
+ set_field_value(&cmn_pll_clk_osr, 0x1);
+ set_field_value(&cmn_pll_clk_div2_ratio, 0x1);
+ set_field_value(&cmn_pll_clk_div2_sel, 0x1);
+ break;
+ case CLK_RATIO_3_4:
+ set_field_value(&cmn_pll_clk_osr, 0x1);
+ set_field_value(&cmn_pll_clk_div2_ratio, 0x2);
+ set_field_value(&cmn_pll_clk_div2_sel, 0x1);
+ break;
+ }
+ } else if (inside_f(rx_clk_freq, 300000, 340000)) {
+ set_field_value(&cmnda_pll0_ip_div, 0x3);
+ set_field_value(&cmnda_pll0_hs_sym_div_sel, 0x0);
+ set_field_value(&cmn_pll0_fb_div_high_ovrd_en, 0x1);
+ set_field_value(&cmnda_pll0_fb_div_high_out, 0x0A);
+ set_field_value(&cmn_pll0_fb_div_low_ovrd_en, 0x1);
+ set_field_value(&cmnda_pll0_fb_div_low_out, 0x10);
+ set_field_value(&rx_diag_smplr_osr, 0x0);
+ set_field_value(&rx_psc_a0, 0x8BF5);
+ set_field_value(&rx_ree_pergcsm_eqenm_ph1, 0x0080);
+ set_field_value(&rx_ree_pergcsm_eqenm_ph2, 0x0080);
+ set_field_value(&vga_gain_accum_override_en, 0x1);
+ set_field_value(&vga_gain_accum_override, 0x1A);
+ set_field_value(&vga_gain_tgt_adj_override_en, 0x0);
+ set_field_value(&vga_gain_tgt_adj_override, 0x00);
+ set_field_value(&ree_gen_sm_en_usb, 0x1);
+ set_field_value(&ree_gen_sm_en_periodic, 0x1);
+ set_field_value(&ana_en_epath_gen_ctrl_sm_usb, 0x0);
+ set_field_value(&ana_en_epath_gen_ctrl_sm_periodic,
+ 0x0);
+ set_field_value(&rxda_eq_range_sel, 0x3);
+ set_field_value(&rxda_vga_sa_range_sel, 0x3);
+ switch (clk_ratio) {
+ case CLK_RATIO_1_1:
+ set_field_value(&cmn_pll_clk_osr, 0x0);
+ set_field_value(&cmn_pll_clk_div2_ratio, 0x0);
+ set_field_value(&cmn_pll_clk_div2_sel, 0x0);
+ break;
+ case CLK_RATIO_5_4:
+ set_field_value(&cmn_pll_clk_osr, 0x0);
+ set_field_value(&cmn_pll_clk_div2_ratio, 0x4);
+ set_field_value(&cmn_pll_clk_div2_sel, 0x1);
+ break;
+ case CLK_RATIO_3_2:
+ set_field_value(&cmn_pll_clk_osr, 0x0);
+ set_field_value(&cmn_pll_clk_div2_ratio, 0x5);
+ set_field_value(&cmn_pll_clk_div2_sel, 0x1);
+ break;
+ case CLK_RATIO_2_1:
+ set_field_value(&cmn_pll_clk_osr, 0x0);
+ set_field_value(&cmn_pll_clk_div2_ratio, 0x0);
+ set_field_value(&cmn_pll_clk_div2_sel, 0x3);
+ break;
+ case CLK_RATIO_1_2:
+ set_field_value(&cmn_pll_clk_osr, 0x0);
+ set_field_value(&cmn_pll_clk_div2_ratio, 0x0);
+ set_field_value(&cmn_pll_clk_div2_sel, 0x1);
+ break;
+ case CLK_RATIO_5_8:
+ set_field_value(&cmn_pll_clk_osr, 0x0);
+ set_field_value(&cmn_pll_clk_div2_ratio, 0x1);
+ set_field_value(&cmn_pll_clk_div2_sel, 0x1);
+ break;
+ case CLK_RATIO_3_4:
+ set_field_value(&cmn_pll_clk_osr, 0x0);
+ set_field_value(&cmn_pll_clk_div2_ratio, 0x2);
+ set_field_value(&cmn_pll_clk_div2_sel, 0x1);
+ break;
+ }
+ } else
+ pr_err("TMDS clock frequency (%d KHz) is out of range\n", rx_clk_freq);
+
+ } else { /* TMDS_BIT_CLOCK_RATIO_1_40 */
+ if (inside_f(rx_clk_freq, 85000, 150000)) {
+ set_field_value(&cmnda_pll0_ip_div, 0x1);
+ set_field_value(&cmnda_pll0_hs_sym_div_sel, 0x0);
+ set_field_value(&cmn_pll0_fb_div_high_ovrd_en, 0x1);
+ set_field_value(&cmnda_pll0_fb_div_high_out, 0x0A);
+ set_field_value(&cmn_pll0_fb_div_low_ovrd_en, 0x1);
+ set_field_value(&cmnda_pll0_fb_div_low_out, 0x1A);
+ set_field_value(&rx_diag_smplr_osr, 0x0);
+ set_field_value(&rx_psc_a0, 0x8BFD);
+ set_field_value(&rx_ree_pergcsm_eqenm_ph1, 0x019F);
+ set_field_value(&rx_ree_pergcsm_eqenm_ph2, 0x019F);
+ set_field_value(&vga_gain_accum_override_en, 0x0);
+ set_field_value(&vga_gain_accum_override, 0x01);
+ set_field_value(&vga_gain_tgt_adj_override_en, 0x0);
+ set_field_value(&vga_gain_tgt_adj_override, 0x1F);
+ set_field_value(&ree_gen_sm_en_usb, 0x1);
+ set_field_value(&ree_gen_sm_en_periodic, 0x1);
+ set_field_value(&ana_en_epath_gen_ctrl_sm_usb, 0x0);
+ set_field_value(&ana_en_epath_gen_ctrl_sm_periodic, 0x1);
+ set_field_value(&rxda_eq_range_sel, 0x3);
+ set_field_value(&rxda_vga_sa_range_sel, 0x3);
+ switch (clk_ratio) {
+ case CLK_RATIO_1_1:
+ set_field_value(&cmn_pll_clk_osr, 0x00);
+ set_field_value(&cmn_pll_clk_div2_ratio, 0x0);
+ set_field_value(&cmn_pll_clk_div2_sel, 0x0);
+ break;
+ case CLK_RATIO_5_4:
+ set_field_value(&cmn_pll_clk_osr, 0x00);
+ set_field_value(&cmn_pll_clk_div2_ratio, 0x4);
+ set_field_value(&cmn_pll_clk_div2_sel, 0x1);
+ break;
+ case CLK_RATIO_3_2:
+ set_field_value(&cmn_pll_clk_osr, 0x00);
+ set_field_value(&cmn_pll_clk_div2_ratio, 0x5);
+ set_field_value(&cmn_pll_clk_div2_sel, 0x1);
+ break;
+ case CLK_RATIO_2_1:
+ set_field_value(&cmn_pll_clk_osr, 0x00);
+ set_field_value(&cmn_pll_clk_div2_ratio, 0x0);
+ set_field_value(&cmn_pll_clk_div2_sel, 0x3);
+ break;
+ case CLK_RATIO_1_2:
+ set_field_value(&cmn_pll_clk_osr, 0x00);
+ set_field_value(&cmn_pll_clk_div2_ratio, 0x0);
+ set_field_value(&cmn_pll_clk_div2_sel, 0x1);
+ break;
+ case CLK_RATIO_5_8:
+ set_field_value(&cmn_pll_clk_osr, 0x00);
+ set_field_value(&cmn_pll_clk_div2_ratio, 0x1);
+ set_field_value(&cmn_pll_clk_div2_sel, 0x1);
+ break;
+ case CLK_RATIO_3_4:
+ set_field_value(&cmn_pll_clk_osr, 0x00);
+ set_field_value(&cmn_pll_clk_div2_ratio, 0x2);
+ set_field_value(&cmn_pll_clk_div2_sel, 0x1);
+ break;
+ }
+ } else
+ pr_err("pma_pll_config() *E: TMDS clock frequency (%d kHz) is out of range\n",
+ rx_clk_freq);
+ }
+
+ vco_freq_khz =
+ (2048 * (u64) rx_clk_freq * (1 << cmn_pll_clk_osr.value) * tmds_bit_clk_ratio) / 2047;
+
+ pr_info("VCO frequency (refclk: %d kHz, TMDS clk: %d kHz, OSR: %0d, tmds_bit_clk_ratio: %d) equals %llu kHz\n",
+ REFCLK_FREQ_KHZ, rx_clk_freq, 1 << cmn_pll_clk_osr.value,
+ tmds_bit_clk_ratio, vco_freq_khz);
+
+ if (inside_f(vco_freq_khz, 3000000, 3400000 - 1000)) {
+ set_field_value(&vco_ring_select, 0x0);
+ set_field_value(&cmnda_pll0_v2i_prog, 0x0);
+ set_field_value(&cmnda_pll0_coarse_prog, 0x3);
+ switch (cmnda_pll0_fb_div_low_out.value) {
+ case 0x7E:
+ set_field_value(&cmnda_pll0_cp_gain, 0x78);
+ break;
+ case 0x3E:
+ set_field_value(&cmnda_pll0_cp_gain, 0x78);
+ break;
+ case 0x10:
+ set_field_value(&cmnda_pll0_cp_gain, 0x58);
+ break;
+ default:
+ set_field_value(&cmnda_pll0_cp_gain, 0x78);
+ }
+ set_field_value(&cmnda_pll0_const_ndac_cntrl, 0x0);
+ set_field_value(&cmnda_pll0_const_pmos_cntrl, 0x04);
+ set_field_value(&cmnda_pll0_ptat_ndac_cntrl, 0x0D);
+ } else if (inside_f(vco_freq_khz, 3400000, 3687000 - 1000)) {
+ set_field_value(&vco_ring_select, 0x1);
+ set_field_value(&cmnda_pll0_v2i_prog, 0x1);
+ set_field_value(&cmnda_pll0_coarse_prog, 0x7);
+ switch (cmnda_pll0_fb_div_low_out.value) {
+ case 0x7E:
+ set_field_value(&cmnda_pll0_cp_gain, 0x68);
+ break;
+ case 0x3E:
+ set_field_value(&cmnda_pll0_cp_gain, 0x68);
+ break;
+ case 0x10:
+ set_field_value(&cmnda_pll0_cp_gain, 0x59);
+ break;
+ default:
+ set_field_value(&cmnda_pll0_cp_gain, 0x68);
+ }
+ set_field_value(&cmnda_pll0_const_ndac_cntrl, 0x0);
+ set_field_value(&cmnda_pll0_const_pmos_cntrl, 0x8E);
+ set_field_value(&cmnda_pll0_ptat_ndac_cntrl, 0x2F);
+ } else if (inside_f(vco_freq_khz, 3687000, 3999000 - 1000)) {
+ set_field_value(&vco_ring_select, 0x1);
+ set_field_value(&cmnda_pll0_v2i_prog, 0x1);
+ set_field_value(&cmnda_pll0_coarse_prog, 0x7);
+ set_field_value(&cmnda_pll0_cp_gain, 0x64);
+ set_field_value(&cmnda_pll0_const_ndac_cntrl, 0x0);
+ set_field_value(&cmnda_pll0_const_pmos_cntrl, 0x8E);
+ set_field_value(&cmnda_pll0_ptat_ndac_cntrl, 0x2F);
+ } else if (inside_f(vco_freq_khz, 3999000, 4337000 - 1000)) {
+ set_field_value(&vco_ring_select, 0x1);
+ set_field_value(&cmnda_pll0_v2i_prog, 0x1);
+ set_field_value(&cmnda_pll0_coarse_prog, 0x7);
+ set_field_value(&cmnda_pll0_cp_gain, 0x56);
+ set_field_value(&cmnda_pll0_const_ndac_cntrl, 0x0);
+ set_field_value(&cmnda_pll0_const_pmos_cntrl, 0x8E);
+ set_field_value(&cmnda_pll0_ptat_ndac_cntrl, 0x2F);
+ } else if (inside_f(vco_freq_khz, 4337000, 4703000 - 1000)) {
+ set_field_value(&vco_ring_select, 0x1);
+ set_field_value(&cmnda_pll0_v2i_prog, 0x1);
+ set_field_value(&cmnda_pll0_coarse_prog, 0x7);
+ set_field_value(&cmnda_pll0_cp_gain, 0x58);
+ set_field_value(&cmnda_pll0_const_ndac_cntrl, 0x0);
+ set_field_value(&cmnda_pll0_const_pmos_cntrl, 0x8E);
+ set_field_value(&cmnda_pll0_ptat_ndac_cntrl, 0x2F);
+ } else if (inside_f(vco_freq_khz, 4703000, 5101000 - 1000)) {
+ set_field_value(&vco_ring_select, 0x1);
+ set_field_value(&cmnda_pll0_v2i_prog, 0x1);
+ set_field_value(&cmnda_pll0_coarse_prog, 0x7);
+ set_field_value(&cmnda_pll0_cp_gain, 0x54);
+ set_field_value(&cmnda_pll0_const_ndac_cntrl, 0x0);
+ set_field_value(&cmnda_pll0_const_pmos_cntrl, 0x04);
+ set_field_value(&cmnda_pll0_ptat_ndac_cntrl, 0x0D);
+ } else if (inside_f(vco_freq_khz, 5101000, 5532000 - 1000)) {
+ set_field_value(&vco_ring_select, 0x1);
+ set_field_value(&cmnda_pll0_v2i_prog, 0x1);
+ set_field_value(&cmnda_pll0_coarse_prog, 0x7);
+ set_field_value(&cmnda_pll0_cp_gain, 0x49);
+ set_field_value(&cmnda_pll0_const_ndac_cntrl, 0x0);
+ set_field_value(&cmnda_pll0_const_pmos_cntrl, 0x04);
+ set_field_value(&cmnda_pll0_ptat_ndac_cntrl, 0x0D);
+ } else if (inside_f(vco_freq_khz, 5532000, 6000000 - 1000)) {
+ set_field_value(&vco_ring_select, 0x1);
+ set_field_value(&cmnda_pll0_v2i_prog, 0x1);
+ set_field_value(&cmnda_pll0_coarse_prog, 0x7);
+ set_field_value(&cmnda_pll0_cp_gain, 0x3E);
+ set_field_value(&cmnda_pll0_const_ndac_cntrl, 0x0);
+ set_field_value(&cmnda_pll0_const_pmos_cntrl, 0x04);
+ set_field_value(&cmnda_pll0_ptat_ndac_cntrl, 0x0D);
+ } else
+ pr_err("%s VCO frequency (%llu KHz) is out of range\n", __func__, vco_freq_khz);
+
+ if (inside_f(vco_freq_khz, 3000000, 4000000)) {
+ set_field_value(&rxda_pi_iq_bias_trim, 0x5);
+ set_field_value(&rxda_pi_iq_pload_bias_trim, 0x2);
+ set_field_value(&rxda_pi_iq_pload_trim, 0x3F);
+ set_field_value(&rxda_pi_e_bias_trim, 0x5);
+ set_field_value(&rxda_pi_e_pload_bias_trim, 0x2);
+ set_field_value(&rxda_pi_e_pload_trim, 0x3F);
+ set_field_value(&rxda_pi_range_sel, 0x2);
+ set_field_value(&rxda_pi_cal_cm_trim, 0x00);
+ } else if (inside_f(vco_freq_khz, 4000000, 6000000)) {
+ set_field_value(&rxda_pi_iq_bias_trim, 0x5);
+ set_field_value(&rxda_pi_iq_pload_bias_trim, 0x4);
+ set_field_value(&rxda_pi_iq_pload_trim, 0x3F);
+ set_field_value(&rxda_pi_e_bias_trim, 0x5);
+ set_field_value(&rxda_pi_e_pload_bias_trim, 0x4);
+ set_field_value(&rxda_pi_e_pload_trim, 0x3F);
+ set_field_value(&rxda_pi_range_sel, 0x3);
+ set_field_value(&rxda_pi_cal_cm_trim, 0x00);
+ }
+ set_field_value(&xcvr_pll_en, 0x1);
+ set_field_value(&xcvr_link_reset_n, 0x0);
+ set_field_value(&xcvr_power_state_req, 0x0);
+ set_field_value(&iso_pma_cmn_pll0_clk_datart1_div, 0x1);
+ set_field_value(&iso_pma_cmn_pll0_clk_datart0_div, 0x2);
+ set_field_value(&iso_pma_cmn_pll0_clk_en, 0x1);
+
+ /*******************************************************
+ * Register setting
+ ********************************************************/
+
+ /* CMN_DIAG_PLL0_INCLK_CTRL */
+ reg_val = set_reg_value(cmnda_pll0_ip_div);
+ reg_val |= set_reg_value(cmnda_pll0_hs_sym_div_sel);
+ write16(state, CMN_DIAG_PLL0_INCLK_CTRL_ADDR, reg_val);
+
+ /* CMN_DIAG_PLL0_FBH_OVRD */
+ reg_val = set_reg_value(cmn_pll0_fb_div_high_ovrd_en);
+ reg_val |= set_reg_value(cmnda_pll0_fb_div_high_out);
+ write16(state, CMN_DIAG_PLL0_FBH_OVRD_ADDR, reg_val);
+
+ /* CMN_DIAG_PLL0_FBL_OVRD */
+ reg_val = set_reg_value(cmn_pll0_fb_div_low_ovrd_en);
+ reg_val |= set_reg_value(cmnda_pll0_fb_div_low_out);
+ write16(state, CMN_DIAG_PLL0_FBL_OVRD_ADDR, reg_val);
+
+ /* CMN_PLL0_DIV2SEL_OSR_CTRL */
+ reg_val = set_reg_value(cmn_pll_clk_osr);
+ reg_val |= set_reg_value(cmn_pll_clk_div2_ratio);
+ reg_val |= set_reg_value(cmn_pll_clk_div2_sel);
+ write16(state, CMN_PLL0_DIV2SEL_OSR_CTRL_ADDR, reg_val);
+
+ /* RX_DIAG_SMPLR_OSR */
+ reg_val = set_reg_value(rx_diag_smplr_osr);
+ multi_write16(state, RX_DIAG_SMPLR_OSR_ADDR, reg_val);
+
+ /* RX_PSC_A0 */
+ reg_val = set_reg_value(rx_psc_a0);
+ multi_write16(state, RX_PSC_A0_ADDR, reg_val);
+
+ /* RX_REE_PERGCSM_EQENM_PH1 */
+ reg_val = set_reg_value(rx_ree_pergcsm_eqenm_ph1);
+ multi_write16(state, RX_REE_PERGCSM_EQENM_PH1_ADDR, reg_val);
+
+ /* RX_REE_PERGCSM_EQENM_PH1 */
+ reg_val = set_reg_value(rx_ree_pergcsm_eqenm_ph2);
+ multi_write16(state, RX_REE_PERGCSM_EQENM_PH2_ADDR, reg_val);
+
+ /* RX_REE_VGA_GAIN_OVRD */
+ reg_val = set_reg_value(vga_gain_accum_override_en);
+ reg_val |= set_reg_value(vga_gain_accum_override);
+ reg_val |= set_reg_value(vga_gain_tgt_adj_override_en);
+ reg_val |= set_reg_value(vga_gain_tgt_adj_override);
+ multi_write16(state, RX_REE_VGA_GAIN_OVRD_ADDR, reg_val);
+
+ /* RX_REE_SMGM_CTRL1 */
+ reg_val = set_reg_value(ree_gen_sm_en_usb);
+ reg_val |= set_reg_value(ree_gen_sm_en_periodic);
+ reg_val |= set_reg_value(ana_en_epath_gen_ctrl_sm_usb);
+ reg_val |= set_reg_value(ana_en_epath_gen_ctrl_sm_periodic);
+ multi_write16(state, RX_REE_SMGM_CTRL1_ADDR, reg_val);
+
+ /* RX_DIAG_DFE_CTRL2 */
+ reg_val = set_reg_value(rxda_eq_range_sel);
+ reg_val |= set_reg_value(rxda_vga_sa_range_sel);
+ multi_write16(state, RX_DIAG_DFE_CTRL2_ADDR, reg_val);
+
+ /* CMN_PLLSM0_USER_DEF_CTRL */
+ reg_val = set_reg_value(vco_ring_select);
+ write16(state, CMN_PLLSM0_USER_DEF_CTRL_ADDR, reg_val);
+
+ /* CMN_DIAG_PLL0_V2I_TUNE */
+ reg_val = set_reg_value(cmnda_pll0_v2i_prog);
+ reg_val |= set_reg_value(cmnda_pll0_coarse_prog);
+ write16(state, CMN_DIAG_PLL0_V2I_TUNE_ADDR, reg_val);
+
+ /* CMN_DIAG_PLL0_CP_TUNE */
+ reg_val = set_reg_value(cmnda_pll0_cp_gain);
+ write16(state, CMN_DIAG_PLL0_CP_TUNE_ADDR, reg_val);
+
+ /* CMN_DIAG_PLL0_PTATIS_TUNE1 */
+ reg_val = set_reg_value(cmnda_pll0_const_ndac_cntrl);
+ reg_val |= set_reg_value(cmnda_pll0_const_pmos_cntrl);
+ write16(state, CMN_DIAG_PLL0_PTATIS_TUNE1_ADDR, reg_val);
+
+ /* CMN_DIAG_PLL0_PTATIS_TUNE2 */
+ reg_val = set_reg_value(cmnda_pll0_ptat_ndac_cntrl);
+ write16(state, CMN_DIAG_PLL0_PTATIS_TUNE2_ADDR, reg_val);
+
+ /* RX_DIAG_ILL_IQ_TRIM0 */
+ reg_val = set_reg_value(rxda_pi_iq_bias_trim);
+ reg_val |= set_reg_value(rxda_pi_iq_pload_bias_trim);
+ reg_val |= set_reg_value(rxda_pi_iq_pload_trim);
+ write16(state, RX_DIAG_ILL_IQ_TRIM0_ADDR, reg_val);
+
+ /* RX_DIAG_ILL_E_TRIM0 */
+ reg_val = set_reg_value(rxda_pi_e_bias_trim);
+ reg_val |= set_reg_value(rxda_pi_e_pload_bias_trim);
+ reg_val |= set_reg_value(rxda_pi_e_pload_trim);
+ write16(state, RX_DIAG_ILL_E_TRIM0_ADDR, reg_val);
+
+ /* RX_DIAG_ILL_IQE_TRIM2 */
+ reg_val = set_reg_value(rxda_pi_range_sel);
+ reg_val |= set_reg_value(rxda_pi_cal_cm_trim);
+ write16(state, RX_DIAG_ILL_IQE_TRIM2_ADDR, reg_val);
+
+ /* Enable PLL */
+ /* PHY_MODE_CTL */
+ reg_val = set_reg_value(xcvr_pll_en);
+ reg_val |= set_reg_value(xcvr_link_reset_n);
+ reg_val |= set_reg_value(xcvr_power_state_req);
+ write16(state, PHY_MODE_CTL_ADDR, reg_val);
+
+ /* Wait for PLL0 ready: */
+ /* PHY_PMA_CMN_CTRL2 */
+ for (i = 0; i < 20; i++) {
+ if (read16(state, PHY_PMA_CMN_CTRL2_ADDR) & (1 << 0))
+ break;
+ msleep(10);
+ }
+ if (i == 20) {
+ pr_err("pma_pll_ready failed\n");
+ return -1;
+ }
+
+ /* Turn on output clocks: */
+ /* PHY_PMA_CMN_CTRL2 */
+ reg_val = set_reg_value(iso_pma_cmn_pll0_clk_datart1_div);
+ reg_val |= set_reg_value(iso_pma_cmn_pll0_clk_datart0_div);
+ reg_val |= set_reg_value(iso_pma_cmn_pll0_clk_en);
+ write16(state, PHY_PMA_CMN_CTRL2_ADDR, reg_val);
+
+ if (data_rate_change) {
+ pr_info("pma_pll_config() Disable Rx Eq Training\n");
+ for (i = 0; i < 3; i++) {
+ reg_val =
+ read16(state, PHY_PMA_XCVR_CTRL_ADDR | (i << 6));
+ reg_val &= 0xFFEF;
+ write16(state, PHY_PMA_XCVR_CTRL_ADDR | (i << 6), reg_val);
+ }
+ }
+ /* Get current power state: */
+ /* PHY_MODE_CTL */
+ reg_val = read16(state, PHY_MODE_CTL_ADDR);
+ reg_val &= 0x00F0;
+ pr_info("pma_pll_config() Current power state: 0x%02X\n", (reg_val >> 4));
+
+ /* Deassert link reset: */
+ /* PHY_MODE_CTL */
+ pr_info("pma_pll_config() Deassert link reset\n");
+ set_field_value(&xcvr_link_reset_n, 0x1);
+ reg_val |= set_reg_value(xcvr_pll_en);
+ reg_val |= set_reg_value(xcvr_link_reset_n);
+ write16(state, PHY_MODE_CTL_ADDR, reg_val);
+
+ /* Wait for xcvr_psm_ready for all the lanes */
+ loop = 0;
+ do {
+ reg_val = (1 << 13);
+ for (i = 0; i < 3; i++) {
+ reg_val &= read16(state, PHY_PMA_XCVR_CTRL_ADDR | (i << 6)) & (1 << 13);
+ pr_info("pma_pll_config() xcvr_psm_ready(%0d): 0x%0X\n", i, reg_val >> 13);
+ }
+ msleep(10);
+ loop++;
+ } while (!reg_val && loop < 20);
+ /* Timeout */
+ if (loop == 20) {
+ pr_err("pma_pll_config() Waiting for xcvr_psm_ready... failed\n");
+ return -1;
+ }
+
+ /* Set A0 power state: */
+ /* PHY_MODE_CTL */
+ set_field_value(&xcvr_power_state_req, 0x1);
+ reg_val = set_reg_value(xcvr_pll_en);
+ reg_val |= set_reg_value(xcvr_link_reset_n);
+ reg_val |= set_reg_value(xcvr_power_state_req);
+ write16(state, PHY_MODE_CTL_ADDR, reg_val);
+ pr_info("pma_pll_config() Requested A0 power mode\n");
+
+ /* Wait for A0 power mode acknowledged: */
+ /* PHY_MODE_CTL */
+ set_field_value(&xcvr_power_state_ack, 0x1);
+
+ for (i = 0; i < 20; i++) {
+ if (((read16(state, PHY_MODE_CTL_ADDR) & 0x00F0) == set_reg_value(xcvr_power_state_ack)))
+ break;
+ msleep(10);
+ }
+ if (i == 20) {
+ pr_err("Waiting for A0 power mode acknowledged failed\n");
+ return -1;
+ }
+
+ if (data_rate_change) {
+ pr_info("pma_pll_config() Enable Rx Eq Training\n");
+ for (i = 0; i < 3; i++) {
+ reg_val =
+ read16(state, PHY_PMA_XCVR_CTRL_ADDR | (i << 6));
+ reg_val |= 0x0010;
+ write16(state, PHY_PMA_XCVR_CTRL_ADDR | (i << 6),
+ reg_val);
+ }
+ }
+ return 0;
+}
+
+clk_ratio_t clk_ratio_detect(state_struct *state,
+ u32 rx_clk_freq, /* khz */
+ u32 pxl_clk_freq, /* khz */
+ u8 vic,
+ pixel_encoding_t pixel_encoding,
+ tmds_bit_clock_ratio_t tmds_bit_clk_ratio)
+{
+ clk_ratio_t clk_ratio_detected = CLK_RATIO_1_1;
+
+ u64 tmds_freq_nominal_1_1, tmds_freq_nominal_1_1_min,
+ tmds_freq_nominal_1_1_max;
+ u64 tmds_freq_nominal_5_4, tmds_freq_nominal_5_4_min,
+ tmds_freq_nominal_5_4_max;
+ u64 tmds_freq_nominal_3_2, tmds_freq_nominal_3_2_min,
+ tmds_freq_nominal_3_2_max;
+ u64 tmds_freq_nominal_2_1, tmds_freq_nominal_2_1_min,
+ tmds_freq_nominal_2_1_max;
+ u64 tmds_freq_nominal_1_2, tmds_freq_nominal_1_2_min,
+ tmds_freq_nominal_1_2_max;
+ u64 tmds_freq_nominal_5_8, tmds_freq_nominal_5_8_min,
+ tmds_freq_nominal_5_8_max;
+ u64 tmds_freq_nominal_3_4, tmds_freq_nominal_3_4_min,
+ tmds_freq_nominal_3_4_max;
+ u64 min, max;
+
+ /* Check the TMDS/pixel clock ratio. */
+ pr_info("VIC %0d, pixel encoding: %0d, TMDS bit clock ratio: %0d and TMDS clk %d KHz\n",
+ vic, pixel_encoding, tmds_bit_clk_ratio, rx_clk_freq);
+
+ tmds_freq_nominal_1_1 = pxl_clk_freq;
+
+ min = 990;
+ max = 1010;
+
+ tmds_freq_nominal_5_4 = tmds_freq_nominal_1_1;
+ tmds_freq_nominal_3_2 = tmds_freq_nominal_1_1;
+ tmds_freq_nominal_2_1 = tmds_freq_nominal_1_1;
+ tmds_freq_nominal_1_2 = tmds_freq_nominal_1_1;
+ tmds_freq_nominal_5_8 = tmds_freq_nominal_1_1;
+ tmds_freq_nominal_3_4 = tmds_freq_nominal_1_1;
+
+ /* Exclude some of the clock ratios based on pixel excoding */
+ switch (pixel_encoding) {
+ case PIXEL_ENCODING_YUV422:
+ tmds_freq_nominal_5_4 = 0;
+ tmds_freq_nominal_3_2 = 0;
+ tmds_freq_nominal_2_1 = 0;
+ tmds_freq_nominal_1_2 = 0;
+ tmds_freq_nominal_5_8 = 0;
+ tmds_freq_nominal_3_4 = 0;
+ break;
+ case PIXEL_ENCODING_YUV420:
+ tmds_freq_nominal_5_4 = 0;
+ tmds_freq_nominal_3_2 = 0;
+ tmds_freq_nominal_2_1 = 0;
+ break;
+ default: /* RGB/YUV444 */
+ tmds_freq_nominal_1_2 = 0;
+ tmds_freq_nominal_5_8 = 0;
+ tmds_freq_nominal_3_4 = 0;
+ }
+
+ tmds_freq_nominal_1_1_min =
+ min * tmds_freq_nominal_1_1 * 10 * 1 / (tmds_bit_clk_ratio * 1000 * 1);
+ tmds_freq_nominal_1_1_max =
+ max * tmds_freq_nominal_1_1 * 10 * 1 / (tmds_bit_clk_ratio * 1000 * 1);
+ tmds_freq_nominal_5_4_min =
+ min * tmds_freq_nominal_5_4 * 10 * 5 / (tmds_bit_clk_ratio * 1000 * 4);
+ tmds_freq_nominal_5_4_max =
+ max * tmds_freq_nominal_5_4 * 10 * 5 / (tmds_bit_clk_ratio * 1000 * 4);
+ tmds_freq_nominal_3_2_min =
+ min * tmds_freq_nominal_3_2 * 10 * 3 / (tmds_bit_clk_ratio * 1000 * 2);
+ tmds_freq_nominal_3_2_max =
+ max * tmds_freq_nominal_3_2 * 10 * 3 / (tmds_bit_clk_ratio * 1000 * 2);
+ tmds_freq_nominal_2_1_min =
+ min * tmds_freq_nominal_2_1 * 10 * 2 / (tmds_bit_clk_ratio * 1000 * 1);
+ tmds_freq_nominal_2_1_max =
+ max * tmds_freq_nominal_2_1 * 10 * 2 / (tmds_bit_clk_ratio * 1000 * 1);
+ tmds_freq_nominal_1_2_min =
+ min * tmds_freq_nominal_1_2 * 10 * 1 / (tmds_bit_clk_ratio * 1000 * 2);
+ tmds_freq_nominal_1_2_max =
+ max * tmds_freq_nominal_1_2 * 10 * 1 / (tmds_bit_clk_ratio * 1000 * 2);
+ tmds_freq_nominal_5_8_min =
+ min * tmds_freq_nominal_5_8 * 10 * 5 / (tmds_bit_clk_ratio * 1000 * 8);
+ tmds_freq_nominal_5_8_max =
+ max * tmds_freq_nominal_5_8 * 10 * 5 / (tmds_bit_clk_ratio * 1000 * 8);
+ tmds_freq_nominal_3_4_min =
+ min * tmds_freq_nominal_3_4 * 10 * 3 / (tmds_bit_clk_ratio * 1000 * 4);
+ tmds_freq_nominal_3_4_max =
+ max * tmds_freq_nominal_3_4 * 10 * 3 / (tmds_bit_clk_ratio * 1000 * 4);
+
+ if (rx_clk_freq > tmds_freq_nominal_1_1_min
+ && rx_clk_freq < tmds_freq_nominal_1_1_max) {
+ clk_ratio_detected = CLK_RATIO_1_1;
+ pr_info("Detected TMDS/pixel clock ratio of 1:1\n");
+ } else if (rx_clk_freq > tmds_freq_nominal_5_4_min
+ && rx_clk_freq < tmds_freq_nominal_5_4_max) {
+ clk_ratio_detected = CLK_RATIO_5_4;
+ pr_info("Detected TMDS/pixel clock ratio of 5:4\n");
+ } else if (rx_clk_freq > tmds_freq_nominal_3_2_min
+ && rx_clk_freq < tmds_freq_nominal_3_2_max) {
+ clk_ratio_detected = CLK_RATIO_3_2;
+ pr_info("Detected TMDS/pixel clock ratio of 3:2\n");
+ } else if (rx_clk_freq > tmds_freq_nominal_2_1_min
+ && rx_clk_freq < tmds_freq_nominal_2_1_max) {
+ clk_ratio_detected = CLK_RATIO_2_1;
+ pr_info("Detected TMDS/pixel clock ratio of 2:1\n");
+ } else if (rx_clk_freq > tmds_freq_nominal_1_2_min
+ && rx_clk_freq < tmds_freq_nominal_1_2_max) {
+ clk_ratio_detected = CLK_RATIO_1_2;
+ pr_info("Detected TMDS/pixel clock ratio of 1:2\n");
+ } else if (rx_clk_freq > tmds_freq_nominal_5_8_min
+ && rx_clk_freq < tmds_freq_nominal_5_8_max) {
+ clk_ratio_detected = CLK_RATIO_5_8;
+ pr_info("Detected TMDS/pixel clock ratio of 5:8\n");
+ } else if (rx_clk_freq > tmds_freq_nominal_3_4_min
+ && rx_clk_freq < tmds_freq_nominal_3_4_max) {
+ clk_ratio_detected = CLK_RATIO_3_4;
+ pr_info("Detected TMDS/pixel clock ratio of 3:4\n");
+ } else {
+ pr_err("Failed to detected TMDS/pixel clock ratio\n");
+ pr_err("VIC: %02d and TMDS clock of %d KHz\n", vic, rx_clk_freq);
+ }
+
+ return clk_ratio_detected;
+}
diff --git a/drivers/media/platform/imx8/hdmi/API_AFE_ss28fdsoi_hdmirx.h b/drivers/media/platform/imx8/hdmi/API_AFE_ss28fdsoi_hdmirx.h
new file mode 100644
index 000000000000..f4a06d2bcc37
--- /dev/null
+++ b/drivers/media/platform/imx8/hdmi/API_AFE_ss28fdsoi_hdmirx.h
@@ -0,0 +1,142 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2016-2017 Cadence Design Systems, Inc.
+ * All rights reserved worldwide.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 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.
+ *
+ * Copyright 2018 NXP
+ *
+ ******************************************************************************
+ *
+ * API_AFE_ss28fdsoi_hdmirx.h
+ *
+ ******************************************************************************
+ */
+
+#ifndef API_AFE_SS28FDSOI_HDMIRX_H_
+#define API_AFE_SS28FDSOI_HDMIRX_H_
+
+#include <linux/io.h>
+#include "../../../../mxc/hdp/all.h"
+
+#define REFCLK_FREQ_KHZ 24000
+#define LINK_WRITE 0x2000
+#define LINK_ID 0x0
+
+#define CMN_PLLSM0_PLLEN_TMR_ADDR 0x0029
+#define CMN_PLLSM0_PLLPRE_TMR_ADDR 0x002A
+#define CMN_PLLSM0_PLLVREF_TMR_ADDR 0x002B
+#define CMN_PLLSM0_PLLLOCK_TMR_ADDR 0x002C
+#define CMN_PLLSM0_USER_DEF_CTRL_ADDR 0x002F
+#define CMN_PLL0_VCOCAL_CTRL_ADDR 0x0080
+#define CMN_PLL0_VCOCAL_OVRD_ADDR 0x0083
+#define CMN_PLL0_LOCK_REFCNT_START_ADDR 0x0090
+#define CMN_PLL0_LOCK_PLLCNT_START_ADDR 0x0092
+#define CMN_PLL0_DIV2SEL_OSR_CTRL_ADDR 0x009B
+#define CMN_ICAL_CTRL_ADDR 0x00C0
+#define CMN_ICAL_OVRD_ADDR 0x00C1
+#define CMN_RXCAL_CTRL_ADDR 0x00D0
+#define CMN_RXCAL_OVRD_ADDR 0x00D1
+#define CMN_RXCAL_INIT_TMR_ADDR 0x00D4
+#define CMN_TXPUCAL_OVRD_ADDR 0x00E1
+#define CMN_TXPDCAL_OVRD_ADDR 0x00F1
+#define CMN_CMSMT_CLK_FREQ_MSMT_CTRL_ADDR 0x01A0
+#define CMN_CMSMT_REF_CLK_TMR_VALUE_ADDR 0x01A2
+#define CMN_CMSMT_TEST_CLK_CNT_VALUE_ADDR 0x01A3
+#define CMN_DIAG_PLL0_FBH_OVRD_ADDR 0x01C0
+#define CMN_DIAG_PLL0_FBL_OVRD_ADDR 0x01C1
+#define CMN_DIAG_PLL0_TEST_MODE_ADDR 0x01C4
+#define CMN_DIAG_PLL0_INCLK_CTRL_ADDR 0x01CA
+#define CMN_DIAG_PLL0_V2I_TUNE_ADDR 0x01C5
+#define CMN_DIAG_PLL0_CP_TUNE_ADDR 0x01C6
+#define CMN_DIAG_PLL0_PTATIS_TUNE1_ADDR 0x01C8
+#define CMN_DIAG_PLL0_PTATIS_TUNE2_ADDR 0x01C9
+#define XCVR_PSM_CAL_TMR_ADDR 0x4002
+#define XCVR_PSM_A0IN_TMR_ADDR 0x4003
+#define XCVR_DIAG_RX_LANE_CAL_RST_TMR_ADDR 0x40EA
+#define TX_ANA_CTRL_REG_1_ADDR 0x5020
+#define TX_ANA_CTRL_REG_2_ADDR 0x5021
+#define TX_DIG_CTRL_REG_1_ADDR 0x5023
+#define TX_DIG_CTRL_REG_2_ADDR 0x5024
+#define TXDA_CYA_AUXDA_CYA_ADDR 0x5025
+#define TX_ANA_CTRL_REG_3_ADDR 0x5026
+#define TX_ANA_CTRL_REG_4_ADDR 0x5027
+#define TX_ANA_CTRL_REG_5_ADDR 0x5029
+#define RX_PSC_A0_ADDR 0x8000
+#define RX_IQPI_ILL_CAL_OVRD_ADDR 0x8023
+#define RX_EPI_ILL_CAL_OVRD_ADDR 0x8033
+#define RX_SLC_CTRL_ADDR 0x80E0
+#define RX_REE_PERGCSM_EQENM_PH1_ADDR 0x8179
+#define RX_REE_PERGCSM_EQENM_PH2_ADDR 0x817A
+#define RX_REE_VGA_GAIN_OVRD_ADDR 0x81AD
+#define RX_REE_SMGM_CTRL1_ADDR 0x81BD
+#define RX_DIAG_ILL_IQ_TRIM0_ADDR 0x81C1
+#define RX_DIAG_ILL_E_TRIM0_ADDR 0x81C2
+#define RX_DIAG_ILL_IQE_TRIM2_ADDR 0x81C5
+#define RX_DIAG_DFE_CTRL2_ADDR 0x81D4
+#define RX_DIAG_SC2C_DELAY_ADDR 0x81E1
+#define RX_DIAG_SMPLR_OSR_ADDR 0x81E2
+#define RX_CLK_SLICER_CAL_OVRD_ADDR 0x8621
+#define RX_CLK_SLICER_CAL_INIT_TMR_ADDR 0x8624
+#define PHY_MODE_CTL_ADDR 0xC008
+#define PHY_PMA_CMN_CTRL1_ADDR 0xC800
+#define PHY_PMA_CMN_CTRL2_ADDR 0xC801
+#define PHY_PMA_SSM_STATE_ADDR 0xC802
+#define PHY_PMA_PLL_SM_STATE_ADDR 0xC803
+#define PHY_PMA_XCVR_CTRL_ADDR 0xCC00
+
+typedef enum {
+ TMDS_BIT_CLOCK_RATIO_1_10 = 10,
+ TMDS_BIT_CLOCK_RATIO_1_40 = 40
+} tmds_bit_clock_ratio_t;
+
+typedef enum {
+ PIXEL_ENCODING_RGB = 0,
+ PIXEL_ENCODING_YUV422 = 1,
+ PIXEL_ENCODING_YUV444 = 2,
+ PIXEL_ENCODING_YUV420 = 3,
+} pixel_encoding_t;
+
+void speedup_config(state_struct *state);
+void arc_config(state_struct *state);
+void pma_config(state_struct *state);
+int pma_cmn_ready(state_struct *state);
+int pma_rx_clk_signal_detect(state_struct *state);
+int pma_rx_clk_freq_detect(state_struct *state);
+void pre_data_rate_change(state_struct *state);
+int pma_pll_config(state_struct *state, u32, clk_ratio_t, tmds_bit_clock_ratio_t, unsigned char);
+clk_ratio_t clk_ratio_detect(state_struct *state, u32, u32, u8, pixel_encoding_t, tmds_bit_clock_ratio_t);
+void phy_status(state_struct *state);
+
+#endif
diff --git a/drivers/media/platform/imx8/hdmi/Kconfig b/drivers/media/platform/imx8/hdmi/Kconfig
new file mode 100644
index 000000000000..ed2736f82de3
--- /dev/null
+++ b/drivers/media/platform/imx8/hdmi/Kconfig
@@ -0,0 +1,4 @@
+config IMX8_HDMI_RX
+ tristate "IMX8 HDMI RX Controller"
+ select MX8_HDP_RX
+ default y
diff --git a/drivers/media/platform/imx8/hdmi/Makefile b/drivers/media/platform/imx8/hdmi/Makefile
new file mode 100644
index 000000000000..93c0b3f44d72
--- /dev/null
+++ b/drivers/media/platform/imx8/hdmi/Makefile
@@ -0,0 +1,2 @@
+obj-$(CONFIG_IMX8_HDMI_RX) += mxc-hdmi-rx.o mxc-hdmi-hw.o API_AFE_ss28fdsoi_hdmirx.o \
+ mxc-hdmi-rx-audio.o
diff --git a/drivers/media/platform/imx8/hdmi/mxc-hdmi-hw.c b/drivers/media/platform/imx8/hdmi/mxc-hdmi-hw.c
new file mode 100644
index 000000000000..3fef1f146248
--- /dev/null
+++ b/drivers/media/platform/imx8/hdmi/mxc-hdmi-hw.c
@@ -0,0 +1,523 @@
+/*
+ * Copyright 2018 NXP
+ *
+ * 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 "API_AFE_ss28fdsoi_hdmirx.h"
+#include "mxc-hdmi-rx.h"
+
+u8 block0[128] = {
+ 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00,
+ 0x3B, 0x10, 0xFD, 0x5A, 0x9B, 0x5F, 0x02, 0x00,
+ 0x19, 0x1C, 0x01, 0x04, 0xB3, 0x3C, 0x22, 0x78,
+ 0x9F, 0x30, 0x35, 0xA7, 0x55, 0x4E, 0xA3, 0x26,
+ 0x0F, 0x50, 0x54, 0x20, 0x00, 0x00, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00,
+ 0x00, 0xFC, 0x00, 0x69, 0x4D, 0x58, 0x38, 0x51,
+ 0x4D, 0x20, 0x48, 0x44, 0x4D, 0x49, 0x52, 0x58,
+ 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x00, 0x28,
+ 0x3D, 0x87, 0x87, 0x1E, 0x01, 0x0A, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0x10,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x64
+};
+
+u8 block1[128] = {
+ 0x02, 0x03, 0x13, 0x71, 0x46, 0x90, 0x04, 0x03,
+ 0x5D, 0x1F, 0x22, 0x23, 0x09, 0x07, 0x07, 0x83,
+ 0x01, 0x00, 0x00, 0x04, 0x74, 0x00, 0x30, 0xF2,
+ 0x70, 0x5A, 0x80, 0xB0, 0x58, 0x8A, 0x00, 0x20,
+ 0xC2, 0x31, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x97
+};
+
+S_HDMI_SCDC_SET_MSG scdcExampleData = {
+ .sink_ver = 6,
+ .manufacturer_oui_1 = 0x1,
+ .manufacturer_oui_2 = 0x2,
+ .manufacturer_oui_3 = 0x3,
+ .devId = {1, 2, 3, 4, 5, 6, 7, 8},
+ .hardware_major_rev = 12,
+ .hardware_minor_rev = 13,
+ .software_major_rev = 0xAB,
+ .software_minor_rev = 0XBC,
+ .manufacturerSpecific = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
+ 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34}
+};
+
+int hdmi_infoframe_poll(state_struct *state)
+{
+ GENERAL_Read_Register_response regresp;
+ struct mxc_hdmi_rx_dev *hdmi_rx = state_to_mxc_hdmirx(state);
+ u32 regread;
+ u32 i;
+
+ /* Unmask "AVI InfoFrame received" interrupt */
+ CDN_API_General_Write_Register_blocking(state,
+ ADDR_SINK_MHL_HD + (TMDS_MHL_HD_INT_MASK << 2),
+ F_TMDS_MHL_HD_MASK(0xFD));
+
+ /* Unmask "tmds_mhl_hd_int" interrupt */
+ CDN_API_General_Write_Register_blocking(state,
+ ADDR_SINK_MHL_HD + (MHL_HD_INT_MASK << 2),
+ F_MHL_HD_INT_MASK(0xE));
+
+ /* MHL_HD_INT_STAT */
+ CDN_API_General_Read_Register_blocking(state,
+ ADDR_SINK_MHL_HD + (MHL_HD_INT_STAT << 2), &regresp);
+ for (i = 0; i < 5; i++) {
+ if (regresp.val & (1 << 0))
+ break;
+ else
+ CDN_API_General_Read_Register_blocking(state,
+ ADDR_SINK_MHL_HD + (MHL_HD_INT_STAT << 2), &regresp);
+ msleep(20);
+ }
+ if (i == 5) {
+ dev_err(&hdmi_rx->pdev->dev, "Waiting for tmds_mhl_hd_int...failed!\n");
+ return -1;
+ } else
+ dev_dbg(&hdmi_rx->pdev->dev, "Waiting for tmds_mhl_hd_int...DONE\n");
+
+ /* Mask "AVI InfoFrame received" interrupt */
+ CDN_API_General_Write_Register_blocking(state,
+ ADDR_SINK_MHL_HD + (TMDS_MHL_HD_INT_MASK << 2),
+ F_TMDS_MHL_HD_MASK(0xFF));
+
+ /* Mask "tmds_mhl_hd_int" interrupt */
+ CDN_API_General_Write_Register_blocking(state,
+ ADDR_SINK_MHL_HD + (MHL_HD_INT_MASK << 2),
+ F_MHL_HD_INT_MASK(0xF));
+
+ /* Read back TMDS_MHL_HD_INT_STAT to clear the interrupt */
+ CDN_API_General_Read_Register_blocking(state,
+ ADDR_SINK_MHL_HD + (TMDS_MHL_HD_INT_STAT << 2),
+ &regresp);
+
+ /* Packet 0 read request */
+ cdn_apb_write(state, ADDR_SINK_PIF + (PKT_INFO_CTRL << 2),
+ F_PACKET_RDN_WR(0x0) | F_PACKET_NUM(0x0));
+
+ /* Wait for pkt_host_rdy_status */
+ cdn_apb_read(state, ADDR_SINK_PIF + (PKT_INT_STATUS << 2), &regread);
+ for (i = 0; i < 5; i++) {
+ if (regread & (1 << 16))
+ break;
+ else
+ cdn_apb_read(state, ADDR_SINK_PIF + (PKT_INT_STATUS << 2), &regread);
+ msleep(20);
+ }
+ if (i == 5) {
+ dev_err(&hdmi_rx->pdev->dev, "Waiting for packet data available for reading...FAILED!\n");
+ return -1;
+ } else
+ dev_dbg(&hdmi_rx->pdev->dev, "Waiting for packet data available for reading...DONE\n");
+
+ return 0;
+}
+
+/* Exemplary code to configure the controller */
+/* for the AVI_InfoFrame reception */
+static int get_avi_infoframe(state_struct *state)
+{
+ struct mxc_hdmi_rx_dev *hdmi_rx = state_to_mxc_hdmirx(state);
+ GENERAL_Read_Register_response regresp;
+ int ret;
+
+ dev_dbg(&hdmi_rx->pdev->dev, "%s\n", __func__);
+ /* Get VIC code and pixel encoding */
+ ret = hdmi_infoframe_poll(state);
+ if (ret < 0)
+ return -1;
+
+ CDN_API_General_Read_Register_blocking(state, ADDR_SINK_MHL_HD + (PKT_AVI_DATA_LOW << 2), &regresp);
+ hdmi_rx->vic_code = (regresp.val & 0xFF000000) >> 24;
+ hdmi_rx->pixel_encoding = (regresp.val & 0x00000060) >> 5;
+ return 0;
+}
+
+static int get_vendor_infoframe(state_struct *state)
+{
+ struct mxc_hdmi_rx_dev *hdmi_rx = state_to_mxc_hdmirx(state);
+ u32 regread;
+ int ret;
+
+ dev_dbg(&hdmi_rx->pdev->dev, "%s\n", __func__);
+ /* Set info_type1 to vendor Info Frame */
+ cdn_apb_write(state, ADDR_SINK_PIF + (PKT_INFO_TYPE_CFG1 << 2),
+ F_INFO_TYPE1(0x81));
+
+ ret = hdmi_infoframe_poll(state);
+ if (ret < 0)
+ return -1;
+
+ /* Get IEEE OUI */
+ cdn_apb_read(state, ADDR_SINK_PIF + (PKT_INFO_DATA1 << 2), &regread);
+ if (regread >> 8 == 0x000c03)
+ dev_info(&hdmi_rx->pdev->dev, "HDMI 1.4b Vendor Specific Infoframe\n");
+ else if (regread >> 8 == 0xC45DD8)
+ dev_info(&hdmi_rx->pdev->dev, "HDMI 2.0 Vendor Specific Infoframe\n");
+ else
+ dev_err(&hdmi_rx->pdev->dev,
+ "Error Vendro Infoframe IEEE OUI=0x%6X\n", regread >> 8);
+
+ /* Get HDMI Video format */
+ cdn_apb_read(state, ADDR_SINK_PIF + (PKT_INFO_DATA2 << 2), &regread);
+
+ /* Extened resoluction format */
+ if (((regread >> 5) & 0x0000007) == 1) {
+ hdmi_rx->hdmi_vic = (regread >> 8) & 0xff;
+ dev_info(&hdmi_rx->pdev->dev, "hdmi_vic=%d\n", hdmi_rx->hdmi_vic);
+ }
+
+ /* Clear info_type1 */
+ cdn_apb_write(state, ADDR_SINK_PIF + (PKT_INFO_TYPE_CFG1 << 2),
+ F_INFO_TYPE1(0x00));
+
+ return 0;
+}
+
+static void get_color_depth(struct mxc_hdmi_rx_dev *hdmi_rx,
+ clk_ratio_t clk_ratio)
+{
+ u8 pixel_encoding = hdmi_rx->pixel_encoding;
+
+ hdmi_rx->color_depth = 8;
+
+ switch (pixel_encoding) {
+ case PIXEL_ENCODING_YUV422:
+ switch (clk_ratio) {
+ case CLK_RATIO_1_1:
+ hdmi_rx->color_depth = 8;
+ break;
+ case CLK_RATIO_5_4:
+ case CLK_RATIO_3_2:
+ case CLK_RATIO_2_1:
+ case CLK_RATIO_1_2:
+ case CLK_RATIO_5_8:
+ case CLK_RATIO_3_4:
+ default:
+ pr_err("YUV422 Not supported clk ration\n");
+ }
+ break;
+ case PIXEL_ENCODING_YUV420:
+ switch (clk_ratio) {
+ case CLK_RATIO_1_1:
+ hdmi_rx->color_depth = 16;
+ break;
+ case CLK_RATIO_1_2:
+ hdmi_rx->color_depth = 8;
+ break;
+ case CLK_RATIO_5_8:
+ hdmi_rx->color_depth = 10;
+ break;
+ case CLK_RATIO_3_4:
+ hdmi_rx->color_depth = 12;
+ break;
+ case CLK_RATIO_5_4:
+ case CLK_RATIO_3_2:
+ case CLK_RATIO_2_1:
+ default:
+ pr_err("YUV420 Not supported clk ration\n");
+ }
+ break;
+ default: /* RGB/YUV444 */
+ switch (clk_ratio) {
+ case CLK_RATIO_1_1:
+ hdmi_rx->color_depth = 8;
+ break;
+ case CLK_RATIO_5_4:
+ hdmi_rx->color_depth = 10;
+ break;
+ case CLK_RATIO_3_2:
+ hdmi_rx->color_depth = 12;
+ break;
+ case CLK_RATIO_2_1:
+ hdmi_rx->color_depth = 16;
+ break;
+ case CLK_RATIO_1_2:
+ case CLK_RATIO_5_8:
+ case CLK_RATIO_3_4:
+ default:
+ pr_err("RGB/YUV444 Not supported clk ration\n");
+ }
+ }
+}
+
+/* Set edid data sample */
+void hdmirx_edid_set(state_struct *state)
+{
+ struct mxc_hdmi_rx_dev *hdmi_rx = state_to_mxc_hdmirx(state);
+
+ /* Set EDID - block 0 */
+ CDN_API_HDMIRX_SET_EDID_blocking(state, 0, 0, &block0[0]);
+ /* Set EDID - block 1 */
+ CDN_API_HDMIRX_SET_EDID_blocking(state, 0, 1, &block1[0]);
+ dev_dbg(&hdmi_rx->pdev->dev, "EDID block 0/1 set complete.\n");
+}
+
+/* Set SCDC data sample */
+void hdmirx_scdc_set(state_struct *state)
+{
+ struct mxc_hdmi_rx_dev *hdmi_rx = state_to_mxc_hdmirx(state);
+
+ CDN_API_HDMIRX_SET_SCDC_SLAVE_blocking(state, &scdcExampleData);
+ dev_dbg(&hdmi_rx->pdev->dev, "SCDC set complete.\n");
+}
+
+int hdmirx_init(state_struct *state)
+{
+ u8 sts;
+ u32 ret = 0;
+
+ /* Set uCPU Clock frequency for FW's use [MHz]; */
+ CDN_API_SetClock(state, 200);
+
+ /* Relase uCPU */
+ cdn_apb_write(state, ADDR_APB_CFG, 0);
+
+ /* Check if the firmware is running */
+ ret = CDN_API_CheckAlive_blocking(state);
+ if (ret != 0) {
+ DRM_ERROR("NO HDMI RX FW running\n");
+ return -ENXIO;
+ }
+
+ /* Set driver and firmware active */
+ CDN_API_MainControl_blocking(state, 1, &sts);
+ /* set sample edid and scdc */
+ hdmirx_edid_set(state);
+ hdmirx_scdc_set(state);
+
+ return ret;
+}
+
+int hdmirx_get_hpd_state(state_struct *state, u8 *hpd)
+{
+ return CDN_API_General_GetHpdState_blocking(state, hpd);
+}
+
+void hdmirx_hotplug_trigger(state_struct *state)
+{
+ /* Clear HPD */
+ CDN_API_HDMIRX_SetHpd_blocking(state, 0);
+ /* provide minimum low pulse length (100ms) */
+ msleep(110);
+ CDN_API_HDMIRX_SetHpd_blocking(state, 1);
+}
+
+/* Bring-up sequence for the HDMI-RX */
+int hdmirx_startup(state_struct *state)
+{
+ u8 sts;
+ int rx_clk_freq;
+ u8 data_rate_change = 0;
+ u8 scrambling_en;
+ clk_ratio_t clk_ratio, clk_ratio_detected;
+ tmds_bit_clock_ratio_t tmds_bit_clock_ratio;
+ struct mxc_hdmi_rx_dev *hdmi_rx = state_to_mxc_hdmirx(state);
+ S_HDMI_SCDC_GET_MSG *scdcData = &hdmi_rx->scdcData;
+ int ret = 0;
+
+ /* Start from TMDS/pixel clock ratio of 1:1.
+ * It affects only pixel clock frequency as the character/data clocks are generated based on
+ * a measured TMDS clock.
+ * This guarantees that the TMDS characters are correctly decoded in the controller regardless
+ * of the pixel clock ratio being programmed. */
+ clk_ratio = CLK_RATIO_1_1;
+
+ /* Get TMDS_Bit_Clock_Ratio and Scrambling setting */
+ CDN_API_HDMIRX_GET_SCDC_SLAVE_blocking(state, scdcData);
+ tmds_bit_clock_ratio =
+ ((scdcData->TMDS_Config & (1 << 1)) >> 1) ?
+ TMDS_BIT_CLOCK_RATIO_1_40 : TMDS_BIT_CLOCK_RATIO_1_10;
+ scrambling_en = scdcData->TMDS_Config & (1 << 0);
+
+ dev_dbg(&hdmi_rx->pdev->dev,
+ "TMDS ratio: 1/%0d, Scrambling %0d).\n", tmds_bit_clock_ratio, scrambling_en);
+
+ /* Configure the PHY */
+ pma_config(state);
+
+ /* Reset HDMI RX PHY */
+ imx8qm_hdmi_phy_reset(state, 1);
+
+ ret = pma_cmn_ready(state);
+ if (ret < 0) {
+ dev_err(&hdmi_rx->pdev->dev, "pma_cmn_ready failed\n");
+ return -1;
+ }
+
+ msleep(500);
+
+ /* init ARC */
+ arc_config(state);
+
+ /* Detect rx clk signal */
+ ret = pma_rx_clk_signal_detect(state);
+ if (ret < 0) {
+ dev_err(&hdmi_rx->pdev->dev, "Common rx_clk signal detect failed\n");
+ return -1;
+ }
+ /* Get TMDS clock frequency */
+ rx_clk_freq = pma_rx_clk_freq_detect(state);
+ if (rx_clk_freq < 0) {
+ dev_err(&hdmi_rx->pdev->dev, "detect tmds clock failed\n");
+ return -1;
+ }
+ dev_info(&hdmi_rx->pdev->dev, "detect TMDS clock freq: %d kHz\n", rx_clk_freq);
+
+ ret = pma_pll_config(state, rx_clk_freq, clk_ratio, tmds_bit_clock_ratio,
+ data_rate_change);
+ if (ret < 0) {
+ dev_err(&hdmi_rx->pdev->dev, "pma_pll_config failed\n");
+ return -1;
+ }
+ msleep(500);
+
+ /* Setup the scrambling mode */
+ CDN_API_General_Write_Register_blocking(state,
+ ADDR_SINK_MHL_HD + (TMDS_SCR_CTRL << 2),
+ F_SCRAMBLER_MODE(scrambling_en));
+ dev_info(&hdmi_rx->pdev->dev,
+ "Scrambling %s.\n", (scrambling_en) ? "enabled" : "disabled");
+ /*Just to initiate the counters: */
+ CDN_API_General_Write_Register_blocking(state,
+ ADDR_SINK_MHL_HD + (TMDS_SCR_CNT_INT_CTRL << 2),
+ F_SCRAMBLER_SSCP_LINE_DET_THR(0) |
+ F_SCRAMBLER_CTRL_LINE_DET_THR(0));
+ CDN_API_General_Write_Register_blocking(state,
+ ADDR_SINK_MHL_HD + (TMDS_SCR_VALID_CTRL << 2),
+ F_SCRAMBLER_SSCP_LINE_VALID_THR(1) |
+ F_SCRAMBLER_CTRL_LINE_VALID_THR(0));
+
+ /* The PHY got programmed with the assumed TMDS/pixel clock ratio of 1:1.
+ * Implement the link training procedure to find out the real clock ratio:
+ * 1. Wait for AVI InfoFrame packet
+ * 2. Get the VIC code and pixel encoding from the packet
+ * 3. Evaluate the TMDS/pixel clock ratio based on the vic_table.c
+ * 4. Compare the programmed clock ratio with evaluated one
+ * 5. If mismatch found - reprogram the PHY
+ * 6. Enable the video data path in the controller */
+
+ ret = get_avi_infoframe(state);
+ if (ret < 0) {
+ dev_err(&hdmi_rx->pdev->dev, "Get AVI info frame failed\n");
+ return -1;
+ }
+ ret = get_vendor_infoframe(state);
+ if (ret < 0)
+ dev_warn(&hdmi_rx->pdev->dev, "No Vendor info frame\n");
+
+ dev_info(&hdmi_rx->pdev->dev, "VIC: %0d, pixel_encoding: %0d.\n",
+ hdmi_rx->vic_code, hdmi_rx->pixel_encoding);
+ ret = mxc_hdmi_frame_timing(hdmi_rx);
+ if (ret < 0) {
+ dev_err(&hdmi_rx->pdev->dev, "Get frame timing failed\n\n");
+ return -1;
+ }
+
+ clk_ratio_detected = clk_ratio_detect(state, rx_clk_freq,
+ hdmi_rx->timings->timings.bt.
+ pixelclock / 1000,
+ hdmi_rx->vic_code,
+ hdmi_rx->pixel_encoding,
+ tmds_bit_clock_ratio);
+
+ data_rate_change = (clk_ratio != clk_ratio_detected);
+ if (data_rate_change) {
+ dev_dbg(&hdmi_rx->pdev->dev,
+ "TMDS/pixel clock ratio mismatch detected (programmed: %0d, detected: %0d)\n",
+ clk_ratio, clk_ratio_detected);
+
+ /* Reconfigure the PHY */
+ pre_data_rate_change(state);
+ pma_rx_clk_signal_detect(state);
+ rx_clk_freq = pma_rx_clk_freq_detect(state);
+ pma_pll_config(state, rx_clk_freq, clk_ratio_detected,
+ tmds_bit_clock_ratio, data_rate_change);
+ } else
+ dev_info(&hdmi_rx->pdev->dev, "TMDS/pixel clock ratio correct\n");
+
+ get_color_depth(hdmi_rx, clk_ratio_detected);
+ switch (hdmi_rx->pixel_encoding) {
+ case PIXEL_ENCODING_YUV422:
+ dev_info(&hdmi_rx->pdev->dev, "Detect mode VIC %d %dbit YUV422\n",
+ hdmi_rx->vic_code, hdmi_rx->color_depth);
+ break;
+ case PIXEL_ENCODING_YUV420:
+ dev_info(&hdmi_rx->pdev->dev, "Detect mode VIC %d %dbit YUV420\n",
+ hdmi_rx->vic_code, hdmi_rx->color_depth);
+ break;
+ case PIXEL_ENCODING_YUV444:
+ dev_info(&hdmi_rx->pdev->dev, "Detect mode VIC %d %dbit YUV444\n",
+ hdmi_rx->vic_code, hdmi_rx->color_depth);
+ break;
+ case PIXEL_ENCODING_RGB:
+ dev_info(&hdmi_rx->pdev->dev, "Detect mode VIC %d %dbit RGB\n",
+ hdmi_rx->vic_code, hdmi_rx->color_depth);
+ break;
+ default:
+ dev_err(&hdmi_rx->pdev->dev, "Unknow color format\n");
+ }
+
+ /* Do post PHY programming settings */
+ CDN_API_MainControl_blocking(state, 0x80, &sts);
+ dev_dbg(&hdmi_rx->pdev->dev,
+ "CDN_API_MainControl_blocking() Stage 2 complete.\n");
+
+ /* Initialize HDMI RX */
+ CDN_API_HDMIRX_Init_blocking(state);
+ dev_dbg(&hdmi_rx->pdev->dev,
+ "CDN_API_HDMIRX_Init_blocking() complete.\n");
+
+ /* Initialize HDMI RX CEC */
+ CDN_API_General_Write_Register_blocking(state,
+ ADDR_SINK_CAR + (SINK_CEC_CAR << 2),
+ F_SINK_CEC_SYS_CLK_EN(1) |
+ F_SINK_CEC_SYS_CLK_RSTN_EN(1));
+ return 0;
+}
+
+/* Stop for the HDMI-RX */
+void hdmirx_stop(state_struct *state)
+{
+ CDN_API_HDMIRX_Stop_blocking(state);
+}
+
+void hdmirx_phy_pix_engine_reset(state_struct *state)
+{
+ GENERAL_Read_Register_response regresp;
+
+ CDN_API_General_Read_Register_blocking(state, ADDR_SINK_CAR +
+ (SINK_MHL_HD_CAR << 2),
+ &regresp);
+ CDN_API_General_Write_Register_blocking(state, ADDR_SINK_CAR +
+ (SINK_MHL_HD_CAR << 2),
+ regresp.val & 0x3D);
+ CDN_API_General_Write_Register_blocking(state, ADDR_SINK_CAR +
+ (SINK_MHL_HD_CAR << 2),
+ regresp.val);
+}
diff --git a/drivers/media/platform/imx8/hdmi/mxc-hdmi-rx-audio.c b/drivers/media/platform/imx8/hdmi/mxc-hdmi-rx-audio.c
new file mode 100644
index 000000000000..22a55df879d7
--- /dev/null
+++ b/drivers/media/platform/imx8/hdmi/mxc-hdmi-rx-audio.c
@@ -0,0 +1,250 @@
+/*
+ * Copyright 2018 NXP
+ *
+ * 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/clk.h>
+#include <linux/kthread.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/component.h>
+#include <linux/mfd/syscon.h>
+#include <linux/of.h>
+#include <linux/irq.h>
+#include <linux/of_device.h>
+#include <sound/hdmi-codec.h>
+
+#include "mxc-hdmi-rx.h"
+#include "../../../../mxc/hdp/API_Audio.h"
+#include "../../../../mxc/hdp/API_HDMI_RX_Audio.h"
+#include "../../../../mxc/hdp/sink_pif.h"
+#include "../../../../mxc/hdp/aif_pckt2smp.h"
+
+
+static int get_audio_infoframe(state_struct *state, unsigned int *chan)
+{
+
+ unsigned int regread;
+ int ret = 0;
+ int times = 0;
+
+ cdn_apb_write(state, ADDR_SINK_PIF + (PKT_INFO_TYPE_CFG1 << 2), F_INFO_TYPE1(0x84));
+
+ cdn_apb_write(state, ADDR_SINK_PIF + (PKT_INT_MASK << 2), 0x1FFFE);
+
+ do {
+ cdn_apb_read(state, ADDR_SINK_PIF + (PKT_INT_STATUS << 2), &regread);
+ udelay(100);
+ times++;
+ } while (!(regread & (1 << 0)) && times < 5000);
+
+ if (times == 5000) {
+ ret = -EINVAL;
+ return ret;
+ }
+
+ cdn_apb_write(state, ADDR_SINK_PIF + (PKT_INFO_CTRL << 2), F_PACKET_RDN_WR(0x0) | F_PACKET_NUM(0x0));
+
+ times = 0;
+
+ do {
+ cdn_apb_read(state, ADDR_SINK_PIF + (PKT_INT_STATUS << 2), &regread);
+ udelay(10);
+ times++;
+ } while (!(regread & (1 << 16)) && times < 100);
+
+ if (times == 100) {
+ ret = -EINVAL;
+ return ret;
+ }
+
+ cdn_apb_read(state, ADDR_SINK_PIF + (PKT_INFO_DATA1 << 2), &regread);
+
+ cdn_apb_write(state, ADDR_SINK_PIF + (PKT_INFO_TYPE_CFG1 << 2), F_INFO_TYPE1(0x00));
+
+ *chan = ((regread & 0x700) >> 8) + 1;
+
+ cdn_apb_write(state, ADDR_SINK_PIF + (PKT_INFO_HEADER << 2), 0);
+ cdn_apb_write(state, ADDR_SINK_PIF + (PKT_INFO_DATA1 << 2), 0);
+ cdn_apb_write(state, ADDR_SINK_PIF + (PKT_INFO_DATA2 << 2), 0);
+ cdn_apb_write(state, ADDR_SINK_PIF + (PKT_INFO_DATA3 << 2), 0);
+ cdn_apb_write(state, ADDR_SINK_PIF + (PKT_INFO_DATA4 << 2), 0);
+ cdn_apb_write(state, ADDR_SINK_PIF + (PKT_INFO_DATA5 << 2), 0);
+ cdn_apb_write(state, ADDR_SINK_PIF + (PKT_INFO_DATA6 << 2), 0);
+ cdn_apb_write(state, ADDR_SINK_PIF + (PKT_INFO_DATA7 << 2), 0);
+
+ cdn_apb_write(state, ADDR_SINK_PIF + (PKT_INFO_CTRL << 2), F_PACKET_RDN_WR(0x1) | F_PACKET_NUM(0x0));
+
+ times = 0;
+ do {
+ cdn_apb_read(state, ADDR_SINK_PIF + (PKT_INT_STATUS << 2), &regread);
+ udelay(10);
+ times++;
+ } while (!(regread & (1 << 16)) && times < 100);
+
+ if (times == 100) {
+ ret = -EINVAL;
+ return ret;
+ }
+
+ return ret;
+}
+
+static u32 TMDS_rate_table[7] = {
+25200, 27000, 54000, 74250, 148500, 297000, 594000,
+};
+
+static u32 N_table_32k[8] = {
+/*25200, 27000, 54000, 74250, 148500, 297000, 594000,*/
+4096, 4096, 4096, 4096, 4096, 3072, 3072, 4096,
+};
+
+static u32 N_table_44k[8] = {
+6272, 6272, 6272, 6272, 6272, 4704, 9408, 6272,
+};
+
+static u32 N_table_48k[8] = {
+6144, 6144, 6144, 6144, 6144, 5120, 6144, 6144,
+};
+
+static int select_rate(u32 pclk, u32 N)
+{
+ int i = 0;
+ int rate = 0;
+
+ for (i = 0; i < 7; i++) {
+ if (pclk == TMDS_rate_table[i])
+ break;
+ }
+
+ if (i == 7)
+ DRM_WARN("pclkc %d is not supported!\n", pclk);
+
+ if (N_table_32k[i] == N)
+ rate = 32000;
+
+ if (N_table_44k[i] == N)
+ rate = 44100;
+
+ if (N_table_44k[i] * 2 == N)
+ rate = 44100 * 2;
+
+ if (N_table_44k[i] * 4 == N)
+ rate = 44100 * 4;
+
+ if (N_table_48k[i] == N)
+ rate = 48000;
+
+ if (N_table_48k[i] * 2 == N)
+ rate = 48000 * 2;
+
+ if (N_table_48k[i] * 4 == N)
+ rate = 48000 * 4;
+
+ return rate;
+}
+
+
+
+static int mxc_hdmi_rx_audio(struct mxc_hdmi_rx_dev *hdmi)
+{
+ state_struct *state = &hdmi->state;
+ u32 regread;
+ u32 rate;
+ u32 chan = 2;
+ CDN_API_STATUS status;
+ int ret;
+
+ ret = get_audio_infoframe(state, &chan);
+ if (ret)
+ return ret;
+
+ status = CDN_API_RX_AudioAutoConfig(state, chan, chan/2, 0, 32, 32);
+ if (status != CDN_OK)
+ return -EINVAL;
+
+ if (cdn_apb_read(state, ADDR_AIF_ENCODER + (AIF_ACR_N_ST << 2), &regread))
+ return -EINVAL;
+
+ rate = select_rate(hdmi->timings->timings.bt.pixelclock/1000, regread);
+
+ hdmi->channels = chan;
+ hdmi->sample_rate = rate;
+
+ return 0;
+}
+
+/*
+ * HDMI audio codec callbacks
+ */
+static int mxc_hdmi_rx_audio_hw_params(struct device *dev, void *data,
+ struct hdmi_codec_daifmt *daifmt,
+ struct hdmi_codec_params *params)
+{
+ return 0;
+}
+
+static void mxc_hdmi_rx_audio_shutdown(struct device *dev, void *data)
+{
+ pm_runtime_put_sync(dev);
+}
+
+static int mxc_hdmi_rx_audio_startup(struct device *dev, void *data)
+{
+ struct mxc_hdmi_rx_dev *hdmi = dev_get_drvdata(dev);
+ int ret;
+
+ pm_runtime_get_sync(dev);
+ ret = mxc_hdmi_rx_audio(hdmi);
+
+ return ret;
+}
+
+static int mxc_hdmi_rx_audio_get_eld(struct device *dev, void *data, uint8_t *buf, size_t len)
+{
+ struct mxc_hdmi_rx_dev *hdmi = dev_get_drvdata(dev);
+
+ if (len < 8)
+ return -EINVAL;
+
+ memcpy(buf, &hdmi->sample_rate, 4);
+ memcpy(buf + 4, &hdmi->channels, 4);
+
+ return 0;
+}
+
+static const struct hdmi_codec_ops mxc_hdmi_rx_audio_codec_ops = {
+ .hw_params = mxc_hdmi_rx_audio_hw_params,
+ .audio_shutdown = mxc_hdmi_rx_audio_shutdown,
+ .audio_startup = mxc_hdmi_rx_audio_startup,
+ .get_eld = mxc_hdmi_rx_audio_get_eld,
+};
+
+void mxc_hdmi_rx_register_audio_driver(struct device *dev)
+{
+ struct hdmi_codec_pdata codec_data = {
+ .ops = &mxc_hdmi_rx_audio_codec_ops,
+ .max_i2s_channels = 8,
+ .i2s = 1,
+ };
+ struct platform_device *pdev;
+
+ pdev = platform_device_register_data(dev, HDMI_CODEC_DRV_NAME,
+ 2, &codec_data,
+ sizeof(codec_data));
+ if (IS_ERR(pdev))
+ return;
+
+ DRM_INFO("%s driver bound to HDMI\n", HDMI_CODEC_DRV_NAME);
+}
+
+
diff --git a/drivers/media/platform/imx8/hdmi/mxc-hdmi-rx.c b/drivers/media/platform/imx8/hdmi/mxc-hdmi-rx.c
new file mode 100644
index 000000000000..c4361ce3c47b
--- /dev/null
+++ b/drivers/media/platform/imx8/hdmi/mxc-hdmi-rx.c
@@ -0,0 +1,1051 @@
+/*
+ * Copyright 2018 NXP
+ *
+ * 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/irq.h>
+#include "mxc-hdmi-rx.h"
+#include "API_AFE_ss28fdsoi_hdmirx.h"
+
+#define MXC_HDMI_DRIVER_NAME "iMX HDMI RX"
+#define MXC_HDMI_MIN_WIDTH 640
+#define MXC_HDMI_MAX_WIDTH 3840
+#define MXC_HDMI_MIN_HEIGHT 480
+#define MXC_HDMI_MAX_HEIGHT 2160
+
+/* V4L2_DV_BT_CEA_640X480P59_94 */
+#define MXC_HDMI_MIN_PIXELCLOCK 24000000
+/* V4L2_DV_BT_CEA_3840X2160P30 */
+#define MXC_HDMI_MAX_PIXELCLOCK 297000000
+
+#define imx_sd_to_hdmi(sd) container_of(sd, struct mxc_hdmi_rx_dev, sd)
+
+static void mxc_hdmi_cec_init(struct mxc_hdmi_rx_dev *hdmi_rx);
+
+static const struct v4l2_dv_timings_cap mxc_hdmi_timings_cap = {
+ .type = V4L2_DV_BT_656_1120,
+ /* keep this initialization for compatibility with GCC < 4.4.6 */
+ .reserved = { 0 },
+
+ V4L2_INIT_BT_TIMINGS(MXC_HDMI_MIN_WIDTH, MXC_HDMI_MAX_WIDTH,
+ MXC_HDMI_MIN_HEIGHT, MXC_HDMI_MAX_HEIGHT,
+ MXC_HDMI_MIN_PIXELCLOCK,
+ MXC_HDMI_MAX_PIXELCLOCK,
+ V4L2_DV_BT_STD_CEA861 | V4L2_DV_BT_STD_DMT,
+ V4L2_DV_BT_CAP_PROGRESSIVE)
+};
+
+struct mxc_hdmi_rx_dev_video_standards
+mxc_hdmi_video_standards[] = {
+ {V4L2_DV_BT_CEA_640X480P59_94, 1, 0, 60},
+ {V4L2_DV_BT_CEA_720X480P59_94, 2, 0, 60},
+ {V4L2_DV_BT_CEA_720X480P59_94, 3, 0, 60},
+ {V4L2_DV_BT_CEA_720X576P50, 18, 0, 50},
+ {V4L2_DV_BT_CEA_720X576P50, 17, 0, 50},
+ {V4L2_DV_BT_CEA_1280X720P60, 4, 0, 60},
+ {V4L2_DV_BT_CEA_1280X720P50, 19, 0, 50},
+ {V4L2_DV_BT_CEA_1280X720P30, 62, 0, 30},
+ {V4L2_DV_BT_CEA_1280X720P25, 61, 0, 25},
+ {V4L2_DV_BT_CEA_1280X720P24, 60, 0, 24},
+ {V4L2_DV_BT_CEA_1920X1080P60, 16, 0, 60},
+ {V4L2_DV_BT_CEA_1920X1080P50, 31, 0, 50},
+ {V4L2_DV_BT_CEA_1920X1080P30, 34, 0, 30},
+ {V4L2_DV_BT_CEA_1920X1080P25, 33, 0, 25},
+ {V4L2_DV_BT_CEA_1920X1080P24, 32, 0, 24},
+ {V4L2_DV_BT_CEA_3840X2160P24, 93, 3, 24},
+ {V4L2_DV_BT_CEA_3840X2160P25, 94, 2, 25},
+ {V4L2_DV_BT_CEA_3840X2160P30, 95, 1, 30},
+ {V4L2_DV_BT_CEA_4096X2160P24, 98, 4, 24},
+ {V4L2_DV_BT_CEA_4096X2160P25, 99, 0, 25},
+ {V4L2_DV_BT_CEA_4096X2160P30, 100, 0, 30},
+ /* SVGA */
+ {V4L2_DV_BT_DMT_800X600P56, 0x0, 0, 56},
+ {V4L2_DV_BT_DMT_800X600P60, 0x0, 0, 60},
+ {V4L2_DV_BT_DMT_800X600P72, 0x0, 0, 72},
+ {V4L2_DV_BT_DMT_800X600P75, 0x0, 0, 75},
+ {V4L2_DV_BT_DMT_800X600P85, 0x0, 0, 85},
+ /* SXGA */
+ {V4L2_DV_BT_DMT_1280X1024P60, 0x0, 0, 60},
+ {V4L2_DV_BT_DMT_1280X1024P75, 0x0, 0, 75},
+ /* VGA */
+ { V4L2_DV_BT_DMT_640X480P72, 0x0, 0, 72},
+ { V4L2_DV_BT_DMT_640X480P75, 0x0, 0, 75},
+ { V4L2_DV_BT_DMT_640X480P85, 0x0, 0, 85},
+ /* XGA */
+ { V4L2_DV_BT_DMT_1024X768P60, 0x0, 0, 60},
+ { V4L2_DV_BT_DMT_1024X768P70, 0x0, 0, 70},
+ { V4L2_DV_BT_DMT_1024X768P75, 0x0, 0, 75},
+ { V4L2_DV_BT_DMT_1024X768P85, 0x0, 0, 85},
+ /* UXGA */
+ { V4L2_DV_BT_DMT_1600X1200P60, 0x0, 0, 60},
+};
+
+int mxc_hdmi_frame_timing(struct mxc_hdmi_rx_dev *hdmi_rx)
+{
+ struct mxc_hdmi_rx_dev_video_standards *stds;
+ u32 i, vic, hdmi_vic;
+
+ vic = hdmi_rx->vic_code;
+ hdmi_vic = hdmi_rx->hdmi_vic;
+ stds = mxc_hdmi_video_standards;
+
+ if (vic == 0 && hdmi_vic != 0) {
+ for (i = 0; i < ARRAY_SIZE(mxc_hdmi_video_standards); i++) {
+ if (stds[i].hdmi_vic == hdmi_vic) {
+ hdmi_rx->timings = &stds[i];
+ return true;
+ }
+ }
+ } else if (vic > 109) {
+ dev_err(&hdmi_rx->pdev->dev,
+ "Unsupported mode vic=%d, hdmi_vic=%d\n", vic, hdmi_vic);
+ return -EINVAL;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(mxc_hdmi_video_standards); i++) {
+ if (stds[i].vic == vic) {
+ hdmi_rx->timings = &stds[i];
+ return true;
+ }
+ }
+
+ if (i >= ARRAY_SIZE(mxc_hdmi_video_standards))
+ return -EINVAL;
+
+ return true;
+}
+
+static int mxc_hdmi_clock_init(struct mxc_hdmi_rx_dev *hdmi_rx)
+{
+ struct device *dev = &hdmi_rx->pdev->dev;
+
+ hdmi_rx->ref_clk = devm_clk_get(dev, "ref_clk");
+ if (IS_ERR(hdmi_rx->ref_clk)) {
+ dev_err(dev, "failed to get hdmi rx ref clk\n");
+ return PTR_ERR(hdmi_rx->ref_clk);
+ }
+
+ hdmi_rx->pxl_clk = devm_clk_get(dev, "pxl_clk");
+ if (IS_ERR(hdmi_rx->pxl_clk)) {
+ dev_err(dev, "failed to get hdmi rx pxl clk\n");
+ return PTR_ERR(hdmi_rx->pxl_clk);
+ }
+ hdmi_rx->pclk = devm_clk_get(dev, "pclk");
+ if (IS_ERR(hdmi_rx->pclk)) {
+ dev_err(dev, "failed to get hdmi rx pclk\n");
+ return PTR_ERR(hdmi_rx->pclk);
+ }
+
+ hdmi_rx->sclk = devm_clk_get(dev, "sclk");
+ if (IS_ERR(hdmi_rx->sclk)) {
+ dev_err(dev, "failed to get hdmi rx sclk\n");
+ return PTR_ERR(hdmi_rx->sclk);
+ }
+
+ hdmi_rx->enc_clk = devm_clk_get(dev, "enc_clk");
+ if (IS_ERR(hdmi_rx->enc_clk)) {
+ dev_err(dev, "failed to get hdmi rx enc clk\n");
+ return PTR_ERR(hdmi_rx->enc_clk);
+ }
+
+ hdmi_rx->i2s_clk = devm_clk_get(dev, "i2s_clk");
+ if (IS_ERR(hdmi_rx->i2s_clk)) {
+ dev_err(dev, "failed to get hdmi rx i2s clk\n");
+ return PTR_ERR(hdmi_rx->i2s_clk);
+ }
+
+ hdmi_rx->spdif_clk = devm_clk_get(dev, "spdif_clk");
+ if (IS_ERR(hdmi_rx->spdif_clk)) {
+ dev_err(dev, "failed to get hdmi rx spdif clk\n");
+ return PTR_ERR(hdmi_rx->spdif_clk);
+ }
+
+ hdmi_rx->pxl_link_clk = devm_clk_get(dev, "pxl_link_clk");
+ if (IS_ERR(hdmi_rx->pxl_link_clk)) {
+ dev_err(dev, "failed to get hdmi rx pixel link clk\n");
+ return PTR_ERR(hdmi_rx->pxl_link_clk);
+ }
+
+ return 0;
+}
+
+static int mxc_hdmi_clock_enable(struct mxc_hdmi_rx_dev *hdmi_rx)
+{
+ struct device *dev = &hdmi_rx->pdev->dev;
+ int ret;
+
+ dev_dbg(dev, "%s\n", __func__);
+ ret = clk_prepare_enable(hdmi_rx->ref_clk);
+ if (ret < 0) {
+ dev_err(dev, "%s, pre ref_clk error %d\n", __func__, ret);
+ return ret;
+ }
+ ret = clk_prepare_enable(hdmi_rx->pxl_clk);
+ if (ret < 0) {
+ dev_err(dev, "%s, pre pxl_clk error %d\n", __func__, ret);
+ return ret;
+ }
+ ret = clk_prepare_enable(hdmi_rx->enc_clk);
+ if (ret < 0) {
+ dev_err(dev, "%s, pre enc_clk error %d\n", __func__, ret);
+ return ret;
+ }
+ ret = clk_prepare_enable(hdmi_rx->sclk);
+ if (ret < 0) {
+ dev_err(dev, "%s, pre sclk error %d\n", __func__, ret);
+ return ret;
+ }
+ ret = clk_prepare_enable(hdmi_rx->pclk);
+ if (ret < 0) {
+ dev_err(dev, "%s, pre pclk error %d\n", __func__, ret);
+ return ret;
+ }
+
+ ret = clk_prepare_enable(hdmi_rx->i2s_clk);
+ if (ret < 0) {
+ dev_err(dev, "%s, pre i2s_clk error %d\n", __func__, ret);
+ return ret;
+ }
+
+ ret = clk_prepare_enable(hdmi_rx->spdif_clk);
+ if (ret < 0) {
+ dev_err(dev, "%s, pre spdif_clk error %d\n", __func__, ret);
+ return ret;
+ }
+ ret = clk_prepare_enable(hdmi_rx->pxl_link_clk);
+ if (ret < 0) {
+ dev_err(dev, "%s, pre pxl_link_clk error %d\n", __func__, ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static void mxc_hdmi_clock_disable(struct mxc_hdmi_rx_dev *hdmi_rx)
+{
+ dev_dbg(&hdmi_rx->pdev->dev, "%s\n", __func__);
+
+ clk_disable_unprepare(hdmi_rx->ref_clk);
+ clk_disable_unprepare(hdmi_rx->pxl_clk);
+ clk_disable_unprepare(hdmi_rx->enc_clk);
+ clk_disable_unprepare(hdmi_rx->sclk);
+ clk_disable_unprepare(hdmi_rx->pclk);
+ clk_disable_unprepare(hdmi_rx->i2s_clk);
+ clk_disable_unprepare(hdmi_rx->spdif_clk);
+ clk_disable_unprepare(hdmi_rx->pxl_link_clk);
+}
+
+static void mxc_hdmi_pixel_link_encoder(struct mxc_hdmi_rx_dev *hdmi_rx)
+{
+ u32 val;
+
+ switch (hdmi_rx->pixel_encoding) {
+ case PIXEL_ENCODING_YUV422:
+ val = 3;
+ break;
+ case PIXEL_ENCODING_YUV420:
+ val = 4;
+ break;
+ case PIXEL_ENCODING_YUV444:
+ val = 2;
+ break;
+ case PIXEL_ENCODING_RGB:
+ val = 0;
+ break;
+ default:
+ val = 0x6;
+ }
+
+ /* HDMI RX H/Vsync Polarity */
+ if (hdmi_rx->timings->timings.bt.polarities & V4L2_DV_VSYNC_POS_POL)
+ val |= 1 << PL_ENC_CTL_PXL_VCP;
+ if (hdmi_rx->timings->timings.bt.polarities & V4L2_DV_HSYNC_POS_POL)
+ val |= 1 << PL_ENC_CTL_PXL_HCP;
+
+ writel(val, hdmi_rx->mem.ss_base);
+}
+
+/* -----------------------------------------------------------------------------
+ * v4l2_subdev_video_ops
+ */
+static int mxc_hdmi_s_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *a)
+{
+ struct mxc_hdmi_rx_dev *hdmi_rx = imx_sd_to_hdmi(sd);
+ struct device *dev = &hdmi_rx->pdev->dev;
+
+ dev_dbg(dev, "%s\n", __func__);
+
+ return 0;
+}
+
+static int mxc_hdmi_g_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *a)
+{
+ struct v4l2_captureparm *cparm = &a->parm.capture;
+ struct mxc_hdmi_rx_dev *hdmi_rx = imx_sd_to_hdmi(sd);
+ int ret = 0;
+
+ if (hdmi_rx->cable_plugin == false) {
+ dev_warn(&hdmi_rx->pdev->dev, "No Cable Connected!\n");
+ return -EINVAL;
+ }
+
+ switch (a->type) {
+ /* This is the only case currently handled. */
+ case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+ case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
+ memset(a, 0, sizeof(*a));
+ a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ cparm->timeperframe.denominator = hdmi_rx->timings->fps;
+ cparm->timeperframe.numerator = 1;
+ ret = 0;
+ break;
+
+ /* These are all the possible cases. */
+ case V4L2_BUF_TYPE_VIDEO_OUTPUT:
+ case V4L2_BUF_TYPE_VIDEO_OVERLAY:
+ case V4L2_BUF_TYPE_VBI_CAPTURE:
+ case V4L2_BUF_TYPE_VBI_OUTPUT:
+ case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
+ case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
+ ret = -EINVAL;
+ break;
+ default:
+ pr_debug(" type is unknown - %d\n", a->type);
+ ret = -EINVAL;
+ break;
+ }
+
+ return ret;
+}
+
+static int mxc_hdmi_s_stream(struct v4l2_subdev *sd, int enable)
+{
+ struct mxc_hdmi_rx_dev *hdmi_rx = imx_sd_to_hdmi(sd);
+ u32 val;
+
+ dev_dbg(&hdmi_rx->pdev->dev, "%s\n", __func__);
+ if (hdmi_rx->cable_plugin == false) {
+ dev_warn(&hdmi_rx->pdev->dev, "No Cable Connected!\n");
+ return -EINVAL;
+ }
+
+ mxc_hdmi_pixel_link_encoder(hdmi_rx);
+
+ if (enable) {
+ val = readl(hdmi_rx->mem.ss_base);
+ val |= 1 << PL_ENC_CTL_PXL_EN;
+ writel(val, hdmi_rx->mem.ss_base);
+ mdelay(17);
+
+ val = readl(hdmi_rx->mem.ss_base);
+ val |= 1 << PL_ENC_CTL_PXL_VAL;
+ writel(val, hdmi_rx->mem.ss_base);
+ } else {
+ val = readl(hdmi_rx->mem.ss_base);
+ val |= ~(1 << PL_ENC_CTL_PXL_VAL);
+ writel(val, hdmi_rx->mem.ss_base);
+ mdelay(17);
+
+ val = readl(hdmi_rx->mem.ss_base);
+ val |= ~(1 << PL_ENC_CTL_PXL_EN);
+ writel(val, hdmi_rx->mem.ss_base);
+ }
+
+ return 0;
+}
+
+static const struct v4l2_subdev_video_ops imx_video_ops_hdmi = {
+ .s_stream = mxc_hdmi_s_stream,
+ .g_parm = mxc_hdmi_g_parm,
+ .s_parm = mxc_hdmi_s_parm,
+};
+
+/* -----------------------------------------------------------------------------
+ * Media Operations
+ */
+
+static const struct media_entity_operations hdmi_media_ops = {
+ .link_validate = v4l2_subdev_link_validate,
+};
+
+/* -----------------------------------------------------------------------------
+ * v4l2_subdev_pad_ops
+ */
+static int mxc_hdmi_enum_framesizes(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_frame_size_enum *fse)
+{
+ struct mxc_hdmi_rx_dev *hdmi_rx = imx_sd_to_hdmi(sd);
+
+ if (fse->index > 1 || hdmi_rx->cable_plugin == false)
+ return -EINVAL;
+
+ fse->min_width = hdmi_rx->timings->timings.bt.width;
+ fse->max_width = fse->min_width;
+
+ fse->min_height = hdmi_rx->timings->timings.bt.height;
+ fse->max_height = fse->min_height;
+ return 0;
+}
+static int mxc_hdmi_enum_frame_interval(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_frame_interval_enum *fie)
+{
+ struct mxc_hdmi_rx_dev *hdmi_rx = imx_sd_to_hdmi(sd);
+
+ if (fie->index > 8)
+ return -EINVAL;
+
+ if (fie->width == 0 || fie->height == 0 ||
+ fie->code == 0) {
+ pr_warning("Please assign pixel format, width and height.\n");
+ return -EINVAL;
+ }
+
+ fie->interval.numerator = 1;
+
+ /* TODO Reserved to extension */
+ fie->interval.denominator = hdmi_rx->timings->fps;
+ return 0;
+}
+
+static int mxc_hdmi_enum_mbus_code(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_mbus_code_enum *code)
+{
+ if (code->index != 0)
+ return -EINVAL;
+
+ code->code = MEDIA_BUS_FMT_RGB888_1X24;
+
+ return 0;
+}
+
+static int mxc_hdmi_get_format(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_format *sdformat)
+{
+ struct mxc_hdmi_rx_dev *hdmi_rx = imx_sd_to_hdmi(sd);
+ struct v4l2_mbus_framefmt *mbusformat = &sdformat->format;
+
+ if (hdmi_rx->cable_plugin == false) {
+ dev_warn(&hdmi_rx->pdev->dev, "No Cable Connected!\n");
+ return -EINVAL;
+ }
+
+ if (sdformat->pad != MXC_HDMI_RX_PAD_SOURCE)
+ return -EINVAL;
+
+ switch (hdmi_rx->pixel_encoding) {
+ case PIXEL_ENCODING_YUV422:
+ mbusformat->code = MEDIA_BUS_FMT_YUYV8_1X16;
+ break;
+ case PIXEL_ENCODING_YUV420:
+ mbusformat->code = MEDIA_BUS_FMT_UV8_1X8;
+ break;
+ case PIXEL_ENCODING_YUV444:
+ mbusformat->code = MEDIA_BUS_FMT_AYUV8_1X32;
+ break;
+ default:
+ mbusformat->code = MEDIA_BUS_FMT_RGB888_1X24;
+ }
+
+ mbusformat->width = hdmi_rx->timings->timings.bt.width;
+ mbusformat->height = hdmi_rx->timings->timings.bt.height;
+ mbusformat->colorspace = V4L2_COLORSPACE_JPEG;
+
+ return 0;
+}
+
+static int mxc_hdmi_get_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid)
+{
+ struct mxc_hdmi_rx_dev *hdmi_rx = imx_sd_to_hdmi(sd);
+
+ memset(edid->reserved, 0, sizeof(edid->reserved));
+
+ if (!hdmi_rx->edid.present)
+ return -ENODATA;
+
+ if (edid->start_block == 0 && edid->blocks == 0) {
+ edid->blocks = hdmi_rx->edid.blocks;
+ return 0;
+ }
+
+ if (edid->start_block >= hdmi_rx->edid.blocks)
+ return -EINVAL;
+
+ if (edid->start_block + edid->blocks > hdmi_rx->edid.blocks)
+ edid->blocks = hdmi_rx->edid.blocks - edid->start_block;
+
+ memcpy(edid->edid, hdmi_rx->edid.edid + edid->start_block * 128,
+ edid->blocks * 128);
+
+ return 0;
+}
+
+static int mxc_hdmi_set_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid)
+{
+ struct mxc_hdmi_rx_dev *hdmi_rx = imx_sd_to_hdmi(sd);
+ state_struct *state = &hdmi_rx->state;
+ int err, i;
+
+ memset(edid->reserved, 0, sizeof(edid->reserved));
+
+ if (edid->start_block != 0)
+ return -EINVAL;
+
+ if (edid->blocks == 0) {
+ /* Default EDID */
+ hdmi_rx->edid.blocks = 2;
+ hdmi_rx->edid.present = true;
+ } else if (edid->blocks > 4) {
+ edid->blocks = 4;
+ return -E2BIG;
+ } else {
+ memcpy(hdmi_rx->edid.edid, edid->edid, 128 * edid->blocks);
+ hdmi_rx->edid.blocks = edid->blocks;
+ hdmi_rx->edid.present = true;
+ }
+
+ for (i = 0; i < hdmi_rx->edid.blocks; i++) {
+ /* EDID block */
+ err = CDN_API_HDMIRX_SET_EDID_blocking(state, 0, i, &hdmi_rx->edid.edid[i * 128]);
+ if (err != CDN_OK) {
+ v4l2_err(sd, "error %d writing edid pad %d\n", err, edid->pad);
+ return -err;
+ }
+ }
+
+ return 0;
+}
+
+static bool mxc_hdmi_check_dv_timings(const struct v4l2_dv_timings *timings,
+ void *hdl)
+{
+ const struct mxc_hdmi_rx_dev_video_standards *stds =
+ mxc_hdmi_video_standards;
+ u32 i;
+
+ for (i = 0; stds[i].timings.bt.width; i++)
+ if (v4l2_match_dv_timings(timings, &stds[i].timings, 0, false))
+ return true;
+
+ return false;
+}
+
+static int mxc_hdmi_enum_dv_timings(struct v4l2_subdev *sd,
+ struct v4l2_enum_dv_timings *timings)
+{
+ return v4l2_enum_dv_timings_cap(timings, &mxc_hdmi_timings_cap,
+ mxc_hdmi_check_dv_timings, NULL);
+}
+
+static int mxc_hdmi_dv_timings_cap(struct v4l2_subdev *sd,
+ struct v4l2_dv_timings_cap *cap)
+{
+ *cap = mxc_hdmi_timings_cap;
+ return 0;
+}
+
+static const struct v4l2_subdev_pad_ops imx_pad_ops_hdmi = {
+ .enum_mbus_code = mxc_hdmi_enum_mbus_code,
+ .enum_frame_size = mxc_hdmi_enum_framesizes,
+ .enum_frame_interval = mxc_hdmi_enum_frame_interval,
+ .get_fmt = mxc_hdmi_get_format,
+ .get_edid = mxc_hdmi_get_edid,
+ .set_edid = mxc_hdmi_set_edid,
+ .dv_timings_cap = mxc_hdmi_dv_timings_cap,
+ .enum_dv_timings = mxc_hdmi_enum_dv_timings,
+};
+
+static int mxc_hdmi_s_power(struct v4l2_subdev *sd, int on)
+{
+ struct mxc_hdmi_rx_dev *hdmi_rx = imx_sd_to_hdmi(sd);
+ struct device *dev = &hdmi_rx->pdev->dev;
+
+ dev_dbg(dev, "%s\n", __func__);
+
+ return 0;
+}
+static struct v4l2_subdev_core_ops imx_core_ops_hdmi = {
+ .s_power = mxc_hdmi_s_power,
+};
+
+/* -----------------------------------------------------------------------------
+ * v4l2_subdev_ops
+ */
+static const struct v4l2_subdev_ops imx_ops_hdmi = {
+ .core = &imx_core_ops_hdmi,
+ .video = &imx_video_ops_hdmi,
+ .pad = &imx_pad_ops_hdmi,
+};
+
+void imx8qm_hdmi_phy_reset(state_struct *state, u8 reset)
+{
+ struct mxc_hdmi_rx_dev *hdmi_rx = state_to_mxc_hdmirx(state);
+ sc_err_t sciErr;
+
+ dev_dbg(&hdmi_rx->pdev->dev, "%s\n", __func__);
+ /* set the pixel link mode and pixel type */
+ sciErr = sc_misc_set_control(hdmi_rx->ipcHndl, SC_R_HDMI_RX, SC_C_PHY_RESET, reset);
+ if (sciErr != SC_ERR_NONE)
+ DRM_ERROR("SC_R_HDMI PHY reset failed %d!\n", sciErr);
+}
+
+static int imx8qm_hdp_read(struct hdp_mem *mem, u32 addr, u32 *value)
+{
+ u32 temp;
+ void *tmp_addr;
+ void *off_addr;
+
+ mutex_lock(&mem->mutex);
+ tmp_addr = (addr & 0xfff) + mem->regs_base;
+ off_addr = 0x4 + mem->ss_base;
+ __raw_writel(addr >> 12, off_addr);
+ temp = __raw_readl((volatile u32 *)tmp_addr);
+
+ *value = temp;
+ mutex_unlock(&mem->mutex);
+ return 0;
+}
+
+static int imx8qm_hdp_write(struct hdp_mem *mem, u32 addr, u32 value)
+{
+ void *tmp_addr;
+ void *off_addr;
+
+ mutex_lock(&mem->mutex);
+ tmp_addr = (addr & 0xfff) + mem->regs_base;
+ off_addr = 0x4 + mem->ss_base;;
+ __raw_writel(addr >> 12, off_addr);
+
+ __raw_writel(value, (volatile u32 *) tmp_addr);
+ mutex_unlock(&mem->mutex);
+
+ return 0;
+}
+
+static int imx8qm_hdp_sread(struct hdp_mem *mem, u32 addr, u32 *value)
+{
+ u32 temp;
+ void *tmp_addr;
+ void *off_addr;
+
+ mutex_lock(&mem->mutex);
+ tmp_addr = (addr & 0xfff) + mem->regs_base;
+ off_addr = 0xc + mem->ss_base;
+ __raw_writel(addr >> 12, off_addr);
+
+ temp = __raw_readl((volatile u32 *)tmp_addr);
+ *value = temp;
+ mutex_unlock(&mem->mutex);
+ return 0;
+}
+
+static int imx8qm_hdp_swrite(struct hdp_mem *mem, u32 addr, u32 value)
+{
+ void *tmp_addr;
+ void *off_addr;
+
+ mutex_lock(&mem->mutex);
+ tmp_addr = (addr & 0xfff) + mem->regs_base;
+ off_addr = 0xc + mem->ss_base;
+ __raw_writel(addr >> 12, off_addr);
+ __raw_writel(value, (volatile u32 *)tmp_addr);
+ mutex_unlock(&mem->mutex);
+
+ return 0;
+}
+static struct hdp_rw_func imx8qm_rw = {
+ .read_reg = imx8qm_hdp_read,
+ .write_reg = imx8qm_hdp_write,
+ .sread_reg = imx8qm_hdp_sread,
+ .swrite_reg = imx8qm_hdp_swrite,
+};
+
+static void mxc_hdmi_state_init(struct mxc_hdmi_rx_dev *hdmi_rx)
+{
+ state_struct *state = &hdmi_rx->state;
+
+ memset(state, 0, sizeof(state_struct));
+ mutex_init(&state->mutex);
+
+ state->mem = &hdmi_rx->mem;
+ state->rw = &imx8qm_rw;
+}
+
+#ifdef CONFIG_IMX_HDP_CEC
+static void mxc_hdmi_cec_init(struct mxc_hdmi_rx_dev *hdmi_rx)
+{
+ state_struct *state = &hdmi_rx->state;
+ struct imx_cec_dev *cec = &hdmi_rx->cec;
+ u32 clk_rate;
+
+ memset(cec, 0, sizeof(struct imx_cec_dev));
+
+ CDN_API_GetClock(state, &clk_rate);
+ cec->clk_div = clk_rate * 10;
+ cec->dev = &hdmi_rx->pdev->dev;
+ cec->mem = &hdmi_rx->mem;
+ cec->rw = &imx8qm_rw;
+}
+#endif
+
+
+int mxc_hdmi_init(struct mxc_hdmi_rx_dev *hdmi_rx)
+{
+ sc_err_t sciErr;
+
+ dev_dbg(&hdmi_rx->pdev->dev, "%s\n", __func__);
+ mxc_hdmi_state_init(hdmi_rx);
+
+ sciErr = sc_ipc_getMuID(&hdmi_rx->mu_id);
+ if (sciErr != SC_ERR_NONE) {
+ DRM_ERROR("Cannot obtain MU ID\n");
+ return -EINVAL;
+ }
+
+ sciErr = sc_ipc_open(&hdmi_rx->ipcHndl, hdmi_rx->mu_id);
+ if (sciErr != SC_ERR_NONE) {
+ DRM_ERROR("sc_ipc_open failed! (sciError = %d)\n", sciErr);
+ return -EINVAL;
+ }
+
+
+ return 0;
+}
+
+static void hpd5v_work_func(struct work_struct *work)
+{
+ struct mxc_hdmi_rx_dev *hdmi_rx = container_of(work, struct mxc_hdmi_rx_dev,
+ hpd5v_work.work);
+ char event_string[32];
+ char *envp[] = { event_string, NULL };
+ u8 sts;
+ u8 hpd;
+
+ /* Check cable states before enable irq */
+ hdmirx_get_hpd_state(&hdmi_rx->state, &hpd);
+ if (hpd == 1) {
+ pr_info("HDMI RX Cable Plug In\n");
+
+ CDN_API_MainControl_blocking(&hdmi_rx->state, 1, &sts);
+ hdmirx_hotplug_trigger(&hdmi_rx->state);
+ hdmirx_startup(&hdmi_rx->state);
+ enable_irq(hdmi_rx->irq[HPD5V_IRQ_OUT]);
+ sprintf(event_string, "EVENT=hdmirxin");
+ kobject_uevent_env(&hdmi_rx->pdev->dev.kobj, KOBJ_CHANGE, envp);
+ hdmi_rx->cable_plugin = true;
+#ifdef CONFIG_IMX_HDP_CEC
+ if (hdmi_rx->is_cec) {
+ mxc_hdmi_cec_init(hdmi_rx);
+ imx_cec_register(&hdmi_rx->cec);
+ hdmi_rx->cec_running = true;
+ }
+#endif
+ } else if (hpd == 0){
+ pr_info("HDMI RX Cable Plug Out\n");
+ hdmirx_stop(&hdmi_rx->state);
+#ifdef CONFIG_IMX_HDP_CEC
+ if (hdmi_rx->is_cec && hdmi_rx->cec_running) {
+ imx_cec_unregister(&hdmi_rx->cec);
+ hdmi_rx->cec_running = false;
+ }
+#endif
+ hdmirx_phy_pix_engine_reset(&hdmi_rx->state);
+ sprintf(event_string, "EVENT=hdmirxout");
+ kobject_uevent_env(&hdmi_rx->pdev->dev.kobj, KOBJ_CHANGE, envp);
+ enable_irq(hdmi_rx->irq[HPD5V_IRQ_IN]);
+ CDN_API_MainControl_blocking(&hdmi_rx->state, 0, &sts);
+ hdmi_rx->cable_plugin = false;
+ } else
+ pr_warn("HDMI RX Cable State unknow\n");
+
+}
+
+#define HOTPLUG_DEBOUNCE_MS 200
+static irqreturn_t mxc_hdp5v_irq_thread(int irq, void *data)
+{
+ struct mxc_hdmi_rx_dev *hdmi_rx = data;
+
+ disable_irq_nosync(irq);
+
+ mod_delayed_work(system_wq, &hdmi_rx->hpd5v_work,
+ msecs_to_jiffies(HOTPLUG_DEBOUNCE_MS));
+
+ return IRQ_HANDLED;
+}
+
+static int mxc_hdmi_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct mxc_hdmi_rx_dev *hdmi_rx;
+ struct resource *res;
+ u8 hpd;
+ int ret = 0;
+
+ dev_dbg(dev, "%s\n", __func__);
+ hdmi_rx = devm_kzalloc(dev, sizeof(*hdmi_rx), GFP_KERNEL);
+ if (!hdmi_rx)
+ return -ENOMEM;
+
+ hdmi_rx->pdev = pdev;
+
+ mutex_init(&hdmi_rx->mem.mutex);
+ /* register map */
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ hdmi_rx->mem.regs_base = devm_ioremap_resource(dev, res);
+ if (IS_ERR(hdmi_rx->mem.regs_base)) {
+ dev_err(dev, "Failed to get HDMI RX CTRL base register\n");
+ return -EINVAL;
+ }
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+ hdmi_rx->mem.ss_base = devm_ioremap_resource(dev, res);
+ if (IS_ERR(hdmi_rx->mem.ss_base)) {
+ dev_err(dev, "Failed to get HDMI RX CRS base register\n");
+ return -EINVAL;
+ }
+
+ hdmi_rx->irq[HPD5V_IRQ_IN] = platform_get_irq_byname(pdev, "plug_in");
+ if (hdmi_rx->irq[HPD5V_IRQ_IN] < 0)
+ dev_info(&pdev->dev, "No plug_in irq number\n");
+
+ hdmi_rx->irq[HPD5V_IRQ_OUT] = platform_get_irq_byname(pdev, "plug_out");
+ if (hdmi_rx->irq[HPD5V_IRQ_OUT] < 0)
+ dev_info(&pdev->dev, "No plug_out irq number\n");
+
+ INIT_DELAYED_WORK(&hdmi_rx->hpd5v_work, hpd5v_work_func);
+
+
+ v4l2_subdev_init(&hdmi_rx->sd, &imx_ops_hdmi);
+ /* sd.dev may use by match_of */
+ hdmi_rx->sd.dev = dev;
+
+ /* the owner is the same as the i2c_client's driver owner */
+ hdmi_rx->sd.owner = THIS_MODULE;
+ hdmi_rx->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+ hdmi_rx->sd.entity.function = MEDIA_ENT_F_IO_DTV;
+
+ /* This allows to retrieve the platform device id by the host driver */
+ v4l2_set_subdevdata(&hdmi_rx->sd, pdev);
+
+ /* initialize name */
+ snprintf(hdmi_rx->sd.name, sizeof(hdmi_rx->sd.name), "%s",
+ MXC_HDMI_RX_SUBDEV_NAME);
+
+ hdmi_rx->pads[MXC_HDMI_RX_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
+ hdmi_rx->pads[MXC_HDMI_RX_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
+
+ hdmi_rx->sd.entity.ops = &hdmi_media_ops;
+ ret = media_entity_pads_init(&hdmi_rx->sd.entity,
+ MXC_HDMI_RX_PADS_NUM, hdmi_rx->pads);
+ if (ret)
+ return ret;
+
+ platform_set_drvdata(pdev, hdmi_rx);
+ ret = v4l2_async_register_subdev(&hdmi_rx->sd);
+ if (ret < 0) {
+ dev_err(dev,
+ "%s--Async register failed, ret=%d\n", __func__, ret);
+ media_entity_cleanup(&hdmi_rx->sd.entity);
+ }
+
+ hdmi_rx->is_cec = of_property_read_bool(pdev->dev.of_node, "fsl,cec");
+
+ mxc_hdmi_clock_init(hdmi_rx);
+
+ hdmi_rx->flags = MXC_HDMI_RX_PM_POWERED;
+
+ mxc_hdmi_clock_enable(hdmi_rx);
+ pm_runtime_set_active(dev);
+ pm_runtime_enable(dev);
+ pm_runtime_get_sync(dev);
+ ret = mxc_hdmi_init(hdmi_rx);
+ if (ret < 0) {
+ dev_err(dev, "mxc hdmi init failed\n");
+ goto failed;
+ }
+ ret = hdmirx_init(&hdmi_rx->state);
+ if (ret < 0) {
+ dev_err(dev, "mxc hdmi rx init failed\n");
+ goto failed;
+ }
+
+ /* Check cable states before enable irq */
+ hdmirx_get_hpd_state(&hdmi_rx->state, &hpd);
+
+ /* Enable Hotplug Detect IRQ thread */
+ if (hdmi_rx->irq[HPD5V_IRQ_IN] > 0) {
+ irq_set_status_flags(hdmi_rx->irq[HPD5V_IRQ_IN], IRQ_NOAUTOEN);
+ ret = devm_request_threaded_irq(dev, hdmi_rx->irq[HPD5V_IRQ_IN],
+ NULL, mxc_hdp5v_irq_thread,
+ IRQF_ONESHOT, dev_name(dev), hdmi_rx);
+ if (ret) {
+ dev_err(&pdev->dev, "can't claim irq %d\n",
+ hdmi_rx->irq[HPD5V_IRQ_IN]);
+ goto failed;
+ }
+ /* Cable Disconnedted, enable Plug in IRQ */
+ if (hpd == 0) {
+ enable_irq(hdmi_rx->irq[HPD5V_IRQ_IN]);
+ hdmi_rx->cable_plugin = false;
+ }
+ }
+ if (hdmi_rx->irq[HPD5V_IRQ_OUT] > 0) {
+ irq_set_status_flags(hdmi_rx->irq[HPD5V_IRQ_OUT], IRQ_NOAUTOEN);
+ ret = devm_request_threaded_irq(dev, hdmi_rx->irq[HPD5V_IRQ_OUT],
+ NULL, mxc_hdp5v_irq_thread,
+ IRQF_ONESHOT, dev_name(dev), hdmi_rx);
+ if (ret) {
+ dev_err(&pdev->dev, "can't claim irq %d\n",
+ hdmi_rx->irq[HPD5V_IRQ_OUT]);
+ goto failed;
+ }
+ if (hpd == 1) {
+ hdmirx_hotplug_trigger(&hdmi_rx->state);
+ hdmirx_startup(&hdmi_rx->state);
+ /* Cable Connected, enable Plug out IRQ */
+ enable_irq(hdmi_rx->irq[HPD5V_IRQ_OUT]);
+ hdmi_rx->cable_plugin = true;
+ }
+ }
+
+ mxc_hdmi_rx_register_audio_driver(dev);
+
+ dev_info(dev, "iMX8 HDMI RX probe successfully\n");
+
+ return ret;
+failed:
+ v4l2_async_unregister_subdev(&hdmi_rx->sd);
+ media_entity_cleanup(&hdmi_rx->sd.entity);
+
+ mxc_hdmi_clock_disable(hdmi_rx);
+ pm_runtime_disable(dev);
+ dev_info(dev, "mxc hdmi rx probe failed\n");
+ return ret;
+}
+
+static int mxc_hdmi_remove(struct platform_device *pdev)
+{
+ struct mxc_hdmi_rx_dev *hdmi_rx = platform_get_drvdata(pdev);
+ state_struct *state = &hdmi_rx->state;
+ struct device *dev = &pdev->dev;
+ u8 sts;
+
+ dev_dbg(dev, "%s\n", __func__);
+ v4l2_async_unregister_subdev(&hdmi_rx->sd);
+ media_entity_cleanup(&hdmi_rx->sd.entity);
+
+#ifdef CONFIG_IMX_HDP_CEC
+ if (hdmi_rx->is_cec)
+ imx_cec_unregister(&hdmi_rx->cec);
+#endif
+
+ /* Reset HDMI RX PHY */
+ CDN_API_HDMIRX_Stop_blocking(state);
+ CDN_API_MainControl_blocking(state, 0, &sts);
+
+ mxc_hdmi_clock_disable(hdmi_rx);
+ pm_runtime_put_sync(dev);
+ pm_runtime_disable(dev);
+
+ return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int mxc_hdmi_pm_suspend(struct device *dev)
+{
+ struct mxc_hdmi_rx_dev *hdmi_rx = dev_get_drvdata(dev);
+
+ dev_dbg(dev, "%s\n", __func__);
+ if ((hdmi_rx->flags & MXC_HDMI_RX_PM_SUSPENDED) ||
+ (hdmi_rx->flags & MXC_HDMI_RX_RUNTIME_SUSPEND))
+ return 0;
+
+ mxc_hdmi_clock_disable(hdmi_rx);
+ hdmi_rx->flags |= MXC_HDMI_RX_PM_SUSPENDED;
+ hdmi_rx->flags &= ~MXC_HDMI_RX_PM_POWERED;
+
+ return 0;
+}
+
+static int mxc_hdmi_pm_resume(struct device *dev)
+{
+ struct mxc_hdmi_rx_dev *hdmi_rx = dev_get_drvdata(dev);
+ int ret;
+
+ dev_dbg(dev, "%s\n", __func__);
+ if (hdmi_rx->flags & MXC_HDMI_RX_PM_POWERED)
+ return 0;
+
+ hdmi_rx->flags |= MXC_HDMI_RX_PM_POWERED;
+ hdmi_rx->flags &= ~MXC_HDMI_RX_PM_SUSPENDED;
+
+ ret = mxc_hdmi_clock_enable(hdmi_rx);
+ return (ret) ? -EAGAIN : 0;
+}
+#endif
+
+static int mxc_hdmi_runtime_suspend(struct device *dev)
+{
+ struct mxc_hdmi_rx_dev *hdmi_rx = dev_get_drvdata(dev);
+
+ dev_dbg(dev, "%s\n", __func__);
+ if (hdmi_rx->flags & MXC_HDMI_RX_RUNTIME_SUSPEND)
+ return 0;
+
+ if (hdmi_rx->flags & MXC_HDMI_RX_PM_POWERED) {
+ mxc_hdmi_clock_disable(hdmi_rx);
+ hdmi_rx->flags |= MXC_HDMI_RX_RUNTIME_SUSPEND;
+ hdmi_rx->flags &= ~MXC_HDMI_RX_PM_POWERED;
+ }
+ return 0;
+}
+
+static int mxc_hdmi_runtime_resume(struct device *dev)
+{
+ struct mxc_hdmi_rx_dev *hdmi_rx = dev_get_drvdata(dev);
+
+ dev_dbg(dev, "%s\n", __func__);
+ if (hdmi_rx->flags & MXC_HDMI_RX_PM_POWERED)
+ return 0;
+
+ if (hdmi_rx->flags & MXC_HDMI_RX_RUNTIME_SUSPEND) {
+ mxc_hdmi_clock_enable(hdmi_rx);
+ hdmi_rx->flags |= MXC_HDMI_RX_PM_POWERED;
+ hdmi_rx->flags &= ~MXC_HDMI_RX_RUNTIME_SUSPEND;
+ }
+ return 0;
+}
+
+static const struct dev_pm_ops mxc_hdmi_pm_ops = {
+ SET_SYSTEM_SLEEP_PM_OPS(mxc_hdmi_pm_suspend, mxc_hdmi_pm_resume)
+ SET_RUNTIME_PM_OPS(mxc_hdmi_runtime_suspend, mxc_hdmi_runtime_resume, NULL)
+};
+
+static const struct of_device_id mxc_hdmi_of_match[] = {
+ {.compatible = "fsl,imx-hdmi-rx",},
+ { /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, mxc_hdmi_of_match);
+
+static struct platform_driver mxc_hdmi_driver = {
+ .probe = mxc_hdmi_probe,
+ .remove = mxc_hdmi_remove,
+ .driver = {
+ .of_match_table = mxc_hdmi_of_match,
+ .name = MXC_HDMI_RX_DRIVER_NAME,
+ .pm = &mxc_hdmi_pm_ops,
+ }
+};
+
+module_platform_driver(mxc_hdmi_driver);
diff --git a/drivers/media/platform/imx8/hdmi/mxc-hdmi-rx.h b/drivers/media/platform/imx8/hdmi/mxc-hdmi-rx.h
new file mode 100644
index 000000000000..1c8292affc0a
--- /dev/null
+++ b/drivers/media/platform/imx8/hdmi/mxc-hdmi-rx.h
@@ -0,0 +1,153 @@
+/*
+ * Copyright 2018 NXP
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _MXC_HDMI_RX_
+#define _MXC_HDMI_RX_
+
+#include <linux/module.h>
+#include <linux/mutex.h>
+
+#include <linux/clk.h>
+#include <linux/of.h>
+#include <linux/of_graph.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-dv-timings.h>
+#include <media/v4l2-ioctl.h>
+#include <media/v4l2-subdev.h>
+#include <soc/imx8/sc/sci.h>
+#include <drm/drm_of.h>
+#include <drm/drmP.h>
+
+#include <uapi/linux/v4l2-dv-timings.h>
+
+#include "../../../../mxc/hdp/all.h"
+#include "../../../../mxc/hdp-cec/imx-hdp-cec.h"
+
+#define state_to_mxc_hdmirx(env) \
+ container_of(env, struct mxc_hdmi_rx_dev, state)
+
+#define MXC_HDMI_RX_DRIVER_NAME "mxc-hdmi-rx"
+#define MXC_HDMI_RX_SUBDEV_NAME MXC_HDMI_RX_DRIVER_NAME
+
+#define MXC_HDMI_RX_NODE_NAME "hdmi_rx"
+
+#define MXC_HDMI_RX_MAX_DEVS 2
+#define MXC_HDMI_RX_MAX_LANES 4
+
+#define MXC_HDMI_RX_PAD_SINK 1
+#define MXC_HDMI_RX_PAD_SOURCE 2
+#define MXC_HDMI_RX_PADS_NUM 3
+
+#define CSR_PIXEL_LINK_ENC_CTL 0x00
+#define PL_ENC_CTL_PXL_VAL 15
+#define PL_ENC_CTL_PXL_VPP 14
+#define PL_ENC_CTL_PXL_HPP 13
+#define PL_ENC_CTL_PXL_VCP 12
+#define PL_ENC_CTL_PXL_HCP 11
+#define PL_ENC_CTL_PXL_ADD 9
+#define PL_ENC_CTL_PXL_EXT 7
+#define PL_ENC_CTL_PXL_EN 6
+#define PL_ENC_CTL_PXL_ITC 4
+#define PL_ENC_CTL_PXL_ODD_EVEN 3
+#define PL_ENC_CTL_PXL_TYP 1
+#define PL_ENC_CTL_PXL_YUV 0
+
+#define CSR_HDP_RX_CTRL_CTRL0 0x04
+#define CSR_HDP_RX_CTRL_CTRL1 0x08
+
+struct mxc_hdmi_rx_dev_video_standards {
+ struct v4l2_dv_timings timings;
+ u8 vic;
+ u8 hdmi_vic;
+ u8 fps;
+};
+
+enum hdp_rx_irq {
+ HPD5V_IRQ_IN,
+ HPD5V_IRQ_OUT,
+ HPD5V_IRQ_NUM,
+};
+
+struct mxc_hdmi_rx_dev {
+ struct mutex lock;
+ wait_queue_head_t irq_queue;
+ struct media_pad pads[MXC_HDMI_RX_PADS_NUM];
+
+ struct platform_device *pdev;
+ struct v4l2_device *v4l2_dev;
+ struct v4l2_subdev sd;
+ struct v4l2_async_subdev asd;
+ struct v4l2_ctrl_handler ctrl_hdl;
+ struct v4l2_mbus_framefmt format;
+ struct v4l2_fract aspect_ratio;
+ struct {
+ u8 edid[512];
+ u32 present;
+ u32 blocks;
+ } edid;
+
+ state_struct state;
+ struct clk *sclk;
+ struct clk *pclk;
+ struct clk *ref_clk;
+ struct clk *pxl_clk;
+ struct clk *enc_clk;
+ struct clk *i2s_clk;
+ struct clk *spdif_clk;
+ struct clk *pxl_link_clk;
+ struct hdp_mem mem;
+
+ u32 flags;
+ sc_ipc_t ipcHndl;
+ u32 mu_id;
+ S_HDMI_SCDC_GET_MSG scdcData;
+
+ struct mxc_hdmi_rx_dev_video_standards *timings;
+ u8 vic_code;
+ u8 hdmi_vic;
+ u8 pixel_encoding;
+ u8 color_depth;
+ bool cable_plugin;
+
+ u8 is_cec;
+ bool cec_running;
+ struct imx_cec_dev cec;
+ u32 sample_rate;
+ u32 sample_width;
+ u32 channels;
+
+ int irq[HPD5V_IRQ_NUM];
+ struct delayed_work hpd5v_work;
+};
+
+enum mxc_hdmi_rx_power_state {
+ MXC_HDMI_RX_PM_SUSPENDED = 0x01,
+ MXC_HDMI_RX_PM_POWERED = 0x02,
+ MXC_HDMI_RX_RUNTIME_SUSPEND = 0x04,
+};
+
+void hdmirx_stop(state_struct *state);
+void hdmirx_hotplug_trigger(state_struct *state);
+void hdmirx_phy_pix_engine_reset(state_struct *state);
+int hdmirx_startup(state_struct *state);
+int hdmirx_init(state_struct *state);
+int hdmirx_get_hpd_state(state_struct *state, u8 *hpd);
+int mxc_hdmi_frame_timing(struct mxc_hdmi_rx_dev *hdmi_rx);
+void mxc_hdmi_rx_register_audio_driver(struct device *dev);
+void imx8qm_hdmi_phy_reset(state_struct *state, u8 reset);
+
+#endif
diff --git a/drivers/media/platform/imx8/max9286.c b/drivers/media/platform/imx8/max9286.c
new file mode 100644
index 000000000000..0fb52f3f4ab3
--- /dev/null
+++ b/drivers/media/platform/imx8/max9286.c
@@ -0,0 +1,3386 @@
+/*
+ * Copyright 2017-2018 NXP
+ */
+/*
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/ctype.h>
+#include <linux/types.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/of_device.h>
+#include <linux/i2c.h>
+#include <linux/v4l2-mediabus.h>
+#include <linux/of_gpio.h>
+#include <linux/pinctrl/consumer.h>
+#include <linux/regulator/consumer.h>
+#include <media/v4l2-subdev.h>
+
+
+#define MAX9271_MAX_SENSOR_NUM 4
+#define CAMERA_USES_15HZ
+
+#define ADDR_MAX9286 0x6A
+#define ADDR_MAX9271 0x40
+#define ADDR_MAX9271_ALL (ADDR_MAX9271 + 5) /* Broadcast address */
+
+#define MIPI_CSI2_SENS_VC0_PAD_SOURCE 0
+#define MIPI_CSI2_SENS_VC1_PAD_SOURCE 1
+#define MIPI_CSI2_SENS_VC2_PAD_SOURCE 2
+#define MIPI_CSI2_SENS_VC3_PAD_SOURCE 3
+#define MIPI_CSI2_SENS_VCX_PADS_NUM 4
+
+#define MAX_FPS 30
+#define MIN_FPS 15
+#define DEFAULT_FPS 30
+
+#define ADDR_OV_SENSOR 0x30
+#define ADDR_AP_SENSOR 0x5D
+
+/*!
+ * Maintains the information on the current state of the sesor.
+ */
+struct imxdpu_videomode {
+ char name[64]; /* may not be needed */
+
+ uint32_t pixelclock; /* Hz */
+
+ /* htotal (pixels) = hlen + hfp + hsync + hbp */
+ uint32_t hlen;
+ uint32_t hfp;
+ uint32_t hbp;
+ uint32_t hsync;
+
+ /* field0 - vtotal (lines) = vlen + vfp + vsync + vbp */
+ uint32_t vlen;
+ uint32_t vfp;
+ uint32_t vbp;
+ uint32_t vsync;
+
+ /* field1 */
+ uint32_t vlen1;
+ uint32_t vfp1;
+ uint32_t vbp1;
+ uint32_t vsync1;
+
+ uint32_t flags;
+
+ uint32_t format;
+ uint32_t dest_format; /*buffer format for capture*/
+
+ int16_t clip_top;
+ int16_t clip_left;
+ uint16_t clip_width;
+ uint16_t clip_height;
+};
+
+struct sensor_data {
+ struct v4l2_subdev subdev;
+ struct media_pad pads[MIPI_CSI2_SENS_VCX_PADS_NUM];
+ struct i2c_client *i2c_client;
+ struct v4l2_mbus_framefmt format;
+ struct v4l2_captureparm streamcap;
+ char running;
+
+ /* control settings */
+ int brightness;
+ int hue;
+ int contrast;
+ int saturation;
+ int red;
+ int green;
+ int blue;
+ int ae_mode;
+
+ u32 mclk;
+ u8 mclk_source;
+ struct clk *sensor_clk;
+ int v_channel;
+ bool is_mipi;
+ struct imxdpu_videomode cap_mode;
+
+ unsigned int sensor_num; /* sensor num connect max9271 */
+ unsigned char sensor_is_there; /* Bit 0~3 for 4 cameras, 0b1= is there; 0b0 = is not there */
+ int pwn_gpio;
+};
+
+#define OV10635_REG_PID 0x300A
+#define OV10635_REG_VER 0x300B
+
+struct reg_value {
+ unsigned short reg_addr;
+ unsigned char val;
+ unsigned int delay_ms;
+};
+
+enum ov10635_mode {
+ ov10635_mode_MIN = 0,
+ ov10635_mode_WXGA_1280_800 = 0,
+ ov10635_mode_720P_1280_720 = 1,
+ ov10635_mode_WVGA_752_480 = 2,
+ ov10635_mode_VGA_640_480 = 3,
+ ov10635_mode_CIF_352_288 = 4,
+ ov10635_mode_QVGA_320_240 = 5,
+ ov10635_mode_MAX = 5,
+};
+
+enum ov10635_frame_rate {
+ OV10635_15_FPS = 0,
+ OV10635_30_FPS,
+};
+
+static int ov10635_framerates[] = {
+ [OV10635_15_FPS] = 15,
+ [OV10635_30_FPS] = 30,
+};
+
+static struct reg_value ov10635_init_data[] = {
+ { 0x0103, 0x01, 0 },
+ { 0x300c, 0x61, 0 },
+ { 0x300c, 0x61, 0 },
+ { 0x300c, 0x61, 0 },
+ { 0x300c, 0x61, 0 },
+ { 0x300c, 0x61, 0 },
+ { 0x300c, 0x61, 0 },
+ { 0x300c, 0x61, 0 },
+ { 0x300c, 0x61, 0 },
+ { 0x300c, 0x61, 0 },
+ { 0x300c, 0x61, 0 },
+ { 0x300c, 0x61, 0 },
+ { 0x300c, 0x61, 0 },
+ { 0x300c, 0x61, 0 },
+ { 0x300c, 0x61, 0 },
+ { 0x300c, 0x61, 0 },
+ { 0x300c, 0x61, 0 },
+ { 0x300c, 0x61, 0 },
+ { 0x300c, 0x61, 0 },
+ { 0x300c, 0x61, 0 },
+ { 0x300c, 0x61, 0 },
+ { 0x300c, 0x61, 0 },
+ { 0x300c, 0x61, 0 },
+ { 0x300c, 0x61, 0 },
+ { 0x301b, 0xff, 0 },
+ { 0x301c, 0xff, 0 },
+ { 0x301a, 0xff, 0 },
+ { 0x3011, 0x42, 0 },
+ { 0x6900, 0x0c, 0 },
+ { 0x6901, 0x11, 0 },
+ { 0x3503, 0x10, 0 },
+ { 0x3025, 0x03, 0 },
+ { 0x3003, 0x20, 0 },
+ { 0x3004, 0x21, 0 },
+ { 0x3005, 0x20, 0 },
+ { 0x3006, 0x91, 0 },
+ { 0x3600, 0x74, 0 },
+ { 0x3601, 0x2b, 0 },
+ { 0x3612, 0x00, 0 },
+ { 0x3611, 0x67, 0 },
+ { 0x3633, 0xca, 0 },
+ { 0x3602, 0x2f, 0 },
+ { 0x3603, 0x00, 0 },
+ { 0x3630, 0x28, 0 },
+ { 0x3631, 0x16, 0 },
+ { 0x3714, 0x10, 0 },
+ { 0x371d, 0x01, 0 },
+ { 0x4300, 0x38, 0 },
+ { 0x3007, 0x01, 0 },
+ { 0x3024, 0x01, 0 },
+ { 0x3020, 0x0b, 0 },
+ { 0x3702, 0x20, 0 },
+ { 0x3703, 0x48, 0 },
+ { 0x3704, 0x32, 0 },
+ { 0x3709, 0xa8, 0 },
+ { 0x3709, 0xa8, 0 },
+ { 0x370c, 0xc7, 0 },
+ { 0x370d, 0x80, 0 },
+ { 0x3712, 0x00, 0 },
+ { 0x3713, 0x20, 0 },
+ { 0x3715, 0x04, 0 },
+ { 0x381d, 0x40, 0 },
+ { 0x381c, 0x00, 0 },
+ { 0x3822, 0x50, 0 },
+ { 0x3824, 0x50, 0 },
+ { 0x3815, 0x8c, 0 },
+ { 0x3804, 0x05, 0 },
+ { 0x3805, 0x1f, 0 },
+ { 0x3800, 0x00, 0 },
+ { 0x3801, 0x00, 0 },
+ { 0x3806, 0x03, 0 },
+ { 0x3807, 0x29, 0 },
+ { 0x3802, 0x00, 0 },
+ { 0x3803, 0x04, 0 },
+ { 0x3808, 0x05, 0 },
+ { 0x3809, 0x00, 0 },
+ { 0x380a, 0x03, 0 },
+ { 0x380b, 0x20, 0 },
+ { 0x380c, 0x07, 0 },
+ { 0x380d, 0x71, 0 },
+ { 0x6e42, 0x03, 0 },
+ { 0x6e43, 0x48, 0 },
+ { 0x380e, 0x03, 0 },
+ { 0x380f, 0x48, 0 },
+ { 0x3813, 0x02, 0 },
+ { 0x3811, 0x10, 0 },
+ { 0x381f, 0x0c, 0 },
+ { 0x3828, 0x03, 0 },
+ { 0x3829, 0x10, 0 },
+ { 0x382a, 0x10, 0 },
+ { 0x382b, 0x10, 0 },
+ { 0x3621, 0x64, 0 },
+ { 0x5005, 0x08, 0 },
+ { 0x56d5, 0x00, 0 },
+ { 0x56d6, 0x80, 0 },
+ { 0x56d7, 0x00, 0 },
+ { 0x56d8, 0x00, 0 },
+ { 0x56d9, 0x00, 0 },
+ { 0x56da, 0x80, 0 },
+ { 0x56db, 0x00, 0 },
+ { 0x56dc, 0x00, 0 },
+ { 0x56e8, 0x00, 0 },
+ { 0x56e9, 0x7f, 0 },
+ { 0x56ea, 0x00, 0 },
+ { 0x56eb, 0x7f, 0 },
+ { 0x5100, 0x00, 0 },
+ { 0x5101, 0x80, 0 },
+ { 0x5102, 0x00, 0 },
+ { 0x5103, 0x80, 0 },
+ { 0x5104, 0x00, 0 },
+ { 0x5105, 0x80, 0 },
+ { 0x5106, 0x00, 0 },
+ { 0x5107, 0x80, 0 },
+ { 0x5108, 0x00, 0 },
+ { 0x5109, 0x00, 0 },
+ { 0x510a, 0x00, 0 },
+ { 0x510b, 0x00, 0 },
+ { 0x510c, 0x00, 0 },
+ { 0x510d, 0x00, 0 },
+ { 0x510e, 0x00, 0 },
+ { 0x510f, 0x00, 0 },
+ { 0x5110, 0x00, 0 },
+ { 0x5111, 0x80, 0 },
+ { 0x5112, 0x00, 0 },
+ { 0x5113, 0x80, 0 },
+ { 0x5114, 0x00, 0 },
+ { 0x5115, 0x80, 0 },
+ { 0x5116, 0x00, 0 },
+ { 0x5117, 0x80, 0 },
+ { 0x5118, 0x00, 0 },
+ { 0x5119, 0x00, 0 },
+ { 0x511a, 0x00, 0 },
+ { 0x511b, 0x00, 0 },
+ { 0x511c, 0x00, 0 },
+ { 0x511d, 0x00, 0 },
+ { 0x511e, 0x00, 0 },
+ { 0x511f, 0x00, 0 },
+ { 0x56d0, 0x00, 0 },
+ { 0x5006, 0x24, 0 },
+ { 0x5608, 0x0d, 0 },
+ { 0x52d7, 0x06, 0 },
+ { 0x528d, 0x08, 0 },
+ { 0x5293, 0x12, 0 },
+ { 0x52d3, 0x12, 0 },
+ { 0x5288, 0x06, 0 },
+ { 0x5289, 0x20, 0 },
+ { 0x52c8, 0x06, 0 },
+ { 0x52c9, 0x20, 0 },
+ { 0x52cd, 0x04, 0 },
+ { 0x5381, 0x00, 0 },
+ { 0x5382, 0xff, 0 },
+ { 0x5589, 0x76, 0 },
+ { 0x558a, 0x47, 0 },
+ { 0x558b, 0xef, 0 },
+ { 0x558c, 0xc9, 0 },
+ { 0x558d, 0x49, 0 },
+ { 0x558e, 0x30, 0 },
+ { 0x558f, 0x67, 0 },
+ { 0x5590, 0x3f, 0 },
+ { 0x5591, 0xf0, 0 },
+ { 0x5592, 0x10, 0 },
+ { 0x55a2, 0x6d, 0 },
+ { 0x55a3, 0x55, 0 },
+ { 0x55a4, 0xc3, 0 },
+ { 0x55a5, 0xb5, 0 },
+ { 0x55a6, 0x43, 0 },
+ { 0x55a7, 0x38, 0 },
+ { 0x55a8, 0x5f, 0 },
+ { 0x55a9, 0x4b, 0 },
+ { 0x55aa, 0xf0, 0 },
+ { 0x55ab, 0x10, 0 },
+ { 0x5581, 0x52, 0 },
+ { 0x5300, 0x01, 0 },
+ { 0x5301, 0x00, 0 },
+ { 0x5302, 0x00, 0 },
+ { 0x5303, 0x0e, 0 },
+ { 0x5304, 0x00, 0 },
+ { 0x5305, 0x0e, 0 },
+ { 0x5306, 0x00, 0 },
+ { 0x5307, 0x36, 0 },
+ { 0x5308, 0x00, 0 },
+ { 0x5309, 0xd9, 0 },
+ { 0x530a, 0x00, 0 },
+ { 0x530b, 0x0f, 0 },
+ { 0x530c, 0x00, 0 },
+ { 0x530d, 0x2c, 0 },
+ { 0x530e, 0x00, 0 },
+ { 0x530f, 0x59, 0 },
+ { 0x5310, 0x00, 0 },
+ { 0x5311, 0x7b, 0 },
+ { 0x5312, 0x00, 0 },
+ { 0x5313, 0x22, 0 },
+ { 0x5314, 0x00, 0 },
+ { 0x5315, 0xd5, 0 },
+ { 0x5316, 0x00, 0 },
+ { 0x5317, 0x13, 0 },
+ { 0x5318, 0x00, 0 },
+ { 0x5319, 0x18, 0 },
+ { 0x531a, 0x00, 0 },
+ { 0x531b, 0x26, 0 },
+ { 0x531c, 0x00, 0 },
+ { 0x531d, 0xdc, 0 },
+ { 0x531e, 0x00, 0 },
+ { 0x531f, 0x02, 0 },
+ { 0x5320, 0x00, 0 },
+ { 0x5321, 0x24, 0 },
+ { 0x5322, 0x00, 0 },
+ { 0x5323, 0x56, 0 },
+ { 0x5324, 0x00, 0 },
+ { 0x5325, 0x85, 0 },
+ { 0x5326, 0x00, 0 },
+ { 0x5327, 0x20, 0 },
+ { 0x5609, 0x01, 0 },
+ { 0x560a, 0x40, 0 },
+ { 0x560b, 0x01, 0 },
+ { 0x560c, 0x40, 0 },
+ { 0x560d, 0x00, 0 },
+ { 0x560e, 0xfa, 0 },
+ { 0x560f, 0x00, 0 },
+ { 0x5610, 0xfa, 0 },
+ { 0x5611, 0x02, 0 },
+ { 0x5612, 0x80, 0 },
+ { 0x5613, 0x02, 0 },
+ { 0x5614, 0x80, 0 },
+ { 0x5615, 0x01, 0 },
+ { 0x5616, 0x2c, 0 },
+ { 0x5617, 0x01, 0 },
+ { 0x5618, 0x2c, 0 },
+ { 0x563b, 0x01, 0 },
+ { 0x563c, 0x01, 0 },
+ { 0x563d, 0x01, 0 },
+ { 0x563e, 0x01, 0 },
+ { 0x563f, 0x03, 0 },
+ { 0x5640, 0x03, 0 },
+ { 0x5641, 0x03, 0 },
+ { 0x5642, 0x05, 0 },
+ { 0x5643, 0x09, 0 },
+ { 0x5644, 0x05, 0 },
+ { 0x5645, 0x05, 0 },
+ { 0x5646, 0x05, 0 },
+ { 0x5647, 0x05, 0 },
+ { 0x5651, 0x00, 0 },
+ { 0x5652, 0x80, 0 },
+ { 0x521a, 0x01, 0 },
+ { 0x521b, 0x03, 0 },
+ { 0x521c, 0x06, 0 },
+ { 0x521d, 0x0a, 0 },
+ { 0x521e, 0x0e, 0 },
+ { 0x521f, 0x12, 0 },
+ { 0x5220, 0x16, 0 },
+ { 0x5223, 0x02, 0 },
+ { 0x5225, 0x04, 0 },
+ { 0x5227, 0x08, 0 },
+ { 0x5229, 0x0c, 0 },
+ { 0x522b, 0x12, 0 },
+ { 0x522d, 0x18, 0 },
+ { 0x522f, 0x1e, 0 },
+ { 0x5241, 0x04, 0 },
+ { 0x5242, 0x01, 0 },
+ { 0x5243, 0x03, 0 },
+ { 0x5244, 0x06, 0 },
+ { 0x5245, 0x0a, 0 },
+ { 0x5246, 0x0e, 0 },
+ { 0x5247, 0x12, 0 },
+ { 0x5248, 0x16, 0 },
+ { 0x524a, 0x03, 0 },
+ { 0x524c, 0x04, 0 },
+ { 0x524e, 0x08, 0 },
+ { 0x5250, 0x0c, 0 },
+ { 0x5252, 0x12, 0 },
+ { 0x5254, 0x18, 0 },
+ { 0x5256, 0x1e, 0 },
+ { 0x4606, 0x07, 0 },
+ { 0x4607, 0x71, 0 },
+ { 0x460a, 0x02, 0 },
+ { 0x460b, 0x70, 0 },
+ { 0x460c, 0x00, 0 },
+ { 0x4620, 0x0e, 0 },
+ { 0x4700, 0x04, 0 },
+ { 0x4701, 0x00, 0 },
+ { 0x4702, 0x01, 0 },
+ { 0x4004, 0x04, 0 },
+ { 0x4005, 0x18, 0 },
+ { 0x4001, 0x06, 0 },
+ { 0x4050, 0x22, 0 },
+ { 0x4051, 0x24, 0 },
+ { 0x4052, 0x02, 0 },
+ { 0x4057, 0x9c, 0 },
+ { 0x405a, 0x00, 0 },
+ { 0x4202, 0x02, 0 },
+ { 0x3023, 0x10, 0 },
+ { 0x100 , 0x0f, 0 },
+ { 0x100 , 0x0f, 0 },
+ { 0x6f10, 0x07, 0 },
+ { 0x6f11, 0x82, 0 },
+ { 0x6f12, 0x04, 0 },
+ { 0x6f13, 0x00, 0 },
+ { 0x6f14, 0x1f, 0 },
+ { 0x6f15, 0xdd, 0 },
+ { 0x6f16, 0x04, 0 },
+ { 0x6f17, 0x04, 0 },
+ { 0x6f18, 0x36, 0 },
+ { 0x6f19, 0x66, 0 },
+ { 0x6f1a, 0x04, 0 },
+ { 0x6f1b, 0x08, 0 },
+ { 0x6f1c, 0x0c, 0 },
+ { 0x6f1d, 0xe7, 0 },
+ { 0x6f1e, 0x04, 0 },
+ { 0x6f1f, 0x0c, 0 },
+ { 0xd000, 0x19, 0 },
+ { 0xd001, 0xa0, 0 },
+ { 0xd002, 0x00, 0 },
+ { 0xd003, 0x01, 0 },
+ { 0xd004, 0xa9, 0 },
+ { 0xd005, 0xad, 0 },
+ { 0xd006, 0x10, 0 },
+ { 0xd007, 0x40, 0 },
+ { 0xd008, 0x44, 0 },
+ { 0xd009, 0x00, 0 },
+ { 0xd00a, 0x68, 0 },
+ { 0xd00b, 0x00, 0 },
+ { 0xd00c, 0x15, 0 },
+ { 0xd00d, 0x00, 0 },
+ { 0xd00e, 0x00, 0 },
+ { 0xd00f, 0x00, 0 },
+ { 0xd010, 0x19, 0 },
+ { 0xd011, 0xa0, 0 },
+ { 0xd012, 0x00, 0 },
+ { 0xd013, 0x01, 0 },
+ { 0xd014, 0xa9, 0 },
+ { 0xd015, 0xad, 0 },
+ { 0xd016, 0x13, 0 },
+ { 0xd017, 0xd0, 0 },
+ { 0xd018, 0x44, 0 },
+ { 0xd019, 0x00, 0 },
+ { 0xd01a, 0x68, 0 },
+ { 0xd01b, 0x00, 0 },
+ { 0xd01c, 0x15, 0 },
+ { 0xd01d, 0x00, 0 },
+ { 0xd01e, 0x00, 0 },
+ { 0xd01f, 0x00, 0 },
+ { 0xd020, 0x19, 0 },
+ { 0xd021, 0xa0, 0 },
+ { 0xd022, 0x00, 0 },
+ { 0xd023, 0x01, 0 },
+ { 0xd024, 0xa9, 0 },
+ { 0xd025, 0xad, 0 },
+ { 0xd026, 0x14, 0 },
+ { 0xd027, 0xb8, 0 },
+ { 0xd028, 0x44, 0 },
+ { 0xd029, 0x00, 0 },
+ { 0xd02a, 0x68, 0 },
+ { 0xd02b, 0x00, 0 },
+ { 0xd02c, 0x15, 0 },
+ { 0xd02d, 0x00, 0 },
+ { 0xd02e, 0x00, 0 },
+ { 0xd02f, 0x00, 0 },
+ { 0xd030, 0x19, 0 },
+ { 0xd031, 0xa0, 0 },
+ { 0xd032, 0x00, 0 },
+ { 0xd033, 0x01, 0 },
+ { 0xd034, 0xa9, 0 },
+ { 0xd035, 0xad, 0 },
+ { 0xd036, 0x14, 0 },
+ { 0xd037, 0xdc, 0 },
+ { 0xd038, 0x44, 0 },
+ { 0xd039, 0x00, 0 },
+ { 0xd03a, 0x68, 0 },
+ { 0xd03b, 0x00, 0 },
+ { 0xd03c, 0x15, 0 },
+ { 0xd03d, 0x00, 0 },
+ { 0xd03e, 0x00, 0 },
+ { 0xd03f, 0x00, 0 },
+ { 0xd040, 0x9c, 0 },
+ { 0xd041, 0x21, 0 },
+ { 0xd042, 0xff, 0 },
+ { 0xd043, 0xe4, 0 },
+ { 0xd044, 0xd4, 0 },
+ { 0xd045, 0x01, 0 },
+ { 0xd046, 0x48, 0 },
+ { 0xd047, 0x00, 0 },
+ { 0xd048, 0xd4, 0 },
+ { 0xd049, 0x01, 0 },
+ { 0xd04a, 0x50, 0 },
+ { 0xd04b, 0x04, 0 },
+ { 0xd04c, 0xd4, 0 },
+ { 0xd04d, 0x01, 0 },
+ { 0xd04e, 0x60, 0 },
+ { 0xd04f, 0x08, 0 },
+ { 0xd050, 0xd4, 0 },
+ { 0xd051, 0x01, 0 },
+ { 0xd052, 0x70, 0 },
+ { 0xd053, 0x0c, 0 },
+ { 0xd054, 0xd4, 0 },
+ { 0xd055, 0x01, 0 },
+ { 0xd056, 0x80, 0 },
+ { 0xd057, 0x10, 0 },
+ { 0xd058, 0x19, 0 },
+ { 0xd059, 0xc0, 0 },
+ { 0xd05a, 0x00, 0 },
+ { 0xd05b, 0x01, 0 },
+ { 0xd05c, 0xa9, 0 },
+ { 0xd05d, 0xce, 0 },
+ { 0xd05e, 0x02, 0 },
+ { 0xd05f, 0xa4, 0 },
+ { 0xd060, 0x9c, 0 },
+ { 0xd061, 0xa0, 0 },
+ { 0xd062, 0x00, 0 },
+ { 0xd063, 0x00, 0 },
+ { 0xd064, 0x84, 0 },
+ { 0xd065, 0x6e, 0 },
+ { 0xd066, 0x00, 0 },
+ { 0xd067, 0x00, 0 },
+ { 0xd068, 0xd8, 0 },
+ { 0xd069, 0x03, 0 },
+ { 0xd06a, 0x28, 0 },
+ { 0xd06b, 0x76, 0 },
+ { 0xd06c, 0x1a, 0 },
+ { 0xd06d, 0x00, 0 },
+ { 0xd06e, 0x00, 0 },
+ { 0xd06f, 0x01, 0 },
+ { 0xd070, 0xaa, 0 },
+ { 0xd071, 0x10, 0 },
+ { 0xd072, 0x03, 0 },
+ { 0xd073, 0xf0, 0 },
+ { 0xd074, 0x18, 0 },
+ { 0xd075, 0x60, 0 },
+ { 0xd076, 0x00, 0 },
+ { 0xd077, 0x01, 0 },
+ { 0xd078, 0xa8, 0 },
+ { 0xd079, 0x63, 0 },
+ { 0xd07a, 0x07, 0 },
+ { 0xd07b, 0x80, 0 },
+ { 0xd07c, 0xe0, 0 },
+ { 0xd07d, 0xa0, 0 },
+ { 0xd07e, 0x00, 0 },
+ { 0xd07f, 0x04, 0 },
+ { 0xd080, 0x18, 0 },
+ { 0xd081, 0xc0, 0 },
+ { 0xd082, 0x00, 0 },
+ { 0xd083, 0x00, 0 },
+ { 0xd084, 0xa8, 0 },
+ { 0xd085, 0xc6, 0 },
+ { 0xd086, 0x00, 0 },
+ { 0xd087, 0x00, 0 },
+ { 0xd088, 0x8c, 0 },
+ { 0xd089, 0x63, 0 },
+ { 0xd08a, 0x00, 0 },
+ { 0xd08b, 0x00, 0 },
+ { 0xd08c, 0xd4, 0 },
+ { 0xd08d, 0x01, 0 },
+ { 0xd08e, 0x28, 0 },
+ { 0xd08f, 0x14, 0 },
+ { 0xd090, 0xd4, 0 },
+ { 0xd091, 0x01, 0 },
+ { 0xd092, 0x30, 0 },
+ { 0xd093, 0x18, 0 },
+ { 0xd094, 0x07, 0 },
+ { 0xd095, 0xff, 0 },
+ { 0xd096, 0xf8, 0 },
+ { 0xd097, 0xfd, 0 },
+ { 0xd098, 0x9c, 0 },
+ { 0xd099, 0x80, 0 },
+ { 0xd09a, 0x00, 0 },
+ { 0xd09b, 0x03, 0 },
+ { 0xd09c, 0xa5, 0 },
+ { 0xd09d, 0x6b, 0 },
+ { 0xd09e, 0x00, 0 },
+ { 0xd09f, 0xff, 0 },
+ { 0xd0a0, 0x18, 0 },
+ { 0xd0a1, 0xc0, 0 },
+ { 0xd0a2, 0x00, 0 },
+ { 0xd0a3, 0x01, 0 },
+ { 0xd0a4, 0xa8, 0 },
+ { 0xd0a5, 0xc6, 0 },
+ { 0xd0a6, 0x01, 0 },
+ { 0xd0a7, 0x02, 0 },
+ { 0xd0a8, 0xe1, 0 },
+ { 0xd0a9, 0x6b, 0 },
+ { 0xd0aa, 0x58, 0 },
+ { 0xd0ab, 0x00, 0 },
+ { 0xd0ac, 0x84, 0 },
+ { 0xd0ad, 0x8e, 0 },
+ { 0xd0ae, 0x00, 0 },
+ { 0xd0af, 0x00, 0 },
+ { 0xd0b0, 0xe1, 0 },
+ { 0xd0b1, 0x6b, 0 },
+ { 0xd0b2, 0x30, 0 },
+ { 0xd0b3, 0x00, 0 },
+ { 0xd0b4, 0x98, 0 },
+ { 0xd0b5, 0xb0, 0 },
+ { 0xd0b6, 0x00, 0 },
+ { 0xd0b7, 0x00, 0 },
+ { 0xd0b8, 0x8c, 0 },
+ { 0xd0b9, 0x64, 0 },
+ { 0xd0ba, 0x00, 0 },
+ { 0xd0bb, 0x6e, 0 },
+ { 0xd0bc, 0xe5, 0 },
+ { 0xd0bd, 0xa5, 0 },
+ { 0xd0be, 0x18, 0 },
+ { 0xd0bf, 0x00, 0 },
+ { 0xd0c0, 0x10, 0 },
+ { 0xd0c1, 0x00, 0 },
+ { 0xd0c2, 0x00, 0 },
+ { 0xd0c3, 0x06, 0 },
+ { 0xd0c4, 0x95, 0 },
+ { 0xd0c5, 0x8b, 0 },
+ { 0xd0c6, 0x00, 0 },
+ { 0xd0c7, 0x00, 0 },
+ { 0xd0c8, 0x94, 0 },
+ { 0xd0c9, 0xa4, 0 },
+ { 0xd0ca, 0x00, 0 },
+ { 0xd0cb, 0x70, 0 },
+ { 0xd0cc, 0xe5, 0 },
+ { 0xd0cd, 0x65, 0 },
+ { 0xd0ce, 0x60, 0 },
+ { 0xd0cf, 0x00, 0 },
+ { 0xd0d0, 0x0c, 0 },
+ { 0xd0d1, 0x00, 0 },
+ { 0xd0d2, 0x00, 0 },
+ { 0xd0d3, 0x62, 0 },
+ { 0xd0d4, 0x15, 0 },
+ { 0xd0d5, 0x00, 0 },
+ { 0xd0d6, 0x00, 0 },
+ { 0xd0d7, 0x00, 0 },
+ { 0xd0d8, 0x18, 0 },
+ { 0xd0d9, 0x60, 0 },
+ { 0xd0da, 0x80, 0 },
+ { 0xd0db, 0x06, 0 },
+ { 0xd0dc, 0xa8, 0 },
+ { 0xd0dd, 0x83, 0 },
+ { 0xd0de, 0x38, 0 },
+ { 0xd0df, 0x29, 0 },
+ { 0xd0e0, 0xa8, 0 },
+ { 0xd0e1, 0xe3, 0 },
+ { 0xd0e2, 0x40, 0 },
+ { 0xd0e3, 0x08, 0 },
+ { 0xd0e4, 0x8c, 0 },
+ { 0xd0e5, 0x84, 0 },
+ { 0xd0e6, 0x00, 0 },
+ { 0xd0e7, 0x00, 0 },
+ { 0xd0e8, 0xa8, 0 },
+ { 0xd0e9, 0xa3, 0 },
+ { 0xd0ea, 0x40, 0 },
+ { 0xd0eb, 0x09, 0 },
+ { 0xd0ec, 0xa8, 0 },
+ { 0xd0ed, 0xc3, 0 },
+ { 0xd0ee, 0x38, 0 },
+ { 0xd0ef, 0x2a, 0 },
+ { 0xd0f0, 0xd8, 0 },
+ { 0xd0f1, 0x07, 0 },
+ { 0xd0f2, 0x20, 0 },
+ { 0xd0f3, 0x00, 0 },
+ { 0xd0f4, 0x8c, 0 },
+ { 0xd0f5, 0x66, 0 },
+ { 0xd0f6, 0x00, 0 },
+ { 0xd0f7, 0x00, 0 },
+ { 0xd0f8, 0xd8, 0 },
+ { 0xd0f9, 0x05, 0 },
+ { 0xd0fa, 0x18, 0 },
+ { 0xd0fb, 0x00, 0 },
+ { 0xd0fc, 0x18, 0 },
+ { 0xd0fd, 0x60, 0 },
+ { 0xd0fe, 0x00, 0 },
+ { 0xd0ff, 0x01, 0 },
+ { 0xd100, 0x98, 0 },
+ { 0xd101, 0x90, 0 },
+ { 0xd102, 0x00, 0 },
+ { 0xd103, 0x00, 0 },
+ { 0xd104, 0x84, 0 },
+ { 0xd105, 0xae, 0 },
+ { 0xd106, 0x00, 0 },
+ { 0xd107, 0x00, 0 },
+ { 0xd108, 0xa8, 0 },
+ { 0xd109, 0x63, 0 },
+ { 0xd10a, 0x06, 0 },
+ { 0xd10b, 0x4c, 0 },
+ { 0xd10c, 0x9c, 0 },
+ { 0xd10d, 0xc0, 0 },
+ { 0xd10e, 0x00, 0 },
+ { 0xd10f, 0x00, 0 },
+ { 0xd110, 0xd8, 0 },
+ { 0xd111, 0x03, 0 },
+ { 0xd112, 0x30, 0 },
+ { 0xd113, 0x00, 0 },
+ { 0xd114, 0x8c, 0 },
+ { 0xd115, 0x65, 0 },
+ { 0xd116, 0x00, 0 },
+ { 0xd117, 0x6e, 0 },
+ { 0xd118, 0xe5, 0 },
+ { 0xd119, 0x84, 0 },
+ { 0xd11a, 0x18, 0 },
+ { 0xd11b, 0x00, 0 },
+ { 0xd11c, 0x10, 0 },
+ { 0xd11d, 0x00, 0 },
+ { 0xd11e, 0x00, 0 },
+ { 0xd11f, 0x07, 0 },
+ { 0xd120, 0x18, 0 },
+ { 0xd121, 0x80, 0 },
+ { 0xd122, 0x80, 0 },
+ { 0xd123, 0x06, 0 },
+ { 0xd124, 0x94, 0 },
+ { 0xd125, 0x65, 0 },
+ { 0xd126, 0x00, 0 },
+ { 0xd127, 0x70, 0 },
+ { 0xd128, 0xe5, 0 },
+ { 0xd129, 0x43, 0 },
+ { 0xd12a, 0x60, 0 },
+ { 0xd12b, 0x00, 0 },
+ { 0xd12c, 0x0c, 0 },
+ { 0xd12d, 0x00, 0 },
+ { 0xd12e, 0x00, 0 },
+ { 0xd12f, 0x3e, 0 },
+ { 0xd130, 0xa8, 0 },
+ { 0xd131, 0x64, 0 },
+ { 0xd132, 0x38, 0 },
+ { 0xd133, 0x24, 0 },
+ { 0xd134, 0x18, 0 },
+ { 0xd135, 0x80, 0 },
+ { 0xd136, 0x80, 0 },
+ { 0xd137, 0x06, 0 },
+ { 0xd138, 0xa8, 0 },
+ { 0xd139, 0x64, 0 },
+ { 0xd13a, 0x38, 0 },
+ { 0xd13b, 0x24, 0 },
+ { 0xd13c, 0x8c, 0 },
+ { 0xd13d, 0x63, 0 },
+ { 0xd13e, 0x00, 0 },
+ { 0xd13f, 0x00, 0 },
+ { 0xd140, 0xa4, 0 },
+ { 0xd141, 0x63, 0 },
+ { 0xd142, 0x00, 0 },
+ { 0xd143, 0x40, 0 },
+ { 0xd144, 0xbc, 0 },
+ { 0xd145, 0x23, 0 },
+ { 0xd146, 0x00, 0 },
+ { 0xd147, 0x00, 0 },
+ { 0xd148, 0x0c, 0 },
+ { 0xd149, 0x00, 0 },
+ { 0xd14a, 0x00, 0 },
+ { 0xd14b, 0x2a, 0 },
+ { 0xd14c, 0xa8, 0 },
+ { 0xd14d, 0x64, 0 },
+ { 0xd14e, 0x6e, 0 },
+ { 0xd14f, 0x44, 0 },
+ { 0xd150, 0x19, 0 },
+ { 0xd151, 0x00, 0 },
+ { 0xd152, 0x80, 0 },
+ { 0xd153, 0x06, 0 },
+ { 0xd154, 0xa8, 0 },
+ { 0xd155, 0xe8, 0 },
+ { 0xd156, 0x3d, 0 },
+ { 0xd157, 0x05, 0 },
+ { 0xd158, 0x8c, 0 },
+ { 0xd159, 0x67, 0 },
+ { 0xd15a, 0x00, 0 },
+ { 0xd15b, 0x00, 0 },
+ { 0xd15c, 0xb8, 0 },
+ { 0xd15d, 0x63, 0 },
+ { 0xd15e, 0x00, 0 },
+ { 0xd15f, 0x18, 0 },
+ { 0xd160, 0xb8, 0 },
+ { 0xd161, 0x63, 0 },
+ { 0xd162, 0x00, 0 },
+ { 0xd163, 0x98, 0 },
+ { 0xd164, 0xbc, 0 },
+ { 0xd165, 0x03, 0 },
+ { 0xd166, 0x00, 0 },
+ { 0xd167, 0x00, 0 },
+ { 0xd168, 0x10, 0 },
+ { 0xd169, 0x00, 0 },
+ { 0xd16a, 0x00, 0 },
+ { 0xd16b, 0x10, 0 },
+ { 0xd16c, 0xa9, 0 },
+ { 0xd16d, 0x48, 0 },
+ { 0xd16e, 0x67, 0 },
+ { 0xd16f, 0x02, 0 },
+ { 0xd170, 0xb8, 0 },
+ { 0xd171, 0xa3, 0 },
+ { 0xd172, 0x00, 0 },
+ { 0xd173, 0x19, 0 },
+ { 0xd174, 0x8c, 0 },
+ { 0xd175, 0x8a, 0 },
+ { 0xd176, 0x00, 0 },
+ { 0xd177, 0x00, 0 },
+ { 0xd178, 0xa9, 0 },
+ { 0xd179, 0x68, 0 },
+ { 0xd17a, 0x67, 0 },
+ { 0xd17b, 0x03, 0 },
+ { 0xd17c, 0xb8, 0 },
+ { 0xd17d, 0xc4, 0 },
+ { 0xd17e, 0x00, 0 },
+ { 0xd17f, 0x08, 0 },
+ { 0xd180, 0x8c, 0 },
+ { 0xd181, 0x6b, 0 },
+ { 0xd182, 0x00, 0 },
+ { 0xd183, 0x00, 0 },
+ { 0xd184, 0xb8, 0 },
+ { 0xd185, 0x85, 0 },
+ { 0xd186, 0x00, 0 },
+ { 0xd187, 0x98, 0 },
+ { 0xd188, 0xe0, 0 },
+ { 0xd189, 0x63, 0 },
+ { 0xd18a, 0x30, 0 },
+ { 0xd18b, 0x04, 0 },
+ { 0xd18c, 0xe0, 0 },
+ { 0xd18d, 0x64, 0 },
+ { 0xd18e, 0x18, 0 },
+ { 0xd18f, 0x00, 0 },
+ { 0xd190, 0xa4, 0 },
+ { 0xd191, 0x83, 0 },
+ { 0xd192, 0xff, 0 },
+ { 0xd193, 0xff, 0 },
+ { 0xd194, 0xb8, 0 },
+ { 0xd195, 0x64, 0 },
+ { 0xd196, 0x00, 0 },
+ { 0xd197, 0x48, 0 },
+ { 0xd198, 0xd8, 0 },
+ { 0xd199, 0x0a, 0 },
+ { 0xd19a, 0x18, 0 },
+ { 0xd19b, 0x00, 0 },
+ { 0xd19c, 0xd8, 0 },
+ { 0xd19d, 0x0b, 0 },
+ { 0xd19e, 0x20, 0 },
+ { 0xd19f, 0x00, 0 },
+ { 0xd1a0, 0x9c, 0 },
+ { 0xd1a1, 0x60, 0 },
+ { 0xd1a2, 0x00, 0 },
+ { 0xd1a3, 0x00, 0 },
+ { 0xd1a4, 0xd8, 0 },
+ { 0xd1a5, 0x07, 0 },
+ { 0xd1a6, 0x18, 0 },
+ { 0xd1a7, 0x00, 0 },
+ { 0xd1a8, 0xa8, 0 },
+ { 0xd1a9, 0x68, 0 },
+ { 0xd1aa, 0x38, 0 },
+ { 0xd1ab, 0x22, 0 },
+ { 0xd1ac, 0x9c, 0 },
+ { 0xd1ad, 0x80, 0 },
+ { 0xd1ae, 0x00, 0 },
+ { 0xd1af, 0x70, 0 },
+ { 0xd1b0, 0xa8, 0 },
+ { 0xd1b1, 0xe8, 0 },
+ { 0xd1b2, 0x38, 0 },
+ { 0xd1b3, 0x43, 0 },
+ { 0xd1b4, 0xd8, 0 },
+ { 0xd1b5, 0x03, 0 },
+ { 0xd1b6, 0x20, 0 },
+ { 0xd1b7, 0x00, 0 },
+ { 0xd1b8, 0x9c, 0 },
+ { 0xd1b9, 0xa0, 0 },
+ { 0xd1ba, 0x00, 0 },
+ { 0xd1bb, 0x00, 0 },
+ { 0xd1bc, 0xa8, 0 },
+ { 0xd1bd, 0xc8, 0 },
+ { 0xd1be, 0x38, 0 },
+ { 0xd1bf, 0x42, 0 },
+ { 0xd1c0, 0x8c, 0 },
+ { 0xd1c1, 0x66, 0 },
+ { 0xd1c2, 0x00, 0 },
+ { 0xd1c3, 0x00, 0 },
+ { 0xd1c4, 0x9c, 0 },
+ { 0xd1c5, 0xa5, 0 },
+ { 0xd1c6, 0x00, 0 },
+ { 0xd1c7, 0x01, 0 },
+ { 0xd1c8, 0xb8, 0 },
+ { 0xd1c9, 0x83, 0 },
+ { 0xd1ca, 0x00, 0 },
+ { 0xd1cb, 0x08, 0 },
+ { 0xd1cc, 0xa4, 0 },
+ { 0xd1cd, 0xa5, 0 },
+ { 0xd1ce, 0x00, 0 },
+ { 0xd1cf, 0xff, 0 },
+ { 0xd1d0, 0x8c, 0 },
+ { 0xd1d1, 0x67, 0 },
+ { 0xd1d2, 0x00, 0 },
+ { 0xd1d3, 0x00, 0 },
+ { 0xd1d4, 0xe0, 0 },
+ { 0xd1d5, 0x63, 0 },
+ { 0xd1d6, 0x20, 0 },
+ { 0xd1d7, 0x00, 0 },
+ { 0xd1d8, 0xa4, 0 },
+ { 0xd1d9, 0x63, 0 },
+ { 0xd1da, 0xff, 0 },
+ { 0xd1db, 0xff, 0 },
+ { 0xd1dc, 0xbc, 0 },
+ { 0xd1dd, 0x43, 0 },
+ { 0xd1de, 0x00, 0 },
+ { 0xd1df, 0x07, 0 },
+ { 0xd1e0, 0x0c, 0 },
+ { 0xd1e1, 0x00, 0 },
+ { 0xd1e2, 0x00, 0 },
+ { 0xd1e3, 0x5b, 0 },
+ { 0xd1e4, 0xbc, 0 },
+ { 0xd1e5, 0x05, 0 },
+ { 0xd1e6, 0x00, 0 },
+ { 0xd1e7, 0x02, 0 },
+ { 0xd1e8, 0x03, 0 },
+ { 0xd1e9, 0xff, 0 },
+ { 0xd1ea, 0xff, 0 },
+ { 0xd1eb, 0xf6, 0 },
+ { 0xd1ec, 0x9c, 0 },
+ { 0xd1ed, 0xa0, 0 },
+ { 0xd1ee, 0x00, 0 },
+ { 0xd1ef, 0x00, 0 },
+ { 0xd1f0, 0xa8, 0 },
+ { 0xd1f1, 0xa4, 0 },
+ { 0xd1f2, 0x55, 0 },
+ { 0xd1f3, 0x86, 0 },
+ { 0xd1f4, 0x8c, 0 },
+ { 0xd1f5, 0x63, 0 },
+ { 0xd1f6, 0x00, 0 },
+ { 0xd1f7, 0x00, 0 },
+ { 0xd1f8, 0xa8, 0 },
+ { 0xd1f9, 0xc4, 0 },
+ { 0xd1fa, 0x6e, 0 },
+ { 0xd1fb, 0x45, 0 },
+ { 0xd1fc, 0xa8, 0 },
+ { 0xd1fd, 0xe4, 0 },
+ { 0xd1fe, 0x55, 0 },
+ { 0xd1ff, 0x87, 0 },
+ { 0xd200, 0xd8, 0 },
+ { 0xd201, 0x05, 0 },
+ { 0xd202, 0x18, 0 },
+ { 0xd203, 0x00, 0 },
+ { 0xd204, 0x8c, 0 },
+ { 0xd205, 0x66, 0 },
+ { 0xd206, 0x00, 0 },
+ { 0xd207, 0x00, 0 },
+ { 0xd208, 0xa8, 0 },
+ { 0xd209, 0xa4, 0 },
+ { 0xd20a, 0x6e, 0 },
+ { 0xd20b, 0x46, 0 },
+ { 0xd20c, 0xd8, 0 },
+ { 0xd20d, 0x07, 0 },
+ { 0xd20e, 0x18, 0 },
+ { 0xd20f, 0x00, 0 },
+ { 0xd210, 0xa8, 0 },
+ { 0xd211, 0x84, 0 },
+ { 0xd212, 0x55, 0 },
+ { 0xd213, 0x88, 0 },
+ { 0xd214, 0x8c, 0 },
+ { 0xd215, 0x65, 0 },
+ { 0xd216, 0x00, 0 },
+ { 0xd217, 0x00, 0 },
+ { 0xd218, 0xd8, 0 },
+ { 0xd219, 0x04, 0 },
+ { 0xd21a, 0x18, 0 },
+ { 0xd21b, 0x00, 0 },
+ { 0xd21c, 0x03, 0 },
+ { 0xd21d, 0xff, 0 },
+ { 0xd21e, 0xff, 0 },
+ { 0xd21f, 0xce, 0 },
+ { 0xd220, 0x19, 0 },
+ { 0xd221, 0x00, 0 },
+ { 0xd222, 0x80, 0 },
+ { 0xd223, 0x06, 0 },
+ { 0xd224, 0x8c, 0 },
+ { 0xd225, 0x63, 0 },
+ { 0xd226, 0x00, 0 },
+ { 0xd227, 0x00, 0 },
+ { 0xd228, 0xa4, 0 },
+ { 0xd229, 0x63, 0 },
+ { 0xd22a, 0x00, 0 },
+ { 0xd22b, 0x40, 0 },
+ { 0xd22c, 0xbc, 0 },
+ { 0xd22d, 0x23, 0 },
+ { 0xd22e, 0x00, 0 },
+ { 0xd22f, 0x00, 0 },
+ { 0xd230, 0x13, 0 },
+ { 0xd231, 0xff, 0 },
+ { 0xd232, 0xff, 0 },
+ { 0xd233, 0xc8, 0 },
+ { 0xd234, 0x9d, 0 },
+ { 0xd235, 0x00, 0 },
+ { 0xd236, 0x00, 0 },
+ { 0xd237, 0x40, 0 },
+ { 0xd238, 0xa8, 0 },
+ { 0xd239, 0x64, 0 },
+ { 0xd23a, 0x55, 0 },
+ { 0xd23b, 0x86, 0 },
+ { 0xd23c, 0xa8, 0 },
+ { 0xd23d, 0xa4, 0 },
+ { 0xd23e, 0x55, 0 },
+ { 0xd23f, 0x87, 0 },
+ { 0xd240, 0xd8, 0 },
+ { 0xd241, 0x03, 0 },
+ { 0xd242, 0x40, 0 },
+ { 0xd243, 0x00, 0 },
+ { 0xd244, 0xa8, 0 },
+ { 0xd245, 0x64, 0 },
+ { 0xd246, 0x55, 0 },
+ { 0xd247, 0x88, 0 },
+ { 0xd248, 0xd8, 0 },
+ { 0xd249, 0x05, 0 },
+ { 0xd24a, 0x40, 0 },
+ { 0xd24b, 0x00, 0 },
+ { 0xd24c, 0xd8, 0 },
+ { 0xd24d, 0x03, 0 },
+ { 0xd24e, 0x40, 0 },
+ { 0xd24f, 0x00, 0 },
+ { 0xd250, 0x03, 0 },
+ { 0xd251, 0xff, 0 },
+ { 0xd252, 0xff, 0 },
+ { 0xd253, 0xc1, 0 },
+ { 0xd254, 0x19, 0 },
+ { 0xd255, 0x00, 0 },
+ { 0xd256, 0x80, 0 },
+ { 0xd257, 0x06, 0 },
+ { 0xd258, 0x94, 0 },
+ { 0xd259, 0x84, 0 },
+ { 0xd25a, 0x00, 0 },
+ { 0xd25b, 0x72, 0 },
+ { 0xd25c, 0xe5, 0 },
+ { 0xd25d, 0xa4, 0 },
+ { 0xd25e, 0x60, 0 },
+ { 0xd25f, 0x00, 0 },
+ { 0xd260, 0x0c, 0 },
+ { 0xd261, 0x00, 0 },
+ { 0xd262, 0x00, 0 },
+ { 0xd263, 0x3f, 0 },
+ { 0xd264, 0x9d, 0 },
+ { 0xd265, 0x60, 0 },
+ { 0xd266, 0x01, 0 },
+ { 0xd267, 0x00, 0 },
+ { 0xd268, 0x85, 0 },
+ { 0xd269, 0x4e, 0 },
+ { 0xd26a, 0x00, 0 },
+ { 0xd26b, 0x00, 0 },
+ { 0xd26c, 0x98, 0 },
+ { 0xd26d, 0x70, 0 },
+ { 0xd26e, 0x00, 0 },
+ { 0xd26f, 0x00, 0 },
+ { 0xd270, 0x8c, 0 },
+ { 0xd271, 0x8a, 0 },
+ { 0xd272, 0x00, 0 },
+ { 0xd273, 0x6f, 0 },
+ { 0xd274, 0xe5, 0 },
+ { 0xd275, 0x63, 0 },
+ { 0xd276, 0x20, 0 },
+ { 0xd277, 0x00, 0 },
+ { 0xd278, 0x10, 0 },
+ { 0xd279, 0x00, 0 },
+ { 0xd27a, 0x00, 0 },
+ { 0xd27b, 0x07, 0 },
+ { 0xd27c, 0x15, 0 },
+ { 0xd27d, 0x00, 0 },
+ { 0xd27e, 0x00, 0 },
+ { 0xd27f, 0x00, 0 },
+ { 0xd280, 0x8c, 0 },
+ { 0xd281, 0xaa, 0 },
+ { 0xd282, 0x00, 0 },
+ { 0xd283, 0x6e, 0 },
+ { 0xd284, 0xe0, 0 },
+ { 0xd285, 0x63, 0 },
+ { 0xd286, 0x28, 0 },
+ { 0xd287, 0x02, 0 },
+ { 0xd288, 0xe0, 0 },
+ { 0xd289, 0x84, 0 },
+ { 0xd28a, 0x28, 0 },
+ { 0xd28b, 0x02, 0 },
+ { 0xd28c, 0x07, 0 },
+ { 0xd28d, 0xff, 0 },
+ { 0xd28e, 0xf8, 0 },
+ { 0xd28f, 0x66, 0 },
+ { 0xd290, 0xe0, 0 },
+ { 0xd291, 0x63, 0 },
+ { 0xd292, 0x5b, 0 },
+ { 0xd293, 0x06, 0 },
+ { 0xd294, 0x8c, 0 },
+ { 0xd295, 0x6a, 0 },
+ { 0xd296, 0x00, 0 },
+ { 0xd297, 0x77, 0 },
+ { 0xd298, 0xe0, 0 },
+ { 0xd299, 0x63, 0 },
+ { 0xd29a, 0x5b, 0 },
+ { 0xd29b, 0x06, 0 },
+ { 0xd29c, 0xbd, 0 },
+ { 0xd29d, 0x63, 0 },
+ { 0xd29e, 0x00, 0 },
+ { 0xd29f, 0x00, 0 },
+ { 0xd2a0, 0x0c, 0 },
+ { 0xd2a1, 0x00, 0 },
+ { 0xd2a2, 0x00, 0 },
+ { 0xd2a3, 0x3c, 0 },
+ { 0xd2a4, 0x15, 0 },
+ { 0xd2a5, 0x00, 0 },
+ { 0xd2a6, 0x00, 0 },
+ { 0xd2a7, 0x00, 0 },
+ { 0xd2a8, 0x8c, 0 },
+ { 0xd2a9, 0x8a, 0 },
+ { 0xd2aa, 0x00, 0 },
+ { 0xd2ab, 0x78, 0 },
+ { 0xd2ac, 0xb8, 0 },
+ { 0xd2ad, 0x63, 0 },
+ { 0xd2ae, 0x00, 0 },
+ { 0xd2af, 0x88, 0 },
+ { 0xd2b0, 0xe1, 0 },
+ { 0xd2b1, 0x64, 0 },
+ { 0xd2b2, 0x5b, 0 },
+ { 0xd2b3, 0x06, 0 },
+ { 0xd2b4, 0xbd, 0 },
+ { 0xd2b5, 0x6b, 0 },
+ { 0xd2b6, 0x00, 0 },
+ { 0xd2b7, 0x00, 0 },
+ { 0xd2b8, 0x0c, 0 },
+ { 0xd2b9, 0x00, 0 },
+ { 0xd2ba, 0x00, 0 },
+ { 0xd2bb, 0x34, 0 },
+ { 0xd2bc, 0xd4, 0 },
+ { 0xd2bd, 0x01, 0 },
+ { 0xd2be, 0x18, 0 },
+ { 0xd2bf, 0x14, 0 },
+ { 0xd2c0, 0xb9, 0 },
+ { 0xd2c1, 0x6b, 0 },
+ { 0xd2c2, 0x00, 0 },
+ { 0xd2c3, 0x88, 0 },
+ { 0xd2c4, 0x85, 0 },
+ { 0xd2c5, 0x01, 0 },
+ { 0xd2c6, 0x00, 0 },
+ { 0xd2c7, 0x14, 0 },
+ { 0xd2c8, 0xbd, 0 },
+ { 0xd2c9, 0x68, 0 },
+ { 0xd2ca, 0x00, 0 },
+ { 0xd2cb, 0x00, 0 },
+ { 0xd2cc, 0x0c, 0 },
+ { 0xd2cd, 0x00, 0 },
+ { 0xd2ce, 0x00, 0 },
+ { 0xd2cf, 0x2c, 0 },
+ { 0xd2d0, 0xd4, 0 },
+ { 0xd2d1, 0x01, 0 },
+ { 0xd2d2, 0x58, 0 },
+ { 0xd2d3, 0x18, 0 },
+ { 0xd2d4, 0x84, 0 },
+ { 0xd2d5, 0x81, 0 },
+ { 0xd2d6, 0x00, 0 },
+ { 0xd2d7, 0x14, 0 },
+ { 0xd2d8, 0xbd, 0 },
+ { 0xd2d9, 0xa4, 0 },
+ { 0xd2da, 0x01, 0 },
+ { 0xd2db, 0x00, 0 },
+ { 0xd2dc, 0x10, 0 },
+ { 0xd2dd, 0x00, 0 },
+ { 0xd2de, 0x00, 0 },
+ { 0xd2df, 0x05, 0 },
+ { 0xd2e0, 0x84, 0 },
+ { 0xd2e1, 0xc1, 0 },
+ { 0xd2e2, 0x00, 0 },
+ { 0xd2e3, 0x18, 0 },
+ { 0xd2e4, 0x9c, 0 },
+ { 0xd2e5, 0xa0, 0 },
+ { 0xd2e6, 0x01, 0 },
+ { 0xd2e7, 0x00, 0 },
+ { 0xd2e8, 0xd4, 0 },
+ { 0xd2e9, 0x01, 0 },
+ { 0xd2ea, 0x28, 0 },
+ { 0xd2eb, 0x14, 0 },
+ { 0xd2ec, 0x84, 0 },
+ { 0xd2ed, 0xc1, 0 },
+ { 0xd2ee, 0x00, 0 },
+ { 0xd2ef, 0x18, 0 },
+ { 0xd2f0, 0xbd, 0 },
+ { 0xd2f1, 0x66, 0 },
+ { 0xd2f2, 0x00, 0 },
+ { 0xd2f3, 0x00, 0 },
+ { 0xd2f4, 0x0c, 0 },
+ { 0xd2f5, 0x00, 0 },
+ { 0xd2f6, 0x00, 0 },
+ { 0xd2f7, 0x20, 0 },
+ { 0xd2f8, 0x9d, 0 },
+ { 0xd2f9, 0x00, 0 },
+ { 0xd2fa, 0x00, 0 },
+ { 0xd2fb, 0x00, 0 },
+ { 0xd2fc, 0x84, 0 },
+ { 0xd2fd, 0x61, 0 },
+ { 0xd2fe, 0x00, 0 },
+ { 0xd2ff, 0x18, 0 },
+ { 0xd300, 0xbd, 0 },
+ { 0xd301, 0xa3, 0 },
+ { 0xd302, 0x01, 0 },
+ { 0xd303, 0x00, 0 },
+ { 0xd304, 0x10, 0 },
+ { 0xd305, 0x00, 0 },
+ { 0xd306, 0x00, 0 },
+ { 0xd307, 0x03, 0 },
+ { 0xd308, 0x9c, 0 },
+ { 0xd309, 0x80, 0 },
+ { 0xd30a, 0x01, 0 },
+ { 0xd30b, 0x00, 0 },
+ { 0xd30c, 0xd4, 0 },
+ { 0xd30d, 0x01, 0 },
+ { 0xd30e, 0x20, 0 },
+ { 0xd30f, 0x18, 0 },
+ { 0xd310, 0x18, 0 },
+ { 0xd311, 0x60, 0 },
+ { 0xd312, 0x80, 0 },
+ { 0xd313, 0x06, 0 },
+ { 0xd314, 0x85, 0 },
+ { 0xd315, 0x01, 0 },
+ { 0xd316, 0x00, 0 },
+ { 0xd317, 0x14, 0 },
+ { 0xd318, 0xa8, 0 },
+ { 0xd319, 0x83, 0 },
+ { 0xd31a, 0x38, 0 },
+ { 0xd31b, 0x29, 0 },
+ { 0xd31c, 0xa8, 0 },
+ { 0xd31d, 0xc3, 0 },
+ { 0xd31e, 0x40, 0 },
+ { 0xd31f, 0x08, 0 },
+ { 0xd320, 0x8c, 0 },
+ { 0xd321, 0x84, 0 },
+ { 0xd322, 0x00, 0 },
+ { 0xd323, 0x00, 0 },
+ { 0xd324, 0xa8, 0 },
+ { 0xd325, 0xa3, 0 },
+ { 0xd326, 0x38, 0 },
+ { 0xd327, 0x2a, 0 },
+ { 0xd328, 0xa8, 0 },
+ { 0xd329, 0xe3, 0 },
+ { 0xd32a, 0x40, 0 },
+ { 0xd32b, 0x09, 0 },
+ { 0xd32c, 0xe0, 0 },
+ { 0xd32d, 0x64, 0 },
+ { 0xd32e, 0x40, 0 },
+ { 0xd32f, 0x00, 0 },
+ { 0xd330, 0xd8, 0 },
+ { 0xd331, 0x06, 0 },
+ { 0xd332, 0x18, 0 },
+ { 0xd333, 0x00, 0 },
+ { 0xd334, 0x8c, 0 },
+ { 0xd335, 0x65, 0 },
+ { 0xd336, 0x00, 0 },
+ { 0xd337, 0x00, 0 },
+ { 0xd338, 0x84, 0 },
+ { 0xd339, 0x81, 0 },
+ { 0xd33a, 0x00, 0 },
+ { 0xd33b, 0x18, 0 },
+ { 0xd33c, 0xe3, 0 },
+ { 0xd33d, 0xe3, 0 },
+ { 0xd33e, 0x20, 0 },
+ { 0xd33f, 0x00, 0 },
+ { 0xd340, 0xd8, 0 },
+ { 0xd341, 0x07, 0 },
+ { 0xd342, 0xf8, 0 },
+ { 0xd343, 0x00, 0 },
+ { 0xd344, 0x03, 0 },
+ { 0xd345, 0xff, 0 },
+ { 0xd346, 0xff, 0 },
+ { 0xd347, 0x6f, 0 },
+ { 0xd348, 0x18, 0 },
+ { 0xd349, 0x60, 0 },
+ { 0xd34a, 0x00, 0 },
+ { 0xd34b, 0x01, 0 },
+ { 0xd34c, 0xf , 0 },
+ { 0xd34d, 0xff, 0 },
+ { 0xd34e, 0xff, 0 },
+ { 0xd34f, 0x9d, 0 },
+ { 0xd350, 0x18, 0 },
+ { 0xd351, 0x60, 0 },
+ { 0xd352, 0x80, 0 },
+ { 0xd353, 0x06, 0 },
+ { 0xd354, 0x00, 0 },
+ { 0xd355, 0x00, 0 },
+ { 0xd356, 0x00, 0 },
+ { 0xd357, 0x11, 0 },
+ { 0xd358, 0xa8, 0 },
+ { 0xd359, 0x83, 0 },
+ { 0xd35a, 0x6e, 0 },
+ { 0xd35b, 0x43, 0 },
+ { 0xd35c, 0xe0, 0 },
+ { 0xd35d, 0x6c, 0 },
+ { 0xd35e, 0x28, 0 },
+ { 0xd35f, 0x02, 0 },
+ { 0xd360, 0xe0, 0 },
+ { 0xd361, 0x84, 0 },
+ { 0xd362, 0x28, 0 },
+ { 0xd363, 0x02, 0 },
+ { 0xd364, 0x07, 0 },
+ { 0xd365, 0xff, 0 },
+ { 0xd366, 0xf8, 0 },
+ { 0xd367, 0x30, 0 },
+ { 0xd368, 0xb8, 0 },
+ { 0xd369, 0x63, 0 },
+ { 0xd36a, 0x00, 0 },
+ { 0xd36b, 0x08, 0 },
+ { 0xd36c, 0x03, 0 },
+ { 0xd36d, 0xff, 0 },
+ { 0xd36e, 0xff, 0 },
+ { 0xd36f, 0xc0, 0 },
+ { 0xd370, 0x85, 0 },
+ { 0xd371, 0x4e, 0 },
+ { 0xd372, 0x00, 0 },
+ { 0xd373, 0x00, 0 },
+ { 0xd374, 0x03, 0 },
+ { 0xd375, 0xff, 0 },
+ { 0xd376, 0xff, 0 },
+ { 0xd377, 0xe7, 0 },
+ { 0xd378, 0xd4, 0 },
+ { 0xd379, 0x01, 0 },
+ { 0xd37a, 0x40, 0 },
+ { 0xd37b, 0x18, 0 },
+ { 0xd37c, 0x9c, 0 },
+ { 0xd37d, 0x60, 0 },
+ { 0xd37e, 0x00, 0 },
+ { 0xd37f, 0x00, 0 },
+ { 0xd380, 0x03, 0 },
+ { 0xd381, 0xff, 0 },
+ { 0xd382, 0xff, 0 },
+ { 0xd383, 0xdb, 0 },
+ { 0xd384, 0xd4, 0 },
+ { 0xd385, 0x01, 0 },
+ { 0xd386, 0x18, 0 },
+ { 0xd387, 0x14, 0 },
+ { 0xd388, 0x03, 0 },
+ { 0xd389, 0xff, 0 },
+ { 0xd38a, 0xff, 0 },
+ { 0xd38b, 0xce, 0 },
+ { 0xd38c, 0x9d, 0 },
+ { 0xd38d, 0x6b, 0 },
+ { 0xd38e, 0x00, 0 },
+ { 0xd38f, 0xff, 0 },
+ { 0xd390, 0x03, 0 },
+ { 0xd391, 0xff, 0 },
+ { 0xd392, 0xff, 0 },
+ { 0xd393, 0xc6, 0 },
+ { 0xd394, 0x9c, 0 },
+ { 0xd395, 0x63, 0 },
+ { 0xd396, 0x00, 0 },
+ { 0xd397, 0xff, 0 },
+ { 0xd398, 0xa8, 0 },
+ { 0xd399, 0xe3, 0 },
+ { 0xd39a, 0x38, 0 },
+ { 0xd39b, 0xf , 0 },
+ { 0xd39c, 0x8c, 0 },
+ { 0xd39d, 0x84, 0 },
+ { 0xd39e, 0x00, 0 },
+ { 0xd39f, 0x00, 0 },
+ { 0xd3a0, 0xa8, 0 },
+ { 0xd3a1, 0xa3, 0 },
+ { 0xd3a2, 0x38, 0 },
+ { 0xd3a3, 0x0e, 0 },
+ { 0xd3a4, 0xa8, 0 },
+ { 0xd3a5, 0xc3, 0 },
+ { 0xd3a6, 0x6e, 0 },
+ { 0xd3a7, 0x42, 0 },
+ { 0xd3a8, 0xd8, 0 },
+ { 0xd3a9, 0x07, 0 },
+ { 0xd3aa, 0x20, 0 },
+ { 0xd3ab, 0x00, 0 },
+ { 0xd3ac, 0x8c, 0 },
+ { 0xd3ad, 0x66, 0 },
+ { 0xd3ae, 0x00, 0 },
+ { 0xd3af, 0x00, 0 },
+ { 0xd3b0, 0xd8, 0 },
+ { 0xd3b1, 0x05, 0 },
+ { 0xd3b2, 0x18, 0 },
+ { 0xd3b3, 0x00, 0 },
+ { 0xd3b4, 0x85, 0 },
+ { 0xd3b5, 0x21, 0 },
+ { 0xd3b6, 0x00, 0 },
+ { 0xd3b7, 0x00, 0 },
+ { 0xd3b8, 0x85, 0 },
+ { 0xd3b9, 0x41, 0 },
+ { 0xd3ba, 0x00, 0 },
+ { 0xd3bb, 0x04, 0 },
+ { 0xd3bc, 0x85, 0 },
+ { 0xd3bd, 0x81, 0 },
+ { 0xd3be, 0x00, 0 },
+ { 0xd3bf, 0x08, 0 },
+ { 0xd3c0, 0x85, 0 },
+ { 0xd3c1, 0xc1, 0 },
+ { 0xd3c2, 0x00, 0 },
+ { 0xd3c3, 0x0c, 0 },
+ { 0xd3c4, 0x86, 0 },
+ { 0xd3c5, 0x01, 0 },
+ { 0xd3c6, 0x00, 0 },
+ { 0xd3c7, 0x10, 0 },
+ { 0xd3c8, 0x44, 0 },
+ { 0xd3c9, 0x00, 0 },
+ { 0xd3ca, 0x48, 0 },
+ { 0xd3cb, 0x00, 0 },
+ { 0xd3cc, 0x9c, 0 },
+ { 0xd3cd, 0x21, 0 },
+ { 0xd3ce, 0x00, 0 },
+ { 0xd3cf, 0x1c, 0 },
+ { 0xd3d0, 0x9c, 0 },
+ { 0xd3d1, 0x21, 0 },
+ { 0xd3d2, 0xff, 0 },
+ { 0xd3d3, 0xfc, 0 },
+ { 0xd3d4, 0xd4, 0 },
+ { 0xd3d5, 0x01, 0 },
+ { 0xd3d6, 0x48, 0 },
+ { 0xd3d7, 0x00, 0 },
+ { 0xd3d8, 0x18, 0 },
+ { 0xd3d9, 0x60, 0 },
+ { 0xd3da, 0x00, 0 },
+ { 0xd3db, 0x01, 0 },
+ { 0xd3dc, 0xa8, 0 },
+ { 0xd3dd, 0x63, 0 },
+ { 0xd3de, 0x07, 0 },
+ { 0xd3df, 0x80, 0 },
+ { 0xd3e0, 0x8c, 0 },
+ { 0xd3e1, 0x63, 0 },
+ { 0xd3e2, 0x00, 0 },
+ { 0xd3e3, 0x68, 0 },
+ { 0xd3e4, 0xbc, 0 },
+ { 0xd3e5, 0x03, 0 },
+ { 0xd3e6, 0x00, 0 },
+ { 0xd3e7, 0x00, 0 },
+ { 0xd3e8, 0x10, 0 },
+ { 0xd3e9, 0x00, 0 },
+ { 0xd3ea, 0x00, 0 },
+ { 0xd3eb, 0x0c, 0 },
+ { 0xd3ec, 0x15, 0 },
+ { 0xd3ed, 0x00, 0 },
+ { 0xd3ee, 0x00, 0 },
+ { 0xd3ef, 0x00, 0 },
+ { 0xd3f0, 0x07, 0 },
+ { 0xd3f1, 0xff, 0 },
+ { 0xd3f2, 0xd9, 0 },
+ { 0xd3f3, 0x98, 0 },
+ { 0xd3f4, 0x15, 0 },
+ { 0xd3f5, 0x00, 0 },
+ { 0xd3f6, 0x00, 0 },
+ { 0xd3f7, 0x00, 0 },
+ { 0xd3f8, 0x18, 0 },
+ { 0xd3f9, 0x60, 0 },
+ { 0xd3fa, 0x80, 0 },
+ { 0xd3fb, 0x06, 0 },
+ { 0xd3fc, 0xa8, 0 },
+ { 0xd3fd, 0x63, 0 },
+ { 0xd3fe, 0xc4, 0 },
+ { 0xd3ff, 0xb8, 0 },
+ { 0xd400, 0x8c, 0 },
+ { 0xd401, 0x63, 0 },
+ { 0xd402, 0x00, 0 },
+ { 0xd403, 0x00, 0 },
+ { 0xd404, 0xbc, 0 },
+ { 0xd405, 0x23, 0 },
+ { 0xd406, 0x00, 0 },
+ { 0xd407, 0x01, 0 },
+ { 0xd408, 0x10, 0 },
+ { 0xd409, 0x00, 0 },
+ { 0xd40a, 0x00, 0 },
+ { 0xd40b, 0x25, 0 },
+ { 0xd40c, 0x9d, 0 },
+ { 0xd40d, 0x00, 0 },
+ { 0xd40e, 0x00, 0 },
+ { 0xd40f, 0x00, 0 },
+ { 0xd410, 0x00, 0 },
+ { 0xd411, 0x00, 0 },
+ { 0xd412, 0x00, 0 },
+ { 0xd413, 0x0b, 0 },
+ { 0xd414, 0xb8, 0 },
+ { 0xd415, 0xe8, 0 },
+ { 0xd416, 0x00, 0 },
+ { 0xd417, 0x02, 0 },
+ { 0xd418, 0x07, 0 },
+ { 0xd419, 0xff, 0 },
+ { 0xd41a, 0xd6, 0 },
+ { 0xd41b, 0x24, 0 },
+ { 0xd41c, 0x15, 0 },
+ { 0xd41d, 0x00, 0 },
+ { 0xd41e, 0x00, 0 },
+ { 0xd41f, 0x00, 0 },
+ { 0xd420, 0x18, 0 },
+ { 0xd421, 0x60, 0 },
+ { 0xd422, 0x80, 0 },
+ { 0xd423, 0x06, 0 },
+ { 0xd424, 0xa8, 0 },
+ { 0xd425, 0x63, 0 },
+ { 0xd426, 0xc4, 0 },
+ { 0xd427, 0xb8, 0 },
+ { 0xd428, 0x8c, 0 },
+ { 0xd429, 0x63, 0 },
+ { 0xd42a, 0x00, 0 },
+ { 0xd42b, 0x00, 0 },
+ { 0xd42c, 0xbc, 0 },
+ { 0xd42d, 0x23, 0 },
+ { 0xd42e, 0x00, 0 },
+ { 0xd42f, 0x01, 0 },
+ { 0xd430, 0x10, 0 },
+ { 0xd431, 0x00, 0 },
+ { 0xd432, 0x00, 0 },
+ { 0xd433, 0x1b, 0 },
+ { 0xd434, 0x9d, 0 },
+ { 0xd435, 0x00, 0 },
+ { 0xd436, 0x00, 0 },
+ { 0xd437, 0x00, 0 },
+ { 0xd438, 0xb8, 0 },
+ { 0xd439, 0xe8, 0 },
+ { 0xd43a, 0x00, 0 },
+ { 0xd43b, 0x02, 0 },
+ { 0xd43c, 0x9c, 0 },
+ { 0xd43d, 0xc0, 0 },
+ { 0xd43e, 0x00, 0 },
+ { 0xd43f, 0x00, 0 },
+ { 0xd440, 0x18, 0 },
+ { 0xd441, 0xa0, 0 },
+ { 0xd442, 0x80, 0 },
+ { 0xd443, 0x06, 0 },
+ { 0xd444, 0xe0, 0 },
+ { 0xd445, 0x67, 0 },
+ { 0xd446, 0x30, 0 },
+ { 0xd447, 0x00, 0 },
+ { 0xd448, 0xa8, 0 },
+ { 0xd449, 0xa5, 0 },
+ { 0xd44a, 0xce, 0 },
+ { 0xd44b, 0xb0, 0 },
+ { 0xd44c, 0x19, 0 },
+ { 0xd44d, 0x60, 0 },
+ { 0xd44e, 0x00, 0 },
+ { 0xd44f, 0x01, 0 },
+ { 0xd450, 0xa9, 0 },
+ { 0xd451, 0x6b, 0 },
+ { 0xd452, 0x06, 0 },
+ { 0xd453, 0x14, 0 },
+ { 0xd454, 0xe0, 0 },
+ { 0xd455, 0x83, 0 },
+ { 0xd456, 0x28, 0 },
+ { 0xd457, 0x00, 0 },
+ { 0xd458, 0x9c, 0 },
+ { 0xd459, 0xc6, 0 },
+ { 0xd45a, 0x00, 0 },
+ { 0xd45b, 0x01, 0 },
+ { 0xd45c, 0xe0, 0 },
+ { 0xd45d, 0x63, 0 },
+ { 0xd45e, 0x18, 0 },
+ { 0xd45f, 0x00, 0 },
+ { 0xd460, 0x8c, 0 },
+ { 0xd461, 0x84, 0 },
+ { 0xd462, 0x00, 0 },
+ { 0xd463, 0x00, 0 },
+ { 0xd464, 0xe0, 0 },
+ { 0xd465, 0xa3, 0 },
+ { 0xd466, 0x58, 0 },
+ { 0xd467, 0x00, 0 },
+ { 0xd468, 0xa4, 0 },
+ { 0xd469, 0xc6, 0 },
+ { 0xd46a, 0x00, 0 },
+ { 0xd46b, 0xff, 0 },
+ { 0xd46c, 0xb8, 0 },
+ { 0xd46d, 0x64, 0 },
+ { 0xd46e, 0x00, 0 },
+ { 0xd46f, 0x18, 0 },
+ { 0xd470, 0xbc, 0 },
+ { 0xd471, 0x46, 0 },
+ { 0xd472, 0x00, 0 },
+ { 0xd473, 0x03, 0 },
+ { 0xd474, 0x94, 0 },
+ { 0xd475, 0x85, 0 },
+ { 0xd476, 0x00, 0 },
+ { 0xd477, 0x00, 0 },
+ { 0xd478, 0xb8, 0 },
+ { 0xd479, 0x63, 0 },
+ { 0xd47a, 0x00, 0 },
+ { 0xd47b, 0x98, 0 },
+ { 0xd47c, 0xe0, 0 },
+ { 0xd47d, 0x64, 0 },
+ { 0xd47e, 0x18, 0 },
+ { 0xd47f, 0x00, 0 },
+ { 0xd480, 0xf , 0 },
+ { 0xd481, 0xff, 0 },
+ { 0xd482, 0xff, 0 },
+ { 0xd483, 0xf0, 0 },
+ { 0xd484, 0xdc, 0 },
+ { 0xd485, 0x05, 0 },
+ { 0xd486, 0x18, 0 },
+ { 0xd487, 0x00, 0 },
+ { 0xd488, 0x9c, 0 },
+ { 0xd489, 0x68, 0 },
+ { 0xd48a, 0x00, 0 },
+ { 0xd48b, 0x01, 0 },
+ { 0xd48c, 0xa5, 0 },
+ { 0xd48d, 0x03, 0 },
+ { 0xd48e, 0x00, 0 },
+ { 0xd48f, 0xff, 0 },
+ { 0xd490, 0xbc, 0 },
+ { 0xd491, 0x48, 0 },
+ { 0xd492, 0x00, 0 },
+ { 0xd493, 0x01, 0 },
+ { 0xd494, 0xf , 0 },
+ { 0xd495, 0xff, 0 },
+ { 0xd496, 0xff, 0 },
+ { 0xd497, 0xea, 0 },
+ { 0xd498, 0xb8, 0 },
+ { 0xd499, 0xe8, 0 },
+ { 0xd49a, 0x00, 0 },
+ { 0xd49b, 0x02, 0 },
+ { 0xd49c, 0x18, 0 },
+ { 0xd49d, 0x60, 0 },
+ { 0xd49e, 0x00, 0 },
+ { 0xd49f, 0x01, 0 },
+ { 0xd4a0, 0xa8, 0 },
+ { 0xd4a1, 0x63, 0 },
+ { 0xd4a2, 0x06, 0 },
+ { 0xd4a3, 0x14, 0 },
+ { 0xd4a4, 0x07, 0 },
+ { 0xd4a5, 0xff, 0 },
+ { 0xd4a6, 0xe4, 0 },
+ { 0xd4a7, 0x05, 0 },
+ { 0xd4a8, 0x9c, 0 },
+ { 0xd4a9, 0x83, 0 },
+ { 0xd4aa, 0x00, 0 },
+ { 0xd4ab, 0x10, 0 },
+ { 0xd4ac, 0x85, 0 },
+ { 0xd4ad, 0x21, 0 },
+ { 0xd4ae, 0x00, 0 },
+ { 0xd4af, 0x00, 0 },
+ { 0xd4b0, 0x44, 0 },
+ { 0xd4b1, 0x00, 0 },
+ { 0xd4b2, 0x48, 0 },
+ { 0xd4b3, 0x00, 0 },
+ { 0xd4b4, 0x9c, 0 },
+ { 0xd4b5, 0x21, 0 },
+ { 0xd4b6, 0x00, 0 },
+ { 0xd4b7, 0x04, 0 },
+ { 0xd4b8, 0x18, 0 },
+ { 0xd4b9, 0x60, 0 },
+ { 0xd4ba, 0x00, 0 },
+ { 0xd4bb, 0x01, 0 },
+ { 0xd4bc, 0x9c, 0 },
+ { 0xd4bd, 0x80, 0 },
+ { 0xd4be, 0xff, 0 },
+ { 0xd4bf, 0xff, 0 },
+ { 0xd4c0, 0xa8, 0 },
+ { 0xd4c1, 0x63, 0 },
+ { 0xd4c2, 0x09, 0 },
+ { 0xd4c3, 0xef, 0 },
+ { 0xd4c4, 0xd8, 0 },
+ { 0xd4c5, 0x03, 0 },
+ { 0xd4c6, 0x20, 0 },
+ { 0xd4c7, 0x00, 0 },
+ { 0xd4c8, 0x18, 0 },
+ { 0xd4c9, 0x60, 0 },
+ { 0xd4ca, 0x80, 0 },
+ { 0xd4cb, 0x06, 0 },
+ { 0xd4cc, 0xa8, 0 },
+ { 0xd4cd, 0x63, 0 },
+ { 0xd4ce, 0xc9, 0 },
+ { 0xd4cf, 0xef, 0 },
+ { 0xd4d0, 0xd8, 0 },
+ { 0xd4d1, 0x03, 0 },
+ { 0xd4d2, 0x20, 0 },
+ { 0xd4d3, 0x00, 0 },
+ { 0xd4d4, 0x44, 0 },
+ { 0xd4d5, 0x00, 0 },
+ { 0xd4d6, 0x48, 0 },
+ { 0xd4d7, 0x00, 0 },
+ { 0xd4d8, 0x15, 0 },
+ { 0xd4d9, 0x00, 0 },
+ { 0xd4da, 0x00, 0 },
+ { 0xd4db, 0x00, 0 },
+ { 0xd4dc, 0x18, 0 },
+ { 0xd4dd, 0x80, 0 },
+ { 0xd4de, 0x00, 0 },
+ { 0xd4df, 0x01, 0 },
+ { 0xd4e0, 0xa8, 0 },
+ { 0xd4e1, 0x84, 0 },
+ { 0xd4e2, 0x0a, 0 },
+ { 0xd4e3, 0x12, 0 },
+ { 0xd4e4, 0x8c, 0 },
+ { 0xd4e5, 0x64, 0 },
+ { 0xd4e6, 0x00, 0 },
+ { 0xd4e7, 0x00, 0 },
+ { 0xd4e8, 0xbc, 0 },
+ { 0xd4e9, 0x03, 0 },
+ { 0xd4ea, 0x00, 0 },
+ { 0xd4eb, 0x00, 0 },
+ { 0xd4ec, 0x13, 0 },
+ { 0xd4ed, 0xff, 0 },
+ { 0xd4ee, 0xff, 0 },
+ { 0xd4ef, 0xfe, 0 },
+ { 0xd4f0, 0x15, 0 },
+ { 0xd4f1, 0x00, 0 },
+ { 0xd4f2, 0x00, 0 },
+ { 0xd4f3, 0x00, 0 },
+ { 0xd4f4, 0x44, 0 },
+ { 0xd4f5, 0x00, 0 },
+ { 0xd4f6, 0x48, 0 },
+ { 0xd4f7, 0x00, 0 },
+ { 0xd4f8, 0x15, 0 },
+ { 0xd4f9, 0x00, 0 },
+ { 0xd4fa, 0x00, 0 },
+ { 0xd4fb, 0x00, 0 },
+ { 0xd4fc, 0x00, 0 },
+ { 0xd4fd, 0x00, 0 },
+ { 0xd4fe, 0x00, 0 },
+ { 0xd4ff, 0x00, 0 },
+ { 0xd500, 0x00, 0 },
+ { 0xd501, 0x00, 0 },
+ { 0xd502, 0x00, 0 },
+ { 0xd503, 0x00, 0 },
+ { 0x6f0e, 0x33, 0 },
+ { 0x6f0f, 0x33, 0 },
+ { 0x460e, 0x08, 0 },
+ { 0x460f, 0x01, 0 },
+ { 0x4610, 0x00, 0 },
+ { 0x4611, 0x01, 0 },
+ { 0x4612, 0x00, 0 },
+ { 0x4613, 0x01, 0 },
+ { 0x4605, 0x08, 0 },
+ { 0x4608, 0x00, 0 },
+ { 0x4609, 0x08, 0 },
+ { 0x6804, 0x00, 0 },
+ { 0x6805, 0x06, 0 },
+ { 0x6806, 0x00, 0 },
+ { 0x5120, 0x00, 0 },
+ { 0x3510, 0x00, 0 },
+ { 0x3504, 0x00, 0 },
+ { 0x6800, 0x00, 0 },
+ { 0x6f0d, 0xf , 0 },
+ { 0x5000, 0xff, 0 },
+ { 0x5001, 0xbf, 0 },
+ { 0x5002, 0x7e, 0 },
+ { 0x5003, 0x0c, 0 },
+ { 0x503d, 0x00, 0 },
+ { 0xc450, 0x01, 0 },
+ { 0xc452, 0x04, 0 },
+ { 0xc453, 0x00, 0 },
+ { 0xc454, 0x00, 0 },
+ { 0xc455, 0x00, 0 },
+ { 0xc456, 0x00, 0 },
+ { 0xc457, 0x00, 0 },
+ { 0xc458, 0x00, 0 },
+ { 0xc459, 0x00, 0 },
+ { 0xc45b, 0x00, 0 },
+ { 0xc45c, 0x00, 0 },
+ { 0xc45d, 0x00, 0 },
+ { 0xc45e, 0x00, 0 },
+ { 0xc45f, 0x00, 0 },
+ { 0xc460, 0x00, 0 },
+ { 0xc461, 0x01, 0 },
+ { 0xc462, 0x01, 0 },
+ { 0xc464, 0x88, 0 },
+ { 0xc465, 0x00, 0 },
+ { 0xc466, 0x8a, 0 },
+ { 0xc467, 0x00, 0 },
+ { 0xc468, 0x86, 0 },
+ { 0xc469, 0x00, 0 },
+ { 0xc46a, 0x40, 0 },
+ { 0xc46b, 0x50, 0 },
+ { 0xc46c, 0x30, 0 },
+ { 0xc46d, 0x28, 0 },
+ { 0xc46e, 0x60, 0 },
+ { 0xc46f, 0x40, 0 },
+ { 0xc47c, 0x01, 0 },
+ { 0xc47d, 0x38, 0 },
+ { 0xc47e, 0x00, 0 },
+ { 0xc47f, 0x00, 0 },
+ { 0xc480, 0x00, 0 },
+ { 0xc481, 0xff, 0 },
+ { 0xc482, 0x00, 0 },
+ { 0xc483, 0x40, 0 },
+ { 0xc484, 0x00, 0 },
+ { 0xc485, 0x18, 0 },
+ { 0xc486, 0x00, 0 },
+ { 0xc487, 0x18, 0 },
+ { 0xc488, 0x34, 0 },
+ { 0xc489, 0x00, 0 },
+ { 0xc48a, 0x34, 0 },
+ { 0xc48b, 0x00, 0 },
+ { 0xc48c, 0x00, 0 },
+ { 0xc48d, 0x04, 0 },
+ { 0xc48e, 0x00, 0 },
+ { 0xc48f, 0x04, 0 },
+ { 0xc490, 0x07, 0 },
+ { 0xc492, 0x20, 0 },
+ { 0xc493, 0x08, 0 },
+ { 0xc498, 0x02, 0 },
+ { 0xc499, 0x00, 0 },
+ { 0xc49a, 0x02, 0 },
+ { 0xc49b, 0x00, 0 },
+ { 0xc49c, 0x02, 0 },
+ { 0xc49d, 0x00, 0 },
+ { 0xc49e, 0x02, 0 },
+ { 0xc49f, 0x60, 0 },
+ { 0xc4a0, 0x03, 0 },
+ { 0xc4a1, 0x00, 0 },
+ { 0xc4a2, 0x04, 0 },
+ { 0xc4a3, 0x00, 0 },
+ { 0xc4a4, 0x00, 0 },
+ { 0xc4a5, 0x10, 0 },
+ { 0xc4a6, 0x00, 0 },
+ { 0xc4a7, 0x40, 0 },
+ { 0xc4a8, 0x00, 0 },
+ { 0xc4a9, 0x80, 0 },
+ { 0xc4aa, 0x0d, 0 },
+ { 0xc4ab, 0x00, 0 },
+ { 0xc4ac, 0xf , 0 },
+ { 0xc4ad, 0xc0, 0 },
+ { 0xc4b4, 0x01, 0 },
+ { 0xc4b5, 0x01, 0 },
+ { 0xc4b6, 0x00, 0 },
+ { 0xc4b7, 0x01, 0 },
+ { 0xc4b8, 0x00, 0 },
+ { 0xc4b9, 0x01, 0 },
+ { 0xc4ba, 0x01, 0 },
+ { 0xc4bb, 0x00, 0 },
+ { 0xc4bc, 0x01, 0 },
+ { 0xc4bd, 0x60, 0 },
+ { 0xc4be, 0x02, 0 },
+ { 0xc4bf, 0x33, 0 },
+ { 0xc4c8, 0x03, 0 },
+ { 0xc4c9, 0xd0, 0 },
+ { 0xc4ca, 0x0e, 0 },
+ { 0xc4cb, 0x00, 0 },
+ { 0xc4cc, 0x10, 0 },
+ { 0xc4cd, 0x18, 0 },
+ { 0xc4ce, 0x10, 0 },
+ { 0xc4cf, 0x18, 0 },
+ { 0xc4d0, 0x04, 0 },
+ { 0xc4d1, 0x80, 0 },
+ { 0xc4e0, 0x04, 0 },
+ { 0xc4e1, 0x02, 0 },
+ { 0xc4e2, 0x01, 0 },
+ { 0xc4e4, 0x10, 0 },
+ { 0xc4e5, 0x20, 0 },
+ { 0xc4e6, 0x30, 0 },
+ { 0xc4e7, 0x40, 0 },
+ { 0xc4e8, 0x50, 0 },
+ { 0xc4e9, 0x60, 0 },
+ { 0xc4ea, 0x70, 0 },
+ { 0xc4eb, 0x80, 0 },
+ { 0xc4ec, 0x90, 0 },
+ { 0xc4ed, 0xa0, 0 },
+ { 0xc4ee, 0xb0, 0 },
+ { 0xc4ef, 0xc0, 0 },
+ { 0xc4f0, 0xd0, 0 },
+ { 0xc4f1, 0xe0, 0 },
+ { 0xc4f2, 0xf0, 0 },
+ { 0xc4f3, 0x80, 0 },
+ { 0xc4f4, 0x00, 0 },
+ { 0xc4f5, 0x20, 0 },
+ { 0xc4f6, 0x02, 0 },
+ { 0xc4f7, 0x00, 0 },
+ { 0xc4f8, 0x04, 0 },
+ { 0xc4f9, 0x0b, 0 },
+ { 0xc4fa, 0x00, 0 },
+ { 0xc4fb, 0x00, 0 },
+ { 0xc4fc, 0x01, 0 },
+ { 0xc4fd, 0x00, 0 },
+ { 0xc4fe, 0x04, 0 },
+ { 0xc4ff, 0x02, 0 },
+ { 0xc500, 0x48, 0 },
+ { 0xc501, 0x74, 0 },
+ { 0xc502, 0x58, 0 },
+ { 0xc503, 0x80, 0 },
+ { 0xc504, 0x05, 0 },
+ { 0xc505, 0x80, 0 },
+ { 0xc506, 0x03, 0 },
+ { 0xc507, 0x80, 0 },
+ { 0xc508, 0x01, 0 },
+ { 0xc509, 0xc0, 0 },
+ { 0xc50a, 0x01, 0 },
+ { 0xc50b, 0xa0, 0 },
+ { 0xc50c, 0x01, 0 },
+ { 0xc50d, 0x2c, 0 },
+ { 0xc50e, 0x01, 0 },
+ { 0xc50f, 0x0a, 0 },
+ { 0xc510, 0x00, 0 },
+ { 0xc511, 0x01, 0 },
+ { 0xc512, 0x01, 0 },
+ { 0xc513, 0x80, 0 },
+ { 0xc514, 0x04, 0 },
+ { 0xc515, 0x00, 0 },
+ { 0xc518, 0x03, 0 },
+ { 0xc519, 0x48, 0 },
+ { 0xc51a, 0x07, 0 },
+ { 0xc51b, 0x70, 0 },
+ { 0xc2e0, 0x00, 0 },
+ { 0xc2e1, 0x51, 0 },
+ { 0xc2e2, 0x00, 0 },
+ { 0xc2e3, 0xd6, 0 },
+ { 0xc2e4, 0x01, 0 },
+ { 0xc2e5, 0x5e, 0 },
+ { 0xc2e9, 0x01, 0 },
+ { 0xc2ea, 0x7a, 0 },
+ { 0xc2eb, 0x90, 0 },
+ { 0xc2ed, 0x00, 0 },
+ { 0xc2ee, 0x7a, 0 },
+ { 0xc2ef, 0x64, 0 },
+ { 0xc308, 0x00, 0 },
+ { 0xc309, 0x00, 0 },
+ { 0xc30a, 0x00, 0 },
+ { 0xc30c, 0x00, 0 },
+ { 0xc30d, 0x01, 0 },
+ { 0xc30e, 0x00, 0 },
+ { 0xc30f, 0x00, 0 },
+ { 0xc310, 0x01, 0 },
+ { 0xc311, 0x60, 0 },
+ { 0xc312, 0xff, 0 },
+ { 0xc313, 0x08, 0 },
+ { 0xc314, 0x01, 0 },
+ { 0xc315, 0x7f, 0 },
+ { 0xc316, 0xff, 0 },
+ { 0xc317, 0x0b, 0 },
+ { 0xc318, 0x00, 0 },
+ { 0xc319, 0x0c, 0 },
+ { 0xc31a, 0x00, 0 },
+ { 0xc31b, 0xe0, 0 },
+ { 0xc31c, 0x00, 0 },
+ { 0xc31d, 0x14, 0 },
+ { 0xc31e, 0x00, 0 },
+ { 0xc31f, 0xc5, 0 },
+ { 0xc320, 0xff, 0 },
+ { 0xc321, 0x4b, 0 },
+ { 0xc322, 0xff, 0 },
+ { 0xc323, 0xf0, 0 },
+ { 0xc324, 0xff, 0 },
+ { 0xc325, 0xe8, 0 },
+ { 0xc326, 0x00, 0 },
+ { 0xc327, 0x46, 0 },
+ { 0xc328, 0xff, 0 },
+ { 0xc329, 0xd2, 0 },
+ { 0xc32a, 0xff, 0 },
+ { 0xc32b, 0xe4, 0 },
+ { 0xc32c, 0xff, 0 },
+ { 0xc32d, 0xbb, 0 },
+ { 0xc32e, 0x00, 0 },
+ { 0xc32f, 0x61, 0 },
+ { 0xc330, 0xff, 0 },
+ { 0xc331, 0xf9, 0 },
+ { 0xc332, 0x00, 0 },
+ { 0xc333, 0xd9, 0 },
+ { 0xc334, 0x00, 0 },
+ { 0xc335, 0x2e, 0 },
+ { 0xc336, 0x00, 0 },
+ { 0xc337, 0xb1, 0 },
+ { 0xc338, 0xff, 0 },
+ { 0xc339, 0x64, 0 },
+ { 0xc33a, 0xff, 0 },
+ { 0xc33b, 0xeb, 0 },
+ { 0xc33c, 0xff, 0 },
+ { 0xc33d, 0xe8, 0 },
+ { 0xc33e, 0x00, 0 },
+ { 0xc33f, 0x48, 0 },
+ { 0xc340, 0xff, 0 },
+ { 0xc341, 0xd0, 0 },
+ { 0xc342, 0xff, 0 },
+ { 0xc343, 0xed, 0 },
+ { 0xc344, 0xff, 0 },
+ { 0xc345, 0xad, 0 },
+ { 0xc346, 0x00, 0 },
+ { 0xc347, 0x66, 0 },
+ { 0xc348, 0x01, 0 },
+ { 0xc349, 0x00, 0 },
+ { 0x6700, 0x04, 0 },
+ { 0x6701, 0x7b, 0 },
+ { 0x6702, 0xfd, 0 },
+ { 0x6703, 0xf9, 0 },
+ { 0x6704, 0x3d, 0 },
+ { 0x6705, 0x71, 0 },
+ { 0x6706, 0x78, 0 },
+ { 0x6708, 0x05, 0 },
+ { 0x6f06, 0x6f, 0 },
+ { 0x6f07, 0x00, 0 },
+ { 0x6f0a, 0x6f, 0 },
+ { 0x6f0b, 0x00, 0 },
+ { 0x6f00, 0x03, 0 },
+ { 0xc34c, 0x01, 0 },
+ { 0xc34d, 0x00, 0 },
+ { 0xc34e, 0x46, 0 },
+ { 0xc34f, 0x55, 0 },
+ { 0xc350, 0x00, 0 },
+ { 0xc351, 0x40, 0 },
+ { 0xc352, 0x00, 0 },
+ { 0xc353, 0xff, 0 },
+ { 0xc354, 0x04, 0 },
+ { 0xc355, 0x08, 0 },
+ { 0xc356, 0x01, 0 },
+ { 0xc357, 0xef, 0 },
+ { 0xc358, 0x30, 0 },
+ { 0xc359, 0x01, 0 },
+ { 0xc35a, 0x64, 0 },
+ { 0xc35b, 0x46, 0 },
+ { 0xc35c, 0x00, 0 },
+ { 0x3042, 0xf0, 0 },
+ { 0x3042, 0xf0, 0 },
+ { 0x3042, 0xf0, 0 },
+ { 0x3042, 0xf0, 0 },
+ { 0x3042, 0xf0, 0 },
+ { 0x3042, 0xf0, 0 },
+ { 0x3042, 0xf0, 0 },
+ { 0x3042, 0xf0, 0 },
+ { 0x3042, 0xf0, 0 },
+ { 0x3042, 0xf0, 0 },
+ { 0x3042, 0xf0, 0 },
+ { 0x3042, 0xf0, 0 },
+ { 0x3042, 0xf0, 0 },
+ { 0x3042, 0xf0, 0 },
+ { 0x3042, 0xf0, 0 },
+ { 0x3042, 0xf0, 0 },
+ { 0x3042, 0xf0, 0 },
+ { 0x3042, 0xf0, 0 },
+ { 0x3042, 0xf0, 0 },
+ { 0x3042, 0xf0, 0 },
+ { 0x3042, 0xf0, 0 },
+ { 0x3042, 0xf0, 0 },
+ { 0x3042, 0xf0, 0 },
+ { 0x3042, 0xf0, 0 },
+ { 0x3042, 0xf0, 0 },
+ { 0x3042, 0xf0, 0 },
+ { 0x301b, 0xf0, 0 },
+ { 0x301c, 0xf0, 0 },
+ { 0x301a, 0xf0, 0 },
+ { 0xceb0, 0x00, 0 },
+ { 0xceb1, 0x00, 0 },
+ { 0xceb2, 0x00, 0 },
+ { 0xceb3, 0x00, 0 },
+ { 0xceb4, 0x00, 0 },
+ { 0xceb5, 0x00, 0 },
+ { 0xceb6, 0x00, 0 },
+ { 0xceb7, 0x00, 0 },
+ { 0xc4bc, 0x01, 0 },
+ { 0xc4bd, 0x60, 0 },
+
+ { 0x4709, 0x10, 0 },/* dvp swap */
+ { 0x4300, 0x3a, 0 },/* YUV order UYVY */
+ { 0x3832, 0x01, 0 },/* fsin */
+ { 0x3833, 0x1A, 0 },
+ { 0x3834, 0x03, 0 },
+ { 0x3835, 0x48, 0 },
+ { 0x302E, 0x01, 0 },
+};
+
+struct ov10635_mode_info {
+ enum ov10635_mode mode;
+ u32 width;
+ u32 height;
+ struct reg_value *init_data_ptr;
+ u32 init_data_size;
+};
+
+static struct reg_value ov10635_setting_30fps_WXGA_1280_800[] = {
+ { 0x3024, 0x01, 0 },
+ { 0x3003, 0x20, 0 },
+ { 0x3004, 0x21, 0 },
+ { 0x3005, 0x20, 0 },
+ { 0x3006, 0x91, 0 },
+ /* 1280x800 */
+ { 0x3808, 0x05, 0 },
+ { 0x3809, 0x00, 0 },
+ { 0x380a, 0x03, 0 },
+ { 0x380b, 0x20, 0 },
+};
+
+static struct reg_value ov10635_setting_30fps_720P_1280_720[] = {
+ { 0x3024, 0x01, 0 },
+ { 0x3003, 0x20, 0 },
+ { 0x3004, 0x21, 0 },
+ { 0x3005, 0x20, 0 },
+ { 0x3006, 0x91, 0 },
+ /* 1280x720 */
+ { 0x3808, 0x05, 0 },
+ { 0x3809, 0x00, 0 },
+ { 0x380a, 0x02, 0 },
+ { 0x380b, 0xD0, 0 },
+};
+
+static struct reg_value ov10635_setting_30fps_WVGA_752_480[] = {
+ { 0x3024, 0x01, 0 },
+ { 0x3003, 0x20, 0 },
+ { 0x3004, 0x21, 0 },
+ { 0x3005, 0x20, 0 },
+ { 0x3006, 0x91, 0 },
+ /* 752x480 */
+ { 0x3808, 0x02, 0 },
+ { 0x3809, 0xF0, 0 },
+ { 0x380a, 0x01, 0 },
+ { 0x380b, 0xE0, 0 },
+};
+
+static struct reg_value ov10635_setting_30fps_VGA_640_480[] = {
+ { 0x3024, 0x01, 0 },
+ { 0x3003, 0x20, 0 },
+ { 0x3004, 0x21, 0 },
+ { 0x3005, 0x20, 0 },
+ { 0x3006, 0x91, 0 },
+ /* 640x480 */
+ { 0x3808, 0x02, 0 },
+ { 0x3809, 0x80, 0 },
+ { 0x380a, 0x01, 0 },
+ { 0x380b, 0xE0, 0 },
+};
+
+static struct reg_value ov10635_setting_30fps_CIF_352_288[] = {
+ { 0x3024, 0x01, 0 },
+ { 0x3003, 0x20, 0 },
+ { 0x3004, 0x21, 0 },
+ { 0x3005, 0x20, 0 },
+ { 0x3006, 0x91, 0 },
+ /* 352x288 */
+ { 0x3808, 0x01, 0 },
+ { 0x3809, 0x60, 0 },
+ { 0x380a, 0x01, 0 },
+ { 0x380b, 0x20, 0 },
+};
+
+static struct reg_value ov10635_setting_30fps_QVGA_320_240[] = {
+ { 0x3024, 0x01, 0 },
+ { 0x3003, 0x20, 0 },
+ { 0x3004, 0x21, 0 },
+ { 0x3005, 0x20, 0 },
+ { 0x3006, 0x91, 0 },
+ /* 320x240 */
+ { 0x3808, 0x01, 0 },
+ { 0x3809, 0x40, 0 },
+ { 0x380a, 0x00, 0 },
+ { 0x380b, 0xF0, 0 },
+};
+
+static struct ov10635_mode_info ov10635_mode_info_data[2][ov10635_mode_MAX + 1] = {
+ /* 15fps not support */
+ {
+ { ov10635_mode_WXGA_1280_800, 0, 0, NULL, 0 },
+ { ov10635_mode_720P_1280_720, 0, 0, NULL, 0 },
+ { ov10635_mode_WVGA_752_480, 0, 0, NULL, 0 },
+ { ov10635_mode_VGA_640_480, 0, 0, NULL, 0 },
+ { ov10635_mode_CIF_352_288, 0, 0, NULL, 0},
+ { ov10635_mode_QVGA_320_240, 0, 0, NULL, 0},
+ },
+ /* 30fps */
+ {
+ { ov10635_mode_WXGA_1280_800, 1280, 800,
+ ov10635_setting_30fps_WXGA_1280_800,
+ ARRAY_SIZE(ov10635_setting_30fps_WXGA_1280_800)
+ },
+ { ov10635_mode_720P_1280_720, 1280, 720,
+ ov10635_setting_30fps_720P_1280_720,
+ ARRAY_SIZE(ov10635_setting_30fps_720P_1280_720)
+ },
+ { ov10635_mode_WVGA_752_480, 752, 480,
+ ov10635_setting_30fps_WVGA_752_480,
+ ARRAY_SIZE(ov10635_setting_30fps_WVGA_752_480)
+ },
+ { ov10635_mode_VGA_640_480, 640, 480,
+ ov10635_setting_30fps_VGA_640_480,
+ ARRAY_SIZE(ov10635_setting_30fps_VGA_640_480)
+ },
+ { ov10635_mode_CIF_352_288, 352, 288,
+ ov10635_setting_30fps_CIF_352_288,
+ ARRAY_SIZE(ov10635_setting_30fps_CIF_352_288)
+ },
+ { ov10635_mode_QVGA_320_240, 320, 240,
+ ov10635_setting_30fps_QVGA_320_240,
+ ARRAY_SIZE(ov10635_setting_30fps_QVGA_320_240)
+ },
+ }
+};
+
+static inline struct sensor_data *subdev_to_sensor_data(struct v4l2_subdev *sd)
+{
+ return container_of(sd, struct sensor_data, subdev);
+}
+
+static enum ov10635_frame_rate to_ov10635_frame_rate(struct v4l2_fract *timeperframe)
+{
+ enum ov10635_frame_rate rate;
+ u32 tgt_fps; /* target frames per secound */
+
+ tgt_fps = timeperframe->denominator / timeperframe->numerator;
+
+ if (tgt_fps == 30)
+ rate = OV10635_30_FPS;
+ else if (tgt_fps == 15)
+ rate = OV10635_15_FPS;
+ else
+ rate = -EINVAL;
+
+ return rate;
+}
+
+static inline int ov10635_read_reg(struct sensor_data *max9286_data, int index,
+ unsigned short reg, unsigned char *val)
+{
+ unsigned char u8_buf[2] = { 0 };
+ unsigned int buf_len = 2;
+ int retry, timeout = 10;
+ unsigned char u8_val = 0;
+
+ u8_buf[0] = (reg >> 8) & 0xFF;
+ u8_buf[1] = reg & 0xFF;
+
+ max9286_data->i2c_client->addr = ADDR_OV_SENSOR + index;
+
+ for (retry = 0; retry < timeout; retry++) {
+ if (i2c_master_send(max9286_data->i2c_client, u8_buf, buf_len) < 0) {
+ dev_dbg(&max9286_data->i2c_client->dev,
+ "%s:read reg error on send: reg=0x%x, retry = %d.\n", __func__, reg, retry);
+ msleep(5);
+ continue;
+ }
+ if (i2c_master_recv(max9286_data->i2c_client, &u8_val, 1) != 1) {
+ dev_dbg(&max9286_data->i2c_client->dev,
+ "%s:read reg error on recv: reg=0x%x, retry = %d.\n", __func__, reg, retry);
+ msleep(5);
+ continue;
+ }
+ break;
+ }
+
+ if (retry >= timeout) {
+ dev_info(&max9286_data->i2c_client->dev,
+ "%s:read reg error: reg=0x%x.\n", __func__, reg);
+ return -1;
+ }
+
+ *val = u8_val;
+
+ return u8_val;
+}
+
+static inline int ov10635_write_reg(struct sensor_data *max9286_data, int index,
+ unsigned short reg, unsigned char val)
+{
+ unsigned char u8_buf[3] = { 0 };
+ unsigned int buf_len = 3;
+ int retry, timeout = 10;
+
+ u8_buf[0] = (reg >> 8) & 0xFF;
+ u8_buf[1] = reg & 0xFF;
+ u8_buf[2] = val;
+
+ max9286_data->i2c_client->addr = ADDR_OV_SENSOR + index;
+ for (retry = 0; retry < timeout; retry++) {
+ if (i2c_master_send(max9286_data->i2c_client, u8_buf, buf_len) < 0) {
+ dev_dbg(&max9286_data->i2c_client->dev,
+ "%s:write reg error: reg=0x%x, val=0x%x, retry = %d.\n", __func__, reg, val, retry);
+ msleep(5);
+ continue;
+ }
+ break;
+ }
+
+ if (retry >= timeout) {
+ dev_info(&max9286_data->i2c_client->dev,
+ "%s:write reg error: reg=0x%x, val=0x%x.\n", __func__, reg, val);
+ return -1;
+ }
+
+ return 0;
+}
+
+static int ov10635_check_device(struct sensor_data *max9286_data, int index)
+{
+ unsigned char reg = 0;
+
+ ov10635_read_reg(max9286_data, index, OV10635_REG_PID, &reg);
+ if (reg != 0xA6) {
+ dev_err(&max9286_data->i2c_client->dev,
+ "%s: OV10635 hasn't been found, reg[0x%x] = 0x%x., index=%d\n",
+ __func__, OV10635_REG_PID, reg, index);
+ return -1;
+ }
+ ov10635_read_reg(max9286_data, index, OV10635_REG_VER, &reg);
+ if (reg != 0x35) {
+ dev_err(&max9286_data->i2c_client->dev,
+ "%s: OV10635 hasn't been found, reg[0x%x] = 0x%x.\n", __func__, OV10635_REG_VER, reg);
+ return -1;
+ }
+ dev_info(&max9286_data->i2c_client->dev, "%s: OV10635 index=%d was found.\n", __func__, index);
+
+ return 0;
+}
+
+static int ov10635_download_firmware(struct sensor_data *max9286_data,
+ int index, struct reg_value *pModeSetting, s32 ArySize)
+{
+ register u32 Delay_ms = 0;
+ register u16 RegAddr = 0;
+ register u8 Val = 0;
+ int i, retval = 0;
+
+ for (i = 0; i < ArySize; ++i, ++pModeSetting) {
+ Delay_ms = pModeSetting->delay_ms;
+ RegAddr = pModeSetting->reg_addr;
+ Val = pModeSetting->val;
+
+ retval = ov10635_write_reg(max9286_data, index, RegAddr, Val);
+ if (retval < 0)
+ goto err;
+
+ if (Delay_ms)
+ msleep(Delay_ms);
+ }
+err:
+ return retval;
+}
+
+static int ov10635_initialize(struct sensor_data *max9286_data, int index)
+{
+ int i, array_size;
+ int retval;
+
+ dev_info(&max9286_data->i2c_client->dev, "%s: index = %d.\n", __func__, index);
+ array_size = ARRAY_SIZE(ov10635_init_data);
+ for (i = 0; i < array_size; i++) {
+ retval = ov10635_write_reg(max9286_data, index,
+ ov10635_init_data[i].reg_addr, ov10635_init_data[i].val);
+ if (retval < 0)
+ break;
+ if (ov10635_init_data[i].delay_ms != 0)
+ msleep(ov10635_init_data[i].delay_ms);
+ }
+
+ return 0;
+}
+
+static inline int max9271_read_reg(struct sensor_data *max9286_data, int index, u8 reg)
+{
+ int val;
+ int retry, timeout = 10;
+
+ max9286_data->i2c_client->addr = ADDR_MAX9271 + index;
+ for (retry = 0; retry < timeout; retry++) {
+ val = i2c_smbus_read_byte_data(max9286_data->i2c_client, reg);
+ if (val < 0)
+ msleep(5);
+ else
+ break;
+ }
+
+ if (retry >= timeout) {
+ dev_info(&max9286_data->i2c_client->dev,
+ "%s:read reg error: reg=%2x\n", __func__, reg);
+ return -1;
+ }
+
+ return val;
+}
+
+static int max9271_write_reg(struct sensor_data *max9286_data, int index, u8 reg, u8 val)
+{
+ s32 ret;
+ int retry, timeout = 10;
+
+ max9286_data->i2c_client->addr = ADDR_MAX9271 + index;
+ for (retry = 0; retry < timeout; retry++) {
+ ret = i2c_smbus_write_byte_data(max9286_data->i2c_client, reg, val);
+ if (val < 0)
+ msleep(5);
+ else
+ break;
+ }
+ dev_dbg(&max9286_data->i2c_client->dev,
+ "%s: addr %02x reg %02x val %02x\n",
+ __func__, max9286_data->i2c_client->addr, reg, val);
+
+ if (retry >= timeout) {
+ dev_info(&max9286_data->i2c_client->dev,
+ "%s:write reg error:reg=%2x,val=%2x\n", __func__,
+ reg, val);
+ return -1;
+ }
+
+ return 0;
+}
+
+/*! Read one register from a MAX9286 i2c slave device.
+ *
+ * @param *reg register in the device we wish to access.
+ *
+ * @return 0 if success, an error code otherwise.
+ */
+static inline int max9286_read_reg(struct sensor_data *max9286_data, u8 reg)
+{
+ int val;
+
+ max9286_data->i2c_client->addr = ADDR_MAX9286;
+ val = i2c_smbus_read_byte_data(max9286_data->i2c_client, reg);
+ if (val < 0) {
+ dev_info(&max9286_data->i2c_client->dev,
+ "%s:read reg error: reg=%2x\n", __func__, reg);
+ return -1;
+ }
+ return val;
+}
+
+/*! Write one register of a MAX9286 i2c slave device.
+ *
+ * @param *reg register in the device we wish to access.
+ *
+ * @return 0 if success, an error code otherwise.
+ */
+static int max9286_write_reg(struct sensor_data *max9286_data, u8 reg, u8 val)
+{
+ s32 ret;
+
+ max9286_data->i2c_client->addr = ADDR_MAX9286;
+ ret = i2c_smbus_write_byte_data(max9286_data->i2c_client, reg, val);
+
+ dev_dbg(&max9286_data->i2c_client->dev,
+ "%s: addr %02x reg %02x val %02x\n",
+ __func__, max9286_data->i2c_client->addr, reg, val);
+
+ if (ret < 0) {
+ dev_info(&max9286_data->i2c_client->dev,
+ "%s:write reg error:reg=%2x,val=%2x\n", __func__,
+ reg, val);
+ return -1;
+ }
+ return 0;
+}
+
+#ifdef debug
+static void max9271_dump_registers(struct sensor_data *max9286_data, int index)
+{
+ unsigned char i;
+ printk("max9271_dump_registers: index = %d.\r\n", index);
+ for (i = 0; i < 0x20; i++)
+ printk("MAX9271 Reg 0x%02x = 0x%x.\r\n", i, max9271_read_reg(max9286_data, index, i));
+}
+
+static void max9286_dump_registers(struct sensor_data *max9286_data)
+{
+ unsigned char i;
+ printk("Dump MAX9286 registers:\r\n");
+ for (i = 0; i < 0x72; i++)
+ printk("MAX9286 Reg 0x%02x = 0x%x.\r\n", i, max9286_read_reg(max9286_data, i));
+}
+#else
+static void max9271_dump_registers(struct sensor_data *max9286_data, int index)
+{
+}
+#endif
+
+static void max9286_hw_reset(struct sensor_data *max9286_data)
+{
+ gpio_set_value(max9286_data->pwn_gpio, 0);
+ udelay(200);
+ gpio_set_value(max9286_data->pwn_gpio, 1);
+ msleep(1);
+}
+
+static int max9286_hardware_preinit(struct sensor_data *max9286_data)
+{
+ u8 reg;
+
+ dev_info(&max9286_data->i2c_client->dev, "In %s()\n", __func__);
+
+ /* Disable CSI Output */
+ max9286_write_reg(max9286_data, 0x15, 0x03);
+
+ /* Enable PRBS test */
+ max9286_write_reg(max9286_data, 0x0E, 0x5F);
+ msleep(10);
+
+ /* Enable Custom Reverse Channel & First Pulse Length STEP 1 */
+ max9286_write_reg(max9286_data, 0x3F, 0x4F);
+ msleep(2); /* STEP 2 */
+
+ /* Reverse Channel Amplitude to mid level and transition time */
+ max9286_write_reg(max9286_data, 0x3B, 0x1E); /* STEP 3 */
+ msleep(2); /* STEP 4 */
+
+ /* Enable MAX9271 Configuration Link */
+ max9271_write_reg(max9286_data, 0, 0x04, 0x43); /* STEP 5 */
+ msleep(2); /* STEP 6 */
+
+ /* Increase serializer reverse channel input thresholds */
+ max9271_write_reg(max9286_data, 0, 0x08, 0x01); /* STEP 7 */
+ msleep(2); /* STEP 8 */
+
+ /* Reverse Channel Amplitude level */
+ max9286_write_reg(max9286_data, 0x3B, 0x19); /* STEP 9 */
+ msleep(5); /* STEP 10 */
+
+ /* Set YUV422 8 bits mode, Double Data Rate, 4 data lane */
+ max9286_write_reg(max9286_data, 0x12, 0xF3); /* STEP 12 */
+
+ max9286_write_reg(max9286_data, 0x01, 0x02); /* STEP 13 */
+ /* Enable All Link 0-3 */
+ max9286_write_reg(max9286_data, 0x00, 0xef); /* STEP 14 */
+
+ /* Frame Sync */
+ /* Automatic Mode */
+ max9286_write_reg(max9286_data, 0x01, 0x02);/* STEP 13 */
+ msleep(200);
+ /* Detect link */
+ max9286_data->sensor_num = 0;
+ reg = max9286_read_reg(max9286_data, 0x49);
+ max9286_data->sensor_is_there = ((reg >> 4) & 0xF) | (reg & 0xF);
+ if (max9286_data->sensor_is_there & (0x1 << 0))
+ max9286_data->sensor_num += 1;
+ if (max9286_data->sensor_is_there & (0x1 << 1))
+ max9286_data->sensor_num += 1;
+ if (max9286_data->sensor_is_there & (0x1 << 2))
+ max9286_data->sensor_num += 1;
+ if (max9286_data->sensor_is_there & (0x1 << 3))
+ max9286_data->sensor_num += 1;
+ pr_info("max9286_mipi: reg = 0x%02x.\n", reg);
+ pr_info("max9286_mipi: sensor number = %d.\n", max9286_data->sensor_num);
+
+ if (max9286_data->sensor_num == 0) {
+ pr_err("%s: no camera connected.\n", __func__);
+ return -1;
+ }
+ return 0;
+
+}
+
+static void max9286_camera_reorder(struct sensor_data *max9286_data)
+{
+ u8 reg;
+
+ reg = 0xE4;
+ if (max9286_data->sensor_num == 1) {
+ switch (max9286_data->sensor_is_there) {
+ case 0x8:
+ reg = 0x27;
+ break;
+ case 0x4:
+ reg = 0xC6;
+ break;
+ case 0x2:
+ reg = 0xE1;
+ break;
+ case 0x1:
+ default:
+ reg = 0xE4;
+ break;
+ }
+ } else if (max9286_data->sensor_num == 2) {
+ switch (max9286_data->sensor_is_there) {
+ case 0xC:
+ reg = 0x4E;
+ break;
+ case 0xA:
+ reg = 0x72;
+ break;
+ case 0x9:
+ reg = 0x78;
+ break;
+ case 0x6:
+ reg = 0xD2;
+ break;
+ case 0x5:
+ reg = 0xD8;
+ break;
+ case 0x3:
+ default:
+ reg = 0xE4;
+ break;
+ }
+ } else if (max9286_data->sensor_num == 3) {
+ switch (max9286_data->sensor_is_there) {
+ case 0xE:
+ reg = 0x93;
+ break;
+ case 0xD:
+ reg = 0x9C;
+ break;
+ case 0xB:
+ reg = 0xB4;
+ break;
+ case 0x7:
+ default:
+ reg = 0xE4;
+ break;
+ }
+ }
+ max9286_write_reg(max9286_data, 0x0B, reg);
+}
+
+static int max9286_hardware_init(struct sensor_data *max9286_data)
+{
+ int retval = 0;
+ int i;
+ u8 reg, sensor_addr = 0;
+
+ dev_info(&max9286_data->i2c_client->dev, "In %s()\n", __func__);
+
+ /* Disable PRBS test */
+ max9286_write_reg(max9286_data, 0x0E, 0x50);
+
+ /* reorder camera */
+ max9286_camera_reorder(max9286_data);
+
+ /* Enable all links */
+ reg = 0xE0 | max9286_data->sensor_is_there;
+ max9286_write_reg(max9286_data, 0x00, reg);
+
+ /* Set up links */
+ sensor_addr = ADDR_OV_SENSOR;
+ max9271_write_reg(max9286_data, 0, 0x07, 0x84);
+ /* STEP 15-46 */
+ reg = 0;
+ for (i = 1; i <= MAX9271_MAX_SENSOR_NUM; i++) {
+ if (((0x1 << (i - 1)) & max9286_data->sensor_is_there) == 0)
+ continue;
+
+ /* Enable Link control channel */
+ reg |= (0x11 << (i - 1));
+ max9286_write_reg(max9286_data, 0x0A, reg);/* STEP 15 */
+
+ /* Set MAX9271 new address for link 0 */
+ max9271_write_reg(max9286_data, 0, 0x00, (ADDR_MAX9271 + i) << 1);
+ msleep(2);
+
+ max9271_write_reg(max9286_data, i, 0x01, ADDR_MAX9286 << 1);
+ max9271_write_reg(max9286_data, i, 0x09, (sensor_addr + i) << 1);
+ max9271_write_reg(max9286_data, i, 0x0A, sensor_addr << 1);
+ max9271_write_reg(max9286_data, i, 0x0B, ADDR_MAX9271_ALL << 1);
+ max9271_write_reg(max9286_data, i, 0x0C, (ADDR_MAX9271 + i) << 1);
+
+ msleep(1);
+ pr_info("max9286_mipi: initialized sensor = 0x%02x.\n", i);
+ max9271_dump_registers(max9286_data, i);
+ }
+ max9286_write_reg(max9286_data, 0x0A, reg);
+ max9286_write_reg(max9286_data, 0x0A, reg);
+
+ /* Disable Local Auto I2C ACK */
+ max9286_write_reg(max9286_data, 0x34, 0x36); /* STEP 48 */
+
+ /* Initialize Camera Sensor */
+ /* STEP 49 */
+ if (max9286_data->sensor_is_there & (0x1 << 0)) {
+ retval = ov10635_check_device(max9286_data, 1);
+ if (retval < 0)
+ return retval;
+ ov10635_initialize(max9286_data, 0);
+ }
+
+ if (max9286_data->sensor_is_there & (0x1 << 1)) {
+ retval = ov10635_check_device(max9286_data, 2);
+ if (retval < 0)
+ return retval;
+ ov10635_initialize(max9286_data, 1);
+ }
+
+ if (max9286_data->sensor_is_there & (0x1 << 2)) {
+ retval = ov10635_check_device(max9286_data, 3);
+ if (retval < 0)
+ return retval;
+ ov10635_initialize(max9286_data, 2);
+ }
+
+ if (max9286_data->sensor_is_there & (0x1 << 3)) {
+ retval = ov10635_check_device(max9286_data, 4);
+ if (retval < 0)
+ return retval;
+ ov10635_initialize(max9286_data, 3);
+ }
+
+ /* Enable Local Auto I2C ACK */
+ max9286_write_reg(max9286_data, 0x34, 0xB6); /* STEP 50 */
+
+ /* MAX9271: Enable Serial Links and Disable Configuration Link */
+ max9271_write_reg(max9286_data, ADDR_MAX9271_ALL - ADDR_MAX9271, 0x04, 0x83); /* STEP 51 */
+ /* Wait for more than 2 frame time */
+ msleep(1000); /* STEP 52 */
+
+ /* Enable CSI output, set virtual channel according to the link number */
+ max9286_write_reg(max9286_data, 0x15, 0x9B); /* STEP 52 */
+ msleep(10);
+ return retval;
+}
+
+static int ov10635_change_mode(struct sensor_data *max9286_data)
+{
+ struct reg_value *pModeSetting = NULL;
+ enum ov10635_mode mode = max9286_data->streamcap.capturemode;
+ enum ov10635_frame_rate rate =
+ to_ov10635_frame_rate(&max9286_data->streamcap.timeperframe);
+ int ArySize = 0, retval = 0;
+
+ if (mode > ov10635_mode_MAX || mode < ov10635_mode_MIN) {
+ pr_err("Wrong ov10635 mode detected!\n");
+ return -1;
+ }
+
+ pModeSetting = ov10635_mode_info_data[rate][mode].init_data_ptr;
+ ArySize = ov10635_mode_info_data[rate][mode].init_data_size;
+
+ max9286_data->format.width = ov10635_mode_info_data[rate][mode].width;
+ max9286_data->format.height = ov10635_mode_info_data[rate][mode].height;
+
+ if (max9286_data->format.width == 0 ||
+ max9286_data->format.height == 0 ||
+ pModeSetting == NULL || ArySize == 0) {
+ pr_err("Not support mode=%d %s\n", mode,
+ (rate == 0) ? "15(fps)" : "30(fps)");
+ return -EINVAL;
+ }
+
+ retval = ov10635_download_firmware(max9286_data, 0, pModeSetting, ArySize);
+
+ return retval;
+}
+
+static int max9286_g_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *a)
+{
+ struct v4l2_captureparm *cparm = &a->parm.capture;
+ struct sensor_data *max9286_data = subdev_to_sensor_data(sd);
+ int ret = 0;
+
+ switch (a->type) {
+ /* This is the only case currently handled. */
+ case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+ case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
+ memset(a, 0, sizeof(*a));
+ a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ cparm->capability = max9286_data->streamcap.capability;
+ cparm->timeperframe = max9286_data->streamcap.timeperframe;
+ cparm->capturemode = max9286_data->streamcap.capturemode;
+ ret = 0;
+ break;
+
+ /* These are all the possible cases. */
+ case V4L2_BUF_TYPE_VIDEO_OUTPUT:
+ case V4L2_BUF_TYPE_VIDEO_OVERLAY:
+ case V4L2_BUF_TYPE_VBI_CAPTURE:
+ case V4L2_BUF_TYPE_VBI_OUTPUT:
+ case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
+ case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
+ ret = -EINVAL;
+ break;
+ default:
+ pr_debug(" type is unknown - %d\n", a->type);
+ ret = -EINVAL;
+ break;
+ }
+
+ return ret;
+}
+
+/*!
+ * ioctl_s_parm - V4L2 sensor interface handler for VIDIOC_S_PARM ioctl
+ * @s: pointer to standard V4L2 device structure
+ * @a: pointer to standard V4L2 VIDIOC_S_PARM ioctl structure
+ *
+ * Configures the sensor to use the input parameters, if possible. If
+ * not possible, reverts to the old parameters and returns the
+ * appropriate error code.
+ */
+static int max9286_s_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *a)
+{
+ struct sensor_data *max9286_data = subdev_to_sensor_data(sd);
+ struct v4l2_fract *timeperframe = &a->parm.capture.timeperframe;
+ enum ov10635_frame_rate frame_rate;
+ enum ov10635_mode mode = a->parm.capture.capturemode;
+ u32 tgt_fps;
+ int ret = 0;
+
+ switch (a->type) {
+ /* This is the only case currently handled. */
+ case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+ case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
+ /* Check that the new frame rate is allowed. */
+ if ((timeperframe->numerator == 0) ||
+ (timeperframe->denominator == 0)) {
+ timeperframe->denominator = DEFAULT_FPS;
+ timeperframe->numerator = 1;
+ }
+
+ tgt_fps = timeperframe->denominator /
+ timeperframe->numerator;
+
+ if (tgt_fps > MAX_FPS) {
+ timeperframe->denominator = MAX_FPS;
+ timeperframe->numerator = 1;
+ } else if (tgt_fps < MIN_FPS) {
+ timeperframe->denominator = MIN_FPS;
+ timeperframe->numerator = 1;
+ }
+
+ /* Actual frame rate we use */
+ tgt_fps = timeperframe->denominator /
+ timeperframe->numerator;
+
+ if (tgt_fps == 30)
+ frame_rate = OV10635_30_FPS;
+ else if (tgt_fps == 15)
+ frame_rate = OV10635_15_FPS;
+ else
+ frame_rate = -EINVAL;
+
+ if (frame_rate != OV10635_30_FPS && frame_rate != OV10635_15_FPS) {
+ pr_err(" The camera %d frame rate is not supported!\n", frame_rate);
+ return -EINVAL;
+ }
+
+ if (mode > ov10635_mode_MAX || mode < ov10635_mode_MIN) {
+ pr_err("The camera mode[%d] is not supported!\n", mode);
+ return -EINVAL;
+ }
+
+ max9286_data->streamcap.timeperframe = *timeperframe;
+ max9286_data->streamcap.capturemode = a->parm.capture.capturemode;
+ max9286_data->format.reserved[0] = 72 * 8;
+ break;
+
+ /* These are all the possible cases. */
+ case V4L2_BUF_TYPE_VIDEO_OUTPUT:
+ case V4L2_BUF_TYPE_VIDEO_OVERLAY:
+ case V4L2_BUF_TYPE_VBI_CAPTURE:
+ case V4L2_BUF_TYPE_VBI_OUTPUT:
+ case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
+ case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
+ pr_debug(" type is not "\
+ "V4L2_BUF_TYPE_VIDEO_CAPTURE but %d\n",
+ a->type);
+ ret = -EINVAL;
+ break;
+
+ default:
+ pr_debug(" type is unknown - %d\n", a->type);
+ ret = -EINVAL;
+ break;
+ }
+
+ return ret;
+}
+
+static int max9286_enum_mbus_code(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_mbus_code_enum *code)
+{
+ struct sensor_data *max9286_data = subdev_to_sensor_data(sd);
+
+ code->code = max9286_data->format.code;
+ return 0;
+}
+
+/*!
+ * max9286_enum_framesizes - V4L2 sensor interface handler for
+ * VIDIOC_ENUM_FRAMESIZES ioctl
+ * @s: pointer to standard V4L2 device structure
+ * @fsize: standard V4L2 VIDIOC_ENUM_FRAMESIZES ioctl structure
+ *
+ * Return 0 if successful, otherwise -EINVAL.
+ */
+static int max9286_enum_framesizes(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_frame_size_enum *fse)
+{
+ if (fse->index > ov10635_mode_MAX)
+ return -EINVAL;
+
+ fse->max_width =
+ max(ov10635_mode_info_data[0][fse->index].width,
+ ov10635_mode_info_data[1][fse->index].width);
+ fse->min_width = fse->max_width;
+
+ fse->max_height =
+ max(ov10635_mode_info_data[0][fse->index].height,
+ ov10635_mode_info_data[1][fse->index].height);
+ fse->min_height = fse->max_height;
+
+ return 0;
+}
+static int max9286_enum_frame_interval(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_frame_interval_enum *fie)
+{
+ int i, j, count;
+
+ if (fie->index < 0 || fie->index > ov10635_mode_MAX)
+ return -EINVAL;
+
+ if (fie->width == 0 || fie->height == 0 ||
+ fie->code == 0) {
+ pr_warning("Please assign pixel format, width and height.\n");
+ return -EINVAL;
+ }
+
+ fie->interval.numerator = 1;
+
+ /* TODO Reserved to extension */
+ count = 0;
+ for (i = 0; i < ARRAY_SIZE(ov10635_framerates); i++) {
+ for (j = 0; j < (ov10635_mode_MAX + 1); j++) {
+ if (fie->width == ov10635_mode_info_data[i][j].width
+ && fie->height == ov10635_mode_info_data[i][j].height
+ && ov10635_mode_info_data[i][j].init_data_ptr != NULL) {
+ count++;
+ }
+ if (fie->index == (count - 1)) {
+ fie->interval.denominator = ov10635_framerates[i];
+ return 0;
+ }
+ }
+ }
+
+ return -EINVAL;
+}
+
+static int max9286_get_fmt(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_format *fmt)
+{
+ struct sensor_data *max9286_data = subdev_to_sensor_data(sd);
+ struct v4l2_mbus_framefmt *mf = &fmt->format;
+
+ if (fmt->pad)
+ return -EINVAL;
+
+ mf->code = max9286_data->format.code;
+ mf->width = max9286_data->format.width;
+ mf->height = max9286_data->format.height;
+ mf->colorspace = max9286_data->format.colorspace;
+ mf->field = max9286_data->format.field;
+ mf->reserved[0] = max9286_data->format.reserved[0];
+
+ return 0;
+}
+
+static struct ov10635_mode_info *get_max_resolution(enum ov10635_frame_rate rate)
+{
+ u32 max_width;
+ enum ov10635_mode mode;
+ int i;
+
+ mode = 0;
+ max_width = ov10635_mode_info_data[rate][0].width;
+
+ for (i = 0; i < (ov10635_mode_MAX + 1); i++) {
+ if (ov10635_mode_info_data[rate][i].width > max_width) {
+ max_width = ov10635_mode_info_data[rate][i].width;
+ mode = i;
+ }
+ }
+ return &ov10635_mode_info_data[rate][mode];
+}
+
+static struct ov10635_mode_info *match(struct v4l2_mbus_framefmt *fmt,
+ enum ov10635_frame_rate rate)
+{
+ struct ov10635_mode_info *info;
+ int i;
+
+ for (i = 0; i < (ov10635_mode_MAX + 1); i++) {
+ if (fmt->width == ov10635_mode_info_data[rate][i].width &&
+ fmt->height == ov10635_mode_info_data[rate][i].height) {
+ info = &ov10635_mode_info_data[rate][i];
+ break;
+ }
+ }
+ if (i == ov10635_mode_MAX + 1)
+ info = NULL;
+
+ return info;
+}
+
+static void try_to_find_resolution(struct sensor_data *sensor,
+ struct v4l2_mbus_framefmt *mf)
+{
+ enum ov10635_mode mode = sensor->streamcap.capturemode;
+ struct v4l2_fract *timeperframe = &sensor->streamcap.timeperframe;
+ enum ov10635_frame_rate frame_rate = to_ov10635_frame_rate(timeperframe);
+ struct device *dev = &sensor->i2c_client->dev;
+ struct ov10635_mode_info *info;
+ bool found = false;
+
+ /*printk("%s:%d mode=%d, frame_rate=%d, w/h=(%d,%d)\n", __func__, __LINE__,*/
+ /*mode, frame_rate, mf->width, mf->height);*/
+
+ if ((mf->width == ov10635_mode_info_data[frame_rate][mode].width) &&
+ (mf->height == ov10635_mode_info_data[frame_rate][mode].height)) {
+ info = &ov10635_mode_info_data[frame_rate][mode];
+ found = true;
+ } else {
+ /* get mode info according to frame user's width and height */
+ info = match(mf, frame_rate);
+ if (info == NULL) {
+ frame_rate ^= 0x1;
+ info = match(mf, frame_rate);
+ if (info) {
+ sensor->streamcap.capturemode = -1;
+ dev_err(dev, "%s %dx%d only support %s(fps)\n", __func__,
+ info->width, info->height,
+ (frame_rate == 0) ? "15fps" : "30fps");
+ return;
+ }
+ goto max_resolution;
+ }
+ found = true;
+ }
+
+ /* get max resolution to resize */
+max_resolution:
+ if (!found) {
+ frame_rate ^= 0x1;
+ info = get_max_resolution(frame_rate);
+ }
+
+ /*printk("%s:%d mode=%d, frame_rate=%d, w/h=(%d,%d)\n", __func__, __LINE__,*/
+ /*mode, frame_rate, mf->width, mf->height);*/
+
+ sensor->streamcap.capturemode = info->mode;
+ sensor->streamcap.timeperframe.denominator = (frame_rate) ? 30 : 15;
+ sensor->format.width = info->width;
+ sensor->format.height = info->height;
+}
+
+static int max9286_set_fmt(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_format *fmt)
+{
+ struct sensor_data *max9286_data = subdev_to_sensor_data(sd);
+ struct v4l2_mbus_framefmt *mf = &fmt->format;
+ int ret;
+
+ if (fmt->pad)
+ return -EINVAL;
+
+ mf->code = max9286_data->format.code;
+ mf->colorspace = max9286_data->format.colorspace;
+ mf->field = V4L2_FIELD_NONE;
+
+ try_to_find_resolution(max9286_data, mf);
+
+ if (fmt->which == V4L2_SUBDEV_FORMAT_TRY)
+ return 0;
+
+ ret = ov10635_change_mode(max9286_data);
+
+ return ret;
+}
+
+static int max9286_get_frame_desc(struct v4l2_subdev *sd, unsigned int pad,
+ struct v4l2_mbus_frame_desc *fd)
+{
+ return 0;
+}
+
+static int max9286_set_frame_desc(struct v4l2_subdev *sd,
+ unsigned int pad,
+ struct v4l2_mbus_frame_desc *fd)
+{
+ return 0;
+}
+
+static int max9286_set_power(struct v4l2_subdev *sd, int on)
+{
+ return 0;
+}
+
+static int max9286_s_stream(struct v4l2_subdev *sd, int enable)
+{
+ struct sensor_data *max9286_data = subdev_to_sensor_data(sd);
+
+ dev_dbg(sd->dev, "%s\n", __func__);
+ if (enable) {
+ if (!max9286_data->running) {
+ /* Enable CSI output, set virtual channel according to the link number */
+ max9286_write_reg(max9286_data, 0x15, 0x9B);
+ }
+ max9286_data->running++;
+
+ } else {
+
+ if (max9286_data->running) {
+ /* Disable CSI Output */
+ max9286_write_reg(max9286_data, 0x15, 0x03);
+ }
+ max9286_data->running--;
+ }
+
+ return 0;
+}
+
+static int max9286_link_setup(struct media_entity *entity,
+ const struct media_pad *local,
+ const struct media_pad *remote, u32 flags)
+{
+ return 0;
+}
+
+static const struct v4l2_subdev_pad_ops max9286_pad_ops = {
+ .enum_mbus_code = max9286_enum_mbus_code,
+ .enum_frame_size = max9286_enum_framesizes,
+ .enum_frame_interval = max9286_enum_frame_interval,
+ .get_fmt = max9286_get_fmt,
+ .set_fmt = max9286_set_fmt,
+ .get_frame_desc = max9286_get_frame_desc,
+ .set_frame_desc = max9286_set_frame_desc,
+};
+
+static const struct v4l2_subdev_core_ops max9286_core_ops = {
+ .s_power = max9286_set_power,
+};
+
+static const struct v4l2_subdev_video_ops max9286_video_ops = {
+ .s_parm = max9286_s_parm,
+ .g_parm = max9286_g_parm,
+ .s_stream = max9286_s_stream,
+};
+
+static const struct v4l2_subdev_ops max9286_subdev_ops = {
+ .core = &max9286_core_ops,
+ .pad = &max9286_pad_ops,
+ .video = &max9286_video_ops,
+};
+
+static const struct media_entity_operations max9286_sd_media_ops = {
+ .link_setup = max9286_link_setup,
+};
+
+ssize_t analog_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct v4l2_subdev *sd = dev_get_drvdata(dev);
+ struct sensor_data *max9286_data = subdev_to_sensor_data(sd);
+ u8 val = 0;
+
+ ov10635_read_reg(max9286_data, 0, 0x370A, &val);
+ return sprintf(buf, "%s\n", (val & 0x4) ? "enabled" : "disabled");
+}
+
+static ssize_t analog_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ struct v4l2_subdev *sd = dev_get_drvdata(dev);
+ struct sensor_data *max9286_data = subdev_to_sensor_data(sd);
+ char enabled[32];
+
+ if (sscanf(buf, "%s", enabled) > 0) {
+ if (strcmp(enabled, "enable") == 0)
+ ov10635_write_reg(max9286_data, 0, 0x370A, 0x4);
+ else
+ ov10635_write_reg(max9286_data, 0, 0x370A, 0x0);
+ return count;
+ }
+ return -EINVAL;
+}
+
+static DEVICE_ATTR(analog_test_pattern, 0644, analog_show, analog_store);
+
+/*!
+ * max9286 I2C probe function
+ *
+ * @param adapter struct i2c_adapter *
+ * @return Error code indicating success or failure
+ */
+static int max9286_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct device *dev = &client->dev;
+ struct sensor_data *max9286_data;
+ struct v4l2_subdev *sd;
+ int retval;
+
+ max9286_data = devm_kzalloc(dev, sizeof(*max9286_data), GFP_KERNEL);
+ if (!max9286_data)
+ return -ENOMEM;
+
+ /* Set initial values for the sensor struct. */
+ max9286_data->sensor_clk = devm_clk_get(dev, "capture_mclk");
+ if (IS_ERR(max9286_data->sensor_clk)) {
+ /* assuming clock enabled by default */
+ max9286_data->sensor_clk = NULL;
+ dev_err(dev, "clock-frequency missing or invalid\n");
+ return PTR_ERR(max9286_data->sensor_clk);
+ }
+
+ retval = of_property_read_u32(dev->of_node, "mclk",
+ &(max9286_data->mclk));
+ if (retval) {
+ dev_err(dev, "mclk missing or invalid\n");
+ return retval;
+ }
+
+ retval = of_property_read_u32(dev->of_node, "mclk_source",
+ (u32 *)&(max9286_data->mclk_source));
+ if (retval) {
+ dev_err(dev, "mclk_source missing or invalid\n");
+ return retval;
+ }
+
+ /* request power down pin */
+ max9286_data->pwn_gpio = of_get_named_gpio(dev->of_node, "pwn-gpios", 0);
+ if (!gpio_is_valid(max9286_data->pwn_gpio)) {
+ dev_err(dev, "no sensor pwdn pin available\n");
+ return -ENODEV;
+ }
+ retval = devm_gpio_request_one(dev, max9286_data->pwn_gpio, GPIOF_OUT_INIT_HIGH,
+ "max9286_pwd");
+ if (retval < 0)
+ return retval;
+
+ max9286_hw_reset(max9286_data);
+
+ clk_prepare_enable(max9286_data->sensor_clk);
+
+ max9286_data->i2c_client = client;
+ max9286_data->format.code = MEDIA_BUS_FMT_YUYV8_1X16;
+ max9286_data->format.width = ov10635_mode_info_data[1][0].width;
+ max9286_data->format.height = ov10635_mode_info_data[1][0].height;
+ max9286_data->format.colorspace = V4L2_COLORSPACE_JPEG;
+ /*****************************************
+ * Pass mipi phy clock rate Mbps
+ * fcsi2 = PCLk * WIDTH * CHANNELS / LANES
+ * fsci2 = 72MPCLK * 8 bit * 4 channels / 4 lanes
+ ****************************************/
+ max9286_data->format.reserved[0] = 72 * 8;
+ max9286_data->format.field = V4L2_FIELD_NONE;
+ max9286_data->streamcap.capturemode = 0;
+ max9286_data->streamcap.timeperframe.denominator = 30;
+ max9286_data->streamcap.timeperframe.numerator = 1;
+ max9286_data->is_mipi = 1;
+
+ retval = max9286_read_reg(max9286_data, 0x1e);
+ if (retval != 0x40) {
+ pr_warning("max9286 is not found, chip id reg 0x1e = 0x%x.\n", retval);
+ clk_disable_unprepare(max9286_data->sensor_clk);
+ devm_gpio_free(dev, max9286_data->pwn_gpio);
+ return -ENODEV;
+ }
+
+ max9286_hardware_preinit(max9286_data);
+
+ if (max9286_data->sensor_num == 0) {
+ pr_warning("cameras are not found,\n");
+ clk_disable_unprepare(max9286_data->sensor_clk);
+ devm_gpio_free(dev, max9286_data->pwn_gpio);
+ return -ENODEV;
+ }
+
+ max9286_data->streamcap.capability = V4L2_CAP_TIMEPERFRAME;
+ max9286_data->streamcap.timeperframe.denominator = 30;
+ max9286_data->streamcap.timeperframe.numerator = 1;
+ max9286_data->v_channel = 0;
+ max9286_data->cap_mode.clip_top = 0;
+ max9286_data->cap_mode.clip_left = 0;
+
+ max9286_data->cap_mode.clip_height = 800;
+ max9286_data->cap_mode.clip_width = 1280;
+
+ max9286_data->cap_mode.hlen = max9286_data->cap_mode.clip_width;
+
+ max9286_data->cap_mode.hfp = 0;
+ max9286_data->cap_mode.hbp = 0;
+ max9286_data->cap_mode.hsync = 625;
+ max9286_data->cap_mode.vlen = 800;
+ max9286_data->cap_mode.vfp = 0;
+ max9286_data->cap_mode.vbp = 0;
+ max9286_data->cap_mode.vsync = 40;
+ max9286_data->cap_mode.vlen1 = 0;
+ max9286_data->cap_mode.vfp1 = 0;
+ max9286_data->cap_mode.vbp1 = 0;
+ max9286_data->cap_mode.vsync1 = 0;
+ max9286_data->cap_mode.pixelclock = 27000000;
+
+ sd = &max9286_data->subdev;
+ v4l2_i2c_subdev_init(sd, client, &max9286_subdev_ops);
+ sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+
+ sd->entity.function = MEDIA_ENT_F_CAM_SENSOR;
+ max9286_data->pads[MIPI_CSI2_SENS_VC0_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
+ max9286_data->pads[MIPI_CSI2_SENS_VC1_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
+ max9286_data->pads[MIPI_CSI2_SENS_VC2_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
+ max9286_data->pads[MIPI_CSI2_SENS_VC3_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
+ retval = media_entity_pads_init(&sd->entity, MIPI_CSI2_SENS_VCX_PADS_NUM,
+ max9286_data->pads);
+ if (retval < 0)
+ return retval;
+
+ max9286_data->subdev.entity.ops = &max9286_sd_media_ops;
+ retval = v4l2_async_register_subdev(&max9286_data->subdev);
+ if (retval < 0) {
+ dev_err(&client->dev,
+ "%s--Async register failed, ret=%d\n", __func__, retval);
+ media_entity_cleanup(&sd->entity);
+ }
+
+ retval = max9286_hardware_init(max9286_data);
+ if (retval < 0) {
+ dev_err(&client->dev, "camera init failed\n");
+ clk_disable_unprepare(max9286_data->sensor_clk);
+ media_entity_cleanup(&sd->entity);
+ v4l2_async_unregister_subdev(sd);
+ return retval;
+ }
+
+ max9286_data->running = 0;
+
+ /* Disable CSI Output */
+ max9286_write_reg(max9286_data, 0x15, 0x03);
+
+ /*Create device attr in sys */
+ retval = device_create_file(&client->dev, &dev_attr_analog_test_pattern);
+ if (retval < 0) {
+ dev_err(&client->dev, "%s: create device file fail\n", __func__);
+ return retval;
+ }
+
+ dev_info(&max9286_data->i2c_client->dev,
+ "max9286_mipi is found, name %s\n", sd->name);
+ return retval;
+}
+
+/*!
+ * max9286 I2C detach function
+ *
+ * @param client struct i2c_client *
+ * @return Error code indicating success or failure
+ */
+static int max9286_remove(struct i2c_client *client)
+{
+ struct v4l2_subdev *sd = i2c_get_clientdata(client);
+ struct sensor_data *max9286_data = subdev_to_sensor_data(sd);
+
+ clk_disable_unprepare(max9286_data->sensor_clk);
+ device_remove_file(&client->dev, &dev_attr_analog_test_pattern);
+ media_entity_cleanup(&sd->entity);
+ v4l2_async_unregister_subdev(sd);
+
+ return 0;
+}
+static const struct i2c_device_id max9286_id[] = {
+ {},
+};
+
+MODULE_DEVICE_TABLE(i2c, max9286_id);
+
+static const struct of_device_id max9286_of_match[] = {
+ { .compatible = "maxim,max9286_mipi" },
+ { /* sentinel */ }
+};
+
+static struct i2c_driver max9286_i2c_driver = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "max9286_mipi",
+ .of_match_table = of_match_ptr(max9286_of_match),
+ },
+ .probe = max9286_probe,
+ .remove = max9286_remove,
+ .id_table = max9286_id,
+};
+
+module_i2c_driver(max9286_i2c_driver);
+
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("MAX9286 GSML Deserializer Driver");
+MODULE_LICENSE("GPL");
+MODULE_VERSION("1.0");
+MODULE_ALIAS("CSI");
diff --git a/drivers/media/platform/imx8/mxc-isi-cap.c b/drivers/media/platform/imx8/mxc-isi-cap.c
new file mode 100644
index 000000000000..16d43b6a786f
--- /dev/null
+++ b/drivers/media/platform/imx8/mxc-isi-cap.c
@@ -0,0 +1,1795 @@
+/*
+ * Copyright 2017-2018 NXP
+ */
+/*
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/bug.h>
+#include <linux/interrupt.h>
+#include <linux/device.h>
+#include <linux/pm_runtime.h>
+#include <linux/list.h>
+#include <linux/slab.h>
+#include <linux/of_graph.h>
+
+#include <linux/videodev2.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-ioctl.h>
+#include <media/v4l2-mem2mem.h>
+#include <media/videobuf2-core.h>
+#include <media/videobuf2-dma-contig.h>
+#include <soc/imx8/sc/sci.h>
+
+#include "mxc-isi-core.h"
+#include "mxc-isi-hw.h"
+#include "mxc-media-dev.h"
+
+struct mxc_isi_fmt mxc_isi_out_formats[] = {
+ {
+ .name = "RGB565",
+ .fourcc = V4L2_PIX_FMT_RGB565,
+ .depth = { 16 },
+ .color = MXC_ISI_OUT_FMT_RGB565,
+ .memplanes = 1,
+ .colplanes = 1,
+ .mbus_code = MEDIA_BUS_FMT_RGB565_1X16,
+ }, {
+ .name = "RGB24",
+ .fourcc = V4L2_PIX_FMT_RGB24,
+ .depth = { 24 },
+ .color = MXC_ISI_OUT_FMT_BGR32P,
+ .memplanes = 1,
+ .colplanes = 1,
+ .mbus_code = MEDIA_BUS_FMT_RGB888_1X24,
+ }, {
+ .name = "BGR24",
+ .fourcc = V4L2_PIX_FMT_BGR24,
+ .depth = { 24 },
+ .color = MXC_ISI_OUT_FMT_RGB32P,
+ .memplanes = 1,
+ .colplanes = 1,
+ .mbus_code = MEDIA_BUS_FMT_BGR888_1X24,
+ }, {
+ .name = "YUYV-16",
+ .fourcc = V4L2_PIX_FMT_YUYV,
+ .depth = { 16 },
+ .color = MXC_ISI_OUT_FMT_YUV422_1P8P,
+ .memplanes = 1,
+ .colplanes = 1,
+ .mbus_code = MEDIA_BUS_FMT_YUYV8_1X16,
+ }, {
+ .name = "YUV32 (X-Y-U-V)",
+ .fourcc = V4L2_PIX_FMT_YUV32,
+ .depth = { 32 },
+ .color = MXC_ISI_OUT_FMT_YUV444_1P8,
+ .memplanes = 1,
+ .colplanes = 1,
+ .mbus_code = MEDIA_BUS_FMT_AYUV8_1X32,
+ }, {
+ .name = "NV12 (YUYV)",
+ .fourcc = V4L2_PIX_FMT_NV12,
+ .depth = { 8, 8 },
+ .color = MXC_ISI_OUT_FMT_YUV420_2P8P,
+ .memplanes = 2,
+ .colplanes = 2,
+ .mbus_code = MEDIA_BUS_FMT_YUYV8_1X16,
+ }, {
+ .name = "YUV444M (Y-U-V)",
+ .fourcc = V4L2_PIX_FMT_YUV444M,
+ .depth = { 8, 8, 8 },
+ .color = MXC_ISI_OUT_FMT_YUV444_3P8P,
+ .memplanes = 3,
+ .colplanes = 3,
+ .mbus_code = MEDIA_BUS_FMT_YUV8_1X24,
+ }, {
+ .name = "xBGR32",
+ .fourcc = V4L2_PIX_FMT_XBGR32,
+ .depth = { 32 },
+ .color = MXC_ISI_OUT_FMT_XRGB32,
+ .memplanes = 1,
+ .colplanes = 1,
+ .mbus_code = MEDIA_BUS_FMT_RGB888_1X24,
+ }, {
+ .name = "ABGR32",
+ .fourcc = V4L2_PIX_FMT_ABGR32,
+ .depth = { 32 },
+ .color = MXC_ISI_OUT_FMT_ARGB32,
+ .memplanes = 1,
+ .colplanes = 1,
+ .mbus_code = MEDIA_BUS_FMT_RGB888_1X24,
+ }
+};
+
+struct mxc_isi_fmt mxc_isi_src_formats[] = {
+ /* Pixel link input format */
+ {
+ .name = "RGB32",
+ .fourcc = V4L2_PIX_FMT_RGB32,
+ .depth = { 32 },
+ .memplanes = 1,
+ .colplanes = 1,
+ }, {
+ .name = "YUV32 (X-Y-U-V)",
+ .fourcc = V4L2_PIX_FMT_YUV32,
+ .depth = { 32 },
+ .memplanes = 1,
+ .colplanes = 1,
+ }
+};
+
+struct mxc_isi_fmt *mxc_isi_get_format(unsigned int index)
+{
+ return &mxc_isi_out_formats[index];
+}
+
+/**
+ * mxc_isi_find_format - lookup mxc_isi color format by fourcc or media bus format
+ */
+struct mxc_isi_fmt *mxc_isi_find_format(const u32 *pixelformat,
+ const u32 *mbus_code, int index)
+{
+ struct mxc_isi_fmt *fmt, *def_fmt = NULL;
+ unsigned int i;
+ int id = 0;
+
+ if (index >= (int)ARRAY_SIZE(mxc_isi_out_formats))
+ return NULL;
+
+ for (i = 0; i < ARRAY_SIZE(mxc_isi_out_formats); i++) {
+ fmt = &mxc_isi_out_formats[i];
+ if (pixelformat && fmt->fourcc == *pixelformat)
+ return fmt;
+ if (mbus_code && fmt->mbus_code == *mbus_code)
+ return fmt;
+ if (index == id)
+ def_fmt = fmt;
+ id++;
+ }
+ return def_fmt;
+}
+
+struct mxc_isi_fmt *mxc_isi_get_src_fmt(struct v4l2_subdev_format *sd_fmt)
+{
+ u32 index;
+
+ /* two fmt RGB32 and YUV444 from pixellink */
+ if (sd_fmt->format.code == MEDIA_BUS_FMT_YUYV8_1X16 ||
+ sd_fmt->format.code == MEDIA_BUS_FMT_YVYU8_2X8 ||
+ sd_fmt->format.code == MEDIA_BUS_FMT_AYUV8_1X32 ||
+ sd_fmt->format.code == MEDIA_BUS_FMT_UYVY8_2X8)
+ index = 1;
+ else
+ index = 0;
+ return &mxc_isi_src_formats[index];
+}
+
+/*
+ * mxc_isi_pipeline_enable() - Enable streaming on a pipeline
+ *
+ */
+static int mxc_isi_pipeline_enable(struct mxc_isi_dev *mxc_isi, bool enable)
+{
+ struct media_entity *entity = &mxc_isi->isi_cap.vdev.entity;
+ struct media_device *mdev = entity->graph_obj.mdev;
+ struct media_graph graph;
+ struct v4l2_subdev *subdev;
+ int ret = 0;
+
+ mutex_lock(&mdev->graph_mutex);
+
+ ret = media_graph_walk_init(&graph, entity->graph_obj.mdev);
+ if (ret) {
+ mutex_unlock(&mdev->graph_mutex);
+ return ret;
+ }
+ media_graph_walk_start(&graph, entity);
+
+ while ((entity = media_graph_walk_next(&graph))) {
+ if (entity == NULL) {
+ dev_dbg(&mxc_isi->pdev->dev,
+ "%s ,entity is NULL\n", __func__);
+ continue;
+ }
+
+ if (!is_media_entity_v4l2_subdev(entity)) {
+ dev_dbg(&mxc_isi->pdev->dev,
+ "%s ,entity is no v4l2, %s\n", __func__, entity->name);
+ continue;
+ }
+
+ subdev = media_entity_to_v4l2_subdev(entity);
+ if (subdev == NULL) {
+ dev_dbg(&mxc_isi->pdev->dev,
+ "%s ,%s,subdev is NULL\n", __func__, entity->name);
+ continue;
+ }
+
+ ret = v4l2_subdev_call(subdev, video, s_stream, enable);
+ if (ret < 0 && ret != -ENOIOCTLCMD) {
+ dev_err(&mxc_isi->pdev->dev,
+ "%s ,subdev %s s_stream failed\n", __func__, subdev->name);
+ break;
+ }
+ }
+ mutex_unlock(&mdev->graph_mutex);
+ media_graph_walk_cleanup(&graph);
+
+ return ret;
+}
+
+static int mxc_isi_update_buf_paddr(struct mxc_isi_buffer *buf, int memplanes)
+{
+ struct frame_addr *paddr = &buf->paddr;
+ struct vb2_buffer *vb2 = &buf->v4l2_buf.vb2_buf;
+ int ret = 0;
+
+ /* support one plane now */
+ paddr->cb = 0;
+ paddr->cr = 0;
+
+ switch (memplanes) {
+ case 3:
+ paddr->cr = vb2_dma_contig_plane_dma_addr(vb2, 2);
+ case 2:
+ paddr->cb = vb2_dma_contig_plane_dma_addr(vb2, 1);
+ case 1:
+ paddr->y = vb2_dma_contig_plane_dma_addr(vb2, 0);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return ret;
+}
+
+void mxc_isi_cap_frame_write_done(struct mxc_isi_dev *mxc_isi)
+{
+ struct mxc_isi_buffer *buf;
+ struct vb2_buffer *vb2;
+
+ if (list_empty(&mxc_isi->isi_cap.out_active)) {
+ dev_warn(&mxc_isi->pdev->dev,
+ "%s trying to access empty active list\n", __func__);
+ return;
+ }
+
+ buf = list_first_entry(&mxc_isi->isi_cap.out_active,
+ struct mxc_isi_buffer, list);
+
+ if (buf->discard) {
+ list_move_tail(mxc_isi->isi_cap.out_active.next,
+ &mxc_isi->isi_cap.out_discard);
+ } else {
+ vb2 = &buf->v4l2_buf.vb2_buf;
+ list_del_init(&buf->list);
+ buf->v4l2_buf.vb2_buf.timestamp = ktime_get_ns();
+ vb2_buffer_done(&buf->v4l2_buf.vb2_buf, VB2_BUF_STATE_DONE);
+ }
+
+ mxc_isi->isi_cap.frame_count++;
+
+ if (list_empty(&mxc_isi->isi_cap.out_pending)) {
+ if (list_empty(&mxc_isi->isi_cap.out_discard)) {
+ dev_warn(&mxc_isi->pdev->dev,
+ "%s: trying to access empty discard list\n", __func__);
+ return;
+ }
+
+ buf = list_first_entry(&mxc_isi->isi_cap.out_discard,
+ struct mxc_isi_buffer, list);
+ buf->v4l2_buf.sequence = mxc_isi->isi_cap.frame_count;
+ mxc_isi_channel_set_outbuf(mxc_isi, buf);
+ list_move_tail(mxc_isi->isi_cap.out_discard.next,
+ &mxc_isi->isi_cap.out_active);
+ return;
+ }
+
+ /* ISI channel output buffer */
+ buf = list_first_entry(&mxc_isi->isi_cap.out_pending,
+ struct mxc_isi_buffer, list);
+
+ buf->v4l2_buf.sequence = mxc_isi->isi_cap.frame_count;
+ mxc_isi_channel_set_outbuf(mxc_isi, buf);
+ vb2 = &buf->v4l2_buf.vb2_buf;
+ vb2->state = VB2_BUF_STATE_ACTIVE;
+ list_move_tail(mxc_isi->isi_cap.out_pending.next, &mxc_isi->isi_cap.out_active);
+}
+
+static int cap_vb2_queue_setup(struct vb2_queue *q,
+ unsigned int *num_buffers, unsigned int *num_planes,
+ unsigned int sizes[], struct device *alloc_devs[])
+{
+ struct mxc_isi_dev *mxc_isi = q->drv_priv;
+ struct mxc_isi_frame *dst_f = &mxc_isi->isi_cap.dst_f;
+ struct mxc_isi_fmt *fmt = dst_f->fmt;
+ unsigned long wh;
+ int i;
+
+ if (fmt == NULL)
+ return -EINVAL;
+
+ for (i = 0; i < fmt->memplanes; i++)
+ alloc_devs[i] = &mxc_isi->pdev->dev;
+
+ wh = dst_f->width * dst_f->height;
+
+ *num_planes = fmt->memplanes;
+
+ for (i = 0; i < fmt->memplanes; i++) {
+ unsigned int size = (wh * fmt->depth[i]) / 8;
+
+ if (i == 1 && fmt->fourcc == V4L2_PIX_FMT_NV12)
+ size >>= 1;
+ sizes[i] = max_t(u32, size, dst_f->sizeimage[i]);
+ }
+ dev_dbg(&mxc_isi->pdev->dev, "%s, buf_n=%d, size=%d\n",
+ __func__, *num_buffers, sizes[0]);
+
+ return 0;
+}
+
+static int cap_vb2_buffer_prepare(struct vb2_buffer *vb2)
+{
+ struct vb2_queue *q = vb2->vb2_queue;
+ struct mxc_isi_dev *mxc_isi = q->drv_priv;
+ struct mxc_isi_frame *dst_f = &mxc_isi->isi_cap.dst_f;
+ int i;
+
+ dev_dbg(&mxc_isi->pdev->dev, "%s\n", __func__);
+
+ if (mxc_isi->isi_cap.dst_f.fmt == NULL)
+ return -EINVAL;
+
+ for (i = 0; i < dst_f->fmt->memplanes; i++) {
+ unsigned long size = dst_f->sizeimage[i];
+
+ if (vb2_plane_size(vb2, i) < size) {
+ v4l2_err(&mxc_isi->isi_cap.vdev,
+ "User buffer too small (%ld < %ld)\n",
+ vb2_plane_size(vb2, i), size);
+ return -EINVAL;
+ }
+#if 0 //debug only
+ if (vb2_plane_vaddr(vb2, i))
+ memset((void *)vb2_plane_vaddr(vb2, i), 0xaa,
+ vb2_get_plane_payload(vb2, i));
+#endif
+ vb2_set_plane_payload(vb2, i, size);
+ }
+
+ return 0;
+}
+
+static void cap_vb2_buffer_queue(struct vb2_buffer *vb2)
+{
+ struct vb2_v4l2_buffer *v4l2_buf = to_vb2_v4l2_buffer(vb2);
+ struct mxc_isi_buffer *buf
+ = container_of(v4l2_buf, struct mxc_isi_buffer, v4l2_buf);
+ struct mxc_isi_dev *mxc_isi = vb2_get_drv_priv(vb2->vb2_queue);
+ unsigned long flags;
+
+ spin_lock_irqsave(&mxc_isi->slock, flags);
+
+ mxc_isi_update_buf_paddr(buf, mxc_isi->isi_cap.dst_f.fmt->mdataplanes);
+ list_add_tail(&buf->list, &mxc_isi->isi_cap.out_pending);
+
+ spin_unlock_irqrestore(&mxc_isi->slock, flags);
+}
+
+static int cap_vb2_start_streaming(struct vb2_queue *q, unsigned int count)
+{
+ struct mxc_isi_dev *mxc_isi = q->drv_priv;
+ struct mxc_isi_buffer *buf;
+ struct vb2_buffer *vb2;
+ unsigned long flags;
+ int i, j;
+
+ dev_dbg(&mxc_isi->pdev->dev, "%s\n", __func__);
+
+ if (count < 2)
+ return -ENOBUFS;
+
+ /* Create a buffer for discard operation */
+ for (i = 0; i < mxc_isi->pix.num_planes; i++) {
+ mxc_isi->discard_size[i] = mxc_isi->isi_cap.dst_f.sizeimage[i];
+ mxc_isi->discard_buffer[i] = dma_alloc_coherent(&mxc_isi->pdev->dev,
+ PAGE_ALIGN(mxc_isi->discard_size[i]),
+ &mxc_isi->discard_buffer_dma[i], GFP_DMA | GFP_KERNEL);
+ if (!mxc_isi->discard_buffer[i]) {
+ for (j = 0; j < i; j++) {
+ dma_free_coherent(&mxc_isi->pdev->dev,
+ mxc_isi->discard_size[j],
+ mxc_isi->discard_buffer[j],
+ mxc_isi->discard_buffer_dma[j]);
+ dev_err(&mxc_isi->pdev->dev, "%s: alloc dma buffer_%d fail\n",
+ __func__, j);
+ }
+ return -ENOMEM;
+ }
+ dev_dbg(&mxc_isi->pdev->dev,
+ "%s: num_plane=%d discard_size=%d discard_buffer=%p\n"
+ , __func__, i,
+ (int)mxc_isi->discard_size[i],
+ mxc_isi->discard_buffer[i]);
+ }
+
+ spin_lock_irqsave(&mxc_isi->slock, flags);
+
+ /* add two list member to out_discard list head */
+ mxc_isi->buf_discard[0].discard = true;
+ list_add_tail(&mxc_isi->buf_discard[0].list, &mxc_isi->isi_cap.out_discard);
+
+ mxc_isi->buf_discard[1].discard = true;
+ list_add_tail(&mxc_isi->buf_discard[1].list, &mxc_isi->isi_cap.out_discard);
+
+
+ /* ISI channel output buffer 1 */
+ buf = list_first_entry(&mxc_isi->isi_cap.out_discard,
+ struct mxc_isi_buffer, list);
+ buf->v4l2_buf.sequence = 0;
+ vb2 = &buf->v4l2_buf.vb2_buf;
+ vb2->state = VB2_BUF_STATE_ACTIVE;
+ mxc_isi_channel_set_outbuf(mxc_isi, buf);
+ list_move_tail(mxc_isi->isi_cap.out_discard.next, &mxc_isi->isi_cap.out_active);
+
+ /* ISI channel output buffer 2 */
+ buf = list_first_entry(&mxc_isi->isi_cap.out_pending,
+ struct mxc_isi_buffer, list);
+ buf->v4l2_buf.sequence = 1;
+ vb2 = &buf->v4l2_buf.vb2_buf;
+ vb2->state = VB2_BUF_STATE_ACTIVE;
+ mxc_isi_channel_set_outbuf(mxc_isi, buf);
+ list_move_tail(mxc_isi->isi_cap.out_pending.next, &mxc_isi->isi_cap.out_active);
+
+ /* Clear frame count */
+ mxc_isi->isi_cap.frame_count = 1;
+ spin_unlock_irqrestore(&mxc_isi->slock, flags);
+
+ return 0;
+}
+
+static void cap_vb2_stop_streaming(struct vb2_queue *q)
+{
+ struct mxc_isi_dev *mxc_isi = q->drv_priv;
+ struct mxc_isi_buffer *buf, *tmp;
+ unsigned long flags;
+ int i;
+
+ dev_dbg(&mxc_isi->pdev->dev, "%s\n", __func__);
+
+ mxc_isi_channel_disable(mxc_isi);
+
+ spin_lock_irqsave(&mxc_isi->slock, flags);
+
+ while (!list_empty(&mxc_isi->isi_cap.out_active)) {
+ buf = list_entry(mxc_isi->isi_cap.out_active.next, struct mxc_isi_buffer, list);
+
+ list_del(&buf->list);
+ if (buf->discard)
+ continue;
+
+ vb2_buffer_done(&buf->v4l2_buf.vb2_buf, VB2_BUF_STATE_ERROR);
+ }
+
+ while (!list_empty(&mxc_isi->isi_cap.out_pending)) {
+ buf = list_entry(mxc_isi->isi_cap.out_pending.next, struct mxc_isi_buffer, list);
+
+ list_del(&buf->list);
+ vb2_buffer_done(&buf->v4l2_buf.vb2_buf, VB2_BUF_STATE_ERROR);
+ }
+
+ while (!list_empty(&mxc_isi->isi_cap.out_discard)) {
+ buf = list_entry(mxc_isi->isi_cap.out_discard.next, struct mxc_isi_buffer, list);
+ list_del(&buf->list);
+ }
+
+ list_for_each_entry_safe(buf, tmp,
+ &mxc_isi->isi_cap.out_active, list) {
+ list_del(&buf->list);
+ vb2_buffer_done(&buf->v4l2_buf.vb2_buf, VB2_BUF_STATE_ERROR);
+ }
+
+ list_for_each_entry_safe(buf, tmp,
+ &mxc_isi->isi_cap.out_pending, list) {
+ list_del(&buf->list);
+ vb2_buffer_done(&buf->v4l2_buf.vb2_buf, VB2_BUF_STATE_ERROR);
+ }
+
+ INIT_LIST_HEAD(&mxc_isi->isi_cap.out_active);
+ INIT_LIST_HEAD(&mxc_isi->isi_cap.out_pending);
+ INIT_LIST_HEAD(&mxc_isi->isi_cap.out_discard);
+
+ spin_unlock_irqrestore(&mxc_isi->slock, flags);
+
+ for (i = 0; i < mxc_isi->pix.num_planes; i++)
+ dma_free_coherent(&mxc_isi->pdev->dev,
+ mxc_isi->discard_size[i],
+ mxc_isi->discard_buffer[i],
+ mxc_isi->discard_buffer_dma[i]);
+}
+
+static struct vb2_ops mxc_cap_vb2_qops = {
+ .queue_setup = cap_vb2_queue_setup,
+ .buf_prepare = cap_vb2_buffer_prepare,
+ .buf_queue = cap_vb2_buffer_queue,
+ .wait_prepare = vb2_ops_wait_prepare,
+ .wait_finish = vb2_ops_wait_finish,
+ .start_streaming = cap_vb2_start_streaming,
+ .stop_streaming = cap_vb2_stop_streaming,
+};
+
+/*
+ * V4L2 controls handling
+ */
+#define ctrl_to_mxc_isi(__ctrl) \
+ container_of((__ctrl)->handler, struct mxc_isi_dev, ctrls.handler)
+
+static int mxc_isi_s_ctrl(struct v4l2_ctrl *ctrl)
+{
+ struct mxc_isi_dev *mxc_isi = ctrl_to_mxc_isi(ctrl);
+ unsigned long flags;
+
+ dev_dbg(&mxc_isi->pdev->dev, "%s\n", __func__);
+
+ if (ctrl->flags & V4L2_CTRL_FLAG_INACTIVE)
+ return 0;
+
+ spin_lock_irqsave(&mxc_isi->slock, flags);
+
+ switch (ctrl->id) {
+ case V4L2_CID_HFLIP:
+ if (ctrl->val < 0)
+ return -EINVAL;
+ mxc_isi->hflip = (ctrl->val > 0) ? 1 : 0;
+ break;
+
+ case V4L2_CID_VFLIP:
+ if (ctrl->val < 0)
+ return -EINVAL;
+ mxc_isi->vflip = (ctrl->val > 0) ? 1 : 0;
+ break;
+
+ case V4L2_CID_ALPHA_COMPONENT:
+ if (ctrl->val < 0 || ctrl->val > 255)
+ return -EINVAL;
+ mxc_isi->alpha = ctrl->val;
+ mxc_isi->alphaen = 1;
+ break;
+
+ default:
+ dev_err(&mxc_isi->pdev->dev, "%s: Not support %d CID\n", __func__, ctrl->id);
+ return -EINVAL;
+ }
+
+ spin_unlock_irqrestore(&mxc_isi->slock, flags);
+
+ return 0;
+}
+
+static const struct v4l2_ctrl_ops mxc_isi_ctrl_ops = {
+ .s_ctrl = mxc_isi_s_ctrl,
+};
+
+int mxc_isi_ctrls_create(struct mxc_isi_dev *mxc_isi)
+{
+ struct mxc_isi_ctrls *ctrls = &mxc_isi->ctrls;
+ struct v4l2_ctrl_handler *handler = &ctrls->handler;
+
+ if (mxc_isi->ctrls.ready)
+ return 0;
+
+ v4l2_ctrl_handler_init(handler, 4);
+
+ ctrls->hflip = v4l2_ctrl_new_std(handler, &mxc_isi_ctrl_ops,
+ V4L2_CID_HFLIP, 0, 1, 1, 0);
+ ctrls->vflip = v4l2_ctrl_new_std(handler, &mxc_isi_ctrl_ops,
+ V4L2_CID_VFLIP, 0, 1, 1, 0);
+
+ ctrls->alpha = v4l2_ctrl_new_std(handler, &mxc_isi_ctrl_ops,
+ V4L2_CID_ALPHA_COMPONENT, 0, 0xff, 1, 0);
+
+ if (!handler->error)
+ ctrls->ready = true;
+
+ return handler->error;
+}
+
+void mxc_isi_ctrls_delete(struct mxc_isi_dev *mxc_isi)
+{
+ struct mxc_isi_ctrls *ctrls = &mxc_isi->ctrls;
+
+ if (ctrls->ready) {
+ v4l2_ctrl_handler_free(&ctrls->handler);
+ ctrls->ready = false;
+ ctrls->alpha = NULL;
+ }
+}
+
+static struct media_pad *mxc_isi_get_remote_source_pad(struct mxc_isi_dev *mxc_isi)
+{
+ struct mxc_isi_cap_dev *isi_cap = &mxc_isi->isi_cap;
+ struct v4l2_subdev *subdev = &isi_cap->sd;
+ struct media_pad *sink_pad, *source_pad;
+ int i;
+
+ while (1) {
+ source_pad = NULL;
+ for (i = 0; i < subdev->entity.num_pads; i++) {
+ sink_pad = &subdev->entity.pads[i];
+
+ if (sink_pad->flags & MEDIA_PAD_FL_SINK) {
+ source_pad = media_entity_remote_pad(sink_pad);
+ if (source_pad)
+ break;
+ }
+ }
+ /* return first pad point in the loop */
+ return source_pad;
+ }
+
+ if (i == subdev->entity.num_pads)
+ v4l2_err(mxc_isi->v4l2_dev, "%s, No remote pad found!\n", __func__);
+
+ return NULL;
+}
+
+static int mxc_isi_capture_open(struct file *file)
+{
+ struct mxc_isi_dev *mxc_isi = video_drvdata(file);
+ struct media_pad *source_pad;
+ struct v4l2_subdev *sd;
+ struct device *dev = &mxc_isi->pdev->dev;
+ int ret = -EBUSY;
+
+ dev_dbg(&mxc_isi->pdev->dev, "%s, ISI%d\n", __func__, mxc_isi->id);
+
+ if (mxc_isi->is_m2m) {
+ v4l2_err(mxc_isi->v4l2_dev, "%s: ISI channel[%d] is busy\n",
+ __func__, mxc_isi->id);
+ return -EBUSY;
+ }
+ atomic_inc(&mxc_isi->open_count);
+ mxc_isi->is_m2m = 0;
+
+ /* Get remote source pad */
+ source_pad = mxc_isi_get_remote_source_pad(mxc_isi);
+ if (source_pad == NULL) {
+ v4l2_err(mxc_isi->v4l2_dev, "%s, No remote pad found!\n", __func__);
+ goto fail;
+ }
+
+ /* Get remote source pad subdev */
+ sd = media_entity_to_v4l2_subdev(source_pad->entity);
+ if (sd == NULL) {
+ v4l2_err(mxc_isi->v4l2_dev, "%s, No remote subdev found!\n", __func__);
+ goto fail;
+ }
+
+ mutex_lock(&mxc_isi->lock);
+ ret = v4l2_fh_open(file);
+ mutex_unlock(&mxc_isi->lock);
+
+ pm_runtime_get_sync(dev);
+
+ ret = v4l2_subdev_call(sd, core, s_power, 1);
+ if (ret) {
+ v4l2_err(mxc_isi->v4l2_dev, "%s, Call subdev s_power fail!\n", __func__);
+ pm_runtime_put(dev);
+ goto fail;
+ }
+
+ return 0;
+
+fail:
+ atomic_dec(&mxc_isi->open_count);
+ return -EINVAL;
+}
+
+static int mxc_isi_capture_release(struct file *file)
+{
+ struct mxc_isi_dev *mxc_isi = video_drvdata(file);
+ struct media_pad *source_pad;
+ struct v4l2_subdev *sd;
+ struct device *dev = &mxc_isi->pdev->dev;
+ int ret;
+
+ dev_dbg(&mxc_isi->pdev->dev, "%s\n", __func__);
+
+ /* Get remote source pad */
+ source_pad = mxc_isi_get_remote_source_pad(mxc_isi);
+ if (source_pad == NULL) {
+ v4l2_err(mxc_isi->v4l2_dev, "%s, No remote pad found!\n", __func__);
+ ret = -EINVAL;
+ goto label;
+ }
+
+ /* Get remote source pad subdev */
+ sd = media_entity_to_v4l2_subdev(source_pad->entity);
+ if (sd == NULL) {
+ v4l2_err(mxc_isi->v4l2_dev, "%s, No remote subdev found!\n", __func__);
+ ret = -EINVAL;
+ goto label;
+ }
+
+ mutex_lock(&mxc_isi->lock);
+ ret = _vb2_fop_release(file, NULL);
+ if (ret) {
+ v4l2_err(mxc_isi->v4l2_dev, "%s fail\n", __func__);
+ mutex_unlock(&mxc_isi->lock);
+ goto label;
+ }
+ mutex_unlock(&mxc_isi->lock);
+
+ if (atomic_read(&mxc_isi->open_count) > 0 &&
+ atomic_dec_and_test(&mxc_isi->open_count))
+ mxc_isi_channel_deinit(mxc_isi);
+
+ ret = v4l2_subdev_call(sd, core, s_power, 0);
+ if (ret < 0 && ret != -ENOIOCTLCMD) {
+ v4l2_err(mxc_isi->v4l2_dev, "%s s_power fail\n", __func__);
+ goto label;
+ }
+
+label:
+ pm_runtime_put(dev);
+ return (ret) ? ret : 0;
+}
+
+static const struct v4l2_file_operations mxc_isi_capture_fops = {
+ .owner = THIS_MODULE,
+ .open = mxc_isi_capture_open,
+ .release = mxc_isi_capture_release,
+ .poll = vb2_fop_poll,
+ .unlocked_ioctl = video_ioctl2,
+ .mmap = vb2_fop_mmap,
+};
+
+/*
+ * Format and crop negotiation helpers
+ */
+
+/*
+ * The video node ioctl operations
+ */
+static int mxc_isi_cap_querycap(struct file *file, void *priv,
+ struct v4l2_capability *cap)
+{
+ struct mxc_isi_dev *mxc_isi = video_drvdata(file);
+
+ strlcpy(cap->driver, MXC_ISI_DRIVER_NAME, sizeof(cap->driver));
+ strlcpy(cap->card, MXC_ISI_DRIVER_NAME, sizeof(cap->card));
+ snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s.%d",
+ dev_name(&mxc_isi->pdev->dev), mxc_isi->id);
+
+ cap->device_caps = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_CAPTURE_MPLANE;
+ cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
+
+ return 0;
+}
+
+static int mxc_isi_cap_enum_fmt_mplane(struct file *file, void *priv,
+ struct v4l2_fmtdesc *f)
+{
+ struct mxc_isi_dev *mxc_isi = video_drvdata(file);
+ struct mxc_isi_fmt *fmt;
+
+ dev_dbg(&mxc_isi->pdev->dev, "%s\n", __func__);
+ if (f->index >= (int)ARRAY_SIZE(mxc_isi_out_formats))
+ return -EINVAL;
+
+ fmt = &mxc_isi_out_formats[f->index];
+ strncpy(f->description, fmt->name, sizeof(f->description) - 1);
+
+ f->pixelformat = fmt->fourcc;
+
+ return 0;
+}
+
+static int mxc_isi_cap_g_fmt_mplane(struct file *file, void *fh,
+ struct v4l2_format *f)
+{
+ struct mxc_isi_dev *mxc_isi = video_drvdata(file);
+ struct v4l2_pix_format_mplane *pix = &f->fmt.pix_mp;
+ struct mxc_isi_frame *dst_f = &mxc_isi->isi_cap.dst_f;
+ int i;
+
+ dev_dbg(&mxc_isi->pdev->dev, "%s\n", __func__);
+
+ pix->width = dst_f->o_width;
+ pix->height = dst_f->o_height;
+ pix->field = V4L2_FIELD_NONE;
+ pix->pixelformat = dst_f->fmt->fourcc;
+ pix->colorspace = V4L2_COLORSPACE_JPEG;
+ pix->num_planes = dst_f->fmt->memplanes;
+
+ for (i = 0; i < pix->num_planes; ++i) {
+ pix->plane_fmt[i].bytesperline = dst_f->bytesperline[i];
+ pix->plane_fmt[i].sizeimage = dst_f->sizeimage[i];
+ }
+
+ return 0;
+}
+
+
+static int mxc_isi_cap_try_fmt_mplane(struct file *file, void *fh,
+ struct v4l2_format *f)
+{
+ struct mxc_isi_dev *mxc_isi = video_drvdata(file);
+ struct v4l2_pix_format_mplane *pix = &f->fmt.pix_mp;
+ struct mxc_isi_fmt *fmt;
+ int i;
+
+ dev_dbg(&mxc_isi->pdev->dev, "%s\n", __func__);
+
+ for (i = 0; i < ARRAY_SIZE(mxc_isi_out_formats); i++) {
+ fmt = &mxc_isi_out_formats[i];
+ if (fmt->fourcc == pix->pixelformat)
+ break;
+ }
+ if (i >= ARRAY_SIZE(mxc_isi_out_formats)) {
+ v4l2_err(mxc_isi->v4l2_dev, "%s, format is not support!\n", __func__);
+ return -EINVAL;
+ }
+
+ if (pix->width <= 0 || pix->height <= 0) {
+ v4l2_err(mxc_isi->v4l2_dev, "%s, width %d, height %d is not valid\n"
+ , __func__, pix->width, pix->height);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+/* Update input frame size and formate */
+static int mxc_isi_source_fmt_init(struct mxc_isi_dev *mxc_isi)
+{
+ struct mxc_isi_frame *src_f = &mxc_isi->isi_cap.src_f;
+ struct mxc_isi_frame *dst_f = &mxc_isi->isi_cap.dst_f;
+ struct v4l2_subdev_format src_fmt;
+ struct media_pad *source_pad;
+ struct v4l2_subdev *src_sd;
+ int ret;
+
+ /* Get remote source pad */
+ source_pad = mxc_isi_get_remote_source_pad(mxc_isi);
+ if (source_pad == NULL) {
+ v4l2_err(mxc_isi->v4l2_dev, "%s, No remote pad found!\n", __func__);
+ return -EINVAL;
+ }
+
+ /* Get remote source pad subdev */
+ src_sd = media_entity_to_v4l2_subdev(source_pad->entity);
+ if (src_sd == NULL) {
+ v4l2_err(mxc_isi->v4l2_dev, "%s, No remote subdev found!\n", __func__);
+ return -EINVAL;
+ }
+
+ src_fmt.pad = source_pad->index;
+ src_fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
+ src_fmt.format.width = dst_f->width;
+ src_fmt.format.height = dst_f->height;
+ ret = v4l2_subdev_call(src_sd, pad, set_fmt, NULL, &src_fmt);
+ if (ret < 0 && ret != -ENOIOCTLCMD) {
+ v4l2_err(mxc_isi->v4l2_dev, "%s, set remote fmt fail!\n", __func__);
+ return -EINVAL;
+ }
+
+ memset(&src_fmt, 0, sizeof(src_fmt));
+ src_fmt.pad = source_pad->index;
+ src_fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
+ ret = v4l2_subdev_call(src_sd, pad, get_fmt, NULL, &src_fmt);
+ if (ret < 0 && ret != -ENOIOCTLCMD) {
+ v4l2_err(mxc_isi->v4l2_dev, "%s, get remote fmt fail!\n", __func__);
+ return -EINVAL;
+ }
+
+ /* Pixel link master will transfer format to RGB32 or YUV32 */
+ src_f->fmt = mxc_isi_get_src_fmt(&src_fmt);
+
+ set_frame_bounds(src_f, src_fmt.format.width, src_fmt.format.height);
+
+ if (dst_f->width > src_f->width || dst_f->height > src_f->height) {
+ dev_err(&mxc_isi->pdev->dev,
+ "%s: src:(%d,%d), dst:(%d,%d) Not support upscale\n", __func__,
+ src_f->width, src_f->height,
+ dst_f->width, dst_f->height);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int mxc_isi_cap_s_fmt_mplane(struct file *file, void *priv,
+ struct v4l2_format *f)
+{
+ struct mxc_isi_dev *mxc_isi = video_drvdata(file);
+ struct v4l2_pix_format_mplane *pix = &f->fmt.pix_mp;
+ struct mxc_isi_frame *dst_f = &mxc_isi->isi_cap.dst_f;
+ struct mxc_isi_fmt *fmt;
+ int bpl;
+ int i;
+
+ /* Step1: Check format with output support format list.
+ * Step2: Update output frame information.
+ * Step3: Checkout the format whether is supported by remote subdev
+ * Step3.1: If Yes, call remote subdev set_fmt.
+ * Step3.2: If NO, call remote subdev get_fmt.
+ * Step4: Update input frame information.
+ * Step5: Update mxc isi channel configuration.
+ * */
+
+ dev_dbg(&mxc_isi->pdev->dev, "%s, fmt=0x%X\n", __func__, pix->pixelformat);
+ if (vb2_is_busy(&mxc_isi->isi_cap.vb2_q)) {
+ return -EBUSY;
+ }
+
+ /* Check out put format */
+ for (i = 0; i < ARRAY_SIZE(mxc_isi_out_formats); i++) {
+ fmt = &mxc_isi_out_formats[i];
+ if (pix && fmt->fourcc == pix->pixelformat)
+ break;
+ }
+
+ if (i >= ARRAY_SIZE(mxc_isi_out_formats)) {
+ dev_dbg(&mxc_isi->pdev->dev, "%s, format is not support!\n", __func__);
+ return -EINVAL;
+ }
+
+ /* update out put frame size and formate */
+ if (pix->height <= 0 || pix->width <= 0)
+ return -EINVAL;
+
+ dst_f->fmt = fmt;
+ dst_f->height = pix->height;
+ dst_f->width = pix->width;
+
+ pix->num_planes = fmt->memplanes;
+
+ for (i = 0; i < pix->num_planes; i++) {
+ bpl = pix->plane_fmt[i].bytesperline;
+
+ if ((bpl == 0) || (bpl / (fmt->depth[i] >> 3)) < pix->width)
+ pix->plane_fmt[i].bytesperline =
+ (pix->width * fmt->depth[i]) >> 3;
+
+ if (pix->plane_fmt[i].sizeimage == 0) {
+
+ if ((i == 1) && (pix->pixelformat == V4L2_PIX_FMT_NV12))
+ pix->plane_fmt[i].sizeimage =
+ (pix->width * (pix->height >> 1) * fmt->depth[i] >> 3);
+ else
+ pix->plane_fmt[i].sizeimage = (pix->width * pix->height *
+ fmt->depth[i] >> 3);
+ }
+ }
+
+ if (pix->num_planes > 1) {
+ for (i = 0; i < pix->num_planes; i++) {
+ dst_f->bytesperline[i] = pix->plane_fmt[i].bytesperline;
+ dst_f->sizeimage[i] = pix->plane_fmt[i].sizeimage;
+ }
+ } else {
+ dst_f->bytesperline[0] = dst_f->width * dst_f->fmt->depth[0] / 8;
+ dst_f->sizeimage[0] = dst_f->height * dst_f->bytesperline[0];
+ }
+
+ memcpy(&mxc_isi->pix, pix, sizeof(*pix));
+
+ set_frame_bounds(dst_f, pix->width, pix->height);
+
+ return 0;
+}
+
+static int mxc_isi_config_parm(struct mxc_isi_dev *mxc_isi)
+{
+ int ret;
+
+ ret = mxc_isi_source_fmt_init(mxc_isi);
+ if (ret < 0)
+ return -EINVAL;
+
+ mxc_isi_channel_init(mxc_isi);
+ mxc_isi_channel_config(mxc_isi);
+
+ return 0;
+}
+
+static int mxc_isi_cap_streamon(struct file *file, void *priv,
+ enum v4l2_buf_type type)
+{
+ struct mxc_isi_dev *mxc_isi = video_drvdata(file);
+ int ret;
+
+ dev_dbg(&mxc_isi->pdev->dev, "%s\n", __func__);
+
+ ret = mxc_isi_config_parm(mxc_isi);
+ if (ret < 0)
+ return -EINVAL;
+
+ ret = vb2_ioctl_streamon(file, priv, type);
+ mxc_isi_channel_enable(mxc_isi);
+ mxc_isi_pipeline_enable(mxc_isi, 1);
+
+ mxc_isi->is_streaming = 1;
+
+ return ret;
+}
+
+static int mxc_isi_cap_streamoff(struct file *file, void *priv,
+ enum v4l2_buf_type type)
+{
+ struct mxc_isi_dev *mxc_isi = video_drvdata(file);
+ int ret;
+
+ dev_dbg(&mxc_isi->pdev->dev, "%s\n", __func__);
+
+ mxc_isi_pipeline_enable(mxc_isi, 0);
+ mxc_isi_channel_disable(mxc_isi);
+ ret = vb2_ioctl_streamoff(file, priv, type);
+
+ mxc_isi->is_streaming = 0;
+
+ return ret;
+}
+
+static int mxc_isi_cap_g_selection(struct file *file, void *fh,
+ struct v4l2_selection *s)
+{
+ struct mxc_isi_dev *mxc_isi = video_drvdata(file);
+ struct mxc_isi_frame *f = &mxc_isi->isi_cap.src_f;
+
+ dev_dbg(&mxc_isi->pdev->dev, "%s\n", __func__);
+
+ if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
+ return -EINVAL;
+
+ switch (s->target) {
+ case V4L2_SEL_TGT_COMPOSE_DEFAULT:
+ case V4L2_SEL_TGT_COMPOSE_BOUNDS:
+ f = &mxc_isi->isi_cap.dst_f;
+ case V4L2_SEL_TGT_CROP_BOUNDS:
+ case V4L2_SEL_TGT_CROP_DEFAULT:
+ s->r.left = 0;
+ s->r.top = 0;
+ s->r.width = f->o_width;
+ s->r.height = f->o_height;
+ return 0;
+
+ case V4L2_SEL_TGT_COMPOSE:
+ f = &mxc_isi->isi_cap.dst_f;
+ case V4L2_SEL_TGT_CROP:
+ s->r.left = f->h_off;
+ s->r.top = f->v_off;
+ s->r.width = f->width;
+ s->r.height = f->height;
+ return 0;
+ }
+
+ return -EINVAL;
+}
+
+static int enclosed_rectangle(struct v4l2_rect *a, struct v4l2_rect *b)
+{
+ if (a->left < b->left || a->top < b->top)
+ return 0;
+
+ if (a->left + a->width > b->left + b->width)
+ return 0;
+
+ if (a->top + a->height > b->top + b->height)
+ return 0;
+
+ return 1;
+}
+static int mxc_isi_cap_s_selection(struct file *file, void *fh,
+ struct v4l2_selection *s)
+{
+ struct mxc_isi_dev *mxc_isi = video_drvdata(file);
+ struct mxc_isi_frame *f;
+ struct v4l2_rect rect = s->r;
+ unsigned long flags;
+
+ dev_dbg(&mxc_isi->pdev->dev, "%s\n", __func__);
+ if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
+ return -EINVAL;
+
+ if (s->target == V4L2_SEL_TGT_COMPOSE)
+ f = &mxc_isi->isi_cap.dst_f;
+ else if (s->target == V4L2_SEL_TGT_CROP)
+ f = &mxc_isi->isi_cap.src_f;
+ else
+ return -EINVAL;
+
+ if (s->flags & V4L2_SEL_FLAG_LE &&
+ !enclosed_rectangle(&rect, &s->r))
+ return -ERANGE;
+
+ if (s->flags & V4L2_SEL_FLAG_GE &&
+ !enclosed_rectangle(&s->r, &rect))
+ return -ERANGE;
+
+ s->r = rect;
+ spin_lock_irqsave(&mxc_isi->slock, flags);
+ set_frame_crop(f, s->r.left, s->r.top, s->r.width,
+ s->r.height);
+ spin_unlock_irqrestore(&mxc_isi->slock, flags);
+
+ return 0;
+}
+
+static int mxc_isi_cap_g_chip_ident(struct file *file, void *fb,
+ struct v4l2_dbg_chip_ident *chip)
+{
+ struct device_node *local, *remote, *endpoint;
+ struct mxc_isi_dev *mxc_isi = video_drvdata(file);
+ struct video_device *vdev = video_devdata(file);
+ struct v4l2_subdev *sd;
+ struct media_pad *source_pad;
+
+ source_pad = mxc_isi_get_remote_source_pad(mxc_isi);
+ if (source_pad == NULL) {
+ v4l2_err(mxc_isi->v4l2_dev, "%s, No remote pad found!\n", __func__);
+ return -EINVAL;
+ }
+
+ /* Get remote source pad subdev */
+ sd = media_entity_to_v4l2_subdev(source_pad->entity);
+ if (sd == NULL) {
+ v4l2_err(mxc_isi->v4l2_dev, "%s, No remote subdev found!\n", __func__);
+ return -EINVAL;
+ }
+
+ local = dev_of_node(sd->dev);
+ if (!local) {
+ v4l2_err(mxc_isi->v4l2_dev, "%s, Get device node fail\n", __func__);
+ return -ENODEV;
+ }
+
+ endpoint = of_graph_get_endpoint_by_regs(local, -1, -1);
+ if (!endpoint) {
+ v4l2_err(mxc_isi->v4l2_dev, "%s, No %s endpoint\n",
+ __func__, local->name);
+ return -ENODEV;
+ }
+
+ remote = of_graph_get_remote_port_parent(endpoint);
+ if (!remote) {
+ v4l2_err(mxc_isi->v4l2_dev, "%s No remote port for %s\n",
+ __func__, endpoint->name);
+ return -ENODEV;
+ }
+
+ sprintf(chip->match.name, "imx8_%s_%d", remote->name, vdev->num);
+
+ return 0;
+}
+
+static int mxc_isi_cap_g_parm(struct file *file, void *fh,
+ struct v4l2_streamparm *a)
+{
+ struct mxc_isi_dev *mxc_isi = video_drvdata(file);
+ struct v4l2_subdev *sd;
+ struct media_pad *source_pad;
+
+ source_pad = mxc_isi_get_remote_source_pad(mxc_isi);
+ if (source_pad == NULL) {
+ v4l2_err(mxc_isi->v4l2_dev, "%s, No remote pad found!\n", __func__);
+ return -EINVAL;
+ }
+
+ /* Get remote source pad subdev */
+ sd = media_entity_to_v4l2_subdev(source_pad->entity);
+ if (sd == NULL) {
+ v4l2_err(mxc_isi->v4l2_dev, "%s, No remote subdev found!\n", __func__);
+ return -EINVAL;
+ }
+ return v4l2_subdev_call(sd, video, g_parm, a);
+}
+
+static int mxc_isi_cap_s_parm(struct file *file, void *fh,
+ struct v4l2_streamparm *a)
+{
+ struct mxc_isi_dev *mxc_isi = video_drvdata(file);
+ struct v4l2_subdev *sd;
+ struct media_pad *source_pad;
+
+ source_pad = mxc_isi_get_remote_source_pad(mxc_isi);
+ if (source_pad == NULL) {
+ v4l2_err(mxc_isi->v4l2_dev, "%s, No remote pad found!\n", __func__);
+ return -EINVAL;
+ }
+
+ /* Get remote source pad subdev */
+ sd = media_entity_to_v4l2_subdev(source_pad->entity);
+ if (sd == NULL) {
+ v4l2_err(mxc_isi->v4l2_dev, "%s, No remote subdev found!\n", __func__);
+ return -EINVAL;
+ }
+ return v4l2_subdev_call(sd, video, s_parm, a);
+}
+
+static int mxc_isi_cap_enum_framesizes(struct file *file, void *priv,
+ struct v4l2_frmsizeenum *fsize)
+{
+ struct mxc_isi_dev *mxc_isi = video_drvdata(file);
+ struct v4l2_subdev *sd;
+ struct mxc_isi_fmt *fmt;
+ struct media_pad *source_pad;
+ struct v4l2_subdev_frame_size_enum fse = {
+ .index = fsize->index,
+ .which = V4L2_SUBDEV_FORMAT_ACTIVE,
+ };
+ int ret;
+
+ fmt = mxc_isi_find_format(&fsize->pixel_format, NULL, 0);
+ if (!fmt || fmt->fourcc != fsize->pixel_format)
+ return -EINVAL;
+ fse.code = fmt->mbus_code;
+
+ source_pad = mxc_isi_get_remote_source_pad(mxc_isi);
+ if (source_pad == NULL) {
+ v4l2_err(mxc_isi->v4l2_dev, "%s, No remote pad found!\n", __func__);
+ return -EINVAL;
+ }
+
+ /* Get remote source pad subdev */
+ sd = media_entity_to_v4l2_subdev(source_pad->entity);
+ if (sd == NULL) {
+ v4l2_err(mxc_isi->v4l2_dev, "%s, No remote subdev found!\n", __func__);
+ return -EINVAL;
+ }
+
+ if (sd == NULL) {
+ v4l2_err(&mxc_isi->isi_cap.sd, "Can't find subdev\n");
+ return -ENODEV;
+ }
+
+ ret = v4l2_subdev_call(sd, pad, enum_frame_size, NULL, &fse);
+ if (ret)
+ return ret;
+
+ if (fse.min_width == fse.max_width &&
+ fse.min_height == fse.max_height) {
+ fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
+ fsize->discrete.width = fse.min_width;
+ fsize->discrete.height = fse.min_height;
+ return 0;
+ }
+
+ fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE;
+ fsize->stepwise.min_width = fse.min_width;
+ fsize->stepwise.max_width = fse.max_width;
+ fsize->stepwise.min_height = fse.min_height;
+ fsize->stepwise.max_height = fse.max_height;
+ fsize->stepwise.step_width = 1;
+ fsize->stepwise.step_height = 1;
+
+ return 0;
+}
+
+static int mxc_isi_cap_enum_frameintervals(struct file *file, void *fh,
+ struct v4l2_frmivalenum *interval)
+{
+ struct mxc_isi_dev *mxc_isi = video_drvdata(file);
+ struct v4l2_subdev *sd;
+ struct mxc_isi_fmt *fmt;
+ struct media_pad *source_pad;
+ struct v4l2_subdev_frame_interval_enum fie = {
+ .index = interval->index,
+ .width = interval->width,
+ .height = interval->height,
+ .which = V4L2_SUBDEV_FORMAT_ACTIVE,
+ };
+ int ret;
+
+ fmt = mxc_isi_find_format(&interval->pixel_format, NULL, 0);
+ if (!fmt || fmt->fourcc != interval->pixel_format)
+ return -EINVAL;
+ fie.code = fmt->mbus_code;
+
+ source_pad = mxc_isi_get_remote_source_pad(mxc_isi);
+ if (source_pad == NULL) {
+ v4l2_err(mxc_isi->v4l2_dev, "%s, No remote pad found!\n", __func__);
+ return -EINVAL;
+ }
+
+ /* Get remote source pad subdev */
+ sd = media_entity_to_v4l2_subdev(source_pad->entity);
+ if (sd == NULL) {
+ v4l2_err(mxc_isi->v4l2_dev, "%s, No remote subdev found!\n", __func__);
+ return -EINVAL;
+ }
+
+ ret = v4l2_subdev_call(sd, pad, enum_frame_interval, NULL, &fie);
+ if (ret)
+ return ret;
+
+ interval->type = V4L2_FRMIVAL_TYPE_DISCRETE;
+ interval->discrete = fie.interval;
+
+ return 0;
+}
+
+static const struct v4l2_ioctl_ops mxc_isi_capture_ioctl_ops = {
+ .vidioc_querycap = mxc_isi_cap_querycap,
+
+ .vidioc_enum_fmt_vid_cap_mplane = mxc_isi_cap_enum_fmt_mplane,
+ .vidioc_try_fmt_vid_cap_mplane = mxc_isi_cap_try_fmt_mplane,
+ .vidioc_s_fmt_vid_cap_mplane = mxc_isi_cap_s_fmt_mplane,
+ .vidioc_g_fmt_vid_cap_mplane = mxc_isi_cap_g_fmt_mplane,
+
+ .vidioc_reqbufs = vb2_ioctl_reqbufs,
+ .vidioc_querybuf = vb2_ioctl_querybuf,
+ .vidioc_qbuf = vb2_ioctl_qbuf,
+ .vidioc_dqbuf = vb2_ioctl_dqbuf,
+ .vidioc_expbuf = vb2_ioctl_expbuf,
+ .vidioc_prepare_buf = vb2_ioctl_prepare_buf,
+ .vidioc_create_bufs = vb2_ioctl_create_bufs,
+
+ .vidioc_streamon = mxc_isi_cap_streamon,
+ .vidioc_streamoff = mxc_isi_cap_streamoff,
+
+ .vidioc_g_selection = mxc_isi_cap_g_selection,
+ .vidioc_s_selection = mxc_isi_cap_s_selection,
+ .vidioc_g_chip_ident = mxc_isi_cap_g_chip_ident,
+
+ .vidioc_g_parm = mxc_isi_cap_g_parm,
+ .vidioc_s_parm = mxc_isi_cap_s_parm,
+
+ .vidioc_enum_framesizes = mxc_isi_cap_enum_framesizes,
+ .vidioc_enum_frameintervals = mxc_isi_cap_enum_frameintervals,
+};
+
+/* Capture subdev media entity operations */
+static int mxc_isi_link_setup(struct media_entity *entity,
+ const struct media_pad *local,
+ const struct media_pad *remote, u32 flags)
+{
+ struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity);
+ struct mxc_isi_dev *mxc_isi = v4l2_get_subdevdata(sd);
+
+ if (WARN_ON(mxc_isi == NULL))
+ return 0;
+
+ if (!(flags & MEDIA_LNK_FL_ENABLED)) {
+ return 0;
+ }
+ /* TODO */
+ /* Add ISI source and sink pad link configuration */
+ if (local->flags & MEDIA_PAD_FL_SOURCE) {
+ switch (local->index) {
+ case MXC_ISI_SD_PAD_SOURCE_DC0:
+ case MXC_ISI_SD_PAD_SOURCE_DC1:
+ break;
+ case MXC_ISI_SD_PAD_SOURCE_MEM:
+ break;
+ default:
+ dev_err(&mxc_isi->pdev->dev, "%s invalid source pad\n", __func__);
+ return -EINVAL;
+ }
+ } else if (local->flags & MEDIA_PAD_FL_SINK) {
+ switch (local->index) {
+ case MXC_ISI_SD_PAD_SINK_MIPI0_VC0:
+ case MXC_ISI_SD_PAD_SINK_MIPI0_VC1:
+ case MXC_ISI_SD_PAD_SINK_MIPI0_VC2:
+ case MXC_ISI_SD_PAD_SINK_MIPI0_VC3:
+ case MXC_ISI_SD_PAD_SINK_MIPI1_VC0:
+ case MXC_ISI_SD_PAD_SINK_MIPI1_VC1:
+ case MXC_ISI_SD_PAD_SINK_MIPI1_VC2:
+ case MXC_ISI_SD_PAD_SINK_MIPI1_VC3:
+ case MXC_ISI_SD_PAD_SINK_HDMI:
+ case MXC_ISI_SD_PAD_SINK_DC0:
+ case MXC_ISI_SD_PAD_SINK_DC1:
+ case MXC_ISI_SD_PAD_SINK_MEM:
+ case MXC_ISI_SD_PAD_SINK_PARALLEL_CSI:
+ break;
+ default:
+ dev_err(&mxc_isi->pdev->dev, "%s invalid sink pad\n", __func__);
+ return -EINVAL;
+ }
+ }
+
+ return 0;
+}
+
+static const struct media_entity_operations mxc_isi_sd_media_ops = {
+ .link_setup = mxc_isi_link_setup,
+};
+
+static int mxc_isi_subdev_enum_mbus_code(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_mbus_code_enum *code)
+{
+ return 0;
+}
+
+static int mxc_isi_subdev_get_fmt(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_format *fmt)
+{
+ struct mxc_isi_dev *mxc_isi = v4l2_get_subdevdata(sd);
+ struct mxc_isi_frame *f;
+ struct v4l2_mbus_framefmt *mf;
+
+ mutex_lock(&mxc_isi->lock);
+
+ switch (fmt->pad) {
+ case MXC_ISI_SD_PAD_SOURCE_MEM:
+ case MXC_ISI_SD_PAD_SOURCE_DC0:
+ case MXC_ISI_SD_PAD_SOURCE_DC1:
+ f = &mxc_isi->isi_cap.dst_f;
+ break;
+ case MXC_ISI_SD_PAD_SINK_MIPI0_VC0:
+ case MXC_ISI_SD_PAD_SINK_MIPI0_VC1:
+ case MXC_ISI_SD_PAD_SINK_MIPI0_VC2:
+ case MXC_ISI_SD_PAD_SINK_MIPI0_VC3:
+ case MXC_ISI_SD_PAD_SINK_MIPI1_VC0:
+ case MXC_ISI_SD_PAD_SINK_MIPI1_VC1:
+ case MXC_ISI_SD_PAD_SINK_MIPI1_VC2:
+ case MXC_ISI_SD_PAD_SINK_MIPI1_VC3:
+ case MXC_ISI_SD_PAD_SINK_HDMI:
+ case MXC_ISI_SD_PAD_SINK_DC0:
+ case MXC_ISI_SD_PAD_SINK_DC1:
+ case MXC_ISI_SD_PAD_SINK_MEM:
+ f = &mxc_isi->isi_cap.src_f;
+ break;
+ default:
+ mutex_unlock(&mxc_isi->lock);
+ v4l2_err(mxc_isi->v4l2_dev, "%s, Pad is not support now!\n", __func__);
+ return -1;
+ }
+
+ if (!WARN_ON(f->fmt == NULL))
+ mf->code = f->fmt->mbus_code;
+
+ /* Source/Sink pads crop rectangle size */
+ mf->width = f->width;
+ mf->height = f->height;
+
+ mutex_unlock(&mxc_isi->lock);
+ mf->colorspace = V4L2_COLORSPACE_JPEG;
+
+ return 0;
+}
+
+static int mxc_isi_subdev_set_fmt(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_format *fmt)
+{
+ struct mxc_isi_dev *mxc_isi = v4l2_get_subdevdata(sd);
+ struct v4l2_mbus_framefmt *mf = &fmt->format;
+ struct mxc_isi_frame *dst_f = &mxc_isi->isi_cap.dst_f;
+ struct mxc_isi_fmt *out_fmt;
+ int i;
+
+ if (fmt->pad < MXC_ISI_SD_PAD_SOURCE_MEM &&
+ vb2_is_busy(&mxc_isi->isi_cap.vb2_q))
+ return -EBUSY;
+
+ for (i = 0; i < ARRAY_SIZE(mxc_isi_out_formats); i++) {
+ out_fmt = &mxc_isi_out_formats[i];
+ if (mf->code == out_fmt->mbus_code)
+ break;
+ }
+ if (i >= ARRAY_SIZE(mxc_isi_out_formats)) {
+ v4l2_err(mxc_isi->v4l2_dev, "%s, format is not support!\n", __func__);
+ return -EINVAL;
+ }
+
+ mutex_lock(&mxc_isi->lock);
+ /* update out put frame size and formate */
+ dst_f->fmt = &mxc_isi_out_formats[i];
+ set_frame_bounds(dst_f, mf->width, mf->height);
+ mutex_unlock(&mxc_isi->lock);
+
+ dev_dbg(&mxc_isi->pdev->dev, "pad%d: code: 0x%x, %dx%d",
+ fmt->pad, mf->code, mf->width, mf->height);
+
+ return 0;
+}
+
+static int mxc_isi_subdev_get_selection(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_selection *sel)
+{
+ struct mxc_isi_dev *mxc_isi = v4l2_get_subdevdata(sd);
+ struct mxc_isi_frame *f = &mxc_isi->isi_cap.src_f;
+ struct v4l2_rect *r = &sel->r;
+ struct v4l2_rect *try_sel;
+
+ mutex_lock(&mxc_isi->lock);
+
+ switch (sel->target) {
+ case V4L2_SEL_TGT_COMPOSE_BOUNDS:
+ f = &mxc_isi->isi_cap.dst_f;
+ case V4L2_SEL_TGT_CROP_BOUNDS:
+ r->width = f->o_width;
+ r->height = f->o_height;
+ r->left = 0;
+ r->top = 0;
+ mutex_unlock(&mxc_isi->lock);
+ return 0;
+
+ case V4L2_SEL_TGT_CROP:
+ try_sel = v4l2_subdev_get_try_crop(sd, cfg, sel->pad);
+ break;
+ case V4L2_SEL_TGT_COMPOSE:
+ try_sel = v4l2_subdev_get_try_compose(sd, cfg, sel->pad);
+ f = &mxc_isi->isi_cap.dst_f;
+ break;
+ default:
+ mutex_unlock(&mxc_isi->lock);
+ return -EINVAL;
+ }
+
+ if (sel->which == V4L2_SUBDEV_FORMAT_TRY) {
+ sel->r = *try_sel;
+ } else {
+ r->left = f->h_off;
+ r->top = f->v_off;
+ r->width = f->width;
+ r->height = f->height;
+ }
+
+ dev_dbg(&mxc_isi->pdev->dev, "%s, target %#x: l:%d, t:%d, %dx%d, f_w: %d, f_h: %d",
+ __func__, sel->pad, r->left, r->top, r->width, r->height,
+ f->c_width, f->c_height);
+
+ mutex_unlock(&mxc_isi->lock);
+ return 0;
+}
+
+static int mxc_isi_subdev_set_selection(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_selection *sel)
+{
+ struct mxc_isi_dev *mxc_isi = v4l2_get_subdevdata(sd);
+ struct mxc_isi_frame *f = &mxc_isi->isi_cap.src_f;
+ struct v4l2_rect *r = &sel->r;
+ struct v4l2_rect *try_sel;
+ unsigned long flags;
+
+ mutex_lock(&mxc_isi->lock);
+
+ switch (sel->target) {
+ case V4L2_SEL_TGT_CROP:
+ try_sel = v4l2_subdev_get_try_crop(sd, cfg, sel->pad);
+ break;
+ case V4L2_SEL_TGT_COMPOSE:
+ try_sel = v4l2_subdev_get_try_compose(sd, cfg, sel->pad);
+ f = &mxc_isi->isi_cap.dst_f;
+ break;
+ default:
+ mutex_unlock(&mxc_isi->lock);
+ return -EINVAL;
+ }
+
+ if (sel->which == V4L2_SUBDEV_FORMAT_TRY) {
+ *try_sel = sel->r;
+ } else {
+ spin_lock_irqsave(&mxc_isi->slock, flags);
+ set_frame_crop(f, r->left, r->top, r->width, r->height);
+ spin_unlock_irqrestore(&mxc_isi->slock, flags);
+ }
+
+ dev_dbg(&mxc_isi->pdev->dev, "%s, target %#x: (%d,%d)/%dx%d", __func__,
+ sel->target, r->left, r->top, r->width, r->height);
+
+ mutex_unlock(&mxc_isi->lock);
+
+ return 0;
+}
+
+static struct v4l2_subdev_pad_ops mxc_isi_subdev_pad_ops = {
+ .enum_mbus_code = mxc_isi_subdev_enum_mbus_code,
+ .get_selection = mxc_isi_subdev_get_selection,
+ .set_selection = mxc_isi_subdev_set_selection,
+ .get_fmt = mxc_isi_subdev_get_fmt,
+ .set_fmt = mxc_isi_subdev_set_fmt,
+};
+
+static struct v4l2_subdev_ops mxc_isi_subdev_ops = {
+ .pad = &mxc_isi_subdev_pad_ops,
+};
+
+static int mxc_isi_register_cap_device(struct mxc_isi_dev *mxc_isi,
+ struct v4l2_device *v4l2_dev)
+{
+ struct video_device *vdev = &mxc_isi->isi_cap.vdev;
+ struct vb2_queue *q = &mxc_isi->isi_cap.vb2_q;
+ struct mxc_isi_cap_dev *isi_cap = &mxc_isi->isi_cap;
+ int ret = -ENOMEM;
+
+ dev_dbg(&mxc_isi->pdev->dev, "%s\n", __func__);
+ memset(vdev, 0, sizeof(*vdev));
+ snprintf(vdev->name, sizeof(vdev->name), "mxc_isi.%d.capture", mxc_isi->id);
+
+ vdev->fops = &mxc_isi_capture_fops;
+ vdev->ioctl_ops = &mxc_isi_capture_ioctl_ops;
+ vdev->v4l2_dev = v4l2_dev;
+ vdev->minor = -1;
+ vdev->release = video_device_release_empty;
+ vdev->queue = q;
+ vdev->lock = &mxc_isi->lock;
+
+ video_set_drvdata(vdev, mxc_isi);
+
+ INIT_LIST_HEAD(&mxc_isi->isi_cap.out_pending);
+ INIT_LIST_HEAD(&mxc_isi->isi_cap.out_active);
+ INIT_LIST_HEAD(&mxc_isi->isi_cap.out_discard);
+
+ memset(q, 0, sizeof(*q));
+ q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+ q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF;
+ q->drv_priv = mxc_isi;
+ q->ops = &mxc_cap_vb2_qops;
+ q->mem_ops = &vb2_dma_contig_memops;
+ q->buf_struct_size = sizeof(struct mxc_isi_buffer);
+ q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
+ q->lock = &mxc_isi->lock;
+
+ ret = vb2_queue_init(q);
+ if (ret)
+ goto err_free_ctx;
+
+ /* Default configuration */
+ isi_cap->dst_f.width = 1280;
+ isi_cap->dst_f.height = 800;
+ isi_cap->dst_f.fmt = &mxc_isi_out_formats[0];;
+ isi_cap->src_f.fmt = isi_cap->dst_f.fmt;
+
+ isi_cap->cap_pad.flags = MEDIA_PAD_FL_SINK;
+ vdev->entity.function = MEDIA_ENT_F_PROC_VIDEO_SCALER;
+ ret = media_entity_pads_init(&vdev->entity, 1, &isi_cap->cap_pad);
+ if (ret)
+ goto err_free_ctx;
+
+ ret = mxc_isi_ctrls_create(mxc_isi);
+ if (ret)
+ goto err_me_cleanup;
+
+ ret = video_register_device(vdev, VFL_TYPE_GRABBER, -1);
+ if (ret)
+ goto err_ctrl_free;
+
+ vdev->ctrl_handler = &mxc_isi->ctrls.handler;
+ v4l2_info(v4l2_dev, "Registered %s as /dev/%s\n",
+ vdev->name, video_device_node_name(vdev));
+
+ return 0;
+
+err_ctrl_free:
+ mxc_isi_ctrls_delete(mxc_isi);
+err_me_cleanup:
+ media_entity_cleanup(&vdev->entity);
+err_free_ctx:
+ return ret;
+}
+
+static int mxc_isi_register_cap_and_m2m_device(struct mxc_isi_dev *mxc_isi,
+ struct v4l2_device *v4l2_dev)
+{
+ struct mxc_md *mxc_md = container_of(v4l2_dev, struct mxc_md, v4l2_dev);
+ int ret;
+
+ ret = mxc_isi_register_cap_device(mxc_isi, v4l2_dev);
+ if (ret)
+ return ret;
+
+ /* register m2m at last */
+ if (!(--mxc_md->nr_isi) && mxc_md->mxc_isi[0]) {
+ ret = mxc_isi_register_m2m_device(mxc_md->mxc_isi[0], v4l2_dev);
+ if (ret < 0)
+ return ret;
+ dev_info(&mxc_isi->pdev->dev, "register m2m device success\n");
+ }
+
+ return ret;
+}
+
+static int mxc_isi_subdev_registered(struct v4l2_subdev *sd)
+{
+ struct mxc_isi_dev *mxc_isi = v4l2_get_subdevdata(sd);
+ int ret;
+
+ if (mxc_isi == NULL)
+ return -ENXIO;
+
+ dev_dbg(&mxc_isi->pdev->dev, "%s\n", __func__);
+
+ ret = mxc_isi_register_cap_and_m2m_device(mxc_isi, sd->v4l2_dev);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
+static void mxc_isi_subdev_unregistered(struct v4l2_subdev *sd)
+{
+ struct mxc_isi_dev *mxc_isi = v4l2_get_subdevdata(sd);
+ struct video_device *vdev;
+
+ if (mxc_isi == NULL)
+ return;
+
+ dev_dbg(&mxc_isi->pdev->dev, "%s\n", __func__);
+ mutex_lock(&mxc_isi->lock);
+
+ if (mxc_isi->id == 0 && mxc_isi->skip_m2m == 0)
+ mxc_isi_unregister_m2m_device(mxc_isi);
+
+ vdev = &mxc_isi->isi_cap.vdev;
+ if (video_is_registered(vdev)) {
+ video_unregister_device(vdev);
+ mxc_isi_ctrls_delete(mxc_isi);
+ media_entity_cleanup(&vdev->entity);
+ }
+
+ mutex_unlock(&mxc_isi->lock);
+}
+
+static const struct v4l2_subdev_internal_ops mxc_isi_capture_sd_internal_ops = {
+ .registered = mxc_isi_subdev_registered,
+ .unregistered = mxc_isi_subdev_unregistered,
+};
+
+int mxc_isi_initialize_capture_subdev(struct mxc_isi_dev *mxc_isi)
+{
+ struct v4l2_subdev *sd = &mxc_isi->isi_cap.sd;
+ int ret;
+
+ v4l2_subdev_init(sd, &mxc_isi_subdev_ops);
+ sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+ snprintf(sd->name, sizeof(sd->name), "mxc_isi.%d", mxc_isi->id);
+
+ sd->entity.function = MEDIA_ENT_F_PROC_VIDEO_PIXEL_FORMATTER;
+
+ /* ISI Sink pads */
+ mxc_isi->isi_cap.sd_pads[MXC_ISI_SD_PAD_SINK_MIPI0_VC0].flags = MEDIA_PAD_FL_SINK;
+ mxc_isi->isi_cap.sd_pads[MXC_ISI_SD_PAD_SINK_MIPI0_VC1].flags = MEDIA_PAD_FL_SINK;
+ mxc_isi->isi_cap.sd_pads[MXC_ISI_SD_PAD_SINK_MIPI0_VC2].flags = MEDIA_PAD_FL_SINK;
+ mxc_isi->isi_cap.sd_pads[MXC_ISI_SD_PAD_SINK_MIPI0_VC3].flags = MEDIA_PAD_FL_SINK;
+ mxc_isi->isi_cap.sd_pads[MXC_ISI_SD_PAD_SINK_MIPI1_VC0].flags = MEDIA_PAD_FL_SINK;
+ mxc_isi->isi_cap.sd_pads[MXC_ISI_SD_PAD_SINK_MIPI1_VC1].flags = MEDIA_PAD_FL_SINK;
+ mxc_isi->isi_cap.sd_pads[MXC_ISI_SD_PAD_SINK_MIPI1_VC2].flags = MEDIA_PAD_FL_SINK;
+ mxc_isi->isi_cap.sd_pads[MXC_ISI_SD_PAD_SINK_MIPI1_VC3].flags = MEDIA_PAD_FL_SINK;
+ mxc_isi->isi_cap.sd_pads[MXC_ISI_SD_PAD_SINK_DC0].flags = MEDIA_PAD_FL_SINK;
+ mxc_isi->isi_cap.sd_pads[MXC_ISI_SD_PAD_SINK_DC1].flags = MEDIA_PAD_FL_SINK;
+ mxc_isi->isi_cap.sd_pads[MXC_ISI_SD_PAD_SINK_HDMI].flags = MEDIA_PAD_FL_SINK;
+ mxc_isi->isi_cap.sd_pads[MXC_ISI_SD_PAD_SINK_MEM].flags = MEDIA_PAD_FL_SINK;
+ mxc_isi->isi_cap.sd_pads[MXC_ISI_SD_PAD_SINK_PARALLEL_CSI].flags = MEDIA_PAD_FL_SINK;
+
+ /* ISI source pads */
+ mxc_isi->isi_cap.sd_pads[MXC_ISI_SD_PAD_SOURCE_MEM].flags = MEDIA_PAD_FL_SOURCE;
+ mxc_isi->isi_cap.sd_pads[MXC_ISI_SD_PAD_SOURCE_DC0].flags = MEDIA_PAD_FL_SOURCE;
+ mxc_isi->isi_cap.sd_pads[MXC_ISI_SD_PAD_SOURCE_DC1].flags = MEDIA_PAD_FL_SOURCE;
+
+ ret = media_entity_pads_init(&sd->entity, MXC_ISI_SD_PADS_NUM,
+ mxc_isi->isi_cap.sd_pads);
+ if (ret)
+ return ret;
+
+ sd->entity.ops = &mxc_isi_sd_media_ops;
+ sd->internal_ops = &mxc_isi_capture_sd_internal_ops;
+ v4l2_set_subdevdata(sd, mxc_isi);
+
+ return 0;
+}
+
+void mxc_isi_unregister_capture_subdev(struct mxc_isi_dev *mxc_isi)
+{
+ struct v4l2_subdev *sd = &mxc_isi->isi_cap.sd;
+
+ v4l2_device_unregister_subdev(sd);
+ media_entity_cleanup(&sd->entity);
+ v4l2_set_subdevdata(sd, NULL);
+}
diff --git a/drivers/media/platform/imx8/mxc-isi-core.c b/drivers/media/platform/imx8/mxc-isi-core.c
new file mode 100644
index 000000000000..ae9daf9d98e4
--- /dev/null
+++ b/drivers/media/platform/imx8/mxc-isi-core.c
@@ -0,0 +1,281 @@
+/*
+ * Copyright 2017-2018 NXP
+ */
+/*
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+#include "mxc-media-dev.h"
+
+static irqreturn_t mxc_isi_irq_handler(int irq, void *priv)
+{
+ struct mxc_isi_dev *mxc_isi = priv;
+ struct device *dev = &mxc_isi->pdev->dev;
+ u32 status;
+
+ spin_lock(&mxc_isi->slock);
+
+ status = mxc_isi_get_irq_status(mxc_isi);
+ mxc_isi_clean_irq_status(mxc_isi, status);
+
+ if (status & CHNL_STS_FRM_STRD_MASK) {
+ if (mxc_isi->is_m2m)
+ mxc_isi_m2m_frame_write_done(mxc_isi);
+ else
+ mxc_isi_cap_frame_write_done(mxc_isi);
+ }
+
+ if (status & (CHNL_STS_AXI_WR_ERR_Y_MASK |
+ CHNL_STS_AXI_WR_ERR_U_MASK |
+ CHNL_STS_AXI_WR_ERR_V_MASK))
+ dev_dbg(dev, "%s, IRQ AXI Error stat=0x%X\n", __func__, status);
+ if (status & (CHNL_STS_OFLW_PANIC_Y_BUF_MASK |
+ CHNL_STS_OFLW_PANIC_U_BUF_MASK |
+ CHNL_STS_OFLW_PANIC_V_BUF_MASK))
+ dev_dbg(dev, "%s, IRQ Panic OFLW Error stat=0x%X\n", __func__, status);
+ if (status & (CHNL_STS_OFLW_Y_BUF_MASK |
+ CHNL_STS_OFLW_U_BUF_MASK |
+ CHNL_STS_OFLW_V_BUF_MASK))
+ dev_dbg(dev, "%s, IRQ OFLW Error stat=0x%X\n", __func__, status);
+ if (status & (CHNL_STS_EXCS_OFLW_Y_BUF_MASK |
+ CHNL_STS_EXCS_OFLW_U_BUF_MASK |
+ CHNL_STS_EXCS_OFLW_V_BUF_MASK))
+ dev_dbg(dev, "%s, IRQ EXCS OFLW Error stat=0x%X\n", __func__, status);
+
+ spin_unlock(&mxc_isi->slock);
+ return IRQ_HANDLED;
+}
+
+/**
+ * mxc_isi_adjust_mplane_format - adjust bytesperline or sizeimage
+ */
+void mxc_isi_adjust_mplane_format(struct mxc_isi_fmt *fmt, u32 width, u32 height,
+ struct v4l2_pix_format_mplane *pix)
+{
+ u32 bytesperline = 0;
+ int i;
+
+ pix->colorspace = V4L2_COLORSPACE_JPEG;
+ pix->field = V4L2_FIELD_NONE;
+ pix->num_planes = fmt->memplanes;
+ pix->pixelformat = fmt->fourcc;
+ pix->height = height;
+ pix->width = width;
+
+ for (i = 0; i < pix->num_planes; ++i) {
+ struct v4l2_plane_pix_format *plane_fmt = &pix->plane_fmt[i];
+ u32 bpl = plane_fmt->bytesperline;
+
+ if (fmt->colplanes > 1 && (bpl == 0 || bpl < pix->width))
+ bpl = pix->width; /* Planar */
+
+ if (fmt->colplanes == 1 && /* Packed */
+ (bpl == 0 || ((bpl * 8) / fmt->depth[i]) < pix->width))
+ bpl = (pix->width * fmt->depth[0]) / 8;
+
+ if (i == 0)
+ bytesperline = bpl;
+ else if (i == 1 && fmt->memplanes == 3)
+ bytesperline /= 2;
+
+ plane_fmt->bytesperline = bytesperline;
+ plane_fmt->sizeimage = max((pix->width * pix->height *
+ fmt->depth[i]) / 8, plane_fmt->sizeimage);
+ }
+}
+
+static int mxc_isi_parse_dt(struct mxc_isi_dev *mxc_isi)
+{
+ struct device *dev = &mxc_isi->pdev->dev;
+ struct device_node *node = dev->of_node;
+ int ret = 0;
+
+ mxc_isi->id = of_alias_get_id(node, "isi");
+
+ ret = of_property_read_u32_array(node, "interface",
+ mxc_isi->interface, 3);
+ if (ret < 0)
+ return ret;
+
+ mxc_isi->parallel_csi = of_property_read_bool(node, "parallel_csi");
+
+ dev_dbg(dev, "%s, isi_%d,interface(%d, %d, %d)\n", __func__, mxc_isi->id,
+ mxc_isi->interface[0], mxc_isi->interface[1], mxc_isi->interface[2]);
+
+ mxc_isi->chain_buf = of_property_read_bool(node, "fsl,chain_buf");
+ return 0;
+}
+
+
+static int mxc_isi_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct mxc_isi_dev *mxc_isi;
+ struct resource *res;
+ int ret = 0;
+
+ mxc_isi = devm_kzalloc(dev, sizeof(*mxc_isi), GFP_KERNEL);
+ if (!mxc_isi)
+ return -ENOMEM;
+
+ mxc_isi->pdev = pdev;
+
+ ret = mxc_isi_parse_dt(mxc_isi);
+ if (ret < 0)
+ return ret;
+
+ if (mxc_isi->id >= MXC_ISI_MAX_DEVS || mxc_isi->id < 0) {
+ dev_err(dev, "Invalid driver data or device id (%d)\n",
+ mxc_isi->id);
+ return -EINVAL;
+ }
+
+ init_waitqueue_head(&mxc_isi->irq_queue);
+ spin_lock_init(&mxc_isi->slock);
+ mutex_init(&mxc_isi->lock);
+ mutex_init(&mxc_isi->m2m_lock);
+ atomic_set(&mxc_isi->open_count, 0);
+
+ mxc_isi->clk = devm_clk_get(dev, NULL);
+ if (IS_ERR(mxc_isi->clk)) {
+ dev_err(dev, "failed to get isi clk\n");
+ return PTR_ERR(mxc_isi->clk);
+ }
+ ret = clk_prepare(mxc_isi->clk);
+ if (ret < 0) {
+ dev_err(dev, "%s, prepare clk error\n", __func__);
+ return -EINVAL;
+ }
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ mxc_isi->regs = devm_ioremap_resource(dev, res);
+ if (IS_ERR(mxc_isi->regs)) {
+ dev_err(dev, "Failed to get ISI register map\n");
+ return PTR_ERR(mxc_isi->regs);
+ }
+
+ res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+ if (res == NULL) {
+ dev_err(dev, "Failed to get IRQ resource\n");
+ return -ENXIO;
+ }
+
+ mxc_isi_clean_registers(mxc_isi);
+
+ ret = devm_request_irq(dev, res->start, mxc_isi_irq_handler,
+ 0, dev_name(dev), mxc_isi);
+ if (ret < 0) {
+ dev_err(dev, "failed to install irq (%d)\n", ret);
+ return -EINVAL;
+ }
+
+ ret = mxc_isi_initialize_capture_subdev(mxc_isi);
+ if (ret < 0) {
+ dev_err(dev, "failed to init cap subdev (%d)\n", ret);
+ return -EINVAL;
+ }
+
+ platform_set_drvdata(pdev, mxc_isi);
+
+ ret = clk_enable(mxc_isi->clk);
+ if (ret < 0) {
+ dev_err(dev, "%s, enable clk error\n", __func__);
+ goto err_sclk;
+ }
+
+ mxc_isi_channel_set_chain_buf(mxc_isi);
+ clk_disable_unprepare(mxc_isi->clk);
+
+ pm_runtime_enable(dev);
+
+ dev_dbg(dev, "mxc_isi.%d registered successfully\n", mxc_isi->id);
+
+ return 0;
+
+err_sclk:
+ mxc_isi_unregister_capture_subdev(mxc_isi);
+ return ret;
+}
+
+static int mxc_isi_remove(struct platform_device *pdev)
+{
+ struct mxc_isi_dev *mxc_isi = platform_get_drvdata(pdev);
+ struct device *dev = &pdev->dev;
+
+ mxc_isi_unregister_capture_subdev(mxc_isi);
+ pm_runtime_disable(dev);
+
+ return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int mxc_isi_pm_suspend(struct device *dev)
+{
+ struct mxc_isi_dev *mxc_isi = dev_get_drvdata(dev);
+
+ if (mxc_isi->is_streaming) {
+ dev_warn(dev, "running, prevent entering suspend.\n");
+ return -EAGAIN;
+ }
+
+ return pm_runtime_force_suspend(dev);
+}
+
+static int mxc_isi_pm_resume(struct device *dev)
+{
+ return pm_runtime_force_resume(dev);
+}
+#endif
+
+static int mxc_isi_runtime_suspend(struct device *dev)
+{
+ struct mxc_isi_dev *mxc_isi = dev_get_drvdata(dev);
+
+ clk_disable_unprepare(mxc_isi->clk);
+ return 0;
+}
+
+static int mxc_isi_runtime_resume(struct device *dev)
+{
+ struct mxc_isi_dev *mxc_isi = dev_get_drvdata(dev);
+ int ret;
+
+ ret = clk_prepare_enable(mxc_isi->clk);
+ if (ret)
+ dev_err(dev, "%s clk enable fail\n", __func__);
+
+ return (ret) ? ret : 0;
+}
+
+static const struct dev_pm_ops mxc_isi_pm_ops = {
+ SET_SYSTEM_SLEEP_PM_OPS(mxc_isi_pm_suspend, mxc_isi_pm_resume)
+ SET_RUNTIME_PM_OPS(mxc_isi_runtime_suspend, mxc_isi_runtime_resume, NULL)
+};
+
+static const struct of_device_id mxc_isi_of_match[] = {
+ {.compatible = "fsl,imx8-isi",},
+ { /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, mxc_isi_of_match);
+
+static struct platform_driver mxc_isi_driver = {
+ .probe = mxc_isi_probe,
+ .remove = mxc_isi_remove,
+ .driver = {
+ .of_match_table = mxc_isi_of_match,
+ .name = MXC_ISI_DRIVER_NAME,
+ .pm = &mxc_isi_pm_ops,
+ }
+};
+
+module_platform_driver(mxc_isi_driver);
+
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("MXC Image Subsystem driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("ISI");
+MODULE_VERSION("1.0");
diff --git a/drivers/media/platform/imx8/mxc-isi-core.h b/drivers/media/platform/imx8/mxc-isi-core.h
new file mode 100644
index 000000000000..c26060c0870d
--- /dev/null
+++ b/drivers/media/platform/imx8/mxc-isi-core.h
@@ -0,0 +1,355 @@
+/*
+ * Copyright 2017-2018 NXP
+ */
+/*
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#ifndef MXC_ISI_CORE_H_
+#define MXC_ISI_CORE_H_
+
+#include <media/v4l2-device.h>
+#include <media/v4l2-subdev.h>
+#include <media/v4l2-ctrls.h>
+#include <media/videobuf2-core.h>
+#include <media/videobuf2-dma-contig.h>
+
+#define MXC_ISI_DRIVER_NAME "mxc-isi"
+#define MXC_ISI_MAX_DEVS 8
+
+#define ISI_OF_NODE_NAME "isi"
+
+#define MXC_ISI_SD_PAD_SINK_MIPI0_VC0 0
+#define MXC_ISI_SD_PAD_SINK_MIPI0_VC1 1
+#define MXC_ISI_SD_PAD_SINK_MIPI0_VC2 2
+#define MXC_ISI_SD_PAD_SINK_MIPI0_VC3 3
+#define MXC_ISI_SD_PAD_SINK_MIPI1_VC0 4
+#define MXC_ISI_SD_PAD_SINK_MIPI1_VC1 5
+#define MXC_ISI_SD_PAD_SINK_MIPI1_VC2 6
+#define MXC_ISI_SD_PAD_SINK_MIPI1_VC3 7
+#if 0
+#define MXC_ISI_SD_PAD_SINK_MIPI_CSI0 0
+#define MXC_ISI_SD_PAD_SINK_MIPI_CSI1 1
+#endif
+#define MXC_ISI_SD_PAD_SINK_DC0 8
+#define MXC_ISI_SD_PAD_SINK_DC1 9
+#define MXC_ISI_SD_PAD_SINK_HDMI 10
+#define MXC_ISI_SD_PAD_SINK_MEM 11
+#define MXC_ISI_SD_PAD_SOURCE_MEM 12
+#define MXC_ISI_SD_PAD_SOURCE_DC0 13
+#define MXC_ISI_SD_PAD_SOURCE_DC1 14
+#define MXC_ISI_SD_PAD_SINK_PARALLEL_CSI 15
+#define MXC_ISI_SD_PADS_NUM 16
+
+#define MXC_MAX_PLANES 3
+
+enum isi_input_interface {
+ ISI_INPUT_INTERFACE_DC0 = 0,
+ ISI_INPUT_INTERFACE_DC1,
+ ISI_INPUT_INTERFACE_MIPI0_CSI2,
+ ISI_INPUT_INTERFACE_MIPI1_CSI2,
+ ISI_INPUT_INTERFACE_HDMI,
+ ISI_INPUT_INTERFACE_MEM,
+ ISI_INPUT_INTERFACE_PARALLEL_CSI,
+ ISI_INPUT_INTERFACE_MAX,
+};
+
+enum isi_input_sub_interface {
+ ISI_INPUT_SUB_INTERFACE_VC0 = 0,
+ ISI_INPUT_SUB_INTERFACE_VC1,
+ ISI_INPUT_SUB_INTERFACE_VC2,
+ ISI_INPUT_SUB_INTERFACE_VC3,
+};
+
+enum isi_output_interface {
+ ISI_OUTPUT_INTERFACE_DC0 = 0,
+ ISI_OUTPUT_INTERFACE_DC1,
+ ISI_OUTPUT_INTERFACE_MEM,
+ ISI_OUTPUT_INTERFACE_MAX,
+};
+
+enum {
+ IN_PORT,
+ SUB_IN_PORT,
+ OUT_PORT,
+ MAX_PORTS,
+};
+
+enum mxc_isi_out_fmt {
+ MXC_ISI_OUT_FMT_RGBA32 = 0x0,
+ MXC_ISI_OUT_FMT_ABGR32,
+ MXC_ISI_OUT_FMT_ARGB32,
+ MXC_ISI_OUT_FMT_RGBX32,
+ MXC_ISI_OUT_FMT_XBGR32,
+ MXC_ISI_OUT_FMT_XRGB32,
+ MXC_ISI_OUT_FMT_RGB32P,
+ MXC_ISI_OUT_FMT_BGR32P,
+ MXC_ISI_OUT_FMT_A2BGR10,
+ MXC_ISI_OUT_FMT_A2RGB10,
+ MXC_ISI_OUT_FMT_RGB565,
+ MXC_ISI_OUT_FMT_RAW8,
+ MXC_ISI_OUT_FMT_RAW10,
+ MXC_ISI_OUT_FMT_RAW10P,
+ MXC_ISI_OUT_FMT_RAW12,
+ MXC_ISI_OUT_FMT_RAW16,
+ MXC_ISI_OUT_FMT_YUV444_1P8P,
+ MXC_ISI_OUT_FMT_YUV444_2P8P,
+ MXC_ISI_OUT_FMT_YUV444_3P8P,
+ MXC_ISI_OUT_FMT_YUV444_1P8,
+ MXC_ISI_OUT_FMT_YUV444_1P10,
+ MXC_ISI_OUT_FMT_YUV444_2P10,
+ MXC_ISI_OUT_FMT_YUV444_3P10,
+ MXC_ISI_OUT_FMT_YUV444_1P10P = 0x18,
+ MXC_ISI_OUT_FMT_YUV444_2P10P,
+ MXC_ISI_OUT_FMT_YUV444_3P10P,
+ MXC_ISI_OUT_FMT_YUV444_1P12 = 0x1C,
+ MXC_ISI_OUT_FMT_YUV444_2P12,
+ MXC_ISI_OUT_FMT_YUV444_3P12,
+ MXC_ISI_OUT_FMT_YUV422_1P8P = 0x20,
+ MXC_ISI_OUT_FMT_YUV422_2P8P,
+ MXC_ISI_OUT_FMT_YUV422_3P8P,
+ MXC_ISI_OUT_FMT_YUV422_1P10 = 0x24,
+ MXC_ISI_OUT_FMT_YUV422_2P10,
+ MXC_ISI_OUT_FMT_YUV422_3P10,
+ MXC_ISI_OUT_FMT_YUV422_1P10P = 0x28,
+ MXC_ISI_OUT_FMT_YUV422_2P10P,
+ MXC_ISI_OUT_FMT_YUV422_3P10P,
+ MXC_ISI_OUT_FMT_YUV422_1P12 = 0x2C,
+ MXC_ISI_OUT_FMT_YUV422_2P12,
+ MXC_ISI_OUT_FMT_YUV422_3P12,
+ MXC_ISI_OUT_FMT_YUV420_2P8P = 0x31,
+ MXC_ISI_OUT_FMT_YUV420_3P8P,
+ MXC_ISI_OUT_FMT_YUV420_2P10 = 0x35,
+ MXC_ISI_OUT_FMT_YUV420_3P10,
+ MXC_ISI_OUT_FMT_YUV420_2P10P = 0x39,
+ MXC_ISI_OUT_FMT_YUV420_3P10P,
+ MXC_ISI_OUT_FMT_YUV420_2P12 = 0x3D,
+ MXC_ISI_OUT_FMT_YUV420_3P12,
+};
+
+enum mxc_isi_in_fmt {
+ MXC_ISI_IN_FMT_BGR8P = 0x0,
+};
+
+enum mxc_isi_m2m_in_fmt {
+ MXC_ISI_M2M_IN_FMT_BGR8P = 0x0,
+ MXC_ISI_M2M_IN_FMT_RGB8P,
+ MXC_ISI_M2M_IN_FMT_XRGB8,
+ MXC_ISI_M2M_IN_FMT_RGBX8,
+ MXC_ISI_M2M_IN_FMT_XBGR8,
+ MXC_ISI_M2M_IN_FMT_RGB565,
+ MXC_ISI_M2M_IN_FMT_A2BGR10,
+ MXC_ISI_M2M_IN_FMT_A2RGB10,
+ MXC_ISI_M2M_IN_FMT_YUV444_1P8P,
+ MXC_ISI_M2M_IN_FMT_YUV444_1P10,
+ MXC_ISI_M2M_IN_FMT_YUV444_1P10P,
+ MXC_ISI_M2M_IN_FMT_YUV444_1P12,
+ MXC_ISI_M2M_IN_FMT_YUV444_1P8,
+ MXC_ISI_M2M_IN_FMT_YUV422_1P8P,
+ MXC_ISI_M2M_IN_FMT_YUV422_1P10,
+ MXC_ISI_M2M_IN_FMT_YUV422_1P10P,
+};
+
+struct mxc_isi_fmt {
+ char *name;
+ u32 mbus_code;
+ u32 fourcc;
+ u32 color;
+ u16 memplanes;
+ u16 colplanes;
+ u8 colorspace;
+ u8 depth[MXC_MAX_PLANES];
+ u16 mdataplanes;
+ u16 flags;
+};
+
+struct mxc_isi_ctrls {
+ struct v4l2_ctrl_handler handler;
+ struct v4l2_ctrl *hflip;
+ struct v4l2_ctrl *vflip;
+ struct v4l2_ctrl *alpha;
+ bool ready;
+};
+
+/**
+ * struct addr - physical address set for DMA
+ * @y: luminance plane physical address
+ * @cb: Cb plane physical address
+ * @cr: Cr plane physical address
+ */
+struct frame_addr {
+ u32 y;
+ u32 cb;
+ u32 cr;
+};
+
+/**
+ * struct mxc_isi_frame - source/target frame properties
+ * o_width: original image width from sensor
+ * o_height: original image height from sensor
+ * c_width: crop image width set by g_selection
+ * c_height: crop image height set by g_selection
+ * h_off: crop horizontal pixel offset
+ * v_off: crop vertical pixel offset
+ * width: out image pixel width
+ * height: out image pixel weight
+ * bytesperline: bytesperline value for each plane
+ * paddr: image frame buffer physical addresses
+ * fmt: color format pointer
+ */
+struct mxc_isi_frame {
+ u32 o_width;
+ u32 o_height;
+ u32 c_width;
+ u32 c_height;
+ u32 h_off;
+ u32 v_off;
+ u32 width;
+ u32 height;
+ unsigned int sizeimage[MXC_MAX_PLANES];
+ unsigned int bytesperline[MXC_MAX_PLANES];
+ struct mxc_isi_fmt *fmt;
+};
+
+struct mxc_isi_roi_alpha {
+ u8 alpha;
+ struct v4l2_rect rect;
+};
+
+struct mxc_isi_buffer {
+ struct vb2_v4l2_buffer v4l2_buf;
+ struct list_head list;
+ struct frame_addr paddr;
+ bool discard;
+};
+
+struct mxc_isi_m2m_dev {
+ struct video_device vdev;
+ struct v4l2_m2m_dev *m2m_dev;
+ struct v4l2_fh fh;
+
+ struct mxc_isi_frame src_f;
+ struct mxc_isi_frame dst_f;
+
+ unsigned int vflip:1;
+ unsigned int hflip:1;
+ unsigned int alphaen:1;
+
+ unsigned int aborting;
+ unsigned int frame_count;
+
+ struct list_head out_active;
+ struct mxc_isi_ctrls ctrls;
+
+ u8 alpha;
+};
+
+struct mxc_isi_ctx {
+ struct mxc_isi_dev *isi_dev;
+ struct v4l2_fh fh;
+};
+
+struct mxc_isi_cap_dev {
+ struct v4l2_subdev sd;
+ struct video_device vdev;
+ struct v4l2_fh fh;
+ struct media_pad cap_pad;
+ struct media_pad sd_pads[MXC_ISI_SD_PADS_NUM];
+ struct vb2_queue vb2_q;
+ struct list_head out_pending;
+ struct list_head out_active;
+ struct list_head out_discard;
+
+ struct mxc_isi_frame src_f;
+ struct mxc_isi_frame dst_f;
+ u32 frame_count;
+
+ u32 buf_index;
+};
+
+struct mxc_isi_dev {
+ spinlock_t slock;
+ struct mutex lock;
+ struct mutex m2m_lock;
+ wait_queue_head_t irq_queue;
+
+ int id;
+ void __iomem *regs;
+ unsigned long state;
+
+ struct platform_device *pdev;
+ struct v4l2_device *v4l2_dev;
+ struct mxc_isi_m2m_dev m2m;
+ struct mxc_isi_cap_dev isi_cap;
+ struct clk *clk;
+
+ u32 interface[MAX_PORTS];
+ u32 flags;
+ u32 skip_m2m;
+ u8 chain_buf;
+
+ atomic_t open_count;
+
+ /* scale factor */
+ u32 xfactor;
+ u32 yfactor;
+ u32 pre_dec_x;
+ u32 pre_dec_y;
+
+ unsigned int hflip:1;
+ unsigned int vflip:1;
+
+ unsigned int cscen:1;
+ unsigned int scale:1;
+ unsigned int alphaen:1;
+ unsigned int crop:1;
+ unsigned int deinterlace:1;
+ unsigned int parallel_csi:1;
+ unsigned int is_m2m:1;
+ unsigned int is_streaming:1;
+
+ struct mxc_isi_ctrls ctrls;
+ u8 alpha; /* goable alpha */
+ struct mxc_isi_roi_alpha alpha_roi[5]; /* ROI alpha */
+
+ struct v4l2_pix_format_mplane pix;
+
+ size_t discard_size[MXC_MAX_PLANES];
+ void *discard_buffer[MXC_MAX_PLANES];
+ dma_addr_t discard_buffer_dma[MXC_MAX_PLANES];
+ struct mxc_isi_buffer buf_discard[2];
+};
+
+static inline void set_frame_bounds(struct mxc_isi_frame *f, u32 width, u32 height)
+{
+ f->o_width = width;
+ f->o_height = height;
+ f->c_width = width;
+ f->c_height = height;
+ f->width = width;
+ f->height = height;
+}
+
+static inline void set_frame_out(struct mxc_isi_frame *f, u32 width, u32 height)
+{
+ f->c_width = width;
+ f->c_height = height;
+ f->width = width;
+ f->height = height;
+}
+
+static inline void set_frame_crop(struct mxc_isi_frame *f,
+ u32 left, u32 top, u32 width, u32 height)
+{
+ f->h_off = left;
+ f->v_off = top;
+ f->c_width = width;
+ f->c_height = height;
+}
+
+#endif
diff --git a/drivers/media/platform/imx8/mxc-isi-hw.c b/drivers/media/platform/imx8/mxc-isi-hw.c
new file mode 100644
index 000000000000..94c01ea07303
--- /dev/null
+++ b/drivers/media/platform/imx8/mxc-isi-hw.c
@@ -0,0 +1,803 @@
+/*
+ * Copyright 2017-2018 NXP
+ */
+/*
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+#include <soc/imx8/sc/sci.h>
+#include <dt-bindings/pinctrl/pads-imx8qxp.h>
+
+#include "mxc-isi-hw.h"
+#define ISI_DOWNSCALE_THRESHOLD 0x4000
+
+#ifdef DEBUG
+void dump_isi_regs(struct mxc_isi_dev *mxc_isi)
+{
+ struct device *dev = &mxc_isi->pdev->dev;
+
+ dev_dbg(dev, "ISI CHNLC register dump, isi%d\n", mxc_isi->id);
+ dev_dbg(dev, "CHNL_CTRL 0x0h = 0x%8x\n", readl(mxc_isi->regs + 0x0));
+ dev_dbg(dev, "CHNL_IMG_CTRL 0x4h = 0x%8x\n", readl(mxc_isi->regs + 0x4));
+ dev_dbg(dev, "CHNL_OUT_BUF_CTRL 0x8h = 0x%8x\n", readl(mxc_isi->regs + 0x8));
+ dev_dbg(dev, "CHNL_IMG_CFG 0xCh = 0x%8x\n", readl(mxc_isi->regs + 0xC));
+ dev_dbg(dev, "CHNL_IER 0x10h = 0x%8x\n", readl(mxc_isi->regs + 0x10));
+ dev_dbg(dev, "CHNL_STS 0x14h = 0x%8x\n", readl(mxc_isi->regs + 0x14));
+ dev_dbg(dev, "CHNL_SCALE_FACTOR 0x18h = 0x%8x\n", readl(mxc_isi->regs + 0x18));
+ dev_dbg(dev, "CHNL_SCALE_OFFSET 0x1Ch = 0x%8x\n", readl(mxc_isi->regs + 0x1C));
+ dev_dbg(dev, "CHNL_CROP_ULC 0x20h = 0x%8x\n", readl(mxc_isi->regs + 0x20));
+ dev_dbg(dev, "CHNL_CROP_LRC 0x24h = 0x%8x\n", readl(mxc_isi->regs + 0x24));
+ dev_dbg(dev, "CHNL_CSC_COEFF0 0x28h = 0x%8x\n", readl(mxc_isi->regs + 0x28));
+ dev_dbg(dev, "CHNL_CSC_COEFF1 0x2Ch = 0x%8x\n", readl(mxc_isi->regs + 0x2C));
+ dev_dbg(dev, "CHNL_CSC_COEFF2 0x30h = 0x%8x\n", readl(mxc_isi->regs + 0x30));
+ dev_dbg(dev, "CHNL_CSC_COEFF3 0x34h = 0x%8x\n", readl(mxc_isi->regs + 0x34));
+ dev_dbg(dev, "CHNL_CSC_COEFF4 0x38h = 0x%8x\n", readl(mxc_isi->regs + 0x38));
+ dev_dbg(dev, "CHNL_CSC_COEFF5 0x3Ch = 0x%8x\n", readl(mxc_isi->regs + 0x3C));
+ dev_dbg(dev, "CHNL_ROI_0_ALPHA 0x40h = 0x%8x\n", readl(mxc_isi->regs + 0x40));
+ dev_dbg(dev, "CHNL_ROI_0_ULC 0x44h = 0x%8x\n", readl(mxc_isi->regs + 0x44));
+ dev_dbg(dev, "CHNL_ROI_0_LRC 0x48h = 0x%8x\n", readl(mxc_isi->regs + 0x48));
+ dev_dbg(dev, "CHNL_ROI_1_ALPHA 0x4Ch = 0x%8x\n", readl(mxc_isi->regs + 0x4C));
+ dev_dbg(dev, "CHNL_ROI_1_ULC 0x50h = 0x%8x\n", readl(mxc_isi->regs + 0x50));
+ dev_dbg(dev, "CHNL_ROI_1_LRC 0x54h = 0x%8x\n", readl(mxc_isi->regs + 0x54));
+ dev_dbg(dev, "CHNL_ROI_2_ALPHA 0x58h = 0x%8x\n", readl(mxc_isi->regs + 0x58));
+ dev_dbg(dev, "CHNL_ROI_2_ULC 0x5Ch = 0x%8x\n", readl(mxc_isi->regs + 0x5C));
+ dev_dbg(dev, "CHNL_ROI_2_LRC 0x60h = 0x%8x\n", readl(mxc_isi->regs + 0x60));
+ dev_dbg(dev, "CHNL_ROI_3_ALPHA 0x64h = 0x%8x\n", readl(mxc_isi->regs + 0x64));
+ dev_dbg(dev, "CHNL_ROI_3_ULC 0x68h = 0x%8x\n", readl(mxc_isi->regs + 0x68));
+ dev_dbg(dev, "CHNL_ROI_3_LRC 0x6Ch = 0x%8x\n", readl(mxc_isi->regs + 0x6C));
+ dev_dbg(dev, "CHNL_OUT_BUF1_ADDR_Y 0x70h = 0x%8x\n", readl(mxc_isi->regs + 0x70));
+ dev_dbg(dev, "CHNL_OUT_BUF1_ADDR_U 0x74h = 0x%8x\n", readl(mxc_isi->regs + 0x74));
+ dev_dbg(dev, "CHNL_OUT_BUF1_ADDR_V 0x78h = 0x%8x\n", readl(mxc_isi->regs + 0x78));
+ dev_dbg(dev, "CHNL_OUT_BUF_PITCH 0x7Ch = 0x%8x\n", readl(mxc_isi->regs + 0x7C));
+ dev_dbg(dev, "CHNL_IN_BUF_ADDR 0x80h = 0x%8x\n", readl(mxc_isi->regs + 0x80));
+ dev_dbg(dev, "CHNL_IN_BUF_PITCH 0x84h = 0x%8x\n", readl(mxc_isi->regs + 0x84));
+ dev_dbg(dev, "CHNL_MEM_RD_CTRL 0x88h = 0x%8x\n", readl(mxc_isi->regs + 0x88));
+ dev_dbg(dev, "CHNL_OUT_BUF2_ADDR_Y 0x8Ch = 0x%8x\n", readl(mxc_isi->regs + 0x8C));
+ dev_dbg(dev, "CHNL_OUT_BUF2_ADDR_U 0x90h = 0x%8x\n", readl(mxc_isi->regs + 0x90));
+ dev_dbg(dev, "CHNL_OUT_BUF2_ADDR_V 0x94h = 0x%8x\n", readl(mxc_isi->regs + 0x94));
+}
+#else
+void dump_isi_regs(struct mxc_isi_dev *mxc_isi)
+{
+}
+#endif
+
+static const u32 coeffs[2][6] = {
+ /* A2,A1, B1, A3, B3, B2, C2, C1, D1, C3, D3, D2 */
+ /* YUV2RGB */
+ { 0x0000012A, 0x012A0198, 0x0730079C, 0x0204012A, 0x01F00000, 0x01800180 },
+ /* RGB->YUV */
+ { 0x00810041, 0x07db0019, 0x007007b6, 0x07a20070, 0x001007ee, 0x00800080 },
+};
+
+static void printk_pixelformat(char *prefix, int val)
+{
+ printk("%s %c%c%c%c\n", prefix ? prefix : "pixelformat",
+ val & 0xff, (val >> 8) & 0xff, (val >> 16) & 0xff, (val >> 24) & 0xff);
+}
+
+static bool is_rgb(u32 pix_fmt)
+{
+ if ((pix_fmt == V4L2_PIX_FMT_RGB565) ||
+ (pix_fmt == V4L2_PIX_FMT_RGB24) ||
+ (pix_fmt == V4L2_PIX_FMT_RGB32) ||
+ (pix_fmt == V4L2_PIX_FMT_BGR32) ||
+ (pix_fmt == V4L2_PIX_FMT_XRGB32) ||
+ (pix_fmt == V4L2_PIX_FMT_XBGR32) ||
+ (pix_fmt == V4L2_PIX_FMT_BGR24) ||
+ (pix_fmt == V4L2_PIX_FMT_RGBA) ||
+ (pix_fmt == V4L2_PIX_FMT_ABGR32) ||
+ (pix_fmt == V4L2_PIX_FMT_ARGB32)) {
+ return true;
+ } else {
+ return false;
+ }
+}
+
+static bool is_yuv(u32 pix_fmt)
+{
+ if ((pix_fmt == V4L2_PIX_FMT_YUYV) ||
+ (pix_fmt == V4L2_PIX_FMT_YUV32) ||
+ (pix_fmt == V4L2_PIX_FMT_YUV444M) ||
+ (pix_fmt == V4L2_PIX_FMT_NV12)) {
+ return true;
+ } else {
+ return false;
+ }
+}
+
+static void chain_buf(struct mxc_isi_dev *mxc_isi)
+{
+ struct mxc_isi_frame *src_f;
+ u32 val;
+
+ if (mxc_isi->is_m2m)
+ src_f = &mxc_isi->m2m.src_f;
+ else
+ src_f = &mxc_isi->isi_cap.src_f;
+
+ if (src_f->o_width > 2048) {
+ val = readl(mxc_isi->regs + CHNL_CTRL);
+ val &= ~CHNL_CTRL_CHAIN_BUF_MASK;
+ val |= (CHNL_CTRL_CHAIN_BUF_2_CHAIN << CHNL_CTRL_CHAIN_BUF_OFFSET);
+ writel(val, mxc_isi->regs + CHNL_CTRL);
+ } else if (!mxc_isi->chain_buf) {
+ val = readl(mxc_isi->regs + CHNL_CTRL);
+ val &= ~CHNL_CTRL_CHAIN_BUF_MASK;
+ writel(val, mxc_isi->regs + CHNL_CTRL);
+ }
+}
+
+void mxc_isi_channel_set_outbuf(struct mxc_isi_dev *mxc_isi, struct mxc_isi_buffer *buf)
+{
+ struct vb2_buffer *vb2_buf = &buf->v4l2_buf.vb2_buf;
+ struct frame_addr *paddr = &buf->paddr;
+ struct v4l2_pix_format_mplane *pix = &mxc_isi->pix;
+ u32 framecount = buf->v4l2_buf.sequence;
+ int val = 0;
+
+ if (buf->discard) {
+ paddr->y = mxc_isi->discard_buffer_dma[0];
+ if (pix->num_planes == 2)
+ paddr->cb = mxc_isi->discard_buffer_dma[1];
+ if (pix->num_planes == 3) {
+ paddr->cb = mxc_isi->discard_buffer_dma[1];
+ paddr->cr = mxc_isi->discard_buffer_dma[2];
+ }
+ } else {
+ paddr->y = vb2_dma_contig_plane_dma_addr(vb2_buf, 0);
+
+ if (vb2_buf->num_planes == 2)
+ paddr->cb = vb2_dma_contig_plane_dma_addr(vb2_buf, 1);
+ if (vb2_buf->num_planes == 3) {
+ paddr->cb = vb2_dma_contig_plane_dma_addr(vb2_buf, 1);
+ paddr->cr = vb2_dma_contig_plane_dma_addr(vb2_buf, 2);
+ }
+ }
+
+ val = readl(mxc_isi->regs + CHNL_OUT_BUF_CTRL);
+
+ if (framecount % 2 == 0) {
+ writel(paddr->y, mxc_isi->regs + CHNL_OUT_BUF1_ADDR_Y);
+ writel(paddr->cb, mxc_isi->regs + CHNL_OUT_BUF1_ADDR_U);
+ writel(paddr->cr, mxc_isi->regs + CHNL_OUT_BUF1_ADDR_V);
+ val ^= CHNL_OUT_BUF_CTRL_LOAD_BUF1_ADDR_MASK;
+ } else if (framecount % 2 == 1) {
+ writel(paddr->y, mxc_isi->regs + CHNL_OUT_BUF2_ADDR_Y);
+ writel(paddr->cb, mxc_isi->regs + CHNL_OUT_BUF2_ADDR_U);
+ writel(paddr->cr, mxc_isi->regs + CHNL_OUT_BUF2_ADDR_V);
+ val ^= CHNL_OUT_BUF_CTRL_LOAD_BUF2_ADDR_MASK;
+ }
+ writel(val, mxc_isi->regs + CHNL_OUT_BUF_CTRL);
+}
+
+void mxc_isi_channel_set_m2m_out_addr(struct mxc_isi_dev *mxc_isi,
+ struct mxc_isi_buffer *buf)
+{
+ mxc_isi_channel_set_outbuf(mxc_isi, buf);
+}
+
+void mxc_isi_channel_set_m2m_src_addr(struct mxc_isi_dev *mxc_isi,
+ struct mxc_isi_buffer *buf)
+{
+ struct vb2_buffer *vb2_buf = &buf->v4l2_buf.vb2_buf;
+ struct frame_addr *paddr = &buf->paddr;
+
+ /* Only support one plane */
+ paddr->y = vb2_dma_contig_plane_dma_addr(vb2_buf, 0);
+ writel(paddr->y, mxc_isi->regs + CHNL_IN_BUF_ADDR);
+}
+
+void mxc_isi_channel_sw_reset(struct mxc_isi_dev *mxc_isi)
+{
+ u32 val;
+
+ val = readl(mxc_isi->regs + CHNL_CTRL);
+ val |= CHNL_CTRL_SW_RST;
+ writel(val, mxc_isi->regs + CHNL_CTRL);
+ mdelay(5);
+ val &= ~CHNL_CTRL_SW_RST;
+ writel(val, mxc_isi->regs + CHNL_CTRL);
+}
+
+void mxc_isi_channel_source_config(struct mxc_isi_dev *mxc_isi)
+{
+ u32 val;
+
+ val = readl(mxc_isi->regs + CHNL_CTRL);
+ val &= ~(CHNL_CTRL_MIPI_VC_ID_MASK |
+ CHNL_CTRL_SRC_INPUT_MASK | CHNL_CTRL_SRC_TYPE_MASK);
+
+ switch (mxc_isi->interface[IN_PORT]) {
+ case ISI_INPUT_INTERFACE_MIPI0_CSI2:
+ val |= CHNL_CTRL_SRC_INPUT_MIPI0;
+ if (mxc_isi->interface[SUB_IN_PORT] <= CHNL_CTRL_MIPI_VC_ID_VC3 &&
+ mxc_isi->interface[SUB_IN_PORT] >= CHNL_CTRL_MIPI_VC_ID_VC0)
+ val |= (mxc_isi->interface[SUB_IN_PORT] << CHNL_CTRL_MIPI_VC_ID_OFFSET);
+ break;
+ case ISI_INPUT_INTERFACE_MIPI1_CSI2:
+ val |= CHNL_CTRL_SRC_INPUT_MIPI1;
+ if (mxc_isi->interface[SUB_IN_PORT] <= CHNL_CTRL_MIPI_VC_ID_VC3 &&
+ mxc_isi->interface[SUB_IN_PORT] >= CHNL_CTRL_MIPI_VC_ID_VC0)
+ val |= (mxc_isi->interface[SUB_IN_PORT] << CHNL_CTRL_MIPI_VC_ID_OFFSET);
+ break;
+ case ISI_INPUT_INTERFACE_DC0:
+ val |= CHNL_CTRL_SRC_INPUT_DC0;
+ break;
+ case ISI_INPUT_INTERFACE_DC1:
+ val |= CHNL_CTRL_SRC_INPUT_DC1;
+ break;
+ case ISI_INPUT_INTERFACE_HDMI:
+ val |= CHNL_CTRL_SRC_INPUT_HDMI;
+ break;
+ case ISI_INPUT_INTERFACE_PARALLEL_CSI:
+ val |= CHNL_CTRL_SRC_INPUT_CSI;
+ break;
+ case ISI_INPUT_INTERFACE_MEM:
+ val |= CHNL_CTRL_SRC_INPUT_MEMORY;
+ val |= (CHNL_CTRL_SRC_TYPE_MEMORY << CHNL_CTRL_SRC_TYPE_OFFSET);
+ break;
+ default:
+ dev_err(&mxc_isi->pdev->dev, "invalid interface\n");
+ break;
+ }
+
+ writel(val, mxc_isi->regs + CHNL_CTRL);
+}
+
+void mxc_isi_channel_set_flip(struct mxc_isi_dev *mxc_isi)
+{
+ u32 val;
+
+ val = readl(mxc_isi->regs + CHNL_IMG_CTRL);
+ val &= ~(CHNL_IMG_CTRL_VFLIP_EN_MASK | CHNL_IMG_CTRL_HFLIP_EN_MASK);
+
+ if (mxc_isi->vflip)
+ val |= (CHNL_IMG_CTRL_VFLIP_EN_ENABLE << CHNL_IMG_CTRL_VFLIP_EN_OFFSET);
+ if (mxc_isi->hflip)
+ val |= (CHNL_IMG_CTRL_HFLIP_EN_ENABLE << CHNL_IMG_CTRL_HFLIP_EN_OFFSET);
+
+ writel(val, mxc_isi->regs + CHNL_IMG_CTRL);
+}
+
+void mxc_isi_channel_set_csc(struct mxc_isi_dev *mxc_isi)
+{
+ struct mxc_isi_fmt *dst_fmt = mxc_isi->isi_cap.dst_f.fmt;
+ struct mxc_isi_fmt *src_fmt = mxc_isi->isi_cap.src_f.fmt;
+ u32 val, csc = 0;
+
+ if (mxc_isi->is_m2m) {
+ src_fmt = mxc_isi->m2m.src_f.fmt;
+ dst_fmt = mxc_isi->m2m.dst_f.fmt;
+ }
+
+ val = readl(mxc_isi->regs + CHNL_IMG_CTRL);
+ val &= ~(CHNL_IMG_CTRL_FORMAT_MASK |
+ CHNL_IMG_CTRL_YCBCR_MODE_MASK |
+ CHNL_IMG_CTRL_CSC_BYPASS_MASK |
+ CHNL_IMG_CTRL_CSC_MODE_MASK);
+
+ /* set outbuf format */
+ val |= dst_fmt->color << CHNL_IMG_CTRL_FORMAT_OFFSET;
+
+ mxc_isi->cscen = 1;
+
+ if (is_yuv(src_fmt->fourcc) && is_rgb(dst_fmt->fourcc)) {
+ /* YUV2RGB */
+ csc = YUV2RGB;
+ /* YCbCr enable??? */
+ val |= (CHNL_IMG_CTRL_CSC_MODE_YCBCR2RGB << CHNL_IMG_CTRL_CSC_MODE_OFFSET);
+ val |= (CHNL_IMG_CTRL_YCBCR_MODE_ENABLE << CHNL_IMG_CTRL_YCBCR_MODE_OFFSET);
+ } else if (is_rgb(src_fmt->fourcc) && is_yuv(dst_fmt->fourcc)) {
+ /* RGB2YUV */
+ csc = RGB2YUV;
+ val |= (CHNL_IMG_CTRL_CSC_MODE_RGB2YCBCR << CHNL_IMG_CTRL_CSC_MODE_OFFSET);
+ } else {
+ /* Bypass CSC */
+ printk("bypass csc\n");
+ mxc_isi->cscen = 0;
+ val |= CHNL_IMG_CTRL_CSC_BYPASS_ENABLE;
+ }
+
+ printk_pixelformat("input fmt", src_fmt->fourcc);
+ printk_pixelformat("output fmt", dst_fmt->fourcc);
+
+ if (mxc_isi->cscen) {
+ writel(coeffs[csc][0], mxc_isi->regs + CHNL_CSC_COEFF0);
+ writel(coeffs[csc][1], mxc_isi->regs + CHNL_CSC_COEFF1);
+ writel(coeffs[csc][2], mxc_isi->regs + CHNL_CSC_COEFF2);
+ writel(coeffs[csc][3], mxc_isi->regs + CHNL_CSC_COEFF3);
+ writel(coeffs[csc][4], mxc_isi->regs + CHNL_CSC_COEFF4);
+ writel(coeffs[csc][5], mxc_isi->regs + CHNL_CSC_COEFF5);
+ }
+
+ writel(val, mxc_isi->regs + CHNL_IMG_CTRL);
+}
+void mxc_isi_channel_set_alpha_roi0(struct mxc_isi_dev *mxc_isi,
+ struct v4l2_rect *rect)
+{
+ u32 val0, val1;
+ val0 = (rect->left << 16) | rect->top;
+ writel(val0, mxc_isi->regs + CHNL_ROI_0_ULC);
+ val1 = (rect->width << 16) | rect->height;
+ writel(val0 + val1, mxc_isi->regs + CHNL_ROI_0_LRC);
+}
+
+void mxc_isi_channel_set_alpha(struct mxc_isi_dev *mxc_isi)
+{
+ u32 val;
+
+ val = readl(mxc_isi->regs + CHNL_IMG_CTRL);
+ val &= ~(CHNL_IMG_CTRL_GBL_ALPHA_VAL_MASK | CHNL_IMG_CTRL_GBL_ALPHA_EN_MASK);
+ val |= ((mxc_isi->alpha << CHNL_IMG_CTRL_GBL_ALPHA_VAL_OFFSET) |
+ (CHNL_IMG_CTRL_GBL_ALPHA_EN_ENABLE << CHNL_IMG_CTRL_GBL_ALPHA_EN_OFFSET));
+
+ writel(val, mxc_isi->regs + CHNL_IMG_CTRL);
+}
+
+void mxc_isi_channel_set_chain_buf(struct mxc_isi_dev *mxc_isi)
+{
+ u32 val;
+
+ if (mxc_isi->chain_buf) {
+ printk("%s\n", __func__);
+ val = readl(mxc_isi->regs + CHNL_CTRL);
+ val &= ~CHNL_CTRL_CHAIN_BUF_MASK;
+ val |= (CHNL_CTRL_CHAIN_BUF_2_CHAIN << CHNL_CTRL_CHAIN_BUF_OFFSET);
+
+ writel(val, mxc_isi->regs + CHNL_CTRL);
+ }
+}
+
+void mxc_isi_channel_deinterlace_init(struct mxc_isi_dev *mxc_isi)
+{
+ /* Config for Blending deinterlace */
+}
+
+void mxc_isi_channel_set_deinterlace(struct mxc_isi_dev *mxc_isi)
+{
+ /* de-interlacing method
+ * Weaving-------------Yes
+ * Line Doubling-------No
+ * Blending -----------TODO*/
+ u32 val;
+
+ val = readl(mxc_isi->regs + CHNL_IMG_CTRL);
+ val &= ~CHNL_IMG_CTRL_DEINT_MASK;
+ if (mxc_isi->deinterlace)
+ val |= mxc_isi->deinterlace << CHNL_IMG_CTRL_DEINT_OFFSET;
+ if (mxc_isi->deinterlace == CHNL_IMG_CTRL_DEINT_LDOUBLE_ODD_EVEN ||
+ mxc_isi->deinterlace == CHNL_IMG_CTRL_DEINT_LDOUBLE_EVEN_ODD)
+ mxc_isi_channel_deinterlace_init(mxc_isi);
+
+ writel(val, mxc_isi->regs + CHNL_IMG_CTRL);
+}
+
+
+void mxc_isi_channel_set_crop(struct mxc_isi_dev *mxc_isi)
+{
+ struct mxc_isi_frame *src_f = &mxc_isi->isi_cap.src_f;
+ struct v4l2_rect crop;
+ u32 val, val0, val1, temp;
+
+ val = readl(mxc_isi->regs + CHNL_IMG_CTRL);
+ val &= ~CHNL_IMG_CTRL_CROP_EN_MASK;
+
+ if ((src_f->o_height == src_f->height) &&
+ (src_f->o_width == src_f->width)) {
+ mxc_isi->crop = 0;
+ writel(val, mxc_isi->regs + CHNL_IMG_CTRL);
+ return;
+ }
+
+ if (mxc_isi->scale) {
+ temp = (src_f->h_off << 12) / mxc_isi->xfactor;
+ crop.left = temp >> mxc_isi->pre_dec_x;
+ temp = (src_f->v_off << 12) / mxc_isi->yfactor;
+ crop.top = temp >> mxc_isi->pre_dec_y;
+ temp = (src_f->width << 12) / mxc_isi->xfactor;
+ crop.width = temp >> mxc_isi->pre_dec_x;
+ temp = (src_f->height << 12) / mxc_isi->yfactor;
+ crop.height = temp >> mxc_isi->pre_dec_y;
+ } else {
+ crop.left = src_f->h_off;
+ crop.top = src_f->v_off;
+ crop.width = src_f->width;
+ crop.height = src_f->height;
+ }
+
+ mxc_isi->crop = 1;
+ val |= (CHNL_IMG_CTRL_CROP_EN_ENABLE << CHNL_IMG_CTRL_CROP_EN_OFFSET);
+ val0 = crop.top | (crop.left << CHNL_CROP_ULC_X_OFFSET);
+ val1 = crop.height | (crop.width << CHNL_CROP_LRC_X_OFFSET);
+
+ writel(val0, mxc_isi->regs + CHNL_CROP_ULC);
+ writel((val1 + val0), mxc_isi->regs + CHNL_CROP_LRC);
+ writel(val, mxc_isi->regs + CHNL_IMG_CTRL);
+}
+
+static void mxc_isi_channel_clear_scaling(struct mxc_isi_dev *mxc_isi)
+{
+ u32 val0;
+
+ writel(0x10001000, mxc_isi->regs + CHNL_SCALE_FACTOR);
+
+ val0 = readl(mxc_isi->regs + CHNL_IMG_CTRL);
+ val0 &= ~(CHNL_IMG_CTRL_DEC_X_MASK | CHNL_IMG_CTRL_DEC_Y_MASK);
+ writel(val0, mxc_isi->regs + CHNL_IMG_CTRL);
+}
+
+void mxc_isi_channel_set_scaling(struct mxc_isi_dev *mxc_isi)
+{
+ struct mxc_isi_frame *dst_f = &mxc_isi->isi_cap.dst_f;
+ struct mxc_isi_frame *src_f = &mxc_isi->isi_cap.src_f;
+ u32 decx, decy;
+ u32 xscale, yscale;
+ u32 xdec = 0, ydec = 0;
+ u32 val0, val1;
+
+ if (mxc_isi->is_m2m) {
+ src_f = &mxc_isi->m2m.src_f;
+ dst_f = &mxc_isi->m2m.dst_f;
+ }
+
+ if (dst_f->height == src_f->height ||
+ dst_f->width == src_f->width) {
+ mxc_isi->scale = 0;
+ mxc_isi_channel_clear_scaling(mxc_isi);
+ dev_dbg(&mxc_isi->pdev->dev, "%s: no scale\n", __func__);
+ return;
+ }
+
+ dev_info(&mxc_isi->pdev->dev, "input_size(%d,%d), output_size(%d,%d)\n",
+ src_f->width, src_f->height, dst_f->width, dst_f->height);
+
+ mxc_isi->scale = 1;
+
+ decx = src_f->width / dst_f->width;
+ decy = src_f->height / dst_f->height;
+
+ if (decx > 1) {
+ /* Down */
+ if (decx >= 2 && decx < 4) {
+ decx = 2;
+ xdec = 1;
+ } else if (decx >= 4 && decx < 8) {
+ decx = 4;
+ xdec = 2;
+ } else if (decx >= 8) {
+ decx = 8;
+ xdec = 3;
+ }
+ xscale = src_f->width * 0x1000 / (dst_f->width * decx);
+ } else
+ /* Up */
+ xscale = src_f->width * 0x1000 / dst_f->width;
+
+ if (decy > 1) {
+ if (decy >= 2 && decy < 4) {
+ decy = 2;
+ ydec = 1;
+ } else if (decy >= 4 && decy < 8) {
+ decy = 4;
+ ydec = 2;
+ } else if (decy >= 8) {
+ decy = 8;
+ ydec = 3;
+ }
+ yscale = src_f->height * 0x1000 / (dst_f->height * decy);
+ } else
+ yscale = src_f->height * 0x1000 / dst_f->height;
+
+ val0 = readl(mxc_isi->regs + CHNL_IMG_CTRL);
+ val0 |= CHNL_IMG_CTRL_YCBCR_MODE_MASK;//YCbCr Sandor???
+ val0 &= ~(CHNL_IMG_CTRL_DEC_X_MASK | CHNL_IMG_CTRL_DEC_Y_MASK);
+ val0 |= (xdec << CHNL_IMG_CTRL_DEC_X_OFFSET) |
+ (ydec << CHNL_IMG_CTRL_DEC_Y_OFFSET);
+ writel(val0, mxc_isi->regs + CHNL_IMG_CTRL);
+
+ if (xscale > ISI_DOWNSCALE_THRESHOLD)
+ xscale = ISI_DOWNSCALE_THRESHOLD;
+ if (yscale > ISI_DOWNSCALE_THRESHOLD)
+ yscale = ISI_DOWNSCALE_THRESHOLD;
+
+ val1 = xscale | (yscale << CHNL_SCALE_FACTOR_Y_SCALE_OFFSET);
+
+ writel(val1, mxc_isi->regs + CHNL_SCALE_FACTOR);
+
+ /* Update scale config if scaling enabled */
+ val1 = dst_f->o_width | (dst_f->o_height << CHNL_SCL_IMG_CFG_HEIGHT_OFFSET);
+ writel(val1, mxc_isi->regs + CHNL_SCL_IMG_CFG);
+
+ writel(0, mxc_isi->regs + CHNL_SCALE_OFFSET);
+
+ return;
+}
+
+void mxc_isi_channel_init(struct mxc_isi_dev *mxc_isi)
+{
+ u32 val;
+
+ /* sw reset */
+ mxc_isi_channel_sw_reset(mxc_isi);
+
+ /* Init channel clk first */
+ val = readl(mxc_isi->regs + CHNL_CTRL);
+ val |= (CHNL_CTRL_CLK_EN_ENABLE << CHNL_CTRL_CLK_EN_OFFSET);
+ writel(val, mxc_isi->regs + CHNL_CTRL);
+}
+
+void mxc_isi_channel_deinit(struct mxc_isi_dev *mxc_isi)
+{
+ u32 val;
+
+ /* sw reset */
+ mxc_isi_channel_sw_reset(mxc_isi);
+
+ /* deinit channel clk first */
+ val = (CHNL_CTRL_CLK_EN_ENABLE << CHNL_CTRL_CLK_EN_OFFSET);
+ writel(val, mxc_isi->regs + CHNL_CTRL);
+}
+
+void mxc_isi_channel_config(struct mxc_isi_dev *mxc_isi)
+{
+ struct mxc_isi_frame *dst_f = &mxc_isi->isi_cap.dst_f;
+ struct mxc_isi_frame *src_f = &mxc_isi->isi_cap.src_f;
+ u32 val;
+
+ /* images having higher than 2048 horizontal resolution */
+ chain_buf(mxc_isi);
+
+ /* config output frame size and format */
+ val = src_f->o_width | (src_f->o_height << CHNL_IMG_CFG_HEIGHT_OFFSET);
+ writel(val, mxc_isi->regs + CHNL_IMG_CFG);
+
+ /* scale size need to equal input size when scaling disabled*/
+ writel(val, mxc_isi->regs + CHNL_SCL_IMG_CFG);
+
+ /* check csc and scaling */
+ mxc_isi_channel_set_csc(mxc_isi);
+
+ mxc_isi_channel_set_scaling(mxc_isi);
+
+ /* select the source input / src type / virtual channel for mipi*/
+ mxc_isi_channel_source_config(mxc_isi);
+
+ /* line pitch */
+ val = dst_f->bytesperline[0];
+ writel(val, mxc_isi->regs + CHNL_OUT_BUF_PITCH);
+
+ /* TODO */
+ mxc_isi_channel_set_flip(mxc_isi);
+
+ if (mxc_isi->alphaen)
+ mxc_isi_channel_set_alpha(mxc_isi);
+#if 0
+ mxc_isi_channel_set_crop(mxc_isi);
+#endif
+
+ val = readl(mxc_isi->regs + CHNL_CTRL);
+ val &= ~CHNL_CTRL_CHNL_BYPASS_MASK;
+
+ /* Bypass channel */
+ if (!mxc_isi->cscen && !mxc_isi->scale)
+ val |= (CHNL_CTRL_CHNL_BYPASS_ENABLE << CHNL_CTRL_CHNL_BYPASS_OFFSET);
+
+ writel(val, mxc_isi->regs + CHNL_CTRL);
+}
+
+void mxc_isi_clean_registers(struct mxc_isi_dev *mxc_isi)
+{
+ u32 status;
+
+ status = mxc_isi_get_irq_status(mxc_isi);
+ mxc_isi_clean_irq_status(mxc_isi, status);
+}
+
+void mxc_isi_channel_enable(struct mxc_isi_dev *mxc_isi)
+{
+ u32 val;
+
+ val = readl(mxc_isi->regs + CHNL_CTRL);
+ val |= (CHNL_CTRL_CHNL_EN_ENABLE << CHNL_CTRL_CHNL_EN_OFFSET);
+ val |= 0xff << CHNL_CTRL_BLANK_PXL_OFFSET;
+ writel(val, mxc_isi->regs + CHNL_CTRL);
+
+ mxc_isi_clean_registers(mxc_isi);
+ mxc_isi_enable_irq(mxc_isi);
+ msleep(300);
+ dump_isi_regs(mxc_isi);
+}
+
+void mxc_isi_channel_disable(struct mxc_isi_dev *mxc_isi)
+{
+ u32 val;
+
+ mxc_isi_disable_irq(mxc_isi);
+
+ val = readl(mxc_isi->regs + CHNL_CTRL);
+ val &= ~(CHNL_CTRL_CHNL_EN_MASK | CHNL_CTRL_CLK_EN_MASK);
+ val |= (CHNL_CTRL_CHNL_EN_DISABLE << CHNL_CTRL_CHNL_EN_OFFSET);
+ val |= (CHNL_CTRL_CLK_EN_DISABLE << CHNL_CTRL_CLK_EN_OFFSET);
+ writel(val, mxc_isi->regs + CHNL_CTRL);
+}
+
+void mxc_isi_enable_irq(struct mxc_isi_dev *mxc_isi)
+{
+ u32 val;
+
+ val = CHNL_IER_FRM_RCVD_EN_MASK |
+ CHNL_IER_OFLW_Y_BUF_EN_MASK |
+ CHNL_IER_AXI_WR_ERR_U_EN_MASK |
+ CHNL_IER_AXI_WR_ERR_V_EN_MASK |
+ CHNL_IER_AXI_WR_ERR_Y_EN_MASK |
+ CHNL_IER_OFLW_PANIC_V_BUF_EN_MASK |
+ CHNL_IER_EXCS_OFLW_V_BUF_EN_MASK |
+ CHNL_IER_OFLW_V_BUF_EN_MASK |
+ CHNL_IER_OFLW_PANIC_U_BUF_EN_MASK |
+ CHNL_IER_EXCS_OFLW_U_BUF_EN_MASK |
+ CHNL_IER_OFLW_U_BUF_EN_MASK |
+ CHNL_IER_OFLW_PANIC_Y_BUF_EN_MASK |
+ CHNL_IER_EXCS_OFLW_Y_BUF_EN_MASK |
+ CHNL_IER_OFLW_Y_BUF_EN_MASK;
+ writel(val, mxc_isi->regs + CHNL_IER);
+}
+
+void mxc_isi_disable_irq(struct mxc_isi_dev *mxc_isi)
+{
+ writel(0, mxc_isi->regs + CHNL_IER);
+}
+
+u32 mxc_isi_get_irq_status(struct mxc_isi_dev *mxc_isi)
+{
+ return readl(mxc_isi->regs + CHNL_STS);
+}
+
+void mxc_isi_clean_irq_status(struct mxc_isi_dev *mxc_isi, u32 val)
+{
+ writel(val, mxc_isi->regs + CHNL_STS);
+}
+
+void mxc_isi_m2m_channel_set_filp(struct mxc_isi_dev *mxc_isi)
+{
+ u32 val;
+
+ val = readl(mxc_isi->regs + CHNL_IMG_CTRL);
+ val &= ~(CHNL_IMG_CTRL_VFLIP_EN_MASK | CHNL_IMG_CTRL_HFLIP_EN_MASK);
+
+ if (mxc_isi->m2m.vflip)
+ val |= (CHNL_IMG_CTRL_VFLIP_EN_ENABLE << CHNL_IMG_CTRL_VFLIP_EN_OFFSET);
+ if (mxc_isi->m2m.hflip)
+ val |= (CHNL_IMG_CTRL_HFLIP_EN_ENABLE << CHNL_IMG_CTRL_HFLIP_EN_OFFSET);
+
+ writel(val, mxc_isi->regs + CHNL_IMG_CTRL);
+}
+
+void mxc_isi_m2m_channel_set_alpha(struct mxc_isi_dev *mxc_isi)
+{
+ u32 val;
+
+ val = readl(mxc_isi->regs + CHNL_IMG_CTRL);
+ val &= ~(CHNL_IMG_CTRL_GBL_ALPHA_VAL_MASK | CHNL_IMG_CTRL_GBL_ALPHA_EN_MASK);
+ val |= ((mxc_isi->m2m.alpha << CHNL_IMG_CTRL_GBL_ALPHA_VAL_OFFSET) |
+ (CHNL_IMG_CTRL_GBL_ALPHA_EN_ENABLE << CHNL_IMG_CTRL_GBL_ALPHA_EN_OFFSET));
+
+ writel(val, mxc_isi->regs + CHNL_IMG_CTRL);
+}
+
+void mxc_isi_m2m_channel_init(struct mxc_isi_dev *mxc_isi)
+{
+ u32 val;
+
+ /* sw reset */
+ mxc_isi_channel_sw_reset(mxc_isi);
+
+ /* Init channel clk first */
+ val = readl(mxc_isi->regs + CHNL_CTRL);
+ val |= (CHNL_CTRL_CLK_EN_ENABLE << CHNL_CTRL_CLK_EN_OFFSET);
+ writel(val, mxc_isi->regs + CHNL_CTRL);
+}
+
+void mxc_isi_m2m_channel_config(struct mxc_isi_dev *mxc_isi)
+{
+ struct mxc_isi_frame *src_f, *dst_f;
+ u32 reg;
+
+ src_f = &mxc_isi->m2m.src_f;
+ dst_f = &mxc_isi->m2m.dst_f;
+
+ chain_buf(mxc_isi);
+
+ /* scale size need to equal input size when scaling disabled*/
+ reg = src_f->o_width | (src_f->o_height << CHNL_IMG_CFG_HEIGHT_OFFSET);
+ writel(reg, mxc_isi->regs + CHNL_SCL_IMG_CFG);
+
+ /* CSC */
+ mxc_isi_channel_set_csc(mxc_isi);
+
+ /* Scaling */
+ mxc_isi_channel_set_scaling(mxc_isi);
+
+ /* Horizonal and Vertical flip */
+ mxc_isi_m2m_channel_set_filp(mxc_isi);
+
+ if (mxc_isi->m2m.alphaen)
+ mxc_isi_m2m_channel_set_alpha(mxc_isi);
+}
+
+void mxc_isi_m2m_channel_enable(struct mxc_isi_dev *mxc_isi)
+{
+ u32 reg;
+
+ /* Read from memory and enable ISI channel */
+ reg = readl(mxc_isi->regs + CHNL_CTRL);
+ reg &= ~(CHNL_CTRL_SRC_TYPE_MASK |
+ CHNL_CTRL_SRC_INPUT_MASK |
+ CHNL_CTRL_CHNL_EN_MASK);
+ reg |= (CHNL_CTRL_SRC_INPUT_MEMORY << CHNL_CTRL_SRC_INPUT_OFFSET |
+ CHNL_CTRL_SRC_TYPE_MEMORY << CHNL_CTRL_SRC_TYPE_OFFSET|
+ CHNL_CTRL_CHNL_EN_ENABLE << CHNL_CTRL_CHNL_EN_OFFSET);
+ writel(reg, mxc_isi->regs + CHNL_CTRL);
+
+ mxc_isi_clean_registers(mxc_isi);
+ mxc_isi_enable_irq(mxc_isi);
+ mxc_isi_m2m_start_read(mxc_isi);
+
+ dump_isi_regs(mxc_isi);
+}
+
+void mxc_isi_m2m_config_src(struct mxc_isi_dev *mxc_isi)
+{
+ struct mxc_isi_frame *src_f = &mxc_isi->m2m.src_f;
+ u32 val;
+
+ /* source format */
+ val = readl(mxc_isi->regs + CHNL_MEM_RD_CTRL);
+ val &= ~CHNL_MEM_RD_CTRL_IMG_TYPE_MASK;
+ val |= src_f->fmt->color << CHNL_MEM_RD_CTRL_IMG_TYPE_OFFSET;
+ writel(val, mxc_isi->regs + CHNL_MEM_RD_CTRL);
+
+ /* source image width and height */
+ val = (src_f->width << CHNL_IMG_CFG_WIDTH_OFFSET |
+ src_f->height << CHNL_IMG_CFG_HEIGHT_OFFSET);
+ writel(val, mxc_isi->regs + CHNL_IMG_CFG);
+
+ /* source pitch */
+ val = src_f->bytesperline[0] << CHNL_IN_BUF_PITCH_LINE_PITCH_OFFSET;
+ writel(val, mxc_isi->regs + CHNL_IN_BUF_PITCH);
+}
+
+void mxc_isi_m2m_config_dst(struct mxc_isi_dev *mxc_isi)
+{
+ struct mxc_isi_frame *dst_f = &mxc_isi->m2m.dst_f;
+ u32 val;
+
+ /* out format */
+ val = readl(mxc_isi->regs + CHNL_IMG_CTRL);
+ val &= ~CHNL_IMG_CTRL_FORMAT_MASK;
+ val |= dst_f->fmt->color << CHNL_IMG_CTRL_FORMAT_OFFSET;
+ writel(val, mxc_isi->regs + CHNL_IMG_CTRL);
+
+ /* out pitch */
+ val = readl(mxc_isi->regs + CHNL_OUT_BUF_PITCH);
+ val &= ~CHNL_IN_BUF_PITCH_LINE_PITCH_MASK;
+ val |= dst_f->bytesperline[0] << CHNL_OUT_BUF_PITCH_LINE_PITCH_OFFSET;
+ writel(val, mxc_isi->regs + CHNL_OUT_BUF_PITCH);
+}
+
+void mxc_isi_m2m_start_read(struct mxc_isi_dev *mxc_isi)
+{
+ u32 val;
+
+ val = readl(mxc_isi->regs + CHNL_MEM_RD_CTRL);
+ val &= ~ CHNL_MEM_RD_CTRL_READ_MEM_MASK;
+ writel(val, mxc_isi->regs + CHNL_MEM_RD_CTRL);
+ udelay(300);
+
+ val |= CHNL_MEM_RD_CTRL_READ_MEM_ENABLE << CHNL_MEM_RD_CTRL_READ_MEM_OFFSET;
+ writel(val, mxc_isi->regs + CHNL_MEM_RD_CTRL);
+}
diff --git a/drivers/media/platform/imx8/mxc-isi-hw.h b/drivers/media/platform/imx8/mxc-isi-hw.h
new file mode 100644
index 000000000000..30010cbc5345
--- /dev/null
+++ b/drivers/media/platform/imx8/mxc-isi-hw.h
@@ -0,0 +1,507 @@
+/*
+ * Copyright 2017-2018 NXP
+ */
+/*
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#ifndef MXC_ISI_HW_H_
+#define MXC_ISI_HW_H_
+
+#include <linux/delay.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/bug.h>
+#include <linux/platform_device.h>
+#include <linux/videodev2.h>
+
+#include "mxc-isi-core.h"
+
+/* ISI Registers Define */
+/* Channel Control Register */
+#define CHNL_CTRL 0x0
+#define CHNL_CTRL_CHNL_EN_OFFSET 31
+#define CHNL_CTRL_CHNL_EN_MASK 0x80000000
+#define CHNL_CTRL_CHNL_EN_DISABLE 0
+#define CHNL_CTRL_CHNL_EN_ENABLE 1
+#define CHNL_CTRL_CLK_EN_OFFSET 30
+#define CHNL_CTRL_CLK_EN_MASK 0x40000000
+#define CHNL_CTRL_CLK_EN_DISABLE 0
+#define CHNL_CTRL_CLK_EN_ENABLE 1
+#define CHNL_CTRL_CHNL_BYPASS_OFFSET 29
+#define CHNL_CTRL_CHNL_BYPASS_MASK 0x20000000
+#define CHNL_CTRL_CHNL_BYPASS_ENABLE 1
+#define CHNL_CTRL_CHAIN_BUF_OFFSET 25
+#define CHNL_CTRL_CHAIN_BUF_MASK 0x60000
+#define CHNL_CTRL_CHAIN_BUF_NO_CHAIN 0
+#define CHNL_CTRL_CHAIN_BUF_2_CHAIN 1
+#define CHNL_CTRL_SW_RST_OFFSET 24
+#define CHNL_CTRL_SW_RST_MASK 0x1000000
+#define CHNL_CTRL_SW_RST 0x1000000
+#define CHNL_CTRL_BLANK_PXL_OFFSET 16
+#define CHNL_CTRL_MIPI_VC_ID_OFFSET 6
+#define CHNL_CTRL_MIPI_VC_ID_MASK 0xc0
+#define CHNL_CTRL_MIPI_VC_ID_VC0 0
+#define CHNL_CTRL_MIPI_VC_ID_VC1 1
+#define CHNL_CTRL_MIPI_VC_ID_VC2 2
+#define CHNL_CTRL_MIPI_VC_ID_VC3 3
+#define CHNL_CTRL_SRC_TYPE_OFFSET 4
+#define CHNL_CTRL_SRC_TYPE_MASK 0x10
+#define CHNL_CTRL_SRC_TYPE_DEVICE 0
+#define CHNL_CTRL_SRC_TYPE_MEMORY 1
+#define CHNL_CTRL_SRC_INPUT_OFFSET 0
+#define CHNL_CTRL_SRC_INPUT_MASK 0x7
+#define CHNL_CTRL_SRC_INPUT_DC0 0
+#define CHNL_CTRL_SRC_INPUT_DC1 1
+#define CHNL_CTRL_SRC_INPUT_MIPI0 2
+#define CHNL_CTRL_SRC_INPUT_MIPI1 3
+#define CHNL_CTRL_SRC_INPUT_HDMI 4
+#define CHNL_CTRL_SRC_INPUT_CSI 4
+#define CHNL_CTRL_SRC_INPUT_MEMORY 5
+
+/* Channel Image Control Register */
+#define CHNL_IMG_CTRL 0x4
+#define CHNL_IMG_CTRL_FORMAT_OFFSET 24
+#define CHNL_IMG_CTRL_FORMAT_MASK 0x3F000000
+#define CHNL_IMG_CTRL_GBL_ALPHA_VAL_OFFSET 16
+#define CHNL_IMG_CTRL_GBL_ALPHA_VAL_MASK 0xFF0000
+#define CHNL_IMG_CTRL_GBL_ALPHA_EN_OFFSET 15
+#define CHNL_IMG_CTRL_GBL_ALPHA_EN_ENABLE 1
+#define CHNL_IMG_CTRL_GBL_ALPHA_EN_MASK 0x8000
+#define CHNL_IMG_CTRL_DEINT_OFFSET 12
+#define CHNL_IMG_CTRL_DEINT_MASK 0x7000
+#define CHNL_IMG_CTRL_DEINT_WEAVE_ODD_EVEN 2
+#define CHNL_IMG_CTRL_DEINT_WEAVE_EVEN_ODD 3
+#define CHNL_IMG_CTRL_DEINT_BLEND_ODD_EVEN 4
+#define CHNL_IMG_CTRL_DEINT_BLEND_EVEN_ODD 5
+#define CHNL_IMG_CTRL_DEINT_LDOUBLE_ODD_EVEN 6
+#define CHNL_IMG_CTRL_DEINT_LDOUBLE_EVEN_ODD 7
+#define CHNL_IMG_CTRL_DEC_X_OFFSET 10
+#define CHNL_IMG_CTRL_DEC_X_MASK 0xC00
+#define CHNL_IMG_CTRL_DEC_X_0 0
+#define CHNL_IMG_CTRL_DEC_X_2 1
+#define CHNL_IMG_CTRL_DEC_X_4 2
+#define CHNL_IMG_CTRL_DEC_X_8 3
+#define CHNL_IMG_CTRL_DEC_Y_OFFSET 8
+#define CHNL_IMG_CTRL_DEC_Y_MASK 0x300
+#define CHNL_IMG_CTRL_DEC_Y_0 0
+#define CHNL_IMG_CTRL_DEC_Y_2 1
+#define CHNL_IMG_CTRL_DEC_Y_4 2
+#define CHNL_IMG_CTRL_DEC_Y_8 3
+#define CHNL_IMG_CTRL_CROP_EN_OFFSET 7
+#define CHNL_IMG_CTRL_CROP_EN_MASK 0x80
+#define CHNL_IMG_CTRL_CROP_EN_ENABLE 1
+#define CHNL_IMG_CTRL_VFLIP_EN_OFFSET 6
+#define CHNL_IMG_CTRL_VFLIP_EN_MASK 0x40
+#define CHNL_IMG_CTRL_VFLIP_EN_ENABLE 1
+#define CHNL_IMG_CTRL_HFLIP_EN_OFFSET 5
+#define CHNL_IMG_CTRL_HFLIP_EN_MASK 0x20
+#define CHNL_IMG_CTRL_HFLIP_EN_ENABLE 1
+#define CHNL_IMG_CTRL_YCBCR_MODE_OFFSET 3
+#define CHNL_IMG_CTRL_YCBCR_MODE_MASK 0x8
+#define CHNL_IMG_CTRL_YCBCR_MODE_ENABLE 1
+#define CHNL_IMG_CTRL_CSC_MODE_OFFSET 1
+#define CHNL_IMG_CTRL_CSC_MODE_MASK 0x6
+#define CHNL_IMG_CTRL_CSC_MODE_YUV2RGB 0
+#define CHNL_IMG_CTRL_CSC_MODE_YCBCR2RGB 1
+#define CHNL_IMG_CTRL_CSC_MODE_RGB2YUV 2
+#define CHNL_IMG_CTRL_CSC_MODE_RGB2YCBCR 3
+#define CHNL_IMG_CTRL_CSC_BYPASS_OFFSET 0
+#define CHNL_IMG_CTRL_CSC_BYPASS_MASK 0x1
+#define CHNL_IMG_CTRL_CSC_BYPASS_ENABLE 0x1
+
+/* Channel Output Buffer Control Register */
+#define CHNL_OUT_BUF_CTRL 0x8
+#define CHNL_OUT_BUF_CTRL_LOAD_BUF2_ADDR_OFFSET 15
+#define CHNL_OUT_BUF_CTRL_LOAD_BUF2_ADDR_MASK 0x8000
+#define CHNL_OUT_BUF_CTRL_LOAD_BUF1_ADDR_OFFSET 14
+#define CHNL_OUT_BUF_CTRL_LOAD_BUF1_ADDR_MASK 0x4000
+#define CHNL_OUT_BUF_CTRL_OFLW_PANIC_SET_THD_V_OFFSET 6
+#define CHNL_OUT_BUF_CTRL_OFLW_PANIC_SET_THD_V_MASK 0xC0
+#define CHNL_OUT_BUF_CTRL_OFLW_PANIC_SET_THD_V_NO_PANIC 0
+#define CHNL_OUT_BUF_CTRL_OFLW_PANIC_SET_THD_V_PANIC_25 1
+#define CHNL_OUT_BUF_CTRL_OFLW_PANIC_SET_THD_V_PANIC_50 2
+#define CHNL_OUT_BUF_CTRL_OFLW_PANIC_SET_THD_V_PANIC_75 3
+#define CHNL_OUT_BUF_CTRL_OFLW_PANIC_SET_THD_U_OFFSET 3
+#define CHNL_OUT_BUF_CTRL_OFLW_PANIC_SET_THD_U_MASK 0x18
+#define CHNL_OUT_BUF_CTRL_OFLW_PANIC_SET_THD_U_NO_PANIC 0
+#define CHNL_OUT_BUF_CTRL_OFLW_PANIC_SET_THD_U_PANIC_25 1
+#define CHNL_OUT_BUF_CTRL_OFLW_PANIC_SET_THD_U_PANIC_50 2
+#define CHNL_OUT_BUF_CTRL_OFLW_PANIC_SET_THD_U_PANIC_75 3
+#define CHNL_OUT_BUF_CTRL_OFLW_PANIC_SET_THD_Y_OFFSET 0
+#define CHNL_OUT_BUF_CTRL_OFLW_PANIC_SET_THD_Y_MASK 0x3
+#define CHNL_OUT_BUF_CTRL_OFLW_PANIC_SET_THD_Y_NO_PANIC 0
+#define CHNL_OUT_BUF_CTRL_OFLW_PANIC_SET_THD_Y_PANIC_25 1
+#define CHNL_OUT_BUF_CTRL_OFLW_PANIC_SET_THD_Y_PANIC_50 2
+#define CHNL_OUT_BUF_CTRL_OFLW_PANIC_SET_THD_Y_PANIC_75 3
+
+/* Channel Image Configuration */
+#define CHNL_IMG_CFG 0xC
+#define CHNL_IMG_CFG_HEIGHT_OFFSET 16
+#define CHNL_IMG_CFG_HEIGHT_MASK 0x1FFF0000
+#define CHNL_IMG_CFG_WIDTH_OFFSET 0
+#define CHNL_IMG_CFG_WIDTH_MASK 0x1FFF
+
+/* Channel Interrupt Enable Register */
+#define CHNL_IER 0x10
+#define CHNL_IER_MEM_RD_DONE_EN_OFFSET 31
+#define CHNL_IER_MEM_RD_DONE_EN_MASK 0x80000000
+#define CHNL_IER_MEM_RD_DONE_EN_ENABLE 1
+#define CHNL_IER_LINE_RCVD_EN_OFFSET 30
+#define CHNL_IER_LINE_RCVD_EN_MASK 0x40000000
+#define CHNL_IER_LINE_RCVD_EN_ENABLE 1
+#define CHNL_IER_FRM_RCVD_EN_OFFSET 29
+#define CHNL_IER_FRM_RCVD_EN_MASK 0x20000000
+#define CHNL_IER_FRM_RCVD_EN_ENABLE 1
+#define CHNL_IER_AXI_WR_ERR_V_EN_OFFSET 28
+#define CHNL_IER_AXI_WR_ERR_V_EN_MASK 0x10000000
+#define CHNL_IER_AXI_WR_ERR_V_EN_ENABLE 1
+#define CHNL_IER_AXI_WR_ERR_U_EN_OFFSET 27
+#define CHNL_IER_AXI_WR_ERR_U_EN_MASK 0x8000000
+#define CHNL_IER_AXI_WR_ERR_U_EN_ENABLE 1
+#define CHNL_IER_AXI_WR_ERR_Y_EN_OFFSET 26
+#define CHNL_IER_AXI_WR_ERR_Y_EN_MASK 0x4000000
+#define CHNL_IER_AXI_WR_ERR_Y_EN_ENABLE 1
+#define CHNL_IER_AXI_RD_ERR_EN_OFFSET 25
+#define CHNL_IER_AXI_RD_ERR_EN_MASK 0x2000000
+#define CHNL_IER_AXI_RD_ERR_EN_ENABLE 1
+#define CHNL_IER_OFLW_PANIC_V_BUF_EN_OFFSET 24
+#define CHNL_IER_OFLW_PANIC_V_BUF_EN_MASK 0x1000000
+#define CHNL_IER_OFLW_PANIC_V_BUF_EN_ENABLE 1
+#define CHNL_IER_EXCS_OFLW_V_BUF_EN_OFFSET 23
+#define CHNL_IER_EXCS_OFLW_V_BUF_EN_MASK 0x800000
+#define CHNL_IER_EXCS_OFLW_V_BUF_EN_ENABLE 1
+#define CHNL_IER_OFLW_V_BUF_EN_OFFSET 22
+#define CHNL_IER_OFLW_V_BUF_EN_MASK 0x400000
+#define CHNL_IER_OFLW_V_BUF_EN_ENABLE 1
+#define CHNL_IER_OFLW_PANIC_U_BUF_EN_OFFSET 21
+#define CHNL_IER_OFLW_PANIC_U_BUF_EN_MASK 0x200000
+#define CHNL_IER_OFLW_PANIC_U_BUF_EN_ENABLE 1
+#define CHNL_IER_EXCS_OFLW_U_BUF_EN_OFFSET 20
+#define CHNL_IER_EXCS_OFLW_U_BUF_EN_MASK 0x100000
+#define CHNL_IER_EXCS_OFLW_U_BUF_EN_ENABLE 1
+#define CHNL_IER_OFLW_U_BUF_EN_OFFSET 19
+#define CHNL_IER_OFLW_U_BUF_EN_MASK 0x80000
+#define CHNL_IER_OFLW_U_BUF_EN_ENABLE 1
+#define CHNL_IER_OFLW_PANIC_Y_BUF_EN_OFFSET 18
+#define CHNL_IER_OFLW_PANIC_Y_BUF_EN_MASK 0x40000
+#define CHNL_IER_OFLW_PANIC_Y_BUF_EN_ENABLE 1
+#define CHNL_IER_EXCS_OFLW_Y_BUF_EN_OFFSET 17
+#define CHNL_IER_EXCS_OFLW_Y_BUF_EN_MASK 0x20000
+#define CHNL_IER_EXCS_OFLW_Y_BUF_EN_ENABLE 1
+#define CHNL_IER_OFLW_Y_BUF_EN_OFFSET 16
+#define CHNL_IER_OFLW_Y_BUF_EN_MASK 0x10000
+#define CHNL_IER_OFLW_Y_BUF_EN_ENABLE 1
+
+/* Channel Status Register */
+#define CHNL_STS 0x14
+#define CHNL_STS_MEM_RD_DONE_OFFSET 31
+#define CHNL_STS_MEM_RD_DONE_MASK 0x80000000
+#define CHNL_STS_MEM_RD_DONE_ENABLE 1
+#define CHNL_STS_LINE_STRD_OFFSET 30
+#define CHNL_STS_LINE_STRD_MASK 0x40000000
+#define CHNL_STS_LINE_STRD_ENABLE 1
+#define CHNL_STS_FRM_STRD_OFFSET 29
+#define CHNL_STS_FRM_STRD_MASK 0x20000000
+#define CHNL_STS_FRM_STRD_ENABLE 1
+#define CHNL_STS_AXI_WR_ERR_V_OFFSET 28
+#define CHNL_STS_AXI_WR_ERR_V_MASK 0x10000000
+#define CHNL_STS_AXI_WR_ERR_V_ENABLE 1
+#define CHNL_STS_AXI_WR_ERR_U_OFFSET 27
+#define CHNL_STS_AXI_WR_ERR_U_MASK 0x8000000
+#define CHNL_STS_AXI_WR_ERR_U_ENABLE 1
+#define CHNL_STS_AXI_WR_ERR_Y_OFFSET 26
+#define CHNL_STS_AXI_WR_ERR_Y_MASK 0x4000000
+#define CHNL_STS_AXI_WR_ERR_Y_ENABLE 1
+#define CHNL_STS_AXI_RD_ERR_OFFSET 25
+#define CHNL_STS_AXI_RD_ERR_MASK 0x2000000
+#define CHNL_STS_AXI_RD_ERR_ENABLE 1
+#define CHNL_STS_OFLW_PANIC_V_BUF_OFFSET 24
+#define CHNL_STS_OFLW_PANIC_V_BUF_MASK 0x1000000
+#define CHNL_STS_OFLW_PANIC_V_BUF_ENABLE 1
+#define CHNL_STS_EXCS_OFLW_V_BUF_OFFSET 23
+#define CHNL_STS_EXCS_OFLW_V_BUF_MASK 0x800000
+#define CHNL_STS_EXCS_OFLW_V_BUF_ENABLE 1
+#define CHNL_STS_OFLW_V_BUF_OFFSET 22
+#define CHNL_STS_OFLW_V_BUF_MASK 0x400000
+#define CHNL_STS_OFLW_V_BUF_ENABLE 1
+#define CHNL_STS_OFLW_PANIC_U_BUF_OFFSET 21
+#define CHNL_STS_OFLW_PANIC_U_BUF_MASK 0x200000
+#define CHNL_STS_OFLW_PANIC_U_BUF_ENABLE 1
+#define CHNL_STS_EXCS_OFLW_U_BUF_OFFSET 20
+#define CHNL_STS_EXCS_OFLW_U_BUF_MASK 0x100000
+#define CHNL_STS_EXCS_OFLW_U_BUF_ENABLE 1
+#define CHNL_STS_OFLW_U_BUF_OFFSET 19
+#define CHNL_STS_OFLW_U_BUF_MASK 0x80000
+#define CHNL_STS_OFLW_U_BUF_ENABLE 1
+#define CHNL_STS_OFLW_PANIC_Y_BUF_OFFSET 18
+#define CHNL_STS_OFLW_PANIC_Y_BUF_MASK 0x40000
+#define CHNL_STS_OFLW_PANIC_Y_BUF_ENABLE 1
+#define CHNL_STS_EXCS_OFLW_Y_BUF_OFFSET 17
+#define CHNL_STS_EXCS_OFLW_Y_BUF_MASK 0x20000
+#define CHNL_STS_EXCS_OFLW_Y_BUF_ENABLE 1
+#define CHNL_STS_OFLW_Y_BUF_OFFSET 16
+#define CHNL_STS_OFLW_Y_BUF_MASK 0x10000
+#define CHNL_STS_OFLW_Y_BUF_ENABLE 1
+#define CHNL_STS_OFLW_BYTES_OFFSET 0
+#define CHNL_STS_OFLW_BYTES_MASK 0xFF
+
+/* Channel Scale Factor Register */
+#define CHNL_SCALE_FACTOR 0x18
+#define CHNL_SCALE_FACTOR_Y_SCALE_OFFSET 16
+#define CHNL_SCALE_FACTOR_Y_SCALE_MASK 0x3FFF0000
+#define CHNL_SCALE_FACTOR_X_SCALE_OFFSET 0
+#define CHNL_SCALE_FACTOR_X_SCALE_MASK 0x3FFF
+
+/* Channel Scale Offset Register */
+#define CHNL_SCALE_OFFSET 0x1C
+#define CHNL_SCALE_OFFSET_Y_SCALE_OFFSET 16
+#define CHNL_SCALE_OFFSET_Y_SCALE_MASK 0xFFF0000
+#define CHNL_SCALE_OFFSET_X_SCALE_OFFSET 0
+#define CHNL_SCALE_OFFSET_X_SCALE_MASK 0xFFF
+
+/* Channel Crop Upper Left Corner Coordinate Register */
+#define CHNL_CROP_ULC 0x20
+#define CHNL_CROP_ULC_X_OFFSET 16
+#define CHNL_CROP_ULC_X_MASK 0xFFF0000
+#define CHNL_CROP_ULC_Y_OFFSET 0
+#define CHNL_CROP_ULC_Y_MASK 0xFFF
+
+/* Channel Crop Lower Right Corner Coordinate Register */
+#define CHNL_CROP_LRC 0x24
+#define CHNL_CROP_LRC_X_OFFSET 16
+#define CHNL_CROP_LRC_X_MASK 0xFFF0000
+#define CHNL_CROP_LRC_Y_OFFSET 0
+#define CHNL_CROP_LRC_Y_MASK 0xFFF
+
+/* Channel Color Space Conversion Coefficient Register 0 */
+#define CHNL_CSC_COEFF0 0x28
+#define CHNL_CSC_COEFF0_A2_OFFSET 16
+#define CHNL_CSC_COEFF0_A2_MASK 0x7FF0000
+#define CHNL_CSC_COEFF0_A1_OFFSET 0
+#define CHNL_CSC_COEFF0_A1_MASK 0x7FF
+
+
+/* Channel Color Space Conversion Coefficient Register 1 */
+#define CHNL_CSC_COEFF1 0x2C
+#define CHNL_CSC_COEFF1_B1_OFFSET 16
+#define CHNL_CSC_COEFF1_B1_MASK 0x7FF0000
+#define CHNL_CSC_COEFF1_A3_OFFSET 0
+#define CHNL_CSC_COEFF1_A3_MASK 0x7FF
+
+/* Channel Color Space Conversion Coefficient Register 2 */
+#define CHNL_CSC_COEFF2 0x30
+#define CHNL_CSC_COEFF2_B3_OFFSET 16
+#define CHNL_CSC_COEFF2_B3_MASK 0x7FF0000
+#define CHNL_CSC_COEFF2_B2_OFFSET 0
+#define CHNL_CSC_COEFF2_B2_MASK 0x7FF
+
+/* Channel Color Space Conversion Coefficient Register 3 */
+#define CHNL_CSC_COEFF3 0x34
+#define CHNL_CSC_COEFF3_C2_OFFSET 16
+#define CHNL_CSC_COEFF3_C2_MASK 0x7FF0000
+#define CHNL_CSC_COEFF3_C1_OFFSET 0
+#define CHNL_CSC_COEFF3_C1_MASK 0x7FF
+
+/* Channel Color Space Conversion Coefficient Register 4 */
+#define CHNL_CSC_COEFF4 0x38
+#define CHNL_CSC_COEFF4_D1_OFFSET 16
+#define CHNL_CSC_COEFF4_D1_MASK 0x1FF0000
+#define CHNL_CSC_COEFF4_C3_OFFSET 0
+#define CHNL_CSC_COEFF4_C3_MASK 0x7FF
+
+/* Channel Color Space Conversion Coefficient Register 5 */
+#define CHNL_CSC_COEFF5 0x3C
+#define CHNL_CSC_COEFF5_D3_OFFSET 16
+#define CHNL_CSC_COEFF5_D3_MASK 0x1FF0000
+#define CHNL_CSC_COEFF5_D2_OFFSET 0
+#define CHNL_CSC_COEFF5_D2_MASK 0x1FF
+
+/* Channel Alpha Value Register for ROI 0 */
+#define CHNL_ROI_0_ALPHA 0x40
+#define CHNL_ROI_0_ALPHA_OFFSET 24
+#define CHNL_ROI_0_ALPHA_MASK 0xFF000000
+#define CHNL_ROI_0_ALPHA_EN_OFFSET 16
+#define CHNL_ROI_0_ALPHA_EN_MASK 0x10000
+
+/* Channel Upper Left Coordinate Register for ROI 0 */
+#define CHNL_ROI_0_ULC 0x44
+#define CHNL_ROI_0_ULC_X_OFFSET 16
+#define CHNL_ROI_0_ULC_X_MASK 0xFFF0000
+#define CHNL_ROI_0_ULC_Y_OFFSET 0
+#define CHNL_ROI_0_ULC_Y_MASK 0xFFF
+
+/* Channel Lower Right Coordinate Register for ROI 0 */
+#define CHNL_ROI_0_LRC 0x48
+#define CHNL_ROI_0_LRC_X_OFFSET 16
+#define CHNL_ROI_0_LRC_X_MASK 0xFFF0000
+#define CHNL_ROI_0_LRC_Y_OFFSET 0
+#define CHNL_ROI_0_LRC_Y_MASK 0xFFF
+
+/* Channel Alpha Value Register for ROI 1 */
+#define CHNL_ROI_1_ALPHA 0x4C
+#define CHNL_ROI_1_ALPHA_OFFSET 24
+#define CHNL_ROI_1_ALPHA_MASK 0xFF000000
+#define CHNL_ROI_1_ALPHA_EN_OFFSET 16
+#define CHNL_ROI_1_ALPHA_EN_MASK 0x10000
+
+/* Channel Upper Left Coordinate Register for ROI 1 */
+#define CHNL_ROI_1_ULC 0x50
+#define CHNL_ROI_1_ULC_X_OFFSET 16
+#define CHNL_ROI_1_ULC_X_MASK 0xFFF0000
+#define CHNL_ROI_1_ULC_Y_OFFSET 0
+#define CHNL_ROI_1_ULC_Y_MASK 0xFFF
+
+/* Channel Lower Right Coordinate Register for ROI 1 */
+#define CHNL_ROI_1_LRC 0x54
+#define CHNL_ROI_1_LRC_X_OFFSET 16
+#define CHNL_ROI_1_LRC_X_MASK 0xFFF0000
+#define CHNL_ROI_1_LRC_Y_OFFSET 0
+#define CHNL_ROI_1_LRC_Y_MASK 0xFFF
+
+/* Channel Alpha Value Register for ROI 2 */
+#define CHNL_ROI_2_ALPHA 0x58
+#define CHNL_ROI_2_ALPHA_OFFSET 24
+#define CHNL_ROI_2_ALPHA_MASK 0xFF000000
+#define CHNL_ROI_2_ALPHA_EN_OFFSET 16
+#define CHNL_ROI_2_ALPHA_EN_MASK 0x10000
+
+/* Channel Upper Left Coordinate Register for ROI 2 */
+#define CHNL_ROI_2_ULC 0x5C
+#define CHNL_ROI_2_ULC_X_OFFSET 16
+#define CHNL_ROI_2_ULC_X_MASK 0xFFF0000
+#define CHNL_ROI_2_ULC_Y_OFFSET 0
+#define CHNL_ROI_2_ULC_Y_MASK 0xFFF
+
+/* Channel Lower Right Coordinate Register for ROI 2 */
+#define CHNL_ROI_2_LRC 0x60
+#define CHNL_ROI_2_LRC_X_OFFSET 16
+#define CHNL_ROI_2_LRC_X_MASK 0xFFF0000
+#define CHNL_ROI_2_LRC_Y_OFFSET 0
+#define CHNL_ROI_2_LRC_Y_MASK 0xFFF
+
+/* Channel Alpha Value Register for ROI 3 */
+#define CHNL_ROI_3_ALPHA 0x64
+#define CHNL_ROI_3_ALPHA_OFFSET 24
+#define CHNL_ROI_3_ALPHA_MASK 0xFF000000
+#define CHNL_ROI_3_ALPHA_EN_OFFSET 16
+#define CHNL_ROI_3_ALPHA_EN_MASK 0x10000
+
+/* Channel Upper Left Coordinate Register for ROI 3 */
+#define CHNL_ROI_3_ULC 0x68
+#define CHNL_ROI_3_ULC_X_OFFSET 16
+#define CHNL_ROI_3_ULC_X_MASK 0xFFF0000
+#define CHNL_ROI_3_ULC_Y_OFFSET 0
+#define CHNL_ROI_3_ULC_Y_MASK 0xFFF
+
+/* Channel Lower Right Coordinate Register for ROI 3 */
+#define CHNL_ROI_3_LRC 0x6C
+#define CHNL_ROI_3_LRC_X_OFFSET 16
+#define CHNL_ROI_3_LRC_X_MASK 0xFFF0000
+#define CHNL_ROI_3_LRC_Y_OFFSET 0
+#define CHNL_ROI_3_LRC_Y_MASK 0xFFF
+
+/* Channel RGB or Luma (Y) Output Buffer 1 Address */
+#define CHNL_OUT_BUF1_ADDR_Y 0x70
+
+/* Channel Chroma (U/Cb/UV/CbCr) Output Buffer 1 Address */
+#define CHNL_OUT_BUF1_ADDR_U 0x74
+
+/* Channel Chroma (V/Cr) Output Buffer 1 Address */
+#define CHNL_OUT_BUF1_ADDR_V 0x78
+
+/* Channel Output Buffer Pitch */
+#define CHNL_OUT_BUF_PITCH 0x7C
+#define CHNL_OUT_BUF_PITCH_LINE_PITCH_OFFSET 0
+#define CHNL_OUT_BUF_PITCH_LINE_PITCH_MASK 0xFFFF
+
+/* Channel Input Buffer Address */
+#define CHNL_IN_BUF_ADDR 0x80
+
+/* Channel Input Buffer Pitch */
+#define CHNL_IN_BUF_PITCH 0x84
+#define CHNL_IN_BUF_PITCH_FRM_PITCH_OFFSET 16
+#define CHNL_IN_BUF_PITCH_FRM_PITCH_MASK 0xFFFF0000
+#define CHNL_IN_BUF_PITCH_LINE_PITCH_OFFSET 0
+#define CHNL_IN_BUF_PITCH_LINE_PITCH_MASK 0xFFFF
+
+/* Channel Memory Read Control */
+#define CHNL_MEM_RD_CTRL 0x88
+#define CHNL_MEM_RD_CTRL_IMG_TYPE_OFFSET 28
+#define CHNL_MEM_RD_CTRL_IMG_TYPE_MASK 0xF0000000
+#define CHNL_MEM_RD_CTRL_READ_MEM_OFFSET 0
+#define CHNL_MEM_RD_CTRL_READ_MEM_MASK 1
+#define CHNL_MEM_RD_CTRL_READ_MEM_ENABLE 1
+
+/* Channel RGB or Luma (Y) Output Buffer 2 Address */
+#define CHNL_OUT_BUF2_ADDR_Y 0x8C
+
+/* Channel Chroma (U/Cb/UV/CbCr) Output Buffer 2 Address */
+#define CHNL_OUT_BUF2_ADDR_U 0x90
+
+/* Channel Chroma (V/Cr) Output Buffer 2 Address */
+#define CHNL_OUT_BUF2_ADDR_V 0x94
+
+/* Channel scale image config */
+#define CHNL_SCL_IMG_CFG 0x98
+#define CHNL_SCL_IMG_CFG_HEIGHT_OFFSET 16
+#define CHNL_SCL_IMG_CFG_HEIGHT_MASK 0x1FFF0000
+#define CHNL_SCL_IMG_CFG_WIDTH_OFFSET 0
+#define CHNL_SCL_IMG_CFG_WIDTH_MASK 0x1FFF
+
+enum isi_csi_coeff {
+ YUV2RGB = 0,
+ RGB2YUV,
+};
+
+
+void mxc_isi_channel_init(struct mxc_isi_dev *mxc_isi);
+void mxc_isi_channel_deinit(struct mxc_isi_dev *mxc_isi);
+void mxc_isi_channel_config(struct mxc_isi_dev *mxc_isi);
+void mxc_isi_channel_enable(struct mxc_isi_dev *mxc_isi);
+void mxc_isi_channel_disable(struct mxc_isi_dev *mxc_isi);
+void mxc_isi_channel_set_outbuf(struct mxc_isi_dev *mxc_isi,
+ struct mxc_isi_buffer *buf);
+void mxc_isi_cap_frame_write_done(struct mxc_isi_dev *mxc_isi);
+void mxc_isi_m2m_frame_write_done(struct mxc_isi_dev *mxc_isi);
+void mxc_isi_m2m_frame_read_done(struct mxc_isi_dev *mxc_isi);
+void mxc_isi_channel_set_deinterlace(struct mxc_isi_dev *mxc_isi);
+void mxc_isi_channel_sw_reset(struct mxc_isi_dev *mxc_isi);
+void mxc_isi_channel_hw_reset(struct mxc_isi_dev *mxc_isi);
+void mxc_isi_channel_source_config(struct mxc_isi_dev *mxc_isi);
+void mxc_isi_channel_set_flip(struct mxc_isi_dev *mxc_isi);
+void mxc_isi_channel_set_csc(struct mxc_isi_dev *mxc_isi);
+void mxc_isi_channel_set_alpha_roi0(struct mxc_isi_dev *mxc_isi,
+ struct v4l2_rect *rect);
+void mxc_isi_channel_set_alpha(struct mxc_isi_dev *mxc_isi);
+void mxc_isi_channel_set_chain_buf(struct mxc_isi_dev *mxc_isi);
+void mxc_isi_channel_set_deinterlace(struct mxc_isi_dev *mxc_isi);
+void mxc_isi_channel_set_crop(struct mxc_isi_dev *mxc_isi);
+void mxc_isi_channel_set_memory_image(struct mxc_isi_dev *mxc_isi);
+void mxc_isi_channel_set_scaler(struct mxc_isi_dev *mxc_isi);
+
+void mxc_isi_m2m_channel_init(struct mxc_isi_dev *mxc_isi);
+void mxc_isi_m2m_channel_config(struct mxc_isi_dev *mxc_isi);
+void mxc_isi_m2m_channel_enable(struct mxc_isi_dev *mxc_isi);
+void mxc_isi_m2m_channel_disable(struct mxc_isi_dev *mxc_isi);
+void mxc_isi_m2m_config_src(struct mxc_isi_dev *mxc_isi);
+void mxc_isi_m2m_config_dst(struct mxc_isi_dev *mxc_isi);
+void mxc_isi_m2m_start_read(struct mxc_isi_dev *mxc_isi);
+
+void mxc_isi_clean_irq_status(struct mxc_isi_dev *mxc_isi, u32 val);
+u32 mxc_isi_get_irq_status(struct mxc_isi_dev *mxc_isi);
+void mxc_isi_clean_registers(struct mxc_isi_dev *mxc_isi);
+void mxc_isi_enable_irq(struct mxc_isi_dev *mxc_isi);
+void mxc_isi_disable_irq(struct mxc_isi_dev *mxc_isi);
+void mxc_isi_channel_set_m2m_out_addr(struct mxc_isi_dev *mxc_isi,
+ struct mxc_isi_buffer *buf);
+void mxc_isi_channel_set_m2m_src_addr(struct mxc_isi_dev *mxc_isi,
+ struct mxc_isi_buffer *buf);
+
+void dump_isi_regs(struct mxc_isi_dev *mxc_isi);
+#endif /* MXC_ISI_HW_H_ */
diff --git a/drivers/media/platform/imx8/mxc-isi-m2m.c b/drivers/media/platform/imx8/mxc-isi-m2m.c
new file mode 100644
index 000000000000..709ea0a19887
--- /dev/null
+++ b/drivers/media/platform/imx8/mxc-isi-m2m.c
@@ -0,0 +1,1117 @@
+/*
+ * Copyright 2017-2018 NXP
+ */
+/*
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/bug.h>
+#include <linux/interrupt.h>
+#include <linux/device.h>
+#include <linux/pm_runtime.h>
+#include <linux/list.h>
+#include <linux/slab.h>
+#include <linux/of_graph.h>
+
+#include <linux/videodev2.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-ioctl.h>
+#include <media/v4l2-mem2mem.h>
+#include <media/videobuf2-core.h>
+#include <media/videobuf2-dma-contig.h>
+#include <soc/imx8/sc/sci.h>
+
+#include "mxc-isi-core.h"
+#include "mxc-isi-hw.h"
+#include "mxc-media-dev.h"
+
+#define to_isi_buffer(x) \
+ container_of((x), struct mxc_isi_buffer, v4l2_buf)
+
+#define file_to_ctx(file) \
+ container_of(file->private_data, struct mxc_isi_ctx, fh);
+
+extern struct mxc_isi_fmt mxc_isi_out_formats[9];
+
+struct mxc_isi_fmt mxc_isi_input_formats[] = {
+ /* Pixel link input format */
+ {
+ .name = "XBGR32",
+ .fourcc = V4L2_PIX_FMT_XBGR32,
+ .depth = { 32 },
+ .color = MXC_ISI_M2M_IN_FMT_XRGB8,
+ .memplanes = 1,
+ .colplanes = 1,
+ }, {
+ .name = "RGB565",
+ .fourcc = V4L2_PIX_FMT_RGB565,
+ .depth = { 16 },
+ .color = MXC_ISI_M2M_IN_FMT_RGB565,
+ .memplanes = 1,
+ .colplanes = 1,
+ }, {
+ .name = "YUV32 (X-Y-U-V)",
+ .fourcc = V4L2_PIX_FMT_YUV32,
+ .depth = { 32 },
+ .color = MXC_ISI_M2M_IN_FMT_YUV444_1P8P,
+ .memplanes = 1,
+ .colplanes = 1,
+ }, {
+ .name = "YUV16 (X-Y-U-V)",
+ .fourcc = V4L2_PIX_FMT_YUYV,
+ .depth = { 16 },
+ .color = MXC_ISI_M2M_IN_FMT_YUV422_1P8P,
+ .memplanes = 1,
+ .colplanes = 1,
+ }, {
+ .name = "RGBA (R-G-B-A)",
+ .fourcc = V4L2_PIX_FMT_RGBA,
+ .depth = { 32 },
+ .color = MXC_ISI_M2M_IN_FMT_XBGR8,
+ .memplanes = 1,
+ .colplanes = 1,
+ }
+};
+
+static struct mxc_isi_buffer *vb2_to_isi_buffer(struct vb2_buffer *vb2)
+{
+ struct vb2_v4l2_buffer *v4l2_buf;
+ struct mxc_isi_buffer *buf;
+
+ v4l2_buf = to_vb2_v4l2_buffer(vb2);
+ buf = to_isi_buffer(v4l2_buf);
+
+ return buf;
+}
+
+static struct v4l2_m2m_buffer *to_v4l2_m2m_buffer(struct vb2_buffer *vb2)
+{
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb2);
+ struct v4l2_m2m_buffer *b;
+
+ b = container_of(vbuf, struct v4l2_m2m_buffer, vb);
+ return b;
+}
+
+static void mxc_isi_m2m_device_run(void *priv)
+{
+ struct mxc_isi_ctx *mxc_ctx = priv;
+ struct mxc_isi_dev *mxc_isi = mxc_ctx->isi_dev;
+ struct v4l2_fh *fh = &mxc_ctx->fh;
+ struct vb2_buffer *src_vb2;
+ struct mxc_isi_buffer *src_buf;
+ unsigned long flags;
+
+ dev_dbg(&mxc_isi->pdev->dev, "%s enter\n", __func__);
+
+ spin_lock_irqsave(&mxc_isi->slock, flags);
+
+ /* SRC */
+ src_vb2 = v4l2_m2m_next_src_buf(fh->m2m_ctx);
+ if (!src_vb2) {
+ dev_err(&mxc_isi->pdev->dev, "Null src buf\n");
+ goto unlock;
+ }
+
+ src_buf = vb2_to_isi_buffer(src_vb2);
+
+
+ mxc_isi_channel_set_m2m_src_addr(mxc_isi, src_buf);
+ mxc_isi_m2m_channel_enable(mxc_isi);
+
+unlock:
+ spin_unlock_irqrestore(&mxc_isi->slock, flags);
+}
+
+static int mxc_isi_m2m_job_ready(void *priv)
+{
+ struct mxc_isi_ctx *mxc_ctx = priv;
+ struct mxc_isi_dev *mxc_isi = mxc_ctx->isi_dev;
+ struct v4l2_fh *fh = &mxc_ctx->fh;
+ unsigned int num_src_bufs_ready;
+ unsigned int num_dst_bufs_ready;
+ unsigned long flags;
+
+ dev_dbg(&mxc_isi->pdev->dev, "%s\n", __func__);
+
+ spin_lock_irqsave(&mxc_isi->slock, flags);
+ num_src_bufs_ready = v4l2_m2m_num_src_bufs_ready(fh->m2m_ctx);
+ num_dst_bufs_ready = v4l2_m2m_num_dst_bufs_ready(fh->m2m_ctx);
+ spin_unlock_irqrestore(&mxc_isi->slock, flags);
+
+ if (num_src_bufs_ready >= 1 && num_dst_bufs_ready >= 1)
+ return 1;
+ return 0;
+}
+
+static void mxc_isi_m2m_job_abort(void *priv)
+{
+ struct mxc_isi_ctx *mxc_ctx = priv;
+ struct mxc_isi_dev *mxc_isi = mxc_ctx->isi_dev;
+
+ mxc_isi->m2m.aborting = 1;
+ dev_dbg(&mxc_isi->pdev->dev, "Abort requested\n");
+}
+
+static struct v4l2_m2m_ops mxc_isi_m2m_ops = {
+ .device_run = mxc_isi_m2m_device_run,
+ .job_ready = mxc_isi_m2m_job_ready,
+ .job_abort = mxc_isi_m2m_job_abort,
+};
+
+static int m2m_vb2_queue_setup(struct vb2_queue *q,
+ unsigned int *num_buffers, unsigned int *num_planes,
+ unsigned int sizes[], struct device *alloc_devs[])
+{
+ struct mxc_isi_ctx *mxc_ctx = vb2_get_drv_priv(q);
+ struct mxc_isi_dev *mxc_isi = mxc_ctx->isi_dev;
+ struct device *dev = &mxc_isi->pdev->dev;
+ struct mxc_isi_frame *frame;
+ struct mxc_isi_fmt *fmt;
+ unsigned long wh;
+ int i;
+
+ dev_dbg(&mxc_isi->pdev->dev, "%s\n", __func__);
+
+ if (q->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
+ if (*num_buffers < 3) {
+ dev_err(dev, "%s at least need 3 buffer\n", __func__);
+ return -EINVAL;
+ }
+ frame = &mxc_isi->m2m.dst_f;
+ } else {
+ if (*num_buffers < 1) {
+ dev_err(dev, "%s at least need one buffer\n", __func__);
+ return -EINVAL;
+ }
+ frame = &mxc_isi->m2m.src_f;
+ }
+
+ fmt = frame->fmt;
+ if (fmt == NULL)
+ return -EINVAL;
+
+ for (i = 0; i < fmt->memplanes; i++)
+ alloc_devs[i] = &mxc_isi->pdev->dev;
+
+ *num_planes = fmt->memplanes;
+ wh = frame->width * frame->height;
+
+ for (i = 0; i < fmt->memplanes; i++) {
+ unsigned int size = (wh * fmt->depth[i]) >> 3;
+
+ if (i == 1 && fmt->fourcc == V4L2_PIX_FMT_NV12)
+ size >>= 1;
+ sizes[i] = max_t(u32, size, frame->sizeimage[i]);
+
+ dev_dbg(&mxc_isi->pdev->dev, "%s, buf_n=%d, planes[%d]->size=%d\n",
+ __func__, *num_buffers, i, sizes[i]);
+ }
+
+ return 0;
+}
+
+static int m2m_vb2_buffer_prepare(struct vb2_buffer *vb2)
+{
+ struct vb2_queue *vq = vb2->vb2_queue;
+ struct mxc_isi_ctx *mxc_ctx = vb2_get_drv_priv(vq);
+ struct mxc_isi_dev *mxc_isi = mxc_ctx->isi_dev;
+ struct mxc_isi_frame *frame;
+ int i;
+
+ if (vq->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
+ frame = &mxc_isi->m2m.dst_f;
+ else
+ frame = &mxc_isi->m2m.src_f;
+
+ if (frame == NULL)
+ return -EINVAL;
+
+ for (i = 0; i < frame->fmt->memplanes; i++) {
+ unsigned long size = frame->sizeimage[i];
+
+ if (vb2_plane_size(vb2, i) < size) {
+ dev_err(&mxc_isi->pdev->dev,
+ "User buffer too small (%ld < %ld)\n",
+ vb2_plane_size(vb2, i), size);
+ return -EINVAL;
+ }
+ vb2_set_plane_payload(vb2, i, size);
+ }
+
+ return 0;
+}
+
+static void m2m_vb2_buffer_queue(struct vb2_buffer *vb2)
+{
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb2);
+ struct mxc_isi_ctx *mxc_ctx = vb2_get_drv_priv(vb2->vb2_queue);
+ struct v4l2_fh *fh = &mxc_ctx->fh;
+
+ v4l2_m2m_buf_queue(fh->m2m_ctx, vbuf);
+}
+
+static int m2m_vb2_start_streaming(struct vb2_queue *q, unsigned int count)
+{
+ struct mxc_isi_ctx *mxc_ctx = vb2_get_drv_priv(q);
+ struct mxc_isi_dev *mxc_isi = mxc_ctx->isi_dev;
+ struct v4l2_fh *fh = &mxc_ctx->fh;
+ struct vb2_buffer *dst_vb2;
+ struct v4l2_m2m_buffer *b;
+ struct mxc_isi_buffer *dst_buf;
+ unsigned long flags;
+
+ dev_dbg(&mxc_isi->pdev->dev, "%s\n", __func__);
+
+ if (V4L2_TYPE_IS_OUTPUT(q->type))
+ return 0;
+
+ if (count < 2) {
+ dev_err(&mxc_isi->pdev->dev, "Need to at leas 2 buffers\n");
+ return -EINVAL;
+ }
+
+ spin_lock_irqsave(&mxc_isi->slock, flags);
+
+ /* BUF1 */
+ dst_vb2 = v4l2_m2m_next_dst_buf(fh->m2m_ctx);
+ if (!dst_vb2) {
+ dev_err(&mxc_isi->pdev->dev, "%d: Null dst buf\n", __LINE__);
+ goto unlock;
+ }
+ dst_vb2->state = VB2_BUF_STATE_ACTIVE;
+ dst_buf = vb2_to_isi_buffer(dst_vb2);
+ dst_buf->v4l2_buf.sequence = 0;
+ mxc_isi_channel_set_m2m_out_addr(mxc_isi, dst_buf);
+ v4l2_m2m_dst_buf_remove(fh->m2m_ctx);
+ b = to_v4l2_m2m_buffer(dst_vb2);
+ list_add_tail(&b->list, &mxc_isi->m2m.out_active);
+
+ /* BUF2 */
+ dst_vb2 = v4l2_m2m_next_dst_buf(fh->m2m_ctx);
+ if (!dst_vb2) {
+ dev_err(&mxc_isi->pdev->dev, "%d: Null dst buf\n", __LINE__);
+ goto unlock;
+ }
+ dst_vb2->state = VB2_BUF_STATE_ACTIVE;
+ dst_buf = vb2_to_isi_buffer(dst_vb2);
+ dst_buf->v4l2_buf.sequence = 1;
+ mxc_isi_channel_set_m2m_out_addr(mxc_isi, dst_buf);
+ v4l2_m2m_dst_buf_remove(fh->m2m_ctx);
+ b = to_v4l2_m2m_buffer(dst_vb2);
+ list_add_tail(&b->list, &mxc_isi->m2m.out_active);
+
+ mxc_isi->m2m.frame_count = 1;
+ mxc_isi->m2m.aborting = 0;
+unlock:
+ spin_unlock_irqrestore(&mxc_isi->slock, flags);
+
+ return 0;
+}
+
+static void m2m_vb2_stop_streaming(struct vb2_queue *q)
+{
+ struct mxc_isi_ctx *mxc_ctx = vb2_get_drv_priv(q);
+ struct mxc_isi_dev *mxc_isi = mxc_ctx->isi_dev;
+ struct vb2_v4l2_buffer *vb2;
+ struct mxc_isi_buffer *buf;
+ unsigned long flags;
+
+ spin_lock_irqsave(&mxc_isi->slock, flags);
+
+ while ((vb2 = v4l2_m2m_src_buf_remove(mxc_ctx->fh.m2m_ctx)) != NULL)
+ v4l2_m2m_buf_done(vb2, VB2_BUF_STATE_ERROR);
+
+ while ((vb2 = v4l2_m2m_dst_buf_remove(mxc_ctx->fh.m2m_ctx)) != NULL)
+ v4l2_m2m_buf_done(vb2, VB2_BUF_STATE_ERROR);
+
+ while (!list_empty(&mxc_isi->m2m.out_active)) {
+ buf = list_entry(mxc_isi->m2m.out_active.next, struct mxc_isi_buffer, list);
+ list_del(&buf->list);
+ vb2_buffer_done(&buf->v4l2_buf.vb2_buf, VB2_BUF_STATE_ERROR);
+ }
+
+ INIT_LIST_HEAD(&mxc_isi->isi_cap.out_active);
+
+ spin_unlock_irqrestore(&mxc_isi->slock, flags);
+}
+
+static struct vb2_ops mxc_m2m_vb2_qops = {
+ .queue_setup = m2m_vb2_queue_setup,
+ .buf_prepare = m2m_vb2_buffer_prepare,
+ .buf_queue = m2m_vb2_buffer_queue,
+ .wait_prepare = vb2_ops_wait_prepare,
+ .wait_finish = vb2_ops_wait_finish,
+ .start_streaming = m2m_vb2_start_streaming,
+ .stop_streaming = m2m_vb2_stop_streaming,
+};
+
+
+static int mxc_m2m_queue_init(void *priv, struct vb2_queue *src_vq,
+ struct vb2_queue *dst_vq)
+{
+ struct mxc_isi_ctx *mxc_ctx = priv;
+ struct mxc_isi_dev *mxc_isi = mxc_ctx->isi_dev;
+ int ret;
+
+ src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+ src_vq->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF;
+ src_vq->drv_priv = mxc_ctx;
+ src_vq->buf_struct_size = sizeof(struct mxc_isi_buffer);
+ src_vq->ops = &mxc_m2m_vb2_qops;
+ src_vq->mem_ops = &vb2_dma_contig_memops;
+ src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
+ src_vq->lock = &mxc_isi->m2m_lock;
+ src_vq->dev = &mxc_isi->pdev->dev;
+
+ ret = vb2_queue_init(src_vq);
+ if (ret)
+ return ret;
+
+ dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+ dst_vq->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF;
+ dst_vq->drv_priv = mxc_ctx;
+ dst_vq->buf_struct_size = sizeof(struct mxc_isi_buffer);
+ dst_vq->ops = &mxc_m2m_vb2_qops;
+ dst_vq->mem_ops = &vb2_dma_contig_memops;
+ dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
+ dst_vq->lock = &mxc_isi->m2m_lock;
+ dst_vq->dev = &mxc_isi->pdev->dev;
+
+ ret = vb2_queue_init(dst_vq);
+ return ret;
+}
+
+static int mxc_isi_m2m_open(struct file *file)
+{
+ struct video_device *vdev = video_devdata(file);
+ struct mxc_isi_dev *mxc_isi = video_drvdata(file);
+ struct mxc_isi_m2m_dev *isi_m2m = &mxc_isi->m2m;
+ struct device *dev = &mxc_isi->pdev->dev;
+ struct mxc_isi_ctx *mxc_ctx = NULL;
+ int ret = 0;
+
+ dev_dbg(dev, "%s, ISI%d\n", __func__, mxc_isi->id);
+
+ if (atomic_read(&mxc_isi->open_count) > 0) {
+ dev_err(dev, "%s: ISI channel[%d] is busy\n", __func__, mxc_isi->id);
+ return -EBUSY;
+ }
+
+ if (mutex_lock_interruptible(&mxc_isi->m2m_lock))
+ return -ERESTARTSYS;
+ mxc_ctx = kzalloc(sizeof(*mxc_ctx), GFP_KERNEL);
+ if (!mxc_ctx) {
+ ret = -ENOMEM;
+ goto unlock;
+ }
+
+ mxc_ctx->isi_dev = mxc_isi;
+
+ v4l2_fh_init(&mxc_ctx->fh, vdev);
+ file->private_data = &mxc_ctx->fh;
+
+ mxc_ctx->fh.m2m_ctx =
+ v4l2_m2m_ctx_init(isi_m2m->m2m_dev, mxc_ctx, mxc_m2m_queue_init);
+ if (IS_ERR(mxc_ctx->fh.m2m_ctx)) {
+ dev_err(dev, "%s v4l2_m2m_ctx_init fail\n", __func__);
+ ret = PTR_ERR(mxc_ctx->fh.m2m_ctx);
+ v4l2_fh_exit(&mxc_ctx->fh);
+ kfree(mxc_ctx);
+ goto unlock;
+ }
+ v4l2_fh_add(&mxc_ctx->fh);
+
+ pm_runtime_get_sync(dev);
+ if (atomic_inc_return(&mxc_isi->open_count) == 1)
+ mxc_isi_m2m_channel_init(mxc_isi);
+
+ mxc_isi->is_m2m = 1;
+unlock:
+ mutex_unlock(&mxc_isi->m2m_lock);
+ return ret;
+}
+
+static int mxc_isi_m2m_release(struct file *file)
+{
+ struct mxc_isi_dev *mxc_isi = video_drvdata(file);
+ struct device *dev = &mxc_isi->pdev->dev;
+ struct mxc_isi_ctx *mxc_ctx = file_to_ctx(file);
+
+ dev_dbg(&mxc_isi->pdev->dev, "%s\n", __func__);
+
+ v4l2_fh_del(&mxc_ctx->fh);
+ v4l2_fh_exit(&mxc_ctx->fh);
+
+ if (mutex_is_locked(&mxc_isi->m2m_lock))
+ mutex_unlock(&mxc_isi->m2m_lock);
+
+ mutex_lock(&mxc_isi->m2m_lock);
+ v4l2_m2m_ctx_release(mxc_ctx->fh.m2m_ctx);
+ mutex_unlock(&mxc_isi->m2m_lock);
+
+ kfree(mxc_ctx);
+ if (atomic_dec_and_test(&mxc_isi->open_count))
+ mxc_isi_channel_deinit(mxc_isi);
+
+ mxc_isi->is_m2m = 0;
+ pm_runtime_put(dev);
+ return 0;
+}
+
+static const struct v4l2_file_operations mxc_isi_m2m_fops = {
+ .owner = THIS_MODULE,
+ .open = mxc_isi_m2m_open,
+ .release = mxc_isi_m2m_release,
+ .poll = v4l2_m2m_fop_poll,
+ .unlocked_ioctl = video_ioctl2,
+ .mmap = v4l2_m2m_fop_mmap,
+};
+
+static int mxc_isi_m2m_querycap(struct file *file, void *priv,
+ struct v4l2_capability *cap)
+{
+ struct mxc_isi_dev *mxc_isi = video_drvdata(file);
+
+ strlcpy(cap->driver, MXC_ISI_DRIVER_NAME, sizeof(cap->driver));
+ strlcpy(cap->card, MXC_ISI_DRIVER_NAME, sizeof(cap->card));
+ snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s.%d",
+ dev_name(&mxc_isi->pdev->dev), mxc_isi->id);
+
+ cap->device_caps = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_M2M_MPLANE |
+ V4L2_CAP_VIDEO_CAPTURE_MPLANE | V4L2_CAP_VIDEO_OUTPUT_MPLANE;
+ cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
+
+ return 0;
+}
+
+static int mxc_isi_m2m_enum_fmt_vid_out(struct file *file, void *priv,
+ struct v4l2_fmtdesc *f)
+{
+ struct mxc_isi_dev *mxc_isi = video_drvdata(file);
+ struct mxc_isi_fmt *fmt;
+
+ dev_dbg(&mxc_isi->pdev->dev, "%s\n", __func__);
+ if (f->index >= (int)ARRAY_SIZE(mxc_isi_input_formats))
+ return -EINVAL;
+
+ fmt = &mxc_isi_input_formats[f->index];
+ strncpy(f->description, fmt->name, sizeof(f->description) - 1);
+
+ f->pixelformat = fmt->fourcc;
+
+ return 0;
+}
+
+static int mxc_isi_m2m_enum_fmt_vid_cap(struct file *file, void *priv,
+ struct v4l2_fmtdesc *f)
+{
+ struct mxc_isi_dev *mxc_isi = video_drvdata(file);
+ struct mxc_isi_fmt *fmt;
+
+ dev_dbg(&mxc_isi->pdev->dev, "%s\n", __func__);
+ if (f->index >= (int)ARRAY_SIZE(mxc_isi_out_formats))
+ return -EINVAL;
+
+ fmt = &mxc_isi_out_formats[f->index];
+ strncpy(f->description, fmt->name, sizeof(f->description) - 1);
+
+ f->pixelformat = fmt->fourcc;
+
+ return 0;
+}
+
+static int mxc_isi_m2m_try_fmt_vid_out(struct file *file, void *fh,
+ struct v4l2_format *f)
+{
+ struct mxc_isi_dev *mxc_isi = video_drvdata(file);
+ struct v4l2_pix_format_mplane *pix = &f->fmt.pix_mp;
+ struct mxc_isi_fmt *fmt = NULL;
+ int i;
+
+ dev_dbg(&mxc_isi->pdev->dev, "%s\n", __func__);
+
+ if (f->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
+ return -EINVAL;
+
+ for (i = 0; i < ARRAY_SIZE(mxc_isi_input_formats); i++) {
+ fmt = &mxc_isi_input_formats[i];
+ if (fmt->fourcc == pix->pixelformat)
+ break;
+ }
+
+ if (i >= ARRAY_SIZE(mxc_isi_input_formats)) {
+ v4l2_err(mxc_isi->v4l2_dev, "%s, format is not support!\n", __func__);
+ return -EINVAL;
+ }
+
+ if (pix->width <= 0 || pix->height <= 0) {
+ v4l2_err(mxc_isi->v4l2_dev, "%s, width %d, height %d is not valid\n"
+ , __func__, pix->width, pix->height);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int mxc_isi_m2m_try_fmt_vid_cap(struct file *file, void *fh,
+ struct v4l2_format *f)
+{
+ struct mxc_isi_dev *mxc_isi = video_drvdata(file);
+ struct v4l2_pix_format_mplane *pix = &f->fmt.pix_mp;
+ struct mxc_isi_fmt *fmt = NULL;
+ int i;
+
+ dev_dbg(&mxc_isi->pdev->dev, "%s\n", __func__);
+
+ if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
+ return -EINVAL;
+
+ for (i = 0; i < ARRAY_SIZE(mxc_isi_out_formats); i++) {
+ fmt = &mxc_isi_out_formats[i];
+ if (fmt->fourcc == pix->pixelformat)
+ break;
+ }
+
+ if (i >= ARRAY_SIZE(mxc_isi_out_formats)) {
+ v4l2_err(mxc_isi->v4l2_dev, "%s, format is not support!\n", __func__);
+ return -EINVAL;
+ }
+
+ if (pix->width <= 0 || pix->height <= 0) {
+ v4l2_err(mxc_isi->v4l2_dev, "%s, width %d, height %d is not valid\n"
+ , __func__, pix->width, pix->height);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int mxc_isi_m2m_s_fmt_vid_out(struct file *file, void *priv,
+ struct v4l2_format *f)
+{
+ struct mxc_isi_dev *mxc_isi = video_drvdata(file);
+ struct v4l2_fh *fh = file->private_data;
+ struct mxc_isi_frame *frame = &mxc_isi->m2m.src_f;
+ struct v4l2_pix_format_mplane *pix = &f->fmt.pix_mp;
+ struct mxc_isi_fmt *fmt;
+ struct vb2_queue *vq;
+ int bpl, i;
+
+ dev_dbg(&mxc_isi->pdev->dev, "%s\n", __func__);
+
+ if (f->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
+ return -EINVAL;
+
+ vq = v4l2_m2m_get_vq(fh->m2m_ctx, f->type);
+ if (!vq)
+ return -EINVAL;
+
+ if (vb2_is_busy(vq)) {
+ dev_err(&mxc_isi->pdev->dev, "queue busy\n");
+ return -EBUSY;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(mxc_isi_input_formats); i++) {
+ fmt = &mxc_isi_input_formats[i];
+ if (pix && fmt->fourcc == pix->pixelformat)
+ break;
+ }
+
+ if (i >= ARRAY_SIZE(mxc_isi_input_formats)) {
+ dev_dbg(&mxc_isi->pdev->dev, "%s, format is not support!\n", __func__);
+ return -EINVAL;
+ }
+
+ /* update out put frame size and formate */
+ if (pix->height <= 0 || pix->width <= 0)
+ return -EINVAL;
+
+ frame->fmt = fmt;
+ frame->height = pix->height;
+ frame->width = pix->width;
+
+ pix->num_planes = fmt->memplanes;
+ for (i = 0; i < pix->num_planes; i++) {
+ bpl = pix->plane_fmt[i].bytesperline;
+
+ if ((bpl == 0) || (bpl / (fmt->depth[i] >> 3)) < pix->width)
+ pix->plane_fmt[i].bytesperline =
+ (pix->width * fmt->depth[i]) >> 3;
+
+ if (pix->plane_fmt[i].sizeimage == 0)
+ pix->plane_fmt[i].sizeimage = (pix->width * pix->height *
+ fmt->depth[i] >> 3);
+ }
+
+ frame->bytesperline[0] = frame->width * frame->fmt->depth[0] / 8;
+ frame->sizeimage[0] = frame->height * frame->bytesperline[0];
+
+ set_frame_bounds(frame, pix->width, pix->height);
+ mxc_isi_m2m_config_src(mxc_isi);
+
+ return 0;
+}
+
+static int mxc_isi_m2m_s_fmt_vid_cap(struct file *file, void *priv,
+ struct v4l2_format *f)
+{
+ struct mxc_isi_dev *mxc_isi = video_drvdata(file);
+ struct v4l2_fh *fh = file->private_data;
+ struct mxc_isi_frame *frame = &mxc_isi->m2m.dst_f;
+ struct v4l2_pix_format_mplane *pix = &f->fmt.pix_mp;
+ struct mxc_isi_fmt *fmt;
+ struct vb2_queue *vq;
+ int bpl, i;
+
+ dev_dbg(&mxc_isi->pdev->dev, "%s\n", __func__);
+
+ if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
+ return -EINVAL;
+
+ vq = v4l2_m2m_get_vq(fh->m2m_ctx, f->type);
+ if (!vq)
+ return -EINVAL;
+
+ if (vb2_is_busy(vq)) {
+ dev_err(&mxc_isi->pdev->dev, "queue busy\n");
+ return -EBUSY;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(mxc_isi_out_formats); i++) {
+ fmt = &mxc_isi_out_formats[i];
+ if (pix && fmt->fourcc == pix->pixelformat)
+ break;
+ }
+
+ if (i >= ARRAY_SIZE(mxc_isi_out_formats)) {
+ dev_err(&mxc_isi->pdev->dev, "%s, format is not support!\n", __func__);
+ return -EINVAL;
+ }
+
+ /* update out put frame size and formate */
+ if (pix->height <= 0 || pix->width <= 0) {
+ dev_err(&mxc_isi->pdev->dev,
+ "Invalid width or height(w=%d, h=%d)\n",
+ pix->width, pix->height);
+ return -EINVAL;
+ }
+
+ if ((pix->pixelformat == V4L2_PIX_FMT_NV12) && ((pix->width / 4) % 2)) {
+ dev_err(&mxc_isi->pdev->dev,
+ "Invalid width or height(w=%d, h=%d) for NV12\n",
+ pix->width, pix->height);
+ return -EINVAL;
+ } else if ((pix->pixelformat != V4L2_PIX_FMT_XBGR32) && (pix->width % 2)) {
+ dev_err(&mxc_isi->pdev->dev,
+ "Invalid width or height(w=%d, h=%d) for %.4s\n",
+ pix->width, pix->height, (char *)&pix->pixelformat);
+ return -EINVAL;
+ }
+
+ frame->fmt = fmt;
+ frame->height = pix->height;
+ frame->width = pix->width;
+
+ pix->num_planes = fmt->memplanes;
+ for (i = 0; i < pix->num_planes; i++) {
+ bpl = pix->plane_fmt[i].bytesperline;
+
+ if ((bpl == 0) || (bpl / (fmt->depth[i] >> 3)) < pix->width)
+ pix->plane_fmt[i].bytesperline =
+ (pix->width * fmt->depth[i]) >> 3;
+
+ if (pix->plane_fmt[i].sizeimage == 0) {
+
+ if ((i == 1) && (pix->pixelformat == V4L2_PIX_FMT_NV12))
+ pix->plane_fmt[i].sizeimage =
+ (pix->width * (pix->height >> 1) * fmt->depth[i] >> 3);
+ else
+ pix->plane_fmt[i].sizeimage = (pix->width * pix->height *
+ fmt->depth[i] >> 3);
+ }
+ }
+
+ if (pix->num_planes > 1) {
+ for (i = 0; i < pix->num_planes; i++) {
+ frame->bytesperline[i] = pix->plane_fmt[i].bytesperline;
+ frame->sizeimage[i] = pix->plane_fmt[i].sizeimage;
+ }
+ } else {
+ frame->bytesperline[0] = frame->width * frame->fmt->depth[0] / 8;
+ frame->sizeimage[0] = frame->height * frame->bytesperline[0];
+ }
+
+ memcpy(&mxc_isi->pix, pix, sizeof(*pix));
+
+ set_frame_bounds(frame, pix->width, pix->height);
+ mxc_isi_m2m_config_dst(mxc_isi);
+
+ return 0;
+}
+
+static int mxc_isi_m2m_g_fmt_vid_cap(struct file *file, void *fh,
+ struct v4l2_format *f)
+{
+ struct mxc_isi_dev *mxc_isi = video_drvdata(file);
+ struct v4l2_pix_format_mplane *pix = &f->fmt.pix_mp;
+ struct mxc_isi_frame *frame = &mxc_isi->m2m.dst_f;
+ int i;
+
+ dev_dbg(&mxc_isi->pdev->dev, "%s\n", __func__);
+
+ if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
+ return -EINVAL;
+
+ pix->width = frame->o_width;
+ pix->height = frame->o_height;
+ pix->field = V4L2_FIELD_NONE;
+ pix->pixelformat = frame->fmt->fourcc;
+ pix->colorspace = V4L2_COLORSPACE_JPEG;
+ pix->num_planes = frame->fmt->memplanes;
+
+ for (i = 0; i < pix->num_planes; ++i) {
+ pix->plane_fmt[i].bytesperline = frame->bytesperline[i];
+ pix->plane_fmt[i].sizeimage = frame->sizeimage[i];
+ }
+
+ return 0;
+}
+
+static int mxc_isi_m2m_g_fmt_vid_out(struct file *file, void *fh,
+ struct v4l2_format *f)
+{
+ struct mxc_isi_dev *mxc_isi = video_drvdata(file);
+ struct v4l2_pix_format_mplane *pix = &f->fmt.pix_mp;
+ struct mxc_isi_frame *frame = &mxc_isi->m2m.src_f;
+ int i;
+
+ dev_dbg(&mxc_isi->pdev->dev, "%s\n", __func__);
+
+ if (f->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
+ return -EINVAL;
+
+ pix->width = frame->o_width;
+ pix->height = frame->o_height;
+ pix->field = V4L2_FIELD_NONE;
+ pix->pixelformat = frame->fmt->fourcc;
+ pix->colorspace = V4L2_COLORSPACE_JPEG;
+ pix->num_planes = frame->fmt->memplanes;
+
+ for (i = 0; i < pix->num_planes; ++i) {
+ pix->plane_fmt[i].bytesperline = frame->bytesperline[i];
+ pix->plane_fmt[i].sizeimage = frame->sizeimage[i];
+ }
+
+ return 0;
+}
+
+static int mxc_isi_m2m_streamon(struct file *file, void *priv,
+ enum v4l2_buf_type type)
+{
+ struct mxc_isi_dev *mxc_isi = video_drvdata(file);
+ struct mxc_isi_frame *src_f, *dst_f;
+ int ret;
+
+ src_f = &mxc_isi->m2m.src_f;
+ dst_f = &mxc_isi->m2m.dst_f;
+ if ((dst_f->width > src_f->width) ||
+ (dst_f->height > src_f->height)) {
+ dev_err(&mxc_isi->pdev->dev, "%s Not support upscale\n", __func__);
+ return -EINVAL;
+ }
+
+ if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
+ mxc_isi->m2m.frame_count = 0;
+ mxc_isi_m2m_channel_config(mxc_isi);
+ }
+
+ ret = v4l2_m2m_ioctl_streamon(file, priv, type);
+
+ return ret;
+}
+
+static int mxc_isi_m2m_streamoff(struct file *file, void *priv,
+ enum v4l2_buf_type type)
+{
+ struct mxc_isi_dev *mxc_isi = video_drvdata(file);
+ int ret;
+
+ if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
+ mxc_isi_channel_disable(mxc_isi);
+
+ ret = v4l2_m2m_ioctl_streamoff(file, priv, type);
+
+ return ret;
+}
+
+static const struct v4l2_ioctl_ops mxc_isi_m2m_ioctl_ops = {
+ .vidioc_querycap = mxc_isi_m2m_querycap,
+
+ .vidioc_enum_fmt_vid_cap_mplane = mxc_isi_m2m_enum_fmt_vid_cap,
+ .vidioc_enum_fmt_vid_out_mplane = mxc_isi_m2m_enum_fmt_vid_out,
+
+ .vidioc_try_fmt_vid_cap_mplane = mxc_isi_m2m_try_fmt_vid_cap,
+ .vidioc_try_fmt_vid_out_mplane = mxc_isi_m2m_try_fmt_vid_out,
+
+ .vidioc_s_fmt_vid_cap_mplane = mxc_isi_m2m_s_fmt_vid_cap,
+ .vidioc_s_fmt_vid_out_mplane = mxc_isi_m2m_s_fmt_vid_out,
+
+ .vidioc_g_fmt_vid_cap_mplane = mxc_isi_m2m_g_fmt_vid_cap,
+ .vidioc_g_fmt_vid_out_mplane = mxc_isi_m2m_g_fmt_vid_out,
+
+ .vidioc_reqbufs = v4l2_m2m_ioctl_reqbufs,
+ .vidioc_querybuf = v4l2_m2m_ioctl_querybuf,
+ .vidioc_qbuf = v4l2_m2m_ioctl_qbuf,
+ .vidioc_dqbuf = v4l2_m2m_ioctl_dqbuf,
+ .vidioc_expbuf = v4l2_m2m_ioctl_expbuf,
+ .vidioc_prepare_buf = v4l2_m2m_ioctl_prepare_buf,
+ .vidioc_create_bufs = v4l2_m2m_ioctl_create_bufs,
+
+ .vidioc_streamon = mxc_isi_m2m_streamon,
+ .vidioc_streamoff = mxc_isi_m2m_streamoff,
+};
+
+/*
+ * V4L2 controls handling
+ */
+#define ctrl_to_mxc_isi_m2m(__ctrl) \
+ container_of((__ctrl)->handler, struct mxc_isi_dev, m2m.ctrls.handler)
+
+static int mxc_isi_m2m_s_ctrl(struct v4l2_ctrl *ctrl)
+{
+ struct mxc_isi_dev *mxc_isi = ctrl_to_mxc_isi_m2m(ctrl);
+ unsigned long flags;
+ int ret = 0;
+
+ dev_dbg(&mxc_isi->pdev->dev, "%s\n", __func__);
+
+ if (ctrl->flags & V4L2_CTRL_FLAG_INACTIVE)
+ return 0;
+
+ spin_lock_irqsave(&mxc_isi->slock, flags);
+
+ switch (ctrl->id) {
+ case V4L2_CID_HFLIP:
+ if (ctrl->val < 0) {
+ ret = -EINVAL;
+ goto unlock;
+ }
+ mxc_isi->m2m.hflip = (ctrl->val > 0) ? 1 : 0;
+ break;
+
+ case V4L2_CID_VFLIP:
+ if (ctrl->val < 0) {
+ ret = -EINVAL;
+ goto unlock;
+ }
+ mxc_isi->m2m.vflip = (ctrl->val > 0) ? 1 : 0;
+ break;
+
+ case V4L2_CID_ALPHA_COMPONENT:
+ if (ctrl->val < 0 || ctrl->val > 255) {
+ ret = -EINVAL;
+ goto unlock;
+ }
+ mxc_isi->m2m.alpha = ctrl->val;
+ mxc_isi->m2m.alphaen = 1;
+ break;
+
+ default:
+ dev_err(&mxc_isi->pdev->dev, "%s: Not support %d CID\n", __func__, ctrl->id);
+ ret = -EINVAL;
+ }
+
+unlock:
+ spin_unlock_irqrestore(&mxc_isi->slock, flags);
+ return ret;
+}
+
+static const struct v4l2_ctrl_ops mxc_isi_m2m_ctrl_ops = {
+ .s_ctrl = mxc_isi_m2m_s_ctrl,
+};
+
+static int mxc_isi_m2m_ctrls_create(struct mxc_isi_dev *mxc_isi)
+{
+ struct mxc_isi_ctrls *ctrls = &mxc_isi->m2m.ctrls;
+ struct v4l2_ctrl_handler *handler = &ctrls->handler;
+
+ if (mxc_isi->m2m.ctrls.ready)
+ return 0;
+
+ v4l2_ctrl_handler_init(handler, 4);
+
+ ctrls->hflip = v4l2_ctrl_new_std(handler, &mxc_isi_m2m_ctrl_ops,
+ V4L2_CID_HFLIP, 0, 1, 1, 0);
+ ctrls->vflip = v4l2_ctrl_new_std(handler, &mxc_isi_m2m_ctrl_ops,
+ V4L2_CID_VFLIP, 0, 1, 1, 0);
+ ctrls->alpha = v4l2_ctrl_new_std(handler, &mxc_isi_m2m_ctrl_ops,
+ V4L2_CID_ALPHA_COMPONENT, 0, 0xff, 1, 0);
+
+ if (!handler->error)
+ ctrls->ready = true;
+
+ return handler->error;
+
+}
+
+void mxc_isi_m2m_ctrls_delete(struct mxc_isi_dev *mxc_isi)
+{
+ struct mxc_isi_ctrls *ctrls = &mxc_isi->m2m.ctrls;
+
+ if (ctrls->ready) {
+ v4l2_ctrl_handler_free(&ctrls->handler);
+ ctrls->ready = false;
+ ctrls->alpha = NULL;
+ }
+}
+
+int mxc_isi_register_m2m_device(struct mxc_isi_dev *mxc_isi,
+ struct v4l2_device *v4l2_dev)
+{
+ struct device *dev = &mxc_isi->pdev->dev;
+ struct video_device *vdev = &mxc_isi->m2m.vdev;
+ struct mxc_isi_m2m_dev *isi_m2m = &mxc_isi->m2m;
+ int ret = -ENOMEM;
+
+ /* Only ISI channel0 support memory to memory */
+ if (mxc_isi->id != 0)
+ return -EINVAL;
+
+ dev_dbg(&mxc_isi->pdev->dev, "%s\n", __func__);
+
+ /* m2m */
+ isi_m2m->m2m_dev = v4l2_m2m_init(&mxc_isi_m2m_ops);
+ if (IS_ERR(isi_m2m->m2m_dev)) {
+ dev_err(dev, "%s fail to get m2m device\n", __func__);
+ return PTR_ERR(isi_m2m->m2m_dev);
+ }
+
+ INIT_LIST_HEAD(&isi_m2m->out_active);
+
+ /* Video device */
+ memset(vdev, 0, sizeof(*vdev));
+ snprintf(vdev->name, sizeof(vdev->name), "mxc_isi.%d.m2m", mxc_isi->id);
+
+ vdev->fops = &mxc_isi_m2m_fops;
+ vdev->ioctl_ops = &mxc_isi_m2m_ioctl_ops;
+ vdev->v4l2_dev = v4l2_dev;
+ vdev->minor = -1;
+ vdev->release = video_device_release_empty;
+ vdev->vfl_dir = VFL_DIR_M2M;
+ vdev->device_caps = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_M2M;
+
+ ret = mxc_isi_m2m_ctrls_create(mxc_isi);
+ if (ret)
+ goto free_m2m;
+
+ ret = video_register_device(vdev, VFL_TYPE_GRABBER, -1);
+ if (ret < 0) {
+ dev_err(dev, "%s fail to register video device\n", __func__);
+ goto ctrl_free;
+ }
+
+ vdev->ctrl_handler = &mxc_isi->m2m.ctrls.handler;
+ video_set_drvdata(vdev, mxc_isi);
+
+ return 0;
+
+ctrl_free:
+ mxc_isi_m2m_ctrls_delete(mxc_isi);
+free_m2m:
+ v4l2_m2m_release(isi_m2m->m2m_dev);
+ return ret;
+}
+
+void mxc_isi_unregister_m2m_device(struct mxc_isi_dev *mxc_isi)
+{
+ struct video_device *vdev;
+
+ vdev = &mxc_isi->m2m.vdev;
+ if (video_is_registered(vdev))
+ video_unregister_device(vdev);
+
+ v4l2_m2m_release(mxc_isi->m2m.m2m_dev);
+}
+
+void mxc_isi_m2m_frame_write_done(struct mxc_isi_dev *mxc_isi)
+{
+ struct v4l2_fh *fh;
+ struct mxc_isi_ctx *curr_mxc_ctx;
+ struct vb2_buffer *src_vb2, *dst_vb2;
+ struct mxc_isi_buffer *src_buf, *dst_buf;
+ struct v4l2_m2m_buffer *b;
+
+ dev_dbg(&mxc_isi->pdev->dev, "%s\n", __func__);
+
+ curr_mxc_ctx = v4l2_m2m_get_curr_priv(mxc_isi->m2m.m2m_dev);
+ if (!curr_mxc_ctx) {
+ dev_err(&mxc_isi->pdev->dev,
+ "Instance released before the end of transaction\n");
+ return;
+ }
+ fh = &curr_mxc_ctx->fh;
+
+ if (mxc_isi->m2m.aborting) {
+ mxc_isi_channel_disable(mxc_isi);
+ dev_warn(&mxc_isi->pdev->dev, "Aborting current job\n");
+ goto job_finish;
+ }
+
+ src_vb2 = v4l2_m2m_next_src_buf(fh->m2m_ctx);
+ if (!src_vb2) {
+ dev_err(&mxc_isi->pdev->dev, "No enought source buffers\n");
+ goto job_finish;
+ }
+ src_buf = vb2_to_isi_buffer(src_vb2);
+ v4l2_m2m_src_buf_remove(fh->m2m_ctx);
+ v4l2_m2m_buf_done(to_vb2_v4l2_buffer(src_vb2), VB2_BUF_STATE_DONE);
+
+ if (!list_empty(&mxc_isi->m2m.out_active)) {
+ dst_buf = list_first_entry(&mxc_isi->m2m.out_active,
+ struct mxc_isi_buffer, list);
+ dst_vb2 = &dst_buf->v4l2_buf.vb2_buf;
+ list_del_init(&dst_buf->list);
+ dst_buf->v4l2_buf.vb2_buf.timestamp = ktime_get_ns();
+ v4l2_m2m_buf_done(to_vb2_v4l2_buffer(dst_vb2), VB2_BUF_STATE_DONE);
+
+#if 0 // for debug
+ char *s_buf, *d_buf;
+ s_buf = vb2_plane_vaddr(src_vb2, 0);
+ if (s_buf) {
+ pr_info("src: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
+ s_buf[0],s_buf[1], s_buf[2],s_buf[3],s_buf[4],
+ s_buf[5],s_buf[6], s_buf[7],s_buf[8],s_buf[9]);
+ }
+ d_buf = vb2_plane_vaddr(dst_vb2, 0);
+ if (d_buf) {
+ pr_info("dst: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
+ d_buf[0],d_buf[1], d_buf[2], d_buf[3],d_buf[4],
+ d_buf[5],d_buf[6], d_buf[7],d_buf[8],d_buf[9]);
+ }
+#endif
+ }
+ mxc_isi->m2m.frame_count++;
+
+ dst_vb2 = v4l2_m2m_next_dst_buf(fh->m2m_ctx);
+ if (dst_vb2) {
+ dst_vb2->state = VB2_BUF_STATE_ACTIVE;
+ dst_buf = vb2_to_isi_buffer(dst_vb2);
+ dst_buf->v4l2_buf.sequence = mxc_isi->m2m.frame_count;
+ mxc_isi_channel_set_m2m_out_addr(mxc_isi, dst_buf);
+ v4l2_m2m_dst_buf_remove(fh->m2m_ctx);
+ b = to_v4l2_m2m_buffer(dst_vb2);
+ list_add_tail(&b->list, &mxc_isi->m2m.out_active);
+ }
+
+job_finish:
+ v4l2_m2m_job_finish(mxc_isi->m2m.m2m_dev, fh->m2m_ctx);
+}
diff --git a/drivers/media/platform/imx8/mxc-jpeg-hw.c b/drivers/media/platform/imx8/mxc-jpeg-hw.c
new file mode 100644
index 000000000000..2263ec426790
--- /dev/null
+++ b/drivers/media/platform/imx8/mxc-jpeg-hw.c
@@ -0,0 +1,244 @@
+/*
+ * Copyright 2018 NXP
+ */
+/*
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/delay.h>
+#include <media/videobuf2-core.h>
+#include "mxc-jpeg-hw.h"
+
+#define print_wrapper_reg(dev, base_address, reg_offset)\
+ internal_print_wrapper_reg(dev, (base_address), #reg_offset,\
+ (reg_offset))
+#define internal_print_wrapper_reg(dev, base_address, reg_name, reg_offset) {\
+ int val;\
+ val = readl((base_address) + (reg_offset));\
+ dev_dbg(dev, "Wrapper reg %s = 0x%x\n", reg_name, val);\
+}
+
+void print_descriptor_info(struct device *dev, struct mxc_jpeg_desc *desc)
+{
+ dev_dbg(dev, " MXC JPEG NEXT_DESCPT_PTR 0x%x\n",
+ desc->next_descpt_ptr);
+ dev_dbg(dev, " MXC JPEG BUF_BASE0 0x%x\n", desc->buf_base0);
+ dev_dbg(dev, " MXC JPEG BUF_BASE1 0x%x\n", desc->buf_base1);
+ dev_dbg(dev, " MXC JPEG LINE_PITCH %d\n", desc->line_pitch);
+ dev_dbg(dev, " MXC JPEG STM_BUFBASE 0x%x\n", desc->stm_bufbase);
+ dev_dbg(dev, " MXC JPEG STM_BUFSIZE %d\n", desc->stm_bufsize);
+ dev_dbg(dev, " MXC JPEG IMGSIZE %x (%d x %d)\n", desc->imgsize,
+ desc->imgsize >> 16, desc->imgsize & 0xFFFF);
+ dev_dbg(dev, " MXC JPEG STM_CTRL 0x%x\n", desc->stm_ctrl);
+}
+
+void print_cast_status(struct device *dev, void __iomem *reg, unsigned int mode)
+{
+ dev_dbg(dev, "CAST IP status regs:\n");
+ print_wrapper_reg(dev, reg, CAST_STATUS0);
+ print_wrapper_reg(dev, reg, CAST_STATUS1);
+ print_wrapper_reg(dev, reg, CAST_STATUS2);
+ print_wrapper_reg(dev, reg, CAST_STATUS3);
+ print_wrapper_reg(dev, reg, CAST_STATUS4);
+ print_wrapper_reg(dev, reg, CAST_STATUS5);
+ print_wrapper_reg(dev, reg, CAST_STATUS6);
+ print_wrapper_reg(dev, reg, CAST_STATUS7);
+ print_wrapper_reg(dev, reg, CAST_STATUS8);
+ print_wrapper_reg(dev, reg, CAST_STATUS9);
+ print_wrapper_reg(dev, reg, CAST_STATUS10);
+ print_wrapper_reg(dev, reg, CAST_STATUS11);
+ print_wrapper_reg(dev, reg, CAST_STATUS12);
+ print_wrapper_reg(dev, reg, CAST_STATUS13);
+ if (mode == MXC_JPEG_DECODE)
+ return;
+ print_wrapper_reg(dev, reg, CAST_STATUS14);
+ print_wrapper_reg(dev, reg, CAST_STATUS15);
+ print_wrapper_reg(dev, reg, CAST_STATUS16);
+ print_wrapper_reg(dev, reg, CAST_STATUS17);
+ print_wrapper_reg(dev, reg, CAST_STATUS18);
+ print_wrapper_reg(dev, reg, CAST_STATUS19);
+}
+
+void print_wrapper_info(struct device *dev, void __iomem *reg)
+{
+ dev_dbg(dev, "Wrapper regs:\n");
+ print_wrapper_reg(dev, reg, GLB_CTRL);
+ print_wrapper_reg(dev, reg, COM_STATUS);
+ print_wrapper_reg(dev, reg, BUF_BASE0);
+ print_wrapper_reg(dev, reg, BUF_BASE1);
+ print_wrapper_reg(dev, reg, LINE_PITCH);
+ print_wrapper_reg(dev, reg, STM_BUFBASE);
+ print_wrapper_reg(dev, reg, STM_BUFSIZE);
+ print_wrapper_reg(dev, reg, IMGSIZE);
+ print_wrapper_reg(dev, reg, STM_CTRL);
+}
+
+void mxc_jpeg_enable_irq(void __iomem *reg, int slot)
+{
+ writel(0xFFFFFFFF, reg + MXC_SLOT_OFFSET(slot, SLOT_IRQ_EN));
+}
+
+void mxc_jpeg_sw_reset(void __iomem *reg)
+{
+ /*
+ * engine soft reset, internal state machine reset
+ * this will not reset registers, however, it seems
+ * the registers may remain inconsistent with the internal state
+ * so, on purpose, at least let GLB_CTRL bits clear after this reset
+ */
+ writel(GLB_CTRL_SFT_RST, reg + GLB_CTRL);
+}
+
+u32 mxc_jpeg_get_offset(void __iomem *reg, int slot)
+{
+ return readl(reg + MXC_SLOT_OFFSET(slot, SLOT_BUF_PTR));
+}
+
+void mxc_jpeg_go_enc(struct device *dev, void __iomem *reg)
+{
+ dev_dbg(dev, "CAST Encoder GO...\n");
+ /*
+ * "Config_Mode" enabled, "Config_Mode auto clear enabled",
+ * "GO" enabled, "GO bit auto clear" enabled
+ */
+ writel(0x1e0, reg + CAST_MODE);
+
+ /* all markers and segments */
+ writel(0x3ff, reg + CAST_CFG_MODE);
+
+ /* quality factor */
+ writel(0x4b, reg + CAST_QUALITY);
+}
+
+void wait_frmdone(struct device *dev, void __iomem *reg)
+{
+ u32 regval = 0;
+
+ do {
+ regval = readl(reg + MXC_SLOT_OFFSET(0, SLOT_STATUS));
+ } while (!(regval & SLOTa_STATUS_FRMDONE));
+
+ writel(regval, reg + MXC_SLOT_OFFSET(0, SLOT_STATUS)); /* w1c */
+
+ dev_dbg(dev, "Received FRMDONE\n");
+ if (regval & SLOTa_STATUS_ENC_CONFIG_ERR)
+ dev_info(dev, "SLOTa_STATUS_ENC_CONFIG_ERR\n");
+}
+
+int mxc_jpeg_enable(void __iomem *reg)
+{
+ u32 regval;
+
+ writel(GLB_CTRL_JPG_EN, reg + GLB_CTRL);
+ regval = readl(reg);
+ return regval;
+}
+
+void mxc_jpeg_go_dec(struct device *dev, void __iomem *reg)
+{
+ dev_dbg(dev, "CAST Decoder GO...\n");
+ writel(MXC_DEC_EXIT_IDLE_MODE, reg + CAST_CTRL);
+}
+
+int mxc_jpeg_get_slot(void __iomem *reg)
+{
+ int slot_val;
+ int i = 0;
+ int tmp = GLB_CTRL_SLOT_EN(0);
+
+ /* currently enabled slots */
+ slot_val = readl(reg + GLB_CTRL) & 0xF0;
+
+ for (; tmp != tmp << 4; tmp = tmp << 1) {
+ if ((slot_val & tmp) == 0)
+ /* first free slot */
+ return i;
+ ++i;
+ }
+ return -EINVAL;
+}
+
+void mxc_jpeg_enable_slot(void __iomem *reg, int slot)
+{
+ u32 regval;
+
+ regval = readl(reg + GLB_CTRL);
+ writel(GLB_CTRL_SLOT_EN(slot) | regval, reg + GLB_CTRL);
+}
+
+void mxc_jpeg_set_l_endian(void __iomem *reg, int le)
+{
+ u32 regval;
+
+ regval = readl(reg + GLB_CTRL);
+ regval &= ~GLB_CTRL_L_ENDIAN(1); /* clear */
+ writel(GLB_CTRL_L_ENDIAN(le) | regval, reg + GLB_CTRL); /* set */
+}
+
+void mxc_jpeg_set_config_mode(void __iomem *reg, int config_mode)
+{
+ u32 regval;
+
+ regval = readl(reg + STM_CTRL);
+ regval &= ~STM_CTRL_CONFIG_MOD(1);
+ writel(STM_CTRL_CONFIG_MOD(config_mode) | regval, reg + STM_CTRL);
+}
+
+int mxc_jpeg_set_params(struct mxc_jpeg_desc *desc, u32 bufsize,
+ u16 out_pitch, u32 format)
+{
+ desc->line_pitch = out_pitch;
+ desc->stm_bufsize = bufsize;
+ switch (format) {
+ case V4L2_PIX_FMT_YUV32:
+ desc->stm_ctrl |= MXC_JPEG_YUV444 << 3;
+ break;
+ case V4L2_PIX_FMT_YUYV:
+ desc->stm_ctrl |= MXC_JPEG_YUV422 << 3;
+ break;
+ case V4L2_PIX_FMT_RGB32:
+ desc->stm_ctrl |= MXC_JPEG_RGB << 3;
+ break;
+ default:
+ return -1;
+ }
+ return 0;
+}
+
+void mxc_jpeg_set_bufsize(struct mxc_jpeg_desc *desc, u32 bufsize)
+{
+ desc->stm_bufsize = bufsize;
+}
+
+void mxc_jpeg_set_res(struct mxc_jpeg_desc *desc, u16 w, u16 h)
+{
+ desc->imgsize = w << 16 | h;
+}
+
+
+void mxc_jpeg_set_line_pitch(struct mxc_jpeg_desc *desc, u32 line_pitch)
+{
+ desc->line_pitch = line_pitch;
+}
+
+void mxc_jpeg_set_desc(u32 desc, void __iomem *reg, int slot)
+{
+ writel(desc | MXC_NXT_DESCPT_EN,
+ reg + MXC_SLOT_OFFSET(slot, SLOT_NXT_DESCPT_PTR));
+}
+
+void mxc_jpeg_set_regs_from_desc(struct mxc_jpeg_desc *desc, void __iomem *reg)
+{
+ writel(desc->buf_base0, reg + BUF_BASE0);
+ writel(desc->buf_base1, reg + BUF_BASE1);
+ writel(desc->line_pitch, reg + LINE_PITCH);
+ writel(desc->stm_bufbase, reg + STM_BUFBASE);
+ writel(desc->stm_bufsize, reg + STM_BUFSIZE);
+ writel(desc->imgsize, reg + IMGSIZE);
+ writel(desc->stm_ctrl, reg + STM_CTRL);
+}
diff --git a/drivers/media/platform/imx8/mxc-jpeg-hw.h b/drivers/media/platform/imx8/mxc-jpeg-hw.h
new file mode 100644
index 000000000000..2094d93a0435
--- /dev/null
+++ b/drivers/media/platform/imx8/mxc-jpeg-hw.h
@@ -0,0 +1,142 @@
+/*
+ * Copyright 2018 NXP
+ */
+/*
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+#ifndef _MXC_JPEG_HW_H
+#define _MXC_JPEG_HW_H
+
+#define MXC_JPEG_DECODE 0
+#define MXC_JPEG_ENCODE 1
+
+/* JPEG Decoder/Encoder Wrapper Register Map */
+#define GLB_CTRL 0x0
+#define COM_STATUS 0x4
+#define BUF_BASE0 0x14
+#define BUF_BASE1 0x18
+#define LINE_PITCH 0x1C
+#define STM_BUFBASE 0x20
+#define STM_BUFSIZE 0x24
+#define IMGSIZE 0x28
+#define STM_CTRL 0x2C
+
+/* CAST JPEG-Decoder/Encoder Status Register Map (read-only)*/
+#define CAST_STATUS0 0x100
+#define CAST_STATUS1 0x104
+#define CAST_STATUS2 0x108
+#define CAST_STATUS3 0x10c
+#define CAST_STATUS4 0x110
+#define CAST_STATUS5 0x114
+#define CAST_STATUS6 0x118
+#define CAST_STATUS7 0x11c
+#define CAST_STATUS8 0x120
+#define CAST_STATUS9 0x124
+#define CAST_STATUS10 0x128
+#define CAST_STATUS11 0x12c
+#define CAST_STATUS12 0x130
+#define CAST_STATUS13 0x134
+/* the following are for encoder only */
+#define CAST_STATUS14 0x138
+#define CAST_STATUS15 0x13c
+#define CAST_STATUS16 0x140
+#define CAST_STATUS17 0x144
+#define CAST_STATUS18 0x148
+#define CAST_STATUS19 0x14c
+
+/* CAST JPEG-Decoder Control Register Map (write-only) */
+#define CAST_CTRL CAST_STATUS13
+
+/* CAST JPEG-Encoder Control Register Map (write-only) */
+#define CAST_MODE CAST_STATUS0
+#define CAST_CFG_MODE CAST_STATUS1
+#define CAST_QUALITY CAST_STATUS2
+#define CAST_RSVD CAST_STATUS3
+#define CAST_REC_REGS_SEL CAST_STATUS4
+#define CAST_LUMTH CAST_STATUS5
+#define CAST_CHRTH CAST_STATUS6
+#define CAST_NOMFRSIZE_LO CAST_STATUS7
+#define CAST_NOMFRSIZE_HI CAST_STATUS8
+#define CAST_OFBSIZE_LO CAST_STATUS9
+#define CAST_OFBSIZE_HI CAST_STATUS10
+
+#define MXC_MAX_SLOTS 1 /* TODO use all 4 slots*/
+/* JPEG-Decoder Wrapper Slot Registers 0..3 */
+#define SLOT_BASE 0x10000
+#define SLOT_STATUS 0x0
+#define SLOT_IRQ_EN 0x4
+#define SLOT_BUF_PTR 0x8
+#define SLOT_CUR_DESCPT_PTR 0xC
+#define SLOT_NXT_DESCPT_PTR 0x10
+#define MXC_SLOT_OFFSET(slot, offset) ((SLOT_BASE * (slot + 1)) + offset)
+
+/* GLB_CTRL fields */
+#define GLB_CTRL_JPG_EN 0x1
+#define GLB_CTRL_SFT_RST (0x1 << 1)
+#define GLB_CTRL_DEC_GO (0x1 << 2)
+#define GLB_CTRL_L_ENDIAN(le) ((le) << 3)
+#define GLB_CTRL_SLOT_EN(slot) (0x1 << (slot + 4))
+
+/* STM_CTRL fields */
+#define STM_CTRL_PIXEL_PRECISION (0x1 << 2)
+#define STM_CTRL_IMAGE_FORMAT(img_fmt) ((img_fmt) << 3)
+#define STM_CTRL_IMAGE_FORMAT_MASK (0xF << 3)
+#define STM_CTRL_BITBUF_PTR_CLR(clr) ((clr) << 7)
+#define STM_CTRL_AUTO_START(go) ((go) << 8)
+#define STM_CTRL_CONFIG_MOD(mod) ((mod) << 9)
+
+/* SLOTa_STATUS fields TBD */
+#define SLOTa_STATUS_FRMDONE (0x1 << 3)
+#define SLOTa_STATUS_ENC_CONFIG_ERR (0x1 << 8)
+
+/* SLOTa_IRQ_EN fields TBD */
+
+#define MXC_NXT_DESCPT_EN 0x1
+#define MXC_DEC_EXIT_IDLE_MODE 0x4
+
+/* JPEG-Decoder Wrapper - STM_CTRL Register Fields */
+#define MXC_PIXEL_PRECISION(precision) ((precision)/8 << 2)
+enum mxc_jpeg_image_format {
+ MXC_JPEG_INVALID = -1,
+ MXC_JPEG_YUV420 = 0x0, /* 2 Plannar, Y=1st plane UV=2nd plane */
+ MXC_JPEG_YUV422 = 0x1, /* 1 Plannar, YUYV sequence */
+ MXC_JPEG_RGB = 0x2, /* RGBRGB packed format */
+ MXC_JPEG_YUV444 = 0x3, /* 1 Plannar, YUVYUV sequence */
+ MXC_JPEG_GRAY = 0x4, /* Y8 or Y12 or Single Component */
+ MXC_JPEG_RESERVED = 0x5,
+ MXC_JPEG_ARGB = 0x6,
+};
+
+
+#include "mxc-jpeg.h"
+void print_descriptor_info(struct device *dev, struct mxc_jpeg_desc *desc);
+void print_cast_status(struct device *dev, void __iomem *reg,
+ unsigned int mode);
+void print_wrapper_info(struct device *dev, void __iomem *reg);
+void mxc_jpeg_sw_reset(void __iomem *reg);
+int mxc_jpeg_enable(void __iomem *reg);
+void wait_frmdone(struct device *dev, void __iomem *reg);
+void mxc_jpeg_go_enc(struct device *dev, void __iomem *reg);
+void mxc_jpeg_go_dec(struct device *dev, void __iomem *reg);
+int mxc_jpeg_get_slot(void __iomem *reg);
+u32 mxc_jpeg_get_offset(void __iomem *reg, int slot);
+void mxc_jpeg_enable_slot(void __iomem *reg, int slot);
+void mxc_jpeg_set_l_endian(void __iomem *reg, int le);
+void mxc_jpeg_enable_irq(void __iomem *reg, int slot);
+int mxc_jpeg_set_input(void __iomem *reg, u32 in_buf, u32 bufsize);
+int mxc_jpeg_set_output(void __iomem *reg, u16 out_pitch, u32 out_buf,
+ u16 w, u16 h);
+void mxc_jpeg_set_config_mode(void __iomem *reg, int config_mode);
+int mxc_jpeg_set_params(struct mxc_jpeg_desc *desc, u32 bufsize, u16
+ out_pitch, u32 format);
+void mxc_jpeg_set_bufsize(struct mxc_jpeg_desc *desc, u32 bufsize);
+void mxc_jpeg_set_res(struct mxc_jpeg_desc *desc, u16 w, u16 h);
+void mxc_jpeg_set_line_pitch(struct mxc_jpeg_desc *desc, u32 line_pitch);
+void mxc_jpeg_set_desc(u32 desc, void __iomem *reg, int slot);
+void mxc_jpeg_set_regs_from_desc(struct mxc_jpeg_desc *desc, void __iomem *reg);
+#endif
diff --git a/drivers/media/platform/imx8/mxc-jpeg.c b/drivers/media/platform/imx8/mxc-jpeg.c
new file mode 100644
index 000000000000..58ac99c86d5f
--- /dev/null
+++ b/drivers/media/platform/imx8/mxc-jpeg.c
@@ -0,0 +1,1772 @@
+/*
+ * Copyright 2018 NXP
+ */
+/*
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/io.h>
+#include <linux/clk.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/irqreturn.h>
+#include <linux/interrupt.h>
+#include <linux/pm_runtime.h>
+#include <linux/string.h>
+
+#include <media/v4l2-mem2mem.h>
+#include <media/v4l2-ioctl.h>
+#include <media/v4l2-common.h>
+#include <media/v4l2-event.h>
+#include <media/videobuf2-dma-contig.h>
+
+#include "mxc-jpeg-hw.h"
+#include "mxc-jpeg.h"
+
+static struct mxc_jpeg_fmt mxc_formats[] = {
+ {
+ .name = "JPEG",
+ .fourcc = V4L2_PIX_FMT_JPEG,
+ .colplanes = 1,
+ .flags = MXC_JPEG_FMT_TYPE_ENC,
+ },
+ {
+ .name = "RGB", /*RGBRGB packed format*/
+ .fourcc = V4L2_PIX_FMT_RGB24,
+ .depth = 24,
+ .colplanes = 1,
+ .h_align = 0,
+ .v_align = 0,
+ .flags = MXC_JPEG_FMT_TYPE_RAW,
+ },
+ {
+ .name = "ARGB", /* ARGBARGB packed format */
+ .fourcc = V4L2_PIX_FMT_ARGB32,
+ .depth = 32,
+ .colplanes = 1,
+ .h_align = 0,
+ .v_align = 0,
+ .flags = MXC_JPEG_FMT_TYPE_RAW,
+ },
+ {
+ .name = "YUV420", /* 1st plane = Y, 2nd plane = UV */
+ .fourcc = V4L2_PIX_FMT_NV12,
+ .depth = 12, /* 6 bytes (4Y + UV) for 4 pixels */
+ .colplanes = 2, /* 1 plane Y, 1 plane UV interleaved */
+ .h_align = 2,
+ .v_align = 0,
+ .flags = MXC_JPEG_FMT_TYPE_RAW,
+ },
+ {
+ .name = "YUV422", /* YUYV */
+ .fourcc = V4L2_PIX_FMT_YUYV,
+ .depth = 16,
+ .colplanes = 1,
+ .h_align = 2,
+ .v_align = 0,
+ .flags = MXC_JPEG_FMT_TYPE_RAW,
+ },
+ {
+ .name = "YUV444", /* YUVYUV */
+ .fourcc = V4L2_PIX_FMT_YUV32,
+ .depth = 24,
+ .colplanes = 1,
+ .h_align = 0,
+ .v_align = 0,
+ .flags = MXC_JPEG_FMT_TYPE_RAW,
+ },
+ {
+ .name = "Gray", /* Gray (Y8/Y12) or Single Comp */
+ .fourcc = V4L2_PIX_FMT_GREY,
+ .depth = 8,
+ .colplanes = 1,
+ .h_align = 0,
+ .v_align = 0,
+ .flags = MXC_JPEG_FMT_TYPE_RAW,
+ },
+};
+#define MXC_JPEG_NUM_FORMATS ARRAY_SIZE(mxc_formats)
+
+static const struct of_device_id mxc_jpeg_match[] = {
+ {
+ .compatible = "fsl,imx8-jpgdec",
+ .data = (void *)MXC_JPEG_DECODE,
+ },
+ {
+ .compatible = "fsl,imx8-jpgenc",
+ .data = (void *)MXC_JPEG_ENCODE,
+ },
+ { },
+};
+
+static const unsigned char hactbl[615] = {
+0xFF, 0xD8, 0xFF, 0xE0, 0x00, 0x10, 0x4A,
+0x46, 0x49, 0x46, 0x00, 0x01, 0x01, 0x00,
+0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0xFF,
+0xDB, 0x00, 0x84, 0x00, 0x10, 0x0B, 0x0C,
+0x0E, 0x0C, 0x0A, 0x10, 0x0E, 0x0D, 0x0E,
+0x12, 0x11, 0x10, 0x13, 0x18, 0x28, 0x1A,
+0x18, 0x16, 0x16, 0x18, 0x31, 0x23, 0x25,
+0x1D, 0x28, 0x3A, 0x33, 0x3D, 0x3C, 0x39,
+0x33, 0x38, 0x37, 0x40, 0x48, 0x5C, 0x4E,
+0x40, 0x44, 0x57, 0x45, 0x37, 0x38, 0x50,
+0x6D, 0x51, 0x57, 0x5F, 0x62, 0x67, 0x68,
+0x67, 0x3E, 0x4D, 0x71, 0x79, 0x70, 0x64,
+0x78, 0x5C, 0x65, 0x67, 0x63, 0x01, 0x11,
+0x12, 0x12, 0x18, 0x15, 0x18, 0x2F, 0x1A,
+0x1A, 0x2F, 0x63, 0x42, 0x38, 0x42, 0x63,
+0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
+0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
+0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
+0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
+0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
+0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
+0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
+0xFF, 0xC0, 0x00, 0x11, 0x08, 0x00, 0x40,
+0x00, 0x40, 0x03, 0x01, 0x21, 0x00, 0x02,
+0x11, 0x01, 0x03, 0x11, 0x01, 0xFF, 0xC4,
+0x01, 0xA2, 0x00, 0x00, 0x01, 0x05, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
+0x09, 0x0A, 0x0B, 0x10, 0x00, 0x02, 0x01,
+0x03, 0x03, 0x02, 0x04, 0x03, 0x05, 0x05,
+0x04, 0x04, 0x00, 0x00, 0x01, 0x7D, 0x01,
+0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12,
+0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61,
+0x07, 0x22, 0x71, 0x14, 0x32, 0x81, 0x91,
+0xA1, 0x08, 0x23, 0x42, 0xB1, 0xC1, 0x15,
+0x52, 0xD1, 0xF0, 0x24, 0x33, 0x62, 0x72,
+0x82, 0x09, 0x0A, 0x16, 0x17, 0x18, 0x19,
+0x1A, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A,
+0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A,
+0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
+0x4A, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
+0x59, 0x5A, 0x63, 0x64, 0x65, 0x66, 0x67,
+0x68, 0x69, 0x6A, 0x73, 0x74, 0x75, 0x76,
+0x77, 0x78, 0x79, 0x7A, 0x83, 0x84, 0x85,
+0x86, 0x87, 0x88, 0x89, 0x8A, 0x92, 0x93,
+0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A,
+0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8,
+0xA9, 0xAA, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6,
+0xB7, 0xB8, 0xB9, 0xBA, 0xC2, 0xC3, 0xC4,
+0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xD2,
+0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9,
+0xDA, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6,
+0xE7, 0xE8, 0xE9, 0xEA, 0xF1, 0xF2, 0xF3,
+0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA,
+0x01, 0x00, 0x03, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03,
+0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A,
+0x0B, 0x11, 0x00, 0x02, 0x01, 0x02, 0x04,
+0x04, 0x03, 0x04, 0x07, 0x05, 0x04, 0x04,
+0x00, 0x01, 0x02, 0x77, 0x00, 0x01, 0x02,
+0x03, 0x11, 0x04, 0x05, 0x21, 0x31, 0x06,
+0x12, 0x41, 0x51, 0x07, 0x61, 0x71, 0x13,
+0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91,
+0xA1, 0xB1, 0xC1, 0x09, 0x23, 0x33, 0x52,
+0xF0, 0x15, 0x62, 0x72, 0xD1, 0x0A, 0x16,
+0x24, 0x34, 0xE1, 0x25, 0xF1, 0x17, 0x18,
+0x19, 0x1A, 0x26, 0x27, 0x28, 0x29, 0x2A,
+0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x43,
+0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A,
+0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
+0x5A, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
+0x69, 0x6A, 0x73, 0x74, 0x75, 0x76, 0x77,
+0x78, 0x79, 0x7A, 0x82, 0x83, 0x84, 0x85,
+0x86, 0x87, 0x88, 0x89, 0x8A, 0x92, 0x93,
+0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A,
+0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8,
+0xA9, 0xAA, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6,
+0xB7, 0xB8, 0xB9, 0xBA, 0xC2, 0xC3, 0xC4,
+0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xD2,
+0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9,
+0xDA, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,
+0xE8, 0xE9, 0xEA, 0xF2, 0xF3, 0xF4, 0xF5,
+0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFF, 0xDD,
+0x00, 0x04, 0x00, 0x20, 0xFF, 0xDA, 0x00,
+0x0C, 0x03, 0x01, 0x00, 0x02, 0x11, 0x03,
+0x11, 0x00, 0x3F, 0x00, 0xFF, 0xD9
+};
+#define HACTBL_H_OFFSET 159
+#define HACTBL_W_OFFSET 161
+#define HACTBL_COMP1_SUBSAMPLING 165
+#define HACTBL_COMP2_SUBSAMPLING 168
+#define HACTBL_COMP3_SUBSAMPLING 171
+
+/* Print Four-character-code (FOURCC) */
+static char *fourcc_to_str(u32 format)
+{
+ char *buf = kmalloc(32, GFP_KERNEL);
+
+ snprintf(buf, 32,
+ "%c%c%c%c",
+ format & 0xff,
+ (format >> 8) & 0xff,
+ (format >> 16) & 0xff,
+ (format >> 24) & 0x7f);
+ return buf;
+}
+
+static unsigned int mxc_jpeg_tracing;
+EXPORT_SYMBOL(mxc_jpeg_tracing);
+
+module_param_named(jpeg_tracing, mxc_jpeg_tracing, int, 0600);
+
+static void print_buf_preview(struct device *dev, struct vb2_buffer *buf)
+{
+ unsigned char *data;
+ u32 dma_addr;
+
+ if (!mxc_jpeg_tracing)
+ return;
+
+ dma_addr = vb2_dma_contig_plane_dma_addr(buf, 0);
+ data = (char *)vb2_plane_vaddr(buf, 0);
+
+ /* print just the first 4 bytes from the beginning of the buffer */
+ dev_dbg(dev, "vaddr=%p dma_addr=%x: %x %x %x %x ...\n",
+ data, dma_addr,
+ data[0], data[1], data[2], data[3]);
+}
+
+static void print_nbuf_to_eoi(struct device *dev, struct vb2_buffer *buf, int n)
+{
+ unsigned char *data;
+ u32 dma_addr;
+ int i;
+ int items_per_line = 22;
+ char *bufstr, *bufptr;
+
+ if (!mxc_jpeg_tracing)
+ return;
+
+ if (n == 0)
+ n = buf->planes[0].bytesused;
+
+ dma_addr = vb2_dma_contig_plane_dma_addr(buf, 0);
+ data = (unsigned char *)vb2_plane_vaddr(buf, 0);
+
+ dev_dbg(dev, "vaddr=%p dma_addr=%x bytesused=%d:",
+ data, dma_addr, n);
+
+ bufstr = kmalloc(items_per_line * 6, GFP_ATOMIC);
+ bufptr = bufstr;
+ for (i = 0; i < n; i++) {
+ snprintf(bufptr, 6, "0x%02x,", data[i]);
+ bufptr += 5;
+ if ((i+1) % items_per_line == 0) {
+ /* print the current line */
+ dev_dbg(dev, "%s", bufstr);
+ /* back to buffer start */
+ bufptr = bufstr;
+ }
+ /* stop at End of Image (EOI) marker*/
+ if (i > 0 && data[i-1] == 0xFF && data[i] == 0xD9)
+ break;
+ }
+ if (bufptr != bufstr)
+ dev_dbg(dev, "%s", bufstr);
+ dev_dbg(dev, "buffer size = %d", i);
+ kfree(bufstr);
+}
+
+static inline u32 mxc_jpeg_align(u32 val, u32 align)
+{
+ return (val + align - 1) & ~(align - 1);
+}
+
+static inline struct mxc_jpeg_ctx *mxc_jpeg_fh_to_ctx(struct v4l2_fh *fh)
+{
+ return container_of(fh, struct mxc_jpeg_ctx, fh);
+}
+
+static int enum_fmt(struct mxc_jpeg_fmt *mxc_formats, int n,
+ struct v4l2_fmtdesc *f, u32 type)
+{
+ int i, num = 0;
+
+ for (i = 0; i < n; ++i) {
+ if (mxc_formats[i].flags == type) {
+ /* index-th format of type type found ? */
+ if (num == f->index)
+ break;
+ /* Correct type but haven't reached our index yet,
+ * just increment per-type index
+ */
+ ++num;
+ }
+ }
+
+ /* Format not found */
+ if (i >= n)
+ return -EINVAL;
+
+ strlcpy(f->description, mxc_formats[i].name, sizeof(f->description));
+ f->pixelformat = mxc_formats[i].fourcc;
+
+ return 0;
+}
+
+static struct mxc_jpeg_fmt *mxc_jpeg_find_format(struct mxc_jpeg_ctx *ctx,
+ u32 pixelformat)
+{
+ unsigned int k;
+
+ for (k = 0; k < MXC_JPEG_NUM_FORMATS; k++) {
+ struct mxc_jpeg_fmt *fmt = &mxc_formats[k];
+
+ if (fmt->fourcc == pixelformat)
+ return fmt;
+ }
+ return NULL;
+}
+
+static enum mxc_jpeg_image_format mxc_jpeg_fourcc_to_imgfmt(
+ u32 fourcc)
+{
+ switch (fourcc) {
+ case V4L2_PIX_FMT_GREY:
+ return MXC_JPEG_GRAY;
+ case V4L2_PIX_FMT_YUYV:
+ return MXC_JPEG_YUV422;
+ case V4L2_PIX_FMT_NV12:
+ return MXC_JPEG_YUV420;
+ case V4L2_PIX_FMT_YUV32:
+ return MXC_JPEG_YUV444;
+ case V4L2_PIX_FMT_RGB24:
+ return MXC_JPEG_RGB;
+ case V4L2_PIX_FMT_ARGB32:
+ return MXC_JPEG_ARGB;
+ default:
+ return MXC_JPEG_INVALID;
+ }
+}
+
+static int mxc_jpeg_imgfmt_to_fourcc(enum mxc_jpeg_image_format imgfmt,
+ u32 *fourcc)
+{
+ switch (imgfmt) {
+ case MXC_JPEG_GRAY:
+ *fourcc = V4L2_PIX_FMT_GREY;
+ return 0;
+ case MXC_JPEG_YUV422:
+ *fourcc = V4L2_PIX_FMT_YUYV;
+ return 0;
+ case MXC_JPEG_YUV420:
+ *fourcc = V4L2_PIX_FMT_NV12;
+ return 0;
+ case MXC_JPEG_YUV444:
+ *fourcc = V4L2_PIX_FMT_YUV32;
+ return 0;
+ case MXC_JPEG_RGB:
+ *fourcc = V4L2_PIX_FMT_RGB24;
+ return 0;
+ case MXC_JPEG_ARGB:
+ *fourcc = V4L2_PIX_FMT_ARGB32;
+ return 0;
+ default:
+ return 1;
+ }
+}
+
+static struct mxc_jpeg_q_data *mxc_jpeg_get_q_data(struct mxc_jpeg_ctx *ctx,
+ enum v4l2_buf_type type)
+{
+ if (V4L2_TYPE_IS_OUTPUT(type))
+ return &ctx->out_q;
+ return &ctx->cap_q;
+}
+
+static void mxc_jpeg_addrs(struct mxc_jpeg_desc *desc,
+ struct vb2_buffer *b_base0_buf,
+ struct vb2_buffer *bufbase_buf, int offset)
+{
+ int img_fmt = desc->stm_ctrl & STM_CTRL_IMAGE_FORMAT_MASK;
+
+ desc->buf_base0 = vb2_dma_contig_plane_dma_addr(b_base0_buf, 0);
+ desc->buf_base1 = 0;
+ if (img_fmt == STM_CTRL_IMAGE_FORMAT(MXC_JPEG_YUV420)) {
+ u32 h = desc->imgsize & 0xFFFF;
+ u32 w = (desc->imgsize >> 16) & 0xFFFF;
+ u32 luma_plane_size = w * h;
+
+ desc->buf_base1 = desc->buf_base0 + luma_plane_size;
+ }
+ desc->stm_bufbase = vb2_dma_contig_plane_dma_addr(bufbase_buf, 0) +
+ offset;
+}
+
+static void notify_eos(struct mxc_jpeg_ctx *ctx)
+{
+ const struct v4l2_event ev = {
+ .type = V4L2_EVENT_EOS
+ };
+
+ dev_dbg(ctx->mxc_jpeg->dev, "Notify app event EOS reached");
+ v4l2_event_queue_fh(&ctx->fh, &ev);
+}
+
+static irqreturn_t mxc_jpeg_dec_irq(int irq, void *priv)
+{
+ struct mxc_jpeg_dev *jpeg = priv;
+ struct mxc_jpeg_ctx *ctx;
+ void __iomem *reg = jpeg->base_reg;
+ struct device *dev = jpeg->dev;
+ struct vb2_buffer *src_buf, *dst_buf;
+ enum vb2_buffer_state buf_state;
+ u32 dec_ret;
+ unsigned long payload_size;
+ struct mxc_jpeg_q_data *q_data;
+ int slot = 0; /* TODO remove hardcoded slot 0 */
+
+ spin_lock(&jpeg->hw_lock);
+
+ dec_ret = readl(reg + MXC_SLOT_OFFSET(slot, SLOT_STATUS));
+ writel(dec_ret, reg + MXC_SLOT_OFFSET(slot, SLOT_STATUS)); /* w1c */
+
+ ctx = v4l2_m2m_get_curr_priv(jpeg->m2m_dev);
+ if (!ctx) {
+ dev_err(dev,
+ "Instance released before the end of transaction 0x%x.",
+ dec_ret);
+ /* soft reset only resets internal state, not registers */
+ mxc_jpeg_sw_reset(reg);
+ /* clear all interrupts */
+ writel(0xFFFFFFFF, reg + MXC_SLOT_OFFSET(slot, SLOT_STATUS));
+ goto job_unlock;
+ }
+
+ dst_buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
+ src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
+
+ if (ctx->aborting) {
+ dev_warn(dev, "Aborting current job\n");
+ mxc_jpeg_sw_reset(reg);
+ buf_state = VB2_BUF_STATE_ERROR;
+ goto buffers_done;
+ }
+
+ if (dec_ret & SLOTa_STATUS_ENC_CONFIG_ERR) {
+ u32 ret = readl(reg + CAST_STATUS12);
+
+ dev_err(dev, "Encoder/decoder error, status=0x%08x", ret);
+ mxc_jpeg_sw_reset(reg);
+ buf_state = VB2_BUF_STATE_ERROR;
+ goto buffers_done;
+ }
+
+ if (!(dec_ret & SLOTa_STATUS_FRMDONE))
+ goto job_unlock;
+
+ if (ctx->mode == MXC_JPEG_ENCODE
+ && ctx->enc_state == MXC_JPEG_ENC_CONF) {
+ ctx->enc_state = MXC_JPEG_ENC_DONE;
+ dev_dbg(dev, "Encoder config finished. Start encoding...\n");
+ goto job_unlock;
+ }
+ if (ctx->mode == MXC_JPEG_ENCODE) {
+ payload_size = readl(reg + MXC_SLOT_OFFSET(slot, SLOT_BUF_PTR));
+ vb2_set_plane_payload(dst_buf, 0, payload_size);
+ dev_dbg(dev, "Encoding finished, payload_size: %ld\n",
+ payload_size);
+ } else {
+ q_data = mxc_jpeg_get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
+ payload_size = q_data->sizeimage[0];
+ vb2_set_plane_payload(dst_buf, 0, payload_size);
+ dev_dbg(dev, "Decoding finished, payload_size: %ld\n",
+ payload_size);
+ }
+
+ /* short preview of the results */
+ dev_dbg(dev, "src_buf preview: ");
+ print_buf_preview(dev, src_buf);
+ dev_dbg(dev, "dst_buf preview: ");
+ print_buf_preview(dev, dst_buf);
+ buf_state = VB2_BUF_STATE_DONE;
+
+buffers_done:
+ v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
+ v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
+ v4l2_m2m_buf_done(to_vb2_v4l2_buffer(src_buf), buf_state);
+ v4l2_m2m_buf_done(to_vb2_v4l2_buffer(dst_buf), buf_state);
+ spin_unlock(&jpeg->hw_lock);
+ v4l2_m2m_job_finish(jpeg->m2m_dev, ctx->fh.m2m_ctx);
+ return IRQ_HANDLED;
+job_unlock:
+ spin_unlock(&jpeg->hw_lock);
+ return IRQ_HANDLED;
+}
+
+static void mxc_jpeg_config_dec_desc(struct vb2_buffer *out_buf,
+ int slot,
+ struct mxc_jpeg_dev *jpeg,
+ struct vb2_buffer *src_buf, struct vb2_buffer *dst_buf)
+{
+ void __iomem *reg = jpeg->base_reg;
+ struct mxc_jpeg_desc *desc = jpeg->slot_data[slot].desc;
+ dma_addr_t desc_handle = jpeg->slot_data[slot].desc_handle;
+
+ mxc_jpeg_addrs(desc, dst_buf, src_buf, 0);
+ mxc_jpeg_set_bufsize(desc,
+ mxc_jpeg_align(vb2_plane_size(src_buf, 0), 1024));
+ print_descriptor_info(jpeg->dev, desc);
+
+ /* validate the decoding descriptor */
+ mxc_jpeg_set_desc(desc_handle, reg, slot);
+}
+
+static void mxc_jpeg_fixup_cfg_stream(void *cfg_stream_vaddr,
+ enum mxc_jpeg_image_format img_fmt,
+ u16 w, u16 h)
+{
+ u8 *hactbl = (u8 *)cfg_stream_vaddr;
+
+ hactbl[HACTBL_W_OFFSET] = w >> 8;
+ hactbl[HACTBL_W_OFFSET+1] = (u8)w;
+ hactbl[HACTBL_H_OFFSET] = h >> 8;
+ hactbl[HACTBL_H_OFFSET+1] = (u8)h;
+ switch (img_fmt) {
+ case MXC_JPEG_YUV420:
+ hactbl[HACTBL_COMP1_SUBSAMPLING] = 0x22;
+ hactbl[HACTBL_COMP2_SUBSAMPLING] = 0x11;
+ hactbl[HACTBL_COMP3_SUBSAMPLING] = 0x11;
+ break;
+ case MXC_JPEG_YUV422:
+ hactbl[HACTBL_COMP1_SUBSAMPLING] = 0x21;
+ hactbl[HACTBL_COMP2_SUBSAMPLING] = 0x11;
+ hactbl[HACTBL_COMP3_SUBSAMPLING] = 0x11;
+ break;
+ case MXC_JPEG_YUV444:
+ case MXC_JPEG_RGB:
+ default:
+ hactbl[HACTBL_COMP1_SUBSAMPLING] = 0x11;
+ hactbl[HACTBL_COMP2_SUBSAMPLING] = 0x11;
+ hactbl[HACTBL_COMP3_SUBSAMPLING] = 0x11;
+ break;
+ case MXC_JPEG_ARGB:
+ /* TODO: should be 4 componennts, SOF0 length should change*/
+ hactbl[HACTBL_COMP1_SUBSAMPLING] = 0x11;
+ hactbl[HACTBL_COMP2_SUBSAMPLING] = 0x11;
+ hactbl[HACTBL_COMP3_SUBSAMPLING] = 0x11;
+ break;
+ case MXC_JPEG_GRAY:
+ /* TODO: should be 1 comp only, SOF0 length should change*/
+ hactbl[HACTBL_COMP1_SUBSAMPLING] = 0x11;
+ break;
+ }
+}
+
+static void mxc_jpeg_config_enc_desc(struct vb2_buffer *out_buf,
+ int slot,
+ struct mxc_jpeg_ctx *ctx,
+ struct vb2_buffer *src_buf, struct vb2_buffer *dst_buf)
+{
+ struct mxc_jpeg_dev *jpeg = ctx->mxc_jpeg;
+ void __iomem *reg = jpeg->base_reg;
+ struct mxc_jpeg_desc *desc = jpeg->slot_data[slot].desc;
+ struct mxc_jpeg_desc *cfg_desc = jpeg->slot_data[slot].cfg_desc;
+ dma_addr_t desc_handle = jpeg->slot_data[slot].desc_handle;
+ dma_addr_t cfg_desc_handle = jpeg->slot_data[slot].cfg_desc_handle;
+ struct mxc_jpeg_q_data *q_data;
+ enum mxc_jpeg_image_format img_fmt;
+
+ q_data = mxc_jpeg_get_q_data(ctx, src_buf->vb2_queue->type);
+
+ /* chain the config descriptor with the encoding descriptor */
+ cfg_desc->next_descpt_ptr = desc_handle | MXC_NXT_DESCPT_EN;
+
+ cfg_desc->buf_base0 = jpeg->slot_data[slot].cfg_stream_handle;
+ cfg_desc->buf_base1 = 0;
+ cfg_desc->line_pitch = 0;
+ cfg_desc->stm_bufbase = 0;
+ cfg_desc->stm_bufsize = 0x2000;
+ cfg_desc->imgsize = 0;
+ cfg_desc->stm_ctrl = STM_CTRL_CONFIG_MOD(1);
+
+ desc->next_descpt_ptr = 0; /* end of chain */
+ mxc_jpeg_set_res(desc, q_data->w, q_data->h);
+ mxc_jpeg_set_line_pitch(desc, q_data->w * (q_data->fmt->depth / 8));
+ mxc_jpeg_set_bufsize(desc, desc->line_pitch * q_data->h);
+ img_fmt = mxc_jpeg_fourcc_to_imgfmt(q_data->fmt->fourcc);
+ if (img_fmt == MXC_JPEG_INVALID)
+ dev_err(jpeg->dev, "No valid image format detected\n");
+ desc->stm_ctrl = STM_CTRL_CONFIG_MOD(0) |
+ STM_CTRL_IMAGE_FORMAT(img_fmt);
+ mxc_jpeg_fixup_cfg_stream(jpeg->slot_data[slot].cfg_stream_vaddr,
+ img_fmt, q_data->w, q_data->h);
+ mxc_jpeg_addrs(desc, src_buf, dst_buf, 0);
+ dev_dbg(jpeg->dev, "cfg_desc - 0x%llx:\n", cfg_desc_handle);
+ print_descriptor_info(jpeg->dev, cfg_desc);
+ dev_dbg(jpeg->dev, "enc desc - 0x%llx:\n", desc_handle);
+ print_descriptor_info(jpeg->dev, desc);
+ print_wrapper_info(jpeg->dev, reg);
+ print_cast_status(jpeg->dev, reg, MXC_JPEG_ENCODE);
+
+ /* validate the configuration descriptor */
+ mxc_jpeg_set_desc(cfg_desc_handle, reg, slot);
+}
+
+static void mxc_jpeg_device_run(void *priv)
+{
+ struct mxc_jpeg_ctx *ctx = priv;
+ struct mxc_jpeg_dev *jpeg = ctx->mxc_jpeg;
+ void __iomem *reg = jpeg->base_reg;
+ struct device *dev = jpeg->dev;
+ struct vb2_buffer *src_buf, *dst_buf;
+ unsigned long flags;
+ int slot = 0;
+
+ spin_lock_irqsave(&ctx->mxc_jpeg->hw_lock, flags);
+ src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
+ dst_buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
+ if (!src_buf || !dst_buf) {
+ dev_err(dev, "Null src or dst buf\n");
+ goto end;
+ }
+
+ mxc_jpeg_sw_reset(reg);
+ mxc_jpeg_enable(reg);
+ mxc_jpeg_set_l_endian(reg, 1);
+
+ slot = 0; /* TODO get slot */
+ mxc_jpeg_enable_slot(reg, slot);
+ mxc_jpeg_enable_irq(reg, slot);
+
+ if (ctx->mode == MXC_JPEG_ENCODE) {
+ dev_dbg(dev, "Encoding on slot %d\n", slot);
+ ctx->enc_state = MXC_JPEG_ENC_CONF;
+ mxc_jpeg_config_enc_desc(dst_buf, slot, ctx, src_buf, dst_buf);
+ mxc_jpeg_go_enc(dev, reg);
+ } else {
+ dev_dbg(dev, "Decoding on slot %d\n", slot);
+ print_nbuf_to_eoi(dev, src_buf, 0);
+ mxc_jpeg_config_dec_desc(dst_buf, slot, jpeg, src_buf, dst_buf);
+ mxc_jpeg_go_dec(dev, reg);
+ }
+end:
+ spin_unlock_irqrestore(&ctx->mxc_jpeg->hw_lock, flags);
+}
+
+static int mxc_jpeg_decoder_cmd(struct file *file, void *priv,
+ struct v4l2_decoder_cmd *cmd)
+{
+ struct v4l2_fh *fh = file->private_data;
+ struct mxc_jpeg_ctx *ctx = mxc_jpeg_fh_to_ctx(fh);
+ struct device *dev = ctx->mxc_jpeg->dev;
+
+ switch (cmd->cmd) {
+ case V4L2_DEC_CMD_STOP:
+ dev_dbg(dev, "Received V4L2_DEC_CMD_STOP");
+ if (v4l2_m2m_num_src_bufs_ready(fh->m2m_ctx) == 0) {
+ /* No more src bufs, notify app EOS */
+ notify_eos(ctx);
+ } else {
+ /* will send EOS later*/
+ ctx->stopping = 1;
+ }
+ return 0;
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static int mxc_jpeg_job_ready(void *priv)
+{
+ struct mxc_jpeg_ctx *ctx = priv;
+ unsigned int num_src_bufs_ready;
+ unsigned int num_dst_bufs_ready;
+ unsigned long flags;
+
+ spin_lock_irqsave(&ctx->mxc_jpeg->hw_lock, flags);
+
+ num_src_bufs_ready = v4l2_m2m_num_src_bufs_ready(ctx->fh.m2m_ctx);
+ num_dst_bufs_ready = v4l2_m2m_num_dst_bufs_ready(ctx->fh.m2m_ctx);
+
+ spin_unlock_irqrestore(&ctx->mxc_jpeg->hw_lock, flags);
+
+ if (num_src_bufs_ready >= 1 && num_dst_bufs_ready >= 1)
+ return 1;
+ return 0;
+}
+static void mxc_jpeg_job_abort(void *priv)
+{
+ struct mxc_jpeg_ctx *ctx = priv;
+
+ ctx->aborting = 1;
+ dev_dbg(ctx->mxc_jpeg->dev, "Abort requested\n");
+}
+
+static int mxc_jpeg_queue_setup(struct vb2_queue *q,
+ unsigned int *num_buffers,
+ unsigned int *num_planes,
+ unsigned int sizes[],
+ struct device *alloc_ctxs[])
+{
+ struct mxc_jpeg_ctx *ctx = vb2_get_drv_priv(q);
+ struct mxc_jpeg_q_data *q_data = NULL;
+
+ q_data = mxc_jpeg_get_q_data(ctx, q->type);
+ if (!q_data)
+ return -EINVAL;
+ *num_planes = 1;
+
+ /* assuming worst case jpeg compression: 6 x raw file size */
+ sizes[0] = q_data->w * q_data->h * 6;
+
+ if (q_data->sizeimage[0] > 0)
+ sizes[0] = q_data->sizeimage[0];
+
+ return 0;
+}
+static int mxc_jpeg_start_streaming(struct vb2_queue *q, unsigned int count)
+{
+ struct mxc_jpeg_ctx *ctx = vb2_get_drv_priv(q);
+ int ret;
+
+ dev_dbg(ctx->mxc_jpeg->dev, "Start streaming ctx=%p", ctx);
+ ret = pm_runtime_get_sync(ctx->mxc_jpeg->dev);
+ return ret > 0 ? 0 : ret;
+}
+
+static void release_active_buffers(struct vb2_queue *q, enum vb2_buffer_state s)
+{
+ struct vb2_buffer *vb;
+
+ if (!list_empty(&q->queued_list))
+ list_for_each_entry(vb, &q->queued_list, queued_entry) {
+ if (vb->state == VB2_BUF_STATE_ACTIVE)
+ vb2_buffer_done(vb, s);
+ }
+}
+
+static void mxc_jpeg_stop_streaming(struct vb2_queue *q)
+{
+ struct mxc_jpeg_ctx *ctx = vb2_get_drv_priv(q);
+
+ dev_dbg(ctx->mxc_jpeg->dev, "Stop streaming ctx=%p", ctx);
+
+ /* Release all active buffers */
+ release_active_buffers(q, VB2_BUF_STATE_ERROR);
+
+ pm_runtime_put_sync(&ctx->mxc_jpeg->pdev->dev);
+}
+struct mxc_jpeg_stream {
+ u8 *addr;
+ u32 loc;
+ u32 end;
+};
+static u8 get_byte(struct mxc_jpeg_stream *stream)
+{
+ u8 ret;
+
+ if (stream->loc >= stream->end)
+ return -1;
+ ret = stream->addr[stream->loc];
+ stream->loc++;
+ return ret;
+}
+
+static void _bswap16(u16 *a)
+{
+ *a = ((*a & 0x00FF) << 8) | ((*a & 0xFF00) >> 8);
+}
+
+static int get_sof(struct device *dev,
+ struct mxc_jpeg_stream *stream,
+ struct mxc_jpeg_sof *sof)
+{
+ int i;
+
+ if (stream->loc + sizeof(struct mxc_jpeg_sof) >= stream->end)
+ return -1;
+ memcpy(sof, &stream->addr[stream->loc], sizeof(struct mxc_jpeg_sof));
+ _bswap16(&sof->length);
+ _bswap16(&sof->height);
+ _bswap16(&sof->width);
+ dev_dbg(dev, "JPEG SOF: precision=%d\n", sof->precision);
+ dev_dbg(dev, "JPEG SOF: height=%d, width=%d\n",
+ sof->height, sof->width);
+ for (i = 0; i < sof->components_no; i++) {
+ dev_dbg(dev, "JPEG SOF: comp_id=%d, H=0x%x, V=0x%x\n",
+ sof->comp[i].id, sof->comp[i].v, sof->comp[i].h);
+ }
+ return 0;
+}
+
+static int mxc_jpeg_valid_comp_id(
+ struct device *dev,
+ const struct mxc_jpeg_sof *sof)
+{
+ int valid = 1;
+ int i;
+
+ for (i = 0; i < sof->components_no; i++)
+ if (sof->comp[i].id > MXC_JPEG_MAX_COMPONENTS) {
+ valid = 0;
+ dev_err(dev, "Component %d has invalid ID: %d",
+ i, sof->comp[i].id);
+ }
+
+ return valid;
+}
+
+static enum mxc_jpeg_image_format mxc_jpeg_get_image_format(
+ struct device *dev,
+ const struct mxc_jpeg_sof *sof)
+{
+ if (sof->components_no == 1) {
+ dev_dbg(dev, "IMAGE_FORMAT is: MXC_JPEG_GRAY\n");
+ return MXC_JPEG_GRAY;
+ }
+ if (sof->components_no == 3) {
+ if (sof->comp[0].h == 2 && sof->comp[0].v == 2 &&
+ sof->comp[1].h == 1 && sof->comp[1].v == 1 &&
+ sof->comp[2].h == 1 && sof->comp[2].v == 1){
+ dev_dbg(dev, "IMAGE_FORMAT is: MXC_JPEG_YUV420\n");
+ return MXC_JPEG_YUV420;
+ }
+ if (sof->comp[0].h == 2 && sof->comp[0].v == 1 &&
+ sof->comp[1].h == 1 && sof->comp[1].v == 1 &&
+ sof->comp[2].h == 1 && sof->comp[2].v == 1){
+ dev_dbg(dev, "IMAGE_FORMAT is: MXC_JPEG_YUV422\n");
+ return MXC_JPEG_YUV422;
+ }
+ if (sof->comp[0].h == 1 && sof->comp[0].v == 1 &&
+ sof->comp[1].h == 1 && sof->comp[1].v == 1 &&
+ sof->comp[2].h == 1 && sof->comp[2].v == 1){
+ dev_dbg(dev, "IMAGE_FORMAT is: MXC_JPEG_YUV444\n");
+ return MXC_JPEG_YUV444;
+ }
+ }
+ if (sof->components_no == 4) {
+ if (sof->comp[0].h == 1 && sof->comp[0].v == 1 &&
+ sof->comp[1].h == 1 && sof->comp[1].v == 1 &&
+ sof->comp[2].h == 1 && sof->comp[2].v == 1 &&
+ sof->comp[3].h == 1 && sof->comp[3].v == 1){
+ /* this is not tested */
+ dev_dbg(dev, "IMAGE_FORMAT is: MXC_JPEG_ARGB\n");
+ return MXC_JPEG_ARGB;
+ }
+ }
+ dev_err(dev, "Could not identify image format\n");
+ return MXC_JPEG_INVALID;
+}
+
+static u32 mxc_jpeg_get_line_pitch(
+ struct device *dev,
+ const struct mxc_jpeg_sof *sof,
+ enum mxc_jpeg_image_format img_fmt)
+{
+ u32 line_pitch;
+
+ switch (img_fmt) {
+ case MXC_JPEG_YUV420:
+ line_pitch = sof->width * (sof->precision/8) * 1;
+ break;
+ case MXC_JPEG_YUV422:
+ line_pitch = sof->width * (sof->precision/8) * 2;
+ break;
+ case MXC_JPEG_RGB:
+ line_pitch = sof->width * (sof->precision/8) * 3;
+ break;
+ case MXC_JPEG_ARGB:
+ line_pitch = sof->width * (sof->precision/8) * 4;
+ break;
+ case MXC_JPEG_YUV444:
+ line_pitch = sof->width * (sof->precision/8) * 3;
+ break;
+ case MXC_JPEG_GRAY:
+ line_pitch = sof->width * (sof->precision/8) * 1;
+ break;
+ default:
+ line_pitch = sof->width * (sof->precision/8) * 3;
+ break;
+ }
+ dev_dbg(dev, "line_pitch = %d\n", line_pitch);
+ return line_pitch;
+}
+
+static int mxc_jpeg_parse(struct mxc_jpeg_ctx *ctx,
+ struct mxc_jpeg_desc *desc, u8 *src_addr, u32 size)
+{
+ struct device *dev = ctx->mxc_jpeg->dev;
+ struct mxc_jpeg_q_data *q_data_out, *q_data_cap;
+ struct mxc_jpeg_stream stream;
+ bool notfound = true;
+ struct mxc_jpeg_sof sof;
+ int byte;
+ enum mxc_jpeg_image_format img_fmt;
+ u32 fourcc;
+
+ memset(&sof, 0, sizeof(struct mxc_jpeg_sof));
+ stream.addr = src_addr;
+ stream.end = size;
+ stream.loc = 0;
+ while (notfound) {
+ byte = get_byte(&stream);
+ if (byte == -1)
+ return -EINVAL;
+ if (byte != 0xff)
+ continue;
+ do {
+ byte = get_byte(&stream);
+ } while (byte == 0xff);
+ if (byte == -1)
+ return false;
+ if (byte == 0)
+ continue;
+ switch (byte) {
+ case SOF2:
+ case SOF0:
+ if (get_sof(dev, &stream, &sof) == -1)
+ break;
+ notfound = false;
+ break;
+ default:
+ notfound = true;
+ }
+ }
+ q_data_out = mxc_jpeg_get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT);
+ if (sof.width != q_data_out->w || sof.height != q_data_out->h) {
+ dev_err(dev,
+ "Resolution mismatch: %dx%d (JPEG) versus %dx%d(user)",
+ sof.width, sof.height, q_data_out->w, q_data_out->h);
+ return -EINVAL;
+ }
+ if (sof.width % 8 != 0 || sof.height % 8 != 0) {
+ dev_err(dev, "JPEG width or height not multiple of 8: %dx%d\n",
+ sof.width, sof.height);
+ return -EINVAL;
+ }
+ if (sof.width > 0x2000 || sof.height > 0x2000) {
+ dev_err(dev, "JPEG width or height should be <= 8192: %dx%d\n",
+ sof.width, sof.height);
+ return -EINVAL;
+ }
+ if (sof.components_no > MXC_JPEG_MAX_COMPONENTS) {
+ dev_err(dev, "JPEG number of components should be <=%d",
+ MXC_JPEG_MAX_COMPONENTS);
+ return -EINVAL;
+ }
+ if (!mxc_jpeg_valid_comp_id(dev, &sof)) {
+ dev_err(dev, "JPEG component identifiers should be 0-3 or 1-4");
+ return -EINVAL;
+ }
+ desc->imgsize = sof.width << 16 | sof.height;
+ dev_dbg(dev, "JPEG imgsize = 0x%x (%dx%d)\n", desc->imgsize,
+ sof.width, sof.height);
+ img_fmt = mxc_jpeg_get_image_format(dev, &sof);
+ if (img_fmt == MXC_JPEG_INVALID)
+ return -EINVAL;
+ if (mxc_jpeg_imgfmt_to_fourcc(img_fmt, &fourcc)) {
+ dev_err(dev, "Fourcc not found for %d", img_fmt);
+ return -EINVAL;
+ }
+
+ q_data_cap = mxc_jpeg_get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
+ if (q_data_cap->w == 0 && q_data_cap->h == 0) {
+ dev_dbg(dev, "capture queue format is not set-up yet, using output queue settings");
+ q_data_cap->w = q_data_out->w;
+ q_data_cap->h = q_data_out->h;
+ q_data_cap->fmt = mxc_jpeg_find_format(ctx, fourcc);
+ }
+ if (fourcc != q_data_cap->fmt->fourcc) {
+ char *jpeg_format_name = fourcc_to_str(fourcc);
+ char *user_format_name = fourcc_to_str(q_data_cap->fmt->fourcc);
+
+ dev_warn(dev,
+ "Pixel format mismatch: jpeg(%s) versus user (%s)",
+ jpeg_format_name, user_format_name);
+ dev_warn(dev, "Keeping user settings\n");
+ kfree(jpeg_format_name);
+ kfree(user_format_name);
+ img_fmt = mxc_jpeg_fourcc_to_imgfmt(q_data_cap->fmt->fourcc);
+ }
+ desc->stm_ctrl |= STM_CTRL_IMAGE_FORMAT(img_fmt);
+ desc->line_pitch = mxc_jpeg_get_line_pitch(dev, &sof, img_fmt);
+ q_data_cap->stride = desc->line_pitch;
+ q_data_cap->sizeimage[0] = q_data_cap->w * q_data_cap->h *
+ q_data_cap->fmt->depth / 8;
+
+ return 0;
+}
+
+static void mxc_jpeg_buf_queue(struct vb2_buffer *vb)
+{
+ int ret;
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+ struct mxc_jpeg_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
+ int slot = 0; /* TODO get slot*/
+
+ if (vb->vb2_queue->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ goto end;
+
+ /* for V4L2_BUF_TYPE_VIDEO_OUTPUT */
+ if (ctx->mode != MXC_JPEG_DECODE)
+ goto end;
+ ret = mxc_jpeg_parse(ctx,
+ ctx->mxc_jpeg->slot_data[slot].desc,
+ (u8 *)vb2_plane_vaddr(vb, 0),
+ vb2_get_plane_payload(vb, 0));
+ if (ret) {
+ v4l2_err(&ctx->mxc_jpeg->v4l2_dev,
+ "driver does not support this resolution/format\n");
+ vb2_buffer_done(vb, VB2_BUF_STATE_ERROR);
+ return;
+ }
+
+
+ if (ctx->state == MXC_JPEG_INIT) {
+ static const struct v4l2_event ev_src_ch = {
+ .type = V4L2_EVENT_SOURCE_CHANGE,
+ .u.src_change.changes =
+ V4L2_EVENT_SRC_CH_RESOLUTION,
+ };
+
+ v4l2_event_queue_fh(&ctx->fh, &ev_src_ch);
+ ctx->state = MXC_JPEG_RUNNING;
+ }
+
+end:
+ v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf);
+}
+static int mxc_jpeg_buf_prepare(struct vb2_buffer *vb)
+{
+ struct mxc_jpeg_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
+ struct mxc_jpeg_q_data *q_data = NULL;
+ unsigned long sizeimage;
+
+ q_data = mxc_jpeg_get_q_data(ctx, vb->vb2_queue->type);
+ if (!q_data)
+ return -EINVAL;
+ sizeimage = q_data->sizeimage[0];
+ if (vb2_plane_size(vb, 0) < sizeimage) {
+ dev_err(ctx->mxc_jpeg->dev, "buffer too small (%lu < %lu)",
+ vb2_plane_size(vb, 0), sizeimage);
+ return -EINVAL;
+ }
+ vb2_set_plane_payload(vb, 0, sizeimage);
+ return 0;
+}
+
+static void mxc_jpeg_buf_clean(struct vb2_buffer *vb)
+{
+ return;
+}
+
+static const struct vb2_ops mxc_jpeg_qops = {
+ .queue_setup = mxc_jpeg_queue_setup,
+ .wait_prepare = vb2_ops_wait_prepare,
+ .wait_finish = vb2_ops_wait_finish,
+ .buf_prepare = mxc_jpeg_buf_prepare,
+ .buf_cleanup = mxc_jpeg_buf_clean,
+ .start_streaming = mxc_jpeg_start_streaming,
+ .stop_streaming = mxc_jpeg_stop_streaming,
+ .buf_queue = mxc_jpeg_buf_queue,
+};
+static int mxc_jpeg_queue_init(void *priv, struct vb2_queue *src_vq,
+ struct vb2_queue *dst_vq)
+{
+ struct mxc_jpeg_ctx *ctx = priv;
+ int ret;
+
+ src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
+ src_vq->io_modes = VB2_MMAP | VB2_USERPTR;
+ src_vq->drv_priv = ctx;
+ src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
+ src_vq->ops = &mxc_jpeg_qops;
+ src_vq->mem_ops = &vb2_dma_contig_memops;
+ src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
+ src_vq->lock = &ctx->mxc_jpeg->lock;
+ src_vq->dev = ctx->mxc_jpeg->dev;
+ src_vq->allow_zero_bytesused = 1; /* keep old userspace apps working */
+
+ ret = vb2_queue_init(src_vq);
+ if (ret)
+ return ret;
+
+ dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ dst_vq->io_modes = VB2_MMAP | VB2_USERPTR;
+ dst_vq->drv_priv = ctx;
+ dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
+ dst_vq->ops = &mxc_jpeg_qops;
+ dst_vq->mem_ops = &vb2_dma_contig_memops;
+ dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
+ dst_vq->lock = &ctx->mxc_jpeg->lock;
+ dst_vq->dev = ctx->mxc_jpeg->dev;
+
+ ret = vb2_queue_init(dst_vq);
+ return ret;
+}
+
+static int mxc_jpeg_alloc_slot_data(struct mxc_jpeg_dev *jpeg)
+{
+ int slot;
+
+ for (slot = 0; slot < MXC_MAX_SLOTS; slot++) {
+ /* allocate descriptor for decoding/encoding phase */
+ jpeg->slot_data[slot].desc = dma_zalloc_coherent(jpeg->dev,
+ sizeof(struct mxc_jpeg_desc),
+ &(jpeg->slot_data[slot].desc_handle), 0);
+ if (!jpeg->slot_data[slot].desc)
+ goto err;
+ dev_dbg(jpeg->dev, "Descriptor for dec/enc: %p 0x%llx\n",
+ jpeg->slot_data[slot].desc,
+ jpeg->slot_data[slot].desc_handle);
+
+ /* allocate descriptor for configuration phase (encoder only) */
+ jpeg->slot_data[slot].cfg_desc = dma_zalloc_coherent(jpeg->dev,
+ sizeof(struct mxc_jpeg_desc),
+ &jpeg->slot_data[slot].cfg_desc_handle, 0);
+ if (!jpeg->slot_data[slot].cfg_desc)
+ goto err;
+ dev_dbg(jpeg->dev, "Descriptor for config phase: %p 0x%llx\n",
+ jpeg->slot_data[slot].cfg_desc,
+ jpeg->slot_data[slot].cfg_desc_handle);
+
+ /* allocate configuration stream */
+ jpeg->slot_data[slot].cfg_stream_vaddr = dma_zalloc_coherent(
+ jpeg->dev,
+ sizeof(hactbl),
+ &jpeg->slot_data[slot].cfg_stream_handle, 0);
+ if (!jpeg->slot_data[slot].cfg_stream_vaddr)
+ goto err;
+ dev_dbg(jpeg->dev, "Configuration stream: %p 0x%llx\n",
+ jpeg->slot_data[slot].cfg_stream_vaddr,
+ jpeg->slot_data[slot].cfg_stream_handle);
+
+ /* initial set-up for configuration stream
+ * TODO: fixup the sizes, currently harcoded to 64x64)
+ */
+ memcpy(jpeg->slot_data[slot].cfg_stream_vaddr,
+ &hactbl, sizeof(hactbl));
+ }
+ return 0;
+err:
+ dev_err(jpeg->dev, "Could not allocate descriptors\n");
+ return 1;
+}
+
+static int mxc_jpeg_free_slot_data(struct mxc_jpeg_dev *jpeg)
+{
+ int slot;
+
+ for (slot = 0; slot < MXC_MAX_SLOTS; slot++) {
+ /* free descriptor for decoding/encoding phase */
+ dma_free_coherent(jpeg->dev, sizeof(struct mxc_jpeg_desc),
+ jpeg->slot_data[slot].desc,
+ jpeg->slot_data[slot].desc_handle);
+
+ /* free descriptor for configuration phase (encoder only) */
+ dma_free_coherent(jpeg->dev, sizeof(struct mxc_jpeg_desc),
+ jpeg->slot_data[slot].cfg_desc,
+ jpeg->slot_data[slot].cfg_desc_handle);
+
+ /* free configuration stream */
+ dma_free_coherent(jpeg->dev, sizeof(hactbl),
+ jpeg->slot_data[slot].cfg_stream_vaddr,
+ jpeg->slot_data[slot].cfg_stream_handle);
+ }
+ return 0;
+}
+
+static int mxc_jpeg_open(struct file *file)
+{
+ struct mxc_jpeg_dev *mxc_jpeg = video_drvdata(file);
+ struct video_device *mxc_vfd = video_devdata(file);
+ struct mxc_jpeg_ctx *ctx;
+ struct mxc_jpeg_fmt *out_fmt, *cap_fmt;
+ int ret = 0;
+
+ ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
+ if (!ctx)
+ return -ENOMEM;
+
+ if (mutex_lock_interruptible(&mxc_jpeg->lock)) {
+ ret = -ERESTARTSYS;
+ goto free;
+ }
+
+ pm_runtime_get_sync(mxc_jpeg->dev);
+
+ v4l2_fh_init(&ctx->fh, mxc_vfd);
+ file->private_data = &ctx->fh;
+ v4l2_fh_add(&ctx->fh);
+
+ ctx->mxc_jpeg = mxc_jpeg;
+ if (mxc_jpeg->mode == MXC_JPEG_ENCODE) {
+ ctx->mode = MXC_JPEG_ENCODE;
+ out_fmt = mxc_jpeg_find_format(ctx, V4L2_PIX_FMT_RGB24);
+ cap_fmt = mxc_jpeg_find_format(ctx, V4L2_PIX_FMT_JPEG);
+ } else {
+ ctx->mode = MXC_JPEG_DECODE;
+ out_fmt = mxc_jpeg_find_format(ctx, V4L2_PIX_FMT_JPEG);
+ cap_fmt = mxc_jpeg_find_format(ctx, V4L2_PIX_FMT_RGB24);
+ }
+ ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(mxc_jpeg->m2m_dev, ctx,
+ mxc_jpeg_queue_init);
+ ctx->out_q.fmt = out_fmt;
+ ctx->cap_q.fmt = cap_fmt;
+ if (IS_ERR(ctx->fh.m2m_ctx)) {
+ ret = PTR_ERR(ctx->fh.m2m_ctx);
+ goto error;
+ }
+
+ if (mxc_jpeg_alloc_slot_data(mxc_jpeg))
+ goto error;
+
+ mutex_unlock(&mxc_jpeg->lock);
+ return 0;
+
+error:
+ v4l2_fh_del(&ctx->fh);
+ v4l2_fh_exit(&ctx->fh);
+ mutex_unlock(&mxc_jpeg->lock);
+free:
+ kfree(ctx);
+ return ret;
+}
+
+static int mxc_jpeg_querycap(struct file *file, void *priv,
+ struct v4l2_capability *cap)
+{
+ struct mxc_jpeg_dev *mxc_jpeg = video_drvdata(file);
+
+ strlcpy(cap->driver, MXC_JPEG_NAME " decoder", sizeof(cap->driver));
+ strlcpy(cap->card, MXC_JPEG_NAME " decoder", sizeof(cap->card));
+ snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s",
+ dev_name(mxc_jpeg->dev));
+ cap->device_caps = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_M2M;
+ cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
+
+ return 0;
+}
+static int mxc_jpeg_enum_fmt_vid_cap(struct file *file, void *priv,
+ struct v4l2_fmtdesc *f)
+{
+ struct mxc_jpeg_ctx *ctx = mxc_jpeg_fh_to_ctx(priv);
+
+ if (ctx->mode == MXC_JPEG_ENCODE)
+ return enum_fmt(mxc_formats, MXC_JPEG_NUM_FORMATS, f,
+ MXC_IN_FORMAT);
+ else
+ return enum_fmt(mxc_formats, MXC_JPEG_NUM_FORMATS, f,
+ MXC_OUT_FORMAT);
+}
+
+static int mxc_jpeg_enum_fmt_vid_out(struct file *file, void *priv,
+ struct v4l2_fmtdesc *f)
+{
+ struct mxc_jpeg_ctx *ctx = mxc_jpeg_fh_to_ctx(priv);
+
+ if (ctx->mode == MXC_JPEG_DECODE)
+ return enum_fmt(mxc_formats, MXC_JPEG_NUM_FORMATS, f,
+ MXC_IN_FORMAT);
+ else
+ return enum_fmt(mxc_formats, MXC_JPEG_NUM_FORMATS, f,
+ MXC_OUT_FORMAT);
+}
+
+static int mxc_jpeg_bound_align_image(u32 *w, unsigned int wmin,
+ unsigned int wmax, unsigned int walign,
+ u32 *h, unsigned int hmin,
+ unsigned int hmax, unsigned int halign)
+{
+ int width, height, w_step, h_step;
+
+ width = *w;
+ height = *h;
+ w_step = 1 << walign;
+ h_step = 1 << halign;
+
+ v4l_bound_align_image(w, wmin, wmax, walign, h, hmin, hmax, halign, 0);
+ if (*w < width && (*w + w_step) <= wmax)
+ *w += w_step;
+ if (*h < height && (*h + h_step) <= hmax)
+ *h += h_step;
+
+ return (width != *w || height != *h);
+}
+static int mxc_jpeg_try_fmt(struct v4l2_format *f, struct mxc_jpeg_fmt *fmt,
+ struct mxc_jpeg_ctx *ctx, int q_type)
+{
+ struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp;
+ struct v4l2_plane_pix_format *pfmt = &pix_mp->plane_fmt[0];
+ u32 w = pix_mp->width;
+ u32 h = pix_mp->height;
+ unsigned int mode = ctx->mode;
+
+ memset(pix_mp->reserved, 0, sizeof(pix_mp->reserved));
+ pix_mp->field = V4L2_FIELD_NONE;
+ pix_mp->num_planes = fmt->colplanes;
+ pix_mp->pixelformat = fmt->fourcc;
+ mxc_jpeg_bound_align_image(&w,
+ MXC_JPEG_MIN_WIDTH,
+ MXC_JPEG_MAX_WIDTH,
+ MXC_JPEG_W_ALIGN,
+ &h,
+ MXC_JPEG_MIN_HEIGHT,
+ MXC_JPEG_MAX_HEIGHT,
+ MXC_JPEG_H_ALIGN);
+
+ memset(pfmt->reserved, 0, sizeof(pfmt->reserved));
+
+ /* TODO try_fmt should not modify the state, move to s_fmt */
+ if (q_type == MXC_JPEG_FMT_TYPE_ENC && mode == MXC_JPEG_DECODE) {
+ pfmt->bytesperline = 0;
+ /* Source size must be aligned to 128 */
+ pfmt->sizeimage = mxc_jpeg_align(pfmt->sizeimage, 128);
+ if (pfmt->sizeimage == 0)
+ pfmt->sizeimage = MXC_JPEG_DEFAULT_SIZEIMAGE;
+ } else if (q_type == MXC_JPEG_FMT_TYPE_RAW && mode == MXC_JPEG_DECODE) {
+ pfmt->bytesperline = w * (fmt->depth / 8);
+ pfmt->sizeimage = w * h * fmt->depth / 8;
+ } else if (q_type == MXC_JPEG_FMT_TYPE_ENC && mode == MXC_JPEG_ENCODE) {
+ pfmt->bytesperline = 0;
+ /* assuming worst jpeg compression */
+ pfmt->sizeimage = w * h * 6;
+ } else { /* MXC_JPEG_FMT_TYPE_RAW && MXC_JPEG_ENCODE */
+ pfmt->bytesperline = w * (fmt->depth / 8);
+ pfmt->sizeimage = w * h * fmt->depth / 8;
+ }
+
+ return 0;
+}
+static int mxc_jpeg_try_fmt_vid_cap(struct file *file, void *priv,
+ struct v4l2_format *f)
+{
+ struct mxc_jpeg_ctx *ctx = mxc_jpeg_fh_to_ctx(priv);
+ struct mxc_jpeg_dev *jpeg = ctx->mxc_jpeg;
+ struct device *dev = jpeg->dev;
+ struct mxc_jpeg_fmt *fmt;
+ u32 fourcc = f->fmt.pix_mp.pixelformat;
+
+ int q_type = (ctx->mode == MXC_JPEG_DECODE) ?
+ MXC_JPEG_FMT_TYPE_RAW : MXC_JPEG_FMT_TYPE_ENC;
+
+ fmt = mxc_jpeg_find_format(ctx, f->fmt.pix_mp.pixelformat);
+ if (!fmt || (fmt->flags != q_type)) {
+ char *format_name = fourcc_to_str(fourcc);
+
+ dev_err(dev, "Format not supported: %s.\n",
+ format_name);
+ kfree(format_name);
+ return -1;
+ }
+ return mxc_jpeg_try_fmt(f, fmt, ctx, q_type);
+}
+static int mxc_jpeg_try_fmt_vid_out(struct file *file, void *priv,
+ struct v4l2_format *f)
+{
+ struct mxc_jpeg_ctx *ctx = mxc_jpeg_fh_to_ctx(priv);
+ struct mxc_jpeg_dev *jpeg = ctx->mxc_jpeg;
+ struct device *dev = jpeg->dev;
+ struct mxc_jpeg_fmt *fmt;
+ u32 fourcc = f->fmt.pix_mp.pixelformat;
+
+ int q_type = (ctx->mode == MXC_JPEG_ENCODE) ?
+ MXC_JPEG_FMT_TYPE_RAW : MXC_JPEG_FMT_TYPE_ENC;
+
+ fmt = mxc_jpeg_find_format(ctx, fourcc);
+ if (!fmt || (fmt->flags != q_type)) {
+ char *format_name = fourcc_to_str(fourcc);
+
+ dev_err(dev, "Format not supported: %s.\n",
+ format_name);
+ kfree(format_name);
+ return -1;
+ }
+ return mxc_jpeg_try_fmt(f, fmt, ctx, q_type);
+}
+static int mxc_jpeg_s_fmt(struct mxc_jpeg_ctx *ctx,
+ struct v4l2_format *f)
+{
+ struct vb2_queue *vq;
+ struct mxc_jpeg_q_data *q_data = NULL;
+ struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp;
+ struct mxc_jpeg_dev *jpeg = ctx->mxc_jpeg;
+
+ vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type);
+ if (!vq)
+ return -EINVAL;
+
+ q_data = mxc_jpeg_get_q_data(ctx, f->type);
+
+ if (vb2_is_busy(vq)) {
+ v4l2_err(&jpeg->v4l2_dev, "queue busy\n");
+ return -EBUSY;
+ }
+
+ q_data->fmt = mxc_jpeg_find_format(ctx, pix_mp->pixelformat);
+ q_data->w = pix_mp->width;
+ q_data->h = pix_mp->height;
+ q_data->bytesperline[0] = pix_mp->plane_fmt[0].bytesperline;
+ q_data->sizeimage[0] = pix_mp->plane_fmt[0].sizeimage;
+
+ return 0;
+}
+static int mxc_jpeg_s_fmt_vid_cap(struct file *file, void *priv,
+ struct v4l2_format *f)
+{
+ int ret;
+
+ ret = mxc_jpeg_try_fmt_vid_cap(file, priv, f);
+ if (ret)
+ return ret;
+
+ return mxc_jpeg_s_fmt(mxc_jpeg_fh_to_ctx(priv), f);
+}
+static int mxc_jpeg_s_fmt_vid_out(struct file *file, void *priv,
+ struct v4l2_format *f)
+{
+ int ret;
+
+ ret = mxc_jpeg_try_fmt_vid_out(file, priv, f);
+ if (ret)
+ return ret;
+
+ return mxc_jpeg_s_fmt(mxc_jpeg_fh_to_ctx(priv), f);
+}
+static int mxc_jpeg_g_fmt_vid_cap(struct file *file, void *priv,
+ struct v4l2_format *f)
+{
+ struct mxc_jpeg_ctx *ctx = mxc_jpeg_fh_to_ctx(priv);
+ struct v4l2_pix_format *pix = &f->fmt.pix;
+ struct mxc_jpeg_q_data *q_data = mxc_jpeg_get_q_data(ctx, f->type);
+
+ pix->pixelformat = q_data->fmt->fourcc;
+ pix->width = q_data->w;
+ pix->height = q_data->h;
+ pix->field = V4L2_FIELD_NONE;
+ pix->colorspace = V4L2_COLORSPACE_REC709;
+ pix->bytesperline = q_data->stride;
+ pix->sizeimage = q_data->sizeimage[0];
+
+ return 0;
+}
+static int mxc_jpeg_g_fmt_vid_out(struct file *file, void *priv,
+ struct v4l2_format *f)
+{
+ return 0;
+}
+
+static int mxc_jpeg_subscribe_event(struct v4l2_fh *fh,
+ const struct v4l2_event_subscription *sub)
+{
+ switch (sub->type) {
+ case V4L2_EVENT_EOS:
+ return v4l2_event_subscribe(fh, sub, 0, NULL);
+ case V4L2_EVENT_SOURCE_CHANGE:
+ return v4l2_src_change_event_subscribe(fh, sub);
+ default:
+ return -EINVAL;
+ }
+}
+
+static int mxc_jpeg_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
+{
+ struct v4l2_fh *fh = file->private_data;
+ struct mxc_jpeg_ctx *ctx = mxc_jpeg_fh_to_ctx(priv);
+ struct device *dev = ctx->mxc_jpeg->dev;
+ struct vb2_queue *vq;
+
+ dev_dbg(dev, "QBUF type=%d, index=%d", buf->type, buf->index);
+ vq = v4l2_m2m_get_vq(fh->m2m_ctx, buf->type);
+ if (buf->index >= vq->num_buffers) {
+ dev_err(dev, "buffer index out of range\n");
+ return -EINVAL;
+ }
+
+ return v4l2_m2m_qbuf(file, fh->m2m_ctx, buf);
+}
+
+static int mxc_jpeg_dqbuf(struct file *file, void *priv,
+ struct v4l2_buffer *buf)
+{
+ struct v4l2_fh *fh = file->private_data;
+ struct mxc_jpeg_ctx *ctx = mxc_jpeg_fh_to_ctx(priv);
+ struct device *dev = ctx->mxc_jpeg->dev;
+ int num_src_ready = v4l2_m2m_num_src_bufs_ready(fh->m2m_ctx);
+ int ret;
+
+ dev_dbg(dev, "DQBUF type=%d, index=%d", buf->type, buf->index);
+ if (ctx->stopping == 1 && num_src_ready == 0) {
+ /* No more src bufs, notify app EOS */
+ notify_eos(ctx);
+ ctx->stopping = 0;
+ }
+
+ ret = v4l2_m2m_dqbuf(file, fh->m2m_ctx, buf);
+ buf->field = V4L2_FIELD_NONE;
+
+ return ret;
+}
+static const struct v4l2_ioctl_ops mxc_jpeg_ioctl_ops = {
+ .vidioc_querycap = mxc_jpeg_querycap,
+ .vidioc_enum_fmt_vid_cap = mxc_jpeg_enum_fmt_vid_cap,
+ .vidioc_enum_fmt_vid_out = mxc_jpeg_enum_fmt_vid_out,
+
+ .vidioc_try_fmt_vid_cap = mxc_jpeg_try_fmt_vid_cap,
+ .vidioc_try_fmt_vid_out = mxc_jpeg_try_fmt_vid_out,
+
+ .vidioc_s_fmt_vid_cap = mxc_jpeg_s_fmt_vid_cap,
+ .vidioc_s_fmt_vid_out = mxc_jpeg_s_fmt_vid_out,
+
+ .vidioc_g_fmt_vid_cap = mxc_jpeg_g_fmt_vid_cap,
+ .vidioc_g_fmt_vid_out = mxc_jpeg_g_fmt_vid_out,
+
+ .vidioc_subscribe_event = mxc_jpeg_subscribe_event,
+ .vidioc_decoder_cmd = mxc_jpeg_decoder_cmd,
+
+ .vidioc_qbuf = mxc_jpeg_qbuf,
+ .vidioc_dqbuf = mxc_jpeg_dqbuf,
+
+ .vidioc_create_bufs = v4l2_m2m_ioctl_create_bufs,
+ .vidioc_prepare_buf = v4l2_m2m_ioctl_prepare_buf,
+ .vidioc_reqbufs = v4l2_m2m_ioctl_reqbufs,
+ .vidioc_querybuf = v4l2_m2m_ioctl_querybuf,
+ .vidioc_expbuf = v4l2_m2m_ioctl_expbuf,
+ .vidioc_streamon = v4l2_m2m_ioctl_streamon,
+ .vidioc_streamoff = v4l2_m2m_ioctl_streamoff,
+};
+
+static int mxc_jpeg_release(struct file *file)
+{
+ struct mxc_jpeg_dev *mxc_jpeg = video_drvdata(file);
+ struct mxc_jpeg_ctx *ctx = mxc_jpeg_fh_to_ctx(file->private_data);
+
+ mutex_lock(&mxc_jpeg->lock);
+ mxc_jpeg_free_slot_data(mxc_jpeg);
+ v4l2_m2m_ctx_release(ctx->fh.m2m_ctx);
+ v4l2_fh_del(&ctx->fh);
+ v4l2_fh_exit(&ctx->fh);
+ kfree(ctx);
+ mutex_unlock(&mxc_jpeg->lock);
+
+ pm_runtime_put_sync(mxc_jpeg->dev);
+ return 0;
+}
+
+static const struct v4l2_file_operations mxc_jpeg_fops = {
+ .owner = THIS_MODULE,
+ .open = mxc_jpeg_open,
+ .release = mxc_jpeg_release,
+ .poll = v4l2_m2m_fop_poll,
+ .unlocked_ioctl = video_ioctl2,
+ .mmap = v4l2_m2m_fop_mmap,
+};
+static struct v4l2_m2m_ops mxc_jpeg_m2m_ops = {
+ .device_run = mxc_jpeg_device_run,
+ .job_ready = mxc_jpeg_job_ready,
+ .job_abort = mxc_jpeg_job_abort,
+};
+
+static int mxc_jpeg_probe(struct platform_device *pdev)
+{
+ struct mxc_jpeg_dev *jpeg;
+ struct device *dev = &pdev->dev;
+ struct resource *res;
+ int dec_irq;
+ int ret;
+ int mode;
+ const struct of_device_id *of_id;
+
+ of_id = of_match_node(mxc_jpeg_match, dev->of_node);
+ mode = (int)(u64) of_id->data;
+
+ jpeg = devm_kzalloc(dev, sizeof(struct mxc_jpeg_dev), GFP_KERNEL);
+ if (!jpeg)
+ return -ENOMEM;
+
+ mutex_init(&jpeg->lock);
+ spin_lock_init(&jpeg->hw_lock);
+
+ if (dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32))) {
+ dev_err(&pdev->dev, "No suitable DMA available.\n");
+ return -EINVAL;
+ }
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ dec_irq = platform_get_irq(pdev, 0);
+ if (!res || dec_irq < 0) {
+ dev_err(&pdev->dev, "Failed to get dec_irq %d.\n", dec_irq);
+ ret = -EINVAL;
+ goto err_irq;
+ }
+ ret = devm_request_irq(&pdev->dev, dec_irq, mxc_jpeg_dec_irq, 0,
+ pdev->name, jpeg);
+ if (ret) {
+ dev_err(&pdev->dev, "Failed to request dec_irq %d (%d)\n",
+ dec_irq, ret);
+ ret = -EINVAL;
+ goto err_irq;
+ }
+ jpeg->base_reg = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(jpeg->base_reg))
+ return PTR_ERR(jpeg->base_reg);
+
+ jpeg->pdev = pdev;
+ jpeg->dev = dev;
+ jpeg->mode = mode;
+
+ /* Start clock */
+ jpeg->clk_ipg = devm_clk_get(dev, "ipg");
+ if (IS_ERR(jpeg->clk_ipg)) {
+ dev_err(dev, "failed to get clock: ipg\n");
+ goto err_clk;
+ }
+
+ jpeg->clk_per = devm_clk_get(dev, "per");
+ if (IS_ERR(jpeg->clk_per)) {
+ dev_err(dev, "failed to get clock: per\n");
+ goto err_clk;
+ }
+
+ /* v4l2 */
+ ret = v4l2_device_register(dev, &jpeg->v4l2_dev);
+ if (ret) {
+ dev_err(dev, "failed to register v4l2 device\n");
+ goto err_register;
+ }
+ jpeg->m2m_dev = v4l2_m2m_init(&mxc_jpeg_m2m_ops);
+ if (IS_ERR(jpeg->m2m_dev)) {
+ dev_err(dev, "failed to register v4l2 device\n");
+ goto err_m2m;
+ }
+
+ jpeg->dec_vdev = video_device_alloc();
+ if (!jpeg->dec_vdev) {
+ dev_err(dev, "failed to register v4l2 device\n");
+ goto err_vdev_alloc;
+ }
+ if (mode == MXC_JPEG_ENCODE)
+ snprintf(jpeg->dec_vdev->name,
+ sizeof(jpeg->dec_vdev->name),
+ "%s-enc", MXC_JPEG_M2M_NAME);
+ else
+ snprintf(jpeg->dec_vdev->name,
+ sizeof(jpeg->dec_vdev->name),
+ "%s-dec", MXC_JPEG_M2M_NAME);
+
+ jpeg->dec_vdev->fops = &mxc_jpeg_fops;
+ jpeg->dec_vdev->ioctl_ops = &mxc_jpeg_ioctl_ops;
+ jpeg->dec_vdev->minor = -1;
+ jpeg->dec_vdev->release = video_device_release;
+ jpeg->dec_vdev->lock = &jpeg->lock; /* lock for ioctl serialization*/
+ jpeg->dec_vdev->v4l2_dev = &jpeg->v4l2_dev;
+ jpeg->dec_vdev->vfl_dir = VFL_DIR_M2M;
+ jpeg->dec_vdev->device_caps = V4L2_CAP_STREAMING |
+ V4L2_CAP_VIDEO_M2M;
+
+ ret = video_register_device(jpeg->dec_vdev, VFL_TYPE_GRABBER, -1);
+ if (ret) {
+ dev_err(dev, "failed to register video device\n");
+ goto err_vdev_register;
+ }
+ video_set_drvdata(jpeg->dec_vdev, jpeg);
+ if (mode == MXC_JPEG_ENCODE)
+ v4l2_info(&jpeg->v4l2_dev,
+ "encoder device registered as /dev/video%d (%d,%d)\n",
+ jpeg->dec_vdev->num, VIDEO_MAJOR,
+ jpeg->dec_vdev->minor);
+ else
+ v4l2_info(&jpeg->v4l2_dev,
+ "decoder device registered as /dev/video%d (%d,%d)\n",
+ jpeg->dec_vdev->num, VIDEO_MAJOR,
+ jpeg->dec_vdev->minor);
+
+ platform_set_drvdata(pdev, jpeg);
+ pm_runtime_enable(dev);
+ return 0;
+
+err_vdev_register:
+ video_device_release(jpeg->dec_vdev);
+
+err_vdev_alloc:
+ v4l2_m2m_release(jpeg->m2m_dev);
+
+err_m2m:
+ v4l2_device_unregister(&jpeg->v4l2_dev);
+
+err_register:
+err_irq:
+err_clk:
+ return ret;
+}
+
+#ifdef CONFIG_PM
+static int mxc_jpeg_runtime_resume(struct device *dev)
+{
+ struct mxc_jpeg_dev *jpeg = dev_get_drvdata(dev);
+ int ret;
+
+ ret = clk_prepare_enable(jpeg->clk_ipg);
+ if (ret < 0) {
+ dev_err(dev, "failed to enable clock: ipg\n");
+ goto err_clk;
+ }
+
+ ret = clk_prepare_enable(jpeg->clk_per);
+ if (ret < 0) {
+ dev_err(dev, "failed to enable clock: per\n");
+ goto err_clk;
+ }
+
+ return 0;
+
+err_clk:
+ return ret;
+}
+
+static int mxc_jpeg_runtime_suspend(struct device *dev)
+{
+ struct mxc_jpeg_dev *jpeg = dev_get_drvdata(dev);
+
+ clk_disable_unprepare(jpeg->clk_ipg);
+ clk_disable_unprepare(jpeg->clk_per);
+
+ return 0;
+}
+#endif
+
+static const struct dev_pm_ops mxc_jpeg_pm_ops = {
+ SET_RUNTIME_PM_OPS(mxc_jpeg_runtime_suspend,
+ mxc_jpeg_runtime_resume, NULL)
+};
+
+static int mxc_jpeg_remove(struct platform_device *pdev)
+{
+ struct mxc_jpeg_dev *jpeg = platform_get_drvdata(pdev);
+
+ pm_runtime_disable(&pdev->dev);
+ video_unregister_device(jpeg->dec_vdev);
+ video_device_release(jpeg->dec_vdev);
+ v4l2_m2m_release(jpeg->m2m_dev);
+ v4l2_device_unregister(&jpeg->v4l2_dev);
+
+ return 0;
+}
+
+MODULE_DEVICE_TABLE(of, mxc_jpeg_match);
+
+static struct platform_driver mxc_jpeg_driver = {
+ .probe = mxc_jpeg_probe,
+ .remove = mxc_jpeg_remove,
+ .driver = {
+ .name = "mxc-jpeg",
+ .of_match_table = mxc_jpeg_match,
+ .pm = &mxc_jpeg_pm_ops,
+ },
+};
+module_platform_driver(mxc_jpeg_driver);
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/platform/imx8/mxc-jpeg.h b/drivers/media/platform/imx8/mxc-jpeg.h
new file mode 100644
index 000000000000..d1e129484127
--- /dev/null
+++ b/drivers/media/platform/imx8/mxc-jpeg.h
@@ -0,0 +1,144 @@
+/*
+ * Copyright 2018 NXP
+ */
+/*
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-fh.h>
+
+#ifndef _MXC_JPEG_CORE_H
+#define _MXC_JPEG_CORE_H
+
+#define MXC_JPEG_M2M_NAME "mxc-jpeg"
+#define MXC_JPEG_NAME "mxc-jpeg"
+#define MXC_IN_FORMAT 0
+#define MXC_OUT_FORMAT 1
+#define MXC_JPEG_INIT 0
+#define MXC_JPEG_RUNNING 1
+#define MXC_JPEG_FMT_TYPE_ENC 0
+#define MXC_JPEG_FMT_TYPE_RAW 1
+#define MXC_JPEG_MIN_HEIGHT 0x8
+#define MXC_JPEG_MIN_WIDTH 0x8
+#define MXC_JPEG_MAX_HEIGHT 0x2000
+#define MXC_JPEG_MAX_WIDTH 0x2000
+#define MXC_JPEG_H_ALIGN 3
+#define MXC_JPEG_W_ALIGN 3
+#define MXC_JPEG_DEFAULT_SIZEIMAGE 10000
+#define MXC_JPEG_ENC_CONF 1
+#define MXC_JPEG_ENC_DONE 0
+#define SOF0 0xC0
+#define SOF2 0xC2
+#define MXC_JPEG_ENC_CONF_DONE 1
+
+
+/**
+ * struct jpeg_fmt - driver's internal color format data
+ * @name: format description
+ * @fourcc: fourcc code, 0 if not applicable
+ * @depth: number of bits per pixel
+ * @colplanes: number of color planes (1 for packed formats)
+ * @h_align: horizontal alignment order (align to 2^h_align)
+ * @v_align: vertical alignment order (align to 2^v_align)
+ * @flags: flags describing format applicability
+ */
+struct mxc_jpeg_fmt {
+ char *name;
+ u32 fourcc;
+ int depth;
+ int colplanes;
+ int memplanes;
+ int h_align;
+ int v_align;
+ int subsampling;
+ u32 flags;
+};
+struct mxc_jpeg_desc {
+ u32 next_descpt_ptr;
+ u32 buf_base0;
+ u32 buf_base1;
+ u32 line_pitch;
+ u32 stm_bufbase;
+ u32 stm_bufsize;
+ u32 imgsize;
+ u32 stm_ctrl;
+} __packed;
+
+struct mxc_jpeg_q_data {
+ struct mxc_jpeg_fmt *fmt;
+ u32 sizeimage[1];
+ u32 bytesperline[2];
+ int w;
+ int h;
+ u32 stride;
+};
+struct mxc_jpeg_ctx {
+ struct mxc_jpeg_dev *mxc_jpeg;
+ struct mxc_jpeg_q_data out_q;
+ struct mxc_jpeg_q_data cap_q;
+ struct v4l2_rect crop_rect;
+ unsigned long state;
+ struct v4l2_fh fh;
+ unsigned int mode;
+ unsigned int enc_state;
+ unsigned int aborting;
+ unsigned int stopping;
+};
+
+struct mxc_jpeg_slot_data {
+ int used;
+ struct mxc_jpeg_desc *desc; // enc/dec descriptor
+ struct mxc_jpeg_desc *cfg_desc; // configuration descriptor
+ void *cfg_stream_vaddr; // configuration bitstream virtual address
+ int flags;
+ dma_addr_t desc_handle;
+ dma_addr_t cfg_desc_handle; // configuration descriptor dma address
+ dma_addr_t cfg_stream_handle; // configuration bitstream dma address
+};
+
+struct mxc_jpeg_dev {
+ spinlock_t hw_lock;
+ unsigned int mode;
+ struct mutex lock;
+ bool enc;
+ bool dec;
+ struct clk *clk_ipg;
+ struct clk *clk_per;
+ struct platform_device *pdev;
+ struct device *dev;
+ void __iomem *base_reg;
+ void __iomem *enc_reg;
+ struct v4l2_device v4l2_dev;
+ struct v4l2_m2m_dev *m2m_dev;
+ struct video_device *dec_vdev;
+ unsigned int irq;
+ int id;
+
+ struct mxc_jpeg_slot_data slot_data[MXC_MAX_SLOTS];
+};
+
+#define MXC_JPEG_MAX_COMPONENTS 4
+/* JPEG Start Of Frame marker fields*/
+struct mxc_jpeg_sof_comp {
+ u8 id; /*component id*/
+ u8 v :4; /* vertical sampling*/
+ u8 h :4; /* horizontal sampling*/
+ u8 quantization_table_no;
+} __packed;
+
+struct mxc_jpeg_sof {
+ u16 length;
+ u8 precision;
+ u16 height, width;
+ u8 components_no;
+ struct mxc_jpeg_sof_comp comp[MXC_JPEG_MAX_COMPONENTS];
+} __packed;
+
+#endif
diff --git a/drivers/media/platform/imx8/mxc-media-dev.c b/drivers/media/platform/imx8/mxc-media-dev.c
new file mode 100644
index 000000000000..b3300ad8eb0f
--- /dev/null
+++ b/drivers/media/platform/imx8/mxc-media-dev.c
@@ -0,0 +1,884 @@
+/*
+ * Copyright 2017-2018 NXP
+ */
+/*
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/bug.h>
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/device.h>
+#include <linux/errno.h>
+#include <linux/i2c.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/of_device.h>
+#include <linux/of_graph.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <media/v4l2-fwnode.h>
+#include <media/v4l2-async.h>
+#include <media/v4l2-ctrls.h>
+#include <media/media-device.h>
+
+#include "mxc-media-dev.h"
+#include "mxc-isi-core.h"
+#include "mxc-mipi-csi2.h"
+#include "mxc-parallel-csi.h"
+
+/*create default links between registered entities */
+static int mxc_md_create_links(struct mxc_md *mxc_md)
+{
+ struct media_entity *source, *sink;
+ struct mxc_isi_dev *mxc_isi;
+ struct mxc_sensor_info *sensor;
+ struct mxc_mipi_csi2_dev *mipi_csi2;
+ struct mxc_parallel_csi_dev *pcsidev;
+ int num_sensors = mxc_md->subdev_notifier.num_subdevs;
+ int i, j, ret = 0;
+ u16 source_pad, sink_pad;
+ u32 flags;
+ u32 mipi_vc = 0;
+
+ /* Create links between each ISI's subdev and video node */
+ flags = MEDIA_LNK_FL_ENABLED;
+ for (i = 0; i < MXC_ISI_MAX_DEVS; i++) {
+ mxc_isi = mxc_md->mxc_isi[i];
+ if (!mxc_isi)
+ continue;
+
+ /* Connect ISI source to video device */
+ source = &mxc_isi->isi_cap.sd.entity;
+ sink = &mxc_isi->isi_cap.vdev.entity;
+ sink_pad = 0;
+
+ switch (mxc_isi->interface[OUT_PORT]) {
+ case ISI_OUTPUT_INTERFACE_DC0:
+ source_pad = MXC_ISI_SD_PAD_SOURCE_DC0;
+ break;
+ case ISI_OUTPUT_INTERFACE_DC1:
+ source_pad = MXC_ISI_SD_PAD_SOURCE_DC1;
+ break;
+ case ISI_OUTPUT_INTERFACE_MEM:
+ source_pad = MXC_ISI_SD_PAD_SOURCE_MEM;
+ break;
+ default:
+ v4l2_err(&mxc_md->v4l2_dev, "Wrong output interface: %x\n",
+ mxc_isi->interface[OUT_PORT]);
+ return -EINVAL;
+ }
+
+ ret = media_create_pad_link(source, source_pad,
+ sink, sink_pad, flags);
+ if (ret) {
+ v4l2_err(&mxc_md->v4l2_dev, "Failed created link [%s] %c> [%s]\n",
+ source->name, flags ? '=' : '-', sink->name);
+ break;
+ }
+
+ /* Notify capture subdev entity ,ISI cap link setup */
+ ret = media_entity_call(source, link_setup, &source->pads[source_pad],
+ &sink->pads[sink_pad], flags);
+ if (ret) {
+ v4l2_err(&mxc_md->v4l2_dev, "failed call link_setup [%s] %c> [%s]\n",
+ source->name, flags ? '=' : '-', sink->name);
+ break;
+ }
+
+ v4l2_info(&mxc_md->v4l2_dev, "created link [%s] %c> [%s]\n",
+ source->name, flags ? '=' : '-', sink->name);
+
+ /* Connect MIPI/HDMI/Mem source to ISI sink */
+ sink = &mxc_isi->isi_cap.sd.entity;
+
+ switch (mxc_isi->interface[IN_PORT]) {
+
+ case ISI_INPUT_INTERFACE_MIPI0_CSI2:
+ if (mxc_md->mipi_csi2[0] == NULL)
+ continue;
+ source = &mxc_md->mipi_csi2[0]->sd.entity;
+
+ switch (mxc_isi->interface[SUB_IN_PORT]) {
+ case ISI_INPUT_SUB_INTERFACE_VC1:
+ source_pad = MXC_MIPI_CSI2_VC1_PAD_SOURCE;
+ sink_pad = MXC_ISI_SD_PAD_SINK_MIPI0_VC1;
+ break;
+ case ISI_INPUT_SUB_INTERFACE_VC2:
+ source_pad = MXC_MIPI_CSI2_VC2_PAD_SOURCE;
+ sink_pad = MXC_ISI_SD_PAD_SINK_MIPI0_VC2;
+ break;
+ case ISI_INPUT_SUB_INTERFACE_VC3:
+ source_pad = MXC_MIPI_CSI2_VC3_PAD_SOURCE;
+ sink_pad = MXC_ISI_SD_PAD_SINK_MIPI0_VC3;
+ break;
+ default:
+ source_pad = MXC_MIPI_CSI2_VC0_PAD_SOURCE;
+ sink_pad = MXC_ISI_SD_PAD_SINK_MIPI0_VC0;
+ break;
+ }
+ break;
+
+ case ISI_INPUT_INTERFACE_MIPI1_CSI2:
+ if (mxc_md->mipi_csi2[1] == NULL)
+ continue;
+ source = &mxc_md->mipi_csi2[1]->sd.entity;
+
+ switch (mxc_isi->interface[SUB_IN_PORT]) {
+ case ISI_INPUT_SUB_INTERFACE_VC1:
+ source_pad = MXC_MIPI_CSI2_VC1_PAD_SOURCE;
+ sink_pad = MXC_ISI_SD_PAD_SINK_MIPI1_VC1;
+ break;
+ case ISI_INPUT_SUB_INTERFACE_VC2:
+ source_pad = MXC_MIPI_CSI2_VC2_PAD_SOURCE;
+ sink_pad = MXC_ISI_SD_PAD_SINK_MIPI1_VC2;
+ break;
+ case ISI_INPUT_SUB_INTERFACE_VC3:
+ source_pad = MXC_MIPI_CSI2_VC3_PAD_SOURCE;
+ sink_pad = MXC_ISI_SD_PAD_SINK_MIPI1_VC3;
+ break;
+ default:
+ source_pad = MXC_MIPI_CSI2_VC0_PAD_SOURCE;
+ sink_pad = MXC_ISI_SD_PAD_SINK_MIPI1_VC0;
+ break;
+ }
+ break;
+ case ISI_INPUT_INTERFACE_PARALLEL_CSI:
+ if (mxc_md->pcsidev == NULL)
+ continue;
+ source = &mxc_md->pcsidev->sd.entity;
+ source_pad = MXC_PARALLEL_CSI_PAD_SOURCE;
+ sink_pad = MXC_ISI_SD_PAD_SINK_PARALLEL_CSI;
+ break;
+
+ case ISI_INPUT_INTERFACE_HDMI:
+ if (mxc_md->hdmi_rx == NULL)
+ continue;
+ source = &mxc_md->hdmi_rx->sd.entity;
+ source_pad = MXC_HDMI_RX_PAD_SOURCE;
+ sink_pad = MXC_ISI_SD_PAD_SINK_HDMI;
+ break;
+
+ case ISI_INPUT_INTERFACE_DC0:
+ case ISI_INPUT_INTERFACE_DC1:
+ case ISI_INPUT_INTERFACE_MEM:
+ default:
+ v4l2_err(&mxc_md->v4l2_dev, "Not support input interface: %x\n",
+ mxc_isi->interface[IN_PORT]);
+ return -EINVAL;
+ }
+ /* Create link MIPI/HDMI to ISI */
+ ret = media_create_pad_link(source, source_pad, sink, sink_pad, flags);
+ if (ret) {
+ v4l2_err(&mxc_md->v4l2_dev, "created link [%s] %c> [%s] fail\n",
+ source->name, flags ? '=' : '-', sink->name);
+ break;
+ }
+
+ /* Notify ISI subdev entity */
+ ret = media_entity_call(sink, link_setup, &sink->pads[sink_pad],
+ &source->pads[source_pad], 0);
+ if (ret)
+ break;
+
+ /* Notify MIPI/HDMI entity */
+ ret = media_entity_call(source, link_setup, &source->pads[source_pad],
+ &sink->pads[sink_pad], 0);
+ if (ret)
+ break;
+
+ v4l2_info(&mxc_md->v4l2_dev, "created link [%s] %c> [%s]\n",
+ source->name, flags ? '=' : '-', sink->name);
+ }
+
+ /* Connect MIPI Sensor to MIPI CSI2 */
+ for (i = 0; i < num_sensors; i++) {
+ sensor = &mxc_md->sensor[i];
+ if (sensor == NULL || sensor->sd == NULL)
+ continue;
+
+ if (mxc_md->parallel_csi && !sensor->mipi_mode) {
+ pcsidev = mxc_md->pcsidev;
+ if (pcsidev == NULL)
+ continue;
+ source = &sensor->sd->entity;
+ sink = &pcsidev->sd.entity;
+
+ source_pad = 0;
+ sink_pad = MXC_PARALLEL_CSI_PAD_SINK;
+
+ ret = media_create_pad_link(source, source_pad, sink, sink_pad,
+ MEDIA_LNK_FL_IMMUTABLE | MEDIA_LNK_FL_ENABLED);
+ if (ret)
+ return ret;
+
+ /* Notify MIPI subdev entity */
+ ret = media_entity_call(sink, link_setup, &sink->pads[sink_pad],
+ &source->pads[source_pad], 0);
+ if (ret)
+ return ret;
+
+ /* Notify MIPI sensor subdev entity */
+ ret = media_entity_call(source, link_setup, &source->pads[source_pad],
+ &sink->pads[sink_pad], 0);
+ if (ret)
+ return ret;
+ v4l2_info(&mxc_md->v4l2_dev, "created link [%s] => [%s]\n",
+ sensor->sd->entity.name, pcsidev->sd.entity.name);
+ } else if (mxc_md->mipi_csi2) {
+ mipi_csi2 = mxc_md->mipi_csi2[sensor->id];
+ if (mipi_csi2 == NULL)
+ continue;
+ source = &sensor->sd->entity;
+ sink = &mipi_csi2->sd.entity;
+
+ source_pad = 0; /* sensor source pad: MIPI_CSI2_SENS_VC0_PAD_SOURCE */
+ sink_pad = source_pad; /* mipi sink pad: MXC_MIPI_CSI2_VC0_PAD_SINK; */
+
+ if (mipi_csi2->vchannel == true)
+ mipi_vc = 4;
+ else
+ mipi_vc = 1;
+
+ for (j = 0; j < mipi_vc; j++) {
+ ret = media_create_pad_link(source, source_pad + j, sink, sink_pad + j,
+ MEDIA_LNK_FL_IMMUTABLE | MEDIA_LNK_FL_ENABLED);
+ if (ret)
+ return ret;
+
+ /* Notify MIPI subdev entity */
+ ret = media_entity_call(sink, link_setup, &sink->pads[sink_pad + j],
+ &source->pads[source_pad + j], 0);
+ if (ret)
+ return ret;
+
+ /* Notify MIPI sensor subdev entity */
+ ret = media_entity_call(source, link_setup, &source->pads[source_pad + j],
+ &sink->pads[sink_pad + j], 0);
+ if (ret)
+ return ret;
+ }
+ v4l2_info(&mxc_md->v4l2_dev, "created link [%s] => [%s]\n",
+ sensor->sd->entity.name, mipi_csi2->sd.entity.name);
+ }
+ }
+ dev_info(&mxc_md->pdev->dev, "%s\n", __func__);
+ return 0;
+}
+
+static int subdev_notifier_bound(struct v4l2_async_notifier *notifier,
+ struct v4l2_subdev *sd,
+ struct v4l2_async_subdev *asd)
+{
+ struct mxc_md *mxc_md = notifier_to_mxc_md(notifier);
+ struct mxc_sensor_info *sensor = NULL;
+ int i;
+
+ dev_dbg(&mxc_md->pdev->dev, "%s\n", __func__);
+ /* Find platform data for this sensor subdev */
+ for (i = 0; i < ARRAY_SIZE(mxc_md->sensor); i++) {
+ if (mxc_md->sensor[i].asd.match.fwnode.fwnode ==
+ of_fwnode_handle(sd->dev->of_node))
+ sensor = &mxc_md->sensor[i];
+ }
+
+ if (sensor == NULL)
+ return -EINVAL;
+
+ sd->grp_id = GRP_ID_MXC_SENSOR;
+
+ sensor->sd = sd;
+
+ mxc_md->num_sensors++;
+
+ v4l2_info(&mxc_md->v4l2_dev, "Registered sensor subdevice: %s (%d)\n",
+ sd->name, mxc_md->num_sensors);
+
+ return 0;
+}
+
+static int subdev_notifier_complete(struct v4l2_async_notifier *notifier)
+{
+ struct mxc_md *mxc_md = notifier_to_mxc_md(notifier);
+ int ret;
+
+ dev_dbg(&mxc_md->pdev->dev, "%s\n", __func__);
+ mutex_lock(&mxc_md->media_dev.graph_mutex);
+
+ ret = mxc_md_create_links(mxc_md);
+ if (ret < 0)
+ goto unlock;
+
+ mxc_md->link_status = 1;
+
+ ret = v4l2_device_register_subdev_nodes(&mxc_md->v4l2_dev);
+unlock:
+ mutex_unlock(&mxc_md->media_dev.graph_mutex);
+ if (ret < 0) {
+ v4l2_err(&mxc_md->v4l2_dev, "%s error exit\n", __func__);
+ return ret;
+ }
+
+ return media_device_register(&mxc_md->media_dev);
+}
+
+
+/**
+ * mxc_sensor_notify - v4l2_device notification from a sensor subdev
+ */
+void mxc_sensor_notify(struct v4l2_subdev *sd, unsigned int notification,
+ void *arg)
+{
+ return;
+}
+
+/* Register mipi sensor / Parallel CSI / HDMI Rx sub-devices */
+static int register_sensor_entities(struct mxc_md *mxc_md)
+{
+ struct device_node *parent = mxc_md->pdev->dev.of_node;
+ struct device_node *node, *ep, *rem;
+ struct v4l2_fwnode_endpoint endpoint;
+ int index = 0;
+
+ mxc_md->num_sensors = 0;
+
+ /* Attach sensors linked to MIPI CSI2 / paralle csi / HDMI Rx */
+ for_each_available_child_of_node(parent, node) {
+ struct device_node *port;
+
+ if (!of_node_cmp(node->name, "hdmi_rx")) {
+ mxc_md->sensor[index].asd.match_type = V4L2_ASYNC_MATCH_FWNODE;
+ mxc_md->sensor[index].asd.match.fwnode.fwnode = of_fwnode_handle(node);
+ mxc_md->async_subdevs[index] = &mxc_md->sensor[index].asd;
+
+ mxc_md->num_sensors++;
+ index++;
+ continue;
+ }
+
+ if (of_node_cmp(node->name, "csi") &&
+ of_node_cmp(node->name, "pcsi"))
+ continue;
+
+ if (!of_device_is_available(node))
+ continue;
+
+ /* csi2 node have only port */
+ port = of_get_next_child(node, NULL);
+ if (!port)
+ continue;
+
+ /* port can have only endpoint */
+ ep = of_get_next_child(port, NULL);
+ if (!ep)
+ return -EINVAL;
+
+ v4l2_fwnode_endpoint_parse(of_fwnode_handle(ep), &endpoint);
+ if (WARN_ON(endpoint.base.port >= MXC_MAX_SENSORS)) {
+ v4l2_err(&mxc_md->v4l2_dev, "Failed to get sensor endpoint\n");
+ return -EINVAL;
+ }
+
+ mxc_md->sensor[index].id = endpoint.base.port;
+
+ if (!of_node_cmp(node->name, "csi"))
+ mxc_md->sensor[index].mipi_mode = true;
+
+ /* remote port---sensor node */
+ rem = of_graph_get_remote_port_parent(ep);
+ of_node_put(ep);
+ if (rem == NULL) {
+ v4l2_info(&mxc_md->v4l2_dev, "Remote device at %s not found\n",
+ ep->full_name);
+ continue;
+ }
+
+ mxc_md->sensor[index].asd.match_type = V4L2_ASYNC_MATCH_FWNODE;
+ mxc_md->sensor[index].asd.match.fwnode.fwnode = of_fwnode_handle(rem);
+ mxc_md->async_subdevs[index] = &mxc_md->sensor[index].asd;
+
+ mxc_md->num_sensors++;
+
+ index++;
+ }
+
+ return 0;
+}
+
+static int register_isi_entity(struct mxc_md *mxc_md, struct mxc_isi_dev *mxc_isi)
+{
+ struct v4l2_subdev *sd = &mxc_isi->isi_cap.sd;
+ int ret;
+
+ dev_dbg(&mxc_md->pdev->dev, "%s\n", __func__);
+ if (WARN_ON(mxc_isi->id >= MXC_ISI_MAX_DEVS))
+ return -EBUSY;
+
+ sd->grp_id = GRP_ID_MXC_ISI;
+
+ ret = v4l2_device_register_subdev(&mxc_md->v4l2_dev, sd);
+ if (!ret)
+ mxc_md->mxc_isi[mxc_isi->id] = mxc_isi;
+ else
+ v4l2_err(&mxc_md->v4l2_dev, "Failed to register ISI.%d (%d)\n",
+ mxc_isi->id, ret);
+ return ret;
+}
+
+static int register_mipi_csi2_entity(struct mxc_md *mxc_md,
+ struct mxc_mipi_csi2_dev *mipi_csi2)
+{
+ struct v4l2_subdev *sd = &mipi_csi2->sd;
+ int ret;
+
+ if (WARN_ON(mipi_csi2->id >= MXC_MIPI_CSI2_MAX_DEVS))
+ return -ENOENT;
+
+ sd->grp_id = GRP_ID_MXC_MIPI_CSI2;
+ ret = v4l2_device_register_subdev(&mxc_md->v4l2_dev, sd);
+ if (!ret)
+ mxc_md->mipi_csi2[mipi_csi2->id] = mipi_csi2;
+ else
+ v4l2_err(&mxc_md->v4l2_dev,
+ "Failed to register MIPI-CSIS.%d (%d)\n", mipi_csi2->id, ret);
+ return ret;
+}
+
+static int register_parallel_csi_entity(struct mxc_md *mxc_md,
+ struct mxc_parallel_csi_dev *pcsidev)
+{
+ struct v4l2_subdev *sd = &pcsidev->sd;
+ int ret;
+
+ sd->grp_id = GRP_ID_MXC_PARALLEL_CSI;
+ ret = v4l2_device_register_subdev(&mxc_md->v4l2_dev, sd);
+ if (!ret)
+ mxc_md->pcsidev = pcsidev;
+ else
+ v4l2_err(&mxc_md->v4l2_dev,
+ "Failed to register PARALLEL CSI ret=(%d)\n", ret);
+ return ret;
+}
+
+static int register_hdmi_rx_entity(struct mxc_md *mxc_md,
+ struct mxc_hdmi_rx_dev *hdmi_rx)
+{
+ struct v4l2_subdev *sd = &hdmi_rx->sd;;
+
+ dev_dbg(&mxc_md->pdev->dev, "%s\n", __func__);
+ sd->grp_id = GRP_ID_MXC_HDMI_RX;
+ mxc_md->hdmi_rx = hdmi_rx;
+
+ return 0;
+}
+
+static int mxc_md_register_platform_entity(struct mxc_md *mxc_md,
+ struct platform_device *pdev,
+ int plat_entity)
+{
+ struct device *dev = &pdev->dev;
+ int ret = -EPROBE_DEFER;
+ void *drvdata;
+
+ /* Lock to ensure dev->driver won't change. */
+ device_lock(dev);
+
+ if (!dev->driver || !try_module_get(dev->driver->owner))
+ goto dev_unlock;
+
+ drvdata = dev_get_drvdata(dev);
+ /* Some subdev didn't probe successfully id drvdata is NULL */
+ if (drvdata) {
+ switch (plat_entity) {
+ case IDX_ISI:
+ ret = register_isi_entity(mxc_md, drvdata);
+ break;
+ case IDX_MIPI_CSI2:
+ ret = register_mipi_csi2_entity(mxc_md, drvdata);
+ break;
+ case IDX_PARALLEL_CSI:
+ ret = register_parallel_csi_entity(mxc_md, drvdata);
+ break;
+ case IDX_HDMI_RX:
+ ret = register_hdmi_rx_entity(mxc_md, drvdata);
+ break;
+ default:
+ ret = -ENODEV;
+ }
+ }
+ module_put(dev->driver->owner);
+
+dev_unlock:
+ device_unlock(dev);
+ if (ret == -EPROBE_DEFER)
+ dev_info(&mxc_md->pdev->dev, "deferring %s device registration\n",
+ dev_name(dev));
+ else if (ret < 0)
+ dev_err(&mxc_md->pdev->dev, "%s device registration failed (%d)\n",
+ dev_name(dev), ret);
+
+ return ret;
+}
+
+/* Register ISI, MIPI CSI2 and HDMI Rx Media entities */
+static int mxc_md_register_platform_entities(struct mxc_md *mxc_md,
+ struct device_node *parent)
+{
+ struct device_node *node;
+ int ret = 0;
+
+ for_each_available_child_of_node(parent, node) {
+ struct platform_device *pdev;
+ int plat_entity = -1;
+
+ pdev = of_find_device_by_node(node);
+ if (!pdev)
+ continue;
+
+ /* If driver of any entity isn't ready try all again later. */
+ if (!strcmp(node->name, ISI_OF_NODE_NAME))
+ plat_entity = IDX_ISI;
+ else if (!strcmp(node->name, MIPI_CSI2_OF_NODE_NAME))
+ plat_entity = IDX_MIPI_CSI2;
+ else if (!strcmp(node->name, PARALLEL_CSI_OF_NODE_NAME))
+ plat_entity = IDX_PARALLEL_CSI;
+ else if (!strcmp(node->name, MXC_HDMI_RX_NODE_NAME))
+ plat_entity = IDX_HDMI_RX;
+
+ if (plat_entity >= 0)
+ ret = mxc_md_register_platform_entity(mxc_md, pdev,
+ plat_entity);
+ put_device(&pdev->dev);
+ if (ret < 0)
+ break;
+ }
+
+ return ret;
+}
+
+static void mxc_md_prepare_for_m2m(struct mxc_md *mxc_md,
+ struct device_node *parent)
+{
+ struct device *dev = &mxc_md->pdev->dev;
+ struct device_node *node;
+
+ for_each_available_child_of_node(parent, node) {
+ if (!strcmp(node->name, ISI_OF_NODE_NAME)) {
+ mxc_md->nr_isi++;
+
+ /* achive ISI channel0 driver data */
+ if (of_alias_get_id(node, "isi") == 0) {
+ struct platform_device *pdev =
+ of_find_device_by_node(node);
+
+ if (pdev && pdev->dev.driver) {
+ device_lock(&pdev->dev);
+ mxc_md->mxc_isi[0] = dev_get_drvdata(&pdev->dev);
+ mxc_md->mxc_isi[0]->skip_m2m = 0;
+ device_unlock(&pdev->dev);
+ }
+ put_device(&pdev->dev);
+ }
+ }
+ }
+
+ dev_dbg(dev, "%s: nr_isi = %d\n", __func__, mxc_md->nr_isi);
+}
+
+static void mxc_md_unregister_entities(struct mxc_md *mxc_md)
+{
+ int i;
+
+ for (i = 0; i < MXC_ISI_MAX_DEVS; i++) {
+ struct mxc_isi_dev *dev = mxc_md->mxc_isi[i];
+ if (dev == NULL)
+ continue;
+ v4l2_device_unregister_subdev(&dev->isi_cap.sd);
+ mxc_md->mxc_isi[i] = NULL;
+ }
+ for (i = 0; i < MXC_MIPI_CSI2_MAX_DEVS; i++) {
+ if (mxc_md->mipi_csi2[i] == NULL)
+ continue;
+ v4l2_device_unregister_subdev(&mxc_md->mipi_csi2[i]->sd);
+ mxc_md->mipi_csi2[i] = NULL;
+ }
+
+ if (mxc_md->pcsidev) {
+ v4l2_device_unregister_subdev(&mxc_md->pcsidev->sd);
+ mxc_md->pcsidev = NULL;
+ }
+
+ v4l2_info(&mxc_md->v4l2_dev, "Unregistered all entities\n");
+}
+
+static int mxc_md_do_clean(struct mxc_md *mxc_md, struct media_pad *pad)
+{
+ struct device *dev = &mxc_md->pdev->dev;
+ struct media_pad *remote_pad;
+ struct v4l2_subdev *subdev;
+ struct mxc_isi_dev *mxc_isi;
+
+ remote_pad = media_entity_remote_pad(pad);
+ if (remote_pad == NULL) {
+ dev_err(dev, "%s get remote pad fail\n", __func__);
+ return -ENODEV;
+ }
+
+ subdev = media_entity_to_v4l2_subdev(remote_pad->entity);
+ if (subdev == NULL) {
+ dev_err(dev, "%s media entity to v4l2 subdev fail\n", __func__);
+ return -ENODEV;
+ }
+
+ mxc_isi = v4l2_get_subdevdata(subdev);
+ if (mxc_isi == NULL) {
+ dev_err(dev, "%s Can't get subdev %s data\n", __func__, subdev->name);
+ return -ENODEV;
+ }
+
+ if (mxc_isi->id == 0)
+ mxc_isi->skip_m2m = 1;
+
+ v4l2_device_unregister_subdev(subdev);
+ media_entity_cleanup(&subdev->entity);
+
+ dev_info(dev, "clean ISI channel[%d]\n", mxc_isi->id);
+
+ return 0;
+}
+
+static int mxc_md_clean_channel(struct mxc_md *mxc_md, int index)
+{
+ struct mxc_sensor_info *sensor = &mxc_md->sensor[index];
+ struct mxc_mipi_csi2_dev *mipi_csi2;
+ struct mxc_parallel_csi_dev *pcsidev;
+ struct media_pad *local_pad;
+ struct media_entity *local_en;
+ u32 i, mipi_vc = 0;
+ int ret;
+
+ if (mxc_md->mipi_csi2[index]) {
+ mipi_csi2 = mxc_md->mipi_csi2[index];
+
+ if (mipi_csi2->vchannel == true)
+ mipi_vc = 4;
+ else
+ mipi_vc = 1;
+
+ local_en = &mipi_csi2->sd.entity;
+ if (local_en == NULL)
+ return -ENODEV;
+
+ for (i = 0; i < mipi_vc; i++) {
+ local_pad = &local_en->pads[MXC_MIPI_CSI2_VC0_PAD_SOURCE + i];
+ ret = mxc_md_do_clean(mxc_md, local_pad);
+ if (ret < 0)
+ return -ENODEV;
+ }
+ } else if (mxc_md->parallel_csi && !sensor->mipi_mode) {
+ pcsidev = mxc_md->pcsidev;
+ if (pcsidev == NULL)
+ return -ENODEV;
+
+ local_en = &pcsidev->sd.entity;
+ if (local_en == NULL)
+ return -ENODEV;
+
+ local_pad = &local_en->pads[MXC_PARALLEL_CSI_PAD_SOURCE];
+ ret = mxc_md_do_clean(mxc_md, local_pad);
+ if (ret < 0)
+ return -ENODEV;
+ }
+
+ return 0;
+}
+
+static int mxc_md_clean_unlink_channels(struct mxc_md *mxc_md)
+{
+ struct mxc_sensor_info *sensor;
+ int num_subdevs = mxc_md->subdev_notifier.num_subdevs;
+ int i, ret;
+
+ for (i = 0; i < num_subdevs; i++) {
+ sensor = &mxc_md->sensor[i];
+ if (sensor->sd != NULL)
+ continue;
+
+ ret = mxc_md_clean_channel(mxc_md, i);
+ if (ret < 0) {
+ pr_err("%s: clean channel fail(%d)\n", __func__, i);
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+static void mxc_md_unregister_all(struct mxc_md *mxc_md)
+{
+ struct mxc_isi_dev *mxc_isi;
+ int i;
+
+ for (i = 0; i < MXC_ISI_MAX_DEVS; i++) {
+ mxc_isi = mxc_md->mxc_isi[i];
+ if (!mxc_isi)
+ continue;
+
+ if (mxc_isi->id == 0)
+ mxc_isi->skip_m2m = 1;
+
+ v4l2_device_unregister_subdev(&mxc_isi->isi_cap.sd);
+ media_entity_cleanup(&mxc_isi->isi_cap.sd.entity);
+
+ dev_info(&mxc_isi->pdev->dev, "%s unregister ISI channel[%d]\n",
+ __func__, mxc_isi->id);
+ }
+}
+
+static int mxc_md_link_notify(struct media_link *link, unsigned int flags,
+ unsigned int notification)
+{
+ return 0;
+}
+
+static const struct media_device_ops mxc_md_ops = {
+ .link_notify = mxc_md_link_notify,
+};
+
+
+static int mxc_md_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct v4l2_device *v4l2_dev;
+ struct mxc_md *mxc_md;
+ int ret;
+
+ mxc_md = devm_kzalloc(dev, sizeof(*mxc_md), GFP_KERNEL);
+ if (!mxc_md)
+ return -ENOMEM;
+
+ mxc_md->pdev = pdev;
+ platform_set_drvdata(pdev, mxc_md);
+
+ mxc_md->parallel_csi = of_property_read_bool(dev->of_node, "parallel_csi");
+
+ /* register media device */
+ strlcpy(mxc_md->media_dev.model, "FSL Capture Media Deivce",
+ sizeof(mxc_md->media_dev.model));
+ mxc_md->media_dev.ops = &mxc_md_ops;
+ mxc_md->media_dev.dev = dev;
+
+ /* register v4l2 device */
+ v4l2_dev = &mxc_md->v4l2_dev;
+ v4l2_dev->mdev = &mxc_md->media_dev;
+ v4l2_dev->notify = mxc_sensor_notify;
+ strlcpy(v4l2_dev->name, "mx8-img-md", sizeof(v4l2_dev->name));
+
+ media_device_init(&mxc_md->media_dev);
+
+ ret = v4l2_device_register(dev, &mxc_md->v4l2_dev);
+ if (ret < 0) {
+ v4l2_err(v4l2_dev, "Failed to register v4l2_device: %d\n", ret);
+ goto err_md;
+ }
+
+ /* prepare for registration m2m */
+ mxc_md_prepare_for_m2m(mxc_md, dev->of_node);
+
+ ret = mxc_md_register_platform_entities(mxc_md, dev->of_node);
+ if (ret < 0)
+ goto err_v4l2_dev;
+
+ ret = register_sensor_entities(mxc_md);
+ if (ret < 0)
+ goto err_m_ent;
+
+ if (mxc_md->num_sensors > 0) {
+ mxc_md->subdev_notifier.subdevs = mxc_md->async_subdevs;
+ mxc_md->subdev_notifier.num_subdevs = mxc_md->num_sensors;
+ mxc_md->subdev_notifier.bound = subdev_notifier_bound;
+ mxc_md->subdev_notifier.complete = subdev_notifier_complete;
+ mxc_md->num_sensors = 0;
+ mxc_md->link_status = 0;
+
+ ret = v4l2_async_notifier_register(&mxc_md->v4l2_dev,
+ &mxc_md->subdev_notifier);
+ if (ret < 0) {
+ dev_warn(&mxc_md->pdev->dev, "Sensor register failed\n");
+ goto err_m_ent;
+ }
+
+ if (!mxc_md->link_status) {
+ if (mxc_md->num_sensors > 0) {
+ ret = subdev_notifier_complete(&mxc_md->subdev_notifier);
+ if (ret < 0)
+ goto err_m_ent;
+
+ mxc_md_clean_unlink_channels(mxc_md);
+ } else {
+ /* no sensors connected */
+ mxc_md_unregister_all(mxc_md);
+ }
+ }
+ }
+
+ return 0;
+
+err_m_ent:
+ mxc_md_unregister_entities(mxc_md);
+err_v4l2_dev:
+ v4l2_device_unregister(&mxc_md->v4l2_dev);
+err_md:
+ media_device_cleanup(&mxc_md->media_dev);
+ return ret;
+}
+
+static int mxc_md_remove(struct platform_device *pdev)
+{
+ struct mxc_md *mxc_md = platform_get_drvdata(pdev);
+
+ if (!mxc_md)
+ return 0;
+
+ v4l2_async_notifier_unregister(&mxc_md->subdev_notifier);
+
+ v4l2_device_unregister(&mxc_md->v4l2_dev);
+ mxc_md_unregister_entities(mxc_md);
+ media_device_unregister(&mxc_md->media_dev);
+ media_device_cleanup(&mxc_md->media_dev);
+
+ return 0;
+}
+
+static const struct of_device_id mxc_md_of_match[] = {
+ { .compatible = "fsl,mxc-md",},
+ { /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, mxc_md_of_match);
+
+
+static struct platform_driver mxc_md_driver = {
+ .driver = {
+ .name = MXC_MD_DRIVER_NAME,
+ .of_match_table = mxc_md_of_match,
+ },
+ .probe = mxc_md_probe,
+ .remove = mxc_md_remove,
+};
+
+module_platform_driver(mxc_md_driver);
+
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("MXC Media Device driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:" MXC_MD_DRIVER_NAME);
diff --git a/drivers/media/platform/imx8/mxc-media-dev.h b/drivers/media/platform/imx8/mxc-media-dev.h
new file mode 100644
index 000000000000..d5ee92317519
--- /dev/null
+++ b/drivers/media/platform/imx8/mxc-media-dev.h
@@ -0,0 +1,126 @@
+/*
+ * Copyright 2017 NXP
+ */
+/*
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#ifndef MXC_MEDIA_DEV_H_
+#define MXC_MEDIA_DEV_H_
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/bug.h>
+#include <linux/interrupt.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/list.h>
+#include <linux/mfd/syscon.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/slab.h>
+#include <linux/clk.h>
+#include <media/media-device.h>
+#include <media/media-entity.h>
+#include <media/v4l2-subdev.h>
+#include <media/v4l2-ioctl.h>
+#include <media/v4l2-mem2mem.h>
+#include <media/videobuf2-core.h>
+
+#include "mxc-mipi-csi2.h"
+#include "mxc-isi-core.h"
+#include "mxc-isi-hw.h"
+#include "hdmi/mxc-hdmi-rx.h"
+
+#define MXC_MD_DRIVER_NAME "mxc-md"
+#define MXC_MAX_SENSORS 3
+
+#define MJPEG_DEC_OF_NODE_NAME "jpegdec"
+#define MJPEG_ENC_OF_NODE_NAME "jpegenc"
+
+/*
+ * The subdevices' group IDs.
+ */
+#define GRP_ID_MXC_SENSOR (1 << 8)
+#define GRP_ID_MXC_ISI (1 << 9)
+#define GRP_ID_MXC_MIPI_CSI2 (1 << 11)
+#define GRP_ID_MXC_HDMI_RX (1 << 12)
+#define GRP_ID_MXC_MJPEG_DEC (1 << 13)
+#define GRP_ID_MXC_MJPEG_ENC (1 << 14)
+#define GRP_ID_MXC_PARALLEL_CSI (1 << 15)
+
+enum mxc_subdev_index {
+ IDX_SENSOR,
+ IDX_ISI,
+ IDX_MIPI_CSI2,
+ IDX_HDMI_RX,
+ IDX_MJPEG_ENC,
+ IDX_MJPEG_DEC,
+ IDX_PARALLEL_CSI,
+ IDX_MAX,
+};
+
+struct mxc_sensor_info {
+ int id;
+ struct v4l2_subdev *sd;
+ struct v4l2_async_subdev asd;
+ bool mipi_mode;
+ /* struct mxc_isi_dev *host; */
+};
+
+struct mxc_mjpeg_dec{
+ struct v4l2_device *v4l2_dev;
+ struct v4l2_subdev sd;
+};
+
+struct mxc_mjpeg_enc{
+ struct v4l2_device *v4l2_dev;
+ struct v4l2_subdev sd;
+};
+
+struct mxc_md {
+ struct mxc_isi_dev *mxc_isi[MXC_ISI_MAX_DEVS];
+ struct mxc_hdmi_rx_dev *hdmi_rx;
+ struct mxc_parallel_csi_dev *pcsidev;
+ struct mxc_mipi_csi2_dev *mipi_csi2[MXC_MIPI_CSI2_MAX_DEVS];
+ struct mxc_sensor_info sensor[MXC_MAX_SENSORS];
+ struct mxc_mjpeg_dec *mjpeg_dec;
+ struct mxc_mjpeg_enc *mjpeg_enc;
+
+ int link_status;
+ int num_sensors;
+ unsigned int nr_isi;
+ bool parallel_csi;
+
+ struct media_device media_dev;
+ struct v4l2_device v4l2_dev;
+ struct platform_device *pdev;
+
+ struct v4l2_async_notifier subdev_notifier;
+ struct v4l2_async_subdev *async_subdevs[MXC_MAX_SENSORS];
+};
+
+static inline struct mxc_md *notifier_to_mxc_md(struct v4l2_async_notifier *n)
+{
+ return container_of(n, struct mxc_md, subdev_notifier);
+};
+
+int mxc_isi_initialize_capture_subdev(struct mxc_isi_dev *mxc_isi);
+void mxc_isi_unregister_capture_subdev(struct mxc_isi_dev *mxc_isi);
+int mxc_isi_register_m2m_device(struct mxc_isi_dev *mxc_isi,
+ struct v4l2_device *v4l2_dev);
+void mxc_sensor_notify(struct v4l2_subdev *sd, unsigned int notification,
+ void *arg);
+void mxc_isi_unregister_m2m_device(struct mxc_isi_dev *mxc_isi);
+int mxc_isi_register_driver(void);
+void mxc_isi_unregister_driver(void);
+#endif
diff --git a/drivers/media/platform/imx8/mxc-mipi-csi2.c b/drivers/media/platform/imx8/mxc-mipi-csi2.c
new file mode 100644
index 000000000000..aaa0e638800a
--- /dev/null
+++ b/drivers/media/platform/imx8/mxc-mipi-csi2.c
@@ -0,0 +1,853 @@
+/*
+ * Copyright 2017-2018 NXP
+ */
+/*
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/errno.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/kernel.h>
+#include <linux/memory.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_graph.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/regulator/consumer.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/videodev2.h>
+#include <media/v4l2-fwnode.h>
+#include <media/v4l2-subdev.h>
+#include <media/v4l2-device.h>
+#include <soc/imx8/sc/sci.h>
+
+#include "mxc-mipi-csi2.h"
+static int debug;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "Debug level (0-2)");
+
+/* 0~ 80Mbps: 0xB
+ * 80~250Mbps: 0x8
+ * 250~1.5Gbps: 0x6*/
+static u8 rxhs_settle[3] = {0xD, 0xA, 0x7};
+
+static struct mxc_mipi_csi2_dev *sd_to_mxc_mipi_csi2_dev(struct v4l2_subdev *sdev)
+{
+ return container_of(sdev, struct mxc_mipi_csi2_dev, sd);
+}
+
+/****************************************
+ * rxhs-settle calculate
+ * UI = 1000 / mipi csi phy clock
+ * THS-SETTLE_mim = 85ns + 6 * UI
+ * THS-SETTLE_max = 145ns +10 * UI
+ * PRG_RXHS_SETTLE = THS-SETTLE / (Tperiod of RxClk_ESC) + 1
+ ****************************************/
+static int calc_hs_settle(struct mxc_mipi_csi2_dev *csi2dev, u32 dphy_clk)
+{
+ u32 esc_rate;
+ u32 hs_settle;
+ u32 rxhs_settle;
+
+ esc_rate = clk_get_rate(csi2dev->clk_esc) / 1000000;
+ hs_settle = 140 + 8 * 1000 / dphy_clk;
+ rxhs_settle = hs_settle / (1000 / esc_rate) - 1;
+ return rxhs_settle;
+}
+
+#ifdef debug
+static void mxc_mipi_csi2_reg_dump(struct mxc_mipi_csi2_dev *csi2dev)
+{
+ printk("MIPI CSI2 HC register dump, mipi csi%d\n", csi2dev->id);
+ printk("MIPI CSI2 HC num of lanes 0x100 = 0x%x\n", readl(csi2dev->base_regs + 0x100));
+ printk("MIPI CSI2 HC dis lanes 0x104 = 0x%x\n", readl(csi2dev->base_regs + 0x104));
+ printk("MIPI CSI2 HC BIT ERR 0x108 = 0x%x\n", readl(csi2dev->base_regs + 0x108));
+ printk("MIPI CSI2 HC IRQ STATUS 0x10C = 0x%x\n", readl(csi2dev->base_regs + 0x10C));
+ printk("MIPI CSI2 HC IRQ MASK 0x110 = 0x%x\n", readl(csi2dev->base_regs + 0x110));
+ printk("MIPI CSI2 HC ULPS STATUS 0x114 = 0x%x\n", readl(csi2dev->base_regs + 0x114));
+ printk("MIPI CSI2 HC DPHY ErrSotHS 0x118 = 0x%x\n", readl(csi2dev->base_regs + 0x118));
+ printk("MIPI CSI2 HC DPHY ErrSotSync 0x11c = 0x%x\n", readl(csi2dev->base_regs + 0x11c));
+ printk("MIPI CSI2 HC DPHY ErrEsc 0x120 = 0x%x\n", readl(csi2dev->base_regs + 0x120));
+ printk("MIPI CSI2 HC DPHY ErrSyncEsc 0x124 = 0x%x\n", readl(csi2dev->base_regs + 0x124));
+ printk("MIPI CSI2 HC DPHY ErrControl 0x128 = 0x%x\n", readl(csi2dev->base_regs + 0x128));
+ printk("MIPI CSI2 HC DISABLE_PAYLOAD 0x12C = 0x%x\n", readl(csi2dev->base_regs + 0x12C));
+ printk("MIPI CSI2 HC DISABLE_PAYLOAD 0x130 = 0x%x\n", readl(csi2dev->base_regs + 0x130));
+ printk("MIPI CSI2 HC IGNORE_VC 0x180 = 0x%x\n", readl(csi2dev->base_regs + 0x180));
+ printk("MIPI CSI2 HC VID_VC 0x184 = 0x%x\n", readl(csi2dev->base_regs + 0x184));
+ printk("MIPI CSI2 HC FIFO_SEND_LEVEL 0x188 = 0x%x\n", readl(csi2dev->base_regs + 0x188));
+ printk("MIPI CSI2 HC VID_VSYNC 0x18C = 0x%x\n", readl(csi2dev->base_regs + 0x18C));
+ printk("MIPI CSI2 HC VID_SYNC_FP 0x190 = 0x%x\n", readl(csi2dev->base_regs + 0x190));
+ printk("MIPI CSI2 HC VID_HSYNC 0x194 = 0x%x\n", readl(csi2dev->base_regs + 0x194));
+ printk("MIPI CSI2 HC VID_HSYNC_BP 0x198 = 0x%x\n", readl(csi2dev->base_regs + 0x198));
+ printk("MIPI CSI2 CSR register dump\n");
+ printk("MIPI CSI2 CSR PLM_CTRL 0x000 = 0x%x\n", readl(csi2dev->csr_regs + 0x000));
+ printk("MIPI CSI2 CSR PHY_CTRL 0x004 = 0x%x\n", readl(csi2dev->csr_regs + 0x004));
+ printk("MIPI CSI2 CSR PHY_Status 0x008 = 0x%x\n", readl(csi2dev->csr_regs + 0x008));
+ printk("MIPI CSI2 CSR PHY_Test_Status 0x010 = 0x%x\n", readl(csi2dev->csr_regs + 0x010));
+ printk("MIPI CSI2 CSR PHY_Test_Status 0x014 = 0x%x\n", readl(csi2dev->csr_regs + 0x014));
+ printk("MIPI CSI2 CSR PHY_Test_Status 0x018 = 0x%x\n", readl(csi2dev->csr_regs + 0x018));
+ printk("MIPI CSI2 CSR PHY_Test_Status 0x01C = 0x%x\n", readl(csi2dev->csr_regs + 0x01C));
+ printk("MIPI CSI2 CSR PHY_Test_Status 0x020 = 0x%x\n", readl(csi2dev->csr_regs + 0x020));
+ printk("MIPI CSI2 CSR VC Interlaced 0x030 = 0x%x\n", readl(csi2dev->csr_regs + 0x030));
+ printk("MIPI CSI2 CSR Data Type Dis 0x038 = 0x%x\n", readl(csi2dev->csr_regs + 0x038));
+ printk("MIPI CSI2 CSR 420 1st type 0x040 = 0x%x\n", readl(csi2dev->csr_regs + 0x040));
+ printk("MIPI CSI2 CSR Ctr_Ck_Rst_Ctr 0x044 = 0x%x\n", readl(csi2dev->csr_regs + 0x044));
+ printk("MIPI CSI2 CSR Stream Fencing 0x048 = 0x%x\n", readl(csi2dev->csr_regs + 0x048));
+ printk("MIPI CSI2 CSR Stream Fencing 0x04C = 0x%x\n", readl(csi2dev->csr_regs + 0x04C));
+}
+#else
+static void mxc_mipi_csi2_reg_dump(struct mxc_mipi_csi2_dev *csi2dev)
+{
+}
+#endif
+
+static void mipi_sc_fw_init(struct mxc_mipi_csi2_dev *csi2dev, char enable)
+{
+ sc_ipc_t ipcHndl;
+ sc_err_t sciErr;
+ sc_rsrc_t rsrc_id;
+ uint32_t mu_id;
+
+ sciErr = sc_ipc_getMuID(&mu_id);
+ if (sciErr != SC_ERR_NONE) {
+ pr_err("Cannot obtain MU ID\n");
+ return;
+ }
+
+ sciErr = sc_ipc_open(&ipcHndl, mu_id);
+ if (sciErr != SC_ERR_NONE) {
+ pr_err("sc_ipc_open failed! (sciError = %d)\n", sciErr);
+ return;
+ }
+
+ if (csi2dev->id == 1)
+ rsrc_id = SC_R_CSI_1;
+ else
+ rsrc_id = SC_R_CSI_0;
+
+ sciErr = sc_misc_set_control(ipcHndl, rsrc_id, SC_C_MIPI_RESET, enable);
+ if (sciErr != SC_ERR_NONE)
+ pr_err("sc_misc_MIPI reset failed! (sciError = %d)\n", sciErr);
+
+ msleep(10);
+
+ sc_ipc_close(mu_id);
+}
+
+static void mxc_mipi_csi2_reset(struct mxc_mipi_csi2_dev *csi2dev)
+{
+ u32 val;
+
+ /* Reset MIPI CSI */
+ val = CSI2SS_CTRL_CLK_RESET_EN | CSI2SS_CTRL_CLK_RESET_CLK_OFF;
+ writel(val, csi2dev->csr_regs + CSI2SS_CTRL_CLK_RESET);
+}
+
+static void mxc_mipi_csi2_enable(struct mxc_mipi_csi2_dev *csi2dev)
+{
+ u32 val = 0;
+
+ val = readl(csi2dev->csr_regs + CSI2SS_PLM_CTRL);
+ while (val & CSI2SS_PLM_CTRL_PL_CLK_RUN) {
+ msleep(10);
+ val = readl(csi2dev->csr_regs + CSI2SS_PLM_CTRL);
+ printk("Waiting pl clk running, val=0x%x\n", val);
+ }
+
+ /* Enable Pixel link Master*/
+ val = readl(csi2dev->csr_regs + CSI2SS_PLM_CTRL);
+ val |= CSI2SS_PLM_CTRL_ENABLE_PL;
+ writel(val, csi2dev->csr_regs + CSI2SS_PLM_CTRL);
+
+ val |= CSI2SS_PLM_CTRL_VALID_OVERRIDE;
+ writel(val, csi2dev->csr_regs + CSI2SS_PLM_CTRL);
+
+ /* PHY Enable */
+ val = readl(csi2dev->csr_regs + CSI2SS_PHY_CTRL);
+ val &= ~(CSI2SS_PHY_CTRL_PD_MASK | CSI2SS_PLM_CTRL_POLARITY_MASK);
+ writel(val, csi2dev->csr_regs + CSI2SS_PHY_CTRL);
+
+ /* Deassert reset */
+ writel(1, csi2dev->csr_regs + CSI2SS_CTRL_CLK_RESET);
+}
+
+static void mxc_mipi_csi2_disable(struct mxc_mipi_csi2_dev *csi2dev)
+{
+ /* Disable Data lanes */
+ writel(0xf, csi2dev->base_regs + CSI2RX_CFG_DISABLE_DATA_LANES);
+
+ /* Disable Pixel Link */
+ writel(0, csi2dev->csr_regs + CSI2SS_PLM_CTRL);
+
+ /* Disable PHY */
+ writel(0, csi2dev->csr_regs + CSI2SS_PHY_CTRL);
+
+ /* Reset */
+ writel(2, csi2dev->csr_regs + CSI2SS_CTRL_CLK_RESET);
+}
+
+static void mxc_mipi_csi2_csr_config(struct mxc_mipi_csi2_dev *csi2dev)
+{
+ u32 val;
+
+ /* format */
+ val = 0;
+ writel(val, csi2dev->csr_regs + CSI2SS_DATA_TYPE);
+
+ /* polarity */
+ val = readl(csi2dev->csr_regs + CSI2SS_PLM_CTRL);
+ val &= ~(CSI2SS_PLM_CTRL_VSYNC_OVERRIDE |
+ CSI2SS_PLM_CTRL_HSYNC_OVERRIDE |
+ CSI2SS_PLM_CTRL_VALID_OVERRIDE |
+ CSI2SS_PLM_CTRL_POLARITY_MASK);
+
+ writel(val, csi2dev->csr_regs + CSI2SS_PLM_CTRL);
+
+ val = CSI2SS_PHY_CTRL_RX_ENABLE |
+ CSI2SS_PHY_CTRL_DDRCLK_EN << CSI2SS_PHY_CTRL_DDRCLK_EN_OFFSET |
+ CSI2SS_PHY_CTRL_CONT_CLK_MODE << CSI2SS_PHY_CTRL_CONT_CLK_MODE_OFFSET |
+ csi2dev->hs_settle << CSI2SS_PHY_CTRL_RX_HS_SETTLE_OFFSET |
+ CSI2SS_PHY_CTRL_PD << CSI2SS_PHY_CTRL_PD_OFFSET |
+ CSI2SS_PHY_CTRL_RTERM_SEL << CSI2SS_PHY_CTRL_RTERM_SEL_OFFSET |
+ CSI2SS_PHY_CTRL_AUTO_PD_EN << CSI2SS_PHY_CTRL_AUTO_PD_EN_OFFSET;
+
+ writel(val, csi2dev->csr_regs + CSI2SS_PHY_CTRL);
+}
+
+static void mxc_mipi_csi2_hc_config(struct mxc_mipi_csi2_dev *csi2dev)
+{
+ u32 val0, val1;
+ u32 i;
+
+ val0 = 0;
+
+ /* Lanes */
+ writel(csi2dev->num_lanes - 1, csi2dev->base_regs + CSI2RX_CFG_NUM_LANES);
+
+ for (i = 0; i < csi2dev->num_lanes; i++)
+ val0 |= (1 << (csi2dev->data_lanes[i] - 1));
+
+ val1 = 0xF & ~val0;
+ writel(val1, csi2dev->base_regs + CSI2RX_CFG_DISABLE_DATA_LANES);
+
+ /* Mask interrupt */
+ writel(0x1FF, csi2dev->base_regs + CSI2RX_IRQ_MASK);
+
+ /* vid_vc */
+ writel(3, csi2dev->base_regs + 0x184);
+}
+
+static struct media_pad *mxc_csi2_get_remote_sensor_pad(struct mxc_mipi_csi2_dev *csi2dev)
+{
+ struct v4l2_subdev *subdev = &csi2dev->sd;
+ struct media_pad *sink_pad, *source_pad;
+ int i;
+
+ while (1) {
+ source_pad = NULL;
+ for (i = 0; i < subdev->entity.num_pads; i++) {
+ sink_pad = &subdev->entity.pads[i];
+
+ if (sink_pad->flags & MEDIA_PAD_FL_SINK) {
+ source_pad = media_entity_remote_pad(sink_pad);
+ if (source_pad)
+ break;
+ }
+ }
+ /* return first pad point in the loop */
+ return source_pad;
+ }
+
+ if (i == subdev->entity.num_pads)
+ v4l2_err(&csi2dev->v4l2_dev, "%s, No remote pad found!\n", __func__);
+
+ return NULL;
+}
+
+static int mxc_csi2_get_sensor_fmt(struct mxc_mipi_csi2_dev *csi2dev)
+{
+ struct v4l2_mbus_framefmt *mf = &csi2dev->format;
+ struct v4l2_subdev *sen_sd;
+ struct media_pad *source_pad;
+ struct v4l2_subdev_format src_fmt;
+ int ret;
+
+ /* Get remote source pad */
+ source_pad = mxc_csi2_get_remote_sensor_pad(csi2dev);
+ if (source_pad == NULL) {
+ v4l2_err(&csi2dev->v4l2_dev, "%s, No remote pad found!\n", __func__);
+ return -EINVAL;
+ }
+
+ /* Get remote source pad subdev */
+ sen_sd = media_entity_to_v4l2_subdev(source_pad->entity);
+ if (sen_sd == NULL) {
+ v4l2_err(&csi2dev->v4l2_dev, "%s, No remote subdev found!\n", __func__);
+ return -EINVAL;
+ }
+
+ src_fmt.pad = source_pad->index;
+ ret = v4l2_subdev_call(sen_sd, pad, get_fmt, NULL, &src_fmt);
+ if (ret < 0 && ret != -ENOIOCTLCMD)
+ return -EINVAL;
+
+ /* Update input frame size and formate */
+ memcpy(mf, &src_fmt.format, sizeof(struct v4l2_mbus_framefmt));
+
+ dev_dbg(&csi2dev->pdev->dev, "width=%d, height=%d, fmt.code=0x%x\n", mf->width, mf->height, mf->code);
+
+ /* Get rxhs settle */
+ if (src_fmt.format.reserved[0] != 0)
+ csi2dev->hs_settle = calc_hs_settle(csi2dev, src_fmt.format.reserved[0]);
+ else if (src_fmt.format.reserved[1] != 0)
+ csi2dev->hs_settle = src_fmt.format.reserved[1];
+ else {
+ if (src_fmt.format.height * src_fmt.format.width > 1024 * 768)
+ csi2dev->hs_settle = rxhs_settle[2];
+ else if (src_fmt.format.height * src_fmt.format.width < 480 * 320)
+ csi2dev->hs_settle = rxhs_settle[0];
+ else
+ csi2dev->hs_settle = rxhs_settle[1];
+ }
+
+ return 0;
+}
+
+static int mipi_csi2_clk_init(struct mxc_mipi_csi2_dev *csi2dev)
+{
+ struct device *dev = &csi2dev->pdev->dev;
+
+ csi2dev->clk_apb = devm_clk_get(dev, "clk_apb");
+ if (IS_ERR(csi2dev->clk_apb)) {
+ dev_err(dev, "failed to get csi apb clk\n");
+ return PTR_ERR(csi2dev->clk_apb);
+ }
+
+ csi2dev->clk_core = devm_clk_get(dev, "clk_core");
+ if (IS_ERR(csi2dev->clk_core)) {
+ dev_err(dev, "failed to get csi core clk\n");
+ return PTR_ERR(csi2dev->clk_core);
+ }
+
+ csi2dev->clk_esc = devm_clk_get(dev, "clk_esc");
+ if (IS_ERR(csi2dev->clk_esc)) {
+ dev_err(dev, "failed to get csi esc clk\n");
+ return PTR_ERR(csi2dev->clk_esc);
+ }
+
+ csi2dev->clk_pxl = devm_clk_get(dev, "clk_pxl");
+ if (IS_ERR(csi2dev->clk_pxl)) {
+ dev_err(dev, "failed to get csi pixel link clk\n");
+ return PTR_ERR(csi2dev->clk_pxl);
+ }
+
+ return 0;
+}
+
+static int mipi_csi2_clk_enable(struct mxc_mipi_csi2_dev *csi2dev)
+{
+ struct device *dev = &csi2dev->pdev->dev;
+ int ret;
+
+ ret = clk_prepare_enable(csi2dev->clk_apb);
+ if (ret < 0) {
+ dev_err(dev, "%s, pre clk_apb error\n", __func__);
+ return ret;
+ }
+ ret = clk_prepare_enable(csi2dev->clk_core);
+ if (ret < 0) {
+ dev_err(dev, "%s, pre clk_core error\n", __func__);
+ return ret;
+ }
+ ret = clk_prepare_enable(csi2dev->clk_esc);
+ if (ret < 0) {
+ dev_err(dev, "%s, prepare clk_esc error\n", __func__);
+ return ret;
+ }
+ ret = clk_prepare_enable(csi2dev->clk_pxl);
+ if (ret < 0) {
+ dev_err(dev, "%s, prepare clk_pxl error\n", __func__);
+ return ret;
+ }
+
+ return ret;
+}
+
+static void mipi_csi2_clk_disable(struct mxc_mipi_csi2_dev *csi2dev)
+{
+ clk_disable_unprepare(csi2dev->clk_apb);
+ clk_disable_unprepare(csi2dev->clk_core);
+ clk_disable_unprepare(csi2dev->clk_esc);
+ clk_disable_unprepare(csi2dev->clk_pxl);
+}
+
+static int mipi_csi2_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
+{
+ return 0;
+}
+
+/* mipi csi2 subdev media entity operations */
+static int mipi_csi2_link_setup(struct media_entity *entity,
+ const struct media_pad *local,
+ const struct media_pad *remote, u32 flags)
+{
+ /* TODO */
+ /* Add MIPI source and sink pad link configuration */
+ if (local->flags & MEDIA_PAD_FL_SOURCE) {
+ switch (local->index) {
+ case MXC_MIPI_CSI2_VC0_PAD_SOURCE:
+ case MXC_MIPI_CSI2_VC1_PAD_SOURCE:
+ case MXC_MIPI_CSI2_VC2_PAD_SOURCE:
+ case MXC_MIPI_CSI2_VC3_PAD_SOURCE:
+ break;
+ default:
+ return 0;
+ }
+ } else if (local->flags & MEDIA_PAD_FL_SINK) {
+ switch (local->index) {
+ case MXC_MIPI_CSI2_VC0_PAD_SINK:
+ case MXC_MIPI_CSI2_VC1_PAD_SINK:
+ case MXC_MIPI_CSI2_VC2_PAD_SINK:
+ case MXC_MIPI_CSI2_VC3_PAD_SINK:
+ break;
+ default:
+ return 0;
+ }
+ }
+ return 0;
+}
+
+static const struct media_entity_operations mipi_csi2_sd_media_ops = {
+ .link_setup = mipi_csi2_link_setup,
+};
+
+/*
+ * V4L2 subdev operations
+ */
+static int mipi_csi2_s_power(struct v4l2_subdev *sd, int on)
+{
+ struct mxc_mipi_csi2_dev *csi2dev = sd_to_mxc_mipi_csi2_dev(sd);
+ struct media_pad *source_pad;
+ struct v4l2_subdev *sen_sd;
+
+ /* Get remote source pad */
+ source_pad = mxc_csi2_get_remote_sensor_pad(csi2dev);
+ if (source_pad == NULL) {
+ v4l2_err(&csi2dev->v4l2_dev, "%s, No remote pad found!\n", __func__);
+ return -EINVAL;
+ }
+
+ /* Get remote source pad subdev */
+ sen_sd = media_entity_to_v4l2_subdev(source_pad->entity);
+ if (sen_sd == NULL) {
+ v4l2_err(&csi2dev->v4l2_dev, "%s, No remote subdev found!\n", __func__);
+ return -EINVAL;
+ }
+ return v4l2_subdev_call(sen_sd, core, s_power, on);
+}
+
+static int mipi_csi2_s_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *a)
+{
+ struct mxc_mipi_csi2_dev *csi2dev = sd_to_mxc_mipi_csi2_dev(sd);
+ struct media_pad *source_pad;
+ struct v4l2_subdev *sen_sd;
+
+ /* Get remote source pad */
+ source_pad = mxc_csi2_get_remote_sensor_pad(csi2dev);
+ if (source_pad == NULL) {
+ v4l2_err(&csi2dev->v4l2_dev, "%s, No remote pad found!\n", __func__);
+ return -EINVAL;
+ }
+
+ /* Get remote source pad subdev */
+ sen_sd = media_entity_to_v4l2_subdev(source_pad->entity);
+ if (sen_sd == NULL) {
+ v4l2_err(&csi2dev->v4l2_dev, "%s, No remote subdev found!\n", __func__);
+ return -EINVAL;
+ }
+ return v4l2_subdev_call(sen_sd, video, s_parm, a);
+}
+
+static int mipi_csi2_g_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *a)
+{
+ struct mxc_mipi_csi2_dev *csi2dev = sd_to_mxc_mipi_csi2_dev(sd);
+ struct media_pad *source_pad;
+ struct v4l2_subdev *sen_sd;
+
+ /* Get remote source pad */
+ source_pad = mxc_csi2_get_remote_sensor_pad(csi2dev);
+ if (source_pad == NULL) {
+ v4l2_err(&csi2dev->v4l2_dev, "%s, No remote pad found!\n", __func__);
+ return -EINVAL;
+ }
+
+ /* Get remote source pad subdev */
+ sen_sd = media_entity_to_v4l2_subdev(source_pad->entity);
+ if (sen_sd == NULL) {
+ v4l2_err(&csi2dev->v4l2_dev, "%s, No remote subdev found!\n", __func__);
+ return -EINVAL;
+ }
+
+ return v4l2_subdev_call(sen_sd, video, g_parm, a);
+}
+
+static int mipi_csi2_s_stream(struct v4l2_subdev *sd, int enable)
+{
+ struct mxc_mipi_csi2_dev *csi2dev = sd_to_mxc_mipi_csi2_dev(sd);
+ struct device *dev = &csi2dev->pdev->dev;
+ int ret = 0;
+
+ dev_dbg(&csi2dev->pdev->dev, "%s: %d, csi2dev: 0x%x\n",
+ __func__, enable, csi2dev->flags);
+
+ if (enable) {
+ pm_runtime_get_sync(dev);
+ if (!csi2dev->running) {
+ mxc_csi2_get_sensor_fmt(csi2dev);
+ mxc_mipi_csi2_hc_config(csi2dev);
+ mxc_mipi_csi2_reset(csi2dev);
+ mxc_mipi_csi2_csr_config(csi2dev);
+ mxc_mipi_csi2_enable(csi2dev);
+ mxc_mipi_csi2_reg_dump(csi2dev);
+ }
+ csi2dev->running++;
+ } else {
+
+ if (csi2dev->running)
+ mxc_mipi_csi2_disable(csi2dev);
+
+ csi2dev->running--;
+ pm_runtime_put(dev);
+ }
+
+ return ret;
+}
+
+static int mipi_csi2_enum_framesizes(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_frame_size_enum *fse)
+{
+ struct mxc_mipi_csi2_dev *csi2dev = sd_to_mxc_mipi_csi2_dev(sd);
+ struct media_pad *source_pad;
+ struct v4l2_subdev *sen_sd;
+
+ /* Get remote source pad */
+ source_pad = mxc_csi2_get_remote_sensor_pad(csi2dev);
+ if (source_pad == NULL) {
+ v4l2_err(&csi2dev->v4l2_dev, "%s, No remote pad found!\n", __func__);
+ return -EINVAL;
+ }
+
+ /* Get remote source pad subdev */
+ sen_sd = media_entity_to_v4l2_subdev(source_pad->entity);
+ if (sen_sd == NULL) {
+ v4l2_err(&csi2dev->v4l2_dev, "%s, No remote subdev found!\n", __func__);
+ return -EINVAL;
+ }
+
+ return v4l2_subdev_call(sen_sd, pad, enum_frame_size, NULL, fse);
+}
+
+static int mipi_csi2_enum_frame_interval(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_frame_interval_enum *fie)
+{
+ struct mxc_mipi_csi2_dev *csi2dev = sd_to_mxc_mipi_csi2_dev(sd);
+ struct media_pad *source_pad;
+ struct v4l2_subdev *sen_sd;
+
+ /* Get remote source pad */
+ source_pad = mxc_csi2_get_remote_sensor_pad(csi2dev);
+ if (source_pad == NULL) {
+ v4l2_err(&csi2dev->v4l2_dev, "%s, No remote pad found!\n", __func__);
+ return -EINVAL;
+ }
+
+ /* Get remote source pad subdev */
+ sen_sd = media_entity_to_v4l2_subdev(source_pad->entity);
+ if (sen_sd == NULL) {
+ v4l2_err(&csi2dev->v4l2_dev, "%s, No remote subdev found!\n", __func__);
+ return -EINVAL;
+ }
+
+ return v4l2_subdev_call(sen_sd, pad, enum_frame_interval, NULL, fie);
+}
+
+static int mipi_csi2_get_fmt(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_format *fmt)
+{
+ struct mxc_mipi_csi2_dev *csi2dev = sd_to_mxc_mipi_csi2_dev(sd);
+ struct v4l2_mbus_framefmt *mf = &fmt->format;
+
+ mxc_csi2_get_sensor_fmt(csi2dev);
+
+ memcpy(mf, &csi2dev->format, sizeof(struct v4l2_mbus_framefmt));
+ /* Source/Sink pads crop rectangle size */
+
+ return 0;
+}
+
+static int mipi_csi2_set_fmt(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_format *fmt)
+{
+ struct mxc_mipi_csi2_dev *csi2dev = sd_to_mxc_mipi_csi2_dev(sd);
+ struct v4l2_subdev *sen_sd;
+ struct media_pad *source_pad;
+ int ret;
+
+ /* Get remote source pad */
+ source_pad = mxc_csi2_get_remote_sensor_pad(csi2dev);
+ if (source_pad == NULL) {
+ v4l2_err(&csi2dev->v4l2_dev, "%s, No remote pad found!\n", __func__);
+ return -EINVAL;
+ }
+
+ /* Get remote source pad subdev */
+ sen_sd = media_entity_to_v4l2_subdev(source_pad->entity);
+ if (sen_sd == NULL) {
+ v4l2_err(&csi2dev->v4l2_dev, "%s, No remote subdev found!\n", __func__);
+ return -EINVAL;
+ }
+
+ fmt->pad = source_pad->index;
+ ret = v4l2_subdev_call(sen_sd, pad, set_fmt, NULL, fmt);
+ if (ret < 0 && ret != -ENOIOCTLCMD)
+ return -EINVAL;
+
+ return 0;
+}
+
+static const struct v4l2_subdev_internal_ops mipi_csi2_sd_internal_ops = {
+ .open = mipi_csi2_open,
+};
+
+static struct v4l2_subdev_pad_ops mipi_csi2_pad_ops = {
+ .enum_frame_size = mipi_csi2_enum_framesizes,
+ .enum_frame_interval = mipi_csi2_enum_frame_interval,
+ .get_fmt = mipi_csi2_get_fmt,
+ .set_fmt = mipi_csi2_set_fmt,
+};
+
+static struct v4l2_subdev_core_ops mipi_csi2_core_ops = {
+ .s_power = mipi_csi2_s_power,
+};
+
+static struct v4l2_subdev_video_ops mipi_csi2_video_ops = {
+ .s_parm = mipi_csi2_s_parm,
+ .g_parm = mipi_csi2_g_parm,
+ .s_stream = mipi_csi2_s_stream,
+};
+
+static struct v4l2_subdev_ops mipi_csi2_subdev_ops = {
+ .core = &mipi_csi2_core_ops,
+ .video = &mipi_csi2_video_ops,
+ .pad = &mipi_csi2_pad_ops,
+};
+static int mipi_csi2_parse_dt(struct mxc_mipi_csi2_dev *csi2dev)
+{
+ struct device *dev = &csi2dev->pdev->dev;
+ struct device_node *node = dev->of_node;
+ struct device_node *ep;
+ struct v4l2_fwnode_endpoint endpoint;
+ u32 i;
+
+ csi2dev->id = of_alias_get_id(node, "csi");
+
+ csi2dev->vchannel = of_property_read_bool(node, "virtual-channel");
+
+ ep = of_graph_get_next_endpoint(node, NULL);
+ if (!ep) {
+ dev_err(dev, "No port node at %s\n", node->full_name);
+ return -EINVAL;
+ }
+
+ /* Get port node */
+ v4l2_fwnode_endpoint_parse(of_fwnode_handle(ep), &endpoint);
+
+ csi2dev->num_lanes = endpoint.bus.mipi_csi2.num_data_lanes;
+ for (i = 0; i < 4; i++)
+ csi2dev->data_lanes[i] = endpoint.bus.mipi_csi2.data_lanes[i];
+
+ of_node_put(ep);
+
+ return 0;
+}
+
+static int mipi_csi2_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct resource *mem_res;
+ struct mxc_mipi_csi2_dev *csi2dev;
+ int ret = -ENOMEM;
+
+ dev_info(&pdev->dev, "%s\n", __func__);
+ csi2dev = devm_kzalloc(dev, sizeof(*csi2dev), GFP_KERNEL);
+ if (!csi2dev)
+ return -ENOMEM;
+
+ csi2dev->pdev = pdev;
+ mutex_init(&csi2dev->lock);
+
+ ret = mipi_csi2_parse_dt(csi2dev);
+ if (ret < 0)
+ return -EINVAL ;
+
+ mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ csi2dev->base_regs = devm_ioremap_resource(dev, mem_res);
+ if (IS_ERR(csi2dev->base_regs)) {
+ dev_err(dev, "Failed to get mipi csi2 HC register\n");
+ return PTR_ERR(csi2dev->base_regs);
+ }
+
+ mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+ csi2dev->csr_regs = devm_ioremap_resource(dev, mem_res);
+ if (IS_ERR(csi2dev->csr_regs)) {
+ dev_err(dev, "Failed to get mipi CSR register\n");
+ return PTR_ERR(csi2dev->csr_regs);
+ }
+
+ ret = mipi_csi2_clk_init(csi2dev);
+ if (ret < 0)
+ return -EINVAL ;
+
+ v4l2_subdev_init(&csi2dev->sd, &mipi_csi2_subdev_ops);
+
+ csi2dev->sd.owner = THIS_MODULE;
+ snprintf(csi2dev->sd.name, sizeof(csi2dev->sd.name), "%s.%d",
+ MXC_MIPI_CSI2_SUBDEV_NAME, csi2dev->id);
+
+ csi2dev->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+ csi2dev->sd.entity.function = MEDIA_ENT_F_IO_V4L;
+
+ csi2dev->sd.dev = dev;
+
+ csi2dev->pads[MXC_MIPI_CSI2_VC0_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
+ csi2dev->pads[MXC_MIPI_CSI2_VC1_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
+ csi2dev->pads[MXC_MIPI_CSI2_VC2_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
+ csi2dev->pads[MXC_MIPI_CSI2_VC3_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
+ csi2dev->pads[MXC_MIPI_CSI2_VC0_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
+ csi2dev->pads[MXC_MIPI_CSI2_VC1_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
+ csi2dev->pads[MXC_MIPI_CSI2_VC2_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
+ csi2dev->pads[MXC_MIPI_CSI2_VC3_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
+
+ ret = media_entity_pads_init(&csi2dev->sd.entity,
+ MXC_MIPI_CSI2_VCX_PADS_NUM, csi2dev->pads);
+ if (ret < 0)
+ goto e_clkdis;
+
+ csi2dev->sd.entity.ops = &mipi_csi2_sd_media_ops;
+
+ /* This allows to retrieve the platform device id by the host driver */
+ v4l2_set_subdevdata(&csi2dev->sd, pdev);
+
+ /* .. and a pointer to the subdev. */
+ platform_set_drvdata(pdev, csi2dev);
+
+ mipi_sc_fw_init(csi2dev, 1);
+
+ csi2dev->running = 0;
+
+ pm_runtime_enable(dev);
+
+ dev_dbg(&pdev->dev, "lanes: %d, name: %s\n",
+ csi2dev->num_lanes, csi2dev->sd.name);
+
+ return 0;
+
+e_clkdis:
+ media_entity_cleanup(&csi2dev->sd.entity);
+ return ret;
+}
+
+static int mipi_csi2_remove(struct platform_device *pdev)
+{
+ struct v4l2_subdev *sd = platform_get_drvdata(pdev);
+ struct mxc_mipi_csi2_dev *csi2dev = sd_to_mxc_mipi_csi2_dev(sd);
+
+ mipi_sc_fw_init(csi2dev, 0);
+ media_entity_cleanup(&csi2dev->sd.entity);
+ pm_runtime_disable(&pdev->dev);
+
+ return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int mipi_csi2_pm_suspend(struct device *dev)
+{
+ struct v4l2_subdev *sd = dev_get_drvdata(dev);
+ struct mxc_mipi_csi2_dev *csi2dev = sd_to_mxc_mipi_csi2_dev(sd);
+
+ if (csi2dev->running > 0) {
+ dev_warn(dev, "running, prevent entering suspend.\n");
+ return -EAGAIN;
+ }
+
+ return pm_runtime_force_suspend(dev);
+}
+
+static int mipi_csi2_pm_resume(struct device *dev)
+{
+ return pm_runtime_force_resume(dev);
+}
+#endif
+
+static int mipi_csi2_runtime_suspend(struct device *dev)
+{
+ struct mxc_mipi_csi2_dev *csi2dev = dev_get_drvdata(dev);
+
+ mipi_csi2_clk_disable(csi2dev);
+ return 0;
+}
+static int mipi_csi2_runtime_resume(struct device *dev)
+{
+ struct mxc_mipi_csi2_dev *csi2dev = dev_get_drvdata(dev);
+ int ret;
+
+ ret = mipi_csi2_clk_enable(csi2dev);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+static const struct dev_pm_ops mipi_csi_pm_ops = {
+ SET_SYSTEM_SLEEP_PM_OPS(mipi_csi2_pm_suspend, mipi_csi2_pm_resume)
+ SET_RUNTIME_PM_OPS(mipi_csi2_runtime_suspend, mipi_csi2_runtime_resume, NULL)
+};
+
+static const struct of_device_id mipi_csi2_of_match[] = {
+ { .compatible = "fsl,mxc-mipi-csi2",},
+ { /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, mipi_csi2_of_match);
+
+
+static struct platform_driver mipi_csi2_driver = {
+ .driver = {
+ .name = MXC_MIPI_CSI2_DRIVER_NAME,
+ .of_match_table = mipi_csi2_of_match,
+ .pm = &mipi_csi_pm_ops,
+ },
+ .probe = mipi_csi2_probe,
+ .remove = mipi_csi2_remove,
+};
+
+module_platform_driver(mipi_csi2_driver);
+
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("MXC MIPI CSI2 driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:" MXC_MIPI_CSI2_DRIVER_NAME);
diff --git a/drivers/media/platform/imx8/mxc-mipi-csi2.h b/drivers/media/platform/imx8/mxc-mipi-csi2.h
new file mode 100644
index 000000000000..ed01adc1958b
--- /dev/null
+++ b/drivers/media/platform/imx8/mxc-mipi-csi2.h
@@ -0,0 +1,279 @@
+/*
+ * Copyright 2017 NXP
+ */
+/*
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#ifndef MXC_MIPI_CSI2_H_
+#define MXC_MIPI_CSI2_H_
+
+#include <media/v4l2-device.h>
+
+#define MXC_MIPI_CSI2_DRIVER_NAME "mxc-mipi-csi2"
+#define MXC_MIPI_CSI2_SUBDEV_NAME MXC_MIPI_CSI2_DRIVER_NAME
+#define MXC_MIPI_CSI2_MAX_DEVS 2
+#define MXC_MIPI_CSI2_MAX_LANES 4
+
+#define MIPI_CSI2_OF_NODE_NAME "csi"
+
+#define MXC_MIPI_CSI2_VC0_PAD_SINK 0
+#define MXC_MIPI_CSI2_VC1_PAD_SINK 1
+#define MXC_MIPI_CSI2_VC2_PAD_SINK 2
+#define MXC_MIPI_CSI2_VC3_PAD_SINK 3
+
+#define MXC_MIPI_CSI2_VC0_PAD_SOURCE 4
+#define MXC_MIPI_CSI2_VC1_PAD_SOURCE 5
+#define MXC_MIPI_CSI2_VC2_PAD_SOURCE 6
+#define MXC_MIPI_CSI2_VC3_PAD_SOURCE 7
+#define MXC_MIPI_CSI2_VCX_PADS_NUM 8
+
+/* Subsystem CSR */
+#define CSI2SS_BASE_OFFSET 0x0
+
+#define CSI2SS_PLM_CTRL (CSI2SS_BASE_OFFSET + 0x0)
+#define CSI2SS_PLM_CTRL_PL_CLK_RUN 0x80000000
+#define CSI2SS_PLM_CTRL_VSYNC_OVERRIDE 0x200
+#define CSI2SS_PLM_CTRL_HSYNC_OVERRIDE 0x400
+#define CSI2SS_PLM_CTRL_VALID_OVERRIDE 0x800
+#define CSI2SS_PLM_CTRL_POLARITY_MASK 0x1000
+#define CSI2SS_PLM_CTRL_POLARITY_HIGH 0x1000
+#define CSI2SS_PLM_CTRL_POLARITY_LOW 0x0
+#define CSI2SS_PLM_CTRL_ENABLE_PL 1
+#define CSI2SS_PLM_CTRL_ENABLE_PL_OFFSET 0
+#define CSI2SS_PLM_CTRL_ENABLE_PL_MASK 1
+
+#define CSI2SS_PHY_CTRL (CSI2SS_BASE_OFFSET + 0x4)
+#define CSI2SS_PHY_CTRL_PD 1
+#define CSI2SS_PHY_CTRL_PD_OFFSET 22
+#define CSI2SS_PHY_CTRL_PD_MASK 0x400000
+#define CSI2SS_PHY_CTRL_RTERM_SEL 1
+#define CSI2SS_PHY_CTRL_RTERM_SEL_OFFSET 21
+#define CSI2SS_PHY_CTRL_RTERM_SEL_MASK 0x200000
+#define CSI2SS_PHY_CTRL_RX_HS_SETTLE_OFFSET 4
+#define CSI2SS_PHY_CTRL_RX_HS_SETTLE_MASK 0x3F0
+#define CSI2SS_PHY_CTRL_CONT_CLK_MODE 1
+#define CSI2SS_PHY_CTRL_CONT_CLK_MODE_OFFSET 3
+#define CSI2SS_PHY_CTRL_CONT_CLK_MODE_MASK 0x8
+#define CSI2SS_PHY_CTRL_DDRCLK_EN 1
+#define CSI2SS_PHY_CTRL_DDRCLK_EN_OFFSET 2
+#define CSI2SS_PHY_CTRL_DDRCLK_EN_MASK 0x4
+#define CSI2SS_PHY_CTRL_AUTO_PD_EN 1
+#define CSI2SS_PHY_CTRL_AUTO_PD_EN_OFFSET 1
+#define CSI2SS_PHY_CTRL_AUTO_PD_EN_MASK 0x2
+#define CSI2SS_PHY_CTRL_RX_ENABLE 1
+#define CSI2SS_PHY_CTRL_RX_ENABLE_OFFSET 0
+#define CSI2SS_PHY_CTRL_RX_ENABLE_MASK 0x1
+
+#define CSI2SS_PHY_STATUS (CSI2SS_BASE_OFFSET + 0x8)
+#define CSI2SS_PHY_TEST_STATUS (CSI2SS_BASE_OFFSET + 0x10)
+#define CSI2SS_PHY_TEST_STATUS_D0 (CSI2SS_BASE_OFFSET + 0x14)
+#define CSI2SS_PHY_TEST_STATUS_D1 (CSI2SS_BASE_OFFSET + 0x18)
+#define CSI2SS_PHY_TEST_STATUS_D2 (CSI2SS_BASE_OFFSET + 0x1C)
+#define CSI2SS_PHY_TEST_STATUS_D3 (CSI2SS_BASE_OFFSET + 0x20)
+
+#define CSI2SS_VC_INTERLACED (CSI2SS_BASE_OFFSET + 0x30)
+#define CSI2SS_VC_INTERLACED_VC0 1
+#define CSI2SS_VC_INTERLACED_VC1 2
+#define CSI2SS_VC_INTERLACED_VC2 4
+#define CSI2SS_VC_INTERLACED_VC3 8
+#define CSI2SS_VC_INTERLACED_OFFSET 0
+#define CSI2SS_VC_INTERLACED_MASK 0xF
+
+#define CSI2SS_DATA_TYPE (CSI2SS_BASE_OFFSET + 0x38)
+#define CSI2SS_DATA_TYPE_LEGACY_YUV420_8BIT (1 << 2)
+#define CSI2SS_DATA_TYPE_YUV422_8BIT (1 << 6)
+#define CSI2SS_DATA_TYPE_YUV422_10BIT (1 << 7)
+#define CSI2SS_DATA_TYPE_RGB444 (1 << 8)
+#define CSI2SS_DATA_TYPE_RGB555 (1 << 9)
+#define CSI2SS_DATA_TYPE_RGB565 (1 << 10)
+#define CSI2SS_DATA_TYPE_RGB666 (1 << 11)
+#define CSI2SS_DATA_TYPE_RGB888 (1 << 12)
+#define CSI2SS_DATA_TYPE_RAW6 (1 << 16)
+#define CSI2SS_DATA_TYPE_RAW8 (1 << 18)
+#define CSI2SS_DATA_TYPE_RAW10 (1 << 19)
+#define CSI2SS_DATA_TYPE_RAW12 (1 << 20)
+#define CSI2SS_DATA_TYPE_RAW14 (1 << 21)
+
+#define CSI2SS_YUV420_1ST_LINE_DATA_TYPE (CSI2SS_BASE_OFFSET + 0x40)
+#define CSI2SS_YUV420_1ST_LINE_DATA_TYPE_ODD 0
+#define CSI2SS_YUV420_1ST_LINE_DATA_TYPE_EVEN 1
+#define CSI2SS_YUV420_1ST_LINE_DATA_TYPE_OFFSET 0
+#define CSI2SS_YUV420_1ST_LINE_DATA_TYPE_MASK 1
+
+#define CSI2SS_CTRL_CLK_RESET (CSI2SS_BASE_OFFSET + 0x44)
+#define CSI2SS_CTRL_CLK_RESET_EN 1
+#define CSI2SS_CTRL_CLK_RESET_OFFSET 0
+#define CSI2SS_CTRL_CLK_RESET_MASK 1
+#define CSI2SS_CTRL_CLK_RESET_CLK_OFF 1
+#define CSI2SS_CTRL_CLK_RESET_CLK_OFFSET 1
+#define CSI2SS_CTRL_CLK_RESET_CLK_MASK 0x1
+
+#define CSI2SS_STREAM_FENCE_CTRL (CSI2SS_BASE_OFFSET + 0x48)
+#define CSI2SS_STREAM_FENCE_VC0 1
+#define CSI2SS_STREAM_FENCE_VC1 2
+#define CSI2SS_STREAM_FENCE_VC2 4
+#define CSI2SS_STREAM_FENCE_VC3 8
+#define CSI2SS_STREAM_FENCE_CTRL_OFFSET 0
+#define CSI2SS_STREAM_FENCE_CTRL_MASK 0xF
+
+#define CSI2SS_STREAM_FENCE_STATUS (CSI2SS_BASE_OFFSET + 0x4C)
+
+/* CSI-2 controller CSR */
+#define CSI2RX_BASE_OFFSET (0x100)
+
+#define CSI2RX_CFG_NUM_LANES (CSI2RX_BASE_OFFSET + 0x0)
+#define CSI2RX_CFG_NUM_LANES_OFFSET 0
+#define CSI2RX_CFG_NUM_LANES_MASK 0x3
+
+#define CSI2RX_CFG_DISABLE_DATA_LANES (CSI2RX_BASE_OFFSET + 0x4)
+#define CSI2RX_CFG_DISABLE_DATA_LANES_3 8
+#define CSI2RX_CFG_DISABLE_DATA_LANES_2 4
+#define CSI2RX_CFG_DISABLE_DATA_LANES_1 2
+#define CSI2RX_CFG_DISABLE_DATA_LANES_0 1
+#define CSI2RX_CFG_DISABLE_DATA_LANES_OFFSET 0
+#define CSI2RX_CFG_DISABLE_DATA_LANES_MASK 0xF
+
+#define CSI2RX_BIT_ERR (CSI2RX_BASE_OFFSET + 0x8)
+
+#define CSI2RX_IRQ_STATUS (CSI2RX_BASE_OFFSET + 0xC)
+#define CSI2RX_IRQ_STATUS_CRC_ERROR 0x1
+#define CSI2RX_IRQ_STATUS_1BIT_CRC_ERROR 0x2
+#define CSI2RX_IRQ_STATUS_2BIT_CRC_ERROR 0x4
+#define CSI2RX_IRQ_STATUS_ULPS_CHANGE 0x8
+#define CSI2RX_IRQ_STATUS_DPHY_ERRSOTHS 0x10
+#define CSI2RX_IRQ_STATUS_DPHY_ERRSOTSYNC_HS 0x20
+#define CSI2RX_IRQ_STATUS_DPHY_ERRESC 0x40
+#define CSI2RX_IRQ_STATUS_DPHY_ERRSYNCESC 0x80
+#define CSI2RX_IRQ_STATUS_DPHY_ERRCTRL 0x100
+
+#define CSI2RX_IRQ_MASK (CSI2RX_BASE_OFFSET + 0x10)
+#define CSI2RX_IRQ_MASK_CRC_ERROR 0x1
+#define CSI2RX_IRQ_MASK_1BIT_CRC_ERROR 0x2
+#define CSI2RX_IRQ_MASK_2BIT_CRC_ERROR 0x4
+#define CSI2RX_IRQ_MASK_ULPS_CHANGE 0x8
+#define CSI2RX_IRQ_MASK_DPHY_ERRSOTHS 0x10
+#define CSI2RX_IRQ_MASK_DPHY_ERRSOTSYNC_HS 0x20
+#define CSI2RX_IRQ_MASK_DPHY_ERRESC 0x40
+#define CSI2RX_IRQ_MASK_DPHY_ERRSYNCESC 0x80
+#define CSI2RX_IRQ_MASK_DPHY_ERRCTRL 0x100
+
+#define CSI2RX_ULPS_STATUS (CSI2RX_BASE_OFFSET + 0x14)
+#define CSI2RX_ULPS_STATUS_CLK_LANE_ULPS 0x1
+#define CSI2RX_ULPS_STATUS_DAT_LANE0_ULPS 0x2
+#define CSI2RX_ULPS_STATUS_DAT_LANE1_ULPS 0x4
+#define CSI2RX_ULPS_STATUS_DAT_LANE2_ULPS 0x8
+#define CSI2RX_ULPS_STATUS_DAT_LANE3_ULPS 0x10
+#define CSI2RX_ULPS_STATUS_CLK_LANE_MARK 0x20
+#define CSI2RX_ULPS_STATUS_DAT_LANE0_MARK 0x40
+#define CSI2RX_ULPS_STATUS_DAT_LANE1_MARK 0x80
+#define CSI2RX_ULPS_STATUS_DAT_LANE2_MARK 0x100
+#define CSI2RX_ULPS_STATUS_DAT_LANE3_MARK 0x200
+
+#define CSI2RX_PPI_ERRSOT_HS (CSI2RX_BASE_OFFSET + 0x18)
+#define CSI2RX_PPI_ERRSOT_HS_DAT_LANE0 0x1
+#define CSI2RX_PPI_ERRSOT_HS_DAT_LANE1 0x2
+#define CSI2RX_PPI_ERRSOT_HS_DAT_LANE2 0x4
+#define CSI2RX_PPI_ERRSOT_HS_DAT_LANE3 0x8
+
+#define CSI2RX_PPI_ERRSOTSYNC_HS (CSI2RX_BASE_OFFSET + 0x1C)
+#define CSI2RX_PPI_ERRSOTSYNC_HS_DAT_LANE0 0x1
+#define CSI2RX_PPI_ERRSOTSYNC_HS_DAT_LANE1 0x2
+#define CSI2RX_PPI_ERRSOTSYNC_HS_DAT_LANE2 0x4
+#define CSI2RX_PPI_ERRSOTSYNC_HS_DAT_LANE3 0x8
+
+#define CSI2RX_PPI_ERRESC (CSI2RX_BASE_OFFSET + 0x20)
+#define CSI2RX_PPI_ERRESC_DAT_LANE0 0x1
+#define CSI2RX_PPI_ERRESC_DAT_LANE1 0x2
+#define CSI2RX_PPI_ERRESC_DAT_LANE2 0x4
+#define CSI2RX_PPI_ERRESC_DAT_LANE3 0x8
+
+#define CSI2RX_PPI_ERRSYNCESC (CSI2RX_BASE_OFFSET + 0x24)
+#define CSI2RX_PPI_ERRSYNCESC_DAT_LANE0 0x1
+#define CSI2RX_PPI_ERRSYNCESC_DAT_LANE1 0x2
+#define CSI2RX_PPI_ERRSYNCESC_DAT_LANE2 0x4
+#define CSI2RX_PPI_ERRSYNCESC_DAT_LANE3 0x8
+
+#define CSI2RX_PPI_ERRCONTROL (CSI2RX_BASE_OFFSET + 0x28)
+#define CSI2RX_PPI_ERRCONTROL_DAT_LANE0 0x1
+#define CSI2RX_PPI_ERRCONTROL_DAT_LANE1 0x2
+#define CSI2RX_PPI_ERRCONTROL_DAT_LANE2 0x4
+#define CSI2RX_PPI_ERRCONTROL_DAT_LANE3 0x8
+
+#define CSI2RX_CFG_DISABLE_PAYLOAD_0 (CSI2RX_BASE_OFFSET + 0x2C)
+#define CSI2RX_CFG_DISABLE_PAYLOAD_TYPE_LEGACY_YUV420_8BIT (1 << 10)
+#define CSI2RX_CFG_DISABLE_PAYLOAD_TYPE_YUV422_8BIT (1 << 14)
+#define CSI2RX_CFG_DISABLE_PAYLOAD_TYPE_YUV422_10BIT (1 << 15)
+#define CSI2RX_CFG_DISABLE_PAYLOAD_TYPE_RGB444 (1 << 16)
+#define CSI2RX_CFG_DISABLE_PAYLOAD_TYPE_RGB555 (1 << 17)
+#define CSI2RX_CFG_DISABLE_PAYLOAD_TYPE_RGB565 (1 << 18)
+#define CSI2RX_CFG_DISABLE_PAYLOAD_TYPE_RGB666 (1 << 19)
+#define CSI2RX_CFG_DISABLE_PAYLOAD_TYPE_RGB888 (1 << 20)
+#define CSI2RX_CFG_DISABLE_PAYLOAD_TYPE_RAW6 (1 << 24)
+#define CSI2RX_CFG_DISABLE_PAYLOAD_TYPE_RAW7 (1 << 25)
+#define CSI2RX_CFG_DISABLE_PAYLOAD_TYPE_RAW8 (1 << 26)
+#define CSI2RX_CFG_DISABLE_PAYLOAD_TYPE_RAW10 (1 << 27)
+#define CSI2RX_CFG_DISABLE_PAYLOAD_TYPE_RAW12 (1 << 28)
+#define CSI2RX_CFG_DISABLE_PAYLOAD_TYPE_RAW14 (1 << 29)
+
+#define CSI2RX_CFG_DISABLE_PAYLOAD_1 (CSI2RX_BASE_OFFSET + 0x30)
+
+struct csis_hw_reset {
+ struct regmap *src;
+ u8 req_src;
+ u8 rst_val;
+};
+struct csis_phy_gpr {
+ struct regmap *gpr;
+ u8 req_src;
+};
+
+struct mxc_mipi_csi2_dev {
+ struct v4l2_device v4l2_dev;
+ struct v4l2_subdev sd;
+ struct v4l2_subdev *sensor_sd;
+
+ struct media_pad pads[MXC_MIPI_CSI2_VCX_PADS_NUM];
+ struct v4l2_mbus_framefmt format;
+
+ void __iomem *csr_regs;
+ void __iomem *base_regs;
+ struct platform_device *pdev;
+ u32 flags;
+ int irq;
+
+ struct clk *clk_apb;
+ struct clk *clk_core;
+ struct clk *clk_esc;
+ struct clk *clk_pxl;
+
+ struct csis_hw_reset hw_reset;
+ struct csis_phy_gpr phy_gpr;
+
+ struct v4l2_async_subdev asd;
+ struct v4l2_async_notifier subdev_notifier;
+ struct v4l2_async_subdev *async_subdevs[2];
+
+ struct mutex lock;
+
+ int id;
+ u32 hs_settle;
+ u32 send_level;
+ u32 num_lanes;
+ u8 data_lanes[4];
+ u8 vchannel;
+ u8 running;
+};
+
+enum mxc_mipi_csi2_pm_state {
+ MXC_MIPI_CSI2_PM_POWERED = 0x1,
+ MXC_MIPI_CSI2_PM_SUSPENDED = 0x2,
+ MXC_MIPI_CSI2_RUNTIME_SUSPENDED = 0x4,
+};
+
+#endif
diff --git a/drivers/media/platform/imx8/mxc-mipi-csi2_yav.c b/drivers/media/platform/imx8/mxc-mipi-csi2_yav.c
new file mode 100644
index 000000000000..abeb38279962
--- /dev/null
+++ b/drivers/media/platform/imx8/mxc-mipi-csi2_yav.c
@@ -0,0 +1,748 @@
+/*
+ * Copyright 2017 NXP
+ *
+ * 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/clk.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/errno.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/kernel.h>
+#include <linux/memory.h>
+#include <linux/mfd/syscon.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_graph.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/regmap.h>
+#include <linux/regulator/consumer.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/videodev2.h>
+#include <media/v4l2-fwnode.h>
+#include <media/v4l2-subdev.h>
+#include <media/v4l2-device.h>
+
+#include "mxc-mipi-csi2.h"
+static int debug;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "Debug level (0-2)");
+
+#define MXC_MIPI_CSI2_YAV_DRIVER_NAME "mxc-mipi-csi2_yav"
+#define MXC_MIPI_CSI2_YAV_SUBDEV_NAME MXC_MIPI_CSI2_DRIVER_NAME
+
+#define GPR_CSI2_1_RX_ENABLE BIT(13)
+#define GPR_CSI2_1_VID_INTFC_ENB BIT(12)
+#define GPR_CSI2_1_PD_RX BIT(11)
+#define GPR_CSI2_1_HSEL BIT(10)
+#define GPR_CSI2_1_AUTO_PD_EN BIT(9)
+#define GPR_CSI2_1_CONT_CLK_MODE BIT(8)
+#define GPR_CSI2_1_S_PRG_RXHS_SETTLE(x) (((x) & 0x3F) << 2)
+#define GPR_CSI2_1_RX_RCAL (3)
+
+static u8 rxhs_settle[2] = { 0x14, 0x9 };
+
+static struct mxc_mipi_csi2_dev *sd_to_mxc_mipi_csi2_dev(struct v4l2_subdev
+ *sdev)
+{
+ return container_of(sdev, struct mxc_mipi_csi2_dev, sd);
+}
+
+#ifdef debug
+static void mxc_mipi_csi2_reg_dump(struct mxc_mipi_csi2_dev *csi2dev)
+{
+ printk("MIPI CSI2 HC register dump, mipi csi%d\n", csi2dev->id);
+ printk("MIPI CSI2 HC num of lanes 0x100 = 0x%x\n",
+ readl(csi2dev->base_regs + 0x100));
+ printk("MIPI CSI2 HC dis lanes 0x104 = 0x%x\n",
+ readl(csi2dev->base_regs + 0x104));
+ printk("MIPI CSI2 HC BIT ERR 0x108 = 0x%x\n",
+ readl(csi2dev->base_regs + 0x108));
+ printk("MIPI CSI2 HC IRQ STATUS 0x10C = 0x%x\n",
+ readl(csi2dev->base_regs + 0x10C));
+ printk("MIPI CSI2 HC IRQ MASK 0x110 = 0x%x\n",
+ readl(csi2dev->base_regs + 0x110));
+ printk("MIPI CSI2 HC ULPS STATUS 0x114 = 0x%x\n",
+ readl(csi2dev->base_regs + 0x114));
+ printk("MIPI CSI2 HC DPHY ErrSotHS 0x118 = 0x%x\n",
+ readl(csi2dev->base_regs + 0x118));
+ printk("MIPI CSI2 HC DPHY ErrSotSync 0x11c = 0x%x\n",
+ readl(csi2dev->base_regs + 0x11c));
+ printk("MIPI CSI2 HC DPHY ErrEsc 0x120 = 0x%x\n",
+ readl(csi2dev->base_regs + 0x120));
+ printk("MIPI CSI2 HC DPHY ErrSyncEsc 0x124 = 0x%x\n",
+ readl(csi2dev->base_regs + 0x124));
+ printk("MIPI CSI2 HC DPHY ErrControl 0x128 = 0x%x\n",
+ readl(csi2dev->base_regs + 0x128));
+ printk("MIPI CSI2 HC DISABLE_PAYLOAD 0x12C = 0x%x\n",
+ readl(csi2dev->base_regs + 0x12C));
+ printk("MIPI CSI2 HC DISABLE_PAYLOAD 0x130 = 0x%x\n",
+ readl(csi2dev->base_regs + 0x130));
+ printk("MIPI CSI2 HC IGNORE_VC 0x180 = 0x%x\n",
+ readl(csi2dev->base_regs + 0x180));
+ printk("MIPI CSI2 HC VID_VC 0x184 = 0x%x\n",
+ readl(csi2dev->base_regs + 0x184));
+ printk("MIPI CSI2 HC FIFO_SEND_LEVEL 0x188 = 0x%x\n",
+ readl(csi2dev->base_regs + 0x188));
+ printk("MIPI CSI2 HC VID_VSYNC 0x18C = 0x%x\n",
+ readl(csi2dev->base_regs + 0x18C));
+ printk("MIPI CSI2 HC VID_SYNC_FP 0x190 = 0x%x\n",
+ readl(csi2dev->base_regs + 0x190));
+ printk("MIPI CSI2 HC VID_HSYNC 0x194 = 0x%x\n",
+ readl(csi2dev->base_regs + 0x194));
+ printk("MIPI CSI2 HC VID_HSYNC_BP 0x198 = 0x%x\n",
+ readl(csi2dev->base_regs + 0x198));
+}
+#else
+static void mxc_mipi_csi2_reg_dump(struct mxc_mipi_csi2_dev *csi2dev)
+{
+}
+#endif
+
+static int mxc_mipi_csi2_phy_reset(struct mxc_mipi_csi2_dev *csi2dev)
+{
+ struct device *dev = &csi2dev->pdev->dev;
+ struct device_node *np = dev->of_node;
+ struct device_node *node;
+ phandle phandle;
+ u32 out_val[3];
+ int ret;
+
+ ret = of_property_read_u32_array(np, "csis-phy-reset", out_val, 3);
+ if (ret) {
+ dev_info(dev, "no csis-hw-reset property found\n");
+ } else {
+ phandle = *out_val;
+
+ node = of_find_node_by_phandle(phandle);
+ if (!node) {
+ dev_dbg(dev, "not find src node by phandle\n");
+ ret = PTR_ERR(node);
+ }
+ csi2dev->hw_reset.src = syscon_node_to_regmap(node);
+ if (IS_ERR(csi2dev->hw_reset.src)) {
+ dev_err(dev, "failed to get src regmap\n");
+ ret = PTR_ERR(csi2dev->hw_reset.src);
+ }
+ of_node_put(node);
+ if (ret < 0)
+ return ret;
+
+ csi2dev->hw_reset.req_src = out_val[1];
+ csi2dev->hw_reset.rst_val = out_val[2];
+
+ /* reset mipi phy */
+ regmap_update_bits(csi2dev->hw_reset.src,
+ csi2dev->hw_reset.req_src,
+ csi2dev->hw_reset.rst_val,
+ csi2dev->hw_reset.rst_val);
+ msleep(20);
+ }
+
+ return ret;
+}
+
+static int mxc_mipi_csi2_phy_gpr(struct mxc_mipi_csi2_dev *csi2dev)
+{
+ struct device *dev = &csi2dev->pdev->dev;
+ struct device_node *np = dev->of_node;
+ struct device_node *node;
+ phandle phandle;
+ u32 out_val[2];
+ int ret;
+
+ ret = of_property_read_u32_array(np, "phy-gpr", out_val, 2);
+ if (ret) {
+ dev_dbg(dev, "no phy-gpr property found\n");
+ } else {
+ phandle = *out_val;
+
+ node = of_find_node_by_phandle(phandle);
+ if (!node) {
+ dev_dbg(dev, "not find gpr node by phandle\n");
+ ret = PTR_ERR(node);
+ }
+ csi2dev->phy_gpr.gpr = syscon_node_to_regmap(node);
+ if (IS_ERR(csi2dev->phy_gpr.gpr)) {
+ dev_err(dev, "failed to get gpr regmap\n");
+ ret = PTR_ERR(csi2dev->phy_gpr.gpr);
+ }
+ of_node_put(node);
+ if (ret < 0)
+ return ret;
+
+ csi2dev->phy_gpr.req_src = out_val[1];
+
+ regmap_update_bits(csi2dev->phy_gpr.gpr,
+ csi2dev->phy_gpr.req_src,
+ 0x3FFF,
+ GPR_CSI2_1_RX_ENABLE |
+ GPR_CSI2_1_VID_INTFC_ENB |
+ GPR_CSI2_1_HSEL |
+ GPR_CSI2_1_CONT_CLK_MODE |
+ GPR_CSI2_1_S_PRG_RXHS_SETTLE(csi2dev->
+ hs_settle));
+ }
+
+ return ret;
+}
+
+static void mxc_mipi_csi2_enable(struct mxc_mipi_csi2_dev *csi2dev)
+{
+ mxc_mipi_csi2_phy_gpr(csi2dev);
+}
+
+static void mxc_mipi_csi2_disable(struct mxc_mipi_csi2_dev *csi2dev)
+{
+ /* Disable Data lanes */
+ writel(0xf, csi2dev->base_regs + CSI2RX_CFG_DISABLE_DATA_LANES);
+}
+
+static void mxc_mipi_csi2_hc_config(struct mxc_mipi_csi2_dev *csi2dev)
+{
+ u32 val0, val1;
+ u32 i;
+
+ val0 = 0;
+
+ /* Lanes */
+ writel(csi2dev->num_lanes - 1,
+ csi2dev->base_regs + CSI2RX_CFG_NUM_LANES);
+
+ for (i = 0; i < csi2dev->num_lanes; i++)
+ val0 |= (1 << (csi2dev->data_lanes[i] - 1));
+
+ val1 = 0xF & ~val0;
+ writel(val1, csi2dev->base_regs + CSI2RX_CFG_DISABLE_DATA_LANES);
+
+ /* Mask interrupt */
+ writel(0x1FF, csi2dev->base_regs + CSI2RX_IRQ_MASK);
+
+ writel(1, csi2dev->base_regs + 0x180);
+ /* vid_vc */
+ writel(1, csi2dev->base_regs + 0x184);
+ writel(csi2dev->send_level, csi2dev->base_regs + 0x188);
+}
+
+static int mipi_csi2_clk_init(struct mxc_mipi_csi2_dev *csi2dev)
+{
+ struct device *dev = &csi2dev->pdev->dev;
+
+ csi2dev->clk_apb = devm_clk_get(dev, "clk_apb");
+ if (IS_ERR(csi2dev->clk_apb)) {
+ dev_err(dev, "failed to get csi apb clk\n");
+ return PTR_ERR(csi2dev->clk_apb);
+ }
+
+ csi2dev->clk_core = devm_clk_get(dev, "clk_core");
+ if (IS_ERR(csi2dev->clk_core)) {
+ dev_err(dev, "failed to get csi core clk\n");
+ return PTR_ERR(csi2dev->clk_core);
+ }
+
+ csi2dev->clk_esc = devm_clk_get(dev, "clk_esc");
+ if (IS_ERR(csi2dev->clk_esc)) {
+ dev_err(dev, "failed to get csi esc clk\n");
+ return PTR_ERR(csi2dev->clk_esc);
+ }
+
+ csi2dev->clk_pxl = devm_clk_get(dev, "clk_pxl");
+ if (IS_ERR(csi2dev->clk_pxl)) {
+ dev_err(dev, "failed to get csi pixel link clk\n");
+ return PTR_ERR(csi2dev->clk_pxl);
+ }
+
+ return 0;
+}
+
+static int mipi_csi2_clk_enable(struct mxc_mipi_csi2_dev *csi2dev)
+{
+ struct device *dev = &csi2dev->pdev->dev;
+ int ret;
+
+ ret = clk_prepare_enable(csi2dev->clk_apb);
+ if (ret < 0) {
+ dev_err(dev, "%s, pre clk_apb error\n", __func__);
+ return ret;
+ }
+ ret = clk_prepare_enable(csi2dev->clk_core);
+ if (ret < 0) {
+ dev_err(dev, "%s, pre clk_core error\n", __func__);
+ return ret;
+ }
+ ret = clk_prepare_enable(csi2dev->clk_esc);
+ if (ret < 0) {
+ dev_err(dev, "%s, prepare clk_esc error\n", __func__);
+ return ret;
+ }
+ ret = clk_prepare_enable(csi2dev->clk_pxl);
+ if (ret < 0) {
+ dev_err(dev, "%s, prepare clk_pxl error\n", __func__);
+ return ret;
+ }
+ return ret;
+}
+
+static void mipi_csi2_clk_disable(struct mxc_mipi_csi2_dev *csi2dev)
+{
+ clk_disable_unprepare(csi2dev->clk_apb);
+ clk_disable_unprepare(csi2dev->clk_core);
+ clk_disable_unprepare(csi2dev->clk_esc);
+ clk_disable_unprepare(csi2dev->clk_pxl);
+}
+
+static int mipi_csi2_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
+{
+ return 0;
+}
+
+/*
+ * V4L2 subdev operations
+ */
+static int mipi_csi2_s_power(struct v4l2_subdev *sd, int on)
+{
+ return 0;
+}
+
+static int mipi_csi2_s_stream(struct v4l2_subdev *sd, int enable)
+{
+ struct mxc_mipi_csi2_dev *csi2dev = sd_to_mxc_mipi_csi2_dev(sd);
+ struct device *dev = &csi2dev->pdev->dev;
+ struct v4l2_subdev *sensor_sd = csi2dev->sensor_sd;
+ int ret = 0;
+
+ dev_dbg(&csi2dev->pdev->dev, "%s: %d, csi2dev: 0x%x\n",
+ __func__, enable, csi2dev->flags);
+
+ if (enable) {
+ if (!csi2dev->running) {
+ pm_runtime_get_sync(dev);
+ mxc_mipi_csi2_phy_reset(csi2dev);
+ mxc_mipi_csi2_hc_config(csi2dev);
+ mxc_mipi_csi2_enable(csi2dev);
+ mxc_mipi_csi2_reg_dump(csi2dev);
+ }
+ v4l2_subdev_call(sensor_sd, video, s_stream, true);
+ csi2dev->running++;
+
+ } else {
+
+ v4l2_subdev_call(sensor_sd, video, s_stream, false);
+ csi2dev->running--;
+ if (!csi2dev->running) {
+ pm_runtime_put(dev);
+ mxc_mipi_csi2_disable(csi2dev);
+ }
+ }
+
+ return ret;
+}
+
+static int mipi_csis_enum_framesizes(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_frame_size_enum *fse)
+{
+ struct mxc_mipi_csi2_dev *csi2dev = sd_to_mxc_mipi_csi2_dev(sd);
+ struct v4l2_subdev *sensor_sd = csi2dev->sensor_sd;
+
+ return v4l2_subdev_call(sensor_sd, pad, enum_frame_size, NULL, fse);
+}
+
+static int mipi_csis_enum_frameintervals(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_frame_interval_enum
+ *fie)
+{
+ struct mxc_mipi_csi2_dev *csi2dev = sd_to_mxc_mipi_csi2_dev(sd);
+ struct v4l2_subdev *sensor_sd = csi2dev->sensor_sd;
+
+ return v4l2_subdev_call(sensor_sd, pad, enum_frame_interval, NULL, fie);
+}
+
+static int mipi_csis_enum_mbus_code(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_mbus_code_enum *code)
+{
+ struct mxc_mipi_csi2_dev *csi2dev = sd_to_mxc_mipi_csi2_dev(sd);
+ struct v4l2_subdev *sensor_sd = csi2dev->sensor_sd;
+
+ return v4l2_subdev_call(sensor_sd, pad, enum_mbus_code, NULL, code);
+}
+
+static int mipi_csi2_get_fmt(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_format *fmt)
+{
+ struct mxc_mipi_csi2_dev *csi2dev = sd_to_mxc_mipi_csi2_dev(sd);
+ struct v4l2_subdev *sensor_sd = csi2dev->sensor_sd;
+
+ if (fmt->pad)
+ return -EINVAL;
+
+ return v4l2_subdev_call(sensor_sd, pad, get_fmt, NULL, fmt);
+}
+
+static int mipi_csi2_set_fmt(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_format *fmt)
+{
+ struct mxc_mipi_csi2_dev *csi2dev = sd_to_mxc_mipi_csi2_dev(sd);
+ struct v4l2_subdev *sensor_sd = csi2dev->sensor_sd;
+
+ if (fmt->pad)
+ return -EINVAL;
+
+ if (fmt->format.width * fmt->format.height > 720 * 480) {
+ csi2dev->hs_settle = rxhs_settle[1];
+ } else {
+ csi2dev->hs_settle = rxhs_settle[0];
+ }
+ csi2dev->send_level = 64;
+
+ return v4l2_subdev_call(sensor_sd, pad, set_fmt, NULL, fmt);
+}
+
+static int mipi_csis_s_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *a)
+{
+ struct mxc_mipi_csi2_dev *csi2dev = sd_to_mxc_mipi_csi2_dev(sd);
+ struct v4l2_subdev *sensor_sd = csi2dev->sensor_sd;
+
+ return v4l2_subdev_call(sensor_sd, video, s_parm, a);
+}
+
+static int mipi_csis_g_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *a)
+{
+ struct mxc_mipi_csi2_dev *csi2dev = sd_to_mxc_mipi_csi2_dev(sd);
+ struct v4l2_subdev *sensor_sd = csi2dev->sensor_sd;
+
+ return v4l2_subdev_call(sensor_sd, video, g_parm, a);
+}
+
+static const struct v4l2_subdev_internal_ops mipi_csi2_sd_internal_ops = {
+ .open = mipi_csi2_open,
+};
+
+static struct v4l2_subdev_pad_ops mipi_csi2_pad_ops = {
+ .enum_frame_size = mipi_csis_enum_framesizes,
+ .enum_frame_interval = mipi_csis_enum_frameintervals,
+ .enum_mbus_code = mipi_csis_enum_mbus_code,
+ .get_fmt = mipi_csi2_get_fmt,
+ .set_fmt = mipi_csi2_set_fmt,
+};
+
+static struct v4l2_subdev_core_ops mipi_csi2_core_ops = {
+ .s_power = mipi_csi2_s_power,
+};
+
+static struct v4l2_subdev_video_ops mipi_csi2_video_ops = {
+ .s_stream = mipi_csi2_s_stream,
+
+ .s_parm = mipi_csis_s_parm,
+ .g_parm = mipi_csis_g_parm,
+};
+
+static struct v4l2_subdev_ops mipi_csi2_subdev_ops = {
+ .core = &mipi_csi2_core_ops,
+ .video = &mipi_csi2_video_ops,
+ .pad = &mipi_csi2_pad_ops,
+};
+
+static int mipi_csi2_parse_dt(struct mxc_mipi_csi2_dev *csi2dev)
+{
+ struct device *dev = &csi2dev->pdev->dev;
+ struct device_node *node = dev->of_node;
+ struct v4l2_fwnode_endpoint endpoint;
+ u32 i;
+
+ csi2dev->id = of_alias_get_id(node, "csi");
+
+ csi2dev->vchannel = of_property_read_bool(node, "virtual-channel");
+
+ node = of_graph_get_next_endpoint(node, NULL);
+ if (!node) {
+ dev_err(dev, "No port node at %s\n", node->full_name);
+ return -EINVAL;
+ }
+
+ /* Get port node */
+ v4l2_fwnode_endpoint_parse(of_fwnode_handle(node), &endpoint);
+
+ csi2dev->num_lanes = endpoint.bus.mipi_csi2.num_data_lanes;
+ for (i = 0; i < csi2dev->num_lanes; i++)
+ csi2dev->data_lanes[i] = endpoint.bus.mipi_csi2.data_lanes[i];
+
+ of_node_put(node);
+
+ return 0;
+}
+
+static inline struct mxc_mipi_csi2_dev
+*notifier_to_mipi_dev(struct v4l2_async_notifier *n)
+{
+ return container_of(n, struct mxc_mipi_csi2_dev, subdev_notifier);
+}
+
+static int subdev_notifier_bound(struct v4l2_async_notifier *notifier,
+ struct v4l2_subdev *subdev,
+ struct v4l2_async_subdev *asd)
+{
+ struct mxc_mipi_csi2_dev *csi2dev = notifier_to_mipi_dev(notifier);
+
+ /* Find platform data for this sensor subdev */
+ if (csi2dev->asd.match.fwnode.fwnode == of_fwnode_handle(subdev->dev->of_node))
+ csi2dev->sensor_sd = subdev;
+
+ if (subdev == NULL)
+ return -EINVAL;
+
+ v4l2_info(&csi2dev->v4l2_dev, "Registered sensor subdevice: %s\n",
+ subdev->name);
+
+ return 0;
+}
+
+static int mipi_csis_subdev_host(struct mxc_mipi_csi2_dev *csi2dev)
+{
+ struct device *dev = &csi2dev->pdev->dev;
+ struct device_node *parent = dev->of_node;
+ struct device_node *node, *port, *rem;
+ int ret;
+
+ /* Attach sensors linked to csi receivers */
+ for_each_available_child_of_node(parent, node) {
+ if (of_node_cmp(node->name, "port"))
+ continue;
+
+ /* The csi node can have only port subnode. */
+ port = of_get_next_child(node, NULL);
+ if (!port)
+ continue;
+ rem = of_graph_get_remote_port_parent(port);
+ of_node_put(port);
+ if (rem == NULL) {
+ v4l2_info(&csi2dev->v4l2_dev,
+ "Remote device at %s not found\n",
+ port->full_name);
+ return -1;
+ } else
+ v4l2_info(&csi2dev->v4l2_dev,
+ "Remote device at %s XXX found\n",
+ port->full_name);
+
+ csi2dev->asd.match_type = V4L2_ASYNC_MATCH_FWNODE;
+ csi2dev->asd.match.fwnode.fwnode = of_fwnode_handle(rem);
+ csi2dev->async_subdevs[0] = &csi2dev->asd;
+
+ of_node_put(rem);
+ break;
+ }
+
+ csi2dev->subdev_notifier.subdevs = csi2dev->async_subdevs;
+ csi2dev->subdev_notifier.num_subdevs = 1;
+ csi2dev->subdev_notifier.bound = subdev_notifier_bound;
+
+ ret = v4l2_async_notifier_register(&csi2dev->v4l2_dev,
+ &csi2dev->subdev_notifier);
+ if (ret)
+ dev_err(dev,
+ "Error register async notifier regoster, ret %d\n",
+ ret);
+
+ return ret;
+}
+
+static int mipi_csi2_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct resource *mem_res;
+ struct mxc_mipi_csi2_dev *csi2dev;
+ int ret = -ENOMEM;
+
+ dev_info(&pdev->dev, "%s\n", __func__);
+ csi2dev = devm_kzalloc(dev, sizeof(*csi2dev), GFP_KERNEL);
+ if (!csi2dev)
+ return -ENOMEM;
+
+ csi2dev->pdev = pdev;
+
+ ret = mipi_csi2_parse_dt(csi2dev);
+ if (ret < 0)
+ return -EINVAL;
+
+ mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ csi2dev->base_regs = devm_ioremap_resource(dev, mem_res);
+ if (IS_ERR(csi2dev->base_regs)) {
+ dev_err(dev, "Failed to get mipi csi2 HC register\n");
+ return PTR_ERR(csi2dev->base_regs);
+ }
+
+ ret = mipi_csi2_clk_init(csi2dev);
+ if (ret < 0)
+ return -EINVAL;
+
+ v4l2_subdev_init(&csi2dev->sd, &mipi_csi2_subdev_ops);
+
+ csi2dev->sd.owner = THIS_MODULE;
+ snprintf(csi2dev->sd.name, sizeof(csi2dev->sd.name), "%s.%d",
+ MXC_MIPI_CSI2_YAV_SUBDEV_NAME, csi2dev->id);
+
+ csi2dev->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+ csi2dev->sd.dev = &pdev->dev;
+
+ /* First register a v4l2 device */
+ ret = v4l2_device_register(dev, &csi2dev->v4l2_dev);
+ if (ret) {
+ dev_err(&pdev->dev, "Unable to register v4l2 device.\n");
+ return -EINVAL;
+ }
+ ret = v4l2_async_register_subdev(&csi2dev->sd);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "%s--Async register faialed, ret=%d\n",
+ __func__, ret);
+ goto e_v4l_dev;
+ }
+
+ ret = mipi_csis_subdev_host(csi2dev);
+ if (ret < 0)
+ goto e_clkdis;
+
+ /* This allows to retrieve the platform device id by the host driver */
+ v4l2_set_subdevdata(&csi2dev->sd, pdev);
+
+ /* .. and a pointer to the subdev. */
+ platform_set_drvdata(pdev, csi2dev);
+
+ ret = mipi_csi2_clk_enable(csi2dev);
+ if (ret < 0)
+ goto e_clkdis;
+
+ dev_info(&pdev->dev, "lanes: %d, name: %s\n",
+ csi2dev->num_lanes, csi2dev->sd.name);
+
+ csi2dev->running = 0;
+ csi2dev->flags = MXC_MIPI_CSI2_PM_POWERED;
+ pm_runtime_enable(&pdev->dev);
+
+ return 0;
+
+e_clkdis:
+ v4l2_async_unregister_subdev(&csi2dev->sd);
+e_v4l_dev:
+ v4l2_device_unregister(&csi2dev->v4l2_dev);
+ return ret;
+}
+
+static int mipi_csi2_remove(struct platform_device *pdev)
+{
+ struct v4l2_subdev *sd = platform_get_drvdata(pdev);
+ struct mxc_mipi_csi2_dev *csi2dev = sd_to_mxc_mipi_csi2_dev(sd);
+
+ mipi_csi2_clk_disable(csi2dev);
+ pm_runtime_disable(&pdev->dev);
+
+ return 0;
+}
+
+static int mipi_csi2_pm_runtime_resume(struct device *dev)
+{
+ struct mxc_mipi_csi2_dev *csi2dev = dev_get_drvdata(dev);
+ int ret;
+
+ ret = mipi_csi2_clk_enable(csi2dev);
+ if (ret < 0) {
+ dev_info(dev, "%s:%d fail\n", __func__, __LINE__);
+ return -EAGAIN;
+ }
+
+ return 0;
+}
+
+static int mipi_csi2_runtime_pm_suspend(struct device *dev)
+{
+ struct mxc_mipi_csi2_dev *csi2dev = dev_get_drvdata(dev);
+
+ mipi_csi2_clk_disable(csi2dev);
+
+ return 0;
+}
+
+static int mipi_csi2_pm_suspend(struct device *dev)
+{
+ struct mxc_mipi_csi2_dev *csi2dev = dev_get_drvdata(dev);
+
+ if (csi2dev->flags & MXC_MIPI_CSI2_PM_SUSPENDED)
+ return 0;
+
+ if (csi2dev->running) {
+ dev_warn(dev, "running, prevent entering suspend.\n");
+ return -EAGAIN;
+ }
+ mipi_csi2_clk_disable(csi2dev);
+ csi2dev->flags &= ~MXC_MIPI_CSI2_PM_POWERED;
+ csi2dev->flags |= MXC_MIPI_CSI2_PM_SUSPENDED;
+
+ return 0;
+}
+
+static int mipi_csi2_pm_resume(struct device *dev)
+{
+ struct mxc_mipi_csi2_dev *csi2dev = dev_get_drvdata(dev);
+ int ret;
+
+ if (csi2dev->flags & MXC_MIPI_CSI2_PM_POWERED)
+ return 0;
+
+ ret = mipi_csi2_clk_enable(csi2dev);
+ if (ret < 0) {
+ dev_info(dev, "%s:%d fail\n", __func__, __LINE__);
+ return -EAGAIN;
+ }
+
+ csi2dev->flags |= MXC_MIPI_CSI2_PM_POWERED;
+ csi2dev->flags &= ~MXC_MIPI_CSI2_PM_SUSPENDED;
+
+ return 0;
+}
+
+static const struct dev_pm_ops mipi_csi_pm_ops = {
+ SET_SYSTEM_SLEEP_PM_OPS(mipi_csi2_pm_suspend, mipi_csi2_pm_resume)
+ SET_RUNTIME_PM_OPS(mipi_csi2_runtime_pm_suspend,
+ mipi_csi2_pm_runtime_resume,
+ NULL)
+};
+
+static const struct of_device_id mipi_csi2_of_match[] = {
+ {.compatible = "fsl,mxc-mipi-csi2_yav",},
+ { /* sentinel */ },
+};
+
+MODULE_DEVICE_TABLE(of, mipi_csi2_of_match);
+
+static struct platform_driver mipi_csi2_driver = {
+ .driver = {
+ .name = MXC_MIPI_CSI2_YAV_DRIVER_NAME,
+ .of_match_table = mipi_csi2_of_match,
+ .pm = &mipi_csi_pm_ops,
+ },
+ .probe = mipi_csi2_probe,
+ .remove = mipi_csi2_remove,
+};
+
+module_platform_driver(mipi_csi2_driver);
+
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("MXC MIPI CSI2 driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:" MXC_MIPI_CSI2_YAV_DRIVER_NAME);
diff --git a/drivers/media/platform/imx8/mxc-parallel-csi.c b/drivers/media/platform/imx8/mxc-parallel-csi.c
new file mode 100644
index 000000000000..afefdd54db08
--- /dev/null
+++ b/drivers/media/platform/imx8/mxc-parallel-csi.c
@@ -0,0 +1,672 @@
+/*
+ * Copyright 2018 NXP
+ */
+/*
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+#define DEBUG
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/errno.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/kernel.h>
+#include <linux/memory.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_graph.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/regulator/consumer.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/videodev2.h>
+#include <media/v4l2-fwnode.h>
+#include <media/v4l2-subdev.h>
+#include <media/v4l2-device.h>
+#include <soc/imx8/sc/sci.h>
+#include <dt-bindings/pinctrl/pads-imx8qxp.h>
+#include <linux/init.h>
+
+#include "mxc-parallel-csi.h"
+
+static int debug;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "Debug level (0-2)");
+
+static int format;
+module_param(format, int, 0644);
+MODULE_PARM_DESC(format, "Format level (0-2)");
+
+#ifdef DEBUG
+static void mxc_pcsi_regs_dump(struct mxc_parallel_csi_dev *pcsidev)
+{
+ struct device *dev = &pcsidev->pdev->dev;
+
+ dev_dbg(dev, "HW_IF_CTRL_REG = 0x%08x\n",
+ readl(pcsidev->csr_regs + IF_CTRL_REG));
+ dev_dbg(dev, "HW_CSI_CTRL_REG = 0x%08x\n",
+ readl(pcsidev->csr_regs + CSI_CTRL_REG));
+ dev_dbg(dev, "HW_CSI_STATUS = 0x%08x\n",
+ readl(pcsidev->csr_regs + CSI_STATUS));
+ dev_dbg(dev, "HW_CSI_CTRL_REG1 = 0x%08x\n",
+ readl(pcsidev->csr_regs + CSI_CTRL_REG1));
+}
+#else
+static void mxc_pcsi_regs_dump(struct mxc_parallel_csi_dev *pcsidev) { }
+#endif
+
+static struct mxc_parallel_csi_dev *sd_to_mxc_pcsi_dev(struct v4l2_subdev *sdev)
+{
+ return container_of(sdev, struct mxc_parallel_csi_dev, sd);
+}
+
+static int mxc_pcsi_clk_get(struct mxc_parallel_csi_dev *pcsidev)
+{
+ struct device *dev = &pcsidev->pdev->dev;
+
+ pcsidev->clk_pixel = devm_clk_get(dev, "pixel");
+ if (IS_ERR(pcsidev->clk_pixel)) {
+ dev_info(dev, "%s failed to get parallel csi pixel clk\n", __func__);
+ return PTR_ERR(pcsidev->clk_pixel);
+ }
+
+ pcsidev->clk_ipg = devm_clk_get(dev, "ipg");
+ if (IS_ERR(pcsidev->clk_ipg)) {
+ dev_info(dev, "%s failed to get parallel ipg pixel clk\n", __func__);
+ return PTR_ERR(pcsidev->clk_ipg);
+ }
+
+ return 0;
+}
+
+static int mxc_pcsi_clk_enable(struct mxc_parallel_csi_dev *pcsidev)
+{
+ struct device *dev = &pcsidev->pdev->dev;
+ int ret;
+
+ if (pcsidev->clk_enable)
+ return 0;
+
+ ret = clk_prepare_enable(pcsidev->clk_pixel);
+ if (ret < 0) {
+ dev_info(dev, "%s, enable pixel clk error\n", __func__);
+ return ret;
+ }
+
+ ret = clk_prepare_enable(pcsidev->clk_ipg);
+ if (ret < 0) {
+ dev_info(dev, "%s, enable ipg clk error\n", __func__);
+ return ret;
+ }
+
+ pcsidev->clk_enable = true;
+
+ return 0;
+}
+
+static void mxc_pcsi_clk_disable(struct mxc_parallel_csi_dev *pcsidev)
+{
+ if (!pcsidev->clk_enable)
+ return;
+
+ clk_disable_unprepare(pcsidev->clk_pixel);
+ clk_disable_unprepare(pcsidev->clk_ipg);
+
+ pcsidev->clk_enable = false;
+}
+
+static void mxc_pcsi_sw_reset(struct mxc_parallel_csi_dev *pcsidev)
+{
+ u32 val;
+
+ /* Softwaret Reset */
+ val = CSI_CTRL_REG_SOFTRST;
+ writel(val, pcsidev->csr_regs + CSI_CTRL_REG_SET);
+
+ msleep(1);
+ writel(val, pcsidev->csr_regs + CSI_CTRL_REG_CLR);
+}
+
+static void mxc_pcsi_csr_config(struct mxc_parallel_csi_dev *pcsidev)
+{
+ u32 val;
+
+ /* Software Reset */
+ mxc_pcsi_sw_reset(pcsidev);
+
+ /* Config PL Data Type */
+ val = IF_CTRL_REG_DATA_TYPE(DATA_TYPE_OUT_YUV444);
+ writel(val, pcsidev->csr_regs + IF_CTRL_REG_SET);
+
+ /* Enable sync Force */
+ val = (CSI_CTRL_REG_HSYNC_FORCE_EN | CSI_CTRL_REG_VSYNC_FORCE_EN);
+ writel(val, pcsidev->csr_regs + CSI_CTRL_REG_SET);
+
+ /* Enable Pixel Link */
+ val = IF_CTRL_REG_PL_ENABLE;
+ writel(val , pcsidev->csr_regs + IF_CTRL_REG_SET);
+
+ /* Enable Pixel Link */
+ val = IF_CTRL_REG_PL_VALID;
+ writel(val , pcsidev->csr_regs + IF_CTRL_REG_SET);
+
+ /* Config CTRL REG */
+ val = readl(pcsidev->csr_regs + CSI_CTRL_REG);
+ val |= (
+ CSI_CTRL_REG_DATA_TYPE_IN(DATA_TYPE_IN_YVYU_8BITS) |
+ CSI_CTRL_REG_HSYNC_POL |
+ CSI_CTRL_REG_MASK_VSYNC_COUNTER(3) |
+ CSI_CTRL_REG_HSYNC_PULSE(2));
+
+ if (pcsidev->uv_swap)
+ val |= CSI_CTRL_REG_UV_SWAP_EN;
+
+ if (pcsidev->mode & GATE_CLOCK_MODE)
+ val |= CSI_CTRL_REG_GCLK_MODE_EN;
+ else if (pcsidev->mode & CCIR_MODE) {
+ val |= (CSI_CTRL_REG_CCIR_EN |
+ CSI_CTRL_REG_CCIR_VSYNC_RESET_EN |
+ CSI_CTRL_REG_CCIR_EXT_VSYNC_EN |
+ CSI_CTRL_REG_CCIR_ECC_ERR_CORRECT_EN);
+ }
+
+ writel(val, pcsidev->csr_regs + CSI_CTRL_REG);
+}
+
+static void mxc_pcsi_config_ctrl_reg1(struct mxc_parallel_csi_dev *pcsidev)
+{
+ struct device *dev = &pcsidev->pdev->dev;
+ u32 val;
+
+ if (pcsidev->format.width <= 0 || pcsidev->format.height <= 0) {
+ dev_dbg(dev, "%s width/height invalid\n", __func__);
+ return;
+ }
+
+ /* Config Pixel Width */
+ val = (CSI_CTRL_REG1_PIXEL_WIDTH(pcsidev->format.width - 1) |
+ CSI_CTRL_REG1_VSYNC_PULSE(pcsidev->format.width << 1));
+ writel(val, pcsidev->csr_regs + CSI_CTRL_REG1);
+
+}
+
+static void mxc_pcsi_enable_csi(struct mxc_parallel_csi_dev *pcsidev)
+{
+ u32 val;
+
+ /* Enable CSI */
+ val = CSI_CTRL_REG_CSI_EN;
+ writel(val, pcsidev->csr_regs + CSI_CTRL_REG_SET);
+
+ /* Disable SYNC Force */
+ val = (CSI_CTRL_REG_HSYNC_FORCE_EN | CSI_CTRL_REG_VSYNC_FORCE_EN);
+ writel(val, pcsidev->csr_regs + CSI_CTRL_REG_CLR);
+}
+
+static void mxc_pcsi_disable_csi(struct mxc_parallel_csi_dev *pcsidev)
+{
+ u32 val;
+
+ /* Enable Sync Force */
+ val = (CSI_CTRL_REG_HSYNC_FORCE_EN | CSI_CTRL_REG_VSYNC_FORCE_EN);
+ writel(val, pcsidev->csr_regs + CSI_CTRL_REG_SET);
+
+ /* Disable CSI */
+ val = CSI_CTRL_REG_CSI_EN;
+ writel(val, pcsidev->csr_regs + CSI_CTRL_REG_CLR);
+
+ /* Disable Pixel Link */
+ val = IF_CTRL_REG_PL_VALID | IF_CTRL_REG_PL_ENABLE;
+ writel(val , pcsidev->csr_regs + IF_CTRL_REG_CLR);
+}
+
+static struct media_pad *mxc_pcsi_get_remote_sensor_pad(
+ struct mxc_parallel_csi_dev *pcsidev)
+{
+ struct v4l2_subdev *subdev = &pcsidev->sd;
+ struct media_pad *sink_pad, *source_pad;
+ int i;
+
+ while (1) {
+ source_pad = NULL;
+ for (i = 0; i < subdev->entity.num_pads; i++) {
+ sink_pad = &subdev->entity.pads[i];
+
+ if (sink_pad->flags & MEDIA_PAD_FL_SINK) {
+ source_pad = media_entity_remote_pad(sink_pad);
+ if (source_pad)
+ break;
+ }
+ }
+ /* return first pad point in the loop */
+ return source_pad;
+ }
+
+ if (i == subdev->entity.num_pads)
+ v4l2_err(&pcsidev->v4l2_dev, "%s, No remote pad found!\n", __func__);
+
+ return NULL;
+}
+
+static int mxc_pcsi_get_sensor_fmt(struct mxc_parallel_csi_dev *pcsidev)
+{
+ struct v4l2_mbus_framefmt *mf = &pcsidev->format;
+ struct v4l2_subdev *sen_sd;
+ struct media_pad *source_pad;
+ struct v4l2_subdev_format src_fmt;
+ int ret;
+
+ /* Get remote source pad */
+ source_pad = mxc_pcsi_get_remote_sensor_pad(pcsidev);
+ if (source_pad == NULL) {
+ v4l2_err(&pcsidev->v4l2_dev, "%s, No remote pad found!\n", __func__);
+ return -EINVAL;
+ }
+
+ /* Get remote source pad subdev */
+ sen_sd = media_entity_to_v4l2_subdev(source_pad->entity);
+ if (sen_sd == NULL) {
+ v4l2_err(&pcsidev->v4l2_dev, "%s, No remote subdev found!\n", __func__);
+ return -EINVAL;
+ }
+
+ src_fmt.pad = source_pad->index;
+ ret = v4l2_subdev_call(sen_sd, pad, get_fmt, NULL, &src_fmt);
+ if (ret < 0 && ret != -ENOIOCTLCMD)
+ return -EINVAL;
+
+ /* Update input frame size and formate */
+ memcpy(mf, &src_fmt.format, sizeof(struct v4l2_mbus_framefmt));
+
+ if (mf->code == MEDIA_BUS_FMT_YUYV8_2X8)
+ pcsidev->uv_swap = 1;
+
+ dev_dbg(&pcsidev->pdev->dev, "width=%d, height=%d, fmt.code=0x%x\n", mf->width, mf->height, mf->code);
+
+ return 0;
+}
+
+static int mxc_pcsi_enum_framesizes(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_frame_size_enum *fse)
+{
+ struct mxc_parallel_csi_dev *pcsidev = sd_to_mxc_pcsi_dev(sd);
+ struct media_pad *source_pad;
+ struct v4l2_subdev *sen_sd;
+
+ /* Get remote source pad */
+ source_pad = mxc_pcsi_get_remote_sensor_pad(pcsidev);
+ if (source_pad == NULL) {
+ v4l2_err(&pcsidev->v4l2_dev, "%s, No remote pad found!\n", __func__);
+ return -EINVAL;
+ }
+
+ /* Get remote source pad subdev */
+ sen_sd = media_entity_to_v4l2_subdev(source_pad->entity);
+ if (sen_sd == NULL) {
+ v4l2_err(&pcsidev->v4l2_dev, "%s, No remote subdev found!\n", __func__);
+ return -EINVAL;
+ }
+
+ return v4l2_subdev_call(sen_sd, pad, enum_frame_size, NULL, fse);
+}
+
+static int mxc_pcsi_enum_frame_interval(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_frame_interval_enum *fie)
+{
+ struct mxc_parallel_csi_dev *pcsidev = sd_to_mxc_pcsi_dev(sd);
+ struct media_pad *source_pad;
+ struct v4l2_subdev *sen_sd;
+
+ /* Get remote source pad */
+ source_pad = mxc_pcsi_get_remote_sensor_pad(pcsidev);
+ if (source_pad == NULL) {
+ v4l2_err(&pcsidev->v4l2_dev, "%s, No remote pad found!\n", __func__);
+ return -EINVAL;
+ }
+
+ /* Get remote source pad subdev */
+ sen_sd = media_entity_to_v4l2_subdev(source_pad->entity);
+ if (sen_sd == NULL) {
+ v4l2_err(&pcsidev->v4l2_dev, "%s, No remote subdev found!\n", __func__);
+ return -EINVAL;
+ }
+
+ return v4l2_subdev_call(sen_sd, pad, enum_frame_interval, NULL, fie);
+}
+
+static int mxc_pcsi_get_fmt(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_format *fmt)
+{
+ struct mxc_parallel_csi_dev *pcsidev = sd_to_mxc_pcsi_dev(sd);
+ struct v4l2_mbus_framefmt *mf = &fmt->format;
+
+ mxc_pcsi_get_sensor_fmt(pcsidev);
+
+ memcpy(mf, &pcsidev->format, sizeof(struct v4l2_mbus_framefmt));
+ /* Source/Sink pads crop rectangle size */
+
+ return 0;
+}
+
+static int mxc_pcsi_set_fmt(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_format *fmt)
+{
+ struct mxc_parallel_csi_dev *pcsidev = sd_to_mxc_pcsi_dev(sd);
+ struct v4l2_subdev *sen_sd;
+ struct media_pad *source_pad;
+ int ret;
+
+ /* Get remote source pad */
+ source_pad = mxc_pcsi_get_remote_sensor_pad(pcsidev);
+ if (source_pad == NULL) {
+ v4l2_err(&pcsidev->v4l2_dev, "%s, No remote pad found!\n", __func__);
+ return -EINVAL;
+ }
+
+ /* Get remote source pad subdev */
+ sen_sd = media_entity_to_v4l2_subdev(source_pad->entity);
+ if (sen_sd == NULL) {
+ v4l2_err(&pcsidev->v4l2_dev, "%s, No remote subdev found!\n", __func__);
+ return -EINVAL;
+ }
+
+ fmt->pad = source_pad->index;
+ ret = v4l2_subdev_call(sen_sd, pad, set_fmt, NULL, fmt);
+ if (ret < 0 && ret != -ENOIOCTLCMD)
+ return -EINVAL;
+
+ return 0;
+}
+
+static int mxc_pcsi_s_power(struct v4l2_subdev *sd, int on)
+{
+ struct mxc_parallel_csi_dev *pcsidev = sd_to_mxc_pcsi_dev(sd);
+ struct media_pad *source_pad;
+ struct v4l2_subdev *sen_sd;
+
+ /* Get remote source pad */
+ source_pad = mxc_pcsi_get_remote_sensor_pad(pcsidev);
+ if (source_pad == NULL) {
+ v4l2_err(&pcsidev->v4l2_dev, "%s, No remote pad found!\n", __func__);
+ return -EINVAL;
+ }
+
+ /* Get remote source pad subdev */
+ sen_sd = media_entity_to_v4l2_subdev(source_pad->entity);
+ if (sen_sd == NULL) {
+ v4l2_err(&pcsidev->v4l2_dev, "%s, No remote subdev found!\n", __func__);
+ return -EINVAL;
+ }
+
+ return v4l2_subdev_call(sen_sd, core, s_power, on);
+}
+
+static int mxc_pcsi_s_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *a)
+{
+ struct mxc_parallel_csi_dev *pcsidev = sd_to_mxc_pcsi_dev(sd);
+ struct media_pad *source_pad;
+ struct v4l2_subdev *sen_sd;
+
+ /* Get remote source pad */
+ source_pad = mxc_pcsi_get_remote_sensor_pad(pcsidev);
+ if (source_pad == NULL) {
+ v4l2_err(&pcsidev->v4l2_dev, "%s, No remote pad found!\n", __func__);
+ return -EINVAL;
+ }
+
+ /* Get remote source pad subdev */
+ sen_sd = media_entity_to_v4l2_subdev(source_pad->entity);
+ if (sen_sd == NULL) {
+ v4l2_err(&pcsidev->v4l2_dev, "%s, No remote subdev found!\n", __func__);
+ return -EINVAL;
+ }
+
+ return v4l2_subdev_call(sen_sd, video, s_parm, a);
+}
+
+static int mxc_pcsi_g_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *a)
+{
+ struct mxc_parallel_csi_dev *pcsidev = sd_to_mxc_pcsi_dev(sd);
+ struct media_pad *source_pad;
+ struct v4l2_subdev *sen_sd;
+
+ /* Get remote source pad */
+ source_pad = mxc_pcsi_get_remote_sensor_pad(pcsidev);
+ if (source_pad == NULL) {
+ v4l2_err(&pcsidev->v4l2_dev, "%s, No remote pad found!\n", __func__);
+ return -EINVAL;
+ }
+
+ /* Get remote source pad subdev */
+ sen_sd = media_entity_to_v4l2_subdev(source_pad->entity);
+ if (sen_sd == NULL) {
+ v4l2_err(&pcsidev->v4l2_dev, "%s, No remote subdev found!\n", __func__);
+ return -EINVAL;
+ }
+ return v4l2_subdev_call(sen_sd, video, g_parm, a);
+}
+
+static int mxc_pcsi_s_stream(struct v4l2_subdev *sd, int enable)
+{
+ struct mxc_parallel_csi_dev *pcsidev = sd_to_mxc_pcsi_dev(sd);
+ struct device *dev = &pcsidev->pdev->dev;
+
+ dev_dbg(dev, "%s: %d, pcsidev: 0x%d\n", __func__, __LINE__, enable);
+
+ if (enable) {
+ pm_runtime_get_sync(dev);
+ if (!pcsidev->running) {
+ mxc_pcsi_get_sensor_fmt(pcsidev);
+ mxc_pcsi_csr_config(pcsidev);
+ mxc_pcsi_config_ctrl_reg1(pcsidev);
+ mxc_pcsi_enable_csi(pcsidev);
+ mxc_pcsi_regs_dump(pcsidev);
+ }
+ pcsidev->running++;
+ } else {
+ if (pcsidev->running)
+ mxc_pcsi_disable_csi(pcsidev);
+ pcsidev->running--;
+ pm_runtime_put(dev);
+ }
+
+ return 0;
+}
+
+static int mxc_pcsi_link_setup(struct media_entity *entity,
+ const struct media_pad *local,
+ const struct media_pad *remote, u32 flags)
+{
+ struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity);
+ struct platform_device *pdev = v4l2_get_subdevdata(sd);
+
+ if (local->flags & MEDIA_PAD_FL_SOURCE) {
+ switch (local->index) {
+ case MXC_PARALLEL_CSI_PAD_SOURCE:
+ break;
+ default:
+ dev_err(&pdev->dev, "%s invalid source pad\n", __func__);
+ return -EINVAL;
+ }
+ } else if (local->flags & MEDIA_PAD_FL_SINK) {
+ switch (local->index) {
+ case MXC_PARALLEL_CSI_PAD_SINK:
+ break;
+ default:
+ dev_err(&pdev->dev, "%s invalid sink pad\n", __func__);
+ return -EINVAL;
+ }
+ }
+ return 0;
+}
+
+static struct v4l2_subdev_pad_ops pcsi_pad_ops = {
+ .enum_frame_size = mxc_pcsi_enum_framesizes,
+ .enum_frame_interval = mxc_pcsi_enum_frame_interval,
+ .get_fmt = mxc_pcsi_get_fmt,
+ .set_fmt = mxc_pcsi_set_fmt,
+};
+
+static struct v4l2_subdev_core_ops pcsi_core_ops = {
+ .s_power = mxc_pcsi_s_power,
+};
+
+static struct v4l2_subdev_video_ops pcsi_video_ops = {
+ .s_parm = mxc_pcsi_s_parm,
+ .g_parm = mxc_pcsi_g_parm,
+ .s_stream = mxc_pcsi_s_stream,
+};
+
+static struct v4l2_subdev_ops pcsi_subdev_ops = {
+ .core = &pcsi_core_ops,
+ .video = &pcsi_video_ops,
+ .pad = &pcsi_pad_ops,
+};
+static const struct media_entity_operations mxc_pcsi_sd_media_ops = {
+ .link_setup = mxc_pcsi_link_setup,
+};
+
+static int mxc_parallel_csi_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct resource *mem_res;
+ struct mxc_parallel_csi_dev *pcsidev;
+ int ret;
+
+ pcsidev = devm_kzalloc(dev, sizeof(*pcsidev), GFP_KERNEL);
+ if (!pcsidev)
+ return -ENOMEM;
+
+ pcsidev->pdev = pdev;
+
+ mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ pcsidev->csr_regs = devm_ioremap_resource(dev, mem_res);
+ if (IS_ERR(pcsidev->csr_regs)) {
+ dev_dbg(dev, "Failed to get parallel CSI CSR register\n");
+ return PTR_ERR(pcsidev->csr_regs);
+ }
+
+ ret = mxc_pcsi_clk_get(pcsidev);
+ if (ret < 0)
+ return ret;
+
+ v4l2_subdev_init(&pcsidev->sd, &pcsi_subdev_ops);
+
+ pcsidev->mode = GATE_CLOCK_MODE;
+
+ pcsidev->sd.owner = THIS_MODULE;
+ sprintf(pcsidev->sd.name, "%s", MXC_PARALLEL_CSI_SUBDEV_NAME);
+
+ pcsidev->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+ pcsidev->sd.entity.function = MEDIA_ENT_F_IO_V4L;
+
+ pcsidev->sd.dev = dev;
+
+ pcsidev->pads[MXC_PARALLEL_CSI_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
+ pcsidev->pads[MXC_PARALLEL_CSI_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
+
+ ret = media_entity_pads_init(&pcsidev->sd.entity,
+ MXC_PARALLEL_CSI_PADS_NUM, pcsidev->pads);
+ if (ret < 0)
+ goto e_clkdis;
+
+ pcsidev->sd.entity.ops = &mxc_pcsi_sd_media_ops;
+
+ v4l2_set_subdevdata(&pcsidev->sd, pdev);
+
+ platform_set_drvdata(pdev, pcsidev);
+
+ pcsidev->running = 0;
+ pm_runtime_enable(dev);
+
+ dev_info(dev, "%s probe successfully\n", __func__);
+ return 0;
+
+e_clkdis:
+ media_entity_cleanup(&pcsidev->sd.entity);
+ return ret;
+}
+
+static int mxc_parallel_csi_remove(struct platform_device *pdev)
+{
+ struct mxc_parallel_csi_dev *pcsidev =
+ (struct mxc_parallel_csi_dev *)platform_get_drvdata(pdev);
+
+ media_entity_cleanup(&pcsidev->sd.entity);
+ pm_runtime_disable(&pdev->dev);
+
+ return 0;
+}
+
+static int parallel_csi_pm_suspend(struct device *dev)
+{
+ return pm_runtime_force_suspend(dev);
+}
+
+static int parallel_csi_pm_resume(struct device *dev)
+{
+ return pm_runtime_force_resume(dev);
+}
+
+static int parallel_csi_runtime_suspend(struct device *dev)
+{
+ struct mxc_parallel_csi_dev *pcsidev = dev_get_drvdata(dev);
+
+ mxc_pcsi_clk_disable(pcsidev);
+
+ return 0;
+}
+
+static int parallel_csi_runtime_resume(struct device *dev)
+{
+ struct mxc_parallel_csi_dev *pcsidev = dev_get_drvdata(dev);
+ int ret;
+
+ ret = mxc_pcsi_clk_enable(pcsidev);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
+static const struct dev_pm_ops parallel_csi_pm_ops = {
+ SET_SYSTEM_SLEEP_PM_OPS(parallel_csi_pm_suspend, parallel_csi_pm_resume)
+ SET_RUNTIME_PM_OPS(parallel_csi_runtime_suspend,
+ parallel_csi_runtime_resume, NULL)
+};
+
+static const struct of_device_id parallel_csi_of_match[] = {
+ { .compatible = "fsl,mxc-parallel-csi",},
+ { /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, parallel_csi_of_match);
+
+
+static struct platform_driver parallel_csi_driver = {
+ .driver = {
+ .name = MXC_PARALLEL_CSI_DRIVER_NAME,
+ .of_match_table = parallel_csi_of_match,
+ .pm = &parallel_csi_pm_ops,
+ },
+ .probe = mxc_parallel_csi_probe,
+ .remove = mxc_parallel_csi_remove,
+};
+
+module_platform_driver(parallel_csi_driver);
+
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("MXC PARALLEL CSI driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:" MXC_PARALLEL_CSI_DRIVER_NAME);
diff --git a/drivers/media/platform/imx8/mxc-parallel-csi.h b/drivers/media/platform/imx8/mxc-parallel-csi.h
new file mode 100644
index 000000000000..49b1fbfab07a
--- /dev/null
+++ b/drivers/media/platform/imx8/mxc-parallel-csi.h
@@ -0,0 +1,170 @@
+
+/*
+ * Copyright 2018 NXP
+ */
+/*
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#ifndef MXC_PARALLEL_CSI_H_
+#define MXC_PARALLEL_CSI_H_
+
+#include <media/v4l2-device.h>
+
+#define MXC_PARALLEL_CSI_DRIVER_NAME "mxc-parallel-csi"
+#define MXC_PARALLEL_CSI_SUBDEV_NAME MXC_PARALLEL_CSI_DRIVER_NAME
+
+#define PARALLEL_CSI_OF_NODE_NAME "pcsi"
+#define BIT_U(nr) (1U << (nr))
+
+#define MXC_PARALLEL_CSI_PAD_SOURCE 0
+#define MXC_PARALLEL_CSI_PAD_SINK 1
+#define MXC_PARALLEL_CSI_PADS_NUM 2
+
+#define CI_PI_BASE_OFFSET 0x0U
+
+/* CI_PI INTERFACE Control */
+#define IF_CTRL_REG (CI_PI_BASE_OFFSET + 0x00)
+#define IF_CTRL_REG_PL_ENABLE BIT_U(0)
+#define IF_CTRL_REG_PL_VALID BIT_U(1)
+#define IF_CTRL_REG_PL_ADDR(x) (((x) & 0x7U) << 2)
+#define IF_CTRL_REG_IF_FORCE(x) (((x) & 0x7U) << 5)
+#define IF_CTRL_REG_DATA_TYPE_SEL BIT_U(8)
+#define IF_CTRL_REG_DATA_TYPE(x) (((x) & 0x1FU) << 9)
+
+#define DATA_TYPE_OUT_NULL (0x00)
+#define DATA_TYPE_OUT_RGB (0x04)
+#define DATA_TYPE_OUT_YUV444 (0x08)
+#define DATA_TYPE_OUT_YYU420_ODD (0x10)
+#define DATA_TYPE_OUT_YYU420_EVEN (0x12)
+#define DATA_TYPE_OUT_YYY_ODD (0x18)
+#define DATA_TYPE_OUT_UYVY_EVEN (0x1A)
+#define DATA_TYPE_OUT_RAW (0x1C)
+
+#define IF_CTRL_REG_IF_FORCE_HSYNV_OVERRIDE 0x4
+#define IF_CTRL_REG_IF_FORCE_VSYNV_OVERRIDE 0x2
+#define IF_CTRL_REG_IF_FORCE_DATA_ENABLE_OVERRIDE 0x1
+
+#define IF_CTRL_REG_SET (CI_PI_BASE_OFFSET + 0x04)
+#define IF_CTRL_REG_CLR (CI_PI_BASE_OFFSET + 0x08)
+#define IF_CTRL_REG_TOG (CI_PI_BASE_OFFSET + 0x0C)
+
+/* CSI INTERFACE CONTROL REG */
+#define CSI_CTRL_REG (CI_PI_BASE_OFFSET + 0x10)
+#define CSI_CTRL_REG_CSI_EN BIT_U(0)
+#define CSI_CTRL_REG_PIXEL_CLK_POL BIT_U(1)
+#define CSI_CTRL_REG_HSYNC_POL BIT_U(2)
+#define CSI_CTRL_REG_VSYNC_POL BIT_U(3)
+#define CSI_CTRL_REG_DE_POL BIT_U(4)
+#define CSI_CTRL_REG_PIXEL_DATA_POL BIT_U(5)
+#define CSI_CTRL_REG_CCIR_EXT_VSYNC_EN BIT_U(6)
+#define CSI_CTRL_REG_CCIR_EN BIT_U(7)
+#define CSI_CTRL_REG_CCIR_VIDEO_MODE BIT_U(8)
+#define CSI_CTRL_REG_CCIR_NTSC_EN BIT_U(9)
+#define CSI_CTRL_REG_CCIR_VSYNC_RESET_EN BIT_U(10)
+#define CSI_CTRL_REG_CCIR_ECC_ERR_CORRECT_EN BIT_U(11)
+#define CSI_CTRL_REG_HSYNC_FORCE_EN BIT_U(12)
+#define CSI_CTRL_REG_VSYNC_FORCE_EN BIT_U(13)
+#define CSI_CTRL_REG_GCLK_MODE_EN BIT_U(14)
+#define CSI_CTRL_REG_VALID_SEL BIT_U(15)
+#define CSI_CTRL_REG_RAW_OUT_SEL BIT_U(16)
+#define CSI_CTRL_REG_HSYNC_OUT_SEL BIT_U(17)
+#define CSI_CTRL_REG_HSYNC_PULSE(x) (((x) & 0x7U) << 19)
+#define CSI_CTRL_REG_UV_SWAP_EN BIT_U(22)
+#define CSI_CTRL_REG_DATA_TYPE_IN(x) (((x) & 0xFU) << 23)
+#define CSI_CTRL_REG_MASK_VSYNC_COUNTER(x) (((x) & 0x3U) << 27)
+#define CSI_CTRL_REG_SOFTRST BIT_U(31)
+
+#define DATA_TYPE_IN_UYVY_BT656_8BITS 0x0
+#define DATA_TYPE_IN_UYVY_BT656_10BITS 0x1
+#define DATA_TYPE_IN_RGB_8BITS 0x2
+#define DATA_TYPE_IN_BGR_8BITS 0x3
+#define DATA_TYPE_IN_RGB_24BITS 0x4
+#define DATA_TYPE_IN_YVYU_8BITS 0x5
+#define DATA_TYPE_IN_YUV_8BITS 0x6
+#define DATA_TYPE_IN_YVYU_16BITS 0x7
+#define DATA_TYPE_IN_YUV_24BITS 0x8
+#define DATA_TYPE_IN_BAYER_8BITS 0x9
+#define DATA_TYPE_IN_BAYER_10BITS 0xA
+#define DATA_TYPE_IN_BAYER_12BITS 0xB
+#define DATA_TYPE_IN_BAYER_16BITS 0xC
+
+#define CSI_CTRL_REG_SET (CI_PI_BASE_OFFSET + 0x14)
+#define CSI_CTRL_REG_CLR (CI_PI_BASE_OFFSET + 0x18)
+#define CSI_CTRL_REG_TOG (CI_PI_BASE_OFFSET + 0x1C)
+
+/* CSI interface Status */
+#define CSI_STATUS (CI_PI_BASE_OFFSET + 0x20)
+#define CSI_STATUS_FIELD_TOGGLE BIT_U(0)
+#define CSI_STATUS_ECC_ERROR BIT_U(1)
+
+#define CSI_STATUS_SET (CI_PI_BASE_OFFSET + 0x24)
+#define CSI_STATUS_CLR (CI_PI_BASE_OFFSET + 0x28)
+#define CSI_STATUS_TOG (CI_PI_BASE_OFFSET + 0x2C)
+
+/* CSI INTERFACE CONTROL REG1 */
+#define CSI_CTRL_REG1 (CI_PI_BASE_OFFSET + 0x30)
+#define CSI_CTRL_REG1_PIXEL_WIDTH(v) (((v) & 0xFFFFU) << 0)
+#define CSI_CTRL_REG1_VSYNC_PULSE(v) (((v) & 0xFFFFU) << 16)
+
+#define CSI_CTRL_REG1_SET (CI_PI_BASE_OFFSET + 0x34)
+#define CSI_CTRL_REG1_CLR (CI_PI_BASE_OFFSET + 0x38)
+#define CSI_CTRL_REG1_TOG (CI_PI_BASE_OFFSET + 0x3C)
+
+/***********************************************************/
+#define LPCG_BASE (void __iomem *)0x58263000
+#define LPCG_LIS_CLK (0x00)
+#define LPCG_CSR_CLK (0x04)
+#define LPCG_GPIO_CLK (0x08)
+#define LPCG_PWM_CLK (0x0c)
+#define LPCG_I2C_CLK (0x10)
+#define LPCG_CSI_INTERFACE_CLK (0x18)
+#define LPCG_CSI_MCLK (0x1c)
+/***********************************************************/
+
+//#define CSI_INTERFACE_CCIR656 1
+
+struct mxc_parallel_csi_dev {
+ struct v4l2_device v4l2_dev;
+ struct v4l2_subdev sd;
+ struct v4l2_subdev *sensor_sd;
+
+ struct media_pad pads[MXC_PARALLEL_CSI_PADS_NUM];
+ struct v4l2_mbus_framefmt format;
+
+ void __iomem *csr_regs;
+ void __iomem *lpcg_regs;
+ struct platform_device *pdev;
+ u32 flags;
+ int irq;
+
+ struct clk *clk_ipg;
+ struct clk *clk_pixel;
+ struct clk *clk_sel;
+ struct clk *clk_div;
+ struct clk *clk_dpll;
+
+ bool clk_enable;
+
+ struct v4l2_async_subdev asd;
+ struct v4l2_async_notifier subdev_notifier;
+ struct v4l2_async_subdev *async_subdevs[2];
+
+ struct mutex lock;
+
+ u8 running;
+ u8 mode;
+ u8 uv_swap;
+ u8 tvdec;
+};
+#endif
+
+enum {
+ GATE_CLOCK_MODE = 0x01,
+ CCIR_MODE = 0x02,
+};
diff --git a/drivers/media/platform/imx8/ov5640_mipi_v3.c b/drivers/media/platform/imx8/ov5640_mipi_v3.c
new file mode 100644
index 000000000000..82ef3e241e3d
--- /dev/null
+++ b/drivers/media/platform/imx8/ov5640_mipi_v3.c
@@ -0,0 +1,1383 @@
+/*
+ * Copyright (C) 2012-2015 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2018 NXP
+ */
+/*
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/i2c.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/of_gpio.h>
+#include <linux/pinctrl/consumer.h>
+#include <linux/regulator/consumer.h>
+#include <linux/v4l2-mediabus.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-ctrls.h>
+
+#define OV5640_VOLTAGE_ANALOG 2800000
+#define OV5640_VOLTAGE_DIGITAL_CORE 1500000
+#define OV5640_VOLTAGE_DIGITAL_IO 1800000
+
+#define MIN_FPS 15
+#define MAX_FPS 30
+#define DEFAULT_FPS 30
+
+#define OV5640_XCLK_MIN 6000000
+#define OV5640_XCLK_MAX 24000000
+
+#define OV5640_CHIP_ID_HIGH_BYTE 0x300A
+#define OV5640_CHIP_ID_LOW_BYTE 0x300B
+
+#define OV5640_SENS_PAD_SOURCE 0
+#define OV5640_SENS_PADS_NUM 1
+
+enum ov5640_mode {
+ ov5640_mode_MIN = 0,
+ ov5640_mode_1080P_1920_1080 = 0,
+ ov5640_mode_720P_1280_720 = 1,
+ ov5640_mode_NTSC_720_480 = 2,
+ ov5640_mode_VGA_640_480 = 3,
+ ov5640_mode_QVGA_320_240 = 4,
+ ov5640_mode_QSXGA_2592_1944 = 5,
+ ov5640_mode_MAX = 5,
+ ov5640_mode_INIT = 0xff, /*only for sensor init*/
+};
+
+enum ov5640_frame_rate {
+ ov5640_15_fps,
+ ov5640_30_fps
+};
+
+static int ov5640_framerates[] = {
+ [ov5640_15_fps] = 15,
+ [ov5640_30_fps] = 30,
+};
+
+struct ov5640_datafmt {
+ u32 code;
+ enum v4l2_colorspace colorspace;
+};
+
+/* image size under 1280 * 960 are SUBSAMPLING
+ * image size upper 1280 * 960 are SCALING
+ */
+enum ov5640_downsize_mode {
+ SUBSAMPLING,
+ SCALING,
+};
+
+struct reg_value {
+ u16 u16RegAddr;
+ u8 u8Val;
+ u8 u8Mask;
+ u32 u32Delay_ms;
+};
+
+struct ov5640_mode_info {
+ enum ov5640_mode mode;
+ enum ov5640_downsize_mode dn_mode;
+ u32 width;
+ u32 height;
+ struct reg_value *init_data_ptr;
+ u32 init_data_size;
+};
+
+struct ov5640_pll_info {
+ enum ov5640_mode mode;
+ struct reg_value *init_data_ptr;
+ u32 init_data_size;
+};
+
+struct ov5640_hs_info {
+ u32 width;
+ u32 height;
+ u32 frame_rate;
+ u32 val;
+};
+
+struct ov5640 {
+ struct v4l2_subdev subdev;
+ struct i2c_client *i2c_client;
+ struct v4l2_pix_format pix;
+ const struct ov5640_datafmt *fmt;
+ struct v4l2_captureparm streamcap;
+ struct media_pad pads[OV5640_SENS_PADS_NUM];
+ bool on;
+
+ /* control settings */
+ int brightness;
+ int hue;
+ int contrast;
+ int saturation;
+ int red;
+ int green;
+ int blue;
+ int ae_mode;
+
+ u32 mclk;
+ u8 mclk_source;
+ struct clk *sensor_clk;
+ int csi;
+
+ void (*io_init)(struct ov5640 *);
+ int pwn_gpio, rst_gpio;
+};
+
+static struct reg_value ov5640_init_setting_30fps_VGA[] = {
+
+ {0x3103, 0x11, 0, 0}, {0x3008, 0x82, 0, 5}, {0x3008, 0x42, 0, 0},
+ {0x3103, 0x03, 0, 0}, {0x3017, 0x00, 0, 0}, {0x3018, 0x00, 0, 0},
+ {0x3034, 0x18, 0, 0}, {0x3035, 0x14, 0, 0}, {0x3036, 0x38, 0, 0},
+ {0x3037, 0x13, 0, 0}, {0x3108, 0x01, 0, 0}, {0x3630, 0x36, 0, 0},
+ {0x3631, 0x0e, 0, 0}, {0x3632, 0xe2, 0, 0}, {0x3633, 0x12, 0, 0},
+ {0x3621, 0xe0, 0, 0}, {0x3704, 0xa0, 0, 0}, {0x3703, 0x5a, 0, 0},
+ {0x3715, 0x78, 0, 0}, {0x3717, 0x01, 0, 0}, {0x370b, 0x60, 0, 0},
+ {0x3705, 0x1a, 0, 0}, {0x3905, 0x02, 0, 0}, {0x3906, 0x10, 0, 0},
+ {0x3901, 0x0a, 0, 0}, {0x3731, 0x12, 0, 0}, {0x3600, 0x08, 0, 0},
+ {0x3601, 0x33, 0, 0}, {0x302d, 0x60, 0, 0}, {0x3620, 0x52, 0, 0},
+ {0x371b, 0x20, 0, 0}, {0x471c, 0x50, 0, 0}, {0x3a13, 0x43, 0, 0},
+ {0x3a18, 0x00, 0, 0}, {0x3a19, 0xf8, 0, 0}, {0x3635, 0x13, 0, 0},
+ {0x3636, 0x03, 0, 0}, {0x3634, 0x40, 0, 0}, {0x3622, 0x01, 0, 0},
+ {0x3c01, 0xa4, 0, 0}, {0x3c04, 0x28, 0, 0}, {0x3c05, 0x98, 0, 0},
+ {0x3c06, 0x00, 0, 0}, {0x3c07, 0x08, 0, 0}, {0x3c08, 0x00, 0, 0},
+ {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
+ {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0},
+ {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
+ {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0}, {0x3804, 0x0a, 0, 0},
+ {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9b, 0, 0},
+ {0x3808, 0x02, 0, 0}, {0x3809, 0x80, 0, 0}, {0x380a, 0x01, 0, 0},
+ {0x380b, 0xe0, 0, 0}, {0x380c, 0x07, 0, 0}, {0x380d, 0x68, 0, 0},
+ {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0}, {0x3810, 0x00, 0, 0},
+ {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x06, 0, 0},
+ {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0},
+ {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x03, 0, 0},
+ {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0},
+ {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0},
+ {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0},
+ {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x3000, 0x00, 0, 0},
+ {0x3002, 0x1c, 0, 0}, {0x3004, 0xff, 0, 0}, {0x3006, 0xc3, 0, 0},
+ {0x300e, 0x45, 0, 0}, {0x302e, 0x08, 0, 0}, {0x4300, 0x3F, 0, 0},
+ {0x501f, 0x00, 0, 0}, {0x4713, 0x03, 0, 0}, {0x4407, 0x04, 0, 0},
+ {0x440e, 0x00, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0},
+ {0x4837, 0x0a, 0, 0}, {0x4800, 0x04, 0, 0}, {0x3824, 0x02, 0, 0},
+ {0x5000, 0xa7, 0, 0}, {0x5001, 0xa3, 0, 0}, {0x5180, 0xff, 0, 0},
+ {0x5181, 0xf2, 0, 0}, {0x5182, 0x00, 0, 0}, {0x5183, 0x14, 0, 0},
+ {0x5184, 0x25, 0, 0}, {0x5185, 0x24, 0, 0}, {0x5186, 0x09, 0, 0},
+ {0x5187, 0x09, 0, 0}, {0x5188, 0x09, 0, 0}, {0x5189, 0x88, 0, 0},
+ {0x518a, 0x54, 0, 0}, {0x518b, 0xee, 0, 0}, {0x518c, 0xb2, 0, 0},
+ {0x518d, 0x50, 0, 0}, {0x518e, 0x34, 0, 0}, {0x518f, 0x6b, 0, 0},
+ {0x5190, 0x46, 0, 0}, {0x5191, 0xf8, 0, 0}, {0x5192, 0x04, 0, 0},
+ {0x5193, 0x70, 0, 0}, {0x5194, 0xf0, 0, 0}, {0x5195, 0xf0, 0, 0},
+ {0x5196, 0x03, 0, 0}, {0x5197, 0x01, 0, 0}, {0x5198, 0x04, 0, 0},
+ {0x5199, 0x6c, 0, 0}, {0x519a, 0x04, 0, 0}, {0x519b, 0x00, 0, 0},
+ {0x519c, 0x09, 0, 0}, {0x519d, 0x2b, 0, 0}, {0x519e, 0x38, 0, 0},
+ {0x5381, 0x1e, 0, 0}, {0x5382, 0x5b, 0, 0}, {0x5383, 0x08, 0, 0},
+ {0x5384, 0x0a, 0, 0}, {0x5385, 0x7e, 0, 0}, {0x5386, 0x88, 0, 0},
+ {0x5387, 0x7c, 0, 0}, {0x5388, 0x6c, 0, 0}, {0x5389, 0x10, 0, 0},
+ {0x538a, 0x01, 0, 0}, {0x538b, 0x98, 0, 0}, {0x5300, 0x08, 0, 0},
+ {0x5301, 0x30, 0, 0}, {0x5302, 0x10, 0, 0}, {0x5303, 0x00, 0, 0},
+ {0x5304, 0x08, 0, 0}, {0x5305, 0x30, 0, 0}, {0x5306, 0x08, 0, 0},
+ {0x5307, 0x16, 0, 0}, {0x5309, 0x08, 0, 0}, {0x530a, 0x30, 0, 0},
+ {0x530b, 0x04, 0, 0}, {0x530c, 0x06, 0, 0}, {0x5480, 0x01, 0, 0},
+ {0x5481, 0x08, 0, 0}, {0x5482, 0x14, 0, 0}, {0x5483, 0x28, 0, 0},
+ {0x5484, 0x51, 0, 0}, {0x5485, 0x65, 0, 0}, {0x5486, 0x71, 0, 0},
+ {0x5487, 0x7d, 0, 0}, {0x5488, 0x87, 0, 0}, {0x5489, 0x91, 0, 0},
+ {0x548a, 0x9a, 0, 0}, {0x548b, 0xaa, 0, 0}, {0x548c, 0xb8, 0, 0},
+ {0x548d, 0xcd, 0, 0}, {0x548e, 0xdd, 0, 0}, {0x548f, 0xea, 0, 0},
+ {0x5490, 0x1d, 0, 0}, {0x5580, 0x02, 0, 0}, {0x5583, 0x40, 0, 0},
+ {0x5584, 0x10, 0, 0}, {0x5589, 0x10, 0, 0}, {0x558a, 0x00, 0, 0},
+ {0x558b, 0xf8, 0, 0}, {0x5800, 0x23, 0, 0}, {0x5801, 0x14, 0, 0},
+ {0x5802, 0x0f, 0, 0}, {0x5803, 0x0f, 0, 0}, {0x5804, 0x12, 0, 0},
+ {0x5805, 0x26, 0, 0}, {0x5806, 0x0c, 0, 0}, {0x5807, 0x08, 0, 0},
+ {0x5808, 0x05, 0, 0}, {0x5809, 0x05, 0, 0}, {0x580a, 0x08, 0, 0},
+ {0x580b, 0x0d, 0, 0}, {0x580c, 0x08, 0, 0}, {0x580d, 0x03, 0, 0},
+ {0x580e, 0x00, 0, 0}, {0x580f, 0x00, 0, 0}, {0x5810, 0x03, 0, 0},
+ {0x5811, 0x09, 0, 0}, {0x5812, 0x07, 0, 0}, {0x5813, 0x03, 0, 0},
+ {0x5814, 0x00, 0, 0}, {0x5815, 0x01, 0, 0}, {0x5816, 0x03, 0, 0},
+ {0x5817, 0x08, 0, 0}, {0x5818, 0x0d, 0, 0}, {0x5819, 0x08, 0, 0},
+ {0x581a, 0x05, 0, 0}, {0x581b, 0x06, 0, 0}, {0x581c, 0x08, 0, 0},
+ {0x581d, 0x0e, 0, 0}, {0x581e, 0x29, 0, 0}, {0x581f, 0x17, 0, 0},
+ {0x5820, 0x11, 0, 0}, {0x5821, 0x11, 0, 0}, {0x5822, 0x15, 0, 0},
+ {0x5823, 0x28, 0, 0}, {0x5824, 0x46, 0, 0}, {0x5825, 0x26, 0, 0},
+ {0x5826, 0x08, 0, 0}, {0x5827, 0x26, 0, 0}, {0x5828, 0x64, 0, 0},
+ {0x5829, 0x26, 0, 0}, {0x582a, 0x24, 0, 0}, {0x582b, 0x22, 0, 0},
+ {0x582c, 0x24, 0, 0}, {0x582d, 0x24, 0, 0}, {0x582e, 0x06, 0, 0},
+ {0x582f, 0x22, 0, 0}, {0x5830, 0x40, 0, 0}, {0x5831, 0x42, 0, 0},
+ {0x5832, 0x24, 0, 0}, {0x5833, 0x26, 0, 0}, {0x5834, 0x24, 0, 0},
+ {0x5835, 0x22, 0, 0}, {0x5836, 0x22, 0, 0}, {0x5837, 0x26, 0, 0},
+ {0x5838, 0x44, 0, 0}, {0x5839, 0x24, 0, 0}, {0x583a, 0x26, 0, 0},
+ {0x583b, 0x28, 0, 0}, {0x583c, 0x42, 0, 0}, {0x583d, 0xce, 0, 0},
+ {0x5025, 0x00, 0, 0}, {0x3a0f, 0x30, 0, 0}, {0x3a10, 0x28, 0, 0},
+ {0x3a1b, 0x30, 0, 0}, {0x3a1e, 0x26, 0, 0}, {0x3a11, 0x60, 0, 0},
+ {0x3a1f, 0x14, 0, 0}, {0x3008, 0x42, 0, 0}, {0x3c00, 0x04, 0, 300},
+};
+
+static struct reg_value ov5640_setting_30fps_VGA_640_480[] = {
+ {0x3008, 0x42, 0, 0},
+ {0x3035, 0x12, 0, 0}, {0x3036, 0x38, 0, 0}, {0x3c07, 0x08, 0, 0},
+ {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
+ {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0},
+ {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
+ {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0}, {0x3804, 0x0a, 0, 0},
+ {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9b, 0, 0},
+ {0x3808, 0x02, 0, 0}, {0x3809, 0x80, 0, 0}, {0x380a, 0x01, 0, 0},
+ {0x380b, 0xe0, 0, 0}, {0x380c, 0x07, 0, 0}, {0x380d, 0x68, 0, 0},
+ {0x380e, 0x04, 0, 0}, {0x380f, 0x38, 0, 0}, {0x3810, 0x00, 0, 0},
+ {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x06, 0, 0},
+ {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0},
+ {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x03, 0, 0},
+ {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x0e, 0, 0},
+ {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0},
+ {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0},
+ {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x4713, 0x03, 0, 0},
+ {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0},
+ {0x3824, 0x02, 0, 0}, {0x5001, 0xa3, 0, 0},
+ {0x4005, 0x1a, 0, 0}, {0x3008, 0x02, 0, 0}, {0x3503, 0x00, 0, 0},
+};
+
+static struct reg_value ov5640_setting_30fps_QVGA_320_240[] = {
+ {0x3008, 0x42, 0, 0},
+ {0x3035, 0x12, 0, 0}, {0x3036, 0x38, 0, 0}, {0x3c07, 0x08, 0, 0},
+ {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
+ {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0},
+ {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
+ {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0}, {0x3804, 0x0a, 0, 0},
+ {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9b, 0, 0},
+ {0x3808, 0x01, 0, 0}, {0x3809, 0x40, 0, 0}, {0x380a, 0x00, 0, 0},
+ {0x380b, 0xF0, 0, 0}, {0x380c, 0x07, 0, 0}, {0x380d, 0x68, 0, 0},
+ {0x380e, 0x04, 0, 0}, {0x380f, 0x38, 0, 0}, {0x3810, 0x00, 0, 0},
+ {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x06, 0, 0},
+ {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0},
+ {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x03, 0, 0},
+ {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x0e, 0, 0},
+ {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0},
+ {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0},
+ {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x4713, 0x03, 0, 0},
+ {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0},
+ {0x3824, 0x02, 0, 0}, {0x5001, 0xa3, 0, 0},
+ {0x4005, 0x1a, 0, 0}, {0x3008, 0x02, 0, 0}, {0x3503, 0x00, 0, 0},
+};
+
+static struct reg_value ov5640_setting_30fps_NTSC_720_480[] = {
+ {0x3008, 0x42, 0, 0},
+ {0x3035, 0x12, 0, 0}, {0x3036, 0x38, 0, 0}, {0x3c07, 0x08, 0, 0},
+ {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
+ {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0},
+ {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
+ {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0}, {0x3804, 0x0a, 0, 0},
+ {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9b, 0, 0},
+ {0x3808, 0x02, 0, 0}, {0x3809, 0xd0, 0, 0}, {0x380a, 0x01, 0, 0},
+ {0x380b, 0xe0, 0, 0}, {0x380c, 0x07, 0, 0}, {0x380d, 0x68, 0, 0},
+ {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0}, {0x3810, 0x00, 0, 0},
+ {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x3c, 0, 0},
+ {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0},
+ {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x03, 0, 0},
+ {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0},
+ {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0},
+ {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0},
+ {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x4713, 0x03, 0, 0},
+ {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0},
+ {0x3824, 0x02, 0, 0}, {0x5001, 0xa3, 0, 0},
+ {0x4005, 0x1a, 0, 0}, {0x3008, 0x02, 0, 0}, {0x3503, 0, 0, 0},
+};
+
+static struct reg_value ov5640_setting_30fps_720P_1280_720[] = {
+ {0x3008, 0x42, 0, 0},
+ {0x3035, 0x21, 0, 0}, {0x3036, 0x54, 0, 0}, {0x3c07, 0x07, 0, 0},
+ {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
+ {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0},
+ {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
+ {0x3802, 0x00, 0, 0}, {0x3803, 0xfa, 0, 0}, {0x3804, 0x0a, 0, 0},
+ {0x3805, 0x3f, 0, 0}, {0x3806, 0x06, 0, 0}, {0x3807, 0xa9, 0, 0},
+ {0x3808, 0x05, 0, 0}, {0x3809, 0x00, 0, 0}, {0x380a, 0x02, 0, 0},
+ {0x380b, 0xd0, 0, 0}, {0x380c, 0x07, 0, 0}, {0x380d, 0x64, 0, 0},
+ {0x380e, 0x02, 0, 0}, {0x380f, 0xe4, 0, 0}, {0x3810, 0x00, 0, 0},
+ {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x04, 0, 0},
+ {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0},
+ {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x02, 0, 0},
+ {0x3a03, 0xe4, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0xbc, 0, 0},
+ {0x3a0a, 0x01, 0, 0}, {0x3a0b, 0x72, 0, 0}, {0x3a0e, 0x01, 0, 0},
+ {0x3a0d, 0x02, 0, 0}, {0x3a14, 0x02, 0, 0}, {0x3a15, 0xe4, 0, 0},
+ {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x4713, 0x02, 0, 0},
+ {0x4407, 0x04, 0, 0}, {0x460b, 0x37, 0, 0}, {0x460c, 0x20, 0, 0},
+ {0x3824, 0x04, 0, 0}, {0x5001, 0x83, 0, 0}, {0x4005, 0x1a, 0, 0},
+ {0x3008, 0x02, 0, 0}, {0x3503, 0, 0, 0},
+};
+
+static struct reg_value ov5640_setting_30fps_1080P_1920_1080[] = {
+ {0x3008, 0x42, 0, 0},
+ {0x3035, 0x21, 0, 0}, {0x3036, 0x54, 0, 0}, {0x3c07, 0x08, 0, 0},
+ {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
+ {0x3820, 0x40, 0, 0}, {0x3821, 0x06, 0, 0}, {0x3814, 0x11, 0, 0},
+ {0x3815, 0x11, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
+ {0x3802, 0x00, 0, 0}, {0x3803, 0x00, 0, 0}, {0x3804, 0x0a, 0, 0},
+ {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9f, 0, 0},
+ {0x3808, 0x0a, 0, 0}, {0x3809, 0x20, 0, 0}, {0x380a, 0x07, 0, 0},
+ {0x380b, 0x98, 0, 0}, {0x380c, 0x0b, 0, 0}, {0x380d, 0x1c, 0, 0},
+ {0x380e, 0x07, 0, 0}, {0x380f, 0xb0, 0, 0}, {0x3810, 0x00, 0, 0},
+ {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x04, 0, 0},
+ {0x3618, 0x04, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x21, 0, 0},
+ {0x3709, 0x12, 0, 0}, {0x370c, 0x00, 0, 0}, {0x3a02, 0x03, 0, 0},
+ {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0},
+ {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0},
+ {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0},
+ {0x4001, 0x02, 0, 0}, {0x4004, 0x06, 0, 0}, {0x4713, 0x03, 0, 0},
+ {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0},
+ {0x3824, 0x02, 0, 0}, {0x5001, 0x83, 0, 0}, {0x3035, 0x11, 0, 0},
+ {0x3036, 0x54, 0, 0}, {0x3c07, 0x07, 0, 0}, {0x3c08, 0x00, 0, 0},
+ {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
+ {0x3800, 0x01, 0, 0}, {0x3801, 0x50, 0, 0}, {0x3802, 0x01, 0, 0},
+ {0x3803, 0xb2, 0, 0}, {0x3804, 0x08, 0, 0}, {0x3805, 0xef, 0, 0},
+ {0x3806, 0x05, 0, 0}, {0x3807, 0xf1, 0, 0}, {0x3808, 0x07, 0, 0},
+ {0x3809, 0x80, 0, 0}, {0x380a, 0x04, 0, 0}, {0x380b, 0x38, 0, 0},
+ {0x380c, 0x09, 0, 0}, {0x380d, 0xc4, 0, 0}, {0x380e, 0x04, 0, 0},
+ {0x380f, 0x60, 0, 0}, {0x3612, 0x2b, 0, 0}, {0x3708, 0x64, 0, 0},
+ {0x3a02, 0x04, 0, 0}, {0x3a03, 0x60, 0, 0}, {0x3a08, 0x01, 0, 0},
+ {0x3a09, 0x50, 0, 0}, {0x3a0a, 0x01, 0, 0}, {0x3a0b, 0x18, 0, 0},
+ {0x3a0e, 0x03, 0, 0}, {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x04, 0, 0},
+ {0x3a15, 0x60, 0, 0}, {0x4713, 0x02, 0, 0}, {0x4407, 0x04, 0, 0},
+ {0x460b, 0x37, 0, 0}, {0x460c, 0x20, 0, 0}, {0x3824, 0x04, 0, 0},
+ {0x4005, 0x1a, 0, 0}, {0x3008, 0x02, 0, 0},
+ {0x3503, 0, 0, 0},
+};
+
+static struct reg_value ov5640_setting_15fps_QSXGA_2592_1944[] = {
+ {0x3008, 0x42, 0, 0},
+ {0x4202, 0x0f, 0, 0}, /* stream off the sensor */
+ {0x3820, 0x40, 0, 0}, {0x3821, 0x06, 0, 0}, /*disable flip*/
+ {0x3035, 0x21, 0, 0}, {0x3036, 0x54, 0, 0}, {0x3c07, 0x08, 0, 0},
+ {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
+ {0x3820, 0x40, 0, 0}, {0x3821, 0x06, 0, 0}, {0x3814, 0x11, 0, 0},
+ {0x3815, 0x11, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
+ {0x3802, 0x00, 0, 0}, {0x3803, 0x00, 0, 0}, {0x3804, 0x0a, 0, 0},
+ {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9f, 0, 0},
+ {0x3808, 0x0a, 0, 0}, {0x3809, 0x20, 0, 0}, {0x380a, 0x07, 0, 0},
+ {0x380b, 0x98, 0, 0}, {0x380c, 0x0b, 0, 0}, {0x380d, 0x1c, 0, 0},
+ {0x380e, 0x07, 0, 0}, {0x380f, 0xb0, 0, 0}, {0x3810, 0x00, 0, 0},
+ {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x04, 0, 0},
+ {0x3618, 0x04, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x21, 0, 0},
+ {0x3709, 0x12, 0, 0}, {0x370c, 0x00, 0, 0}, {0x3a02, 0x03, 0, 0},
+ {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0},
+ {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0},
+ {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0},
+ {0x4001, 0x02, 0, 0}, {0x4004, 0x06, 0, 0}, {0x4713, 0x03, 0, 0},
+ {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0},
+ {0x3824, 0x02, 0, 0}, {0x5001, 0x83, 0, 70}, {0x3008, 0x02, 0, 0},
+ {0x4202, 0x00, 0, 0}, /* stream on the sensor */
+};
+
+static struct ov5640_mode_info ov5640_mode_info_data[2][ov5640_mode_MAX + 1] = {
+ {
+ {ov5640_mode_1080P_1920_1080, -1, 0, 0, NULL, 0},
+ {ov5640_mode_720P_1280_720, -1, 0, 0, NULL, 0},
+ {ov5640_mode_NTSC_720_480, -1, 0, 0, NULL, 0},
+ {ov5640_mode_VGA_640_480, -1, 0, 0, NULL, 0},
+ {ov5640_mode_QVGA_320_240, -1, 0, 0, NULL, 0},
+ {ov5640_mode_QSXGA_2592_1944, SCALING, 2592, 1944,
+ ov5640_setting_15fps_QSXGA_2592_1944,
+ ARRAY_SIZE(ov5640_setting_15fps_QSXGA_2592_1944)},
+ },
+ {
+ {ov5640_mode_1080P_1920_1080, SCALING, 1920, 1080,
+ ov5640_setting_30fps_1080P_1920_1080,
+ ARRAY_SIZE(ov5640_setting_30fps_1080P_1920_1080)},
+ {ov5640_mode_720P_1280_720, SUBSAMPLING, 1280, 720,
+ ov5640_setting_30fps_720P_1280_720,
+ ARRAY_SIZE(ov5640_setting_30fps_720P_1280_720)},
+ {ov5640_mode_NTSC_720_480, SUBSAMPLING, 720, 480,
+ ov5640_setting_30fps_NTSC_720_480,
+ ARRAY_SIZE(ov5640_setting_30fps_NTSC_720_480)},
+ {ov5640_mode_VGA_640_480, SUBSAMPLING, 640, 480,
+ ov5640_setting_30fps_VGA_640_480,
+ ARRAY_SIZE(ov5640_setting_30fps_VGA_640_480)},
+ {ov5640_mode_QVGA_320_240, SUBSAMPLING, 320, 240,
+ ov5640_setting_30fps_QVGA_320_240,
+ ARRAY_SIZE(ov5640_setting_30fps_QVGA_320_240)},
+ {ov5640_mode_QSXGA_2592_1944, -1, 0, 0, NULL, 0},
+ },
+};
+
+static struct ov5640_hs_info hs_setting[] = {
+ {2592, 1944, 30, 0x0B},
+ {2592, 1944, 15, 0x10},
+
+ {1920, 1080, 30, 0x0B},
+ {1920, 1080, 15, 0x10},
+
+ {1280, 720, 30, 0x11},
+ {1280, 720, 15, 0x16},
+
+ {720, 480, 30, 0x1E},
+ {720, 480, 15, 0x23},
+
+ {640, 480, 30, 0x1E},
+ {640, 480, 15, 0x23},
+
+ {320, 240, 30, 0x1E},
+ {320, 240, 15, 0x23},
+};
+
+static struct regulator *io_regulator;
+static struct regulator *core_regulator;
+static struct regulator *analog_regulator;
+
+static int ov5640_probe(struct i2c_client *adapter,
+ const struct i2c_device_id *device_id);
+static int ov5640_remove(struct i2c_client *client);
+
+static s32 ov5640_read_reg(struct ov5640 *sensor, u16 reg, u8 *val);
+static s32 ov5640_write_reg(struct ov5640 *sensor, u16 reg, u8 val);
+
+static const struct i2c_device_id ov5640_id[] = {
+ {"ov5640_mipi_v3", 0},
+ {},
+};
+
+MODULE_DEVICE_TABLE(i2c, ov5640_id);
+
+static struct i2c_driver ov5640_i2c_driver = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "ov5640_mipi_v3",
+ },
+ .probe = ov5640_probe,
+ .remove = ov5640_remove,
+ .id_table = ov5640_id,
+};
+
+static const struct ov5640_datafmt ov5640_colour_fmts[] = {
+ {MEDIA_BUS_FMT_YVYU8_2X8, V4L2_COLORSPACE_JPEG},
+ {MEDIA_BUS_FMT_UYVY8_2X8, V4L2_COLORSPACE_JPEG},
+};
+
+static struct ov5640 *to_ov5640(const struct i2c_client *client)
+{
+ return container_of(i2c_get_clientdata(client), struct ov5640, subdev);
+}
+
+static enum ov5640_frame_rate to_ov5640_frame_rate(struct v4l2_fract *timeperframe)
+{
+ enum ov5640_frame_rate rate;
+ u32 tgt_fps; /* target frames per secound */
+
+ tgt_fps = timeperframe->denominator / timeperframe->numerator;
+
+ if (tgt_fps == 30)
+ rate = ov5640_30_fps;
+ else if (tgt_fps == 15)
+ rate = ov5640_15_fps;
+ else
+ rate = -EINVAL;
+
+ return rate;
+}
+
+static uint16_t find_hs_configure(struct ov5640 *sensor)
+{
+ struct device *dev = &sensor->i2c_client->dev;
+ struct v4l2_fract *timeperframe = &sensor->streamcap.timeperframe;
+ struct v4l2_pix_format *pix = &sensor->pix;
+ u32 frame_rate = timeperframe->denominator / timeperframe->numerator;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(hs_setting); i++) {
+ if (hs_setting[i].width == pix->width &&
+ hs_setting[i].height == pix->height &&
+ hs_setting[i].frame_rate == frame_rate)
+ return hs_setting[i].val;
+ }
+
+ if (i == ARRAY_SIZE(hs_setting))
+ dev_err(dev, "%s can not find hs configure\n", __func__);
+
+ return -EINVAL;
+}
+
+/* Find a data format by a pixel code in an array */
+static const struct ov5640_datafmt
+ *ov5640_find_datafmt(u32 code)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(ov5640_colour_fmts); i++)
+ if (ov5640_colour_fmts[i].code == code)
+ return ov5640_colour_fmts + i;
+
+ return NULL;
+}
+
+static inline void ov5640_power_down(struct ov5640 *sensor, int enable)
+{
+ gpio_set_value_cansleep(sensor->pwn_gpio, enable);
+
+ udelay(2000);
+}
+
+static inline void ov5640_reset(struct ov5640 *sensor)
+{
+ gpio_set_value_cansleep(sensor->pwn_gpio, 1);
+ gpio_set_value_cansleep(sensor->rst_gpio, 0);
+ udelay(5000);
+
+ gpio_set_value_cansleep(sensor->pwn_gpio, 0);
+ udelay(1000);
+
+ gpio_set_value_cansleep(sensor->rst_gpio, 1);
+ msleep(20);
+}
+
+static int ov5640_regulator_enable(struct device *dev)
+{
+ int ret = 0;
+
+ io_regulator = devm_regulator_get(dev, "DOVDD");
+ if (!IS_ERR(io_regulator)) {
+ regulator_set_voltage(io_regulator,
+ OV5640_VOLTAGE_DIGITAL_IO,
+ OV5640_VOLTAGE_DIGITAL_IO);
+ ret = regulator_enable(io_regulator);
+ if (ret) {
+ dev_err(dev, "set io voltage failed\n");
+ return ret;
+ } else {
+ dev_dbg(dev, "set io voltage ok\n");
+ }
+ } else {
+ io_regulator = NULL;
+ dev_warn(dev, "cannot get io voltage\n");
+ }
+
+ core_regulator = devm_regulator_get(dev, "DVDD");
+ if (!IS_ERR(core_regulator)) {
+ regulator_set_voltage(core_regulator,
+ OV5640_VOLTAGE_DIGITAL_CORE,
+ OV5640_VOLTAGE_DIGITAL_CORE);
+ ret = regulator_enable(core_regulator);
+ if (ret) {
+ dev_err(dev, "set core voltage failed\n");
+ return ret;
+ } else {
+ dev_dbg(dev, "set core voltage ok\n");
+ }
+ } else {
+ core_regulator = NULL;
+ dev_warn(dev, "cannot get core voltage\n");
+ }
+
+ analog_regulator = devm_regulator_get(dev, "AVDD");
+ if (!IS_ERR(analog_regulator)) {
+ regulator_set_voltage(analog_regulator,
+ OV5640_VOLTAGE_ANALOG,
+ OV5640_VOLTAGE_ANALOG);
+ ret = regulator_enable(analog_regulator);
+ if (ret)
+ dev_err(dev, "set analog voltage failed\n");
+ else
+ dev_dbg(dev, "set analog voltage ok\n");
+ } else {
+ analog_regulator = NULL;
+ dev_warn(dev, "cannot get analog voltage\n");
+ }
+
+ return ret;
+}
+
+static s32 ov5640_write_reg(struct ov5640 *sensor, u16 reg, u8 val)
+{
+ struct device *dev = &sensor->i2c_client->dev;
+ u8 au8Buf[3] = {0};
+
+ au8Buf[0] = reg >> 8;
+ au8Buf[1] = reg & 0xff;
+ au8Buf[2] = val;
+
+ if (i2c_master_send(sensor->i2c_client, au8Buf, 3) < 0) {
+ dev_err(dev, "Write reg error: reg=%x, val=%x\n", reg, val);
+ return -1;
+ }
+
+ return 0;
+}
+
+static s32 ov5640_read_reg(struct ov5640 *sensor, u16 reg, u8 *val)
+{
+ struct device *dev = &sensor->i2c_client->dev;
+ u8 au8RegBuf[2] = {0};
+ u8 u8RdVal = 0;
+
+ au8RegBuf[0] = reg >> 8;
+ au8RegBuf[1] = reg & 0xff;
+
+ if (i2c_master_send(sensor->i2c_client, au8RegBuf, 2) != 2) {
+ dev_err(dev, "Read reg error: reg=%x\n", reg);
+ return -1;
+ }
+
+ if (i2c_master_recv(sensor->i2c_client, &u8RdVal, 1) != 1) {
+ dev_err(dev, "Read reg error: reg=%x, val=%x\n", reg, u8RdVal);
+ return -1;
+ }
+
+ *val = u8RdVal;
+
+ return u8RdVal;
+}
+
+static int ov5640_set_clk_rate(struct ov5640 *sensor)
+{
+ u32 tgt_xclk; /* target xclk */
+ int ret;
+
+ /* mclk */
+ tgt_xclk = sensor->mclk;
+ tgt_xclk = min_t(u32, tgt_xclk, (u32)OV5640_XCLK_MAX);
+ tgt_xclk = max_t(u32, tgt_xclk, (u32)OV5640_XCLK_MIN);
+ sensor->mclk = tgt_xclk;
+
+ pr_debug(" Setting mclk to %d MHz\n", tgt_xclk / 1000000);
+ ret = clk_set_rate(sensor->sensor_clk, sensor->mclk);
+ if (ret < 0)
+ pr_debug("set rate filed, rate=%d\n", sensor->mclk);
+ return ret;
+}
+
+/* download ov5640 settings to sensor through i2c */
+static int ov5640_download_firmware(struct ov5640 *sensor,
+ struct reg_value *pModeSetting, s32 ArySize)
+{
+ register u32 Delay_ms = 0;
+ register u16 RegAddr = 0;
+ register u8 Mask = 0;
+ register u8 Val = 0;
+ u8 RegVal = 0;
+ int i, retval = 0;
+
+ for (i = 0; i < ArySize; ++i, ++pModeSetting) {
+ Delay_ms = pModeSetting->u32Delay_ms;
+ RegAddr = pModeSetting->u16RegAddr;
+ Val = pModeSetting->u8Val;
+ Mask = pModeSetting->u8Mask;
+
+ if (Mask) {
+ retval = ov5640_read_reg(sensor, RegAddr, &RegVal);
+ if (retval < 0)
+ goto err;
+
+ RegVal &= ~(u8)Mask;
+ Val &= Mask;
+ Val |= RegVal;
+ }
+
+ retval = ov5640_write_reg(sensor, RegAddr, Val);
+ if (retval < 0)
+ goto err;
+
+ if (Delay_ms)
+ msleep(Delay_ms);
+ }
+err:
+ return retval;
+}
+
+static void ov5640_soft_reset(struct ov5640 *sensor)
+{
+ /* sysclk from pad */
+ ov5640_write_reg(sensor, 0x3103, 0x11);
+
+ /* software reset */
+ ov5640_write_reg(sensor, 0x3008, 0x82);
+
+ /* delay at least 5ms */
+ msleep(10);
+}
+
+static int ov5640_config_init(struct ov5640 *sensor)
+{
+ struct reg_value *pModeSetting = NULL;
+ int ArySize = 0, retval = 0;
+
+ /* Configure ov5640 initial parm */
+ pModeSetting = ov5640_init_setting_30fps_VGA;
+ ArySize = ARRAY_SIZE(ov5640_init_setting_30fps_VGA);
+
+ retval = ov5640_download_firmware(sensor, pModeSetting, ArySize);
+ if (retval < 0)
+ return retval;
+
+ return 0;
+}
+
+static void ov5640_start(struct ov5640 *sensor)
+{
+ ov5640_write_reg(sensor, 0x3008, 0x02);
+ ov5640_write_reg(sensor, 0x3008, 0x02);
+
+ /* Color bar control */
+ /*ov5640_write_reg(sensor, 0x503d, 0x80);*/
+ udelay(1000);
+}
+
+static int ov5640_change_mode(struct ov5640 *sensor)
+{
+ struct reg_value *pModeSetting = NULL;
+ enum ov5640_mode mode = sensor->streamcap.capturemode;
+ enum ov5640_frame_rate frame_rate =
+ to_ov5640_frame_rate(&sensor->streamcap.timeperframe);
+ int ArySize = 0, retval = 0;
+
+ if (mode > ov5640_mode_MAX || mode < ov5640_mode_MIN) {
+ pr_err("Wrong ov5640 mode detected!\n");
+ return -1;
+ }
+
+ pModeSetting = ov5640_mode_info_data[frame_rate][mode].init_data_ptr;
+ ArySize = ov5640_mode_info_data[frame_rate][mode].init_data_size;
+
+ sensor->pix.width = ov5640_mode_info_data[frame_rate][mode].width;
+ sensor->pix.height = ov5640_mode_info_data[frame_rate][mode].height;
+
+ if (sensor->pix.width == 0 || sensor->pix.height == 0 ||
+ pModeSetting == NULL || ArySize == 0) {
+ pr_err("Not support mode=%d %s\n", mode,
+ (frame_rate == 0) ? "15(fps)" : "30(fps)");
+ return -EINVAL;
+ }
+
+ retval = ov5640_download_firmware(sensor, pModeSetting, ArySize);
+ return retval;
+}
+
+static int init_device(struct ov5640 *sensor)
+{
+ int retval;
+
+ ov5640_soft_reset(sensor);
+ retval = ov5640_config_init(sensor);
+ if (retval < 0)
+ return retval;
+
+ ov5640_start(sensor);
+
+ return 0;
+}
+
+static void ov5640_stop(struct ov5640 *sensor)
+{
+ ov5640_write_reg(sensor, 0x3008, 0x42);
+ udelay(1000);
+}
+
+/*!
+ * ov5640_s_power - V4L2 sensor interface handler for VIDIOC_S_POWER ioctl
+ * @s: pointer to standard V4L2 device structure
+ * @on: indicates power mode (on or off)
+ *
+ * Turns the power on or off, depending on the value of on and returns the
+ * appropriate error code.
+ */
+static int ov5640_s_power(struct v4l2_subdev *sd, int on)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct ov5640 *sensor = to_ov5640(client);
+
+ if (on)
+ clk_prepare_enable(sensor->sensor_clk);
+ else
+ clk_disable_unprepare(sensor->sensor_clk);
+
+ sensor->on = on;
+ return 0;
+}
+
+/*!
+ * ov5640_g_parm - V4L2 sensor interface handler for VIDIOC_G_PARM ioctl
+ * @s: pointer to standard V4L2 sub device structure
+ * @a: pointer to standard V4L2 VIDIOC_G_PARM ioctl structure
+ *
+ * Returns the sensor's video CAPTURE parameters.
+ */
+static int ov5640_g_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *a)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct ov5640 *sensor = to_ov5640(client);
+ struct v4l2_captureparm *cparm = &a->parm.capture;
+ int ret = 0;
+
+ switch (a->type) {
+ /* This is the only case currently handled. */
+ case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+ case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
+ memset(a, 0, sizeof(*a));
+ a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ cparm->capability = sensor->streamcap.capability;
+ cparm->timeperframe = sensor->streamcap.timeperframe;
+ cparm->capturemode = sensor->streamcap.capturemode;
+ ret = 0;
+ break;
+
+ /* These are all the possible cases. */
+ case V4L2_BUF_TYPE_VIDEO_OUTPUT:
+ case V4L2_BUF_TYPE_VIDEO_OVERLAY:
+ case V4L2_BUF_TYPE_VBI_CAPTURE:
+ case V4L2_BUF_TYPE_VBI_OUTPUT:
+ case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
+ case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
+ ret = -EINVAL;
+ break;
+
+ default:
+ pr_debug(" type is unknown - %d\n", a->type);
+ ret = -EINVAL;
+ break;
+ }
+
+ return ret;
+}
+
+/*!
+ * ov5460_s_parm - V4L2 sensor interface handler for VIDIOC_S_PARM ioctl
+ * @s: pointer to standard V4L2 sub device structure
+ * @a: pointer to standard V4L2 VIDIOC_S_PARM ioctl structure
+ *
+ * Configures the sensor to use the input parameters, if possible. If
+ * not possible, reverts to the old parameters and returns the
+ * appropriate error code.
+ */
+static int ov5640_s_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *a)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct ov5640 *sensor = to_ov5640(client);
+ struct v4l2_fract *timeperframe = &a->parm.capture.timeperframe;
+ u32 tgt_fps; /* target frames per secound */
+ enum ov5640_mode mode = a->parm.capture.capturemode;
+ int ret = 0;
+
+
+ switch (a->type) {
+ /* This is the only case currently handled. */
+ case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+ case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
+ /* Check that the new frame rate is allowed. */
+ if ((timeperframe->numerator == 0) ||
+ (timeperframe->denominator == 0)) {
+ timeperframe->denominator = DEFAULT_FPS;
+ timeperframe->numerator = 1;
+ }
+
+ tgt_fps = timeperframe->denominator /
+ timeperframe->numerator;
+
+ if (tgt_fps > MAX_FPS) {
+ timeperframe->denominator = MAX_FPS;
+ timeperframe->numerator = 1;
+ } else if (tgt_fps < MIN_FPS) {
+ timeperframe->denominator = MIN_FPS;
+ timeperframe->numerator = 1;
+ }
+
+ if (mode > ov5640_mode_MAX || mode < ov5640_mode_MIN) {
+ pr_err("The camera mode[%d] is not supported!\n", mode);
+ return -EINVAL;
+ }
+
+ sensor->streamcap.capturemode = mode;
+ sensor->streamcap.timeperframe = *timeperframe;
+ break;
+
+ /* These are all the possible cases. */
+ case V4L2_BUF_TYPE_VIDEO_OUTPUT:
+ case V4L2_BUF_TYPE_VIDEO_OVERLAY:
+ case V4L2_BUF_TYPE_VBI_CAPTURE:
+ case V4L2_BUF_TYPE_VBI_OUTPUT:
+ case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
+ case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
+ pr_debug(" type is not V4L2_BUF_TYPE_VIDEO_CAPTURE but %d\n",
+ a->type);
+ ret = -EINVAL;
+ break;
+
+ default:
+ pr_debug(" type is unknown - %d\n", a->type);
+ ret = -EINVAL;
+ break;
+ }
+
+ return ret;
+}
+
+static int ov5640_s_stream(struct v4l2_subdev *sd, int enable)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct ov5640 *sensor = to_ov5640(client);
+
+ if (enable)
+ ov5640_start(sensor);
+ else
+ ov5640_stop(sensor);
+
+ sensor->on = enable;
+ return 0;
+}
+
+static struct ov5640_mode_info *get_max_resolution(enum ov5640_frame_rate rate)
+{
+ u32 max_width;
+ enum ov5640_mode mode;
+ int i;
+
+ mode = 0;
+ max_width = ov5640_mode_info_data[rate][0].width;
+
+ for (i = 0; i < (ov5640_mode_MAX + 1); i++) {
+ if (ov5640_mode_info_data[rate][i].width > max_width) {
+ max_width = ov5640_mode_info_data[rate][i].width;
+ mode = i;
+ }
+ }
+ return &ov5640_mode_info_data[rate][mode];
+}
+
+static struct ov5640_mode_info *match(struct v4l2_mbus_framefmt *fmt,
+ enum ov5640_frame_rate rate)
+{
+ struct ov5640_mode_info *info;
+ int i;
+
+ for (i = 0; i < (ov5640_mode_MAX + 1); i++) {
+ if (fmt->width == ov5640_mode_info_data[rate][i].width &&
+ fmt->height == ov5640_mode_info_data[rate][i].height) {
+ info = &ov5640_mode_info_data[rate][i];
+ break;
+ }
+ }
+ if (i == ov5640_mode_MAX + 1)
+ info = NULL;
+
+ return info;
+}
+
+static void try_to_find_resolution(struct ov5640 *sensor,
+ struct v4l2_mbus_framefmt *mf)
+{
+ enum ov5640_mode mode = sensor->streamcap.capturemode;
+ struct v4l2_fract *timeperframe = &sensor->streamcap.timeperframe;
+ enum ov5640_frame_rate frame_rate = to_ov5640_frame_rate(timeperframe);
+ struct device *dev = &sensor->i2c_client->dev;
+ struct ov5640_mode_info *info;
+ bool found = false;
+
+ if ((mf->width == ov5640_mode_info_data[frame_rate][mode].width) &&
+ (mf->height == ov5640_mode_info_data[frame_rate][mode].height)) {
+ info = &ov5640_mode_info_data[frame_rate][mode];
+ found = true;
+ } else {
+ /* get mode info according to frame user's width and height */
+ info = match(mf, frame_rate);
+ if (info == NULL) {
+ frame_rate ^= 0x1;
+ info = match(mf, frame_rate);
+ if (info) {
+ sensor->streamcap.capturemode = -1;
+ dev_err(dev, "%s %dx%d only support %s(fps)\n", __func__,
+ info->width, info->height,
+ (frame_rate == 0) ? "15fps" : "30fps");
+ return;
+ }
+ goto max_resolution;
+ }
+ found = true;
+ }
+
+ /* get max resolution to resize */
+max_resolution:
+ if (!found) {
+ frame_rate ^= 0x1;
+ info = get_max_resolution(frame_rate);
+ }
+
+ sensor->streamcap.capturemode = info->mode;
+ sensor->streamcap.timeperframe.denominator = (frame_rate) ? 30 : 15;
+ sensor->pix.width = info->width;
+ sensor->pix.height = info->height;
+}
+
+static int ov5640_set_fmt(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_format *format)
+{
+ struct v4l2_mbus_framefmt *mf = &format->format;
+ const struct ov5640_datafmt *fmt = ov5640_find_datafmt(mf->code);
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct ov5640 *sensor = to_ov5640(client);
+ int ret;
+
+ if (format->pad)
+ return -EINVAL;
+
+ if (!fmt) {
+ mf->code = ov5640_colour_fmts[1].code;
+ mf->colorspace = ov5640_colour_fmts[1].colorspace;
+ }
+
+ mf->field = V4L2_FIELD_NONE;
+ try_to_find_resolution(sensor, mf);
+
+ if (format->which == V4L2_SUBDEV_FORMAT_TRY)
+ return 0;
+
+ init_device(sensor);
+ ret = ov5640_change_mode(sensor);
+ sensor->fmt = fmt;
+
+ return ret;
+}
+
+static int ov5640_get_fmt(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_format *format)
+{
+ struct v4l2_mbus_framefmt *mf = &format->format;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct ov5640 *sensor = to_ov5640(client);
+
+ if (format->pad)
+ return -EINVAL;
+
+ memset(mf, 0, sizeof(struct v4l2_mbus_framefmt));
+
+ mf->code = ov5640_colour_fmts[1].code;
+ mf->colorspace = ov5640_colour_fmts[1].colorspace;
+ mf->width = sensor->pix.width;
+ mf->height = sensor->pix.height;
+ mf->field = V4L2_FIELD_NONE;
+ mf->reserved[1] = find_hs_configure(sensor);
+
+ dev_dbg(&client->dev, "%s code=0x%x, w/h=(%d,%d), colorspace=%d, field=%d\n",
+ __func__, mf->code, mf->width, mf->height, mf->colorspace, mf->field);
+
+ return 0;
+}
+
+static int ov5640_enum_code(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_mbus_code_enum *code)
+{
+ if (code->pad || code->index >= ARRAY_SIZE(ov5640_colour_fmts))
+ return -EINVAL;
+
+ code->code = ov5640_colour_fmts[code->index].code;
+ return 0;
+}
+
+/*!
+ * ov5640_enum_framesizes - V4L2 sensor interface handler for
+ * VIDIOC_ENUM_FRAMESIZES ioctl
+ * @s: pointer to standard V4L2 device structure
+ * @fsize: standard V4L2 VIDIOC_ENUM_FRAMESIZES ioctl structure
+ *
+ * Return 0 if successful, otherwise -EINVAL.
+ */
+static int ov5640_enum_framesizes(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_frame_size_enum *fse)
+{
+ if (fse->index > ov5640_mode_MAX)
+ return -EINVAL;
+
+ fse->max_width =
+ max(ov5640_mode_info_data[0][fse->index].width,
+ ov5640_mode_info_data[1][fse->index].width);
+ fse->min_width = fse->max_width;
+
+ fse->max_height =
+ max(ov5640_mode_info_data[0][fse->index].height,
+ ov5640_mode_info_data[1][fse->index].height);
+ fse->min_height = fse->max_height;
+
+ return 0;
+}
+
+/*!
+ * ov5640_enum_frameintervals - V4L2 sensor interface handler for
+ * VIDIOC_ENUM_FRAMEINTERVALS ioctl
+ * @s: pointer to standard V4L2 device structure
+ * @fival: standard V4L2 VIDIOC_ENUM_FRAMEINTERVALS ioctl structure
+ *
+ * Return 0 if successful, otherwise -EINVAL.
+ */
+static int ov5640_enum_frameintervals(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_frame_interval_enum *fie)
+{
+ int i, j, count;
+
+ if (fie->index < 0 || fie->index > ov5640_mode_MAX)
+ return -EINVAL;
+
+ if (fie->width == 0 || fie->height == 0 ||
+ fie->code == 0) {
+ pr_warn("Please assign pixel format, width and height.\n");
+ return -EINVAL;
+ }
+
+ fie->interval.numerator = 1;
+
+ count = 0;
+ for (i = 0; i < ARRAY_SIZE(ov5640_framerates); i++) {
+ for (j = 0; j < (ov5640_mode_MAX + 1); j++) {
+ if (fie->width == ov5640_mode_info_data[i][j].width
+ && fie->height == ov5640_mode_info_data[i][j].height
+ && ov5640_mode_info_data[i][j].init_data_ptr != NULL) {
+ count++;
+ }
+ if (fie->index == (count - 1)) {
+ fie->interval.denominator = ov5640_framerates[i];
+ return 0;
+ }
+ }
+ }
+
+ return -EINVAL;
+}
+
+static int ov5640_link_setup(struct media_entity *entity,
+ const struct media_pad *local,
+ const struct media_pad *remote, u32 flags)
+{
+ return 0;
+}
+
+static struct v4l2_subdev_video_ops ov5640_subdev_video_ops = {
+ .g_parm = ov5640_g_parm,
+ .s_parm = ov5640_s_parm,
+ .s_stream = ov5640_s_stream,
+};
+
+static const struct v4l2_subdev_pad_ops ov5640_subdev_pad_ops = {
+ .enum_frame_size = ov5640_enum_framesizes,
+ .enum_frame_interval = ov5640_enum_frameintervals,
+ .enum_mbus_code = ov5640_enum_code,
+ .set_fmt = ov5640_set_fmt,
+ .get_fmt = ov5640_get_fmt,
+};
+
+static struct v4l2_subdev_core_ops ov5640_subdev_core_ops = {
+ .s_power = ov5640_s_power,
+};
+
+static struct v4l2_subdev_ops ov5640_subdev_ops = {
+ .core = &ov5640_subdev_core_ops,
+ .video = &ov5640_subdev_video_ops,
+ .pad = &ov5640_subdev_pad_ops,
+};
+
+static const struct media_entity_operations ov5640_sd_media_ops = {
+ .link_setup = ov5640_link_setup,
+};
+
+/*!
+ * ov5640 I2C probe function
+ *
+ * @param adapter struct i2c_adapter *
+ * @return Error code indicating success or failure
+ */
+static int ov5640_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct pinctrl *pinctrl;
+ struct device *dev = &client->dev;
+ struct v4l2_subdev *sd;
+ int retval;
+ u8 chip_id_high, chip_id_low;
+ struct ov5640 *sensor;
+
+ sensor = devm_kmalloc(dev, sizeof(*sensor), GFP_KERNEL);
+ if (!sensor)
+ return -ENOMEM;
+ /* Set initial values for the sensor struct. */
+ memset(sensor, 0, sizeof(*sensor));
+
+ /* ov5640 pinctrl */
+ pinctrl = devm_pinctrl_get_select_default(dev);
+ if (IS_ERR(pinctrl)) {
+ dev_err(dev, "setup pinctrl failed\n");
+ return PTR_ERR(pinctrl);
+ }
+
+ /* request power down pin */
+ sensor->pwn_gpio = of_get_named_gpio(dev->of_node, "pwn-gpios", 0);
+ if (!gpio_is_valid(sensor->pwn_gpio))
+ dev_warn(dev, "No sensor pwdn pin available");
+ else {
+ retval = devm_gpio_request_one(dev, sensor->pwn_gpio,
+ GPIOF_OUT_INIT_HIGH, "ov5640_mipi_pwdn");
+ if (retval < 0) {
+ dev_warn(dev, "Failed to set power pin\n");
+ dev_warn(dev, "retval=%d\n", retval);
+ return retval;
+ }
+ }
+
+ /* request reset pin */
+ sensor->rst_gpio = of_get_named_gpio(dev->of_node, "rst-gpios", 0);
+ if (!gpio_is_valid(sensor->rst_gpio))
+ dev_warn(dev, "No sensor reset pin available");
+ else {
+ retval = devm_gpio_request_one(dev, sensor->rst_gpio,
+ GPIOF_OUT_INIT_HIGH, "ov5640_mipi_reset");
+ if (retval < 0) {
+ dev_warn(dev, "Failed to set reset pin\n");
+ return retval;
+ }
+ }
+
+ /* Set initial values for the sensor struct. */
+ sensor->sensor_clk = devm_clk_get(dev, "csi_mclk");
+ if (IS_ERR(sensor->sensor_clk)) {
+ /* assuming clock enabled by default */
+ sensor->sensor_clk = NULL;
+ dev_err(dev, "clock-frequency missing or invalid\n");
+ return PTR_ERR(sensor->sensor_clk);
+ }
+
+ retval = of_property_read_u32(dev->of_node, "mclk",
+ &(sensor->mclk));
+ if (retval) {
+ dev_err(dev, "mclk missing or invalid\n");
+ return retval;
+ }
+
+ retval = of_property_read_u32(dev->of_node, "mclk_source",
+ (u32 *) &(sensor->mclk_source));
+ if (retval) {
+ dev_err(dev, "mclk_source missing or invalid\n");
+ return retval;
+ }
+
+ retval = of_property_read_u32(dev->of_node, "csi_id",
+ &(sensor->csi));
+ if (retval) {
+ dev_err(dev, "csi id missing or invalid\n");
+ return retval;
+ }
+
+ /* Set mclk rate before clk on */
+ ov5640_set_clk_rate(sensor);
+
+ retval = clk_prepare_enable(sensor->sensor_clk);
+ if (retval < 0) {
+ dev_err(dev, "%s: enable sensor clk fail\n", __func__);
+ return -EINVAL;
+ }
+
+ sensor->io_init = ov5640_reset;
+ sensor->i2c_client = client;
+
+ sensor->pix.pixelformat = V4L2_PIX_FMT_UYVY;
+ sensor->pix.width = ov5640_mode_info_data[1][0].width;
+ sensor->pix.height = ov5640_mode_info_data[1][0].height;
+ sensor->streamcap.capability = V4L2_MODE_HIGHQUALITY |
+ V4L2_CAP_TIMEPERFRAME;
+ sensor->streamcap.capturemode = 0;
+ sensor->streamcap.timeperframe.denominator = DEFAULT_FPS;
+ sensor->streamcap.timeperframe.numerator = 1;
+
+ ov5640_regulator_enable(&client->dev);
+
+ ov5640_reset(sensor);
+
+ retval = ov5640_read_reg(sensor, OV5640_CHIP_ID_HIGH_BYTE,
+ &chip_id_high);
+ if (retval < 0 || chip_id_high != 0x56) {
+ clk_disable_unprepare(sensor->sensor_clk);
+ pr_warn("camera ov5640 is not found\n");
+ return -ENODEV;
+ }
+ retval = ov5640_read_reg(sensor, OV5640_CHIP_ID_LOW_BYTE,
+ &chip_id_low);
+ if (retval < 0 || chip_id_low != 0x40) {
+ clk_disable_unprepare(sensor->sensor_clk);
+ pr_warn("camera ov5640 is not found\n");
+ return -ENODEV;
+ }
+
+ retval = init_device(sensor);
+ if (retval < 0) {
+ clk_disable_unprepare(sensor->sensor_clk);
+ pr_warn("camera ov5640 init fail\n");
+ return -ENODEV;
+ }
+
+ sd = &sensor->subdev;
+ v4l2_i2c_subdev_init(sd, client, &ov5640_subdev_ops);
+
+ sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+ sd->entity.function = MEDIA_ENT_F_CAM_SENSOR;
+ sensor->pads[OV5640_SENS_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
+
+ retval = media_entity_pads_init(&sd->entity, OV5640_SENS_PADS_NUM,
+ sensor->pads);
+ sd->entity.ops = &ov5640_sd_media_ops;
+ if (retval < 0)
+ return retval;
+
+ retval = v4l2_async_register_subdev(sd);
+ if (retval < 0) {
+ dev_err(&client->dev,
+ "%s--Async register failed, ret=%d\n", __func__, retval);
+ media_entity_cleanup(&sd->entity);
+ }
+
+ clk_disable_unprepare(sensor->sensor_clk);
+
+ pr_info("%s camera mipi ov5640, is found\n", __func__);
+ return retval;
+}
+
+/*!
+ * ov5640 I2C detach function
+ *
+ * @param client struct i2c_client *
+ * @return Error code indicating success or failure
+ */
+static int ov5640_remove(struct i2c_client *client)
+{
+ struct v4l2_subdev *sd = i2c_get_clientdata(client);
+ struct ov5640 *sensor = to_ov5640(client);
+
+ v4l2_async_unregister_subdev(sd);
+
+ clk_unprepare(sensor->sensor_clk);
+
+ ov5640_power_down(sensor, 1);
+
+ if (analog_regulator)
+ regulator_disable(analog_regulator);
+
+ if (core_regulator)
+ regulator_disable(core_regulator);
+
+ if (io_regulator)
+ regulator_disable(io_regulator);
+
+ return 0;
+}
+
+module_i2c_driver(ov5640_i2c_driver);
+
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("OV5640 Camera Driver");
+MODULE_LICENSE("GPL");
+MODULE_VERSION("3.0");
+MODULE_ALIAS("MIPI CSI");
diff --git a/drivers/media/platform/imx8/ov5640_v3.c b/drivers/media/platform/imx8/ov5640_v3.c
new file mode 100644
index 000000000000..45d2579c5f50
--- /dev/null
+++ b/drivers/media/platform/imx8/ov5640_v3.c
@@ -0,0 +1,1741 @@
+/*
+ * Copyright (C) 2012-2015 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2018 NXP
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/i2c.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/of_gpio.h>
+#include <linux/pinctrl/consumer.h>
+#include <linux/regulator/consumer.h>
+#include <linux/v4l2-mediabus.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-ctrls.h>
+
+#define OV5640_VOLTAGE_ANALOG 2800000
+#define OV5640_VOLTAGE_DIGITAL_CORE 1500000
+#define OV5640_VOLTAGE_DIGITAL_IO 1800000
+
+#define MIN_FPS 15
+#define MAX_FPS 30
+#define DEFAULT_FPS 30
+
+#define OV5640_XCLK_MIN 6000000
+#define OV5640_XCLK_MAX 24000000
+
+#define OV5640_CHIP_ID_HIGH_BYTE 0x300A
+#define OV5640_CHIP_ID_LOW_BYTE 0x300B
+
+#define OV5640_SENS_PAD_SOURCE 0
+#define OV5640_SENS_PADS_NUM 1
+
+enum ov5640_mode {
+ ov5640_mode_MIN = 0,
+ ov5640_mode_1080P_1920_1080 = 0,
+ ov5640_mode_720P_1280_720 = 1,
+ ov5640_mode_XGA_1024_768 = 2,
+ ov5640_mode_PAL_720_576 = 3,
+ ov5640_mode_NTSC_720_480 = 4,
+ ov5640_mode_VGA_640_480 = 5,
+ ov5640_mode_QVGA_320_240 = 6,
+ ov5640_mode_QCIF_176_144 = 7,
+ ov5640_mode_QSXGA_2592_1944 = 8,
+ ov5640_mode_MAX = 8
+
+};
+
+enum ov5640_frame_rate {
+ ov5640_15_fps,
+ ov5640_30_fps
+};
+
+static int ov5640_framerates[] = {
+ [ov5640_15_fps] = 15,
+ [ov5640_30_fps] = 30,
+};
+
+struct ov5640_datafmt {
+ u32 code;
+ enum v4l2_colorspace colorspace;
+};
+
+struct reg_value {
+ u16 u16RegAddr;
+ u8 u8Val;
+ u8 u8Mask;
+ u32 u32Delay_ms;
+};
+
+struct ov5640_mode_info {
+ enum ov5640_mode mode;
+ u32 width;
+ u32 height;
+ struct reg_value *init_data_ptr;
+ u32 init_data_size;
+};
+
+struct ov5640_pll_info {
+ enum ov5640_mode mode;
+ struct reg_value *init_data_ptr;
+ u32 init_data_size;
+};
+
+struct ov5640_hs_info {
+ u32 width;
+ u32 height;
+ u32 frame_rate;
+ u32 val;
+};
+
+struct ov5640 {
+ struct v4l2_subdev subdev;
+ struct i2c_client *i2c_client;
+ struct v4l2_pix_format pix;
+ const struct ov5640_datafmt *fmt;
+ struct v4l2_captureparm streamcap;
+ struct media_pad pads[OV5640_SENS_PADS_NUM];
+ bool on;
+
+ /* control settings */
+ int brightness;
+ int hue;
+ int contrast;
+ int saturation;
+ int red;
+ int green;
+ int blue;
+ int ae_mode;
+
+ u32 mclk;
+ u8 mclk_source;
+ struct clk *sensor_clk;
+ int csi;
+
+ void (*io_init)(void);
+};
+
+/*!
+ * Maintains the information on the current state of the sesor.
+ */
+static struct ov5640 ov5640_data;
+static int pwn_gpio, rst_gpio;
+
+static struct reg_value ov5640_global_init_setting[] = {
+ {0x3008, 0x42, 0, 0},
+
+ /* System setting.0*/
+ {0x3103, 0x03, 0, 0},
+ {0x3000, 0x00, 0, 0},
+ {0x3004, 0xff, 0, 0},
+ {0x3002, 0x1c, 0, 0},
+ {0x3006, 0xc3, 0, 0},
+ {0x302e, 0x08, 0, 0},
+ {0x3037, 0x13, 0, 0},
+ {0x3108, 0x01, 0, 0},
+ {0x3618, 0x00, 0, 0},
+ {0x3612, 0x29, 0, 0},
+ {0x3708, 0x64, 0, 0},
+ {0x3709, 0x52, 0, 0},
+ {0x370c, 0x03, 0, 0},
+ {0x3820, 0x41, 0, 0},
+ {0x3821, 0x07, 0, 0},
+ {0x3630, 0x36, 0, 0},
+ {0x3631, 0x0e, 0, 0},
+ {0x3632, 0xe2, 0, 0},
+ {0x3633, 0x12, 0, 0},
+ {0x3621, 0xe0, 0, 0},
+ {0x3704, 0xa0, 0, 0},
+ {0x3703, 0x5a, 0, 0},
+ {0x3715, 0x78, 0, 0},
+ {0x3717, 0x01, 0, 0},
+ {0x370b, 0x60, 0, 0},
+ {0x3705, 0x1a, 0, 0},
+ {0x3905, 0x02, 0, 0},
+ {0x3906, 0x10, 0, 0},
+ {0x3901, 0x0a, 0, 0},
+ {0x3731, 0x12, 0, 0},
+ {0x3600, 0x08, 0, 0},
+ {0x3601, 0x33, 0, 0},
+ {0x302d, 0x60, 0, 0},
+ {0x3620, 0x52, 0, 0},
+ {0x371b, 0x20, 0, 0},
+ {0x471c, 0x50, 0, 0},
+ {0x3a13, 0x43, 0, 0},
+ {0x3a18, 0x00, 0, 0},
+ {0x3a19, 0x7c, 0, 0},
+ {0x3635, 0x13, 0, 0},
+ {0x3636, 0x03, 0, 0},
+ {0x3634, 0x40, 0, 0},
+ {0x3622, 0x01, 0, 0},
+ {0x3c01, 0x00, 0, 0},
+ {0x3a00, 0x58, 0, 0},
+ {0x4001, 0x02, 0, 0},
+ {0x4004, 0x02, 0, 0},
+ {0x4005, 0x1a, 0, 0},
+ {0x5001, 0xa3, 0, 0},
+
+ /* AEC */
+ {0x3a0f, 0x30, 0, 0},
+ {0x3a10, 0x28, 0, 0},
+ {0x3a1b, 0x30, 0, 0},
+ {0x3a1e, 0x26, 0, 0},
+ {0x3a11, 0x60, 0, 0},
+ {0x3a1f, 0x14, 0, 0},
+
+ /* AWB */
+ {0x5180, 0xff, 0, 0},
+ {0x5181, 0xf2, 0, 0},
+ {0x5182, 0x00, 0, 0},
+ {0x5183, 0x14, 0, 0},
+ {0x5184, 0x25, 0, 0},
+ {0x5185, 0x24, 0, 0},
+ {0x5186, 0x09, 0, 0},
+ {0x5187, 0x09, 0, 0},
+ {0x5188, 0x09, 0, 0},
+ {0x5189, 0x88, 0, 0},
+ {0x518a, 0x54, 0, 0},
+ {0x518b, 0xee, 0, 0},
+ {0x518c, 0xb2, 0, 0},
+ {0x518d, 0x50, 0, 0},
+ {0x518e, 0x34, 0, 0},
+ {0x518f, 0x6b, 0, 0},
+ {0x5190, 0x46, 0, 0},
+ {0x5191, 0xf8, 0, 0},
+ {0x5192, 0x04, 0, 0},
+ {0x5193, 0x70, 0, 0},
+ {0x5194, 0xf0, 0, 0},
+ {0x5195, 0xf0, 0, 0},
+ {0x5196, 0x03, 0, 0},
+ {0x5197, 0x01, 0, 0},
+ {0x5198, 0x04, 0, 0},
+ {0x5199, 0x6c, 0, 0},
+ {0x519a, 0x04, 0, 0},
+ {0x519b, 0x00, 0, 0},
+ {0x519c, 0x09, 0, 0},
+ {0x519d, 0x2b, 0, 0},
+ {0x519e, 0x38, 0, 0},
+
+ /* Color Matrix */
+ {0x5381, 0x1e, 0, 0},
+ {0x5382, 0x5b, 0, 0},
+ {0x5383, 0x08, 0, 0},
+ {0x5384, 0x0a, 0, 0},
+ {0x5385, 0x7e, 0, 0},
+ {0x5386, 0x88, 0, 0},
+ {0x5387, 0x7c, 0, 0},
+ {0x5388, 0x6c, 0, 0},
+ {0x5389, 0x10, 0, 0},
+ {0x538a, 0x01, 0, 0},
+ {0x538b, 0x98, 0, 0},
+
+ /* sharp */
+ {0x5300, 0x08, 0, 0},
+ {0x5301, 0x30, 0, 0},
+ {0x5302, 0x10, 0, 0},
+ {0x5303, 0x00, 0, 0},
+ {0x5304, 0x08, 0, 0},
+ {0x5305, 0x30, 0, 0},
+ {0x5306, 0x08, 0, 0},
+ {0x5307, 0x16, 0, 0},
+ {0x5309, 0x08, 0, 0},
+ {0x530a, 0x30, 0, 0},
+ {0x530b, 0x04, 0, 0},
+ {0x530c, 0x06, 0, 0},
+
+ /* Gamma */
+ {0x5480, 0x01, 0, 0},
+ {0x5481, 0x08, 0, 0},
+ {0x5482, 0x14, 0, 0},
+ {0x5483, 0x28, 0, 0},
+ {0x5484, 0x51, 0, 0},
+ {0x5485, 0x65, 0, 0},
+ {0x5486, 0x71, 0, 0},
+ {0x5487, 0x7d, 0, 0},
+ {0x5488, 0x87, 0, 0},
+ {0x5489, 0x91, 0, 0},
+ {0x548a, 0x9a, 0, 0},
+ {0x548b, 0xaa, 0, 0},
+ {0x548c, 0xb8, 0, 0},
+ {0x548d, 0xcd, 0, 0},
+ {0x548e, 0xdd, 0, 0},
+ {0x548f, 0xea, 0, 0},
+ {0x5490, 0x1d, 0, 0},
+
+ /* UV adjust. */
+ {0x5580, 0x02, 0, 0},
+ {0x5583, 0x40, 0, 0},
+ {0x5584, 0x10, 0, 0},
+ {0x5589, 0x10, 0, 0},
+ {0x558a, 0x00, 0, 0},
+ {0x558b, 0xf8, 0, 0},
+
+ /* Lens correction0 */
+ {0x5800, 0x23, 0, 0},
+ {0x5801, 0x14, 0, 0},
+ {0x5802, 0x0f, 0, 0},
+ {0x5803, 0x0f, 0, 0},
+ {0x5804, 0x12, 0, 0},
+ {0x5805, 0x26, 0, 0},
+ {0x5806, 0x0c, 0, 0},
+ {0x5807, 0x08, 0, 0},
+ {0x5808, 0x05, 0, 0},
+ {0x5809, 0x05, 0, 0},
+ {0x580a, 0x08, 0, 0},
+ {0x580b, 0x0d, 0, 0},
+ {0x580c, 0x08, 0, 0},
+ {0x580d, 0x03, 0, 0},
+ {0x580e, 0x00, 0, 0},
+ {0x580f, 0x00, 0, 0},
+ {0x5810, 0x03, 0, 0},
+ {0x5811, 0x09, 0, 0},
+ {0x5812, 0x07, 0, 0},
+ {0x5813, 0x03, 0, 0},
+ {0x5814, 0x00, 0, 0},
+ {0x5815, 0x01, 0, 0},
+ {0x5816, 0x03, 0, 0},
+ {0x5817, 0x08, 0, 0},
+ {0x5818, 0x0d, 0, 0},
+ {0x5819, 0x08, 0, 0},
+ {0x581a, 0x05, 0, 0},
+ {0x581b, 0x06, 0, 0},
+ {0x581c, 0x08, 0, 0},
+ {0x581d, 0x0e, 0, 0},
+ {0x581e, 0x29, 0, 0},
+ {0x581f, 0x17, 0, 0},
+ {0x5820, 0x11, 0, 0},
+ {0x5821, 0x11, 0, 0},
+ {0x5822, 0x15, 0, 0},
+ {0x5823, 0x28, 0, 0},
+ {0x5824, 0x46, 0, 0},
+ {0x5825, 0x26, 0, 0},
+ {0x5826, 0x08, 0, 0},
+ {0x5827, 0x26, 0, 0},
+ {0x5828, 0x64, 0, 0},
+ {0x5829, 0x26, 0, 0},
+ {0x582a, 0x24, 0, 0},
+ {0x582b, 0x22, 0, 0},
+ {0x582c, 0x24, 0, 0},
+ {0x582d, 0x24, 0, 0},
+ {0x582e, 0x06, 0, 0},
+ {0x582f, 0x22, 0, 0},
+ {0x5830, 0x40, 0, 0},
+ {0x5831, 0x42, 0, 0},
+ {0x5832, 0x24, 0, 0},
+ {0x5833, 0x26, 0, 0},
+ {0x5834, 0x24, 0, 0},
+ {0x5835, 0x22, 0, 0},
+ {0x5836, 0x22, 0, 0},
+ {0x5837, 0x26, 0, 0},
+ {0x5838, 0x44, 0, 0},
+ {0x5839, 0x24, 0, 0},
+ {0x583a, 0x26, 0, 0},
+ {0x583b, 0x28, 0, 0},
+ {0x583c, 0x42, 0, 0},
+ {0x583d, 0xce, 0, 0},
+ {0x4740, 0x23, 0, 0},
+};
+
+static struct reg_value ov5640_init_setting_30fps_VGA[] = {
+ {0x3008, 0x42, 0, 0},
+ {0x3103, 0x03, 0, 0}, {0x3017, 0xff, 0, 0}, {0x3018, 0xff, 0, 0},
+ {0x3034, 0x1a, 0, 0}, {0x3035, 0x11, 0, 0}, {0x3036, 0x46, 0, 0},
+ {0x3037, 0x13, 0, 0}, {0x3108, 0x01, 0, 0}, {0x3630, 0x36, 0, 0},
+ {0x3631, 0x0e, 0, 0}, {0x3632, 0xe2, 0, 0}, {0x3633, 0x12, 0, 0},
+ {0x3621, 0xe0, 0, 0}, {0x3704, 0xa0, 0, 0}, {0x3703, 0x5a, 0, 0},
+ {0x3715, 0x78, 0, 0}, {0x3717, 0x01, 0, 0}, {0x370b, 0x60, 0, 0},
+ {0x3705, 0x1a, 0, 0}, {0x3905, 0x02, 0, 0}, {0x3906, 0x10, 0, 0},
+ {0x3901, 0x0a, 0, 0}, {0x3731, 0x12, 0, 0}, {0x3600, 0x08, 0, 0},
+ {0x3601, 0x33, 0, 0}, {0x302d, 0x60, 0, 0}, {0x3620, 0x52, 0, 0},
+ {0x371b, 0x20, 0, 0}, {0x471c, 0x50, 0, 0}, {0x3a13, 0x43, 0, 0},
+ {0x3a18, 0x00, 0, 0}, {0x3a19, 0xf8, 0, 0}, {0x3635, 0x13, 0, 0},
+ {0x3636, 0x03, 0, 0}, {0x3634, 0x40, 0, 0}, {0x3622, 0x01, 0, 0},
+ {0x3c01, 0x34, 0, 0}, {0x3c04, 0x28, 0, 0}, {0x3c05, 0x98, 0, 0},
+ {0x3c06, 0x00, 0, 0}, {0x3c07, 0x08, 0, 0}, {0x3c08, 0x00, 0, 0},
+ {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
+ {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0},
+ {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
+ {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0}, {0x3804, 0x0a, 0, 0},
+ {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9b, 0, 0},
+ {0x3808, 0x02, 0, 0}, {0x3809, 0x80, 0, 0}, {0x380a, 0x01, 0, 0},
+ {0x380b, 0xe0, 0, 0}, {0x380c, 0x07, 0, 0}, {0x380d, 0x68, 0, 0},
+ {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0}, {0x3810, 0x00, 0, 0},
+ {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x06, 0, 0},
+ {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0},
+ {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x03, 0, 0},
+ {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0},
+ {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0},
+ {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0},
+ {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x3000, 0x00, 0, 0},
+ {0x3002, 0x1c, 0, 0}, {0x3004, 0xff, 0, 0}, {0x3006, 0xc3, 0, 0},
+ {0x300e, 0x58, 0, 0}, {0x302e, 0x00, 0, 0}, {0x4300, 0x31, 0, 0},
+ {0x501f, 0x00, 0, 0}, {0x4713, 0x03, 0, 0}, {0x4407, 0x04, 0, 0},
+ {0x440e, 0x00, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0},
+ {0x4837, 0x22, 0, 0}, {0x3824, 0x02, 0, 0}, {0x5000, 0xa7, 0, 0},
+ {0x5001, 0xa3, 0, 0}, {0x5180, 0xff, 0, 0}, {0x5181, 0xf2, 0, 0},
+ {0x5182, 0x00, 0, 0}, {0x5183, 0x14, 0, 0}, {0x5184, 0x25, 0, 0},
+ {0x5185, 0x24, 0, 0}, {0x5186, 0x09, 0, 0}, {0x5187, 0x09, 0, 0},
+ {0x5188, 0x09, 0, 0}, {0x5189, 0x88, 0, 0}, {0x518a, 0x54, 0, 0},
+ {0x518b, 0xee, 0, 0}, {0x518c, 0xb2, 0, 0}, {0x518d, 0x50, 0, 0},
+ {0x518e, 0x34, 0, 0}, {0x518f, 0x6b, 0, 0}, {0x5190, 0x46, 0, 0},
+ {0x5191, 0xf8, 0, 0}, {0x5192, 0x04, 0, 0}, {0x5193, 0x70, 0, 0},
+ {0x5194, 0xf0, 0, 0}, {0x5195, 0xf0, 0, 0}, {0x5196, 0x03, 0, 0},
+ {0x5197, 0x01, 0, 0}, {0x5198, 0x04, 0, 0}, {0x5199, 0x6c, 0, 0},
+ {0x519a, 0x04, 0, 0}, {0x519b, 0x00, 0, 0}, {0x519c, 0x09, 0, 0},
+ {0x519d, 0x2b, 0, 0}, {0x519e, 0x38, 0, 0}, {0x5381, 0x1e, 0, 0},
+ {0x5382, 0x5b, 0, 0}, {0x5383, 0x08, 0, 0}, {0x5384, 0x0a, 0, 0},
+ {0x5385, 0x7e, 0, 0}, {0x5386, 0x88, 0, 0}, {0x5387, 0x7c, 0, 0},
+ {0x5388, 0x6c, 0, 0}, {0x5389, 0x10, 0, 0}, {0x538a, 0x01, 0, 0},
+ {0x538b, 0x98, 0, 0}, {0x5300, 0x08, 0, 0}, {0x5301, 0x30, 0, 0},
+ {0x5302, 0x10, 0, 0}, {0x5303, 0x00, 0, 0}, {0x5304, 0x08, 0, 0},
+ {0x5305, 0x30, 0, 0}, {0x5306, 0x08, 0, 0}, {0x5307, 0x16, 0, 0},
+ {0x5309, 0x08, 0, 0}, {0x530a, 0x30, 0, 0}, {0x530b, 0x04, 0, 0},
+ {0x530c, 0x06, 0, 0}, {0x5480, 0x01, 0, 0}, {0x5481, 0x08, 0, 0},
+ {0x5482, 0x14, 0, 0}, {0x5483, 0x28, 0, 0}, {0x5484, 0x51, 0, 0},
+ {0x5485, 0x65, 0, 0}, {0x5486, 0x71, 0, 0}, {0x5487, 0x7d, 0, 0},
+ {0x5488, 0x87, 0, 0}, {0x5489, 0x91, 0, 0}, {0x548a, 0x9a, 0, 0},
+ {0x548b, 0xaa, 0, 0}, {0x548c, 0xb8, 0, 0}, {0x548d, 0xcd, 0, 0},
+ {0x548e, 0xdd, 0, 0}, {0x548f, 0xea, 0, 0}, {0x5490, 0x1d, 0, 0},
+ {0x5580, 0x02, 0, 0}, {0x5583, 0x40, 0, 0}, {0x5584, 0x10, 0, 0},
+ {0x5589, 0x10, 0, 0}, {0x558a, 0x00, 0, 0}, {0x558b, 0xf8, 0, 0},
+ {0x5800, 0x23, 0, 0}, {0x5801, 0x14, 0, 0}, {0x5802, 0x0f, 0, 0},
+ {0x5803, 0x0f, 0, 0}, {0x5804, 0x12, 0, 0}, {0x5805, 0x26, 0, 0},
+ {0x5806, 0x0c, 0, 0}, {0x5807, 0x08, 0, 0}, {0x5808, 0x05, 0, 0},
+ {0x5809, 0x05, 0, 0}, {0x580a, 0x08, 0, 0}, {0x580b, 0x0d, 0, 0},
+ {0x580c, 0x08, 0, 0}, {0x580d, 0x03, 0, 0}, {0x580e, 0x00, 0, 0},
+ {0x580f, 0x00, 0, 0}, {0x5810, 0x03, 0, 0}, {0x5811, 0x09, 0, 0},
+ {0x5812, 0x07, 0, 0}, {0x5813, 0x03, 0, 0}, {0x5814, 0x00, 0, 0},
+ {0x5815, 0x01, 0, 0}, {0x5816, 0x03, 0, 0}, {0x5817, 0x08, 0, 0},
+ {0x5818, 0x0d, 0, 0}, {0x5819, 0x08, 0, 0}, {0x581a, 0x05, 0, 0},
+ {0x581b, 0x06, 0, 0}, {0x581c, 0x08, 0, 0}, {0x581d, 0x0e, 0, 0},
+ {0x581e, 0x29, 0, 0}, {0x581f, 0x17, 0, 0}, {0x5820, 0x11, 0, 0},
+ {0x5821, 0x11, 0, 0}, {0x5822, 0x15, 0, 0}, {0x5823, 0x28, 0, 0},
+ {0x5824, 0x46, 0, 0}, {0x5825, 0x26, 0, 0}, {0x5826, 0x08, 0, 0},
+ {0x5827, 0x26, 0, 0}, {0x5828, 0x64, 0, 0}, {0x5829, 0x26, 0, 0},
+ {0x582a, 0x24, 0, 0}, {0x582b, 0x22, 0, 0}, {0x582c, 0x24, 0, 0},
+ {0x582d, 0x24, 0, 0}, {0x582e, 0x06, 0, 0}, {0x582f, 0x22, 0, 0},
+ {0x5830, 0x40, 0, 0}, {0x5831, 0x42, 0, 0}, {0x5832, 0x24, 0, 0},
+ {0x5833, 0x26, 0, 0}, {0x5834, 0x24, 0, 0}, {0x5835, 0x22, 0, 0},
+ {0x5836, 0x22, 0, 0}, {0x5837, 0x26, 0, 0}, {0x5838, 0x44, 0, 0},
+ {0x5839, 0x24, 0, 0}, {0x583a, 0x26, 0, 0}, {0x583b, 0x28, 0, 0},
+ {0x583c, 0x42, 0, 0}, {0x583d, 0xce, 0, 0}, {0x5025, 0x00, 0, 0},
+ {0x3a0f, 0x30, 0, 0}, {0x3a10, 0x28, 0, 0}, {0x3a1b, 0x30, 0, 0},
+ {0x3a1e, 0x26, 0, 0}, {0x3a11, 0x60, 0, 0}, {0x3a1f, 0x14, 0, 0},
+ {0x3008, 0x02, 0, 0}, {0x3034, 0x1a, 0, 0}, {0x3035, 0x11, 0, 0},
+ {0x3036, 0x46, 0, 0}, {0x3037, 0x13, 0, 0},
+};
+
+static struct reg_value ov5640_setting_30fps_VGA_640_480[] = {
+ {0x3c07, 0x08, 0, 0}, {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0},
+ {0x3814, 0x31, 0, 0}, {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0},
+ {0x3801, 0x00, 0, 0}, {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0},
+ {0x3804, 0x0a, 0, 0}, {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0},
+ {0x3807, 0x9b, 0, 0}, {0x3808, 0x02, 0, 0}, {0x3809, 0x80, 0, 0},
+ {0x380a, 0x01, 0, 0}, {0x380b, 0xe0, 0, 0}, {0x380c, 0x07, 0, 0},
+ {0x380d, 0x68, 0, 0}, {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0},
+ {0x3813, 0x06, 0, 0}, {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0},
+ {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x0b, 0, 0},
+ {0x3a03, 0x88, 0, 0}, {0x3a14, 0x0b, 0, 0}, {0x3a15, 0x88, 0, 0},
+ {0x4004, 0x02, 0, 0}, {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0},
+ {0x4713, 0x03, 0, 0}, {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0},
+ {0x460c, 0x22, 0, 0}, {0x4837, 0x22, 0, 0}, {0x3824, 0x02, 0, 0},
+ {0x5001, 0xa3, 0, 0}, {0x3034, 0x1a, 0, 0}, {0x3035, 0x11, 0, 0},
+ {0x3036, 0x46, 0, 0}, {0x3037, 0x13, 0, 0}, {0x3503, 0x00, 0, 0},
+};
+
+static struct reg_value ov5640_setting_15fps_VGA_640_480[] = {
+ {0x3c07, 0x08, 0, 0}, {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0},
+ {0x3814, 0x31, 0, 0}, {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0},
+ {0x3801, 0x00, 0, 0}, {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0},
+ {0x3804, 0x0a, 0, 0}, {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0},
+ {0x3807, 0x9b, 0, 0}, {0x3808, 0x02, 0, 0}, {0x3809, 0x80, 0, 0},
+ {0x380a, 0x01, 0, 0}, {0x380b, 0xe0, 0, 0}, {0x380c, 0x07, 0, 0},
+ {0x380d, 0x68, 0, 0}, {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0},
+ {0x3813, 0x06, 0, 0}, {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0},
+ {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x0b, 0, 0},
+ {0x3a03, 0x88, 0, 0}, {0x3a14, 0x0b, 0, 0}, {0x3a15, 0x88, 0, 0},
+ {0x4004, 0x02, 0, 0}, {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0},
+ {0x4713, 0x03, 0, 0}, {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0},
+ {0x460c, 0x22, 0, 0}, {0x4837, 0x22, 0, 0}, {0x3824, 0x02, 0, 0},
+ {0x5001, 0xa3, 0, 0}, {0x3034, 0x1a, 0, 0}, {0x3035, 0x21, 0, 0},
+ {0x3036, 0x46, 0, 0}, {0x3037, 0x13, 0, 0}, {0x3503, 0x00, 0, 0},
+};
+
+static struct reg_value ov5640_setting_30fps_QVGA_320_240[] = {
+ {0x3c07, 0x08, 0, 0}, {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0},
+ {0x3814, 0x31, 0, 0}, {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0},
+ {0x3801, 0x00, 0, 0}, {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0},
+ {0x3804, 0x0a, 0, 0}, {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0},
+ {0x3807, 0x9b, 0, 0}, {0x3808, 0x01, 0, 0}, {0x3809, 0x40, 0, 0},
+ {0x380a, 0x00, 0, 0}, {0x380b, 0xf0, 0, 0}, {0x380c, 0x07, 0, 0},
+ {0x380d, 0x68, 0, 0}, {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0},
+ {0x3813, 0x06, 0, 0}, {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0},
+ {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x0b, 0, 0},
+ {0x3a03, 0x88, 0, 0}, {0x3a14, 0x0b, 0, 0}, {0x3a15, 0x88, 0, 0},
+ {0x4004, 0x02, 0, 0}, {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0},
+ {0x4713, 0x03, 0, 0}, {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0},
+ {0x460c, 0x22, 0, 0}, {0x4837, 0x22, 0, 0}, {0x3824, 0x02, 0, 0},
+ {0x5001, 0xa3, 0, 0}, {0x3034, 0x1a, 0, 0}, {0x3035, 0x11, 0, 0},
+ {0x3036, 0x46, 0, 0}, {0x3037, 0x13, 0, 0},
+};
+
+static struct reg_value ov5640_setting_15fps_QVGA_320_240[] = {
+ {0x3c07, 0x08, 0, 0}, {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0},
+ {0x3814, 0x31, 0, 0}, {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0},
+ {0x3801, 0x00, 0, 0}, {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0},
+ {0x3804, 0x0a, 0, 0}, {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0},
+ {0x3807, 0x9b, 0, 0}, {0x3808, 0x01, 0, 0}, {0x3809, 0x40, 0, 0},
+ {0x380a, 0x00, 0, 0}, {0x380b, 0xf0, 0, 0}, {0x380c, 0x07, 0, 0},
+ {0x380d, 0x68, 0, 0}, {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0},
+ {0x3813, 0x06, 0, 0}, {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0},
+ {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x0b, 0, 0},
+ {0x3a03, 0x88, 0, 0}, {0x3a14, 0x0b, 0, 0}, {0x3a15, 0x88, 0, 0},
+ {0x4004, 0x02, 0, 0}, {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0},
+ {0x4713, 0x03, 0, 0}, {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0},
+ {0x460c, 0x22, 0, 0}, {0x4837, 0x22, 0, 0}, {0x3824, 0x02, 0, 0},
+ {0x5001, 0xa3, 0, 0}, {0x3034, 0x1a, 0, 0}, {0x3035, 0x21, 0, 0},
+ {0x3036, 0x46, 0, 0}, {0x3037, 0x13, 0, 0},
+};
+
+static struct reg_value ov5640_setting_30fps_NTSC_720_480[] = {
+ {0x3c07, 0x08, 0, 0}, {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0},
+ {0x3814, 0x31, 0, 0}, {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0},
+ {0x3801, 0x00, 0, 0}, {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0},
+ {0x3804, 0x0a, 0, 0}, {0x3805, 0x3f, 0, 0}, {0x3806, 0x06, 0, 0},
+ {0x3807, 0xd4, 0, 0}, {0x3808, 0x02, 0, 0}, {0x3809, 0xd0, 0, 0},
+ {0x380a, 0x01, 0, 0}, {0x380b, 0xe0, 0, 0}, {0x380c, 0x07, 0, 0},
+ {0x380d, 0x68, 0, 0}, {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0},
+ {0x3813, 0x06, 0, 0}, {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0},
+ {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x0b, 0, 0},
+ {0x3a03, 0x88, 0, 0}, {0x3a14, 0x0b, 0, 0}, {0x3a15, 0x88, 0, 0},
+ {0x4004, 0x02, 0, 0}, {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0},
+ {0x4713, 0x03, 0, 0}, {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0},
+ {0x460c, 0x22, 0, 0}, {0x4837, 0x22, 0, 0}, {0x3824, 0x02, 0, 0},
+ {0x5001, 0xa3, 0, 0}, {0x3034, 0x1a, 0, 0}, {0x3035, 0x11, 0, 0},
+ {0x3036, 0x46, 0, 0}, {0x3037, 0x13, 0, 0},
+};
+
+static struct reg_value ov5640_setting_15fps_NTSC_720_480[] = {
+ {0x3c07, 0x08, 0, 0}, {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0},
+ {0x3814, 0x31, 0, 0}, {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0},
+ {0x3801, 0x00, 0, 0}, {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0},
+ {0x3804, 0x0a, 0, 0}, {0x3805, 0x3f, 0, 0}, {0x3806, 0x06, 0, 0},
+ {0x3807, 0xd4, 0, 0}, {0x3808, 0x02, 0, 0}, {0x3809, 0xd0, 0, 0},
+ {0x380a, 0x01, 0, 0}, {0x380b, 0xe0, 0, 0}, {0x380c, 0x07, 0, 0},
+ {0x380d, 0x68, 0, 0}, {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0},
+ {0x3813, 0x06, 0, 0}, {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0},
+ {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x0b, 0, 0},
+ {0x3a03, 0x88, 0, 0}, {0x3a14, 0x0b, 0, 0}, {0x3a15, 0x88, 0, 0},
+ {0x4004, 0x02, 0, 0}, {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0},
+ {0x4713, 0x03, 0, 0}, {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0},
+ {0x460c, 0x22, 0, 0}, {0x4837, 0x22, 0, 0}, {0x3824, 0x02, 0, 0},
+ {0x5001, 0xa3, 0, 0}, {0x3034, 0x1a, 0, 0}, {0x3035, 0x21, 0, 0},
+ {0x3036, 0x46, 0, 0}, {0x3037, 0x13, 0, 0},
+};
+
+static struct reg_value ov5640_setting_30fps_PAL_720_576[] = {
+ {0x3c07, 0x08, 0, 0}, {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0},
+ {0x3814, 0x31, 0, 0}, {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0},
+ {0x3801, 0x60, 0, 0}, {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0},
+ {0x3804, 0x09, 0, 0}, {0x3805, 0x7e, 0, 0}, {0x3806, 0x07, 0, 0},
+ {0x3807, 0x9b, 0, 0}, {0x3808, 0x02, 0, 0}, {0x3809, 0xd0, 0, 0},
+ {0x380a, 0x02, 0, 0}, {0x380b, 0x40, 0, 0}, {0x380c, 0x07, 0, 0},
+ {0x380d, 0x68, 0, 0}, {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0},
+ {0x3813, 0x06, 0, 0}, {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0},
+ {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x0b, 0, 0},
+ {0x3a03, 0x88, 0, 0}, {0x3a14, 0x0b, 0, 0}, {0x3a15, 0x88, 0, 0},
+ {0x4004, 0x02, 0, 0}, {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0},
+ {0x4713, 0x03, 0, 0}, {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0},
+ {0x460c, 0x22, 0, 0}, {0x4837, 0x22, 0, 0}, {0x3824, 0x02, 0, 0},
+ {0x5001, 0xa3, 0, 0}, {0x3034, 0x1a, 0, 0}, {0x3035, 0x11, 0, 0},
+ {0x3036, 0x46, 0, 0}, {0x3037, 0x13, 0, 0},
+};
+
+static struct reg_value ov5640_setting_15fps_PAL_720_576[] = {
+ {0x3c07, 0x08, 0, 0}, {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0},
+ {0x3814, 0x31, 0, 0}, {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0},
+ {0x3801, 0x60, 0, 0}, {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0},
+ {0x3804, 0x09, 0, 0}, {0x3805, 0x7e, 0, 0}, {0x3806, 0x07, 0, 0},
+ {0x3807, 0x9b, 0, 0}, {0x3808, 0x02, 0, 0}, {0x3809, 0xd0, 0, 0},
+ {0x380a, 0x02, 0, 0}, {0x380b, 0x40, 0, 0}, {0x380c, 0x07, 0, 0},
+ {0x380d, 0x68, 0, 0}, {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0},
+ {0x3813, 0x06, 0, 0}, {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0},
+ {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x0b, 0, 0},
+ {0x3a03, 0x88, 0, 0}, {0x3a14, 0x0b, 0, 0}, {0x3a15, 0x88, 0, 0},
+ {0x4004, 0x02, 0, 0}, {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0},
+ {0x4713, 0x03, 0, 0}, {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0},
+ {0x460c, 0x22, 0, 0}, {0x4837, 0x22, 0, 0}, {0x3824, 0x02, 0, 0},
+ {0x5001, 0xa3, 0, 0}, {0x3034, 0x1a, 0, 0}, {0x3035, 0x21, 0, 0},
+ {0x3036, 0x46, 0, 0}, {0x3037, 0x13, 0, 0},
+};
+
+static struct reg_value ov5640_setting_30fps_720P_1280_720[] = {
+ {0x3035, 0x21, 0, 0}, {0x3036, 0x69, 0, 0}, {0x3c07, 0x07, 0, 0},
+ {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0},
+ {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
+ {0x3802, 0x00, 0, 0}, {0x3803, 0xfa, 0, 0}, {0x3804, 0x0a, 0, 0},
+ {0x3805, 0x3f, 0, 0}, {0x3806, 0x06, 0, 0}, {0x3807, 0xa9, 0, 0},
+ {0x3808, 0x05, 0, 0}, {0x3809, 0x00, 0, 0}, {0x380a, 0x02, 0, 0},
+ {0x380b, 0xd0, 0, 0}, {0x380c, 0x07, 0, 0}, {0x380d, 0x64, 0, 0},
+ {0x380e, 0x02, 0, 0}, {0x380f, 0xe4, 0, 0}, {0x3813, 0x04, 0, 0},
+ {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3709, 0x52, 0, 0},
+ {0x370c, 0x03, 0, 0}, {0x3a02, 0x02, 0, 0}, {0x3a03, 0xe0, 0, 0},
+ {0x3a14, 0x02, 0, 0}, {0x3a15, 0xe0, 0, 0}, {0x4004, 0x02, 0, 0},
+ {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0}, {0x4713, 0x03, 0, 0},
+ {0x4407, 0x04, 0, 0}, {0x460b, 0x37, 0, 0}, {0x460c, 0x20, 0, 0},
+ {0x4837, 0x16, 0, 0}, {0x3824, 0x04, 0, 0}, {0x5001, 0x83, 0, 0},
+ {0x3503, 0x00, 0, 0},
+};
+
+static struct reg_value ov5640_setting_15fps_720P_1280_720[] = {
+ {0x3035, 0x41, 0, 0}, {0x3036, 0x69, 0, 0}, {0x3c07, 0x07, 0, 0},
+ {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0},
+ {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
+ {0x3802, 0x00, 0, 0}, {0x3803, 0xfa, 0, 0}, {0x3804, 0x0a, 0, 0},
+ {0x3805, 0x3f, 0, 0}, {0x3806, 0x06, 0, 0}, {0x3807, 0xa9, 0, 0},
+ {0x3808, 0x05, 0, 0}, {0x3809, 0x00, 0, 0}, {0x380a, 0x02, 0, 0},
+ {0x380b, 0xd0, 0, 0}, {0x380c, 0x07, 0, 0}, {0x380d, 0x64, 0, 0},
+ {0x380e, 0x02, 0, 0}, {0x380f, 0xe4, 0, 0}, {0x3813, 0x04, 0, 0},
+ {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3709, 0x52, 0, 0},
+ {0x370c, 0x03, 0, 0}, {0x3a02, 0x02, 0, 0}, {0x3a03, 0xe0, 0, 0},
+ {0x3a14, 0x02, 0, 0}, {0x3a15, 0xe0, 0, 0}, {0x4004, 0x02, 0, 0},
+ {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0}, {0x4713, 0x03, 0, 0},
+ {0x4407, 0x04, 0, 0}, {0x460b, 0x37, 0, 0}, {0x460c, 0x20, 0, 0},
+ {0x4837, 0x16, 0, 0}, {0x3824, 0x04, 0, 0}, {0x5001, 0x83, 0, 0},
+ {0x3503, 0x00, 0, 0},
+};
+
+static struct reg_value ov5640_setting_30fps_QCIF_176_144[] = {
+ {0x3c07, 0x08, 0, 0}, {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0},
+ {0x3814, 0x31, 0, 0}, {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0},
+ {0x3801, 0x00, 0, 0}, {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0},
+ {0x3804, 0x0a, 0, 0}, {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0},
+ {0x3807, 0x9b, 0, 0}, {0x3808, 0x00, 0, 0}, {0x3809, 0xb0, 0, 0},
+ {0x380a, 0x00, 0, 0}, {0x380b, 0x90, 0, 0}, {0x380c, 0x07, 0, 0},
+ {0x380d, 0x68, 0, 0}, {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0},
+ {0x3813, 0x06, 0, 0}, {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0},
+ {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x0b, 0, 0},
+ {0x3a03, 0x88, 0, 0}, {0x3a14, 0x0b, 0, 0}, {0x3a15, 0x88, 0, 0},
+ {0x4004, 0x02, 0, 0}, {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0},
+ {0x4713, 0x03, 0, 0}, {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0},
+ {0x460c, 0x22, 0, 0}, {0x4837, 0x22, 0, 0}, {0x3824, 0x02, 0, 0},
+ {0x5001, 0xa3, 0, 0}, {0x3034, 0x1a, 0, 0}, {0x3035, 0x11, 0, 0},
+ {0x3036, 0x46, 0, 0}, {0x3037, 0x13, 0, 0},
+};
+
+static struct reg_value ov5640_setting_15fps_QCIF_176_144[] = {
+ {0x3c07, 0x08, 0, 0}, {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0},
+ {0x3814, 0x31, 0, 0}, {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0},
+ {0x3801, 0x00, 0, 0}, {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0},
+ {0x3804, 0x0a, 0, 0}, {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0},
+ {0x3807, 0x9b, 0, 0}, {0x3808, 0x00, 0, 0}, {0x3809, 0xb0, 0, 0},
+ {0x380a, 0x00, 0, 0}, {0x380b, 0x90, 0, 0}, {0x380c, 0x07, 0, 0},
+ {0x380d, 0x68, 0, 0}, {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0},
+ {0x3813, 0x06, 0, 0}, {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0},
+ {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x0b, 0, 0},
+ {0x3a03, 0x88, 0, 0}, {0x3a14, 0x0b, 0, 0}, {0x3a15, 0x88, 0, 0},
+ {0x4004, 0x02, 0, 0}, {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0},
+ {0x4713, 0x03, 0, 0}, {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0},
+ {0x460c, 0x22, 0, 0}, {0x4837, 0x22, 0, 0}, {0x3824, 0x02, 0, 0},
+ {0x5001, 0xa3, 0, 0}, {0x3034, 0x1a, 0, 0}, {0x3035, 0x21, 0, 0},
+ {0x3036, 0x46, 0, 0}, {0x3037, 0x13, 0, 0},
+};
+
+static struct reg_value ov5640_setting_30fps_XGA_1024_768[] = {
+ {0x3c07, 0x08, 0, 0}, {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0},
+ {0x3814, 0x31, 0, 0}, {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0},
+ {0x3801, 0x00, 0, 0}, {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0},
+ {0x3804, 0x0a, 0, 0}, {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0},
+ {0x3807, 0x9b, 0, 0}, {0x3808, 0x04, 0, 0}, {0x3809, 0x00, 0, 0},
+ {0x380a, 0x03, 0, 0}, {0x380b, 0x00, 0, 0}, {0x380c, 0x07, 0, 0},
+ {0x380d, 0x68, 0, 0}, {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0},
+ {0x3813, 0x06, 0, 0}, {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0},
+ {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x0b, 0, 0},
+ {0x3a03, 0x88, 0, 0}, {0x3a14, 0x0b, 0, 0}, {0x3a15, 0x88, 0, 0},
+ {0x4004, 0x02, 0, 0}, {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0},
+ {0x4713, 0x03, 0, 0}, {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0},
+ {0x460c, 0x20, 0, 0}, {0x4837, 0x22, 0, 0}, {0x3824, 0x01, 0, 0},
+ {0x5001, 0xa3, 0, 0}, {0x3034, 0x1a, 0, 0}, {0x3035, 0x21, 0, 0},
+ {0x3036, 0x69, 0, 0}, {0x3037, 0x13, 0, 0},
+};
+
+static struct reg_value ov5640_setting_15fps_XGA_1024_768[] = {
+ {0x3c07, 0x08, 0, 0}, {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0},
+ {0x3814, 0x31, 0, 0}, {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0},
+ {0x3801, 0x00, 0, 0}, {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0},
+ {0x3804, 0x0a, 0, 0}, {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0},
+ {0x3807, 0x9b, 0, 0}, {0x3808, 0x04, 0, 0}, {0x3809, 0x00, 0, 0},
+ {0x380a, 0x03, 0, 0}, {0x380b, 0x00, 0, 0}, {0x380c, 0x07, 0, 0},
+ {0x380d, 0x68, 0, 0}, {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0},
+ {0x3813, 0x06, 0, 0}, {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0},
+ {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x0b, 0, 0},
+ {0x3a03, 0x88, 0, 0}, {0x3a14, 0x0b, 0, 0}, {0x3a15, 0x88, 0, 0},
+ {0x4004, 0x02, 0, 0}, {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0},
+ {0x4713, 0x03, 0, 0}, {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0},
+ {0x460c, 0x20, 0, 0}, {0x4837, 0x22, 0, 0}, {0x3824, 0x01, 0, 0},
+ {0x5001, 0xa3, 0, 0}, {0x3034, 0x1a, 0, 0}, {0x3035, 0x21, 0, 0},
+ {0x3036, 0x46, 0, 0}, {0x3037, 0x13, 0, 0},
+};
+
+static struct reg_value ov5640_setting_15fps_1080P_1920_1080[] = {
+ {0x3c07, 0x07, 0, 0}, {0x3820, 0x40, 0, 0}, {0x3821, 0x06, 0, 0},
+ {0x3814, 0x11, 0, 0}, {0x3815, 0x11, 0, 0}, {0x3800, 0x00, 0, 0},
+ {0x3801, 0x00, 0, 0}, {0x3802, 0x00, 0, 0}, {0x3803, 0xee, 0, 0},
+ {0x3804, 0x0a, 0, 0}, {0x3805, 0x3f, 0, 0}, {0x3806, 0x05, 0, 0},
+ {0x3807, 0xc3, 0, 0}, {0x3808, 0x07, 0, 0}, {0x3809, 0x80, 0, 0},
+ {0x380a, 0x04, 0, 0}, {0x380b, 0x38, 0, 0}, {0x380c, 0x0b, 0, 0},
+ {0x380d, 0x1c, 0, 0}, {0x380e, 0x07, 0, 0}, {0x380f, 0xb0, 0, 0},
+ {0x3813, 0x04, 0, 0}, {0x3618, 0x04, 0, 0}, {0x3612, 0x2b, 0, 0},
+ {0x3709, 0x12, 0, 0}, {0x370c, 0x00, 0, 0}, {0x3a02, 0x07, 0, 0},
+ {0x3a03, 0xae, 0, 0}, {0x3a14, 0x07, 0, 0}, {0x3a15, 0xae, 0, 0},
+ {0x4004, 0x06, 0, 0}, {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0},
+ {0x4713, 0x02, 0, 0}, {0x4407, 0x0c, 0, 0}, {0x460b, 0x37, 0, 0},
+ {0x460c, 0x20, 0, 0}, {0x4837, 0x16, 0, 0}, {0x3824, 0x04, 0, 0},
+ {0x5001, 0x83, 0, 0}, {0x3034, 0x1a, 0, 0}, {0x3035, 0x21, 0, 0},
+ {0x3036, 0x69, 0, 0}, {0x3037, 0x13, 0, 0},
+};
+
+static struct reg_value ov5640_setting_15fps_QSXGA_2592_1944[] = {
+ {0x3c07, 0x07, 0, 0}, {0x3820, 0x40, 0, 0}, {0x3821, 0x06, 0, 0},
+ {0x3814, 0x11, 0, 0}, {0x3815, 0x11, 0, 0}, {0x3800, 0x00, 0, 0},
+ {0x3801, 0x00, 0, 0}, {0x3802, 0x00, 0, 0}, {0x3803, 0x00, 0, 0},
+ {0x3804, 0x0a, 0, 0}, {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0},
+ {0x3807, 0x9f, 0, 0}, {0x3808, 0x0a, 0, 0}, {0x3809, 0x20, 0, 0},
+ {0x380a, 0x07, 0, 0}, {0x380b, 0x98, 0, 0}, {0x380c, 0x0b, 0, 0},
+ {0x380d, 0x1c, 0, 0}, {0x380e, 0x07, 0, 0}, {0x380f, 0xb0, 0, 0},
+ {0x3813, 0x04, 0, 0}, {0x3618, 0x04, 0, 0}, {0x3612, 0x2b, 0, 0},
+ {0x3709, 0x12, 0, 0}, {0x370c, 0x00, 0, 0}, {0x3a02, 0x07, 0, 0},
+ {0x3a03, 0xae, 0, 0}, {0x3a14, 0x07, 0, 0}, {0x3a15, 0xae, 0, 0},
+ {0x4004, 0x06, 0, 0}, {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0},
+ {0x4713, 0x02, 0, 0}, {0x4407, 0x0c, 0, 0}, {0x460b, 0x37, 0, 0},
+ {0x460c, 0x20, 0, 0}, {0x4837, 0x2c, 0, 0}, {0x3824, 0x01, 0, 0},
+ {0x5001, 0x83, 0, 0}, {0x3034, 0x1a, 0, 0}, {0x3035, 0x21, 0, 0},
+ {0x3036, 0x69, 0, 0}, {0x3037, 0x13, 0, 0},
+};
+
+static struct ov5640_mode_info ov5640_mode_info_data[2][ov5640_mode_MAX + 1] = {
+ {
+ {ov5640_mode_1080P_1920_1080, 1920, 1080,
+ ov5640_setting_15fps_1080P_1920_1080,
+ ARRAY_SIZE(ov5640_setting_15fps_1080P_1920_1080)},
+
+ {ov5640_mode_720P_1280_720, 1280, 720,
+ ov5640_setting_15fps_720P_1280_720,
+ ARRAY_SIZE(ov5640_setting_15fps_720P_1280_720)},
+
+ {ov5640_mode_XGA_1024_768, 1024, 768,
+ ov5640_setting_15fps_XGA_1024_768,
+ ARRAY_SIZE(ov5640_setting_15fps_XGA_1024_768)},
+
+ {ov5640_mode_PAL_720_576, 720, 576,
+ ov5640_setting_15fps_PAL_720_576,
+ ARRAY_SIZE(ov5640_setting_15fps_PAL_720_576)},
+
+ {ov5640_mode_NTSC_720_480, 720, 480,
+ ov5640_setting_15fps_NTSC_720_480,
+ ARRAY_SIZE(ov5640_setting_15fps_NTSC_720_480)},
+
+ {ov5640_mode_VGA_640_480, 640, 480,
+ ov5640_setting_15fps_VGA_640_480,
+ ARRAY_SIZE(ov5640_setting_15fps_VGA_640_480)},
+
+ {ov5640_mode_QVGA_320_240, 320, 240,
+ ov5640_setting_15fps_QVGA_320_240,
+ ARRAY_SIZE(ov5640_setting_15fps_QVGA_320_240)},
+
+ {ov5640_mode_QCIF_176_144, 176, 144,
+ ov5640_setting_15fps_QCIF_176_144,
+ ARRAY_SIZE(ov5640_setting_15fps_QCIF_176_144)},
+
+ {ov5640_mode_QSXGA_2592_1944, 2592, 1944,
+ ov5640_setting_15fps_QSXGA_2592_1944,
+ ARRAY_SIZE(ov5640_setting_15fps_QSXGA_2592_1944)},
+ },
+ {
+ {ov5640_mode_1080P_1920_1080, 0, 0, NULL, 0},
+
+ {ov5640_mode_720P_1280_720, 1280, 720,
+ ov5640_setting_30fps_720P_1280_720,
+ ARRAY_SIZE(ov5640_setting_30fps_720P_1280_720)},
+
+ {ov5640_mode_XGA_1024_768, 1024, 768,
+ ov5640_setting_30fps_XGA_1024_768,
+ ARRAY_SIZE(ov5640_setting_30fps_XGA_1024_768)},
+
+ {ov5640_mode_PAL_720_576, 720, 576,
+ ov5640_setting_30fps_PAL_720_576,
+ ARRAY_SIZE(ov5640_setting_30fps_PAL_720_576)},
+
+ {ov5640_mode_NTSC_720_480, 720, 480,
+ ov5640_setting_30fps_NTSC_720_480,
+ ARRAY_SIZE(ov5640_setting_30fps_NTSC_720_480)},
+
+ {ov5640_mode_VGA_640_480, 640, 480,
+ ov5640_setting_30fps_VGA_640_480,
+ ARRAY_SIZE(ov5640_setting_30fps_VGA_640_480)},
+
+ {ov5640_mode_QVGA_320_240, 320, 240,
+ ov5640_setting_30fps_QVGA_320_240,
+ ARRAY_SIZE(ov5640_setting_30fps_QVGA_320_240)},
+
+ {ov5640_mode_QCIF_176_144, 176, 144,
+ ov5640_setting_30fps_QCIF_176_144,
+ ARRAY_SIZE(ov5640_setting_30fps_QCIF_176_144)},
+
+ {ov5640_mode_QSXGA_2592_1944, 0, 0, NULL, 0},
+ },
+};
+
+static struct regulator *io_regulator;
+static struct regulator *core_regulator;
+static struct regulator *analog_regulator;
+
+static int ov5640_probe(struct i2c_client *adapter,
+ const struct i2c_device_id *device_id);
+static int ov5640_remove(struct i2c_client *client);
+
+static s32 ov5640_read_reg(u16 reg, u8 *val);
+static s32 ov5640_write_reg(u16 reg, u8 val);
+
+static const struct i2c_device_id ov5640_id[] = {
+ {"ov5640_v3", 0},
+ {},
+};
+
+MODULE_DEVICE_TABLE(i2c, ov5640_id);
+
+static struct i2c_driver ov5640_i2c_driver = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "ov5640_v3",
+ },
+ .probe = ov5640_probe,
+ .remove = ov5640_remove,
+ .id_table = ov5640_id,
+};
+
+static const struct ov5640_datafmt ov5640_colour_fmts[] = {
+ {MEDIA_BUS_FMT_YVYU8_2X8, V4L2_COLORSPACE_JPEG},
+ {MEDIA_BUS_FMT_UYVY8_2X8, V4L2_COLORSPACE_JPEG},
+};
+
+static struct ov5640 *to_ov5640(const struct i2c_client *client)
+{
+ return container_of(i2c_get_clientdata(client), struct ov5640, subdev);
+}
+
+static enum ov5640_frame_rate to_ov5640_frame_rate(struct v4l2_fract *timeperframe)
+{
+ enum ov5640_frame_rate rate;
+ u32 tgt_fps; /* target frames per secound */
+
+ tgt_fps = timeperframe->denominator / timeperframe->numerator;
+
+ if (tgt_fps == 30)
+ rate = ov5640_30_fps;
+ else if (tgt_fps == 15)
+ rate = ov5640_15_fps;
+ else
+ rate = -EINVAL;
+
+ return rate;
+}
+
+/* Find a data format by a pixel code in an array */
+static const struct ov5640_datafmt
+ *ov5640_find_datafmt(u32 code)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(ov5640_colour_fmts); i++)
+ if (ov5640_colour_fmts[i].code == code)
+ return ov5640_colour_fmts + i;
+
+ return NULL;
+}
+
+static inline void ov5640_power_down(int enable)
+{
+ gpio_set_value_cansleep(pwn_gpio, enable);
+
+ msleep(2);
+}
+
+static inline void ov5640_reset(void)
+{
+ gpio_set_value_cansleep(pwn_gpio, 1);
+ gpio_set_value_cansleep(rst_gpio, 0);
+ msleep(5);
+
+ gpio_set_value_cansleep(pwn_gpio, 0);
+ msleep(1);
+
+ gpio_set_value_cansleep(rst_gpio, 1);
+ msleep(20);
+}
+
+static int ov5640_regulator_enable(struct device *dev)
+{
+ int ret = 0;
+
+ io_regulator = devm_regulator_get(dev, "DOVDD");
+ if (!IS_ERR(io_regulator)) {
+ regulator_set_voltage(io_regulator,
+ OV5640_VOLTAGE_DIGITAL_IO,
+ OV5640_VOLTAGE_DIGITAL_IO);
+ ret = regulator_enable(io_regulator);
+ if (ret) {
+ dev_err(dev, "set io voltage failed\n");
+ return ret;
+ } else {
+ dev_dbg(dev, "set io voltage ok\n");
+ }
+ } else {
+ io_regulator = NULL;
+ dev_warn(dev, "cannot get io voltage\n");
+ }
+
+ core_regulator = devm_regulator_get(dev, "DVDD");
+ if (!IS_ERR(core_regulator)) {
+ regulator_set_voltage(core_regulator,
+ OV5640_VOLTAGE_DIGITAL_CORE,
+ OV5640_VOLTAGE_DIGITAL_CORE);
+ ret = regulator_enable(core_regulator);
+ if (ret) {
+ dev_err(dev, "set core voltage failed\n");
+ return ret;
+ } else {
+ dev_dbg(dev, "set core voltage ok\n");
+ }
+ } else {
+ core_regulator = NULL;
+ dev_warn(dev, "cannot get core voltage\n");
+ }
+
+ analog_regulator = devm_regulator_get(dev, "AVDD");
+ if (!IS_ERR(analog_regulator)) {
+ regulator_set_voltage(analog_regulator,
+ OV5640_VOLTAGE_ANALOG,
+ OV5640_VOLTAGE_ANALOG);
+ ret = regulator_enable(analog_regulator);
+ if (ret) {
+ dev_err(dev, "set analog voltage failed\n");
+ return ret;
+ } else {
+ dev_dbg(dev, "set analog voltage ok\n");
+ }
+ } else {
+ analog_regulator = NULL;
+ dev_warn(dev, "cannot get analog voltage\n");
+ }
+
+ return ret;
+}
+
+static s32 ov5640_write_reg(u16 reg, u8 val)
+{
+ u8 au8Buf[3] = {0};
+
+ au8Buf[0] = reg >> 8;
+ au8Buf[1] = reg & 0xff;
+ au8Buf[2] = val;
+
+ if (i2c_master_send(ov5640_data.i2c_client, au8Buf, 3) < 0) {
+ pr_err("%s:write reg error:reg=%x,val=%x\n",
+ __func__, reg, val);
+ return -1;
+ }
+
+ return 0;
+}
+
+static s32 ov5640_read_reg(u16 reg, u8 *val)
+{
+ u8 au8RegBuf[2] = {0};
+ u8 u8RdVal = 0;
+
+ au8RegBuf[0] = reg >> 8;
+ au8RegBuf[1] = reg & 0xff;
+
+ if (2 != i2c_master_send(ov5640_data.i2c_client, au8RegBuf, 2)) {
+ pr_err("%s:write reg error:reg=%x\n",
+ __func__, reg);
+ return -1;
+ }
+
+ if (1 != i2c_master_recv(ov5640_data.i2c_client, &u8RdVal, 1)) {
+ pr_err("%s:read reg error:reg=%x,val=%x\n",
+ __func__, reg, u8RdVal);
+ return -1;
+ }
+
+ *val = u8RdVal;
+
+ return u8RdVal;
+}
+
+static int ov5640_set_clk_rate(void)
+{
+ u32 tgt_xclk; /* target xclk */
+ int ret;
+
+ /* mclk */
+ tgt_xclk = ov5640_data.mclk;
+ tgt_xclk = min(tgt_xclk, (u32)OV5640_XCLK_MAX);
+ tgt_xclk = max(tgt_xclk, (u32)OV5640_XCLK_MIN);
+ ov5640_data.mclk = tgt_xclk;
+
+ pr_debug(" Setting mclk to %d MHz\n", tgt_xclk / 1000000);
+ ret = clk_set_rate(ov5640_data.sensor_clk, ov5640_data.mclk);
+ if (ret < 0)
+ pr_debug("set rate filed, rate=%d\n", ov5640_data.mclk);
+ return ret;
+}
+
+/* download ov5640 settings to sensor through i2c */
+static int ov5640_download_firmware(struct reg_value *pModeSetting, s32 ArySize)
+{
+ register u32 Delay_ms = 0;
+ register u16 RegAddr = 0;
+ register u8 Mask = 0;
+ register u8 Val = 0;
+ u8 RegVal = 0;
+ int i, retval = 0;
+
+ if (!pModeSetting) {
+ pr_err("Not support the mode\n");
+ return -EINVAL;
+ }
+
+ for (i = 0; i < ArySize; ++i, ++pModeSetting) {
+ Delay_ms = pModeSetting->u32Delay_ms;
+ RegAddr = pModeSetting->u16RegAddr;
+ Val = pModeSetting->u8Val;
+ Mask = pModeSetting->u8Mask;
+
+ if (Mask) {
+ retval = ov5640_read_reg(RegAddr, &RegVal);
+ if (retval < 0)
+ goto err;
+
+ RegVal &= ~(u8)Mask;
+ Val &= Mask;
+ Val |= RegVal;
+ }
+
+ retval = ov5640_write_reg(RegAddr, Val);
+ if (retval < 0)
+ goto err;
+
+ if (Delay_ms)
+ msleep(Delay_ms);
+ }
+
+err:
+ return retval;
+}
+
+static void ov5640_soft_reset(void)
+{
+ /* sysclk from pad */
+ ov5640_write_reg(0x3103, 0x11);
+
+ /* software reset */
+ ov5640_write_reg(0x3008, 0x82);
+
+ /* delay at least 5ms */
+ msleep(10);
+}
+
+static int ov5640_config_init(void)
+{
+ struct reg_value *pModeSetting = NULL;
+ int ArySize = 0, retval = 0;
+
+ /* Configure ov5640 initial parm */
+ pModeSetting = ov5640_global_init_setting;
+ ArySize = ARRAY_SIZE(ov5640_global_init_setting);
+
+ retval = ov5640_download_firmware(pModeSetting, ArySize);
+ if (retval < 0)
+ return retval;
+
+ pModeSetting = ov5640_init_setting_30fps_VGA;
+ ArySize = ARRAY_SIZE(ov5640_init_setting_30fps_VGA);
+ retval = ov5640_download_firmware(pModeSetting, ArySize);
+ if (retval < 0)
+ return retval;
+
+ /* driver capability */
+ ov5640_write_reg(0x302C, 0xc2);
+
+ return 0;
+}
+
+static void ov5640_start(void)
+{
+ ov5640_write_reg(0x3008, 0x02);
+ ov5640_write_reg(0x3008, 0x02);
+ msleep(1);
+}
+
+static int ov5640_change_mode(struct ov5640 *sensor)
+{
+ struct reg_value *pModeSetting = NULL;
+ enum ov5640_mode mode = sensor->streamcap.capturemode;
+ enum ov5640_frame_rate frame_rate =
+ to_ov5640_frame_rate(&sensor->streamcap.timeperframe);
+ int ArySize = 0, retval = 0;
+
+ if (mode > ov5640_mode_MAX || mode < ov5640_mode_MIN) {
+ pr_err("Wrong ov5640 mode detected!\n");
+ return -1;
+ }
+
+ pModeSetting = ov5640_mode_info_data[frame_rate][mode].init_data_ptr;
+ ArySize = ov5640_mode_info_data[frame_rate][mode].init_data_size;
+
+ ov5640_data.pix.width = ov5640_mode_info_data[frame_rate][mode].width;
+ ov5640_data.pix.height = ov5640_mode_info_data[frame_rate][mode].height;
+
+ if (ov5640_data.pix.width == 0 || ov5640_data.pix.height == 0 ||
+ pModeSetting == NULL || ArySize == 0) {
+ pr_err("Not support mode=%d %s\n", mode,
+ (frame_rate == 0) ? "15(fps)" : "30(fps)");
+ return -EINVAL;
+ }
+
+ retval = ov5640_download_firmware(pModeSetting, ArySize);
+ return retval;
+}
+
+static int init_device(void)
+{
+ int retval;
+
+ ov5640_soft_reset();
+ retval = ov5640_config_init();
+ if (retval < 0)
+ return retval;
+
+ ov5640_start();
+
+ return 0;
+}
+
+static void ov5640_stop(void)
+{
+ ov5640_write_reg(0x3008, 0x42);
+ msleep(1);
+}
+
+/*!
+ * ov5640_s_power - V4L2 sensor interface handler for VIDIOC_S_POWER ioctl
+ * @s: pointer to standard V4L2 device structure
+ * @on: indicates power mode (on or off)
+ *
+ * Turns the power on or off, depending on the value of on and returns the
+ * appropriate error code.
+ */
+static int ov5640_s_power(struct v4l2_subdev *sd, int on)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct ov5640 *sensor = to_ov5640(client);
+
+ if (on)
+ clk_prepare_enable(ov5640_data.sensor_clk);
+ else
+ clk_disable_unprepare(ov5640_data.sensor_clk);
+
+ sensor->on = on;
+ return 0;
+}
+
+/*!
+ * ov5640_g_parm - V4L2 sensor interface handler for VIDIOC_G_PARM ioctl
+ * @s: pointer to standard V4L2 sub device structure
+ * @a: pointer to standard V4L2 VIDIOC_G_PARM ioctl structure
+ *
+ * Returns the sensor's video CAPTURE parameters.
+ */
+static int ov5640_g_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *a)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct ov5640 *sensor = to_ov5640(client);
+ struct v4l2_captureparm *cparm = &a->parm.capture;
+ int ret = 0;
+
+ switch (a->type) {
+ /* This is the only case currently handled. */
+ case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+ case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
+ memset(a, 0, sizeof(*a));
+ a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ cparm->capability = sensor->streamcap.capability;
+ cparm->timeperframe = sensor->streamcap.timeperframe;
+ cparm->capturemode = sensor->streamcap.capturemode;
+ ret = 0;
+ break;
+
+ /* These are all the possible cases. */
+ case V4L2_BUF_TYPE_VIDEO_OUTPUT:
+ case V4L2_BUF_TYPE_VIDEO_OVERLAY:
+ case V4L2_BUF_TYPE_VBI_CAPTURE:
+ case V4L2_BUF_TYPE_VBI_OUTPUT:
+ case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
+ case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
+ ret = -EINVAL;
+ break;
+
+ default:
+ pr_debug(" type is unknown - %d\n", a->type);
+ ret = -EINVAL;
+ break;
+ }
+
+ return ret;
+}
+
+/*!
+ * ov5460_s_parm - V4L2 sensor interface handler for VIDIOC_S_PARM ioctl
+ * @s: pointer to standard V4L2 sub device structure
+ * @a: pointer to standard V4L2 VIDIOC_S_PARM ioctl structure
+ *
+ * Configures the sensor to use the input parameters, if possible. If
+ * not possible, reverts to the old parameters and returns the
+ * appropriate error code.
+ */
+static int ov5640_s_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *a)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct ov5640 *sensor = to_ov5640(client);
+ struct v4l2_fract *timeperframe = &a->parm.capture.timeperframe;
+ u32 tgt_fps; /* target frames per secound */
+ enum ov5640_mode mode = a->parm.capture.capturemode;
+ int ret = 0;
+
+ switch (a->type) {
+ /* This is the only case currently handled. */
+ case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+ case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
+ /* Check that the new frame rate is allowed. */
+ if ((timeperframe->numerator == 0) ||
+ (timeperframe->denominator == 0)) {
+ timeperframe->denominator = DEFAULT_FPS;
+ timeperframe->numerator = 1;
+ }
+
+ tgt_fps = timeperframe->denominator /
+ timeperframe->numerator;
+
+ if (tgt_fps > MAX_FPS) {
+ timeperframe->denominator = MAX_FPS;
+ timeperframe->numerator = 1;
+ } else if (tgt_fps < MIN_FPS) {
+ timeperframe->denominator = MIN_FPS;
+ timeperframe->numerator = 1;
+ }
+
+ if (mode > ov5640_mode_MAX || mode < ov5640_mode_MIN) {
+ pr_err("The camera mode[%d] is not supported!\n", mode);
+ return -EINVAL;
+ }
+
+ sensor->streamcap.timeperframe = *timeperframe;
+ sensor->streamcap.capturemode = mode;
+ break;
+
+ /* These are all the possible cases. */
+ case V4L2_BUF_TYPE_VIDEO_OUTPUT:
+ case V4L2_BUF_TYPE_VIDEO_OVERLAY:
+ case V4L2_BUF_TYPE_VBI_CAPTURE:
+ case V4L2_BUF_TYPE_VBI_OUTPUT:
+ case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
+ case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
+ pr_debug(" type is not " \
+ "V4L2_BUF_TYPE_VIDEO_CAPTURE but %d\n",
+ a->type);
+ ret = -EINVAL;
+ break;
+
+ default:
+ pr_debug(" type is unknown - %d\n", a->type);
+ ret = -EINVAL;
+ break;
+ }
+
+ return ret;
+}
+
+static int ov5640_s_stream(struct v4l2_subdev *sd, int enable)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct ov5640 *sensor = to_ov5640(client);
+
+ if (enable)
+ ov5640_start();
+ else
+ ov5640_stop();
+
+ sensor->on = enable;
+ return 0;
+}
+
+static struct ov5640_mode_info *get_max_resolution(enum ov5640_frame_rate rate)
+{
+ u32 max_width;
+ enum ov5640_mode mode;
+ int i;
+
+ mode = 0;
+ max_width = ov5640_mode_info_data[rate][0].width;
+
+ for (i = 0; i < (ov5640_mode_MAX + 1); i++) {
+ if (ov5640_mode_info_data[rate][i].width > max_width) {
+ max_width = ov5640_mode_info_data[rate][i].width;
+ mode = i;
+ }
+ }
+ return &ov5640_mode_info_data[rate][mode];
+}
+
+static struct ov5640_mode_info *match(struct v4l2_mbus_framefmt *fmt,
+ enum ov5640_frame_rate rate)
+{
+ struct ov5640_mode_info *info;
+ int i;
+
+ for (i = 0; i < (ov5640_mode_MAX + 1); i++) {
+ if (fmt->width == ov5640_mode_info_data[rate][i].width &&
+ fmt->height == ov5640_mode_info_data[rate][i].height) {
+ info = &ov5640_mode_info_data[rate][i];
+ break;
+ }
+ }
+ if (i == ov5640_mode_MAX + 1)
+ info = NULL;
+
+ return info;
+}
+
+static void try_to_find_resolution(struct ov5640 *sensor,
+ struct v4l2_mbus_framefmt *mf)
+{
+ enum ov5640_mode mode = sensor->streamcap.capturemode;
+ struct v4l2_fract *timeperframe = &sensor->streamcap.timeperframe;
+ enum ov5640_frame_rate frame_rate = to_ov5640_frame_rate(timeperframe);
+ struct device *dev = &sensor->i2c_client->dev;
+ struct ov5640_mode_info *info;
+ bool found = false;
+
+ if ((mf->width == ov5640_mode_info_data[frame_rate][mode].width) &&
+ (mf->height == ov5640_mode_info_data[frame_rate][mode].height)) {
+ info = &ov5640_mode_info_data[frame_rate][mode];
+ found = true;
+ } else {
+ /* get mode info according to frame user's width and height */
+ info = match(mf, frame_rate);
+ if (info == NULL) {
+ frame_rate ^= 0x1;
+ info = match(mf, frame_rate);
+ if (info) {
+ sensor->streamcap.capturemode = -1;
+ dev_err(dev, "%s %dx%d only support %s(fps)\n", __func__,
+ info->width, info->height,
+ (frame_rate == 0) ? "15fps" : "30fps");
+ return;
+ }
+ goto max_resolution;
+ }
+ found = true;
+ }
+
+ /* get max resolution to resize */
+max_resolution:
+ if (!found) {
+ frame_rate ^= 0x1;
+ info = get_max_resolution(frame_rate);
+ }
+
+ sensor->streamcap.capturemode = info->mode;
+ sensor->streamcap.timeperframe.denominator = (frame_rate) ? 30 : 15;
+ sensor->pix.width = info->width;
+ sensor->pix.height = info->height;
+}
+
+static int ov5640_set_fmt(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_format *format)
+{
+ struct v4l2_mbus_framefmt *mf = &format->format;
+ const struct ov5640_datafmt *fmt = ov5640_find_datafmt(mf->code);
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct ov5640 *sensor = to_ov5640(client);
+ int ret;
+
+ if (format->pad)
+ return -EINVAL;
+
+ if (!fmt) {
+ mf->code = ov5640_colour_fmts[0].code;
+ mf->colorspace = ov5640_colour_fmts[0].colorspace;
+ }
+
+ mf->field = V4L2_FIELD_NONE;
+ try_to_find_resolution(sensor, mf);
+
+ if (format->which == V4L2_SUBDEV_FORMAT_TRY)
+ return 0;
+
+ init_device();
+ ret = ov5640_change_mode(sensor);
+ sensor->fmt = fmt;
+
+ return ret;
+}
+
+static int ov5640_get_fmt(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_format *format)
+{
+ struct v4l2_mbus_framefmt *mf = &format->format;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct ov5640 *sensor = to_ov5640(client);
+ if (format->pad)
+ return -EINVAL;
+
+ memset(mf, 0, sizeof(struct v4l2_mbus_framefmt));
+
+ mf->code = ov5640_colour_fmts[0].code;
+ mf->colorspace = ov5640_colour_fmts[0].colorspace;
+ mf->width = sensor->pix.width;
+ mf->height = sensor->pix.height;
+ mf->field = V4L2_FIELD_NONE;
+ mf->reserved[1] = 0;
+
+ dev_dbg(&client->dev, "%s code=0x%x, w/h=(%d,%d), colorspace=%d, field=%d\n",
+ __func__, mf->code, mf->width, mf->height, mf->colorspace, mf->field);
+
+ return 0;
+}
+
+static int ov5640_enum_code(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_mbus_code_enum *code)
+{
+ if (code->pad || code->index >= ARRAY_SIZE(ov5640_colour_fmts))
+ return -EINVAL;
+
+ code->code = ov5640_colour_fmts[code->index].code;
+ return 0;
+}
+
+/*!
+ * ov5640_enum_framesizes - V4L2 sensor interface handler for
+ * VIDIOC_ENUM_FRAMESIZES ioctl
+ * @s: pointer to standard V4L2 device structure
+ * @fsize: standard V4L2 VIDIOC_ENUM_FRAMESIZES ioctl structure
+ *
+ * Return 0 if successful, otherwise -EINVAL.
+ */
+static int ov5640_enum_framesizes(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_frame_size_enum *fse)
+{
+ if (fse->index > ov5640_mode_MAX)
+ return -EINVAL;
+
+ fse->max_width =
+ max(ov5640_mode_info_data[0][fse->index].width,
+ ov5640_mode_info_data[1][fse->index].width);
+ fse->min_width = fse->max_width;
+
+ fse->max_height =
+ max(ov5640_mode_info_data[0][fse->index].height,
+ ov5640_mode_info_data[1][fse->index].height);
+ fse->min_height = fse->max_height;
+
+ return 0;
+}
+
+/*!
+ * ov5640_enum_frameintervals - V4L2 sensor interface handler for
+ * VIDIOC_ENUM_FRAMEINTERVALS ioctl
+ * @s: pointer to standard V4L2 device structure
+ * @fival: standard V4L2 VIDIOC_ENUM_FRAMEINTERVALS ioctl structure
+ *
+ * Return 0 if successful, otherwise -EINVAL.
+ */
+static int ov5640_enum_frameintervals(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_frame_interval_enum *fie)
+{
+ int i, j, count;
+
+ if (fie->index < 0 || fie->index > ov5640_mode_MAX)
+ return -EINVAL;
+
+ if (fie->width == 0 || fie->height == 0 ||
+ fie->code == 0) {
+ pr_warning("Please assign pixel format, width and height.\n");
+ return -EINVAL;
+ }
+
+ fie->interval.numerator = 1;
+
+ count = 0;
+ for (i = 0; i < ARRAY_SIZE(ov5640_framerates); i++) {
+ for (j = 0; j < (ov5640_mode_MAX + 1); j++) {
+ if (fie->width == ov5640_mode_info_data[i][j].width
+ && fie->height == ov5640_mode_info_data[i][j].height
+ && ov5640_mode_info_data[i][j].init_data_ptr != NULL) {
+ count++;
+ }
+ if (fie->index == (count - 1)) {
+ fie->interval.denominator = ov5640_framerates[i];
+ return 0;
+ }
+ }
+ }
+
+ return -EINVAL;
+}
+
+static int ov5640_link_setup(struct media_entity *entity,
+ const struct media_pad *local,
+ const struct media_pad *remote, u32 flags)
+{
+ return 0;
+}
+
+static struct v4l2_subdev_video_ops ov5640_subdev_video_ops = {
+ .g_parm = ov5640_g_parm,
+ .s_parm = ov5640_s_parm,
+ .s_stream = ov5640_s_stream,
+};
+
+static const struct v4l2_subdev_pad_ops ov5640_subdev_pad_ops = {
+ .enum_frame_size = ov5640_enum_framesizes,
+ .enum_frame_interval = ov5640_enum_frameintervals,
+ .enum_mbus_code = ov5640_enum_code,
+ .set_fmt = ov5640_set_fmt,
+ .get_fmt = ov5640_get_fmt,
+};
+
+static struct v4l2_subdev_core_ops ov5640_subdev_core_ops = {
+ .s_power = ov5640_s_power,
+};
+
+static struct v4l2_subdev_ops ov5640_subdev_ops = {
+ .core = &ov5640_subdev_core_ops,
+ .video = &ov5640_subdev_video_ops,
+ .pad = &ov5640_subdev_pad_ops,
+};
+
+static const struct media_entity_operations ov5640_sd_media_ops = {
+ .link_setup = ov5640_link_setup,
+};
+
+/*!
+ * ov5640 I2C probe function
+ *
+ * @param adapter struct i2c_adapter *
+ * @return Error code indicating success or failure
+ */
+static int ov5640_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct pinctrl *pinctrl;
+ struct device *dev = &client->dev;
+ struct v4l2_subdev *sd;
+ int retval;
+ u8 chip_id_high, chip_id_low;
+
+ /* ov5640 pinctrl */
+ pinctrl = devm_pinctrl_get_select_default(dev);
+ if (IS_ERR(pinctrl)) {
+ dev_err(dev, "setup pinctrl failed\n");
+ return PTR_ERR(pinctrl);
+ }
+
+ /* request power down pin */
+ pwn_gpio = of_get_named_gpio(dev->of_node, "pwn-gpios", 0);
+ if (!gpio_is_valid(pwn_gpio)) {
+ dev_err(dev, "no sensor pwdn pin available\n");
+ return -ENODEV;
+ }
+ retval = devm_gpio_request_one(dev, pwn_gpio, GPIOF_OUT_INIT_HIGH,
+ "ov5640_pwdn");
+ if (retval < 0)
+ return retval;
+
+ /* request reset pin */
+ rst_gpio = of_get_named_gpio(dev->of_node, "rst-gpios", 0);
+ if (!gpio_is_valid(rst_gpio)) {
+ dev_err(dev, "no sensor reset pin available\n");
+ devm_gpio_free(dev, rst_gpio);
+ return -EINVAL;
+ }
+ retval = devm_gpio_request_one(dev, rst_gpio, GPIOF_OUT_INIT_LOW,
+ "ov5640_reset");
+ if (retval < 0) {
+ devm_gpio_free(dev, pwn_gpio);
+ return retval;
+ }
+
+ /* Set initial values for the sensor struct. */
+ memset(&ov5640_data, 0, sizeof(ov5640_data));
+ ov5640_data.sensor_clk = devm_clk_get(dev, "csi_mclk");
+ if (IS_ERR(ov5640_data.sensor_clk)) {
+ dev_err(dev, "get mclk failed\n");
+ devm_gpio_free(dev, pwn_gpio);
+ devm_gpio_free(dev, rst_gpio);
+ return PTR_ERR(ov5640_data.sensor_clk);
+ }
+
+ retval = of_property_read_u32(dev->of_node, "mclk",
+ &ov5640_data.mclk);
+ if (retval) {
+ dev_err(dev, "mclk frequency is invalid\n");
+ return retval;
+ }
+
+ retval = of_property_read_u32(dev->of_node, "mclk_source",
+ (u32 *) &(ov5640_data.mclk_source));
+ if (retval) {
+ dev_err(dev, "mclk_source invalid\n");
+ return retval;
+ }
+
+ retval = of_property_read_u32(dev->of_node, "csi_id",
+ &(ov5640_data.csi));
+ if (retval) {
+ dev_err(dev, "csi_id invalid\n");
+ return retval;
+ }
+
+ /* Set mclk rate before clk on */
+ ov5640_set_clk_rate();
+
+ retval = clk_prepare_enable(ov5640_data.sensor_clk);
+ if (retval < 0) {
+ dev_err(dev, "%s: enable sensor clk fail\n", __func__);
+ return -EINVAL;
+ }
+
+ ov5640_data.io_init = ov5640_reset;
+ ov5640_data.i2c_client = client;
+
+ ov5640_data.pix.pixelformat = V4L2_PIX_FMT_YVYU;
+ ov5640_data.pix.width = ov5640_mode_info_data[1][1].width;
+ ov5640_data.pix.height = ov5640_mode_info_data[1][1].height;
+ ov5640_data.streamcap.capability = V4L2_MODE_HIGHQUALITY |
+ V4L2_CAP_TIMEPERFRAME;
+ ov5640_data.streamcap.capturemode = 1;
+ ov5640_data.streamcap.timeperframe.denominator = DEFAULT_FPS;
+ ov5640_data.streamcap.timeperframe.numerator = 1;
+
+ ov5640_regulator_enable(&client->dev);
+
+ ov5640_reset();
+
+ retval = ov5640_read_reg(OV5640_CHIP_ID_HIGH_BYTE, &chip_id_high);
+ if (retval < 0 || chip_id_high != 0x56) {
+ clk_disable_unprepare(ov5640_data.sensor_clk);
+ pr_warning("camera ov5640 is not found\n");
+ return -ENODEV;
+ }
+ retval = ov5640_read_reg(OV5640_CHIP_ID_LOW_BYTE, &chip_id_low);
+ if (retval < 0 || chip_id_low != 0x40) {
+ clk_disable_unprepare(ov5640_data.sensor_clk);
+ pr_warning("camera ov5640 is not found\n");
+ return -ENODEV;
+ }
+
+ retval = init_device();
+ if (retval < 0) {
+ clk_disable_unprepare(ov5640_data.sensor_clk);
+ pr_warning("camera ov5640 init fail\n");
+ return -ENODEV;
+ }
+
+ sd = &ov5640_data.subdev;
+ v4l2_i2c_subdev_init(sd, client, &ov5640_subdev_ops);
+
+ sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+ sd->entity.function = MEDIA_ENT_F_CAM_SENSOR;
+ ov5640_data.pads[OV5640_SENS_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
+
+ retval = media_entity_pads_init(&sd->entity, OV5640_SENS_PADS_NUM,
+ ov5640_data.pads);
+ sd->entity.ops = &ov5640_sd_media_ops;
+ if (retval < 0)
+ return retval;
+
+ retval = v4l2_async_register_subdev(sd);
+ if (retval < 0) {
+ dev_err(&client->dev,
+ "%s--Async register failed, ret=%d\n", __func__, retval);
+ media_entity_cleanup(&sd->entity);
+ }
+
+ clk_disable_unprepare(ov5640_data.sensor_clk);
+
+ pr_info("%s camera ov5640, is found\n", __func__);
+ return retval;
+}
+
+/*!
+ * ov5640 I2C detach function
+ *
+ * @param client struct i2c_client *
+ * @return Error code indicating success or failure
+ */
+static int ov5640_remove(struct i2c_client *client)
+{
+ struct v4l2_subdev *sd = i2c_get_clientdata(client);
+
+ v4l2_async_unregister_subdev(sd);
+
+ clk_unprepare(ov5640_data.sensor_clk);
+
+ ov5640_power_down(1);
+
+ if (analog_regulator)
+ regulator_disable(analog_regulator);
+
+ if (core_regulator)
+ regulator_disable(core_regulator);
+
+ if (io_regulator)
+ regulator_disable(io_regulator);
+
+ return 0;
+}
+
+module_i2c_driver(ov5640_i2c_driver);
+
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("OV5640 Camera Driver");
+MODULE_LICENSE("GPL");
+MODULE_VERSION("3.0");
+MODULE_ALIAS("CSI");
diff --git a/drivers/media/platform/mxc/capture/Kconfig b/drivers/media/platform/mxc/capture/Kconfig
new file mode 100644
index 000000000000..040b6a051d04
--- /dev/null
+++ b/drivers/media/platform/mxc/capture/Kconfig
@@ -0,0 +1,125 @@
+if VIDEO_MXC_CAPTURE
+
+config VIDEO_V4L2_MXC_INT_DEVICE
+ tristate
+
+config VIDEO_MXC_CSI_CAMERA
+ tristate "CSI camera support"
+ depends on VIDEO_MXC_CAPTURE && VIDEO_V4L2
+ select VIDEOBUF2_DMA_CONTIG
+ ---help---
+ This is the video4linux2 capture driver based on CSI module.
+
+config MXC_VADC
+ tristate "mxc VADC support"
+ depends on VIDEO_MXC_CAPTURE && VIDEO_V4L2
+ ---help---
+ If you plan to use the VADC with your MXC system, say Y here.
+
+config MXC_MIPI_CSI
+ tristate "mxc mipi csi driver"
+ depends on VIDEO_MXC_CAPTURE && VIDEO_V4L2
+ ---help---
+ This is a V4L2 driver for i.MX7D SoC MIPI-CSI2 receiver devices.
+
+menu "MXC Camera/V4L2 PRP Features support"
+config VIDEO_MXC_IPU_CAMERA
+ bool
+ select VIDEO_V4L2_MXC_INT_DEVICE
+ depends on VIDEO_MXC_CAPTURE && MXC_IPU
+ default y
+
+config MXC_CAMERA_OV5640
+ tristate "OmniVision ov5640 camera support"
+ depends on !VIDEO_MXC_EMMA_CAMERA && I2C
+ depends on VIDEO_V4L2_MXC_INT_DEVICE
+ ---help---
+ If you plan to use the ov5640 Camera with your MXC system, say Y here.
+
+config MXC_CAMERA_OV5640_V2
+ tristate "OmniVision ov5640 camera support"
+ depends on VIDEO_MXC_CAPTURE && I2C
+ ---help---
+ If you plan to use the ov5640 Camera with your MXC system, say Y here.
+
+config MXC_CAMERA_OV5642
+ tristate "OmniVision ov5642 camera support"
+ depends on !VIDEO_MXC_EMMA_CAMERA && I2C
+ depends on VIDEO_V4L2_MXC_INT_DEVICE
+ ---help---
+ If you plan to use the ov5642 Camera with your MXC system, say Y here.
+
+config MXC_CAMERA_OV5640_MIPI
+ tristate "OmniVision ov5640 camera support using mipi"
+ depends on !VIDEO_MXC_EMMA_CAMERA && I2C && MXC_MIPI_CSI2
+ depends on VIDEO_V4L2_MXC_INT_DEVICE
+ ---help---
+ If you plan to use the ov5640 Camera with mipi interface in your MXC system, say Y here.
+
+config MXC_CAMERA_OV5640_MIPI_V2
+ tristate "OmniVision ov5640 camera support using mipi"
+ depends on MXC_MIPI_CSI && I2C
+ ---help---
+ If you plan to use the ov5640 Camera with mipi interface in your MXC system, say Y here.
+
+config MXC_CAMERA_OV5647_MIPI
+ tristate "OmniVision ov5647 camera support using mipi"
+ depends on MXC_MIPI_CSI && I2C
+ ---help---
+ If you plan to use the ov5647 Camera with mipi interface in your MXC system, say Y here.
+
+config MXC_TVIN_ADV7180
+ tristate "Analog Device adv7180 TV Decoder Input support"
+ depends on !VIDEO_MXC_EMMA_CAMERA && I2C
+ depends on VIDEO_V4L2_MXC_INT_DEVICE
+ ---help---
+ If you plan to use the adv7180 video decoder with your MXC system, say Y here.
+
+choice
+ prompt "Select Overlay Rounting"
+ default MXC_IPU_DEVICE_QUEUE_SDC
+ depends on VIDEO_MXC_IPU_CAMERA && FB_MXC_SYNC_PANEL
+
+config MXC_IPU_DEVICE_QUEUE_SDC
+ tristate "Queue ipu device for overlay library"
+ depends on VIDEO_MXC_IPU_CAMERA
+ ---help---
+ Use case CSI->MEM->IPU DEVICE->SDC:
+ Images from sensor will be frist recieved in memory,then
+ queue to ipu device for processing if needed, and displaying
+ it on synchronous display with SDC use case.
+
+config MXC_IPU_PRP_VF_SDC
+ bool "Pre-Processor VF SDC library"
+ depends on VIDEO_MXC_IPU_CAMERA
+ ---help---
+ Use case PRP_VF_SDC:
+ Preprocessing image from smart sensor for viewfinder and
+ displaying it on synchronous display with SDC use case.
+ If SDC BG is selected, Rotation will not be supported.
+ CSI -> IC (PRP VF) -> MEM
+ MEM -> IC (ROT) -> MEM
+ MEM -> SDC (FG/BG)
+
+endchoice
+
+config MXC_IPU_PRP_ENC
+ tristate "Pre-processor Encoder library"
+ depends on VIDEO_MXC_IPU_CAMERA
+ default y
+ ---help---
+ Use case PRP_ENC:
+ Preprocessing image from smart sensor for encoder.
+ CSI -> IC (PRP ENC) -> MEM
+
+config MXC_IPU_CSI_ENC
+ tristate "IPU CSI Encoder library"
+ depends on VIDEO_MXC_IPU_CAMERA
+ default y
+ ---help---
+ Use case IPU_CSI_ENC:
+ Get raw image with CSI from smart sensor for encoder.
+ CSI -> MEM
+endmenu
+
+endif
diff --git a/drivers/media/platform/mxc/capture/Makefile b/drivers/media/platform/mxc/capture/Makefile
new file mode 100644
index 000000000000..e6e4b99f9435
--- /dev/null
+++ b/drivers/media/platform/mxc/capture/Makefile
@@ -0,0 +1,38 @@
+ifeq ($(CONFIG_VIDEO_MXC_IPU_CAMERA),y)
+ obj-$(CONFIG_VIDEO_MXC_CAPTURE) += mxc_v4l2_capture.o
+ obj-$(CONFIG_MXC_IPU_PRP_VF_SDC) += ipu_prp_vf_sdc.o ipu_prp_vf_sdc_bg.o
+ obj-$(CONFIG_MXC_IPU_DEVICE_QUEUE_SDC) += ipu_fg_overlay_sdc.o ipu_bg_overlay_sdc.o
+ obj-$(CONFIG_MXC_IPU_PRP_ENC) += ipu_prp_enc.o ipu_still.o
+ obj-$(CONFIG_MXC_IPU_CSI_ENC) += ipu_csi_enc.o ipu_still.o
+endif
+
+obj-$(CONFIG_VIDEO_MXC_CSI_CAMERA) += mx6s_capture.o
+obj-$(CONFIG_MXC_VADC) += mxc_vadc.o
+obj-$(CONFIG_MXC_MIPI_CSI) += mxc_mipi_csi.o
+
+# Used for iMX 6QDL
+ov5640_camera_int-objs := ov5640.o
+obj-$(CONFIG_MXC_CAMERA_OV5640) += ov5640_camera_int.o
+
+# Used for iMX 6UL/ULL/SX/SL/SLL
+ov5640_camera_v2-objs := ov5640_v2.o
+obj-$(CONFIG_MXC_CAMERA_OV5640_V2) += ov5640_camera_v2.o
+
+ov5642_camera-objs := ov5642.o
+obj-$(CONFIG_MXC_CAMERA_OV5642) += ov5642_camera.o
+
+# Used for iMX 6QDL/DQSCM
+ov5640_camera_mipi_int-objs := ov5640_mipi.o
+obj-$(CONFIG_MXC_CAMERA_OV5640_MIPI) += ov5640_camera_mipi_int.o
+
+# Used for iMX 7D
+ov5640_camera_mipi_v2-objs := ov5640_mipi_v2.o
+obj-$(CONFIG_MXC_CAMERA_OV5640_MIPI_V2) += ov5640_camera_mipi_v2.o
+
+ov5647_camera_mipi-objs := ov5647_mipi.o
+obj-$(CONFIG_MXC_CAMERA_OV5647_MIPI) += ov5647_camera_mipi.o
+
+adv7180_tvin-objs := adv7180.o
+obj-$(CONFIG_MXC_TVIN_ADV7180) += adv7180_tvin.o
+
+obj-$(CONFIG_VIDEO_V4L2_MXC_INT_DEVICE) += v4l2-int-device.o
diff --git a/drivers/media/platform/mxc/capture/adv7180.c b/drivers/media/platform/mxc/capture/adv7180.c
new file mode 100644
index 000000000000..abd615927a48
--- /dev/null
+++ b/drivers/media/platform/mxc/capture/adv7180.c
@@ -0,0 +1,1380 @@
+/*
+ * Copyright 2005-2014 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/*!
+ * @file adv7180.c
+ *
+ * @brief Analog Device ADV7180 video decoder functions
+ *
+ * @ingroup Camera
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/i2c.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/of_gpio.h>
+#include <linux/pinctrl/consumer.h>
+#include <linux/regulator/consumer.h>
+#include <media/v4l2-chip-ident.h>
+#include "v4l2-int-device.h"
+#include "mxc_v4l2_capture.h"
+
+#define ADV7180_VOLTAGE_ANALOG 1800000
+#define ADV7180_VOLTAGE_DIGITAL_CORE 1800000
+#define ADV7180_VOLTAGE_DIGITAL_IO 3300000
+#define ADV7180_VOLTAGE_PLL 1800000
+
+static struct regulator *dvddio_regulator;
+static struct regulator *dvdd_regulator;
+static struct regulator *avdd_regulator;
+static struct regulator *pvdd_regulator;
+static int pwn_gpio;
+
+static int adv7180_probe(struct i2c_client *adapter,
+ const struct i2c_device_id *id);
+static int adv7180_detach(struct i2c_client *client);
+
+static const struct i2c_device_id adv7180_id[] = {
+ {"adv7180", 0},
+ {},
+};
+
+MODULE_DEVICE_TABLE(i2c, adv7180_id);
+
+static struct i2c_driver adv7180_i2c_driver = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "adv7180",
+ },
+ .probe = adv7180_probe,
+ .remove = adv7180_detach,
+ .id_table = adv7180_id,
+};
+
+/*!
+ * Maintains the information on the current state of the sensor.
+ */
+struct sensor {
+ struct sensor_data sen;
+ v4l2_std_id std_id;
+} adv7180_data;
+
+
+/*! List of input video formats supported. The video formats is corresponding
+ * with v4l2 id in video_fmt_t
+ */
+typedef enum {
+ ADV7180_NTSC = 0, /*!< Locked on (M) NTSC video signal. */
+ ADV7180_PAL, /*!< (B, G, H, I, N)PAL video signal. */
+ ADV7180_NOT_LOCKED, /*!< Not locked on a signal. */
+} video_fmt_idx;
+
+/*! Number of video standards supported (including 'not locked' signal). */
+#define ADV7180_STD_MAX (ADV7180_PAL + 1)
+
+/*! Video format structure. */
+typedef struct {
+ int v4l2_id; /*!< Video for linux ID. */
+ char name[16]; /*!< Name (e.g., "NTSC", "PAL", etc.) */
+ u16 raw_width; /*!< Raw width. */
+ u16 raw_height; /*!< Raw height. */
+ u16 active_width; /*!< Active width. */
+ u16 active_height; /*!< Active height. */
+ int frame_rate; /*!< Frame rate. */
+} video_fmt_t;
+
+/*! Description of video formats supported.
+ *
+ * PAL: raw=720x625, active=720x576.
+ * NTSC: raw=720x525, active=720x480.
+ */
+static video_fmt_t video_fmts[] = {
+ { /*! NTSC */
+ .v4l2_id = V4L2_STD_NTSC,
+ .name = "NTSC",
+ .raw_width = 720, /* SENS_FRM_WIDTH */
+ .raw_height = 525, /* SENS_FRM_HEIGHT */
+ .active_width = 720, /* ACT_FRM_WIDTH plus 1 */
+ .active_height = 480, /* ACT_FRM_WIDTH plus 1 */
+ .frame_rate = 30,
+ },
+ { /*! (B, G, H, I, N) PAL */
+ .v4l2_id = V4L2_STD_PAL,
+ .name = "PAL",
+ .raw_width = 720,
+ .raw_height = 625,
+ .active_width = 720,
+ .active_height = 576,
+ .frame_rate = 25,
+ },
+ { /*! Unlocked standard */
+ .v4l2_id = V4L2_STD_ALL,
+ .name = "Autodetect",
+ .raw_width = 720,
+ .raw_height = 625,
+ .active_width = 720,
+ .active_height = 576,
+ .frame_rate = 0,
+ },
+};
+
+/*!* Standard index of ADV7180. */
+static video_fmt_idx video_idx = ADV7180_PAL;
+
+/*! @brief This mutex is used to provide mutual exclusion.
+ *
+ * Create a mutex that can be used to provide mutually exclusive
+ * read/write access to the globally accessible data structures
+ * and variables that were defined above.
+ */
+static DEFINE_MUTEX(mutex);
+
+#define IF_NAME "adv7180"
+#define ADV7180_INPUT_CTL 0x00 /* Input Control */
+#define ADV7180_STATUS_1 0x10 /* Status #1 */
+#define ADV7180_BRIGHTNESS 0x0a /* Brightness */
+#define ADV7180_IDENT 0x11 /* IDENT */
+#define ADV7180_VSYNC_FIELD_CTL_1 0x31 /* VSYNC Field Control #1 */
+#define ADV7180_MANUAL_WIN_CTL 0x3d /* Manual Window Control */
+#define ADV7180_SD_SATURATION_CB 0xe3 /* SD Saturation Cb */
+#define ADV7180_SD_SATURATION_CR 0xe4 /* SD Saturation Cr */
+#define ADV7180_PWR_MNG 0x0f /* Power Management */
+
+/* supported controls */
+/* This hasn't been fully implemented yet.
+ * This is how it should work, though. */
+static struct v4l2_queryctrl adv7180_qctrl[] = {
+ {
+ .id = V4L2_CID_BRIGHTNESS,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Brightness",
+ .minimum = 0, /* check this value */
+ .maximum = 255, /* check this value */
+ .step = 1, /* check this value */
+ .default_value = 127, /* check this value */
+ .flags = 0,
+ }, {
+ .id = V4L2_CID_SATURATION,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Saturation",
+ .minimum = 0, /* check this value */
+ .maximum = 255, /* check this value */
+ .step = 0x1, /* check this value */
+ .default_value = 127, /* check this value */
+ .flags = 0,
+ }
+};
+
+static inline void adv7180_power_down(int enable)
+{
+ gpio_set_value_cansleep(pwn_gpio, !enable);
+ msleep(2);
+}
+
+static int adv7180_regulator_enable(struct device *dev)
+{
+ int ret = 0;
+
+ dvddio_regulator = devm_regulator_get(dev, "DOVDD");
+
+ if (!IS_ERR(dvddio_regulator)) {
+ regulator_set_voltage(dvddio_regulator,
+ ADV7180_VOLTAGE_DIGITAL_IO,
+ ADV7180_VOLTAGE_DIGITAL_IO);
+ ret = regulator_enable(dvddio_regulator);
+ if (ret) {
+ dev_err(dev, "set io voltage failed\n");
+ return ret;
+ } else {
+ dev_dbg(dev, "set io voltage ok\n");
+ }
+ } else {
+ dev_warn(dev, "cannot get io voltage\n");
+ }
+
+ dvdd_regulator = devm_regulator_get(dev, "DVDD");
+ if (!IS_ERR(dvdd_regulator)) {
+ regulator_set_voltage(dvdd_regulator,
+ ADV7180_VOLTAGE_DIGITAL_CORE,
+ ADV7180_VOLTAGE_DIGITAL_CORE);
+ ret = regulator_enable(dvdd_regulator);
+ if (ret) {
+ dev_err(dev, "set core voltage failed\n");
+ return ret;
+ } else {
+ dev_dbg(dev, "set core voltage ok\n");
+ }
+ } else {
+ dev_warn(dev, "cannot get core voltage\n");
+ }
+
+ avdd_regulator = devm_regulator_get(dev, "AVDD");
+ if (!IS_ERR(avdd_regulator)) {
+ regulator_set_voltage(avdd_regulator,
+ ADV7180_VOLTAGE_ANALOG,
+ ADV7180_VOLTAGE_ANALOG);
+ ret = regulator_enable(avdd_regulator);
+ if (ret) {
+ dev_err(dev, "set analog voltage failed\n");
+ return ret;
+ } else {
+ dev_dbg(dev, "set analog voltage ok\n");
+ }
+ } else {
+ dev_warn(dev, "cannot get analog voltage\n");
+ }
+
+ pvdd_regulator = devm_regulator_get(dev, "PVDD");
+ if (!IS_ERR(pvdd_regulator)) {
+ regulator_set_voltage(pvdd_regulator,
+ ADV7180_VOLTAGE_PLL,
+ ADV7180_VOLTAGE_PLL);
+ ret = regulator_enable(pvdd_regulator);
+ if (ret) {
+ dev_err(dev, "set pll voltage failed\n");
+ return ret;
+ } else {
+ dev_dbg(dev, "set pll voltage ok\n");
+ }
+ } else {
+ dev_warn(dev, "cannot get pll voltage\n");
+ }
+
+ return ret;
+}
+
+
+/***********************************************************************
+ * I2C transfert.
+ ***********************************************************************/
+
+/*! Read one register from a ADV7180 i2c slave device.
+ *
+ * @param *reg register in the device we wish to access.
+ *
+ * @return 0 if success, an error code otherwise.
+ */
+static inline int adv7180_read(u8 reg)
+{
+ int val;
+
+ val = i2c_smbus_read_byte_data(adv7180_data.sen.i2c_client, reg);
+ if (val < 0) {
+ dev_dbg(&adv7180_data.sen.i2c_client->dev,
+ "%s:read reg error: reg=%2x\n", __func__, reg);
+ return -1;
+ }
+ return val;
+}
+
+/*! Write one register of a ADV7180 i2c slave device.
+ *
+ * @param *reg register in the device we wish to access.
+ *
+ * @return 0 if success, an error code otherwise.
+ */
+static int adv7180_write_reg(u8 reg, u8 val)
+{
+ s32 ret;
+
+ ret = i2c_smbus_write_byte_data(adv7180_data.sen.i2c_client, reg, val);
+ if (ret < 0) {
+ dev_dbg(&adv7180_data.sen.i2c_client->dev,
+ "%s:write reg error:reg=%2x,val=%2x\n", __func__,
+ reg, val);
+ return -1;
+ }
+ return 0;
+}
+
+/***********************************************************************
+ * mxc_v4l2_capture interface.
+ ***********************************************************************/
+
+/*!
+ * Return attributes of current video standard.
+ * Since this device autodetects the current standard, this function also
+ * sets the values that need to be changed if the standard changes.
+ * There is no set std equivalent function.
+ *
+ * @return None.
+ */
+static void adv7180_get_std(v4l2_std_id *std)
+{
+ int status_1, standard, idx;
+ bool locked;
+
+ dev_dbg(&adv7180_data.sen.i2c_client->dev, "In adv7180_get_std\n");
+
+ status_1 = adv7180_read(ADV7180_STATUS_1);
+ locked = status_1 & 0x1;
+ standard = status_1 & 0x70;
+
+ mutex_lock(&mutex);
+ *std = V4L2_STD_ALL;
+ idx = ADV7180_NOT_LOCKED;
+ if (locked) {
+ if (standard == 0x40) {
+ *std = V4L2_STD_PAL;
+ idx = ADV7180_PAL;
+ } else if (standard == 0) {
+ *std = V4L2_STD_NTSC;
+ idx = ADV7180_NTSC;
+ }
+ }
+ mutex_unlock(&mutex);
+
+ /* This assumes autodetect which this device uses. */
+ if (*std != adv7180_data.std_id) {
+ video_idx = idx;
+ adv7180_data.std_id = *std;
+ adv7180_data.sen.pix.width = video_fmts[video_idx].raw_width;
+ adv7180_data.sen.pix.height = video_fmts[video_idx].raw_height;
+ }
+}
+
+/***********************************************************************
+ * IOCTL Functions from v4l2_int_ioctl_desc.
+ ***********************************************************************/
+
+/*!
+ * ioctl_g_ifparm - V4L2 sensor interface handler for vidioc_int_g_ifparm_num
+ * s: pointer to standard V4L2 device structure
+ * p: pointer to standard V4L2 vidioc_int_g_ifparm_num ioctl structure
+ *
+ * Gets slave interface parameters.
+ * Calculates the required xclk value to support the requested
+ * clock parameters in p. This value is returned in the p
+ * parameter.
+ *
+ * vidioc_int_g_ifparm returns platform-specific information about the
+ * interface settings used by the sensor.
+ *
+ * Called on open.
+ */
+static int ioctl_g_ifparm(struct v4l2_int_device *s, struct v4l2_ifparm *p)
+{
+ dev_dbg(&adv7180_data.sen.i2c_client->dev, "adv7180:ioctl_g_ifparm\n");
+
+ if (s == NULL) {
+ pr_err(" ERROR!! no slave device set!\n");
+ return -1;
+ }
+
+ /* Initialize structure to 0s then set any non-0 values. */
+ memset(p, 0, sizeof(*p));
+ p->if_type = V4L2_IF_TYPE_BT656; /* This is the only possibility. */
+ p->u.bt656.mode = V4L2_IF_TYPE_BT656_MODE_NOBT_8BIT;
+ p->u.bt656.nobt_hs_inv = 1;
+ p->u.bt656.bt_sync_correct = 1;
+
+ /* ADV7180 has a dedicated clock so no clock settings needed. */
+
+ return 0;
+}
+
+/*!
+ * Sets the camera power.
+ *
+ * s pointer to the camera device
+ * on if 1, power is to be turned on. 0 means power is to be turned off
+ *
+ * ioctl_s_power - V4L2 sensor interface handler for vidioc_int_s_power_num
+ * @s: pointer to standard V4L2 device structure
+ * @on: power state to which device is to be set
+ *
+ * Sets devices power state to requrested state, if possible.
+ * This is called on open, close, suspend and resume.
+ */
+static int ioctl_s_power(struct v4l2_int_device *s, int on)
+{
+ struct sensor *sensor = s->priv;
+
+ dev_dbg(&adv7180_data.sen.i2c_client->dev, "adv7180:ioctl_s_power\n");
+
+ if (on && !sensor->sen.on) {
+ if (adv7180_write_reg(ADV7180_PWR_MNG, 0x04) != 0)
+ return -EIO;
+
+ /*
+ * FIXME:Additional 400ms to wait the chip to be stable?
+ * This is a workaround for preview scrolling issue.
+ */
+ msleep(400);
+ } else if (!on && sensor->sen.on) {
+ if (adv7180_write_reg(ADV7180_PWR_MNG, 0x24) != 0)
+ return -EIO;
+ }
+
+ sensor->sen.on = on;
+
+ return 0;
+}
+
+/*!
+ * ioctl_g_parm - V4L2 sensor interface handler for VIDIOC_G_PARM ioctl
+ * @s: pointer to standard V4L2 device structure
+ * @a: pointer to standard V4L2 VIDIOC_G_PARM ioctl structure
+ *
+ * Returns the sensor's video CAPTURE parameters.
+ */
+static int ioctl_g_parm(struct v4l2_int_device *s, struct v4l2_streamparm *a)
+{
+ struct sensor *sensor = s->priv;
+ struct v4l2_captureparm *cparm = &a->parm.capture;
+
+ dev_dbg(&adv7180_data.sen.i2c_client->dev, "In adv7180:ioctl_g_parm\n");
+
+ switch (a->type) {
+ /* These are all the possible cases. */
+ case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+ pr_debug(" type is V4L2_BUF_TYPE_VIDEO_CAPTURE\n");
+ memset(a, 0, sizeof(*a));
+ a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ cparm->capability = sensor->sen.streamcap.capability;
+ cparm->timeperframe = sensor->sen.streamcap.timeperframe;
+ cparm->capturemode = sensor->sen.streamcap.capturemode;
+ break;
+
+ case V4L2_BUF_TYPE_VIDEO_OUTPUT:
+ case V4L2_BUF_TYPE_VIDEO_OVERLAY:
+ case V4L2_BUF_TYPE_VBI_CAPTURE:
+ case V4L2_BUF_TYPE_VBI_OUTPUT:
+ case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
+ case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
+ break;
+
+ default:
+ pr_debug("ioctl_g_parm:type is unknown %d\n", a->type);
+ break;
+ }
+
+ return 0;
+}
+
+/*!
+ * ioctl_s_parm - V4L2 sensor interface handler for VIDIOC_S_PARM ioctl
+ * @s: pointer to standard V4L2 device structure
+ * @a: pointer to standard V4L2 VIDIOC_S_PARM ioctl structure
+ *
+ * Configures the sensor to use the input parameters, if possible. If
+ * not possible, reverts to the old parameters and returns the
+ * appropriate error code.
+ *
+ * This driver cannot change these settings.
+ */
+static int ioctl_s_parm(struct v4l2_int_device *s, struct v4l2_streamparm *a)
+{
+ dev_dbg(&adv7180_data.sen.i2c_client->dev, "In adv7180:ioctl_s_parm\n");
+
+ switch (a->type) {
+ /* These are all the possible cases. */
+ case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+ case V4L2_BUF_TYPE_VIDEO_OUTPUT:
+ case V4L2_BUF_TYPE_VIDEO_OVERLAY:
+ case V4L2_BUF_TYPE_VBI_CAPTURE:
+ case V4L2_BUF_TYPE_VBI_OUTPUT:
+ case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
+ case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
+ break;
+
+ default:
+ pr_debug(" type is unknown - %d\n", a->type);
+ break;
+ }
+
+ return 0;
+}
+
+/*!
+ * ioctl_g_fmt_cap - V4L2 sensor interface handler for ioctl_g_fmt_cap
+ * @s: pointer to standard V4L2 device structure
+ * @f: pointer to standard V4L2 v4l2_format structure
+ *
+ * Returns the sensor's current pixel format in the v4l2_format
+ * parameter.
+ */
+static int ioctl_g_fmt_cap(struct v4l2_int_device *s, struct v4l2_format *f)
+{
+ struct sensor *sensor = s->priv;
+
+ dev_dbg(&adv7180_data.sen.i2c_client->dev, "adv7180:ioctl_g_fmt_cap\n");
+
+ switch (f->type) {
+ case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+ pr_debug(" Returning size of %dx%d\n",
+ sensor->sen.pix.width, sensor->sen.pix.height);
+ f->fmt.pix = sensor->sen.pix;
+ break;
+
+ case V4L2_BUF_TYPE_PRIVATE: {
+ v4l2_std_id std;
+ adv7180_get_std(&std);
+ f->fmt.pix.pixelformat = (u32)std;
+ }
+ break;
+
+ default:
+ f->fmt.pix = sensor->sen.pix;
+ break;
+ }
+
+ return 0;
+}
+
+/*!
+ * ioctl_queryctrl - V4L2 sensor interface handler for VIDIOC_QUERYCTRL ioctl
+ * @s: pointer to standard V4L2 device structure
+ * @qc: standard V4L2 VIDIOC_QUERYCTRL ioctl structure
+ *
+ * If the requested control is supported, returns the control information
+ * from the video_control[] array. Otherwise, returns -EINVAL if the
+ * control is not supported.
+ */
+static int ioctl_queryctrl(struct v4l2_int_device *s,
+ struct v4l2_queryctrl *qc)
+{
+ int i;
+
+ dev_dbg(&adv7180_data.sen.i2c_client->dev, "adv7180:ioctl_queryctrl\n");
+
+ for (i = 0; i < ARRAY_SIZE(adv7180_qctrl); i++)
+ if (qc->id && qc->id == adv7180_qctrl[i].id) {
+ memcpy(qc, &(adv7180_qctrl[i]),
+ sizeof(*qc));
+ return 0;
+ }
+
+ return -EINVAL;
+}
+
+/*!
+ * ioctl_g_ctrl - V4L2 sensor interface handler for VIDIOC_G_CTRL ioctl
+ * @s: pointer to standard V4L2 device structure
+ * @vc: standard V4L2 VIDIOC_G_CTRL ioctl structure
+ *
+ * If the requested control is supported, returns the control's current
+ * value from the video_control[] array. Otherwise, returns -EINVAL
+ * if the control is not supported.
+ */
+static int ioctl_g_ctrl(struct v4l2_int_device *s, struct v4l2_control *vc)
+{
+ int ret = 0;
+ int sat = 0;
+
+ dev_dbg(&adv7180_data.sen.i2c_client->dev, "In adv7180:ioctl_g_ctrl\n");
+
+ switch (vc->id) {
+ case V4L2_CID_BRIGHTNESS:
+ dev_dbg(&adv7180_data.sen.i2c_client->dev,
+ " V4L2_CID_BRIGHTNESS\n");
+ adv7180_data.sen.brightness = adv7180_read(ADV7180_BRIGHTNESS);
+ vc->value = adv7180_data.sen.brightness;
+ break;
+ case V4L2_CID_CONTRAST:
+ dev_dbg(&adv7180_data.sen.i2c_client->dev,
+ " V4L2_CID_CONTRAST\n");
+ vc->value = adv7180_data.sen.contrast;
+ break;
+ case V4L2_CID_SATURATION:
+ dev_dbg(&adv7180_data.sen.i2c_client->dev,
+ " V4L2_CID_SATURATION\n");
+ sat = adv7180_read(ADV7180_SD_SATURATION_CB);
+ adv7180_data.sen.saturation = sat;
+ vc->value = adv7180_data.sen.saturation;
+ break;
+ case V4L2_CID_HUE:
+ dev_dbg(&adv7180_data.sen.i2c_client->dev,
+ " V4L2_CID_HUE\n");
+ vc->value = adv7180_data.sen.hue;
+ break;
+ case V4L2_CID_AUTO_WHITE_BALANCE:
+ dev_dbg(&adv7180_data.sen.i2c_client->dev,
+ " V4L2_CID_AUTO_WHITE_BALANCE\n");
+ break;
+ case V4L2_CID_DO_WHITE_BALANCE:
+ dev_dbg(&adv7180_data.sen.i2c_client->dev,
+ " V4L2_CID_DO_WHITE_BALANCE\n");
+ break;
+ case V4L2_CID_RED_BALANCE:
+ dev_dbg(&adv7180_data.sen.i2c_client->dev,
+ " V4L2_CID_RED_BALANCE\n");
+ vc->value = adv7180_data.sen.red;
+ break;
+ case V4L2_CID_BLUE_BALANCE:
+ dev_dbg(&adv7180_data.sen.i2c_client->dev,
+ " V4L2_CID_BLUE_BALANCE\n");
+ vc->value = adv7180_data.sen.blue;
+ break;
+ case V4L2_CID_GAMMA:
+ dev_dbg(&adv7180_data.sen.i2c_client->dev,
+ " V4L2_CID_GAMMA\n");
+ break;
+ case V4L2_CID_EXPOSURE:
+ dev_dbg(&adv7180_data.sen.i2c_client->dev,
+ " V4L2_CID_EXPOSURE\n");
+ vc->value = adv7180_data.sen.ae_mode;
+ break;
+ case V4L2_CID_AUTOGAIN:
+ dev_dbg(&adv7180_data.sen.i2c_client->dev,
+ " V4L2_CID_AUTOGAIN\n");
+ break;
+ case V4L2_CID_GAIN:
+ dev_dbg(&adv7180_data.sen.i2c_client->dev,
+ " V4L2_CID_GAIN\n");
+ break;
+ case V4L2_CID_HFLIP:
+ dev_dbg(&adv7180_data.sen.i2c_client->dev,
+ " V4L2_CID_HFLIP\n");
+ break;
+ case V4L2_CID_VFLIP:
+ dev_dbg(&adv7180_data.sen.i2c_client->dev,
+ " V4L2_CID_VFLIP\n");
+ break;
+ default:
+ dev_dbg(&adv7180_data.sen.i2c_client->dev,
+ " Default case\n");
+ vc->value = 0;
+ ret = -EPERM;
+ break;
+ }
+
+ return ret;
+}
+
+/*!
+ * ioctl_s_ctrl - V4L2 sensor interface handler for VIDIOC_S_CTRL ioctl
+ * @s: pointer to standard V4L2 device structure
+ * @vc: standard V4L2 VIDIOC_S_CTRL ioctl structure
+ *
+ * If the requested control is supported, sets the control's current
+ * value in HW (and updates the video_control[] array). Otherwise,
+ * returns -EINVAL if the control is not supported.
+ */
+static int ioctl_s_ctrl(struct v4l2_int_device *s, struct v4l2_control *vc)
+{
+ int retval = 0;
+ u8 tmp;
+
+ dev_dbg(&adv7180_data.sen.i2c_client->dev, "In adv7180:ioctl_s_ctrl\n");
+
+ switch (vc->id) {
+ case V4L2_CID_BRIGHTNESS:
+ dev_dbg(&adv7180_data.sen.i2c_client->dev,
+ " V4L2_CID_BRIGHTNESS\n");
+ tmp = vc->value;
+ adv7180_write_reg(ADV7180_BRIGHTNESS, tmp);
+ adv7180_data.sen.brightness = vc->value;
+ break;
+ case V4L2_CID_CONTRAST:
+ dev_dbg(&adv7180_data.sen.i2c_client->dev,
+ " V4L2_CID_CONTRAST\n");
+ break;
+ case V4L2_CID_SATURATION:
+ dev_dbg(&adv7180_data.sen.i2c_client->dev,
+ " V4L2_CID_SATURATION\n");
+ tmp = vc->value;
+ adv7180_write_reg(ADV7180_SD_SATURATION_CB, tmp);
+ adv7180_write_reg(ADV7180_SD_SATURATION_CR, tmp);
+ adv7180_data.sen.saturation = vc->value;
+ break;
+ case V4L2_CID_HUE:
+ dev_dbg(&adv7180_data.sen.i2c_client->dev,
+ " V4L2_CID_HUE\n");
+ break;
+ case V4L2_CID_AUTO_WHITE_BALANCE:
+ dev_dbg(&adv7180_data.sen.i2c_client->dev,
+ " V4L2_CID_AUTO_WHITE_BALANCE\n");
+ break;
+ case V4L2_CID_DO_WHITE_BALANCE:
+ dev_dbg(&adv7180_data.sen.i2c_client->dev,
+ " V4L2_CID_DO_WHITE_BALANCE\n");
+ break;
+ case V4L2_CID_RED_BALANCE:
+ dev_dbg(&adv7180_data.sen.i2c_client->dev,
+ " V4L2_CID_RED_BALANCE\n");
+ break;
+ case V4L2_CID_BLUE_BALANCE:
+ dev_dbg(&adv7180_data.sen.i2c_client->dev,
+ " V4L2_CID_BLUE_BALANCE\n");
+ break;
+ case V4L2_CID_GAMMA:
+ dev_dbg(&adv7180_data.sen.i2c_client->dev,
+ " V4L2_CID_GAMMA\n");
+ break;
+ case V4L2_CID_EXPOSURE:
+ dev_dbg(&adv7180_data.sen.i2c_client->dev,
+ " V4L2_CID_EXPOSURE\n");
+ break;
+ case V4L2_CID_AUTOGAIN:
+ dev_dbg(&adv7180_data.sen.i2c_client->dev,
+ " V4L2_CID_AUTOGAIN\n");
+ break;
+ case V4L2_CID_GAIN:
+ dev_dbg(&adv7180_data.sen.i2c_client->dev,
+ " V4L2_CID_GAIN\n");
+ break;
+ case V4L2_CID_HFLIP:
+ dev_dbg(&adv7180_data.sen.i2c_client->dev,
+ " V4L2_CID_HFLIP\n");
+ break;
+ case V4L2_CID_VFLIP:
+ dev_dbg(&adv7180_data.sen.i2c_client->dev,
+ " V4L2_CID_VFLIP\n");
+ break;
+ default:
+ dev_dbg(&adv7180_data.sen.i2c_client->dev,
+ " Default case\n");
+ retval = -EPERM;
+ break;
+ }
+
+ return retval;
+}
+
+/*!
+ * ioctl_enum_framesizes - V4L2 sensor interface handler for
+ * VIDIOC_ENUM_FRAMESIZES ioctl
+ * @s: pointer to standard V4L2 device structure
+ * @fsize: standard V4L2 VIDIOC_ENUM_FRAMESIZES ioctl structure
+ *
+ * Return 0 if successful, otherwise -EINVAL.
+ */
+static int ioctl_enum_framesizes(struct v4l2_int_device *s,
+ struct v4l2_frmsizeenum *fsize)
+{
+ if (fsize->index >= 1)
+ return -EINVAL;
+
+ fsize->discrete.width = video_fmts[video_idx].active_width;
+ fsize->discrete.height = video_fmts[video_idx].active_height;
+
+ return 0;
+}
+
+/*!
+ * ioctl_enum_frameintervals - V4L2 sensor interface handler for
+ * VIDIOC_ENUM_FRAMEINTERVALS ioctl
+ * @s: pointer to standard V4L2 device structure
+ * @fival: standard V4L2 VIDIOC_ENUM_FRAMEINTERVALS ioctl structure
+ *
+ * Return 0 if successful, otherwise -EINVAL.
+ */
+static int ioctl_enum_frameintervals(struct v4l2_int_device *s,
+ struct v4l2_frmivalenum *fival)
+{
+ video_fmt_t fmt;
+ int i;
+
+ if (fival->index != 0)
+ return -EINVAL;
+
+ for (i = 0; i < ARRAY_SIZE(video_fmts) - 1; i++) {
+ fmt = video_fmts[i];
+ if (fival->width == fmt.active_width &&
+ fival->height == fmt.active_height) {
+ fival->type = V4L2_FRMIVAL_TYPE_DISCRETE;
+ fival->discrete.numerator = 1;
+ fival->discrete.denominator = fmt.frame_rate;
+ return 0;
+ }
+ }
+
+ return -EINVAL;
+}
+
+/*!
+ * ioctl_g_chip_ident - V4L2 sensor interface handler for
+ * VIDIOC_DBG_G_CHIP_IDENT ioctl
+ * @s: pointer to standard V4L2 device structure
+ * @id: pointer to int
+ *
+ * Return 0.
+ */
+static int ioctl_g_chip_ident(struct v4l2_int_device *s, int *id)
+{
+ ((struct v4l2_dbg_chip_ident *)id)->match.type =
+ V4L2_CHIP_MATCH_I2C_DRIVER;
+ strcpy(((struct v4l2_dbg_chip_ident *)id)->match.name,
+ "adv7180_decoder");
+ ((struct v4l2_dbg_chip_ident *)id)->ident = V4L2_IDENT_ADV7180;
+
+ return 0;
+}
+
+/*!
+ * ioctl_init - V4L2 sensor interface handler for VIDIOC_INT_INIT
+ * @s: pointer to standard V4L2 device structure
+ */
+static int ioctl_init(struct v4l2_int_device *s)
+{
+ dev_dbg(&adv7180_data.sen.i2c_client->dev, "In adv7180:ioctl_init\n");
+ return 0;
+}
+
+/*!
+ * ioctl_dev_init - V4L2 sensor interface handler for vidioc_int_dev_init_num
+ * @s: pointer to standard V4L2 device structure
+ *
+ * Initialise the device when slave attaches to the master.
+ */
+static int ioctl_dev_init(struct v4l2_int_device *s)
+{
+ dev_dbg(&adv7180_data.sen.i2c_client->dev, "adv7180:ioctl_dev_init\n");
+ return 0;
+}
+
+/*!
+ * This structure defines all the ioctls for this module.
+ */
+static struct v4l2_int_ioctl_desc adv7180_ioctl_desc[] = {
+
+ {vidioc_int_dev_init_num, (v4l2_int_ioctl_func*)ioctl_dev_init},
+
+ /*!
+ * Delinitialise the dev. at slave detach.
+ * The complement of ioctl_dev_init.
+ */
+/* {vidioc_int_dev_exit_num, (v4l2_int_ioctl_func *)ioctl_dev_exit}, */
+
+ {vidioc_int_s_power_num, (v4l2_int_ioctl_func*)ioctl_s_power},
+ {vidioc_int_g_ifparm_num, (v4l2_int_ioctl_func*)ioctl_g_ifparm},
+/* {vidioc_int_g_needs_reset_num,
+ (v4l2_int_ioctl_func *)ioctl_g_needs_reset}, */
+/* {vidioc_int_reset_num, (v4l2_int_ioctl_func *)ioctl_reset}, */
+ {vidioc_int_init_num, (v4l2_int_ioctl_func*)ioctl_init},
+
+ /*!
+ * VIDIOC_ENUM_FMT ioctl for the CAPTURE buffer type.
+ */
+/* {vidioc_int_enum_fmt_cap_num,
+ (v4l2_int_ioctl_func *)ioctl_enum_fmt_cap}, */
+
+ /*!
+ * VIDIOC_TRY_FMT ioctl for the CAPTURE buffer type.
+ * This ioctl is used to negotiate the image capture size and
+ * pixel format without actually making it take effect.
+ */
+/* {vidioc_int_try_fmt_cap_num,
+ (v4l2_int_ioctl_func *)ioctl_try_fmt_cap}, */
+
+ {vidioc_int_g_fmt_cap_num, (v4l2_int_ioctl_func*)ioctl_g_fmt_cap},
+
+ /*!
+ * If the requested format is supported, configures the HW to use that
+ * format, returns error code if format not supported or HW can't be
+ * correctly configured.
+ */
+/* {vidioc_int_s_fmt_cap_num, (v4l2_int_ioctl_func *)ioctl_s_fmt_cap}, */
+
+ {vidioc_int_g_parm_num, (v4l2_int_ioctl_func*)ioctl_g_parm},
+ {vidioc_int_s_parm_num, (v4l2_int_ioctl_func*)ioctl_s_parm},
+ {vidioc_int_queryctrl_num, (v4l2_int_ioctl_func*)ioctl_queryctrl},
+ {vidioc_int_g_ctrl_num, (v4l2_int_ioctl_func*)ioctl_g_ctrl},
+ {vidioc_int_s_ctrl_num, (v4l2_int_ioctl_func*)ioctl_s_ctrl},
+ {vidioc_int_enum_framesizes_num,
+ (v4l2_int_ioctl_func *)ioctl_enum_framesizes},
+ {vidioc_int_enum_frameintervals_num,
+ (v4l2_int_ioctl_func *)
+ ioctl_enum_frameintervals},
+ {vidioc_int_g_chip_ident_num,
+ (v4l2_int_ioctl_func *)ioctl_g_chip_ident},
+};
+
+static struct v4l2_int_slave adv7180_slave = {
+ .ioctls = adv7180_ioctl_desc,
+ .num_ioctls = ARRAY_SIZE(adv7180_ioctl_desc),
+};
+
+static struct v4l2_int_device adv7180_int_device = {
+ .module = THIS_MODULE,
+ .name = "adv7180",
+ .type = v4l2_int_type_slave,
+ .u = {
+ .slave = &adv7180_slave,
+ },
+};
+
+
+/***********************************************************************
+ * I2C client and driver.
+ ***********************************************************************/
+
+/*! ADV7180 Reset function.
+ *
+ * @return None.
+ */
+static void adv7180_hard_reset(bool cvbs)
+{
+ dev_dbg(&adv7180_data.sen.i2c_client->dev,
+ "In adv7180:adv7180_hard_reset\n");
+
+ if (cvbs) {
+ /* Set CVBS input on AIN1 */
+ adv7180_write_reg(ADV7180_INPUT_CTL, 0x00);
+ } else {
+ /*
+ * Set YPbPr input on AIN1,4,5 and normal
+ * operations(autodection of all stds).
+ */
+ adv7180_write_reg(ADV7180_INPUT_CTL, 0x09);
+ }
+
+ /* Datasheet recommends */
+ adv7180_write_reg(0x01, 0xc8);
+ adv7180_write_reg(0x02, 0x04);
+ adv7180_write_reg(0x03, 0x00);
+ adv7180_write_reg(0x04, 0x45);
+ adv7180_write_reg(0x05, 0x00);
+ adv7180_write_reg(0x06, 0x02);
+ adv7180_write_reg(0x07, 0x7F);
+ adv7180_write_reg(0x08, 0x80);
+ adv7180_write_reg(0x0A, 0x00);
+ adv7180_write_reg(0x0B, 0x00);
+ adv7180_write_reg(0x0C, 0x36);
+ adv7180_write_reg(0x0D, 0x7C);
+ adv7180_write_reg(0x0E, 0x00);
+ adv7180_write_reg(0x0F, 0x00);
+ adv7180_write_reg(0x13, 0x00);
+ adv7180_write_reg(0x14, 0x12);
+ adv7180_write_reg(0x15, 0x00);
+ adv7180_write_reg(0x16, 0x00);
+ adv7180_write_reg(0x17, 0x01);
+ adv7180_write_reg(0x18, 0x93);
+ adv7180_write_reg(0xF1, 0x19);
+ adv7180_write_reg(0x1A, 0x00);
+ adv7180_write_reg(0x1B, 0x00);
+ adv7180_write_reg(0x1C, 0x00);
+ adv7180_write_reg(0x1D, 0x40);
+ adv7180_write_reg(0x1E, 0x00);
+ adv7180_write_reg(0x1F, 0x00);
+ adv7180_write_reg(0x20, 0x00);
+ adv7180_write_reg(0x21, 0x00);
+ adv7180_write_reg(0x22, 0x00);
+ adv7180_write_reg(0x23, 0xC0);
+ adv7180_write_reg(0x24, 0x00);
+ adv7180_write_reg(0x25, 0x00);
+ adv7180_write_reg(0x26, 0x00);
+ adv7180_write_reg(0x27, 0x58);
+ adv7180_write_reg(0x28, 0x00);
+ adv7180_write_reg(0x29, 0x00);
+ adv7180_write_reg(0x2A, 0x00);
+ adv7180_write_reg(0x2B, 0xE1);
+ adv7180_write_reg(0x2C, 0xAE);
+ adv7180_write_reg(0x2D, 0xF4);
+ adv7180_write_reg(0x2E, 0x00);
+ adv7180_write_reg(0x2F, 0xF0);
+ adv7180_write_reg(0x30, 0x00);
+ adv7180_write_reg(0x31, 0x12);
+ adv7180_write_reg(0x32, 0x41);
+ adv7180_write_reg(0x33, 0x84);
+ adv7180_write_reg(0x34, 0x00);
+ adv7180_write_reg(0x35, 0x02);
+ adv7180_write_reg(0x36, 0x00);
+ adv7180_write_reg(0x37, 0x01);
+ adv7180_write_reg(0x38, 0x80);
+ adv7180_write_reg(0x39, 0xC0);
+ adv7180_write_reg(0x3A, 0x10);
+ adv7180_write_reg(0x3B, 0x05);
+ adv7180_write_reg(0x3C, 0x58);
+ adv7180_write_reg(0x3D, 0xB2);
+ adv7180_write_reg(0x3E, 0x64);
+ adv7180_write_reg(0x3F, 0xE4);
+ adv7180_write_reg(0x40, 0x90);
+ adv7180_write_reg(0x41, 0x01);
+ adv7180_write_reg(0x42, 0x7E);
+ adv7180_write_reg(0x43, 0xA4);
+ adv7180_write_reg(0x44, 0xFF);
+ adv7180_write_reg(0x45, 0xB6);
+ adv7180_write_reg(0x46, 0x12);
+ adv7180_write_reg(0x48, 0x00);
+ adv7180_write_reg(0x49, 0x00);
+ adv7180_write_reg(0x4A, 0x00);
+ adv7180_write_reg(0x4B, 0x00);
+ adv7180_write_reg(0x4C, 0x00);
+ adv7180_write_reg(0x4D, 0xEF);
+ adv7180_write_reg(0x4E, 0x08);
+ adv7180_write_reg(0x4F, 0x08);
+ adv7180_write_reg(0x50, 0x08);
+ adv7180_write_reg(0x51, 0x24);
+ adv7180_write_reg(0x52, 0x0B);
+ adv7180_write_reg(0x53, 0x4E);
+ adv7180_write_reg(0x54, 0x80);
+ adv7180_write_reg(0x55, 0x00);
+ adv7180_write_reg(0x56, 0x10);
+ adv7180_write_reg(0x57, 0x00);
+ adv7180_write_reg(0x58, 0x00);
+ adv7180_write_reg(0x59, 0x00);
+ adv7180_write_reg(0x5A, 0x00);
+ adv7180_write_reg(0x5B, 0x00);
+ adv7180_write_reg(0x5C, 0x00);
+ adv7180_write_reg(0x5D, 0x00);
+ adv7180_write_reg(0x5E, 0x00);
+ adv7180_write_reg(0x5F, 0x00);
+ adv7180_write_reg(0x60, 0x00);
+ adv7180_write_reg(0x61, 0x00);
+ adv7180_write_reg(0x62, 0x20);
+ adv7180_write_reg(0x63, 0x00);
+ adv7180_write_reg(0x64, 0x00);
+ adv7180_write_reg(0x65, 0x00);
+ adv7180_write_reg(0x66, 0x00);
+ adv7180_write_reg(0x67, 0x03);
+ adv7180_write_reg(0x68, 0x01);
+ adv7180_write_reg(0x69, 0x00);
+ adv7180_write_reg(0x6A, 0x00);
+ adv7180_write_reg(0x6B, 0xC0);
+ adv7180_write_reg(0x6C, 0x00);
+ adv7180_write_reg(0x6D, 0x00);
+ adv7180_write_reg(0x6E, 0x00);
+ adv7180_write_reg(0x6F, 0x00);
+ adv7180_write_reg(0x70, 0x00);
+ adv7180_write_reg(0x71, 0x00);
+ adv7180_write_reg(0x72, 0x00);
+ adv7180_write_reg(0x73, 0x10);
+ adv7180_write_reg(0x74, 0x04);
+ adv7180_write_reg(0x75, 0x01);
+ adv7180_write_reg(0x76, 0x00);
+ adv7180_write_reg(0x77, 0x3F);
+ adv7180_write_reg(0x78, 0xFF);
+ adv7180_write_reg(0x79, 0xFF);
+ adv7180_write_reg(0x7A, 0xFF);
+ adv7180_write_reg(0x7B, 0x1E);
+ adv7180_write_reg(0x7C, 0xC0);
+ adv7180_write_reg(0x7D, 0x00);
+ adv7180_write_reg(0x7E, 0x00);
+ adv7180_write_reg(0x7F, 0x00);
+ adv7180_write_reg(0x80, 0x00);
+ adv7180_write_reg(0x81, 0xC0);
+ adv7180_write_reg(0x82, 0x04);
+ adv7180_write_reg(0x83, 0x00);
+ adv7180_write_reg(0x84, 0x0C);
+ adv7180_write_reg(0x85, 0x02);
+ adv7180_write_reg(0x86, 0x03);
+ adv7180_write_reg(0x87, 0x63);
+ adv7180_write_reg(0x88, 0x5A);
+ adv7180_write_reg(0x89, 0x08);
+ adv7180_write_reg(0x8A, 0x10);
+ adv7180_write_reg(0x8B, 0x00);
+ adv7180_write_reg(0x8C, 0x40);
+ adv7180_write_reg(0x8D, 0x00);
+ adv7180_write_reg(0x8E, 0x40);
+ adv7180_write_reg(0x8F, 0x00);
+ adv7180_write_reg(0x90, 0x00);
+ adv7180_write_reg(0x91, 0x50);
+ adv7180_write_reg(0x92, 0x00);
+ adv7180_write_reg(0x93, 0x00);
+ adv7180_write_reg(0x94, 0x00);
+ adv7180_write_reg(0x95, 0x00);
+ adv7180_write_reg(0x96, 0x00);
+ adv7180_write_reg(0x97, 0xF0);
+ adv7180_write_reg(0x98, 0x00);
+ adv7180_write_reg(0x99, 0x00);
+ adv7180_write_reg(0x9A, 0x00);
+ adv7180_write_reg(0x9B, 0x00);
+ adv7180_write_reg(0x9C, 0x00);
+ adv7180_write_reg(0x9D, 0x00);
+ adv7180_write_reg(0x9E, 0x00);
+ adv7180_write_reg(0x9F, 0x00);
+ adv7180_write_reg(0xA0, 0x00);
+ adv7180_write_reg(0xA1, 0x00);
+ adv7180_write_reg(0xA2, 0x00);
+ adv7180_write_reg(0xA3, 0x00);
+ adv7180_write_reg(0xA4, 0x00);
+ adv7180_write_reg(0xA5, 0x00);
+ adv7180_write_reg(0xA6, 0x00);
+ adv7180_write_reg(0xA7, 0x00);
+ adv7180_write_reg(0xA8, 0x00);
+ adv7180_write_reg(0xA9, 0x00);
+ adv7180_write_reg(0xAA, 0x00);
+ adv7180_write_reg(0xAB, 0x00);
+ adv7180_write_reg(0xAC, 0x00);
+ adv7180_write_reg(0xAD, 0x00);
+ adv7180_write_reg(0xAE, 0x60);
+ adv7180_write_reg(0xAF, 0x00);
+ adv7180_write_reg(0xB0, 0x00);
+ adv7180_write_reg(0xB1, 0x60);
+ adv7180_write_reg(0xB2, 0x1C);
+ adv7180_write_reg(0xB3, 0x54);
+ adv7180_write_reg(0xB4, 0x00);
+ adv7180_write_reg(0xB5, 0x00);
+ adv7180_write_reg(0xB6, 0x00);
+ adv7180_write_reg(0xB7, 0x13);
+ adv7180_write_reg(0xB8, 0x03);
+ adv7180_write_reg(0xB9, 0x33);
+ adv7180_write_reg(0xBF, 0x02);
+ adv7180_write_reg(0xC0, 0x00);
+ adv7180_write_reg(0xC1, 0x00);
+ adv7180_write_reg(0xC2, 0x00);
+ adv7180_write_reg(0xC3, 0x00);
+ adv7180_write_reg(0xC4, 0x00);
+ adv7180_write_reg(0xC5, 0x81);
+ adv7180_write_reg(0xC6, 0x00);
+ adv7180_write_reg(0xC7, 0x00);
+ adv7180_write_reg(0xC8, 0x00);
+ adv7180_write_reg(0xC9, 0x04);
+ adv7180_write_reg(0xCC, 0x69);
+ adv7180_write_reg(0xCD, 0x00);
+ adv7180_write_reg(0xCE, 0x01);
+ adv7180_write_reg(0xCF, 0xB4);
+ adv7180_write_reg(0xD0, 0x00);
+ adv7180_write_reg(0xD1, 0x10);
+ adv7180_write_reg(0xD2, 0xFF);
+ adv7180_write_reg(0xD3, 0xFF);
+ adv7180_write_reg(0xD4, 0x7F);
+ adv7180_write_reg(0xD5, 0x7F);
+ adv7180_write_reg(0xD6, 0x3E);
+ adv7180_write_reg(0xD7, 0x08);
+ adv7180_write_reg(0xD8, 0x3C);
+ adv7180_write_reg(0xD9, 0x08);
+ adv7180_write_reg(0xDA, 0x3C);
+ adv7180_write_reg(0xDB, 0x9B);
+ adv7180_write_reg(0xDC, 0xAC);
+ adv7180_write_reg(0xDD, 0x4C);
+ adv7180_write_reg(0xDE, 0x00);
+ adv7180_write_reg(0xDF, 0x00);
+ adv7180_write_reg(0xE0, 0x14);
+ adv7180_write_reg(0xE1, 0x80);
+ adv7180_write_reg(0xE2, 0x80);
+ adv7180_write_reg(0xE3, 0x80);
+ adv7180_write_reg(0xE4, 0x80);
+ adv7180_write_reg(0xE5, 0x25);
+ adv7180_write_reg(0xE6, 0x44);
+ adv7180_write_reg(0xE7, 0x63);
+ adv7180_write_reg(0xE8, 0x65);
+ adv7180_write_reg(0xE9, 0x14);
+ adv7180_write_reg(0xEA, 0x63);
+ adv7180_write_reg(0xEB, 0x55);
+ adv7180_write_reg(0xEC, 0x55);
+ adv7180_write_reg(0xEE, 0x00);
+ adv7180_write_reg(0xEF, 0x4A);
+ adv7180_write_reg(0xF0, 0x44);
+ adv7180_write_reg(0xF1, 0x0C);
+ adv7180_write_reg(0xF2, 0x32);
+ adv7180_write_reg(0xF3, 0x00);
+ adv7180_write_reg(0xF4, 0x3F);
+ adv7180_write_reg(0xF5, 0xE0);
+ adv7180_write_reg(0xF6, 0x69);
+ adv7180_write_reg(0xF7, 0x10);
+ adv7180_write_reg(0xF8, 0x00);
+ adv7180_write_reg(0xF9, 0x03);
+ adv7180_write_reg(0xFA, 0xFA);
+ adv7180_write_reg(0xFB, 0x40);
+}
+
+/*! ADV7180 I2C attach function.
+ *
+ * @param *adapter struct i2c_adapter *.
+ *
+ * @return Error code indicating success or failure.
+ */
+
+/*!
+ * ADV7180 I2C probe function.
+ * Function set in i2c_driver struct.
+ * Called by insmod.
+ *
+ * @param *adapter I2C adapter descriptor.
+ *
+ * @return Error code indicating success or failure.
+ */
+static int adv7180_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ int rev_id;
+ int ret = 0;
+ u32 cvbs = true;
+ struct pinctrl *pinctrl;
+ struct device *dev = &client->dev;
+
+ printk(KERN_ERR"DBG sensor data is at %p\n", &adv7180_data);
+
+ /* ov5640 pinctrl */
+ pinctrl = devm_pinctrl_get_select_default(dev);
+ if (IS_ERR(pinctrl)) {
+ dev_err(dev, "setup pinctrl failed\n");
+ return PTR_ERR(pinctrl);
+ }
+
+ /* request power down pin */
+ pwn_gpio = of_get_named_gpio(dev->of_node, "pwn-gpios", 0);
+ if (!gpio_is_valid(pwn_gpio)) {
+ dev_err(dev, "no sensor pwdn pin available\n");
+ return -ENODEV;
+ }
+ ret = devm_gpio_request_one(dev, pwn_gpio, GPIOF_OUT_INIT_HIGH,
+ "adv7180_pwdn");
+ if (ret < 0) {
+ dev_err(dev, "no power pin available!\n");
+ return ret;
+ }
+
+ adv7180_regulator_enable(dev);
+
+ adv7180_power_down(0);
+
+ msleep(1);
+
+ /* Set initial values for the sensor struct. */
+ memset(&adv7180_data, 0, sizeof(adv7180_data));
+ adv7180_data.sen.i2c_client = client;
+ adv7180_data.sen.streamcap.timeperframe.denominator = 30;
+ adv7180_data.sen.streamcap.timeperframe.numerator = 1;
+ adv7180_data.std_id = V4L2_STD_ALL;
+ video_idx = ADV7180_NOT_LOCKED;
+ adv7180_data.sen.pix.width = video_fmts[video_idx].raw_width;
+ adv7180_data.sen.pix.height = video_fmts[video_idx].raw_height;
+ adv7180_data.sen.pix.pixelformat = V4L2_PIX_FMT_UYVY; /* YUV422 */
+ adv7180_data.sen.pix.priv = 1; /* 1 is used to indicate TV in */
+ adv7180_data.sen.on = true;
+
+ adv7180_data.sen.sensor_clk = devm_clk_get(dev, "csi_mclk");
+ if (IS_ERR(adv7180_data.sen.sensor_clk)) {
+ dev_err(dev, "get mclk failed\n");
+ return PTR_ERR(adv7180_data.sen.sensor_clk);
+ }
+
+ ret = of_property_read_u32(dev->of_node, "mclk",
+ &adv7180_data.sen.mclk);
+ if (ret) {
+ dev_err(dev, "mclk frequency is invalid\n");
+ return ret;
+ }
+
+ ret = of_property_read_u32(
+ dev->of_node, "mclk_source",
+ (u32 *) &(adv7180_data.sen.mclk_source));
+ if (ret) {
+ dev_err(dev, "mclk_source invalid\n");
+ return ret;
+ }
+
+ ret = of_property_read_u32(dev->of_node, "csi_id",
+ &(adv7180_data.sen.csi));
+ if (ret) {
+ dev_err(dev, "csi_id invalid\n");
+ return ret;
+ }
+
+ clk_prepare_enable(adv7180_data.sen.sensor_clk);
+
+ dev_dbg(&adv7180_data.sen.i2c_client->dev,
+ "%s:adv7180 probe i2c address is 0x%02X\n",
+ __func__, adv7180_data.sen.i2c_client->addr);
+
+ /*! Read the revision ID of the tvin chip */
+ rev_id = adv7180_read(ADV7180_IDENT);
+ dev_dbg(dev,
+ "%s:Analog Device adv7%2X0 detected!\n", __func__,
+ rev_id);
+
+ ret = of_property_read_u32(dev->of_node, "cvbs", &(cvbs));
+ if (ret) {
+ dev_err(dev, "cvbs setting is not found\n");
+ cvbs = true;
+ }
+
+ /*! ADV7180 initialization. */
+ adv7180_hard_reset(cvbs);
+
+ pr_debug(" type is %d (expect %d)\n",
+ adv7180_int_device.type, v4l2_int_type_slave);
+ pr_debug(" num ioctls is %d\n",
+ adv7180_int_device.u.slave->num_ioctls);
+
+ /* This function attaches this structure to the /dev/video0 device.
+ * The pointer in priv points to the adv7180_data structure here.*/
+ adv7180_int_device.priv = &adv7180_data;
+ ret = v4l2_int_device_register(&adv7180_int_device);
+
+ clk_disable_unprepare(adv7180_data.sen.sensor_clk);
+
+ return ret;
+}
+
+/*!
+ * ADV7180 I2C detach function.
+ * Called on rmmod.
+ *
+ * @param *client struct i2c_client*.
+ *
+ * @return Error code indicating success or failure.
+ */
+static int adv7180_detach(struct i2c_client *client)
+{
+ dev_dbg(&adv7180_data.sen.i2c_client->dev,
+ "%s:Removing %s video decoder @ 0x%02X from adapter %s\n",
+ __func__, IF_NAME, client->addr << 1, client->adapter->name);
+
+ /* Power down via i2c */
+ adv7180_write_reg(ADV7180_PWR_MNG, 0x24);
+
+ if (dvddio_regulator)
+ regulator_disable(dvddio_regulator);
+
+ if (dvdd_regulator)
+ regulator_disable(dvdd_regulator);
+
+ if (avdd_regulator)
+ regulator_disable(avdd_regulator);
+
+ if (pvdd_regulator)
+ regulator_disable(pvdd_regulator);
+
+ v4l2_int_device_unregister(&adv7180_int_device);
+
+ return 0;
+}
+
+/*!
+ * ADV7180 init function.
+ * Called on insmod.
+ *
+ * @return Error code indicating success or failure.
+ */
+static __init int adv7180_init(void)
+{
+ u8 err = 0;
+
+ pr_debug("In adv7180_init\n");
+
+ /* Tells the i2c driver what functions to call for this driver. */
+ err = i2c_add_driver(&adv7180_i2c_driver);
+ if (err != 0)
+ pr_err("%s:driver registration failed, error=%d\n",
+ __func__, err);
+
+ return err;
+}
+
+/*!
+ * ADV7180 cleanup function.
+ * Called on rmmod.
+ *
+ * @return Error code indicating success or failure.
+ */
+static void __exit adv7180_clean(void)
+{
+ dev_dbg(&adv7180_data.sen.i2c_client->dev, "In adv7180_clean\n");
+ i2c_del_driver(&adv7180_i2c_driver);
+}
+
+module_init(adv7180_init);
+module_exit(adv7180_clean);
+
+MODULE_AUTHOR("Freescale Semiconductor");
+MODULE_DESCRIPTION("Anolog Device ADV7180 video decoder driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/platform/mxc/capture/ipu_bg_overlay_sdc.c b/drivers/media/platform/mxc/capture/ipu_bg_overlay_sdc.c
new file mode 100644
index 000000000000..193cbd5ec0f7
--- /dev/null
+++ b/drivers/media/platform/mxc/capture/ipu_bg_overlay_sdc.c
@@ -0,0 +1,552 @@
+
+/*
+ * Copyright 2004-2015 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/*!
+ * @file ipu_bg_overlay_sdc_bg.c
+ *
+ * @brief IPU Use case for PRP-VF back-ground
+ *
+ * @ingroup IPU
+ */
+#include <linux/module.h>
+#include <linux/dma-mapping.h>
+#include <linux/fb.h>
+#include <linux/ipu.h>
+#include <linux/mipi_csi2.h>
+#include "mxc_v4l2_capture.h"
+#include "ipu_prp_sw.h"
+
+static int csi_buffer_num;
+static u32 bpp, csi_mem_bufsize = 3;
+static u32 out_format;
+static struct ipu_soc *disp_ipu;
+static u32 offset;
+
+static void csi_buf_work_func(struct work_struct *work)
+{
+ int err = 0;
+ cam_data *cam =
+ container_of(work, struct _cam_data, csi_work_struct);
+
+ struct ipu_task task;
+ memset(&task, 0, sizeof(task));
+
+ if (csi_buffer_num)
+ task.input.paddr = cam->vf_bufs[0];
+ else
+ task.input.paddr = cam->vf_bufs[1];
+ task.input.width = cam->crop_current.width;
+ task.input.height = cam->crop_current.height;
+ task.input.format = IPU_PIX_FMT_UYVY;
+
+ task.output.paddr = offset;
+ task.output.width = cam->overlay_fb->var.xres;
+ task.output.height = cam->overlay_fb->var.yres;
+ task.output.format = out_format;
+ task.output.rotate = cam->rotation;
+ task.output.crop.pos.x = cam->win.w.left;
+ task.output.crop.pos.y = cam->win.w.top;
+ if (cam->win.w.width > 1024 || cam->win.w.height > 1024) {
+ task.output.crop.w = cam->overlay_fb->var.xres;
+ task.output.crop.h = cam->overlay_fb->var.yres;
+ } else {
+ task.output.crop.w = cam->win.w.width;
+ task.output.crop.h = cam->win.w.height;
+ }
+again:
+ err = ipu_check_task(&task);
+ if (err != IPU_CHECK_OK) {
+ if (err > IPU_CHECK_ERR_MIN) {
+ if (err == IPU_CHECK_ERR_SPLIT_INPUTW_OVER) {
+ task.input.crop.w -= 8;
+ goto again;
+ }
+ if (err == IPU_CHECK_ERR_SPLIT_INPUTH_OVER) {
+ task.input.crop.h -= 8;
+ goto again;
+ }
+ if (err == IPU_CHECK_ERR_SPLIT_OUTPUTW_OVER) {
+ task.output.width -= 8;
+ task.output.crop.w = task.output.width;
+ goto again;
+ }
+ if (err == IPU_CHECK_ERR_SPLIT_OUTPUTH_OVER) {
+ task.output.height -= 8;
+ task.output.crop.h = task.output.height;
+ goto again;
+ }
+ printk(KERN_ERR "check ipu taks fail\n");
+ return;
+ }
+ printk(KERN_ERR "check ipu taks fail\n");
+ return;
+ }
+ err = ipu_queue_task(&task);
+ if (err < 0)
+ printk(KERN_ERR "queue ipu task error\n");
+}
+
+static void get_disp_ipu(cam_data *cam)
+{
+ if (cam->output > 2)
+ disp_ipu = ipu_get_soc(1); /* using DISP4 */
+ else
+ disp_ipu = ipu_get_soc(0);
+}
+
+
+/*!
+ * csi ENC callback function.
+ *
+ * @param irq int irq line
+ * @param dev_id void * device id
+ *
+ * @return status IRQ_HANDLED for handled
+ */
+static irqreturn_t csi_enc_callback(int irq, void *dev_id)
+{
+ cam_data *cam = (cam_data *) dev_id;
+ ipu_channel_t chan = (irq == IPU_IRQ_CSI0_OUT_EOF) ?
+ CSI_MEM0 : CSI_MEM1;
+
+ ipu_select_buffer(cam->ipu, chan,
+ IPU_OUTPUT_BUFFER, csi_buffer_num);
+ schedule_work(&cam->csi_work_struct);
+ csi_buffer_num = (csi_buffer_num == 0) ? 1 : 0;
+ return IRQ_HANDLED;
+}
+
+static int csi_enc_setup(cam_data *cam)
+{
+ ipu_channel_params_t params;
+ u32 pixel_fmt;
+ int err = 0, sensor_protocol = 0;
+ ipu_channel_t chan = (cam->csi == 0) ? CSI_MEM0 : CSI_MEM1;
+
+#ifdef CONFIG_MXC_MIPI_CSI2
+ void *mipi_csi2_info;
+ int ipu_id;
+ int csi_id;
+#endif
+
+ if (!cam) {
+ printk(KERN_ERR "cam private is NULL\n");
+ return -ENXIO;
+ }
+
+ memset(&params, 0, sizeof(ipu_channel_params_t));
+ params.csi_mem.csi = cam->csi;
+
+ sensor_protocol = ipu_csi_get_sensor_protocol(cam->ipu, cam->csi);
+ switch (sensor_protocol) {
+ case IPU_CSI_CLK_MODE_GATED_CLK:
+ case IPU_CSI_CLK_MODE_NONGATED_CLK:
+ case IPU_CSI_CLK_MODE_CCIR656_PROGRESSIVE:
+ case IPU_CSI_CLK_MODE_CCIR1120_PROGRESSIVE_DDR:
+ case IPU_CSI_CLK_MODE_CCIR1120_PROGRESSIVE_SDR:
+ params.csi_mem.interlaced = false;
+ break;
+ case IPU_CSI_CLK_MODE_CCIR656_INTERLACED:
+ case IPU_CSI_CLK_MODE_CCIR1120_INTERLACED_DDR:
+ case IPU_CSI_CLK_MODE_CCIR1120_INTERLACED_SDR:
+ params.csi_mem.interlaced = true;
+ break;
+ default:
+ printk(KERN_ERR "sensor protocol unsupported\n");
+ return -EINVAL;
+ }
+
+#ifdef CONFIG_MXC_MIPI_CSI2
+ mipi_csi2_info = mipi_csi2_get_info();
+
+ if (mipi_csi2_info) {
+ if (mipi_csi2_get_status(mipi_csi2_info)) {
+ ipu_id = mipi_csi2_get_bind_ipu(mipi_csi2_info);
+ csi_id = mipi_csi2_get_bind_csi(mipi_csi2_info);
+
+ if (cam->ipu == ipu_get_soc(ipu_id)
+ && cam->csi == csi_id) {
+ params.csi_mem.mipi_en = true;
+ params.csi_mem.mipi_vc =
+ mipi_csi2_get_virtual_channel(mipi_csi2_info);
+ params.csi_mem.mipi_id =
+ mipi_csi2_get_datatype(mipi_csi2_info);
+
+ mipi_csi2_pixelclk_enable(mipi_csi2_info);
+ } else {
+ params.csi_mem.mipi_en = false;
+ params.csi_mem.mipi_vc = 0;
+ params.csi_mem.mipi_id = 0;
+ }
+ } else {
+ params.csi_mem.mipi_en = false;
+ params.csi_mem.mipi_vc = 0;
+ params.csi_mem.mipi_id = 0;
+ }
+ }
+#endif
+
+ if (cam->vf_bufs_vaddr[0]) {
+ dma_free_coherent(0, cam->vf_bufs_size[0],
+ cam->vf_bufs_vaddr[0],
+ (dma_addr_t) cam->vf_bufs[0]);
+ }
+ if (cam->vf_bufs_vaddr[1]) {
+ dma_free_coherent(0, cam->vf_bufs_size[1],
+ cam->vf_bufs_vaddr[1],
+ (dma_addr_t) cam->vf_bufs[1]);
+ }
+ csi_mem_bufsize =
+ cam->crop_current.width * cam->crop_current.height * 2;
+ cam->vf_bufs_size[0] = PAGE_ALIGN(csi_mem_bufsize);
+ cam->vf_bufs_vaddr[0] = (void *)dma_alloc_coherent(0,
+ cam->vf_bufs_size[0],
+ (dma_addr_t *) &
+ cam->vf_bufs[0],
+ GFP_DMA |
+ GFP_KERNEL);
+ if (cam->vf_bufs_vaddr[0] == NULL) {
+ printk(KERN_ERR "Error to allocate vf buffer\n");
+ err = -ENOMEM;
+ goto out_2;
+ }
+ cam->vf_bufs_size[1] = PAGE_ALIGN(csi_mem_bufsize);
+ cam->vf_bufs_vaddr[1] = (void *)dma_alloc_coherent(0,
+ cam->vf_bufs_size[1],
+ (dma_addr_t *) &
+ cam->vf_bufs[1],
+ GFP_DMA |
+ GFP_KERNEL);
+ if (cam->vf_bufs_vaddr[1] == NULL) {
+ printk(KERN_ERR "Error to allocate vf buffer\n");
+ err = -ENOMEM;
+ goto out_1;
+ }
+ pr_debug("vf_bufs %x %x\n", cam->vf_bufs[0], cam->vf_bufs[1]);
+
+ err = ipu_init_channel(cam->ipu, chan, &params);
+ if (err != 0) {
+ printk(KERN_ERR "ipu_init_channel %d\n", err);
+ goto out_1;
+ }
+
+ pixel_fmt = IPU_PIX_FMT_UYVY;
+ err = ipu_init_channel_buffer(
+ cam->ipu, chan, IPU_OUTPUT_BUFFER, pixel_fmt,
+ cam->crop_current.width, cam->crop_current.height,
+ cam->crop_current.width, IPU_ROTATE_NONE,
+ cam->vf_bufs[0], cam->vf_bufs[1], 0,
+ cam->offset.u_offset, cam->offset.u_offset);
+ if (err != 0) {
+ printk(KERN_ERR "CSI_MEM output buffer\n");
+ goto out_1;
+ }
+ err = ipu_enable_channel(cam->ipu, chan);
+ if (err < 0) {
+ printk(KERN_ERR "ipu_enable_channel CSI_MEM\n");
+ goto out_1;
+ }
+
+ csi_buffer_num = 0;
+
+ ipu_select_buffer(cam->ipu, chan, IPU_OUTPUT_BUFFER, 0);
+ ipu_select_buffer(cam->ipu, chan, IPU_OUTPUT_BUFFER, 1);
+ return err;
+out_1:
+ if (cam->vf_bufs_vaddr[0]) {
+ dma_free_coherent(0, cam->vf_bufs_size[0],
+ cam->vf_bufs_vaddr[0],
+ (dma_addr_t) cam->vf_bufs[0]);
+ cam->vf_bufs_vaddr[0] = NULL;
+ cam->vf_bufs[0] = 0;
+ }
+ if (cam->vf_bufs_vaddr[1]) {
+ dma_free_coherent(0, cam->vf_bufs_size[1],
+ cam->vf_bufs_vaddr[1],
+ (dma_addr_t) cam->vf_bufs[1]);
+ cam->vf_bufs_vaddr[1] = NULL;
+ cam->vf_bufs[1] = 0;
+ }
+out_2:
+ return err;
+}
+
+/*!
+ * Enable encoder task
+ * @param private struct cam_data * mxc capture instance
+ *
+ * @return status
+ */
+static int csi_enc_enabling_tasks(void *private)
+{
+ cam_data *cam = (cam_data *) private;
+ int err = 0;
+
+ ipu_clear_irq(cam->ipu, IPU_IRQ_CSI0_OUT_EOF + cam->csi);
+ err = ipu_request_irq(cam->ipu, IPU_IRQ_CSI0_OUT_EOF + cam->csi,
+ csi_enc_callback, 0, "Mxc Camera", cam);
+ if (err != 0) {
+ printk(KERN_ERR "Error registering CSI_OUT_EOF irq\n");
+ return err;
+ }
+
+ INIT_WORK(&cam->csi_work_struct, csi_buf_work_func);
+
+ err = csi_enc_setup(cam);
+ if (err != 0) {
+ printk(KERN_ERR "csi_enc_setup %d\n", err);
+ goto out1;
+ }
+
+ return err;
+out1:
+ ipu_free_irq(cam->ipu, IPU_IRQ_CSI0_OUT_EOF + cam->csi, cam);
+ return err;
+}
+
+/*!
+ * bg_overlay_start - start the overlay task
+ *
+ * @param private cam_data * mxc v4l2 main structure
+ *
+ */
+static int bg_overlay_start(void *private)
+{
+ cam_data *cam = (cam_data *) private;
+ int err = 0;
+
+ if (!cam) {
+ printk(KERN_ERR "private is NULL\n");
+ return -EIO;
+ }
+
+ if (cam->overlay_active == true) {
+ pr_debug("already start.\n");
+ return 0;
+ }
+
+ get_disp_ipu(cam);
+
+ out_format = cam->v4l2_fb.fmt.pixelformat;
+ if (cam->v4l2_fb.fmt.pixelformat == IPU_PIX_FMT_BGR24) {
+ bpp = 3, csi_mem_bufsize = 3;
+ pr_info("BGR24\n");
+ } else if (cam->v4l2_fb.fmt.pixelformat == IPU_PIX_FMT_RGB565) {
+ bpp = 2, csi_mem_bufsize = 2;
+ pr_info("RGB565\n");
+ } else if (cam->v4l2_fb.fmt.pixelformat == IPU_PIX_FMT_BGR32) {
+ bpp = 4, csi_mem_bufsize = 4;
+ pr_info("BGR32\n");
+ } else {
+ printk(KERN_ERR
+ "unsupported fix format from the framebuffer.\n");
+ return -EINVAL;
+ }
+
+ offset = cam->v4l2_fb.fmt.bytesperline * cam->win.w.top +
+ csi_mem_bufsize * cam->win.w.left;
+
+ if (cam->v4l2_fb.base == 0)
+ printk(KERN_ERR "invalid frame buffer address.\n");
+ else
+ offset += (u32) cam->v4l2_fb.base;
+
+ csi_mem_bufsize = cam->win.w.width * cam->win.w.height
+ * csi_mem_bufsize;
+
+ err = csi_enc_enabling_tasks(cam);
+ if (err != 0) {
+ printk(KERN_ERR "Error csi enc enable fail\n");
+ return err;
+ }
+
+ cam->overlay_active = true;
+ return err;
+}
+
+/*!
+ * bg_overlay_stop - stop the overlay task
+ *
+ * @param private cam_data * mxc v4l2 main structure
+ *
+ */
+static int bg_overlay_stop(void *private)
+{
+ int err = 0;
+ cam_data *cam = (cam_data *) private;
+ ipu_channel_t chan = (cam->csi == 0) ? CSI_MEM0 : CSI_MEM1;
+#ifdef CONFIG_MXC_MIPI_CSI2
+ void *mipi_csi2_info;
+ int ipu_id;
+ int csi_id;
+#endif
+
+ if (cam->overlay_active == false)
+ return 0;
+
+ err = ipu_disable_channel(cam->ipu, chan, true);
+
+ ipu_uninit_channel(cam->ipu, chan);
+
+ csi_buffer_num = 0;
+
+#ifdef CONFIG_MXC_MIPI_CSI2
+ mipi_csi2_info = mipi_csi2_get_info();
+
+ if (mipi_csi2_info) {
+ if (mipi_csi2_get_status(mipi_csi2_info)) {
+ ipu_id = mipi_csi2_get_bind_ipu(mipi_csi2_info);
+ csi_id = mipi_csi2_get_bind_csi(mipi_csi2_info);
+
+ if (cam->ipu == ipu_get_soc(ipu_id)
+ && cam->csi == csi_id)
+ mipi_csi2_pixelclk_disable(mipi_csi2_info);
+ }
+ }
+#endif
+
+ flush_work(&cam->csi_work_struct);
+ cancel_work_sync(&cam->csi_work_struct);
+
+ if (cam->vf_bufs_vaddr[0]) {
+ dma_free_coherent(0, cam->vf_bufs_size[0],
+ cam->vf_bufs_vaddr[0], cam->vf_bufs[0]);
+ cam->vf_bufs_vaddr[0] = NULL;
+ cam->vf_bufs[0] = 0;
+ }
+ if (cam->vf_bufs_vaddr[1]) {
+ dma_free_coherent(0, cam->vf_bufs_size[1],
+ cam->vf_bufs_vaddr[1], cam->vf_bufs[1]);
+ cam->vf_bufs_vaddr[1] = NULL;
+ cam->vf_bufs[1] = 0;
+ }
+ if (cam->rot_vf_bufs_vaddr[0]) {
+ dma_free_coherent(0, cam->rot_vf_buf_size[0],
+ cam->rot_vf_bufs_vaddr[0],
+ cam->rot_vf_bufs[0]);
+ cam->rot_vf_bufs_vaddr[0] = NULL;
+ cam->rot_vf_bufs[0] = 0;
+ }
+ if (cam->rot_vf_bufs_vaddr[1]) {
+ dma_free_coherent(0, cam->rot_vf_buf_size[1],
+ cam->rot_vf_bufs_vaddr[1],
+ cam->rot_vf_bufs[1]);
+ cam->rot_vf_bufs_vaddr[1] = NULL;
+ cam->rot_vf_bufs[1] = 0;
+ }
+
+ cam->overlay_active = false;
+ return err;
+}
+
+/*!
+ * Enable csi
+ * @param private struct cam_data * mxc capture instance
+ *
+ * @return status
+ */
+static int bg_overlay_enable_csi(void *private)
+{
+ cam_data *cam = (cam_data *) private;
+
+ return ipu_enable_csi(cam->ipu, cam->csi);
+}
+
+/*!
+ * Disable csi
+ * @param private struct cam_data * mxc capture instance
+ *
+ * @return status
+ */
+static int bg_overlay_disable_csi(void *private)
+{
+ cam_data *cam = (cam_data *) private;
+
+ /* free csi eof irq firstly.
+ * when disable csi, wait for idmac eof.
+ * it requests eof irq again */
+ ipu_free_irq(cam->ipu, IPU_IRQ_CSI0_OUT_EOF + cam->csi, cam);
+
+ return ipu_disable_csi(cam->ipu, cam->csi);
+}
+
+/*!
+ * function to select bg as the working path
+ *
+ * @param private cam_data * mxc v4l2 main structure
+ *
+ * @return status
+ */
+int bg_overlay_sdc_select(void *private)
+{
+ cam_data *cam = (cam_data *) private;
+
+ if (cam) {
+ cam->vf_start_sdc = bg_overlay_start;
+ cam->vf_stop_sdc = bg_overlay_stop;
+ cam->vf_enable_csi = bg_overlay_enable_csi;
+ cam->vf_disable_csi = bg_overlay_disable_csi;
+ cam->overlay_active = false;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL(bg_overlay_sdc_select);
+
+/*!
+ * function to de-select bg as the working path
+ *
+ * @param private cam_data * mxc v4l2 main structure
+ *
+ * @return status
+ */
+int bg_overlay_sdc_deselect(void *private)
+{
+ cam_data *cam = (cam_data *) private;
+
+ if (cam) {
+ cam->vf_start_sdc = NULL;
+ cam->vf_stop_sdc = NULL;
+ cam->vf_enable_csi = NULL;
+ cam->vf_disable_csi = NULL;
+ }
+ return 0;
+}
+EXPORT_SYMBOL(bg_overlay_sdc_deselect);
+
+/*!
+ * Init background overlay task.
+ *
+ * @return Error code indicating success or failure
+ */
+__init int bg_overlay_sdc_init(void)
+{
+ return 0;
+}
+
+/*!
+ * Deinit background overlay task.
+ *
+ * @return Error code indicating success or failure
+ */
+void __exit bg_overlay_sdc_exit(void)
+{
+}
+
+module_init(bg_overlay_sdc_init);
+module_exit(bg_overlay_sdc_exit);
+
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("IPU PRP VF SDC Backgroud Driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/platform/mxc/capture/ipu_csi_enc.c b/drivers/media/platform/mxc/capture/ipu_csi_enc.c
new file mode 100644
index 000000000000..3a824a9659e7
--- /dev/null
+++ b/drivers/media/platform/mxc/capture/ipu_csi_enc.c
@@ -0,0 +1,430 @@
+/*
+ * Copyright 2009-2015 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/*!
+ * @file ipu_csi_enc.c
+ *
+ * @brief CSI Use case for video capture
+ *
+ * @ingroup IPU
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+#include <linux/ipu.h>
+#include <linux/mipi_csi2.h>
+#include "mxc_v4l2_capture.h"
+#include "ipu_prp_sw.h"
+
+#ifdef CAMERA_DBG
+ #define CAMERA_TRACE(x) (printk)x
+#else
+ #define CAMERA_TRACE(x)
+#endif
+
+/*
+ * Function definitions
+ */
+
+/*!
+ * csi ENC callback function.
+ *
+ * @param irq int irq line
+ * @param dev_id void * device id
+ *
+ * @return status IRQ_HANDLED for handled
+ */
+static irqreturn_t csi_enc_callback(int irq, void *dev_id)
+{
+ cam_data *cam = (cam_data *) dev_id;
+
+ if (cam->enc_callback == NULL)
+ return IRQ_HANDLED;
+
+ cam->enc_callback(irq, dev_id);
+ return IRQ_HANDLED;
+}
+
+/*!
+ * CSI ENC enable channel setup function
+ *
+ * @param cam struct cam_data * mxc capture instance
+ *
+ * @return status
+ */
+static int csi_enc_setup(cam_data *cam)
+{
+ ipu_channel_params_t params;
+ u32 pixel_fmt;
+ int err = 0, sensor_protocol = 0;
+ dma_addr_t dummy = cam->dummy_frame.buffer.m.offset;
+ ipu_channel_t chan = (cam->csi == 0) ? CSI_MEM0 : CSI_MEM1;
+#ifdef CONFIG_MXC_MIPI_CSI2
+ void *mipi_csi2_info;
+ int ipu_id;
+ int csi_id;
+#endif
+
+ CAMERA_TRACE("In csi_enc_setup\n");
+ if (!cam) {
+ printk(KERN_ERR "cam private is NULL\n");
+ return -ENXIO;
+ }
+
+ memset(&params, 0, sizeof(ipu_channel_params_t));
+ params.csi_mem.csi = cam->csi;
+
+ sensor_protocol = ipu_csi_get_sensor_protocol(cam->ipu, cam->csi);
+ switch (sensor_protocol) {
+ case IPU_CSI_CLK_MODE_GATED_CLK:
+ case IPU_CSI_CLK_MODE_NONGATED_CLK:
+ case IPU_CSI_CLK_MODE_CCIR656_PROGRESSIVE:
+ case IPU_CSI_CLK_MODE_CCIR1120_PROGRESSIVE_DDR:
+ case IPU_CSI_CLK_MODE_CCIR1120_PROGRESSIVE_SDR:
+ params.csi_mem.interlaced = false;
+ break;
+ case IPU_CSI_CLK_MODE_CCIR656_INTERLACED:
+ case IPU_CSI_CLK_MODE_CCIR1120_INTERLACED_DDR:
+ case IPU_CSI_CLK_MODE_CCIR1120_INTERLACED_SDR:
+ params.csi_mem.interlaced = true;
+ break;
+ default:
+ printk(KERN_ERR "sensor protocol unsupported\n");
+ return -EINVAL;
+ }
+
+ if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_YUV420)
+ pixel_fmt = IPU_PIX_FMT_YUV420P;
+ else if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_YVU420)
+ pixel_fmt = IPU_PIX_FMT_YVU420P;
+ else if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_YUV422P)
+ pixel_fmt = IPU_PIX_FMT_YUV422P;
+ else if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_UYVY)
+ pixel_fmt = IPU_PIX_FMT_UYVY;
+ else if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_YUYV)
+ pixel_fmt = IPU_PIX_FMT_YUYV;
+ else if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_NV12)
+ pixel_fmt = IPU_PIX_FMT_NV12;
+ else if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_BGR24)
+ pixel_fmt = IPU_PIX_FMT_BGR24;
+ else if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_RGB24)
+ pixel_fmt = IPU_PIX_FMT_RGB24;
+ else if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_RGB565)
+ pixel_fmt = IPU_PIX_FMT_RGB565;
+ else if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_BGR32)
+ pixel_fmt = IPU_PIX_FMT_BGR32;
+ else if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_RGB32)
+ pixel_fmt = IPU_PIX_FMT_RGB32;
+ else {
+ printk(KERN_ERR "format not supported\n");
+ return -EINVAL;
+ }
+
+#ifdef CONFIG_MXC_MIPI_CSI2
+ mipi_csi2_info = mipi_csi2_get_info();
+
+ if (mipi_csi2_info) {
+ if (mipi_csi2_get_status(mipi_csi2_info)) {
+ ipu_id = mipi_csi2_get_bind_ipu(mipi_csi2_info);
+ csi_id = mipi_csi2_get_bind_csi(mipi_csi2_info);
+
+ if (cam->ipu == ipu_get_soc(ipu_id)
+ && cam->csi == csi_id) {
+ params.csi_mem.mipi_en = true;
+ params.csi_mem.mipi_vc =
+ mipi_csi2_get_virtual_channel(mipi_csi2_info);
+ params.csi_mem.mipi_id =
+ mipi_csi2_get_datatype(mipi_csi2_info);
+
+ mipi_csi2_pixelclk_enable(mipi_csi2_info);
+ } else {
+ params.csi_mem.mipi_en = false;
+ params.csi_mem.mipi_vc = 0;
+ params.csi_mem.mipi_id = 0;
+ }
+ } else {
+ params.csi_mem.mipi_en = false;
+ params.csi_mem.mipi_vc = 0;
+ params.csi_mem.mipi_id = 0;
+ }
+ }
+#endif
+
+ err = ipu_init_channel(cam->ipu, chan, &params);
+ if (err != 0) {
+ printk(KERN_ERR "ipu_init_channel %d\n", err);
+ return err;
+ }
+
+ err = ipu_init_channel_buffer(cam->ipu,
+ chan,
+ IPU_OUTPUT_BUFFER,
+ pixel_fmt, cam->v2f.fmt.pix.width,
+ cam->v2f.fmt.pix.height,
+ cam->v2f.fmt.pix.bytesperline,
+ IPU_ROTATE_NONE,
+ dummy, dummy, 0,
+ cam->offset.u_offset,
+ cam->offset.v_offset);
+ if (err != 0) {
+ printk(KERN_ERR "CSI_MEM output buffer\n");
+ return err;
+ }
+ err = ipu_enable_channel(cam->ipu, chan);
+ if (err < 0) {
+ printk(KERN_ERR "ipu_enable_channel CSI_MEM\n");
+ return err;
+ }
+
+ return err;
+}
+
+/*!
+ * function to update physical buffer address for encorder IDMA channel
+ *
+ * @param *private pointer to the cam_data structure
+ * @param eba physical buffer address for encorder IDMA channel
+ *
+ * @return status
+ */
+static int csi_enc_eba_update(void *private, dma_addr_t eba)
+{
+ int err = 0;
+ cam_data *cam = (cam_data *) private;
+ struct ipu_soc *ipu = cam->ipu;
+ int *buffer_num = &cam->ping_pong_csi;
+ ipu_channel_t chan = (cam->csi == 0) ? CSI_MEM0 : CSI_MEM1;
+
+ pr_debug("eba %x\n", eba);
+ err = ipu_update_channel_buffer(ipu, chan, IPU_OUTPUT_BUFFER,
+ *buffer_num, eba);
+ if (err != 0) {
+ ipu_clear_buffer_ready(ipu, chan, IPU_OUTPUT_BUFFER,
+ *buffer_num);
+
+ err = ipu_update_channel_buffer(ipu, chan,
+ IPU_OUTPUT_BUFFER, *buffer_num, eba);
+ if (err != 0) {
+ pr_err("ERROR: v4l2 capture: fail to update "
+ "buf%d\n", *buffer_num);
+ return err;
+ }
+ }
+
+ ipu_select_buffer(ipu, chan, IPU_OUTPUT_BUFFER, *buffer_num);
+
+ *buffer_num = (*buffer_num == 0) ? 1 : 0;
+
+ return 0;
+}
+
+/*!
+ * Enable encoder task
+ * @param private struct cam_data * mxc capture instance
+ *
+ * @return status
+ */
+static int csi_enc_enabling_tasks(void *private)
+{
+ cam_data *cam = (cam_data *) private;
+ int err = 0;
+ uint32_t irq = (cam->csi == 0) ?
+ IPU_IRQ_CSI0_OUT_EOF : IPU_IRQ_CSI1_OUT_EOF;
+
+ CAMERA_TRACE("IPU:In csi_enc_enabling_tasks\n");
+
+ cam->dummy_frame.vaddress = dma_alloc_coherent(0,
+ PAGE_ALIGN(cam->v2f.fmt.pix.sizeimage),
+ &cam->dummy_frame.paddress,
+ GFP_DMA | GFP_KERNEL);
+ if (cam->dummy_frame.vaddress == 0) {
+ pr_err("ERROR: v4l2 capture: Allocate dummy frame "
+ "failed.\n");
+ return -ENOBUFS;
+ }
+ cam->dummy_frame.buffer.type = V4L2_BUF_TYPE_PRIVATE;
+ cam->dummy_frame.buffer.length =
+ PAGE_ALIGN(cam->v2f.fmt.pix.sizeimage);
+ cam->dummy_frame.buffer.m.offset = cam->dummy_frame.paddress;
+
+ ipu_clear_irq(cam->ipu, irq);
+ err = ipu_request_irq(
+ cam->ipu, irq, csi_enc_callback, 0, "Mxc Camera", cam);
+ if (err != 0) {
+ printk(KERN_ERR "Error registering rot irq\n");
+ return err;
+ }
+
+ err = csi_enc_setup(cam);
+ if (err != 0) {
+ printk(KERN_ERR "csi_enc_setup %d\n", err);
+ return err;
+ }
+
+ return err;
+}
+
+/*!
+ * Disable encoder task
+ * @param private struct cam_data * mxc capture instance
+ *
+ * @return int
+ */
+static int csi_enc_disabling_tasks(void *private)
+{
+ cam_data *cam = (cam_data *) private;
+ int err = 0;
+ ipu_channel_t chan = (cam->csi == 0) ? CSI_MEM0 : CSI_MEM1;
+#ifdef CONFIG_MXC_MIPI_CSI2
+ void *mipi_csi2_info;
+ int ipu_id;
+ int csi_id;
+#endif
+
+ err = ipu_disable_channel(cam->ipu, chan, true);
+
+ ipu_uninit_channel(cam->ipu, chan);
+
+ if (cam->dummy_frame.vaddress != 0) {
+ dma_free_coherent(0, cam->dummy_frame.buffer.length,
+ cam->dummy_frame.vaddress,
+ cam->dummy_frame.paddress);
+ cam->dummy_frame.vaddress = 0;
+ }
+
+#ifdef CONFIG_MXC_MIPI_CSI2
+ mipi_csi2_info = mipi_csi2_get_info();
+
+ if (mipi_csi2_info) {
+ if (mipi_csi2_get_status(mipi_csi2_info)) {
+ ipu_id = mipi_csi2_get_bind_ipu(mipi_csi2_info);
+ csi_id = mipi_csi2_get_bind_csi(mipi_csi2_info);
+
+ if (cam->ipu == ipu_get_soc(ipu_id)
+ && cam->csi == csi_id)
+ mipi_csi2_pixelclk_disable(mipi_csi2_info);
+ }
+ }
+#endif
+
+ return err;
+}
+
+/*!
+ * Enable csi
+ * @param private struct cam_data * mxc capture instance
+ *
+ * @return status
+ */
+static int csi_enc_enable_csi(void *private)
+{
+ cam_data *cam = (cam_data *) private;
+
+ return ipu_enable_csi(cam->ipu, cam->csi);
+}
+
+/*!
+ * Disable csi
+ * @param private struct cam_data * mxc capture instance
+ *
+ * @return status
+ */
+static int csi_enc_disable_csi(void *private)
+{
+ cam_data *cam = (cam_data *) private;
+ uint32_t irq = (cam->csi == 0) ?
+ IPU_IRQ_CSI0_OUT_EOF : IPU_IRQ_CSI1_OUT_EOF;
+
+ /* free csi eof irq firstly.
+ * when disable csi, wait for idmac eof.
+ * it requests eof irq again */
+ ipu_free_irq(cam->ipu, irq, cam);
+
+ return ipu_disable_csi(cam->ipu, cam->csi);
+}
+
+/*!
+ * function to select CSI ENC as the working path
+ *
+ * @param private struct cam_data * mxc capture instance
+ *
+ * @return int
+ */
+int csi_enc_select(void *private)
+{
+ cam_data *cam = (cam_data *) private;
+ int err = 0;
+
+ if (cam) {
+ cam->enc_update_eba = csi_enc_eba_update;
+ cam->enc_enable = csi_enc_enabling_tasks;
+ cam->enc_disable = csi_enc_disabling_tasks;
+ cam->enc_enable_csi = csi_enc_enable_csi;
+ cam->enc_disable_csi = csi_enc_disable_csi;
+ } else {
+ err = -EIO;
+ }
+
+ return err;
+}
+EXPORT_SYMBOL(csi_enc_select);
+
+/*!
+ * function to de-select CSI ENC as the working path
+ *
+ * @param private struct cam_data * mxc capture instance
+ *
+ * @return int
+ */
+int csi_enc_deselect(void *private)
+{
+ cam_data *cam = (cam_data *) private;
+ int err = 0;
+
+ if (cam) {
+ cam->enc_update_eba = NULL;
+ cam->enc_enable = NULL;
+ cam->enc_disable = NULL;
+ cam->enc_enable_csi = NULL;
+ cam->enc_disable_csi = NULL;
+ }
+
+ return err;
+}
+EXPORT_SYMBOL(csi_enc_deselect);
+
+/*!
+ * Init the Encorder channels
+ *
+ * @return Error code indicating success or failure
+ */
+__init int csi_enc_init(void)
+{
+ return 0;
+}
+
+/*!
+ * Deinit the Encorder channels
+ *
+ */
+void __exit csi_enc_exit(void)
+{
+}
+
+module_init(csi_enc_init);
+module_exit(csi_enc_exit);
+
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("CSI ENC Driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/platform/mxc/capture/ipu_fg_overlay_sdc.c b/drivers/media/platform/mxc/capture/ipu_fg_overlay_sdc.c
new file mode 100644
index 000000000000..4d6b1365bb0d
--- /dev/null
+++ b/drivers/media/platform/mxc/capture/ipu_fg_overlay_sdc.c
@@ -0,0 +1,638 @@
+/*
+ * Copyright 2004-2015 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+/* * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/*!
+ * @file ipu_foreground_sdc.c
+ *
+ * @brief IPU Use case for PRP-VF
+ *
+ * @ingroup IPU
+ */
+
+#include <linux/module.h>
+#include <linux/dma-mapping.h>
+#include <linux/console.h>
+#include <linux/ipu.h>
+#include <linux/mxcfb.h>
+#include <linux/mipi_csi2.h>
+
+#include "mxc_v4l2_capture.h"
+#include "ipu_prp_sw.h"
+
+#ifdef CAMERA_DBG
+ #define CAMERA_TRACE(x) (printk)x
+#else
+ #define CAMERA_TRACE(x)
+#endif
+
+static int csi_buffer_num, buffer_num;
+static u32 csi_mem_bufsize;
+static struct ipu_soc *disp_ipu;
+static struct fb_info *fbi;
+static struct fb_var_screeninfo fbvar;
+static u32 vf_out_format;
+static void csi_buf_work_func(struct work_struct *work)
+{
+ int err = 0;
+ cam_data *cam =
+ container_of(work, struct _cam_data, csi_work_struct);
+
+ struct ipu_task task;
+ memset(&task, 0, sizeof(task));
+
+ if (csi_buffer_num)
+ task.input.paddr = cam->vf_bufs[0];
+ else
+ task.input.paddr = cam->vf_bufs[1];
+ task.input.width = cam->crop_current.width;
+ task.input.height = cam->crop_current.height;
+ task.input.format = IPU_PIX_FMT_NV12;
+
+ if (buffer_num == 0)
+ task.output.paddr = fbi->fix.smem_start +
+ (fbi->fix.line_length * fbvar.yres);
+ else
+ task.output.paddr = fbi->fix.smem_start;
+ task.output.width = cam->win.w.width;
+ task.output.height = cam->win.w.height;
+ task.output.format = vf_out_format;
+ task.output.rotate = cam->rotation;
+again:
+ err = ipu_check_task(&task);
+ if (err != IPU_CHECK_OK) {
+ if (err > IPU_CHECK_ERR_MIN) {
+ if (err == IPU_CHECK_ERR_SPLIT_INPUTW_OVER) {
+ task.input.crop.w -= 8;
+ goto again;
+ }
+ if (err == IPU_CHECK_ERR_SPLIT_INPUTH_OVER) {
+ task.input.crop.h -= 8;
+ goto again;
+ }
+ if (err == IPU_CHECK_ERR_SPLIT_OUTPUTW_OVER) {
+ task.output.width -= 8;
+ task.output.crop.w = task.output.width;
+ goto again;
+ }
+ if (err == IPU_CHECK_ERR_SPLIT_OUTPUTH_OVER) {
+ task.output.height -= 8;
+ task.output.crop.h = task.output.height;
+ goto again;
+ }
+ printk(KERN_ERR "check ipu taks fail\n");
+ return;
+ }
+ printk(KERN_ERR "check ipu taks fail\n");
+ return;
+ }
+ err = ipu_queue_task(&task);
+ if (err < 0)
+ printk(KERN_ERR "queue ipu task error\n");
+ ipu_select_buffer(disp_ipu, MEM_FG_SYNC, IPU_INPUT_BUFFER, buffer_num);
+ buffer_num = (buffer_num == 0) ? 1 : 0;
+}
+
+static void get_disp_ipu(cam_data *cam)
+{
+ if (cam->output > 2)
+ disp_ipu = ipu_get_soc(1); /* using DISP4 */
+ else
+ disp_ipu = ipu_get_soc(0);
+}
+
+/*!
+ * csi ENC callback function.
+ *
+ * @param irq int irq line
+ * @param dev_id void * device id
+ *
+ * @return status IRQ_HANDLED for handled
+ */
+static irqreturn_t csi_enc_callback(int irq, void *dev_id)
+{
+ cam_data *cam = (cam_data *) dev_id;
+ ipu_channel_t chan = (irq == IPU_IRQ_CSI0_OUT_EOF) ?
+ CSI_MEM0 : CSI_MEM1;
+
+ ipu_select_buffer(cam->ipu, chan,
+ IPU_OUTPUT_BUFFER, csi_buffer_num);
+
+ if ((cam->crop_current.width != cam->win.w.width) ||
+ (cam->crop_current.height != cam->win.w.height) ||
+ (vf_out_format != IPU_PIX_FMT_NV12) ||
+ (cam->rotation >= IPU_ROTATE_VERT_FLIP))
+ schedule_work(&cam->csi_work_struct);
+ csi_buffer_num = (csi_buffer_num == 0) ? 1 : 0;
+ return IRQ_HANDLED;
+}
+
+static int csi_enc_setup(cam_data *cam)
+{
+ ipu_channel_params_t params;
+ int err = 0, sensor_protocol = 0;
+ ipu_channel_t chan = (cam->csi == 0) ? CSI_MEM0 : CSI_MEM1;
+#ifdef CONFIG_MXC_MIPI_CSI2
+ void *mipi_csi2_info;
+ int ipu_id;
+ int csi_id;
+#endif
+
+ CAMERA_TRACE("In csi_enc_setup\n");
+ if (!cam) {
+ printk(KERN_ERR "cam private is NULL\n");
+ return -ENXIO;
+ }
+
+ memset(&params, 0, sizeof(ipu_channel_params_t));
+ params.csi_mem.csi = cam->csi;
+
+ sensor_protocol = ipu_csi_get_sensor_protocol(cam->ipu, cam->csi);
+ switch (sensor_protocol) {
+ case IPU_CSI_CLK_MODE_GATED_CLK:
+ case IPU_CSI_CLK_MODE_NONGATED_CLK:
+ case IPU_CSI_CLK_MODE_CCIR656_PROGRESSIVE:
+ case IPU_CSI_CLK_MODE_CCIR1120_PROGRESSIVE_DDR:
+ case IPU_CSI_CLK_MODE_CCIR1120_PROGRESSIVE_SDR:
+ params.csi_mem.interlaced = false;
+ break;
+ case IPU_CSI_CLK_MODE_CCIR656_INTERLACED:
+ case IPU_CSI_CLK_MODE_CCIR1120_INTERLACED_DDR:
+ case IPU_CSI_CLK_MODE_CCIR1120_INTERLACED_SDR:
+ params.csi_mem.interlaced = true;
+ break;
+ default:
+ printk(KERN_ERR "sensor protocol unsupported\n");
+ return -EINVAL;
+ }
+
+#ifdef CONFIG_MXC_MIPI_CSI2
+ mipi_csi2_info = mipi_csi2_get_info();
+
+ if (mipi_csi2_info) {
+ if (mipi_csi2_get_status(mipi_csi2_info)) {
+ ipu_id = mipi_csi2_get_bind_ipu(mipi_csi2_info);
+ csi_id = mipi_csi2_get_bind_csi(mipi_csi2_info);
+
+ if (cam->ipu == ipu_get_soc(ipu_id)
+ && cam->csi == csi_id) {
+ params.csi_mem.mipi_en = true;
+ params.csi_mem.mipi_vc =
+ mipi_csi2_get_virtual_channel(mipi_csi2_info);
+ params.csi_mem.mipi_id =
+ mipi_csi2_get_datatype(mipi_csi2_info);
+
+ mipi_csi2_pixelclk_enable(mipi_csi2_info);
+ } else {
+ params.csi_mem.mipi_en = false;
+ params.csi_mem.mipi_vc = 0;
+ params.csi_mem.mipi_id = 0;
+ }
+ } else {
+ params.csi_mem.mipi_en = false;
+ params.csi_mem.mipi_vc = 0;
+ params.csi_mem.mipi_id = 0;
+ }
+ }
+#endif
+
+ if (cam->vf_bufs_vaddr[0]) {
+ dma_free_coherent(0, cam->vf_bufs_size[0],
+ cam->vf_bufs_vaddr[0],
+ (dma_addr_t) cam->vf_bufs[0]);
+ }
+ if (cam->vf_bufs_vaddr[1]) {
+ dma_free_coherent(0, cam->vf_bufs_size[1],
+ cam->vf_bufs_vaddr[1],
+ (dma_addr_t) cam->vf_bufs[1]);
+ }
+ csi_mem_bufsize = cam->crop_current.width *
+ cam->crop_current.height * 3/2;
+ cam->vf_bufs_size[0] = PAGE_ALIGN(csi_mem_bufsize);
+ cam->vf_bufs_vaddr[0] = (void *)dma_alloc_coherent(0,
+ cam->vf_bufs_size[0],
+ (dma_addr_t *) &
+ cam->vf_bufs[0],
+ GFP_DMA |
+ GFP_KERNEL);
+ if (cam->vf_bufs_vaddr[0] == NULL) {
+ printk(KERN_ERR "Error to allocate vf buffer\n");
+ err = -ENOMEM;
+ goto out_2;
+ }
+ cam->vf_bufs_size[1] = PAGE_ALIGN(csi_mem_bufsize);
+ cam->vf_bufs_vaddr[1] = (void *)dma_alloc_coherent(0,
+ cam->vf_bufs_size[1],
+ (dma_addr_t *) &
+ cam->vf_bufs[1],
+ GFP_DMA |
+ GFP_KERNEL);
+ if (cam->vf_bufs_vaddr[1] == NULL) {
+ printk(KERN_ERR "Error to allocate vf buffer\n");
+ err = -ENOMEM;
+ goto out_1;
+ }
+ pr_debug("vf_bufs %x %x\n", cam->vf_bufs[0], cam->vf_bufs[1]);
+
+ err = ipu_init_channel(cam->ipu, chan, &params);
+ if (err != 0) {
+ printk(KERN_ERR "ipu_init_channel %d\n", err);
+ goto out_1;
+ }
+
+ if ((cam->crop_current.width == cam->win.w.width) &&
+ (cam->crop_current.height == cam->win.w.height) &&
+ (vf_out_format == IPU_PIX_FMT_NV12) &&
+ (cam->rotation < IPU_ROTATE_VERT_FLIP)) {
+ err = ipu_init_channel_buffer(cam->ipu, chan,
+ IPU_OUTPUT_BUFFER, IPU_PIX_FMT_NV12,
+ cam->crop_current.width,
+ cam->crop_current.height,
+ cam->crop_current.width, IPU_ROTATE_NONE,
+ fbi->fix.smem_start +
+ (fbi->fix.line_length * fbvar.yres),
+ fbi->fix.smem_start, 0,
+ cam->offset.u_offset, cam->offset.u_offset);
+ } else {
+ err = ipu_init_channel_buffer(cam->ipu, chan,
+ IPU_OUTPUT_BUFFER, IPU_PIX_FMT_NV12,
+ cam->crop_current.width,
+ cam->crop_current.height,
+ cam->crop_current.width, IPU_ROTATE_NONE,
+ cam->vf_bufs[0], cam->vf_bufs[1], 0,
+ cam->offset.u_offset, cam->offset.u_offset);
+ }
+ if (err != 0) {
+ printk(KERN_ERR "CSI_MEM output buffer\n");
+ goto out_1;
+ }
+ err = ipu_enable_channel(cam->ipu, chan);
+ if (err < 0) {
+ printk(KERN_ERR "ipu_enable_channel CSI_MEM\n");
+ goto out_1;
+ }
+
+ csi_buffer_num = 0;
+
+ ipu_select_buffer(cam->ipu, chan, IPU_OUTPUT_BUFFER, 0);
+ ipu_select_buffer(cam->ipu, chan, IPU_OUTPUT_BUFFER, 1);
+ return err;
+out_1:
+ if (cam->vf_bufs_vaddr[0]) {
+ dma_free_coherent(0, cam->vf_bufs_size[0],
+ cam->vf_bufs_vaddr[0],
+ (dma_addr_t) cam->vf_bufs[0]);
+ cam->vf_bufs_vaddr[0] = NULL;
+ cam->vf_bufs[0] = 0;
+ }
+ if (cam->vf_bufs_vaddr[1]) {
+ dma_free_coherent(0, cam->vf_bufs_size[1],
+ cam->vf_bufs_vaddr[1],
+ (dma_addr_t) cam->vf_bufs[1]);
+ cam->vf_bufs_vaddr[1] = NULL;
+ cam->vf_bufs[1] = 0;
+ }
+out_2:
+ return err;
+}
+
+/*!
+ * Enable encoder task
+ * @param private struct cam_data * mxc capture instance
+ *
+ * @return status
+ */
+static int csi_enc_enabling_tasks(void *private)
+{
+ cam_data *cam = (cam_data *) private;
+ int err = 0;
+ CAMERA_TRACE("IPU:In csi_enc_enabling_tasks\n");
+
+ ipu_clear_irq(cam->ipu, IPU_IRQ_CSI0_OUT_EOF + cam->csi);
+ err = ipu_request_irq(cam->ipu, IPU_IRQ_CSI0_OUT_EOF + cam->csi,
+ csi_enc_callback, 0, "Mxc Camera", cam);
+ if (err != 0) {
+ printk(KERN_ERR "Error registering CSI_OUT_EOF irq\n");
+ return err;
+ }
+
+ INIT_WORK(&cam->csi_work_struct, csi_buf_work_func);
+
+ err = csi_enc_setup(cam);
+ if (err != 0) {
+ printk(KERN_ERR "csi_enc_setup %d\n", err);
+ goto out1;
+ }
+
+ return err;
+out1:
+ ipu_free_irq(cam->ipu, IPU_IRQ_CSI0_OUT_EOF + cam->csi, cam);
+ return err;
+}
+
+/*
+ * Function definitions
+ */
+
+/*!
+ * foreground_start - start the vf task
+ *
+ * @param private cam_data * mxc v4l2 main structure
+ *
+ */
+static int foreground_start(void *private)
+{
+ cam_data *cam = (cam_data *) private;
+ int err = 0, i = 0, screen_size;
+ char *base;
+
+ if (!cam) {
+ printk(KERN_ERR "private is NULL\n");
+ return -EIO;
+ }
+
+ if (cam->overlay_active == true) {
+ pr_debug("already started.\n");
+ return 0;
+ }
+
+ get_disp_ipu(cam);
+
+ for (i = 0; i < num_registered_fb; i++) {
+ char *idstr = registered_fb[i]->fix.id;
+ if (((strcmp(idstr, "DISP3 FG") == 0) && (cam->output < 3)) ||
+ ((strcmp(idstr, "DISP4 FG") == 0) && (cam->output >= 3))) {
+ fbi = registered_fb[i];
+ break;
+ }
+ }
+
+ if (fbi == NULL) {
+ printk(KERN_ERR "DISP FG fb not found\n");
+ return -EPERM;
+ }
+
+ fbvar = fbi->var;
+
+ /* Store the overlay frame buffer's original std */
+ cam->fb_origin_std = fbvar.nonstd;
+
+ if (cam->devtype == IMX5_V4L2 || cam->devtype == IMX6_V4L2) {
+ /* Use DP to do CSC so that we can get better performance */
+ vf_out_format = IPU_PIX_FMT_NV12;
+ fbvar.nonstd = vf_out_format;
+ } else {
+ vf_out_format = IPU_PIX_FMT_RGB565;
+ fbvar.nonstd = 0;
+ }
+
+ fbvar.bits_per_pixel = 16;
+ fbvar.xres = fbvar.xres_virtual = cam->win.w.width;
+ fbvar.yres = cam->win.w.height;
+ fbvar.yres_virtual = cam->win.w.height * 2;
+ fbvar.yoffset = 0;
+ fbvar.vmode &= ~FB_VMODE_YWRAP;
+ fbvar.accel_flags = FB_ACCEL_DOUBLE_FLAG;
+ fbvar.activate |= FB_ACTIVATE_FORCE;
+ fb_set_var(fbi, &fbvar);
+
+ ipu_disp_set_window_pos(disp_ipu, MEM_FG_SYNC, cam->win.w.left,
+ cam->win.w.top);
+
+ /* Fill black color for framebuffer */
+ base = (char *) fbi->screen_base;
+ screen_size = fbi->var.xres * fbi->var.yres;
+ if (cam->devtype == IMX5_V4L2 || cam->devtype == IMX6_V4L2) {
+ memset(base, 0, screen_size);
+ base += screen_size;
+ for (i = 0; i < screen_size / 2; i++, base++)
+ *base = 0x80;
+ } else {
+ for (i = 0; i < screen_size * 2; i++, base++)
+ *base = 0x00;
+ }
+
+ console_lock();
+ fb_blank(fbi, FB_BLANK_UNBLANK);
+ console_unlock();
+
+ /* correct display ch buffer address */
+ ipu_update_channel_buffer(disp_ipu, MEM_FG_SYNC, IPU_INPUT_BUFFER,
+ 0, fbi->fix.smem_start +
+ (fbi->fix.line_length * fbvar.yres));
+ ipu_update_channel_buffer(disp_ipu, MEM_FG_SYNC, IPU_INPUT_BUFFER,
+ 1, fbi->fix.smem_start);
+
+ err = csi_enc_enabling_tasks(cam);
+ if (err != 0) {
+ printk(KERN_ERR "Error csi enc enable fail\n");
+ return err;
+ }
+
+ cam->overlay_active = true;
+ return err;
+
+}
+
+/*!
+ * foreground_stop - stop the vf task
+ *
+ * @param private cam_data * mxc v4l2 main structure
+ *
+ */
+static int foreground_stop(void *private)
+{
+ cam_data *cam = (cam_data *) private;
+ int err = 0, i = 0;
+ struct fb_info *fbi = NULL;
+ struct fb_var_screeninfo fbvar;
+ ipu_channel_t chan = (cam->csi == 0) ? CSI_MEM0 : CSI_MEM1;
+
+#ifdef CONFIG_MXC_MIPI_CSI2
+ void *mipi_csi2_info;
+ int ipu_id;
+ int csi_id;
+#endif
+
+ if (cam->overlay_active == false)
+ return 0;
+
+ err = ipu_disable_channel(cam->ipu, chan, true);
+
+ ipu_uninit_channel(cam->ipu, chan);
+
+ csi_buffer_num = 0;
+ buffer_num = 0;
+
+ for (i = 0; i < num_registered_fb; i++) {
+ char *idstr = registered_fb[i]->fix.id;
+ if (((strcmp(idstr, "DISP3 FG") == 0) && (cam->output < 3)) ||
+ ((strcmp(idstr, "DISP4 FG") == 0) && (cam->output >= 3))) {
+ fbi = registered_fb[i];
+ break;
+ }
+ }
+
+ if (fbi == NULL) {
+ printk(KERN_ERR "DISP FG fb not found\n");
+ return -EPERM;
+ }
+
+ console_lock();
+ fb_blank(fbi, FB_BLANK_POWERDOWN);
+ console_unlock();
+
+ /* Set the overlay frame buffer std to what it is used to be */
+ fbvar = fbi->var;
+ fbvar.accel_flags = FB_ACCEL_TRIPLE_FLAG;
+ fbvar.nonstd = cam->fb_origin_std;
+ fbvar.activate |= FB_ACTIVATE_FORCE;
+ fb_set_var(fbi, &fbvar);
+
+#ifdef CONFIG_MXC_MIPI_CSI2
+ mipi_csi2_info = mipi_csi2_get_info();
+
+ if (mipi_csi2_info) {
+ if (mipi_csi2_get_status(mipi_csi2_info)) {
+ ipu_id = mipi_csi2_get_bind_ipu(mipi_csi2_info);
+ csi_id = mipi_csi2_get_bind_csi(mipi_csi2_info);
+
+ if (cam->ipu == ipu_get_soc(ipu_id)
+ && cam->csi == csi_id)
+ mipi_csi2_pixelclk_disable(mipi_csi2_info);
+ }
+ }
+#endif
+
+ flush_work(&cam->csi_work_struct);
+ cancel_work_sync(&cam->csi_work_struct);
+
+ if (cam->vf_bufs_vaddr[0]) {
+ dma_free_coherent(0, cam->vf_bufs_size[0],
+ cam->vf_bufs_vaddr[0],
+ (dma_addr_t) cam->vf_bufs[0]);
+ cam->vf_bufs_vaddr[0] = NULL;
+ cam->vf_bufs[0] = 0;
+ }
+ if (cam->vf_bufs_vaddr[1]) {
+ dma_free_coherent(0, cam->vf_bufs_size[1],
+ cam->vf_bufs_vaddr[1],
+ (dma_addr_t) cam->vf_bufs[1]);
+ cam->vf_bufs_vaddr[1] = NULL;
+ cam->vf_bufs[1] = 0;
+ }
+
+ cam->overlay_active = false;
+ return err;
+}
+
+/*!
+ * Enable csi
+ * @param private struct cam_data * mxc capture instance
+ *
+ * @return status
+ */
+static int foreground_enable_csi(void *private)
+{
+ cam_data *cam = (cam_data *) private;
+
+ return ipu_enable_csi(cam->ipu, cam->csi);
+}
+
+/*!
+ * Disable csi
+ * @param private struct cam_data * mxc capture instance
+ *
+ * @return status
+ */
+static int foreground_disable_csi(void *private)
+{
+ cam_data *cam = (cam_data *) private;
+
+ /* free csi eof irq firstly.
+ * when disable csi, wait for idmac eof.
+ * it requests eof irq again */
+ ipu_free_irq(cam->ipu, IPU_IRQ_CSI0_OUT_EOF + cam->csi, cam);
+
+ return ipu_disable_csi(cam->ipu, cam->csi);
+}
+
+/*!
+ * function to select foreground as the working path
+ *
+ * @param private cam_data * mxc v4l2 main structure
+ *
+ * @return status
+ */
+int foreground_sdc_select(void *private)
+{
+ cam_data *cam;
+ int err = 0;
+ if (private) {
+ cam = (cam_data *) private;
+ cam->vf_start_sdc = foreground_start;
+ cam->vf_stop_sdc = foreground_stop;
+ cam->vf_enable_csi = foreground_enable_csi;
+ cam->vf_disable_csi = foreground_disable_csi;
+ cam->overlay_active = false;
+ } else
+ err = -EIO;
+
+ return err;
+}
+EXPORT_SYMBOL(foreground_sdc_select);
+
+/*!
+ * function to de-select foreground as the working path
+ *
+ * @param private cam_data * mxc v4l2 main structure
+ *
+ * @return int
+ */
+int foreground_sdc_deselect(void *private)
+{
+ cam_data *cam;
+
+ if (private) {
+ cam = (cam_data *) private;
+ cam->vf_start_sdc = NULL;
+ cam->vf_stop_sdc = NULL;
+ cam->vf_enable_csi = NULL;
+ cam->vf_disable_csi = NULL;
+ }
+ return 0;
+}
+EXPORT_SYMBOL(foreground_sdc_deselect);
+
+/*!
+ * Init viewfinder task.
+ *
+ * @return Error code indicating success or failure
+ */
+__init int foreground_sdc_init(void)
+{
+ return 0;
+}
+
+/*!
+ * Deinit viewfinder task.
+ *
+ * @return Error code indicating success or failure
+ */
+void __exit foreground_sdc_exit(void)
+{
+}
+
+module_init(foreground_sdc_init);
+module_exit(foreground_sdc_exit);
+
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("IPU PRP VF SDC Driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/platform/mxc/capture/ipu_prp_enc.c b/drivers/media/platform/mxc/capture/ipu_prp_enc.c
new file mode 100644
index 000000000000..1e4420b952f8
--- /dev/null
+++ b/drivers/media/platform/mxc/capture/ipu_prp_enc.c
@@ -0,0 +1,597 @@
+/*
+ * Copyright 2004-2015 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/*!
+ * @file ipu_prp_enc.c
+ *
+ * @brief IPU Use case for PRP-ENC
+ *
+ * @ingroup IPU
+ */
+
+#include <linux/module.h>
+#include <linux/dma-mapping.h>
+#include <linux/platform_device.h>
+#include <linux/ipu.h>
+#include <linux/mipi_csi2.h>
+#include "mxc_v4l2_capture.h"
+#include "ipu_prp_sw.h"
+
+#ifdef CAMERA_DBG
+ #define CAMERA_TRACE(x) (printk)x
+#else
+ #define CAMERA_TRACE(x)
+#endif
+
+static ipu_rotate_mode_t grotation = IPU_ROTATE_NONE;
+
+/*
+ * Function definitions
+ */
+
+/*!
+ * IPU ENC callback function.
+ *
+ * @param irq int irq line
+ * @param dev_id void * device id
+ *
+ * @return status IRQ_HANDLED for handled
+ */
+static irqreturn_t prp_enc_callback(int irq, void *dev_id)
+{
+ cam_data *cam = (cam_data *) dev_id;
+
+ if (cam->enc_callback == NULL)
+ return IRQ_HANDLED;
+
+ cam->enc_callback(irq, dev_id);
+
+ return IRQ_HANDLED;
+}
+
+/*!
+ * PrpENC enable channel setup function
+ *
+ * @param cam struct cam_data * mxc capture instance
+ *
+ * @return status
+ */
+static int prp_enc_setup(cam_data *cam)
+{
+ ipu_channel_params_t enc;
+ int err = 0;
+ dma_addr_t dummy = cam->dummy_frame.buffer.m.offset;
+#ifdef CONFIG_MXC_MIPI_CSI2
+ void *mipi_csi2_info;
+ int ipu_id;
+ int csi_id;
+#endif
+
+ CAMERA_TRACE("In prp_enc_setup\n");
+ if (!cam) {
+ printk(KERN_ERR "cam private is NULL\n");
+ return -ENXIO;
+ }
+ memset(&enc, 0, sizeof(ipu_channel_params_t));
+
+ ipu_csi_get_window_size(cam->ipu, &enc.csi_prp_enc_mem.in_width,
+ &enc.csi_prp_enc_mem.in_height, cam->csi);
+
+ enc.csi_prp_enc_mem.in_pixel_fmt = IPU_PIX_FMT_UYVY;
+ enc.csi_prp_enc_mem.out_width = cam->v2f.fmt.pix.width;
+ enc.csi_prp_enc_mem.out_height = cam->v2f.fmt.pix.height;
+ enc.csi_prp_enc_mem.csi = cam->csi;
+ if (cam->rotation >= IPU_ROTATE_90_RIGHT) {
+ enc.csi_prp_enc_mem.out_width = cam->v2f.fmt.pix.height;
+ enc.csi_prp_enc_mem.out_height = cam->v2f.fmt.pix.width;
+ }
+
+ if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_YUV420) {
+ enc.csi_prp_enc_mem.out_pixel_fmt = IPU_PIX_FMT_YUV420P;
+ pr_info("YUV420\n");
+ } else if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_YVU420) {
+ enc.csi_prp_enc_mem.out_pixel_fmt = IPU_PIX_FMT_YVU420P;
+ pr_info("YVU420\n");
+ } else if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_YUV422P) {
+ enc.csi_prp_enc_mem.out_pixel_fmt = IPU_PIX_FMT_YUV422P;
+ pr_info("YUV422P\n");
+ } else if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_YUYV) {
+ enc.csi_prp_enc_mem.out_pixel_fmt = IPU_PIX_FMT_YUYV;
+ pr_info("YUYV\n");
+ } else if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_UYVY) {
+ enc.csi_prp_enc_mem.out_pixel_fmt = IPU_PIX_FMT_UYVY;
+ pr_info("UYVY\n");
+ } else if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_NV12) {
+ enc.csi_prp_enc_mem.out_pixel_fmt = IPU_PIX_FMT_NV12;
+ pr_info("NV12\n");
+ } else if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_BGR24) {
+ enc.csi_prp_enc_mem.out_pixel_fmt = IPU_PIX_FMT_BGR24;
+ pr_info("BGR24\n");
+ } else if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_RGB24) {
+ enc.csi_prp_enc_mem.out_pixel_fmt = IPU_PIX_FMT_RGB24;
+ pr_info("RGB24\n");
+ } else if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_RGB565) {
+ enc.csi_prp_enc_mem.out_pixel_fmt = IPU_PIX_FMT_RGB565;
+ pr_info("RGB565\n");
+ } else if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_BGR32) {
+ enc.csi_prp_enc_mem.out_pixel_fmt = IPU_PIX_FMT_BGR32;
+ pr_info("BGR32\n");
+ } else if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_RGB32) {
+ enc.csi_prp_enc_mem.out_pixel_fmt = IPU_PIX_FMT_RGB32;
+ pr_info("RGB32\n");
+ } else {
+ printk(KERN_ERR "format not supported\n");
+ return -EINVAL;
+ }
+
+#ifdef CONFIG_MXC_MIPI_CSI2
+ mipi_csi2_info = mipi_csi2_get_info();
+
+ if (mipi_csi2_info) {
+ if (mipi_csi2_get_status(mipi_csi2_info)) {
+ ipu_id = mipi_csi2_get_bind_ipu(mipi_csi2_info);
+ csi_id = mipi_csi2_get_bind_csi(mipi_csi2_info);
+
+ if (cam->ipu == ipu_get_soc(ipu_id)
+ && cam->csi == csi_id) {
+ enc.csi_prp_enc_mem.mipi_en = true;
+ enc.csi_prp_enc_mem.mipi_vc =
+ mipi_csi2_get_virtual_channel(mipi_csi2_info);
+ enc.csi_prp_enc_mem.mipi_id =
+ mipi_csi2_get_datatype(mipi_csi2_info);
+
+ mipi_csi2_pixelclk_enable(mipi_csi2_info);
+ } else {
+ enc.csi_prp_enc_mem.mipi_en = false;
+ enc.csi_prp_enc_mem.mipi_vc = 0;
+ enc.csi_prp_enc_mem.mipi_id = 0;
+ }
+ } else {
+ enc.csi_prp_enc_mem.mipi_en = false;
+ enc.csi_prp_enc_mem.mipi_vc = 0;
+ enc.csi_prp_enc_mem.mipi_id = 0;
+ }
+ }
+#endif
+
+ err = ipu_init_channel(cam->ipu, CSI_PRP_ENC_MEM, &enc);
+ if (err != 0) {
+ printk(KERN_ERR "ipu_init_channel %d\n", err);
+ return err;
+ }
+
+ grotation = cam->rotation;
+ if (cam->rotation >= IPU_ROTATE_90_RIGHT) {
+ if (cam->rot_enc_bufs_vaddr[0]) {
+ dma_free_coherent(0, cam->rot_enc_buf_size[0],
+ cam->rot_enc_bufs_vaddr[0],
+ cam->rot_enc_bufs[0]);
+ }
+ if (cam->rot_enc_bufs_vaddr[1]) {
+ dma_free_coherent(0, cam->rot_enc_buf_size[1],
+ cam->rot_enc_bufs_vaddr[1],
+ cam->rot_enc_bufs[1]);
+ }
+ cam->rot_enc_buf_size[0] =
+ PAGE_ALIGN(cam->v2f.fmt.pix.sizeimage);
+ cam->rot_enc_bufs_vaddr[0] =
+ (void *)dma_alloc_coherent(0, cam->rot_enc_buf_size[0],
+ &cam->rot_enc_bufs[0],
+ GFP_DMA | GFP_KERNEL);
+ if (!cam->rot_enc_bufs_vaddr[0]) {
+ printk(KERN_ERR "alloc enc_bufs0\n");
+ return -ENOMEM;
+ }
+ cam->rot_enc_buf_size[1] =
+ PAGE_ALIGN(cam->v2f.fmt.pix.sizeimage);
+ cam->rot_enc_bufs_vaddr[1] =
+ (void *)dma_alloc_coherent(0, cam->rot_enc_buf_size[1],
+ &cam->rot_enc_bufs[1],
+ GFP_DMA | GFP_KERNEL);
+ if (!cam->rot_enc_bufs_vaddr[1]) {
+ dma_free_coherent(0, cam->rot_enc_buf_size[0],
+ cam->rot_enc_bufs_vaddr[0],
+ cam->rot_enc_bufs[0]);
+ cam->rot_enc_bufs_vaddr[0] = NULL;
+ cam->rot_enc_bufs[0] = 0;
+ printk(KERN_ERR "alloc enc_bufs1\n");
+ return -ENOMEM;
+ }
+
+ err = ipu_init_channel_buffer(cam->ipu, CSI_PRP_ENC_MEM,
+ IPU_OUTPUT_BUFFER,
+ enc.csi_prp_enc_mem.out_pixel_fmt,
+ enc.csi_prp_enc_mem.out_width,
+ enc.csi_prp_enc_mem.out_height,
+ enc.csi_prp_enc_mem.out_width,
+ IPU_ROTATE_NONE,
+ cam->rot_enc_bufs[0],
+ cam->rot_enc_bufs[1], 0, 0, 0);
+ if (err != 0) {
+ printk(KERN_ERR "CSI_PRP_ENC_MEM err\n");
+ return err;
+ }
+
+ err = ipu_init_channel(cam->ipu, MEM_ROT_ENC_MEM, NULL);
+ if (err != 0) {
+ printk(KERN_ERR "MEM_ROT_ENC_MEM channel err\n");
+ return err;
+ }
+
+ err = ipu_init_channel_buffer(cam->ipu, MEM_ROT_ENC_MEM,
+ IPU_INPUT_BUFFER,
+ enc.csi_prp_enc_mem.out_pixel_fmt,
+ enc.csi_prp_enc_mem.out_width,
+ enc.csi_prp_enc_mem.out_height,
+ enc.csi_prp_enc_mem.out_width,
+ cam->rotation,
+ cam->rot_enc_bufs[0],
+ cam->rot_enc_bufs[1], 0, 0, 0);
+ if (err != 0) {
+ printk(KERN_ERR "MEM_ROT_ENC_MEM input buffer\n");
+ return err;
+ }
+
+ err =
+ ipu_init_channel_buffer(cam->ipu, MEM_ROT_ENC_MEM,
+ IPU_OUTPUT_BUFFER,
+ enc.csi_prp_enc_mem.out_pixel_fmt,
+ enc.csi_prp_enc_mem.out_height,
+ enc.csi_prp_enc_mem.out_width,
+ cam->v2f.fmt.pix.bytesperline /
+ bytes_per_pixel(enc.csi_prp_enc_mem.
+ out_pixel_fmt),
+ IPU_ROTATE_NONE,
+ dummy, dummy, 0,
+ cam->offset.u_offset,
+ cam->offset.v_offset);
+ if (err != 0) {
+ printk(KERN_ERR "MEM_ROT_ENC_MEM output buffer\n");
+ return err;
+ }
+
+ err = ipu_link_channels(cam->ipu,
+ CSI_PRP_ENC_MEM, MEM_ROT_ENC_MEM);
+ if (err < 0) {
+ printk(KERN_ERR
+ "link CSI_PRP_ENC_MEM-MEM_ROT_ENC_MEM\n");
+ return err;
+ }
+
+ err = ipu_enable_channel(cam->ipu, CSI_PRP_ENC_MEM);
+ if (err < 0) {
+ printk(KERN_ERR "ipu_enable_channel CSI_PRP_ENC_MEM\n");
+ return err;
+ }
+ err = ipu_enable_channel(cam->ipu, MEM_ROT_ENC_MEM);
+ if (err < 0) {
+ printk(KERN_ERR "ipu_enable_channel MEM_ROT_ENC_MEM\n");
+ return err;
+ }
+
+ ipu_select_buffer(cam->ipu, CSI_PRP_ENC_MEM,
+ IPU_OUTPUT_BUFFER, 0);
+ ipu_select_buffer(cam->ipu, CSI_PRP_ENC_MEM,
+ IPU_OUTPUT_BUFFER, 1);
+ } else {
+ err =
+ ipu_init_channel_buffer(cam->ipu, CSI_PRP_ENC_MEM,
+ IPU_OUTPUT_BUFFER,
+ enc.csi_prp_enc_mem.out_pixel_fmt,
+ enc.csi_prp_enc_mem.out_width,
+ enc.csi_prp_enc_mem.out_height,
+ cam->v2f.fmt.pix.bytesperline /
+ bytes_per_pixel(enc.csi_prp_enc_mem.
+ out_pixel_fmt),
+ cam->rotation,
+ dummy, dummy, 0,
+ cam->offset.u_offset,
+ cam->offset.v_offset);
+ if (err != 0) {
+ printk(KERN_ERR "CSI_PRP_ENC_MEM output buffer\n");
+ return err;
+ }
+ err = ipu_enable_channel(cam->ipu, CSI_PRP_ENC_MEM);
+ if (err < 0) {
+ printk(KERN_ERR "ipu_enable_channel CSI_PRP_ENC_MEM\n");
+ return err;
+ }
+ }
+
+ return err;
+}
+
+/*!
+ * function to update physical buffer address for encorder IDMA channel
+ *
+ * @param private pointer to cam_data structure
+ * @param eba physical buffer address for encorder IDMA channel
+ *
+ * @return status
+ */
+static int prp_enc_eba_update(void *private, dma_addr_t eba)
+{
+ int err = 0;
+ cam_data *cam = (cam_data *) private;
+ struct ipu_soc *ipu = cam->ipu;
+ int *buffer_num = &cam->ping_pong_csi;
+
+ pr_debug("eba %x\n", eba);
+ if (grotation >= IPU_ROTATE_90_RIGHT) {
+ err = ipu_update_channel_buffer(ipu, MEM_ROT_ENC_MEM,
+ IPU_OUTPUT_BUFFER, *buffer_num,
+ eba);
+ } else {
+ err = ipu_update_channel_buffer(ipu, CSI_PRP_ENC_MEM,
+ IPU_OUTPUT_BUFFER, *buffer_num,
+ eba);
+ }
+ if (err != 0) {
+ if (grotation >= IPU_ROTATE_90_RIGHT) {
+ ipu_clear_buffer_ready(ipu, MEM_ROT_ENC_MEM,
+ IPU_OUTPUT_BUFFER,
+ *buffer_num);
+ err = ipu_update_channel_buffer(ipu, MEM_ROT_ENC_MEM,
+ IPU_OUTPUT_BUFFER,
+ *buffer_num,
+ eba);
+ } else {
+ ipu_clear_buffer_ready(ipu, CSI_PRP_ENC_MEM,
+ IPU_OUTPUT_BUFFER,
+ *buffer_num);
+ err = ipu_update_channel_buffer(ipu, CSI_PRP_ENC_MEM,
+ IPU_OUTPUT_BUFFER,
+ *buffer_num,
+ eba);
+ }
+
+ if (err != 0) {
+ pr_err("ERROR: v4l2 capture: fail to update "
+ "buf%d\n", *buffer_num);
+ return err;
+ }
+ }
+
+ if (grotation >= IPU_ROTATE_90_RIGHT) {
+ ipu_select_buffer(ipu, MEM_ROT_ENC_MEM, IPU_OUTPUT_BUFFER,
+ *buffer_num);
+ } else {
+ ipu_select_buffer(ipu, CSI_PRP_ENC_MEM, IPU_OUTPUT_BUFFER,
+ *buffer_num);
+ }
+
+ *buffer_num = (*buffer_num == 0) ? 1 : 0;
+ return 0;
+}
+
+/*!
+ * Enable encoder task
+ * @param private struct cam_data * mxc capture instance
+ *
+ * @return status
+ */
+static int prp_enc_enabling_tasks(void *private)
+{
+ cam_data *cam = (cam_data *) private;
+ int err = 0;
+ CAMERA_TRACE("IPU:In prp_enc_enabling_tasks\n");
+
+ cam->dummy_frame.vaddress = dma_alloc_coherent(0,
+ PAGE_ALIGN(cam->v2f.fmt.pix.sizeimage),
+ &cam->dummy_frame.paddress,
+ GFP_DMA | GFP_KERNEL);
+ if (cam->dummy_frame.vaddress == 0) {
+ pr_err("ERROR: v4l2 capture: Allocate dummy frame "
+ "failed.\n");
+ return -ENOBUFS;
+ }
+ cam->dummy_frame.buffer.type = V4L2_BUF_TYPE_PRIVATE;
+ cam->dummy_frame.buffer.length =
+ PAGE_ALIGN(cam->v2f.fmt.pix.sizeimage);
+ cam->dummy_frame.buffer.m.offset = cam->dummy_frame.paddress;
+
+ if (cam->rotation >= IPU_ROTATE_90_RIGHT) {
+ err = ipu_request_irq(cam->ipu, IPU_IRQ_PRP_ENC_ROT_OUT_EOF,
+ prp_enc_callback, 0, "Mxc Camera", cam);
+ } else {
+ err = ipu_request_irq(cam->ipu, IPU_IRQ_PRP_ENC_OUT_EOF,
+ prp_enc_callback, 0, "Mxc Camera", cam);
+ }
+ if (err != 0) {
+ printk(KERN_ERR "Error registering rot irq\n");
+ return err;
+ }
+
+ err = prp_enc_setup(cam);
+ if (err != 0) {
+ printk(KERN_ERR "prp_enc_setup %d\n", err);
+ return err;
+ }
+
+ return err;
+}
+
+/*!
+ * Disable encoder task
+ * @param private struct cam_data * mxc capture instance
+ *
+ * @return int
+ */
+static int prp_enc_disabling_tasks(void *private)
+{
+ cam_data *cam = (cam_data *) private;
+ int err = 0;
+#ifdef CONFIG_MXC_MIPI_CSI2
+ void *mipi_csi2_info;
+ int ipu_id;
+ int csi_id;
+#endif
+
+ if (cam->rotation >= IPU_ROTATE_90_RIGHT) {
+ ipu_free_irq(cam->ipu, IPU_IRQ_PRP_ENC_ROT_OUT_EOF, cam);
+ ipu_unlink_channels(cam->ipu, CSI_PRP_ENC_MEM, MEM_ROT_ENC_MEM);
+ }
+
+ err = ipu_disable_channel(cam->ipu, CSI_PRP_ENC_MEM, true);
+ if (cam->rotation >= IPU_ROTATE_90_RIGHT)
+ err |= ipu_disable_channel(cam->ipu, MEM_ROT_ENC_MEM, true);
+
+ ipu_uninit_channel(cam->ipu, CSI_PRP_ENC_MEM);
+ if (cam->rotation >= IPU_ROTATE_90_RIGHT)
+ ipu_uninit_channel(cam->ipu, MEM_ROT_ENC_MEM);
+
+ if (cam->dummy_frame.vaddress != 0) {
+ dma_free_coherent(0, cam->dummy_frame.buffer.length,
+ cam->dummy_frame.vaddress,
+ cam->dummy_frame.paddress);
+ cam->dummy_frame.vaddress = 0;
+ }
+
+#ifdef CONFIG_MXC_MIPI_CSI2
+ mipi_csi2_info = mipi_csi2_get_info();
+
+ if (mipi_csi2_info) {
+ if (mipi_csi2_get_status(mipi_csi2_info)) {
+ ipu_id = mipi_csi2_get_bind_ipu(mipi_csi2_info);
+ csi_id = mipi_csi2_get_bind_csi(mipi_csi2_info);
+
+ if (cam->ipu == ipu_get_soc(ipu_id)
+ && cam->csi == csi_id)
+ mipi_csi2_pixelclk_disable(mipi_csi2_info);
+ }
+ }
+#endif
+
+ return err;
+}
+
+/*!
+ * Enable csi
+ * @param private struct cam_data * mxc capture instance
+ *
+ * @return status
+ */
+static int prp_enc_enable_csi(void *private)
+{
+ cam_data *cam = (cam_data *) private;
+
+ return ipu_enable_csi(cam->ipu, cam->csi);
+}
+
+/*!
+ * Disable csi
+ * @param private struct cam_data * mxc capture instance
+ *
+ * @return status
+ */
+static int prp_enc_disable_csi(void *private)
+{
+ cam_data *cam = (cam_data *) private;
+
+ /* free csi eof irq firstly.
+ * when disable csi, wait for idmac eof.
+ * it requests eof irq again */
+ if (cam->rotation < IPU_ROTATE_90_RIGHT)
+ ipu_free_irq(cam->ipu, IPU_IRQ_PRP_ENC_OUT_EOF, cam);
+
+ return ipu_disable_csi(cam->ipu, cam->csi);
+}
+
+/*!
+ * function to select PRP-ENC as the working path
+ *
+ * @param private struct cam_data * mxc capture instance
+ *
+ * @return int
+ */
+int prp_enc_select(void *private)
+{
+ cam_data *cam = (cam_data *) private;
+ int err = 0;
+
+ if (cam) {
+ cam->enc_update_eba = prp_enc_eba_update;
+ cam->enc_enable = prp_enc_enabling_tasks;
+ cam->enc_disable = prp_enc_disabling_tasks;
+ cam->enc_enable_csi = prp_enc_enable_csi;
+ cam->enc_disable_csi = prp_enc_disable_csi;
+ } else {
+ err = -EIO;
+ }
+
+ return err;
+}
+EXPORT_SYMBOL(prp_enc_select);
+
+/*!
+ * function to de-select PRP-ENC as the working path
+ *
+ * @param private struct cam_data * mxc capture instance
+ *
+ * @return int
+ */
+int prp_enc_deselect(void *private)
+{
+ cam_data *cam = (cam_data *) private;
+ int err = 0;
+
+ if (cam) {
+ cam->enc_update_eba = NULL;
+ cam->enc_enable = NULL;
+ cam->enc_disable = NULL;
+ cam->enc_enable_csi = NULL;
+ cam->enc_disable_csi = NULL;
+ if (cam->rot_enc_bufs_vaddr[0]) {
+ dma_free_coherent(0, cam->rot_enc_buf_size[0],
+ cam->rot_enc_bufs_vaddr[0],
+ cam->rot_enc_bufs[0]);
+ cam->rot_enc_bufs_vaddr[0] = NULL;
+ cam->rot_enc_bufs[0] = 0;
+ }
+ if (cam->rot_enc_bufs_vaddr[1]) {
+ dma_free_coherent(0, cam->rot_enc_buf_size[1],
+ cam->rot_enc_bufs_vaddr[1],
+ cam->rot_enc_bufs[1]);
+ cam->rot_enc_bufs_vaddr[1] = NULL;
+ cam->rot_enc_bufs[1] = 0;
+ }
+ }
+
+ return err;
+}
+EXPORT_SYMBOL(prp_enc_deselect);
+
+/*!
+ * Init the Encorder channels
+ *
+ * @return Error code indicating success or failure
+ */
+__init int prp_enc_init(void)
+{
+ return 0;
+}
+
+/*!
+ * Deinit the Encorder channels
+ *
+ */
+void __exit prp_enc_exit(void)
+{
+}
+
+module_init(prp_enc_init);
+module_exit(prp_enc_exit);
+
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("IPU PRP ENC Driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/platform/mxc/capture/ipu_prp_sw.h b/drivers/media/platform/mxc/capture/ipu_prp_sw.h
new file mode 100644
index 000000000000..be02ab061e20
--- /dev/null
+++ b/drivers/media/platform/mxc/capture/ipu_prp_sw.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2004-2014 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/*!
+ * @file ipu_prp_sw.h
+ *
+ * @brief This file contains the IPU PRP use case driver header.
+ *
+ * @ingroup IPU
+ */
+
+#ifndef _INCLUDE_IPU__PRP_SW_H_
+#define _INCLUDE_IPU__PRP_SW_H_
+
+int csi_enc_select(void *private);
+int csi_enc_deselect(void *private);
+int prp_enc_select(void *private);
+int prp_enc_deselect(void *private);
+#ifdef CONFIG_MXC_IPU_PRP_VF_SDC
+int prp_vf_sdc_select(void *private);
+int prp_vf_sdc_deselect(void *private);
+int prp_vf_sdc_select_bg(void *private);
+int prp_vf_sdc_deselect_bg(void *private);
+#else
+int foreground_sdc_select(void *private);
+int foreground_sdc_deselect(void *private);
+int bg_overlay_sdc_select(void *private);
+int bg_overlay_sdc_deselect(void *private);
+#endif
+int prp_still_select(void *private);
+int prp_still_deselect(void *private);
+
+#endif
diff --git a/drivers/media/platform/mxc/capture/ipu_prp_vf_sdc.c b/drivers/media/platform/mxc/capture/ipu_prp_vf_sdc.c
new file mode 100644
index 000000000000..b9610f1ed820
--- /dev/null
+++ b/drivers/media/platform/mxc/capture/ipu_prp_vf_sdc.c
@@ -0,0 +1,582 @@
+/*
+ * Copyright 2004-2014 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+/* * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/*!
+ * @file ipu_prp_vf_sdc.c
+ *
+ * @brief IPU Use case for PRP-VF
+ *
+ * @ingroup IPU
+ */
+
+#include <linux/dma-mapping.h>
+#include <linux/console.h>
+#include <linux/ipu.h>
+#include <linux/module.h>
+#include <linux/mxcfb.h>
+#include <mach/hardware.h>
+#include <mach/mipi_csi2.h>
+#include "mxc_v4l2_capture.h"
+#include "ipu_prp_sw.h"
+
+static int buffer_num;
+static struct ipu_soc *disp_ipu;
+
+static void get_disp_ipu(cam_data *cam)
+{
+ if (cam->output > 2)
+ disp_ipu = ipu_get_soc(1); /* using DISP4 */
+ else
+ disp_ipu = ipu_get_soc(0);
+}
+
+static irqreturn_t prpvf_rot_eof_callback(int irq, void *dev_id)
+{
+ cam_data *cam = dev_id;
+ pr_debug("buffer_num %d\n", buffer_num);
+
+ if (cam->vf_rotation >= IPU_ROTATE_VERT_FLIP) {
+ ipu_select_buffer(disp_ipu, MEM_FG_SYNC,
+ IPU_INPUT_BUFFER, buffer_num);
+ buffer_num = (buffer_num == 0) ? 1 : 0;
+ ipu_select_buffer(cam->ipu, MEM_ROT_VF_MEM,
+ IPU_OUTPUT_BUFFER, buffer_num);
+ } else {
+ ipu_select_buffer(disp_ipu, MEM_FG_SYNC,
+ IPU_INPUT_BUFFER, buffer_num);
+ buffer_num = (buffer_num == 0) ? 1 : 0;
+ ipu_select_buffer(cam->ipu, CSI_PRP_VF_MEM,
+ IPU_OUTPUT_BUFFER, buffer_num);
+ }
+ return IRQ_HANDLED;
+}
+/*
+ * Function definitions
+ */
+
+/*!
+ * prpvf_start - start the vf task
+ *
+ * @param private cam_data * mxc v4l2 main structure
+ *
+ */
+static int prpvf_start(void *private)
+{
+ struct fb_var_screeninfo fbvar;
+ struct fb_info *fbi = NULL;
+ cam_data *cam = (cam_data *) private;
+ ipu_channel_params_t vf;
+ u32 vf_out_format = 0;
+ u32 size = 2, temp = 0;
+ int err = 0, i = 0;
+ short *tmp, color;
+#ifdef CONFIG_MXC_MIPI_CSI2
+ void *mipi_csi2_info;
+ int ipu_id;
+ int csi_id;
+#endif
+
+ if (!cam) {
+ printk(KERN_ERR "private is NULL\n");
+ return -EIO;
+ }
+
+ if (cam->overlay_active == true) {
+ pr_debug("already started.\n");
+ return 0;
+ }
+
+ get_disp_ipu(cam);
+
+ for (i = 0; i < num_registered_fb; i++) {
+ char *idstr = registered_fb[i]->fix.id;
+ if (((strcmp(idstr, "DISP3 FG") == 0) && (cam->output < 3)) ||
+ ((strcmp(idstr, "DISP4 FG") == 0) && (cam->output >= 3))) {
+ fbi = registered_fb[i];
+ break;
+ }
+ }
+
+ if (fbi == NULL) {
+ printk(KERN_ERR "DISP FG fb not found\n");
+ return -EPERM;
+ }
+
+ fbvar = fbi->var;
+
+ /* Store the overlay frame buffer's original std */
+ cam->fb_origin_std = fbvar.nonstd;
+
+ if (cam->devtype == IMX5_V4L2 || cam->devtype == IMX6_V4L2) {
+ /* Use DP to do CSC so that we can get better performance */
+ vf_out_format = IPU_PIX_FMT_UYVY;
+ fbvar.nonstd = vf_out_format;
+ color = 0x80;
+ } else {
+ vf_out_format = IPU_PIX_FMT_RGB565;
+ fbvar.nonstd = 0;
+ color = 0x0;
+ }
+
+ fbvar.bits_per_pixel = 16;
+ fbvar.xres = fbvar.xres_virtual = cam->win.w.width;
+ fbvar.yres = cam->win.w.height;
+ fbvar.yres_virtual = cam->win.w.height * 2;
+ fbvar.yoffset = 0;
+ fbvar.accel_flags = FB_ACCEL_DOUBLE_FLAG;
+ fbvar.activate |= FB_ACTIVATE_FORCE;
+ fb_set_var(fbi, &fbvar);
+
+ ipu_disp_set_window_pos(disp_ipu, MEM_FG_SYNC, cam->win.w.left,
+ cam->win.w.top);
+
+ /* Fill black color for framebuffer */
+ tmp = (short *) fbi->screen_base;
+ for (i = 0; i < (fbi->fix.line_length * fbi->var.yres)/2;
+ i++, tmp++)
+ *tmp = color;
+
+ console_lock();
+ fb_blank(fbi, FB_BLANK_UNBLANK);
+ console_unlock();
+
+ /* correct display ch buffer address */
+ ipu_update_channel_buffer(disp_ipu, MEM_FG_SYNC, IPU_INPUT_BUFFER,
+ 0, fbi->fix.smem_start +
+ (fbi->fix.line_length * fbvar.yres));
+ ipu_update_channel_buffer(disp_ipu, MEM_FG_SYNC, IPU_INPUT_BUFFER,
+ 1, fbi->fix.smem_start);
+
+ memset(&vf, 0, sizeof(ipu_channel_params_t));
+ ipu_csi_get_window_size(cam->ipu, &vf.csi_prp_vf_mem.in_width,
+ &vf.csi_prp_vf_mem.in_height, cam->csi);
+ vf.csi_prp_vf_mem.in_pixel_fmt = IPU_PIX_FMT_UYVY;
+ vf.csi_prp_vf_mem.out_width = cam->win.w.width;
+ vf.csi_prp_vf_mem.out_height = cam->win.w.height;
+ vf.csi_prp_vf_mem.csi = cam->csi;
+ if (cam->vf_rotation >= IPU_ROTATE_90_RIGHT) {
+ vf.csi_prp_vf_mem.out_width = cam->win.w.height;
+ vf.csi_prp_vf_mem.out_height = cam->win.w.width;
+ }
+ vf.csi_prp_vf_mem.out_pixel_fmt = vf_out_format;
+ size = cam->win.w.width * cam->win.w.height * size;
+
+#ifdef CONFIG_MXC_MIPI_CSI2
+ mipi_csi2_info = mipi_csi2_get_info();
+
+ if (mipi_csi2_info) {
+ if (mipi_csi2_get_status(mipi_csi2_info)) {
+ ipu_id = mipi_csi2_get_bind_ipu(mipi_csi2_info);
+ csi_id = mipi_csi2_get_bind_csi(mipi_csi2_info);
+
+ if (cam->ipu == ipu_get_soc(ipu_id)
+ && cam->csi == csi_id) {
+ vf.csi_prp_vf_mem.mipi_en = true;
+ vf.csi_prp_vf_mem.mipi_vc =
+ mipi_csi2_get_virtual_channel(mipi_csi2_info);
+ vf.csi_prp_vf_mem.mipi_id =
+ mipi_csi2_get_datatype(mipi_csi2_info);
+
+ mipi_csi2_pixelclk_enable(mipi_csi2_info);
+ } else {
+ vf.csi_prp_vf_mem.mipi_en = false;
+ vf.csi_prp_vf_mem.mipi_vc = 0;
+ vf.csi_prp_vf_mem.mipi_id = 0;
+ }
+ } else {
+ vf.csi_prp_vf_mem.mipi_en = false;
+ vf.csi_prp_vf_mem.mipi_vc = 0;
+ vf.csi_prp_vf_mem.mipi_id = 0;
+ }
+ }
+#endif
+
+ err = ipu_init_channel(cam->ipu, CSI_PRP_VF_MEM, &vf);
+ if (err != 0)
+ goto out_5;
+
+ if (cam->vf_bufs_vaddr[0]) {
+ dma_free_coherent(0, cam->vf_bufs_size[0],
+ cam->vf_bufs_vaddr[0],
+ (dma_addr_t) cam->vf_bufs[0]);
+ }
+ if (cam->vf_bufs_vaddr[1]) {
+ dma_free_coherent(0, cam->vf_bufs_size[1],
+ cam->vf_bufs_vaddr[1],
+ (dma_addr_t) cam->vf_bufs[1]);
+ }
+ cam->vf_bufs_size[0] = PAGE_ALIGN(size);
+ cam->vf_bufs_vaddr[0] = (void *)dma_alloc_coherent(0,
+ cam->vf_bufs_size[0],
+ (dma_addr_t *) &
+ cam->vf_bufs[0],
+ GFP_DMA |
+ GFP_KERNEL);
+ if (cam->vf_bufs_vaddr[0] == NULL) {
+ printk(KERN_ERR "Error to allocate vf buffer\n");
+ err = -ENOMEM;
+ goto out_4;
+ }
+ cam->vf_bufs_size[1] = PAGE_ALIGN(size);
+ cam->vf_bufs_vaddr[1] = (void *)dma_alloc_coherent(0,
+ cam->vf_bufs_size[1],
+ (dma_addr_t *) &
+ cam->vf_bufs[1],
+ GFP_DMA |
+ GFP_KERNEL);
+ if (cam->vf_bufs_vaddr[1] == NULL) {
+ printk(KERN_ERR "Error to allocate vf buffer\n");
+ err = -ENOMEM;
+ goto out_3;
+ }
+ pr_debug("vf_bufs %x %x\n", cam->vf_bufs[0], cam->vf_bufs[1]);
+
+ if (cam->vf_rotation >= IPU_ROTATE_VERT_FLIP) {
+ err = ipu_init_channel_buffer(cam->ipu, CSI_PRP_VF_MEM,
+ IPU_OUTPUT_BUFFER,
+ vf_out_format,
+ vf.csi_prp_vf_mem.out_width,
+ vf.csi_prp_vf_mem.out_height,
+ vf.csi_prp_vf_mem.out_width,
+ IPU_ROTATE_NONE,
+ cam->vf_bufs[0], cam->vf_bufs[1],
+ 0, 0, 0);
+ if (err != 0)
+ goto out_3;
+
+ err = ipu_init_channel(cam->ipu, MEM_ROT_VF_MEM, NULL);
+ if (err != 0) {
+ printk(KERN_ERR "Error MEM_ROT_VF_MEM channel\n");
+ goto out_3;
+ }
+
+ err = ipu_init_channel_buffer(cam->ipu, MEM_ROT_VF_MEM,
+ IPU_INPUT_BUFFER,
+ vf_out_format,
+ vf.csi_prp_vf_mem.out_width,
+ vf.csi_prp_vf_mem.out_height,
+ vf.csi_prp_vf_mem.out_width,
+ cam->vf_rotation,
+ cam->vf_bufs[0],
+ cam->vf_bufs[1],
+ 0, 0, 0);
+ if (err != 0) {
+ printk(KERN_ERR "Error MEM_ROT_VF_MEM input buffer\n");
+ goto out_2;
+ }
+
+ if (cam->vf_rotation < IPU_ROTATE_90_RIGHT) {
+ temp = vf.csi_prp_vf_mem.out_width;
+ vf.csi_prp_vf_mem.out_width =
+ vf.csi_prp_vf_mem.out_height;
+ vf.csi_prp_vf_mem.out_height = temp;
+ }
+
+ err = ipu_init_channel_buffer(cam->ipu, MEM_ROT_VF_MEM,
+ IPU_OUTPUT_BUFFER,
+ vf_out_format,
+ vf.csi_prp_vf_mem.out_height,
+ vf.csi_prp_vf_mem.out_width,
+ vf.csi_prp_vf_mem.out_height,
+ IPU_ROTATE_NONE,
+ fbi->fix.smem_start +
+ (fbi->fix.line_length *
+ fbi->var.yres),
+ fbi->fix.smem_start, 0, 0, 0);
+
+ if (err != 0) {
+ printk(KERN_ERR "Error MEM_ROT_VF_MEM output buffer\n");
+ goto out_2;
+ }
+
+ ipu_clear_irq(cam->ipu, IPU_IRQ_PRP_VF_ROT_OUT_EOF);
+ err = ipu_request_irq(cam->ipu, IPU_IRQ_PRP_VF_ROT_OUT_EOF,
+ prpvf_rot_eof_callback,
+ 0, "Mxc Camera", cam);
+ if (err < 0) {
+ printk(KERN_ERR "Error request irq:IPU_IRQ_PRP_VF_ROT_OUT_EOF\n");
+ goto out_2;
+ }
+
+ err = ipu_link_channels(cam->ipu,
+ CSI_PRP_VF_MEM, MEM_ROT_VF_MEM);
+ if (err < 0) {
+ printk(KERN_ERR
+ "Error link CSI_PRP_VF_MEM-MEM_ROT_VF_MEM\n");
+ goto out_1;
+ }
+
+ ipu_enable_channel(cam->ipu, CSI_PRP_VF_MEM);
+ ipu_enable_channel(cam->ipu, MEM_ROT_VF_MEM);
+
+ ipu_select_buffer(cam->ipu, CSI_PRP_VF_MEM,
+ IPU_OUTPUT_BUFFER, 0);
+ ipu_select_buffer(cam->ipu, CSI_PRP_VF_MEM,
+ IPU_OUTPUT_BUFFER, 1);
+ ipu_select_buffer(cam->ipu, MEM_ROT_VF_MEM,
+ IPU_OUTPUT_BUFFER, 0);
+ } else {
+ err = ipu_init_channel_buffer(cam->ipu, CSI_PRP_VF_MEM,
+ IPU_OUTPUT_BUFFER,
+ vf_out_format, cam->win.w.width,
+ cam->win.w.height,
+ cam->win.w.width,
+ cam->vf_rotation,
+ fbi->fix.smem_start +
+ (fbi->fix.line_length *
+ fbi->var.yres),
+ fbi->fix.smem_start, 0, 0, 0);
+ if (err != 0) {
+ printk(KERN_ERR "Error initializing CSI_PRP_VF_MEM\n");
+ goto out_4;
+ }
+ ipu_clear_irq(cam->ipu, IPU_IRQ_PRP_VF_OUT_EOF);
+ err = ipu_request_irq(cam->ipu, IPU_IRQ_PRP_VF_OUT_EOF,
+ prpvf_rot_eof_callback,
+ 0, "Mxc Camera", cam);
+ if (err < 0) {
+ printk(KERN_ERR "Error request irq:IPU_IRQ_PRP_VF_OUT_EOF\n");
+ goto out_4;
+ }
+
+ ipu_enable_channel(cam->ipu, CSI_PRP_VF_MEM);
+
+ ipu_select_buffer(cam->ipu, CSI_PRP_VF_MEM,
+ IPU_OUTPUT_BUFFER, 0);
+ }
+
+ cam->overlay_active = true;
+ return err;
+
+out_1:
+ ipu_free_irq(cam->ipu, IPU_IRQ_PRP_VF_OUT_EOF, NULL);
+out_2:
+ if (cam->vf_rotation >= IPU_ROTATE_VERT_FLIP)
+ ipu_uninit_channel(cam->ipu, MEM_ROT_VF_MEM);
+out_3:
+ if (cam->vf_bufs_vaddr[0]) {
+ dma_free_coherent(0, cam->vf_bufs_size[0],
+ cam->vf_bufs_vaddr[0],
+ (dma_addr_t) cam->vf_bufs[0]);
+ cam->vf_bufs_vaddr[0] = NULL;
+ cam->vf_bufs[0] = 0;
+ }
+ if (cam->vf_bufs_vaddr[1]) {
+ dma_free_coherent(0, cam->vf_bufs_size[1],
+ cam->vf_bufs_vaddr[1],
+ (dma_addr_t) cam->vf_bufs[1]);
+ cam->vf_bufs_vaddr[1] = NULL;
+ cam->vf_bufs[1] = 0;
+ }
+out_4:
+ ipu_uninit_channel(cam->ipu, CSI_PRP_VF_MEM);
+out_5:
+ return err;
+}
+
+/*!
+ * prpvf_stop - stop the vf task
+ *
+ * @param private cam_data * mxc v4l2 main structure
+ *
+ */
+static int prpvf_stop(void *private)
+{
+ cam_data *cam = (cam_data *) private;
+ int err = 0, i = 0;
+ struct fb_info *fbi = NULL;
+ struct fb_var_screeninfo fbvar;
+#ifdef CONFIG_MXC_MIPI_CSI2
+ void *mipi_csi2_info;
+ int ipu_id;
+ int csi_id;
+#endif
+
+ if (cam->overlay_active == false)
+ return 0;
+
+ for (i = 0; i < num_registered_fb; i++) {
+ char *idstr = registered_fb[i]->fix.id;
+ if (((strcmp(idstr, "DISP3 FG") == 0) && (cam->output < 3)) ||
+ ((strcmp(idstr, "DISP4 FG") == 0) && (cam->output >= 3))) {
+ fbi = registered_fb[i];
+ break;
+ }
+ }
+
+ if (fbi == NULL) {
+ printk(KERN_ERR "DISP FG fb not found\n");
+ return -EPERM;
+ }
+
+ if (cam->vf_rotation >= IPU_ROTATE_VERT_FLIP) {
+ ipu_unlink_channels(cam->ipu, CSI_PRP_VF_MEM, MEM_ROT_VF_MEM);
+ ipu_free_irq(cam->ipu, IPU_IRQ_PRP_VF_ROT_OUT_EOF, cam);
+ }
+ buffer_num = 0;
+
+ ipu_disable_channel(cam->ipu, CSI_PRP_VF_MEM, true);
+
+ if (cam->vf_rotation >= IPU_ROTATE_VERT_FLIP) {
+ ipu_disable_channel(cam->ipu, MEM_ROT_VF_MEM, true);
+ ipu_uninit_channel(cam->ipu, MEM_ROT_VF_MEM);
+ }
+ ipu_uninit_channel(cam->ipu, CSI_PRP_VF_MEM);
+
+ console_lock();
+ fb_blank(fbi, FB_BLANK_POWERDOWN);
+ console_unlock();
+
+ /* Set the overlay frame buffer std to what it is used to be */
+ fbvar = fbi->var;
+ fbvar.accel_flags = FB_ACCEL_TRIPLE_FLAG;
+ fbvar.nonstd = cam->fb_origin_std;
+ fbvar.activate |= FB_ACTIVATE_FORCE;
+ fb_set_var(fbi, &fbvar);
+
+#ifdef CONFIG_MXC_MIPI_CSI2
+ mipi_csi2_info = mipi_csi2_get_info();
+
+ if (mipi_csi2_info) {
+ if (mipi_csi2_get_status(mipi_csi2_info)) {
+ ipu_id = mipi_csi2_get_bind_ipu(mipi_csi2_info);
+ csi_id = mipi_csi2_get_bind_csi(mipi_csi2_info);
+
+ if (cam->ipu == ipu_get_soc(ipu_id)
+ && cam->csi == csi_id)
+ mipi_csi2_pixelclk_disable(mipi_csi2_info);
+ }
+ }
+#endif
+
+ if (cam->vf_bufs_vaddr[0]) {
+ dma_free_coherent(0, cam->vf_bufs_size[0],
+ cam->vf_bufs_vaddr[0],
+ (dma_addr_t) cam->vf_bufs[0]);
+ cam->vf_bufs_vaddr[0] = NULL;
+ cam->vf_bufs[0] = 0;
+ }
+ if (cam->vf_bufs_vaddr[1]) {
+ dma_free_coherent(0, cam->vf_bufs_size[1],
+ cam->vf_bufs_vaddr[1],
+ (dma_addr_t) cam->vf_bufs[1]);
+ cam->vf_bufs_vaddr[1] = NULL;
+ cam->vf_bufs[1] = 0;
+ }
+
+ cam->overlay_active = false;
+ return err;
+}
+
+/*!
+ * Enable csi
+ * @param private struct cam_data * mxc capture instance
+ *
+ * @return status
+ */
+static int prp_vf_enable_csi(void *private)
+{
+ cam_data *cam = (cam_data *) private;
+
+ return ipu_enable_csi(cam->ipu, cam->csi);
+}
+
+/*!
+ * Disable csi
+ * @param private struct cam_data * mxc capture instance
+ *
+ * @return status
+ */
+static int prp_vf_disable_csi(void *private)
+{
+ cam_data *cam = (cam_data *) private;
+
+ /* free csi eof irq firstly.
+ * when disable csi, wait for idmac eof.
+ * it requests eof irq again */
+ if (cam->vf_rotation < IPU_ROTATE_VERT_FLIP)
+ ipu_free_irq(cam->ipu, IPU_IRQ_PRP_VF_OUT_EOF, cam);
+
+ return ipu_disable_csi(cam->ipu, cam->csi);
+}
+
+/*!
+ * function to select PRP-VF as the working path
+ *
+ * @param private cam_data * mxc v4l2 main structure
+ *
+ * @return status
+ */
+int prp_vf_sdc_select(void *private)
+{
+ cam_data *cam;
+ int err = 0;
+ if (private) {
+ cam = (cam_data *) private;
+ cam->vf_start_sdc = prpvf_start;
+ cam->vf_stop_sdc = prpvf_stop;
+ cam->vf_enable_csi = prp_vf_enable_csi;
+ cam->vf_disable_csi = prp_vf_disable_csi;
+ cam->overlay_active = false;
+ } else
+ err = -EIO;
+
+ return err;
+}
+EXPORT_SYMBOL(prp_vf_sdc_select);
+
+/*!
+ * function to de-select PRP-VF as the working path
+ *
+ * @param private cam_data * mxc v4l2 main structure
+ *
+ * @return int
+ */
+int prp_vf_sdc_deselect(void *private)
+{
+ cam_data *cam;
+
+ if (private) {
+ cam = (cam_data *) private;
+ cam->vf_start_sdc = NULL;
+ cam->vf_stop_sdc = NULL;
+ cam->vf_enable_csi = NULL;
+ cam->vf_disable_csi = NULL;
+ }
+ return 0;
+}
+EXPORT_SYMBOL(prp_vf_sdc_deselect);
+
+/*!
+ * Init viewfinder task.
+ *
+ * @return Error code indicating success or failure
+ */
+__init int prp_vf_sdc_init(void)
+{
+ return 0;
+}
+
+/*!
+ * Deinit viewfinder task.
+ *
+ * @return Error code indicating success or failure
+ */
+void __exit prp_vf_sdc_exit(void)
+{
+}
+
+module_init(prp_vf_sdc_init);
+module_exit(prp_vf_sdc_exit);
+
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("IPU PRP VF SDC Driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/platform/mxc/capture/ipu_prp_vf_sdc_bg.c b/drivers/media/platform/mxc/capture/ipu_prp_vf_sdc_bg.c
new file mode 100644
index 000000000000..a24d82dfca63
--- /dev/null
+++ b/drivers/media/platform/mxc/capture/ipu_prp_vf_sdc_bg.c
@@ -0,0 +1,521 @@
+/*
+ * Copyright 2004-2014 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/*!
+ * @file ipu_prp_vf_sdc_bg.c
+ *
+ * @brief IPU Use case for PRP-VF back-ground
+ *
+ * @ingroup IPU
+ */
+#include <linux/dma-mapping.h>
+#include <linux/fb.h>
+#include <linux/ipu.h>
+#include <linux/module.h>
+#include <mach/mipi_csi2.h>
+#include "mxc_v4l2_capture.h"
+#include "ipu_prp_sw.h"
+
+static int buffer_num;
+static int buffer_ready;
+static struct ipu_soc *disp_ipu;
+
+static void get_disp_ipu(cam_data *cam)
+{
+ if (cam->output > 2)
+ disp_ipu = ipu_get_soc(1); /* using DISP4 */
+ else
+ disp_ipu = ipu_get_soc(0);
+}
+
+/*
+ * Function definitions
+ */
+
+/*!
+ * SDC V-Sync callback function.
+ *
+ * @param irq int irq line
+ * @param dev_id void * device id
+ *
+ * @return status IRQ_HANDLED for handled
+ */
+static irqreturn_t prpvf_sdc_vsync_callback(int irq, void *dev_id)
+{
+ cam_data *cam = dev_id;
+ if (buffer_ready > 0) {
+ ipu_select_buffer(cam->ipu, MEM_ROT_VF_MEM,
+ IPU_OUTPUT_BUFFER, 0);
+ buffer_ready--;
+ }
+
+ return IRQ_HANDLED;
+}
+
+/*!
+ * VF EOF callback function.
+ *
+ * @param irq int irq line
+ * @param dev_id void * device id
+ *
+ * @return status IRQ_HANDLED for handled
+ */
+static irqreturn_t prpvf_vf_eof_callback(int irq, void *dev_id)
+{
+ cam_data *cam = dev_id;
+ pr_debug("buffer_ready %d buffer_num %d\n", buffer_ready, buffer_num);
+
+ ipu_select_buffer(cam->ipu, MEM_ROT_VF_MEM,
+ IPU_INPUT_BUFFER, buffer_num);
+ buffer_num = (buffer_num == 0) ? 1 : 0;
+ ipu_select_buffer(cam->ipu, CSI_PRP_VF_MEM,
+ IPU_OUTPUT_BUFFER, buffer_num);
+ buffer_ready++;
+ return IRQ_HANDLED;
+}
+
+/*!
+ * prpvf_start - start the vf task
+ *
+ * @param private cam_data * mxc v4l2 main structure
+ *
+ */
+static int prpvf_start(void *private)
+{
+ cam_data *cam = (cam_data *) private;
+ ipu_channel_params_t vf;
+ u32 format;
+ u32 offset;
+ u32 bpp, size = 3;
+ int err = 0;
+#ifdef CONFIG_MXC_MIPI_CSI2
+ void *mipi_csi2_info;
+ int ipu_id;
+ int csi_id;
+#endif
+
+ if (!cam) {
+ printk(KERN_ERR "private is NULL\n");
+ return -EIO;
+ }
+
+ if (cam->overlay_active == true) {
+ pr_debug("already start.\n");
+ return 0;
+ }
+
+ get_disp_ipu(cam);
+
+ format = cam->v4l2_fb.fmt.pixelformat;
+ if (cam->v4l2_fb.fmt.pixelformat == IPU_PIX_FMT_BGR24) {
+ bpp = 3, size = 3;
+ pr_info("BGR24\n");
+ } else if (cam->v4l2_fb.fmt.pixelformat == IPU_PIX_FMT_RGB565) {
+ bpp = 2, size = 2;
+ pr_info("RGB565\n");
+ } else if (cam->v4l2_fb.fmt.pixelformat == IPU_PIX_FMT_BGR32) {
+ bpp = 4, size = 4;
+ pr_info("BGR32\n");
+ } else {
+ printk(KERN_ERR
+ "unsupported fix format from the framebuffer.\n");
+ return -EINVAL;
+ }
+
+ offset = cam->v4l2_fb.fmt.bytesperline * cam->win.w.top +
+ size * cam->win.w.left;
+
+ if (cam->v4l2_fb.base == 0)
+ printk(KERN_ERR "invalid frame buffer address.\n");
+ else
+ offset += (u32) cam->v4l2_fb.base;
+
+ memset(&vf, 0, sizeof(ipu_channel_params_t));
+ ipu_csi_get_window_size(cam->ipu, &vf.csi_prp_vf_mem.in_width,
+ &vf.csi_prp_vf_mem.in_height, cam->csi);
+ vf.csi_prp_vf_mem.in_pixel_fmt = IPU_PIX_FMT_UYVY;
+ vf.csi_prp_vf_mem.out_width = cam->win.w.width;
+ vf.csi_prp_vf_mem.out_height = cam->win.w.height;
+ vf.csi_prp_vf_mem.csi = cam->csi;
+ if (cam->vf_rotation >= IPU_ROTATE_90_RIGHT) {
+ vf.csi_prp_vf_mem.out_width = cam->win.w.height;
+ vf.csi_prp_vf_mem.out_height = cam->win.w.width;
+ }
+ vf.csi_prp_vf_mem.out_pixel_fmt = format;
+ size = cam->win.w.width * cam->win.w.height * size;
+
+#ifdef CONFIG_MXC_MIPI_CSI2
+ mipi_csi2_info = mipi_csi2_get_info();
+
+ if (mipi_csi2_info) {
+ if (mipi_csi2_get_status(mipi_csi2_info)) {
+ ipu_id = mipi_csi2_get_bind_ipu(mipi_csi2_info);
+ csi_id = mipi_csi2_get_bind_csi(mipi_csi2_info);
+
+ if (cam->ipu == ipu_get_soc(ipu_id)
+ && cam->csi == csi_id) {
+ vf.csi_prp_vf_mem.mipi_en = true;
+ vf.csi_prp_vf_mem.mipi_vc =
+ mipi_csi2_get_virtual_channel(mipi_csi2_info);
+ vf.csi_prp_vf_mem.mipi_id =
+ mipi_csi2_get_datatype(mipi_csi2_info);
+
+ mipi_csi2_pixelclk_enable(mipi_csi2_info);
+ } else {
+ vf.csi_prp_vf_mem.mipi_en = false;
+ vf.csi_prp_vf_mem.mipi_vc = 0;
+ vf.csi_prp_vf_mem.mipi_id = 0;
+ }
+ } else {
+ vf.csi_prp_vf_mem.mipi_en = false;
+ vf.csi_prp_vf_mem.mipi_vc = 0;
+ vf.csi_prp_vf_mem.mipi_id = 0;
+ }
+ }
+#endif
+
+ err = ipu_init_channel(cam->ipu, CSI_PRP_VF_MEM, &vf);
+ if (err != 0)
+ goto out_4;
+
+ if (cam->vf_bufs_vaddr[0]) {
+ dma_free_coherent(0, cam->vf_bufs_size[0],
+ cam->vf_bufs_vaddr[0], cam->vf_bufs[0]);
+ }
+ if (cam->vf_bufs_vaddr[1]) {
+ dma_free_coherent(0, cam->vf_bufs_size[1],
+ cam->vf_bufs_vaddr[1], cam->vf_bufs[1]);
+ }
+ cam->vf_bufs_size[0] = PAGE_ALIGN(size);
+ cam->vf_bufs_vaddr[0] = (void *)dma_alloc_coherent(0,
+ cam->vf_bufs_size[0],
+ &cam->vf_bufs[0],
+ GFP_DMA |
+ GFP_KERNEL);
+ if (cam->vf_bufs_vaddr[0] == NULL) {
+ printk(KERN_ERR "Error to allocate vf buffer\n");
+ err = -ENOMEM;
+ goto out_3;
+ }
+ cam->vf_bufs_size[1] = PAGE_ALIGN(size);
+ cam->vf_bufs_vaddr[1] = (void *)dma_alloc_coherent(0,
+ cam->vf_bufs_size[1],
+ &cam->vf_bufs[1],
+ GFP_DMA |
+ GFP_KERNEL);
+ if (cam->vf_bufs_vaddr[1] == NULL) {
+ printk(KERN_ERR "Error to allocate vf buffer\n");
+ err = -ENOMEM;
+ goto out_3;
+ }
+
+ err = ipu_init_channel_buffer(cam->ipu, CSI_PRP_VF_MEM,
+ IPU_OUTPUT_BUFFER,
+ format, vf.csi_prp_vf_mem.out_width,
+ vf.csi_prp_vf_mem.out_height,
+ vf.csi_prp_vf_mem.out_width,
+ IPU_ROTATE_NONE,
+ cam->vf_bufs[0],
+ cam->vf_bufs[1],
+ 0, 0, 0);
+ if (err != 0) {
+ printk(KERN_ERR "Error initializing CSI_PRP_VF_MEM\n");
+ goto out_3;
+ }
+ err = ipu_init_channel(cam->ipu, MEM_ROT_VF_MEM, NULL);
+ if (err != 0) {
+ printk(KERN_ERR "Error MEM_ROT_VF_MEM channel\n");
+ goto out_3;
+ }
+
+ err = ipu_init_channel_buffer(cam->ipu, MEM_ROT_VF_MEM,
+ IPU_INPUT_BUFFER,
+ format, vf.csi_prp_vf_mem.out_width,
+ vf.csi_prp_vf_mem.out_height,
+ vf.csi_prp_vf_mem.out_width,
+ cam->vf_rotation,
+ cam->vf_bufs[0],
+ cam->vf_bufs[1],
+ 0, 0, 0);
+ if (err != 0) {
+ printk(KERN_ERR "Error MEM_ROT_VF_MEM input buffer\n");
+ goto out_2;
+ }
+
+ if (cam->vf_rotation >= IPU_ROTATE_90_RIGHT) {
+ err = ipu_init_channel_buffer(cam->ipu, MEM_ROT_VF_MEM,
+ IPU_OUTPUT_BUFFER,
+ format,
+ vf.csi_prp_vf_mem.out_height,
+ vf.csi_prp_vf_mem.out_width,
+ cam->overlay_fb->var.xres * bpp,
+ IPU_ROTATE_NONE,
+ offset, 0, 0, 0, 0);
+
+ if (err != 0) {
+ printk(KERN_ERR "Error MEM_ROT_VF_MEM output buffer\n");
+ goto out_2;
+ }
+ } else {
+ err = ipu_init_channel_buffer(cam->ipu, MEM_ROT_VF_MEM,
+ IPU_OUTPUT_BUFFER,
+ format,
+ vf.csi_prp_vf_mem.out_width,
+ vf.csi_prp_vf_mem.out_height,
+ cam->overlay_fb->var.xres * bpp,
+ IPU_ROTATE_NONE,
+ offset, 0, 0, 0, 0);
+ if (err != 0) {
+ printk(KERN_ERR "Error MEM_ROT_VF_MEM output buffer\n");
+ goto out_2;
+ }
+ }
+
+ ipu_clear_irq(cam->ipu, IPU_IRQ_PRP_VF_OUT_EOF);
+ err = ipu_request_irq(cam->ipu, IPU_IRQ_PRP_VF_OUT_EOF,
+ prpvf_vf_eof_callback,
+ 0, "Mxc Camera", cam);
+ if (err != 0) {
+ printk(KERN_ERR
+ "Error registering IPU_IRQ_PRP_VF_OUT_EOF irq.\n");
+ goto out_2;
+ }
+
+ ipu_clear_irq(disp_ipu, IPU_IRQ_BG_SF_END);
+ err = ipu_request_irq(disp_ipu, IPU_IRQ_BG_SF_END,
+ prpvf_sdc_vsync_callback,
+ 0, "Mxc Camera", cam);
+ if (err != 0) {
+ printk(KERN_ERR "Error registering IPU_IRQ_BG_SF_END irq.\n");
+ goto out_1;
+ }
+
+ ipu_enable_channel(cam->ipu, CSI_PRP_VF_MEM);
+ ipu_enable_channel(cam->ipu, MEM_ROT_VF_MEM);
+
+ buffer_num = 0;
+ buffer_ready = 0;
+ ipu_select_buffer(cam->ipu, CSI_PRP_VF_MEM, IPU_OUTPUT_BUFFER, 0);
+
+ cam->overlay_active = true;
+ return err;
+
+out_1:
+ ipu_free_irq(cam->ipu, IPU_IRQ_PRP_VF_OUT_EOF, NULL);
+out_2:
+ ipu_uninit_channel(cam->ipu, MEM_ROT_VF_MEM);
+out_3:
+ ipu_uninit_channel(cam->ipu, CSI_PRP_VF_MEM);
+out_4:
+ if (cam->vf_bufs_vaddr[0]) {
+ dma_free_coherent(0, cam->vf_bufs_size[0],
+ cam->vf_bufs_vaddr[0], cam->vf_bufs[0]);
+ cam->vf_bufs_vaddr[0] = NULL;
+ cam->vf_bufs[0] = 0;
+ }
+ if (cam->vf_bufs_vaddr[1]) {
+ dma_free_coherent(0, cam->vf_bufs_size[1],
+ cam->vf_bufs_vaddr[1], cam->vf_bufs[1]);
+ cam->vf_bufs_vaddr[1] = NULL;
+ cam->vf_bufs[1] = 0;
+ }
+ if (cam->rot_vf_bufs_vaddr[0]) {
+ dma_free_coherent(0, cam->rot_vf_buf_size[0],
+ cam->rot_vf_bufs_vaddr[0],
+ cam->rot_vf_bufs[0]);
+ cam->rot_vf_bufs_vaddr[0] = NULL;
+ cam->rot_vf_bufs[0] = 0;
+ }
+ if (cam->rot_vf_bufs_vaddr[1]) {
+ dma_free_coherent(0, cam->rot_vf_buf_size[1],
+ cam->rot_vf_bufs_vaddr[1],
+ cam->rot_vf_bufs[1]);
+ cam->rot_vf_bufs_vaddr[1] = NULL;
+ cam->rot_vf_bufs[1] = 0;
+ }
+ return err;
+}
+
+/*!
+ * prpvf_stop - stop the vf task
+ *
+ * @param private cam_data * mxc v4l2 main structure
+ *
+ */
+static int prpvf_stop(void *private)
+{
+ cam_data *cam = (cam_data *) private;
+#ifdef CONFIG_MXC_MIPI_CSI2
+ void *mipi_csi2_info;
+ int ipu_id;
+ int csi_id;
+#endif
+
+ if (cam->overlay_active == false)
+ return 0;
+
+ ipu_free_irq(disp_ipu, IPU_IRQ_BG_SF_END, cam);
+
+ ipu_disable_channel(cam->ipu, CSI_PRP_VF_MEM, true);
+ ipu_disable_channel(cam->ipu, MEM_ROT_VF_MEM, true);
+ ipu_uninit_channel(cam->ipu, CSI_PRP_VF_MEM);
+ ipu_uninit_channel(cam->ipu, MEM_ROT_VF_MEM);
+
+#ifdef CONFIG_MXC_MIPI_CSI2
+ mipi_csi2_info = mipi_csi2_get_info();
+
+ if (mipi_csi2_info) {
+ if (mipi_csi2_get_status(mipi_csi2_info)) {
+ ipu_id = mipi_csi2_get_bind_ipu(mipi_csi2_info);
+ csi_id = mipi_csi2_get_bind_csi(mipi_csi2_info);
+
+ if (cam->ipu == ipu_get_soc(ipu_id)
+ && cam->csi == csi_id)
+ mipi_csi2_pixelclk_disable(mipi_csi2_info);
+ }
+ }
+#endif
+
+ if (cam->vf_bufs_vaddr[0]) {
+ dma_free_coherent(0, cam->vf_bufs_size[0],
+ cam->vf_bufs_vaddr[0], cam->vf_bufs[0]);
+ cam->vf_bufs_vaddr[0] = NULL;
+ cam->vf_bufs[0] = 0;
+ }
+ if (cam->vf_bufs_vaddr[1]) {
+ dma_free_coherent(0, cam->vf_bufs_size[1],
+ cam->vf_bufs_vaddr[1], cam->vf_bufs[1]);
+ cam->vf_bufs_vaddr[1] = NULL;
+ cam->vf_bufs[1] = 0;
+ }
+ if (cam->rot_vf_bufs_vaddr[0]) {
+ dma_free_coherent(0, cam->rot_vf_buf_size[0],
+ cam->rot_vf_bufs_vaddr[0],
+ cam->rot_vf_bufs[0]);
+ cam->rot_vf_bufs_vaddr[0] = NULL;
+ cam->rot_vf_bufs[0] = 0;
+ }
+ if (cam->rot_vf_bufs_vaddr[1]) {
+ dma_free_coherent(0, cam->rot_vf_buf_size[1],
+ cam->rot_vf_bufs_vaddr[1],
+ cam->rot_vf_bufs[1]);
+ cam->rot_vf_bufs_vaddr[1] = NULL;
+ cam->rot_vf_bufs[1] = 0;
+ }
+
+ buffer_num = 0;
+ buffer_ready = 0;
+ cam->overlay_active = false;
+ return 0;
+}
+
+/*!
+ * Enable csi
+ * @param private struct cam_data * mxc capture instance
+ *
+ * @return status
+ */
+static int prp_vf_enable_csi(void *private)
+{
+ cam_data *cam = (cam_data *) private;
+
+ return ipu_enable_csi(cam->ipu, cam->csi);
+}
+
+/*!
+ * Disable csi
+ * @param private struct cam_data * mxc capture instance
+ *
+ * @return status
+ */
+static int prp_vf_disable_csi(void *private)
+{
+ cam_data *cam = (cam_data *) private;
+
+ /* free csi eof irq firstly.
+ * when disable csi, wait for idmac eof.
+ * it requests eof irq again */
+ ipu_free_irq(cam->ipu, IPU_IRQ_PRP_VF_OUT_EOF, cam);
+
+ return ipu_disable_csi(cam->ipu, cam->csi);
+}
+
+/*!
+ * function to select PRP-VF as the working path
+ *
+ * @param private cam_data * mxc v4l2 main structure
+ *
+ * @return status
+ */
+int prp_vf_sdc_select_bg(void *private)
+{
+ cam_data *cam = (cam_data *) private;
+
+ if (cam) {
+ cam->vf_start_sdc = prpvf_start;
+ cam->vf_stop_sdc = prpvf_stop;
+ cam->vf_enable_csi = prp_vf_enable_csi;
+ cam->vf_disable_csi = prp_vf_disable_csi;
+ cam->overlay_active = false;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL(prp_vf_sdc_select_bg);
+
+/*!
+ * function to de-select PRP-VF as the working path
+ *
+ * @param private cam_data * mxc v4l2 main structure
+ *
+ * @return status
+ */
+int prp_vf_sdc_deselect_bg(void *private)
+{
+ cam_data *cam = (cam_data *) private;
+
+ if (cam) {
+ cam->vf_start_sdc = NULL;
+ cam->vf_stop_sdc = NULL;
+ cam->vf_enable_csi = NULL;
+ cam->vf_disable_csi = NULL;
+ }
+ return 0;
+}
+EXPORT_SYMBOL(prp_vf_sdc_deselect_bg);
+
+/*!
+ * Init viewfinder task.
+ *
+ * @return Error code indicating success or failure
+ */
+__init int prp_vf_sdc_init_bg(void)
+{
+ return 0;
+}
+
+/*!
+ * Deinit viewfinder task.
+ *
+ * @return Error code indicating success or failure
+ */
+void __exit prp_vf_sdc_exit_bg(void)
+{
+}
+
+module_init(prp_vf_sdc_init_bg);
+module_exit(prp_vf_sdc_exit_bg);
+
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("IPU PRP VF SDC Backgroud Driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/platform/mxc/capture/ipu_still.c b/drivers/media/platform/mxc/capture/ipu_still.c
new file mode 100644
index 000000000000..b18c3cf873cc
--- /dev/null
+++ b/drivers/media/platform/mxc/capture/ipu_still.c
@@ -0,0 +1,268 @@
+/*
+ * Copyright 2004-2014 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/*!
+ * @file ipu_still.c
+ *
+ * @brief IPU Use case for still image capture
+ *
+ * @ingroup IPU
+ */
+
+#include <linux/module.h>
+#include <linux/semaphore.h>
+#include <linux/sched.h>
+#include <linux/ipu.h>
+#include "mxc_v4l2_capture.h"
+#include "ipu_prp_sw.h"
+
+static int callback_eof_flag;
+#ifndef CONFIG_MXC_IPU_V1
+static int buffer_num;
+#endif
+
+#ifdef CONFIG_MXC_IPU_V1
+static int callback_flag;
+/*
+ * Function definitions
+ */
+/*!
+ * CSI EOF callback function.
+ *
+ * @param irq int irq line
+ * @param dev_id void * device id
+ *
+ * @return status IRQ_HANDLED for handled
+ */
+static irqreturn_t prp_csi_eof_callback(int irq, void *dev_id)
+{
+ cam_data *cam = devid;
+ ipu_select_buffer(cam->ipu, CSI_MEM, IPU_OUTPUT_BUFFER,
+ callback_flag%2 ? 1 : 0);
+ if (callback_flag == 0)
+ ipu_enable_channel(cam->ipu, CSI_MEM);
+
+ callback_flag++;
+ return IRQ_HANDLED;
+}
+#endif
+
+/*!
+ * CSI callback function.
+ *
+ * @param irq int irq line
+ * @param dev_id void * device id
+ *
+ * @return status IRQ_HANDLED for handled
+ */
+static irqreturn_t prp_still_callback(int irq, void *dev_id)
+{
+ cam_data *cam = (cam_data *) dev_id;
+
+ callback_eof_flag++;
+ if (callback_eof_flag < 5) {
+#ifndef CONFIG_MXC_IPU_V1
+ buffer_num = (buffer_num == 0) ? 1 : 0;
+ ipu_select_buffer(cam->ipu, CSI_MEM,
+ IPU_OUTPUT_BUFFER, buffer_num);
+#endif
+ } else {
+ cam->still_counter++;
+ wake_up_interruptible(&cam->still_queue);
+ }
+
+ return IRQ_HANDLED;
+}
+
+/*!
+ * start csi->mem task
+ * @param private struct cam_data * mxc capture instance
+ *
+ * @return status
+ */
+static int prp_still_start(void *private)
+{
+ cam_data *cam = (cam_data *) private;
+ u32 pixel_fmt;
+ int err;
+ ipu_channel_params_t params;
+
+ if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_YUV420)
+ pixel_fmt = IPU_PIX_FMT_YUV420P;
+ else if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_NV12)
+ pixel_fmt = IPU_PIX_FMT_NV12;
+ else if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_YUV422P)
+ pixel_fmt = IPU_PIX_FMT_YUV422P;
+ else if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_UYVY)
+ pixel_fmt = IPU_PIX_FMT_UYVY;
+ else if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_YUYV)
+ pixel_fmt = IPU_PIX_FMT_YUYV;
+ else if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_BGR24)
+ pixel_fmt = IPU_PIX_FMT_BGR24;
+ else if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_RGB24)
+ pixel_fmt = IPU_PIX_FMT_RGB24;
+ else if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_RGB565)
+ pixel_fmt = IPU_PIX_FMT_RGB565;
+ else if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_BGR32)
+ pixel_fmt = IPU_PIX_FMT_BGR32;
+ else if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_RGB32)
+ pixel_fmt = IPU_PIX_FMT_RGB32;
+ else {
+ printk(KERN_ERR "format not supported\n");
+ return -EINVAL;
+ }
+
+ memset(&params, 0, sizeof(params));
+ err = ipu_init_channel(cam->ipu, CSI_MEM, &params);
+ if (err != 0)
+ return err;
+
+ err = ipu_init_channel_buffer(cam->ipu, CSI_MEM, IPU_OUTPUT_BUFFER,
+ pixel_fmt, cam->v2f.fmt.pix.width,
+ cam->v2f.fmt.pix.height,
+ cam->v2f.fmt.pix.width, IPU_ROTATE_NONE,
+ cam->still_buf[0], cam->still_buf[1], 0,
+ 0, 0);
+ if (err != 0)
+ return err;
+
+#ifdef CONFIG_MXC_IPU_V1
+ ipu_clear_irq(IPU_IRQ_SENSOR_OUT_EOF);
+ err = ipu_request_irq(IPU_IRQ_SENSOR_OUT_EOF, prp_still_callback,
+ 0, "Mxc Camera", cam);
+ if (err != 0) {
+ printk(KERN_ERR "Error registering irq.\n");
+ return err;
+ }
+ callback_flag = 0;
+ callback_eof_flag = 0;
+ ipu_clear_irq(IPU_IRQ_SENSOR_EOF);
+ err = ipu_request_irq(IPU_IRQ_SENSOR_EOF, prp_csi_eof_callback,
+ 0, "Mxc Camera", cam);
+ if (err != 0) {
+ printk(KERN_ERR "Error IPU_IRQ_SENSOR_EOF\n");
+ return err;
+ }
+#else
+ callback_eof_flag = 0;
+ buffer_num = 0;
+
+ ipu_clear_irq(cam->ipu, IPU_IRQ_CSI0_OUT_EOF);
+ err = ipu_request_irq(cam->ipu, IPU_IRQ_CSI0_OUT_EOF,
+ prp_still_callback,
+ 0, "Mxc Camera", cam);
+ if (err != 0) {
+ printk(KERN_ERR "Error registering irq.\n");
+ return err;
+ }
+
+ ipu_select_buffer(cam->ipu, CSI_MEM, IPU_OUTPUT_BUFFER, 0);
+ ipu_enable_channel(cam->ipu, CSI_MEM);
+ ipu_enable_csi(cam->ipu, cam->csi);
+#endif
+
+ return err;
+}
+
+/*!
+ * stop csi->mem encoder task
+ * @param private struct cam_data * mxc capture instance
+ *
+ * @return status
+ */
+static int prp_still_stop(void *private)
+{
+ cam_data *cam = (cam_data *) private;
+ int err = 0;
+
+#ifdef CONFIG_MXC_IPU_V1
+ ipu_free_irq(IPU_IRQ_SENSOR_EOF, NULL);
+ ipu_free_irq(IPU_IRQ_SENSOR_OUT_EOF, cam);
+#else
+ ipu_free_irq(cam->ipu, IPU_IRQ_CSI0_OUT_EOF, cam);
+#endif
+
+ ipu_disable_csi(cam->ipu, cam->csi);
+ ipu_disable_channel(cam->ipu, CSI_MEM, true);
+ ipu_uninit_channel(cam->ipu, CSI_MEM);
+
+ return err;
+}
+
+/*!
+ * function to select CSI_MEM as the working path
+ *
+ * @param private struct cam_data * mxc capture instance
+ *
+ * @return status
+ */
+int prp_still_select(void *private)
+{
+ cam_data *cam = (cam_data *) private;
+
+ if (cam) {
+ cam->csi_start = prp_still_start;
+ cam->csi_stop = prp_still_stop;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL(prp_still_select);
+
+/*!
+ * function to de-select CSI_MEM as the working path
+ *
+ * @param private struct cam_data * mxc capture instance
+ *
+ * @return status
+ */
+int prp_still_deselect(void *private)
+{
+ cam_data *cam = (cam_data *) private;
+ int err = 0;
+
+ err = prp_still_stop(cam);
+
+ if (cam) {
+ cam->csi_start = NULL;
+ cam->csi_stop = NULL;
+ }
+
+ return err;
+}
+EXPORT_SYMBOL(prp_still_deselect);
+
+/*!
+ * Init the Encorder channels
+ *
+ * @return Error code indicating success or failure
+ */
+__init int prp_still_init(void)
+{
+ return 0;
+}
+
+/*!
+ * Deinit the Encorder channels
+ *
+ */
+void __exit prp_still_exit(void)
+{
+}
+
+module_init(prp_still_init);
+module_exit(prp_still_exit);
+
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("IPU PRP STILL IMAGE Driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/platform/mxc/capture/mx6s_capture.c b/drivers/media/platform/mxc/capture/mx6s_capture.c
new file mode 100644
index 000000000000..a1f885dcc834
--- /dev/null
+++ b/drivers/media/platform/mxc/capture/mx6s_capture.c
@@ -0,0 +1,2047 @@
+/*
+ * Copyright (C) 2014-2016 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/*!
+ * @file mx6s_csi.c
+ *
+ * @brief mx6sx CMOS Sensor interface functions
+ *
+ * @ingroup CSI
+ */
+#include <asm/dma.h>
+#include <linux/busfreq-imx.h>
+#include <linux/clk.h>
+#include <linux/dma-mapping.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/errno.h>
+#include <linux/fs.h>
+#include <linux/gcd.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/math64.h>
+#include <linux/mfd/syscon.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/of_graph.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+#include <linux/time.h>
+#include <linux/media-bus-format.h>
+#include <media/v4l2-common.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-dev.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-ioctl.h>
+#include <media/videobuf2-core.h>
+#include <media/videobuf2-dma-contig.h>
+
+#define MX6S_CAM_DRV_NAME "mx6s-csi"
+#define MX6S_CAM_VERSION "0.0.1"
+#define MX6S_CAM_DRIVER_DESCRIPTION "i.MX6S_CSI"
+
+#define MAX_VIDEO_MEM 64
+
+/* reset values */
+#define CSICR1_RESET_VAL 0x40000800
+#define CSICR2_RESET_VAL 0x0
+#define CSICR3_RESET_VAL 0x0
+
+/* csi control reg 1 */
+#define BIT_SWAP16_EN (0x1 << 31)
+#define BIT_EXT_VSYNC (0x1 << 30)
+#define BIT_EOF_INT_EN (0x1 << 29)
+#define BIT_PRP_IF_EN (0x1 << 28)
+#define BIT_CCIR_MODE (0x1 << 27)
+#define BIT_COF_INT_EN (0x1 << 26)
+#define BIT_SF_OR_INTEN (0x1 << 25)
+#define BIT_RF_OR_INTEN (0x1 << 24)
+#define BIT_SFF_DMA_DONE_INTEN (0x1 << 22)
+#define BIT_STATFF_INTEN (0x1 << 21)
+#define BIT_FB2_DMA_DONE_INTEN (0x1 << 20)
+#define BIT_FB1_DMA_DONE_INTEN (0x1 << 19)
+#define BIT_RXFF_INTEN (0x1 << 18)
+#define BIT_SOF_POL (0x1 << 17)
+#define BIT_SOF_INTEN (0x1 << 16)
+#define BIT_MCLKDIV (0xF << 12)
+#define BIT_HSYNC_POL (0x1 << 11)
+#define BIT_CCIR_EN (0x1 << 10)
+#define BIT_MCLKEN (0x1 << 9)
+#define BIT_FCC (0x1 << 8)
+#define BIT_PACK_DIR (0x1 << 7)
+#define BIT_CLR_STATFIFO (0x1 << 6)
+#define BIT_CLR_RXFIFO (0x1 << 5)
+#define BIT_GCLK_MODE (0x1 << 4)
+#define BIT_INV_DATA (0x1 << 3)
+#define BIT_INV_PCLK (0x1 << 2)
+#define BIT_REDGE (0x1 << 1)
+#define BIT_PIXEL_BIT (0x1 << 0)
+
+#define SHIFT_MCLKDIV 12
+
+/* control reg 3 */
+#define BIT_FRMCNT (0xFFFF << 16)
+#define BIT_FRMCNT_RST (0x1 << 15)
+#define BIT_DMA_REFLASH_RFF (0x1 << 14)
+#define BIT_DMA_REFLASH_SFF (0x1 << 13)
+#define BIT_DMA_REQ_EN_RFF (0x1 << 12)
+#define BIT_DMA_REQ_EN_SFF (0x1 << 11)
+#define BIT_STATFF_LEVEL (0x7 << 8)
+#define BIT_HRESP_ERR_EN (0x1 << 7)
+#define BIT_RXFF_LEVEL (0x7 << 4)
+#define BIT_TWO_8BIT_SENSOR (0x1 << 3)
+#define BIT_ZERO_PACK_EN (0x1 << 2)
+#define BIT_ECC_INT_EN (0x1 << 1)
+#define BIT_ECC_AUTO_EN (0x1 << 0)
+
+#define SHIFT_FRMCNT 16
+#define SHIFT_RXFIFO_LEVEL 4
+
+/* csi status reg */
+#define BIT_ADDR_CH_ERR_INT (0x1 << 28)
+#define BIT_FIELD0_INT (0x1 << 27)
+#define BIT_FIELD1_INT (0x1 << 26)
+#define BIT_SFF_OR_INT (0x1 << 25)
+#define BIT_RFF_OR_INT (0x1 << 24)
+#define BIT_DMA_TSF_DONE_SFF (0x1 << 22)
+#define BIT_STATFF_INT (0x1 << 21)
+#define BIT_DMA_TSF_DONE_FB2 (0x1 << 20)
+#define BIT_DMA_TSF_DONE_FB1 (0x1 << 19)
+#define BIT_RXFF_INT (0x1 << 18)
+#define BIT_EOF_INT (0x1 << 17)
+#define BIT_SOF_INT (0x1 << 16)
+#define BIT_F2_INT (0x1 << 15)
+#define BIT_F1_INT (0x1 << 14)
+#define BIT_COF_INT (0x1 << 13)
+#define BIT_HRESP_ERR_INT (0x1 << 7)
+#define BIT_ECC_INT (0x1 << 1)
+#define BIT_DRDY (0x1 << 0)
+
+/* csi control reg 18 */
+#define BIT_CSI_ENABLE (0x1 << 31)
+#define BIT_MIPI_DATA_FORMAT_RAW8 (0x2a << 25)
+#define BIT_MIPI_DATA_FORMAT_RAW10 (0x2b << 25)
+#define BIT_MIPI_DATA_FORMAT_YUV422_8B (0x1e << 25)
+#define BIT_MIPI_DATA_FORMAT_MASK (0x3F << 25)
+#define BIT_MIPI_DATA_FORMAT_OFFSET 25
+#define BIT_DATA_FROM_MIPI (0x1 << 22)
+#define BIT_MIPI_YU_SWAP (0x1 << 21)
+#define BIT_MIPI_DOUBLE_CMPNT (0x1 << 20)
+#define BIT_BASEADDR_CHG_ERR_EN (0x1 << 9)
+#define BIT_BASEADDR_SWITCH_SEL (0x1 << 5)
+#define BIT_BASEADDR_SWITCH_EN (0x1 << 4)
+#define BIT_PARALLEL24_EN (0x1 << 3)
+#define BIT_DEINTERLACE_EN (0x1 << 2)
+#define BIT_TVDECODER_IN_EN (0x1 << 1)
+#define BIT_NTSC_EN (0x1 << 0)
+
+#define CSI_MCLK_VF 1
+#define CSI_MCLK_ENC 2
+#define CSI_MCLK_RAW 4
+#define CSI_MCLK_I2C 8
+
+#define CSI_CSICR1 0x0
+#define CSI_CSICR2 0x4
+#define CSI_CSICR3 0x8
+#define CSI_STATFIFO 0xC
+#define CSI_CSIRXFIFO 0x10
+#define CSI_CSIRXCNT 0x14
+#define CSI_CSISR 0x18
+
+#define CSI_CSIDBG 0x1C
+#define CSI_CSIDMASA_STATFIFO 0x20
+#define CSI_CSIDMATS_STATFIFO 0x24
+#define CSI_CSIDMASA_FB1 0x28
+#define CSI_CSIDMASA_FB2 0x2C
+#define CSI_CSIFBUF_PARA 0x30
+#define CSI_CSIIMAG_PARA 0x34
+
+#define CSI_CSICR18 0x48
+#define CSI_CSICR19 0x4c
+
+#define NUM_FORMATS ARRAY_SIZE(formats)
+#define MX6SX_MAX_SENSORS 1
+
+struct csi_signal_cfg_t {
+ unsigned data_width:3;
+ unsigned clk_mode:2;
+ unsigned ext_vsync:1;
+ unsigned Vsync_pol:1;
+ unsigned Hsync_pol:1;
+ unsigned pixclk_pol:1;
+ unsigned data_pol:1;
+ unsigned sens_clksrc:1;
+};
+
+struct csi_config_t {
+ /* control reg 1 */
+ unsigned int swap16_en:1;
+ unsigned int ext_vsync:1;
+ unsigned int eof_int_en:1;
+ unsigned int prp_if_en:1;
+ unsigned int ccir_mode:1;
+ unsigned int cof_int_en:1;
+ unsigned int sf_or_inten:1;
+ unsigned int rf_or_inten:1;
+ unsigned int sff_dma_done_inten:1;
+ unsigned int statff_inten:1;
+ unsigned int fb2_dma_done_inten:1;
+ unsigned int fb1_dma_done_inten:1;
+ unsigned int rxff_inten:1;
+ unsigned int sof_pol:1;
+ unsigned int sof_inten:1;
+ unsigned int mclkdiv:4;
+ unsigned int hsync_pol:1;
+ unsigned int ccir_en:1;
+ unsigned int mclken:1;
+ unsigned int fcc:1;
+ unsigned int pack_dir:1;
+ unsigned int gclk_mode:1;
+ unsigned int inv_data:1;
+ unsigned int inv_pclk:1;
+ unsigned int redge:1;
+ unsigned int pixel_bit:1;
+
+ /* control reg 3 */
+ unsigned int frmcnt:16;
+ unsigned int frame_reset:1;
+ unsigned int dma_reflash_rff:1;
+ unsigned int dma_reflash_sff:1;
+ unsigned int dma_req_en_rff:1;
+ unsigned int dma_req_en_sff:1;
+ unsigned int statff_level:3;
+ unsigned int hresp_err_en:1;
+ unsigned int rxff_level:3;
+ unsigned int two_8bit_sensor:1;
+ unsigned int zero_pack_en:1;
+ unsigned int ecc_int_en:1;
+ unsigned int ecc_auto_en:1;
+ /* fifo counter */
+ unsigned int rxcnt;
+};
+
+/*
+ * Basic structures
+ */
+struct mx6s_fmt {
+ char name[32];
+ u32 fourcc; /* v4l2 format id */
+ u32 pixelformat;
+ u32 mbus_code;
+ int bpp;
+};
+
+static struct mx6s_fmt formats[] = {
+ {
+ .name = "UYVY-16",
+ .fourcc = V4L2_PIX_FMT_UYVY,
+ .pixelformat = V4L2_PIX_FMT_UYVY,
+ .mbus_code = MEDIA_BUS_FMT_UYVY8_2X8,
+ .bpp = 2,
+ }, {
+ .name = "YUYV-16",
+ .fourcc = V4L2_PIX_FMT_YUYV,
+ .pixelformat = V4L2_PIX_FMT_YUYV,
+ .mbus_code = MEDIA_BUS_FMT_YUYV8_2X8,
+ .bpp = 2,
+ }, {
+ .name = "YUV32 (X-Y-U-V)",
+ .fourcc = V4L2_PIX_FMT_YUV32,
+ .pixelformat = V4L2_PIX_FMT_YUV32,
+ .mbus_code = MEDIA_BUS_FMT_AYUV8_1X32,
+ .bpp = 4,
+ }, {
+ .name = "RAWRGB8 (SBGGR8)",
+ .fourcc = V4L2_PIX_FMT_SBGGR8,
+ .pixelformat = V4L2_PIX_FMT_SBGGR8,
+ .mbus_code = MEDIA_BUS_FMT_SBGGR8_1X8,
+ .bpp = 1,
+ }
+};
+
+struct mx6s_buf_internal {
+ struct list_head queue;
+ int bufnum;
+ bool discard;
+};
+
+/* buffer for one video frame */
+struct mx6s_buffer {
+ /* common v4l buffer stuff -- must be first */
+ struct vb2_v4l2_buffer vb;
+ struct mx6s_buf_internal internal;
+};
+
+struct mx6s_csi_mux {
+ struct regmap *gpr;
+ u8 req_gpr;
+ u8 req_bit;
+};
+
+struct mx6s_csi_soc {
+ bool rx_fifo_rst;
+ int baseaddr_switch;
+};
+
+struct mx6s_csi_dev {
+ struct device *dev;
+ struct video_device *vdev;
+ struct v4l2_subdev *sd;
+ struct v4l2_device v4l2_dev;
+
+ struct vb2_queue vb2_vidq;
+ struct v4l2_ctrl_handler ctrl_handler;
+
+ struct mutex lock;
+ spinlock_t slock;
+
+ /* clock */
+ struct clk *clk_disp_axi;
+ struct clk *clk_disp_dcic;
+ struct clk *clk_csi_mclk;
+
+ void __iomem *regbase;
+ int irq;
+
+ u32 nextfb;
+ u32 skipframe;
+ u32 type;
+ u32 bytesperline;
+ v4l2_std_id std;
+ struct mx6s_fmt *fmt;
+ struct v4l2_pix_format pix;
+ u32 mbus_code;
+
+ unsigned int frame_count;
+
+ struct list_head capture;
+ struct list_head active_bufs;
+ struct list_head discard;
+
+ void *discard_buffer;
+ dma_addr_t discard_buffer_dma;
+ size_t discard_size;
+ struct mx6s_buf_internal buf_discard[2];
+
+ struct v4l2_async_subdev asd;
+ struct v4l2_async_notifier subdev_notifier;
+ struct v4l2_async_subdev *async_subdevs[2];
+
+ bool csi_mipi_mode;
+ bool csi_two_8bit_sensor_mode;
+ const struct mx6s_csi_soc *soc;
+ struct mx6s_csi_mux csi_mux;
+};
+
+static const struct of_device_id mx6s_csi_dt_ids[];
+
+static inline int csi_read(struct mx6s_csi_dev *csi, unsigned int offset)
+{
+ return __raw_readl(csi->regbase + offset);
+}
+static inline void csi_write(struct mx6s_csi_dev *csi, unsigned int value,
+ unsigned int offset)
+{
+ __raw_writel(value, csi->regbase + offset);
+}
+
+static inline struct mx6s_csi_dev
+ *notifier_to_mx6s_dev(struct v4l2_async_notifier *n)
+{
+ return container_of(n, struct mx6s_csi_dev, subdev_notifier);
+}
+
+struct mx6s_fmt *format_by_fourcc(int fourcc)
+{
+ int i;
+
+ for (i = 0; i < NUM_FORMATS; i++) {
+ if (formats[i].pixelformat == fourcc)
+ return formats + i;
+ }
+
+ pr_err("unknown pixelformat:'%4.4s'\n", (char *)&fourcc);
+ return NULL;
+}
+
+struct mx6s_fmt *format_by_mbus(u32 code)
+{
+ int i;
+
+ for (i = 0; i < NUM_FORMATS; i++) {
+ if (formats[i].mbus_code == code)
+ return formats + i;
+ }
+
+ pr_err("unknown mbus:0x%x\n", code);
+ return NULL;
+}
+
+static struct mx6s_buffer *mx6s_ibuf_to_buf(struct mx6s_buf_internal *int_buf)
+{
+ return container_of(int_buf, struct mx6s_buffer, internal);
+}
+
+void csi_clk_enable(struct mx6s_csi_dev *csi_dev)
+{
+ clk_prepare_enable(csi_dev->clk_disp_axi);
+ clk_prepare_enable(csi_dev->clk_disp_dcic);
+ clk_prepare_enable(csi_dev->clk_csi_mclk);
+}
+
+void csi_clk_disable(struct mx6s_csi_dev *csi_dev)
+{
+ clk_disable_unprepare(csi_dev->clk_csi_mclk);
+ clk_disable_unprepare(csi_dev->clk_disp_dcic);
+ clk_disable_unprepare(csi_dev->clk_disp_axi);
+}
+
+static void csihw_reset(struct mx6s_csi_dev *csi_dev)
+{
+ __raw_writel(__raw_readl(csi_dev->regbase + CSI_CSICR3)
+ | BIT_FRMCNT_RST,
+ csi_dev->regbase + CSI_CSICR3);
+
+ __raw_writel(CSICR1_RESET_VAL, csi_dev->regbase + CSI_CSICR1);
+ __raw_writel(CSICR2_RESET_VAL, csi_dev->regbase + CSI_CSICR2);
+ __raw_writel(CSICR3_RESET_VAL, csi_dev->regbase + CSI_CSICR3);
+}
+
+static void csisw_reset(struct mx6s_csi_dev *csi_dev)
+{
+ int cr1, cr3, cr18, isr;
+
+ /* Disable csi */
+ cr18 = csi_read(csi_dev, CSI_CSICR18);
+ cr18 &= ~BIT_CSI_ENABLE;
+ csi_write(csi_dev, cr18, CSI_CSICR18);
+
+ /* Clear RX FIFO */
+ cr1 = csi_read(csi_dev, CSI_CSICR1);
+ csi_write(csi_dev, cr1 & ~BIT_FCC, CSI_CSICR1);
+ cr1 = csi_read(csi_dev, CSI_CSICR1);
+ csi_write(csi_dev, cr1 | BIT_CLR_RXFIFO, CSI_CSICR1);
+
+ /* DMA reflash */
+ cr3 = csi_read(csi_dev, CSI_CSICR3);
+ cr3 |= BIT_DMA_REFLASH_RFF | BIT_FRMCNT_RST;
+ csi_write(csi_dev, cr3, CSI_CSICR3);
+
+ msleep(2);
+
+ cr1 = csi_read(csi_dev, CSI_CSICR1);
+ csi_write(csi_dev, cr1 | BIT_FCC, CSI_CSICR1);
+
+ isr = csi_read(csi_dev, CSI_CSISR);
+ csi_write(csi_dev, isr, CSI_CSISR);
+
+ cr18 |= csi_dev->soc->baseaddr_switch;
+
+ /* Enable csi */
+ cr18 |= BIT_CSI_ENABLE;
+ csi_write(csi_dev, cr18, CSI_CSICR18);
+}
+
+/*!
+ * csi_init_interface
+ * Init csi interface
+ */
+static void csi_init_interface(struct mx6s_csi_dev *csi_dev)
+{
+ unsigned int val = 0;
+ unsigned int imag_para;
+
+ val |= BIT_SOF_POL;
+ val |= BIT_REDGE;
+ val |= BIT_GCLK_MODE;
+ val |= BIT_HSYNC_POL;
+ val |= BIT_FCC;
+ val |= 1 << SHIFT_MCLKDIV;
+ val |= BIT_MCLKEN;
+ __raw_writel(val, csi_dev->regbase + CSI_CSICR1);
+
+ imag_para = (640 << 16) | 960;
+ __raw_writel(imag_para, csi_dev->regbase + CSI_CSIIMAG_PARA);
+
+ val = BIT_DMA_REFLASH_RFF;
+ __raw_writel(val, csi_dev->regbase + CSI_CSICR3);
+}
+
+static void csi_enable_int(struct mx6s_csi_dev *csi_dev, int arg)
+{
+ unsigned long cr1 = __raw_readl(csi_dev->regbase + CSI_CSICR1);
+
+ cr1 |= BIT_SOF_INTEN;
+ cr1 |= BIT_RFF_OR_INT;
+ if (arg == 1) {
+ /* still capture needs DMA intterrupt */
+ cr1 |= BIT_FB1_DMA_DONE_INTEN;
+ cr1 |= BIT_FB2_DMA_DONE_INTEN;
+ }
+ __raw_writel(cr1, csi_dev->regbase + CSI_CSICR1);
+}
+
+static void csi_disable_int(struct mx6s_csi_dev *csi_dev)
+{
+ unsigned long cr1 = __raw_readl(csi_dev->regbase + CSI_CSICR1);
+
+ cr1 &= ~BIT_SOF_INTEN;
+ cr1 &= ~BIT_RFF_OR_INT;
+ cr1 &= ~BIT_FB1_DMA_DONE_INTEN;
+ cr1 &= ~BIT_FB2_DMA_DONE_INTEN;
+ __raw_writel(cr1, csi_dev->regbase + CSI_CSICR1);
+}
+
+static void csi_enable(struct mx6s_csi_dev *csi_dev, int arg)
+{
+ unsigned long cr = __raw_readl(csi_dev->regbase + CSI_CSICR18);
+
+ if (arg == 1)
+ cr |= BIT_CSI_ENABLE;
+ else
+ cr &= ~BIT_CSI_ENABLE;
+ __raw_writel(cr, csi_dev->regbase + CSI_CSICR18);
+}
+
+static void csi_buf_stride_set(struct mx6s_csi_dev *csi_dev, u32 stride)
+{
+ __raw_writel(stride, csi_dev->regbase + CSI_CSIFBUF_PARA);
+}
+
+static void csi_deinterlace_enable(struct mx6s_csi_dev *csi_dev, bool enable)
+{
+ unsigned long cr18 = __raw_readl(csi_dev->regbase + CSI_CSICR18);
+
+ if (enable == true)
+ cr18 |= BIT_DEINTERLACE_EN;
+ else
+ cr18 &= ~BIT_DEINTERLACE_EN;
+
+ __raw_writel(cr18, csi_dev->regbase + CSI_CSICR18);
+}
+
+static void csi_deinterlace_mode(struct mx6s_csi_dev *csi_dev, int mode)
+{
+ unsigned long cr18 = __raw_readl(csi_dev->regbase + CSI_CSICR18);
+
+ if (mode == V4L2_STD_NTSC)
+ cr18 |= BIT_NTSC_EN;
+ else
+ cr18 &= ~BIT_NTSC_EN;
+
+ __raw_writel(cr18, csi_dev->regbase + CSI_CSICR18);
+}
+
+static void csi_tvdec_enable(struct mx6s_csi_dev *csi_dev, bool enable)
+{
+ unsigned long cr18 = __raw_readl(csi_dev->regbase + CSI_CSICR18);
+ unsigned long cr1 = __raw_readl(csi_dev->regbase + CSI_CSICR1);
+
+ if (enable == true) {
+ cr18 |= (BIT_TVDECODER_IN_EN |
+ BIT_BASEADDR_SWITCH_EN |
+ BIT_BASEADDR_SWITCH_SEL |
+ BIT_BASEADDR_CHG_ERR_EN);
+ cr1 |= BIT_CCIR_MODE;
+ cr1 &= ~(BIT_SOF_POL | BIT_REDGE);
+ } else {
+ cr18 &= ~(BIT_TVDECODER_IN_EN |
+ BIT_BASEADDR_SWITCH_EN |
+ BIT_BASEADDR_SWITCH_SEL |
+ BIT_BASEADDR_CHG_ERR_EN);
+ cr1 &= ~BIT_CCIR_MODE;
+ cr1 |= BIT_SOF_POL | BIT_REDGE;
+ }
+
+ __raw_writel(cr18, csi_dev->regbase + CSI_CSICR18);
+ __raw_writel(cr1, csi_dev->regbase + CSI_CSICR1);
+}
+
+static void csi_dmareq_rff_enable(struct mx6s_csi_dev *csi_dev)
+{
+ unsigned long cr3 = __raw_readl(csi_dev->regbase + CSI_CSICR3);
+ unsigned long cr2 = __raw_readl(csi_dev->regbase + CSI_CSICR2);
+
+ /* Burst Type of DMA Transfer from RxFIFO. INCR16 */
+ cr2 |= 0xC0000000;
+
+ cr3 |= BIT_DMA_REQ_EN_RFF;
+ cr3 |= BIT_HRESP_ERR_EN;
+ cr3 &= ~BIT_RXFF_LEVEL;
+ cr3 |= 0x2 << 4;
+ if (csi_dev->csi_two_8bit_sensor_mode)
+ cr3 |= BIT_TWO_8BIT_SENSOR;
+
+ __raw_writel(cr3, csi_dev->regbase + CSI_CSICR3);
+ __raw_writel(cr2, csi_dev->regbase + CSI_CSICR2);
+}
+
+static void csi_dmareq_rff_disable(struct mx6s_csi_dev *csi_dev)
+{
+ unsigned long cr3 = __raw_readl(csi_dev->regbase + CSI_CSICR3);
+
+ cr3 &= ~BIT_DMA_REQ_EN_RFF;
+ cr3 &= ~BIT_HRESP_ERR_EN;
+ __raw_writel(cr3, csi_dev->regbase + CSI_CSICR3);
+}
+
+static void csi_set_imagpara(struct mx6s_csi_dev *csi,
+ int width, int height)
+{
+ int imag_para = 0;
+ unsigned long cr3 = __raw_readl(csi->regbase + CSI_CSICR3);
+
+ imag_para = (width << 16) | height;
+ __raw_writel(imag_para, csi->regbase + CSI_CSIIMAG_PARA);
+
+ /* reflash the embeded DMA controller */
+ __raw_writel(cr3 | BIT_DMA_REFLASH_RFF, csi->regbase + CSI_CSICR3);
+}
+
+static void csi_error_recovery(struct mx6s_csi_dev *csi_dev)
+{
+ u32 cr1, cr3, cr18;
+ /* software reset */
+
+ /* Disable csi */
+ cr18 = csi_read(csi_dev, CSI_CSICR18);
+ cr18 &= ~BIT_CSI_ENABLE;
+ csi_write(csi_dev, cr18, CSI_CSICR18);
+
+ /* Clear RX FIFO */
+ cr1 = csi_read(csi_dev, CSI_CSICR1);
+ csi_write(csi_dev, cr1 & ~BIT_FCC, CSI_CSICR1);
+ cr1 = csi_read(csi_dev, CSI_CSICR1);
+ csi_write(csi_dev, cr1 | BIT_CLR_RXFIFO, CSI_CSICR1);
+
+ cr1 = csi_read(csi_dev, CSI_CSICR1);
+ csi_write(csi_dev, cr1 | BIT_FCC, CSI_CSICR1);
+
+ /* DMA reflash */
+ cr3 = csi_read(csi_dev, CSI_CSICR3);
+ cr3 |= BIT_DMA_REFLASH_RFF;
+ csi_write(csi_dev, cr3, CSI_CSICR3);
+
+ /* Ensable csi */
+ cr18 |= BIT_CSI_ENABLE;
+ csi_write(csi_dev, cr18, CSI_CSICR18);
+}
+
+/*
+ * Videobuf operations
+ */
+static int mx6s_videobuf_setup(struct vb2_queue *vq,
+ unsigned int *count, unsigned int *num_planes,
+ unsigned int sizes[], struct device *alloc_devs[])
+{
+ struct mx6s_csi_dev *csi_dev = vb2_get_drv_priv(vq);
+
+ dev_dbg(csi_dev->dev, "count=%d, size=%d\n", *count, sizes[0]);
+
+ alloc_devs[0] = csi_dev->dev;
+
+ sizes[0] = csi_dev->pix.sizeimage;
+
+ pr_debug("size=%d\n", sizes[0]);
+ if (0 == *count)
+ *count = 32;
+ if (!*num_planes &&
+ sizes[0] * *count > MAX_VIDEO_MEM * 1024 * 1024)
+ *count = (MAX_VIDEO_MEM * 1024 * 1024) / sizes[0];
+
+ *num_planes = 1;
+
+ return 0;
+}
+
+static int mx6s_videobuf_prepare(struct vb2_buffer *vb)
+{
+ struct mx6s_csi_dev *csi_dev = vb2_get_drv_priv(vb->vb2_queue);
+ int ret = 0;
+
+ dev_dbg(csi_dev->dev, "%s (vb=0x%p) 0x%p %lu\n", __func__,
+ vb, vb2_plane_vaddr(vb, 0), vb2_get_plane_payload(vb, 0));
+
+#ifdef DEBUG
+ /*
+ * This can be useful if you want to see if we actually fill
+ * the buffer with something
+ */
+ if (vb2_plane_vaddr(vb, 0))
+ memset((void *)vb2_plane_vaddr(vb, 0),
+ 0xaa, vb2_get_plane_payload(vb, 0));
+#endif
+
+ vb2_set_plane_payload(vb, 0, csi_dev->pix.sizeimage);
+ if (vb2_plane_vaddr(vb, 0) &&
+ vb2_get_plane_payload(vb, 0) > vb2_plane_size(vb, 0)) {
+ ret = -EINVAL;
+ goto out;
+ }
+
+ return 0;
+
+out:
+ return ret;
+}
+
+static void mx6s_videobuf_queue(struct vb2_buffer *vb)
+{
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+ struct mx6s_csi_dev *csi_dev = vb2_get_drv_priv(vb->vb2_queue);
+ struct mx6s_buffer *buf = container_of(vbuf, struct mx6s_buffer, vb);
+ unsigned long flags;
+
+ dev_dbg(csi_dev->dev, "%s (vb=0x%p) 0x%p %lu\n", __func__,
+ vb, vb2_plane_vaddr(vb, 0), vb2_get_plane_payload(vb, 0));
+
+ spin_lock_irqsave(&csi_dev->slock, flags);
+
+ list_add_tail(&buf->internal.queue, &csi_dev->capture);
+
+ spin_unlock_irqrestore(&csi_dev->slock, flags);
+}
+
+static void mx6s_update_csi_buf(struct mx6s_csi_dev *csi_dev,
+ unsigned long phys, int bufnum)
+{
+ if (bufnum == 1)
+ csi_write(csi_dev, phys, CSI_CSIDMASA_FB2);
+ else
+ csi_write(csi_dev, phys, CSI_CSIDMASA_FB1);
+}
+
+static void mx6s_csi_init(struct mx6s_csi_dev *csi_dev)
+{
+ csi_clk_enable(csi_dev);
+ csihw_reset(csi_dev);
+ csi_init_interface(csi_dev);
+ csi_dmareq_rff_disable(csi_dev);
+}
+
+static void mx6s_csi_deinit(struct mx6s_csi_dev *csi_dev)
+{
+ csihw_reset(csi_dev);
+ csi_init_interface(csi_dev);
+ csi_dmareq_rff_disable(csi_dev);
+ csi_clk_disable(csi_dev);
+}
+
+static int mx6s_csi_enable(struct mx6s_csi_dev *csi_dev)
+{
+ struct v4l2_pix_format *pix = &csi_dev->pix;
+ unsigned long flags;
+ unsigned long val;
+ int timeout, timeout2;
+
+ csi_dev->skipframe = 0;
+ csisw_reset(csi_dev);
+
+ if (pix->field == V4L2_FIELD_INTERLACED)
+ csi_tvdec_enable(csi_dev, true);
+
+ /* For mipi csi input only */
+ if (csi_dev->csi_mipi_mode == true) {
+ csi_dmareq_rff_enable(csi_dev);
+ csi_enable_int(csi_dev, 1);
+ csi_enable(csi_dev, 1);
+ return 0;
+ }
+
+ local_irq_save(flags);
+ for (timeout = 10000000; timeout > 0; timeout--) {
+ if (csi_read(csi_dev, CSI_CSISR) & BIT_SOF_INT) {
+ val = csi_read(csi_dev, CSI_CSICR3);
+ csi_write(csi_dev, val | BIT_DMA_REFLASH_RFF,
+ CSI_CSICR3);
+ /* Wait DMA reflash done */
+ for (timeout2 = 1000000; timeout2 > 0; timeout2--) {
+ if (csi_read(csi_dev, CSI_CSICR3) &
+ BIT_DMA_REFLASH_RFF)
+ cpu_relax();
+ else
+ break;
+ }
+ if (timeout2 <= 0) {
+ pr_err("timeout when wait for reflash done.\n");
+ local_irq_restore(flags);
+ return -ETIME;
+ }
+ /* For imx6sl csi, DMA FIFO will auto start when sensor ready to work,
+ * so DMA should enable right after FIFO reset, otherwise dma will lost data
+ * and image will split.
+ */
+ csi_dmareq_rff_enable(csi_dev);
+ csi_enable_int(csi_dev, 1);
+ csi_enable(csi_dev, 1);
+ break;
+ } else
+ cpu_relax();
+ }
+ if (timeout <= 0) {
+ pr_err("timeout when wait for SOF\n");
+ local_irq_restore(flags);
+ return -ETIME;
+ }
+ local_irq_restore(flags);
+
+ return 0;
+}
+
+static void mx6s_csi_disable(struct mx6s_csi_dev *csi_dev)
+{
+ struct v4l2_pix_format *pix = &csi_dev->pix;
+
+ csi_dmareq_rff_disable(csi_dev);
+ csi_disable_int(csi_dev);
+
+ /* set CSI_CSIDMASA_FB1 and CSI_CSIDMASA_FB2 to default value */
+ csi_write(csi_dev, 0, CSI_CSIDMASA_FB1);
+ csi_write(csi_dev, 0, CSI_CSIDMASA_FB2);
+
+ csi_buf_stride_set(csi_dev, 0);
+
+ if (pix->field == V4L2_FIELD_INTERLACED) {
+ csi_deinterlace_enable(csi_dev, false);
+ csi_tvdec_enable(csi_dev, false);
+ }
+
+ csi_enable(csi_dev, 0);
+}
+
+static int mx6s_configure_csi(struct mx6s_csi_dev *csi_dev)
+{
+ struct v4l2_pix_format *pix = &csi_dev->pix;
+ u32 cr1, cr18;
+ u32 width;
+
+ if (pix->field == V4L2_FIELD_INTERLACED) {
+ csi_deinterlace_enable(csi_dev, true);
+ csi_buf_stride_set(csi_dev, csi_dev->pix.width);
+ csi_deinterlace_mode(csi_dev, csi_dev->std);
+ } else {
+ csi_deinterlace_enable(csi_dev, false);
+ csi_buf_stride_set(csi_dev, 0);
+ }
+
+ switch (csi_dev->fmt->pixelformat) {
+ case V4L2_PIX_FMT_YUV32:
+ case V4L2_PIX_FMT_SBGGR8:
+ width = pix->width;
+ break;
+ case V4L2_PIX_FMT_UYVY:
+ case V4L2_PIX_FMT_YUYV:
+ if (csi_dev->csi_mipi_mode == true)
+ width = pix->width;
+ else
+ /* For parallel 8-bit sensor input */
+ width = pix->width * 2;
+ break;
+ default:
+ pr_debug(" case not supported\n");
+ return -EINVAL;
+ }
+ csi_set_imagpara(csi_dev, width, pix->height);
+
+ if (csi_dev->csi_mipi_mode == true) {
+ cr1 = csi_read(csi_dev, CSI_CSICR1);
+ cr1 &= ~BIT_GCLK_MODE;
+ csi_write(csi_dev, cr1, CSI_CSICR1);
+
+ cr18 = csi_read(csi_dev, CSI_CSICR18);
+ cr18 &= ~BIT_MIPI_DATA_FORMAT_MASK;
+ cr18 |= BIT_DATA_FROM_MIPI;
+
+ switch (csi_dev->fmt->pixelformat) {
+ case V4L2_PIX_FMT_UYVY:
+ case V4L2_PIX_FMT_YUYV:
+ cr18 |= BIT_MIPI_DATA_FORMAT_YUV422_8B;
+ break;
+ case V4L2_PIX_FMT_SBGGR8:
+ cr18 |= BIT_MIPI_DATA_FORMAT_RAW8;
+ break;
+ default:
+ pr_debug(" fmt not supported\n");
+ return -EINVAL;
+ }
+
+ csi_write(csi_dev, cr18, CSI_CSICR18);
+ }
+ return 0;
+}
+
+static int mx6s_start_streaming(struct vb2_queue *vq, unsigned int count)
+{
+ struct mx6s_csi_dev *csi_dev = vb2_get_drv_priv(vq);
+ struct vb2_buffer *vb;
+ struct mx6s_buffer *buf;
+ unsigned long phys;
+ unsigned long flags;
+
+ if (count < 2)
+ return -ENOBUFS;
+
+ /*
+ * I didn't manage to properly enable/disable
+ * a per frame basis during running transfers,
+ * thus we allocate a buffer here and use it to
+ * discard frames when no buffer is available.
+ * Feel free to work on this ;)
+ */
+ csi_dev->discard_size = csi_dev->pix.sizeimage;
+ csi_dev->discard_buffer = dma_alloc_coherent(csi_dev->v4l2_dev.dev,
+ PAGE_ALIGN(csi_dev->discard_size),
+ &csi_dev->discard_buffer_dma,
+ GFP_DMA | GFP_KERNEL);
+ if (!csi_dev->discard_buffer)
+ return -ENOMEM;
+
+ spin_lock_irqsave(&csi_dev->slock, flags);
+
+ csi_dev->buf_discard[0].discard = true;
+ list_add_tail(&csi_dev->buf_discard[0].queue,
+ &csi_dev->discard);
+
+ csi_dev->buf_discard[1].discard = true;
+ list_add_tail(&csi_dev->buf_discard[1].queue,
+ &csi_dev->discard);
+
+ /* csi buf 0 */
+ buf = list_first_entry(&csi_dev->capture, struct mx6s_buffer,
+ internal.queue);
+ buf->internal.bufnum = 0;
+ vb = &buf->vb.vb2_buf;
+ vb->state = VB2_BUF_STATE_ACTIVE;
+
+ phys = vb2_dma_contig_plane_dma_addr(vb, 0);
+
+ mx6s_update_csi_buf(csi_dev, phys, buf->internal.bufnum);
+ list_move_tail(csi_dev->capture.next, &csi_dev->active_bufs);
+
+ /* csi buf 1 */
+ buf = list_first_entry(&csi_dev->capture, struct mx6s_buffer,
+ internal.queue);
+ buf->internal.bufnum = 1;
+ vb = &buf->vb.vb2_buf;
+ vb->state = VB2_BUF_STATE_ACTIVE;
+
+ phys = vb2_dma_contig_plane_dma_addr(vb, 0);
+ mx6s_update_csi_buf(csi_dev, phys, buf->internal.bufnum);
+ list_move_tail(csi_dev->capture.next, &csi_dev->active_bufs);
+
+ csi_dev->nextfb = 0;
+
+ spin_unlock_irqrestore(&csi_dev->slock, flags);
+
+ return mx6s_csi_enable(csi_dev);
+}
+
+static void mx6s_stop_streaming(struct vb2_queue *vq)
+{
+ struct mx6s_csi_dev *csi_dev = vb2_get_drv_priv(vq);
+ unsigned long flags;
+ struct mx6s_buffer *buf, *tmp;
+ void *b;
+
+ mx6s_csi_disable(csi_dev);
+
+ spin_lock_irqsave(&csi_dev->slock, flags);
+
+ list_for_each_entry_safe(buf, tmp,
+ &csi_dev->active_bufs, internal.queue) {
+ list_del_init(&buf->internal.queue);
+ if (buf->vb.vb2_buf.state == VB2_BUF_STATE_ACTIVE)
+ vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
+ }
+
+ list_for_each_entry_safe(buf, tmp,
+ &csi_dev->capture, internal.queue) {
+ list_del_init(&buf->internal.queue);
+ if (buf->vb.vb2_buf.state == VB2_BUF_STATE_ACTIVE)
+ vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
+ }
+
+ INIT_LIST_HEAD(&csi_dev->capture);
+ INIT_LIST_HEAD(&csi_dev->active_bufs);
+ INIT_LIST_HEAD(&csi_dev->discard);
+
+ b = csi_dev->discard_buffer;
+ csi_dev->discard_buffer = NULL;
+
+ spin_unlock_irqrestore(&csi_dev->slock, flags);
+
+ dma_free_coherent(csi_dev->v4l2_dev.dev,
+ csi_dev->discard_size, b,
+ csi_dev->discard_buffer_dma);
+}
+
+static struct vb2_ops mx6s_videobuf_ops = {
+ .queue_setup = mx6s_videobuf_setup,
+ .buf_prepare = mx6s_videobuf_prepare,
+ .buf_queue = mx6s_videobuf_queue,
+ .wait_prepare = vb2_ops_wait_prepare,
+ .wait_finish = vb2_ops_wait_finish,
+ .start_streaming = mx6s_start_streaming,
+ .stop_streaming = mx6s_stop_streaming,
+};
+
+static void mx6s_csi_frame_done(struct mx6s_csi_dev *csi_dev,
+ int bufnum, bool err)
+{
+ struct mx6s_buf_internal *ibuf;
+ struct mx6s_buffer *buf;
+ struct vb2_buffer *vb;
+ unsigned long phys;
+ unsigned int phys_fb1;
+ unsigned int phys_fb2;
+
+ ibuf = list_first_entry(&csi_dev->active_bufs, struct mx6s_buf_internal,
+ queue);
+
+ if (ibuf->discard) {
+ /*
+ * Discard buffer must not be returned to user space.
+ * Just return it to the discard queue.
+ */
+ list_move_tail(csi_dev->active_bufs.next, &csi_dev->discard);
+ } else {
+ buf = mx6s_ibuf_to_buf(ibuf);
+
+ vb = &buf->vb.vb2_buf;
+ phys = vb2_dma_contig_plane_dma_addr(vb, 0);
+ if (bufnum == 1) {
+ phys_fb2 = csi_read(csi_dev, CSI_CSIDMASA_FB2);
+ if (phys_fb2 != (u32)phys) {
+ dev_err(csi_dev->dev, "%lx != %x\n", phys,
+ phys_fb2);
+ }
+ } else {
+ phys_fb1 = csi_read(csi_dev, CSI_CSIDMASA_FB1);
+ if (phys_fb1 != (u32)phys) {
+ dev_err(csi_dev->dev, "%lx != %x\n", phys,
+ phys_fb1);
+ }
+ }
+ dev_dbg(csi_dev->dev, "%s (vb=0x%p) 0x%p %lu\n", __func__, vb,
+ vb2_plane_vaddr(vb, 0),
+ vb2_get_plane_payload(vb, 0));
+
+ list_del_init(&buf->internal.queue);
+ vb->timestamp =ktime_get_ns();
+ to_vb2_v4l2_buffer(vb)->sequence = csi_dev->frame_count;
+ if (err)
+ vb2_buffer_done(vb, VB2_BUF_STATE_ERROR);
+ else
+ vb2_buffer_done(vb, VB2_BUF_STATE_DONE);
+ }
+
+ csi_dev->frame_count++;
+ csi_dev->nextfb = (bufnum == 0 ? 1: 0);
+
+ /* Config discard buffer to active_bufs */
+ if (list_empty(&csi_dev->capture)) {
+ if (list_empty(&csi_dev->discard)) {
+ dev_warn(csi_dev->dev,
+ "%s: trying to access empty discard list\n",
+ __func__);
+ return;
+ }
+
+ ibuf = list_first_entry(&csi_dev->discard,
+ struct mx6s_buf_internal, queue);
+ ibuf->bufnum = bufnum;
+
+ list_move_tail(csi_dev->discard.next, &csi_dev->active_bufs);
+
+ mx6s_update_csi_buf(csi_dev,
+ csi_dev->discard_buffer_dma, bufnum);
+ return;
+ }
+
+ buf = list_first_entry(&csi_dev->capture, struct mx6s_buffer,
+ internal.queue);
+
+ buf->internal.bufnum = bufnum;
+
+ list_move_tail(csi_dev->capture.next, &csi_dev->active_bufs);
+
+ vb = &buf->vb.vb2_buf;
+ vb->state = VB2_BUF_STATE_ACTIVE;
+
+ phys = vb2_dma_contig_plane_dma_addr(vb, 0);
+ mx6s_update_csi_buf(csi_dev, phys, bufnum);
+}
+
+static irqreturn_t mx6s_csi_irq_handler(int irq, void *data)
+{
+ struct mx6s_csi_dev *csi_dev = data;
+ unsigned long status;
+ u32 cr3, cr18;
+
+ spin_lock(&csi_dev->slock);
+
+ status = csi_read(csi_dev, CSI_CSISR);
+ csi_write(csi_dev, status, CSI_CSISR);
+
+ if (list_empty(&csi_dev->active_bufs)) {
+ dev_warn(csi_dev->dev,
+ "%s: called while active list is empty\n",
+ __func__);
+
+ spin_unlock(&csi_dev->slock);
+ return IRQ_HANDLED;
+ }
+
+ if (status & BIT_RFF_OR_INT) {
+ dev_warn(csi_dev->dev, "%s Rx fifo overflow\n", __func__);
+ if (csi_dev->soc->rx_fifo_rst)
+ csi_error_recovery(csi_dev);
+ }
+
+ if (status & BIT_HRESP_ERR_INT) {
+ dev_warn(csi_dev->dev, "%s Hresponse error detected\n",
+ __func__);
+ csi_error_recovery(csi_dev);
+ }
+
+ if (status & BIT_ADDR_CH_ERR_INT) {
+ /* Disable csi */
+ cr18 = csi_read(csi_dev, CSI_CSICR18);
+ cr18 &= ~BIT_CSI_ENABLE;
+ csi_write(csi_dev, cr18, CSI_CSICR18);
+
+ /* DMA reflash */
+ cr3 = csi_read(csi_dev, CSI_CSICR3);
+ cr3 |= BIT_DMA_REFLASH_RFF;
+ csi_write(csi_dev, cr3, CSI_CSICR3);
+
+ /* Ensable csi */
+ cr18 |= BIT_CSI_ENABLE;
+ csi_write(csi_dev, cr18, CSI_CSICR18);
+
+ csi_dev->skipframe = 1;
+ pr_debug("base address switching Change Err.\n");
+ }
+
+ if ((status & BIT_DMA_TSF_DONE_FB1) &&
+ (status & BIT_DMA_TSF_DONE_FB2)) {
+ /* For both FB1 and FB2 interrupter bits set case,
+ * CSI DMA is work in one of FB1 and FB2 buffer,
+ * but software can not know the state.
+ * Skip it to avoid base address updated
+ * when csi work in field0 and field1 will write to
+ * new base address.
+ * PDM TKT230775 */
+ pr_debug("Skip two frames\n");
+ } else if (status & BIT_DMA_TSF_DONE_FB1) {
+ if (csi_dev->nextfb == 0) {
+ if (csi_dev->skipframe > 0)
+ csi_dev->skipframe--;
+ else
+ mx6s_csi_frame_done(csi_dev, 0, false);
+ } else
+ pr_warn("skip frame 0 \n");
+
+ } else if (status & BIT_DMA_TSF_DONE_FB2) {
+ if (csi_dev->nextfb == 1) {
+ if (csi_dev->skipframe > 0)
+ csi_dev->skipframe--;
+ else
+ mx6s_csi_frame_done(csi_dev, 1, false);
+ } else
+ pr_warn("skip frame 1 \n");
+ }
+
+ spin_unlock(&csi_dev->slock);
+
+ return IRQ_HANDLED;
+}
+
+/*
+ * File operations for the device
+ */
+static int mx6s_csi_open(struct file *file)
+{
+ struct mx6s_csi_dev *csi_dev = video_drvdata(file);
+ struct v4l2_subdev *sd = csi_dev->sd;
+ struct vb2_queue *q = &csi_dev->vb2_vidq;
+ int ret = 0;
+
+ file->private_data = csi_dev;
+
+ if (mutex_lock_interruptible(&csi_dev->lock))
+ return -ERESTARTSYS;
+
+ q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ q->io_modes = VB2_MMAP | VB2_USERPTR;
+ q->drv_priv = csi_dev;
+ q->ops = &mx6s_videobuf_ops;
+ q->mem_ops = &vb2_dma_contig_memops;
+ q->buf_struct_size = sizeof(struct mx6s_buffer);
+ q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
+ q->lock = &csi_dev->lock;
+
+ ret = vb2_queue_init(q);
+ if (ret < 0)
+ goto unlock;
+
+ pm_runtime_get_sync(csi_dev->dev);
+
+ request_bus_freq(BUS_FREQ_HIGH);
+
+ v4l2_subdev_call(sd, core, s_power, 1);
+ mx6s_csi_init(csi_dev);
+
+ mutex_unlock(&csi_dev->lock);
+
+ return ret;
+unlock:
+ mutex_unlock(&csi_dev->lock);
+ return ret;
+}
+
+static int mx6s_csi_close(struct file *file)
+{
+ struct mx6s_csi_dev *csi_dev = video_drvdata(file);
+ struct v4l2_subdev *sd = csi_dev->sd;
+
+ mutex_lock(&csi_dev->lock);
+
+ vb2_queue_release(&csi_dev->vb2_vidq);
+
+ mx6s_csi_deinit(csi_dev);
+ v4l2_subdev_call(sd, core, s_power, 0);
+
+ mutex_unlock(&csi_dev->lock);
+
+ file->private_data = NULL;
+
+ release_bus_freq(BUS_FREQ_HIGH);
+
+ pm_runtime_put_sync_suspend(csi_dev->dev);
+ return 0;
+}
+
+static ssize_t mx6s_csi_read(struct file *file, char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ struct mx6s_csi_dev *csi_dev = video_drvdata(file);
+ int ret;
+
+ dev_dbg(csi_dev->dev, "read called, buf %p\n", buf);
+
+ mutex_lock(&csi_dev->lock);
+ ret = vb2_read(&csi_dev->vb2_vidq, buf, count, ppos,
+ file->f_flags & O_NONBLOCK);
+ mutex_unlock(&csi_dev->lock);
+ return ret;
+}
+
+static int mx6s_csi_mmap(struct file *file, struct vm_area_struct *vma)
+{
+ struct mx6s_csi_dev *csi_dev = video_drvdata(file);
+ int ret;
+
+ if (mutex_lock_interruptible(&csi_dev->lock))
+ return -ERESTARTSYS;
+ ret = vb2_mmap(&csi_dev->vb2_vidq, vma);
+ mutex_unlock(&csi_dev->lock);
+
+ pr_debug("vma start=0x%08lx, size=%ld, ret=%d\n",
+ (unsigned long)vma->vm_start,
+ (unsigned long)vma->vm_end-(unsigned long)vma->vm_start,
+ ret);
+
+ return ret;
+}
+
+static struct v4l2_file_operations mx6s_csi_fops = {
+ .owner = THIS_MODULE,
+ .open = mx6s_csi_open,
+ .release = mx6s_csi_close,
+ .read = mx6s_csi_read,
+ .poll = vb2_fop_poll,
+ .unlocked_ioctl = video_ioctl2, /* V4L2 ioctl handler */
+ .mmap = mx6s_csi_mmap,
+};
+
+/*
+ * Video node IOCTLs
+ */
+static int mx6s_vidioc_enum_input(struct file *file, void *priv,
+ struct v4l2_input *inp)
+{
+ if (inp->index != 0)
+ return -EINVAL;
+
+ /* default is camera */
+ inp->type = V4L2_INPUT_TYPE_CAMERA;
+ strcpy(inp->name, "Camera");
+
+ return 0;
+}
+
+static int mx6s_vidioc_g_input(struct file *file, void *priv, unsigned int *i)
+{
+ *i = 0;
+
+ return 0;
+}
+
+static int mx6s_vidioc_s_input(struct file *file, void *priv, unsigned int i)
+{
+ if (i > 0)
+ return -EINVAL;
+
+ return 0;
+}
+
+static int mx6s_vidioc_querystd(struct file *file, void *priv, v4l2_std_id *a)
+{
+ struct mx6s_csi_dev *csi_dev = video_drvdata(file);
+ struct v4l2_subdev *sd = csi_dev->sd;
+
+ return v4l2_subdev_call(sd, video, querystd, a);
+}
+
+static int mx6s_vidioc_s_std(struct file *file, void *priv, v4l2_std_id a)
+{
+ struct mx6s_csi_dev *csi_dev = video_drvdata(file);
+ struct v4l2_subdev *sd = csi_dev->sd;
+
+ return v4l2_subdev_call(sd, video, s_std, a);
+}
+
+static int mx6s_vidioc_g_std(struct file *file, void *priv, v4l2_std_id *a)
+{
+ struct mx6s_csi_dev *csi_dev = video_drvdata(file);
+ struct v4l2_subdev *sd = csi_dev->sd;
+
+ return v4l2_subdev_call(sd, video, g_std, a);
+}
+
+static int mx6s_vidioc_reqbufs(struct file *file, void *priv,
+ struct v4l2_requestbuffers *p)
+{
+ struct mx6s_csi_dev *csi_dev = video_drvdata(file);
+
+ WARN_ON(priv != file->private_data);
+
+ return vb2_reqbufs(&csi_dev->vb2_vidq, p);
+}
+
+static int mx6s_vidioc_querybuf(struct file *file, void *priv,
+ struct v4l2_buffer *p)
+{
+ struct mx6s_csi_dev *csi_dev = video_drvdata(file);
+ int ret;
+
+ WARN_ON(priv != file->private_data);
+
+ ret = vb2_querybuf(&csi_dev->vb2_vidq, p);
+
+ if (!ret) {
+ /* return physical address */
+ struct vb2_buffer *vb = csi_dev->vb2_vidq.bufs[p->index];
+ if (p->flags & V4L2_BUF_FLAG_MAPPED)
+ p->m.offset = vb2_dma_contig_plane_dma_addr(vb, 0);
+ }
+ return ret;
+}
+
+static int mx6s_vidioc_qbuf(struct file *file, void *priv,
+ struct v4l2_buffer *p)
+{
+ struct mx6s_csi_dev *csi_dev = video_drvdata(file);
+
+ WARN_ON(priv != file->private_data);
+
+ return vb2_qbuf(&csi_dev->vb2_vidq, p);
+}
+
+static int mx6s_vidioc_dqbuf(struct file *file, void *priv,
+ struct v4l2_buffer *p)
+{
+ struct mx6s_csi_dev *csi_dev = video_drvdata(file);
+
+ WARN_ON(priv != file->private_data);
+
+ return vb2_dqbuf(&csi_dev->vb2_vidq, p, file->f_flags & O_NONBLOCK);
+}
+
+static int mx6s_vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
+ struct v4l2_fmtdesc *f)
+{
+ struct mx6s_csi_dev *csi_dev = video_drvdata(file);
+ struct v4l2_subdev *sd = csi_dev->sd;
+ struct v4l2_subdev_mbus_code_enum code = {
+ .which = V4L2_SUBDEV_FORMAT_ACTIVE,
+ .index = f->index,
+ };
+ struct mx6s_fmt *fmt;
+ int ret;
+
+ WARN_ON(priv != file->private_data);
+
+ ret = v4l2_subdev_call(sd, pad, enum_mbus_code, NULL, &code);
+ if (ret < 0) {
+ /* no more formats */
+ dev_dbg(csi_dev->dev, "No more fmt\n");
+ return -EINVAL;
+ }
+
+ fmt = format_by_mbus(code.code);
+ if (!fmt) {
+ dev_err(csi_dev->dev, "mbus (0x%08x) invalid.\n", code.code);
+ return -EINVAL;
+ }
+
+ strlcpy(f->description, fmt->name, sizeof(f->description));
+ f->pixelformat = fmt->pixelformat;
+
+ return 0;
+}
+
+static int mx6s_vidioc_try_fmt_vid_cap(struct file *file, void *priv,
+ struct v4l2_format *f)
+{
+ struct mx6s_csi_dev *csi_dev = video_drvdata(file);
+ struct v4l2_subdev *sd = csi_dev->sd;
+ struct v4l2_pix_format *pix = &f->fmt.pix;
+ struct v4l2_subdev_format format = {
+ .which = V4L2_SUBDEV_FORMAT_ACTIVE,
+ };
+ struct mx6s_fmt *fmt;
+ int ret;
+
+ fmt = format_by_fourcc(f->fmt.pix.pixelformat);
+ if (!fmt) {
+ dev_err(csi_dev->dev, "Fourcc format (0x%08x) invalid.",
+ f->fmt.pix.pixelformat);
+ return -EINVAL;
+ }
+
+ if (f->fmt.pix.width == 0 || f->fmt.pix.height == 0) {
+ dev_err(csi_dev->dev, "width %d, height %d is too small.\n",
+ f->fmt.pix.width, f->fmt.pix.height);
+ return -EINVAL;
+ }
+
+ v4l2_fill_mbus_format(&format.format, pix, fmt->mbus_code);
+ ret = v4l2_subdev_call(sd, pad, set_fmt, NULL, &format);
+ v4l2_fill_pix_format(pix, &format.format);
+
+ if (pix->field != V4L2_FIELD_INTERLACED)
+ pix->field = V4L2_FIELD_NONE;
+
+ pix->sizeimage = fmt->bpp * pix->height * pix->width;
+ pix->bytesperline = fmt->bpp * pix->width;
+
+ return ret;
+}
+
+/*
+ * The real work of figuring out a workable format.
+ */
+
+static int mx6s_vidioc_s_fmt_vid_cap(struct file *file, void *priv,
+ struct v4l2_format *f)
+{
+ struct mx6s_csi_dev *csi_dev = video_drvdata(file);
+ int ret;
+
+ ret = mx6s_vidioc_try_fmt_vid_cap(file, csi_dev, f);
+ if (ret < 0)
+ return ret;
+
+ csi_dev->fmt = format_by_fourcc(f->fmt.pix.pixelformat);
+ csi_dev->mbus_code = csi_dev->fmt->mbus_code;
+ csi_dev->pix.width = f->fmt.pix.width;
+ csi_dev->pix.height = f->fmt.pix.height;
+ csi_dev->pix.sizeimage = f->fmt.pix.sizeimage;
+ csi_dev->pix.field = f->fmt.pix.field;
+ csi_dev->type = f->type;
+ dev_dbg(csi_dev->dev, "set to pixelformat '%4.6s'\n",
+ (char *)&csi_dev->fmt->name);
+
+ /* Config csi */
+ mx6s_configure_csi(csi_dev);
+
+ return 0;
+}
+
+static int mx6s_vidioc_g_fmt_vid_cap(struct file *file, void *priv,
+ struct v4l2_format *f)
+{
+ struct mx6s_csi_dev *csi_dev = video_drvdata(file);
+
+ WARN_ON(priv != file->private_data);
+
+ f->fmt.pix = csi_dev->pix;
+
+ return 0;
+}
+
+static int mx6s_vidioc_querycap(struct file *file, void *priv,
+ struct v4l2_capability *cap)
+{
+ struct mx6s_csi_dev *csi_dev = video_drvdata(file);
+
+ WARN_ON(priv != file->private_data);
+
+ /* cap->name is set by the friendly caller:-> */
+ strlcpy(cap->driver, MX6S_CAM_DRV_NAME, sizeof(cap->driver));
+ strlcpy(cap->card, MX6S_CAM_DRIVER_DESCRIPTION, sizeof(cap->card));
+ snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s",
+ dev_name(csi_dev->dev));
+
+ cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
+ cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
+ return 0;
+}
+
+static int mx6s_vidioc_expbuf(struct file *file, void *priv,
+ struct v4l2_exportbuffer *eb)
+{
+ struct mx6s_csi_dev *csi_dev = video_drvdata(file);
+
+ if (eb->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ return vb2_expbuf(&csi_dev->vb2_vidq, eb);
+
+ return -EINVAL;
+}
+
+static int mx6s_vidioc_streamon(struct file *file, void *priv,
+ enum v4l2_buf_type i)
+{
+ struct mx6s_csi_dev *csi_dev = video_drvdata(file);
+ struct v4l2_subdev *sd = csi_dev->sd;
+ int ret;
+
+ WARN_ON(priv != file->private_data);
+
+ if (i != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ return -EINVAL;
+
+ ret = vb2_streamon(&csi_dev->vb2_vidq, i);
+ if (!ret)
+ v4l2_subdev_call(sd, video, s_stream, 1);
+
+ return ret;
+}
+
+static int mx6s_vidioc_streamoff(struct file *file, void *priv,
+ enum v4l2_buf_type i)
+{
+ struct mx6s_csi_dev *csi_dev = video_drvdata(file);
+ struct v4l2_subdev *sd = csi_dev->sd;
+
+ WARN_ON(priv != file->private_data);
+
+ if (i != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ return -EINVAL;
+
+ /*
+ * This calls buf_release from host driver's videobuf_queue_ops for all
+ * remaining buffers. When the last buffer is freed, stop capture
+ */
+ vb2_streamoff(&csi_dev->vb2_vidq, i);
+
+ v4l2_subdev_call(sd, video, s_stream, 0);
+
+ return 0;
+}
+
+static int mx6s_vidioc_cropcap(struct file *file, void *fh,
+ struct v4l2_cropcap *a)
+{
+ struct mx6s_csi_dev *csi_dev = video_drvdata(file);
+
+ if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ return -EINVAL;
+ dev_dbg(csi_dev->dev, "VIDIOC_CROPCAP not implemented\n");
+
+ return 0;
+}
+
+static int mx6s_vidioc_g_crop(struct file *file, void *priv,
+ struct v4l2_crop *a)
+{
+ struct mx6s_csi_dev *csi_dev = video_drvdata(file);
+
+ if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ return -EINVAL;
+ dev_dbg(csi_dev->dev, "VIDIOC_G_CROP not implemented\n");
+
+ return 0;
+}
+
+static int mx6s_vidioc_s_crop(struct file *file, void *priv,
+ const struct v4l2_crop *a)
+{
+ struct mx6s_csi_dev *csi_dev = video_drvdata(file);
+
+ if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ return -EINVAL;
+
+ dev_dbg(csi_dev->dev, "VIDIOC_S_CROP not implemented\n");
+
+ return 0;
+}
+
+static int mx6s_vidioc_g_parm(struct file *file, void *priv,
+ struct v4l2_streamparm *a)
+{
+ struct mx6s_csi_dev *csi_dev = video_drvdata(file);
+ struct v4l2_subdev *sd = csi_dev->sd;
+
+ return v4l2_subdev_call(sd, video, g_parm, a);
+}
+
+static int mx6s_vidioc_s_parm(struct file *file, void *priv,
+ struct v4l2_streamparm *a)
+{
+ struct mx6s_csi_dev *csi_dev = video_drvdata(file);
+ struct v4l2_subdev *sd = csi_dev->sd;
+
+ return v4l2_subdev_call(sd, video, s_parm, a);
+}
+
+static int mx6s_vidioc_enum_framesizes(struct file *file, void *priv,
+ struct v4l2_frmsizeenum *fsize)
+{
+ struct mx6s_csi_dev *csi_dev = video_drvdata(file);
+ struct v4l2_subdev *sd = csi_dev->sd;
+ struct mx6s_fmt *fmt;
+ struct v4l2_subdev_frame_size_enum fse = {
+ .index = fsize->index,
+ .which = V4L2_SUBDEV_FORMAT_ACTIVE,
+ };
+ int ret;
+
+ fmt = format_by_fourcc(fsize->pixel_format);
+ if (fmt->pixelformat != fsize->pixel_format)
+ return -EINVAL;
+ fse.code = fmt->mbus_code;
+
+ ret = v4l2_subdev_call(sd, pad, enum_frame_size, NULL, &fse);
+ if (ret)
+ return ret;
+
+ if (fse.min_width == fse.max_width &&
+ fse.min_height == fse.max_height) {
+ fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
+ fsize->discrete.width = fse.min_width;
+ fsize->discrete.height = fse.min_height;
+ return 0;
+ }
+
+ fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
+ fsize->stepwise.min_width = fse.min_width;
+ fsize->stepwise.max_width = fse.max_width;
+ fsize->stepwise.min_height = fse.min_height;
+ fsize->stepwise.max_height = fse.max_height;
+ fsize->stepwise.step_width = 1;
+ fsize->stepwise.step_height = 1;
+
+ return 0;
+}
+
+static int mx6s_vidioc_enum_frameintervals(struct file *file, void *priv,
+ struct v4l2_frmivalenum *interval)
+{
+ struct mx6s_csi_dev *csi_dev = video_drvdata(file);
+ struct v4l2_subdev *sd = csi_dev->sd;
+ struct mx6s_fmt *fmt;
+ struct v4l2_subdev_frame_interval_enum fie = {
+ .index = interval->index,
+ .width = interval->width,
+ .height = interval->height,
+ .which = V4L2_SUBDEV_FORMAT_ACTIVE,
+ };
+ int ret;
+
+ fmt = format_by_fourcc(interval->pixel_format);
+ if (fmt->pixelformat != interval->pixel_format)
+ return -EINVAL;
+ fie.code = fmt->mbus_code;
+
+ ret = v4l2_subdev_call(sd, pad, enum_frame_interval, NULL, &fie);
+ if (ret)
+ return ret;
+ interval->type = V4L2_FRMIVAL_TYPE_DISCRETE;
+ interval->discrete = fie.interval;
+ return 0;
+}
+
+static const struct v4l2_ioctl_ops mx6s_csi_ioctl_ops = {
+ .vidioc_querycap = mx6s_vidioc_querycap,
+ .vidioc_enum_fmt_vid_cap = mx6s_vidioc_enum_fmt_vid_cap,
+ .vidioc_try_fmt_vid_cap = mx6s_vidioc_try_fmt_vid_cap,
+ .vidioc_g_fmt_vid_cap = mx6s_vidioc_g_fmt_vid_cap,
+ .vidioc_s_fmt_vid_cap = mx6s_vidioc_s_fmt_vid_cap,
+ .vidioc_cropcap = mx6s_vidioc_cropcap,
+ .vidioc_s_crop = mx6s_vidioc_s_crop,
+ .vidioc_g_crop = mx6s_vidioc_g_crop,
+ .vidioc_reqbufs = mx6s_vidioc_reqbufs,
+ .vidioc_querybuf = mx6s_vidioc_querybuf,
+ .vidioc_qbuf = mx6s_vidioc_qbuf,
+ .vidioc_dqbuf = mx6s_vidioc_dqbuf,
+ .vidioc_g_std = mx6s_vidioc_g_std,
+ .vidioc_s_std = mx6s_vidioc_s_std,
+ .vidioc_querystd = mx6s_vidioc_querystd,
+ .vidioc_enum_input = mx6s_vidioc_enum_input,
+ .vidioc_g_input = mx6s_vidioc_g_input,
+ .vidioc_s_input = mx6s_vidioc_s_input,
+ .vidioc_expbuf = mx6s_vidioc_expbuf,
+ .vidioc_streamon = mx6s_vidioc_streamon,
+ .vidioc_streamoff = mx6s_vidioc_streamoff,
+ .vidioc_g_parm = mx6s_vidioc_g_parm,
+ .vidioc_s_parm = mx6s_vidioc_s_parm,
+ .vidioc_enum_framesizes = mx6s_vidioc_enum_framesizes,
+ .vidioc_enum_frameintervals = mx6s_vidioc_enum_frameintervals,
+};
+
+static int subdev_notifier_bound(struct v4l2_async_notifier *notifier,
+ struct v4l2_subdev *subdev,
+ struct v4l2_async_subdev *asd)
+{
+ struct mx6s_csi_dev *csi_dev = notifier_to_mx6s_dev(notifier);
+
+ /* Find platform data for this sensor subdev */
+ if (csi_dev->asd.match.fwnode.fwnode == dev_fwnode(subdev->dev))
+ csi_dev->sd = subdev;
+
+ if (subdev == NULL)
+ return -EINVAL;
+
+ v4l2_info(&csi_dev->v4l2_dev, "Registered sensor subdevice: %s\n",
+ subdev->name);
+
+ return 0;
+}
+
+static int mx6s_csi_mode_sel(struct mx6s_csi_dev *csi_dev)
+{
+ struct device_node *np = csi_dev->dev->of_node;
+ struct device_node *node;
+ phandle phandle;
+ u32 out_val[3];
+ int ret = 0;
+
+ if (of_get_property(np, "fsl,mipi-mode", NULL))
+ csi_dev->csi_mipi_mode = true;
+ else {
+ csi_dev->csi_mipi_mode = false;
+ return ret;
+ }
+
+ ret = of_property_read_u32_array(np, "csi-mux-mipi", out_val, 3);
+ if (ret) {
+ dev_dbg(csi_dev->dev, "no csi-mux-mipi property found\n");
+ } else {
+ phandle = *out_val;
+
+ node = of_find_node_by_phandle(phandle);
+ if (!node) {
+ dev_dbg(csi_dev->dev, "not find gpr node by phandle\n");
+ ret = PTR_ERR(node);
+ }
+ csi_dev->csi_mux.gpr = syscon_node_to_regmap(node);
+ if (IS_ERR(csi_dev->csi_mux.gpr)) {
+ dev_err(csi_dev->dev, "failed to get gpr regmap\n");
+ ret = PTR_ERR(csi_dev->csi_mux.gpr);
+ }
+ of_node_put(node);
+ if (ret < 0)
+ return ret;
+
+ csi_dev->csi_mux.req_gpr = out_val[1];
+ csi_dev->csi_mux.req_bit = out_val[2];
+
+ regmap_update_bits(csi_dev->csi_mux.gpr, csi_dev->csi_mux.req_gpr,
+ 1 << csi_dev->csi_mux.req_bit, 1 << csi_dev->csi_mux.req_bit);
+ }
+ return ret;
+}
+
+static int mx6s_csi_two_8bit_sensor_mode_sel(struct mx6s_csi_dev *csi_dev)
+{
+ struct device_node *np = csi_dev->dev->of_node;
+
+ if (of_get_property(np, "fsl,two-8bit-sensor-mode", NULL))
+ csi_dev->csi_two_8bit_sensor_mode = true;
+ else {
+ csi_dev->csi_two_8bit_sensor_mode = false;
+ }
+
+ return 0;
+}
+
+static int mx6sx_register_subdevs(struct mx6s_csi_dev *csi_dev)
+{
+ struct device_node *parent = csi_dev->dev->of_node;
+ struct device_node *node, *port, *rem;
+ int ret;
+
+ /* Attach sensors linked to csi receivers */
+ for_each_available_child_of_node(parent, node) {
+ if (of_node_cmp(node->name, "port"))
+ continue;
+
+ /* The csi node can have only port subnode. */
+ port = of_get_next_child(node, NULL);
+ if (!port)
+ continue;
+ rem = of_graph_get_remote_port_parent(port);
+ of_node_put(port);
+ if (rem == NULL) {
+ v4l2_info(&csi_dev->v4l2_dev,
+ "Remote device at %s not found\n",
+ port->full_name);
+ return -1;
+ }
+
+ csi_dev->asd.match_type = V4L2_ASYNC_MATCH_FWNODE;
+ csi_dev->asd.match.fwnode.fwnode = of_fwnode_handle(rem);
+ csi_dev->async_subdevs[0] = &csi_dev->asd;
+
+ of_node_put(rem);
+ break;
+ }
+
+ csi_dev->subdev_notifier.subdevs = csi_dev->async_subdevs;
+ csi_dev->subdev_notifier.num_subdevs = 1;
+ csi_dev->subdev_notifier.bound = subdev_notifier_bound;
+
+ ret = v4l2_async_notifier_register(&csi_dev->v4l2_dev,
+ &csi_dev->subdev_notifier);
+ if (ret)
+ dev_err(csi_dev->dev,
+ "Error register async notifier regoster\n");
+
+ return ret;
+}
+
+static int mx6s_csi_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ const struct of_device_id *of_id;
+ struct mx6s_csi_dev *csi_dev;
+ struct video_device *vdev;
+ struct resource *res;
+ int ret = 0;
+
+ dev_dbg(dev, "initialising\n");
+
+ /* Prepare our private structure */
+ csi_dev = devm_kzalloc(dev, sizeof(struct mx6s_csi_dev), GFP_ATOMIC);
+ if (!csi_dev) {
+ dev_err(dev, "Can't allocate private structure\n");
+ return -ENODEV;
+ }
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ csi_dev->irq = platform_get_irq(pdev, 0);
+ if (res == NULL || csi_dev->irq < 0) {
+ dev_err(dev, "Missing platform resources data\n");
+ return -ENODEV;
+ }
+
+ csi_dev->regbase = devm_ioremap_resource(dev, res);
+ if (IS_ERR(csi_dev->regbase)) {
+ dev_err(dev, "Failed platform resources map\n");
+ return -ENODEV;
+ }
+
+ /* init video dma queues */
+ INIT_LIST_HEAD(&csi_dev->capture);
+ INIT_LIST_HEAD(&csi_dev->active_bufs);
+ INIT_LIST_HEAD(&csi_dev->discard);
+
+ csi_dev->clk_disp_axi = devm_clk_get(dev, "disp-axi");
+ if (IS_ERR(csi_dev->clk_disp_axi)) {
+ dev_err(dev, "Could not get csi axi clock\n");
+ return -ENODEV;
+ }
+
+ csi_dev->clk_disp_dcic = devm_clk_get(dev, "disp_dcic");
+ if (IS_ERR(csi_dev->clk_disp_dcic)) {
+ dev_err(dev, "Could not get disp dcic clock\n");
+ return -ENODEV;
+ }
+
+ csi_dev->clk_csi_mclk = devm_clk_get(dev, "csi_mclk");
+ if (IS_ERR(csi_dev->clk_csi_mclk)) {
+ dev_err(dev, "Could not get csi mclk clock\n");
+ return -ENODEV;
+ }
+
+ csi_dev->dev = dev;
+
+ mx6s_csi_mode_sel(csi_dev);
+ mx6s_csi_two_8bit_sensor_mode_sel(csi_dev);
+
+ of_id = of_match_node(mx6s_csi_dt_ids, csi_dev->dev->of_node);
+ if (!of_id)
+ return -EINVAL;
+ csi_dev->soc = of_id->data;
+
+ snprintf(csi_dev->v4l2_dev.name,
+ sizeof(csi_dev->v4l2_dev.name), "CSI");
+
+ ret = v4l2_device_register(dev, &csi_dev->v4l2_dev);
+ if (ret < 0) {
+ dev_err(dev, "v4l2_device_register() failed: %d\n", ret);
+ return -ENODEV;
+ }
+
+ /* initialize locks */
+ mutex_init(&csi_dev->lock);
+ spin_lock_init(&csi_dev->slock);
+
+ /* Allocate memory for video device */
+ vdev = video_device_alloc();
+ if (vdev == NULL) {
+ ret = -ENOMEM;
+ goto err_vdev;
+ }
+
+ snprintf(vdev->name, sizeof(vdev->name), "mx6s-csi");
+
+ vdev->v4l2_dev = &csi_dev->v4l2_dev;
+ vdev->fops = &mx6s_csi_fops;
+ vdev->ioctl_ops = &mx6s_csi_ioctl_ops;
+ vdev->release = video_device_release;
+ vdev->lock = &csi_dev->lock;
+
+ vdev->queue = &csi_dev->vb2_vidq;
+
+ csi_dev->vdev = vdev;
+
+ video_set_drvdata(csi_dev->vdev, csi_dev);
+ mutex_lock(&csi_dev->lock);
+
+ ret = video_register_device(csi_dev->vdev, VFL_TYPE_GRABBER, -1);
+ if (ret < 0) {
+ video_device_release(csi_dev->vdev);
+ mutex_unlock(&csi_dev->lock);
+ goto err_vdev;
+ }
+
+ /* install interrupt handler */
+ if (devm_request_irq(dev, csi_dev->irq, mx6s_csi_irq_handler,
+ 0, "csi", (void *)csi_dev)) {
+ mutex_unlock(&csi_dev->lock);
+ dev_err(dev, "Request CSI IRQ failed.\n");
+ ret = -ENODEV;
+ goto err_irq;
+ }
+
+ mutex_unlock(&csi_dev->lock);
+
+ ret = mx6sx_register_subdevs(csi_dev);
+ if (ret < 0)
+ goto err_irq;
+
+ pm_runtime_enable(csi_dev->dev);
+ return 0;
+
+err_irq:
+ video_unregister_device(csi_dev->vdev);
+err_vdev:
+ v4l2_device_unregister(&csi_dev->v4l2_dev);
+ return ret;
+}
+
+static int mx6s_csi_remove(struct platform_device *pdev)
+{
+ struct v4l2_device *v4l2_dev = dev_get_drvdata(&pdev->dev);
+ struct mx6s_csi_dev *csi_dev =
+ container_of(v4l2_dev, struct mx6s_csi_dev, v4l2_dev);
+
+ v4l2_async_notifier_unregister(&csi_dev->subdev_notifier);
+
+ video_unregister_device(csi_dev->vdev);
+ v4l2_device_unregister(&csi_dev->v4l2_dev);
+
+ pm_runtime_disable(csi_dev->dev);
+ return 0;
+}
+
+static int mx6s_csi_runtime_suspend(struct device *dev)
+{
+ dev_dbg(dev, "csi v4l2 busfreq high release.\n");
+ return 0;
+}
+
+static int mx6s_csi_runtime_resume(struct device *dev)
+{
+ dev_dbg(dev, "csi v4l2 busfreq high request.\n");
+ return 0;
+}
+
+static const struct dev_pm_ops mx6s_csi_pm_ops = {
+ SET_RUNTIME_PM_OPS(mx6s_csi_runtime_suspend, mx6s_csi_runtime_resume, NULL)
+};
+
+static const struct mx6s_csi_soc mx6s_soc = {
+ .rx_fifo_rst = true,
+ .baseaddr_switch = 0,
+};
+static const struct mx6s_csi_soc mx6sl_soc = {
+ .rx_fifo_rst = false,
+ .baseaddr_switch = 0,
+};
+static const struct mx6s_csi_soc mx8mq_soc = {
+ .rx_fifo_rst = true,
+ .baseaddr_switch = 0x80030,
+};
+
+static const struct of_device_id mx6s_csi_dt_ids[] = {
+ { .compatible = "fsl,imx6s-csi",
+ .data = &mx6s_soc,
+ },
+ { .compatible = "fsl,imx6sl-csi",
+ .data = &mx6sl_soc,
+ },
+ { .compatible = "fsl,imx8mq-csi",
+ .data = &mx8mq_soc,
+ },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, mx6s_csi_dt_ids);
+
+static struct platform_driver mx6s_csi_driver = {
+ .driver = {
+ .name = MX6S_CAM_DRV_NAME,
+ .of_match_table = of_match_ptr(mx6s_csi_dt_ids),
+ .pm = &mx6s_csi_pm_ops,
+ },
+ .probe = mx6s_csi_probe,
+ .remove = mx6s_csi_remove,
+};
+
+module_platform_driver(mx6s_csi_driver);
+
+MODULE_DESCRIPTION("i.MX6Sx SoC Camera Host driver");
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_LICENSE("GPL");
+MODULE_VERSION(MX6S_CAM_VERSION);
diff --git a/drivers/media/platform/mxc/capture/mxc_mipi_csi.c b/drivers/media/platform/mxc/capture/mxc_mipi_csi.c
new file mode 100644
index 000000000000..a7964b7b8345
--- /dev/null
+++ b/drivers/media/platform/mxc/capture/mxc_mipi_csi.c
@@ -0,0 +1,1317 @@
+/*
+ * Freescale i.MX7 SoC series MIPI-CSI V3.3 receiver driver
+ *
+ * Copyright (C) 2015-2016 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+/*
+ * Samsung S5P/EXYNOS SoC series MIPI-CSI receiver driver
+ *
+ * Copyright (C) 2011 - 2013 Samsung Electronics Co., Ltd.
+ * Author: Sylwester Nawrocki <s.nawrocki@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/errno.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_address.h>
+#include <linux/of_graph.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/regmap.h>
+#include <linux/regulator/consumer.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/videodev2.h>
+#include <media/v4l2-subdev.h>
+#include <media/v4l2-device.h>
+
+static int debug;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "Debug level (0-2)");
+
+#define CSIS_DRIVER_NAME "mxc_mipi-csi"
+#define CSIS_SUBDEV_NAME CSIS_DRIVER_NAME
+#define CSIS_MAX_ENTITIES 2
+#define CSIS0_MAX_LANES 4
+#define CSIS1_MAX_LANES 2
+
+#define MIPI_CSIS_DEF_PIX_WIDTH 640
+#define MIPI_CSIS_DEF_PIX_HEIGHT 480
+
+/* Register map definition */
+
+/* CSIS version */
+#define MIPI_CSIS_VERSION 0x00
+
+/* CSIS common control */
+#define MIPI_CSIS_CMN_CTRL 0x04
+#define MIPI_CSIS_CMN_CTRL_UPDATE_SHADOW (1 << 16)
+#define MIPI_CSIS_CMN_CTRL_INTER_MODE (1 << 10)
+#define MIPI_CSIS_CMN_CTRL_LANE_NR_OFFSET 8
+#define MIPI_CSIS_CMN_CTRL_LANE_NR_MASK (3 << 8)
+#define MIPI_CSIS_CMN_CTRL_UPDATE_SHADOW_CTRL (1 << 2)
+#define MIPI_CSIS_CMN_CTRL_RESET (1 << 1)
+#define MIPI_CSIS_CMN_CTRL_ENABLE (1 << 0)
+
+/* CSIS clock control */
+#define MIPI_CSIS_CLK_CTRL 0x08
+#define MIPI_CSIS_CLK_CTRL_CLKGATE_TRAIL_CH3(x) (x << 28)
+#define MIPI_CSIS_CLK_CTRL_CLKGATE_TRAIL_CH2(x) (x << 24)
+#define MIPI_CSIS_CLK_CTRL_CLKGATE_TRAIL_CH1(x) (x << 20)
+#define MIPI_CSIS_CLK_CTRL_CLKGATE_TRAIL_CH0(x) (x << 16)
+#define MIPI_CSIS_CLK_CTRL_CLKGATE_EN_MSK (0xf << 4)
+#define MIPI_CSIS_CLK_CTRL_WCLK_SRC (1 << 0)
+
+/* CSIS Interrupt mask */
+#define MIPI_CSIS_INTMSK 0x10
+#define MIPI_CSIS_INTMSK_EVEN_BEFORE (1 << 31)
+#define MIPI_CSIS_INTMSK_EVEN_AFTER (1 << 30)
+#define MIPI_CSIS_INTMSK_ODD_BEFORE (1 << 29)
+#define MIPI_CSIS_INTMSK_ODD_AFTER (1 << 28)
+#define MIPI_CSIS_INTMSK_FRAME_START (1 << 24)
+#define MIPI_CSIS_INTMSK_FRAME_END (1 << 20)
+#define MIPI_CSIS_INTMSK_ERR_SOT_HS (1 << 16)
+#define MIPI_CSIS_INTMSK_ERR_LOST_FS (1 << 12)
+#define MIPI_CSIS_INTMSK_ERR_LOST_FE (1 << 8)
+#define MIPI_CSIS_INTMSK_ERR_OVER (1 << 4)
+#define MIPI_CSIS_INTMSK_ERR_WRONG_CFG (1 << 3)
+#define MIPI_CSIS_INTMSK_ERR_ECC (1 << 2)
+#define MIPI_CSIS_INTMSK_ERR_CRC (1 << 1)
+#define MIPI_CSIS_INTMSK_ERR_UNKNOWN (1 << 0)
+
+/* CSIS Interrupt source */
+#define MIPI_CSIS_INTSRC 0x14
+#define MIPI_CSIS_INTSRC_EVEN_BEFORE (1 << 31)
+#define MIPI_CSIS_INTSRC_EVEN_AFTER (1 << 30)
+#define MIPI_CSIS_INTSRC_EVEN (0x3 << 30)
+#define MIPI_CSIS_INTSRC_ODD_BEFORE (1 << 29)
+#define MIPI_CSIS_INTSRC_ODD_AFTER (1 << 28)
+#define MIPI_CSIS_INTSRC_ODD (0x3 << 28)
+#define MIPI_CSIS_INTSRC_NON_IMAGE_DATA (0xf << 28)
+#define MIPI_CSIS_INTSRC_FRAME_START (1 << 24)
+#define MIPI_CSIS_INTSRC_FRAME_END (1 << 20)
+#define MIPI_CSIS_INTSRC_ERR_SOT_HS (1 << 16)
+#define MIPI_CSIS_INTSRC_ERR_LOST_FS (1 << 12)
+#define MIPI_CSIS_INTSRC_ERR_LOST_FE (1 << 8)
+#define MIPI_CSIS_INTSRC_ERR_OVER (1 << 4)
+#define MIPI_CSIS_INTSRC_ERR_WRONG_CFG (1 << 3)
+#define MIPI_CSIS_INTSRC_ERR_ECC (1 << 2)
+#define MIPI_CSIS_INTSRC_ERR_CRC (1 << 1)
+#define MIPI_CSIS_INTSRC_ERR_UNKNOWN (1 << 0)
+#define MIPI_CSIS_INTSRC_ERRORS 0xfffff
+
+/* D-PHY status control */
+#define MIPI_CSIS_DPHYSTATUS 0x20
+#define MIPI_CSIS_DPHYSTATUS_ULPS_DAT (1 << 8)
+#define MIPI_CSIS_DPHYSTATUS_STOPSTATE_DAT (1 << 4)
+#define MIPI_CSIS_DPHYSTATUS_ULPS_CLK (1 << 1)
+#define MIPI_CSIS_DPHYSTATUS_STOPSTATE_CLK (1 << 0)
+
+/* D-PHY common control */
+#define MIPI_CSIS_DPHYCTRL 0x24
+#define MIPI_CSIS_DPHYCTRL_HSS_MASK (0xff << 24)
+#define MIPI_CSIS_DPHYCTRL_HSS_OFFSET 24
+#define MIPI_CSIS_DPHYCTRL_SCLKS_MASK (0x3 << 22)
+#define MIPI_CSIS_DPHYCTRL_SCLKS_OFFSET 22
+#define MIPI_CSIS_DPHYCTRL_DPDN_SWAP_CLK (1 << 6)
+#define MIPI_CSIS_DPHYCTRL_DPDN_SWAP_DAT (1 << 5)
+#define MIPI_CSIS_DPHYCTRL_ENABLE_DAT (1 << 1)
+#define MIPI_CSIS_DPHYCTRL_ENABLE_CLK (1 << 0)
+#define MIPI_CSIS_DPHYCTRL_ENABLE (0x1f << 0)
+
+/* D-PHY Master and Slave Control register Low */
+#define MIPI_CSIS_DPHYBCTRL_L 0x30
+/* D-PHY Master and Slave Control register High */
+#define MIPI_CSIS_DPHYBCTRL_H 0x34
+/* D-PHY Slave Control register Low */
+#define MIPI_CSIS_DPHYSCTRL_L 0x38
+/* D-PHY Slave Control register High */
+#define MIPI_CSIS_DPHYSCTRL_H 0x3c
+
+
+/* ISP Configuration register */
+#define MIPI_CSIS_ISPCONFIG_CH0 0x40
+#define MIPI_CSIS_ISPCONFIG_CH1 0x50
+#define MIPI_CSIS_ISPCONFIG_CH2 0x60
+#define MIPI_CSIS_ISPCONFIG_CH3 0x70
+
+#define MIPI_CSIS_ISPCFG_MEM_FULL_GAP_MSK (0xff << 24)
+#define MIPI_CSIS_ISPCFG_MEM_FULL_GAP(x) (x << 24)
+#define MIPI_CSIS_ISPCFG_DOUBLE_CMPNT (1 << 12)
+#define MIPI_CSIS_ISPCFG_ALIGN_32BIT (1 << 11)
+#define MIPI_CSIS_ISPCFG_FMT_YCBCR422_8BIT (0x1e << 2)
+#define MIPI_CSIS_ISPCFG_FMT_RAW8 (0x2a << 2)
+#define MIPI_CSIS_ISPCFG_FMT_RAW10 (0x2b << 2)
+#define MIPI_CSIS_ISPCFG_FMT_RAW12 (0x2c << 2)
+/* User defined formats, x = 1...4 */
+#define MIPI_CSIS_ISPCFG_FMT_USER(x) ((0x30 + x - 1) << 2)
+#define MIPI_CSIS_ISPCFG_FMT_MASK (0x3f << 2)
+
+/* ISP Image Resolution register */
+#define MIPI_CSIS_ISPRESOL_CH0 0x44
+#define MIPI_CSIS_ISPRESOL_CH1 0x54
+#define MIPI_CSIS_ISPRESOL_CH2 0x64
+#define MIPI_CSIS_ISPRESOL_CH3 0x74
+#define CSIS_MAX_PIX_WIDTH 0xffff
+#define CSIS_MAX_PIX_HEIGHT 0xffff
+
+/* ISP SYNC register */
+#define MIPI_CSIS_ISPSYNC_CH0 0x48
+#define MIPI_CSIS_ISPSYNC_CH1 0x58
+#define MIPI_CSIS_ISPSYNC_CH2 0x68
+#define MIPI_CSIS_ISPSYNC_CH3 0x78
+
+#define MIPI_CSIS_ISPSYNC_HSYNC_LINTV_OFFSET 18
+#define MIPI_CSIS_ISPSYNC_VSYNC_SINTV_OFFSET 12
+#define MIPI_CSIS_ISPSYNC_VSYNC_EINTV_OFFSET 0
+
+/* Non-image packet data buffers */
+#define MIPI_CSIS_PKTDATA_ODD 0x2000
+#define MIPI_CSIS_PKTDATA_EVEN 0x3000
+#define MIPI_CSIS_PKTDATA_SIZE SZ_4K
+
+#define GPR_MIPI_RESET 0x08
+#define GPR_MIPI_S_RESETN BIT(16)
+
+#define DEFAULT_SCLK_CSIS_FREQ 166000000UL
+
+enum {
+ ST_POWERED = 1,
+ ST_STREAMING = 2,
+ ST_SUSPENDED = 4,
+};
+
+struct mipi_csis_event {
+ u32 mask;
+ const char * const name;
+ unsigned int counter;
+};
+
+static const struct mipi_csis_event mipi_csis_events[] = {
+ /* Errors */
+ { MIPI_CSIS_INTSRC_ERR_SOT_HS, "SOT Error" },
+ { MIPI_CSIS_INTSRC_ERR_LOST_FS, "Lost Frame Start Error" },
+ { MIPI_CSIS_INTSRC_ERR_LOST_FE, "Lost Frame End Error" },
+ { MIPI_CSIS_INTSRC_ERR_OVER, "FIFO Overflow Error" },
+ { MIPI_CSIS_INTSRC_ERR_ECC, "ECC Error" },
+ { MIPI_CSIS_INTSRC_ERR_CRC, "CRC Error" },
+ { MIPI_CSIS_INTSRC_ERR_UNKNOWN, "Unknown Error" },
+ /* Non-image data receive events */
+ { MIPI_CSIS_INTSRC_EVEN_BEFORE, "Non-image data before even frame" },
+ { MIPI_CSIS_INTSRC_EVEN_AFTER, "Non-image data after even frame" },
+ { MIPI_CSIS_INTSRC_ODD_BEFORE, "Non-image data before odd frame" },
+ { MIPI_CSIS_INTSRC_ODD_AFTER, "Non-image data after odd frame" },
+ /* Frame start/end */
+ { MIPI_CSIS_INTSRC_FRAME_START, "Frame Start" },
+ { MIPI_CSIS_INTSRC_FRAME_END, "Frame End" },
+};
+#define MIPI_CSIS_NUM_EVENTS ARRAY_SIZE(mipi_csis_events)
+
+struct csis_pktbuf {
+ u32 *data;
+ unsigned int len;
+};
+
+struct csis_hw_reset {
+ struct regmap *src;
+ u8 req_src;
+ u8 rst_bit;
+};
+
+/**
+ * struct csi_state - the driver's internal state data structure
+ * @lock: mutex serializing the subdev and power management operations,
+ * protecting @format and @flags members
+ * @sd: v4l2_subdev associated with CSIS device instance
+ * @index: the hardware instance index
+ * @pdev: CSIS platform device
+ * @phy: pointer to the CSIS generic PHY
+ * @regs: mmaped I/O registers memory
+ * @supplies: CSIS regulator supplies
+ * @clock: CSIS clocks
+ * @irq: requested s5p-mipi-csis irq number
+ * @flags: the state variable for power and streaming control
+ * @clock_frequency: device bus clock frequency
+ * @hs_settle: HS-RX settle time
+ * @clk_settle: Clk settle time
+ * @num_lanes: number of MIPI-CSI data lanes used
+ * @max_num_lanes: maximum number of MIPI-CSI data lanes supported
+ * @wclk_ext: CSI wrapper clock: 0 - bus clock, 1 - external SCLK_CAM
+ * @csis_fmt: current CSIS pixel format
+ * @format: common media bus format for the source and sink pad
+ * @slock: spinlock protecting structure members below
+ * @pkt_buf: the frame embedded (non-image) data buffer
+ * @events: MIPI-CSIS event (error) counters
+ */
+struct csi_state {
+ struct mutex lock;
+ struct device *dev;
+ struct v4l2_subdev mipi_sd;
+ struct v4l2_subdev *sensor_sd;
+ struct v4l2_device v4l2_dev;
+
+ u8 index;
+ struct platform_device *pdev;
+ struct phy *phy;
+ void __iomem *regs;
+ struct clk *mipi_clk;
+ struct clk *phy_clk;
+ struct clk *disp_axi;
+ struct clk *disp_apb;
+ int irq;
+ u32 flags;
+
+ u32 clk_frequency;
+ u32 hs_settle;
+ u32 clk_settle;
+ u32 num_lanes;
+ u32 max_num_lanes;
+ u8 wclk_ext;
+
+ const struct csis_pix_format *csis_fmt;
+ struct v4l2_mbus_framefmt format;
+
+ spinlock_t slock;
+ struct csis_pktbuf pkt_buf;
+ struct mipi_csis_event events[MIPI_CSIS_NUM_EVENTS];
+
+ struct v4l2_async_subdev asd;
+ struct v4l2_async_notifier subdev_notifier;
+ struct v4l2_async_subdev *async_subdevs[2];
+
+ struct csis_hw_reset hw_reset;
+ struct regulator *mipi_phy_regulator;
+};
+
+/**
+ * struct csis_pix_format - CSIS pixel format description
+ * @pix_width_alignment: horizontal pixel alignment, width will be
+ * multiple of 2^pix_width_alignment
+ * @code: corresponding media bus code
+ * @fmt_reg: MIPI_CSIS_CONFIG register value
+ * @data_alignment: MIPI-CSI data alignment in bits
+ */
+struct csis_pix_format {
+ unsigned int pix_width_alignment;
+ u32 code;
+ u32 fmt_reg;
+ u8 data_alignment;
+};
+
+static const struct csis_pix_format mipi_csis_formats[] = {
+ {
+ .code = MEDIA_BUS_FMT_YUYV8_2X8,
+ .fmt_reg = MIPI_CSIS_ISPCFG_FMT_YCBCR422_8BIT,
+ .data_alignment = 16,
+ }, {
+ .code = MEDIA_BUS_FMT_VYUY8_2X8,
+ .fmt_reg = MIPI_CSIS_ISPCFG_FMT_YCBCR422_8BIT,
+ .data_alignment = 16,
+ }, {
+ .code = MEDIA_BUS_FMT_SBGGR8_1X8,
+ .fmt_reg = MIPI_CSIS_ISPCFG_FMT_RAW8,
+ .data_alignment = 8,
+ }
+};
+
+typedef int (*mipi_csis_phy_reset_t)(struct csi_state *state);
+
+#define mipi_csis_write(__csis, __r, __v) writel(__v, __csis->regs + __r)
+#define mipi_csis_read(__csis, __r) readl(__csis->regs + __r)
+
+static struct csi_state *mipi_sd_to_csi_state(struct v4l2_subdev *sdev)
+{
+ return container_of(sdev, struct csi_state, mipi_sd);
+}
+
+static inline struct csi_state
+ *notifier_to_mipi_dev(struct v4l2_async_notifier *n)
+{
+ return container_of(n, struct csi_state, subdev_notifier);
+}
+
+static const struct csis_pix_format *find_csis_format(u32 code)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(mipi_csis_formats); i++)
+ if (code == mipi_csis_formats[i].code)
+ return &mipi_csis_formats[i];
+ return NULL;
+}
+
+static void mipi_csis_enable_interrupts(struct csi_state *state, bool on)
+{
+ u32 val = mipi_csis_read(state, MIPI_CSIS_INTMSK);
+ if (on)
+ val |= 0xf00fffff;
+ else
+ val &= ~0xf00fffff;
+ mipi_csis_write(state, MIPI_CSIS_INTMSK, val);
+}
+
+static void mipi_csis_sw_reset(struct csi_state *state)
+{
+ u32 val = mipi_csis_read(state, MIPI_CSIS_CMN_CTRL);
+
+ mipi_csis_write(state, MIPI_CSIS_CMN_CTRL, val | MIPI_CSIS_CMN_CTRL_RESET);
+ udelay(10);
+}
+
+static int mipi_csis_phy_init(struct csi_state *state)
+{
+ int ret;
+
+ state->mipi_phy_regulator = devm_regulator_get(state->dev,
+ "mipi-phy");
+
+ ret = regulator_set_voltage(state->mipi_phy_regulator,
+ 1000000, 1000000);
+
+ return ret;
+}
+
+static int mipi_csis_phy_reset_mx8mm(struct csi_state *state)
+{
+ struct device_node *np = state->dev->of_node;
+ struct regmap *gpr;
+
+ gpr = syscon_regmap_lookup_by_phandle(np, "csi-gpr");
+ if (IS_ERR(gpr))
+ return PTR_ERR(gpr);
+
+ regmap_update_bits(gpr, GPR_MIPI_RESET,
+ GPR_MIPI_S_RESETN,
+ 0x0);
+ usleep_range(10, 20);
+ regmap_update_bits(gpr, GPR_MIPI_RESET,
+ GPR_MIPI_S_RESETN,
+ GPR_MIPI_S_RESETN);
+ usleep_range(10, 20);
+
+ return 0;
+}
+
+static int mipi_csis_phy_reset(struct csi_state *state)
+{
+ struct device_node *np = state->dev->of_node;
+ struct device_node *node;
+ phandle phandle;
+ u32 out_val[3];
+ int ret;
+
+ ret = of_property_read_u32_array(np, "csis-phy-reset", out_val, 3);
+ if (ret) {
+ dev_dbg(state->dev, "no csis-hw-reset property found\n");
+ } else {
+ phandle = *out_val;
+
+ node = of_find_node_by_phandle(phandle);
+ if (!node) {
+ dev_dbg(state->dev, "not find src node by phandle\n");
+ ret = PTR_ERR(node);
+ }
+ state->hw_reset.src = syscon_node_to_regmap(node);
+ if (IS_ERR(state->hw_reset.src)) {
+ dev_err(state->dev, "failed to get src regmap\n");
+ ret = PTR_ERR(state->hw_reset.src);
+ }
+ of_node_put(node);
+ if (ret < 0)
+ return ret;
+
+ state->hw_reset.req_src = out_val[1];
+ state->hw_reset.rst_bit = out_val[2];
+
+ /* reset mipi phy */
+ regmap_update_bits(state->hw_reset.src, state->hw_reset.req_src,
+ 1 << state->hw_reset.rst_bit, 1 << state->hw_reset.rst_bit);
+ msleep(20);
+ regmap_update_bits(state->hw_reset.src, state->hw_reset.req_src,
+ 1 << state->hw_reset.rst_bit, 0);
+
+ }
+ return ret;
+}
+
+static void mipi_csis_system_enable(struct csi_state *state, int on)
+{
+ u32 val, mask;
+
+ val = mipi_csis_read(state, MIPI_CSIS_CMN_CTRL);
+ if (on)
+ val |= MIPI_CSIS_CMN_CTRL_ENABLE;
+ else
+ val &= ~MIPI_CSIS_CMN_CTRL_ENABLE;
+ mipi_csis_write(state, MIPI_CSIS_CMN_CTRL, val);
+
+ val = mipi_csis_read(state, MIPI_CSIS_DPHYCTRL);
+ val &= ~MIPI_CSIS_DPHYCTRL_ENABLE;
+ if (on) {
+ mask = (1 << (state->num_lanes + 1)) - 1;
+ val |= (mask & MIPI_CSIS_DPHYCTRL_ENABLE);
+ }
+ mipi_csis_write(state, MIPI_CSIS_DPHYCTRL, val);
+}
+
+/* Called with the state.lock mutex held */
+static void __mipi_csis_set_format(struct csi_state *state)
+{
+ struct v4l2_mbus_framefmt *mf = &state->format;
+ u32 val;
+
+ v4l2_dbg(1, debug, &state->mipi_sd, "fmt: %#x, %d x %d\n",
+ mf->code, mf->width, mf->height);
+
+ /* Color format */
+ val = mipi_csis_read(state, MIPI_CSIS_ISPCONFIG_CH0);
+ val = (val & ~MIPI_CSIS_ISPCFG_FMT_MASK) | state->csis_fmt->fmt_reg;
+ mipi_csis_write(state, MIPI_CSIS_ISPCONFIG_CH0, val);
+
+ /* Pixel resolution */
+ val = mf->width | (mf->height << 16);
+ mipi_csis_write(state, MIPI_CSIS_ISPRESOL_CH0, val);
+}
+
+static void mipi_csis_set_hsync_settle(struct csi_state *state,
+ int hs_settle, int clk_settle)
+{
+ u32 val = mipi_csis_read(state, MIPI_CSIS_DPHYCTRL);
+
+ val = (val & ~MIPI_CSIS_DPHYCTRL_HSS_MASK) |
+ (hs_settle << 24) | (clk_settle << 22);
+
+ mipi_csis_write(state, MIPI_CSIS_DPHYCTRL, val);
+}
+
+static void mipi_csis_set_params(struct csi_state *state)
+{
+ u32 val;
+
+ val = mipi_csis_read(state, MIPI_CSIS_CMN_CTRL);
+ val &= ~MIPI_CSIS_CMN_CTRL_LANE_NR_MASK;
+ val |= (state->num_lanes - 1) << MIPI_CSIS_CMN_CTRL_LANE_NR_OFFSET;
+ mipi_csis_write(state, MIPI_CSIS_CMN_CTRL, val);
+
+ __mipi_csis_set_format(state);
+
+ mipi_csis_set_hsync_settle(state, state->hs_settle, state->clk_settle);
+
+ val = mipi_csis_read(state, MIPI_CSIS_ISPCONFIG_CH0);
+ if (state->csis_fmt->data_alignment == 32)
+ val |= MIPI_CSIS_ISPCFG_ALIGN_32BIT;
+ else /* Normal output */
+ val &= ~MIPI_CSIS_ISPCFG_ALIGN_32BIT;
+ mipi_csis_write(state, MIPI_CSIS_ISPCONFIG_CH0, val);
+
+ val = (0 << MIPI_CSIS_ISPSYNC_HSYNC_LINTV_OFFSET) |
+ (0 << MIPI_CSIS_ISPSYNC_VSYNC_SINTV_OFFSET) |
+ (0 << MIPI_CSIS_ISPSYNC_VSYNC_EINTV_OFFSET);
+ mipi_csis_write(state, MIPI_CSIS_ISPSYNC_CH0, val);
+
+ val = mipi_csis_read(state, MIPI_CSIS_CLK_CTRL);
+ val &= ~MIPI_CSIS_CLK_CTRL_WCLK_SRC;
+ if (state->wclk_ext)
+ val |= MIPI_CSIS_CLK_CTRL_WCLK_SRC;
+ val |= MIPI_CSIS_CLK_CTRL_CLKGATE_TRAIL_CH0(15);
+ val &= ~MIPI_CSIS_CLK_CTRL_CLKGATE_EN_MSK;
+ mipi_csis_write(state, MIPI_CSIS_CLK_CTRL, val);
+
+ mipi_csis_write(state, MIPI_CSIS_DPHYBCTRL_L, 0x1f4);
+ mipi_csis_write(state, MIPI_CSIS_DPHYBCTRL_H, 0);
+
+ /* Update the shadow register. */
+ val = mipi_csis_read(state, MIPI_CSIS_CMN_CTRL);
+ mipi_csis_write(state, MIPI_CSIS_CMN_CTRL, val | MIPI_CSIS_CMN_CTRL_UPDATE_SHADOW |
+ MIPI_CSIS_CMN_CTRL_UPDATE_SHADOW_CTRL);
+}
+
+static void mipi_csis_clk_enable(struct csi_state *state)
+{
+ clk_prepare_enable(state->mipi_clk);
+ clk_prepare_enable(state->phy_clk);
+ if (state->disp_axi)
+ clk_prepare_enable(state->disp_axi);
+ if (state->disp_apb)
+ clk_prepare_enable(state->disp_apb);
+}
+
+static void mipi_csis_clk_disable(struct csi_state *state)
+{
+ clk_disable_unprepare(state->mipi_clk);
+ clk_disable_unprepare(state->phy_clk);
+ if (state->disp_axi)
+ clk_disable_unprepare(state->disp_axi);
+ if (state->disp_apb)
+ clk_disable_unprepare(state->disp_apb);
+}
+
+static int mipi_csis_clk_get(struct csi_state *state)
+{
+ struct device *dev = &state->pdev->dev;
+ int ret = true;
+
+ state->mipi_clk = devm_clk_get(dev, "mipi_clk");
+ if (IS_ERR(state->mipi_clk)) {
+ dev_err(dev, "Could not get mipi csi clock\n");
+ return -ENODEV;
+ }
+
+ state->phy_clk = devm_clk_get(dev, "phy_clk");
+ if (IS_ERR(state->phy_clk)) {
+ dev_err(dev, "Could not get mipi phy clock\n");
+ return -ENODEV;
+ }
+
+ state->disp_axi = devm_clk_get(dev, "disp_axi");
+ if (IS_ERR(state->disp_axi)) {
+ dev_warn(dev, "Could not get disp_axi clock\n");
+ state->disp_axi = NULL;
+ }
+
+ state->disp_apb = devm_clk_get(dev, "disp_apb");
+ if (IS_ERR(state->disp_apb)) {
+ dev_warn(dev, "Could not get disp apb clock\n");
+ state->disp_apb = NULL;
+ }
+
+ /* Set clock rate */
+ if (state->clk_frequency)
+ ret = clk_set_rate(state->mipi_clk,
+ state->clk_frequency);
+ else
+ dev_WARN(dev, "No clock frequency specified!\n");
+ if (ret < 0) {
+ dev_err(dev, "set rate filed, rate=%d\n", state->clk_frequency);
+ return -EINVAL;
+ }
+
+ return ret;
+}
+
+static void dump_regs(struct csi_state *state, const char *label)
+{
+ struct {
+ u32 offset;
+ const char * const name;
+ } registers[] = {
+ { 0x00, "CTRL" },
+ { 0x04, "DPHYCTRL" },
+ { 0x08, "CONFIG" },
+ { 0x0c, "DPHYSTS" },
+ { 0x10, "INTMSK" },
+ { 0x2c, "RESOL" },
+ { 0x38, "SDW_CONFIG" },
+ };
+ u32 i;
+
+ v4l2_info(&state->mipi_sd, "--- %s ---\n", label);
+
+ for (i = 0; i < ARRAY_SIZE(registers); i++) {
+ u32 cfg = mipi_csis_read(state, registers[i].offset);
+ v4l2_info(&state->mipi_sd, "%10s: 0x%08x\n", registers[i].name, cfg);
+ }
+}
+
+static void mipi_csis_start_stream(struct csi_state *state)
+{
+ mipi_csis_sw_reset(state);
+ mipi_csis_set_params(state);
+ mipi_csis_system_enable(state, true);
+ mipi_csis_enable_interrupts(state, true);
+}
+
+static void mipi_csis_stop_stream(struct csi_state *state)
+{
+ mipi_csis_enable_interrupts(state, false);
+ mipi_csis_system_enable(state, false);
+}
+
+static void mipi_csis_clear_counters(struct csi_state *state)
+{
+ unsigned long flags;
+ int i;
+
+ spin_lock_irqsave(&state->slock, flags);
+ for (i = 0; i < MIPI_CSIS_NUM_EVENTS; i++)
+ state->events[i].counter = 0;
+ spin_unlock_irqrestore(&state->slock, flags);
+}
+
+static void mipi_csis_log_counters(struct csi_state *state, bool non_errors)
+{
+ int i = non_errors ? MIPI_CSIS_NUM_EVENTS : MIPI_CSIS_NUM_EVENTS - 4;
+ unsigned long flags;
+
+ spin_lock_irqsave(&state->slock, flags);
+
+ for (i--; i >= 0; i--) {
+ if (state->events[i].counter > 0 || debug)
+ v4l2_info(&state->mipi_sd, "%s events: %d\n",
+ state->events[i].name,
+ state->events[i].counter);
+ }
+ spin_unlock_irqrestore(&state->slock, flags);
+}
+
+/*
+ * V4L2 subdev operations
+ */
+static int mipi_csis_s_power(struct v4l2_subdev *mipi_sd, int on)
+{
+ struct csi_state *state = mipi_sd_to_csi_state(mipi_sd);
+ struct device *dev = &state->pdev->dev;
+
+ v4l2_subdev_call(state->sensor_sd, core, s_power, on);
+
+ if (on)
+ return pm_runtime_get_sync(dev);
+
+ return pm_runtime_put_sync(dev);
+}
+
+static int mipi_csis_s_stream(struct v4l2_subdev *mipi_sd, int enable)
+{
+ struct csi_state *state = mipi_sd_to_csi_state(mipi_sd);
+ int ret = 0;
+
+ v4l2_dbg(1, debug, mipi_sd, "%s: %d, state: 0x%x\n",
+ __func__, enable, state->flags);
+
+ if (enable) {
+ mipi_csis_clear_counters(state);
+ ret = pm_runtime_get_sync(&state->pdev->dev);
+ if (ret && ret != 1)
+ return ret;
+ }
+
+ mutex_lock(&state->lock);
+ if (enable) {
+ if (state->flags & ST_SUSPENDED) {
+ ret = -EBUSY;
+ goto unlock;
+ }
+ mipi_csis_start_stream(state);
+ v4l2_subdev_call(state->sensor_sd, video, s_stream, true);
+ state->flags |= ST_STREAMING;
+ } else {
+ v4l2_subdev_call(state->sensor_sd, video, s_stream, false);
+ mipi_csis_stop_stream(state);
+ state->flags &= ~ST_STREAMING;
+ if (debug > 0)
+ mipi_csis_log_counters(state, true);
+ }
+unlock:
+ mutex_unlock(&state->lock);
+ if (!enable)
+ pm_runtime_put(&state->pdev->dev);
+
+ return ret == 1 ? 0 : ret;
+}
+
+static int mipi_csis_enum_mbus_code(struct v4l2_subdev *mipi_sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_mbus_code_enum *code)
+{
+ struct csi_state *state = mipi_sd_to_csi_state(mipi_sd);
+ struct v4l2_subdev *sensor_sd = state->sensor_sd;
+ struct csis_pix_format const *csis_fmt;
+ int ret;
+
+ ret = v4l2_subdev_call(sensor_sd, pad, enum_mbus_code, NULL, code);
+ if (ret < 0)
+ return -EINVAL;
+
+ csis_fmt = find_csis_format(code->code);
+ if (csis_fmt == NULL) {
+ dev_err(state->dev, "format not match\n");
+ return -EINVAL;
+ }
+
+ return ret;
+}
+
+static int mipi_csis_set_fmt(struct v4l2_subdev *mipi_sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_format *format)
+{
+ struct csi_state *state = mipi_sd_to_csi_state(mipi_sd);
+ struct v4l2_subdev *sensor_sd = state->sensor_sd;
+ struct csis_pix_format const *csis_fmt;
+ struct v4l2_mbus_framefmt *mf = &format->format;
+
+ if (format->pad)
+ return -EINVAL;
+
+ csis_fmt = find_csis_format(mf->code);
+ if (csis_fmt == NULL)
+ csis_fmt = &mipi_csis_formats[0];
+
+ v4l2_subdev_call(sensor_sd, pad, set_fmt, NULL, format);
+
+ mf->code = csis_fmt->code;
+ v4l_bound_align_image(&mf->width, 1, CSIS_MAX_PIX_WIDTH,
+ csis_fmt->pix_width_alignment,
+ &mf->height, 1, CSIS_MAX_PIX_HEIGHT, 1,
+ 0);
+
+ if (format->which == V4L2_SUBDEV_FORMAT_TRY)
+ return 0;
+
+ state->format.code = mf->code;
+ state->format.width = mf->width;
+ state->format.height = mf->height;
+
+ mutex_lock(&state->lock);
+ state->csis_fmt = csis_fmt;
+ mutex_unlock(&state->lock);
+
+ return 0;
+}
+
+static int mipi_csis_get_fmt(struct v4l2_subdev *mipi_sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_format *format)
+{
+ struct csi_state *state = mipi_sd_to_csi_state(mipi_sd);
+ struct v4l2_subdev *sensor_sd = state->sensor_sd;
+
+ if (format->pad)
+ return -EINVAL;
+
+ return v4l2_subdev_call(sensor_sd, pad, get_fmt, NULL, format);
+}
+
+static int mipi_csis_s_rx_buffer(struct v4l2_subdev *mipi_sd, void *buf,
+ unsigned int *size)
+{
+ struct csi_state *state = mipi_sd_to_csi_state(mipi_sd);
+ unsigned long flags;
+
+ *size = min_t(unsigned int, *size, MIPI_CSIS_PKTDATA_SIZE);
+
+ spin_lock_irqsave(&state->slock, flags);
+ state->pkt_buf.data = buf;
+ state->pkt_buf.len = *size;
+ spin_unlock_irqrestore(&state->slock, flags);
+
+ return 0;
+}
+
+static int mipi_csis_s_parm(struct v4l2_subdev *mipi_sd, struct v4l2_streamparm *a)
+{
+ struct csi_state *state = mipi_sd_to_csi_state(mipi_sd);
+ struct v4l2_subdev *sensor_sd = state->sensor_sd;
+
+ return v4l2_subdev_call(sensor_sd, video, s_parm, a);
+}
+
+static int mipi_csis_g_parm(struct v4l2_subdev *mipi_sd, struct v4l2_streamparm *a)
+{
+ struct csi_state *state = mipi_sd_to_csi_state(mipi_sd);
+ struct v4l2_subdev *sensor_sd = state->sensor_sd;
+
+ return v4l2_subdev_call(sensor_sd, video, g_parm, a);
+}
+
+static int mipi_csis_enum_framesizes(struct v4l2_subdev *mipi_sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_frame_size_enum *fse)
+{
+ struct csi_state *state = mipi_sd_to_csi_state(mipi_sd);
+ struct v4l2_subdev *sensor_sd = state->sensor_sd;
+
+ return v4l2_subdev_call(sensor_sd, pad, enum_frame_size, NULL, fse);
+}
+
+static int mipi_csis_enum_frameintervals(struct v4l2_subdev *mipi_sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_frame_interval_enum *fie)
+{
+ struct csi_state *state = mipi_sd_to_csi_state(mipi_sd);
+ struct v4l2_subdev *sensor_sd = state->sensor_sd;
+
+ return v4l2_subdev_call(sensor_sd, pad, enum_frame_interval, NULL, fie);
+}
+
+static int mipi_csis_log_status(struct v4l2_subdev *mipi_sd)
+{
+ struct csi_state *state = mipi_sd_to_csi_state(mipi_sd);
+
+ mutex_lock(&state->lock);
+ mipi_csis_log_counters(state, true);
+ if (debug && (state->flags & ST_POWERED))
+ dump_regs(state, __func__);
+ mutex_unlock(&state->lock);
+ return 0;
+}
+
+static struct v4l2_subdev_core_ops mipi_csis_core_ops = {
+ .s_power = mipi_csis_s_power,
+ .log_status = mipi_csis_log_status,
+};
+
+static struct v4l2_subdev_video_ops mipi_csis_video_ops = {
+ .s_rx_buffer = mipi_csis_s_rx_buffer,
+ .s_stream = mipi_csis_s_stream,
+
+ .s_parm = mipi_csis_s_parm,
+ .g_parm = mipi_csis_g_parm,
+};
+
+static const struct v4l2_subdev_pad_ops mipi_csis_pad_ops = {
+ .enum_frame_size = mipi_csis_enum_framesizes,
+ .enum_frame_interval = mipi_csis_enum_frameintervals,
+ .enum_mbus_code = mipi_csis_enum_mbus_code,
+ .get_fmt = mipi_csis_get_fmt,
+ .set_fmt = mipi_csis_set_fmt,
+};
+
+static struct v4l2_subdev_ops mipi_csis_subdev_ops = {
+ .core = &mipi_csis_core_ops,
+ .video = &mipi_csis_video_ops,
+ .pad = &mipi_csis_pad_ops,
+};
+
+static irqreturn_t mipi_csis_irq_handler(int irq, void *dev_id)
+{
+ struct csi_state *state = dev_id;
+ struct csis_pktbuf *pktbuf = &state->pkt_buf;
+ unsigned long flags;
+ u32 status;
+
+ status = mipi_csis_read(state, MIPI_CSIS_INTSRC);
+
+ spin_lock_irqsave(&state->slock, flags);
+
+ if ((status & MIPI_CSIS_INTSRC_NON_IMAGE_DATA) && pktbuf->data) {
+ u32 offset;
+
+ if (status & MIPI_CSIS_INTSRC_EVEN)
+ offset = MIPI_CSIS_PKTDATA_EVEN;
+ else
+ offset = MIPI_CSIS_PKTDATA_ODD;
+
+ memcpy(pktbuf->data, state->regs + offset, pktbuf->len);
+ pktbuf->data = NULL;
+ rmb();
+ }
+
+ /* Update the event/error counters */
+ if ((status & MIPI_CSIS_INTSRC_ERRORS) || debug) {
+ int i;
+ for (i = 0; i < MIPI_CSIS_NUM_EVENTS; i++) {
+ if (!(status & state->events[i].mask))
+ continue;
+ state->events[i].counter++;
+ v4l2_dbg(2, debug, &state->mipi_sd, "%s: %d\n",
+ state->events[i].name,
+ state->events[i].counter);
+ }
+ v4l2_dbg(2, debug, &state->mipi_sd, "status: %08x\n", status);
+ }
+ spin_unlock_irqrestore(&state->slock, flags);
+
+ mipi_csis_write(state, MIPI_CSIS_INTSRC, status);
+ return IRQ_HANDLED;
+}
+
+static int subdev_notifier_bound(struct v4l2_async_notifier *notifier,
+ struct v4l2_subdev *subdev,
+ struct v4l2_async_subdev *asd)
+{
+ struct csi_state *state = notifier_to_mipi_dev(notifier);
+
+ /* Find platform data for this sensor subdev */
+ if (state->asd.match.fwnode.fwnode == dev_fwnode(subdev->dev))
+ state->sensor_sd = subdev;
+
+ if (subdev == NULL)
+ return -EINVAL;
+
+ v4l2_info(&state->v4l2_dev, "Registered sensor subdevice: %s\n",
+ subdev->name);
+
+ return 0;
+}
+
+static int mipi_csis_parse_dt(struct platform_device *pdev,
+ struct csi_state *state)
+{
+ struct device_node *node = pdev->dev.of_node;
+
+ if (of_property_read_u32(node, "clock-frequency",
+ &state->clk_frequency))
+ state->clk_frequency = DEFAULT_SCLK_CSIS_FREQ;
+ if (of_property_read_u32(node, "bus-width",
+ &state->max_num_lanes))
+ return -EINVAL;
+
+ node = of_graph_get_next_endpoint(node, NULL);
+ if (!node) {
+ dev_err(&pdev->dev, "No port node at %s\n",
+ pdev->dev.of_node->full_name);
+ return -EINVAL;
+ }
+
+ /* Get MIPI CSI-2 bus configration from the endpoint node. */
+ of_property_read_u32(node, "csis-hs-settle",
+ &state->hs_settle);
+
+ of_property_read_u32(node, "csis-clk-settle",
+ &state->clk_settle);
+ state->wclk_ext = of_property_read_bool(node,
+ "csis-wclk");
+
+ of_property_read_u32(node, "data-lanes",
+ &state->num_lanes);
+ of_node_put(node);
+
+ return 0;
+}
+
+static int mipi_csis_pm_resume(struct device *dev, bool runtime);
+static const struct of_device_id mipi_csis_of_match[];
+
+/* register parent dev */
+static int mipi_csis_subdev_host(struct csi_state *state)
+{
+ struct device_node *parent = state->dev->of_node;
+ struct device_node *node, *port, *rem;
+ int ret;
+
+ /* Attach sensors linked to csi receivers */
+ for_each_available_child_of_node(parent, node) {
+ if (of_node_cmp(node->name, "port"))
+ continue;
+
+ /* The csi node can have only port subnode. */
+ port = of_get_next_child(node, NULL);
+ if (!port)
+ continue;
+ rem = of_graph_get_remote_port_parent(port);
+ of_node_put(port);
+ if (rem == NULL) {
+ v4l2_info(&state->v4l2_dev,
+ "Remote device at %s not found\n",
+ port->full_name);
+ return -1;
+ }
+
+ state->asd.match_type = V4L2_ASYNC_MATCH_FWNODE;
+ state->asd.match.fwnode.fwnode = of_fwnode_handle(rem);
+ state->async_subdevs[0] = &state->asd;
+
+ of_node_put(rem);
+ break;
+ }
+
+ state->subdev_notifier.subdevs = state->async_subdevs;
+ state->subdev_notifier.num_subdevs = 1;
+ state->subdev_notifier.bound = subdev_notifier_bound;
+
+ ret = v4l2_async_notifier_register(&state->v4l2_dev,
+ &state->subdev_notifier);
+ if (ret)
+ dev_err(state->dev,
+ "Error register async notifier regoster\n");
+
+ return ret;
+}
+
+/* init subdev */
+static int mipi_csis_subdev_init(struct v4l2_subdev *mipi_sd,
+ struct platform_device *pdev,
+ const struct v4l2_subdev_ops *ops)
+{
+ struct csi_state *state = platform_get_drvdata(pdev);
+ int ret = 0;
+
+ v4l2_subdev_init(mipi_sd, ops);
+ mipi_sd->owner = THIS_MODULE;
+ snprintf(mipi_sd->name, sizeof(mipi_sd->name), "%s.%d",
+ CSIS_SUBDEV_NAME, state->index);
+ mipi_sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+ mipi_sd->dev = &pdev->dev;
+
+ state->csis_fmt = &mipi_csis_formats[0];
+ state->format.code = mipi_csis_formats[0].code;
+ state->format.width = MIPI_CSIS_DEF_PIX_WIDTH;
+ state->format.height = MIPI_CSIS_DEF_PIX_HEIGHT;
+
+ /* This allows to retrieve the platform device id by the host driver */
+ v4l2_set_subdevdata(mipi_sd, pdev);
+
+ ret = v4l2_async_register_subdev(mipi_sd);
+ if (ret < 0)
+ dev_err(&pdev->dev, "%s--Async register faialed, ret=%d\n", __func__, ret);
+
+ return ret;
+}
+
+static int mipi_csis_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct v4l2_subdev *mipi_sd;
+ struct resource *mem_res;
+ struct csi_state *state;
+ const struct of_device_id *of_id;
+ mipi_csis_phy_reset_t phy_reset_fn;
+ int ret = -ENOMEM;
+
+ state = devm_kzalloc(dev, sizeof(*state), GFP_KERNEL);
+ if (!state)
+ return -ENOMEM;
+
+ mutex_init(&state->lock);
+ spin_lock_init(&state->slock);
+
+ state->pdev = pdev;
+ mipi_sd = &state->mipi_sd;
+ state->dev = dev;
+
+ ret = mipi_csis_parse_dt(pdev, state);
+ if (ret < 0)
+ return ret;
+
+ if (state->num_lanes == 0 || state->num_lanes > state->max_num_lanes) {
+ dev_err(dev, "Unsupported number of data lanes: %d (max. %d)\n",
+ state->num_lanes, state->max_num_lanes);
+ return -EINVAL;
+ }
+
+ mipi_csis_phy_init(state);
+ of_id = of_match_node(mipi_csis_of_match, dev->of_node);
+ if (!of_id || !of_id->data)
+ return -EINVAL;
+
+ phy_reset_fn = of_id->data;
+
+ mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ state->regs = devm_ioremap_resource(dev, mem_res);
+ if (IS_ERR(state->regs))
+ return PTR_ERR(state->regs);
+
+ state->irq = platform_get_irq(pdev, 0);
+ if (state->irq < 0) {
+ dev_err(dev, "Failed to get irq\n");
+ return state->irq;
+ }
+
+ ret = mipi_csis_clk_get(state);
+ if (ret < 0)
+ return ret;
+
+ mipi_csis_clk_enable(state);
+
+ phy_reset_fn(state);
+
+ ret = devm_request_irq(dev, state->irq, mipi_csis_irq_handler,
+ 0, dev_name(dev), state);
+ if (ret) {
+ dev_err(dev, "Interrupt request failed\n");
+ goto e_clkdis;
+ }
+
+ /* First register a v4l2 device */
+ ret = v4l2_device_register(dev, &state->v4l2_dev);
+ if (ret) {
+ v4l2_err(dev->driver,
+ "Unable to register v4l2 device.\n");
+ goto e_clkdis;
+ }
+ v4l2_info(&state->v4l2_dev, "mipi csi v4l2 device registered\n");
+
+ /* .. and a pointer to the subdev. */
+ platform_set_drvdata(pdev, state);
+
+ ret = mipi_csis_subdev_init(&state->mipi_sd, pdev, &mipi_csis_subdev_ops);
+ if (ret < 0)
+ goto e_sd_mipi;
+
+ memcpy(state->events, mipi_csis_events, sizeof(state->events));
+
+ /* subdev host register */
+ ret = mipi_csis_subdev_host(state);
+ if (ret < 0)
+ goto e_sd_host;
+
+ pm_runtime_enable(dev);
+ if (!pm_runtime_enabled(dev)) {
+ ret = mipi_csis_pm_resume(dev, true);
+ if (ret < 0)
+ goto e_sd_host;
+ }
+
+ dev_info(&pdev->dev,
+ "lanes: %d, hs_settle: %d, clk_settle: %d, wclk: %d, freq: %u\n",
+ state->num_lanes, state->hs_settle, state->clk_settle,
+ state->wclk_ext, state->clk_frequency);
+ return 0;
+
+e_sd_host:
+ v4l2_async_notifier_unregister(&state->subdev_notifier);
+ v4l2_device_unregister(&state->v4l2_dev);
+e_sd_mipi:
+ v4l2_async_unregister_subdev(&state->mipi_sd);
+e_clkdis:
+ mipi_csis_clk_disable(state);
+ return ret;
+}
+
+static int mipi_csis_pm_suspend(struct device *dev, bool runtime)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct csi_state *state = platform_get_drvdata(pdev);
+ struct v4l2_subdev *mipi_sd = &state->mipi_sd;
+ int ret = 0;
+
+ v4l2_dbg(1, debug, mipi_sd, "%s: flags: 0x%x\n",
+ __func__, state->flags);
+
+ mutex_lock(&state->lock);
+ if (state->flags & ST_POWERED) {
+ mipi_csis_stop_stream(state);
+ ret = regulator_disable(state->mipi_phy_regulator);
+ if (ret)
+ goto unlock;
+ mipi_csis_clk_disable(state);
+ state->flags &= ~ST_POWERED;
+ if (!runtime)
+ state->flags |= ST_SUSPENDED;
+ }
+ unlock:
+ mutex_unlock(&state->lock);
+ return ret ? -EAGAIN : 0;
+}
+
+static int mipi_csis_pm_resume(struct device *dev, bool runtime)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct csi_state *state = platform_get_drvdata(pdev);
+ struct v4l2_subdev *mipi_sd = &state->mipi_sd;
+ int ret = 0;
+
+ v4l2_dbg(1, debug, mipi_sd, "%s: flags: 0x%x\n",
+ __func__, state->flags);
+
+ mutex_lock(&state->lock);
+ if (!runtime && !(state->flags & ST_SUSPENDED))
+ goto unlock;
+
+ if (!(state->flags & ST_POWERED)) {
+ ret = regulator_enable(state->mipi_phy_regulator);
+ if (!ret) {
+ state->flags |= ST_POWERED;
+ } else {
+ goto unlock;
+ }
+ mipi_csis_clk_enable(state);
+ }
+ if (state->flags & ST_STREAMING)
+ mipi_csis_start_stream(state);
+
+ state->flags &= ~ST_SUSPENDED;
+ unlock:
+ mutex_unlock(&state->lock);
+ return ret ? -EAGAIN : 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int mipi_csis_suspend(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct csi_state *state = platform_get_drvdata(pdev);
+
+ if (state->flags & ST_STREAMING) {
+ dev_warn(dev, "running, prevent entering suspend.\n");
+ return -EAGAIN;
+ }
+
+ return mipi_csis_pm_suspend(dev, false);
+}
+
+static int mipi_csis_resume(struct device *dev)
+{
+ return mipi_csis_pm_resume(dev, false);
+}
+#endif
+
+static int mipi_csis_runtime_suspend(struct device *dev)
+{
+ return mipi_csis_pm_suspend(dev, true);
+}
+
+static int mipi_csis_runtime_resume(struct device *dev)
+{
+ return mipi_csis_pm_resume(dev, true);
+}
+
+static int mipi_csis_remove(struct platform_device *pdev)
+{
+ struct csi_state *state = platform_get_drvdata(pdev);
+
+ v4l2_async_unregister_subdev(&state->mipi_sd);
+ v4l2_async_notifier_unregister(&state->subdev_notifier);
+ v4l2_device_unregister(&state->v4l2_dev);
+
+ pm_runtime_disable(&pdev->dev);
+ mipi_csis_pm_suspend(&pdev->dev, true);
+ mipi_csis_clk_disable(state);
+ pm_runtime_set_suspended(&pdev->dev);
+
+ return 0;
+}
+
+static const struct dev_pm_ops mipi_csis_pm_ops = {
+ SET_RUNTIME_PM_OPS(mipi_csis_runtime_suspend, mipi_csis_runtime_resume,
+ NULL)
+ SET_SYSTEM_SLEEP_PM_OPS(mipi_csis_suspend, mipi_csis_resume)
+};
+
+static const struct of_device_id mipi_csis_of_match[] = {
+ { .compatible = "fsl,imx7d-mipi-csi",
+ .data = (void *)&mipi_csis_phy_reset,
+ },
+ { .compatible = "fsl,imx8mm-mipi-csi",
+ .data = (void *)&mipi_csis_phy_reset_mx8mm,
+ },
+ { /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, mipi_csis_of_match);
+
+static struct platform_driver mipi_csis_driver = {
+ .probe = mipi_csis_probe,
+ .remove = mipi_csis_remove,
+ .driver = {
+ .of_match_table = mipi_csis_of_match,
+ .name = CSIS_DRIVER_NAME,
+ .owner = THIS_MODULE,
+ .pm = &mipi_csis_pm_ops,
+ },
+};
+
+module_platform_driver(mipi_csis_driver);
+
+MODULE_DESCRIPTION("Freescale MIPI-CSI2 receiver driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/platform/mxc/capture/mxc_v4l2_capture.c b/drivers/media/platform/mxc/capture/mxc_v4l2_capture.c
new file mode 100644
index 000000000000..3d7adecaa325
--- /dev/null
+++ b/drivers/media/platform/mxc/capture/mxc_v4l2_capture.c
@@ -0,0 +1,3148 @@
+/*
+ * Copyright 2004-2015 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/*!
+ * @file drivers/media/video/mxc/capture/mxc_v4l2_capture.c
+ *
+ * @brief Mxc Video For Linux 2 driver
+ *
+ * @ingroup MXC_V4L2_CAPTURE
+ */
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/fs.h>
+#include <linux/slab.h>
+#include <linux/ctype.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/semaphore.h>
+#include <linux/pagemap.h>
+#include <linux/vmalloc.h>
+#include <linux/types.h>
+#include <linux/fb.h>
+#include <linux/dma-mapping.h>
+#include <linux/delay.h>
+#include <linux/mxcfb.h>
+#include <linux/of_device.h>
+#include <media/v4l2-chip-ident.h>
+#include <media/v4l2-ioctl.h>
+#include <media/v4l2-device.h>
+#include "v4l2-int-device.h"
+#include <linux/fsl_devices.h>
+#include "mxc_v4l2_capture.h"
+#include "ipu_prp_sw.h"
+
+#define init_MUTEX(sem) sema_init(sem, 1)
+
+static struct platform_device_id imx_v4l2_devtype[] = {
+ {
+ .name = "v4l2-capture-imx5",
+ .driver_data = IMX5_V4L2,
+ }, {
+ .name = "v4l2-capture-imx6",
+ .driver_data = IMX6_V4L2,
+ }, {
+ /* sentinel */
+ }
+};
+MODULE_DEVICE_TABLE(platform, imx_v4l2_devtype);
+
+static const struct of_device_id mxc_v4l2_dt_ids[] = {
+ {
+ .compatible = "fsl,imx6q-v4l2-capture",
+ .data = &imx_v4l2_devtype[IMX6_V4L2],
+ }, {
+ /* sentinel */
+ }
+};
+MODULE_DEVICE_TABLE(of, mxc_v4l2_dt_ids);
+
+static int video_nr = -1;
+
+/*! This data is used for the output to the display. */
+#define MXC_V4L2_CAPTURE_NUM_OUTPUTS 6
+#define MXC_V4L2_CAPTURE_NUM_INPUTS 2
+static struct v4l2_output mxc_capture_outputs[MXC_V4L2_CAPTURE_NUM_OUTPUTS] = {
+ {
+ .index = 0,
+ .name = "DISP3 BG",
+ .type = V4L2_OUTPUT_TYPE_ANALOG,
+ .audioset = 0,
+ .modulator = 0,
+ .std = V4L2_STD_UNKNOWN,
+ },
+ {
+ .index = 1,
+ .name = "DISP3 BG - DI1",
+ .type = V4L2_OUTPUT_TYPE_ANALOG,
+ .audioset = 0,
+ .modulator = 0,
+ .std = V4L2_STD_UNKNOWN,
+ },
+ {
+ .index = 2,
+ .name = "DISP3 FG",
+ .type = V4L2_OUTPUT_TYPE_ANALOG,
+ .audioset = 0,
+ .modulator = 0,
+ .std = V4L2_STD_UNKNOWN,
+ },
+ {
+ .index = 3,
+ .name = "DISP4 BG",
+ .type = V4L2_OUTPUT_TYPE_ANALOG,
+ .audioset = 0,
+ .modulator = 0,
+ .std = V4L2_STD_UNKNOWN,
+ },
+ {
+ .index = 4,
+ .name = "DISP4 BG - DI1",
+ .type = V4L2_OUTPUT_TYPE_ANALOG,
+ .audioset = 0,
+ .modulator = 0,
+ .std = V4L2_STD_UNKNOWN,
+ },
+ {
+ .index = 5,
+ .name = "DISP4 FG",
+ .type = V4L2_OUTPUT_TYPE_ANALOG,
+ .audioset = 0,
+ .modulator = 0,
+ .std = V4L2_STD_UNKNOWN,
+ },
+};
+
+static struct v4l2_input mxc_capture_inputs[MXC_V4L2_CAPTURE_NUM_INPUTS] = {
+ {
+ .index = 0,
+ .name = "CSI IC MEM",
+ .type = V4L2_INPUT_TYPE_CAMERA,
+ .audioset = 0,
+ .tuner = 0,
+ .std = V4L2_STD_UNKNOWN,
+ .status = 0,
+ },
+ {
+ .index = 1,
+ .name = "CSI MEM",
+ .type = V4L2_INPUT_TYPE_CAMERA,
+ .audioset = 0,
+ .tuner = 0,
+ .std = V4L2_STD_UNKNOWN,
+ .status = V4L2_IN_ST_NO_POWER,
+ },
+};
+
+/*! List of TV input video formats supported. The video formats is corresponding
+ * to the v4l2_id in video_fmt_t.
+ * Currently, only PAL and NTSC is supported. Needs to be expanded in the
+ * future.
+ */
+typedef enum {
+ TV_NTSC = 0, /*!< Locked on (M) NTSC video signal. */
+ TV_PAL, /*!< (B, G, H, I, N)PAL video signal. */
+ TV_NOT_LOCKED, /*!< Not locked on a signal. */
+} video_fmt_idx;
+
+/*! Number of video standards supported (including 'not locked' signal). */
+#define TV_STD_MAX (TV_NOT_LOCKED + 1)
+
+/*! Video format structure. */
+typedef struct {
+ int v4l2_id; /*!< Video for linux ID. */
+ char name[16]; /*!< Name (e.g., "NTSC", "PAL", etc.) */
+ u16 raw_width; /*!< Raw width. */
+ u16 raw_height; /*!< Raw height. */
+ u16 active_width; /*!< Active width. */
+ u16 active_height; /*!< Active height. */
+ u16 active_top; /*!< Active top. */
+ u16 active_left; /*!< Active left. */
+} video_fmt_t;
+
+/*!
+ * Description of video formats supported.
+ *
+ * PAL: raw=720x625, active=720x576.
+ * NTSC: raw=720x525, active=720x480.
+ */
+static video_fmt_t video_fmts[] = {
+ { /*! NTSC */
+ .v4l2_id = V4L2_STD_NTSC,
+ .name = "NTSC",
+ .raw_width = 720, /* SENS_FRM_WIDTH */
+ .raw_height = 525, /* SENS_FRM_HEIGHT */
+ .active_width = 720, /* ACT_FRM_WIDTH */
+ .active_height = 480, /* ACT_FRM_HEIGHT */
+ .active_top = 13,
+ .active_left = 0,
+ },
+ { /*! (B, G, H, I, N) PAL */
+ .v4l2_id = V4L2_STD_PAL,
+ .name = "PAL",
+ .raw_width = 720,
+ .raw_height = 625,
+ .active_width = 720,
+ .active_height = 576,
+ .active_top = 0,
+ .active_left = 0,
+ },
+ { /*! Unlocked standard */
+ .v4l2_id = V4L2_STD_ALL,
+ .name = "Autodetect",
+ .raw_width = 720,
+ .raw_height = 625,
+ .active_width = 720,
+ .active_height = 576,
+ .active_top = 0,
+ .active_left = 0,
+ },
+};
+
+/*!* Standard index of TV. */
+static video_fmt_idx video_index = TV_NOT_LOCKED;
+
+static int mxc_v4l2_master_attach(struct v4l2_int_device *slave);
+static void mxc_v4l2_master_detach(struct v4l2_int_device *slave);
+static int start_preview(cam_data *cam);
+static int stop_preview(cam_data *cam);
+
+/*! Information about this driver. */
+static struct v4l2_int_master mxc_v4l2_master = {
+ .attach = mxc_v4l2_master_attach,
+ .detach = mxc_v4l2_master_detach,
+};
+
+/***************************************************************************
+ * Functions for handling Frame buffers.
+ **************************************************************************/
+
+/*!
+ * Free frame buffers
+ *
+ * @param cam Structure cam_data *
+ *
+ * @return status 0 success.
+ */
+static int mxc_free_frame_buf(cam_data *cam)
+{
+ int i;
+
+ pr_debug("MVC: In mxc_free_frame_buf\n");
+
+ for (i = 0; i < FRAME_NUM; i++) {
+ if (cam->frame[i].vaddress != 0) {
+ dma_free_coherent(0, cam->frame[i].buffer.length,
+ cam->frame[i].vaddress,
+ cam->frame[i].paddress);
+ cam->frame[i].vaddress = 0;
+ }
+ }
+
+ return 0;
+}
+
+/*!
+ * Allocate frame buffers
+ *
+ * @param cam Structure cam_data*
+ * @param count int number of buffer need to allocated
+ *
+ * @return status -0 Successfully allocated a buffer, -ENOBUFS failed.
+ */
+static int mxc_allocate_frame_buf(cam_data *cam, int count)
+{
+ int i;
+
+ pr_debug("In MVC:mxc_allocate_frame_buf - size=%d\n",
+ cam->v2f.fmt.pix.sizeimage);
+
+ for (i = 0; i < count; i++) {
+ cam->frame[i].vaddress =
+ dma_alloc_coherent(0,
+ PAGE_ALIGN(cam->v2f.fmt.pix.sizeimage),
+ &cam->frame[i].paddress,
+ GFP_DMA | GFP_KERNEL);
+ if (cam->frame[i].vaddress == 0) {
+ pr_err("ERROR: v4l2 capture: "
+ "mxc_allocate_frame_buf failed.\n");
+ mxc_free_frame_buf(cam);
+ return -ENOBUFS;
+ }
+ cam->frame[i].buffer.index = i;
+ cam->frame[i].buffer.flags = V4L2_BUF_FLAG_MAPPED;
+ cam->frame[i].buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ cam->frame[i].buffer.length =
+ PAGE_ALIGN(cam->v2f.fmt.pix.sizeimage);
+ cam->frame[i].buffer.memory = V4L2_MEMORY_MMAP;
+ cam->frame[i].buffer.m.offset = cam->frame[i].paddress;
+ cam->frame[i].index = i;
+ }
+
+ return 0;
+}
+
+/*!
+ * Free frame buffers status
+ *
+ * @param cam Structure cam_data *
+ *
+ * @return none
+ */
+static void mxc_free_frames(cam_data *cam)
+{
+ int i;
+
+ pr_debug("In MVC:mxc_free_frames\n");
+
+ for (i = 0; i < FRAME_NUM; i++)
+ cam->frame[i].buffer.flags = V4L2_BUF_FLAG_MAPPED;
+
+ cam->enc_counter = 0;
+ INIT_LIST_HEAD(&cam->ready_q);
+ INIT_LIST_HEAD(&cam->working_q);
+ INIT_LIST_HEAD(&cam->done_q);
+}
+
+/*!
+ * Return the buffer status
+ *
+ * @param cam Structure cam_data *
+ * @param buf Structure v4l2_buffer *
+ *
+ * @return status 0 success, EINVAL failed.
+ */
+static int mxc_v4l2_buffer_status(cam_data *cam, struct v4l2_buffer *buf)
+{
+ pr_debug("In MVC:mxc_v4l2_buffer_status\n");
+
+ if (buf->index < 0 || buf->index >= FRAME_NUM) {
+ pr_err("ERROR: v4l2 capture: mxc_v4l2_buffer_status buffers "
+ "not allocated\n");
+ return -EINVAL;
+ }
+
+ memcpy(buf, &(cam->frame[buf->index].buffer), sizeof(*buf));
+ return 0;
+}
+
+static int mxc_v4l2_release_bufs(cam_data *cam)
+{
+ pr_debug("In MVC:mxc_v4l2_release_bufs\n");
+ return 0;
+}
+
+static int mxc_v4l2_prepare_bufs(cam_data *cam, struct v4l2_buffer *buf)
+{
+ pr_debug("In MVC:mxc_v4l2_prepare_bufs\n");
+
+ if (buf->index < 0 || buf->index >= FRAME_NUM || buf->length <
+ PAGE_ALIGN(cam->v2f.fmt.pix.sizeimage)) {
+ pr_err("ERROR: v4l2 capture: mxc_v4l2_prepare_bufs buffers "
+ "not allocated,index=%d, length=%d\n", buf->index,
+ buf->length);
+ return -EINVAL;
+ }
+
+ cam->frame[buf->index].buffer.index = buf->index;
+ cam->frame[buf->index].buffer.flags = V4L2_BUF_FLAG_MAPPED;
+ cam->frame[buf->index].buffer.length = buf->length;
+ cam->frame[buf->index].buffer.m.offset = cam->frame[buf->index].paddress
+ = buf->m.offset;
+ cam->frame[buf->index].buffer.type = buf->type;
+ cam->frame[buf->index].buffer.memory = V4L2_MEMORY_USERPTR;
+ cam->frame[buf->index].index = buf->index;
+
+ return 0;
+}
+
+/***************************************************************************
+ * Functions for handling the video stream.
+ **************************************************************************/
+
+/*!
+ * Indicates whether the palette is supported.
+ *
+ * @param palette V4L2_PIX_FMT_RGB565, V4L2_PIX_FMT_BGR24 or V4L2_PIX_FMT_BGR32
+ *
+ * @return 0 if failed
+ */
+static inline int valid_mode(u32 palette)
+{
+ return ((palette == V4L2_PIX_FMT_RGB565) ||
+ (palette == V4L2_PIX_FMT_BGR24) ||
+ (palette == V4L2_PIX_FMT_RGB24) ||
+ (palette == V4L2_PIX_FMT_BGR32) ||
+ (palette == V4L2_PIX_FMT_RGB32) ||
+ (palette == V4L2_PIX_FMT_YUV422P) ||
+ (palette == V4L2_PIX_FMT_UYVY) ||
+ (palette == V4L2_PIX_FMT_YUYV) ||
+ (palette == V4L2_PIX_FMT_YUV420) ||
+ (palette == V4L2_PIX_FMT_YVU420) ||
+ (palette == V4L2_PIX_FMT_NV12));
+}
+
+/*!
+ * Start the encoder job
+ *
+ * @param cam structure cam_data *
+ *
+ * @return status 0 Success
+ */
+static int mxc_streamon(cam_data *cam)
+{
+ struct mxc_v4l_frame *frame;
+ unsigned long lock_flags;
+ int err = 0;
+
+ pr_debug("In MVC:mxc_streamon\n");
+
+ if (NULL == cam) {
+ pr_err("ERROR! cam parameter is NULL\n");
+ return -1;
+ }
+
+ if (cam->capture_on) {
+ pr_err("ERROR: v4l2 capture: Capture stream has been turned "
+ " on\n");
+ return -1;
+ }
+
+ if (list_empty(&cam->ready_q)) {
+ pr_err("ERROR: v4l2 capture: mxc_streamon buffer has not been "
+ "queued yet\n");
+ return -EINVAL;
+ }
+ if (cam->enc_update_eba &&
+ cam->ready_q.prev == cam->ready_q.next) {
+ pr_err("ERROR: v4l2 capture: mxc_streamon buffer need "
+ "ping pong at least two buffers\n");
+ return -EINVAL;
+ }
+
+ cam->capture_pid = current->pid;
+
+ if (cam->overlay_on == true)
+ stop_preview(cam);
+
+ if (cam->enc_enable) {
+ err = cam->enc_enable(cam);
+ if (err != 0)
+ return err;
+ }
+
+ spin_lock_irqsave(&cam->queue_int_lock, lock_flags);
+ cam->ping_pong_csi = 0;
+ cam->local_buf_num = 0;
+ if (cam->enc_update_eba) {
+ frame =
+ list_entry(cam->ready_q.next, struct mxc_v4l_frame, queue);
+ list_del(cam->ready_q.next);
+ list_add_tail(&frame->queue, &cam->working_q);
+ frame->ipu_buf_num = cam->ping_pong_csi;
+ err = cam->enc_update_eba(cam, frame->buffer.m.offset);
+
+ frame =
+ list_entry(cam->ready_q.next, struct mxc_v4l_frame, queue);
+ list_del(cam->ready_q.next);
+ list_add_tail(&frame->queue, &cam->working_q);
+ frame->ipu_buf_num = cam->ping_pong_csi;
+ err |= cam->enc_update_eba(cam, frame->buffer.m.offset);
+ spin_unlock_irqrestore(&cam->queue_int_lock, lock_flags);
+ } else {
+ spin_unlock_irqrestore(&cam->queue_int_lock, lock_flags);
+ return -EINVAL;
+ }
+
+ if (cam->overlay_on == true)
+ start_preview(cam);
+
+ if (cam->enc_enable_csi) {
+ err = cam->enc_enable_csi(cam);
+ if (err != 0)
+ return err;
+ }
+
+ cam->capture_on = true;
+
+ return err;
+}
+
+/*!
+ * Shut down the encoder job
+ *
+ * @param cam structure cam_data *
+ *
+ * @return status 0 Success
+ */
+static int mxc_streamoff(cam_data *cam)
+{
+ int err = 0;
+
+ pr_debug("In MVC:mxc_streamoff\n");
+
+ if (cam->capture_on == false)
+ return 0;
+
+ /* For both CSI--MEM and CSI--IC--MEM
+ * 1. wait for idmac eof
+ * 2. disable csi first
+ * 3. disable idmac
+ * 4. disable smfc (CSI--MEM channel)
+ */
+ if (mxc_capture_inputs[cam->current_input].name != NULL) {
+ if (cam->enc_disable_csi) {
+ err = cam->enc_disable_csi(cam);
+ if (err != 0)
+ return err;
+ }
+ if (cam->enc_disable) {
+ err = cam->enc_disable(cam);
+ if (err != 0)
+ return err;
+ }
+ }
+
+ mxc_free_frames(cam);
+ mxc_capture_inputs[cam->current_input].status |= V4L2_IN_ST_NO_POWER;
+ cam->capture_on = false;
+ return err;
+}
+
+/*!
+ * Valid and adjust the overlay window size, position
+ *
+ * @param cam structure cam_data *
+ * @param win struct v4l2_window *
+ *
+ * @return 0
+ */
+static int verify_preview(cam_data *cam, struct v4l2_window *win)
+{
+ int i = 0, width_bound = 0, height_bound = 0;
+ int *width, *height;
+ unsigned int ipu_ch = CHAN_NONE;
+ struct fb_info *bg_fbi = NULL, *fbi = NULL;
+ bool foregound_fb = false;
+ mm_segment_t old_fs;
+
+ pr_debug("In MVC: verify_preview\n");
+
+ do {
+ fbi = (struct fb_info *)registered_fb[i];
+ if (fbi == NULL) {
+ pr_err("ERROR: verify_preview frame buffer NULL.\n");
+ return -1;
+ }
+
+ /* Which DI supports 2 layers? */
+ if (((strncmp(fbi->fix.id, "DISP3 BG", 8) == 0) &&
+ (cam->output < 3)) ||
+ ((strncmp(fbi->fix.id, "DISP4 BG", 8) == 0) &&
+ (cam->output >= 3))) {
+ if (fbi->fbops->fb_ioctl) {
+ old_fs = get_fs();
+ set_fs(KERNEL_DS);
+ fbi->fbops->fb_ioctl(fbi, MXCFB_GET_FB_IPU_CHAN,
+ (unsigned long)&ipu_ch);
+ set_fs(old_fs);
+ }
+ if (ipu_ch == MEM_BG_SYNC) {
+ bg_fbi = fbi;
+ pr_debug("Found background frame buffer.\n");
+ }
+ }
+
+ /* Found the frame buffer to preview on. */
+ if (strcmp(fbi->fix.id,
+ mxc_capture_outputs[cam->output].name) == 0) {
+ if (((strcmp(fbi->fix.id, "DISP3 FG") == 0) &&
+ (cam->output < 3)) ||
+ ((strcmp(fbi->fix.id, "DISP4 FG") == 0) &&
+ (cam->output >= 3)))
+ foregound_fb = true;
+
+ cam->overlay_fb = fbi;
+ break;
+ }
+ } while (++i < FB_MAX);
+
+ if (foregound_fb) {
+ width_bound = bg_fbi->var.xres;
+ height_bound = bg_fbi->var.yres;
+
+ if (win->w.width + win->w.left > bg_fbi->var.xres ||
+ win->w.height + win->w.top > bg_fbi->var.yres) {
+ pr_err("ERROR: FG window position exceeds.\n");
+ return -1;
+ }
+ } else {
+ /* 4 bytes alignment for BG */
+ width_bound = cam->overlay_fb->var.xres;
+ height_bound = cam->overlay_fb->var.yres;
+
+ if (cam->overlay_fb->var.bits_per_pixel == 24)
+ win->w.left -= win->w.left % 4;
+ else if (cam->overlay_fb->var.bits_per_pixel == 16)
+ win->w.left -= win->w.left % 2;
+
+ if (win->w.width + win->w.left > cam->overlay_fb->var.xres)
+ win->w.width = cam->overlay_fb->var.xres - win->w.left;
+ if (win->w.height + win->w.top > cam->overlay_fb->var.yres)
+ win->w.height = cam->overlay_fb->var.yres - win->w.top;
+ }
+
+ /* stride line limitation */
+ win->w.height -= win->w.height % 8;
+ win->w.width -= win->w.width % 8;
+
+ if (cam->rotation >= IPU_ROTATE_90_RIGHT) {
+ height = &win->w.width;
+ width = &win->w.height;
+ } else {
+ width = &win->w.width;
+ height = &win->w.height;
+ }
+
+ if (*width == 0 || *height == 0) {
+ pr_err("ERROR: v4l2 capture: width or height"
+ " too small.\n");
+ return -EINVAL;
+ }
+
+ if ((cam->crop_bounds.width / *width > 8) ||
+ ((cam->crop_bounds.width / *width == 8) &&
+ (cam->crop_bounds.width % *width))) {
+ *width = cam->crop_bounds.width / 8;
+ if (*width % 8)
+ *width += 8 - *width % 8;
+ if (*width + win->w.left > width_bound) {
+ pr_err("ERROR: v4l2 capture: width exceeds "
+ "resize limit.\n");
+ return -1;
+ }
+ pr_err("ERROR: v4l2 capture: width exceeds limit. "
+ "Resize to %d.\n",
+ *width);
+ }
+
+ if ((cam->crop_bounds.height / *height > 8) ||
+ ((cam->crop_bounds.height / *height == 8) &&
+ (cam->crop_bounds.height % *height))) {
+ *height = cam->crop_bounds.height / 8;
+ if (*height % 8)
+ *height += 8 - *height % 8;
+ if (*height + win->w.top > height_bound) {
+ pr_err("ERROR: v4l2 capture: height exceeds "
+ "resize limit.\n");
+ return -1;
+ }
+ pr_err("ERROR: v4l2 capture: height exceeds limit "
+ "resize to %d.\n",
+ *height);
+ }
+
+ return 0;
+}
+
+/*!
+ * start the viewfinder job
+ *
+ * @param cam structure cam_data *
+ *
+ * @return status 0 Success
+ */
+static int start_preview(cam_data *cam)
+{
+ int err = 0;
+
+ pr_debug("MVC: start_preview\n");
+
+ if (cam->v4l2_fb.flags == V4L2_FBUF_FLAG_OVERLAY)
+ #ifdef CONFIG_MXC_IPU_PRP_VF_SDC
+ err = prp_vf_sdc_select(cam);
+ #else
+ err = foreground_sdc_select(cam);
+ #endif
+ else if (cam->v4l2_fb.flags == V4L2_FBUF_FLAG_PRIMARY)
+ #ifdef CONFIG_MXC_IPU_PRP_VF_SDC
+ err = prp_vf_sdc_select_bg(cam);
+ #else
+ err = bg_overlay_sdc_select(cam);
+ #endif
+ if (err != 0)
+ return err;
+
+ if (cam->vf_start_sdc) {
+ err = cam->vf_start_sdc(cam);
+ if (err != 0)
+ return err;
+ }
+
+ if (cam->vf_enable_csi)
+ err = cam->vf_enable_csi(cam);
+
+ pr_debug("End of %s: v2f pix widthxheight %d x %d\n",
+ __func__,
+ cam->v2f.fmt.pix.width, cam->v2f.fmt.pix.height);
+ pr_debug("End of %s: crop_bounds widthxheight %d x %d\n",
+ __func__,
+ cam->crop_bounds.width, cam->crop_bounds.height);
+ pr_debug("End of %s: crop_defrect widthxheight %d x %d\n",
+ __func__,
+ cam->crop_defrect.width, cam->crop_defrect.height);
+ pr_debug("End of %s: crop_current widthxheight %d x %d\n",
+ __func__,
+ cam->crop_current.width, cam->crop_current.height);
+
+ return err;
+}
+
+/*!
+ * shut down the viewfinder job
+ *
+ * @param cam structure cam_data *
+ *
+ * @return status 0 Success
+ */
+static int stop_preview(cam_data *cam)
+{
+ int err = 0;
+
+ if (cam->vf_disable_csi) {
+ err = cam->vf_disable_csi(cam);
+ if (err != 0)
+ return err;
+ }
+
+ if (cam->vf_stop_sdc) {
+ err = cam->vf_stop_sdc(cam);
+ if (err != 0)
+ return err;
+ }
+
+ if (cam->v4l2_fb.flags == V4L2_FBUF_FLAG_OVERLAY)
+ #ifdef CONFIG_MXC_IPU_PRP_VF_SDC
+ err = prp_vf_sdc_deselect(cam);
+ #else
+ err = foreground_sdc_deselect(cam);
+ #endif
+ else if (cam->v4l2_fb.flags == V4L2_FBUF_FLAG_PRIMARY)
+ #ifdef CONFIG_MXC_IPU_PRP_VF_SDC
+ err = prp_vf_sdc_deselect_bg(cam);
+ #else
+ err = bg_overlay_sdc_deselect(cam);
+ #endif
+
+ return err;
+}
+
+/***************************************************************************
+ * VIDIOC Functions.
+ **************************************************************************/
+
+/*!
+ * V4L2 - mxc_v4l2_g_fmt function
+ *
+ * @param cam structure cam_data *
+ *
+ * @param f structure v4l2_format *
+ *
+ * @return status 0 success, EINVAL failed
+ */
+static int mxc_v4l2_g_fmt(cam_data *cam, struct v4l2_format *f)
+{
+ int retval = 0;
+
+ pr_debug("In MVC: mxc_v4l2_g_fmt type=%d\n", f->type);
+
+ switch (f->type) {
+ case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+ pr_debug(" type is V4L2_BUF_TYPE_VIDEO_CAPTURE\n");
+ f->fmt.pix = cam->v2f.fmt.pix;
+ break;
+ case V4L2_BUF_TYPE_VIDEO_OVERLAY:
+ pr_debug(" type is V4L2_BUF_TYPE_VIDEO_OVERLAY\n");
+ f->fmt.win = cam->win;
+ break;
+ default:
+ pr_debug(" type is invalid\n");
+ retval = -EINVAL;
+ }
+
+ pr_debug("End of %s: v2f pix widthxheight %d x %d\n",
+ __func__,
+ cam->v2f.fmt.pix.width, cam->v2f.fmt.pix.height);
+ pr_debug("End of %s: crop_bounds widthxheight %d x %d\n",
+ __func__,
+ cam->crop_bounds.width, cam->crop_bounds.height);
+ pr_debug("End of %s: crop_defrect widthxheight %d x %d\n",
+ __func__,
+ cam->crop_defrect.width, cam->crop_defrect.height);
+ pr_debug("End of %s: crop_current widthxheight %d x %d\n",
+ __func__,
+ cam->crop_current.width, cam->crop_current.height);
+
+ return retval;
+}
+
+/*!
+ * V4L2 - mxc_v4l2_s_fmt function
+ *
+ * @param cam structure cam_data *
+ *
+ * @param f structure v4l2_format *
+ *
+ * @return status 0 success, EINVAL failed
+ */
+static int mxc_v4l2_s_fmt(cam_data *cam, struct v4l2_format *f)
+{
+ int retval = 0;
+ int size = 0;
+ int bytesperline = 0;
+ int *width, *height;
+
+ pr_debug("In MVC: mxc_v4l2_s_fmt\n");
+
+ switch (f->type) {
+ case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+ pr_debug(" type=V4L2_BUF_TYPE_VIDEO_CAPTURE\n");
+ if (!valid_mode(f->fmt.pix.pixelformat)) {
+ pr_err("ERROR: v4l2 capture: mxc_v4l2_s_fmt: format "
+ "not supported\n");
+ return -EINVAL;
+ }
+
+ /*
+ * Force the capture window resolution to be crop bounds
+ * for CSI MEM input mode.
+ */
+ if (strcmp(mxc_capture_inputs[cam->current_input].name,
+ "CSI MEM") == 0) {
+ f->fmt.pix.width = cam->crop_current.width;
+ f->fmt.pix.height = cam->crop_current.height;
+ }
+
+ if (cam->rotation >= IPU_ROTATE_90_RIGHT) {
+ height = &f->fmt.pix.width;
+ width = &f->fmt.pix.height;
+ } else {
+ width = &f->fmt.pix.width;
+ height = &f->fmt.pix.height;
+ }
+
+ /* stride line limitation */
+ *width -= *width % 8;
+ *height -= *height % 8;
+
+ if (*width == 0 || *height == 0) {
+ pr_err("ERROR: v4l2 capture: width or height"
+ " too small.\n");
+ return -EINVAL;
+ }
+
+ if ((cam->crop_current.width / *width > 8) ||
+ ((cam->crop_current.width / *width == 8) &&
+ (cam->crop_current.width % *width))) {
+ *width = cam->crop_current.width / 8;
+ if (*width % 8)
+ *width += 8 - *width % 8;
+ pr_err("ERROR: v4l2 capture: width exceeds limit "
+ "resize to %d.\n",
+ *width);
+ }
+
+ if ((cam->crop_current.height / *height > 8) ||
+ ((cam->crop_current.height / *height == 8) &&
+ (cam->crop_current.height % *height))) {
+ *height = cam->crop_current.height / 8;
+ if (*height % 8)
+ *height += 8 - *height % 8;
+ pr_err("ERROR: v4l2 capture: height exceeds limit "
+ "resize to %d.\n",
+ *height);
+ }
+
+ switch (f->fmt.pix.pixelformat) {
+ case V4L2_PIX_FMT_RGB565:
+ size = f->fmt.pix.width * f->fmt.pix.height * 2;
+ bytesperline = f->fmt.pix.width * 2;
+ break;
+ case V4L2_PIX_FMT_BGR24:
+ size = f->fmt.pix.width * f->fmt.pix.height * 3;
+ bytesperline = f->fmt.pix.width * 3;
+ break;
+ case V4L2_PIX_FMT_RGB24:
+ size = f->fmt.pix.width * f->fmt.pix.height * 3;
+ bytesperline = f->fmt.pix.width * 3;
+ break;
+ case V4L2_PIX_FMT_BGR32:
+ size = f->fmt.pix.width * f->fmt.pix.height * 4;
+ bytesperline = f->fmt.pix.width * 4;
+ break;
+ case V4L2_PIX_FMT_RGB32:
+ size = f->fmt.pix.width * f->fmt.pix.height * 4;
+ bytesperline = f->fmt.pix.width * 4;
+ break;
+ case V4L2_PIX_FMT_YUV422P:
+ size = f->fmt.pix.width * f->fmt.pix.height * 2;
+ bytesperline = f->fmt.pix.width;
+ break;
+ case V4L2_PIX_FMT_UYVY:
+ case V4L2_PIX_FMT_YUYV:
+ size = f->fmt.pix.width * f->fmt.pix.height * 2;
+ bytesperline = f->fmt.pix.width * 2;
+ break;
+ case V4L2_PIX_FMT_YUV420:
+ case V4L2_PIX_FMT_YVU420:
+ size = f->fmt.pix.width * f->fmt.pix.height * 3 / 2;
+ bytesperline = f->fmt.pix.width;
+ break;
+ case V4L2_PIX_FMT_NV12:
+ size = f->fmt.pix.width * f->fmt.pix.height * 3 / 2;
+ bytesperline = f->fmt.pix.width;
+ break;
+ default:
+ break;
+ }
+
+ if (f->fmt.pix.bytesperline < bytesperline)
+ f->fmt.pix.bytesperline = bytesperline;
+ else
+ bytesperline = f->fmt.pix.bytesperline;
+
+ if (f->fmt.pix.sizeimage < size)
+ f->fmt.pix.sizeimage = size;
+ else
+ size = f->fmt.pix.sizeimage;
+
+ cam->v2f.fmt.pix = f->fmt.pix;
+ break;
+ case V4L2_BUF_TYPE_VIDEO_OVERLAY:
+ pr_debug(" type=V4L2_BUF_TYPE_VIDEO_OVERLAY\n");
+ retval = verify_preview(cam, &f->fmt.win);
+ cam->win = f->fmt.win;
+ break;
+ default:
+ retval = -EINVAL;
+ }
+
+ pr_debug("End of %s: v2f pix widthxheight %d x %d\n",
+ __func__,
+ cam->v2f.fmt.pix.width, cam->v2f.fmt.pix.height);
+ pr_debug("End of %s: crop_bounds widthxheight %d x %d\n",
+ __func__,
+ cam->crop_bounds.width, cam->crop_bounds.height);
+ pr_debug("End of %s: crop_defrect widthxheight %d x %d\n",
+ __func__,
+ cam->crop_defrect.width, cam->crop_defrect.height);
+ pr_debug("End of %s: crop_current widthxheight %d x %d\n",
+ __func__,
+ cam->crop_current.width, cam->crop_current.height);
+
+ return retval;
+}
+
+/*!
+ * get control param
+ *
+ * @param cam structure cam_data *
+ *
+ * @param c structure v4l2_control *
+ *
+ * @return status 0 success, EINVAL failed
+ */
+static int mxc_v4l2_g_ctrl(cam_data *cam, struct v4l2_control *c)
+{
+ int status = 0;
+
+ pr_debug("In MVC:mxc_v4l2_g_ctrl\n");
+
+ /* probably don't need to store the values that can be retrieved,
+ * locally, but they are for now. */
+ switch (c->id) {
+ case V4L2_CID_HFLIP:
+ /* This is handled in the ipu. */
+ if (cam->rotation == IPU_ROTATE_HORIZ_FLIP)
+ c->value = 1;
+ break;
+ case V4L2_CID_VFLIP:
+ /* This is handled in the ipu. */
+ if (cam->rotation == IPU_ROTATE_VERT_FLIP)
+ c->value = 1;
+ break;
+ case V4L2_CID_MXC_ROT:
+ /* This is handled in the ipu. */
+ c->value = cam->rotation;
+ break;
+ case V4L2_CID_BRIGHTNESS:
+ if (cam->sensor) {
+ c->value = cam->bright;
+ status = vidioc_int_g_ctrl(cam->sensor, c);
+ cam->bright = c->value;
+ } else {
+ pr_err("ERROR: v4l2 capture: slave not found!\n");
+ status = -ENODEV;
+ }
+ break;
+ case V4L2_CID_HUE:
+ if (cam->sensor) {
+ c->value = cam->hue;
+ status = vidioc_int_g_ctrl(cam->sensor, c);
+ cam->hue = c->value;
+ } else {
+ pr_err("ERROR: v4l2 capture: slave not found!\n");
+ status = -ENODEV;
+ }
+ break;
+ case V4L2_CID_CONTRAST:
+ if (cam->sensor) {
+ c->value = cam->contrast;
+ status = vidioc_int_g_ctrl(cam->sensor, c);
+ cam->contrast = c->value;
+ } else {
+ pr_err("ERROR: v4l2 capture: slave not found!\n");
+ status = -ENODEV;
+ }
+ break;
+ case V4L2_CID_SATURATION:
+ if (cam->sensor) {
+ c->value = cam->saturation;
+ status = vidioc_int_g_ctrl(cam->sensor, c);
+ cam->saturation = c->value;
+ } else {
+ pr_err("ERROR: v4l2 capture: slave not found!\n");
+ status = -ENODEV;
+ }
+ break;
+ case V4L2_CID_RED_BALANCE:
+ if (cam->sensor) {
+ c->value = cam->red;
+ status = vidioc_int_g_ctrl(cam->sensor, c);
+ cam->red = c->value;
+ } else {
+ pr_err("ERROR: v4l2 capture: slave not found!\n");
+ status = -ENODEV;
+ }
+ break;
+ case V4L2_CID_BLUE_BALANCE:
+ if (cam->sensor) {
+ c->value = cam->blue;
+ status = vidioc_int_g_ctrl(cam->sensor, c);
+ cam->blue = c->value;
+ } else {
+ pr_err("ERROR: v4l2 capture: slave not found!\n");
+ status = -ENODEV;
+ }
+ break;
+ case V4L2_CID_BLACK_LEVEL:
+ if (cam->sensor) {
+ c->value = cam->ae_mode;
+ status = vidioc_int_g_ctrl(cam->sensor, c);
+ cam->ae_mode = c->value;
+ } else {
+ pr_err("ERROR: v4l2 capture: slave not found!\n");
+ status = -ENODEV;
+ }
+ break;
+ default:
+ pr_err("ERROR: v4l2 capture: unsupported ioctrl!\n");
+ }
+
+ return status;
+}
+
+/*!
+ * V4L2 - set_control function
+ * V4L2_CID_PRIVATE_BASE is the extention for IPU preprocessing.
+ * 0 for normal operation
+ * 1 for vertical flip
+ * 2 for horizontal flip
+ * 3 for horizontal and vertical flip
+ * 4 for 90 degree rotation
+ * @param cam structure cam_data *
+ *
+ * @param c structure v4l2_control *
+ *
+ * @return status 0 success, EINVAL failed
+ */
+static int mxc_v4l2_s_ctrl(cam_data *cam, struct v4l2_control *c)
+{
+ int i, ret = 0;
+ int tmp_rotation = IPU_ROTATE_NONE;
+ struct sensor_data *sensor_data;
+
+ pr_debug("In MVC:mxc_v4l2_s_ctrl\n");
+
+ switch (c->id) {
+ case V4L2_CID_HFLIP:
+ /* This is done by the IPU */
+ if (c->value == 1) {
+ if ((cam->rotation != IPU_ROTATE_VERT_FLIP) &&
+ (cam->rotation != IPU_ROTATE_180))
+ cam->rotation = IPU_ROTATE_HORIZ_FLIP;
+ else
+ cam->rotation = IPU_ROTATE_180;
+ } else {
+ if (cam->rotation == IPU_ROTATE_HORIZ_FLIP)
+ cam->rotation = IPU_ROTATE_NONE;
+ if (cam->rotation == IPU_ROTATE_180)
+ cam->rotation = IPU_ROTATE_VERT_FLIP;
+ }
+ break;
+ case V4L2_CID_VFLIP:
+ /* This is done by the IPU */
+ if (c->value == 1) {
+ if ((cam->rotation != IPU_ROTATE_HORIZ_FLIP) &&
+ (cam->rotation != IPU_ROTATE_180))
+ cam->rotation = IPU_ROTATE_VERT_FLIP;
+ else
+ cam->rotation = IPU_ROTATE_180;
+ } else {
+ if (cam->rotation == IPU_ROTATE_VERT_FLIP)
+ cam->rotation = IPU_ROTATE_NONE;
+ if (cam->rotation == IPU_ROTATE_180)
+ cam->rotation = IPU_ROTATE_HORIZ_FLIP;
+ }
+ break;
+ case V4L2_CID_MXC_ROT:
+ case V4L2_CID_MXC_VF_ROT:
+ /* This is done by the IPU */
+ switch (c->value) {
+ case V4L2_MXC_ROTATE_NONE:
+ tmp_rotation = IPU_ROTATE_NONE;
+ break;
+ case V4L2_MXC_ROTATE_VERT_FLIP:
+ tmp_rotation = IPU_ROTATE_VERT_FLIP;
+ break;
+ case V4L2_MXC_ROTATE_HORIZ_FLIP:
+ tmp_rotation = IPU_ROTATE_HORIZ_FLIP;
+ break;
+ case V4L2_MXC_ROTATE_180:
+ tmp_rotation = IPU_ROTATE_180;
+ break;
+ case V4L2_MXC_ROTATE_90_RIGHT:
+ tmp_rotation = IPU_ROTATE_90_RIGHT;
+ break;
+ case V4L2_MXC_ROTATE_90_RIGHT_VFLIP:
+ tmp_rotation = IPU_ROTATE_90_RIGHT_VFLIP;
+ break;
+ case V4L2_MXC_ROTATE_90_RIGHT_HFLIP:
+ tmp_rotation = IPU_ROTATE_90_RIGHT_HFLIP;
+ break;
+ case V4L2_MXC_ROTATE_90_LEFT:
+ tmp_rotation = IPU_ROTATE_90_LEFT;
+ break;
+ default:
+ ret = -EINVAL;
+ }
+ #ifdef CONFIG_MXC_IPU_PRP_VF_SDC
+ if (c->id == V4L2_CID_MXC_VF_ROT)
+ cam->vf_rotation = tmp_rotation;
+ else
+ cam->rotation = tmp_rotation;
+ #else
+ cam->rotation = tmp_rotation;
+ #endif
+
+ break;
+ case V4L2_CID_HUE:
+ if (cam->sensor) {
+ cam->hue = c->value;
+ ret = vidioc_int_s_ctrl(cam->sensor, c);
+ } else {
+ pr_err("ERROR: v4l2 capture: slave not found!\n");
+ ret = -ENODEV;
+ }
+ break;
+ case V4L2_CID_CONTRAST:
+ if (cam->sensor) {
+ cam->contrast = c->value;
+ ret = vidioc_int_s_ctrl(cam->sensor, c);
+ } else {
+ pr_err("ERROR: v4l2 capture: slave not found!\n");
+ ret = -ENODEV;
+ }
+ break;
+ case V4L2_CID_BRIGHTNESS:
+ if (cam->sensor) {
+ cam->bright = c->value;
+ ret = vidioc_int_s_ctrl(cam->sensor, c);
+ } else {
+ pr_err("ERROR: v4l2 capture: slave not found!\n");
+ ret = -ENODEV;
+ }
+ break;
+ case V4L2_CID_SATURATION:
+ if (cam->sensor) {
+ cam->saturation = c->value;
+ ret = vidioc_int_s_ctrl(cam->sensor, c);
+ } else {
+ pr_err("ERROR: v4l2 capture: slave not found!\n");
+ ret = -ENODEV;
+ }
+ break;
+ case V4L2_CID_RED_BALANCE:
+ if (cam->sensor) {
+ cam->red = c->value;
+ ret = vidioc_int_s_ctrl(cam->sensor, c);
+ } else {
+ pr_err("ERROR: v4l2 capture: slave not found!\n");
+ ret = -ENODEV;
+ }
+ break;
+ case V4L2_CID_BLUE_BALANCE:
+ if (cam->sensor) {
+ cam->blue = c->value;
+ ret = vidioc_int_s_ctrl(cam->sensor, c);
+ } else {
+ pr_err("ERROR: v4l2 capture: slave not found!\n");
+ ret = -ENODEV;
+ }
+ break;
+ case V4L2_CID_EXPOSURE:
+ if (cam->sensor) {
+ cam->ae_mode = c->value;
+ ret = vidioc_int_s_ctrl(cam->sensor, c);
+ } else {
+ pr_err("ERROR: v4l2 capture: slave not found!\n");
+ ret = -ENODEV;
+ }
+ break;
+ case V4L2_CID_MXC_FLASH:
+#ifdef CONFIG_MXC_IPU_V1
+ ipu_csi_flash_strobe(true);
+#endif
+ break;
+ case V4L2_CID_MXC_SWITCH_CAM:
+ if (cam->sensor == cam->all_sensors[c->value])
+ break;
+
+ /* power down other cameraes before enable new one */
+ for (i = 0; i < cam->sensor_index; i++) {
+ if (i != c->value) {
+ vidioc_int_dev_exit(cam->all_sensors[i]);
+ vidioc_int_s_power(cam->all_sensors[i], 0);
+ if (cam->mclk_on[cam->mclk_source]) {
+ ipu_csi_enable_mclk_if(cam->ipu,
+ CSI_MCLK_I2C,
+ cam->mclk_source,
+ false, false);
+ cam->mclk_on[cam->mclk_source] =
+ false;
+ }
+ }
+ }
+ sensor_data = cam->all_sensors[c->value]->priv;
+ if (sensor_data->io_init)
+ sensor_data->io_init();
+ cam->sensor = cam->all_sensors[c->value];
+ cam->mclk_source = sensor_data->mclk_source;
+ ipu_csi_enable_mclk_if(cam->ipu, CSI_MCLK_I2C,
+ cam->mclk_source, true, true);
+ cam->mclk_on[cam->mclk_source] = true;
+ vidioc_int_s_power(cam->sensor, 1);
+ vidioc_int_dev_init(cam->sensor);
+ break;
+ default:
+ pr_debug(" default case\n");
+ ret = -EINVAL;
+ break;
+ }
+
+ return ret;
+}
+
+/*!
+ * V4L2 - mxc_v4l2_s_param function
+ * Allows setting of capturemode and frame rate.
+ *
+ * @param cam structure cam_data *
+ * @param parm structure v4l2_streamparm *
+ *
+ * @return status 0 success, EINVAL failed
+ */
+static int mxc_v4l2_s_param(cam_data *cam, struct v4l2_streamparm *parm)
+{
+ struct v4l2_ifparm ifparm;
+ struct v4l2_format cam_fmt;
+ struct v4l2_streamparm currentparm;
+ ipu_csi_signal_cfg_t csi_param;
+ u32 current_fps, parm_fps;
+ int err = 0;
+
+ pr_debug("In mxc_v4l2_s_param\n");
+
+ if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
+ pr_err(KERN_ERR "mxc_v4l2_s_param invalid type\n");
+ return -EINVAL;
+ }
+
+ /* Stop the viewfinder */
+ if (cam->overlay_on == true)
+ stop_preview(cam);
+
+ currentparm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+
+ /* First check that this device can support the changes requested. */
+ err = vidioc_int_g_parm(cam->sensor, &currentparm);
+ if (err) {
+ pr_err("%s: vidioc_int_g_parm returned an error %d\n",
+ __func__, err);
+ goto exit;
+ }
+
+ current_fps = currentparm.parm.capture.timeperframe.denominator
+ / currentparm.parm.capture.timeperframe.numerator;
+ parm_fps = parm->parm.capture.timeperframe.denominator
+ / parm->parm.capture.timeperframe.numerator;
+
+ pr_debug(" Current capabilities are %x\n",
+ currentparm.parm.capture.capability);
+ pr_debug(" Current capturemode is %d change to %d\n",
+ currentparm.parm.capture.capturemode,
+ parm->parm.capture.capturemode);
+ pr_debug(" Current framerate is %d change to %d\n",
+ current_fps, parm_fps);
+
+ /* This will change any camera settings needed. */
+ err = vidioc_int_s_parm(cam->sensor, parm);
+ if (err) {
+ pr_err("%s: vidioc_int_s_parm returned an error %d\n",
+ __func__, err);
+ goto exit;
+ }
+
+ /* If resolution changed, need to re-program the CSI */
+ /* Get new values. */
+ vidioc_int_g_ifparm(cam->sensor, &ifparm);
+
+ csi_param.data_width = 0;
+ csi_param.clk_mode = 0;
+ csi_param.ext_vsync = 0;
+ csi_param.Vsync_pol = 0;
+ csi_param.Hsync_pol = 0;
+ csi_param.pixclk_pol = 0;
+ csi_param.data_pol = 0;
+ csi_param.sens_clksrc = 0;
+ csi_param.pack_tight = 0;
+ csi_param.force_eof = 0;
+ csi_param.data_en_pol = 0;
+ csi_param.data_fmt = 0;
+ csi_param.csi = cam->csi;
+ csi_param.mclk = 0;
+
+ pr_debug(" clock_curr=mclk=%d\n", ifparm.u.bt656.clock_curr);
+ if (ifparm.u.bt656.clock_curr == 0)
+ csi_param.clk_mode = IPU_CSI_CLK_MODE_CCIR656_INTERLACED;
+ else
+ csi_param.clk_mode = IPU_CSI_CLK_MODE_GATED_CLK;
+
+ csi_param.pixclk_pol = ifparm.u.bt656.latch_clk_inv;
+
+ if (ifparm.u.bt656.mode == V4L2_IF_TYPE_BT656_MODE_NOBT_8BIT) {
+ csi_param.data_width = IPU_CSI_DATA_WIDTH_8;
+ } else if (ifparm.u.bt656.mode
+ == V4L2_IF_TYPE_BT656_MODE_NOBT_10BIT) {
+ csi_param.data_width = IPU_CSI_DATA_WIDTH_10;
+ } else {
+ csi_param.data_width = IPU_CSI_DATA_WIDTH_8;
+ }
+
+ csi_param.Vsync_pol = ifparm.u.bt656.nobt_vs_inv;
+ csi_param.Hsync_pol = ifparm.u.bt656.nobt_hs_inv;
+ csi_param.ext_vsync = ifparm.u.bt656.bt_sync_correct;
+
+ /* if the capturemode changed, the size bounds will have changed. */
+ cam_fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ vidioc_int_g_fmt_cap(cam->sensor, &cam_fmt);
+ pr_debug(" g_fmt_cap returns widthxheight of input as %d x %d\n",
+ cam_fmt.fmt.pix.width, cam_fmt.fmt.pix.height);
+
+ csi_param.data_fmt = cam_fmt.fmt.pix.pixelformat;
+
+ cam->crop_bounds.top = cam->crop_bounds.left = 0;
+ cam->crop_bounds.width = cam_fmt.fmt.pix.width;
+ cam->crop_bounds.height = cam_fmt.fmt.pix.height;
+
+ /*
+ * Set the default current cropped resolution to be the same with
+ * the cropping boundary(except for tvin module).
+ */
+ if (cam->device_type != 1) {
+ cam->crop_current.width = cam->crop_bounds.width;
+ cam->crop_current.height = cam->crop_bounds.height;
+ }
+
+ /* This essentially loses the data at the left and bottom of the image
+ * giving a digital zoom image, if crop_current is less than the full
+ * size of the image. */
+ ipu_csi_set_window_size(cam->ipu, cam->crop_current.width,
+ cam->crop_current.height, cam->csi);
+ ipu_csi_set_window_pos(cam->ipu, cam->crop_current.left,
+ cam->crop_current.top,
+ cam->csi);
+ ipu_csi_init_interface(cam->ipu, cam->crop_bounds.width,
+ cam->crop_bounds.height,
+ cam_fmt.fmt.pix.pixelformat, csi_param);
+
+
+exit:
+ if (cam->overlay_on == true)
+ start_preview(cam);
+
+ return err;
+}
+
+/*!
+ * V4L2 - mxc_v4l2_s_std function
+ *
+ * Sets the TV standard to be used.
+ *
+ * @param cam structure cam_data *
+ * @param parm structure v4l2_streamparm *
+ *
+ * @return status 0 success, EINVAL failed
+ */
+static int mxc_v4l2_s_std(cam_data *cam, v4l2_std_id e)
+{
+ pr_debug("In mxc_v4l2_s_std %Lx\n", e);
+
+ if (e == V4L2_STD_PAL) {
+ pr_debug(" Setting standard to PAL %Lx\n", V4L2_STD_PAL);
+ cam->standard.id = V4L2_STD_PAL;
+ video_index = TV_PAL;
+ } else if (e == V4L2_STD_NTSC) {
+ pr_debug(" Setting standard to NTSC %Lx\n",
+ V4L2_STD_NTSC);
+ /* Get rid of the white dot line in NTSC signal input */
+ cam->standard.id = V4L2_STD_NTSC;
+ video_index = TV_NTSC;
+ } else {
+ cam->standard.id = V4L2_STD_ALL;
+ video_index = TV_NOT_LOCKED;
+ pr_err("ERROR: unrecognized std! %Lx (PAL=%Lx, NTSC=%Lx\n",
+ e, V4L2_STD_PAL, V4L2_STD_NTSC);
+ }
+
+ cam->standard.index = video_index;
+ strcpy(cam->standard.name, video_fmts[video_index].name);
+ cam->crop_bounds.width = video_fmts[video_index].raw_width;
+ cam->crop_bounds.height = video_fmts[video_index].raw_height;
+ cam->crop_current.width = video_fmts[video_index].active_width;
+ cam->crop_current.height = video_fmts[video_index].active_height;
+ cam->crop_current.top = video_fmts[video_index].active_top;
+ cam->crop_current.left = video_fmts[video_index].active_left;
+
+ return 0;
+}
+
+/*!
+ * V4L2 - mxc_v4l2_g_std function
+ *
+ * Gets the TV standard from the TV input device.
+ *
+ * @param cam structure cam_data *
+ *
+ * @param e structure v4l2_streamparm *
+ *
+ * @return status 0 success, EINVAL failed
+ */
+static int mxc_v4l2_g_std(cam_data *cam, v4l2_std_id *e)
+{
+ struct v4l2_format tv_fmt;
+
+ pr_debug("In mxc_v4l2_g_std\n");
+
+ if (cam->device_type == 1) {
+ /* Use this function to get what the TV-In device detects the
+ * format to be. pixelformat is used to return the std value
+ * since the interface has no vidioc_g_std.*/
+ tv_fmt.type = V4L2_BUF_TYPE_PRIVATE;
+ vidioc_int_g_fmt_cap(cam->sensor, &tv_fmt);
+
+ /* If the TV-in automatically detects the standard, then if it
+ * changes, the settings need to change. */
+ if (cam->standard_autodetect) {
+ if (cam->standard.id != tv_fmt.fmt.pix.pixelformat) {
+ pr_debug("MVC: mxc_v4l2_g_std: "
+ "Changing standard\n");
+ mxc_v4l2_s_std(cam, tv_fmt.fmt.pix.pixelformat);
+ }
+ }
+
+ *e = tv_fmt.fmt.pix.pixelformat;
+ }
+
+ return 0;
+}
+
+/*!
+ * Dequeue one V4L capture buffer
+ *
+ * @param cam structure cam_data *
+ * @param buf structure v4l2_buffer *
+ *
+ * @return status 0 success, EINVAL invalid frame number,
+ * ETIME timeout, ERESTARTSYS interrupted by user
+ */
+static int mxc_v4l_dqueue(cam_data *cam, struct v4l2_buffer *buf)
+{
+ int retval = 0;
+ struct mxc_v4l_frame *frame;
+ unsigned long lock_flags;
+
+ pr_debug("In MVC:mxc_v4l_dqueue\n");
+
+ if (!wait_event_interruptible_timeout(cam->enc_queue,
+ cam->enc_counter != 0,
+ 10 * HZ)) {
+ pr_err("ERROR: v4l2 capture: mxc_v4l_dqueue timeout "
+ "enc_counter %x\n",
+ cam->enc_counter);
+ return -ETIME;
+ } else if (signal_pending(current)) {
+ pr_err("ERROR: v4l2 capture: mxc_v4l_dqueue() "
+ "interrupt received\n");
+ return -ERESTARTSYS;
+ }
+
+ if (down_interruptible(&cam->busy_lock))
+ return -EBUSY;
+
+ spin_lock_irqsave(&cam->dqueue_int_lock, lock_flags);
+ cam->enc_counter--;
+
+ frame = list_entry(cam->done_q.next, struct mxc_v4l_frame, queue);
+ list_del(cam->done_q.next);
+ if (frame->buffer.flags & V4L2_BUF_FLAG_DONE) {
+ frame->buffer.flags &= ~V4L2_BUF_FLAG_DONE;
+ } else if (frame->buffer.flags & V4L2_BUF_FLAG_QUEUED) {
+ pr_err("ERROR: v4l2 capture: VIDIOC_DQBUF: "
+ "Buffer not filled.\n");
+ frame->buffer.flags &= ~V4L2_BUF_FLAG_QUEUED;
+ retval = -EINVAL;
+ } else if ((frame->buffer.flags & 0x7) == V4L2_BUF_FLAG_MAPPED) {
+ pr_err("ERROR: v4l2 capture: VIDIOC_DQBUF: "
+ "Buffer not queued.\n");
+ retval = -EINVAL;
+ }
+
+ cam->frame[frame->index].buffer.field = cam->device_type ?
+ V4L2_FIELD_INTERLACED : V4L2_FIELD_NONE;
+
+ buf->bytesused = cam->v2f.fmt.pix.sizeimage;
+ buf->index = frame->index;
+ buf->flags = frame->buffer.flags;
+ buf->m = cam->frame[frame->index].buffer.m;
+ buf->timestamp = cam->frame[frame->index].buffer.timestamp;
+ buf->field = cam->frame[frame->index].buffer.field;
+ spin_unlock_irqrestore(&cam->dqueue_int_lock, lock_flags);
+
+ up(&cam->busy_lock);
+ return retval;
+}
+
+/*!
+ * V4L interface - open function
+ *
+ * @param file structure file *
+ *
+ * @return status 0 success, ENODEV invalid device instance,
+ * ENODEV timeout, ERESTARTSYS interrupted by user
+ */
+static int mxc_v4l_open(struct file *file)
+{
+ struct v4l2_ifparm ifparm;
+ struct v4l2_format cam_fmt;
+ ipu_csi_signal_cfg_t csi_param;
+ struct video_device *dev = video_devdata(file);
+ cam_data *cam = video_get_drvdata(dev);
+ int err = 0;
+ struct sensor_data *sensor;
+
+ pr_debug("\nIn MVC: mxc_v4l_open\n");
+ pr_debug(" device name is %s\n", dev->name);
+
+ if (!cam) {
+ pr_err("ERROR: v4l2 capture: Internal error, "
+ "cam_data not found!\n");
+ return -EBADF;
+ }
+
+ if (cam->sensor == NULL ||
+ cam->sensor->type != v4l2_int_type_slave) {
+ pr_err("ERROR: v4l2 capture: slave not found!\n");
+ return -EAGAIN;
+ }
+
+ sensor = cam->sensor->priv;
+ if (!sensor) {
+ pr_err("%s: Internal error, sensor_data is not found!\n",
+ __func__);
+ return -EBADF;
+ }
+
+ down(&cam->busy_lock);
+ err = 0;
+ if (signal_pending(current))
+ goto oops;
+
+ if (cam->open_count++ == 0) {
+ wait_event_interruptible(cam->power_queue,
+ cam->low_power == false);
+
+ if (strcmp(mxc_capture_inputs[cam->current_input].name,
+ "CSI MEM") == 0) {
+#if defined(CONFIG_MXC_IPU_CSI_ENC) || defined(CONFIG_MXC_IPU_CSI_ENC_MODULE)
+ err = csi_enc_select(cam);
+#endif
+ } else if (strcmp(mxc_capture_inputs[cam->current_input].name,
+ "CSI IC MEM") == 0) {
+#if defined(CONFIG_MXC_IPU_PRP_ENC) || defined(CONFIG_MXC_IPU_PRP_ENC_MODULE)
+ err = prp_enc_select(cam);
+#endif
+ }
+
+ cam->enc_counter = 0;
+ INIT_LIST_HEAD(&cam->ready_q);
+ INIT_LIST_HEAD(&cam->working_q);
+ INIT_LIST_HEAD(&cam->done_q);
+
+ vidioc_int_g_ifparm(cam->sensor, &ifparm);
+
+ csi_param.sens_clksrc = 0;
+
+ csi_param.clk_mode = 0;
+ csi_param.data_pol = 0;
+ csi_param.ext_vsync = 0;
+
+ csi_param.pack_tight = 0;
+ csi_param.force_eof = 0;
+ csi_param.data_en_pol = 0;
+
+ csi_param.mclk = ifparm.u.bt656.clock_curr;
+
+ csi_param.pixclk_pol = ifparm.u.bt656.latch_clk_inv;
+
+ if (ifparm.u.bt656.mode
+ == V4L2_IF_TYPE_BT656_MODE_NOBT_8BIT)
+ csi_param.data_width = IPU_CSI_DATA_WIDTH_8;
+ else if (ifparm.u.bt656.mode
+ == V4L2_IF_TYPE_BT656_MODE_NOBT_10BIT)
+ csi_param.data_width = IPU_CSI_DATA_WIDTH_10;
+ else
+ csi_param.data_width = IPU_CSI_DATA_WIDTH_8;
+
+
+ csi_param.Vsync_pol = ifparm.u.bt656.nobt_vs_inv;
+ csi_param.Hsync_pol = ifparm.u.bt656.nobt_hs_inv;
+
+ csi_param.csi = cam->csi;
+
+ cam_fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ vidioc_int_g_fmt_cap(cam->sensor, &cam_fmt);
+
+ /* Reset the sizes. Needed to prevent carryover of last
+ * operation.*/
+ cam->crop_bounds.top = cam->crop_bounds.left = 0;
+ cam->crop_bounds.width = cam_fmt.fmt.pix.width;
+ cam->crop_bounds.height = cam_fmt.fmt.pix.height;
+
+ /* This also is the max crop size for this device. */
+ cam->crop_defrect.top = cam->crop_defrect.left = 0;
+ cam->crop_defrect.width = cam_fmt.fmt.pix.width;
+ cam->crop_defrect.height = cam_fmt.fmt.pix.height;
+
+ /* At this point, this is also the current image size. */
+ cam->crop_current.top = cam->crop_current.left = 0;
+ cam->crop_current.width = cam_fmt.fmt.pix.width;
+ cam->crop_current.height = cam_fmt.fmt.pix.height;
+
+ pr_debug("End of %s: v2f pix widthxheight %d x %d\n",
+ __func__,
+ cam->v2f.fmt.pix.width, cam->v2f.fmt.pix.height);
+ pr_debug("End of %s: crop_bounds widthxheight %d x %d\n",
+ __func__,
+ cam->crop_bounds.width, cam->crop_bounds.height);
+ pr_debug("End of %s: crop_defrect widthxheight %d x %d\n",
+ __func__,
+ cam->crop_defrect.width, cam->crop_defrect.height);
+ pr_debug("End of %s: crop_current widthxheight %d x %d\n",
+ __func__,
+ cam->crop_current.width, cam->crop_current.height);
+
+ csi_param.data_fmt = cam_fmt.fmt.pix.pixelformat;
+ pr_debug("On Open: Input to ipu size is %d x %d\n",
+ cam_fmt.fmt.pix.width, cam_fmt.fmt.pix.height);
+ ipu_csi_set_window_size(cam->ipu, cam->crop_current.width,
+ cam->crop_current.height,
+ cam->csi);
+ ipu_csi_set_window_pos(cam->ipu, cam->crop_current.left,
+ cam->crop_current.top,
+ cam->csi);
+ ipu_csi_init_interface(cam->ipu, cam->crop_bounds.width,
+ cam->crop_bounds.height,
+ cam_fmt.fmt.pix.pixelformat,
+ csi_param);
+ clk_prepare_enable(sensor->sensor_clk);
+ vidioc_int_s_power(cam->sensor, 1);
+ vidioc_int_init(cam->sensor);
+ vidioc_int_dev_init(cam->sensor);
+ }
+
+ file->private_data = dev;
+
+oops:
+ up(&cam->busy_lock);
+ return err;
+}
+
+/*!
+ * V4L interface - close function
+ *
+ * @param file struct file *
+ *
+ * @return 0 success
+ */
+static int mxc_v4l_close(struct file *file)
+{
+ struct video_device *dev = video_devdata(file);
+ int err = 0;
+ cam_data *cam = video_get_drvdata(dev);
+ struct sensor_data *sensor;
+ pr_debug("In MVC:mxc_v4l_close\n");
+
+ if (!cam) {
+ pr_err("ERROR: v4l2 capture: Internal error, "
+ "cam_data not found!\n");
+ return -EBADF;
+ }
+
+ if (!cam->sensor) {
+ pr_err("%s: Internal error, camera is not found!\n",
+ __func__);
+ return -EBADF;
+ }
+
+ sensor = cam->sensor->priv;
+ if (!sensor) {
+ pr_err("%s: Internal error, sensor_data is not found!\n",
+ __func__);
+ return -EBADF;
+ }
+
+ down(&cam->busy_lock);
+
+ /* for the case somebody hit the ctrl C */
+ if (cam->overlay_pid == current->pid && cam->overlay_on) {
+ err = stop_preview(cam);
+ cam->overlay_on = false;
+ }
+ if (cam->capture_pid == current->pid) {
+ err |= mxc_streamoff(cam);
+ wake_up_interruptible(&cam->enc_queue);
+ }
+
+ if (--cam->open_count == 0) {
+ vidioc_int_s_power(cam->sensor, 0);
+ clk_disable_unprepare(sensor->sensor_clk);
+ wait_event_interruptible(cam->power_queue,
+ cam->low_power == false);
+ pr_debug("mxc_v4l_close: release resource\n");
+
+ if (strcmp(mxc_capture_inputs[cam->current_input].name,
+ "CSI MEM") == 0) {
+#if defined(CONFIG_MXC_IPU_CSI_ENC) || defined(CONFIG_MXC_IPU_CSI_ENC_MODULE)
+ err |= csi_enc_deselect(cam);
+#endif
+ } else if (strcmp(mxc_capture_inputs[cam->current_input].name,
+ "CSI IC MEM") == 0) {
+#if defined(CONFIG_MXC_IPU_PRP_ENC) || defined(CONFIG_MXC_IPU_PRP_ENC_MODULE)
+ err |= prp_enc_deselect(cam);
+#endif
+ }
+
+ mxc_free_frame_buf(cam);
+ file->private_data = NULL;
+
+ /* capture off */
+ wake_up_interruptible(&cam->enc_queue);
+ mxc_free_frames(cam);
+ cam->enc_counter++;
+ }
+
+ up(&cam->busy_lock);
+
+ return err;
+}
+
+#if defined(CONFIG_MXC_IPU_PRP_ENC) || defined(CONFIG_MXC_IPU_CSI_ENC) || \
+ defined(CONFIG_MXC_IPU_PRP_ENC_MODULE) || \
+ defined(CONFIG_MXC_IPU_CSI_ENC_MODULE)
+/*
+ * V4L interface - read function
+ *
+ * @param file struct file *
+ * @param read buf char *
+ * @param count size_t
+ * @param ppos structure loff_t *
+ *
+ * @return bytes read
+ */
+static ssize_t mxc_v4l_read(struct file *file, char *buf, size_t count,
+ loff_t *ppos)
+{
+ int err = 0;
+ u8 *v_address[2];
+ struct video_device *dev = video_devdata(file);
+ cam_data *cam = video_get_drvdata(dev);
+
+ if (down_interruptible(&cam->busy_lock))
+ return -EINTR;
+
+ /* Stop the viewfinder */
+ if (cam->overlay_on == true)
+ stop_preview(cam);
+
+ v_address[0] = dma_alloc_coherent(0,
+ PAGE_ALIGN(cam->v2f.fmt.pix.sizeimage),
+ &cam->still_buf[0],
+ GFP_DMA | GFP_KERNEL);
+
+ v_address[1] = dma_alloc_coherent(0,
+ PAGE_ALIGN(cam->v2f.fmt.pix.sizeimage),
+ &cam->still_buf[1],
+ GFP_DMA | GFP_KERNEL);
+
+ if (!v_address[0] || !v_address[1]) {
+ err = -ENOBUFS;
+ goto exit0;
+ }
+
+ err = prp_still_select(cam);
+ if (err != 0) {
+ err = -EIO;
+ goto exit0;
+ }
+
+ cam->still_counter = 0;
+ err = cam->csi_start(cam);
+ if (err != 0) {
+ err = -EIO;
+ goto exit1;
+ }
+
+ if (!wait_event_interruptible_timeout(cam->still_queue,
+ cam->still_counter != 0,
+ 10 * HZ)) {
+ pr_err("ERROR: v4l2 capture: mxc_v4l_read timeout counter %x\n",
+ cam->still_counter);
+ err = -ETIME;
+ goto exit1;
+ }
+ err = copy_to_user(buf, v_address[1], cam->v2f.fmt.pix.sizeimage);
+
+exit1:
+ prp_still_deselect(cam);
+
+exit0:
+ if (v_address[0] != 0)
+ dma_free_coherent(0, cam->v2f.fmt.pix.sizeimage, v_address[0],
+ cam->still_buf[0]);
+ if (v_address[1] != 0)
+ dma_free_coherent(0, cam->v2f.fmt.pix.sizeimage, v_address[1],
+ cam->still_buf[1]);
+
+ cam->still_buf[0] = cam->still_buf[1] = 0;
+
+ if (cam->overlay_on == true)
+ start_preview(cam);
+
+ up(&cam->busy_lock);
+ if (err < 0)
+ return err;
+
+ return cam->v2f.fmt.pix.sizeimage - err;
+}
+#endif
+
+/*!
+ * V4L interface - ioctl function
+ *
+ * @param file struct file*
+ *
+ * @param ioctlnr unsigned int
+ *
+ * @param arg void*
+ *
+ * @return 0 success, ENODEV for invalid device instance,
+ * -1 for other errors.
+ */
+static long mxc_v4l_do_ioctl(struct file *file,
+ unsigned int ioctlnr, void *arg)
+{
+ struct video_device *dev = video_devdata(file);
+ cam_data *cam = video_get_drvdata(dev);
+ int retval = 0;
+ unsigned long lock_flags;
+
+ pr_debug("In MVC: mxc_v4l_do_ioctl %x\n", ioctlnr);
+ wait_event_interruptible(cam->power_queue, cam->low_power == false);
+ /* make this _really_ smp-safe */
+ if (ioctlnr != VIDIOC_DQBUF)
+ if (down_interruptible(&cam->busy_lock))
+ return -EBUSY;
+
+ switch (ioctlnr) {
+ /*!
+ * V4l2 VIDIOC_QUERYCAP ioctl
+ */
+ case VIDIOC_QUERYCAP: {
+ struct v4l2_capability *cap = arg;
+ pr_debug(" case VIDIOC_QUERYCAP\n");
+ strcpy(cap->driver, "mxc_v4l2");
+ cap->version = KERNEL_VERSION(0, 1, 11);
+ cap->capabilities = V4L2_CAP_VIDEO_CAPTURE |
+ V4L2_CAP_VIDEO_OVERLAY |
+ V4L2_CAP_STREAMING |
+ V4L2_CAP_READWRITE;
+ cap->card[0] = '\0';
+ cap->bus_info[0] = '\0';
+ break;
+ }
+
+ /*!
+ * V4l2 VIDIOC_G_FMT ioctl
+ */
+ case VIDIOC_G_FMT: {
+ struct v4l2_format *gf = arg;
+ pr_debug(" case VIDIOC_G_FMT\n");
+ retval = mxc_v4l2_g_fmt(cam, gf);
+ break;
+ }
+
+ /*!
+ * V4l2 VIDIOC_S_DEST_CROP ioctl
+ */
+ case VIDIOC_S_DEST_CROP: {
+ struct v4l2_mxc_dest_crop *of = arg;
+ pr_debug(" case VIDIOC_S_DEST_CROP\n");
+ cam->offset.u_offset = of->offset.u_offset;
+ cam->offset.v_offset = of->offset.v_offset;
+ break;
+ }
+
+ /*!
+ * V4l2 VIDIOC_S_FMT ioctl
+ */
+ case VIDIOC_S_FMT: {
+ struct v4l2_format *sf = arg;
+ pr_debug(" case VIDIOC_S_FMT\n");
+ retval = mxc_v4l2_s_fmt(cam, sf);
+ break;
+ }
+
+ /*!
+ * V4l2 VIDIOC_REQBUFS ioctl
+ */
+ case VIDIOC_REQBUFS: {
+ struct v4l2_requestbuffers *req = arg;
+ pr_debug(" case VIDIOC_REQBUFS\n");
+
+ if (req->count > FRAME_NUM) {
+ pr_err("ERROR: v4l2 capture: VIDIOC_REQBUFS: "
+ "not enough buffers\n");
+ req->count = FRAME_NUM;
+ }
+
+ if ((req->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)) {
+ pr_err("ERROR: v4l2 capture: VIDIOC_REQBUFS: "
+ "wrong buffer type\n");
+ retval = -EINVAL;
+ break;
+ }
+
+ mxc_streamoff(cam);
+ if (req->memory & V4L2_MEMORY_MMAP) {
+ mxc_free_frame_buf(cam);
+ retval = mxc_allocate_frame_buf(cam, req->count);
+ }
+ break;
+ }
+
+ /*!
+ * V4l2 VIDIOC_QUERYBUF ioctl
+ */
+ case VIDIOC_QUERYBUF: {
+ struct v4l2_buffer *buf = arg;
+ int index = buf->index;
+ pr_debug(" case VIDIOC_QUERYBUF\n");
+
+ if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
+ pr_err("ERROR: v4l2 capture: "
+ "VIDIOC_QUERYBUFS: "
+ "wrong buffer type\n");
+ retval = -EINVAL;
+ break;
+ }
+
+ if (buf->memory & V4L2_MEMORY_MMAP) {
+ memset(buf, 0, sizeof(buf));
+ buf->index = index;
+ }
+
+ down(&cam->param_lock);
+ if (buf->memory & V4L2_MEMORY_USERPTR) {
+ mxc_v4l2_release_bufs(cam);
+ retval = mxc_v4l2_prepare_bufs(cam, buf);
+ }
+
+ if (buf->memory & V4L2_MEMORY_MMAP)
+ retval = mxc_v4l2_buffer_status(cam, buf);
+ up(&cam->param_lock);
+ break;
+ }
+
+ /*!
+ * V4l2 VIDIOC_QBUF ioctl
+ */
+ case VIDIOC_QBUF: {
+ struct v4l2_buffer *buf = arg;
+ int index = buf->index;
+ pr_debug(" case VIDIOC_QBUF\n");
+
+ spin_lock_irqsave(&cam->queue_int_lock, lock_flags);
+ if ((cam->frame[index].buffer.flags & 0x7) ==
+ V4L2_BUF_FLAG_MAPPED) {
+ cam->frame[index].buffer.flags |=
+ V4L2_BUF_FLAG_QUEUED;
+ list_add_tail(&cam->frame[index].queue,
+ &cam->ready_q);
+ } else if (cam->frame[index].buffer.
+ flags & V4L2_BUF_FLAG_QUEUED) {
+ pr_err("ERROR: v4l2 capture: VIDIOC_QBUF: "
+ "buffer already queued\n");
+ retval = -EINVAL;
+ } else if (cam->frame[index].buffer.
+ flags & V4L2_BUF_FLAG_DONE) {
+ pr_err("ERROR: v4l2 capture: VIDIOC_QBUF: "
+ "overwrite done buffer.\n");
+ cam->frame[index].buffer.flags &=
+ ~V4L2_BUF_FLAG_DONE;
+ cam->frame[index].buffer.flags |=
+ V4L2_BUF_FLAG_QUEUED;
+ retval = -EINVAL;
+ }
+
+ buf->flags = cam->frame[index].buffer.flags;
+ spin_unlock_irqrestore(&cam->queue_int_lock, lock_flags);
+ break;
+ }
+
+ /*!
+ * V4l2 VIDIOC_DQBUF ioctl
+ */
+ case VIDIOC_DQBUF: {
+ struct v4l2_buffer *buf = arg;
+ pr_debug(" case VIDIOC_DQBUF\n");
+
+ if ((cam->enc_counter == 0) &&
+ (file->f_flags & O_NONBLOCK)) {
+ retval = -EAGAIN;
+ break;
+ }
+
+ retval = mxc_v4l_dqueue(cam, buf);
+ break;
+ }
+
+ /*!
+ * V4l2 VIDIOC_STREAMON ioctl
+ */
+ case VIDIOC_STREAMON: {
+ pr_debug(" case VIDIOC_STREAMON\n");
+ retval = mxc_streamon(cam);
+ break;
+ }
+
+ /*!
+ * V4l2 VIDIOC_STREAMOFF ioctl
+ */
+ case VIDIOC_STREAMOFF: {
+ pr_debug(" case VIDIOC_STREAMOFF\n");
+ retval = mxc_streamoff(cam);
+ break;
+ }
+
+ /*!
+ * V4l2 VIDIOC_G_CTRL ioctl
+ */
+ case VIDIOC_G_CTRL: {
+ pr_debug(" case VIDIOC_G_CTRL\n");
+ retval = mxc_v4l2_g_ctrl(cam, arg);
+ break;
+ }
+
+ /*!
+ * V4l2 VIDIOC_S_CTRL ioctl
+ */
+ case VIDIOC_S_CTRL: {
+ pr_debug(" case VIDIOC_S_CTRL\n");
+ retval = mxc_v4l2_s_ctrl(cam, arg);
+ break;
+ }
+
+ /*!
+ * V4l2 VIDIOC_CROPCAP ioctl
+ */
+ case VIDIOC_CROPCAP: {
+ struct v4l2_cropcap *cap = arg;
+ pr_debug(" case VIDIOC_CROPCAP\n");
+ if (cap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
+ cap->type != V4L2_BUF_TYPE_VIDEO_OVERLAY) {
+ retval = -EINVAL;
+ break;
+ }
+ cap->bounds = cam->crop_bounds;
+ cap->defrect = cam->crop_defrect;
+ break;
+ }
+
+ /*!
+ * V4l2 VIDIOC_G_CROP ioctl
+ */
+ case VIDIOC_G_CROP: {
+ struct v4l2_crop *crop = arg;
+ pr_debug(" case VIDIOC_G_CROP\n");
+
+ if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
+ crop->type != V4L2_BUF_TYPE_VIDEO_OVERLAY) {
+ retval = -EINVAL;
+ break;
+ }
+ crop->c = cam->crop_current;
+ break;
+ }
+
+ /*!
+ * V4l2 VIDIOC_S_CROP ioctl
+ */
+ case VIDIOC_S_CROP: {
+ struct v4l2_crop *crop = arg;
+ struct v4l2_rect *b = &cam->crop_bounds;
+ pr_debug(" case VIDIOC_S_CROP\n");
+
+ if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
+ crop->type != V4L2_BUF_TYPE_VIDEO_OVERLAY) {
+ retval = -EINVAL;
+ break;
+ }
+
+ crop->c.top = (crop->c.top < b->top) ? b->top
+ : crop->c.top;
+ if (crop->c.top > b->top + b->height)
+ crop->c.top = b->top + b->height - 1;
+ if (crop->c.height > b->top + b->height - crop->c.top)
+ crop->c.height =
+ b->top + b->height - crop->c.top;
+
+ crop->c.left = (crop->c.left < b->left) ? b->left
+ : crop->c.left;
+ if (crop->c.left > b->left + b->width)
+ crop->c.left = b->left + b->width - 1;
+ if (crop->c.width > b->left - crop->c.left + b->width)
+ crop->c.width =
+ b->left - crop->c.left + b->width;
+
+ crop->c.width -= crop->c.width % 8;
+ crop->c.left -= crop->c.left % 4;
+ cam->crop_current = crop->c;
+
+ pr_debug(" Cropping Input to ipu size %d x %d\n",
+ cam->crop_current.width,
+ cam->crop_current.height);
+ ipu_csi_set_window_size(cam->ipu, cam->crop_current.width,
+ cam->crop_current.height,
+ cam->csi);
+ ipu_csi_set_window_pos(cam->ipu, cam->crop_current.left,
+ cam->crop_current.top,
+ cam->csi);
+ break;
+ }
+
+ /*!
+ * V4l2 VIDIOC_OVERLAY ioctl
+ */
+ case VIDIOC_OVERLAY: {
+ int *on = arg;
+ pr_debug(" VIDIOC_OVERLAY on=%d\n", *on);
+ if (*on) {
+ cam->overlay_on = true;
+ cam->overlay_pid = current->pid;
+ retval = start_preview(cam);
+ }
+ if (!*on) {
+ retval = stop_preview(cam);
+ cam->overlay_on = false;
+ }
+ break;
+ }
+
+ /*!
+ * V4l2 VIDIOC_G_FBUF ioctl
+ */
+ case VIDIOC_G_FBUF: {
+ struct v4l2_framebuffer *fb = arg;
+ pr_debug(" case VIDIOC_G_FBUF\n");
+ *fb = cam->v4l2_fb;
+ fb->capability = V4L2_FBUF_CAP_EXTERNOVERLAY;
+ break;
+ }
+
+ /*!
+ * V4l2 VIDIOC_S_FBUF ioctl
+ */
+ case VIDIOC_S_FBUF: {
+ struct v4l2_framebuffer *fb = arg;
+ pr_debug(" case VIDIOC_S_FBUF\n");
+ cam->v4l2_fb = *fb;
+ break;
+ }
+
+ case VIDIOC_G_PARM: {
+ struct v4l2_streamparm *parm = arg;
+ pr_debug(" case VIDIOC_G_PARM\n");
+ if (cam->sensor)
+ retval = vidioc_int_g_parm(cam->sensor, parm);
+ else {
+ pr_err("ERROR: v4l2 capture: slave not found!\n");
+ retval = -ENODEV;
+ }
+ break;
+ }
+
+ case VIDIOC_S_PARM: {
+ struct v4l2_streamparm *parm = arg;
+ pr_debug(" case VIDIOC_S_PARM\n");
+ if (cam->sensor)
+ retval = mxc_v4l2_s_param(cam, parm);
+ else {
+ pr_err("ERROR: v4l2 capture: slave not found!\n");
+ retval = -ENODEV;
+ }
+ break;
+ }
+
+ /* linux v4l2 bug, kernel c0485619 user c0405619 */
+ case VIDIOC_ENUMSTD: {
+ struct v4l2_standard *e = arg;
+ pr_debug(" case VIDIOC_ENUMSTD\n");
+ *e = cam->standard;
+ break;
+ }
+
+ case VIDIOC_G_STD: {
+ v4l2_std_id *e = arg;
+ pr_debug(" case VIDIOC_G_STD\n");
+ if (cam->sensor)
+ retval = mxc_v4l2_g_std(cam, e);
+ else {
+ pr_err("ERROR: v4l2 capture: slave not found!\n");
+ retval = -ENODEV;
+ }
+ break;
+ }
+
+ case VIDIOC_S_STD: {
+ v4l2_std_id *e = arg;
+ pr_debug(" case VIDIOC_S_STD\n");
+ retval = mxc_v4l2_s_std(cam, *e);
+
+ break;
+ }
+
+ case VIDIOC_ENUMOUTPUT: {
+ struct v4l2_output *output = arg;
+ pr_debug(" case VIDIOC_ENUMOUTPUT\n");
+ if (output->index >= MXC_V4L2_CAPTURE_NUM_OUTPUTS) {
+ retval = -EINVAL;
+ break;
+ }
+ *output = mxc_capture_outputs[output->index];
+
+ break;
+ }
+ case VIDIOC_G_OUTPUT: {
+ int *p_output_num = arg;
+ pr_debug(" case VIDIOC_G_OUTPUT\n");
+ *p_output_num = cam->output;
+ break;
+ }
+
+ case VIDIOC_S_OUTPUT: {
+ int *p_output_num = arg;
+ pr_debug(" case VIDIOC_S_OUTPUT\n");
+ if (*p_output_num >= MXC_V4L2_CAPTURE_NUM_OUTPUTS) {
+ retval = -EINVAL;
+ break;
+ }
+ cam->output = *p_output_num;
+ break;
+ }
+
+ case VIDIOC_ENUMINPUT: {
+ struct v4l2_input *input = arg;
+ pr_debug(" case VIDIOC_ENUMINPUT\n");
+ if (input->index >= MXC_V4L2_CAPTURE_NUM_INPUTS) {
+ retval = -EINVAL;
+ break;
+ }
+ *input = mxc_capture_inputs[input->index];
+ break;
+ }
+
+ case VIDIOC_G_INPUT: {
+ int *index = arg;
+ pr_debug(" case VIDIOC_G_INPUT\n");
+ *index = cam->current_input;
+ break;
+ }
+
+ case VIDIOC_S_INPUT: {
+ int *index = arg;
+ pr_debug(" case VIDIOC_S_INPUT\n");
+ if (*index >= MXC_V4L2_CAPTURE_NUM_INPUTS) {
+ retval = -EINVAL;
+ break;
+ }
+
+ if (*index == cam->current_input)
+ break;
+
+ if ((mxc_capture_inputs[cam->current_input].status &
+ V4L2_IN_ST_NO_POWER) == 0) {
+ retval = mxc_streamoff(cam);
+ if (retval)
+ break;
+ mxc_capture_inputs[cam->current_input].status |=
+ V4L2_IN_ST_NO_POWER;
+ }
+
+ if (strcmp(mxc_capture_inputs[*index].name, "CSI MEM") == 0) {
+#if defined(CONFIG_MXC_IPU_CSI_ENC) || defined(CONFIG_MXC_IPU_CSI_ENC_MODULE)
+ retval = csi_enc_select(cam);
+ if (retval)
+ break;
+#endif
+ } else if (strcmp(mxc_capture_inputs[*index].name,
+ "CSI IC MEM") == 0) {
+#if defined(CONFIG_MXC_IPU_PRP_ENC) || defined(CONFIG_MXC_IPU_PRP_ENC_MODULE)
+ retval = prp_enc_select(cam);
+ if (retval)
+ break;
+#endif
+ }
+
+ mxc_capture_inputs[*index].status &= ~V4L2_IN_ST_NO_POWER;
+ cam->current_input = *index;
+ break;
+ }
+ case VIDIOC_ENUM_FMT: {
+ struct v4l2_fmtdesc *f = arg;
+ if (cam->sensor)
+ retval = vidioc_int_enum_fmt_cap(cam->sensor, f);
+ else {
+ pr_err("ERROR: v4l2 capture: slave not found!\n");
+ retval = -ENODEV;
+ }
+ break;
+ }
+ case VIDIOC_ENUM_FRAMESIZES: {
+ struct v4l2_frmsizeenum *fsize = arg;
+ if (cam->sensor)
+ retval = vidioc_int_enum_framesizes(cam->sensor, fsize);
+ else {
+ pr_err("ERROR: v4l2 capture: slave not found!\n");
+ retval = -ENODEV;
+ }
+ break;
+ }
+ case VIDIOC_ENUM_FRAMEINTERVALS: {
+ struct v4l2_frmivalenum *fival = arg;
+ if (cam->sensor) {
+ retval = vidioc_int_enum_frameintervals(cam->sensor,
+ fival);
+ } else {
+ pr_err("ERROR: v4l2 capture: slave not found!\n");
+ retval = -ENODEV;
+ }
+ break;
+ }
+ case VIDIOC_DBG_G_CHIP_IDENT: {
+ struct v4l2_dbg_chip_ident *p = arg;
+ p->ident = V4L2_IDENT_NONE;
+ p->revision = 0;
+ if (cam->sensor)
+ retval = vidioc_int_g_chip_ident(cam->sensor, (int *)p);
+ else {
+ pr_err("ERROR: v4l2 capture: slave not found!\n");
+ retval = -ENODEV;
+ }
+ break;
+ }
+ case VIDIOC_TRY_FMT:
+ case VIDIOC_QUERYCTRL:
+ case VIDIOC_G_TUNER:
+ case VIDIOC_S_TUNER:
+ case VIDIOC_G_FREQUENCY:
+ case VIDIOC_S_FREQUENCY:
+ default:
+ pr_debug(" case default or not supported\n");
+ retval = -EINVAL;
+ break;
+ }
+
+ if (ioctlnr != VIDIOC_DQBUF)
+ up(&cam->busy_lock);
+ return retval;
+}
+
+/*
+ * V4L interface - ioctl function
+ *
+ * @return None
+ */
+static long mxc_v4l_ioctl(struct file *file, unsigned int cmd,
+ unsigned long arg)
+{
+ pr_debug("In MVC:mxc_v4l_ioctl\n");
+ return video_usercopy(file, cmd, arg, mxc_v4l_do_ioctl);
+}
+
+/*!
+ * V4L interface - mmap function
+ *
+ * @param file structure file *
+ *
+ * @param vma structure vm_area_struct *
+ *
+ * @return status 0 Success, EINTR busy lock error, ENOBUFS remap_page error
+ */
+static int mxc_mmap(struct file *file, struct vm_area_struct *vma)
+{
+ struct video_device *dev = video_devdata(file);
+ unsigned long size;
+ int res = 0;
+ cam_data *cam = video_get_drvdata(dev);
+
+ pr_debug("In MVC:mxc_mmap\n");
+ pr_debug(" pgoff=0x%lx, start=0x%lx, end=0x%lx\n",
+ vma->vm_pgoff, vma->vm_start, vma->vm_end);
+
+ /* make this _really_ smp-safe */
+ if (down_interruptible(&cam->busy_lock))
+ return -EINTR;
+
+ size = vma->vm_end - vma->vm_start;
+ vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
+
+ if (remap_pfn_range(vma, vma->vm_start,
+ vma->vm_pgoff, size, vma->vm_page_prot)) {
+ pr_err("ERROR: v4l2 capture: mxc_mmap: "
+ "remap_pfn_range failed\n");
+ res = -ENOBUFS;
+ goto mxc_mmap_exit;
+ }
+
+ vma->vm_flags &= ~VM_IO; /* using shared anonymous pages */
+
+mxc_mmap_exit:
+ up(&cam->busy_lock);
+ return res;
+}
+
+/*!
+ * V4L interface - poll function
+ *
+ * @param file structure file *
+ *
+ * @param wait structure poll_table_struct *
+ *
+ * @return status POLLIN | POLLRDNORM
+ */
+static unsigned int mxc_poll(struct file *file, struct poll_table_struct *wait)
+{
+ struct video_device *dev = video_devdata(file);
+ cam_data *cam = video_get_drvdata(dev);
+ wait_queue_head_t *queue = NULL;
+ int res = POLLIN | POLLRDNORM;
+
+ pr_debug("In MVC:mxc_poll\n");
+
+ if (down_interruptible(&cam->busy_lock))
+ return -EINTR;
+
+ queue = &cam->enc_queue;
+ poll_wait(file, queue, wait);
+
+ up(&cam->busy_lock);
+
+ return res;
+}
+
+/*!
+ * This structure defines the functions to be called in this driver.
+ */
+static struct v4l2_file_operations mxc_v4l_fops = {
+ .owner = THIS_MODULE,
+ .open = mxc_v4l_open,
+ .release = mxc_v4l_close,
+ .read = mxc_v4l_read,
+ .unlocked_ioctl = mxc_v4l_ioctl,
+ .mmap = mxc_mmap,
+ .poll = mxc_poll,
+};
+
+static struct video_device mxc_v4l_template = {
+ .name = "Mxc Camera",
+ .fops = &mxc_v4l_fops,
+ .release = video_device_release,
+};
+
+/*!
+ * This function can be used to release any platform data on closing.
+ */
+static void camera_platform_release(struct device *device)
+{
+}
+
+/*!
+ * Camera V4l2 callback function.
+ *
+ * @param mask u32
+ *
+ * @param dev void device structure
+ *
+ * @return status
+ */
+static void camera_callback(u32 mask, void *dev)
+{
+ struct mxc_v4l_frame *done_frame;
+ struct mxc_v4l_frame *ready_frame;
+ struct timeval cur_time;
+
+ cam_data *cam = (cam_data *) dev;
+ if (cam == NULL)
+ return;
+
+ pr_debug("In MVC:camera_callback\n");
+
+ spin_lock(&cam->queue_int_lock);
+ spin_lock(&cam->dqueue_int_lock);
+ if (!list_empty(&cam->working_q)) {
+ do_gettimeofday(&cur_time);
+
+ done_frame = list_entry(cam->working_q.next,
+ struct mxc_v4l_frame,
+ queue);
+
+ if (done_frame->ipu_buf_num != cam->local_buf_num)
+ goto next;
+
+ /*
+ * Set the current time to done frame buffer's
+ * timestamp. Users can use this information to judge
+ * the frame's usage.
+ */
+ done_frame->buffer.timestamp = cur_time;
+
+ if (done_frame->buffer.flags & V4L2_BUF_FLAG_QUEUED) {
+ done_frame->buffer.flags |= V4L2_BUF_FLAG_DONE;
+ done_frame->buffer.flags &= ~V4L2_BUF_FLAG_QUEUED;
+
+ /* Added to the done queue */
+ list_del(cam->working_q.next);
+ list_add_tail(&done_frame->queue, &cam->done_q);
+
+ /* Wake up the queue */
+ cam->enc_counter++;
+ wake_up_interruptible(&cam->enc_queue);
+ } else
+ pr_err("ERROR: v4l2 capture: camera_callback: "
+ "buffer not queued\n");
+ }
+
+next:
+ if (!list_empty(&cam->ready_q)) {
+ ready_frame = list_entry(cam->ready_q.next,
+ struct mxc_v4l_frame,
+ queue);
+ if (cam->enc_update_eba)
+ if (cam->enc_update_eba(
+ cam,
+ ready_frame->buffer.m.offset) == 0) {
+ list_del(cam->ready_q.next);
+ list_add_tail(&ready_frame->queue,
+ &cam->working_q);
+ ready_frame->ipu_buf_num = cam->local_buf_num;
+ }
+ } else {
+ if (cam->enc_update_eba)
+ cam->enc_update_eba(
+ cam, cam->dummy_frame.buffer.m.offset);
+ }
+
+ cam->local_buf_num = (cam->local_buf_num == 0) ? 1 : 0;
+ spin_unlock(&cam->dqueue_int_lock);
+ spin_unlock(&cam->queue_int_lock);
+
+ return;
+}
+
+/*!
+ * initialize cam_data structure
+ *
+ * @param cam structure cam_data *
+ *
+ * @return status 0 Success
+ */
+static int init_camera_struct(cam_data *cam, struct platform_device *pdev)
+{
+ const struct of_device_id *of_id =
+ of_match_device(mxc_v4l2_dt_ids, &pdev->dev);
+ struct device_node *np = pdev->dev.of_node;
+ int ipu_id, csi_id, mclk_source;
+ int ret = 0;
+ struct v4l2_device *v4l2_dev;
+
+ pr_debug("In MVC: init_camera_struct\n");
+
+ ret = of_property_read_u32(np, "ipu_id", &ipu_id);
+ if (ret) {
+ dev_err(&pdev->dev, "ipu_id missing or invalid\n");
+ return ret;
+ }
+
+ ret = of_property_read_u32(np, "csi_id", &csi_id);
+ if (ret) {
+ dev_err(&pdev->dev, "csi_id missing or invalid\n");
+ return ret;
+ }
+
+ ret = of_property_read_u32(np, "mclk_source", &mclk_source);
+ if (ret) {
+ dev_err(&pdev->dev, "sensor mclk missing or invalid\n");
+ return ret;
+ }
+
+ /* Default everything to 0 */
+ memset(cam, 0, sizeof(cam_data));
+
+ /* get devtype to distinguish if the cpu is imx5 or imx6
+ * IMX5_V4L2 specify the cpu is imx5
+ * IMX6_V4L2 specify the cpu is imx6q or imx6sdl
+ */
+ if (of_id)
+ pdev->id_entry = of_id->data;
+ cam->devtype = pdev->id_entry->driver_data;
+
+ cam->ipu = ipu_get_soc(ipu_id);
+ if (cam->ipu == NULL) {
+ pr_err("ERROR: v4l2 capture: failed to get ipu\n");
+ return -EINVAL;
+ } else if (cam->ipu == ERR_PTR(-ENODEV)) {
+ pr_err("ERROR: v4l2 capture: get invalid ipu\n");
+ return -ENODEV;
+ }
+
+ init_MUTEX(&cam->param_lock);
+ init_MUTEX(&cam->busy_lock);
+
+ cam->video_dev = video_device_alloc();
+ if (cam->video_dev == NULL)
+ return -ENODEV;
+
+ *(cam->video_dev) = mxc_v4l_template;
+
+ video_set_drvdata(cam->video_dev, cam);
+ dev_set_drvdata(&pdev->dev, (void *)cam);
+ cam->video_dev->minor = -1;
+
+ v4l2_dev = kzalloc(sizeof(*v4l2_dev), GFP_KERNEL);
+ if (!v4l2_dev) {
+ dev_err(&pdev->dev, "failed to allocate v4l2_dev structure\n");
+ video_device_release(cam->video_dev);
+ return -ENOMEM;
+ }
+
+ if (v4l2_device_register(&pdev->dev, v4l2_dev) < 0) {
+ dev_err(&pdev->dev, "register v4l2 device failed\n");
+ video_device_release(cam->video_dev);
+ kfree(v4l2_dev);
+ return -ENODEV;
+ }
+ cam->video_dev->v4l2_dev = v4l2_dev;
+
+ init_waitqueue_head(&cam->enc_queue);
+ init_waitqueue_head(&cam->still_queue);
+
+ /* setup cropping */
+ cam->crop_bounds.left = 0;
+ cam->crop_bounds.width = 640;
+ cam->crop_bounds.top = 0;
+ cam->crop_bounds.height = 480;
+ cam->crop_current = cam->crop_defrect = cam->crop_bounds;
+ ipu_csi_set_window_size(cam->ipu, cam->crop_current.width,
+ cam->crop_current.height, cam->csi);
+ ipu_csi_set_window_pos(cam->ipu, cam->crop_current.left,
+ cam->crop_current.top, cam->csi);
+ cam->streamparm.parm.capture.capturemode = 0;
+
+ cam->standard.index = 0;
+ cam->standard.id = V4L2_STD_UNKNOWN;
+ cam->standard.frameperiod.denominator = 30;
+ cam->standard.frameperiod.numerator = 1;
+ cam->standard.framelines = 480;
+ cam->standard_autodetect = true;
+ cam->streamparm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ cam->streamparm.parm.capture.timeperframe = cam->standard.frameperiod;
+ cam->streamparm.parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
+ cam->overlay_on = false;
+ cam->capture_on = false;
+ cam->v4l2_fb.flags = V4L2_FBUF_FLAG_OVERLAY;
+
+ cam->v2f.fmt.pix.sizeimage = 352 * 288 * 3 / 2;
+ cam->v2f.fmt.pix.bytesperline = 288 * 3 / 2;
+ cam->v2f.fmt.pix.width = 288;
+ cam->v2f.fmt.pix.height = 352;
+ cam->v2f.fmt.pix.pixelformat = V4L2_PIX_FMT_YUV420;
+ cam->win.w.width = 160;
+ cam->win.w.height = 160;
+ cam->win.w.left = 0;
+ cam->win.w.top = 0;
+
+ cam->ipu_id = ipu_id;
+ cam->csi = csi_id;
+ cam->mclk_source = mclk_source;
+ cam->mclk_on[cam->mclk_source] = false;
+
+ cam->enc_callback = camera_callback;
+ init_waitqueue_head(&cam->power_queue);
+ spin_lock_init(&cam->queue_int_lock);
+ spin_lock_init(&cam->dqueue_int_lock);
+
+ cam->self = kmalloc(sizeof(struct v4l2_int_device), GFP_KERNEL);
+ cam->self->module = THIS_MODULE;
+ sprintf(cam->self->name, "mxc_v4l2_cap%d", cam->csi);
+ cam->self->type = v4l2_int_type_master;
+ cam->self->u.master = &mxc_v4l2_master;
+
+ return 0;
+}
+
+static ssize_t show_streaming(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct video_device *video_dev = container_of(dev,
+ struct video_device, dev);
+ cam_data *cam = video_get_drvdata(video_dev);
+
+ if (cam->capture_on)
+ return sprintf(buf, "stream on\n");
+ else
+ return sprintf(buf, "stream off\n");
+}
+static DEVICE_ATTR(fsl_v4l2_capture_property, S_IRUGO, show_streaming, NULL);
+
+static ssize_t show_overlay(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct video_device *video_dev = container_of(dev,
+ struct video_device, dev);
+ cam_data *cam = video_get_drvdata(video_dev);
+
+ if (cam->overlay_on)
+ return sprintf(buf, "overlay on\n");
+ else
+ return sprintf(buf, "overlay off\n");
+}
+static DEVICE_ATTR(fsl_v4l2_overlay_property, S_IRUGO, show_overlay, NULL);
+
+static ssize_t show_csi(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct video_device *video_dev = container_of(dev,
+ struct video_device, dev);
+ cam_data *cam = video_get_drvdata(video_dev);
+
+ return sprintf(buf, "ipu%d_csi%d\n", cam->ipu_id, cam->csi);
+}
+static DEVICE_ATTR(fsl_csi_property, S_IRUGO, show_csi, NULL);
+
+/*!
+ * This function is called to probe the devices if registered.
+ *
+ * @param pdev the device structure used to give information on which device
+ * to probe
+ *
+ * @return The function returns 0 on success and -1 on failure.
+ */
+static int mxc_v4l2_probe(struct platform_device *pdev)
+{
+ /* Create cam and initialize it. */
+ cam_data *cam = kmalloc(sizeof(cam_data), GFP_KERNEL);
+ if (cam == NULL) {
+ pr_err("ERROR: v4l2 capture: failed to register camera\n");
+ return -1;
+ }
+
+ init_camera_struct(cam, pdev);
+ pdev->dev.release = camera_platform_release;
+
+ /* Set up the v4l2 device and register it*/
+ cam->self->priv = cam;
+ v4l2_int_device_register(cam->self);
+
+ /* register v4l video device */
+ if (video_register_device(cam->video_dev, VFL_TYPE_GRABBER, video_nr)
+ < 0) {
+ kfree(cam);
+ cam = NULL;
+ pr_err("ERROR: v4l2 capture: video_register_device failed\n");
+ return -1;
+ }
+ pr_debug(" Video device registered: %s #%d\n",
+ cam->video_dev->name, cam->video_dev->minor);
+
+ if (device_create_file(&cam->video_dev->dev,
+ &dev_attr_fsl_v4l2_capture_property))
+ dev_err(&pdev->dev, "Error on creating sysfs file"
+ " for capture\n");
+
+ if (device_create_file(&cam->video_dev->dev,
+ &dev_attr_fsl_v4l2_overlay_property))
+ dev_err(&pdev->dev, "Error on creating sysfs file"
+ " for overlay\n");
+
+ if (device_create_file(&cam->video_dev->dev,
+ &dev_attr_fsl_csi_property))
+ dev_err(&pdev->dev, "Error on creating sysfs file"
+ " for csi number\n");
+
+ return 0;
+}
+
+/*!
+ * This function is called to remove the devices when device unregistered.
+ *
+ * @param pdev the device structure used to give information on which device
+ * to remove
+ *
+ * @return The function returns 0 on success and -1 on failure.
+ */
+static int mxc_v4l2_remove(struct platform_device *pdev)
+{
+ cam_data *cam = (cam_data *)platform_get_drvdata(pdev);
+ if (cam->open_count) {
+ pr_err("ERROR: v4l2 capture:camera open "
+ "-- setting ops to NULL\n");
+ return -EBUSY;
+ } else {
+ struct v4l2_device *v4l2_dev = cam->video_dev->v4l2_dev;
+ device_remove_file(&cam->video_dev->dev,
+ &dev_attr_fsl_v4l2_capture_property);
+ device_remove_file(&cam->video_dev->dev,
+ &dev_attr_fsl_v4l2_overlay_property);
+ device_remove_file(&cam->video_dev->dev,
+ &dev_attr_fsl_csi_property);
+
+ pr_info("V4L2 freeing image input device\n");
+ v4l2_int_device_unregister(cam->self);
+ video_unregister_device(cam->video_dev);
+
+ mxc_free_frame_buf(cam);
+ kfree(cam);
+
+ v4l2_device_unregister(v4l2_dev);
+ kfree(v4l2_dev);
+ }
+
+ pr_info("V4L2 unregistering video\n");
+ return 0;
+}
+
+/*!
+ * This function is called to put the sensor in a low power state.
+ * Refer to the document driver-model/driver.txt in the kernel source tree
+ * for more information.
+ *
+ * @param pdev the device structure used to give information on which I2C
+ * to suspend
+ * @param state the power state the device is entering
+ *
+ * @return The function returns 0 on success and -1 on failure.
+ */
+static int mxc_v4l2_suspend(struct platform_device *pdev, pm_message_t state)
+{
+ cam_data *cam = platform_get_drvdata(pdev);
+
+ pr_debug("In MVC:mxc_v4l2_suspend\n");
+
+ if (cam == NULL)
+ return -1;
+
+ down(&cam->busy_lock);
+
+ cam->low_power = true;
+
+ if (cam->overlay_on == true)
+ stop_preview(cam);
+ if (cam->capture_on == true) {
+ if (cam->enc_disable_csi)
+ cam->enc_disable_csi(cam);
+
+ if (cam->enc_disable)
+ cam->enc_disable(cam);
+ }
+
+ if (cam->sensor && cam->open_count) {
+ if (cam->mclk_on[cam->mclk_source]) {
+ ipu_csi_enable_mclk_if(cam->ipu, CSI_MCLK_I2C,
+ cam->mclk_source,
+ false, false);
+ cam->mclk_on[cam->mclk_source] = false;
+ }
+ vidioc_int_s_power(cam->sensor, 0);
+ }
+
+ up(&cam->busy_lock);
+
+ return 0;
+}
+
+/*!
+ * This function is called to bring the sensor back from a low power state.
+ * Refer to the document driver-model/driver.txt in the kernel source tree
+ * for more information.
+ *
+ * @param pdev the device structure
+ *
+ * @return The function returns 0 on success and -1 on failure
+ */
+static int mxc_v4l2_resume(struct platform_device *pdev)
+{
+ cam_data *cam = platform_get_drvdata(pdev);
+
+ pr_debug("In MVC:mxc_v4l2_resume\n");
+
+ if (cam == NULL)
+ return -1;
+
+ down(&cam->busy_lock);
+
+ cam->low_power = false;
+ wake_up_interruptible(&cam->power_queue);
+
+ if (cam->sensor && cam->open_count) {
+ vidioc_int_s_power(cam->sensor, 1);
+
+ if (!cam->mclk_on[cam->mclk_source]) {
+ ipu_csi_enable_mclk_if(cam->ipu, CSI_MCLK_I2C,
+ cam->mclk_source,
+ true, true);
+ cam->mclk_on[cam->mclk_source] = true;
+ }
+ }
+
+ if (cam->overlay_on == true)
+ start_preview(cam);
+ if (cam->capture_on == true) {
+ if (cam->enc_enable)
+ cam->enc_enable(cam);
+
+ if (cam->enc_enable_csi)
+ cam->enc_enable_csi(cam);
+ }
+
+ up(&cam->busy_lock);
+
+ return 0;
+}
+
+/*!
+ * This structure contains pointers to the power management callback functions.
+ */
+static struct platform_driver mxc_v4l2_driver = {
+ .driver = {
+ .name = "mxc_v4l2_capture",
+ .owner = THIS_MODULE,
+ .of_match_table = mxc_v4l2_dt_ids,
+ },
+ .id_table = imx_v4l2_devtype,
+ .probe = mxc_v4l2_probe,
+ .remove = mxc_v4l2_remove,
+ .suspend = mxc_v4l2_suspend,
+ .resume = mxc_v4l2_resume,
+ .shutdown = NULL,
+};
+
+/*!
+ * Initializes the camera driver.
+ */
+static int mxc_v4l2_master_attach(struct v4l2_int_device *slave)
+{
+ cam_data *cam = slave->u.slave->master->priv;
+ struct v4l2_format cam_fmt;
+ int i;
+ struct sensor_data *sdata = slave->priv;
+
+ pr_debug("In MVC: mxc_v4l2_master_attach\n");
+ pr_debug(" slave.name = %s\n", slave->name);
+ pr_debug(" master.name = %s\n", slave->u.slave->master->name);
+
+ if (slave == NULL) {
+ pr_err("ERROR: v4l2 capture: slave parameter not valid.\n");
+ return -1;
+ }
+
+ if (sdata->csi != cam->csi) {
+ pr_debug("%s: csi doesn't match\n", __func__);
+ return -1;
+ }
+
+ cam->sensor = slave;
+
+ if (cam->sensor_index < MXC_SENSOR_NUM) {
+ cam->all_sensors[cam->sensor_index] = slave;
+ cam->sensor_index++;
+ } else {
+ pr_err("ERROR: v4l2 capture: slave number exceeds "
+ "the maximum.\n");
+ return -1;
+ }
+
+ for (i = 0; i < cam->sensor_index; i++) {
+ vidioc_int_dev_exit(cam->all_sensors[i]);
+ vidioc_int_s_power(cam->all_sensors[i], 0);
+ }
+
+ cam_fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ vidioc_int_g_fmt_cap(cam->sensor, &cam_fmt);
+
+ /* Used to detect TV in (type 1) vs. camera (type 0)*/
+ cam->device_type = cam_fmt.fmt.pix.priv;
+
+ /* Set the input size to the ipu for this device */
+ cam->crop_bounds.top = cam->crop_bounds.left = 0;
+ cam->crop_bounds.width = cam_fmt.fmt.pix.width;
+ cam->crop_bounds.height = cam_fmt.fmt.pix.height;
+
+ /* This also is the max crop size for this device. */
+ cam->crop_defrect.top = cam->crop_defrect.left = 0;
+ cam->crop_defrect.width = cam_fmt.fmt.pix.width;
+ cam->crop_defrect.height = cam_fmt.fmt.pix.height;
+
+ /* At this point, this is also the current image size. */
+ cam->crop_current.top = cam->crop_current.left = 0;
+ cam->crop_current.width = cam_fmt.fmt.pix.width;
+ cam->crop_current.height = cam_fmt.fmt.pix.height;
+
+ pr_debug("End of %s: v2f pix widthxheight %d x %d\n",
+ __func__,
+ cam->v2f.fmt.pix.width, cam->v2f.fmt.pix.height);
+ pr_debug("End of %s: crop_bounds widthxheight %d x %d\n",
+ __func__,
+ cam->crop_bounds.width, cam->crop_bounds.height);
+ pr_debug("End of %s: crop_defrect widthxheight %d x %d\n",
+ __func__,
+ cam->crop_defrect.width, cam->crop_defrect.height);
+ pr_debug("End of %s: crop_current widthxheight %d x %d\n",
+ __func__,
+ cam->crop_current.width, cam->crop_current.height);
+
+ return 0;
+}
+
+/*!
+ * Disconnects the camera driver.
+ */
+static void mxc_v4l2_master_detach(struct v4l2_int_device *slave)
+{
+ unsigned int i;
+ cam_data *cam = slave->u.slave->master->priv;
+
+ pr_debug("In MVC:mxc_v4l2_master_detach\n");
+
+ if (cam->sensor_index > 1) {
+ for (i = 0; i < cam->sensor_index; i++) {
+ if (cam->all_sensors[i] != slave)
+ continue;
+ /* Move all the sensors behind this
+ * sensor one step forward
+ */
+ for (; i <= MXC_SENSOR_NUM - 2; i++)
+ cam->all_sensors[i] = cam->all_sensors[i+1];
+ break;
+ }
+ /* Point current sensor to the last one */
+ cam->sensor = cam->all_sensors[cam->sensor_index - 2];
+ } else
+ cam->sensor = NULL;
+
+ cam->sensor_index--;
+ vidioc_int_dev_exit(slave);
+}
+
+/*!
+ * Entry point for the V4L2
+ *
+ * @return Error code indicating success or failure
+ */
+static __init int camera_init(void)
+{
+ u8 err = 0;
+
+ pr_debug("In MVC:camera_init\n");
+
+ /* Register the device driver structure. */
+ err = platform_driver_register(&mxc_v4l2_driver);
+ if (err != 0) {
+ pr_err("ERROR: v4l2 capture:camera_init: "
+ "platform_driver_register failed.\n");
+ return err;
+ }
+
+ return err;
+}
+
+/*!
+ * Exit and cleanup for the V4L2
+ */
+static void __exit camera_exit(void)
+{
+ pr_debug("In MVC: camera_exit\n");
+
+ platform_driver_unregister(&mxc_v4l2_driver);
+}
+
+module_init(camera_init);
+module_exit(camera_exit);
+
+module_param(video_nr, int, 0444);
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("V4L2 capture driver for Mxc based cameras");
+MODULE_LICENSE("GPL");
+MODULE_SUPPORTED_DEVICE("video");
diff --git a/drivers/media/platform/mxc/capture/mxc_v4l2_capture.h b/drivers/media/platform/mxc/capture/mxc_v4l2_capture.h
new file mode 100644
index 000000000000..f6717752d4b9
--- /dev/null
+++ b/drivers/media/platform/mxc/capture/mxc_v4l2_capture.h
@@ -0,0 +1,262 @@
+/*
+ * Copyright 2004-2015 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/*!
+ * @defgroup MXC_V4L2_CAPTURE MXC V4L2 Video Capture Driver
+ */
+/*!
+ * @file mxc_v4l2_capture.h
+ *
+ * @brief mxc V4L2 capture device API Header file
+ *
+ * It include all the defines for frame operations, also three structure defines
+ * use case ops structure, common v4l2 driver structure and frame structure.
+ *
+ * @ingroup MXC_V4L2_CAPTURE
+ */
+#ifndef __MXC_V4L2_CAPTURE_H__
+#define __MXC_V4L2_CAPTURE_H__
+
+#include <linux/uaccess.h>
+#include <linux/list.h>
+#include <linux/mxc_v4l2.h>
+#include <linux/completion.h>
+#include <linux/dmaengine.h>
+#include <linux/pxp_dma.h>
+#include <linux/ipu-v3.h>
+#include <linux/platform_data/dma-imx.h>
+
+#include <media/v4l2-dev.h>
+#include "v4l2-int-device.h"
+
+
+#define FRAME_NUM 10
+#define MXC_SENSOR_NUM 2
+
+enum imx_v4l2_devtype {
+ IMX5_V4L2,
+ IMX6_V4L2,
+};
+
+/*!
+ * v4l2 frame structure.
+ */
+struct mxc_v4l_frame {
+ u32 paddress;
+ void *vaddress;
+ int count;
+ int width;
+ int height;
+
+ struct v4l2_buffer buffer;
+ struct list_head queue;
+ int index;
+ union {
+ int ipu_buf_num;
+ int csi_buf_num;
+ };
+};
+
+/* Only for old version. Will go away soon. */
+typedef struct {
+ u8 clk_mode;
+ u8 ext_vsync;
+ u8 Vsync_pol;
+ u8 Hsync_pol;
+ u8 pixclk_pol;
+ u8 data_pol;
+ u8 data_width;
+ u8 pack_tight;
+ u8 force_eof;
+ u8 data_en_pol;
+ u16 width;
+ u16 height;
+ u32 pixel_fmt;
+ u32 mclk;
+ u16 active_width;
+ u16 active_height;
+} sensor_interface;
+
+/* Sensor control function */
+/* Only for old version. Will go away soon. */
+struct camera_sensor {
+ void (*set_color) (int bright, int saturation, int red, int green,
+ int blue);
+ void (*get_color) (int *bright, int *saturation, int *red, int *green,
+ int *blue);
+ void (*set_ae_mode) (int ae_mode);
+ void (*get_ae_mode) (int *ae_mode);
+ sensor_interface *(*config) (int *frame_rate, int high_quality);
+ sensor_interface *(*reset) (void);
+ void (*get_std) (v4l2_std_id *std);
+ void (*set_std) (v4l2_std_id std);
+ unsigned int csi;
+};
+
+/*!
+ * common v4l2 driver structure.
+ */
+typedef struct _cam_data {
+ struct video_device *video_dev;
+ int device_type;
+
+ /* semaphore guard against SMP multithreading */
+ struct semaphore busy_lock;
+
+ int open_count;
+
+ /* params lock for this camera */
+ struct semaphore param_lock;
+
+ /* Encoder */
+ struct list_head ready_q;
+ struct list_head done_q;
+ struct list_head working_q;
+ int ping_pong_csi;
+ spinlock_t queue_int_lock;
+ spinlock_t dqueue_int_lock;
+ struct mxc_v4l_frame frame[FRAME_NUM];
+ struct mxc_v4l_frame dummy_frame;
+ wait_queue_head_t enc_queue;
+ int enc_counter;
+ dma_addr_t rot_enc_bufs[2];
+ void *rot_enc_bufs_vaddr[2];
+ int rot_enc_buf_size[2];
+ enum v4l2_buf_type type;
+
+ /* still image capture */
+ wait_queue_head_t still_queue;
+ int still_counter;
+ dma_addr_t still_buf[2];
+ void *still_buf_vaddr;
+
+ /* overlay */
+ struct v4l2_window win;
+ struct v4l2_framebuffer v4l2_fb;
+ dma_addr_t vf_bufs[2];
+ void *vf_bufs_vaddr[2];
+ int vf_bufs_size[2];
+ dma_addr_t rot_vf_bufs[2];
+ void *rot_vf_bufs_vaddr[2];
+ int rot_vf_buf_size[2];
+ bool overlay_active;
+ int output;
+ struct fb_info *overlay_fb;
+ int fb_origin_std;
+ struct work_struct csi_work_struct;
+
+ /* v4l2 format */
+ struct v4l2_format v2f;
+ struct v4l2_format input_fmt; /* camera in */
+ bool bswapenable;
+ int rotation; /* for IPUv1 and IPUv3, this means encoder rotation */
+ int vf_rotation; /* viewfinder rotation only for IPUv1 and IPUv3 */
+ struct v4l2_mxc_offset offset;
+
+ /* V4l2 control bit */
+ int bright;
+ int hue;
+ int contrast;
+ int saturation;
+ int red;
+ int green;
+ int blue;
+ int ae_mode;
+
+ /* standard */
+ struct v4l2_streamparm streamparm;
+ struct v4l2_standard standard;
+ bool standard_autodetect;
+
+ /* crop */
+ struct v4l2_rect crop_bounds;
+ struct v4l2_rect crop_defrect;
+ struct v4l2_rect crop_current;
+
+ int (*enc_update_eba) (void *private, dma_addr_t eba);
+ int (*enc_enable) (void *private);
+ int (*enc_disable) (void *private);
+ int (*enc_enable_csi) (void *private);
+ int (*enc_disable_csi) (void *private);
+ void (*enc_callback) (u32 mask, void *dev);
+ int (*vf_start_adc) (void *private);
+ int (*vf_stop_adc) (void *private);
+ int (*vf_start_sdc) (void *private);
+ int (*vf_stop_sdc) (void *private);
+ int (*vf_enable_csi) (void *private);
+ int (*vf_disable_csi) (void *private);
+ int (*csi_start) (void *private);
+ int (*csi_stop) (void *private);
+
+ /* misc status flag */
+ bool overlay_on;
+ bool capture_on;
+ int overlay_pid;
+ int capture_pid;
+ bool low_power;
+ wait_queue_head_t power_queue;
+ unsigned int ipu_id;
+ unsigned int csi;
+ u8 mclk_source;
+ bool mclk_on[2]; /* two mclk sources at most now */
+ int current_input;
+
+ int local_buf_num;
+
+ /* camera sensor interface */
+ struct camera_sensor *cam_sensor; /* old version */
+ struct v4l2_int_device *all_sensors[MXC_SENSOR_NUM];
+ struct v4l2_int_device *sensor;
+ struct v4l2_int_device *self;
+ int sensor_index;
+ void *ipu;
+ void *csi_soc;
+ enum imx_v4l2_devtype devtype;
+
+ /* v4l2 buf elements related to PxP DMA */
+ struct completion pxp_tx_cmpl;
+ struct pxp_channel *pxp_chan;
+ struct pxp_config_data pxp_conf;
+ struct dma_async_tx_descriptor *txd;
+ dma_cookie_t cookie;
+ struct scatterlist sg[2];
+} cam_data;
+
+struct sensor_data {
+ const struct ov5642_platform_data *platform_data;
+ struct v4l2_int_device *v4l2_int_device;
+ struct i2c_client *i2c_client;
+ struct v4l2_pix_format pix;
+ struct v4l2_captureparm streamcap;
+ bool on;
+
+ /* control settings */
+ int brightness;
+ int hue;
+ int contrast;
+ int saturation;
+ int red;
+ int green;
+ int blue;
+ int ae_mode;
+
+ u32 mclk;
+ u8 mclk_source;
+ struct clk *sensor_clk;
+ int csi;
+
+ void (*io_init)(void);
+};
+
+void set_mclk_rate(uint32_t *p_mclk_freq, uint32_t csi);
+#endif /* __MXC_V4L2_CAPTURE_H__ */
diff --git a/drivers/media/platform/mxc/capture/mxc_vadc.c b/drivers/media/platform/mxc/capture/mxc_vadc.c
new file mode 100644
index 000000000000..2a844ca8ab5d
--- /dev/null
+++ b/drivers/media/platform/mxc/capture/mxc_vadc.c
@@ -0,0 +1,830 @@
+/*
+ * Copyright (C) 2014-2015 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/mfd/syscon.h>
+#include <linux/mfd/syscon/imx6q-iomuxc-gpr.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/regmap.h>
+#include <linux/media-bus-format.h>
+#include <media/v4l2-ioctl.h>
+#include <linux/videodev2.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-ctrls.h>
+#include "mxc_vadc.h"
+
+/* Resource names for the VADC driver. */
+#define VAFE_REGS_ADDR_RES_NAME "vadc-vafe"
+#define VDEC_REGS_ADDR_RES_NAME "vadc-vdec"
+
+#define reg32_write(addr, val) __raw_writel(val, addr)
+#define reg32_read(addr) __raw_readl(addr)
+#define reg32setbit(addr, bitpos) \
+ reg32_write((addr), (reg32_read((addr)) | (1<<(bitpos))))
+
+#define reg32clrbit(addr, bitpos) \
+ reg32_write((addr), (reg32_read((addr)) & (0xFFFFFFFF ^ (1<<(bitpos)))))
+
+#define GPC_CNTR 0x00
+#define IMX6SX_GPC_CNTR_VADC_ANALOG_OFF_MASK BIT(17)
+#define IMX6SX_GPC_CNTR_VADC_POWER_DOWN_MASK BIT(18)
+
+void __iomem *vafe_regbase;
+void __iomem *vdec_regbase;
+
+
+/* List of input video formats supported. The video formats is corresponding
+ * with v4l2 id in video_fmt
+ */
+enum video_fmt_idx {
+ VADC_NTSC = 0, /* Locked on (M) NTSC video signal. */
+ VADC_PAL, /* (B, G, H, I, N)PAL video signal. */
+};
+
+/* Number of video standards supported (including 'not locked' signal). */
+#define VADC_STD_MAX (VADC_PAL + 1)
+
+/* Video format structure. */
+struct video_fmt{
+ v4l2_std_id v4l2_std; /* Video for linux ID. */
+ char name[16]; /* Name (e.g., "NTSC", "PAL", etc.) */
+ u16 raw_width; /* Raw width. */
+ u16 raw_height; /* Raw height. */
+ u16 active_width; /* Active width. */
+ u16 active_height; /* Active height. */
+ u16 framerates;
+};
+
+/*
+ * Maintains the information on the current state of the sensor.
+ */
+struct vadc_state {
+ struct v4l2_device v4l2_dev;
+ struct v4l2_subdev sd;
+ struct video_fmt *fmt;
+
+ struct clk *vadc_clk;
+ struct clk *csi_clk;
+ struct regmap *gpr;
+ void __iomem *gpc_reg;
+
+ u32 vadc_in;
+ u32 csi_id;
+};
+
+static int vadc_querystd(struct v4l2_subdev *sd, v4l2_std_id *std);
+
+/* Description of video formats supported.
+ *
+ * PAL: raw=720x625, active=720x576.
+ * NTSC: raw=720x525, active=720x480.
+ */
+static struct video_fmt video_fmts[] = {
+ /* NTSC */
+ {
+ .v4l2_std = V4L2_STD_NTSC,
+ .name = "NTSC",
+ .raw_width = 720,
+ .raw_height = 525,
+ .active_width = 720,
+ .active_height = 480,
+ .framerates = 30,
+ },
+ /* (B, G, H, I, N) PAL */
+ {
+ .v4l2_std = V4L2_STD_PAL,
+ .name = "PAL",
+ .raw_width = 720,
+ .raw_height = 625,
+ .active_width = 720,
+ .active_height = 576,
+ .framerates = 25,
+ },
+};
+
+static void afe_voltage_clampingmode(void)
+{
+ reg32_write(AFE_CLAMP, 0x07);
+ reg32_write(AFE_CLMPAMP, 0x60);
+ reg32_write(AFE_CLMPDAT, 0xF0);
+}
+
+static void afe_alwayson_clampingmode(void)
+{
+ reg32_write(AFE_CLAMP, 0x15);
+ reg32_write(AFE_CLMPDAT, 0x08);
+ reg32_write(AFE_CLMPAMP, 0x00);
+}
+
+static void afe_init(void)
+{
+ pr_debug("%s\n", __func__);
+
+ reg32_write(AFE_PDBUF, 0x1f);
+ reg32_write(AFE_PDADC, 0x0f);
+ reg32_write(AFE_PDSARH, 0x01);
+ reg32_write(AFE_PDSARL, 0xff);
+ reg32_write(AFE_PDADCRFH, 0x01);
+ reg32_write(AFE_PDADCRFL, 0xff);
+ reg32_write(AFE_ICTRL, 0x3a);
+ reg32_write(AFE_ICTLSTG, 0x1e);
+
+ reg32_write(AFE_RCTRLSTG, 0x1e);
+ reg32_write(AFE_INPBUF, 0x035);
+ reg32_write(AFE_INPFLT, 0x02);
+ reg32_write(AFE_ADCDGN, 0x40);
+ reg32_write(AFE_TSTSEL, 0x10);
+
+ reg32_write(AFE_ACCTST, 0x07);
+
+ reg32_write(AFE_BGREG, 0x08);
+
+ reg32_write(AFE_ADCGN, 0x09);
+
+ /* set current controlled clamping
+ * always on, low current */
+ reg32_write(AFE_CLAMP, 0x11);
+ reg32_write(AFE_CLMPAMP, 0x08);
+}
+
+static void vdec_mode_timing_init(int std)
+{
+ if (std == V4L2_STD_NTSC) {
+ /* NTSC 720x480 */
+ reg32_write(VDEC_HACTS, 0x66);
+ reg32_write(VDEC_HACTE, 0x24);
+
+ reg32_write(VDEC_VACTS, 0x29);
+ reg32_write(VDEC_VACTE, 0x04);
+
+ /* set V Position */
+ reg32_write(VDEC_VRTPOS, 0x2);
+ } else if (std == V4L2_STD_PAL) {
+ /* PAL 720x576 */
+ reg32_write(VDEC_HACTS, 0x66);
+ reg32_write(VDEC_HACTE, 0x24);
+
+ reg32_write(VDEC_VACTS, 0x29);
+ reg32_write(VDEC_VACTE, 0x04);
+
+ /* set V Position */
+ reg32_write(VDEC_VRTPOS, 0x6);
+ } else
+ pr_debug("Error not support video mode\n");
+
+ /* set H Position */
+ reg32_write(VDEC_HZPOS, 0x60);
+
+ /* set H ignore start */
+ reg32_write(VDEC_HSIGS, 0xf8);
+
+ /* set H ignore end */
+ reg32_write(VDEC_HSIGE, 0x18);
+}
+
+/*
+* vdec_init()
+* Initialises the VDEC registers
+* Returns: nothing
+*/
+static void vdec_init(struct vadc_state *vadc)
+{
+ v4l2_std_id std;
+
+ pr_debug("%s\n", __func__);
+
+ /* Get work mode PAL or NTSC */
+ vadc_querystd(&vadc->sd, &std);
+
+ vdec_mode_timing_init(std);
+
+ /* vcr detect threshold high, automatic detections */
+ reg32_write(VDEC_VSCON2, 0);
+
+ reg32_write(VDEC_BASE + 0x110, 0x01);
+
+ /* set the noramp mode on the Hloop PLL. */
+ reg32_write(VDEC_BASE+(0x14*4), 0x10);
+
+ /* set the YC relative delay.*/
+ reg32_write(VDEC_YCDEL, 0x90);
+
+ /* setup the Hpll */
+ reg32_write(VDEC_BASE+(0x13*4), 0x13);
+
+ /* setup the 2d comb */
+ /* set the gain of the Hdetail output to 3
+ * set the notch alpha gain to 1 */
+ reg32_write(VDEC_CFC2, 0x34);
+
+ /* setup various 2d comb bits.*/
+ reg32_write(VDEC_BASE+(0x02*4), 0x01);
+ reg32_write(VDEC_BASE+(0x03*4), 0x18);
+ reg32_write(VDEC_BASE+(0x04*4), 0x34);
+
+ /* set the start of the burst gate */
+ reg32_write(VDEC_BRSTGT, 0x30);
+
+ /* set 1f motion gain */
+ reg32_write(VDEC_BASE+(0x0f*4), 0x20);
+
+ /* set the 1F chroma motion detector thresh
+ * for colour reverse detection */
+ reg32_write(VDEC_THSH1, 0x02);
+ reg32_write(VDEC_BASE+(0x4a*4), 0x20);
+ reg32_write(VDEC_BASE+(0x4b*4), 0x08);
+
+ reg32_write(VDEC_BASE+(0x4c*4), 0x08);
+
+ /* set the threshold for the narrow/wide adaptive chroma BW */
+ reg32_write(VDEC_BASE+(0x20*4), 0x20);
+
+ /* turn up the colour with the new colour gain reg */
+ /* hue: */
+ reg32_write(VDEC_HUE, 0x00);
+
+ /* cbgain: 22 B4 */
+ reg32_write(VDEC_CBGN, 0xb4);
+ /* cr gain 80 */
+ reg32_write(VDEC_CRGN, 0x80);
+ /* luma gain (contrast) */
+ reg32_write(VDEC_CNTR, 0x80);
+
+ /* setup the signed black level register, brightness */
+ reg32_write(VDEC_BRT, 0x00);
+
+ /* filter the standard detection
+ * enable the comb for the ntsc443 */
+ reg32_write(VDEC_STDDBG, 0x20);
+
+ /* setup chroma kill thresh for no chroma */
+ reg32_write(VDEC_CHBTH, 0x0);
+
+ /* set chroma loop to wider BW
+ * no set it to normal BW. i fixed the bw problem.*/
+ reg32_write(VDEC_YCDEL, 0x00);
+
+ /* set the compensation in the chroma loop for the Hloop
+ * set the ratio for the nonarithmetic 3d comb modes.*/
+ reg32_write(VDEC_BASE + (0x1d*4), 0x90);
+
+ /* set the threshold for the nonarithmetic mode for the 2d comb
+ * the higher the value the more Fc Fh offset
+ * we will tolerate before turning off the comb. */
+ reg32_write(VDEC_BASE + (0x33*4), 0xa0);
+
+ /* setup the bluescreen output colour */
+ reg32_write(VDEC_BASE + (0x3d*4), 35);
+ reg32_write(VDEC_BLSCRCR, 114);
+ reg32_write(VDEC_BLSCRCB, 212);
+
+ /* disable the active blanking */
+ reg32_write(VDEC_BASE + (0x15*4), 0x02);
+
+ /* setup the luma agc for automatic gain. */
+ reg32_write(VDEC_LMAGC2, 0x5e);
+ reg32_write(VDEC_LMAGC1, 0x81);
+
+ /* setup chroma agc */
+ reg32_write(VDEC_CHAGC2, 0xa0);
+ reg32_write(VDEC_CHAGC1, 0x01);
+
+ /* setup the MV thresh lower nibble
+ * setup the sync top cap, upper nibble */
+ reg32_write(VDEC_BASE + (0x3a*4), 0x80);
+ reg32_write(VDEC_SHPIMP, 0x00);
+
+ /* setup the vsync block */
+ reg32_write(VDEC_VSCON1, 0x87);
+
+ /* set the nosignal threshold
+ * set the vsync threshold */
+ reg32_write(VDEC_VSSGTH, 0x35);
+
+ /* set length for min hphase filter
+ * (or saturate limit if saturate is chosen) */
+ reg32_write(VDEC_BASE + (0x45*4), 0x40);
+
+ /* enable the internal resampler,
+ * select min filter not saturate for
+ * hphase noise filter for vcr detect.
+ * enable vcr pause mode different field lengths */
+ reg32_write(VDEC_BASE + (0x46*4), 0x90);
+
+ /* disable VCR detection, lock to the Hsync rather than the Vsync */
+ reg32_write(VDEC_VSCON2, 0x04);
+
+ /* set tiplevel goal for dc clamp. */
+ reg32_write(VDEC_BASE + (0x3c*4), 0xB0);
+
+ /* override SECAM detection and force SECAM off */
+ reg32_write(VDEC_BASE + (0x2f*4), 0x20);
+
+ /* Set r3d_hardblend in 3D control2 reg */
+ reg32_write(VDEC_BASE + (0x0c*4), 0x04);
+}
+
+/* set Input selector & input pull-downs */
+static void vadc_s_routing(int vadc_in)
+{
+ switch (vadc_in) {
+ case 0:
+ reg32_write(AFE_INPFLT, 0x02);
+ reg32_write(AFE_OFFDRV, 0x00);
+ reg32_write(AFE_INPCONFIG, 0x1e);
+ break;
+ case 1:
+ reg32_write(AFE_INPFLT, 0x02);
+ reg32_write(AFE_OFFDRV, 0x00);
+ reg32_write(AFE_INPCONFIG, 0x2d);
+ break;
+ case 2:
+ reg32_write(AFE_INPFLT, 0x02);
+ reg32_write(AFE_OFFDRV, 0x00);
+ reg32_write(AFE_INPCONFIG, 0x4b);
+ break;
+ case 3:
+ reg32_write(AFE_INPFLT, 0x02);
+ reg32_write(AFE_OFFDRV, 0x00);
+ reg32_write(AFE_INPCONFIG, 0x87);
+ break;
+ default:
+ pr_debug("error video input %d\n", vadc_in);
+ }
+}
+
+static void vadc_power_up(struct vadc_state *state)
+{
+ /* Power on vadc analog */
+ reg32clrbit(state->gpc_reg + GPC_CNTR, 17);
+
+ /* Power down vadc ext power */
+ reg32clrbit(state->gpc_reg + GPC_CNTR, 18);
+
+ /* software reset afe */
+ regmap_update_bits(state->gpr, IOMUXC_GPR1,
+ IMX6SX_GPR1_VADC_SW_RST_MASK,
+ IMX6SX_GPR1_VADC_SW_RST_RESET);
+
+ msleep(10);
+
+ /* clock config for vadc */
+ reg32_write(VDEC_BASE + 0x320, 0xe3);
+ reg32_write(VDEC_BASE + 0x324, 0x38);
+ reg32_write(VDEC_BASE + 0x328, 0x8e);
+ reg32_write(VDEC_BASE + 0x32c, 0x23);
+
+ /* Release reset bit */
+ regmap_update_bits(state->gpr, IOMUXC_GPR1,
+ IMX6SX_GPR1_VADC_SW_RST_MASK,
+ IMX6SX_GPR1_VADC_SW_RST_RELEASE);
+
+ /* Power on vadc ext power */
+ reg32setbit(state->gpc_reg + GPC_CNTR, 18);
+}
+
+static void vadc_power_down(struct vadc_state *state)
+{
+ /* Power down vadc analog */
+ reg32setbit(state->gpc_reg + GPC_CNTR, 17);
+
+ /* Power down vadc ext power */
+ reg32clrbit(state->gpc_reg + GPC_CNTR, 18);
+
+}
+static void vadc_init(struct vadc_state *vadc)
+{
+ pr_debug("%s\n", __func__);
+
+ vadc_power_up(vadc);
+
+ afe_init();
+
+ /* select Video Input 0-3 */
+ vadc_s_routing(vadc->vadc_in);
+
+ afe_voltage_clampingmode();
+
+ vdec_init(vadc);
+
+ /*
+ * current control loop will move sinewave input off below
+ * the bottom of the signal range visible
+ * when the testbus is viewed as magnitude,
+ * so have to break before this point while capturing ENOB data:
+ */
+ afe_alwayson_clampingmode();
+}
+
+static inline struct vadc_state *to_state(struct v4l2_subdev *sd)
+{
+ return container_of(sd, struct vadc_state, sd);
+}
+
+static int vadc_g_std(struct v4l2_subdev *sd, v4l2_std_id *std)
+{
+ struct vadc_state *state = to_state(sd);
+
+ *std = state->fmt->v4l2_std;
+ return 0;
+}
+
+/*!
+ * Return attributes of current video standard.
+ * Since this device autodetects the current standard, this function also
+ * sets the values that need to be changed if the standard changes.
+ * There is no set std equivalent function.
+ *
+ * @return None.
+ */
+static int vadc_querystd(struct v4l2_subdev *sd, v4l2_std_id *std)
+{
+ struct vadc_state *state = to_state(sd);
+ int mod;
+ int idx;
+ int i;
+
+ /* Read auto mode detected result */
+ printk(KERN_INFO"wait vadc auto detect video mode....\n");
+ for (i = 0; i < 10; i++) {
+ msleep(200);
+ mod = reg32_read(VDEC_VIDMOD);
+ /* Check video signal states */
+ if ((mod & VDEC_VIDMOD_SIGNAL_MASK)
+ == VDEC_VIDMOD_SIGNAL_DETECT)
+ break;
+ }
+ if (i == 10)
+ printk(KERN_INFO"Timeout detect video signal mod=0x%x\n", mod);
+
+ if ((mod & VDEC_VIDMOD_PAL_MASK) || (mod & VDEC_VIDMOD_M625_MASK))
+ idx = VADC_PAL;
+ else
+ idx = VADC_NTSC;
+
+ *std = video_fmts[idx].v4l2_std;
+ state->fmt = &video_fmts[idx];
+
+ printk(KERN_INFO"video mode %s\n", video_fmts[idx].name);
+ return 0;
+}
+
+static int vadc_enum_mbus_code(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_mbus_code_enum *code)
+{
+ /* support only one format */
+ if (code->pad || code->index >= 1)
+ return -EINVAL;
+
+ code->code = MEDIA_BUS_FMT_AYUV8_1X32;
+ return 0;
+}
+
+static int vadc_get_fmt(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_format *format)
+{
+ struct vadc_state *state = to_state(sd);
+ struct v4l2_mbus_framefmt *fmt = &format->format;
+
+ if (format->pad)
+ return -EINVAL;
+
+ fmt->code = MEDIA_BUS_FMT_AYUV8_1X32;
+ fmt->colorspace = V4L2_COLORSPACE_SMPTE170M;
+ fmt->field = V4L2_FIELD_INTERLACED;
+ fmt->width = 720;
+ fmt->height = state->fmt->v4l2_std & V4L2_STD_NTSC ? 480 : 576;
+
+ return 0;
+}
+
+static int vadc_set_fmt(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_format *format)
+{
+ return vadc_get_fmt(sd, cfg, format);
+}
+
+static int vadc_enum_framesizes(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_frame_size_enum *fse)
+{
+ struct vadc_state *state = to_state(sd);
+ if (fse->index >= 1)
+ return -EINVAL;
+
+ fse->min_width = state->fmt->active_width;
+ fse->max_width = state->fmt->active_width;
+ fse->min_height = state->fmt->active_height;
+ fse->max_height = state->fmt->active_height;
+
+ return 0;
+}
+static int vadc_enum_frameintervals(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_frame_interval_enum *fie)
+{
+ struct vadc_state *state = to_state(sd);
+
+ if (fie->index < 0 || fie->index >= 1)
+ return -EINVAL;
+
+ fie->interval.numerator = 1;
+
+ fie->interval.denominator = state->fmt->framerates;
+
+ return 0;
+}
+
+static int vadc_s_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *parms)
+{
+ struct vadc_state *state = to_state(sd);
+
+ if (parms->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ return -EINVAL;
+
+ if (parms->parm.capture.timeperframe.denominator
+ != state->fmt->framerates)
+ parms->parm.capture.timeperframe.denominator
+ = state->fmt->framerates;
+
+ return 0;
+}
+
+static const struct v4l2_subdev_video_ops vadc_video_ops = {
+ .querystd = vadc_querystd,
+ .s_parm = vadc_s_parm,
+ .g_std = vadc_g_std,
+};
+
+
+static const struct v4l2_subdev_pad_ops vadc_pad_ops = {
+ .get_fmt = vadc_get_fmt,
+ .set_fmt = vadc_set_fmt,
+ .enum_mbus_code = vadc_enum_mbus_code,
+ .enum_frame_size = vadc_enum_framesizes,
+ .enum_frame_interval = vadc_enum_frameintervals,
+};
+
+static const struct v4l2_subdev_ops vadc_ops = {
+ .video = &vadc_video_ops,
+ .pad = &vadc_pad_ops,
+};
+
+static const struct of_device_id fsl_vadc_dt_ids[] = {
+ { .compatible = "fsl,imx6sx-vadc", },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, fsl_vadc_dt_ids);
+
+static int vadc_of_init(struct platform_device *pdev)
+{
+ struct device_node *np = pdev->dev.of_node;
+ struct device_node *gpc_np;
+ struct vadc_state *state = platform_get_drvdata(pdev);
+ int csi_id;
+ int ret;
+
+ /* Get csi_id to setting vadc to csi mux in gpr */
+ ret = of_property_read_u32(np, "csi_id", &csi_id);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to read of property csi_id\n");
+ return ret;
+ }
+
+ state->csi_id = csi_id;
+
+ /* remap GPR register */
+ state->gpr = syscon_regmap_lookup_by_phandle(pdev->dev.of_node,
+ "gpr");
+ if (IS_ERR(state->gpr)) {
+ dev_dbg(&pdev->dev, "can not get gpr\n");
+ return -ENOMEM;
+ }
+
+ /* Configuration vadc-to-csi 0 or 1 */
+ if (csi_id) {
+ regmap_update_bits(state->gpr, IOMUXC_GPR5,
+ IMX6SX_GPR5_CSI2_MUX_CTRL_MASK,
+ IMX6SX_GPR5_CSI2_MUX_CTRL_CVD);
+ } else {
+ regmap_update_bits(state->gpr, IOMUXC_GPR5,
+ IMX6SX_GPR5_CSI1_MUX_CTRL_MASK,
+ IMX6SX_GPR5_CSI1_MUX_CTRL_CVD);
+ }
+
+ /* Get default vadc_in number */
+ ret = of_property_read_u32(np, "vadc_in", &state->vadc_in);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to read of property vadc_in\n");
+ return ret;
+ }
+
+ /* map GPC register */
+ gpc_np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-gpc");
+ state->gpc_reg = of_iomap(gpc_np, 0);
+ if (!state->gpc_reg) {
+ dev_err(&pdev->dev, "ioremap failed with gpc base\n");
+ goto error;
+ }
+
+ return ret;
+
+error:
+ iounmap(state->gpc_reg);
+ return ret;
+}
+
+static void vadc_v4l2_subdev_init(struct v4l2_subdev *sd,
+ struct platform_device *pdev,
+ const struct v4l2_subdev_ops *ops)
+{
+ struct vadc_state *state = platform_get_drvdata(pdev);
+ int ret = 0;
+
+ v4l2_subdev_init(sd, ops);
+ sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+ sd->owner = pdev->dev.driver->owner;
+ sd->dev = &pdev->dev;
+
+ /* initialize name */
+ snprintf(sd->name, sizeof(sd->name), "%s",
+ pdev->dev.driver->name);
+
+ v4l2_set_subdevdata(sd, state);
+
+ ret = v4l2_async_register_subdev(sd);
+ if (ret < 0)
+ dev_err(&pdev->dev, "%s--Async register faialed, ret=%d\n", __func__, ret);
+}
+
+static int vadc_probe(struct platform_device *pdev)
+{
+ struct vadc_state *state;
+ struct v4l2_subdev *sd;
+ struct resource *res;
+ int ret = 0;
+
+ state = devm_kzalloc(&pdev->dev, sizeof(struct vadc_state), GFP_KERNEL);
+ if (!state) {
+ dev_err(&pdev->dev, "Cannot allocate device data\n");
+ return -ENOMEM;
+ }
+
+ /* Set initial values for the sensor struct. */
+ state->fmt = &video_fmts[VADC_NTSC];
+
+ sd = &state->sd;
+
+ /* map vafe address */
+ res = platform_get_resource_byname(pdev,
+ IORESOURCE_MEM, VAFE_REGS_ADDR_RES_NAME);
+ if (!res) {
+ dev_err(&pdev->dev, "No vafe base address found.\n");
+ return -ENOMEM;
+ }
+ vafe_regbase = devm_ioremap_resource(&pdev->dev, res);
+ if (!vafe_regbase) {
+ dev_err(&pdev->dev, "ioremap failed with vafe base\n");
+ return -ENOMEM;
+ }
+
+ /* map vdec address */
+ res = platform_get_resource_byname(pdev,
+ IORESOURCE_MEM, VDEC_REGS_ADDR_RES_NAME);
+ if (!res) {
+ dev_err(&pdev->dev, "No vdec base address found.\n");
+ return -ENODEV;
+ }
+ vdec_regbase = devm_ioremap_resource(&pdev->dev, res);
+ if (!vdec_regbase) {
+ dev_err(&pdev->dev, "ioremap failed with vdec base\n");
+ return -ENOMEM;
+ }
+
+ /* Get clock */
+ state->vadc_clk = devm_clk_get(&pdev->dev, "vadc");
+ if (IS_ERR(state->vadc_clk)) {
+ ret = PTR_ERR(state->vadc_clk);
+ return ret;
+ }
+
+ state->csi_clk = devm_clk_get(&pdev->dev, "csi");
+ if (IS_ERR(state->csi_clk)) {
+ ret = PTR_ERR(state->csi_clk);
+ return ret;
+ }
+
+ /* clock */
+ clk_prepare_enable(state->csi_clk);
+ clk_prepare_enable(state->vadc_clk);
+
+ platform_set_drvdata(pdev, state);
+
+ vadc_v4l2_subdev_init(sd, pdev, &vadc_ops);
+
+ pm_runtime_enable(&pdev->dev);
+
+ pm_runtime_get_sync(&pdev->dev);
+ /* Init VADC */
+ ret = vadc_of_init(pdev);
+ if (ret < 0)
+ goto err;
+ vadc_init(state);
+
+ pr_info("vadc driver loaded\n");
+
+ return 0;
+err:
+ pm_runtime_put_sync(&pdev->dev);
+ pm_runtime_disable(&pdev->dev);
+ v4l2_async_unregister_subdev(&state->sd);
+ clk_disable_unprepare(state->csi_clk);
+ clk_disable_unprepare(state->vadc_clk);
+ return ret;
+}
+
+static int vadc_remove(struct platform_device *pdev)
+{
+ struct vadc_state *state = platform_get_drvdata(pdev);
+
+ pm_runtime_put_sync(&pdev->dev);
+ pm_runtime_disable(&pdev->dev);
+ v4l2_async_unregister_subdev(&state->sd);
+ clk_disable_unprepare(state->csi_clk);
+ clk_disable_unprepare(state->vadc_clk);
+
+ vadc_power_down(state);
+ return true;
+}
+
+static int vadc_suspend(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct vadc_state *state = platform_get_drvdata(pdev);
+
+ clk_disable(state->csi_clk);
+ clk_disable(state->vadc_clk);
+
+ vadc_power_down(state);
+
+ return 0;
+}
+
+static int vadc_resume(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct vadc_state *state = platform_get_drvdata(pdev);
+
+ clk_enable(state->csi_clk);
+ clk_enable(state->vadc_clk);
+
+ vadc_init(state);
+ return 0;
+}
+
+static const struct dev_pm_ops vadc_pm_ops = {
+ SET_SYSTEM_SLEEP_PM_OPS(vadc_suspend, vadc_resume)
+};
+
+static struct platform_driver vadc_driver = {
+ .driver = {
+ .name = "fsl_vadc",
+ .of_match_table = of_match_ptr(fsl_vadc_dt_ids),
+ .pm = &vadc_pm_ops,
+ },
+ .probe = vadc_probe,
+ .remove = vadc_remove,
+};
+
+module_platform_driver(vadc_driver);
+
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("fsl VADC/VDEC driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/platform/mxc/capture/mxc_vadc.h b/drivers/media/platform/mxc/capture/mxc_vadc.h
new file mode 100644
index 000000000000..d5c1389cbc58
--- /dev/null
+++ b/drivers/media/platform/mxc/capture/mxc_vadc.h
@@ -0,0 +1,239 @@
+/*
+ * Copyright (C) 2011-2015 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef MXC_VDEC_H
+#define MXC_VDEC_H
+
+/*** define base address ***/
+#define VDEC_BASE vdec_regbase
+#define AFE_BASE vafe_regbase
+
+/* AFE - Register offsets */
+#define AFE_BLOCK_ID_OFFSET 0x00000000
+#define AFE_PDBUF_OFFSET 0x00000004
+#define AFE_SWRST_OFFSET 0x00000008
+#define AFE_TSTSEL_OFFSET 0x0000000c
+#define AFE_TSTMSC_OFFSET 0x00000010
+#define AFE_ENPADIO_OFFSET 0x00000014
+#define AFE_BGREG_OFFSET 0x00000018
+#define AFE_ACCESSAR_ID_OFFSET 0x00000400
+#define AFE_PDADC_OFFSET 0x00000404
+#define AFE_PDSARH_OFFSET 0x00000408
+#define AFE_PDSARL_OFFSET 0x0000040C
+#define AFE_PDADCRFH_OFFSET 0x00000410
+#define AFE_PDADCRFL_OFFSET 0x00000414
+#define AFE_ACCTST_OFFSET 0x00000418
+#define AFE_ADCGN_OFFSET 0x0000041C
+#define AFE_ICTRL_OFFSET 0x00000420
+#define AFE_ICTLSTG_OFFSET 0x00000424
+#define AFE_RCTRLSTG_OFFSET 0x00000428
+#define AFE_TCTRLSTG_OFFSET 0x0000042c
+#define AFE_REFMOD_OFFSET 0x00000430
+#define AFE_REFTRIML_OFFSET 0x00000434
+#define AFE_REFTRIMH_OFFSET 0x00000438
+#define AFE_ADCR_OFFSET 0x0000043c
+#define AFE_DUMMY0_OFFSET 0x00000440
+#define AFE_DUMMY1_OFFSET 0x00000444
+#define AFE_DUMMY2_OFFSET 0x00000448
+#define AFE_DACAMP_OFFSET 0x0000044c
+#define AFE_CLMPTST_OFFSET 0x00000450
+#define AFE_CLMPDAT_OFFSET 0x00000454
+#define AFE_CLMPAMP_OFFSET 0x00000458
+#define AFE_CLAMP_OFFSET 0x0000045c
+#define AFE_INPBUF_OFFSET 0x00000460
+#define AFE_INPFLT_OFFSET 0x00000464
+#define AFE_ADCDGN_OFFSET 0x00000468
+#define AFE_OFFDRV_OFFSET 0x0000046c
+#define AFE_INPCONFIG_OFFSET 0x00000470
+#define AFE_PROGDELAY_OFFSET 0x00000474
+#define AFE_ADCOMT_OFFSET 0x00000478
+#define AFE_ALGDELAY_OFFSET 0x0000047c
+#define AFE_ACC_ID_OFFSET 0x00000800
+#define AFE_ACCSTA_OFFSET 0x00000804
+#define AFE_ACCNOSLI_OFFSET 0x00000808
+#define AFE_ACCCALCON_OFFSET 0x0000080c
+#define AFE_BWEWRICTRL_OFFSET 0x00000810
+#define AFE_SELSLI_OFFSET 0x00000814
+#define AFE_SELBYT_OFFSET 0x00000818
+#define AFE_REDVAL_OFFSET 0x00000820
+#define AFE_WRIBYT_OFFSET 0x00000824
+
+/* AFE Register per module */
+#define AFE_BLOCK_ID (AFE_BASE + AFE_BLOCK_ID_OFFSET)
+#define AFE_PDBUF (AFE_BASE + AFE_PDBUF_OFFSET)
+#define AFE_SWRST (AFE_BASE + AFE_SWRST_OFFSET)
+#define AFE_TSTSEL (AFE_BASE + AFE_TSTSEL_OFFSET)
+#define AFE_TSTMSC (AFE_BASE + AFE_TSTMSC_OFFSET)
+#define AFE_ENPADIO (AFE_BASE + AFE_ENPADIO_OFFSET)
+#define AFE_BGREG (AFE_BASE + AFE_BGREG_OFFSET)
+#define AFE_ACCESSAR_ID (AFE_BASE + AFE_ACCESSAR_ID_OFFSET)
+#define AFE_PDADC (AFE_BASE + AFE_PDADC_OFFSET)
+#define AFE_PDSARH (AFE_BASE + AFE_PDSARH_OFFSET)
+#define AFE_PDSARL (AFE_BASE + AFE_PDSARL_OFFSET)
+#define AFE_PDADCRFH (AFE_BASE + AFE_PDADCRFH_OFFSET)
+#define AFE_PDADCRFL (AFE_BASE + AFE_PDADCRFL_OFFSET)
+#define AFE_ACCTST (AFE_BASE + AFE_ACCTST_OFFSET)
+#define AFE_ADCGN (AFE_BASE + AFE_ADCGN_OFFSET)
+#define AFE_ICTRL (AFE_BASE + AFE_ICTRL_OFFSET)
+#define AFE_ICTLSTG (AFE_BASE + AFE_ICTLSTG_OFFSET)
+#define AFE_RCTRLSTG (AFE_BASE + AFE_RCTRLSTG_OFFSET)
+#define AFE_TCTRLSTG (AFE_BASE + AFE_TCTRLSTG_OFFSET)
+#define AFE_REFMOD (AFE_BASE + AFE_REFMOD_OFFSET)
+#define AFE_REFTRIML (AFE_BASE + AFE_REFTRIML_OFFSET)
+#define AFE_REFTRIMH (AFE_BASE + AFE_REFTRIMH_OFFSET)
+#define AFE_ADCR (AFE_BASE + AFE_ADCR_OFFSET)
+#define AFE_DUMMY0 (AFE_BASE + AFE_DUMMY0_OFFSET)
+#define AFE_DUMMY1 (AFE_BASE + AFE_DUMMY1_OFFSET)
+#define AFE_DUMMY2 (AFE_BASE + AFE_DUMMY2_OFFSET)
+#define AFE_DACAMP (AFE_BASE + AFE_DACAMP_OFFSET)
+#define AFE_CLMPTST (AFE_BASE + AFE_CLMPTST_OFFSET)
+#define AFE_CLMPDAT (AFE_BASE + AFE_CLMPDAT_OFFSET)
+#define AFE_CLMPAMP (AFE_BASE + AFE_CLMPAMP_OFFSET)
+#define AFE_CLAMP (AFE_BASE + AFE_CLAMP_OFFSET)
+#define AFE_INPBUF (AFE_BASE + AFE_INPBUF_OFFSET)
+#define AFE_INPFLT (AFE_BASE + AFE_INPFLT_OFFSET)
+#define AFE_ADCDGN (AFE_BASE + AFE_ADCDGN_OFFSET)
+#define AFE_OFFDRV (AFE_BASE + AFE_OFFDRV_OFFSET)
+#define AFE_INPCONFIG (AFE_BASE + AFE_INPCONFIG_OFFSET)
+#define AFE_PROGDELAY (AFE_BASE + AFE_PROGDELAY_OFFSET)
+#define AFE_ADCOMT (AFE_BASE + AFE_ADCOMT_OFFSET)
+#define AFE_ALGDELAY (AFE_BASE + AFE_ALGDELAY_OFFSET)
+#define AFE_ACC_ID (AFE_BASE + AFE_ACC_ID_OFFSET)
+#define AFE_ACCSTA (AFE_BASE + AFE_ACCSTA_OFFSET)
+#define AFE_ACCNOSLI (AFE_BASE + AFE_ACCNOSLI_OFFSET)
+#define AFE_ACCCALCON (AFE_BASE + AFE_ACCCALCON_OFFSET)
+#define AFE_BWEWRICTRL (AFE_BASE + AFE_BWEWRICTRL_OFFSET)
+#define AFE_SELSLI (AFE_BASE + AFE_SELSLI_OFFSET)
+#define AFE_SELBYT (AFE_BASE + AFE_SELBYT_OFFSET)
+#define AFE_REDVAL (AFE_BASE + AFE_REDVAL_OFFSET)
+#define AFE_WRIBYT (AFE_BASE + AFE_WRIBYT_OFFSET)
+
+/* VDEC - Register offsets */
+#define VDEC_CFC1_OFFSET 0x00000000
+#define VDEC_CFC2_OFFSET 0x00000004
+#define VDEC_BRSTGT_OFFSET 0x00000024
+#define VDEC_HZPOS_OFFSET 0x00000040
+#define VDEC_VRTPOS_OFFSET 0x00000044
+#define VDEC_HVSHIFT_OFFSET 0x00000054
+#define VDEC_HSIGS_OFFSET 0x00000058
+#define VDEC_HSIGE_OFFSET 0x0000005C
+#define VDEC_VSCON1_OFFSET 0x00000060
+#define VDEC_VSCON2_OFFSET 0x00000064
+#define VDEC_YCDEL_OFFSET 0x0000006C
+#define VDEC_AFTCLP_OFFSET 0x00000070
+#define VDEC_DCOFF_OFFSET 0x00000078
+#define VDEC_CSID_OFFSET 0x00000084
+#define VDEC_CBGN_OFFSET 0x00000088
+#define VDEC_CRGN_OFFSET 0x0000008C
+#define VDEC_CNTR_OFFSET 0x00000090
+#define VDEC_BRT_OFFSET 0x00000094
+#define VDEC_HUE_OFFSET 0x00000098
+#define VDEC_CHBTH_OFFSET 0x0000009C
+#define VDEC_SHPIMP_OFFSET 0x000000A4
+#define VDEC_CHPLLIM_OFFSET 0x000000A8
+#define VDEC_VIDMOD_OFFSET 0x000000AC
+#define VDEC_VIDSTS_OFFSET 0x000000B0
+#define VDEC_NOISE_OFFSET 0x000000B4
+#define VDEC_STDDBG_OFFSET 0x000000B8
+#define VDEC_MANOVR_OFFSET 0x000000BC
+#define VDEC_VSSGTH_OFFSET 0x000000C8
+#define VDEC_DBGFBH_OFFSET 0x000000D0
+#define VDEC_DBGFBL_OFFSET 0x000000D4
+#define VDEC_HACTS_OFFSET 0x000000D8
+#define VDEC_HACTE_OFFSET 0x000000DC
+#define VDEC_VACTS_OFFSET 0x000000E0
+#define VDEC_VACTE_OFFSET 0x000000E4
+#define VDEC_HSTIP_OFFSET 0x000000EC
+#define VDEC_BLSCRY_OFFSET 0x000000F4
+#define VDEC_BLSCRCR_OFFSET 0x000000F8
+#define VDEC_BLSCRCB_OFFSET 0x000000FC
+#define VDEC_LMAGC1_OFFSET 0x00000100
+#define VDEC_LMAGC2_OFFSET 0x00000104
+#define VDEC_CHAGC1_OFFSET 0x00000108
+#define VDEC_CHAGC2_OFFSET 0x0000010C
+#define VDEC_MINTH_OFFSET 0x00000114
+#define VDEC_VFRQOH_OFFSET 0x0000011C
+#define VDEC_VFRQOL_OFFSET 0x00000120
+#define VDEC_THSH1_OFFSET 0x00000124
+#define VDEC_THSH2_OFFSET 0x00000128
+#define VDEC_NCHTH_OFFSET 0x0000012C
+#define VDEC_TH1F_OFFSET 0x00000130
+
+/* VDEC Register per module */
+#define VDEC_CFC1 (VDEC_BASE + VDEC_CFC1_OFFSET)
+#define VDEC_CFC2 (VDEC_BASE + VDEC_CFC2_OFFSET)
+#define VDEC_BRSTGT (VDEC_BASE + VDEC_BRSTGT_OFFSET)
+#define VDEC_HZPOS (VDEC_BASE + VDEC_HZPOS_OFFSET)
+#define VDEC_VRTPOS (VDEC_BASE + VDEC_VRTPOS_OFFSET)
+#define VDEC_HVSHIFT (VDEC_BASE + VDEC_HVSHIFT_OFFSET)
+#define VDEC_HSIGS (VDEC_BASE + VDEC_HSIGS_OFFSET)
+#define VDEC_HSIGE (VDEC_BASE + VDEC_HSIGE_OFFSET)
+#define VDEC_VSCON1 (VDEC_BASE + VDEC_VSCON1_OFFSET)
+#define VDEC_VSCON2 (VDEC_BASE + VDEC_VSCON2_OFFSET)
+#define VDEC_YCDEL (VDEC_BASE + VDEC_YCDEL_OFFSET)
+#define VDEC_AFTCLP (VDEC_BASE + VDEC_AFTCLP_OFFSET)
+#define VDEC_DCOFF (VDEC_BASE + VDEC_DCOFF_OFFSET)
+#define VDEC_CSID (VDEC_BASE + VDEC_CSID_OFFSET)
+#define VDEC_CBGN (VDEC_BASE + VDEC_CBGN_OFFSET)
+#define VDEC_CRGN (VDEC_BASE + VDEC_CRGN_OFFSET)
+#define VDEC_CNTR (VDEC_BASE + VDEC_CNTR_OFFSET)
+#define VDEC_BRT (VDEC_BASE + VDEC_BRT_OFFSET)
+#define VDEC_HUE (VDEC_BASE + VDEC_HUE_OFFSET)
+#define VDEC_CHBTH (VDEC_BASE + VDEC_CHBTH_OFFSET)
+#define VDEC_SHPIMP (VDEC_BASE + VDEC_SHPIMP_OFFSET)
+#define VDEC_CHPLLIM (VDEC_BASE + VDEC_CHPLLIM_OFFSET)
+#define VDEC_VIDMOD (VDEC_BASE + VDEC_VIDMOD_OFFSET)
+#define VDEC_VIDSTS (VDEC_BASE + VDEC_VIDSTS_OFFSET)
+#define VDEC_NOISE (VDEC_BASE + VDEC_NOISE_OFFSET)
+#define VDEC_STDDBG (VDEC_BASE + VDEC_STDDBG_OFFSET)
+#define VDEC_MANOVR (VDEC_BASE + VDEC_MANOVR_OFFSET)
+#define VDEC_VSSGTH (VDEC_BASE + VDEC_VSSGTH_OFFSET)
+#define VDEC_DBGFBH (VDEC_BASE + VDEC_DBGFBH_OFFSET)
+#define VDEC_DBGFBL (VDEC_BASE + VDEC_DBGFBL_OFFSET)
+#define VDEC_HACTS (VDEC_BASE + VDEC_HACTS_OFFSET)
+#define VDEC_HACTE (VDEC_BASE + VDEC_HACTE_OFFSET)
+#define VDEC_VACTS (VDEC_BASE + VDEC_VACTS_OFFSET)
+#define VDEC_VACTE (VDEC_BASE + VDEC_VACTE_OFFSET)
+#define VDEC_HSTIP (VDEC_BASE + VDEC_HSTIP_OFFSET)
+#define VDEC_BLSCRY (VDEC_BASE + VDEC_BLSCRY_OFFSET)
+#define VDEC_BLSCRCR (VDEC_BASE + VDEC_BLSCRCR_OFFSET)
+#define VDEC_BLSCRCB (VDEC_BASE + VDEC_BLSCRCB_OFFSET)
+#define VDEC_LMAGC1 (VDEC_BASE + VDEC_LMAGC1_OFFSET)
+#define VDEC_LMAGC2 (VDEC_BASE + VDEC_LMAGC2_OFFSET)
+#define VDEC_CHAGC1 (VDEC_BASE + VDEC_CHAGC1_OFFSET)
+#define VDEC_CHAGC2 (VDEC_BASE + VDEC_CHAGC2_OFFSET)
+#define VDEC_MINTH (VDEC_BASE + VDEC_MINTH_OFFSET)
+#define VDEC_VFRQOH (VDEC_BASE + VDEC_VFRQOH_OFFSET)
+#define VDEC_VFRQOL (VDEC_BASE + VDEC_VFRQOL_OFFSET)
+#define VDEC_THSH1 (VDEC_BASE + VDEC_THSH1_OFFSET)
+#define VDEC_THSH2 (VDEC_BASE + VDEC_THSH2_OFFSET)
+#define VDEC_NCHTH (VDEC_BASE + VDEC_NCHTH_OFFSET)
+#define VDEC_TH1F (VDEC_BASE + VDEC_TH1F_OFFSET)
+
+#define VDEC_VIDMOD_SIGNAL_MASK 0x0F
+#define VDEC_VIDMOD_SIGNAL_DETECT 0x0F
+
+#define VDEC_VIDMOD_M625_SHIFT 4
+#define VDEC_VIDMOD_M625_MASK (1 << VDEC_VIDMOD_M625_SHIFT)
+
+#define VDEC_VIDMOD_PAL_SHIFT 7
+#define VDEC_VIDMOD_PAL_MASK (1 << VDEC_VIDMOD_PAL_SHIFT)
+/*** define base address ***/
+
+#endif
diff --git a/drivers/media/platform/mxc/capture/ov5640.c b/drivers/media/platform/mxc/capture/ov5640.c
new file mode 100644
index 000000000000..ec8b8090201d
--- /dev/null
+++ b/drivers/media/platform/mxc/capture/ov5640.c
@@ -0,0 +1,1950 @@
+/*
+ * Copyright (C) 2012-2015 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/i2c.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/of_gpio.h>
+#include <linux/pinctrl/consumer.h>
+#include <linux/regulator/consumer.h>
+#include <media/v4l2-chip-ident.h>
+#include "v4l2-int-device.h"
+#include "mxc_v4l2_capture.h"
+
+#define OV5640_VOLTAGE_ANALOG 2800000
+#define OV5640_VOLTAGE_DIGITAL_CORE 1500000
+#define OV5640_VOLTAGE_DIGITAL_IO 1800000
+
+#define MIN_FPS 15
+#define MAX_FPS 30
+#define DEFAULT_FPS 30
+
+#define OV5640_XCLK_MIN 6000000
+#define OV5640_XCLK_MAX 24000000
+
+#define OV5640_CHIP_ID_HIGH_BYTE 0x300A
+#define OV5640_CHIP_ID_LOW_BYTE 0x300B
+
+enum ov5640_mode {
+ ov5640_mode_MIN = 0,
+ ov5640_mode_VGA_640_480 = 0,
+ ov5640_mode_QVGA_320_240 = 1,
+ ov5640_mode_NTSC_720_480 = 2,
+ ov5640_mode_PAL_720_576 = 3,
+ ov5640_mode_720P_1280_720 = 4,
+ ov5640_mode_1080P_1920_1080 = 5,
+ ov5640_mode_QSXGA_2592_1944 = 6,
+ ov5640_mode_QCIF_176_144 = 7,
+ ov5640_mode_XGA_1024_768 = 8,
+ ov5640_mode_MAX = 8
+};
+
+enum ov5640_frame_rate {
+ ov5640_15_fps,
+ ov5640_30_fps
+};
+
+static int ov5640_framerates[] = {
+ [ov5640_15_fps] = 15,
+ [ov5640_30_fps] = 30,
+};
+
+struct reg_value {
+ u16 u16RegAddr;
+ u8 u8Val;
+ u8 u8Mask;
+ u32 u32Delay_ms;
+};
+
+struct ov5640_mode_info {
+ enum ov5640_mode mode;
+ u32 width;
+ u32 height;
+ struct reg_value *init_data_ptr;
+ u32 init_data_size;
+};
+
+/*!
+ * Maintains the information on the current state of the sesor.
+ */
+static struct sensor_data ov5640_data;
+static int pwn_gpio, rst_gpio;
+static int prev_sysclk;
+static int AE_Target = 52, night_mode;
+static int prev_HTS;
+static int AE_high, AE_low;
+
+static struct reg_value ov5640_global_init_setting[] = {
+ {0x3008, 0x42, 0, 0},
+ {0x3103, 0x03, 0, 0}, {0x3017, 0xff, 0, 0}, {0x3018, 0xff, 0, 0},
+ {0x3034, 0x1a, 0, 0}, {0x3037, 0x13, 0, 0}, {0x3108, 0x01, 0, 0},
+ {0x3630, 0x36, 0, 0}, {0x3631, 0x0e, 0, 0}, {0x3632, 0xe2, 0, 0},
+ {0x3633, 0x12, 0, 0}, {0x3621, 0xe0, 0, 0}, {0x3704, 0xa0, 0, 0},
+ {0x3703, 0x5a, 0, 0}, {0x3715, 0x78, 0, 0}, {0x3717, 0x01, 0, 0},
+ {0x370b, 0x60, 0, 0}, {0x3705, 0x1a, 0, 0}, {0x3905, 0x02, 0, 0},
+ {0x3906, 0x10, 0, 0}, {0x3901, 0x0a, 0, 0}, {0x3731, 0x12, 0, 0},
+ {0x3600, 0x08, 0, 0}, {0x3601, 0x33, 0, 0}, {0x302d, 0x60, 0, 0},
+ {0x3620, 0x52, 0, 0}, {0x371b, 0x20, 0, 0}, {0x471c, 0x50, 0, 0},
+ {0x3a13, 0x43, 0, 0}, {0x3a18, 0x00, 0, 0}, {0x3a19, 0x7c, 0, 0},
+ {0x3635, 0x13, 0, 0}, {0x3636, 0x03, 0, 0}, {0x3634, 0x40, 0, 0},
+ {0x3622, 0x01, 0, 0}, {0x3c01, 0x34, 0, 0}, {0x3c04, 0x28, 0, 0},
+ {0x3c05, 0x98, 0, 0}, {0x3c06, 0x00, 0, 0}, {0x3c07, 0x07, 0, 0},
+ {0x3c08, 0x00, 0, 0}, {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0},
+ {0x3c0b, 0x40, 0, 0}, {0x3810, 0x00, 0, 0}, {0x3811, 0x10, 0, 0},
+ {0x3812, 0x00, 0, 0}, {0x3708, 0x64, 0, 0}, {0x4001, 0x02, 0, 0},
+ {0x4005, 0x1a, 0, 0}, {0x3000, 0x00, 0, 0}, {0x3004, 0xff, 0, 0},
+ {0x300e, 0x58, 0, 0}, {0x302e, 0x00, 0, 0}, {0x4300, 0x30, 0, 0},
+ {0x501f, 0x00, 0, 0}, {0x440e, 0x00, 0, 0}, {0x5000, 0xa7, 0, 0},
+ {0x3008, 0x02, 0, 0},
+};
+
+static struct reg_value ov5640_init_setting_30fps_VGA[] = {
+ {0x3008, 0x42, 0, 0},
+ {0x3103, 0x03, 0, 0}, {0x3017, 0xff, 0, 0}, {0x3018, 0xff, 0, 0},
+ {0x3034, 0x1a, 0, 0}, {0x3035, 0x11, 0, 0}, {0x3036, 0x46, 0, 0},
+ {0x3037, 0x13, 0, 0}, {0x3108, 0x01, 0, 0}, {0x3630, 0x36, 0, 0},
+ {0x3631, 0x0e, 0, 0}, {0x3632, 0xe2, 0, 0}, {0x3633, 0x12, 0, 0},
+ {0x3621, 0xe0, 0, 0}, {0x3704, 0xa0, 0, 0}, {0x3703, 0x5a, 0, 0},
+ {0x3715, 0x78, 0, 0}, {0x3717, 0x01, 0, 0}, {0x370b, 0x60, 0, 0},
+ {0x3705, 0x1a, 0, 0}, {0x3905, 0x02, 0, 0}, {0x3906, 0x10, 0, 0},
+ {0x3901, 0x0a, 0, 0}, {0x3731, 0x12, 0, 0}, {0x3600, 0x08, 0, 0},
+ {0x3601, 0x33, 0, 0}, {0x302d, 0x60, 0, 0}, {0x3620, 0x52, 0, 0},
+ {0x371b, 0x20, 0, 0}, {0x471c, 0x50, 0, 0}, {0x3a13, 0x43, 0, 0},
+ {0x3a18, 0x00, 0, 0}, {0x3a19, 0xf8, 0, 0}, {0x3635, 0x13, 0, 0},
+ {0x3636, 0x03, 0, 0}, {0x3634, 0x40, 0, 0}, {0x3622, 0x01, 0, 0},
+ {0x3c01, 0x34, 0, 0}, {0x3c04, 0x28, 0, 0}, {0x3c05, 0x98, 0, 0},
+ {0x3c06, 0x00, 0, 0}, {0x3c07, 0x08, 0, 0}, {0x3c08, 0x00, 0, 0},
+ {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
+ {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0},
+ {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
+ {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0}, {0x3804, 0x0a, 0, 0},
+ {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9b, 0, 0},
+ {0x3808, 0x02, 0, 0}, {0x3809, 0x80, 0, 0}, {0x380a, 0x01, 0, 0},
+ {0x380b, 0xe0, 0, 0}, {0x380c, 0x07, 0, 0}, {0x380d, 0x68, 0, 0},
+ {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0}, {0x3810, 0x00, 0, 0},
+ {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x06, 0, 0},
+ {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0},
+ {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x03, 0, 0},
+ {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0},
+ {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0},
+ {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0},
+ {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x3000, 0x00, 0, 0},
+ {0x3002, 0x1c, 0, 0}, {0x3004, 0xff, 0, 0}, {0x3006, 0xc3, 0, 0},
+ {0x300e, 0x58, 0, 0}, {0x302e, 0x00, 0, 0}, {0x4300, 0x30, 0, 0},
+ {0x501f, 0x00, 0, 0}, {0x4713, 0x03, 0, 0}, {0x4407, 0x04, 0, 0},
+ {0x440e, 0x00, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0},
+ {0x4837, 0x22, 0, 0}, {0x3824, 0x02, 0, 0}, {0x5000, 0xa7, 0, 0},
+ {0x5001, 0xa3, 0, 0}, {0x5180, 0xff, 0, 0}, {0x5181, 0xf2, 0, 0},
+ {0x5182, 0x00, 0, 0}, {0x5183, 0x14, 0, 0}, {0x5184, 0x25, 0, 0},
+ {0x5185, 0x24, 0, 0}, {0x5186, 0x09, 0, 0}, {0x5187, 0x09, 0, 0},
+ {0x5188, 0x09, 0, 0}, {0x5189, 0x88, 0, 0}, {0x518a, 0x54, 0, 0},
+ {0x518b, 0xee, 0, 0}, {0x518c, 0xb2, 0, 0}, {0x518d, 0x50, 0, 0},
+ {0x518e, 0x34, 0, 0}, {0x518f, 0x6b, 0, 0}, {0x5190, 0x46, 0, 0},
+ {0x5191, 0xf8, 0, 0}, {0x5192, 0x04, 0, 0}, {0x5193, 0x70, 0, 0},
+ {0x5194, 0xf0, 0, 0}, {0x5195, 0xf0, 0, 0}, {0x5196, 0x03, 0, 0},
+ {0x5197, 0x01, 0, 0}, {0x5198, 0x04, 0, 0}, {0x5199, 0x6c, 0, 0},
+ {0x519a, 0x04, 0, 0}, {0x519b, 0x00, 0, 0}, {0x519c, 0x09, 0, 0},
+ {0x519d, 0x2b, 0, 0}, {0x519e, 0x38, 0, 0}, {0x5381, 0x1e, 0, 0},
+ {0x5382, 0x5b, 0, 0}, {0x5383, 0x08, 0, 0}, {0x5384, 0x0a, 0, 0},
+ {0x5385, 0x7e, 0, 0}, {0x5386, 0x88, 0, 0}, {0x5387, 0x7c, 0, 0},
+ {0x5388, 0x6c, 0, 0}, {0x5389, 0x10, 0, 0}, {0x538a, 0x01, 0, 0},
+ {0x538b, 0x98, 0, 0}, {0x5300, 0x08, 0, 0}, {0x5301, 0x30, 0, 0},
+ {0x5302, 0x10, 0, 0}, {0x5303, 0x00, 0, 0}, {0x5304, 0x08, 0, 0},
+ {0x5305, 0x30, 0, 0}, {0x5306, 0x08, 0, 0}, {0x5307, 0x16, 0, 0},
+ {0x5309, 0x08, 0, 0}, {0x530a, 0x30, 0, 0}, {0x530b, 0x04, 0, 0},
+ {0x530c, 0x06, 0, 0}, {0x5480, 0x01, 0, 0}, {0x5481, 0x08, 0, 0},
+ {0x5482, 0x14, 0, 0}, {0x5483, 0x28, 0, 0}, {0x5484, 0x51, 0, 0},
+ {0x5485, 0x65, 0, 0}, {0x5486, 0x71, 0, 0}, {0x5487, 0x7d, 0, 0},
+ {0x5488, 0x87, 0, 0}, {0x5489, 0x91, 0, 0}, {0x548a, 0x9a, 0, 0},
+ {0x548b, 0xaa, 0, 0}, {0x548c, 0xb8, 0, 0}, {0x548d, 0xcd, 0, 0},
+ {0x548e, 0xdd, 0, 0}, {0x548f, 0xea, 0, 0}, {0x5490, 0x1d, 0, 0},
+ {0x5580, 0x02, 0, 0}, {0x5583, 0x40, 0, 0}, {0x5584, 0x10, 0, 0},
+ {0x5589, 0x10, 0, 0}, {0x558a, 0x00, 0, 0}, {0x558b, 0xf8, 0, 0},
+ {0x5800, 0x23, 0, 0}, {0x5801, 0x14, 0, 0}, {0x5802, 0x0f, 0, 0},
+ {0x5803, 0x0f, 0, 0}, {0x5804, 0x12, 0, 0}, {0x5805, 0x26, 0, 0},
+ {0x5806, 0x0c, 0, 0}, {0x5807, 0x08, 0, 0}, {0x5808, 0x05, 0, 0},
+ {0x5809, 0x05, 0, 0}, {0x580a, 0x08, 0, 0}, {0x580b, 0x0d, 0, 0},
+ {0x580c, 0x08, 0, 0}, {0x580d, 0x03, 0, 0}, {0x580e, 0x00, 0, 0},
+ {0x580f, 0x00, 0, 0}, {0x5810, 0x03, 0, 0}, {0x5811, 0x09, 0, 0},
+ {0x5812, 0x07, 0, 0}, {0x5813, 0x03, 0, 0}, {0x5814, 0x00, 0, 0},
+ {0x5815, 0x01, 0, 0}, {0x5816, 0x03, 0, 0}, {0x5817, 0x08, 0, 0},
+ {0x5818, 0x0d, 0, 0}, {0x5819, 0x08, 0, 0}, {0x581a, 0x05, 0, 0},
+ {0x581b, 0x06, 0, 0}, {0x581c, 0x08, 0, 0}, {0x581d, 0x0e, 0, 0},
+ {0x581e, 0x29, 0, 0}, {0x581f, 0x17, 0, 0}, {0x5820, 0x11, 0, 0},
+ {0x5821, 0x11, 0, 0}, {0x5822, 0x15, 0, 0}, {0x5823, 0x28, 0, 0},
+ {0x5824, 0x46, 0, 0}, {0x5825, 0x26, 0, 0}, {0x5826, 0x08, 0, 0},
+ {0x5827, 0x26, 0, 0}, {0x5828, 0x64, 0, 0}, {0x5829, 0x26, 0, 0},
+ {0x582a, 0x24, 0, 0}, {0x582b, 0x22, 0, 0}, {0x582c, 0x24, 0, 0},
+ {0x582d, 0x24, 0, 0}, {0x582e, 0x06, 0, 0}, {0x582f, 0x22, 0, 0},
+ {0x5830, 0x40, 0, 0}, {0x5831, 0x42, 0, 0}, {0x5832, 0x24, 0, 0},
+ {0x5833, 0x26, 0, 0}, {0x5834, 0x24, 0, 0}, {0x5835, 0x22, 0, 0},
+ {0x5836, 0x22, 0, 0}, {0x5837, 0x26, 0, 0}, {0x5838, 0x44, 0, 0},
+ {0x5839, 0x24, 0, 0}, {0x583a, 0x26, 0, 0}, {0x583b, 0x28, 0, 0},
+ {0x583c, 0x42, 0, 0}, {0x583d, 0xce, 0, 0}, {0x5025, 0x00, 0, 0},
+ {0x3a0f, 0x30, 0, 0}, {0x3a10, 0x28, 0, 0}, {0x3a1b, 0x30, 0, 0},
+ {0x3a1e, 0x26, 0, 0}, {0x3a11, 0x60, 0, 0}, {0x3a1f, 0x14, 0, 0},
+ {0x3008, 0x02, 0, 0}, {0x3034, 0x1a, 0, 0}, {0x3035, 0x11, 0, 0},
+ {0x3036, 0x46, 0, 0}, {0x3037, 0x13, 0, 0},
+};
+
+static struct reg_value ov5640_setting_30fps_VGA_640_480[] = {
+ {0x3c07, 0x08, 0, 0}, {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0},
+ {0x3814, 0x31, 0, 0}, {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0},
+ {0x3801, 0x00, 0, 0}, {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0},
+ {0x3804, 0x0a, 0, 0}, {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0},
+ {0x3807, 0x9b, 0, 0}, {0x3808, 0x02, 0, 0}, {0x3809, 0x80, 0, 0},
+ {0x380a, 0x01, 0, 0}, {0x380b, 0xe0, 0, 0}, {0x380c, 0x07, 0, 0},
+ {0x380d, 0x68, 0, 0}, {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0},
+ {0x3813, 0x06, 0, 0}, {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0},
+ {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x0b, 0, 0},
+ {0x3a03, 0x88, 0, 0}, {0x3a14, 0x0b, 0, 0}, {0x3a15, 0x88, 0, 0},
+ {0x4004, 0x02, 0, 0}, {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0},
+ {0x4713, 0x03, 0, 0}, {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0},
+ {0x460c, 0x22, 0, 0}, {0x4837, 0x22, 0, 0}, {0x3824, 0x02, 0, 0},
+ {0x5001, 0xa3, 0, 0}, {0x3034, 0x1a, 0, 0}, {0x3035, 0x11, 0, 0},
+ {0x3036, 0x46, 0, 0}, {0x3037, 0x13, 0, 0}, {0x3503, 0x00, 0, 0},
+};
+
+static struct reg_value ov5640_setting_15fps_VGA_640_480[] = {
+ {0x3c07, 0x08, 0, 0}, {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0},
+ {0x3814, 0x31, 0, 0}, {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0},
+ {0x3801, 0x00, 0, 0}, {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0},
+ {0x3804, 0x0a, 0, 0}, {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0},
+ {0x3807, 0x9b, 0, 0}, {0x3808, 0x02, 0, 0}, {0x3809, 0x80, 0, 0},
+ {0x380a, 0x01, 0, 0}, {0x380b, 0xe0, 0, 0}, {0x380c, 0x07, 0, 0},
+ {0x380d, 0x68, 0, 0}, {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0},
+ {0x3813, 0x06, 0, 0}, {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0},
+ {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x0b, 0, 0},
+ {0x3a03, 0x88, 0, 0}, {0x3a14, 0x0b, 0, 0}, {0x3a15, 0x88, 0, 0},
+ {0x4004, 0x02, 0, 0}, {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0},
+ {0x4713, 0x03, 0, 0}, {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0},
+ {0x460c, 0x22, 0, 0}, {0x4837, 0x22, 0, 0}, {0x3824, 0x02, 0, 0},
+ {0x5001, 0xa3, 0, 0}, {0x3034, 0x1a, 0, 0}, {0x3035, 0x21, 0, 0},
+ {0x3036, 0x46, 0, 0}, {0x3037, 0x13, 0, 0}, {0x3503, 0x00, 0, 0},
+};
+
+static struct reg_value ov5640_setting_30fps_QVGA_320_240[] = {
+ {0x3c07, 0x08, 0, 0}, {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0},
+ {0x3814, 0x31, 0, 0}, {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0},
+ {0x3801, 0x00, 0, 0}, {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0},
+ {0x3804, 0x0a, 0, 0}, {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0},
+ {0x3807, 0x9b, 0, 0}, {0x3808, 0x01, 0, 0}, {0x3809, 0x40, 0, 0},
+ {0x380a, 0x00, 0, 0}, {0x380b, 0xf0, 0, 0}, {0x380c, 0x07, 0, 0},
+ {0x380d, 0x68, 0, 0}, {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0},
+ {0x3813, 0x06, 0, 0}, {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0},
+ {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x0b, 0, 0},
+ {0x3a03, 0x88, 0, 0}, {0x3a14, 0x0b, 0, 0}, {0x3a15, 0x88, 0, 0},
+ {0x4004, 0x02, 0, 0}, {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0},
+ {0x4713, 0x03, 0, 0}, {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0},
+ {0x460c, 0x22, 0, 0}, {0x4837, 0x22, 0, 0}, {0x3824, 0x02, 0, 0},
+ {0x5001, 0xa3, 0, 0}, {0x3034, 0x1a, 0, 0}, {0x3035, 0x11, 0, 0},
+ {0x3036, 0x46, 0, 0}, {0x3037, 0x13, 0, 0},
+};
+
+static struct reg_value ov5640_setting_15fps_QVGA_320_240[] = {
+ {0x3c07, 0x08, 0, 0}, {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0},
+ {0x3814, 0x31, 0, 0}, {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0},
+ {0x3801, 0x00, 0, 0}, {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0},
+ {0x3804, 0x0a, 0, 0}, {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0},
+ {0x3807, 0x9b, 0, 0}, {0x3808, 0x01, 0, 0}, {0x3809, 0x40, 0, 0},
+ {0x380a, 0x00, 0, 0}, {0x380b, 0xf0, 0, 0}, {0x380c, 0x07, 0, 0},
+ {0x380d, 0x68, 0, 0}, {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0},
+ {0x3813, 0x06, 0, 0}, {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0},
+ {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x0b, 0, 0},
+ {0x3a03, 0x88, 0, 0}, {0x3a14, 0x0b, 0, 0}, {0x3a15, 0x88, 0, 0},
+ {0x4004, 0x02, 0, 0}, {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0},
+ {0x4713, 0x03, 0, 0}, {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0},
+ {0x460c, 0x22, 0, 0}, {0x4837, 0x22, 0, 0}, {0x3824, 0x02, 0, 0},
+ {0x5001, 0xa3, 0, 0}, {0x3034, 0x1a, 0, 0}, {0x3035, 0x21, 0, 0},
+ {0x3036, 0x46, 0, 0}, {0x3037, 0x13, 0, 0},
+};
+
+static struct reg_value ov5640_setting_30fps_NTSC_720_480[] = {
+ {0x3c07, 0x08, 0, 0}, {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0},
+ {0x3814, 0x31, 0, 0}, {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0},
+ {0x3801, 0x00, 0, 0}, {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0},
+ {0x3804, 0x0a, 0, 0}, {0x3805, 0x3f, 0, 0}, {0x3806, 0x06, 0, 0},
+ {0x3807, 0xd4, 0, 0}, {0x3808, 0x02, 0, 0}, {0x3809, 0xd0, 0, 0},
+ {0x380a, 0x01, 0, 0}, {0x380b, 0xe0, 0, 0}, {0x380c, 0x07, 0, 0},
+ {0x380d, 0x68, 0, 0}, {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0},
+ {0x3813, 0x06, 0, 0}, {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0},
+ {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x0b, 0, 0},
+ {0x3a03, 0x88, 0, 0}, {0x3a14, 0x0b, 0, 0}, {0x3a15, 0x88, 0, 0},
+ {0x4004, 0x02, 0, 0}, {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0},
+ {0x4713, 0x03, 0, 0}, {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0},
+ {0x460c, 0x22, 0, 0}, {0x4837, 0x22, 0, 0}, {0x3824, 0x02, 0, 0},
+ {0x5001, 0xa3, 0, 0}, {0x3034, 0x1a, 0, 0}, {0x3035, 0x11, 0, 0},
+ {0x3036, 0x46, 0, 0}, {0x3037, 0x13, 0, 0},
+};
+
+static struct reg_value ov5640_setting_15fps_NTSC_720_480[] = {
+ {0x3c07, 0x08, 0, 0}, {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0},
+ {0x3814, 0x31, 0, 0}, {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0},
+ {0x3801, 0x00, 0, 0}, {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0},
+ {0x3804, 0x0a, 0, 0}, {0x3805, 0x3f, 0, 0}, {0x3806, 0x06, 0, 0},
+ {0x3807, 0xd4, 0, 0}, {0x3808, 0x02, 0, 0}, {0x3809, 0xd0, 0, 0},
+ {0x380a, 0x01, 0, 0}, {0x380b, 0xe0, 0, 0}, {0x380c, 0x07, 0, 0},
+ {0x380d, 0x68, 0, 0}, {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0},
+ {0x3813, 0x06, 0, 0}, {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0},
+ {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x0b, 0, 0},
+ {0x3a03, 0x88, 0, 0}, {0x3a14, 0x0b, 0, 0}, {0x3a15, 0x88, 0, 0},
+ {0x4004, 0x02, 0, 0}, {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0},
+ {0x4713, 0x03, 0, 0}, {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0},
+ {0x460c, 0x22, 0, 0}, {0x4837, 0x22, 0, 0}, {0x3824, 0x02, 0, 0},
+ {0x5001, 0xa3, 0, 0}, {0x3034, 0x1a, 0, 0}, {0x3035, 0x21, 0, 0},
+ {0x3036, 0x46, 0, 0}, {0x3037, 0x13, 0, 0},
+};
+
+static struct reg_value ov5640_setting_30fps_PAL_720_576[] = {
+ {0x3c07, 0x08, 0, 0}, {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0},
+ {0x3814, 0x31, 0, 0}, {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0},
+ {0x3801, 0x60, 0, 0}, {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0},
+ {0x3804, 0x09, 0, 0}, {0x3805, 0x7e, 0, 0}, {0x3806, 0x07, 0, 0},
+ {0x3807, 0x9b, 0, 0}, {0x3808, 0x02, 0, 0}, {0x3809, 0xd0, 0, 0},
+ {0x380a, 0x02, 0, 0}, {0x380b, 0x40, 0, 0}, {0x380c, 0x07, 0, 0},
+ {0x380d, 0x68, 0, 0}, {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0},
+ {0x3813, 0x06, 0, 0}, {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0},
+ {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x0b, 0, 0},
+ {0x3a03, 0x88, 0, 0}, {0x3a14, 0x0b, 0, 0}, {0x3a15, 0x88, 0, 0},
+ {0x4004, 0x02, 0, 0}, {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0},
+ {0x4713, 0x03, 0, 0}, {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0},
+ {0x460c, 0x22, 0, 0}, {0x4837, 0x22, 0, 0}, {0x3824, 0x02, 0, 0},
+ {0x5001, 0xa3, 0, 0}, {0x3034, 0x1a, 0, 0}, {0x3035, 0x11, 0, 0},
+ {0x3036, 0x46, 0, 0}, {0x3037, 0x13, 0, 0},
+};
+
+static struct reg_value ov5640_setting_15fps_PAL_720_576[] = {
+ {0x3c07, 0x08, 0, 0}, {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0},
+ {0x3814, 0x31, 0, 0}, {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0},
+ {0x3801, 0x60, 0, 0}, {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0},
+ {0x3804, 0x09, 0, 0}, {0x3805, 0x7e, 0, 0}, {0x3806, 0x07, 0, 0},
+ {0x3807, 0x9b, 0, 0}, {0x3808, 0x02, 0, 0}, {0x3809, 0xd0, 0, 0},
+ {0x380a, 0x02, 0, 0}, {0x380b, 0x40, 0, 0}, {0x380c, 0x07, 0, 0},
+ {0x380d, 0x68, 0, 0}, {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0},
+ {0x3813, 0x06, 0, 0}, {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0},
+ {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x0b, 0, 0},
+ {0x3a03, 0x88, 0, 0}, {0x3a14, 0x0b, 0, 0}, {0x3a15, 0x88, 0, 0},
+ {0x4004, 0x02, 0, 0}, {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0},
+ {0x4713, 0x03, 0, 0}, {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0},
+ {0x460c, 0x22, 0, 0}, {0x4837, 0x22, 0, 0}, {0x3824, 0x02, 0, 0},
+ {0x5001, 0xa3, 0, 0}, {0x3034, 0x1a, 0, 0}, {0x3035, 0x21, 0, 0},
+ {0x3036, 0x46, 0, 0}, {0x3037, 0x13, 0, 0},
+};
+
+static struct reg_value ov5640_setting_30fps_720P_1280_720[] = {
+ {0x3035, 0x21, 0, 0}, {0x3036, 0x69, 0, 0}, {0x3c07, 0x07, 0, 0},
+ {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0},
+ {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
+ {0x3802, 0x00, 0, 0}, {0x3803, 0xfa, 0, 0}, {0x3804, 0x0a, 0, 0},
+ {0x3805, 0x3f, 0, 0}, {0x3806, 0x06, 0, 0}, {0x3807, 0xa9, 0, 0},
+ {0x3808, 0x05, 0, 0}, {0x3809, 0x00, 0, 0}, {0x380a, 0x02, 0, 0},
+ {0x380b, 0xd0, 0, 0}, {0x380c, 0x07, 0, 0}, {0x380d, 0x64, 0, 0},
+ {0x380e, 0x02, 0, 0}, {0x380f, 0xe4, 0, 0}, {0x3813, 0x04, 0, 0},
+ {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3709, 0x52, 0, 0},
+ {0x370c, 0x03, 0, 0}, {0x3a02, 0x02, 0, 0}, {0x3a03, 0xe0, 0, 0},
+ {0x3a14, 0x02, 0, 0}, {0x3a15, 0xe0, 0, 0}, {0x4004, 0x02, 0, 0},
+ {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0}, {0x4713, 0x03, 0, 0},
+ {0x4407, 0x04, 0, 0}, {0x460b, 0x37, 0, 0}, {0x460c, 0x20, 0, 0},
+ {0x4837, 0x16, 0, 0}, {0x3824, 0x04, 0, 0}, {0x5001, 0x83, 0, 0},
+ {0x3503, 0x00, 0, 0},
+};
+
+static struct reg_value ov5640_setting_15fps_720P_1280_720[] = {
+ {0x3035, 0x41, 0, 0}, {0x3036, 0x69, 0, 0}, {0x3c07, 0x07, 0, 0},
+ {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0},
+ {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
+ {0x3802, 0x00, 0, 0}, {0x3803, 0xfa, 0, 0}, {0x3804, 0x0a, 0, 0},
+ {0x3805, 0x3f, 0, 0}, {0x3806, 0x06, 0, 0}, {0x3807, 0xa9, 0, 0},
+ {0x3808, 0x05, 0, 0}, {0x3809, 0x00, 0, 0}, {0x380a, 0x02, 0, 0},
+ {0x380b, 0xd0, 0, 0}, {0x380c, 0x07, 0, 0}, {0x380d, 0x64, 0, 0},
+ {0x380e, 0x02, 0, 0}, {0x380f, 0xe4, 0, 0}, {0x3813, 0x04, 0, 0},
+ {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3709, 0x52, 0, 0},
+ {0x370c, 0x03, 0, 0}, {0x3a02, 0x02, 0, 0}, {0x3a03, 0xe0, 0, 0},
+ {0x3a14, 0x02, 0, 0}, {0x3a15, 0xe0, 0, 0}, {0x4004, 0x02, 0, 0},
+ {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0}, {0x4713, 0x03, 0, 0},
+ {0x4407, 0x04, 0, 0}, {0x460b, 0x37, 0, 0}, {0x460c, 0x20, 0, 0},
+ {0x4837, 0x16, 0, 0}, {0x3824, 0x04, 0, 0}, {0x5001, 0x83, 0, 0},
+ {0x3503, 0x00, 0, 0},
+};
+
+static struct reg_value ov5640_setting_30fps_QCIF_176_144[] = {
+ {0x3c07, 0x08, 0, 0}, {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0},
+ {0x3814, 0x31, 0, 0}, {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0},
+ {0x3801, 0x00, 0, 0}, {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0},
+ {0x3804, 0x0a, 0, 0}, {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0},
+ {0x3807, 0x9b, 0, 0}, {0x3808, 0x00, 0, 0}, {0x3809, 0xb0, 0, 0},
+ {0x380a, 0x00, 0, 0}, {0x380b, 0x90, 0, 0}, {0x380c, 0x07, 0, 0},
+ {0x380d, 0x68, 0, 0}, {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0},
+ {0x3813, 0x06, 0, 0}, {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0},
+ {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x0b, 0, 0},
+ {0x3a03, 0x88, 0, 0}, {0x3a14, 0x0b, 0, 0}, {0x3a15, 0x88, 0, 0},
+ {0x4004, 0x02, 0, 0}, {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0},
+ {0x4713, 0x03, 0, 0}, {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0},
+ {0x460c, 0x22, 0, 0}, {0x4837, 0x22, 0, 0}, {0x3824, 0x02, 0, 0},
+ {0x5001, 0xa3, 0, 0}, {0x3034, 0x1a, 0, 0}, {0x3035, 0x11, 0, 0},
+ {0x3036, 0x46, 0, 0}, {0x3037, 0x13, 0, 0},
+};
+
+static struct reg_value ov5640_setting_15fps_QCIF_176_144[] = {
+ {0x3c07, 0x08, 0, 0}, {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0},
+ {0x3814, 0x31, 0, 0}, {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0},
+ {0x3801, 0x00, 0, 0}, {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0},
+ {0x3804, 0x0a, 0, 0}, {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0},
+ {0x3807, 0x9b, 0, 0}, {0x3808, 0x00, 0, 0}, {0x3809, 0xb0, 0, 0},
+ {0x380a, 0x00, 0, 0}, {0x380b, 0x90, 0, 0}, {0x380c, 0x07, 0, 0},
+ {0x380d, 0x68, 0, 0}, {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0},
+ {0x3813, 0x06, 0, 0}, {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0},
+ {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x0b, 0, 0},
+ {0x3a03, 0x88, 0, 0}, {0x3a14, 0x0b, 0, 0}, {0x3a15, 0x88, 0, 0},
+ {0x4004, 0x02, 0, 0}, {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0},
+ {0x4713, 0x03, 0, 0}, {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0},
+ {0x460c, 0x22, 0, 0}, {0x4837, 0x22, 0, 0}, {0x3824, 0x02, 0, 0},
+ {0x5001, 0xa3, 0, 0}, {0x3034, 0x1a, 0, 0}, {0x3035, 0x21, 0, 0},
+ {0x3036, 0x46, 0, 0}, {0x3037, 0x13, 0, 0},
+};
+
+static struct reg_value ov5640_setting_30fps_XGA_1024_768[] = {
+ {0x3c07, 0x08, 0, 0}, {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0},
+ {0x3814, 0x31, 0, 0}, {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0},
+ {0x3801, 0x00, 0, 0}, {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0},
+ {0x3804, 0x0a, 0, 0}, {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0},
+ {0x3807, 0x9b, 0, 0}, {0x3808, 0x04, 0, 0}, {0x3809, 0x00, 0, 0},
+ {0x380a, 0x03, 0, 0}, {0x380b, 0x00, 0, 0}, {0x380c, 0x07, 0, 0},
+ {0x380d, 0x68, 0, 0}, {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0},
+ {0x3813, 0x06, 0, 0}, {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0},
+ {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x0b, 0, 0},
+ {0x3a03, 0x88, 0, 0}, {0x3a14, 0x0b, 0, 0}, {0x3a15, 0x88, 0, 0},
+ {0x4004, 0x02, 0, 0}, {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0},
+ {0x4713, 0x03, 0, 0}, {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0},
+ {0x460c, 0x20, 0, 0}, {0x4837, 0x22, 0, 0}, {0x3824, 0x01, 0, 0},
+ {0x5001, 0xa3, 0, 0}, {0x3034, 0x1a, 0, 0}, {0x3035, 0x21, 0, 0},
+ {0x3036, 0x69, 0, 0}, {0x3037, 0x13, 0, 0},
+};
+
+static struct reg_value ov5640_setting_15fps_XGA_1024_768[] = {
+ {0x3c07, 0x08, 0, 0}, {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0},
+ {0x3814, 0x31, 0, 0}, {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0},
+ {0x3801, 0x00, 0, 0}, {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0},
+ {0x3804, 0x0a, 0, 0}, {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0},
+ {0x3807, 0x9b, 0, 0}, {0x3808, 0x04, 0, 0}, {0x3809, 0x00, 0, 0},
+ {0x380a, 0x03, 0, 0}, {0x380b, 0x00, 0, 0}, {0x380c, 0x07, 0, 0},
+ {0x380d, 0x68, 0, 0}, {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0},
+ {0x3813, 0x06, 0, 0}, {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0},
+ {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x0b, 0, 0},
+ {0x3a03, 0x88, 0, 0}, {0x3a14, 0x0b, 0, 0}, {0x3a15, 0x88, 0, 0},
+ {0x4004, 0x02, 0, 0}, {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0},
+ {0x4713, 0x03, 0, 0}, {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0},
+ {0x460c, 0x20, 0, 0}, {0x4837, 0x22, 0, 0}, {0x3824, 0x01, 0, 0},
+ {0x5001, 0xa3, 0, 0}, {0x3034, 0x1a, 0, 0}, {0x3035, 0x21, 0, 0},
+ {0x3036, 0x46, 0, 0}, {0x3037, 0x13, 0, 0},
+};
+
+
+static struct reg_value ov5640_setting_15fps_1080P_1920_1080[] = {
+ {0x3c07, 0x07, 0, 0}, {0x3820, 0x40, 0, 0}, {0x3821, 0x06, 0, 0},
+ {0x3814, 0x11, 0, 0}, {0x3815, 0x11, 0, 0}, {0x3800, 0x00, 0, 0},
+ {0x3801, 0x00, 0, 0}, {0x3802, 0x00, 0, 0}, {0x3803, 0xee, 0, 0},
+ {0x3804, 0x0a, 0, 0}, {0x3805, 0x3f, 0, 0}, {0x3806, 0x05, 0, 0},
+ {0x3807, 0xc3, 0, 0}, {0x3808, 0x07, 0, 0}, {0x3809, 0x80, 0, 0},
+ {0x380a, 0x04, 0, 0}, {0x380b, 0x38, 0, 0}, {0x380c, 0x0b, 0, 0},
+ {0x380d, 0x1c, 0, 0}, {0x380e, 0x07, 0, 0}, {0x380f, 0xb0, 0, 0},
+ {0x3813, 0x04, 0, 0}, {0x3618, 0x04, 0, 0}, {0x3612, 0x2b, 0, 0},
+ {0x3709, 0x12, 0, 0}, {0x370c, 0x00, 0, 0}, {0x3a02, 0x07, 0, 0},
+ {0x3a03, 0xae, 0, 0}, {0x3a14, 0x07, 0, 0}, {0x3a15, 0xae, 0, 0},
+ {0x4004, 0x06, 0, 0}, {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0},
+ {0x4713, 0x02, 0, 0}, {0x4407, 0x0c, 0, 0}, {0x460b, 0x37, 0, 0},
+ {0x460c, 0x20, 0, 0}, {0x4837, 0x2c, 0, 0}, {0x3824, 0x01, 0, 0},
+ {0x5001, 0x83, 0, 0}, {0x3034, 0x1a, 0, 0}, {0x3035, 0x21, 0, 0},
+ {0x3036, 0x69, 0, 0}, {0x3037, 0x13, 0, 0},
+};
+
+static struct reg_value ov5640_setting_15fps_QSXGA_2592_1944[] = {
+ {0x3c07, 0x07, 0, 0}, {0x3820, 0x40, 0, 0}, {0x3821, 0x06, 0, 0},
+ {0x3814, 0x11, 0, 0}, {0x3815, 0x11, 0, 0}, {0x3800, 0x00, 0, 0},
+ {0x3801, 0x00, 0, 0}, {0x3802, 0x00, 0, 0}, {0x3803, 0x00, 0, 0},
+ {0x3804, 0x0a, 0, 0}, {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0},
+ {0x3807, 0x9f, 0, 0}, {0x3808, 0x0a, 0, 0}, {0x3809, 0x20, 0, 0},
+ {0x380a, 0x07, 0, 0}, {0x380b, 0x98, 0, 0}, {0x380c, 0x0b, 0, 0},
+ {0x380d, 0x1c, 0, 0}, {0x380e, 0x07, 0, 0}, {0x380f, 0xb0, 0, 0},
+ {0x3813, 0x04, 0, 0}, {0x3618, 0x04, 0, 0}, {0x3612, 0x2b, 0, 0},
+ {0x3709, 0x12, 0, 0}, {0x370c, 0x00, 0, 0}, {0x3a02, 0x07, 0, 0},
+ {0x3a03, 0xae, 0, 0}, {0x3a14, 0x07, 0, 0}, {0x3a15, 0xae, 0, 0},
+ {0x4004, 0x06, 0, 0}, {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0},
+ {0x4713, 0x02, 0, 0}, {0x4407, 0x0c, 0, 0}, {0x460b, 0x37, 0, 0},
+ {0x460c, 0x20, 0, 0}, {0x4837, 0x2c, 0, 0}, {0x3824, 0x01, 0, 0},
+ {0x5001, 0x83, 0, 0}, {0x3034, 0x1a, 0, 0}, {0x3035, 0x21, 0, 0},
+ {0x3036, 0x69, 0, 0}, {0x3037, 0x13, 0, 0},
+};
+
+static struct ov5640_mode_info ov5640_mode_info_data[2][ov5640_mode_MAX + 1] = {
+ {
+ {ov5640_mode_VGA_640_480, 640, 480,
+ ov5640_setting_15fps_VGA_640_480,
+ ARRAY_SIZE(ov5640_setting_15fps_VGA_640_480)},
+ {ov5640_mode_QVGA_320_240, 320, 240,
+ ov5640_setting_15fps_QVGA_320_240,
+ ARRAY_SIZE(ov5640_setting_15fps_QVGA_320_240)},
+ {ov5640_mode_NTSC_720_480, 720, 480,
+ ov5640_setting_15fps_NTSC_720_480,
+ ARRAY_SIZE(ov5640_setting_15fps_NTSC_720_480)},
+ {ov5640_mode_PAL_720_576, 720, 576,
+ ov5640_setting_15fps_PAL_720_576,
+ ARRAY_SIZE(ov5640_setting_15fps_PAL_720_576)},
+ {ov5640_mode_720P_1280_720, 1280, 720,
+ ov5640_setting_15fps_720P_1280_720,
+ ARRAY_SIZE(ov5640_setting_15fps_720P_1280_720)},
+ {ov5640_mode_1080P_1920_1080, 1920, 1080,
+ ov5640_setting_15fps_1080P_1920_1080,
+ ARRAY_SIZE(ov5640_setting_15fps_1080P_1920_1080)},
+ {ov5640_mode_QSXGA_2592_1944, 2592, 1944,
+ ov5640_setting_15fps_QSXGA_2592_1944,
+ ARRAY_SIZE(ov5640_setting_15fps_QSXGA_2592_1944)},
+ {ov5640_mode_QCIF_176_144, 176, 144,
+ ov5640_setting_15fps_QCIF_176_144,
+ ARRAY_SIZE(ov5640_setting_15fps_QCIF_176_144)},
+ {ov5640_mode_XGA_1024_768, 1024, 768,
+ ov5640_setting_15fps_XGA_1024_768,
+ ARRAY_SIZE(ov5640_setting_15fps_XGA_1024_768)},
+ },
+ {
+ {ov5640_mode_VGA_640_480, 640, 480,
+ ov5640_setting_30fps_VGA_640_480,
+ ARRAY_SIZE(ov5640_setting_30fps_VGA_640_480)},
+ {ov5640_mode_QVGA_320_240, 320, 240,
+ ov5640_setting_30fps_QVGA_320_240,
+ ARRAY_SIZE(ov5640_setting_30fps_QVGA_320_240)},
+ {ov5640_mode_NTSC_720_480, 720, 480,
+ ov5640_setting_30fps_NTSC_720_480,
+ ARRAY_SIZE(ov5640_setting_30fps_NTSC_720_480)},
+ {ov5640_mode_PAL_720_576, 720, 576,
+ ov5640_setting_30fps_PAL_720_576,
+ ARRAY_SIZE(ov5640_setting_30fps_PAL_720_576)},
+ {ov5640_mode_720P_1280_720, 1280, 720,
+ ov5640_setting_30fps_720P_1280_720,
+ ARRAY_SIZE(ov5640_setting_30fps_720P_1280_720)},
+ {ov5640_mode_1080P_1920_1080, 0, 0, NULL, 0},
+ {ov5640_mode_QSXGA_2592_1944, 0, 0, NULL, 0},
+ {ov5640_mode_QCIF_176_144, 176, 144,
+ ov5640_setting_30fps_QCIF_176_144,
+ ARRAY_SIZE(ov5640_setting_30fps_QCIF_176_144)},
+ {ov5640_mode_XGA_1024_768, 1024, 768,
+ ov5640_setting_30fps_XGA_1024_768,
+ ARRAY_SIZE(ov5640_setting_30fps_XGA_1024_768)},
+ },
+};
+
+static struct regulator *io_regulator;
+static struct regulator *core_regulator;
+static struct regulator *analog_regulator;
+
+static int ov5640_probe(struct i2c_client *adapter,
+ const struct i2c_device_id *device_id);
+static int ov5640_remove(struct i2c_client *client);
+
+static s32 ov5640_read_reg(u16 reg, u8 *val);
+static s32 ov5640_write_reg(u16 reg, u8 val);
+
+static const struct i2c_device_id ov5640_id[] = {
+ {"ov564x", 0},
+ {},
+};
+
+MODULE_DEVICE_TABLE(i2c, ov5640_id);
+
+static struct i2c_driver ov5640_i2c_driver = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "ov564x",
+ },
+ .probe = ov5640_probe,
+ .remove = ov5640_remove,
+ .id_table = ov5640_id,
+};
+
+static inline void ov5640_power_down(int enable)
+{
+ gpio_set_value(pwn_gpio, enable);
+
+ msleep(2);
+}
+
+static inline void ov5640_reset(void)
+{
+ /* camera reset */
+ gpio_set_value(rst_gpio, 1);
+
+ /* camera power down */
+ gpio_set_value(pwn_gpio, 1);
+ msleep(5);
+ gpio_set_value(pwn_gpio, 0);
+ msleep(5);
+ gpio_set_value(rst_gpio, 0);
+ msleep(1);
+ gpio_set_value(rst_gpio, 1);
+ msleep(5);
+ gpio_set_value(pwn_gpio, 1);
+}
+
+static int ov5640_regulator_enable(struct device *dev)
+{
+ int ret = 0;
+
+ io_regulator = devm_regulator_get(dev, "DOVDD");
+ if (!IS_ERR(io_regulator)) {
+ regulator_set_voltage(io_regulator,
+ OV5640_VOLTAGE_DIGITAL_IO,
+ OV5640_VOLTAGE_DIGITAL_IO);
+ ret = regulator_enable(io_regulator);
+ if (ret) {
+ dev_err(dev, "set io voltage failed\n");
+ return ret;
+ } else {
+ dev_dbg(dev, "set io voltage ok\n");
+ }
+ } else {
+ io_regulator = NULL;
+ dev_warn(dev, "cannot get io voltage\n");
+ }
+
+ core_regulator = devm_regulator_get(dev, "DVDD");
+ if (!IS_ERR(core_regulator)) {
+ regulator_set_voltage(core_regulator,
+ OV5640_VOLTAGE_DIGITAL_CORE,
+ OV5640_VOLTAGE_DIGITAL_CORE);
+ ret = regulator_enable(core_regulator);
+ if (ret) {
+ dev_err(dev, "set core voltage failed\n");
+ return ret;
+ } else {
+ dev_dbg(dev, "set core voltage ok\n");
+ }
+ } else {
+ core_regulator = NULL;
+ dev_warn(dev, "cannot get core voltage\n");
+ }
+
+ analog_regulator = devm_regulator_get(dev, "AVDD");
+ if (!IS_ERR(analog_regulator)) {
+ regulator_set_voltage(analog_regulator,
+ OV5640_VOLTAGE_ANALOG,
+ OV5640_VOLTAGE_ANALOG);
+ ret = regulator_enable(analog_regulator);
+ if (ret) {
+ dev_err(dev, "set analog voltage failed\n");
+ return ret;
+ } else {
+ dev_dbg(dev, "set analog voltage ok\n");
+ }
+ } else {
+ analog_regulator = NULL;
+ dev_warn(dev, "cannot get analog voltage\n");
+ }
+
+ return ret;
+}
+
+static s32 ov5640_write_reg(u16 reg, u8 val)
+{
+ u8 au8Buf[3] = {0};
+
+ au8Buf[0] = reg >> 8;
+ au8Buf[1] = reg & 0xff;
+ au8Buf[2] = val;
+
+ if (i2c_master_send(ov5640_data.i2c_client, au8Buf, 3) < 0) {
+ pr_err("%s:write reg error:reg=%x,val=%x\n",
+ __func__, reg, val);
+ return -1;
+ }
+
+ return 0;
+}
+
+static s32 ov5640_read_reg(u16 reg, u8 *val)
+{
+ u8 au8RegBuf[2] = {0};
+ u8 u8RdVal = 0;
+
+ au8RegBuf[0] = reg >> 8;
+ au8RegBuf[1] = reg & 0xff;
+
+ if (2 != i2c_master_send(ov5640_data.i2c_client, au8RegBuf, 2)) {
+ pr_err("%s:write reg error:reg=%x\n",
+ __func__, reg);
+ return -1;
+ }
+
+ if (1 != i2c_master_recv(ov5640_data.i2c_client, &u8RdVal, 1)) {
+ pr_err("%s:read reg error:reg=%x,val=%x\n",
+ __func__, reg, u8RdVal);
+ return -1;
+ }
+
+ *val = u8RdVal;
+
+ return u8RdVal;
+}
+
+static void ov5640_soft_reset(void)
+{
+ /* sysclk from pad */
+ ov5640_write_reg(0x3103, 0x11);
+
+ /* software reset */
+ ov5640_write_reg(0x3008, 0x82);
+
+ /* delay at least 5ms */
+ msleep(10);
+}
+
+/* set sensor driver capability
+ * 0x302c[7:6] - strength
+ 00 - 1x
+ 01 - 2x
+ 10 - 3x
+ 11 - 4x
+ */
+static int ov5640_driver_capability(int strength)
+{
+ u8 temp = 0;
+
+ if (strength > 4 || strength < 1) {
+ pr_err("The valid driver capability of ov5640 is 1x~4x\n");
+ return -EINVAL;
+ }
+
+ ov5640_read_reg(0x302c, &temp);
+
+ temp &= ~0xc0; /* clear [7:6] */
+ temp |= ((strength - 1) << 6); /* set [7:6] */
+
+ ov5640_write_reg(0x302c, temp);
+
+ return 0;
+}
+
+/* calculate sysclk */
+static int ov5640_get_sysclk(void)
+{
+ int xvclk = ov5640_data.mclk / 10000;
+ int sysclk;
+ int temp1, temp2;
+ int Multiplier, PreDiv, VCO, SysDiv, Pll_rdiv, Bit_div2x, sclk_rdiv;
+ int sclk_rdiv_map[] = {1, 2, 4, 8};
+ u8 regval = 0;
+
+ temp1 = ov5640_read_reg(0x3034, &regval);
+ temp2 = temp1 & 0x0f;
+ if (temp2 == 8 || temp2 == 10) {
+ Bit_div2x = temp2 / 2;
+ } else {
+ pr_err("ov5640: unsupported bit mode %d\n", temp2);
+ return -1;
+ }
+
+ temp1 = ov5640_read_reg(0x3035, &regval);
+ SysDiv = temp1 >> 4;
+ if (SysDiv == 0)
+ SysDiv = 16;
+
+ temp1 = ov5640_read_reg(0x3036, &regval);
+ Multiplier = temp1;
+ temp1 = ov5640_read_reg(0x3037, &regval);
+ PreDiv = temp1 & 0x0f;
+ Pll_rdiv = ((temp1 >> 4) & 0x01) + 1;
+
+ temp1 = ov5640_read_reg(0x3108, &regval);
+ temp2 = temp1 & 0x03;
+
+ sclk_rdiv = sclk_rdiv_map[temp2];
+ VCO = xvclk * Multiplier / PreDiv;
+ sysclk = VCO / SysDiv / Pll_rdiv * 2 / Bit_div2x / sclk_rdiv;
+
+ return sysclk;
+}
+
+/* read HTS from register settings */
+static int ov5640_get_HTS(void)
+{
+ int HTS;
+ u8 temp = 0;
+
+ HTS = ov5640_read_reg(0x380c, &temp);
+ HTS = (HTS<<8) + ov5640_read_reg(0x380d, &temp);
+ return HTS;
+}
+
+/* read VTS from register settings */
+static int ov5640_get_VTS(void)
+{
+ int VTS;
+ u8 temp = 0;
+
+ VTS = ov5640_read_reg(0x380e, &temp);
+ VTS = (VTS<<8) + ov5640_read_reg(0x380f, &temp);
+
+ return VTS;
+}
+
+/* write VTS to registers */
+static int ov5640_set_VTS(int VTS)
+{
+ int temp;
+
+ temp = VTS & 0xff;
+ ov5640_write_reg(0x380f, temp);
+
+ temp = VTS>>8;
+ ov5640_write_reg(0x380e, temp);
+ return 0;
+}
+
+/* read shutter, in number of line period */
+static int ov5640_get_shutter(void)
+{
+ int shutter;
+ u8 regval;
+
+ shutter = (ov5640_read_reg(0x03500, &regval) & 0x0f);
+
+ shutter = (shutter<<8) + ov5640_read_reg(0x3501, &regval);
+ shutter = (shutter<<4) + (ov5640_read_reg(0x3502, &regval)>>4);
+
+ return shutter;
+}
+
+/* write shutter, in number of line period */
+static int ov5640_set_shutter(int shutter)
+{
+ int temp;
+
+ shutter = shutter & 0xffff;
+ temp = shutter & 0x0f;
+ temp = temp<<4;
+ ov5640_write_reg(0x3502, temp);
+
+ temp = shutter & 0xfff;
+ temp = temp>>4;
+ ov5640_write_reg(0x3501, temp);
+
+ temp = shutter>>12;
+ ov5640_write_reg(0x3500, temp);
+
+ return 0;
+}
+
+/* read gain, 16 = 1x */
+static int ov5640_get_gain16(void)
+{
+ int gain16;
+ u8 regval;
+
+ gain16 = ov5640_read_reg(0x350a, &regval) & 0x03;
+ gain16 = (gain16<<8) + ov5640_read_reg(0x350b, &regval);
+
+ return gain16;
+}
+
+/* write gain, 16 = 1x */
+static int ov5640_set_gain16(int gain16)
+{
+ int temp;
+
+ gain16 = gain16 & 0x3ff;
+ temp = gain16 & 0xff;
+
+ ov5640_write_reg(0x350b, temp);
+ temp = gain16>>8;
+
+ ov5640_write_reg(0x350a, temp);
+ return 0;
+}
+
+/* get banding filter value */
+static int ov5640_get_light_freq(void)
+{
+ int temp, temp1, light_frequency;
+ u8 regval;
+
+ temp = ov5640_read_reg(0x3c01, &regval);
+ if (temp & 0x80) {
+ /* manual */
+ temp1 = ov5640_read_reg(0x3c00, &regval);
+ if (temp1 & 0x04) {
+ /* 50Hz */
+ light_frequency = 50;
+ } else {
+ /* 60Hz */
+ light_frequency = 60;
+ }
+ } else {
+ /* auto */
+ temp1 = ov5640_read_reg(0x3c0c, &regval);
+ if (temp1 & 0x01) {
+ /* 50Hz */
+ light_frequency = 50;
+ } else {
+ /* 60Hz */
+ light_frequency = 60;
+ }
+ }
+
+ return light_frequency;
+}
+
+static void ov5640_set_bandingfilter(void)
+{
+ int prev_VTS;
+ int band_step60, max_band60, band_step50, max_band50;
+
+ /* read preview PCLK */
+ prev_sysclk = ov5640_get_sysclk();
+
+ /* read preview HTS */
+ prev_HTS = ov5640_get_HTS();
+
+ /* read preview VTS */
+ prev_VTS = ov5640_get_VTS();
+
+ /* calculate banding filter */
+ /* 60Hz */
+ band_step60 = prev_sysclk * 100/prev_HTS * 100/120;
+ ov5640_write_reg(0x3a0a, (band_step60 >> 8));
+ ov5640_write_reg(0x3a0b, (band_step60 & 0xff));
+
+ max_band60 = (int)((prev_VTS-4)/band_step60);
+ ov5640_write_reg(0x3a0d, max_band60);
+
+ /* 50Hz */
+ band_step50 = prev_sysclk * 100/prev_HTS;
+ ov5640_write_reg(0x3a08, (band_step50 >> 8));
+ ov5640_write_reg(0x3a09, (band_step50 & 0xff));
+
+ max_band50 = (int)((prev_VTS-4)/band_step50);
+ ov5640_write_reg(0x3a0e, max_band50);
+}
+
+/* stable in high */
+static int ov5640_set_AE_target(int target)
+{
+ int fast_high, fast_low;
+
+ AE_low = target * 23 / 25; /* 0.92 */
+ AE_high = target * 27 / 25; /* 1.08 */
+ fast_high = AE_high << 1;
+
+ if (fast_high > 255)
+ fast_high = 255;
+ fast_low = AE_low >> 1;
+
+ ov5640_write_reg(0x3a0f, AE_high);
+ ov5640_write_reg(0x3a10, AE_low);
+ ov5640_write_reg(0x3a1b, AE_high);
+ ov5640_write_reg(0x3a1e, AE_low);
+ ov5640_write_reg(0x3a11, fast_high);
+ ov5640_write_reg(0x3a1f, fast_low);
+
+ return 0;
+}
+
+/* enable = 0 to turn off night mode
+ enable = 1 to turn on night mode */
+static int ov5640_set_night_mode(int enable)
+{
+ u8 mode;
+
+ ov5640_read_reg(0x3a00, &mode);
+
+ if (enable) {
+ /* night mode on */
+ mode |= 0x04;
+ ov5640_write_reg(0x3a00, mode);
+ } else {
+ /* night mode off */
+ mode &= 0xfb;
+ ov5640_write_reg(0x3a00, mode);
+ }
+
+ return 0;
+}
+
+/* enable = 0 to turn off AEC/AGC
+ enable = 1 to turn on AEC/AGC */
+static void ov5640_turn_on_AE_AG(int enable)
+{
+ u8 ae_ag_ctrl;
+
+ ov5640_read_reg(0x3503, &ae_ag_ctrl);
+ if (enable) {
+ /* turn on auto AE/AG */
+ ae_ag_ctrl = ae_ag_ctrl & ~(0x03);
+ } else {
+ /* turn off AE/AG */
+ ae_ag_ctrl = ae_ag_ctrl | 0x03;
+ }
+ ov5640_write_reg(0x3503, ae_ag_ctrl);
+}
+
+/* download ov5640 settings to sensor through i2c */
+static int ov5640_download_firmware(struct reg_value *pModeSetting, s32 ArySize)
+{
+ register u32 Delay_ms = 0;
+ register u16 RegAddr = 0;
+ register u8 Mask = 0;
+ register u8 Val = 0;
+ u8 RegVal = 0;
+ int i, retval = 0;
+
+ for (i = 0; i < ArySize; ++i, ++pModeSetting) {
+ Delay_ms = pModeSetting->u32Delay_ms;
+ RegAddr = pModeSetting->u16RegAddr;
+ Val = pModeSetting->u8Val;
+ Mask = pModeSetting->u8Mask;
+
+ if (Mask) {
+ retval = ov5640_read_reg(RegAddr, &RegVal);
+ if (retval < 0)
+ goto err;
+
+ RegVal &= ~(u8)Mask;
+ Val &= Mask;
+ Val |= RegVal;
+ }
+
+ retval = ov5640_write_reg(RegAddr, Val);
+ if (retval < 0)
+ goto err;
+
+ if (Delay_ms)
+ msleep(Delay_ms);
+ }
+err:
+ return retval;
+}
+
+static int ov5640_init_mode(void)
+{
+ struct reg_value *pModeSetting = NULL;
+ int ArySize = 0, retval = 0;
+
+ ov5640_soft_reset();
+
+ pModeSetting = ov5640_global_init_setting;
+ ArySize = ARRAY_SIZE(ov5640_global_init_setting);
+ retval = ov5640_download_firmware(pModeSetting, ArySize);
+ if (retval < 0)
+ goto err;
+
+ pModeSetting = ov5640_init_setting_30fps_VGA;
+ ArySize = ARRAY_SIZE(ov5640_init_setting_30fps_VGA);
+ retval = ov5640_download_firmware(pModeSetting, ArySize);
+ if (retval < 0)
+ goto err;
+
+ /* change driver capability to 2x according to validation board.
+ * if the image is not stable, please increase the driver strength.
+ */
+ ov5640_driver_capability(2);
+ ov5640_set_bandingfilter();
+ ov5640_set_AE_target(AE_Target);
+ ov5640_set_night_mode(night_mode);
+
+ /* skip 9 vysnc: start capture at 10th vsync */
+ msleep(300);
+
+ /* turn off night mode */
+ night_mode = 0;
+ ov5640_data.pix.width = 640;
+ ov5640_data.pix.height = 480;
+err:
+ return retval;
+}
+
+/* change to or back to subsampling mode set the mode directly
+ * image size below 1280 * 960 is subsampling mode */
+static int ov5640_change_mode_direct(enum ov5640_frame_rate frame_rate,
+ enum ov5640_mode mode)
+{
+ struct reg_value *pModeSetting = NULL;
+ s32 ArySize = 0;
+ int retval = 0;
+
+ if (mode > ov5640_mode_MAX || mode < ov5640_mode_MIN) {
+ pr_err("Wrong ov5640 mode detected!\n");
+ return -1;
+ }
+
+ pModeSetting = ov5640_mode_info_data[frame_rate][mode].init_data_ptr;
+ ArySize =
+ ov5640_mode_info_data[frame_rate][mode].init_data_size;
+
+ ov5640_data.pix.width = ov5640_mode_info_data[frame_rate][mode].width;
+ ov5640_data.pix.height = ov5640_mode_info_data[frame_rate][mode].height;
+
+ if (ov5640_data.pix.width == 0 || ov5640_data.pix.height == 0 ||
+ pModeSetting == NULL || ArySize == 0)
+ return -EINVAL;
+
+ /* set ov5640 to subsampling mode */
+ retval = ov5640_download_firmware(pModeSetting, ArySize);
+
+ /* turn on AE AG for subsampling mode, in case the firmware didn't */
+ ov5640_turn_on_AE_AG(1);
+
+ /* calculate banding filter */
+ ov5640_set_bandingfilter();
+
+ /* set AE target */
+ ov5640_set_AE_target(AE_Target);
+
+ /* update night mode setting */
+ ov5640_set_night_mode(night_mode);
+
+ /* skip 9 vysnc: start capture at 10th vsync */
+ if (mode == ov5640_mode_XGA_1024_768 && frame_rate == ov5640_30_fps) {
+ pr_warning("ov5640: actual frame rate of XGA is 22.5fps\n");
+ /* 1/22.5 * 9*/
+ msleep(400);
+ return retval;
+ }
+
+ if (frame_rate == ov5640_15_fps) {
+ /* 1/15 * 9*/
+ msleep(600);
+ } else if (frame_rate == ov5640_30_fps) {
+ /* 1/30 * 9*/
+ msleep(300);
+ }
+
+ return retval;
+}
+
+/* change to scaling mode go through exposure calucation
+ * image size above 1280 * 960 is scaling mode */
+static int ov5640_change_mode_exposure_calc(enum ov5640_frame_rate frame_rate,
+ enum ov5640_mode mode)
+{
+ int prev_shutter, prev_gain16, average;
+ int cap_shutter, cap_gain16;
+ int cap_sysclk, cap_HTS, cap_VTS;
+ int light_freq, cap_bandfilt, cap_maxband;
+ long cap_gain16_shutter;
+ u8 temp;
+ struct reg_value *pModeSetting = NULL;
+ s32 ArySize = 0;
+ int retval = 0;
+
+ /* check if the input mode and frame rate is valid */
+ pModeSetting =
+ ov5640_mode_info_data[frame_rate][mode].init_data_ptr;
+ ArySize =
+ ov5640_mode_info_data[frame_rate][mode].init_data_size;
+
+ ov5640_data.pix.width =
+ ov5640_mode_info_data[frame_rate][mode].width;
+ ov5640_data.pix.height =
+ ov5640_mode_info_data[frame_rate][mode].height;
+
+ if (ov5640_data.pix.width == 0 || ov5640_data.pix.height == 0 ||
+ pModeSetting == NULL || ArySize == 0)
+ return -EINVAL;
+
+ /* read preview shutter */
+ prev_shutter = ov5640_get_shutter();
+
+ /* read preview gain */
+ prev_gain16 = ov5640_get_gain16();
+
+ /* get average */
+ average = ov5640_read_reg(0x56a1, &temp);
+
+ /* turn off night mode for capture */
+ ov5640_set_night_mode(0);
+
+ /* turn off overlay */
+ ov5640_write_reg(0x3022, 0x06);
+
+ /* Write capture setting */
+ retval = ov5640_download_firmware(pModeSetting, ArySize);
+ if (retval < 0)
+ goto err;
+
+ /* turn off AE AG when capture image. */
+ ov5640_turn_on_AE_AG(0);
+
+ /* read capture VTS */
+ cap_VTS = ov5640_get_VTS();
+ cap_HTS = ov5640_get_HTS();
+ cap_sysclk = ov5640_get_sysclk();
+
+ /* calculate capture banding filter */
+ light_freq = ov5640_get_light_freq();
+ if (light_freq == 60) {
+ /* 60Hz */
+ cap_bandfilt = cap_sysclk * 100 / cap_HTS * 100 / 120;
+ } else {
+ /* 50Hz */
+ cap_bandfilt = cap_sysclk * 100 / cap_HTS;
+ }
+ cap_maxband = (int)((cap_VTS - 4)/cap_bandfilt);
+ /* calculate capture shutter/gain16 */
+ if (average > AE_low && average < AE_high) {
+ /* in stable range */
+ cap_gain16_shutter =
+ prev_gain16 * prev_shutter * cap_sysclk/prev_sysclk *
+ prev_HTS/cap_HTS * AE_Target / average;
+ } else {
+ cap_gain16_shutter =
+ prev_gain16 * prev_shutter * cap_sysclk/prev_sysclk *
+ prev_HTS/cap_HTS;
+ }
+
+ /* gain to shutter */
+ if (cap_gain16_shutter < (cap_bandfilt * 16)) {
+ /* shutter < 1/100 */
+ cap_shutter = cap_gain16_shutter/16;
+ if (cap_shutter < 1)
+ cap_shutter = 1;
+ cap_gain16 = cap_gain16_shutter/cap_shutter;
+ if (cap_gain16 < 16)
+ cap_gain16 = 16;
+ } else {
+ if (cap_gain16_shutter > (cap_bandfilt*cap_maxband*16)) {
+ /* exposure reach max */
+ cap_shutter = cap_bandfilt*cap_maxband;
+ cap_gain16 = cap_gain16_shutter / cap_shutter;
+ } else {
+ /* 1/100 < cap_shutter =< max, cap_shutter = n/100 */
+ cap_shutter =
+ ((int)(cap_gain16_shutter/16/cap_bandfilt))
+ * cap_bandfilt;
+ cap_gain16 = cap_gain16_shutter / cap_shutter;
+ }
+ }
+
+ /* write capture gain */
+ ov5640_set_gain16(cap_gain16);
+
+ /* write capture shutter */
+ if (cap_shutter > (cap_VTS - 4)) {
+ cap_VTS = cap_shutter + 4;
+ ov5640_set_VTS(cap_VTS);
+ }
+
+ ov5640_set_shutter(cap_shutter);
+
+ /* skip 2 vysnc: start capture at 3rd vsync
+ * frame rate of QSXGA and 1080P is 7.5fps: 1/7.5 * 2
+ */
+ pr_warning("ov5640: the actual frame rate of %s is 7.5fps\n",
+ mode == ov5640_mode_1080P_1920_1080 ? "1080P" : "QSXGA");
+ msleep(267);
+err:
+ return retval;
+}
+
+static int ov5640_change_mode(enum ov5640_frame_rate frame_rate,
+ enum ov5640_mode mode)
+{
+ int retval = 0;
+
+ if (mode > ov5640_mode_MAX || mode < ov5640_mode_MIN) {
+ pr_err("Wrong ov5640 mode detected!\n");
+ return -1;
+ }
+
+ if (mode == ov5640_mode_1080P_1920_1080 ||
+ mode == ov5640_mode_QSXGA_2592_1944) {
+ /* change to scaling mode go through exposure calucation
+ * image size above 1280 * 960 is scaling mode */
+ retval = ov5640_change_mode_exposure_calc(frame_rate, mode);
+ } else {
+ /* change back to subsampling modem download firmware directly
+ * image size below 1280 * 960 is subsampling mode */
+ retval = ov5640_change_mode_direct(frame_rate, mode);
+ }
+
+ return retval;
+}
+
+/* --------------- IOCTL functions from v4l2_int_ioctl_desc --------------- */
+
+static int ioctl_g_ifparm(struct v4l2_int_device *s, struct v4l2_ifparm *p)
+{
+ if (s == NULL) {
+ pr_err(" ERROR!! no slave device set!\n");
+ return -1;
+ }
+
+ memset(p, 0, sizeof(*p));
+ p->u.bt656.clock_curr = ov5640_data.mclk;
+ pr_debug(" clock_curr=mclk=%d\n", ov5640_data.mclk);
+ p->if_type = V4L2_IF_TYPE_BT656;
+ p->u.bt656.mode = V4L2_IF_TYPE_BT656_MODE_NOBT_8BIT;
+ p->u.bt656.clock_min = OV5640_XCLK_MIN;
+ p->u.bt656.clock_max = OV5640_XCLK_MAX;
+ p->u.bt656.bt_sync_correct = 1; /* Indicate external vsync */
+
+ return 0;
+}
+
+/*!
+ * ioctl_s_power - V4L2 sensor interface handler for VIDIOC_S_POWER ioctl
+ * @s: pointer to standard V4L2 device structure
+ * @on: indicates power mode (on or off)
+ *
+ * Turns the power on or off, depending on the value of on and returns the
+ * appropriate error code.
+ */
+static int ioctl_s_power(struct v4l2_int_device *s, int on)
+{
+ struct sensor_data *sensor = s->priv;
+
+ if (on && !sensor->on) {
+ if (io_regulator)
+ if (regulator_enable(io_regulator) != 0)
+ return -EIO;
+ if (core_regulator)
+ if (regulator_enable(core_regulator) != 0)
+ return -EIO;
+ if (analog_regulator)
+ if (regulator_enable(analog_regulator) != 0)
+ return -EIO;
+ /* Make sure power on */
+ ov5640_power_down(0);
+ } else if (!on && sensor->on) {
+ if (analog_regulator)
+ regulator_disable(analog_regulator);
+ if (core_regulator)
+ regulator_disable(core_regulator);
+ if (io_regulator)
+ regulator_disable(io_regulator);
+
+ ov5640_power_down(1);
+}
+
+ sensor->on = on;
+
+ return 0;
+}
+
+/*!
+ * ioctl_g_parm - V4L2 sensor interface handler for VIDIOC_G_PARM ioctl
+ * @s: pointer to standard V4L2 device structure
+ * @a: pointer to standard V4L2 VIDIOC_G_PARM ioctl structure
+ *
+ * Returns the sensor's video CAPTURE parameters.
+ */
+static int ioctl_g_parm(struct v4l2_int_device *s, struct v4l2_streamparm *a)
+{
+ struct sensor_data *sensor = s->priv;
+ struct v4l2_captureparm *cparm = &a->parm.capture;
+ int ret = 0;
+
+ switch (a->type) {
+ /* This is the only case currently handled. */
+ case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+ memset(a, 0, sizeof(*a));
+ a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ cparm->capability = sensor->streamcap.capability;
+ cparm->timeperframe = sensor->streamcap.timeperframe;
+ cparm->capturemode = sensor->streamcap.capturemode;
+ ret = 0;
+ break;
+
+ /* These are all the possible cases. */
+ case V4L2_BUF_TYPE_VIDEO_OUTPUT:
+ case V4L2_BUF_TYPE_VIDEO_OVERLAY:
+ case V4L2_BUF_TYPE_VBI_CAPTURE:
+ case V4L2_BUF_TYPE_VBI_OUTPUT:
+ case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
+ case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
+ ret = -EINVAL;
+ break;
+
+ default:
+ pr_debug(" type is unknown - %d\n", a->type);
+ ret = -EINVAL;
+ break;
+ }
+
+ return ret;
+}
+
+/*!
+ * ioctl_s_parm - V4L2 sensor interface handler for VIDIOC_S_PARM ioctl
+ * @s: pointer to standard V4L2 device structure
+ * @a: pointer to standard V4L2 VIDIOC_S_PARM ioctl structure
+ *
+ * Configures the sensor to use the input parameters, if possible. If
+ * not possible, reverts to the old parameters and returns the
+ * appropriate error code.
+ */
+static int ioctl_s_parm(struct v4l2_int_device *s, struct v4l2_streamparm *a)
+{
+ struct sensor_data *sensor = s->priv;
+ struct v4l2_fract *timeperframe = &a->parm.capture.timeperframe;
+ u32 tgt_fps; /* target frames per secound */
+ enum ov5640_frame_rate frame_rate;
+ int ret = 0;
+
+ /* Make sure power on */
+ ov5640_power_down(0);
+
+ switch (a->type) {
+ /* This is the only case currently handled. */
+ case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+ /* Check that the new frame rate is allowed. */
+ if ((timeperframe->numerator == 0) ||
+ (timeperframe->denominator == 0)) {
+ timeperframe->denominator = DEFAULT_FPS;
+ timeperframe->numerator = 1;
+ }
+
+ tgt_fps = timeperframe->denominator /
+ timeperframe->numerator;
+
+ if (tgt_fps > MAX_FPS) {
+ timeperframe->denominator = MAX_FPS;
+ timeperframe->numerator = 1;
+ } else if (tgt_fps < MIN_FPS) {
+ timeperframe->denominator = MIN_FPS;
+ timeperframe->numerator = 1;
+ }
+
+ /* Actual frame rate we use */
+ tgt_fps = timeperframe->denominator /
+ timeperframe->numerator;
+
+ if (tgt_fps == 15)
+ frame_rate = ov5640_15_fps;
+ else if (tgt_fps == 30)
+ frame_rate = ov5640_30_fps;
+ else {
+ pr_err(" The camera frame rate is not supported!\n");
+ return -EINVAL;
+ }
+
+ ret = ov5640_change_mode(frame_rate,
+ a->parm.capture.capturemode);
+ if (ret < 0)
+ return ret;
+
+ sensor->streamcap.timeperframe = *timeperframe;
+ sensor->streamcap.capturemode = a->parm.capture.capturemode;
+
+ break;
+
+ /* These are all the possible cases. */
+ case V4L2_BUF_TYPE_VIDEO_OUTPUT:
+ case V4L2_BUF_TYPE_VIDEO_OVERLAY:
+ case V4L2_BUF_TYPE_VBI_CAPTURE:
+ case V4L2_BUF_TYPE_VBI_OUTPUT:
+ case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
+ case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
+ pr_debug(" type is not " \
+ "V4L2_BUF_TYPE_VIDEO_CAPTURE but %d\n",
+ a->type);
+ ret = -EINVAL;
+ break;
+
+ default:
+ pr_debug(" type is unknown - %d\n", a->type);
+ ret = -EINVAL;
+ break;
+ }
+
+ return ret;
+}
+
+/*!
+ * ioctl_g_fmt_cap - V4L2 sensor interface handler for ioctl_g_fmt_cap
+ * @s: pointer to standard V4L2 device structure
+ * @f: pointer to standard V4L2 v4l2_format structure
+ *
+ * Returns the sensor's current pixel format in the v4l2_format
+ * parameter.
+ */
+static int ioctl_g_fmt_cap(struct v4l2_int_device *s, struct v4l2_format *f)
+{
+ struct sensor_data *sensor = s->priv;
+
+ f->fmt.pix = sensor->pix;
+
+ return 0;
+}
+
+/*!
+ * ioctl_g_ctrl - V4L2 sensor interface handler for VIDIOC_G_CTRL ioctl
+ * @s: pointer to standard V4L2 device structure
+ * @vc: standard V4L2 VIDIOC_G_CTRL ioctl structure
+ *
+ * If the requested control is supported, returns the control's current
+ * value from the video_control[] array. Otherwise, returns -EINVAL
+ * if the control is not supported.
+ */
+static int ioctl_g_ctrl(struct v4l2_int_device *s, struct v4l2_control *vc)
+{
+ int ret = 0;
+
+ switch (vc->id) {
+ case V4L2_CID_BRIGHTNESS:
+ vc->value = ov5640_data.brightness;
+ break;
+ case V4L2_CID_HUE:
+ vc->value = ov5640_data.hue;
+ break;
+ case V4L2_CID_CONTRAST:
+ vc->value = ov5640_data.contrast;
+ break;
+ case V4L2_CID_SATURATION:
+ vc->value = ov5640_data.saturation;
+ break;
+ case V4L2_CID_RED_BALANCE:
+ vc->value = ov5640_data.red;
+ break;
+ case V4L2_CID_BLUE_BALANCE:
+ vc->value = ov5640_data.blue;
+ break;
+ case V4L2_CID_EXPOSURE:
+ vc->value = ov5640_data.ae_mode;
+ break;
+ default:
+ ret = -EINVAL;
+ }
+
+ return ret;
+}
+
+/*!
+ * ioctl_s_ctrl - V4L2 sensor interface handler for VIDIOC_S_CTRL ioctl
+ * @s: pointer to standard V4L2 device structure
+ * @vc: standard V4L2 VIDIOC_S_CTRL ioctl structure
+ *
+ * If the requested control is supported, sets the control's current
+ * value in HW (and updates the video_control[] array). Otherwise,
+ * returns -EINVAL if the control is not supported.
+ */
+static int ioctl_s_ctrl(struct v4l2_int_device *s, struct v4l2_control *vc)
+{
+ int retval = 0;
+
+ pr_debug("In ov5640:ioctl_s_ctrl %d\n",
+ vc->id);
+
+ switch (vc->id) {
+ case V4L2_CID_BRIGHTNESS:
+ break;
+ case V4L2_CID_CONTRAST:
+ break;
+ case V4L2_CID_SATURATION:
+ break;
+ case V4L2_CID_HUE:
+ break;
+ case V4L2_CID_AUTO_WHITE_BALANCE:
+ break;
+ case V4L2_CID_DO_WHITE_BALANCE:
+ break;
+ case V4L2_CID_RED_BALANCE:
+ break;
+ case V4L2_CID_BLUE_BALANCE:
+ break;
+ case V4L2_CID_GAMMA:
+ break;
+ case V4L2_CID_EXPOSURE:
+ break;
+ case V4L2_CID_AUTOGAIN:
+ break;
+ case V4L2_CID_GAIN:
+ break;
+ case V4L2_CID_HFLIP:
+ break;
+ case V4L2_CID_VFLIP:
+ break;
+ default:
+ retval = -EPERM;
+ break;
+ }
+
+ return retval;
+}
+
+/*!
+ * ioctl_enum_framesizes - V4L2 sensor interface handler for
+ * VIDIOC_ENUM_FRAMESIZES ioctl
+ * @s: pointer to standard V4L2 device structure
+ * @fsize: standard V4L2 VIDIOC_ENUM_FRAMESIZES ioctl structure
+ *
+ * Return 0 if successful, otherwise -EINVAL.
+ */
+static int ioctl_enum_framesizes(struct v4l2_int_device *s,
+ struct v4l2_frmsizeenum *fsize)
+{
+ if (fsize->index > ov5640_mode_MAX)
+ return -EINVAL;
+
+ fsize->pixel_format = ov5640_data.pix.pixelformat;
+ fsize->discrete.width =
+ max(ov5640_mode_info_data[0][fsize->index].width,
+ ov5640_mode_info_data[1][fsize->index].width);
+ fsize->discrete.height =
+ max(ov5640_mode_info_data[0][fsize->index].height,
+ ov5640_mode_info_data[1][fsize->index].height);
+ return 0;
+}
+
+/*!
+ * ioctl_enum_frameintervals - V4L2 sensor interface handler for
+ * VIDIOC_ENUM_FRAMEINTERVALS ioctl
+ * @s: pointer to standard V4L2 device structure
+ * @fival: standard V4L2 VIDIOC_ENUM_FRAMEINTERVALS ioctl structure
+ *
+ * Return 0 if successful, otherwise -EINVAL.
+ */
+static int ioctl_enum_frameintervals(struct v4l2_int_device *s,
+ struct v4l2_frmivalenum *fival)
+{
+ int i, j, count;
+
+ if (fival->index < 0 || fival->index > ov5640_mode_MAX)
+ return -EINVAL;
+
+ if (fival->width == 0 || fival->height == 0 ||
+ fival->pixel_format == 0) {
+ pr_warning("Please assign pixelformat, width and height.\n");
+ return -EINVAL;
+ }
+
+ fival->type = V4L2_FRMIVAL_TYPE_DISCRETE;
+ fival->discrete.numerator = 1;
+
+ count = 0;
+ for (i = 0; i < ARRAY_SIZE(ov5640_mode_info_data); i++) {
+ for (j = 0; j < (ov5640_mode_MAX + 1); j++) {
+ if (fival->pixel_format == ov5640_data.pix.pixelformat
+ && fival->width == ov5640_mode_info_data[i][j].width
+ && fival->height == ov5640_mode_info_data[i][j].height
+ && ov5640_mode_info_data[i][j].init_data_ptr != NULL) {
+ count++;
+ }
+ if (fival->index == (count - 1)) {
+ fival->discrete.denominator =
+ ov5640_framerates[i];
+ return 0;
+ }
+ }
+ }
+
+ return -EINVAL;
+}
+
+/*!
+ * ioctl_g_chip_ident - V4L2 sensor interface handler for
+ * VIDIOC_DBG_G_CHIP_IDENT ioctl
+ * @s: pointer to standard V4L2 device structure
+ * @id: pointer to int
+ *
+ * Return 0.
+ */
+static int ioctl_g_chip_ident(struct v4l2_int_device *s, int *id)
+{
+ ((struct v4l2_dbg_chip_ident *)id)->match.type =
+ V4L2_CHIP_MATCH_I2C_DRIVER;
+ strcpy(((struct v4l2_dbg_chip_ident *)id)->match.name, "ov5640_camera");
+
+ return 0;
+}
+
+/*!
+ * ioctl_init - V4L2 sensor interface handler for VIDIOC_INT_INIT
+ * @s: pointer to standard V4L2 device structure
+ */
+static int ioctl_init(struct v4l2_int_device *s)
+{
+
+ return 0;
+}
+
+/*!
+ * ioctl_enum_fmt_cap - V4L2 sensor interface handler for VIDIOC_ENUM_FMT
+ * @s: pointer to standard V4L2 device structure
+ * @fmt: pointer to standard V4L2 fmt description structure
+ *
+ * Return 0.
+ */
+static int ioctl_enum_fmt_cap(struct v4l2_int_device *s,
+ struct v4l2_fmtdesc *fmt)
+{
+ if (fmt->index > ov5640_mode_MAX)
+ return -EINVAL;
+
+ fmt->pixelformat = ov5640_data.pix.pixelformat;
+
+ return 0;
+}
+
+/*!
+ * ioctl_dev_init - V4L2 sensor interface handler for vidioc_int_dev_init_num
+ * @s: pointer to standard V4L2 device structure
+ *
+ * Initialise the device when slave attaches to the master.
+ */
+static int ioctl_dev_init(struct v4l2_int_device *s)
+{
+ struct sensor_data *sensor = s->priv;
+ u32 tgt_xclk; /* target xclk */
+ u32 tgt_fps; /* target frames per secound */
+ enum ov5640_frame_rate frame_rate;
+ int ret;
+
+ ov5640_data.on = true;
+
+ /* mclk */
+ tgt_xclk = ov5640_data.mclk;
+ tgt_xclk = min(tgt_xclk, (u32)OV5640_XCLK_MAX);
+ tgt_xclk = max(tgt_xclk, (u32)OV5640_XCLK_MIN);
+ ov5640_data.mclk = tgt_xclk;
+
+ pr_debug(" Setting mclk to %d MHz\n", tgt_xclk / 1000000);
+ clk_set_rate(ov5640_data.sensor_clk, ov5640_data.mclk);
+
+ /* Default camera frame rate is set in probe */
+ tgt_fps = sensor->streamcap.timeperframe.denominator /
+ sensor->streamcap.timeperframe.numerator;
+
+ if (tgt_fps == 15)
+ frame_rate = ov5640_15_fps;
+ else if (tgt_fps == 30)
+ frame_rate = ov5640_30_fps;
+ else
+ return -EINVAL; /* Only support 15fps or 30fps now. */
+
+ ret = ov5640_init_mode();
+ return ret;
+}
+
+/*!
+ * ioctl_dev_exit - V4L2 sensor interface handler for vidioc_int_dev_exit_num
+ * @s: pointer to standard V4L2 device structure
+ *
+ * Delinitialise the device when slave detaches to the master.
+ */
+static int ioctl_dev_exit(struct v4l2_int_device *s)
+{
+ return 0;
+}
+
+/*!
+ * This structure defines all the ioctls for this module and links them to the
+ * enumeration.
+ */
+static struct v4l2_int_ioctl_desc ov5640_ioctl_desc[] = {
+ { vidioc_int_dev_init_num,
+ (v4l2_int_ioctl_func *)ioctl_dev_init },
+ { vidioc_int_dev_exit_num,
+ ioctl_dev_exit},
+ { vidioc_int_s_power_num,
+ (v4l2_int_ioctl_func *)ioctl_s_power },
+ { vidioc_int_g_ifparm_num,
+ (v4l2_int_ioctl_func *)ioctl_g_ifparm },
+ { vidioc_int_init_num,
+ (v4l2_int_ioctl_func *)ioctl_init },
+ { vidioc_int_enum_fmt_cap_num,
+ (v4l2_int_ioctl_func *)ioctl_enum_fmt_cap },
+ { vidioc_int_g_fmt_cap_num,
+ (v4l2_int_ioctl_func *)ioctl_g_fmt_cap },
+ { vidioc_int_g_parm_num,
+ (v4l2_int_ioctl_func *)ioctl_g_parm },
+ { vidioc_int_s_parm_num,
+ (v4l2_int_ioctl_func *)ioctl_s_parm },
+ { vidioc_int_g_ctrl_num,
+ (v4l2_int_ioctl_func *)ioctl_g_ctrl },
+ { vidioc_int_s_ctrl_num,
+ (v4l2_int_ioctl_func *)ioctl_s_ctrl },
+ { vidioc_int_enum_framesizes_num,
+ (v4l2_int_ioctl_func *)ioctl_enum_framesizes },
+ { vidioc_int_enum_frameintervals_num,
+ (v4l2_int_ioctl_func *)ioctl_enum_frameintervals },
+ { vidioc_int_g_chip_ident_num,
+ (v4l2_int_ioctl_func *)ioctl_g_chip_ident },
+};
+
+static struct v4l2_int_slave ov5640_slave = {
+ .ioctls = ov5640_ioctl_desc,
+ .num_ioctls = ARRAY_SIZE(ov5640_ioctl_desc),
+};
+
+static struct v4l2_int_device ov5640_int_device = {
+ .module = THIS_MODULE,
+ .name = "ov564x",
+ .type = v4l2_int_type_slave,
+ .u = {
+ .slave = &ov5640_slave,
+ },
+};
+
+/*!
+ * ov5640 I2C probe function
+ *
+ * @param adapter struct i2c_adapter *
+ * @return Error code indicating success or failure
+ */
+static int ov5640_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct pinctrl *pinctrl;
+ struct device *dev = &client->dev;
+ int retval;
+ u8 chip_id_high, chip_id_low;
+
+ /* ov5640 pinctrl */
+ pinctrl = devm_pinctrl_get_select_default(dev);
+ if (IS_ERR(pinctrl)) {
+ dev_err(dev, "setup pinctrl failed\n");
+ return PTR_ERR(pinctrl);
+ }
+
+ /* request power down pin */
+ pwn_gpio = of_get_named_gpio(dev->of_node, "pwn-gpios", 0);
+ if (!gpio_is_valid(pwn_gpio)) {
+ dev_err(dev, "no sensor pwdn pin available\n");
+ return -ENODEV;
+ }
+ retval = devm_gpio_request_one(dev, pwn_gpio, GPIOF_OUT_INIT_HIGH,
+ "ov5640_pwdn");
+ if (retval < 0)
+ return retval;
+
+ /* request reset pin */
+ rst_gpio = of_get_named_gpio(dev->of_node, "rst-gpios", 0);
+ if (!gpio_is_valid(rst_gpio)) {
+ dev_err(dev, "no sensor reset pin available\n");
+ return -EINVAL;
+ }
+ retval = devm_gpio_request_one(dev, rst_gpio, GPIOF_OUT_INIT_HIGH,
+ "ov5640_reset");
+ if (retval < 0)
+ return retval;
+
+ /* Set initial values for the sensor struct. */
+ memset(&ov5640_data, 0, sizeof(ov5640_data));
+ ov5640_data.sensor_clk = devm_clk_get(dev, "csi_mclk");
+ if (IS_ERR(ov5640_data.sensor_clk)) {
+ dev_err(dev, "get mclk failed\n");
+ return PTR_ERR(ov5640_data.sensor_clk);
+ }
+
+ retval = of_property_read_u32(dev->of_node, "mclk",
+ &ov5640_data.mclk);
+ if (retval) {
+ dev_err(dev, "mclk frequency is invalid\n");
+ return retval;
+ }
+
+ retval = of_property_read_u32(dev->of_node, "mclk_source",
+ (u32 *) &(ov5640_data.mclk_source));
+ if (retval) {
+ dev_err(dev, "mclk_source invalid\n");
+ return retval;
+ }
+
+ retval = of_property_read_u32(dev->of_node, "csi_id",
+ &(ov5640_data.csi));
+ if (retval) {
+ dev_err(dev, "csi_id invalid\n");
+ return retval;
+ }
+
+ clk_prepare_enable(ov5640_data.sensor_clk);
+
+ ov5640_data.io_init = ov5640_reset;
+ ov5640_data.i2c_client = client;
+ ov5640_data.pix.pixelformat = V4L2_PIX_FMT_YUYV;
+ ov5640_data.pix.width = 640;
+ ov5640_data.pix.height = 480;
+ ov5640_data.streamcap.capability = V4L2_MODE_HIGHQUALITY |
+ V4L2_CAP_TIMEPERFRAME;
+ ov5640_data.streamcap.capturemode = 0;
+ ov5640_data.streamcap.timeperframe.denominator = DEFAULT_FPS;
+ ov5640_data.streamcap.timeperframe.numerator = 1;
+
+ ov5640_regulator_enable(&client->dev);
+
+ ov5640_reset();
+
+ ov5640_power_down(0);
+
+ retval = ov5640_read_reg(OV5640_CHIP_ID_HIGH_BYTE, &chip_id_high);
+ if (retval < 0 || chip_id_high != 0x56) {
+ clk_disable_unprepare(ov5640_data.sensor_clk);
+ pr_warning("camera ov5640 is not found\n");
+ return -ENODEV;
+ }
+ retval = ov5640_read_reg(OV5640_CHIP_ID_LOW_BYTE, &chip_id_low);
+ if (retval < 0 || chip_id_low != 0x40) {
+ clk_disable_unprepare(ov5640_data.sensor_clk);
+ pr_warning("camera ov5640 is not found\n");
+ return -ENODEV;
+ }
+
+ ov5640_power_down(1);
+
+ clk_disable_unprepare(ov5640_data.sensor_clk);
+
+ ov5640_int_device.priv = &ov5640_data;
+ retval = v4l2_int_device_register(&ov5640_int_device);
+
+ pr_info("camera ov5640 is found\n");
+ return retval;
+}
+
+/*!
+ * ov5640 I2C detach function
+ *
+ * @param client struct i2c_client *
+ * @return Error code indicating success or failure
+ */
+static int ov5640_remove(struct i2c_client *client)
+{
+ v4l2_int_device_unregister(&ov5640_int_device);
+
+ if (analog_regulator)
+ regulator_disable(analog_regulator);
+
+ if (core_regulator)
+ regulator_disable(core_regulator);
+
+ if (io_regulator)
+ regulator_disable(io_regulator);
+
+ return 0;
+}
+
+module_i2c_driver(ov5640_i2c_driver);
+
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("OV5640 Camera Driver");
+MODULE_LICENSE("GPL");
+MODULE_VERSION("1.0");
+MODULE_ALIAS("CSI");
diff --git a/drivers/media/platform/mxc/capture/ov5640_mipi.c b/drivers/media/platform/mxc/capture/ov5640_mipi.c
new file mode 100644
index 000000000000..0d146b534f61
--- /dev/null
+++ b/drivers/media/platform/mxc/capture/ov5640_mipi.c
@@ -0,0 +1,2142 @@
+/*
+ * Copyright (C) 2011-2015 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/ctype.h>
+#include <linux/types.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/of_device.h>
+#include <linux/i2c.h>
+#include <linux/of_gpio.h>
+#include <linux/pinctrl/consumer.h>
+#include <linux/regulator/consumer.h>
+#include <linux/fsl_devices.h>
+#include <linux/mipi_csi2.h>
+#include <media/v4l2-chip-ident.h>
+#include "v4l2-int-device.h"
+#include "mxc_v4l2_capture.h"
+
+#define OV5640_VOLTAGE_ANALOG 2800000
+#define OV5640_VOLTAGE_DIGITAL_CORE 1500000
+#define OV5640_VOLTAGE_DIGITAL_IO 1800000
+
+#define MIN_FPS 15
+#define MAX_FPS 30
+#define DEFAULT_FPS 30
+
+#define OV5640_XCLK_MIN 6000000
+#define OV5640_XCLK_MAX 24000000
+
+#define OV5640_CHIP_ID_HIGH_BYTE 0x300A
+#define OV5640_CHIP_ID_LOW_BYTE 0x300B
+
+enum ov5640_mode {
+ ov5640_mode_MIN = 0,
+ ov5640_mode_VGA_640_480 = 0,
+ ov5640_mode_QVGA_320_240 = 1,
+ ov5640_mode_NTSC_720_480 = 2,
+ ov5640_mode_PAL_720_576 = 3,
+ ov5640_mode_720P_1280_720 = 4,
+ ov5640_mode_1080P_1920_1080 = 5,
+ ov5640_mode_QSXGA_2592_1944 = 6,
+ ov5640_mode_QCIF_176_144 = 7,
+ ov5640_mode_XGA_1024_768 = 8,
+ ov5640_mode_MAX = 8,
+ ov5640_mode_INIT = 0xff, /*only for sensor init*/
+};
+
+enum ov5640_frame_rate {
+ ov5640_15_fps,
+ ov5640_30_fps
+};
+
+static int ov5640_framerates[] = {
+ [ov5640_15_fps] = 15,
+ [ov5640_30_fps] = 30,
+};
+
+/* image size under 1280 * 960 are SUBSAMPLING
+ * image size upper 1280 * 960 are SCALING
+ */
+enum ov5640_downsize_mode {
+ SUBSAMPLING,
+ SCALING,
+};
+
+struct reg_value {
+ u16 u16RegAddr;
+ u8 u8Val;
+ u8 u8Mask;
+ u32 u32Delay_ms;
+};
+
+struct ov5640_mode_info {
+ enum ov5640_mode mode;
+ enum ov5640_downsize_mode dn_mode;
+ u32 width;
+ u32 height;
+ struct reg_value *init_data_ptr;
+ u32 init_data_size;
+};
+
+/*!
+ * Maintains the information on the current state of the sesor.
+ */
+static struct sensor_data ov5640_data;
+static int pwn_gpio, rst_gpio;
+
+static struct reg_value ov5640_init_setting_30fps_VGA[] = {
+
+ {0x3103, 0x11, 0, 0}, {0x3008, 0x82, 0, 5}, {0x3008, 0x42, 0, 0},
+ {0x3103, 0x03, 0, 0}, {0x3017, 0x00, 0, 0}, {0x3018, 0x00, 0, 0},
+ {0x3034, 0x18, 0, 0}, {0x3035, 0x14, 0, 0}, {0x3036, 0x38, 0, 0},
+ {0x3037, 0x13, 0, 0}, {0x3108, 0x01, 0, 0}, {0x3630, 0x36, 0, 0},
+ {0x3631, 0x0e, 0, 0}, {0x3632, 0xe2, 0, 0}, {0x3633, 0x12, 0, 0},
+ {0x3621, 0xe0, 0, 0}, {0x3704, 0xa0, 0, 0}, {0x3703, 0x5a, 0, 0},
+ {0x3715, 0x78, 0, 0}, {0x3717, 0x01, 0, 0}, {0x370b, 0x60, 0, 0},
+ {0x3705, 0x1a, 0, 0}, {0x3905, 0x02, 0, 0}, {0x3906, 0x10, 0, 0},
+ {0x3901, 0x0a, 0, 0}, {0x3731, 0x12, 0, 0}, {0x3600, 0x08, 0, 0},
+ {0x3601, 0x33, 0, 0}, {0x302d, 0x60, 0, 0}, {0x3620, 0x52, 0, 0},
+ {0x371b, 0x20, 0, 0}, {0x471c, 0x50, 0, 0}, {0x3a13, 0x43, 0, 0},
+ {0x3a18, 0x00, 0, 0}, {0x3a19, 0xf8, 0, 0}, {0x3635, 0x13, 0, 0},
+ {0x3636, 0x03, 0, 0}, {0x3634, 0x40, 0, 0}, {0x3622, 0x01, 0, 0},
+ {0x3c01, 0xa4, 0, 0}, {0x3c04, 0x28, 0, 0}, {0x3c05, 0x98, 0, 0},
+ {0x3c06, 0x00, 0, 0}, {0x3c07, 0x08, 0, 0}, {0x3c08, 0x00, 0, 0},
+ {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
+ {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0},
+ {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
+ {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0}, {0x3804, 0x0a, 0, 0},
+ {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9b, 0, 0},
+ {0x3808, 0x02, 0, 0}, {0x3809, 0x80, 0, 0}, {0x380a, 0x01, 0, 0},
+ {0x380b, 0xe0, 0, 0}, {0x380c, 0x07, 0, 0}, {0x380d, 0x68, 0, 0},
+ {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0}, {0x3810, 0x00, 0, 0},
+ {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x06, 0, 0},
+ {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0},
+ {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x03, 0, 0},
+ {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0},
+ {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0},
+ {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0},
+ {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x3000, 0x00, 0, 0},
+ {0x3002, 0x1c, 0, 0}, {0x3004, 0xff, 0, 0}, {0x3006, 0xc3, 0, 0},
+ {0x300e, 0x45, 0, 0}, {0x302e, 0x08, 0, 0}, {0x4300, 0x3f, 0, 0},
+ {0x501f, 0x00, 0, 0}, {0x4713, 0x03, 0, 0}, {0x4407, 0x04, 0, 0},
+ {0x440e, 0x00, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0},
+ {0x4837, 0x0a, 0, 0}, {0x4800, 0x04, 0, 0}, {0x3824, 0x02, 0, 0},
+ {0x5000, 0xa7, 0, 0}, {0x5001, 0xa3, 0, 0}, {0x5180, 0xff, 0, 0},
+ {0x5181, 0xf2, 0, 0}, {0x5182, 0x00, 0, 0}, {0x5183, 0x14, 0, 0},
+ {0x5184, 0x25, 0, 0}, {0x5185, 0x24, 0, 0}, {0x5186, 0x09, 0, 0},
+ {0x5187, 0x09, 0, 0}, {0x5188, 0x09, 0, 0}, {0x5189, 0x88, 0, 0},
+ {0x518a, 0x54, 0, 0}, {0x518b, 0xee, 0, 0}, {0x518c, 0xb2, 0, 0},
+ {0x518d, 0x50, 0, 0}, {0x518e, 0x34, 0, 0}, {0x518f, 0x6b, 0, 0},
+ {0x5190, 0x46, 0, 0}, {0x5191, 0xf8, 0, 0}, {0x5192, 0x04, 0, 0},
+ {0x5193, 0x70, 0, 0}, {0x5194, 0xf0, 0, 0}, {0x5195, 0xf0, 0, 0},
+ {0x5196, 0x03, 0, 0}, {0x5197, 0x01, 0, 0}, {0x5198, 0x04, 0, 0},
+ {0x5199, 0x6c, 0, 0}, {0x519a, 0x04, 0, 0}, {0x519b, 0x00, 0, 0},
+ {0x519c, 0x09, 0, 0}, {0x519d, 0x2b, 0, 0}, {0x519e, 0x38, 0, 0},
+ {0x5381, 0x1e, 0, 0}, {0x5382, 0x5b, 0, 0}, {0x5383, 0x08, 0, 0},
+ {0x5384, 0x0a, 0, 0}, {0x5385, 0x7e, 0, 0}, {0x5386, 0x88, 0, 0},
+ {0x5387, 0x7c, 0, 0}, {0x5388, 0x6c, 0, 0}, {0x5389, 0x10, 0, 0},
+ {0x538a, 0x01, 0, 0}, {0x538b, 0x98, 0, 0}, {0x5300, 0x08, 0, 0},
+ {0x5301, 0x30, 0, 0}, {0x5302, 0x10, 0, 0}, {0x5303, 0x00, 0, 0},
+ {0x5304, 0x08, 0, 0}, {0x5305, 0x30, 0, 0}, {0x5306, 0x08, 0, 0},
+ {0x5307, 0x16, 0, 0}, {0x5309, 0x08, 0, 0}, {0x530a, 0x30, 0, 0},
+ {0x530b, 0x04, 0, 0}, {0x530c, 0x06, 0, 0}, {0x5480, 0x01, 0, 0},
+ {0x5481, 0x08, 0, 0}, {0x5482, 0x14, 0, 0}, {0x5483, 0x28, 0, 0},
+ {0x5484, 0x51, 0, 0}, {0x5485, 0x65, 0, 0}, {0x5486, 0x71, 0, 0},
+ {0x5487, 0x7d, 0, 0}, {0x5488, 0x87, 0, 0}, {0x5489, 0x91, 0, 0},
+ {0x548a, 0x9a, 0, 0}, {0x548b, 0xaa, 0, 0}, {0x548c, 0xb8, 0, 0},
+ {0x548d, 0xcd, 0, 0}, {0x548e, 0xdd, 0, 0}, {0x548f, 0xea, 0, 0},
+ {0x5490, 0x1d, 0, 0}, {0x5580, 0x02, 0, 0}, {0x5583, 0x40, 0, 0},
+ {0x5584, 0x10, 0, 0}, {0x5589, 0x10, 0, 0}, {0x558a, 0x00, 0, 0},
+ {0x558b, 0xf8, 0, 0}, {0x5800, 0x23, 0, 0}, {0x5801, 0x14, 0, 0},
+ {0x5802, 0x0f, 0, 0}, {0x5803, 0x0f, 0, 0}, {0x5804, 0x12, 0, 0},
+ {0x5805, 0x26, 0, 0}, {0x5806, 0x0c, 0, 0}, {0x5807, 0x08, 0, 0},
+ {0x5808, 0x05, 0, 0}, {0x5809, 0x05, 0, 0}, {0x580a, 0x08, 0, 0},
+ {0x580b, 0x0d, 0, 0}, {0x580c, 0x08, 0, 0}, {0x580d, 0x03, 0, 0},
+ {0x580e, 0x00, 0, 0}, {0x580f, 0x00, 0, 0}, {0x5810, 0x03, 0, 0},
+ {0x5811, 0x09, 0, 0}, {0x5812, 0x07, 0, 0}, {0x5813, 0x03, 0, 0},
+ {0x5814, 0x00, 0, 0}, {0x5815, 0x01, 0, 0}, {0x5816, 0x03, 0, 0},
+ {0x5817, 0x08, 0, 0}, {0x5818, 0x0d, 0, 0}, {0x5819, 0x08, 0, 0},
+ {0x581a, 0x05, 0, 0}, {0x581b, 0x06, 0, 0}, {0x581c, 0x08, 0, 0},
+ {0x581d, 0x0e, 0, 0}, {0x581e, 0x29, 0, 0}, {0x581f, 0x17, 0, 0},
+ {0x5820, 0x11, 0, 0}, {0x5821, 0x11, 0, 0}, {0x5822, 0x15, 0, 0},
+ {0x5823, 0x28, 0, 0}, {0x5824, 0x46, 0, 0}, {0x5825, 0x26, 0, 0},
+ {0x5826, 0x08, 0, 0}, {0x5827, 0x26, 0, 0}, {0x5828, 0x64, 0, 0},
+ {0x5829, 0x26, 0, 0}, {0x582a, 0x24, 0, 0}, {0x582b, 0x22, 0, 0},
+ {0x582c, 0x24, 0, 0}, {0x582d, 0x24, 0, 0}, {0x582e, 0x06, 0, 0},
+ {0x582f, 0x22, 0, 0}, {0x5830, 0x40, 0, 0}, {0x5831, 0x42, 0, 0},
+ {0x5832, 0x24, 0, 0}, {0x5833, 0x26, 0, 0}, {0x5834, 0x24, 0, 0},
+ {0x5835, 0x22, 0, 0}, {0x5836, 0x22, 0, 0}, {0x5837, 0x26, 0, 0},
+ {0x5838, 0x44, 0, 0}, {0x5839, 0x24, 0, 0}, {0x583a, 0x26, 0, 0},
+ {0x583b, 0x28, 0, 0}, {0x583c, 0x42, 0, 0}, {0x583d, 0xce, 0, 0},
+ {0x5025, 0x00, 0, 0}, {0x3a0f, 0x30, 0, 0}, {0x3a10, 0x28, 0, 0},
+ {0x3a1b, 0x30, 0, 0}, {0x3a1e, 0x26, 0, 0}, {0x3a11, 0x60, 0, 0},
+ {0x3a1f, 0x14, 0, 0}, {0x3008, 0x02, 0, 0}, {0x3c00, 0x04, 0, 300},
+};
+
+static struct reg_value ov5640_setting_30fps_VGA_640_480[] = {
+
+ {0x3035, 0x14, 0, 0}, {0x3036, 0x38, 0, 0}, {0x3c07, 0x08, 0, 0},
+ {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
+ {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0},
+ {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
+ {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0}, {0x3804, 0x0a, 0, 0},
+ {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9b, 0, 0},
+ {0x3808, 0x02, 0, 0}, {0x3809, 0x80, 0, 0}, {0x380a, 0x01, 0, 0},
+ {0x380b, 0xe0, 0, 0}, {0x380c, 0x07, 0, 0}, {0x380d, 0x68, 0, 0},
+ {0x380e, 0x04, 0, 0}, {0x380f, 0x38, 0, 0}, {0x3810, 0x00, 0, 0},
+ {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x06, 0, 0},
+ {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0},
+ {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x03, 0, 0},
+ {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x0e, 0, 0},
+ {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0},
+ {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0},
+ {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x4713, 0x03, 0, 0},
+ {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0},
+ {0x3824, 0x02, 0, 0}, {0x5001, 0xa3, 0, 0}, {0x3503, 0x00, 0, 0},
+};
+
+static struct reg_value ov5640_setting_15fps_VGA_640_480[] = {
+ {0x3035, 0x22, 0, 0}, {0x3036, 0x38, 0, 0}, {0x3c07, 0x08, 0, 0},
+ {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
+ {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0},
+ {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
+ {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0}, {0x3804, 0x0a, 0, 0},
+ {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9b, 0, 0},
+ {0x3808, 0x02, 0, 0}, {0x3809, 0x80, 0, 0}, {0x380a, 0x01, 0, 0},
+ {0x380b, 0xe0, 0, 0}, {0x380c, 0x07, 0, 0}, {0x380d, 0x68, 0, 0},
+ {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0}, {0x3810, 0x00, 0, 0},
+ {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x06, 0, 0},
+ {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0},
+ {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x03, 0, 0},
+ {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0},
+ {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0},
+ {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0},
+ {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x4713, 0x03, 0, 0},
+ {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0},
+ {0x3824, 0x02, 0, 0}, {0x5001, 0xa3, 0, 0},
+};
+
+static struct reg_value ov5640_setting_30fps_XGA_1024_768[] = {
+
+ {0x3035, 0x14, 0, 0}, {0x3036, 0x38, 0, 0}, {0x3c07, 0x08, 0, 0},
+ {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
+ {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0},
+ {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
+ {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0}, {0x3804, 0x0a, 0, 0},
+ {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9b, 0, 0},
+ {0x3808, 0x02, 0, 0}, {0x3809, 0x80, 0, 0}, {0x380a, 0x01, 0, 0},
+ {0x380b, 0xe0, 0, 0}, {0x380c, 0x07, 0, 0}, {0x380d, 0x68, 0, 0},
+ {0x380e, 0x04, 0, 0}, {0x380f, 0x38, 0, 0}, {0x3810, 0x00, 0, 0},
+ {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x06, 0, 0},
+ {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0},
+ {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x03, 0, 0},
+ {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x0e, 0, 0},
+ {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0},
+ {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0},
+ {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x4713, 0x03, 0, 0},
+ {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0},
+ {0x3824, 0x02, 0, 0}, {0x5001, 0xa3, 0, 0}, {0x3503, 0x00, 0, 0},
+ {0x3808, 0x04, 0, 0}, {0x3809, 0x00, 0, 0}, {0x380a, 0x03, 0, 0},
+ {0x380b, 0x00, 0, 0}, {0x3035, 0x12, 0, 0},
+};
+
+static struct reg_value ov5640_setting_15fps_XGA_1024_768[] = {
+ {0x3035, 0x22, 0, 0}, {0x3036, 0x38, 0, 0}, {0x3c07, 0x08, 0, 0},
+ {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
+ {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0},
+ {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
+ {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0}, {0x3804, 0x0a, 0, 0},
+ {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9b, 0, 0},
+ {0x3808, 0x02, 0, 0}, {0x3809, 0x80, 0, 0}, {0x380a, 0x01, 0, 0},
+ {0x380b, 0xe0, 0, 0}, {0x380c, 0x07, 0, 0}, {0x380d, 0x68, 0, 0},
+ {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0}, {0x3810, 0x00, 0, 0},
+ {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x06, 0, 0},
+ {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0},
+ {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x03, 0, 0},
+ {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0},
+ {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0},
+ {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0},
+ {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x4713, 0x03, 0, 0},
+ {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0},
+ {0x3824, 0x02, 0, 0}, {0x5001, 0xa3, 0, 0}, {0x3808, 0x04, 0, 0},
+ {0x3809, 0x00, 0, 0}, {0x380a, 0x03, 0, 0}, {0x380b, 0x00, 0, 0},
+};
+
+static struct reg_value ov5640_setting_30fps_QVGA_320_240[] = {
+ {0x3035, 0x14, 0, 0}, {0x3036, 0x38, 0, 0}, {0x3c07, 0x08, 0, 0},
+ {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
+ {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0},
+ {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
+ {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0}, {0x3804, 0x0a, 0, 0},
+ {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9b, 0, 0},
+ {0x3808, 0x01, 0, 0}, {0x3809, 0x40, 0, 0}, {0x380a, 0x00, 0, 0},
+ {0x380b, 0xf0, 0, 0}, {0x380c, 0x07, 0, 0}, {0x380d, 0x68, 0, 0},
+ {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0}, {0x3810, 0x00, 0, 0},
+ {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x06, 0, 0},
+ {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0},
+ {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x03, 0, 0},
+ {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0},
+ {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0},
+ {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0},
+ {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x4713, 0x03, 0, 0},
+ {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0},
+ {0x3824, 0x02, 0, 0}, {0x5001, 0xa3, 0, 0},
+};
+
+static struct reg_value ov5640_setting_15fps_QVGA_320_240[] = {
+ {0x3035, 0x22, 0, 0}, {0x3036, 0x38, 0, 0}, {0x3c07, 0x08, 0, 0},
+ {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
+ {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0},
+ {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
+ {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0}, {0x3804, 0x0a, 0, 0},
+ {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9b, 0, 0},
+ {0x3808, 0x01, 0, 0}, {0x3809, 0x40, 0, 0}, {0x380a, 0x00, 0, 0},
+ {0x380b, 0xf0, 0, 0}, {0x380c, 0x07, 0, 0}, {0x380d, 0x68, 0, 0},
+ {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0}, {0x3810, 0x00, 0, 0},
+ {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x06, 0, 0},
+ {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0},
+ {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x03, 0, 0},
+ {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0},
+ {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0},
+ {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0},
+ {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x4713, 0x03, 0, 0},
+ {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0},
+ {0x3824, 0x02, 0, 0}, {0x5001, 0xa3, 0, 0},
+};
+
+static struct reg_value ov5640_setting_30fps_QCIF_176_144[] = {
+ {0x3035, 0x14, 0, 0}, {0x3036, 0x38, 0, 0}, {0x3c07, 0x08, 0, 0},
+ {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
+ {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0},
+ {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
+ {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0}, {0x3804, 0x0a, 0, 0},
+ {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9b, 0, 0},
+ {0x3808, 0x00, 0, 0}, {0x3809, 0xb0, 0, 0}, {0x380a, 0x00, 0, 0},
+ {0x380b, 0x90, 0, 0}, {0x380c, 0x07, 0, 0}, {0x380d, 0x68, 0, 0},
+ {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0}, {0x3810, 0x00, 0, 0},
+ {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x06, 0, 0},
+ {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0},
+ {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x03, 0, 0},
+ {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0},
+ {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0},
+ {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0},
+ {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x4713, 0x03, 0, 0},
+ {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0},
+ {0x3824, 0x02, 0, 0}, {0x5001, 0xa3, 0, 0},
+};
+static struct reg_value ov5640_setting_15fps_QCIF_176_144[] = {
+ {0x3035, 0x22, 0, 0}, {0x3036, 0x38, 0, 0}, {0x3c07, 0x08, 0, 0},
+ {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
+ {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0},
+ {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
+ {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0}, {0x3804, 0x0a, 0, 0},
+ {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9b, 0, 0},
+ {0x3808, 0x00, 0, 0}, {0x3809, 0xb0, 0, 0}, {0x380a, 0x00, 0, 0},
+ {0x380b, 0x90, 0, 0}, {0x380c, 0x07, 0, 0}, {0x380d, 0x68, 0, 0},
+ {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0}, {0x3810, 0x00, 0, 0},
+ {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x06, 0, 0},
+ {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0},
+ {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x03, 0, 0},
+ {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0},
+ {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0},
+ {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0},
+ {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x4713, 0x03, 0, 0},
+ {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0},
+ {0x3824, 0x02, 0, 0}, {0x5001, 0xa3, 0, 0},
+};
+
+static struct reg_value ov5640_setting_30fps_NTSC_720_480[] = {
+ {0x3035, 0x12, 0, 0}, {0x3036, 0x38, 0, 0}, {0x3c07, 0x08, 0, 0},
+ {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
+ {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0},
+ {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
+ {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0}, {0x3804, 0x0a, 0, 0},
+ {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9b, 0, 0},
+ {0x3808, 0x02, 0, 0}, {0x3809, 0xd0, 0, 0}, {0x380a, 0x01, 0, 0},
+ {0x380b, 0xe0, 0, 0}, {0x380c, 0x07, 0, 0}, {0x380d, 0x68, 0, 0},
+ {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0}, {0x3810, 0x00, 0, 0},
+ {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x3c, 0, 0},
+ {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0},
+ {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x03, 0, 0},
+ {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0},
+ {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0},
+ {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0},
+ {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x4713, 0x03, 0, 0},
+ {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0},
+ {0x3824, 0x02, 0, 0}, {0x5001, 0xa3, 0, 0},
+};
+
+static struct reg_value ov5640_setting_15fps_NTSC_720_480[] = {
+ {0x3035, 0x22, 0, 0}, {0x3036, 0x38, 0, 0}, {0x3c07, 0x08, 0, 0},
+ {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
+ {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0},
+ {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
+ {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0}, {0x3804, 0x0a, 0, 0},
+ {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9b, 0, 0},
+ {0x3808, 0x02, 0, 0}, {0x3809, 0xd0, 0, 0}, {0x380a, 0x01, 0, 0},
+ {0x380b, 0xe0, 0, 0}, {0x380c, 0x07, 0, 0}, {0x380d, 0x68, 0, 0},
+ {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0}, {0x3810, 0x00, 0, 0},
+ {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x3c, 0, 0},
+ {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0},
+ {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x03, 0, 0},
+ {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0},
+ {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0},
+ {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0},
+ {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x4713, 0x03, 0, 0},
+ {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0},
+ {0x3824, 0x02, 0, 0}, {0x5001, 0xa3, 0, 0},
+};
+
+static struct reg_value ov5640_setting_30fps_PAL_720_576[] = {
+ {0x3035, 0x12, 0, 0}, {0x3036, 0x38, 0, 0}, {0x3c07, 0x08, 0, 0},
+ {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
+ {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0},
+ {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
+ {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0}, {0x3804, 0x0a, 0, 0},
+ {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9b, 0, 0},
+ {0x3808, 0x02, 0, 0}, {0x3809, 0xd0, 0, 0}, {0x380a, 0x02, 0, 0},
+ {0x380b, 0x40, 0, 0}, {0x380c, 0x07, 0, 0}, {0x380d, 0x68, 0, 0},
+ {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0}, {0x3810, 0x00, 0, 0},
+ {0x3811, 0x38, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x06, 0, 0},
+ {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0},
+ {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x03, 0, 0},
+ {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0},
+ {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0},
+ {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0},
+ {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x4713, 0x03, 0, 0},
+ {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0},
+ {0x3824, 0x02, 0, 0}, {0x5001, 0xa3, 0, 0},
+};
+
+static struct reg_value ov5640_setting_15fps_PAL_720_576[] = {
+ {0x3035, 0x22, 0, 0}, {0x3036, 0x38, 0, 0}, {0x3c07, 0x08, 0, 0},
+ {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
+ {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0},
+ {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
+ {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0}, {0x3804, 0x0a, 0, 0},
+ {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9b, 0, 0},
+ {0x3808, 0x02, 0, 0}, {0x3809, 0xd0, 0, 0}, {0x380a, 0x02, 0, 0},
+ {0x380b, 0x40, 0, 0}, {0x380c, 0x07, 0, 0}, {0x380d, 0x68, 0, 0},
+ {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0}, {0x3810, 0x00, 0, 0},
+ {0x3811, 0x38, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x06, 0, 0},
+ {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0},
+ {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x03, 0, 0},
+ {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0},
+ {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0},
+ {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0},
+ {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x4713, 0x03, 0, 0},
+ {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0},
+ {0x3824, 0x02, 0, 0}, {0x5001, 0xa3, 0, 0},
+};
+
+static struct reg_value ov5640_setting_30fps_720P_1280_720[] = {
+ {0x3008, 0x42, 0, 0},
+ {0x3035, 0x21, 0, 0}, {0x3036, 0x54, 0, 0}, {0x3c07, 0x07, 0, 0},
+ {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
+ {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0},
+ {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
+ {0x3802, 0x00, 0, 0}, {0x3803, 0xfa, 0, 0}, {0x3804, 0x0a, 0, 0},
+ {0x3805, 0x3f, 0, 0}, {0x3806, 0x06, 0, 0}, {0x3807, 0xa9, 0, 0},
+ {0x3808, 0x05, 0, 0}, {0x3809, 0x00, 0, 0}, {0x380a, 0x02, 0, 0},
+ {0x380b, 0xd0, 0, 0}, {0x380c, 0x07, 0, 0}, {0x380d, 0x64, 0, 0},
+ {0x380e, 0x02, 0, 0}, {0x380f, 0xe4, 0, 0}, {0x3810, 0x00, 0, 0},
+ {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x04, 0, 0},
+ {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0},
+ {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x02, 0, 0},
+ {0x3a03, 0xe4, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0xbc, 0, 0},
+ {0x3a0a, 0x01, 0, 0}, {0x3a0b, 0x72, 0, 0}, {0x3a0e, 0x01, 0, 0},
+ {0x3a0d, 0x02, 0, 0}, {0x3a14, 0x02, 0, 0}, {0x3a15, 0xe4, 0, 0},
+ {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x4713, 0x02, 0, 0},
+ {0x4407, 0x04, 0, 0}, {0x460b, 0x37, 0, 0}, {0x460c, 0x20, 0, 0},
+ {0x3824, 0x04, 0, 0}, {0x5001, 0x83, 0, 0}, {0x4005, 0x1a, 0, 0},
+ {0x3008, 0x02, 0, 0}, {0x3503, 0, 0, 0},
+};
+
+static struct reg_value ov5640_setting_15fps_720P_1280_720[] = {
+ {0x3035, 0x41, 0, 0}, {0x3036, 0x54, 0, 0}, {0x3c07, 0x07, 0, 0},
+ {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
+ {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0},
+ {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
+ {0x3802, 0x00, 0, 0}, {0x3803, 0xfa, 0, 0}, {0x3804, 0x0a, 0, 0},
+ {0x3805, 0x3f, 0, 0}, {0x3806, 0x06, 0, 0}, {0x3807, 0xa9, 0, 0},
+ {0x3808, 0x05, 0, 0}, {0x3809, 0x00, 0, 0}, {0x380a, 0x02, 0, 0},
+ {0x380b, 0xd0, 0, 0}, {0x380c, 0x07, 0, 0}, {0x380d, 0x64, 0, 0},
+ {0x380e, 0x02, 0, 0}, {0x380f, 0xe4, 0, 0}, {0x3810, 0x00, 0, 0},
+ {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x04, 0, 0},
+ {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0},
+ {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x02, 0, 0},
+ {0x3a03, 0xe4, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0xbc, 0, 0},
+ {0x3a0a, 0x01, 0, 0}, {0x3a0b, 0x72, 0, 0}, {0x3a0e, 0x01, 0, 0},
+ {0x3a0d, 0x02, 0, 0}, {0x3a14, 0x02, 0, 0}, {0x3a15, 0xe4, 0, 0},
+ {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x4713, 0x02, 0, 0},
+ {0x4407, 0x04, 0, 0}, {0x460b, 0x37, 0, 0}, {0x460c, 0x20, 0, 0},
+ {0x3824, 0x04, 0, 0}, {0x5001, 0x83, 0, 0},
+};
+
+static struct reg_value ov5640_setting_30fps_1080P_1920_1080[] = {
+ {0x3008, 0x42, 0, 0},
+ {0x3035, 0x21, 0, 0}, {0x3036, 0x54, 0, 0}, {0x3c07, 0x08, 0, 0},
+ {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
+ {0x3820, 0x40, 0, 0}, {0x3821, 0x06, 0, 0}, {0x3814, 0x11, 0, 0},
+ {0x3815, 0x11, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
+ {0x3802, 0x00, 0, 0}, {0x3803, 0x00, 0, 0}, {0x3804, 0x0a, 0, 0},
+ {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9f, 0, 0},
+ {0x3808, 0x0a, 0, 0}, {0x3809, 0x20, 0, 0}, {0x380a, 0x07, 0, 0},
+ {0x380b, 0x98, 0, 0}, {0x380c, 0x0b, 0, 0}, {0x380d, 0x1c, 0, 0},
+ {0x380e, 0x07, 0, 0}, {0x380f, 0xb0, 0, 0}, {0x3810, 0x00, 0, 0},
+ {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x04, 0, 0},
+ {0x3618, 0x04, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x21, 0, 0},
+ {0x3709, 0x12, 0, 0}, {0x370c, 0x00, 0, 0}, {0x3a02, 0x03, 0, 0},
+ {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0},
+ {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0},
+ {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0},
+ {0x4001, 0x02, 0, 0}, {0x4004, 0x06, 0, 0}, {0x4713, 0x03, 0, 0},
+ {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0},
+ {0x3824, 0x02, 0, 0}, {0x5001, 0x83, 0, 0}, {0x3035, 0x11, 0, 0},
+ {0x3036, 0x54, 0, 0}, {0x3c07, 0x07, 0, 0}, {0x3c08, 0x00, 0, 0},
+ {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
+ {0x3800, 0x01, 0, 0}, {0x3801, 0x50, 0, 0}, {0x3802, 0x01, 0, 0},
+ {0x3803, 0xb2, 0, 0}, {0x3804, 0x08, 0, 0}, {0x3805, 0xef, 0, 0},
+ {0x3806, 0x05, 0, 0}, {0x3807, 0xf1, 0, 0}, {0x3808, 0x07, 0, 0},
+ {0x3809, 0x80, 0, 0}, {0x380a, 0x04, 0, 0}, {0x380b, 0x38, 0, 0},
+ {0x380c, 0x09, 0, 0}, {0x380d, 0xc4, 0, 0}, {0x380e, 0x04, 0, 0},
+ {0x380f, 0x60, 0, 0}, {0x3612, 0x2b, 0, 0}, {0x3708, 0x64, 0, 0},
+ {0x3a02, 0x04, 0, 0}, {0x3a03, 0x60, 0, 0}, {0x3a08, 0x01, 0, 0},
+ {0x3a09, 0x50, 0, 0}, {0x3a0a, 0x01, 0, 0}, {0x3a0b, 0x18, 0, 0},
+ {0x3a0e, 0x03, 0, 0}, {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x04, 0, 0},
+ {0x3a15, 0x60, 0, 0}, {0x4713, 0x02, 0, 0}, {0x4407, 0x04, 0, 0},
+ {0x460b, 0x37, 0, 0}, {0x460c, 0x20, 0, 0}, {0x3824, 0x04, 0, 0},
+ {0x4005, 0x1a, 0, 0}, {0x3008, 0x02, 0, 0},
+ {0x3503, 0, 0, 0},
+};
+
+static struct reg_value ov5640_setting_15fps_1080P_1920_1080[] = {
+ {0x3008, 0x42, 0, 0},
+ {0x3035, 0x21, 0, 0}, {0x3036, 0x54, 0, 0}, {0x3c07, 0x08, 0, 0},
+ {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
+ {0x3820, 0x40, 0, 0}, {0x3821, 0x06, 0, 0}, {0x3814, 0x11, 0, 0},
+ {0x3815, 0x11, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
+ {0x3802, 0x00, 0, 0}, {0x3803, 0x00, 0, 0}, {0x3804, 0x0a, 0, 0},
+ {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9f, 0, 0},
+ {0x3808, 0x0a, 0, 0}, {0x3809, 0x20, 0, 0}, {0x380a, 0x07, 0, 0},
+ {0x380b, 0x98, 0, 0}, {0x380c, 0x0b, 0, 0}, {0x380d, 0x1c, 0, 0},
+ {0x380e, 0x07, 0, 0}, {0x380f, 0xb0, 0, 0}, {0x3810, 0x00, 0, 0},
+ {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x04, 0, 0},
+ {0x3618, 0x04, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x21, 0, 0},
+ {0x3709, 0x12, 0, 0}, {0x370c, 0x00, 0, 0}, {0x3a02, 0x03, 0, 0},
+ {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0},
+ {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0},
+ {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0},
+ {0x4001, 0x02, 0, 0}, {0x4004, 0x06, 0, 0}, {0x4713, 0x03, 0, 0},
+ {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0},
+ {0x3824, 0x02, 0, 0}, {0x5001, 0x83, 0, 0}, {0x3035, 0x21, 0, 0},
+ {0x3036, 0x54, 0, 1}, {0x3c07, 0x07, 0, 0}, {0x3c08, 0x00, 0, 0},
+ {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
+ {0x3800, 0x01, 0, 0}, {0x3801, 0x50, 0, 0}, {0x3802, 0x01, 0, 0},
+ {0x3803, 0xb2, 0, 0}, {0x3804, 0x08, 0, 0}, {0x3805, 0xef, 0, 0},
+ {0x3806, 0x05, 0, 0}, {0x3807, 0xf1, 0, 0}, {0x3808, 0x07, 0, 0},
+ {0x3809, 0x80, 0, 0}, {0x380a, 0x04, 0, 0}, {0x380b, 0x38, 0, 0},
+ {0x380c, 0x09, 0, 0}, {0x380d, 0xc4, 0, 0}, {0x380e, 0x04, 0, 0},
+ {0x380f, 0x60, 0, 0}, {0x3612, 0x2b, 0, 0}, {0x3708, 0x64, 0, 0},
+ {0x3a02, 0x04, 0, 0}, {0x3a03, 0x60, 0, 0}, {0x3a08, 0x01, 0, 0},
+ {0x3a09, 0x50, 0, 0}, {0x3a0a, 0x01, 0, 0}, {0x3a0b, 0x18, 0, 0},
+ {0x3a0e, 0x03, 0, 0}, {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x04, 0, 0},
+ {0x3a15, 0x60, 0, 0}, {0x4713, 0x02, 0, 0}, {0x4407, 0x04, 0, 0},
+ {0x460b, 0x37, 0, 0}, {0x460c, 0x20, 0, 0}, {0x3824, 0x04, 0, 0},
+ {0x4005, 0x1a, 0, 0}, {0x3008, 0x02, 0, 0}, {0x3503, 0, 0, 0},
+};
+
+static struct reg_value ov5640_setting_15fps_QSXGA_2592_1944[] = {
+ {0x4202, 0x0f, 0, 0}, /* stream off the sensor */
+ {0x3820, 0x40, 0, 0}, {0x3821, 0x06, 0, 0}, /*disable flip*/
+ {0x3035, 0x21, 0, 0}, {0x3036, 0x54, 0, 0}, {0x3c07, 0x08, 0, 0},
+ {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
+ {0x3820, 0x40, 0, 0}, {0x3821, 0x06, 0, 0}, {0x3814, 0x11, 0, 0},
+ {0x3815, 0x11, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
+ {0x3802, 0x00, 0, 0}, {0x3803, 0x00, 0, 0}, {0x3804, 0x0a, 0, 0},
+ {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9f, 0, 0},
+ {0x3808, 0x0a, 0, 0}, {0x3809, 0x20, 0, 0}, {0x380a, 0x07, 0, 0},
+ {0x380b, 0x98, 0, 0}, {0x380c, 0x0b, 0, 0}, {0x380d, 0x1c, 0, 0},
+ {0x380e, 0x07, 0, 0}, {0x380f, 0xb0, 0, 0}, {0x3810, 0x00, 0, 0},
+ {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x04, 0, 0},
+ {0x3618, 0x04, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x21, 0, 0},
+ {0x3709, 0x12, 0, 0}, {0x370c, 0x00, 0, 0}, {0x3a02, 0x03, 0, 0},
+ {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0},
+ {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0},
+ {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0},
+ {0x4001, 0x02, 0, 0}, {0x4004, 0x06, 0, 0}, {0x4713, 0x03, 0, 0},
+ {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0},
+ {0x3824, 0x02, 0, 0}, {0x5001, 0x83, 0, 70},
+ {0x4202, 0x00, 0, 0}, /* stream on the sensor */
+};
+
+static struct ov5640_mode_info ov5640_mode_info_data[2][ov5640_mode_MAX + 1] = {
+ {
+ {ov5640_mode_VGA_640_480, SUBSAMPLING, 640, 480,
+ ov5640_setting_15fps_VGA_640_480,
+ ARRAY_SIZE(ov5640_setting_15fps_VGA_640_480)},
+ {ov5640_mode_QVGA_320_240, SUBSAMPLING, 320, 240,
+ ov5640_setting_15fps_QVGA_320_240,
+ ARRAY_SIZE(ov5640_setting_15fps_QVGA_320_240)},
+ {ov5640_mode_NTSC_720_480, SUBSAMPLING, 720, 480,
+ ov5640_setting_15fps_NTSC_720_480,
+ ARRAY_SIZE(ov5640_setting_15fps_NTSC_720_480)},
+ {ov5640_mode_PAL_720_576, SUBSAMPLING, 720, 576,
+ ov5640_setting_15fps_PAL_720_576,
+ ARRAY_SIZE(ov5640_setting_15fps_PAL_720_576)},
+ {ov5640_mode_720P_1280_720, SUBSAMPLING, 1280, 720,
+ ov5640_setting_15fps_720P_1280_720,
+ ARRAY_SIZE(ov5640_setting_15fps_720P_1280_720)},
+ {ov5640_mode_1080P_1920_1080, SCALING, 1920, 1080,
+ ov5640_setting_15fps_1080P_1920_1080,
+ ARRAY_SIZE(ov5640_setting_15fps_1080P_1920_1080)},
+ {ov5640_mode_QSXGA_2592_1944, SCALING, 2592, 1944,
+ ov5640_setting_15fps_QSXGA_2592_1944,
+ ARRAY_SIZE(ov5640_setting_15fps_QSXGA_2592_1944)},
+ {ov5640_mode_QCIF_176_144, SUBSAMPLING, 176, 144,
+ ov5640_setting_15fps_QCIF_176_144,
+ ARRAY_SIZE(ov5640_setting_15fps_QCIF_176_144)},
+ {ov5640_mode_XGA_1024_768, SUBSAMPLING, 1024, 768,
+ ov5640_setting_15fps_XGA_1024_768,
+ ARRAY_SIZE(ov5640_setting_15fps_XGA_1024_768)},
+ },
+ {
+ {ov5640_mode_VGA_640_480, SUBSAMPLING, 640, 480,
+ ov5640_setting_30fps_VGA_640_480,
+ ARRAY_SIZE(ov5640_setting_30fps_VGA_640_480)},
+ {ov5640_mode_QVGA_320_240, SUBSAMPLING, 320, 240,
+ ov5640_setting_30fps_QVGA_320_240,
+ ARRAY_SIZE(ov5640_setting_30fps_QVGA_320_240)},
+ {ov5640_mode_NTSC_720_480, SUBSAMPLING, 720, 480,
+ ov5640_setting_30fps_NTSC_720_480,
+ ARRAY_SIZE(ov5640_setting_30fps_NTSC_720_480)},
+ {ov5640_mode_PAL_720_576, SUBSAMPLING, 720, 576,
+ ov5640_setting_30fps_PAL_720_576,
+ ARRAY_SIZE(ov5640_setting_30fps_PAL_720_576)},
+ {ov5640_mode_720P_1280_720, SUBSAMPLING, 1280, 720,
+ ov5640_setting_30fps_720P_1280_720,
+ ARRAY_SIZE(ov5640_setting_30fps_720P_1280_720)},
+ {ov5640_mode_1080P_1920_1080, SCALING, 1920, 1080,
+ ov5640_setting_30fps_1080P_1920_1080,
+ ARRAY_SIZE(ov5640_setting_30fps_1080P_1920_1080)},
+ {ov5640_mode_QSXGA_2592_1944, -1, 0, 0, NULL, 0},
+ {ov5640_mode_QCIF_176_144, SUBSAMPLING, 176, 144,
+ ov5640_setting_30fps_QCIF_176_144,
+ ARRAY_SIZE(ov5640_setting_30fps_QCIF_176_144)},
+ {ov5640_mode_XGA_1024_768, SUBSAMPLING, 1024, 768,
+ ov5640_setting_30fps_XGA_1024_768,
+ ARRAY_SIZE(ov5640_setting_30fps_XGA_1024_768)},
+ },
+};
+
+static struct regulator *io_regulator;
+static struct regulator *core_regulator;
+static struct regulator *analog_regulator;
+static struct regulator *gpo_regulator;
+
+static int ov5640_probe(struct i2c_client *adapter,
+ const struct i2c_device_id *device_id);
+static int ov5640_remove(struct i2c_client *client);
+
+static s32 ov5640_read_reg(u16 reg, u8 *val);
+static s32 ov5640_write_reg(u16 reg, u8 val);
+
+static const struct i2c_device_id ov5640_id[] = {
+ {"ov564x_mipi", 0},
+ {},
+};
+
+MODULE_DEVICE_TABLE(i2c, ov5640_id);
+
+static struct i2c_driver ov5640_i2c_driver = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "ov564x_mipi",
+ },
+ .probe = ov5640_probe,
+ .remove = ov5640_remove,
+ .id_table = ov5640_id,
+};
+
+static void ov5640_standby(s32 enable)
+{
+ if (enable)
+ gpio_set_value(pwn_gpio, 1);
+ else
+ gpio_set_value(pwn_gpio, 0);
+
+ msleep(100);
+}
+
+static void ov5640_reset(void)
+{
+ /* camera reset */
+ gpio_set_value(rst_gpio, 1);
+
+ /* camera power dowmn */
+ gpio_set_value(pwn_gpio, 1);
+ msleep(5);
+
+ gpio_set_value(pwn_gpio, 0);
+ msleep(5);
+
+ gpio_set_value(rst_gpio, 0);
+ msleep(1);
+
+ gpio_set_value(rst_gpio, 1);
+ msleep(5);
+
+ gpio_set_value(pwn_gpio, 1);
+}
+
+static int ov5640_power_on(struct device *dev)
+{
+ int ret = 0;
+
+ io_regulator = devm_regulator_get(dev, "DOVDD");
+ if (!IS_ERR(io_regulator)) {
+ regulator_set_voltage(io_regulator,
+ OV5640_VOLTAGE_DIGITAL_IO,
+ OV5640_VOLTAGE_DIGITAL_IO);
+ ret = regulator_enable(io_regulator);
+ if (ret) {
+ pr_err("%s:io set voltage error\n", __func__);
+ return ret;
+ } else {
+ dev_dbg(dev,
+ "%s:io set voltage ok\n", __func__);
+ }
+ } else {
+ pr_err("%s: cannot get io voltage error\n", __func__);
+ io_regulator = NULL;
+ }
+
+ core_regulator = devm_regulator_get(dev, "DVDD");
+ if (!IS_ERR(core_regulator)) {
+ regulator_set_voltage(core_regulator,
+ OV5640_VOLTAGE_DIGITAL_CORE,
+ OV5640_VOLTAGE_DIGITAL_CORE);
+ ret = regulator_enable(core_regulator);
+ if (ret) {
+ pr_err("%s:core set voltage error\n", __func__);
+ return ret;
+ } else {
+ dev_dbg(dev,
+ "%s:core set voltage ok\n", __func__);
+ }
+ } else {
+ core_regulator = NULL;
+ pr_err("%s: cannot get core voltage error\n", __func__);
+ }
+
+ analog_regulator = devm_regulator_get(dev, "AVDD");
+ if (!IS_ERR(analog_regulator)) {
+ regulator_set_voltage(analog_regulator,
+ OV5640_VOLTAGE_ANALOG,
+ OV5640_VOLTAGE_ANALOG);
+ ret = regulator_enable(analog_regulator);
+ if (ret) {
+ pr_err("%s:analog set voltage error\n",
+ __func__);
+ return ret;
+ } else {
+ dev_dbg(dev,
+ "%s:analog set voltage ok\n", __func__);
+ }
+ } else {
+ analog_regulator = NULL;
+ pr_err("%s: cannot get analog voltage error\n", __func__);
+ }
+
+ return ret;
+}
+
+static s32 ov5640_write_reg(u16 reg, u8 val)
+{
+ u8 au8Buf[3] = {0};
+
+ au8Buf[0] = reg >> 8;
+ au8Buf[1] = reg & 0xff;
+ au8Buf[2] = val;
+
+ if (i2c_master_send(ov5640_data.i2c_client, au8Buf, 3) < 0) {
+ pr_err("%s:write reg error:reg=%x,val=%x\n",
+ __func__, reg, val);
+ return -1;
+ }
+
+ return 0;
+}
+
+static s32 ov5640_read_reg(u16 reg, u8 *val)
+{
+ u8 au8RegBuf[2] = {0};
+ u8 u8RdVal = 0;
+
+ au8RegBuf[0] = reg >> 8;
+ au8RegBuf[1] = reg & 0xff;
+
+ if (2 != i2c_master_send(ov5640_data.i2c_client, au8RegBuf, 2)) {
+ pr_err("%s:write reg error:reg=%x\n",
+ __func__, reg);
+ return -1;
+ }
+
+ if (1 != i2c_master_recv(ov5640_data.i2c_client, &u8RdVal, 1)) {
+ pr_err("%s:read reg error:reg=%x,val=%x\n",
+ __func__, reg, u8RdVal);
+ return -1;
+ }
+
+ *val = u8RdVal;
+
+ return u8RdVal;
+}
+
+static int prev_sysclk, prev_HTS;
+static int AE_low, AE_high, AE_Target = 52;
+
+static void OV5640_stream_on(void)
+{
+ ov5640_write_reg(0x4202, 0x00);
+}
+
+static void OV5640_stream_off(void)
+{
+ ov5640_write_reg(0x4202, 0x0f);
+}
+
+
+static int OV5640_get_sysclk(void)
+{
+ /* calculate sysclk */
+ int xvclk = ov5640_data.mclk / 10000;
+ int temp1, temp2;
+ int Multiplier, PreDiv, VCO, SysDiv, Pll_rdiv;
+ int Bit_div2x = 1, sclk_rdiv, sysclk;
+ u8 temp;
+
+ int sclk_rdiv_map[] = {1, 2, 4, 8};
+
+ temp1 = ov5640_read_reg(0x3034, &temp);
+ temp2 = temp1 & 0x0f;
+ if (temp2 == 8 || temp2 == 10)
+ Bit_div2x = temp2 / 2;
+
+ temp1 = ov5640_read_reg(0x3035, &temp);
+ SysDiv = temp1>>4;
+ if (SysDiv == 0)
+ SysDiv = 16;
+
+ temp1 = ov5640_read_reg(0x3036, &temp);
+ Multiplier = temp1;
+
+ temp1 = ov5640_read_reg(0x3037, &temp);
+ PreDiv = temp1 & 0x0f;
+ Pll_rdiv = ((temp1 >> 4) & 0x01) + 1;
+
+ temp1 = ov5640_read_reg(0x3108, &temp);
+ temp2 = temp1 & 0x03;
+ sclk_rdiv = sclk_rdiv_map[temp2];
+
+ VCO = xvclk * Multiplier / PreDiv;
+
+ sysclk = VCO / SysDiv / Pll_rdiv * 2 / Bit_div2x / sclk_rdiv;
+
+ return sysclk;
+}
+
+static void OV5640_set_night_mode(void)
+{
+ /* read HTS from register settings */
+ u8 mode;
+
+ ov5640_read_reg(0x3a00, &mode);
+ mode &= 0xfb;
+ ov5640_write_reg(0x3a00, mode);
+}
+
+static int OV5640_get_HTS(void)
+{
+ /* read HTS from register settings */
+ int HTS;
+ u8 temp;
+
+ HTS = ov5640_read_reg(0x380c, &temp);
+ HTS = (HTS<<8) + ov5640_read_reg(0x380d, &temp);
+
+ return HTS;
+}
+
+static int OV5640_get_VTS(void)
+{
+ /* read VTS from register settings */
+ int VTS;
+ u8 temp;
+
+ /* total vertical size[15:8] high byte */
+ VTS = ov5640_read_reg(0x380e, &temp);
+
+ VTS = (VTS<<8) + ov5640_read_reg(0x380f, &temp);
+
+ return VTS;
+}
+
+static int OV5640_set_VTS(int VTS)
+{
+ /* write VTS to registers */
+ int temp;
+
+ temp = VTS & 0xff;
+ ov5640_write_reg(0x380f, temp);
+
+ temp = VTS>>8;
+ ov5640_write_reg(0x380e, temp);
+
+ return 0;
+}
+
+static int OV5640_get_shutter(void)
+{
+ /* read shutter, in number of line period */
+ int shutter;
+ u8 temp;
+
+ shutter = (ov5640_read_reg(0x03500, &temp) & 0x0f);
+ shutter = (shutter<<8) + ov5640_read_reg(0x3501, &temp);
+ shutter = (shutter<<4) + (ov5640_read_reg(0x3502, &temp)>>4);
+
+ return shutter;
+}
+
+static int OV5640_set_shutter(int shutter)
+{
+ /* write shutter, in number of line period */
+ int temp;
+
+ shutter = shutter & 0xffff;
+
+ temp = shutter & 0x0f;
+ temp = temp<<4;
+ ov5640_write_reg(0x3502, temp);
+
+ temp = shutter & 0xfff;
+ temp = temp>>4;
+ ov5640_write_reg(0x3501, temp);
+
+ temp = shutter>>12;
+ ov5640_write_reg(0x3500, temp);
+
+ return 0;
+}
+
+static int OV5640_get_gain16(void)
+{
+ /* read gain, 16 = 1x */
+ int gain16;
+ u8 temp;
+
+ gain16 = ov5640_read_reg(0x350a, &temp) & 0x03;
+ gain16 = (gain16<<8) + ov5640_read_reg(0x350b, &temp);
+
+ return gain16;
+}
+
+static int OV5640_set_gain16(int gain16)
+{
+ /* write gain, 16 = 1x */
+ u8 temp;
+ gain16 = gain16 & 0x3ff;
+
+ temp = gain16 & 0xff;
+ ov5640_write_reg(0x350b, temp);
+
+ temp = gain16>>8;
+ ov5640_write_reg(0x350a, temp);
+
+ return 0;
+}
+
+static int OV5640_get_light_freq(void)
+{
+ /* get banding filter value */
+ int temp, temp1, light_freq = 0;
+ u8 tmp;
+
+ temp = ov5640_read_reg(0x3c01, &tmp);
+
+ if (temp & 0x80) {
+ /* manual */
+ temp1 = ov5640_read_reg(0x3c00, &tmp);
+ if (temp1 & 0x04) {
+ /* 50Hz */
+ light_freq = 50;
+ } else {
+ /* 60Hz */
+ light_freq = 60;
+ }
+ } else {
+ /* auto */
+ temp1 = ov5640_read_reg(0x3c0c, &tmp);
+ if (temp1 & 0x01) {
+ /* 50Hz */
+ light_freq = 50;
+ } else {
+ /* 60Hz */
+ }
+ }
+ return light_freq;
+}
+
+static void OV5640_set_bandingfilter(void)
+{
+ int prev_VTS;
+ int band_step60, max_band60, band_step50, max_band50;
+
+ /* read preview PCLK */
+ prev_sysclk = OV5640_get_sysclk();
+ /* read preview HTS */
+ prev_HTS = OV5640_get_HTS();
+
+ /* read preview VTS */
+ prev_VTS = OV5640_get_VTS();
+
+ /* calculate banding filter */
+ /* 60Hz */
+ band_step60 = prev_sysclk * 100/prev_HTS * 100/120;
+ ov5640_write_reg(0x3a0a, (band_step60 >> 8));
+ ov5640_write_reg(0x3a0b, (band_step60 & 0xff));
+
+ max_band60 = (int)((prev_VTS-4)/band_step60);
+ ov5640_write_reg(0x3a0d, max_band60);
+
+ /* 50Hz */
+ band_step50 = prev_sysclk * 100/prev_HTS;
+ ov5640_write_reg(0x3a08, (band_step50 >> 8));
+ ov5640_write_reg(0x3a09, (band_step50 & 0xff));
+
+ max_band50 = (int)((prev_VTS-4)/band_step50);
+ ov5640_write_reg(0x3a0e, max_band50);
+}
+
+static int OV5640_set_AE_target(int target)
+{
+ /* stable in high */
+ int fast_high, fast_low;
+ AE_low = target * 23 / 25; /* 0.92 */
+ AE_high = target * 27 / 25; /* 1.08 */
+
+ fast_high = AE_high<<1;
+ if (fast_high > 255)
+ fast_high = 255;
+
+ fast_low = AE_low >> 1;
+
+ ov5640_write_reg(0x3a0f, AE_high);
+ ov5640_write_reg(0x3a10, AE_low);
+ ov5640_write_reg(0x3a1b, AE_high);
+ ov5640_write_reg(0x3a1e, AE_low);
+ ov5640_write_reg(0x3a11, fast_high);
+ ov5640_write_reg(0x3a1f, fast_low);
+
+ return 0;
+}
+
+static void OV5640_turn_on_AE_AG(int enable)
+{
+ u8 ae_ag_ctrl;
+
+ ov5640_read_reg(0x3503, &ae_ag_ctrl);
+ if (enable) {
+ /* turn on auto AE/AG */
+ ae_ag_ctrl = ae_ag_ctrl & ~(0x03);
+ } else {
+ /* turn off AE/AG */
+ ae_ag_ctrl = ae_ag_ctrl | 0x03;
+ }
+ ov5640_write_reg(0x3503, ae_ag_ctrl);
+}
+
+static bool binning_on(void)
+{
+ u8 temp;
+ ov5640_read_reg(0x3821, &temp);
+ temp &= 0xfe;
+ if (temp)
+ return true;
+ else
+ return false;
+}
+
+static void ov5640_set_virtual_channel(int channel)
+{
+ u8 channel_id;
+
+ ov5640_read_reg(0x4814, &channel_id);
+ channel_id &= ~(3 << 6);
+ ov5640_write_reg(0x4814, channel_id | (channel << 6));
+}
+
+/* download ov5640 settings to sensor through i2c */
+static int ov5640_download_firmware(struct reg_value *pModeSetting, s32 ArySize)
+{
+ register u32 Delay_ms = 0;
+ register u16 RegAddr = 0;
+ register u8 Mask = 0;
+ register u8 Val = 0;
+ u8 RegVal = 0;
+ int i, retval = 0;
+
+ for (i = 0; i < ArySize; ++i, ++pModeSetting) {
+ Delay_ms = pModeSetting->u32Delay_ms;
+ RegAddr = pModeSetting->u16RegAddr;
+ Val = pModeSetting->u8Val;
+ Mask = pModeSetting->u8Mask;
+
+ if (Mask) {
+ retval = ov5640_read_reg(RegAddr, &RegVal);
+ if (retval < 0)
+ goto err;
+
+ RegVal &= ~(u8)Mask;
+ Val &= Mask;
+ Val |= RegVal;
+ }
+
+ retval = ov5640_write_reg(RegAddr, Val);
+ if (retval < 0)
+ goto err;
+
+ if (Delay_ms)
+ msleep(Delay_ms);
+ }
+err:
+ return retval;
+}
+
+/* sensor changes between scaling and subsampling
+ * go through exposure calcualtion
+ */
+static int ov5640_change_mode_exposure_calc(enum ov5640_frame_rate frame_rate,
+ enum ov5640_mode mode)
+{
+ struct reg_value *pModeSetting = NULL;
+ s32 ArySize = 0;
+ u8 average;
+ int prev_shutter, prev_gain16;
+ int cap_shutter, cap_gain16;
+ int cap_sysclk, cap_HTS, cap_VTS;
+ int light_freq, cap_bandfilt, cap_maxband;
+ long cap_gain16_shutter;
+ int retval = 0;
+
+ /* check if the input mode and frame rate is valid */
+ pModeSetting =
+ ov5640_mode_info_data[frame_rate][mode].init_data_ptr;
+ ArySize =
+ ov5640_mode_info_data[frame_rate][mode].init_data_size;
+
+ ov5640_data.pix.width =
+ ov5640_mode_info_data[frame_rate][mode].width;
+ ov5640_data.pix.height =
+ ov5640_mode_info_data[frame_rate][mode].height;
+
+ if (ov5640_data.pix.width == 0 || ov5640_data.pix.height == 0 ||
+ pModeSetting == NULL || ArySize == 0)
+ return -EINVAL;
+
+ /* auto focus */
+ /* OV5640_auto_focus();//if no af function, just skip it */
+
+ /* turn off AE/AG */
+ OV5640_turn_on_AE_AG(0);
+
+ /* read preview shutter */
+ prev_shutter = OV5640_get_shutter();
+ if ((binning_on()) && (mode != ov5640_mode_720P_1280_720)
+ && (mode != ov5640_mode_1080P_1920_1080))
+ prev_shutter *= 2;
+
+ /* read preview gain */
+ prev_gain16 = OV5640_get_gain16();
+
+ /* get average */
+ ov5640_read_reg(0x56a1, &average);
+
+ /* turn off night mode for capture */
+ OV5640_set_night_mode();
+
+ /* turn off overlay */
+ /* ov5640_write_reg(0x3022, 0x06);//if no af function, just skip it */
+
+ OV5640_stream_off();
+
+ /* Write capture setting */
+ retval = ov5640_download_firmware(pModeSetting, ArySize);
+ if (retval < 0)
+ goto err;
+
+ /* read capture VTS */
+ cap_VTS = OV5640_get_VTS();
+ cap_HTS = OV5640_get_HTS();
+ cap_sysclk = OV5640_get_sysclk();
+
+ /* calculate capture banding filter */
+ light_freq = OV5640_get_light_freq();
+ if (light_freq == 60) {
+ /* 60Hz */
+ cap_bandfilt = cap_sysclk * 100 / cap_HTS * 100 / 120;
+ } else {
+ /* 50Hz */
+ cap_bandfilt = cap_sysclk * 100 / cap_HTS;
+ }
+ cap_maxband = (int)((cap_VTS - 4)/cap_bandfilt);
+
+ /* calculate capture shutter/gain16 */
+ if (average > AE_low && average < AE_high) {
+ /* in stable range */
+ cap_gain16_shutter =
+ prev_gain16 * prev_shutter * cap_sysclk/prev_sysclk
+ * prev_HTS/cap_HTS * AE_Target / average;
+ } else {
+ cap_gain16_shutter =
+ prev_gain16 * prev_shutter * cap_sysclk/prev_sysclk
+ * prev_HTS/cap_HTS;
+ }
+
+ /* gain to shutter */
+ if (cap_gain16_shutter < (cap_bandfilt * 16)) {
+ /* shutter < 1/100 */
+ cap_shutter = cap_gain16_shutter/16;
+ if (cap_shutter < 1)
+ cap_shutter = 1;
+
+ cap_gain16 = cap_gain16_shutter/cap_shutter;
+ if (cap_gain16 < 16)
+ cap_gain16 = 16;
+ } else {
+ if (cap_gain16_shutter >
+ (cap_bandfilt * cap_maxband * 16)) {
+ /* exposure reach max */
+ cap_shutter = cap_bandfilt * cap_maxband;
+ cap_gain16 = cap_gain16_shutter / cap_shutter;
+ } else {
+ /* 1/100 < (cap_shutter = n/100) =< max */
+ cap_shutter =
+ ((int) (cap_gain16_shutter/16 / cap_bandfilt))
+ *cap_bandfilt;
+ cap_gain16 = cap_gain16_shutter / cap_shutter;
+ }
+ }
+
+ /* write capture gain */
+ OV5640_set_gain16(cap_gain16);
+
+ /* write capture shutter */
+ if (cap_shutter > (cap_VTS - 4)) {
+ cap_VTS = cap_shutter + 4;
+ OV5640_set_VTS(cap_VTS);
+ }
+ OV5640_set_shutter(cap_shutter);
+
+ OV5640_stream_on();
+
+err:
+ return retval;
+}
+
+/* if sensor changes inside scaling or subsampling
+ * change mode directly
+ * */
+static int ov5640_change_mode_direct(enum ov5640_frame_rate frame_rate,
+ enum ov5640_mode mode)
+{
+ struct reg_value *pModeSetting = NULL;
+ s32 ArySize = 0;
+ int retval = 0;
+
+ /* check if the input mode and frame rate is valid */
+ pModeSetting =
+ ov5640_mode_info_data[frame_rate][mode].init_data_ptr;
+ ArySize =
+ ov5640_mode_info_data[frame_rate][mode].init_data_size;
+
+ ov5640_data.pix.width =
+ ov5640_mode_info_data[frame_rate][mode].width;
+ ov5640_data.pix.height =
+ ov5640_mode_info_data[frame_rate][mode].height;
+
+ if (ov5640_data.pix.width == 0 || ov5640_data.pix.height == 0 ||
+ pModeSetting == NULL || ArySize == 0)
+ return -EINVAL;
+
+ /* turn off AE/AG */
+ OV5640_turn_on_AE_AG(0);
+
+ OV5640_stream_off();
+
+ /* Write capture setting */
+ retval = ov5640_download_firmware(pModeSetting, ArySize);
+ if (retval < 0)
+ goto err;
+
+ OV5640_stream_on();
+
+ OV5640_turn_on_AE_AG(1);
+
+err:
+ return retval;
+}
+
+static int ov5640_init_mode(enum ov5640_frame_rate frame_rate,
+ enum ov5640_mode mode, enum ov5640_mode orig_mode)
+{
+ struct reg_value *pModeSetting = NULL;
+ s32 ArySize = 0;
+ int retval = 0;
+ void *mipi_csi2_info;
+ u32 mipi_reg, msec_wait4stable = 0;
+ enum ov5640_downsize_mode dn_mode, orig_dn_mode;
+
+ if ((mode > ov5640_mode_MAX || mode < ov5640_mode_MIN)
+ && (mode != ov5640_mode_INIT)) {
+ pr_err("Wrong ov5640 mode detected!\n");
+ return -1;
+ }
+
+ mipi_csi2_info = mipi_csi2_get_info();
+
+ /* initial mipi dphy */
+ if (!mipi_csi2_info) {
+ printk(KERN_ERR "%s() in %s: Fail to get mipi_csi2_info!\n",
+ __func__, __FILE__);
+ return -1;
+ }
+
+ if (!mipi_csi2_get_status(mipi_csi2_info))
+ mipi_csi2_enable(mipi_csi2_info);
+
+ if (!mipi_csi2_get_status(mipi_csi2_info)) {
+ pr_err("Can not enable mipi csi2 driver!\n");
+ return -1;
+ }
+
+ mipi_csi2_set_lanes(mipi_csi2_info);
+
+ /*Only reset MIPI CSI2 HW at sensor initialize*/
+ if (mode == ov5640_mode_INIT)
+ mipi_csi2_reset(mipi_csi2_info);
+
+ if (ov5640_data.pix.pixelformat == V4L2_PIX_FMT_UYVY)
+ mipi_csi2_set_datatype(mipi_csi2_info, MIPI_DT_YUV422);
+ else if (ov5640_data.pix.pixelformat == V4L2_PIX_FMT_RGB565)
+ mipi_csi2_set_datatype(mipi_csi2_info, MIPI_DT_RGB565);
+ else
+ pr_err("currently this sensor format can not be supported!\n");
+
+ dn_mode = ov5640_mode_info_data[frame_rate][mode].dn_mode;
+ orig_dn_mode = ov5640_mode_info_data[frame_rate][orig_mode].dn_mode;
+ if (mode == ov5640_mode_INIT) {
+ pModeSetting = ov5640_init_setting_30fps_VGA;
+ ArySize = ARRAY_SIZE(ov5640_init_setting_30fps_VGA);
+
+ ov5640_data.pix.width = 640;
+ ov5640_data.pix.height = 480;
+ retval = ov5640_download_firmware(pModeSetting, ArySize);
+ if (retval < 0)
+ goto err;
+
+ pModeSetting = ov5640_setting_30fps_VGA_640_480;
+ ArySize = ARRAY_SIZE(ov5640_setting_30fps_VGA_640_480);
+ retval = ov5640_download_firmware(pModeSetting, ArySize);
+ } else if ((dn_mode == SUBSAMPLING && orig_dn_mode == SCALING) ||
+ (dn_mode == SCALING && orig_dn_mode == SUBSAMPLING)) {
+ /* change between subsampling and scaling
+ * go through exposure calucation */
+ retval = ov5640_change_mode_exposure_calc(frame_rate, mode);
+ } else {
+ /* change inside subsampling or scaling
+ * download firmware directly */
+ retval = ov5640_change_mode_direct(frame_rate, mode);
+ }
+
+ if (retval < 0)
+ goto err;
+
+ OV5640_set_AE_target(AE_Target);
+ OV5640_get_light_freq();
+ OV5640_set_bandingfilter();
+ ov5640_set_virtual_channel(ov5640_data.csi);
+
+ /* add delay to wait for sensor stable */
+ if (mode == ov5640_mode_QSXGA_2592_1944) {
+ /* dump the first two frames: 1/7.5*2
+ * the frame rate of QSXGA is 7.5fps */
+ msec_wait4stable = 267;
+ } else if (frame_rate == ov5640_15_fps) {
+ /* dump the first nine frames: 1/15*9 */
+ msec_wait4stable = 600;
+ } else if (frame_rate == ov5640_30_fps) {
+ /* dump the first nine frames: 1/30*9 */
+ msec_wait4stable = 300;
+ }
+ msleep(msec_wait4stable);
+
+ if (mipi_csi2_info) {
+ unsigned int i;
+
+ i = 0;
+
+ /* wait for mipi sensor ready */
+ mipi_reg = mipi_csi2_dphy_status(mipi_csi2_info);
+ while ((mipi_reg == 0x200) && (i < 10)) {
+ mipi_reg = mipi_csi2_dphy_status(mipi_csi2_info);
+ i++;
+ msleep(10);
+ }
+
+ if (i >= 10) {
+ pr_err("mipi csi2 can not receive sensor clk!\n");
+ return -1;
+ }
+
+ i = 0;
+
+ /* wait for mipi stable */
+ mipi_reg = mipi_csi2_get_error1(mipi_csi2_info);
+ while ((mipi_reg != 0x0) && (i < 10)) {
+ mipi_reg = mipi_csi2_get_error1(mipi_csi2_info);
+ i++;
+ msleep(10);
+ }
+
+ if (i >= 10) {
+ pr_err("mipi csi2 can not reveive data correctly!\n");
+ return -1;
+ }
+ }
+err:
+ return retval;
+}
+
+/* --------------- IOCTL functions from v4l2_int_ioctl_desc --------------- */
+
+static int ioctl_g_ifparm(struct v4l2_int_device *s, struct v4l2_ifparm *p)
+{
+ if (s == NULL) {
+ pr_err(" ERROR!! no slave device set!\n");
+ return -1;
+ }
+
+ memset(p, 0, sizeof(*p));
+ p->u.bt656.clock_curr = ov5640_data.mclk;
+ pr_debug(" clock_curr=mclk=%d\n", ov5640_data.mclk);
+ p->if_type = V4L2_IF_TYPE_BT656;
+ p->u.bt656.mode = V4L2_IF_TYPE_BT656_MODE_NOBT_8BIT;
+ p->u.bt656.clock_min = OV5640_XCLK_MIN;
+ p->u.bt656.clock_max = OV5640_XCLK_MAX;
+ p->u.bt656.bt_sync_correct = 1; /* Indicate external vsync */
+
+ return 0;
+}
+
+/*!
+ * ioctl_s_power - V4L2 sensor interface handler for VIDIOC_S_POWER ioctl
+ * @s: pointer to standard V4L2 device structure
+ * @on: indicates power mode (on or off)
+ *
+ * Turns the power on or off, depending on the value of on and returns the
+ * appropriate error code.
+ */
+static int ioctl_s_power(struct v4l2_int_device *s, int on)
+{
+ struct sensor_data *sensor = s->priv;
+
+ if (on && !sensor->on) {
+ if (io_regulator)
+ if (regulator_enable(io_regulator) != 0)
+ return -EIO;
+ if (core_regulator)
+ if (regulator_enable(core_regulator) != 0)
+ return -EIO;
+ if (gpo_regulator)
+ if (regulator_enable(gpo_regulator) != 0)
+ return -EIO;
+ if (analog_regulator)
+ if (regulator_enable(analog_regulator) != 0)
+ return -EIO;
+ /* Make sure power on */
+ ov5640_standby(0);
+ } else if (!on && sensor->on) {
+ if (analog_regulator)
+ regulator_disable(analog_regulator);
+ if (core_regulator)
+ regulator_disable(core_regulator);
+ if (io_regulator)
+ regulator_disable(io_regulator);
+ if (gpo_regulator)
+ regulator_disable(gpo_regulator);
+
+ ov5640_standby(1);
+ }
+
+ sensor->on = on;
+
+ return 0;
+}
+
+/*!
+ * ioctl_g_parm - V4L2 sensor interface handler for VIDIOC_G_PARM ioctl
+ * @s: pointer to standard V4L2 device structure
+ * @a: pointer to standard V4L2 VIDIOC_G_PARM ioctl structure
+ *
+ * Returns the sensor's video CAPTURE parameters.
+ */
+static int ioctl_g_parm(struct v4l2_int_device *s, struct v4l2_streamparm *a)
+{
+ struct sensor_data *sensor = s->priv;
+ struct v4l2_captureparm *cparm = &a->parm.capture;
+ int ret = 0;
+
+ switch (a->type) {
+ /* This is the only case currently handled. */
+ case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+ memset(a, 0, sizeof(*a));
+ a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ cparm->capability = sensor->streamcap.capability;
+ cparm->timeperframe = sensor->streamcap.timeperframe;
+ cparm->capturemode = sensor->streamcap.capturemode;
+ ret = 0;
+ break;
+
+ /* These are all the possible cases. */
+ case V4L2_BUF_TYPE_VIDEO_OUTPUT:
+ case V4L2_BUF_TYPE_VIDEO_OVERLAY:
+ case V4L2_BUF_TYPE_VBI_CAPTURE:
+ case V4L2_BUF_TYPE_VBI_OUTPUT:
+ case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
+ case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
+ ret = -EINVAL;
+ break;
+
+ default:
+ pr_debug(" type is unknown - %d\n", a->type);
+ ret = -EINVAL;
+ break;
+ }
+
+ return ret;
+}
+
+/*!
+ * ioctl_s_parm - V4L2 sensor interface handler for VIDIOC_S_PARM ioctl
+ * @s: pointer to standard V4L2 device structure
+ * @a: pointer to standard V4L2 VIDIOC_S_PARM ioctl structure
+ *
+ * Configures the sensor to use the input parameters, if possible. If
+ * not possible, reverts to the old parameters and returns the
+ * appropriate error code.
+ */
+static int ioctl_s_parm(struct v4l2_int_device *s, struct v4l2_streamparm *a)
+{
+ struct sensor_data *sensor = s->priv;
+ struct v4l2_fract *timeperframe = &a->parm.capture.timeperframe;
+ u32 tgt_fps; /* target frames per secound */
+ enum ov5640_frame_rate frame_rate;
+ enum ov5640_mode orig_mode;
+ int ret = 0;
+
+ /* Make sure power on */
+ ov5640_standby(0);
+
+ switch (a->type) {
+ /* This is the only case currently handled. */
+ case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+ /* Check that the new frame rate is allowed. */
+ if ((timeperframe->numerator == 0) ||
+ (timeperframe->denominator == 0)) {
+ timeperframe->denominator = DEFAULT_FPS;
+ timeperframe->numerator = 1;
+ }
+
+ tgt_fps = timeperframe->denominator /
+ timeperframe->numerator;
+
+ if (tgt_fps > MAX_FPS) {
+ timeperframe->denominator = MAX_FPS;
+ timeperframe->numerator = 1;
+ } else if (tgt_fps < MIN_FPS) {
+ timeperframe->denominator = MIN_FPS;
+ timeperframe->numerator = 1;
+ }
+
+ /* Actual frame rate we use */
+ tgt_fps = timeperframe->denominator /
+ timeperframe->numerator;
+
+ if (tgt_fps == 15)
+ frame_rate = ov5640_15_fps;
+ else if (tgt_fps == 30)
+ frame_rate = ov5640_30_fps;
+ else {
+ pr_err(" The camera frame rate is not supported!\n");
+ return -EINVAL;
+ }
+
+ orig_mode = sensor->streamcap.capturemode;
+ ret = ov5640_init_mode(frame_rate,
+ (u32)a->parm.capture.capturemode, orig_mode);
+ if (ret < 0)
+ return ret;
+
+ sensor->streamcap.timeperframe = *timeperframe;
+ sensor->streamcap.capturemode =
+ (u32)a->parm.capture.capturemode;
+
+ break;
+
+ /* These are all the possible cases. */
+ case V4L2_BUF_TYPE_VIDEO_OUTPUT:
+ case V4L2_BUF_TYPE_VIDEO_OVERLAY:
+ case V4L2_BUF_TYPE_VBI_CAPTURE:
+ case V4L2_BUF_TYPE_VBI_OUTPUT:
+ case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
+ case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
+ pr_debug(" type is not " \
+ "V4L2_BUF_TYPE_VIDEO_CAPTURE but %d\n",
+ a->type);
+ ret = -EINVAL;
+ break;
+
+ default:
+ pr_debug(" type is unknown - %d\n", a->type);
+ ret = -EINVAL;
+ break;
+ }
+
+ return ret;
+}
+
+/*!
+ * ioctl_g_fmt_cap - V4L2 sensor interface handler for ioctl_g_fmt_cap
+ * @s: pointer to standard V4L2 device structure
+ * @f: pointer to standard V4L2 v4l2_format structure
+ *
+ * Returns the sensor's current pixel format in the v4l2_format
+ * parameter.
+ */
+static int ioctl_g_fmt_cap(struct v4l2_int_device *s, struct v4l2_format *f)
+{
+ struct sensor_data *sensor = s->priv;
+
+ f->fmt.pix = sensor->pix;
+
+ return 0;
+}
+
+/*!
+ * ioctl_g_ctrl - V4L2 sensor interface handler for VIDIOC_G_CTRL ioctl
+ * @s: pointer to standard V4L2 device structure
+ * @vc: standard V4L2 VIDIOC_G_CTRL ioctl structure
+ *
+ * If the requested control is supported, returns the control's current
+ * value from the video_control[] array. Otherwise, returns -EINVAL
+ * if the control is not supported.
+ */
+static int ioctl_g_ctrl(struct v4l2_int_device *s, struct v4l2_control *vc)
+{
+ int ret = 0;
+
+ switch (vc->id) {
+ case V4L2_CID_BRIGHTNESS:
+ vc->value = ov5640_data.brightness;
+ break;
+ case V4L2_CID_HUE:
+ vc->value = ov5640_data.hue;
+ break;
+ case V4L2_CID_CONTRAST:
+ vc->value = ov5640_data.contrast;
+ break;
+ case V4L2_CID_SATURATION:
+ vc->value = ov5640_data.saturation;
+ break;
+ case V4L2_CID_RED_BALANCE:
+ vc->value = ov5640_data.red;
+ break;
+ case V4L2_CID_BLUE_BALANCE:
+ vc->value = ov5640_data.blue;
+ break;
+ case V4L2_CID_EXPOSURE:
+ vc->value = ov5640_data.ae_mode;
+ break;
+ default:
+ ret = -EINVAL;
+ }
+
+ return ret;
+}
+
+/*!
+ * ioctl_s_ctrl - V4L2 sensor interface handler for VIDIOC_S_CTRL ioctl
+ * @s: pointer to standard V4L2 device structure
+ * @vc: standard V4L2 VIDIOC_S_CTRL ioctl structure
+ *
+ * If the requested control is supported, sets the control's current
+ * value in HW (and updates the video_control[] array). Otherwise,
+ * returns -EINVAL if the control is not supported.
+ */
+static int ioctl_s_ctrl(struct v4l2_int_device *s, struct v4l2_control *vc)
+{
+ int retval = 0;
+
+ pr_debug("In ov5640:ioctl_s_ctrl %d\n",
+ vc->id);
+
+ switch (vc->id) {
+ case V4L2_CID_BRIGHTNESS:
+ break;
+ case V4L2_CID_CONTRAST:
+ break;
+ case V4L2_CID_SATURATION:
+ break;
+ case V4L2_CID_HUE:
+ break;
+ case V4L2_CID_AUTO_WHITE_BALANCE:
+ break;
+ case V4L2_CID_DO_WHITE_BALANCE:
+ break;
+ case V4L2_CID_RED_BALANCE:
+ break;
+ case V4L2_CID_BLUE_BALANCE:
+ break;
+ case V4L2_CID_GAMMA:
+ break;
+ case V4L2_CID_EXPOSURE:
+ break;
+ case V4L2_CID_AUTOGAIN:
+ break;
+ case V4L2_CID_GAIN:
+ break;
+ case V4L2_CID_HFLIP:
+ break;
+ case V4L2_CID_VFLIP:
+ break;
+ default:
+ retval = -EPERM;
+ break;
+ }
+
+ return retval;
+}
+
+/*!
+ * ioctl_enum_framesizes - V4L2 sensor interface handler for
+ * VIDIOC_ENUM_FRAMESIZES ioctl
+ * @s: pointer to standard V4L2 device structure
+ * @fsize: standard V4L2 VIDIOC_ENUM_FRAMESIZES ioctl structure
+ *
+ * Return 0 if successful, otherwise -EINVAL.
+ */
+static int ioctl_enum_framesizes(struct v4l2_int_device *s,
+ struct v4l2_frmsizeenum *fsize)
+{
+ if (fsize->index > ov5640_mode_MAX)
+ return -EINVAL;
+
+ fsize->pixel_format = ov5640_data.pix.pixelformat;
+ fsize->discrete.width =
+ max(ov5640_mode_info_data[0][fsize->index].width,
+ ov5640_mode_info_data[1][fsize->index].width);
+ fsize->discrete.height =
+ max(ov5640_mode_info_data[0][fsize->index].height,
+ ov5640_mode_info_data[1][fsize->index].height);
+ return 0;
+}
+
+/*!
+ * ioctl_enum_frameintervals - V4L2 sensor interface handler for
+ * VIDIOC_ENUM_FRAMEINTERVALS ioctl
+ * @s: pointer to standard V4L2 device structure
+ * @fival: standard V4L2 VIDIOC_ENUM_FRAMEINTERVALS ioctl structure
+ *
+ * Return 0 if successful, otherwise -EINVAL.
+ */
+static int ioctl_enum_frameintervals(struct v4l2_int_device *s,
+ struct v4l2_frmivalenum *fival)
+{
+ int i, j, count = 0;
+
+ fival->type = V4L2_FRMIVAL_TYPE_DISCRETE;
+ fival->discrete.numerator = 1;
+
+ for (i = 0; i < ARRAY_SIZE(ov5640_mode_info_data); i++)
+ for (j = 0; j < (ov5640_mode_MAX + 1); j++)
+ if (fival->pixel_format == ov5640_data.pix.pixelformat
+ && fival->width == ov5640_mode_info_data[i][j].width
+ && fival->height == ov5640_mode_info_data[i][j].height
+ && ov5640_mode_info_data[i][j].init_data_ptr != NULL
+ && fival->index == count++) {
+ fival->discrete.denominator =
+ ov5640_framerates[i];
+ return 0;
+ }
+
+ return -EINVAL;
+}
+
+/*!
+ * ioctl_g_chip_ident - V4L2 sensor interface handler for
+ * VIDIOC_DBG_G_CHIP_IDENT ioctl
+ * @s: pointer to standard V4L2 device structure
+ * @id: pointer to int
+ *
+ * Return 0.
+ */
+static int ioctl_g_chip_ident(struct v4l2_int_device *s, int *id)
+{
+ ((struct v4l2_dbg_chip_ident *)id)->match.type =
+ V4L2_CHIP_MATCH_I2C_DRIVER;
+ strcpy(((struct v4l2_dbg_chip_ident *)id)->match.name,
+ "ov5640_mipi_camera");
+
+ return 0;
+}
+
+/*!
+ * ioctl_init - V4L2 sensor interface handler for VIDIOC_INT_INIT
+ * @s: pointer to standard V4L2 device structure
+ */
+static int ioctl_init(struct v4l2_int_device *s)
+{
+
+ return 0;
+}
+
+/*!
+ * ioctl_enum_fmt_cap - V4L2 sensor interface handler for VIDIOC_ENUM_FMT
+ * @s: pointer to standard V4L2 device structure
+ * @fmt: pointer to standard V4L2 fmt description structure
+ *
+ * Return 0.
+ */
+static int ioctl_enum_fmt_cap(struct v4l2_int_device *s,
+ struct v4l2_fmtdesc *fmt)
+{
+ if (fmt->index > ov5640_mode_MAX)
+ return -EINVAL;
+
+ fmt->pixelformat = ov5640_data.pix.pixelformat;
+
+ return 0;
+}
+
+/*!
+ * ioctl_dev_init - V4L2 sensor interface handler for vidioc_int_dev_init_num
+ * @s: pointer to standard V4L2 device structure
+ *
+ * Initialise the device when slave attaches to the master.
+ */
+static int ioctl_dev_init(struct v4l2_int_device *s)
+{
+ struct sensor_data *sensor = s->priv;
+ u32 tgt_xclk; /* target xclk */
+ u32 tgt_fps; /* target frames per secound */
+ int ret;
+ enum ov5640_frame_rate frame_rate;
+ void *mipi_csi2_info;
+
+ ov5640_data.on = true;
+
+ /* mclk */
+ tgt_xclk = ov5640_data.mclk;
+ tgt_xclk = min(tgt_xclk, (u32)OV5640_XCLK_MAX);
+ tgt_xclk = max(tgt_xclk, (u32)OV5640_XCLK_MIN);
+ ov5640_data.mclk = tgt_xclk;
+
+ pr_debug(" Setting mclk to %d MHz\n", tgt_xclk / 1000000);
+
+ /* Default camera frame rate is set in probe */
+ tgt_fps = sensor->streamcap.timeperframe.denominator /
+ sensor->streamcap.timeperframe.numerator;
+
+ if (tgt_fps == 15)
+ frame_rate = ov5640_15_fps;
+ else if (tgt_fps == 30)
+ frame_rate = ov5640_30_fps;
+ else
+ return -EINVAL; /* Only support 15fps or 30fps now. */
+
+ mipi_csi2_info = mipi_csi2_get_info();
+
+ /* enable mipi csi2 */
+ if (mipi_csi2_info)
+ mipi_csi2_enable(mipi_csi2_info);
+ else {
+ printk(KERN_ERR "%s() in %s: Fail to get mipi_csi2_info!\n",
+ __func__, __FILE__);
+ return -EPERM;
+ }
+
+ ret = ov5640_init_mode(frame_rate, ov5640_mode_INIT, ov5640_mode_INIT);
+
+ return ret;
+}
+
+/*!
+ * ioctl_dev_exit - V4L2 sensor interface handler for vidioc_int_dev_exit_num
+ * @s: pointer to standard V4L2 device structure
+ *
+ * Delinitialise the device when slave detaches to the master.
+ */
+static int ioctl_dev_exit(struct v4l2_int_device *s)
+{
+ void *mipi_csi2_info;
+
+ mipi_csi2_info = mipi_csi2_get_info();
+
+ /* disable mipi csi2 */
+ if (mipi_csi2_info)
+ if (mipi_csi2_get_status(mipi_csi2_info))
+ mipi_csi2_disable(mipi_csi2_info);
+
+ return 0;
+}
+
+/*!
+ * This structure defines all the ioctls for this module and links them to the
+ * enumeration.
+ */
+static struct v4l2_int_ioctl_desc ov5640_ioctl_desc[] = {
+ {vidioc_int_dev_init_num, (v4l2_int_ioctl_func *) ioctl_dev_init},
+ {vidioc_int_dev_exit_num, ioctl_dev_exit},
+ {vidioc_int_s_power_num, (v4l2_int_ioctl_func *) ioctl_s_power},
+ {vidioc_int_g_ifparm_num, (v4l2_int_ioctl_func *) ioctl_g_ifparm},
+/* {vidioc_int_g_needs_reset_num,
+ (v4l2_int_ioctl_func *)ioctl_g_needs_reset}, */
+/* {vidioc_int_reset_num, (v4l2_int_ioctl_func *)ioctl_reset}, */
+ {vidioc_int_init_num, (v4l2_int_ioctl_func *) ioctl_init},
+ {vidioc_int_enum_fmt_cap_num,
+ (v4l2_int_ioctl_func *) ioctl_enum_fmt_cap},
+/* {vidioc_int_try_fmt_cap_num,
+ (v4l2_int_ioctl_func *)ioctl_try_fmt_cap}, */
+ {vidioc_int_g_fmt_cap_num, (v4l2_int_ioctl_func *) ioctl_g_fmt_cap},
+/* {vidioc_int_s_fmt_cap_num, (v4l2_int_ioctl_func *) ioctl_s_fmt_cap}, */
+ {vidioc_int_g_parm_num, (v4l2_int_ioctl_func *) ioctl_g_parm},
+ {vidioc_int_s_parm_num, (v4l2_int_ioctl_func *) ioctl_s_parm},
+/* {vidioc_int_queryctrl_num, (v4l2_int_ioctl_func *)ioctl_queryctrl}, */
+ {vidioc_int_g_ctrl_num, (v4l2_int_ioctl_func *) ioctl_g_ctrl},
+ {vidioc_int_s_ctrl_num, (v4l2_int_ioctl_func *) ioctl_s_ctrl},
+ {vidioc_int_enum_framesizes_num,
+ (v4l2_int_ioctl_func *) ioctl_enum_framesizes},
+ {vidioc_int_enum_frameintervals_num,
+ (v4l2_int_ioctl_func *) ioctl_enum_frameintervals},
+ {vidioc_int_g_chip_ident_num,
+ (v4l2_int_ioctl_func *) ioctl_g_chip_ident},
+};
+
+static struct v4l2_int_slave ov5640_slave = {
+ .ioctls = ov5640_ioctl_desc,
+ .num_ioctls = ARRAY_SIZE(ov5640_ioctl_desc),
+};
+
+static struct v4l2_int_device ov5640_int_device = {
+ .module = THIS_MODULE,
+ .name = "ov564x",
+ .type = v4l2_int_type_slave,
+ .u = {
+ .slave = &ov5640_slave,
+ },
+};
+
+/*!
+ * ov5640 I2C probe function
+ *
+ * @param adapter struct i2c_adapter *
+ * @return Error code indicating success or failure
+ */
+static int ov5640_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct device *dev = &client->dev;
+ int retval;
+ u8 chip_id_high, chip_id_low;
+
+ /* request power down pin */
+ pwn_gpio = of_get_named_gpio(dev->of_node, "pwn-gpios", 0);
+ if (!gpio_is_valid(pwn_gpio)) {
+ dev_warn(dev, "no sensor pwdn pin available");
+ return -EINVAL;
+ }
+ retval = devm_gpio_request_one(dev, pwn_gpio, GPIOF_OUT_INIT_HIGH,
+ "ov5640_mipi_pwdn");
+ if (retval < 0)
+ return retval;
+
+ /* request reset pin */
+ rst_gpio = of_get_named_gpio(dev->of_node, "rst-gpios", 0);
+ if (!gpio_is_valid(rst_gpio)) {
+ dev_warn(dev, "no sensor reset pin available");
+ return -EINVAL;
+ }
+ retval = devm_gpio_request_one(dev, rst_gpio, GPIOF_OUT_INIT_HIGH,
+ "ov5640_mipi_reset");
+ if (retval < 0)
+ return retval;
+
+ /* Set initial values for the sensor struct. */
+ memset(&ov5640_data, 0, sizeof(ov5640_data));
+ ov5640_data.sensor_clk = devm_clk_get(dev, "csi_mclk");
+ if (IS_ERR(ov5640_data.sensor_clk)) {
+ /* assuming clock enabled by default */
+ ov5640_data.sensor_clk = NULL;
+ dev_err(dev, "clock-frequency missing or invalid\n");
+ return PTR_ERR(ov5640_data.sensor_clk);
+ }
+
+ retval = of_property_read_u32(dev->of_node, "mclk",
+ &(ov5640_data.mclk));
+ if (retval) {
+ dev_err(dev, "mclk missing or invalid\n");
+ return retval;
+ }
+
+ retval = of_property_read_u32(dev->of_node, "mclk_source",
+ (u32 *) &(ov5640_data.mclk_source));
+ if (retval) {
+ dev_err(dev, "mclk_source missing or invalid\n");
+ return retval;
+ }
+
+ retval = of_property_read_u32(dev->of_node, "csi_id",
+ &(ov5640_data.csi));
+ if (retval) {
+ dev_err(dev, "csi id missing or invalid\n");
+ return retval;
+ }
+
+ clk_prepare_enable(ov5640_data.sensor_clk);
+
+ ov5640_data.io_init = ov5640_reset;
+ ov5640_data.i2c_client = client;
+ ov5640_data.pix.pixelformat = V4L2_PIX_FMT_UYVY;
+ ov5640_data.pix.width = 640;
+ ov5640_data.pix.height = 480;
+ ov5640_data.streamcap.capability = V4L2_MODE_HIGHQUALITY |
+ V4L2_CAP_TIMEPERFRAME;
+ ov5640_data.streamcap.capturemode = 0;
+ ov5640_data.streamcap.timeperframe.denominator = DEFAULT_FPS;
+ ov5640_data.streamcap.timeperframe.numerator = 1;
+
+ ov5640_power_on(dev);
+
+ ov5640_reset();
+
+ ov5640_standby(0);
+
+ retval = ov5640_read_reg(OV5640_CHIP_ID_HIGH_BYTE, &chip_id_high);
+ if (retval < 0 || chip_id_high != 0x56) {
+ pr_warning("camera ov5640_mipi is not found\n");
+ clk_disable_unprepare(ov5640_data.sensor_clk);
+ return -ENODEV;
+ }
+ retval = ov5640_read_reg(OV5640_CHIP_ID_LOW_BYTE, &chip_id_low);
+ if (retval < 0 || chip_id_low != 0x40) {
+ pr_warning("camera ov5640_mipi is not found\n");
+ clk_disable_unprepare(ov5640_data.sensor_clk);
+ return -ENODEV;
+ }
+
+ ov5640_standby(1);
+
+ ov5640_int_device.priv = &ov5640_data;
+ retval = v4l2_int_device_register(&ov5640_int_device);
+
+ clk_disable_unprepare(ov5640_data.sensor_clk);
+
+ pr_info("camera ov5640_mipi is found\n");
+ return retval;
+}
+
+/*!
+ * ov5640 I2C detach function
+ *
+ * @param client struct i2c_client *
+ * @return Error code indicating success or failure
+ */
+static int ov5640_remove(struct i2c_client *client)
+{
+ v4l2_int_device_unregister(&ov5640_int_device);
+
+ if (gpo_regulator)
+ regulator_disable(gpo_regulator);
+
+ if (analog_regulator)
+ regulator_disable(analog_regulator);
+
+ if (core_regulator)
+ regulator_disable(core_regulator);
+
+ if (io_regulator)
+ regulator_disable(io_regulator);
+
+ return 0;
+}
+
+/*!
+ * ov5640 init function
+ * Called by insmod ov5640_camera.ko.
+ *
+ * @return Error code indicating success or failure
+ */
+static __init int ov5640_init(void)
+{
+ u8 err;
+
+ err = i2c_add_driver(&ov5640_i2c_driver);
+ if (err != 0)
+ pr_err("%s:driver registration failed, error=%d\n",
+ __func__, err);
+
+ return err;
+}
+
+/*!
+ * OV5640 cleanup function
+ * Called on rmmod ov5640_camera.ko
+ *
+ * @return Error code indicating success or failure
+ */
+static void __exit ov5640_clean(void)
+{
+ i2c_del_driver(&ov5640_i2c_driver);
+}
+
+module_init(ov5640_init);
+module_exit(ov5640_clean);
+
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("OV5640 MIPI Camera Driver");
+MODULE_LICENSE("GPL");
+MODULE_VERSION("1.0");
+MODULE_ALIAS("CSI");
diff --git a/drivers/media/platform/mxc/capture/ov5640_mipi_v2.c b/drivers/media/platform/mxc/capture/ov5640_mipi_v2.c
new file mode 100644
index 000000000000..d68186312635
--- /dev/null
+++ b/drivers/media/platform/mxc/capture/ov5640_mipi_v2.c
@@ -0,0 +1,1818 @@
+/*
+ * Copyright (C) 2011-2016 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * Copyright 2018 NXP
+ *
+ */
+
+/*
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/ctype.h>
+#include <linux/types.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/of_device.h>
+#include <linux/i2c.h>
+#include <linux/of_gpio.h>
+#include <linux/pinctrl/consumer.h>
+#include <linux/regulator/consumer.h>
+#include <linux/v4l2-mediabus.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-ctrls.h>
+
+#define OV5640_VOLTAGE_ANALOG 2800000
+#define OV5640_VOLTAGE_DIGITAL_CORE 1500000
+#define OV5640_VOLTAGE_DIGITAL_IO 1800000
+
+#define MIN_FPS 15
+#define MAX_FPS 30
+#define DEFAULT_FPS 30
+
+#define OV5640_XCLK_MIN 6000000
+#define OV5640_XCLK_MAX 24000000
+#define OV5640_XCLK_20MHZ 20000000
+
+#define OV5640_CHIP_ID_HIGH_BYTE 0x300A
+#define OV5640_CHIP_ID_LOW_BYTE 0x300B
+
+#define DEFAULT_SCCB_ID 0x78
+
+enum ov5640_mode {
+ ov5640_mode_MIN = 0,
+ ov5640_mode_VGA_640_480 = 0,
+ ov5640_mode_QVGA_320_240 = 1,
+ ov5640_mode_NTSC_720_480 = 2,
+ ov5640_mode_720P_1280_720 = 3,
+ ov5640_mode_1080P_1920_1080 = 4,
+ ov5640_mode_QSXGA_2592_1944 = 5,
+ ov5640_mode_MAX = 6,
+ ov5640_mode_INIT = 0xff, /*only for sensor init*/
+};
+
+enum ov5640_frame_rate {
+ ov5640_15_fps,
+ ov5640_30_fps
+};
+
+static int ov5640_framerates[] = {
+ [ov5640_15_fps] = 15,
+ [ov5640_30_fps] = 30,
+};
+
+struct ov5640_datafmt {
+ u32 code;
+ enum v4l2_colorspace colorspace;
+};
+
+/* image size under 1280 * 960 are SUBSAMPLING
+ * image size upper 1280 * 960 are SCALING
+ */
+enum ov5640_downsize_mode {
+ SUBSAMPLING,
+ SCALING,
+};
+
+struct reg_value {
+ u16 u16RegAddr;
+ u8 u8Val;
+ u8 u8Mask;
+ u32 u32Delay_ms;
+};
+
+struct ov5640_mode_info {
+ enum ov5640_mode mode;
+ enum ov5640_downsize_mode dn_mode;
+ u32 width;
+ u32 height;
+ struct reg_value *init_data_ptr;
+ u32 init_data_size;
+};
+
+struct ov5640 {
+ struct v4l2_subdev subdev;
+ struct i2c_client *i2c_client;
+ struct v4l2_pix_format pix;
+ const struct ov5640_datafmt *fmt;
+ struct v4l2_captureparm streamcap;
+ bool on;
+
+ /* control settings */
+ int brightness;
+ int hue;
+ int contrast;
+ int saturation;
+ int red;
+ int green;
+ int blue;
+ int ae_mode;
+
+ u32 mclk;
+ u8 mclk_source;
+ struct clk *sensor_clk;
+ int csi;
+
+ void (*io_init)(struct ov5640 *);
+ int pwn_gpio, rst_gpio;
+};
+
+struct ov5640_res {
+ int width;
+ int height;
+};
+
+/*!
+ * Maintains the information on the current state of the sesor.
+ */
+
+
+struct ov5640_res ov5640_valid_res[] = {
+ [0] = {640, 480},
+ [1] = {320, 240},
+ [2] = {720, 480},
+ [3] = {1280, 720},
+ [4] = {1920, 1080},
+ [5] = {2592, 1944},
+};
+
+static struct reg_value ov5640_init_setting_30fps_VGA[] = {
+
+ {0x3103, 0x11, 0, 0}, {0x3008, 0x82, 0, 5}, {0x3008, 0x42, 0, 0},
+ {0x3103, 0x03, 0, 0}, {0x3017, 0x00, 0, 0}, {0x3018, 0x00, 0, 0},
+ {0x3034, 0x18, 0, 0}, {0x3035, 0x14, 0, 0}, {0x3036, 0x38, 0, 0},
+ {0x3037, 0x13, 0, 0}, {0x3108, 0x01, 0, 0}, {0x3630, 0x36, 0, 0},
+ {0x3631, 0x0e, 0, 0}, {0x3632, 0xe2, 0, 0}, {0x3633, 0x12, 0, 0},
+ {0x3621, 0xe0, 0, 0}, {0x3704, 0xa0, 0, 0}, {0x3703, 0x5a, 0, 0},
+ {0x3715, 0x78, 0, 0}, {0x3717, 0x01, 0, 0}, {0x370b, 0x60, 0, 0},
+ {0x3705, 0x1a, 0, 0}, {0x3905, 0x02, 0, 0}, {0x3906, 0x10, 0, 0},
+ {0x3901, 0x0a, 0, 0}, {0x3731, 0x12, 0, 0}, {0x3600, 0x08, 0, 0},
+ {0x3601, 0x33, 0, 0}, {0x302d, 0x60, 0, 0}, {0x3620, 0x52, 0, 0},
+ {0x371b, 0x20, 0, 0}, {0x471c, 0x50, 0, 0}, {0x3a13, 0x43, 0, 0},
+ {0x3a18, 0x00, 0, 0}, {0x3a19, 0xf8, 0, 0}, {0x3635, 0x13, 0, 0},
+ {0x3636, 0x03, 0, 0}, {0x3634, 0x40, 0, 0}, {0x3622, 0x01, 0, 0},
+ {0x3c01, 0xa4, 0, 0}, {0x3c04, 0x28, 0, 0}, {0x3c05, 0x98, 0, 0},
+ {0x3c06, 0x00, 0, 0}, {0x3c07, 0x08, 0, 0}, {0x3c08, 0x00, 0, 0},
+ {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
+ {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0},
+ {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
+ {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0}, {0x3804, 0x0a, 0, 0},
+ {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9b, 0, 0},
+ {0x3808, 0x02, 0, 0}, {0x3809, 0x80, 0, 0}, {0x380a, 0x01, 0, 0},
+ {0x380b, 0xe0, 0, 0}, {0x380c, 0x07, 0, 0}, {0x380d, 0x68, 0, 0},
+ {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0}, {0x3810, 0x00, 0, 0},
+ {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x06, 0, 0},
+ {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0},
+ {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x03, 0, 0},
+ {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0},
+ {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0},
+ {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0},
+ {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x3000, 0x00, 0, 0},
+ {0x3002, 0x1c, 0, 0}, {0x3004, 0xff, 0, 0}, {0x3006, 0xc3, 0, 0},
+ {0x300e, 0x45, 0, 0}, {0x302e, 0x08, 0, 0}, {0x4300, 0x30, 0, 0},
+ {0x501f, 0x00, 0, 0}, {0x4713, 0x03, 0, 0}, {0x4407, 0x04, 0, 0},
+ {0x440e, 0x00, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0},
+ {0x4837, 0x0a, 0, 0}, {0x4800, 0x04, 0, 0}, {0x3824, 0x02, 0, 0},
+ {0x5000, 0xa7, 0, 0}, {0x5001, 0xa3, 0, 0}, {0x5180, 0xff, 0, 0},
+ {0x5181, 0xf2, 0, 0}, {0x5182, 0x00, 0, 0}, {0x5183, 0x14, 0, 0},
+ {0x5184, 0x25, 0, 0}, {0x5185, 0x24, 0, 0}, {0x5186, 0x09, 0, 0},
+ {0x5187, 0x09, 0, 0}, {0x5188, 0x09, 0, 0}, {0x5189, 0x88, 0, 0},
+ {0x518a, 0x54, 0, 0}, {0x518b, 0xee, 0, 0}, {0x518c, 0xb2, 0, 0},
+ {0x518d, 0x50, 0, 0}, {0x518e, 0x34, 0, 0}, {0x518f, 0x6b, 0, 0},
+ {0x5190, 0x46, 0, 0}, {0x5191, 0xf8, 0, 0}, {0x5192, 0x04, 0, 0},
+ {0x5193, 0x70, 0, 0}, {0x5194, 0xf0, 0, 0}, {0x5195, 0xf0, 0, 0},
+ {0x5196, 0x03, 0, 0}, {0x5197, 0x01, 0, 0}, {0x5198, 0x04, 0, 0},
+ {0x5199, 0x6c, 0, 0}, {0x519a, 0x04, 0, 0}, {0x519b, 0x00, 0, 0},
+ {0x519c, 0x09, 0, 0}, {0x519d, 0x2b, 0, 0}, {0x519e, 0x38, 0, 0},
+ {0x5381, 0x1e, 0, 0}, {0x5382, 0x5b, 0, 0}, {0x5383, 0x08, 0, 0},
+ {0x5384, 0x0a, 0, 0}, {0x5385, 0x7e, 0, 0}, {0x5386, 0x88, 0, 0},
+ {0x5387, 0x7c, 0, 0}, {0x5388, 0x6c, 0, 0}, {0x5389, 0x10, 0, 0},
+ {0x538a, 0x01, 0, 0}, {0x538b, 0x98, 0, 0}, {0x5300, 0x08, 0, 0},
+ {0x5301, 0x30, 0, 0}, {0x5302, 0x10, 0, 0}, {0x5303, 0x00, 0, 0},
+ {0x5304, 0x08, 0, 0}, {0x5305, 0x30, 0, 0}, {0x5306, 0x08, 0, 0},
+ {0x5307, 0x16, 0, 0}, {0x5309, 0x08, 0, 0}, {0x530a, 0x30, 0, 0},
+ {0x530b, 0x04, 0, 0}, {0x530c, 0x06, 0, 0}, {0x5480, 0x01, 0, 0},
+ {0x5481, 0x08, 0, 0}, {0x5482, 0x14, 0, 0}, {0x5483, 0x28, 0, 0},
+ {0x5484, 0x51, 0, 0}, {0x5485, 0x65, 0, 0}, {0x5486, 0x71, 0, 0},
+ {0x5487, 0x7d, 0, 0}, {0x5488, 0x87, 0, 0}, {0x5489, 0x91, 0, 0},
+ {0x548a, 0x9a, 0, 0}, {0x548b, 0xaa, 0, 0}, {0x548c, 0xb8, 0, 0},
+ {0x548d, 0xcd, 0, 0}, {0x548e, 0xdd, 0, 0}, {0x548f, 0xea, 0, 0},
+ {0x5490, 0x1d, 0, 0}, {0x5580, 0x02, 0, 0}, {0x5583, 0x40, 0, 0},
+ {0x5584, 0x10, 0, 0}, {0x5589, 0x10, 0, 0}, {0x558a, 0x00, 0, 0},
+ {0x558b, 0xf8, 0, 0}, {0x5800, 0x23, 0, 0}, {0x5801, 0x14, 0, 0},
+ {0x5802, 0x0f, 0, 0}, {0x5803, 0x0f, 0, 0}, {0x5804, 0x12, 0, 0},
+ {0x5805, 0x26, 0, 0}, {0x5806, 0x0c, 0, 0}, {0x5807, 0x08, 0, 0},
+ {0x5808, 0x05, 0, 0}, {0x5809, 0x05, 0, 0}, {0x580a, 0x08, 0, 0},
+ {0x580b, 0x0d, 0, 0}, {0x580c, 0x08, 0, 0}, {0x580d, 0x03, 0, 0},
+ {0x580e, 0x00, 0, 0}, {0x580f, 0x00, 0, 0}, {0x5810, 0x03, 0, 0},
+ {0x5811, 0x09, 0, 0}, {0x5812, 0x07, 0, 0}, {0x5813, 0x03, 0, 0},
+ {0x5814, 0x00, 0, 0}, {0x5815, 0x01, 0, 0}, {0x5816, 0x03, 0, 0},
+ {0x5817, 0x08, 0, 0}, {0x5818, 0x0d, 0, 0}, {0x5819, 0x08, 0, 0},
+ {0x581a, 0x05, 0, 0}, {0x581b, 0x06, 0, 0}, {0x581c, 0x08, 0, 0},
+ {0x581d, 0x0e, 0, 0}, {0x581e, 0x29, 0, 0}, {0x581f, 0x17, 0, 0},
+ {0x5820, 0x11, 0, 0}, {0x5821, 0x11, 0, 0}, {0x5822, 0x15, 0, 0},
+ {0x5823, 0x28, 0, 0}, {0x5824, 0x46, 0, 0}, {0x5825, 0x26, 0, 0},
+ {0x5826, 0x08, 0, 0}, {0x5827, 0x26, 0, 0}, {0x5828, 0x64, 0, 0},
+ {0x5829, 0x26, 0, 0}, {0x582a, 0x24, 0, 0}, {0x582b, 0x22, 0, 0},
+ {0x582c, 0x24, 0, 0}, {0x582d, 0x24, 0, 0}, {0x582e, 0x06, 0, 0},
+ {0x582f, 0x22, 0, 0}, {0x5830, 0x40, 0, 0}, {0x5831, 0x42, 0, 0},
+ {0x5832, 0x24, 0, 0}, {0x5833, 0x26, 0, 0}, {0x5834, 0x24, 0, 0},
+ {0x5835, 0x22, 0, 0}, {0x5836, 0x22, 0, 0}, {0x5837, 0x26, 0, 0},
+ {0x5838, 0x44, 0, 0}, {0x5839, 0x24, 0, 0}, {0x583a, 0x26, 0, 0},
+ {0x583b, 0x28, 0, 0}, {0x583c, 0x42, 0, 0}, {0x583d, 0xce, 0, 0},
+ {0x5025, 0x00, 0, 0}, {0x3a0f, 0x30, 0, 0}, {0x3a10, 0x28, 0, 0},
+ {0x3a1b, 0x30, 0, 0}, {0x3a1e, 0x26, 0, 0}, {0x3a11, 0x60, 0, 0},
+ {0x3a1f, 0x14, 0, 0}, {0x3008, 0x42, 0, 0}, {0x3c00, 0x04, 0, 300},
+};
+
+static struct reg_value ov5640_setting_30fps_QVGA_320_240[] = {
+ {0x3008, 0x42, 0, 0},
+ {0x3035, 0x12, 0, 0}, {0x3036, 0x38, 0, 0}, {0x3c07, 0x08, 0, 0},
+ {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
+ {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0},
+ {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
+ {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0}, {0x3804, 0x0a, 0, 0},
+ {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9b, 0, 0},
+ {0x3808, 0x01, 0, 0}, {0x3809, 0x40, 0, 0}, {0x380a, 0x00, 0, 0},
+ {0x380b, 0xF0, 0, 0}, {0x380c, 0x07, 0, 0}, {0x380d, 0x68, 0, 0},
+ {0x380e, 0x04, 0, 0}, {0x380f, 0x38, 0, 0}, {0x3810, 0x00, 0, 0},
+ {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x06, 0, 0},
+ {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0},
+ {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x03, 0, 0},
+ {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x0e, 0, 0},
+ {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0},
+ {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0},
+ {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x4713, 0x03, 0, 0},
+ {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0},
+ {0x3824, 0x02, 0, 0}, {0x5001, 0xa3, 0, 0},
+ {0x4005, 0x1a, 0, 0}, {0x3008, 0x02, 0, 0}, {0x3503, 0x00, 0, 0},
+};
+
+static struct reg_value ov5640_setting_30fps_VGA_640_480[] = {
+ {0x3008, 0x42, 0, 0},
+ {0x3035, 0x12, 0, 0}, {0x3036, 0x38, 0, 0}, {0x3c07, 0x08, 0, 0},
+ {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
+ {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0},
+ {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
+ {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0}, {0x3804, 0x0a, 0, 0},
+ {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9b, 0, 0},
+ {0x3808, 0x02, 0, 0}, {0x3809, 0x80, 0, 0}, {0x380a, 0x01, 0, 0},
+ {0x380b, 0xe0, 0, 0}, {0x380c, 0x07, 0, 0}, {0x380d, 0x68, 0, 0},
+ {0x380e, 0x04, 0, 0}, {0x380f, 0x38, 0, 0}, {0x3810, 0x00, 0, 0},
+ {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x06, 0, 0},
+ {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0},
+ {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x03, 0, 0},
+ {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x0e, 0, 0},
+ {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0},
+ {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0},
+ {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x4713, 0x03, 0, 0},
+ {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0},
+ {0x3824, 0x02, 0, 0}, {0x5001, 0xa3, 0, 0},
+ {0x4005, 0x1a, 0, 0}, {0x3008, 0x02, 0, 0}, {0x3503, 0x00, 0, 0},
+};
+
+static struct reg_value ov5640_setting_30fps_NTSC_720_480[] = {
+ {0x3008, 0x42, 0, 0},
+ {0x3035, 0x12, 0, 0}, {0x3036, 0x38, 0, 0}, {0x3c07, 0x08, 0, 0},
+ {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
+ {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0},
+ {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
+ {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0}, {0x3804, 0x0a, 0, 0},
+ {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9b, 0, 0},
+ {0x3808, 0x02, 0, 0}, {0x3809, 0xd0, 0, 0}, {0x380a, 0x01, 0, 0},
+ {0x380b, 0xe0, 0, 0}, {0x380c, 0x07, 0, 0}, {0x380d, 0x68, 0, 0},
+ {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0}, {0x3810, 0x00, 0, 0},
+ {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x3c, 0, 0},
+ {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0},
+ {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x03, 0, 0},
+ {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0},
+ {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0},
+ {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0},
+ {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x4713, 0x03, 0, 0},
+ {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0},
+ {0x3824, 0x02, 0, 0}, {0x5001, 0xa3, 0, 0},
+ {0x4005, 0x1a, 0, 0}, {0x3008, 0x02, 0, 0}, {0x3503, 0, 0, 0},
+};
+
+static struct reg_value ov5640_setting_30fps_720P_1280_720[] = {
+ {0x3008, 0x42, 0, 0},
+ {0x3035, 0x21, 0, 0}, {0x3036, 0x54, 0, 0}, {0x3c07, 0x07, 0, 0},
+ {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
+ {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0},
+ {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
+ {0x3802, 0x00, 0, 0}, {0x3803, 0xfa, 0, 0}, {0x3804, 0x0a, 0, 0},
+ {0x3805, 0x3f, 0, 0}, {0x3806, 0x06, 0, 0}, {0x3807, 0xa9, 0, 0},
+ {0x3808, 0x05, 0, 0}, {0x3809, 0x00, 0, 0}, {0x380a, 0x02, 0, 0},
+ {0x380b, 0xd0, 0, 0}, {0x380c, 0x07, 0, 0}, {0x380d, 0x64, 0, 0},
+ {0x380e, 0x02, 0, 0}, {0x380f, 0xe4, 0, 0}, {0x3810, 0x00, 0, 0},
+ {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x04, 0, 0},
+ {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0},
+ {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x02, 0, 0},
+ {0x3a03, 0xe4, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0xbc, 0, 0},
+ {0x3a0a, 0x01, 0, 0}, {0x3a0b, 0x72, 0, 0}, {0x3a0e, 0x01, 0, 0},
+ {0x3a0d, 0x02, 0, 0}, {0x3a14, 0x02, 0, 0}, {0x3a15, 0xe4, 0, 0},
+ {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x4713, 0x02, 0, 0},
+ {0x4407, 0x04, 0, 0}, {0x460b, 0x37, 0, 0}, {0x460c, 0x20, 0, 0},
+ {0x3824, 0x04, 0, 0}, {0x5001, 0x83, 0, 0}, {0x4005, 0x1a, 0, 0},
+ {0x3008, 0x02, 0, 0}, {0x3503, 0, 0, 0},
+};
+
+static struct reg_value ov5640_setting_30fps_1080P_1920_1080[] = {
+ {0x3008, 0x42, 0, 0},
+ {0x3035, 0x21, 0, 0}, {0x3036, 0x54, 0, 0}, {0x3c07, 0x08, 0, 0},
+ {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
+ {0x3820, 0x40, 0, 0}, {0x3821, 0x06, 0, 0}, {0x3814, 0x11, 0, 0},
+ {0x3815, 0x11, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
+ {0x3802, 0x00, 0, 0}, {0x3803, 0x00, 0, 0}, {0x3804, 0x0a, 0, 0},
+ {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9f, 0, 0},
+ {0x3808, 0x0a, 0, 0}, {0x3809, 0x20, 0, 0}, {0x380a, 0x07, 0, 0},
+ {0x380b, 0x98, 0, 0}, {0x380c, 0x0b, 0, 0}, {0x380d, 0x1c, 0, 0},
+ {0x380e, 0x07, 0, 0}, {0x380f, 0xb0, 0, 0}, {0x3810, 0x00, 0, 0},
+ {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x04, 0, 0},
+ {0x3618, 0x04, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x21, 0, 0},
+ {0x3709, 0x12, 0, 0}, {0x370c, 0x00, 0, 0}, {0x3a02, 0x03, 0, 0},
+ {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0},
+ {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0},
+ {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0},
+ {0x4001, 0x02, 0, 0}, {0x4004, 0x06, 0, 0}, {0x4713, 0x03, 0, 0},
+ {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0},
+ {0x3824, 0x02, 0, 0}, {0x5001, 0x83, 0, 0}, {0x3035, 0x11, 0, 0},
+ {0x3036, 0x54, 0, 0}, {0x3c07, 0x07, 0, 0}, {0x3c08, 0x00, 0, 0},
+ {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
+ {0x3800, 0x01, 0, 0}, {0x3801, 0x50, 0, 0}, {0x3802, 0x01, 0, 0},
+ {0x3803, 0xb2, 0, 0}, {0x3804, 0x08, 0, 0}, {0x3805, 0xef, 0, 0},
+ {0x3806, 0x05, 0, 0}, {0x3807, 0xf1, 0, 0}, {0x3808, 0x07, 0, 0},
+ {0x3809, 0x80, 0, 0}, {0x380a, 0x04, 0, 0}, {0x380b, 0x38, 0, 0},
+ {0x380c, 0x09, 0, 0}, {0x380d, 0xc4, 0, 0}, {0x380e, 0x04, 0, 0},
+ {0x380f, 0x60, 0, 0}, {0x3612, 0x2b, 0, 0}, {0x3708, 0x64, 0, 0},
+ {0x3a02, 0x04, 0, 0}, {0x3a03, 0x60, 0, 0}, {0x3a08, 0x01, 0, 0},
+ {0x3a09, 0x50, 0, 0}, {0x3a0a, 0x01, 0, 0}, {0x3a0b, 0x18, 0, 0},
+ {0x3a0e, 0x03, 0, 0}, {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x04, 0, 0},
+ {0x3a15, 0x60, 0, 0}, {0x4713, 0x02, 0, 0}, {0x4407, 0x04, 0, 0},
+ {0x460b, 0x37, 0, 0}, {0x460c, 0x20, 0, 0}, {0x3824, 0x04, 0, 0},
+ {0x4005, 0x1a, 0, 0}, {0x3008, 0x02, 0, 0},
+ {0x3503, 0, 0, 0},
+};
+
+static struct reg_value ov5640_setting_15fps_QSXGA_2592_1944[] = {
+ {0x3008, 0x42, 0, 0},
+ {0x3820, 0x40, 0, 0}, {0x3821, 0x06, 0, 0}, /*disable flip*/
+ {0x3035, 0x11, 0, 0}, {0x3036, 0x54, 0, 0}, {0x3c07, 0x08, 0, 0},
+ {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
+ {0x3820, 0x40, 0, 0}, {0x3821, 0x06, 0, 0}, {0x3814, 0x11, 0, 0},
+ {0x3815, 0x11, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
+ {0x3802, 0x00, 0, 0}, {0x3803, 0x00, 0, 0}, {0x3804, 0x0a, 0, 0},
+ {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9f, 0, 0},
+ {0x3808, 0x0a, 0, 0}, {0x3809, 0x20, 0, 0}, {0x380a, 0x07, 0, 0},
+ {0x380b, 0x98, 0, 0}, {0x380c, 0x0b, 0, 0}, {0x380d, 0x1c, 0, 0},
+ {0x380e, 0x07, 0, 0}, {0x380f, 0xb0, 0, 0}, {0x3810, 0x00, 0, 0},
+ {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x04, 0, 0},
+ {0x3618, 0x04, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x21, 0, 0},
+ {0x3709, 0x12, 0, 0}, {0x370c, 0x00, 0, 0}, {0x3a02, 0x03, 0, 0},
+ {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0},
+ {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0},
+ {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0},
+ {0x4001, 0x02, 0, 0}, {0x4004, 0x06, 0, 0}, {0x4713, 0x03, 0, 0},
+ {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0},
+ {0x3824, 0x02, 0, 0}, {0x5001, 0x83, 0, 70}, {0x3008, 0x02, 0, 0},
+};
+
+static struct ov5640_mode_info ov5640_mode_info_data[2][ov5640_mode_MAX + 1] = {
+ {
+ {ov5640_mode_VGA_640_480, -1, 0, 0, NULL, 0},
+ {ov5640_mode_QVGA_320_240, -1, 0, 0, NULL, 0},
+ {ov5640_mode_NTSC_720_480, -1, 0, 0, NULL, 0},
+ {ov5640_mode_720P_1280_720, -1, 0, 0, NULL, 0},
+ {ov5640_mode_1080P_1920_1080, -1, 0, 0, NULL, 0},
+ {ov5640_mode_QSXGA_2592_1944, SCALING, 2592, 1944,
+ ov5640_setting_15fps_QSXGA_2592_1944,
+ ARRAY_SIZE(ov5640_setting_15fps_QSXGA_2592_1944)},
+ },
+ {
+ {ov5640_mode_VGA_640_480, SUBSAMPLING, 640, 480,
+ ov5640_setting_30fps_VGA_640_480,
+ ARRAY_SIZE(ov5640_setting_30fps_VGA_640_480)},
+ {ov5640_mode_QVGA_320_240, SUBSAMPLING, 320, 240,
+ ov5640_setting_30fps_QVGA_320_240,
+ ARRAY_SIZE(ov5640_setting_30fps_QVGA_320_240)},
+ {ov5640_mode_NTSC_720_480, SUBSAMPLING, 720, 480,
+ ov5640_setting_30fps_NTSC_720_480,
+ ARRAY_SIZE(ov5640_setting_30fps_NTSC_720_480)},
+ {ov5640_mode_720P_1280_720, SUBSAMPLING, 1280, 720,
+ ov5640_setting_30fps_720P_1280_720,
+ ARRAY_SIZE(ov5640_setting_30fps_720P_1280_720)},
+ {ov5640_mode_1080P_1920_1080, SCALING, 1920, 1080,
+ ov5640_setting_30fps_1080P_1920_1080,
+ ARRAY_SIZE(ov5640_setting_30fps_1080P_1920_1080)},
+ {ov5640_mode_QSXGA_2592_1944, -1, 0, 0, NULL, 0},
+ },
+};
+
+static struct regulator *io_regulator;
+static struct regulator *core_regulator;
+static struct regulator *analog_regulator;
+static struct regulator *gpo_regulator;
+static DEFINE_MUTEX(ov5640_mutex);
+
+static int ov5640_probe(struct i2c_client *adapter,
+ const struct i2c_device_id *device_id);
+static int ov5640_remove(struct i2c_client *client);
+
+static s32 ov5640_read_reg(struct ov5640 *sensor, u16 reg, u8 *val);
+static s32 ov5640_write_reg(struct ov5640 *sensor, u16 reg, u8 val);
+
+static const struct i2c_device_id ov5640_id[] = {
+ {"ov5640_mipi", 0},
+ {},
+};
+
+MODULE_DEVICE_TABLE(i2c, ov5640_id);
+
+static struct i2c_driver ov5640_i2c_driver = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "ov5640_mipi",
+ },
+ .probe = ov5640_probe,
+ .remove = ov5640_remove,
+ .id_table = ov5640_id,
+};
+
+static const struct ov5640_datafmt ov5640_colour_fmts[] = {
+ {MEDIA_BUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_JPEG},
+};
+
+static int get_capturemode(int width, int height)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(ov5640_valid_res); i++) {
+ if ((ov5640_valid_res[i].width == width) &&
+ (ov5640_valid_res[i].height == height))
+ return i;
+ }
+
+ return -1;
+}
+
+static struct ov5640 *to_ov5640(const struct i2c_client *client)
+{
+ return container_of(i2c_get_clientdata(client), struct ov5640, subdev);
+}
+
+/* Find a data format by a pixel code in an array */
+static const struct ov5640_datafmt
+ *ov5640_find_datafmt(u32 code)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(ov5640_colour_fmts); i++)
+ if (ov5640_colour_fmts[i].code == code)
+ return ov5640_colour_fmts + i;
+
+ return NULL;
+}
+
+static inline void ov5640_power_down(struct ov5640 *sensor, int enable)
+{
+ if (sensor->pwn_gpio < 0)
+ return;
+
+ if (!enable)
+ gpio_set_value_cansleep(sensor->pwn_gpio, 0);
+ else
+ gpio_set_value_cansleep(sensor->pwn_gpio, 1);
+
+ msleep(2);
+}
+
+static int ov5640_update_slave_id(struct ov5640 *sensor)
+{
+ struct device *dev = &sensor->i2c_client->dev;
+ u8 slave_id;
+ struct i2c_client *tmp_client;
+ s32 retval;
+
+ if (sensor->i2c_client->addr << 1 == DEFAULT_SCCB_ID)
+ return 0; /* nothing to do */
+
+ /* Change camera i2c slave address */
+ slave_id = (u8)(sensor->i2c_client->addr << 1); /* new slave id*/
+ tmp_client = sensor->i2c_client;
+
+ sensor->i2c_client =
+ i2c_new_dummy(tmp_client->adapter, DEFAULT_SCCB_ID >> 1);
+ if (!sensor->i2c_client) {
+ dev_err(dev, "Failed to communicate on 0x%x\n",
+ DEFAULT_SCCB_ID);
+ return -1;
+ }
+
+ retval = ov5640_write_reg(sensor, 0x3100, slave_id);
+ i2c_unregister_device(sensor->i2c_client);
+ sensor->i2c_client = tmp_client;
+ if (retval != 0) {
+ dev_err(dev, "Failed to update SCCB_ID to 0x%x\n", slave_id);
+ return -1;
+ }
+
+ ov5640_read_reg(sensor, 0x3100, &slave_id);
+ dev_dbg(dev, "Updated SCCB_ID 0x%x\n", slave_id);
+
+ return 0;
+}
+
+static void ov5640_reset(struct ov5640 *sensor)
+{
+ if (sensor->rst_gpio < 0 || sensor->pwn_gpio < 0)
+ return;
+
+ /* camera reset */
+ gpio_set_value(sensor->rst_gpio, 1);
+
+ /* camera power dowmn */
+ gpio_set_value(sensor->pwn_gpio, 1);
+ msleep(5);
+
+ gpio_set_value(sensor->rst_gpio, 0);
+ msleep(1);
+
+ gpio_set_value(sensor->pwn_gpio, 0);
+ msleep(5);
+
+ gpio_set_value(sensor->rst_gpio, 1);
+ msleep(5);
+}
+
+static int ov5640_regulator_enable(struct device *dev)
+{
+ int ret = 0;
+
+ io_regulator = devm_regulator_get(dev, "DOVDD");
+ if (!IS_ERR(io_regulator)) {
+ regulator_set_voltage(io_regulator,
+ OV5640_VOLTAGE_DIGITAL_IO,
+ OV5640_VOLTAGE_DIGITAL_IO);
+ ret = regulator_enable(io_regulator);
+ if (ret) {
+ pr_err("%s:io set voltage error\n", __func__);
+ return ret;
+ } else {
+ dev_dbg(dev,
+ "%s:io set voltage ok\n", __func__);
+ }
+ } else {
+ pr_err("%s: cannot get io voltage error\n", __func__);
+ io_regulator = NULL;
+ }
+
+ core_regulator = devm_regulator_get(dev, "DVDD");
+ if (!IS_ERR(core_regulator)) {
+ regulator_set_voltage(core_regulator,
+ OV5640_VOLTAGE_DIGITAL_CORE,
+ OV5640_VOLTAGE_DIGITAL_CORE);
+ ret = regulator_enable(core_regulator);
+ if (ret) {
+ pr_err("%s:core set voltage error\n", __func__);
+ return ret;
+ } else {
+ dev_dbg(dev,
+ "%s:core set voltage ok\n", __func__);
+ }
+ } else {
+ core_regulator = NULL;
+ pr_err("%s: cannot get core voltage error\n", __func__);
+ }
+
+ analog_regulator = devm_regulator_get(dev, "AVDD");
+ if (!IS_ERR(analog_regulator)) {
+ regulator_set_voltage(analog_regulator,
+ OV5640_VOLTAGE_ANALOG,
+ OV5640_VOLTAGE_ANALOG);
+ ret = regulator_enable(analog_regulator);
+ if (ret) {
+ pr_err("%s:analog set voltage error\n",
+ __func__);
+ return ret;
+ } else {
+ dev_dbg(dev,
+ "%s:analog set voltage ok\n", __func__);
+ }
+ } else {
+ analog_regulator = NULL;
+ pr_err("%s: cannot get analog voltage error\n", __func__);
+ }
+
+ return ret;
+}
+
+static s32 ov5640_write_reg(struct ov5640 *sensor, u16 reg, u8 val)
+{
+ struct device *dev = &sensor->i2c_client->dev;
+ u8 au8Buf[3] = {0};
+
+ au8Buf[0] = reg >> 8;
+ au8Buf[1] = reg & 0xff;
+ au8Buf[2] = val;
+
+ if (i2c_master_send(sensor->i2c_client, au8Buf, 3) < 0) {
+ dev_err(dev, "Write reg error: reg=%x, val=%x\n", reg, val);
+ return -1;
+ }
+
+ return 0;
+}
+
+static s32 ov5640_read_reg(struct ov5640 *sensor, u16 reg, u8 *val)
+{
+ struct device *dev = &sensor->i2c_client->dev;
+ u8 au8RegBuf[2] = {0};
+ u8 u8RdVal = 0;
+
+ au8RegBuf[0] = reg >> 8;
+ au8RegBuf[1] = reg & 0xff;
+
+ if (i2c_master_send(sensor->i2c_client, au8RegBuf, 2) != 2) {
+ dev_err(dev, "Read reg error: reg=%x\n", reg);
+ return -1;
+ }
+
+ if (i2c_master_recv(sensor->i2c_client, &u8RdVal, 1) != 1) {
+ dev_err(dev, "Read reg error: reg=%x, val=%x\n", reg, u8RdVal);
+ return -1;
+ }
+
+ *val = u8RdVal;
+
+ return u8RdVal;
+}
+
+static int prev_sysclk, prev_HTS;
+static int AE_low, AE_high, AE_Target = 52;
+
+static void OV5640_stream_on(struct ov5640 *sensor)
+{
+ ov5640_write_reg(sensor, 0x4202, 0x00);
+}
+
+static void OV5640_stream_off(struct ov5640 *sensor)
+{
+ ov5640_write_reg(sensor, 0x4202, 0x0f);
+ ov5640_write_reg(sensor, 0x3008, 0x42);
+}
+
+static int OV5640_get_sysclk(struct ov5640 *sensor)
+{
+ /* calculate sysclk */
+ int xvclk = sensor->mclk / 10000;
+ int temp1, temp2;
+ int Multiplier, PreDiv, VCO, SysDiv, Pll_rdiv;
+ int Bit_div2x = 1, sclk_rdiv, sysclk;
+ u8 temp;
+
+ int sclk_rdiv_map[] = {1, 2, 4, 8};
+
+ temp1 = ov5640_read_reg(sensor, 0x3034, &temp);
+ temp2 = temp1 & 0x0f;
+ if (temp2 == 8 || temp2 == 10)
+ Bit_div2x = temp2 / 2;
+
+ temp1 = ov5640_read_reg(sensor, 0x3035, &temp);
+ SysDiv = temp1>>4;
+ if (SysDiv == 0)
+ SysDiv = 16;
+
+ temp1 = ov5640_read_reg(sensor, 0x3036, &temp);
+ Multiplier = temp1;
+
+ temp1 = ov5640_read_reg(sensor, 0x3037, &temp);
+ PreDiv = temp1 & 0x0f;
+ Pll_rdiv = ((temp1 >> 4) & 0x01) + 1;
+
+ temp1 = ov5640_read_reg(sensor, 0x3108, &temp);
+ temp2 = temp1 & 0x03;
+ sclk_rdiv = sclk_rdiv_map[temp2];
+
+ VCO = xvclk * Multiplier / PreDiv;
+
+ sysclk = VCO / SysDiv / Pll_rdiv * 2 / Bit_div2x / sclk_rdiv;
+
+ return sysclk;
+}
+
+static void OV5640_set_night_mode(struct ov5640 *sensor)
+{
+ /* read HTS from register settings */
+ u8 mode;
+
+ ov5640_read_reg(sensor, 0x3a00, &mode);
+ mode &= 0xfb;
+ ov5640_write_reg(sensor, 0x3a00, mode);
+}
+
+static int OV5640_get_HTS(struct ov5640 *sensor)
+{
+ /* read HTS from register settings */
+ int HTS;
+ u8 temp;
+
+ HTS = ov5640_read_reg(sensor, 0x380c, &temp);
+ HTS = (HTS<<8) + ov5640_read_reg(sensor, 0x380d, &temp);
+
+ return HTS;
+}
+
+static int OV5640_get_VTS(struct ov5640 *sensor)
+{
+ /* read VTS from register settings */
+ int VTS;
+ u8 temp;
+
+ /* total vertical size[15:8] high byte */
+ VTS = ov5640_read_reg(sensor, 0x380e, &temp);
+
+ VTS = (VTS<<8) + ov5640_read_reg(sensor, 0x380f, &temp);
+
+ return VTS;
+}
+
+static int OV5640_set_VTS(struct ov5640 *sensor, int VTS)
+{
+ /* write VTS to registers */
+ int temp;
+
+ temp = VTS & 0xff;
+ ov5640_write_reg(sensor, 0x380f, temp);
+
+ temp = VTS>>8;
+ ov5640_write_reg(sensor, 0x380e, temp);
+
+ return 0;
+}
+
+static int OV5640_get_shutter(struct ov5640 *sensor)
+{
+ /* read shutter, in number of line period */
+ int shutter;
+ u8 temp;
+
+ shutter = (ov5640_read_reg(sensor, 0x03500, &temp) & 0x0f);
+ shutter = (shutter<<8) + ov5640_read_reg(sensor, 0x3501, &temp);
+ shutter = (shutter<<4) + (ov5640_read_reg(sensor, 0x3502, &temp)>>4);
+
+ return shutter;
+}
+
+static int OV5640_set_shutter(struct ov5640 *sensor, int shutter)
+{
+ /* write shutter, in number of line period */
+ int temp;
+
+ shutter = shutter & 0xffff;
+
+ temp = shutter & 0x0f;
+ temp = temp<<4;
+ ov5640_write_reg(sensor, 0x3502, temp);
+
+ temp = shutter & 0xfff;
+ temp = temp>>4;
+ ov5640_write_reg(sensor, 0x3501, temp);
+
+ temp = shutter>>12;
+ ov5640_write_reg(sensor, 0x3500, temp);
+
+ return 0;
+}
+
+
+static int OV5640_get_gain16(struct ov5640 *sensor)
+{
+ /* read gain, 16 = 1x */
+ int gain16;
+ u8 temp;
+
+ gain16 = ov5640_read_reg(sensor, 0x350a, &temp) & 0x03;
+ gain16 = (gain16<<8) + ov5640_read_reg(sensor, 0x350b, &temp);
+
+ return gain16;
+}
+
+static int OV5640_set_gain16(struct ov5640 *sensor, int gain16)
+{
+ /* write gain, 16 = 1x */
+ u8 temp;
+ gain16 = gain16 & 0x3ff;
+
+ temp = gain16 & 0xff;
+ ov5640_write_reg(sensor, 0x350b, temp);
+
+ temp = gain16>>8;
+ ov5640_write_reg(sensor, 0x350a, temp);
+
+ return 0;
+}
+
+static int OV5640_get_light_freq(struct ov5640 *sensor)
+{
+ /* get banding filter value */
+ int temp, temp1, light_freq = 0;
+ u8 tmp;
+
+ temp = ov5640_read_reg(sensor, 0x3c01, &tmp);
+
+ if (temp & 0x80) {
+ /* manual */
+ temp1 = ov5640_read_reg(sensor, 0x3c00, &tmp);
+ if (temp1 & 0x04) {
+ /* 50Hz */
+ light_freq = 50;
+ } else {
+ /* 60Hz */
+ light_freq = 60;
+ }
+ } else {
+ /* auto */
+ temp1 = ov5640_read_reg(sensor, 0x3c0c, &tmp);
+ if (temp1 & 0x01) {
+ /* 50Hz */
+ light_freq = 50;
+ } else {
+ /* 60Hz */
+ }
+ }
+ return light_freq;
+}
+
+static void OV5640_set_bandingfilter(struct ov5640 *sensor)
+{
+ int prev_VTS;
+ int band_step60, max_band60, band_step50, max_band50;
+
+ /* read preview PCLK */
+ prev_sysclk = OV5640_get_sysclk(sensor);
+ /* read preview HTS */
+ prev_HTS = OV5640_get_HTS(sensor);
+
+ /* read preview VTS */
+ prev_VTS = OV5640_get_VTS(sensor);
+
+ /* calculate banding filter */
+ /* 60Hz */
+ band_step60 = prev_sysclk * 100/prev_HTS * 100/120;
+ ov5640_write_reg(sensor, 0x3a0a, (band_step60 >> 8));
+ ov5640_write_reg(sensor, 0x3a0b, (band_step60 & 0xff));
+
+ max_band60 = (int)((prev_VTS-4)/band_step60);
+ ov5640_write_reg(sensor, 0x3a0d, max_band60);
+
+ /* 50Hz */
+ band_step50 = prev_sysclk * 100/prev_HTS;
+ ov5640_write_reg(sensor, 0x3a08, (band_step50 >> 8));
+ ov5640_write_reg(sensor, 0x3a09, (band_step50 & 0xff));
+
+ max_band50 = (int)((prev_VTS-4)/band_step50);
+ ov5640_write_reg(sensor, 0x3a0e, max_band50);
+}
+
+static int OV5640_set_AE_target(struct ov5640 *sensor, int target)
+{
+ /* stable in high */
+ int fast_high, fast_low;
+ AE_low = target * 23 / 25; /* 0.92 */
+ AE_high = target * 27 / 25; /* 1.08 */
+
+ fast_high = AE_high<<1;
+ if (fast_high > 255)
+ fast_high = 255;
+
+ fast_low = AE_low >> 1;
+
+ ov5640_write_reg(sensor, 0x3a0f, AE_high);
+ ov5640_write_reg(sensor, 0x3a10, AE_low);
+ ov5640_write_reg(sensor, 0x3a1b, AE_high);
+ ov5640_write_reg(sensor, 0x3a1e, AE_low);
+ ov5640_write_reg(sensor, 0x3a11, fast_high);
+ ov5640_write_reg(sensor, 0x3a1f, fast_low);
+
+ return 0;
+}
+
+static void OV5640_turn_on_AE_AG(struct ov5640 *sensor, int enable)
+{
+ u8 ae_ag_ctrl;
+
+ ov5640_read_reg(sensor, 0x3503, &ae_ag_ctrl);
+ if (enable) {
+ /* turn on auto AE/AG */
+ ae_ag_ctrl = ae_ag_ctrl & ~(0x03);
+ } else {
+ /* turn off AE/AG */
+ ae_ag_ctrl = ae_ag_ctrl | 0x03;
+ }
+ ov5640_write_reg(sensor, 0x3503, ae_ag_ctrl);
+}
+
+static bool binning_on(struct ov5640 *sensor)
+{
+ u8 temp;
+ ov5640_read_reg(sensor, 0x3821, &temp);
+ temp &= 0xfe;
+ if (temp)
+ return true;
+ else
+ return false;
+}
+
+static void ov5640_set_virtual_channel(struct ov5640 *sensor, int channel)
+{
+ u8 channel_id;
+
+ ov5640_read_reg(sensor, 0x4814, &channel_id);
+ channel_id &= ~(3 << 6);
+ ov5640_write_reg(sensor, 0x4814, channel_id | (channel << 6));
+}
+
+/* download ov5640 settings to sensor through i2c */
+static int ov5640_download_firmware(struct ov5640 *sensor,
+ struct reg_value *pModeSetting,
+ s32 ArySize)
+{
+ register u32 Delay_ms = 0;
+ register u16 RegAddr = 0;
+ register u8 Mask = 0;
+ register u8 Val = 0;
+ u8 RegVal = 0;
+ int i, retval = 0;
+
+ for (i = 0; i < ArySize; ++i, ++pModeSetting) {
+ Delay_ms = pModeSetting->u32Delay_ms;
+ RegAddr = pModeSetting->u16RegAddr;
+ Val = pModeSetting->u8Val;
+ Mask = pModeSetting->u8Mask;
+
+ if (Mask) {
+ retval = ov5640_read_reg(sensor, RegAddr, &RegVal);
+ if (retval < 0)
+ goto err;
+
+ RegVal &= ~(u8)Mask;
+ Val &= Mask;
+ Val |= RegVal;
+ }
+
+ retval = ov5640_write_reg(sensor, RegAddr, Val);
+ if (retval < 0)
+ goto err;
+
+ if (Delay_ms)
+ msleep(Delay_ms);
+ }
+err:
+ return retval;
+}
+
+/* sensor changes between scaling and subsampling
+ * go through exposure calcualtion
+ */
+static int ov5640_change_mode_exposure_calc(struct ov5640 *sensor,
+ enum ov5640_frame_rate frame_rate,
+ enum ov5640_mode mode)
+{
+ struct reg_value *pModeSetting = NULL;
+ s32 ArySize = 0;
+ u8 average;
+ int prev_shutter, prev_gain16;
+ int cap_shutter, cap_gain16;
+ int cap_sysclk, cap_HTS, cap_VTS;
+ int light_freq, cap_bandfilt, cap_maxband;
+ long cap_gain16_shutter;
+ int retval = 0;
+
+ /* check if the input mode and frame rate is valid */
+ pModeSetting =
+ ov5640_mode_info_data[frame_rate][mode].init_data_ptr;
+ ArySize =
+ ov5640_mode_info_data[frame_rate][mode].init_data_size;
+
+ sensor->pix.width =
+ ov5640_mode_info_data[frame_rate][mode].width;
+ sensor->pix.height =
+ ov5640_mode_info_data[frame_rate][mode].height;
+
+ if (sensor->pix.width == 0 || sensor->pix.height == 0 ||
+ pModeSetting == NULL || ArySize == 0)
+ return -EINVAL;
+
+ /* auto focus */
+ /* OV5640_auto_focus();//if no af function, just skip it */
+
+ /* turn off AE/AG */
+ OV5640_turn_on_AE_AG(sensor, 0);
+
+ /* read preview shutter */
+ prev_shutter = OV5640_get_shutter(sensor);
+ if ((binning_on(sensor)) && (mode != ov5640_mode_720P_1280_720)
+ && (mode != ov5640_mode_1080P_1920_1080))
+ prev_shutter *= 2;
+
+ /* read preview gain */
+ prev_gain16 = OV5640_get_gain16(sensor);
+
+ /* get average */
+ ov5640_read_reg(sensor, 0x56a1, &average);
+
+ /* turn off night mode for capture */
+ OV5640_set_night_mode(sensor);
+
+ /* turn off overlay */
+ /* ov5640_write_reg(0x3022, 0x06);//if no af function, just skip it */
+
+ OV5640_stream_off(sensor);
+
+ /* Write capture setting */
+ retval = ov5640_download_firmware(sensor, pModeSetting, ArySize);
+ if (retval < 0)
+ goto err;
+
+ /* read capture VTS */
+ cap_VTS = OV5640_get_VTS(sensor);
+ cap_HTS = OV5640_get_HTS(sensor);
+ cap_sysclk = OV5640_get_sysclk(sensor);
+
+ /* calculate capture banding filter */
+ light_freq = OV5640_get_light_freq(sensor);
+ if (light_freq == 60) {
+ /* 60Hz */
+ cap_bandfilt = cap_sysclk * 100 / cap_HTS * 100 / 120;
+ } else {
+ /* 50Hz */
+ cap_bandfilt = cap_sysclk * 100 / cap_HTS;
+ }
+ cap_maxband = (int)((cap_VTS - 4)/cap_bandfilt);
+
+ /* calculate capture shutter/gain16 */
+ if (average > AE_low && average < AE_high) {
+ /* in stable range */
+ cap_gain16_shutter =
+ prev_gain16 * prev_shutter * cap_sysclk/prev_sysclk
+ * prev_HTS/cap_HTS * AE_Target / average;
+ } else {
+ cap_gain16_shutter =
+ prev_gain16 * prev_shutter * cap_sysclk/prev_sysclk
+ * prev_HTS/cap_HTS;
+ }
+
+ /* gain to shutter */
+ if (cap_gain16_shutter < (cap_bandfilt * 16)) {
+ /* shutter < 1/100 */
+ cap_shutter = cap_gain16_shutter/16;
+ if (cap_shutter < 1)
+ cap_shutter = 1;
+
+ cap_gain16 = cap_gain16_shutter/cap_shutter;
+ if (cap_gain16 < 16)
+ cap_gain16 = 16;
+ } else {
+ if (cap_gain16_shutter >
+ (cap_bandfilt * cap_maxband * 16)) {
+ /* exposure reach max */
+ cap_shutter = cap_bandfilt * cap_maxband;
+ cap_gain16 = cap_gain16_shutter / cap_shutter;
+ } else {
+ /* 1/100 < (cap_shutter = n/100) =< max */
+ cap_shutter =
+ ((int) (cap_gain16_shutter/16 / cap_bandfilt))
+ *cap_bandfilt;
+ cap_gain16 = cap_gain16_shutter / cap_shutter;
+ }
+ }
+
+ /* write capture gain */
+ OV5640_set_gain16(sensor, cap_gain16);
+
+ /* write capture shutter */
+ if (cap_shutter > (cap_VTS - 4)) {
+ cap_VTS = cap_shutter + 4;
+ OV5640_set_VTS(sensor, cap_VTS);
+ }
+ OV5640_set_shutter(sensor, cap_shutter);
+
+err:
+ return retval;
+}
+
+/* if sensor changes inside scaling or subsampling
+ * change mode directly
+ * */
+static int ov5640_change_mode_direct(struct ov5640 *sensor,
+ enum ov5640_frame_rate frame_rate,
+ enum ov5640_mode mode)
+{
+ struct reg_value *pModeSetting = NULL;
+ s32 ArySize = 0;
+ int retval = 0;
+
+ /* check if the input mode and frame rate is valid */
+ pModeSetting =
+ ov5640_mode_info_data[frame_rate][mode].init_data_ptr;
+ ArySize =
+ ov5640_mode_info_data[frame_rate][mode].init_data_size;
+
+ sensor->pix.width =
+ ov5640_mode_info_data[frame_rate][mode].width;
+ sensor->pix.height =
+ ov5640_mode_info_data[frame_rate][mode].height;
+
+ if (sensor->pix.width == 0 || sensor->pix.height == 0 ||
+ pModeSetting == NULL || ArySize == 0)
+ return -EINVAL;
+
+ /* turn off AE/AG */
+ OV5640_turn_on_AE_AG(sensor, 0);
+
+ OV5640_stream_off(sensor);
+
+ /* Write capture setting */
+ retval = ov5640_download_firmware(sensor, pModeSetting, ArySize);
+ if (retval < 0)
+ goto err;
+
+ OV5640_turn_on_AE_AG(sensor, 1);
+
+err:
+ return retval;
+}
+
+static int ov5640_init_mode(struct ov5640 *sensor,
+ enum ov5640_frame_rate frame_rate,
+ enum ov5640_mode mode, enum ov5640_mode orig_mode)
+{
+ struct device *dev = &sensor->i2c_client->dev;
+ struct reg_value *pModeSetting = NULL;
+ s32 ArySize = 0;
+ int retval = 0;
+ u32 msec_wait4stable = 0;
+ enum ov5640_downsize_mode dn_mode, orig_dn_mode;
+
+ if ((mode > ov5640_mode_MAX || mode < ov5640_mode_MIN)
+ && (mode != ov5640_mode_INIT)) {
+ dev_err(dev, "Wrong ov5640 mode detected!\n");
+ return -1;
+ }
+
+ dn_mode = ov5640_mode_info_data[frame_rate][mode].dn_mode;
+ orig_dn_mode = ov5640_mode_info_data[frame_rate][orig_mode].dn_mode;
+ if (mode == ov5640_mode_INIT) {
+ pModeSetting = ov5640_init_setting_30fps_VGA;
+ ArySize = ARRAY_SIZE(ov5640_init_setting_30fps_VGA);
+
+ sensor->pix.width = 640;
+ sensor->pix.height = 480;
+ retval = ov5640_download_firmware(sensor, pModeSetting,
+ ArySize);
+ if (retval < 0)
+ goto err;
+
+ pModeSetting = ov5640_setting_30fps_VGA_640_480;
+ ArySize = ARRAY_SIZE(ov5640_setting_30fps_VGA_640_480);
+ retval = ov5640_download_firmware(sensor, pModeSetting,
+ ArySize);
+ } else if ((dn_mode == SUBSAMPLING && orig_dn_mode == SCALING) ||
+ (dn_mode == SCALING && orig_dn_mode == SUBSAMPLING)) {
+ /* change between subsampling and scaling
+ * go through exposure calucation */
+ retval = ov5640_change_mode_exposure_calc(sensor,
+ frame_rate, mode);
+ } else {
+ /* change inside subsampling or scaling
+ * download firmware directly */
+ retval = ov5640_change_mode_direct(sensor, frame_rate, mode);
+ }
+
+ if (retval < 0)
+ goto err;
+
+ OV5640_set_AE_target(sensor, AE_Target);
+ OV5640_get_light_freq(sensor);
+ OV5640_set_bandingfilter(sensor);
+ ov5640_set_virtual_channel(sensor, sensor->csi);
+
+ /* add delay to wait for sensor stable */
+ if (mode == ov5640_mode_QSXGA_2592_1944) {
+ /* dump the first two frames: 1/7.5*2
+ * the frame rate of QSXGA is 7.5fps */
+ msec_wait4stable = 267;
+ } else {
+ /* dump the first eighteen frames: 1/30*18 */
+ msec_wait4stable = 600;
+ }
+ msleep(msec_wait4stable);
+
+err:
+ return retval;
+}
+
+/*!
+ * ov5640_s_power - V4L2 sensor interface handler for VIDIOC_S_POWER ioctl
+ * @s: pointer to standard V4L2 device structure
+ * @on: indicates power mode (on or off)
+ *
+ * Turns the power on or off, depending on the value of on and returns the
+ * appropriate error code.
+ */
+static int ov5640_s_power(struct v4l2_subdev *sd, int on)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct ov5640 *sensor = to_ov5640(client);
+
+ if (on && !sensor->on) {
+ if (io_regulator)
+ if (regulator_enable(io_regulator) != 0)
+ return -EIO;
+ if (core_regulator)
+ if (regulator_enable(core_regulator) != 0)
+ return -EIO;
+ if (gpo_regulator)
+ if (regulator_enable(gpo_regulator) != 0)
+ return -EIO;
+ if (analog_regulator)
+ if (regulator_enable(analog_regulator) != 0)
+ return -EIO;
+ } else if (!on && sensor->on) {
+ if (analog_regulator)
+ regulator_disable(analog_regulator);
+ if (core_regulator)
+ regulator_disable(core_regulator);
+ if (io_regulator)
+ regulator_disable(io_regulator);
+ if (gpo_regulator)
+ regulator_disable(gpo_regulator);
+ }
+
+ sensor->on = on;
+
+ return 0;
+}
+
+/*!
+ * ov5640_g_parm - V4L2 sensor interface handler for VIDIOC_G_PARM ioctl
+ * @s: pointer to standard V4L2 sub device structure
+ * @a: pointer to standard V4L2 VIDIOC_G_PARM ioctl structure
+ *
+ * Returns the sensor's video CAPTURE parameters.
+ */
+static int ov5640_g_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *a)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct ov5640 *sensor = to_ov5640(client);
+ struct device *dev = &sensor->i2c_client->dev;
+ struct v4l2_captureparm *cparm = &a->parm.capture;
+ int ret = 0;
+
+ switch (a->type) {
+ /* This is the only case currently handled. */
+ case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+ memset(a, 0, sizeof(*a));
+ a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ cparm->capability = sensor->streamcap.capability;
+ cparm->timeperframe = sensor->streamcap.timeperframe;
+ cparm->capturemode = sensor->streamcap.capturemode;
+ ret = 0;
+ break;
+
+ /* These are all the possible cases. */
+ case V4L2_BUF_TYPE_VIDEO_OUTPUT:
+ case V4L2_BUF_TYPE_VIDEO_OVERLAY:
+ case V4L2_BUF_TYPE_VBI_CAPTURE:
+ case V4L2_BUF_TYPE_VBI_OUTPUT:
+ case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
+ case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
+ ret = -EINVAL;
+ break;
+
+ default:
+ dev_warn(dev, "Type is unknown - %d\n", a->type);
+ ret = -EINVAL;
+ break;
+ }
+
+ return ret;
+}
+
+/*!
+ * ov5460_s_parm - V4L2 sensor interface handler for VIDIOC_S_PARM ioctl
+ * @s: pointer to standard V4L2 sub device structure
+ * @a: pointer to standard V4L2 VIDIOC_S_PARM ioctl structure
+ *
+ * Configures the sensor to use the input parameters, if possible. If
+ * not possible, reverts to the old parameters and returns the
+ * appropriate error code.
+ */
+static int ov5640_s_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *a)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct ov5640 *sensor = to_ov5640(client);
+ struct device *dev = &sensor->i2c_client->dev;
+ struct v4l2_fract *timeperframe = &a->parm.capture.timeperframe;
+ u32 tgt_fps; /* target frames per secound */
+ enum ov5640_frame_rate frame_rate;
+ enum ov5640_mode orig_mode;
+ int ret = 0;
+
+ switch (a->type) {
+ /* This is the only case currently handled. */
+ case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+ /* Check that the new frame rate is allowed. */
+ if ((timeperframe->numerator == 0) ||
+ (timeperframe->denominator == 0)) {
+ timeperframe->denominator = DEFAULT_FPS;
+ timeperframe->numerator = 1;
+ }
+
+ tgt_fps = timeperframe->denominator /
+ timeperframe->numerator;
+
+ if (tgt_fps > MAX_FPS) {
+ timeperframe->denominator = MAX_FPS;
+ timeperframe->numerator = 1;
+ } else if (tgt_fps < MIN_FPS) {
+ timeperframe->denominator = MIN_FPS;
+ timeperframe->numerator = 1;
+ }
+
+ /* Actual frame rate we use */
+ tgt_fps = timeperframe->denominator /
+ timeperframe->numerator;
+
+ if (tgt_fps == 15)
+ frame_rate = ov5640_15_fps;
+ else if (tgt_fps == 30)
+ frame_rate = ov5640_30_fps;
+ else {
+ dev_warn(dev,
+ "The camera frame rate is not supported!\n");
+ return -EINVAL;
+ }
+
+ orig_mode = sensor->streamcap.capturemode;
+ ret = ov5640_init_mode(sensor, frame_rate,
+ (u32)a->parm.capture.capturemode, orig_mode);
+ if (ret < 0)
+ return ret;
+
+ sensor->streamcap.timeperframe = *timeperframe;
+ sensor->streamcap.capturemode =
+ (u32)a->parm.capture.capturemode;
+
+ break;
+
+ /* These are all the possible cases. */
+ case V4L2_BUF_TYPE_VIDEO_OUTPUT:
+ case V4L2_BUF_TYPE_VIDEO_OVERLAY:
+ case V4L2_BUF_TYPE_VBI_CAPTURE:
+ case V4L2_BUF_TYPE_VBI_OUTPUT:
+ case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
+ case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
+ dev_warn(dev, "Type is not V4L2_BUF_TYPE_VIDEO_CAPTURE but %d\n",
+ a->type);
+ ret = -EINVAL;
+ break;
+
+ default:
+ dev_warn(dev, "Type is unknown - %d\n", a->type);
+ ret = -EINVAL;
+ break;
+ }
+
+ return ret;
+}
+
+static int ov5640_set_fmt(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_format *format)
+{
+ struct v4l2_mbus_framefmt *mf = &format->format;
+ const struct ov5640_datafmt *fmt = ov5640_find_datafmt(mf->code);
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct ov5640 *sensor = to_ov5640(client);
+ int capturemode;
+
+ if (!fmt) {
+ mf->code = ov5640_colour_fmts[0].code;
+ mf->colorspace = ov5640_colour_fmts[0].colorspace;
+ }
+
+ mf->field = V4L2_FIELD_NONE;
+
+ if (format->which == V4L2_SUBDEV_FORMAT_TRY)
+ return 0;
+
+ sensor->fmt = fmt;
+
+ capturemode = get_capturemode(mf->width, mf->height);
+ if (capturemode >= 0) {
+ sensor->streamcap.capturemode = capturemode;
+ sensor->pix.width = mf->width;
+ sensor->pix.height = mf->height;
+ return 0;
+ }
+
+ dev_err(&client->dev, "Set format failed %d, %d\n",
+ fmt->code, fmt->colorspace);
+ return -EINVAL;
+}
+
+
+static int ov5640_get_fmt(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_format *format)
+{
+ struct v4l2_mbus_framefmt *mf = &format->format;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct ov5640 *sensor = to_ov5640(client);
+ const struct ov5640_datafmt *fmt = sensor->fmt;
+
+ if (format->pad)
+ return -EINVAL;
+
+ mf->code = fmt->code;
+ mf->colorspace = fmt->colorspace;
+ mf->field = V4L2_FIELD_NONE;
+
+ mf->width = sensor->pix.width;
+ mf->height = sensor->pix.height;
+
+ return 0;
+}
+
+static int ov5640_enum_mbus_code(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_mbus_code_enum *code)
+{
+ if (code->pad || code->index >= ARRAY_SIZE(ov5640_colour_fmts))
+ return -EINVAL;
+
+ code->code = ov5640_colour_fmts[code->index].code;
+ return 0;
+}
+
+/*!
+ * ov5640_enum_framesizes - V4L2 sensor interface handler for
+ * VIDIOC_ENUM_FRAMESIZES ioctl
+ * @s: pointer to standard V4L2 device structure
+ * @fsize: standard V4L2 VIDIOC_ENUM_FRAMESIZES ioctl structure
+ *
+ * Return 0 if successful, otherwise -EINVAL.
+ */
+static int ov5640_enum_framesizes(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_frame_size_enum *fse)
+{
+ if (fse->index > ov5640_mode_MAX)
+ return -EINVAL;
+
+ fse->max_width =
+ max(ov5640_mode_info_data[0][fse->index].width,
+ ov5640_mode_info_data[1][fse->index].width);
+ fse->min_width = fse->max_width;
+ fse->max_height =
+ max(ov5640_mode_info_data[0][fse->index].height,
+ ov5640_mode_info_data[1][fse->index].height);
+ fse->min_height = fse->max_height;
+ return 0;
+}
+
+/*!
+ * ov5640_enum_frameintervals - V4L2 sensor interface handler for
+ * VIDIOC_ENUM_FRAMEINTERVALS ioctl
+ * @s: pointer to standard V4L2 device structure
+ * @fival: standard V4L2 VIDIOC_ENUM_FRAMEINTERVALS ioctl structure
+ *
+ * Return 0 if successful, otherwise -EINVAL.
+ */
+static int ov5640_enum_frameintervals(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_frame_interval_enum *fie)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct device *dev = &client->dev;
+ int i, j, count = 0;
+
+ if (fie->index < 0 || fie->index > ov5640_mode_MAX)
+ return -EINVAL;
+
+ if (fie->width == 0 || fie->height == 0 ||
+ fie->code == 0) {
+ dev_warn(dev, "Please assign pixel format, width and height\n");
+ return -EINVAL;
+ }
+
+ fie->interval.numerator = 1;
+
+ count = 0;
+ for (i = 0; i < ARRAY_SIZE(ov5640_mode_info_data); i++) {
+ for (j = 0; j < (ov5640_mode_MAX + 1); j++) {
+ if (fie->width == ov5640_mode_info_data[i][j].width
+ && fie->height == ov5640_mode_info_data[i][j].height
+ && ov5640_mode_info_data[i][j].init_data_ptr != NULL) {
+ count++;
+ }
+ if (fie->index == (count - 1)) {
+ fie->interval.denominator =
+ ov5640_framerates[i];
+ return 0;
+ }
+ }
+ }
+
+ return -EINVAL;
+}
+
+/*!
+ * dev_init - V4L2 sensor init
+ * @s: pointer to standard V4L2 device structure
+ *
+ */
+static int init_device(struct ov5640 *sensor)
+{
+ struct device *dev = &sensor->i2c_client->dev;
+ u32 tgt_xclk; /* target xclk */
+ u32 tgt_fps; /* target frames per secound */
+ enum ov5640_frame_rate frame_rate;
+ int ret;
+
+ sensor->on = true;
+
+ /* mclk */
+ tgt_xclk = sensor->mclk;
+ tgt_xclk = min(tgt_xclk, (u32)OV5640_XCLK_MAX);
+ tgt_xclk = max(tgt_xclk, (u32)OV5640_XCLK_MIN);
+ sensor->mclk = tgt_xclk;
+
+ dev_dbg(dev, "Setting mclk to %d MHz\n", tgt_xclk / 1000000);
+
+ /* Default camera frame rate is set in probe */
+ tgt_fps = sensor->streamcap.timeperframe.denominator /
+ sensor->streamcap.timeperframe.numerator;
+
+ if (tgt_fps == 15)
+ frame_rate = ov5640_15_fps;
+ else if (tgt_fps == 30)
+ frame_rate = ov5640_30_fps;
+ else
+ return -EINVAL; /* Only support 15fps or 30fps now. */
+
+ ret = ov5640_init_mode(sensor, frame_rate, ov5640_mode_INIT,
+ ov5640_mode_INIT);
+
+ return ret;
+}
+
+static int ov5640_s_stream(struct v4l2_subdev *sd, int enable)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct ov5640 *sensor = to_ov5640(client);
+ struct device *dev = &sensor->i2c_client->dev;
+
+ dev_info(dev, "s_stream: %d\n", enable);
+ if (enable)
+ OV5640_stream_on(sensor);
+ else
+ OV5640_stream_off(sensor);
+ return 0;
+}
+
+static struct v4l2_subdev_video_ops ov5640_subdev_video_ops = {
+ .g_parm = ov5640_g_parm,
+ .s_parm = ov5640_s_parm,
+ .s_stream = ov5640_s_stream,
+};
+
+static const struct v4l2_subdev_pad_ops ov5640_subdev_pad_ops = {
+ .enum_frame_size = ov5640_enum_framesizes,
+ .enum_frame_interval = ov5640_enum_frameintervals,
+ .enum_mbus_code = ov5640_enum_mbus_code,
+ .set_fmt = ov5640_set_fmt,
+ .get_fmt = ov5640_get_fmt,
+};
+
+static struct v4l2_subdev_core_ops ov5640_subdev_core_ops = {
+ .s_power = ov5640_s_power,
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+ .g_register = ov5640_get_register,
+ .s_register = ov5640_set_register,
+#endif
+};
+
+static struct v4l2_subdev_ops ov5640_subdev_ops = {
+ .core = &ov5640_subdev_core_ops,
+ .video = &ov5640_subdev_video_ops,
+ .pad = &ov5640_subdev_pad_ops,
+};
+
+static void ov5640_adjust_setting_20mhz(void)
+{
+ struct reg_value *regsetting;
+ int i, array_size;
+
+ /* adjust for INIT mode */
+ regsetting = ov5640_init_setting_30fps_VGA;
+ array_size = ARRAY_SIZE(ov5640_init_setting_30fps_VGA);
+
+ for (i = 0; i < array_size; i++, regsetting++)
+ if (regsetting->u16RegAddr == 0x3037)
+ regsetting->u8Val = 0x17;
+}
+
+/*!
+ * ov5640 I2C probe function
+ *
+ * @param adapter struct i2c_adapter *
+ * @return Error code indicating success or failure
+ */
+static int ov5640_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct pinctrl *pinctrl;
+ struct device *dev = &client->dev;
+ int retval;
+ u8 chip_id_high, chip_id_low;
+ struct ov5640 *sensor;
+
+ sensor = devm_kzalloc(dev, sizeof(*sensor), GFP_KERNEL);
+
+ /* ov5640 pinctrl */
+ pinctrl = devm_pinctrl_get_select_default(dev);
+ if (IS_ERR(pinctrl))
+ dev_warn(dev, "No pin available\n");
+
+ /* request power down pin */
+ sensor->pwn_gpio = of_get_named_gpio(dev->of_node, "pwn-gpios", 0);
+ if (!gpio_is_valid(sensor->pwn_gpio))
+ dev_warn(dev, "No sensor pwdn pin available");
+ else {
+ retval = devm_gpio_request_one(dev, sensor->pwn_gpio,
+ GPIOF_OUT_INIT_HIGH, "ov5640_mipi_pwdn");
+ if (retval < 0) {
+ dev_warn(dev, "Failed to set power pin\n");
+ dev_warn(dev, "retval=%d\n", retval);
+ return retval;
+ }
+ }
+
+ /* request reset pin */
+ sensor->rst_gpio = of_get_named_gpio(dev->of_node, "rst-gpios", 0);
+ if (!gpio_is_valid(sensor->rst_gpio))
+ dev_warn(dev, "No sensor reset pin available");
+ else {
+ retval = devm_gpio_request_one(dev, sensor->rst_gpio,
+ GPIOF_OUT_INIT_HIGH, "ov5640_mipi_reset");
+ if (retval < 0) {
+ dev_warn(dev, "Failed to set reset pin\n");
+ return retval;
+ }
+ }
+
+
+ sensor->sensor_clk = devm_clk_get(dev, "csi_mclk");
+ if (IS_ERR(sensor->sensor_clk)) {
+ /* assuming clock enabled by default */
+ sensor->sensor_clk = NULL;
+ dev_err(dev, "clock-frequency missing or invalid\n");
+ return PTR_ERR(sensor->sensor_clk);
+ }
+
+ retval = of_property_read_u32(dev->of_node, "mclk",
+ &(sensor->mclk));
+ if (retval) {
+ dev_err(dev, "mclk missing or invalid\n");
+ return retval;
+ }
+
+ if (sensor->mclk == OV5640_XCLK_20MHZ)
+ ov5640_adjust_setting_20mhz();
+
+ retval = of_property_read_u32(dev->of_node, "mclk_source",
+ (u32 *) &(sensor->mclk_source));
+ if (retval) {
+ dev_err(dev, "mclk_source missing or invalid\n");
+ return retval;
+ }
+
+ retval = of_property_read_u32(dev->of_node, "csi_id",
+ &(sensor->csi));
+ if (retval) {
+ dev_err(dev, "csi id missing or invalid\n");
+ return retval;
+ }
+
+ clk_prepare_enable(sensor->sensor_clk);
+
+ sensor->io_init = ov5640_reset;
+ sensor->i2c_client = client;
+ sensor->pix.pixelformat = V4L2_PIX_FMT_YUYV;
+ sensor->pix.width = 640;
+ sensor->pix.height = 480;
+ sensor->streamcap.capability = V4L2_MODE_HIGHQUALITY |
+ V4L2_CAP_TIMEPERFRAME;
+ sensor->streamcap.capturemode = 0;
+ sensor->streamcap.timeperframe.denominator = DEFAULT_FPS;
+ sensor->streamcap.timeperframe.numerator = 1;
+
+ ov5640_regulator_enable(&client->dev);
+
+ mutex_lock(&ov5640_mutex);
+ {
+ ov5640_reset(sensor);
+ ov5640_power_down(sensor, 0);
+ retval = ov5640_update_slave_id(sensor);
+ }
+ mutex_unlock(&ov5640_mutex);
+ if (retval < 0) {
+ clk_disable_unprepare(sensor->sensor_clk);
+ return -ENODEV;
+ }
+
+ retval = ov5640_read_reg(sensor, OV5640_CHIP_ID_HIGH_BYTE,
+ &chip_id_high);
+ if (retval < 0 || chip_id_high != 0x56) {
+ dev_warn(dev, "Camera is not found\n");
+ clk_disable_unprepare(sensor->sensor_clk);
+ return -ENODEV;
+ }
+ retval = ov5640_read_reg(sensor, OV5640_CHIP_ID_LOW_BYTE, &chip_id_low);
+ if (retval < 0 || chip_id_low != 0x40) {
+ dev_warn(dev, "Camera is not found\n");
+ clk_disable_unprepare(sensor->sensor_clk);
+ return -ENODEV;
+ }
+
+
+ retval = init_device(sensor);
+ if (retval < 0) {
+ clk_disable_unprepare(sensor->sensor_clk);
+ dev_warn(dev, "Camera init failed\n");
+ ov5640_power_down(sensor, 1);
+ return retval;
+ }
+
+ v4l2_i2c_subdev_init(&sensor->subdev, client, &ov5640_subdev_ops);
+
+ sensor->subdev.grp_id = 678;
+ retval = v4l2_async_register_subdev(&sensor->subdev);
+ if (retval < 0)
+ dev_err(&client->dev, "Async register failed, ret=%d\n",
+ retval);
+
+ OV5640_stream_off(sensor);
+ dev_info(dev, "Camera is found\n");
+ return retval;
+}
+
+/*!
+ * ov5640 I2C detach function
+ *
+ * @param client struct i2c_client *
+ * @return Error code indicating success or failure
+ */
+static int ov5640_remove(struct i2c_client *client)
+{
+ struct v4l2_subdev *sd = i2c_get_clientdata(client);
+ struct ov5640 *sensor = to_ov5640(client);
+
+ v4l2_async_unregister_subdev(sd);
+
+ clk_disable_unprepare(sensor->sensor_clk);
+
+ ov5640_power_down(sensor, 1);
+
+ if (gpo_regulator)
+ regulator_disable(gpo_regulator);
+
+ if (analog_regulator)
+ regulator_disable(analog_regulator);
+
+ if (core_regulator)
+ regulator_disable(core_regulator);
+
+ if (io_regulator)
+ regulator_disable(io_regulator);
+
+ return 0;
+}
+
+module_i2c_driver(ov5640_i2c_driver);
+
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("OV5640 MIPI Camera Driver");
+MODULE_LICENSE("GPL");
+MODULE_VERSION("1.0");
+MODULE_ALIAS("CSI");
diff --git a/drivers/media/platform/mxc/capture/ov5640_v2.c b/drivers/media/platform/mxc/capture/ov5640_v2.c
new file mode 100644
index 000000000000..70e2a8321fd0
--- /dev/null
+++ b/drivers/media/platform/mxc/capture/ov5640_v2.c
@@ -0,0 +1,1895 @@
+/*
+ * Copyright (C) 2012-2015 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/i2c.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/of_gpio.h>
+#include <linux/pinctrl/consumer.h>
+#include <linux/regulator/consumer.h>
+#include <linux/v4l2-mediabus.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-ctrls.h>
+
+#define OV5640_VOLTAGE_ANALOG 2800000
+#define OV5640_VOLTAGE_DIGITAL_CORE 1500000
+#define OV5640_VOLTAGE_DIGITAL_IO 1800000
+
+#define MIN_FPS 15
+#define MAX_FPS 30
+#define DEFAULT_FPS 30
+
+#define OV5640_XCLK_MIN 6000000
+#define OV5640_XCLK_MAX 24000000
+
+#define OV5640_CHIP_ID_HIGH_BYTE 0x300A
+#define OV5640_CHIP_ID_LOW_BYTE 0x300B
+
+enum ov5640_mode {
+ ov5640_mode_MIN = 0,
+ ov5640_mode_VGA_640_480 = 0,
+ ov5640_mode_QVGA_320_240 = 1,
+ ov5640_mode_NTSC_720_480 = 2,
+ ov5640_mode_PAL_720_576 = 3,
+ ov5640_mode_720P_1280_720 = 4,
+ ov5640_mode_1080P_1920_1080 = 5,
+ ov5640_mode_QSXGA_2592_1944 = 6,
+ ov5640_mode_QCIF_176_144 = 7,
+ ov5640_mode_XGA_1024_768 = 8,
+ ov5640_mode_MAX = 8
+};
+
+enum ov5640_frame_rate {
+ ov5640_15_fps,
+ ov5640_30_fps
+};
+
+static int ov5640_framerates[] = {
+ [ov5640_15_fps] = 15,
+ [ov5640_30_fps] = 30,
+};
+
+struct ov5640_datafmt {
+ u32 code;
+ enum v4l2_colorspace colorspace;
+};
+
+struct reg_value {
+ u16 u16RegAddr;
+ u8 u8Val;
+ u8 u8Mask;
+ u32 u32Delay_ms;
+};
+
+struct ov5640_mode_info {
+ enum ov5640_mode mode;
+ u32 width;
+ u32 height;
+ struct reg_value *init_data_ptr;
+ u32 init_data_size;
+};
+
+struct ov5640 {
+ struct v4l2_subdev subdev;
+ struct i2c_client *i2c_client;
+ struct v4l2_pix_format pix;
+ const struct ov5640_datafmt *fmt;
+ struct v4l2_captureparm streamcap;
+ bool on;
+
+ /* control settings */
+ int brightness;
+ int hue;
+ int contrast;
+ int saturation;
+ int red;
+ int green;
+ int blue;
+ int ae_mode;
+
+ u32 mclk;
+ u8 mclk_source;
+ struct clk *sensor_clk;
+ int csi;
+
+ void (*io_init)(void);
+};
+
+/*!
+ * Maintains the information on the current state of the sesor.
+ */
+static struct ov5640 ov5640_data;
+static int pwn_gpio, rst_gpio;
+static int prev_sysclk;
+static int AE_Target = 52, night_mode;
+static int prev_HTS;
+static int AE_high, AE_low;
+
+static struct reg_value ov5640_global_init_setting[] = {
+ {0x3008, 0x42, 0, 0},
+ {0x3103, 0x03, 0, 0}, {0x3017, 0xff, 0, 0}, {0x3018, 0xff, 0, 0},
+ {0x3034, 0x1a, 0, 0}, {0x3037, 0x13, 0, 0}, {0x3108, 0x01, 0, 0},
+ {0x3630, 0x36, 0, 0}, {0x3631, 0x0e, 0, 0}, {0x3632, 0xe2, 0, 0},
+ {0x3633, 0x12, 0, 0}, {0x3621, 0xe0, 0, 0}, {0x3704, 0xa0, 0, 0},
+ {0x3703, 0x5a, 0, 0}, {0x3715, 0x78, 0, 0}, {0x3717, 0x01, 0, 0},
+ {0x370b, 0x60, 0, 0}, {0x3705, 0x1a, 0, 0}, {0x3905, 0x02, 0, 0},
+ {0x3906, 0x10, 0, 0}, {0x3901, 0x0a, 0, 0}, {0x3731, 0x12, 0, 0},
+ {0x3600, 0x08, 0, 0}, {0x3601, 0x33, 0, 0}, {0x302d, 0x60, 0, 0},
+ {0x3620, 0x52, 0, 0}, {0x371b, 0x20, 0, 0}, {0x471c, 0x50, 0, 0},
+ {0x3a13, 0x43, 0, 0}, {0x3a18, 0x00, 0, 0}, {0x3a19, 0x7c, 0, 0},
+ {0x3635, 0x13, 0, 0}, {0x3636, 0x03, 0, 0}, {0x3634, 0x40, 0, 0},
+ {0x3622, 0x01, 0, 0}, {0x3c01, 0x34, 0, 0}, {0x3c04, 0x28, 0, 0},
+ {0x3c05, 0x98, 0, 0}, {0x3c06, 0x00, 0, 0}, {0x3c07, 0x07, 0, 0},
+ {0x3c08, 0x00, 0, 0}, {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0},
+ {0x3c0b, 0x40, 0, 0}, {0x3810, 0x00, 0, 0}, {0x3811, 0x10, 0, 0},
+ {0x3812, 0x00, 0, 0}, {0x3708, 0x64, 0, 0}, {0x4001, 0x02, 0, 0},
+ {0x4005, 0x1a, 0, 0}, {0x3000, 0x00, 0, 0}, {0x3004, 0xff, 0, 0},
+ {0x300e, 0x58, 0, 0}, {0x302e, 0x00, 0, 0}, {0x4300, 0x30, 0, 0},
+ {0x501f, 0x00, 0, 0}, {0x440e, 0x00, 0, 0}, {0x5000, 0xa7, 0, 0},
+ {0x3008, 0x02, 0, 0},
+};
+
+static struct reg_value ov5640_init_setting_30fps_VGA[] = {
+ {0x3008, 0x42, 0, 0},
+ {0x3103, 0x03, 0, 0}, {0x3017, 0xff, 0, 0}, {0x3018, 0xff, 0, 0},
+ {0x3034, 0x1a, 0, 0}, {0x3035, 0x11, 0, 0}, {0x3036, 0x46, 0, 0},
+ {0x3037, 0x13, 0, 0}, {0x3108, 0x01, 0, 0}, {0x3630, 0x36, 0, 0},
+ {0x3631, 0x0e, 0, 0}, {0x3632, 0xe2, 0, 0}, {0x3633, 0x12, 0, 0},
+ {0x3621, 0xe0, 0, 0}, {0x3704, 0xa0, 0, 0}, {0x3703, 0x5a, 0, 0},
+ {0x3715, 0x78, 0, 0}, {0x3717, 0x01, 0, 0}, {0x370b, 0x60, 0, 0},
+ {0x3705, 0x1a, 0, 0}, {0x3905, 0x02, 0, 0}, {0x3906, 0x10, 0, 0},
+ {0x3901, 0x0a, 0, 0}, {0x3731, 0x12, 0, 0}, {0x3600, 0x08, 0, 0},
+ {0x3601, 0x33, 0, 0}, {0x302d, 0x60, 0, 0}, {0x3620, 0x52, 0, 0},
+ {0x371b, 0x20, 0, 0}, {0x471c, 0x50, 0, 0}, {0x3a13, 0x43, 0, 0},
+ {0x3a18, 0x00, 0, 0}, {0x3a19, 0xf8, 0, 0}, {0x3635, 0x13, 0, 0},
+ {0x3636, 0x03, 0, 0}, {0x3634, 0x40, 0, 0}, {0x3622, 0x01, 0, 0},
+ {0x3c01, 0x34, 0, 0}, {0x3c04, 0x28, 0, 0}, {0x3c05, 0x98, 0, 0},
+ {0x3c06, 0x00, 0, 0}, {0x3c07, 0x08, 0, 0}, {0x3c08, 0x00, 0, 0},
+ {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
+ {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0},
+ {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
+ {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0}, {0x3804, 0x0a, 0, 0},
+ {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9b, 0, 0},
+ {0x3808, 0x02, 0, 0}, {0x3809, 0x80, 0, 0}, {0x380a, 0x01, 0, 0},
+ {0x380b, 0xe0, 0, 0}, {0x380c, 0x07, 0, 0}, {0x380d, 0x68, 0, 0},
+ {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0}, {0x3810, 0x00, 0, 0},
+ {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x06, 0, 0},
+ {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0},
+ {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x03, 0, 0},
+ {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0},
+ {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0},
+ {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0},
+ {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x3000, 0x00, 0, 0},
+ {0x3002, 0x1c, 0, 0}, {0x3004, 0xff, 0, 0}, {0x3006, 0xc3, 0, 0},
+ {0x300e, 0x58, 0, 0}, {0x302e, 0x00, 0, 0}, {0x4300, 0x30, 0, 0},
+ {0x501f, 0x00, 0, 0}, {0x4713, 0x03, 0, 0}, {0x4407, 0x04, 0, 0},
+ {0x440e, 0x00, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0},
+ {0x4837, 0x22, 0, 0}, {0x3824, 0x02, 0, 0}, {0x5000, 0xa7, 0, 0},
+ {0x5001, 0xa3, 0, 0}, {0x5180, 0xff, 0, 0}, {0x5181, 0xf2, 0, 0},
+ {0x5182, 0x00, 0, 0}, {0x5183, 0x14, 0, 0}, {0x5184, 0x25, 0, 0},
+ {0x5185, 0x24, 0, 0}, {0x5186, 0x09, 0, 0}, {0x5187, 0x09, 0, 0},
+ {0x5188, 0x09, 0, 0}, {0x5189, 0x88, 0, 0}, {0x518a, 0x54, 0, 0},
+ {0x518b, 0xee, 0, 0}, {0x518c, 0xb2, 0, 0}, {0x518d, 0x50, 0, 0},
+ {0x518e, 0x34, 0, 0}, {0x518f, 0x6b, 0, 0}, {0x5190, 0x46, 0, 0},
+ {0x5191, 0xf8, 0, 0}, {0x5192, 0x04, 0, 0}, {0x5193, 0x70, 0, 0},
+ {0x5194, 0xf0, 0, 0}, {0x5195, 0xf0, 0, 0}, {0x5196, 0x03, 0, 0},
+ {0x5197, 0x01, 0, 0}, {0x5198, 0x04, 0, 0}, {0x5199, 0x6c, 0, 0},
+ {0x519a, 0x04, 0, 0}, {0x519b, 0x00, 0, 0}, {0x519c, 0x09, 0, 0},
+ {0x519d, 0x2b, 0, 0}, {0x519e, 0x38, 0, 0}, {0x5381, 0x1e, 0, 0},
+ {0x5382, 0x5b, 0, 0}, {0x5383, 0x08, 0, 0}, {0x5384, 0x0a, 0, 0},
+ {0x5385, 0x7e, 0, 0}, {0x5386, 0x88, 0, 0}, {0x5387, 0x7c, 0, 0},
+ {0x5388, 0x6c, 0, 0}, {0x5389, 0x10, 0, 0}, {0x538a, 0x01, 0, 0},
+ {0x538b, 0x98, 0, 0}, {0x5300, 0x08, 0, 0}, {0x5301, 0x30, 0, 0},
+ {0x5302, 0x10, 0, 0}, {0x5303, 0x00, 0, 0}, {0x5304, 0x08, 0, 0},
+ {0x5305, 0x30, 0, 0}, {0x5306, 0x08, 0, 0}, {0x5307, 0x16, 0, 0},
+ {0x5309, 0x08, 0, 0}, {0x530a, 0x30, 0, 0}, {0x530b, 0x04, 0, 0},
+ {0x530c, 0x06, 0, 0}, {0x5480, 0x01, 0, 0}, {0x5481, 0x08, 0, 0},
+ {0x5482, 0x14, 0, 0}, {0x5483, 0x28, 0, 0}, {0x5484, 0x51, 0, 0},
+ {0x5485, 0x65, 0, 0}, {0x5486, 0x71, 0, 0}, {0x5487, 0x7d, 0, 0},
+ {0x5488, 0x87, 0, 0}, {0x5489, 0x91, 0, 0}, {0x548a, 0x9a, 0, 0},
+ {0x548b, 0xaa, 0, 0}, {0x548c, 0xb8, 0, 0}, {0x548d, 0xcd, 0, 0},
+ {0x548e, 0xdd, 0, 0}, {0x548f, 0xea, 0, 0}, {0x5490, 0x1d, 0, 0},
+ {0x5580, 0x02, 0, 0}, {0x5583, 0x40, 0, 0}, {0x5584, 0x10, 0, 0},
+ {0x5589, 0x10, 0, 0}, {0x558a, 0x00, 0, 0}, {0x558b, 0xf8, 0, 0},
+ {0x5800, 0x23, 0, 0}, {0x5801, 0x14, 0, 0}, {0x5802, 0x0f, 0, 0},
+ {0x5803, 0x0f, 0, 0}, {0x5804, 0x12, 0, 0}, {0x5805, 0x26, 0, 0},
+ {0x5806, 0x0c, 0, 0}, {0x5807, 0x08, 0, 0}, {0x5808, 0x05, 0, 0},
+ {0x5809, 0x05, 0, 0}, {0x580a, 0x08, 0, 0}, {0x580b, 0x0d, 0, 0},
+ {0x580c, 0x08, 0, 0}, {0x580d, 0x03, 0, 0}, {0x580e, 0x00, 0, 0},
+ {0x580f, 0x00, 0, 0}, {0x5810, 0x03, 0, 0}, {0x5811, 0x09, 0, 0},
+ {0x5812, 0x07, 0, 0}, {0x5813, 0x03, 0, 0}, {0x5814, 0x00, 0, 0},
+ {0x5815, 0x01, 0, 0}, {0x5816, 0x03, 0, 0}, {0x5817, 0x08, 0, 0},
+ {0x5818, 0x0d, 0, 0}, {0x5819, 0x08, 0, 0}, {0x581a, 0x05, 0, 0},
+ {0x581b, 0x06, 0, 0}, {0x581c, 0x08, 0, 0}, {0x581d, 0x0e, 0, 0},
+ {0x581e, 0x29, 0, 0}, {0x581f, 0x17, 0, 0}, {0x5820, 0x11, 0, 0},
+ {0x5821, 0x11, 0, 0}, {0x5822, 0x15, 0, 0}, {0x5823, 0x28, 0, 0},
+ {0x5824, 0x46, 0, 0}, {0x5825, 0x26, 0, 0}, {0x5826, 0x08, 0, 0},
+ {0x5827, 0x26, 0, 0}, {0x5828, 0x64, 0, 0}, {0x5829, 0x26, 0, 0},
+ {0x582a, 0x24, 0, 0}, {0x582b, 0x22, 0, 0}, {0x582c, 0x24, 0, 0},
+ {0x582d, 0x24, 0, 0}, {0x582e, 0x06, 0, 0}, {0x582f, 0x22, 0, 0},
+ {0x5830, 0x40, 0, 0}, {0x5831, 0x42, 0, 0}, {0x5832, 0x24, 0, 0},
+ {0x5833, 0x26, 0, 0}, {0x5834, 0x24, 0, 0}, {0x5835, 0x22, 0, 0},
+ {0x5836, 0x22, 0, 0}, {0x5837, 0x26, 0, 0}, {0x5838, 0x44, 0, 0},
+ {0x5839, 0x24, 0, 0}, {0x583a, 0x26, 0, 0}, {0x583b, 0x28, 0, 0},
+ {0x583c, 0x42, 0, 0}, {0x583d, 0xce, 0, 0}, {0x5025, 0x00, 0, 0},
+ {0x3a0f, 0x30, 0, 0}, {0x3a10, 0x28, 0, 0}, {0x3a1b, 0x30, 0, 0},
+ {0x3a1e, 0x26, 0, 0}, {0x3a11, 0x60, 0, 0}, {0x3a1f, 0x14, 0, 0},
+ {0x3008, 0x02, 0, 0}, {0x3034, 0x1a, 0, 0}, {0x3035, 0x11, 0, 0},
+ {0x3036, 0x46, 0, 0}, {0x3037, 0x13, 0, 0},
+};
+
+static struct reg_value ov5640_setting_30fps_VGA_640_480[] = {
+ {0x3c07, 0x08, 0, 0}, {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0},
+ {0x3814, 0x31, 0, 0}, {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0},
+ {0x3801, 0x00, 0, 0}, {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0},
+ {0x3804, 0x0a, 0, 0}, {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0},
+ {0x3807, 0x9b, 0, 0}, {0x3808, 0x02, 0, 0}, {0x3809, 0x80, 0, 0},
+ {0x380a, 0x01, 0, 0}, {0x380b, 0xe0, 0, 0}, {0x380c, 0x07, 0, 0},
+ {0x380d, 0x68, 0, 0}, {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0},
+ {0x3813, 0x06, 0, 0}, {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0},
+ {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x0b, 0, 0},
+ {0x3a03, 0x88, 0, 0}, {0x3a14, 0x0b, 0, 0}, {0x3a15, 0x88, 0, 0},
+ {0x4004, 0x02, 0, 0}, {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0},
+ {0x4713, 0x03, 0, 0}, {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0},
+ {0x460c, 0x22, 0, 0}, {0x4837, 0x22, 0, 0}, {0x3824, 0x02, 0, 0},
+ {0x5001, 0xa3, 0, 0}, {0x3034, 0x1a, 0, 0}, {0x3035, 0x11, 0, 0},
+ {0x3036, 0x46, 0, 0}, {0x3037, 0x13, 0, 0}, {0x3503, 0x00, 0, 0},
+};
+
+static struct reg_value ov5640_setting_15fps_VGA_640_480[] = {
+ {0x3c07, 0x08, 0, 0}, {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0},
+ {0x3814, 0x31, 0, 0}, {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0},
+ {0x3801, 0x00, 0, 0}, {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0},
+ {0x3804, 0x0a, 0, 0}, {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0},
+ {0x3807, 0x9b, 0, 0}, {0x3808, 0x02, 0, 0}, {0x3809, 0x80, 0, 0},
+ {0x380a, 0x01, 0, 0}, {0x380b, 0xe0, 0, 0}, {0x380c, 0x07, 0, 0},
+ {0x380d, 0x68, 0, 0}, {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0},
+ {0x3813, 0x06, 0, 0}, {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0},
+ {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x0b, 0, 0},
+ {0x3a03, 0x88, 0, 0}, {0x3a14, 0x0b, 0, 0}, {0x3a15, 0x88, 0, 0},
+ {0x4004, 0x02, 0, 0}, {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0},
+ {0x4713, 0x03, 0, 0}, {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0},
+ {0x460c, 0x22, 0, 0}, {0x4837, 0x22, 0, 0}, {0x3824, 0x02, 0, 0},
+ {0x5001, 0xa3, 0, 0}, {0x3034, 0x1a, 0, 0}, {0x3035, 0x21, 0, 0},
+ {0x3036, 0x46, 0, 0}, {0x3037, 0x13, 0, 0}, {0x3503, 0x00, 0, 0},
+};
+
+static struct reg_value ov5640_setting_30fps_QVGA_320_240[] = {
+ {0x3c07, 0x08, 0, 0}, {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0},
+ {0x3814, 0x31, 0, 0}, {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0},
+ {0x3801, 0x00, 0, 0}, {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0},
+ {0x3804, 0x0a, 0, 0}, {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0},
+ {0x3807, 0x9b, 0, 0}, {0x3808, 0x01, 0, 0}, {0x3809, 0x40, 0, 0},
+ {0x380a, 0x00, 0, 0}, {0x380b, 0xf0, 0, 0}, {0x380c, 0x07, 0, 0},
+ {0x380d, 0x68, 0, 0}, {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0},
+ {0x3813, 0x06, 0, 0}, {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0},
+ {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x0b, 0, 0},
+ {0x3a03, 0x88, 0, 0}, {0x3a14, 0x0b, 0, 0}, {0x3a15, 0x88, 0, 0},
+ {0x4004, 0x02, 0, 0}, {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0},
+ {0x4713, 0x03, 0, 0}, {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0},
+ {0x460c, 0x22, 0, 0}, {0x4837, 0x22, 0, 0}, {0x3824, 0x02, 0, 0},
+ {0x5001, 0xa3, 0, 0}, {0x3034, 0x1a, 0, 0}, {0x3035, 0x11, 0, 0},
+ {0x3036, 0x46, 0, 0}, {0x3037, 0x13, 0, 0},
+};
+
+static struct reg_value ov5640_setting_15fps_QVGA_320_240[] = {
+ {0x3c07, 0x08, 0, 0}, {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0},
+ {0x3814, 0x31, 0, 0}, {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0},
+ {0x3801, 0x00, 0, 0}, {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0},
+ {0x3804, 0x0a, 0, 0}, {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0},
+ {0x3807, 0x9b, 0, 0}, {0x3808, 0x01, 0, 0}, {0x3809, 0x40, 0, 0},
+ {0x380a, 0x00, 0, 0}, {0x380b, 0xf0, 0, 0}, {0x380c, 0x07, 0, 0},
+ {0x380d, 0x68, 0, 0}, {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0},
+ {0x3813, 0x06, 0, 0}, {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0},
+ {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x0b, 0, 0},
+ {0x3a03, 0x88, 0, 0}, {0x3a14, 0x0b, 0, 0}, {0x3a15, 0x88, 0, 0},
+ {0x4004, 0x02, 0, 0}, {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0},
+ {0x4713, 0x03, 0, 0}, {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0},
+ {0x460c, 0x22, 0, 0}, {0x4837, 0x22, 0, 0}, {0x3824, 0x02, 0, 0},
+ {0x5001, 0xa3, 0, 0}, {0x3034, 0x1a, 0, 0}, {0x3035, 0x21, 0, 0},
+ {0x3036, 0x46, 0, 0}, {0x3037, 0x13, 0, 0},
+};
+
+static struct reg_value ov5640_setting_30fps_NTSC_720_480[] = {
+ {0x3c07, 0x08, 0, 0}, {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0},
+ {0x3814, 0x31, 0, 0}, {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0},
+ {0x3801, 0x00, 0, 0}, {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0},
+ {0x3804, 0x0a, 0, 0}, {0x3805, 0x3f, 0, 0}, {0x3806, 0x06, 0, 0},
+ {0x3807, 0xd4, 0, 0}, {0x3808, 0x02, 0, 0}, {0x3809, 0xd0, 0, 0},
+ {0x380a, 0x01, 0, 0}, {0x380b, 0xe0, 0, 0}, {0x380c, 0x07, 0, 0},
+ {0x380d, 0x68, 0, 0}, {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0},
+ {0x3813, 0x06, 0, 0}, {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0},
+ {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x0b, 0, 0},
+ {0x3a03, 0x88, 0, 0}, {0x3a14, 0x0b, 0, 0}, {0x3a15, 0x88, 0, 0},
+ {0x4004, 0x02, 0, 0}, {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0},
+ {0x4713, 0x03, 0, 0}, {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0},
+ {0x460c, 0x22, 0, 0}, {0x4837, 0x22, 0, 0}, {0x3824, 0x02, 0, 0},
+ {0x5001, 0xa3, 0, 0}, {0x3034, 0x1a, 0, 0}, {0x3035, 0x11, 0, 0},
+ {0x3036, 0x46, 0, 0}, {0x3037, 0x13, 0, 0},
+};
+
+static struct reg_value ov5640_setting_15fps_NTSC_720_480[] = {
+ {0x3c07, 0x08, 0, 0}, {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0},
+ {0x3814, 0x31, 0, 0}, {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0},
+ {0x3801, 0x00, 0, 0}, {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0},
+ {0x3804, 0x0a, 0, 0}, {0x3805, 0x3f, 0, 0}, {0x3806, 0x06, 0, 0},
+ {0x3807, 0xd4, 0, 0}, {0x3808, 0x02, 0, 0}, {0x3809, 0xd0, 0, 0},
+ {0x380a, 0x01, 0, 0}, {0x380b, 0xe0, 0, 0}, {0x380c, 0x07, 0, 0},
+ {0x380d, 0x68, 0, 0}, {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0},
+ {0x3813, 0x06, 0, 0}, {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0},
+ {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x0b, 0, 0},
+ {0x3a03, 0x88, 0, 0}, {0x3a14, 0x0b, 0, 0}, {0x3a15, 0x88, 0, 0},
+ {0x4004, 0x02, 0, 0}, {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0},
+ {0x4713, 0x03, 0, 0}, {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0},
+ {0x460c, 0x22, 0, 0}, {0x4837, 0x22, 0, 0}, {0x3824, 0x02, 0, 0},
+ {0x5001, 0xa3, 0, 0}, {0x3034, 0x1a, 0, 0}, {0x3035, 0x21, 0, 0},
+ {0x3036, 0x46, 0, 0}, {0x3037, 0x13, 0, 0},
+};
+
+static struct reg_value ov5640_setting_30fps_PAL_720_576[] = {
+ {0x3c07, 0x08, 0, 0}, {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0},
+ {0x3814, 0x31, 0, 0}, {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0},
+ {0x3801, 0x60, 0, 0}, {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0},
+ {0x3804, 0x09, 0, 0}, {0x3805, 0x7e, 0, 0}, {0x3806, 0x07, 0, 0},
+ {0x3807, 0x9b, 0, 0}, {0x3808, 0x02, 0, 0}, {0x3809, 0xd0, 0, 0},
+ {0x380a, 0x02, 0, 0}, {0x380b, 0x40, 0, 0}, {0x380c, 0x07, 0, 0},
+ {0x380d, 0x68, 0, 0}, {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0},
+ {0x3813, 0x06, 0, 0}, {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0},
+ {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x0b, 0, 0},
+ {0x3a03, 0x88, 0, 0}, {0x3a14, 0x0b, 0, 0}, {0x3a15, 0x88, 0, 0},
+ {0x4004, 0x02, 0, 0}, {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0},
+ {0x4713, 0x03, 0, 0}, {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0},
+ {0x460c, 0x22, 0, 0}, {0x4837, 0x22, 0, 0}, {0x3824, 0x02, 0, 0},
+ {0x5001, 0xa3, 0, 0}, {0x3034, 0x1a, 0, 0}, {0x3035, 0x11, 0, 0},
+ {0x3036, 0x46, 0, 0}, {0x3037, 0x13, 0, 0},
+};
+
+static struct reg_value ov5640_setting_15fps_PAL_720_576[] = {
+ {0x3c07, 0x08, 0, 0}, {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0},
+ {0x3814, 0x31, 0, 0}, {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0},
+ {0x3801, 0x60, 0, 0}, {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0},
+ {0x3804, 0x09, 0, 0}, {0x3805, 0x7e, 0, 0}, {0x3806, 0x07, 0, 0},
+ {0x3807, 0x9b, 0, 0}, {0x3808, 0x02, 0, 0}, {0x3809, 0xd0, 0, 0},
+ {0x380a, 0x02, 0, 0}, {0x380b, 0x40, 0, 0}, {0x380c, 0x07, 0, 0},
+ {0x380d, 0x68, 0, 0}, {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0},
+ {0x3813, 0x06, 0, 0}, {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0},
+ {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x0b, 0, 0},
+ {0x3a03, 0x88, 0, 0}, {0x3a14, 0x0b, 0, 0}, {0x3a15, 0x88, 0, 0},
+ {0x4004, 0x02, 0, 0}, {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0},
+ {0x4713, 0x03, 0, 0}, {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0},
+ {0x460c, 0x22, 0, 0}, {0x4837, 0x22, 0, 0}, {0x3824, 0x02, 0, 0},
+ {0x5001, 0xa3, 0, 0}, {0x3034, 0x1a, 0, 0}, {0x3035, 0x21, 0, 0},
+ {0x3036, 0x46, 0, 0}, {0x3037, 0x13, 0, 0},
+};
+
+static struct reg_value ov5640_setting_30fps_720P_1280_720[] = {
+ {0x3035, 0x21, 0, 0}, {0x3036, 0x69, 0, 0}, {0x3c07, 0x07, 0, 0},
+ {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0},
+ {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
+ {0x3802, 0x00, 0, 0}, {0x3803, 0xfa, 0, 0}, {0x3804, 0x0a, 0, 0},
+ {0x3805, 0x3f, 0, 0}, {0x3806, 0x06, 0, 0}, {0x3807, 0xa9, 0, 0},
+ {0x3808, 0x05, 0, 0}, {0x3809, 0x00, 0, 0}, {0x380a, 0x02, 0, 0},
+ {0x380b, 0xd0, 0, 0}, {0x380c, 0x07, 0, 0}, {0x380d, 0x64, 0, 0},
+ {0x380e, 0x02, 0, 0}, {0x380f, 0xe4, 0, 0}, {0x3813, 0x04, 0, 0},
+ {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3709, 0x52, 0, 0},
+ {0x370c, 0x03, 0, 0}, {0x3a02, 0x02, 0, 0}, {0x3a03, 0xe0, 0, 0},
+ {0x3a14, 0x02, 0, 0}, {0x3a15, 0xe0, 0, 0}, {0x4004, 0x02, 0, 0},
+ {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0}, {0x4713, 0x03, 0, 0},
+ {0x4407, 0x04, 0, 0}, {0x460b, 0x37, 0, 0}, {0x460c, 0x20, 0, 0},
+ {0x4837, 0x16, 0, 0}, {0x3824, 0x04, 0, 0}, {0x5001, 0x83, 0, 0},
+ {0x3503, 0x00, 0, 0},
+};
+
+static struct reg_value ov5640_setting_15fps_720P_1280_720[] = {
+ {0x3035, 0x41, 0, 0}, {0x3036, 0x69, 0, 0}, {0x3c07, 0x07, 0, 0},
+ {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0},
+ {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
+ {0x3802, 0x00, 0, 0}, {0x3803, 0xfa, 0, 0}, {0x3804, 0x0a, 0, 0},
+ {0x3805, 0x3f, 0, 0}, {0x3806, 0x06, 0, 0}, {0x3807, 0xa9, 0, 0},
+ {0x3808, 0x05, 0, 0}, {0x3809, 0x00, 0, 0}, {0x380a, 0x02, 0, 0},
+ {0x380b, 0xd0, 0, 0}, {0x380c, 0x07, 0, 0}, {0x380d, 0x64, 0, 0},
+ {0x380e, 0x02, 0, 0}, {0x380f, 0xe4, 0, 0}, {0x3813, 0x04, 0, 0},
+ {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3709, 0x52, 0, 0},
+ {0x370c, 0x03, 0, 0}, {0x3a02, 0x02, 0, 0}, {0x3a03, 0xe0, 0, 0},
+ {0x3a14, 0x02, 0, 0}, {0x3a15, 0xe0, 0, 0}, {0x4004, 0x02, 0, 0},
+ {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0}, {0x4713, 0x03, 0, 0},
+ {0x4407, 0x04, 0, 0}, {0x460b, 0x37, 0, 0}, {0x460c, 0x20, 0, 0},
+ {0x4837, 0x16, 0, 0}, {0x3824, 0x04, 0, 0}, {0x5001, 0x83, 0, 0},
+ {0x3503, 0x00, 0, 0},
+};
+
+static struct reg_value ov5640_setting_30fps_QCIF_176_144[] = {
+ {0x3c07, 0x08, 0, 0}, {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0},
+ {0x3814, 0x31, 0, 0}, {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0},
+ {0x3801, 0x00, 0, 0}, {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0},
+ {0x3804, 0x0a, 0, 0}, {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0},
+ {0x3807, 0x9b, 0, 0}, {0x3808, 0x00, 0, 0}, {0x3809, 0xb0, 0, 0},
+ {0x380a, 0x00, 0, 0}, {0x380b, 0x90, 0, 0}, {0x380c, 0x07, 0, 0},
+ {0x380d, 0x68, 0, 0}, {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0},
+ {0x3813, 0x06, 0, 0}, {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0},
+ {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x0b, 0, 0},
+ {0x3a03, 0x88, 0, 0}, {0x3a14, 0x0b, 0, 0}, {0x3a15, 0x88, 0, 0},
+ {0x4004, 0x02, 0, 0}, {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0},
+ {0x4713, 0x03, 0, 0}, {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0},
+ {0x460c, 0x22, 0, 0}, {0x4837, 0x22, 0, 0}, {0x3824, 0x02, 0, 0},
+ {0x5001, 0xa3, 0, 0}, {0x3034, 0x1a, 0, 0}, {0x3035, 0x11, 0, 0},
+ {0x3036, 0x46, 0, 0}, {0x3037, 0x13, 0, 0},
+};
+
+static struct reg_value ov5640_setting_15fps_QCIF_176_144[] = {
+ {0x3c07, 0x08, 0, 0}, {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0},
+ {0x3814, 0x31, 0, 0}, {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0},
+ {0x3801, 0x00, 0, 0}, {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0},
+ {0x3804, 0x0a, 0, 0}, {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0},
+ {0x3807, 0x9b, 0, 0}, {0x3808, 0x00, 0, 0}, {0x3809, 0xb0, 0, 0},
+ {0x380a, 0x00, 0, 0}, {0x380b, 0x90, 0, 0}, {0x380c, 0x07, 0, 0},
+ {0x380d, 0x68, 0, 0}, {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0},
+ {0x3813, 0x06, 0, 0}, {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0},
+ {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x0b, 0, 0},
+ {0x3a03, 0x88, 0, 0}, {0x3a14, 0x0b, 0, 0}, {0x3a15, 0x88, 0, 0},
+ {0x4004, 0x02, 0, 0}, {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0},
+ {0x4713, 0x03, 0, 0}, {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0},
+ {0x460c, 0x22, 0, 0}, {0x4837, 0x22, 0, 0}, {0x3824, 0x02, 0, 0},
+ {0x5001, 0xa3, 0, 0}, {0x3034, 0x1a, 0, 0}, {0x3035, 0x21, 0, 0},
+ {0x3036, 0x46, 0, 0}, {0x3037, 0x13, 0, 0},
+};
+
+static struct reg_value ov5640_setting_30fps_XGA_1024_768[] = {
+ {0x3c07, 0x08, 0, 0}, {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0},
+ {0x3814, 0x31, 0, 0}, {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0},
+ {0x3801, 0x00, 0, 0}, {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0},
+ {0x3804, 0x0a, 0, 0}, {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0},
+ {0x3807, 0x9b, 0, 0}, {0x3808, 0x04, 0, 0}, {0x3809, 0x00, 0, 0},
+ {0x380a, 0x03, 0, 0}, {0x380b, 0x00, 0, 0}, {0x380c, 0x07, 0, 0},
+ {0x380d, 0x68, 0, 0}, {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0},
+ {0x3813, 0x06, 0, 0}, {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0},
+ {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x0b, 0, 0},
+ {0x3a03, 0x88, 0, 0}, {0x3a14, 0x0b, 0, 0}, {0x3a15, 0x88, 0, 0},
+ {0x4004, 0x02, 0, 0}, {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0},
+ {0x4713, 0x03, 0, 0}, {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0},
+ {0x460c, 0x20, 0, 0}, {0x4837, 0x22, 0, 0}, {0x3824, 0x01, 0, 0},
+ {0x5001, 0xa3, 0, 0}, {0x3034, 0x1a, 0, 0}, {0x3035, 0x21, 0, 0},
+ {0x3036, 0x69, 0, 0}, {0x3037, 0x13, 0, 0},
+};
+
+static struct reg_value ov5640_setting_15fps_XGA_1024_768[] = {
+ {0x3c07, 0x08, 0, 0}, {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0},
+ {0x3814, 0x31, 0, 0}, {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0},
+ {0x3801, 0x00, 0, 0}, {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0},
+ {0x3804, 0x0a, 0, 0}, {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0},
+ {0x3807, 0x9b, 0, 0}, {0x3808, 0x04, 0, 0}, {0x3809, 0x00, 0, 0},
+ {0x380a, 0x03, 0, 0}, {0x380b, 0x00, 0, 0}, {0x380c, 0x07, 0, 0},
+ {0x380d, 0x68, 0, 0}, {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0},
+ {0x3813, 0x06, 0, 0}, {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0},
+ {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x0b, 0, 0},
+ {0x3a03, 0x88, 0, 0}, {0x3a14, 0x0b, 0, 0}, {0x3a15, 0x88, 0, 0},
+ {0x4004, 0x02, 0, 0}, {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0},
+ {0x4713, 0x03, 0, 0}, {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0},
+ {0x460c, 0x20, 0, 0}, {0x4837, 0x22, 0, 0}, {0x3824, 0x01, 0, 0},
+ {0x5001, 0xa3, 0, 0}, {0x3034, 0x1a, 0, 0}, {0x3035, 0x21, 0, 0},
+ {0x3036, 0x46, 0, 0}, {0x3037, 0x13, 0, 0},
+};
+
+
+static struct reg_value ov5640_setting_15fps_1080P_1920_1080[] = {
+ {0x3c07, 0x07, 0, 0}, {0x3820, 0x40, 0, 0}, {0x3821, 0x06, 0, 0},
+ {0x3814, 0x11, 0, 0}, {0x3815, 0x11, 0, 0}, {0x3800, 0x00, 0, 0},
+ {0x3801, 0x00, 0, 0}, {0x3802, 0x00, 0, 0}, {0x3803, 0xee, 0, 0},
+ {0x3804, 0x0a, 0, 0}, {0x3805, 0x3f, 0, 0}, {0x3806, 0x05, 0, 0},
+ {0x3807, 0xc3, 0, 0}, {0x3808, 0x07, 0, 0}, {0x3809, 0x80, 0, 0},
+ {0x380a, 0x04, 0, 0}, {0x380b, 0x38, 0, 0}, {0x380c, 0x0b, 0, 0},
+ {0x380d, 0x1c, 0, 0}, {0x380e, 0x07, 0, 0}, {0x380f, 0xb0, 0, 0},
+ {0x3813, 0x04, 0, 0}, {0x3618, 0x04, 0, 0}, {0x3612, 0x2b, 0, 0},
+ {0x3709, 0x12, 0, 0}, {0x370c, 0x00, 0, 0}, {0x3a02, 0x07, 0, 0},
+ {0x3a03, 0xae, 0, 0}, {0x3a14, 0x07, 0, 0}, {0x3a15, 0xae, 0, 0},
+ {0x4004, 0x06, 0, 0}, {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0},
+ {0x4713, 0x02, 0, 0}, {0x4407, 0x0c, 0, 0}, {0x460b, 0x37, 0, 0},
+ {0x460c, 0x20, 0, 0}, {0x4837, 0x2c, 0, 0}, {0x3824, 0x01, 0, 0},
+ {0x5001, 0x83, 0, 0}, {0x3034, 0x1a, 0, 0}, {0x3035, 0x21, 0, 0},
+ {0x3036, 0x69, 0, 0}, {0x3037, 0x13, 0, 0},
+};
+
+static struct reg_value ov5640_setting_15fps_QSXGA_2592_1944[] = {
+ {0x3c07, 0x07, 0, 0}, {0x3820, 0x40, 0, 0}, {0x3821, 0x06, 0, 0},
+ {0x3814, 0x11, 0, 0}, {0x3815, 0x11, 0, 0}, {0x3800, 0x00, 0, 0},
+ {0x3801, 0x00, 0, 0}, {0x3802, 0x00, 0, 0}, {0x3803, 0x00, 0, 0},
+ {0x3804, 0x0a, 0, 0}, {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0},
+ {0x3807, 0x9f, 0, 0}, {0x3808, 0x0a, 0, 0}, {0x3809, 0x20, 0, 0},
+ {0x380a, 0x07, 0, 0}, {0x380b, 0x98, 0, 0}, {0x380c, 0x0b, 0, 0},
+ {0x380d, 0x1c, 0, 0}, {0x380e, 0x07, 0, 0}, {0x380f, 0xb0, 0, 0},
+ {0x3813, 0x04, 0, 0}, {0x3618, 0x04, 0, 0}, {0x3612, 0x2b, 0, 0},
+ {0x3709, 0x12, 0, 0}, {0x370c, 0x00, 0, 0}, {0x3a02, 0x07, 0, 0},
+ {0x3a03, 0xae, 0, 0}, {0x3a14, 0x07, 0, 0}, {0x3a15, 0xae, 0, 0},
+ {0x4004, 0x06, 0, 0}, {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0},
+ {0x4713, 0x02, 0, 0}, {0x4407, 0x0c, 0, 0}, {0x460b, 0x37, 0, 0},
+ {0x460c, 0x20, 0, 0}, {0x4837, 0x2c, 0, 0}, {0x3824, 0x01, 0, 0},
+ {0x5001, 0x83, 0, 0}, {0x3034, 0x1a, 0, 0}, {0x3035, 0x21, 0, 0},
+ {0x3036, 0x69, 0, 0}, {0x3037, 0x13, 0, 0},
+};
+
+static struct ov5640_mode_info ov5640_mode_info_data[2][ov5640_mode_MAX + 1] = {
+ {
+ {ov5640_mode_VGA_640_480, 640, 480,
+ ov5640_setting_15fps_VGA_640_480,
+ ARRAY_SIZE(ov5640_setting_15fps_VGA_640_480)},
+ {ov5640_mode_QVGA_320_240, 320, 240,
+ ov5640_setting_15fps_QVGA_320_240,
+ ARRAY_SIZE(ov5640_setting_15fps_QVGA_320_240)},
+ {ov5640_mode_NTSC_720_480, 720, 480,
+ ov5640_setting_15fps_NTSC_720_480,
+ ARRAY_SIZE(ov5640_setting_15fps_NTSC_720_480)},
+ {ov5640_mode_PAL_720_576, 720, 576,
+ ov5640_setting_15fps_PAL_720_576,
+ ARRAY_SIZE(ov5640_setting_15fps_PAL_720_576)},
+ {ov5640_mode_720P_1280_720, 1280, 720,
+ ov5640_setting_15fps_720P_1280_720,
+ ARRAY_SIZE(ov5640_setting_15fps_720P_1280_720)},
+ {ov5640_mode_1080P_1920_1080, 1920, 1080,
+ ov5640_setting_15fps_1080P_1920_1080,
+ ARRAY_SIZE(ov5640_setting_15fps_1080P_1920_1080)},
+ {ov5640_mode_QSXGA_2592_1944, 2592, 1944,
+ ov5640_setting_15fps_QSXGA_2592_1944,
+ ARRAY_SIZE(ov5640_setting_15fps_QSXGA_2592_1944)},
+ {ov5640_mode_QCIF_176_144, 176, 144,
+ ov5640_setting_15fps_QCIF_176_144,
+ ARRAY_SIZE(ov5640_setting_15fps_QCIF_176_144)},
+ {ov5640_mode_XGA_1024_768, 1024, 768,
+ ov5640_setting_15fps_XGA_1024_768,
+ ARRAY_SIZE(ov5640_setting_15fps_XGA_1024_768)},
+ },
+ {
+ {ov5640_mode_VGA_640_480, 640, 480,
+ ov5640_setting_30fps_VGA_640_480,
+ ARRAY_SIZE(ov5640_setting_30fps_VGA_640_480)},
+ {ov5640_mode_QVGA_320_240, 320, 240,
+ ov5640_setting_30fps_QVGA_320_240,
+ ARRAY_SIZE(ov5640_setting_30fps_QVGA_320_240)},
+ {ov5640_mode_NTSC_720_480, 720, 480,
+ ov5640_setting_30fps_NTSC_720_480,
+ ARRAY_SIZE(ov5640_setting_30fps_NTSC_720_480)},
+ {ov5640_mode_PAL_720_576, 720, 576,
+ ov5640_setting_30fps_PAL_720_576,
+ ARRAY_SIZE(ov5640_setting_30fps_PAL_720_576)},
+ {ov5640_mode_720P_1280_720, 1280, 720,
+ ov5640_setting_30fps_720P_1280_720,
+ ARRAY_SIZE(ov5640_setting_30fps_720P_1280_720)},
+ {ov5640_mode_1080P_1920_1080, 0, 0, NULL, 0},
+ {ov5640_mode_QSXGA_2592_1944, 0, 0, NULL, 0},
+ {ov5640_mode_QCIF_176_144, 176, 144,
+ ov5640_setting_30fps_QCIF_176_144,
+ ARRAY_SIZE(ov5640_setting_30fps_QCIF_176_144)},
+ {ov5640_mode_XGA_1024_768, 1024, 768,
+ ov5640_setting_30fps_XGA_1024_768,
+ ARRAY_SIZE(ov5640_setting_30fps_XGA_1024_768)},
+ },
+};
+
+static struct regulator *io_regulator;
+static struct regulator *core_regulator;
+static struct regulator *analog_regulator;
+
+static int ov5640_probe(struct i2c_client *adapter,
+ const struct i2c_device_id *device_id);
+static int ov5640_remove(struct i2c_client *client);
+
+static s32 ov5640_read_reg(u16 reg, u8 *val);
+static s32 ov5640_write_reg(u16 reg, u8 val);
+
+static const struct i2c_device_id ov5640_id[] = {
+ {"ov5640", 0},
+ {},
+};
+
+MODULE_DEVICE_TABLE(i2c, ov5640_id);
+
+static struct i2c_driver ov5640_i2c_driver = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "ov5640",
+ },
+ .probe = ov5640_probe,
+ .remove = ov5640_remove,
+ .id_table = ov5640_id,
+};
+
+static const struct ov5640_datafmt ov5640_colour_fmts[] = {
+ {MEDIA_BUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_JPEG},
+};
+
+static struct ov5640 *to_ov5640(const struct i2c_client *client)
+{
+ return container_of(i2c_get_clientdata(client), struct ov5640, subdev);
+}
+
+/* Find a data format by a pixel code in an array */
+static const struct ov5640_datafmt
+ *ov5640_find_datafmt(u32 code)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(ov5640_colour_fmts); i++)
+ if (ov5640_colour_fmts[i].code == code)
+ return ov5640_colour_fmts + i;
+
+ return NULL;
+}
+
+static inline void ov5640_power_down(int enable)
+{
+ gpio_set_value_cansleep(pwn_gpio, enable);
+
+ msleep(2);
+}
+
+static inline void ov5640_reset(void)
+{
+ /* camera reset */
+ gpio_set_value_cansleep(rst_gpio, 1);
+
+ /* camera power down */
+ gpio_set_value_cansleep(pwn_gpio, 1);
+ msleep(5);
+ gpio_set_value_cansleep(pwn_gpio, 0);
+ msleep(5);
+ gpio_set_value_cansleep(rst_gpio, 0);
+ msleep(1);
+ gpio_set_value_cansleep(rst_gpio, 1);
+ msleep(5);
+ gpio_set_value_cansleep(pwn_gpio, 1);
+}
+
+static int ov5640_regulator_enable(struct device *dev)
+{
+ int ret = 0;
+
+ io_regulator = devm_regulator_get(dev, "DOVDD");
+ if (!IS_ERR(io_regulator)) {
+ regulator_set_voltage(io_regulator,
+ OV5640_VOLTAGE_DIGITAL_IO,
+ OV5640_VOLTAGE_DIGITAL_IO);
+ ret = regulator_enable(io_regulator);
+ if (ret) {
+ dev_err(dev, "set io voltage failed\n");
+ return ret;
+ } else {
+ dev_dbg(dev, "set io voltage ok\n");
+ }
+ } else {
+ io_regulator = NULL;
+ dev_warn(dev, "cannot get io voltage\n");
+ }
+
+ core_regulator = devm_regulator_get(dev, "DVDD");
+ if (!IS_ERR(core_regulator)) {
+ regulator_set_voltage(core_regulator,
+ OV5640_VOLTAGE_DIGITAL_CORE,
+ OV5640_VOLTAGE_DIGITAL_CORE);
+ ret = regulator_enable(core_regulator);
+ if (ret) {
+ dev_err(dev, "set core voltage failed\n");
+ return ret;
+ } else {
+ dev_dbg(dev, "set core voltage ok\n");
+ }
+ } else {
+ core_regulator = NULL;
+ dev_warn(dev, "cannot get core voltage\n");
+ }
+
+ analog_regulator = devm_regulator_get(dev, "AVDD");
+ if (!IS_ERR(analog_regulator)) {
+ regulator_set_voltage(analog_regulator,
+ OV5640_VOLTAGE_ANALOG,
+ OV5640_VOLTAGE_ANALOG);
+ ret = regulator_enable(analog_regulator);
+ if (ret) {
+ dev_err(dev, "set analog voltage failed\n");
+ return ret;
+ } else {
+ dev_dbg(dev, "set analog voltage ok\n");
+ }
+ } else {
+ analog_regulator = NULL;
+ dev_warn(dev, "cannot get analog voltage\n");
+ }
+
+ return ret;
+}
+
+static s32 ov5640_write_reg(u16 reg, u8 val)
+{
+ u8 au8Buf[3] = {0};
+
+ au8Buf[0] = reg >> 8;
+ au8Buf[1] = reg & 0xff;
+ au8Buf[2] = val;
+
+ if (i2c_master_send(ov5640_data.i2c_client, au8Buf, 3) < 0) {
+ pr_err("%s:write reg error:reg=%x,val=%x\n",
+ __func__, reg, val);
+ return -1;
+ }
+
+ return 0;
+}
+
+static s32 ov5640_read_reg(u16 reg, u8 *val)
+{
+ u8 au8RegBuf[2] = {0};
+ u8 u8RdVal = 0;
+
+ au8RegBuf[0] = reg >> 8;
+ au8RegBuf[1] = reg & 0xff;
+
+ if (2 != i2c_master_send(ov5640_data.i2c_client, au8RegBuf, 2)) {
+ pr_err("%s:write reg error:reg=%x\n",
+ __func__, reg);
+ return -1;
+ }
+
+ if (1 != i2c_master_recv(ov5640_data.i2c_client, &u8RdVal, 1)) {
+ pr_err("%s:read reg error:reg=%x,val=%x\n",
+ __func__, reg, u8RdVal);
+ return -1;
+ }
+
+ *val = u8RdVal;
+
+ return u8RdVal;
+}
+
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+static int ov5640_get_register(struct v4l2_subdev *sd,
+ struct v4l2_dbg_register *reg)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ int ret;
+ u8 val;
+
+ if (reg->reg & ~0xffff)
+ return -EINVAL;
+
+ reg->size = 1;
+
+ ret = ov5640_read_reg(reg->reg, &val);
+ if (!ret)
+ reg->val = (__u64)val;
+
+ return ret;
+}
+
+static int ov5640_set_register(struct v4l2_subdev *sd,
+ const struct v4l2_dbg_register *reg)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+
+ if (reg->reg & ~0xffff || reg->val & ~0xff)
+ return -EINVAL;
+
+ return ov5640_write_reg(reg->reg, reg->val);
+}
+#endif
+
+static void ov5640_soft_reset(void)
+{
+ /* sysclk from pad */
+ ov5640_write_reg(0x3103, 0x11);
+
+ /* software reset */
+ ov5640_write_reg(0x3008, 0x82);
+
+ /* delay at least 5ms */
+ msleep(10);
+}
+
+/* set sensor driver capability
+ * 0x302c[7:6] - strength
+ 00 - 1x
+ 01 - 2x
+ 10 - 3x
+ 11 - 4x
+ */
+static int ov5640_driver_capability(int strength)
+{
+ u8 temp = 0;
+
+ if (strength > 4 || strength < 1) {
+ pr_err("The valid driver capability of ov5640 is 1x~4x\n");
+ return -EINVAL;
+ }
+
+ ov5640_read_reg(0x302c, &temp);
+
+ temp &= ~0xc0; /* clear [7:6] */
+ temp |= ((strength - 1) << 6); /* set [7:6] */
+
+ ov5640_write_reg(0x302c, temp);
+
+ return 0;
+}
+
+/* calculate sysclk */
+static int ov5640_get_sysclk(void)
+{
+ int xvclk = ov5640_data.mclk / 10000;
+ int sysclk;
+ int temp1, temp2;
+ int Multiplier, PreDiv, VCO, SysDiv, Pll_rdiv, Bit_div2x, sclk_rdiv;
+ int sclk_rdiv_map[] = {1, 2, 4, 8};
+ u8 regval = 0;
+
+ temp1 = ov5640_read_reg(0x3034, &regval);
+ temp2 = temp1 & 0x0f;
+ if (temp2 == 8 || temp2 == 10) {
+ Bit_div2x = temp2 / 2;
+ } else {
+ pr_err("ov5640: unsupported bit mode %d\n", temp2);
+ return -1;
+ }
+
+ temp1 = ov5640_read_reg(0x3035, &regval);
+ SysDiv = temp1 >> 4;
+ if (SysDiv == 0)
+ SysDiv = 16;
+
+ temp1 = ov5640_read_reg(0x3036, &regval);
+ Multiplier = temp1;
+ temp1 = ov5640_read_reg(0x3037, &regval);
+ PreDiv = temp1 & 0x0f;
+ Pll_rdiv = ((temp1 >> 4) & 0x01) + 1;
+
+ temp1 = ov5640_read_reg(0x3108, &regval);
+ temp2 = temp1 & 0x03;
+
+ sclk_rdiv = sclk_rdiv_map[temp2];
+ VCO = xvclk * Multiplier / PreDiv;
+ sysclk = VCO / SysDiv / Pll_rdiv * 2 / Bit_div2x / sclk_rdiv;
+
+ return sysclk;
+}
+
+/* read HTS from register settings */
+static int ov5640_get_HTS(void)
+{
+ int HTS;
+ u8 temp = 0;
+
+ HTS = ov5640_read_reg(0x380c, &temp);
+ HTS = (HTS<<8) + ov5640_read_reg(0x380d, &temp);
+ return HTS;
+}
+
+/* read VTS from register settings */
+static int ov5640_get_VTS(void)
+{
+ int VTS;
+ u8 temp = 0;
+
+ VTS = ov5640_read_reg(0x380e, &temp);
+ VTS = (VTS<<8) + ov5640_read_reg(0x380f, &temp);
+
+ return VTS;
+}
+
+/* write VTS to registers */
+static int ov5640_set_VTS(int VTS)
+{
+ int temp;
+
+ temp = VTS & 0xff;
+ ov5640_write_reg(0x380f, temp);
+
+ temp = VTS>>8;
+ ov5640_write_reg(0x380e, temp);
+ return 0;
+}
+
+/* read shutter, in number of line period */
+static int ov5640_get_shutter(void)
+{
+ int shutter;
+ u8 regval;
+
+ shutter = (ov5640_read_reg(0x03500, &regval) & 0x0f);
+
+ shutter = (shutter<<8) + ov5640_read_reg(0x3501, &regval);
+ shutter = (shutter<<4) + (ov5640_read_reg(0x3502, &regval)>>4);
+
+ return shutter;
+}
+
+/* write shutter, in number of line period */
+static int ov5640_set_shutter(int shutter)
+{
+ int temp;
+
+ shutter = shutter & 0xffff;
+ temp = shutter & 0x0f;
+ temp = temp<<4;
+ ov5640_write_reg(0x3502, temp);
+
+ temp = shutter & 0xfff;
+ temp = temp>>4;
+ ov5640_write_reg(0x3501, temp);
+
+ temp = shutter>>12;
+ ov5640_write_reg(0x3500, temp);
+
+ return 0;
+}
+
+/* read gain, 16 = 1x */
+static int ov5640_get_gain16(void)
+{
+ int gain16;
+ u8 regval;
+
+ gain16 = ov5640_read_reg(0x350a, &regval) & 0x03;
+ gain16 = (gain16<<8) + ov5640_read_reg(0x350b, &regval);
+
+ return gain16;
+}
+
+/* write gain, 16 = 1x */
+static int ov5640_set_gain16(int gain16)
+{
+ int temp;
+
+ gain16 = gain16 & 0x3ff;
+ temp = gain16 & 0xff;
+
+ ov5640_write_reg(0x350b, temp);
+ temp = gain16>>8;
+
+ ov5640_write_reg(0x350a, temp);
+ return 0;
+}
+
+/* get banding filter value */
+static int ov5640_get_light_freq(void)
+{
+ int temp, temp1, light_frequency;
+ u8 regval;
+
+ temp = ov5640_read_reg(0x3c01, &regval);
+ if (temp & 0x80) {
+ /* manual */
+ temp1 = ov5640_read_reg(0x3c00, &regval);
+ if (temp1 & 0x04) {
+ /* 50Hz */
+ light_frequency = 50;
+ } else {
+ /* 60Hz */
+ light_frequency = 60;
+ }
+ } else {
+ /* auto */
+ temp1 = ov5640_read_reg(0x3c0c, &regval);
+ if (temp1 & 0x01) {
+ /* 50Hz */
+ light_frequency = 50;
+ } else {
+ /* 60Hz */
+ light_frequency = 60;
+ }
+ }
+
+ return light_frequency;
+}
+
+static void ov5640_set_bandingfilter(void)
+{
+ int prev_VTS;
+ int band_step60, max_band60, band_step50, max_band50;
+
+ /* read preview PCLK */
+ prev_sysclk = ov5640_get_sysclk();
+
+ /* read preview HTS */
+ prev_HTS = ov5640_get_HTS();
+
+ /* read preview VTS */
+ prev_VTS = ov5640_get_VTS();
+
+ /* calculate banding filter */
+ /* 60Hz */
+ band_step60 = prev_sysclk * 100/prev_HTS * 100/120;
+ ov5640_write_reg(0x3a0a, (band_step60 >> 8));
+ ov5640_write_reg(0x3a0b, (band_step60 & 0xff));
+
+ max_band60 = (int)((prev_VTS-4)/band_step60);
+ ov5640_write_reg(0x3a0d, max_band60);
+
+ /* 50Hz */
+ band_step50 = prev_sysclk * 100/prev_HTS;
+ ov5640_write_reg(0x3a08, (band_step50 >> 8));
+ ov5640_write_reg(0x3a09, (band_step50 & 0xff));
+
+ max_band50 = (int)((prev_VTS-4)/band_step50);
+ ov5640_write_reg(0x3a0e, max_band50);
+}
+
+/* stable in high */
+static int ov5640_set_AE_target(int target)
+{
+ int fast_high, fast_low;
+
+ AE_low = target * 23 / 25; /* 0.92 */
+ AE_high = target * 27 / 25; /* 1.08 */
+ fast_high = AE_high << 1;
+
+ if (fast_high > 255)
+ fast_high = 255;
+ fast_low = AE_low >> 1;
+
+ ov5640_write_reg(0x3a0f, AE_high);
+ ov5640_write_reg(0x3a10, AE_low);
+ ov5640_write_reg(0x3a1b, AE_high);
+ ov5640_write_reg(0x3a1e, AE_low);
+ ov5640_write_reg(0x3a11, fast_high);
+ ov5640_write_reg(0x3a1f, fast_low);
+
+ return 0;
+}
+
+/* enable = 0 to turn off night mode
+ enable = 1 to turn on night mode */
+static int ov5640_set_night_mode(int enable)
+{
+ u8 mode;
+
+ ov5640_read_reg(0x3a00, &mode);
+
+ if (enable) {
+ /* night mode on */
+ mode |= 0x04;
+ ov5640_write_reg(0x3a00, mode);
+ } else {
+ /* night mode off */
+ mode &= 0xfb;
+ ov5640_write_reg(0x3a00, mode);
+ }
+
+ return 0;
+}
+
+/* enable = 0 to turn off AEC/AGC
+ enable = 1 to turn on AEC/AGC */
+static void ov5640_turn_on_AE_AG(int enable)
+{
+ u8 ae_ag_ctrl;
+
+ ov5640_read_reg(0x3503, &ae_ag_ctrl);
+ if (enable) {
+ /* turn on auto AE/AG */
+ ae_ag_ctrl = ae_ag_ctrl & ~(0x03);
+ } else {
+ /* turn off AE/AG */
+ ae_ag_ctrl = ae_ag_ctrl | 0x03;
+ }
+ ov5640_write_reg(0x3503, ae_ag_ctrl);
+}
+
+/* download ov5640 settings to sensor through i2c */
+static int ov5640_download_firmware(struct reg_value *pModeSetting, s32 ArySize)
+{
+ register u32 Delay_ms = 0;
+ register u16 RegAddr = 0;
+ register u8 Mask = 0;
+ register u8 Val = 0;
+ u8 RegVal = 0;
+ int i, retval = 0;
+
+ for (i = 0; i < ArySize; ++i, ++pModeSetting) {
+ Delay_ms = pModeSetting->u32Delay_ms;
+ RegAddr = pModeSetting->u16RegAddr;
+ Val = pModeSetting->u8Val;
+ Mask = pModeSetting->u8Mask;
+
+ if (Mask) {
+ retval = ov5640_read_reg(RegAddr, &RegVal);
+ if (retval < 0)
+ goto err;
+
+ RegVal &= ~(u8)Mask;
+ Val &= Mask;
+ Val |= RegVal;
+ }
+
+ retval = ov5640_write_reg(RegAddr, Val);
+ if (retval < 0)
+ goto err;
+
+ if (Delay_ms)
+ msleep(Delay_ms);
+ }
+err:
+ return retval;
+}
+
+static int ov5640_init_mode(void)
+{
+ struct reg_value *pModeSetting = NULL;
+ int ArySize = 0, retval = 0;
+
+ ov5640_soft_reset();
+
+ pModeSetting = ov5640_global_init_setting;
+ ArySize = ARRAY_SIZE(ov5640_global_init_setting);
+ retval = ov5640_download_firmware(pModeSetting, ArySize);
+ if (retval < 0)
+ goto err;
+
+ pModeSetting = ov5640_init_setting_30fps_VGA;
+ ArySize = ARRAY_SIZE(ov5640_init_setting_30fps_VGA);
+ retval = ov5640_download_firmware(pModeSetting, ArySize);
+ if (retval < 0)
+ goto err;
+
+ /* change driver capability to 2x according to validation board.
+ * if the image is not stable, please increase the driver strength.
+ */
+ ov5640_driver_capability(2);
+ ov5640_set_bandingfilter();
+ ov5640_set_AE_target(AE_Target);
+ ov5640_set_night_mode(night_mode);
+
+ /* skip 9 vysnc: start capture at 10th vsync */
+ msleep(300);
+
+ /* turn off night mode */
+ night_mode = 0;
+ ov5640_data.pix.width = 640;
+ ov5640_data.pix.height = 480;
+err:
+ return retval;
+}
+
+/* change to or back to subsampling mode set the mode directly
+ * image size below 1280 * 960 is subsampling mode */
+static int ov5640_change_mode_direct(enum ov5640_frame_rate frame_rate,
+ enum ov5640_mode mode)
+{
+ struct reg_value *pModeSetting = NULL;
+ s32 ArySize = 0;
+ int retval = 0;
+
+ if (mode > ov5640_mode_MAX || mode < ov5640_mode_MIN) {
+ pr_err("Wrong ov5640 mode detected!\n");
+ return -1;
+ }
+
+ pModeSetting = ov5640_mode_info_data[frame_rate][mode].init_data_ptr;
+ ArySize =
+ ov5640_mode_info_data[frame_rate][mode].init_data_size;
+
+ ov5640_data.pix.width = ov5640_mode_info_data[frame_rate][mode].width;
+ ov5640_data.pix.height = ov5640_mode_info_data[frame_rate][mode].height;
+
+ if (ov5640_data.pix.width == 0 || ov5640_data.pix.height == 0 ||
+ pModeSetting == NULL || ArySize == 0)
+ return -EINVAL;
+
+ /* set ov5640 to subsampling mode */
+ retval = ov5640_download_firmware(pModeSetting, ArySize);
+
+ /* turn on AE AG for subsampling mode, in case the firmware didn't */
+ ov5640_turn_on_AE_AG(1);
+
+ /* calculate banding filter */
+ ov5640_set_bandingfilter();
+
+ /* set AE target */
+ ov5640_set_AE_target(AE_Target);
+
+ /* update night mode setting */
+ ov5640_set_night_mode(night_mode);
+
+ /* skip 9 vysnc: start capture at 10th vsync */
+ if (mode == ov5640_mode_XGA_1024_768 && frame_rate == ov5640_30_fps) {
+ pr_warning("ov5640: actual frame rate of XGA is 22.5fps\n");
+ /* 1/22.5 * 9*/
+ msleep(400);
+ return retval;
+ }
+
+ if (frame_rate == ov5640_15_fps) {
+ /* 1/15 * 9*/
+ msleep(600);
+ } else if (frame_rate == ov5640_30_fps) {
+ /* 1/30 * 9*/
+ msleep(300);
+ }
+
+ return retval;
+}
+
+/* change to scaling mode go through exposure calucation
+ * image size above 1280 * 960 is scaling mode */
+static int ov5640_change_mode_exposure_calc(enum ov5640_frame_rate frame_rate,
+ enum ov5640_mode mode)
+{
+ int prev_shutter, prev_gain16, average;
+ int cap_shutter, cap_gain16;
+ int cap_sysclk, cap_HTS, cap_VTS;
+ int light_freq, cap_bandfilt, cap_maxband;
+ long cap_gain16_shutter;
+ u8 temp;
+ struct reg_value *pModeSetting = NULL;
+ s32 ArySize = 0;
+ int retval = 0;
+
+ /* check if the input mode and frame rate is valid */
+ pModeSetting =
+ ov5640_mode_info_data[frame_rate][mode].init_data_ptr;
+ ArySize =
+ ov5640_mode_info_data[frame_rate][mode].init_data_size;
+
+ ov5640_data.pix.width =
+ ov5640_mode_info_data[frame_rate][mode].width;
+ ov5640_data.pix.height =
+ ov5640_mode_info_data[frame_rate][mode].height;
+
+ if (ov5640_data.pix.width == 0 || ov5640_data.pix.height == 0 ||
+ pModeSetting == NULL || ArySize == 0)
+ return -EINVAL;
+
+ /* read preview shutter */
+ prev_shutter = ov5640_get_shutter();
+
+ /* read preview gain */
+ prev_gain16 = ov5640_get_gain16();
+
+ /* get average */
+ average = ov5640_read_reg(0x56a1, &temp);
+
+ /* turn off night mode for capture */
+ ov5640_set_night_mode(0);
+
+ /* turn off overlay */
+ ov5640_write_reg(0x3022, 0x06);
+
+ /* Write capture setting */
+ retval = ov5640_download_firmware(pModeSetting, ArySize);
+ if (retval < 0)
+ goto err;
+
+ /* turn off AE AG when capture image. */
+ ov5640_turn_on_AE_AG(0);
+
+ /* read capture VTS */
+ cap_VTS = ov5640_get_VTS();
+ cap_HTS = ov5640_get_HTS();
+ cap_sysclk = ov5640_get_sysclk();
+
+ /* calculate capture banding filter */
+ light_freq = ov5640_get_light_freq();
+ if (light_freq == 60) {
+ /* 60Hz */
+ cap_bandfilt = cap_sysclk * 100 / cap_HTS * 100 / 120;
+ } else {
+ /* 50Hz */
+ cap_bandfilt = cap_sysclk * 100 / cap_HTS;
+ }
+ cap_maxband = (int)((cap_VTS - 4)/cap_bandfilt);
+ /* calculate capture shutter/gain16 */
+ if (average > AE_low && average < AE_high) {
+ /* in stable range */
+ cap_gain16_shutter =
+ prev_gain16 * prev_shutter * cap_sysclk/prev_sysclk *
+ prev_HTS/cap_HTS * AE_Target / average;
+ } else {
+ cap_gain16_shutter =
+ prev_gain16 * prev_shutter * cap_sysclk/prev_sysclk *
+ prev_HTS/cap_HTS;
+ }
+
+ /* gain to shutter */
+ if (cap_gain16_shutter < (cap_bandfilt * 16)) {
+ /* shutter < 1/100 */
+ cap_shutter = cap_gain16_shutter/16;
+ if (cap_shutter < 1)
+ cap_shutter = 1;
+ cap_gain16 = cap_gain16_shutter/cap_shutter;
+ if (cap_gain16 < 16)
+ cap_gain16 = 16;
+ } else {
+ if (cap_gain16_shutter > (cap_bandfilt*cap_maxband*16)) {
+ /* exposure reach max */
+ cap_shutter = cap_bandfilt*cap_maxband;
+ cap_gain16 = cap_gain16_shutter / cap_shutter;
+ } else {
+ /* 1/100 < cap_shutter =< max, cap_shutter = n/100 */
+ cap_shutter =
+ ((int)(cap_gain16_shutter/16/cap_bandfilt))
+ * cap_bandfilt;
+ cap_gain16 = cap_gain16_shutter / cap_shutter;
+ }
+ }
+
+ /* write capture gain */
+ ov5640_set_gain16(cap_gain16);
+
+ /* write capture shutter */
+ if (cap_shutter > (cap_VTS - 4)) {
+ cap_VTS = cap_shutter + 4;
+ ov5640_set_VTS(cap_VTS);
+ }
+
+ ov5640_set_shutter(cap_shutter);
+
+ /* skip 2 vysnc: start capture at 3rd vsync
+ * frame rate of QSXGA and 1080P is 7.5fps: 1/7.5 * 2
+ */
+ pr_warning("ov5640: the actual frame rate of %s is 7.5fps\n",
+ mode == ov5640_mode_1080P_1920_1080 ? "1080P" : "QSXGA");
+ msleep(267);
+err:
+ return retval;
+}
+
+static int ov5640_change_mode(enum ov5640_frame_rate frame_rate,
+ enum ov5640_mode mode)
+{
+ int retval = 0;
+
+ if (mode > ov5640_mode_MAX || mode < ov5640_mode_MIN) {
+ pr_err("Wrong ov5640 mode detected!\n");
+ return -1;
+ }
+
+ if (mode == ov5640_mode_1080P_1920_1080 ||
+ mode == ov5640_mode_QSXGA_2592_1944) {
+ /* change to scaling mode go through exposure calucation
+ * image size above 1280 * 960 is scaling mode */
+ retval = ov5640_change_mode_exposure_calc(frame_rate, mode);
+ } else {
+ /* change back to subsampling modem download firmware directly
+ * image size below 1280 * 960 is subsampling mode */
+ retval = ov5640_change_mode_direct(frame_rate, mode);
+ }
+
+ return retval;
+}
+
+/*!
+ * ov5640_s_power - V4L2 sensor interface handler for VIDIOC_S_POWER ioctl
+ * @s: pointer to standard V4L2 device structure
+ * @on: indicates power mode (on or off)
+ *
+ * Turns the power on or off, depending on the value of on and returns the
+ * appropriate error code.
+ */
+static int ov5640_s_power(struct v4l2_subdev *sd, int on)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct ov5640 *sensor = to_ov5640(client);
+
+ if (on)
+ clk_enable(ov5640_data.sensor_clk);
+ else
+ clk_disable(ov5640_data.sensor_clk);
+
+ sensor->on = on;
+
+ return 0;
+}
+
+/*!
+ * ov5640_g_parm - V4L2 sensor interface handler for VIDIOC_G_PARM ioctl
+ * @s: pointer to standard V4L2 sub device structure
+ * @a: pointer to standard V4L2 VIDIOC_G_PARM ioctl structure
+ *
+ * Returns the sensor's video CAPTURE parameters.
+ */
+static int ov5640_g_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *a)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct ov5640 *sensor = to_ov5640(client);
+ struct v4l2_captureparm *cparm = &a->parm.capture;
+ int ret = 0;
+
+ switch (a->type) {
+ /* This is the only case currently handled. */
+ case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+ memset(a, 0, sizeof(*a));
+ a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ cparm->capability = sensor->streamcap.capability;
+ cparm->timeperframe = sensor->streamcap.timeperframe;
+ cparm->capturemode = sensor->streamcap.capturemode;
+ ret = 0;
+ break;
+
+ /* These are all the possible cases. */
+ case V4L2_BUF_TYPE_VIDEO_OUTPUT:
+ case V4L2_BUF_TYPE_VIDEO_OVERLAY:
+ case V4L2_BUF_TYPE_VBI_CAPTURE:
+ case V4L2_BUF_TYPE_VBI_OUTPUT:
+ case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
+ case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
+ ret = -EINVAL;
+ break;
+
+ default:
+ pr_debug(" type is unknown - %d\n", a->type);
+ ret = -EINVAL;
+ break;
+ }
+
+ return ret;
+}
+
+/*!
+ * ov5460_s_parm - V4L2 sensor interface handler for VIDIOC_S_PARM ioctl
+ * @s: pointer to standard V4L2 sub device structure
+ * @a: pointer to standard V4L2 VIDIOC_S_PARM ioctl structure
+ *
+ * Configures the sensor to use the input parameters, if possible. If
+ * not possible, reverts to the old parameters and returns the
+ * appropriate error code.
+ */
+static int ov5640_s_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *a)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct ov5640 *sensor = to_ov5640(client);
+ struct v4l2_fract *timeperframe = &a->parm.capture.timeperframe;
+ u32 tgt_fps; /* target frames per secound */
+ enum ov5640_frame_rate frame_rate;
+ int ret = 0;
+
+ switch (a->type) {
+ /* This is the only case currently handled. */
+ case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+ /* Check that the new frame rate is allowed. */
+ if ((timeperframe->numerator == 0) ||
+ (timeperframe->denominator == 0)) {
+ timeperframe->denominator = DEFAULT_FPS;
+ timeperframe->numerator = 1;
+ }
+
+ tgt_fps = timeperframe->denominator /
+ timeperframe->numerator;
+
+ if (tgt_fps > MAX_FPS) {
+ timeperframe->denominator = MAX_FPS;
+ timeperframe->numerator = 1;
+ } else if (tgt_fps < MIN_FPS) {
+ timeperframe->denominator = MIN_FPS;
+ timeperframe->numerator = 1;
+ }
+
+ /* Actual frame rate we use */
+ tgt_fps = timeperframe->denominator /
+ timeperframe->numerator;
+
+ if (tgt_fps == 15)
+ frame_rate = ov5640_15_fps;
+ else if (tgt_fps == 30)
+ frame_rate = ov5640_30_fps;
+ else {
+ pr_err(" The camera frame rate is not supported!\n");
+ goto error;
+ }
+
+ ret = ov5640_change_mode(frame_rate,
+ a->parm.capture.capturemode);
+ if (ret < 0)
+ goto error;
+
+ sensor->streamcap.timeperframe = *timeperframe;
+ sensor->streamcap.capturemode = a->parm.capture.capturemode;
+
+ break;
+
+ /* These are all the possible cases. */
+ case V4L2_BUF_TYPE_VIDEO_OUTPUT:
+ case V4L2_BUF_TYPE_VIDEO_OVERLAY:
+ case V4L2_BUF_TYPE_VBI_CAPTURE:
+ case V4L2_BUF_TYPE_VBI_OUTPUT:
+ case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
+ case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
+ pr_debug(" type is not " \
+ "V4L2_BUF_TYPE_VIDEO_CAPTURE but %d\n",
+ a->type);
+ ret = -EINVAL;
+ break;
+
+ default:
+ pr_debug(" type is unknown - %d\n", a->type);
+ ret = -EINVAL;
+ break;
+ }
+
+error:
+ return ret;
+}
+
+static int ov5640_set_fmt(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_format *format)
+{
+ struct v4l2_mbus_framefmt *mf = &format->format;
+ const struct ov5640_datafmt *fmt = ov5640_find_datafmt(mf->code);
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct ov5640 *sensor = to_ov5640(client);
+
+ if (format->pad)
+ return -EINVAL;
+
+ if (!fmt) {
+ mf->code = ov5640_colour_fmts[0].code;
+ mf->colorspace = ov5640_colour_fmts[0].colorspace;
+ }
+
+ mf->field = V4L2_FIELD_NONE;
+
+ if (format->which == V4L2_SUBDEV_FORMAT_TRY)
+ return 0;
+
+ sensor->fmt = fmt;
+
+ return 0;
+}
+
+static int ov5640_get_fmt(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_format *format)
+{
+ struct v4l2_mbus_framefmt *mf = &format->format;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct ov5640 *sensor = to_ov5640(client);
+ const struct ov5640_datafmt *fmt = sensor->fmt;
+
+ if (format->pad)
+ return -EINVAL;
+
+ mf->code = fmt->code;
+ mf->colorspace = fmt->colorspace;
+ mf->field = V4L2_FIELD_NONE;
+
+ return 0;
+}
+
+static int ov5640_enum_code(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_mbus_code_enum *code)
+{
+ if (code->pad || code->index >= ARRAY_SIZE(ov5640_colour_fmts))
+ return -EINVAL;
+
+ code->code = ov5640_colour_fmts[code->index].code;
+ return 0;
+}
+
+/*!
+ * ov5640_enum_framesizes - V4L2 sensor interface handler for
+ * VIDIOC_ENUM_FRAMESIZES ioctl
+ * @s: pointer to standard V4L2 device structure
+ * @fsize: standard V4L2 VIDIOC_ENUM_FRAMESIZES ioctl structure
+ *
+ * Return 0 if successful, otherwise -EINVAL.
+ */
+static int ov5640_enum_framesizes(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_frame_size_enum *fse)
+{
+ if (fse->index > ov5640_mode_MAX)
+ return -EINVAL;
+
+ fse->max_width =
+ max(ov5640_mode_info_data[0][fse->index].width,
+ ov5640_mode_info_data[1][fse->index].width);
+ fse->min_width = fse->max_width;
+ fse->max_height =
+ max(ov5640_mode_info_data[0][fse->index].height,
+ ov5640_mode_info_data[1][fse->index].height);
+ fse->min_height = fse->max_height;
+ return 0;
+}
+
+/*!
+ * ov5640_enum_frameintervals - V4L2 sensor interface handler for
+ * VIDIOC_ENUM_FRAMEINTERVALS ioctl
+ * @s: pointer to standard V4L2 device structure
+ * @fival: standard V4L2 VIDIOC_ENUM_FRAMEINTERVALS ioctl structure
+ *
+ * Return 0 if successful, otherwise -EINVAL.
+ */
+static int ov5640_enum_frameintervals(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_frame_interval_enum *fie)
+{
+ int i, j, count;
+
+ if (fie->index < 0 || fie->index > ov5640_mode_MAX)
+ return -EINVAL;
+
+ if (fie->width == 0 || fie->height == 0 ||
+ fie->code == 0) {
+ pr_warning("Please assign pixel format, width and height.\n");
+ return -EINVAL;
+ }
+
+ fie->interval.numerator = 1;
+
+ count = 0;
+ for (i = 0; i < ARRAY_SIZE(ov5640_mode_info_data); i++) {
+ for (j = 0; j < (ov5640_mode_MAX + 1); j++) {
+ if (fie->width == ov5640_mode_info_data[i][j].width
+ && fie->height == ov5640_mode_info_data[i][j].height
+ && ov5640_mode_info_data[i][j].init_data_ptr != NULL) {
+ count++;
+ }
+ if (fie->index == (count - 1)) {
+ fie->interval.denominator =
+ ov5640_framerates[i];
+ return 0;
+ }
+ }
+ }
+
+ return -EINVAL;
+}
+
+static int ov5640_set_clk_rate(void)
+{
+ u32 tgt_xclk; /* target xclk */
+ int ret;
+
+ /* mclk */
+ tgt_xclk = ov5640_data.mclk;
+ tgt_xclk = min(tgt_xclk, (u32)OV5640_XCLK_MAX);
+ tgt_xclk = max(tgt_xclk, (u32)OV5640_XCLK_MIN);
+ ov5640_data.mclk = tgt_xclk;
+
+ pr_debug(" Setting mclk to %d MHz\n", tgt_xclk / 1000000);
+ ret = clk_set_rate(ov5640_data.sensor_clk, ov5640_data.mclk);
+ if (ret < 0)
+ pr_debug("set rate filed, rate=%d\n", ov5640_data.mclk);
+ return ret;
+}
+
+/*!
+ * dev_init - V4L2 sensor init
+ * @s: pointer to standard V4L2 device structure
+ *
+ */
+static int init_device(void)
+{
+ u32 tgt_xclk; /* target xclk */
+ u32 tgt_fps; /* target frames per secound */
+ enum ov5640_frame_rate frame_rate;
+ int ret;
+
+ ov5640_data.on = true;
+
+ /* mclk */
+ tgt_xclk = ov5640_data.mclk;
+
+ /* Default camera frame rate is set in probe */
+ tgt_fps = ov5640_data.streamcap.timeperframe.denominator /
+ ov5640_data.streamcap.timeperframe.numerator;
+
+ if (tgt_fps == 15)
+ frame_rate = ov5640_15_fps;
+ else if (tgt_fps == 30)
+ frame_rate = ov5640_30_fps;
+ else
+ return -EINVAL; /* Only support 15fps or 30fps now. */
+
+ ret = ov5640_init_mode();
+
+ return ret;
+}
+
+static struct v4l2_subdev_video_ops ov5640_subdev_video_ops = {
+ .g_parm = ov5640_g_parm,
+ .s_parm = ov5640_s_parm,
+};
+
+static const struct v4l2_subdev_pad_ops ov5640_subdev_pad_ops = {
+ .enum_frame_size = ov5640_enum_framesizes,
+ .enum_frame_interval = ov5640_enum_frameintervals,
+ .enum_mbus_code = ov5640_enum_code,
+ .set_fmt = ov5640_set_fmt,
+ .get_fmt = ov5640_get_fmt,
+};
+
+static struct v4l2_subdev_core_ops ov5640_subdev_core_ops = {
+ .s_power = ov5640_s_power,
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+ .g_register = ov5640_get_register,
+ .s_register = ov5640_set_register,
+#endif
+};
+
+static struct v4l2_subdev_ops ov5640_subdev_ops = {
+ .core = &ov5640_subdev_core_ops,
+ .video = &ov5640_subdev_video_ops,
+ .pad = &ov5640_subdev_pad_ops,
+};
+
+/*!
+ * ov5640 I2C probe function
+ *
+ * @param adapter struct i2c_adapter *
+ * @return Error code indicating success or failure
+ */
+static int ov5640_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct pinctrl *pinctrl;
+ struct device *dev = &client->dev;
+ int retval;
+ u8 chip_id_high, chip_id_low;
+
+ /* ov5640 pinctrl */
+ pinctrl = devm_pinctrl_get_select_default(dev);
+ if (IS_ERR(pinctrl)) {
+ dev_err(dev, "setup pinctrl failed\n");
+ return PTR_ERR(pinctrl);
+ }
+
+ /* request power down pin */
+ pwn_gpio = of_get_named_gpio(dev->of_node, "pwn-gpios", 0);
+ if (!gpio_is_valid(pwn_gpio)) {
+ dev_err(dev, "no sensor pwdn pin available\n");
+ return -ENODEV;
+ }
+ retval = devm_gpio_request_one(dev, pwn_gpio, GPIOF_OUT_INIT_HIGH,
+ "ov5640_pwdn");
+ if (retval < 0)
+ return retval;
+
+ /* request reset pin */
+ rst_gpio = of_get_named_gpio(dev->of_node, "rst-gpios", 0);
+ if (!gpio_is_valid(rst_gpio)) {
+ dev_err(dev, "no sensor reset pin available\n");
+ return -EINVAL;
+ }
+ retval = devm_gpio_request_one(dev, rst_gpio, GPIOF_OUT_INIT_HIGH,
+ "ov5640_reset");
+ if (retval < 0)
+ return retval;
+
+ /* Set initial values for the sensor struct. */
+ memset(&ov5640_data, 0, sizeof(ov5640_data));
+ ov5640_data.sensor_clk = devm_clk_get(dev, "csi_mclk");
+ if (IS_ERR(ov5640_data.sensor_clk)) {
+ dev_err(dev, "get mclk failed\n");
+ return PTR_ERR(ov5640_data.sensor_clk);
+ }
+
+ retval = of_property_read_u32(dev->of_node, "mclk",
+ &ov5640_data.mclk);
+ if (retval) {
+ dev_err(dev, "mclk frequency is invalid\n");
+ return retval;
+ }
+
+ retval = of_property_read_u32(dev->of_node, "mclk_source",
+ (u32 *) &(ov5640_data.mclk_source));
+ if (retval) {
+ dev_err(dev, "mclk_source invalid\n");
+ return retval;
+ }
+
+ retval = of_property_read_u32(dev->of_node, "csi_id",
+ &(ov5640_data.csi));
+ if (retval) {
+ dev_err(dev, "csi_id invalid\n");
+ return retval;
+ }
+
+ /* Set mclk rate before clk on */
+ ov5640_set_clk_rate();
+
+ clk_prepare_enable(ov5640_data.sensor_clk);
+
+ ov5640_data.io_init = ov5640_reset;
+ ov5640_data.i2c_client = client;
+ ov5640_data.pix.pixelformat = V4L2_PIX_FMT_YUYV;
+ ov5640_data.pix.width = 640;
+ ov5640_data.pix.height = 480;
+ ov5640_data.streamcap.capability = V4L2_MODE_HIGHQUALITY |
+ V4L2_CAP_TIMEPERFRAME;
+ ov5640_data.streamcap.capturemode = 0;
+ ov5640_data.streamcap.timeperframe.denominator = DEFAULT_FPS;
+ ov5640_data.streamcap.timeperframe.numerator = 1;
+
+ ov5640_regulator_enable(&client->dev);
+
+ ov5640_reset();
+
+ ov5640_power_down(0);
+
+ retval = ov5640_read_reg(OV5640_CHIP_ID_HIGH_BYTE, &chip_id_high);
+ if (retval < 0 || chip_id_high != 0x56) {
+ clk_disable_unprepare(ov5640_data.sensor_clk);
+ pr_warning("camera ov5640 is not found\n");
+ return -ENODEV;
+ }
+ retval = ov5640_read_reg(OV5640_CHIP_ID_LOW_BYTE, &chip_id_low);
+ if (retval < 0 || chip_id_low != 0x40) {
+ clk_disable_unprepare(ov5640_data.sensor_clk);
+ pr_warning("camera ov5640 is not found\n");
+ return -ENODEV;
+ }
+
+ retval = init_device();
+ if (retval < 0) {
+ clk_disable_unprepare(ov5640_data.sensor_clk);
+ pr_warning("camera ov5640 init failed\n");
+ ov5640_power_down(1);
+ return retval;
+ }
+
+ clk_disable(ov5640_data.sensor_clk);
+
+ v4l2_i2c_subdev_init(&ov5640_data.subdev, client, &ov5640_subdev_ops);
+
+ retval = v4l2_async_register_subdev(&ov5640_data.subdev);
+ if (retval < 0)
+ dev_err(&client->dev,
+ "%s--Async register failed, ret=%d\n", __func__, retval);
+
+ pr_info("camera ov5640, is found\n");
+ return retval;
+}
+
+/*!
+ * ov5640 I2C detach function
+ *
+ * @param client struct i2c_client *
+ * @return Error code indicating success or failure
+ */
+static int ov5640_remove(struct i2c_client *client)
+{
+ struct v4l2_subdev *sd = i2c_get_clientdata(client);
+
+ v4l2_async_unregister_subdev(sd);
+
+ clk_unprepare(ov5640_data.sensor_clk);
+
+ ov5640_power_down(1);
+
+ if (analog_regulator)
+ regulator_disable(analog_regulator);
+
+ if (core_regulator)
+ regulator_disable(core_regulator);
+
+ if (io_regulator)
+ regulator_disable(io_regulator);
+
+ return 0;
+}
+
+module_i2c_driver(ov5640_i2c_driver);
+
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("OV5640 Camera Driver");
+MODULE_LICENSE("GPL");
+MODULE_VERSION("1.0");
+MODULE_ALIAS("CSI");
diff --git a/drivers/media/platform/mxc/capture/ov5642.c b/drivers/media/platform/mxc/capture/ov5642.c
new file mode 100644
index 000000000000..be6122205c18
--- /dev/null
+++ b/drivers/media/platform/mxc/capture/ov5642.c
@@ -0,0 +1,4252 @@
+/*
+ * Copyright (C) 2012-2014 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/ctype.h>
+#include <linux/types.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/of_device.h>
+#include <linux/i2c.h>
+#include <linux/of_gpio.h>
+#include <linux/pinctrl/consumer.h>
+#include <linux/regulator/consumer.h>
+#include <linux/fsl_devices.h>
+#include <media/v4l2-chip-ident.h>
+#include "v4l2-int-device.h"
+#include "mxc_v4l2_capture.h"
+
+#define OV5642_VOLTAGE_ANALOG 2800000
+#define OV5642_VOLTAGE_DIGITAL_CORE 1500000
+#define OV5642_VOLTAGE_DIGITAL_IO 1800000
+
+#define MIN_FPS 15
+#define MAX_FPS 30
+#define DEFAULT_FPS 30
+
+#define OV5642_XCLK_MIN 6000000
+#define OV5642_XCLK_MAX 24000000
+
+#define OV5642_CHIP_ID_HIGH_BYTE 0x300A
+#define OV5642_CHIP_ID_LOW_BYTE 0x300B
+
+enum ov5642_mode {
+ ov5642_mode_MIN = 0,
+ ov5642_mode_VGA_640_480 = 0,
+ ov5642_mode_QVGA_320_240 = 1,
+ ov5642_mode_NTSC_720_480 = 2,
+ ov5642_mode_PAL_720_576 = 3,
+ ov5642_mode_720P_1280_720 = 4,
+ ov5642_mode_1080P_1920_1080 = 5,
+ ov5642_mode_QSXGA_2592_1944 = 6,
+ ov5642_mode_QCIF_176_144 = 7,
+ ov5642_mode_XGA_1024_768 = 8,
+ ov5642_mode_MAX = 8
+};
+
+enum ov5642_frame_rate {
+ ov5642_15_fps,
+ ov5642_30_fps
+};
+
+static int ov5642_framerates[] = {
+ [ov5642_15_fps] = 15,
+ [ov5642_30_fps] = 30,
+};
+
+struct reg_value {
+ u16 u16RegAddr;
+ u8 u8Val;
+ u8 u8Mask;
+ u32 u32Delay_ms;
+};
+
+struct ov5642_mode_info {
+ enum ov5642_mode mode;
+ u32 width;
+ u32 height;
+ struct reg_value *init_data_ptr;
+ u32 init_data_size;
+};
+
+/*!
+ * Maintains the information on the current state of the sesor.
+ */
+static struct sensor_data ov5642_data;
+static int pwn_gpio, rst_gpio;
+
+static struct reg_value ov5642_rot_none_VGA[] = {
+ {0x3818, 0xc1, 0x00, 0x00}, {0x3621, 0x87, 0x00, 0x00},
+};
+
+static struct reg_value ov5642_rot_vert_flip_VGA[] = {
+ {0x3818, 0x20, 0xbf, 0x00}, {0x3621, 0x20, 0xff, 0x00},
+};
+
+static struct reg_value ov5642_rot_horiz_flip_VGA[] = {
+ {0x3818, 0x81, 0x00, 0x01}, {0x3621, 0xa7, 0x00, 0x00},
+};
+
+static struct reg_value ov5642_rot_180_VGA[] = {
+ {0x3818, 0x60, 0xff, 0x00}, {0x3621, 0x00, 0xdf, 0x00},
+};
+
+
+static struct reg_value ov5642_rot_none_FULL[] = {
+ {0x3818, 0xc0, 0x00, 0x00}, {0x3621, 0x09, 0x00, 0x00},
+};
+
+static struct reg_value ov5642_rot_vert_flip_FULL[] = {
+ {0x3818, 0x20, 0xbf, 0x01}, {0x3621, 0x20, 0xff, 0x00},
+};
+
+static struct reg_value ov5642_rot_horiz_flip_FULL[] = {
+ {0x3818, 0x80, 0x00, 0x01}, {0x3621, 0x29, 0x00, 0x00},
+};
+
+static struct reg_value ov5642_rot_180_FULL[] = {
+ {0x3818, 0x60, 0xff, 0x00}, {0x3621, 0x00, 0xdf, 0x00},
+};
+
+
+static struct reg_value ov5642_initial_setting[] = {
+ {0x3103, 0x93, 0, 0}, {0x3008, 0x82, 0, 0}, {0x3017, 0x7f, 0, 0},
+ {0x3018, 0xfc, 0, 0}, {0x3810, 0xc2, 0, 0}, {0x3615, 0xf0, 0, 0},
+ {0x3000, 0x00, 0, 0}, {0x3001, 0x00, 0, 0}, {0x3002, 0x5c, 0, 0},
+ {0x3003, 0x00, 0, 0}, {0x3004, 0xff, 0, 0}, {0x3005, 0xff, 0, 0},
+ {0x3006, 0x43, 0, 0}, {0x3007, 0x37, 0, 0}, {0x3011, 0x08, 0, 0},
+ {0x3010, 0x00, 0, 0}, {0x460c, 0x22, 0, 0}, {0x3815, 0x04, 0, 0},
+ {0x370c, 0xa0, 0, 0}, {0x3602, 0xfc, 0, 0}, {0x3612, 0xff, 0, 0},
+ {0x3634, 0xc0, 0, 0}, {0x3613, 0x00, 0, 0}, {0x3605, 0x7c, 0, 0},
+ {0x3621, 0x09, 0, 0}, {0x3622, 0x60, 0, 0}, {0x3604, 0x40, 0, 0},
+ {0x3603, 0xa7, 0, 0}, {0x3603, 0x27, 0, 0}, {0x4000, 0x21, 0, 0},
+ {0x401d, 0x22, 0, 0}, {0x3600, 0x54, 0, 0}, {0x3605, 0x04, 0, 0},
+ {0x3606, 0x3f, 0, 0}, {0x3c00, 0x04, 0, 0}, {0x3c01, 0x80, 0, 0},
+ {0x5000, 0x4f, 0, 0}, {0x5020, 0x04, 0, 0}, {0x5181, 0x79, 0, 0},
+ {0x5182, 0x00, 0, 0}, {0x5185, 0x22, 0, 0}, {0x5197, 0x01, 0, 0},
+ {0x5001, 0xff, 0, 0}, {0x5500, 0x0a, 0, 0}, {0x5504, 0x00, 0, 0},
+ {0x5505, 0x7f, 0, 0}, {0x5080, 0x08, 0, 0}, {0x300e, 0x18, 0, 0},
+ {0x4610, 0x00, 0, 0}, {0x471d, 0x05, 0, 0}, {0x4708, 0x06, 0, 0},
+ {0x3808, 0x02, 0, 0}, {0x3809, 0x80, 0, 0}, {0x380a, 0x01, 0, 0},
+ {0x380b, 0xe0, 0, 0}, {0x380e, 0x07, 0, 0}, {0x380f, 0xd0, 0, 0},
+ {0x501f, 0x00, 0, 0}, {0x5000, 0x4f, 0, 0}, {0x4300, 0x30, 0, 0},
+ {0x3503, 0x07, 0, 0}, {0x3501, 0x73, 0, 0}, {0x3502, 0x80, 0, 0},
+ {0x350b, 0x00, 0, 0}, {0x3503, 0x07, 0, 0}, {0x3824, 0x11, 0, 0},
+ {0x3501, 0x1e, 0, 0}, {0x3502, 0x80, 0, 0}, {0x350b, 0x7f, 0, 0},
+ {0x380c, 0x0c, 0, 0}, {0x380d, 0x80, 0, 0}, {0x380e, 0x03, 0, 0},
+ {0x380f, 0xe8, 0, 0}, {0x3a0d, 0x04, 0, 0}, {0x3a0e, 0x03, 0, 0},
+ {0x3818, 0xc1, 0, 0}, {0x3705, 0xdb, 0, 0}, {0x370a, 0x81, 0, 0},
+ {0x3801, 0x80, 0, 0}, {0x3621, 0x87, 0, 0}, {0x3801, 0x50, 0, 0},
+ {0x3803, 0x08, 0, 0}, {0x3827, 0x08, 0, 0}, {0x3810, 0x40, 0, 0},
+ {0x3804, 0x05, 0, 0}, {0x3805, 0x00, 0, 0}, {0x5682, 0x05, 0, 0},
+ {0x5683, 0x00, 0, 0}, {0x3806, 0x03, 0, 0}, {0x3807, 0xc0, 0, 0},
+ {0x5686, 0x03, 0, 0}, {0x5687, 0xbc, 0, 0}, {0x3a00, 0x78, 0, 0},
+ {0x3a1a, 0x05, 0, 0}, {0x3a13, 0x30, 0, 0}, {0x3a18, 0x00, 0, 0},
+ {0x3a19, 0x7c, 0, 0}, {0x3a08, 0x12, 0, 0}, {0x3a09, 0xc0, 0, 0},
+ {0x3a0a, 0x0f, 0, 0}, {0x3a0b, 0xa0, 0, 0}, {0x350c, 0x07, 0, 0},
+ {0x350d, 0xd0, 0, 0}, {0x3500, 0x00, 0, 0}, {0x3501, 0x00, 0, 0},
+ {0x3502, 0x00, 0, 0}, {0x350a, 0x00, 0, 0}, {0x350b, 0x00, 0, 0},
+ {0x3503, 0x00, 0, 0}, {0x528a, 0x02, 0, 0}, {0x528b, 0x04, 0, 0},
+ {0x528c, 0x08, 0, 0}, {0x528d, 0x08, 0, 0}, {0x528e, 0x08, 0, 0},
+ {0x528f, 0x10, 0, 0}, {0x5290, 0x10, 0, 0}, {0x5292, 0x00, 0, 0},
+ {0x5293, 0x02, 0, 0}, {0x5294, 0x00, 0, 0}, {0x5295, 0x02, 0, 0},
+ {0x5296, 0x00, 0, 0}, {0x5297, 0x02, 0, 0}, {0x5298, 0x00, 0, 0},
+ {0x5299, 0x02, 0, 0}, {0x529a, 0x00, 0, 0}, {0x529b, 0x02, 0, 0},
+ {0x529c, 0x00, 0, 0}, {0x529d, 0x02, 0, 0}, {0x529e, 0x00, 0, 0},
+ {0x529f, 0x02, 0, 0}, {0x3a0f, 0x3c, 0, 0}, {0x3a10, 0x30, 0, 0},
+ {0x3a1b, 0x3c, 0, 0}, {0x3a1e, 0x30, 0, 0}, {0x3a11, 0x70, 0, 0},
+ {0x3a1f, 0x10, 0, 0}, {0x3030, 0x0b, 0, 0}, {0x3a02, 0x00, 0, 0},
+ {0x3a03, 0x7d, 0, 0}, {0x3a04, 0x00, 0, 0}, {0x3a14, 0x00, 0, 0},
+ {0x3a15, 0x7d, 0, 0}, {0x3a16, 0x00, 0, 0}, {0x3a00, 0x78, 0, 0},
+ {0x5193, 0x70, 0, 0}, {0x589b, 0x04, 0, 0}, {0x589a, 0xc5, 0, 0},
+ {0x401e, 0x20, 0, 0}, {0x4001, 0x42, 0, 0}, {0x401c, 0x04, 0, 0},
+ {0x528a, 0x01, 0, 0}, {0x528b, 0x04, 0, 0}, {0x528c, 0x08, 0, 0},
+ {0x528d, 0x10, 0, 0}, {0x528e, 0x20, 0, 0}, {0x528f, 0x28, 0, 0},
+ {0x5290, 0x30, 0, 0}, {0x5292, 0x00, 0, 0}, {0x5293, 0x01, 0, 0},
+ {0x5294, 0x00, 0, 0}, {0x5295, 0x04, 0, 0}, {0x5296, 0x00, 0, 0},
+ {0x5297, 0x08, 0, 0}, {0x5298, 0x00, 0, 0}, {0x5299, 0x10, 0, 0},
+ {0x529a, 0x00, 0, 0}, {0x529b, 0x20, 0, 0}, {0x529c, 0x00, 0, 0},
+ {0x529d, 0x28, 0, 0}, {0x529e, 0x00, 0, 0}, {0x529f, 0x30, 0, 0},
+ {0x5282, 0x00, 0, 0}, {0x5300, 0x00, 0, 0}, {0x5301, 0x20, 0, 0},
+ {0x5302, 0x00, 0, 0}, {0x5303, 0x7c, 0, 0}, {0x530c, 0x00, 0, 0},
+ {0x530d, 0x0c, 0, 0}, {0x530e, 0x20, 0, 0}, {0x530f, 0x80, 0, 0},
+ {0x5310, 0x20, 0, 0}, {0x5311, 0x80, 0, 0}, {0x5308, 0x20, 0, 0},
+ {0x5309, 0x40, 0, 0}, {0x5304, 0x00, 0, 0}, {0x5305, 0x30, 0, 0},
+ {0x5306, 0x00, 0, 0}, {0x5307, 0x80, 0, 0}, {0x5314, 0x08, 0, 0},
+ {0x5315, 0x20, 0, 0}, {0x5319, 0x30, 0, 0}, {0x5316, 0x10, 0, 0},
+ {0x5317, 0x00, 0, 0}, {0x5318, 0x02, 0, 0}, {0x5380, 0x01, 0, 0},
+ {0x5381, 0x00, 0, 0}, {0x5382, 0x00, 0, 0}, {0x5383, 0x4e, 0, 0},
+ {0x5384, 0x00, 0, 0}, {0x5385, 0x0f, 0, 0}, {0x5386, 0x00, 0, 0},
+ {0x5387, 0x00, 0, 0}, {0x5388, 0x01, 0, 0}, {0x5389, 0x15, 0, 0},
+ {0x538a, 0x00, 0, 0}, {0x538b, 0x31, 0, 0}, {0x538c, 0x00, 0, 0},
+ {0x538d, 0x00, 0, 0}, {0x538e, 0x00, 0, 0}, {0x538f, 0x0f, 0, 0},
+ {0x5390, 0x00, 0, 0}, {0x5391, 0xab, 0, 0}, {0x5392, 0x00, 0, 0},
+ {0x5393, 0xa2, 0, 0}, {0x5394, 0x08, 0, 0}, {0x5480, 0x14, 0, 0},
+ {0x5481, 0x21, 0, 0}, {0x5482, 0x36, 0, 0}, {0x5483, 0x57, 0, 0},
+ {0x5484, 0x65, 0, 0}, {0x5485, 0x71, 0, 0}, {0x5486, 0x7d, 0, 0},
+ {0x5487, 0x87, 0, 0}, {0x5488, 0x91, 0, 0}, {0x5489, 0x9a, 0, 0},
+ {0x548a, 0xaa, 0, 0}, {0x548b, 0xb8, 0, 0}, {0x548c, 0xcd, 0, 0},
+ {0x548d, 0xdd, 0, 0}, {0x548e, 0xea, 0, 0}, {0x548f, 0x1d, 0, 0},
+ {0x5490, 0x05, 0, 0}, {0x5491, 0x00, 0, 0}, {0x5492, 0x04, 0, 0},
+ {0x5493, 0x20, 0, 0}, {0x5494, 0x03, 0, 0}, {0x5495, 0x60, 0, 0},
+ {0x5496, 0x02, 0, 0}, {0x5497, 0xb8, 0, 0}, {0x5498, 0x02, 0, 0},
+ {0x5499, 0x86, 0, 0}, {0x549a, 0x02, 0, 0}, {0x549b, 0x5b, 0, 0},
+ {0x549c, 0x02, 0, 0}, {0x549d, 0x3b, 0, 0}, {0x549e, 0x02, 0, 0},
+ {0x549f, 0x1c, 0, 0}, {0x54a0, 0x02, 0, 0}, {0x54a1, 0x04, 0, 0},
+ {0x54a2, 0x01, 0, 0}, {0x54a3, 0xed, 0, 0}, {0x54a4, 0x01, 0, 0},
+ {0x54a5, 0xc5, 0, 0}, {0x54a6, 0x01, 0, 0}, {0x54a7, 0xa5, 0, 0},
+ {0x54a8, 0x01, 0, 0}, {0x54a9, 0x6c, 0, 0}, {0x54aa, 0x01, 0, 0},
+ {0x54ab, 0x41, 0, 0}, {0x54ac, 0x01, 0, 0}, {0x54ad, 0x20, 0, 0},
+ {0x54ae, 0x00, 0, 0}, {0x54af, 0x16, 0, 0}, {0x54b0, 0x01, 0, 0},
+ {0x54b1, 0x20, 0, 0}, {0x54b2, 0x00, 0, 0}, {0x54b3, 0x10, 0, 0},
+ {0x54b4, 0x00, 0, 0}, {0x54b5, 0xf0, 0, 0}, {0x54b6, 0x00, 0, 0},
+ {0x54b7, 0xdf, 0, 0}, {0x5402, 0x3f, 0, 0}, {0x5403, 0x00, 0, 0},
+ {0x3406, 0x00, 0, 0}, {0x5180, 0xff, 0, 0}, {0x5181, 0x52, 0, 0},
+ {0x5182, 0x11, 0, 0}, {0x5183, 0x14, 0, 0}, {0x5184, 0x25, 0, 0},
+ {0x5185, 0x24, 0, 0}, {0x5186, 0x06, 0, 0}, {0x5187, 0x08, 0, 0},
+ {0x5188, 0x08, 0, 0}, {0x5189, 0x7c, 0, 0}, {0x518a, 0x60, 0, 0},
+ {0x518b, 0xb2, 0, 0}, {0x518c, 0xb2, 0, 0}, {0x518d, 0x44, 0, 0},
+ {0x518e, 0x3d, 0, 0}, {0x518f, 0x58, 0, 0}, {0x5190, 0x46, 0, 0},
+ {0x5191, 0xf8, 0, 0}, {0x5192, 0x04, 0, 0}, {0x5193, 0x70, 0, 0},
+ {0x5194, 0xf0, 0, 0}, {0x5195, 0xf0, 0, 0}, {0x5196, 0x03, 0, 0},
+ {0x5197, 0x01, 0, 0}, {0x5198, 0x04, 0, 0}, {0x5199, 0x12, 0, 0},
+ {0x519a, 0x04, 0, 0}, {0x519b, 0x00, 0, 0}, {0x519c, 0x06, 0, 0},
+ {0x519d, 0x82, 0, 0}, {0x519e, 0x00, 0, 0}, {0x5025, 0x80, 0, 0},
+ {0x3a0f, 0x38, 0, 0}, {0x3a10, 0x30, 0, 0}, {0x3a1b, 0x3a, 0, 0},
+ {0x3a1e, 0x2e, 0, 0}, {0x3a11, 0x60, 0, 0}, {0x3a1f, 0x10, 0, 0},
+ {0x5688, 0xa6, 0, 0}, {0x5689, 0x6a, 0, 0}, {0x568a, 0xea, 0, 0},
+ {0x568b, 0xae, 0, 0}, {0x568c, 0xa6, 0, 0}, {0x568d, 0x6a, 0, 0},
+ {0x568e, 0x62, 0, 0}, {0x568f, 0x26, 0, 0}, {0x5583, 0x40, 0, 0},
+ {0x5584, 0x40, 0, 0}, {0x5580, 0x02, 0, 0}, {0x5000, 0xcf, 0, 0},
+ {0x5800, 0x27, 0, 0}, {0x5801, 0x19, 0, 0}, {0x5802, 0x12, 0, 0},
+ {0x5803, 0x0f, 0, 0}, {0x5804, 0x10, 0, 0}, {0x5805, 0x15, 0, 0},
+ {0x5806, 0x1e, 0, 0}, {0x5807, 0x2f, 0, 0}, {0x5808, 0x15, 0, 0},
+ {0x5809, 0x0d, 0, 0}, {0x580a, 0x0a, 0, 0}, {0x580b, 0x09, 0, 0},
+ {0x580c, 0x0a, 0, 0}, {0x580d, 0x0c, 0, 0}, {0x580e, 0x12, 0, 0},
+ {0x580f, 0x19, 0, 0}, {0x5810, 0x0b, 0, 0}, {0x5811, 0x07, 0, 0},
+ {0x5812, 0x04, 0, 0}, {0x5813, 0x03, 0, 0}, {0x5814, 0x03, 0, 0},
+ {0x5815, 0x06, 0, 0}, {0x5816, 0x0a, 0, 0}, {0x5817, 0x0f, 0, 0},
+ {0x5818, 0x0a, 0, 0}, {0x5819, 0x05, 0, 0}, {0x581a, 0x01, 0, 0},
+ {0x581b, 0x00, 0, 0}, {0x581c, 0x00, 0, 0}, {0x581d, 0x03, 0, 0},
+ {0x581e, 0x08, 0, 0}, {0x581f, 0x0c, 0, 0}, {0x5820, 0x0a, 0, 0},
+ {0x5821, 0x05, 0, 0}, {0x5822, 0x01, 0, 0}, {0x5823, 0x00, 0, 0},
+ {0x5824, 0x00, 0, 0}, {0x5825, 0x03, 0, 0}, {0x5826, 0x08, 0, 0},
+ {0x5827, 0x0c, 0, 0}, {0x5828, 0x0e, 0, 0}, {0x5829, 0x08, 0, 0},
+ {0x582a, 0x06, 0, 0}, {0x582b, 0x04, 0, 0}, {0x582c, 0x05, 0, 0},
+ {0x582d, 0x07, 0, 0}, {0x582e, 0x0b, 0, 0}, {0x582f, 0x12, 0, 0},
+ {0x5830, 0x18, 0, 0}, {0x5831, 0x10, 0, 0}, {0x5832, 0x0c, 0, 0},
+ {0x5833, 0x0a, 0, 0}, {0x5834, 0x0b, 0, 0}, {0x5835, 0x0e, 0, 0},
+ {0x5836, 0x15, 0, 0}, {0x5837, 0x19, 0, 0}, {0x5838, 0x32, 0, 0},
+ {0x5839, 0x1f, 0, 0}, {0x583a, 0x18, 0, 0}, {0x583b, 0x16, 0, 0},
+ {0x583c, 0x17, 0, 0}, {0x583d, 0x1e, 0, 0}, {0x583e, 0x26, 0, 0},
+ {0x583f, 0x53, 0, 0}, {0x5840, 0x10, 0, 0}, {0x5841, 0x0f, 0, 0},
+ {0x5842, 0x0d, 0, 0}, {0x5843, 0x0c, 0, 0}, {0x5844, 0x0e, 0, 0},
+ {0x5845, 0x09, 0, 0}, {0x5846, 0x11, 0, 0}, {0x5847, 0x10, 0, 0},
+ {0x5848, 0x10, 0, 0}, {0x5849, 0x10, 0, 0}, {0x584a, 0x10, 0, 0},
+ {0x584b, 0x0e, 0, 0}, {0x584c, 0x10, 0, 0}, {0x584d, 0x10, 0, 0},
+ {0x584e, 0x11, 0, 0}, {0x584f, 0x10, 0, 0}, {0x5850, 0x0f, 0, 0},
+ {0x5851, 0x0c, 0, 0}, {0x5852, 0x0f, 0, 0}, {0x5853, 0x10, 0, 0},
+ {0x5854, 0x10, 0, 0}, {0x5855, 0x0f, 0, 0}, {0x5856, 0x0e, 0, 0},
+ {0x5857, 0x0b, 0, 0}, {0x5858, 0x10, 0, 0}, {0x5859, 0x0d, 0, 0},
+ {0x585a, 0x0d, 0, 0}, {0x585b, 0x0c, 0, 0}, {0x585c, 0x0c, 0, 0},
+ {0x585d, 0x0c, 0, 0}, {0x585e, 0x0b, 0, 0}, {0x585f, 0x0c, 0, 0},
+ {0x5860, 0x0c, 0, 0}, {0x5861, 0x0c, 0, 0}, {0x5862, 0x0d, 0, 0},
+ {0x5863, 0x08, 0, 0}, {0x5864, 0x11, 0, 0}, {0x5865, 0x18, 0, 0},
+ {0x5866, 0x18, 0, 0}, {0x5867, 0x19, 0, 0}, {0x5868, 0x17, 0, 0},
+ {0x5869, 0x19, 0, 0}, {0x586a, 0x16, 0, 0}, {0x586b, 0x13, 0, 0},
+ {0x586c, 0x13, 0, 0}, {0x586d, 0x12, 0, 0}, {0x586e, 0x13, 0, 0},
+ {0x586f, 0x16, 0, 0}, {0x5870, 0x14, 0, 0}, {0x5871, 0x12, 0, 0},
+ {0x5872, 0x10, 0, 0}, {0x5873, 0x11, 0, 0}, {0x5874, 0x11, 0, 0},
+ {0x5875, 0x16, 0, 0}, {0x5876, 0x14, 0, 0}, {0x5877, 0x11, 0, 0},
+ {0x5878, 0x10, 0, 0}, {0x5879, 0x0f, 0, 0}, {0x587a, 0x10, 0, 0},
+ {0x587b, 0x14, 0, 0}, {0x587c, 0x13, 0, 0}, {0x587d, 0x12, 0, 0},
+ {0x587e, 0x11, 0, 0}, {0x587f, 0x11, 0, 0}, {0x5880, 0x12, 0, 0},
+ {0x5881, 0x15, 0, 0}, {0x5882, 0x14, 0, 0}, {0x5883, 0x15, 0, 0},
+ {0x5884, 0x15, 0, 0}, {0x5885, 0x15, 0, 0}, {0x5886, 0x13, 0, 0},
+ {0x5887, 0x17, 0, 0}, {0x3710, 0x10, 0, 0}, {0x3632, 0x51, 0, 0},
+ {0x3702, 0x10, 0, 0}, {0x3703, 0xb2, 0, 0}, {0x3704, 0x18, 0, 0},
+ {0x370b, 0x40, 0, 0}, {0x370d, 0x03, 0, 0}, {0x3631, 0x01, 0, 0},
+ {0x3632, 0x52, 0, 0}, {0x3606, 0x24, 0, 0}, {0x3620, 0x96, 0, 0},
+ {0x5785, 0x07, 0, 0}, {0x3a13, 0x30, 0, 0}, {0x3600, 0x52, 0, 0},
+ {0x3604, 0x48, 0, 0}, {0x3606, 0x1b, 0, 0}, {0x370d, 0x0b, 0, 0},
+ {0x370f, 0xc0, 0, 0}, {0x3709, 0x01, 0, 0}, {0x3823, 0x00, 0, 0},
+ {0x5007, 0x00, 0, 0}, {0x5009, 0x00, 0, 0}, {0x5011, 0x00, 0, 0},
+ {0x5013, 0x00, 0, 0}, {0x519e, 0x00, 0, 0}, {0x5086, 0x00, 0, 0},
+ {0x5087, 0x00, 0, 0}, {0x5088, 0x00, 0, 0}, {0x5089, 0x00, 0, 0},
+ {0x302b, 0x00, 0, 300},
+};
+
+static struct reg_value ov5642_setting_15fps_QCIF_176_144[] = {
+ {0x3103, 0x93, 0, 0}, {0x3008, 0x82, 0, 0}, {0x3017, 0x7f, 0, 0},
+ {0x3018, 0xfc, 0, 0}, {0x3810, 0xc2, 0, 0}, {0x3615, 0xf0, 0, 0},
+ {0x3000, 0x00, 0, 0}, {0x3001, 0x00, 0, 0}, {0x3002, 0x5c, 0, 0},
+ {0x3003, 0x00, 0, 0}, {0x3004, 0xff, 0, 0}, {0x3005, 0xff, 0, 0},
+ {0x3006, 0x43, 0, 0}, {0x3007, 0x37, 0, 0}, {0x3011, 0x08, 0, 0},
+ {0x3010, 0x10, 0, 0}, {0x460c, 0x22, 0, 0}, {0x3815, 0x04, 0, 0},
+ {0x370c, 0xa0, 0, 0}, {0x3602, 0xfc, 0, 0}, {0x3612, 0xff, 0, 0},
+ {0x3634, 0xc0, 0, 0}, {0x3613, 0x00, 0, 0}, {0x3605, 0x7c, 0, 0},
+ {0x3621, 0x09, 0, 0}, {0x3622, 0x60, 0, 0}, {0x3604, 0x40, 0, 0},
+ {0x3603, 0xa7, 0, 0}, {0x3603, 0x27, 0, 0}, {0x4000, 0x21, 0, 0},
+ {0x401d, 0x22, 0, 0}, {0x3600, 0x54, 0, 0}, {0x3605, 0x04, 0, 0},
+ {0x3606, 0x3f, 0, 0}, {0x3c01, 0x80, 0, 0}, {0x5000, 0x4f, 0, 0},
+ {0x5020, 0x04, 0, 0}, {0x5181, 0x79, 0, 0}, {0x5182, 0x00, 0, 0},
+ {0x5185, 0x22, 0, 0}, {0x5197, 0x01, 0, 0}, {0x5001, 0xff, 0, 0},
+ {0x5500, 0x0a, 0, 0}, {0x5504, 0x00, 0, 0}, {0x5505, 0x7f, 0, 0},
+ {0x5080, 0x08, 0, 0}, {0x300e, 0x18, 0, 0}, {0x4610, 0x00, 0, 0},
+ {0x471d, 0x05, 0, 0}, {0x4708, 0x06, 0, 0}, {0x3808, 0x02, 0, 0},
+ {0x3809, 0x80, 0, 0}, {0x380a, 0x01, 0, 0}, {0x380b, 0xe0, 0, 0},
+ {0x380e, 0x07, 0, 0}, {0x380f, 0xd0, 0, 0}, {0x501f, 0x00, 0, 0},
+ {0x5000, 0x4f, 0, 0}, {0x4300, 0x30, 0, 0}, {0x3503, 0x07, 0, 0},
+ {0x3501, 0x73, 0, 0}, {0x3502, 0x80, 0, 0}, {0x350b, 0x00, 0, 0},
+ {0x3503, 0x07, 0, 0}, {0x3824, 0x11, 0, 0}, {0x3501, 0x1e, 0, 0},
+ {0x3502, 0x80, 0, 0}, {0x350b, 0x7f, 0, 0}, {0x380c, 0x0c, 0, 0},
+ {0x380d, 0x80, 0, 0}, {0x380e, 0x03, 0, 0}, {0x380f, 0xe8, 0, 0},
+ {0x3a0d, 0x04, 0, 0}, {0x3a0e, 0x03, 0, 0}, {0x3818, 0xc1, 0, 0},
+ {0x3705, 0xdb, 0, 0}, {0x370a, 0x81, 0, 0}, {0x3801, 0x80, 0, 0},
+ {0x3621, 0x87, 0, 0}, {0x3801, 0x50, 0, 0}, {0x3803, 0x08, 0, 0},
+ {0x3827, 0x08, 0, 0}, {0x3810, 0x40, 0, 0}, {0x3804, 0x05, 0, 0},
+ {0x3805, 0x00, 0, 0}, {0x5682, 0x05, 0, 0}, {0x5683, 0x00, 0, 0},
+ {0x3806, 0x03, 0, 0}, {0x3807, 0xc0, 0, 0}, {0x5686, 0x03, 0, 0},
+ {0x5687, 0xbc, 0, 0}, {0x3a00, 0x78, 0, 0}, {0x3a1a, 0x05, 0, 0},
+ {0x3a13, 0x30, 0, 0}, {0x3a18, 0x00, 0, 0}, {0x3a19, 0x7c, 0, 0},
+ {0x3a08, 0x12, 0, 0}, {0x3a09, 0xc0, 0, 0}, {0x3a0a, 0x0f, 0, 0},
+ {0x3a0b, 0xa0, 0, 0}, {0x350c, 0x07, 0, 0}, {0x350d, 0xd0, 0, 0},
+ {0x3500, 0x00, 0, 0}, {0x3501, 0x00, 0, 0}, {0x3502, 0x00, 0, 0},
+ {0x350a, 0x00, 0, 0}, {0x350b, 0x00, 0, 0}, {0x3503, 0x00, 0, 0},
+ {0x528a, 0x02, 0, 0}, {0x528b, 0x04, 0, 0}, {0x528c, 0x08, 0, 0},
+ {0x528d, 0x08, 0, 0}, {0x528e, 0x08, 0, 0}, {0x528f, 0x10, 0, 0},
+ {0x5290, 0x10, 0, 0}, {0x5292, 0x00, 0, 0}, {0x5293, 0x02, 0, 0},
+ {0x5294, 0x00, 0, 0}, {0x5295, 0x02, 0, 0}, {0x5296, 0x00, 0, 0},
+ {0x5297, 0x02, 0, 0}, {0x5298, 0x00, 0, 0}, {0x5299, 0x02, 0, 0},
+ {0x529a, 0x00, 0, 0}, {0x529b, 0x02, 0, 0}, {0x529c, 0x00, 0, 0},
+ {0x529d, 0x02, 0, 0}, {0x529e, 0x00, 0, 0}, {0x529f, 0x02, 0, 0},
+ {0x3a0f, 0x3c, 0, 0}, {0x3a10, 0x30, 0, 0}, {0x3a1b, 0x3c, 0, 0},
+ {0x3a1e, 0x30, 0, 0}, {0x3a11, 0x70, 0, 0}, {0x3a1f, 0x10, 0, 0},
+ {0x3030, 0x2b, 0, 0}, {0x3a02, 0x00, 0, 0}, {0x3a03, 0x7d, 0, 0},
+ {0x3a04, 0x00, 0, 0}, {0x3a14, 0x00, 0, 0}, {0x3a15, 0x7d, 0, 0},
+ {0x3a16, 0x00, 0, 0}, {0x3a00, 0x78, 0, 0}, {0x3a08, 0x09, 0, 0},
+ {0x3a09, 0x60, 0, 0}, {0x3a0a, 0x07, 0, 0}, {0x3a0b, 0xd0, 0, 0},
+ {0x3a0d, 0x08, 0, 0}, {0x3a0e, 0x06, 0, 0}, {0x5193, 0x70, 0, 0},
+ {0x589b, 0x04, 0, 0}, {0x589a, 0xc5, 0, 0}, {0x401e, 0x20, 0, 0},
+ {0x4001, 0x42, 0, 0}, {0x401c, 0x04, 0, 0}, {0x528a, 0x01, 0, 0},
+ {0x528b, 0x04, 0, 0}, {0x528c, 0x08, 0, 0}, {0x528d, 0x10, 0, 0},
+ {0x528e, 0x20, 0, 0}, {0x528f, 0x28, 0, 0}, {0x5290, 0x30, 0, 0},
+ {0x5292, 0x00, 0, 0}, {0x5293, 0x01, 0, 0}, {0x5294, 0x00, 0, 0},
+ {0x5295, 0x04, 0, 0}, {0x5296, 0x00, 0, 0}, {0x5297, 0x08, 0, 0},
+ {0x5298, 0x00, 0, 0}, {0x5299, 0x10, 0, 0}, {0x529a, 0x00, 0, 0},
+ {0x529b, 0x20, 0, 0}, {0x529c, 0x00, 0, 0}, {0x529d, 0x28, 0, 0},
+ {0x529e, 0x00, 0, 0}, {0x529f, 0x30, 0, 0}, {0x5282, 0x00, 0, 0},
+ {0x5300, 0x00, 0, 0}, {0x5301, 0x20, 0, 0}, {0x5302, 0x00, 0, 0},
+ {0x5303, 0x7c, 0, 0}, {0x530c, 0x00, 0, 0}, {0x530d, 0x0c, 0, 0},
+ {0x530e, 0x20, 0, 0}, {0x530f, 0x80, 0, 0}, {0x5310, 0x20, 0, 0},
+ {0x5311, 0x80, 0, 0}, {0x5308, 0x20, 0, 0}, {0x5309, 0x40, 0, 0},
+ {0x5304, 0x00, 0, 0}, {0x5305, 0x30, 0, 0}, {0x5306, 0x00, 0, 0},
+ {0x5307, 0x80, 0, 0}, {0x5314, 0x08, 0, 0}, {0x5315, 0x20, 0, 0},
+ {0x5319, 0x30, 0, 0}, {0x5316, 0x10, 0, 0}, {0x5317, 0x00, 0, 0},
+ {0x5318, 0x02, 0, 0}, {0x5380, 0x01, 0, 0}, {0x5381, 0x00, 0, 0},
+ {0x5382, 0x00, 0, 0}, {0x5383, 0x4e, 0, 0}, {0x5384, 0x00, 0, 0},
+ {0x5385, 0x0f, 0, 0}, {0x5386, 0x00, 0, 0}, {0x5387, 0x00, 0, 0},
+ {0x5388, 0x01, 0, 0}, {0x5389, 0x15, 0, 0}, {0x538a, 0x00, 0, 0},
+ {0x538b, 0x31, 0, 0}, {0x538c, 0x00, 0, 0}, {0x538d, 0x00, 0, 0},
+ {0x538e, 0x00, 0, 0}, {0x538f, 0x0f, 0, 0}, {0x5390, 0x00, 0, 0},
+ {0x5391, 0xab, 0, 0}, {0x5392, 0x00, 0, 0}, {0x5393, 0xa2, 0, 0},
+ {0x5394, 0x08, 0, 0}, {0x5480, 0x14, 0, 0}, {0x5481, 0x21, 0, 0},
+ {0x5482, 0x36, 0, 0}, {0x5483, 0x57, 0, 0}, {0x5484, 0x65, 0, 0},
+ {0x5485, 0x71, 0, 0}, {0x5486, 0x7d, 0, 0}, {0x5487, 0x87, 0, 0},
+ {0x5488, 0x91, 0, 0}, {0x5489, 0x9a, 0, 0}, {0x548a, 0xaa, 0, 0},
+ {0x548b, 0xb8, 0, 0}, {0x548c, 0xcd, 0, 0}, {0x548d, 0xdd, 0, 0},
+ {0x548e, 0xea, 0, 0}, {0x548f, 0x1d, 0, 0}, {0x5490, 0x05, 0, 0},
+ {0x5491, 0x00, 0, 0}, {0x5492, 0x04, 0, 0}, {0x5493, 0x20, 0, 0},
+ {0x5494, 0x03, 0, 0}, {0x5495, 0x60, 0, 0}, {0x5496, 0x02, 0, 0},
+ {0x5497, 0xb8, 0, 0}, {0x5498, 0x02, 0, 0}, {0x5499, 0x86, 0, 0},
+ {0x549a, 0x02, 0, 0}, {0x549b, 0x5b, 0, 0}, {0x549c, 0x02, 0, 0},
+ {0x549d, 0x3b, 0, 0}, {0x549e, 0x02, 0, 0}, {0x549f, 0x1c, 0, 0},
+ {0x54a0, 0x02, 0, 0}, {0x54a1, 0x04, 0, 0}, {0x54a2, 0x01, 0, 0},
+ {0x54a3, 0xed, 0, 0}, {0x54a4, 0x01, 0, 0}, {0x54a5, 0xc5, 0, 0},
+ {0x54a6, 0x01, 0, 0}, {0x54a7, 0xa5, 0, 0}, {0x54a8, 0x01, 0, 0},
+ {0x54a9, 0x6c, 0, 0}, {0x54aa, 0x01, 0, 0}, {0x54ab, 0x41, 0, 0},
+ {0x54ac, 0x01, 0, 0}, {0x54ad, 0x20, 0, 0}, {0x54ae, 0x00, 0, 0},
+ {0x54af, 0x16, 0, 0}, {0x54b0, 0x01, 0, 0}, {0x54b1, 0x20, 0, 0},
+ {0x54b2, 0x00, 0, 0}, {0x54b3, 0x10, 0, 0}, {0x54b4, 0x00, 0, 0},
+ {0x54b5, 0xf0, 0, 0}, {0x54b6, 0x00, 0, 0}, {0x54b7, 0xdf, 0, 0},
+ {0x5402, 0x3f, 0, 0}, {0x5403, 0x00, 0, 0}, {0x3406, 0x00, 0, 0},
+ {0x5180, 0xff, 0, 0}, {0x5181, 0x52, 0, 0}, {0x5182, 0x11, 0, 0},
+ {0x5183, 0x14, 0, 0}, {0x5184, 0x25, 0, 0}, {0x5185, 0x24, 0, 0},
+ {0x5186, 0x06, 0, 0}, {0x5187, 0x08, 0, 0}, {0x5188, 0x08, 0, 0},
+ {0x5189, 0x7c, 0, 0}, {0x518a, 0x60, 0, 0}, {0x518b, 0xb2, 0, 0},
+ {0x518c, 0xb2, 0, 0}, {0x518d, 0x44, 0, 0}, {0x518e, 0x3d, 0, 0},
+ {0x518f, 0x58, 0, 0}, {0x5190, 0x46, 0, 0}, {0x5191, 0xf8, 0, 0},
+ {0x5192, 0x04, 0, 0}, {0x5193, 0x70, 0, 0}, {0x5194, 0xf0, 0, 0},
+ {0x5195, 0xf0, 0, 0}, {0x5196, 0x03, 0, 0}, {0x5197, 0x01, 0, 0},
+ {0x5198, 0x04, 0, 0}, {0x5199, 0x12, 0, 0}, {0x519a, 0x04, 0, 0},
+ {0x519b, 0x00, 0, 0}, {0x519c, 0x06, 0, 0}, {0x519d, 0x82, 0, 0},
+ {0x519e, 0x00, 0, 0}, {0x5025, 0x80, 0, 0}, {0x3a0f, 0x38, 0, 0},
+ {0x3a10, 0x30, 0, 0}, {0x3a1b, 0x3a, 0, 0}, {0x3a1e, 0x2e, 0, 0},
+ {0x3a11, 0x60, 0, 0}, {0x3a1f, 0x10, 0, 0}, {0x5688, 0xa6, 0, 0},
+ {0x5689, 0x6a, 0, 0}, {0x568a, 0xea, 0, 0}, {0x568b, 0xae, 0, 0},
+ {0x568c, 0xa6, 0, 0}, {0x568d, 0x6a, 0, 0}, {0x568e, 0x62, 0, 0},
+ {0x568f, 0x26, 0, 0}, {0x5583, 0x40, 0, 0}, {0x5584, 0x40, 0, 0},
+ {0x5580, 0x02, 0, 0}, {0x5000, 0xcf, 0, 0}, {0x5800, 0x27, 0, 0},
+ {0x5801, 0x19, 0, 0}, {0x5802, 0x12, 0, 0}, {0x5803, 0x0f, 0, 0},
+ {0x5804, 0x10, 0, 0}, {0x5805, 0x15, 0, 0}, {0x5806, 0x1e, 0, 0},
+ {0x5807, 0x2f, 0, 0}, {0x5808, 0x15, 0, 0}, {0x5809, 0x0d, 0, 0},
+ {0x580a, 0x0a, 0, 0}, {0x580b, 0x09, 0, 0}, {0x580c, 0x0a, 0, 0},
+ {0x580d, 0x0c, 0, 0}, {0x580e, 0x12, 0, 0}, {0x580f, 0x19, 0, 0},
+ {0x5810, 0x0b, 0, 0}, {0x5811, 0x07, 0, 0}, {0x5812, 0x04, 0, 0},
+ {0x5813, 0x03, 0, 0}, {0x5814, 0x03, 0, 0}, {0x5815, 0x06, 0, 0},
+ {0x5816, 0x0a, 0, 0}, {0x5817, 0x0f, 0, 0}, {0x5818, 0x0a, 0, 0},
+ {0x5819, 0x05, 0, 0}, {0x581a, 0x01, 0, 0}, {0x581b, 0x00, 0, 0},
+ {0x581c, 0x00, 0, 0}, {0x581d, 0x03, 0, 0}, {0x581e, 0x08, 0, 0},
+ {0x581f, 0x0c, 0, 0}, {0x5820, 0x0a, 0, 0}, {0x5821, 0x05, 0, 0},
+ {0x5822, 0x01, 0, 0}, {0x5823, 0x00, 0, 0}, {0x5824, 0x00, 0, 0},
+ {0x5825, 0x03, 0, 0}, {0x5826, 0x08, 0, 0}, {0x5827, 0x0c, 0, 0},
+ {0x5828, 0x0e, 0, 0}, {0x5829, 0x08, 0, 0}, {0x582a, 0x06, 0, 0},
+ {0x582b, 0x04, 0, 0}, {0x582c, 0x05, 0, 0}, {0x582d, 0x07, 0, 0},
+ {0x582e, 0x0b, 0, 0}, {0x582f, 0x12, 0, 0}, {0x5830, 0x18, 0, 0},
+ {0x5831, 0x10, 0, 0}, {0x5832, 0x0c, 0, 0}, {0x5833, 0x0a, 0, 0},
+ {0x5834, 0x0b, 0, 0}, {0x5835, 0x0e, 0, 0}, {0x5836, 0x15, 0, 0},
+ {0x5837, 0x19, 0, 0}, {0x5838, 0x32, 0, 0}, {0x5839, 0x1f, 0, 0},
+ {0x583a, 0x18, 0, 0}, {0x583b, 0x16, 0, 0}, {0x583c, 0x17, 0, 0},
+ {0x583d, 0x1e, 0, 0}, {0x583e, 0x26, 0, 0}, {0x583f, 0x53, 0, 0},
+ {0x5840, 0x10, 0, 0}, {0x5841, 0x0f, 0, 0}, {0x5842, 0x0d, 0, 0},
+ {0x5843, 0x0c, 0, 0}, {0x5844, 0x0e, 0, 0}, {0x5845, 0x09, 0, 0},
+ {0x5846, 0x11, 0, 0}, {0x5847, 0x10, 0, 0}, {0x5848, 0x10, 0, 0},
+ {0x5849, 0x10, 0, 0}, {0x584a, 0x10, 0, 0}, {0x584b, 0x0e, 0, 0},
+ {0x584c, 0x10, 0, 0}, {0x584d, 0x10, 0, 0}, {0x584e, 0x11, 0, 0},
+ {0x584f, 0x10, 0, 0}, {0x5850, 0x0f, 0, 0}, {0x5851, 0x0c, 0, 0},
+ {0x5852, 0x0f, 0, 0}, {0x5853, 0x10, 0, 0}, {0x5854, 0x10, 0, 0},
+ {0x5855, 0x0f, 0, 0}, {0x5856, 0x0e, 0, 0}, {0x5857, 0x0b, 0, 0},
+ {0x5858, 0x10, 0, 0}, {0x5859, 0x0d, 0, 0}, {0x585a, 0x0d, 0, 0},
+ {0x585b, 0x0c, 0, 0}, {0x585c, 0x0c, 0, 0}, {0x585d, 0x0c, 0, 0},
+ {0x585e, 0x0b, 0, 0}, {0x585f, 0x0c, 0, 0}, {0x5860, 0x0c, 0, 0},
+ {0x5861, 0x0c, 0, 0}, {0x5862, 0x0d, 0, 0}, {0x5863, 0x08, 0, 0},
+ {0x5864, 0x11, 0, 0}, {0x5865, 0x18, 0, 0}, {0x5866, 0x18, 0, 0},
+ {0x5867, 0x19, 0, 0}, {0x5868, 0x17, 0, 0}, {0x5869, 0x19, 0, 0},
+ {0x586a, 0x16, 0, 0}, {0x586b, 0x13, 0, 0}, {0x586c, 0x13, 0, 0},
+ {0x586d, 0x12, 0, 0}, {0x586e, 0x13, 0, 0}, {0x586f, 0x16, 0, 0},
+ {0x5870, 0x14, 0, 0}, {0x5871, 0x12, 0, 0}, {0x5872, 0x10, 0, 0},
+ {0x5873, 0x11, 0, 0}, {0x5874, 0x11, 0, 0}, {0x5875, 0x16, 0, 0},
+ {0x5876, 0x14, 0, 0}, {0x5877, 0x11, 0, 0}, {0x5878, 0x10, 0, 0},
+ {0x5879, 0x0f, 0, 0}, {0x587a, 0x10, 0, 0}, {0x587b, 0x14, 0, 0},
+ {0x587c, 0x13, 0, 0}, {0x587d, 0x12, 0, 0}, {0x587e, 0x11, 0, 0},
+ {0x587f, 0x11, 0, 0}, {0x5880, 0x12, 0, 0}, {0x5881, 0x15, 0, 0},
+ {0x5882, 0x14, 0, 0}, {0x5883, 0x15, 0, 0}, {0x5884, 0x15, 0, 0},
+ {0x5885, 0x15, 0, 0}, {0x5886, 0x13, 0, 0}, {0x5887, 0x17, 0, 0},
+ {0x3710, 0x10, 0, 0}, {0x3632, 0x51, 0, 0}, {0x3702, 0x10, 0, 0},
+ {0x3703, 0xb2, 0, 0}, {0x3704, 0x18, 0, 0}, {0x370b, 0x40, 0, 0},
+ {0x370d, 0x03, 0, 0}, {0x3631, 0x01, 0, 0}, {0x3632, 0x52, 0, 0},
+ {0x3606, 0x24, 0, 0}, {0x3620, 0x96, 0, 0}, {0x5785, 0x07, 0, 0},
+ {0x3a13, 0x30, 0, 0}, {0x3600, 0x52, 0, 0}, {0x3604, 0x48, 0, 0},
+ {0x3606, 0x1b, 0, 0}, {0x370d, 0x0b, 0, 0}, {0x370f, 0xc0, 0, 0},
+ {0x3709, 0x01, 0, 0}, {0x3823, 0x00, 0, 0}, {0x5007, 0x00, 0, 0},
+ {0x5009, 0x00, 0, 0}, {0x5011, 0x00, 0, 0}, {0x5013, 0x00, 0, 0},
+ {0x519e, 0x00, 0, 0}, {0x5086, 0x00, 0, 0}, {0x5087, 0x00, 0, 0},
+ {0x5088, 0x00, 0, 0}, {0x5089, 0x00, 0, 0}, {0x302b, 0x00, 0, 0},
+ {0x3808, 0x00, 0, 0}, {0x3809, 0xb0, 0, 0}, {0x380a, 0x00, 0, 0},
+ {0x380b, 0x90, 0, 0}, {0x3a00, 0x78, 0, 0},
+};
+
+static struct reg_value ov5642_setting_30fps_QCIF_176_144[] = {
+ {0x3103, 0x93, 0, 0}, {0x3008, 0x82, 0, 0}, {0x3017, 0x7f, 0, 0},
+ {0x3018, 0xfc, 0, 0}, {0x3810, 0xc2, 0, 0}, {0x3615, 0xf0, 0, 0},
+ {0x3000, 0x00, 0, 0}, {0x3001, 0x00, 0, 0}, {0x3002, 0x5c, 0, 0},
+ {0x3003, 0x00, 0, 0}, {0x3004, 0xff, 0, 0}, {0x3005, 0xff, 0, 0},
+ {0x3006, 0x43, 0, 0}, {0x3007, 0x37, 0, 0}, {0x3011, 0x10, 0, 0},
+ {0x3010, 0x10, 0, 0}, {0x460c, 0x22, 0, 0}, {0x3815, 0x04, 0, 0},
+ {0x370c, 0xa0, 0, 0}, {0x3602, 0xfc, 0, 0}, {0x3612, 0xff, 0, 0},
+ {0x3634, 0xc0, 0, 0}, {0x3613, 0x00, 0, 0}, {0x3605, 0x7c, 0, 0},
+ {0x3621, 0x09, 0, 0}, {0x3622, 0x60, 0, 0}, {0x3604, 0x40, 0, 0},
+ {0x3603, 0xa7, 0, 0}, {0x3603, 0x27, 0, 0}, {0x4000, 0x21, 0, 0},
+ {0x401d, 0x22, 0, 0}, {0x3600, 0x54, 0, 0}, {0x3605, 0x04, 0, 0},
+ {0x3606, 0x3f, 0, 0}, {0x3c01, 0x80, 0, 0}, {0x5000, 0x4f, 0, 0},
+ {0x5020, 0x04, 0, 0}, {0x5181, 0x79, 0, 0}, {0x5182, 0x00, 0, 0},
+ {0x5185, 0x22, 0, 0}, {0x5197, 0x01, 0, 0}, {0x5001, 0xff, 0, 0},
+ {0x5500, 0x0a, 0, 0}, {0x5504, 0x00, 0, 0}, {0x5505, 0x7f, 0, 0},
+ {0x5080, 0x08, 0, 0}, {0x300e, 0x18, 0, 0}, {0x4610, 0x00, 0, 0},
+ {0x471d, 0x05, 0, 0}, {0x4708, 0x06, 0, 0}, {0x3808, 0x02, 0, 0},
+ {0x3809, 0x80, 0, 0}, {0x380a, 0x01, 0, 0}, {0x380b, 0xe0, 0, 0},
+ {0x380e, 0x07, 0, 0}, {0x380f, 0xd0, 0, 0}, {0x501f, 0x00, 0, 0},
+ {0x5000, 0x4f, 0, 0}, {0x4300, 0x30, 0, 0}, {0x3503, 0x07, 0, 0},
+ {0x3501, 0x73, 0, 0}, {0x3502, 0x80, 0, 0}, {0x350b, 0x00, 0, 0},
+ {0x3503, 0x07, 0, 0}, {0x3824, 0x11, 0, 0}, {0x3501, 0x1e, 0, 0},
+ {0x3502, 0x80, 0, 0}, {0x350b, 0x7f, 0, 0}, {0x380c, 0x0c, 0, 0},
+ {0x380d, 0x80, 0, 0}, {0x380e, 0x03, 0, 0}, {0x380f, 0xe8, 0, 0},
+ {0x3a0d, 0x04, 0, 0}, {0x3a0e, 0x03, 0, 0}, {0x3818, 0xc1, 0, 0},
+ {0x3705, 0xdb, 0, 0}, {0x370a, 0x81, 0, 0}, {0x3801, 0x80, 0, 0},
+ {0x3621, 0x87, 0, 0}, {0x3801, 0x50, 0, 0}, {0x3803, 0x08, 0, 0},
+ {0x3827, 0x08, 0, 0}, {0x3810, 0x40, 0, 0}, {0x3804, 0x05, 0, 0},
+ {0x3805, 0x00, 0, 0}, {0x5682, 0x05, 0, 0}, {0x5683, 0x00, 0, 0},
+ {0x3806, 0x03, 0, 0}, {0x3807, 0xc0, 0, 0}, {0x5686, 0x03, 0, 0},
+ {0x5687, 0xbc, 0, 0}, {0x3a00, 0x78, 0, 0}, {0x3a1a, 0x05, 0, 0},
+ {0x3a13, 0x30, 0, 0}, {0x3a18, 0x00, 0, 0}, {0x3a19, 0x7c, 0, 0},
+ {0x3a08, 0x12, 0, 0}, {0x3a09, 0xc0, 0, 0}, {0x3a0a, 0x0f, 0, 0},
+ {0x3a0b, 0xa0, 0, 0}, {0x350c, 0x07, 0, 0}, {0x350d, 0xd0, 0, 0},
+ {0x3500, 0x00, 0, 0}, {0x3501, 0x00, 0, 0}, {0x3502, 0x00, 0, 0},
+ {0x350a, 0x00, 0, 0}, {0x350b, 0x00, 0, 0}, {0x3503, 0x00, 0, 0},
+ {0x528a, 0x02, 0, 0}, {0x528b, 0x04, 0, 0}, {0x528c, 0x08, 0, 0},
+ {0x528d, 0x08, 0, 0}, {0x528e, 0x08, 0, 0}, {0x528f, 0x10, 0, 0},
+ {0x5290, 0x10, 0, 0}, {0x5292, 0x00, 0, 0}, {0x5293, 0x02, 0, 0},
+ {0x5294, 0x00, 0, 0}, {0x5295, 0x02, 0, 0}, {0x5296, 0x00, 0, 0},
+ {0x5297, 0x02, 0, 0}, {0x5298, 0x00, 0, 0}, {0x5299, 0x02, 0, 0},
+ {0x529a, 0x00, 0, 0}, {0x529b, 0x02, 0, 0}, {0x529c, 0x00, 0, 0},
+ {0x529d, 0x02, 0, 0}, {0x529e, 0x00, 0, 0}, {0x529f, 0x02, 0, 0},
+ {0x3a0f, 0x3c, 0, 0}, {0x3a10, 0x30, 0, 0}, {0x3a1b, 0x3c, 0, 0},
+ {0x3a1e, 0x30, 0, 0}, {0x3a11, 0x70, 0, 0}, {0x3a1f, 0x10, 0, 0},
+ {0x3030, 0x2b, 0, 0}, {0x3a02, 0x00, 0, 0}, {0x3a03, 0x7d, 0, 0},
+ {0x3a04, 0x00, 0, 0}, {0x3a14, 0x00, 0, 0}, {0x3a15, 0x7d, 0, 0},
+ {0x3a16, 0x00, 0, 0}, {0x3a00, 0x78, 0, 0}, {0x3a08, 0x09, 0, 0},
+ {0x3a09, 0x60, 0, 0}, {0x3a0a, 0x07, 0, 0}, {0x3a0b, 0xd0, 0, 0},
+ {0x3a0d, 0x08, 0, 0}, {0x3a0e, 0x06, 0, 0}, {0x5193, 0x70, 0, 0},
+ {0x589b, 0x04, 0, 0}, {0x589a, 0xc5, 0, 0}, {0x401e, 0x20, 0, 0},
+ {0x4001, 0x42, 0, 0}, {0x401c, 0x04, 0, 0}, {0x528a, 0x01, 0, 0},
+ {0x528b, 0x04, 0, 0}, {0x528c, 0x08, 0, 0}, {0x528d, 0x10, 0, 0},
+ {0x528e, 0x20, 0, 0}, {0x528f, 0x28, 0, 0}, {0x5290, 0x30, 0, 0},
+ {0x5292, 0x00, 0, 0}, {0x5293, 0x01, 0, 0}, {0x5294, 0x00, 0, 0},
+ {0x5295, 0x04, 0, 0}, {0x5296, 0x00, 0, 0}, {0x5297, 0x08, 0, 0},
+ {0x5298, 0x00, 0, 0}, {0x5299, 0x10, 0, 0}, {0x529a, 0x00, 0, 0},
+ {0x529b, 0x20, 0, 0}, {0x529c, 0x00, 0, 0}, {0x529d, 0x28, 0, 0},
+ {0x529e, 0x00, 0, 0}, {0x529f, 0x30, 0, 0}, {0x5282, 0x00, 0, 0},
+ {0x5300, 0x00, 0, 0}, {0x5301, 0x20, 0, 0}, {0x5302, 0x00, 0, 0},
+ {0x5303, 0x7c, 0, 0}, {0x530c, 0x00, 0, 0}, {0x530d, 0x0c, 0, 0},
+ {0x530e, 0x20, 0, 0}, {0x530f, 0x80, 0, 0}, {0x5310, 0x20, 0, 0},
+ {0x5311, 0x80, 0, 0}, {0x5308, 0x20, 0, 0}, {0x5309, 0x40, 0, 0},
+ {0x5304, 0x00, 0, 0}, {0x5305, 0x30, 0, 0}, {0x5306, 0x00, 0, 0},
+ {0x5307, 0x80, 0, 0}, {0x5314, 0x08, 0, 0}, {0x5315, 0x20, 0, 0},
+ {0x5319, 0x30, 0, 0}, {0x5316, 0x10, 0, 0}, {0x5317, 0x00, 0, 0},
+ {0x5318, 0x02, 0, 0}, {0x5380, 0x01, 0, 0}, {0x5381, 0x00, 0, 0},
+ {0x5382, 0x00, 0, 0}, {0x5383, 0x4e, 0, 0}, {0x5384, 0x00, 0, 0},
+ {0x5385, 0x0f, 0, 0}, {0x5386, 0x00, 0, 0}, {0x5387, 0x00, 0, 0},
+ {0x5388, 0x01, 0, 0}, {0x5389, 0x15, 0, 0}, {0x538a, 0x00, 0, 0},
+ {0x538b, 0x31, 0, 0}, {0x538c, 0x00, 0, 0}, {0x538d, 0x00, 0, 0},
+ {0x538e, 0x00, 0, 0}, {0x538f, 0x0f, 0, 0}, {0x5390, 0x00, 0, 0},
+ {0x5391, 0xab, 0, 0}, {0x5392, 0x00, 0, 0}, {0x5393, 0xa2, 0, 0},
+ {0x5394, 0x08, 0, 0}, {0x5480, 0x14, 0, 0}, {0x5481, 0x21, 0, 0},
+ {0x5482, 0x36, 0, 0}, {0x5483, 0x57, 0, 0}, {0x5484, 0x65, 0, 0},
+ {0x5485, 0x71, 0, 0}, {0x5486, 0x7d, 0, 0}, {0x5487, 0x87, 0, 0},
+ {0x5488, 0x91, 0, 0}, {0x5489, 0x9a, 0, 0}, {0x548a, 0xaa, 0, 0},
+ {0x548b, 0xb8, 0, 0}, {0x548c, 0xcd, 0, 0}, {0x548d, 0xdd, 0, 0},
+ {0x548e, 0xea, 0, 0}, {0x548f, 0x1d, 0, 0}, {0x5490, 0x05, 0, 0},
+ {0x5491, 0x00, 0, 0}, {0x5492, 0x04, 0, 0}, {0x5493, 0x20, 0, 0},
+ {0x5494, 0x03, 0, 0}, {0x5495, 0x60, 0, 0}, {0x5496, 0x02, 0, 0},
+ {0x5497, 0xb8, 0, 0}, {0x5498, 0x02, 0, 0}, {0x5499, 0x86, 0, 0},
+ {0x549a, 0x02, 0, 0}, {0x549b, 0x5b, 0, 0}, {0x549c, 0x02, 0, 0},
+ {0x549d, 0x3b, 0, 0}, {0x549e, 0x02, 0, 0}, {0x549f, 0x1c, 0, 0},
+ {0x54a0, 0x02, 0, 0}, {0x54a1, 0x04, 0, 0}, {0x54a2, 0x01, 0, 0},
+ {0x54a3, 0xed, 0, 0}, {0x54a4, 0x01, 0, 0}, {0x54a5, 0xc5, 0, 0},
+ {0x54a6, 0x01, 0, 0}, {0x54a7, 0xa5, 0, 0}, {0x54a8, 0x01, 0, 0},
+ {0x54a9, 0x6c, 0, 0}, {0x54aa, 0x01, 0, 0}, {0x54ab, 0x41, 0, 0},
+ {0x54ac, 0x01, 0, 0}, {0x54ad, 0x20, 0, 0}, {0x54ae, 0x00, 0, 0},
+ {0x54af, 0x16, 0, 0}, {0x54b0, 0x01, 0, 0}, {0x54b1, 0x20, 0, 0},
+ {0x54b2, 0x00, 0, 0}, {0x54b3, 0x10, 0, 0}, {0x54b4, 0x00, 0, 0},
+ {0x54b5, 0xf0, 0, 0}, {0x54b6, 0x00, 0, 0}, {0x54b7, 0xdf, 0, 0},
+ {0x5402, 0x3f, 0, 0}, {0x5403, 0x00, 0, 0}, {0x3406, 0x00, 0, 0},
+ {0x5180, 0xff, 0, 0}, {0x5181, 0x52, 0, 0}, {0x5182, 0x11, 0, 0},
+ {0x5183, 0x14, 0, 0}, {0x5184, 0x25, 0, 0}, {0x5185, 0x24, 0, 0},
+ {0x5186, 0x06, 0, 0}, {0x5187, 0x08, 0, 0}, {0x5188, 0x08, 0, 0},
+ {0x5189, 0x7c, 0, 0}, {0x518a, 0x60, 0, 0}, {0x518b, 0xb2, 0, 0},
+ {0x518c, 0xb2, 0, 0}, {0x518d, 0x44, 0, 0}, {0x518e, 0x3d, 0, 0},
+ {0x518f, 0x58, 0, 0}, {0x5190, 0x46, 0, 0}, {0x5191, 0xf8, 0, 0},
+ {0x5192, 0x04, 0, 0}, {0x5193, 0x70, 0, 0}, {0x5194, 0xf0, 0, 0},
+ {0x5195, 0xf0, 0, 0}, {0x5196, 0x03, 0, 0}, {0x5197, 0x01, 0, 0},
+ {0x5198, 0x04, 0, 0}, {0x5199, 0x12, 0, 0}, {0x519a, 0x04, 0, 0},
+ {0x519b, 0x00, 0, 0}, {0x519c, 0x06, 0, 0}, {0x519d, 0x82, 0, 0},
+ {0x519e, 0x00, 0, 0}, {0x5025, 0x80, 0, 0}, {0x3a0f, 0x38, 0, 0},
+ {0x3a10, 0x30, 0, 0}, {0x3a1b, 0x3a, 0, 0}, {0x3a1e, 0x2e, 0, 0},
+ {0x3a11, 0x60, 0, 0}, {0x3a1f, 0x10, 0, 0}, {0x5688, 0xa6, 0, 0},
+ {0x5689, 0x6a, 0, 0}, {0x568a, 0xea, 0, 0}, {0x568b, 0xae, 0, 0},
+ {0x568c, 0xa6, 0, 0}, {0x568d, 0x6a, 0, 0}, {0x568e, 0x62, 0, 0},
+ {0x568f, 0x26, 0, 0}, {0x5583, 0x40, 0, 0}, {0x5584, 0x40, 0, 0},
+ {0x5580, 0x02, 0, 0}, {0x5000, 0xcf, 0, 0}, {0x5800, 0x27, 0, 0},
+ {0x5801, 0x19, 0, 0}, {0x5802, 0x12, 0, 0}, {0x5803, 0x0f, 0, 0},
+ {0x5804, 0x10, 0, 0}, {0x5805, 0x15, 0, 0}, {0x5806, 0x1e, 0, 0},
+ {0x5807, 0x2f, 0, 0}, {0x5808, 0x15, 0, 0}, {0x5809, 0x0d, 0, 0},
+ {0x580a, 0x0a, 0, 0}, {0x580b, 0x09, 0, 0}, {0x580c, 0x0a, 0, 0},
+ {0x580d, 0x0c, 0, 0}, {0x580e, 0x12, 0, 0}, {0x580f, 0x19, 0, 0},
+ {0x5810, 0x0b, 0, 0}, {0x5811, 0x07, 0, 0}, {0x5812, 0x04, 0, 0},
+ {0x5813, 0x03, 0, 0}, {0x5814, 0x03, 0, 0}, {0x5815, 0x06, 0, 0},
+ {0x5816, 0x0a, 0, 0}, {0x5817, 0x0f, 0, 0}, {0x5818, 0x0a, 0, 0},
+ {0x5819, 0x05, 0, 0}, {0x581a, 0x01, 0, 0}, {0x581b, 0x00, 0, 0},
+ {0x581c, 0x00, 0, 0}, {0x581d, 0x03, 0, 0}, {0x581e, 0x08, 0, 0},
+ {0x581f, 0x0c, 0, 0}, {0x5820, 0x0a, 0, 0}, {0x5821, 0x05, 0, 0},
+ {0x5822, 0x01, 0, 0}, {0x5823, 0x00, 0, 0}, {0x5824, 0x00, 0, 0},
+ {0x5825, 0x03, 0, 0}, {0x5826, 0x08, 0, 0}, {0x5827, 0x0c, 0, 0},
+ {0x5828, 0x0e, 0, 0}, {0x5829, 0x08, 0, 0}, {0x582a, 0x06, 0, 0},
+ {0x582b, 0x04, 0, 0}, {0x582c, 0x05, 0, 0}, {0x582d, 0x07, 0, 0},
+ {0x582e, 0x0b, 0, 0}, {0x582f, 0x12, 0, 0}, {0x5830, 0x18, 0, 0},
+ {0x5831, 0x10, 0, 0}, {0x5832, 0x0c, 0, 0}, {0x5833, 0x0a, 0, 0},
+ {0x5834, 0x0b, 0, 0}, {0x5835, 0x0e, 0, 0}, {0x5836, 0x15, 0, 0},
+ {0x5837, 0x19, 0, 0}, {0x5838, 0x32, 0, 0}, {0x5839, 0x1f, 0, 0},
+ {0x583a, 0x18, 0, 0}, {0x583b, 0x16, 0, 0}, {0x583c, 0x17, 0, 0},
+ {0x583d, 0x1e, 0, 0}, {0x583e, 0x26, 0, 0}, {0x583f, 0x53, 0, 0},
+ {0x5840, 0x10, 0, 0}, {0x5841, 0x0f, 0, 0}, {0x5842, 0x0d, 0, 0},
+ {0x5843, 0x0c, 0, 0}, {0x5844, 0x0e, 0, 0}, {0x5845, 0x09, 0, 0},
+ {0x5846, 0x11, 0, 0}, {0x5847, 0x10, 0, 0}, {0x5848, 0x10, 0, 0},
+ {0x5849, 0x10, 0, 0}, {0x584a, 0x10, 0, 0}, {0x584b, 0x0e, 0, 0},
+ {0x584c, 0x10, 0, 0}, {0x584d, 0x10, 0, 0}, {0x584e, 0x11, 0, 0},
+ {0x584f, 0x10, 0, 0}, {0x5850, 0x0f, 0, 0}, {0x5851, 0x0c, 0, 0},
+ {0x5852, 0x0f, 0, 0}, {0x5853, 0x10, 0, 0}, {0x5854, 0x10, 0, 0},
+ {0x5855, 0x0f, 0, 0}, {0x5856, 0x0e, 0, 0}, {0x5857, 0x0b, 0, 0},
+ {0x5858, 0x10, 0, 0}, {0x5859, 0x0d, 0, 0}, {0x585a, 0x0d, 0, 0},
+ {0x585b, 0x0c, 0, 0}, {0x585c, 0x0c, 0, 0}, {0x585d, 0x0c, 0, 0},
+ {0x585e, 0x0b, 0, 0}, {0x585f, 0x0c, 0, 0}, {0x5860, 0x0c, 0, 0},
+ {0x5861, 0x0c, 0, 0}, {0x5862, 0x0d, 0, 0}, {0x5863, 0x08, 0, 0},
+ {0x5864, 0x11, 0, 0}, {0x5865, 0x18, 0, 0}, {0x5866, 0x18, 0, 0},
+ {0x5867, 0x19, 0, 0}, {0x5868, 0x17, 0, 0}, {0x5869, 0x19, 0, 0},
+ {0x586a, 0x16, 0, 0}, {0x586b, 0x13, 0, 0}, {0x586c, 0x13, 0, 0},
+ {0x586d, 0x12, 0, 0}, {0x586e, 0x13, 0, 0}, {0x586f, 0x16, 0, 0},
+ {0x5870, 0x14, 0, 0}, {0x5871, 0x12, 0, 0}, {0x5872, 0x10, 0, 0},
+ {0x5873, 0x11, 0, 0}, {0x5874, 0x11, 0, 0}, {0x5875, 0x16, 0, 0},
+ {0x5876, 0x14, 0, 0}, {0x5877, 0x11, 0, 0}, {0x5878, 0x10, 0, 0},
+ {0x5879, 0x0f, 0, 0}, {0x587a, 0x10, 0, 0}, {0x587b, 0x14, 0, 0},
+ {0x587c, 0x13, 0, 0}, {0x587d, 0x12, 0, 0}, {0x587e, 0x11, 0, 0},
+ {0x587f, 0x11, 0, 0}, {0x5880, 0x12, 0, 0}, {0x5881, 0x15, 0, 0},
+ {0x5882, 0x14, 0, 0}, {0x5883, 0x15, 0, 0}, {0x5884, 0x15, 0, 0},
+ {0x5885, 0x15, 0, 0}, {0x5886, 0x13, 0, 0}, {0x5887, 0x17, 0, 0},
+ {0x3710, 0x10, 0, 0}, {0x3632, 0x51, 0, 0}, {0x3702, 0x10, 0, 0},
+ {0x3703, 0xb2, 0, 0}, {0x3704, 0x18, 0, 0}, {0x370b, 0x40, 0, 0},
+ {0x370d, 0x03, 0, 0}, {0x3631, 0x01, 0, 0}, {0x3632, 0x52, 0, 0},
+ {0x3606, 0x24, 0, 0}, {0x3620, 0x96, 0, 0}, {0x5785, 0x07, 0, 0},
+ {0x3a13, 0x30, 0, 0}, {0x3600, 0x52, 0, 0}, {0x3604, 0x48, 0, 0},
+ {0x3606, 0x1b, 0, 0}, {0x370d, 0x0b, 0, 0}, {0x370f, 0xc0, 0, 0},
+ {0x3709, 0x01, 0, 0}, {0x3823, 0x00, 0, 0}, {0x5007, 0x00, 0, 0},
+ {0x5009, 0x00, 0, 0}, {0x5011, 0x00, 0, 0}, {0x5013, 0x00, 0, 0},
+ {0x519e, 0x00, 0, 0}, {0x5086, 0x00, 0, 0}, {0x5087, 0x00, 0, 0},
+ {0x5088, 0x00, 0, 0}, {0x5089, 0x00, 0, 0}, {0x302b, 0x00, 0, 0},
+ {0x3808, 0x00, 0, 0}, {0x3809, 0xb0, 0, 0}, {0x380a, 0x00, 0, 0},
+ {0x380b, 0x90, 0, 0}, {0x3a00, 0x78, 0, 0},
+};
+
+static struct reg_value ov5642_setting_15fps_QSXGA_2592_1944[] = {
+ {0x3503, 0x07, 0, 0}, {0x3000, 0x00, 0, 0}, {0x3001, 0x00, 0, 0},
+ {0x3002, 0x00, 0, 0}, {0x3003, 0x00, 0, 0}, {0x3004, 0xff, 0, 0},
+ {0x3005, 0xff, 0, 0}, {0x3006, 0xff, 0, 0}, {0x3007, 0x3f, 0, 0},
+ {0x3011, 0x08, 0, 0}, {0x3010, 0x10, 0, 0}, {0x3818, 0xc0, 0, 0},
+ {0x3621, 0x09, 0, 0}, {0x350c, 0x07, 0, 0}, {0x350d, 0xd0, 0, 0},
+ {0x3602, 0xe4, 0, 0}, {0x3612, 0xac, 0, 0}, {0x3613, 0x44, 0, 0},
+ {0x3622, 0x60, 0, 0}, {0x3623, 0x22, 0, 0}, {0x3604, 0x48, 0, 0},
+ {0x3705, 0xda, 0, 0}, {0x370a, 0x80, 0, 0}, {0x3801, 0x95, 0, 0},
+ {0x3803, 0x0e, 0, 0}, {0x3804, 0x0a, 0, 0}, {0x3805, 0x20, 0, 0},
+ {0x3806, 0x07, 0, 0}, {0x3807, 0x98, 0, 0}, {0x3808, 0x0a, 0, 0},
+ {0x3809, 0x20, 0, 0}, {0x380a, 0x07, 0, 0}, {0x380b, 0x98, 0, 0},
+ {0x380c, 0x0c, 0, 0}, {0x380d, 0x80, 0, 0}, {0x380e, 0x07, 0, 0},
+ {0x380f, 0xd0, 0, 0}, {0x3810, 0xc2, 0, 0}, {0x3815, 0x44, 0, 0},
+ {0x3824, 0x11, 0, 0}, {0x3825, 0xac, 0, 0}, {0x3827, 0x0c, 0, 0},
+ {0x3a00, 0x78, 0, 0}, {0x3a0d, 0x10, 0, 0}, {0x3a0e, 0x0d, 0, 0},
+ {0x5682, 0x0a, 0, 0}, {0x5683, 0x20, 0, 0}, {0x5686, 0x07, 0, 0},
+ {0x5687, 0x98, 0, 0}, {0x5001, 0xff, 0, 0}, {0x589b, 0x00, 0, 0},
+ {0x589a, 0xc0, 0, 0}, {0x4407, 0x04, 0, 0}, {0x3008, 0x02, 0, 0},
+ {0x460b, 0x37, 0, 0}, {0x460c, 0x22, 0, 0}, {0x471d, 0x05, 0, 0},
+ {0x4713, 0x03, 0, 0}, {0x471c, 0xd0, 0, 0}, {0x3815, 0x01, 0, 0},
+ {0x501f, 0x00, 0, 0}, {0x3002, 0x1c, 0, 0}, {0x3819, 0x80, 0, 0},
+ {0x5002, 0xe0, 0, 0}, {0x530a, 0x01, 0, 0}, {0x530d, 0x10, 0, 0},
+ {0x530c, 0x04, 0, 0}, {0x5312, 0x20, 0, 0}, {0x5282, 0x01, 0, 0},
+ {0x3010, 0x10, 0, 0}, {0x3012, 0x00, 0, 0},
+};
+
+
+static struct reg_value ov5642_setting_VGA_2_QVGA[] = {
+ {0x3808, 0x01, 0, 0}, {0x3809, 0x40, 0, 0}, {0x380a, 0x00, 0, 0},
+ {0x380b, 0xf0, 0, 0}, {0x3815, 0x04, 0, 0},
+};
+
+static struct reg_value ov5642_setting_QSXGA_2_VGA[] = {
+ {0x3503, 0x00, 0, 0}, {0x3000, 0x00, 0, 0}, {0x3001, 0x00, 0, 0},
+ {0x3002, 0x5c, 0, 0}, {0x3003, 0x00, 0, 0}, {0x3004, 0xff, 0, 0},
+ {0x3005, 0xff, 0, 0}, {0x3006, 0x43, 0, 0}, {0x3007, 0x37, 0, 0},
+ {0x3010, 0x00, 0, 0}, {0x3818, 0xc1, 0, 0}, {0x3621, 0x87, 0, 0},
+ {0x350c, 0x03, 0, 0}, {0x350d, 0xe8, 0, 0}, {0x3602, 0xfc, 0, 0},
+ {0x3612, 0xff, 0, 0}, {0x3613, 0x00, 0, 0}, {0x3622, 0x60, 0, 0},
+ {0x3623, 0x01, 0, 0}, {0x3604, 0x48, 0, 0}, {0x3705, 0xdb, 0, 0},
+ {0x370a, 0x81, 0, 0}, {0x3801, 0x50, 0, 0}, {0x3803, 0x08, 0, 0},
+ {0x3804, 0x05, 0, 0}, {0x3805, 0x00, 0, 0}, {0x3806, 0x03, 0, 0},
+ {0x3807, 0xc0, 0, 0}, {0x3808, 0x02, 0, 0}, {0x3809, 0x80, 0, 0},
+ {0x380a, 0x01, 0, 0}, {0x380b, 0xe0, 0, 0}, {0x380c, 0x0c, 0, 0},
+ {0x380d, 0x80, 0, 0}, {0x380e, 0x03, 0, 0}, {0x380f, 0xe8, 0, 0},
+ {0x3810, 0x40, 0, 0}, {0x3815, 0x04, 0, 0}, {0x3824, 0x11, 0, 0},
+ {0x3825, 0xb4, 0, 0}, {0x3827, 0x08, 0, 0}, {0x3a00, 0x78, 0, 0},
+ {0x3a0d, 0x04, 0, 0}, {0x3a0e, 0x03, 0, 0}, {0x5682, 0x05, 0, 0},
+ {0x5683, 0x00, 0, 0}, {0x5686, 0x03, 0, 0}, {0x5687, 0xbc, 0, 0},
+ {0x5001, 0xff, 0, 0}, {0x589b, 0x04, 0, 0}, {0x589a, 0xc5, 0, 0},
+ {0x4407, 0x0c, 0, 0}, {0x3008, 0x02, 0, 0}, {0x460b, 0x37, 0, 0},
+ {0x460c, 0x22, 0, 0}, {0x471d, 0x05, 0, 0}, {0x4713, 0x02, 0, 0},
+ {0x471c, 0xd0, 0, 0}, {0x3815, 0x04, 0, 0}, {0x501f, 0x00, 0, 0},
+ {0x3002, 0x5c, 0, 0}, {0x3819, 0x80, 0, 0}, {0x5002, 0xe0, 0, 0},
+ {0x530a, 0x01, 0, 0}, {0x530d, 0x0c, 0, 0}, {0x530c, 0x00, 0, 0},
+ {0x5312, 0x40, 0, 0}, {0x5282, 0x00, 0, 0},
+ {0x3012, 0x02, 0, 0}, {0x3010, 0x00, 0, 0},
+};
+
+static struct reg_value ov5642_setting_30fps_VGA_640_480[] = {
+ {0x3103, 0x93, 0, 0}, {0x3008, 0x82, 0, 0}, {0x3017, 0x7f, 0, 0},
+ {0x3018, 0xfc, 0, 0}, {0x3615, 0xf0, 0, 0}, {0x3000, 0x00, 0, 0},
+ {0x3001, 0x00, 0, 0}, {0x3002, 0x5c, 0, 0}, {0x3003, 0x00, 0, 0},
+ {0x3004, 0xff, 0, 0}, {0x3005, 0xff, 0, 0}, {0x3006, 0x43, 0, 0},
+ {0x3007, 0x37, 0, 0}, {0x3011, 0x09, 0, 0}, {0x3012, 0x02, 0, 0},
+ {0x3010, 0x00, 0, 0}, {0x460c, 0x20, 0, 0}, {0x3815, 0x04, 0, 0},
+ {0x370c, 0xa0, 0, 0}, {0x3602, 0xfc, 0, 0}, {0x3612, 0xff, 0, 0},
+ {0x3634, 0xc0, 0, 0}, {0x3613, 0x00, 0, 0}, {0x3605, 0x7c, 0, 0},
+ {0x3621, 0x09, 0, 0}, {0x3622, 0x60, 0, 0}, {0x3604, 0x40, 0, 0},
+ {0x3603, 0xa7, 0, 0}, {0x3603, 0x27, 0, 0}, {0x4000, 0x21, 0, 0},
+ {0x401d, 0x22, 0, 0}, {0x3600, 0x54, 0, 0}, {0x3605, 0x04, 0, 0},
+ {0x3606, 0x3f, 0, 0}, {0x3c01, 0x80, 0, 0}, {0x5000, 0x4f, 0, 0},
+ {0x5020, 0x04, 0, 0}, {0x5181, 0x79, 0, 0}, {0x5182, 0x00, 0, 0},
+ {0x5185, 0x22, 0, 0}, {0x5197, 0x01, 0, 0}, {0x5001, 0xff, 0, 0},
+ {0x5500, 0x0a, 0, 0}, {0x5504, 0x00, 0, 0}, {0x5505, 0x7f, 0, 0},
+ {0x5080, 0x08, 0, 0}, {0x300e, 0x18, 0, 0}, {0x4610, 0x00, 0, 0},
+ {0x471d, 0x05, 0, 0}, {0x4708, 0x06, 0, 0}, {0x3808, 0x02, 0, 0},
+ {0x3809, 0x80, 0, 0}, {0x380a, 0x01, 0, 0}, {0x380b, 0xe0, 0, 0},
+ {0x380e, 0x07, 0, 0}, {0x380f, 0xd0, 0, 0}, {0x501f, 0x00, 0, 0},
+ {0x5000, 0x4f, 0, 0}, {0x4300, 0x30, 0, 0}, {0x3503, 0x07, 0, 0},
+ {0x3501, 0x73, 0, 0}, {0x3502, 0x80, 0, 0}, {0x350b, 0x00, 0, 0},
+ {0x3503, 0x07, 0, 0}, {0x3824, 0x11, 0, 0}, {0x3825, 0xb0, 0, 0},
+ {0x3501, 0x1e, 0, 0}, {0x3502, 0x80, 0, 0}, {0x350b, 0x7f, 0, 0},
+ {0x380c, 0x07, 0, 0}, {0x380d, 0x2a, 0, 0}, {0x380e, 0x03, 0, 0},
+ {0x380f, 0xe8, 0, 0}, {0x3a0d, 0x04, 0, 0}, {0x3a0e, 0x03, 0, 0},
+ {0x3818, 0xc1, 0, 0}, {0x3705, 0xdb, 0, 0}, {0x370a, 0x81, 0, 0},
+ {0x3801, 0x80, 0, 0}, {0x3621, 0xc7, 0, 0}, {0x3801, 0x50, 0, 0},
+ {0x3803, 0x08, 0, 0}, {0x3827, 0x08, 0, 0}, {0x3810, 0x80, 0, 0},
+ {0x3804, 0x05, 0, 0}, {0x3805, 0x00, 0, 0}, {0x5682, 0x05, 0, 0},
+ {0x5683, 0x00, 0, 0}, {0x3806, 0x03, 0, 0}, {0x3807, 0xc0, 0, 0},
+ {0x5686, 0x03, 0, 0}, {0x5687, 0xbc, 0, 0}, {0x3a00, 0x78, 0, 0},
+ {0x3a1a, 0x05, 0, 0}, {0x3a13, 0x30, 0, 0}, {0x3a18, 0x00, 0, 0},
+ {0x3a19, 0x7c, 0, 0}, {0x3a08, 0x12, 0, 0}, {0x3a09, 0xc0, 0, 0},
+ {0x3a0a, 0x0f, 0, 0}, {0x3a0b, 0xa0, 0, 0}, {0x350c, 0x07, 0, 0},
+ {0x350d, 0xd0, 0, 0}, {0x3500, 0x00, 0, 0}, {0x3501, 0x00, 0, 0},
+ {0x3502, 0x00, 0, 0}, {0x350a, 0x00, 0, 0}, {0x350b, 0x00, 0, 0},
+ {0x3503, 0x00, 0, 0}, {0x528a, 0x02, 0, 0}, {0x528b, 0x04, 0, 0},
+ {0x528c, 0x08, 0, 0}, {0x528d, 0x08, 0, 0}, {0x528e, 0x08, 0, 0},
+ {0x528f, 0x10, 0, 0}, {0x5290, 0x10, 0, 0}, {0x5292, 0x00, 0, 0},
+ {0x5293, 0x02, 0, 0}, {0x5294, 0x00, 0, 0}, {0x5295, 0x02, 0, 0},
+ {0x5296, 0x00, 0, 0}, {0x5297, 0x02, 0, 0}, {0x5298, 0x00, 0, 0},
+ {0x5299, 0x02, 0, 0}, {0x529a, 0x00, 0, 0}, {0x529b, 0x02, 0, 0},
+ {0x529c, 0x00, 0, 0}, {0x529d, 0x02, 0, 0}, {0x529e, 0x00, 0, 0},
+ {0x529f, 0x02, 0, 0}, {0x3a0f, 0x3c, 0, 0}, {0x3a10, 0x30, 0, 0},
+ {0x3a1b, 0x3c, 0, 0}, {0x3a1e, 0x30, 0, 0}, {0x3a11, 0x70, 0, 0},
+ {0x3a1f, 0x10, 0, 0}, {0x3030, 0x2b, 0, 0}, {0x3a02, 0x00, 0, 0},
+ {0x3a03, 0x7d, 0, 0}, {0x3a04, 0x00, 0, 0}, {0x3a14, 0x00, 0, 0},
+ {0x3a15, 0x7d, 0, 0}, {0x3a16, 0x00, 0, 0}, {0x3a00, 0x78, 0, 0},
+ {0x3a08, 0x12, 0, 0}, {0x3a09, 0xc0, 0, 0}, {0x3a0a, 0x0f, 0, 0},
+ {0x3a0b, 0xa0, 0, 0}, {0x3a0d, 0x04, 0, 0}, {0x3a0e, 0x03, 0, 0},
+ {0x5193, 0x70, 0, 0}, {0x589b, 0x04, 0, 0}, {0x589a, 0xc5, 0, 0},
+ {0x401e, 0x20, 0, 0}, {0x4001, 0x42, 0, 0}, {0x401c, 0x04, 0, 0},
+ {0x528a, 0x01, 0, 0}, {0x528b, 0x04, 0, 0}, {0x528c, 0x08, 0, 0},
+ {0x528d, 0x10, 0, 0}, {0x528e, 0x20, 0, 0}, {0x528f, 0x28, 0, 0},
+ {0x5290, 0x30, 0, 0}, {0x5292, 0x00, 0, 0}, {0x5293, 0x01, 0, 0},
+ {0x5294, 0x00, 0, 0}, {0x5295, 0x04, 0, 0}, {0x5296, 0x00, 0, 0},
+ {0x5297, 0x08, 0, 0}, {0x5298, 0x00, 0, 0}, {0x5299, 0x10, 0, 0},
+ {0x529a, 0x00, 0, 0}, {0x529b, 0x20, 0, 0}, {0x529c, 0x00, 0, 0},
+ {0x529d, 0x28, 0, 0}, {0x529e, 0x00, 0, 0}, {0x529f, 0x30, 0, 0},
+ {0x5282, 0x00, 0, 0}, {0x5300, 0x00, 0, 0}, {0x5301, 0x20, 0, 0},
+ {0x5302, 0x00, 0, 0}, {0x5303, 0x7c, 0, 0}, {0x530c, 0x00, 0, 0},
+ {0x530d, 0x0c, 0, 0}, {0x530e, 0x20, 0, 0}, {0x530f, 0x80, 0, 0},
+ {0x5310, 0x20, 0, 0}, {0x5311, 0x80, 0, 0}, {0x5308, 0x20, 0, 0},
+ {0x5309, 0x40, 0, 0}, {0x5304, 0x00, 0, 0}, {0x5305, 0x30, 0, 0},
+ {0x5306, 0x00, 0, 0}, {0x5307, 0x80, 0, 0}, {0x5314, 0x08, 0, 0},
+ {0x5315, 0x20, 0, 0}, {0x5319, 0x30, 0, 0}, {0x5316, 0x10, 0, 0},
+ {0x5317, 0x00, 0, 0}, {0x5318, 0x02, 0, 0}, {0x5380, 0x01, 0, 0},
+ {0x5381, 0x00, 0, 0}, {0x5382, 0x00, 0, 0}, {0x5383, 0x4e, 0, 0},
+ {0x5384, 0x00, 0, 0}, {0x5385, 0x0f, 0, 0}, {0x5386, 0x00, 0, 0},
+ {0x5387, 0x00, 0, 0}, {0x5388, 0x01, 0, 0}, {0x5389, 0x15, 0, 0},
+ {0x538a, 0x00, 0, 0}, {0x538b, 0x31, 0, 0}, {0x538c, 0x00, 0, 0},
+ {0x538d, 0x00, 0, 0}, {0x538e, 0x00, 0, 0}, {0x538f, 0x0f, 0, 0},
+ {0x5390, 0x00, 0, 0}, {0x5391, 0xab, 0, 0}, {0x5392, 0x00, 0, 0},
+ {0x5393, 0xa2, 0, 0}, {0x5394, 0x08, 0, 0}, {0x5480, 0x14, 0, 0},
+ {0x5481, 0x21, 0, 0}, {0x5482, 0x36, 0, 0}, {0x5483, 0x57, 0, 0},
+ {0x5484, 0x65, 0, 0}, {0x5485, 0x71, 0, 0}, {0x5486, 0x7d, 0, 0},
+ {0x5487, 0x87, 0, 0}, {0x5488, 0x91, 0, 0}, {0x5489, 0x9a, 0, 0},
+ {0x548a, 0xaa, 0, 0}, {0x548b, 0xb8, 0, 0}, {0x548c, 0xcd, 0, 0},
+ {0x548d, 0xdd, 0, 0}, {0x548e, 0xea, 0, 0}, {0x548f, 0x1d, 0, 0},
+ {0x5490, 0x05, 0, 0}, {0x5491, 0x00, 0, 0}, {0x5492, 0x04, 0, 0},
+ {0x5493, 0x20, 0, 0}, {0x5494, 0x03, 0, 0}, {0x5495, 0x60, 0, 0},
+ {0x5496, 0x02, 0, 0}, {0x5497, 0xb8, 0, 0}, {0x5498, 0x02, 0, 0},
+ {0x5499, 0x86, 0, 0}, {0x549a, 0x02, 0, 0}, {0x549b, 0x5b, 0, 0},
+ {0x549c, 0x02, 0, 0}, {0x549d, 0x3b, 0, 0}, {0x549e, 0x02, 0, 0},
+ {0x549f, 0x1c, 0, 0}, {0x54a0, 0x02, 0, 0}, {0x54a1, 0x04, 0, 0},
+ {0x54a2, 0x01, 0, 0}, {0x54a3, 0xed, 0, 0}, {0x54a4, 0x01, 0, 0},
+ {0x54a5, 0xc5, 0, 0}, {0x54a6, 0x01, 0, 0}, {0x54a7, 0xa5, 0, 0},
+ {0x54a8, 0x01, 0, 0}, {0x54a9, 0x6c, 0, 0}, {0x54aa, 0x01, 0, 0},
+ {0x54ab, 0x41, 0, 0}, {0x54ac, 0x01, 0, 0}, {0x54ad, 0x20, 0, 0},
+ {0x54ae, 0x00, 0, 0}, {0x54af, 0x16, 0, 0}, {0x54b0, 0x01, 0, 0},
+ {0x54b1, 0x20, 0, 0}, {0x54b2, 0x00, 0, 0}, {0x54b3, 0x10, 0, 0},
+ {0x54b4, 0x00, 0, 0}, {0x54b5, 0xf0, 0, 0}, {0x54b6, 0x00, 0, 0},
+ {0x54b7, 0xdf, 0, 0}, {0x5402, 0x3f, 0, 0}, {0x5403, 0x00, 0, 0},
+ {0x3406, 0x00, 0, 0}, {0x5180, 0xff, 0, 0}, {0x5181, 0x52, 0, 0},
+ {0x5182, 0x11, 0, 0}, {0x5183, 0x14, 0, 0}, {0x5184, 0x25, 0, 0},
+ {0x5185, 0x24, 0, 0}, {0x5186, 0x06, 0, 0}, {0x5187, 0x08, 0, 0},
+ {0x5188, 0x08, 0, 0}, {0x5189, 0x7c, 0, 0}, {0x518a, 0x60, 0, 0},
+ {0x518b, 0xb2, 0, 0}, {0x518c, 0xb2, 0, 0}, {0x518d, 0x44, 0, 0},
+ {0x518e, 0x3d, 0, 0}, {0x518f, 0x58, 0, 0}, {0x5190, 0x46, 0, 0},
+ {0x5191, 0xf8, 0, 0}, {0x5192, 0x04, 0, 0}, {0x5193, 0x70, 0, 0},
+ {0x5194, 0xf0, 0, 0}, {0x5195, 0xf0, 0, 0}, {0x5196, 0x03, 0, 0},
+ {0x5197, 0x01, 0, 0}, {0x5198, 0x04, 0, 0}, {0x5199, 0x12, 0, 0},
+ {0x519a, 0x04, 0, 0}, {0x519b, 0x00, 0, 0}, {0x519c, 0x06, 0, 0},
+ {0x519d, 0x82, 0, 0}, {0x519e, 0x00, 0, 0}, {0x5025, 0x80, 0, 0},
+ {0x3a0f, 0x38, 0, 0}, {0x3a10, 0x30, 0, 0}, {0x3a1b, 0x3a, 0, 0},
+ {0x3a1e, 0x2e, 0, 0}, {0x3a11, 0x60, 0, 0}, {0x3a1f, 0x10, 0, 0},
+ {0x5688, 0xa6, 0, 0}, {0x5689, 0x6a, 0, 0}, {0x568a, 0xea, 0, 0},
+ {0x568b, 0xae, 0, 0}, {0x568c, 0xa6, 0, 0}, {0x568d, 0x6a, 0, 0},
+ {0x568e, 0x62, 0, 0}, {0x568f, 0x26, 0, 0}, {0x5583, 0x40, 0, 0},
+ {0x5584, 0x40, 0, 0}, {0x5580, 0x02, 0, 0}, {0x5000, 0xcf, 0, 0},
+ {0x5800, 0x27, 0, 0}, {0x5801, 0x19, 0, 0}, {0x5802, 0x12, 0, 0},
+ {0x5803, 0x0f, 0, 0}, {0x5804, 0x10, 0, 0}, {0x5805, 0x15, 0, 0},
+ {0x5806, 0x1e, 0, 0}, {0x5807, 0x2f, 0, 0}, {0x5808, 0x15, 0, 0},
+ {0x5809, 0x0d, 0, 0}, {0x580a, 0x0a, 0, 0}, {0x580b, 0x09, 0, 0},
+ {0x580c, 0x0a, 0, 0}, {0x580d, 0x0c, 0, 0}, {0x580e, 0x12, 0, 0},
+ {0x580f, 0x19, 0, 0}, {0x5810, 0x0b, 0, 0}, {0x5811, 0x07, 0, 0},
+ {0x5812, 0x04, 0, 0}, {0x5813, 0x03, 0, 0}, {0x5814, 0x03, 0, 0},
+ {0x5815, 0x06, 0, 0}, {0x5816, 0x0a, 0, 0}, {0x5817, 0x0f, 0, 0},
+ {0x5818, 0x0a, 0, 0}, {0x5819, 0x05, 0, 0}, {0x581a, 0x01, 0, 0},
+ {0x581b, 0x00, 0, 0}, {0x581c, 0x00, 0, 0}, {0x581d, 0x03, 0, 0},
+ {0x581e, 0x08, 0, 0}, {0x581f, 0x0c, 0, 0}, {0x5820, 0x0a, 0, 0},
+ {0x5821, 0x05, 0, 0}, {0x5822, 0x01, 0, 0}, {0x5823, 0x00, 0, 0},
+ {0x5824, 0x00, 0, 0}, {0x5825, 0x03, 0, 0}, {0x5826, 0x08, 0, 0},
+ {0x5827, 0x0c, 0, 0}, {0x5828, 0x0e, 0, 0}, {0x5829, 0x08, 0, 0},
+ {0x582a, 0x06, 0, 0}, {0x582b, 0x04, 0, 0}, {0x582c, 0x05, 0, 0},
+ {0x582d, 0x07, 0, 0}, {0x582e, 0x0b, 0, 0}, {0x582f, 0x12, 0, 0},
+ {0x5830, 0x18, 0, 0}, {0x5831, 0x10, 0, 0}, {0x5832, 0x0c, 0, 0},
+ {0x5833, 0x0a, 0, 0}, {0x5834, 0x0b, 0, 0}, {0x5835, 0x0e, 0, 0},
+ {0x5836, 0x15, 0, 0}, {0x5837, 0x19, 0, 0}, {0x5838, 0x32, 0, 0},
+ {0x5839, 0x1f, 0, 0}, {0x583a, 0x18, 0, 0}, {0x583b, 0x16, 0, 0},
+ {0x583c, 0x17, 0, 0}, {0x583d, 0x1e, 0, 0}, {0x583e, 0x26, 0, 0},
+ {0x583f, 0x53, 0, 0}, {0x5840, 0x10, 0, 0}, {0x5841, 0x0f, 0, 0},
+ {0x5842, 0x0d, 0, 0}, {0x5843, 0x0c, 0, 0}, {0x5844, 0x0e, 0, 0},
+ {0x5845, 0x09, 0, 0}, {0x5846, 0x11, 0, 0}, {0x5847, 0x10, 0, 0},
+ {0x5848, 0x10, 0, 0}, {0x5849, 0x10, 0, 0}, {0x584a, 0x10, 0, 0},
+ {0x584b, 0x0e, 0, 0}, {0x584c, 0x10, 0, 0}, {0x584d, 0x10, 0, 0},
+ {0x584e, 0x11, 0, 0}, {0x584f, 0x10, 0, 0}, {0x5850, 0x0f, 0, 0},
+ {0x5851, 0x0c, 0, 0}, {0x5852, 0x0f, 0, 0}, {0x5853, 0x10, 0, 0},
+ {0x5854, 0x10, 0, 0}, {0x5855, 0x0f, 0, 0}, {0x5856, 0x0e, 0, 0},
+ {0x5857, 0x0b, 0, 0}, {0x5858, 0x10, 0, 0}, {0x5859, 0x0d, 0, 0},
+ {0x585a, 0x0d, 0, 0}, {0x585b, 0x0c, 0, 0}, {0x585c, 0x0c, 0, 0},
+ {0x585d, 0x0c, 0, 0}, {0x585e, 0x0b, 0, 0}, {0x585f, 0x0c, 0, 0},
+ {0x5860, 0x0c, 0, 0}, {0x5861, 0x0c, 0, 0}, {0x5862, 0x0d, 0, 0},
+ {0x5863, 0x08, 0, 0}, {0x5864, 0x11, 0, 0}, {0x5865, 0x18, 0, 0},
+ {0x5866, 0x18, 0, 0}, {0x5867, 0x19, 0, 0}, {0x5868, 0x17, 0, 0},
+ {0x5869, 0x19, 0, 0}, {0x586a, 0x16, 0, 0}, {0x586b, 0x13, 0, 0},
+ {0x586c, 0x13, 0, 0}, {0x586d, 0x12, 0, 0}, {0x586e, 0x13, 0, 0},
+ {0x586f, 0x16, 0, 0}, {0x5870, 0x14, 0, 0}, {0x5871, 0x12, 0, 0},
+ {0x5872, 0x10, 0, 0}, {0x5873, 0x11, 0, 0}, {0x5874, 0x11, 0, 0},
+ {0x5875, 0x16, 0, 0}, {0x5876, 0x14, 0, 0}, {0x5877, 0x11, 0, 0},
+ {0x5878, 0x10, 0, 0}, {0x5879, 0x0f, 0, 0}, {0x587a, 0x10, 0, 0},
+ {0x587b, 0x14, 0, 0}, {0x587c, 0x13, 0, 0}, {0x587d, 0x12, 0, 0},
+ {0x587e, 0x11, 0, 0}, {0x587f, 0x11, 0, 0}, {0x5880, 0x12, 0, 0},
+ {0x5881, 0x15, 0, 0}, {0x5882, 0x14, 0, 0}, {0x5883, 0x15, 0, 0},
+ {0x5884, 0x15, 0, 0}, {0x5885, 0x15, 0, 0}, {0x5886, 0x13, 0, 0},
+ {0x5887, 0x17, 0, 0}, {0x3710, 0x10, 0, 0}, {0x3632, 0x51, 0, 0},
+ {0x3702, 0x10, 0, 0}, {0x3703, 0xb2, 0, 0}, {0x3704, 0x18, 0, 0},
+ {0x370b, 0x40, 0, 0}, {0x370d, 0x03, 0, 0}, {0x3631, 0x01, 0, 0},
+ {0x3632, 0x52, 0, 0}, {0x3606, 0x24, 0, 0}, {0x3620, 0x96, 0, 0},
+ {0x5785, 0x07, 0, 0}, {0x3a13, 0x30, 0, 0}, {0x3600, 0x52, 0, 0},
+ {0x3604, 0x48, 0, 0}, {0x3606, 0x1b, 0, 0}, {0x370d, 0x0b, 0, 0},
+ {0x370f, 0xc0, 0, 0}, {0x3709, 0x01, 0, 0}, {0x3823, 0x00, 0, 0},
+ {0x5007, 0x00, 0, 0}, {0x5009, 0x00, 0, 0}, {0x5011, 0x00, 0, 0},
+ {0x5013, 0x00, 0, 0}, {0x519e, 0x00, 0, 0}, {0x5086, 0x00, 0, 0},
+ {0x5087, 0x00, 0, 0}, {0x5088, 0x00, 0, 0}, {0x5089, 0x00, 0, 0},
+ {0x302b, 0x00, 0, 0}, {0x3621, 0x87, 0, 0}, {0x3a00, 0x78, 0, 0},
+};
+
+static struct reg_value ov5642_setting_15fps_VGA_640_480[] = {
+ {0x3103, 0x93, 0, 0}, {0x3008, 0x82, 0, 0}, {0x3017, 0x7f, 0, 0},
+ {0x3018, 0xfc, 0, 0}, {0x3615, 0xf0, 0, 0}, {0x3000, 0x00, 0, 0},
+ {0x3001, 0x00, 0, 0}, {0x3002, 0x5c, 0, 0}, {0x3003, 0x00, 0, 0},
+ {0x3004, 0xff, 0, 0}, {0x3005, 0xff, 0, 0}, {0x3006, 0x43, 0, 0},
+ {0x3007, 0x37, 0, 0}, {0x3011, 0x09, 0, 0}, {0x3012, 0x02, 0, 0},
+ {0x3010, 0x00, 0, 0}, {0x460c, 0x20, 0, 0}, {0x3815, 0x04, 0, 0},
+ {0x370c, 0xa0, 0, 0}, {0x3602, 0xfc, 0, 0}, {0x3612, 0xff, 0, 0},
+ {0x3634, 0xc0, 0, 0}, {0x3613, 0x00, 0, 0}, {0x3605, 0x7c, 0, 0},
+ {0x3621, 0x09, 0, 0}, {0x3622, 0x60, 0, 0}, {0x3604, 0x40, 0, 0},
+ {0x3603, 0xa7, 0, 0}, {0x3603, 0x27, 0, 0}, {0x4000, 0x21, 0, 0},
+ {0x401d, 0x22, 0, 0}, {0x3600, 0x54, 0, 0}, {0x3605, 0x04, 0, 0},
+ {0x3606, 0x3f, 0, 0}, {0x3c01, 0x80, 0, 0}, {0x5000, 0x4f, 0, 0},
+ {0x5020, 0x04, 0, 0}, {0x5181, 0x79, 0, 0}, {0x5182, 0x00, 0, 0},
+ {0x5185, 0x22, 0, 0}, {0x5197, 0x01, 0, 0}, {0x5001, 0xff, 0, 0},
+ {0x5500, 0x0a, 0, 0}, {0x5504, 0x00, 0, 0}, {0x5505, 0x7f, 0, 0},
+ {0x5080, 0x08, 0, 0}, {0x300e, 0x18, 0, 0}, {0x4610, 0x00, 0, 0},
+ {0x471d, 0x05, 0, 0}, {0x4708, 0x06, 0, 0}, {0x3808, 0x02, 0, 0},
+ {0x3809, 0x80, 0, 0}, {0x380a, 0x01, 0, 0}, {0x380b, 0xe0, 0, 0},
+ {0x380e, 0x07, 0, 0}, {0x380f, 0xd0, 0, 0}, {0x501f, 0x00, 0, 0},
+ {0x5000, 0x4f, 0, 0}, {0x4300, 0x30, 0, 0}, {0x3503, 0x07, 0, 0},
+ {0x3501, 0x73, 0, 0}, {0x3502, 0x80, 0, 0}, {0x350b, 0x00, 0, 0},
+ {0x3503, 0x07, 0, 0}, {0x3824, 0x11, 0, 0}, {0x3825, 0xb0, 0, 0},
+ {0x3501, 0x1e, 0, 0}, {0x3502, 0x80, 0, 0}, {0x350b, 0x7f, 0, 0},
+ {0x380c, 0x07, 0, 0}, {0x380d, 0x2a, 0, 0}, {0x380e, 0x07, 0, 0},
+ {0x380f, 0xd0, 0, 0}, {0x3a0d, 0x04, 0, 0}, {0x3a0e, 0x03, 0, 0},
+ {0x3818, 0xc1, 0, 0}, {0x3705, 0xdb, 0, 0}, {0x370a, 0x81, 0, 0},
+ {0x3801, 0x80, 0, 0}, {0x3621, 0xc7, 0, 0}, {0x3801, 0x50, 0, 0},
+ {0x3803, 0x08, 0, 0}, {0x3827, 0x08, 0, 0}, {0x3810, 0x80, 0, 0},
+ {0x3804, 0x05, 0, 0}, {0x3805, 0x00, 0, 0}, {0x5682, 0x05, 0, 0},
+ {0x5683, 0x00, 0, 0}, {0x3806, 0x03, 0, 0}, {0x3807, 0xc0, 0, 0},
+ {0x5686, 0x03, 0, 0}, {0x5687, 0xbc, 0, 0}, {0x3a00, 0x78, 0, 0},
+ {0x3a1a, 0x05, 0, 0}, {0x3a13, 0x30, 0, 0}, {0x3a18, 0x00, 0, 0},
+ {0x3a19, 0x7c, 0, 0}, {0x3a08, 0x12, 0, 0}, {0x3a09, 0xc0, 0, 0},
+ {0x3a0a, 0x0f, 0, 0}, {0x3a0b, 0xa0, 0, 0}, {0x350c, 0x07, 0, 0},
+ {0x350d, 0xd0, 0, 0}, {0x3500, 0x00, 0, 0}, {0x3501, 0x00, 0, 0},
+ {0x3502, 0x00, 0, 0}, {0x350a, 0x00, 0, 0}, {0x350b, 0x00, 0, 0},
+ {0x3503, 0x00, 0, 0}, {0x528a, 0x02, 0, 0}, {0x528b, 0x04, 0, 0},
+ {0x528c, 0x08, 0, 0}, {0x528d, 0x08, 0, 0}, {0x528e, 0x08, 0, 0},
+ {0x528f, 0x10, 0, 0}, {0x5290, 0x10, 0, 0}, {0x5292, 0x00, 0, 0},
+ {0x5293, 0x02, 0, 0}, {0x5294, 0x00, 0, 0}, {0x5295, 0x02, 0, 0},
+ {0x5296, 0x00, 0, 0}, {0x5297, 0x02, 0, 0}, {0x5298, 0x00, 0, 0},
+ {0x5299, 0x02, 0, 0}, {0x529a, 0x00, 0, 0}, {0x529b, 0x02, 0, 0},
+ {0x529c, 0x00, 0, 0}, {0x529d, 0x02, 0, 0}, {0x529e, 0x00, 0, 0},
+ {0x529f, 0x02, 0, 0}, {0x3a0f, 0x3c, 0, 0}, {0x3a10, 0x30, 0, 0},
+ {0x3a1b, 0x3c, 0, 0}, {0x3a1e, 0x30, 0, 0}, {0x3a11, 0x70, 0, 0},
+ {0x3a1f, 0x10, 0, 0}, {0x3030, 0x2b, 0, 0}, {0x3a02, 0x00, 0, 0},
+ {0x3a03, 0x7d, 0, 0}, {0x3a04, 0x00, 0, 0}, {0x3a14, 0x00, 0, 0},
+ {0x3a15, 0x7d, 0, 0}, {0x3a16, 0x00, 0, 0}, {0x3a00, 0x78, 0, 0},
+ {0x3a08, 0x12, 0, 0}, {0x3a09, 0xc0, 0, 0}, {0x3a0a, 0x0f, 0, 0},
+ {0x3a0b, 0xa0, 0, 0}, {0x3a0d, 0x04, 0, 0}, {0x3a0e, 0x03, 0, 0},
+ {0x5193, 0x70, 0, 0}, {0x589b, 0x04, 0, 0}, {0x589a, 0xc5, 0, 0},
+ {0x401e, 0x20, 0, 0}, {0x4001, 0x42, 0, 0}, {0x401c, 0x04, 0, 0},
+ {0x528a, 0x01, 0, 0}, {0x528b, 0x04, 0, 0}, {0x528c, 0x08, 0, 0},
+ {0x528d, 0x10, 0, 0}, {0x528e, 0x20, 0, 0}, {0x528f, 0x28, 0, 0},
+ {0x5290, 0x30, 0, 0}, {0x5292, 0x00, 0, 0}, {0x5293, 0x01, 0, 0},
+ {0x5294, 0x00, 0, 0}, {0x5295, 0x04, 0, 0}, {0x5296, 0x00, 0, 0},
+ {0x5297, 0x08, 0, 0}, {0x5298, 0x00, 0, 0}, {0x5299, 0x10, 0, 0},
+ {0x529a, 0x00, 0, 0}, {0x529b, 0x20, 0, 0}, {0x529c, 0x00, 0, 0},
+ {0x529d, 0x28, 0, 0}, {0x529e, 0x00, 0, 0}, {0x529f, 0x30, 0, 0},
+ {0x5282, 0x00, 0, 0}, {0x5300, 0x00, 0, 0}, {0x5301, 0x20, 0, 0},
+ {0x5302, 0x00, 0, 0}, {0x5303, 0x7c, 0, 0}, {0x530c, 0x00, 0, 0},
+ {0x530d, 0x0c, 0, 0}, {0x530e, 0x20, 0, 0}, {0x530f, 0x80, 0, 0},
+ {0x5310, 0x20, 0, 0}, {0x5311, 0x80, 0, 0}, {0x5308, 0x20, 0, 0},
+ {0x5309, 0x40, 0, 0}, {0x5304, 0x00, 0, 0}, {0x5305, 0x30, 0, 0},
+ {0x5306, 0x00, 0, 0}, {0x5307, 0x80, 0, 0}, {0x5314, 0x08, 0, 0},
+ {0x5315, 0x20, 0, 0}, {0x5319, 0x30, 0, 0}, {0x5316, 0x10, 0, 0},
+ {0x5317, 0x00, 0, 0}, {0x5318, 0x02, 0, 0}, {0x5380, 0x01, 0, 0},
+ {0x5381, 0x00, 0, 0}, {0x5382, 0x00, 0, 0}, {0x5383, 0x4e, 0, 0},
+ {0x5384, 0x00, 0, 0}, {0x5385, 0x0f, 0, 0}, {0x5386, 0x00, 0, 0},
+ {0x5387, 0x00, 0, 0}, {0x5388, 0x01, 0, 0}, {0x5389, 0x15, 0, 0},
+ {0x538a, 0x00, 0, 0}, {0x538b, 0x31, 0, 0}, {0x538c, 0x00, 0, 0},
+ {0x538d, 0x00, 0, 0}, {0x538e, 0x00, 0, 0}, {0x538f, 0x0f, 0, 0},
+ {0x5390, 0x00, 0, 0}, {0x5391, 0xab, 0, 0}, {0x5392, 0x00, 0, 0},
+ {0x5393, 0xa2, 0, 0}, {0x5394, 0x08, 0, 0}, {0x5480, 0x14, 0, 0},
+ {0x5481, 0x21, 0, 0}, {0x5482, 0x36, 0, 0}, {0x5483, 0x57, 0, 0},
+ {0x5484, 0x65, 0, 0}, {0x5485, 0x71, 0, 0}, {0x5486, 0x7d, 0, 0},
+ {0x5487, 0x87, 0, 0}, {0x5488, 0x91, 0, 0}, {0x5489, 0x9a, 0, 0},
+ {0x548a, 0xaa, 0, 0}, {0x548b, 0xb8, 0, 0}, {0x548c, 0xcd, 0, 0},
+ {0x548d, 0xdd, 0, 0}, {0x548e, 0xea, 0, 0}, {0x548f, 0x1d, 0, 0},
+ {0x5490, 0x05, 0, 0}, {0x5491, 0x00, 0, 0}, {0x5492, 0x04, 0, 0},
+ {0x5493, 0x20, 0, 0}, {0x5494, 0x03, 0, 0}, {0x5495, 0x60, 0, 0},
+ {0x5496, 0x02, 0, 0}, {0x5497, 0xb8, 0, 0}, {0x5498, 0x02, 0, 0},
+ {0x5499, 0x86, 0, 0}, {0x549a, 0x02, 0, 0}, {0x549b, 0x5b, 0, 0},
+ {0x549c, 0x02, 0, 0}, {0x549d, 0x3b, 0, 0}, {0x549e, 0x02, 0, 0},
+ {0x549f, 0x1c, 0, 0}, {0x54a0, 0x02, 0, 0}, {0x54a1, 0x04, 0, 0},
+ {0x54a2, 0x01, 0, 0}, {0x54a3, 0xed, 0, 0}, {0x54a4, 0x01, 0, 0},
+ {0x54a5, 0xc5, 0, 0}, {0x54a6, 0x01, 0, 0}, {0x54a7, 0xa5, 0, 0},
+ {0x54a8, 0x01, 0, 0}, {0x54a9, 0x6c, 0, 0}, {0x54aa, 0x01, 0, 0},
+ {0x54ab, 0x41, 0, 0}, {0x54ac, 0x01, 0, 0}, {0x54ad, 0x20, 0, 0},
+ {0x54ae, 0x00, 0, 0}, {0x54af, 0x16, 0, 0}, {0x54b0, 0x01, 0, 0},
+ {0x54b1, 0x20, 0, 0}, {0x54b2, 0x00, 0, 0}, {0x54b3, 0x10, 0, 0},
+ {0x54b4, 0x00, 0, 0}, {0x54b5, 0xf0, 0, 0}, {0x54b6, 0x00, 0, 0},
+ {0x54b7, 0xdf, 0, 0}, {0x5402, 0x3f, 0, 0}, {0x5403, 0x00, 0, 0},
+ {0x3406, 0x00, 0, 0}, {0x5180, 0xff, 0, 0}, {0x5181, 0x52, 0, 0},
+ {0x5182, 0x11, 0, 0}, {0x5183, 0x14, 0, 0}, {0x5184, 0x25, 0, 0},
+ {0x5185, 0x24, 0, 0}, {0x5186, 0x06, 0, 0}, {0x5187, 0x08, 0, 0},
+ {0x5188, 0x08, 0, 0}, {0x5189, 0x7c, 0, 0}, {0x518a, 0x60, 0, 0},
+ {0x518b, 0xb2, 0, 0}, {0x518c, 0xb2, 0, 0}, {0x518d, 0x44, 0, 0},
+ {0x518e, 0x3d, 0, 0}, {0x518f, 0x58, 0, 0}, {0x5190, 0x46, 0, 0},
+ {0x5191, 0xf8, 0, 0}, {0x5192, 0x04, 0, 0}, {0x5193, 0x70, 0, 0},
+ {0x5194, 0xf0, 0, 0}, {0x5195, 0xf0, 0, 0}, {0x5196, 0x03, 0, 0},
+ {0x5197, 0x01, 0, 0}, {0x5198, 0x04, 0, 0}, {0x5199, 0x12, 0, 0},
+ {0x519a, 0x04, 0, 0}, {0x519b, 0x00, 0, 0}, {0x519c, 0x06, 0, 0},
+ {0x519d, 0x82, 0, 0}, {0x519e, 0x00, 0, 0}, {0x5025, 0x80, 0, 0},
+ {0x3a0f, 0x38, 0, 0}, {0x3a10, 0x30, 0, 0}, {0x3a1b, 0x3a, 0, 0},
+ {0x3a1e, 0x2e, 0, 0}, {0x3a11, 0x60, 0, 0}, {0x3a1f, 0x10, 0, 0},
+ {0x5688, 0xa6, 0, 0}, {0x5689, 0x6a, 0, 0}, {0x568a, 0xea, 0, 0},
+ {0x568b, 0xae, 0, 0}, {0x568c, 0xa6, 0, 0}, {0x568d, 0x6a, 0, 0},
+ {0x568e, 0x62, 0, 0}, {0x568f, 0x26, 0, 0}, {0x5583, 0x40, 0, 0},
+ {0x5584, 0x40, 0, 0}, {0x5580, 0x02, 0, 0}, {0x5000, 0xcf, 0, 0},
+ {0x5800, 0x27, 0, 0}, {0x5801, 0x19, 0, 0}, {0x5802, 0x12, 0, 0},
+ {0x5803, 0x0f, 0, 0}, {0x5804, 0x10, 0, 0}, {0x5805, 0x15, 0, 0},
+ {0x5806, 0x1e, 0, 0}, {0x5807, 0x2f, 0, 0}, {0x5808, 0x15, 0, 0},
+ {0x5809, 0x0d, 0, 0}, {0x580a, 0x0a, 0, 0}, {0x580b, 0x09, 0, 0},
+ {0x580c, 0x0a, 0, 0}, {0x580d, 0x0c, 0, 0}, {0x580e, 0x12, 0, 0},
+ {0x580f, 0x19, 0, 0}, {0x5810, 0x0b, 0, 0}, {0x5811, 0x07, 0, 0},
+ {0x5812, 0x04, 0, 0}, {0x5813, 0x03, 0, 0}, {0x5814, 0x03, 0, 0},
+ {0x5815, 0x06, 0, 0}, {0x5816, 0x0a, 0, 0}, {0x5817, 0x0f, 0, 0},
+ {0x5818, 0x0a, 0, 0}, {0x5819, 0x05, 0, 0}, {0x581a, 0x01, 0, 0},
+ {0x581b, 0x00, 0, 0}, {0x581c, 0x00, 0, 0}, {0x581d, 0x03, 0, 0},
+ {0x581e, 0x08, 0, 0}, {0x581f, 0x0c, 0, 0}, {0x5820, 0x0a, 0, 0},
+ {0x5821, 0x05, 0, 0}, {0x5822, 0x01, 0, 0}, {0x5823, 0x00, 0, 0},
+ {0x5824, 0x00, 0, 0}, {0x5825, 0x03, 0, 0}, {0x5826, 0x08, 0, 0},
+ {0x5827, 0x0c, 0, 0}, {0x5828, 0x0e, 0, 0}, {0x5829, 0x08, 0, 0},
+ {0x582a, 0x06, 0, 0}, {0x582b, 0x04, 0, 0}, {0x582c, 0x05, 0, 0},
+ {0x582d, 0x07, 0, 0}, {0x582e, 0x0b, 0, 0}, {0x582f, 0x12, 0, 0},
+ {0x5830, 0x18, 0, 0}, {0x5831, 0x10, 0, 0}, {0x5832, 0x0c, 0, 0},
+ {0x5833, 0x0a, 0, 0}, {0x5834, 0x0b, 0, 0}, {0x5835, 0x0e, 0, 0},
+ {0x5836, 0x15, 0, 0}, {0x5837, 0x19, 0, 0}, {0x5838, 0x32, 0, 0},
+ {0x5839, 0x1f, 0, 0}, {0x583a, 0x18, 0, 0}, {0x583b, 0x16, 0, 0},
+ {0x583c, 0x17, 0, 0}, {0x583d, 0x1e, 0, 0}, {0x583e, 0x26, 0, 0},
+ {0x583f, 0x53, 0, 0}, {0x5840, 0x10, 0, 0}, {0x5841, 0x0f, 0, 0},
+ {0x5842, 0x0d, 0, 0}, {0x5843, 0x0c, 0, 0}, {0x5844, 0x0e, 0, 0},
+ {0x5845, 0x09, 0, 0}, {0x5846, 0x11, 0, 0}, {0x5847, 0x10, 0, 0},
+ {0x5848, 0x10, 0, 0}, {0x5849, 0x10, 0, 0}, {0x584a, 0x10, 0, 0},
+ {0x584b, 0x0e, 0, 0}, {0x584c, 0x10, 0, 0}, {0x584d, 0x10, 0, 0},
+ {0x584e, 0x11, 0, 0}, {0x584f, 0x10, 0, 0}, {0x5850, 0x0f, 0, 0},
+ {0x5851, 0x0c, 0, 0}, {0x5852, 0x0f, 0, 0}, {0x5853, 0x10, 0, 0},
+ {0x5854, 0x10, 0, 0}, {0x5855, 0x0f, 0, 0}, {0x5856, 0x0e, 0, 0},
+ {0x5857, 0x0b, 0, 0}, {0x5858, 0x10, 0, 0}, {0x5859, 0x0d, 0, 0},
+ {0x585a, 0x0d, 0, 0}, {0x585b, 0x0c, 0, 0}, {0x585c, 0x0c, 0, 0},
+ {0x585d, 0x0c, 0, 0}, {0x585e, 0x0b, 0, 0}, {0x585f, 0x0c, 0, 0},
+ {0x5860, 0x0c, 0, 0}, {0x5861, 0x0c, 0, 0}, {0x5862, 0x0d, 0, 0},
+ {0x5863, 0x08, 0, 0}, {0x5864, 0x11, 0, 0}, {0x5865, 0x18, 0, 0},
+ {0x5866, 0x18, 0, 0}, {0x5867, 0x19, 0, 0}, {0x5868, 0x17, 0, 0},
+ {0x5869, 0x19, 0, 0}, {0x586a, 0x16, 0, 0}, {0x586b, 0x13, 0, 0},
+ {0x586c, 0x13, 0, 0}, {0x586d, 0x12, 0, 0}, {0x586e, 0x13, 0, 0},
+ {0x586f, 0x16, 0, 0}, {0x5870, 0x14, 0, 0}, {0x5871, 0x12, 0, 0},
+ {0x5872, 0x10, 0, 0}, {0x5873, 0x11, 0, 0}, {0x5874, 0x11, 0, 0},
+ {0x5875, 0x16, 0, 0}, {0x5876, 0x14, 0, 0}, {0x5877, 0x11, 0, 0},
+ {0x5878, 0x10, 0, 0}, {0x5879, 0x0f, 0, 0}, {0x587a, 0x10, 0, 0},
+ {0x587b, 0x14, 0, 0}, {0x587c, 0x13, 0, 0}, {0x587d, 0x12, 0, 0},
+ {0x587e, 0x11, 0, 0}, {0x587f, 0x11, 0, 0}, {0x5880, 0x12, 0, 0},
+ {0x5881, 0x15, 0, 0}, {0x5882, 0x14, 0, 0}, {0x5883, 0x15, 0, 0},
+ {0x5884, 0x15, 0, 0}, {0x5885, 0x15, 0, 0}, {0x5886, 0x13, 0, 0},
+ {0x5887, 0x17, 0, 0}, {0x3710, 0x10, 0, 0}, {0x3632, 0x51, 0, 0},
+ {0x3702, 0x10, 0, 0}, {0x3703, 0xb2, 0, 0}, {0x3704, 0x18, 0, 0},
+ {0x370b, 0x40, 0, 0}, {0x370d, 0x03, 0, 0}, {0x3631, 0x01, 0, 0},
+ {0x3632, 0x52, 0, 0}, {0x3606, 0x24, 0, 0}, {0x3620, 0x96, 0, 0},
+ {0x5785, 0x07, 0, 0}, {0x3a13, 0x30, 0, 0}, {0x3600, 0x52, 0, 0},
+ {0x3604, 0x48, 0, 0}, {0x3606, 0x1b, 0, 0}, {0x370d, 0x0b, 0, 0},
+ {0x370f, 0xc0, 0, 0}, {0x3709, 0x01, 0, 0}, {0x3823, 0x00, 0, 0},
+ {0x5007, 0x00, 0, 0}, {0x5009, 0x00, 0, 0}, {0x5011, 0x00, 0, 0},
+ {0x5013, 0x00, 0, 0}, {0x519e, 0x00, 0, 0}, {0x5086, 0x00, 0, 0},
+ {0x5087, 0x00, 0, 0}, {0x5088, 0x00, 0, 0}, {0x5089, 0x00, 0, 0},
+ {0x302b, 0x00, 0, 0}, {0x3621, 0x87, 0, 0}, {0x3a00, 0x78, 0, 0},
+};
+
+
+static struct reg_value ov5642_setting_30fps_XGA_1024_768[] = {
+ {0x3103, 0x93, 0, 0}, {0x3008, 0x82, 0, 0}, {0x3017, 0x7f, 0, 0},
+ {0x3018, 0xfc, 0, 0}, {0x3615, 0xf0, 0, 0}, {0x3000, 0x00, 0, 0},
+ {0x3001, 0x00, 0, 0}, {0x3002, 0x5c, 0, 0}, {0x3003, 0x00, 0, 0},
+ {0x3004, 0xff, 0, 0}, {0x3005, 0xff, 0, 0}, {0x3006, 0x43, 0, 0},
+ {0x3007, 0x37, 0, 0}, {0x3011, 0x09, 0, 0}, {0x3012, 0x02, 0, 0},
+ {0x3010, 0x00, 0, 0}, {0x460c, 0x20, 0, 0}, {0x3815, 0x04, 0, 0},
+ {0x370c, 0xa0, 0, 0}, {0x3602, 0xfc, 0, 0}, {0x3612, 0xff, 0, 0},
+ {0x3634, 0xc0, 0, 0}, {0x3613, 0x00, 0, 0}, {0x3605, 0x7c, 0, 0},
+ {0x3621, 0x09, 0, 0}, {0x3622, 0x60, 0, 0}, {0x3604, 0x40, 0, 0},
+ {0x3603, 0xa7, 0, 0}, {0x3603, 0x27, 0, 0}, {0x4000, 0x21, 0, 0},
+ {0x401d, 0x22, 0, 0}, {0x3600, 0x54, 0, 0}, {0x3605, 0x04, 0, 0},
+ {0x3606, 0x3f, 0, 0}, {0x3c01, 0x80, 0, 0}, {0x5000, 0x4f, 0, 0},
+ {0x5020, 0x04, 0, 0}, {0x5181, 0x79, 0, 0}, {0x5182, 0x00, 0, 0},
+ {0x5185, 0x22, 0, 0}, {0x5197, 0x01, 0, 0}, {0x5001, 0xff, 0, 0},
+ {0x5500, 0x0a, 0, 0}, {0x5504, 0x00, 0, 0}, {0x5505, 0x7f, 0, 0},
+ {0x5080, 0x08, 0, 0}, {0x300e, 0x18, 0, 0}, {0x4610, 0x00, 0, 0},
+ {0x471d, 0x05, 0, 0}, {0x4708, 0x06, 0, 0}, {0x3808, 0x02, 0, 0},
+ {0x3809, 0x80, 0, 0}, {0x380a, 0x01, 0, 0}, {0x380b, 0xe0, 0, 0},
+ {0x380e, 0x07, 0, 0}, {0x380f, 0xd0, 0, 0}, {0x501f, 0x00, 0, 0},
+ {0x5000, 0x4f, 0, 0}, {0x4300, 0x30, 0, 0}, {0x3503, 0x07, 0, 0},
+ {0x3501, 0x73, 0, 0}, {0x3502, 0x80, 0, 0}, {0x350b, 0x00, 0, 0},
+ {0x3503, 0x07, 0, 0}, {0x3824, 0x11, 0, 0}, {0x3825, 0xb0, 0, 0},
+ {0x3501, 0x1e, 0, 0}, {0x3502, 0x80, 0, 0}, {0x350b, 0x7f, 0, 0},
+ {0x380c, 0x07, 0, 0}, {0x380d, 0x2a, 0, 0}, {0x380e, 0x03, 0, 0},
+ {0x380f, 0xe8, 0, 0}, {0x3a0d, 0x04, 0, 0}, {0x3a0e, 0x03, 0, 0},
+ {0x3818, 0xc1, 0, 0}, {0x3705, 0xdb, 0, 0}, {0x370a, 0x81, 0, 0},
+ {0x3801, 0x80, 0, 0}, {0x3621, 0xc7, 0, 0}, {0x3801, 0x50, 0, 0},
+ {0x3803, 0x08, 0, 0}, {0x3827, 0x08, 0, 0}, {0x3810, 0x80, 0, 0},
+ {0x3804, 0x05, 0, 0}, {0x3805, 0x00, 0, 0}, {0x5682, 0x05, 0, 0},
+ {0x5683, 0x00, 0, 0}, {0x3806, 0x03, 0, 0}, {0x3807, 0xc0, 0, 0},
+ {0x5686, 0x03, 0, 0}, {0x5687, 0xbc, 0, 0}, {0x3a00, 0x78, 0, 0},
+ {0x3a1a, 0x05, 0, 0}, {0x3a13, 0x30, 0, 0}, {0x3a18, 0x00, 0, 0},
+ {0x3a19, 0x7c, 0, 0}, {0x3a08, 0x12, 0, 0}, {0x3a09, 0xc0, 0, 0},
+ {0x3a0a, 0x0f, 0, 0}, {0x3a0b, 0xa0, 0, 0}, {0x350c, 0x07, 0, 0},
+ {0x350d, 0xd0, 0, 0}, {0x3500, 0x00, 0, 0}, {0x3501, 0x00, 0, 0},
+ {0x3502, 0x00, 0, 0}, {0x350a, 0x00, 0, 0}, {0x350b, 0x00, 0, 0},
+ {0x3503, 0x00, 0, 0}, {0x528a, 0x02, 0, 0}, {0x528b, 0x04, 0, 0},
+ {0x528c, 0x08, 0, 0}, {0x528d, 0x08, 0, 0}, {0x528e, 0x08, 0, 0},
+ {0x528f, 0x10, 0, 0}, {0x5290, 0x10, 0, 0}, {0x5292, 0x00, 0, 0},
+ {0x5293, 0x02, 0, 0}, {0x5294, 0x00, 0, 0}, {0x5295, 0x02, 0, 0},
+ {0x5296, 0x00, 0, 0}, {0x5297, 0x02, 0, 0}, {0x5298, 0x00, 0, 0},
+ {0x5299, 0x02, 0, 0}, {0x529a, 0x00, 0, 0}, {0x529b, 0x02, 0, 0},
+ {0x529c, 0x00, 0, 0}, {0x529d, 0x02, 0, 0}, {0x529e, 0x00, 0, 0},
+ {0x529f, 0x02, 0, 0}, {0x3a0f, 0x3c, 0, 0}, {0x3a10, 0x30, 0, 0},
+ {0x3a1b, 0x3c, 0, 0}, {0x3a1e, 0x30, 0, 0}, {0x3a11, 0x70, 0, 0},
+ {0x3a1f, 0x10, 0, 0}, {0x3030, 0x2b, 0, 0}, {0x3a02, 0x00, 0, 0},
+ {0x3a03, 0x7d, 0, 0}, {0x3a04, 0x00, 0, 0}, {0x3a14, 0x00, 0, 0},
+ {0x3a15, 0x7d, 0, 0}, {0x3a16, 0x00, 0, 0}, {0x3a00, 0x78, 0, 0},
+ {0x3a08, 0x12, 0, 0}, {0x3a09, 0xc0, 0, 0}, {0x3a0a, 0x0f, 0, 0},
+ {0x3a0b, 0xa0, 0, 0}, {0x3a0d, 0x04, 0, 0}, {0x3a0e, 0x03, 0, 0},
+ {0x5193, 0x70, 0, 0}, {0x589b, 0x04, 0, 0}, {0x589a, 0xc5, 0, 0},
+ {0x401e, 0x20, 0, 0}, {0x4001, 0x42, 0, 0}, {0x401c, 0x04, 0, 0},
+ {0x528a, 0x01, 0, 0}, {0x528b, 0x04, 0, 0}, {0x528c, 0x08, 0, 0},
+ {0x528d, 0x10, 0, 0}, {0x528e, 0x20, 0, 0}, {0x528f, 0x28, 0, 0},
+ {0x5290, 0x30, 0, 0}, {0x5292, 0x00, 0, 0}, {0x5293, 0x01, 0, 0},
+ {0x5294, 0x00, 0, 0}, {0x5295, 0x04, 0, 0}, {0x5296, 0x00, 0, 0},
+ {0x5297, 0x08, 0, 0}, {0x5298, 0x00, 0, 0}, {0x5299, 0x10, 0, 0},
+ {0x529a, 0x00, 0, 0}, {0x529b, 0x20, 0, 0}, {0x529c, 0x00, 0, 0},
+ {0x529d, 0x28, 0, 0}, {0x529e, 0x00, 0, 0}, {0x529f, 0x30, 0, 0},
+ {0x5282, 0x00, 0, 0}, {0x5300, 0x00, 0, 0}, {0x5301, 0x20, 0, 0},
+ {0x5302, 0x00, 0, 0}, {0x5303, 0x7c, 0, 0}, {0x530c, 0x00, 0, 0},
+ {0x530d, 0x0c, 0, 0}, {0x530e, 0x20, 0, 0}, {0x530f, 0x80, 0, 0},
+ {0x5310, 0x20, 0, 0}, {0x5311, 0x80, 0, 0}, {0x5308, 0x20, 0, 0},
+ {0x5309, 0x40, 0, 0}, {0x5304, 0x00, 0, 0}, {0x5305, 0x30, 0, 0},
+ {0x5306, 0x00, 0, 0}, {0x5307, 0x80, 0, 0}, {0x5314, 0x08, 0, 0},
+ {0x5315, 0x20, 0, 0}, {0x5319, 0x30, 0, 0}, {0x5316, 0x10, 0, 0},
+ {0x5317, 0x00, 0, 0}, {0x5318, 0x02, 0, 0}, {0x5380, 0x01, 0, 0},
+ {0x5381, 0x00, 0, 0}, {0x5382, 0x00, 0, 0}, {0x5383, 0x4e, 0, 0},
+ {0x5384, 0x00, 0, 0}, {0x5385, 0x0f, 0, 0}, {0x5386, 0x00, 0, 0},
+ {0x5387, 0x00, 0, 0}, {0x5388, 0x01, 0, 0}, {0x5389, 0x15, 0, 0},
+ {0x538a, 0x00, 0, 0}, {0x538b, 0x31, 0, 0}, {0x538c, 0x00, 0, 0},
+ {0x538d, 0x00, 0, 0}, {0x538e, 0x00, 0, 0}, {0x538f, 0x0f, 0, 0},
+ {0x5390, 0x00, 0, 0}, {0x5391, 0xab, 0, 0}, {0x5392, 0x00, 0, 0},
+ {0x5393, 0xa2, 0, 0}, {0x5394, 0x08, 0, 0}, {0x5480, 0x14, 0, 0},
+ {0x5481, 0x21, 0, 0}, {0x5482, 0x36, 0, 0}, {0x5483, 0x57, 0, 0},
+ {0x5484, 0x65, 0, 0}, {0x5485, 0x71, 0, 0}, {0x5486, 0x7d, 0, 0},
+ {0x5487, 0x87, 0, 0}, {0x5488, 0x91, 0, 0}, {0x5489, 0x9a, 0, 0},
+ {0x548a, 0xaa, 0, 0}, {0x548b, 0xb8, 0, 0}, {0x548c, 0xcd, 0, 0},
+ {0x548d, 0xdd, 0, 0}, {0x548e, 0xea, 0, 0}, {0x548f, 0x1d, 0, 0},
+ {0x5490, 0x05, 0, 0}, {0x5491, 0x00, 0, 0}, {0x5492, 0x04, 0, 0},
+ {0x5493, 0x20, 0, 0}, {0x5494, 0x03, 0, 0}, {0x5495, 0x60, 0, 0},
+ {0x5496, 0x02, 0, 0}, {0x5497, 0xb8, 0, 0}, {0x5498, 0x02, 0, 0},
+ {0x5499, 0x86, 0, 0}, {0x549a, 0x02, 0, 0}, {0x549b, 0x5b, 0, 0},
+ {0x549c, 0x02, 0, 0}, {0x549d, 0x3b, 0, 0}, {0x549e, 0x02, 0, 0},
+ {0x549f, 0x1c, 0, 0}, {0x54a0, 0x02, 0, 0}, {0x54a1, 0x04, 0, 0},
+ {0x54a2, 0x01, 0, 0}, {0x54a3, 0xed, 0, 0}, {0x54a4, 0x01, 0, 0},
+ {0x54a5, 0xc5, 0, 0}, {0x54a6, 0x01, 0, 0}, {0x54a7, 0xa5, 0, 0},
+ {0x54a8, 0x01, 0, 0}, {0x54a9, 0x6c, 0, 0}, {0x54aa, 0x01, 0, 0},
+ {0x54ab, 0x41, 0, 0}, {0x54ac, 0x01, 0, 0}, {0x54ad, 0x20, 0, 0},
+ {0x54ae, 0x00, 0, 0}, {0x54af, 0x16, 0, 0}, {0x54b0, 0x01, 0, 0},
+ {0x54b1, 0x20, 0, 0}, {0x54b2, 0x00, 0, 0}, {0x54b3, 0x10, 0, 0},
+ {0x54b4, 0x00, 0, 0}, {0x54b5, 0xf0, 0, 0}, {0x54b6, 0x00, 0, 0},
+ {0x54b7, 0xdf, 0, 0}, {0x5402, 0x3f, 0, 0}, {0x5403, 0x00, 0, 0},
+ {0x3406, 0x00, 0, 0}, {0x5180, 0xff, 0, 0}, {0x5181, 0x52, 0, 0},
+ {0x5182, 0x11, 0, 0}, {0x5183, 0x14, 0, 0}, {0x5184, 0x25, 0, 0},
+ {0x5185, 0x24, 0, 0}, {0x5186, 0x06, 0, 0}, {0x5187, 0x08, 0, 0},
+ {0x5188, 0x08, 0, 0}, {0x5189, 0x7c, 0, 0}, {0x518a, 0x60, 0, 0},
+ {0x518b, 0xb2, 0, 0}, {0x518c, 0xb2, 0, 0}, {0x518d, 0x44, 0, 0},
+ {0x518e, 0x3d, 0, 0}, {0x518f, 0x58, 0, 0}, {0x5190, 0x46, 0, 0},
+ {0x5191, 0xf8, 0, 0}, {0x5192, 0x04, 0, 0}, {0x5193, 0x70, 0, 0},
+ {0x5194, 0xf0, 0, 0}, {0x5195, 0xf0, 0, 0}, {0x5196, 0x03, 0, 0},
+ {0x5197, 0x01, 0, 0}, {0x5198, 0x04, 0, 0}, {0x5199, 0x12, 0, 0},
+ {0x519a, 0x04, 0, 0}, {0x519b, 0x00, 0, 0}, {0x519c, 0x06, 0, 0},
+ {0x519d, 0x82, 0, 0}, {0x519e, 0x00, 0, 0}, {0x5025, 0x80, 0, 0},
+ {0x3a0f, 0x38, 0, 0}, {0x3a10, 0x30, 0, 0}, {0x3a1b, 0x3a, 0, 0},
+ {0x3a1e, 0x2e, 0, 0}, {0x3a11, 0x60, 0, 0}, {0x3a1f, 0x10, 0, 0},
+ {0x5688, 0xa6, 0, 0}, {0x5689, 0x6a, 0, 0}, {0x568a, 0xea, 0, 0},
+ {0x568b, 0xae, 0, 0}, {0x568c, 0xa6, 0, 0}, {0x568d, 0x6a, 0, 0},
+ {0x568e, 0x62, 0, 0}, {0x568f, 0x26, 0, 0}, {0x5583, 0x40, 0, 0},
+ {0x5584, 0x40, 0, 0}, {0x5580, 0x02, 0, 0}, {0x5000, 0xcf, 0, 0},
+ {0x5800, 0x27, 0, 0}, {0x5801, 0x19, 0, 0}, {0x5802, 0x12, 0, 0},
+ {0x5803, 0x0f, 0, 0}, {0x5804, 0x10, 0, 0}, {0x5805, 0x15, 0, 0},
+ {0x5806, 0x1e, 0, 0}, {0x5807, 0x2f, 0, 0}, {0x5808, 0x15, 0, 0},
+ {0x5809, 0x0d, 0, 0}, {0x580a, 0x0a, 0, 0}, {0x580b, 0x09, 0, 0},
+ {0x580c, 0x0a, 0, 0}, {0x580d, 0x0c, 0, 0}, {0x580e, 0x12, 0, 0},
+ {0x580f, 0x19, 0, 0}, {0x5810, 0x0b, 0, 0}, {0x5811, 0x07, 0, 0},
+ {0x5812, 0x04, 0, 0}, {0x5813, 0x03, 0, 0}, {0x5814, 0x03, 0, 0},
+ {0x5815, 0x06, 0, 0}, {0x5816, 0x0a, 0, 0}, {0x5817, 0x0f, 0, 0},
+ {0x5818, 0x0a, 0, 0}, {0x5819, 0x05, 0, 0}, {0x581a, 0x01, 0, 0},
+ {0x581b, 0x00, 0, 0}, {0x581c, 0x00, 0, 0}, {0x581d, 0x03, 0, 0},
+ {0x581e, 0x08, 0, 0}, {0x581f, 0x0c, 0, 0}, {0x5820, 0x0a, 0, 0},
+ {0x5821, 0x05, 0, 0}, {0x5822, 0x01, 0, 0}, {0x5823, 0x00, 0, 0},
+ {0x5824, 0x00, 0, 0}, {0x5825, 0x03, 0, 0}, {0x5826, 0x08, 0, 0},
+ {0x5827, 0x0c, 0, 0}, {0x5828, 0x0e, 0, 0}, {0x5829, 0x08, 0, 0},
+ {0x582a, 0x06, 0, 0}, {0x582b, 0x04, 0, 0}, {0x582c, 0x05, 0, 0},
+ {0x582d, 0x07, 0, 0}, {0x582e, 0x0b, 0, 0}, {0x582f, 0x12, 0, 0},
+ {0x5830, 0x18, 0, 0}, {0x5831, 0x10, 0, 0}, {0x5832, 0x0c, 0, 0},
+ {0x5833, 0x0a, 0, 0}, {0x5834, 0x0b, 0, 0}, {0x5835, 0x0e, 0, 0},
+ {0x5836, 0x15, 0, 0}, {0x5837, 0x19, 0, 0}, {0x5838, 0x32, 0, 0},
+ {0x5839, 0x1f, 0, 0}, {0x583a, 0x18, 0, 0}, {0x583b, 0x16, 0, 0},
+ {0x583c, 0x17, 0, 0}, {0x583d, 0x1e, 0, 0}, {0x583e, 0x26, 0, 0},
+ {0x583f, 0x53, 0, 0}, {0x5840, 0x10, 0, 0}, {0x5841, 0x0f, 0, 0},
+ {0x5842, 0x0d, 0, 0}, {0x5843, 0x0c, 0, 0}, {0x5844, 0x0e, 0, 0},
+ {0x5845, 0x09, 0, 0}, {0x5846, 0x11, 0, 0}, {0x5847, 0x10, 0, 0},
+ {0x5848, 0x10, 0, 0}, {0x5849, 0x10, 0, 0}, {0x584a, 0x10, 0, 0},
+ {0x584b, 0x0e, 0, 0}, {0x584c, 0x10, 0, 0}, {0x584d, 0x10, 0, 0},
+ {0x584e, 0x11, 0, 0}, {0x584f, 0x10, 0, 0}, {0x5850, 0x0f, 0, 0},
+ {0x5851, 0x0c, 0, 0}, {0x5852, 0x0f, 0, 0}, {0x5853, 0x10, 0, 0},
+ {0x5854, 0x10, 0, 0}, {0x5855, 0x0f, 0, 0}, {0x5856, 0x0e, 0, 0},
+ {0x5857, 0x0b, 0, 0}, {0x5858, 0x10, 0, 0}, {0x5859, 0x0d, 0, 0},
+ {0x585a, 0x0d, 0, 0}, {0x585b, 0x0c, 0, 0}, {0x585c, 0x0c, 0, 0},
+ {0x585d, 0x0c, 0, 0}, {0x585e, 0x0b, 0, 0}, {0x585f, 0x0c, 0, 0},
+ {0x5860, 0x0c, 0, 0}, {0x5861, 0x0c, 0, 0}, {0x5862, 0x0d, 0, 0},
+ {0x5863, 0x08, 0, 0}, {0x5864, 0x11, 0, 0}, {0x5865, 0x18, 0, 0},
+ {0x5866, 0x18, 0, 0}, {0x5867, 0x19, 0, 0}, {0x5868, 0x17, 0, 0},
+ {0x5869, 0x19, 0, 0}, {0x586a, 0x16, 0, 0}, {0x586b, 0x13, 0, 0},
+ {0x586c, 0x13, 0, 0}, {0x586d, 0x12, 0, 0}, {0x586e, 0x13, 0, 0},
+ {0x586f, 0x16, 0, 0}, {0x5870, 0x14, 0, 0}, {0x5871, 0x12, 0, 0},
+ {0x5872, 0x10, 0, 0}, {0x5873, 0x11, 0, 0}, {0x5874, 0x11, 0, 0},
+ {0x5875, 0x16, 0, 0}, {0x5876, 0x14, 0, 0}, {0x5877, 0x11, 0, 0},
+ {0x5878, 0x10, 0, 0}, {0x5879, 0x0f, 0, 0}, {0x587a, 0x10, 0, 0},
+ {0x587b, 0x14, 0, 0}, {0x587c, 0x13, 0, 0}, {0x587d, 0x12, 0, 0},
+ {0x587e, 0x11, 0, 0}, {0x587f, 0x11, 0, 0}, {0x5880, 0x12, 0, 0},
+ {0x5881, 0x15, 0, 0}, {0x5882, 0x14, 0, 0}, {0x5883, 0x15, 0, 0},
+ {0x5884, 0x15, 0, 0}, {0x5885, 0x15, 0, 0}, {0x5886, 0x13, 0, 0},
+ {0x5887, 0x17, 0, 0}, {0x3710, 0x10, 0, 0}, {0x3632, 0x51, 0, 0},
+ {0x3702, 0x10, 0, 0}, {0x3703, 0xb2, 0, 0}, {0x3704, 0x18, 0, 0},
+ {0x370b, 0x40, 0, 0}, {0x370d, 0x03, 0, 0}, {0x3631, 0x01, 0, 0},
+ {0x3632, 0x52, 0, 0}, {0x3606, 0x24, 0, 0}, {0x3620, 0x96, 0, 0},
+ {0x5785, 0x07, 0, 0}, {0x3a13, 0x30, 0, 0}, {0x3600, 0x52, 0, 0},
+ {0x3604, 0x48, 0, 0}, {0x3606, 0x1b, 0, 0}, {0x370d, 0x0b, 0, 0},
+ {0x370f, 0xc0, 0, 0}, {0x3709, 0x01, 0, 0}, {0x3823, 0x00, 0, 0},
+ {0x5007, 0x00, 0, 0}, {0x5009, 0x00, 0, 0}, {0x5011, 0x00, 0, 0},
+ {0x5013, 0x00, 0, 0}, {0x519e, 0x00, 0, 0}, {0x5086, 0x00, 0, 0},
+ {0x5087, 0x00, 0, 0}, {0x5088, 0x00, 0, 0}, {0x5089, 0x00, 0, 0},
+ {0x302b, 0x00, 0, 0}, {0x3621, 0x87, 0, 0}, {0x3a00, 0x78, 0, 0},
+ {0x3808, 0x04, 0, 0}, {0x3809, 0x00, 0, 0}, {0x380a, 0x03, 0, 0},
+ {0x380b, 0x00, 0, 0}, {0x3815, 0x02, 0, 0}, {0x302c, 0x60, 0x60, 0},
+};
+
+static struct reg_value ov5642_setting_15fps_XGA_1024_768[] = {
+ {0x3103, 0x93, 0, 0}, {0x3008, 0x82, 0, 0}, {0x3017, 0x7f, 0, 0},
+ {0x3018, 0xfc, 0, 0}, {0x3615, 0xf0, 0, 0}, {0x3000, 0x00, 0, 0},
+ {0x3001, 0x00, 0, 0}, {0x3002, 0x5c, 0, 0}, {0x3003, 0x00, 0, 0},
+ {0x3004, 0xff, 0, 0}, {0x3005, 0xff, 0, 0}, {0x3006, 0x43, 0, 0},
+ {0x3007, 0x37, 0, 0}, {0x3011, 0x09, 0, 0}, {0x3012, 0x02, 0, 0},
+ {0x3010, 0x00, 0, 0}, {0x460c, 0x20, 0, 0}, {0x3815, 0x04, 0, 0},
+ {0x370c, 0xa0, 0, 0}, {0x3602, 0xfc, 0, 0}, {0x3612, 0xff, 0, 0},
+ {0x3634, 0xc0, 0, 0}, {0x3613, 0x00, 0, 0}, {0x3605, 0x7c, 0, 0},
+ {0x3621, 0x09, 0, 0}, {0x3622, 0x60, 0, 0}, {0x3604, 0x40, 0, 0},
+ {0x3603, 0xa7, 0, 0}, {0x3603, 0x27, 0, 0}, {0x4000, 0x21, 0, 0},
+ {0x401d, 0x22, 0, 0}, {0x3600, 0x54, 0, 0}, {0x3605, 0x04, 0, 0},
+ {0x3606, 0x3f, 0, 0}, {0x3c01, 0x80, 0, 0}, {0x5000, 0x4f, 0, 0},
+ {0x5020, 0x04, 0, 0}, {0x5181, 0x79, 0, 0}, {0x5182, 0x00, 0, 0},
+ {0x5185, 0x22, 0, 0}, {0x5197, 0x01, 0, 0}, {0x5001, 0xff, 0, 0},
+ {0x5500, 0x0a, 0, 0}, {0x5504, 0x00, 0, 0}, {0x5505, 0x7f, 0, 0},
+ {0x5080, 0x08, 0, 0}, {0x300e, 0x18, 0, 0}, {0x4610, 0x00, 0, 0},
+ {0x471d, 0x05, 0, 0}, {0x4708, 0x06, 0, 0}, {0x3808, 0x02, 0, 0},
+ {0x3809, 0x80, 0, 0}, {0x380a, 0x01, 0, 0}, {0x380b, 0xe0, 0, 0},
+ {0x380e, 0x07, 0, 0}, {0x380f, 0xd0, 0, 0}, {0x501f, 0x00, 0, 0},
+ {0x5000, 0x4f, 0, 0}, {0x4300, 0x30, 0, 0}, {0x3503, 0x07, 0, 0},
+ {0x3501, 0x73, 0, 0}, {0x3502, 0x80, 0, 0}, {0x350b, 0x00, 0, 0},
+ {0x3503, 0x07, 0, 0}, {0x3824, 0x11, 0, 0}, {0x3825, 0xb0, 0, 0},
+ {0x3501, 0x1e, 0, 0}, {0x3502, 0x80, 0, 0}, {0x350b, 0x7f, 0, 0},
+ {0x380c, 0x07, 0, 0}, {0x380d, 0x2a, 0, 0}, {0x380e, 0x07, 0, 0},
+ {0x380f, 0xd0, 0, 0}, {0x3a0d, 0x04, 0, 0}, {0x3a0e, 0x03, 0, 0},
+ {0x3818, 0xc1, 0, 0}, {0x3705, 0xdb, 0, 0}, {0x370a, 0x81, 0, 0},
+ {0x3801, 0x80, 0, 0}, {0x3621, 0xc7, 0, 0}, {0x3801, 0x50, 0, 0},
+ {0x3803, 0x08, 0, 0}, {0x3827, 0x08, 0, 0}, {0x3810, 0x80, 0, 0},
+ {0x3804, 0x05, 0, 0}, {0x3805, 0x00, 0, 0}, {0x5682, 0x05, 0, 0},
+ {0x5683, 0x00, 0, 0}, {0x3806, 0x03, 0, 0}, {0x3807, 0xc0, 0, 0},
+ {0x5686, 0x03, 0, 0}, {0x5687, 0xbc, 0, 0}, {0x3a00, 0x78, 0, 0},
+ {0x3a1a, 0x05, 0, 0}, {0x3a13, 0x30, 0, 0}, {0x3a18, 0x00, 0, 0},
+ {0x3a19, 0x7c, 0, 0}, {0x3a08, 0x12, 0, 0}, {0x3a09, 0xc0, 0, 0},
+ {0x3a0a, 0x0f, 0, 0}, {0x3a0b, 0xa0, 0, 0}, {0x350c, 0x07, 0, 0},
+ {0x350d, 0xd0, 0, 0}, {0x3500, 0x00, 0, 0}, {0x3501, 0x00, 0, 0},
+ {0x3502, 0x00, 0, 0}, {0x350a, 0x00, 0, 0}, {0x350b, 0x00, 0, 0},
+ {0x3503, 0x00, 0, 0}, {0x528a, 0x02, 0, 0}, {0x528b, 0x04, 0, 0},
+ {0x528c, 0x08, 0, 0}, {0x528d, 0x08, 0, 0}, {0x528e, 0x08, 0, 0},
+ {0x528f, 0x10, 0, 0}, {0x5290, 0x10, 0, 0}, {0x5292, 0x00, 0, 0},
+ {0x5293, 0x02, 0, 0}, {0x5294, 0x00, 0, 0}, {0x5295, 0x02, 0, 0},
+ {0x5296, 0x00, 0, 0}, {0x5297, 0x02, 0, 0}, {0x5298, 0x00, 0, 0},
+ {0x5299, 0x02, 0, 0}, {0x529a, 0x00, 0, 0}, {0x529b, 0x02, 0, 0},
+ {0x529c, 0x00, 0, 0}, {0x529d, 0x02, 0, 0}, {0x529e, 0x00, 0, 0},
+ {0x529f, 0x02, 0, 0}, {0x3a0f, 0x3c, 0, 0}, {0x3a10, 0x30, 0, 0},
+ {0x3a1b, 0x3c, 0, 0}, {0x3a1e, 0x30, 0, 0}, {0x3a11, 0x70, 0, 0},
+ {0x3a1f, 0x10, 0, 0}, {0x3030, 0x2b, 0, 0}, {0x3a02, 0x00, 0, 0},
+ {0x3a03, 0x7d, 0, 0}, {0x3a04, 0x00, 0, 0}, {0x3a14, 0x00, 0, 0},
+ {0x3a15, 0x7d, 0, 0}, {0x3a16, 0x00, 0, 0}, {0x3a00, 0x78, 0, 0},
+ {0x3a08, 0x12, 0, 0}, {0x3a09, 0xc0, 0, 0}, {0x3a0a, 0x0f, 0, 0},
+ {0x3a0b, 0xa0, 0, 0}, {0x3a0d, 0x04, 0, 0}, {0x3a0e, 0x03, 0, 0},
+ {0x5193, 0x70, 0, 0}, {0x589b, 0x04, 0, 0}, {0x589a, 0xc5, 0, 0},
+ {0x401e, 0x20, 0, 0}, {0x4001, 0x42, 0, 0}, {0x401c, 0x04, 0, 0},
+ {0x528a, 0x01, 0, 0}, {0x528b, 0x04, 0, 0}, {0x528c, 0x08, 0, 0},
+ {0x528d, 0x10, 0, 0}, {0x528e, 0x20, 0, 0}, {0x528f, 0x28, 0, 0},
+ {0x5290, 0x30, 0, 0}, {0x5292, 0x00, 0, 0}, {0x5293, 0x01, 0, 0},
+ {0x5294, 0x00, 0, 0}, {0x5295, 0x04, 0, 0}, {0x5296, 0x00, 0, 0},
+ {0x5297, 0x08, 0, 0}, {0x5298, 0x00, 0, 0}, {0x5299, 0x10, 0, 0},
+ {0x529a, 0x00, 0, 0}, {0x529b, 0x20, 0, 0}, {0x529c, 0x00, 0, 0},
+ {0x529d, 0x28, 0, 0}, {0x529e, 0x00, 0, 0}, {0x529f, 0x30, 0, 0},
+ {0x5282, 0x00, 0, 0}, {0x5300, 0x00, 0, 0}, {0x5301, 0x20, 0, 0},
+ {0x5302, 0x00, 0, 0}, {0x5303, 0x7c, 0, 0}, {0x530c, 0x00, 0, 0},
+ {0x530d, 0x0c, 0, 0}, {0x530e, 0x20, 0, 0}, {0x530f, 0x80, 0, 0},
+ {0x5310, 0x20, 0, 0}, {0x5311, 0x80, 0, 0}, {0x5308, 0x20, 0, 0},
+ {0x5309, 0x40, 0, 0}, {0x5304, 0x00, 0, 0}, {0x5305, 0x30, 0, 0},
+ {0x5306, 0x00, 0, 0}, {0x5307, 0x80, 0, 0}, {0x5314, 0x08, 0, 0},
+ {0x5315, 0x20, 0, 0}, {0x5319, 0x30, 0, 0}, {0x5316, 0x10, 0, 0},
+ {0x5317, 0x00, 0, 0}, {0x5318, 0x02, 0, 0}, {0x5380, 0x01, 0, 0},
+ {0x5381, 0x00, 0, 0}, {0x5382, 0x00, 0, 0}, {0x5383, 0x4e, 0, 0},
+ {0x5384, 0x00, 0, 0}, {0x5385, 0x0f, 0, 0}, {0x5386, 0x00, 0, 0},
+ {0x5387, 0x00, 0, 0}, {0x5388, 0x01, 0, 0}, {0x5389, 0x15, 0, 0},
+ {0x538a, 0x00, 0, 0}, {0x538b, 0x31, 0, 0}, {0x538c, 0x00, 0, 0},
+ {0x538d, 0x00, 0, 0}, {0x538e, 0x00, 0, 0}, {0x538f, 0x0f, 0, 0},
+ {0x5390, 0x00, 0, 0}, {0x5391, 0xab, 0, 0}, {0x5392, 0x00, 0, 0},
+ {0x5393, 0xa2, 0, 0}, {0x5394, 0x08, 0, 0}, {0x5480, 0x14, 0, 0},
+ {0x5481, 0x21, 0, 0}, {0x5482, 0x36, 0, 0}, {0x5483, 0x57, 0, 0},
+ {0x5484, 0x65, 0, 0}, {0x5485, 0x71, 0, 0}, {0x5486, 0x7d, 0, 0},
+ {0x5487, 0x87, 0, 0}, {0x5488, 0x91, 0, 0}, {0x5489, 0x9a, 0, 0},
+ {0x548a, 0xaa, 0, 0}, {0x548b, 0xb8, 0, 0}, {0x548c, 0xcd, 0, 0},
+ {0x548d, 0xdd, 0, 0}, {0x548e, 0xea, 0, 0}, {0x548f, 0x1d, 0, 0},
+ {0x5490, 0x05, 0, 0}, {0x5491, 0x00, 0, 0}, {0x5492, 0x04, 0, 0},
+ {0x5493, 0x20, 0, 0}, {0x5494, 0x03, 0, 0}, {0x5495, 0x60, 0, 0},
+ {0x5496, 0x02, 0, 0}, {0x5497, 0xb8, 0, 0}, {0x5498, 0x02, 0, 0},
+ {0x5499, 0x86, 0, 0}, {0x549a, 0x02, 0, 0}, {0x549b, 0x5b, 0, 0},
+ {0x549c, 0x02, 0, 0}, {0x549d, 0x3b, 0, 0}, {0x549e, 0x02, 0, 0},
+ {0x549f, 0x1c, 0, 0}, {0x54a0, 0x02, 0, 0}, {0x54a1, 0x04, 0, 0},
+ {0x54a2, 0x01, 0, 0}, {0x54a3, 0xed, 0, 0}, {0x54a4, 0x01, 0, 0},
+ {0x54a5, 0xc5, 0, 0}, {0x54a6, 0x01, 0, 0}, {0x54a7, 0xa5, 0, 0},
+ {0x54a8, 0x01, 0, 0}, {0x54a9, 0x6c, 0, 0}, {0x54aa, 0x01, 0, 0},
+ {0x54ab, 0x41, 0, 0}, {0x54ac, 0x01, 0, 0}, {0x54ad, 0x20, 0, 0},
+ {0x54ae, 0x00, 0, 0}, {0x54af, 0x16, 0, 0}, {0x54b0, 0x01, 0, 0},
+ {0x54b1, 0x20, 0, 0}, {0x54b2, 0x00, 0, 0}, {0x54b3, 0x10, 0, 0},
+ {0x54b4, 0x00, 0, 0}, {0x54b5, 0xf0, 0, 0}, {0x54b6, 0x00, 0, 0},
+ {0x54b7, 0xdf, 0, 0}, {0x5402, 0x3f, 0, 0}, {0x5403, 0x00, 0, 0},
+ {0x3406, 0x00, 0, 0}, {0x5180, 0xff, 0, 0}, {0x5181, 0x52, 0, 0},
+ {0x5182, 0x11, 0, 0}, {0x5183, 0x14, 0, 0}, {0x5184, 0x25, 0, 0},
+ {0x5185, 0x24, 0, 0}, {0x5186, 0x06, 0, 0}, {0x5187, 0x08, 0, 0},
+ {0x5188, 0x08, 0, 0}, {0x5189, 0x7c, 0, 0}, {0x518a, 0x60, 0, 0},
+ {0x518b, 0xb2, 0, 0}, {0x518c, 0xb2, 0, 0}, {0x518d, 0x44, 0, 0},
+ {0x518e, 0x3d, 0, 0}, {0x518f, 0x58, 0, 0}, {0x5190, 0x46, 0, 0},
+ {0x5191, 0xf8, 0, 0}, {0x5192, 0x04, 0, 0}, {0x5193, 0x70, 0, 0},
+ {0x5194, 0xf0, 0, 0}, {0x5195, 0xf0, 0, 0}, {0x5196, 0x03, 0, 0},
+ {0x5197, 0x01, 0, 0}, {0x5198, 0x04, 0, 0}, {0x5199, 0x12, 0, 0},
+ {0x519a, 0x04, 0, 0}, {0x519b, 0x00, 0, 0}, {0x519c, 0x06, 0, 0},
+ {0x519d, 0x82, 0, 0}, {0x519e, 0x00, 0, 0}, {0x5025, 0x80, 0, 0},
+ {0x3a0f, 0x38, 0, 0}, {0x3a10, 0x30, 0, 0}, {0x3a1b, 0x3a, 0, 0},
+ {0x3a1e, 0x2e, 0, 0}, {0x3a11, 0x60, 0, 0}, {0x3a1f, 0x10, 0, 0},
+ {0x5688, 0xa6, 0, 0}, {0x5689, 0x6a, 0, 0}, {0x568a, 0xea, 0, 0},
+ {0x568b, 0xae, 0, 0}, {0x568c, 0xa6, 0, 0}, {0x568d, 0x6a, 0, 0},
+ {0x568e, 0x62, 0, 0}, {0x568f, 0x26, 0, 0}, {0x5583, 0x40, 0, 0},
+ {0x5584, 0x40, 0, 0}, {0x5580, 0x02, 0, 0}, {0x5000, 0xcf, 0, 0},
+ {0x5800, 0x27, 0, 0}, {0x5801, 0x19, 0, 0}, {0x5802, 0x12, 0, 0},
+ {0x5803, 0x0f, 0, 0}, {0x5804, 0x10, 0, 0}, {0x5805, 0x15, 0, 0},
+ {0x5806, 0x1e, 0, 0}, {0x5807, 0x2f, 0, 0}, {0x5808, 0x15, 0, 0},
+ {0x5809, 0x0d, 0, 0}, {0x580a, 0x0a, 0, 0}, {0x580b, 0x09, 0, 0},
+ {0x580c, 0x0a, 0, 0}, {0x580d, 0x0c, 0, 0}, {0x580e, 0x12, 0, 0},
+ {0x580f, 0x19, 0, 0}, {0x5810, 0x0b, 0, 0}, {0x5811, 0x07, 0, 0},
+ {0x5812, 0x04, 0, 0}, {0x5813, 0x03, 0, 0}, {0x5814, 0x03, 0, 0},
+ {0x5815, 0x06, 0, 0}, {0x5816, 0x0a, 0, 0}, {0x5817, 0x0f, 0, 0},
+ {0x5818, 0x0a, 0, 0}, {0x5819, 0x05, 0, 0}, {0x581a, 0x01, 0, 0},
+ {0x581b, 0x00, 0, 0}, {0x581c, 0x00, 0, 0}, {0x581d, 0x03, 0, 0},
+ {0x581e, 0x08, 0, 0}, {0x581f, 0x0c, 0, 0}, {0x5820, 0x0a, 0, 0},
+ {0x5821, 0x05, 0, 0}, {0x5822, 0x01, 0, 0}, {0x5823, 0x00, 0, 0},
+ {0x5824, 0x00, 0, 0}, {0x5825, 0x03, 0, 0}, {0x5826, 0x08, 0, 0},
+ {0x5827, 0x0c, 0, 0}, {0x5828, 0x0e, 0, 0}, {0x5829, 0x08, 0, 0},
+ {0x582a, 0x06, 0, 0}, {0x582b, 0x04, 0, 0}, {0x582c, 0x05, 0, 0},
+ {0x582d, 0x07, 0, 0}, {0x582e, 0x0b, 0, 0}, {0x582f, 0x12, 0, 0},
+ {0x5830, 0x18, 0, 0}, {0x5831, 0x10, 0, 0}, {0x5832, 0x0c, 0, 0},
+ {0x5833, 0x0a, 0, 0}, {0x5834, 0x0b, 0, 0}, {0x5835, 0x0e, 0, 0},
+ {0x5836, 0x15, 0, 0}, {0x5837, 0x19, 0, 0}, {0x5838, 0x32, 0, 0},
+ {0x5839, 0x1f, 0, 0}, {0x583a, 0x18, 0, 0}, {0x583b, 0x16, 0, 0},
+ {0x583c, 0x17, 0, 0}, {0x583d, 0x1e, 0, 0}, {0x583e, 0x26, 0, 0},
+ {0x583f, 0x53, 0, 0}, {0x5840, 0x10, 0, 0}, {0x5841, 0x0f, 0, 0},
+ {0x5842, 0x0d, 0, 0}, {0x5843, 0x0c, 0, 0}, {0x5844, 0x0e, 0, 0},
+ {0x5845, 0x09, 0, 0}, {0x5846, 0x11, 0, 0}, {0x5847, 0x10, 0, 0},
+ {0x5848, 0x10, 0, 0}, {0x5849, 0x10, 0, 0}, {0x584a, 0x10, 0, 0},
+ {0x584b, 0x0e, 0, 0}, {0x584c, 0x10, 0, 0}, {0x584d, 0x10, 0, 0},
+ {0x584e, 0x11, 0, 0}, {0x584f, 0x10, 0, 0}, {0x5850, 0x0f, 0, 0},
+ {0x5851, 0x0c, 0, 0}, {0x5852, 0x0f, 0, 0}, {0x5853, 0x10, 0, 0},
+ {0x5854, 0x10, 0, 0}, {0x5855, 0x0f, 0, 0}, {0x5856, 0x0e, 0, 0},
+ {0x5857, 0x0b, 0, 0}, {0x5858, 0x10, 0, 0}, {0x5859, 0x0d, 0, 0},
+ {0x585a, 0x0d, 0, 0}, {0x585b, 0x0c, 0, 0}, {0x585c, 0x0c, 0, 0},
+ {0x585d, 0x0c, 0, 0}, {0x585e, 0x0b, 0, 0}, {0x585f, 0x0c, 0, 0},
+ {0x5860, 0x0c, 0, 0}, {0x5861, 0x0c, 0, 0}, {0x5862, 0x0d, 0, 0},
+ {0x5863, 0x08, 0, 0}, {0x5864, 0x11, 0, 0}, {0x5865, 0x18, 0, 0},
+ {0x5866, 0x18, 0, 0}, {0x5867, 0x19, 0, 0}, {0x5868, 0x17, 0, 0},
+ {0x5869, 0x19, 0, 0}, {0x586a, 0x16, 0, 0}, {0x586b, 0x13, 0, 0},
+ {0x586c, 0x13, 0, 0}, {0x586d, 0x12, 0, 0}, {0x586e, 0x13, 0, 0},
+ {0x586f, 0x16, 0, 0}, {0x5870, 0x14, 0, 0}, {0x5871, 0x12, 0, 0},
+ {0x5872, 0x10, 0, 0}, {0x5873, 0x11, 0, 0}, {0x5874, 0x11, 0, 0},
+ {0x5875, 0x16, 0, 0}, {0x5876, 0x14, 0, 0}, {0x5877, 0x11, 0, 0},
+ {0x5878, 0x10, 0, 0}, {0x5879, 0x0f, 0, 0}, {0x587a, 0x10, 0, 0},
+ {0x587b, 0x14, 0, 0}, {0x587c, 0x13, 0, 0}, {0x587d, 0x12, 0, 0},
+ {0x587e, 0x11, 0, 0}, {0x587f, 0x11, 0, 0}, {0x5880, 0x12, 0, 0},
+ {0x5881, 0x15, 0, 0}, {0x5882, 0x14, 0, 0}, {0x5883, 0x15, 0, 0},
+ {0x5884, 0x15, 0, 0}, {0x5885, 0x15, 0, 0}, {0x5886, 0x13, 0, 0},
+ {0x5887, 0x17, 0, 0}, {0x3710, 0x10, 0, 0}, {0x3632, 0x51, 0, 0},
+ {0x3702, 0x10, 0, 0}, {0x3703, 0xb2, 0, 0}, {0x3704, 0x18, 0, 0},
+ {0x370b, 0x40, 0, 0}, {0x370d, 0x03, 0, 0}, {0x3631, 0x01, 0, 0},
+ {0x3632, 0x52, 0, 0}, {0x3606, 0x24, 0, 0}, {0x3620, 0x96, 0, 0},
+ {0x5785, 0x07, 0, 0}, {0x3a13, 0x30, 0, 0}, {0x3600, 0x52, 0, 0},
+ {0x3604, 0x48, 0, 0}, {0x3606, 0x1b, 0, 0}, {0x370d, 0x0b, 0, 0},
+ {0x370f, 0xc0, 0, 0}, {0x3709, 0x01, 0, 0}, {0x3823, 0x00, 0, 0},
+ {0x5007, 0x00, 0, 0}, {0x5009, 0x00, 0, 0}, {0x5011, 0x00, 0, 0},
+ {0x5013, 0x00, 0, 0}, {0x519e, 0x00, 0, 0}, {0x5086, 0x00, 0, 0},
+ {0x5087, 0x00, 0, 0}, {0x5088, 0x00, 0, 0}, {0x5089, 0x00, 0, 0},
+ {0x302b, 0x00, 0, 0}, {0x3621, 0x87, 0, 0}, {0x3a00, 0x78, 0, 0},
+ {0x3808, 0x04, 0, 0}, {0x3809, 0x00, 0, 0}, {0x380a, 0x03, 0, 0},
+ {0x380b, 0x00, 0, 0}, {0x3815, 0x02, 0, 0}, {0x302c, 0x60, 0x60, 0},
+};
+
+static struct reg_value ov5642_setting_30fps_QVGA_320_240[] = {
+ {0x3103, 0x93, 0, 0}, {0x3008, 0x82, 0, 0}, {0x3017, 0x7f, 0, 0},
+ {0x3018, 0xfc, 0, 0}, {0x3615, 0xf0, 0, 0}, {0x3000, 0x00, 0, 0},
+ {0x3001, 0x00, 0, 0}, {0x3002, 0x5c, 0, 0}, {0x3003, 0x00, 0, 0},
+ {0x3004, 0xff, 0, 0}, {0x3005, 0xff, 0, 0}, {0x3006, 0x43, 0, 0},
+ {0x3007, 0x37, 0, 0}, {0x3011, 0x09, 0, 0}, {0x3012, 0x02, 0, 0},
+ {0x3010, 0x00, 0, 0}, {0x460c, 0x20, 0, 0}, {0x3815, 0x04, 0, 0},
+ {0x370c, 0xa0, 0, 0}, {0x3602, 0xfc, 0, 0}, {0x3612, 0xff, 0, 0},
+ {0x3634, 0xc0, 0, 0}, {0x3613, 0x00, 0, 0}, {0x3605, 0x7c, 0, 0},
+ {0x3621, 0x09, 0, 0}, {0x3622, 0x60, 0, 0}, {0x3604, 0x40, 0, 0},
+ {0x3603, 0xa7, 0, 0}, {0x3603, 0x27, 0, 0}, {0x4000, 0x21, 0, 0},
+ {0x401d, 0x22, 0, 0}, {0x3600, 0x54, 0, 0}, {0x3605, 0x04, 0, 0},
+ {0x3606, 0x3f, 0, 0}, {0x3c01, 0x80, 0, 0}, {0x5000, 0x4f, 0, 0},
+ {0x5020, 0x04, 0, 0}, {0x5181, 0x79, 0, 0}, {0x5182, 0x00, 0, 0},
+ {0x5185, 0x22, 0, 0}, {0x5197, 0x01, 0, 0}, {0x5001, 0xff, 0, 0},
+ {0x5500, 0x0a, 0, 0}, {0x5504, 0x00, 0, 0}, {0x5505, 0x7f, 0, 0},
+ {0x5080, 0x08, 0, 0}, {0x300e, 0x18, 0, 0}, {0x4610, 0x00, 0, 0},
+ {0x471d, 0x05, 0, 0}, {0x4708, 0x06, 0, 0}, {0x3808, 0x02, 0, 0},
+ {0x3809, 0x80, 0, 0}, {0x380a, 0x01, 0, 0}, {0x380b, 0xe0, 0, 0},
+ {0x380e, 0x07, 0, 0}, {0x380f, 0xd0, 0, 0}, {0x501f, 0x00, 0, 0},
+ {0x5000, 0x4f, 0, 0}, {0x4300, 0x30, 0, 0}, {0x3503, 0x07, 0, 0},
+ {0x3501, 0x73, 0, 0}, {0x3502, 0x80, 0, 0}, {0x350b, 0x00, 0, 0},
+ {0x3503, 0x07, 0, 0}, {0x3824, 0x11, 0, 0}, {0x3825, 0xb0, 0, 0},
+ {0x3501, 0x1e, 0, 0}, {0x3502, 0x80, 0, 0}, {0x350b, 0x7f, 0, 0},
+ {0x380c, 0x07, 0, 0}, {0x380d, 0x2a, 0, 0}, {0x380e, 0x03, 0, 0},
+ {0x380f, 0xe8, 0, 0}, {0x3a0d, 0x04, 0, 0}, {0x3a0e, 0x03, 0, 0},
+ {0x3818, 0xc1, 0, 0}, {0x3705, 0xdb, 0, 0}, {0x370a, 0x81, 0, 0},
+ {0x3801, 0x80, 0, 0}, {0x3621, 0xc7, 0, 0}, {0x3801, 0x50, 0, 0},
+ {0x3803, 0x08, 0, 0}, {0x3827, 0x08, 0, 0}, {0x3810, 0x80, 0, 0},
+ {0x3804, 0x05, 0, 0}, {0x3805, 0x00, 0, 0}, {0x5682, 0x05, 0, 0},
+ {0x5683, 0x00, 0, 0}, {0x3806, 0x03, 0, 0}, {0x3807, 0xc0, 0, 0},
+ {0x5686, 0x03, 0, 0}, {0x5687, 0xbc, 0, 0}, {0x3a00, 0x78, 0, 0},
+ {0x3a1a, 0x05, 0, 0}, {0x3a13, 0x30, 0, 0}, {0x3a18, 0x00, 0, 0},
+ {0x3a19, 0x7c, 0, 0}, {0x3a08, 0x12, 0, 0}, {0x3a09, 0xc0, 0, 0},
+ {0x3a0a, 0x0f, 0, 0}, {0x3a0b, 0xa0, 0, 0}, {0x350c, 0x07, 0, 0},
+ {0x350d, 0xd0, 0, 0}, {0x3500, 0x00, 0, 0}, {0x3501, 0x00, 0, 0},
+ {0x3502, 0x00, 0, 0}, {0x350a, 0x00, 0, 0}, {0x350b, 0x00, 0, 0},
+ {0x3503, 0x00, 0, 0}, {0x528a, 0x02, 0, 0}, {0x528b, 0x04, 0, 0},
+ {0x528c, 0x08, 0, 0}, {0x528d, 0x08, 0, 0}, {0x528e, 0x08, 0, 0},
+ {0x528f, 0x10, 0, 0}, {0x5290, 0x10, 0, 0}, {0x5292, 0x00, 0, 0},
+ {0x5293, 0x02, 0, 0}, {0x5294, 0x00, 0, 0}, {0x5295, 0x02, 0, 0},
+ {0x5296, 0x00, 0, 0}, {0x5297, 0x02, 0, 0}, {0x5298, 0x00, 0, 0},
+ {0x5299, 0x02, 0, 0}, {0x529a, 0x00, 0, 0}, {0x529b, 0x02, 0, 0},
+ {0x529c, 0x00, 0, 0}, {0x529d, 0x02, 0, 0}, {0x529e, 0x00, 0, 0},
+ {0x529f, 0x02, 0, 0}, {0x3a0f, 0x3c, 0, 0}, {0x3a10, 0x30, 0, 0},
+ {0x3a1b, 0x3c, 0, 0}, {0x3a1e, 0x30, 0, 0}, {0x3a11, 0x70, 0, 0},
+ {0x3a1f, 0x10, 0, 0}, {0x3030, 0x2b, 0, 0}, {0x3a02, 0x00, 0, 0},
+ {0x3a03, 0x7d, 0, 0}, {0x3a04, 0x00, 0, 0}, {0x3a14, 0x00, 0, 0},
+ {0x3a15, 0x7d, 0, 0}, {0x3a16, 0x00, 0, 0}, {0x3a00, 0x78, 0, 0},
+ {0x3a08, 0x12, 0, 0}, {0x3a09, 0xc0, 0, 0}, {0x3a0a, 0x0f, 0, 0},
+ {0x3a0b, 0xa0, 0, 0}, {0x3a0d, 0x04, 0, 0}, {0x3a0e, 0x03, 0, 0},
+ {0x5193, 0x70, 0, 0}, {0x589b, 0x04, 0, 0}, {0x589a, 0xc5, 0, 0},
+ {0x401e, 0x20, 0, 0}, {0x4001, 0x42, 0, 0}, {0x401c, 0x04, 0, 0},
+ {0x528a, 0x01, 0, 0}, {0x528b, 0x04, 0, 0}, {0x528c, 0x08, 0, 0},
+ {0x528d, 0x10, 0, 0}, {0x528e, 0x20, 0, 0}, {0x528f, 0x28, 0, 0},
+ {0x5290, 0x30, 0, 0}, {0x5292, 0x00, 0, 0}, {0x5293, 0x01, 0, 0},
+ {0x5294, 0x00, 0, 0}, {0x5295, 0x04, 0, 0}, {0x5296, 0x00, 0, 0},
+ {0x5297, 0x08, 0, 0}, {0x5298, 0x00, 0, 0}, {0x5299, 0x10, 0, 0},
+ {0x529a, 0x00, 0, 0}, {0x529b, 0x20, 0, 0}, {0x529c, 0x00, 0, 0},
+ {0x529d, 0x28, 0, 0}, {0x529e, 0x00, 0, 0}, {0x529f, 0x30, 0, 0},
+ {0x5282, 0x00, 0, 0}, {0x5300, 0x00, 0, 0}, {0x5301, 0x20, 0, 0},
+ {0x5302, 0x00, 0, 0}, {0x5303, 0x7c, 0, 0}, {0x530c, 0x00, 0, 0},
+ {0x530d, 0x0c, 0, 0}, {0x530e, 0x20, 0, 0}, {0x530f, 0x80, 0, 0},
+ {0x5310, 0x20, 0, 0}, {0x5311, 0x80, 0, 0}, {0x5308, 0x20, 0, 0},
+ {0x5309, 0x40, 0, 0}, {0x5304, 0x00, 0, 0}, {0x5305, 0x30, 0, 0},
+ {0x5306, 0x00, 0, 0}, {0x5307, 0x80, 0, 0}, {0x5314, 0x08, 0, 0},
+ {0x5315, 0x20, 0, 0}, {0x5319, 0x30, 0, 0}, {0x5316, 0x10, 0, 0},
+ {0x5317, 0x00, 0, 0}, {0x5318, 0x02, 0, 0}, {0x5380, 0x01, 0, 0},
+ {0x5381, 0x00, 0, 0}, {0x5382, 0x00, 0, 0}, {0x5383, 0x4e, 0, 0},
+ {0x5384, 0x00, 0, 0}, {0x5385, 0x0f, 0, 0}, {0x5386, 0x00, 0, 0},
+ {0x5387, 0x00, 0, 0}, {0x5388, 0x01, 0, 0}, {0x5389, 0x15, 0, 0},
+ {0x538a, 0x00, 0, 0}, {0x538b, 0x31, 0, 0}, {0x538c, 0x00, 0, 0},
+ {0x538d, 0x00, 0, 0}, {0x538e, 0x00, 0, 0}, {0x538f, 0x0f, 0, 0},
+ {0x5390, 0x00, 0, 0}, {0x5391, 0xab, 0, 0}, {0x5392, 0x00, 0, 0},
+ {0x5393, 0xa2, 0, 0}, {0x5394, 0x08, 0, 0}, {0x5480, 0x14, 0, 0},
+ {0x5481, 0x21, 0, 0}, {0x5482, 0x36, 0, 0}, {0x5483, 0x57, 0, 0},
+ {0x5484, 0x65, 0, 0}, {0x5485, 0x71, 0, 0}, {0x5486, 0x7d, 0, 0},
+ {0x5487, 0x87, 0, 0}, {0x5488, 0x91, 0, 0}, {0x5489, 0x9a, 0, 0},
+ {0x548a, 0xaa, 0, 0}, {0x548b, 0xb8, 0, 0}, {0x548c, 0xcd, 0, 0},
+ {0x548d, 0xdd, 0, 0}, {0x548e, 0xea, 0, 0}, {0x548f, 0x1d, 0, 0},
+ {0x5490, 0x05, 0, 0}, {0x5491, 0x00, 0, 0}, {0x5492, 0x04, 0, 0},
+ {0x5493, 0x20, 0, 0}, {0x5494, 0x03, 0, 0}, {0x5495, 0x60, 0, 0},
+ {0x5496, 0x02, 0, 0}, {0x5497, 0xb8, 0, 0}, {0x5498, 0x02, 0, 0},
+ {0x5499, 0x86, 0, 0}, {0x549a, 0x02, 0, 0}, {0x549b, 0x5b, 0, 0},
+ {0x549c, 0x02, 0, 0}, {0x549d, 0x3b, 0, 0}, {0x549e, 0x02, 0, 0},
+ {0x549f, 0x1c, 0, 0}, {0x54a0, 0x02, 0, 0}, {0x54a1, 0x04, 0, 0},
+ {0x54a2, 0x01, 0, 0}, {0x54a3, 0xed, 0, 0}, {0x54a4, 0x01, 0, 0},
+ {0x54a5, 0xc5, 0, 0}, {0x54a6, 0x01, 0, 0}, {0x54a7, 0xa5, 0, 0},
+ {0x54a8, 0x01, 0, 0}, {0x54a9, 0x6c, 0, 0}, {0x54aa, 0x01, 0, 0},
+ {0x54ab, 0x41, 0, 0}, {0x54ac, 0x01, 0, 0}, {0x54ad, 0x20, 0, 0},
+ {0x54ae, 0x00, 0, 0}, {0x54af, 0x16, 0, 0}, {0x54b0, 0x01, 0, 0},
+ {0x54b1, 0x20, 0, 0}, {0x54b2, 0x00, 0, 0}, {0x54b3, 0x10, 0, 0},
+ {0x54b4, 0x00, 0, 0}, {0x54b5, 0xf0, 0, 0}, {0x54b6, 0x00, 0, 0},
+ {0x54b7, 0xdf, 0, 0}, {0x5402, 0x3f, 0, 0}, {0x5403, 0x00, 0, 0},
+ {0x3406, 0x00, 0, 0}, {0x5180, 0xff, 0, 0}, {0x5181, 0x52, 0, 0},
+ {0x5182, 0x11, 0, 0}, {0x5183, 0x14, 0, 0}, {0x5184, 0x25, 0, 0},
+ {0x5185, 0x24, 0, 0}, {0x5186, 0x06, 0, 0}, {0x5187, 0x08, 0, 0},
+ {0x5188, 0x08, 0, 0}, {0x5189, 0x7c, 0, 0}, {0x518a, 0x60, 0, 0},
+ {0x518b, 0xb2, 0, 0}, {0x518c, 0xb2, 0, 0}, {0x518d, 0x44, 0, 0},
+ {0x518e, 0x3d, 0, 0}, {0x518f, 0x58, 0, 0}, {0x5190, 0x46, 0, 0},
+ {0x5191, 0xf8, 0, 0}, {0x5192, 0x04, 0, 0}, {0x5193, 0x70, 0, 0},
+ {0x5194, 0xf0, 0, 0}, {0x5195, 0xf0, 0, 0}, {0x5196, 0x03, 0, 0},
+ {0x5197, 0x01, 0, 0}, {0x5198, 0x04, 0, 0}, {0x5199, 0x12, 0, 0},
+ {0x519a, 0x04, 0, 0}, {0x519b, 0x00, 0, 0}, {0x519c, 0x06, 0, 0},
+ {0x519d, 0x82, 0, 0}, {0x519e, 0x00, 0, 0}, {0x5025, 0x80, 0, 0},
+ {0x3a0f, 0x38, 0, 0}, {0x3a10, 0x30, 0, 0}, {0x3a1b, 0x3a, 0, 0},
+ {0x3a1e, 0x2e, 0, 0}, {0x3a11, 0x60, 0, 0}, {0x3a1f, 0x10, 0, 0},
+ {0x5688, 0xa6, 0, 0}, {0x5689, 0x6a, 0, 0}, {0x568a, 0xea, 0, 0},
+ {0x568b, 0xae, 0, 0}, {0x568c, 0xa6, 0, 0}, {0x568d, 0x6a, 0, 0},
+ {0x568e, 0x62, 0, 0}, {0x568f, 0x26, 0, 0}, {0x5583, 0x40, 0, 0},
+ {0x5584, 0x40, 0, 0}, {0x5580, 0x02, 0, 0}, {0x5000, 0xcf, 0, 0},
+ {0x5800, 0x27, 0, 0}, {0x5801, 0x19, 0, 0}, {0x5802, 0x12, 0, 0},
+ {0x5803, 0x0f, 0, 0}, {0x5804, 0x10, 0, 0}, {0x5805, 0x15, 0, 0},
+ {0x5806, 0x1e, 0, 0}, {0x5807, 0x2f, 0, 0}, {0x5808, 0x15, 0, 0},
+ {0x5809, 0x0d, 0, 0}, {0x580a, 0x0a, 0, 0}, {0x580b, 0x09, 0, 0},
+ {0x580c, 0x0a, 0, 0}, {0x580d, 0x0c, 0, 0}, {0x580e, 0x12, 0, 0},
+ {0x580f, 0x19, 0, 0}, {0x5810, 0x0b, 0, 0}, {0x5811, 0x07, 0, 0},
+ {0x5812, 0x04, 0, 0}, {0x5813, 0x03, 0, 0}, {0x5814, 0x03, 0, 0},
+ {0x5815, 0x06, 0, 0}, {0x5816, 0x0a, 0, 0}, {0x5817, 0x0f, 0, 0},
+ {0x5818, 0x0a, 0, 0}, {0x5819, 0x05, 0, 0}, {0x581a, 0x01, 0, 0},
+ {0x581b, 0x00, 0, 0}, {0x581c, 0x00, 0, 0}, {0x581d, 0x03, 0, 0},
+ {0x581e, 0x08, 0, 0}, {0x581f, 0x0c, 0, 0}, {0x5820, 0x0a, 0, 0},
+ {0x5821, 0x05, 0, 0}, {0x5822, 0x01, 0, 0}, {0x5823, 0x00, 0, 0},
+ {0x5824, 0x00, 0, 0}, {0x5825, 0x03, 0, 0}, {0x5826, 0x08, 0, 0},
+ {0x5827, 0x0c, 0, 0}, {0x5828, 0x0e, 0, 0}, {0x5829, 0x08, 0, 0},
+ {0x582a, 0x06, 0, 0}, {0x582b, 0x04, 0, 0}, {0x582c, 0x05, 0, 0},
+ {0x582d, 0x07, 0, 0}, {0x582e, 0x0b, 0, 0}, {0x582f, 0x12, 0, 0},
+ {0x5830, 0x18, 0, 0}, {0x5831, 0x10, 0, 0}, {0x5832, 0x0c, 0, 0},
+ {0x5833, 0x0a, 0, 0}, {0x5834, 0x0b, 0, 0}, {0x5835, 0x0e, 0, 0},
+ {0x5836, 0x15, 0, 0}, {0x5837, 0x19, 0, 0}, {0x5838, 0x32, 0, 0},
+ {0x5839, 0x1f, 0, 0}, {0x583a, 0x18, 0, 0}, {0x583b, 0x16, 0, 0},
+ {0x583c, 0x17, 0, 0}, {0x583d, 0x1e, 0, 0}, {0x583e, 0x26, 0, 0},
+ {0x583f, 0x53, 0, 0}, {0x5840, 0x10, 0, 0}, {0x5841, 0x0f, 0, 0},
+ {0x5842, 0x0d, 0, 0}, {0x5843, 0x0c, 0, 0}, {0x5844, 0x0e, 0, 0},
+ {0x5845, 0x09, 0, 0}, {0x5846, 0x11, 0, 0}, {0x5847, 0x10, 0, 0},
+ {0x5848, 0x10, 0, 0}, {0x5849, 0x10, 0, 0}, {0x584a, 0x10, 0, 0},
+ {0x584b, 0x0e, 0, 0}, {0x584c, 0x10, 0, 0}, {0x584d, 0x10, 0, 0},
+ {0x584e, 0x11, 0, 0}, {0x584f, 0x10, 0, 0}, {0x5850, 0x0f, 0, 0},
+ {0x5851, 0x0c, 0, 0}, {0x5852, 0x0f, 0, 0}, {0x5853, 0x10, 0, 0},
+ {0x5854, 0x10, 0, 0}, {0x5855, 0x0f, 0, 0}, {0x5856, 0x0e, 0, 0},
+ {0x5857, 0x0b, 0, 0}, {0x5858, 0x10, 0, 0}, {0x5859, 0x0d, 0, 0},
+ {0x585a, 0x0d, 0, 0}, {0x585b, 0x0c, 0, 0}, {0x585c, 0x0c, 0, 0},
+ {0x585d, 0x0c, 0, 0}, {0x585e, 0x0b, 0, 0}, {0x585f, 0x0c, 0, 0},
+ {0x5860, 0x0c, 0, 0}, {0x5861, 0x0c, 0, 0}, {0x5862, 0x0d, 0, 0},
+ {0x5863, 0x08, 0, 0}, {0x5864, 0x11, 0, 0}, {0x5865, 0x18, 0, 0},
+ {0x5866, 0x18, 0, 0}, {0x5867, 0x19, 0, 0}, {0x5868, 0x17, 0, 0},
+ {0x5869, 0x19, 0, 0}, {0x586a, 0x16, 0, 0}, {0x586b, 0x13, 0, 0},
+ {0x586c, 0x13, 0, 0}, {0x586d, 0x12, 0, 0}, {0x586e, 0x13, 0, 0},
+ {0x586f, 0x16, 0, 0}, {0x5870, 0x14, 0, 0}, {0x5871, 0x12, 0, 0},
+ {0x5872, 0x10, 0, 0}, {0x5873, 0x11, 0, 0}, {0x5874, 0x11, 0, 0},
+ {0x5875, 0x16, 0, 0}, {0x5876, 0x14, 0, 0}, {0x5877, 0x11, 0, 0},
+ {0x5878, 0x10, 0, 0}, {0x5879, 0x0f, 0, 0}, {0x587a, 0x10, 0, 0},
+ {0x587b, 0x14, 0, 0}, {0x587c, 0x13, 0, 0}, {0x587d, 0x12, 0, 0},
+ {0x587e, 0x11, 0, 0}, {0x587f, 0x11, 0, 0}, {0x5880, 0x12, 0, 0},
+ {0x5881, 0x15, 0, 0}, {0x5882, 0x14, 0, 0}, {0x5883, 0x15, 0, 0},
+ {0x5884, 0x15, 0, 0}, {0x5885, 0x15, 0, 0}, {0x5886, 0x13, 0, 0},
+ {0x5887, 0x17, 0, 0}, {0x3710, 0x10, 0, 0}, {0x3632, 0x51, 0, 0},
+ {0x3702, 0x10, 0, 0}, {0x3703, 0xb2, 0, 0}, {0x3704, 0x18, 0, 0},
+ {0x370b, 0x40, 0, 0}, {0x370d, 0x03, 0, 0}, {0x3631, 0x01, 0, 0},
+ {0x3632, 0x52, 0, 0}, {0x3606, 0x24, 0, 0}, {0x3620, 0x96, 0, 0},
+ {0x5785, 0x07, 0, 0}, {0x3a13, 0x30, 0, 0}, {0x3600, 0x52, 0, 0},
+ {0x3604, 0x48, 0, 0}, {0x3606, 0x1b, 0, 0}, {0x370d, 0x0b, 0, 0},
+ {0x370f, 0xc0, 0, 0}, {0x3709, 0x01, 0, 0}, {0x3823, 0x00, 0, 0},
+ {0x5007, 0x00, 0, 0}, {0x5009, 0x00, 0, 0}, {0x5011, 0x00, 0, 0},
+ {0x5013, 0x00, 0, 0}, {0x519e, 0x00, 0, 0}, {0x5086, 0x00, 0, 0},
+ {0x5087, 0x00, 0, 0}, {0x5088, 0x00, 0, 0}, {0x5089, 0x00, 0, 0},
+ {0x302b, 0x00, 0, 0}, {0x3621, 0x87, 0, 0}, {0x3808, 0x01, 0, 0},
+ {0x3809, 0x40, 0, 0}, {0x380a, 0x00, 0, 0}, {0x380b, 0xf0, 0, 0},
+};
+
+static struct reg_value ov5642_setting_30fps_NTSC_720_480[] = {
+ {0x3103, 0x93, 0, 0}, {0x3008, 0x82, 0, 0}, {0x3017, 0x7f, 0, 0},
+ {0x3018, 0xfc, 0, 0}, {0x3615, 0xf0, 0, 0}, {0x3000, 0x00, 0, 0},
+ {0x3001, 0x00, 0, 0}, {0x3002, 0x5c, 0, 0}, {0x3003, 0x00, 0, 0},
+ {0x3004, 0xff, 0, 0}, {0x3005, 0xff, 0, 0}, {0x3006, 0x43, 0, 0},
+ {0x3007, 0x37, 0, 0}, {0x3011, 0x09, 0, 0}, {0x3012, 0x02, 0, 0},
+ {0x3010, 0x00, 0, 0}, {0x460c, 0x20, 0, 0}, {0x3815, 0x04, 0, 0},
+ {0x370c, 0xa0, 0, 0}, {0x3602, 0xfc, 0, 0}, {0x3612, 0xff, 0, 0},
+ {0x3634, 0xc0, 0, 0}, {0x3613, 0x00, 0, 0}, {0x3605, 0x7c, 0, 0},
+ {0x3621, 0x09, 0, 0}, {0x3622, 0x60, 0, 0}, {0x3604, 0x40, 0, 0},
+ {0x3603, 0xa7, 0, 0}, {0x3603, 0x27, 0, 0}, {0x4000, 0x21, 0, 0},
+ {0x401d, 0x22, 0, 0}, {0x3600, 0x54, 0, 0}, {0x3605, 0x04, 0, 0},
+ {0x3606, 0x3f, 0, 0}, {0x3c01, 0x80, 0, 0}, {0x5000, 0x4f, 0, 0},
+ {0x5020, 0x04, 0, 0}, {0x5181, 0x79, 0, 0}, {0x5182, 0x00, 0, 0},
+ {0x5185, 0x22, 0, 0}, {0x5197, 0x01, 0, 0}, {0x5001, 0xff, 0, 0},
+ {0x5500, 0x0a, 0, 0}, {0x5504, 0x00, 0, 0}, {0x5505, 0x7f, 0, 0},
+ {0x5080, 0x08, 0, 0}, {0x300e, 0x18, 0, 0}, {0x4610, 0x00, 0, 0},
+ {0x471d, 0x05, 0, 0}, {0x4708, 0x06, 0, 0}, {0x3808, 0x02, 0, 0},
+ {0x3809, 0xd0, 0, 0}, {0x380a, 0x01, 0, 0}, {0x380b, 0xe0, 0, 0},
+ {0x380e, 0x07, 0, 0}, {0x380f, 0xd0, 0, 0}, {0x501f, 0x00, 0, 0},
+ {0x5000, 0x4f, 0, 0}, {0x4300, 0x30, 0, 0}, {0x3503, 0x07, 0, 0},
+ {0x3501, 0x73, 0, 0}, {0x3502, 0x80, 0, 0}, {0x350b, 0x00, 0, 0},
+ {0x3503, 0x07, 0, 0}, {0x3824, 0x11, 0, 0}, {0x3825, 0xb0, 0, 0},
+ {0x3501, 0x1e, 0, 0}, {0x3502, 0x80, 0, 0}, {0x350b, 0x7f, 0, 0},
+ {0x380c, 0x07, 0, 0}, {0x380d, 0x2a, 0, 0}, {0x380e, 0x03, 0, 0},
+ {0x380f, 0xe8, 0, 0}, {0x3a0d, 0x04, 0, 0}, {0x3a0e, 0x03, 0, 0},
+ {0x3818, 0xc1, 0, 0}, {0x3705, 0xdb, 0, 0}, {0x370a, 0x81, 0, 0},
+ {0x3801, 0x80, 0, 0}, {0x3621, 0xc7, 0, 0}, {0x3801, 0x50, 0, 0},
+ {0x3803, 0x08, 0, 0}, {0x3827, 0x3c, 0, 0}, {0x3810, 0x80, 0, 0},
+ {0x3804, 0x05, 0, 0}, {0x3805, 0x00, 0, 0}, {0x5682, 0x05, 0, 0},
+ {0x5683, 0x00, 0, 0}, {0x3806, 0x03, 0, 0}, {0x3807, 0x58, 0, 0},
+ {0x5686, 0x03, 0, 0}, {0x5687, 0x58, 0, 0}, {0x3a00, 0x78, 0, 0},
+ {0x3a1a, 0x05, 0, 0}, {0x3a13, 0x30, 0, 0}, {0x3a18, 0x00, 0, 0},
+ {0x3a19, 0x7c, 0, 0}, {0x3a08, 0x12, 0, 0}, {0x3a09, 0xc0, 0, 0},
+ {0x3a0a, 0x0f, 0, 0}, {0x3a0b, 0xa0, 0, 0}, {0x350c, 0x07, 0, 0},
+ {0x350d, 0xd0, 0, 0}, {0x3500, 0x00, 0, 0}, {0x3501, 0x00, 0, 0},
+ {0x3502, 0x00, 0, 0}, {0x350a, 0x00, 0, 0}, {0x350b, 0x00, 0, 0},
+ {0x3503, 0x00, 0, 0}, {0x528a, 0x02, 0, 0}, {0x528b, 0x04, 0, 0},
+ {0x528c, 0x08, 0, 0}, {0x528d, 0x08, 0, 0}, {0x528e, 0x08, 0, 0},
+ {0x528f, 0x10, 0, 0}, {0x5290, 0x10, 0, 0}, {0x5292, 0x00, 0, 0},
+ {0x5293, 0x02, 0, 0}, {0x5294, 0x00, 0, 0}, {0x5295, 0x02, 0, 0},
+ {0x5296, 0x00, 0, 0}, {0x5297, 0x02, 0, 0}, {0x5298, 0x00, 0, 0},
+ {0x5299, 0x02, 0, 0}, {0x529a, 0x00, 0, 0}, {0x529b, 0x02, 0, 0},
+ {0x529c, 0x00, 0, 0}, {0x529d, 0x02, 0, 0}, {0x529e, 0x00, 0, 0},
+ {0x529f, 0x02, 0, 0}, {0x3a0f, 0x3c, 0, 0}, {0x3a10, 0x30, 0, 0},
+ {0x3a1b, 0x3c, 0, 0}, {0x3a1e, 0x30, 0, 0}, {0x3a11, 0x70, 0, 0},
+ {0x3a1f, 0x10, 0, 0}, {0x3030, 0x2b, 0, 0}, {0x3a02, 0x00, 0, 0},
+ {0x3a03, 0x7d, 0, 0}, {0x3a04, 0x00, 0, 0}, {0x3a14, 0x00, 0, 0},
+ {0x3a15, 0x7d, 0, 0}, {0x3a16, 0x00, 0, 0}, {0x3a00, 0x78, 0, 0},
+ {0x3a08, 0x12, 0, 0}, {0x3a09, 0xc0, 0, 0}, {0x3a0a, 0x0f, 0, 0},
+ {0x3a0b, 0xa0, 0, 0}, {0x3a0d, 0x04, 0, 0}, {0x3a0e, 0x03, 0, 0},
+ {0x5193, 0x70, 0, 0}, {0x589b, 0x04, 0, 0}, {0x589a, 0xc5, 0, 0},
+ {0x401e, 0x20, 0, 0}, {0x4001, 0x42, 0, 0}, {0x401c, 0x04, 0, 0},
+ {0x528a, 0x01, 0, 0}, {0x528b, 0x04, 0, 0}, {0x528c, 0x08, 0, 0},
+ {0x528d, 0x10, 0, 0}, {0x528e, 0x20, 0, 0}, {0x528f, 0x28, 0, 0},
+ {0x5290, 0x30, 0, 0}, {0x5292, 0x00, 0, 0}, {0x5293, 0x01, 0, 0},
+ {0x5294, 0x00, 0, 0}, {0x5295, 0x04, 0, 0}, {0x5296, 0x00, 0, 0},
+ {0x5297, 0x08, 0, 0}, {0x5298, 0x00, 0, 0}, {0x5299, 0x10, 0, 0},
+ {0x529a, 0x00, 0, 0}, {0x529b, 0x20, 0, 0}, {0x529c, 0x00, 0, 0},
+ {0x529d, 0x28, 0, 0}, {0x529e, 0x00, 0, 0}, {0x529f, 0x30, 0, 0},
+ {0x5282, 0x00, 0, 0}, {0x5300, 0x00, 0, 0}, {0x5301, 0x20, 0, 0},
+ {0x5302, 0x00, 0, 0}, {0x5303, 0x7c, 0, 0}, {0x530c, 0x00, 0, 0},
+ {0x530d, 0x0c, 0, 0}, {0x530e, 0x20, 0, 0}, {0x530f, 0x80, 0, 0},
+ {0x5310, 0x20, 0, 0}, {0x5311, 0x80, 0, 0}, {0x5308, 0x20, 0, 0},
+ {0x5309, 0x40, 0, 0}, {0x5304, 0x00, 0, 0}, {0x5305, 0x30, 0, 0},
+ {0x5306, 0x00, 0, 0}, {0x5307, 0x80, 0, 0}, {0x5314, 0x08, 0, 0},
+ {0x5315, 0x20, 0, 0}, {0x5319, 0x30, 0, 0}, {0x5316, 0x10, 0, 0},
+ {0x5317, 0x00, 0, 0}, {0x5318, 0x02, 0, 0}, {0x5380, 0x01, 0, 0},
+ {0x5381, 0x00, 0, 0}, {0x5382, 0x00, 0, 0}, {0x5383, 0x4e, 0, 0},
+ {0x5384, 0x00, 0, 0}, {0x5385, 0x0f, 0, 0}, {0x5386, 0x00, 0, 0},
+ {0x5387, 0x00, 0, 0}, {0x5388, 0x01, 0, 0}, {0x5389, 0x15, 0, 0},
+ {0x538a, 0x00, 0, 0}, {0x538b, 0x31, 0, 0}, {0x538c, 0x00, 0, 0},
+ {0x538d, 0x00, 0, 0}, {0x538e, 0x00, 0, 0}, {0x538f, 0x0f, 0, 0},
+ {0x5390, 0x00, 0, 0}, {0x5391, 0xab, 0, 0}, {0x5392, 0x00, 0, 0},
+ {0x5393, 0xa2, 0, 0}, {0x5394, 0x08, 0, 0}, {0x5480, 0x14, 0, 0},
+ {0x5481, 0x21, 0, 0}, {0x5482, 0x36, 0, 0}, {0x5483, 0x57, 0, 0},
+ {0x5484, 0x65, 0, 0}, {0x5485, 0x71, 0, 0}, {0x5486, 0x7d, 0, 0},
+ {0x5487, 0x87, 0, 0}, {0x5488, 0x91, 0, 0}, {0x5489, 0x9a, 0, 0},
+ {0x548a, 0xaa, 0, 0}, {0x548b, 0xb8, 0, 0}, {0x548c, 0xcd, 0, 0},
+ {0x548d, 0xdd, 0, 0}, {0x548e, 0xea, 0, 0}, {0x548f, 0x1d, 0, 0},
+ {0x5490, 0x05, 0, 0}, {0x5491, 0x00, 0, 0}, {0x5492, 0x04, 0, 0},
+ {0x5493, 0x20, 0, 0}, {0x5494, 0x03, 0, 0}, {0x5495, 0x60, 0, 0},
+ {0x5496, 0x02, 0, 0}, {0x5497, 0xb8, 0, 0}, {0x5498, 0x02, 0, 0},
+ {0x5499, 0x86, 0, 0}, {0x549a, 0x02, 0, 0}, {0x549b, 0x5b, 0, 0},
+ {0x549c, 0x02, 0, 0}, {0x549d, 0x3b, 0, 0}, {0x549e, 0x02, 0, 0},
+ {0x549f, 0x1c, 0, 0}, {0x54a0, 0x02, 0, 0}, {0x54a1, 0x04, 0, 0},
+ {0x54a2, 0x01, 0, 0}, {0x54a3, 0xed, 0, 0}, {0x54a4, 0x01, 0, 0},
+ {0x54a5, 0xc5, 0, 0}, {0x54a6, 0x01, 0, 0}, {0x54a7, 0xa5, 0, 0},
+ {0x54a8, 0x01, 0, 0}, {0x54a9, 0x6c, 0, 0}, {0x54aa, 0x01, 0, 0},
+ {0x54ab, 0x41, 0, 0}, {0x54ac, 0x01, 0, 0}, {0x54ad, 0x20, 0, 0},
+ {0x54ae, 0x00, 0, 0}, {0x54af, 0x16, 0, 0}, {0x54b0, 0x01, 0, 0},
+ {0x54b1, 0x20, 0, 0}, {0x54b2, 0x00, 0, 0}, {0x54b3, 0x10, 0, 0},
+ {0x54b4, 0x00, 0, 0}, {0x54b5, 0xf0, 0, 0}, {0x54b6, 0x00, 0, 0},
+ {0x54b7, 0xdf, 0, 0}, {0x5402, 0x3f, 0, 0}, {0x5403, 0x00, 0, 0},
+ {0x3406, 0x00, 0, 0}, {0x5180, 0xff, 0, 0}, {0x5181, 0x52, 0, 0},
+ {0x5182, 0x11, 0, 0}, {0x5183, 0x14, 0, 0}, {0x5184, 0x25, 0, 0},
+ {0x5185, 0x24, 0, 0}, {0x5186, 0x06, 0, 0}, {0x5187, 0x08, 0, 0},
+ {0x5188, 0x08, 0, 0}, {0x5189, 0x7c, 0, 0}, {0x518a, 0x60, 0, 0},
+ {0x518b, 0xb2, 0, 0}, {0x518c, 0xb2, 0, 0}, {0x518d, 0x44, 0, 0},
+ {0x518e, 0x3d, 0, 0}, {0x518f, 0x58, 0, 0}, {0x5190, 0x46, 0, 0},
+ {0x5191, 0xf8, 0, 0}, {0x5192, 0x04, 0, 0}, {0x5193, 0x70, 0, 0},
+ {0x5194, 0xf0, 0, 0}, {0x5195, 0xf0, 0, 0}, {0x5196, 0x03, 0, 0},
+ {0x5197, 0x01, 0, 0}, {0x5198, 0x04, 0, 0}, {0x5199, 0x12, 0, 0},
+ {0x519a, 0x04, 0, 0}, {0x519b, 0x00, 0, 0}, {0x519c, 0x06, 0, 0},
+ {0x519d, 0x82, 0, 0}, {0x519e, 0x00, 0, 0}, {0x5025, 0x80, 0, 0},
+ {0x3a0f, 0x38, 0, 0}, {0x3a10, 0x30, 0, 0}, {0x3a1b, 0x3a, 0, 0},
+ {0x3a1e, 0x2e, 0, 0}, {0x3a11, 0x60, 0, 0}, {0x3a1f, 0x10, 0, 0},
+ {0x5688, 0xa6, 0, 0}, {0x5689, 0x6a, 0, 0}, {0x568a, 0xea, 0, 0},
+ {0x568b, 0xae, 0, 0}, {0x568c, 0xa6, 0, 0}, {0x568d, 0x6a, 0, 0},
+ {0x568e, 0x62, 0, 0}, {0x568f, 0x26, 0, 0}, {0x5583, 0x40, 0, 0},
+ {0x5584, 0x40, 0, 0}, {0x5580, 0x02, 0, 0}, {0x5000, 0xcf, 0, 0},
+ {0x5800, 0x27, 0, 0}, {0x5801, 0x19, 0, 0}, {0x5802, 0x12, 0, 0},
+ {0x5803, 0x0f, 0, 0}, {0x5804, 0x10, 0, 0}, {0x5805, 0x15, 0, 0},
+ {0x5806, 0x1e, 0, 0}, {0x5807, 0x2f, 0, 0}, {0x5808, 0x15, 0, 0},
+ {0x5809, 0x0d, 0, 0}, {0x580a, 0x0a, 0, 0}, {0x580b, 0x09, 0, 0},
+ {0x580c, 0x0a, 0, 0}, {0x580d, 0x0c, 0, 0}, {0x580e, 0x12, 0, 0},
+ {0x580f, 0x19, 0, 0}, {0x5810, 0x0b, 0, 0}, {0x5811, 0x07, 0, 0},
+ {0x5812, 0x04, 0, 0}, {0x5813, 0x03, 0, 0}, {0x5814, 0x03, 0, 0},
+ {0x5815, 0x06, 0, 0}, {0x5816, 0x0a, 0, 0}, {0x5817, 0x0f, 0, 0},
+ {0x5818, 0x0a, 0, 0}, {0x5819, 0x05, 0, 0}, {0x581a, 0x01, 0, 0},
+ {0x581b, 0x00, 0, 0}, {0x581c, 0x00, 0, 0}, {0x581d, 0x03, 0, 0},
+ {0x581e, 0x08, 0, 0}, {0x581f, 0x0c, 0, 0}, {0x5820, 0x0a, 0, 0},
+ {0x5821, 0x05, 0, 0}, {0x5822, 0x01, 0, 0}, {0x5823, 0x00, 0, 0},
+ {0x5824, 0x00, 0, 0}, {0x5825, 0x03, 0, 0}, {0x5826, 0x08, 0, 0},
+ {0x5827, 0x0c, 0, 0}, {0x5828, 0x0e, 0, 0}, {0x5829, 0x08, 0, 0},
+ {0x582a, 0x06, 0, 0}, {0x582b, 0x04, 0, 0}, {0x582c, 0x05, 0, 0},
+ {0x582d, 0x07, 0, 0}, {0x582e, 0x0b, 0, 0}, {0x582f, 0x12, 0, 0},
+ {0x5830, 0x18, 0, 0}, {0x5831, 0x10, 0, 0}, {0x5832, 0x0c, 0, 0},
+ {0x5833, 0x0a, 0, 0}, {0x5834, 0x0b, 0, 0}, {0x5835, 0x0e, 0, 0},
+ {0x5836, 0x15, 0, 0}, {0x5837, 0x19, 0, 0}, {0x5838, 0x32, 0, 0},
+ {0x5839, 0x1f, 0, 0}, {0x583a, 0x18, 0, 0}, {0x583b, 0x16, 0, 0},
+ {0x583c, 0x17, 0, 0}, {0x583d, 0x1e, 0, 0}, {0x583e, 0x26, 0, 0},
+ {0x583f, 0x53, 0, 0}, {0x5840, 0x10, 0, 0}, {0x5841, 0x0f, 0, 0},
+ {0x5842, 0x0d, 0, 0}, {0x5843, 0x0c, 0, 0}, {0x5844, 0x0e, 0, 0},
+ {0x5845, 0x09, 0, 0}, {0x5846, 0x11, 0, 0}, {0x5847, 0x10, 0, 0},
+ {0x5848, 0x10, 0, 0}, {0x5849, 0x10, 0, 0}, {0x584a, 0x10, 0, 0},
+ {0x584b, 0x0e, 0, 0}, {0x584c, 0x10, 0, 0}, {0x584d, 0x10, 0, 0},
+ {0x584e, 0x11, 0, 0}, {0x584f, 0x10, 0, 0}, {0x5850, 0x0f, 0, 0},
+ {0x5851, 0x0c, 0, 0}, {0x5852, 0x0f, 0, 0}, {0x5853, 0x10, 0, 0},
+ {0x5854, 0x10, 0, 0}, {0x5855, 0x0f, 0, 0}, {0x5856, 0x0e, 0, 0},
+ {0x5857, 0x0b, 0, 0}, {0x5858, 0x10, 0, 0}, {0x5859, 0x0d, 0, 0},
+ {0x585a, 0x0d, 0, 0}, {0x585b, 0x0c, 0, 0}, {0x585c, 0x0c, 0, 0},
+ {0x585d, 0x0c, 0, 0}, {0x585e, 0x0b, 0, 0}, {0x585f, 0x0c, 0, 0},
+ {0x5860, 0x0c, 0, 0}, {0x5861, 0x0c, 0, 0}, {0x5862, 0x0d, 0, 0},
+ {0x5863, 0x08, 0, 0}, {0x5864, 0x11, 0, 0}, {0x5865, 0x18, 0, 0},
+ {0x5866, 0x18, 0, 0}, {0x5867, 0x19, 0, 0}, {0x5868, 0x17, 0, 0},
+ {0x5869, 0x19, 0, 0}, {0x586a, 0x16, 0, 0}, {0x586b, 0x13, 0, 0},
+ {0x586c, 0x13, 0, 0}, {0x586d, 0x12, 0, 0}, {0x586e, 0x13, 0, 0},
+ {0x586f, 0x16, 0, 0}, {0x5870, 0x14, 0, 0}, {0x5871, 0x12, 0, 0},
+ {0x5872, 0x10, 0, 0}, {0x5873, 0x11, 0, 0}, {0x5874, 0x11, 0, 0},
+ {0x5875, 0x16, 0, 0}, {0x5876, 0x14, 0, 0}, {0x5877, 0x11, 0, 0},
+ {0x5878, 0x10, 0, 0}, {0x5879, 0x0f, 0, 0}, {0x587a, 0x10, 0, 0},
+ {0x587b, 0x14, 0, 0}, {0x587c, 0x13, 0, 0}, {0x587d, 0x12, 0, 0},
+ {0x587e, 0x11, 0, 0}, {0x587f, 0x11, 0, 0}, {0x5880, 0x12, 0, 0},
+ {0x5881, 0x15, 0, 0}, {0x5882, 0x14, 0, 0}, {0x5883, 0x15, 0, 0},
+ {0x5884, 0x15, 0, 0}, {0x5885, 0x15, 0, 0}, {0x5886, 0x13, 0, 0},
+ {0x5887, 0x17, 0, 0}, {0x3710, 0x10, 0, 0}, {0x3632, 0x51, 0, 0},
+ {0x3702, 0x10, 0, 0}, {0x3703, 0xb2, 0, 0}, {0x3704, 0x18, 0, 0},
+ {0x370b, 0x40, 0, 0}, {0x370d, 0x03, 0, 0}, {0x3631, 0x01, 0, 0},
+ {0x3632, 0x52, 0, 0}, {0x3606, 0x24, 0, 0}, {0x3620, 0x96, 0, 0},
+ {0x5785, 0x07, 0, 0}, {0x3a13, 0x30, 0, 0}, {0x3600, 0x52, 0, 0},
+ {0x3604, 0x48, 0, 0}, {0x3606, 0x1b, 0, 0}, {0x370d, 0x0b, 0, 0},
+ {0x370f, 0xc0, 0, 0}, {0x3709, 0x01, 0, 0}, {0x3823, 0x00, 0, 0},
+ {0x5007, 0x00, 0, 0}, {0x5009, 0x00, 0, 0}, {0x5011, 0x00, 0, 0},
+ {0x5013, 0x00, 0, 0}, {0x519e, 0x00, 0, 0}, {0x5086, 0x00, 0, 0},
+ {0x5087, 0x00, 0, 0}, {0x5088, 0x00, 0, 0}, {0x5089, 0x00, 0, 0},
+ {0x302b, 0x00, 0, 0}, {0x3621, 0x87, 0, 0}, {0x3a00, 0x78, 0, 0},
+ {0x302c, 0x60, 0x60, 0},
+};
+
+static struct reg_value ov5642_setting_30fps_PAL_720_576[] = {
+ {0x3103, 0x93, 0, 0}, {0x3008, 0x82, 0, 0}, {0x3017, 0x7f, 0, 0},
+ {0x3018, 0xfc, 0, 0}, {0x3615, 0xf0, 0, 0}, {0x3000, 0x00, 0, 0},
+ {0x3001, 0x00, 0, 0}, {0x3002, 0x5c, 0, 0}, {0x3003, 0x00, 0, 0},
+ {0x3004, 0xff, 0, 0}, {0x3005, 0xff, 0, 0}, {0x3006, 0x43, 0, 0},
+ {0x3007, 0x37, 0, 0}, {0x3011, 0x09, 0, 0}, {0x3012, 0x02, 0, 0},
+ {0x3010, 0x00, 0, 0}, {0x460c, 0x20, 0, 0}, {0x3815, 0x04, 0, 0},
+ {0x370c, 0xa0, 0, 0}, {0x3602, 0xfc, 0, 0}, {0x3612, 0xff, 0, 0},
+ {0x3634, 0xc0, 0, 0}, {0x3613, 0x00, 0, 0}, {0x3605, 0x7c, 0, 0},
+ {0x3621, 0x09, 0, 0}, {0x3622, 0x60, 0, 0}, {0x3604, 0x40, 0, 0},
+ {0x3603, 0xa7, 0, 0}, {0x3603, 0x27, 0, 0}, {0x4000, 0x21, 0, 0},
+ {0x401d, 0x22, 0, 0}, {0x3600, 0x54, 0, 0}, {0x3605, 0x04, 0, 0},
+ {0x3606, 0x3f, 0, 0}, {0x3c01, 0x80, 0, 0}, {0x5000, 0x4f, 0, 0},
+ {0x5020, 0x04, 0, 0}, {0x5181, 0x79, 0, 0}, {0x5182, 0x00, 0, 0},
+ {0x5185, 0x22, 0, 0}, {0x5197, 0x01, 0, 0}, {0x5001, 0xff, 0, 0},
+ {0x5500, 0x0a, 0, 0}, {0x5504, 0x00, 0, 0}, {0x5505, 0x7f, 0, 0},
+ {0x5080, 0x08, 0, 0}, {0x300e, 0x18, 0, 0}, {0x4610, 0x00, 0, 0},
+ {0x471d, 0x05, 0, 0}, {0x4708, 0x06, 0, 0}, {0x3808, 0x02, 0, 0},
+ {0x3809, 0xd0, 0, 0}, {0x380a, 0x02, 0, 0}, {0x380b, 0x40, 0, 0},
+ {0x380e, 0x07, 0, 0}, {0x380f, 0xd0, 0, 0}, {0x501f, 0x00, 0, 0},
+ {0x5000, 0x4f, 0, 0}, {0x4300, 0x30, 0, 0}, {0x3503, 0x07, 0, 0},
+ {0x3501, 0x73, 0, 0}, {0x3502, 0x80, 0, 0}, {0x350b, 0x00, 0, 0},
+ {0x3503, 0x07, 0, 0}, {0x3824, 0x11, 0, 0}, {0x3825, 0xd8, 0, 0},
+ {0x3501, 0x1e, 0, 0}, {0x3502, 0x80, 0, 0}, {0x350b, 0x7f, 0, 0},
+ {0x380c, 0x07, 0, 0}, {0x380d, 0x2a, 0, 0}, {0x380e, 0x03, 0, 0},
+ {0x380f, 0xe8, 0, 0}, {0x3a0d, 0x04, 0, 0}, {0x3a0e, 0x03, 0, 0},
+ {0x3818, 0xc1, 0, 0}, {0x3705, 0xdb, 0, 0}, {0x370a, 0x81, 0, 0},
+ {0x3801, 0x80, 0, 0}, {0x3621, 0xc7, 0, 0}, {0x3801, 0x50, 0, 0},
+ {0x3803, 0x08, 0, 0}, {0x3827, 0x3c, 0, 0}, {0x3810, 0x80, 0, 0},
+ {0x3804, 0x04, 0, 0}, {0x3805, 0xb0, 0, 0}, {0x5682, 0x04, 0, 0},
+ {0x5683, 0xb0, 0, 0}, {0x3806, 0x03, 0, 0}, {0x3807, 0x58, 0, 0},
+ {0x5686, 0x03, 0, 0}, {0x5687, 0x58, 0, 0}, {0x3a00, 0x78, 0, 0},
+ {0x3a1a, 0x05, 0, 0}, {0x3a13, 0x30, 0, 0}, {0x3a18, 0x00, 0, 0},
+ {0x3a19, 0x7c, 0, 0}, {0x3a08, 0x12, 0, 0}, {0x3a09, 0xc0, 0, 0},
+ {0x3a0a, 0x0f, 0, 0}, {0x3a0b, 0xa0, 0, 0}, {0x350c, 0x07, 0, 0},
+ {0x350d, 0xd0, 0, 0}, {0x3500, 0x00, 0, 0}, {0x3501, 0x00, 0, 0},
+ {0x3502, 0x00, 0, 0}, {0x350a, 0x00, 0, 0}, {0x350b, 0x00, 0, 0},
+ {0x3503, 0x00, 0, 0}, {0x528a, 0x02, 0, 0}, {0x528b, 0x04, 0, 0},
+ {0x528c, 0x08, 0, 0}, {0x528d, 0x08, 0, 0}, {0x528e, 0x08, 0, 0},
+ {0x528f, 0x10, 0, 0}, {0x5290, 0x10, 0, 0}, {0x5292, 0x00, 0, 0},
+ {0x5293, 0x02, 0, 0}, {0x5294, 0x00, 0, 0}, {0x5295, 0x02, 0, 0},
+ {0x5296, 0x00, 0, 0}, {0x5297, 0x02, 0, 0}, {0x5298, 0x00, 0, 0},
+ {0x5299, 0x02, 0, 0}, {0x529a, 0x00, 0, 0}, {0x529b, 0x02, 0, 0},
+ {0x529c, 0x00, 0, 0}, {0x529d, 0x02, 0, 0}, {0x529e, 0x00, 0, 0},
+ {0x529f, 0x02, 0, 0}, {0x3a0f, 0x3c, 0, 0}, {0x3a10, 0x30, 0, 0},
+ {0x3a1b, 0x3c, 0, 0}, {0x3a1e, 0x30, 0, 0}, {0x3a11, 0x70, 0, 0},
+ {0x3a1f, 0x10, 0, 0}, {0x3030, 0x2b, 0, 0}, {0x3a02, 0x00, 0, 0},
+ {0x3a03, 0x7d, 0, 0}, {0x3a04, 0x00, 0, 0}, {0x3a14, 0x00, 0, 0},
+ {0x3a15, 0x7d, 0, 0}, {0x3a16, 0x00, 0, 0}, {0x3a00, 0x78, 0, 0},
+ {0x3a08, 0x12, 0, 0}, {0x3a09, 0xc0, 0, 0}, {0x3a0a, 0x0f, 0, 0},
+ {0x3a0b, 0xa0, 0, 0}, {0x3a0d, 0x04, 0, 0}, {0x3a0e, 0x03, 0, 0},
+ {0x5193, 0x70, 0, 0}, {0x589b, 0x04, 0, 0}, {0x589a, 0xc5, 0, 0},
+ {0x401e, 0x20, 0, 0}, {0x4001, 0x42, 0, 0}, {0x401c, 0x04, 0, 0},
+ {0x528a, 0x01, 0, 0}, {0x528b, 0x04, 0, 0}, {0x528c, 0x08, 0, 0},
+ {0x528d, 0x10, 0, 0}, {0x528e, 0x20, 0, 0}, {0x528f, 0x28, 0, 0},
+ {0x5290, 0x30, 0, 0}, {0x5292, 0x00, 0, 0}, {0x5293, 0x01, 0, 0},
+ {0x5294, 0x00, 0, 0}, {0x5295, 0x04, 0, 0}, {0x5296, 0x00, 0, 0},
+ {0x5297, 0x08, 0, 0}, {0x5298, 0x00, 0, 0}, {0x5299, 0x10, 0, 0},
+ {0x529a, 0x00, 0, 0}, {0x529b, 0x20, 0, 0}, {0x529c, 0x00, 0, 0},
+ {0x529d, 0x28, 0, 0}, {0x529e, 0x00, 0, 0}, {0x529f, 0x30, 0, 0},
+ {0x5282, 0x00, 0, 0}, {0x5300, 0x00, 0, 0}, {0x5301, 0x20, 0, 0},
+ {0x5302, 0x00, 0, 0}, {0x5303, 0x7c, 0, 0}, {0x530c, 0x00, 0, 0},
+ {0x530d, 0x0c, 0, 0}, {0x530e, 0x20, 0, 0}, {0x530f, 0x80, 0, 0},
+ {0x5310, 0x20, 0, 0}, {0x5311, 0x80, 0, 0}, {0x5308, 0x20, 0, 0},
+ {0x5309, 0x40, 0, 0}, {0x5304, 0x00, 0, 0}, {0x5305, 0x30, 0, 0},
+ {0x5306, 0x00, 0, 0}, {0x5307, 0x80, 0, 0}, {0x5314, 0x08, 0, 0},
+ {0x5315, 0x20, 0, 0}, {0x5319, 0x30, 0, 0}, {0x5316, 0x10, 0, 0},
+ {0x5317, 0x00, 0, 0}, {0x5318, 0x02, 0, 0}, {0x5380, 0x01, 0, 0},
+ {0x5381, 0x00, 0, 0}, {0x5382, 0x00, 0, 0}, {0x5383, 0x4e, 0, 0},
+ {0x5384, 0x00, 0, 0}, {0x5385, 0x0f, 0, 0}, {0x5386, 0x00, 0, 0},
+ {0x5387, 0x00, 0, 0}, {0x5388, 0x01, 0, 0}, {0x5389, 0x15, 0, 0},
+ {0x538a, 0x00, 0, 0}, {0x538b, 0x31, 0, 0}, {0x538c, 0x00, 0, 0},
+ {0x538d, 0x00, 0, 0}, {0x538e, 0x00, 0, 0}, {0x538f, 0x0f, 0, 0},
+ {0x5390, 0x00, 0, 0}, {0x5391, 0xab, 0, 0}, {0x5392, 0x00, 0, 0},
+ {0x5393, 0xa2, 0, 0}, {0x5394, 0x08, 0, 0}, {0x5480, 0x14, 0, 0},
+ {0x5481, 0x21, 0, 0}, {0x5482, 0x36, 0, 0}, {0x5483, 0x57, 0, 0},
+ {0x5484, 0x65, 0, 0}, {0x5485, 0x71, 0, 0}, {0x5486, 0x7d, 0, 0},
+ {0x5487, 0x87, 0, 0}, {0x5488, 0x91, 0, 0}, {0x5489, 0x9a, 0, 0},
+ {0x548a, 0xaa, 0, 0}, {0x548b, 0xb8, 0, 0}, {0x548c, 0xcd, 0, 0},
+ {0x548d, 0xdd, 0, 0}, {0x548e, 0xea, 0, 0}, {0x548f, 0x1d, 0, 0},
+ {0x5490, 0x05, 0, 0}, {0x5491, 0x00, 0, 0}, {0x5492, 0x04, 0, 0},
+ {0x5493, 0x20, 0, 0}, {0x5494, 0x03, 0, 0}, {0x5495, 0x60, 0, 0},
+ {0x5496, 0x02, 0, 0}, {0x5497, 0xb8, 0, 0}, {0x5498, 0x02, 0, 0},
+ {0x5499, 0x86, 0, 0}, {0x549a, 0x02, 0, 0}, {0x549b, 0x5b, 0, 0},
+ {0x549c, 0x02, 0, 0}, {0x549d, 0x3b, 0, 0}, {0x549e, 0x02, 0, 0},
+ {0x549f, 0x1c, 0, 0}, {0x54a0, 0x02, 0, 0}, {0x54a1, 0x04, 0, 0},
+ {0x54a2, 0x01, 0, 0}, {0x54a3, 0xed, 0, 0}, {0x54a4, 0x01, 0, 0},
+ {0x54a5, 0xc5, 0, 0}, {0x54a6, 0x01, 0, 0}, {0x54a7, 0xa5, 0, 0},
+ {0x54a8, 0x01, 0, 0}, {0x54a9, 0x6c, 0, 0}, {0x54aa, 0x01, 0, 0},
+ {0x54ab, 0x41, 0, 0}, {0x54ac, 0x01, 0, 0}, {0x54ad, 0x20, 0, 0},
+ {0x54ae, 0x00, 0, 0}, {0x54af, 0x16, 0, 0}, {0x54b0, 0x01, 0, 0},
+ {0x54b1, 0x20, 0, 0}, {0x54b2, 0x00, 0, 0}, {0x54b3, 0x10, 0, 0},
+ {0x54b4, 0x00, 0, 0}, {0x54b5, 0xf0, 0, 0}, {0x54b6, 0x00, 0, 0},
+ {0x54b7, 0xdf, 0, 0}, {0x5402, 0x3f, 0, 0}, {0x5403, 0x00, 0, 0},
+ {0x3406, 0x00, 0, 0}, {0x5180, 0xff, 0, 0}, {0x5181, 0x52, 0, 0},
+ {0x5182, 0x11, 0, 0}, {0x5183, 0x14, 0, 0}, {0x5184, 0x25, 0, 0},
+ {0x5185, 0x24, 0, 0}, {0x5186, 0x06, 0, 0}, {0x5187, 0x08, 0, 0},
+ {0x5188, 0x08, 0, 0}, {0x5189, 0x7c, 0, 0}, {0x518a, 0x60, 0, 0},
+ {0x518b, 0xb2, 0, 0}, {0x518c, 0xb2, 0, 0}, {0x518d, 0x44, 0, 0},
+ {0x518e, 0x3d, 0, 0}, {0x518f, 0x58, 0, 0}, {0x5190, 0x46, 0, 0},
+ {0x5191, 0xf8, 0, 0}, {0x5192, 0x04, 0, 0}, {0x5193, 0x70, 0, 0},
+ {0x5194, 0xf0, 0, 0}, {0x5195, 0xf0, 0, 0}, {0x5196, 0x03, 0, 0},
+ {0x5197, 0x01, 0, 0}, {0x5198, 0x04, 0, 0}, {0x5199, 0x12, 0, 0},
+ {0x519a, 0x04, 0, 0}, {0x519b, 0x00, 0, 0}, {0x519c, 0x06, 0, 0},
+ {0x519d, 0x82, 0, 0}, {0x519e, 0x00, 0, 0}, {0x5025, 0x80, 0, 0},
+ {0x3a0f, 0x38, 0, 0}, {0x3a10, 0x30, 0, 0}, {0x3a1b, 0x3a, 0, 0},
+ {0x3a1e, 0x2e, 0, 0}, {0x3a11, 0x60, 0, 0}, {0x3a1f, 0x10, 0, 0},
+ {0x5688, 0xa6, 0, 0}, {0x5689, 0x6a, 0, 0}, {0x568a, 0xea, 0, 0},
+ {0x568b, 0xae, 0, 0}, {0x568c, 0xa6, 0, 0}, {0x568d, 0x6a, 0, 0},
+ {0x568e, 0x62, 0, 0}, {0x568f, 0x26, 0, 0}, {0x5583, 0x40, 0, 0},
+ {0x5584, 0x40, 0, 0}, {0x5580, 0x02, 0, 0}, {0x5000, 0xcf, 0, 0},
+ {0x5800, 0x27, 0, 0}, {0x5801, 0x19, 0, 0}, {0x5802, 0x12, 0, 0},
+ {0x5803, 0x0f, 0, 0}, {0x5804, 0x10, 0, 0}, {0x5805, 0x15, 0, 0},
+ {0x5806, 0x1e, 0, 0}, {0x5807, 0x2f, 0, 0}, {0x5808, 0x15, 0, 0},
+ {0x5809, 0x0d, 0, 0}, {0x580a, 0x0a, 0, 0}, {0x580b, 0x09, 0, 0},
+ {0x580c, 0x0a, 0, 0}, {0x580d, 0x0c, 0, 0}, {0x580e, 0x12, 0, 0},
+ {0x580f, 0x19, 0, 0}, {0x5810, 0x0b, 0, 0}, {0x5811, 0x07, 0, 0},
+ {0x5812, 0x04, 0, 0}, {0x5813, 0x03, 0, 0}, {0x5814, 0x03, 0, 0},
+ {0x5815, 0x06, 0, 0}, {0x5816, 0x0a, 0, 0}, {0x5817, 0x0f, 0, 0},
+ {0x5818, 0x0a, 0, 0}, {0x5819, 0x05, 0, 0}, {0x581a, 0x01, 0, 0},
+ {0x581b, 0x00, 0, 0}, {0x581c, 0x00, 0, 0}, {0x581d, 0x03, 0, 0},
+ {0x581e, 0x08, 0, 0}, {0x581f, 0x0c, 0, 0}, {0x5820, 0x0a, 0, 0},
+ {0x5821, 0x05, 0, 0}, {0x5822, 0x01, 0, 0}, {0x5823, 0x00, 0, 0},
+ {0x5824, 0x00, 0, 0}, {0x5825, 0x03, 0, 0}, {0x5826, 0x08, 0, 0},
+ {0x5827, 0x0c, 0, 0}, {0x5828, 0x0e, 0, 0}, {0x5829, 0x08, 0, 0},
+ {0x582a, 0x06, 0, 0}, {0x582b, 0x04, 0, 0}, {0x582c, 0x05, 0, 0},
+ {0x582d, 0x07, 0, 0}, {0x582e, 0x0b, 0, 0}, {0x582f, 0x12, 0, 0},
+ {0x5830, 0x18, 0, 0}, {0x5831, 0x10, 0, 0}, {0x5832, 0x0c, 0, 0},
+ {0x5833, 0x0a, 0, 0}, {0x5834, 0x0b, 0, 0}, {0x5835, 0x0e, 0, 0},
+ {0x5836, 0x15, 0, 0}, {0x5837, 0x19, 0, 0}, {0x5838, 0x32, 0, 0},
+ {0x5839, 0x1f, 0, 0}, {0x583a, 0x18, 0, 0}, {0x583b, 0x16, 0, 0},
+ {0x583c, 0x17, 0, 0}, {0x583d, 0x1e, 0, 0}, {0x583e, 0x26, 0, 0},
+ {0x583f, 0x53, 0, 0}, {0x5840, 0x10, 0, 0}, {0x5841, 0x0f, 0, 0},
+ {0x5842, 0x0d, 0, 0}, {0x5843, 0x0c, 0, 0}, {0x5844, 0x0e, 0, 0},
+ {0x5845, 0x09, 0, 0}, {0x5846, 0x11, 0, 0}, {0x5847, 0x10, 0, 0},
+ {0x5848, 0x10, 0, 0}, {0x5849, 0x10, 0, 0}, {0x584a, 0x10, 0, 0},
+ {0x584b, 0x0e, 0, 0}, {0x584c, 0x10, 0, 0}, {0x584d, 0x10, 0, 0},
+ {0x584e, 0x11, 0, 0}, {0x584f, 0x10, 0, 0}, {0x5850, 0x0f, 0, 0},
+ {0x5851, 0x0c, 0, 0}, {0x5852, 0x0f, 0, 0}, {0x5853, 0x10, 0, 0},
+ {0x5854, 0x10, 0, 0}, {0x5855, 0x0f, 0, 0}, {0x5856, 0x0e, 0, 0},
+ {0x5857, 0x0b, 0, 0}, {0x5858, 0x10, 0, 0}, {0x5859, 0x0d, 0, 0},
+ {0x585a, 0x0d, 0, 0}, {0x585b, 0x0c, 0, 0}, {0x585c, 0x0c, 0, 0},
+ {0x585d, 0x0c, 0, 0}, {0x585e, 0x0b, 0, 0}, {0x585f, 0x0c, 0, 0},
+ {0x5860, 0x0c, 0, 0}, {0x5861, 0x0c, 0, 0}, {0x5862, 0x0d, 0, 0},
+ {0x5863, 0x08, 0, 0}, {0x5864, 0x11, 0, 0}, {0x5865, 0x18, 0, 0},
+ {0x5866, 0x18, 0, 0}, {0x5867, 0x19, 0, 0}, {0x5868, 0x17, 0, 0},
+ {0x5869, 0x19, 0, 0}, {0x586a, 0x16, 0, 0}, {0x586b, 0x13, 0, 0},
+ {0x586c, 0x13, 0, 0}, {0x586d, 0x12, 0, 0}, {0x586e, 0x13, 0, 0},
+ {0x586f, 0x16, 0, 0}, {0x5870, 0x14, 0, 0}, {0x5871, 0x12, 0, 0},
+ {0x5872, 0x10, 0, 0}, {0x5873, 0x11, 0, 0}, {0x5874, 0x11, 0, 0},
+ {0x5875, 0x16, 0, 0}, {0x5876, 0x14, 0, 0}, {0x5877, 0x11, 0, 0},
+ {0x5878, 0x10, 0, 0}, {0x5879, 0x0f, 0, 0}, {0x587a, 0x10, 0, 0},
+ {0x587b, 0x14, 0, 0}, {0x587c, 0x13, 0, 0}, {0x587d, 0x12, 0, 0},
+ {0x587e, 0x11, 0, 0}, {0x587f, 0x11, 0, 0}, {0x5880, 0x12, 0, 0},
+ {0x5881, 0x15, 0, 0}, {0x5882, 0x14, 0, 0}, {0x5883, 0x15, 0, 0},
+ {0x5884, 0x15, 0, 0}, {0x5885, 0x15, 0, 0}, {0x5886, 0x13, 0, 0},
+ {0x5887, 0x17, 0, 0}, {0x3710, 0x10, 0, 0}, {0x3632, 0x51, 0, 0},
+ {0x3702, 0x10, 0, 0}, {0x3703, 0xb2, 0, 0}, {0x3704, 0x18, 0, 0},
+ {0x370b, 0x40, 0, 0}, {0x370d, 0x03, 0, 0}, {0x3631, 0x01, 0, 0},
+ {0x3632, 0x52, 0, 0}, {0x3606, 0x24, 0, 0}, {0x3620, 0x96, 0, 0},
+ {0x5785, 0x07, 0, 0}, {0x3a13, 0x30, 0, 0}, {0x3600, 0x52, 0, 0},
+ {0x3604, 0x48, 0, 0}, {0x3606, 0x1b, 0, 0}, {0x370d, 0x0b, 0, 0},
+ {0x370f, 0xc0, 0, 0}, {0x3709, 0x01, 0, 0}, {0x3823, 0x00, 0, 0},
+ {0x5007, 0x00, 0, 0}, {0x5009, 0x00, 0, 0}, {0x5011, 0x00, 0, 0},
+ {0x5013, 0x00, 0, 0}, {0x519e, 0x00, 0, 0}, {0x5086, 0x00, 0, 0},
+ {0x5087, 0x00, 0, 0}, {0x5088, 0x00, 0, 0}, {0x5089, 0x00, 0, 0},
+ {0x302b, 0x00, 0, 0}, {0x3621, 0x87, 0, 0}, {0x3a00, 0x78, 0, 0},
+ {0x302c, 0x60, 0x60, 0},
+};
+
+static struct reg_value ov5642_setting_15fps_720P_1280_720[] = {
+ {0x3103, 0x93, 0, 0}, {0x3008, 0x82, 0, 0}, {0x3017, 0x7f, 0, 0},
+ {0x3018, 0xfc, 0, 0}, {0x3810, 0xc2, 0, 0}, {0x3615, 0xf0, 0, 0},
+ {0x3000, 0x00, 0, 0}, {0x3001, 0x00, 0, 0}, {0x3002, 0x00, 0, 0},
+ {0x3003, 0x00, 0, 0}, {0x3004, 0xff, 0, 0}, {0x3030, 0x2b, 0, 0},
+ {0x3011, 0x08, 0, 0}, {0x3010, 0x10, 0, 0}, {0x3604, 0x60, 0, 0},
+ {0x3622, 0x60, 0, 0}, {0x3621, 0x09, 0, 0}, {0x3709, 0x00, 0, 0},
+ {0x4000, 0x21, 0, 0}, {0x401d, 0x22, 0, 0}, {0x3600, 0x54, 0, 0},
+ {0x3605, 0x04, 0, 0}, {0x3606, 0x3f, 0, 0}, {0x3c01, 0x80, 0, 0},
+ {0x300d, 0x22, 0, 0}, {0x3623, 0x22, 0, 0}, {0x5000, 0x4f, 0, 0},
+ {0x5020, 0x04, 0, 0}, {0x5181, 0x79, 0, 0}, {0x5182, 0x00, 0, 0},
+ {0x5185, 0x22, 0, 0}, {0x5197, 0x01, 0, 0}, {0x5500, 0x0a, 0, 0},
+ {0x5504, 0x00, 0, 0}, {0x5505, 0x7f, 0, 0}, {0x5080, 0x08, 0, 0},
+ {0x300e, 0x18, 0, 0}, {0x4610, 0x00, 0, 0}, {0x471d, 0x05, 0, 0},
+ {0x4708, 0x06, 0, 0}, {0x370c, 0xa0, 0, 0}, {0x3808, 0x0a, 0, 0},
+ {0x3809, 0x20, 0, 0}, {0x380a, 0x07, 0, 0}, {0x380b, 0x98, 0, 0},
+ {0x380c, 0x0c, 0, 0}, {0x380d, 0x80, 0, 0}, {0x380e, 0x07, 0, 0},
+ {0x380f, 0xd0, 0, 0}, {0x5687, 0x94, 0, 0}, {0x501f, 0x00, 0, 0},
+ {0x5000, 0x4f, 0, 0}, {0x5001, 0xcf, 0, 0}, {0x4300, 0x30, 0, 0},
+ {0x4300, 0x30, 0, 0}, {0x460b, 0x35, 0, 0}, {0x471d, 0x00, 0, 0},
+ {0x3002, 0x0c, 0, 0}, {0x3002, 0x00, 0, 0}, {0x4713, 0x03, 0, 0},
+ {0x471c, 0x50, 0, 0}, {0x4721, 0x02, 0, 0}, {0x4402, 0x90, 0, 0},
+ {0x460c, 0x22, 0, 0}, {0x3815, 0x44, 0, 0}, {0x3503, 0x07, 0, 0},
+ {0x3501, 0x73, 0, 0}, {0x3502, 0x80, 0, 0}, {0x350b, 0x00, 0, 0},
+ {0x3818, 0xc8, 0, 0}, {0x3801, 0x88, 0, 0}, {0x3824, 0x11, 0, 0},
+ {0x3a00, 0x78, 0, 0}, {0x3a1a, 0x04, 0, 0}, {0x3a13, 0x30, 0, 0},
+ {0x3a18, 0x00, 0, 0}, {0x3a19, 0x7c, 0, 0}, {0x3a08, 0x12, 0, 0},
+ {0x3a09, 0xc0, 0, 0}, {0x3a0a, 0x0f, 0, 0}, {0x3a0b, 0xa0, 0, 0},
+ {0x350c, 0x07, 0, 0}, {0x350d, 0xd0, 0, 0}, {0x3a0d, 0x08, 0, 0},
+ {0x3a0e, 0x06, 0, 0}, {0x3500, 0x00, 0, 0}, {0x3501, 0x00, 0, 0},
+ {0x3502, 0x00, 0, 0}, {0x350a, 0x00, 0, 0}, {0x350b, 0x00, 0, 0},
+ {0x3503, 0x00, 0, 0}, {0x3a0f, 0x3c, 0, 0}, {0x3a10, 0x32, 0, 0},
+ {0x3a1b, 0x3c, 0, 0}, {0x3a1e, 0x32, 0, 0}, {0x3a11, 0x80, 0, 0},
+ {0x3a1f, 0x20, 0, 0}, {0x3030, 0x2b, 0, 0}, {0x3a02, 0x00, 0, 0},
+ {0x3a03, 0x7d, 0, 0}, {0x3a04, 0x00, 0, 0}, {0x3a14, 0x00, 0, 0},
+ {0x3a15, 0x7d, 0, 0}, {0x3a16, 0x00, 0, 0}, {0x3a00, 0x78, 0, 0},
+ {0x3a08, 0x09, 0, 0}, {0x3a09, 0x60, 0, 0}, {0x3a0a, 0x07, 0, 0},
+ {0x3a0b, 0xd0, 0, 0}, {0x3a0d, 0x10, 0, 0}, {0x3a0e, 0x0d, 0, 0},
+ {0x4407, 0x04, 0, 0}, {0x5193, 0x70, 0, 0}, {0x589b, 0x00, 0, 0},
+ {0x589a, 0xc0, 0, 0}, {0x401e, 0x20, 0, 0}, {0x4001, 0x42, 0, 0},
+ {0x401c, 0x06, 0, 0}, {0x3825, 0xac, 0, 0}, {0x3827, 0x0c, 0, 0},
+ {0x528a, 0x01, 0, 0}, {0x528b, 0x04, 0, 0}, {0x528c, 0x08, 0, 0},
+ {0x528d, 0x10, 0, 0}, {0x528e, 0x20, 0, 0}, {0x528f, 0x28, 0, 0},
+ {0x5290, 0x30, 0, 0}, {0x5292, 0x00, 0, 0}, {0x5293, 0x01, 0, 0},
+ {0x5294, 0x00, 0, 0}, {0x5295, 0x04, 0, 0}, {0x5296, 0x00, 0, 0},
+ {0x5297, 0x08, 0, 0}, {0x5298, 0x00, 0, 0}, {0x5299, 0x10, 0, 0},
+ {0x529a, 0x00, 0, 0}, {0x529b, 0x20, 0, 0}, {0x529c, 0x00, 0, 0},
+ {0x529d, 0x28, 0, 0}, {0x529e, 0x00, 0, 0}, {0x529f, 0x30, 0, 0},
+ {0x5282, 0x00, 0, 0}, {0x5300, 0x00, 0, 0}, {0x5301, 0x20, 0, 0},
+ {0x5302, 0x00, 0, 0}, {0x5303, 0x7c, 0, 0}, {0x530c, 0x00, 0, 0},
+ {0x530d, 0x0c, 0, 0}, {0x530e, 0x20, 0, 0}, {0x530f, 0x80, 0, 0},
+ {0x5310, 0x20, 0, 0}, {0x5311, 0x80, 0, 0}, {0x5308, 0x20, 0, 0},
+ {0x5309, 0x40, 0, 0}, {0x5304, 0x00, 0, 0}, {0x5305, 0x30, 0, 0},
+ {0x5306, 0x00, 0, 0}, {0x5307, 0x80, 0, 0}, {0x5314, 0x08, 0, 0},
+ {0x5315, 0x20, 0, 0}, {0x5319, 0x30, 0, 0}, {0x5316, 0x10, 0, 0},
+ {0x5317, 0x00, 0, 0}, {0x5318, 0x02, 0, 0}, {0x5380, 0x01, 0, 0},
+ {0x5381, 0x00, 0, 0}, {0x5382, 0x00, 0, 0}, {0x5383, 0x4e, 0, 0},
+ {0x5384, 0x00, 0, 0}, {0x5385, 0x0f, 0, 0}, {0x5386, 0x00, 0, 0},
+ {0x5387, 0x00, 0, 0}, {0x5388, 0x01, 0, 0}, {0x5389, 0x15, 0, 0},
+ {0x538a, 0x00, 0, 0}, {0x538b, 0x31, 0, 0}, {0x538c, 0x00, 0, 0},
+ {0x538d, 0x00, 0, 0}, {0x538e, 0x00, 0, 0}, {0x538f, 0x0f, 0, 0},
+ {0x5390, 0x00, 0, 0}, {0x5391, 0xab, 0, 0}, {0x5392, 0x00, 0, 0},
+ {0x5393, 0xa2, 0, 0}, {0x5394, 0x08, 0, 0}, {0x5480, 0x14, 0, 0},
+ {0x5481, 0x21, 0, 0}, {0x5482, 0x36, 0, 0}, {0x5483, 0x57, 0, 0},
+ {0x5484, 0x65, 0, 0}, {0x5485, 0x71, 0, 0}, {0x5486, 0x7d, 0, 0},
+ {0x5487, 0x87, 0, 0}, {0x5488, 0x91, 0, 0}, {0x5489, 0x9a, 0, 0},
+ {0x548a, 0xaa, 0, 0}, {0x548b, 0xb8, 0, 0}, {0x548c, 0xcd, 0, 0},
+ {0x548d, 0xdd, 0, 0}, {0x548e, 0xea, 0, 0}, {0x548f, 0x1d, 0, 0},
+ {0x5490, 0x05, 0, 0}, {0x5491, 0x00, 0, 0}, {0x5492, 0x04, 0, 0},
+ {0x5493, 0x20, 0, 0}, {0x5494, 0x03, 0, 0}, {0x5495, 0x60, 0, 0},
+ {0x5496, 0x02, 0, 0}, {0x5497, 0xb8, 0, 0}, {0x5498, 0x02, 0, 0},
+ {0x5499, 0x86, 0, 0}, {0x549a, 0x02, 0, 0}, {0x549b, 0x5b, 0, 0},
+ {0x549c, 0x02, 0, 0}, {0x549d, 0x3b, 0, 0}, {0x549e, 0x02, 0, 0},
+ {0x549f, 0x1c, 0, 0}, {0x54a0, 0x02, 0, 0}, {0x54a1, 0x04, 0, 0},
+ {0x54a2, 0x01, 0, 0}, {0x54a3, 0xed, 0, 0}, {0x54a4, 0x01, 0, 0},
+ {0x54a5, 0xc5, 0, 0}, {0x54a6, 0x01, 0, 0}, {0x54a7, 0xa5, 0, 0},
+ {0x54a8, 0x01, 0, 0}, {0x54a9, 0x6c, 0, 0}, {0x54aa, 0x01, 0, 0},
+ {0x54ab, 0x41, 0, 0}, {0x54ac, 0x01, 0, 0}, {0x54ad, 0x20, 0, 0},
+ {0x54ae, 0x00, 0, 0}, {0x54af, 0x16, 0, 0}, {0x54b0, 0x01, 0, 0},
+ {0x54b1, 0x20, 0, 0}, {0x54b2, 0x00, 0, 0}, {0x54b3, 0x10, 0, 0},
+ {0x54b4, 0x00, 0, 0}, {0x54b5, 0xf0, 0, 0}, {0x54b6, 0x00, 0, 0},
+ {0x54b7, 0xdf, 0, 0}, {0x5402, 0x3f, 0, 0}, {0x5403, 0x00, 0, 0},
+ {0x3406, 0x00, 0, 0}, {0x5180, 0xff, 0, 0}, {0x5181, 0x52, 0, 0},
+ {0x5182, 0x11, 0, 0}, {0x5183, 0x14, 0, 0}, {0x5184, 0x25, 0, 0},
+ {0x5185, 0x24, 0, 0}, {0x5186, 0x06, 0, 0}, {0x5187, 0x08, 0, 0},
+ {0x5188, 0x08, 0, 0}, {0x5189, 0x7c, 0, 0}, {0x518a, 0x60, 0, 0},
+ {0x518b, 0xb2, 0, 0}, {0x518c, 0xb2, 0, 0}, {0x518d, 0x44, 0, 0},
+ {0x518e, 0x3d, 0, 0}, {0x518f, 0x58, 0, 0}, {0x5190, 0x46, 0, 0},
+ {0x5191, 0xf8, 0, 0}, {0x5192, 0x04, 0, 0}, {0x5193, 0x70, 0, 0},
+ {0x5194, 0xf0, 0, 0}, {0x5195, 0xf0, 0, 0}, {0x5196, 0x03, 0, 0},
+ {0x5197, 0x01, 0, 0}, {0x5198, 0x04, 0, 0}, {0x5199, 0x12, 0, 0},
+ {0x519a, 0x04, 0, 0}, {0x519b, 0x00, 0, 0}, {0x519c, 0x06, 0, 0},
+ {0x519d, 0x82, 0, 0}, {0x519e, 0x00, 0, 0}, {0x5025, 0x80, 0, 0},
+ {0x3a0f, 0x38, 0, 0}, {0x3a10, 0x30, 0, 0}, {0x3a1b, 0x3a, 0, 0},
+ {0x3a1e, 0x2e, 0, 0}, {0x3a11, 0x60, 0, 0}, {0x3a1f, 0x10, 0, 0},
+ {0x5688, 0xa6, 0, 0}, {0x5689, 0x6a, 0, 0}, {0x568a, 0xea, 0, 0},
+ {0x568b, 0xae, 0, 0}, {0x568c, 0xa6, 0, 0}, {0x568d, 0x6a, 0, 0},
+ {0x568e, 0x62, 0, 0}, {0x568f, 0x26, 0, 0}, {0x5583, 0x40, 0, 0},
+ {0x5584, 0x40, 0, 0}, {0x5580, 0x02, 0, 0}, {0x5000, 0xcf, 0, 0},
+ {0x5800, 0x27, 0, 0}, {0x5801, 0x19, 0, 0}, {0x5802, 0x12, 0, 0},
+ {0x5803, 0x0f, 0, 0}, {0x5804, 0x10, 0, 0}, {0x5805, 0x15, 0, 0},
+ {0x5806, 0x1e, 0, 0}, {0x5807, 0x2f, 0, 0}, {0x5808, 0x15, 0, 0},
+ {0x5809, 0x0d, 0, 0}, {0x580a, 0x0a, 0, 0}, {0x580b, 0x09, 0, 0},
+ {0x580c, 0x0a, 0, 0}, {0x580d, 0x0c, 0, 0}, {0x580e, 0x12, 0, 0},
+ {0x580f, 0x19, 0, 0}, {0x5810, 0x0b, 0, 0}, {0x5811, 0x07, 0, 0},
+ {0x5812, 0x04, 0, 0}, {0x5813, 0x03, 0, 0}, {0x5814, 0x03, 0, 0},
+ {0x5815, 0x06, 0, 0}, {0x5816, 0x0a, 0, 0}, {0x5817, 0x0f, 0, 0},
+ {0x5818, 0x0a, 0, 0}, {0x5819, 0x05, 0, 0}, {0x581a, 0x01, 0, 0},
+ {0x581b, 0x00, 0, 0}, {0x581c, 0x00, 0, 0}, {0x581d, 0x03, 0, 0},
+ {0x581e, 0x08, 0, 0}, {0x581f, 0x0c, 0, 0}, {0x5820, 0x0a, 0, 0},
+ {0x5821, 0x05, 0, 0}, {0x5822, 0x01, 0, 0}, {0x5823, 0x00, 0, 0},
+ {0x5824, 0x00, 0, 0}, {0x5825, 0x03, 0, 0}, {0x5826, 0x08, 0, 0},
+ {0x5827, 0x0c, 0, 0}, {0x5828, 0x0e, 0, 0}, {0x5829, 0x08, 0, 0},
+ {0x582a, 0x06, 0, 0}, {0x582b, 0x04, 0, 0}, {0x582c, 0x05, 0, 0},
+ {0x582d, 0x07, 0, 0}, {0x582e, 0x0b, 0, 0}, {0x582f, 0x12, 0, 0},
+ {0x5830, 0x18, 0, 0}, {0x5831, 0x10, 0, 0}, {0x5832, 0x0c, 0, 0},
+ {0x5833, 0x0a, 0, 0}, {0x5834, 0x0b, 0, 0}, {0x5835, 0x0e, 0, 0},
+ {0x5836, 0x15, 0, 0}, {0x5837, 0x19, 0, 0}, {0x5838, 0x32, 0, 0},
+ {0x5839, 0x1f, 0, 0}, {0x583a, 0x18, 0, 0}, {0x583b, 0x16, 0, 0},
+ {0x583c, 0x17, 0, 0}, {0x583d, 0x1e, 0, 0}, {0x583e, 0x26, 0, 0},
+ {0x583f, 0x53, 0, 0}, {0x5840, 0x10, 0, 0}, {0x5841, 0x0f, 0, 0},
+ {0x5842, 0x0d, 0, 0}, {0x5843, 0x0c, 0, 0}, {0x5844, 0x0e, 0, 0},
+ {0x5845, 0x09, 0, 0}, {0x5846, 0x11, 0, 0}, {0x5847, 0x10, 0, 0},
+ {0x5848, 0x10, 0, 0}, {0x5849, 0x10, 0, 0}, {0x584a, 0x10, 0, 0},
+ {0x584b, 0x0e, 0, 0}, {0x584c, 0x10, 0, 0}, {0x584d, 0x10, 0, 0},
+ {0x584e, 0x11, 0, 0}, {0x584f, 0x10, 0, 0}, {0x5850, 0x0f, 0, 0},
+ {0x5851, 0x0c, 0, 0}, {0x5852, 0x0f, 0, 0}, {0x5853, 0x10, 0, 0},
+ {0x5854, 0x10, 0, 0}, {0x5855, 0x0f, 0, 0}, {0x5856, 0x0e, 0, 0},
+ {0x5857, 0x0b, 0, 0}, {0x5858, 0x10, 0, 0}, {0x5859, 0x0d, 0, 0},
+ {0x585a, 0x0d, 0, 0}, {0x585b, 0x0c, 0, 0}, {0x585c, 0x0c, 0, 0},
+ {0x585d, 0x0c, 0, 0}, {0x585e, 0x0b, 0, 0}, {0x585f, 0x0c, 0, 0},
+ {0x5860, 0x0c, 0, 0}, {0x5861, 0x0c, 0, 0}, {0x5862, 0x0d, 0, 0},
+ {0x5863, 0x08, 0, 0}, {0x5864, 0x11, 0, 0}, {0x5865, 0x18, 0, 0},
+ {0x5866, 0x18, 0, 0}, {0x5867, 0x19, 0, 0}, {0x5868, 0x17, 0, 0},
+ {0x5869, 0x19, 0, 0}, {0x586a, 0x16, 0, 0}, {0x586b, 0x13, 0, 0},
+ {0x586c, 0x13, 0, 0}, {0x586d, 0x12, 0, 0}, {0x586e, 0x13, 0, 0},
+ {0x586f, 0x16, 0, 0}, {0x5870, 0x14, 0, 0}, {0x5871, 0x12, 0, 0},
+ {0x5872, 0x10, 0, 0}, {0x5873, 0x11, 0, 0}, {0x5874, 0x11, 0, 0},
+ {0x5875, 0x16, 0, 0}, {0x5876, 0x14, 0, 0}, {0x5877, 0x11, 0, 0},
+ {0x5878, 0x10, 0, 0}, {0x5879, 0x0f, 0, 0}, {0x587a, 0x10, 0, 0},
+ {0x587b, 0x14, 0, 0}, {0x587c, 0x13, 0, 0}, {0x587d, 0x12, 0, 0},
+ {0x587e, 0x11, 0, 0}, {0x587f, 0x11, 0, 0}, {0x5880, 0x12, 0, 0},
+ {0x5881, 0x15, 0, 0}, {0x5882, 0x14, 0, 0}, {0x5883, 0x15, 0, 0},
+ {0x5884, 0x15, 0, 0}, {0x5885, 0x15, 0, 0}, {0x5886, 0x13, 0, 0},
+ {0x5887, 0x17, 0, 0}, {0x3710, 0x10, 0, 0}, {0x3632, 0x51, 0, 0},
+ {0x3702, 0x10, 0, 0}, {0x3703, 0xb2, 0, 0}, {0x3704, 0x18, 0, 0},
+ {0x370b, 0x40, 0, 0}, {0x370d, 0x03, 0, 0}, {0x3631, 0x01, 0, 0},
+ {0x3632, 0x52, 0, 0}, {0x3606, 0x24, 0, 0}, {0x3620, 0x96, 0, 0},
+ {0x5785, 0x07, 0, 0}, {0x3a13, 0x30, 0, 0}, {0x3600, 0x52, 0, 0},
+ {0x3604, 0x48, 0, 0}, {0x3606, 0x1b, 0, 0}, {0x370d, 0x0b, 0, 0},
+ {0x370f, 0xc0, 0, 0}, {0x3709, 0x01, 0, 0}, {0x3823, 0x00, 0, 0},
+ {0x5007, 0x00, 0, 0}, {0x5009, 0x00, 0, 0}, {0x5011, 0x00, 0, 0},
+ {0x5013, 0x00, 0, 0}, {0x519e, 0x00, 0, 0}, {0x5086, 0x00, 0, 0},
+ {0x5087, 0x00, 0, 0}, {0x5088, 0x00, 0, 0}, {0x5089, 0x00, 0, 0},
+ {0x302b, 0x00, 0, 0}, {0x3503, 0x07, 0, 0}, {0x3011, 0x08, 0, 0},
+ {0x350c, 0x02, 0, 0}, {0x350d, 0xe4, 0, 0}, {0x3621, 0xc9, 0, 0},
+ {0x370a, 0x81, 0, 0}, {0x3803, 0x08, 0, 0}, {0x3804, 0x05, 0, 0},
+ {0x3805, 0x00, 0, 0}, {0x3806, 0x02, 0, 0}, {0x3807, 0xd0, 0, 0},
+ {0x3808, 0x05, 0, 0}, {0x3809, 0x00, 0, 0}, {0x380a, 0x02, 0, 0},
+ {0x380b, 0xd0, 0, 0}, {0x380c, 0x08, 0, 0}, {0x380d, 0x72, 0, 0},
+ {0x380e, 0x02, 0, 0}, {0x380f, 0xe4, 0, 0}, {0x3810, 0xc0, 0, 0},
+ {0x3818, 0xc9, 0, 0}, {0x381c, 0x10, 0, 0}, {0x381d, 0xa0, 0, 0},
+ {0x381e, 0x05, 0, 0}, {0x381f, 0xb0, 0, 0}, {0x3820, 0x00, 0, 0},
+ {0x3821, 0x00, 0, 0}, {0x3824, 0x11, 0, 0}, {0x3a08, 0x1b, 0, 0},
+ {0x3a09, 0xc0, 0, 0}, {0x3a0a, 0x17, 0, 0}, {0x3a0b, 0x20, 0, 0},
+ {0x3a0d, 0x02, 0, 0}, {0x3a0e, 0x01, 0, 0}, {0x401c, 0x04, 0, 0},
+ {0x5682, 0x05, 0, 0}, {0x5683, 0x00, 0, 0}, {0x5686, 0x02, 0, 0},
+ {0x5687, 0xcc, 0, 0}, {0x5001, 0x7f, 0, 0}, {0x589b, 0x06, 0, 0},
+ {0x589a, 0xc5, 0, 0}, {0x3503, 0x00, 0, 0}, {0x3010, 0x10, 0, 0},
+ {0x460c, 0x20, 0, 0}, {0x460b, 0x37, 0, 0}, {0x471c, 0xd0, 0, 0},
+ {0x471d, 0x05, 0, 0}, {0x3815, 0x01, 0, 0}, {0x3818, 0x00, 0x08, 0},
+ {0x501f, 0x00, 0, 0}, {0x4300, 0x30, 0, 0}, {0x3002, 0x1c, 0, 0},
+ {0x3819, 0x80, 0, 0}, {0x5002, 0xe0, 0, 0}, {0x3010, 0x30, 0, 0},
+ {0x3a08, 0x06, 0, 0}, {0x3a09, 0x60, 0, 0}, {0x3a0a, 0x05, 0, 0},
+ {0x3a0b, 0x50, 0, 0}, {0x3a0d, 0x08, 0, 0}, {0x3a0e, 0x07, 0, 0},
+};
+
+static struct reg_value ov5642_setting_30fps_720P_1280_720[] = {
+ {0x3103, 0x93, 0, 0}, {0x3008, 0x82, 0, 0}, {0x3017, 0x7f, 0, 0},
+ {0x3018, 0xfc, 0, 0}, {0x3810, 0xc2, 0, 0}, {0x3615, 0xf0, 0, 0},
+ {0x3000, 0x00, 0, 0}, {0x3001, 0x00, 0, 0}, {0x3002, 0x00, 0, 0},
+ {0x3003, 0x00, 0, 0}, {0x3004, 0xff, 0, 0}, {0x3030, 0x2b, 0, 0},
+ {0x3011, 0x08, 0, 0}, {0x3010, 0x10, 0, 0}, {0x3604, 0x60, 0, 0},
+ {0x3622, 0x60, 0, 0}, {0x3621, 0x09, 0, 0}, {0x3709, 0x00, 0, 0},
+ {0x4000, 0x21, 0, 0}, {0x401d, 0x22, 0, 0}, {0x3600, 0x54, 0, 0},
+ {0x3605, 0x04, 0, 0}, {0x3606, 0x3f, 0, 0}, {0x3c01, 0x80, 0, 0},
+ {0x300d, 0x22, 0, 0}, {0x3623, 0x22, 0, 0}, {0x5000, 0x4f, 0, 0},
+ {0x5020, 0x04, 0, 0}, {0x5181, 0x79, 0, 0}, {0x5182, 0x00, 0, 0},
+ {0x5185, 0x22, 0, 0}, {0x5197, 0x01, 0, 0}, {0x5500, 0x0a, 0, 0},
+ {0x5504, 0x00, 0, 0}, {0x5505, 0x7f, 0, 0}, {0x5080, 0x08, 0, 0},
+ {0x300e, 0x18, 0, 0}, {0x4610, 0x00, 0, 0}, {0x471d, 0x05, 0, 0},
+ {0x4708, 0x06, 0, 0}, {0x370c, 0xa0, 0, 0}, {0x3808, 0x0a, 0, 0},
+ {0x3809, 0x20, 0, 0}, {0x380a, 0x07, 0, 0}, {0x380b, 0x98, 0, 0},
+ {0x380c, 0x0c, 0, 0}, {0x380d, 0x80, 0, 0}, {0x380e, 0x07, 0, 0},
+ {0x380f, 0xd0, 0, 0}, {0x5687, 0x94, 0, 0}, {0x501f, 0x00, 0, 0},
+ {0x5000, 0x4f, 0, 0}, {0x5001, 0xcf, 0, 0}, {0x4300, 0x30, 0, 0},
+ {0x4300, 0x30, 0, 0}, {0x460b, 0x35, 0, 0}, {0x471d, 0x00, 0, 0},
+ {0x3002, 0x0c, 0, 0}, {0x3002, 0x00, 0, 0}, {0x4713, 0x03, 0, 0},
+ {0x471c, 0x50, 0, 0}, {0x4721, 0x02, 0, 0}, {0x4402, 0x90, 0, 0},
+ {0x460c, 0x22, 0, 0}, {0x3815, 0x44, 0, 0}, {0x3503, 0x07, 0, 0},
+ {0x3501, 0x73, 0, 0}, {0x3502, 0x80, 0, 0}, {0x350b, 0x00, 0, 0},
+ {0x3818, 0xc8, 0, 0}, {0x3801, 0x88, 0, 0}, {0x3824, 0x11, 0, 0},
+ {0x3a00, 0x78, 0, 0}, {0x3a1a, 0x04, 0, 0}, {0x3a13, 0x30, 0, 0},
+ {0x3a18, 0x00, 0, 0}, {0x3a19, 0x7c, 0, 0}, {0x3a08, 0x12, 0, 0},
+ {0x3a09, 0xc0, 0, 0}, {0x3a0a, 0x0f, 0, 0}, {0x3a0b, 0xa0, 0, 0},
+ {0x350c, 0x07, 0, 0}, {0x350d, 0xd0, 0, 0}, {0x3a0d, 0x08, 0, 0},
+ {0x3a0e, 0x06, 0, 0}, {0x3500, 0x00, 0, 0}, {0x3501, 0x00, 0, 0},
+ {0x3502, 0x00, 0, 0}, {0x350a, 0x00, 0, 0}, {0x350b, 0x00, 0, 0},
+ {0x3503, 0x00, 0, 0}, {0x3a0f, 0x3c, 0, 0}, {0x3a10, 0x32, 0, 0},
+ {0x3a1b, 0x3c, 0, 0}, {0x3a1e, 0x32, 0, 0}, {0x3a11, 0x80, 0, 0},
+ {0x3a1f, 0x20, 0, 0}, {0x3030, 0x2b, 0, 0}, {0x3a02, 0x00, 0, 0},
+ {0x3a03, 0x7d, 0, 0}, {0x3a04, 0x00, 0, 0}, {0x3a14, 0x00, 0, 0},
+ {0x3a15, 0x7d, 0, 0}, {0x3a16, 0x00, 0, 0}, {0x3a00, 0x78, 0, 0},
+ {0x3a08, 0x09, 0, 0}, {0x3a09, 0x60, 0, 0}, {0x3a0a, 0x07, 0, 0},
+ {0x3a0b, 0xd0, 0, 0}, {0x3a0d, 0x10, 0, 0}, {0x3a0e, 0x0d, 0, 0},
+ {0x4407, 0x04, 0, 0}, {0x5193, 0x70, 0, 0}, {0x589b, 0x00, 0, 0},
+ {0x589a, 0xc0, 0, 0}, {0x401e, 0x20, 0, 0}, {0x4001, 0x42, 0, 0},
+ {0x401c, 0x06, 0, 0}, {0x3825, 0xac, 0, 0}, {0x3827, 0x0c, 0, 0},
+ {0x528a, 0x01, 0, 0}, {0x528b, 0x04, 0, 0}, {0x528c, 0x08, 0, 0},
+ {0x528d, 0x10, 0, 0}, {0x528e, 0x20, 0, 0}, {0x528f, 0x28, 0, 0},
+ {0x5290, 0x30, 0, 0}, {0x5292, 0x00, 0, 0}, {0x5293, 0x01, 0, 0},
+ {0x5294, 0x00, 0, 0}, {0x5295, 0x04, 0, 0}, {0x5296, 0x00, 0, 0},
+ {0x5297, 0x08, 0, 0}, {0x5298, 0x00, 0, 0}, {0x5299, 0x10, 0, 0},
+ {0x529a, 0x00, 0, 0}, {0x529b, 0x20, 0, 0}, {0x529c, 0x00, 0, 0},
+ {0x529d, 0x28, 0, 0}, {0x529e, 0x00, 0, 0}, {0x529f, 0x30, 0, 0},
+ {0x5282, 0x00, 0, 0}, {0x5300, 0x00, 0, 0}, {0x5301, 0x20, 0, 0},
+ {0x5302, 0x00, 0, 0}, {0x5303, 0x7c, 0, 0}, {0x530c, 0x00, 0, 0},
+ {0x530d, 0x0c, 0, 0}, {0x530e, 0x20, 0, 0}, {0x530f, 0x80, 0, 0},
+ {0x5310, 0x20, 0, 0}, {0x5311, 0x80, 0, 0}, {0x5308, 0x20, 0, 0},
+ {0x5309, 0x40, 0, 0}, {0x5304, 0x00, 0, 0}, {0x5305, 0x30, 0, 0},
+ {0x5306, 0x00, 0, 0}, {0x5307, 0x80, 0, 0}, {0x5314, 0x08, 0, 0},
+ {0x5315, 0x20, 0, 0}, {0x5319, 0x30, 0, 0}, {0x5316, 0x10, 0, 0},
+ {0x5317, 0x00, 0, 0}, {0x5318, 0x02, 0, 0}, {0x5380, 0x01, 0, 0},
+ {0x5381, 0x00, 0, 0}, {0x5382, 0x00, 0, 0}, {0x5383, 0x4e, 0, 0},
+ {0x5384, 0x00, 0, 0}, {0x5385, 0x0f, 0, 0}, {0x5386, 0x00, 0, 0},
+ {0x5387, 0x00, 0, 0}, {0x5388, 0x01, 0, 0}, {0x5389, 0x15, 0, 0},
+ {0x538a, 0x00, 0, 0}, {0x538b, 0x31, 0, 0}, {0x538c, 0x00, 0, 0},
+ {0x538d, 0x00, 0, 0}, {0x538e, 0x00, 0, 0}, {0x538f, 0x0f, 0, 0},
+ {0x5390, 0x00, 0, 0}, {0x5391, 0xab, 0, 0}, {0x5392, 0x00, 0, 0},
+ {0x5393, 0xa2, 0, 0}, {0x5394, 0x08, 0, 0}, {0x5480, 0x14, 0, 0},
+ {0x5481, 0x21, 0, 0}, {0x5482, 0x36, 0, 0}, {0x5483, 0x57, 0, 0},
+ {0x5484, 0x65, 0, 0}, {0x5485, 0x71, 0, 0}, {0x5486, 0x7d, 0, 0},
+ {0x5487, 0x87, 0, 0}, {0x5488, 0x91, 0, 0}, {0x5489, 0x9a, 0, 0},
+ {0x548a, 0xaa, 0, 0}, {0x548b, 0xb8, 0, 0}, {0x548c, 0xcd, 0, 0},
+ {0x548d, 0xdd, 0, 0}, {0x548e, 0xea, 0, 0}, {0x548f, 0x1d, 0, 0},
+ {0x5490, 0x05, 0, 0}, {0x5491, 0x00, 0, 0}, {0x5492, 0x04, 0, 0},
+ {0x5493, 0x20, 0, 0}, {0x5494, 0x03, 0, 0}, {0x5495, 0x60, 0, 0},
+ {0x5496, 0x02, 0, 0}, {0x5497, 0xb8, 0, 0}, {0x5498, 0x02, 0, 0},
+ {0x5499, 0x86, 0, 0}, {0x549a, 0x02, 0, 0}, {0x549b, 0x5b, 0, 0},
+ {0x549c, 0x02, 0, 0}, {0x549d, 0x3b, 0, 0}, {0x549e, 0x02, 0, 0},
+ {0x549f, 0x1c, 0, 0}, {0x54a0, 0x02, 0, 0}, {0x54a1, 0x04, 0, 0},
+ {0x54a2, 0x01, 0, 0}, {0x54a3, 0xed, 0, 0}, {0x54a4, 0x01, 0, 0},
+ {0x54a5, 0xc5, 0, 0}, {0x54a6, 0x01, 0, 0}, {0x54a7, 0xa5, 0, 0},
+ {0x54a8, 0x01, 0, 0}, {0x54a9, 0x6c, 0, 0}, {0x54aa, 0x01, 0, 0},
+ {0x54ab, 0x41, 0, 0}, {0x54ac, 0x01, 0, 0}, {0x54ad, 0x20, 0, 0},
+ {0x54ae, 0x00, 0, 0}, {0x54af, 0x16, 0, 0}, {0x54b0, 0x01, 0, 0},
+ {0x54b1, 0x20, 0, 0}, {0x54b2, 0x00, 0, 0}, {0x54b3, 0x10, 0, 0},
+ {0x54b4, 0x00, 0, 0}, {0x54b5, 0xf0, 0, 0}, {0x54b6, 0x00, 0, 0},
+ {0x54b7, 0xdf, 0, 0}, {0x5402, 0x3f, 0, 0}, {0x5403, 0x00, 0, 0},
+ {0x3406, 0x00, 0, 0}, {0x5180, 0xff, 0, 0}, {0x5181, 0x52, 0, 0},
+ {0x5182, 0x11, 0, 0}, {0x5183, 0x14, 0, 0}, {0x5184, 0x25, 0, 0},
+ {0x5185, 0x24, 0, 0}, {0x5186, 0x06, 0, 0}, {0x5187, 0x08, 0, 0},
+ {0x5188, 0x08, 0, 0}, {0x5189, 0x7c, 0, 0}, {0x518a, 0x60, 0, 0},
+ {0x518b, 0xb2, 0, 0}, {0x518c, 0xb2, 0, 0}, {0x518d, 0x44, 0, 0},
+ {0x518e, 0x3d, 0, 0}, {0x518f, 0x58, 0, 0}, {0x5190, 0x46, 0, 0},
+ {0x5191, 0xf8, 0, 0}, {0x5192, 0x04, 0, 0}, {0x5193, 0x70, 0, 0},
+ {0x5194, 0xf0, 0, 0}, {0x5195, 0xf0, 0, 0}, {0x5196, 0x03, 0, 0},
+ {0x5197, 0x01, 0, 0}, {0x5198, 0x04, 0, 0}, {0x5199, 0x12, 0, 0},
+ {0x519a, 0x04, 0, 0}, {0x519b, 0x00, 0, 0}, {0x519c, 0x06, 0, 0},
+ {0x519d, 0x82, 0, 0}, {0x519e, 0x00, 0, 0}, {0x5025, 0x80, 0, 0},
+ {0x3a0f, 0x38, 0, 0}, {0x3a10, 0x30, 0, 0}, {0x3a1b, 0x3a, 0, 0},
+ {0x3a1e, 0x2e, 0, 0}, {0x3a11, 0x60, 0, 0}, {0x3a1f, 0x10, 0, 0},
+ {0x5688, 0xa6, 0, 0}, {0x5689, 0x6a, 0, 0}, {0x568a, 0xea, 0, 0},
+ {0x568b, 0xae, 0, 0}, {0x568c, 0xa6, 0, 0}, {0x568d, 0x6a, 0, 0},
+ {0x568e, 0x62, 0, 0}, {0x568f, 0x26, 0, 0}, {0x5583, 0x40, 0, 0},
+ {0x5584, 0x40, 0, 0}, {0x5580, 0x02, 0, 0}, {0x5000, 0xcf, 0, 0},
+ {0x5800, 0x27, 0, 0}, {0x5801, 0x19, 0, 0}, {0x5802, 0x12, 0, 0},
+ {0x5803, 0x0f, 0, 0}, {0x5804, 0x10, 0, 0}, {0x5805, 0x15, 0, 0},
+ {0x5806, 0x1e, 0, 0}, {0x5807, 0x2f, 0, 0}, {0x5808, 0x15, 0, 0},
+ {0x5809, 0x0d, 0, 0}, {0x580a, 0x0a, 0, 0}, {0x580b, 0x09, 0, 0},
+ {0x580c, 0x0a, 0, 0}, {0x580d, 0x0c, 0, 0}, {0x580e, 0x12, 0, 0},
+ {0x580f, 0x19, 0, 0}, {0x5810, 0x0b, 0, 0}, {0x5811, 0x07, 0, 0},
+ {0x5812, 0x04, 0, 0}, {0x5813, 0x03, 0, 0}, {0x5814, 0x03, 0, 0},
+ {0x5815, 0x06, 0, 0}, {0x5816, 0x0a, 0, 0}, {0x5817, 0x0f, 0, 0},
+ {0x5818, 0x0a, 0, 0}, {0x5819, 0x05, 0, 0}, {0x581a, 0x01, 0, 0},
+ {0x581b, 0x00, 0, 0}, {0x581c, 0x00, 0, 0}, {0x581d, 0x03, 0, 0},
+ {0x581e, 0x08, 0, 0}, {0x581f, 0x0c, 0, 0}, {0x5820, 0x0a, 0, 0},
+ {0x5821, 0x05, 0, 0}, {0x5822, 0x01, 0, 0}, {0x5823, 0x00, 0, 0},
+ {0x5824, 0x00, 0, 0}, {0x5825, 0x03, 0, 0}, {0x5826, 0x08, 0, 0},
+ {0x5827, 0x0c, 0, 0}, {0x5828, 0x0e, 0, 0}, {0x5829, 0x08, 0, 0},
+ {0x582a, 0x06, 0, 0}, {0x582b, 0x04, 0, 0}, {0x582c, 0x05, 0, 0},
+ {0x582d, 0x07, 0, 0}, {0x582e, 0x0b, 0, 0}, {0x582f, 0x12, 0, 0},
+ {0x5830, 0x18, 0, 0}, {0x5831, 0x10, 0, 0}, {0x5832, 0x0c, 0, 0},
+ {0x5833, 0x0a, 0, 0}, {0x5834, 0x0b, 0, 0}, {0x5835, 0x0e, 0, 0},
+ {0x5836, 0x15, 0, 0}, {0x5837, 0x19, 0, 0}, {0x5838, 0x32, 0, 0},
+ {0x5839, 0x1f, 0, 0}, {0x583a, 0x18, 0, 0}, {0x583b, 0x16, 0, 0},
+ {0x583c, 0x17, 0, 0}, {0x583d, 0x1e, 0, 0}, {0x583e, 0x26, 0, 0},
+ {0x583f, 0x53, 0, 0}, {0x5840, 0x10, 0, 0}, {0x5841, 0x0f, 0, 0},
+ {0x5842, 0x0d, 0, 0}, {0x5843, 0x0c, 0, 0}, {0x5844, 0x0e, 0, 0},
+ {0x5845, 0x09, 0, 0}, {0x5846, 0x11, 0, 0}, {0x5847, 0x10, 0, 0},
+ {0x5848, 0x10, 0, 0}, {0x5849, 0x10, 0, 0}, {0x584a, 0x10, 0, 0},
+ {0x584b, 0x0e, 0, 0}, {0x584c, 0x10, 0, 0}, {0x584d, 0x10, 0, 0},
+ {0x584e, 0x11, 0, 0}, {0x584f, 0x10, 0, 0}, {0x5850, 0x0f, 0, 0},
+ {0x5851, 0x0c, 0, 0}, {0x5852, 0x0f, 0, 0}, {0x5853, 0x10, 0, 0},
+ {0x5854, 0x10, 0, 0}, {0x5855, 0x0f, 0, 0}, {0x5856, 0x0e, 0, 0},
+ {0x5857, 0x0b, 0, 0}, {0x5858, 0x10, 0, 0}, {0x5859, 0x0d, 0, 0},
+ {0x585a, 0x0d, 0, 0}, {0x585b, 0x0c, 0, 0}, {0x585c, 0x0c, 0, 0},
+ {0x585d, 0x0c, 0, 0}, {0x585e, 0x0b, 0, 0}, {0x585f, 0x0c, 0, 0},
+ {0x5860, 0x0c, 0, 0}, {0x5861, 0x0c, 0, 0}, {0x5862, 0x0d, 0, 0},
+ {0x5863, 0x08, 0, 0}, {0x5864, 0x11, 0, 0}, {0x5865, 0x18, 0, 0},
+ {0x5866, 0x18, 0, 0}, {0x5867, 0x19, 0, 0}, {0x5868, 0x17, 0, 0},
+ {0x5869, 0x19, 0, 0}, {0x586a, 0x16, 0, 0}, {0x586b, 0x13, 0, 0},
+ {0x586c, 0x13, 0, 0}, {0x586d, 0x12, 0, 0}, {0x586e, 0x13, 0, 0},
+ {0x586f, 0x16, 0, 0}, {0x5870, 0x14, 0, 0}, {0x5871, 0x12, 0, 0},
+ {0x5872, 0x10, 0, 0}, {0x5873, 0x11, 0, 0}, {0x5874, 0x11, 0, 0},
+ {0x5875, 0x16, 0, 0}, {0x5876, 0x14, 0, 0}, {0x5877, 0x11, 0, 0},
+ {0x5878, 0x10, 0, 0}, {0x5879, 0x0f, 0, 0}, {0x587a, 0x10, 0, 0},
+ {0x587b, 0x14, 0, 0}, {0x587c, 0x13, 0, 0}, {0x587d, 0x12, 0, 0},
+ {0x587e, 0x11, 0, 0}, {0x587f, 0x11, 0, 0}, {0x5880, 0x12, 0, 0},
+ {0x5881, 0x15, 0, 0}, {0x5882, 0x14, 0, 0}, {0x5883, 0x15, 0, 0},
+ {0x5884, 0x15, 0, 0}, {0x5885, 0x15, 0, 0}, {0x5886, 0x13, 0, 0},
+ {0x5887, 0x17, 0, 0}, {0x3710, 0x10, 0, 0}, {0x3632, 0x51, 0, 0},
+ {0x3702, 0x10, 0, 0}, {0x3703, 0xb2, 0, 0}, {0x3704, 0x18, 0, 0},
+ {0x370b, 0x40, 0, 0}, {0x370d, 0x03, 0, 0}, {0x3631, 0x01, 0, 0},
+ {0x3632, 0x52, 0, 0}, {0x3606, 0x24, 0, 0}, {0x3620, 0x96, 0, 0},
+ {0x5785, 0x07, 0, 0}, {0x3a13, 0x30, 0, 0}, {0x3600, 0x52, 0, 0},
+ {0x3604, 0x48, 0, 0}, {0x3606, 0x1b, 0, 0}, {0x370d, 0x0b, 0, 0},
+ {0x370f, 0xc0, 0, 0}, {0x3709, 0x01, 0, 0}, {0x3823, 0x00, 0, 0},
+ {0x5007, 0x00, 0, 0}, {0x5009, 0x00, 0, 0}, {0x5011, 0x00, 0, 0},
+ {0x5013, 0x00, 0, 0}, {0x519e, 0x00, 0, 0}, {0x5086, 0x00, 0, 0},
+ {0x5087, 0x00, 0, 0}, {0x5088, 0x00, 0, 0}, {0x5089, 0x00, 0, 0},
+ {0x302b, 0x00, 0, 0}, {0x3503, 0x07, 0, 0}, {0x3011, 0x08, 0, 0},
+ {0x350c, 0x02, 0, 0}, {0x350d, 0xe4, 0, 0}, {0x3621, 0xc9, 0, 0},
+ {0x370a, 0x81, 0, 0}, {0x3803, 0x08, 0, 0}, {0x3804, 0x05, 0, 0},
+ {0x3805, 0x00, 0, 0}, {0x3806, 0x02, 0, 0}, {0x3807, 0xd0, 0, 0},
+ {0x3808, 0x05, 0, 0}, {0x3809, 0x00, 0, 0}, {0x380a, 0x02, 0, 0},
+ {0x380b, 0xd0, 0, 0}, {0x380c, 0x08, 0, 0}, {0x380d, 0x72, 0, 0},
+ {0x380e, 0x02, 0, 0}, {0x380f, 0xe4, 0, 0}, {0x3810, 0xc0, 0, 0},
+ {0x3818, 0xc9, 0, 0}, {0x381c, 0x10, 0, 0}, {0x381d, 0xa0, 0, 0},
+ {0x381e, 0x05, 0, 0}, {0x381f, 0xb0, 0, 0}, {0x3820, 0x00, 0, 0},
+ {0x3821, 0x00, 0, 0}, {0x3824, 0x11, 0, 0}, {0x3a08, 0x1b, 0, 0},
+ {0x3a09, 0xc0, 0, 0}, {0x3a0a, 0x17, 0, 0}, {0x3a0b, 0x20, 0, 0},
+ {0x3a0d, 0x02, 0, 0}, {0x3a0e, 0x01, 0, 0}, {0x401c, 0x04, 0, 0},
+ {0x5682, 0x05, 0, 0}, {0x5683, 0x00, 0, 0}, {0x5686, 0x02, 0, 0},
+ {0x5687, 0xcc, 0, 0}, {0x5001, 0x7f, 0, 0}, {0x589b, 0x06, 0, 0},
+ {0x589a, 0xc5, 0, 0}, {0x3503, 0x00, 0, 0}, {0x3010, 0x10, 0, 0},
+ {0x460c, 0x20, 0, 0}, {0x460b, 0x37, 0, 0}, {0x471c, 0xd0, 0, 0},
+ {0x471d, 0x05, 0, 0}, {0x3815, 0x01, 0, 0}, {0x3818, 0x00, 0x08, 0},
+ {0x501f, 0x00, 0, 0}, {0x4300, 0x30, 0, 0}, {0x3002, 0x1c, 0, 0},
+ {0x3819, 0x80, 0, 0}, {0x5002, 0xe0, 0, 0},
+};
+
+static struct reg_value ov5642_setting_15fps_1080P_1920_1080[] = {
+ {0x3103, 0x93, 0, 0}, {0x3008, 0x82, 0, 0}, {0x3017, 0x7f, 0, 0},
+ {0x3018, 0xfc, 0, 0}, {0x3810, 0xc2, 0, 0}, {0x3615, 0xf0, 0, 0},
+ {0x3000, 0x00, 0, 0}, {0x3001, 0x00, 0, 0}, {0x3002, 0x00, 0, 0},
+ {0x3003, 0x00, 0, 0}, {0x3004, 0xff, 0, 0}, {0x3030, 0x2b, 0, 0},
+ {0x3011, 0x08, 0, 0}, {0x3010, 0x10, 0, 0}, {0x3604, 0x60, 0, 0},
+ {0x3622, 0x60, 0, 0}, {0x3621, 0x09, 0, 0}, {0x3709, 0x00, 0, 0},
+ {0x4000, 0x21, 0, 0}, {0x401d, 0x22, 0, 0}, {0x3600, 0x54, 0, 0},
+ {0x3605, 0x04, 0, 0}, {0x3606, 0x3f, 0, 0}, {0x3c01, 0x80, 0, 0},
+ {0x300d, 0x22, 0, 0}, {0x3623, 0x22, 0, 0}, {0x5000, 0x4f, 0, 0},
+ {0x5020, 0x04, 0, 0}, {0x5181, 0x79, 0, 0}, {0x5182, 0x00, 0, 0},
+ {0x5185, 0x22, 0, 0}, {0x5197, 0x01, 0, 0}, {0x5500, 0x0a, 0, 0},
+ {0x5504, 0x00, 0, 0}, {0x5505, 0x7f, 0, 0}, {0x5080, 0x08, 0, 0},
+ {0x300e, 0x18, 0, 0}, {0x4610, 0x00, 0, 0}, {0x471d, 0x05, 0, 0},
+ {0x4708, 0x06, 0, 0}, {0x370c, 0xa0, 0, 0}, {0x3808, 0x0a, 0, 0},
+ {0x3809, 0x20, 0, 0}, {0x380a, 0x07, 0, 0}, {0x380b, 0x98, 0, 0},
+ {0x380c, 0x0c, 0, 0}, {0x380d, 0x80, 0, 0}, {0x380e, 0x07, 0, 0},
+ {0x380f, 0xd0, 0, 0}, {0x5687, 0x94, 0, 0}, {0x501f, 0x00, 0, 0},
+ {0x5000, 0x4f, 0, 0}, {0x5001, 0xcf, 0, 0}, {0x4300, 0x30, 0, 0},
+ {0x4300, 0x30, 0, 0}, {0x460b, 0x35, 0, 0}, {0x471d, 0x00, 0, 0},
+ {0x3002, 0x0c, 0, 0}, {0x3002, 0x00, 0, 0}, {0x4713, 0x03, 0, 0},
+ {0x471c, 0x50, 0, 0}, {0x4721, 0x02, 0, 0}, {0x4402, 0x90, 0, 0},
+ {0x460c, 0x22, 0, 0}, {0x3815, 0x44, 0, 0}, {0x3503, 0x07, 0, 0},
+ {0x3501, 0x73, 0, 0}, {0x3502, 0x80, 0, 0}, {0x350b, 0x00, 0, 0},
+ {0x3818, 0xc8, 0, 0}, {0x3801, 0x88, 0, 0}, {0x3824, 0x11, 0, 0},
+ {0x3a00, 0x78, 0, 0}, {0x3a1a, 0x04, 0, 0}, {0x3a13, 0x30, 0, 0},
+ {0x3a18, 0x00, 0, 0}, {0x3a19, 0x7c, 0, 0}, {0x3a08, 0x12, 0, 0},
+ {0x3a09, 0xc0, 0, 0}, {0x3a0a, 0x0f, 0, 0}, {0x3a0b, 0xa0, 0, 0},
+ {0x350c, 0x07, 0, 0}, {0x350d, 0xd0, 0, 0}, {0x3a0d, 0x08, 0, 0},
+ {0x3a0e, 0x06, 0, 0}, {0x3500, 0x00, 0, 0}, {0x3501, 0x00, 0, 0},
+ {0x3502, 0x00, 0, 0}, {0x350a, 0x00, 0, 0}, {0x350b, 0x00, 0, 0},
+ {0x3503, 0x00, 0, 0}, {0x3a0f, 0x3c, 0, 0}, {0x3a10, 0x32, 0, 0},
+ {0x3a1b, 0x3c, 0, 0}, {0x3a1e, 0x32, 0, 0}, {0x3a11, 0x80, 0, 0},
+ {0x3a1f, 0x20, 0, 0}, {0x3030, 0x2b, 0, 0}, {0x3a02, 0x00, 0, 0},
+ {0x3a03, 0x7d, 0, 0}, {0x3a04, 0x00, 0, 0}, {0x3a14, 0x00, 0, 0},
+ {0x3a15, 0x7d, 0, 0}, {0x3a16, 0x00, 0, 0}, {0x3a00, 0x78, 0, 0},
+ {0x3a08, 0x09, 0, 0}, {0x3a09, 0x60, 0, 0}, {0x3a0a, 0x07, 0, 0},
+ {0x3a0b, 0xd0, 0, 0}, {0x3a0d, 0x10, 0, 0}, {0x3a0e, 0x0d, 0, 0},
+ {0x4407, 0x04, 0, 0}, {0x5193, 0x70, 0, 0}, {0x589b, 0x00, 0, 0},
+ {0x589a, 0xc0, 0, 0}, {0x401e, 0x20, 0, 0}, {0x4001, 0x42, 0, 0},
+ {0x401c, 0x06, 0, 0}, {0x3825, 0xac, 0, 0}, {0x3827, 0x0c, 0, 0},
+ {0x528a, 0x01, 0, 0}, {0x528b, 0x04, 0, 0}, {0x528c, 0x08, 0, 0},
+ {0x528d, 0x10, 0, 0}, {0x528e, 0x20, 0, 0}, {0x528f, 0x28, 0, 0},
+ {0x5290, 0x30, 0, 0}, {0x5292, 0x00, 0, 0}, {0x5293, 0x01, 0, 0},
+ {0x5294, 0x00, 0, 0}, {0x5295, 0x04, 0, 0}, {0x5296, 0x00, 0, 0},
+ {0x5297, 0x08, 0, 0}, {0x5298, 0x00, 0, 0}, {0x5299, 0x10, 0, 0},
+ {0x529a, 0x00, 0, 0}, {0x529b, 0x20, 0, 0}, {0x529c, 0x00, 0, 0},
+ {0x529d, 0x28, 0, 0}, {0x529e, 0x00, 0, 0}, {0x529f, 0x30, 0, 0},
+ {0x5282, 0x00, 0, 0}, {0x5300, 0x00, 0, 0}, {0x5301, 0x20, 0, 0},
+ {0x5302, 0x00, 0, 0}, {0x5303, 0x7c, 0, 0}, {0x530c, 0x00, 0, 0},
+ {0x530d, 0x0c, 0, 0}, {0x530e, 0x20, 0, 0}, {0x530f, 0x80, 0, 0},
+ {0x5310, 0x20, 0, 0}, {0x5311, 0x80, 0, 0}, {0x5308, 0x20, 0, 0},
+ {0x5309, 0x40, 0, 0}, {0x5304, 0x00, 0, 0}, {0x5305, 0x30, 0, 0},
+ {0x5306, 0x00, 0, 0}, {0x5307, 0x80, 0, 0}, {0x5314, 0x08, 0, 0},
+ {0x5315, 0x20, 0, 0}, {0x5319, 0x30, 0, 0}, {0x5316, 0x10, 0, 0},
+ {0x5317, 0x00, 0, 0}, {0x5318, 0x02, 0, 0}, {0x5380, 0x01, 0, 0},
+ {0x5381, 0x00, 0, 0}, {0x5382, 0x00, 0, 0}, {0x5383, 0x4e, 0, 0},
+ {0x5384, 0x00, 0, 0}, {0x5385, 0x0f, 0, 0}, {0x5386, 0x00, 0, 0},
+ {0x5387, 0x00, 0, 0}, {0x5388, 0x01, 0, 0}, {0x5389, 0x15, 0, 0},
+ {0x538a, 0x00, 0, 0}, {0x538b, 0x31, 0, 0}, {0x538c, 0x00, 0, 0},
+ {0x538d, 0x00, 0, 0}, {0x538e, 0x00, 0, 0}, {0x538f, 0x0f, 0, 0},
+ {0x5390, 0x00, 0, 0}, {0x5391, 0xab, 0, 0}, {0x5392, 0x00, 0, 0},
+ {0x5393, 0xa2, 0, 0}, {0x5394, 0x08, 0, 0}, {0x5480, 0x14, 0, 0},
+ {0x5481, 0x21, 0, 0}, {0x5482, 0x36, 0, 0}, {0x5483, 0x57, 0, 0},
+ {0x5484, 0x65, 0, 0}, {0x5485, 0x71, 0, 0}, {0x5486, 0x7d, 0, 0},
+ {0x5487, 0x87, 0, 0}, {0x5488, 0x91, 0, 0}, {0x5489, 0x9a, 0, 0},
+ {0x548a, 0xaa, 0, 0}, {0x548b, 0xb8, 0, 0}, {0x548c, 0xcd, 0, 0},
+ {0x548d, 0xdd, 0, 0}, {0x548e, 0xea, 0, 0}, {0x548f, 0x1d, 0, 0},
+ {0x5490, 0x05, 0, 0}, {0x5491, 0x00, 0, 0}, {0x5492, 0x04, 0, 0},
+ {0x5493, 0x20, 0, 0}, {0x5494, 0x03, 0, 0}, {0x5495, 0x60, 0, 0},
+ {0x5496, 0x02, 0, 0}, {0x5497, 0xb8, 0, 0}, {0x5498, 0x02, 0, 0},
+ {0x5499, 0x86, 0, 0}, {0x549a, 0x02, 0, 0}, {0x549b, 0x5b, 0, 0},
+ {0x549c, 0x02, 0, 0}, {0x549d, 0x3b, 0, 0}, {0x549e, 0x02, 0, 0},
+ {0x549f, 0x1c, 0, 0}, {0x54a0, 0x02, 0, 0}, {0x54a1, 0x04, 0, 0},
+ {0x54a2, 0x01, 0, 0}, {0x54a3, 0xed, 0, 0}, {0x54a4, 0x01, 0, 0},
+ {0x54a5, 0xc5, 0, 0}, {0x54a6, 0x01, 0, 0}, {0x54a7, 0xa5, 0, 0},
+ {0x54a8, 0x01, 0, 0}, {0x54a9, 0x6c, 0, 0}, {0x54aa, 0x01, 0, 0},
+ {0x54ab, 0x41, 0, 0}, {0x54ac, 0x01, 0, 0}, {0x54ad, 0x20, 0, 0},
+ {0x54ae, 0x00, 0, 0}, {0x54af, 0x16, 0, 0}, {0x54b0, 0x01, 0, 0},
+ {0x54b1, 0x20, 0, 0}, {0x54b2, 0x00, 0, 0}, {0x54b3, 0x10, 0, 0},
+ {0x54b4, 0x00, 0, 0}, {0x54b5, 0xf0, 0, 0}, {0x54b6, 0x00, 0, 0},
+ {0x54b7, 0xdf, 0, 0}, {0x5402, 0x3f, 0, 0}, {0x5403, 0x00, 0, 0},
+ {0x3406, 0x00, 0, 0}, {0x5180, 0xff, 0, 0}, {0x5181, 0x52, 0, 0},
+ {0x5182, 0x11, 0, 0}, {0x5183, 0x14, 0, 0}, {0x5184, 0x25, 0, 0},
+ {0x5185, 0x24, 0, 0}, {0x5186, 0x06, 0, 0}, {0x5187, 0x08, 0, 0},
+ {0x5188, 0x08, 0, 0}, {0x5189, 0x7c, 0, 0}, {0x518a, 0x60, 0, 0},
+ {0x518b, 0xb2, 0, 0}, {0x518c, 0xb2, 0, 0}, {0x518d, 0x44, 0, 0},
+ {0x518e, 0x3d, 0, 0}, {0x518f, 0x58, 0, 0}, {0x5190, 0x46, 0, 0},
+ {0x5191, 0xf8, 0, 0}, {0x5192, 0x04, 0, 0}, {0x5193, 0x70, 0, 0},
+ {0x5194, 0xf0, 0, 0}, {0x5195, 0xf0, 0, 0}, {0x5196, 0x03, 0, 0},
+ {0x5197, 0x01, 0, 0}, {0x5198, 0x04, 0, 0}, {0x5199, 0x12, 0, 0},
+ {0x519a, 0x04, 0, 0}, {0x519b, 0x00, 0, 0}, {0x519c, 0x06, 0, 0},
+ {0x519d, 0x82, 0, 0}, {0x519e, 0x00, 0, 0}, {0x5025, 0x80, 0, 0},
+ {0x3a0f, 0x38, 0, 0}, {0x3a10, 0x30, 0, 0}, {0x3a1b, 0x3a, 0, 0},
+ {0x3a1e, 0x2e, 0, 0}, {0x3a11, 0x60, 0, 0}, {0x3a1f, 0x10, 0, 0},
+ {0x5688, 0xa6, 0, 0}, {0x5689, 0x6a, 0, 0}, {0x568a, 0xea, 0, 0},
+ {0x568b, 0xae, 0, 0}, {0x568c, 0xa6, 0, 0}, {0x568d, 0x6a, 0, 0},
+ {0x568e, 0x62, 0, 0}, {0x568f, 0x26, 0, 0}, {0x5583, 0x40, 0, 0},
+ {0x5584, 0x40, 0, 0}, {0x5580, 0x02, 0, 0}, {0x5000, 0xcf, 0, 0},
+ {0x5800, 0x27, 0, 0}, {0x5801, 0x19, 0, 0}, {0x5802, 0x12, 0, 0},
+ {0x5803, 0x0f, 0, 0}, {0x5804, 0x10, 0, 0}, {0x5805, 0x15, 0, 0},
+ {0x5806, 0x1e, 0, 0}, {0x5807, 0x2f, 0, 0}, {0x5808, 0x15, 0, 0},
+ {0x5809, 0x0d, 0, 0}, {0x580a, 0x0a, 0, 0}, {0x580b, 0x09, 0, 0},
+ {0x580c, 0x0a, 0, 0}, {0x580d, 0x0c, 0, 0}, {0x580e, 0x12, 0, 0},
+ {0x580f, 0x19, 0, 0}, {0x5810, 0x0b, 0, 0}, {0x5811, 0x07, 0, 0},
+ {0x5812, 0x04, 0, 0}, {0x5813, 0x03, 0, 0}, {0x5814, 0x03, 0, 0},
+ {0x5815, 0x06, 0, 0}, {0x5816, 0x0a, 0, 0}, {0x5817, 0x0f, 0, 0},
+ {0x5818, 0x0a, 0, 0}, {0x5819, 0x05, 0, 0}, {0x581a, 0x01, 0, 0},
+ {0x581b, 0x00, 0, 0}, {0x581c, 0x00, 0, 0}, {0x581d, 0x03, 0, 0},
+ {0x581e, 0x08, 0, 0}, {0x581f, 0x0c, 0, 0}, {0x5820, 0x0a, 0, 0},
+ {0x5821, 0x05, 0, 0}, {0x5822, 0x01, 0, 0}, {0x5823, 0x00, 0, 0},
+ {0x5824, 0x00, 0, 0}, {0x5825, 0x03, 0, 0}, {0x5826, 0x08, 0, 0},
+ {0x5827, 0x0c, 0, 0}, {0x5828, 0x0e, 0, 0}, {0x5829, 0x08, 0, 0},
+ {0x582a, 0x06, 0, 0}, {0x582b, 0x04, 0, 0}, {0x582c, 0x05, 0, 0},
+ {0x582d, 0x07, 0, 0}, {0x582e, 0x0b, 0, 0}, {0x582f, 0x12, 0, 0},
+ {0x5830, 0x18, 0, 0}, {0x5831, 0x10, 0, 0}, {0x5832, 0x0c, 0, 0},
+ {0x5833, 0x0a, 0, 0}, {0x5834, 0x0b, 0, 0}, {0x5835, 0x0e, 0, 0},
+ {0x5836, 0x15, 0, 0}, {0x5837, 0x19, 0, 0}, {0x5838, 0x32, 0, 0},
+ {0x5839, 0x1f, 0, 0}, {0x583a, 0x18, 0, 0}, {0x583b, 0x16, 0, 0},
+ {0x583c, 0x17, 0, 0}, {0x583d, 0x1e, 0, 0}, {0x583e, 0x26, 0, 0},
+ {0x583f, 0x53, 0, 0}, {0x5840, 0x10, 0, 0}, {0x5841, 0x0f, 0, 0},
+ {0x5842, 0x0d, 0, 0}, {0x5843, 0x0c, 0, 0}, {0x5844, 0x0e, 0, 0},
+ {0x5845, 0x09, 0, 0}, {0x5846, 0x11, 0, 0}, {0x5847, 0x10, 0, 0},
+ {0x5848, 0x10, 0, 0}, {0x5849, 0x10, 0, 0}, {0x584a, 0x10, 0, 0},
+ {0x584b, 0x0e, 0, 0}, {0x584c, 0x10, 0, 0}, {0x584d, 0x10, 0, 0},
+ {0x584e, 0x11, 0, 0}, {0x584f, 0x10, 0, 0}, {0x5850, 0x0f, 0, 0},
+ {0x5851, 0x0c, 0, 0}, {0x5852, 0x0f, 0, 0}, {0x5853, 0x10, 0, 0},
+ {0x5854, 0x10, 0, 0}, {0x5855, 0x0f, 0, 0}, {0x5856, 0x0e, 0, 0},
+ {0x5857, 0x0b, 0, 0}, {0x5858, 0x10, 0, 0}, {0x5859, 0x0d, 0, 0},
+ {0x585a, 0x0d, 0, 0}, {0x585b, 0x0c, 0, 0}, {0x585c, 0x0c, 0, 0},
+ {0x585d, 0x0c, 0, 0}, {0x585e, 0x0b, 0, 0}, {0x585f, 0x0c, 0, 0},
+ {0x5860, 0x0c, 0, 0}, {0x5861, 0x0c, 0, 0}, {0x5862, 0x0d, 0, 0},
+ {0x5863, 0x08, 0, 0}, {0x5864, 0x11, 0, 0}, {0x5865, 0x18, 0, 0},
+ {0x5866, 0x18, 0, 0}, {0x5867, 0x19, 0, 0}, {0x5868, 0x17, 0, 0},
+ {0x5869, 0x19, 0, 0}, {0x586a, 0x16, 0, 0}, {0x586b, 0x13, 0, 0},
+ {0x586c, 0x13, 0, 0}, {0x586d, 0x12, 0, 0}, {0x586e, 0x13, 0, 0},
+ {0x586f, 0x16, 0, 0}, {0x5870, 0x14, 0, 0}, {0x5871, 0x12, 0, 0},
+ {0x5872, 0x10, 0, 0}, {0x5873, 0x11, 0, 0}, {0x5874, 0x11, 0, 0},
+ {0x5875, 0x16, 0, 0}, {0x5876, 0x14, 0, 0}, {0x5877, 0x11, 0, 0},
+ {0x5878, 0x10, 0, 0}, {0x5879, 0x0f, 0, 0}, {0x587a, 0x10, 0, 0},
+ {0x587b, 0x14, 0, 0}, {0x587c, 0x13, 0, 0}, {0x587d, 0x12, 0, 0},
+ {0x587e, 0x11, 0, 0}, {0x587f, 0x11, 0, 0}, {0x5880, 0x12, 0, 0},
+ {0x5881, 0x15, 0, 0}, {0x5882, 0x14, 0, 0}, {0x5883, 0x15, 0, 0},
+ {0x5884, 0x15, 0, 0}, {0x5885, 0x15, 0, 0}, {0x5886, 0x13, 0, 0},
+ {0x5887, 0x17, 0, 0}, {0x3710, 0x10, 0, 0}, {0x3632, 0x51, 0, 0},
+ {0x3702, 0x10, 0, 0}, {0x3703, 0xb2, 0, 0}, {0x3704, 0x18, 0, 0},
+ {0x370b, 0x40, 0, 0}, {0x370d, 0x03, 0, 0}, {0x3631, 0x01, 0, 0},
+ {0x3632, 0x52, 0, 0}, {0x3606, 0x24, 0, 0}, {0x3620, 0x96, 0, 0},
+ {0x5785, 0x07, 0, 0}, {0x3a13, 0x30, 0, 0}, {0x3600, 0x52, 0, 0},
+ {0x3604, 0x48, 0, 0}, {0x3606, 0x1b, 0, 0}, {0x370d, 0x0b, 0, 0},
+ {0x370f, 0xc0, 0, 0}, {0x3709, 0x01, 0, 0}, {0x3823, 0x00, 0, 0},
+ {0x5007, 0x00, 0, 0}, {0x5009, 0x00, 0, 0}, {0x5011, 0x00, 0, 0},
+ {0x5013, 0x00, 0, 0}, {0x519e, 0x00, 0, 0}, {0x5086, 0x00, 0, 0},
+ {0x5087, 0x00, 0, 0}, {0x5088, 0x00, 0, 0}, {0x5089, 0x00, 0, 0},
+ {0x302b, 0x00, 0, 0}, {0x3503, 0x07, 0, 0}, {0x3011, 0x07, 0, 0},
+ {0x350c, 0x04, 0, 0}, {0x350d, 0x58, 0, 0}, {0x3801, 0x8a, 0, 0},
+ {0x3803, 0x0a, 0, 0}, {0x3804, 0x07, 0, 0}, {0x3805, 0x80, 0, 0},
+ {0x3806, 0x04, 0, 0}, {0x3807, 0x39, 0, 0}, {0x3808, 0x07, 0, 0},
+ {0x3809, 0x80, 0, 0}, {0x380a, 0x04, 0, 0}, {0x380b, 0x38, 0, 0},
+ {0x380c, 0x09, 0, 0}, {0x380d, 0xd6, 0, 0}, {0x380e, 0x04, 0, 0},
+ {0x380f, 0x58, 0, 0}, {0x381c, 0x11, 0, 0}, {0x381d, 0xba, 0, 0},
+ {0x381e, 0x04, 0, 0}, {0x381f, 0x48, 0, 0}, {0x3820, 0x04, 0, 0},
+ {0x3821, 0x18, 0, 0}, {0x3a08, 0x14, 0, 0}, {0x3a09, 0xe0, 0, 0},
+ {0x3a0a, 0x11, 0, 0}, {0x3a0b, 0x60, 0, 0}, {0x3a0d, 0x04, 0, 0},
+ {0x3a0e, 0x03, 0, 0}, {0x5682, 0x07, 0, 0}, {0x5683, 0x60, 0, 0},
+ {0x5686, 0x04, 0, 0}, {0x5687, 0x1c, 0, 0}, {0x5001, 0x7f, 0, 0},
+ {0x3503, 0x00, 0, 0}, {0x3010, 0x10, 0, 0}, {0x460c, 0x20, 0, 0},
+ {0x460b, 0x37, 0, 0}, {0x471c, 0xd0, 0, 0}, {0x471d, 0x05, 0, 0},
+ {0x3815, 0x01, 0, 0}, {0x3818, 0x00, 0x08, 0}, {0x501f, 0x00, 0, 0},
+ {0x4300, 0x30, 0, 0}, {0x3002, 0x1c, 0, 0}, {0x3819, 0x80, 0, 0},
+ {0x5002, 0xe0, 0, 0},
+};
+
+static struct reg_value ov5642_setting_15fps_QVGA_320_240[] = {
+ {0x3103, 0x93, 0, 0}, {0x3008, 0x82, 0, 0}, {0x3017, 0x7f, 0, 0},
+ {0x3018, 0xfc, 0, 0}, {0x3810, 0xc2, 0, 0}, {0x3615, 0xf0, 0, 0},
+ {0x3000, 0x00, 0, 0}, {0x3001, 0x00, 0, 0}, {0x3002, 0x5c, 0, 0},
+ {0x3003, 0x00, 0, 0}, {0x3004, 0xff, 0, 0}, {0x3005, 0xff, 0, 0},
+ {0x3006, 0x43, 0, 0}, {0x3007, 0x37, 0, 0}, {0x3011, 0x08, 0, 0},
+ {0x3010, 0x10, 0, 0}, {0x460c, 0x22, 0, 0}, {0x3815, 0x04, 0, 0},
+ {0x370c, 0xa0, 0, 0}, {0x3602, 0xfc, 0, 0}, {0x3612, 0xff, 0, 0},
+ {0x3634, 0xc0, 0, 0}, {0x3613, 0x00, 0, 0}, {0x3605, 0x7c, 0, 0},
+ {0x3621, 0x09, 0, 0}, {0x3622, 0x60, 0, 0}, {0x3604, 0x40, 0, 0},
+ {0x3603, 0xa7, 0, 0}, {0x3603, 0x27, 0, 0}, {0x4000, 0x21, 0, 0},
+ {0x401d, 0x22, 0, 0}, {0x3600, 0x54, 0, 0}, {0x3605, 0x04, 0, 0},
+ {0x3606, 0x3f, 0, 0}, {0x3c01, 0x80, 0, 0}, {0x5000, 0x4f, 0, 0},
+ {0x5020, 0x04, 0, 0}, {0x5181, 0x79, 0, 0}, {0x5182, 0x00, 0, 0},
+ {0x5185, 0x22, 0, 0}, {0x5197, 0x01, 0, 0}, {0x5001, 0xff, 0, 0},
+ {0x5500, 0x0a, 0, 0}, {0x5504, 0x00, 0, 0}, {0x5505, 0x7f, 0, 0},
+ {0x5080, 0x08, 0, 0}, {0x300e, 0x18, 0, 0}, {0x4610, 0x00, 0, 0},
+ {0x471d, 0x05, 0, 0}, {0x4708, 0x06, 0, 0}, {0x3808, 0x02, 0, 0},
+ {0x3809, 0x80, 0, 0}, {0x380a, 0x01, 0, 0}, {0x380b, 0xe0, 0, 0},
+ {0x380e, 0x07, 0, 0}, {0x380f, 0xd0, 0, 0}, {0x501f, 0x00, 0, 0},
+ {0x5000, 0x4f, 0, 0}, {0x4300, 0x30, 0, 0}, {0x3503, 0x07, 0, 0},
+ {0x3501, 0x73, 0, 0}, {0x3502, 0x80, 0, 0}, {0x350b, 0x00, 0, 0},
+ {0x3503, 0x07, 0, 0}, {0x3824, 0x11, 0, 0}, {0x3501, 0x1e, 0, 0},
+ {0x3502, 0x80, 0, 0}, {0x350b, 0x7f, 0, 0}, {0x380c, 0x0c, 0, 0},
+ {0x380d, 0x80, 0, 0}, {0x380e, 0x03, 0, 0}, {0x380f, 0xe8, 0, 0},
+ {0x3a0d, 0x04, 0, 0}, {0x3a0e, 0x03, 0, 0}, {0x3818, 0xc1, 0, 0},
+ {0x3705, 0xdb, 0, 0}, {0x370a, 0x81, 0, 0}, {0x3801, 0x80, 0, 0},
+ {0x3621, 0x87, 0, 0}, {0x3801, 0x50, 0, 0}, {0x3803, 0x08, 0, 0},
+ {0x3827, 0x08, 0, 0}, {0x3810, 0x40, 0, 0}, {0x3804, 0x05, 0, 0},
+ {0x3805, 0x00, 0, 0}, {0x5682, 0x05, 0, 0}, {0x5683, 0x00, 0, 0},
+ {0x3806, 0x03, 0, 0}, {0x3807, 0xc0, 0, 0}, {0x5686, 0x03, 0, 0},
+ {0x5687, 0xbc, 0, 0}, {0x3a00, 0x78, 0, 0}, {0x3a1a, 0x05, 0, 0},
+ {0x3a13, 0x30, 0, 0}, {0x3a18, 0x00, 0, 0}, {0x3a19, 0x7c, 0, 0},
+ {0x3a08, 0x12, 0, 0}, {0x3a09, 0xc0, 0, 0}, {0x3a0a, 0x0f, 0, 0},
+ {0x3a0b, 0xa0, 0, 0}, {0x350c, 0x07, 0, 0}, {0x350d, 0xd0, 0, 0},
+ {0x3500, 0x00, 0, 0}, {0x3501, 0x00, 0, 0}, {0x3502, 0x00, 0, 0},
+ {0x350a, 0x00, 0, 0}, {0x350b, 0x00, 0, 0}, {0x3503, 0x00, 0, 0},
+ {0x528a, 0x02, 0, 0}, {0x528b, 0x04, 0, 0}, {0x528c, 0x08, 0, 0},
+ {0x528d, 0x08, 0, 0}, {0x528e, 0x08, 0, 0}, {0x528f, 0x10, 0, 0},
+ {0x5290, 0x10, 0, 0}, {0x5292, 0x00, 0, 0}, {0x5293, 0x02, 0, 0},
+ {0x5294, 0x00, 0, 0}, {0x5295, 0x02, 0, 0}, {0x5296, 0x00, 0, 0},
+ {0x5297, 0x02, 0, 0}, {0x5298, 0x00, 0, 0}, {0x5299, 0x02, 0, 0},
+ {0x529a, 0x00, 0, 0}, {0x529b, 0x02, 0, 0}, {0x529c, 0x00, 0, 0},
+ {0x529d, 0x02, 0, 0}, {0x529e, 0x00, 0, 0}, {0x529f, 0x02, 0, 0},
+ {0x3a0f, 0x3c, 0, 0}, {0x3a10, 0x30, 0, 0}, {0x3a1b, 0x3c, 0, 0},
+ {0x3a1e, 0x30, 0, 0}, {0x3a11, 0x70, 0, 0}, {0x3a1f, 0x10, 0, 0},
+ {0x3030, 0x2b, 0, 0}, {0x3a02, 0x00, 0, 0}, {0x3a03, 0x7d, 0, 0},
+ {0x3a04, 0x00, 0, 0}, {0x3a14, 0x00, 0, 0}, {0x3a15, 0x7d, 0, 0},
+ {0x3a16, 0x00, 0, 0}, {0x3a00, 0x78, 0, 0}, {0x3a08, 0x09, 0, 0},
+ {0x3a09, 0x60, 0, 0}, {0x3a0a, 0x07, 0, 0}, {0x3a0b, 0xd0, 0, 0},
+ {0x3a0d, 0x08, 0, 0}, {0x3a0e, 0x06, 0, 0}, {0x5193, 0x70, 0, 0},
+ {0x589b, 0x04, 0, 0}, {0x589a, 0xc5, 0, 0}, {0x401e, 0x20, 0, 0},
+ {0x4001, 0x42, 0, 0}, {0x401c, 0x04, 0, 0}, {0x528a, 0x01, 0, 0},
+ {0x528b, 0x04, 0, 0}, {0x528c, 0x08, 0, 0}, {0x528d, 0x10, 0, 0},
+ {0x528e, 0x20, 0, 0}, {0x528f, 0x28, 0, 0}, {0x5290, 0x30, 0, 0},
+ {0x5292, 0x00, 0, 0}, {0x5293, 0x01, 0, 0}, {0x5294, 0x00, 0, 0},
+ {0x5295, 0x04, 0, 0}, {0x5296, 0x00, 0, 0}, {0x5297, 0x08, 0, 0},
+ {0x5298, 0x00, 0, 0}, {0x5299, 0x10, 0, 0}, {0x529a, 0x00, 0, 0},
+ {0x529b, 0x20, 0, 0}, {0x529c, 0x00, 0, 0}, {0x529d, 0x28, 0, 0},
+ {0x529e, 0x00, 0, 0}, {0x529f, 0x30, 0, 0}, {0x5282, 0x00, 0, 0},
+ {0x5300, 0x00, 0, 0}, {0x5301, 0x20, 0, 0}, {0x5302, 0x00, 0, 0},
+ {0x5303, 0x7c, 0, 0}, {0x530c, 0x00, 0, 0}, {0x530d, 0x0c, 0, 0},
+ {0x530e, 0x20, 0, 0}, {0x530f, 0x80, 0, 0}, {0x5310, 0x20, 0, 0},
+ {0x5311, 0x80, 0, 0}, {0x5308, 0x20, 0, 0}, {0x5309, 0x40, 0, 0},
+ {0x5304, 0x00, 0, 0}, {0x5305, 0x30, 0, 0}, {0x5306, 0x00, 0, 0},
+ {0x5307, 0x80, 0, 0}, {0x5314, 0x08, 0, 0}, {0x5315, 0x20, 0, 0},
+ {0x5319, 0x30, 0, 0}, {0x5316, 0x10, 0, 0}, {0x5317, 0x00, 0, 0},
+ {0x5318, 0x02, 0, 0}, {0x5380, 0x01, 0, 0}, {0x5381, 0x00, 0, 0},
+ {0x5382, 0x00, 0, 0}, {0x5383, 0x4e, 0, 0}, {0x5384, 0x00, 0, 0},
+ {0x5385, 0x0f, 0, 0}, {0x5386, 0x00, 0, 0}, {0x5387, 0x00, 0, 0},
+ {0x5388, 0x01, 0, 0}, {0x5389, 0x15, 0, 0}, {0x538a, 0x00, 0, 0},
+ {0x538b, 0x31, 0, 0}, {0x538c, 0x00, 0, 0}, {0x538d, 0x00, 0, 0},
+ {0x538e, 0x00, 0, 0}, {0x538f, 0x0f, 0, 0}, {0x5390, 0x00, 0, 0},
+ {0x5391, 0xab, 0, 0}, {0x5392, 0x00, 0, 0}, {0x5393, 0xa2, 0, 0},
+ {0x5394, 0x08, 0, 0}, {0x5480, 0x14, 0, 0}, {0x5481, 0x21, 0, 0},
+ {0x5482, 0x36, 0, 0}, {0x5483, 0x57, 0, 0}, {0x5484, 0x65, 0, 0},
+ {0x5485, 0x71, 0, 0}, {0x5486, 0x7d, 0, 0}, {0x5487, 0x87, 0, 0},
+ {0x5488, 0x91, 0, 0}, {0x5489, 0x9a, 0, 0}, {0x548a, 0xaa, 0, 0},
+ {0x548b, 0xb8, 0, 0}, {0x548c, 0xcd, 0, 0}, {0x548d, 0xdd, 0, 0},
+ {0x548e, 0xea, 0, 0}, {0x548f, 0x1d, 0, 0}, {0x5490, 0x05, 0, 0},
+ {0x5491, 0x00, 0, 0}, {0x5492, 0x04, 0, 0}, {0x5493, 0x20, 0, 0},
+ {0x5494, 0x03, 0, 0}, {0x5495, 0x60, 0, 0}, {0x5496, 0x02, 0, 0},
+ {0x5497, 0xb8, 0, 0}, {0x5498, 0x02, 0, 0}, {0x5499, 0x86, 0, 0},
+ {0x549a, 0x02, 0, 0}, {0x549b, 0x5b, 0, 0}, {0x549c, 0x02, 0, 0},
+ {0x549d, 0x3b, 0, 0}, {0x549e, 0x02, 0, 0}, {0x549f, 0x1c, 0, 0},
+ {0x54a0, 0x02, 0, 0}, {0x54a1, 0x04, 0, 0}, {0x54a2, 0x01, 0, 0},
+ {0x54a3, 0xed, 0, 0}, {0x54a4, 0x01, 0, 0}, {0x54a5, 0xc5, 0, 0},
+ {0x54a6, 0x01, 0, 0}, {0x54a7, 0xa5, 0, 0}, {0x54a8, 0x01, 0, 0},
+ {0x54a9, 0x6c, 0, 0}, {0x54aa, 0x01, 0, 0}, {0x54ab, 0x41, 0, 0},
+ {0x54ac, 0x01, 0, 0}, {0x54ad, 0x20, 0, 0}, {0x54ae, 0x00, 0, 0},
+ {0x54af, 0x16, 0, 0}, {0x54b0, 0x01, 0, 0}, {0x54b1, 0x20, 0, 0},
+ {0x54b2, 0x00, 0, 0}, {0x54b3, 0x10, 0, 0}, {0x54b4, 0x00, 0, 0},
+ {0x54b5, 0xf0, 0, 0}, {0x54b6, 0x00, 0, 0}, {0x54b7, 0xdf, 0, 0},
+ {0x5402, 0x3f, 0, 0}, {0x5403, 0x00, 0, 0}, {0x3406, 0x00, 0, 0},
+ {0x5180, 0xff, 0, 0}, {0x5181, 0x52, 0, 0}, {0x5182, 0x11, 0, 0},
+ {0x5183, 0x14, 0, 0}, {0x5184, 0x25, 0, 0}, {0x5185, 0x24, 0, 0},
+ {0x5186, 0x06, 0, 0}, {0x5187, 0x08, 0, 0}, {0x5188, 0x08, 0, 0},
+ {0x5189, 0x7c, 0, 0}, {0x518a, 0x60, 0, 0}, {0x518b, 0xb2, 0, 0},
+ {0x518c, 0xb2, 0, 0}, {0x518d, 0x44, 0, 0}, {0x518e, 0x3d, 0, 0},
+ {0x518f, 0x58, 0, 0}, {0x5190, 0x46, 0, 0}, {0x5191, 0xf8, 0, 0},
+ {0x5192, 0x04, 0, 0}, {0x5193, 0x70, 0, 0}, {0x5194, 0xf0, 0, 0},
+ {0x5195, 0xf0, 0, 0}, {0x5196, 0x03, 0, 0}, {0x5197, 0x01, 0, 0},
+ {0x5198, 0x04, 0, 0}, {0x5199, 0x12, 0, 0}, {0x519a, 0x04, 0, 0},
+ {0x519b, 0x00, 0, 0}, {0x519c, 0x06, 0, 0}, {0x519d, 0x82, 0, 0},
+ {0x519e, 0x00, 0, 0}, {0x5025, 0x80, 0, 0}, {0x3a0f, 0x38, 0, 0},
+ {0x3a10, 0x30, 0, 0}, {0x3a1b, 0x3a, 0, 0}, {0x3a1e, 0x2e, 0, 0},
+ {0x3a11, 0x60, 0, 0}, {0x3a1f, 0x10, 0, 0}, {0x5688, 0xa6, 0, 0},
+ {0x5689, 0x6a, 0, 0}, {0x568a, 0xea, 0, 0}, {0x568b, 0xae, 0, 0},
+ {0x568c, 0xa6, 0, 0}, {0x568d, 0x6a, 0, 0}, {0x568e, 0x62, 0, 0},
+ {0x568f, 0x26, 0, 0}, {0x5583, 0x40, 0, 0}, {0x5584, 0x40, 0, 0},
+ {0x5580, 0x02, 0, 0}, {0x5000, 0xcf, 0, 0}, {0x5800, 0x27, 0, 0},
+ {0x5801, 0x19, 0, 0}, {0x5802, 0x12, 0, 0}, {0x5803, 0x0f, 0, 0},
+ {0x5804, 0x10, 0, 0}, {0x5805, 0x15, 0, 0}, {0x5806, 0x1e, 0, 0},
+ {0x5807, 0x2f, 0, 0}, {0x5808, 0x15, 0, 0}, {0x5809, 0x0d, 0, 0},
+ {0x580a, 0x0a, 0, 0}, {0x580b, 0x09, 0, 0}, {0x580c, 0x0a, 0, 0},
+ {0x580d, 0x0c, 0, 0}, {0x580e, 0x12, 0, 0}, {0x580f, 0x19, 0, 0},
+ {0x5810, 0x0b, 0, 0}, {0x5811, 0x07, 0, 0}, {0x5812, 0x04, 0, 0},
+ {0x5813, 0x03, 0, 0}, {0x5814, 0x03, 0, 0}, {0x5815, 0x06, 0, 0},
+ {0x5816, 0x0a, 0, 0}, {0x5817, 0x0f, 0, 0}, {0x5818, 0x0a, 0, 0},
+ {0x5819, 0x05, 0, 0}, {0x581a, 0x01, 0, 0}, {0x581b, 0x00, 0, 0},
+ {0x581c, 0x00, 0, 0}, {0x581d, 0x03, 0, 0}, {0x581e, 0x08, 0, 0},
+ {0x581f, 0x0c, 0, 0}, {0x5820, 0x0a, 0, 0}, {0x5821, 0x05, 0, 0},
+ {0x5822, 0x01, 0, 0}, {0x5823, 0x00, 0, 0}, {0x5824, 0x00, 0, 0},
+ {0x5825, 0x03, 0, 0}, {0x5826, 0x08, 0, 0}, {0x5827, 0x0c, 0, 0},
+ {0x5828, 0x0e, 0, 0}, {0x5829, 0x08, 0, 0}, {0x582a, 0x06, 0, 0},
+ {0x582b, 0x04, 0, 0}, {0x582c, 0x05, 0, 0}, {0x582d, 0x07, 0, 0},
+ {0x582e, 0x0b, 0, 0}, {0x582f, 0x12, 0, 0}, {0x5830, 0x18, 0, 0},
+ {0x5831, 0x10, 0, 0}, {0x5832, 0x0c, 0, 0}, {0x5833, 0x0a, 0, 0},
+ {0x5834, 0x0b, 0, 0}, {0x5835, 0x0e, 0, 0}, {0x5836, 0x15, 0, 0},
+ {0x5837, 0x19, 0, 0}, {0x5838, 0x32, 0, 0}, {0x5839, 0x1f, 0, 0},
+ {0x583a, 0x18, 0, 0}, {0x583b, 0x16, 0, 0}, {0x583c, 0x17, 0, 0},
+ {0x583d, 0x1e, 0, 0}, {0x583e, 0x26, 0, 0}, {0x583f, 0x53, 0, 0},
+ {0x5840, 0x10, 0, 0}, {0x5841, 0x0f, 0, 0}, {0x5842, 0x0d, 0, 0},
+ {0x5843, 0x0c, 0, 0}, {0x5844, 0x0e, 0, 0}, {0x5845, 0x09, 0, 0},
+ {0x5846, 0x11, 0, 0}, {0x5847, 0x10, 0, 0}, {0x5848, 0x10, 0, 0},
+ {0x5849, 0x10, 0, 0}, {0x584a, 0x10, 0, 0}, {0x584b, 0x0e, 0, 0},
+ {0x584c, 0x10, 0, 0}, {0x584d, 0x10, 0, 0}, {0x584e, 0x11, 0, 0},
+ {0x584f, 0x10, 0, 0}, {0x5850, 0x0f, 0, 0}, {0x5851, 0x0c, 0, 0},
+ {0x5852, 0x0f, 0, 0}, {0x5853, 0x10, 0, 0}, {0x5854, 0x10, 0, 0},
+ {0x5855, 0x0f, 0, 0}, {0x5856, 0x0e, 0, 0}, {0x5857, 0x0b, 0, 0},
+ {0x5858, 0x10, 0, 0}, {0x5859, 0x0d, 0, 0}, {0x585a, 0x0d, 0, 0},
+ {0x585b, 0x0c, 0, 0}, {0x585c, 0x0c, 0, 0}, {0x585d, 0x0c, 0, 0},
+ {0x585e, 0x0b, 0, 0}, {0x585f, 0x0c, 0, 0}, {0x5860, 0x0c, 0, 0},
+ {0x5861, 0x0c, 0, 0}, {0x5862, 0x0d, 0, 0}, {0x5863, 0x08, 0, 0},
+ {0x5864, 0x11, 0, 0}, {0x5865, 0x18, 0, 0}, {0x5866, 0x18, 0, 0},
+ {0x5867, 0x19, 0, 0}, {0x5868, 0x17, 0, 0}, {0x5869, 0x19, 0, 0},
+ {0x586a, 0x16, 0, 0}, {0x586b, 0x13, 0, 0}, {0x586c, 0x13, 0, 0},
+ {0x586d, 0x12, 0, 0}, {0x586e, 0x13, 0, 0}, {0x586f, 0x16, 0, 0},
+ {0x5870, 0x14, 0, 0}, {0x5871, 0x12, 0, 0}, {0x5872, 0x10, 0, 0},
+ {0x5873, 0x11, 0, 0}, {0x5874, 0x11, 0, 0}, {0x5875, 0x16, 0, 0},
+ {0x5876, 0x14, 0, 0}, {0x5877, 0x11, 0, 0}, {0x5878, 0x10, 0, 0},
+ {0x5879, 0x0f, 0, 0}, {0x587a, 0x10, 0, 0}, {0x587b, 0x14, 0, 0},
+ {0x587c, 0x13, 0, 0}, {0x587d, 0x12, 0, 0}, {0x587e, 0x11, 0, 0},
+ {0x587f, 0x11, 0, 0}, {0x5880, 0x12, 0, 0}, {0x5881, 0x15, 0, 0},
+ {0x5882, 0x14, 0, 0}, {0x5883, 0x15, 0, 0}, {0x5884, 0x15, 0, 0},
+ {0x5885, 0x15, 0, 0}, {0x5886, 0x13, 0, 0}, {0x5887, 0x17, 0, 0},
+ {0x3710, 0x10, 0, 0}, {0x3632, 0x51, 0, 0}, {0x3702, 0x10, 0, 0},
+ {0x3703, 0xb2, 0, 0}, {0x3704, 0x18, 0, 0}, {0x370b, 0x40, 0, 0},
+ {0x370d, 0x03, 0, 0}, {0x3631, 0x01, 0, 0}, {0x3632, 0x52, 0, 0},
+ {0x3606, 0x24, 0, 0}, {0x3620, 0x96, 0, 0}, {0x5785, 0x07, 0, 0},
+ {0x3a13, 0x30, 0, 0}, {0x3600, 0x52, 0, 0}, {0x3604, 0x48, 0, 0},
+ {0x3606, 0x1b, 0, 0}, {0x370d, 0x0b, 0, 0}, {0x370f, 0xc0, 0, 0},
+ {0x3709, 0x01, 0, 0}, {0x3823, 0x00, 0, 0}, {0x5007, 0x00, 0, 0},
+ {0x5009, 0x00, 0, 0}, {0x5011, 0x00, 0, 0}, {0x5013, 0x00, 0, 0},
+ {0x519e, 0x00, 0, 0}, {0x5086, 0x00, 0, 0}, {0x5087, 0x00, 0, 0},
+ {0x5088, 0x00, 0, 0}, {0x5089, 0x00, 0, 0}, {0x302b, 0x00, 0, 0},
+ {0x3808, 0x01, 0, 0}, {0x3809, 0x40, 0, 0}, {0x380a, 0x00, 0, 0},
+ {0x380b, 0xf0, 0, 0}, {0x3a00, 0x78, 0, 0},
+};
+
+static struct reg_value ov5642_setting_15fps_NTSC_720_480[] = {
+ {0x3103, 0x93, 0, 0}, {0x3008, 0x82, 0, 0}, {0x3017, 0x7f, 0, 0},
+ {0x3018, 0xfc, 0, 0}, {0x3810, 0xc2, 0, 0}, {0x3615, 0xf0, 0, 0},
+ {0x3000, 0x00, 0, 0}, {0x3001, 0x00, 0, 0}, {0x3002, 0x5c, 0, 0},
+ {0x3003, 0x00, 0, 0}, {0x3004, 0xff, 0, 0}, {0x3005, 0xff, 0, 0},
+ {0x3006, 0x43, 0, 0}, {0x3007, 0x37, 0, 0}, {0x3011, 0x08, 0, 0},
+ {0x3010, 0x10, 0, 0}, {0x460c, 0x22, 0, 0}, {0x3815, 0x04, 0, 0},
+ {0x370c, 0xa0, 0, 0}, {0x3602, 0xfc, 0, 0}, {0x3612, 0xff, 0, 0},
+ {0x3634, 0xc0, 0, 0}, {0x3613, 0x00, 0, 0}, {0x3605, 0x7c, 0, 0},
+ {0x3621, 0x09, 0, 0}, {0x3622, 0x60, 0, 0}, {0x3604, 0x40, 0, 0},
+ {0x3603, 0xa7, 0, 0}, {0x3603, 0x27, 0, 0}, {0x4000, 0x21, 0, 0},
+ {0x401d, 0x22, 0, 0}, {0x3600, 0x54, 0, 0}, {0x3605, 0x04, 0, 0},
+ {0x3606, 0x3f, 0, 0}, {0x3c01, 0x80, 0, 0}, {0x5000, 0x4f, 0, 0},
+ {0x5020, 0x04, 0, 0}, {0x5181, 0x79, 0, 0}, {0x5182, 0x00, 0, 0},
+ {0x5185, 0x22, 0, 0}, {0x5197, 0x01, 0, 0}, {0x5001, 0xff, 0, 0},
+ {0x5500, 0x0a, 0, 0}, {0x5504, 0x00, 0, 0}, {0x5505, 0x7f, 0, 0},
+ {0x5080, 0x08, 0, 0}, {0x300e, 0x18, 0, 0}, {0x4610, 0x00, 0, 0},
+ {0x471d, 0x05, 0, 0}, {0x4708, 0x06, 0, 0}, {0x3808, 0x02, 0, 0},
+ {0x3809, 0x80, 0, 0}, {0x380a, 0x01, 0, 0}, {0x380b, 0xe0, 0, 0},
+ {0x380e, 0x07, 0, 0}, {0x380f, 0xd0, 0, 0}, {0x501f, 0x00, 0, 0},
+ {0x5000, 0x4f, 0, 0}, {0x4300, 0x30, 0, 0}, {0x3503, 0x07, 0, 0},
+ {0x3501, 0x73, 0, 0}, {0x3502, 0x80, 0, 0}, {0x350b, 0x00, 0, 0},
+ {0x3503, 0x07, 0, 0}, {0x3824, 0x11, 0, 0}, {0x3501, 0x1e, 0, 0},
+ {0x3502, 0x80, 0, 0}, {0x350b, 0x7f, 0, 0}, {0x380c, 0x0c, 0, 0},
+ {0x380d, 0x80, 0, 0}, {0x380e, 0x03, 0, 0}, {0x380f, 0xe8, 0, 0},
+ {0x3a0d, 0x04, 0, 0}, {0x3a0e, 0x03, 0, 0}, {0x3818, 0xc1, 0, 0},
+ {0x3705, 0xdb, 0, 0}, {0x370a, 0x81, 0, 0}, {0x3801, 0x80, 0, 0},
+ {0x3621, 0x87, 0, 0}, {0x3801, 0x50, 0, 0}, {0x3803, 0x08, 0, 0},
+ {0x3827, 0x08, 0, 0}, {0x3810, 0x40, 0, 0}, {0x3804, 0x05, 0, 0},
+ {0x3805, 0x00, 0, 0}, {0x5682, 0x05, 0, 0}, {0x5683, 0x00, 0, 0},
+ {0x3806, 0x03, 0, 0}, {0x3807, 0xc0, 0, 0}, {0x5686, 0x03, 0, 0},
+ {0x5687, 0xbc, 0, 0}, {0x3a00, 0x78, 0, 0}, {0x3a1a, 0x05, 0, 0},
+ {0x3a13, 0x30, 0, 0}, {0x3a18, 0x00, 0, 0}, {0x3a19, 0x7c, 0, 0},
+ {0x3a08, 0x12, 0, 0}, {0x3a09, 0xc0, 0, 0}, {0x3a0a, 0x0f, 0, 0},
+ {0x3a0b, 0xa0, 0, 0}, {0x350c, 0x07, 0, 0}, {0x350d, 0xd0, 0, 0},
+ {0x3500, 0x00, 0, 0}, {0x3501, 0x00, 0, 0}, {0x3502, 0x00, 0, 0},
+ {0x350a, 0x00, 0, 0}, {0x350b, 0x00, 0, 0}, {0x3503, 0x00, 0, 0},
+ {0x528a, 0x02, 0, 0}, {0x528b, 0x04, 0, 0}, {0x528c, 0x08, 0, 0},
+ {0x528d, 0x08, 0, 0}, {0x528e, 0x08, 0, 0}, {0x528f, 0x10, 0, 0},
+ {0x5290, 0x10, 0, 0}, {0x5292, 0x00, 0, 0}, {0x5293, 0x02, 0, 0},
+ {0x5294, 0x00, 0, 0}, {0x5295, 0x02, 0, 0}, {0x5296, 0x00, 0, 0},
+ {0x5297, 0x02, 0, 0}, {0x5298, 0x00, 0, 0}, {0x5299, 0x02, 0, 0},
+ {0x529a, 0x00, 0, 0}, {0x529b, 0x02, 0, 0}, {0x529c, 0x00, 0, 0},
+ {0x529d, 0x02, 0, 0}, {0x529e, 0x00, 0, 0}, {0x529f, 0x02, 0, 0},
+ {0x3a0f, 0x3c, 0, 0}, {0x3a10, 0x30, 0, 0}, {0x3a1b, 0x3c, 0, 0},
+ {0x3a1e, 0x30, 0, 0}, {0x3a11, 0x70, 0, 0}, {0x3a1f, 0x10, 0, 0},
+ {0x3030, 0x2b, 0, 0}, {0x3a02, 0x00, 0, 0}, {0x3a03, 0x7d, 0, 0},
+ {0x3a04, 0x00, 0, 0}, {0x3a14, 0x00, 0, 0}, {0x3a15, 0x7d, 0, 0},
+ {0x3a16, 0x00, 0, 0}, {0x3a00, 0x78, 0, 0}, {0x3a08, 0x09, 0, 0},
+ {0x3a09, 0x60, 0, 0}, {0x3a0a, 0x07, 0, 0}, {0x3a0b, 0xd0, 0, 0},
+ {0x3a0d, 0x08, 0, 0}, {0x3a0e, 0x06, 0, 0}, {0x5193, 0x70, 0, 0},
+ {0x589b, 0x04, 0, 0}, {0x589a, 0xc5, 0, 0}, {0x401e, 0x20, 0, 0},
+ {0x4001, 0x42, 0, 0}, {0x401c, 0x04, 0, 0}, {0x528a, 0x01, 0, 0},
+ {0x528b, 0x04, 0, 0}, {0x528c, 0x08, 0, 0}, {0x528d, 0x10, 0, 0},
+ {0x528e, 0x20, 0, 0}, {0x528f, 0x28, 0, 0}, {0x5290, 0x30, 0, 0},
+ {0x5292, 0x00, 0, 0}, {0x5293, 0x01, 0, 0}, {0x5294, 0x00, 0, 0},
+ {0x5295, 0x04, 0, 0}, {0x5296, 0x00, 0, 0}, {0x5297, 0x08, 0, 0},
+ {0x5298, 0x00, 0, 0}, {0x5299, 0x10, 0, 0}, {0x529a, 0x00, 0, 0},
+ {0x529b, 0x20, 0, 0}, {0x529c, 0x00, 0, 0}, {0x529d, 0x28, 0, 0},
+ {0x529e, 0x00, 0, 0}, {0x529f, 0x30, 0, 0}, {0x5282, 0x00, 0, 0},
+ {0x5300, 0x00, 0, 0}, {0x5301, 0x20, 0, 0}, {0x5302, 0x00, 0, 0},
+ {0x5303, 0x7c, 0, 0}, {0x530c, 0x00, 0, 0}, {0x530d, 0x0c, 0, 0},
+ {0x530e, 0x20, 0, 0}, {0x530f, 0x80, 0, 0}, {0x5310, 0x20, 0, 0},
+ {0x5311, 0x80, 0, 0}, {0x5308, 0x20, 0, 0}, {0x5309, 0x40, 0, 0},
+ {0x5304, 0x00, 0, 0}, {0x5305, 0x30, 0, 0}, {0x5306, 0x00, 0, 0},
+ {0x5307, 0x80, 0, 0}, {0x5314, 0x08, 0, 0}, {0x5315, 0x20, 0, 0},
+ {0x5319, 0x30, 0, 0}, {0x5316, 0x10, 0, 0}, {0x5317, 0x00, 0, 0},
+ {0x5318, 0x02, 0, 0}, {0x5380, 0x01, 0, 0}, {0x5381, 0x00, 0, 0},
+ {0x5382, 0x00, 0, 0}, {0x5383, 0x4e, 0, 0}, {0x5384, 0x00, 0, 0},
+ {0x5385, 0x0f, 0, 0}, {0x5386, 0x00, 0, 0}, {0x5387, 0x00, 0, 0},
+ {0x5388, 0x01, 0, 0}, {0x5389, 0x15, 0, 0}, {0x538a, 0x00, 0, 0},
+ {0x538b, 0x31, 0, 0}, {0x538c, 0x00, 0, 0}, {0x538d, 0x00, 0, 0},
+ {0x538e, 0x00, 0, 0}, {0x538f, 0x0f, 0, 0}, {0x5390, 0x00, 0, 0},
+ {0x5391, 0xab, 0, 0}, {0x5392, 0x00, 0, 0}, {0x5393, 0xa2, 0, 0},
+ {0x5394, 0x08, 0, 0}, {0x5480, 0x14, 0, 0}, {0x5481, 0x21, 0, 0},
+ {0x5482, 0x36, 0, 0}, {0x5483, 0x57, 0, 0}, {0x5484, 0x65, 0, 0},
+ {0x5485, 0x71, 0, 0}, {0x5486, 0x7d, 0, 0}, {0x5487, 0x87, 0, 0},
+ {0x5488, 0x91, 0, 0}, {0x5489, 0x9a, 0, 0}, {0x548a, 0xaa, 0, 0},
+ {0x548b, 0xb8, 0, 0}, {0x548c, 0xcd, 0, 0}, {0x548d, 0xdd, 0, 0},
+ {0x548e, 0xea, 0, 0}, {0x548f, 0x1d, 0, 0}, {0x5490, 0x05, 0, 0},
+ {0x5491, 0x00, 0, 0}, {0x5492, 0x04, 0, 0}, {0x5493, 0x20, 0, 0},
+ {0x5494, 0x03, 0, 0}, {0x5495, 0x60, 0, 0}, {0x5496, 0x02, 0, 0},
+ {0x5497, 0xb8, 0, 0}, {0x5498, 0x02, 0, 0}, {0x5499, 0x86, 0, 0},
+ {0x549a, 0x02, 0, 0}, {0x549b, 0x5b, 0, 0}, {0x549c, 0x02, 0, 0},
+ {0x549d, 0x3b, 0, 0}, {0x549e, 0x02, 0, 0}, {0x549f, 0x1c, 0, 0},
+ {0x54a0, 0x02, 0, 0}, {0x54a1, 0x04, 0, 0}, {0x54a2, 0x01, 0, 0},
+ {0x54a3, 0xed, 0, 0}, {0x54a4, 0x01, 0, 0}, {0x54a5, 0xc5, 0, 0},
+ {0x54a6, 0x01, 0, 0}, {0x54a7, 0xa5, 0, 0}, {0x54a8, 0x01, 0, 0},
+ {0x54a9, 0x6c, 0, 0}, {0x54aa, 0x01, 0, 0}, {0x54ab, 0x41, 0, 0},
+ {0x54ac, 0x01, 0, 0}, {0x54ad, 0x20, 0, 0}, {0x54ae, 0x00, 0, 0},
+ {0x54af, 0x16, 0, 0}, {0x54b0, 0x01, 0, 0}, {0x54b1, 0x20, 0, 0},
+ {0x54b2, 0x00, 0, 0}, {0x54b3, 0x10, 0, 0}, {0x54b4, 0x00, 0, 0},
+ {0x54b5, 0xf0, 0, 0}, {0x54b6, 0x00, 0, 0}, {0x54b7, 0xdf, 0, 0},
+ {0x5402, 0x3f, 0, 0}, {0x5403, 0x00, 0, 0}, {0x3406, 0x00, 0, 0},
+ {0x5180, 0xff, 0, 0}, {0x5181, 0x52, 0, 0}, {0x5182, 0x11, 0, 0},
+ {0x5183, 0x14, 0, 0}, {0x5184, 0x25, 0, 0}, {0x5185, 0x24, 0, 0},
+ {0x5186, 0x06, 0, 0}, {0x5187, 0x08, 0, 0}, {0x5188, 0x08, 0, 0},
+ {0x5189, 0x7c, 0, 0}, {0x518a, 0x60, 0, 0}, {0x518b, 0xb2, 0, 0},
+ {0x518c, 0xb2, 0, 0}, {0x518d, 0x44, 0, 0}, {0x518e, 0x3d, 0, 0},
+ {0x518f, 0x58, 0, 0}, {0x5190, 0x46, 0, 0}, {0x5191, 0xf8, 0, 0},
+ {0x5192, 0x04, 0, 0}, {0x5193, 0x70, 0, 0}, {0x5194, 0xf0, 0, 0},
+ {0x5195, 0xf0, 0, 0}, {0x5196, 0x03, 0, 0}, {0x5197, 0x01, 0, 0},
+ {0x5198, 0x04, 0, 0}, {0x5199, 0x12, 0, 0}, {0x519a, 0x04, 0, 0},
+ {0x519b, 0x00, 0, 0}, {0x519c, 0x06, 0, 0}, {0x519d, 0x82, 0, 0},
+ {0x519e, 0x00, 0, 0}, {0x5025, 0x80, 0, 0}, {0x3a0f, 0x38, 0, 0},
+ {0x3a10, 0x30, 0, 0}, {0x3a1b, 0x3a, 0, 0}, {0x3a1e, 0x2e, 0, 0},
+ {0x3a11, 0x60, 0, 0}, {0x3a1f, 0x10, 0, 0}, {0x5688, 0xa6, 0, 0},
+ {0x5689, 0x6a, 0, 0}, {0x568a, 0xea, 0, 0}, {0x568b, 0xae, 0, 0},
+ {0x568c, 0xa6, 0, 0}, {0x568d, 0x6a, 0, 0}, {0x568e, 0x62, 0, 0},
+ {0x568f, 0x26, 0, 0}, {0x5583, 0x40, 0, 0}, {0x5584, 0x40, 0, 0},
+ {0x5580, 0x02, 0, 0}, {0x5000, 0xcf, 0, 0}, {0x5800, 0x27, 0, 0},
+ {0x5801, 0x19, 0, 0}, {0x5802, 0x12, 0, 0}, {0x5803, 0x0f, 0, 0},
+ {0x5804, 0x10, 0, 0}, {0x5805, 0x15, 0, 0}, {0x5806, 0x1e, 0, 0},
+ {0x5807, 0x2f, 0, 0}, {0x5808, 0x15, 0, 0}, {0x5809, 0x0d, 0, 0},
+ {0x580a, 0x0a, 0, 0}, {0x580b, 0x09, 0, 0}, {0x580c, 0x0a, 0, 0},
+ {0x580d, 0x0c, 0, 0}, {0x580e, 0x12, 0, 0}, {0x580f, 0x19, 0, 0},
+ {0x5810, 0x0b, 0, 0}, {0x5811, 0x07, 0, 0}, {0x5812, 0x04, 0, 0},
+ {0x5813, 0x03, 0, 0}, {0x5814, 0x03, 0, 0}, {0x5815, 0x06, 0, 0},
+ {0x5816, 0x0a, 0, 0}, {0x5817, 0x0f, 0, 0}, {0x5818, 0x0a, 0, 0},
+ {0x5819, 0x05, 0, 0}, {0x581a, 0x01, 0, 0}, {0x581b, 0x00, 0, 0},
+ {0x581c, 0x00, 0, 0}, {0x581d, 0x03, 0, 0}, {0x581e, 0x08, 0, 0},
+ {0x581f, 0x0c, 0, 0}, {0x5820, 0x0a, 0, 0}, {0x5821, 0x05, 0, 0},
+ {0x5822, 0x01, 0, 0}, {0x5823, 0x00, 0, 0}, {0x5824, 0x00, 0, 0},
+ {0x5825, 0x03, 0, 0}, {0x5826, 0x08, 0, 0}, {0x5827, 0x0c, 0, 0},
+ {0x5828, 0x0e, 0, 0}, {0x5829, 0x08, 0, 0}, {0x582a, 0x06, 0, 0},
+ {0x582b, 0x04, 0, 0}, {0x582c, 0x05, 0, 0}, {0x582d, 0x07, 0, 0},
+ {0x582e, 0x0b, 0, 0}, {0x582f, 0x12, 0, 0}, {0x5830, 0x18, 0, 0},
+ {0x5831, 0x10, 0, 0}, {0x5832, 0x0c, 0, 0}, {0x5833, 0x0a, 0, 0},
+ {0x5834, 0x0b, 0, 0}, {0x5835, 0x0e, 0, 0}, {0x5836, 0x15, 0, 0},
+ {0x5837, 0x19, 0, 0}, {0x5838, 0x32, 0, 0}, {0x5839, 0x1f, 0, 0},
+ {0x583a, 0x18, 0, 0}, {0x583b, 0x16, 0, 0}, {0x583c, 0x17, 0, 0},
+ {0x583d, 0x1e, 0, 0}, {0x583e, 0x26, 0, 0}, {0x583f, 0x53, 0, 0},
+ {0x5840, 0x10, 0, 0}, {0x5841, 0x0f, 0, 0}, {0x5842, 0x0d, 0, 0},
+ {0x5843, 0x0c, 0, 0}, {0x5844, 0x0e, 0, 0}, {0x5845, 0x09, 0, 0},
+ {0x5846, 0x11, 0, 0}, {0x5847, 0x10, 0, 0}, {0x5848, 0x10, 0, 0},
+ {0x5849, 0x10, 0, 0}, {0x584a, 0x10, 0, 0}, {0x584b, 0x0e, 0, 0},
+ {0x584c, 0x10, 0, 0}, {0x584d, 0x10, 0, 0}, {0x584e, 0x11, 0, 0},
+ {0x584f, 0x10, 0, 0}, {0x5850, 0x0f, 0, 0}, {0x5851, 0x0c, 0, 0},
+ {0x5852, 0x0f, 0, 0}, {0x5853, 0x10, 0, 0}, {0x5854, 0x10, 0, 0},
+ {0x5855, 0x0f, 0, 0}, {0x5856, 0x0e, 0, 0}, {0x5857, 0x0b, 0, 0},
+ {0x5858, 0x10, 0, 0}, {0x5859, 0x0d, 0, 0}, {0x585a, 0x0d, 0, 0},
+ {0x585b, 0x0c, 0, 0}, {0x585c, 0x0c, 0, 0}, {0x585d, 0x0c, 0, 0},
+ {0x585e, 0x0b, 0, 0}, {0x585f, 0x0c, 0, 0}, {0x5860, 0x0c, 0, 0},
+ {0x5861, 0x0c, 0, 0}, {0x5862, 0x0d, 0, 0}, {0x5863, 0x08, 0, 0},
+ {0x5864, 0x11, 0, 0}, {0x5865, 0x18, 0, 0}, {0x5866, 0x18, 0, 0},
+ {0x5867, 0x19, 0, 0}, {0x5868, 0x17, 0, 0}, {0x5869, 0x19, 0, 0},
+ {0x586a, 0x16, 0, 0}, {0x586b, 0x13, 0, 0}, {0x586c, 0x13, 0, 0},
+ {0x586d, 0x12, 0, 0}, {0x586e, 0x13, 0, 0}, {0x586f, 0x16, 0, 0},
+ {0x5870, 0x14, 0, 0}, {0x5871, 0x12, 0, 0}, {0x5872, 0x10, 0, 0},
+ {0x5873, 0x11, 0, 0}, {0x5874, 0x11, 0, 0}, {0x5875, 0x16, 0, 0},
+ {0x5876, 0x14, 0, 0}, {0x5877, 0x11, 0, 0}, {0x5878, 0x10, 0, 0},
+ {0x5879, 0x0f, 0, 0}, {0x587a, 0x10, 0, 0}, {0x587b, 0x14, 0, 0},
+ {0x587c, 0x13, 0, 0}, {0x587d, 0x12, 0, 0}, {0x587e, 0x11, 0, 0},
+ {0x587f, 0x11, 0, 0}, {0x5880, 0x12, 0, 0}, {0x5881, 0x15, 0, 0},
+ {0x5882, 0x14, 0, 0}, {0x5883, 0x15, 0, 0}, {0x5884, 0x15, 0, 0},
+ {0x5885, 0x15, 0, 0}, {0x5886, 0x13, 0, 0}, {0x5887, 0x17, 0, 0},
+ {0x3710, 0x10, 0, 0}, {0x3632, 0x51, 0, 0}, {0x3702, 0x10, 0, 0},
+ {0x3703, 0xb2, 0, 0}, {0x3704, 0x18, 0, 0}, {0x370b, 0x40, 0, 0},
+ {0x370d, 0x03, 0, 0}, {0x3631, 0x01, 0, 0}, {0x3632, 0x52, 0, 0},
+ {0x3606, 0x24, 0, 0}, {0x3620, 0x96, 0, 0}, {0x5785, 0x07, 0, 0},
+ {0x3a13, 0x30, 0, 0}, {0x3600, 0x52, 0, 0}, {0x3604, 0x48, 0, 0},
+ {0x3606, 0x1b, 0, 0}, {0x370d, 0x0b, 0, 0}, {0x370f, 0xc0, 0, 0},
+ {0x3709, 0x01, 0, 0}, {0x3823, 0x00, 0, 0}, {0x5007, 0x00, 0, 0},
+ {0x5009, 0x00, 0, 0}, {0x5011, 0x00, 0, 0}, {0x5013, 0x00, 0, 0},
+ {0x519e, 0x00, 0, 0}, {0x5086, 0x00, 0, 0}, {0x5087, 0x00, 0, 0},
+ {0x5088, 0x00, 0, 0}, {0x5089, 0x00, 0, 0}, {0x302b, 0x00, 0, 0},
+ {0x3824, 0x11, 0, 0}, {0x3825, 0xb4, 0, 0}, {0x3826, 0x00, 0, 0},
+ {0x3827, 0x3d, 0, 0}, {0x380c, 0x0c, 0, 0}, {0x380d, 0x80, 0, 0},
+ {0x380e, 0x03, 0, 0}, {0x380f, 0xe8, 0, 0}, {0x3808, 0x02, 0, 0},
+ {0x3809, 0xd0, 0, 0}, {0x380A, 0x01, 0, 0}, {0x380B, 0xe0, 0, 0},
+ {0x3804, 0x05, 0, 0}, {0x3805, 0x00, 0, 0}, {0x3806, 0x03, 0, 0},
+ {0x3807, 0x55, 0, 0}, {0x5686, 0x03, 0, 0}, {0x5687, 0x55, 0, 0},
+ {0x5682, 0x05, 0, 0}, {0x5683, 0x00, 0, 0},
+};
+
+static struct reg_value ov5642_setting_15fps_PAL_720_576[] = {
+ {0x3103, 0x93, 0, 0}, {0x3008, 0x82, 0, 0}, {0x3017, 0x7f, 0, 0},
+ {0x3018, 0xfc, 0, 0}, {0x3810, 0xc2, 0, 0}, {0x3615, 0xf0, 0, 0},
+ {0x3000, 0x00, 0, 0}, {0x3001, 0x00, 0, 0}, {0x3002, 0x5c, 0, 0},
+ {0x3003, 0x00, 0, 0}, {0x3004, 0xff, 0, 0}, {0x3005, 0xff, 0, 0},
+ {0x3006, 0x43, 0, 0}, {0x3007, 0x37, 0, 0}, {0x3011, 0x08, 0, 0},
+ {0x3010, 0x10, 0, 0}, {0x460c, 0x22, 0, 0}, {0x3815, 0x04, 0, 0},
+ {0x370c, 0xa0, 0, 0}, {0x3602, 0xfc, 0, 0}, {0x3612, 0xff, 0, 0},
+ {0x3634, 0xc0, 0, 0}, {0x3613, 0x00, 0, 0}, {0x3605, 0x7c, 0, 0},
+ {0x3621, 0x09, 0, 0}, {0x3622, 0x60, 0, 0}, {0x3604, 0x40, 0, 0},
+ {0x3603, 0xa7, 0, 0}, {0x3603, 0x27, 0, 0}, {0x4000, 0x21, 0, 0},
+ {0x401d, 0x22, 0, 0}, {0x3600, 0x54, 0, 0}, {0x3605, 0x04, 0, 0},
+ {0x3606, 0x3f, 0, 0}, {0x3c01, 0x80, 0, 0}, {0x5000, 0x4f, 0, 0},
+ {0x5020, 0x04, 0, 0}, {0x5181, 0x79, 0, 0}, {0x5182, 0x00, 0, 0},
+ {0x5185, 0x22, 0, 0}, {0x5197, 0x01, 0, 0}, {0x5001, 0xff, 0, 0},
+ {0x5500, 0x0a, 0, 0}, {0x5504, 0x00, 0, 0}, {0x5505, 0x7f, 0, 0},
+ {0x5080, 0x08, 0, 0}, {0x300e, 0x18, 0, 0}, {0x4610, 0x00, 0, 0},
+ {0x471d, 0x05, 0, 0}, {0x4708, 0x06, 0, 0}, {0x3808, 0x02, 0, 0},
+ {0x3809, 0x80, 0, 0}, {0x380a, 0x01, 0, 0}, {0x380b, 0xe0, 0, 0},
+ {0x380e, 0x07, 0, 0}, {0x380f, 0xd0, 0, 0}, {0x501f, 0x00, 0, 0},
+ {0x5000, 0x4f, 0, 0}, {0x4300, 0x30, 0, 0}, {0x3503, 0x07, 0, 0},
+ {0x3501, 0x73, 0, 0}, {0x3502, 0x80, 0, 0}, {0x350b, 0x00, 0, 0},
+ {0x3503, 0x07, 0, 0}, {0x3824, 0x11, 0, 0}, {0x3501, 0x1e, 0, 0},
+ {0x3502, 0x80, 0, 0}, {0x350b, 0x7f, 0, 0}, {0x380c, 0x0c, 0, 0},
+ {0x380d, 0x80, 0, 0}, {0x380e, 0x03, 0, 0}, {0x380f, 0xe8, 0, 0},
+ {0x3a0d, 0x04, 0, 0}, {0x3a0e, 0x03, 0, 0}, {0x3818, 0xc1, 0, 0},
+ {0x3705, 0xdb, 0, 0}, {0x370a, 0x81, 0, 0}, {0x3801, 0x80, 0, 0},
+ {0x3621, 0x87, 0, 0}, {0x3801, 0x50, 0, 0}, {0x3803, 0x08, 0, 0},
+ {0x3827, 0x08, 0, 0}, {0x3810, 0x40, 0, 0}, {0x3804, 0x05, 0, 0},
+ {0x3805, 0x00, 0, 0}, {0x5682, 0x05, 0, 0}, {0x5683, 0x00, 0, 0},
+ {0x3806, 0x03, 0, 0}, {0x3807, 0xc0, 0, 0}, {0x5686, 0x03, 0, 0},
+ {0x5687, 0xbc, 0, 0}, {0x3a00, 0x78, 0, 0}, {0x3a1a, 0x05, 0, 0},
+ {0x3a13, 0x30, 0, 0}, {0x3a18, 0x00, 0, 0}, {0x3a19, 0x7c, 0, 0},
+ {0x3a08, 0x12, 0, 0}, {0x3a09, 0xc0, 0, 0}, {0x3a0a, 0x0f, 0, 0},
+ {0x3a0b, 0xa0, 0, 0}, {0x350c, 0x07, 0, 0}, {0x350d, 0xd0, 0, 0},
+ {0x3500, 0x00, 0, 0}, {0x3501, 0x00, 0, 0}, {0x3502, 0x00, 0, 0},
+ {0x350a, 0x00, 0, 0}, {0x350b, 0x00, 0, 0}, {0x3503, 0x00, 0, 0},
+ {0x528a, 0x02, 0, 0}, {0x528b, 0x04, 0, 0}, {0x528c, 0x08, 0, 0},
+ {0x528d, 0x08, 0, 0}, {0x528e, 0x08, 0, 0}, {0x528f, 0x10, 0, 0},
+ {0x5290, 0x10, 0, 0}, {0x5292, 0x00, 0, 0}, {0x5293, 0x02, 0, 0},
+ {0x5294, 0x00, 0, 0}, {0x5295, 0x02, 0, 0}, {0x5296, 0x00, 0, 0},
+ {0x5297, 0x02, 0, 0}, {0x5298, 0x00, 0, 0}, {0x5299, 0x02, 0, 0},
+ {0x529a, 0x00, 0, 0}, {0x529b, 0x02, 0, 0}, {0x529c, 0x00, 0, 0},
+ {0x529d, 0x02, 0, 0}, {0x529e, 0x00, 0, 0}, {0x529f, 0x02, 0, 0},
+ {0x3a0f, 0x3c, 0, 0}, {0x3a10, 0x30, 0, 0}, {0x3a1b, 0x3c, 0, 0},
+ {0x3a1e, 0x30, 0, 0}, {0x3a11, 0x70, 0, 0}, {0x3a1f, 0x10, 0, 0},
+ {0x3030, 0x2b, 0, 0}, {0x3a02, 0x00, 0, 0}, {0x3a03, 0x7d, 0, 0},
+ {0x3a04, 0x00, 0, 0}, {0x3a14, 0x00, 0, 0}, {0x3a15, 0x7d, 0, 0},
+ {0x3a16, 0x00, 0, 0}, {0x3a00, 0x78, 0, 0}, {0x3a08, 0x09, 0, 0},
+ {0x3a09, 0x60, 0, 0}, {0x3a0a, 0x07, 0, 0}, {0x3a0b, 0xd0, 0, 0},
+ {0x3a0d, 0x08, 0, 0}, {0x3a0e, 0x06, 0, 0}, {0x5193, 0x70, 0, 0},
+ {0x589b, 0x04, 0, 0}, {0x589a, 0xc5, 0, 0}, {0x401e, 0x20, 0, 0},
+ {0x4001, 0x42, 0, 0}, {0x401c, 0x04, 0, 0}, {0x528a, 0x01, 0, 0},
+ {0x528b, 0x04, 0, 0}, {0x528c, 0x08, 0, 0}, {0x528d, 0x10, 0, 0},
+ {0x528e, 0x20, 0, 0}, {0x528f, 0x28, 0, 0}, {0x5290, 0x30, 0, 0},
+ {0x5292, 0x00, 0, 0}, {0x5293, 0x01, 0, 0}, {0x5294, 0x00, 0, 0},
+ {0x5295, 0x04, 0, 0}, {0x5296, 0x00, 0, 0}, {0x5297, 0x08, 0, 0},
+ {0x5298, 0x00, 0, 0}, {0x5299, 0x10, 0, 0}, {0x529a, 0x00, 0, 0},
+ {0x529b, 0x20, 0, 0}, {0x529c, 0x00, 0, 0}, {0x529d, 0x28, 0, 0},
+ {0x529e, 0x00, 0, 0}, {0x529f, 0x30, 0, 0}, {0x5282, 0x00, 0, 0},
+ {0x5300, 0x00, 0, 0}, {0x5301, 0x20, 0, 0}, {0x5302, 0x00, 0, 0},
+ {0x5303, 0x7c, 0, 0}, {0x530c, 0x00, 0, 0}, {0x530d, 0x0c, 0, 0},
+ {0x530e, 0x20, 0, 0}, {0x530f, 0x80, 0, 0}, {0x5310, 0x20, 0, 0},
+ {0x5311, 0x80, 0, 0}, {0x5308, 0x20, 0, 0}, {0x5309, 0x40, 0, 0},
+ {0x5304, 0x00, 0, 0}, {0x5305, 0x30, 0, 0}, {0x5306, 0x00, 0, 0},
+ {0x5307, 0x80, 0, 0}, {0x5314, 0x08, 0, 0}, {0x5315, 0x20, 0, 0},
+ {0x5319, 0x30, 0, 0}, {0x5316, 0x10, 0, 0}, {0x5317, 0x00, 0, 0},
+ {0x5318, 0x02, 0, 0}, {0x5380, 0x01, 0, 0}, {0x5381, 0x00, 0, 0},
+ {0x5382, 0x00, 0, 0}, {0x5383, 0x4e, 0, 0}, {0x5384, 0x00, 0, 0},
+ {0x5385, 0x0f, 0, 0}, {0x5386, 0x00, 0, 0}, {0x5387, 0x00, 0, 0},
+ {0x5388, 0x01, 0, 0}, {0x5389, 0x15, 0, 0}, {0x538a, 0x00, 0, 0},
+ {0x538b, 0x31, 0, 0}, {0x538c, 0x00, 0, 0}, {0x538d, 0x00, 0, 0},
+ {0x538e, 0x00, 0, 0}, {0x538f, 0x0f, 0, 0}, {0x5390, 0x00, 0, 0},
+ {0x5391, 0xab, 0, 0}, {0x5392, 0x00, 0, 0}, {0x5393, 0xa2, 0, 0},
+ {0x5394, 0x08, 0, 0}, {0x5480, 0x14, 0, 0}, {0x5481, 0x21, 0, 0},
+ {0x5482, 0x36, 0, 0}, {0x5483, 0x57, 0, 0}, {0x5484, 0x65, 0, 0},
+ {0x5485, 0x71, 0, 0}, {0x5486, 0x7d, 0, 0}, {0x5487, 0x87, 0, 0},
+ {0x5488, 0x91, 0, 0}, {0x5489, 0x9a, 0, 0}, {0x548a, 0xaa, 0, 0},
+ {0x548b, 0xb8, 0, 0}, {0x548c, 0xcd, 0, 0}, {0x548d, 0xdd, 0, 0},
+ {0x548e, 0xea, 0, 0}, {0x548f, 0x1d, 0, 0}, {0x5490, 0x05, 0, 0},
+ {0x5491, 0x00, 0, 0}, {0x5492, 0x04, 0, 0}, {0x5493, 0x20, 0, 0},
+ {0x5494, 0x03, 0, 0}, {0x5495, 0x60, 0, 0}, {0x5496, 0x02, 0, 0},
+ {0x5497, 0xb8, 0, 0}, {0x5498, 0x02, 0, 0}, {0x5499, 0x86, 0, 0},
+ {0x549a, 0x02, 0, 0}, {0x549b, 0x5b, 0, 0}, {0x549c, 0x02, 0, 0},
+ {0x549d, 0x3b, 0, 0}, {0x549e, 0x02, 0, 0}, {0x549f, 0x1c, 0, 0},
+ {0x54a0, 0x02, 0, 0}, {0x54a1, 0x04, 0, 0}, {0x54a2, 0x01, 0, 0},
+ {0x54a3, 0xed, 0, 0}, {0x54a4, 0x01, 0, 0}, {0x54a5, 0xc5, 0, 0},
+ {0x54a6, 0x01, 0, 0}, {0x54a7, 0xa5, 0, 0}, {0x54a8, 0x01, 0, 0},
+ {0x54a9, 0x6c, 0, 0}, {0x54aa, 0x01, 0, 0}, {0x54ab, 0x41, 0, 0},
+ {0x54ac, 0x01, 0, 0}, {0x54ad, 0x20, 0, 0}, {0x54ae, 0x00, 0, 0},
+ {0x54af, 0x16, 0, 0}, {0x54b0, 0x01, 0, 0}, {0x54b1, 0x20, 0, 0},
+ {0x54b2, 0x00, 0, 0}, {0x54b3, 0x10, 0, 0}, {0x54b4, 0x00, 0, 0},
+ {0x54b5, 0xf0, 0, 0}, {0x54b6, 0x00, 0, 0}, {0x54b7, 0xdf, 0, 0},
+ {0x5402, 0x3f, 0, 0}, {0x5403, 0x00, 0, 0}, {0x3406, 0x00, 0, 0},
+ {0x5180, 0xff, 0, 0}, {0x5181, 0x52, 0, 0}, {0x5182, 0x11, 0, 0},
+ {0x5183, 0x14, 0, 0}, {0x5184, 0x25, 0, 0}, {0x5185, 0x24, 0, 0},
+ {0x5186, 0x06, 0, 0}, {0x5187, 0x08, 0, 0}, {0x5188, 0x08, 0, 0},
+ {0x5189, 0x7c, 0, 0}, {0x518a, 0x60, 0, 0}, {0x518b, 0xb2, 0, 0},
+ {0x518c, 0xb2, 0, 0}, {0x518d, 0x44, 0, 0}, {0x518e, 0x3d, 0, 0},
+ {0x518f, 0x58, 0, 0}, {0x5190, 0x46, 0, 0}, {0x5191, 0xf8, 0, 0},
+ {0x5192, 0x04, 0, 0}, {0x5193, 0x70, 0, 0}, {0x5194, 0xf0, 0, 0},
+ {0x5195, 0xf0, 0, 0}, {0x5196, 0x03, 0, 0}, {0x5197, 0x01, 0, 0},
+ {0x5198, 0x04, 0, 0}, {0x5199, 0x12, 0, 0}, {0x519a, 0x04, 0, 0},
+ {0x519b, 0x00, 0, 0}, {0x519c, 0x06, 0, 0}, {0x519d, 0x82, 0, 0},
+ {0x519e, 0x00, 0, 0}, {0x5025, 0x80, 0, 0}, {0x3a0f, 0x38, 0, 0},
+ {0x3a10, 0x30, 0, 0}, {0x3a1b, 0x3a, 0, 0}, {0x3a1e, 0x2e, 0, 0},
+ {0x3a11, 0x60, 0, 0}, {0x3a1f, 0x10, 0, 0}, {0x5688, 0xa6, 0, 0},
+ {0x5689, 0x6a, 0, 0}, {0x568a, 0xea, 0, 0}, {0x568b, 0xae, 0, 0},
+ {0x568c, 0xa6, 0, 0}, {0x568d, 0x6a, 0, 0}, {0x568e, 0x62, 0, 0},
+ {0x568f, 0x26, 0, 0}, {0x5583, 0x40, 0, 0}, {0x5584, 0x40, 0, 0},
+ {0x5580, 0x02, 0, 0}, {0x5000, 0xcf, 0, 0}, {0x5800, 0x27, 0, 0},
+ {0x5801, 0x19, 0, 0}, {0x5802, 0x12, 0, 0}, {0x5803, 0x0f, 0, 0},
+ {0x5804, 0x10, 0, 0}, {0x5805, 0x15, 0, 0}, {0x5806, 0x1e, 0, 0},
+ {0x5807, 0x2f, 0, 0}, {0x5808, 0x15, 0, 0}, {0x5809, 0x0d, 0, 0},
+ {0x580a, 0x0a, 0, 0}, {0x580b, 0x09, 0, 0}, {0x580c, 0x0a, 0, 0},
+ {0x580d, 0x0c, 0, 0}, {0x580e, 0x12, 0, 0}, {0x580f, 0x19, 0, 0},
+ {0x5810, 0x0b, 0, 0}, {0x5811, 0x07, 0, 0}, {0x5812, 0x04, 0, 0},
+ {0x5813, 0x03, 0, 0}, {0x5814, 0x03, 0, 0}, {0x5815, 0x06, 0, 0},
+ {0x5816, 0x0a, 0, 0}, {0x5817, 0x0f, 0, 0}, {0x5818, 0x0a, 0, 0},
+ {0x5819, 0x05, 0, 0}, {0x581a, 0x01, 0, 0}, {0x581b, 0x00, 0, 0},
+ {0x581c, 0x00, 0, 0}, {0x581d, 0x03, 0, 0}, {0x581e, 0x08, 0, 0},
+ {0x581f, 0x0c, 0, 0}, {0x5820, 0x0a, 0, 0}, {0x5821, 0x05, 0, 0},
+ {0x5822, 0x01, 0, 0}, {0x5823, 0x00, 0, 0}, {0x5824, 0x00, 0, 0},
+ {0x5825, 0x03, 0, 0}, {0x5826, 0x08, 0, 0}, {0x5827, 0x0c, 0, 0},
+ {0x5828, 0x0e, 0, 0}, {0x5829, 0x08, 0, 0}, {0x582a, 0x06, 0, 0},
+ {0x582b, 0x04, 0, 0}, {0x582c, 0x05, 0, 0}, {0x582d, 0x07, 0, 0},
+ {0x582e, 0x0b, 0, 0}, {0x582f, 0x12, 0, 0}, {0x5830, 0x18, 0, 0},
+ {0x5831, 0x10, 0, 0}, {0x5832, 0x0c, 0, 0}, {0x5833, 0x0a, 0, 0},
+ {0x5834, 0x0b, 0, 0}, {0x5835, 0x0e, 0, 0}, {0x5836, 0x15, 0, 0},
+ {0x5837, 0x19, 0, 0}, {0x5838, 0x32, 0, 0}, {0x5839, 0x1f, 0, 0},
+ {0x583a, 0x18, 0, 0}, {0x583b, 0x16, 0, 0}, {0x583c, 0x17, 0, 0},
+ {0x583d, 0x1e, 0, 0}, {0x583e, 0x26, 0, 0}, {0x583f, 0x53, 0, 0},
+ {0x5840, 0x10, 0, 0}, {0x5841, 0x0f, 0, 0}, {0x5842, 0x0d, 0, 0},
+ {0x5843, 0x0c, 0, 0}, {0x5844, 0x0e, 0, 0}, {0x5845, 0x09, 0, 0},
+ {0x5846, 0x11, 0, 0}, {0x5847, 0x10, 0, 0}, {0x5848, 0x10, 0, 0},
+ {0x5849, 0x10, 0, 0}, {0x584a, 0x10, 0, 0}, {0x584b, 0x0e, 0, 0},
+ {0x584c, 0x10, 0, 0}, {0x584d, 0x10, 0, 0}, {0x584e, 0x11, 0, 0},
+ {0x584f, 0x10, 0, 0}, {0x5850, 0x0f, 0, 0}, {0x5851, 0x0c, 0, 0},
+ {0x5852, 0x0f, 0, 0}, {0x5853, 0x10, 0, 0}, {0x5854, 0x10, 0, 0},
+ {0x5855, 0x0f, 0, 0}, {0x5856, 0x0e, 0, 0}, {0x5857, 0x0b, 0, 0},
+ {0x5858, 0x10, 0, 0}, {0x5859, 0x0d, 0, 0}, {0x585a, 0x0d, 0, 0},
+ {0x585b, 0x0c, 0, 0}, {0x585c, 0x0c, 0, 0}, {0x585d, 0x0c, 0, 0},
+ {0x585e, 0x0b, 0, 0}, {0x585f, 0x0c, 0, 0}, {0x5860, 0x0c, 0, 0},
+ {0x5861, 0x0c, 0, 0}, {0x5862, 0x0d, 0, 0}, {0x5863, 0x08, 0, 0},
+ {0x5864, 0x11, 0, 0}, {0x5865, 0x18, 0, 0}, {0x5866, 0x18, 0, 0},
+ {0x5867, 0x19, 0, 0}, {0x5868, 0x17, 0, 0}, {0x5869, 0x19, 0, 0},
+ {0x586a, 0x16, 0, 0}, {0x586b, 0x13, 0, 0}, {0x586c, 0x13, 0, 0},
+ {0x586d, 0x12, 0, 0}, {0x586e, 0x13, 0, 0}, {0x586f, 0x16, 0, 0},
+ {0x5870, 0x14, 0, 0}, {0x5871, 0x12, 0, 0}, {0x5872, 0x10, 0, 0},
+ {0x5873, 0x11, 0, 0}, {0x5874, 0x11, 0, 0}, {0x5875, 0x16, 0, 0},
+ {0x5876, 0x14, 0, 0}, {0x5877, 0x11, 0, 0}, {0x5878, 0x10, 0, 0},
+ {0x5879, 0x0f, 0, 0}, {0x587a, 0x10, 0, 0}, {0x587b, 0x14, 0, 0},
+ {0x587c, 0x13, 0, 0}, {0x587d, 0x12, 0, 0}, {0x587e, 0x11, 0, 0},
+ {0x587f, 0x11, 0, 0}, {0x5880, 0x12, 0, 0}, {0x5881, 0x15, 0, 0},
+ {0x5882, 0x14, 0, 0}, {0x5883, 0x15, 0, 0}, {0x5884, 0x15, 0, 0},
+ {0x5885, 0x15, 0, 0}, {0x5886, 0x13, 0, 0}, {0x5887, 0x17, 0, 0},
+ {0x3710, 0x10, 0, 0}, {0x3632, 0x51, 0, 0}, {0x3702, 0x10, 0, 0},
+ {0x3703, 0xb2, 0, 0}, {0x3704, 0x18, 0, 0}, {0x370b, 0x40, 0, 0},
+ {0x370d, 0x03, 0, 0}, {0x3631, 0x01, 0, 0}, {0x3632, 0x52, 0, 0},
+ {0x3606, 0x24, 0, 0}, {0x3620, 0x96, 0, 0}, {0x5785, 0x07, 0, 0},
+ {0x3a13, 0x30, 0, 0}, {0x3600, 0x52, 0, 0}, {0x3604, 0x48, 0, 0},
+ {0x3606, 0x1b, 0, 0}, {0x370d, 0x0b, 0, 0}, {0x370f, 0xc0, 0, 0},
+ {0x3709, 0x01, 0, 0}, {0x3823, 0x00, 0, 0}, {0x5007, 0x00, 0, 0},
+ {0x5009, 0x00, 0, 0}, {0x5011, 0x00, 0, 0}, {0x5013, 0x00, 0, 0},
+ {0x519e, 0x00, 0, 0}, {0x5086, 0x00, 0, 0}, {0x5087, 0x00, 0, 0},
+ {0x5088, 0x00, 0, 0}, {0x5089, 0x00, 0, 0}, {0x302b, 0x00, 0, 0},
+ {0x3824, 0x11, 0, 0}, {0x3825, 0xdc, 0, 0}, {0x3826, 0x00, 0, 0},
+ {0x3827, 0x08, 0, 0}, {0x380c, 0x0c, 0, 0}, {0x380d, 0x80, 0, 0},
+ {0x380e, 0x03, 0, 0}, {0x380f, 0xe8, 0, 0}, {0x3808, 0x02, 0, 0},
+ {0x3809, 0xd0, 0, 0}, {0x380A, 0x02, 0, 0}, {0x380B, 0x40, 0, 0},
+ {0x3804, 0x04, 0, 0}, {0x3805, 0xb0, 0, 0}, {0x3806, 0x03, 0, 0},
+ {0x3807, 0xc0, 0, 0}, {0x5686, 0x03, 0, 0}, {0x5687, 0xc0, 0, 0},
+ {0x5682, 0x04, 0, 0}, {0x5683, 0xb0, 0, 0},
+};
+
+static struct ov5642_mode_info ov5642_mode_info_data[2][ov5642_mode_MAX + 1] = {
+ {
+ {ov5642_mode_VGA_640_480, 640, 480,
+ ov5642_setting_15fps_VGA_640_480,
+ ARRAY_SIZE(ov5642_setting_15fps_VGA_640_480)},
+ {ov5642_mode_QVGA_320_240, 320, 240,
+ ov5642_setting_15fps_QVGA_320_240,
+ ARRAY_SIZE(ov5642_setting_15fps_QVGA_320_240)},
+ {ov5642_mode_NTSC_720_480, 720, 480,
+ ov5642_setting_15fps_NTSC_720_480,
+ ARRAY_SIZE(ov5642_setting_15fps_NTSC_720_480)},
+ {ov5642_mode_PAL_720_576, 720, 576,
+ ov5642_setting_15fps_PAL_720_576,
+ ARRAY_SIZE(ov5642_setting_15fps_PAL_720_576)},
+ {ov5642_mode_720P_1280_720, 1280, 720,
+ ov5642_setting_15fps_720P_1280_720,
+ ARRAY_SIZE(ov5642_setting_15fps_720P_1280_720)},
+ {ov5642_mode_1080P_1920_1080, 1920, 1080,
+ ov5642_setting_15fps_1080P_1920_1080,
+ ARRAY_SIZE(ov5642_setting_15fps_1080P_1920_1080)},
+ {ov5642_mode_QSXGA_2592_1944, 2592, 1944,
+ ov5642_setting_15fps_QSXGA_2592_1944,
+ ARRAY_SIZE(ov5642_setting_15fps_QSXGA_2592_1944)},
+ {ov5642_mode_QCIF_176_144, 176, 144,
+ ov5642_setting_15fps_QCIF_176_144,
+ ARRAY_SIZE(ov5642_setting_15fps_QCIF_176_144)},
+ {ov5642_mode_XGA_1024_768, 1024, 768,
+ ov5642_setting_15fps_XGA_1024_768,
+ ARRAY_SIZE(ov5642_setting_15fps_XGA_1024_768)},
+ },
+ {
+ {ov5642_mode_VGA_640_480, 640, 480,
+ ov5642_setting_30fps_VGA_640_480,
+ ARRAY_SIZE(ov5642_setting_30fps_VGA_640_480)},
+ {ov5642_mode_QVGA_320_240, 320, 240,
+ ov5642_setting_30fps_QVGA_320_240,
+ ARRAY_SIZE(ov5642_setting_30fps_QVGA_320_240)},
+ {ov5642_mode_NTSC_720_480, 720, 480,
+ ov5642_setting_30fps_NTSC_720_480,
+ ARRAY_SIZE(ov5642_setting_30fps_NTSC_720_480)},
+ {ov5642_mode_PAL_720_576, 720, 576,
+ ov5642_setting_30fps_PAL_720_576,
+ ARRAY_SIZE(ov5642_setting_30fps_PAL_720_576)},
+ {ov5642_mode_720P_1280_720, 1280, 720,
+ ov5642_setting_30fps_720P_1280_720,
+ ARRAY_SIZE(ov5642_setting_30fps_720P_1280_720)},
+ {ov5642_mode_1080P_1920_1080, 0, 0, NULL, 0},
+ {ov5642_mode_QSXGA_2592_1944, 0, 0, NULL, 0},
+ {ov5642_mode_QCIF_176_144, 176, 144,
+ ov5642_setting_30fps_QCIF_176_144,
+ ARRAY_SIZE(ov5642_setting_30fps_QCIF_176_144)},
+ {ov5642_mode_XGA_1024_768, 1024, 768,
+ ov5642_setting_30fps_XGA_1024_768,
+ ARRAY_SIZE(ov5642_setting_30fps_XGA_1024_768)},
+ },
+};
+
+static struct regulator *io_regulator;
+static struct regulator *core_regulator;
+static struct regulator *analog_regulator;
+static struct regulator *gpo_regulator;
+
+static int ov5642_probe(struct i2c_client *adapter,
+ const struct i2c_device_id *device_id);
+static int ov5642_remove(struct i2c_client *client);
+
+static s32 ov5642_read_reg(u16 reg, u8 *val);
+static s32 ov5642_write_reg(u16 reg, u8 val);
+
+static const struct i2c_device_id ov5642_id[] = {
+ {"ov5642", 0},
+ {"ov564x", 0},
+ {},
+};
+
+MODULE_DEVICE_TABLE(i2c, ov5642_id);
+
+static struct i2c_driver ov5642_i2c_driver = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "ov5642",
+ },
+ .probe = ov5642_probe,
+ .remove = ov5642_remove,
+ .id_table = ov5642_id,
+};
+
+static void ov5642_standby(s32 enable)
+{
+ if (enable)
+ gpio_set_value(pwn_gpio, 1);
+ else
+ gpio_set_value(pwn_gpio, 0);
+
+ msleep(2);
+}
+
+static void ov5642_reset(void)
+{
+ /* camera reset */
+ gpio_set_value(rst_gpio, 1);
+
+ /* camera power down */
+ gpio_set_value(pwn_gpio, 1);
+ msleep(5);
+
+ gpio_set_value(pwn_gpio, 0);
+ msleep(5);
+
+ gpio_set_value(rst_gpio, 0);
+ msleep(1);
+
+ gpio_set_value(rst_gpio, 1);
+ msleep(5);
+
+ gpio_set_value(pwn_gpio, 1);
+}
+
+static int ov5642_power_on(struct device *dev)
+{
+ int ret = 0;
+
+ io_regulator = devm_regulator_get(dev, "DOVDD");
+ if (!IS_ERR(io_regulator)) {
+ regulator_set_voltage(io_regulator,
+ OV5642_VOLTAGE_DIGITAL_IO,
+ OV5642_VOLTAGE_DIGITAL_IO);
+ ret = regulator_enable(io_regulator);
+ if (ret) {
+ pr_err("%s:io set voltage error\n", __func__);
+ return ret;
+ } else {
+ dev_dbg(dev,
+ "%s:io set voltage ok\n", __func__);
+ }
+ } else {
+ pr_err("%s: cannot get io voltage error\n", __func__);
+ io_regulator = NULL;
+ }
+
+ core_regulator = devm_regulator_get(dev, "DVDD");
+ if (!IS_ERR(core_regulator)) {
+ regulator_set_voltage(core_regulator,
+ OV5642_VOLTAGE_DIGITAL_CORE,
+ OV5642_VOLTAGE_DIGITAL_CORE);
+ ret = regulator_enable(core_regulator);
+ if (ret) {
+ pr_err("%s:core set voltage error\n", __func__);
+ return ret;
+ } else {
+ dev_dbg(dev,
+ "%s:core set voltage ok\n", __func__);
+ }
+ } else {
+ core_regulator = NULL;
+ pr_err("%s: cannot get core voltage error\n", __func__);
+ }
+
+ analog_regulator = devm_regulator_get(dev, "AVDD");
+ if (!IS_ERR(analog_regulator)) {
+ regulator_set_voltage(analog_regulator,
+ OV5642_VOLTAGE_ANALOG,
+ OV5642_VOLTAGE_ANALOG);
+ ret = regulator_enable(analog_regulator);
+ if (ret) {
+ pr_err("%s:analog set voltage error\n",
+ __func__);
+ return ret;
+ } else {
+ dev_dbg(dev,
+ "%s:analog set voltage ok\n", __func__);
+ }
+ } else {
+ analog_regulator = NULL;
+ pr_err("%s: cannot get analog voltage error\n", __func__);
+ }
+
+ return ret;
+}
+
+static s32 ov5642_write_reg(u16 reg, u8 val)
+{
+ u8 au8Buf[3] = {0};
+
+ au8Buf[0] = reg >> 8;
+ au8Buf[1] = reg & 0xff;
+ au8Buf[2] = val;
+
+ if (i2c_master_send(ov5642_data.i2c_client, au8Buf, 3) < 0) {
+ pr_err("%s:write reg error:reg=%x,val=%x\n",
+ __func__, reg, val);
+ return -1;
+ }
+
+ return 0;
+}
+
+static s32 ov5642_read_reg(u16 reg, u8 *val)
+{
+ u8 au8RegBuf[2] = {0};
+ u8 u8RdVal = 0;
+
+ au8RegBuf[0] = reg >> 8;
+ au8RegBuf[1] = reg & 0xff;
+
+ if (2 != i2c_master_send(ov5642_data.i2c_client, au8RegBuf, 2)) {
+ pr_err("%s:write reg error:reg=%x\n",
+ __func__, reg);
+ return -1;
+ }
+
+ if (1 != i2c_master_recv(ov5642_data.i2c_client, &u8RdVal, 1)) {
+ pr_err("%s:read reg error:reg=%x,val=%x\n",
+ __func__, reg, u8RdVal);
+ return -1;
+ }
+
+ *val = u8RdVal;
+
+ return u8RdVal;
+}
+
+static int ov5642_set_rot_mode(struct reg_value *rot_mode)
+{
+ s32 i = 0;
+ s32 iModeSettingArySize = 2;
+ register u32 Delay_ms = 0;
+ register u16 RegAddr = 0;
+ register u8 Mask = 0;
+ register u8 Val = 0;
+ u8 RegVal = 0;
+ int retval = 0;
+ for (i = 0; i < iModeSettingArySize; ++i, ++rot_mode) {
+ Delay_ms = rot_mode->u32Delay_ms;
+ RegAddr = rot_mode->u16RegAddr;
+ Val = rot_mode->u8Val;
+ Mask = rot_mode->u8Mask;
+
+ if (Mask) {
+ retval = ov5642_read_reg(RegAddr, &RegVal);
+ if (retval < 0) {
+ pr_err("%s, read reg 0x%x failed\n",
+ __func__, RegAddr);
+ goto err;
+ }
+
+ Val |= RegVal;
+ Val &= Mask;
+ }
+
+ retval = ov5642_write_reg(RegAddr, Val);
+ if (retval < 0) {
+ pr_err("%s, write reg 0x%x failed\n",
+ __func__, RegAddr);
+ goto err;
+ }
+
+ if (Delay_ms)
+ mdelay(Delay_ms);
+ }
+err:
+ return retval;
+}
+static int ov5642_init_mode(enum ov5642_frame_rate frame_rate,
+ enum ov5642_mode mode);
+static int ov5642_write_snapshot_para(enum ov5642_frame_rate frame_rate,
+ enum ov5642_mode mode);
+static int ov5642_change_mode(enum ov5642_frame_rate new_frame_rate,
+ enum ov5642_frame_rate old_frame_rate,
+ enum ov5642_mode new_mode,
+ enum ov5642_mode orig_mode)
+{
+ struct reg_value *pModeSetting = NULL;
+ s32 i = 0;
+ s32 iModeSettingArySize = 0;
+ register u32 Delay_ms = 0;
+ register u16 RegAddr = 0;
+ register u8 Mask = 0;
+ register u8 Val = 0;
+ u8 RegVal = 0;
+ int retval = 0;
+
+ if (new_mode > ov5642_mode_MAX || new_mode < ov5642_mode_MIN) {
+ pr_err("Wrong ov5642 mode detected!\n");
+ return -1;
+ }
+
+ if ((new_frame_rate == old_frame_rate) &&
+ (new_mode == ov5642_mode_VGA_640_480) &&
+ (orig_mode == ov5642_mode_QSXGA_2592_1944)) {
+ pModeSetting = ov5642_setting_QSXGA_2_VGA;
+ iModeSettingArySize = ARRAY_SIZE(ov5642_setting_QSXGA_2_VGA);
+ ov5642_data.pix.width = 640;
+ ov5642_data.pix.height = 480;
+ } else if ((new_frame_rate == old_frame_rate) &&
+ (new_mode == ov5642_mode_QVGA_320_240) &&
+ (orig_mode == ov5642_mode_VGA_640_480)) {
+ pModeSetting = ov5642_setting_VGA_2_QVGA;
+ iModeSettingArySize = ARRAY_SIZE(ov5642_setting_VGA_2_QVGA);
+ ov5642_data.pix.width = 320;
+ ov5642_data.pix.height = 240;
+ } else {
+ retval = ov5642_write_snapshot_para(new_frame_rate, new_mode);
+ goto err;
+ }
+
+ if (ov5642_data.pix.width == 0 || ov5642_data.pix.height == 0 ||
+ pModeSetting == NULL || iModeSettingArySize == 0)
+ return -EINVAL;
+
+ for (i = 0; i < iModeSettingArySize; ++i, ++pModeSetting) {
+ Delay_ms = pModeSetting->u32Delay_ms;
+ RegAddr = pModeSetting->u16RegAddr;
+ Val = pModeSetting->u8Val;
+ Mask = pModeSetting->u8Mask;
+
+ if (Mask) {
+ retval = ov5642_read_reg(RegAddr, &RegVal);
+ if (retval < 0) {
+ pr_err("read reg error addr=0x%x", RegAddr);
+ goto err;
+ }
+
+ RegVal &= ~(u8)Mask;
+ Val &= Mask;
+ Val |= RegVal;
+ }
+
+ retval = ov5642_write_reg(RegAddr, Val);
+ if (retval < 0) {
+ pr_err("write reg error addr=0x%x", RegAddr);
+ goto err;
+ }
+
+ if (Delay_ms)
+ msleep(Delay_ms);
+ }
+err:
+ return retval;
+}
+static int ov5642_init_mode(enum ov5642_frame_rate frame_rate,
+ enum ov5642_mode mode)
+{
+ struct reg_value *pModeSetting = NULL;
+ s32 i = 0;
+ s32 iModeSettingArySize = 0;
+ register u32 Delay_ms = 0;
+ register u16 RegAddr = 0;
+ register u8 Mask = 0;
+ register u8 Val = 0;
+ u8 RegVal = 0;
+ int retval = 0;
+
+ if (mode > ov5642_mode_MAX || mode < ov5642_mode_MIN) {
+ pr_err("Wrong ov5642 mode detected!\n");
+ return -1;
+ }
+
+ pModeSetting = ov5642_mode_info_data[frame_rate][mode].init_data_ptr;
+ iModeSettingArySize =
+ ov5642_mode_info_data[frame_rate][mode].init_data_size;
+
+ ov5642_data.pix.width = ov5642_mode_info_data[frame_rate][mode].width;
+ ov5642_data.pix.height = ov5642_mode_info_data[frame_rate][mode].height;
+
+ if (ov5642_data.pix.width == 0 || ov5642_data.pix.height == 0 ||
+ pModeSetting == NULL || iModeSettingArySize == 0)
+ return -EINVAL;
+
+ for (i = 0; i < iModeSettingArySize; ++i, ++pModeSetting) {
+ Delay_ms = pModeSetting->u32Delay_ms;
+ RegAddr = pModeSetting->u16RegAddr;
+ Val = pModeSetting->u8Val;
+ Mask = pModeSetting->u8Mask;
+
+ if (Mask) {
+ retval = ov5642_read_reg(RegAddr, &RegVal);
+ if (retval < 0) {
+ pr_err("read reg error addr=0x%x", RegAddr);
+ goto err;
+ }
+
+ RegVal &= ~(u8)Mask;
+ Val &= Mask;
+ Val |= RegVal;
+ }
+
+ retval = ov5642_write_reg(RegAddr, Val);
+ if (retval < 0) {
+ pr_err("write reg error addr=0x%x", RegAddr);
+ goto err;
+ }
+
+ if (Delay_ms)
+ msleep(Delay_ms);
+ }
+err:
+ return retval;
+}
+
+static int ov5642_write_snapshot_para(enum ov5642_frame_rate frame_rate,
+ enum ov5642_mode mode)
+{
+ int ret = 0;
+ bool m_60Hz = false;
+ u16 cap_frame_rate = 50;
+ u16 g_prev_frame_rate = 225;
+
+ u8 ev_low, ev_mid, ev_high;
+ u8 ret_l, ret_m, ret_h, gain, lines_10ms;
+ u16 ulcap_ev, icap_gain, prev_maxlines;
+ u32 ulcap_ev_gain, cap_maxlines, g_prev_ev;
+
+ ov5642_write_reg(0x3503, 0x07);
+
+ ret_h = ret_m = ret_l = 0;
+ g_prev_ev = 0;
+ ov5642_read_reg(0x3500, &ret_h);
+ ov5642_read_reg(0x3501, &ret_m);
+ ov5642_read_reg(0x3502, &ret_l);
+ g_prev_ev = (ret_h << 12) + (ret_m << 4) + (ret_l >> 4);
+
+ ret_h = ret_m = ret_l = 0;
+ prev_maxlines = 0;
+ ov5642_read_reg(0x380e, &ret_h);
+ ov5642_read_reg(0x380f, &ret_l);
+ prev_maxlines = (ret_h << 8) + ret_l;
+ /*Read back AGC Gain for preview*/
+ gain = 0;
+ ov5642_read_reg(0x350b, &gain);
+
+ ret = ov5642_init_mode(frame_rate, mode);
+ if (ret < 0)
+ return ret;
+
+ ret_h = ret_m = ret_l = 0;
+ ov5642_read_reg(0x380e, &ret_h);
+ ov5642_read_reg(0x380f, &ret_l);
+ cap_maxlines = (ret_h << 8) + ret_l;
+ if (m_60Hz == true)
+ lines_10ms = cap_frame_rate * cap_maxlines/12000;
+ else
+ lines_10ms = cap_frame_rate * cap_maxlines/10000;
+
+ if (prev_maxlines == 0)
+ prev_maxlines = 1;
+
+ ulcap_ev = (g_prev_ev*(cap_frame_rate)*(cap_maxlines))/
+ (((prev_maxlines)*(g_prev_frame_rate)));
+ icap_gain = (gain & 0x0f) + 16;
+ if (gain & 0x10)
+ icap_gain = icap_gain << 1;
+
+ if (gain & 0x20)
+ icap_gain = icap_gain << 1;
+
+ if (gain & 0x40)
+ icap_gain = icap_gain << 1;
+
+ if (gain & 0x80)
+ icap_gain = icap_gain << 1;
+
+ ulcap_ev_gain = 2 * ulcap_ev * icap_gain;
+
+ if (ulcap_ev_gain < cap_maxlines*16) {
+ ulcap_ev = ulcap_ev_gain/16;
+ if (ulcap_ev > lines_10ms) {
+ ulcap_ev /= lines_10ms;
+ ulcap_ev *= lines_10ms;
+ }
+ } else
+ ulcap_ev = cap_maxlines;
+
+ if (ulcap_ev == 0)
+ ulcap_ev = 1;
+
+ icap_gain = (ulcap_ev_gain*2/ulcap_ev + 1)/2;
+ ev_low = ((unsigned char)ulcap_ev)<<4;
+ ev_mid = (unsigned char)(ulcap_ev >> 4) & 0xff;
+ ev_high = (unsigned char)(ulcap_ev >> 12);
+
+ gain = 0;
+ if (icap_gain > 31) {
+ gain |= 0x10;
+ icap_gain = icap_gain >> 1;
+ }
+ if (icap_gain > 31) {
+ gain |= 0x20;
+ icap_gain = icap_gain >> 1;
+ }
+ if (icap_gain > 31) {
+ gain |= 0x40;
+ icap_gain = icap_gain >> 1;
+ }
+ if (icap_gain > 31) {
+ gain |= 0x80;
+ icap_gain = icap_gain >> 1;
+ }
+ if (icap_gain > 16)
+ gain |= ((icap_gain - 16) & 0x0f);
+
+ if (gain == 0x10)
+ gain = 0x11;
+
+ ov5642_write_reg(0x350b, gain);
+ ov5642_write_reg(0x3502, ev_low);
+ ov5642_write_reg(0x3501, ev_mid);
+ ov5642_write_reg(0x3500, ev_high);
+ msleep(500);
+
+ return ret ;
+}
+
+
+/* --------------- IOCTL functions from v4l2_int_ioctl_desc --------------- */
+
+static int ioctl_g_ifparm(struct v4l2_int_device *s, struct v4l2_ifparm *p)
+{
+ if (s == NULL) {
+ pr_err(" ERROR!! no slave device set!\n");
+ return -1;
+ }
+
+ memset(p, 0, sizeof(*p));
+ p->u.bt656.clock_curr = ov5642_data.mclk;
+ pr_debug(" clock_curr=mclk=%d\n", ov5642_data.mclk);
+ p->if_type = V4L2_IF_TYPE_BT656;
+ p->u.bt656.mode = V4L2_IF_TYPE_BT656_MODE_NOBT_8BIT;
+ p->u.bt656.clock_min = OV5642_XCLK_MIN;
+ p->u.bt656.clock_max = OV5642_XCLK_MAX;
+ p->u.bt656.bt_sync_correct = 1; /* Indicate external vsync */
+
+ return 0;
+}
+
+/*!
+ * ioctl_s_power - V4L2 sensor interface handler for VIDIOC_S_POWER ioctl
+ * @s: pointer to standard V4L2 device structure
+ * @on: indicates power mode (on or off)
+ *
+ * Turns the power on or off, depending on the value of on and returns the
+ * appropriate error code.
+ */
+static int ioctl_s_power(struct v4l2_int_device *s, int on)
+{
+ struct sensor_data *sensor = s->priv;
+
+ if (on && !sensor->on) {
+ if (io_regulator)
+ if (regulator_enable(io_regulator) != 0)
+ return -EIO;
+ if (core_regulator)
+ if (regulator_enable(core_regulator) != 0)
+ return -EIO;
+ if (gpo_regulator)
+ if (regulator_enable(gpo_regulator) != 0)
+ return -EIO;
+ if (analog_regulator)
+ if (regulator_enable(analog_regulator) != 0)
+ return -EIO;
+ /* Make sure power on */
+ ov5642_standby(0);
+ } else if (!on && sensor->on) {
+ if (analog_regulator)
+ regulator_disable(analog_regulator);
+ if (core_regulator)
+ regulator_disable(core_regulator);
+ if (io_regulator)
+ regulator_disable(io_regulator);
+ if (gpo_regulator)
+ regulator_disable(gpo_regulator);
+
+ ov5642_standby(1);
+ }
+
+ sensor->on = on;
+
+ return 0;
+}
+
+/*!
+ * ioctl_g_parm - V4L2 sensor interface handler for VIDIOC_G_PARM ioctl
+ * @s: pointer to standard V4L2 device structure
+ * @a: pointer to standard V4L2 VIDIOC_G_PARM ioctl structure
+ *
+ * Returns the sensor's video CAPTURE parameters.
+ */
+static int ioctl_g_parm(struct v4l2_int_device *s, struct v4l2_streamparm *a)
+{
+ struct sensor_data *sensor = s->priv;
+ struct v4l2_captureparm *cparm = &a->parm.capture;
+ int ret = 0;
+
+ switch (a->type) {
+ /* This is the only case currently handled. */
+ case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+ memset(a, 0, sizeof(*a));
+ a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ cparm->capability = sensor->streamcap.capability;
+ cparm->timeperframe = sensor->streamcap.timeperframe;
+ cparm->capturemode = sensor->streamcap.capturemode;
+ ret = 0;
+ break;
+
+ /* These are all the possible cases. */
+ case V4L2_BUF_TYPE_VIDEO_OUTPUT:
+ case V4L2_BUF_TYPE_VIDEO_OVERLAY:
+ case V4L2_BUF_TYPE_VBI_CAPTURE:
+ case V4L2_BUF_TYPE_VBI_OUTPUT:
+ case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
+ case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
+ ret = -EINVAL;
+ break;
+
+ default:
+ pr_debug(" type is unknown - %d\n", a->type);
+ ret = -EINVAL;
+ break;
+ }
+
+ return ret;
+}
+
+/*!
+ * ioctl_s_parm - V4L2 sensor interface handler for VIDIOC_S_PARM ioctl
+ * @s: pointer to standard V4L2 device structure
+ * @a: pointer to standard V4L2 VIDIOC_S_PARM ioctl structure
+ *
+ * Configures the sensor to use the input parameters, if possible. If
+ * not possible, reverts to the old parameters and returns the
+ * appropriate error code.
+ */
+static int ioctl_s_parm(struct v4l2_int_device *s, struct v4l2_streamparm *a)
+{
+ struct sensor_data *sensor = s->priv;
+ struct v4l2_fract *timeperframe = &a->parm.capture.timeperframe;
+ u32 tgt_fps, old_fps; /* target frames per secound */
+ enum ov5642_frame_rate new_frame_rate, old_frame_rate;
+ int ret = 0;
+
+ /* Make sure power on */
+ ov5642_standby(0);
+
+ switch (a->type) {
+ /* This is the only case currently handled. */
+ case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+ /* Check that the new frame rate is allowed. */
+ if ((timeperframe->numerator == 0) ||
+ (timeperframe->denominator == 0)) {
+ timeperframe->denominator = DEFAULT_FPS;
+ timeperframe->numerator = 1;
+ }
+
+ tgt_fps = timeperframe->denominator /
+ timeperframe->numerator;
+
+ if (tgt_fps > MAX_FPS) {
+ timeperframe->denominator = MAX_FPS;
+ timeperframe->numerator = 1;
+ } else if (tgt_fps < MIN_FPS) {
+ timeperframe->denominator = MIN_FPS;
+ timeperframe->numerator = 1;
+ }
+
+ /* Actual frame rate we use */
+ tgt_fps = timeperframe->denominator /
+ timeperframe->numerator;
+
+ if (tgt_fps == 15)
+ new_frame_rate = ov5642_15_fps;
+ else if (tgt_fps == 30)
+ new_frame_rate = ov5642_30_fps;
+ else {
+ pr_err(" The camera frame rate is not supported!\n");
+ return -EINVAL;
+ }
+
+ if (sensor->streamcap.timeperframe.numerator != 0)
+ old_fps = sensor->streamcap.timeperframe.denominator /
+ sensor->streamcap.timeperframe.numerator;
+ else
+ old_fps = 30;
+
+ if (old_fps == 15)
+ old_frame_rate = ov5642_15_fps;
+ else if (old_fps == 30)
+ old_frame_rate = ov5642_30_fps;
+ else {
+ pr_warning(" No valid frame rate set!\n");
+ old_frame_rate = ov5642_30_fps;
+ }
+
+ ret = ov5642_change_mode(new_frame_rate, old_frame_rate,
+ a->parm.capture.capturemode,
+ sensor->streamcap.capturemode);
+ if (ret < 0)
+ return ret;
+
+ sensor->streamcap.timeperframe = *timeperframe;
+ sensor->streamcap.capturemode =
+ (u32)a->parm.capture.capturemode;
+ break;
+
+ /* These are all the possible cases. */
+ case V4L2_BUF_TYPE_VIDEO_OUTPUT:
+ case V4L2_BUF_TYPE_VIDEO_OVERLAY:
+ case V4L2_BUF_TYPE_VBI_CAPTURE:
+ case V4L2_BUF_TYPE_VBI_OUTPUT:
+ case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
+ case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
+ pr_debug(" type is not " \
+ "V4L2_BUF_TYPE_VIDEO_CAPTURE but %d\n",
+ a->type);
+ ret = -EINVAL;
+ break;
+
+ default:
+ pr_debug(" type is unknown - %d\n", a->type);
+ ret = -EINVAL;
+ break;
+ }
+
+ return ret;
+}
+
+/*!
+ * ioctl_g_fmt_cap - V4L2 sensor interface handler for ioctl_g_fmt_cap
+ * @s: pointer to standard V4L2 device structure
+ * @f: pointer to standard V4L2 v4l2_format structure
+ *
+ * Returns the sensor's current pixel format in the v4l2_format
+ * parameter.
+ */
+static int ioctl_g_fmt_cap(struct v4l2_int_device *s, struct v4l2_format *f)
+{
+ struct sensor_data *sensor = s->priv;
+
+ f->fmt.pix = sensor->pix;
+
+ return 0;
+}
+
+/*!
+ * ioctl_g_ctrl - V4L2 sensor interface handler for VIDIOC_G_CTRL ioctl
+ * @s: pointer to standard V4L2 device structure
+ * @vc: standard V4L2 VIDIOC_G_CTRL ioctl structure
+ *
+ * If the requested control is supported, returns the control's current
+ * value from the video_control[] array. Otherwise, returns -EINVAL
+ * if the control is not supported.
+ */
+static int ioctl_g_ctrl(struct v4l2_int_device *s, struct v4l2_control *vc)
+{
+ int ret = 0;
+
+ switch (vc->id) {
+ case V4L2_CID_BRIGHTNESS:
+ vc->value = ov5642_data.brightness;
+ break;
+ case V4L2_CID_HUE:
+ vc->value = ov5642_data.hue;
+ break;
+ case V4L2_CID_CONTRAST:
+ vc->value = ov5642_data.contrast;
+ break;
+ case V4L2_CID_SATURATION:
+ vc->value = ov5642_data.saturation;
+ break;
+ case V4L2_CID_RED_BALANCE:
+ vc->value = ov5642_data.red;
+ break;
+ case V4L2_CID_BLUE_BALANCE:
+ vc->value = ov5642_data.blue;
+ break;
+ case V4L2_CID_EXPOSURE:
+ vc->value = ov5642_data.ae_mode;
+ break;
+ default:
+ ret = -EINVAL;
+ }
+
+ return ret;
+}
+
+/*!
+ * ioctl_s_ctrl - V4L2 sensor interface handler for VIDIOC_S_CTRL ioctl
+ * @s: pointer to standard V4L2 device structure
+ * @vc: standard V4L2 VIDIOC_S_CTRL ioctl structure
+ *
+ * If the requested control is supported, sets the control's current
+ * value in HW (and updates the video_control[] array). Otherwise,
+ * returns -EINVAL if the control is not supported.
+ */
+static int ioctl_s_ctrl(struct v4l2_int_device *s, struct v4l2_control *vc)
+{
+ int retval = 0;
+ struct sensor_data *sensor = s->priv;
+ __u32 captureMode = sensor->streamcap.capturemode;
+ struct reg_value *rot_mode = NULL;
+
+ pr_debug("In ov5642:ioctl_s_ctrl %d\n",
+ vc->id);
+
+ switch (vc->id) {
+ case V4L2_CID_BRIGHTNESS:
+ break;
+ case V4L2_CID_CONTRAST:
+ break;
+ case V4L2_CID_SATURATION:
+ break;
+ case V4L2_CID_HUE:
+ break;
+ case V4L2_CID_AUTO_WHITE_BALANCE:
+ break;
+ case V4L2_CID_DO_WHITE_BALANCE:
+ break;
+ case V4L2_CID_RED_BALANCE:
+ break;
+ case V4L2_CID_BLUE_BALANCE:
+ break;
+ case V4L2_CID_GAMMA:
+ break;
+ case V4L2_CID_EXPOSURE:
+ break;
+ case V4L2_CID_AUTOGAIN:
+ break;
+ case V4L2_CID_GAIN:
+ break;
+ case V4L2_CID_HFLIP:
+ break;
+ case V4L2_CID_VFLIP:
+ break;
+ case V4L2_CID_MXC_ROT:
+ case V4L2_CID_MXC_VF_ROT:
+ switch (vc->value) {
+ case V4L2_MXC_ROTATE_NONE:
+ if (captureMode == ov5642_mode_QSXGA_2592_1944)
+ rot_mode = ov5642_rot_none_FULL;
+ else
+ rot_mode = ov5642_rot_none_VGA;
+
+ if (ov5642_set_rot_mode(rot_mode))
+ retval = -EPERM;
+ break;
+ case V4L2_MXC_ROTATE_VERT_FLIP:
+ if (captureMode == ov5642_mode_QSXGA_2592_1944)
+ rot_mode = ov5642_rot_vert_flip_FULL;
+ else
+ rot_mode = ov5642_rot_vert_flip_VGA ;
+
+ if (ov5642_set_rot_mode(rot_mode))
+ retval = -EPERM;
+ break;
+ case V4L2_MXC_ROTATE_HORIZ_FLIP:
+ if (captureMode == ov5642_mode_QSXGA_2592_1944)
+ rot_mode = ov5642_rot_horiz_flip_FULL;
+ else
+ rot_mode = ov5642_rot_horiz_flip_VGA;
+
+ if (ov5642_set_rot_mode(rot_mode))
+ retval = -EPERM;
+ break;
+ case V4L2_MXC_ROTATE_180:
+ if (captureMode == ov5642_mode_QSXGA_2592_1944)
+ rot_mode = ov5642_rot_180_FULL;
+ else
+ rot_mode = ov5642_rot_180_VGA;
+
+ if (ov5642_set_rot_mode(rot_mode))
+ retval = -EPERM;
+ break;
+ default:
+ retval = -EPERM;
+ break;
+ }
+ break;
+ default:
+ retval = -EPERM;
+ break;
+ }
+
+ return retval;
+}
+
+/*!
+ * ioctl_enum_framesizes - V4L2 sensor interface handler for
+ * VIDIOC_ENUM_FRAMESIZES ioctl
+ * @s: pointer to standard V4L2 device structure
+ * @fsize: standard V4L2 VIDIOC_ENUM_FRAMESIZES ioctl structure
+ *
+ * Return 0 if successful, otherwise -EINVAL.
+ */
+static int ioctl_enum_framesizes(struct v4l2_int_device *s,
+ struct v4l2_frmsizeenum *fsize)
+{
+ if (fsize->index > ov5642_mode_MAX)
+ return -EINVAL;
+
+ fsize->pixel_format = ov5642_data.pix.pixelformat;
+ fsize->discrete.width =
+ max(ov5642_mode_info_data[0][fsize->index].width,
+ ov5642_mode_info_data[1][fsize->index].width);
+ fsize->discrete.height =
+ max(ov5642_mode_info_data[0][fsize->index].height,
+ ov5642_mode_info_data[1][fsize->index].height);
+ return 0;
+}
+
+/*!
+ * ioctl_enum_frameintervals - V4L2 sensor interface handler for
+ * VIDIOC_ENUM_FRAMEINTERVALS ioctl
+ * @s: pointer to standard V4L2 device structure
+ * @fival: standard V4L2 VIDIOC_ENUM_FRAMEINTERVALS ioctl structure
+ *
+ * Return 0 if successful, otherwise -EINVAL.
+ */
+static int ioctl_enum_frameintervals(struct v4l2_int_device *s,
+ struct v4l2_frmivalenum *fival)
+{
+ int i, j, count;
+
+ if (fival->index < 0 || fival->index > ov5642_mode_MAX)
+ return -EINVAL;
+
+ if (fival->pixel_format == 0 || fival->width == 0 ||
+ fival->height == 0) {
+ pr_warning("Please assign pixelformat, width and height.\n");
+ return -EINVAL;
+ }
+
+ fival->type = V4L2_FRMIVAL_TYPE_DISCRETE;
+ fival->discrete.numerator = 1;
+
+ count = 0;
+ for (i = 0; i < ARRAY_SIZE(ov5642_mode_info_data); i++) {
+ for (j = 0; j < (ov5642_mode_MAX + 1); j++) {
+ if (fival->pixel_format == ov5642_data.pix.pixelformat
+ && fival->width == ov5642_mode_info_data[i][j].width
+ && fival->height == ov5642_mode_info_data[i][j].height
+ && ov5642_mode_info_data[i][j].init_data_ptr != NULL) {
+ count++;
+ }
+ if (fival->index == (count - 1)) {
+ fival->discrete.denominator =
+ ov5642_framerates[i];
+ return 0;
+ }
+ }
+ }
+
+ return -EINVAL;
+}
+
+/*!
+ * ioctl_g_chip_ident - V4L2 sensor interface handler for
+ * VIDIOC_DBG_G_CHIP_IDENT ioctl
+ * @s: pointer to standard V4L2 device structure
+ * @id: pointer to int
+ *
+ * Return 0.
+ */
+static int ioctl_g_chip_ident(struct v4l2_int_device *s, int *id)
+{
+ ((struct v4l2_dbg_chip_ident *)id)->match.type =
+ V4L2_CHIP_MATCH_I2C_DRIVER;
+ strcpy(((struct v4l2_dbg_chip_ident *)id)->match.name, "ov5642_camera");
+
+ return 0;
+}
+
+/*!
+ * ioctl_init - V4L2 sensor interface handler for VIDIOC_INT_INIT
+ * @s: pointer to standard V4L2 device structure
+ */
+static int ioctl_init(struct v4l2_int_device *s)
+{
+
+ return 0;
+}
+
+/*!
+ * ioctl_enum_fmt_cap - V4L2 sensor interface handler for VIDIOC_ENUM_FMT
+ * @s: pointer to standard V4L2 device structure
+ * @fmt: pointer to standard V4L2 fmt description structure
+ *
+ * Return 0.
+ */
+static int ioctl_enum_fmt_cap(struct v4l2_int_device *s,
+ struct v4l2_fmtdesc *fmt)
+{
+ if (fmt->index > 0) /* only 1 pixelformat support so far */
+ return -EINVAL;
+
+ fmt->pixelformat = ov5642_data.pix.pixelformat;
+
+ return 0;
+}
+
+/*!
+ * ioctl_dev_init - V4L2 sensor interface handler for vidioc_int_dev_init_num
+ * @s: pointer to standard V4L2 device structure
+ *
+ * Initialise the device when slave attaches to the master.
+ */
+static int ioctl_dev_init(struct v4l2_int_device *s)
+{
+ struct reg_value *pModeSetting = NULL;
+ s32 i = 0;
+ s32 iModeSettingArySize = 0;
+ register u32 Delay_ms = 0;
+ register u16 RegAddr = 0;
+ register u8 Mask = 0;
+ register u8 Val = 0;
+ u8 RegVal = 0;
+ int retval = 0;
+
+ struct sensor_data *sensor = s->priv;
+ u32 tgt_xclk; /* target xclk */
+ u32 tgt_fps; /* target frames per secound */
+ enum ov5642_frame_rate frame_rate;
+
+ ov5642_data.on = true;
+
+ /* mclk */
+ tgt_xclk = ov5642_data.mclk;
+ tgt_xclk = min(tgt_xclk, (u32)OV5642_XCLK_MAX);
+ tgt_xclk = max(tgt_xclk, (u32)OV5642_XCLK_MIN);
+ ov5642_data.mclk = tgt_xclk;
+
+ pr_debug(" Setting mclk to %d MHz\n", tgt_xclk / 1000000);
+
+ /* Default camera frame rate is set in probe */
+ tgt_fps = sensor->streamcap.timeperframe.denominator /
+ sensor->streamcap.timeperframe.numerator;
+
+ if (tgt_fps == 15)
+ frame_rate = ov5642_15_fps;
+ else if (tgt_fps == 30)
+ frame_rate = ov5642_30_fps;
+ else
+ return -EINVAL; /* Only support 15fps or 30fps now. */
+
+ pModeSetting = ov5642_initial_setting;
+ iModeSettingArySize = ARRAY_SIZE(ov5642_initial_setting);
+
+ for (i = 0; i < iModeSettingArySize; ++i, ++pModeSetting) {
+ Delay_ms = pModeSetting->u32Delay_ms;
+ RegAddr = pModeSetting->u16RegAddr;
+ Val = pModeSetting->u8Val;
+ Mask = pModeSetting->u8Mask;
+ if (Mask) {
+ retval = ov5642_read_reg(RegAddr, &RegVal);
+ if (retval < 0)
+ goto err;
+
+ RegVal &= ~(u8)Mask;
+ Val &= Mask;
+ Val |= RegVal;
+ }
+
+ retval = ov5642_write_reg(RegAddr, Val);
+ if (retval < 0)
+ goto err;
+
+ if (Delay_ms)
+ msleep(Delay_ms);
+ }
+err:
+ return retval;
+}
+
+/*!
+ * ioctl_dev_exit - V4L2 sensor interface handler for vidioc_int_dev_exit_num
+ * @s: pointer to standard V4L2 device structure
+ *
+ * Delinitialise the device when slave detaches to the master.
+ */
+static int ioctl_dev_exit(struct v4l2_int_device *s)
+{
+ return 0;
+}
+
+/*!
+ * This structure defines all the ioctls for this module and links them to the
+ * enumeration.
+ */
+static struct v4l2_int_ioctl_desc ov5642_ioctl_desc[] = {
+ { vidioc_int_dev_init_num,
+ (v4l2_int_ioctl_func *)ioctl_dev_init },
+ { vidioc_int_dev_exit_num, ioctl_dev_exit},
+ { vidioc_int_s_power_num,
+ (v4l2_int_ioctl_func *)ioctl_s_power },
+ { vidioc_int_g_ifparm_num,
+ (v4l2_int_ioctl_func *)ioctl_g_ifparm },
+/* { vidioc_int_g_needs_reset_num,
+ (v4l2_int_ioctl_func *)ioctl_g_needs_reset }, */
+/* { vidioc_int_reset_num,
+ (v4l2_int_ioctl_func *)ioctl_reset }, */
+ { vidioc_int_init_num,
+ (v4l2_int_ioctl_func *)ioctl_init },
+ { vidioc_int_enum_fmt_cap_num,
+ (v4l2_int_ioctl_func *)ioctl_enum_fmt_cap },
+/* { vidioc_int_try_fmt_cap_num,
+ (v4l2_int_ioctl_func *)ioctl_try_fmt_cap }, */
+ { vidioc_int_g_fmt_cap_num,
+ (v4l2_int_ioctl_func *)ioctl_g_fmt_cap },
+/* { vidioc_int_s_fmt_cap_num,
+ (v4l2_int_ioctl_func *)ioctl_s_fmt_cap }, */
+ { vidioc_int_g_parm_num,
+ (v4l2_int_ioctl_func *)ioctl_g_parm },
+ { vidioc_int_s_parm_num,
+ (v4l2_int_ioctl_func *)ioctl_s_parm },
+/* { vidioc_int_queryctrl_num,
+ (v4l2_int_ioctl_func *)ioctl_queryctrl }, */
+ { vidioc_int_g_ctrl_num,
+ (v4l2_int_ioctl_func *)ioctl_g_ctrl },
+ { vidioc_int_s_ctrl_num,
+ (v4l2_int_ioctl_func *)ioctl_s_ctrl },
+ { vidioc_int_enum_framesizes_num,
+ (v4l2_int_ioctl_func *)ioctl_enum_framesizes },
+ { vidioc_int_enum_frameintervals_num,
+ (v4l2_int_ioctl_func *)ioctl_enum_frameintervals },
+ { vidioc_int_g_chip_ident_num,
+ (v4l2_int_ioctl_func *)ioctl_g_chip_ident },
+};
+
+static struct v4l2_int_slave ov5642_slave = {
+ .ioctls = ov5642_ioctl_desc,
+ .num_ioctls = ARRAY_SIZE(ov5642_ioctl_desc),
+};
+
+static struct v4l2_int_device ov5642_int_device = {
+ .module = THIS_MODULE,
+ .name = "ov5642",
+ .type = v4l2_int_type_slave,
+ .u = {
+ .slave = &ov5642_slave,
+ },
+};
+
+/*!
+ * ov5642 I2C probe function
+ *
+ * @param adapter struct i2c_adapter *
+ * @return Error code indicating success or failure
+ */
+static int ov5642_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct pinctrl *pinctrl;
+ struct device *dev = &client->dev;
+ int retval;
+ u8 chip_id_high, chip_id_low;
+
+ /* ov5642 pinctrl */
+ pinctrl = devm_pinctrl_get_select_default(dev);
+ if (IS_ERR(pinctrl)) {
+ dev_err(dev, "ov5642 setup pinctrl failed!");
+ return PTR_ERR(pinctrl);
+ }
+
+ /* request power down pin */
+ pwn_gpio = of_get_named_gpio(dev->of_node, "pwn-gpios", 0);
+ if (!gpio_is_valid(pwn_gpio)) {
+ dev_warn(dev, "no sensor pwdn pin available");
+ return -EINVAL;
+ }
+ retval = devm_gpio_request_one(dev, pwn_gpio, GPIOF_OUT_INIT_HIGH,
+ "ov5642_pwdn");
+ if (retval < 0)
+ return retval;
+
+ /* request reset pin */
+ rst_gpio = of_get_named_gpio(dev->of_node, "rst-gpios", 0);
+ if (!gpio_is_valid(rst_gpio)) {
+ dev_warn(dev, "no sensor reset pin available");
+ return -EINVAL;
+ }
+ retval = devm_gpio_request_one(dev, rst_gpio, GPIOF_OUT_INIT_HIGH,
+ "ov5642_reset");
+ if (retval < 0)
+ return retval;
+
+ /* Set initial values for the sensor struct. */
+ memset(&ov5642_data, 0, sizeof(ov5642_data));
+ ov5642_data.sensor_clk = devm_clk_get(dev, "csi_mclk");
+ if (IS_ERR(ov5642_data.sensor_clk)) {
+ /* assuming clock enabled by default */
+ ov5642_data.sensor_clk = NULL;
+ dev_err(dev, "clock-frequency missing or invalid\n");
+ return PTR_ERR(ov5642_data.sensor_clk);
+ }
+
+ retval = of_property_read_u32(dev->of_node, "mclk",
+ (u32 *) &(ov5642_data.mclk));
+ if (retval) {
+ dev_err(dev, "mclk missing or invalid\n");
+ return retval;
+ }
+
+ retval = of_property_read_u32(dev->of_node, "mclk_source",
+ (u32 *) &(ov5642_data.mclk_source));
+ if (retval) {
+ dev_err(dev, "mclk_source missing or invalid\n");
+ return retval;
+ }
+
+ retval = of_property_read_u32(dev->of_node, "csi_id",
+ &(ov5642_data.csi));
+ if (retval) {
+ dev_err(dev, "csi_id missing or invalid\n");
+ return retval;
+ }
+
+ clk_prepare_enable(ov5642_data.sensor_clk);
+
+ ov5642_data.io_init = ov5642_reset;
+ ov5642_data.i2c_client = client;
+ ov5642_data.pix.pixelformat = V4L2_PIX_FMT_YUYV;
+ ov5642_data.pix.width = 640;
+ ov5642_data.pix.height = 480;
+ ov5642_data.streamcap.capability = V4L2_MODE_HIGHQUALITY |
+ V4L2_CAP_TIMEPERFRAME;
+ ov5642_data.streamcap.capturemode = 0;
+ ov5642_data.streamcap.timeperframe.denominator = DEFAULT_FPS;
+ ov5642_data.streamcap.timeperframe.numerator = 1;
+
+ ov5642_power_on(&client->dev);
+
+ ov5642_reset();
+
+ ov5642_standby(0);
+
+ retval = ov5642_read_reg(OV5642_CHIP_ID_HIGH_BYTE, &chip_id_high);
+ if (retval < 0 || chip_id_high != 0x56) {
+ pr_warning("camera ov5642 is not found\n");
+ clk_disable_unprepare(ov5642_data.sensor_clk);
+ return -ENODEV;
+ }
+ retval = ov5642_read_reg(OV5642_CHIP_ID_LOW_BYTE, &chip_id_low);
+ if (retval < 0 || chip_id_low != 0x42) {
+ pr_warning("camera ov5642 is not found\n");
+ clk_disable_unprepare(ov5642_data.sensor_clk);
+ return -ENODEV;
+ }
+
+ ov5642_standby(1);
+
+ ov5642_int_device.priv = &ov5642_data;
+ retval = v4l2_int_device_register(&ov5642_int_device);
+
+ clk_disable_unprepare(ov5642_data.sensor_clk);
+
+ pr_info("camera ov5642 is found\n");
+ return retval;
+}
+
+/*!
+ * ov5642 I2C detach function
+ *
+ * @param client struct i2c_client *
+ * @return Error code indicating success or failure
+ */
+static int ov5642_remove(struct i2c_client *client)
+{
+ v4l2_int_device_unregister(&ov5642_int_device);
+
+ if (gpo_regulator)
+ regulator_disable(gpo_regulator);
+
+ if (analog_regulator)
+ regulator_disable(analog_regulator);
+
+ if (core_regulator)
+ regulator_disable(core_regulator);
+
+ if (io_regulator)
+ regulator_disable(io_regulator);
+
+ return 0;
+}
+
+/*!
+ * ov5642 init function
+ * Called by insmod ov5642_camera.ko.
+ *
+ * @return Error code indicating success or failure
+ */
+static __init int ov5642_init(void)
+{
+ u8 err;
+
+ err = i2c_add_driver(&ov5642_i2c_driver);
+ if (err != 0)
+ pr_err("%s:driver registration failed, error=%d\n",
+ __func__, err);
+
+ return err;
+}
+
+/*!
+ * OV5642 cleanup function
+ * Called on rmmod ov5642_camera.ko
+ *
+ * @return Error code indicating success or failure
+ */
+static void __exit ov5642_clean(void)
+{
+ i2c_del_driver(&ov5642_i2c_driver);
+}
+
+module_init(ov5642_init);
+module_exit(ov5642_clean);
+
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("OV5642 Camera Driver");
+MODULE_LICENSE("GPL");
+MODULE_VERSION("1.0");
+MODULE_ALIAS("CSI");
diff --git a/drivers/media/platform/mxc/capture/ov5647_mipi.c b/drivers/media/platform/mxc/capture/ov5647_mipi.c
new file mode 100644
index 000000000000..109f77438f51
--- /dev/null
+++ b/drivers/media/platform/mxc/capture/ov5647_mipi.c
@@ -0,0 +1,1721 @@
+/*
+ * Copyright (C) 2011-2015 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/ctype.h>
+#include <linux/types.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/of_device.h>
+#include <linux/i2c.h>
+#include <linux/of_gpio.h>
+#include <linux/pinctrl/consumer.h>
+#include <linux/regulator/consumer.h>
+#include <linux/v4l2-mediabus.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-ctrls.h>
+
+#define OV5647_VOLTAGE_ANALOG 2800000
+#define OV5647_VOLTAGE_DIGITAL_CORE 1500000
+#define OV5647_VOLTAGE_DIGITAL_IO 1800000
+
+#define MIN_FPS 15
+#define MAX_FPS 30
+#define DEFAULT_FPS 30
+
+#define OV5647_XCLK_MIN 6000000
+#define OV5647_XCLK_MAX 24000000
+
+#define OV5647_CHIP_ID_HIGH_BYTE 0x300A
+#define OV5647_CHIP_ID_LOW_BYTE 0x300B
+
+enum ov5647_mode {
+ ov5647_mode_MIN = 0,
+ ov5647_mode_VGA_640_480 = 0,
+ ov5647_mode_720P_1280_720 = 1,
+ ov5647_mode_1080P_1920_1080 = 2,
+ ov5647_mode_QSXGA_2592_1944 = 3,
+ ov5647_mode_MAX = 3,
+ ov5647_mode_INIT = 0xff, /*only for sensor init*/
+};
+
+enum ov5647_frame_rate {
+ ov5647_15_fps,
+ ov5647_30_fps
+};
+
+static int ov5647_framerates[] = {
+ [ov5647_15_fps] = 15,
+ [ov5647_30_fps] = 30,
+};
+
+struct ov5647_datafmt {
+ u32 code;
+ enum v4l2_colorspace colorspace;
+};
+
+/* image size under 1280 * 960 are SUBSAMPLING
+ * image size upper 1280 * 960 are SCALING
+ */
+enum ov5647_downsize_mode {
+ SUBSAMPLING,
+ SCALING,
+};
+
+struct reg_value {
+ u16 u16RegAddr;
+ u8 u8Val;
+ u8 u8Mask;
+ u32 u32Delay_ms;
+};
+
+struct ov5647_mode_info {
+ enum ov5647_mode mode;
+ enum ov5647_downsize_mode dn_mode;
+ u32 width;
+ u32 height;
+ struct reg_value *init_data_ptr;
+ u32 init_data_size;
+};
+
+struct otp_struct {
+ int customer_id;
+ int module_integrator_id;
+ int lens_id;
+ int rg_ratio;
+ int bg_ratio;
+ int user_data[3];
+ int light_rg;
+ int light_bg;
+};
+
+struct ov5647 {
+ struct v4l2_subdev subdev;
+ struct i2c_client *i2c_client;
+ struct v4l2_pix_format pix;
+ const struct ov5647_datafmt *fmt;
+ struct v4l2_captureparm streamcap;
+ bool on;
+
+ /* control settings */
+ int brightness;
+ int hue;
+ int contrast;
+ int saturation;
+ int red;
+ int green;
+ int blue;
+ int ae_mode;
+
+ u32 mclk;
+ u8 mclk_source;
+ struct clk *sensor_clk;
+ int csi;
+
+ void (*io_init)(void);
+};
+/*!
+ * Maintains the information on the current state of the sesor.
+ */
+static struct ov5647 ov5647_data;
+static int pwn_gpio, rst_gpio;
+static int prev_sysclk, prev_HTS;
+static int AE_low, AE_high, AE_Target = 52;
+
+/* R/G and B/G of typical camera module is defined here,
+ * the typical camera module is selected by CameraAnalyzer. */
+static int RG_Ratio_Typical = 0x70;
+static int BG_Ratio_Typical = 0x70;
+
+
+static struct reg_value ov5647_init_setting[] = {
+
+ {0x0100, 0x00, 0, 0}, {0x3035, 0x11, 0, 0},
+ {0x3036, 0x69, 0, 0}, {0x303c, 0x11, 0, 0}, {0x3821, 0x07, 0, 0},
+ {0x3820, 0x41, 0, 0}, {0x370c, 0x0f, 0, 0}, {0x3612, 0x59, 0, 0},
+ {0x3618, 0x00, 0, 0}, {0x5000, 0x06, 0, 0}, {0x5002, 0x40, 0, 0},
+ {0x5003, 0x08, 0, 0}, {0x5a00, 0x08, 0, 0}, {0x3000, 0xff, 0, 0},
+ {0x3001, 0xff, 0, 0}, {0x3002, 0xff, 0, 0}, {0x301d, 0xf0, 0, 0},
+ {0x3a18, 0x00, 0, 0}, {0x3a19, 0xf8, 0, 0}, {0x3c01, 0x80, 0, 0},
+ {0x3b07, 0x0c, 0, 0}, {0x380c, 0x07, 0, 0}, {0x380d, 0x68, 0, 0},
+ {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0}, {0x3814, 0x31, 0, 0},
+ {0x3815, 0x31, 0, 0}, {0x3708, 0x64, 0, 0}, {0x3709, 0x52, 0, 0},
+ {0x3808, 0x05, 0, 0}, {0x3809, 0x00, 0, 0}, {0x380a, 0x03, 0, 0},
+ {0x380b, 0xc0, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x18, 0, 0},
+ {0x3802, 0x00, 0, 0}, {0x3803, 0x0e, 0, 0}, {0x3804, 0x0a, 0, 0},
+ {0x3805, 0x27, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x95, 0, 0},
+ {0x3630, 0x2e, 0, 0}, {0x3632, 0xe2, 0, 0}, {0x3633, 0x23, 0, 0},
+ {0x3634, 0x44, 0, 0}, {0x3620, 0x64, 0, 0}, {0x3621, 0xe0, 0, 0},
+ {0x3600, 0x37, 0, 0}, {0x3704, 0xa0, 0, 0}, {0x3703, 0x5a, 0, 0},
+ {0x3715, 0x78, 0, 0}, {0x3717, 0x01, 0, 0}, {0x3731, 0x02, 0, 0},
+ {0x370b, 0x60, 0, 0}, {0x3705, 0x1a, 0, 0}, {0x3f05, 0x02, 0, 0},
+ {0x3f06, 0x10, 0, 0}, {0x3f01, 0x0a, 0, 0}, {0x3a08, 0x01, 0, 0},
+ {0x3a09, 0x27, 0, 0}, {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0},
+ {0x3a0d, 0x04, 0, 0}, {0x3a0e, 0x03, 0, 0}, {0x3a0f, 0x58, 0, 0},
+ {0x3a10, 0x50, 0, 0}, {0x3a1b, 0x58, 0, 0}, {0x3a1e, 0x50, 0, 0},
+ {0x3a11, 0x60, 0, 0}, {0x3a1f, 0x28, 0, 0}, {0x4001, 0x02, 0, 0},
+ {0x4004, 0x02, 0, 0}, {0x4000, 0x09, 0, 0}, {0x4050, 0x6e, 0, 0},
+ {0x4051, 0x8f, 0, 0}, {0x4837, 0x17, 0, 0}, {0x3503, 0x03, 0, 0},
+ {0x3501, 0x44, 0, 0}, {0x3502, 0x80, 0, 0}, {0x350a, 0x00, 0, 0},
+ {0x350b, 0x7f, 0, 0}, {0x5001, 0x01, 0, 0}, {0x5002, 0x41, 0, 0},
+ {0x5180, 0x08, 0, 0}, {0x5186, 0x04, 0, 0}, {0x5187, 0x00, 0, 0},
+ {0x5188, 0x04, 0, 0}, {0x5189, 0x00, 0, 0}, {0x518a, 0x04, 0, 0},
+ {0x518b, 0x00, 0, 0}, {0x5000, 0x86, 0, 0}, {0x5800, 0x11, 0, 0},
+ {0x5801, 0x0a, 0, 0}, {0x5802, 0x09, 0, 0}, {0x5803, 0x09, 0, 0},
+ {0x5804, 0x0a, 0, 0}, {0x5805, 0x0f, 0, 0}, {0x5806, 0x07, 0, 0},
+ {0x5807, 0x05, 0, 0}, {0x5808, 0x03, 0, 0}, {0x5809, 0x03, 0, 0},
+ {0x580a, 0x05, 0, 0}, {0x580b, 0x07, 0, 0}, {0x580c, 0x05, 0, 0},
+ {0x580d, 0x02, 0, 0}, {0x580e, 0x00, 0, 0}, {0x580f, 0x00, 0, 0},
+ {0x5810, 0x02, 0, 0}, {0x5811, 0x05, 0, 0}, {0x5812, 0x05, 0, 0},
+ {0x5813, 0x02, 0, 0}, {0x5814, 0x00, 0, 0}, {0x5815, 0x00, 0, 0},
+ {0x5816, 0x01, 0, 0}, {0x5817, 0x05, 0, 0}, {0x5818, 0x08, 0, 0},
+ {0x5819, 0x05, 0, 0}, {0x581a, 0x03, 0, 0}, {0x581b, 0x03, 0, 0},
+ {0x581c, 0x04, 0, 0}, {0x581d, 0x07, 0, 0}, {0x581e, 0x10, 0, 0},
+ {0x581f, 0x0b, 0, 0}, {0x5820, 0x09, 0, 0}, {0x5821, 0x09, 0, 0},
+ {0x5822, 0x09, 0, 0}, {0x5823, 0x0e, 0, 0}, {0x5824, 0x28, 0, 0},
+ {0x5825, 0x1a, 0, 0}, {0x5826, 0x1a, 0, 0}, {0x5827, 0x1a, 0, 0},
+ {0x5828, 0x46, 0, 0}, {0x5829, 0x2a, 0, 0}, {0x582a, 0x26, 0, 0},
+ {0x582b, 0x44, 0, 0}, {0x582c, 0x26, 0, 0}, {0x582d, 0x2a, 0, 0},
+ {0x582e, 0x28, 0, 0}, {0x582f, 0x42, 0, 0}, {0x5830, 0x40, 0, 0},
+ {0x5831, 0x42, 0, 0}, {0x5832, 0x28, 0, 0}, {0x5833, 0x0a, 0, 0},
+ {0x5834, 0x16, 0, 0}, {0x5835, 0x44, 0, 0}, {0x5836, 0x26, 0, 0},
+ {0x5837, 0x2a, 0, 0}, {0x5838, 0x28, 0, 0}, {0x5839, 0x0a, 0, 0},
+ {0x583a, 0x0a, 0, 0}, {0x583b, 0x0a, 0, 0}, {0x583c, 0x26, 0, 0},
+ {0x583d, 0xbe, 0, 0}, {0x0100, 0x01, 0, 0}, {0x3000, 0x00, 0, 0},
+ {0x3001, 0x00, 0, 0}, {0x3002, 0x00, 0, 0}, {0x3017, 0xe0, 0, 0},
+ {0x301c, 0xfc, 0, 0}, {0x3636, 0x06, 0, 0}, {0x3016, 0x08, 0, 0},
+ {0x3827, 0xec, 0, 0}, {0x3018, 0x44, 0, 0}, {0x3035, 0x21, 0, 0},
+ {0x3106, 0xf5, 0, 0}, {0x3034, 0x18, 0, 0}, {0x301c, 0xf8, 0, 0},
+};
+
+static struct reg_value ov5647_setting_60fps_VGA_640_480[] = {
+ {0x0100, 0x00, 0, 0}, {0x3035, 0x11, 0, 0},
+ {0x3036, 0x46, 0, 0}, {0x303c, 0x11, 0, 0}, {0x3821, 0x07, 0, 0},
+ {0x3820, 0x41, 0, 0}, {0x370c, 0x0f, 0, 0}, {0x3612, 0x59, 0, 0},
+ {0x3618, 0x00, 0, 0}, {0x5000, 0x06, 0, 0}, {0x5002, 0x40, 0, 0},
+ {0x5003, 0x08, 0, 0}, {0x5a00, 0x08, 0, 0}, {0x3000, 0xff, 0, 0},
+ {0x3001, 0xff, 0, 0}, {0x3002, 0xff, 0, 0}, {0x301d, 0xf0, 0, 0},
+ {0x3a18, 0x00, 0, 0}, {0x3a19, 0xf8, 0, 0}, {0x3c01, 0x80, 0, 0},
+ {0x3b07, 0x0c, 0, 0}, {0x380c, 0x07, 0, 0}, {0x380d, 0x3c, 0, 0},
+ {0x380e, 0x01, 0, 0}, {0x380f, 0xf8, 0, 0}, {0x3814, 0x71, 0, 0},
+ {0x3815, 0x71, 0, 0}, {0x3708, 0x64, 0, 0}, {0x3709, 0x52, 0, 0},
+ {0x3808, 0x02, 0, 0}, {0x3809, 0x80, 0, 0}, {0x380a, 0x01, 0, 0},
+ {0x380b, 0xe0, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x10, 0, 0},
+ {0x3802, 0x00, 0, 0}, {0x3803, 0x00, 0, 0}, {0x3804, 0x0a, 0, 0},
+ {0x3805, 0x2f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9f, 0, 0},
+ {0x3630, 0x2e, 0, 0}, {0x3632, 0xe2, 0, 0}, {0x3633, 0x23, 0, 0},
+ {0x3634, 0x44, 0, 0}, {0x3620, 0x64, 0, 0}, {0x3621, 0xe0, 0, 0},
+ {0x3600, 0x37, 0, 0}, {0x3704, 0xa0, 0, 0}, {0x3703, 0x5a, 0, 0},
+ {0x3715, 0x78, 0, 0}, {0x3717, 0x01, 0, 0}, {0x3731, 0x02, 0, 0},
+ {0x370b, 0x60, 0, 0}, {0x3705, 0x1a, 0, 0}, {0x3f05, 0x02, 0, 0},
+ {0x3f06, 0x10, 0, 0}, {0x3f01, 0x0a, 0, 0}, {0x3a08, 0x01, 0, 0},
+ {0x3a09, 0x2e, 0, 0}, {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xfb, 0, 0},
+ {0x3a0d, 0x02, 0, 0}, {0x3a0e, 0x01, 0, 0}, {0x3a0f, 0x58, 0, 0},
+ {0x3a10, 0x50, 0, 0}, {0x3a1b, 0x58, 0, 0}, {0x3a1e, 0x50, 0, 0},
+ {0x3a11, 0x60, 0, 0}, {0x3a1f, 0x28, 0, 0}, {0x4001, 0x02, 0, 0},
+ {0x4004, 0x02, 0, 0}, {0x4000, 0x09, 0, 0}, {0x4050, 0x6e, 0, 0},
+ {0x4051, 0x8f, 0, 0}, {0x0100, 0x01, 0, 0}, {0x3000, 0x00, 0, 0},
+ {0x3001, 0x00, 0, 0}, {0x3002, 0x00, 0, 0}, {0x3017, 0xe0, 0, 0},
+ {0x301c, 0xfc, 0, 0}, {0x3636, 0x06, 0, 0}, {0x3016, 0x08, 0, 0},
+ {0x3827, 0xec, 0, 0}, {0x3018, 0x44, 0, 0}, {0x3035, 0x21, 0, 0},
+ {0x3106, 0xf5, 0, 0}, {0x3034, 0x18, 0, 0}, {0x301c, 0xf8, 0, 0},
+};
+
+static struct reg_value ov5647_setting_30fps_720P_1280_720[] = {
+ {0x0100, 0x00, 0, 0}, {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0},
+ {0x3612, 0x59, 0, 0}, {0x3618, 0x00, 0, 0}, {0x380c, 0x09, 0, 0},
+ {0x380d, 0xe8, 0, 0}, {0x380e, 0x04, 0, 0}, {0x380f, 0x50, 0, 0},
+ {0x3814, 0x31, 0, 0}, {0x3815, 0x31, 0, 0}, {0x3709, 0x52, 0, 0},
+ {0x3808, 0x05, 0, 0}, {0x3809, 0x00, 0, 0}, {0x380a, 0x02, 0, 0},
+ {0x380b, 0xd0, 0, 0}, {0x3801, 0x18, 0, 0}, {0x3802, 0x00, 0, 0},
+ {0x3803, 0xf8, 0, 0}, {0x3804, 0x0a, 0, 0}, {0x3805, 0x27, 0, 0},
+ {0x3806, 0x06, 0, 0}, {0x3807, 0xa7, 0, 0}, {0x3a09, 0xbe, 0, 0},
+ {0x3a0a, 0x01, 0, 0}, {0x3a0b, 0x74, 0, 0}, {0x3a0d, 0x02, 0, 0},
+ {0x3a0e, 0x01, 0, 0}, {0x4004, 0x02, 0, 0}, {0x4005, 0x18, 0, 0},
+ {0x0100, 0x01, 0, 0},
+};
+
+static struct reg_value ov5647_setting_30fps_1080P_1920_1080[] = {
+ {0x0100, 0x00, 0, 0}, {0x3820, 0x00, 0, 0}, {0x3821, 0x06, 0, 0},
+ {0x3612, 0x5b, 0, 0}, {0x3618, 0x04, 0, 0}, {0x380c, 0x09, 0, 0},
+ {0x380d, 0xe8, 0, 0}, {0x380e, 0x04, 0, 0}, {0x380f, 0x50, 0, 0},
+ {0x3814, 0x11, 0, 0}, {0x3815, 0x11, 0, 0}, {0x3709, 0x12, 0, 0},
+ {0x3808, 0x07, 0, 0}, {0x3809, 0x80, 0, 0}, {0x380a, 0x04, 0, 0},
+ {0x380b, 0x38, 0, 0}, {0x3801, 0x5c, 0, 0}, {0x3802, 0x01, 0, 0},
+ {0x3803, 0xb2, 0, 0}, {0x3804, 0x08, 0, 0}, {0x3805, 0xe3, 0, 0},
+ {0x3806, 0x05, 0, 0}, {0x3807, 0xf1, 0, 0}, {0x3a09, 0x4b, 0, 0},
+ {0x3a0a, 0x01, 0, 0}, {0x3a0b, 0x13, 0, 0}, {0x3a0d, 0x04, 0, 0},
+ {0x3a0e, 0x03, 0, 0}, {0x4004, 0x04, 0, 0}, {0x4005, 0x18, 0, 0},
+ {0x0100, 0x01, 0, 0},
+};
+
+static struct reg_value ov5647_setting_15fps_QSXGA_2592_1944[] = {
+ {0x0100, 0x00, 0, 0}, {0x3820, 0x00, 0, 0}, {0x3821, 0x06, 0, 0},
+ {0x3612, 0x5b, 0, 0}, {0x3618, 0x04, 0, 0}, {0x380c, 0x0b, 0, 0},
+ {0x380d, 0x10, 0, 0}, {0x380e, 0x07, 0, 0}, {0x380f, 0xb8, 0, 0},
+ {0x3814, 0x11, 0, 0}, {0x3815, 0x11, 0, 0}, {0x3709, 0x12, 0, 0},
+ {0x3808, 0x0a, 0, 0}, {0x3809, 0x20, 0, 0}, {0x380a, 0x07, 0, 0},
+ {0x380b, 0x98, 0, 0}, {0x3801, 0x0c, 0, 0}, {0x3802, 0x00, 0, 0},
+ {0x3803, 0x04, 0, 0}, {0x3804, 0x0a, 0, 0}, {0x3805, 0x33, 0, 0},
+ {0x3806, 0x07, 0, 0}, {0x3807, 0xa3, 0, 0}, {0x3a09, 0x28, 0, 0},
+ {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0d, 0x08, 0, 0},
+ {0x3a0e, 0x06, 0, 0}, {0x4004, 0x04, 0, 0}, {0x4005, 0x1a, 0, 0},
+ {0x0100, 0x01, 0, 0},
+};
+
+static struct ov5647_mode_info ov5647_mode_info_data[2][ov5647_mode_MAX + 1] = {
+ {
+ {ov5647_mode_VGA_640_480, -1, 0, 0, NULL, 0},
+ {ov5647_mode_720P_1280_720, -1, 0, 0, NULL, 0},
+ {ov5647_mode_1080P_1920_1080, -1, 0, 0, NULL, 0},
+ {ov5647_mode_QSXGA_2592_1944, SCALING, 2592, 1944,
+ ov5647_setting_15fps_QSXGA_2592_1944,
+ ARRAY_SIZE(ov5647_setting_15fps_QSXGA_2592_1944)},
+ },
+ {
+ /* Actually VGA working in 60fps mode */
+ {ov5647_mode_VGA_640_480, SUBSAMPLING, 640, 480,
+ ov5647_setting_60fps_VGA_640_480,
+ ARRAY_SIZE(ov5647_setting_60fps_VGA_640_480)},
+ {ov5647_mode_720P_1280_720, SUBSAMPLING, 1280, 720,
+ ov5647_setting_30fps_720P_1280_720,
+ ARRAY_SIZE(ov5647_setting_30fps_720P_1280_720)},
+ {ov5647_mode_1080P_1920_1080, SCALING, 1920, 1080,
+ ov5647_setting_30fps_1080P_1920_1080,
+ ARRAY_SIZE(ov5647_setting_30fps_1080P_1920_1080)},
+ {ov5647_mode_QSXGA_2592_1944, -1, 0, 0, NULL, 0},
+ },
+};
+
+static struct regulator *io_regulator;
+static struct regulator *core_regulator;
+static struct regulator *analog_regulator;
+static struct regulator *gpo_regulator;
+
+static int ov5647_probe(struct i2c_client *adapter,
+ const struct i2c_device_id *device_id);
+static int ov5647_remove(struct i2c_client *client);
+
+static s32 ov5647_read_reg(u16 reg, u8 *val);
+static s32 ov5647_write_reg(u16 reg, u8 val);
+
+static const struct i2c_device_id ov5647_id[] = {
+ {"ov5647_mipi", 0},
+ {},
+};
+
+MODULE_DEVICE_TABLE(i2c, ov5647_id);
+
+static struct i2c_driver ov5647_i2c_driver = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "ov5647_mipi",
+ },
+ .probe = ov5647_probe,
+ .remove = ov5647_remove,
+ .id_table = ov5647_id,
+};
+
+static const struct ov5647_datafmt ov5647_colour_fmts[] = {
+ {MEDIA_BUS_FMT_SBGGR8_1X8, V4L2_COLORSPACE_JPEG},
+};
+
+static struct ov5647 *to_ov5647(const struct i2c_client *client)
+{
+ return container_of(i2c_get_clientdata(client), struct ov5647, subdev);
+}
+
+/* Find a data format by a pixel code in an array */
+static const struct ov5647_datafmt
+ *ov5647_find_datafmt(u32 code)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(ov5647_colour_fmts); i++)
+ if (ov5647_colour_fmts[i].code == code)
+ return ov5647_colour_fmts + i;
+
+ return NULL;
+}
+
+static inline void ov5647_power_down(int enable)
+{
+ if (pwn_gpio < 0)
+ return;
+
+ /* 19x19 pwdn pin invert by mipi daughter card */
+ if (!enable)
+ gpio_set_value_cansleep(pwn_gpio, 1);
+ else
+ gpio_set_value_cansleep(pwn_gpio, 0);
+
+ msleep(2);
+}
+
+static void ov5647_reset(void)
+{
+ if (rst_gpio < 0 || pwn_gpio < 0)
+ return;
+
+ /* camera reset */
+ gpio_set_value_cansleep(rst_gpio, 1);
+
+ /* camera power dowmn */
+ gpio_set_value_cansleep(pwn_gpio, 1);
+ msleep(5);
+
+ gpio_set_value_cansleep(pwn_gpio, 0);
+ msleep(5);
+
+ gpio_set_value_cansleep(rst_gpio, 0);
+ msleep(1);
+
+ gpio_set_value_cansleep(rst_gpio, 1);
+ msleep(5);
+
+ gpio_set_value_cansleep(pwn_gpio, 1);
+}
+
+static int ov5647_regulator_enable(struct device *dev)
+{
+ int ret = 0;
+
+ io_regulator = devm_regulator_get(dev, "DOVDD");
+ if (!IS_ERR(io_regulator)) {
+ regulator_set_voltage(io_regulator,
+ OV5647_VOLTAGE_DIGITAL_IO,
+ OV5647_VOLTAGE_DIGITAL_IO);
+ ret = regulator_enable(io_regulator);
+ if (ret) {
+ pr_err("%s:io set voltage error\n", __func__);
+ return ret;
+ } else {
+ dev_dbg(dev,
+ "%s:io set voltage ok\n", __func__);
+ }
+ } else {
+ pr_err("%s: cannot get io voltage error\n", __func__);
+ io_regulator = NULL;
+ }
+
+ core_regulator = devm_regulator_get(dev, "DVDD");
+ if (!IS_ERR(core_regulator)) {
+ regulator_set_voltage(core_regulator,
+ OV5647_VOLTAGE_DIGITAL_CORE,
+ OV5647_VOLTAGE_DIGITAL_CORE);
+ ret = regulator_enable(core_regulator);
+ if (ret) {
+ pr_err("%s:core set voltage error\n", __func__);
+ return ret;
+ } else {
+ dev_dbg(dev,
+ "%s:core set voltage ok\n", __func__);
+ }
+ } else {
+ core_regulator = NULL;
+ pr_err("%s: cannot get core voltage error\n", __func__);
+ }
+
+ analog_regulator = devm_regulator_get(dev, "AVDD");
+ if (!IS_ERR(analog_regulator)) {
+ regulator_set_voltage(analog_regulator,
+ OV5647_VOLTAGE_ANALOG,
+ OV5647_VOLTAGE_ANALOG);
+ ret = regulator_enable(analog_regulator);
+ if (ret) {
+ pr_err("%s:analog set voltage error\n",
+ __func__);
+ return ret;
+ } else {
+ dev_dbg(dev,
+ "%s:analog set voltage ok\n", __func__);
+ }
+ } else {
+ analog_regulator = NULL;
+ pr_err("%s: cannot get analog voltage error\n", __func__);
+ }
+
+ return ret;
+}
+
+static s32 ov5647_write_reg(u16 reg, u8 val)
+{
+ u8 au8Buf[3] = {0};
+
+ au8Buf[0] = reg >> 8;
+ au8Buf[1] = reg & 0xff;
+ au8Buf[2] = val;
+
+ if (i2c_master_send(ov5647_data.i2c_client, au8Buf, 3) < 0) {
+ pr_err("%s:write reg error:reg=%x,val=%x\n",
+ __func__, reg, val);
+ return -1;
+ }
+
+ return 0;
+}
+
+static s32 ov5647_read_reg(u16 reg, u8 *val)
+{
+ u8 au8RegBuf[2] = {0};
+ u8 u8RdVal = 0;
+
+ au8RegBuf[0] = reg >> 8;
+ au8RegBuf[1] = reg & 0xff;
+
+ if (2 != i2c_master_send(ov5647_data.i2c_client, au8RegBuf, 2)) {
+ pr_err("%s:write reg error:reg=%x\n",
+ __func__, reg);
+ return -1;
+ }
+
+ if (1 != i2c_master_recv(ov5647_data.i2c_client, &u8RdVal, 1)) {
+ pr_err("%s:read reg error:reg=%x,val=%x\n",
+ __func__, reg, u8RdVal);
+ return -1;
+ }
+
+ *val = u8RdVal;
+
+ return u8RdVal;
+}
+
+/* index: index of otp group. (0, 1, 2)
+ * return:
+ * 0, group index is empty
+ * 1, group index has invalid data
+ * 2, group index has valid data */
+static int ov5647_check_otp(int index)
+{
+ int i;
+ int address;
+ u8 temp;
+
+ /* read otp into buffer */
+ ov5647_write_reg(0x3d21, 0x01);
+ msleep(20);
+ address = 0x3d05 + index * 9;
+ temp = ov5647_read_reg(address, &temp);
+
+ /* disable otp read */
+ ov5647_write_reg(0x3d21, 0x00);
+
+ /* clear otp buffer */
+ for (i = 0; i < 32; i++)
+ ov5647_write_reg(0x3d00 + i, 0x00);
+
+ if (!temp)
+ return 0;
+ else if ((!(temp & 0x80)) && (temp & 0x7f))
+ return 2;
+ else
+ return 1;
+}
+
+/* index: index of otp group. (0, 1, 2)
+ * return: 0 */
+static int ov5647_read_otp(int index, struct otp_struct *otp_ptr)
+{
+ int i;
+ int address;
+ u8 temp;
+
+ /* read otp into buffer */
+ ov5647_write_reg(0x3d21, 0x01);
+ msleep(2);
+ address = 0x3d05 + index * 9;
+ temp = ov5647_read_reg(address, &temp);
+ (*otp_ptr).customer_id = temp & 0x7f;
+
+ (*otp_ptr).module_integrator_id = ov5647_read_reg(address, &temp);
+ (*otp_ptr).lens_id = ov5647_read_reg(address + 1, &temp);
+ (*otp_ptr).rg_ratio = ov5647_read_reg(address + 2, &temp);
+ (*otp_ptr).bg_ratio = ov5647_read_reg(address + 3, &temp);
+ (*otp_ptr).user_data[0] = ov5647_read_reg(address + 4, &temp);
+ (*otp_ptr).user_data[1] = ov5647_read_reg(address + 5, &temp);
+ (*otp_ptr).user_data[2] = ov5647_read_reg(address + 6, &temp);
+ (*otp_ptr).light_rg = ov5647_read_reg(address + 7, &temp);
+ (*otp_ptr).light_bg = ov5647_read_reg(address + 8, &temp);
+
+ /* disable otp read */
+ ov5647_write_reg(0x3d21, 0x00);
+
+ /* clear otp buffer */
+ for (i = 0; i < 32; i++)
+ ov5647_write_reg(0x3d00 + i, 0x00);
+
+ return 0;
+}
+
+/* R_gain, sensor red gain of AWB, 0x400 =1
+ * G_gain, sensor green gain of AWB, 0x400 =1
+ * B_gain, sensor blue gain of AWB, 0x400 =1
+ * return 0 */
+static int ov5647_update_awb_gain(int R_gain, int G_gain, int B_gain)
+{
+ if (R_gain > 0x400) {
+ ov5647_write_reg(0x5186, R_gain >> 8);
+ ov5647_write_reg(0x5187, R_gain & 0x00ff);
+ }
+ if (G_gain > 0x400) {
+ ov5647_write_reg(0x5188, G_gain >> 8);
+ ov5647_write_reg(0x5189, G_gain & 0x00ff);
+ }
+ if (B_gain > 0x400) {
+ ov5647_write_reg(0x518a, B_gain >> 8);
+ ov5647_write_reg(0x518b, B_gain & 0x00ff);
+ }
+
+ return 0;
+}
+
+/* call this function after OV5647 initialization
+ * return value:
+ * 0 update success
+ * 1 no OTP */
+static int ov5647_update_otp(void)
+{
+ struct otp_struct current_otp;
+ int i;
+ int otp_index;
+ int temp;
+ int R_gain, G_gain, B_gain, G_gain_R, G_gain_B;
+ int rg, bg;
+
+ /* R/G and B/G of current camera module is read out from sensor OTP
+ * check first OTP with valid data */
+ for (i = 0; i < 3; i++) {
+ temp = ov5647_check_otp(i);
+ if (temp == 2) {
+ otp_index = i;
+ break;
+ }
+ }
+ if (i == 3) {
+ /* no valid wb OTP data */
+ printk(KERN_WARNING "No valid wb otp data\n");
+ return 1;
+ }
+
+ ov5647_read_otp(otp_index, &current_otp);
+ if (current_otp.light_rg == 0)
+ rg = current_otp.rg_ratio;
+ else
+ rg = current_otp.rg_ratio * (current_otp.light_rg + 128) / 256;
+
+ if (current_otp.light_bg == 0)
+ bg = current_otp.bg_ratio;
+ else
+ bg = current_otp.bg_ratio * (current_otp.light_bg + 128) / 256;
+
+ /* calculate G gain
+ * 0x400 = 1x gain */
+ if (bg < BG_Ratio_Typical) {
+ if (rg < RG_Ratio_Typical) {
+ /* current_otp.bg_ratio < BG_Ratio_typical &&
+ * current_otp.rg_ratio < RG_Ratio_typical */
+ G_gain = 0x400;
+ B_gain = 0x400 * BG_Ratio_Typical / bg;
+ R_gain = 0x400 * RG_Ratio_Typical / rg;
+ } else {
+ /* current_otp.bg_ratio < BG_Ratio_typical &&
+ * current_otp.rg_ratio >= RG_Ratio_typical */
+ R_gain = 0x400;
+ G_gain = 0x400 * rg / RG_Ratio_Typical;
+ B_gain = G_gain * BG_Ratio_Typical / bg;
+ }
+ } else {
+ if (rg < RG_Ratio_Typical) {
+ /* current_otp.bg_ratio >= BG_Ratio_typical &&
+ * current_otp.rg_ratio < RG_Ratio_typical */
+ B_gain = 0x400;
+ G_gain = 0x400 * bg / BG_Ratio_Typical;
+ R_gain = G_gain * RG_Ratio_Typical / rg;
+ } else {
+ /* current_otp.bg_ratio >= BG_Ratio_typical &&
+ * current_otp.rg_ratio >= RG_Ratio_typical */
+ G_gain_B = 0x400 * bg / BG_Ratio_Typical;
+ G_gain_R = 0x400 * rg / RG_Ratio_Typical;
+ if (G_gain_B > G_gain_R) {
+ B_gain = 0x400;
+ G_gain = G_gain_B;
+ R_gain = G_gain * RG_Ratio_Typical / rg;
+ } else {
+ R_gain = 0x400;
+ G_gain = G_gain_R;
+ B_gain = G_gain * BG_Ratio_Typical / bg;
+ }
+ }
+ }
+ ov5647_update_awb_gain(R_gain, G_gain, B_gain);
+ return 0;
+}
+
+static void ov5647_stream_on(void)
+{
+ ov5647_write_reg(0x4202, 0x00);
+}
+
+static void ov5647_stream_off(void)
+{
+ ov5647_write_reg(0x4202, 0x0f);
+ /* both clock and data lane in LP00 */
+ ov5647_write_reg(0x0100, 0x00);
+}
+
+static int ov5647_get_sysclk(void)
+{
+ /* calculate sysclk */
+ int xvclk = ov5647_data.mclk / 10000;
+ int sysclk, temp1, temp2;
+ int pre_div02x, div_cnt7b, sdiv0, pll_rdiv, bit_div2x, sclk_div, VCO;
+ int pre_div02x_map[] = {2, 2, 4, 6, 8, 3, 12, 5, 16, 2, 2, 2, 2, 2, 2, 2};
+ int sdiv0_map[] = {16, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
+ int pll_rdiv_map[] = {1, 2};
+ int bit_div2x_map[] = {2, 2, 2, 2, 2, 2, 2, 2, 4, 2, 5, 2, 2, 2, 2, 2};
+ int sclk_div_map[] = {1, 2, 4, 1};
+ u8 temp;
+
+ temp1 = ov5647_read_reg(0x3037, &temp);
+ temp2 = temp1 & 0x0f;
+ pre_div02x = pre_div02x_map[temp2];
+ temp2 = (temp1 >> 4) & 0x01;
+ pll_rdiv = pll_rdiv_map[temp2];
+ temp1 = ov5647_read_reg(0x3036, &temp);
+
+ div_cnt7b = temp1;
+
+ VCO = xvclk * 2 / pre_div02x * div_cnt7b;
+ temp1 = ov5647_read_reg(0x3035, &temp);
+ temp2 = temp1 >> 4;
+ sdiv0 = sdiv0_map[temp2];
+ temp1 = ov5647_read_reg(0x3034, &temp);
+ temp2 = temp1 & 0x0f;
+ bit_div2x = bit_div2x_map[temp2];
+ temp1 = ov5647_read_reg(0x3106, &temp);
+ temp2 = (temp1 >> 2) & 0x03;
+ sclk_div = sclk_div_map[temp2];
+ sysclk = VCO * 2 / sdiv0 / pll_rdiv / bit_div2x / sclk_div;
+ return sysclk;
+}
+
+static void ov5647_set_night_mode(void)
+{
+ /* read HTS from register settings */
+ u8 mode;
+
+ ov5647_read_reg(0x3a00, &mode);
+ mode &= 0xfb;
+ ov5647_write_reg(0x3a00, mode);
+}
+
+static int ov5647_get_HTS(void)
+{
+ /* read HTS from register settings */
+ int HTS;
+ u8 temp;
+
+ HTS = ov5647_read_reg(0x380c, &temp);
+ HTS = (HTS << 8) + ov5647_read_reg(0x380d, &temp);
+
+ return HTS;
+}
+
+static int ov5647_soft_reset(void)
+{
+ /* soft reset ov5647 */
+
+ ov5647_write_reg(0x0103, 0x1);
+ msleep(5);
+
+ return 0;
+}
+
+static int ov5647_get_VTS(void)
+{
+ /* read VTS from register settings */
+ int VTS;
+ u8 temp;
+
+ /* total vertical size[15:8] high byte */
+ VTS = ov5647_read_reg(0x380e, &temp);
+
+ VTS = (VTS << 8) + ov5647_read_reg(0x380f, &temp);
+
+ return VTS;
+}
+
+static int ov5647_set_VTS(int VTS)
+{
+ /* write VTS to registers */
+ int temp;
+
+ temp = VTS & 0xff;
+ ov5647_write_reg(0x380f, temp);
+
+ temp = VTS >> 8;
+ ov5647_write_reg(0x380e, temp);
+
+ return 0;
+}
+
+static int ov5647_get_shutter(void)
+{
+ /* read shutter, in number of line period */
+ int shutter;
+ u8 temp;
+
+ shutter = (ov5647_read_reg(0x03500, &temp) & 0x0f);
+ shutter = (shutter << 8) + ov5647_read_reg(0x3501, &temp);
+ shutter = (shutter << 4) + (ov5647_read_reg(0x3502, &temp)>>4);
+
+ return shutter;
+}
+
+static int ov5647_set_shutter(int shutter)
+{
+ /* write shutter, in number of line period */
+ int temp;
+
+ shutter = shutter & 0xffff;
+
+ temp = shutter & 0x0f;
+ temp = temp << 4;
+ ov5647_write_reg(0x3502, temp);
+
+ temp = shutter & 0xfff;
+ temp = temp >> 4;
+ ov5647_write_reg(0x3501, temp);
+
+ temp = shutter >> 12;
+ ov5647_write_reg(0x3500, temp);
+
+ return 0;
+}
+
+static int ov5647_get_gain16(void)
+{
+ /* read gain, 16 = 1x */
+ int gain16;
+ u8 temp;
+
+ gain16 = ov5647_read_reg(0x350a, &temp) & 0x03;
+ gain16 = (gain16 << 8) + ov5647_read_reg(0x350b, &temp);
+
+ return gain16;
+}
+
+static int ov5647_set_gain16(int gain16)
+{
+ /* write gain, 16 = 1x */
+ u8 temp;
+ gain16 = gain16 & 0x3ff;
+
+ temp = gain16 & 0xff;
+ ov5647_write_reg(0x350b, temp);
+
+ temp = gain16 >> 8;
+ ov5647_write_reg(0x350a, temp);
+
+ return 0;
+}
+
+static int ov5647_get_light_freq(void)
+{
+ /* get banding filter value */
+ int temp, temp1, light_freq = 0;
+ u8 tmp;
+
+ temp = ov5647_read_reg(0x3c01, &tmp);
+
+ if (temp & 0x80) {
+ /* manual */
+ temp1 = ov5647_read_reg(0x3c00, &tmp);
+ if (temp1 & 0x04) {
+ /* 50Hz */
+ light_freq = 50;
+ } else {
+ /* 60Hz */
+ light_freq = 60;
+ }
+ } else {
+ /* auto */
+ temp1 = ov5647_read_reg(0x3c0c, &tmp);
+ if (temp1 & 0x01) {
+ /* 50Hz */
+ light_freq = 50;
+ } else {
+ /* 60Hz */
+ }
+ }
+ return light_freq;
+}
+
+static void ov5647_set_bandingfilter(void)
+{
+ int prev_VTS;
+ int band_step60, max_band60, band_step50, max_band50;
+
+ /* read preview PCLK */
+ prev_sysclk = ov5647_get_sysclk();
+ /* read preview HTS */
+ prev_HTS = ov5647_get_HTS();
+
+ /* read preview VTS */
+ prev_VTS = ov5647_get_VTS();
+
+ /* calculate banding filter */
+ /* 60Hz */
+ band_step60 = prev_sysclk * 100/prev_HTS * 100/120;
+ ov5647_write_reg(0x3a0a, (band_step60 >> 8));
+ ov5647_write_reg(0x3a0b, (band_step60 & 0xff));
+
+ max_band60 = (int)((prev_VTS-4)/band_step60);
+ ov5647_write_reg(0x3a0d, max_band60);
+
+ /* 50Hz */
+ band_step50 = prev_sysclk * 100/prev_HTS;
+ ov5647_write_reg(0x3a08, (band_step50 >> 8));
+ ov5647_write_reg(0x3a09, (band_step50 & 0xff));
+
+ max_band50 = (int)((prev_VTS-4)/band_step50);
+ ov5647_write_reg(0x3a0e, max_band50);
+}
+
+static int ov5647_set_AE_target(int target)
+{
+ /* stable in high */
+ int fast_high, fast_low;
+ AE_low = target * 23 / 25; /* 0.92 */
+ AE_high = target * 27 / 25; /* 1.08 */
+
+ fast_high = AE_high<<1;
+ if (fast_high > 255)
+ fast_high = 255;
+
+ fast_low = AE_low >> 1;
+
+ ov5647_write_reg(0x3a0f, AE_high);
+ ov5647_write_reg(0x3a10, AE_low);
+ ov5647_write_reg(0x3a1b, AE_high);
+ ov5647_write_reg(0x3a1e, AE_low);
+ ov5647_write_reg(0x3a11, fast_high);
+ ov5647_write_reg(0x3a1f, fast_low);
+
+ return 0;
+}
+
+static void ov5647_turn_on_AE_AG(int enable)
+{
+ u8 ae_ag_ctrl;
+
+ ov5647_read_reg(0x3503, &ae_ag_ctrl);
+ if (enable) {
+ /* turn on auto AE/AG */
+ ae_ag_ctrl = ae_ag_ctrl & ~(0x03);
+ } else {
+ /* turn off AE/AG */
+ ae_ag_ctrl = ae_ag_ctrl | 0x03;
+ }
+ ov5647_write_reg(0x3503, ae_ag_ctrl);
+}
+
+static void ov5647_set_virtual_channel(int channel)
+{
+ u8 channel_id;
+
+ ov5647_read_reg(0x4814, &channel_id);
+ channel_id &= ~(3 << 6);
+ ov5647_write_reg(0x4814, channel_id | (channel << 6));
+}
+
+/* download ov5647 settings to sensor through i2c */
+static int ov5647_download_firmware(struct reg_value *pModeSetting, s32 ArySize)
+{
+ register u32 Delay_ms = 0;
+ register u16 RegAddr = 0;
+ register u8 Mask = 0;
+ register u8 Val = 0;
+ u8 RegVal = 0;
+ int i, retval = 0;
+
+ for (i = 0; i < ArySize; ++i, ++pModeSetting) {
+ Delay_ms = pModeSetting->u32Delay_ms;
+ RegAddr = pModeSetting->u16RegAddr;
+ Val = pModeSetting->u8Val;
+ Mask = pModeSetting->u8Mask;
+
+ if (Mask) {
+ retval = ov5647_read_reg(RegAddr, &RegVal);
+ if (retval < 0)
+ goto err;
+
+ RegVal &= ~(u8)Mask;
+ Val &= Mask;
+ Val |= RegVal;
+ }
+
+ retval = ov5647_write_reg(RegAddr, Val);
+ if (retval < 0)
+ goto err;
+
+ if (Delay_ms)
+ msleep(Delay_ms);
+ }
+err:
+ return retval;
+}
+
+/* sensor changes between scaling and subsampling
+ * go through exposure calcualtion
+ */
+static int ov5647_change_mode_exposure_calc(enum ov5647_frame_rate frame_rate,
+ enum ov5647_mode mode)
+{
+ struct reg_value *pModeSetting = NULL;
+ s32 ArySize = 0;
+ int pre_shutter, pre_gain16;
+ int cap_shutter, cap_gain16;
+ int pre_sysclk, pre_HTS;
+ int cap_sysclk, cap_HTS, cap_VTS;
+ long cap_gain16_shutter;
+ int retval = 0;
+
+ /* check if the input mode and frame rate is valid */
+ pModeSetting =
+ ov5647_mode_info_data[frame_rate][mode].init_data_ptr;
+ ArySize =
+ ov5647_mode_info_data[frame_rate][mode].init_data_size;
+
+ ov5647_data.pix.width =
+ ov5647_mode_info_data[frame_rate][mode].width;
+ ov5647_data.pix.height =
+ ov5647_mode_info_data[frame_rate][mode].height;
+
+ if (ov5647_data.pix.width == 0 || ov5647_data.pix.height == 0 ||
+ pModeSetting == NULL || ArySize == 0)
+ return -EINVAL;
+
+ ov5647_stream_off();
+
+ /* turn off night mode for capture */
+ ov5647_set_night_mode();
+
+ pre_shutter = ov5647_get_shutter();
+ pre_gain16 = ov5647_get_gain16();
+ pre_HTS = ov5647_get_HTS();
+ pre_sysclk = ov5647_get_sysclk();
+
+ /* Write capture setting */
+ retval = ov5647_download_firmware(pModeSetting, ArySize);
+ if (retval < 0)
+ goto err;
+
+ /* read capture VTS */
+ cap_VTS = ov5647_get_VTS();
+ cap_HTS = ov5647_get_HTS();
+ cap_sysclk = ov5647_get_sysclk();
+
+ /* calculate capture shutter/gain16 */
+ cap_shutter = pre_shutter * cap_sysclk/pre_sysclk * pre_HTS / cap_HTS;
+
+ if (cap_shutter < 16) {
+ cap_gain16_shutter = pre_shutter * pre_gain16 *
+ cap_sysclk / pre_sysclk * pre_HTS / cap_HTS;
+ cap_shutter = ((int)(cap_gain16_shutter / 16));
+ if (cap_shutter < 1)
+ cap_shutter = 1;
+ cap_gain16 = ((int)(cap_gain16_shutter / cap_shutter));
+ if (cap_gain16 < 16)
+ cap_gain16 = 16;
+ } else
+ cap_gain16 = pre_gain16;
+
+ /* gain to shutter */
+ while ((cap_gain16 > 32) &&
+ (cap_shutter < ((int)((cap_VTS - 4) / 2)))) {
+ cap_gain16 = cap_gain16 / 2;
+ cap_shutter = cap_shutter * 2;
+ }
+ /* write capture gain */
+ ov5647_set_gain16(cap_gain16);
+
+ /* write capture shutter */
+ if (cap_shutter > (cap_VTS - 4)) {
+ cap_VTS = cap_shutter + 4;
+ ov5647_set_VTS(cap_VTS);
+ }
+ ov5647_set_shutter(cap_shutter);
+
+err:
+ return retval;
+}
+
+/* if sensor changes inside scaling or subsampling
+ * change mode directly
+ * */
+static int ov5647_change_mode_direct(enum ov5647_frame_rate frame_rate,
+ enum ov5647_mode mode)
+{
+ struct reg_value *pModeSetting = NULL;
+ s32 ArySize = 0;
+ int retval = 0;
+
+ /* check if the input mode and frame rate is valid */
+ pModeSetting =
+ ov5647_mode_info_data[frame_rate][mode].init_data_ptr;
+ ArySize =
+ ov5647_mode_info_data[frame_rate][mode].init_data_size;
+
+ ov5647_data.pix.width =
+ ov5647_mode_info_data[frame_rate][mode].width;
+ ov5647_data.pix.height =
+ ov5647_mode_info_data[frame_rate][mode].height;
+
+ if (ov5647_data.pix.width == 0 || ov5647_data.pix.height == 0 ||
+ pModeSetting == NULL || ArySize == 0)
+ return -EINVAL;
+
+ /* turn off AE/AG */
+ ov5647_turn_on_AE_AG(0);
+
+ ov5647_stream_off();
+
+ /* Write capture setting */
+ retval = ov5647_download_firmware(pModeSetting, ArySize);
+ if (retval < 0)
+ goto err;
+
+ ov5647_turn_on_AE_AG(1);
+
+err:
+ return retval;
+}
+
+static int ov5647_init_mode(enum ov5647_frame_rate frame_rate,
+ enum ov5647_mode mode, enum ov5647_mode orig_mode)
+{
+ struct reg_value *pModeSetting = NULL;
+ s32 ArySize = 0;
+ int retval = 0;
+ u32 msec_wait4stable = 0;
+ enum ov5647_downsize_mode dn_mode, orig_dn_mode;
+
+ if ((mode > ov5647_mode_MAX || mode < ov5647_mode_MIN)
+ && (mode != ov5647_mode_INIT)) {
+ pr_err("Wrong ov5647 mode detected!\n");
+ return -1;
+ }
+
+ dn_mode = ov5647_mode_info_data[frame_rate][mode].dn_mode;
+ orig_dn_mode = ov5647_mode_info_data[frame_rate][orig_mode].dn_mode;
+ if (mode == ov5647_mode_INIT) {
+ ov5647_soft_reset();
+ pModeSetting = ov5647_init_setting;
+ ArySize = ARRAY_SIZE(ov5647_init_setting);
+ retval = ov5647_download_firmware(pModeSetting, ArySize);
+ if (retval < 0)
+ goto err;
+ pModeSetting = ov5647_setting_60fps_VGA_640_480;
+ ArySize = ARRAY_SIZE(ov5647_setting_60fps_VGA_640_480);
+ retval = ov5647_download_firmware(pModeSetting, ArySize);
+
+ ov5647_data.pix.width = 640;
+ ov5647_data.pix.height = 480;
+ } else if ((dn_mode == SUBSAMPLING && orig_dn_mode == SCALING) ||
+ (dn_mode == SCALING && orig_dn_mode == SUBSAMPLING)) {
+ /* change between subsampling and scaling
+ * go through exposure calucation */
+ retval = ov5647_change_mode_exposure_calc(frame_rate, mode);
+ } else {
+ /* change inside subsampling or scaling
+ * download firmware directly */
+ retval = ov5647_change_mode_direct(frame_rate, mode);
+ }
+
+ if (retval < 0)
+ goto err;
+
+ ov5647_set_AE_target(AE_Target);
+ ov5647_get_light_freq();
+ ov5647_set_bandingfilter();
+ ov5647_set_virtual_channel(ov5647_data.csi);
+
+ /* add delay to wait for sensor stable */
+ if (mode == ov5647_mode_QSXGA_2592_1944) {
+ /* dump the first two frames: 1/7.5*2
+ * the frame rate of QSXGA is 7.5fps */
+ msec_wait4stable = 267;
+ } else if (frame_rate == ov5647_15_fps) {
+ /* dump the first nine frames: 1/15*9 */
+ msec_wait4stable = 600;
+ } else if (frame_rate == ov5647_30_fps) {
+ /* dump the first nine frames: 1/30*9 */
+ msec_wait4stable = 300;
+ }
+ msleep(msec_wait4stable);
+
+err:
+ return retval;
+}
+
+/*!
+ * ov5647_s_power - V4L2 sensor interface handler for VIDIOC_S_POWER ioctl
+ * @s: pointer to standard V4L2 device structure
+ * @on: indicates power mode (on or off)
+ *
+ * Turns the power on or off, depending on the value of on and returns the
+ * appropriate error code.
+ */
+static int ov5647_s_power(struct v4l2_subdev *sd, int on)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct ov5647 *sensor = to_ov5647(client);
+
+ if (on && !sensor->on) {
+ if (io_regulator)
+ if (regulator_enable(io_regulator) != 0)
+ return -EIO;
+ if (core_regulator)
+ if (regulator_enable(core_regulator) != 0)
+ return -EIO;
+ if (gpo_regulator)
+ if (regulator_enable(gpo_regulator) != 0)
+ return -EIO;
+ if (analog_regulator)
+ if (regulator_enable(analog_regulator) != 0)
+ return -EIO;
+ } else if (!on && sensor->on) {
+ if (analog_regulator)
+ regulator_disable(analog_regulator);
+ if (core_regulator)
+ regulator_disable(core_regulator);
+ if (io_regulator)
+ regulator_disable(io_regulator);
+ if (gpo_regulator)
+ regulator_disable(gpo_regulator);
+ }
+
+ sensor->on = on;
+
+ return 0;
+}
+
+/*!
+ * ov5647_g_parm - V4L2 sensor interface handler for VIDIOC_G_PARM ioctl
+ * @s: pointer to standard V4L2 sub device structure
+ * @a: pointer to standard V4L2 VIDIOC_G_PARM ioctl structure
+ *
+ * Returns the sensor's video CAPTURE parameters.
+ */
+static int ov5647_g_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *a)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct ov5647 *sensor = to_ov5647(client);
+ struct v4l2_captureparm *cparm = &a->parm.capture;
+ int ret = 0;
+
+ switch (a->type) {
+ /* This is the only case currently handled. */
+ case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+ memset(a, 0, sizeof(*a));
+ a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ cparm->capability = sensor->streamcap.capability;
+ cparm->timeperframe = sensor->streamcap.timeperframe;
+ cparm->capturemode = sensor->streamcap.capturemode;
+ ret = 0;
+ break;
+
+ /* These are all the possible cases. */
+ case V4L2_BUF_TYPE_VIDEO_OUTPUT:
+ case V4L2_BUF_TYPE_VIDEO_OVERLAY:
+ case V4L2_BUF_TYPE_VBI_CAPTURE:
+ case V4L2_BUF_TYPE_VBI_OUTPUT:
+ case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
+ case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
+ ret = -EINVAL;
+ break;
+
+ default:
+ pr_debug(" type is unknown - %d\n", a->type);
+ ret = -EINVAL;
+ break;
+ }
+
+ return ret;
+}
+
+/*!
+ * ov5460_s_parm - V4L2 sensor interface handler for VIDIOC_S_PARM ioctl
+ * @s: pointer to standard V4L2 sub device structure
+ * @a: pointer to standard V4L2 VIDIOC_S_PARM ioctl structure
+ *
+ * Configures the sensor to use the input parameters, if possible. If
+ * not possible, reverts to the old parameters and returns the
+ * appropriate error code.
+ */
+static int ov5647_s_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *a)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct ov5647 *sensor = to_ov5647(client);
+ struct v4l2_fract *timeperframe = &a->parm.capture.timeperframe;
+ u32 tgt_fps; /* target frames per secound */
+ enum ov5647_frame_rate frame_rate;
+ enum ov5647_mode orig_mode;
+ int ret = 0;
+
+ /* Make sure power on */
+ ov5647_power_down(0);
+
+ switch (a->type) {
+ /* This is the only case currently handled. */
+ case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+ /* Check that the new frame rate is allowed. */
+ if ((timeperframe->numerator == 0) ||
+ (timeperframe->denominator == 0)) {
+ timeperframe->denominator = DEFAULT_FPS;
+ timeperframe->numerator = 1;
+ }
+
+ tgt_fps = timeperframe->denominator /
+ timeperframe->numerator;
+
+ if (tgt_fps > MAX_FPS) {
+ timeperframe->denominator = MAX_FPS;
+ timeperframe->numerator = 1;
+ } else if (tgt_fps < MIN_FPS) {
+ timeperframe->denominator = MIN_FPS;
+ timeperframe->numerator = 1;
+ }
+
+ /* Actual frame rate we use */
+ tgt_fps = timeperframe->denominator /
+ timeperframe->numerator;
+
+ if (tgt_fps == 15)
+ frame_rate = ov5647_15_fps;
+ else if (tgt_fps == 30)
+ frame_rate = ov5647_30_fps;
+ else {
+ pr_err(" The camera frame rate is not supported!\n");
+ return -EINVAL;
+ }
+
+ orig_mode = sensor->streamcap.capturemode;
+ ret = ov5647_init_mode(frame_rate,
+ (u32)a->parm.capture.capturemode, orig_mode);
+ if (ret < 0)
+ return ret;
+
+ sensor->streamcap.timeperframe = *timeperframe;
+ sensor->streamcap.capturemode =
+ (u32)a->parm.capture.capturemode;
+
+ break;
+
+ /* These are all the possible cases. */
+ case V4L2_BUF_TYPE_VIDEO_OUTPUT:
+ case V4L2_BUF_TYPE_VIDEO_OVERLAY:
+ case V4L2_BUF_TYPE_VBI_CAPTURE:
+ case V4L2_BUF_TYPE_VBI_OUTPUT:
+ case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
+ case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
+ pr_debug("type is not " \
+ "V4L2_BUF_TYPE_VIDEO_CAPTURE but %d\n",
+ a->type);
+ ret = -EINVAL;
+ break;
+
+ default:
+ pr_debug("type is unknown - %d\n", a->type);
+ ret = -EINVAL;
+ break;
+ }
+
+ return ret;
+}
+
+static int ov5647_set_fmt(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_format *format)
+{
+ struct v4l2_mbus_framefmt *mf = &format->format;
+ const struct ov5647_datafmt *fmt = ov5647_find_datafmt(mf->code);
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct ov5647 *sensor = to_ov5647(client);
+
+ if (!fmt) {
+ mf->code = ov5647_colour_fmts[0].code;
+ mf->colorspace = ov5647_colour_fmts[0].colorspace;
+ }
+
+ mf->field = V4L2_FIELD_NONE;
+
+ if (format->which == V4L2_SUBDEV_FORMAT_TRY)
+ return 0;
+
+ sensor->fmt = fmt;
+
+ return 0;
+}
+
+static int ov5647_get_fmt(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_format *format)
+{
+ struct v4l2_mbus_framefmt *mf = &format->format;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct ov5647 *sensor = to_ov5647(client);
+ const struct ov5647_datafmt *fmt = sensor->fmt;
+
+ if (format->pad)
+ return -EINVAL;
+
+ mf->code = fmt->code;
+ mf->colorspace = fmt->colorspace;
+ mf->field = V4L2_FIELD_NONE;
+
+ return 0;
+}
+
+static int ov5647_enum_mbus_code(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_mbus_code_enum *code)
+{
+ if (code->pad || code->index >= ARRAY_SIZE(ov5647_colour_fmts))
+ return -EINVAL;
+
+ code->code = ov5647_colour_fmts[code->index].code;
+ return 0;
+}
+
+/*!
+ * ov5647_enum_framesizes - V4L2 sensor interface handler for
+ * VIDIOC_ENUM_FRAMESIZES ioctl
+ * @s: pointer to standard V4L2 device structure
+ * @fsize: standard V4L2 VIDIOC_ENUM_FRAMESIZES ioctl structure
+ *
+ * Return 0 if successful, otherwise -EINVAL.
+ */
+static int ov5647_enum_framesizes(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_frame_size_enum *fse)
+{
+ if (fse->index > ov5647_mode_MAX)
+ return -EINVAL;
+
+ fse->max_width =
+ max(ov5647_mode_info_data[0][fse->index].width,
+ ov5647_mode_info_data[1][fse->index].width);
+ fse->min_width = fse->max_width;
+ fse->max_height =
+ max(ov5647_mode_info_data[0][fse->index].height,
+ ov5647_mode_info_data[1][fse->index].height);
+ fse->min_height = fse->max_height;
+ return 0;
+}
+
+/*!
+ * ov5647_enum_frameintervals - V4L2 sensor interface handler for
+ * VIDIOC_ENUM_FRAMEINTERVALS ioctl
+ * @s: pointer to standard V4L2 device structure
+ * @fival: standard V4L2 VIDIOC_ENUM_FRAMEINTERVALS ioctl structure
+ *
+ * Return 0 if successful, otherwise -EINVAL.
+ */
+static int ov5647_enum_frameintervals(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_frame_interval_enum *fie)
+{
+ int i, j, count;
+
+ if (fie->index < 0 || fie->index > ov5647_mode_MAX)
+ return -EINVAL;
+
+ if (fie->width == 0 || fie->height == 0 ||
+ fie->code == 0) {
+ pr_warning("Please assign pixel format, width and height.\n");
+ return -EINVAL;
+ }
+
+ fie->interval.numerator = 1;
+
+ count = 0;
+ for (i = 0; i < ARRAY_SIZE(ov5647_mode_info_data); i++) {
+ for (j = 0; j < (ov5647_mode_MAX + 1); j++) {
+ if (fie->width == ov5647_mode_info_data[i][j].width
+ && fie->height == ov5647_mode_info_data[i][j].height
+ && ov5647_mode_info_data[i][j].init_data_ptr != NULL) {
+ count++;
+ }
+ if (fie->index == (count - 1)) {
+ fie->interval.denominator =
+ ov5647_framerates[i];
+ return 0;
+ }
+ }
+ }
+
+ return -EINVAL;
+}
+
+/*!
+ * dev_init - V4L2 sensor init
+ * @s: pointer to standard V4L2 device structure
+ *
+ */
+static int init_device(void)
+{
+ u32 tgt_xclk; /* target xclk */
+ u32 tgt_fps; /* target frames per secound */
+ enum ov5647_frame_rate frame_rate;
+ int ret;
+
+ ov5647_data.on = true;
+
+ /* mclk */
+ tgt_xclk = ov5647_data.mclk;
+ tgt_xclk = min(tgt_xclk, (u32)OV5647_XCLK_MAX);
+ tgt_xclk = max(tgt_xclk, (u32)OV5647_XCLK_MIN);
+ ov5647_data.mclk = tgt_xclk;
+
+ pr_debug(" Setting mclk to %d MHz\n", tgt_xclk / 1000000);
+
+ /* Default camera frame rate is set in probe */
+ tgt_fps = ov5647_data.streamcap.timeperframe.denominator /
+ ov5647_data.streamcap.timeperframe.numerator;
+
+ if (tgt_fps == 15)
+ frame_rate = ov5647_15_fps;
+ else if (tgt_fps == 30)
+ frame_rate = ov5647_30_fps;
+ else
+ return -EINVAL; /* Only support 15fps or 30fps now. */
+
+ ret = ov5647_init_mode(frame_rate, ov5647_mode_INIT, ov5647_mode_INIT);
+
+ ov5647_update_otp();
+ return ret;
+}
+
+static int ov5647_s_stream(struct v4l2_subdev *sd, int enable)
+{
+ if (enable)
+ ov5647_stream_on();
+ else
+ ov5647_stream_off();
+ return 0;
+}
+
+static struct v4l2_subdev_video_ops ov5647_subdev_video_ops = {
+ .g_parm = ov5647_g_parm,
+ .s_parm = ov5647_s_parm,
+ .s_stream = ov5647_s_stream,
+};
+
+static const struct v4l2_subdev_pad_ops ov5647_subdev_pad_ops = {
+ .enum_frame_size = ov5647_enum_framesizes,
+ .enum_frame_interval = ov5647_enum_frameintervals,
+ .enum_mbus_code = ov5647_enum_mbus_code,
+ .set_fmt = ov5647_set_fmt,
+ .get_fmt = ov5647_get_fmt,
+};
+
+static struct v4l2_subdev_core_ops ov5647_subdev_core_ops = {
+ .s_power = ov5647_s_power,
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+ .g_register = ov5647_get_register,
+ .s_register = ov5647_set_register,
+#endif
+};
+
+static struct v4l2_subdev_ops ov5647_subdev_ops = {
+ .core = &ov5647_subdev_core_ops,
+ .video = &ov5647_subdev_video_ops,
+ .pad = &ov5647_subdev_pad_ops,
+};
+
+
+/*!
+ * ov5647 I2C probe function
+ *
+ * @param adapter struct i2c_adapter *
+ * @return Error code indicating success or failure
+ */
+static int ov5647_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct pinctrl *pinctrl;
+ struct device *dev = &client->dev;
+ int retval;
+ u8 chip_id_high, chip_id_low;
+
+ /* ov5647 pinctrl */
+ pinctrl = devm_pinctrl_get_select_default(dev);
+ if (IS_ERR(pinctrl)) {
+ dev_warn(dev, "no pin available\n");
+ }
+
+
+ /* request power down pin */
+ pwn_gpio = of_get_named_gpio(dev->of_node, "pwn-gpios", 0);
+ if (!gpio_is_valid(pwn_gpio)) {
+ dev_warn(dev, "no sensor pwdn pin available\n");
+ pwn_gpio = -1;
+ } else {
+ retval = devm_gpio_request_one(dev, pwn_gpio, GPIOF_OUT_INIT_HIGH,
+ "ov5647_mipi_pwdn");
+ if (retval < 0) {
+ dev_warn(dev, "Failed to set power pin\n");
+ return retval;
+ }
+ }
+
+ /* request reset pin */
+ rst_gpio = of_get_named_gpio(dev->of_node, "rst-gpios", 0);
+ if (!gpio_is_valid(rst_gpio)) {
+ dev_warn(dev, "no sensor reset pin available\n");
+ rst_gpio = -1;
+ } else {
+ retval = devm_gpio_request_one(dev, rst_gpio, GPIOF_OUT_INIT_HIGH,
+ "ov5647_mipi_reset");
+ if (retval < 0) {
+ dev_warn(dev, "Failed to set reset pin\n");
+ return retval;
+ }
+ }
+
+ /* Set initial values for the sensor struct. */
+ memset(&ov5647_data, 0, sizeof(ov5647_data));
+ ov5647_data.sensor_clk = devm_clk_get(dev, "csi_mclk");
+ if (IS_ERR(ov5647_data.sensor_clk)) {
+ /* assuming clock enabled by default */
+ ov5647_data.sensor_clk = NULL;
+ dev_err(dev, "clock-frequency missing or invalid\n");
+ return PTR_ERR(ov5647_data.sensor_clk);
+ }
+
+ retval = of_property_read_u32(dev->of_node, "mclk",
+ &(ov5647_data.mclk));
+ if (retval) {
+ dev_err(dev, "mclk missing or invalid\n");
+ return retval;
+ }
+
+ retval = of_property_read_u32(dev->of_node, "mclk_source",
+ (u32 *) &(ov5647_data.mclk_source));
+ if (retval) {
+ dev_err(dev, "mclk_source missing or invalid\n");
+ return retval;
+ }
+
+ retval = of_property_read_u32(dev->of_node, "csi_id",
+ &(ov5647_data.csi));
+ if (retval) {
+ dev_err(dev, "csi id missing or invalid\n");
+ return retval;
+ }
+
+ clk_prepare_enable(ov5647_data.sensor_clk);
+
+ ov5647_data.io_init = ov5647_reset;
+ ov5647_data.i2c_client = client;
+ ov5647_data.pix.pixelformat = V4L2_PIX_FMT_SBGGR8;
+ ov5647_data.pix.width = 640;
+ ov5647_data.pix.height = 480;
+ ov5647_data.streamcap.capability = V4L2_MODE_HIGHQUALITY |
+ V4L2_CAP_TIMEPERFRAME;
+ ov5647_data.streamcap.capturemode = 0;
+ ov5647_data.streamcap.timeperframe.denominator = DEFAULT_FPS;
+ ov5647_data.streamcap.timeperframe.numerator = 1;
+
+ ov5647_regulator_enable(&client->dev);
+
+ ov5647_reset();
+
+ ov5647_power_down(0);
+
+ retval = ov5647_read_reg(OV5647_CHIP_ID_HIGH_BYTE, &chip_id_high);
+ if (retval < 0 || chip_id_high != 0x56) {
+ pr_warning("camera ov5647_mipi is not found\n");
+ clk_disable_unprepare(ov5647_data.sensor_clk);
+ return -ENODEV;
+ }
+ retval = ov5647_read_reg(OV5647_CHIP_ID_LOW_BYTE, &chip_id_low);
+ if (retval < 0 || chip_id_low != 0x47) {
+ pr_warning("camera ov5647_mipi is not found\n");
+ clk_disable_unprepare(ov5647_data.sensor_clk);
+ return -ENODEV;
+ }
+
+ retval = init_device();
+ if (retval < 0) {
+ clk_disable_unprepare(ov5647_data.sensor_clk);
+ pr_warning("camera ov5647 init failed\n");
+ ov5647_power_down(1);
+ return retval;
+ }
+
+ v4l2_i2c_subdev_init(&ov5647_data.subdev, client, &ov5647_subdev_ops);
+
+ ov5647_data.subdev.grp_id = 678;
+ retval = v4l2_async_register_subdev(&ov5647_data.subdev);
+ if (retval < 0)
+ dev_err(&client->dev,
+ "%s--Async register failed, ret=%d\n", __func__, retval);
+
+ ov5647_stream_off();
+ pr_info("camera ov5647_mipi is found\n");
+ return retval;
+}
+
+/*!
+ * ov5647 I2C detach function
+ *
+ * @param client struct i2c_client *
+ * @return Error code indicating success or failure
+ */
+static int ov5647_remove(struct i2c_client *client)
+{
+ struct v4l2_subdev *sd = i2c_get_clientdata(client);
+
+ v4l2_async_unregister_subdev(sd);
+
+ clk_disable_unprepare(ov5647_data.sensor_clk);
+
+ ov5647_power_down(1);
+
+ if (gpo_regulator)
+ regulator_disable(gpo_regulator);
+
+ if (analog_regulator)
+ regulator_disable(analog_regulator);
+
+ if (core_regulator)
+ regulator_disable(core_regulator);
+
+ if (io_regulator)
+ regulator_disable(io_regulator);
+
+ return 0;
+}
+
+module_i2c_driver(ov5647_i2c_driver);
+
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("OV5647 MIPI Camera Driver");
+MODULE_LICENSE("GPL");
+MODULE_VERSION("1.0");
+MODULE_ALIAS("CSI");
diff --git a/drivers/media/platform/mxc/capture/v4l2-int-device.c b/drivers/media/platform/mxc/capture/v4l2-int-device.c
new file mode 100644
index 000000000000..e49da150f887
--- /dev/null
+++ b/drivers/media/platform/mxc/capture/v4l2-int-device.c
@@ -0,0 +1,165 @@
+/*
+ * drivers/media/video/v4l2-int-device.c
+ *
+ * V4L2 internal ioctl interface.
+ *
+ * Copyright 2005-2014 Freescale Semiconductor, Inc.
+ * Copyright (C) 2007 Nokia Corporation.
+ *
+ * Contact: Sakari Ailus <sakari.ailus@nokia.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, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/sort.h>
+#include <linux/string.h>
+#include <linux/module.h>
+
+#include "v4l2-int-device.h"
+
+static DEFINE_MUTEX(mutex);
+static LIST_HEAD(int_list);
+
+void v4l2_int_device_try_attach_all(void)
+{
+ struct v4l2_int_device *m, *s;
+
+ list_for_each_entry(m, &int_list, head) {
+ if (m->type != v4l2_int_type_master)
+ continue;
+
+ list_for_each_entry(s, &int_list, head) {
+ if (s->type != v4l2_int_type_slave)
+ continue;
+
+ /* Slave is connected? */
+ if (s->u.slave->master)
+ continue;
+
+ /* Slave wants to attach to master? */
+ if (s->u.slave->attach_to[0] != 0
+ && strncmp(m->name, s->u.slave->attach_to,
+ V4L2NAMESIZE))
+ continue;
+
+ if (!try_module_get(m->module))
+ continue;
+
+ s->u.slave->master = m;
+ if (m->u.master->attach(s)) {
+ s->u.slave->master = NULL;
+ module_put(m->module);
+ continue;
+ }
+ }
+ }
+}
+EXPORT_SYMBOL_GPL(v4l2_int_device_try_attach_all);
+
+static int ioctl_sort_cmp(const void *a, const void *b)
+{
+ const struct v4l2_int_ioctl_desc *d1 = a, *d2 = b;
+
+ if (d1->num > d2->num)
+ return 1;
+
+ if (d1->num < d2->num)
+ return -1;
+
+ return 0;
+}
+
+int v4l2_int_device_register(struct v4l2_int_device *d)
+{
+ if (d->type == v4l2_int_type_slave)
+ sort(d->u.slave->ioctls, d->u.slave->num_ioctls,
+ sizeof(struct v4l2_int_ioctl_desc),
+ &ioctl_sort_cmp, NULL);
+ mutex_lock(&mutex);
+ list_add(&d->head, &int_list);
+ v4l2_int_device_try_attach_all();
+ mutex_unlock(&mutex);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(v4l2_int_device_register);
+
+void v4l2_int_device_unregister(struct v4l2_int_device *d)
+{
+ mutex_lock(&mutex);
+ list_del(&d->head);
+ if (d->type == v4l2_int_type_slave
+ && d->u.slave->master != NULL) {
+ d->u.slave->master->u.master->detach(d);
+ module_put(d->u.slave->master->module);
+ d->u.slave->master = NULL;
+ }
+ mutex_unlock(&mutex);
+}
+EXPORT_SYMBOL_GPL(v4l2_int_device_unregister);
+
+/* Adapted from search_extable in extable.c. */
+static v4l2_int_ioctl_func *find_ioctl(struct v4l2_int_slave *slave, int cmd,
+ v4l2_int_ioctl_func *no_such_ioctl)
+{
+ const struct v4l2_int_ioctl_desc *first = slave->ioctls;
+ const struct v4l2_int_ioctl_desc *last =
+ first + slave->num_ioctls - 1;
+
+ while (first <= last) {
+ const struct v4l2_int_ioctl_desc *mid;
+
+ mid = (last - first) / 2 + first;
+
+ if (mid->num < cmd)
+ first = mid + 1;
+ else if (mid->num > cmd)
+ last = mid - 1;
+ else
+ return mid->func;
+ }
+
+ return no_such_ioctl;
+}
+
+static int no_such_ioctl_0(struct v4l2_int_device *d)
+{
+ return -ENOIOCTLCMD;
+}
+
+int v4l2_int_ioctl_0(struct v4l2_int_device *d, int cmd)
+{
+ return ((v4l2_int_ioctl_func_0 *)
+ find_ioctl(d->u.slave, cmd,
+ (v4l2_int_ioctl_func *)no_such_ioctl_0))(d);
+}
+EXPORT_SYMBOL_GPL(v4l2_int_ioctl_0);
+
+static int no_such_ioctl_1(struct v4l2_int_device *d, void *arg)
+{
+ return -ENOIOCTLCMD;
+}
+
+int v4l2_int_ioctl_1(struct v4l2_int_device *d, int cmd, void *arg)
+{
+ return ((v4l2_int_ioctl_func_1 *)
+ find_ioctl(d->u.slave, cmd,
+ (v4l2_int_ioctl_func *)no_such_ioctl_1))(d, arg);
+}
+EXPORT_SYMBOL_GPL(v4l2_int_ioctl_1);
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/platform/mxc/capture/v4l2-int-device.h b/drivers/media/platform/mxc/capture/v4l2-int-device.h
new file mode 100644
index 000000000000..810d87f28794
--- /dev/null
+++ b/drivers/media/platform/mxc/capture/v4l2-int-device.h
@@ -0,0 +1,309 @@
+/*
+ * include/media/v4l2-int-device.h
+ *
+ * V4L2 internal ioctl interface.
+ *
+ * Copyright 2005-2014 Freescale Semiconductor, Inc.
+ * Copyright (C) 2007 Nokia Corporation.
+ *
+ * Contact: Sakari Ailus <sakari.ailus@nokia.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, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+
+#ifndef V4L2_INT_DEVICE_H
+#define V4L2_INT_DEVICE_H
+
+#include <media/v4l2-common.h>
+
+#define V4L2NAMESIZE 32
+
+/*
+ *
+ * The internal V4L2 device interface core.
+ *
+ */
+
+enum v4l2_int_type {
+ v4l2_int_type_master = 1,
+ v4l2_int_type_slave
+};
+
+struct module;
+
+struct v4l2_int_device;
+
+struct v4l2_int_master {
+ int (*attach)(struct v4l2_int_device *slave);
+ void (*detach)(struct v4l2_int_device *slave);
+};
+
+typedef int (v4l2_int_ioctl_func)(struct v4l2_int_device *);
+typedef int (v4l2_int_ioctl_func_0)(struct v4l2_int_device *);
+typedef int (v4l2_int_ioctl_func_1)(struct v4l2_int_device *, void *);
+
+struct v4l2_int_ioctl_desc {
+ int num;
+ v4l2_int_ioctl_func *func;
+};
+
+struct v4l2_int_slave {
+ /* Don't touch master. */
+ struct v4l2_int_device *master;
+
+ char attach_to[V4L2NAMESIZE];
+
+ int num_ioctls;
+ struct v4l2_int_ioctl_desc *ioctls;
+};
+
+struct v4l2_int_device {
+ /* Don't touch head. */
+ struct list_head head;
+
+ struct module *module;
+
+ char name[V4L2NAMESIZE];
+
+ enum v4l2_int_type type;
+ union {
+ struct v4l2_int_master *master;
+ struct v4l2_int_slave *slave;
+ } u;
+
+ void *priv;
+};
+
+void v4l2_int_device_try_attach_all(void);
+
+int v4l2_int_device_register(struct v4l2_int_device *d);
+void v4l2_int_device_unregister(struct v4l2_int_device *d);
+
+int v4l2_int_ioctl_0(struct v4l2_int_device *d, int cmd);
+int v4l2_int_ioctl_1(struct v4l2_int_device *d, int cmd, void *arg);
+
+/*
+ *
+ * Types and definitions for IOCTL commands.
+ *
+ */
+
+enum v4l2_power {
+ V4L2_POWER_OFF = 0,
+ V4L2_POWER_ON,
+ V4L2_POWER_STANDBY,
+};
+
+/* Slave interface type. */
+enum v4l2_if_type {
+ /*
+ * Parallel 8-, 10- or 12-bit interface, used by for example
+ * on certain image sensors.
+ */
+ V4L2_IF_TYPE_BT656,
+};
+
+enum v4l2_if_type_bt656_mode {
+ /*
+ * Modes without Bt synchronisation codes. Separate
+ * synchronisation signal lines are used.
+ */
+ V4L2_IF_TYPE_BT656_MODE_NOBT_8BIT,
+ V4L2_IF_TYPE_BT656_MODE_NOBT_10BIT,
+ V4L2_IF_TYPE_BT656_MODE_NOBT_12BIT,
+ /*
+ * Use Bt synchronisation codes. The vertical and horizontal
+ * synchronisation is done based on synchronisation codes.
+ */
+ V4L2_IF_TYPE_BT656_MODE_BT_8BIT,
+ V4L2_IF_TYPE_BT656_MODE_BT_10BIT,
+};
+
+struct v4l2_if_type_bt656 {
+ /*
+ * 0: Frame begins when vsync is high.
+ * 1: Frame begins when vsync changes from low to high.
+ */
+ unsigned frame_start_on_rising_vs:1;
+ /* Use Bt synchronisation codes for sync correction. */
+ unsigned bt_sync_correct:1;
+ /* Swap every two adjacent image data elements. */
+ unsigned swap:1;
+ /* Inverted latch clock polarity from slave. */
+ unsigned latch_clk_inv:1;
+ /* Hs polarity. 0 is active high, 1 active low. */
+ unsigned nobt_hs_inv:1;
+ /* Vs polarity. 0 is active high, 1 active low. */
+ unsigned nobt_vs_inv:1;
+ enum v4l2_if_type_bt656_mode mode;
+ /* Minimum accepted bus clock for slave (in Hz). */
+ u32 clock_min;
+ /* Maximum accepted bus clock for slave. */
+ u32 clock_max;
+ /*
+ * Current wish of the slave. May only change in response to
+ * ioctls that affect image capture.
+ */
+ u32 clock_curr;
+};
+
+struct v4l2_ifparm {
+ enum v4l2_if_type if_type;
+ union {
+ struct v4l2_if_type_bt656 bt656;
+ } u;
+};
+
+/* IOCTL command numbers. */
+enum v4l2_int_ioctl_num {
+ /*
+ *
+ * "Proper" V4L ioctls, as in struct video_device.
+ *
+ */
+ vidioc_int_enum_fmt_cap_num = 1,
+ vidioc_int_g_fmt_cap_num,
+ vidioc_int_s_fmt_cap_num,
+ vidioc_int_try_fmt_cap_num,
+ vidioc_int_queryctrl_num,
+ vidioc_int_g_ctrl_num,
+ vidioc_int_s_ctrl_num,
+ vidioc_int_cropcap_num,
+ vidioc_int_g_crop_num,
+ vidioc_int_s_crop_num,
+ vidioc_int_g_parm_num,
+ vidioc_int_s_parm_num,
+ vidioc_int_querystd_num,
+ vidioc_int_s_std_num,
+ vidioc_int_s_video_routing_num,
+
+ /*
+ *
+ * Strictly internal ioctls.
+ *
+ */
+ /* Initialise the device when slave attaches to the master. */
+ vidioc_int_dev_init_num = 1000,
+ /* Delinitialise the device at slave detach. */
+ vidioc_int_dev_exit_num,
+ /* Set device power state. */
+ vidioc_int_s_power_num,
+ /*
+ * Get slave private data, e.g. platform-specific slave
+ * configuration used by the master.
+ */
+ vidioc_int_g_priv_num,
+ /* Get slave interface parameters. */
+ vidioc_int_g_ifparm_num,
+ /* Does the slave need to be reset after VIDIOC_DQBUF? */
+ vidioc_int_g_needs_reset_num,
+ vidioc_int_enum_framesizes_num,
+ vidioc_int_enum_frameintervals_num,
+
+ /*
+ *
+ * VIDIOC_INT_* ioctls.
+ *
+ */
+ /* VIDIOC_INT_RESET */
+ vidioc_int_reset_num,
+ /* VIDIOC_INT_INIT */
+ vidioc_int_init_num,
+ /* VIDIOC_DBG_G_CHIP_IDENT */
+ vidioc_int_g_chip_ident_num,
+
+ /*
+ *
+ * Start of private ioctls.
+ *
+ */
+ vidioc_int_priv_start_num = 2000,
+};
+
+/*
+ *
+ * IOCTL wrapper functions for better type checking.
+ *
+ */
+
+#define V4L2_INT_WRAPPER_0(name) \
+ static inline int vidioc_int_##name(struct v4l2_int_device *d) \
+ { \
+ return v4l2_int_ioctl_0(d, vidioc_int_##name##_num); \
+ } \
+ \
+ static inline struct v4l2_int_ioctl_desc \
+ vidioc_int_##name##_cb(int (*func) \
+ (struct v4l2_int_device *)) \
+ { \
+ struct v4l2_int_ioctl_desc desc; \
+ \
+ desc.num = vidioc_int_##name##_num; \
+ desc.func = (v4l2_int_ioctl_func *)func; \
+ \
+ return desc; \
+ }
+
+#define V4L2_INT_WRAPPER_1(name, arg_type, asterisk) \
+ static inline int vidioc_int_##name(struct v4l2_int_device *d, \
+ arg_type asterisk arg) \
+ { \
+ return v4l2_int_ioctl_1(d, vidioc_int_##name##_num, \
+ (void *)(unsigned long)arg); \
+ } \
+ \
+ static inline struct v4l2_int_ioctl_desc \
+ vidioc_int_##name##_cb(int (*func) \
+ (struct v4l2_int_device *, \
+ arg_type asterisk)) \
+ { \
+ struct v4l2_int_ioctl_desc desc; \
+ \
+ desc.num = vidioc_int_##name##_num; \
+ desc.func = (v4l2_int_ioctl_func *)func; \
+ \
+ return desc; \
+ }
+
+V4L2_INT_WRAPPER_1(enum_fmt_cap, struct v4l2_fmtdesc, *);
+V4L2_INT_WRAPPER_1(g_fmt_cap, struct v4l2_format, *);
+V4L2_INT_WRAPPER_1(s_fmt_cap, struct v4l2_format, *);
+V4L2_INT_WRAPPER_1(try_fmt_cap, struct v4l2_format, *);
+V4L2_INT_WRAPPER_1(queryctrl, struct v4l2_queryctrl, *);
+V4L2_INT_WRAPPER_1(g_ctrl, struct v4l2_control, *);
+V4L2_INT_WRAPPER_1(s_ctrl, struct v4l2_control, *);
+V4L2_INT_WRAPPER_1(cropcap, struct v4l2_cropcap, *);
+V4L2_INT_WRAPPER_1(g_crop, struct v4l2_crop, *);
+V4L2_INT_WRAPPER_1(s_crop, struct v4l2_crop, *);
+V4L2_INT_WRAPPER_1(g_parm, struct v4l2_streamparm, *);
+V4L2_INT_WRAPPER_1(s_parm, struct v4l2_streamparm, *);
+V4L2_INT_WRAPPER_1(querystd, v4l2_std_id, *);
+V4L2_INT_WRAPPER_1(s_std, v4l2_std_id, *);
+V4L2_INT_WRAPPER_1(s_video_routing, struct v4l2_routing, *);
+
+V4L2_INT_WRAPPER_0(dev_init);
+V4L2_INT_WRAPPER_0(dev_exit);
+V4L2_INT_WRAPPER_1(s_power, enum v4l2_power, /*dummy arg*/);
+V4L2_INT_WRAPPER_1(g_priv, void, *);
+V4L2_INT_WRAPPER_1(g_ifparm, struct v4l2_ifparm, *);
+V4L2_INT_WRAPPER_1(g_needs_reset, void, *);
+V4L2_INT_WRAPPER_1(enum_framesizes, struct v4l2_frmsizeenum, *);
+V4L2_INT_WRAPPER_1(enum_frameintervals, struct v4l2_frmivalenum, *);
+
+V4L2_INT_WRAPPER_0(reset);
+V4L2_INT_WRAPPER_0(init);
+V4L2_INT_WRAPPER_1(g_chip_ident, int, *);
+
+#endif
diff --git a/drivers/media/platform/mxc/output/Kconfig b/drivers/media/platform/mxc/output/Kconfig
new file mode 100644
index 000000000000..237f8a88b5cb
--- /dev/null
+++ b/drivers/media/platform/mxc/output/Kconfig
@@ -0,0 +1,16 @@
+config VIDEO_MXC_IPU_OUTPUT
+ tristate "IPU v4l2 output support"
+ depends on VIDEO_MXC_OUTPUT && MXC_IPU
+ ---help---
+ This is the video4linux2 driver for IPU post processing video output.
+
+config VIDEO_MXC_PXP_V4L2
+ tristate "MXC PxP V4L2 driver"
+ depends on VIDEO_DEV && VIDEO_V4L2
+ select VIDEOBUF_DMA_CONTIG
+ ---help---
+ This is a video4linux driver for the Freescale PxP
+ (Pixel Pipeline). This module supports output overlay of
+ the MXC framebuffer on a video stream.
+
+ To compile this driver as a module, choose M here.
diff --git a/drivers/media/platform/mxc/output/Makefile b/drivers/media/platform/mxc/output/Makefile
new file mode 100644
index 000000000000..88f1a9fb735d
--- /dev/null
+++ b/drivers/media/platform/mxc/output/Makefile
@@ -0,0 +1,2 @@
+obj-$(CONFIG_VIDEO_MXC_IPU_OUTPUT) += mxc_vout.o
+obj-$(CONFIG_VIDEO_MXC_PXP_V4L2) += mxc_pxp_v4l2.o
diff --git a/drivers/media/platform/mxc/output/mxc_pxp_v4l2.c b/drivers/media/platform/mxc/output/mxc_pxp_v4l2.c
new file mode 100644
index 000000000000..16da4d3e3347
--- /dev/null
+++ b/drivers/media/platform/mxc/output/mxc_pxp_v4l2.c
@@ -0,0 +1,1346 @@
+/*
+ * Copyright (C) 2010-2015 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.
+ *
+ * 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
+ *
+ */
+/*
+ * Based on STMP378X PxP driver
+ * Copyright 2008-2009 Embedded Alley Solutions, Inc All Rights Reserved.
+ */
+
+#include <linux/dma-mapping.h>
+#include <linux/fb.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/platform_device.h>
+#include <linux/vmalloc.h>
+#include <linux/videodev2.h>
+#include <linux/dmaengine.h>
+#include <linux/pxp_dma.h>
+#include <linux/delay.h>
+#include <linux/console.h>
+#include <linux/mxcfb.h>
+#include <linux/platform_data/dma-imx.h>
+
+#include <media/videobuf-dma-contig.h>
+#include <media/v4l2-common.h>
+#include <media/v4l2-dev.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-ioctl.h>
+
+#include "mxc_pxp_v4l2.h"
+
+#define PXP_DRIVER_NAME "pxp-v4l2"
+#define PXP_DRIVER_MAJOR 2
+#define PXP_DRIVER_MINOR 0
+
+#define PXP_DEF_BUFS 2
+#define PXP_MIN_PIX 8
+
+#define V4L2_OUTPUT_TYPE_INTERNAL 4
+
+static int video_nr = -1; /* -1 ==> auto assign */
+static struct pxp_data_format pxp_s0_formats[] = {
+ {
+ .name = "24-bit RGB",
+ .bpp = 4,
+ .fourcc = V4L2_PIX_FMT_RGB24,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ }, {
+ .name = "16-bit RGB 5:6:5",
+ .bpp = 2,
+ .fourcc = V4L2_PIX_FMT_RGB565,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ }, {
+ .name = "16-bit RGB 5:5:5",
+ .bpp = 2,
+ .fourcc = V4L2_PIX_FMT_RGB555,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ }, {
+ .name = "YUV 4:2:0 Planar",
+ .bpp = 2,
+ .fourcc = V4L2_PIX_FMT_YUV420,
+ .colorspace = V4L2_COLORSPACE_JPEG,
+ }, {
+ .name = "YUV 4:2:2 Planar",
+ .bpp = 2,
+ .fourcc = V4L2_PIX_FMT_YUV422P,
+ .colorspace = V4L2_COLORSPACE_JPEG,
+ }, {
+ .name = "UYVY",
+ .bpp = 2,
+ .fourcc = V4L2_PIX_FMT_UYVY,
+ .colorspace = V4L2_COLORSPACE_JPEG,
+ }, {
+ .name = "YUYV",
+ .bpp = 2,
+ .fourcc = V4L2_PIX_FMT_YUYV,
+ .colorspace = V4L2_COLORSPACE_JPEG,
+ }, {
+ .name = "YUV32",
+ .bpp = 4,
+ .fourcc = V4L2_PIX_FMT_YUV32,
+ .colorspace = V4L2_COLORSPACE_JPEG,
+ },
+};
+
+static unsigned int v4l2_fmt_to_pxp_fmt(u32 v4l2_pix_fmt)
+{
+ u32 pxp_fmt = 0;
+
+ if (v4l2_pix_fmt == V4L2_PIX_FMT_RGB24)
+ pxp_fmt = PXP_PIX_FMT_XRGB32;
+ else if (v4l2_pix_fmt == V4L2_PIX_FMT_RGB565)
+ pxp_fmt = PXP_PIX_FMT_RGB565;
+ else if (v4l2_pix_fmt == V4L2_PIX_FMT_RGB555)
+ pxp_fmt = PXP_PIX_FMT_RGB555;
+ else if (v4l2_pix_fmt == V4L2_PIX_FMT_YUV420)
+ pxp_fmt = PXP_PIX_FMT_YUV420P;
+ else if (v4l2_pix_fmt == V4L2_PIX_FMT_YUV422P)
+ pxp_fmt = PXP_PIX_FMT_YUV422P;
+ else if (v4l2_pix_fmt == V4L2_PIX_FMT_UYVY)
+ pxp_fmt = PXP_PIX_FMT_UYVY;
+ else if (v4l2_pix_fmt == V4L2_PIX_FMT_YUV32)
+ pxp_fmt = PXP_PIX_FMT_VUY444;
+ else if (v4l2_pix_fmt == V4L2_PIX_FMT_YUYV)
+ pxp_fmt = PXP_PIX_FMT_YUYV;
+
+ return pxp_fmt;
+}
+struct v4l2_queryctrl pxp_controls[] = {
+ {
+ .id = V4L2_CID_HFLIP,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "Horizontal Flip",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0,
+ .flags = 0,
+ }, {
+ .id = V4L2_CID_VFLIP,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "Vertical Flip",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0,
+ .flags = 0,
+ }, {
+ .id = V4L2_CID_PRIVATE_BASE,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Rotation",
+ .minimum = 0,
+ .maximum = 270,
+ .step = 90,
+ .default_value = 0,
+ .flags = 0,
+ }, {
+ .id = V4L2_CID_PRIVATE_BASE + 1,
+ .name = "Background Color",
+ .minimum = 0,
+ .maximum = 0xFFFFFF,
+ .step = 1,
+ .default_value = 0,
+ .flags = 0,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ }, {
+ .id = V4L2_CID_PRIVATE_BASE + 2,
+ .name = "Set S0 Chromakey",
+ .minimum = -1,
+ .maximum = 0xFFFFFF,
+ .step = 1,
+ .default_value = -1,
+ .flags = 0,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ }, {
+ .id = V4L2_CID_PRIVATE_BASE + 3,
+ .name = "YUV Colorspace",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0,
+ .flags = 0,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ },
+};
+
+static void free_dma_buf(struct pxps *pxp, struct dma_mem *buf)
+{
+ dma_free_coherent(&pxp->pdev->dev, buf->size, buf->vaddr, buf->paddr);
+ dev_dbg(&pxp->pdev->dev,
+ "free dma size:0x%x, paddr:0x%x\n",
+ buf->size, buf->paddr);
+ memset(buf, 0, sizeof(*buf));
+}
+
+static int alloc_dma_buf(struct pxps *pxp, struct dma_mem *buf)
+{
+
+ buf->vaddr = dma_alloc_coherent(&pxp->pdev->dev, buf->size, &buf->paddr,
+ GFP_DMA | GFP_KERNEL);
+ if (!buf->vaddr) {
+ dev_err(&pxp->pdev->dev,
+ "cannot get dma buf size:0x%x\n", buf->size);
+ return -ENOMEM;
+ }
+ dev_dbg(&pxp->pdev->dev,
+ "alloc dma buf size:0x%x, paddr:0x%x\n", buf->size, buf->paddr);
+ return 0;
+}
+
+/* callback function */
+static void video_dma_done(void *arg)
+{
+ struct pxp_tx_desc *tx_desc = to_tx_desc(arg);
+ struct dma_chan *chan = tx_desc->txd.chan;
+ struct pxp_channel *pxp_chan = to_pxp_channel(chan);
+ struct pxps *pxp = pxp_chan->client;
+ struct videobuf_buffer *vb;
+
+ dev_dbg(chan->device->dev, "callback cookie %d, active DMA 0x%08x\n",
+ tx_desc->txd.cookie,
+ pxp->active ? sg_dma_address(&pxp->active->sg[0]) : 0);
+
+ spin_lock(&pxp->lock);
+ if (pxp->active) {
+ vb = &pxp->active->vb;
+
+ list_del_init(&vb->queue);
+ vb->state = VIDEOBUF_DONE;
+ do_gettimeofday(&vb->ts);
+ vb->field_count++;
+ wake_up(&vb->done);
+ }
+
+ if (list_empty(&pxp->outq)) {
+ pxp->active = NULL;
+ spin_unlock(&pxp->lock);
+
+ return;
+ }
+
+ pxp->active = list_entry(pxp->outq.next,
+ struct pxp_buffer, vb.queue);
+ pxp->active->vb.state = VIDEOBUF_ACTIVE;
+ spin_unlock(&pxp->lock);
+}
+
+static bool chan_filter(struct dma_chan *chan, void *arg)
+{
+ if (imx_dma_is_pxp(chan))
+ return true;
+ else
+ return false;
+}
+
+static int acquire_dma_channel(struct pxps *pxp)
+{
+ dma_cap_mask_t mask;
+ struct dma_chan *chan;
+ struct pxp_channel **pchan = &pxp->pxp_channel[0];
+
+ if (*pchan) {
+ struct videobuf_buffer *vb, *_vb;
+ dma_release_channel(&(*pchan)->dma_chan);
+ *pchan = NULL;
+ pxp->active = NULL;
+ list_for_each_entry_safe(vb, _vb, &pxp->outq, queue) {
+ list_del_init(&vb->queue);
+ vb->state = VIDEOBUF_ERROR;
+ wake_up(&vb->done);
+ }
+ }
+
+ dma_cap_zero(mask);
+ dma_cap_set(DMA_SLAVE, mask);
+ dma_cap_set(DMA_PRIVATE, mask);
+ chan = dma_request_channel(mask, chan_filter, NULL);
+ if (!chan)
+ return -EBUSY;
+
+ *pchan = to_pxp_channel(chan);
+ (*pchan)->client = pxp;
+
+ return 0;
+}
+
+static int _get_fbinfo(struct fb_info **fbi)
+{
+ int i;
+ for (i = 0; i < num_registered_fb; i++) {
+ char *idstr = registered_fb[i]->fix.id;
+ if (strncmp(idstr, "mxs", 3) == 0) {
+ *fbi = registered_fb[i];
+ return 0;
+ }
+ }
+
+ return -ENODEV;
+}
+
+static int pxp_set_fbinfo(struct pxps *pxp)
+{
+ struct v4l2_framebuffer *fb = &pxp->fb;
+ int err;
+
+ err = _get_fbinfo(&pxp->fbi);
+ if (err)
+ return err;
+
+ fb->fmt.width = pxp->fbi->var.xres;
+ fb->fmt.height = pxp->fbi->var.yres;
+ pxp->pxp_conf.out_param.stride = pxp->fbi->var.xres;
+ if (pxp->fbi->var.bits_per_pixel == 16)
+ fb->fmt.pixelformat = V4L2_PIX_FMT_RGB565;
+ else
+ fb->fmt.pixelformat = V4L2_PIX_FMT_RGB24;
+
+ fb->base = (void *)pxp->fbi->fix.smem_start;
+
+ return 0;
+}
+
+static int _get_cur_fb_blank(struct pxps *pxp)
+{
+ struct fb_info *fbi;
+ mm_segment_t old_fs;
+ int err = 0;
+
+ err = _get_fbinfo(&fbi);
+ if (err)
+ return err;
+
+ if (fbi->fbops->fb_ioctl) {
+ old_fs = get_fs();
+ set_fs(KERNEL_DS);
+ err = fbi->fbops->fb_ioctl(fbi, MXCFB_GET_FB_BLANK,
+ (unsigned int)(&pxp->fb_blank));
+ set_fs(old_fs);
+ }
+
+ return err;
+}
+
+static int pxp_show_buf(struct pxps *pxp, unsigned long paddr)
+{
+ struct fb_info *fbi = pxp->fbi;
+ int ret = -EINVAL;
+
+ if (paddr == 0) {
+ dev_err(&pxp->pdev->dev, "Invalid paddr\n");
+ return ret;
+ }
+
+ console_lock();
+ fbi->fix.smem_start = paddr;
+ ret = fb_pan_display(fbi, &fbi->var);
+ console_unlock();
+
+ return ret;
+}
+
+static int set_fb_blank(int blank)
+{
+ struct fb_info *fbi;
+ int err = 0;
+
+ err = _get_fbinfo(&fbi);
+ if (err)
+ return err;
+
+ console_lock();
+ fb_blank(fbi, blank);
+ console_unlock();
+
+ return err;
+}
+
+static int pxp_set_cstate(struct pxps *pxp, struct v4l2_control *vc)
+{
+
+ if (vc->id == V4L2_CID_HFLIP) {
+ pxp->pxp_conf.proc_data.hflip = vc->value;
+ } else if (vc->id == V4L2_CID_VFLIP) {
+ pxp->pxp_conf.proc_data.vflip = vc->value;
+ } else if (vc->id == V4L2_CID_PRIVATE_BASE) {
+ if (vc->value % 90)
+ return -ERANGE;
+ pxp->pxp_conf.proc_data.rotate = vc->value;
+ } else if (vc->id == V4L2_CID_PRIVATE_BASE + 1) {
+ pxp->pxp_conf.proc_data.bgcolor = vc->value;
+ } else if (vc->id == V4L2_CID_PRIVATE_BASE + 2) {
+ pxp->pxp_conf.s0_param.color_key = vc->value;
+ } else if (vc->id == V4L2_CID_PRIVATE_BASE + 3) {
+ pxp->pxp_conf.proc_data.yuv = vc->value;
+ }
+
+ return 0;
+}
+
+static int pxp_get_cstate(struct pxps *pxp, struct v4l2_control *vc)
+{
+ if (vc->id == V4L2_CID_HFLIP)
+ vc->value = pxp->pxp_conf.proc_data.hflip;
+ else if (vc->id == V4L2_CID_VFLIP)
+ vc->value = pxp->pxp_conf.proc_data.vflip;
+ else if (vc->id == V4L2_CID_PRIVATE_BASE)
+ vc->value = pxp->pxp_conf.proc_data.rotate;
+ else if (vc->id == V4L2_CID_PRIVATE_BASE + 1)
+ vc->value = pxp->pxp_conf.proc_data.bgcolor;
+ else if (vc->id == V4L2_CID_PRIVATE_BASE + 2)
+ vc->value = pxp->pxp_conf.s0_param.color_key;
+ else if (vc->id == V4L2_CID_PRIVATE_BASE + 3)
+ vc->value = pxp->pxp_conf.proc_data.yuv;
+
+ return 0;
+}
+
+static int pxp_enumoutput(struct file *file, void *fh,
+ struct v4l2_output *o)
+{
+ struct pxps *pxp = video_get_drvdata(video_devdata(file));
+
+ if (o->index > 1)
+ return -EINVAL;
+
+ memset(o, 0, sizeof(struct v4l2_output));
+ if (o->index == 0) {
+ strcpy(o->name, "PxP Display Output");
+ pxp->output = 0;
+ } else {
+ strcpy(o->name, "PxP Virtual Output");
+ pxp->output = 1;
+ }
+ o->type = V4L2_OUTPUT_TYPE_INTERNAL;
+ o->std = 0;
+ o->reserved[0] = pxp->outbuf.paddr;
+
+ return 0;
+}
+
+static int pxp_g_output(struct file *file, void *fh,
+ unsigned int *i)
+{
+ struct pxps *pxp = video_get_drvdata(video_devdata(file));
+
+ *i = pxp->output;
+
+ return 0;
+}
+
+static int pxp_s_output(struct file *file, void *fh,
+ unsigned int i)
+{
+ struct pxps *pxp = video_get_drvdata(video_devdata(file));
+ struct v4l2_pix_format *fmt = (struct v4l2_pix_format*)(&pxp->fb.fmt);
+ u32 size;
+ int ret, bpp;
+
+ if (i > 1)
+ return -EINVAL;
+
+ /* Output buffer is same format as fbdev */
+ if (fmt->pixelformat == V4L2_PIX_FMT_RGB24 ||
+ fmt->pixelformat == V4L2_PIX_FMT_YUV32)
+ bpp = 4;
+ else
+ bpp = 2;
+
+ size = fmt->width * fmt->height * bpp;
+ if (size > pxp->outbuf.size) {
+ if (pxp->outbuf.vaddr)
+ free_dma_buf(pxp, &pxp->outbuf);
+ pxp->outbuf.size = size;
+ ret = alloc_dma_buf(pxp, &pxp->outbuf);
+ if (ret < 0)
+ return ret;
+ }
+ memset(pxp->outbuf.vaddr, 0x0, pxp->outbuf.size);
+
+ pxp->pxp_conf.out_param.width = fmt->width;
+ pxp->pxp_conf.out_param.height = fmt->height;
+ if (fmt->pixelformat == V4L2_PIX_FMT_RGB24)
+ pxp->pxp_conf.out_param.pixel_fmt = PXP_PIX_FMT_XRGB32;
+ else
+ pxp->pxp_conf.out_param.pixel_fmt = PXP_PIX_FMT_RGB565;
+
+ return 0;
+}
+
+static int pxp_enum_fmt_video_output(struct file *file, void *fh,
+ struct v4l2_fmtdesc *fmt)
+{
+ enum v4l2_buf_type type = fmt->type;
+ unsigned int index = fmt->index;
+
+ if (fmt->index >= ARRAY_SIZE(pxp_s0_formats))
+ return -EINVAL;
+
+ memset(fmt, 0, sizeof(struct v4l2_fmtdesc));
+ fmt->index = index;
+ fmt->type = type;
+ fmt->pixelformat = pxp_s0_formats[index].fourcc;
+ strcpy(fmt->description, pxp_s0_formats[index].name);
+
+ return 0;
+}
+
+static int pxp_g_fmt_video_output(struct file *file, void *fh,
+ struct v4l2_format *f)
+{
+ struct v4l2_pix_format *pf = &f->fmt.pix;
+ struct pxps *pxp = video_get_drvdata(video_devdata(file));
+ struct pxp_data_format *fmt = pxp->s0_fmt;
+
+ pf->width = pxp->pxp_conf.s0_param.width;
+ pf->height = pxp->pxp_conf.s0_param.height;
+ pf->pixelformat = fmt->fourcc;
+ pf->field = V4L2_FIELD_NONE;
+ pf->bytesperline = fmt->bpp * pf->width;
+ pf->sizeimage = pf->bytesperline * pf->height;
+ pf->colorspace = fmt->colorspace;
+ pf->priv = 0;
+
+ return 0;
+}
+
+static struct pxp_data_format *pxp_get_format(struct v4l2_format *f)
+{
+ struct pxp_data_format *fmt;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(pxp_s0_formats); i++) {
+ fmt = &pxp_s0_formats[i];
+ if (fmt->fourcc == f->fmt.pix.pixelformat)
+ break;
+ }
+
+ if (i == ARRAY_SIZE(pxp_s0_formats))
+ return NULL;
+
+ return &pxp_s0_formats[i];
+}
+
+static int pxp_try_fmt_video_output(struct file *file, void *fh,
+ struct v4l2_format *f)
+{
+ int w = f->fmt.pix.width;
+ int h = f->fmt.pix.height;
+ struct pxp_data_format *fmt = pxp_get_format(f);
+
+ if (!fmt)
+ return -EINVAL;
+
+ w = min(w, 2040);
+ w = max(w, 8);
+ h = min(h, 2040);
+ h = max(h, 8);
+ f->fmt.pix.field = V4L2_FIELD_NONE;
+ f->fmt.pix.width = w;
+ f->fmt.pix.height = h;
+ f->fmt.pix.pixelformat = fmt->fourcc;
+
+ return 0;
+}
+
+static int pxp_s_fmt_video_output(struct file *file, void *fh,
+ struct v4l2_format *f)
+{
+ struct pxps *pxp = video_get_drvdata(video_devdata(file));
+ struct v4l2_pix_format *pf = &f->fmt.pix;
+ int ret;
+
+ ret = acquire_dma_channel(pxp);
+ if (ret < 0)
+ return ret;
+
+ ret = pxp_try_fmt_video_output(file, fh, f);
+ if (ret == 0) {
+ pxp->s0_fmt = pxp_get_format(f);
+ pxp->pxp_conf.s0_param.pixel_fmt =
+ v4l2_fmt_to_pxp_fmt(pxp->s0_fmt->fourcc);
+ pxp->pxp_conf.s0_param.width = pf->width;
+ pxp->pxp_conf.s0_param.height = pf->height;
+ }
+
+
+ return ret;
+}
+
+static int pxp_g_fmt_output_overlay(struct file *file, void *fh,
+ struct v4l2_format *f)
+{
+ struct pxps *pxp = video_get_drvdata(video_devdata(file));
+ struct v4l2_window *wf = &f->fmt.win;
+
+ memset(wf, 0, sizeof(struct v4l2_window));
+ wf->chromakey = pxp->s1_chromakey;
+ wf->global_alpha = pxp->global_alpha;
+ wf->field = V4L2_FIELD_NONE;
+ wf->clips = NULL;
+ wf->clipcount = 0;
+ wf->bitmap = NULL;
+ wf->w.left = pxp->pxp_conf.proc_data.srect.left;
+ wf->w.top = pxp->pxp_conf.proc_data.srect.top;
+ wf->w.width = pxp->pxp_conf.proc_data.srect.width;
+ wf->w.height = pxp->pxp_conf.proc_data.srect.height;
+
+ return 0;
+}
+
+static int pxp_try_fmt_output_overlay(struct file *file, void *fh,
+ struct v4l2_format *f)
+{
+ struct pxps *pxp = video_get_drvdata(video_devdata(file));
+ struct v4l2_window *wf = &f->fmt.win;
+ struct v4l2_rect srect;
+ u32 s1_chromakey = wf->chromakey;
+ u8 global_alpha = wf->global_alpha;
+
+ memcpy(&srect, &(wf->w), sizeof(struct v4l2_rect));
+
+ pxp_g_fmt_output_overlay(file, fh, f);
+
+ wf->chromakey = s1_chromakey;
+ wf->global_alpha = global_alpha;
+
+ /* Constrain parameters to the input buffer */
+ wf->w.left = srect.left;
+ wf->w.top = srect.top;
+ wf->w.width = min(srect.width,
+ ((__u32)pxp->pxp_conf.s0_param.width - wf->w.left));
+ wf->w.height = min(srect.height,
+ ((__u32)pxp->pxp_conf.s0_param.height - wf->w.top));
+
+ return 0;
+}
+
+static int pxp_s_fmt_output_overlay(struct file *file, void *fh,
+ struct v4l2_format *f)
+{
+ struct pxps *pxp = video_get_drvdata(video_devdata(file));
+ struct v4l2_window *wf = &f->fmt.win;
+ int ret = pxp_try_fmt_output_overlay(file, fh, f);
+
+ if (ret == 0) {
+ pxp->global_alpha = wf->global_alpha;
+ pxp->s1_chromakey = wf->chromakey;
+ pxp->pxp_conf.proc_data.srect.left = wf->w.left;
+ pxp->pxp_conf.proc_data.srect.top = wf->w.top;
+ pxp->pxp_conf.proc_data.srect.width = wf->w.width;
+ pxp->pxp_conf.proc_data.srect.height = wf->w.height;
+ pxp->pxp_conf.ol_param[0].global_alpha = pxp->global_alpha;
+ pxp->pxp_conf.ol_param[0].color_key = pxp->s1_chromakey;
+ pxp->pxp_conf.ol_param[0].color_key_enable =
+ pxp->s1_chromakey_state;
+ }
+
+ return ret;
+}
+
+static int pxp_reqbufs(struct file *file, void *priv,
+ struct v4l2_requestbuffers *r)
+{
+ struct pxps *pxp = video_get_drvdata(video_devdata(file));
+
+ return videobuf_reqbufs(&pxp->s0_vbq, r);
+}
+
+static int pxp_querybuf(struct file *file, void *priv,
+ struct v4l2_buffer *b)
+{
+ int ret;
+ struct pxps *pxp = video_get_drvdata(video_devdata(file));
+
+ ret = videobuf_querybuf(&pxp->s0_vbq, b);
+ if (!ret) {
+ struct videobuf_buffer *vb = pxp->s0_vbq.bufs[b->index];
+ if (b->flags & V4L2_BUF_FLAG_MAPPED)
+ b->m.offset = videobuf_to_dma_contig(vb);
+ }
+
+ return ret;
+}
+
+static int pxp_qbuf(struct file *file, void *priv,
+ struct v4l2_buffer *b)
+{
+ struct pxps *pxp = video_get_drvdata(video_devdata(file));
+
+ return videobuf_qbuf(&pxp->s0_vbq, b);
+}
+
+static int pxp_dqbuf(struct file *file, void *priv,
+ struct v4l2_buffer *b)
+{
+ struct pxps *pxp = video_get_drvdata(video_devdata(file));
+
+ return videobuf_dqbuf(&pxp->s0_vbq, b, file->f_flags & O_NONBLOCK);
+}
+
+static int pxp_streamon(struct file *file, void *priv,
+ enum v4l2_buf_type t)
+{
+ struct pxps *pxp = video_get_drvdata(video_devdata(file));
+ int ret = 0;
+
+ if (t != V4L2_BUF_TYPE_VIDEO_OUTPUT)
+ return -EINVAL;
+
+ _get_cur_fb_blank(pxp);
+ set_fb_blank(FB_BLANK_UNBLANK);
+
+ ret = videobuf_streamon(&pxp->s0_vbq);
+
+ if (!ret && (pxp->output == 0))
+ pxp_show_buf(pxp, pxp->outbuf.paddr);
+
+ return ret;
+}
+
+static int pxp_streamoff(struct file *file, void *priv,
+ enum v4l2_buf_type t)
+{
+ struct pxps *pxp = video_get_drvdata(video_devdata(file));
+ int ret = 0;
+
+ if ((t != V4L2_BUF_TYPE_VIDEO_OUTPUT))
+ return -EINVAL;
+
+ ret = videobuf_streamoff(&pxp->s0_vbq);
+
+ pxp_show_buf(pxp, (unsigned long)pxp->fb.base);
+
+ if (pxp->fb_blank)
+ set_fb_blank(FB_BLANK_POWERDOWN);
+
+ return ret;
+}
+
+static int pxp_buf_setup(struct videobuf_queue *q,
+ unsigned int *count, unsigned *size)
+{
+ struct pxps *pxp = q->priv_data;
+
+ *size = pxp->pxp_conf.s0_param.width *
+ pxp->pxp_conf.s0_param.height * pxp->s0_fmt->bpp;
+
+ if (0 == *count)
+ *count = PXP_DEF_BUFS;
+
+ return 0;
+}
+
+static void pxp_buf_free(struct videobuf_queue *q, struct pxp_buffer *buf)
+{
+ struct videobuf_buffer *vb = &buf->vb;
+
+ BUG_ON(in_interrupt());
+
+ pr_debug("%s (vb=0x%p) 0x%08lx %d\n", __func__,
+ vb, vb->baddr, vb->bsize);
+
+ /*
+ * This waits until this buffer is out of danger, i.e., until it is no
+ * longer in STATE_QUEUED or STATE_ACTIVE
+ */
+ videobuf_waiton(q, vb, 0, 0);
+
+ videobuf_dma_contig_free(q, vb);
+ buf->txd = NULL;
+
+ vb->state = VIDEOBUF_NEEDS_INIT;
+}
+
+static int pxp_buf_prepare(struct videobuf_queue *q,
+ struct videobuf_buffer *vb,
+ enum v4l2_field field)
+{
+ struct pxps *pxp = q->priv_data;
+ struct pxp_config_data *pxp_conf = &pxp->pxp_conf;
+ struct pxp_proc_data *proc_data = &pxp_conf->proc_data;
+ struct pxp_buffer *buf = container_of(vb, struct pxp_buffer, vb);
+ struct pxp_tx_desc *desc;
+ int ret = 0;
+ int i, length;
+
+ if (!pxp->outbuf.paddr) {
+ dev_err(&pxp->pdev->dev, "Not allocate memory for "
+ "PxP Out buffer?\n");
+ return -ENOMEM;
+ }
+
+ vb->width = pxp->pxp_conf.s0_param.width;
+ vb->height = pxp->pxp_conf.s0_param.height;
+ vb->size = vb->width * vb->height * pxp->s0_fmt->bpp;
+ vb->field = V4L2_FIELD_NONE;
+ if (vb->state != VIDEOBUF_NEEDS_INIT)
+ pxp_buf_free(q, buf);
+
+ if (vb->state == VIDEOBUF_NEEDS_INIT) {
+ struct pxp_channel *pchan = pxp->pxp_channel[0];
+ struct scatterlist *sg = &buf->sg[0];
+
+ /* This actually (allocates and) maps buffers */
+ ret = videobuf_iolock(q, vb, NULL);
+ if (ret) {
+ pr_err("fail to call videobuf_iolock, ret = %d\n", ret);
+ goto fail;
+ }
+
+ /*
+ * sg[0] for input(S0)
+ * Sg[1] for output
+ */
+ sg_init_table(sg, 3);
+
+ buf->txd = pchan->dma_chan.device->device_prep_slave_sg(
+ &pchan->dma_chan, sg, 3, DMA_FROM_DEVICE,
+ DMA_PREP_INTERRUPT, NULL);
+ if (!buf->txd) {
+ ret = -EIO;
+ goto fail;
+ }
+
+ buf->txd->callback_param = buf->txd;
+ buf->txd->callback = video_dma_done;
+
+ desc = to_tx_desc(buf->txd);
+ length = desc->len;
+ for (i = 0; i < length; i++) {
+ if (i == 0) {/* S0 */
+ memcpy(&desc->proc_data, proc_data,
+ sizeof(struct pxp_proc_data));
+ pxp_conf->s0_param.paddr =
+ videobuf_to_dma_contig(vb);
+ memcpy(&desc->layer_param.s0_param,
+ &pxp_conf->s0_param,
+ sizeof(struct pxp_layer_param));
+ } else if (i == 1) { /* Output */
+ /* we should always pass the output
+ * width and height which is the value
+ * after been rotated.
+ */
+ pxp_conf->out_param.width =
+ pxp->fb.fmt.width;
+ pxp_conf->out_param.height =
+ pxp->fb.fmt.height;
+
+ pxp_conf->out_param.paddr = pxp->outbuf.paddr;
+ memcpy(&desc->layer_param.out_param,
+ &pxp_conf->out_param,
+ sizeof(struct pxp_layer_param));
+ } else if (pxp_conf->ol_param[0].combine_enable) {
+ /* Overlay */
+ pxp_conf->ol_param[0].paddr =
+ (dma_addr_t)pxp->fb.base;
+ pxp_conf->ol_param[0].width = pxp->fb.fmt.width;
+ pxp_conf->ol_param[0].height =
+ pxp->fb.fmt.height;
+ pxp_conf->ol_param[0].pixel_fmt =
+ pxp_conf->out_param.pixel_fmt;
+ memcpy(&desc->layer_param.ol_param,
+ &pxp_conf->ol_param[0],
+ sizeof(struct pxp_layer_param));
+ }
+
+ desc = desc->next;
+ }
+
+ vb->state = VIDEOBUF_PREPARED;
+ }
+
+ return 0;
+
+fail:
+ pxp_buf_free(q, buf);
+ return ret;
+}
+
+
+static void pxp_buf_queue(struct videobuf_queue *q,
+ struct videobuf_buffer *vb)
+{
+ struct pxps *pxp = q->priv_data;
+ struct pxp_buffer *buf = container_of(vb, struct pxp_buffer, vb);
+ struct dma_async_tx_descriptor *txd = buf->txd;
+ struct pxp_channel *pchan = pxp->pxp_channel[0];
+ dma_cookie_t cookie;
+
+ BUG_ON(!irqs_disabled());
+
+ list_add_tail(&vb->queue, &pxp->outq);
+
+ if (!pxp->active) {
+ pxp->active = buf;
+ vb->state = VIDEOBUF_ACTIVE;
+ } else {
+ vb->state = VIDEOBUF_QUEUED;
+ }
+
+ spin_unlock_irq(&pxp->lock);
+
+ cookie = txd->tx_submit(txd);
+ dev_dbg(&pxp->pdev->dev, "Submitted cookie %d DMA 0x%08x\n",
+ cookie, sg_dma_address(&buf->sg[0]));
+ mdelay(5);
+ /* trigger ePxP */
+ dma_async_issue_pending(&pchan->dma_chan);
+
+ spin_lock_irq(&pxp->lock);
+
+ if (cookie >= 0)
+ return;
+
+ /* Submit error */
+ pr_err("%s: Submit error\n", __func__);
+ vb->state = VIDEOBUF_PREPARED;
+
+ list_del_init(&vb->queue);
+
+ if (pxp->active == buf)
+ pxp->active = NULL;
+}
+
+static void pxp_buf_release(struct videobuf_queue *q,
+ struct videobuf_buffer *vb)
+{
+ struct pxps *pxp = q->priv_data;
+ struct pxp_buffer *buf = container_of(vb, struct pxp_buffer, vb);
+ unsigned long flags;
+
+ spin_lock_irqsave(&pxp->lock, flags);
+ if ((vb->state == VIDEOBUF_ACTIVE || vb->state == VIDEOBUF_QUEUED) &&
+ !list_empty(&vb->queue)) {
+ vb->state = VIDEOBUF_ERROR;
+
+ list_del_init(&vb->queue);
+ if (pxp->active == buf)
+ pxp->active = NULL;
+ }
+ spin_unlock_irqrestore(&pxp->lock, flags);
+
+ pxp_buf_free(q, buf);
+}
+
+static struct videobuf_queue_ops pxp_vbq_ops = {
+ .buf_setup = pxp_buf_setup,
+ .buf_prepare = pxp_buf_prepare,
+ .buf_queue = pxp_buf_queue,
+ .buf_release = pxp_buf_release,
+};
+
+static int pxp_querycap(struct file *file, void *fh,
+ struct v4l2_capability *cap)
+{
+ struct pxps *pxp = video_get_drvdata(video_devdata(file));
+
+ memset(cap, 0, sizeof(*cap));
+ strcpy(cap->driver, "pxp");
+ strcpy(cap->card, "pxp");
+ strlcpy(cap->bus_info, dev_name(&pxp->pdev->dev),
+ sizeof(cap->bus_info));
+
+ cap->version = (PXP_DRIVER_MAJOR << 8) + PXP_DRIVER_MINOR;
+
+ cap->device_caps = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_OUTPUT |
+ V4L2_CAP_VIDEO_OUTPUT_OVERLAY;
+ cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
+
+ return 0;
+}
+
+static int pxp_g_fbuf(struct file *file, void *priv,
+ struct v4l2_framebuffer *fb)
+{
+ struct pxps *pxp = video_get_drvdata(video_devdata(file));
+
+ memset(fb, 0, sizeof(*fb));
+
+ fb->capability = V4L2_FBUF_CAP_EXTERNOVERLAY |
+ V4L2_FBUF_CAP_CHROMAKEY |
+ V4L2_FBUF_CAP_LOCAL_ALPHA |
+ V4L2_FBUF_CAP_GLOBAL_ALPHA;
+
+ if (pxp->global_alpha_state)
+ fb->flags |= V4L2_FBUF_FLAG_GLOBAL_ALPHA;
+ if (pxp->s1_chromakey_state)
+ fb->flags |= V4L2_FBUF_FLAG_CHROMAKEY;
+
+ return 0;
+}
+
+static int pxp_s_fbuf(struct file *file, void *priv,
+ const struct v4l2_framebuffer *fb)
+{
+ struct pxps *pxp = video_get_drvdata(video_devdata(file));
+
+ pxp->overlay_state =
+ (fb->flags & V4L2_FBUF_FLAG_OVERLAY) != 0;
+ pxp->global_alpha_state =
+ (fb->flags & V4L2_FBUF_FLAG_GLOBAL_ALPHA) != 0;
+ pxp->s1_chromakey_state =
+ (fb->flags & V4L2_FBUF_FLAG_CHROMAKEY) != 0;
+
+ pxp->pxp_conf.ol_param[0].combine_enable = pxp->overlay_state;
+ pxp->pxp_conf.ol_param[0].global_alpha_enable = pxp->global_alpha_state;
+
+ return 0;
+}
+
+static int pxp_g_crop(struct file *file, void *fh,
+ struct v4l2_crop *c)
+{
+ struct pxps *pxp = video_get_drvdata(video_devdata(file));
+
+ if (c->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY)
+ return -EINVAL;
+
+ c->c.left = pxp->pxp_conf.proc_data.drect.left;
+ c->c.top = pxp->pxp_conf.proc_data.drect.top;
+ c->c.width = pxp->pxp_conf.proc_data.drect.width;
+ c->c.height = pxp->pxp_conf.proc_data.drect.height;
+
+ return 0;
+}
+
+static int pxp_s_crop(struct file *file, void *fh,
+ const struct v4l2_crop *c)
+{
+ struct pxps *pxp = video_get_drvdata(video_devdata(file));
+ int l = c->c.left;
+ int t = c->c.top;
+ int w = c->c.width;
+ int h = c->c.height;
+ int fbw = pxp->fb.fmt.width;
+ int fbh = pxp->fb.fmt.height;
+
+ if (c->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY)
+ return -EINVAL;
+
+ /* Constrain parameters to FB limits */
+ w = min(w, fbw);
+ w = max(w, PXP_MIN_PIX);
+ h = min(h, fbh);
+ h = max(h, PXP_MIN_PIX);
+
+ /* Round up values to PxP pixel block */
+ l = roundup(l, PXP_MIN_PIX);
+ t = roundup(t, PXP_MIN_PIX);
+ w = roundup(w, PXP_MIN_PIX);
+ h = roundup(h, PXP_MIN_PIX);
+
+ if ((l + w) > fbw)
+ l = 0;
+ if ((t + h) > fbh)
+ t = 0;
+
+ pxp->pxp_conf.proc_data.drect.left = l;
+ pxp->pxp_conf.proc_data.drect.top = t;
+ pxp->pxp_conf.proc_data.drect.width = w;
+ pxp->pxp_conf.proc_data.drect.height = h;
+
+ memset(pxp->outbuf.vaddr, 0x0, pxp->outbuf.size);
+
+ return 0;
+}
+
+static int pxp_queryctrl(struct file *file, void *priv,
+ struct v4l2_queryctrl *qc)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(pxp_controls); i++)
+ if (qc->id && qc->id == pxp_controls[i].id) {
+ memcpy(qc, &(pxp_controls[i]), sizeof(*qc));
+ return 0;
+ }
+
+ return -EINVAL;
+}
+
+static int pxp_g_ctrl(struct file *file, void *priv,
+ struct v4l2_control *vc)
+{
+ int i;
+
+ struct pxps *pxp = video_get_drvdata(video_devdata(file));
+
+ for (i = 0; i < ARRAY_SIZE(pxp_controls); i++)
+ if (vc->id == pxp_controls[i].id)
+ return pxp_get_cstate(pxp, vc);
+
+ return -EINVAL;
+}
+
+static int pxp_s_ctrl(struct file *file, void *priv,
+ struct v4l2_control *vc)
+{
+ int i;
+ struct pxps *pxp = video_get_drvdata(video_devdata(file));
+
+ for (i = 0; i < ARRAY_SIZE(pxp_controls); i++)
+ if (vc->id == pxp_controls[i].id) {
+ if (vc->value < pxp_controls[i].minimum ||
+ vc->value > pxp_controls[i].maximum)
+ return -ERANGE;
+ return pxp_set_cstate(pxp, vc);
+ }
+
+ memset(pxp->outbuf.vaddr, 0x0, pxp->outbuf.size);
+
+ return -EINVAL;
+}
+
+void pxp_release(struct video_device *vfd)
+{
+ struct pxps *pxp = video_get_drvdata(vfd);
+
+ spin_lock(&pxp->lock);
+ video_device_release(vfd);
+ spin_unlock(&pxp->lock);
+}
+
+static int pxp_open(struct file *file)
+{
+ struct pxps *pxp = video_get_drvdata(video_devdata(file));
+ int ret = 0;
+
+ mutex_lock(&pxp->mutex);
+ pxp->users++;
+
+ if (pxp->users > 1) {
+ pxp->users--;
+ ret = -EBUSY;
+ goto out;
+ }
+out:
+ mutex_unlock(&pxp->mutex);
+ if (ret)
+ return ret;
+
+ ret = pxp_set_fbinfo(pxp);
+ if (ret) {
+ dev_err(&pxp->pdev->dev, "failed to call pxp_set_fbinfo\n");
+ return ret;
+ }
+
+ videobuf_queue_dma_contig_init(&pxp->s0_vbq,
+ &pxp_vbq_ops,
+ &pxp->pdev->dev,
+ &pxp->lock,
+ V4L2_BUF_TYPE_VIDEO_OUTPUT,
+ V4L2_FIELD_NONE,
+ sizeof(struct pxp_buffer),
+ pxp,
+ NULL);
+ dev_dbg(&pxp->pdev->dev, "call pxp_open\n");
+
+ return 0;
+}
+
+static int pxp_close(struct file *file)
+{
+ struct pxps *pxp = video_get_drvdata(video_devdata(file));
+
+ pxp_streamoff(file, NULL, V4L2_BUF_TYPE_VIDEO_OUTPUT);
+ videobuf_stop(&pxp->s0_vbq);
+ videobuf_mmap_free(&pxp->s0_vbq);
+ pxp->active = NULL;
+
+ mutex_lock(&pxp->mutex);
+ pxp->users--;
+ mutex_unlock(&pxp->mutex);
+
+ return 0;
+}
+
+static int pxp_mmap(struct file *file, struct vm_area_struct *vma)
+{
+ struct pxps *pxp = video_get_drvdata(video_devdata(file));
+ int ret;
+
+ ret = videobuf_mmap_mapper(&pxp->s0_vbq, vma);
+
+ return ret;
+}
+
+static const struct v4l2_file_operations pxp_fops = {
+ .owner = THIS_MODULE,
+ .open = pxp_open,
+ .release = pxp_close,
+ .unlocked_ioctl = video_ioctl2,
+ .mmap = pxp_mmap,
+};
+
+static const struct v4l2_ioctl_ops pxp_ioctl_ops = {
+ .vidioc_querycap = pxp_querycap,
+
+ .vidioc_reqbufs = pxp_reqbufs,
+ .vidioc_querybuf = pxp_querybuf,
+ .vidioc_qbuf = pxp_qbuf,
+ .vidioc_dqbuf = pxp_dqbuf,
+
+ .vidioc_streamon = pxp_streamon,
+ .vidioc_streamoff = pxp_streamoff,
+
+ .vidioc_enum_output = pxp_enumoutput,
+ .vidioc_g_output = pxp_g_output,
+ .vidioc_s_output = pxp_s_output,
+
+ .vidioc_enum_fmt_vid_out = pxp_enum_fmt_video_output,
+ .vidioc_try_fmt_vid_out = pxp_try_fmt_video_output,
+ .vidioc_g_fmt_vid_out = pxp_g_fmt_video_output,
+ .vidioc_s_fmt_vid_out = pxp_s_fmt_video_output,
+
+ .vidioc_try_fmt_vid_out_overlay = pxp_try_fmt_output_overlay,
+ .vidioc_g_fmt_vid_out_overlay = pxp_g_fmt_output_overlay,
+ .vidioc_s_fmt_vid_out_overlay = pxp_s_fmt_output_overlay,
+
+ .vidioc_g_fbuf = pxp_g_fbuf,
+ .vidioc_s_fbuf = pxp_s_fbuf,
+
+ .vidioc_g_crop = pxp_g_crop,
+ .vidioc_s_crop = pxp_s_crop,
+
+ .vidioc_queryctrl = pxp_queryctrl,
+ .vidioc_g_ctrl = pxp_g_ctrl,
+ .vidioc_s_ctrl = pxp_s_ctrl,
+};
+
+static const struct video_device pxp_template = {
+ .name = "PxP",
+ .vfl_type = V4L2_CAP_VIDEO_OUTPUT |
+ V4L2_CAP_VIDEO_OVERLAY |
+ V4L2_CAP_STREAMING,
+ .vfl_dir = VFL_DIR_TX,
+ .fops = &pxp_fops,
+ .release = pxp_release,
+ .minor = -1,
+ .ioctl_ops = &pxp_ioctl_ops,
+};
+
+static const struct of_device_id imx_pxpv4l2_dt_ids[] = {
+ { .compatible = "fsl,imx6sl-pxp-v4l2", },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, imx_pxpv4l2_dt_ids);
+
+static int pxp_probe(struct platform_device *pdev)
+{
+ struct pxps *pxp;
+ struct v4l2_device *v4l2_dev;
+ int err = 0;
+
+ pxp = kzalloc(sizeof(*pxp), GFP_KERNEL);
+ if (!pxp) {
+ dev_err(&pdev->dev, "failed to allocate control object\n");
+ err = -ENOMEM;
+ goto exit;
+ }
+
+ dev_set_drvdata(&pdev->dev, pxp);
+
+ v4l2_dev = kzalloc(sizeof(*v4l2_dev), GFP_KERNEL);
+ if (!v4l2_dev) {
+ dev_err(&pdev->dev, "failed to allocate v4l2_dev structure\n");
+ err = -ENOMEM;
+ goto freeirq;
+ }
+
+ err = v4l2_device_register(&pdev->dev, v4l2_dev);
+ if (err) {
+ dev_err(&pdev->dev, "register v4l2 device failed\n");
+ goto freev4l2;
+ }
+
+ INIT_LIST_HEAD(&pxp->outq);
+ spin_lock_init(&pxp->lock);
+ mutex_init(&pxp->mutex);
+
+ pxp->pdev = pdev;
+
+ pxp->vdev = video_device_alloc();
+ if (!pxp->vdev) {
+ dev_err(&pdev->dev, "video_device_alloc() failed\n");
+ err = -ENOMEM;
+ goto relv4l2;
+ }
+
+ memcpy(pxp->vdev, &pxp_template, sizeof(pxp_template));
+ pxp->vdev->v4l2_dev = v4l2_dev;
+ video_set_drvdata(pxp->vdev, pxp);
+
+ err = video_register_device(pxp->vdev, VFL_TYPE_GRABBER, video_nr);
+ if (err) {
+ dev_err(&pdev->dev, "failed to register video device\n");
+ goto freevdev;
+ }
+
+ dev_info(&pdev->dev, "initialized\n");
+
+exit:
+ return err;
+
+freevdev:
+ video_device_release(pxp->vdev);
+relv4l2:
+ v4l2_device_unregister(v4l2_dev);
+freev4l2:
+ kfree(v4l2_dev);
+freeirq:
+ kfree(pxp);
+
+ return err;
+}
+
+static int pxp_remove(struct platform_device *pdev)
+{
+ struct pxps *pxp = platform_get_drvdata(pdev);
+ struct v4l2_device *v4l2_dev = pxp->vdev->v4l2_dev;
+
+ video_unregister_device(pxp->vdev);
+ video_device_release(pxp->vdev);
+ v4l2_device_unregister(v4l2_dev);
+ kfree(v4l2_dev);
+
+ free_dma_buf(pxp, &pxp->outbuf);
+
+ kfree(pxp);
+
+ return 0;
+}
+
+static struct platform_driver pxp_driver = {
+ .driver = {
+ .name = PXP_DRIVER_NAME,
+ .of_match_table = of_match_ptr(imx_pxpv4l2_dt_ids),
+ },
+ .probe = pxp_probe,
+ .remove = pxp_remove,
+};
+
+module_platform_driver(pxp_driver);
+
+module_param(video_nr, int, 0444);
+MODULE_DESCRIPTION("MXC PxP V4L2 driver");
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/platform/mxc/output/mxc_pxp_v4l2.h b/drivers/media/platform/mxc/output/mxc_pxp_v4l2.h
new file mode 100644
index 000000000000..8abb4c17f3fd
--- /dev/null
+++ b/drivers/media/platform/mxc/output/mxc_pxp_v4l2.h
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2010-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 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
+ *
+ */
+/*
+ * Based on STMP378X PxP driver
+ * Copyright 2008-2009 Embedded Alley Solutions, Inc All Rights Reserved.
+ */
+
+#ifndef _MXC_PXP_V4L2_H
+#define _MXC_PXP_V4L2_H
+
+#include <linux/dmaengine.h>
+#include <linux/pxp_dma.h>
+
+struct pxp_buffer {
+ /* Must be first! */
+ struct videobuf_buffer vb;
+
+ /* One descriptor per scatterlist (per frame) */
+ struct dma_async_tx_descriptor *txd;
+
+ struct scatterlist sg[3];
+};
+
+struct dma_mem {
+ void *vaddr;
+ dma_addr_t paddr;
+ size_t size;
+};
+
+struct pxps {
+ struct platform_device *pdev;
+
+ spinlock_t lock;
+ struct mutex mutex;
+ int users;
+
+ struct video_device *vdev;
+
+ struct videobuf_queue s0_vbq;
+ struct pxp_buffer *active;
+ struct list_head outq;
+ struct pxp_channel *pxp_channel[1]; /* We need 1 channel */
+ struct pxp_config_data pxp_conf;
+ struct dma_mem outbuf;
+
+ int output;
+
+ /* Current S0 configuration */
+ struct pxp_data_format *s0_fmt;
+
+ struct fb_info *fbi;
+ struct v4l2_framebuffer fb;
+
+ /* Output overlay support */
+ int overlay_state;
+ int global_alpha_state;
+ u8 global_alpha;
+ int s1_chromakey_state;
+ u32 s1_chromakey;
+
+ int fb_blank;
+};
+
+struct pxp_data_format {
+ char *name;
+ unsigned int bpp;
+ u32 fourcc;
+ enum v4l2_colorspace colorspace;
+};
+
+#endif
diff --git a/drivers/media/platform/mxc/output/mxc_vout.c b/drivers/media/platform/mxc/output/mxc_vout.c
new file mode 100644
index 000000000000..c1d8a8f03255
--- /dev/null
+++ b/drivers/media/platform/mxc/output/mxc_vout.c
@@ -0,0 +1,2331 @@
+/*
+ * Copyright (C) 2011-2015 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/console.h>
+#include <linux/dma-mapping.h>
+#include <linux/init.h>
+#include <linux/ipu-v3.h>
+#include <linux/module.h>
+#include <linux/mxcfb.h>
+#include <linux/mxc_v4l2.h>
+#include <linux/platform_device.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/videodev2.h>
+#include <linux/vmalloc.h>
+
+#include <media/videobuf-dma-contig.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-ioctl.h>
+
+#define UYVY_BLACK (0x00800080)
+#define RGB_BLACK (0x0)
+#define UV_BLACK (0x80)
+#define Y_BLACK (0x0)
+
+#define MAX_FB_NUM 6
+#define FB_BUFS 3
+#define VDOA_FB_BUFS (FB_BUFS - 1)
+#define VALID_HEIGHT_1080P (1080)
+#define FRAME_HEIGHT_1080P (1088)
+#define FRAME_WIDTH_1080P (1920)
+#define CHECK_TILED_1080P_DISPLAY(vout) \
+ ((((vout)->task.input.format == IPU_PIX_FMT_TILED_NV12) || \
+ ((vout)->task.input.format == IPU_PIX_FMT_TILED_NV12F)) &&\
+ ((vout)->task.input.width == FRAME_WIDTH_1080P) && \
+ ((vout)->task.input.height == FRAME_HEIGHT_1080P) && \
+ ((vout)->task.input.crop.w == FRAME_WIDTH_1080P) && \
+ (((vout)->task.input.crop.h == FRAME_HEIGHT_1080P) || \
+ ((vout)->task.input.crop.h == VALID_HEIGHT_1080P)) && \
+ ((vout)->task.output.width == FRAME_WIDTH_1080P) && \
+ ((vout)->task.output.height == VALID_HEIGHT_1080P) && \
+ ((vout)->task.output.crop.w == FRAME_WIDTH_1080P) && \
+ ((vout)->task.output.crop.h == VALID_HEIGHT_1080P))
+#define CHECK_TILED_1080P_STREAM(vout) \
+ ((((vout)->task.input.format == IPU_PIX_FMT_TILED_NV12) || \
+ ((vout)->task.input.format == IPU_PIX_FMT_TILED_NV12F)) &&\
+ ((vout)->task.input.width == FRAME_WIDTH_1080P) && \
+ ((vout)->task.input.crop.w == FRAME_WIDTH_1080P) && \
+ ((vout)->task.input.height == FRAME_HEIGHT_1080P) && \
+ ((vout)->task.input.crop.h == FRAME_HEIGHT_1080P))
+#define IS_PLANAR_PIXEL_FORMAT(format) \
+ (format == IPU_PIX_FMT_NV12 || \
+ format == IPU_PIX_FMT_YUV420P2 || \
+ format == IPU_PIX_FMT_YUV420P || \
+ format == IPU_PIX_FMT_YVU420P || \
+ format == IPU_PIX_FMT_YUV422P || \
+ format == IPU_PIX_FMT_YVU422P || \
+ format == IPU_PIX_FMT_YUV444P)
+
+#define NSEC_PER_FRAME_30FPS (33333333)
+
+struct mxc_vout_fb {
+ char *name;
+ int ipu_id;
+ struct v4l2_rect crop_bounds;
+ unsigned int disp_fmt;
+ bool disp_support_csc;
+ bool disp_support_windows;
+};
+
+struct dma_mem {
+ void *vaddr;
+ dma_addr_t paddr;
+ size_t size;
+};
+
+struct mxc_vout_output {
+ int open_cnt;
+ struct fb_info *fbi;
+ unsigned long fb_smem_start;
+ unsigned long fb_smem_len;
+ struct video_device *vfd;
+ struct mutex mutex;
+ struct mutex task_lock;
+ struct mutex accs_lock;
+ enum v4l2_buf_type type;
+
+ struct videobuf_queue vbq;
+ spinlock_t vbq_lock;
+
+ struct list_head queue_list;
+ struct list_head active_list;
+
+ struct v4l2_rect crop_bounds;
+ unsigned int disp_fmt;
+ struct mxcfb_pos win_pos;
+ bool disp_support_windows;
+ bool disp_support_csc;
+
+ bool fmt_init;
+ bool release;
+ bool linear_bypass_pp;
+ bool vdoa_1080p;
+ bool tiled_bypass_pp;
+ struct v4l2_rect in_rect;
+ struct ipu_task task;
+ struct ipu_task vdoa_task;
+ struct dma_mem vdoa_work;
+ struct dma_mem vdoa_output[VDOA_FB_BUFS];
+
+ bool timer_stop;
+ struct hrtimer timer;
+ struct workqueue_struct *v4l_wq;
+ struct work_struct disp_work;
+ unsigned long frame_count;
+ unsigned long vdi_frame_cnt;
+ ktime_t start_ktime;
+
+ int ctrl_rotate;
+ int ctrl_vflip;
+ int ctrl_hflip;
+
+ dma_addr_t disp_bufs[FB_BUFS];
+
+ struct videobuf_buffer *pre1_vb;
+ struct videobuf_buffer *pre2_vb;
+
+ bool input_crop;
+};
+
+struct mxc_vout_dev {
+ struct device *dev;
+ struct v4l2_device v4l2_dev;
+ struct mxc_vout_output *out[MAX_FB_NUM];
+ int out_num;
+};
+
+/* Driver Configuration macros */
+#define VOUT_NAME "mxc_vout"
+
+/* Variables configurable through module params*/
+static int debug;
+static int vdi_rate_double;
+static int video_nr = 16;
+
+static int mxc_vidioc_s_input_crop(struct mxc_vout_output *vout,
+ const struct v4l2_crop *crop);
+static int mxc_vidioc_g_input_crop(struct mxc_vout_output *vout,
+ struct v4l2_crop *crop);
+/* Module parameters */
+module_param(video_nr, int, S_IRUGO);
+MODULE_PARM_DESC(video_nr, "video device numbers");
+module_param(debug, int, 0600);
+MODULE_PARM_DESC(debug, "Debug level (0-1)");
+module_param(vdi_rate_double, int, 0600);
+MODULE_PARM_DESC(vdi_rate_double, "vdi frame rate double on/off");
+
+static const struct v4l2_fmtdesc mxc_formats[] = {
+ {
+ .description = "RGB565",
+ .pixelformat = V4L2_PIX_FMT_RGB565,
+ },
+ {
+ .description = "BGR24",
+ .pixelformat = V4L2_PIX_FMT_BGR24,
+ },
+ {
+ .description = "RGB24",
+ .pixelformat = V4L2_PIX_FMT_RGB24,
+ },
+ {
+ .description = "RGB32",
+ .pixelformat = V4L2_PIX_FMT_RGB32,
+ },
+ {
+ .description = "BGR32",
+ .pixelformat = V4L2_PIX_FMT_BGR32,
+ },
+ {
+ .description = "NV12",
+ .pixelformat = V4L2_PIX_FMT_NV12,
+ },
+ {
+ .description = "UYVY",
+ .pixelformat = V4L2_PIX_FMT_UYVY,
+ },
+ {
+ .description = "YUYV",
+ .pixelformat = V4L2_PIX_FMT_YUYV,
+ },
+ {
+ .description = "YUV422 planar",
+ .pixelformat = V4L2_PIX_FMT_YUV422P,
+ },
+ {
+ .description = "YUV444",
+ .pixelformat = V4L2_PIX_FMT_YUV444,
+ },
+ {
+ .description = "YUV420",
+ .pixelformat = V4L2_PIX_FMT_YUV420,
+ },
+ {
+ .description = "YVU420",
+ .pixelformat = V4L2_PIX_FMT_YVU420,
+ },
+ {
+ .description = "TILED NV12P",
+ .pixelformat = IPU_PIX_FMT_TILED_NV12,
+ },
+ {
+ .description = "TILED NV12F",
+ .pixelformat = IPU_PIX_FMT_TILED_NV12F,
+ },
+ {
+ .description = "YUV444 planar",
+ .pixelformat = IPU_PIX_FMT_YUV444P,
+ },
+};
+
+#define NUM_MXC_VOUT_FORMATS (ARRAY_SIZE(mxc_formats))
+
+#define DEF_INPUT_WIDTH 320
+#define DEF_INPUT_HEIGHT 240
+
+static int mxc_vidioc_streamoff(struct file *file, void *fh,
+ enum v4l2_buf_type i);
+
+static struct mxc_vout_fb g_fb_setting[MAX_FB_NUM];
+static int config_disp_output(struct mxc_vout_output *vout);
+static void release_disp_output(struct mxc_vout_output *vout);
+
+static DEFINE_MUTEX(gfb_mutex);
+static DEFINE_MUTEX(gfbi_mutex);
+
+static unsigned int get_frame_size(struct mxc_vout_output *vout)
+{
+ unsigned int size;
+
+ if (IPU_PIX_FMT_TILED_NV12 == vout->task.input.format)
+ size = TILED_NV12_FRAME_SIZE(vout->task.input.width,
+ vout->task.input.height);
+ else if (IPU_PIX_FMT_TILED_NV12F == vout->task.input.format) {
+ size = TILED_NV12_FRAME_SIZE(vout->task.input.width,
+ vout->task.input.height/2);
+ size *= 2;
+ } else
+ size = vout->task.input.width * vout->task.input.height *
+ fmt_to_bpp(vout->task.input.format)/8;
+
+ return size;
+}
+
+static void free_dma_buf(struct mxc_vout_output *vout, struct dma_mem *buf)
+{
+ dma_free_coherent(vout->vbq.dev, buf->size, buf->vaddr, buf->paddr);
+ v4l2_dbg(1, debug, vout->vfd->v4l2_dev,
+ "free dma size:0x%x, paddr:0x%x\n",
+ buf->size, buf->paddr);
+ memset(buf, 0, sizeof(*buf));
+}
+
+static int alloc_dma_buf(struct mxc_vout_output *vout, struct dma_mem *buf)
+{
+
+ buf->vaddr = dma_alloc_coherent(vout->vbq.dev, buf->size, &buf->paddr,
+ GFP_DMA | GFP_KERNEL);
+ if (!buf->vaddr) {
+ v4l2_err(vout->vfd->v4l2_dev,
+ "cannot get dma buf size:0x%x\n", buf->size);
+ return -ENOMEM;
+ }
+ v4l2_dbg(1, debug, vout->vfd->v4l2_dev,
+ "alloc dma buf size:0x%x, paddr:0x%x\n", buf->size, buf->paddr);
+ return 0;
+}
+
+static ipu_channel_t get_ipu_channel(struct fb_info *fbi)
+{
+ ipu_channel_t ipu_ch = CHAN_NONE;
+ mm_segment_t old_fs;
+
+ if (fbi->fbops->fb_ioctl) {
+ old_fs = get_fs();
+ set_fs(KERNEL_DS);
+ fbi->fbops->fb_ioctl(fbi, MXCFB_GET_FB_IPU_CHAN,
+ (unsigned long)&ipu_ch);
+ set_fs(old_fs);
+ }
+
+ return ipu_ch;
+}
+
+static unsigned int get_ipu_fmt(struct fb_info *fbi)
+{
+ mm_segment_t old_fs;
+ unsigned int fb_fmt = 0;
+
+ if (fbi->fbops->fb_ioctl) {
+ old_fs = get_fs();
+ set_fs(KERNEL_DS);
+ fbi->fbops->fb_ioctl(fbi, MXCFB_GET_DIFMT,
+ (unsigned long)&fb_fmt);
+ set_fs(old_fs);
+ }
+
+ return fb_fmt;
+}
+
+static void update_display_setting(void)
+{
+ int i;
+ struct fb_info *fbi;
+ struct v4l2_rect bg_crop_bounds[2] = { { 0, 0, 0, 0 }, { 0, 0, 0, 0} };
+
+ mutex_lock(&gfb_mutex);
+ for (i = 0; i < num_registered_fb; i++) {
+ fbi = registered_fb[i];
+
+ memset(&g_fb_setting[i], 0, sizeof(struct mxc_vout_fb));
+
+ if (!strncmp(fbi->fix.id, "DISP3", 5))
+ g_fb_setting[i].ipu_id = 0;
+ else
+ g_fb_setting[i].ipu_id = 1;
+
+ g_fb_setting[i].name = fbi->fix.id;
+ g_fb_setting[i].crop_bounds.left = 0;
+ g_fb_setting[i].crop_bounds.top = 0;
+ g_fb_setting[i].crop_bounds.width = fbi->var.xres;
+ g_fb_setting[i].crop_bounds.height = fbi->var.yres;
+ g_fb_setting[i].disp_fmt = get_ipu_fmt(fbi);
+
+ if (get_ipu_channel(fbi) == MEM_BG_SYNC) {
+ bg_crop_bounds[g_fb_setting[i].ipu_id] =
+ g_fb_setting[i].crop_bounds;
+ g_fb_setting[i].disp_support_csc = true;
+ } else if (get_ipu_channel(fbi) == MEM_FG_SYNC) {
+ g_fb_setting[i].disp_support_csc = true;
+ g_fb_setting[i].disp_support_windows = true;
+ }
+ }
+
+ for (i = 0; i < num_registered_fb; i++) {
+ fbi = registered_fb[i];
+
+ if (get_ipu_channel(fbi) == MEM_FG_SYNC)
+ g_fb_setting[i].crop_bounds =
+ bg_crop_bounds[g_fb_setting[i].ipu_id];
+ }
+ mutex_unlock(&gfb_mutex);
+}
+
+/* called after g_fb_setting filled by update_display_setting */
+static int update_setting_from_fbi(struct mxc_vout_output *vout,
+ struct fb_info *fbi)
+{
+ int i;
+ bool found = false;
+
+ mutex_lock(&gfbi_mutex);
+
+ update_display_setting();
+
+ for (i = 0; i < MAX_FB_NUM; i++) {
+ if (g_fb_setting[i].name) {
+ if (!strcmp(fbi->fix.id, g_fb_setting[i].name)) {
+ vout->crop_bounds = g_fb_setting[i].crop_bounds;
+ vout->disp_fmt = g_fb_setting[i].disp_fmt;
+ vout->disp_support_csc =
+ g_fb_setting[i].disp_support_csc;
+ vout->disp_support_windows =
+ g_fb_setting[i].disp_support_windows;
+ found = true;
+ break;
+ }
+ }
+ }
+
+ if (!found) {
+ v4l2_err(vout->vfd->v4l2_dev, "can not find output\n");
+ mutex_unlock(&gfbi_mutex);
+ return -EINVAL;
+ }
+ strlcpy(vout->vfd->name, fbi->fix.id, sizeof(vout->vfd->name));
+
+ memset(&vout->task, 0, sizeof(struct ipu_task));
+
+ vout->task.input.width = DEF_INPUT_WIDTH;
+ vout->task.input.height = DEF_INPUT_HEIGHT;
+ vout->task.input.crop.pos.x = 0;
+ vout->task.input.crop.pos.y = 0;
+ vout->task.input.crop.w = DEF_INPUT_WIDTH;
+ vout->task.input.crop.h = DEF_INPUT_HEIGHT;
+ vout->input_crop = false;
+
+ vout->task.output.width = vout->crop_bounds.width;
+ vout->task.output.height = vout->crop_bounds.height;
+ vout->task.output.crop.pos.x = 0;
+ vout->task.output.crop.pos.y = 0;
+ vout->task.output.crop.w = vout->crop_bounds.width;
+ vout->task.output.crop.h = vout->crop_bounds.height;
+ if (colorspaceofpixel(vout->disp_fmt) == YUV_CS)
+ vout->task.output.format = IPU_PIX_FMT_UYVY;
+ else
+ vout->task.output.format = IPU_PIX_FMT_RGB565;
+
+ mutex_unlock(&gfbi_mutex);
+ return 0;
+}
+
+static inline unsigned long get_jiffies(struct timeval *t)
+{
+ struct timeval cur;
+
+ if (t->tv_usec >= 1000000) {
+ t->tv_sec += t->tv_usec / 1000000;
+ t->tv_usec = t->tv_usec % 1000000;
+ }
+
+ do_gettimeofday(&cur);
+ if ((t->tv_sec < cur.tv_sec)
+ || ((t->tv_sec == cur.tv_sec) && (t->tv_usec < cur.tv_usec)))
+ return jiffies;
+
+ if (t->tv_usec < cur.tv_usec) {
+ cur.tv_sec = t->tv_sec - cur.tv_sec - 1;
+ cur.tv_usec = t->tv_usec + 1000000 - cur.tv_usec;
+ } else {
+ cur.tv_sec = t->tv_sec - cur.tv_sec;
+ cur.tv_usec = t->tv_usec - cur.tv_usec;
+ }
+
+ return jiffies + timeval_to_jiffies(&cur);
+}
+
+static bool deinterlace_3_field(struct mxc_vout_output *vout)
+{
+ return (vout->task.input.deinterlace.enable &&
+ (vout->task.input.deinterlace.motion != HIGH_MOTION));
+}
+
+static int set_field_fmt(struct mxc_vout_output *vout, enum v4l2_field field)
+{
+ struct ipu_deinterlace *deinterlace = &vout->task.input.deinterlace;
+
+ switch (field) {
+ /* Images are in progressive format, not interlaced */
+ case V4L2_FIELD_NONE:
+ case V4L2_FIELD_ANY:
+ deinterlace->enable = false;
+ deinterlace->field_fmt = 0;
+ v4l2_dbg(1, debug, vout->vfd->v4l2_dev, "Progressive frame.\n");
+ break;
+ case V4L2_FIELD_INTERLACED_TB:
+ v4l2_dbg(1, debug, vout->vfd->v4l2_dev,
+ "Enable deinterlace TB.\n");
+ deinterlace->enable = true;
+ deinterlace->field_fmt = IPU_DEINTERLACE_FIELD_TOP;
+ break;
+ case V4L2_FIELD_INTERLACED_BT:
+ v4l2_dbg(1, debug, vout->vfd->v4l2_dev,
+ "Enable deinterlace BT.\n");
+ deinterlace->enable = true;
+ deinterlace->field_fmt = IPU_DEINTERLACE_FIELD_BOTTOM;
+ break;
+ default:
+ v4l2_err(vout->vfd->v4l2_dev,
+ "field format:%d not supported yet!\n", field);
+ return -EINVAL;
+ }
+
+ if (IPU_PIX_FMT_TILED_NV12F == vout->task.input.format) {
+ v4l2_dbg(1, debug, vout->vfd->v4l2_dev,
+ "tiled fmt enable deinterlace.\n");
+ deinterlace->enable = true;
+ }
+
+ if (deinterlace->enable && vdi_rate_double)
+ deinterlace->field_fmt |= IPU_DEINTERLACE_RATE_EN;
+
+ return 0;
+}
+
+static bool is_pp_bypass(struct mxc_vout_output *vout)
+{
+ if ((IPU_PIX_FMT_TILED_NV12 == vout->task.input.format) ||
+ (IPU_PIX_FMT_TILED_NV12F == vout->task.input.format))
+ return false;
+ if ((vout->task.input.width == vout->task.output.width) &&
+ (vout->task.input.height == vout->task.output.height) &&
+ (vout->task.input.crop.w == vout->task.output.crop.w) &&
+ (vout->task.input.crop.h == vout->task.output.crop.h) &&
+ (vout->task.output.rotate < IPU_ROTATE_HORIZ_FLIP) &&
+ !vout->task.input.deinterlace.enable) {
+ if (vout->disp_support_csc)
+ return true;
+ else if (!need_csc(vout->task.input.format, vout->disp_fmt))
+ return true;
+ /*
+ * input crop show to full output which can show based on
+ * xres_virtual/yres_virtual
+ */
+ } else if ((vout->task.input.crop.w == vout->task.output.crop.w) &&
+ (vout->task.output.crop.w == vout->task.output.width) &&
+ (vout->task.input.crop.h == vout->task.output.crop.h) &&
+ (vout->task.output.crop.h ==
+ vout->task.output.height) &&
+ (vout->task.output.rotate < IPU_ROTATE_HORIZ_FLIP) &&
+ !vout->task.input.deinterlace.enable) {
+ if (vout->disp_support_csc)
+ return true;
+ else if (!need_csc(vout->task.input.format, vout->disp_fmt))
+ return true;
+ }
+ return false;
+}
+
+static void setup_buf_timer(struct mxc_vout_output *vout,
+ struct videobuf_buffer *vb)
+{
+ ktime_t expiry_time, now;
+
+ /* if timestamp is 0, then default to 30fps */
+ if ((vb->ts.tv_sec == 0) && (vb->ts.tv_usec == 0))
+ expiry_time = ktime_add_ns(vout->start_ktime,
+ NSEC_PER_FRAME_30FPS * vout->frame_count);
+ else
+ expiry_time = timeval_to_ktime(vb->ts);
+
+ now = hrtimer_cb_get_time(&vout->timer);
+ if (ktime_after(now, expiry_time)) {
+ v4l2_dbg(1, debug, vout->vfd->v4l2_dev,
+ "warning: timer timeout already expired.\n");
+ expiry_time = now;
+ }
+
+ hrtimer_start(&vout->timer, expiry_time, HRTIMER_MODE_ABS);
+
+ v4l2_dbg(1, debug, vout->vfd->v4l2_dev, "timer handler next "
+ "schedule: %lldnsecs\n", ktime_to_ns(expiry_time));
+}
+
+static int show_buf(struct mxc_vout_output *vout, int idx,
+ struct ipu_pos *ipos)
+{
+ struct fb_info *fbi = vout->fbi;
+ struct fb_var_screeninfo var;
+ int ret;
+ u32 fb_base = 0;
+
+ memcpy(&var, &fbi->var, sizeof(var));
+
+ if (vout->linear_bypass_pp || vout->tiled_bypass_pp) {
+ /*
+ * crack fb base
+ * NOTE: should not do other fb operation during v4l2
+ */
+ console_lock();
+ fb_base = fbi->fix.smem_start;
+ fbi->fix.smem_start = vout->task.output.paddr;
+ fbi->var.yoffset = ipos->y + 1;
+ var.xoffset = ipos->x;
+ var.yoffset = ipos->y;
+ var.vmode |= FB_VMODE_YWRAP;
+ ret = fb_pan_display(fbi, &var);
+ fbi->fix.smem_start = fb_base;
+ console_unlock();
+ } else {
+ console_lock();
+ var.yoffset = idx * fbi->var.yres;
+ var.vmode &= ~FB_VMODE_YWRAP;
+ ret = fb_pan_display(fbi, &var);
+ console_unlock();
+ }
+
+ return ret;
+}
+
+static void disp_work_func(struct work_struct *work)
+{
+ struct mxc_vout_output *vout =
+ container_of(work, struct mxc_vout_output, disp_work);
+ struct videobuf_queue *q = &vout->vbq;
+ struct videobuf_buffer *vb, *vb_next = NULL;
+ unsigned long flags = 0;
+ struct ipu_pos ipos;
+ int ret = 0;
+ u32 in_fmt = 0, in_width = 0, in_height = 0;
+ u32 vdi_cnt = 0;
+ u32 vdi_frame;
+ u32 index = 0;
+ u32 ocrop_h = 0;
+ u32 o_height = 0;
+ u32 tiled_interlaced = 0;
+ bool tiled_fmt = false;
+
+ v4l2_dbg(1, debug, vout->vfd->v4l2_dev, "disp work begin one frame\n");
+
+ spin_lock_irqsave(q->irqlock, flags);
+
+ if (list_empty(&vout->active_list)) {
+ v4l2_warn(vout->vfd->v4l2_dev,
+ "no entry in active_list, should not be here\n");
+ spin_unlock_irqrestore(q->irqlock, flags);
+ return;
+ }
+
+ vb = list_first_entry(&vout->active_list,
+ struct videobuf_buffer, queue);
+ ret = set_field_fmt(vout, vb->field);
+ if (ret < 0) {
+ spin_unlock_irqrestore(q->irqlock, flags);
+ return;
+ }
+ if (deinterlace_3_field(vout)) {
+ if (list_is_singular(&vout->active_list)) {
+ if (list_empty(&vout->queue_list)) {
+ vout->timer_stop = true;
+ spin_unlock_irqrestore(q->irqlock, flags);
+ v4l2_warn(vout->vfd->v4l2_dev,
+ "no enough entry for 3 fields "
+ "deinterlacer\n");
+ return;
+ }
+
+ /*
+ * We need to use the next vb even if it is
+ * not on the active list.
+ */
+ vb_next = list_first_entry(&vout->queue_list,
+ struct videobuf_buffer, queue);
+ } else
+ vb_next = list_first_entry(vout->active_list.next,
+ struct videobuf_buffer, queue);
+ v4l2_dbg(1, debug, vout->vfd->v4l2_dev,
+ "cur field_fmt:%d, next field_fmt:%d.\n",
+ vb->field, vb_next->field);
+ /* repeat the last field during field format changing */
+ if ((vb->field != vb_next->field) &&
+ (vb_next->field != V4L2_FIELD_NONE))
+ vb_next = vb;
+ }
+
+ spin_unlock_irqrestore(q->irqlock, flags);
+
+vdi_frame_rate_double:
+ mutex_lock(&vout->task_lock);
+
+ v4l2_dbg(1, debug, vout->vfd->v4l2_dev,
+ "v4l2 frame_cnt:%ld, vb_field:%d, fmt:%d\n",
+ vout->frame_count, vb->field,
+ vout->task.input.deinterlace.field_fmt);
+ if (vb->memory == V4L2_MEMORY_USERPTR)
+ vout->task.input.paddr = vb->baddr;
+ else
+ vout->task.input.paddr = videobuf_to_dma_contig(vb);
+
+ if (vout->task.input.deinterlace.field_fmt & IPU_DEINTERLACE_RATE_EN)
+ index = vout->vdi_frame_cnt % FB_BUFS;
+ else
+ index = vout->frame_count % FB_BUFS;
+ if (vout->linear_bypass_pp) {
+ vout->task.output.paddr = vout->task.input.paddr;
+ ipos.x = vout->task.input.crop.pos.x;
+ ipos.y = vout->task.input.crop.pos.y;
+ } else {
+ if (deinterlace_3_field(vout)) {
+ if (vb->memory == V4L2_MEMORY_USERPTR)
+ vout->task.input.paddr_n = vb_next->baddr;
+ else
+ vout->task.input.paddr_n =
+ videobuf_to_dma_contig(vb_next);
+ }
+ vout->task.output.paddr = vout->disp_bufs[index];
+ if (vout->vdoa_1080p) {
+ o_height = vout->task.output.height;
+ ocrop_h = vout->task.output.crop.h;
+ vout->task.output.height = FRAME_HEIGHT_1080P;
+ vout->task.output.crop.h = FRAME_HEIGHT_1080P;
+ }
+ tiled_fmt =
+ (IPU_PIX_FMT_TILED_NV12 == vout->task.input.format) ||
+ (IPU_PIX_FMT_TILED_NV12F == vout->task.input.format);
+ if (vout->tiled_bypass_pp) {
+ ipos.x = vout->task.input.crop.pos.x;
+ ipos.y = vout->task.input.crop.pos.y;
+ } else if (tiled_fmt) {
+ vout->vdoa_task.input.paddr = vout->task.input.paddr;
+ if (deinterlace_3_field(vout))
+ vout->vdoa_task.input.paddr_n =
+ vout->task.input.paddr_n;
+ vout->vdoa_task.output.paddr = vout->vdoa_work.paddr;
+ ret = ipu_queue_task(&vout->vdoa_task);
+ if (ret < 0) {
+ mutex_unlock(&vout->task_lock);
+ goto err;
+ }
+ vout->task.input.paddr = vout->vdoa_task.output.paddr;
+ in_fmt = vout->task.input.format;
+ in_width = vout->task.input.width;
+ in_height = vout->task.input.height;
+ vout->task.input.format = vout->vdoa_task.output.format;
+ vout->task.input.width = vout->vdoa_task.output.width;
+ vout->task.input.height = vout->vdoa_task.output.height;
+ if (vout->task.input.deinterlace.enable) {
+ tiled_interlaced = 1;
+ vout->task.input.deinterlace.enable = 0;
+ }
+ v4l2_dbg(1, debug, vout->vfd->v4l2_dev,
+ "tiled queue task\n");
+ }
+ ret = ipu_queue_task(&vout->task);
+ if ((!vout->tiled_bypass_pp) && tiled_fmt) {
+ vout->task.input.format = in_fmt;
+ vout->task.input.width = in_width;
+ vout->task.input.height = in_height;
+ }
+ if (tiled_interlaced)
+ vout->task.input.deinterlace.enable = 1;
+ if (ret < 0) {
+ mutex_unlock(&vout->task_lock);
+ goto err;
+ }
+ if (vout->vdoa_1080p) {
+ vout->task.output.crop.h = ocrop_h;
+ vout->task.output.height = o_height;
+ }
+ }
+
+ mutex_unlock(&vout->task_lock);
+
+ ret = show_buf(vout, index, &ipos);
+ if (ret < 0)
+ v4l2_dbg(1, debug, vout->vfd->v4l2_dev,
+ "show buf with ret %d\n", ret);
+
+ if (vout->task.input.deinterlace.field_fmt & IPU_DEINTERLACE_RATE_EN) {
+ vdi_frame = vout->task.input.deinterlace.field_fmt
+ & IPU_DEINTERLACE_RATE_FRAME1;
+ if (vdi_frame)
+ vout->task.input.deinterlace.field_fmt &=
+ ~IPU_DEINTERLACE_RATE_FRAME1;
+ else
+ vout->task.input.deinterlace.field_fmt |=
+ IPU_DEINTERLACE_RATE_FRAME1;
+ vout->vdi_frame_cnt++;
+ vdi_cnt++;
+ if (vdi_cnt < IPU_DEINTERLACE_MAX_FRAME)
+ goto vdi_frame_rate_double;
+ }
+ spin_lock_irqsave(q->irqlock, flags);
+
+ list_del(&vb->queue);
+
+ /*
+ * The videobuf before the last one has been shown. Set
+ * VIDEOBUF_DONE state here to avoid tearing issue in ic bypass
+ * case, which makes sure a buffer being shown will not be
+ * dequeued to be overwritten. It also brings side-effect that
+ * the last 2 buffers can not be dequeued correctly, apps need
+ * to take care of it.
+ */
+ if (vout->pre2_vb) {
+ vout->pre2_vb->state = VIDEOBUF_DONE;
+ wake_up_interruptible(&vout->pre2_vb->done);
+ vout->pre2_vb = NULL;
+ }
+
+ if (vout->linear_bypass_pp) {
+ vout->pre2_vb = vout->pre1_vb;
+ vout->pre1_vb = vb;
+ } else {
+ if (vout->pre1_vb) {
+ vout->pre1_vb->state = VIDEOBUF_DONE;
+ wake_up_interruptible(&vout->pre1_vb->done);
+ vout->pre1_vb = NULL;
+ }
+ vb->state = VIDEOBUF_DONE;
+ wake_up_interruptible(&vb->done);
+ }
+
+ vout->frame_count++;
+
+ /* pick next queue buf to setup timer */
+ if (list_empty(&vout->queue_list))
+ vout->timer_stop = true;
+ else {
+ vb = list_first_entry(&vout->queue_list,
+ struct videobuf_buffer, queue);
+ setup_buf_timer(vout, vb);
+ }
+
+ spin_unlock_irqrestore(q->irqlock, flags);
+
+ v4l2_dbg(1, debug, vout->vfd->v4l2_dev, "disp work finish one frame\n");
+
+ return;
+err:
+ v4l2_err(vout->vfd->v4l2_dev, "display work fail ret = %d\n", ret);
+ vout->timer_stop = true;
+ vb->state = VIDEOBUF_ERROR;
+ return;
+}
+
+static enum hrtimer_restart mxc_vout_timer_handler(struct hrtimer *timer)
+{
+ struct mxc_vout_output *vout = container_of(timer,
+ struct mxc_vout_output,
+ timer);
+ struct videobuf_queue *q = &vout->vbq;
+ struct videobuf_buffer *vb;
+ unsigned long flags = 0;
+
+ spin_lock_irqsave(q->irqlock, flags);
+
+ /*
+ * put first queued entry into active, if previous entry did not
+ * finish, setup current entry's timer again.
+ */
+ if (list_empty(&vout->queue_list)) {
+ spin_unlock_irqrestore(q->irqlock, flags);
+ return HRTIMER_NORESTART;
+ }
+
+ /* move videobuf from queued list to active list */
+ vb = list_first_entry(&vout->queue_list,
+ struct videobuf_buffer, queue);
+ list_del(&vb->queue);
+ list_add_tail(&vb->queue, &vout->active_list);
+
+ if (queue_work(vout->v4l_wq, &vout->disp_work) == 0) {
+ v4l2_warn(vout->vfd->v4l2_dev,
+ "disp work was in queue already, queue buf again next time\n");
+ list_del(&vb->queue);
+ list_add(&vb->queue, &vout->queue_list);
+ spin_unlock_irqrestore(q->irqlock, flags);
+ return HRTIMER_NORESTART;
+ }
+
+ vb->state = VIDEOBUF_ACTIVE;
+
+ spin_unlock_irqrestore(q->irqlock, flags);
+
+ return HRTIMER_NORESTART;
+}
+
+/* Video buffer call backs */
+
+/*
+ * Buffer setup function is called by videobuf layer when REQBUF ioctl is
+ * called. This is used to setup buffers and return size and count of
+ * buffers allocated. After the call to this buffer, videobuf layer will
+ * setup buffer queue depending on the size and count of buffers
+ */
+static int mxc_vout_buffer_setup(struct videobuf_queue *q, unsigned int *count,
+ unsigned int *size)
+{
+ struct mxc_vout_output *vout = q->priv_data;
+ unsigned int frame_size;
+
+ if (!vout)
+ return -EINVAL;
+
+ if (V4L2_BUF_TYPE_VIDEO_OUTPUT != q->type)
+ return -EINVAL;
+
+ frame_size = get_frame_size(vout);
+ *size = PAGE_ALIGN(frame_size);
+
+ return 0;
+}
+
+/*
+ * This function will be called when VIDIOC_QBUF ioctl is called.
+ * It prepare buffers before give out for the display. This function
+ * converts user space virtual address into physical address if userptr memory
+ * exchange mechanism is used.
+ */
+static int mxc_vout_buffer_prepare(struct videobuf_queue *q,
+ struct videobuf_buffer *vb,
+ enum v4l2_field field)
+{
+ vb->state = VIDEOBUF_PREPARED;
+ return 0;
+}
+
+/*
+ * Buffer queue funtion will be called from the videobuf layer when _QBUF
+ * ioctl is called. It is used to enqueue buffer, which is ready to be
+ * displayed.
+ * This function is protected by q->irqlock.
+ */
+static void mxc_vout_buffer_queue(struct videobuf_queue *q,
+ struct videobuf_buffer *vb)
+{
+ struct mxc_vout_output *vout = q->priv_data;
+ struct videobuf_buffer *active_vb;
+
+ list_add_tail(&vb->queue, &vout->queue_list);
+ vb->state = VIDEOBUF_QUEUED;
+
+ if (vout->timer_stop) {
+ if (deinterlace_3_field(vout) &&
+ !list_empty(&vout->active_list)) {
+ active_vb = list_first_entry(&vout->active_list,
+ struct videobuf_buffer, queue);
+ setup_buf_timer(vout, active_vb);
+ } else {
+ setup_buf_timer(vout, vb);
+ }
+ vout->timer_stop = false;
+ }
+}
+
+/*
+ * Buffer release function is called from videobuf layer to release buffer
+ * which are already allocated
+ */
+static void mxc_vout_buffer_release(struct videobuf_queue *q,
+ struct videobuf_buffer *vb)
+{
+ vb->state = VIDEOBUF_NEEDS_INIT;
+}
+
+static int mxc_vout_mmap(struct file *file, struct vm_area_struct *vma)
+{
+ int ret;
+ struct mxc_vout_output *vout = file->private_data;
+
+ if (!vout)
+ return -ENODEV;
+
+ ret = videobuf_mmap_mapper(&vout->vbq, vma);
+ if (ret < 0)
+ v4l2_err(vout->vfd->v4l2_dev,
+ "offset invalid [offset=0x%lx]\n",
+ (vma->vm_pgoff << PAGE_SHIFT));
+
+ return ret;
+}
+
+static int mxc_vout_release(struct file *file)
+{
+ unsigned int ret = 0;
+ struct videobuf_queue *q;
+ struct mxc_vout_output *vout = file->private_data;
+
+ if (!vout)
+ return 0;
+
+ mutex_lock(&vout->accs_lock);
+ if (--vout->open_cnt == 0) {
+ q = &vout->vbq;
+ if (q->streaming)
+ mxc_vidioc_streamoff(file, vout, vout->type);
+ else {
+ release_disp_output(vout);
+ videobuf_queue_cancel(q);
+ }
+ destroy_workqueue(vout->v4l_wq);
+ ret = videobuf_mmap_free(q);
+ }
+
+ mutex_unlock(&vout->accs_lock);
+ return ret;
+}
+
+static long mxc_vout_ioctl(struct file *file,
+ unsigned int cmd, unsigned long arg)
+{
+ struct mxc_vout_output *vout = file->private_data;
+ struct v4l2_crop crop;
+ int ret;
+
+ switch (cmd) {
+ case VIDIOC_S_INPUT_CROP:
+ if (copy_from_user(&crop, (void __user *)arg, sizeof(struct v4l2_crop)))
+ return -EFAULT;
+ ret = mxc_vidioc_s_input_crop(vout, &crop);
+ break;
+ case VIDIOC_G_INPUT_CROP:
+ mxc_vidioc_g_input_crop(vout, &crop);
+ ret = copy_from_user((void __user *)arg, &crop, sizeof(struct v4l2_crop));
+ break;
+ default:
+ ret = video_ioctl2(file, cmd, arg);
+ }
+ return ret;
+}
+
+static int mxc_vout_open(struct file *file)
+{
+ struct mxc_vout_output *vout = NULL;
+ int ret = 0;
+
+ vout = video_drvdata(file);
+
+ if (vout == NULL)
+ return -ENODEV;
+
+ mutex_lock(&vout->accs_lock);
+ if (vout->open_cnt++ == 0) {
+ vout->ctrl_rotate = 0;
+ vout->ctrl_vflip = 0;
+ vout->ctrl_hflip = 0;
+ ret = update_setting_from_fbi(vout, vout->fbi);
+ if (ret < 0)
+ goto err;
+
+ vout->v4l_wq = create_singlethread_workqueue("v4l2q");
+ if (!vout->v4l_wq) {
+ v4l2_err(vout->vfd->v4l2_dev,
+ "Could not create work queue\n");
+ ret = -ENOMEM;
+ goto err;
+ }
+
+ INIT_WORK(&vout->disp_work, disp_work_func);
+
+ INIT_LIST_HEAD(&vout->queue_list);
+ INIT_LIST_HEAD(&vout->active_list);
+
+ vout->fmt_init = false;
+ vout->frame_count = 0;
+ vout->vdi_frame_cnt = 0;
+
+ vout->win_pos.x = 0;
+ vout->win_pos.y = 0;
+ vout->release = true;
+ }
+
+ file->private_data = vout;
+
+err:
+ mutex_unlock(&vout->accs_lock);
+ return ret;
+}
+
+/*
+ * V4L2 ioctls
+ */
+static int mxc_vidioc_querycap(struct file *file, void *fh,
+ struct v4l2_capability *cap)
+{
+ struct mxc_vout_output *vout = fh;
+
+ strlcpy(cap->driver, VOUT_NAME, sizeof(cap->driver));
+ strlcpy(cap->card, vout->vfd->name, sizeof(cap->card));
+ cap->bus_info[0] = '\0';
+ cap->device_caps = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_OUTPUT;
+ cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
+
+ return 0;
+}
+
+static int mxc_vidioc_enum_fmt_vid_out(struct file *file, void *fh,
+ struct v4l2_fmtdesc *fmt)
+{
+ if (fmt->index >= NUM_MXC_VOUT_FORMATS)
+ return -EINVAL;
+
+ strlcpy(fmt->description, mxc_formats[fmt->index].description,
+ sizeof(fmt->description));
+ fmt->pixelformat = mxc_formats[fmt->index].pixelformat;
+
+ return 0;
+}
+
+static int mxc_vidioc_g_fmt_vid_out(struct file *file, void *fh,
+ struct v4l2_format *f)
+{
+ struct mxc_vout_output *vout = fh;
+
+ f->fmt.pix.width = vout->task.input.width;
+ f->fmt.pix.height = vout->task.input.height;
+ f->fmt.pix.pixelformat = vout->task.input.format;
+ f->fmt.pix.sizeimage = get_frame_size(vout);
+
+ v4l2_dbg(1, debug, vout->vfd->v4l2_dev,
+ "frame_size:0x%x, pix_fmt:0x%x\n",
+ f->fmt.pix.sizeimage,
+ vout->task.input.format);
+
+ return 0;
+}
+
+static inline int ipu_try_task(struct mxc_vout_output *vout)
+{
+ int ret;
+ struct ipu_task *task = &vout->task;
+
+again:
+ ret = ipu_check_task(task);
+ if (ret != IPU_CHECK_OK) {
+ if (ret > IPU_CHECK_ERR_MIN) {
+ if (ret == IPU_CHECK_ERR_SPLIT_INPUTW_OVER ||
+ ret == IPU_CHECK_ERR_W_DOWNSIZE_OVER) {
+ task->input.crop.w -= 8;
+ goto again;
+ }
+ if (ret == IPU_CHECK_ERR_SPLIT_INPUTH_OVER ||
+ ret == IPU_CHECK_ERR_H_DOWNSIZE_OVER) {
+ task->input.crop.h -= 8;
+ goto again;
+ }
+ if (ret == IPU_CHECK_ERR_SPLIT_OUTPUTW_OVER) {
+ if (vout->disp_support_windows) {
+ task->output.width -= 8;
+ task->output.crop.w =
+ task->output.width;
+ } else
+ task->output.crop.w -= 8;
+ goto again;
+ }
+ if (ret == IPU_CHECK_ERR_SPLIT_OUTPUTH_OVER) {
+ if (vout->disp_support_windows) {
+ task->output.height -= 8;
+ task->output.crop.h =
+ task->output.height;
+ } else
+ task->output.crop.h -= 8;
+ goto again;
+ }
+ ret = -EINVAL;
+ }
+ } else
+ ret = 0;
+
+ return ret;
+}
+
+static inline int vdoaipu_try_task(struct mxc_vout_output *vout)
+{
+ int ret;
+ int is_1080p_stream;
+ int in_width, in_height;
+ size_t size;
+ struct ipu_task *ipu_task = &vout->task;
+ struct ipu_crop *icrop = &ipu_task->input.crop;
+ struct ipu_task *vdoa_task = &vout->vdoa_task;
+ u32 deinterlace = 0;
+ u32 in_fmt;
+
+ if (vout->task.input.deinterlace.enable)
+ deinterlace = 1;
+
+ memset(vdoa_task, 0, sizeof(*vdoa_task));
+ vdoa_task->output.format = IPU_PIX_FMT_NV12;
+ memcpy(&vdoa_task->input, &ipu_task->input,
+ sizeof(ipu_task->input));
+ if ((icrop->w % IPU_PIX_FMT_TILED_NV12_MBALIGN) ||
+ (icrop->h % IPU_PIX_FMT_TILED_NV12_MBALIGN)) {
+ vdoa_task->input.crop.w =
+ ALIGN(icrop->w, IPU_PIX_FMT_TILED_NV12_MBALIGN);
+ vdoa_task->input.crop.h =
+ ALIGN(icrop->h, IPU_PIX_FMT_TILED_NV12_MBALIGN);
+ }
+ vdoa_task->output.width = vdoa_task->input.crop.w;
+ vdoa_task->output.height = vdoa_task->input.crop.h;
+ vdoa_task->output.crop.w = vdoa_task->input.crop.w;
+ vdoa_task->output.crop.h = vdoa_task->input.crop.h;
+
+ size = PAGE_ALIGN(vdoa_task->input.crop.w *
+ vdoa_task->input.crop.h *
+ fmt_to_bpp(vdoa_task->output.format)/8);
+ if (size > vout->vdoa_work.size) {
+ if (vout->vdoa_work.vaddr)
+ free_dma_buf(vout, &vout->vdoa_work);
+ vout->vdoa_work.size = size;
+ ret = alloc_dma_buf(vout, &vout->vdoa_work);
+ if (ret < 0)
+ return ret;
+ }
+ ret = ipu_check_task(vdoa_task);
+ if (ret != IPU_CHECK_OK)
+ return -EINVAL;
+
+ is_1080p_stream = CHECK_TILED_1080P_STREAM(vout);
+ if (is_1080p_stream)
+ ipu_task->input.crop.h = VALID_HEIGHT_1080P;
+ in_fmt = ipu_task->input.format;
+ in_width = ipu_task->input.width;
+ in_height = ipu_task->input.height;
+ ipu_task->input.format = vdoa_task->output.format;
+ ipu_task->input.height = vdoa_task->output.height;
+ ipu_task->input.width = vdoa_task->output.width;
+ if (deinterlace)
+ ipu_task->input.deinterlace.enable = 0;
+ ret = ipu_try_task(vout);
+ if (deinterlace)
+ ipu_task->input.deinterlace.enable = 1;
+ ipu_task->input.format = in_fmt;
+ ipu_task->input.width = in_width;
+ ipu_task->input.height = in_height;
+
+ return ret;
+}
+
+static int mxc_vout_try_task(struct mxc_vout_output *vout)
+{
+ int ret = 0;
+ struct ipu_output *output = &vout->task.output;
+ struct ipu_input *input = &vout->task.input;
+ struct ipu_crop *crop = &input->crop;
+ u32 o_height = 0;
+ u32 ocrop_h = 0;
+ bool tiled_fmt = false;
+ bool tiled_need_pp = false;
+
+ vout->vdoa_1080p = CHECK_TILED_1080P_DISPLAY(vout);
+ if (vout->vdoa_1080p) {
+ input->crop.h = FRAME_HEIGHT_1080P;
+ o_height = output->height;
+ ocrop_h = output->crop.h;
+ output->height = FRAME_HEIGHT_1080P;
+ output->crop.h = FRAME_HEIGHT_1080P;
+ }
+
+ if ((IPU_PIX_FMT_TILED_NV12 == input->format) ||
+ (IPU_PIX_FMT_TILED_NV12F == input->format)) {
+ if ((input->width % IPU_PIX_FMT_TILED_NV12_MBALIGN) ||
+ (input->height % IPU_PIX_FMT_TILED_NV12_MBALIGN) ||
+ (crop->pos.x % IPU_PIX_FMT_TILED_NV12_MBALIGN) ||
+ (crop->pos.y % IPU_PIX_FMT_TILED_NV12_MBALIGN)) {
+ v4l2_err(vout->vfd->v4l2_dev,
+ "ERR: tiled fmt needs 16 pixel align.\n");
+ return -EINVAL;
+ }
+ if ((crop->w % IPU_PIX_FMT_TILED_NV12_MBALIGN) ||
+ (crop->h % IPU_PIX_FMT_TILED_NV12_MBALIGN))
+ tiled_need_pp = true;
+ } else {
+ crop->w -= crop->w % 8;
+ crop->h -= crop->h % 8;
+ }
+ /* assume task.output already set by S_CROP */
+ vout->linear_bypass_pp = is_pp_bypass(vout);
+ if (vout->linear_bypass_pp) {
+ v4l2_info(vout->vfd->v4l2_dev, "Bypass IC.\n");
+ output->format = input->format;
+ } else {
+ /* if need CSC, choose IPU-DP or IPU_IC do it */
+ if (vout->disp_support_csc) {
+ if (colorspaceofpixel(input->format) == YUV_CS)
+ output->format = IPU_PIX_FMT_UYVY;
+ else
+ output->format = IPU_PIX_FMT_RGB565;
+ } else {
+ if (colorspaceofpixel(vout->disp_fmt) == YUV_CS)
+ output->format = IPU_PIX_FMT_UYVY;
+ else
+ output->format = IPU_PIX_FMT_RGB565;
+ }
+
+ vout->tiled_bypass_pp = false;
+ if ((IPU_PIX_FMT_TILED_NV12 == input->format) ||
+ (IPU_PIX_FMT_TILED_NV12F == input->format)) {
+ /* check resize/rotate/flip, or csc task */
+ if (!(tiled_need_pp ||
+ (IPU_ROTATE_NONE != output->rotate) ||
+ (input->crop.w != output->crop.w) ||
+ (input->crop.h != output->crop.h) ||
+ (!vout->disp_support_csc &&
+ (colorspaceofpixel(vout->disp_fmt) == RGB_CS)))
+ ) {
+ /* IC bypass */
+ output->format = IPU_PIX_FMT_NV12;
+ v4l2_dbg(1, debug, vout->vfd->v4l2_dev,
+ "tiled bypass pp\n");
+ vout->tiled_bypass_pp = true;
+ }
+ tiled_fmt = true;
+ }
+
+ if ((!vout->tiled_bypass_pp) && tiled_fmt)
+ ret = vdoaipu_try_task(vout);
+ else
+ ret = ipu_try_task(vout);
+ }
+
+ if (vout->vdoa_1080p) {
+ output->height = o_height;
+ output->crop.h = ocrop_h;
+ }
+
+ v4l2_dbg(1, debug, vout->vfd->v4l2_dev,
+ "icrop.w:%u, icrop.h:%u, iw:%u, ih:%u,"
+ "ocrop.w:%u, ocrop.h:%u, ow:%u, oh:%u\n",
+ input->crop.w, input->crop.h,
+ input->width, input->height,
+ output->crop.w, output->crop.h,
+ output->width, output->height);
+ return ret;
+}
+
+static int mxc_vout_try_format(struct mxc_vout_output *vout,
+ struct v4l2_format *f)
+{
+ int ret = 0;
+
+ if ((f->fmt.pix.field != V4L2_FIELD_NONE) &&
+ (IPU_PIX_FMT_TILED_NV12 == vout->task.input.format)) {
+ v4l2_err(vout->vfd->v4l2_dev,
+ "progressive tiled fmt should used V4L2_FIELD_NONE!\n");
+ return -EINVAL;
+ }
+
+ if (vout->input_crop == false) {
+ vout->task.input.crop.pos.x = 0;
+ vout->task.input.crop.pos.y = 0;
+ vout->task.input.crop.w = f->fmt.pix.width;
+ vout->task.input.crop.h = f->fmt.pix.height;
+ }
+
+ vout->task.input.width = f->fmt.pix.width;
+ vout->task.input.height = f->fmt.pix.height;
+ vout->task.input.format = f->fmt.pix.pixelformat;
+
+ ret = set_field_fmt(vout, f->fmt.pix.field);
+ if (ret < 0)
+ return ret;
+
+ ret = mxc_vout_try_task(vout);
+ if (!ret) {
+ f->fmt.pix.width = vout->task.input.crop.w;
+ f->fmt.pix.height = vout->task.input.crop.h;
+ }
+
+ return ret;
+}
+
+static bool mxc_vout_need_fb_reconfig(struct mxc_vout_output *vout,
+ struct mxc_vout_output *pre_vout)
+{
+ if (!vout->vbq.streaming)
+ return false;
+
+ if (vout->tiled_bypass_pp)
+ return true;
+
+ if (vout->linear_bypass_pp != pre_vout->linear_bypass_pp)
+ return true;
+
+ /* cropped output resolution or format are changed */
+ if (vout->task.output.format != pre_vout->task.output.format ||
+ vout->task.output.crop.w != pre_vout->task.output.crop.w ||
+ vout->task.output.crop.h != pre_vout->task.output.crop.h)
+ return true;
+
+ /* overlay: window position or resolution are changed */
+ if (vout->disp_support_windows &&
+ (vout->win_pos.x != pre_vout->win_pos.x ||
+ vout->win_pos.y != pre_vout->win_pos.y ||
+ vout->task.output.width != pre_vout->task.output.width ||
+ vout->task.output.height != pre_vout->task.output.height))
+ return true;
+
+ /* background: cropped position is changed */
+ if (!vout->disp_support_windows &&
+ (vout->task.output.crop.pos.x !=
+ pre_vout->task.output.crop.pos.x ||
+ vout->task.output.crop.pos.y !=
+ pre_vout->task.output.crop.pos.y))
+ return true;
+
+ return false;
+}
+
+static int mxc_vidioc_s_fmt_vid_out(struct file *file, void *fh,
+ struct v4l2_format *f)
+{
+ struct mxc_vout_output *vout = fh;
+ int ret = 0;
+
+ if (vout->vbq.streaming)
+ return -EBUSY;
+
+ mutex_lock(&vout->task_lock);
+ ret = mxc_vout_try_format(vout, f);
+ if (ret >= 0)
+ vout->fmt_init = true;
+ mutex_unlock(&vout->task_lock);
+
+ return ret;
+}
+
+static int mxc_vidioc_cropcap(struct file *file, void *fh,
+ struct v4l2_cropcap *cropcap)
+{
+ struct mxc_vout_output *vout = fh;
+
+ if (cropcap->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
+ return -EINVAL;
+
+ cropcap->bounds = vout->crop_bounds;
+ cropcap->defrect = vout->crop_bounds;
+
+ return 0;
+}
+
+static int mxc_vidioc_g_crop(struct file *file, void *fh,
+ struct v4l2_crop *crop)
+{
+ struct mxc_vout_output *vout = fh;
+
+ if (crop->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
+ return -EINVAL;
+
+ if (vout->disp_support_windows) {
+ crop->c.left = vout->win_pos.x;
+ crop->c.top = vout->win_pos.y;
+ crop->c.width = vout->task.output.width;
+ crop->c.height = vout->task.output.height;
+ } else {
+ if (vout->task.output.crop.w && vout->task.output.crop.h) {
+ crop->c.left = vout->task.output.crop.pos.x;
+ crop->c.top = vout->task.output.crop.pos.y;
+ crop->c.width = vout->task.output.crop.w;
+ crop->c.height = vout->task.output.crop.h;
+ } else {
+ crop->c.left = 0;
+ crop->c.top = 0;
+ crop->c.width = vout->task.output.width;
+ crop->c.height = vout->task.output.height;
+ }
+ }
+
+ return 0;
+}
+
+static int mxc_vidioc_s_crop(struct file *file, void *fh,
+ const struct v4l2_crop *crop)
+{
+ struct mxc_vout_output *vout = fh, *pre_vout;
+ struct v4l2_rect *b = &vout->crop_bounds;
+ struct v4l2_crop fix_up_crop;
+ int ret = 0;
+
+ memcpy(&fix_up_crop, crop, sizeof(*crop));
+
+ if (crop->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
+ return -EINVAL;
+
+ if (crop->c.width < 0 || crop->c.height < 0)
+ return -EINVAL;
+
+ if (crop->c.width == 0)
+ fix_up_crop.c.width = b->width - b->left;
+ if (crop->c.height == 0)
+ fix_up_crop.c.height = b->height - b->top;
+
+ if (crop->c.top < b->top)
+ fix_up_crop.c.top = b->top;
+ if (crop->c.top >= b->top + b->height)
+ fix_up_crop.c.top = b->top + b->height - 1;
+ if (crop->c.height > b->top - crop->c.top + b->height)
+ fix_up_crop.c.height =
+ b->top - fix_up_crop.c.top + b->height;
+
+ if (crop->c.left < b->left)
+ fix_up_crop.c.left = b->left;
+ if (crop->c.left >= b->left + b->width)
+ fix_up_crop.c.left = b->left + b->width - 1;
+ if (crop->c.width > b->left - crop->c.left + b->width)
+ fix_up_crop.c.width =
+ b->left - fix_up_crop.c.left + b->width;
+
+ /* stride line limitation */
+ fix_up_crop.c.height -= fix_up_crop.c.height % 8;
+ fix_up_crop.c.width -= fix_up_crop.c.width % 8;
+ if ((fix_up_crop.c.width <= 0) || (fix_up_crop.c.height <= 0) ||
+ ((fix_up_crop.c.left + fix_up_crop.c.width) >
+ (b->left + b->width)) ||
+ ((fix_up_crop.c.top + fix_up_crop.c.height) >
+ (b->top + b->height))) {
+ v4l2_err(vout->vfd->v4l2_dev, "s_crop err: %d, %d, %d, %d",
+ fix_up_crop.c.left, fix_up_crop.c.top,
+ fix_up_crop.c.width, fix_up_crop.c.height);
+ return -EINVAL;
+ }
+
+ /* the same setting, return */
+ if (vout->disp_support_windows) {
+ if ((vout->win_pos.x == fix_up_crop.c.left) &&
+ (vout->win_pos.y == fix_up_crop.c.top) &&
+ (vout->task.output.crop.w == fix_up_crop.c.width) &&
+ (vout->task.output.crop.h == fix_up_crop.c.height))
+ return 0;
+ } else {
+ if ((vout->task.output.crop.pos.x == fix_up_crop.c.left) &&
+ (vout->task.output.crop.pos.y == fix_up_crop.c.top) &&
+ (vout->task.output.crop.w == fix_up_crop.c.width) &&
+ (vout->task.output.crop.h == fix_up_crop.c.height))
+ return 0;
+ }
+
+ pre_vout = vmalloc(sizeof(*pre_vout));
+ if (!pre_vout)
+ return -ENOMEM;
+
+ /* wait current work finish */
+ if (vout->vbq.streaming)
+ flush_workqueue(vout->v4l_wq);
+
+ mutex_lock(&vout->task_lock);
+
+ memcpy(pre_vout, vout, sizeof(*vout));
+
+ if (vout->disp_support_windows) {
+ vout->task.output.crop.pos.x = 0;
+ vout->task.output.crop.pos.y = 0;
+ vout->win_pos.x = fix_up_crop.c.left;
+ vout->win_pos.y = fix_up_crop.c.top;
+ vout->task.output.width = fix_up_crop.c.width;
+ vout->task.output.height = fix_up_crop.c.height;
+ } else {
+ vout->task.output.crop.pos.x = fix_up_crop.c.left;
+ vout->task.output.crop.pos.y = fix_up_crop.c.top;
+ }
+
+ vout->task.output.crop.w = fix_up_crop.c.width;
+ vout->task.output.crop.h = fix_up_crop.c.height;
+
+ /*
+ * must S_CROP before S_FMT, for fist time S_CROP, will not check
+ * ipu task, it will check in S_FMT, after S_FMT, S_CROP should
+ * check ipu task too.
+ */
+ if (vout->fmt_init) {
+ memcpy(&vout->task.input.crop, &vout->in_rect,
+ sizeof(vout->in_rect));
+ ret = mxc_vout_try_task(vout);
+ if (ret < 0) {
+ v4l2_err(vout->vfd->v4l2_dev,
+ "vout check task failed\n");
+ memcpy(vout, pre_vout, sizeof(*vout));
+ goto done;
+ }
+
+ if (mxc_vout_need_fb_reconfig(vout, pre_vout)) {
+ ret = config_disp_output(vout);
+ if (ret < 0)
+ v4l2_err(vout->vfd->v4l2_dev,
+ "Config display output failed\n");
+ }
+ }
+
+done:
+ vfree(pre_vout);
+ mutex_unlock(&vout->task_lock);
+
+ return ret;
+}
+
+static int mxc_vidioc_queryctrl(struct file *file, void *fh,
+ struct v4l2_queryctrl *ctrl)
+{
+ int ret = 0;
+
+ switch (ctrl->id) {
+ case V4L2_CID_ROTATE:
+ ret = v4l2_ctrl_query_fill(ctrl, 0, 270, 90, 0);
+ break;
+ case V4L2_CID_VFLIP:
+ ret = v4l2_ctrl_query_fill(ctrl, 0, 1, 1, 0);
+ break;
+ case V4L2_CID_HFLIP:
+ ret = v4l2_ctrl_query_fill(ctrl, 0, 1, 1, 0);
+ break;
+ case V4L2_CID_MXC_MOTION:
+ ret = v4l2_ctrl_query_fill(ctrl, 0, 2, 1, 0);
+ break;
+ default:
+ ctrl->name[0] = '\0';
+ ret = -EINVAL;
+ }
+ return ret;
+}
+
+static int mxc_vidioc_g_ctrl(struct file *file, void *fh,
+ struct v4l2_control *ctrl)
+{
+ int ret = 0;
+ struct mxc_vout_output *vout = fh;
+
+ switch (ctrl->id) {
+ case V4L2_CID_ROTATE:
+ ctrl->value = vout->ctrl_rotate;
+ break;
+ case V4L2_CID_VFLIP:
+ ctrl->value = vout->ctrl_vflip;
+ break;
+ case V4L2_CID_HFLIP:
+ ctrl->value = vout->ctrl_hflip;
+ break;
+ case V4L2_CID_MXC_MOTION:
+ if (vout->task.input.deinterlace.enable)
+ ctrl->value = vout->task.input.deinterlace.motion;
+ else
+ ctrl->value = 0;
+ break;
+ default:
+ ret = -EINVAL;
+ }
+ return ret;
+}
+
+static void setup_task_rotation(struct mxc_vout_output *vout)
+{
+ if (vout->ctrl_rotate == 0) {
+ if (vout->ctrl_vflip && vout->ctrl_hflip)
+ vout->task.output.rotate = IPU_ROTATE_180;
+ else if (vout->ctrl_vflip)
+ vout->task.output.rotate = IPU_ROTATE_VERT_FLIP;
+ else if (vout->ctrl_hflip)
+ vout->task.output.rotate = IPU_ROTATE_HORIZ_FLIP;
+ else
+ vout->task.output.rotate = IPU_ROTATE_NONE;
+ } else if (vout->ctrl_rotate == 90) {
+ if (vout->ctrl_vflip && vout->ctrl_hflip)
+ vout->task.output.rotate = IPU_ROTATE_90_LEFT;
+ else if (vout->ctrl_vflip)
+ vout->task.output.rotate = IPU_ROTATE_90_RIGHT_VFLIP;
+ else if (vout->ctrl_hflip)
+ vout->task.output.rotate = IPU_ROTATE_90_RIGHT_HFLIP;
+ else
+ vout->task.output.rotate = IPU_ROTATE_90_RIGHT;
+ } else if (vout->ctrl_rotate == 180) {
+ if (vout->ctrl_vflip && vout->ctrl_hflip)
+ vout->task.output.rotate = IPU_ROTATE_NONE;
+ else if (vout->ctrl_vflip)
+ vout->task.output.rotate = IPU_ROTATE_HORIZ_FLIP;
+ else if (vout->ctrl_hflip)
+ vout->task.output.rotate = IPU_ROTATE_VERT_FLIP;
+ else
+ vout->task.output.rotate = IPU_ROTATE_180;
+ } else if (vout->ctrl_rotate == 270) {
+ if (vout->ctrl_vflip && vout->ctrl_hflip)
+ vout->task.output.rotate = IPU_ROTATE_90_RIGHT;
+ else if (vout->ctrl_vflip)
+ vout->task.output.rotate = IPU_ROTATE_90_RIGHT_HFLIP;
+ else if (vout->ctrl_hflip)
+ vout->task.output.rotate = IPU_ROTATE_90_RIGHT_VFLIP;
+ else
+ vout->task.output.rotate = IPU_ROTATE_90_LEFT;
+ }
+}
+
+static int mxc_vidioc_s_ctrl(struct file *file, void *fh,
+ struct v4l2_control *ctrl)
+{
+ int ret = 0;
+ struct mxc_vout_output *vout = fh, *pre_vout;
+
+ pre_vout = vmalloc(sizeof(*pre_vout));
+ if (!pre_vout)
+ return -ENOMEM;
+
+ /* wait current work finish */
+ if (vout->vbq.streaming)
+ flush_workqueue(vout->v4l_wq);
+
+ mutex_lock(&vout->task_lock);
+
+ memcpy(pre_vout, vout, sizeof(*vout));
+
+ switch (ctrl->id) {
+ case V4L2_CID_ROTATE:
+ {
+ vout->ctrl_rotate = (ctrl->value/90) * 90;
+ if (vout->ctrl_rotate > 270)
+ vout->ctrl_rotate = 270;
+ setup_task_rotation(vout);
+ break;
+ }
+ case V4L2_CID_VFLIP:
+ {
+ vout->ctrl_vflip = ctrl->value;
+ setup_task_rotation(vout);
+ break;
+ }
+ case V4L2_CID_HFLIP:
+ {
+ vout->ctrl_hflip = ctrl->value;
+ setup_task_rotation(vout);
+ break;
+ }
+ case V4L2_CID_MXC_MOTION:
+ {
+ vout->task.input.deinterlace.motion = ctrl->value;
+ break;
+ }
+ default:
+ ret = -EINVAL;
+ goto done;
+ }
+
+ if (vout->fmt_init) {
+ memcpy(&vout->task.input.crop, &vout->in_rect,
+ sizeof(vout->in_rect));
+ ret = mxc_vout_try_task(vout);
+ if (ret < 0) {
+ v4l2_err(vout->vfd->v4l2_dev,
+ "vout check task failed\n");
+ memcpy(vout, pre_vout, sizeof(*vout));
+ goto done;
+ }
+
+ if (mxc_vout_need_fb_reconfig(vout, pre_vout)) {
+ ret = config_disp_output(vout);
+ if (ret < 0)
+ v4l2_err(vout->vfd->v4l2_dev,
+ "Config display output failed\n");
+ }
+ }
+
+done:
+ vfree(pre_vout);
+ mutex_unlock(&vout->task_lock);
+
+ return ret;
+}
+
+static int mxc_vidioc_reqbufs(struct file *file, void *fh,
+ struct v4l2_requestbuffers *req)
+{
+ int ret = 0;
+ struct mxc_vout_output *vout = fh;
+ struct videobuf_queue *q = &vout->vbq;
+
+ if (req->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
+ return -EINVAL;
+
+ /* should not be here after streaming, videobuf_reqbufs will control */
+ mutex_lock(&vout->task_lock);
+
+ ret = videobuf_reqbufs(q, req);
+
+ mutex_unlock(&vout->task_lock);
+ return ret;
+}
+
+static int mxc_vidioc_querybuf(struct file *file, void *fh,
+ struct v4l2_buffer *b)
+{
+ int ret;
+ struct mxc_vout_output *vout = fh;
+
+ ret = videobuf_querybuf(&vout->vbq, b);
+ if (!ret) {
+ /* return physical address */
+ struct videobuf_buffer *vb = vout->vbq.bufs[b->index];
+ if (b->flags & V4L2_BUF_FLAG_MAPPED)
+ b->m.offset = videobuf_to_dma_contig(vb);
+ }
+
+ return ret;
+}
+
+static int mxc_vidioc_qbuf(struct file *file, void *fh,
+ struct v4l2_buffer *buffer)
+{
+ struct mxc_vout_output *vout = fh;
+
+ return videobuf_qbuf(&vout->vbq, buffer);
+}
+
+static int mxc_vidioc_dqbuf(struct file *file, void *fh, struct v4l2_buffer *b)
+{
+ struct mxc_vout_output *vout = fh;
+
+ if (!vout->vbq.streaming)
+ return -EINVAL;
+
+ if (file->f_flags & O_NONBLOCK)
+ return videobuf_dqbuf(&vout->vbq, (struct v4l2_buffer *)b, 1);
+ else
+ return videobuf_dqbuf(&vout->vbq, (struct v4l2_buffer *)b, 0);
+}
+
+static int mxc_vidioc_s_input_crop(struct mxc_vout_output *vout,
+ const struct v4l2_crop *crop)
+{
+ int ret = 0;
+
+ if (crop->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
+ return -EINVAL;
+
+ if (crop->c.width < 0 || crop->c.height < 0)
+ return -EINVAL;
+
+ vout->task.input.crop.pos.x = crop->c.left;
+ vout->task.input.crop.pos.y = crop->c.top;
+ vout->task.input.crop.w = crop->c.width;
+ vout->task.input.crop.h = crop->c.height;
+
+ vout->input_crop = true;
+ memcpy(&vout->in_rect, &vout->task.input.crop, sizeof(vout->in_rect));
+
+ return ret;
+}
+
+static int mxc_vidioc_g_input_crop(struct mxc_vout_output *vout,
+ struct v4l2_crop *crop)
+{
+ int ret = 0;
+
+ crop->c.left = vout->task.input.crop.pos.x;
+ crop->c.top = vout->task.input.crop.pos.y;
+ crop->c.width = vout->task.input.crop.w;
+ crop->c.height = vout->task.input.crop.h;
+
+ return ret;
+}
+
+static int set_window_position(struct mxc_vout_output *vout,
+ struct mxcfb_pos *pos)
+{
+ struct fb_info *fbi = vout->fbi;
+ mm_segment_t old_fs;
+ int ret = 0;
+
+ if (vout->disp_support_windows) {
+ old_fs = get_fs();
+ set_fs(KERNEL_DS);
+ ret = fbi->fbops->fb_ioctl(fbi, MXCFB_SET_OVERLAY_POS,
+ (unsigned long)pos);
+ set_fs(old_fs);
+ }
+
+ return ret;
+}
+
+static int config_disp_output(struct mxc_vout_output *vout)
+{
+ struct dma_mem *buf = NULL;
+ struct fb_info *fbi = vout->fbi;
+ struct fb_var_screeninfo var;
+ struct mxcfb_pos pos;
+ int i, fb_num, ret;
+ u32 fb_base;
+ u32 size;
+ u32 display_buf_size;
+ u32 *pixel = NULL;
+ u32 color;
+ int j;
+
+ memcpy(&var, &fbi->var, sizeof(var));
+ fb_base = fbi->fix.smem_start;
+
+ var.xres = vout->task.output.width;
+ var.yres = vout->task.output.height;
+ if (vout->linear_bypass_pp || vout->tiled_bypass_pp) {
+ fb_num = 1;
+ /* input crop */
+ if (vout->task.input.width > vout->task.output.width)
+ var.xres_virtual = vout->task.input.width;
+ else
+ var.xres_virtual = var.xres;
+ if (vout->task.input.height > vout->task.output.height)
+ var.yres_virtual = vout->task.input.height;
+ else
+ var.yres_virtual = var.yres;
+ var.rotate = vout->task.output.rotate;
+ var.vmode |= FB_VMODE_YWRAP;
+ } else {
+ fb_num = FB_BUFS;
+ var.xres_virtual = var.xres;
+ var.yres_virtual = fb_num * var.yres;
+ var.vmode &= ~FB_VMODE_YWRAP;
+ }
+ var.bits_per_pixel = fmt_to_bpp(vout->task.output.format);
+ var.nonstd = vout->task.output.format;
+
+ v4l2_dbg(1, debug, vout->vfd->v4l2_dev,
+ "set display fb to %d %d\n",
+ var.xres, var.yres);
+
+ /*
+ * To setup the overlay fb from scratch without
+ * the last time overlay fb position or resolution's
+ * impact, we take the following steps:
+ * - blank fb
+ * - set fb position to the starting point
+ * - reconfigure fb
+ * - set fb position to a specific point
+ * - unblank fb
+ * This procedure applies to non-overlay fbs as well.
+ */
+ console_lock();
+ fbi->flags |= FBINFO_MISC_USEREVENT;
+ fb_blank(fbi, FB_BLANK_POWERDOWN);
+ fbi->flags &= ~FBINFO_MISC_USEREVENT;
+ console_unlock();
+
+ pos.x = 0;
+ pos.y = 0;
+ ret = set_window_position(vout, &pos);
+ if (ret < 0) {
+ v4l2_err(vout->vfd->v4l2_dev, "failed to set fb position "
+ "to starting point\n");
+ return ret;
+ }
+
+ /* Init display channel through fb API */
+ var.yoffset = 0;
+ var.activate |= FB_ACTIVATE_FORCE;
+ console_lock();
+ fbi->flags |= FBINFO_MISC_USEREVENT;
+ ret = fb_set_var(fbi, &var);
+ fbi->flags &= ~FBINFO_MISC_USEREVENT;
+ console_unlock();
+ if (ret < 0) {
+ v4l2_err(vout->vfd->v4l2_dev,
+ "ERR:%s fb_set_var ret:%d\n", __func__, ret);
+ return ret;
+ }
+
+ ret = set_window_position(vout, &vout->win_pos);
+ if (ret < 0) {
+ v4l2_err(vout->vfd->v4l2_dev, "failed to set fb position\n");
+ return ret;
+ }
+
+ if (vout->linear_bypass_pp || vout->tiled_bypass_pp)
+ display_buf_size = fbi->fix.line_length * fbi->var.yres_virtual;
+ else
+ display_buf_size = fbi->fix.line_length * fbi->var.yres;
+ for (i = 0; i < fb_num; i++)
+ vout->disp_bufs[i] = fbi->fix.smem_start + i * display_buf_size;
+ if (vout->tiled_bypass_pp) {
+ size = PAGE_ALIGN(vout->task.input.crop.w *
+ vout->task.input.crop.h *
+ fmt_to_bpp(vout->task.output.format)/8);
+ if (size > vout->vdoa_output[0].size) {
+ for (i = 0; i < VDOA_FB_BUFS; i++) {
+ buf = &vout->vdoa_output[i];
+ if (buf->vaddr)
+ free_dma_buf(vout, buf);
+ buf->size = size;
+ ret = alloc_dma_buf(vout, buf);
+ if (ret < 0)
+ goto err;
+ }
+ }
+ for (i = fb_num; i < (fb_num + VDOA_FB_BUFS); i++)
+ vout->disp_bufs[i] =
+ vout->vdoa_output[i - fb_num].paddr;
+ }
+ vout->fb_smem_len = fbi->fix.smem_len;
+ vout->fb_smem_start = fbi->fix.smem_start;
+ if (fb_base != fbi->fix.smem_start) {
+ v4l2_dbg(1, debug, vout->vfd->v4l2_dev,
+ "realloc fb mem size:0x%x@0x%lx,old paddr @0x%x\n",
+ fbi->fix.smem_len, fbi->fix.smem_start, fb_base);
+ }
+
+ /* fill black when video config changed */
+ color = colorspaceofpixel(vout->task.output.format) == YUV_CS ?
+ UYVY_BLACK : RGB_BLACK;
+ if (IS_PLANAR_PIXEL_FORMAT(vout->task.output.format)) {
+ size = display_buf_size * 8 /
+ fmt_to_bpp(vout->task.output.format);
+ memset(fbi->screen_base, Y_BLACK, size);
+ memset(fbi->screen_base + size, UV_BLACK,
+ display_buf_size - size);
+ } else {
+ pixel = (u32 *)fbi->screen_base;
+ for (i = 0; i < ((display_buf_size * fb_num) >> 2); i++)
+ *pixel++ = color;
+ }
+ console_lock();
+ fbi->flags |= FBINFO_MISC_USEREVENT;
+ ret = fb_blank(fbi, FB_BLANK_UNBLANK);
+ fbi->flags &= ~FBINFO_MISC_USEREVENT;
+ console_unlock();
+ vout->release = false;
+
+ return ret;
+err:
+ for (j = i - 1; j >= 0; j--) {
+ buf = &vout->vdoa_output[j];
+ if (buf->vaddr)
+ free_dma_buf(vout, buf);
+ }
+ return ret;
+}
+
+static inline void wait_for_vsync(struct mxc_vout_output *vout)
+{
+ struct fb_info *fbi = vout->fbi;
+ mm_segment_t old_fs;
+
+ if (fbi->fbops->fb_ioctl) {
+ old_fs = get_fs();
+ set_fs(KERNEL_DS);
+ fbi->fbops->fb_ioctl(fbi, MXCFB_WAIT_FOR_VSYNC,
+ (unsigned long)NULL);
+ set_fs(old_fs);
+ }
+
+ return;
+}
+
+static void release_disp_output(struct mxc_vout_output *vout)
+{
+ struct fb_info *fbi = vout->fbi;
+ struct mxcfb_pos pos;
+
+ if (vout->release)
+ return;
+ console_lock();
+ fbi->flags |= FBINFO_MISC_USEREVENT;
+ fb_blank(fbi, FB_BLANK_POWERDOWN);
+ fbi->flags &= ~FBINFO_MISC_USEREVENT;
+ console_unlock();
+
+ /* restore pos to 0,0 avoid fb pan display hang? */
+ pos.x = 0;
+ pos.y = 0;
+ set_window_position(vout, &pos);
+
+ if (get_ipu_channel(fbi) == MEM_BG_SYNC) {
+ console_lock();
+ fbi->fix.smem_start = vout->disp_bufs[0];
+ fbi->flags |= FBINFO_MISC_USEREVENT;
+ fb_blank(fbi, FB_BLANK_UNBLANK);
+ fbi->flags &= ~FBINFO_MISC_USEREVENT;
+ console_unlock();
+
+ }
+
+ vout->release = true;
+}
+
+static int mxc_vidioc_streamon(struct file *file, void *fh,
+ enum v4l2_buf_type i)
+{
+ struct mxc_vout_output *vout = fh;
+ struct videobuf_queue *q = &vout->vbq;
+ int ret;
+
+ if (q->streaming) {
+ v4l2_err(vout->vfd->v4l2_dev,
+ "video output already run\n");
+ ret = -EBUSY;
+ goto done;
+ }
+
+ if (deinterlace_3_field(vout) && list_is_singular(&q->stream)) {
+ v4l2_err(vout->vfd->v4l2_dev,
+ "deinterlacing: need queue 2 frame before streamon\n");
+ ret = -EINVAL;
+ goto done;
+ }
+
+ ret = config_disp_output(vout);
+ if (ret < 0) {
+ v4l2_err(vout->vfd->v4l2_dev,
+ "Config display output failed\n");
+ goto done;
+ }
+
+ hrtimer_init(&vout->timer, CLOCK_REALTIME, HRTIMER_MODE_ABS);
+ vout->timer.function = mxc_vout_timer_handler;
+ vout->timer_stop = true;
+ vout->frame_count = 0;
+ vout->vdi_frame_cnt = 0;
+
+ vout->start_ktime = hrtimer_cb_get_time(&vout->timer);
+
+ vout->pre1_vb = NULL;
+ vout->pre2_vb = NULL;
+
+ ret = videobuf_streamon(q);
+done:
+ return ret;
+}
+
+static int mxc_vidioc_streamoff(struct file *file, void *fh,
+ enum v4l2_buf_type i)
+{
+ struct mxc_vout_output *vout = fh;
+ struct videobuf_queue *q = &vout->vbq;
+ int ret = 0;
+
+ if (q->streaming) {
+ flush_workqueue(vout->v4l_wq);
+
+ hrtimer_cancel(&vout->timer);
+
+ /*
+ * Wait for 2 vsyncs to make sure
+ * frames are drained on triple
+ * buffer.
+ */
+ wait_for_vsync(vout);
+ wait_for_vsync(vout);
+
+ release_disp_output(vout);
+
+ ret = videobuf_streamoff(&vout->vbq);
+ }
+ INIT_LIST_HEAD(&vout->queue_list);
+ INIT_LIST_HEAD(&vout->active_list);
+
+ return ret;
+}
+
+static const struct v4l2_ioctl_ops mxc_vout_ioctl_ops = {
+ .vidioc_querycap = mxc_vidioc_querycap,
+ .vidioc_enum_fmt_vid_out = mxc_vidioc_enum_fmt_vid_out,
+ .vidioc_g_fmt_vid_out = mxc_vidioc_g_fmt_vid_out,
+ .vidioc_s_fmt_vid_out = mxc_vidioc_s_fmt_vid_out,
+ .vidioc_cropcap = mxc_vidioc_cropcap,
+ .vidioc_g_crop = mxc_vidioc_g_crop,
+ .vidioc_s_crop = mxc_vidioc_s_crop,
+ .vidioc_queryctrl = mxc_vidioc_queryctrl,
+ .vidioc_g_ctrl = mxc_vidioc_g_ctrl,
+ .vidioc_s_ctrl = mxc_vidioc_s_ctrl,
+ .vidioc_reqbufs = mxc_vidioc_reqbufs,
+ .vidioc_querybuf = mxc_vidioc_querybuf,
+ .vidioc_qbuf = mxc_vidioc_qbuf,
+ .vidioc_dqbuf = mxc_vidioc_dqbuf,
+ .vidioc_streamon = mxc_vidioc_streamon,
+ .vidioc_streamoff = mxc_vidioc_streamoff,
+};
+
+static const struct v4l2_file_operations mxc_vout_fops = {
+ .owner = THIS_MODULE,
+ .unlocked_ioctl = mxc_vout_ioctl,
+ .mmap = mxc_vout_mmap,
+ .open = mxc_vout_open,
+ .release = mxc_vout_release,
+};
+
+static struct video_device mxc_vout_template = {
+ .name = "MXC Video Output",
+ .fops = &mxc_vout_fops,
+ .ioctl_ops = &mxc_vout_ioctl_ops,
+ .release = video_device_release,
+};
+
+static struct videobuf_queue_ops mxc_vout_vbq_ops = {
+ .buf_setup = mxc_vout_buffer_setup,
+ .buf_prepare = mxc_vout_buffer_prepare,
+ .buf_release = mxc_vout_buffer_release,
+ .buf_queue = mxc_vout_buffer_queue,
+};
+
+static void mxc_vout_free_output(struct mxc_vout_dev *dev)
+{
+ int i;
+ int j;
+ struct mxc_vout_output *vout;
+ struct video_device *vfd;
+
+ for (i = 0; i < dev->out_num; i++) {
+ vout = dev->out[i];
+ vfd = vout->vfd;
+ if (vout->vdoa_work.vaddr)
+ free_dma_buf(vout, &vout->vdoa_work);
+ for (j = 0; j < VDOA_FB_BUFS; j++) {
+ if (vout->vdoa_output[j].vaddr)
+ free_dma_buf(vout, &vout->vdoa_output[j]);
+ }
+ if (vfd) {
+ if (!video_is_registered(vfd))
+ video_device_release(vfd);
+ else
+ video_unregister_device(vfd);
+ }
+ kfree(vout);
+ }
+}
+
+static int mxc_vout_setup_output(struct mxc_vout_dev *dev)
+{
+ struct videobuf_queue *q;
+ struct fb_info *fbi;
+ struct mxc_vout_output *vout;
+ int i, ret = 0;
+
+ update_display_setting();
+
+ /* all output/overlay based on fb */
+ for (i = 0; i < num_registered_fb; i++) {
+ fbi = registered_fb[i];
+
+ vout = kzalloc(sizeof(struct mxc_vout_output), GFP_KERNEL);
+ if (!vout) {
+ ret = -ENOMEM;
+ break;
+ }
+
+ dev->out[dev->out_num] = vout;
+ dev->out_num++;
+
+ vout->fbi = fbi;
+ vout->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
+ vout->vfd = video_device_alloc();
+ if (!vout->vfd) {
+ ret = -ENOMEM;
+ break;
+ }
+
+ *vout->vfd = mxc_vout_template;
+ vout->vfd->v4l2_dev = &dev->v4l2_dev;
+ vout->vfd->lock = &vout->mutex;
+ vout->vfd->vfl_dir = VFL_DIR_TX;
+
+ mutex_init(&vout->mutex);
+ mutex_init(&vout->task_lock);
+ mutex_init(&vout->accs_lock);
+
+ strlcpy(vout->vfd->name, fbi->fix.id, sizeof(vout->vfd->name));
+
+ video_set_drvdata(vout->vfd, vout);
+
+ if (video_register_device(vout->vfd,
+ VFL_TYPE_GRABBER, video_nr + i) < 0) {
+ ret = -ENODEV;
+ break;
+ }
+
+ q = &vout->vbq;
+ q->dev = dev->dev;
+ spin_lock_init(&vout->vbq_lock);
+ videobuf_queue_dma_contig_init(q, &mxc_vout_vbq_ops, q->dev,
+ &vout->vbq_lock, vout->type, V4L2_FIELD_NONE,
+ sizeof(struct videobuf_buffer), vout, NULL);
+
+ v4l2_info(vout->vfd->v4l2_dev, "V4L2 device registered as %s\n",
+ video_device_node_name(vout->vfd));
+
+ }
+
+ return ret;
+}
+
+static int mxc_vout_probe(struct platform_device *pdev)
+{
+ int ret;
+ struct mxc_vout_dev *dev;
+
+ dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+ if (!dev)
+ return -ENOMEM;
+
+ dev->dev = &pdev->dev;
+ dev->dev->dma_mask = kmalloc(sizeof(*dev->dev->dma_mask), GFP_KERNEL);
+ *dev->dev->dma_mask = DMA_BIT_MASK(32);
+ dev->dev->coherent_dma_mask = DMA_BIT_MASK(32);
+
+ ret = v4l2_device_register(dev->dev, &dev->v4l2_dev);
+ if (ret) {
+ dev_err(dev->dev, "v4l2_device_register failed\n");
+ goto free_dev;
+ }
+
+ ret = mxc_vout_setup_output(dev);
+ if (ret < 0)
+ goto rel_vdev;
+
+ return 0;
+
+rel_vdev:
+ mxc_vout_free_output(dev);
+ v4l2_device_unregister(&dev->v4l2_dev);
+free_dev:
+ kfree(dev);
+ return ret;
+}
+
+static int mxc_vout_remove(struct platform_device *pdev)
+{
+ struct v4l2_device *v4l2_dev = platform_get_drvdata(pdev);
+ struct mxc_vout_dev *dev = container_of(v4l2_dev, struct
+ mxc_vout_dev, v4l2_dev);
+
+ mxc_vout_free_output(dev);
+ v4l2_device_unregister(v4l2_dev);
+ kfree(dev);
+ return 0;
+}
+
+static const struct of_device_id mxc_v4l2_dt_ids[] = {
+ { .compatible = "fsl,mxc_v4l2_output", },
+ { /* sentinel */ }
+};
+
+static struct platform_driver mxc_vout_driver = {
+ .driver = {
+ .name = "mxc_v4l2_output",
+ .of_match_table = mxc_v4l2_dt_ids,
+ },
+ .probe = mxc_vout_probe,
+ .remove = mxc_vout_remove,
+};
+
+static int __init mxc_vout_init(void)
+{
+ if (platform_driver_register(&mxc_vout_driver) != 0) {
+ printk(KERN_ERR VOUT_NAME ":Could not register Video driver\n");
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static void mxc_vout_cleanup(void)
+{
+ platform_driver_unregister(&mxc_vout_driver);
+}
+
+module_init(mxc_vout_init);
+module_exit(mxc_vout_cleanup);
+
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("V4L2-driver for MXC video output");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/radio/radio-si476x.c b/drivers/media/radio/radio-si476x.c
index 271f725b17e8..1ed7a15dd360 100644
--- a/drivers/media/radio/radio-si476x.c
+++ b/drivers/media/radio/radio-si476x.c
@@ -775,7 +775,8 @@ static int si476x_radio_s_hw_freq_seek(struct file *file, void *priv,
rangelow = si476x_to_v4l2(radio->core, rangelow);
else
goto unlock;
- }
+ } else
+ rangelow = seek->rangelow;
if (!seek->rangehigh) {
err = regmap_read(radio->core->regmap,
SI476X_PROP_SEEK_BAND_TOP,
@@ -784,7 +785,8 @@ static int si476x_radio_s_hw_freq_seek(struct file *file, void *priv,
rangehigh = si476x_to_v4l2(radio->core, rangehigh);
else
goto unlock;
- }
+ } else
+ rangehigh = seek->rangehigh;
if (rangelow > rangehigh) {
err = -EINVAL;
@@ -1008,6 +1010,14 @@ static int si476x_radio_s_ctrl(struct v4l2_ctrl *ctrl)
}
break;
+ case V4L2_CID_AUDIO_MUTE:
+ if (ctrl->val)
+ retval = regmap_write(radio->core->regmap,
+ SI476X_PROP_AUDIO_MUTE, 3);
+ else
+ retval = regmap_write(radio->core->regmap,
+ SI476X_PROP_AUDIO_MUTE, 0);
+ break;
default:
retval = -EINVAL;
break;
@@ -1527,6 +1537,16 @@ static int si476x_radio_probe(struct platform_device *pdev)
goto exit;
}
+ ctrl = v4l2_ctrl_new_std(&radio->ctrl_handler, &si476x_ctrl_ops,
+ V4L2_CID_AUDIO_MUTE,
+ 0, 1, 1, 0);
+ rval = radio->ctrl_handler.error;
+ if (ctrl == NULL && rval) {
+ dev_err(&pdev->dev, "Could not initialize V4L2_CID_AUDIO_MUTE control %d\n",
+ rval);
+ goto exit;
+ }
+
if (si476x_core_has_diversity(radio->core)) {
si476x_ctrls[SI476X_IDX_DIVERSITY_MODE].def =
si476x_phase_diversity_mode_to_idx(radio->core->diversity_mode);
diff --git a/drivers/media/v4l2-core/v4l2-async.c b/drivers/media/v4l2-core/v4l2-async.c
index d741a8e0fdac..171c07ab31cf 100644
--- a/drivers/media/v4l2-core/v4l2-async.c
+++ b/drivers/media/v4l2-core/v4l2-async.c
@@ -224,7 +224,14 @@ void v4l2_async_notifier_unregister(struct v4l2_async_notifier *notifier)
v4l2_async_cleanup(sd);
/* If we handled USB devices, we'd have to lock the parent too */
+ /*
+ * If anyone calls v4l2_async_notifier_unregister() recursively from
+ * device_release_driver(), code will deadlock at list_lock,
+ * so unlock list_lock when device_release_driver() called.
+ */
+ mutex_unlock(&list_lock);
device_release_driver(d);
+ mutex_lock(&list_lock);
if (notifier->unbind)
notifier->unbind(notifier, sd, sd->asd);
diff --git a/drivers/media/v4l2-core/v4l2-dev.c b/drivers/media/v4l2-core/v4l2-dev.c
index c647ba648805..6351ddc510dd 100644
--- a/drivers/media/v4l2-core/v4l2-dev.c
+++ b/drivers/media/v4l2-core/v4l2-dev.c
@@ -360,6 +360,34 @@ static long v4l2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
ret = vdev->fops->unlocked_ioctl(filp, cmd, arg);
if (lock)
mutex_unlock(lock);
+ } else if (vdev->fops->ioctl) {
+ /* This code path is a replacement for the BKL. It is a major
+ * hack but it will have to do for those drivers that are not
+ * yet converted to use unlocked_ioctl.
+ *
+ * All drivers implement struct v4l2_device, so we use the
+ * lock defined there to serialize the ioctls.
+ *
+ * However, if the driver sleeps, then it blocks all ioctls
+ * since the lock is still held. This is very common for
+ * VIDIOC_DQBUF since that normally waits for a frame to arrive.
+ * As a result any other ioctl calls will proceed very, very
+ * slowly since each call will have to wait for the VIDIOC_QBUF
+ * to finish. Things that should take 0.01s may now take 10-20
+ * seconds.
+ *
+ * The workaround is to *not* take the lock for VIDIOC_DQBUF.
+ * This actually works OK for videobuf-based drivers, since
+ * videobuf will take its own internal lock.
+ */
+ struct mutex *m = &vdev->v4l2_dev->ioctl_lock;
+
+ if (cmd != VIDIOC_DQBUF && mutex_lock_interruptible(m))
+ return -ERESTARTSYS;
+ if (video_is_registered(vdev))
+ ret = vdev->fops->ioctl(filp, cmd, arg);
+ if (cmd != VIDIOC_DQBUF)
+ mutex_unlock(m);
} else
ret = -ENOTTY;
@@ -567,6 +595,7 @@ static void determine_valid_ioctls(struct video_device *vdev)
set_bit(_IOC_NR(VIDIOC_DBG_G_REGISTER), valid_ioctls);
set_bit(_IOC_NR(VIDIOC_DBG_S_REGISTER), valid_ioctls);
#endif
+ SET_VALID_IOCTL(ops, VIDIOC_DBG_G_CHIP_IDENT, vidioc_g_chip_ident);
/* yes, really vidioc_subscribe_event */
SET_VALID_IOCTL(ops, VIDIOC_DQEVENT, vidioc_subscribe_event);
SET_VALID_IOCTL(ops, VIDIOC_SUBSCRIBE_EVENT, vidioc_subscribe_event);
diff --git a/drivers/media/v4l2-core/v4l2-device.c b/drivers/media/v4l2-core/v4l2-device.c
index 937c6de85606..eac59ce41c04 100644
--- a/drivers/media/v4l2-core/v4l2-device.c
+++ b/drivers/media/v4l2-core/v4l2-device.c
@@ -37,6 +37,7 @@ int v4l2_device_register(struct device *dev, struct v4l2_device *v4l2_dev)
INIT_LIST_HEAD(&v4l2_dev->subdevs);
spin_lock_init(&v4l2_dev->lock);
+ mutex_init(&v4l2_dev->ioctl_lock);
v4l2_prio_init(&v4l2_dev->prio);
kref_init(&v4l2_dev->ref);
get_device(dev);
diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c
index 681eef972e63..b44dca8f5966 100644
--- a/drivers/media/v4l2-core/v4l2-ioctl.c
+++ b/drivers/media/v4l2-core/v4l2-ioctl.c
@@ -29,6 +29,8 @@
#include <media/v4l2-device.h>
#include <media/videobuf2-v4l2.h>
#include <media/v4l2-mc.h>
+#include <media/v4l2-chip-ident.h>
+#include <media/videobuf2-core.h>
#include <trace/events/v4l2.h>
@@ -639,6 +641,20 @@ static void v4l_print_decoder_cmd(const void *arg, bool write_only)
pr_info("pts=%llu\n", p->stop.pts);
}
+static void v4l_print_dbg_chip_ident(const void *arg, bool write_only)
+{
+ const struct v4l2_dbg_chip_ident *p = arg;
+
+ pr_cont("type=%u, ", p->match.type);
+ if (p->match.type == V4L2_CHIP_MATCH_I2C_DRIVER)
+ pr_cont("name=%.*s, ",
+ (int)sizeof(p->match.name), p->match.name);
+ else
+ pr_cont("addr=%u, ", p->match.addr);
+ pr_cont("chip_ident=%u, revision=0x%x\n",
+ p->ident, p->revision);
+}
+
static void v4l_print_dbg_chip_info(const void *arg, bool write_only)
{
const struct v4l2_dbg_chip_info *p = arg;
@@ -1138,6 +1154,7 @@ static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt)
case V4L2_PIX_FMT_RGB32: descr = "32-bit A/XRGB 8-8-8-8"; break;
case V4L2_PIX_FMT_ARGB32: descr = "32-bit ARGB 8-8-8-8"; break;
case V4L2_PIX_FMT_XRGB32: descr = "32-bit XRGB 8-8-8-8"; break;
+ case V4L2_PIX_FMT_RGBA: descr = "32-bit RGBA 8-8-8-8"; break;
case V4L2_PIX_FMT_GREY: descr = "8-bit Greyscale"; break;
case V4L2_PIX_FMT_Y4: descr = "4-bit Greyscale"; break;
case V4L2_PIX_FMT_Y6: descr = "6-bit Greyscale"; break;
@@ -1287,9 +1304,12 @@ static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt)
case V4L2_PIX_FMT_S5C_UYVY_JPG: descr = "S5C73MX interleaved UYVY/JPEG"; break;
case V4L2_PIX_FMT_MT21C: descr = "Mediatek Compressed Format"; break;
default:
- WARN(1, "Unknown pixelformat 0x%08x\n", fmt->pixelformat);
- if (fmt->description[0])
+ if (!fmt->description[0])
+ WARN(1, "Unknown pixelformat 0x%08x\n", fmt->pixelformat);
+ else {
+ pr_debug("Custom device pixelformat 0x%08x '%s'\n", fmt->pixelformat, fmt->description);
return;
+ }
flags = 0;
snprintf(fmt->description, sz, "%c%c%c%c%s",
(char)(fmt->pixelformat & 0x7f),
@@ -2354,6 +2374,18 @@ static int v4l_dbg_s_register(const struct v4l2_ioctl_ops *ops,
#endif
}
+static int v4l_dbg_g_chip_ident(const struct v4l2_ioctl_ops *ops,
+ struct file *file, void *fh, void *arg)
+{
+ struct v4l2_dbg_chip_ident *p = arg;
+
+ p->ident = V4L2_IDENT_NONE;
+ p->revision = 0;
+ if (p->match.type == V4L2_CHIP_MATCH_SUBDEV)
+ return -EINVAL;
+ return ops->vidioc_g_chip_ident(file, fh, p);
+}
+
static int v4l_dbg_g_chip_info(const struct v4l2_ioctl_ops *ops,
struct file *file, void *fh, void *arg)
{
@@ -2610,6 +2642,7 @@ static struct v4l2_ioctl_info v4l2_ioctls[] = {
IOCTL_INFO_STD(VIDIOC_TRY_DECODER_CMD, vidioc_try_decoder_cmd, v4l_print_decoder_cmd, 0),
IOCTL_INFO_FNC(VIDIOC_DBG_S_REGISTER, v4l_dbg_s_register, v4l_print_dbg_register, 0),
IOCTL_INFO_FNC(VIDIOC_DBG_G_REGISTER, v4l_dbg_g_register, v4l_print_dbg_register, 0),
+ IOCTL_INFO_FNC(VIDIOC_DBG_G_CHIP_IDENT, v4l_dbg_g_chip_ident, v4l_print_dbg_chip_ident, 0),
IOCTL_INFO_FNC(VIDIOC_S_HW_FREQ_SEEK, v4l_s_hw_freq_seek, v4l_print_hw_freq_seek, INFO_FL_PRIO),
IOCTL_INFO_STD(VIDIOC_S_DV_TIMINGS, vidioc_s_dv_timings, v4l_print_dv_timings, INFO_FL_PRIO | INFO_FL_CLEAR(v4l2_dv_timings, bt.flags)),
IOCTL_INFO_STD(VIDIOC_G_DV_TIMINGS, vidioc_g_dv_timings, v4l_print_dv_timings, 0),
diff --git a/drivers/media/v4l2-core/videobuf-core.c b/drivers/media/v4l2-core/videobuf-core.c
index 1dbf6f7785bb..89294e62e761 100644
--- a/drivers/media/v4l2-core/videobuf-core.c
+++ b/drivers/media/v4l2-core/videobuf-core.c
@@ -593,6 +593,13 @@ int videobuf_qbuf(struct videobuf_queue *q, struct v4l2_buffer *b)
buf->baddr != b->m.userptr)
q->ops->buf_release(q, buf);
buf->baddr = b->m.userptr;
+ if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT
+ || q->type == V4L2_BUF_TYPE_VBI_OUTPUT
+ || q->type == V4L2_BUF_TYPE_SLICED_VBI_OUTPUT
+ || q->type == V4L2_BUF_TYPE_SDR_OUTPUT) {
+ buf->field = b->field;
+ buf->ts = b->timestamp;
+ }
break;
case V4L2_MEMORY_OVERLAY:
buf->boff = b->m.offset;
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index fc5e4fef89d2..997a6172735e 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -394,6 +394,27 @@ config MFD_MX25_TSADC
i.MX25 processors. They consist of a conversion queue for general
purpose ADC and a queue for Touchscreens.
+config MFD_MXC_HDMI
+ tristate "Freescale HDMI Core"
+ select MFD_CORE
+ help
+ This is the core driver for the Freescale i.MX6 on-chip HDMI.
+ This MFD driver connects with the video and audio drivers for HDMI.
+
+config MFD_PF1550
+ tristate "Freescale Semiconductor PF1550 PMIC Support"
+ depends on I2C=y
+ select MFD_CORE
+ select REGMAP_I2C
+ select REGMAP_IRQ
+ help
+ Say yes here to add support for Freescale Semiconductor PF1550.
+ This is a companion Power Management IC with regulators, ONKEY,
+ and charger control on chip.
+ This driver provides common support for accessing the device;
+ additional drivers must be enabled in order to use the functionality
+ of the device.
+
config MFD_HI6421_PMIC
tristate "HiSilicon Hi6421 PMU/Codec IC"
depends on OF
@@ -656,6 +677,14 @@ config MFD_MAX14577
additional drivers must be enabled in order to use the functionality
of the device.
+config MFD_MAX17135
+ tristate "Maxim MAX17135 EPD PMIC core"
+ depends on I2C
+
+ help
+ This is the MAX17135 PMIC support. It includes
+ core support for communication with the MAX17135 chip.
+
config MFD_MAX77620
bool "Maxim Semiconductor MAX77620 and MAX20024 PMIC Support"
depends on I2C=y
@@ -1781,6 +1810,14 @@ config MFD_STM32_TIMERS
for PWM and IIO Timer. This driver allow to share the
registers between the others drivers.
+config MFD_BD71837
+ bool "BD71837 Power Management chip"
+ depends on I2C=y
+ select MFD_CORE
+ help
+ if you say yes here you get support for the BD71837
+ Power Management chips.
+
menu "Multimedia Capabilities Port drivers"
depends on ARCH_SA1100
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index 8703ff17998e..c6755df735ba 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -100,6 +100,8 @@ obj-$(CONFIG_MFD_MC13XXX) += mc13xxx-core.o
obj-$(CONFIG_MFD_MC13XXX_SPI) += mc13xxx-spi.o
obj-$(CONFIG_MFD_MC13XXX_I2C) += mc13xxx-i2c.o
+obj-$(CONFIG_MFD_PF1550) += pf1550.o
+
obj-$(CONFIG_MFD_CORE) += mfd-core.o
obj-$(CONFIG_EZX_PCAP) += ezx-pcap.o
@@ -141,6 +143,7 @@ obj-$(CONFIG_MFD_DA9063) += da9063.o
obj-$(CONFIG_MFD_DA9150) += da9150-core.o
obj-$(CONFIG_MFD_MAX14577) += max14577.o
+obj-$(CONFIG_MFD_MAX17135) += max17135-core.o
obj-$(CONFIG_MFD_MAX77620) += max77620.o
obj-$(CONFIG_MFD_MAX77686) += max77686.o
obj-$(CONFIG_MFD_MAX77693) += max77693.o
@@ -214,6 +217,7 @@ obj-$(CONFIG_MFD_HI655X_PMIC) += hi655x-pmic.o
obj-$(CONFIG_MFD_DLN2) += dln2.o
obj-$(CONFIG_MFD_RT5033) += rt5033.o
obj-$(CONFIG_MFD_SKY81452) += sky81452.o
+obj-$(CONFIG_MFD_MXC_HDMI) += mxc-hdmi-core.o
intel-soc-pmic-objs := intel_soc_pmic_core.o intel_soc_pmic_crc.o
obj-$(CONFIG_INTEL_SOC_PMIC) += intel-soc-pmic.o
@@ -227,3 +231,4 @@ obj-$(CONFIG_MFD_SUN4I_GPADC) += sun4i-gpadc.o
obj-$(CONFIG_MFD_STM32_LPTIMER) += stm32-lptimer.o
obj-$(CONFIG_MFD_STM32_TIMERS) += stm32-timers.o
obj-$(CONFIG_MFD_MXS_LRADC) += mxs-lradc.o
+obj-$(CONFIG_MFD_BD71837) += bd71837.o
diff --git a/drivers/mfd/bd71837.c b/drivers/mfd/bd71837.c
new file mode 100644
index 000000000000..f21ec4aa4aa3
--- /dev/null
+++ b/drivers/mfd/bd71837.c
@@ -0,0 +1,310 @@
+/*
+ * @file bd71837.c -- ROHM BD71837MWV mfd driver
+ *
+ * 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.
+ *
+ * @author: cpham2403@gmail.com
+ * Copyright 2017.
+ */
+#define DEBUG
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/irqdomain.h>
+#include <linux/gpio.h>
+#include <linux/regmap.h>
+#include <linux/of_device.h>
+#include <linux/of_gpio.h>
+#include <linux/mfd/core.h>
+#include <linux/mfd/bd71837.h>
+
+/* Default enable debug message All Level */
+unsigned int bd71837_debug_mask = BD71837_DBG0;
+
+/** @brief bd71837 irq resource */
+static struct resource pmic_resources[] = {
+ // irq# 0
+ {
+ .start = BD71837_IRQ,
+ .end = BD71837_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+/** @brief bd71837 multi function cells */
+static struct mfd_cell bd71837_mfd_cells[] = {
+ {
+ .name = "bd71837-pmic",
+ .num_resources = ARRAY_SIZE(pmic_resources),
+ .resources = &pmic_resources[0],
+ },
+};
+
+/** @brief bd71837 irqs */
+static const struct regmap_irq bd71837_irqs[] = {
+ [BD71837_IRQ] = {
+ .mask = BD71837_INT_MASK,
+ .reg_offset = 0,
+ },
+};
+
+/** @brief bd71837 irq chip definition */
+static struct regmap_irq_chip bd71837_irq_chip = {
+ .name = "bd71837",
+ .irqs = bd71837_irqs,
+ .num_irqs = ARRAY_SIZE(bd71837_irqs),
+ .num_regs = 1,
+ .irq_reg_stride = 1,
+ .status_base = BD71837_REG_IRQ,
+ .mask_base = BD71837_REG_MIRQ,
+ .mask_invert = true,
+ // .ack_base = BD71837_REG_IRQ,
+};
+
+/** @brief bd71837 irq initialize
+ * @param bd71837 bd71837 device to init
+ * @param bdinfo platform init data
+ * @retval 0 probe success
+ * @retval negative error number
+ */
+static int bd71837_irq_init(struct bd71837 *bd71837, struct bd71837_board *bdinfo)
+{
+ int irq;
+ int ret = 0;
+
+ if (!bdinfo) {
+ dev_warn(bd71837->dev, "No interrupt support, no pdata\n");
+ return -EINVAL;
+ }
+
+ dev_info(bd71837->dev, "gpio_intr = %d \n", bdinfo->gpio_intr);
+ irq = gpio_to_irq(bdinfo->gpio_intr);
+
+ bd71837->chip_irq = irq;
+ dev_info(bd71837->dev, "chip_irq=%d \n", bd71837->chip_irq);
+ ret = regmap_add_irq_chip(bd71837->regmap, bd71837->chip_irq,
+ IRQF_ONESHOT | IRQF_TRIGGER_FALLING, bdinfo->irq_base,
+ &bd71837_irq_chip, &bd71837->irq_data);
+ if (ret < 0) {
+ dev_warn(bd71837->dev, "Failed to add irq_chip %d\n", ret);
+ }
+ return ret;
+}
+
+/** @brief bd71837 irq initialize
+ * @param bd71837 bd71837 device to init
+ * @retval 0 probe success
+ * @retval negative error number
+ */
+static int bd71837_irq_exit(struct bd71837 *bd71837)
+{
+ if (bd71837->chip_irq > 0)
+ regmap_del_irq_chip(bd71837->chip_irq, bd71837->irq_data);
+ return 0;
+}
+
+/** @brief check whether volatile register
+ * @param dev kernel device pointer
+ * @param reg register index
+ */
+static bool is_volatile_reg(struct device *dev, unsigned int reg)
+{
+ // struct bd71837 *bd71837 = dev_get_drvdata(dev);
+
+ /*
+ * Caching all regulator registers.
+ */
+ return true;
+}
+
+/** @brief regmap configures */
+static const struct regmap_config bd71837_regmap_config = {
+ .reg_bits = 8,
+ .val_bits = 8,
+ .volatile_reg = is_volatile_reg,
+ .max_register = BD71837_MAX_REGISTER - 1,
+ .cache_type = REGCACHE_RBTREE,
+};
+
+#ifdef CONFIG_OF
+static struct of_device_id bd71837_of_match[] = {
+ { .compatible = "rohm,bd71837", .data = (void *)0},
+ { .compatible = "rohm,bd71840", .data = (void *)0},
+ { },
+};
+MODULE_DEVICE_TABLE(of, bd71837_of_match);
+
+
+/** @brief parse device tree data of bd71837
+ * @param client client object provided by system
+ * @param chip_id return chip id back to caller
+ * @return board initialize data
+ */
+static struct bd71837_board *bd71837_parse_dt(struct i2c_client *client,
+ int *chip_id)
+{
+ struct device_node *np = client->dev.of_node;
+ struct bd71837_board *board_info;
+ unsigned int prop;
+ const struct of_device_id *match;
+ int r = 0;
+
+ match = of_match_device(bd71837_of_match, &client->dev);
+ if (!match) {
+ dev_err(&client->dev, "Failed to find matching dt id\n");
+ return NULL;
+ }
+
+ chip_id = (int *)match->data;
+
+ board_info = devm_kzalloc(&client->dev, sizeof(*board_info),
+ GFP_KERNEL);
+ if (!board_info) {
+ dev_err(&client->dev, "Failed to allocate pdata\n");
+ return NULL;
+ }
+
+ board_info->gpio_intr = of_get_named_gpio(np, "gpio_intr", 0);
+ if (!gpio_is_valid(board_info->gpio_intr)) {
+ dev_err(&client->dev, "no pmic intr pin available\n");
+ goto err_intr;
+ }
+
+ r = of_property_read_u32(np, "irq_base", &prop);
+ if (!r) {
+ board_info->irq_base = prop;
+ } else {
+ board_info->irq_base = -1;
+ }
+
+ return board_info;
+
+err_intr:
+ devm_kfree(&client->dev, board_info);
+ return NULL;
+}
+#endif
+
+/** @brief probe bd71837 device
+ * @param i2c client object provided by system
+ * @param id chip id
+ * @retval 0 probe success
+ * @retval negative error number
+ */
+static int bd71837_i2c_probe(struct i2c_client *i2c,
+ const struct i2c_device_id *id)
+{
+ struct bd71837 *bd71837;
+ struct bd71837_board *pmic_plat_data;
+ struct bd71837_board *of_pmic_plat_data = NULL;
+ int chip_id = id->driver_data;
+ int ret = 0;
+
+ pmic_plat_data = dev_get_platdata(&i2c->dev);
+
+ if (!pmic_plat_data && i2c->dev.of_node) {
+ pmic_plat_data = bd71837_parse_dt(i2c, &chip_id);
+ of_pmic_plat_data = pmic_plat_data;
+ }
+
+ if (!pmic_plat_data)
+ return -EINVAL;
+
+ bd71837 = kzalloc(sizeof(struct bd71837), GFP_KERNEL);
+ if (bd71837 == NULL)
+ return -ENOMEM;
+
+ bd71837->of_plat_data = of_pmic_plat_data;
+ i2c_set_clientdata(i2c, bd71837);
+ bd71837->dev = &i2c->dev;
+ bd71837->i2c_client = i2c;
+ bd71837->id = chip_id;
+ mutex_init(&bd71837->io_mutex);
+
+ bd71837->regmap = devm_regmap_init_i2c(i2c, &bd71837_regmap_config);
+ if (IS_ERR(bd71837->regmap)) {
+ ret = PTR_ERR(bd71837->regmap);
+ dev_err(&i2c->dev, "regmap initialization failed: %d\n", ret);
+ return ret;
+ }
+
+ ret = bd71837_reg_read(bd71837, BD71837_REG_REV);
+ if (ret < 0) {
+ dev_err(bd71837->dev, "%s(): Read BD71837_REG_DEVICE failed!\n", __func__);
+ goto err;
+ }
+ dev_info(bd71837->dev, "Device ID=0x%X\n", ret);
+
+ bd71837_irq_init(bd71837, of_pmic_plat_data);
+
+ ret = mfd_add_devices(bd71837->dev, -1,
+ bd71837_mfd_cells, ARRAY_SIZE(bd71837_mfd_cells),
+ NULL, 0,
+ regmap_irq_get_domain(bd71837->irq_data));
+ if (ret < 0)
+ goto err;
+
+ return ret;
+
+err:
+ mfd_remove_devices(bd71837->dev);
+ kfree(bd71837);
+ return ret;
+}
+
+/** @brief remove bd71837 device
+ * @param i2c client object provided by system
+ * @return 0
+ */
+static int bd71837_i2c_remove(struct i2c_client *i2c)
+{
+ struct bd71837 *bd71837 = i2c_get_clientdata(i2c);
+
+ bd71837_irq_exit(bd71837);
+ mfd_remove_devices(bd71837->dev);
+ kfree(bd71837);
+
+ return 0;
+}
+
+static const struct i2c_device_id bd71837_i2c_id[] = {
+ { "bd71837", 0 },
+ { "bd71840", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, bd71837_i2c_id);
+
+static struct i2c_driver bd71837_i2c_driver = {
+ .driver = {
+ .name = "bd71837",
+ .owner = THIS_MODULE,
+ .of_match_table = of_match_ptr(bd71837_of_match),
+ },
+ .probe = bd71837_i2c_probe,
+ .remove = bd71837_i2c_remove,
+ .id_table = bd71837_i2c_id,
+};
+
+static int __init bd71837_i2c_init(void)
+{
+ return i2c_add_driver(&bd71837_i2c_driver);
+}
+/* init early so consumer devices can complete system boot */
+subsys_initcall(bd71837_i2c_init);
+
+static void __exit bd71837_i2c_exit(void)
+{
+ i2c_del_driver(&bd71837_i2c_driver);
+}
+module_exit(bd71837_i2c_exit);
+
+MODULE_AUTHOR("Cong Pham <cpham2403@gmail.com>");
+MODULE_DESCRIPTION("BD71837 chip multi-function driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/mfd/max17135-core.c b/drivers/mfd/max17135-core.c
new file mode 100644
index 000000000000..f663f8068067
--- /dev/null
+++ b/drivers/mfd/max17135-core.c
@@ -0,0 +1,281 @@
+/*
+ * Copyright (C) 2010-2015 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.
+ *
+ * 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
+ *
+ */
+
+/*!
+ * @file pmic/core/max17135.c
+ * @brief This file contains MAX17135 specific PMIC code. This implementaion
+ * may differ for each PMIC chip.
+ *
+ * @ingroup PMIC_CORE
+ */
+
+/*
+ * Includes
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/device.h>
+#include <linux/i2c.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/uaccess.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/of_gpio.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/machine.h>
+#include <linux/pmic_status.h>
+#include <linux/mfd/core.h>
+#include <linux/mfd/max17135.h>
+#include <asm/mach-types.h>
+
+static int max17135_detect(struct i2c_client *client,
+ struct i2c_board_info *info);
+struct i2c_client *max17135_client;
+static struct regulator *gpio_regulator;
+
+static struct mfd_cell max17135_devs[] = {
+ { .name = "max17135-pmic", },
+ { .name = "max17135-sns", },
+};
+
+static const unsigned short normal_i2c[] = {0x48, I2C_CLIENT_END};
+
+int max17135_reg_read(int reg_num, unsigned int *reg_val)
+{
+ int result;
+
+ if (max17135_client == NULL)
+ return PMIC_ERROR;
+
+ if ((reg_num == REG_MAX17135_EXT_TEMP) ||
+ (reg_num == REG_MAX17135_INT_TEMP)) {
+ result = i2c_smbus_read_word_data(max17135_client, reg_num);
+ if (result < 0) {
+ dev_err(&max17135_client->dev,
+ "Unable to read MAX17135 register via I2C\n");
+ return PMIC_ERROR;
+ }
+ /* Swap bytes for dword read */
+ result = (result >> 8) | ((result & 0xFF) << 8);
+ } else {
+ result = i2c_smbus_read_byte_data(max17135_client, reg_num);
+ if (result < 0) {
+ dev_err(&max17135_client->dev,
+ "Unable to read MAX17135 register via I2C\n");
+ return PMIC_ERROR;
+ }
+ }
+
+ *reg_val = result;
+ return PMIC_SUCCESS;
+}
+
+int max17135_reg_write(int reg_num, const unsigned int reg_val)
+{
+ int result;
+
+ if (max17135_client == NULL)
+ return PMIC_ERROR;
+
+ result = i2c_smbus_write_byte_data(max17135_client, reg_num, reg_val);
+ if (result < 0) {
+ dev_err(&max17135_client->dev,
+ "Unable to write MAX17135 register via I2C\n");
+ return PMIC_ERROR;
+ }
+
+ return PMIC_SUCCESS;
+}
+
+#ifdef CONFIG_OF
+static struct max17135_platform_data *max17135_i2c_parse_dt_pdata(
+ struct device *dev)
+{
+ struct max17135_platform_data *pdata;
+
+ pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
+ if (!pdata) {
+ dev_err(dev, "could not allocate memory for pdata\n");
+ return ERR_PTR(-ENOMEM);
+ }
+
+ return pdata;
+}
+#else
+static struct max17135_platform_data *max17135_i2c_parse_dt_pdata(
+ struct device *dev)
+{
+ return NULL;
+}
+#endif /* !CONFIG_OF */
+
+static int max17135_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct max17135 *max17135;
+ struct max17135_platform_data *pdata = client->dev.platform_data;
+ struct device_node *np = client->dev.of_node;
+ int ret = 0;
+
+ if (!np)
+ return -ENODEV;
+
+ gpio_regulator = devm_regulator_get(&client->dev, "SENSOR");
+ if (!IS_ERR(gpio_regulator)) {
+ ret = regulator_enable(gpio_regulator);
+ if (ret) {
+ dev_err(&client->dev, "gpio set voltage error\n");
+ return ret;
+ }
+ }
+
+ /* Create the PMIC data structure */
+ max17135 = kzalloc(sizeof(struct max17135), GFP_KERNEL);
+ if (max17135 == NULL)
+ return -ENOMEM;
+
+ /* Initialize the PMIC data structure */
+ i2c_set_clientdata(client, max17135);
+ max17135->dev = &client->dev;
+ max17135->i2c_client = client;
+
+ max17135_client = client;
+ ret = max17135_detect(client, NULL);
+ if (ret)
+ goto err1;
+
+ mfd_add_devices(max17135->dev, -1, max17135_devs,
+ ARRAY_SIZE(max17135_devs),
+ NULL, 0, NULL);
+
+ if (max17135->dev->of_node) {
+ pdata = max17135_i2c_parse_dt_pdata(max17135->dev);
+ if (IS_ERR(pdata)) {
+ ret = PTR_ERR(pdata);
+ goto err2;
+ }
+
+ }
+ max17135->pdata = pdata;
+
+ dev_info(&client->dev, "PMIC MAX17135 for eInk display\n");
+
+ return ret;
+err2:
+ mfd_remove_devices(max17135->dev);
+err1:
+ kfree(max17135);
+
+ return ret;
+}
+
+
+static int max17135_remove(struct i2c_client *i2c)
+{
+ struct max17135 *max17135 = i2c_get_clientdata(i2c);
+
+ mfd_remove_devices(max17135->dev);
+ return 0;
+}
+
+/* Return 0 if detection is successful, -ENODEV otherwise */
+static int max17135_detect(struct i2c_client *client,
+ struct i2c_board_info *info)
+{
+ struct i2c_adapter *adapter = client->adapter;
+ u8 chip_rev, chip_id;
+
+ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+ return -ENODEV;
+
+ /* detection */
+ if (i2c_smbus_read_byte_data(client,
+ REG_MAX17135_PRODUCT_REV) != 0) {
+ dev_err(&adapter->dev,
+ "Max17135 PMIC not found!\n");
+ return -ENODEV;
+ }
+
+ /* identification */
+ chip_rev = i2c_smbus_read_byte_data(client,
+ REG_MAX17135_PRODUCT_REV);
+ chip_id = i2c_smbus_read_byte_data(client,
+ REG_MAX17135_PRODUCT_ID);
+
+ if (chip_rev != 0x00 || chip_id != 0x4D) { /* identification failed */
+ dev_info(&adapter->dev,
+ "Unsupported chip (man_id=0x%02X, "
+ "chip_id=0x%02X).\n", chip_rev, chip_id);
+ return -ENODEV;
+ }
+
+ if (info)
+ strlcpy(info->type, "max17135_sensor", I2C_NAME_SIZE);
+
+ return 0;
+}
+
+static const struct i2c_device_id max17135_id[] = {
+ { "max17135", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, max17135_id);
+
+static const struct of_device_id max17135_dt_ids[] = {
+ {
+ .compatible = "maxim,max17135",
+ .data = (void *) &max17135_id[0],
+ }, {
+ /* sentinel */
+ }
+};
+MODULE_DEVICE_TABLE(of, max17135_dt_ids);
+
+
+static struct i2c_driver max17135_driver = {
+ .driver = {
+ .name = "max17135",
+ .owner = THIS_MODULE,
+ .of_match_table = max17135_dt_ids,
+ },
+ .probe = max17135_probe,
+ .remove = max17135_remove,
+ .id_table = max17135_id,
+ .detect = max17135_detect,
+ .address_list = &normal_i2c[0],
+};
+
+static int __init max17135_init(void)
+{
+ return i2c_add_driver(&max17135_driver);
+}
+
+static void __exit max17135_exit(void)
+{
+ i2c_del_driver(&max17135_driver);
+}
+
+/*
+ * Module entry points
+ */
+subsys_initcall(max17135_init);
+module_exit(max17135_exit);
diff --git a/drivers/mfd/mxc-hdmi-core.c b/drivers/mfd/mxc-hdmi-core.c
new file mode 100644
index 000000000000..6435b3d7fd60
--- /dev/null
+++ b/drivers/mfd/mxc-hdmi-core.c
@@ -0,0 +1,821 @@
+/*
+ * Copyright (C) 2011-2016 Freescale Semiconductor, Inc.
+
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/clk.h>
+#include <linux/spinlock.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+
+#include <linux/platform_device.h>
+#include <linux/regulator/machine.h>
+#include <asm/mach-types.h>
+
+#include <video/mxc_hdmi.h>
+#include <linux/ipu-v3.h>
+#include <video/mxc_edid.h>
+#include "../mxc/ipu3/ipu_prv.h"
+#include <linux/mfd/mxc-hdmi-core.h>
+#include <linux/of_device.h>
+#include <linux/mod_devicetable.h>
+#include <linux/mfd/mxc-hdmi-core.h>
+
+struct mxc_hdmi_data {
+ struct platform_device *pdev;
+ unsigned long __iomem *reg_base;
+ unsigned long reg_phys_base;
+ struct device *dev;
+};
+
+static void __iomem *hdmi_base;
+static struct clk *isfr_clk;
+static struct clk *iahb_clk;
+static struct clk *mipi_core_clk;
+static spinlock_t irq_spinlock;
+static spinlock_t edid_spinlock;
+static unsigned int sample_rate;
+static unsigned long pixel_clk_rate;
+static struct clk *pixel_clk;
+static int hdmi_ratio;
+int mxc_hdmi_ipu_id;
+int mxc_hdmi_disp_id;
+static struct mxc_edid_cfg hdmi_core_edid_cfg;
+static int hdmi_core_init;
+static unsigned int hdmi_dma_running;
+static struct snd_pcm_substream *hdmi_audio_stream_playback;
+static unsigned int hdmi_cable_state;
+static unsigned int hdmi_blank_state;
+static unsigned int hdmi_abort_state;
+static spinlock_t hdmi_audio_lock, hdmi_blank_state_lock, hdmi_cable_state_lock;
+
+unsigned int hdmi_set_cable_state(unsigned int state)
+{
+ unsigned long flags;
+ struct snd_pcm_substream *substream = hdmi_audio_stream_playback;
+
+ spin_lock_irqsave(&hdmi_cable_state_lock, flags);
+ hdmi_cable_state = state;
+ spin_unlock_irqrestore(&hdmi_cable_state_lock, flags);
+
+#ifndef CONFIG_MFD_MXC_HDMI_ANDROID
+ if (check_hdmi_state() && substream && hdmi_abort_state) {
+ hdmi_abort_state = 0;
+ substream->ops->trigger(substream, SNDRV_PCM_TRIGGER_START);
+ }
+#endif
+ return 0;
+}
+EXPORT_SYMBOL(hdmi_set_cable_state);
+
+unsigned int hdmi_set_blank_state(unsigned int state)
+{
+ unsigned long flags;
+ struct snd_pcm_substream *substream = hdmi_audio_stream_playback;
+
+ spin_lock_irqsave(&hdmi_blank_state_lock, flags);
+ hdmi_blank_state = state;
+ spin_unlock_irqrestore(&hdmi_blank_state_lock, flags);
+
+#ifndef CONFIG_MFD_MXC_HDMI_ANDROID
+ if (check_hdmi_state() && substream && hdmi_abort_state) {
+ hdmi_abort_state = 0;
+ substream->ops->trigger(substream, SNDRV_PCM_TRIGGER_START);
+ }
+#endif
+
+ return 0;
+}
+EXPORT_SYMBOL(hdmi_set_blank_state);
+
+#ifdef CONFIG_SND_SOC_IMX_HDMI_DMA
+static void hdmi_audio_abort_stream(struct snd_pcm_substream *substream)
+{
+ unsigned long flags;
+
+ snd_pcm_stream_lock_irqsave(substream, flags);
+
+#ifndef CONFIG_MFD_MXC_HDMI_ANDROID
+ if (snd_pcm_running(substream)) {
+ hdmi_abort_state = 1;
+ substream->ops->trigger(substream, SNDRV_PCM_TRIGGER_STOP);
+ }
+#else
+ if (snd_pcm_running(substream))
+ snd_pcm_stop(substream, SNDRV_PCM_STATE_DISCONNECTED);
+#endif
+
+ snd_pcm_stream_unlock_irqrestore(substream, flags);
+}
+
+int mxc_hdmi_abort_stream(void)
+{
+ unsigned long flags;
+ spin_lock_irqsave(&hdmi_audio_lock, flags);
+ if (hdmi_audio_stream_playback)
+ hdmi_audio_abort_stream(hdmi_audio_stream_playback);
+ spin_unlock_irqrestore(&hdmi_audio_lock, flags);
+
+ return 0;
+}
+EXPORT_SYMBOL(mxc_hdmi_abort_stream);
+#else
+int mxc_hdmi_abort_stream(void)
+{
+ return 0;
+}
+EXPORT_SYMBOL(mxc_hdmi_abort_stream);
+#endif
+
+int check_hdmi_state(void)
+{
+ unsigned long flags1, flags2;
+ unsigned int ret;
+
+ spin_lock_irqsave(&hdmi_cable_state_lock, flags1);
+ spin_lock_irqsave(&hdmi_blank_state_lock, flags2);
+
+ ret = hdmi_cable_state && hdmi_blank_state;
+
+ spin_unlock_irqrestore(&hdmi_blank_state_lock, flags2);
+ spin_unlock_irqrestore(&hdmi_cable_state_lock, flags1);
+
+ return ret;
+}
+EXPORT_SYMBOL(check_hdmi_state);
+
+#ifdef CONFIG_SND_SOC_IMX_HDMI_DMA
+int mxc_hdmi_register_audio(struct snd_pcm_substream *substream)
+{
+ unsigned long flags, flags1;
+ int ret = 0;
+
+ if (!substream)
+ return -EINVAL;
+
+ snd_pcm_stream_lock_irqsave(substream, flags);
+
+ if (check_hdmi_state()) {
+ spin_lock_irqsave(&hdmi_audio_lock, flags1);
+ if (hdmi_audio_stream_playback) {
+ pr_err("%s unconsist hdmi auido stream!\n", __func__);
+ ret = -EINVAL;
+ }
+ hdmi_audio_stream_playback = substream;
+ hdmi_abort_state = 0;
+ spin_unlock_irqrestore(&hdmi_audio_lock, flags1);
+ } else
+ ret = -EINVAL;
+
+ snd_pcm_stream_unlock_irqrestore(substream, flags);
+
+ return ret;
+}
+EXPORT_SYMBOL(mxc_hdmi_register_audio);
+#endif
+
+void mxc_hdmi_unregister_audio(struct snd_pcm_substream *substream)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&hdmi_audio_lock, flags);
+ hdmi_audio_stream_playback = NULL;
+ hdmi_abort_state = 0;
+ spin_unlock_irqrestore(&hdmi_audio_lock, flags);
+}
+EXPORT_SYMBOL(mxc_hdmi_unregister_audio);
+
+u8 hdmi_readb(unsigned int reg)
+{
+ u8 value;
+
+ value = __raw_readb(hdmi_base + reg);
+
+ return value;
+}
+EXPORT_SYMBOL(hdmi_readb);
+
+#ifdef DEBUG
+static bool overflow_lo;
+static bool overflow_hi;
+
+bool hdmi_check_overflow(void)
+{
+ u8 val, lo, hi;
+
+ val = hdmi_readb(HDMI_IH_FC_STAT2);
+ lo = (val & HDMI_IH_FC_STAT2_LOW_PRIORITY_OVERFLOW) != 0;
+ hi = (val & HDMI_IH_FC_STAT2_HIGH_PRIORITY_OVERFLOW) != 0;
+
+ if ((lo != overflow_lo) || (hi != overflow_hi)) {
+ pr_debug("%s LowPriority=%d HighPriority=%d <=======================\n",
+ __func__, lo, hi);
+ overflow_lo = lo;
+ overflow_hi = hi;
+ return true;
+ }
+ return false;
+}
+#else
+bool hdmi_check_overflow(void)
+{
+ return false;
+}
+#endif
+EXPORT_SYMBOL(hdmi_check_overflow);
+
+void hdmi_writeb(u8 value, unsigned int reg)
+{
+ hdmi_check_overflow();
+ __raw_writeb(value, hdmi_base + reg);
+ hdmi_check_overflow();
+}
+EXPORT_SYMBOL(hdmi_writeb);
+
+void hdmi_mask_writeb(u8 data, unsigned int reg, u8 shift, u8 mask)
+{
+ u8 value = hdmi_readb(reg) & ~mask;
+ value |= (data << shift) & mask;
+ hdmi_writeb(value, reg);
+}
+EXPORT_SYMBOL(hdmi_mask_writeb);
+
+unsigned int hdmi_read4(unsigned int reg)
+{
+ /* read a four byte address from registers */
+ return (hdmi_readb(reg + 3) << 24) |
+ (hdmi_readb(reg + 2) << 16) |
+ (hdmi_readb(reg + 1) << 8) |
+ hdmi_readb(reg);
+}
+EXPORT_SYMBOL(hdmi_read4);
+
+void hdmi_write4(unsigned int value, unsigned int reg)
+{
+ /* write a four byte address to hdmi regs */
+ hdmi_writeb(value & 0xff, reg);
+ hdmi_writeb((value >> 8) & 0xff, reg + 1);
+ hdmi_writeb((value >> 16) & 0xff, reg + 2);
+ hdmi_writeb((value >> 24) & 0xff, reg + 3);
+}
+EXPORT_SYMBOL(hdmi_write4);
+
+static void initialize_hdmi_ih_mutes(void)
+{
+ u8 ih_mute;
+
+ /*
+ * Boot up defaults are:
+ * HDMI_IH_MUTE = 0x03 (disabled)
+ * HDMI_IH_MUTE_* = 0x00 (enabled)
+ */
+
+ /* Disable top level interrupt bits in HDMI block */
+ ih_mute = hdmi_readb(HDMI_IH_MUTE) |
+ HDMI_IH_MUTE_MUTE_WAKEUP_INTERRUPT |
+ HDMI_IH_MUTE_MUTE_ALL_INTERRUPT;
+
+ hdmi_writeb(ih_mute, HDMI_IH_MUTE);
+
+ /* by default mask all interrupts */
+ hdmi_writeb(0xff, HDMI_VP_MASK);
+ hdmi_writeb(0xff, HDMI_FC_MASK0);
+ hdmi_writeb(0xff, HDMI_FC_MASK1);
+ hdmi_writeb(0xff, HDMI_FC_MASK2);
+ hdmi_writeb(0xff, HDMI_PHY_MASK0);
+ hdmi_writeb(0xff, HDMI_PHY_I2CM_INT_ADDR);
+ hdmi_writeb(0xff, HDMI_PHY_I2CM_CTLINT_ADDR);
+ hdmi_writeb(0xff, HDMI_AUD_INT);
+ hdmi_writeb(0xff, HDMI_AUD_SPDIFINT);
+ hdmi_writeb(0xff, HDMI_AUD_HBR_MASK);
+ hdmi_writeb(0xff, HDMI_GP_MASK);
+ hdmi_writeb(0xff, HDMI_A_APIINTMSK);
+ hdmi_writeb(0xff, HDMI_CEC_MASK);
+ hdmi_writeb(0xff, HDMI_I2CM_INT);
+ hdmi_writeb(0xff, HDMI_I2CM_CTLINT);
+
+ /* Disable interrupts in the IH_MUTE_* registers */
+ hdmi_writeb(0xff, HDMI_IH_MUTE_FC_STAT0);
+ hdmi_writeb(0xff, HDMI_IH_MUTE_FC_STAT1);
+ hdmi_writeb(0xff, HDMI_IH_MUTE_FC_STAT2);
+ hdmi_writeb(0xff, HDMI_IH_MUTE_AS_STAT0);
+ hdmi_writeb(0xff, HDMI_IH_MUTE_PHY_STAT0);
+ hdmi_writeb(0xff, HDMI_IH_MUTE_I2CM_STAT0);
+ hdmi_writeb(0xff, HDMI_IH_MUTE_CEC_STAT0);
+ hdmi_writeb(0xff, HDMI_IH_MUTE_VP_STAT0);
+ hdmi_writeb(0xff, HDMI_IH_MUTE_I2CMPHY_STAT0);
+ hdmi_writeb(0xff, HDMI_IH_MUTE_AHBDMAAUD_STAT0);
+
+ /* Enable top level interrupt bits in HDMI block */
+ ih_mute &= ~(HDMI_IH_MUTE_MUTE_WAKEUP_INTERRUPT |
+ HDMI_IH_MUTE_MUTE_ALL_INTERRUPT);
+ hdmi_writeb(ih_mute, HDMI_IH_MUTE);
+}
+
+static void hdmi_set_clock_regenerator_n(unsigned int value)
+{
+ u8 val;
+
+ if (!hdmi_dma_running) {
+ hdmi_writeb(value & 0xff, HDMI_AUD_N1);
+ hdmi_writeb(0, HDMI_AUD_N2);
+ hdmi_writeb(0, HDMI_AUD_N3);
+ }
+
+ hdmi_writeb(value & 0xff, HDMI_AUD_N1);
+ hdmi_writeb((value >> 8) & 0xff, HDMI_AUD_N2);
+ hdmi_writeb((value >> 16) & 0x0f, HDMI_AUD_N3);
+
+ /* nshift factor = 0 */
+ val = hdmi_readb(HDMI_AUD_CTS3);
+ val &= ~HDMI_AUD_CTS3_N_SHIFT_MASK;
+ hdmi_writeb(val, HDMI_AUD_CTS3);
+}
+
+static void hdmi_set_clock_regenerator_cts(unsigned int cts)
+{
+ u8 val;
+
+ if (!hdmi_dma_running) {
+ hdmi_writeb(cts & 0xff, HDMI_AUD_CTS1);
+ hdmi_writeb(0, HDMI_AUD_CTS2);
+ hdmi_writeb(0, HDMI_AUD_CTS3);
+ }
+
+ /* Must be set/cleared first */
+ val = hdmi_readb(HDMI_AUD_CTS3);
+ val &= ~HDMI_AUD_CTS3_CTS_MANUAL;
+ hdmi_writeb(val, HDMI_AUD_CTS3);
+
+ hdmi_writeb(cts & 0xff, HDMI_AUD_CTS1);
+ hdmi_writeb((cts >> 8) & 0xff, HDMI_AUD_CTS2);
+ hdmi_writeb(((cts >> 16) & HDMI_AUD_CTS3_AUDCTS19_16_MASK) |
+ HDMI_AUD_CTS3_CTS_MANUAL, HDMI_AUD_CTS3);
+}
+
+static unsigned int hdmi_compute_n(unsigned int freq, unsigned long pixel_clk,
+ unsigned int ratio)
+{
+ unsigned int n = (128 * freq) / 1000;
+
+ switch (freq) {
+ case 32000:
+ if (pixel_clk == 25174000)
+ n = (ratio == 150) ? 9152 : 4576;
+ else if (pixel_clk == 27020000)
+ n = (ratio == 150) ? 8192 : 4096;
+ else if (pixel_clk == 74170000 || pixel_clk == 148350000)
+ n = 11648;
+ else if (pixel_clk == 297000000)
+ n = (ratio == 150) ? 6144 : 3072;
+ else
+ n = 4096;
+ break;
+
+ case 44100:
+ if (pixel_clk == 25174000)
+ n = 7007;
+ else if (pixel_clk == 74170000)
+ n = 17836;
+ else if (pixel_clk == 148350000)
+ n = (ratio == 150) ? 17836 : 8918;
+ else if (pixel_clk == 297000000)
+ n = (ratio == 150) ? 9408 : 4704;
+ else
+ n = 6272;
+ break;
+
+ case 48000:
+ if (pixel_clk == 25174000)
+ n = (ratio == 150) ? 9152 : 6864;
+ else if (pixel_clk == 27020000)
+ n = (ratio == 150) ? 8192 : 6144;
+ else if (pixel_clk == 74170000)
+ n = 11648;
+ else if (pixel_clk == 148350000)
+ n = (ratio == 150) ? 11648 : 5824;
+ else if (pixel_clk == 297000000)
+ n = (ratio == 150) ? 10240 : 5120;
+ else
+ n = 6144;
+ break;
+
+ case 88200:
+ n = hdmi_compute_n(44100, pixel_clk, ratio) * 2;
+ break;
+
+ case 96000:
+ n = hdmi_compute_n(48000, pixel_clk, ratio) * 2;
+ break;
+
+ case 176400:
+ n = hdmi_compute_n(44100, pixel_clk, ratio) * 4;
+ break;
+
+ case 192000:
+ n = hdmi_compute_n(48000, pixel_clk, ratio) * 4;
+ break;
+
+ default:
+ break;
+ }
+
+ return n;
+}
+
+static unsigned int hdmi_compute_cts(unsigned int freq, unsigned long pixel_clk,
+ unsigned int ratio)
+{
+ unsigned int cts = 0;
+ switch (freq) {
+ case 32000:
+ if (pixel_clk == 297000000) {
+ cts = 222750;
+ break;
+ } else if (pixel_clk == 25174000) {
+ cts = 28125;
+ break;
+ }
+ case 48000:
+ case 96000:
+ case 192000:
+ switch (pixel_clk) {
+ case 25200000:
+ case 27000000:
+ case 54000000:
+ case 74250000:
+ case 148500000:
+ cts = pixel_clk / 1000;
+ break;
+ case 297000000:
+ cts = 247500;
+ break;
+ case 25174000:
+ cts = 28125l;
+ break;
+ /*
+ * All other TMDS clocks are not supported by
+ * DWC_hdmi_tx. The TMDS clocks divided or
+ * multiplied by 1,001 coefficients are not
+ * supported.
+ */
+ default:
+ break;
+ }
+ break;
+ case 44100:
+ case 88200:
+ case 176400:
+ switch (pixel_clk) {
+ case 25200000:
+ cts = 28000;
+ break;
+ case 25174000:
+ cts = 31250;
+ break;
+ case 27000000:
+ cts = 30000;
+ break;
+ case 54000000:
+ cts = 60000;
+ break;
+ case 74250000:
+ cts = 82500;
+ break;
+ case 148500000:
+ cts = 165000;
+ break;
+ case 297000000:
+ cts = 247500;
+ break;
+ default:
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+ if (ratio == 100)
+ return cts;
+ else
+ return (cts * ratio) / 100;
+}
+
+static void hdmi_set_clk_regenerator(void)
+{
+ unsigned int clk_n, clk_cts;
+
+ clk_n = hdmi_compute_n(sample_rate, pixel_clk_rate, hdmi_ratio);
+ clk_cts = hdmi_compute_cts(sample_rate, pixel_clk_rate, hdmi_ratio);
+
+ if (clk_cts == 0) {
+ pr_debug("%s: pixel clock not supported: %d\n",
+ __func__, (int)pixel_clk_rate);
+ return;
+ }
+
+ pr_debug("%s: samplerate=%d ratio=%d pixelclk=%d N=%d cts=%d\n",
+ __func__, sample_rate, hdmi_ratio, (int)pixel_clk_rate,
+ clk_n, clk_cts);
+
+ hdmi_set_clock_regenerator_cts(clk_cts);
+ hdmi_set_clock_regenerator_n(clk_n);
+}
+
+static int hdmi_core_get_of_property(struct platform_device *pdev)
+{
+ struct device_node *np = pdev->dev.of_node;
+ int err;
+ int ipu_id, disp_id;
+
+ err = of_property_read_u32(np, "ipu_id", &ipu_id);
+ if (err) {
+ dev_dbg(&pdev->dev, "get of property ipu_id fail\n");
+ return err;
+ }
+ err = of_property_read_u32(np, "disp_id", &disp_id);
+ if (err) {
+ dev_dbg(&pdev->dev, "get of property disp_id fail\n");
+ return err;
+ }
+
+ mxc_hdmi_ipu_id = ipu_id;
+ mxc_hdmi_disp_id = disp_id;
+
+ return err;
+}
+
+/* Need to run this before phy is enabled the first time to prevent
+ * overflow condition in HDMI_IH_FC_STAT2 */
+void hdmi_init_clk_regenerator(void)
+{
+ if (pixel_clk_rate == 0) {
+ pixel_clk_rate = 74250000;
+ hdmi_set_clk_regenerator();
+ }
+}
+EXPORT_SYMBOL(hdmi_init_clk_regenerator);
+
+void hdmi_clk_regenerator_update_pixel_clock(u32 pixclock)
+{
+
+ if (!pixclock)
+ return;
+ /* Translate pixel clock in ps (pico seconds) to Hz */
+ pixel_clk_rate = PICOS2KHZ(pixclock) * 1000UL;
+ hdmi_set_clk_regenerator();
+}
+EXPORT_SYMBOL(hdmi_clk_regenerator_update_pixel_clock);
+
+void hdmi_set_dma_mode(unsigned int dma_running)
+{
+ hdmi_dma_running = dma_running;
+ hdmi_set_clk_regenerator();
+}
+EXPORT_SYMBOL(hdmi_set_dma_mode);
+
+void hdmi_set_sample_rate(unsigned int rate)
+{
+ sample_rate = rate;
+}
+EXPORT_SYMBOL(hdmi_set_sample_rate);
+
+void hdmi_set_edid_cfg(struct mxc_edid_cfg *cfg)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&edid_spinlock, flags);
+ memcpy(&hdmi_core_edid_cfg, cfg, sizeof(struct mxc_edid_cfg));
+ spin_unlock_irqrestore(&edid_spinlock, flags);
+}
+EXPORT_SYMBOL(hdmi_set_edid_cfg);
+
+void hdmi_get_edid_cfg(struct mxc_edid_cfg *cfg)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&edid_spinlock, flags);
+ memcpy(cfg, &hdmi_core_edid_cfg, sizeof(struct mxc_edid_cfg));
+ spin_unlock_irqrestore(&edid_spinlock, flags);
+}
+EXPORT_SYMBOL(hdmi_get_edid_cfg);
+
+void hdmi_set_registered(int registered)
+{
+ hdmi_core_init = registered;
+}
+EXPORT_SYMBOL(hdmi_set_registered);
+
+int hdmi_get_registered(void)
+{
+ return hdmi_core_init;
+}
+EXPORT_SYMBOL(hdmi_get_registered);
+
+static int mxc_hdmi_core_probe(struct platform_device *pdev)
+{
+ struct mxc_hdmi_data *hdmi_data;
+ struct resource *res;
+ unsigned long flags;
+ int ret = 0;
+
+#ifdef DEBUG
+ overflow_lo = false;
+ overflow_hi = false;
+#endif
+
+ hdmi_core_init = 0;
+ hdmi_dma_running = 0;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res)
+ return -ENOENT;
+
+ ret = hdmi_core_get_of_property(pdev);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "get hdmi of property fail\n");
+ return -ENOENT;
+ }
+
+ hdmi_data = devm_kzalloc(&pdev->dev, sizeof(struct mxc_hdmi_data), GFP_KERNEL);
+ if (!hdmi_data) {
+ dev_err(&pdev->dev, "Couldn't allocate mxc hdmi mfd device\n");
+ return -ENOMEM;
+ }
+ hdmi_data->pdev = pdev;
+
+ pixel_clk = NULL;
+ sample_rate = 48000;
+ pixel_clk_rate = 0;
+ hdmi_ratio = 100;
+
+ spin_lock_init(&irq_spinlock);
+ spin_lock_init(&edid_spinlock);
+
+
+ spin_lock_init(&hdmi_cable_state_lock);
+ spin_lock_init(&hdmi_blank_state_lock);
+ spin_lock_init(&hdmi_audio_lock);
+
+ spin_lock_irqsave(&hdmi_cable_state_lock, flags);
+ hdmi_cable_state = 0;
+ spin_unlock_irqrestore(&hdmi_cable_state_lock, flags);
+
+ spin_lock_irqsave(&hdmi_blank_state_lock, flags);
+ hdmi_blank_state = 0;
+ spin_unlock_irqrestore(&hdmi_blank_state_lock, flags);
+
+ spin_lock_irqsave(&hdmi_audio_lock, flags);
+ hdmi_audio_stream_playback = NULL;
+ hdmi_abort_state = 0;
+ spin_unlock_irqrestore(&hdmi_audio_lock, flags);
+
+ mipi_core_clk = clk_get(&hdmi_data->pdev->dev, "mipi_core");
+ if (IS_ERR(mipi_core_clk)) {
+ ret = PTR_ERR(mipi_core_clk);
+ dev_err(&hdmi_data->pdev->dev,
+ "Unable to get mipi core clk: %d\n", ret);
+ goto eclkg;
+ }
+
+ ret = clk_prepare_enable(mipi_core_clk);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "Cannot enable mipi core clock: %d\n", ret);
+ goto eclke;
+ }
+
+ isfr_clk = clk_get(&hdmi_data->pdev->dev, "hdmi_isfr");
+ if (IS_ERR(isfr_clk)) {
+ ret = PTR_ERR(isfr_clk);
+ dev_err(&hdmi_data->pdev->dev,
+ "Unable to get HDMI isfr clk: %d\n", ret);
+ goto eclkg1;
+ }
+
+ ret = clk_prepare_enable(isfr_clk);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "Cannot enable HDMI clock: %d\n", ret);
+ goto eclke1;
+ }
+
+ pr_debug("%s isfr_clk:%d\n", __func__,
+ (int)clk_get_rate(isfr_clk));
+
+ iahb_clk = clk_get(&hdmi_data->pdev->dev, "hdmi_iahb");
+ if (IS_ERR(iahb_clk)) {
+ ret = PTR_ERR(iahb_clk);
+ dev_err(&hdmi_data->pdev->dev,
+ "Unable to get HDMI iahb clk: %d\n", ret);
+ goto eclkg2;
+ }
+
+ ret = clk_prepare_enable(iahb_clk);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "Cannot enable HDMI clock: %d\n", ret);
+ goto eclke2;
+ }
+
+ hdmi_data->reg_phys_base = res->start;
+ if (!request_mem_region(res->start, resource_size(res),
+ dev_name(&pdev->dev))) {
+ dev_err(&pdev->dev, "request_mem_region failed\n");
+ ret = -EBUSY;
+ goto emem;
+ }
+
+ hdmi_data->reg_base = ioremap(res->start, resource_size(res));
+ if (!hdmi_data->reg_base) {
+ dev_err(&pdev->dev, "ioremap failed\n");
+ ret = -ENOMEM;
+ goto eirq;
+ }
+ hdmi_base = hdmi_data->reg_base;
+
+ pr_debug("\n%s hdmi hw base = 0x%08x\n\n", __func__, (int)res->start);
+
+ initialize_hdmi_ih_mutes();
+
+ /* Disable HDMI clocks until video/audio sub-drivers are initialized */
+ clk_disable_unprepare(isfr_clk);
+ clk_disable_unprepare(iahb_clk);
+ clk_disable_unprepare(mipi_core_clk);
+
+ /* Replace platform data coming in with a local struct */
+ platform_set_drvdata(pdev, hdmi_data);
+
+ return ret;
+
+eirq:
+ release_mem_region(res->start, resource_size(res));
+emem:
+ clk_disable_unprepare(iahb_clk);
+eclke2:
+ clk_put(iahb_clk);
+eclkg2:
+ clk_disable_unprepare(isfr_clk);
+eclke1:
+ clk_put(isfr_clk);
+eclkg1:
+ clk_disable_unprepare(mipi_core_clk);
+eclke:
+ clk_put(mipi_core_clk);
+eclkg:
+ return ret;
+}
+
+
+static int __exit mxc_hdmi_core_remove(struct platform_device *pdev)
+{
+ struct mxc_hdmi_data *hdmi_data = platform_get_drvdata(pdev);
+ struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+
+ iounmap(hdmi_data->reg_base);
+ release_mem_region(res->start, resource_size(res));
+
+ return 0;
+}
+
+static const struct of_device_id imx_hdmi_dt_ids[] = {
+ { .compatible = "fsl,imx6q-hdmi-core", },
+ { .compatible = "fsl,imx6dl-hdmi-core", },
+ { /* sentinel */ }
+};
+
+static struct platform_driver mxc_hdmi_core_driver = {
+ .driver = {
+ .name = "mxc_hdmi_core",
+ .of_match_table = imx_hdmi_dt_ids,
+ .owner = THIS_MODULE,
+ },
+ .remove = __exit_p(mxc_hdmi_core_remove),
+};
+
+static int __init mxc_hdmi_core_init(void)
+{
+ return platform_driver_probe(&mxc_hdmi_core_driver,
+ mxc_hdmi_core_probe);
+}
+
+static void __exit mxc_hdmi_core_exit(void)
+{
+ platform_driver_unregister(&mxc_hdmi_core_driver);
+}
+
+subsys_initcall(mxc_hdmi_core_init);
+module_exit(mxc_hdmi_core_exit);
+
+MODULE_DESCRIPTION("Core driver for Freescale i.Mx on-chip HDMI");
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_LICENSE("GPL");
diff --git a/drivers/mfd/pf1550.c b/drivers/mfd/pf1550.c
new file mode 100644
index 000000000000..44c92f466a99
--- /dev/null
+++ b/drivers/mfd/pf1550.c
@@ -0,0 +1,311 @@
+/*
+ * pf1550.c - mfd core driver for the PF1550
+ *
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Robin Gong <yibin.gong@freescale.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.
+ *
+ * This driver is based on max77693.c
+ */
+
+#include <linux/err.h>
+#include <linux/i2c.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/mfd/core.h>
+#include <linux/mfd/pf1550.h>
+#include <linux/of.h>
+#include <linux/regmap.h>
+
+static const struct mfd_cell pf1550_devs[] = {
+ {
+ .name = "pf1550-regulator",
+ .of_compatible = "fsl,pf1550-regulator",
+ },
+ {
+ .name = "pf1550-onkey",
+ .of_compatible = "fsl,pf1550-onkey",
+ },
+ {
+ .name = "pf1550-charger",
+ .of_compatible = "fsl,pf1550-charger",
+ },
+};
+
+static const struct regmap_config pf1550_regmap_config = {
+ .reg_bits = 8,
+ .val_bits = 8,
+ .max_register = PF1550_PMIC_REG_END,
+};
+
+static const struct regmap_irq pf1550_regulator_irqs[] = {
+ { .reg_offset = 0, .mask = PMIC_IRQ_SW1_LS, },
+ { .reg_offset = 0, .mask = PMIC_IRQ_SW2_LS, },
+ { .reg_offset = 0, .mask = PMIC_IRQ_SW3_LS, },
+
+ { .reg_offset = 3, .mask = PMIC_IRQ_SW1_HS, },
+ { .reg_offset = 3, .mask = PMIC_IRQ_SW2_HS, },
+ { .reg_offset = 3, .mask = PMIC_IRQ_SW3_HS, },
+
+ { .reg_offset = 16, .mask = PMIC_IRQ_LDO1_FAULT, },
+ { .reg_offset = 16, .mask = PMIC_IRQ_LDO2_FAULT, },
+ { .reg_offset = 16, .mask = PMIC_IRQ_LDO3_FAULT, },
+
+ { .reg_offset = 22, .mask = PMIC_IRQ_TEMP_110, },
+ { .reg_offset = 22, .mask = PMIC_IRQ_TEMP_125, },
+};
+
+static const struct regmap_irq_chip pf1550_regulator_irq_chip = {
+ .name = "pf1550-regulator",
+ .status_base = PF1550_PMIC_REG_SW_INT_STAT0,
+ .mask_base = PF1550_PMIC_REG_SW_INT_MASK0,
+ .mask_invert = false,
+ .num_regs = 23,
+ .irqs = pf1550_regulator_irqs,
+ .num_irqs = ARRAY_SIZE(pf1550_regulator_irqs),
+};
+
+static const struct regmap_irq pf1550_onkey_irqs[] = {
+ { .reg_offset = 0, .mask = ONKEY_IRQ_PUSHI, },
+ { .reg_offset = 0, .mask = ONKEY_IRQ_1SI, },
+ { .reg_offset = 0, .mask = ONKEY_IRQ_2SI, },
+ { .reg_offset = 0, .mask = ONKEY_IRQ_3SI, },
+ { .reg_offset = 0, .mask = ONKEY_IRQ_4SI, },
+ { .reg_offset = 0, .mask = ONKEY_IRQ_8SI, },
+};
+
+static const struct regmap_irq_chip pf1550_onkey_irq_chip = {
+ .name = "pf1550-onkey",
+ .status_base = PF1550_PMIC_REG_ONKEY_INT_STAT0,
+ .ack_base = PF1550_PMIC_REG_ONKEY_INT_STAT0,
+ .mask_base = PF1550_PMIC_REG_ONKEY_INT_MASK0,
+ .mask_invert = false,
+ .use_ack = 1,
+ .init_ack_masked = 1,
+ .num_regs = 1,
+ .irqs = pf1550_onkey_irqs,
+ .num_irqs = ARRAY_SIZE(pf1550_onkey_irqs),
+};
+
+static const struct regmap_irq pf1550_charger_irqs[] = {
+ { .reg_offset = 0, .mask = CHARG_IRQ_BAT2SOCI, },
+ { .reg_offset = 0, .mask = CHARG_IRQ_BATI, },
+ { .reg_offset = 0, .mask = CHARG_IRQ_CHGI, },
+ { .reg_offset = 0, .mask = CHARG_IRQ_VBUSI, },
+ { .reg_offset = 0, .mask = CHARG_IRQ_THMI, },
+};
+
+static const struct regmap_irq_chip pf1550_charger_irq_chip = {
+ .name = "pf1550-charger",
+ .status_base = PF1550_CHARG_REG_CHG_INT,
+ .mask_base = PF1550_CHARG_REG_CHG_INT_MASK,
+ .mask_invert = false,
+ .num_regs = 1,
+ .irqs = pf1550_charger_irqs,
+ .num_irqs = ARRAY_SIZE(pf1550_charger_irqs),
+};
+
+int pf1550_read_otp(struct pf1550_dev *pf1550, unsigned int index,
+ unsigned int *val)
+{
+ int ret = 0;
+
+ ret = regmap_write(pf1550->regmap, PF1550_PMIC_REG_KEY, 0x15);
+ if (ret)
+ goto read_err;
+ ret = regmap_write(pf1550->regmap, PF1550_CHARG_REG_CHGR_KEY2, 0x50);
+ if (ret)
+ goto read_err;
+ ret = regmap_write(pf1550->regmap, PF1550_TEST_REG_KEY3, 0xAB);
+ if (ret)
+ goto read_err;
+ ret = regmap_write(pf1550->regmap, PF1550_TEST_REG_FMRADDR, index);
+ if (ret)
+ goto read_err;
+ ret = regmap_read(pf1550->regmap, PF1550_TEST_REG_FMRDATA, val);
+ if (ret)
+ goto read_err;
+
+ return 0;
+
+read_err:
+ dev_err(pf1550->dev, "read otp reg %x found!\n", index);
+ return ret;
+}
+
+static int pf1550_i2c_probe(struct i2c_client *i2c,
+ const struct i2c_device_id *id)
+{
+ struct pf1550_dev *pf1550;
+ unsigned int reg_data = 0;
+ int ret = 0;
+
+ pf1550 = devm_kzalloc(&i2c->dev,
+ sizeof(struct pf1550_dev), GFP_KERNEL);
+ if (!pf1550)
+ return -ENOMEM;
+
+ i2c_set_clientdata(i2c, pf1550);
+ pf1550->dev = &i2c->dev;
+ pf1550->i2c = i2c;
+ pf1550->irq = i2c->irq;
+
+ pf1550->regmap = devm_regmap_init_i2c(i2c, &pf1550_regmap_config);
+ if (IS_ERR(pf1550->regmap)) {
+ ret = PTR_ERR(pf1550->regmap);
+ dev_err(pf1550->dev, "failed to allocate register map: %d\n",
+ ret);
+ return ret;
+ }
+
+ ret = regmap_read(pf1550->regmap, PF1550_PMIC_REG_DEVICE_ID, &reg_data);
+ if (ret < 0 || reg_data != 0x7c) {
+ dev_err(pf1550->dev, "device not found!\n");
+ return ret;
+ }
+
+ pf1550->type = PF1550;
+ dev_info(pf1550->dev, "pf1550 found.\n");
+
+ ret = regmap_add_irq_chip(pf1550->regmap, pf1550->irq,
+ IRQF_ONESHOT | IRQF_SHARED |
+ IRQF_TRIGGER_FALLING, 0,
+ &pf1550_regulator_irq_chip,
+ &pf1550->irq_data_regulator);
+ if (ret) {
+ dev_err(pf1550->dev, "failed to add irq1 chip: %d\n", ret);
+ goto err_regulator_irq;
+ }
+
+ ret = regmap_add_irq_chip(pf1550->regmap, pf1550->irq,
+ IRQF_ONESHOT | IRQF_SHARED |
+ IRQF_TRIGGER_FALLING, 0,
+ &pf1550_onkey_irq_chip,
+ &pf1550->irq_data_onkey);
+ if (ret) {
+ dev_err(pf1550->dev, "failed to add irq3 chip: %d\n", ret);
+ goto err_onkey_irq;
+ }
+
+ ret = regmap_add_irq_chip(pf1550->regmap, pf1550->irq,
+ IRQF_ONESHOT | IRQF_SHARED |
+ IRQF_TRIGGER_FALLING, 0,
+ &pf1550_charger_irq_chip,
+ &pf1550->irq_data_charger);
+ if (ret) {
+ dev_err(pf1550->dev, "failed to add irq4 chip: %d\n", ret);
+ goto err_charger_irq;
+ }
+
+ ret = mfd_add_devices(pf1550->dev, -1, pf1550_devs,
+ ARRAY_SIZE(pf1550_devs), NULL, 0, NULL);
+ if (ret < 0)
+ goto err_mfd;
+
+ return ret;
+
+err_mfd:
+ mfd_remove_devices(pf1550->dev);
+err_charger_irq:
+ regmap_del_irq_chip(pf1550->irq, pf1550->irq_data_charger);
+err_onkey_irq:
+ regmap_del_irq_chip(pf1550->irq, pf1550->irq_data_regulator);
+err_regulator_irq:
+ return ret;
+}
+
+static int pf1550_i2c_remove(struct i2c_client *i2c)
+{
+ struct pf1550_dev *pf1550 = i2c_get_clientdata(i2c);
+
+ mfd_remove_devices(pf1550->dev);
+
+ regmap_del_irq_chip(pf1550->irq, pf1550->irq_data_regulator);
+ regmap_del_irq_chip(pf1550->irq, pf1550->irq_data_onkey);
+ regmap_del_irq_chip(pf1550->irq, pf1550->irq_data_charger);
+
+ return 0;
+}
+
+static const struct i2c_device_id pf1550_i2c_id[] = {
+ { "pf1550", PF1550 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, pf1550_i2c_id);
+
+static int pf1550_suspend(struct device *dev)
+{
+ struct i2c_client *i2c = container_of(dev, struct i2c_client, dev);
+ struct pf1550_dev *pf1550 = i2c_get_clientdata(i2c);
+
+ if (device_may_wakeup(dev)) {
+ enable_irq_wake(pf1550->irq);
+ disable_irq(pf1550->irq);
+ }
+
+ return 0;
+}
+
+static int pf1550_resume(struct device *dev)
+{
+ struct i2c_client *i2c = container_of(dev, struct i2c_client, dev);
+ struct pf1550_dev *pf1550 = i2c_get_clientdata(i2c);
+
+ if (device_may_wakeup(dev)) {
+ disable_irq_wake(pf1550->irq);
+ enable_irq(pf1550->irq);
+ }
+
+ return 0;
+}
+
+static const struct dev_pm_ops pf1550_pm = {
+ .suspend = pf1550_suspend,
+ .resume = pf1550_resume,
+};
+
+#ifdef CONFIG_OF
+static const struct of_device_id pf1550_dt_match[] = {
+ { .compatible = "fsl,pf1550" },
+ {},
+};
+#endif
+
+static struct i2c_driver pf1550_i2c_driver = {
+ .driver = {
+ .name = "pf1550",
+ .owner = THIS_MODULE,
+ .pm = &pf1550_pm,
+ .of_match_table = of_match_ptr(pf1550_dt_match),
+ },
+ .probe = pf1550_i2c_probe,
+ .remove = pf1550_i2c_remove,
+ .id_table = pf1550_i2c_id,
+};
+
+static int __init pf1550_i2c_init(void)
+{
+ return i2c_add_driver(&pf1550_i2c_driver);
+}
+/* init early so consumer devices can complete system boot */
+subsys_initcall(pf1550_i2c_init);
+
+static void __exit pf1550_i2c_exit(void)
+{
+ i2c_del_driver(&pf1550_i2c_driver);
+}
+module_exit(pf1550_i2c_exit);
+
+MODULE_DESCRIPTION("Freescale PF1550 multi-function core driver");
+MODULE_AUTHOR("Robin Gong <yibin.gong@freescale.com>");
+MODULE_LICENSE("GPL");
+
diff --git a/drivers/mfd/si476x-i2c.c b/drivers/mfd/si476x-i2c.c
index e6a3d999a376..3bbbe9124efc 100644
--- a/drivers/mfd/si476x-i2c.c
+++ b/drivers/mfd/si476x-i2c.c
@@ -303,7 +303,7 @@ int si476x_core_set_power_state(struct si476x_core *core,
*/
udelay(100);
- err = si476x_core_start(core, false);
+ err = si476x_core_start(core, true);
if (err < 0)
goto disable_regulators;
@@ -312,7 +312,7 @@ int si476x_core_set_power_state(struct si476x_core *core,
case SI476X_POWER_DOWN:
core->power_state = next_state;
- err = si476x_core_stop(core, false);
+ err = si476x_core_stop(core, true);
if (err < 0)
core->power_state = SI476X_POWER_INCONSISTENT;
disable_regulators:
@@ -740,8 +740,15 @@ static int si476x_core_probe(struct i2c_client *client,
memcpy(&core->pinmux, &pdata->pinmux,
sizeof(struct si476x_pinmux));
} else {
- dev_err(&client->dev, "No platform data provided\n");
- return -EINVAL;
+ dev_warn(&client->dev, "Using default platform data.\n");
+ core->power_up_parameters.xcload = 0x28;
+ core->power_up_parameters.func = SI476X_FUNC_FM_RECEIVER;
+ core->power_up_parameters.freq = SI476X_FREQ_37P209375_MHZ;
+ core->diversity_mode = SI476X_PHDIV_DISABLED;
+ core->pinmux.dclk = SI476X_DCLK_DAUDIO;
+ core->pinmux.dfs = SI476X_DFS_DAUDIO;
+ core->pinmux.dout = SI476X_DOUT_I2S_OUTPUT;
+ core->pinmux.xout = SI476X_XOUT_TRISTATE;
}
core->supplies[0].supply = "vd";
@@ -800,12 +807,19 @@ static int si476x_core_probe(struct i2c_client *client,
core->chip_id = id->driver_data;
+ /* Power down si476x first */
+ core->power_state = SI476X_POWER_UP_FULL;
+ si476x_core_set_power_state(core, SI476X_POWER_DOWN);
+
rval = si476x_core_get_revision_info(core);
if (rval < 0) {
rval = -ENODEV;
goto free_kfifo;
}
+ if (of_property_read_bool(client->dev.of_node, "revision-a10"))
+ core->revision = SI476X_REVISION_A10;
+
cell_num = 0;
cell = &core->cells[SI476X_RADIO_CELL];
@@ -821,6 +835,7 @@ static int si476x_core_probe(struct i2c_client *client,
core->pinmux.xout == SI476X_XOUT_TRISTATE) {
cell = &core->cells[SI476X_CODEC_CELL];
cell->name = "si476x-codec";
+ cell->of_compatible = "si476x-codec";
cell_num++;
}
#endif
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 8136dc7e863d..db105a02c327 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -335,6 +335,26 @@ config ISL29020
This driver can also be built as a module. If so, the module
will be called isl29020.
+config SENSORS_FXOS8700
+ tristate "Freescale FXOS8700 M+G combo sensor"
+ depends on I2C && SYSFS
+ help
+ If you say yes here you get support for the Freescale FXOS8700
+ m+g combo sensor.
+
+ This driver can also be built as a module. If so, the module
+ will be called fxos8700.
+
+config SENSORS_FXAS2100X
+ tristate "Freescale FXAS2100X gyroscope sensor"
+ depends on I2C && SYSFS
+ help
+ If you say yes here you get support for the Freescale FXAS2100X
+ gyroscope sensor.
+
+ This driver can also be built as a module. If so, the module
+ will be called fxas2100x.
+
config SENSORS_TSL2550
tristate "Taos TSL2550 ambient light sensor"
depends on I2C && SYSFS
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index 76f6a4f628b3..18a8e97232c3 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -17,6 +17,8 @@ obj-$(CONFIG_TIFM_CORE) += tifm_core.o
obj-$(CONFIG_TIFM_7XX1) += tifm_7xx1.o
obj-$(CONFIG_PHANTOM) += phantom.o
obj-$(CONFIG_QCOM_COINCELL) += qcom-coincell.o
+obj-$(CONFIG_SENSORS_FXOS8700) += fxos8700.o
+obj-$(CONFIG_SENSORS_FXAS2100X) += fxas2100x.o
obj-$(CONFIG_SENSORS_BH1770) += bh1770glc.o
obj-$(CONFIG_SENSORS_APDS990X) += apds990x.o
obj-$(CONFIG_SGI_IOC4) += ioc4.o
diff --git a/drivers/misc/eeprom/at25.c b/drivers/misc/eeprom/at25.c
index 5afe4cd16569..67eb81aecfe4 100644
--- a/drivers/misc/eeprom/at25.c
+++ b/drivers/misc/eeprom/at25.c
@@ -249,7 +249,7 @@ static int at25_fw_to_chip(struct device *dev, struct spi_eeprom *chip)
u32 val;
memset(chip, 0, sizeof(*chip));
- strncpy(chip->name, "at25", sizeof(chip->name));
+ strlcpy(chip->name, "at25", sizeof(chip->name));
if (device_property_read_u32(dev, "size", &val) == 0 ||
device_property_read_u32(dev, "at25,byte-len", &val) == 0) {
diff --git a/drivers/misc/fxas2100x.c b/drivers/misc/fxas2100x.c
new file mode 100644
index 000000000000..04541cfb5d14
--- /dev/null
+++ b/drivers/misc/fxas2100x.c
@@ -0,0 +1,628 @@
+/*
+ * Copyright (C) 2012-2015 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/pm.h>
+#include <linux/mutex.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/hwmon-sysfs.h>
+#include <linux/err.h>
+#include <linux/hwmon.h>
+#include <linux/input-polldev.h>
+#include <linux/miscdevice.h>
+#include <linux/poll.h>
+
+#define SENSOR_IOCTL_BASE 'S'
+#define SENSOR_GET_MODEL_NAME _IOR(SENSOR_IOCTL_BASE, 0, char *)
+#define SENSOR_GET_POWER_STATUS _IOR(SENSOR_IOCTL_BASE, 2, int)
+#define SENSOR_SET_POWER_STATUS _IOR(SENSOR_IOCTL_BASE, 3, int)
+#define SENSOR_GET_DELAY_TIME _IOR(SENSOR_IOCTL_BASE, 4, int)
+#define SENSOR_SET_DELAY_TIME _IOR(SENSOR_IOCTL_BASE, 5, int)
+#define SENSOR_GET_RAW_DATA _IOR(SENSOR_IOCTL_BASE, 6, short[3])
+
+#define FXAS2100X_I2C_ADDR 0x20
+#define FXAS21000_CHIP_ID 0xD1
+#define FXAS21002_CHID_ID_1 0xD6
+#define FXAS21002_CHID_ID_2 0xD7
+
+#define FXAS2100X_POSITION_DEFAULT 2
+#define FXAS2100X_DELAY_DEFAULT 200
+
+#define FXAS2100X_STATUS_ZYXDR 0x08
+#define FXAS2100X_BUF_SIZE 6
+
+#define FXAS2100X_POLL_INTERVAL 400
+#define FXAS2100X_POLL_MAX 800
+#define FXAS2100X_POLL_MIN 200
+#define ABSMIN_GYRO_VAL -32768
+#define ABSMAX_GYRO_VAL 32768
+
+#define FXAS2100X_DRIVER "fxas2100x"
+
+/* register enum for fxas2100x registers */
+enum {
+ FXAS2100X_STATUS = 0x00,
+ FXAS2100X_OUT_X_MSB,
+ FXAS2100X_OUT_X_LSB,
+ FXAS2100X_OUT_Y_MSB,
+ FXAS2100X_OUT_Y_LSB,
+ FXAS2100X_OUT_Z_MSB,
+ FXAS2100X_OUT_Z_LSB,
+ FXAS2100X_DR_STATUS,
+ FXAS2100X_F_STATUS,
+ FXAS2100X_F_SETUP,
+ FXAS2100X_F_EVENT,
+ FXAS2100X_INT_SRC_FLAG,
+ FXAS2100X_WHO_AM_I,
+ FXAS2100X_CTRL_REG0,
+ FXAS2100X_RT_CFG,
+ FXAS2100X_RT_SRC,
+ FXAS2100X_RT_THS,
+ FXAS2100X_RT_COUNT,
+ FXAS2100X_TEMP,
+ FXAS2100X_CTRL_REG1,
+ FXAS2100X_CTRL_REG2,
+ FXAS2100X_CTRL_REG3, /* fxos21002 special */
+ FXAS2100X_REG_END,
+};
+
+enum {
+ STANDBY = 0,
+ ACTIVED,
+};
+
+struct fxas2100x_data_axis {
+ short x;
+ short y;
+ short z;
+};
+
+struct fxas2100x_data {
+ struct i2c_client *client;
+ struct input_polled_dev *input_polled;
+ atomic_t active;
+ atomic_t active_poll;
+ atomic_t delay;
+ atomic_t position;
+ u8 chip_id;
+};
+
+static struct fxas2100x_data *g_fxas2100x_data;
+
+static int fxas2100x_position_setting[8][3][3] = {
+ { {0, -1, 0}, {1, 0, 0}, {0, 0, 1} },
+ { {-1, 0, 0}, {0, -1, 0}, {0, 0, 1} },
+ { {0, 1, 0}, {-1, 0, 0}, {0, 0, 1} },
+ { {1, 0, 0}, {0, 1, 0}, {0, 0, 1} },
+ { {0, -1, 0}, {-1, 0, 0}, {0, 0, -1} },
+ { {-1, 0, 0}, {0, 1, 0}, {0, 0, -1} },
+ { {0, 1, 0}, {1, 0, 0}, {0, 0, -1} },
+ { {1, 0, 0}, {0, -1, 0}, {0, 0, -1} },
+};
+
+static int fxas2100x_data_convert(struct fxas2100x_data *pdata,
+ struct fxas2100x_data_axis *axis_data)
+{
+ short rawdata[3], data[3];
+ int i, j;
+ int position = atomic_read(&pdata->position);
+
+ if (position < 0 || position > 7)
+ position = 0;
+ rawdata[0] = axis_data->x;
+ rawdata[1] = axis_data->y;
+ rawdata[2] = axis_data->z;
+ for (i = 0; i < 3; i++) {
+ data[i] = 0;
+ for (j = 0; j < 3; j++)
+ data[i] += rawdata[j] * fxas2100x_position_setting[position][i][j];
+ }
+ axis_data->x = data[0];
+ axis_data->y = data[1];
+ axis_data->z = data[2];
+ return 0;
+}
+
+static int fxas2100x_device_init(struct i2c_client *client)
+{
+ int result;
+ u8 val;
+ struct device_node *np = client->dev.of_node;
+
+ struct fxas2100x_data *pdata = i2c_get_clientdata(client);
+ if (pdata->chip_id == FXAS21000_CHIP_ID)
+ val = (0x01 << 2); /* fxas21000 dr 200HZ */
+ else
+ val = (0x02 << 2); /* fxas21002 dr 200HZ */
+ result = i2c_smbus_write_byte_data(client, FXAS2100X_CTRL_REG1, val);
+ if (result < 0)
+ goto out;
+
+ /* set interrupt pin as open-drain */
+ if (of_get_property(np, "interrupt-open-drain", NULL)) {
+ result = i2c_smbus_write_byte_data(client, FXAS2100X_CTRL_REG2, 0x01);
+ if (result < 0)
+ goto out;
+ }
+
+ atomic_set(&pdata->active, STANDBY);
+ return 0;
+out:
+ dev_err(&client->dev, "error when init fxas2100x:(%d)", result);
+ return result;
+}
+
+static int fxas2100x_change_mode(struct i2c_client *client, int mode)
+{
+ u8 val;
+ int ret;
+ if (mode == ACTIVED) {
+ val = i2c_smbus_read_byte_data(client, FXAS2100X_CTRL_REG1);
+ val &= ~0x03;
+ val |= 0x02;
+ /* set bit 1 */
+ ret = i2c_smbus_write_byte_data(client, FXAS2100X_CTRL_REG1, val);
+ } else {
+ val = i2c_smbus_read_byte_data(client, FXAS2100X_CTRL_REG1);
+ val &= (~0x03);
+ /* clear bit 0,1 */
+ ret = i2c_smbus_write_byte_data(client, FXAS2100X_CTRL_REG1, val);
+ }
+ return ret;
+}
+
+static int fxas2100x_set_delay(struct i2c_client *client, int delay)
+{
+ return 0;
+}
+
+static int fxas2100x_device_stop(struct i2c_client *client)
+{
+ u8 val;
+ val = i2c_smbus_read_byte_data(client, FXAS2100X_CTRL_REG1);
+ val &= ~0x03;
+ i2c_smbus_write_byte_data(client, FXAS2100X_CTRL_REG1, val);
+ return 0;
+}
+
+static int fxas2100x_read_data(struct fxas2100x_data *pdata,
+ struct fxas2100x_data_axis *data)
+{
+ struct i2c_client * client = pdata->client;
+ int x, y, z;
+ u8 tmp_data[FXAS2100X_BUF_SIZE];
+ int ret;
+
+ ret = i2c_smbus_read_i2c_block_data(client, FXAS2100X_OUT_X_MSB,
+ FXAS2100X_BUF_SIZE, tmp_data);
+ if (ret < FXAS2100X_BUF_SIZE) {
+ dev_err(&client->dev, "i2c block read failed\n");
+ return -EIO;
+ }
+ data->x = ((tmp_data[0] << 8) & 0xff00) | tmp_data[1];
+ data->y = ((tmp_data[2] << 8) & 0xff00) | tmp_data[3];
+ data->z = ((tmp_data[4] << 8) & 0xff00) | tmp_data[5];
+ if (pdata->chip_id == FXAS21000_CHIP_ID) {
+ x = data->x;
+ y = data->y;
+ z = data->z;
+ x = x * 4 / 5;
+ y = y * 4 / 5;
+ z = z * 4 / 5;
+ data->x = x;
+ data->y = y;
+ data->z = z;
+ }
+
+ return 0;
+}
+
+/* fxas2100x miscdevice */
+static long fxas2100x_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+ struct fxas2100x_data *pdata = file->private_data;
+ void __user *argp = (void __user *)arg;
+ struct fxas2100x_data_axis data;
+ long ret = 0;
+ short sdata[3];
+ int enable;
+ int delay;
+
+ if (!pdata) {
+ printk(KERN_ERR "FXAS2100X struct datt point is NULL.");
+ return -EFAULT;
+ }
+
+ switch (cmd) {
+ case SENSOR_GET_MODEL_NAME:
+ if (copy_to_user(argp, "FXAS2100X GYRO", strlen("FXAS2100X GYRO") + 1)) {
+ printk(KERN_ERR "SENSOR_GET_MODEL_NAME copy_to_user failed.");
+ ret = -EFAULT;
+ }
+ break;
+ case SENSOR_GET_POWER_STATUS:
+ enable = atomic_read(&pdata->active);
+ if (copy_to_user(argp, &enable, sizeof(int))) {
+ printk(KERN_ERR "SENSOR_SET_POWER_STATUS copy_to_user failed.");
+ ret = -EFAULT;
+ }
+ break;
+ case SENSOR_SET_POWER_STATUS:
+ if (copy_from_user(&enable, argp, sizeof(int))) {
+ printk(KERN_ERR "SENSOR_SET_POWER_STATUS copy_to_user failed.");
+ ret = -EFAULT;
+ }
+ if (pdata->client) {
+ ret = fxas2100x_change_mode(pdata->client, enable ? ACTIVED : STANDBY);
+ if (!ret)
+ atomic_set(&pdata->active, enable);
+ }
+ break;
+ case SENSOR_GET_DELAY_TIME:
+ delay = atomic_read(&pdata->delay);
+ if (copy_to_user(argp, &delay, sizeof(delay))) {
+ printk(KERN_ERR "SENSOR_GET_DELAY_TIME copy_to_user failed.");
+ return -EFAULT;
+ }
+ break;
+ case SENSOR_SET_DELAY_TIME:
+ if (copy_from_user(&delay, argp, sizeof(int))) {
+ printk(KERN_ERR "SENSOR_GET_DELAY_TIME copy_to_user failed.");
+ ret = -EFAULT;
+ }
+ if (pdata->client && delay > 0 && delay <= 500) {
+ ret = fxas2100x_set_delay(pdata->client, delay);
+ if (!ret)
+ atomic_set(&pdata->delay, delay);
+ }
+ break;
+ case SENSOR_GET_RAW_DATA:
+ ret = fxas2100x_read_data(pdata, &data);
+ if (!ret) {
+ fxas2100x_data_convert(pdata, &data);
+ sdata[0] = data.x;
+ sdata[1] = data.y;
+ sdata[2] = data.z;
+ if (copy_to_user(argp, sdata, sizeof(sdata))) {
+ printk(KERN_ERR "SENSOR_GET_RAW_DATA copy_to_user failed.");
+ ret = -EFAULT;
+ }
+ }
+ break;
+ default:
+ ret = -1;
+ }
+
+ return ret;
+}
+
+static int fxas2100x_open(struct inode *inode, struct file *file)
+{
+ file->private_data = g_fxas2100x_data;
+ return nonseekable_open(inode, file);
+}
+
+static int fxas2100x_release(struct inode *inode, struct file *file)
+{
+ /* note: releasing the wdt in NOWAYOUT-mode does not stop it */
+ return 0;
+}
+
+static const struct file_operations fxas2100x_fops = {
+ .owner = THIS_MODULE,
+ .open = fxas2100x_open,
+ .release = fxas2100x_release,
+ .unlocked_ioctl = fxas2100x_ioctl,
+};
+
+static struct miscdevice fxas2100x_device = {
+ .minor = MISC_DYNAMIC_MINOR,
+ .name = "FreescaleGyroscope",
+ .fops = &fxas2100x_fops,
+};
+
+static ssize_t fxas2100x_enable_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct fxas2100x_data *pdata = g_fxas2100x_data;
+ int enable = 0;
+ enable = atomic_read(&pdata->active);
+ return sprintf(buf, "%d\n", enable);
+}
+
+static ssize_t fxas2100x_enable_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct fxas2100x_data *pdata = g_fxas2100x_data;
+ struct i2c_client *client = pdata->client;
+ int ret;
+ unsigned long enable;
+
+ if (kstrtoul(buf, 10, &enable) < 0)
+ return -EINVAL;
+
+ enable = (enable > 0) ? 1 : 0;
+ ret = fxas2100x_change_mode(client, (enable > 0 ? ACTIVED : STANDBY));
+ if (!ret) {
+ atomic_set(&pdata->active, enable);
+ atomic_set(&pdata->active_poll, enable);
+ dev_err(dev, "mma enable setting active \n");
+ }
+ return count;
+}
+
+static ssize_t fxas2100x_poll_delay_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct fxas2100x_data *pdata = g_fxas2100x_data;
+ int delay = 0;
+
+ delay = atomic_read(&pdata->delay);
+ return sprintf(buf, "%d\n", delay);
+}
+
+static ssize_t fxas2100x_poll_delay_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct fxas2100x_data *pdata = g_fxas2100x_data;
+ struct i2c_client *client = pdata->client;
+ int ret;
+ int delay;
+
+ delay = simple_strtoul(buf, NULL, 10);
+ ret = fxas2100x_set_delay(client, delay);
+ if (!ret)
+ atomic_set(&pdata->delay, delay);
+ return count;
+}
+
+static ssize_t fxas2100x_position_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct fxas2100x_data *pdata = g_fxas2100x_data;
+ int position = 0;
+
+ position = atomic_read(&pdata->position);
+ return sprintf(buf, "%d\n", position);
+}
+
+static ssize_t fxas2100x_position_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct fxas2100x_data *pdata = g_fxas2100x_data;
+ int position;
+
+ position = simple_strtoul(buf, NULL, 10);
+ atomic_set(&pdata->position, position);
+ return count;
+}
+
+static DEVICE_ATTR(enable, S_IWUSR | S_IRUGO, fxas2100x_enable_show, fxas2100x_enable_store);
+static DEVICE_ATTR(poll_delay, S_IWUSR | S_IRUGO, fxas2100x_poll_delay_show, fxas2100x_poll_delay_store);
+static DEVICE_ATTR(position, S_IWUSR | S_IRUGO, fxas2100x_position_show, fxas2100x_position_store);
+
+static struct attribute *fxas2100x_attributes[] = {
+ &dev_attr_enable.attr,
+ &dev_attr_poll_delay.attr,
+ &dev_attr_position.attr,
+ NULL
+};
+
+static const struct attribute_group fxas2100x_attr_group = {
+ .attrs = fxas2100x_attributes,
+};
+
+static void fxas2100x_poll(struct input_polled_dev *dev)
+{
+ struct fxas2100x_data *pdata = g_fxas2100x_data;
+ struct input_dev *idev = pdata->input_polled->input;
+ struct fxas2100x_data_axis data;
+ int ret;
+
+ if (!(atomic_read(&pdata->active_poll)))
+ return;
+
+ ret = fxas2100x_read_data(pdata, &data);
+ if (!ret) {
+ fxas2100x_data_convert(pdata, &data);
+ input_report_abs(idev, ABS_X, data.x);
+ input_report_abs(idev, ABS_Y, data.y);
+ input_report_abs(idev, ABS_Z, data.z);
+ input_sync(idev);
+ }
+}
+
+static int fxas2100x_register_polled_device(struct fxas2100x_data *pdata)
+{
+ struct input_polled_dev *ipoll_dev;
+ struct input_dev *idev;
+ int error;
+
+ ipoll_dev = input_allocate_polled_device();
+ if (!ipoll_dev)
+ return -ENOMEM;
+
+ ipoll_dev->private = pdata;
+ ipoll_dev->poll = fxas2100x_poll;
+ ipoll_dev->poll_interval = FXAS2100X_POLL_INTERVAL;
+ ipoll_dev->poll_interval_min = FXAS2100X_POLL_MIN;
+ ipoll_dev->poll_interval_max = FXAS2100X_POLL_MAX;
+ idev = ipoll_dev->input;
+ idev->name = FXAS2100X_DRIVER;
+ idev->id.bustype = BUS_I2C;
+ idev->dev.parent = &pdata->client->dev;
+
+ idev->evbit[0] = BIT_MASK(EV_ABS);
+ input_set_abs_params(idev, ABS_X, ABSMIN_GYRO_VAL, ABSMAX_GYRO_VAL, 0, 0);
+ input_set_abs_params(idev, ABS_Y, ABSMIN_GYRO_VAL, ABSMAX_GYRO_VAL, 0, 0);
+ input_set_abs_params(idev, ABS_Z, ABSMIN_GYRO_VAL, ABSMAX_GYRO_VAL, 0, 0);
+
+ error = input_register_polled_device(ipoll_dev);
+ if (error) {
+ input_free_polled_device(ipoll_dev);
+ return error;
+ }
+
+ pdata->input_polled = ipoll_dev;
+ return 0;
+}
+
+static int fxas2100x_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ int result, chip_id;
+ struct fxas2100x_data *pdata;
+ struct i2c_adapter *adapter;
+
+ adapter = to_i2c_adapter(client->dev.parent);
+ result = i2c_check_functionality(adapter,
+ I2C_FUNC_SMBUS_BYTE |
+ I2C_FUNC_SMBUS_BYTE_DATA);
+ if (!result)
+ goto err_out;
+
+ chip_id = i2c_smbus_read_byte_data(client, FXAS2100X_WHO_AM_I);
+ if (chip_id != FXAS21000_CHIP_ID && chip_id != FXAS21002_CHID_ID_1 &&
+ chip_id != FXAS21002_CHID_ID_2) {
+ dev_err(&client->dev,
+ "read chip ID 0x%x is not equal to 0x%x for fxas21000 or 0x%x/0x%x fxas21002!\n",
+ chip_id, FXAS21000_CHIP_ID, FXAS21002_CHID_ID_1, FXAS21002_CHID_ID_2);
+ result = -EINVAL;
+ goto err_out;
+ }
+
+ pdata = kzalloc(sizeof(struct fxas2100x_data), GFP_KERNEL);
+ if (!pdata) {
+ result = -ENOMEM;
+ dev_err(&client->dev, "alloc data memory error!\n");
+ goto err_out;
+ }
+
+ /* Initialize the FXAS2100X chip */
+ g_fxas2100x_data = pdata;
+ pdata->client = client;
+ pdata->chip_id = chip_id;
+ atomic_set(&pdata->delay, FXAS2100X_DELAY_DEFAULT);
+ atomic_set(&pdata->position, FXAS2100X_POSITION_DEFAULT);
+ i2c_set_clientdata(client, pdata);
+ result = misc_register(&fxas2100x_device);
+ if (result != 0) {
+ dev_err(&client->dev, "register acc miscdevice error");
+ goto err_regsiter_misc;
+ }
+
+ /* for debug */
+ if (client->irq <= 0) {
+ result = fxas2100x_register_polled_device(g_fxas2100x_data);
+ if (result)
+ dev_err(&client->dev,
+ "IRQ GPIO conf. error %d, error %d\n",
+ client->irq, result);
+ }
+
+ result = sysfs_create_group(&fxas2100x_device.this_device->kobj,
+ &fxas2100x_attr_group);
+ if (result) {
+ dev_err(&client->dev, "create device file failed!\n");
+ result = -EINVAL;
+ goto err_create_sysfs;
+ }
+ fxas2100x_device_init(client);
+ dev_info(&client->dev, "fxas2100x device driver probe successfully\n");
+ return 0;
+err_create_sysfs:
+ misc_deregister(&fxas2100x_device);
+err_regsiter_misc:
+ kfree(pdata);
+err_out:
+ return result;
+}
+
+static int fxas2100x_remove(struct i2c_client *client)
+{
+ struct fxas2100x_data *pdata = i2c_get_clientdata(client);
+ fxas2100x_device_stop(client);
+ if (client->irq <= 0) {
+ input_unregister_polled_device(pdata->input_polled);
+ input_free_polled_device(pdata->input_polled);
+ }
+ misc_deregister(&fxas2100x_device);
+ if (pdata != NULL)
+ kfree(pdata);
+ return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int fxas2100x_suspend(struct device *dev)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct fxas2100x_data *pdata = i2c_get_clientdata(client);
+
+ if (atomic_read(&pdata->active))
+ fxas2100x_device_stop(client);
+ return 0;
+}
+
+static int fxas2100x_resume(struct device *dev)
+{
+ int val = 0;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct fxas2100x_data *pdata = i2c_get_clientdata(client);
+
+ if (atomic_read(&pdata->active)) {
+ val = i2c_smbus_read_byte_data(client, FXAS2100X_CTRL_REG1);
+ val &= ~0x03;
+ val |= 0x02;
+ i2c_smbus_write_byte_data(client, FXAS2100X_CTRL_REG1, val);
+ }
+ return 0;
+
+}
+#endif
+
+static const struct i2c_device_id fxas2100x_id[] = {
+ { "fxas2100x", 0 },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(i2c, fxas2100x_id);
+
+static SIMPLE_DEV_PM_OPS(fxas2100x_pm_ops, fxas2100x_suspend, fxas2100x_resume);
+static struct i2c_driver fxas2100x_driver = {
+ .driver = {
+ .name = FXAS2100X_DRIVER,
+ .owner = THIS_MODULE,
+ .pm = &fxas2100x_pm_ops,
+ },
+ .probe = fxas2100x_probe,
+ .remove = fxas2100x_remove,
+ .id_table = fxas2100x_id,
+};
+
+module_i2c_driver(fxas2100x_driver);
+
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("FXAS2100X 3-Axis Gyrosope Sensor driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/misc/fxos8700.c b/drivers/misc/fxos8700.c
new file mode 100644
index 000000000000..e9a07113281f
--- /dev/null
+++ b/drivers/misc/fxos8700.c
@@ -0,0 +1,978 @@
+/*
+ * Copyright (C) 2012-2013 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/pm.h>
+#include <linux/mutex.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/hwmon-sysfs.h>
+#include <linux/err.h>
+#include <linux/hwmon.h>
+#include <linux/input-polldev.h>
+#include <linux/miscdevice.h>
+#include <linux/poll.h>
+
+/*register define*/
+#define FXOS8700_STATUS 0x00
+#define FXOS8700_OUT_X_MSB 0x01
+#define FXOS8700_OUT_X_LSB 0x02
+#define FXOS8700_OUT_Y_MSB 0x03
+#define FXOS8700_OUT_Y_LSB 0x04
+#define FXOS8700_OUT_Z_MSB 0x05
+#define FXOS8700_OUT_Z_LSB 0x06
+#define FXOS8700_F_SETUP 0x09
+#define FXOS8700_TRIG_CFG 0x0a
+#define FXOS8700_SYSMOD 0x0B
+#define FXOS8700_INT_SOURCE 0x0c
+#define FXOS8700_WHO_AM_I 0x0d
+#define FXOS8700_XYZ_DATA_CFG 0x0e
+#define FXOS8700_HP_FILTER_CUTOFF 0x0f
+#define FXOS8700_PL_STATUS 0x10
+#define FXOS8700_PL_CFG 0x11
+#define FXOS8700_PL_COUNT 0x12
+#define FXOS8700_PL_BF_ZCOMP 0x13
+#define FXOS8700_PL_P_L_THS_REG 0x14
+#define FXOS8700_FFMT_CFG 0x15
+#define FXOS8700_FFMT_SRC 0x16
+#define FXOS8700_FFMT_THS 0x17
+#define FXOS8700_FFMT_COUNT 0x18
+#define FXOS8700_TRANSIDENT1_CFG 0x1d
+#define FXOS8700_TRANSIDENT1_SRC 0x1e
+#define FXOS8700_TRANSIDENT1_THS 0x1f
+#define FXOS8700_TRANSIDENT1_COUNT 0x20
+#define FXOS8700_PULSE_CFG 0x21
+#define FXOS8700_PULSE_SRC 0x22
+#define FXOS8700_PULSE_THSX 0x23
+#define FXOS8700_PULSE_THSY 0x24
+#define FXOS8700_PULSE_THSZ 0x25
+#define FXOS8700_PULSE_TMLT 0x26
+#define FXOS8700_PULSE_LTCY 0x27
+#define FXOS8700_PULSE_WIND 0x28
+#define FXOS8700_ATSLP_COUNT 0x29
+#define FXOS8700_CTRL_REG1 0x2a
+#define FXOS8700_CTRL_REG2 0x2b
+#define FXOS8700_CTRL_REG3 0x2c
+#define FXOS8700_CTRL_REG4 0x2d
+#define FXOS8700_CTRL_REG5 0x2e
+#define FXOS8700_OFF_X 0x2f
+#define FXOS8700_OFF_Y 0x30
+#define FXOS8700_OFF_Z 0x31
+#define FXOS8700_M_DR_STATUS 0x32
+#define FXOS8700_M_OUT_X_MSB 0x33
+#define FXOS8700_M_OUT_X_LSB 0x34
+#define FXOS8700_M_OUT_Y_MSB 0x35
+#define FXOS8700_M_OUT_Y_LSB 0x36
+#define FXOS8700_M_OUT_Z_MSB 0x37
+#define FXOS8700_M_OUT_Z_LSB 0x38
+#define FXOS8700_CMP_X_MSB 0x39
+#define FXOS8700_CMP_X_LSB 0x3a
+#define FXOS8700_CMP_Y_MSB 0x3b
+#define FXOS8700_CMP_Y_LSB 0x3c
+#define FXOS8700_CMP_Z_MSB 0x3d
+#define FXOS8700_CMP_Z_LSB 0x3e
+#define FXOS8700_M_OFF_X_MSB 0x3f
+#define FXOS8700_M_OFF_X_LSB 0x40
+#define FXOS8700_M_OFF_Y_MSB 0x41
+#define FXOS8700_M_OFF_Y_LSB 0x42
+#define FXOS8700_M_OFF_Z_MSB 0x43
+#define FXOS8700_M_OFF_Z_LSB 0x44
+#define FXOS8700_MAX_X_MSB 0x45
+#define FXOS8700_MAX_X_LSB 0x46
+#define FXOS8700_MAX_Y_MSB 0x47
+#define FXOS8700_MAX_Y_LSB 0x48
+#define FXOS8700_MAX_Z_MSB 0x49
+#define FXOS8700_MAX_Z_LSB 0x4a
+#define FXOS8700_MIN_X_MSB 0x4b
+#define FXOS8700_MIN_X_LSB 0x4c
+#define FXOS8700_MIN_Y_MSB 0x4d
+#define FXOS8700_MIN_Y_LSB 0x4e
+#define FXOS8700_MIN_Z_MSB 0x4f
+#define FXOS8700_MIN_Z_LSB 0x50
+#define FXOS8700_M_TEMP 0x51
+#define FXOS8700_MAG_THS_CFG 0x52
+#define FXOS8700_MAG_THS_SRC 0x53
+#define FXOS8700_MAG_THS_THS_X1 0x54
+#define FXOS8700_MAG_THS_THS_X0 0x55
+#define FXOS8700_MAG_THS_THS_Y1 0x56
+#define FXOS8700_MAG_THS_THS_Y0 0x57
+#define FXOS8700_MAG_THS_THS_Z1 0x58
+#define FXOS8700_MAG_THS_THS_Z0 0x59
+#define FXOS8700_MAG_THS_CUNT 0x5a
+#define FXOS8700_M_CTRL_REG1 0x5b
+#define FXOS8700_M_CTRL_REG2 0x5c
+#define FXOS8700_M_CTRL_REG3 0x5d
+#define FXOS8700_M_INT_SOURCE 0x5e
+#define FXOS8700_G_VECM_CFG 0x5f
+#define FXOS8700_G_VECM_THS_MSB 0x60
+#define FXOS8700_G_VECM_THS_LSB 0x61
+#define FXOS8700_G_VECM_CNT 0x62
+#define FXOS8700_G_VECM_INITX_MSB 0x63
+#define FXOS8700_G_VECM_INITX_LSB 0x64
+#define FXOS8700_G_VECM_INITY_MSB 0x65
+#define FXOS8700_G_VECM_INITY_LSB 0x66
+#define FXOS8700_G_VECM_INITZ_MSB 0x67
+#define FXOS8700_G_VECM_INITZ_LSB 0x68
+#define FXOS8700_M_VECM_CFG 0x69
+#define FXOS8700_M_VECM_THS_MSB 0x6a
+#define FXOS8700_M_VECM_THS_LSB 0x6b
+#define FXOS8700_M_VECM_CNT 0x6d
+#define FXOS8700_M_VECM_INITX_MSB 0x6d
+#define FXOS8700_M_VECM_INITX_LSB 0x6e
+#define FXOS8700_M_VECM_INITY_MSB 0x6f
+#define FXOS8700_M_VECM_INITY_LSB 0x70
+#define FXOS8700_M_VECM_INITZ_MSB 0x71
+#define FXOS8700_M_VECM_INITZ_LSB 0x72
+#define FXOS8700_G_FFMT_THS_X1 0x73
+#define FXOS8700_G_FFMT_THS_X0 0x74
+#define FXOS8700_G_FFMT_THS_Y1 0x75
+#define FXOS8700_G_FFMT_THS_Y0 0x76
+#define FXOS8700_G_FFMT_THS_Z1 0x77
+#define FXOS8700_G_FFMT_THS_Z0 0x78
+#define FXOS8700_G_TRAN_INIT_MSB 0x79
+#define FXOS8700_G_TRAN_INIT_LSB_X 0x7a
+#define FXOS8700_G_TRAN_INIT_LSB_Y 0x7b
+#define FXOS8700_G_TRAN_INIT_LSB_Z 0x7d
+#define FXOS8700_TM_NVM_LOCK 0x7e
+#define FXOS8700_NVM_DATA0_35 0x80
+#define FXOS8700_NVM_DATA_BNK3 0xa4
+#define FXOS8700_NVM_DATA_BNK2 0xa5
+#define FXOS8700_NVM_DATA_BNK1 0xa6
+#define FXOS8700_NVM_DATA_BNK0 0xa7
+
+#define SENSOR_IOCTL_BASE 'S'
+#define SENSOR_GET_MODEL_NAME _IOR(SENSOR_IOCTL_BASE, 0, char *)
+#define SENSOR_GET_POWER_STATUS _IOR(SENSOR_IOCTL_BASE, 2, int)
+#define SENSOR_SET_POWER_STATUS _IOR(SENSOR_IOCTL_BASE, 3, int)
+#define SENSOR_GET_DELAY_TIME _IOR(SENSOR_IOCTL_BASE, 4, int)
+#define SENSOR_SET_DELAY_TIME _IOR(SENSOR_IOCTL_BASE, 5, int)
+#define SENSOR_GET_RAW_DATA _IOR(SENSOR_IOCTL_BASE, 6, short[3])
+
+#define FXOS8700_I2C_ADDR 0x1E
+#define FXOS8700_DEVICE_ID 0xC7
+#define FXOS8700_PRE_DEVICE_ID 0xC4
+#define FXOS8700_DATA_BUF_SIZE 6
+#define FXOS8700_DELAY_DEFAULT 200 /* msecs */
+#define FXOS8700_POSITION_DEFAULT 1 /* msecs */
+
+#define FXOS8700_TYPE_ACC 0x00
+#define FXOS8700_TYPE_MAG 0x01
+#define FXOS8700_STANDBY 0x00
+#define FXOS8700_ACTIVED 0x01
+
+#define ABS_STATUS ABS_WHEEL
+#define FXOS8700_DRIVER "fxos8700"
+
+#define ABSMAX_ACC_VAL 0x01FF
+#define ABSMIN_ACC_VAL -(ABSMAX_ACC_VAL)
+#define FXOS8700_POLL_INTERVAL 400
+#define FXOS8700_POLL_MAX 800
+#define FXOS8700_POLL_MIN 100
+
+enum { MODE_2G = 0, MODE_4G, MODE_8G,
+};
+
+struct fxos8700_data_axis {
+ short x;
+ short y;
+ short z;
+};
+
+struct fxos8700_data {
+ struct i2c_client *client;
+ struct input_polled_dev *input_polled;
+ struct miscdevice *acc_miscdev;
+ struct miscdevice *mag_miscdev;
+ atomic_t acc_delay;
+ atomic_t mag_delay;
+ atomic_t acc_active;
+ atomic_t acc_active_poll;
+ atomic_t mag_active_poll;
+ atomic_t mag_active;
+ atomic_t position;
+ atomic_t range;
+};
+
+static struct fxos8700_data *g_fxos8700_data;
+static int fxos8700_position_settings[8][3][3] = {
+ { { 0, -1, 0}, { 1, 0, 0}, {0, 0, 1} },
+ { {-1, 0, 0}, { 0, -1, 0}, {0, 0, 1} },
+ { { 0, 1, 0}, {-1, 0, 0}, {0, 0, 1} },
+ { { 1, 0, 0}, { 0, 1, 0}, {0, 0, 1} },
+ { { 0, -1, 0}, {-1, 0, 0}, {0, 0, -1} },
+ { {-1, 0, 0}, { 0, 1, 0}, {0, 0, -1} },
+ { { 0, 1, 0}, { 1, 0, 0}, {0, 0, -1} },
+ { { 1, 0, 0}, { 0, -1, 0}, {0, 0, -1} },
+};
+
+static int fxos8700_data_convert(struct fxos8700_data_axis *axis_data, int position)
+{
+ short rawdata[3], data[3];
+ int i, j;
+ if (position < 0 || position > 7)
+ position = 0;
+ rawdata[0] = axis_data->x;
+ rawdata[1] = axis_data->y;
+ rawdata[2] = axis_data->z;
+ for (i = 0; i < 3 ; i++) {
+ data[i] = 0;
+ for (j = 0; j < 3; j++)
+ data[i] += rawdata[j] * fxos8700_position_settings[position][i][j];
+ }
+
+ axis_data->x = data[0];
+ axis_data->y = data[1];
+ axis_data->z = data[2];
+ return 0;
+}
+
+static int fxos8700_change_mode(struct i2c_client *client, int type, int active)
+{
+ u8 data;
+ int acc_act, mag_act;
+ struct fxos8700_data *pdata = i2c_get_clientdata(client);
+
+ acc_act = atomic_read(&pdata->acc_active);
+ mag_act = atomic_read(&pdata->mag_active);
+ data = i2c_smbus_read_byte_data(client, FXOS8700_CTRL_REG1);
+ if (type == FXOS8700_TYPE_ACC)
+ acc_act = active;
+ else
+ mag_act = active;
+ if (acc_act == FXOS8700_ACTIVED || mag_act == FXOS8700_ACTIVED)
+ data |= 0x01;
+ else
+ data &= ~0x01;
+ i2c_smbus_write_byte_data(client, FXOS8700_CTRL_REG1, data);
+
+ return 0;
+}
+
+static int fxos8700_change_range(struct i2c_client *client, int range)
+{
+ int ret;
+
+ ret = i2c_smbus_write_byte_data(client, FXOS8700_XYZ_DATA_CFG, range);
+
+ return ret;
+}
+static int fxos8700_set_odr(struct i2c_client *client, int type, int delay)
+{
+ return 0;
+}
+
+static int fxos8700_device_init(struct i2c_client *client)
+{
+ int result;
+ struct device_node *np = client->dev.of_node;
+ struct fxos8700_data *pdata = i2c_get_clientdata(client);
+
+ /* set interrupt pin as open-drain */
+ if (of_get_property(np, "interrupt-open-drain", NULL)) {
+ result = i2c_smbus_write_byte_data(client, FXOS8700_CTRL_REG3, 0x01);
+ if (result < 0)
+ goto out;
+ }
+
+ /* standby mode */
+ result = i2c_smbus_write_byte_data(client, FXOS8700_CTRL_REG1, 0x00);
+ if (result < 0)
+ goto out;
+ result = i2c_smbus_write_byte_data(client, FXOS8700_M_CTRL_REG1, 0x1F);
+ if (result < 0)
+ goto out;
+ result = i2c_smbus_write_byte_data(client, FXOS8700_M_CTRL_REG2, 0x5c);
+ if (result < 0)
+ goto out;
+ result = i2c_smbus_write_byte_data(client, FXOS8700_CTRL_REG1, 0x03 << 3);
+ if (result < 0)
+ goto out;
+ result = i2c_smbus_write_byte_data(client, FXOS8700_XYZ_DATA_CFG,
+ MODE_2G);
+ if (result < 0)
+ goto out;
+
+ atomic_set(&pdata->acc_active, FXOS8700_STANDBY);
+ atomic_set(&pdata->mag_active, FXOS8700_STANDBY);
+ atomic_set(&pdata->position, FXOS8700_POSITION_DEFAULT);
+ atomic_set(&pdata->range, MODE_2G);
+ return 0;
+out:
+ dev_err(&client->dev, "Error when init fxos8700 device:(%d)", result);
+ return result;
+}
+
+static int fxos8700_device_stop(struct i2c_client *client)
+{
+ i2c_smbus_write_byte_data(client, FXOS8700_CTRL_REG1, 0x00);
+ return 0;
+}
+
+static int
+fxos8700_read_data(struct i2c_client *client, struct fxos8700_data_axis *data, int type)
+{
+ u8 tmp_data[FXOS8700_DATA_BUF_SIZE];
+ int ret;
+ u8 reg;
+
+ if (type == FXOS8700_TYPE_ACC)
+ reg = FXOS8700_OUT_X_MSB;
+ else
+ reg = FXOS8700_M_OUT_X_MSB;
+
+ ret = i2c_smbus_read_i2c_block_data(client, reg, FXOS8700_DATA_BUF_SIZE, tmp_data);
+ if (ret < FXOS8700_DATA_BUF_SIZE) {
+ dev_err(&client->dev, "i2c block read %s failed\n",
+ (type == FXOS8700_TYPE_ACC ? "acc" : "mag"));
+ return -EIO;
+ }
+ data->x = ((tmp_data[0] << 8) & 0xff00) | tmp_data[1];
+ data->y = ((tmp_data[2] << 8) & 0xff00) | tmp_data[3];
+ data->z = ((tmp_data[4] << 8) & 0xff00) | tmp_data[5];
+ return 0;
+}
+
+static long fxos8700_acc_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+ struct fxos8700_data *pdata = file->private_data;
+ void __user *argp = (void __user *)arg;
+ struct fxos8700_data_axis data;
+ long ret = 0;
+ short sdata[3];
+ int enable;
+ int delay;
+ int position;
+
+ if (!pdata) {
+ printk(KERN_ERR "fxos8700 struct datt point is NULL.");
+ return -EFAULT;
+ }
+
+ switch (cmd) {
+ case SENSOR_GET_MODEL_NAME:
+ if (copy_to_user(argp, "FXOS8700 ACC", strlen("FXOS8700 ACC") + 1)) {
+ printk(KERN_ERR "SENSOR_GET_MODEL_NAME copy_to_user failed.");
+ ret = -EFAULT;
+ }
+ break;
+ case SENSOR_GET_POWER_STATUS:
+ enable = atomic_read(&pdata->acc_active);
+ if (copy_to_user(argp, &enable, sizeof(int))) {
+ printk(KERN_ERR "SENSOR_SET_POWER_STATUS copy_to_user failed.");
+ ret = -EFAULT;
+ }
+ break;
+ case SENSOR_SET_POWER_STATUS:
+ if (copy_from_user(&enable, argp, sizeof(int))) {
+ printk(KERN_ERR "SENSOR_SET_POWER_STATUS copy_to_user failed.");
+ ret = -EFAULT;
+ }
+ if (pdata->client) {
+ ret = fxos8700_change_mode(pdata->client, FXOS8700_TYPE_ACC,
+ enable ? FXOS8700_ACTIVED : FXOS8700_STANDBY);
+ if (!ret)
+ atomic_set(&pdata->acc_active, enable);
+ }
+ break;
+ case SENSOR_GET_DELAY_TIME:
+ delay = atomic_read(&pdata->acc_delay);
+ if (copy_to_user(argp, &delay, sizeof(delay))) {
+ printk(KERN_ERR "SENSOR_GET_DELAY_TIME copy_to_user failed.");
+ return -EFAULT;
+ }
+ break;
+ case SENSOR_SET_DELAY_TIME:
+ if (copy_from_user(&delay, argp, sizeof(int))) {
+ printk(KERN_ERR "SENSOR_SET_DELAY_TIME copy_to_user failed.");
+ ret = -EFAULT;
+ }
+ if (pdata->client && delay > 0 && delay <= 500) {
+ ret = fxos8700_set_odr(pdata->client, FXOS8700_TYPE_ACC, delay);
+ if (!ret)
+ atomic_set(&pdata->acc_delay, delay);
+ }
+ break;
+ case SENSOR_GET_RAW_DATA:
+ position = atomic_read(&pdata->position);
+ ret = fxos8700_read_data(pdata->client, &data, FXOS8700_TYPE_ACC);
+ if (!ret) {
+ fxos8700_data_convert(&data, position);
+ sdata[0] = data.x;
+ sdata[1] = data.y;
+ sdata[2] = data.z;
+ if (copy_to_user(argp, sdata, sizeof(sdata))) {
+ printk(KERN_ERR "SENSOR_GET_RAW_DATA copy_to_user failed.");
+ ret = -EFAULT;
+ }
+ }
+ break;
+ default:
+ ret = -1;
+ }
+ return ret;
+}
+
+static int fxos8700_acc_open(struct inode *inode, struct file *file)
+{
+ file->private_data = g_fxos8700_data;
+ return nonseekable_open(inode, file);
+}
+
+static int fxos8700_acc_release(struct inode *inode, struct file *file)
+{
+ /* note: releasing the wdt in NOWAYOUT-mode does not stop it */
+ return 0;
+}
+
+static const struct file_operations fxos8700_acc_fops = {
+ .owner = THIS_MODULE,
+ .open = fxos8700_acc_open,
+ .release = fxos8700_acc_release,
+ .unlocked_ioctl = fxos8700_acc_ioctl,
+};
+
+/* mag char miscdevice */
+static long fxos8700_mag_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+ struct fxos8700_data *pdata = file->private_data;
+ void __user *argp = (void __user *)arg;
+ struct fxos8700_data_axis data;
+ long ret = 0;
+ short sdata[3];
+ int enable;
+ int delay;
+ int position;
+
+ if (!pdata) {
+ printk(KERN_ERR "fxos8700 struct datt point is NULL.");
+ return -EFAULT;
+ }
+
+ switch (cmd) {
+ case SENSOR_GET_MODEL_NAME:
+ if (copy_to_user(argp, "FXOS8700 MAG", strlen("FXOS8700 MAG") + 1)) {
+ printk(KERN_ERR "SENSOR_GET_MODEL_NAME copy_to_user failed.");
+ ret = -EFAULT;
+ }
+ break;
+ case SENSOR_GET_POWER_STATUS:
+ enable = atomic_read(&pdata->mag_active);
+ if (copy_to_user(argp, &enable, sizeof(int))) {
+ printk(KERN_ERR "SENSOR_SET_POWER_STATUS copy_to_user failed.");
+ ret = -EFAULT;
+ }
+ break;
+ case SENSOR_SET_POWER_STATUS:
+ if (copy_from_user(&enable, argp, sizeof(int))) {
+ printk(KERN_ERR "SENSOR_SET_POWER_STATUS copy_to_user failed.");
+ ret = -EFAULT;
+ }
+ if (pdata->client) {
+ ret = fxos8700_change_mode(pdata->client, FXOS8700_TYPE_MAG,
+ enable ? FXOS8700_ACTIVED : FXOS8700_STANDBY);
+ if (!ret)
+ atomic_set(&pdata->mag_active, enable);
+ }
+ break;
+ case SENSOR_GET_DELAY_TIME:
+ delay = atomic_read(&pdata->mag_delay);
+ if (copy_to_user(argp, &delay, sizeof(delay))) {
+ printk(KERN_ERR "SENSOR_GET_DELAY_TIME copy_to_user failed.");
+ return -EFAULT;
+ }
+ break;
+ case SENSOR_SET_DELAY_TIME:
+ if (copy_from_user(&delay, argp, sizeof(int))) {
+ printk(KERN_ERR "SENSOR_SET_DELAY_TIME copy_to_user failed.");
+ ret = -EFAULT;
+ }
+ if (pdata->client && delay > 0 && delay <= 500) {
+ ret = fxos8700_set_odr(pdata->client, FXOS8700_TYPE_MAG, delay);
+ if (!ret)
+ atomic_set(&pdata->mag_delay, delay);
+ }
+ break;
+ case SENSOR_GET_RAW_DATA:
+ position = atomic_read(&pdata->position);
+ ret = fxos8700_read_data(pdata->client, &data, FXOS8700_TYPE_MAG);
+ if (!ret) {
+ fxos8700_data_convert(&data, position);
+ sdata[0] = data.x;
+ sdata[1] = data.y;
+ sdata[2] = data.z;
+ if (copy_to_user(argp, sdata, sizeof(sdata))) {
+ printk(KERN_ERR "SENSOR_GET_RAW_DATA copy_to_user failed.");
+ ret = -EFAULT;
+ }
+ }
+ break;
+ default:
+ ret = -1;
+ }
+ return ret;
+}
+
+static int fxos8700_mag_open(struct inode *inode, struct file *file)
+{
+ file->private_data = g_fxos8700_data;
+ return nonseekable_open(inode, file);
+}
+
+static int fxos8700_mag_release(struct inode *inode, struct file *file)
+{
+ /* note: releasing the wdt in NOWAYOUT-mode does not stop it */
+ return 0;
+}
+
+static const struct file_operations fxos8700_mag_fops = {
+ .owner = THIS_MODULE,
+ .open = fxos8700_mag_open,
+ .release = fxos8700_mag_release,
+ .unlocked_ioctl = fxos8700_mag_ioctl,
+};
+
+static struct miscdevice fxos8700_acc_device = {
+ .minor = MISC_DYNAMIC_MINOR,
+ .name = "FreescaleAccelerometer",
+ .fops = &fxos8700_acc_fops,
+};
+
+static struct miscdevice fxos8700_mag_device = {
+ .minor = MISC_DYNAMIC_MINOR,
+ .name = "FreescaleMagnetometer",
+ .fops = &fxos8700_mag_fops,
+};
+
+static ssize_t fxos8700_enable_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct miscdevice *misc_dev = dev_get_drvdata(dev);
+ struct fxos8700_data *pdata = g_fxos8700_data;
+ int enable = 0;
+
+ if (pdata->acc_miscdev == misc_dev)
+ enable = atomic_read(&pdata->acc_active);
+ if (pdata->mag_miscdev == misc_dev)
+ enable = atomic_read(&pdata->mag_active);
+
+ return sprintf(buf, "%d\n", enable);
+}
+
+static ssize_t fxos8700_enable_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct miscdevice *misc_dev = dev_get_drvdata(dev);
+ struct fxos8700_data *pdata = g_fxos8700_data;
+ struct i2c_client *client = pdata->client;
+ unsigned long enable;
+ int type;
+ int ret;
+
+ if (kstrtoul(buf, 10, &enable) < 0)
+ return -EINVAL;
+
+ if (misc_dev == pdata->acc_miscdev)
+ type = FXOS8700_TYPE_ACC;
+ if (misc_dev == pdata->mag_miscdev)
+ type = FXOS8700_TYPE_MAG;
+ enable = (enable > 0 ? FXOS8700_ACTIVED : FXOS8700_STANDBY);
+ ret = fxos8700_change_mode(client, type, enable);
+ if (!ret) {
+ if (type == FXOS8700_TYPE_ACC) {
+ atomic_set(&pdata->acc_active, enable);
+ atomic_set(&pdata->acc_active_poll, enable);
+ } else {
+ atomic_set(&pdata->mag_active, enable);
+ atomic_set(&pdata->mag_active_poll, enable);
+ }
+ }
+ return count;
+}
+
+static ssize_t fxos8700_poll_delay_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct miscdevice *misc_dev = dev_get_drvdata(dev);
+ struct fxos8700_data *pdata = g_fxos8700_data;
+ int poll_delay = 0;
+
+ if (pdata->acc_miscdev == misc_dev)
+ poll_delay = atomic_read(&pdata->acc_delay);
+ if (pdata->mag_miscdev == misc_dev)
+ poll_delay = atomic_read(&pdata->mag_delay);
+
+ return sprintf(buf, "%d\n", poll_delay);
+}
+
+
+static ssize_t fxos8700_poll_delay_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct miscdevice *misc_dev = dev_get_drvdata(dev);
+ struct fxos8700_data *pdata = g_fxos8700_data;
+ struct i2c_client *client = pdata->client;
+ unsigned long delay;
+ int type;
+ int ret;
+
+ if (kstrtoul(buf, 10, &delay) < 0)
+ return -EINVAL;
+
+ if (misc_dev == pdata->acc_miscdev)
+ type = FXOS8700_TYPE_ACC;
+ if (misc_dev == pdata->mag_miscdev)
+ type = FXOS8700_TYPE_MAG;
+ ret = fxos8700_set_odr(client, type, delay);
+ if (!ret) {
+ if (type == FXOS8700_TYPE_ACC)
+ atomic_set(&pdata->acc_delay, delay);
+ else
+ atomic_set(&pdata->mag_delay, delay);
+ }
+ return count;
+}
+
+static ssize_t fxos8700_position_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct fxos8700_data *pdata = g_fxos8700_data;
+ unsigned long position = atomic_read(&pdata->position);
+
+ return sprintf(buf, "%ld\n", position);
+}
+
+static ssize_t fxos8700_position_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned long position;
+ struct fxos8700_data *pdata = g_fxos8700_data;
+
+ if (kstrtoul(buf, 10, &position) < 0)
+ return -EINVAL;
+
+ atomic_set(&pdata->position, position);
+ return count;
+}
+
+static ssize_t fxos8700_range_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct fxos8700_data *pdata = g_fxos8700_data;
+ unsigned long range = atomic_read(&pdata->range);
+
+ return sprintf(buf, "%ld\n", range);
+}
+
+static ssize_t fxos8700_range_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned long range;
+ struct fxos8700_data *pdata = g_fxos8700_data;
+ struct i2c_client *client = pdata->client;
+ int ret;
+
+ if (kstrtoul(buf, 10, &range) < 0)
+ return -EINVAL;
+
+ if (range == atomic_read(&pdata->range))
+ return count;
+
+ if (atomic_read(&pdata->acc_active) | atomic_read(&pdata->mag_active))
+ printk(KERN_INFO "Pls set the sensor standby and then actived\n");
+ ret = fxos8700_change_range(client, range);
+ if (!ret)
+ atomic_set(&pdata->range, range);
+
+ return count;
+}
+
+static DEVICE_ATTR(enable, S_IWUSR | S_IRUGO, fxos8700_enable_show, fxos8700_enable_store);
+static DEVICE_ATTR(poll_delay, S_IWUSR | S_IRUGO, fxos8700_poll_delay_show, fxos8700_poll_delay_store);
+static DEVICE_ATTR(position, S_IWUSR | S_IRUGO, fxos8700_position_show, fxos8700_position_store);
+static DEVICE_ATTR(range, S_IWUSR | S_IRUGO, fxos8700_range_show, fxos8700_range_store);
+
+static struct attribute *fxos8700_attributes[] = {
+ &dev_attr_enable.attr,
+ &dev_attr_poll_delay.attr,
+ &dev_attr_position.attr,
+ &dev_attr_range.attr,
+ NULL
+};
+
+static const struct attribute_group fxos8700_attr_group = {
+ .attrs = fxos8700_attributes,
+};
+
+static int fxos8700_register_sysfs_device(struct fxos8700_data *pdata)
+{
+ struct miscdevice *misc_dev = NULL;
+ int err = -1;
+
+ /* register sysfs for acc */
+ misc_dev = pdata->acc_miscdev;
+ err = sysfs_create_group(&misc_dev->this_device->kobj, &fxos8700_attr_group);
+ if (err)
+ goto out;
+
+ /* register sysfs for mag */
+ misc_dev = pdata->mag_miscdev;
+ err = sysfs_create_group(&misc_dev->this_device->kobj, &fxos8700_attr_group);
+ if (err)
+ goto err_register_sysfs;
+ return 0;
+err_register_sysfs:
+ misc_dev = pdata->acc_miscdev;
+ sysfs_remove_group(&misc_dev->this_device->kobj, &fxos8700_attr_group);
+ printk("reigster mag sysfs error\n");
+out:
+ printk("reigster acc sysfs error\n");
+ return err;
+}
+
+static int fxos8700_unregister_sysfs_device(struct fxos8700_data *pdata)
+{
+ struct miscdevice *misc_dev;
+ misc_dev = pdata->acc_miscdev;
+ sysfs_remove_group(&misc_dev->this_device->kobj, &fxos8700_attr_group);
+
+ misc_dev = pdata->mag_miscdev;
+ sysfs_remove_group(&misc_dev->this_device->kobj, &fxos8700_attr_group);
+ return 0;
+}
+
+static void fxos8700_report(struct input_polled_dev *dev, int type)
+{
+ struct fxos8700_data_axis data;
+ struct fxos8700_data *pdata = g_fxos8700_data;
+ struct input_dev *idev = pdata->input_polled->input;
+ int position;
+ int ret;
+
+ position = atomic_read(&pdata->position);
+ ret = fxos8700_read_data(pdata->client, &data, type);
+ if (!ret) {
+ fxos8700_data_convert(&data, position);
+ input_report_abs(idev, ABS_X, data.x);
+ input_report_abs(idev, ABS_Y, data.y);
+ input_report_abs(idev, ABS_Z, data.z);
+ input_sync(idev);
+ }
+}
+
+static void fxos8700_poll(struct input_polled_dev *dev)
+{
+ struct fxos8700_data *pdata = g_fxos8700_data;
+ int type;
+
+ if (!(atomic_read(&pdata->acc_active_poll) ||
+ atomic_read(&pdata->mag_active_poll)))
+ return;
+
+ if (atomic_read(&pdata->acc_active_poll))
+ type = FXOS8700_TYPE_ACC;
+ if (atomic_read(&pdata->mag_active_poll))
+ type =FXOS8700_TYPE_MAG;
+ fxos8700_report(dev, type);
+}
+
+static int fxo8700_register_polled_device(struct fxos8700_data *pdata)
+{
+ struct input_polled_dev *ipoll_dev;
+ struct input_dev *idev;
+ int error;
+
+ ipoll_dev = input_allocate_polled_device();
+ if (!ipoll_dev)
+ return -ENOMEM;
+
+ ipoll_dev->private = pdata;
+ ipoll_dev->poll = fxos8700_poll;
+ ipoll_dev->poll_interval = FXOS8700_POLL_INTERVAL;
+ ipoll_dev->poll_interval_min = FXOS8700_POLL_MIN;
+ ipoll_dev->poll_interval_max = FXOS8700_POLL_MAX;
+ idev = ipoll_dev->input;
+ idev->name = FXOS8700_DRIVER;
+ idev->id.bustype = BUS_I2C;
+ idev->dev.parent = &pdata->client->dev;
+
+ idev->evbit[0] = BIT_MASK(EV_ABS);
+ input_set_abs_params(idev, ABS_X, ABSMIN_ACC_VAL, ABSMAX_ACC_VAL, 0, 0);
+ input_set_abs_params(idev, ABS_Y, ABSMIN_ACC_VAL, ABSMAX_ACC_VAL, 0, 0);
+ input_set_abs_params(idev, ABS_Z, ABSMIN_ACC_VAL, ABSMAX_ACC_VAL, 0, 0);
+
+ error = input_register_polled_device(ipoll_dev);
+ if (error) {
+ input_free_polled_device(ipoll_dev);
+ return error;
+ }
+
+ pdata->input_polled = ipoll_dev;
+
+ return 0;
+}
+
+static int fxos8700_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ int result, client_id;
+ struct fxos8700_data *pdata;
+ struct i2c_adapter *adapter;
+
+ adapter = to_i2c_adapter(client->dev.parent);
+ result = i2c_check_functionality(adapter,
+ I2C_FUNC_SMBUS_BYTE |
+ I2C_FUNC_SMBUS_BYTE_DATA);
+ if (!result)
+ goto err_out;
+
+ client_id = i2c_smbus_read_byte_data(client, FXOS8700_WHO_AM_I);
+ if (client_id != FXOS8700_DEVICE_ID && client_id != FXOS8700_PRE_DEVICE_ID) {
+ dev_err(&client->dev,
+ "read chip ID 0x%x is not equal to 0x%x or 0x%x\n",
+ result, FXOS8700_DEVICE_ID, FXOS8700_PRE_DEVICE_ID);
+ result = -EINVAL;
+ goto err_out;
+ }
+ pdata = kzalloc(sizeof(struct fxos8700_data), GFP_KERNEL);
+ if (!pdata) {
+ result = -ENOMEM;
+ dev_err(&client->dev, "alloc data memory error!\n");
+ goto err_out;
+ }
+ g_fxos8700_data = pdata;
+ pdata->client = client;
+ atomic_set(&pdata->acc_delay, FXOS8700_DELAY_DEFAULT);
+ atomic_set(&pdata->mag_delay, FXOS8700_DELAY_DEFAULT);
+ i2c_set_clientdata(client, pdata);
+
+ result = misc_register(&fxos8700_acc_device);
+ if (result != 0) {
+ printk(KERN_ERR "register acc miscdevice error");
+ goto err_regsiter_acc_misc;
+ }
+ pdata->acc_miscdev = &fxos8700_acc_device;
+
+ result = misc_register(&fxos8700_mag_device);
+ if (result != 0) {
+ printk(KERN_ERR "register acc miscdevice error");
+ goto err_regsiter_mag_misc;
+ }
+ pdata->mag_miscdev = &fxos8700_mag_device;
+
+ /* for debug */
+ if (client->irq <= 0) {
+ result = fxo8700_register_polled_device(g_fxos8700_data);
+ if (result)
+ dev_err(&client->dev,
+ "IRQ GPIO conf. error %d, error %d\n",
+ client->irq, result);
+ }
+
+ result = fxos8700_register_sysfs_device(pdata);
+ if (result) {
+ dev_err(&client->dev, "create device file failed!\n");
+ result = -EINVAL;
+ goto err_register_sys;
+ }
+ fxos8700_device_init(client);
+ printk("fxos8700 device driver probe successfully");
+ return 0;
+err_register_sys:
+ misc_deregister(&fxos8700_mag_device);
+ pdata->mag_miscdev = NULL;
+err_regsiter_mag_misc:
+ misc_deregister(&fxos8700_acc_device);
+ pdata->acc_miscdev = NULL;
+err_regsiter_acc_misc:
+ i2c_set_clientdata(client, NULL);
+ kfree(pdata);
+err_out:
+ return result;
+}
+
+static int fxos8700_remove(struct i2c_client *client)
+{
+ struct fxos8700_data *pdata = i2c_get_clientdata(client);
+ if (!pdata)
+ return 0;
+ fxos8700_device_stop(client);
+ if (client->irq <= 0) {
+ input_unregister_polled_device(pdata->input_polled);
+ input_free_polled_device(pdata->input_polled);
+ }
+ fxos8700_unregister_sysfs_device(pdata);
+ misc_deregister(&fxos8700_acc_device);
+ misc_deregister(&fxos8700_mag_device);
+ kfree(pdata);
+ return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int fxos8700_suspend(struct device *dev)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct fxos8700_data *pdata = i2c_get_clientdata(client);
+ if (atomic_read(&pdata->acc_active) || atomic_read(&pdata->mag_active))
+ fxos8700_device_stop(client);
+ return 0;
+}
+
+static int fxos8700_resume(struct device *dev)
+{
+ int ret = 0;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct fxos8700_data *pdata = i2c_get_clientdata(client);
+ if (atomic_read(&pdata->acc_active))
+ fxos8700_change_mode(client, FXOS8700_TYPE_ACC, FXOS8700_ACTIVED);
+ if (atomic_read(&pdata->mag_active))
+ fxos8700_change_mode(client, FXOS8700_TYPE_MAG, FXOS8700_ACTIVED);
+ return ret;
+}
+#endif
+
+static const struct i2c_device_id fxos8700_id[] = {
+ {"fxos8700", 0},
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(i2c, fxos8700_id);
+
+static SIMPLE_DEV_PM_OPS(fxos8700_pm_ops, fxos8700_suspend, fxos8700_resume);
+static struct i2c_driver fxos8700_driver = {
+ .driver = {
+ .name = FXOS8700_DRIVER,
+ .owner = THIS_MODULE,
+ .pm = &fxos8700_pm_ops,
+ },
+ .probe = fxos8700_probe,
+ .remove = fxos8700_remove,
+ .id_table = fxos8700_id,
+};
+
+module_i2c_driver(fxos8700_driver);
+
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("FXOS8700 6-Axis Acc and Mag Combo Sensor driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/misc/sram.c b/drivers/misc/sram.c
index 8daefb81ba29..c09389b644b8 100644
--- a/drivers/misc/sram.c
+++ b/drivers/misc/sram.c
@@ -33,7 +33,7 @@
#include "sram.h"
-#define SRAM_GRANULARITY 32
+#define SRAM_GRANULARITY 4096
static ssize_t sram_read(struct file *filp, struct kobject *kobj,
struct bin_attribute *attr,
diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig
index ec21388311db..42565562577c 100644
--- a/drivers/mmc/Kconfig
+++ b/drivers/mmc/Kconfig
@@ -12,6 +12,16 @@ menuconfig MMC
If you want MMC/SD/SDIO support, you should say Y here and
also to your specific host controller driver.
+config MMC_MQ_DEFAULT
+ bool "MMC: use blk-mq I/O path by default"
+ depends on MMC && BLOCK
+ default y
+ ---help---
+ This option enables the new blk-mq based I/O path for MMC block
+ devices by default. With the option the mmc_core.use_blk_mq
+ module/boot option defaults to Y, without it to N, but it can
+ still be overridden either way.
+
if MMC
source "drivers/mmc/core/Kconfig"
diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c
index ce6dd49fbb98..344b29627818 100644
--- a/drivers/mmc/core/block.c
+++ b/drivers/mmc/core/block.c
@@ -110,6 +110,7 @@ struct mmc_blk_data {
#define MMC_BLK_WRITE BIT(1)
#define MMC_BLK_DISCARD BIT(2)
#define MMC_BLK_SECDISCARD BIT(3)
+#define MMC_BLK_CQE_RECOVERY BIT(4)
/*
* Only set in main mmc_blk_data associated
@@ -161,7 +162,7 @@ static void mmc_blk_put(struct mmc_blk_data *md)
md->usage--;
if (md->usage == 0) {
int devidx = mmc_get_devidx(md->disk);
- blk_cleanup_queue(md->queue.queue);
+ blk_put_queue(md->queue.queue);
ida_simple_remove(&mmc_blk_ida, devidx);
put_disk(md->disk);
kfree(md);
@@ -1200,6 +1201,14 @@ int mmc_access_rpmb(struct mmc_queue *mq)
return false;
}
+static void mmc_blk_end_request(struct request *req, blk_status_t error)
+{
+ if (req->mq_ctx)
+ blk_mq_end_request(req, error);
+ else
+ blk_end_request_all(req, error);
+}
+
/*
* The non-block commands come back from the block layer after it queued it and
* processed it with all other requests and then they get issued in this
@@ -1259,7 +1268,7 @@ static void mmc_blk_issue_drv_op(struct mmc_queue *mq, struct request *req)
break;
}
mq_rq->drv_op_result = ret;
- blk_end_request_all(req, ret ? BLK_STS_IOERR : BLK_STS_OK);
+ mmc_blk_end_request(req, ret ? BLK_STS_IOERR : BLK_STS_OK);
}
static void mmc_blk_issue_discard_rq(struct mmc_queue *mq, struct request *req)
@@ -1302,7 +1311,7 @@ static void mmc_blk_issue_discard_rq(struct mmc_queue *mq, struct request *req)
else
mmc_blk_reset_success(md, type);
fail:
- blk_end_request(req, status, blk_rq_bytes(req));
+ mmc_blk_end_request(req, status);
}
static void mmc_blk_issue_secdiscard_rq(struct mmc_queue *mq,
@@ -1372,7 +1381,7 @@ out_retry:
if (!err)
mmc_blk_reset_success(md, type);
out:
- blk_end_request(req, status, blk_rq_bytes(req));
+ mmc_blk_end_request(req, status);
}
static void mmc_blk_issue_flush(struct mmc_queue *mq, struct request *req)
@@ -1382,7 +1391,7 @@ static void mmc_blk_issue_flush(struct mmc_queue *mq, struct request *req)
int ret = 0;
ret = mmc_flush_cache(card);
- blk_end_request_all(req, ret ? BLK_STS_IOERR : BLK_STS_OK);
+ mmc_blk_end_request(req, ret ? BLK_STS_IOERR : BLK_STS_OK);
}
/*
@@ -1459,11 +1468,9 @@ static void mmc_blk_eval_resp_error(struct mmc_blk_request *brq)
}
}
-static enum mmc_blk_status mmc_blk_err_check(struct mmc_card *card,
- struct mmc_async_req *areq)
+static enum mmc_blk_status __mmc_blk_err_check(struct mmc_card *card,
+ struct mmc_queue_req *mq_mrq)
{
- struct mmc_queue_req *mq_mrq = container_of(areq, struct mmc_queue_req,
- areq);
struct mmc_blk_request *brq = &mq_mrq->brq;
struct request *req = mmc_queue_req_to_req(mq_mrq);
int need_retune = card->host->need_retune;
@@ -1569,26 +1576,37 @@ static enum mmc_blk_status mmc_blk_err_check(struct mmc_card *card,
return MMC_BLK_SUCCESS;
}
+static enum mmc_blk_status mmc_blk_err_check(struct mmc_card *card,
+ struct mmc_async_req *areq)
+{
+ struct mmc_queue_req *mq_mrq = container_of(areq, struct mmc_queue_req,
+ areq);
+
+ return __mmc_blk_err_check(card, mq_mrq);
+}
+
static void mmc_blk_data_prep(struct mmc_queue *mq, struct mmc_queue_req *mqrq,
- int disable_multi, bool *do_rel_wr,
- bool *do_data_tag)
+ int disable_multi, bool *do_rel_wr_p,
+ bool *do_data_tag_p)
{
struct mmc_blk_data *md = mq->blkdata;
struct mmc_card *card = md->queue.card;
struct mmc_blk_request *brq = &mqrq->brq;
struct request *req = mmc_queue_req_to_req(mqrq);
+ bool do_rel_wr, do_data_tag;
/*
* Reliable writes are used to implement Forced Unit Access and
* are supported only on MMCs.
*/
- *do_rel_wr = (req->cmd_flags & REQ_FUA) &&
- rq_data_dir(req) == WRITE &&
- (md->flags & MMC_BLK_REL_WR);
+ do_rel_wr = (req->cmd_flags & REQ_FUA) &&
+ rq_data_dir(req) == WRITE &&
+ (md->flags & MMC_BLK_REL_WR);
memset(brq, 0, sizeof(struct mmc_blk_request));
brq->mrq.data = &brq->data;
+ brq->mrq.tag = req->tag;
brq->stop.opcode = MMC_STOP_TRANSMISSION;
brq->stop.arg = 0;
@@ -1603,6 +1621,14 @@ static void mmc_blk_data_prep(struct mmc_queue *mq, struct mmc_queue_req *mqrq,
brq->data.blksz = 512;
brq->data.blocks = blk_rq_sectors(req);
+ brq->data.blk_addr = blk_rq_pos(req);
+
+ /*
+ * The command queue supports 2 priorities: "high" (1) and "simple" (0).
+ * The eMMC will give "high" priority tasks priority over "simple"
+ * priority tasks. Here we always set "simple" priority by not setting
+ * MMC_DATA_PRIO.
+ */
/*
* The block layer doesn't support all sector count
@@ -1642,18 +1668,23 @@ static void mmc_blk_data_prep(struct mmc_queue *mq, struct mmc_queue_req *mqrq,
brq->data.blocks);
}
- if (*do_rel_wr)
+ if (do_rel_wr) {
mmc_apply_rel_rw(brq, card, req);
+ brq->data.flags |= MMC_DATA_REL_WR;
+ }
/*
* Data tag is used only during writing meta data to speed
* up write and any subsequent read of this meta data
*/
- *do_data_tag = card->ext_csd.data_tag_unit_size &&
- (req->cmd_flags & REQ_META) &&
- (rq_data_dir(req) == WRITE) &&
- ((brq->data.blocks * brq->data.blksz) >=
- card->ext_csd.data_tag_unit_size);
+ do_data_tag = card->ext_csd.data_tag_unit_size &&
+ (req->cmd_flags & REQ_META) &&
+ (rq_data_dir(req) == WRITE) &&
+ ((brq->data.blocks * brq->data.blksz) >=
+ card->ext_csd.data_tag_unit_size);
+
+ if (do_data_tag)
+ brq->data.flags |= MMC_DATA_DAT_TAG;
mmc_set_data_timeout(&brq->data, card);
@@ -1680,6 +1711,144 @@ static void mmc_blk_data_prep(struct mmc_queue *mq, struct mmc_queue_req *mqrq,
}
mqrq->areq.mrq = &brq->mrq;
+
+ if (do_rel_wr_p)
+ *do_rel_wr_p = do_rel_wr;
+
+ if (do_data_tag_p)
+ *do_data_tag_p = do_data_tag;
+}
+
+#define MMC_CQE_RETRIES 2
+
+static void mmc_blk_cqe_complete_rq(struct mmc_queue *mq, struct request *req)
+{
+ struct mmc_queue_req *mqrq = req_to_mmc_queue_req(req);
+ struct mmc_request *mrq = &mqrq->brq.mrq;
+ struct request_queue *q = req->q;
+ struct mmc_host *host = mq->card->host;
+ unsigned long flags;
+ bool put_card;
+ int err;
+
+ mmc_cqe_post_req(host, mrq);
+
+ if (mrq->cmd && mrq->cmd->error)
+ err = mrq->cmd->error;
+ else if (mrq->data && mrq->data->error)
+ err = mrq->data->error;
+ else
+ err = 0;
+
+ if (err) {
+ if (mqrq->retries++ < MMC_CQE_RETRIES)
+ blk_mq_requeue_request(req, true);
+ else
+ blk_mq_end_request(req, BLK_STS_IOERR);
+ } else if (mrq->data) {
+ if (blk_update_request(req, BLK_STS_OK, mrq->data->bytes_xfered))
+ blk_mq_requeue_request(req, true);
+ else
+ __blk_mq_end_request(req, BLK_STS_OK);
+ } else {
+ blk_mq_end_request(req, BLK_STS_OK);
+ }
+
+ spin_lock_irqsave(q->queue_lock, flags);
+
+ mq->in_flight[mmc_issue_type(mq, req)] -= 1;
+
+ put_card = (mmc_tot_in_flight(mq) == 0);
+
+ mmc_cqe_check_busy(mq);
+
+ spin_unlock_irqrestore(q->queue_lock, flags);
+
+ if (!mq->cqe_busy)
+ blk_mq_run_hw_queues(q, true);
+
+ if (put_card)
+ mmc_put_card(mq->card, &mq->ctx);
+}
+
+void mmc_blk_cqe_recovery(struct mmc_queue *mq)
+{
+ struct mmc_card *card = mq->card;
+ struct mmc_host *host = card->host;
+ int err;
+
+ pr_debug("%s: CQE recovery start\n", mmc_hostname(host));
+
+ err = mmc_cqe_recovery(host);
+ if (err)
+ mmc_blk_reset(mq->blkdata, host, MMC_BLK_CQE_RECOVERY);
+ else
+ mmc_blk_reset_success(mq->blkdata, MMC_BLK_CQE_RECOVERY);
+
+ pr_debug("%s: CQE recovery done\n", mmc_hostname(host));
+}
+
+static void mmc_blk_cqe_req_done(struct mmc_request *mrq)
+{
+ struct mmc_queue_req *mqrq = container_of(mrq, struct mmc_queue_req,
+ brq.mrq);
+ struct request *req = mmc_queue_req_to_req(mqrq);
+ struct request_queue *q = req->q;
+ struct mmc_queue *mq = q->queuedata;
+
+ /*
+ * Block layer timeouts race with completions which means the normal
+ * completion path cannot be used during recovery.
+ */
+ if (mq->in_recovery)
+ mmc_blk_cqe_complete_rq(mq, req);
+ else
+ blk_mq_complete_request(req);
+}
+
+static int mmc_blk_cqe_start_req(struct mmc_host *host, struct mmc_request *mrq)
+{
+ mrq->done = mmc_blk_cqe_req_done;
+ mrq->recovery_notifier = mmc_cqe_recovery_notifier;
+
+ return mmc_cqe_start_req(host, mrq);
+}
+
+static struct mmc_request *mmc_blk_cqe_prep_dcmd(struct mmc_queue_req *mqrq,
+ struct request *req)
+{
+ struct mmc_blk_request *brq = &mqrq->brq;
+
+ memset(brq, 0, sizeof(*brq));
+
+ brq->mrq.cmd = &brq->cmd;
+ brq->mrq.tag = req->tag;
+
+ return &brq->mrq;
+}
+
+static int mmc_blk_cqe_issue_flush(struct mmc_queue *mq, struct request *req)
+{
+ struct mmc_queue_req *mqrq = req_to_mmc_queue_req(req);
+ struct mmc_request *mrq = mmc_blk_cqe_prep_dcmd(mqrq, req);
+
+ mrq->cmd->opcode = MMC_SWITCH;
+ mrq->cmd->arg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) |
+ (EXT_CSD_FLUSH_CACHE << 16) |
+ (1 << 8) |
+ EXT_CSD_CMD_SET_NORMAL;
+ mrq->cmd->flags = MMC_CMD_AC | MMC_RSP_R1B;
+
+ return mmc_blk_cqe_start_req(mq->card->host, mrq);
+}
+
+static int mmc_blk_cqe_issue_rw_rq(struct mmc_queue *mq, struct request *req)
+{
+ struct mmc_queue_req *mqrq = req_to_mmc_queue_req(req);
+
+ mmc_blk_data_prep(mq, mqrq, 0, NULL, NULL);
+
+ return mmc_blk_cqe_start_req(mq->card->host, &mqrq->brq.mrq);
}
static void mmc_blk_rw_rq_prep(struct mmc_queue_req *mqrq,
@@ -1750,6 +1919,490 @@ static void mmc_blk_rw_rq_prep(struct mmc_queue_req *mqrq,
mqrq->areq.err_check = mmc_blk_err_check;
}
+#define MMC_MAX_RETRIES 5
+#define MMC_NO_RETRIES (MMC_MAX_RETRIES + 1)
+
+#define MMC_READ_SINGLE_RETRIES 2
+
+/* Single sector read during recovery */
+static void mmc_blk_read_single(struct mmc_queue *mq, struct request *req)
+{
+ struct mmc_queue_req *mqrq = req_to_mmc_queue_req(req);
+ struct mmc_request *mrq = &mqrq->brq.mrq;
+ struct mmc_card *card = mq->card;
+ struct mmc_host *host = card->host;
+ blk_status_t error = BLK_STS_OK;
+ int retries = 0;
+
+ do {
+ u32 status;
+ int err;
+
+ mmc_blk_rw_rq_prep(mqrq, card, 1, mq);
+
+ mmc_wait_for_req(host, mrq);
+
+ err = mmc_send_status(card, &status);
+ if (err)
+ goto error_exit;
+
+ if (!mmc_host_is_spi(host) &&
+ R1_CURRENT_STATE(status) != R1_STATE_TRAN) {
+ u32 stop_status = 0;
+ bool gen_err = false;
+
+ err = send_stop(card,
+ DIV_ROUND_UP(mrq->data->timeout_ns,
+ 1000000),
+ req, &gen_err, &stop_status);
+ if (err)
+ goto error_exit;
+ }
+
+ if (mrq->cmd->error && retries++ < MMC_READ_SINGLE_RETRIES)
+ continue;
+
+ retries = 0;
+
+ if (mrq->cmd->error ||
+ mrq->data->error ||
+ (!mmc_host_is_spi(host) &&
+ (mrq->cmd->resp[0] & CMD_ERRORS || status & CMD_ERRORS)))
+ error = BLK_STS_IOERR;
+ else
+ error = BLK_STS_OK;
+
+ } while (blk_update_request(req, error, 512));
+
+ return;
+
+error_exit:
+ mrq->data->bytes_xfered = 0;
+ blk_update_request(req, BLK_STS_IOERR, 512);
+ /* Let it try the remaining request again */
+ if (mqrq->retries > MMC_MAX_RETRIES - 1)
+ mqrq->retries = MMC_MAX_RETRIES - 1;
+}
+
+static void mmc_blk_mq_rw_recovery(struct mmc_queue *mq, struct request *req)
+{
+ int type = rq_data_dir(req) == READ ? MMC_BLK_READ : MMC_BLK_WRITE;
+ struct mmc_queue_req *mqrq = req_to_mmc_queue_req(req);
+ struct mmc_blk_request *brq = &mqrq->brq;
+ struct mmc_blk_data *md = mq->blkdata;
+ struct mmc_card *card = mq->card;
+ static enum mmc_blk_status status;
+
+ brq->retune_retry_done = mqrq->retries;
+
+ status = __mmc_blk_err_check(card, mqrq);
+
+ mmc_retune_release(card->host);
+
+ /*
+ * Requests are completed by mmc_blk_mq_complete_rq() which sets simple
+ * policy:
+ * 1. A request that has transferred at least some data is considered
+ * successful and will be requeued if there is remaining data to
+ * transfer.
+ * 2. Otherwise the number of retries is incremented and the request
+ * will be requeued if there are remaining retries.
+ * 3. Otherwise the request will be errored out.
+ * That means mmc_blk_mq_complete_rq() is controlled by bytes_xfered and
+ * mqrq->retries. So there are only 4 possible actions here:
+ * 1. do not accept the bytes_xfered value i.e. set it to zero
+ * 2. change mqrq->retries to determine the number of retries
+ * 3. try to reset the card
+ * 4. read one sector at a time
+ */
+ switch (status) {
+ case MMC_BLK_SUCCESS:
+ case MMC_BLK_PARTIAL:
+ /* Reset success, and accept bytes_xfered */
+ mmc_blk_reset_success(md, type);
+ break;
+ case MMC_BLK_CMD_ERR:
+ /*
+ * For SD cards, get bytes written, but do not accept
+ * bytes_xfered if that fails. For MMC cards accept
+ * bytes_xfered. Then try to reset. If reset fails then
+ * error out the remaining request, otherwise retry
+ * once (N.B mmc_blk_reset() will not succeed twice in a
+ * row).
+ */
+ if (mmc_card_sd(card)) {
+ u32 blocks;
+ int err;
+
+ err = mmc_sd_num_wr_blocks(card, &blocks);
+ if (err)
+ brq->data.bytes_xfered = 0;
+ else
+ brq->data.bytes_xfered = blocks << 9;
+ }
+ if (mmc_blk_reset(md, card->host, type))
+ mqrq->retries = MMC_NO_RETRIES;
+ else
+ mqrq->retries = MMC_MAX_RETRIES - 1;
+ break;
+ case MMC_BLK_RETRY:
+ /*
+ * Do not accept bytes_xfered, but retry up to 5 times,
+ * otherwise same as abort.
+ */
+ brq->data.bytes_xfered = 0;
+ if (mqrq->retries < MMC_MAX_RETRIES)
+ break;
+ /* Fall through */
+ case MMC_BLK_ABORT:
+ /*
+ * Do not accept bytes_xfered, but try to reset. If
+ * reset succeeds, try once more, otherwise error out
+ * the request.
+ */
+ brq->data.bytes_xfered = 0;
+ if (mmc_blk_reset(md, card->host, type))
+ mqrq->retries = MMC_NO_RETRIES;
+ else
+ mqrq->retries = MMC_MAX_RETRIES - 1;
+ break;
+ case MMC_BLK_DATA_ERR: {
+ int err;
+
+ /*
+ * Do not accept bytes_xfered, but try to reset. If
+ * reset succeeds, try once more. If reset fails with
+ * ENODEV which means the partition is wrong, then error
+ * out the request. Otherwise attempt to read one sector
+ * at a time.
+ */
+ brq->data.bytes_xfered = 0;
+ err = mmc_blk_reset(md, card->host, type);
+ if (!err) {
+ mqrq->retries = MMC_MAX_RETRIES - 1;
+ break;
+ }
+ if (err == -ENODEV) {
+ mqrq->retries = MMC_NO_RETRIES;
+ break;
+ }
+ /* Fall through */
+ }
+ case MMC_BLK_ECC_ERR:
+ /*
+ * Do not accept bytes_xfered. If reading more than one
+ * sector, try reading one sector at a time.
+ */
+ brq->data.bytes_xfered = 0;
+ /* FIXME: Missing single sector read for large sector size */
+ if (brq->data.blocks > 1 && !mmc_large_sector(card)) {
+ /* Redo read one sector at a time */
+ pr_warn("%s: retrying using single block read\n",
+ req->rq_disk->disk_name);
+ mmc_blk_read_single(mq, req);
+ } else {
+ mqrq->retries = MMC_NO_RETRIES;
+ }
+ break;
+ case MMC_BLK_NOMEDIUM:
+ /* Do not accept bytes_xfered. Error out the request */
+ brq->data.bytes_xfered = 0;
+ mqrq->retries = MMC_NO_RETRIES;
+ break;
+ default:
+ /* Do not accept bytes_xfered. Error out the request */
+ brq->data.bytes_xfered = 0;
+ mqrq->retries = MMC_NO_RETRIES;
+ pr_err("%s: Unhandled return value (%d)",
+ req->rq_disk->disk_name, status);
+ break;
+ }
+}
+
+static void mmc_blk_mq_complete_rq(struct mmc_queue *mq, struct request *req)
+{
+ struct mmc_queue_req *mqrq = req_to_mmc_queue_req(req);
+ unsigned int nr_bytes = mqrq->brq.data.bytes_xfered;
+
+ if (nr_bytes) {
+ if (blk_update_request(req, BLK_STS_OK, nr_bytes))
+ blk_mq_requeue_request(req, true);
+ else
+ __blk_mq_end_request(req, BLK_STS_OK);
+ } else if (!blk_rq_bytes(req)) {
+ __blk_mq_end_request(req, BLK_STS_IOERR);
+ } else if (mqrq->retries++ < MMC_MAX_RETRIES) {
+ blk_mq_requeue_request(req, true);
+ } else {
+ if (mmc_card_removed(mq->card))
+ req->rq_flags |= RQF_QUIET;
+ blk_mq_end_request(req, BLK_STS_IOERR);
+ }
+}
+
+static bool mmc_blk_urgent_bkops_needed(struct mmc_queue *mq,
+ struct mmc_queue_req *mqrq)
+{
+ return mmc_card_mmc(mq->card) && !mmc_host_is_spi(mq->card->host) &&
+ (mqrq->brq.cmd.resp[0] & R1_EXCEPTION_EVENT ||
+ mqrq->brq.stop.resp[0] & R1_EXCEPTION_EVENT);
+}
+
+static void mmc_blk_urgent_bkops(struct mmc_queue *mq,
+ struct mmc_queue_req *mqrq)
+{
+ if (mmc_blk_urgent_bkops_needed(mq, mqrq))
+ mmc_start_bkops(mq->card, true);
+}
+
+void mmc_blk_mq_complete(struct request *req)
+{
+ struct mmc_queue *mq = req->q->queuedata;
+
+ if (mq->use_cqe)
+ mmc_blk_cqe_complete_rq(mq, req);
+ else
+ mmc_blk_mq_complete_rq(mq, req);
+}
+
+static void mmc_blk_mq_poll_completion(struct mmc_queue *mq,
+ struct request *req)
+{
+ struct mmc_queue_req *mqrq = req_to_mmc_queue_req(req);
+
+ mmc_blk_mq_rw_recovery(mq, req);
+
+ mmc_blk_urgent_bkops(mq, mqrq);
+}
+
+static void mmc_blk_mq_dec_in_flight(struct mmc_queue *mq, struct request *req)
+{
+ struct request_queue *q = req->q;
+ unsigned long flags;
+ bool put_card;
+
+ spin_lock_irqsave(q->queue_lock, flags);
+
+ mq->in_flight[mmc_issue_type(mq, req)] -= 1;
+
+ put_card = (mmc_tot_in_flight(mq) == 0);
+
+ spin_unlock_irqrestore(q->queue_lock, flags);
+
+ if (put_card)
+ mmc_put_card(mq->card, &mq->ctx);
+}
+
+static void mmc_blk_mq_post_req(struct mmc_queue *mq, struct request *req)
+{
+ struct mmc_queue_req *mqrq = req_to_mmc_queue_req(req);
+ struct mmc_request *mrq = &mqrq->brq.mrq;
+ struct mmc_host *host = mq->card->host;
+
+ mmc_post_req(host, mrq, 0);
+
+ blk_mq_complete_request(req);
+
+ mmc_blk_mq_dec_in_flight(mq, req);
+}
+
+static void mmc_blk_mq_complete_prev_req(struct mmc_queue *mq,
+ struct request **prev_req)
+{
+ mutex_lock(&mq->complete_lock);
+
+ if (!mq->complete_req)
+ goto out_unlock;
+
+ mmc_blk_mq_poll_completion(mq, mq->complete_req);
+
+ if (prev_req)
+ *prev_req = mq->complete_req;
+ else
+ mmc_blk_mq_post_req(mq, mq->complete_req);
+
+ mq->complete_req = NULL;
+
+out_unlock:
+ mutex_unlock(&mq->complete_lock);
+}
+
+void mmc_blk_mq_complete_work(struct work_struct *work)
+{
+ struct mmc_queue *mq = container_of(work, struct mmc_queue,
+ complete_work);
+
+ mmc_blk_mq_complete_prev_req(mq, NULL);
+}
+
+static void mmc_blk_mq_req_done(struct mmc_request *mrq)
+{
+ struct mmc_queue_req *mqrq = container_of(mrq, struct mmc_queue_req,
+ brq.mrq);
+ struct request *req = mmc_queue_req_to_req(mqrq);
+ struct request_queue *q = req->q;
+ struct mmc_queue *mq = q->queuedata;
+ unsigned long flags;
+ bool waiting;
+
+ /*
+ * We cannot complete the request in this context, so record that there
+ * is a request to complete, and that a following request does not need
+ * to wait (although it does need to complete complete_req first).
+ */
+ spin_lock_irqsave(q->queue_lock, flags);
+ mq->complete_req = req;
+ mq->rw_wait = false;
+ waiting = mq->waiting;
+ spin_unlock_irqrestore(q->queue_lock, flags);
+
+ /*
+ * If 'waiting' then the waiting task will complete this request,
+ * otherwise queue a work to do it. Note that complete_work may still
+ * race with the dispatch of a following request.
+ */
+ if (waiting)
+ wake_up(&mq->wait);
+ else
+ kblockd_schedule_work(&mq->complete_work);
+}
+
+static bool mmc_blk_rw_wait_cond(struct mmc_queue *mq, int *err)
+{
+ struct request_queue *q = mq->queue;
+ unsigned long flags;
+ bool done;
+
+ /*
+ * Wait while there is another request in progress. Also indicate that
+ * there is a request waiting to start.
+ */
+ spin_lock_irqsave(q->queue_lock, flags);
+ done = !mq->rw_wait;
+ mq->waiting = !done;
+ spin_unlock_irqrestore(q->queue_lock, flags);
+
+ return done;
+}
+
+static int mmc_blk_rw_wait(struct mmc_queue *mq, struct request **prev_req)
+{
+ int err = 0;
+
+ wait_event(mq->wait, mmc_blk_rw_wait_cond(mq, &err));
+
+ /* Always complete the previous request if there is one */
+ mmc_blk_mq_complete_prev_req(mq, prev_req);
+
+ return err;
+}
+
+static int mmc_blk_mq_issue_rw_rq(struct mmc_queue *mq,
+ struct request *req)
+{
+ struct mmc_queue_req *mqrq = req_to_mmc_queue_req(req);
+ struct mmc_host *host = mq->card->host;
+ struct request *prev_req = NULL;
+ int err = 0;
+
+ mmc_blk_rw_rq_prep(mqrq, mq->card, 0, mq);
+
+ mqrq->brq.mrq.done = mmc_blk_mq_req_done;
+
+ mmc_pre_req(host, &mqrq->brq.mrq);
+
+ err = mmc_blk_rw_wait(mq, &prev_req);
+ if (err)
+ goto out_post_req;
+
+ mq->rw_wait = true;
+
+ err = mmc_start_request(host, &mqrq->brq.mrq);
+
+ if (prev_req)
+ mmc_blk_mq_post_req(mq, prev_req);
+
+ if (err) {
+ mq->rw_wait = false;
+ mmc_retune_release(host);
+ }
+
+out_post_req:
+ if (err)
+ mmc_post_req(host, &mqrq->brq.mrq, err);
+
+ return err;
+}
+
+static int mmc_blk_wait_for_idle(struct mmc_queue *mq, struct mmc_host *host)
+{
+ if (mq->use_cqe)
+ return host->cqe_ops->cqe_wait_for_idle(host);
+
+ return mmc_blk_rw_wait(mq, NULL);
+}
+
+enum mmc_issued mmc_blk_mq_issue_rq(struct mmc_queue *mq, struct request *req)
+{
+ struct mmc_blk_data *md = mq->blkdata;
+ struct mmc_card *card = md->queue.card;
+ struct mmc_host *host = card->host;
+ int ret;
+
+ ret = mmc_blk_part_switch(card, md->part_type);
+ if (ret)
+ return MMC_REQ_FAILED_TO_START;
+
+ switch (mmc_issue_type(mq, req)) {
+ case MMC_ISSUE_SYNC:
+ ret = mmc_blk_wait_for_idle(mq, host);
+ if (ret)
+ return MMC_REQ_BUSY;
+ switch (req_op(req)) {
+ case REQ_OP_DRV_IN:
+ case REQ_OP_DRV_OUT:
+ mmc_blk_issue_drv_op(mq, req);
+ break;
+ case REQ_OP_DISCARD:
+ mmc_blk_issue_discard_rq(mq, req);
+ break;
+ case REQ_OP_SECURE_ERASE:
+ mmc_blk_issue_secdiscard_rq(mq, req);
+ break;
+ case REQ_OP_FLUSH:
+ mmc_blk_issue_flush(mq, req);
+ break;
+ default:
+ WARN_ON_ONCE(1);
+ return MMC_REQ_FAILED_TO_START;
+ }
+ return MMC_REQ_FINISHED;
+ case MMC_ISSUE_DCMD:
+ case MMC_ISSUE_ASYNC:
+ switch (req_op(req)) {
+ case REQ_OP_FLUSH:
+ ret = mmc_blk_cqe_issue_flush(mq, req);
+ break;
+ case REQ_OP_READ:
+ case REQ_OP_WRITE:
+ if (mq->use_cqe)
+ ret = mmc_blk_cqe_issue_rw_rq(mq, req);
+ else
+ ret = mmc_blk_mq_issue_rw_rq(mq, req);
+ break;
+ default:
+ WARN_ON_ONCE(1);
+ ret = -EINVAL;
+ }
+ if (!ret)
+ return MMC_REQ_STARTED;
+ return ret == -EBUSY ? MMC_REQ_BUSY : MMC_REQ_FAILED_TO_START;
+ default:
+ WARN_ON_ONCE(1);
+ return MMC_REQ_FAILED_TO_START;
+ }
+}
+
static bool mmc_blk_rw_cmd_err(struct mmc_blk_data *md, struct mmc_card *card,
struct mmc_blk_request *brq, struct request *req,
bool old_req_pending)
@@ -1994,7 +2647,7 @@ void mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req)
if (req && !mq->qcnt)
/* claim host only for the first request */
- mmc_get_card(card);
+ mmc_get_card(card, NULL);
ret = mmc_blk_part_switch(card, md->part_type);
if (ret) {
@@ -2057,7 +2710,7 @@ void mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req)
out:
if (!mq->qcnt)
- mmc_put_card(card);
+ mmc_put_card(card, NULL);
}
static inline int mmc_blk_readonly(struct mmc_card *card)
@@ -2122,6 +2775,17 @@ static struct mmc_blk_data *mmc_blk_alloc_req(struct mmc_card *card,
md->queue.blkdata = md;
+ /*
+ * Keep an extra reference to the queue so that we can shutdown the
+ * queue (i.e. call blk_cleanup_queue()) while there are still
+ * references to the 'md'. The corresponding blk_put_queue() is in
+ * mmc_blk_put().
+ */
+ if (!blk_get_queue(md->queue.queue)) {
+ mmc_cleanup_queue(&md->queue);
+ goto err_putdisk;
+ }
+
md->disk->major = MMC_BLOCK_MAJOR;
md->disk->first_minor = devidx * perdev_minors;
md->disk->fops = &mmc_bdops;
diff --git a/drivers/mmc/core/block.h b/drivers/mmc/core/block.h
index 5946636101ef..f472ce5d5647 100644
--- a/drivers/mmc/core/block.h
+++ b/drivers/mmc/core/block.h
@@ -7,4 +7,15 @@ struct request;
void mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req);
+void mmc_blk_cqe_recovery(struct mmc_queue *mq);
+
+enum mmc_issued;
+
+enum mmc_issued mmc_blk_mq_issue_rq(struct mmc_queue *mq, struct request *req);
+void mmc_blk_mq_complete(struct request *req);
+
+struct work_struct;
+
+void mmc_blk_mq_complete_work(struct work_struct *work);
+
#endif
diff --git a/drivers/mmc/core/bus.c b/drivers/mmc/core/bus.c
index 7f428e387de3..7586ff2ad1f1 100644
--- a/drivers/mmc/core/bus.c
+++ b/drivers/mmc/core/bus.c
@@ -372,10 +372,17 @@ int mmc_add_card(struct mmc_card *card)
*/
void mmc_remove_card(struct mmc_card *card)
{
+ struct mmc_host *host = card->host;
+
#ifdef CONFIG_DEBUG_FS
mmc_remove_card_debugfs(card);
#endif
+ if (host->cqe_enabled) {
+ host->cqe_ops->cqe_disable(host);
+ host->cqe_enabled = false;
+ }
+
if (mmc_card_present(card)) {
if (mmc_host_is_spi(card->host)) {
pr_info("%s: SPI card removed\n",
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index 29bfff2ed4d3..905211e86f95 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -58,6 +58,8 @@
static const unsigned freqs[] = { 400000, 300000, 200000, 100000 };
+static int __mmc_max_reserved_idx = -1;
+
/*
* Enabling software CRCs on the data blocks can be a significant (30%)
* performance cost, and for other reasons may not always be desired.
@@ -66,6 +68,13 @@ static const unsigned freqs[] = { 400000, 300000, 200000, 100000 };
bool use_spi_crc = 1;
module_param(use_spi_crc, bool, 0);
+#ifdef CONFIG_MMC_MQ_DEFAULT
+bool mmc_use_blk_mq = true;
+#else
+bool mmc_use_blk_mq = false;
+#endif
+module_param_named(use_blk_mq, mmc_use_blk_mq, bool, S_IWUSR | S_IRUGO);
+
static int mmc_schedule_delayed_work(struct delayed_work *work,
unsigned long delay)
{
@@ -266,7 +275,8 @@ static void __mmc_start_request(struct mmc_host *host, struct mmc_request *mrq)
host->ops->request(host, mrq);
}
-static void mmc_mrq_pr_debug(struct mmc_host *host, struct mmc_request *mrq)
+static void mmc_mrq_pr_debug(struct mmc_host *host, struct mmc_request *mrq,
+ bool cqe)
{
if (mrq->sbc) {
pr_debug("<%s: starting CMD%u arg %08x flags %08x>\n",
@@ -275,9 +285,12 @@ static void mmc_mrq_pr_debug(struct mmc_host *host, struct mmc_request *mrq)
}
if (mrq->cmd) {
- pr_debug("%s: starting CMD%u arg %08x flags %08x\n",
- mmc_hostname(host), mrq->cmd->opcode, mrq->cmd->arg,
- mrq->cmd->flags);
+ pr_debug("%s: starting %sCMD%u arg %08x flags %08x\n",
+ mmc_hostname(host), cqe ? "CQE direct " : "",
+ mrq->cmd->opcode, mrq->cmd->arg, mrq->cmd->flags);
+ } else if (cqe) {
+ pr_debug("%s: starting CQE transfer for tag %d blkaddr %u\n",
+ mmc_hostname(host), mrq->tag, mrq->data->blk_addr);
}
if (mrq->data) {
@@ -333,7 +346,7 @@ static int mmc_mrq_prep(struct mmc_host *host, struct mmc_request *mrq)
return 0;
}
-static int mmc_start_request(struct mmc_host *host, struct mmc_request *mrq)
+int mmc_start_request(struct mmc_host *host, struct mmc_request *mrq)
{
int err;
@@ -342,7 +355,7 @@ static int mmc_start_request(struct mmc_host *host, struct mmc_request *mrq)
if (mmc_card_removed(host->card))
return -ENOMEDIUM;
- mmc_mrq_pr_debug(host, mrq);
+ mmc_mrq_pr_debug(host, mrq, false);
WARN_ON(!host->claimed);
@@ -355,6 +368,7 @@ static int mmc_start_request(struct mmc_host *host, struct mmc_request *mrq)
return 0;
}
+EXPORT_SYMBOL(mmc_start_request);
/*
* mmc_wait_data_done() - done callback for data request
@@ -482,6 +496,155 @@ void mmc_wait_for_req_done(struct mmc_host *host, struct mmc_request *mrq)
}
EXPORT_SYMBOL(mmc_wait_for_req_done);
+/*
+ * mmc_cqe_start_req - Start a CQE request.
+ * @host: MMC host to start the request
+ * @mrq: request to start
+ *
+ * Start the request, re-tuning if needed and it is possible. Returns an error
+ * code if the request fails to start or -EBUSY if CQE is busy.
+ */
+int mmc_cqe_start_req(struct mmc_host *host, struct mmc_request *mrq)
+{
+ int err;
+
+ /*
+ * CQE cannot process re-tuning commands. Caller must hold retuning
+ * while CQE is in use. Re-tuning can happen here only when CQE has no
+ * active requests i.e. this is the first. Note, re-tuning will call
+ * ->cqe_off().
+ */
+ err = mmc_retune(host);
+ if (err)
+ goto out_err;
+
+ mrq->host = host;
+
+ mmc_mrq_pr_debug(host, mrq, true);
+
+ err = mmc_mrq_prep(host, mrq);
+ if (err)
+ goto out_err;
+
+ err = host->cqe_ops->cqe_request(host, mrq);
+ if (err)
+ goto out_err;
+
+ trace_mmc_request_start(host, mrq);
+
+ return 0;
+
+out_err:
+ if (mrq->cmd) {
+ pr_debug("%s: failed to start CQE direct CMD%u, error %d\n",
+ mmc_hostname(host), mrq->cmd->opcode, err);
+ } else {
+ pr_debug("%s: failed to start CQE transfer for tag %d, error %d\n",
+ mmc_hostname(host), mrq->tag, err);
+ }
+ return err;
+}
+EXPORT_SYMBOL(mmc_cqe_start_req);
+
+/**
+ * mmc_cqe_request_done - CQE has finished processing an MMC request
+ * @host: MMC host which completed request
+ * @mrq: MMC request which completed
+ *
+ * CQE drivers should call this function when they have completed
+ * their processing of a request.
+ */
+void mmc_cqe_request_done(struct mmc_host *host, struct mmc_request *mrq)
+{
+ mmc_should_fail_request(host, mrq);
+
+ /* Flag re-tuning needed on CRC errors */
+ if ((mrq->cmd && mrq->cmd->error == -EILSEQ) ||
+ (mrq->data && mrq->data->error == -EILSEQ))
+ mmc_retune_needed(host);
+
+ trace_mmc_request_done(host, mrq);
+
+ if (mrq->cmd) {
+ pr_debug("%s: CQE req done (direct CMD%u): %d\n",
+ mmc_hostname(host), mrq->cmd->opcode, mrq->cmd->error);
+ } else {
+ pr_debug("%s: CQE transfer done tag %d\n",
+ mmc_hostname(host), mrq->tag);
+ }
+
+ if (mrq->data) {
+ pr_debug("%s: %d bytes transferred: %d\n",
+ mmc_hostname(host),
+ mrq->data->bytes_xfered, mrq->data->error);
+ }
+
+ mrq->done(mrq);
+}
+EXPORT_SYMBOL(mmc_cqe_request_done);
+
+/**
+ * mmc_cqe_post_req - CQE post process of a completed MMC request
+ * @host: MMC host
+ * @mrq: MMC request to be processed
+ */
+void mmc_cqe_post_req(struct mmc_host *host, struct mmc_request *mrq)
+{
+ if (host->cqe_ops->cqe_post_req)
+ host->cqe_ops->cqe_post_req(host, mrq);
+}
+EXPORT_SYMBOL(mmc_cqe_post_req);
+
+/* Arbitrary 1 second timeout */
+#define MMC_CQE_RECOVERY_TIMEOUT 1000
+
+/*
+ * mmc_cqe_recovery - Recover from CQE errors.
+ * @host: MMC host to recover
+ *
+ * Recovery consists of stopping CQE, stopping eMMC, discarding the queue in
+ * in eMMC, and discarding the queue in CQE. CQE must call
+ * mmc_cqe_request_done() on all requests. An error is returned if the eMMC
+ * fails to discard its queue.
+ */
+int mmc_cqe_recovery(struct mmc_host *host)
+{
+ struct mmc_command cmd;
+ int err;
+
+ mmc_retune_hold_now(host);
+
+ /*
+ * Recovery is expected seldom, if at all, but it reduces performance,
+ * so make sure it is not completely silent.
+ */
+ pr_warn("%s: running CQE recovery\n", mmc_hostname(host));
+
+ host->cqe_ops->cqe_recovery_start(host);
+
+ memset(&cmd, 0, sizeof(cmd));
+ cmd.opcode = MMC_STOP_TRANSMISSION,
+ cmd.flags = MMC_RSP_R1B | MMC_CMD_AC,
+ cmd.flags &= ~MMC_RSP_CRC; /* Ignore CRC */
+ cmd.busy_timeout = MMC_CQE_RECOVERY_TIMEOUT,
+ mmc_wait_for_cmd(host, &cmd, 0);
+
+ memset(&cmd, 0, sizeof(cmd));
+ cmd.opcode = MMC_CMDQ_TASK_MGMT;
+ cmd.arg = 1; /* Discard entire queue */
+ cmd.flags = MMC_RSP_R1B | MMC_CMD_AC;
+ cmd.flags &= ~MMC_RSP_CRC; /* Ignore CRC */
+ cmd.busy_timeout = MMC_CQE_RECOVERY_TIMEOUT,
+ err = mmc_wait_for_cmd(host, &cmd, 0);
+
+ host->cqe_ops->cqe_recovery_finish(host);
+
+ mmc_retune_release(host);
+
+ return err;
+}
+EXPORT_SYMBOL(mmc_cqe_recovery);
+
/**
* mmc_is_req_done - Determine if a 'cap_cmd_during_tfr' request is done
* @host: MMC host
@@ -504,37 +667,6 @@ bool mmc_is_req_done(struct mmc_host *host, struct mmc_request *mrq)
EXPORT_SYMBOL(mmc_is_req_done);
/**
- * mmc_pre_req - Prepare for a new request
- * @host: MMC host to prepare command
- * @mrq: MMC request to prepare for
- *
- * mmc_pre_req() is called in prior to mmc_start_req() to let
- * host prepare for the new request. Preparation of a request may be
- * performed while another request is running on the host.
- */
-static void mmc_pre_req(struct mmc_host *host, struct mmc_request *mrq)
-{
- if (host->ops->pre_req)
- host->ops->pre_req(host, mrq);
-}
-
-/**
- * mmc_post_req - Post process a completed request
- * @host: MMC host to post process command
- * @mrq: MMC request to post process for
- * @err: Error, if non zero, clean up any resources made in pre_req
- *
- * Let the host post process a completed request. Post processing of
- * a request may be performed while another reuqest is running.
- */
-static void mmc_post_req(struct mmc_host *host, struct mmc_request *mrq,
- int err)
-{
- if (host->ops->post_req)
- host->ops->post_req(host, mrq, err);
-}
-
-/**
* mmc_finalize_areq() - finalize an asynchronous request
* @host: MMC host to finalize any ongoing request on
*
@@ -832,9 +964,36 @@ unsigned int mmc_align_data_size(struct mmc_card *card, unsigned int sz)
}
EXPORT_SYMBOL(mmc_align_data_size);
+/*
+ * Allow claiming an already claimed host if the context is the same or there is
+ * no context but the task is the same.
+ */
+static inline bool mmc_ctx_matches(struct mmc_host *host, struct mmc_ctx *ctx,
+ struct task_struct *task)
+{
+ return host->claimer == ctx ||
+ (!ctx && task && host->claimer->task == task);
+}
+
+static inline void mmc_ctx_set_claimer(struct mmc_host *host,
+ struct mmc_ctx *ctx,
+ struct task_struct *task)
+{
+ if (!host->claimer) {
+ if (ctx)
+ host->claimer = ctx;
+ else
+ host->claimer = &host->default_ctx;
+ }
+ if (task)
+ host->claimer->task = task;
+}
+
/**
* __mmc_claim_host - exclusively claim a host
* @host: mmc host to claim
+ * @ctx: context that claims the host or NULL in which case the default
+ * context will be used
* @abort: whether or not the operation should be aborted
*
* Claim a host for a set of operations. If @abort is non null and
@@ -842,8 +1001,10 @@ EXPORT_SYMBOL(mmc_align_data_size);
* that non-zero value without acquiring the lock. Returns zero
* with the lock held otherwise.
*/
-int __mmc_claim_host(struct mmc_host *host, atomic_t *abort)
+int __mmc_claim_host(struct mmc_host *host, struct mmc_ctx *ctx,
+ atomic_t *abort)
{
+ struct task_struct *task = ctx ? NULL : current;
DECLARE_WAITQUEUE(wait, current);
unsigned long flags;
int stop;
@@ -856,7 +1017,7 @@ int __mmc_claim_host(struct mmc_host *host, atomic_t *abort)
while (1) {
set_current_state(TASK_UNINTERRUPTIBLE);
stop = abort ? atomic_read(abort) : 0;
- if (stop || !host->claimed || host->claimer == current)
+ if (stop || !host->claimed || mmc_ctx_matches(host, ctx, task))
break;
spin_unlock_irqrestore(&host->lock, flags);
schedule();
@@ -865,7 +1026,7 @@ int __mmc_claim_host(struct mmc_host *host, atomic_t *abort)
set_current_state(TASK_RUNNING);
if (!stop) {
host->claimed = 1;
- host->claimer = current;
+ mmc_ctx_set_claimer(host, ctx, task);
host->claim_cnt += 1;
if (host->claim_cnt == 1)
pm = true;
@@ -900,6 +1061,7 @@ void mmc_release_host(struct mmc_host *host)
spin_unlock_irqrestore(&host->lock, flags);
} else {
host->claimed = 0;
+ host->claimer->task = NULL;
host->claimer = NULL;
spin_unlock_irqrestore(&host->lock, flags);
wake_up(&host->wq);
@@ -913,10 +1075,10 @@ EXPORT_SYMBOL(mmc_release_host);
* This is a helper function, which fetches a runtime pm reference for the
* card device and also claims the host.
*/
-void mmc_get_card(struct mmc_card *card)
+void mmc_get_card(struct mmc_card *card, struct mmc_ctx *ctx)
{
pm_runtime_get_sync(&card->dev);
- mmc_claim_host(card->host);
+ __mmc_claim_host(card->host, ctx, NULL);
}
EXPORT_SYMBOL(mmc_get_card);
@@ -924,9 +1086,13 @@ EXPORT_SYMBOL(mmc_get_card);
* This is a helper function, which releases the host and drops the runtime
* pm reference for the card device.
*/
-void mmc_put_card(struct mmc_card *card)
+void mmc_put_card(struct mmc_card *card, struct mmc_ctx *ctx)
{
- mmc_release_host(card->host);
+ struct mmc_host *host = card->host;
+
+ WARN_ON(ctx && host->claimer != ctx);
+
+ mmc_release_host(host);
pm_runtime_mark_last_busy(&card->dev);
pm_runtime_put_autosuspend(&card->dev);
}
@@ -2639,7 +2805,8 @@ void mmc_start_host(struct mmc_host *host)
}
mmc_gpiod_request_cd_irq(host);
- _mmc_detect_change(host, 0, false);
+ if (!(host->caps2 & MMC_CAP2_CD_POST))
+ _mmc_detect_change(host, 0, false);
}
void mmc_stop_host(struct mmc_host *host)
@@ -2810,10 +2977,46 @@ void mmc_init_context_info(struct mmc_host *host)
init_waitqueue_head(&host->context_info.wait);
}
+/*
+ * mmc_first_nonreserved_index() - get the first index that
+ * is not reserved
+ */
+int mmc_first_nonreserved_index(void)
+{
+ return __mmc_max_reserved_idx + 1;
+}
+EXPORT_SYMBOL(mmc_first_nonreserved_index);
+
+/*
+ * mmc_get_reserved_index() - get the index reserved for this host
+ * Return: The index reserved for this host or negative error value
+ * if no index is reserved for this host
+ */
+int mmc_get_reserved_index(struct mmc_host *host)
+{
+ return of_alias_get_id(host->parent->of_node, "mmc");
+}
+EXPORT_SYMBOL(mmc_get_reserved_index);
+
+static void mmc_of_reserve_idx(void)
+{
+ int max;
+
+ max = of_alias_max_index("mmc");
+ if (max < 0)
+ return;
+
+ __mmc_max_reserved_idx = max;
+ pr_debug("MMC: reserving %d slots for of aliases\n",
+ __mmc_max_reserved_idx + 1);
+}
+
static int __init mmc_init(void)
{
int ret;
+ mmc_of_reserve_idx();
+
ret = mmc_register_bus();
if (ret)
return ret;
diff --git a/drivers/mmc/core/core.h b/drivers/mmc/core/core.h
index ca861091a776..cfe00be3e652 100644
--- a/drivers/mmc/core/core.h
+++ b/drivers/mmc/core/core.h
@@ -35,6 +35,8 @@ struct mmc_bus_ops {
int (*reset)(struct mmc_host *);
};
+extern bool mmc_use_blk_mq;
+
void mmc_attach_bus(struct mmc_host *host, const struct mmc_bus_ops *ops);
void mmc_detach_bus(struct mmc_host *host);
@@ -80,6 +82,8 @@ int mmc_attach_mmc(struct mmc_host *host);
int mmc_attach_sd(struct mmc_host *host);
int mmc_attach_sdio(struct mmc_host *host);
+int mmc_first_nonreserved_index(void);
+int mmc_get_reserved_index(struct mmc_host *host);
/* Module parameters */
extern bool use_spi_crc;
@@ -107,6 +111,8 @@ static inline void mmc_unregister_pm_notifier(struct mmc_host *host) { }
void mmc_wait_for_req_done(struct mmc_host *host, struct mmc_request *mrq);
bool mmc_is_req_done(struct mmc_host *host, struct mmc_request *mrq);
+int mmc_start_request(struct mmc_host *host, struct mmc_request *mrq);
+
struct mmc_async_req;
struct mmc_async_req *mmc_start_areq(struct mmc_host *host,
@@ -128,10 +134,11 @@ int mmc_set_blocklen(struct mmc_card *card, unsigned int blocklen);
int mmc_set_blockcount(struct mmc_card *card, unsigned int blockcount,
bool is_rel_write);
-int __mmc_claim_host(struct mmc_host *host, atomic_t *abort);
+int __mmc_claim_host(struct mmc_host *host, struct mmc_ctx *ctx,
+ atomic_t *abort);
void mmc_release_host(struct mmc_host *host);
-void mmc_get_card(struct mmc_card *card);
-void mmc_put_card(struct mmc_card *card);
+void mmc_get_card(struct mmc_card *card, struct mmc_ctx *ctx);
+void mmc_put_card(struct mmc_card *card, struct mmc_ctx *ctx);
/**
* mmc_claim_host - exclusively claim a host
@@ -141,7 +148,42 @@ void mmc_put_card(struct mmc_card *card);
*/
static inline void mmc_claim_host(struct mmc_host *host)
{
- __mmc_claim_host(host, NULL);
+ __mmc_claim_host(host, NULL, NULL);
+}
+
+int mmc_cqe_start_req(struct mmc_host *host, struct mmc_request *mrq);
+void mmc_cqe_post_req(struct mmc_host *host, struct mmc_request *mrq);
+int mmc_cqe_recovery(struct mmc_host *host);
+
+/**
+ * mmc_pre_req - Prepare for a new request
+ * @host: MMC host to prepare command
+ * @mrq: MMC request to prepare for
+ *
+ * mmc_pre_req() is called in prior to mmc_start_req() to let
+ * host prepare for the new request. Preparation of a request may be
+ * performed while another request is running on the host.
+ */
+static inline void mmc_pre_req(struct mmc_host *host, struct mmc_request *mrq)
+{
+ if (host->ops->pre_req)
+ host->ops->pre_req(host, mrq);
+}
+
+/**
+ * mmc_post_req - Post process a completed request
+ * @host: MMC host to post process command
+ * @mrq: MMC request to post process for
+ * @err: Error, if non zero, clean up any resources made in pre_req
+ *
+ * Let the host post process a completed request. Post processing of
+ * a request may be performed while another request is running.
+ */
+static inline void mmc_post_req(struct mmc_host *host, struct mmc_request *mrq,
+ int err)
+{
+ if (host->ops->post_req)
+ host->ops->post_req(host, mrq, err);
}
#endif
diff --git a/drivers/mmc/core/debugfs.c b/drivers/mmc/core/debugfs.c
index 0f4a7d7b2626..83a4e64112fc 100644
--- a/drivers/mmc/core/debugfs.c
+++ b/drivers/mmc/core/debugfs.c
@@ -58,6 +58,9 @@ static int mmc_ios_show(struct seq_file *s, void *data)
struct mmc_ios *ios = &host->ios;
const char *str;
+ if (host->card)
+ mmc_get_card(host->card, NULL);
+
seq_printf(s, "clock:\t\t%u Hz\n", ios->clock);
if (host->actual_clock)
seq_printf(s, "actual clock:\t%u Hz\n", host->actual_clock);
@@ -194,6 +197,9 @@ static int mmc_ios_show(struct seq_file *s, void *data)
}
seq_printf(s, "driver type:\t%u (%s)\n", ios->drv_type, str);
+ if (host->card)
+ mmc_put_card(host->card, NULL);
+
return 0;
}
@@ -213,7 +219,11 @@ static int mmc_clock_opt_get(void *data, u64 *val)
{
struct mmc_host *host = data;
+ if (host->card)
+ mmc_get_card(host->card, NULL);
*val = host->ios.clock;
+ if (host->card)
+ mmc_put_card(host->card, NULL);
return 0;
}
diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c
index ad88deb2e8f3..4c680453e0fb 100644
--- a/drivers/mmc/core/host.c
+++ b/drivers/mmc/core/host.c
@@ -111,12 +111,6 @@ void mmc_retune_hold(struct mmc_host *host)
host->hold_retune += 1;
}
-void mmc_retune_hold_now(struct mmc_host *host)
-{
- host->retune_now = 0;
- host->hold_retune += 1;
-}
-
void mmc_retune_release(struct mmc_host *host)
{
if (host->hold_retune)
@@ -124,6 +118,7 @@ void mmc_retune_release(struct mmc_host *host)
else
WARN_ON(1);
}
+EXPORT_SYMBOL(mmc_retune_release);
int mmc_retune(struct mmc_host *host)
{
@@ -232,6 +227,8 @@ int mmc_of_parse(struct mmc_host *host)
/* Parse Card Detection */
if (device_property_read_bool(dev, "non-removable")) {
host->caps |= MMC_CAP_NONREMOVABLE;
+ if (device_property_read_bool(dev, "cd-post"))
+ host->caps2 |= MMC_CAP2_CD_POST;
} else {
cd_cap_invert = device_property_read_bool(dev, "cd-inverted");
@@ -305,6 +302,8 @@ int mmc_of_parse(struct mmc_host *host)
host->pm_caps |= MMC_PM_WAKE_SDIO_IRQ;
if (device_property_read_bool(dev, "mmc-ddr-3_3v"))
host->caps |= MMC_CAP_3_3V_DDR;
+ if (device_property_read_bool(dev, "pm-ignore-notify"))
+ host->pm_caps |= MMC_PM_IGNORE_PM_NOTIFY;
if (device_property_read_bool(dev, "mmc-ddr-1_8v"))
host->caps |= MMC_CAP_1_8V_DDR;
if (device_property_read_bool(dev, "mmc-ddr-1_2v"))
@@ -349,6 +348,7 @@ EXPORT_SYMBOL(mmc_of_parse);
struct mmc_host *mmc_alloc_host(int extra, struct device *dev)
{
int err;
+ int alias_id;
struct mmc_host *host;
host = kzalloc(sizeof(struct mmc_host) + extra, GFP_KERNEL);
@@ -357,8 +357,16 @@ struct mmc_host *mmc_alloc_host(int extra, struct device *dev)
/* scanning will be enabled when we're ready */
host->rescan_disable = 1;
+ host->parent = dev;
- err = ida_simple_get(&mmc_host_ida, 0, 0, GFP_KERNEL);
+ alias_id = mmc_get_reserved_index(host);
+ if (alias_id >= 0)
+ err = ida_simple_get(&mmc_host_ida, alias_id,
+ alias_id + 1, GFP_KERNEL);
+ else
+ err = ida_simple_get(&mmc_host_ida,
+ mmc_first_nonreserved_index(),
+ 0, GFP_KERNEL);
if (err < 0) {
kfree(host);
return NULL;
@@ -368,7 +376,6 @@ struct mmc_host *mmc_alloc_host(int extra, struct device *dev)
dev_set_name(&host->class_dev, "mmc%d", host->index);
- host->parent = dev;
host->class_dev.parent = dev;
host->class_dev.class = &mmc_host_class;
device_initialize(&host->class_dev);
@@ -398,6 +405,8 @@ struct mmc_host *mmc_alloc_host(int extra, struct device *dev)
host->max_blk_size = 512;
host->max_blk_count = PAGE_SIZE / 512;
+ host->use_blk_mq = mmc_use_blk_mq;
+
return host;
}
@@ -429,7 +438,8 @@ int mmc_add_host(struct mmc_host *host)
#endif
mmc_start_host(host);
- mmc_register_pm_notifier(host);
+ if (!(host->pm_caps& MMC_PM_IGNORE_PM_NOTIFY))
+ mmc_register_pm_notifier(host);
return 0;
}
@@ -446,7 +456,8 @@ EXPORT_SYMBOL(mmc_add_host);
*/
void mmc_remove_host(struct mmc_host *host)
{
- mmc_unregister_pm_notifier(host);
+ if (!(host->pm_caps& MMC_PM_IGNORE_PM_NOTIFY))
+ mmc_unregister_pm_notifier(host);
mmc_stop_host(host);
#ifdef CONFIG_DEBUG_FS
diff --git a/drivers/mmc/core/host.h b/drivers/mmc/core/host.h
index 77d6f60d1bf9..6eaf558e62d6 100644
--- a/drivers/mmc/core/host.h
+++ b/drivers/mmc/core/host.h
@@ -19,12 +19,17 @@ void mmc_unregister_host_class(void);
void mmc_retune_enable(struct mmc_host *host);
void mmc_retune_disable(struct mmc_host *host);
void mmc_retune_hold(struct mmc_host *host);
-void mmc_retune_hold_now(struct mmc_host *host);
void mmc_retune_release(struct mmc_host *host);
int mmc_retune(struct mmc_host *host);
void mmc_retune_pause(struct mmc_host *host);
void mmc_retune_unpause(struct mmc_host *host);
+static inline void mmc_retune_hold_now(struct mmc_host *host)
+{
+ host->retune_now = 0;
+ host->hold_retune += 1;
+}
+
static inline void mmc_retune_recheck(struct mmc_host *host)
{
if (host->hold_retune <= 1)
@@ -69,6 +74,10 @@ static inline bool mmc_card_hs400es(struct mmc_card *card)
return card->host->ios.enhanced_strobe;
}
+static inline bool mmc_host_use_blk_mq(struct mmc_host *host)
+{
+ return host->use_blk_mq;
+}
#endif
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index 814a04e8fdd7..98819a0f0934 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -1792,12 +1792,41 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
}
/*
+ * Enable Command Queue if supported. Note that Packed Commands cannot
+ * be used with Command Queue.
+ */
+ card->ext_csd.cmdq_en = false;
+ if (card->ext_csd.cmdq_support && host->caps2 & MMC_CAP2_CQE) {
+ err = mmc_cmdq_enable(card);
+ if (err && err != -EBADMSG)
+ goto free_card;
+ if (err) {
+ pr_warn("%s: Enabling CMDQ failed\n",
+ mmc_hostname(card->host));
+ card->ext_csd.cmdq_support = false;
+ card->ext_csd.cmdq_depth = 0;
+ err = 0;
+ }
+ }
+ /*
* In some cases (e.g. RPMB or mmc_test), the Command Queue must be
* disabled for a time, so a flag is needed to indicate to re-enable the
* Command Queue.
*/
card->reenable_cmdq = card->ext_csd.cmdq_en;
+ if (card->ext_csd.cmdq_en && !host->cqe_enabled) {
+ err = host->cqe_ops->cqe_enable(host, card);
+ if (err) {
+ pr_err("%s: Failed to enable CQE, error %d\n",
+ mmc_hostname(host), err);
+ } else {
+ host->cqe_enabled = true;
+ pr_info("%s: Command Queue Engine enabled\n",
+ mmc_hostname(host));
+ }
+ }
+
if (!oldcard)
host->card = card;
@@ -1917,14 +1946,14 @@ static void mmc_detect(struct mmc_host *host)
{
int err;
- mmc_get_card(host->card);
+ mmc_get_card(host->card, NULL);
/*
* Just check if our card has been removed.
*/
err = _mmc_detect_card_removed(host);
- mmc_put_card(host->card);
+ mmc_put_card(host->card, NULL);
if (err) {
mmc_remove(host);
diff --git a/drivers/mmc/core/mmc_ops.c b/drivers/mmc/core/mmc_ops.c
index 54686ca4bfb7..73e9c8afa9f6 100644
--- a/drivers/mmc/core/mmc_ops.c
+++ b/drivers/mmc/core/mmc_ops.c
@@ -585,6 +585,12 @@ out_tim:
if (timing)
mmc_set_timing(host, timing);
+ /*
+ * WORKAROUND: for Sandisk eMMC cards, it might need certain delay
+ * before sending CMD13 after CMD6
+ */
+ mdelay(1);
+
if (send_status) {
err = mmc_switch_status(card);
if (err && timing)
@@ -1010,6 +1016,7 @@ void mmc_start_bkops(struct mmc_card *card, bool from_exception)
out:
mmc_release_host(card->host);
}
+EXPORT_SYMBOL(mmc_start_bkops);
/*
* Flush the cache to the non-volatile storage.
diff --git a/drivers/mmc/core/queue.c b/drivers/mmc/core/queue.c
index 0a4e77a5ba33..e991c7af09ee 100644
--- a/drivers/mmc/core/queue.c
+++ b/drivers/mmc/core/queue.c
@@ -22,6 +22,7 @@
#include "block.h"
#include "core.h"
#include "card.h"
+#include "host.h"
/*
* Prepare a MMC request. This just filters out odd stuff.
@@ -34,10 +35,149 @@ static int mmc_prep_request(struct request_queue *q, struct request *req)
return BLKPREP_KILL;
req->rq_flags |= RQF_DONTPREP;
+ req_to_mmc_queue_req(req)->retries = 0;
return BLKPREP_OK;
}
+static inline bool mmc_cqe_dcmd_busy(struct mmc_queue *mq)
+{
+ /* Allow only 1 DCMD at a time */
+ return mq->in_flight[MMC_ISSUE_DCMD];
+}
+
+void mmc_cqe_check_busy(struct mmc_queue *mq)
+{
+ if ((mq->cqe_busy & MMC_CQE_DCMD_BUSY) && !mmc_cqe_dcmd_busy(mq))
+ mq->cqe_busy &= ~MMC_CQE_DCMD_BUSY;
+
+ mq->cqe_busy &= ~MMC_CQE_QUEUE_FULL;
+}
+
+static inline bool mmc_cqe_can_dcmd(struct mmc_host *host)
+{
+ return host->caps2 & MMC_CAP2_CQE_DCMD;
+}
+
+enum mmc_issue_type mmc_cqe_issue_type(struct mmc_host *host,
+ struct request *req)
+{
+ switch (req_op(req)) {
+ case REQ_OP_DRV_IN:
+ case REQ_OP_DRV_OUT:
+ case REQ_OP_DISCARD:
+ case REQ_OP_SECURE_ERASE:
+ return MMC_ISSUE_SYNC;
+ case REQ_OP_FLUSH:
+ return mmc_cqe_can_dcmd(host) ? MMC_ISSUE_DCMD : MMC_ISSUE_SYNC;
+ default:
+ return MMC_ISSUE_ASYNC;
+ }
+}
+
+enum mmc_issue_type mmc_issue_type(struct mmc_queue *mq, struct request *req)
+{
+ struct mmc_host *host = mq->card->host;
+
+ if (mq->use_cqe)
+ return mmc_cqe_issue_type(host, req);
+
+ if (req_op(req) == REQ_OP_READ || req_op(req) == REQ_OP_WRITE)
+ return MMC_ISSUE_ASYNC;
+
+ return MMC_ISSUE_SYNC;
+}
+
+static void __mmc_cqe_recovery_notifier(struct mmc_queue *mq)
+{
+ if (!mq->recovery_needed) {
+ mq->recovery_needed = true;
+ schedule_work(&mq->recovery_work);
+ }
+}
+
+void mmc_cqe_recovery_notifier(struct mmc_request *mrq)
+{
+ struct mmc_queue_req *mqrq = container_of(mrq, struct mmc_queue_req,
+ brq.mrq);
+ struct request *req = mmc_queue_req_to_req(mqrq);
+ struct request_queue *q = req->q;
+ struct mmc_queue *mq = q->queuedata;
+ unsigned long flags;
+
+ spin_lock_irqsave(q->queue_lock, flags);
+ __mmc_cqe_recovery_notifier(mq);
+ spin_unlock_irqrestore(q->queue_lock, flags);
+}
+
+static enum blk_eh_timer_return mmc_cqe_timed_out(struct request *req)
+{
+ struct mmc_queue_req *mqrq = req_to_mmc_queue_req(req);
+ struct mmc_request *mrq = &mqrq->brq.mrq;
+ struct mmc_queue *mq = req->q->queuedata;
+ struct mmc_host *host = mq->card->host;
+ enum mmc_issue_type issue_type = mmc_issue_type(mq, req);
+ bool recovery_needed = false;
+
+ switch (issue_type) {
+ case MMC_ISSUE_ASYNC:
+ case MMC_ISSUE_DCMD:
+ if (host->cqe_ops->cqe_timeout(host, mrq, &recovery_needed)) {
+ if (recovery_needed)
+ __mmc_cqe_recovery_notifier(mq);
+ return BLK_EH_RESET_TIMER;
+ }
+ /* No timeout */
+ return BLK_EH_HANDLED;
+ default:
+ /* Timeout is handled by mmc core */
+ return BLK_EH_RESET_TIMER;
+ }
+}
+
+static enum blk_eh_timer_return mmc_mq_timed_out(struct request *req,
+ bool reserved)
+{
+ struct request_queue *q = req->q;
+ struct mmc_queue *mq = q->queuedata;
+ unsigned long flags;
+ int ret;
+
+ spin_lock_irqsave(q->queue_lock, flags);
+
+ if (mq->recovery_needed || !mq->use_cqe)
+ ret = BLK_EH_RESET_TIMER;
+ else
+ ret = mmc_cqe_timed_out(req);
+
+ spin_unlock_irqrestore(q->queue_lock, flags);
+
+ return ret;
+}
+
+static void mmc_mq_recovery_handler(struct work_struct *work)
+{
+ struct mmc_queue *mq = container_of(work, struct mmc_queue,
+ recovery_work);
+ struct request_queue *q = mq->queue;
+
+ mmc_get_card(mq->card, &mq->ctx);
+
+ mq->in_recovery = true;
+
+ mmc_blk_cqe_recovery(mq);
+
+ mq->in_recovery = false;
+
+ spin_lock_irq(q->queue_lock);
+ mq->recovery_needed = false;
+ spin_unlock_irq(q->queue_lock);
+
+ mmc_put_card(mq->card, &mq->ctx);
+
+ blk_mq_run_hw_queues(q, true);
+}
+
static int mmc_queue_thread(void *d)
{
struct mmc_queue *mq = d;
@@ -154,11 +294,10 @@ static void mmc_queue_setup_discard(struct request_queue *q,
* @req: the request
* @gfp: memory allocation policy
*/
-static int mmc_init_request(struct request_queue *q, struct request *req,
- gfp_t gfp)
+static int __mmc_init_request(struct mmc_queue *mq, struct request *req,
+ gfp_t gfp)
{
struct mmc_queue_req *mq_rq = req_to_mmc_queue_req(req);
- struct mmc_queue *mq = q->queuedata;
struct mmc_card *card = mq->card;
struct mmc_host *host = card->host;
@@ -169,6 +308,12 @@ static int mmc_init_request(struct request_queue *q, struct request *req,
return 0;
}
+static int mmc_init_request(struct request_queue *q, struct request *req,
+ gfp_t gfp)
+{
+ return __mmc_init_request(q->queuedata, req, gfp);
+}
+
static void mmc_exit_request(struct request_queue *q, struct request *req)
{
struct mmc_queue_req *mq_rq = req_to_mmc_queue_req(req);
@@ -177,6 +322,227 @@ static void mmc_exit_request(struct request_queue *q, struct request *req)
mq_rq->sg = NULL;
}
+static int mmc_mq_init_request(struct blk_mq_tag_set *set, struct request *req,
+ unsigned int hctx_idx, unsigned int numa_node)
+{
+ return __mmc_init_request(set->driver_data, req, GFP_KERNEL);
+}
+
+static void mmc_mq_exit_request(struct blk_mq_tag_set *set, struct request *req,
+ unsigned int hctx_idx)
+{
+ struct mmc_queue *mq = set->driver_data;
+
+ mmc_exit_request(mq->queue, req);
+}
+
+/*
+ * We use BLK_MQ_F_BLOCKING and have only 1 hardware queue, which means requests
+ * will not be dispatched in parallel.
+ */
+static blk_status_t mmc_mq_queue_rq(struct blk_mq_hw_ctx *hctx,
+ const struct blk_mq_queue_data *bd)
+{
+ struct request *req = bd->rq;
+ struct request_queue *q = req->q;
+ struct mmc_queue *mq = q->queuedata;
+ struct mmc_card *card = mq->card;
+ struct mmc_host *host = card->host;
+ enum mmc_issue_type issue_type;
+ enum mmc_issued issued;
+ bool get_card, cqe_retune_ok;
+ int ret;
+
+ if (mmc_card_removed(mq->card)) {
+ req->rq_flags |= RQF_QUIET;
+ return BLK_STS_IOERR;
+ }
+
+ issue_type = mmc_issue_type(mq, req);
+
+ spin_lock_irq(q->queue_lock);
+
+ if (mq->recovery_needed) {
+ spin_unlock_irq(q->queue_lock);
+ return BLK_STS_RESOURCE;
+ }
+
+ switch (issue_type) {
+ case MMC_ISSUE_DCMD:
+ if (mmc_cqe_dcmd_busy(mq)) {
+ mq->cqe_busy |= MMC_CQE_DCMD_BUSY;
+ spin_unlock_irq(q->queue_lock);
+ return BLK_STS_RESOURCE;
+ }
+ break;
+ case MMC_ISSUE_ASYNC:
+ break;
+ default:
+ /*
+ * Timeouts are handled by mmc core, and we don't have a host
+ * API to abort requests, so we can't handle the timeout anyway.
+ * However, when the timeout happens, blk_mq_complete_request()
+ * no longer works (to stop the request disappearing under us).
+ * To avoid racing with that, set a large timeout.
+ */
+ req->timeout = 600 * HZ;
+ break;
+ }
+
+ mq->in_flight[issue_type] += 1;
+ get_card = (mmc_tot_in_flight(mq) == 1);
+ cqe_retune_ok = (mmc_cqe_qcnt(mq) == 1);
+
+ spin_unlock_irq(q->queue_lock);
+
+ if (!(req->rq_flags & RQF_DONTPREP)) {
+ req_to_mmc_queue_req(req)->retries = 0;
+ req->rq_flags |= RQF_DONTPREP;
+ }
+
+ if (get_card)
+ mmc_get_card(card, &mq->ctx);
+
+ if (mq->use_cqe) {
+ host->retune_now = host->need_retune && cqe_retune_ok &&
+ !host->hold_retune;
+ }
+
+ blk_mq_start_request(req);
+
+ issued = mmc_blk_mq_issue_rq(mq, req);
+
+ switch (issued) {
+ case MMC_REQ_BUSY:
+ ret = BLK_STS_RESOURCE;
+ break;
+ case MMC_REQ_FAILED_TO_START:
+ ret = BLK_STS_IOERR;
+ break;
+ default:
+ ret = BLK_STS_OK;
+ break;
+ }
+
+ if (issued != MMC_REQ_STARTED) {
+ bool put_card = false;
+
+ spin_lock_irq(q->queue_lock);
+ mq->in_flight[issue_type] -= 1;
+ if (mmc_tot_in_flight(mq) == 0)
+ put_card = true;
+ spin_unlock_irq(q->queue_lock);
+ if (put_card)
+ mmc_put_card(card, &mq->ctx);
+ }
+
+ return ret;
+}
+
+static const struct blk_mq_ops mmc_mq_ops = {
+ .queue_rq = mmc_mq_queue_rq,
+ .init_request = mmc_mq_init_request,
+ .exit_request = mmc_mq_exit_request,
+ .complete = mmc_blk_mq_complete,
+ .timeout = mmc_mq_timed_out,
+};
+
+static void mmc_setup_queue(struct mmc_queue *mq, struct mmc_card *card)
+{
+ struct mmc_host *host = card->host;
+ u64 limit = BLK_BOUNCE_HIGH;
+
+ if (mmc_dev(host)->dma_mask && *mmc_dev(host)->dma_mask)
+ limit = (u64)dma_max_pfn(mmc_dev(host)) << PAGE_SHIFT;
+
+ queue_flag_set_unlocked(QUEUE_FLAG_NONROT, mq->queue);
+ queue_flag_clear_unlocked(QUEUE_FLAG_ADD_RANDOM, mq->queue);
+ if (mmc_can_erase(card))
+ mmc_queue_setup_discard(mq->queue, card);
+
+ blk_queue_bounce_limit(mq->queue, limit);
+ blk_queue_max_hw_sectors(mq->queue,
+ min(host->max_blk_count, host->max_req_size / 512));
+ blk_queue_max_segments(mq->queue, host->max_segs);
+ blk_queue_max_segment_size(mq->queue, host->max_seg_size);
+
+ /* Initialize thread_sem even if it is not used */
+ sema_init(&mq->thread_sem, 1);
+
+ INIT_WORK(&mq->recovery_work, mmc_mq_recovery_handler);
+ INIT_WORK(&mq->complete_work, mmc_blk_mq_complete_work);
+
+ mutex_init(&mq->complete_lock);
+
+ init_waitqueue_head(&mq->wait);
+}
+
+static int mmc_mq_init_queue(struct mmc_queue *mq, int q_depth,
+ const struct blk_mq_ops *mq_ops, spinlock_t *lock)
+{
+ int ret;
+
+ memset(&mq->tag_set, 0, sizeof(mq->tag_set));
+ mq->tag_set.ops = mq_ops;
+ mq->tag_set.queue_depth = q_depth;
+ mq->tag_set.numa_node = NUMA_NO_NODE;
+ mq->tag_set.flags = BLK_MQ_F_SHOULD_MERGE | BLK_MQ_F_SG_MERGE |
+ BLK_MQ_F_BLOCKING;
+ mq->tag_set.nr_hw_queues = 1;
+ mq->tag_set.cmd_size = sizeof(struct mmc_queue_req);
+ mq->tag_set.driver_data = mq;
+
+ ret = blk_mq_alloc_tag_set(&mq->tag_set);
+ if (ret)
+ return ret;
+
+ mq->queue = blk_mq_init_queue(&mq->tag_set);
+ if (IS_ERR(mq->queue)) {
+ ret = PTR_ERR(mq->queue);
+ goto free_tag_set;
+ }
+
+ mq->queue->queue_lock = lock;
+ mq->queue->queuedata = mq;
+
+ return 0;
+
+free_tag_set:
+ blk_mq_free_tag_set(&mq->tag_set);
+
+ return ret;
+}
+
+/* Set queue depth to get a reasonable value for q->nr_requests */
+#define MMC_QUEUE_DEPTH 64
+
+static int mmc_mq_init(struct mmc_queue *mq, struct mmc_card *card,
+ spinlock_t *lock)
+{
+ struct mmc_host *host = card->host;
+ int q_depth;
+ int ret;
+
+ /*
+ * The queue depth for CQE must match the hardware because the request
+ * tag is used to index the hardware queue.
+ */
+ if (mq->use_cqe)
+ q_depth = min_t(int, card->ext_csd.cmdq_depth, host->cqe_qdepth);
+ else
+ q_depth = MMC_QUEUE_DEPTH;
+
+ ret = mmc_mq_init_queue(mq, q_depth, &mmc_mq_ops, lock);
+ if (ret)
+ return ret;
+
+ blk_queue_rq_timeout(mq->queue, 60 * HZ);
+
+ mmc_setup_queue(mq, card);
+
+ return 0;
+}
+
/**
* mmc_init_queue - initialise a queue structure.
* @mq: mmc queue
@@ -190,13 +556,15 @@ int mmc_init_queue(struct mmc_queue *mq, struct mmc_card *card,
spinlock_t *lock, const char *subname)
{
struct mmc_host *host = card->host;
- u64 limit = BLK_BOUNCE_HIGH;
int ret = -ENOMEM;
- if (mmc_dev(host)->dma_mask && *mmc_dev(host)->dma_mask)
- limit = (u64)dma_max_pfn(mmc_dev(host)) << PAGE_SHIFT;
-
mq->card = card;
+
+ mq->use_cqe = host->cqe_enabled;
+
+ if (mq->use_cqe || mmc_host_use_blk_mq(host))
+ return mmc_mq_init(mq, card, lock);
+
mq->queue = blk_alloc_queue(GFP_KERNEL);
if (!mq->queue)
return -ENOMEM;
@@ -214,18 +582,8 @@ int mmc_init_queue(struct mmc_queue *mq, struct mmc_card *card,
}
blk_queue_prep_rq(mq->queue, mmc_prep_request);
- queue_flag_set_unlocked(QUEUE_FLAG_NONROT, mq->queue);
- queue_flag_clear_unlocked(QUEUE_FLAG_ADD_RANDOM, mq->queue);
- if (mmc_can_erase(card))
- mmc_queue_setup_discard(mq->queue, card);
- blk_queue_bounce_limit(mq->queue, limit);
- blk_queue_max_hw_sectors(mq->queue,
- min(host->max_blk_count, host->max_req_size / 512));
- blk_queue_max_segments(mq->queue, host->max_segs);
- blk_queue_max_segment_size(mq->queue, host->max_seg_size);
-
- sema_init(&mq->thread_sem, 1);
+ mmc_setup_queue(mq, card);
mq->thread = kthread_run(mmc_queue_thread, mq, "mmcqd/%d%s",
host->index, subname ? subname : "");
@@ -242,11 +600,70 @@ cleanup_queue:
return ret;
}
+static void mmc_mq_queue_suspend(struct mmc_queue *mq)
+{
+ blk_mq_quiesce_queue(mq->queue);
+
+ /*
+ * The host remains claimed while there are outstanding requests, so
+ * simply claiming and releasing here ensures there are none.
+ */
+ mmc_claim_host(mq->card->host);
+ mmc_release_host(mq->card->host);
+}
+
+static void mmc_mq_queue_resume(struct mmc_queue *mq)
+{
+ blk_mq_unquiesce_queue(mq->queue);
+}
+
+static void __mmc_queue_suspend(struct mmc_queue *mq)
+{
+ struct request_queue *q = mq->queue;
+ unsigned long flags;
+
+ if (!mq->suspended) {
+ mq->suspended |= true;
+
+ spin_lock_irqsave(q->queue_lock, flags);
+ blk_stop_queue(q);
+ spin_unlock_irqrestore(q->queue_lock, flags);
+
+ down(&mq->thread_sem);
+ }
+}
+
+static void __mmc_queue_resume(struct mmc_queue *mq)
+{
+ struct request_queue *q = mq->queue;
+ unsigned long flags;
+
+ if (mq->suspended) {
+ mq->suspended = false;
+
+ up(&mq->thread_sem);
+
+ spin_lock_irqsave(q->queue_lock, flags);
+ blk_start_queue(q);
+ spin_unlock_irqrestore(q->queue_lock, flags);
+ }
+}
+
void mmc_cleanup_queue(struct mmc_queue *mq)
{
struct request_queue *q = mq->queue;
unsigned long flags;
+ if (q->mq_ops) {
+ /*
+ * The legacy code handled the possibility of being suspended,
+ * so do that here too.
+ */
+ if (blk_queue_quiesced(q))
+ blk_mq_unquiesce_queue(q);
+ goto out_cleanup;
+ }
+
/* Make sure the queue isn't suspended, as that will deadlock */
mmc_queue_resume(mq);
@@ -259,6 +676,16 @@ void mmc_cleanup_queue(struct mmc_queue *mq)
blk_start_queue(q);
spin_unlock_irqrestore(q->queue_lock, flags);
+out_cleanup:
+ blk_cleanup_queue(q);
+
+ /*
+ * A request can be completed before the next request, potentially
+ * leaving a complete_work with nothing to do. Such a work item might
+ * still be queued at this point. Flush it.
+ */
+ flush_work(&mq->complete_work);
+
mq->card = NULL;
}
EXPORT_SYMBOL(mmc_cleanup_queue);
@@ -274,17 +701,11 @@ EXPORT_SYMBOL(mmc_cleanup_queue);
void mmc_queue_suspend(struct mmc_queue *mq)
{
struct request_queue *q = mq->queue;
- unsigned long flags;
- if (!mq->suspended) {
- mq->suspended |= true;
-
- spin_lock_irqsave(q->queue_lock, flags);
- blk_stop_queue(q);
- spin_unlock_irqrestore(q->queue_lock, flags);
-
- down(&mq->thread_sem);
- }
+ if (q->mq_ops)
+ mmc_mq_queue_suspend(mq);
+ else
+ __mmc_queue_suspend(mq);
}
/**
@@ -294,17 +715,11 @@ void mmc_queue_suspend(struct mmc_queue *mq)
void mmc_queue_resume(struct mmc_queue *mq)
{
struct request_queue *q = mq->queue;
- unsigned long flags;
-
- if (mq->suspended) {
- mq->suspended = false;
-
- up(&mq->thread_sem);
- spin_lock_irqsave(q->queue_lock, flags);
- blk_start_queue(q);
- spin_unlock_irqrestore(q->queue_lock, flags);
- }
+ if (q->mq_ops)
+ mmc_mq_queue_resume(mq);
+ else
+ __mmc_queue_resume(mq);
}
/*
diff --git a/drivers/mmc/core/queue.h b/drivers/mmc/core/queue.h
index 6bfba32ffa66..d64e23f23476 100644
--- a/drivers/mmc/core/queue.h
+++ b/drivers/mmc/core/queue.h
@@ -8,6 +8,20 @@
#include <linux/mmc/core.h>
#include <linux/mmc/host.h>
+enum mmc_issued {
+ MMC_REQ_STARTED,
+ MMC_REQ_BUSY,
+ MMC_REQ_FAILED_TO_START,
+ MMC_REQ_FINISHED,
+};
+
+enum mmc_issue_type {
+ MMC_ISSUE_SYNC,
+ MMC_ISSUE_DCMD,
+ MMC_ISSUE_ASYNC,
+ MMC_ISSUE_MAX,
+};
+
static inline struct mmc_queue_req *req_to_mmc_queue_req(struct request *rq)
{
return blk_mq_rq_to_pdu(rq);
@@ -55,12 +69,15 @@ struct mmc_queue_req {
int drv_op_result;
void *drv_op_data;
unsigned int ioc_count;
+ int retries;
};
struct mmc_queue {
struct mmc_card *card;
struct task_struct *thread;
struct semaphore thread_sem;
+ struct mmc_ctx ctx;
+ struct blk_mq_tag_set tag_set;
bool suspended;
bool asleep;
struct mmc_blk_data *blkdata;
@@ -72,6 +89,21 @@ struct mmc_queue {
* associated mmc_queue_req data.
*/
int qcnt;
+
+ int in_flight[MMC_ISSUE_MAX];
+ unsigned int cqe_busy;
+#define MMC_CQE_DCMD_BUSY BIT(0)
+#define MMC_CQE_QUEUE_FULL BIT(1)
+ bool use_cqe;
+ bool recovery_needed;
+ bool in_recovery;
+ bool rw_wait;
+ bool waiting;
+ struct work_struct recovery_work;
+ wait_queue_head_t wait;
+ struct request *complete_req;
+ struct mutex complete_lock;
+ struct work_struct complete_work;
};
extern int mmc_init_queue(struct mmc_queue *, struct mmc_card *, spinlock_t *,
@@ -84,4 +116,22 @@ extern unsigned int mmc_queue_map_sg(struct mmc_queue *,
extern int mmc_access_rpmb(struct mmc_queue *);
+void mmc_cqe_check_busy(struct mmc_queue *mq);
+void mmc_cqe_recovery_notifier(struct mmc_request *mrq);
+
+enum mmc_issue_type mmc_issue_type(struct mmc_queue *mq, struct request *req);
+
+static inline int mmc_tot_in_flight(struct mmc_queue *mq)
+{
+ return mq->in_flight[MMC_ISSUE_SYNC] +
+ mq->in_flight[MMC_ISSUE_DCMD] +
+ mq->in_flight[MMC_ISSUE_ASYNC];
+}
+
+static inline int mmc_cqe_qcnt(struct mmc_queue *mq)
+{
+ return mq->in_flight[MMC_ISSUE_DCMD] +
+ mq->in_flight[MMC_ISSUE_ASYNC];
+}
+
#endif
diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c
index 33975ec14b7e..42c68439b015 100644
--- a/drivers/mmc/core/sd.c
+++ b/drivers/mmc/core/sd.c
@@ -488,6 +488,13 @@ static int sd_set_bus_speed_mode(struct mmc_card *card, u8 *status)
else {
mmc_set_timing(card->host, timing);
mmc_set_clock(card->host, card->sw_caps.uhs_max_dtr);
+
+ /*
+ * FIXME: Sandisk SD3.0 cards DDR50 mode requires such
+ * delay to get stable, without this delay we may encounter
+ * CRC errors after switch to DDR50 mode
+ */
+ mmc_delay(100);
}
return 0;
@@ -1064,14 +1071,14 @@ static void mmc_sd_detect(struct mmc_host *host)
{
int err;
- mmc_get_card(host->card);
+ mmc_get_card(host->card, NULL);
/*
* Just check if our card has been removed.
*/
err = _mmc_detect_card_removed(host);
- mmc_put_card(host->card);
+ mmc_put_card(host->card, NULL);
if (err) {
mmc_sd_remove(host);
diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c
index 7ee8c9082021..e8b929b21ed3 100644
--- a/drivers/mmc/core/sdio.c
+++ b/drivers/mmc/core/sdio.c
@@ -802,6 +802,37 @@ err:
return err;
}
+int sdio_reset_comm(struct mmc_card *card)
+{
+ struct mmc_host *host = card->host;
+ u32 ocr;
+ u32 rocr;
+ int err;
+
+ mmc_claim_host(host);
+ mmc_go_idle(host);
+ mmc_set_clock(host, host->f_min);
+ err = mmc_send_io_op_cond(host, 0, &ocr);
+ if (err)
+ goto err;
+ rocr = mmc_select_voltage(host, ocr);
+ if (!rocr) {
+ err = -EINVAL;
+ goto err;
+ }
+ err = mmc_sdio_init_card(host, rocr, card, 0);
+ if (err)
+ goto err;
+ mmc_release_host(host);
+ return 0;
+err:
+ pr_err("%s: Error resetting SDIO communications (%d)\n",
+ mmc_hostname(host), err);
+ mmc_release_host(host);
+ return err;
+}
+EXPORT_SYMBOL(sdio_reset_comm);
+
/*
* Host is being removed. Free up the current card.
*/
@@ -817,9 +848,22 @@ static void mmc_sdio_remove(struct mmc_host *host)
}
mmc_remove_card(host->card);
+ /* clear rescan_entered in case force remove */
+ host->rescan_entered = 0;
host->card = NULL;
}
+void mmc_sdio_force_remove(struct mmc_host *host)
+{
+ mmc_sdio_remove(host);
+
+ mmc_claim_host(host);
+ mmc_detach_bus(host);
+ mmc_power_off(host);
+ mmc_release_host(host);
+}
+EXPORT_SYMBOL_GPL(mmc_sdio_force_remove);
+
/*
* Card detection - card is alive.
*/
diff --git a/drivers/mmc/core/sdio_irq.c b/drivers/mmc/core/sdio_irq.c
index 0656d740b0dd..78d030a635bc 100644
--- a/drivers/mmc/core/sdio_irq.c
+++ b/drivers/mmc/core/sdio_irq.c
@@ -163,7 +163,8 @@ static int sdio_irq_thread(void *_host)
* holding of the host lock does not cover too much work
* that doesn't require that lock to be held.
*/
- ret = __mmc_claim_host(host, &host->sdio_irq_thread_abort);
+ ret = __mmc_claim_host(host, NULL,
+ &host->sdio_irq_thread_abort);
if (ret)
break;
ret = process_sdio_pending_irqs(host);
diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
index 9ed786935a30..d52e71db9915 100644
--- a/drivers/mmc/host/Kconfig
+++ b/drivers/mmc/host/Kconfig
@@ -198,9 +198,10 @@ config MMC_SDHCI_CNS3XXX
config MMC_SDHCI_ESDHC_IMX
tristate "SDHCI support for the Freescale eSDHC/uSDHC i.MX controller"
- depends on ARCH_MXC
+ depends on ARCH_MXC || ARCH_MXC_ARM64 || COMPILE_TEST
depends on MMC_SDHCI_PLTFM
select MMC_SDHCI_IO_ACCESSORS
+ select MMC_CQHCI
help
This selects the Freescale eSDHC/uSDHC controller support
found on i.MX25, i.MX35 i.MX5x and i.MX6x.
@@ -844,6 +845,19 @@ config MMC_SUNXI
This selects support for the SD/MMC Host Controller on
Allwinner sunxi SoCs.
+config MMC_CQHCI
+ tristate "Command Queue Host Controller Interface support"
+ depends on HAS_DMA
+ help
+ This selects the Command Queue Host Controller Interface (CQHCI)
+ support present in host controllers of Qualcomm Technologies, Inc
+ amongst others.
+ This controller supports eMMC devices with command queue support.
+
+ If you have a controller with this interface, say Y or M here.
+
+ If unsure, say N.
+
config MMC_TOSHIBA_PCI
tristate "Toshiba Type A SD/MMC Card Interface Driver"
depends on PCI
diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile
index 7c7b29ff591a..e689b2efbfcf 100644
--- a/drivers/mmc/host/Makefile
+++ b/drivers/mmc/host/Makefile
@@ -90,6 +90,7 @@ obj-$(CONFIG_MMC_SDHCI_MSM) += sdhci-msm.o
obj-$(CONFIG_MMC_SDHCI_ST) += sdhci-st.o
obj-$(CONFIG_MMC_SDHCI_MICROCHIP_PIC32) += sdhci-pic32.o
obj-$(CONFIG_MMC_SDHCI_BRCMSTB) += sdhci-brcmstb.o
+obj-$(CONFIG_MMC_CQHCI) += cqhci.o
ifeq ($(CONFIG_CB710_DEBUG),y)
CFLAGS-cb710-mmc += -DDEBUG
diff --git a/drivers/mmc/host/cqhci.c b/drivers/mmc/host/cqhci.c
new file mode 100644
index 000000000000..43010e37b332
--- /dev/null
+++ b/drivers/mmc/host/cqhci.c
@@ -0,0 +1,1157 @@
+/* Copyright (c) 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/delay.h>
+#include <linux/highmem.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/dma-mapping.h>
+#include <linux/slab.h>
+#include <linux/scatterlist.h>
+#include <linux/platform_device.h>
+#include <linux/ktime.h>
+
+#include <linux/mmc/mmc.h>
+#include <linux/mmc/host.h>
+#include <linux/mmc/card.h>
+
+#include "cqhci.h"
+
+#define DCMD_SLOT 31
+#define NUM_SLOTS 32
+
+struct cqhci_slot {
+ struct mmc_request *mrq;
+ unsigned int flags;
+#define CQHCI_EXTERNAL_TIMEOUT BIT(0)
+#define CQHCI_COMPLETED BIT(1)
+#define CQHCI_HOST_CRC BIT(2)
+#define CQHCI_HOST_TIMEOUT BIT(3)
+#define CQHCI_HOST_OTHER BIT(4)
+};
+
+static inline u8 *get_desc(struct cqhci_host *cq_host, u8 tag)
+{
+ return cq_host->desc_base + (tag * cq_host->slot_sz);
+}
+
+static inline u8 *get_link_desc(struct cqhci_host *cq_host, u8 tag)
+{
+ u8 *desc = get_desc(cq_host, tag);
+
+ return desc + cq_host->task_desc_len;
+}
+
+static inline dma_addr_t get_trans_desc_dma(struct cqhci_host *cq_host, u8 tag)
+{
+ return cq_host->trans_desc_dma_base +
+ (cq_host->mmc->max_segs * tag *
+ cq_host->trans_desc_len);
+}
+
+static inline u8 *get_trans_desc(struct cqhci_host *cq_host, u8 tag)
+{
+ return cq_host->trans_desc_base +
+ (cq_host->trans_desc_len * cq_host->mmc->max_segs * tag);
+}
+
+static void setup_trans_desc(struct cqhci_host *cq_host, u8 tag)
+{
+ u8 *link_temp;
+ dma_addr_t trans_temp;
+
+ link_temp = get_link_desc(cq_host, tag);
+ trans_temp = get_trans_desc_dma(cq_host, tag);
+
+ memset(link_temp, 0, cq_host->link_desc_len);
+ if (cq_host->link_desc_len > 8)
+ *(link_temp + 8) = 0;
+
+ if (tag == DCMD_SLOT && (cq_host->mmc->caps2 & MMC_CAP2_CQE_DCMD)) {
+ *link_temp = CQHCI_VALID(0) | CQHCI_ACT(0) | CQHCI_END(1);
+ return;
+ }
+
+ *link_temp = CQHCI_VALID(1) | CQHCI_ACT(0x6) | CQHCI_END(0);
+
+ if (cq_host->dma64) {
+ __le64 *data_addr = (__le64 __force *)(link_temp + 4);
+
+ data_addr[0] = cpu_to_le64(trans_temp);
+ } else {
+ __le32 *data_addr = (__le32 __force *)(link_temp + 4);
+
+ data_addr[0] = cpu_to_le32(trans_temp);
+ }
+}
+
+static void cqhci_set_irqs(struct cqhci_host *cq_host, u32 set)
+{
+ cqhci_writel(cq_host, set, CQHCI_ISTE);
+ cqhci_writel(cq_host, set, CQHCI_ISGE);
+}
+
+#define DRV_NAME "cqhci"
+
+#define CQHCI_DUMP(f, x...) \
+ pr_err("%s: " DRV_NAME ": " f, mmc_hostname(mmc), ## x)
+
+static void cqhci_dumpregs(struct cqhci_host *cq_host)
+{
+ struct mmc_host *mmc = cq_host->mmc;
+
+ CQHCI_DUMP("============ CQHCI REGISTER DUMP ===========\n");
+
+ CQHCI_DUMP("Caps: 0x%08x | Version: 0x%08x\n",
+ cqhci_readl(cq_host, CQHCI_CAP),
+ cqhci_readl(cq_host, CQHCI_VER));
+ CQHCI_DUMP("Config: 0x%08x | Control: 0x%08x\n",
+ cqhci_readl(cq_host, CQHCI_CFG),
+ cqhci_readl(cq_host, CQHCI_CTL));
+ CQHCI_DUMP("Int stat: 0x%08x | Int enab: 0x%08x\n",
+ cqhci_readl(cq_host, CQHCI_IS),
+ cqhci_readl(cq_host, CQHCI_ISTE));
+ CQHCI_DUMP("Int sig: 0x%08x | Int Coal: 0x%08x\n",
+ cqhci_readl(cq_host, CQHCI_ISGE),
+ cqhci_readl(cq_host, CQHCI_IC));
+ CQHCI_DUMP("TDL base: 0x%08x | TDL up32: 0x%08x\n",
+ cqhci_readl(cq_host, CQHCI_TDLBA),
+ cqhci_readl(cq_host, CQHCI_TDLBAU));
+ CQHCI_DUMP("Doorbell: 0x%08x | TCN: 0x%08x\n",
+ cqhci_readl(cq_host, CQHCI_TDBR),
+ cqhci_readl(cq_host, CQHCI_TCN));
+ CQHCI_DUMP("Dev queue: 0x%08x | Dev Pend: 0x%08x\n",
+ cqhci_readl(cq_host, CQHCI_DQS),
+ cqhci_readl(cq_host, CQHCI_DPT));
+ CQHCI_DUMP("Task clr: 0x%08x | SSC1: 0x%08x\n",
+ cqhci_readl(cq_host, CQHCI_TCLR),
+ cqhci_readl(cq_host, CQHCI_SSC1));
+ CQHCI_DUMP("SSC2: 0x%08x | DCMD rsp: 0x%08x\n",
+ cqhci_readl(cq_host, CQHCI_SSC2),
+ cqhci_readl(cq_host, CQHCI_CRDCT));
+ CQHCI_DUMP("RED mask: 0x%08x | TERRI: 0x%08x\n",
+ cqhci_readl(cq_host, CQHCI_RMEM),
+ cqhci_readl(cq_host, CQHCI_TERRI));
+ CQHCI_DUMP("Resp idx: 0x%08x | Resp arg: 0x%08x\n",
+ cqhci_readl(cq_host, CQHCI_CRI),
+ cqhci_readl(cq_host, CQHCI_CRA));
+
+ if (cq_host->ops->dumpregs)
+ cq_host->ops->dumpregs(mmc);
+ else
+ CQHCI_DUMP(": ===========================================\n");
+}
+
+/**
+ * The allocated descriptor table for task, link & transfer descritors
+ * looks like:
+ * |----------|
+ * |task desc | |->|----------|
+ * |----------| | |trans desc|
+ * |link desc-|->| |----------|
+ * |----------| .
+ * . .
+ * no. of slots max-segs
+ * . |----------|
+ * |----------|
+ * The idea here is to create the [task+trans] table and mark & point the
+ * link desc to the transfer desc table on a per slot basis.
+ */
+static int cqhci_host_alloc_tdl(struct cqhci_host *cq_host)
+{
+ int i = 0;
+
+ /* task descriptor can be 64/128 bit irrespective of arch */
+ if (cq_host->caps & CQHCI_TASK_DESC_SZ_128) {
+ cqhci_writel(cq_host, cqhci_readl(cq_host, CQHCI_CFG) |
+ CQHCI_TASK_DESC_SZ, CQHCI_CFG);
+ cq_host->task_desc_len = 16;
+ } else {
+ cq_host->task_desc_len = 8;
+ }
+
+ /*
+ * 96 bits length of transfer desc instead of 128 bits which means
+ * ADMA would expect next valid descriptor at the 96th bit
+ * or 128th bit
+ */
+ if (cq_host->dma64) {
+ if (cq_host->quirks & CQHCI_QUIRK_SHORT_TXFR_DESC_SZ)
+ cq_host->trans_desc_len = 12;
+ else
+ cq_host->trans_desc_len = 16;
+ cq_host->link_desc_len = 16;
+ } else {
+ cq_host->trans_desc_len = 8;
+ cq_host->link_desc_len = 8;
+ }
+
+ /* total size of a slot: 1 task & 1 transfer (link) */
+ cq_host->slot_sz = cq_host->task_desc_len + cq_host->link_desc_len;
+
+ cq_host->desc_size = cq_host->slot_sz * cq_host->num_slots;
+
+ cq_host->data_size = cq_host->trans_desc_len * cq_host->mmc->max_segs *
+ (cq_host->num_slots - 1);
+
+ pr_debug("%s: cqhci: desc_size: %zu data_sz: %zu slot-sz: %d\n",
+ mmc_hostname(cq_host->mmc), cq_host->desc_size, cq_host->data_size,
+ cq_host->slot_sz);
+
+ /*
+ * allocate a dma-mapped chunk of memory for the descriptors
+ * allocate a dma-mapped chunk of memory for link descriptors
+ * setup each link-desc memory offset per slot-number to
+ * the descriptor table.
+ */
+ cq_host->desc_base = dmam_alloc_coherent(mmc_dev(cq_host->mmc),
+ cq_host->desc_size,
+ &cq_host->desc_dma_base,
+ GFP_KERNEL);
+ cq_host->trans_desc_base = dmam_alloc_coherent(mmc_dev(cq_host->mmc),
+ cq_host->data_size,
+ &cq_host->trans_desc_dma_base,
+ GFP_KERNEL);
+ if (!cq_host->desc_base || !cq_host->trans_desc_base)
+ return -ENOMEM;
+
+ pr_debug("%s: cqhci: desc-base: 0x%p trans-base: 0x%p\n desc_dma 0x%llx trans_dma: 0x%llx\n",
+ mmc_hostname(cq_host->mmc), cq_host->desc_base, cq_host->trans_desc_base,
+ (unsigned long long)cq_host->desc_dma_base,
+ (unsigned long long)cq_host->trans_desc_dma_base);
+
+ for (; i < (cq_host->num_slots); i++)
+ setup_trans_desc(cq_host, i);
+
+ return 0;
+}
+
+static void __cqhci_enable(struct cqhci_host *cq_host)
+{
+ struct mmc_host *mmc = cq_host->mmc;
+ u32 cqcfg;
+
+ cqcfg = cqhci_readl(cq_host, CQHCI_CFG);
+
+ /* Configuration must not be changed while enabled */
+ if (cqcfg & CQHCI_ENABLE) {
+ cqcfg &= ~CQHCI_ENABLE;
+ cqhci_writel(cq_host, cqcfg, CQHCI_CFG);
+ }
+
+ cqcfg &= ~(CQHCI_DCMD | CQHCI_TASK_DESC_SZ);
+
+ if (mmc->caps2 & MMC_CAP2_CQE_DCMD)
+ cqcfg |= CQHCI_DCMD;
+
+ if (cq_host->caps & CQHCI_TASK_DESC_SZ_128)
+ cqcfg |= CQHCI_TASK_DESC_SZ;
+
+ cqhci_writel(cq_host, cqcfg, CQHCI_CFG);
+
+ cqhci_writel(cq_host, lower_32_bits(cq_host->desc_dma_base),
+ CQHCI_TDLBA);
+ cqhci_writel(cq_host, upper_32_bits(cq_host->desc_dma_base),
+ CQHCI_TDLBAU);
+
+ cqhci_writel(cq_host, cq_host->rca, CQHCI_SSC2);
+
+ cqhci_set_irqs(cq_host, 0);
+
+ cqcfg |= CQHCI_ENABLE;
+
+ cqhci_writel(cq_host, cqcfg, CQHCI_CFG);
+
+ /* clear halt and clear all tasks */
+ cqhci_writel(cq_host, 0, CQHCI_CTL);
+ if (cqhci_readl(cq_host, CQHCI_CTL) && CQHCI_HALT) {
+ pr_err("%s: cqhci: CQE failed to exit halt state\n",
+ mmc_hostname(mmc));
+ }
+
+ mmc->cqe_on = true;
+
+ if (cq_host->ops->enable)
+ cq_host->ops->enable(mmc);
+
+ /* Ensure all writes are done before interrupts are enabled */
+ wmb();
+
+ cqhci_set_irqs(cq_host, CQHCI_IS_MASK);
+
+ cq_host->activated = true;
+}
+
+static void __cqhci_disable(struct cqhci_host *cq_host)
+{
+ u32 cqcfg;
+
+ cqcfg = cqhci_readl(cq_host, CQHCI_CFG);
+ cqcfg &= ~CQHCI_ENABLE;
+ cqhci_writel(cq_host, cqcfg, CQHCI_CFG);
+
+ cq_host->mmc->cqe_on = false;
+
+ cq_host->activated = false;
+}
+
+int cqhci_suspend(struct mmc_host *mmc)
+{
+ struct cqhci_host *cq_host = mmc->cqe_private;
+
+ if (cq_host->enabled)
+ __cqhci_disable(cq_host);
+
+ return 0;
+}
+EXPORT_SYMBOL(cqhci_suspend);
+
+int cqhci_resume(struct mmc_host *mmc)
+{
+ /* Re-enable is done upon first request */
+ return 0;
+}
+EXPORT_SYMBOL(cqhci_resume);
+
+static int cqhci_enable(struct mmc_host *mmc, struct mmc_card *card)
+{
+ struct cqhci_host *cq_host = mmc->cqe_private;
+ int err;
+
+ if (cq_host->enabled)
+ return 0;
+
+ cq_host->rca = card->rca;
+
+ err = cqhci_host_alloc_tdl(cq_host);
+ if (err)
+ return err;
+
+ __cqhci_enable(cq_host);
+
+ cq_host->enabled = true;
+
+#ifdef DEBUG
+ cqhci_dumpregs(cq_host);
+#endif
+ return 0;
+}
+
+/* CQHCI is idle and should halt immediately, so set a small timeout */
+#define CQHCI_OFF_TIMEOUT 100
+
+static void cqhci_off(struct mmc_host *mmc)
+{
+ struct cqhci_host *cq_host = mmc->cqe_private;
+ ktime_t timeout;
+ bool timed_out;
+ u32 reg;
+
+ if (!cq_host->enabled || !mmc->cqe_on || cq_host->recovery_halt)
+ return;
+
+ if (cq_host->ops->disable)
+ cq_host->ops->disable(mmc, false);
+
+ cqhci_writel(cq_host, CQHCI_HALT, CQHCI_CTL);
+
+ timeout = ktime_add_us(ktime_get(), CQHCI_OFF_TIMEOUT);
+ while (1) {
+ timed_out = ktime_compare(ktime_get(), timeout) > 0;
+ reg = cqhci_readl(cq_host, CQHCI_CTL);
+ if ((reg & CQHCI_HALT) || timed_out)
+ break;
+ }
+
+ if (timed_out)
+ pr_err("%s: cqhci: CQE stuck on\n", mmc_hostname(mmc));
+ else
+ pr_debug("%s: cqhci: CQE off\n", mmc_hostname(mmc));
+
+ mmc->cqe_on = false;
+}
+
+static void cqhci_disable(struct mmc_host *mmc)
+{
+ struct cqhci_host *cq_host = mmc->cqe_private;
+
+ if (!cq_host->enabled)
+ return;
+
+ cqhci_off(mmc);
+
+ __cqhci_disable(cq_host);
+
+ dmam_free_coherent(mmc_dev(mmc), cq_host->data_size,
+ cq_host->trans_desc_base,
+ cq_host->trans_desc_dma_base);
+
+ dmam_free_coherent(mmc_dev(mmc), cq_host->desc_size,
+ cq_host->desc_base,
+ cq_host->desc_dma_base);
+
+ cq_host->trans_desc_base = NULL;
+ cq_host->desc_base = NULL;
+
+ cq_host->enabled = false;
+}
+
+static void cqhci_prep_task_desc(struct mmc_request *mrq,
+ u64 *data, bool intr)
+{
+ u32 req_flags = mrq->data->flags;
+
+ *data = CQHCI_VALID(1) |
+ CQHCI_END(1) |
+ CQHCI_INT(intr) |
+ CQHCI_ACT(0x5) |
+ CQHCI_FORCED_PROG(!!(req_flags & MMC_DATA_FORCED_PRG)) |
+ CQHCI_DATA_TAG(!!(req_flags & MMC_DATA_DAT_TAG)) |
+ CQHCI_DATA_DIR(!!(req_flags & MMC_DATA_READ)) |
+ CQHCI_PRIORITY(!!(req_flags & MMC_DATA_PRIO)) |
+ CQHCI_QBAR(!!(req_flags & MMC_DATA_QBR)) |
+ CQHCI_REL_WRITE(!!(req_flags & MMC_DATA_REL_WR)) |
+ CQHCI_BLK_COUNT(mrq->data->blocks) |
+ CQHCI_BLK_ADDR((u64)mrq->data->blk_addr);
+
+ pr_debug("%s: cqhci: tag %d task descriptor 0x016%llx\n",
+ mmc_hostname(mrq->host), mrq->tag, (unsigned long long)*data);
+}
+
+static int cqhci_dma_map(struct mmc_host *host, struct mmc_request *mrq)
+{
+ int sg_count;
+ struct mmc_data *data = mrq->data;
+
+ if (!data)
+ return -EINVAL;
+
+ sg_count = dma_map_sg(mmc_dev(host), data->sg,
+ data->sg_len,
+ (data->flags & MMC_DATA_WRITE) ?
+ DMA_TO_DEVICE : DMA_FROM_DEVICE);
+ if (!sg_count) {
+ pr_err("%s: sg-len: %d\n", __func__, data->sg_len);
+ return -ENOMEM;
+ }
+
+ return sg_count;
+}
+
+static void cqhci_set_tran_desc(u8 *desc, dma_addr_t addr, int len, bool end,
+ bool dma64)
+{
+ __le32 *attr = (__le32 __force *)desc;
+
+ *attr = (CQHCI_VALID(1) |
+ CQHCI_END(end ? 1 : 0) |
+ CQHCI_INT(0) |
+ CQHCI_ACT(0x4) |
+ CQHCI_DAT_LENGTH(len));
+
+ if (dma64) {
+ __le64 *dataddr = (__le64 __force *)(desc + 4);
+
+ dataddr[0] = cpu_to_le64(addr);
+ } else {
+ __le32 *dataddr = (__le32 __force *)(desc + 4);
+
+ dataddr[0] = cpu_to_le32(addr);
+ }
+}
+
+static int cqhci_prep_tran_desc(struct mmc_request *mrq,
+ struct cqhci_host *cq_host, int tag)
+{
+ struct mmc_data *data = mrq->data;
+ int i, sg_count, len;
+ bool end = false;
+ bool dma64 = cq_host->dma64;
+ dma_addr_t addr;
+ u8 *desc;
+ struct scatterlist *sg;
+
+ sg_count = cqhci_dma_map(mrq->host, mrq);
+ if (sg_count < 0) {
+ pr_err("%s: %s: unable to map sg lists, %d\n",
+ mmc_hostname(mrq->host), __func__, sg_count);
+ return sg_count;
+ }
+
+ desc = get_trans_desc(cq_host, tag);
+
+ for_each_sg(data->sg, sg, sg_count, i) {
+ addr = sg_dma_address(sg);
+ len = sg_dma_len(sg);
+
+ if ((i+1) == sg_count)
+ end = true;
+ cqhci_set_tran_desc(desc, addr, len, end, dma64);
+ desc += cq_host->trans_desc_len;
+ }
+
+ return 0;
+}
+
+static void cqhci_prep_dcmd_desc(struct mmc_host *mmc,
+ struct mmc_request *mrq)
+{
+ u64 *task_desc = NULL;
+ u64 data = 0;
+ u8 resp_type;
+ u8 *desc;
+ __le64 *dataddr;
+ struct cqhci_host *cq_host = mmc->cqe_private;
+ u8 timing;
+
+ if (!(mrq->cmd->flags & MMC_RSP_PRESENT)) {
+ resp_type = 0x0;
+ timing = 0x1;
+ } else {
+ if (mrq->cmd->flags & MMC_RSP_R1B) {
+ resp_type = 0x3;
+ timing = 0x0;
+ } else {
+ resp_type = 0x2;
+ timing = 0x1;
+ }
+ }
+
+ task_desc = (__le64 __force *)get_desc(cq_host, cq_host->dcmd_slot);
+ memset(task_desc, 0, cq_host->task_desc_len);
+ data |= (CQHCI_VALID(1) |
+ CQHCI_END(1) |
+ CQHCI_INT(1) |
+ CQHCI_QBAR(1) |
+ CQHCI_ACT(0x5) |
+ CQHCI_CMD_INDEX(mrq->cmd->opcode) |
+ CQHCI_CMD_TIMING(timing) | CQHCI_RESP_TYPE(resp_type));
+ *task_desc |= data;
+ desc = (u8 *)task_desc;
+ pr_debug("%s: cqhci: dcmd: cmd: %d timing: %d resp: %d\n",
+ mmc_hostname(mmc), mrq->cmd->opcode, timing, resp_type);
+ dataddr = (__le64 __force *)(desc + 4);
+ dataddr[0] = cpu_to_le64((u64)mrq->cmd->arg);
+
+}
+
+static void cqhci_post_req(struct mmc_host *host, struct mmc_request *mrq)
+{
+ struct mmc_data *data = mrq->data;
+
+ if (data) {
+ dma_unmap_sg(mmc_dev(host), data->sg, data->sg_len,
+ (data->flags & MMC_DATA_READ) ?
+ DMA_FROM_DEVICE : DMA_TO_DEVICE);
+ }
+}
+
+static inline int cqhci_tag(struct mmc_request *mrq)
+{
+ return mrq->cmd ? DCMD_SLOT : mrq->tag;
+}
+
+static int cqhci_request(struct mmc_host *mmc, struct mmc_request *mrq)
+{
+ int err = 0;
+ u64 data = 0;
+ u64 *task_desc = NULL;
+ int tag = cqhci_tag(mrq);
+ struct cqhci_host *cq_host = mmc->cqe_private;
+ unsigned long flags;
+
+ if (!cq_host->enabled) {
+ pr_err("%s: cqhci: not enabled\n", mmc_hostname(mmc));
+ return -EINVAL;
+ }
+
+ /* First request after resume has to re-enable */
+ if (!cq_host->activated)
+ __cqhci_enable(cq_host);
+
+ if (!mmc->cqe_on) {
+ cqhci_writel(cq_host, 0, CQHCI_CTL);
+ mmc->cqe_on = true;
+ pr_debug("%s: cqhci: CQE on\n", mmc_hostname(mmc));
+ if (cqhci_readl(cq_host, CQHCI_CTL) && CQHCI_HALT) {
+ pr_err("%s: cqhci: CQE failed to exit halt state\n",
+ mmc_hostname(mmc));
+ }
+ if (cq_host->ops->enable)
+ cq_host->ops->enable(mmc);
+ }
+
+ if (mrq->data) {
+ task_desc = (__le64 __force *)get_desc(cq_host, tag);
+ cqhci_prep_task_desc(mrq, &data, 1);
+ *task_desc = cpu_to_le64(data);
+ err = cqhci_prep_tran_desc(mrq, cq_host, tag);
+ if (err) {
+ pr_err("%s: cqhci: failed to setup tx desc: %d\n",
+ mmc_hostname(mmc), err);
+ return err;
+ }
+ } else {
+ cqhci_prep_dcmd_desc(mmc, mrq);
+ }
+
+ spin_lock_irqsave(&cq_host->lock, flags);
+
+ if (cq_host->recovery_halt) {
+ err = -EBUSY;
+ goto out_unlock;
+ }
+
+ cq_host->slot[tag].mrq = mrq;
+ cq_host->slot[tag].flags = 0;
+
+ cq_host->qcnt += 1;
+
+ cqhci_writel(cq_host, 1 << tag, CQHCI_TDBR);
+ if (!(cqhci_readl(cq_host, CQHCI_TDBR) & (1 << tag)))
+ pr_debug("%s: cqhci: doorbell not set for tag %d\n",
+ mmc_hostname(mmc), tag);
+out_unlock:
+ spin_unlock_irqrestore(&cq_host->lock, flags);
+
+ if (err)
+ cqhci_post_req(mmc, mrq);
+
+ return err;
+}
+
+static void cqhci_recovery_needed(struct mmc_host *mmc, struct mmc_request *mrq,
+ bool notify)
+{
+ struct cqhci_host *cq_host = mmc->cqe_private;
+
+ if (!cq_host->recovery_halt) {
+ cq_host->recovery_halt = true;
+ pr_debug("%s: cqhci: recovery needed\n", mmc_hostname(mmc));
+ wake_up(&cq_host->wait_queue);
+ if (notify && mrq->recovery_notifier)
+ mrq->recovery_notifier(mrq);
+ }
+}
+
+static unsigned int cqhci_error_flags(int error1, int error2)
+{
+ int error = error1 ? error1 : error2;
+
+ switch (error) {
+ case -EILSEQ:
+ return CQHCI_HOST_CRC;
+ case -ETIMEDOUT:
+ return CQHCI_HOST_TIMEOUT;
+ default:
+ return CQHCI_HOST_OTHER;
+ }
+}
+
+static void cqhci_error_irq(struct mmc_host *mmc, u32 status, int cmd_error,
+ int data_error)
+{
+ struct cqhci_host *cq_host = mmc->cqe_private;
+ struct cqhci_slot *slot;
+ u32 terri;
+ int tag;
+
+ spin_lock(&cq_host->lock);
+
+ terri = cqhci_readl(cq_host, CQHCI_TERRI);
+
+ pr_debug("%s: cqhci: error IRQ status: 0x%08x cmd error %d data error %d TERRI: 0x%08x\n",
+ mmc_hostname(mmc), status, cmd_error, data_error, terri);
+
+ /* Forget about errors when recovery has already been triggered */
+ if (cq_host->recovery_halt)
+ goto out_unlock;
+
+ if (!cq_host->qcnt) {
+ WARN_ONCE(1, "%s: cqhci: error when idle. IRQ status: 0x%08x cmd error %d data error %d TERRI: 0x%08x\n",
+ mmc_hostname(mmc), status, cmd_error, data_error,
+ terri);
+ goto out_unlock;
+ }
+
+ if (CQHCI_TERRI_C_VALID(terri)) {
+ tag = CQHCI_TERRI_C_TASK(terri);
+ slot = &cq_host->slot[tag];
+ if (slot->mrq) {
+ slot->flags = cqhci_error_flags(cmd_error, data_error);
+ cqhci_recovery_needed(mmc, slot->mrq, true);
+ }
+ }
+
+ if (CQHCI_TERRI_D_VALID(terri)) {
+ tag = CQHCI_TERRI_D_TASK(terri);
+ slot = &cq_host->slot[tag];
+ if (slot->mrq) {
+ slot->flags = cqhci_error_flags(data_error, cmd_error);
+ cqhci_recovery_needed(mmc, slot->mrq, true);
+ }
+ }
+
+ if (!cq_host->recovery_halt) {
+ /*
+ * The only way to guarantee forward progress is to mark at
+ * least one task in error, so if none is indicated, pick one.
+ */
+ for (tag = 0; tag < NUM_SLOTS; tag++) {
+ slot = &cq_host->slot[tag];
+ if (!slot->mrq)
+ continue;
+ slot->flags = cqhci_error_flags(data_error, cmd_error);
+ cqhci_recovery_needed(mmc, slot->mrq, true);
+ break;
+ }
+ }
+
+out_unlock:
+ spin_unlock(&cq_host->lock);
+}
+
+static void cqhci_finish_mrq(struct mmc_host *mmc, unsigned int tag)
+{
+ struct cqhci_host *cq_host = mmc->cqe_private;
+ struct cqhci_slot *slot = &cq_host->slot[tag];
+ struct mmc_request *mrq = slot->mrq;
+ struct mmc_data *data;
+
+ if (!mrq) {
+ WARN_ONCE(1, "%s: cqhci: spurious TCN for tag %d\n",
+ mmc_hostname(mmc), tag);
+ return;
+ }
+
+ /* No completions allowed during recovery */
+ if (cq_host->recovery_halt) {
+ slot->flags |= CQHCI_COMPLETED;
+ return;
+ }
+
+ slot->mrq = NULL;
+
+ cq_host->qcnt -= 1;
+
+ data = mrq->data;
+ if (data) {
+ if (data->error)
+ data->bytes_xfered = 0;
+ else
+ data->bytes_xfered = data->blksz * data->blocks;
+ }
+
+ mmc_cqe_request_done(mmc, mrq);
+}
+
+irqreturn_t cqhci_irq(struct mmc_host *mmc, u32 intmask, int cmd_error,
+ int data_error)
+{
+ u32 status;
+ unsigned long tag = 0, comp_status;
+ struct cqhci_host *cq_host = mmc->cqe_private;
+
+ status = cqhci_readl(cq_host, CQHCI_IS);
+ cqhci_writel(cq_host, status, CQHCI_IS);
+
+ pr_debug("%s: cqhci: IRQ status: 0x%08x\n", mmc_hostname(mmc), status);
+
+ if ((status & CQHCI_IS_RED) || cmd_error || data_error)
+ cqhci_error_irq(mmc, status, cmd_error, data_error);
+
+ if (status & CQHCI_IS_TCC) {
+ /* read TCN and complete the request */
+ comp_status = cqhci_readl(cq_host, CQHCI_TCN);
+ cqhci_writel(cq_host, comp_status, CQHCI_TCN);
+ pr_debug("%s: cqhci: TCN: 0x%08lx\n",
+ mmc_hostname(mmc), comp_status);
+
+ spin_lock(&cq_host->lock);
+
+ for_each_set_bit(tag, &comp_status, cq_host->num_slots) {
+ /* complete the corresponding mrq */
+ pr_debug("%s: cqhci: completing tag %lu\n",
+ mmc_hostname(mmc), tag);
+ cqhci_finish_mrq(mmc, tag);
+ }
+
+ if (cq_host->waiting_for_idle && !cq_host->qcnt) {
+ cq_host->waiting_for_idle = false;
+ wake_up(&cq_host->wait_queue);
+ }
+
+ spin_unlock(&cq_host->lock);
+ }
+
+ if (status & CQHCI_IS_TCL)
+ wake_up(&cq_host->wait_queue);
+
+ if (status & CQHCI_IS_HAC)
+ wake_up(&cq_host->wait_queue);
+
+ return IRQ_HANDLED;
+}
+EXPORT_SYMBOL(cqhci_irq);
+
+static bool cqhci_is_idle(struct cqhci_host *cq_host, int *ret)
+{
+ unsigned long flags;
+ bool is_idle;
+
+ spin_lock_irqsave(&cq_host->lock, flags);
+ is_idle = !cq_host->qcnt || cq_host->recovery_halt;
+ *ret = cq_host->recovery_halt ? -EBUSY : 0;
+ cq_host->waiting_for_idle = !is_idle;
+ spin_unlock_irqrestore(&cq_host->lock, flags);
+
+ return is_idle;
+}
+
+static int cqhci_wait_for_idle(struct mmc_host *mmc)
+{
+ struct cqhci_host *cq_host = mmc->cqe_private;
+ int ret;
+
+ wait_event(cq_host->wait_queue, cqhci_is_idle(cq_host, &ret));
+
+ return ret;
+}
+
+static bool cqhci_timeout(struct mmc_host *mmc, struct mmc_request *mrq,
+ bool *recovery_needed)
+{
+ struct cqhci_host *cq_host = mmc->cqe_private;
+ int tag = cqhci_tag(mrq);
+ struct cqhci_slot *slot = &cq_host->slot[tag];
+ unsigned long flags;
+ bool timed_out;
+
+ spin_lock_irqsave(&cq_host->lock, flags);
+ timed_out = slot->mrq == mrq;
+ if (timed_out) {
+ slot->flags |= CQHCI_EXTERNAL_TIMEOUT;
+ cqhci_recovery_needed(mmc, mrq, false);
+ *recovery_needed = cq_host->recovery_halt;
+ }
+ spin_unlock_irqrestore(&cq_host->lock, flags);
+
+ if (timed_out) {
+ pr_err("%s: cqhci: timeout for tag %d\n",
+ mmc_hostname(mmc), tag);
+ cqhci_dumpregs(cq_host);
+ }
+
+ return timed_out;
+}
+
+static bool cqhci_tasks_cleared(struct cqhci_host *cq_host)
+{
+ return !(cqhci_readl(cq_host, CQHCI_CTL) & CQHCI_CLEAR_ALL_TASKS);
+}
+
+static bool cqhci_clear_all_tasks(struct mmc_host *mmc, unsigned int timeout)
+{
+ struct cqhci_host *cq_host = mmc->cqe_private;
+ bool ret;
+ u32 ctl;
+
+ cqhci_set_irqs(cq_host, CQHCI_IS_TCL);
+
+ ctl = cqhci_readl(cq_host, CQHCI_CTL);
+ ctl |= CQHCI_CLEAR_ALL_TASKS;
+ cqhci_writel(cq_host, ctl, CQHCI_CTL);
+
+ wait_event_timeout(cq_host->wait_queue, cqhci_tasks_cleared(cq_host),
+ msecs_to_jiffies(timeout) + 1);
+
+ cqhci_set_irqs(cq_host, 0);
+
+ ret = cqhci_tasks_cleared(cq_host);
+
+ if (!ret)
+ pr_debug("%s: cqhci: Failed to clear tasks\n",
+ mmc_hostname(mmc));
+
+ return ret;
+}
+
+static bool cqhci_halted(struct cqhci_host *cq_host)
+{
+ return cqhci_readl(cq_host, CQHCI_CTL) & CQHCI_HALT;
+}
+
+static bool cqhci_halt(struct mmc_host *mmc, unsigned int timeout)
+{
+ struct cqhci_host *cq_host = mmc->cqe_private;
+ bool ret;
+ u32 ctl;
+
+ if (cqhci_halted(cq_host))
+ return true;
+
+ cqhci_set_irqs(cq_host, CQHCI_IS_HAC);
+
+ ctl = cqhci_readl(cq_host, CQHCI_CTL);
+ ctl |= CQHCI_HALT;
+ cqhci_writel(cq_host, ctl, CQHCI_CTL);
+
+ wait_event_timeout(cq_host->wait_queue, cqhci_halted(cq_host),
+ msecs_to_jiffies(timeout) + 1);
+
+ cqhci_set_irqs(cq_host, 0);
+
+ ret = cqhci_halted(cq_host);
+
+ if (!ret)
+ pr_debug("%s: cqhci: Failed to halt\n", mmc_hostname(mmc));
+
+ return ret;
+}
+
+/*
+ * After halting we expect to be able to use the command line. We interpret the
+ * failure to halt to mean the data lines might still be in use (and the upper
+ * layers will need to send a STOP command), so we set the timeout based on a
+ * generous command timeout.
+ */
+#define CQHCI_START_HALT_TIMEOUT 5
+
+static void cqhci_recovery_start(struct mmc_host *mmc)
+{
+ struct cqhci_host *cq_host = mmc->cqe_private;
+
+ pr_debug("%s: cqhci: %s\n", mmc_hostname(mmc), __func__);
+
+ WARN_ON(!cq_host->recovery_halt);
+
+ cqhci_halt(mmc, CQHCI_START_HALT_TIMEOUT);
+
+ if (cq_host->ops->disable)
+ cq_host->ops->disable(mmc, true);
+
+ mmc->cqe_on = false;
+}
+
+static int cqhci_error_from_flags(unsigned int flags)
+{
+ if (!flags)
+ return 0;
+
+ /* CRC errors might indicate re-tuning so prefer to report that */
+ if (flags & CQHCI_HOST_CRC)
+ return -EILSEQ;
+
+ if (flags & (CQHCI_EXTERNAL_TIMEOUT | CQHCI_HOST_TIMEOUT))
+ return -ETIMEDOUT;
+
+ return -EIO;
+}
+
+static void cqhci_recover_mrq(struct cqhci_host *cq_host, unsigned int tag)
+{
+ struct cqhci_slot *slot = &cq_host->slot[tag];
+ struct mmc_request *mrq = slot->mrq;
+ struct mmc_data *data;
+
+ if (!mrq)
+ return;
+
+ slot->mrq = NULL;
+
+ cq_host->qcnt -= 1;
+
+ data = mrq->data;
+ if (data) {
+ data->bytes_xfered = 0;
+ data->error = cqhci_error_from_flags(slot->flags);
+ } else {
+ mrq->cmd->error = cqhci_error_from_flags(slot->flags);
+ }
+
+ mmc_cqe_request_done(cq_host->mmc, mrq);
+}
+
+static void cqhci_recover_mrqs(struct cqhci_host *cq_host)
+{
+ int i;
+
+ for (i = 0; i < cq_host->num_slots; i++)
+ cqhci_recover_mrq(cq_host, i);
+}
+
+/*
+ * By now the command and data lines should be unused so there is no reason for
+ * CQHCI to take a long time to halt, but if it doesn't halt there could be
+ * problems clearing tasks, so be generous.
+ */
+#define CQHCI_FINISH_HALT_TIMEOUT 20
+
+/* CQHCI could be expected to clear it's internal state pretty quickly */
+#define CQHCI_CLEAR_TIMEOUT 20
+
+static void cqhci_recovery_finish(struct mmc_host *mmc)
+{
+ struct cqhci_host *cq_host = mmc->cqe_private;
+ unsigned long flags;
+ u32 cqcfg;
+ bool ok;
+
+ pr_debug("%s: cqhci: %s\n", mmc_hostname(mmc), __func__);
+
+ WARN_ON(!cq_host->recovery_halt);
+
+ ok = cqhci_halt(mmc, CQHCI_FINISH_HALT_TIMEOUT);
+
+ if (!cqhci_clear_all_tasks(mmc, CQHCI_CLEAR_TIMEOUT))
+ ok = false;
+
+ /*
+ * The specification contradicts itself, by saying that tasks cannot be
+ * cleared if CQHCI does not halt, but if CQHCI does not halt, it should
+ * be disabled/re-enabled, but not to disable before clearing tasks.
+ * Have a go anyway.
+ */
+ if (!ok) {
+ pr_debug("%s: cqhci: disable / re-enable\n", mmc_hostname(mmc));
+ cqcfg = cqhci_readl(cq_host, CQHCI_CFG);
+ cqcfg &= ~CQHCI_ENABLE;
+ cqhci_writel(cq_host, cqcfg, CQHCI_CFG);
+ cqcfg |= CQHCI_ENABLE;
+ cqhci_writel(cq_host, cqcfg, CQHCI_CFG);
+ /* Be sure that there are no tasks */
+ ok = cqhci_halt(mmc, CQHCI_FINISH_HALT_TIMEOUT);
+ if (!cqhci_clear_all_tasks(mmc, CQHCI_CLEAR_TIMEOUT))
+ ok = false;
+ WARN_ON(!ok);
+ }
+
+ cqhci_recover_mrqs(cq_host);
+
+ WARN_ON(cq_host->qcnt);
+
+ spin_lock_irqsave(&cq_host->lock, flags);
+ cq_host->qcnt = 0;
+ cq_host->recovery_halt = false;
+ mmc->cqe_on = false;
+ spin_unlock_irqrestore(&cq_host->lock, flags);
+
+ /* Ensure all writes are done before interrupts are re-enabled */
+ wmb();
+
+ cqhci_writel(cq_host, CQHCI_IS_HAC | CQHCI_IS_TCL, CQHCI_IS);
+
+ cqhci_set_irqs(cq_host, CQHCI_IS_MASK);
+
+ pr_debug("%s: cqhci: recovery done\n", mmc_hostname(mmc));
+}
+
+static const struct mmc_cqe_ops cqhci_cqe_ops = {
+ .cqe_enable = cqhci_enable,
+ .cqe_disable = cqhci_disable,
+ .cqe_request = cqhci_request,
+ .cqe_post_req = cqhci_post_req,
+ .cqe_off = cqhci_off,
+ .cqe_wait_for_idle = cqhci_wait_for_idle,
+ .cqe_timeout = cqhci_timeout,
+ .cqe_recovery_start = cqhci_recovery_start,
+ .cqe_recovery_finish = cqhci_recovery_finish,
+};
+
+struct cqhci_host *cqhci_pltfm_init(struct platform_device *pdev)
+{
+ struct cqhci_host *cq_host;
+ struct resource *cqhci_memres = NULL;
+
+ /* check and setup CMDQ interface */
+ cqhci_memres = platform_get_resource_byname(pdev, IORESOURCE_MEM,
+ "cqhci_mem");
+ if (!cqhci_memres) {
+ dev_dbg(&pdev->dev, "CMDQ not supported\n");
+ return ERR_PTR(-EINVAL);
+ }
+
+ cq_host = devm_kzalloc(&pdev->dev, sizeof(*cq_host), GFP_KERNEL);
+ if (!cq_host)
+ return ERR_PTR(-ENOMEM);
+ cq_host->mmio = devm_ioremap(&pdev->dev,
+ cqhci_memres->start,
+ resource_size(cqhci_memres));
+ if (!cq_host->mmio) {
+ dev_err(&pdev->dev, "failed to remap cqhci regs\n");
+ return ERR_PTR(-EBUSY);
+ }
+ dev_dbg(&pdev->dev, "CMDQ ioremap: done\n");
+
+ return cq_host;
+}
+EXPORT_SYMBOL(cqhci_pltfm_init);
+
+static unsigned int cqhci_ver_major(struct cqhci_host *cq_host)
+{
+ return CQHCI_VER_MAJOR(cqhci_readl(cq_host, CQHCI_VER));
+}
+
+static unsigned int cqhci_ver_minor(struct cqhci_host *cq_host)
+{
+ u32 ver = cqhci_readl(cq_host, CQHCI_VER);
+
+ return CQHCI_VER_MINOR1(ver) * 10 + CQHCI_VER_MINOR2(ver);
+}
+
+int cqhci_init(struct cqhci_host *cq_host, struct mmc_host *mmc,
+ bool dma64)
+{
+ int err;
+
+ cq_host->dma64 = dma64;
+ cq_host->mmc = mmc;
+ cq_host->mmc->cqe_private = cq_host;
+
+ cq_host->num_slots = NUM_SLOTS;
+ cq_host->dcmd_slot = DCMD_SLOT;
+
+ mmc->cqe_ops = &cqhci_cqe_ops;
+
+ mmc->cqe_qdepth = NUM_SLOTS;
+ if (mmc->caps2 & MMC_CAP2_CQE_DCMD)
+ mmc->cqe_qdepth -= 1;
+
+ cq_host->slot = devm_kcalloc(mmc_dev(mmc), cq_host->num_slots,
+ sizeof(*cq_host->slot), GFP_KERNEL);
+ if (!cq_host->slot) {
+ err = -ENOMEM;
+ goto out_err;
+ }
+
+ spin_lock_init(&cq_host->lock);
+
+ init_completion(&cq_host->halt_comp);
+ init_waitqueue_head(&cq_host->wait_queue);
+
+ pr_info("%s: CQHCI version %u.%02u\n",
+ mmc_hostname(mmc), cqhci_ver_major(cq_host),
+ cqhci_ver_minor(cq_host));
+
+ return 0;
+
+out_err:
+ pr_err("%s: CQHCI version %u.%02u failed to initialize, error %d\n",
+ mmc_hostname(mmc), cqhci_ver_major(cq_host),
+ cqhci_ver_minor(cq_host), err);
+ return err;
+}
+EXPORT_SYMBOL(cqhci_init);
+
+MODULE_AUTHOR("Venkat Gopalakrishnan <venkatg@codeaurora.org>");
+MODULE_DESCRIPTION("Command Queue Host Controller Interface driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/mmc/host/cqhci.h b/drivers/mmc/host/cqhci.h
new file mode 100644
index 000000000000..2d39d361b322
--- /dev/null
+++ b/drivers/mmc/host/cqhci.h
@@ -0,0 +1,240 @@
+/* Copyright (c) 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 LINUX_MMC_CQHCI_H
+#define LINUX_MMC_CQHCI_H
+
+#include <linux/compiler.h>
+#include <linux/bitops.h>
+#include <linux/spinlock_types.h>
+#include <linux/types.h>
+#include <linux/completion.h>
+#include <linux/wait.h>
+#include <linux/irqreturn.h>
+#include <asm/io.h>
+
+/* registers */
+/* version */
+#define CQHCI_VER 0x00
+#define CQHCI_VER_MAJOR(x) (((x) & GENMASK(11, 8)) >> 8)
+#define CQHCI_VER_MINOR1(x) (((x) & GENMASK(7, 4)) >> 4)
+#define CQHCI_VER_MINOR2(x) ((x) & GENMASK(3, 0))
+
+/* capabilities */
+#define CQHCI_CAP 0x04
+/* configuration */
+#define CQHCI_CFG 0x08
+#define CQHCI_DCMD 0x00001000
+#define CQHCI_TASK_DESC_SZ 0x00000100
+#define CQHCI_ENABLE 0x00000001
+
+/* control */
+#define CQHCI_CTL 0x0C
+#define CQHCI_CLEAR_ALL_TASKS 0x00000100
+#define CQHCI_HALT 0x00000001
+
+/* interrupt status */
+#define CQHCI_IS 0x10
+#define CQHCI_IS_HAC BIT(0)
+#define CQHCI_IS_TCC BIT(1)
+#define CQHCI_IS_RED BIT(2)
+#define CQHCI_IS_TCL BIT(3)
+
+#define CQHCI_IS_MASK (CQHCI_IS_TCC | CQHCI_IS_RED)
+
+/* interrupt status enable */
+#define CQHCI_ISTE 0x14
+
+/* interrupt signal enable */
+#define CQHCI_ISGE 0x18
+
+/* interrupt coalescing */
+#define CQHCI_IC 0x1C
+#define CQHCI_IC_ENABLE BIT(31)
+#define CQHCI_IC_RESET BIT(16)
+#define CQHCI_IC_ICCTHWEN BIT(15)
+#define CQHCI_IC_ICCTH(x) ((x & 0x1F) << 8)
+#define CQHCI_IC_ICTOVALWEN BIT(7)
+#define CQHCI_IC_ICTOVAL(x) (x & 0x7F)
+
+/* task list base address */
+#define CQHCI_TDLBA 0x20
+
+/* task list base address upper */
+#define CQHCI_TDLBAU 0x24
+
+/* door-bell */
+#define CQHCI_TDBR 0x28
+
+/* task completion notification */
+#define CQHCI_TCN 0x2C
+
+/* device queue status */
+#define CQHCI_DQS 0x30
+
+/* device pending tasks */
+#define CQHCI_DPT 0x34
+
+/* task clear */
+#define CQHCI_TCLR 0x38
+
+/* send status config 1 */
+#define CQHCI_SSC1 0x40
+
+/* send status config 2 */
+#define CQHCI_SSC2 0x44
+
+/* response for dcmd */
+#define CQHCI_CRDCT 0x48
+
+/* response mode error mask */
+#define CQHCI_RMEM 0x50
+
+/* task error info */
+#define CQHCI_TERRI 0x54
+
+#define CQHCI_TERRI_C_INDEX(x) ((x) & GENMASK(5, 0))
+#define CQHCI_TERRI_C_TASK(x) (((x) & GENMASK(12, 8)) >> 8)
+#define CQHCI_TERRI_C_VALID(x) ((x) & BIT(15))
+#define CQHCI_TERRI_D_INDEX(x) (((x) & GENMASK(21, 16)) >> 16)
+#define CQHCI_TERRI_D_TASK(x) (((x) & GENMASK(28, 24)) >> 24)
+#define CQHCI_TERRI_D_VALID(x) ((x) & BIT(31))
+
+/* command response index */
+#define CQHCI_CRI 0x58
+
+/* command response argument */
+#define CQHCI_CRA 0x5C
+
+#define CQHCI_INT_ALL 0xF
+#define CQHCI_IC_DEFAULT_ICCTH 31
+#define CQHCI_IC_DEFAULT_ICTOVAL 1
+
+/* attribute fields */
+#define CQHCI_VALID(x) ((x & 1) << 0)
+#define CQHCI_END(x) ((x & 1) << 1)
+#define CQHCI_INT(x) ((x & 1) << 2)
+#define CQHCI_ACT(x) ((x & 0x7) << 3)
+
+/* data command task descriptor fields */
+#define CQHCI_FORCED_PROG(x) ((x & 1) << 6)
+#define CQHCI_CONTEXT(x) ((x & 0xF) << 7)
+#define CQHCI_DATA_TAG(x) ((x & 1) << 11)
+#define CQHCI_DATA_DIR(x) ((x & 1) << 12)
+#define CQHCI_PRIORITY(x) ((x & 1) << 13)
+#define CQHCI_QBAR(x) ((x & 1) << 14)
+#define CQHCI_REL_WRITE(x) ((x & 1) << 15)
+#define CQHCI_BLK_COUNT(x) ((x & 0xFFFF) << 16)
+#define CQHCI_BLK_ADDR(x) ((x & 0xFFFFFFFF) << 32)
+
+/* direct command task descriptor fields */
+#define CQHCI_CMD_INDEX(x) ((x & 0x3F) << 16)
+#define CQHCI_CMD_TIMING(x) ((x & 1) << 22)
+#define CQHCI_RESP_TYPE(x) ((x & 0x3) << 23)
+
+/* transfer descriptor fields */
+#define CQHCI_DAT_LENGTH(x) ((x & 0xFFFF) << 16)
+#define CQHCI_DAT_ADDR_LO(x) ((x & 0xFFFFFFFF) << 32)
+#define CQHCI_DAT_ADDR_HI(x) ((x & 0xFFFFFFFF) << 0)
+
+struct cqhci_host_ops;
+struct mmc_host;
+struct cqhci_slot;
+
+struct cqhci_host {
+ const struct cqhci_host_ops *ops;
+ void __iomem *mmio;
+ struct mmc_host *mmc;
+
+ spinlock_t lock;
+
+ /* relative card address of device */
+ unsigned int rca;
+
+ /* 64 bit DMA */
+ bool dma64;
+ int num_slots;
+ int qcnt;
+
+ u32 dcmd_slot;
+ u32 caps;
+#define CQHCI_TASK_DESC_SZ_128 0x1
+
+ u32 quirks;
+#define CQHCI_QUIRK_SHORT_TXFR_DESC_SZ 0x1
+
+ bool enabled;
+ bool halted;
+ bool init_done;
+ bool activated;
+ bool waiting_for_idle;
+ bool recovery_halt;
+
+ size_t desc_size;
+ size_t data_size;
+
+ u8 *desc_base;
+
+ /* total descriptor size */
+ u8 slot_sz;
+
+ /* 64/128 bit depends on CQHCI_CFG */
+ u8 task_desc_len;
+
+ /* 64 bit on 32-bit arch, 128 bit on 64-bit */
+ u8 link_desc_len;
+
+ u8 *trans_desc_base;
+ /* same length as transfer descriptor */
+ u8 trans_desc_len;
+
+ dma_addr_t desc_dma_base;
+ dma_addr_t trans_desc_dma_base;
+
+ struct completion halt_comp;
+ wait_queue_head_t wait_queue;
+ struct cqhci_slot *slot;
+};
+
+struct cqhci_host_ops {
+ void (*dumpregs)(struct mmc_host *mmc);
+ void (*write_l)(struct cqhci_host *host, u32 val, int reg);
+ u32 (*read_l)(struct cqhci_host *host, int reg);
+ void (*enable)(struct mmc_host *mmc);
+ void (*disable)(struct mmc_host *mmc, bool recovery);
+};
+
+static inline void cqhci_writel(struct cqhci_host *host, u32 val, int reg)
+{
+ if (unlikely(host->ops->write_l))
+ host->ops->write_l(host, val, reg);
+ else
+ writel_relaxed(val, host->mmio + reg);
+}
+
+static inline u32 cqhci_readl(struct cqhci_host *host, int reg)
+{
+ if (unlikely(host->ops->read_l))
+ return host->ops->read_l(host, reg);
+ else
+ return readl_relaxed(host->mmio + reg);
+}
+
+struct platform_device;
+
+irqreturn_t cqhci_irq(struct mmc_host *mmc, u32 intmask, int cmd_error,
+ int data_error);
+int cqhci_init(struct cqhci_host *cq_host, struct mmc_host *mmc, bool dma64);
+struct cqhci_host *cqhci_pltfm_init(struct platform_device *pdev);
+int cqhci_suspend(struct mmc_host *mmc);
+int cqhci_resume(struct mmc_host *mmc);
+
+#endif
diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
index 8c0b80a54e4d..9668dbfe6576 100644
--- a/drivers/mmc/host/sdhci-esdhc-imx.c
+++ b/drivers/mmc/host/sdhci-esdhc-imx.c
@@ -6,17 +6,21 @@
* Copyright (c) 2010 Pengutronix e.K.
* Author: Wolfram Sang <kernel@pengutronix.de>
*
+ * Copyright 2019 NXP
+ *
* 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/busfreq-imx.h>
#include <linux/io.h>
#include <linux/delay.h>
#include <linux/err.h>
#include <linux/clk.h>
#include <linux/gpio.h>
#include <linux/module.h>
+#include <linux/pm_qos.h>
#include <linux/slab.h>
#include <linux/mmc/host.h>
#include <linux/mmc/mmc.h>
@@ -30,6 +34,7 @@
#include <linux/pm_runtime.h>
#include "sdhci-pltfm.h"
#include "sdhci-esdhc.h"
+#include "cqhci.h"
#define ESDHC_SYS_CTRL_DTOCV_MASK 0x0f
#define ESDHC_CTRL_D3CD 0x08
@@ -49,6 +54,7 @@
#define ESDHC_MIX_CTRL_AUTO_TUNE_EN (1 << 24)
#define ESDHC_MIX_CTRL_FBCLK_SEL (1 << 25)
#define ESDHC_MIX_CTRL_HS400_EN (1 << 26)
+#define ESDHC_MIX_CTRL_HS400_ES (1 << 27)
/* Bits 3 and 6 are not SDHCI standard definitions */
#define ESDHC_MIX_CTRL_SDHCI_MASK 0xb7
/* Tuning bits */
@@ -69,12 +75,17 @@
#define ESDHC_STROBE_DLL_CTRL 0x70
#define ESDHC_STROBE_DLL_CTRL_ENABLE (1 << 0)
#define ESDHC_STROBE_DLL_CTRL_RESET (1 << 1)
+#define ESDHC_STROBE_DLL_CTRL_SLV_DLY_TARGET_DEFAULT 0x7
#define ESDHC_STROBE_DLL_CTRL_SLV_DLY_TARGET_SHIFT 3
+#define ESDHC_STROBE_DLL_CTRL_SLV_UPDATE_INT_DEFAULT (4 << 20)
#define ESDHC_STROBE_DLL_STATUS 0x74
#define ESDHC_STROBE_DLL_STS_REF_LOCK (1 << 1)
#define ESDHC_STROBE_DLL_STS_SLV_LOCK 0x1
+#define ESDHC_VEND_SPEC2 0xc8
+#define ESDHC_VEND_SPEC2_EN_BUSY_IRQ (1 << 8)
+
#define ESDHC_TUNING_CTRL 0xcc
#define ESDHC_STD_TUNING_EN (1 << 24)
/* NOTE: the minimum valid tuning start tap for mx6sl is 1 */
@@ -102,6 +113,9 @@
*/
#define ESDHC_INT_VENDOR_SPEC_DMA_ERR (1 << 28)
+/* the address offset of CQHCI */
+#define ESDHC_CQHCI_ADDR_OFFSET 0x100
+
/*
* The CMDTYPE of the CMD register (offset 0xE) should be set to
* "11" when the STOP CMD12 is issued on imx53 to abort one
@@ -138,8 +152,37 @@
/* The IP supports HS400 mode */
#define ESDHC_FLAG_HS400 BIT(9)
-/* A clock frequency higher than this rate requires strobe dll control */
-#define ESDHC_STROBE_DLL_CLK_FREQ 100000000
+/* The IP state got lost in low power mode */
+#define ESDHC_FLAG_STATE_LOST_IN_LPMODE BIT(10)
+
+/* The IP has errata ERR010450
+ * uSDHC: Due to the I/O timing limit, for SDR mode, SD card clock can't
+ * exceed 150MHz, for DDR mode, SD card clock can't exceed 45MHz.
+ */
+#define ESDHC_FLAG_ERR010450 BIT(11)
+/* need request bus freq during low power */
+#define ESDHC_FLAG_BUSFREQ BIT(12)
+/* need request pmqos during low power */
+#define ESDHC_FLAG_PMQOS BIT(13)
+/* The IP supports HS400ES mode */
+#define ESDHC_FLAG_HS400_ES BIT(14)
+/* The IP lost clock rate in PM_RUNTIME */
+#define ESDHC_FLAG_CLK_RATE_LOST_IN_PM_RUNTIME BIT(15)
+/* The IP has Host Controller Interface for Command Queuing */
+#define ESDHC_FLAG_CQHCI BIT(16)
+
+static struct mmc_host *wifi_mmc_host;
+void wifi_card_detect(bool on)
+{
+ WARN_ON(!wifi_mmc_host);
+ if (on) {
+ mmc_detect_change(wifi_mmc_host, 0);
+ } else {
+ if (wifi_mmc_host->card)
+ mmc_sdio_force_remove(wifi_mmc_host);
+ }
+}
+EXPORT_SYMBOL(wifi_card_detect);
struct esdhc_soc_data {
u32 flags;
@@ -168,18 +211,46 @@ static struct esdhc_soc_data usdhc_imx6q_data = {
static struct esdhc_soc_data usdhc_imx6sl_data = {
.flags = ESDHC_FLAG_USDHC | ESDHC_FLAG_STD_TUNING
| ESDHC_FLAG_HAVE_CAP1 | ESDHC_FLAG_ERR004536
- | ESDHC_FLAG_HS200,
+ | ESDHC_FLAG_HS200 | ESDHC_FLAG_BUSFREQ,
};
static struct esdhc_soc_data usdhc_imx6sx_data = {
.flags = ESDHC_FLAG_USDHC | ESDHC_FLAG_STD_TUNING
- | ESDHC_FLAG_HAVE_CAP1 | ESDHC_FLAG_HS200,
+ | ESDHC_FLAG_HAVE_CAP1 | ESDHC_FLAG_HS200
+ | ESDHC_FLAG_STATE_LOST_IN_LPMODE
+ | ESDHC_FLAG_BUSFREQ,
+};
+
+static struct esdhc_soc_data usdhc_imx6ull_data = {
+ .flags = ESDHC_FLAG_USDHC | ESDHC_FLAG_STD_TUNING
+ | ESDHC_FLAG_HAVE_CAP1 | ESDHC_FLAG_HS200
+ | ESDHC_FLAG_STATE_LOST_IN_LPMODE
+ | ESDHC_FLAG_ERR010450
+ | ESDHC_FLAG_BUSFREQ,
};
static struct esdhc_soc_data usdhc_imx7d_data = {
.flags = ESDHC_FLAG_USDHC | ESDHC_FLAG_STD_TUNING
| ESDHC_FLAG_HAVE_CAP1 | ESDHC_FLAG_HS200
- | ESDHC_FLAG_HS400,
+ | ESDHC_FLAG_HS400 | ESDHC_FLAG_STATE_LOST_IN_LPMODE
+ | ESDHC_FLAG_BUSFREQ,
+};
+
+static struct esdhc_soc_data usdhc_imx7ulp_data = {
+ .flags = ESDHC_FLAG_USDHC | ESDHC_FLAG_STD_TUNING
+ | ESDHC_FLAG_HAVE_CAP1 | ESDHC_FLAG_HS200
+ | ESDHC_FLAG_HS400
+ | ESDHC_FLAG_STATE_LOST_IN_LPMODE
+ | ESDHC_FLAG_PMQOS,
+};
+
+static struct esdhc_soc_data usdhc_imx8qm_data = {
+ .flags = ESDHC_FLAG_USDHC | ESDHC_FLAG_STD_TUNING
+ | ESDHC_FLAG_HAVE_CAP1 | ESDHC_FLAG_HS200
+ | ESDHC_FLAG_HS400 | ESDHC_FLAG_HS400_ES
+ | ESDHC_FLAG_CQHCI
+ | ESDHC_FLAG_STATE_LOST_IN_LPMODE
+ | ESDHC_FLAG_CLK_RATE_LOST_IN_PM_RUNTIME,
};
struct pltfm_imx_data {
@@ -199,6 +270,7 @@ struct pltfm_imx_data {
WAIT_FOR_INT, /* sent CMD12, waiting for response INT */
} multiblock_status;
u32 is_ddr;
+ struct pm_qos_request pm_qos_req;
};
static const struct platform_device_id imx_esdhc_devtype[] = {
@@ -225,7 +297,10 @@ static const struct of_device_id imx_esdhc_dt_ids[] = {
{ .compatible = "fsl,imx6sx-usdhc", .data = &usdhc_imx6sx_data, },
{ .compatible = "fsl,imx6sl-usdhc", .data = &usdhc_imx6sl_data, },
{ .compatible = "fsl,imx6q-usdhc", .data = &usdhc_imx6q_data, },
+ { .compatible = "fsl,imx6ull-usdhc", .data = &usdhc_imx6ull_data, },
{ .compatible = "fsl,imx7d-usdhc", .data = &usdhc_imx7d_data, },
+ { .compatible = "fsl,imx7ulp-usdhc", .data = &usdhc_imx7ulp_data, },
+ { .compatible = "fsl,imx8qm-usdhc", .data = &usdhc_imx8qm_data, },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, imx_esdhc_dt_ids);
@@ -615,6 +690,13 @@ static void esdhc_writeb_le(struct sdhci_host *host, u8 val, int reg)
mask = 0xffff & ~(ESDHC_CTRL_BUSWIDTH_MASK | ESDHC_CTRL_D3CD);
esdhc_clrset_le(host, mask, new_val, reg);
+
+ /*
+ * The imx6q ROM code will change the default watermark
+ * level setting to something insane. Change it back here.
+ */
+ if (esdhc_is_usdhc(imx_data))
+ writel(0x10401040, host->ioaddr + ESDHC_WTMK_LVL);
return;
case SDHCI_SOFTWARE_RESET:
if (val & SDHCI_RESET_DATA)
@@ -715,6 +797,13 @@ static inline void esdhc_pltfm_set_clock(struct sdhci_host *host,
| ESDHC_CLOCK_MASK);
sdhci_writel(host, temp, ESDHC_SYSTEM_CONTROL);
+ if (imx_data->socdata->flags & ESDHC_FLAG_ERR010450) {
+ if (imx_data->is_ddr)
+ clock = clock > 45000000 ? 45000000 : clock;
+ else
+ clock = clock > 150000000 ? 150000000 : clock;
+ }
+
while (host_clock / (16 * pre_div * ddr_pre_div) > clock &&
pre_div < 256)
pre_div *= 2;
@@ -846,6 +935,19 @@ static int esdhc_executing_tuning(struct sdhci_host *host, u32 opcode)
return ret;
}
+static void esdhc_hs400_enhanced_strobe(struct mmc_host *mmc, struct mmc_ios *ios)
+{
+ struct sdhci_host *host = mmc_priv(mmc);
+ u32 m;
+
+ m = readl(host->ioaddr + ESDHC_MIX_CTRL);
+ if (ios->enhanced_strobe)
+ m |= ESDHC_MIX_CTRL_HS400_ES;
+ else
+ m &= ~ESDHC_MIX_CTRL_HS400_ES;
+ writel(m, host->ioaddr + ESDHC_MIX_CTRL);
+}
+
static int esdhc_change_pinstate(struct sdhci_host *host,
unsigned int uhs)
{
@@ -887,39 +989,46 @@ static int esdhc_change_pinstate(struct sdhci_host *host,
* edge of data_strobe line. Due to the time delay between CLK line and
* data_strobe line, if the delay time is larger than one clock cycle,
* then CLK and data_strobe line will be misaligned, read error shows up.
- * So when the CLK is higher than 100MHz, each clock cycle is short enough,
- * host should configure the delay target.
*/
static void esdhc_set_strobe_dll(struct sdhci_host *host)
{
+ struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+ struct pltfm_imx_data *imx_data = sdhci_pltfm_priv(pltfm_host);
u32 v;
-
- if (host->mmc->actual_clock > ESDHC_STROBE_DLL_CLK_FREQ) {
- /* disable clock before enabling strobe dll */
- writel(readl(host->ioaddr + ESDHC_VENDOR_SPEC) &
- ~ESDHC_VENDOR_SPEC_FRC_SDCLK_ON,
- host->ioaddr + ESDHC_VENDOR_SPEC);
-
- /* force a reset on strobe dll */
- writel(ESDHC_STROBE_DLL_CTRL_RESET,
- host->ioaddr + ESDHC_STROBE_DLL_CTRL);
- /*
- * enable strobe dll ctrl and adjust the delay target
- * for the uSDHC loopback read clock
- */
- v = ESDHC_STROBE_DLL_CTRL_ENABLE |
- (7 << ESDHC_STROBE_DLL_CTRL_SLV_DLY_TARGET_SHIFT);
- writel(v, host->ioaddr + ESDHC_STROBE_DLL_CTRL);
- /* wait 1us to make sure strobe dll status register stable */
- udelay(1);
- v = readl(host->ioaddr + ESDHC_STROBE_DLL_STATUS);
- if (!(v & ESDHC_STROBE_DLL_STS_REF_LOCK))
- dev_warn(mmc_dev(host->mmc),
- "warning! HS400 strobe DLL status REF not lock!\n");
- if (!(v & ESDHC_STROBE_DLL_STS_SLV_LOCK))
+ u32 strobe_delay;
+
+ /* disable clock before enabling strobe dll */
+ writel(readl(host->ioaddr + ESDHC_VENDOR_SPEC) &
+ ~ESDHC_VENDOR_SPEC_FRC_SDCLK_ON,
+ host->ioaddr + ESDHC_VENDOR_SPEC);
+
+ /* force a reset on strobe dll */
+ writel(ESDHC_STROBE_DLL_CTRL_RESET,
+ host->ioaddr + ESDHC_STROBE_DLL_CTRL);
+ /* clear the reset bit on strobe dll before any setting */
+ writel(0, host->ioaddr + ESDHC_STROBE_DLL_CTRL);
+
+ /*
+ * enable strobe dll ctrl and adjust the delay target
+ * for the uSDHC loopback read clock
+ */
+ if (imx_data->boarddata.strobe_dll_delay_target)
+ strobe_delay = imx_data->boarddata.strobe_dll_delay_target;
+ else
+ strobe_delay = ESDHC_STROBE_DLL_CTRL_SLV_DLY_TARGET_DEFAULT;
+ v = ESDHC_STROBE_DLL_CTRL_ENABLE |
+ ESDHC_STROBE_DLL_CTRL_SLV_UPDATE_INT_DEFAULT |
+ (strobe_delay << ESDHC_STROBE_DLL_CTRL_SLV_DLY_TARGET_SHIFT);
+ writel(v, host->ioaddr + ESDHC_STROBE_DLL_CTRL);
+ /* wait 5us to make sure strobe dll status register stable */
+ udelay(5);
+ v = readl(host->ioaddr + ESDHC_STROBE_DLL_STATUS);
+ if (!(v & ESDHC_STROBE_DLL_STS_REF_LOCK))
+ dev_warn(mmc_dev(host->mmc),
+ "warning! HS400 strobe DLL status REF not lock!\n");
+ if (!(v & ESDHC_STROBE_DLL_STS_SLV_LOCK))
dev_warn(mmc_dev(host->mmc),
"warning! HS400 strobe DLL status SLV not lock!\n");
- }
}
static void esdhc_reset_tuning(struct sdhci_host *host)
@@ -961,6 +1070,7 @@ static void esdhc_set_uhs_signaling(struct sdhci_host *host, unsigned timing)
case MMC_TIMING_UHS_SDR25:
case MMC_TIMING_UHS_SDR50:
case MMC_TIMING_UHS_SDR104:
+ case MMC_TIMING_SD_HS:
case MMC_TIMING_MMC_HS:
case MMC_TIMING_MMC_HS200:
writel(m, host->ioaddr + ESDHC_MIX_CTRL);
@@ -989,7 +1099,6 @@ static void esdhc_set_uhs_signaling(struct sdhci_host *host, unsigned timing)
esdhc_set_strobe_dll(host);
break;
case MMC_TIMING_LEGACY:
- default:
esdhc_reset_tuning(host);
break;
}
@@ -1025,6 +1134,19 @@ static void esdhc_set_timeout(struct sdhci_host *host, struct mmc_command *cmd)
SDHCI_TIMEOUT_CONTROL);
}
+static u32 esdhc_cqhci_irq(struct sdhci_host *host, u32 intmask)
+{
+ int cmd_error = 0;
+ int data_error = 0;
+
+ if (!sdhci_cqe_irq(host, intmask, &cmd_error, &data_error))
+ return intmask;
+
+ cqhci_irq(host->mmc, intmask, cmd_error, data_error);
+
+ return 0;
+}
+
static struct sdhci_ops sdhci_esdhc_ops = {
.read_l = esdhc_readl_le,
.read_w = esdhc_readw_le,
@@ -1041,6 +1163,7 @@ static struct sdhci_ops sdhci_esdhc_ops = {
.set_bus_width = esdhc_pltfm_set_bus_width,
.set_uhs_signaling = esdhc_set_uhs_signaling,
.reset = esdhc_reset,
+ .irq = esdhc_cqhci_irq,
};
static const struct sdhci_pltfm_data sdhci_esdhc_imx_pdata = {
@@ -1089,6 +1212,23 @@ static void sdhci_esdhc_imx_hwinit(struct sdhci_host *host)
/* disable DLL_CTRL delay line settings */
writel(0x0, host->ioaddr + ESDHC_DLL_CTRL);
+ /*
+ * For the case of command with busy, if set the bit
+ * ESDHC_VEND_SPEC2_EN_BUSY_IRQ, USDHC will generate a
+ * transfer complete interrupt when busy is deasserted.
+ * When CQHCI use DCMD to send a CMD need R1b respons,
+ * CQHCI require to set ESDHC_VEND_SPEC2_EN_BUSY_IRQ,
+ * otherwise DCMD will always meet timeout waiting for
+ * hardware interrupt issue.
+ */
+ if (imx_data->socdata->flags & ESDHC_FLAG_CQHCI) {
+ tmp = readl(host->ioaddr + ESDHC_VEND_SPEC2);
+ tmp |= ESDHC_VEND_SPEC2_EN_BUSY_IRQ;
+ writel(tmp, host->ioaddr + ESDHC_VEND_SPEC2);
+
+ host->quirks &= ~SDHCI_QUIRK_NO_BUSY_IRQ;
+ }
+
if (imx_data->socdata->flags & ESDHC_FLAG_STD_TUNING) {
tmp = readl(host->ioaddr + ESDHC_TUNING_CTRL);
tmp |= ESDHC_STD_TUNING_EN |
@@ -1104,10 +1244,68 @@ static void sdhci_esdhc_imx_hwinit(struct sdhci_host *host)
<< ESDHC_TUNING_STEP_SHIFT;
}
writel(tmp, host->ioaddr + ESDHC_TUNING_CTRL);
+ } else if (imx_data->socdata->flags & ESDHC_FLAG_MAN_TUNING) {
+ /*
+ * ESDHC_STD_TUNING_EN may be configed in bootloader code,
+ * so clear this bit here to make sure the manual tuning
+ * can work.
+ */
+ tmp = readl(host->ioaddr + ESDHC_TUNING_CTRL);
+ tmp &= ~ESDHC_STD_TUNING_EN;
+ writel(tmp, host->ioaddr + ESDHC_TUNING_CTRL);
+ }
+ }
+}
+
+static void esdhc_cqe_enable(struct mmc_host *mmc)
+{
+ struct sdhci_host *host = mmc_priv(mmc);
+ u32 reg;
+ u16 mode;
+ int count = 10;
+
+ /*
+ * CQE gets stuck if it sees Buffer Read Enable bit set, which can be
+ * the case after tuning, so ensure the buffer is drained.
+ */
+ reg = sdhci_readl(host, SDHCI_PRESENT_STATE);
+ while (reg & SDHCI_DATA_AVAILABLE) {
+ sdhci_readl(host, SDHCI_BUFFER);
+ reg = sdhci_readl(host, SDHCI_PRESENT_STATE);
+ if (count-- == 0) {
+ dev_warn(mmc_dev(host->mmc),
+ "CQE may get stuck because the Buffer Read Enable bit is set\n");
+ break;
}
+ mdelay(1);
}
+
+ /*
+ * Runtime resume will reset the entire host controller, which
+ * will also clear the DMAEN/BCEN of register ESDHC_MIX_CTRL.
+ * Here set DMAEN and BCEN when enable CMDQ.
+ */
+ mode = sdhci_readw(host, SDHCI_TRANSFER_MODE);
+ if (host->flags & SDHCI_REQ_USE_DMA)
+ mode |= SDHCI_TRNS_DMA;
+ if (!(host->quirks2 & SDHCI_QUIRK2_SUPPORT_SINGLE))
+ mode |= SDHCI_TRNS_BLK_CNT_EN;
+ sdhci_writew(host, mode, SDHCI_TRANSFER_MODE);
+
+ sdhci_cqe_enable(mmc);
}
+static void esdhc_sdhci_dumpregs(struct mmc_host *mmc)
+{
+ sdhci_dumpregs(mmc_priv(mmc));
+}
+
+static const struct cqhci_host_ops esdhc_cqhci_ops = {
+ .enable = esdhc_cqe_enable,
+ .disable = sdhci_cqe_disable,
+ .dumpregs = esdhc_sdhci_dumpregs,
+};
+
#ifdef CONFIG_OF
static int
sdhci_esdhc_imx_probe_dt(struct platform_device *pdev,
@@ -1128,20 +1326,18 @@ sdhci_esdhc_imx_probe_dt(struct platform_device *pdev,
of_property_read_u32(np, "fsl,tuning-step", &boarddata->tuning_step);
of_property_read_u32(np, "fsl,tuning-start-tap",
&boarddata->tuning_start_tap);
+ of_property_read_u32(np, "fsl,strobe-dll-delay-target",
+ &boarddata->strobe_dll_delay_target);
if (of_find_property(np, "no-1-8-v", NULL))
- boarddata->support_vsel = false;
- else
- boarddata->support_vsel = true;
+ host->quirks2 |= SDHCI_QUIRK2_NO_1_8_V;
if (of_property_read_u32(np, "fsl,delay-line", &boarddata->delay_line))
boarddata->delay_line = 0;
mmc_of_parse_voltage(np, &host->ocr_mask);
- /* sdr50 and sdr104 need work on 1.8v signal voltage */
- if ((boarddata->support_vsel) && esdhc_is_usdhc(imx_data) &&
- !IS_ERR(imx_data->pins_default)) {
+ if (esdhc_is_usdhc(imx_data) && !IS_ERR(imx_data->pins_default)) {
imx_data->pins_100mhz = pinctrl_lookup_state(imx_data->pinctrl,
ESDHC_PINCTRL_STATE_100MHZ);
imx_data->pins_200mhz = pinctrl_lookup_state(imx_data->pinctrl,
@@ -1156,6 +1352,12 @@ sdhci_esdhc_imx_probe_dt(struct platform_device *pdev,
if (mmc_gpio_get_cd(host->mmc) >= 0)
host->quirks &= ~SDHCI_QUIRK_BROKEN_CARD_DETECTION;
+ if (of_get_property(np, "wifi-host", NULL)) {
+ wifi_mmc_host = host->mmc;
+ host->quirks2 |= SDHCI_QUIRK2_SDIO_IRQ_THREAD;
+ dev_info(mmc_dev(host->mmc), "assigned as wifi host\n");
+ }
+
return 0;
}
#else
@@ -1239,8 +1441,10 @@ static int sdhci_esdhc_imx_probe(struct platform_device *pdev)
of_match_device(imx_esdhc_dt_ids, &pdev->dev);
struct sdhci_pltfm_host *pltfm_host;
struct sdhci_host *host;
+ struct cqhci_host *cq_host;
int err;
struct pltfm_imx_data *imx_data;
+ u32 status;
host = sdhci_pltfm_init(pdev, &sdhci_esdhc_imx_pdata,
sizeof(*imx_data));
@@ -1274,6 +1478,14 @@ static int sdhci_esdhc_imx_probe(struct platform_device *pdev)
pltfm_host->clk = imx_data->clk_per;
pltfm_host->clock = clk_get_rate(pltfm_host->clk);
+
+ if (imx_data->socdata->flags & ESDHC_FLAG_BUSFREQ)
+ request_bus_freq(BUS_FREQ_HIGH);
+
+ if (imx_data->socdata->flags & ESDHC_FLAG_PMQOS)
+ pm_qos_add_request(&imx_data->pm_qos_req,
+ PM_QOS_CPU_DMA_LATENCY, 0);
+
err = clk_prepare_enable(imx_data->clk_per);
if (err)
goto free_sdhci;
@@ -1287,14 +1499,15 @@ static int sdhci_esdhc_imx_probe(struct platform_device *pdev)
imx_data->pinctrl = devm_pinctrl_get(&pdev->dev);
if (IS_ERR(imx_data->pinctrl)) {
err = PTR_ERR(imx_data->pinctrl);
- goto disable_ahb_clk;
+ dev_warn(mmc_dev(host->mmc), "could not get pinctrl\n");
+ imx_data->pins_default = ERR_PTR(-EINVAL);
+ } else {
+ imx_data->pins_default = pinctrl_lookup_state(imx_data->pinctrl,
+ PINCTRL_STATE_DEFAULT);
+ if (IS_ERR(imx_data->pins_default))
+ dev_warn(mmc_dev(host->mmc), "could not get default state\n");
}
- imx_data->pins_default = pinctrl_lookup_state(imx_data->pinctrl,
- PINCTRL_STATE_DEFAULT);
- if (IS_ERR(imx_data->pins_default))
- dev_warn(mmc_dev(host->mmc), "could not get default state\n");
-
if (esdhc_is_usdhc(imx_data)) {
host->quirks2 |= SDHCI_QUIRK2_PRESET_VALUE_BROKEN;
host->mmc->caps |= MMC_CAP_1_8V_DDR;
@@ -1307,6 +1520,8 @@ static int sdhci_esdhc_imx_probe(struct platform_device *pdev)
writel(0x0, host->ioaddr + ESDHC_TUNE_CTRL_STATUS);
}
+ host->tuning_delay = 1;
+
if (imx_data->socdata->flags & ESDHC_FLAG_MAN_TUNING)
sdhci_esdhc_ops.platform_execute_tuning =
esdhc_executing_tuning;
@@ -1317,6 +1532,32 @@ static int sdhci_esdhc_imx_probe(struct platform_device *pdev)
if (imx_data->socdata->flags & ESDHC_FLAG_HS400)
host->quirks2 |= SDHCI_QUIRK2_CAPS_BIT63_FOR_HS400;
+ if (imx_data->socdata->flags & ESDHC_FLAG_HS400_ES) {
+ host->mmc->caps2 |= MMC_CAP2_HS400_ES;
+ host->mmc_host_ops.hs400_enhanced_strobe =
+ esdhc_hs400_enhanced_strobe;
+ }
+
+ if (imx_data->socdata->flags & ESDHC_FLAG_CQHCI) {
+ host->mmc->caps2 |= MMC_CAP2_CQE | MMC_CAP2_CQE_DCMD;
+ cq_host = devm_kzalloc(&pdev->dev, sizeof(*cq_host), GFP_KERNEL);
+ if (IS_ERR(cq_host)) {
+ err = PTR_ERR(cq_host);
+ goto disable_ahb_clk;
+ }
+
+ cq_host->mmio = host->ioaddr + ESDHC_CQHCI_ADDR_OFFSET;
+ cq_host->ops = &esdhc_cqhci_ops;
+
+ err = cqhci_init(cq_host, host->mmc, false);
+ if (err)
+ goto disable_ahb_clk;
+
+ status = cqhci_readl(cq_host, CQHCI_IS);
+ cqhci_writel(cq_host, status, CQHCI_IS);
+ cqhci_writel(cq_host, CQHCI_HALT, CQHCI_CTL);
+ }
+
if (of_id)
err = sdhci_esdhc_imx_probe_dt(pdev, host, imx_data);
else
@@ -1326,6 +1567,8 @@ static int sdhci_esdhc_imx_probe(struct platform_device *pdev)
sdhci_esdhc_imx_hwinit(host);
+ device_set_wakeup_capable(&pdev->dev, 1);
+
err = sdhci_add_host(host);
if (err)
goto disable_ahb_clk;
@@ -1344,6 +1587,12 @@ disable_ipg_clk:
clk_disable_unprepare(imx_data->clk_ipg);
disable_per_clk:
clk_disable_unprepare(imx_data->clk_per);
+
+ if (imx_data->socdata->flags & ESDHC_FLAG_BUSFREQ)
+ release_bus_freq(BUS_FREQ_HIGH);
+
+ if (imx_data->socdata->flags & ESDHC_FLAG_PMQOS)
+ pm_qos_remove_request(&imx_data->pm_qos_req);
free_sdhci:
sdhci_pltfm_free(pdev);
return err;
@@ -1356,6 +1605,9 @@ static int sdhci_esdhc_imx_remove(struct platform_device *pdev)
struct pltfm_imx_data *imx_data = sdhci_pltfm_priv(pltfm_host);
int dead = (readl(host->ioaddr + SDHCI_INT_STATUS) == 0xffffffff);
+ if (imx_data->socdata->flags & ESDHC_FLAG_PMQOS)
+ pm_qos_remove_request(&imx_data->pm_qos_req);
+
pm_runtime_get_sync(&pdev->dev);
pm_runtime_disable(&pdev->dev);
pm_runtime_put_noidle(&pdev->dev);
@@ -1365,6 +1617,8 @@ static int sdhci_esdhc_imx_remove(struct platform_device *pdev)
clk_disable_unprepare(imx_data->clk_per);
clk_disable_unprepare(imx_data->clk_ipg);
clk_disable_unprepare(imx_data->clk_ahb);
+ if (imx_data->socdata->flags & ESDHC_FLAG_BUSFREQ)
+ release_bus_freq(BUS_FREQ_HIGH);
sdhci_pltfm_free(pdev);
@@ -1375,21 +1629,75 @@ static int sdhci_esdhc_imx_remove(struct platform_device *pdev)
static int sdhci_esdhc_suspend(struct device *dev)
{
struct sdhci_host *host = dev_get_drvdata(dev);
+ struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+ struct pltfm_imx_data *imx_data = sdhci_pltfm_priv(pltfm_host);
+ int ret;
+
+ pm_runtime_get_sync(dev);
+
+ if (host->mmc->caps2 & MMC_CAP2_CQE) {
+ ret = cqhci_suspend(host->mmc);
+ if (ret)
+ return ret;
+ }
+
+ if ((imx_data->socdata->flags & ESDHC_FLAG_STATE_LOST_IN_LPMODE) &&
+ (host->tuning_mode != SDHCI_TUNING_MODE_1)) {
+ mmc_retune_timer_stop(host->mmc);
+ mmc_retune_needed(host->mmc);
+ }
if (host->tuning_mode != SDHCI_TUNING_MODE_3)
mmc_retune_needed(host->mmc);
- return sdhci_suspend_host(host);
+ ret = sdhci_suspend_host(host);
+
+ pinctrl_pm_select_sleep_state(dev);
+
+ if (!sdhci_sdio_irq_enabled(host)) {
+ clk_disable_unprepare(imx_data->clk_per);
+ clk_disable_unprepare(imx_data->clk_ipg);
+ }
+ clk_disable_unprepare(imx_data->clk_ahb);
+
+ pm_runtime_disable(dev);
+ pm_runtime_set_suspended(dev);
+
+ return ret;
}
static int sdhci_esdhc_resume(struct device *dev)
{
struct sdhci_host *host = dev_get_drvdata(dev);
+ struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+ struct pltfm_imx_data *imx_data = sdhci_pltfm_priv(pltfm_host);
+ int ret;
+
+ if (!sdhci_sdio_irq_enabled(host)) {
+ clk_prepare_enable(imx_data->clk_per);
+ clk_prepare_enable(imx_data->clk_ipg);
+ }
+ clk_prepare_enable(imx_data->clk_ahb);
+
+ pm_runtime_set_active(dev);
+ pm_runtime_enable(dev);
+
+ pinctrl_pm_select_default_state(dev);
/* re-initialize hw state in case it's lost in low power mode */
sdhci_esdhc_imx_hwinit(host);
- return sdhci_resume_host(host);
+ ret = sdhci_resume_host(host);
+ if (ret)
+ return ret;
+
+ if (host->mmc->caps2 & MMC_CAP2_CQE)
+ ret = cqhci_resume(host->mmc);
+
+ pm_runtime_mark_last_busy(dev);
+ pm_runtime_put_autosuspend(dev);
+
+ return ret;
}
#endif
@@ -1401,6 +1709,12 @@ static int sdhci_esdhc_runtime_suspend(struct device *dev)
struct pltfm_imx_data *imx_data = sdhci_pltfm_priv(pltfm_host);
int ret;
+ if (host->mmc->caps2 & MMC_CAP2_CQE) {
+ ret = cqhci_suspend(host->mmc);
+ if (ret)
+ return ret;
+ }
+
ret = sdhci_runtime_suspend_host(host);
if (host->tuning_mode != SDHCI_TUNING_MODE_3)
@@ -1412,6 +1726,12 @@ static int sdhci_esdhc_runtime_suspend(struct device *dev)
}
clk_disable_unprepare(imx_data->clk_ahb);
+ if (imx_data->socdata->flags & ESDHC_FLAG_BUSFREQ)
+ release_bus_freq(BUS_FREQ_HIGH);
+
+ if (imx_data->socdata->flags & ESDHC_FLAG_PMQOS)
+ pm_qos_remove_request(&imx_data->pm_qos_req);
+
return ret;
}
@@ -1422,6 +1742,16 @@ static int sdhci_esdhc_runtime_resume(struct device *dev)
struct pltfm_imx_data *imx_data = sdhci_pltfm_priv(pltfm_host);
int err;
+ if (imx_data->socdata->flags & ESDHC_FLAG_BUSFREQ)
+ request_bus_freq(BUS_FREQ_HIGH);
+
+ if (imx_data->socdata->flags & ESDHC_FLAG_PMQOS)
+ pm_qos_add_request(&imx_data->pm_qos_req,
+ PM_QOS_CPU_DMA_LATENCY, 0);
+
+ if (imx_data->socdata->flags & ESDHC_FLAG_CLK_RATE_LOST_IN_PM_RUNTIME)
+ clk_set_rate(imx_data->clk_per, pltfm_host->clock);
+
if (!sdhci_sdio_irq_enabled(host)) {
err = clk_prepare_enable(imx_data->clk_per);
if (err)
@@ -1437,7 +1767,10 @@ static int sdhci_esdhc_runtime_resume(struct device *dev)
if (err)
goto disable_ahb_clk;
- return 0;
+ if (host->mmc->caps2 & MMC_CAP2_CQE)
+ err = cqhci_resume(host->mmc);
+
+ return err;
disable_ahb_clk:
clk_disable_unprepare(imx_data->clk_ahb);
diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c
index 176cbc67d08a..f615491e3ff2 100644
--- a/drivers/mmc/host/sdhci-of-esdhc.c
+++ b/drivers/mmc/host/sdhci-of-esdhc.c
@@ -428,11 +428,17 @@ static void esdhc_of_adma_workaround(struct sdhci_host *host, u32 intmask)
static int esdhc_of_enable_dma(struct sdhci_host *host)
{
u32 value;
+ int ret;
struct device *dev = mmc_dev(host->mmc);
if (of_device_is_compatible(dev->of_node, "fsl,ls1043a-esdhc") ||
- of_device_is_compatible(dev->of_node, "fsl,ls1046a-esdhc"))
- dma_set_mask_and_coherent(dev, DMA_BIT_MASK(40));
+ of_device_is_compatible(dev->of_node, "fsl,ls1046a-esdhc")) {
+ ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(40));
+ if (ret) {
+ pr_warn("%s: Failed to set 40-bit DMA mask.\n",
+ mmc_hostname(host->mmc));
+ }
+ }
value = sdhci_readl(host, ESDHC_DMA_SYSCTL);
diff --git a/drivers/mmc/host/sdhci-pltfm.c b/drivers/mmc/host/sdhci-pltfm.c
index 02bea6159d79..659b1c7650ef 100644
--- a/drivers/mmc/host/sdhci-pltfm.c
+++ b/drivers/mmc/host/sdhci-pltfm.c
@@ -2,7 +2,7 @@
* sdhci-pltfm.c Support for SDHCI platform devices
* Copyright (c) 2009 Intel Corporation
*
- * Copyright (c) 2007, 2011 Freescale Semiconductor, Inc.
+ * Copyright (C) 2007, 2011, 2015 Freescale Semiconductor, Inc.
* Copyright (c) 2009 MontaVista Software, Inc.
*
* Authors: Xiaobo Xie <X.Xie@freescale.com>
@@ -224,6 +224,8 @@ int sdhci_pltfm_suspend(struct device *dev)
clk_disable_unprepare(pltfm_host->clk);
+ pinctrl_pm_select_sleep_state(dev);
+
return 0;
}
EXPORT_SYMBOL_GPL(sdhci_pltfm_suspend);
@@ -234,6 +236,8 @@ int sdhci_pltfm_resume(struct device *dev)
struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
int ret;
+ pinctrl_pm_select_default_state(dev);
+
ret = clk_prepare_enable(pltfm_host->clk);
if (ret)
return ret;
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 5807028c8309..ccd2f93774fc 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -131,9 +131,10 @@ static inline bool sdhci_data_line_cmd(struct mmc_command *cmd)
static void sdhci_set_card_detection(struct sdhci_host *host, bool enable)
{
u32 present;
+ int gpio_cd = mmc_gpio_get_cd(host->mmc);
if ((host->quirks & SDHCI_QUIRK_BROKEN_CARD_DETECTION) ||
- !mmc_card_is_removable(host->mmc))
+ !mmc_card_is_removable(host->mmc) || (gpio_cd >= 0))
return;
if (enable) {
@@ -716,7 +717,7 @@ static u32 sdhci_sdma_address(struct sdhci_host *host)
static u8 sdhci_calc_timeout(struct sdhci_host *host, struct mmc_command *cmd)
{
u8 count;
- struct mmc_data *data = cmd->data;
+ struct mmc_data *data;
unsigned target_timeout, current_timeout;
/*
@@ -728,6 +729,12 @@ static u8 sdhci_calc_timeout(struct sdhci_host *host, struct mmc_command *cmd)
if (host->quirks & SDHCI_QUIRK_BROKEN_TIMEOUT_VAL)
return 0xE;
+ /* Unspecified command, assume max */
+ if (cmd == NULL)
+ return 0xE;
+
+ data = cmd->data;
+
/* Unspecified timeout, assume max */
if (!data && !cmd->busy_timeout)
return 0xE;
@@ -2106,6 +2113,7 @@ static void sdhci_send_tuning(struct sdhci_host *host, u32 opcode)
struct mmc_request mrq = {};
unsigned long flags;
u32 b = host->sdma_boundary;
+ u8 ctrl;
spin_lock_irqsave(&host->lock, flags);
@@ -2133,6 +2141,17 @@ static void sdhci_send_tuning(struct sdhci_host *host, u32 opcode)
*/
sdhci_writew(host, SDHCI_TRNS_READ, SDHCI_TRANSFER_MODE);
+ /*
+ * DMA already disabled, so clear the DMA Select here.
+ * Otherwise, if use ADMA2, even disable DMA, some
+ * controllers like i.MX usdhc will still prefetch the
+ * ADMA script when send tuning command, which will cause
+ * IOMMU report lack of TLB mapping error
+ */
+ ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
+ ctrl &= ~SDHCI_CTRL_DMA_MASK;
+ sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
+
sdhci_send_command(host, &cmd);
host->cmd = NULL;
@@ -2172,8 +2191,16 @@ static void __sdhci_execute_tuning(struct sdhci_host *host, u32 opcode)
ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
if (!(ctrl & SDHCI_CTRL_EXEC_TUNING)) {
- if (ctrl & SDHCI_CTRL_TUNED_CLK)
+ if (ctrl & SDHCI_CTRL_TUNED_CLK) {
+ /*
+ * need to wait some time, make sure sd/mmc fininsh
+ * send out tuning data, otherwise, the sd/mmc can't
+ * response to any command when the card still out
+ * put the tuning data.
+ */
+ mdelay(1);
return; /* Success! */
+ }
break;
}
@@ -2222,7 +2249,6 @@ int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode)
break;
case MMC_TIMING_UHS_SDR104:
- case MMC_TIMING_UHS_DDR50:
break;
case MMC_TIMING_UHS_SDR50:
@@ -2230,6 +2256,11 @@ int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode)
break;
/* FALLTHROUGH */
+ case MMC_TIMING_UHS_DDR50:
+ if (host->flags & SDHCI_DDR50_NEEDS_TUNING)
+ break;
+ /* FALLTHROUGH */
+
default:
goto out;
}
@@ -2797,6 +2828,7 @@ static irqreturn_t sdhci_irq(int irq, void *dev_id)
struct sdhci_host *host = dev_id;
u32 intmask, mask, unexpected = 0;
int max_loops = 16;
+ int cardint = 0;
spin_lock(&host->lock);
@@ -2870,9 +2902,13 @@ static irqreturn_t sdhci_irq(int irq, void *dev_id)
if ((intmask & SDHCI_INT_CARD_INT) &&
(host->ier & SDHCI_INT_CARD_INT)) {
- sdhci_enable_sdio_irq_nolock(host, false);
- host->thread_isr |= SDHCI_INT_CARD_INT;
- result = IRQ_WAKE_THREAD;
+ if (host->mmc->caps2 & MMC_CAP2_SDIO_IRQ_NOTHREAD) {
+ sdhci_enable_sdio_irq_nolock(host, false);
+ host->thread_isr |= SDHCI_INT_CARD_INT;
+ result = IRQ_WAKE_THREAD;
+ } else {
+ cardint = 1;
+ }
}
intmask &= ~(SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE |
@@ -2899,6 +2935,9 @@ out:
sdhci_dumpregs(host);
}
+ if (cardint && host->mmc->sdio_irqs)
+ mmc_signal_sdio_irq(host->mmc);
+
return result;
}
@@ -2921,12 +2960,13 @@ static irqreturn_t sdhci_thread_irq(int irq, void *dev_id)
}
if (isr & SDHCI_INT_CARD_INT) {
- sdio_run_irqs(host->mmc);
-
- spin_lock_irqsave(&host->lock, flags);
- if (host->flags & SDHCI_SDIO_IRQ_ENABLED)
- sdhci_enable_sdio_irq_nolock(host, true);
- spin_unlock_irqrestore(&host->lock, flags);
+ if (host->mmc->caps2 & MMC_CAP2_SDIO_IRQ_NOTHREAD) {
+ sdio_run_irqs(host->mmc);
+ spin_lock_irqsave(&host->lock, flags);
+ if (host->flags & SDHCI_SDIO_IRQ_ENABLED)
+ sdhci_enable_sdio_irq_nolock(host, true);
+ spin_unlock_irqrestore(&host->lock, flags);
+ }
}
return isr ? IRQ_HANDLED : IRQ_NONE;
@@ -2949,6 +2989,7 @@ static irqreturn_t sdhci_thread_irq(int irq, void *dev_id)
*/
void sdhci_enable_irq_wakeups(struct sdhci_host *host)
{
+ int gpio_cd = mmc_gpio_get_cd(host->mmc);
u8 val;
u8 mask = SDHCI_WAKE_ON_INSERT | SDHCI_WAKE_ON_REMOVE
| SDHCI_WAKE_ON_INT;
@@ -2958,7 +2999,8 @@ void sdhci_enable_irq_wakeups(struct sdhci_host *host)
val = sdhci_readb(host, SDHCI_WAKE_UP_CONTROL);
val |= mask ;
/* Avoid fake wake up */
- if (host->quirks & SDHCI_QUIRK_BROKEN_CARD_DETECTION) {
+ if (host->quirks & SDHCI_QUIRK_BROKEN_CARD_DETECTION ||
+ (gpio_cd >= 0)) {
val &= ~(SDHCI_WAKE_ON_INSERT | SDHCI_WAKE_ON_REMOVE);
irq_val &= ~(SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE);
}
@@ -2988,7 +3030,7 @@ int sdhci_suspend_host(struct sdhci_host *host)
host->ier = 0;
sdhci_writel(host, 0, SDHCI_INT_ENABLE);
sdhci_writel(host, 0, SDHCI_SIGNAL_ENABLE);
- free_irq(host->irq, host);
+ disable_irq(host->irq);
} else {
sdhci_enable_irq_wakeups(host);
enable_irq_wake(host->irq);
@@ -3001,7 +3043,6 @@ EXPORT_SYMBOL_GPL(sdhci_suspend_host);
int sdhci_resume_host(struct sdhci_host *host)
{
struct mmc_host *mmc = host->mmc;
- int ret = 0;
if (host->flags & (SDHCI_USE_SDMA | SDHCI_USE_ADMA)) {
if (host->ops->enable_dma)
@@ -3021,11 +3062,7 @@ int sdhci_resume_host(struct sdhci_host *host)
}
if (!device_may_wakeup(mmc_dev(host->mmc))) {
- ret = request_threaded_irq(host->irq, sdhci_irq,
- sdhci_thread_irq, IRQF_SHARED,
- mmc_hostname(host->mmc), host);
- if (ret)
- return ret;
+ enable_irq(host->irq);
} else {
sdhci_disable_irq_wakeups(host);
disable_irq_wake(host->irq);
@@ -3033,7 +3070,7 @@ int sdhci_resume_host(struct sdhci_host *host)
sdhci_enable_card_detection(host);
- return ret;
+ return 0;
}
EXPORT_SYMBOL_GPL(sdhci_resume_host);
@@ -3138,7 +3175,7 @@ void sdhci_cqe_enable(struct mmc_host *mmc)
SDHCI_BLOCK_SIZE);
/* Set maximum timeout */
- sdhci_writeb(host, 0xE, SDHCI_TIMEOUT_CONTROL);
+ sdhci_set_timeout(host, NULL);
host->ier = host->cqe_ier;
@@ -3408,6 +3445,7 @@ static int sdhci_allocate_bounce_buffer(struct sdhci_host *host)
int sdhci_setup_host(struct sdhci_host *host)
{
struct mmc_host *mmc;
+ struct device *dev;
u32 max_current_caps;
unsigned int ocr_avail;
unsigned int override_timeout_clk;
@@ -3419,6 +3457,7 @@ int sdhci_setup_host(struct sdhci_host *host)
return -EINVAL;
mmc = host->mmc;
+ dev = mmc_dev(mmc);
/*
* If there are external regulators, get them. Note this must be done
@@ -3634,7 +3673,8 @@ int sdhci_setup_host(struct sdhci_host *host)
}
mmc->caps |= MMC_CAP_SDIO_IRQ | MMC_CAP_ERASE | MMC_CAP_CMD23;
- mmc->caps2 |= MMC_CAP2_SDIO_IRQ_NOTHREAD;
+ if (!(host->quirks2 & SDHCI_QUIRK2_SDIO_IRQ_THREAD))
+ mmc->caps2 |= MMC_CAP2_SDIO_IRQ_NOTHREAD;
if (host->quirks & SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12)
host->flags |= SDHCI_AUTO_CMD12;
@@ -3666,11 +3706,7 @@ int sdhci_setup_host(struct sdhci_host *host)
if (host->caps & SDHCI_CAN_DO_HISPD)
mmc->caps |= MMC_CAP_SD_HIGHSPEED | MMC_CAP_MMC_HIGHSPEED;
- if ((host->quirks & SDHCI_QUIRK_BROKEN_CARD_DETECTION) &&
- mmc_card_is_removable(mmc) &&
- mmc_gpio_get_cd(host->mmc) < 0)
- mmc->caps |= MMC_CAP_NEEDS_POLL;
-
+ /* If vqmmc regulator and no 1.8V signalling, then there's no UHS */
if (!IS_ERR(mmc->supply.vqmmc)) {
ret = regulator_enable(mmc->supply.vqmmc);
@@ -3696,6 +3732,7 @@ int sdhci_setup_host(struct sdhci_host *host)
if (host->quirks2 & SDHCI_QUIRK2_NO_1_8_V) {
host->caps1 &= ~(SDHCI_SUPPORT_SDR104 | SDHCI_SUPPORT_SDR50 |
SDHCI_SUPPORT_DDR50);
+ mmc->caps2 |= MMC_CAP2_DDR52_3_3V;
}
/* Any UHS-I mode in caps implies SDR12 and SDR25 support. */
@@ -3835,10 +3872,11 @@ int sdhci_setup_host(struct sdhci_host *host)
goto unreg;
}
- if ((mmc->caps & (MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25 |
+ if (((mmc->caps & (MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25 |
MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_SDR104 |
MMC_CAP_UHS_DDR50 | MMC_CAP_1_8V_DDR)) ||
- (mmc->caps2 & (MMC_CAP2_HS200_1_8V_SDR | MMC_CAP2_HS400_1_8V)))
+ (mmc->caps2 & (MMC_CAP2_HS200_1_8V_SDR | MMC_CAP2_HS400_1_8V))) &&
+ !(mmc->caps2 & MMC_CAP2_DDR52_3_3V))
host->flags |= SDHCI_SIGNALING_180;
if (mmc->caps2 & MMC_CAP2_HSX00_1_2V)
@@ -3877,10 +3915,20 @@ int sdhci_setup_host(struct sdhci_host *host)
* be larger than 64 KiB though.
*/
if (host->flags & SDHCI_USE_ADMA) {
- if (host->quirks & SDHCI_QUIRK_BROKEN_ADMA_ZEROLEN_DESC)
+ if (host->quirks & SDHCI_QUIRK_BROKEN_ADMA_ZEROLEN_DESC) {
mmc->max_seg_size = 65535;
- else
+
+ /*
+ * send the ADMA limitation to IOMMU. In default,
+ * the max segment size of IOMMU is 64KB, this exceed
+ * the ADMA max segment limitation, which is 65535.
+ */
+ dev->dma_parms = devm_kzalloc(dev,
+ sizeof(*dev->dma_parms), GFP_KERNEL);
+ dma_set_max_seg_size(dev, SZ_64K - 1);
+ } else {
mmc->max_seg_size = 65536;
+ }
} else {
mmc->max_seg_size = mmc->max_req_size;
}
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
index c0d5458c36d4..63ade61dbbf4 100644
--- a/drivers/mmc/host/sdhci.h
+++ b/drivers/mmc/host/sdhci.h
@@ -442,6 +442,8 @@ struct sdhci_host {
#define SDHCI_QUIRK2_CLOCK_DIV_ZERO_BROKEN (1<<15)
/* Controller has CRC in 136 bit Command Response */
#define SDHCI_QUIRK2_RSP_136_HAS_CRC (1<<16)
+/* Host or Card can't support no thread sdio irq */
+#define SDHCI_QUIRK2_SDIO_IRQ_THREAD (1<<17)
int irq; /* Device IRQ */
void __iomem *ioaddr; /* Mapped address */
@@ -469,6 +471,7 @@ struct sdhci_host {
#define SDHCI_REQ_USE_DMA (1<<2) /* Use DMA for this req. */
#define SDHCI_DEVICE_DEAD (1<<3) /* Device unresponsive */
#define SDHCI_SDR50_NEEDS_TUNING (1<<4) /* SDR50 needs tuning */
+#define SDHCI_DDR50_NEEDS_TUNING (1<<5) /* DDR50 needs tuning */
#define SDHCI_AUTO_CMD12 (1<<6) /* Auto CMD12 support */
#define SDHCI_AUTO_CMD23 (1<<7) /* Auto CMD23 support */
#define SDHCI_PV_ENABLED (1<<8) /* Preset value enabled */
diff --git a/drivers/mtd/Makefile b/drivers/mtd/Makefile
index d6f8f625e1ff..567664744005 100644
--- a/drivers/mtd/Makefile
+++ b/drivers/mtd/Makefile
@@ -32,7 +32,7 @@ obj-$(CONFIG_MTD_SWAP) += mtdswap.o
nftl-objs := nftlcore.o nftlmount.o
inftl-objs := inftlcore.o inftlmount.o
+obj-$(CONFIG_MTD_SPI_NOR) += spi-nor/
obj-y += chips/ lpddr/ maps/ devices/ nand/ onenand/ tests/
-obj-$(CONFIG_MTD_SPI_NOR) += spi-nor/
obj-$(CONFIG_MTD_UBI) += ubi/
diff --git a/drivers/mtd/nand/gpmi-nand/bch-regs.h b/drivers/mtd/nand/gpmi-nand/bch-regs.h
index 05bb91f2f4c4..03f0a7871c5c 100644
--- a/drivers/mtd/nand/gpmi-nand/bch-regs.h
+++ b/drivers/mtd/nand/gpmi-nand/bch-regs.h
@@ -30,7 +30,13 @@
#define BM_BCH_CTRL_COMPLETE_IRQ (1 << 0)
#define HW_BCH_STATUS0 0x00000010
+
#define HW_BCH_MODE 0x00000020
+#define BP_BCH_MODE_ERASE_THRESHOLD 0
+#define BM_BCH_MODE_ERASE_THRESHOLD (0xff << BP_BCH_MODE_ERASE_THRESHOLD)
+#define BF_BCH_MODE_ERASE_THRESHOLD(v) \
+ (((v) << BP_BCH_MODE_ERASE_THRESHOLD) & BM_BCH_MODE_ERASE_THRESHOLD)
+
#define HW_BCH_ENCODEPTR 0x00000030
#define HW_BCH_DATAPTR 0x00000040
#define HW_BCH_METAPTR 0x00000050
@@ -54,7 +60,7 @@
#define MX6Q_BP_BCH_FLASH0LAYOUT0_ECC0 11
#define MX6Q_BM_BCH_FLASH0LAYOUT0_ECC0 (0x1f << MX6Q_BP_BCH_FLASH0LAYOUT0_ECC0)
#define BF_BCH_FLASH0LAYOUT0_ECC0(v, x) \
- (GPMI_IS_MX6(x) \
+ ((GPMI_IS_MX6(x) || GPMI_IS_MX8(x)) \
? (((v) << MX6Q_BP_BCH_FLASH0LAYOUT0_ECC0) \
& MX6Q_BM_BCH_FLASH0LAYOUT0_ECC0) \
: (((v) << BP_BCH_FLASH0LAYOUT0_ECC0) \
@@ -65,7 +71,7 @@
#define MX6Q_BM_BCH_FLASH0LAYOUT0_GF_13_14 \
(0x1 << MX6Q_BP_BCH_FLASH0LAYOUT0_GF_13_14)
#define BF_BCH_FLASH0LAYOUT0_GF(v, x) \
- ((GPMI_IS_MX6(x) && ((v) == 14)) \
+ (((GPMI_IS_MX6(x) || GPMI_IS_MX8(x)) && ((v) == 14))\
? (((1) << MX6Q_BP_BCH_FLASH0LAYOUT0_GF_13_14) \
& MX6Q_BM_BCH_FLASH0LAYOUT0_GF_13_14) \
: 0 \
@@ -77,7 +83,7 @@
#define MX6Q_BM_BCH_FLASH0LAYOUT0_DATA0_SIZE \
(0x3ff << BP_BCH_FLASH0LAYOUT0_DATA0_SIZE)
#define BF_BCH_FLASH0LAYOUT0_DATA0_SIZE(v, x) \
- (GPMI_IS_MX6(x) \
+ ((GPMI_IS_MX6(x) || GPMI_IS_MX8(x)) \
? (((v) >> 2) & MX6Q_BM_BCH_FLASH0LAYOUT0_DATA0_SIZE) \
: ((v) & BM_BCH_FLASH0LAYOUT0_DATA0_SIZE) \
)
@@ -96,7 +102,7 @@
#define MX6Q_BP_BCH_FLASH0LAYOUT1_ECCN 11
#define MX6Q_BM_BCH_FLASH0LAYOUT1_ECCN (0x1f << MX6Q_BP_BCH_FLASH0LAYOUT1_ECCN)
#define BF_BCH_FLASH0LAYOUT1_ECCN(v, x) \
- (GPMI_IS_MX6(x) \
+ ((GPMI_IS_MX6(x) || GPMI_IS_MX8(x)) \
? (((v) << MX6Q_BP_BCH_FLASH0LAYOUT1_ECCN) \
& MX6Q_BM_BCH_FLASH0LAYOUT1_ECCN) \
: (((v) << BP_BCH_FLASH0LAYOUT1_ECCN) \
@@ -107,7 +113,7 @@
#define MX6Q_BM_BCH_FLASH0LAYOUT1_GF_13_14 \
(0x1 << MX6Q_BP_BCH_FLASH0LAYOUT1_GF_13_14)
#define BF_BCH_FLASH0LAYOUT1_GF(v, x) \
- ((GPMI_IS_MX6(x) && ((v) == 14)) \
+ (((GPMI_IS_MX6(x) || GPMI_IS_MX8(x)) && ((v) == 14))\
? (((1) << MX6Q_BP_BCH_FLASH0LAYOUT1_GF_13_14) \
& MX6Q_BM_BCH_FLASH0LAYOUT1_GF_13_14) \
: 0 \
@@ -119,10 +125,14 @@
#define MX6Q_BM_BCH_FLASH0LAYOUT1_DATAN_SIZE \
(0x3ff << BP_BCH_FLASH0LAYOUT1_DATAN_SIZE)
#define BF_BCH_FLASH0LAYOUT1_DATAN_SIZE(v, x) \
- (GPMI_IS_MX6(x) \
+ ((GPMI_IS_MX6(x) || GPMI_IS_MX8(x)) \
? (((v) >> 2) & MX6Q_BM_BCH_FLASH0LAYOUT1_DATAN_SIZE) \
: ((v) & BM_BCH_FLASH0LAYOUT1_DATAN_SIZE) \
)
#define HW_BCH_VERSION 0x00000160
+#define HW_BCH_DEBUG1 0x00000170
+#define BP_BCH_DEBUG1_ERASED_ZERO_COUNT 0
+#define BM_BCH_DEBUG1_ERASED_ZERO_COUNT \
+ (0x1ff << BP_BCH_DEBUG1_ERASED_ZERO_COUNT)
#endif
diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-lib.c b/drivers/mtd/nand/gpmi-nand/gpmi-lib.c
index 55e369b6b862..0fe7eda4781c 100644
--- a/drivers/mtd/nand/gpmi-nand/gpmi-lib.c
+++ b/drivers/mtd/nand/gpmi-nand/gpmi-lib.c
@@ -1,8 +1,9 @@
/*
* Freescale GPMI NAND Flash Driver
*
- * Copyright (C) 2008-2011 Freescale Semiconductor, Inc.
* Copyright (C) 2008 Embedded Alley Solutions, Inc.
+ * Copyright (C) 2008-2016 Freescale Semiconductor, Inc.
+ * Copyright 2017 NXP
*
* 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
@@ -21,11 +22,17 @@
#include <linux/delay.h>
#include <linux/clk.h>
#include <linux/slab.h>
+#include <linux/pm_runtime.h>
+#include <linux/debugfs.h>
+
#include "gpmi-nand.h"
#include "gpmi-regs.h"
#include "bch-regs.h"
+/* export the bch geometry to dbgfs */
+static struct debugfs_blob_wrapper dbg_bch_geo;
+
static struct timing_threshold timing_default_threshold = {
.max_data_setup_cycles = (BM_GPMI_TIMING0_DATA_SETUP >>
BP_GPMI_TIMING0_DATA_SETUP),
@@ -124,7 +131,7 @@ error:
return -ETIMEDOUT;
}
-static int __gpmi_enable_clk(struct gpmi_nand_data *this, bool v)
+int __gpmi_enable_clk(struct gpmi_nand_data *this, bool v)
{
struct clk *clk;
int ret;
@@ -151,17 +158,17 @@ err_clk:
return ret;
}
-#define gpmi_enable_clk(x) __gpmi_enable_clk(x, true)
-#define gpmi_disable_clk(x) __gpmi_enable_clk(x, false)
-
int gpmi_init(struct gpmi_nand_data *this)
{
struct resources *r = &this->resources;
int ret;
- ret = gpmi_enable_clk(this);
- if (ret)
+ ret = pm_runtime_get_sync(this->dev);
+ if (ret < 0) {
+ dev_err(this->dev, "Failed to enable clock\n");
return ret;
+ }
+
ret = gpmi_reset_block(r->gpmi_regs, false);
if (ret)
goto err_out;
@@ -195,10 +202,10 @@ int gpmi_init(struct gpmi_nand_data *this)
*/
writel(BM_GPMI_CTRL1_DECOUPLE_CS, r->gpmi_regs + HW_GPMI_CTRL1_SET);
- gpmi_disable_clk(this);
- return 0;
err_out:
- gpmi_disable_clk(this);
+ pm_runtime_mark_last_busy(this->dev);
+ pm_runtime_put_autosuspend(this->dev);
+
return ret;
}
@@ -227,7 +234,8 @@ void gpmi_dump_info(struct gpmi_nand_data *this)
"ECC Strength : %u\n"
"Page Size in Bytes : %u\n"
"Metadata Size in Bytes : %u\n"
- "ECC Chunk Size in Bytes: %u\n"
+ "ECC Chunk0 Size in Bytes: %u\n"
+ "ECC Chunkn Size in Bytes: %u\n"
"ECC Chunk Count : %u\n"
"Payload Size in Bytes : %u\n"
"Auxiliary Size in Bytes: %u\n"
@@ -238,7 +246,8 @@ void gpmi_dump_info(struct gpmi_nand_data *this)
geo->ecc_strength,
geo->page_size,
geo->metadata_size,
- geo->ecc_chunk_size,
+ geo->ecc_chunk0_size,
+ geo->ecc_chunkn_size,
geo->ecc_chunk_count,
geo->payload_size,
geo->auxiliary_size,
@@ -247,13 +256,43 @@ void gpmi_dump_info(struct gpmi_nand_data *this)
geo->block_mark_bit_offset);
}
+int bch_create_debugfs(struct gpmi_nand_data *this)
+{
+ struct bch_geometry *bch_geo = &this->bch_geometry;
+ struct dentry *dbg_root;
+
+ dbg_root = debugfs_create_dir("gpmi-nand", NULL);
+ if (!dbg_root) {
+ dev_err(this->dev, "failed to create debug directory\n");
+ return -EINVAL;
+ }
+
+ dbg_bch_geo.data = (void *)bch_geo;
+ dbg_bch_geo.size = sizeof(struct bch_geometry);
+ if (!debugfs_create_blob("bch_geometry", S_IRUGO,
+ dbg_root, &dbg_bch_geo)) {
+ dev_err(this->dev, "failed to create debug bch geometry\n");
+ return -EINVAL;
+ }
+
+ /* create raw mode flag */
+ if (!debugfs_create_file("raw_mode", S_IRUGO,
+ dbg_root, NULL, NULL)) {
+ dev_err(this->dev, "failed to create raw mode flag\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
/* Configures the geometry for BCH. */
int bch_set_geometry(struct gpmi_nand_data *this)
{
struct resources *r = &this->resources;
struct bch_geometry *bch_geo = &this->bch_geometry;
unsigned int block_count;
- unsigned int block_size;
+ unsigned int block0_size;
+ unsigned int blockn_size;
unsigned int metadata_size;
unsigned int ecc_strength;
unsigned int page_size;
@@ -264,15 +303,18 @@ int bch_set_geometry(struct gpmi_nand_data *this)
return !0;
block_count = bch_geo->ecc_chunk_count - 1;
- block_size = bch_geo->ecc_chunk_size;
+ block0_size = bch_geo->ecc_chunk0_size;
+ blockn_size = bch_geo->ecc_chunkn_size;
metadata_size = bch_geo->metadata_size;
ecc_strength = bch_geo->ecc_strength >> 1;
page_size = bch_geo->page_size;
gf_len = bch_geo->gf_len;
- ret = gpmi_enable_clk(this);
- if (ret)
+ ret = pm_runtime_get_sync(this->dev);
+ if (ret < 0) {
+ dev_err(this->dev, "Failed to enable clock\n");
return ret;
+ }
/*
* Due to erratum #2847 of the MX23, the BCH cannot be soft reset on this
@@ -289,15 +331,20 @@ int bch_set_geometry(struct gpmi_nand_data *this)
| BF_BCH_FLASH0LAYOUT0_META_SIZE(metadata_size)
| BF_BCH_FLASH0LAYOUT0_ECC0(ecc_strength, this)
| BF_BCH_FLASH0LAYOUT0_GF(gf_len, this)
- | BF_BCH_FLASH0LAYOUT0_DATA0_SIZE(block_size, this),
+ | BF_BCH_FLASH0LAYOUT0_DATA0_SIZE(block0_size, this),
r->bch_regs + HW_BCH_FLASH0LAYOUT0);
writel(BF_BCH_FLASH0LAYOUT1_PAGE_SIZE(page_size)
| BF_BCH_FLASH0LAYOUT1_ECCN(ecc_strength, this)
| BF_BCH_FLASH0LAYOUT1_GF(gf_len, this)
- | BF_BCH_FLASH0LAYOUT1_DATAN_SIZE(block_size, this),
+ | BF_BCH_FLASH0LAYOUT1_DATAN_SIZE(blockn_size, this),
r->bch_regs + HW_BCH_FLASH0LAYOUT1);
+ /* Set erase threshold to ecc strength for mx6ul, mx6qp and mx7 */
+ if (GPMI_IS_MX6QP(this) || GPMI_IS_MX7D(this) || GPMI_IS_MX6UL(this))
+ writel(BF_BCH_MODE_ERASE_THRESHOLD(ecc_strength),
+ r->bch_regs + HW_BCH_MODE);
+
/* Set *all* chip selects to use layout 0. */
writel(0, r->bch_regs + HW_BCH_LAYOUTSELECT);
@@ -305,10 +352,10 @@ int bch_set_geometry(struct gpmi_nand_data *this)
writel(BM_BCH_CTRL_COMPLETE_IRQ_EN,
r->bch_regs + HW_BCH_CTRL_SET);
- gpmi_disable_clk(this);
- return 0;
err_out:
- gpmi_disable_clk(this);
+ pm_runtime_mark_last_busy(this->dev);
+ pm_runtime_put_autosuspend(this->dev);
+
return ret;
}
@@ -947,9 +994,14 @@ static int enable_edo_mode(struct gpmi_nand_data *this, int mode)
nand->select_chip(mtd, -1);
+ pm_runtime_get_sync(this->dev);
+ clk_disable_unprepare(r->clock[0]);
/* [3] set the main IO clock, 100MHz for mode 5, 80MHz for mode 4. */
rate = (mode == 5) ? 100000000 : 80000000;
clk_set_rate(r->clock[0], rate);
+ clk_prepare_enable(r->clock[0]);
+ pm_runtime_mark_last_busy(this->dev);
+ pm_runtime_put_autosuspend(this->dev);
/* Let the gpmi_begin() re-compute the timing again. */
this->flags &= ~GPMI_TIMING_INIT_OK;
@@ -972,7 +1024,8 @@ int gpmi_extra_init(struct gpmi_nand_data *this)
struct nand_chip *chip = &this->nand;
/* Enable the asynchronous EDO feature. */
- if (GPMI_IS_MX6(this) && chip->onfi_version) {
+ if ((GPMI_IS_MX6(this) || GPMI_IS_MX8(this))
+ && chip->onfi_version) {
int mode = onfi_get_async_timing_mode(chip);
/* We only support the timing mode 4 and mode 5. */
@@ -1000,9 +1053,9 @@ void gpmi_begin(struct gpmi_nand_data *this)
int ret;
/* Enable the clock. */
- ret = gpmi_enable_clk(this);
- if (ret) {
- dev_err(this->dev, "We failed in enable the clk\n");
+ ret = pm_runtime_get_sync(this->dev);
+ if (ret < 0) {
+ dev_err(this->dev, "Failed to enable clock\n");
goto err_out;
}
@@ -1074,7 +1127,8 @@ err_out:
void gpmi_end(struct gpmi_nand_data *this)
{
- gpmi_disable_clk(this);
+ pm_runtime_mark_last_busy(this->dev);
+ pm_runtime_put_autosuspend(this->dev);
}
/* Clears a BCH interrupt. */
@@ -1094,12 +1148,13 @@ int gpmi_is_ready(struct gpmi_nand_data *this, unsigned chip)
if (GPMI_IS_MX23(this)) {
mask = MX23_BM_GPMI_DEBUG_READY0 << chip;
reg = readl(r->gpmi_regs + HW_GPMI_DEBUG);
- } else if (GPMI_IS_MX28(this) || GPMI_IS_MX6(this)) {
+ } else if (GPMI_IS_MX28(this) || GPMI_IS_MX6(this) ||
+ GPMI_IS_MX8(this)) {
/*
* In the imx6, all the ready/busy pins are bound
* together. So we only need to check chip 0.
*/
- if (GPMI_IS_MX6(this))
+ if (GPMI_IS_MX6(this) || GPMI_IS_MX8(this))
chip = 0;
/* MX28 shares the same R/B register as MX6Q. */
diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
index d4d824ef64e9..bb8d50211fb1 100644
--- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
+++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
@@ -26,6 +26,8 @@
#include <linux/mtd/partitions.h>
#include <linux/of.h>
#include <linux/of_device.h>
+#include <linux/busfreq-imx.h>
+#include <linux/pm_runtime.h>
#include "gpmi-nand.h"
#include "bch-regs.h"
@@ -34,6 +36,8 @@
#define GPMI_NAND_BCH_REGS_ADDR_RES_NAME "bch"
#define GPMI_NAND_BCH_INTERRUPT_RES_NAME "bch"
+#define GPMI_RPM_TIMEOUT 50 /* ms */
+
/* add our owner bbt descriptor */
static uint8_t scan_ff_pattern[] = { 0xff };
static struct nand_bbt_descr gpmi_bbt_descr = {
@@ -119,6 +123,14 @@ static const struct gpmi_devdata gpmi_devdata_imx6q = {
.clks_count = ARRAY_SIZE(gpmi_clks_for_mx6),
};
+static const struct gpmi_devdata gpmi_devdata_imx6qp = {
+ .type = IS_MX6QP,
+ .bch_max_ecc_strength = 40,
+ .max_chain_delay = 12,
+ .clks = gpmi_clks_for_mx6,
+ .clks_count = ARRAY_SIZE(gpmi_clks_for_mx6),
+};
+
static const struct gpmi_devdata gpmi_devdata_imx6sx = {
.type = IS_MX6SX,
.bch_max_ecc_strength = 62,
@@ -127,6 +139,14 @@ static const struct gpmi_devdata gpmi_devdata_imx6sx = {
.clks_count = ARRAY_SIZE(gpmi_clks_for_mx6),
};
+static const struct gpmi_devdata gpmi_devdata_imx6ul = {
+ .type = IS_MX6UL,
+ .bch_max_ecc_strength = 40,
+ .max_chain_delay = 12,
+ .clks = gpmi_clks_for_mx6,
+ .clks_count = ARRAY_SIZE(gpmi_clks_for_mx6),
+};
+
static const char * const gpmi_clks_for_mx7d[] = {
"gpmi_io", "gpmi_bch_apb",
};
@@ -139,6 +159,26 @@ static const struct gpmi_devdata gpmi_devdata_imx7d = {
.clks_count = ARRAY_SIZE(gpmi_clks_for_mx7d),
};
+static const struct gpmi_devdata gpmi_devdata_imx6ull = {
+ .type = IS_MX6ULL,
+ .bch_max_ecc_strength = 40,
+ .max_chain_delay = 12,
+ .clks = gpmi_clks_for_mx6,
+ .clks_count = ARRAY_SIZE(gpmi_clks_for_mx6),
+};
+
+static const char * gpmi_clks_for_mx8qxp[GPMI_CLK_MAX] = {
+ "gpmi_apb", "gpmi_bch", "gpmi_apb_bch",
+};
+
+static const struct gpmi_devdata gpmi_devdata_imx8qxp = {
+ .type = IS_MX8QXP,
+ .bch_max_ecc_strength = 62,
+ .max_chain_delay = 12,
+ .clks = gpmi_clks_for_mx8qxp,
+ .clks_count = ARRAY_SIZE(gpmi_clks_for_mx8qxp),
+};
+
static irqreturn_t bch_irq(int irq, void *cookie)
{
struct gpmi_nand_data *this = cookie;
@@ -192,6 +232,36 @@ static inline bool gpmi_check_ecc(struct gpmi_nand_data *this)
return geo->ecc_strength <= this->devdata->bch_max_ecc_strength;
}
+static inline bool bbm_in_data_chunk(struct gpmi_nand_data *this,
+ unsigned int *chunk_num)
+{
+ struct bch_geometry *geo = &this->bch_geometry;
+ struct mtd_info *mtd = &this->nand.mtd;
+ unsigned int i, j;
+
+ if (geo->ecc_chunk0_size != geo->ecc_chunkn_size) {
+ dev_err(this->dev, "The size of chunk0 must equal to chunkn\n");
+ return false;
+ }
+
+ i = (mtd->writesize * 8 - geo->metadata_size * 8) /
+ (geo->gf_len * geo->ecc_strength +
+ geo->ecc_chunkn_size * 8);
+
+ j = (mtd->writesize * 8 - geo->metadata_size * 8) -
+ (geo->gf_len * geo->ecc_strength +
+ geo->ecc_chunkn_size * 8) * i;
+
+ if (j < geo->ecc_chunkn_size * 8) {
+ *chunk_num = i+1;
+ dev_dbg(this->dev, "Set ecc to %d and bbm in chunk %d\n",
+ geo->ecc_strength, *chunk_num);
+ return true;
+ }
+
+ return false;
+}
+
/*
* If we can get the ECC information from the nand chip, we do not
* need to calculate them ourselves.
@@ -221,13 +291,14 @@ static int set_geometry_by_ecc_info(struct gpmi_nand_data *this)
chip->ecc_strength_ds, chip->ecc_step_ds);
return -EINVAL;
}
- geo->ecc_chunk_size = chip->ecc_step_ds;
+ geo->ecc_chunk0_size = chip->ecc_step_ds;
+ geo->ecc_chunkn_size = chip->ecc_step_ds;
geo->ecc_strength = round_up(chip->ecc_strength_ds, 2);
if (!gpmi_check_ecc(this))
return -EINVAL;
/* Keep the C >= O */
- if (geo->ecc_chunk_size < mtd->oobsize) {
+ if (geo->ecc_chunkn_size < mtd->oobsize) {
dev_err(this->dev,
"unsupported nand chip. ecc size: %d, oob size : %d\n",
chip->ecc_step_ds, mtd->oobsize);
@@ -237,7 +308,7 @@ static int set_geometry_by_ecc_info(struct gpmi_nand_data *this)
/* The default value, see comment in the legacy_set_geometry(). */
geo->metadata_size = 10;
- geo->ecc_chunk_count = mtd->writesize / geo->ecc_chunk_size;
+ geo->ecc_chunk_count = mtd->writesize / geo->ecc_chunkn_size;
/*
* Now, the NAND chip with 2K page(data chunk is 512byte) shows below:
@@ -309,6 +380,132 @@ static int set_geometry_by_ecc_info(struct gpmi_nand_data *this)
return 0;
}
+static int set_geometry_for_large_oob(struct gpmi_nand_data *this)
+{
+ struct bch_geometry *geo = &this->bch_geometry;
+ struct mtd_info *mtd = &this->nand.mtd;
+ struct nand_chip *chip = mtd_to_nand(mtd);
+ unsigned int block_mark_bit_offset;
+ unsigned int max_ecc;
+ unsigned int bbm_chunk;
+ unsigned int i;
+
+
+ /* sanity check for the minimum ecc nand required */
+ if (!(chip->ecc_strength_ds > 0 && chip->ecc_step_ds > 0))
+ return -EINVAL;
+ geo->ecc_strength = chip->ecc_strength_ds;
+
+ /* check if platform can support this nand */
+ if (!gpmi_check_ecc(this)) {
+ dev_err(this->dev,
+ "unsupported NAND chip,\
+ minimum ecc required %d\n"
+ , geo->ecc_strength);
+ return -EINVAL;
+ }
+
+ /* calculate the maximum ecc platform can support*/
+ geo->metadata_size = 10;
+ geo->gf_len = 14;
+ geo->ecc_chunk0_size = 1024;
+ geo->ecc_chunkn_size = 1024;
+ geo->ecc_chunk_count = mtd->writesize / geo->ecc_chunkn_size;
+ max_ecc = min(get_ecc_strength(this),
+ this->devdata->bch_max_ecc_strength);
+
+ /* search a supported ecc strength that makes bbm */
+ /* located in data chunk */
+ geo->ecc_strength = chip->ecc_strength_ds;
+ while (!(geo->ecc_strength > max_ecc)) {
+ if (bbm_in_data_chunk(this, &bbm_chunk))
+ goto geo_setting;
+ geo->ecc_strength += 2;
+ }
+
+ /* if none of them works, keep using the minimum ecc */
+ /* nand required but changing ecc page layout */
+ geo->ecc_strength = chip->ecc_strength_ds;
+ /* add extra ecc for meta data */
+ geo->ecc_chunk0_size = 0;
+ geo->ecc_chunk_count = (mtd->writesize / geo->ecc_chunkn_size) + 1;
+ geo->ecc_for_meta = 1;
+ /* check if oob can afford this extra ecc chunk */
+ if (mtd->oobsize * 8 < geo->metadata_size * 8 +
+ geo->gf_len * geo->ecc_strength
+ * geo->ecc_chunk_count) {
+ dev_err(this->dev, "unsupported NAND chip with new layout\n");
+ return -EINVAL;
+ }
+
+ /* calculate in which chunk bbm located */
+ bbm_chunk = (mtd->writesize * 8 - geo->metadata_size * 8 -
+ geo->gf_len * geo->ecc_strength) /
+ (geo->gf_len * geo->ecc_strength +
+ geo->ecc_chunkn_size * 8) + 1;
+
+geo_setting:
+
+ geo->page_size = mtd->writesize + geo->metadata_size +
+ (geo->gf_len * geo->ecc_strength * geo->ecc_chunk_count) / 8;
+ geo->payload_size = mtd->writesize;
+
+ /*
+ * The auxiliary buffer contains the metadata and the ECC status. The
+ * metadata is padded to the nearest 32-bit boundary. The ECC status
+ * contains one byte for every ECC chunk, and is also padded to the
+ * nearest 32-bit boundary.
+ */
+ geo->auxiliary_status_offset = ALIGN(geo->metadata_size, 4);
+ geo->auxiliary_size = ALIGN(geo->metadata_size, 4)
+ + ALIGN(geo->ecc_chunk_count, 4);
+
+ if (!this->swap_block_mark)
+ return 0;
+
+ /* calculate the number of ecc chunk behind the bbm */
+ i = (mtd->writesize / geo->ecc_chunkn_size) - bbm_chunk + 1;
+
+ block_mark_bit_offset = mtd->writesize * 8 -
+ (geo->ecc_strength * geo->gf_len * (geo->ecc_chunk_count - i)
+ + geo->metadata_size * 8);
+
+ geo->block_mark_byte_offset = block_mark_bit_offset / 8;
+ geo->block_mark_bit_offset = block_mark_bit_offset % 8;
+
+ dev_dbg(this->dev, "BCH Geometry :\n"
+ "GF length : %u\n"
+ "ECC Strength : %u\n"
+ "Page Size in Bytes : %u\n"
+ "Metadata Size in Bytes : %u\n"
+ "ECC Chunk0 Size in Bytes: %u\n"
+ "ECC Chunkn Size in Bytes: %u\n"
+ "ECC Chunk Count : %u\n"
+ "Payload Size in Bytes : %u\n"
+ "Auxiliary Size in Bytes: %u\n"
+ "Auxiliary Status Offset: %u\n"
+ "Block Mark Byte Offset : %u\n"
+ "Block Mark Bit Offset : %u\n"
+ "Block Mark in chunk : %u\n"
+ "Ecc for Meta data : %u\n",
+ geo->gf_len,
+ geo->ecc_strength,
+ geo->page_size,
+ geo->metadata_size,
+ geo->ecc_chunk0_size,
+ geo->ecc_chunkn_size,
+ geo->ecc_chunk_count,
+ geo->payload_size,
+ geo->auxiliary_size,
+ geo->auxiliary_status_offset,
+ geo->block_mark_byte_offset,
+ geo->block_mark_bit_offset,
+ bbm_chunk,
+ geo->ecc_for_meta);
+
+ return 0;
+}
+
static int legacy_set_geometry(struct gpmi_nand_data *this)
{
struct bch_geometry *geo = &this->bch_geometry;
@@ -328,20 +525,22 @@ static int legacy_set_geometry(struct gpmi_nand_data *this)
geo->gf_len = 13;
/* The default for chunk size. */
- geo->ecc_chunk_size = 512;
- while (geo->ecc_chunk_size < mtd->oobsize) {
- geo->ecc_chunk_size *= 2; /* keep C >= O */
+ geo->ecc_chunk0_size = 512;
+ geo->ecc_chunkn_size = 512;
+ while (geo->ecc_chunkn_size < mtd->oobsize) {
+ geo->ecc_chunk0_size *= 2; /* keep C >= O */
+ geo->ecc_chunkn_size *= 2; /* keep C >= O */
geo->gf_len = 14;
}
- geo->ecc_chunk_count = mtd->writesize / geo->ecc_chunk_size;
+ geo->ecc_chunk_count = mtd->writesize / geo->ecc_chunkn_size;
/* We use the same ECC strength for all chunks. */
geo->ecc_strength = get_ecc_strength(this);
if (!gpmi_check_ecc(this)) {
dev_err(this->dev,
"ecc strength: %d cannot be supported by the controller (%d)\n"
- "try to use minimum ecc strength that NAND chip required\n",
+ "try to use maximum ecc strength that NAND chip required\n",
geo->ecc_strength,
this->devdata->bch_max_ecc_strength);
return -EINVAL;
@@ -423,11 +622,26 @@ static int legacy_set_geometry(struct gpmi_nand_data *this)
int common_nfc_set_geometry(struct gpmi_nand_data *this)
{
- if ((of_property_read_bool(this->dev->of_node, "fsl,use-minimum-ecc"))
- || legacy_set_geometry(this))
- return set_geometry_by_ecc_info(this);
+ struct mtd_info *mtd = &this->nand.mtd;
+ struct nand_chip *chip = mtd_to_nand(mtd);
- return 0;
+ if (chip->ecc_strength_ds > this->devdata->bch_max_ecc_strength) {
+ dev_err(this->dev,
+ "unsupported NAND chip, minimum ecc required %d\n"
+ , chip->ecc_strength_ds);
+ return -EINVAL;
+ }
+
+ if ((!(chip->ecc_strength_ds > 0 && chip->ecc_step_ds > 0) &&
+ (mtd->oobsize < 1024)) || this->legacy_bch_geometry) {
+ dev_warn(this->dev, "use legacy bch geometry\n");
+ return legacy_set_geometry(this);
+ }
+
+ if (mtd->oobsize > 1024 || chip->ecc_step_ds < mtd->oobsize)
+ return set_geometry_for_large_oob(this);
+
+ return set_geometry_by_ecc_info(this);
}
struct dma_chan *get_dma_chan(struct gpmi_nand_data *this)
@@ -611,6 +825,9 @@ static int acquire_dma_channels(struct gpmi_nand_data *this)
{
struct platform_device *pdev = this->pdev;
struct dma_chan *dma_chan;
+ struct device_node *np = pdev->dev.of_node;
+
+ of_dma_configure(&pdev->dev, np);
/* request dma channel */
dma_chan = dma_request_slave_channel(&pdev->dev, "rx-tx");
@@ -643,7 +860,7 @@ static int gpmi_get_clks(struct gpmi_nand_data *this)
r->clock[i] = clk;
}
- if (GPMI_IS_MX6(this))
+ if (GPMI_IS_MX6(this) || GPMI_IS_MX8(this))
/*
* Set the default value for the gpmi clock.
*
@@ -659,6 +876,15 @@ err_clock:
return err;
}
+static int init_rpm(struct gpmi_nand_data *this)
+{
+ pm_runtime_enable(this->dev);
+ pm_runtime_set_autosuspend_delay(this->dev, GPMI_RPM_TIMEOUT);
+ pm_runtime_use_autosuspend(this->dev);
+
+ return 0;
+}
+
static int acquire_resources(struct gpmi_nand_data *this)
{
int ret;
@@ -675,13 +901,10 @@ static int acquire_resources(struct gpmi_nand_data *this)
if (ret)
goto exit_regs;
- ret = acquire_dma_channels(this);
- if (ret)
- goto exit_regs;
-
ret = gpmi_get_clks(this);
if (ret)
goto exit_clock;
+
return 0;
exit_clock:
@@ -1034,6 +1257,7 @@ static int gpmi_ecc_read_page(struct mtd_info *mtd, struct nand_chip *chip,
{
struct gpmi_nand_data *this = nand_get_controller_data(chip);
struct bch_geometry *nfc_geo = &this->bch_geometry;
+ void __iomem *bch_regs = this->resources.bch_regs;
void *payload_virt;
dma_addr_t payload_phys;
void *auxiliary_virt;
@@ -1042,6 +1266,7 @@ static int gpmi_ecc_read_page(struct mtd_info *mtd, struct nand_chip *chip,
unsigned char *status;
unsigned int max_bitflips = 0;
int ret;
+ int flag = 0;
dev_dbg(this->dev, "page number is : %d\n", page);
ret = read_page_prepare(this, buf, nfc_geo->payload_size,
@@ -1076,8 +1301,16 @@ static int gpmi_ecc_read_page(struct mtd_info *mtd, struct nand_chip *chip,
payload_virt, payload_phys);
for (i = 0; i < nfc_geo->ecc_chunk_count; i++, status++) {
- if ((*status == STATUS_GOOD) || (*status == STATUS_ERASED))
+ if (*status == STATUS_GOOD)
+ continue;
+
+ if (*status == STATUS_ERASED) {
+ if (GPMI_IS_MX6QP(this) || GPMI_IS_MX7D(this) ||
+ GPMI_IS_MX6UL(this))
+ if (readl(bch_regs + HW_BCH_DEBUG1))
+ flag = 1;
continue;
+ }
if (*status == STATUS_UNCORRECTABLE) {
int eccbits = nfc_geo->ecc_strength * nfc_geo->gf_len;
@@ -1088,7 +1321,7 @@ static int gpmi_ecc_read_page(struct mtd_info *mtd, struct nand_chip *chip,
/* Read ECC bytes into our internal raw_buffer */
offset = nfc_geo->metadata_size * 8;
- offset += ((8 * nfc_geo->ecc_chunk_size) + eccbits) * (i + 1);
+ offset += ((8 * nfc_geo->ecc_chunkn_size) + eccbits) * (i + 1);
offset -= eccbits;
bitoffset = offset % 8;
eccbytes = DIV_ROUND_UP(offset + eccbits, 8);
@@ -1125,16 +1358,16 @@ static int gpmi_ecc_read_page(struct mtd_info *mtd, struct nand_chip *chip,
if (i == 0) {
/* The first block includes metadata */
flips = nand_check_erased_ecc_chunk(
- buf + i * nfc_geo->ecc_chunk_size,
- nfc_geo->ecc_chunk_size,
+ buf + i * nfc_geo->ecc_chunkn_size,
+ nfc_geo->ecc_chunkn_size,
eccbuf, eccbytes,
auxiliary_virt,
nfc_geo->metadata_size,
nfc_geo->ecc_strength);
} else {
flips = nand_check_erased_ecc_chunk(
- buf + i * nfc_geo->ecc_chunk_size,
- nfc_geo->ecc_chunk_size,
+ buf + i * nfc_geo->ecc_chunkn_size,
+ nfc_geo->ecc_chunkn_size,
eccbuf, eccbytes,
NULL, 0,
nfc_geo->ecc_strength);
@@ -1173,6 +1406,10 @@ static int gpmi_ecc_read_page(struct mtd_info *mtd, struct nand_chip *chip,
chip->oob_poi[0] = ((uint8_t *) auxiliary_virt)[0];
}
+ /* if bitflip occurred in erased page, change data to all 0xff */
+ if (flag)
+ memset(buf, 0xff, nfc_geo->payload_size);
+
return max_bitflips;
}
@@ -1217,9 +1454,23 @@ static int gpmi_ecc_read_subpage(struct mtd_info *mtd, struct nand_chip *chip,
}
}
+ /*
+ * if there is an ECC dedicate for meta:
+ * - need to add an extra ECC size when calculating col and page_size,
+ * if the meta size is NOT zero.
+ *
+ * - chunk0 size need to set to the same size as other chunks,
+ * if the meta size is zero.
+ */
+
meta = geo->metadata_size;
if (first) {
- col = meta + (size + ecc_parity_size) * first;
+ if (geo->ecc_for_meta)
+ col = meta + ecc_parity_size
+ + (size + ecc_parity_size) * first;
+ else
+ col = meta + (size + ecc_parity_size) * first;
+
chip->cmdfunc(mtd, NAND_CMD_RNDOUT, col, -1);
meta = 0;
@@ -1232,21 +1483,37 @@ static int gpmi_ecc_read_subpage(struct mtd_info *mtd, struct nand_chip *chip,
/* change the BCH registers and bch_geometry{} */
n = last - first + 1;
- page_size = meta + (size + ecc_parity_size) * n;
+
+ if (geo->ecc_for_meta && meta)
+ page_size = meta + ecc_parity_size
+ + (size + ecc_parity_size) * n;
+ else
+ page_size = meta + (size + ecc_parity_size) * n;
r1_new &= ~(BM_BCH_FLASH0LAYOUT0_NBLOCKS |
BM_BCH_FLASH0LAYOUT0_META_SIZE);
- r1_new |= BF_BCH_FLASH0LAYOUT0_NBLOCKS(n - 1)
+ r1_new |= BF_BCH_FLASH0LAYOUT0_NBLOCKS(
+ (geo->ecc_for_meta && meta) ? n : n - 1)
| BF_BCH_FLASH0LAYOUT0_META_SIZE(meta);
+
+ /* set chunk0 size if meta size is 0 */
+ if (!meta) {
+ if (GPMI_IS_MX6(this) || GPMI_IS_MX8(this))
+ r1_new &= ~MX6Q_BM_BCH_FLASH0LAYOUT0_DATA0_SIZE;
+ else
+ r1_new &= ~BM_BCH_FLASH0LAYOUT0_DATA0_SIZE;
+ r1_new |= BF_BCH_FLASH0LAYOUT0_DATA0_SIZE(size, this);
+ }
writel(r1_new, bch_regs + HW_BCH_FLASH0LAYOUT0);
r2_new &= ~BM_BCH_FLASH0LAYOUT1_PAGE_SIZE;
r2_new |= BF_BCH_FLASH0LAYOUT1_PAGE_SIZE(page_size);
writel(r2_new, bch_regs + HW_BCH_FLASH0LAYOUT1);
- geo->ecc_chunk_count = n;
+ geo->ecc_chunk_count = (geo->ecc_for_meta && meta) ? n + 1 : n;
geo->payload_size = n * size;
geo->page_size = page_size;
+ geo->metadata_size = meta;
geo->auxiliary_status_offset = ALIGN(meta, 4);
dev_dbg(this->dev, "page:%d(%d:%d)%d, chunk:(%d:%d), BCH PG size:%d\n",
@@ -1468,7 +1735,7 @@ static int gpmi_ecc_read_page_raw(struct mtd_info *mtd,
{
struct gpmi_nand_data *this = nand_get_controller_data(chip);
struct bch_geometry *nfc_geo = &this->bch_geometry;
- int eccsize = nfc_geo->ecc_chunk_size;
+ int eccsize = nfc_geo->ecc_chunkn_size;
int eccbits = nfc_geo->ecc_strength * nfc_geo->gf_len;
u8 *tmp_buf = this->raw_buffer;
size_t src_bit_off;
@@ -1476,6 +1743,7 @@ static int gpmi_ecc_read_page_raw(struct mtd_info *mtd,
size_t oob_byte_off;
uint8_t *oob = chip->oob_poi;
int step;
+ int ecc_chunk_count;
chip->read_buf(mtd, tmp_buf,
mtd->writesize + mtd->oobsize);
@@ -1503,9 +1771,21 @@ static int gpmi_ecc_read_page_raw(struct mtd_info *mtd,
oob_bit_off = nfc_geo->metadata_size * 8;
src_bit_off = oob_bit_off;
+ ecc_chunk_count = nfc_geo->ecc_chunk_count;
+
+ /* if bch requires dedicate ecc for meta */
+ if (nfc_geo->ecc_for_meta) {
+ if (oob_required)
+ gpmi_copy_bits(oob, oob_bit_off,
+ tmp_buf, src_bit_off,
+ eccbits);
+ src_bit_off += eccbits;
+ oob_bit_off += eccbits;
+ ecc_chunk_count = nfc_geo->ecc_chunk_count - 1;
+ }
/* Extract interleaved payload data and ECC bits */
- for (step = 0; step < nfc_geo->ecc_chunk_count; step++) {
+ for (step = 0; step < ecc_chunk_count; step++) {
if (buf)
gpmi_copy_bits(buf, step * eccsize * 8,
tmp_buf, src_bit_off,
@@ -1513,7 +1793,7 @@ static int gpmi_ecc_read_page_raw(struct mtd_info *mtd,
src_bit_off += eccsize * 8;
/* Align last ECC block to align a byte boundary */
- if (step == nfc_geo->ecc_chunk_count - 1 &&
+ if (step == ecc_chunk_count - 1 &&
(oob_bit_off + eccbits) % 8)
eccbits += 8 - ((oob_bit_off + eccbits) % 8);
@@ -1557,7 +1837,7 @@ static int gpmi_ecc_write_page_raw(struct mtd_info *mtd,
{
struct gpmi_nand_data *this = nand_get_controller_data(chip);
struct bch_geometry *nfc_geo = &this->bch_geometry;
- int eccsize = nfc_geo->ecc_chunk_size;
+ int eccsize = nfc_geo->ecc_chunkn_size;
int eccbits = nfc_geo->ecc_strength * nfc_geo->gf_len;
u8 *tmp_buf = this->raw_buffer;
uint8_t *oob = chip->oob_poi;
@@ -1565,6 +1845,7 @@ static int gpmi_ecc_write_page_raw(struct mtd_info *mtd,
size_t oob_bit_off;
size_t oob_byte_off;
int step;
+ int ecc_chunk_count;
/*
* Initialize all bits to 1 in case we don't have a buffer for the
@@ -1581,16 +1862,28 @@ static int gpmi_ecc_write_page_raw(struct mtd_info *mtd,
memcpy(tmp_buf, oob, nfc_geo->metadata_size);
oob_bit_off = nfc_geo->metadata_size * 8;
dst_bit_off = oob_bit_off;
+ ecc_chunk_count = nfc_geo->ecc_chunk_count;
+
+ /* if bch requires dedicate ecc for meta */
+ if (nfc_geo->ecc_for_meta) {
+ if (oob_required)
+ gpmi_copy_bits(tmp_buf, dst_bit_off,
+ oob, oob_bit_off, eccbits);
+
+ dst_bit_off += eccbits;
+ oob_bit_off += eccbits;
+ ecc_chunk_count = nfc_geo->ecc_chunk_count - 1;
+ }
/* Interleave payload data and ECC bits */
- for (step = 0; step < nfc_geo->ecc_chunk_count; step++) {
+ for (step = 0; step < ecc_chunk_count; step++) {
if (buf)
gpmi_copy_bits(tmp_buf, dst_bit_off,
buf, step * eccsize * 8, eccsize * 8);
dst_bit_off += eccsize * 8;
/* Align last ECC block to align a byte boundary */
- if (step == nfc_geo->ecc_chunk_count - 1 &&
+ if (step == ecc_chunk_count - 1 &&
(oob_bit_off + eccbits) % 8)
eccbits += 8 - ((oob_bit_off + eccbits) % 8);
@@ -1880,7 +2173,7 @@ static int mx23_boot_init(struct gpmi_nand_data *this)
*/
chipnr = block >> (chip->chip_shift - chip->phys_erase_shift);
page = block << (chip->phys_erase_shift - chip->page_shift);
- byte = block << chip->phys_erase_shift;
+ byte = (loff_t) block << chip->phys_erase_shift;
/* Send the command to read the conventional block mark. */
chip->select_chip(mtd, chipnr);
@@ -1949,6 +2242,11 @@ static int gpmi_init_last(struct gpmi_nand_data *this)
if (ret)
return ret;
+ /* Save the geometry to debugfs*/
+ ret = bch_create_debugfs(this);
+ if (ret)
+ return ret;
+
/* Init the nand_ecc_ctrl{} */
ecc->read_page = gpmi_ecc_read_page;
ecc->write_page = gpmi_ecc_write_page;
@@ -1959,7 +2257,7 @@ static int gpmi_init_last(struct gpmi_nand_data *this)
ecc->read_oob_raw = gpmi_ecc_read_oob_raw;
ecc->write_oob_raw = gpmi_ecc_write_oob_raw;
ecc->mode = NAND_ECC_HW;
- ecc->size = bch_geo->ecc_chunk_size;
+ ecc->size = bch_geo->ecc_chunkn_size;
ecc->strength = bch_geo->ecc_strength;
mtd_set_ooblayout(mtd, &gpmi_ooblayout_ops);
@@ -1968,7 +2266,7 @@ static int gpmi_init_last(struct gpmi_nand_data *this)
* (1) the chip is imx6, and
* (2) the size of the ECC parity is byte aligned.
*/
- if (GPMI_IS_MX6(this) &&
+ if ((GPMI_IS_MX6(this) || GPMI_IS_MX8(this)) &&
((bch_geo->gf_len * bch_geo->ecc_strength) % 8) == 0) {
ecc->read_subpage = gpmi_ecc_read_subpage;
chip->options |= NAND_SUBPAGE_READ;
@@ -2024,7 +2322,7 @@ static int gpmi_nand_init(struct gpmi_nand_data *this)
if (ret)
goto err_out;
- ret = nand_scan_ident(mtd, GPMI_IS_MX6(this) ? 2 : 1, NULL);
+ ret = nand_scan_ident(mtd, (GPMI_IS_MX6(this) || GPMI_IS_MX8(this)) ? 2 : 1, NULL);
if (ret)
goto err_out;
@@ -2034,6 +2332,10 @@ static int gpmi_nand_init(struct gpmi_nand_data *this)
if (of_property_read_bool(this->dev->of_node,
"fsl,no-blockmark-swap"))
this->swap_block_mark = false;
+
+ if (of_property_read_bool(this->dev->of_node,
+ "fsl,legacy-bch-geometry"))
+ this->legacy_bch_geometry = true;
}
dev_dbg(this->dev, "Blockmark swapping %sabled\n",
this->swap_block_mark ? "en" : "dis");
@@ -2077,11 +2379,23 @@ static const struct of_device_id gpmi_nand_id_table[] = {
.compatible = "fsl,imx6q-gpmi-nand",
.data = &gpmi_devdata_imx6q,
}, {
+ .compatible = "fsl,imx6qp-gpmi-nand",
+ .data = (void *)&gpmi_devdata_imx6qp,
+ }, {
.compatible = "fsl,imx6sx-gpmi-nand",
.data = &gpmi_devdata_imx6sx,
}, {
+ .compatible = "fsl,imx6ul-gpmi-nand",
+ .data = (void *)&gpmi_devdata_imx6ul,
+ }, {
.compatible = "fsl,imx7d-gpmi-nand",
.data = &gpmi_devdata_imx7d,
+ }, {
+ .compatible = "fsl,imx6ull-gpmi-nand",
+ .data = &gpmi_devdata_imx6ull,
+ }, {
+ .compatible = "fsl,imx8qxp-gpmi-nand",
+ .data = &gpmi_devdata_imx8qxp,
}, {}
};
MODULE_DEVICE_TABLE(of, gpmi_nand_id_table);
@@ -2112,18 +2426,25 @@ static int gpmi_nand_probe(struct platform_device *pdev)
if (ret)
goto exit_acquire_resources;
- ret = init_hardware(this);
+ ret = init_rpm(this);
if (ret)
goto exit_nfc_init;
+ ret = init_hardware(this);
+ if (ret)
+ goto exit_rpm;
+
ret = gpmi_nand_init(this);
if (ret)
- goto exit_nfc_init;
+ goto exit_rpm;
dev_info(this->dev, "driver registered.\n");
return 0;
+exit_rpm:
+ pm_runtime_dont_use_autosuspend(this->dev);
+ pm_runtime_disable(this->dev);
exit_nfc_init:
release_resources(this);
exit_acquire_resources:
@@ -2135,8 +2456,10 @@ static int gpmi_nand_remove(struct platform_device *pdev)
{
struct gpmi_nand_data *this = platform_get_drvdata(pdev);
+ release_bus_freq(BUS_FREQ_HIGH);
nand_release(nand_to_mtd(&this->nand));
gpmi_free_dma_buffer(this);
+ pm_runtime_disable(this->dev);
release_resources(this);
return 0;
}
@@ -2144,10 +2467,12 @@ static int gpmi_nand_remove(struct platform_device *pdev)
#ifdef CONFIG_PM_SLEEP
static int gpmi_pm_suspend(struct device *dev)
{
- struct gpmi_nand_data *this = dev_get_drvdata(dev);
+ int ret;
- release_dma_channels(this);
- return 0;
+ pinctrl_pm_select_sleep_state(dev);
+ ret = pm_runtime_force_suspend(dev);
+
+ return ret;
}
static int gpmi_pm_resume(struct device *dev)
@@ -2155,9 +2480,14 @@ static int gpmi_pm_resume(struct device *dev)
struct gpmi_nand_data *this = dev_get_drvdata(dev);
int ret;
- ret = acquire_dma_channels(this);
- if (ret < 0)
+ /* enable clock, acquire dma */
+ ret = pm_runtime_force_resume(dev);
+ if (ret) {
+ dev_err(this->dev, "Error in resume: %d\n", ret);
return ret;
+ }
+
+ pinctrl_pm_select_default_state(dev);
/* re-init the GPMI registers */
this->flags &= ~GPMI_TIMING_INIT_OK;
@@ -2181,7 +2511,40 @@ static int gpmi_pm_resume(struct device *dev)
}
#endif /* CONFIG_PM_SLEEP */
+#define gpmi_enable_clk(x) __gpmi_enable_clk(x, true)
+#define gpmi_disable_clk(x) __gpmi_enable_clk(x, false)
+
+int gpmi_runtime_suspend(struct device *dev)
+{
+ struct gpmi_nand_data *this = dev_get_drvdata(dev);
+
+ gpmi_disable_clk(this);
+ release_bus_freq(BUS_FREQ_HIGH);
+ release_dma_channels(this);
+
+ return 0;
+}
+
+int gpmi_runtime_resume(struct device *dev)
+{
+ struct gpmi_nand_data *this = dev_get_drvdata(dev);
+ int ret;
+
+ ret = gpmi_enable_clk(this);
+ if (ret)
+ return ret;
+
+ request_bus_freq(BUS_FREQ_HIGH);
+
+ ret = acquire_dma_channels(this);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
static const struct dev_pm_ops gpmi_pm_ops = {
+ SET_RUNTIME_PM_OPS(gpmi_runtime_suspend, gpmi_runtime_resume, NULL)
SET_SYSTEM_SLEEP_PM_OPS(gpmi_pm_suspend, gpmi_pm_resume)
};
diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.h b/drivers/mtd/nand/gpmi-nand/gpmi-nand.h
index a45e4ce13d10..c73133f63bf5 100644
--- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.h
+++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.h
@@ -1,7 +1,7 @@
/*
* Freescale GPMI NAND Flash Driver
*
- * Copyright (C) 2010-2011 Freescale Semiconductor, Inc.
+ * Copyright (C) 2010-2016 Freescale Semiconductor, Inc.
* Copyright (C) 2008 Embedded Alley Solutions, Inc.
*
* This program is free software; you can redistribute it and/or modify
@@ -39,9 +39,9 @@ struct resources {
* @page_size: The size, in bytes, of a physical page, including
* both data and OOB.
* @metadata_size: The size, in bytes, of the metadata.
- * @ecc_chunk_size: The size, in bytes, of a single ECC chunk. Note
- * the first chunk in the page includes both data and
- * metadata, so it's a bit larger than this value.
+ * @ecc_chunk0_size: The size, in bytes, of a first ECC chunk.
+ * @ecc_chunkn_size: The size, in bytes, of a single ECC chunk after
+ * the first chunk in the page.
* @ecc_chunk_count: The number of ECC chunks in the page,
* @payload_size: The size, in bytes, of the payload buffer.
* @auxiliary_size: The size, in bytes, of the auxiliary buffer.
@@ -51,19 +51,23 @@ struct resources {
* which the underlying physical block mark appears.
* @block_mark_bit_offset: The bit offset into the ECC-based page view at
* which the underlying physical block mark appears.
+ * @ecc_for_meta: The flag to indicate if there is a dedicate ecc
+ * for meta.
*/
struct bch_geometry {
unsigned int gf_len;
unsigned int ecc_strength;
unsigned int page_size;
unsigned int metadata_size;
- unsigned int ecc_chunk_size;
+ unsigned int ecc_chunk0_size;
+ unsigned int ecc_chunkn_size;
unsigned int ecc_chunk_count;
unsigned int payload_size;
unsigned int auxiliary_size;
unsigned int auxiliary_status_offset;
unsigned int block_mark_byte_offset;
unsigned int block_mark_bit_offset;
+ unsigned int ecc_for_meta; /* ECC for meta data */
};
/**
@@ -123,8 +127,12 @@ enum gpmi_type {
IS_MX23,
IS_MX28,
IS_MX6Q,
+ IS_MX6QP,
IS_MX6SX,
IS_MX7D,
+ IS_MX6UL,
+ IS_MX6ULL,
+ IS_MX8QXP,
};
struct gpmi_devdata {
@@ -192,6 +200,8 @@ struct gpmi_nand_data {
dma_addr_t auxiliary_phys;
void *raw_buffer;
+ /* legacy bch geometry flag */
+ bool legacy_bch_geometry;
/* DMA channels */
#define DMA_CHANS 8
@@ -278,10 +288,12 @@ extern int start_dma_with_bch_irq(struct gpmi_nand_data *,
struct dma_async_tx_descriptor *);
/* GPMI-NAND helper function library */
+extern int __gpmi_enable_clk(struct gpmi_nand_data *, bool v);
extern int gpmi_init(struct gpmi_nand_data *);
extern int gpmi_extra_init(struct gpmi_nand_data *);
extern void gpmi_clear_bch(struct gpmi_nand_data *);
extern void gpmi_dump_info(struct gpmi_nand_data *);
+extern int bch_create_debugfs(struct gpmi_nand_data *);
extern int bch_set_geometry(struct gpmi_nand_data *);
extern int gpmi_is_ready(struct gpmi_nand_data *, unsigned chip);
extern int gpmi_send_command(struct gpmi_nand_data *);
@@ -307,9 +319,15 @@ void gpmi_copy_bits(u8 *dst, size_t dst_bit_off,
#define GPMI_IS_MX23(x) ((x)->devdata->type == IS_MX23)
#define GPMI_IS_MX28(x) ((x)->devdata->type == IS_MX28)
#define GPMI_IS_MX6Q(x) ((x)->devdata->type == IS_MX6Q)
+#define GPMI_IS_MX6QP(x) ((x)->devdata->type == IS_MX6QP)
#define GPMI_IS_MX6SX(x) ((x)->devdata->type == IS_MX6SX)
#define GPMI_IS_MX7D(x) ((x)->devdata->type == IS_MX7D)
+#define GPMI_IS_MX6UL(x) ((x)->devdata->type == IS_MX6UL)
+#define GPMI_IS_MX6ULL(x) ((x)->devdata->type == IS_MX6ULL)
+#define GPMI_IS_MX8QXP(x) ((x)->devdata->type == IS_MX8QXP)
-#define GPMI_IS_MX6(x) (GPMI_IS_MX6Q(x) || GPMI_IS_MX6SX(x) || \
+#define GPMI_IS_MX6(x) (GPMI_IS_MX6Q(x) || GPMI_IS_MX6QP(x) || GPMI_IS_MX6SX(x) || \
+ GPMI_IS_MX6UL(x) || GPMI_IS_MX6ULL(x) || \
GPMI_IS_MX7D(x))
+#define GPMI_IS_MX8(x) (GPMI_IS_MX8QXP(x))
#endif
diff --git a/drivers/mtd/spi-nor/Kconfig b/drivers/mtd/spi-nor/Kconfig
index 14e8967c1dea..1ee8ac49ce4e 100644
--- a/drivers/mtd/spi-nor/Kconfig
+++ b/drivers/mtd/spi-nor/Kconfig
@@ -129,4 +129,10 @@ config SPI_STM32_QUADSPI
This enables support for the STM32 Quad SPI controller.
We only connect the NOR to this controller.
+config SPI_FSL_FLEXSPI
+ tristate "Freescale Flex SPI controller"
+ help
+ This enables support for the Flex SPI controller in master mode.
+ We only connect the NOR to this controller now.
+
endif # MTD_SPI_NOR
diff --git a/drivers/mtd/spi-nor/Makefile b/drivers/mtd/spi-nor/Makefile
index f4c61d282abd..c49d078000d5 100644
--- a/drivers/mtd/spi-nor/Makefile
+++ b/drivers/mtd/spi-nor/Makefile
@@ -11,3 +11,4 @@ obj-$(CONFIG_SPI_INTEL_SPI) += intel-spi.o
obj-$(CONFIG_SPI_INTEL_SPI_PCI) += intel-spi-pci.o
obj-$(CONFIG_SPI_INTEL_SPI_PLATFORM) += intel-spi-platform.o
obj-$(CONFIG_SPI_STM32_QUADSPI) += stm32-quadspi.o
+obj-$(CONFIG_SPI_FSL_FLEXSPI) += fsl-flexspi.o
diff --git a/drivers/mtd/spi-nor/fsl-flexspi.c b/drivers/mtd/spi-nor/fsl-flexspi.c
new file mode 100644
index 000000000000..ccdb3c5a2189
--- /dev/null
+++ b/drivers/mtd/spi-nor/fsl-flexspi.c
@@ -0,0 +1,1590 @@
+/*
+ * Freescale FlexSPI driver.
+ *
+ * Copyright 2017 NXP
+ *
+ * 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/interrupt.h>
+#include <linux/errno.h>
+#include <linux/platform_device.h>
+#include <linux/sched.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/timer.h>
+#include <linux/jiffies.h>
+#include <linux/completion.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/spi-nor.h>
+#include <linux/mutex.h>
+#include <linux/pm_qos.h>
+#include <linux/pci.h>
+#include <soc/imx8/sc/sci.h>
+#include <linux/pm_runtime.h>
+
+/* Board only enabled up to Quad mode, not Octal*/
+#define FLEXSPI_QUIRK_QUAD_ONLY (1 << 0)
+/* Maximum clock limitation */
+#define FLEXSPI_QUIRK_FREQ_LIMIT (1 << 1)
+/* Config DLL register */
+#define FLEXSPI_QUIRK_CONFIG_DLL (1 << 2)
+
+/* runtime pm timeout */
+#define FSL_FLEXSPI_RPM_TIMEOUT 50 /* 50ms */
+#define FREQ_1MHz 1000000 /* 1MHz */
+
+/* delay cell range */
+#define FLEXSPI_DLL_MIN 75 /* 75ps */
+#define FLEXSPI_DLL_MAX 225 /* 225ps */
+
+/* The registers */
+#define FLEXSPI_MCR0 0x00
+#define FLEXSPI_MCR0_AHB_TIMEOUT_SHIFT 24
+#define FLEXSPI_MCR0_AHB_TIMEOUT_MASK (0xFF << FLEXSPI_MCR0_AHB_TIMEOUT_SHIFT)
+#define FLEXSPI_MCR0_IP_TIMEOUT_SHIFT 16
+#define FLEXSPI_MCR0_IP_TIMEOUT_MASK (0xFF << FLEXSPI_MCR0_IP_TIMEOUT_SHIFT)
+#define FLEXSPI_MCR0_LEARN_EN_SHIFT 15
+#define FLEXSPI_MCR0_LEARN_EN_MASK (1 << FLEXSPI_MCR0_LEARN_EN_SHIFT)
+#define FLEXSPI_MCR0_SCRFRUN_EN_SHIFT 14
+#define FLEXSPI_MCR0_SCRFRUN_EN_MASK (1 << FLEXSPI_MCR0_SCRFRUN_EN_SHIFT)
+#define FLEXSPI_MCR0_OCTCOMB_EN_SHIFT 13
+#define FLEXSPI_MCR0_OCTCOMB_EN_MASK (1 << FLEXSPI_MCR0_OCTCOMB_EN_SHIFT)
+#define FLEXSPI_MCR0_DOZE_EN_SHIFT 12
+#define FLEXSPI_MCR0_DOZE_EN_MASK (1 << FLEXSPI_MCR0_DOZE_EN_SHIFT)
+#define FLEXSPI_MCR0_HSEN_SHIFT 11
+#define FLEXSPI_MCR0_HSEN_MASK (1 << FLEXSPI_MCR0_HSEN_SHIFT)
+#define FLEXSPI_MCR0_SERCLKDIV_SHIFT 8
+#define FLEXSPI_MCR0_SERCLKDIV_MASK (7 << FLEXSPI_MCR0_SERCLKDIV_SHIFT)
+#define FLEXSPI_MCR0_ATDF_EN_SHIFT 7
+#define FLEXSPI_MCR0_ATDF_EN_MASK (1 << FLEXSPI_MCR0_ATDF_EN_SHIFT)
+#define FLEXSPI_MCR0_ARDF_EN_SHIFT 6
+#define FLEXSPI_MCR0_ARDF_EN_MASK (1 << FLEXSPI_MCR0_ARDF_EN_SHIFT)
+#define FLEXSPI_MCR0_RXCLKSRC_SHIFT 4
+#define FLEXSPI_MCR0_RXCLKSRC_MASK (3 << FLEXSPI_MCR0_RXCLKSRC_SHIFT)
+#define FLEXSPI_MCR0_END_CFG_SHIFT 2
+#define FLEXSPI_MCR0_END_CFG_MASK (3 << FLEXSPI_MCR0_END_CFG_SHIFT)
+#define FLEXSPI_MCR0_MDIS_SHIFT 1
+#define FLEXSPI_MCR0_MDIS_MASK (1 << FLEXSPI_MCR0_MDIS_SHIFT)
+#define FLEXSPI_MCR0_SWRST_SHIFT 0
+#define FLEXSPI_MCR0_SWRST_MASK (1 << FLEXSPI_MCR0_SWRST_SHIFT)
+
+#define FLEXSPI_MCR1 0x04
+#define FLEXSPI_MCR1_SEQ_TIMEOUT_SHIFT 16
+#define FLEXSPI_MCR1_SEQ_TIMEOUT_MASK \
+ (0xFFFF << FLEXSPI_MCR1_SEQ_TIMEOUT_SHIFT)
+#define FLEXSPI_MCR1_AHB_TIMEOUT_SHIFT 0
+#define FLEXSPI_MCR1_AHB_TIMEOUT_MASK \
+ (0xFFFF << FLEXSPI_MCR1_AHB_TIMEOUT_SHIFT)
+
+#define FLEXSPI_MCR2 0x08
+#define FLEXSPI_MCR2_IDLE_WAIT_SHIFT 24
+#define FLEXSPI_MCR2_IDLE_WAIT_MASK (0xFF << FLEXSPI_MCR2_IDLE_WAIT_SHIFT)
+#define FLEXSPI_MCR2_SAMEFLASH_SHIFT 15
+#define FLEXSPI_MCR2_SAMEFLASH_MASK (1 << FLEXSPI_MCR2_SAMEFLASH_SHIFT)
+#define FLEXSPI_MCR2_CLRLRPHS_SHIFT 14
+#define FLEXSPI_MCR2_CLRLRPHS_MASK (1 << FLEXSPI_MCR2_CLRLRPHS_SHIFT)
+#define FLEXSPI_MCR2_ABRDATSZ_SHIFT 8
+#define FLEXSPI_MCR2_ABRDATSZ_MASK (1 << FLEXSPI_MCR2_ABRDATSZ_SHIFT)
+#define FLEXSPI_MCR2_ABRLEARN_SHIFT 7
+#define FLEXSPI_MCR2_ABRLEARN_MASK (1 << FLEXSPI_MCR2_ABRLEARN_SHIFT)
+#define FLEXSPI_MCR2_ABR_READ_SHIFT 6
+#define FLEXSPI_MCR2_ABR_READ_MASK (1 << FLEXSPI_MCR2_ABR_READ_SHIFT)
+#define FLEXSPI_MCR2_ABRWRITE_SHIFT 5
+#define FLEXSPI_MCR2_ABRWRITE_MASK (1 << FLEXSPI_MCR2_ABRWRITE_SHIFT)
+#define FLEXSPI_MCR2_ABRDUMMY_SHIFT 4
+#define FLEXSPI_MCR2_ABRDUMMY_MASK (1 << FLEXSPI_MCR2_ABRDUMMY_SHIFT)
+#define FLEXSPI_MCR2_ABR_MODE_SHIFT 3
+#define FLEXSPI_MCR2_ABR_MODE_MASK (1 << FLEXSPI_MCR2_ABR_MODE_SHIFT)
+#define FLEXSPI_MCR2_ABRCADDR_SHIFT 2
+#define FLEXSPI_MCR2_ABRCADDR_MASK (1 << FLEXSPI_MCR2_ABRCADDR_SHIFT)
+#define FLEXSPI_MCR2_ABRRADDR_SHIFT 1
+#define FLEXSPI_MCR2_ABRRADDR_MASK (1 << FLEXSPI_MCR2_ABRRADDR_SHIFT)
+#define FLEXSPI_MCR2_ABR_CMD_SHIFT 0
+#define FLEXSPI_MCR2_ABR_CMD_MASK (1 << FLEXSPI_MCR2_ABR_CMD_SHIFT)
+
+#define FLEXSPI_AHBCR 0x0c
+#define FLEXSPI_AHBCR_RDADDROPT_SHIFT 6
+#define FLEXSPI_AHBCR_RDADDROPT_MASK (1 << FLEXSPI_AHBCR_RDADDROPT_SHIFT)
+#define FLEXSPI_AHBCR_PREF_EN_SHIFT 5
+#define FLEXSPI_AHBCR_PREF_EN_MASK (1 << FLEXSPI_AHBCR_PREF_EN_SHIFT)
+#define FLEXSPI_AHBCR_BUFF_EN_SHIFT 4
+#define FLEXSPI_AHBCR_BUFF_EN_MASK (1 << FLEXSPI_AHBCR_BUFF_EN_SHIFT)
+#define FLEXSPI_AHBCR_CACH_EN_SHIFT 3
+#define FLEXSPI_AHBCR_CACH_EN_MASK (1 << FLEXSPI_AHBCR_CACH_EN_SHIFT)
+#define FLEXSPI_AHBCR_CLRTXBUF_SHIFT 2
+#define FLEXSPI_AHBCR_CLRTXBUF_MASK (1 << FLEXSPI_AHBCR_CLRTXBUF_SHIFT)
+#define FLEXSPI_AHBCR_CLRRXBUF_SHIFT 1
+#define FLEXSPI_AHBCR_CLRRXBUF_MASK (1 << FLEXSPI_AHBCR_CLRRXBUF_SHIFT)
+#define FLEXSPI_AHBCR_PAR_EN_SHIFT 0
+#define FLEXSPI_AHBCR_PAR_EN_MASK (1 << FLEXSPI_AHBCR_PAR_EN_SHIFT)
+
+#define FLEXSPI_INTEN 0x10
+#define FLEXSPI_INTEN_SCLKSBWR_SHIFT 9
+#define FLEXSPI_INTEN_SCLKSBWR_MASK (1 << FLEXSPI_INTEN_SCLKSBWR_SHIFT)
+#define FLEXSPI_INTEN_SCLKSBRD_SHIFT 8
+#define FLEXSPI_INTEN_SCLKSBRD_MASK (1 << FLEXSPI_INTEN_SCLKSBRD_SHIFT)
+#define FLEXSPI_INTEN_DATALRNFL_SHIFT 7
+#define FLEXSPI_INTEN_DATALRNFL_MASK (1 << FLEXSPI_INTEN_DATALRNFL_SHIFT)
+#define FLEXSPI_INTEN_IPTXWE_SHIFT 6
+#define FLEXSPI_INTEN_IPTXWE_MASK (1 << FLEXSPI_INTEN_IPTXWE_SHIFT)
+#define FLEXSPI_INTEN_IPRXWA_SHIFT 5
+#define FLEXSPI_INTEN_IPRXWA_MASK (1 << FLEXSPI_INTEN_IPRXWA_SHIFT)
+#define FLEXSPI_INTEN_AHBCMDERR_SHIFT 4
+#define FLEXSPI_INTEN_AHBCMDERR_MASK (1 << FLEXSPI_INTEN_AHBCMDERR_SHIFT)
+#define FLEXSPI_INTEN_IPCMDERR_SHIFT 3
+#define FLEXSPI_INTEN_IPCMDERR_MASK (1 << FLEXSPI_INTEN_IPCMDERR_SHIFT)
+#define FLEXSPI_INTEN_AHBCMDGE_SHIFT 2
+#define FLEXSPI_INTEN_AHBCMDGE_MASK (1 << FLEXSPI_INTEN_AHBCMDGE_SHIFT)
+#define FLEXSPI_INTEN_IPCMDGE_SHIFT 1
+#define FLEXSPI_INTEN_IPCMDGE_MASK (1 << FLEXSPI_INTEN_IPCMDGE_SHIFT)
+#define FLEXSPI_INTEN_IPCMDDONE_SHIFT 0
+#define FLEXSPI_INTEN_IPCMDDONE_MASK (1 << FLEXSPI_INTEN_IPCMDDONE_SHIFT)
+
+#define FLEXSPI_INTR 0x14
+#define FLEXSPI_INTR_SCLKSBWR_SHIFT 9
+#define FLEXSPI_INTR_SCLKSBWR_MASK (1 << FLEXSPI_INTR_SCLKSBWR_SHIFT)
+#define FLEXSPI_INTR_SCLKSBRD_SHIFT 8
+#define FLEXSPI_INTR_SCLKSBRD_MASK (1 << FLEXSPI_INTR_SCLKSBRD_SHIFT)
+#define FLEXSPI_INTR_DATALRNFL_SHIFT 7
+#define FLEXSPI_INTR_DATALRNFL_MASK (1 << FLEXSPI_INTR_DATALRNFL_SHIFT)
+#define FLEXSPI_INTR_IPTXWE_SHIFT 6
+#define FLEXSPI_INTR_IPTXWE_MASK (1 << FLEXSPI_INTR_IPTXWE_SHIFT)
+#define FLEXSPI_INTR_IPRXWA_SHIFT 5
+#define FLEXSPI_INTR_IPRXWA_MASK (1 << FLEXSPI_INTR_IPRXWA_SHIFT)
+#define FLEXSPI_INTR_AHBCMDERR_SHIFT 4
+#define FLEXSPI_INTR_AHBCMDERR_MASK (1 << FLEXSPI_INTR_AHBCMDERR_SHIFT)
+#define FLEXSPI_INTR_IPCMDERR_SHIFT 3
+#define FLEXSPI_INTR_IPCMDERR_MASK (1 << FLEXSPI_INTR_IPCMDERR_SHIFT)
+#define FLEXSPI_INTR_AHBCMDGE_SHIFT 2
+#define FLEXSPI_INTR_AHBCMDGE_MASK (1 << FLEXSPI_INTR_AHBCMDGE_SHIFT)
+#define FLEXSPI_INTR_IPCMDGE_SHIFT 1
+#define FLEXSPI_INTR_IPCMDGE_MASK (1 << FLEXSPI_INTR_IPCMDGE_SHIFT)
+#define FLEXSPI_INTR_IPCMDDONE_SHIFT 0
+#define FLEXSPI_INTR_IPCMDDONE_MASK (1 << FLEXSPI_INTR_IPCMDDONE_SHIFT)
+
+#define FLEXSPI_LUTKEY 0x18
+#define FLEXSPI_LUTKEY_VALUE 0x5AF05AF0
+
+#define FLEXSPI_LCKCR 0x1C
+#define FLEXSPI_LCKER_LOCK 0x1
+#define FLEXSPI_LCKER_UNLOCK 0x2
+
+#define FLEXSPI_BUFXCR_INVALID_MSTRID 0xe
+#define FLEXSPI_AHBRX_BUF0CR0 0x20
+#define FLEXSPI_AHBRX_BUF1CR0 0x24
+#define FLEXSPI_AHBRX_BUF2CR0 0x28
+#define FLEXSPI_AHBRX_BUF3CR0 0x2C
+#define FLEXSPI_AHBRX_BUF4CR0 0x30
+#define FLEXSPI_AHBRX_BUF5CR0 0x34
+#define FLEXSPI_AHBRX_BUF6CR0 0x38
+#define FLEXSPI_AHBRX_BUF7CR0 0x3C
+#define FLEXSPI_AHBRXBUF0CR7_PREF_SHIFT 31
+#define FLEXSPI_AHBRXBUF0CR7_PREF_MASK (1 << FLEXSPI_AHBRXBUF0CR7_PREF_SHIFT)
+
+#define FLEXSPI_AHBRX_BUF0CR1 0x40
+#define FLEXSPI_AHBRX_BUF1CR1 0x44
+#define FLEXSPI_AHBRX_BUF2CR1 0x48
+#define FLEXSPI_AHBRX_BUF3CR1 0x4C
+#define FLEXSPI_AHBRX_BUF4CR1 0x50
+#define FLEXSPI_AHBRX_BUF5CR1 0x54
+#define FLEXSPI_AHBRX_BUF6CR1 0x58
+#define FLEXSPI_AHBRX_BUF7CR1 0x5C
+#define FLEXSPI_BUFXCR1_MSID_SHIFT 0
+#define FLEXSPI_BUFXCR1_MSID_MASK (0xF << FLEXSPI_BUFXCR1_MSID_SHIFT)
+#define FLEXSPI_BUFXCR1_PRIO_SHIFT 8
+#define FLEXSPI_BUFXCR1_PRIO_MASK (0x7 << FLEXSPI_BUFXCR1_PRIO_SHIFT)
+
+#define FLEXSPI_FLSHA1CR0 0x60
+#define FLEXSPI_FLSHA2CR0 0x64
+#define FLEXSPI_FLSHB1CR0 0x68
+#define FLEXSPI_FLSHB2CR0 0x6C
+#define FLEXSPI_FLSHXCR0_SZ_SHIFT 10
+#define FLEXSPI_FLSHXCR0_SZ_MASK (0x3FFFFF << FLEXSPI_FLSHXCR0_SZ_SHIFT)
+
+#define FLEXSPI_FLSHA1CR1 0x70
+#define FLEXSPI_FLSHA2CR1 0x74
+#define FLEXSPI_FLSHB1CR1 0x78
+#define FLEXSPI_FLSHB2CR1 0x7C
+#define FLEXSPI_FLSHXCR1_CSINTR_SHIFT 16
+#define FLEXSPI_FLSHXCR1_CSINTR_MASK \
+ (0xFFFF << FLEXSPI_FLSHXCR1_CSINTR_SHIFT)
+#define FLEXSPI_FLSHXCR1_CAS_SHIFT 11
+#define FLEXSPI_FLSHXCR1_CAS_MASK (0xF << FLEXSPI_FLSHXCR1_CAS_SHIFT)
+#define FLEXSPI_FLSHXCR1_WA_SHIFT 10
+#define FLEXSPI_FLSHXCR1_WA_MASK (1 << FLEXSPI_FLSHXCR1_WA_SHIFT)
+#define FLEXSPI_FLSHXCR1_TCSH_SHIFT 5
+#define FLEXSPI_FLSHXCR1_TCSH_MASK (0x1F << FLEXSPI_FLSHXCR1_TCSH_SHIFT)
+#define FLEXSPI_FLSHXCR1_TCSS_SHIFT 0
+#define FLEXSPI_FLSHXCR1_TCSS_MASK (0x1F << FLEXSPI_FLSHXCR1_TCSS_SHIFT)
+
+#define FLEXSPI_FLSHA1CR2 0x80
+#define FLEXSPI_FLSHA2CR2 0x84
+#define FLEXSPI_FLSHB1CR2 0x88
+#define FLEXSPI_FLSHB2CR2 0x8C
+#define FLEXSPI_FLSHXCR2_CLRINSP_SHIFT 24
+#define FLEXSPI_FLSHXCR2_CLRINSP_MASK (1 << FLEXSPI_FLSHXCR2_CLRINSP_SHIFT)
+#define FLEXSPI_FLSHXCR2_AWRWAIT_SHIFT 16
+#define FLEXSPI_FLSHXCR2_AWRWAIT_MASK (0xFF << FLEXSPI_FLSHXCR2_AWRWAIT_SHIFT)
+#define FLEXSPI_FLSHXCR2_AWRSEQN_SHIFT 13
+#define FLEXSPI_FLSHXCR2_AWRSEQN_MASK (0x7 << FLEXSPI_FLSHXCR2_AWRSEQN_SHIFT)
+#define FLEXSPI_FLSHXCR2_AWRSEQI_SHIFT 8
+#define FLEXSPI_FLSHXCR2_AWRSEQI_MASK (0xF << FLEXSPI_FLSHXCR2_AWRSEQI_SHIFT)
+#define FLEXSPI_FLSHXCR2_ARDSEQN_SHIFT 5
+#define FLEXSPI_FLSHXCR2_ARDSEQN_MASK (0x7 << FLEXSPI_FLSHXCR2_ARDSEQN_SHIFT)
+#define FLEXSPI_FLSHXCR2_ARDSEQI_SHIFT 0
+#define FLEXSPI_FLSHXCR2_ARDSEQI_MASK (0xF << FLEXSPI_FLSHXCR2_ARDSEQI_SHIFT)
+
+#define FLEXSPI_IPCR0 0xA0
+
+#define FLEXSPI_IPCR1 0xA4
+#define FLEXSPI_IPCR1_IPAREN_SHIFT 31
+#define FLEXSPI_IPCR1_IPAREN_MASK (1 << FLEXSPI_IPCR1_IPAREN_SHIFT)
+#define FLEXSPI_IPCR1_SEQNUM_SHIFT 24
+#define FLEXSPI_IPCR1_SEQNUM_MASK (0xF << FLEXSPI_IPCR1_SEQNUM_SHIFT)
+#define FLEXSPI_IPCR1_SEQID_SHIFT 16
+#define FLEXSPI_IPCR1_SEQID_MASK (0xF << FLEXSPI_IPCR1_SEQID_SHIFT)
+#define FLEXSPI_IPCR1_IDATSZ_SHIFT 0
+#define FLEXSPI_IPCR1_IDATSZ_MASK (0xFFFF << FLEXSPI_IPCR1_IDATSZ_SHIFT)
+
+#define FLEXSPI_IPCMD 0xB0
+#define FLEXSPI_IPCMD_TRG_SHIFT 0
+#define FLEXSPI_IPCMD_TRG_MASK (1 << FLEXSPI_IPCMD_TRG_SHIFT)
+
+#define FLEXSPI_DLPR 0xB4
+
+#define FLEXSPI_IPRXFCR 0xB8
+#define FLEXSPI_IPRXFCR_CLR_SHIFT 0
+#define FLEXSPI_IPRXFCR_CLR_MASK (1 << FLEXSPI_IPRXFCR_CLR_SHIFT)
+#define FLEXSPI_IPRXFCR_DMA_EN_SHIFT 1
+#define FLEXSPI_IPRXFCR_DMA_EN_MASK (1 << FLEXSPI_IPRXFCR_DMA_EN_SHIFT)
+#define FLEXSPI_IPRXFCR_WMRK_SHIFT 2
+#define FLEXSPI_IPRXFCR_WMRK_MASK (0x1F << FLEXSPI_IPRXFCR_WMRK_SHIFT)
+
+#define FLEXSPI_IPTXFCR 0xBC
+#define FLEXSPI_IPTXFCR_CLR_SHIFT 0
+#define FLEXSPI_IPTXFCR_CLR_MASK (1 << FLEXSPI_IPTXFCR_CLR_SHIFT)
+#define FLEXSPI_IPTXFCR_DMA_EN_SHIFT 1
+#define FLEXSPI_IPTXFCR_DMA_EN_MASK (1 << FLEXSPI_IPTXFCR_DMA_EN_SHIFT)
+#define FLEXSPI_IPTXFCR_WMRK_SHIFT 2
+#define FLEXSPI_IPTXFCR_WMRK_MASK (0x1F << FLEXSPI_IPTXFCR_WMRK_SHIFT)
+
+#define FLEXSPI_DLLACR 0xC0
+#define FLEXSPI_DLLACR_REFUPDINT_SHIFT 28
+#define FLEXSPI_DLLACR_REFUPDINT_MASK (0xF << FLEXSPI_DLLACR_REFUPDINT_SHIFT)
+#define FLEXSPI_DLLACR_OVRDVAL_SHIFT 9
+#define FLEXSPI_DLLACR_OVRDVAL_MASK (0x3F << FLEXSPI_DLLACR_OVRDVAL_SHIFT)
+#define FLEXSPI_DLLACR_OVRDEN_SHIFT 8
+#define FLEXSPI_DLLACR_OVRDEN_MASK (1 << FLEXSPI_DLLACR_OVRDEN_SHIFT)
+#define FLEXSPI_DLLACR_SLVDLYTGT_SHIFT 3
+#define FLEXSPI_DLLACR_SLVDLYTGT_MASK (0xF << FLEXSPI_DLLACR_SLVDLYTGT_SHIFT)
+#define FLEXSPI_DLLACR_DLLRST_SHIFT 1
+#define FLEXSPI_DLLACR_DLLRST_MASK (1 << FLEXSPI_DLLACR_DLLRST_SHIFT)
+#define FLEXSPI_DLLACR_DLLEN_SHIFT 0
+#define FLEXSPI_DLLACR_DLLEN_MASK (1 << FLEXSPI_DLLACR_DLLEN_SHIFT)
+
+#define FLEXSPI_DLLBCR 0xC4
+#define FLEXSPI_DLLBCR_REFUPDINT_SHIFT 28
+#define FLEXSPI_DLLBCR_REFUPDINT_MASK (0xF << FLEXSPI_DLLBCR_REFUPDINT_SHIFT)
+#define FLEXSPI_DLLBCR_OVRDVAL_SHIFT 9
+#define FLEXSPI_DLLBCR_OVRDVAL_MASK (0x3F << FLEXSPI_DLLBCR_OVRDVAL_SHIFT)
+#define FLEXSPI_DLLBCR_OVRDEN_SHIFT 8
+#define FLEXSPI_DLLBCR_OVRDEN_MASK (1 << FLEXSPI_DLLBCR_OVRDEN_SHIFT)
+#define FLEXSPI_DLLBCR_SLVDLYTGT_SHIFT 3
+#define FLEXSPI_DLLBCR_SLVDLYTGT_MASK (0xF << FLEXSPI_DLLBCR_SLVDLYTGT_SHIFT)
+#define FLEXSPI_DLLBCR_DLLRST_SHIFT 1
+#define FLEXSPI_DLLBCR_DLLRST_MASK (1 << FLEXSPI_DLLBCR_DLLRST_SHIFT)
+#define FLEXSPI_DLLBCR_DLLEN_SHIFT 0
+#define FLEXSPI_DLLBCR_DLLEN_MASK (1 << FLEXSPI_DLLBCR_DLLEN_SHIFT)
+
+#define FLEXSPI_STS0 0xE0
+#define FLEXSPI_STS0_DLPHA_SHIFT 9
+#define FLEXSPI_STS0_DLPHA_MASK (0x1F << FLEXSPI_STS0_DLPHA_SHIFT)
+#define FLEXSPI_STS0_DLPHB_SHIFT 4
+#define FLEXSPI_STS0_DLPHB_MASK (0x1F << FLEXSPI_STS0_DLPHB_SHIFT)
+#define FLEXSPI_STS0_CMD_SRC_SHIFT 2
+#define FLEXSPI_STS0_CMD_SRC_MASK (3 << FLEXSPI_STS0_CMD_SRC_SHIFT)
+#define FLEXSPI_STS0_ARB_IDLE_SHIFT 1
+#define FLEXSPI_STS0_ARB_IDLE_MASK (1 << FLEXSPI_STS0_ARB_IDLE_SHIFT)
+#define FLEXSPI_STS0_SEQ_IDLE_SHIFT 0
+#define FLEXSPI_STS0_SEQ_IDLE_MASK (1 << FLEXSPI_STS0_SEQ_IDLE_SHIFT)
+
+#define FLEXSPI_STS1 0xE4
+#define FLEXSPI_STS1_IP_ERRCD_SHIFT 24
+#define FLEXSPI_STS1_IP_ERRCD_MASK (0xF << FLEXSPI_STS1_IP_ERRCD_SHIFT)
+#define FLEXSPI_STS1_IP_ERRID_SHIFT 16
+#define FLEXSPI_STS1_IP_ERRID_MASK (0xF << FLEXSPI_STS1_IP_ERRID_SHIFT)
+#define FLEXSPI_STS1_AHB_ERRCD_SHIFT 8
+#define FLEXSPI_STS1_AHB_ERRCD_MASK (0xF << FLEXSPI_STS1_AHB_ERRCD_SHIFT)
+#define FLEXSPI_STS1_AHB_ERRID_SHIFT 0
+#define FLEXSPI_STS1_AHB_ERRID_MASK (0xF << FLEXSPI_STS1_AHB_ERRID_SHIFT)
+
+#define FLEXSPI_AHBSPNST 0xEC
+#define FLEXSPI_AHBSPNST_DATLFT_SHIFT 16
+#define FLEXSPI_AHBSPNST_DATLFT_MASK \
+ (0xFFFF << FLEXSPI_AHBSPNST_DATLFT_SHIFT)
+#define FLEXSPI_AHBSPNST_BUFID_SHIFT 1
+#define FLEXSPI_AHBSPNST_BUFID_MASK (7 << FLEXSPI_AHBSPNST_BUFID_SHIFT)
+#define FLEXSPI_AHBSPNST_ACTIVE_SHIFT 0
+#define FLEXSPI_AHBSPNST_ACTIVE_MASK (1 << FLEXSPI_AHBSPNST_ACTIVE_SHIFT)
+
+#define FLEXSPI_IPRXFSTS 0xF0
+#define FLEXSPI_IPRXFSTS_RDCNTR_SHIFT 16
+#define FLEXSPI_IPRXFSTS_RDCNTR_MASK \
+ (0xFFFF << FLEXSPI_IPRXFSTS_RDCNTR_SHIFT)
+#define FLEXSPI_IPRXFSTS_FILL_SHIFT 0
+#define FLEXSPI_IPRXFSTS_FILL_MASK (0xFF << FLEXSPI_IPRXFSTS_FILL_SHIFT)
+
+#define FLEXSPI_IPTXFSTS 0xF4
+#define FLEXSPI_IPTXFSTS_WRCNTR_SHIFT 16
+#define FLEXSPI_IPTXFSTS_WRCNTR_MASK \
+ (0xFFFF << FLEXSPI_IPTXFSTS_WRCNTR_SHIFT)
+#define FLEXSPI_IPTXFSTS_FILL_SHIFT 0
+#define FLEXSPI_IPTXFSTS_FILL_MASK (0xFF << FLEXSPI_IPTXFSTS_FILL_SHIFT)
+
+#define FLEXSPI_RFDR 0x100
+#define FLEXSPI_TFDR 0x180
+
+#define FLEXSPI_LUT_BASE 0x200
+
+/* register map end */
+
+/*
+ * The definition of the LUT register shows below:
+ *
+ * ---------------------------------------------------
+ * | INSTR1 | PAD1 | OPRND1 | INSTR0 | PAD0 | OPRND0 |
+ * ---------------------------------------------------
+ */
+#define OPRND0_SHIFT 0
+#define PAD0_SHIFT 8
+#define INSTR0_SHIFT 10
+#define OPRND1_SHIFT 16
+
+/* Instruction set for the LUT register. */
+
+#define LUT_STOP 0x00
+#define LUT_CMD 0x01
+#define LUT_ADDR 0x02
+#define LUT_CADDR_SDR 0x03
+#define LUT_MODE 0x04
+#define LUT_MODE2 0x05
+#define LUT_MODE4 0x06
+#define LUT_MODE8 0x07
+#define LUT_FSL_WRITE 0x08
+#define LUT_FSL_READ 0x09
+#define LUT_LEARN_SDR 0x0A
+#define LUT_DATSZ_SDR 0x0B
+#define LUT_DUMMY 0x0C
+#define LUT_DUMMY_RWDS_SDR 0x0D
+#define LUT_JMP_ON_CS 0x1F
+#define LUT_CMD_DDR 0x21
+#define LUT_ADDR_DDR 0x22
+#define LUT_CADDR_DDR 0x23
+#define LUT_MODE_DDR 0x24
+#define LUT_MODE2_DDR 0x25
+#define LUT_MODE4_DDR 0x26
+#define LUT_MODE8_DDR 0x27
+#define LUT_WRITE_DDR 0x28
+#define LUT_READ_DDR 0x29
+#define LUT_LEARN_DDR 0x2A
+#define LUT_DATSZ_DDR 0x2B
+#define LUT_DUMMY_DDR 0x2C
+#define LUT_DUMMY_RWDS_DDR 0x2D
+
+
+/*
+ * The PAD definitions for LUT register.
+ *
+ * The pad stands for the lines number of IO[0:3].
+ * For example, the Quad read need four IO lines, so you should
+ * set LUT_PAD4 which means we use four IO lines.
+ */
+#define LUT_PAD1 0
+#define LUT_PAD2 1
+#define LUT_PAD4 2
+#define LUT_PAD8 3
+
+/* Oprands for the LUT register. */
+#define ADDR24BIT 0x18
+#define ADDR32BIT 0x20
+
+/* Macros for constructing the LUT register. */
+#define LUT0(ins, pad, opr) \
+ (((opr) << OPRND0_SHIFT) | ((LUT_##pad) << PAD0_SHIFT) | \
+ ((LUT_##ins) << INSTR0_SHIFT))
+
+#define LUT1(ins, pad, opr) (LUT0(ins, pad, opr) << OPRND1_SHIFT)
+
+/* other macros for LUT register. */
+#define FLEXSPI_LUT(x) (FLEXSPI_LUT_BASE + (x) * 4)
+#define FLEXSPI_LUT_NUM 64
+
+/* SEQID -- we can have 16 seqids at most. */
+#define SEQID_QUAD_READ 0
+#define SEQID_WREN 1
+#define SEQID_WRDI 2
+#define SEQID_RDSR 3
+#define SEQID_SE 4
+#define SEQID_CHIP_ERASE 5
+#define SEQID_PP 6
+#define SEQID_RDID 7
+#define SEQID_WRSR 8
+#define SEQID_RDCR 9
+#define SEQID_EN4B 10
+#define SEQID_BRWR 11
+#define SEQID_RD_EVCR 12
+#define SEQID_WD_EVCR 13
+#define SEQID_RD_SFDP 14
+
+#define FLEXSPI_MIN_IOMAP SZ_4M
+
+enum fsl_flexspi_devtype {
+ FSL_FLEXSPI_IMX8QM,
+ FSL_FLEXSPI_IMX8QXP,
+ FSL_FLEXSPI_IMX8MM,
+};
+
+struct fsl_flexspi_devtype_data {
+ enum fsl_flexspi_devtype devtype;
+ int rxfifo;
+ int txfifo;
+ int ahb_buf_size;
+ int driver_data;
+ int dllvalue;
+};
+
+static struct fsl_flexspi_devtype_data imx8qm_data = {
+ .devtype = FSL_FLEXSPI_IMX8QM,
+ .rxfifo = 1024,
+ .txfifo = 1024,
+ .ahb_buf_size = 2048,
+ .driver_data = FLEXSPI_QUIRK_CONFIG_DLL,
+ .dllvalue = 80, /* unit is 0.1 ns, this is 8ns */
+};
+
+static struct fsl_flexspi_devtype_data imx8qxp_data = {
+ .devtype = FSL_FLEXSPI_IMX8QXP,
+ .rxfifo = 1024,
+ .txfifo = 1024,
+ .ahb_buf_size = 2048,
+ .driver_data = FLEXSPI_QUIRK_CONFIG_DLL,
+ .dllvalue = 80, /* unit is 0.1 ns, this is 8ns */
+};
+
+static struct fsl_flexspi_devtype_data imx8mm_data = {
+ .devtype = FSL_FLEXSPI_IMX8MM,
+ .rxfifo = 1024,
+ .txfifo = 1024,
+ .ahb_buf_size = 2048,
+ .driver_data = FLEXSPI_QUIRK_QUAD_ONLY | FLEXSPI_QUIRK_FREQ_LIMIT,
+ .dllvalue = 0,
+};
+
+#define FSL_FLEXSPI_MAX_CHIP 4
+struct fsl_flexspi {
+ struct mtd_info mtd[FSL_FLEXSPI_MAX_CHIP];
+ struct spi_nor nor[FSL_FLEXSPI_MAX_CHIP];
+ void __iomem *iobase;
+ void __iomem *ahb_addr;
+ u32 memmap_phy;
+ u32 memmap_offs;
+ u32 memmap_len;
+ struct clk *clk;
+ struct device *dev;
+ struct completion c;
+ struct fsl_flexspi_devtype_data *devtype_data;
+ u32 nor_size;
+ u32 nor_num;
+ u32 clk_rate;
+ unsigned int chip_base_addr; /* We may support two chips. */
+ bool has_second_chip;
+ u32 ddr_smp;
+ struct mutex lock;
+ struct pm_qos_request pm_qos_req;
+
+#define FLEXSPI_INITILIZED (1 << 0)
+ int flags;
+};
+
+static inline int fsl_flexspi_need_config_dll(struct fsl_flexspi *flex)
+{
+ return flex->devtype_data->driver_data & FLEXSPI_QUIRK_CONFIG_DLL;
+}
+
+static inline int fsl_flexspi_freq_limit(struct fsl_flexspi *flex)
+{
+ return flex->devtype_data->driver_data & FLEXSPI_QUIRK_FREQ_LIMIT;
+}
+
+static inline int fsl_flexspi_quad_only(struct fsl_flexspi *flex)
+{
+ return flex->devtype_data->driver_data & FLEXSPI_QUIRK_QUAD_ONLY;
+}
+
+static inline void fsl_flexspi_unlock_lut(struct fsl_flexspi *flex)
+{
+ writel(FLEXSPI_LUTKEY_VALUE, flex->iobase + FLEXSPI_LUTKEY);
+ writel(FLEXSPI_LCKER_UNLOCK, flex->iobase + FLEXSPI_LCKCR);
+}
+
+static inline void fsl_flexspi_lock_lut(struct fsl_flexspi *flex)
+{
+ writel(FLEXSPI_LUTKEY_VALUE, flex->iobase + FLEXSPI_LUTKEY);
+ writel(FLEXSPI_LCKER_LOCK, flex->iobase + FLEXSPI_LCKCR);
+}
+
+static irqreturn_t fsl_flexspi_irq_handler(int irq, void *dev_id)
+{
+ struct fsl_flexspi *flex = dev_id;
+ u32 reg;
+
+ reg = readl(flex->iobase + FLEXSPI_INTR);
+ writel(FLEXSPI_INTR_IPCMDDONE_MASK, flex->iobase + FLEXSPI_INTR);
+ if (reg & FLEXSPI_INTR_IPCMDDONE_MASK)
+ complete(&flex->c);
+
+ return IRQ_HANDLED;
+}
+
+static void fsl_flexspi_init_lut(struct fsl_flexspi *flex)
+{
+ void __iomem *base = flex->iobase;
+ struct spi_nor *nor = &flex->nor[0];
+ u8 addrlen = (nor->addr_width == 3) ? ADDR24BIT : ADDR32BIT;
+ u32 lut_base;
+ u8 op, dm;
+ int i;
+
+ fsl_flexspi_unlock_lut(flex);
+
+ /* Clear all the LUT table */
+ for (i = 0; i < FLEXSPI_LUT_NUM; i++)
+ writel(0, base + FLEXSPI_LUT_BASE + i * 4);
+
+ /* Quad Read and DDR Quad Read*/
+ lut_base = SEQID_QUAD_READ * 4;
+ op = nor->read_opcode;
+ dm = nor->read_dummy;
+
+ /* Normal Read as the default read setting*/
+ if (op == SPINOR_OP_READ || op == 0) {
+ writel(LUT0(CMD, PAD1, SPINOR_OP_READ) |
+ LUT1(ADDR, PAD1, addrlen),
+ base + FLEXSPI_LUT(lut_base));
+
+ writel(LUT0(FSL_READ, PAD1, 0),
+ base + FLEXSPI_LUT(lut_base + 1));
+ /* Octal DDR Read */
+ } else if (op == SPINOR_OP_READ_1_8_8_DTR_4B) {
+ writel(LUT0(CMD, PAD1, op) |
+ LUT1(ADDR_DDR, PAD1, addrlen),
+ base + FLEXSPI_LUT(lut_base));
+
+ writel(LUT0(DUMMY_DDR, PAD8, dm * 2)
+ | LUT1(READ_DDR, PAD8, 0),
+ base + FLEXSPI_LUT(lut_base + 1));
+ /* QUAD Fast Read */
+ } else if (op == SPINOR_OP_READ_1_1_4 || op == SPINOR_OP_READ_1_1_4_4B) {
+ /* read mode : 1-1-4 */
+ writel(LUT0(CMD, PAD1, op) | LUT1(ADDR, PAD1, addrlen),
+ base + FLEXSPI_LUT(lut_base));
+
+ writel(LUT0(DUMMY, PAD4, dm) |
+ LUT1(FSL_READ, PAD4, 0),
+ base + FLEXSPI_LUT(lut_base + 1));
+ /* DDR Quad I/O Read */
+ } else if (op == SPINOR_OP_READ_1_4_4_DTR || op == SPINOR_OP_READ_1_4_4_DTR_4B) {
+ /* read mode : 1-4-4, such as Spansion s25fl128s. */
+ writel(LUT0(CMD, PAD1, op) |
+ LUT1(ADDR_DDR, PAD4, addrlen),
+ base + FLEXSPI_LUT(lut_base));
+
+ writel(LUT0(DUMMY_DDR, PAD4, dm * 2) |
+ LUT1(READ_DDR, PAD4, 0),
+ base + FLEXSPI_LUT(lut_base + 1));
+
+ writel(LUT0(JMP_ON_CS, PAD1, 0),
+ base + FLEXSPI_LUT(lut_base + 2));
+ /* DDR Quad Fast Read */
+ } else if (op == SPINOR_OP_READ_1_1_4_DTR) {
+ /* read mode : 1-1-4, such as Micron N25Q256A. */
+ writel(LUT0(CMD, PAD1, op) |
+ LUT1(ADDR_DDR, PAD1, addrlen),
+ base + FLEXSPI_LUT(lut_base));
+
+ writel(LUT0(DUMMY_DDR, PAD4, dm * 2) |
+ LUT1(READ_DDR, PAD4, 0),
+ base + FLEXSPI_LUT(lut_base + 1));
+
+ writel(LUT0(JMP_ON_CS, PAD1, 0),
+ base + FLEXSPI_LUT(lut_base + 2));
+ }
+
+ /* Write enable */
+ lut_base = SEQID_WREN * 4;
+ writel(LUT0(CMD, PAD1, SPINOR_OP_WREN), base + FLEXSPI_LUT(lut_base));
+
+ /* Page Program */
+ lut_base = SEQID_PP * 4;
+ writel(LUT0(CMD, PAD1, nor->program_opcode) | LUT1(ADDR, PAD1, addrlen),
+ base + FLEXSPI_LUT(lut_base));
+ writel(LUT0(FSL_WRITE, PAD1, 0), base + FLEXSPI_LUT(lut_base + 1));
+
+ /* Read Status */
+ lut_base = SEQID_RDSR * 4;
+ writel(LUT0(CMD, PAD1, SPINOR_OP_RDSR) | LUT1(FSL_READ, PAD1, 0x1),
+ base + FLEXSPI_LUT(lut_base));
+
+ /* Erase a sector */
+ lut_base = SEQID_SE * 4;
+ writel(LUT0(CMD, PAD1, nor->erase_opcode) | LUT1(ADDR, PAD1, addrlen),
+ base + FLEXSPI_LUT(lut_base));
+
+ /* Erase the whole chip */
+ lut_base = SEQID_CHIP_ERASE * 4;
+ writel(LUT0(CMD, PAD1, SPINOR_OP_CHIP_ERASE),
+ base + FLEXSPI_LUT(lut_base));
+
+ /* READ ID */
+ lut_base = SEQID_RDID * 4;
+ writel(LUT0(CMD, PAD1, SPINOR_OP_RDID) | LUT1(FSL_READ, PAD1, 0x8),
+ base + FLEXSPI_LUT(lut_base));
+
+ /* Write Register */
+ lut_base = SEQID_WRSR * 4;
+ writel(LUT0(CMD, PAD1, SPINOR_OP_WRSR) | LUT1(FSL_WRITE, PAD1, 0x2),
+ base + FLEXSPI_LUT(lut_base));
+
+ /* Read Configuration Register */
+ lut_base = SEQID_RDCR * 4;
+ writel(LUT0(CMD, PAD1, SPINOR_OP_RDCR) | LUT1(FSL_READ, PAD1, 0x1),
+ base + FLEXSPI_LUT(lut_base));
+
+ /* Write disable */
+ lut_base = SEQID_WRDI * 4;
+ writel(LUT0(CMD, PAD1, SPINOR_OP_WRDI), base + FLEXSPI_LUT(lut_base));
+
+ /* Enter 4 Byte Mode (Micron) */
+ lut_base = SEQID_EN4B * 4;
+ writel(LUT0(CMD, PAD1, SPINOR_OP_EN4B), base + FLEXSPI_LUT(lut_base));
+
+ /* Enter 4 Byte Mode (Spansion) */
+ lut_base = SEQID_BRWR * 4;
+ writel(LUT0(CMD, PAD1, SPINOR_OP_BRWR), base + FLEXSPI_LUT(lut_base));
+
+ /* Read EVCR register */
+ lut_base = SEQID_RD_EVCR * 4;
+ writel(LUT0(CMD, PAD1, SPINOR_OP_RD_EVCR),
+ base + FLEXSPI_LUT(lut_base));
+
+ /* Write EVCR register */
+ lut_base = SEQID_WD_EVCR * 4;
+ writel(LUT0(CMD, PAD1, SPINOR_OP_WD_EVCR),
+ base + FLEXSPI_LUT(lut_base));
+
+ /* Read SFDP*/
+ lut_base = SEQID_RD_SFDP * 4;
+ writel(LUT0(CMD, PAD1, SPINOR_OP_RDSFDP) | LUT1(ADDR, PAD1, ADDR24BIT),
+ base + FLEXSPI_LUT(lut_base));
+ writel(LUT0(DUMMY, PAD1, 8) | LUT1(FSL_READ, PAD1, 16),
+ base + FLEXSPI_LUT(lut_base + 1));
+ fsl_flexspi_lock_lut(flex);
+}
+
+/* Get the SEQID for the command */
+static int fsl_flexspi_get_seqid(struct fsl_flexspi *flex, u8 cmd)
+{
+
+ switch (cmd) {
+ case SPINOR_OP_READ_1_1_4_DTR:
+ case SPINOR_OP_READ_1_8_8_DTR_4B:
+ case SPINOR_OP_READ_1_4_4_DTR:
+ case SPINOR_OP_READ_1_4_4_DTR_4B:
+ case SPINOR_OP_READ_1_1_4_4B:
+ case SPINOR_OP_READ_1_1_4:
+ case SPINOR_OP_READ_4B:
+ case SPINOR_OP_READ:
+ return SEQID_QUAD_READ;
+ case SPINOR_OP_WREN:
+ return SEQID_WREN;
+ case SPINOR_OP_WRDI:
+ return SEQID_WRDI;
+ case SPINOR_OP_RDSR:
+ return SEQID_RDSR;
+ case SPINOR_OP_BE_4K:
+ case SPINOR_OP_SE:
+ return SEQID_SE;
+ case SPINOR_OP_CHIP_ERASE:
+ return SEQID_CHIP_ERASE;
+ case SPINOR_OP_PP:
+ return SEQID_PP;
+ case SPINOR_OP_RDID:
+ return SEQID_RDID;
+ case SPINOR_OP_WRSR:
+ return SEQID_WRSR;
+ case SPINOR_OP_RDCR:
+ return SEQID_RDCR;
+ case SPINOR_OP_EN4B:
+ return SEQID_EN4B;
+ case SPINOR_OP_BRWR:
+ return SEQID_BRWR;
+ case SPINOR_OP_RD_EVCR:
+ return SEQID_RD_EVCR;
+ case SPINOR_OP_WD_EVCR:
+ return SEQID_WD_EVCR;
+ case SPINOR_OP_RDSFDP:
+ return SEQID_RD_SFDP;
+ default:
+ dev_err(flex->dev, "Unsupported cmd 0x%.2x\n", cmd);
+ break;
+ }
+ return -EINVAL;
+}
+
+static int
+fsl_flexspi_runcmd(struct fsl_flexspi *flex, u8 cmd, unsigned int addr, int len)
+{
+ void __iomem *base = flex->iobase;
+ int seqid;
+ int seqnum = 0;
+ u32 reg;
+ int err;
+
+ init_completion(&flex->c);
+ dev_dbg(flex->dev, "to 0x%.8x:0x%.8x, len:%d, cmd:%.2x\n",
+ flex->chip_base_addr, addr, len, cmd);
+
+ /* write address */
+ writel(flex->chip_base_addr + addr, base + FLEXSPI_IPCR0);
+
+ seqid = fsl_flexspi_get_seqid(flex, cmd);
+
+ writel((seqnum << FLEXSPI_IPCR1_SEQNUM_SHIFT) |
+ (seqid << FLEXSPI_IPCR1_SEQID_SHIFT) | len,
+ base + FLEXSPI_IPCR1);
+
+ /* wait till controller is idle */
+ do {
+ reg = readl(base + FLEXSPI_STS0);
+ if ((reg & FLEXSPI_STS0_ARB_IDLE_MASK) &&
+ (reg & FLEXSPI_STS0_SEQ_IDLE_MASK))
+ break;
+ udelay(1);
+ } while (1);
+
+ /* trigger the LUT now */
+ writel(1, base + FLEXSPI_IPCMD);
+
+ /* Wait for the interrupt. */
+ if (!wait_for_completion_timeout(&flex->c, msecs_to_jiffies(1000))) {
+ dev_dbg(flex->dev,
+ "cmd 0x%.2x timeout, addr@%.8x, Status0:0x%.8x, Status1:0x%.8x\n",
+ cmd, addr, readl(base + FLEXSPI_STS0),
+ readl(base + FLEXSPI_STS1));
+ err = -ETIMEDOUT;
+ } else {
+ err = 0;
+ }
+
+ return err;
+}
+
+/* Read out the data from the FLEXSPI_RBDR buffer registers. */
+static void fsl_flexspi_read_data(struct fsl_flexspi *flex, int len, u8 *rxbuf)
+{
+ /* u64 tmp; */
+ int i = 0;
+ int size;
+
+ /* invalid RXFIFO first */
+ writel(FLEXSPI_IPRXFCR_CLR_MASK, flex->iobase + FLEXSPI_IPRXFCR);
+ while (len > 0) {
+
+ size = len / 8;
+
+ for (i = 0; i < size; ++i) {
+ /* Wait for RXFIFO available*/
+ while (!(readl(flex->iobase + FLEXSPI_INTR)
+ & FLEXSPI_INTR_IPRXWA_MASK))
+ ;
+
+ /* read 64 bit data once */
+ memcpy(rxbuf, flex->iobase + FLEXSPI_RFDR, 8);
+ rxbuf += 8;
+
+ /* move the FIFO pointer */
+ writel(FLEXSPI_INTR_IPRXWA_MASK,
+ flex->iobase + FLEXSPI_INTR);
+ len -= 8;
+ }
+
+ size = len % 8;
+
+ if (size) {
+ /* Wait for RXFIFO available*/
+ while (!(readl(flex->iobase + FLEXSPI_INTR)
+ & FLEXSPI_INTR_IPRXWA_MASK))
+ ;
+
+ memcpy(rxbuf, flex->iobase + FLEXSPI_RFDR, size);
+ len -= size;
+ }
+
+ writel(FLEXSPI_INTR_IPRXWA_MASK,
+ flex->iobase + FLEXSPI_INTR);
+
+ /* invalid the RXFIFO */
+ writel(FLEXSPI_IPRXFCR_CLR_MASK,
+ flex->iobase + FLEXSPI_IPRXFCR);
+ }
+}
+
+/*
+ * If we have changed the content of the flash by writing or erasing,
+ * we need to invalidate the AHB buffer. If we do not do so, we may read out
+ * the wrong data. The spec tells us reset the AHB domain and Serial Flash
+ * domain at the same time.
+ */
+static inline void fsl_flexspi_invalid(struct fsl_flexspi *flex)
+{
+ u32 reg;
+
+ reg = readl(flex->iobase + FLEXSPI_MCR0);
+ writel(reg | FLEXSPI_MCR0_SWRST_MASK, flex->iobase + FLEXSPI_MCR0);
+
+ /*
+ * The minimum delay : 1 AHB + 2 SFCK clocks.
+ * Delay 1 us is enough.
+ */
+ while (readl(flex->iobase + FLEXSPI_MCR0) & FLEXSPI_MCR0_SWRST_MASK)
+ ;
+
+}
+
+static ssize_t fsl_flexspi_nor_write(struct fsl_flexspi *flex,
+ struct spi_nor *nor, u8 opcode,
+ unsigned int to, u32 *txbuf,
+ unsigned int count)
+{
+ int ret, i;
+ int size;
+
+ dev_dbg(flex->dev, "nor write to 0x%.8x:0x%.8x, len : %d\n",
+ flex->chip_base_addr, to, count);
+
+ /* clear the TX FIFO. */
+ writel(FLEXSPI_IPTXFCR_CLR_MASK, flex->iobase + FLEXSPI_IPTXFCR);
+
+ size = count / 8;
+ for (i = 0; i < size; i++) {
+ /* Wait for TXFIFO empty*/
+ while (!(readl(flex->iobase + FLEXSPI_INTR)
+ & FLEXSPI_INTR_IPTXWE_MASK))
+ ;
+
+ memcpy(flex->iobase + FLEXSPI_TFDR, txbuf, 8);
+ txbuf += 2;
+ writel(FLEXSPI_INTR_IPTXWE_MASK, flex->iobase + FLEXSPI_INTR);
+ }
+
+ size = count % 8;
+ if (size) {
+ /* Wait for TXFIFO empty*/
+ while (!(readl(flex->iobase + FLEXSPI_INTR)
+ & FLEXSPI_INTR_IPTXWE_MASK))
+ ;
+
+ memcpy(flex->iobase + FLEXSPI_TFDR, txbuf, size);
+ writel(FLEXSPI_INTR_IPTXWE_MASK, flex->iobase + FLEXSPI_INTR);
+ }
+
+ /* Trigger it */
+ ret = fsl_flexspi_runcmd(flex, opcode, to, count);
+
+ if (ret == 0)
+ return count;
+
+ return ret;
+}
+
+static void fsl_flexspi_set_map_addr(struct fsl_flexspi *flex)
+{
+ int nor_size = flex->nor_size >> 10;
+ void __iomem *base = flex->iobase;
+
+ writel(nor_size, base + FLEXSPI_FLSHA1CR0);
+ writel(nor_size * 2, base + FLEXSPI_FLSHA2CR0);
+ writel(nor_size * 3, base + FLEXSPI_FLSHB1CR0);
+ writel(nor_size * 4, base + FLEXSPI_FLSHB2CR0);
+}
+
+/*
+ * There are two different ways to read out the data from the flash:
+ * the "IP Command Read" and the "AHB Command Read".
+ *
+ * The IC guy suggests we use the "AHB Command Read" which is faster
+ * then the "IP Command Read". (What's more is that there is a bug in
+ * the "IP Command Read" in the Vybrid.)
+ *
+ * After we set up the registers for the "AHB Command Read", we can use
+ * the memcpy to read the data directly. A "missed" access to the buffer
+ * causes the controller to clear the buffer, and use the sequence pointed
+ * by the FLEXSPI_BFGENCR[SEQID] to initiate a read from the flash.
+ */
+static void fsl_flexspi_init_ahb_read(struct fsl_flexspi *flex)
+{
+ void __iomem *base = flex->iobase;
+ struct spi_nor *nor = &flex->nor[0];
+ int seqid;
+ int i;
+
+ /* AHB configuration for access buffer 0/1/2 .*/
+ for (i = 0; i < 7; i++)
+ writel(0, base + FLEXSPI_AHBRX_BUF0CR0 + 4 * i);
+ /*
+ * Set ADATSZ with the maximum AHB buffer size to improve the
+ * read performance.
+ */
+ writel((flex->devtype_data->ahb_buf_size / 8 |
+ FLEXSPI_AHBRXBUF0CR7_PREF_MASK),
+ base + FLEXSPI_AHBRX_BUF7CR0);
+
+ /* no start address alignment limitation */
+ writel(FLEXSPI_AHBCR_RDADDROPT_MASK, base + FLEXSPI_AHBCR);
+
+ /* Set the default lut sequence for AHB Read. */
+ seqid = fsl_flexspi_get_seqid(flex, nor->read_opcode);
+
+ writel(seqid, flex->iobase + FLEXSPI_FLSHA1CR2);
+}
+
+static void fsl_flexspi_ahb_pref_en(struct fsl_flexspi *flex)
+{
+ void __iomem *base = flex->iobase;
+ u32 reg;
+
+ reg = readl(base + FLEXSPI_AHBCR);
+ writel(FLEXSPI_AHBCR_PREF_EN_MASK | reg, base + FLEXSPI_AHBCR);
+}
+
+/* This function was used to prepare and enable QSPI clock */
+static int fsl_flexspi_clk_prep_enable(struct fsl_flexspi *flex)
+{
+ int ret;
+
+ ret = clk_prepare_enable(flex->clk);
+ if (ret) {
+ dev_err(flex->dev, "failed to enable the clock\n");
+ return ret;
+ }
+
+ return 0;
+}
+
+/* This function was used to disable and unprepare QSPI clock */
+static void fsl_flexspi_clk_disable_unprep(struct fsl_flexspi *flex)
+{
+ clk_disable_unprepare(flex->clk);
+}
+
+static int fsl_flexspi_init_rpm(struct fsl_flexspi *flex)
+{
+ struct device *dev = flex->dev;
+
+ pm_runtime_enable(dev);
+ pm_runtime_set_autosuspend_delay(dev, FSL_FLEXSPI_RPM_TIMEOUT);
+ pm_runtime_use_autosuspend(dev);
+
+ return 0;
+}
+
+static void fsl_flexspi_config_dll(struct fsl_flexspi *flex, int rate)
+{
+ int tmp, dll;
+ u32 reg;
+
+ if (!fsl_flexspi_need_config_dll(flex))
+ return;
+
+ if (rate >= 100 * FREQ_1MHz) {
+ writel(FLEXSPI_DLLACR_DLLEN_MASK | FLEXSPI_DLLACR_SLVDLYTGT_MASK,
+ flex->iobase + FLEXSPI_DLLACR);
+ writel(FLEXSPI_DLLBCR_DLLEN_MASK | FLEXSPI_DLLBCR_SLVDLYTGT_MASK,
+ flex->iobase + FLEXSPI_DLLBCR);
+ } else {
+ /*
+ * If Serial root closk is lower than 100MHz, DLL is unable to lock on
+ * half cycle of serial root clock because the dealy cell number is limited
+ * in delay chain, Then DLL should be configured as following instead:
+ * OVRDEN = 0x01
+ * OVRDVAL=N; each dealy cell in DLL is about 75ps - 225ps.
+ * The delay of DLL delay chain ( N * delay_cell_delay) should be larger
+ * than device output data valid time (from SCK edge to data valid).
+ */
+
+ /* 0.1 ns to ps */
+ tmp = flex->devtype_data->dllvalue * 100;
+ dll = tmp / FLEXSPI_DLL_MIN;
+
+ if (dll >= FLEXSPI_DLLACR_OVRDVAL_MASK)
+ dll = FLEXSPI_DLLACR_OVRDVAL_MASK;
+ else if (dll * FLEXSPI_DLL_MIN < tmp)
+ dll++;
+
+ writel(FLEXSPI_DLLACR_OVRDEN_MASK | (dll << FLEXSPI_DLLACR_OVRDVAL_SHIFT) |
+ FLEXSPI_DLLACR_DLLRST_MASK, flex->iobase + FLEXSPI_DLLACR);
+ udelay(1);
+ reg = readl(flex->iobase + FLEXSPI_DLLACR);
+ writel(reg & ~FLEXSPI_DLLACR_DLLRST_MASK, flex->iobase + FLEXSPI_DLLACR);
+
+ writel(FLEXSPI_DLLBCR_OVRDEN_MASK | (dll << FLEXSPI_DLLBCR_OVRDVAL_SHIFT) |
+ FLEXSPI_DLLBCR_DLLRST_MASK, flex->iobase + FLEXSPI_DLLBCR);
+ udelay(1);
+ reg = readl(flex->iobase + FLEXSPI_DLLBCR);
+ writel(reg & ~FLEXSPI_DLLBCR_DLLRST_MASK, flex->iobase + FLEXSPI_DLLBCR);
+ }
+}
+
+/* We use this function to do some basic init for spi_nor_scan(). */
+static int fsl_flexspi_nor_setup(struct fsl_flexspi *flex)
+{
+ void __iomem *base = flex->iobase;
+ int ret;
+
+ /* disable and unprepare clock to avoid glitch pass to controller */
+ fsl_flexspi_clk_disable_unprep(flex);
+
+ /* set rate to 24Mhz as safe clock rate to probe */
+ ret = clk_set_rate(flex->clk, 24 * FREQ_1MHz);
+ if (ret)
+ return ret;
+
+ ret = fsl_flexspi_clk_prep_enable(flex);
+ if (ret)
+ return ret;
+
+ /* Reset the module */
+ writel(FLEXSPI_MCR0_SWRST_MASK, base + FLEXSPI_MCR0);
+ do {
+ udelay(1);
+ } while (0x1 & readl(base + FLEXSPI_MCR0));
+
+ /* Disable the module */
+ writel(FLEXSPI_MCR0_MDIS_MASK, base + FLEXSPI_MCR0);
+
+ /* enable module */
+ writel(FLEXSPI_MCR0_AHB_TIMEOUT_MASK | FLEXSPI_MCR0_IP_TIMEOUT_MASK |
+ FLEXSPI_MCR0_OCTCOMB_EN_MASK, base + FLEXSPI_MCR0);
+
+ /* Reset the FLASHxCR2 */
+ writel(0, base + FLEXSPI_FLSHA1CR2);
+ writel(0, base + FLEXSPI_FLSHA2CR2);
+ writel(0, base + FLEXSPI_FLSHB1CR2);
+ writel(0, base + FLEXSPI_FLSHB2CR2);
+
+ /* Init the LUT table. */
+ fsl_flexspi_init_lut(flex);
+
+ /* enable the interrupt */
+ writel(FLEXSPI_INTEN_IPCMDDONE_MASK, flex->iobase + FLEXSPI_INTEN);
+
+ return 0;
+}
+
+static int fsl_flexspi_nor_setup_last(struct fsl_flexspi *flex)
+{
+ unsigned long rate = flex->clk_rate;
+ int ret;
+
+ /* set to the assigned clock rate */
+ fsl_flexspi_clk_disable_unprep(flex);
+
+ /* clock limitation for i.MX8MM, no more than 160Mhz */
+ if (fsl_flexspi_freq_limit(flex))
+ rate = rate > 160 * FREQ_1MHz ? 160 * FREQ_1MHz : rate;
+
+ ret = clk_set_rate(flex->clk, rate);
+ if (ret)
+ return ret;
+
+ ret = fsl_flexspi_clk_prep_enable(flex);
+ if (ret)
+ return ret;
+
+ /* setup the DLL value */
+ fsl_flexspi_config_dll(flex, rate);
+
+ /* Init the LUT table again. */
+ fsl_flexspi_init_lut(flex);
+
+ /* Init for AHB read */
+ fsl_flexspi_init_ahb_read(flex);
+
+ /* enable AHB prefetch */
+ fsl_flexspi_ahb_pref_en(flex);
+
+ return 0;
+}
+
+static void fsl_flexspi_set_base_addr(struct fsl_flexspi *flex,
+ struct spi_nor *nor)
+{
+ flex->chip_base_addr = flex->nor_size * (nor - flex->nor);
+}
+
+static int fsl_flexspi_read_reg(struct spi_nor *nor, u8 opcode, u8 *buf,
+ int len)
+{
+ int ret;
+ struct fsl_flexspi *flex = nor->priv;
+
+ ret = fsl_flexspi_runcmd(flex, opcode, 0, len);
+ if (ret)
+ return ret;
+
+ fsl_flexspi_read_data(flex, len, buf);
+ return 0;
+}
+
+static int fsl_flexspi_write_reg(struct spi_nor *nor, u8 opcode, u8 *buf,
+ int len)
+{
+ struct fsl_flexspi *flex = nor->priv;
+ int ret;
+
+ if (!buf) {
+ ret = fsl_flexspi_runcmd(flex, opcode, 0, 1);
+ if (ret)
+ return ret;
+
+ if (opcode == SPINOR_OP_CHIP_ERASE)
+ fsl_flexspi_invalid(flex);
+
+ } else if (len > 0) {
+ ret = fsl_flexspi_nor_write(flex, nor, opcode, 0,
+ (u32 *)buf, len);
+ } else {
+ dev_err(flex->dev, "invalid cmd %d\n", opcode);
+ ret = -EINVAL;
+ }
+
+ return ret;
+}
+
+static ssize_t fsl_flexspi_write(struct spi_nor *nor, loff_t to,
+ size_t len, const u_char *buf)
+{
+ struct fsl_flexspi *flex = nor->priv;
+
+ ssize_t ret = fsl_flexspi_nor_write(flex, nor, nor->program_opcode, to,
+ (u32 *)buf, len);
+
+ /* invalid the data in the AHB buffer. */
+ fsl_flexspi_invalid(flex);
+ return ret;
+}
+
+static ssize_t fsl_flexspi_read(struct spi_nor *nor, loff_t from,
+ size_t len, u_char *buf)
+{
+ struct fsl_flexspi *flex = nor->priv;
+
+ /* for read sfdp only */
+ if (nor->read_opcode == SPINOR_OP_RDSFDP)
+ fsl_flexspi_init_ahb_read(flex);
+
+ /* if necessary,ioremap buffer before AHB read, */
+ if (!flex->ahb_addr) {
+ flex->memmap_offs = flex->chip_base_addr + from;
+ flex->memmap_len = len > FLEXSPI_MIN_IOMAP ?
+ len : FLEXSPI_MIN_IOMAP;
+
+ flex->ahb_addr = ioremap_wc(
+ flex->memmap_phy + flex->memmap_offs,
+ flex->memmap_len);
+ if (!flex->ahb_addr) {
+ dev_err(flex->dev, "ioremap failed\n");
+ return -ENOMEM;
+ }
+ /* ioremap if the data requested is out of range */
+ } else if (flex->chip_base_addr + from < flex->memmap_offs
+ || flex->chip_base_addr + from + len >
+ flex->memmap_offs + flex->memmap_len) {
+ iounmap(flex->ahb_addr);
+
+ flex->memmap_offs = flex->chip_base_addr + from;
+ flex->memmap_len = len > FLEXSPI_MIN_IOMAP ?
+ len : FLEXSPI_MIN_IOMAP;
+ flex->ahb_addr = ioremap_wc(
+ flex->memmap_phy + flex->memmap_offs,
+ flex->memmap_len);
+ if (!flex->ahb_addr) {
+ dev_err(flex->dev, "ioremap failed\n");
+ return -ENOMEM;
+ }
+ }
+
+ memcpy(buf, flex->ahb_addr + flex->chip_base_addr + from
+ - flex->memmap_offs, len);
+
+ return len;
+}
+
+static int fsl_flexspi_erase(struct spi_nor *nor, loff_t offs)
+{
+ struct fsl_flexspi *flex = nor->priv;
+ int ret;
+
+ dev_dbg(nor->dev, "%dKiB at 0x%08x:0x%08x\n",
+ nor->mtd.erasesize / 1024, flex->chip_base_addr, (u32)offs);
+
+ ret = fsl_flexspi_runcmd(flex, nor->erase_opcode, offs, 0);
+ if (ret)
+ return ret;
+
+ fsl_flexspi_invalid(flex);
+ return 0;
+}
+
+static int fsl_flexspi_prep(struct spi_nor *nor, enum spi_nor_ops ops)
+{
+ struct fsl_flexspi *flex = nor->priv;
+ int ret;
+
+ mutex_lock(&flex->lock);
+
+ ret = pm_runtime_get_sync(flex->dev);
+ if (ret < 0) {
+ dev_err(flex->dev, "Failed to enable clock %d\n", __LINE__);
+ goto err_mutex;
+ }
+
+ fsl_flexspi_set_base_addr(flex, nor);
+ return 0;
+
+err_mutex:
+ mutex_unlock(&flex->lock);
+ return ret;
+}
+
+static void fsl_flexspi_unprep(struct spi_nor *nor, enum spi_nor_ops ops)
+{
+ struct fsl_flexspi *flex = nor->priv;
+
+ pm_runtime_mark_last_busy(flex->dev);
+ pm_runtime_put_autosuspend(flex->dev);
+ mutex_unlock(&flex->lock);
+}
+
+static const struct of_device_id fsl_flexspi_dt_ids[] = {
+ { .compatible = "fsl,imx8qm-flexspi", .data = (void *)&imx8qm_data, },
+ { .compatible = "fsl,imx8qxp-flexspi", .data = (void *)&imx8qxp_data, },
+ { .compatible = "fsl,imx8mm-flexspi", .data = (void *)&imx8mm_data, },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, fsl_flexspi_dt_ids);
+
+static int fsl_flexspi_probe(struct platform_device *pdev)
+{
+ struct spi_nor_hwcaps hwcaps = {
+ .mask = SNOR_HWCAPS_PP,
+ };
+ struct device_node *np = pdev->dev.of_node;
+ struct device *dev = &pdev->dev;
+ struct fsl_flexspi *flex;
+ struct resource *res;
+ struct spi_nor *nor;
+ struct mtd_info *mtd;
+ int ret, i = 0;
+
+ const struct of_device_id *of_id =
+ of_match_device(fsl_flexspi_dt_ids, &pdev->dev);
+
+ flex = devm_kzalloc(dev, sizeof(*flex), GFP_KERNEL);
+ if (!flex)
+ return -ENOMEM;
+
+ flex->nor_num = of_get_child_count(dev->of_node);
+ if (!flex->nor_num || flex->nor_num > 4)
+ return -ENODEV;
+
+ flex->dev = dev;
+ flex->devtype_data = (struct fsl_flexspi_devtype_data *)of_id->data;
+ platform_set_drvdata(pdev, flex);
+ dev_set_drvdata(dev, flex);
+
+ /* find the resources */
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "FlexSPI");
+ if (!res) {
+ dev_err(dev, "FlexSPI get resource IORESOURCE_MEM failed\n");
+ return -ENODEV;
+ }
+
+ flex->iobase = devm_ioremap_resource(dev, res);
+ if (IS_ERR(flex->iobase))
+ return PTR_ERR(flex->iobase);
+
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
+ "FlexSPI-memory");
+ if (!res) {
+ dev_err(dev,
+ "FlexSPI-memory get resource IORESOURCE_MEM failed\n");
+ return -ENODEV;
+ }
+
+ if (!devm_request_mem_region(dev, res->start, resource_size(res),
+ res->name)) {
+ dev_err(dev, "can't request region for resource %pR\n", res);
+ return -EBUSY;
+ }
+
+ flex->memmap_phy = res->start;
+
+ /* find the clocks */
+ flex->clk = devm_clk_get(dev, "fspi");
+ if (IS_ERR(flex->clk))
+ return PTR_ERR(flex->clk);
+
+ /* find ddrsmp value */
+ ret = of_property_read_u32(dev->of_node, "ddrsmp",
+ &flex->ddr_smp);
+ if (ret)
+ flex->ddr_smp = 0;
+
+ /* enable the rpm*/
+ ret = fsl_flexspi_init_rpm(flex);
+ if (ret) {
+ dev_err(dev, "can not enable the clock\n");
+ goto clk_failed;
+ }
+
+ /* find the irq */
+ ret = platform_get_irq(pdev, 0);
+ if (ret < 0) {
+ dev_err(dev, "failed to get the irq: %d\n", ret);
+ goto rpm_failed;
+ }
+
+ ret = devm_request_irq(dev, ret,
+ fsl_flexspi_irq_handler, 0, pdev->name, flex);
+ if (ret) {
+ dev_err(dev, "failed to request irq: %d\n", ret);
+ goto rpm_failed;
+ }
+
+ /* enable the clock*/
+ ret = pm_runtime_get_sync(flex->dev);
+ if (ret < 0) {
+ dev_err(flex->dev, "Failed to enable clock %d\n", __LINE__);
+ goto rpm_failed;
+ }
+
+
+ ret = fsl_flexspi_nor_setup(flex);
+ if (ret)
+ goto rpm_failed;
+
+ if (of_get_property(np, "fsl,qspi-has-second-chip", NULL))
+ flex->has_second_chip = true;
+
+ mutex_init(&flex->lock);
+
+ /* iterate the subnodes. */
+ for_each_available_child_of_node(dev->of_node, np) {
+ u32 dummy = 0;
+
+ /* skip the holes */
+ if (!flex->has_second_chip)
+ i *= 2;
+
+ nor = &flex->nor[i];
+ mtd = &nor->mtd;
+
+ nor->dev = dev;
+ spi_nor_set_flash_node(nor, np);
+ nor->priv = flex;
+
+ /* fill the hooks */
+ nor->read_reg = fsl_flexspi_read_reg;
+ nor->write_reg = fsl_flexspi_write_reg;
+ nor->read = fsl_flexspi_read;
+ nor->write = fsl_flexspi_write;
+ nor->erase = fsl_flexspi_erase;
+
+ nor->prepare = fsl_flexspi_prep;
+ nor->unprepare = fsl_flexspi_unprep;
+
+ ret = of_property_read_u32(np, "spi-max-frequency",
+ &flex->clk_rate);
+ if (ret < 0)
+ goto mutex_failed;
+
+ /* Can we enable the DDR Quad Read? */
+ ret = of_property_read_u32(np, "spi-nor,ddr-quad-read-dummy",
+ &dummy);
+ if (!ret && dummy > 0)
+ hwcaps.mask |= fsl_flexspi_quad_only(flex) ?
+ SNOR_HWCAPS_READ_1_4_4_DTR : SNOR_HWCAPS_READ_1_8_8_DTR;
+ else
+ hwcaps.mask |= SNOR_HWCAPS_READ;
+
+ /* set the chip address for READID */
+ fsl_flexspi_set_base_addr(flex, nor);
+
+
+ ret = spi_nor_scan(nor, NULL, &hwcaps);
+ if (ret)
+ goto mutex_failed;
+
+ ret = mtd_device_register(mtd, NULL, 0);
+ if (ret)
+ goto mutex_failed;
+
+ /* Set the correct NOR size now. */
+ if (flex->nor_size == 0) {
+ flex->nor_size = mtd->size;
+
+ /* Map the SPI NOR to accessiable address */
+ fsl_flexspi_set_map_addr(flex);
+ }
+
+ /*
+ * The TX FIFO is 64 bytes in the Vybrid, but the Page Program
+ * may writes 265 bytes per time. The write is working in the
+ * unit of the TX FIFO, not in the unit of the SPI NOR's page
+ * size.
+ *
+ * So shrink the spi_nor->page_size if it is larger then the
+ * TX FIFO.
+ */
+ if (nor->page_size > flex->devtype_data->txfifo)
+ nor->page_size = flex->devtype_data->txfifo;
+
+ i++;
+ }
+
+ /* finish the rest init. */
+ ret = fsl_flexspi_nor_setup_last(flex);
+ if (ret)
+ goto last_init_failed;
+
+ pm_runtime_mark_last_busy(flex->dev);
+ pm_runtime_put_autosuspend(flex->dev);
+
+ /* indicate the controller has been initialized */
+ flex->flags |= FLEXSPI_INITILIZED;
+
+ return 0;
+
+last_init_failed:
+ for (i = 0; i < flex->nor_num; i++) {
+ /* skip the holes */
+ if (!flex->has_second_chip)
+ i *= 2;
+ mtd_device_unregister(&flex->mtd[i]);
+ }
+mutex_failed:
+ mutex_destroy(&flex->lock);
+rpm_failed:
+ pm_runtime_dont_use_autosuspend(flex->dev);
+ pm_runtime_disable(flex->dev);
+clk_failed:
+ dev_err(dev, "Freescale FlexSPI probe failed\n");
+ return ret;
+}
+
+static int fsl_flexspi_remove(struct platform_device *pdev)
+{
+ struct fsl_flexspi *flex = platform_get_drvdata(pdev);
+ int i;
+
+ for (i = 0; i < flex->nor_num; i++) {
+ /* skip the holes */
+ if (!flex->has_second_chip)
+ i *= 2;
+ mtd_device_unregister(&flex->nor[i].mtd);
+ }
+
+ /* disable the hardware */
+ writel(FLEXSPI_MCR0_MDIS_MASK, flex->iobase + FLEXSPI_MCR0);
+
+ pm_runtime_disable(flex->dev);
+
+ mutex_destroy(&flex->lock);
+
+ if (flex->ahb_addr)
+ iounmap(flex->ahb_addr);
+
+ return 0;
+}
+
+static int fsl_flexspi_initialized(struct fsl_flexspi *flex)
+{
+ return flex->flags & FLEXSPI_INITILIZED;
+}
+
+static int fsl_flexspi_need_reinit(struct fsl_flexspi *flex)
+{
+ /* we always use the controller in combination mode, so we check this */
+ /* register bit to determine if the controller once lost power, such as */
+ /* suspend/resume, and need to be re-init */
+
+ return !(readl(flex->iobase + FLEXSPI_MCR0) & FLEXSPI_MCR0_OCTCOMB_EN_MASK);
+}
+
+int fsl_flexspi_runtime_suspend(struct device *dev)
+{
+ struct fsl_flexspi *flex = dev_get_drvdata(dev);
+
+ fsl_flexspi_clk_disable_unprep(flex);
+
+ return 0;
+}
+
+int fsl_flexspi_runtime_resume(struct device *dev)
+{
+ struct fsl_flexspi *flex = dev_get_drvdata(dev);
+
+ fsl_flexspi_clk_prep_enable(flex);
+
+ if (fsl_flexspi_initialized(flex) &&
+ fsl_flexspi_need_reinit(flex)) {
+ fsl_flexspi_nor_setup(flex);
+ fsl_flexspi_set_map_addr(flex);
+ fsl_flexspi_nor_setup_last(flex);
+ }
+
+ return 0;
+}
+
+static const struct dev_pm_ops fsl_flexspi_pm_ops = {
+ SET_RUNTIME_PM_OPS(fsl_flexspi_runtime_suspend, fsl_flexspi_runtime_resume, NULL)
+ SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, pm_runtime_force_resume)
+};
+
+static struct platform_driver fsl_flexspi_driver = {
+ .driver = {
+ .name = "fsl-flexspi",
+ .bus = &platform_bus_type,
+ .pm = &fsl_flexspi_pm_ops,
+ .of_match_table = fsl_flexspi_dt_ids,
+ },
+ .probe = fsl_flexspi_probe,
+ .remove = fsl_flexspi_remove,
+};
+module_platform_driver(fsl_flexspi_driver);
+
+
+MODULE_DESCRIPTION("Freescale FlexSPI Controller Driver");
+MODULE_AUTHOR("Freescale Semiconductor Inc.");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/mtd/spi-nor/fsl-quadspi.c b/drivers/mtd/spi-nor/fsl-quadspi.c
index 62f5763482b3..757d44f4cd23 100644
--- a/drivers/mtd/spi-nor/fsl-quadspi.c
+++ b/drivers/mtd/spi-nor/fsl-quadspi.c
@@ -1,7 +1,8 @@
/*
* Freescale QuadSPI driver.
*
- * Copyright (C) 2013 Freescale Semiconductor, Inc.
+ * Copyright (C) 2013-2016 Freescale Semiconductor, Inc.
+ * Copyright 2017-2018 NXP
*
* 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
@@ -29,6 +30,10 @@
#include <linux/mutex.h>
#include <linux/pm_qos.h>
#include <linux/sizes.h>
+#include <linux/pm_runtime.h>
+
+/* runtime pm timeout */
+#define QUADSPI_RPM_TIMEOUT 50 /* 50ms */
/* Controller needs driver to swap endian */
#define QUADSPI_QUIRK_SWAP_ENDIAN (1 << 0)
@@ -44,6 +49,9 @@
/* The registers */
#define QUADSPI_MCR 0x00
+#define MX6SX_QUADSPI_MCR_TX_DDR_DELAY_EN_SHIFT 29
+#define MX6SX_QUADSPI_MCR_TX_DDR_DELAY_EN_MASK \
+ (1 << MX6SX_QUADSPI_MCR_TX_DDR_DELAY_EN_SHIFT)
#define QUADSPI_MCR_RESERVED_SHIFT 16
#define QUADSPI_MCR_RESERVED_MASK (0xF << QUADSPI_MCR_RESERVED_SHIFT)
#define QUADSPI_MCR_MDIS_SHIFT 14
@@ -65,6 +73,11 @@
#define QUADSPI_IPCR_SEQID_SHIFT 24
#define QUADSPI_IPCR_SEQID_MASK (0xF << QUADSPI_IPCR_SEQID_SHIFT)
+#define QUADSPI_FLSHCR 0x0c
+#define QUADSPI_FLSHCR_TDH_SHIFT 16
+#define QUADSPI_FLSHCR_TDH_MASK (3 << QUADSPI_FLSHCR_TDH_SHIFT)
+#define QUADSPI_FLSHCR_TDH_DDR_EN (1 << QUADSPI_FLSHCR_TDH_SHIFT)
+
#define QUADSPI_BUF0CR 0x10
#define QUADSPI_BUF1CR 0x14
#define QUADSPI_BUF2CR 0x18
@@ -183,7 +196,7 @@
/* Macros for constructing the LUT register. */
#define LUT0(ins, pad, opr) \
- (((opr) << OPRND0_SHIFT) | ((LUT_##pad) << PAD0_SHIFT) | \
+ (((opr) << OPRND0_SHIFT) | ((pad) << PAD0_SHIFT) | \
((LUT_##ins) << INSTR0_SHIFT))
#define LUT1(ins, pad, opr) (LUT0(ins, pad, opr) << OPRND1_SHIFT)
@@ -192,22 +205,22 @@
#define QUADSPI_LUT(x) (QUADSPI_LUT_BASE + (x) * 4)
#define QUADSPI_LUT_NUM 64
-/* SEQID -- we can have 16 seqids at most. */
-#define SEQID_READ 0
-#define SEQID_WREN 1
-#define SEQID_WRDI 2
-#define SEQID_RDSR 3
-#define SEQID_SE 4
-#define SEQID_CHIP_ERASE 5
-#define SEQID_PP 6
-#define SEQID_RDID 7
-#define SEQID_WRSR 8
-#define SEQID_RDCR 9
-#define SEQID_EN4B 10
-#define SEQID_BRWR 11
+/* LUT0 programmed by bootloader, for run-time create entry for LUT seqid 1 */
+#define SEQID_LUT0_BOOTLOADER 0
+#define SEQID_LUT1_RUNTIME 1
+#define SEQID_LUT1_AHB 2
#define QUADSPI_MIN_IOMAP SZ_4M
+enum fsl_qspi_ops {
+ FSL_QSPI_OPS_READ = 0,
+ FSL_QSPI_OPS_WRITE,
+ FSL_QSPI_OPS_ERASE,
+ FSL_QSPI_OPS_READ_REG,
+ FSL_QSPI_OPS_WRITE_REG,
+ FSL_QSPI_OPS_WRITE_BUF_REG,
+};
+
enum fsl_qspi_devtype {
FSL_QUADSPI_VYBRID,
FSL_QUADSPI_IMX6SX,
@@ -285,8 +298,12 @@ struct fsl_qspi {
unsigned int chip_base_addr; /* We may support two chips. */
bool has_second_chip;
bool big_endian;
+ u32 ddr_smp; /* ddr sample point */
+ bool ddr_enabled;
struct mutex lock;
struct pm_qos_request pm_qos_req;
+#define FSL_QUADSPI_INITIALIZED (1 << 0)
+ int flags;
};
static inline int needs_swap_endian(struct fsl_qspi *q)
@@ -368,137 +385,173 @@ static irqreturn_t fsl_qspi_irq_handler(int irq, void *dev_id)
return IRQ_HANDLED;
}
-static void fsl_qspi_init_lut(struct fsl_qspi *q)
+static inline s8 pad_count(s8 pad_val)
+{
+ s8 count = -1;
+
+ if (!pad_val)
+ return 0;
+
+ while (pad_val) {
+ pad_val >>= 1;
+ count++;
+ }
+ return count;
+}
+
+/*
+ * Prepare LUT entry for the input cmd.
+ * Protocol info is present in instance of struct spi_nor, using which fields
+ * like cmd, data, addrlen along with pad info etc can be parsed.
+ */
+static void fsl_qspi_prepare_lut(struct spi_nor *nor,
+ enum fsl_qspi_ops ops, u8 cmd)
{
+ struct fsl_qspi *q = nor->priv;
void __iomem *base = q->iobase;
- int rxfifo = q->devtype_data->rxfifo;
u32 lut_base;
- int i;
+ u8 cmd_pad, addr_pad, data_pad, dummy_pad;
+ enum spi_nor_protocol protocol = 0;
+ u8 addrlen = 0;
+ u8 read_dm, opcode;
+ int stop_lut;
+
+ read_dm = opcode = cmd_pad = addr_pad = data_pad = dummy_pad = 0;
+
+ switch (ops) {
+ case FSL_QSPI_OPS_READ_REG:
+ case FSL_QSPI_OPS_WRITE_REG:
+ case FSL_QSPI_OPS_WRITE_BUF_REG:
+ opcode = cmd;
+ protocol = nor->reg_proto;
+ break;
+ case FSL_QSPI_OPS_READ:
+ opcode = cmd;
+ read_dm = nor->read_dummy;
+ protocol = nor->read_proto;
+ break;
+ case FSL_QSPI_OPS_WRITE:
+ opcode = cmd;
+ protocol = nor->write_proto;
+ break;
+ case FSL_QSPI_OPS_ERASE:
+ opcode = cmd;
+ break;
+ default:
+ dev_err(q->dev, "Unsupported operation 0x%.2x\n", ops);
+ return;
+ }
+ if (protocol) {
+ cmd_pad = spi_nor_get_protocol_inst_nbits(protocol);
+ addr_pad = spi_nor_get_protocol_addr_nbits(protocol);
+ data_pad = spi_nor_get_protocol_data_nbits(protocol);
+ }
+
+ dummy_pad = data_pad;
- struct spi_nor *nor = &q->nor[0];
- u8 addrlen = (nor->addr_width == 3) ? ADDR24BIT : ADDR32BIT;
- u8 read_op = nor->read_opcode;
- u8 read_dm = nor->read_dummy;
+ dev_dbg(q->dev, "ops:%x opcode:%x pad[cmd:%d, addr:%d, data:%d]\n",
+ ops, opcode, cmd_pad, addr_pad, data_pad);
fsl_qspi_unlock_lut(q);
- /* Clear all the LUT table */
- for (i = 0; i < QUADSPI_LUT_NUM; i++)
- qspi_writel(q, 0, base + QUADSPI_LUT_BASE + i * 4);
-
- /* Read */
- lut_base = SEQID_READ * 4;
-
- qspi_writel(q, LUT0(CMD, PAD1, read_op) | LUT1(ADDR, PAD1, addrlen),
- base + QUADSPI_LUT(lut_base));
- qspi_writel(q, LUT0(DUMMY, PAD1, read_dm) |
- LUT1(FSL_READ, PAD4, rxfifo),
- base + QUADSPI_LUT(lut_base + 1));
-
- /* Write enable */
- lut_base = SEQID_WREN * 4;
- qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_WREN),
- base + QUADSPI_LUT(lut_base));
-
- /* Page Program */
- lut_base = SEQID_PP * 4;
-
- qspi_writel(q, LUT0(CMD, PAD1, nor->program_opcode) |
- LUT1(ADDR, PAD1, addrlen),
- base + QUADSPI_LUT(lut_base));
- qspi_writel(q, LUT0(FSL_WRITE, PAD1, 0),
- base + QUADSPI_LUT(lut_base + 1));
-
- /* Read Status */
- lut_base = SEQID_RDSR * 4;
- qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_RDSR) |
- LUT1(FSL_READ, PAD1, 0x1),
- base + QUADSPI_LUT(lut_base));
-
- /* Erase a sector */
- lut_base = SEQID_SE * 4;
-
- qspi_writel(q, LUT0(CMD, PAD1, nor->erase_opcode) |
- LUT1(ADDR, PAD1, addrlen),
- base + QUADSPI_LUT(lut_base));
-
- /* Erase the whole chip */
- lut_base = SEQID_CHIP_ERASE * 4;
- qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_CHIP_ERASE),
- base + QUADSPI_LUT(lut_base));
-
- /* READ ID */
- lut_base = SEQID_RDID * 4;
- qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_RDID) |
- LUT1(FSL_READ, PAD1, 0x8),
- base + QUADSPI_LUT(lut_base));
-
- /* Write Register */
- lut_base = SEQID_WRSR * 4;
- qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_WRSR) |
- LUT1(FSL_WRITE, PAD1, 0x2),
- base + QUADSPI_LUT(lut_base));
-
- /* Read Configuration Register */
- lut_base = SEQID_RDCR * 4;
- qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_RDCR) |
- LUT1(FSL_READ, PAD1, 0x1),
- base + QUADSPI_LUT(lut_base));
-
- /* Write disable */
- lut_base = SEQID_WRDI * 4;
- qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_WRDI),
- base + QUADSPI_LUT(lut_base));
-
- /* Enter 4 Byte Mode (Micron) */
- lut_base = SEQID_EN4B * 4;
- qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_EN4B),
- base + QUADSPI_LUT(lut_base));
-
- /* Enter 4 Byte Mode (Spansion) */
- lut_base = SEQID_BRWR * 4;
- qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_BRWR),
- base + QUADSPI_LUT(lut_base));
+ /* Dynamic LUT */
+ lut_base = SEQID_LUT1_RUNTIME * 4;
- fsl_qspi_lock_lut(q);
-}
+ /* default, STOP instruction to be programmed in (lut_base + 1) reg */
+ stop_lut = 1;
+ switch (ops) {
+ case FSL_QSPI_OPS_READ_REG:
+ qspi_writel(q, LUT0(CMD, pad_count(cmd_pad), opcode) |
+ LUT1(FSL_READ, pad_count(data_pad), 0),
+ base + QUADSPI_LUT(lut_base));
+ break;
+ case FSL_QSPI_OPS_WRITE_REG:
+ qspi_writel(q, LUT0(CMD, pad_count(cmd_pad), opcode),
+ base + QUADSPI_LUT(lut_base));
+ break;
+ case FSL_QSPI_OPS_WRITE_BUF_REG:
+ qspi_writel(q, LUT0(CMD, pad_count(cmd_pad), opcode) |
+ LUT1(FSL_WRITE, pad_count(data_pad), 0),
+ base + QUADSPI_LUT(lut_base));
+ break;
+ case FSL_QSPI_OPS_READ:
+ case FSL_QSPI_OPS_WRITE:
+ case FSL_QSPI_OPS_ERASE:
+ /* Common for Read, Write and Erase ops. */
-/* Get the SEQID for the command */
-static int fsl_qspi_get_seqid(struct fsl_qspi *q, u8 cmd)
-{
- switch (cmd) {
- case SPINOR_OP_READ_1_1_4:
- case SPINOR_OP_READ_1_1_4_4B:
- return SEQID_READ;
- case SPINOR_OP_WREN:
- return SEQID_WREN;
- case SPINOR_OP_WRDI:
- return SEQID_WRDI;
- case SPINOR_OP_RDSR:
- return SEQID_RDSR;
- case SPINOR_OP_SE:
- return SEQID_SE;
- case SPINOR_OP_CHIP_ERASE:
- return SEQID_CHIP_ERASE;
- case SPINOR_OP_PP:
- return SEQID_PP;
- case SPINOR_OP_RDID:
- return SEQID_RDID;
- case SPINOR_OP_WRSR:
- return SEQID_WRSR;
- case SPINOR_OP_RDCR:
- return SEQID_RDCR;
- case SPINOR_OP_EN4B:
- return SEQID_EN4B;
- case SPINOR_OP_BRWR:
- return SEQID_BRWR;
+ addrlen = (nor->addr_width == 3) ? ADDR24BIT : ADDR32BIT;
+
+ qspi_writel(q, LUT0(CMD, pad_count(cmd_pad), opcode) |
+ LUT1(ADDR, pad_count(addr_pad), addrlen),
+ base + QUADSPI_LUT(lut_base));
+ /*
+ * For Erase ops - Data and Dummy not required.
+ * For Write ops - Dummy not required.
+ */
+
+ if (ops == FSL_QSPI_OPS_READ) {
+
+ lut_base = SEQID_LUT1_AHB * 4;
+
+ qspi_writel(q, LUT0(CMD, pad_count(cmd_pad), opcode) |
+ LUT1(ADDR, pad_count(addr_pad), addrlen),
+ base + QUADSPI_LUT(lut_base));
+
+ if (spi_nor_protocol_is_dtr(protocol))
+ qspi_writel(q, LUT0(CMD, pad_count(cmd_pad), opcode) |
+ LUT1(ADDR_DDR, pad_count(addr_pad), addrlen),
+ base + QUADSPI_LUT(lut_base));
+ /*
+ * For cmds SPINOR_OP_READ and SPINOR_OP_READ_4B value
+ * of dummy cycles are 0.
+ */
+ if (read_dm) {
+ qspi_writel(q,
+ LUT0(DUMMY, pad_count(dummy_pad),
+ read_dm) |
+ LUT1(FSL_READ, pad_count(data_pad),
+ 0),
+ base + QUADSPI_LUT(lut_base + 1));
+
+ if (spi_nor_protocol_is_dtr(protocol))
+ qspi_writel(q,
+ LUT0(DUMMY, pad_count(dummy_pad),
+ read_dm) |
+ LUT1(FSL_READ_DDR, pad_count(data_pad),
+ 0),
+ base + QUADSPI_LUT(lut_base + 1));
+ } else {
+ qspi_writel(q,
+ LUT0(FSL_READ, pad_count(data_pad),
+ 0),
+ base + QUADSPI_LUT(lut_base + 1));
+
+ if (spi_nor_protocol_is_dtr(protocol))
+ qspi_writel(q,
+ LUT0(FSL_READ_DDR, pad_count(data_pad),
+ 0),
+ base + QUADSPI_LUT(lut_base + 1));
+ }
+
+ stop_lut = 2;
+ }
+
+ if (ops == FSL_QSPI_OPS_WRITE) {
+
+ qspi_writel(q, LUT0(FSL_WRITE, pad_count(data_pad), 0),
+ base + QUADSPI_LUT(lut_base + 1));
+ stop_lut = 2;
+ }
+ break;
default:
- if (cmd == q->nor[0].erase_opcode)
- return SEQID_SE;
- dev_err(q->dev, "Unsupported cmd 0x%.2x\n", cmd);
+ dev_err(q->dev, "Unsupported operation 0x%.2x\n", ops);
break;
}
- return -EINVAL;
+
+ /* prepare LUT for STOP instruction. */
+ qspi_writel(q, 0, base + QUADSPI_LUT(lut_base + stop_lut));
+
+ fsl_qspi_lock_lut(q);
}
static int
@@ -533,7 +586,7 @@ fsl_qspi_runcmd(struct fsl_qspi *q, u8 cmd, unsigned int addr, int len)
} while (1);
/* trigger the LUT now */
- seqid = fsl_qspi_get_seqid(q, cmd);
+ seqid = SEQID_LUT1_RUNTIME;
qspi_writel(q, (seqid << QUADSPI_IPCR_SEQID_SHIFT) | len,
base + QUADSPI_IPCR);
@@ -662,7 +715,7 @@ static void fsl_qspi_set_map_addr(struct fsl_qspi *q)
* causes the controller to clear the buffer, and use the sequence pointed
* by the QUADSPI_BFGENCR[SEQID] to initiate a read from the flash.
*/
-static void fsl_qspi_init_abh_read(struct fsl_qspi *q)
+static void fsl_qspi_init_ahb_read(struct fsl_qspi *q)
{
void __iomem *base = q->iobase;
int seqid;
@@ -676,7 +729,7 @@ static void fsl_qspi_init_abh_read(struct fsl_qspi *q)
* read performance.
*/
qspi_writel(q, QUADSPI_BUF3CR_ALLMST_MASK |
- ((q->devtype_data->ahb_buf_size / 8)
+ ((q->devtype_data->ahb_buf_size / 8 / 8)
<< QUADSPI_BUF3CR_ADATSZ_SHIFT),
base + QUADSPI_BUF3CR);
@@ -685,8 +738,8 @@ static void fsl_qspi_init_abh_read(struct fsl_qspi *q)
qspi_writel(q, 0, base + QUADSPI_BUF1IND);
qspi_writel(q, 0, base + QUADSPI_BUF2IND);
- /* Set the default lut sequence for AHB Read. */
- seqid = fsl_qspi_get_seqid(q, q->nor[0].read_opcode);
+ /* Set dynamic LUT entry as lut sequence for AHB Read . */
+ seqid = SEQID_LUT1_AHB;
qspi_writel(q, seqid << QUADSPI_BFGENCR_SEQID_SHIFT,
q->iobase + QUADSPI_BFGENCR);
}
@@ -723,6 +776,17 @@ static void fsl_qspi_clk_disable_unprep(struct fsl_qspi *q)
}
+static int fsl_qspi_init_rpm(struct fsl_qspi *q)
+{
+ struct device *dev = q->dev;
+
+ pm_runtime_enable(dev);
+ pm_runtime_set_autosuspend_delay(dev, QUADSPI_RPM_TIMEOUT);
+ pm_runtime_use_autosuspend(dev);
+
+ return 0;
+}
+
/* We use this function to do some basic init for spi_nor_scan(). */
static int fsl_qspi_nor_setup(struct fsl_qspi *q)
{
@@ -747,9 +811,6 @@ static int fsl_qspi_nor_setup(struct fsl_qspi *q)
base + QUADSPI_MCR);
udelay(1);
- /* Init the LUT table. */
- fsl_qspi_init_lut(q);
-
/* Disable the module */
qspi_writel(q, QUADSPI_MCR_MDIS_MASK | QUADSPI_MCR_RESERVED_MASK,
base + QUADSPI_MCR);
@@ -760,6 +821,10 @@ static int fsl_qspi_nor_setup(struct fsl_qspi *q)
| QUADSPI_SMPR_HSENA_MASK
| QUADSPI_SMPR_DDRSMP_MASK), base + QUADSPI_SMPR);
+ /* disable the TDH bit of FLSHCR if it's been set*/
+ reg = qspi_readl(q, base + QUADSPI_FLSHCR);
+ qspi_writel(q, reg & ~QUADSPI_FLSHCR_TDH_MASK, base + QUADSPI_FLSHCR);
+
/* Enable the module */
qspi_writel(q, QUADSPI_MCR_RESERVED_MASK | QUADSPI_MCR_END_CFG_MASK,
base + QUADSPI_MCR);
@@ -770,6 +835,9 @@ static int fsl_qspi_nor_setup(struct fsl_qspi *q)
/* enable the interrupt */
qspi_writel(q, QUADSPI_RSER_TFIE, q->iobase + QUADSPI_RSER);
+ /* Init for AHB read */
+ fsl_qspi_init_ahb_read(q);
+
return 0;
}
@@ -792,12 +860,6 @@ static int fsl_qspi_nor_setup_last(struct fsl_qspi *q)
if (ret)
return ret;
- /* Init the LUT table again. */
- fsl_qspi_init_lut(q);
-
- /* Init for AHB read */
- fsl_qspi_init_abh_read(q);
-
return 0;
}
@@ -807,6 +869,7 @@ static const struct of_device_id fsl_qspi_dt_ids[] = {
{ .compatible = "fsl,imx7d-qspi", .data = (void *)&imx7d_data, },
{ .compatible = "fsl,imx6ul-qspi", .data = (void *)&imx6ul_data, },
{ .compatible = "fsl,ls1021a-qspi", .data = (void *)&ls1021a_data, },
+ { .compatible = "fsl,imx6ull-qspi", .data = (void *)&imx6ul_data, },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, fsl_qspi_dt_ids);
@@ -821,6 +884,7 @@ static int fsl_qspi_read_reg(struct spi_nor *nor, u8 opcode, u8 *buf, int len)
int ret;
struct fsl_qspi *q = nor->priv;
+ fsl_qspi_prepare_lut(nor, FSL_QSPI_OPS_READ_REG, opcode);
ret = fsl_qspi_runcmd(q, opcode, 0, len);
if (ret)
return ret;
@@ -835,6 +899,8 @@ static int fsl_qspi_write_reg(struct spi_nor *nor, u8 opcode, u8 *buf, int len)
int ret;
if (!buf) {
+ /* Prepare LUT for WRITE_REG cmd with input BUF as NULL. */
+ fsl_qspi_prepare_lut(nor, FSL_QSPI_OPS_WRITE_REG, opcode);
ret = fsl_qspi_runcmd(q, opcode, 0, 1);
if (ret)
return ret;
@@ -843,6 +909,8 @@ static int fsl_qspi_write_reg(struct spi_nor *nor, u8 opcode, u8 *buf, int len)
fsl_qspi_invalid(q);
} else if (len > 0) {
+ /* Prepare LUT for WRITE_REG cmd with input BUF non-NULL. */
+ fsl_qspi_prepare_lut(nor, FSL_QSPI_OPS_WRITE_BUF_REG, opcode);
ret = fsl_qspi_nor_write(q, nor, opcode, 0,
(u32 *)buf, len);
if (ret > 0)
@@ -859,26 +927,85 @@ static ssize_t fsl_qspi_write(struct spi_nor *nor, loff_t to,
size_t len, const u_char *buf)
{
struct fsl_qspi *q = nor->priv;
- ssize_t ret = fsl_qspi_nor_write(q, nor, nor->program_opcode, to,
- (u32 *)buf, len);
+ ssize_t ret;
+
+ fsl_qspi_prepare_lut(nor, FSL_QSPI_OPS_WRITE, nor->program_opcode);
+ ret = fsl_qspi_nor_write(q, nor, nor->program_opcode, to,
+ (u32 *)buf, len);
/* invalid the data in the AHB buffer. */
fsl_qspi_invalid(q);
return ret;
}
+static void __fsl_qspi_enable_ddr_mode(struct spi_nor *nor, bool v)
+{
+ struct fsl_qspi *q = nor->priv;
+ u32 reg, reg2;
+
+ reg = qspi_readl(q, q->iobase + QUADSPI_MCR);
+
+ /* Firstly, disable the module */
+ qspi_writel(q, reg | QUADSPI_MCR_MDIS_MASK,
+ q->iobase + QUADSPI_MCR);
+
+ reg2 = qspi_readl(q, q->iobase + QUADSPI_SMPR);
+ reg2 &= ~QUADSPI_SMPR_DDRSMP_MASK;
+
+ /* Set the Sampling Register for DDR, if to enable it */
+ if (v)
+ reg2 |= ((q->ddr_smp << QUADSPI_SMPR_DDRSMP_SHIFT) &
+ QUADSPI_SMPR_DDRSMP_MASK);
+
+ qspi_writel(q, reg2, q->iobase + QUADSPI_SMPR);
+
+ /* Enable the module again and enable the DDR, if need */
+ if (v) {
+ reg |= QUADSPI_MCR_DDR_EN_MASK;
+ if (q->devtype_data->devtype == FSL_QUADSPI_IMX6SX)
+ reg |= MX6SX_QUADSPI_MCR_TX_DDR_DELAY_EN_MASK;
+ }
+
+ qspi_writel(q, reg, q->iobase + QUADSPI_MCR);
+
+ if ((q->devtype_data->devtype == FSL_QUADSPI_IMX6UL) ||
+ (q->devtype_data->devtype == FSL_QUADSPI_IMX7D)) {
+
+ reg = qspi_readl(q, q->iobase + QUADSPI_FLSHCR);
+ reg &= ~QUADSPI_FLSHCR_TDH_MASK;
+
+ if (v)
+ reg |= QUADSPI_FLSHCR_TDH_DDR_EN;
+
+ qspi_writel(q, reg, q->iobase + QUADSPI_FLSHCR);
+ }
+}
+
+#define fsl_qspi_enable_ddr_mode(x) __fsl_qspi_enable_ddr_mode(x, true)
+#define fsl_qspi_disable_ddr_mode(x) __fsl_qspi_enable_ddr_mode(x, false)
+
static ssize_t fsl_qspi_read(struct spi_nor *nor, loff_t from,
size_t len, u_char *buf)
{
struct fsl_qspi *q = nor->priv;
u8 cmd = nor->read_opcode;
+ fsl_qspi_prepare_lut(nor, FSL_QSPI_OPS_READ, nor->read_opcode);
+
+ if (spi_nor_protocol_is_dtr(nor->read_proto) && !q->ddr_enabled) {
+ fsl_qspi_enable_ddr_mode(nor);
+ q->ddr_enabled = true;
+ } else if (!spi_nor_protocol_is_dtr(nor->read_proto) && q->ddr_enabled) {
+ fsl_qspi_disable_ddr_mode(nor);
+ q->ddr_enabled = false;
+ }
+
/* if necessary,ioremap buffer before AHB read, */
if (!q->ahb_addr) {
q->memmap_offs = q->chip_base_addr + from;
q->memmap_len = len > QUADSPI_MIN_IOMAP ? len : QUADSPI_MIN_IOMAP;
- q->ahb_addr = ioremap_nocache(
+ q->ahb_addr = ioremap_wc(
q->memmap_phy + q->memmap_offs,
q->memmap_len);
if (!q->ahb_addr) {
@@ -893,7 +1020,7 @@ static ssize_t fsl_qspi_read(struct spi_nor *nor, loff_t from,
q->memmap_offs = q->chip_base_addr + from;
q->memmap_len = len > QUADSPI_MIN_IOMAP ? len : QUADSPI_MIN_IOMAP;
- q->ahb_addr = ioremap_nocache(
+ q->ahb_addr = ioremap_wc(
q->memmap_phy + q->memmap_offs,
q->memmap_len);
if (!q->ahb_addr) {
@@ -906,9 +1033,8 @@ static ssize_t fsl_qspi_read(struct spi_nor *nor, loff_t from,
cmd, q->ahb_addr + q->chip_base_addr + from - q->memmap_offs,
len);
- /* Read out the data directly from the AHB buffer.*/
- memcpy(buf, q->ahb_addr + q->chip_base_addr + from - q->memmap_offs,
- len);
+ memcpy(buf, q->ahb_addr + q->chip_base_addr + from
+ - q->memmap_offs, len);
return len;
}
@@ -921,6 +1047,7 @@ static int fsl_qspi_erase(struct spi_nor *nor, loff_t offs)
dev_dbg(nor->dev, "%dKiB at 0x%08x:0x%08x\n",
nor->mtd.erasesize / 1024, q->chip_base_addr, (u32)offs);
+ fsl_qspi_prepare_lut(nor, FSL_QSPI_OPS_ERASE, nor->erase_opcode);
ret = fsl_qspi_runcmd(q, nor->erase_opcode, offs, 0);
if (ret)
return ret;
@@ -936,9 +1063,11 @@ static int fsl_qspi_prep(struct spi_nor *nor, enum spi_nor_ops ops)
mutex_lock(&q->lock);
- ret = fsl_qspi_clk_prep_enable(q);
- if (ret)
+ ret = pm_runtime_get_sync(q->dev);
+ if (ret < 0) {
+ dev_err(q->dev, "Failed to enable clock\n");
goto err_mutex;
+ }
fsl_qspi_set_base_addr(q, nor);
return 0;
@@ -952,7 +1081,8 @@ static void fsl_qspi_unprep(struct spi_nor *nor, enum spi_nor_ops ops)
{
struct fsl_qspi *q = nor->priv;
- fsl_qspi_clk_disable_unprep(q);
+ pm_runtime_mark_last_busy(q->dev);
+ pm_runtime_put_autosuspend(q->dev);
mutex_unlock(&q->lock);
}
@@ -960,6 +1090,7 @@ static int fsl_qspi_probe(struct platform_device *pdev)
{
const struct spi_nor_hwcaps hwcaps = {
.mask = SNOR_HWCAPS_READ_1_1_4 |
+ SNOR_HWCAPS_READ_1_4_4_DTR |
SNOR_HWCAPS_PP,
};
struct device_node *np = pdev->dev.of_node;
@@ -983,9 +1114,14 @@ static int fsl_qspi_probe(struct platform_device *pdev)
if (!q->devtype_data)
return -ENODEV;
platform_set_drvdata(pdev, q);
+ dev_set_drvdata(dev, q);
/* find the resources */
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "QuadSPI");
+ if (!res) {
+ dev_err(dev, "QuadSPI get resource IORESOURCE_MEM failed\n");
+ return -ENODEV;
+ }
q->iobase = devm_ioremap_resource(dev, res);
if (IS_ERR(q->iobase))
return PTR_ERR(q->iobase);
@@ -993,6 +1129,11 @@ static int fsl_qspi_probe(struct platform_device *pdev)
q->big_endian = of_property_read_bool(np, "big-endian");
res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
"QuadSPI-memory");
+ if (!res) {
+ dev_err(dev,
+ "QuadSPI-memory get resource IORESOURCE_MEM failed\n");
+ return -ENODEV;
+ }
if (!devm_request_mem_region(dev, res->start, resource_size(res),
res->name)) {
dev_err(dev, "can't request region for resource %pR\n", res);
@@ -1010,29 +1151,41 @@ static int fsl_qspi_probe(struct platform_device *pdev)
if (IS_ERR(q->clk))
return PTR_ERR(q->clk);
- ret = fsl_qspi_clk_prep_enable(q);
- if (ret) {
- dev_err(dev, "can not enable the clock\n");
- goto clk_failed;
- }
+ /* find ddrsmp value */
+ ret = of_property_read_u32(dev->of_node, "ddrsmp",
+ &q->ddr_smp);
+ if (ret)
+ q->ddr_smp = 0;
/* find the irq */
ret = platform_get_irq(pdev, 0);
if (ret < 0) {
dev_err(dev, "failed to get the irq: %d\n", ret);
- goto irq_failed;
+ goto clk_failed;
}
ret = devm_request_irq(dev, ret,
fsl_qspi_irq_handler, 0, pdev->name, q);
if (ret) {
dev_err(dev, "failed to request irq: %d\n", ret);
- goto irq_failed;
+ goto clk_failed;
+ }
+
+ ret = fsl_qspi_init_rpm(q);
+ if (ret) {
+ dev_err(dev, "can not enable the clock\n");
+ goto clk_failed;
+ }
+
+ ret = pm_runtime_get_sync(q->dev);
+ if (ret < 0) {
+ dev_err(q->dev, "Failed to enable clock\n");
+ goto rpm_init_failed;
}
ret = fsl_qspi_nor_setup(q);
if (ret)
- goto irq_failed;
+ goto rpm_failed;
if (of_get_property(np, "fsl,qspi-has-second-chip", NULL))
q->has_second_chip = true;
@@ -1106,7 +1259,12 @@ static int fsl_qspi_probe(struct platform_device *pdev)
if (ret)
goto last_init_failed;
- fsl_qspi_clk_disable_unprep(q);
+ pm_runtime_mark_last_busy(q->dev);
+ pm_runtime_put_autosuspend(q->dev);
+
+ /* indicate the controller has been initialized */
+ q->flags |= FSL_QUADSPI_INITIALIZED;
+
return 0;
last_init_failed:
@@ -1118,8 +1276,12 @@ last_init_failed:
}
mutex_failed:
mutex_destroy(&q->lock);
-irq_failed:
- fsl_qspi_clk_disable_unprep(q);
+rpm_failed:
+ pm_runtime_mark_last_busy(q->dev);
+ pm_runtime_put_autosuspend(q->dev);
+rpm_init_failed:
+ pm_runtime_dont_use_autosuspend(q->dev);
+ pm_runtime_disable(q->dev);
clk_failed:
dev_err(dev, "Freescale QuadSPI probe failed\n");
return ret;
@@ -1149,39 +1311,67 @@ static int fsl_qspi_remove(struct platform_device *pdev)
return 0;
}
-static int fsl_qspi_suspend(struct platform_device *pdev, pm_message_t state)
+static int fsl_qspi_initialized(struct fsl_qspi *q)
{
+ return q->flags & FSL_QUADSPI_INITIALIZED;
+}
+
+static int fsl_qspi_need_reinit(struct fsl_qspi *q)
+{
+ /* we always enable AHB data transfer bit for best performance, */
+ /* so check this register bit to determine if the controller */
+ /* once lost power, such as suspend/resume and need to be re-init */
+
+ return !(readl(q->iobase + QUADSPI_BUF3CR)
+ & QUADSPI_BUF3CR_ADATSZ_MASK);
+}
+
+static int fsl_qspi_runtime_suspend(struct device *dev)
+{
+ struct fsl_qspi *q = dev_get_drvdata(dev);
+
+ pinctrl_pm_select_sleep_state(dev);
+ fsl_qspi_clk_disable_unprep(q);
+
return 0;
}
-static int fsl_qspi_resume(struct platform_device *pdev)
+static int fsl_qspi_runtime_resume(struct device *dev)
{
int ret;
- struct fsl_qspi *q = platform_get_drvdata(pdev);
+ struct fsl_qspi *q = dev_get_drvdata(dev);
+
+ pinctrl_pm_select_default_state(dev);
ret = fsl_qspi_clk_prep_enable(q);
if (ret)
return ret;
- fsl_qspi_nor_setup(q);
- fsl_qspi_set_map_addr(q);
- fsl_qspi_nor_setup_last(q);
-
- fsl_qspi_clk_disable_unprep(q);
+ if (fsl_qspi_initialized(q) &&
+ fsl_qspi_need_reinit(q)) {
+ fsl_qspi_nor_setup(q);
+ fsl_qspi_set_map_addr(q);
+ fsl_qspi_nor_setup_last(q);
+ q->ddr_enabled = false;
+ }
return 0;
}
+static const struct dev_pm_ops fsl_qspi_pm_ops = {
+ SET_RUNTIME_PM_OPS(fsl_qspi_runtime_suspend, fsl_qspi_runtime_resume, NULL)
+ SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, pm_runtime_force_resume)
+};
+
static struct platform_driver fsl_qspi_driver = {
.driver = {
.name = "fsl-quadspi",
.bus = &platform_bus_type,
+ .pm = &fsl_qspi_pm_ops,
.of_match_table = fsl_qspi_dt_ids,
},
.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 d550148177a0..140d93384527 100644
--- a/drivers/mtd/spi-nor/spi-nor.c
+++ b/drivers/mtd/spi-nor/spi-nor.c
@@ -3,7 +3,7 @@
* influence from lart.c (Abraham Van Der Merwe) and mtd_dataflash.c
*
* Copyright (C) 2005, Intec Automation Inc.
- * Copyright (C) 2014, Freescale Semiconductor, Inc.
+ * Copyright (C) 2014-2016 Freescale Semiconductor, Inc.
*
* This code is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -89,6 +89,7 @@ struct flash_info {
#define NO_CHIP_ERASE BIT(12) /* Chip does not support chip erase */
#define SPI_NOR_SKIP_SFDP BIT(13) /* Skip parsing of SFDP tables */
#define USE_CLSR BIT(14) /* use CLSR command */
+#define SPI_NOR_OCTAL_READ BIT(15) /* Flash supports DDR Octal Read */
};
#define JEDEC_MFR(info) ((info)->id[0])
@@ -197,6 +198,18 @@ static u8 spi_nor_convert_opcode(u8 opcode, const u8 table[][2], size_t size)
return opcode;
}
+static inline u8 spi_nor_convert_str_to_dtr_read(u8 opcode)
+{
+ static const u8 spi_nor_sdr_to_dtr_read[][2] = {
+ { SPINOR_OP_READ_FAST, SPINOR_OP_READ_1_1_1_DTR },
+ { SPINOR_OP_READ_1_2_2, SPINOR_OP_READ_1_2_2_DTR },
+ { SPINOR_OP_READ_1_4_4, SPINOR_OP_READ_1_4_4_DTR },
+ };
+
+ return spi_nor_convert_opcode(opcode, spi_nor_sdr_to_dtr_read,
+ ARRAY_SIZE(spi_nor_sdr_to_dtr_read));
+};
+
static inline u8 spi_nor_convert_3to4_read(u8 opcode)
{
static const u8 spi_nor_3to4_read[][2] = {
@@ -270,6 +283,7 @@ static inline int set_4byte(struct spi_nor *nor, const struct flash_info *info,
switch (JEDEC_MFR(info)) {
case SNOR_MFR_MICRON:
+ case SNOR_MFR_MICRONO:
/* Some Micron need WREN command; all will accept it */
need_wren = true;
case SNOR_MFR_MACRONIX:
@@ -978,6 +992,11 @@ static const struct flash_info spi_nor_ids[] = {
SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB)
},
{
+ "gd25q16", INFO(0xc86015, 0, 64 * 1024, 32,
+ SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
+ SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB)
+ },
+ {
"gd25q32", INFO(0xc84016, 0, 64 * 1024, 64,
SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB)
@@ -1025,6 +1044,7 @@ static const struct flash_info spi_nor_ids[] = {
{ "mx25u4035", INFO(0xc22533, 0, 64 * 1024, 8, SECT_4K) },
{ "mx25u8035", INFO(0xc22534, 0, 64 * 1024, 16, SECT_4K) },
{ "mx25u6435f", INFO(0xc22537, 0, 64 * 1024, 128, SECT_4K) },
+ { "mx25r6435f", INFO(0xc22817, 0, 64 * 1024, 128, 0) },
{ "mx25l12805d", INFO(0xc22018, 0, 64 * 1024, 256, 0) },
{ "mx25l12855e", INFO(0xc22618, 0, 64 * 1024, 256, 0) },
{ "mx25l25635e", INFO(0xc22019, 0, 64 * 1024, 512, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
@@ -1042,6 +1062,7 @@ static const struct flash_info spi_nor_ids[] = {
{ "n25q064", INFO(0x20ba17, 0, 64 * 1024, 128, SECT_4K | SPI_NOR_QUAD_READ) },
{ "n25q064a", INFO(0x20bb17, 0, 64 * 1024, 128, SECT_4K | SPI_NOR_QUAD_READ) },
{ "n25q128a11", INFO(0x20bb18, 0, 64 * 1024, 256, SECT_4K | SPI_NOR_QUAD_READ) },
+ { "mt25qu256", INFO(0x20bb19, 0, 64 * 1024, 256, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
{ "n25q128a13", INFO(0x20ba18, 0, 64 * 1024, 256, SECT_4K | SPI_NOR_QUAD_READ) },
{ "n25q256a", INFO(0x20ba19, 0, 64 * 1024, 512, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
{ "n25q256ax1", INFO(0x20bb19, 0, 64 * 1024, 512, SECT_4K | SPI_NOR_QUAD_READ) },
@@ -1049,6 +1070,7 @@ static const struct flash_info spi_nor_ids[] = {
{ "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 | NO_CHIP_ERASE) },
{ "n25q00a", INFO(0x20bb21, 0, 64 * 1024, 2048, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ | NO_CHIP_ERASE) },
+ {"mt35xu512aba", INFO(0x2c5b1a, 0, 128 * 1024, 512, SECT_4K | SPI_NOR_OCTAL_READ | SPI_NOR_SKIP_SFDP) },
/* PMC */
{ "pm25lv512", INFO(0, 0, 32 * 1024, 2, SECT_4K_PMC) },
@@ -1979,14 +2001,25 @@ struct sfdp_bfpt {
/* Fast Read settings. */
static inline void
-spi_nor_set_read_settings_from_bfpt(struct spi_nor_read_command *read,
+spi_nor_set_read_settings_from_bfpt(struct spi_nor *nor,
+ struct spi_nor_read_command *read,
u16 half,
enum spi_nor_protocol proto)
{
+ u8 opcode;
+
read->num_mode_clocks = (half >> 5) & 0x07;
read->num_wait_states = (half >> 0) & 0x1f;
- read->opcode = (half >> 8) & 0xff;
read->proto = proto;
+ opcode = (half >> 8) & 0xff;
+
+ if (spi_nor_protocol_is_dtr(proto))
+ opcode = spi_nor_convert_str_to_dtr_read(opcode);
+ if (nor->addr_width == 4)
+ opcode = spi_nor_convert_3to4_read(opcode);
+
+ read->opcode = opcode;
+
}
struct sfdp_bfpt_read {
@@ -2053,6 +2086,14 @@ static const struct sfdp_bfpt_read sfdp_bfpt_reads[] = {
SNOR_PROTO_1_4_4,
},
+ /* Fast Read 1-4-4-DTR */
+ {
+ SNOR_HWCAPS_READ_1_4_4_DTR,
+ BFPT_DWORD(1), BIT(21), /* Supported bit */
+ BFPT_DWORD(3), 0, /* Settings */
+ SNOR_PROTO_1_4_4_DTR,
+ },
+
/* Fast Read 4-4-4 */
{
SNOR_HWCAPS_READ_4_4_4,
@@ -2192,7 +2233,7 @@ static int spi_nor_parse_bfpt(struct spi_nor *nor,
cmd = spi_nor_hwcaps_read2cmd(rd->hwcaps);
read = &params->reads[cmd];
half = bfpt.dwords[rd->settings_dword] >> rd->settings_shift;
- spi_nor_set_read_settings_from_bfpt(read, half, rd->proto);
+ spi_nor_set_read_settings_from_bfpt(nor, read, half, rd->proto);
}
/* Sector Erase settings. */
@@ -2412,6 +2453,13 @@ static int spi_nor_init_params(struct spi_nor *nor,
SNOR_PROTO_1_1_4);
}
+ if (info->flags & SPI_NOR_OCTAL_READ) {
+ params->hwcaps.mask |= SNOR_HWCAPS_READ_1_8_8_DTR;
+ spi_nor_set_read_settings(&params->reads[SNOR_CMD_READ_1_8_8_DTR],
+ 0, 8, SPINOR_OP_READ_1_8_8_DTR_4B,
+ SNOR_PROTO_1_8_8_DTR);
+ }
+
/* Page Program settings. */
params->hwcaps.mask |= SNOR_HWCAPS_PP;
spi_nor_set_pp_settings(&params->page_programs[SNOR_CMD_PP],
@@ -2426,6 +2474,7 @@ static int spi_nor_init_params(struct spi_nor *nor,
break;
case SNOR_MFR_MICRON:
+ case SNOR_MFR_MICRONO:
break;
default:
@@ -2534,6 +2583,14 @@ static int spi_nor_select_read(struct spi_nor *nor,
* into the so called dummy clock cycles.
*/
nor->read_dummy = read->num_mode_clocks + read->num_wait_states;
+
+ /*
+ * STR mode may need 10 dummy cycles but the DDR mode should be
+ * no more than 8 cycles
+ */
+ if (spi_nor_protocol_is_dtr(read->proto))
+ nor->read_dummy = nor->read_dummy > 8 ? 8 : nor->read_dummy;
+
return 0;
}
@@ -2595,6 +2652,7 @@ static int spi_nor_setup(struct spi_nor *nor, const struct flash_info *info,
* Keep only the hardware capabilities supported by both the SPI
* controller and the SPI flash memory.
*/
+
shared_mask = hwcaps->mask & params->hwcaps.mask;
/* SPI n-n-n protocols are not supported yet. */
@@ -2740,6 +2798,7 @@ int spi_nor_scan(struct spi_nor *nor, const char *name,
/* NOR protection support for STmicro/Micron chips and similar */
if (JEDEC_MFR(info) == SNOR_MFR_MICRON ||
+ JEDEC_MFR(info) == SNOR_MFR_MICRONO ||
info->flags & SPI_NOR_HAS_LOCK) {
nor->flash_lock = stm_lock;
nor->flash_unlock = stm_unlock;
diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c
index 0104d9537329..c2870fc969db 100644
--- a/drivers/mtd/ubi/build.c
+++ b/drivers/mtd/ubi/build.c
@@ -580,7 +580,7 @@ static int io_init(struct ubi_device *ubi, int max_beb_per1024)
dbg_gen("sizeof(struct ubi_ainf_peb) %zu", sizeof(struct ubi_ainf_peb));
dbg_gen("sizeof(struct ubi_wl_entry) %zu", sizeof(struct ubi_wl_entry));
- if (ubi->mtd->numeraseregions != 0) {
+ if (ubi->mtd->numeraseregions > 1) {
/*
* Some flashes have several erase regions. Different regions
* may have different eraseblock size and other
diff --git a/drivers/mxc/Kconfig b/drivers/mxc/Kconfig
new file mode 100755
index 000000000000..a011dcd650fb
--- /dev/null
+++ b/drivers/mxc/Kconfig
@@ -0,0 +1,46 @@
+# drivers/mxc/Kconfig
+
+if ARCH_MXC || ARCH_MXC_ARM64
+
+menu "MXC support drivers"
+
+# drivers common to MXC and MX8 go here:
+source "drivers/mxc/gpu-viv/Kconfig"
+source "drivers/mxc/hantro/Kconfig"
+source "drivers/mxc/mlb/Kconfig"
+source "drivers/mxc/hdp/Kconfig"
+source "drivers/mxc/hdp-cec/Kconfig"
+
+config MXC_SIM
+ tristate "MXC SIM support"
+ default n
+ ---help---
+ Say Y to get MXC SIM support.
+
+source "drivers/mxc/sim/Kconfig"
+
+if ARCH_MXC_ARM64
+source "drivers/mxc/hantro_845/Kconfig"
+source "drivers/mxc/hantro_845_h1/Kconfig"
+source "drivers/mxc/vpu_legacy/Kconfig"
+source "drivers/mxc/vpu_malone/Kconfig"
+source "drivers/mxc/vpu_windsor/Kconfig"
+endif
+
+if ARCH_MXC
+config MXC_IPU
+ bool "Image Processing Unit Driver"
+ select MXC_IPU_V3
+ help
+ If you plan to use the Image Processing unit, say
+ Y here. IPU is needed by Framebuffer and V4L2 drivers.
+
+source "drivers/mxc/ipu3/Kconfig"
+source "drivers/mxc/mipi/Kconfig"
+source "drivers/mxc/vpu/Kconfig"
+source "drivers/mxc/hdmi-cec/Kconfig"
+endif
+
+endmenu
+
+endif
diff --git a/drivers/mxc/Makefile b/drivers/mxc/Makefile
new file mode 100755
index 000000000000..72b6b647a07a
--- /dev/null
+++ b/drivers/mxc/Makefile
@@ -0,0 +1,15 @@
+obj-$(CONFIG_MXC_MLB) += mlb/
+obj-$(CONFIG_MXC_SIM) += sim/
+obj-$(CONFIG_MXC_VPU) += vpu/
+obj-$(CONFIG_MXC_IPU_V3) += ipu3/
+obj-$(CONFIG_MXC_HDMI_CEC) += hdmi-cec/
+obj-$(CONFIG_MXC_GPU_VIV) += gpu-viv/
+obj-$(CONFIG_MXC_MIPI_CSI2) += mipi/
+obj-$(CONFIG_MXC_HANTRO) += hantro/
+obj-$(CONFIG_MXC_HANTRO_845) += hantro_845/
+obj-$(CONFIG_MXC_HANTRO_845_H1) += hantro_845_h1/
+obj-$(CONFIG_MXC_VPU_LEGACY) += vpu_legacy/
+obj-$(CONFIG_MX8_HDP) += hdp/
+obj-$(CONFIG_IMX_HDP_CEC) += hdp-cec/
+obj-$(CONFIG_MXC_VPU_MALONE) += vpu_malone/
+obj-$(CONFIG_MXC_VPU_WINDSOR) += vpu_windsor/
diff --git a/drivers/mxc/gpu-viv/Kbuild b/drivers/mxc/gpu-viv/Kbuild
new file mode 100644
index 000000000000..5f45b13d9571
--- /dev/null
+++ b/drivers/mxc/gpu-viv/Kbuild
@@ -0,0 +1,326 @@
+##############################################################################
+#
+# The MIT License (MIT)
+#
+# Copyright (c) 2014 - 2018 Vivante 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 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 GPL License (GPL)
+#
+# Copyright (C) 2014 - 2018 Vivante 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.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+##############################################################################
+#
+# Note: This software is released under dual MIT and GPL licenses. A
+# recipient may use this file under the terms of either the MIT license or
+# GPL License. If you wish to use only one license not the other, you can
+# indicate your decision by deleting one of the above license notices in your
+# version of this file.
+#
+##############################################################################
+
+
+#
+# Linux build file for kernel HAL driver.
+#
+AQROOT := $(srctree)/drivers/mxc/gpu-viv
+
+include $(AQROOT)/config
+
+soc_vendor := $(firstword $(subst -, ,$(SOC_PLATFORM)))
+soc_board := $(lastword $(subst -, ,$(SOC_PLATFORM)))
+
+KERNEL_DIR ?= $(TOOL_DIR)/kernel
+
+OS_KERNEL_DIR := hal/os/linux/kernel
+ARCH_KERNEL_DIR := hal/kernel/arch
+ARCH_VG_KERNEL_DIR := hal/kernel/archvg
+HAL_KERNEL_DIR := hal/kernel
+TA_DIR := hal/security_v1
+HOST := $(shell hostname)
+
+# Include platform config if exists.
+-include $(AQROOT)/$(OS_KERNEL_DIR)/platform/$(soc_vendor)/gc_hal_kernel_platform_$(soc_board).config
+
+MODULE_NAME ?= galcore
+CUSTOMER_ALLOCATOR_OBJS ?=
+ALLOCATOR_ARRAY_H_LOCATION ?= $(OS_KERNEL_DIR)/allocator/default/
+
+EXTRA_CFLAGS += -Werror
+
+OBJS := $(OS_KERNEL_DIR)/gc_hal_kernel_device.o \
+ $(OS_KERNEL_DIR)/gc_hal_kernel_linux.o \
+ $(OS_KERNEL_DIR)/gc_hal_kernel_math.o \
+ $(OS_KERNEL_DIR)/gc_hal_kernel_os.o \
+ $(OS_KERNEL_DIR)/gc_hal_kernel_debugfs.o \
+ $(OS_KERNEL_DIR)/gc_hal_kernel_allocator.o \
+ $(OS_KERNEL_DIR)/allocator/default/gc_hal_kernel_allocator_user_memory.o \
+ $(OS_KERNEL_DIR)/allocator/default/gc_hal_kernel_allocator_dma.o \
+ $(OS_KERNEL_DIR)/allocator/default/gc_hal_kernel_allocator_gfp.o \
+ $(OS_KERNEL_DIR)/allocator/default/gc_hal_kernel_allocator_reserved_mem.o \
+ $(OS_KERNEL_DIR)/gc_hal_kernel_driver.o \
+ $(OS_KERNEL_DIR)/platform/$(soc_vendor)/gc_hal_kernel_platform_$(soc_board).o
+
+ifneq ($(CONFIG_DMA_SHARED_BUFFER),)
+OBJS += $(OS_KERNEL_DIR)/allocator/default/gc_hal_kernel_allocator_dmabuf.o
+endif
+
+ifneq ($(CONFIG_IOMMU_SUPPORT),)
+OBJS += $(OS_KERNEL_DIR)/gc_hal_kernel_iommu.o
+endif
+
+ifneq ($(CONFIG_DRM),)
+OBJS += $(OS_KERNEL_DIR)/gc_hal_kernel_drm.o
+endif
+
+OBJS += $(HAL_KERNEL_DIR)/gc_hal_kernel.o \
+ $(HAL_KERNEL_DIR)/gc_hal_kernel_command.o \
+ $(HAL_KERNEL_DIR)/gc_hal_kernel_async_command.o \
+ $(HAL_KERNEL_DIR)/gc_hal_kernel_db.o \
+ $(HAL_KERNEL_DIR)/gc_hal_kernel_debug.o \
+ $(HAL_KERNEL_DIR)/gc_hal_kernel_event.o \
+ $(HAL_KERNEL_DIR)/gc_hal_kernel_heap.o \
+ $(HAL_KERNEL_DIR)/gc_hal_kernel_mmu.o \
+ $(HAL_KERNEL_DIR)/gc_hal_kernel_video_memory.o \
+ $(HAL_KERNEL_DIR)/gc_hal_kernel_power.o \
+ $(HAL_KERNEL_DIR)/gc_hal_kernel_security_v1.o
+
+OBJS += $(ARCH_KERNEL_DIR)/gc_hal_kernel_context.o \
+ $(ARCH_KERNEL_DIR)/gc_hal_kernel_hardware.o
+
+ifeq ($(VIVANTE_ENABLE_3D), 1)
+OBJS += $(ARCH_KERNEL_DIR)/gc_hal_kernel_recorder.o
+endif
+
+ifneq ($(CONFIG_ARM64),)
+ifeq ($(CONFIG_ANDROID),)
+VIVANTE_ENABLE_VG=0
+endif
+endif
+
+ifeq ($(VIVANTE_ENABLE_VG), 1)
+OBJS +=\
+ $(HAL_KERNEL_DIR)/gc_hal_kernel_vg.o\
+ $(HAL_KERNEL_DIR)/gc_hal_kernel_command_vg.o\
+ $(HAL_KERNEL_DIR)/gc_hal_kernel_interrupt_vg.o\
+ $(HAL_KERNEL_DIR)/gc_hal_kernel_mmu_vg.o\
+ $(ARCH_VG_KERNEL_DIR)/gc_hal_kernel_hardware_command_vg.o\
+ $(ARCH_VG_KERNEL_DIR)/gc_hal_kernel_hardware_vg.o
+endif
+
+ifneq ($(CONFIG_SYNC),)
+EXTRA_CFLAGS += -Idrivers/staging/android
+EXTRA_CFLAGS += -DgcdLINUX_SYNC_FILE=1
+
+OBJS += $(OS_KERNEL_DIR)/gc_hal_kernel_sync.o
+else
+ ifneq ($(CONFIG_SYNC_FILE),)
+ EXTRA_CFLAGS += -DgcdLINUX_SYNC_FILE=1
+ OBJS += $(OS_KERNEL_DIR)/gc_hal_kernel_sync.o
+ endif
+endif
+
+ifeq ($(SECURITY), 1)
+OBJS += $(OS_KERNEL_DIR)/gc_hal_kernel_security_channel.o \
+ $(HAL_KERNEL_DIR)/gc_hal_kernel_security.o
+endif
+
+ifneq ($(CUSTOMER_ALLOCATOR_OBJS),)
+OBJS += $(CUSTOMER_ALLOCATOR_OBJS)
+endif
+
+OBJS += $(OS_KERNEL_DIR)/gc_hal_kernel_security_channel_emulator.o \
+ $(TA_DIR)/gc_hal_ta.o \
+ $(TA_DIR)/gc_hal_ta_hardware.o \
+ $(TA_DIR)/gc_hal_ta_mmu.o \
+ $(TA_DIR)/os/emulator/gc_hal_ta_emulator.o
+
+ifeq ($(KERNELRELEASE), )
+
+.PHONY: all clean install
+
+# Define targets.
+all:
+ @$(MAKE) V=$(V) ARCH=$(ARCH_TYPE) -C $(KERNEL_DIR) SUBDIRS=`pwd` modules
+
+clean:
+ @rm -rf $(OBJS)
+ @rm -rf modules.order Module.symvers .tmp_versions
+ @find $(AQROOT) -name ".gc_*.cmd" | xargs rm -f
+
+install: all
+ @mkdir -p $(SDK_DIR)/drivers
+ @cp $(MODULE_NAME).ko $(SDK_DIR)/drivers
+
+else
+
+
+EXTRA_CFLAGS += -DLINUX -DDRIVER
+
+ifeq ($(FLAREON),1)
+EXTRA_CFLAGS += -DFLAREON
+endif
+
+ifeq ($(DEBUG), 1)
+EXTRA_CFLAGS += -DDBG=1 -DDEBUG -D_DEBUG
+else
+EXTRA_CFLAGS += -DDBG=0
+endif
+
+ifeq ($(NO_DMA_COHERENT), 1)
+EXTRA_CFLAGS += -DNO_DMA_COHERENT
+endif
+
+ifeq ($(CONFIG_DOVE_GPU), 1)
+EXTRA_CFLAGS += -DCONFIG_DOVE_GPU=1
+endif
+
+ifneq ($(USE_PLATFORM_DRIVER), 0)
+EXTRA_CFLAGS += -DUSE_PLATFORM_DRIVER=1
+else
+EXTRA_CFLAGS += -DUSE_PLATFORM_DRIVER=0
+endif
+
+EXTRA_CFLAGS += -DVIVANTE_PROFILER=1
+EXTRA_CFLAGS += -DVIVANTE_PROFILER_CONTEXT=1
+
+ifeq ($(ENABLE_GPU_CLOCK_BY_DRIVER), 1)
+EXTRA_CFLAGS += -DENABLE_GPU_CLOCK_BY_DRIVER=1
+else
+EXTRA_CFLAGS += -DENABLE_GPU_CLOCK_BY_DRIVER=0
+endif
+
+ifeq ($(USE_NEW_LINUX_SIGNAL), 1)
+EXTRA_CFLAGS += -DUSE_NEW_LINUX_SIGNAL=1
+else
+EXTRA_CFLAGS += -DUSE_NEW_LINUX_SIGNAL=0
+endif
+
+ifeq ($(USE_LINUX_PCIE), 1)
+EXTRA_CFLAGS += -DUSE_LINUX_PCIE=1
+else
+EXTRA_CFLAGS += -DUSE_LINUX_PCIE=0
+endif
+
+ifeq ($(FORCE_ALL_VIDEO_MEMORY_CACHED), 1)
+EXTRA_CFLAGS += -DgcdPAGED_MEMORY_CACHEABLE=1
+else
+EXTRA_CFLAGS += -DgcdPAGED_MEMORY_CACHEABLE=0
+endif
+
+ifeq ($(CACHE_FUNCTION_UNIMPLEMENTED), 1)
+EXTRA_CFLAGS += -DgcdCACHE_FUNCTION_UNIMPLEMENTED=1
+else
+EXTRA_CFLAGS += -DgcdCACHE_FUNCTION_UNIMPLEMENTED=0
+endif
+
+ifeq ($(VIVANTE_ENABLE_3D),0)
+EXTRA_CFLAGS += -DgcdENABLE_3D=0
+else
+EXTRA_CFLAGS += -DgcdENABLE_3D=1
+endif
+
+ifeq ($(VIVANTE_ENABLE_2D),0)
+EXTRA_CFLAGS += -DgcdENABLE_2D=0
+else
+EXTRA_CFLAGS += -DgcdENABLE_2D=1
+endif
+
+ifeq ($(VIVANTE_ENABLE_VG),0)
+EXTRA_CFLAGS += -DgcdENABLE_VG=0
+else
+EXTRA_CFLAGS += -DgcdENABLE_VG=1
+endif
+
+ifeq ($(USE_BANK_ALIGNMENT), 1)
+ EXTRA_CFLAGS += -DgcdENABLE_BANK_ALIGNMENT=1
+ ifneq ($(BANK_BIT_START), 0)
+ ifneq ($(BANK_BIT_END), 0)
+ EXTRA_CFLAGS += -DgcdBANK_BIT_START=$(BANK_BIT_START)
+ EXTRA_CFLAGS += -DgcdBANK_BIT_END=$(BANK_BIT_END)
+ endif
+ endif
+
+ ifneq ($(BANK_CHANNEL_BIT), 0)
+ EXTRA_CFLAGS += -DgcdBANK_CHANNEL_BIT=$(BANK_CHANNEL_BIT)
+ endif
+endif
+
+ifeq ($(FPGA_BUILD), 1)
+EXTRA_CFLAGS += -DgcdFPGA_BUILD=1
+else
+EXTRA_CFLAGS += -DgcdFPGA_BUILD=0
+endif
+
+ifeq ($(SECURITY), 1)
+EXTRA_CFLAGS += -DgcdSECURITY=1
+endif
+
+ifneq ($(CONFIG_DRM), )
+ ifneq ($(CONFIG_ANDROID),)
+ EXTRA_CFLAGS += -DgcdENABLE_DRM=$(VIVANTE_ENABLE_DRM)
+ else
+ EXTRA_CFLAGS += -DgcdENABLE_DRM=0
+ endif
+else
+EXTRA_CFLAGS += -DgcdENABLE_DRM=0
+endif
+
+EXTRA_CFLAGS += -I$(AQROOT)/hal/kernel/inc
+EXTRA_CFLAGS += -I$(AQROOT)/hal/kernel
+EXTRA_CFLAGS += -I$(AQROOT)/hal/kernel/arch
+EXTRA_CFLAGS += -I$(AQROOT)/hal/kernel/inc
+EXTRA_CFLAGS += -I$(AQROOT)/hal/os/linux/kernel
+EXTRA_CFLAGS += -I$(AQROOT)/$(ALLOCATOR_ARRAY_H_LOCATION)
+EXTRA_CFLAGS += -I$(AQROOT)/hal/security_v1/
+
+ifneq ($(CONFIG_ARM), )
+EXTRA_CFLAGS += -Iarch/arm/mm
+endif
+
+ifeq ($(VIVANTE_ENABLE_VG), 1)
+EXTRA_CFLAGS += -I$(AQROOT)/hal/kernel/archvg
+endif
+
+EXTRA_CFLAGS += -DHOST=\"$(HOST)\"
+
+EXTRA_CFLAGS += -DgcdENABLE_TRUST_APPLICATION=1
+
+obj-$(CONFIG_MXC_GPU_VIV) = $(MODULE_NAME).o
+
+$(MODULE_NAME)-objs = $(OBJS)
+
+endif
diff --git a/drivers/mxc/gpu-viv/Kconfig b/drivers/mxc/gpu-viv/Kconfig
new file mode 100644
index 000000000000..d1fcd69b2845
--- /dev/null
+++ b/drivers/mxc/gpu-viv/Kconfig
@@ -0,0 +1,11 @@
+menu "MXC Vivante GPU support"
+ depends on SOC_IMX6 || ARCH_FSL_IMX8QM
+
+config MXC_GPU_VIV
+ tristate "MXC Vivante GPU support"
+ default y
+
+ ---help---
+ Say Y to get the GPU driver support.
+
+endmenu
diff --git a/drivers/mxc/gpu-viv/config b/drivers/mxc/gpu-viv/config
new file mode 100644
index 000000000000..1fb80a7cb2e6
--- /dev/null
+++ b/drivers/mxc/gpu-viv/config
@@ -0,0 +1,72 @@
+##############################################################################
+#
+# The MIT License (MIT)
+#
+# Copyright (c) 2014 - 2018 Vivante 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 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 GPL License (GPL)
+#
+# Copyright (C) 2014 - 2018 Vivante 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.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+##############################################################################
+#
+# Note: This software is released under dual MIT and GPL licenses. A
+# recipient may use this file under the terms of either the MIT license or
+# GPL License. If you wish to use only one license not the other, you can
+# indicate your decision by deleting one of the above license notices in your
+# version of this file.
+#
+##############################################################################
+
+
+ARCH_TYPE ?= arm
+SDK_DIR ?= $(AQROOT)/build/sdk
+VIVANTE_ENABLE_3D ?= 1
+VIVANTE_ENABLE_2D ?= 1
+VIVANTE_ENABLE_VG ?= 1
+VIVANTE_ENABLE_DRM ?= 1
+NO_DMA_COHERENT ?= 0
+USE_PLATFORM_DRIVER ?= 1
+ENABLE_GPU_CLOCK_BY_DRIVER ?= 0
+FORCE_ALL_VIDEO_MEMORY_CACHED ?= 0
+CACHE_FUNCTION_UNIMPLEMENTED ?= 0
+USE_BANK_ALIGNMENT ?= 1
+BANK_BIT_START ?= 13
+BANK_BIT_END ?= 15
+BANK_CHANNEL_BIT ?= 12
+SECURITY ?= 0
+SOC_PLATFORM ?= freescale-imx
diff --git a/drivers/mxc/gpu-viv/hal/kernel/arch/gc_hal_kernel_context.c b/drivers/mxc/gpu-viv/hal/kernel/arch/gc_hal_kernel_context.c
new file mode 100644
index 000000000000..951634248031
--- /dev/null
+++ b/drivers/mxc/gpu-viv/hal/kernel/arch/gc_hal_kernel_context.c
@@ -0,0 +1,4794 @@
+/****************************************************************************
+*
+* The MIT License (MIT)
+*
+* Copyright (c) 2014 - 2018 Vivante 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 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 GPL License (GPL)
+*
+* Copyright (C) 2014 - 2018 Vivante 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.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+*****************************************************************************
+*
+* Note: This software is released under dual MIT and GPL licenses. A
+* recipient may use this file under the terms of either the MIT license or
+* GPL License. If you wish to use only one license not the other, you can
+* indicate your decision by deleting one of the above license notices in your
+* version of this file.
+*
+*****************************************************************************/
+
+
+#include "gc_hal.h"
+#include "gc_hal_kernel.h"
+#include "gc_hal_kernel_context.h"
+#include "gc_hal_kernel_buffer.h"
+
+/******************************************************************************\
+******************************** Debugging Macro *******************************
+\******************************************************************************/
+
+/* Zone used for header/footer. */
+#define _GC_OBJ_ZONE gcvZONE_HARDWARE
+
+
+/******************************************************************************\
+************************** Context State Buffer Helpers ************************
+\******************************************************************************/
+
+#define _STATE(reg) \
+ _State(\
+ Context, index, \
+ reg ## _Address >> 2, \
+ reg ## _ResetValue, \
+ reg ## _Count, \
+ gcvFALSE, gcvFALSE \
+ )
+
+#define _STATE_COUNT(reg, count) \
+ _State(\
+ Context, index, \
+ reg ## _Address >> 2, \
+ reg ## _ResetValue, \
+ count, \
+ gcvFALSE, gcvFALSE \
+ )
+
+#define _STATE_COUNT_OFFSET(reg, offset, count) \
+ _State(\
+ Context, index, \
+ (reg ## _Address >> 2) + offset, \
+ reg ## _ResetValue, \
+ count, \
+ gcvFALSE, gcvFALSE \
+ )
+
+#define _STATE_MIRROR_COUNT(reg, mirror, count) \
+ _StateMirror(\
+ Context, \
+ reg ## _Address >> 2, \
+ count, \
+ mirror ## _Address >> 2 \
+ )
+
+#define _STATE_HINT(reg) \
+ _State(\
+ Context, index, \
+ reg ## _Address >> 2, \
+ reg ## _ResetValue, \
+ reg ## _Count, \
+ gcvFALSE, gcvTRUE \
+ )
+
+#define _STATE_HINT_BLOCK(reg, block, count) \
+ _State(\
+ Context, index, \
+ (reg ## _Address >> 2) + (block << reg ## _BLK), \
+ reg ## _ResetValue, \
+ count, \
+ gcvFALSE, gcvTRUE \
+ )
+
+#define _STATE_COUNT_OFFSET_HINT(reg, offset, count) \
+ _State(\
+ Context, index, \
+ (reg ## _Address >> 2) + offset, \
+ reg ## _ResetValue, \
+ count, \
+ gcvFALSE, gcvTRUE \
+ )
+
+#define _STATE_X(reg) \
+ _State(\
+ Context, index, \
+ reg ## _Address >> 2, \
+ reg ## _ResetValue, \
+ reg ## _Count, \
+ gcvTRUE, gcvFALSE \
+ )
+
+#define _STATE_INIT_VALUE(reg, value) \
+ _State(\
+ Context, index, \
+ reg ## _Address >> 2, \
+ value, \
+ reg ## _Count, \
+ gcvFALSE, gcvFALSE \
+ )
+
+#define _CLOSE_RANGE() \
+ _TerminateStateBlock(Context, index)
+
+#define _ENABLE(reg, field) \
+ do \
+ { \
+ if (gcmVERIFYFIELDVALUE(data, reg, MASK_ ## field, ENABLED)) \
+ { \
+ enable |= gcmFIELDMASK(reg, field); \
+ } \
+ } \
+ while (gcvFALSE)
+
+#define _BLOCK_COUNT(reg) \
+ ((reg ## _Count) >> (reg ## _BLK))
+
+
+/******************************************************************************\
+*********************** Support Functions and Definitions **********************
+\******************************************************************************/
+
+#define gcdSTATE_MASK \
+ (gcmSETFIELDVALUE(0, AQ_COMMAND_NOP_COMMAND, OPCODE, NOP) | 0xC0FFEE)
+
+#if gcdENABLE_3D
+static gctUINT32
+_TerminateStateBlock(
+ IN gckCONTEXT Context,
+ IN gctUINT32 Index
+ )
+{
+ gctUINT32_PTR buffer;
+ gctUINT32 align;
+
+ /* Determine if we need alignment. */
+ align = (Index & 1) ? 1 : 0;
+
+ /* Address correct index. */
+ buffer = (Context->buffer == gcvNULL)
+ ? gcvNULL
+ : Context->buffer->logical;
+
+ /* Flush the current state block; make sure no pairing with the states
+ to follow happens. */
+ if (align && (buffer != gcvNULL))
+ {
+ buffer[Index] = 0xDEADDEAD;
+ }
+
+ /* Reset last address. */
+ Context->lastAddress = ~0U;
+
+ /* Return alignment requirement. */
+ return align;
+}
+#endif
+
+
+#if gcdENABLE_3D
+static gctUINT32
+_FlushPipe(
+ IN gckCONTEXT Context,
+ IN gctUINT32 Index,
+ IN gcePIPE_SELECT Pipe
+ )
+{
+ gctUINT32 flushSlots;
+ gctBOOL txCacheFix;
+ gctBOOL fcFlushStall;
+ gctBOOL iCacheInvalidate;
+ gctBOOL halti5;
+ gctBOOL snapPages;
+ gctBOOL hwTFB;
+ gctBOOL blt;
+ gctBOOL peTSFlush;
+
+ txCacheFix
+ = gckHARDWARE_IsFeatureAvailable(Context->hardware, gcvFEATURE_TEX_CACHE_FLUSH_FIX);
+
+ fcFlushStall
+ = gckHARDWARE_IsFeatureAvailable(Context->hardware, gcvFEATURE_FC_FLUSH_STALL);
+
+ iCacheInvalidate
+ = gckHARDWARE_IsFeatureAvailable(Context->hardware, gcvFEATURE_SHADER_HAS_INSTRUCTION_CACHE);
+
+ halti5
+ = gckHARDWARE_IsFeatureAvailable(Context->hardware, gcvFEATURE_HALTI5);
+
+ snapPages
+ = gckHARDWARE_IsFeatureAvailable(Context->hardware, gcvFEATURE_SNAPPAGE_CMD_FIX) &&
+ gckHARDWARE_IsFeatureAvailable(Context->hardware, gcvFEATURE_SNAPPAGE_CMD);
+
+
+ hwTFB
+ = gckHARDWARE_IsFeatureAvailable(Context->hardware, gcvFEATURE_HW_TFB);
+
+ blt
+ = gckHARDWARE_IsFeatureAvailable(Context->hardware, gcvFEATURE_BLT_ENGINE);
+
+ peTSFlush
+ = gckHARDWARE_IsFeatureAvailable(Context->hardware, gcvFEATURE_PE_TILE_CACHE_FLUSH_FIX);
+
+ flushSlots = blt ? 10 : 6;
+
+ if (Pipe == gcvPIPE_3D)
+ {
+ if (!txCacheFix)
+ {
+ /* Semaphore stall */
+ flushSlots += blt ? 8 : 4;
+ }
+
+ /* VST cache */
+ flushSlots += 2;
+ }
+
+ if (fcFlushStall)
+ {
+ /* Flush tile status cache. */
+ flushSlots += blt ? ((!peTSFlush) ? 14 :10) : 6;
+ }
+
+ if (iCacheInvalidate && !halti5)
+ {
+ flushSlots += blt ? 16 : 12;
+ }
+
+ if (hwTFB)
+ {
+ flushSlots += 2;
+ }
+
+ /* Snap pages */
+ if (snapPages)
+ {
+ flushSlots += 2;
+ }
+
+ if (Context->buffer != gcvNULL)
+ {
+ gctUINT32_PTR buffer;
+
+ /* Address correct index. */
+ buffer = Context->buffer->logical + Index;
+
+ if (Pipe == gcvPIPE_3D && !txCacheFix)
+ {
+ if (blt)
+ {
+ /* Semaphore from FE to BLT. */
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x502E) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1))))))) << (0 ?
+ 0:0))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)));
+
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E02) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1))))))) << (0 ?
+ 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1))))))) << (0 ?
+ 12:8))) | (((gctUINT32) (0x10 & ((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
+
+ /* Stall from FE to BLT. */
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x09 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)));
+
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1))))))) << (0 ?
+ 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1))))))) << (0 ?
+ 12:8))) | (((gctUINT32) (0x10 & ((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
+
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x502E) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1))))))) << (0 ?
+ 0:0))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)));
+ }
+ else
+ {
+ /* Semaphore from FE to PE. */
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E02) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1))))))) << (0 ?
+ 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1))))))) << (0 ?
+ 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
+
+ /* Stall from FE to PE. */
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x09 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)));
+
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1))))))) << (0 ?
+ 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1))))))) << (0 ?
+ 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
+ }
+ }
+
+ /* Flush the current pipe. */
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E03) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+
+ *buffer++
+ = (Pipe == gcvPIPE_2D)
+ ?
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 3:3) - (0 ?
+ 3:3) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 3:3) - (0 ?
+ 3:3) + 1))))))) << (0 ?
+ 3:3))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 3:3) - (0 ?
+ 3:3) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 3:3) - (0 ? 3:3) + 1))))))) << (0 ? 3:3)))
+ : ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1))))))) << (0 ?
+ 0:0))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 1:1) - (0 ?
+ 1:1) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 1:1) - (0 ?
+ 1:1) + 1))))))) << (0 ?
+ 1:1))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 1:1) - (0 ?
+ 1:1) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 2:2) - (0 ?
+ 2:2) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 2:2) - (0 ?
+ 2:2) + 1))))))) << (0 ?
+ 2:2))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 2:2) - (0 ?
+ 2:2) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 2:2) - (0 ? 2:2) + 1))))))) << (0 ? 2:2)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 5:5) - (0 ?
+ 5:5) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 5:5) - (0 ?
+ 5:5) + 1))))))) << (0 ?
+ 5:5))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 5:5) - (0 ?
+ 5:5) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 5:5) - (0 ? 5:5) + 1))))))) << (0 ? 5:5)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 10:10) - (0 ?
+ 10:10) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 10:10) - (0 ?
+ 10:10) + 1))))))) << (0 ?
+ 10:10))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 10:10) - (0 ?
+ 10:10) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 10:10) - (0 ? 10:10) + 1))))))) << (0 ? 10:10)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 11:11) - (0 ?
+ 11:11) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 11:11) - (0 ?
+ 11:11) + 1))))))) << (0 ?
+ 11:11))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 11:11) - (0 ?
+ 11:11) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 11:11) - (0 ? 11:11) + 1))))))) << (0 ? 11:11)));
+
+ if (hwTFB)
+ {
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x7003) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
+
+ *buffer++
+ = 0x12345678;
+ }
+
+ /* Flush VST in separate cmd. */
+ if (Pipe == gcvPIPE_3D)
+ {
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E03) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+
+ *buffer++ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 4:4) - (0 ?
+ 4:4) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 4:4) - (0 ?
+ 4:4) + 1))))))) << (0 ?
+ 4:4))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 4:4) - (0 ?
+ 4:4) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 4:4) - (0 ? 4:4) + 1))))))) << (0 ? 4:4)));
+ }
+
+ /* Semaphore from FE to PE. */
+ if (blt)
+ {
+ /* Semaphore from FE to BLT. */
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x502E) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1))))))) << (0 ?
+ 0:0))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)));
+
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E02) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1))))))) << (0 ?
+ 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1))))))) << (0 ?
+ 12:8))) | (((gctUINT32) (0x10 & ((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
+
+ /* Stall from FE to BLT. */
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x09 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)));
+
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1))))))) << (0 ?
+ 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1))))))) << (0 ?
+ 12:8))) | (((gctUINT32) (0x10 & ((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
+
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x502E) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1))))))) << (0 ?
+ 0:0))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)));
+ }
+ else
+ {
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E02) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1))))))) << (0 ?
+ 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1))))))) << (0 ?
+ 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
+
+ /* Stall from FE to PE. */
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x09 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)));
+
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1))))))) << (0 ?
+ 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1))))))) << (0 ?
+ 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
+ }
+
+ if (fcFlushStall)
+ {
+ if (!peTSFlush && blt)
+ {
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x502E) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1))))))) << (0 ?
+ 0:0))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)));
+
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x502B) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
+
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1))))))) << (0 ?
+ 0:0))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)));
+
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x502E) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1))))))) << (0 ?
+ 0:0))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)));
+ }
+ else
+ {
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x0594) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
+
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1))))))) << (0 ?
+ 0:0))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)));
+ }
+
+ /* Semaphore from FE to PE. */
+ if (blt)
+ {
+ /* Semaphore from FE to BLT. */
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x502E) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1))))))) << (0 ?
+ 0:0))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)));
+
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E02) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1))))))) << (0 ?
+ 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1))))))) << (0 ?
+ 12:8))) | (((gctUINT32) (0x10 & ((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
+
+ /* Stall from FE to BLT. */
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x09 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)));
+
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1))))))) << (0 ?
+ 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1))))))) << (0 ?
+ 12:8))) | (((gctUINT32) (0x10 & ((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
+
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x502E) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1))))))) << (0 ?
+ 0:0))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)));
+ }
+ else
+ {
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E02) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1))))))) << (0 ?
+ 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1))))))) << (0 ?
+ 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
+
+ /* Stall from FE to PE. */
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x09 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)));
+
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1))))))) << (0 ?
+ 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1))))))) << (0 ?
+ 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
+ }
+ }
+
+ if (iCacheInvalidate && !halti5)
+ {
+ /* Invalidate I$ after pipe is stalled */
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x0218) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1))))))) << (0 ?
+ 0:0))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)));
+
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x021A) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1))))))) << (0 ?
+ 0:0))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 4:4) - (0 ?
+ 4:4) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 4:4) - (0 ?
+ 4:4) + 1))))))) << (0 ?
+ 4:4))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 4:4) - (0 ?
+ 4:4) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 4:4) - (0 ? 4:4) + 1))))))) << (0 ? 4:4)));
+
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x0218) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1))))))) << (0 ?
+ 0:0))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)));
+
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x021A) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1))))))) << (0 ?
+ 0:0))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 5:5) - (0 ?
+ 5:5) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 5:5) - (0 ?
+ 5:5) + 1))))))) << (0 ?
+ 5:5))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 5:5) - (0 ?
+ 5:5) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 5:5) - (0 ? 5:5) + 1))))))) << (0 ? 5:5)));
+
+ /* Semaphore from FE to PE. */
+ if (blt)
+ {
+ /* Semaphore from FE to BLT. */
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x502E) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1))))))) << (0 ?
+ 0:0))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)));
+
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E02) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1))))))) << (0 ?
+ 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1))))))) << (0 ?
+ 12:8))) | (((gctUINT32) (0x10 & ((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
+
+ /* Stall from FE to BLT. */
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x09 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)));
+
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1))))))) << (0 ?
+ 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1))))))) << (0 ?
+ 12:8))) | (((gctUINT32) (0x10 & ((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
+
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x502E) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1))))))) << (0 ?
+ 0:0))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)));
+ }
+ else
+ {
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E02) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1))))))) << (0 ?
+ 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1))))))) << (0 ?
+ 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
+
+ /* Stall from FE to PE. */
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x09 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)));
+
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1))))))) << (0 ?
+ 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1))))))) << (0 ?
+ 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
+ }
+ }
+
+ if (snapPages)
+ {
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x13 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1))))))) << (0 ?
+ 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1))))))) << (0 ?
+ 4:0))) | (((gctUINT32) (0x02 & ((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1))))))) << (0 ?
+ 4:0))) | (((gctUINT32) (0x04 & ((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1))))))) << (0 ?
+ 4:0))) | (((gctUINT32) (0x08 & ((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1))))))) << (0 ?
+ 4:0))) | (((gctUINT32) (0x10 & ((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)));
+
+ *buffer++
+ = 0;
+ }
+ }
+
+ /* Number of slots taken by flushing pipe. */
+ return flushSlots;
+}
+#endif
+
+#if gcdENABLE_3D
+static gctUINT32
+_SemaphoreStall(
+ IN gckCONTEXT Context,
+ IN gctUINT32 Index
+ )
+{
+ gctBOOL blt = gckHARDWARE_IsFeatureAvailable(Context->hardware, gcvFEATURE_BLT_ENGINE);
+ if (Context->buffer != gcvNULL)
+ {
+ gctUINT32_PTR buffer;
+
+ /* Address correct index. */
+ buffer = Context->buffer->logical + Index;
+
+ if (blt)
+ {
+ /* Semaphore from FE to BLT. */
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x502E) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1))))))) << (0 ?
+ 0:0))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)));
+
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E02) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1))))))) << (0 ?
+ 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1))))))) << (0 ?
+ 12:8))) | (((gctUINT32) (0x10 & ((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
+
+ /* Stall from FE to BLT. */
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x09 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)));
+
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1))))))) << (0 ?
+ 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1))))))) << (0 ?
+ 12:8))) | (((gctUINT32) (0x10 & ((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
+
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x502E) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+
+ *buffer
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1))))))) << (0 ?
+ 0:0))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)));
+ }
+ else
+ {
+ /* Semaphore from FE to PE. */
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E02) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1))))))) << (0 ?
+ 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1))))))) << (0 ?
+ 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
+
+ /* Stall from FE to PE. */
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x09 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)));
+
+ *buffer
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1))))))) << (0 ?
+ 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1))))))) << (0 ?
+ 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
+ }
+ }
+
+ /* Semaphore/stall takes 4 slots. */
+ return (blt ? 8 : 4);
+}
+#endif
+
+#if (gcdENABLE_3D || gcdENABLE_2D)
+static gctUINT32
+_SwitchPipe(
+ IN gckCONTEXT Context,
+ IN gctUINT32 Index,
+ IN gcePIPE_SELECT Pipe
+ )
+{
+ gctUINT32 slots = 2;
+
+ if (Context->buffer != gcvNULL)
+ {
+ gctUINT32_PTR buffer;
+
+ /* Address correct index. */
+ buffer = Context->buffer->logical + Index;
+
+ /* LoadState(AQPipeSelect, 1), pipe. */
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E00) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
+
+ *buffer
+ = (Pipe == gcvPIPE_2D)
+ ? 0x1
+ : 0x0;
+ }
+
+ Context->pipeSelectBytes = slots * gcmSIZEOF(gctUINT32);
+
+ return slots;
+}
+#endif
+
+#if gcdENABLE_3D
+static gctUINT32
+_State(
+ IN gckCONTEXT Context,
+ IN gctUINT32 Index,
+ IN gctUINT32 Address,
+ IN gctUINT32 Value,
+ IN gctUINT32 Size,
+ IN gctBOOL FixedPoint,
+ IN gctBOOL Hinted
+ )
+{
+ gctUINT32_PTR buffer;
+ gctUINT32 align;
+ gctUINT32 i;
+
+ /* Determine if we need alignment. */
+ align = (Index & 1) ? 1 : 0;
+
+ /* Address correct index. */
+ buffer = (Context->buffer == gcvNULL)
+ ? gcvNULL
+ : Context->buffer->logical;
+
+ if ((buffer == gcvNULL) && (Address + Size > Context->maxState))
+ {
+ /* Determine maximum state. */
+ Context->maxState = Address + Size;
+ }
+
+ if (buffer == gcvNULL)
+ {
+ /* Update number of states. */
+ Context->numStates += Size;
+ }
+
+ /* Do we need a new entry? */
+ if ((Address != Context->lastAddress) || (FixedPoint != Context->lastFixed))
+ {
+ if (buffer != gcvNULL)
+ {
+ if (align)
+ {
+ /* Add filler. */
+ buffer[Index++] = 0xDEADDEAD;
+ }
+
+ /* LoadState(Address, Count). */
+ gcmkASSERT((Index & 1) == 0);
+
+ if (FixedPoint)
+ {
+ buffer[Index]
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 26:26) - (0 ?
+ 26:26) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 26:26) - (0 ?
+ 26:26) + 1))))))) << (0 ?
+ 26:26))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 26:26) - (0 ?
+ 26:26) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 26:26) - (0 ? 26:26) + 1))))))) << (0 ? 26:26)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (Size) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (Address) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+ }
+ else
+ {
+ buffer[Index]
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 26:26) - (0 ?
+ 26:26) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 26:26) - (0 ?
+ 26:26) + 1))))))) << (0 ?
+ 26:26))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ?
+ 26:26) - (0 ?
+ 26:26) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 26:26) - (0 ? 26:26) + 1))))))) << (0 ? 26:26)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (Size) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (Address) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+ }
+
+ /* Walk all the states. */
+ for (i = 0; i < (gctUINT32)Size; i += 1)
+ {
+ /* Set state to uninitialized value. */
+ buffer[Index + 1 + i] = Value;
+
+ /* Set index in state mapping table. */
+ Context->map[Address + i].index = (gctUINT)Index + 1 + i;
+
+#if gcdSECURE_USER
+ /* Save hint. */
+ if (Context->hint != gcvNULL)
+ {
+ Context->hint[Address + i] = Hinted;
+ }
+#endif
+ }
+ }
+
+ /* Save information for this LoadState. */
+ Context->lastIndex = (gctUINT)Index;
+ Context->lastAddress = Address + (gctUINT32)Size;
+ Context->lastSize = Size;
+ Context->lastFixed = FixedPoint;
+
+ /* Return size for load state. */
+ return align + 1 + Size;
+ }
+
+ /* Append this state to the previous one. */
+ if (buffer != gcvNULL)
+ {
+ /* Update last load state. */
+ buffer[Context->lastIndex] =
+ ((((gctUINT32) (buffer[Context->lastIndex])) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (Context->lastSize + Size) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
+
+ /* Walk all the states. */
+ for (i = 0; i < (gctUINT32)Size; i += 1)
+ {
+ /* Set state to uninitialized value. */
+ buffer[Index + i] = Value;
+
+ /* Set index in state mapping table. */
+ Context->map[Address + i].index = (gctUINT)Index + i;
+
+#if gcdSECURE_USER
+ /* Save hint. */
+ if (Context->hint != gcvNULL)
+ {
+ Context->hint[Address + i] = Hinted;
+ }
+#endif
+ }
+ }
+
+ /* Update last address and size. */
+ Context->lastAddress += (gctUINT32)Size;
+ Context->lastSize += Size;
+
+ /* Return number of slots required. */
+ return Size;
+}
+
+static gctUINT32
+_StateMirror(
+ IN gckCONTEXT Context,
+ IN gctUINT32 Address,
+ IN gctUINT32 Size,
+ IN gctUINT32 AddressMirror
+ )
+{
+ gctUINT32 i;
+
+ /* Process when buffer is set. */
+ if (Context->buffer != gcvNULL)
+ {
+ /* Walk all states. */
+ for (i = 0; i < Size; i++)
+ {
+ /* Copy the mapping address. */
+ Context->map[Address + i].index =
+ Context->map[AddressMirror + i].index;
+
+#if gcdSECURE_USER
+ Context->hint[Address + i] =
+ Context->hint[AddressMirror + i];
+#endif
+ }
+ }
+
+ /* Return the number of required maps. */
+ return Size;
+}
+#endif
+
+#if (gcdENABLE_3D || gcdENABLE_2D)
+static gceSTATUS
+_InitializeContextBuffer(
+ IN gckCONTEXT Context
+ )
+{
+ gctUINT32_PTR buffer;
+ gctUINT32 index;
+
+#if gcdENABLE_3D
+ gctBOOL halti0, halti1, halti2, halti3, halti4, halti5;
+ gctUINT i;
+ gctUINT vertexUniforms, fragmentUniforms, vsConstBase, psConstBase, constMax;
+ gctBOOL unifiedUniform;
+ gctBOOL hasGS, hasTS;
+ gctBOOL genericAttrib;
+ gctBOOL hasICache;
+ gctBOOL hasICachePrefetch;
+ gctUINT numRT = 0;
+ gctUINT numSamplers = 32;
+ gctBOOL hasTXdesc;
+ gctBOOL hasSecurity;
+ gctBOOL hasRobustness;
+ gctBOOL multiCoreBlockSetCfg2;
+#endif
+
+ gckHARDWARE hardware;
+
+ gcmkHEADER();
+
+ hardware = Context->hardware;
+
+ gcmkVERIFY_OBJECT(hardware, gcvOBJ_HARDWARE);
+
+ /* Reset the buffer index. */
+ index = 0;
+
+ /* Reset the last state address. */
+ Context->lastAddress = ~0U;
+
+ /* Get the buffer pointer. */
+ buffer = (Context->buffer == gcvNULL)
+ ? gcvNULL
+ : Context->buffer->logical;
+
+
+ /**************************************************************************/
+ /* Build 2D states. *******************************************************/
+
+
+#if gcdENABLE_3D
+ /**************************************************************************/
+ /* Build 3D states. *******************************************************/
+
+ halti0 = gckHARDWARE_IsFeatureAvailable(hardware, gcvFEATURE_HALTI0);
+ halti1 = gckHARDWARE_IsFeatureAvailable(hardware, gcvFEATURE_HALTI1);
+ halti2 = gckHARDWARE_IsFeatureAvailable(hardware, gcvFEATURE_HALTI2);
+ halti3 = gckHARDWARE_IsFeatureAvailable(hardware, gcvFEATURE_HALTI3);
+ halti4 = gckHARDWARE_IsFeatureAvailable(hardware, gcvFEATURE_HALTI4);
+ halti5 = gckHARDWARE_IsFeatureAvailable(hardware, gcvFEATURE_HALTI5);
+ hasGS = gckHARDWARE_IsFeatureAvailable(hardware, gcvFEATURE_GEOMETRY_SHADER);
+ hasTS = gckHARDWARE_IsFeatureAvailable(hardware, gcvFEATURE_TESSELLATION);
+ genericAttrib = gckHARDWARE_IsFeatureAvailable(hardware, gcvFEATURE_GENERIC_ATTRIB);
+ hasICache = gckHARDWARE_IsFeatureAvailable(hardware, gcvFEATURE_SHADER_HAS_INSTRUCTION_CACHE);
+ hasTXdesc = gckHARDWARE_IsFeatureAvailable(hardware, gcvFEATURE_TX_DESCRIPTOR);
+ hasSecurity = gckHARDWARE_IsFeatureAvailable(hardware, gcvFEATURE_SECURITY);
+ hasRobustness = gckHARDWARE_IsFeatureAvailable(hardware, gcvFEATURE_ROBUSTNESS);
+ hasICachePrefetch = gckHARDWARE_IsFeatureAvailable(hardware, gcvFEATURE_SH_INSTRUCTION_PREFETCH);
+ multiCoreBlockSetCfg2 = gckHARDWARE_IsFeatureAvailable(hardware, gcvFEATURE_MULTI_CORE_BLOCK_SET_CONFIG2);
+
+ /* Multi render target. */
+ if (halti2 ||
+ (Context->hardware->identity.chipModel == gcv900 && Context->hardware->identity.chipRevision == 0x5250)
+ )
+ {
+ numRT = 8;
+ }
+ else if (halti0)
+ {
+ numRT = 4;
+ }
+ else
+ {
+ numRT = 1;
+ }
+
+ if (hasGS && hasTS)
+ {
+ numSamplers = 80;
+ }
+
+ /* Query how many uniforms can support. */
+ {if (Context->hardware->identity.numConstants > 256){ unifiedUniform = gcvTRUE;
+if (halti5){ vsConstBase = 0xD000;
+ psConstBase = 0xD800;
+}else{ vsConstBase = 0xC000;
+ psConstBase = 0xC000;
+}if ((Context->hardware->identity.chipModel == gcv880) && ((Context->hardware->identity.chipRevision & 0xfff0) == 0x5120)){ vertexUniforms = 512;
+ fragmentUniforms = 64;
+ constMax = 576;
+}else{ vertexUniforms = gcmMIN(512, Context->hardware->identity.numConstants - 64);
+ fragmentUniforms = gcmMIN(512, Context->hardware->identity.numConstants - 64);
+ constMax = Context->hardware->identity.numConstants;
+}}else if (Context->hardware->identity.numConstants == 256){ if (Context->hardware->identity.chipModel == gcv2000 && (Context->hardware->identity.chipRevision == 0x5118 || Context->hardware->identity.chipRevision == 0x5140)) { unifiedUniform = gcvFALSE;
+ vsConstBase = 0x1400;
+ psConstBase = 0x1C00;
+ vertexUniforms = 256;
+ fragmentUniforms = 64;
+ constMax = 320;
+ } else { unifiedUniform = gcvFALSE;
+ vsConstBase = 0x1400;
+ psConstBase = 0x1C00;
+ vertexUniforms = 256;
+ fragmentUniforms = 256;
+ constMax = 512;
+ }}else{ unifiedUniform = gcvFALSE;
+ vsConstBase = 0x1400;
+ psConstBase = 0x1C00;
+ vertexUniforms = 168;
+ fragmentUniforms = 64;
+ constMax = 232;
+}};
+
+
+#if !gcdENABLE_UNIFIED_CONSTANT
+ if (Context->hardware->identity.numConstants > 256)
+ {
+ unifiedUniform = gcvTRUE;
+ }
+ else
+ {
+ unifiedUniform = gcvFALSE;
+ }
+#endif
+
+ /* Store the 3D entry index. */
+ Context->entryOffset3D = (gctUINT)index * gcmSIZEOF(gctUINT32);
+
+ /* Switch to 3D pipe. */
+ index += _SwitchPipe(Context, index, gcvPIPE_3D);
+
+ /* Current context pointer. */
+#if gcdDEBUG
+ index += _State(Context, index, 0x03850 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+#endif
+
+ index += _FlushPipe(Context, index, gcvPIPE_3D);
+
+ /* Global states. */
+ if (hasSecurity)
+ {
+ index += _State(Context, index, 0x03900 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _CLOSE_RANGE();
+ index += _State(Context, index, 0x03904 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ }
+
+ index += _State(Context, index, 0x03814 >> 2, 0x00000001, 1, gcvFALSE, gcvFALSE);
+ index += _CLOSE_RANGE();
+ index += _State(Context, index, 0x03818 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x0381C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+
+ if (halti5)
+ {
+ index += _State(Context, index, 0x03888 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x038C0 >> 2, 0x00000000, 16, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x03884 >> 2, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 2:0) - (0 ?
+ 2:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 2:0) - (0 ?
+ 2:0) + 1))))))) << (0 ?
+ 2:0))) | (((gctUINT32) ((gctUINT32) (hardware->options.uscL1CacheRatio) & ((gctUINT32) ((((1 ?
+ 2:0) - (0 ?
+ 2:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 2:0) - (0 ?
+ 2:0) + 1))))))) << (0 ?
+ 2:0))) | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 20:16) - (0 ?
+ 20:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 20:16) - (0 ?
+ 20:16) + 1))))))) << (0 ?
+ 20:16))) | (((gctUINT32) ((gctUINT32) (2) & ((gctUINT32) ((((1 ?
+ 20:16) - (0 ?
+ 20:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 20:16) - (0 ? 20:16) + 1))))))) << (0 ? 20:16))), 1, gcvFALSE, gcvFALSE);
+ }
+ else
+ {
+ index += _State(Context, index, 0x03820 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x03828 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x0382C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x03834 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x03838 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x03854 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ }
+
+ if (hasGS)
+ {
+ index += _State(Context, index, 0x0388C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ }
+
+ index += _State(Context, index, 0x0384C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+
+ /* Front End states. */
+ if (halti5)
+ {
+ index += _State(Context, index, 0x17800 >> 2, 0x00000000, 32, gcvFALSE, gcvFALSE);
+ index += _CLOSE_RANGE();
+ index += _State(Context, index, 0x007C4 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x17880 >> 2, 0x00000000, 32, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x17900 >> 2, 0x00000000, 32, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x17980 >> 2, 0x00000000, 32, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x17A00 >> 2, 0x3F800000, 32, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x007D0 >> 2, 0x00000000, 2, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x007D8 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x17A80 >> 2, 0x00000000, 32, gcvFALSE, gcvFALSE);
+ }
+ else
+ {
+ index += _State(Context, index, 0x00600 >> 2, 0x00000000, (halti0 ? 16 : 12), gcvFALSE, gcvFALSE);
+ index += _CLOSE_RANGE();
+ if (genericAttrib)
+ {
+ index += _State(Context, index, 0x006C0 >> 2, 0x00000000, 16, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x00700 >> 2, 0x00000000, 16, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x00740 >> 2, 0x00000000, 16, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x00780 >> 2, 0x3F800000, 16, gcvFALSE, gcvFALSE);
+ }
+ }
+
+ if (halti2 || (Context->hardware->identity.streamCount > 8))
+ {
+ index += _State(Context, index, 0x14600 >> 2, 0x00000000, 16, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x14640 >> 2, 0x00000000, 16, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x14680 >> 2, 0x00000000, 16, gcvFALSE, gcvFALSE);
+ }
+ else if (Context->hardware->identity.streamCount > 1)
+ {
+ index += _State(Context, index, 0x00680 >> 2, 0x00000000, 8, gcvFALSE, gcvTRUE);
+ index += _State(Context, index, 0x006A0 >> 2, 0x00000000, 8, gcvFALSE, gcvFALSE);
+ }
+ else
+ {
+ index += _State(Context, index, 0x0064C >> 2, 0x00000000, 1, gcvFALSE, gcvTRUE);
+ index += _State(Context, index, 0x00650 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+
+ }
+ index += _State(Context, index, 0x00644 >> 2, 0x00000000, 1, gcvFALSE, gcvTRUE);
+ index += _State(Context, index, 0x00648 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x00674 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x00678 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x0067C >> 2, 0xFFFFFFFF, 1, gcvFALSE, gcvFALSE);
+ index += _CLOSE_RANGE();
+
+ if (hasRobustness)
+ {
+ index += _State(Context, index, 0x146C0 >> 2, 0x00000000, 16, gcvFALSE, gcvTRUE);
+ index += _CLOSE_RANGE();
+ index += _State(Context, index, 0x007F8 >> 2, 0x00000000, 1, gcvFALSE, gcvTRUE);
+ index += _CLOSE_RANGE();
+ }
+
+ if (halti5)
+ {
+ index += _State(Context, index, 0x008B8 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x15600 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ }
+ else
+ {
+ /* This register is programed by all chips, which program all DECODE_SELECT as VS
+ ** except SAMPLER_DECODE_SELECT.
+ */
+ index += _State(Context, index, 0x00860 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ }
+
+ if (hasICache)
+ {
+ /* I-Cache states. */
+ index += _State(Context, index, 0x00868 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x0086C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x0304C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x01028 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _CLOSE_RANGE();
+
+ if (hasICachePrefetch)
+ {
+ if (halti5)
+ {
+ index += _State(Context, index, 0x15604 >> 2, 0x00000000, 1, gcvFALSE, gcvTRUE);
+ index += _State(Context, index, 0x01094 >> 2, 0x00000000, 1, gcvFALSE, gcvTRUE);
+ }
+ else
+ {
+ index += _State(Context, index, 0x00890 >> 2, 0x00000000, 1, gcvFALSE, gcvTRUE);
+ index += _State(Context, index, 0x0104C >> 2, 0x00000000, 1, gcvFALSE, gcvTRUE);
+ }
+ index += _CLOSE_RANGE();
+ }
+ }
+
+ /* Vertex Shader states. */
+ index += _State(Context, index, 0x00804 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x00808 >> 2, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 5:0) - (0 ?
+ 5:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 5:0) - (0 ?
+ 5:0) + 1))))))) << (0 ?
+ 5:0))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 5:0) - (0 ?
+ 5:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 5:0) - (0 ? 5:0) + 1))))))) << (0 ? 5:0))), 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x0080C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x00830 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+
+ if (halti5)
+ {
+ index += _State(Context, index, 0x00898 >> 2, 0x00000000, 2, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x008A0 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x00870 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x008A8 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x008C0 >> 2, 0x00000000, 8, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x008E0 >> 2, 0x00000000, 8, gcvFALSE, gcvFALSE);
+ }
+ else
+ {
+ index += _State(Context, index, 0x00810 >> 2, 0x00000000, 4, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x00820 >> 2, 0x00000000, 4, gcvFALSE, gcvFALSE);
+ }
+
+ index += _CLOSE_RANGE();
+
+ /* GS */
+ if (hasGS)
+ {
+ index += _State(Context, index, 0x01100 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x01104 >> 2, 0x00000001, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x01108 >> 2, 0x01000001, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x0110C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x01110 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x01114 >> 2, 0x00000000, 1, gcvFALSE, gcvTRUE);
+ index += _State(Context, index, 0x0111C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x01140 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x01144 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x01148 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x0114C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x01154 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x01120 >> 2, 0x00000000, 8, gcvFALSE, gcvFALSE);
+ index += _CLOSE_RANGE();
+ }
+
+ /* TCS & TES */
+
+ if (hasTS)
+ {
+ index += _State(Context, index, 0x007C0 >> 2, 0x00000003, 1, gcvFALSE, gcvFALSE);
+
+ index += _State(Context, index, 0x14A14 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x14A18 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x14A1C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x14A40 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x14A00 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x14A04 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x14A08 >> 2, 0x00000000, 1, gcvFALSE, gcvTRUE);
+ index += _State(Context, index, 0x14A10 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x14A20 >> 2, 0x00000000, 8, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x14A44 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x14A4C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+
+ index += _CLOSE_RANGE();
+
+ index += _State(Context, index, 0x14B18 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x14B1C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x14B20 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x14B04 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x14B08 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x14B0C >> 2, 0x00000000, 1, gcvFALSE, gcvTRUE);
+ index += _State(Context, index, 0x14B14 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x14B40 >> 2, 0x00000000, 8, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x14B24 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x14B2C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x14B34 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+
+ index += _State(Context, index, 0x14B00 >> 2, 0x00040000, 1, gcvFALSE, gcvFALSE);
+
+ }
+
+ index += _CLOSE_RANGE();
+
+ /* TFB */
+ if (gckHARDWARE_IsFeatureAvailable(Context->hardware, gcvFEATURE_HW_TFB))
+ {
+ index += _State(Context, index, 0x1C000 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x1C008 >> 2, 0x00000000, 1, gcvFALSE, gcvTRUE);
+ index += _State(Context, index, (0x1C040 >> 2) + (0 << 4), 0x00000000, 4, gcvFALSE, gcvTRUE);
+ index += _State(Context, index, 0x1C080 >> 2, 0x00000000, 4, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x1C0C0 >> 2, 0x00000000, 4, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x1C100 >> 2, 0x00000000, 4, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x1C800 >> 2, 0x00000000, 128*4, gcvFALSE, gcvFALSE);
+
+ index += _State(Context, index, 0x1C014 >> 2, 0x00000000, 1, gcvFALSE, gcvTRUE);
+ index += _CLOSE_RANGE();
+
+ }
+
+ /* Primitive Assembly states. */
+ index += _State(Context, index, 0x00A00 >> 2, 0x00000000, 1, gcvTRUE, gcvFALSE);
+ index += _State(Context, index, 0x00A04 >> 2, 0x00000000, 1, gcvTRUE, gcvFALSE);
+ index += _State(Context, index, 0x00A08 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x00A0C >> 2, 0x00000000, 1, gcvTRUE, gcvFALSE);
+ index += _State(Context, index, 0x00A10 >> 2, 0x00000000, 1, gcvTRUE, gcvFALSE);
+ index += _State(Context, index, 0x00A14 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x00A18 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x00A1C >> 2, 0x3F000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x00A28 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x00A2C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x00A30 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x00A34 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x00A38 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x00A3C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x00A80 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x00A84 >> 2, 0x00000000, 1, gcvTRUE, gcvFALSE);
+ index += _State(Context, index, 0x00A8C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x00A88 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+
+ if (halti5)
+ {
+ index += _State(Context, index, 0x00AA8 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x00A90 >> 2, 0x00000000, 4, gcvFALSE, gcvFALSE);
+ }
+ else
+ {
+ index += _State(Context, index, 0x00A40 >> 2, 0x00000000, Context->hardware->identity.varyingsCount, gcvFALSE, gcvFALSE);
+ }
+
+ index += _State(Context, index, 0x03A00 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x03A04 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x03A08 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+
+ if (multiCoreBlockSetCfg2)
+ {
+ index += _State(Context, index, 0x03A0C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x03A10 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ }
+
+ /* Setup states. */
+ index += _State(Context, index, 0x00C00 >> 2, 0x00000000, 1, gcvTRUE, gcvFALSE);
+ index += _State(Context, index, 0x00C04 >> 2, 0x00000000, 1, gcvTRUE, gcvFALSE);
+ index += _State(Context, index, 0x00C08 >> 2, 0x45000000, 1, gcvTRUE, gcvFALSE);
+ index += _State(Context, index, 0x00C0C >> 2, 0x45000000, 1, gcvTRUE, gcvFALSE);
+ index += _State(Context, index, 0x00C10 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x00C14 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x00C18 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x00C1C >> 2, 0x42000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x00C20 >> 2, 0x00000000, 1, gcvTRUE, gcvFALSE);
+ index += _State(Context, index, 0x00C24 >> 2, 0x00000000, 1, gcvTRUE, gcvFALSE);
+
+ /* Raster states. */
+ index += _State(Context, index, 0x00E00 >> 2, 0x000000F1, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x00E10 >> 2, 0x00000000, 4, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x00E04 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x00E40 >> 2, 0x00000000, 16, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x00E08 >> 2, 0x17000031, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x00E24 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x00E20 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+
+ if (halti2)
+ {
+ index += _State(Context, index, 0x00E0C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ }
+
+ if (halti5)
+ {
+ index += _State(Context, index, 0x00E34 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ }
+
+
+ /* Pixel Shader states. */
+ index += _State(Context, index, 0x01004 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x01008 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x0100C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x01010 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x01030 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x01034 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+
+ if (halti2)
+ {
+ index += _State(Context, index, 0x01040 >> 2, 0x00000000, 2, gcvFALSE, gcvFALSE);
+ }
+
+ if (numRT == 8)
+ {
+ index += _State(Context, index, 0x0102C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x01038 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ }
+
+ if (halti4)
+ {
+ index += _State(Context, index, 0x01054 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ }
+
+ if (halti5)
+ {
+ index += _State(Context, index, 0x01080 >> 2, 0x00000000, 4, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x01058 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x01098 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ }
+
+
+ index += _CLOSE_RANGE();
+
+ /* Texture states. */
+ if (hasTXdesc)
+ {
+ /* Texture descriptor states */
+ index += _State(Context, index, 0x14C40 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+
+ index += _State(Context, index, 0x16C00 >> 2, 0x00000000, numSamplers, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x16E00 >> 2, 0x00000000, numSamplers, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x17000 >> 2, 0x00000000, numSamplers, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x17200 >> 2, 0x00000000, numSamplers, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x17400 >> 2, 0x00000000, numSamplers, gcvFALSE, gcvFALSE);
+
+ index += _State(Context, index, (0x15C00 >> 2) + (0 << 0), 0x00000000, numSamplers, gcvFALSE, gcvTRUE);
+ index += _State(Context, index, 0x15E00 >> 2, 0x00000000, numSamplers, gcvFALSE, gcvFALSE);
+
+ index += _CLOSE_RANGE();
+
+ _StateMirror(Context, 0x16000 >> 2, numSamplers , 0x16C00 >> 2);
+ _StateMirror(Context, 0x16200 >> 2, numSamplers , 0x16E00 >> 2);
+ _StateMirror(Context, 0x16400 >> 2, numSamplers , 0x17000 >> 2);
+ _StateMirror(Context, 0x16600 >> 2, numSamplers , 0x17200 >> 2);
+ _StateMirror(Context, 0x16800 >> 2, numSamplers , 0x17400 >> 2);
+ _StateMirror(Context, 0x15800 >> 2, numSamplers , 0x15C00 >> 2);
+ _StateMirror(Context, 0x15A00 >> 2, numSamplers , 0x15E00 >> 2);
+ }
+ else
+ {
+ index += _State(Context, index, 0x02000 >> 2, 0x00000000, 12, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x02040 >> 2, 0x00000000, 12, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x02080 >> 2, 0x00000000, 12, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x020C0 >> 2, 0x00000000, 12, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x02100 >> 2, 0x00000000, 12, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x02140 >> 2, 0x00000000, 12, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x02180 >> 2, 0x00000000, 12, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x021C0 >> 2, 0x00321000, 12, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x02200 >> 2, 0x00000000, 12, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x02240 >> 2, 0x00000000, 12, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, (0x02400 >> 2) + (0 << 4), 0x00000000, 12, gcvFALSE, gcvTRUE);
+ index += _State(Context, index, (0x02440 >> 2) + (0 << 4), 0x00000000, 12, gcvFALSE, gcvTRUE);
+ index += _State(Context, index, (0x02480 >> 2) + (0 << 4), 0x00000000, 12, gcvFALSE, gcvTRUE);
+ index += _State(Context, index, (0x024C0 >> 2) + (0 << 4), 0x00000000, 12, gcvFALSE, gcvTRUE);
+ index += _State(Context, index, (0x02500 >> 2) + (0 << 4), 0x00000000, 12, gcvFALSE, gcvTRUE);
+ index += _State(Context, index, (0x02540 >> 2) + (0 << 4), 0x00000000, 12, gcvFALSE, gcvTRUE);
+ index += _State(Context, index, (0x02580 >> 2) + (0 << 4), 0x00000000, 12, gcvFALSE, gcvTRUE);
+ index += _State(Context, index, (0x025C0 >> 2) + (0 << 4), 0x00000000, 12, gcvFALSE, gcvTRUE);
+ index += _State(Context, index, (0x02600 >> 2) + (0 << 4), 0x00000000, 12, gcvFALSE, gcvTRUE);
+ index += _State(Context, index, (0x02640 >> 2) + (0 << 4), 0x00000000, 12, gcvFALSE, gcvTRUE);
+ index += _State(Context, index, (0x02680 >> 2) + (0 << 4), 0x00000000, 12, gcvFALSE, gcvTRUE);
+ index += _State(Context, index, (0x026C0 >> 2) + (0 << 4), 0x00000000, 12, gcvFALSE, gcvTRUE);
+ index += _State(Context, index, (0x02700 >> 2) + (0 << 4), 0x00000000, 12, gcvFALSE, gcvTRUE);
+ index += _State(Context, index, (0x02740 >> 2) + (0 << 4), 0x00000000, 12, gcvFALSE, gcvTRUE);
+ index += _CLOSE_RANGE();
+
+ if (gckHARDWARE_IsFeatureAvailable(hardware, gcvFEATURE_TEXTURE_LINEAR))
+ {
+ /*
+ * Linear stride LODn will overwrite LOD0 on GC880,GC2000.
+ * And only LOD0 is valid for this register.
+ */
+ gctUINT count = halti1 ? 14 : 1;
+
+ for (i = 0; i < 12; i += 1)
+ {
+ index += _State(Context, index, (0x02C00 >> 2) + i * 16, 0x00000000, count, gcvFALSE, gcvFALSE);
+ }
+ }
+
+ if (halti1)
+ {
+ gctUINT texBlockCount;
+ gctUINT gcregTXLogSizeResetValue;
+
+ /* Enable the integer filter pipe for all texture samplers
+ so that the floating point filter clock will shut off until
+ we start using the floating point filter.
+ */
+ gcregTXLogSizeResetValue = ((((gctUINT32) (0x00000000)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 29:29) - (0 ?
+ 29:29) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 29:29) - (0 ?
+ 29:29) + 1))))))) << (0 ?
+ 29:29))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 29:29) - (0 ?
+ 29:29) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 29:29) - (0 ? 29:29) + 1))))))) << (0 ? 29:29)));
+
+ /* New texture block. */
+ index += _State(Context, index, 0x10000 >> 2, 0x00000000, 32, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x10080 >> 2, 0x00000000, 32, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x10100 >> 2, gcregTXLogSizeResetValue, 32, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x10180 >> 2, 0x00000000, 32, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x10200 >> 2, 0x00000000, 32, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x10280 >> 2, 0x00000000, 32, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x10300 >> 2, 0x00000000, 32, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x10380 >> 2, 0x00321000, 32, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x10400 >> 2, 0x00000000, 32, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x10480 >> 2, 0x00000000, 32, gcvFALSE, gcvFALSE);
+
+ if (gckHARDWARE_IsFeatureAvailable(hardware, gcvFEATURE_TX_FILTER))
+ {
+ index += _State(Context, index, 0x12000 >> 2, 0x00000000, 256, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x12400 >> 2, 0x00000000, 256, gcvFALSE, gcvFALSE);
+ }
+
+ texBlockCount = ((512) >> (4));
+
+ for (i = 0; i < texBlockCount; i += 1)
+ {
+ index += _State(Context, index, (0x10800 >> 2) + (i << 4), 0x00000000, 14, gcvFALSE, gcvTRUE);
+ }
+ }
+
+ if (gckHARDWARE_IsFeatureAvailable(Context->hardware, gcvFEATURE_TEX_BASELOD))
+ {
+ index += _State(Context, index, 0x10700 >> 2, 0x00000F00, 32, gcvFALSE, gcvFALSE);
+ }
+
+ if (halti3 ||
+ gckHARDWARE_IsFeatureAvailable(hardware, gcvFEATURE_TX_SUPPORT_DEC))
+ {
+ index += _State(Context, index, 0x10780 >> 2, 0x00030000, 32, gcvFALSE, gcvFALSE);
+ }
+
+ if (halti4)
+ {
+ index += _State(Context, index, 0x11200 >> 2, 0x00000000, 32, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x11280 >> 2, 0x00000000, 32, gcvFALSE, gcvFALSE);
+ }
+
+ if (gckHARDWARE_IsFeatureAvailable(hardware, gcvFEATURE_TX_FRAC_PRECISION_6BIT))
+ {
+ index += _State(Context, index, 0x11000 >> 2, 0x00000000, 32, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x11080 >> 2, 0x00000000, 32, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x11100 >> 2, 0x00000000, 32, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x11180 >> 2, 0x00000000, 32, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x11300 >> 2, 0x00000000, 32, gcvFALSE, gcvFALSE);
+ }
+
+ /* ASTC */
+ if (gckHARDWARE_IsFeatureAvailable(hardware, gcvFEATURE_TEXTURE_ASTC))
+ {
+ index += _State(Context, index, 0x10500 >> 2, 0x00000000, 32, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x10580 >> 2, 0x00000000, 32, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x10600 >> 2, 0x00000000, 32, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x10680 >> 2, 0x00000000, 32, gcvFALSE, gcvFALSE);
+ }
+ }
+
+ if (halti3)
+ {
+ index += _State(Context, index, 0x14C00 >> 2, 0x00000000, 16, gcvFALSE, gcvFALSE);
+ }
+
+ /* Thread walker states. */
+ index += _State(Context, index, 0x00900 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x00904 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x00908 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x0090C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x00910 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x00914 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x00918 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x00924 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x0091C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+
+ if (gckHARDWARE_IsFeatureAvailable(hardware, gcvFEATURE_SHADER_ENHANCEMENTS2))
+ {
+ index += _State(Context, index, 0x00940 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x00944 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x00948 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x0094C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x00950 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x00954 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ }
+
+ if (halti5)
+ {
+ index += _State(Context, index, 0x00958 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x0095C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x00960 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ }
+
+ index += _CLOSE_RANGE();
+
+ /* VS/PS Start/End PC register */
+ if (halti5)
+ {
+ index += _State(Context, index, 0x00874 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x008BC >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x0087C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x01090 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _CLOSE_RANGE();
+ }
+ else if (hasICache)
+ {
+ /* New Shader instruction PC registers(20bit). */
+ index += _State(Context, index, 0x00874 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x00878 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x0087C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x00880 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _CLOSE_RANGE();
+ }
+ else
+ {
+ if (Context->hardware->identity.instructionCount <= 256)
+ {
+ /* old shader instruction PC registers (12bit)*/
+ index += _State(Context, index, 0x00800 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x00838 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _CLOSE_RANGE();
+
+ index += _State(Context, index, 0x01000 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x01018 >> 2, 0x01000000, 1, gcvFALSE, gcvFALSE);
+ index += _CLOSE_RANGE();
+ }
+ else
+ {
+ /* New Shader instruction PC registers (16bit) */
+ index += _State(Context, index, 0x0085C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x0101C >> 2, 0x00000100, 1, gcvFALSE, gcvFALSE);
+ index += _CLOSE_RANGE();
+ }
+ }
+
+
+ if (!hasICachePrefetch)
+ {
+ /* This unified one need SELECT bit to steer */
+ if (Context->hardware->identity.instructionCount > 1024)
+ {
+ for (i = 0;
+ i < Context->hardware->identity.instructionCount << 2;
+ i += 256 << 2
+ )
+ {
+ index += _State(Context, index, (0x20000 >> 2) + i, 0x00000000, 256 << 2, gcvFALSE, gcvFALSE);
+ index += _CLOSE_RANGE();
+ }
+ }
+ /* This unified one is steered by base adddress, it's automatical. */
+ else if (Context->hardware->identity.instructionCount > 256)
+ {
+ /* VS instruction memory. */
+ for (i = 0;
+ i < Context->hardware->identity.instructionCount << 2;
+ i += 256 << 2
+ )
+ {
+ index += _State(Context, index, (0x0C000 >> 2) + i, 0x00000000, 256 << 2, gcvFALSE, gcvFALSE);
+ index += _CLOSE_RANGE();
+ }
+
+ _StateMirror(Context, 0x08000 >> 2, Context->hardware->identity.instructionCount << 2 , 0x0C000 >> 2);
+ }
+ /* if (Context->hardware->identity.instructionCount <= 256). This is non-unified one. */
+ else
+ {
+ index += _State(Context, index, 0x04000 >> 2, 0x00000000, 1024, gcvFALSE, gcvFALSE);
+ index += _CLOSE_RANGE();
+ index += _State(Context, index, 0x06000 >> 2, 0x00000000, 1024, gcvFALSE, gcvFALSE);
+ index += _CLOSE_RANGE();
+ }
+ }
+
+ if (unifiedUniform)
+ {
+ gctINT numConstants = Context->hardware->identity.numConstants;
+
+ /* Base Offset register */
+ index += _State(Context, index, 0x01024 >> 2, 0x00000100, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x00864 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _CLOSE_RANGE();
+
+ for (i = 0;
+ numConstants > 0;
+ i += 256 << 2,
+ numConstants -= 256
+ )
+ {
+ if (halti5)
+ {
+ if (numConstants >= 256)
+ {
+ index += _State(Context, index, (0x36000 >> 2) + i, 0x00000000, 256 << 2, gcvFALSE, gcvFALSE);
+ }
+ else
+ {
+ index += _State(Context, index, (0x36000 >> 2) + i, 0x00000000, numConstants << 2, gcvFALSE, gcvFALSE);
+ }
+ index += _CLOSE_RANGE();
+ }
+ else
+ {
+ if (numConstants >= 256)
+ {
+ index += _State(Context, index, (0x30000 >> 2) + i, 0x00000000, 256 << 2, gcvFALSE, gcvFALSE);
+ }
+ else
+ {
+ index += _State(Context, index, (0x30000 >> 2) + i, 0x00000000, numConstants << 2, gcvFALSE, gcvFALSE);
+ }
+
+ index += _CLOSE_RANGE();
+ }
+ }
+
+ if (halti5)
+ {
+ _StateMirror(Context, 0x34000 >> 2, Context->hardware->identity.numConstants << 2 , 0x36000 >> 2);
+ }
+ }
+#if gcdENABLE_UNIFIED_CONSTANT
+ else
+#endif
+ {
+ index += _State(Context, index, 0x05000 >> 2, 0x00000000, vertexUniforms * 4, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x07000 >> 2, 0x00000000, fragmentUniforms * 4, gcvFALSE, gcvFALSE);
+ }
+
+ if (halti1)
+ {
+ index += _State(Context, index, 0x00884 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ }
+
+ if (halti5)
+ {
+ index += _State(Context, index, 0x008B0 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ }
+
+ /* Store the index of the "XD" entry. */
+ Context->entryOffsetXDFrom3D = (gctUINT)index * gcmSIZEOF(gctUINT32);
+
+
+ /* Pixel Engine states. */
+ index += _State(Context, index, 0x01400 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x01404 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x01408 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x0140C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x01414 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x01418 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x0141C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x01420 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x01424 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x01428 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x0142C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x01434 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x01454 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x01458 >> 2, 0x00000000, 1, gcvFALSE, gcvTRUE);
+ index += _State(Context, index, 0x014A0 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x014A8 >> 2, 0xFFFFFFFF, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x014AC >> 2, 0xFFFFFFFF, 1, gcvFALSE, gcvFALSE);
+
+ if(gckHARDWARE_IsFeatureAvailable(hardware, gcvFEATURE_HALF_FLOAT_PIPE) )
+ {
+ index += _State(Context, index, 0x014B0 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x014B4 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ }
+ index += _State(Context, index, 0x014A4 >> 2, 0x000E400C, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x01580 >> 2, 0x00000000, 3, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x014B8 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+
+ if (halti3)
+ {
+ index += _State(Context, index, 0x0103C >> 2, 0x76543210, 1, gcvFALSE, gcvFALSE);
+ }
+
+ index += _State(Context, index, (0x01460 >> 2) + (0 << 3), 0x00000000, Context->hardware->identity.pixelPipes, gcvFALSE, gcvTRUE);
+
+ if (Context->hardware->identity.pixelPipes == 1)
+ {
+ index += _State(Context, index, 0x01430 >> 2, 0x00000000, 1, gcvFALSE, gcvTRUE);
+ index += _State(Context, index, 0x01410 >> 2, 0x00000000, 1, gcvFALSE, gcvTRUE);
+ }
+
+ if (Context->hardware->identity.pixelPipes > 1 || halti0)
+ {
+ index += _State(Context, index, (0x01480 >> 2) + (0 << 3), 0x00000000, Context->hardware->identity.pixelPipes, gcvFALSE, gcvTRUE);
+ }
+
+ for (i = 0; i < 3; i++)
+ {
+ index += _State(Context, index, (0x01500 >> 2) + (i << 3), 0x00000000, Context->hardware->identity.pixelPipes, gcvFALSE, gcvTRUE);
+ }
+
+ if (numRT == 8)
+ {
+ for (i = 0; i < 7; i++)
+ {
+ index += _State(Context, index, (0x14800 >> 2) + (i << 3), 0x00000000, Context->hardware->identity.pixelPipes, gcvFALSE, gcvTRUE);
+ }
+ index += _State(Context, index, 0x14900 >> 2, 0x00000000, 7, gcvFALSE, gcvFALSE);
+ }
+
+
+ if (halti3)
+ {
+ index += _State(Context, index, 0x014BC >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ }
+
+ if (halti4)
+ {
+ index += _State(Context, index, 0x014C0 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ }
+
+ if (hasGS)
+ {
+ index += _State(Context, index, 0x038A0 >> 2, 0x00000000, 8, gcvFALSE, gcvFALSE);
+ }
+
+ if (halti5)
+ {
+ index += _State(Context, index, 0x14920 >> 2, 0x00000000, 7, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x14940 >> 2, 0x00000000, 7, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x14960 >> 2, 0x00000000, 7, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x14980 >> 2, 0x00000000, 7, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x149A0 >> 2, 0x00000000, 7, gcvFALSE, gcvFALSE);
+ }
+
+ if (hasRobustness)
+ {
+ index += _State(Context, index, 0x149C0 >> 2, 0x00000000, 8, gcvFALSE, gcvTRUE);
+ index += _State(Context, index, 0x014C4 >> 2, 0x00000000, 1, gcvFALSE, gcvTRUE);
+ }
+
+ /* Memory Controller */
+ index += _State(Context, index, 0x01654 >> 2, 0x00200000, 1, gcvFALSE, gcvFALSE);
+
+ index += _CLOSE_RANGE();
+ index += _State(Context, index, 0x01658 >> 2, 0x00000000, 1, gcvFALSE, gcvTRUE);
+ index += _State(Context, index, 0x0165C >> 2, 0x00000000, 1, gcvFALSE, gcvTRUE);
+ index += _State(Context, index, 0x01660 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x01664 >> 2, 0x00000000, 1, gcvFALSE, gcvTRUE);
+ index += _State(Context, index, 0x01668 >> 2, 0x00000000, 1, gcvFALSE, gcvTRUE);
+ index += _State(Context, index, 0x0166C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x01670 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x01674 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x016A4 >> 2, 0x00000000, 1, gcvFALSE, gcvTRUE);
+ index += _State(Context, index, 0x016AC >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x016A8 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x01720 >> 2, 0x00000000, 8, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x01740 >> 2, 0x00000000, 8, gcvFALSE, gcvTRUE);
+ index += _State(Context, index, 0x01760 >> 2, 0x00000000, 8, gcvFALSE, gcvFALSE);
+
+
+ if (halti2)
+ {
+ index += _State(Context, index, 0x01780 >> 2, 0x00000000, 8, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x016BC >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, (0x017A0 >> 2) + 1, 0x00000000, 7, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, (0x017C0 >> 2) + 1, 0x00000000, 7, gcvFALSE, gcvTRUE);
+ index += _State(Context, index, (0x017E0 >> 2) + 1, 0x00000000, 7, gcvFALSE, gcvTRUE);
+ index += _State(Context, index, (0x01A00 >> 2) + 1, 0x00000000, 7, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, (0x01A20 >> 2) + 1, 0x00000000, 7, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, (0x01A40 >> 2) + 1, 0x00000000, 7, gcvFALSE, gcvFALSE);
+ }
+
+ index += _CLOSE_RANGE();
+
+ if (gckHARDWARE_IsFeatureAvailable(hardware, gcvFEATURE_BUG_FIXES18))
+ {
+ index += _State(Context, index, 0x03860 >> 2, 0x6, 1, gcvFALSE, gcvFALSE);
+ index += _CLOSE_RANGE();
+ }
+
+ if (halti3)
+ {
+ index += _State(Context, index, 0x01A80 >> 2, 0x00000000, 8, gcvFALSE, gcvTRUE);
+ index += _CLOSE_RANGE();
+ }
+
+ if (hasSecurity || hasRobustness)
+ {
+ index += _State(Context, index, 0x001AC >> 2, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 16:16) - (0 ?
+ 16:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 16:16) - (0 ?
+ 16:16) + 1))))))) << (0 ?
+ 16:16))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 16:16) - (0 ?
+ 16:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 16:16) - (0 ? 16:16) + 1))))))) << (0 ? 16:16))), 1, gcvFALSE, gcvFALSE);
+ }
+
+ /* Semaphore/stall. */
+ index += _SemaphoreStall(Context, index);
+#endif
+
+ /**************************************************************************/
+ /* Link to another address. ***********************************************/
+
+ Context->linkIndex3D = (gctUINT)index;
+
+ if (buffer != gcvNULL)
+ {
+ buffer[index + 0]
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x08 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+
+ buffer[index + 1]
+ = 0;
+ }
+
+ index += 2;
+
+ /* Store the end of the context buffer. */
+ Context->bufferSize = index * gcmSIZEOF(gctUINT32);
+
+
+ /**************************************************************************/
+ /* Pipe switch for the case where neither 2D nor 3D are used. *************/
+
+ /* Store the 3D entry index. */
+ Context->entryOffsetXDFrom2D = (gctUINT)index * gcmSIZEOF(gctUINT32);
+
+ /* Switch to 3D pipe. */
+ index += _SwitchPipe(Context, index, gcvPIPE_3D);
+
+ /* Store the location of the link. */
+ Context->linkIndexXD = (gctUINT)index;
+
+ if (buffer != gcvNULL)
+ {
+ buffer[index + 0]
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x08 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+
+ buffer[index + 1]
+ = 0;
+ }
+
+ index += 2;
+
+
+ /**************************************************************************/
+ /* Save size for buffer. **************************************************/
+
+ Context->totalSize = index * gcmSIZEOF(gctUINT32);
+
+#if gcdENABLE_3D
+ psConstBase = psConstBase;
+ vsConstBase = vsConstBase;
+ constMax = constMax;
+#endif
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+}
+#endif
+
+static gceSTATUS
+_DestroyContext(
+ IN gckCONTEXT Context
+ )
+{
+ gceSTATUS status = gcvSTATUS_OK;
+
+ if (Context != gcvNULL)
+ {
+ gcsCONTEXT_PTR bufferHead;
+
+ /* Free context buffers. */
+ for (bufferHead = Context->buffer; Context->buffer != gcvNULL;)
+ {
+ /* Get a shortcut to the current buffer. */
+ gcsCONTEXT_PTR buffer = Context->buffer;
+
+ /* Get the next buffer. */
+ gcsCONTEXT_PTR next = buffer->next;
+
+ /* Last item? */
+ if (next == bufferHead)
+ {
+ next = gcvNULL;
+ }
+
+ /* Destroy the signal. */
+ if (buffer->signal != gcvNULL)
+ {
+ gcmkONERROR(gckOS_DestroySignal(
+ Context->os, buffer->signal
+ ));
+
+ buffer->signal = gcvNULL;
+ }
+
+ /* Free state delta map. */
+ if (buffer->logical != gcvNULL)
+ {
+ if (Context->hardware->kernel->virtualCommandBuffer)
+ {
+ gcmkONERROR(gckEVENT_DestroyVirtualCommandBuffer(
+ Context->hardware->kernel->eventObj,
+ Context->totalSize,
+ buffer->physical,
+ buffer->logical,
+ gcvKERNEL_PIXEL
+ ));
+ }
+ else
+ {
+ gcmkONERROR(gckEVENT_FreeContiguousMemory(
+ Context->hardware->kernel->eventObj,
+ Context->totalSize,
+ buffer->physical,
+ buffer->logical,
+ gcvKERNEL_PIXEL
+ ));
+ }
+
+ buffer->logical = gcvNULL;
+ }
+
+ /* Free context buffer. */
+ gcmkONERROR(gcmkOS_SAFE_FREE(Context->os, buffer));
+
+ /* Remove from the list. */
+ Context->buffer = next;
+ }
+
+#if gcdSECURE_USER
+ /* Free the hint array. */
+ if (Context->hint != gcvNULL)
+ {
+ gcmkONERROR(gcmkOS_SAFE_FREE(Context->os, Context->hint));
+ }
+#endif
+
+ /* Mark the gckCONTEXT object as unknown. */
+ Context->object.type = gcvOBJ_UNKNOWN;
+
+ /* Free the gckCONTEXT object. */
+ gcmkONERROR(gcmkOS_SAFE_FREE(Context->os, Context));
+ }
+
+OnError:
+ return status;
+}
+
+#if (gcdENABLE_3D || gcdENABLE_2D)
+static gceSTATUS
+_AllocateContextBuffer(
+ IN gckCONTEXT Context,
+ IN gcsCONTEXT_PTR Buffer
+ )
+{
+ gceSTATUS status;
+ gctPOINTER pointer;
+ gctUINT32 address;
+ gctSIZE_T totalSize = Context->totalSize;
+
+ if (Context->hardware->kernel->virtualCommandBuffer)
+ {
+ gcmkONERROR(gckKERNEL_AllocateVirtualCommandBuffer(
+ Context->hardware->kernel,
+ gcvFALSE,
+ &totalSize,
+ &Buffer->physical,
+ &pointer
+ ));
+
+ gcmkONERROR(gckKERNEL_GetGPUAddress(
+ Context->hardware->kernel,
+ pointer,
+ gcvFALSE,
+ Buffer->physical,
+ &address
+ ));
+ }
+ else
+ {
+ gctUINT32 allocFlag;
+
+#if gcdENABLE_CACHEABLE_COMMAND_BUFFER
+ allocFlag = gcvALLOC_FLAG_CACHEABLE | gcvALLOC_FLAG_CONTIGUOUS;
+#else
+ allocFlag = gcvALLOC_FLAG_CONTIGUOUS;
+#endif
+ gcmkONERROR(gckOS_AllocateNonPagedMemory(
+ Context->os,
+ gcvFALSE,
+ allocFlag,
+ &totalSize,
+ &Buffer->physical,
+ &pointer
+ ));
+
+ gcmkONERROR(gckHARDWARE_ConvertLogical(
+ Context->hardware,
+ pointer,
+ gcvFALSE,
+ &address
+ ));
+ }
+
+ Buffer->logical = pointer;
+ Buffer->address = address;
+
+ return gcvSTATUS_OK;
+
+OnError:
+ return status;
+}
+#endif
+
+/******************************************************************************\
+**************************** Context Management API ****************************
+\******************************************************************************/
+
+/******************************************************************************\
+**
+** gckCONTEXT_Construct
+**
+** Construct a new gckCONTEXT object.
+**
+** INPUT:
+**
+** gckOS Os
+** Pointer to gckOS object.
+**
+** gctUINT32 ProcessID
+** Current process ID.
+**
+** gckHARDWARE Hardware
+** Pointer to gckHARDWARE object.
+**
+** OUTPUT:
+**
+** gckCONTEXT * Context
+** Pointer to a variable thet will receive the gckCONTEXT object
+** pointer.
+*/
+#if (gcdENABLE_3D || gcdENABLE_2D)
+gceSTATUS
+gckCONTEXT_Construct(
+ IN gckOS Os,
+ IN gckHARDWARE Hardware,
+ IN gctUINT32 ProcessID,
+ OUT gckCONTEXT * Context
+ )
+{
+ gceSTATUS status;
+ gckCONTEXT context = gcvNULL;
+ gctUINT32 allocationSize;
+ gctUINT i;
+ gctPOINTER pointer = gcvNULL;
+
+ gcmkHEADER_ARG("Os=0x%08X Hardware=0x%08X", Os, Hardware);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
+ gcmkVERIFY_ARGUMENT(Context != gcvNULL);
+
+
+ /**************************************************************************/
+ /* Allocate and initialize basic fields of gckCONTEXT. ********************/
+
+ /* The context object size. */
+ allocationSize = gcmSIZEOF(struct _gckCONTEXT);
+
+ /* Allocate the object. */
+ gcmkONERROR(gckOS_Allocate(
+ Os, allocationSize, &pointer
+ ));
+
+ context = pointer;
+
+ /* Reset the entire object. */
+ gcmkONERROR(gckOS_ZeroMemory(context, allocationSize));
+
+ /* Initialize the gckCONTEXT object. */
+ context->object.type = gcvOBJ_CONTEXT;
+ context->os = Os;
+ context->hardware = Hardware;
+
+
+#if !gcdENABLE_3D
+ context->entryPipe = gcvPIPE_2D;
+ context->exitPipe = gcvPIPE_2D;
+#elif gcdCMD_NO_2D_CONTEXT
+ context->entryPipe = gcvPIPE_3D;
+ context->exitPipe = gcvPIPE_3D;
+#else
+ context->entryPipe
+ = (((((gctUINT32) (context->hardware->identity.chipFeatures)) >> (0 ? 9:9)) & ((gctUINT32) ((((1 ? 9:9) - (0 ? 9:9) + 1) == 32) ? ~0U : (~(~0U << ((1 ? 9:9) - (0 ? 9:9) + 1)))))) )
+ ? gcvPIPE_2D
+ : gcvPIPE_3D;
+ context->exitPipe = gcvPIPE_3D;
+#endif
+
+ /* Get the command buffer requirements. */
+ gcmkONERROR(gckHARDWARE_QueryCommandBuffer(
+ Hardware,
+ gcvENGINE_RENDER,
+ &context->alignment,
+ &context->reservedHead,
+ gcvNULL
+ ));
+
+ /**************************************************************************/
+ /* Get the size of the context buffer. ************************************/
+
+ gcmkONERROR(_InitializeContextBuffer(context));
+
+ if (context->maxState > 0)
+ {
+ /**************************************************************************/
+ /* Allocate and reset the state mapping table. ****************************/
+ if (context->hardware->kernel->command->stateMap == gcvNULL)
+ {
+ /* Allocate the state mapping table. */
+ gcmkONERROR(gckOS_Allocate(
+ Os,
+ gcmSIZEOF(gcsSTATE_MAP) * context->maxState,
+ &pointer
+ ));
+
+ context->map = pointer;
+
+ /* Zero the state mapping table. */
+ gcmkONERROR(gckOS_ZeroMemory(
+ context->map, gcmSIZEOF(gcsSTATE_MAP) * context->maxState
+ ));
+
+ context->hardware->kernel->command->stateMap = pointer;
+ }
+ else
+ {
+ context->map = context->hardware->kernel->command->stateMap;
+ }
+
+ /**************************************************************************/
+ /* Allocate the hint array. ***********************************************/
+
+#if gcdSECURE_USER
+ /* Allocate hints. */
+ gcmkONERROR(gckOS_Allocate(
+ Os,
+ gcmSIZEOF(gctBOOL) * context->maxState,
+ &pointer
+ ));
+
+ context->hint = pointer;
+#endif
+ }
+
+ /**************************************************************************/
+ /* Allocate the context and state delta buffers. **************************/
+
+ for (i = 0; i < gcdCONTEXT_BUFFER_COUNT; i += 1)
+ {
+ /* Allocate a context buffer. */
+ gcsCONTEXT_PTR buffer;
+
+ /* Allocate the context buffer structure. */
+ gcmkONERROR(gckOS_Allocate(
+ Os,
+ gcmSIZEOF(gcsCONTEXT),
+ &pointer
+ ));
+
+ buffer = pointer;
+
+ /* Reset the context buffer structure. */
+ gcmkVERIFY_OK(gckOS_ZeroMemory(
+ buffer, gcmSIZEOF(gcsCONTEXT)
+ ));
+
+ /* Append to the list. */
+ if (context->buffer == gcvNULL)
+ {
+ buffer->next = buffer;
+ context->buffer = buffer;
+ }
+ else
+ {
+ buffer->next = context->buffer->next;
+ context->buffer->next = buffer;
+ }
+
+ /* Set the number of delta in the order of creation. */
+#if gcmIS_DEBUG(gcdDEBUG_CODE)
+ buffer->num = i;
+#endif
+
+ /* Create the busy signal. */
+ gcmkONERROR(gckOS_CreateSignal(
+ Os, gcvFALSE, &buffer->signal
+ ));
+
+ /* Set the signal, buffer is currently not busy. */
+ gcmkONERROR(gckOS_Signal(
+ Os, buffer->signal, gcvTRUE
+ ));
+
+ /* Create a new physical context buffer. */
+ gcmkONERROR(_AllocateContextBuffer(
+ context, buffer
+ ));
+
+ /* Set gckEVENT object pointer. */
+ buffer->eventObj = Hardware->kernel->eventObj;
+
+ /* Set the pointers to the LINK commands. */
+ if (context->linkIndex2D != 0)
+ {
+ buffer->link2D = &buffer->logical[context->linkIndex2D];
+ }
+
+ if (context->linkIndex3D != 0)
+ {
+ buffer->link3D = &buffer->logical[context->linkIndex3D];
+ }
+
+ if (context->linkIndexXD != 0)
+ {
+ gctPOINTER xdLink;
+ gctUINT32 xdEntryAddress;
+ gctUINT32 xdEntrySize;
+ gctUINT32 linkBytes;
+
+ /* Determine LINK parameters. */
+ xdLink
+ = &buffer->logical[context->linkIndexXD];
+
+ xdEntryAddress
+ = buffer->address
+ + context->entryOffsetXDFrom3D;
+
+ xdEntrySize
+ = context->bufferSize
+ - context->entryOffsetXDFrom3D;
+
+ /* Query LINK size. */
+ gcmkONERROR(gckHARDWARE_Link(
+ Hardware, gcvNULL, 0, 0, &linkBytes, gcvNULL, gcvNULL
+ ));
+
+ /* Generate a LINK. */
+ gcmkONERROR(gckHARDWARE_Link(
+ Hardware,
+ xdLink,
+ xdEntryAddress,
+ xdEntrySize,
+ &linkBytes,
+ gcvNULL,
+ gcvNULL
+ ));
+ }
+ }
+
+
+ /**************************************************************************/
+ /* Initialize the context buffers. ****************************************/
+
+ /* Initialize the current context buffer. */
+ gcmkONERROR(_InitializeContextBuffer(context));
+
+ /* Make all created contexts equal. */
+ {
+ gcsCONTEXT_PTR currContext, tempContext;
+
+ /* Set the current context buffer. */
+ currContext = context->buffer;
+
+ /* Get the next context buffer. */
+ tempContext = currContext->next;
+
+ /* Loop through all buffers. */
+ while (tempContext != currContext)
+ {
+ if (tempContext == gcvNULL)
+ {
+ gcmkONERROR(gcvSTATUS_NOT_FOUND);
+ }
+
+ /* Copy the current context. */
+ gckOS_MemCopy(
+ tempContext->logical,
+ currContext->logical,
+ context->totalSize
+ );
+
+ /* Get the next context buffer. */
+ tempContext = tempContext->next;
+ }
+ }
+
+ /* Return pointer to the gckCONTEXT object. */
+ *Context = context;
+
+ /* Success. */
+ gcmkFOOTER_ARG("*Context=0x%08X", *Context);
+ return gcvSTATUS_OK;
+
+OnError:
+ /* Roll back on error. */
+ gcmkVERIFY_OK(_DestroyContext(context));
+
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+#endif
+
+/******************************************************************************\
+**
+** gckCONTEXT_Destroy
+**
+** Destroy a gckCONTEXT object.
+**
+** INPUT:
+**
+** gckCONTEXT Context
+** Pointer to an gckCONTEXT object.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckCONTEXT_Destroy(
+ IN gckCONTEXT Context
+ )
+{
+ gceSTATUS status;
+
+ gcmkHEADER_ARG("Context=0x%08X", Context);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Context, gcvOBJ_CONTEXT);
+
+ /* Destroy the context and all related objects. */
+ status = _DestroyContext(Context);
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return status;
+}
+
+/******************************************************************************\
+**
+** gckCONTEXT_Update
+**
+** Merge all pending state delta buffers into the current context buffer.
+**
+** INPUT:
+**
+** gckCONTEXT Context
+** Pointer to an gckCONTEXT object.
+**
+** gctUINT32 ProcessID
+** Current process ID.
+**
+** gcsSTATE_DELTA_PTR StateDelta
+** Pointer to the state delta.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckCONTEXT_Update(
+ IN gckCONTEXT Context,
+ IN gctUINT32 ProcessID,
+ IN gcsSTATE_DELTA_PTR StateDelta
+ )
+{
+#if gcdENABLE_3D
+ gceSTATUS status = gcvSTATUS_OK;
+ gcsSTATE_DELTA _stateDelta;
+ gckKERNEL kernel;
+ gcsCONTEXT_PTR buffer;
+ gcsSTATE_MAP_PTR map;
+ gctBOOL needCopy = gcvFALSE;
+ gcsSTATE_DELTA_PTR uDelta = gcvNULL;
+ gcsSTATE_DELTA_PTR kDelta = gcvNULL;
+ gcsSTATE_DELTA_RECORD_PTR record;
+ gcsSTATE_DELTA_RECORD_PTR recordArray = gcvNULL;
+ gctUINT elementCount;
+ gctUINT address;
+ gctUINT32 mask;
+ gctUINT32 data;
+ gctUINT index;
+ gctUINT i, j;
+ gctUINT32 dirtyRecordArraySize = 0;
+
+#if gcdSECURE_USER
+ gcskSECURE_CACHE_PTR cache;
+#endif
+
+ gcmkHEADER_ARG(
+ "Context=0x%08X ProcessID=%d StateDelta=0x%08X",
+ Context, ProcessID, StateDelta
+ );
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Context, gcvOBJ_CONTEXT);
+
+ /* Get a shortcut to the kernel object. */
+ kernel = Context->hardware->kernel;
+
+ /* Check wehther we need to copy the structures or not. */
+ gcmkONERROR(gckOS_QueryNeedCopy(Context->os, ProcessID, &needCopy));
+
+ /* Get the current context buffer. */
+ buffer = Context->buffer;
+
+ /* Wait until the context buffer becomes available; this will
+ also reset the signal and mark the buffer as busy. */
+ gcmkONERROR(gckOS_WaitSignal(
+ Context->os, buffer->signal, gcvFALSE, gcvINFINITE
+ ));
+
+#if gcdSECURE_USER
+ /* Get the cache form the database. */
+ gcmkONERROR(gckKERNEL_GetProcessDBCache(kernel, ProcessID, &cache));
+#endif
+
+#if gcmIS_DEBUG(gcdDEBUG_CODE) && 1 && gcdENABLE_3D
+ /* Update current context token. */
+ buffer->logical[Context->map[0x0E14].index]
+ = (gctUINT32)gcmPTR2INT32(Context);
+#endif
+
+ if (StateDelta != gcvNULL)
+ {
+ /* Get the state map. */
+ map = Context->map;
+
+ /* Get the first delta item. */
+ uDelta = StateDelta;
+
+ /* Reset the vertex stream count. */
+ elementCount = 0;
+
+ /* Merge all pending deltas. */
+ {
+ /* Get access to the state delta. */
+ gcmkONERROR(gckKERNEL_OpenUserData(
+ kernel, needCopy,
+ &_stateDelta,
+ uDelta, gcmSIZEOF(gcsSTATE_DELTA),
+ (gctPOINTER *) &kDelta
+ ));
+
+ dirtyRecordArraySize
+ = gcmSIZEOF(gcsSTATE_DELTA_RECORD) * kDelta->recordCount;
+
+ if (dirtyRecordArraySize)
+ {
+ /* Get access to the state records. */
+ gcmkONERROR(gckOS_MapUserPointer(
+ kernel->os,
+ gcmUINT64_TO_PTR(kDelta->recordArray),
+ dirtyRecordArraySize,
+ (gctPOINTER *) &recordArray
+ ));
+ }
+
+ /* Merge all pending states. */
+ for (j = 0; j < kDelta->recordCount; j += 1)
+ {
+ if (j >= Context->numStates)
+ {
+ break;
+ }
+
+ /* Get the current state record. */
+ record = &recordArray[j];
+
+ /* Get the state address. */
+ gcmkONERROR(gckOS_ReadMappedPointer(kernel->os, &record->address, &address));
+
+ /* Make sure the state is a part of the mapping table. */
+ if (address >= Context->maxState)
+ {
+ gcmkTRACE(
+ gcvLEVEL_ERROR,
+ "%s(%d): State 0x%04X (0x%04X) is not mapped.\n",
+ __FUNCTION__, __LINE__,
+ address, address << 2
+ );
+
+ continue;
+ }
+
+ /* Get the state index. */
+ index = map[address].index;
+
+ /* Skip the state if not mapped. */
+ if (index == 0)
+ {
+ continue;
+ }
+
+ /* Get the data mask. */
+ gcmkONERROR(gckOS_ReadMappedPointer(kernel->os, &record->mask, &mask));
+
+ /* Get the new data value. */
+ gcmkONERROR(gckOS_ReadMappedPointer(kernel->os, &record->data, &data));
+
+ /* Masked states that are being completly reset or regular states. */
+ if ((mask == 0) || (mask == ~0U))
+ {
+ /* Process special states. */
+ if (address == 0x0595)
+ {
+ /* Force auto-disable to be disabled. */
+ data = ((((gctUINT32) (data)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 5:5) - (0 ?
+ 5:5) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 5:5) - (0 ?
+ 5:5) + 1))))))) << (0 ?
+ 5:5))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ?
+ 5:5) - (0 ?
+ 5:5) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 5:5) - (0 ? 5:5) + 1))))))) << (0 ? 5:5)));
+ data = ((((gctUINT32) (data)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 4:4) - (0 ?
+ 4:4) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 4:4) - (0 ?
+ 4:4) + 1))))))) << (0 ?
+ 4:4))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ?
+ 4:4) - (0 ?
+ 4:4) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 4:4) - (0 ? 4:4) + 1))))))) << (0 ? 4:4)));
+ data = ((((gctUINT32) (data)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 13:13) - (0 ?
+ 13:13) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 13:13) - (0 ?
+ 13:13) + 1))))))) << (0 ?
+ 13:13))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ?
+ 13:13) - (0 ?
+ 13:13) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 13:13) - (0 ? 13:13) + 1))))))) << (0 ? 13:13)));
+ }
+
+#if gcdSECURE_USER
+ /* Do we need to convert the logical address? */
+ if (Context->hint[address])
+ {
+ /* Map handle into physical address. */
+ gcmkONERROR(gckKERNEL_MapLogicalToPhysical(
+ kernel, cache, (gctPOINTER) &data
+ ));
+ }
+#endif
+
+ /* Set new data. */
+ buffer->logical[index] = data;
+ }
+
+ /* Masked states that are being set partially. */
+ else
+ {
+ buffer->logical[index]
+ = (~mask & buffer->logical[index])
+ | (mask & data);
+ }
+ }
+
+ /* Get the element count. */
+ if (kDelta->elementCount != 0)
+ {
+ elementCount = kDelta->elementCount;
+ }
+
+ if (dirtyRecordArraySize)
+ {
+ /* Get access to the state records. */
+ gcmkONERROR(gckOS_UnmapUserPointer(
+ kernel->os,
+ gcmUINT64_TO_PTR(kDelta->recordArray),
+ dirtyRecordArraySize,
+ recordArray
+ ));
+
+ recordArray = gcvNULL;
+ }
+
+ /* Close access to the current state delta. */
+ gcmkONERROR(gckKERNEL_CloseUserData(
+ kernel, needCopy,
+ gcvTRUE,
+ uDelta, gcmSIZEOF(gcsSTATE_DELTA),
+ (gctPOINTER *) &kDelta
+ ));
+ }
+
+ /* Hardware disables all input attribute when the attribute 0 is programmed,
+ it then reenables those attributes that were explicitely programmed by
+ the software. Because of this we cannot program the entire array of
+ values, otherwise we'll get all attributes reenabled, but rather program
+ only those that are actully needed by the software.
+ elementCount = attribCount + 1 to make sure 0 is a flag to indicate if UMD
+ touches it.
+ */
+ if (elementCount != 0)
+ {
+ gctUINT base;
+ gctUINT nopCount;
+ gctUINT32_PTR nop;
+ gctUINT fe2vsCount;
+ gctUINT attribCount = elementCount -1;
+ gctUINT32 feAttributeStatgeAddr = 0x0180;
+ if (gckHARDWARE_IsFeatureAvailable(Context->hardware, gcvFEATURE_HALTI5))
+ {
+ fe2vsCount = 32;
+ base = map[0x5E00].index;
+ feAttributeStatgeAddr = 0x5E00;
+ }
+ else if (gckHARDWARE_IsFeatureAvailable(Context->hardware, gcvFEATURE_HALTI0))
+ {
+ fe2vsCount = 16;
+ base = map[0x0180].index;
+ }
+ else
+ {
+ fe2vsCount = 12;
+ base = map[0x0180].index;
+ }
+
+ /* Set the proper state count. */
+ if (attribCount == 0)
+ {
+ gcmkASSERT(gckHARDWARE_IsFeatureAvailable(Context->hardware, gcvFEATURE_ZERO_ATTRIB_SUPPORT));
+
+ buffer->logical[base - 1]
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 26:26) - (0 ?
+ 26:26) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 26:26) - (0 ?
+ 26:26) + 1))))))) << (0 ?
+ 26:26))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ?
+ 26:26) - (0 ?
+ 26:26) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 26:26) - (0 ? 26:26) + 1))))))) << (0 ? 26:26)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (feAttributeStatgeAddr) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+
+ /* Set the proper state count. */
+ buffer->logical[base + 1] =
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 26:26) - (0 ?
+ 26:26) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 26:26) - (0 ?
+ 26:26) + 1))))))) << (0 ?
+ 26:26))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ?
+ 26:26) - (0 ?
+ 26:26) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 26:26) - (0 ? 26:26) + 1))))))) << (0 ? 26:26)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x01F2) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+ buffer->logical[base + 2] = 0x1;
+ attribCount = 3;
+ }
+ else
+ {
+ buffer->logical[base - 1]
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 26:26) - (0 ?
+ 26:26) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 26:26) - (0 ?
+ 26:26) + 1))))))) << (0 ?
+ 26:26))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ?
+ 26:26) - (0 ?
+ 26:26) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 26:26) - (0 ? 26:26) + 1))))))) << (0 ? 26:26)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (attribCount) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (feAttributeStatgeAddr) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+ }
+
+ /* Determine the number of NOP commands. */
+ nopCount = (fe2vsCount / 2) - (attribCount / 2);
+ /* Determine the location of the first NOP. */
+ nop = &buffer->logical[base + (attribCount | 1)];
+
+ /* Fill the unused space with NOPs. */
+ for (i = 0; i < nopCount; i += 1)
+ {
+ if (nop >= buffer->logical + Context->totalSize)
+ {
+ break;
+ }
+
+ /* Generate a NOP command. */
+ *nop = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x03 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)));
+
+ /* Advance. */
+ nop += 2;
+ }
+ }
+ }
+
+ /* Schedule an event to mark the context buffer as available. */
+ gcmkONERROR(gckEVENT_Signal(
+ buffer->eventObj, buffer->signal, gcvKERNEL_PIXEL
+ ));
+
+ /* Advance to the next context buffer. */
+ Context->buffer = buffer->next;
+
+ /* Return the status. */
+ gcmkFOOTER();
+ return gcvSTATUS_OK;
+
+OnError:
+ /* Get access to the state records. */
+ if (kDelta != gcvNULL && recordArray != gcvNULL)
+ {
+ gcmkVERIFY_OK(gckOS_UnmapUserPointer(
+ kernel->os,
+ gcmUINT64_TO_PTR(kDelta->recordArray),
+ dirtyRecordArraySize,
+ (gctPOINTER *) &recordArray
+ ));
+ }
+
+ /* Close access to the current state delta. */
+ gcmkVERIFY_OK(gckKERNEL_CloseUserData(
+ kernel, needCopy,
+ gcvTRUE,
+ uDelta, gcmSIZEOF(gcsSTATE_DELTA),
+ (gctPOINTER *) &kDelta
+ ));
+
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+#else
+ return gcvSTATUS_OK;
+#endif
+}
+
+gceSTATUS
+gckCONTEXT_MapBuffer(
+ IN gckCONTEXT Context,
+ OUT gctUINT32 *Physicals,
+ OUT gctUINT64 *Logicals,
+ OUT gctUINT32 *Bytes
+ )
+{
+ gceSTATUS status;
+ int i = 0;
+ gctSIZE_T pageCount;
+ gckVIRTUAL_COMMAND_BUFFER_PTR commandBuffer;
+ gckKERNEL kernel = Context->hardware->kernel;
+ gctPOINTER logical;
+ gctPHYS_ADDR physical;
+
+ gcsCONTEXT_PTR buffer;
+
+ gcmkHEADER();
+
+ gcmkVERIFY_OBJECT(Context, gcvOBJ_CONTEXT);
+
+ buffer = Context->buffer;
+
+ for (i = 0; i < gcdCONTEXT_BUFFER_COUNT; i++)
+ {
+ if (kernel->virtualCommandBuffer)
+ {
+ commandBuffer = (gckVIRTUAL_COMMAND_BUFFER_PTR)buffer->physical;
+ physical = commandBuffer->virtualBuffer.physical;
+
+ gcmkONERROR(gckOS_CreateUserVirtualMapping(
+ kernel->os,
+ physical,
+ Context->totalSize,
+ &logical,
+ &pageCount));
+ }
+ else
+ {
+ physical = buffer->physical;
+
+ gcmkONERROR(gckOS_MapMemory(
+ kernel->os,
+ physical,
+ Context->totalSize,
+ &logical));
+ }
+
+ Physicals[i] = gcmPTR_TO_NAME(physical);
+
+ Logicals[i] = gcmPTR_TO_UINT64(logical);
+
+ buffer = buffer->next;
+ }
+
+ *Bytes = (gctUINT)Context->totalSize;
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ gcmkFOOTER();
+ return status;
+}
+
diff --git a/drivers/mxc/gpu-viv/hal/kernel/arch/gc_hal_kernel_context.h b/drivers/mxc/gpu-viv/hal/kernel/arch/gc_hal_kernel_context.h
new file mode 100644
index 000000000000..d92b1e38f5bf
--- /dev/null
+++ b/drivers/mxc/gpu-viv/hal/kernel/arch/gc_hal_kernel_context.h
@@ -0,0 +1,188 @@
+/****************************************************************************
+*
+* The MIT License (MIT)
+*
+* Copyright (c) 2014 - 2018 Vivante 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 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 GPL License (GPL)
+*
+* Copyright (C) 2014 - 2018 Vivante 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.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+*****************************************************************************
+*
+* Note: This software is released under dual MIT and GPL licenses. A
+* recipient may use this file under the terms of either the MIT license or
+* GPL License. If you wish to use only one license not the other, you can
+* indicate your decision by deleting one of the above license notices in your
+* version of this file.
+*
+*****************************************************************************/
+
+
+#ifndef __gc_hal_kernel_context_h_
+#define __gc_hal_kernel_context_h_
+
+#include "gc_hal_kernel_buffer.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Maps state locations within the context buffer. */
+typedef struct _gcsSTATE_MAP * gcsSTATE_MAP_PTR;
+typedef struct _gcsSTATE_MAP
+{
+ /* Index of the state in the context buffer. */
+ gctUINT index;
+
+ /* State mask. */
+ gctUINT32 mask;
+}
+gcsSTATE_MAP;
+
+/* Context buffer. */
+typedef struct _gcsCONTEXT * gcsCONTEXT_PTR;
+typedef struct _gcsCONTEXT
+{
+ /* For debugging: the number of context buffer in the order of creation. */
+ gctUINT num;
+
+ /* Pointer to gckEVENT object. */
+ gckEVENT eventObj;
+
+ /* Context busy signal. */
+ gctSIGNAL signal;
+
+ /* Physical address of the context buffer. */
+ gctPHYS_ADDR physical;
+
+ /* Logical address of the context buffer. */
+ gctUINT32_PTR logical;
+
+ /* Hardware address of the context buffer. */
+ gctUINT32 address;
+
+ /* Pointer to the LINK commands. */
+ gctPOINTER link2D;
+ gctPOINTER link3D;
+
+ /* Next context buffer. */
+ gcsCONTEXT_PTR next;
+}
+gcsCONTEXT;
+
+typedef struct _gcsRECORD_ARRAY_MAP * gcsRECORD_ARRAY_MAP_PTR;
+struct _gcsRECORD_ARRAY_MAP
+{
+ /* User pointer key. */
+ gctUINT64 key;
+
+ /* Kernel memory buffer. */
+ gcsSTATE_DELTA_RECORD_PTR kData;
+
+ /* Next map. */
+ gcsRECORD_ARRAY_MAP_PTR next;
+
+};
+
+#define USE_SW_RESET 1
+
+/* gckCONTEXT structure that hold the current context. */
+struct _gckCONTEXT
+{
+ /* Object. */
+ gcsOBJECT object;
+
+ /* Pointer to gckOS object. */
+ gckOS os;
+
+ /* Pointer to gckHARDWARE object. */
+ gckHARDWARE hardware;
+
+ /* Command buffer alignment. */
+ gctUINT32 alignment;
+ gctUINT32 reservedHead;
+
+ /* Context buffer metrics. */
+ gctSIZE_T maxState;
+ gctUINT32 numStates;
+ gctUINT32 totalSize;
+ gctUINT32 bufferSize;
+ gctUINT32 linkIndex2D;
+ gctUINT32 linkIndex3D;
+ gctUINT32 linkIndexXD;
+ gctUINT32 entryOffset3D;
+ gctUINT32 entryOffsetXDFrom2D;
+ gctUINT32 entryOffsetXDFrom3D;
+
+ /* State mapping. */
+ gcsSTATE_MAP_PTR map;
+
+ /* List of context buffers. */
+ gcsCONTEXT_PTR buffer;
+
+ /* Requested pipe select for context. */
+ gcePIPE_SELECT entryPipe;
+ gcePIPE_SELECT exitPipe;
+
+ /* Variables used for building state buffer. */
+ gctUINT32 lastAddress;
+ gctSIZE_T lastSize;
+ gctUINT32 lastIndex;
+ gctBOOL lastFixed;
+
+ gctUINT32 pipeSelectBytes;
+
+ /* Hint array. */
+#if gcdSECURE_USER
+ gctBOOL_PTR hint;
+#endif
+
+ gcsPROFILER_COUNTERS_PART1 latestProfiler_part1;
+ gcsPROFILER_COUNTERS_PART1 histroyProfiler_part1;
+ gcsPROFILER_COUNTERS_PART1 preProfiler_part1;
+ gcsPROFILER_COUNTERS_PART2 latestProfiler_part2;
+ gcsPROFILER_COUNTERS_PART2 histroyProfiler_part2;
+ gcsPROFILER_COUNTERS_PART2 preProfiler_part2;
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __gc_hal_kernel_context_h_ */
+
diff --git a/drivers/mxc/gpu-viv/hal/kernel/arch/gc_hal_kernel_hardware.c b/drivers/mxc/gpu-viv/hal/kernel/arch/gc_hal_kernel_hardware.c
new file mode 100644
index 000000000000..7778da4999df
--- /dev/null
+++ b/drivers/mxc/gpu-viv/hal/kernel/arch/gc_hal_kernel_hardware.c
@@ -0,0 +1,18555 @@
+/****************************************************************************
+*
+* The MIT License (MIT)
+*
+* Copyright (c) 2014 - 2018 Vivante 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 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 GPL License (GPL)
+*
+* Copyright (C) 2014 - 2018 Vivante 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.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+*****************************************************************************
+*
+* Note: This software is released under dual MIT and GPL licenses. A
+* recipient may use this file under the terms of either the MIT license or
+* GPL License. If you wish to use only one license not the other, you can
+* indicate your decision by deleting one of the above license notices in your
+* version of this file.
+*
+*****************************************************************************/
+
+
+#include "gc_hal.h"
+#include "gc_hal_kernel.h"
+#include "gc_hal_kernel_context.h"
+
+#include "gc_feature_database.h"
+
+#define _GC_OBJ_ZONE gcvZONE_HARDWARE
+
+#define gcmSEMAPHORESTALL(buffer) \
+ do \
+ { \
+ /* Arm the PE-FE Semaphore. */ \
+ *buffer++ \
+ = gcmSETFIELDVALUE(0, AQ_COMMAND_LOAD_STATE_COMMAND, OPCODE, LOAD_STATE) \
+ | gcmSETFIELD (0, AQ_COMMAND_LOAD_STATE_COMMAND, COUNT, 1) \
+ | gcmSETFIELD (0, AQ_COMMAND_LOAD_STATE_COMMAND, ADDRESS, 0x0E02); \
+ \
+ *buffer++ \
+ = gcmSETFIELDVALUE(0, AQ_SEMAPHORE, SOURCE, FRONT_END) \
+ | gcmSETFIELDVALUE(0, AQ_SEMAPHORE, DESTINATION, PIXEL_ENGINE);\
+ \
+ /* STALL FE until PE is done flushing. */ \
+ *buffer++ \
+ = gcmSETFIELDVALUE(0, STALL_COMMAND, OPCODE, STALL); \
+ \
+ *buffer++ \
+ = gcmSETFIELDVALUE(0, STALL_STALL, SOURCE, FRONT_END) \
+ | gcmSETFIELDVALUE(0, STALL_STALL, DESTINATION, PIXEL_ENGINE); \
+ } while(0)
+
+typedef struct _gcsiDEBUG_REGISTERS * gcsiDEBUG_REGISTERS_PTR;
+typedef struct _gcsiDEBUG_REGISTERS
+{
+ gctSTRING module;
+ gctUINT index;
+ gctUINT shift;
+ gctUINT data;
+ gctUINT count;
+ gctUINT32 pipeMask;
+ gctUINT32 selectStart;
+}
+gcsiDEBUG_REGISTERS;
+
+typedef struct _gcsFE_STACK
+{
+ gctSTRING name;
+ gctINT count;
+ gctUINT32 highSelect;
+ gctUINT32 lowSelect;
+ gctUINT32 linkSelect;
+ gctUINT32 clear;
+ gctUINT32 next;
+}
+gcsFE_STACK;
+
+/******************************************************************************\
+********************************* Support Code *********************************
+\******************************************************************************/
+static gctBOOL
+_IsHardwareMatch(
+ IN gckHARDWARE Hardware,
+ IN gctINT32 ChipModel,
+ IN gctUINT32 ChipRevision
+ )
+{
+ return ((Hardware->identity.chipModel == ChipModel) &&
+ (Hardware->identity.chipRevision == ChipRevision));
+}
+
+static gceSTATUS
+_ResetGPU(
+ IN gckHARDWARE Hardware,
+ IN gckOS Os,
+ IN gceCORE Core
+ );
+
+static void
+_GetEcoID(
+ IN gckHARDWARE Hardware,
+ IN OUT gcsHAL_QUERY_CHIP_IDENTITY_PTR Identity
+ )
+{
+ gcmkVERIFY_OK(gckOS_ReadRegisterEx(
+ Hardware->os,
+ Hardware->core,
+ 0x000E8,
+ &Identity->ecoID
+ ));
+
+ if (_IsHardwareMatch(Hardware, 0x1000, 0x5037) && (Identity->chipDate == 0x20120617))
+ {
+ Identity->ecoID = 1;
+ }
+
+ if (_IsHardwareMatch(Hardware, 0x320, 0x5303) && (Identity->chipDate == 0x20140511))
+ {
+ Identity->ecoID = 1;
+ }
+
+}
+
+static gceSTATUS
+_IdentifyHardwareByDatabase(
+ IN gckHARDWARE Hardware,
+ IN gckOS Os,
+ IN gceCORE Core,
+ OUT gcsHAL_QUERY_CHIP_IDENTITY_PTR Identity
+ )
+{
+ gceSTATUS status;
+ gctUINT32 chipIdentity;
+ gctUINT32 debugControl0;
+ gctUINT32 chipInfo;
+ gcsFEATURE_DATABASE *database;
+
+ gcmkHEADER_ARG("Os=0x%x", Os);
+
+ /* Get chip date. */
+ gcmkONERROR(gckOS_ReadRegisterEx(Os, Core, 0x00028, &Identity->chipDate));
+
+ /***************************************************************************
+ ** Get chip ID and revision.
+ */
+
+ /* Read chip identity register. */
+ gcmkONERROR(
+ gckOS_ReadRegisterEx(Os, Core,
+ 0x00018,
+ &chipIdentity));
+
+ /* Special case for older graphic cores. */
+ if (((((gctUINT32) (chipIdentity)) >> (0 ?
+ 31:24) & ((gctUINT32) ((((1 ?
+ 31:24) - (0 ?
+ 31:24) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:24) - (0 ?
+ 31:24) + 1)))))) == (0x01 & ((gctUINT32) ((((1 ?
+ 31:24) - (0 ?
+ 31:24) + 1) == 32) ? ~0U : (~(~0U << ((1 ? 31:24) - (0 ? 31:24) + 1))))))))
+ {
+ Identity->chipModel = gcv500;
+ Identity->chipRevision = (((((gctUINT32) (chipIdentity)) >> (0 ? 15:12)) & ((gctUINT32) ((((1 ? 15:12) - (0 ? 15:12) + 1) == 32) ? ~0U : (~(~0U << ((1 ? 15:12) - (0 ? 15:12) + 1)))))) );
+ }
+
+ else
+ {
+ /* Read chip identity register. */
+ gcmkONERROR(
+ gckOS_ReadRegisterEx(Os, Core,
+ 0x00020,
+ (gctUINT32_PTR) &Identity->chipModel));
+
+ if (((Identity->chipModel & 0xFF00) == 0x0400)
+ && (Identity->chipModel != 0x0420)
+ && (Identity->chipModel != 0x0428))
+ {
+ Identity->chipModel = (gceCHIPMODEL) (Identity->chipModel & 0x0400);
+ }
+
+ /* Read CHIP_REV register. */
+ gcmkONERROR(
+ gckOS_ReadRegisterEx(Os, Core,
+ 0x00024,
+ &Identity->chipRevision));
+
+ if ((Identity->chipModel == gcv300)
+ && (Identity->chipRevision == 0x2201)
+ )
+ {
+ gctUINT32 chipDate;
+ gctUINT32 chipTime;
+
+ /* Read date and time registers. */
+ gcmkONERROR(
+ gckOS_ReadRegisterEx(Os, Core,
+ 0x00028,
+ &chipDate));
+
+ gcmkONERROR(
+ gckOS_ReadRegisterEx(Os, Core,
+ 0x0002C,
+ &chipTime));
+
+ if ((chipDate == 0x20080814) && (chipTime == 0x12051100))
+ {
+ /* This IP has an ECO; put the correct revision in it. */
+ Identity->chipRevision = 0x1051;
+ }
+ }
+
+ gcmkONERROR(
+ gckOS_ReadRegisterEx(Os, Core,
+ 0x000A8,
+ &Identity->productID));
+ }
+
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
+ "Identity: chipModel=%X",
+ Identity->chipModel);
+
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
+ "Identity: chipRevision=%X",
+ Identity->chipRevision);
+
+ _GetEcoID(Hardware, Identity);
+
+ gcmkONERROR(
+ gckOS_ReadRegisterEx(Os, Core,
+ 0x00030,
+ &Identity->customerID));
+
+ /***************************************************************************
+ ** Get chip features.
+ */
+
+ database =
+ Hardware->featureDatabase =
+ gcQueryFeatureDB(
+ Hardware->identity.chipModel,
+ Hardware->identity.chipRevision,
+ Hardware->identity.productID,
+ Hardware->identity.ecoID,
+ Hardware->identity.customerID);
+
+ if (database == gcvNULL)
+ {
+ gcmkPRINT("[galcore]: Feature database is not found,"
+ "chipModel=0x%0x, chipRevision=0x%x, productID=0x%x, ecoID=0x%x, customerID=0x%x",
+ Hardware->identity.chipModel,
+ Hardware->identity.chipRevision,
+ Hardware->identity.productID,
+ Hardware->identity.ecoID,
+ Hardware->identity.customerID);
+ gcmkONERROR(gcvSTATUS_NOT_FOUND);
+ }
+
+ Identity->pixelPipes = database->NumPixelPipes;
+ Identity->resolvePipes = database->NumResolvePipes;
+ Identity->instructionCount = database->InstructionCount;
+ Identity->numConstants = database->NumberOfConstants;
+ Identity->varyingsCount = database->VaryingCount;
+ Identity->gpuCoreCount = database->CoreCount;
+ Identity->streamCount = database->Streams;
+
+ if (Identity->chipModel == gcv320)
+ {
+ gctUINT32 data;
+
+ gcmkONERROR(
+ gckOS_ReadRegisterEx(Os,
+ Core,
+ 0x0002C,
+ &data));
+
+ if ((data != 33956864) &&
+ ((Identity->chipRevision == 0x5007) ||
+ (Identity->chipRevision == 0x5220)))
+ {
+ Hardware->maxOutstandingReads = 0xFF &
+ (Identity->chipRevision == 0x5220 ? 8 :
+ (Identity->chipRevision == 0x5007 ? 12 : 0));
+ }
+ }
+
+ if (_IsHardwareMatch(Hardware, gcv880, 0x5107))
+ {
+ Hardware->maxOutstandingReads = 0x00010;
+ }
+
+ gcmkONERROR(gckOS_ReadRegisterEx(Os, Core, 0x00470, &debugControl0));
+
+ if (debugControl0 & (1 << 16))
+ {
+ Identity->chipFlags |= gcvCHIP_FLAG_MSAA_COHERENCEY_ECO_FIX;
+ }
+
+ gcmkONERROR(gckOS_ReadRegisterEx(Os, Core, 0x000A4, &chipInfo));
+
+ if (((((gctUINT32) (chipInfo)) >> (0 ?
+ 21:21) & ((gctUINT32) ((((1 ?
+ 21:21) - (0 ?
+ 21:21) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 21:21) - (0 ?
+ 21:21) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ?
+ 21:21) - (0 ?
+ 21:21) + 1) == 32) ? ~0U : (~(~0U << ((1 ? 21:21) - (0 ? 21:21) + 1))))))))
+ {
+ Identity->chipFlags |= gcvCHIP_AXI_BUS128_BITS;
+ }
+
+ gckOS_QueryOption(Os, "platformFlagBits", &Identity->platformFlagBits);
+
+ /* Success. */
+ gcmkFOOTER();
+ return gcvSTATUS_OK;
+
+OnError:
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+static gceSTATUS
+_GetHardwareSignature(
+ IN gckHARDWARE Hardware,
+ IN gckOS Os,
+ IN gceCORE Core,
+ OUT gcsHARDWARE_SIGNATURE * Signature
+ )
+{
+ gceSTATUS status;
+
+ gctUINT32 chipIdentity;
+
+ gcmkHEADER_ARG("Os=0x%x", Os);
+
+ /***************************************************************************
+ ** Get chip ID and revision.
+ */
+
+ /* Read chip identity register. */
+ gcmkONERROR(
+ gckOS_ReadRegisterEx(Os, Core,
+ 0x00018,
+ &chipIdentity));
+
+ /* Special case for older graphic cores. */
+ if (((((gctUINT32) (chipIdentity)) >> (0 ?
+ 31:24) & ((gctUINT32) ((((1 ?
+ 31:24) - (0 ?
+ 31:24) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:24) - (0 ?
+ 31:24) + 1)))))) == (0x01 & ((gctUINT32) ((((1 ?
+ 31:24) - (0 ?
+ 31:24) + 1) == 32) ? ~0U : (~(~0U << ((1 ? 31:24) - (0 ? 31:24) + 1))))))))
+ {
+ Signature->chipModel = gcv500;
+ Signature->chipRevision = (((((gctUINT32) (chipIdentity)) >> (0 ? 15:12)) & ((gctUINT32) ((((1 ? 15:12) - (0 ? 15:12) + 1) == 32) ? ~0U : (~(~0U << ((1 ? 15:12) - (0 ? 15:12) + 1)))))) );
+ }
+
+ else
+ {
+ /* Read chip identity register. */
+ gcmkONERROR(
+ gckOS_ReadRegisterEx(Os, Core,
+ 0x00020,
+ (gctUINT32_PTR) &Signature->chipModel));
+
+ /* Read CHIP_REV register. */
+ gcmkONERROR(
+ gckOS_ReadRegisterEx(Os, Core,
+ 0x00024,
+ &Signature->chipRevision));
+ }
+
+ /***************************************************************************
+ ** Get chip features.
+ */
+
+ /* Read chip feature register. */
+ gcmkONERROR(
+ gckOS_ReadRegisterEx(Os, Core,
+ 0x0001C,
+ &Signature->chipFeatures));
+
+ if (((Signature->chipModel == gcv500) && (Signature->chipRevision < 2))
+ || ((Signature->chipModel == gcv300) && (Signature->chipRevision < 0x2000))
+ )
+ {
+ /* GC500 rev 1.x and GC300 rev < 2.0 doesn't have these registers. */
+ Signature->chipMinorFeatures = 0;
+ Signature->chipMinorFeatures1 = 0;
+ Signature->chipMinorFeatures2 = 0;
+ }
+ else
+ {
+ /* Read chip minor feature register #0. */
+ gcmkONERROR(
+ gckOS_ReadRegisterEx(Os, Core,
+ 0x00034,
+ &Signature->chipMinorFeatures));
+
+ if (((((gctUINT32) (Signature->chipMinorFeatures)) >> (0 ?
+ 21:21) & ((gctUINT32) ((((1 ?
+ 21:21) - (0 ?
+ 21:21) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 21:21) - (0 ?
+ 21:21) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ?
+ 21:21) - (0 ?
+ 21:21) + 1) == 32) ? ~0U : (~(~0U << ((1 ? 21:21) - (0 ? 21:21) + 1)))))))
+ )
+ {
+ /* Read chip minor features register #1. */
+ gcmkONERROR(
+ gckOS_ReadRegisterEx(Os, Core,
+ 0x00074,
+ &Signature->chipMinorFeatures1));
+
+ /* Read chip minor features register #2. */
+ gcmkONERROR(
+ gckOS_ReadRegisterEx(Os, Core,
+ 0x00084,
+ &Signature->chipMinorFeatures2));
+ }
+ else
+ {
+ /* Chip doesn't has minor features register #1 or 2 or 3 or 4 or 5. */
+ Signature->chipMinorFeatures1 = 0;
+ Signature->chipMinorFeatures2 = 0;
+ }
+ }
+
+ /* Success. */
+ gcmkFOOTER();
+ return gcvSTATUS_OK;
+
+OnError:
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+/* Set to 1 to enable module clock gating debug function.
+* Following options take effect when it is set to 1.
+*/
+#define gcdDEBUG_MODULE_CLOCK_GATING 0
+/* Set to 1 to disable module clock gating of all modules. */
+#define gcdDISABLE_MODULE_CLOCK_GATING 0
+/* Set to 1 to disable module clock gating of each module. */
+#define gcdDISABLE_STARVE_MODULE_CLOCK_GATING 0
+#define gcdDISABLE_FE_CLOCK_GATING 0
+#define gcdDISABLE_PE_CLOCK_GATING 0
+#define gcdDISABLE_SH_CLOCK_GATING 0
+#define gcdDISABLE_PA_CLOCK_GATING 0
+#define gcdDISABLE_SE_CLOCK_GATING 0
+#define gcdDISABLE_RA_CLOCK_GATING 0
+#define gcdDISABLE_RA_EZ_CLOCK_GATING 0
+#define gcdDISABLE_RA_HZ_CLOCK_GATING 0
+#define gcdDISABLE_TX_CLOCK_GATING 0
+#define gcdDISABLE_TFB_CLOCK_GATING 0
+#define gcdDISABLE_GPIPE_CLOCK_GATING 0
+#define gcdDISABLE_BLT_CLOCK_GATING 0
+#define gcdDISABLE_TPG_CLOCK_GATING 0
+#define gcdDISABLE_VX_CLOCK_GATING 0
+
+#if gcdDEBUG_MODULE_CLOCK_GATING
+gceSTATUS
+_ConfigureModuleLevelClockGating(
+ gckHARDWARE Hardware
+ )
+{
+ gctUINT32 data;
+
+ gcmkVERIFY_OK(
+ gckOS_ReadRegisterEx(Hardware->os,
+ Hardware->core,
+ Hardware->powerBaseAddress
+ + 0x00104,
+ &data));
+
+#if gcdDISABLE_FE_CLOCK_GATING
+ data = ((((gctUINT32) (data)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1))))))) << (0 ?
+ 0:0))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)));
+#endif
+
+#if gcdDISABLE_PE_CLOCK_GATING
+ data = ((((gctUINT32) (data)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 2:2) - (0 ?
+ 2:2) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 2:2) - (0 ?
+ 2:2) + 1))))))) << (0 ?
+ 2:2))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 2:2) - (0 ?
+ 2:2) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 2:2) - (0 ? 2:2) + 1))))))) << (0 ? 2:2)));
+#endif
+
+#if gcdDISABLE_SH_CLOCK_GATING
+ data = ((((gctUINT32) (data)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 3:3) - (0 ?
+ 3:3) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 3:3) - (0 ?
+ 3:3) + 1))))))) << (0 ?
+ 3:3))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 3:3) - (0 ?
+ 3:3) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 3:3) - (0 ? 3:3) + 1))))))) << (0 ? 3:3)));
+#endif
+
+#if gcdDISABLE_PA_CLOCK_GATING
+ data = ((((gctUINT32) (data)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 4:4) - (0 ?
+ 4:4) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 4:4) - (0 ?
+ 4:4) + 1))))))) << (0 ?
+ 4:4))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 4:4) - (0 ?
+ 4:4) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 4:4) - (0 ? 4:4) + 1))))))) << (0 ? 4:4)));
+#endif
+
+#if gcdDISABLE_SE_CLOCK_GATING
+ data = ((((gctUINT32) (data)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 5:5) - (0 ?
+ 5:5) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 5:5) - (0 ?
+ 5:5) + 1))))))) << (0 ?
+ 5:5))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 5:5) - (0 ?
+ 5:5) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 5:5) - (0 ? 5:5) + 1))))))) << (0 ? 5:5)));
+#endif
+
+#if gcdDISABLE_RA_CLOCK_GATING
+ data = ((((gctUINT32) (data)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 6:6) - (0 ?
+ 6:6) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 6:6) - (0 ?
+ 6:6) + 1))))))) << (0 ?
+ 6:6))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 6:6) - (0 ?
+ 6:6) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 6:6) - (0 ? 6:6) + 1))))))) << (0 ? 6:6)));
+#endif
+
+#if gcdDISABLE_TX_CLOCK_GATING
+ data = ((((gctUINT32) (data)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 7:7) - (0 ?
+ 7:7) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 7:7) - (0 ?
+ 7:7) + 1))))))) << (0 ?
+ 7:7))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 7:7) - (0 ?
+ 7:7) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 7:7) - (0 ? 7:7) + 1))))))) << (0 ? 7:7)));
+#endif
+
+#if gcdDISABLE_RA_EZ_CLOCK_GATING
+ data = ((((gctUINT32) (data)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 16:16) - (0 ?
+ 16:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 16:16) - (0 ?
+ 16:16) + 1))))))) << (0 ?
+ 16:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 16:16) - (0 ?
+ 16:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 16:16) - (0 ? 16:16) + 1))))))) << (0 ? 16:16)));
+#endif
+
+#if gcdDISABLE_RA_HZ_CLOCK_GATING
+ data = ((((gctUINT32) (data)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 17:17) - (0 ?
+ 17:17) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 17:17) - (0 ?
+ 17:17) + 1))))))) << (0 ?
+ 17:17))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 17:17) - (0 ?
+ 17:17) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 17:17) - (0 ? 17:17) + 1))))))) << (0 ? 17:17)));
+#endif
+
+#if gcdDISABLE_TFB_CLOCK_GATING
+ data = ((((gctUINT32) (data)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 19:19) - (0 ?
+ 19:19) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 19:19) - (0 ?
+ 19:19) + 1))))))) << (0 ?
+ 19:19))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 19:19) - (0 ?
+ 19:19) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 19:19) - (0 ? 19:19) + 1))))))) << (0 ? 19:19)));
+#endif
+
+#if gcdDISABLE_GPIPE_CLOCK_GATING
+ data = ((((gctUINT32) (data)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 22:22) - (0 ?
+ 22:22) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 22:22) - (0 ?
+ 22:22) + 1))))))) << (0 ?
+ 22:22))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 22:22) - (0 ?
+ 22:22) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 22:22) - (0 ? 22:22) + 1))))))) << (0 ? 22:22)));
+#endif
+
+#if gcdDISABLE_BLT_CLOCK_GATING
+ data = ((((gctUINT32) (data)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 20:20) - (0 ?
+ 20:20) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 20:20) - (0 ?
+ 20:20) + 1))))))) << (0 ?
+ 20:20))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 20:20) - (0 ?
+ 20:20) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 20:20) - (0 ? 20:20) + 1))))))) << (0 ? 20:20)));
+#endif
+
+#if gcdDISABLE_TPG_CLOCK_GATING
+ data = ((((gctUINT32) (data)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 18:18) - (0 ?
+ 18:18) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 18:18) - (0 ?
+ 18:18) + 1))))))) << (0 ?
+ 18:18))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 18:18) - (0 ?
+ 18:18) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 18:18) - (0 ? 18:18) + 1))))))) << (0 ? 18:18)));
+#endif
+
+#if gcdDISABLE_VX_CLOCK_GATING
+ data = ((((gctUINT32) (data)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 21:21) - (0 ?
+ 21:21) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 21:21) - (0 ?
+ 21:21) + 1))))))) << (0 ?
+ 21:21))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 21:21) - (0 ?
+ 21:21) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 21:21) - (0 ? 21:21) + 1))))))) << (0 ? 21:21)));
+#endif
+
+ gcmkVERIFY_OK(
+ gckOS_WriteRegisterEx(Hardware->os,
+ Hardware->core,
+ Hardware->powerBaseAddress
+ + 0x00104,
+ data));
+
+#if gcdDISABLE_STARVE_MODULE_CLOCK_GATING
+ gcmkVERIFY_OK(
+ gckOS_ReadRegisterEx(Hardware->os,
+ Hardware->core,
+ Hardware->powerBaseAddress +
+ 0x00100,
+ &data));
+
+ data = ((((gctUINT32) (data)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 2:2) - (0 ?
+ 2:2) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 2:2) - (0 ?
+ 2:2) + 1))))))) << (0 ?
+ 2:2))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 2:2) - (0 ?
+ 2:2) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 2:2) - (0 ? 2:2) + 1))))))) << (0 ? 2:2)));
+
+ gcmkVERIFY_OK(
+ gckOS_WriteRegisterEx(Hardware->os,
+ Hardware->core,
+ Hardware->powerBaseAddress
+ + 0x00100,
+ data));
+
+#endif
+
+#if gcdDISABLE_MODULE_CLOCK_GATING
+ gcmkVERIFY_OK(
+ gckOS_ReadRegisterEx(Hardware->os,
+ Hardware->core,
+ Hardware->powerBaseAddress +
+ 0x00100,
+ &data));
+
+ data = ((((gctUINT32) (data)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1))))))) << (0 ?
+ 0:0))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)));
+
+
+ gcmkVERIFY_OK(
+ gckOS_WriteRegisterEx(Hardware->os,
+ Hardware->core,
+ Hardware->powerBaseAddress
+ + 0x00100,
+ data));
+#endif
+
+ return gcvSTATUS_OK;
+}
+#endif
+
+#if gcdPOWEROFF_TIMEOUT
+void
+_PowerTimerFunction(
+ gctPOINTER Data
+ )
+{
+ gckHARDWARE hardware = (gckHARDWARE)Data;
+ gcmkVERIFY_OK(
+ gckHARDWARE_SetPowerManagementState(hardware, gcvPOWER_OFF_TIMEOUT));
+}
+#endif
+
+static gceSTATUS
+_VerifyDMA(
+ IN gckOS Os,
+ IN gceCORE Core,
+ gctUINT32_PTR Address1,
+ gctUINT32_PTR Address2,
+ gctUINT32_PTR State1,
+ gctUINT32_PTR State2
+ )
+{
+ gceSTATUS status;
+ gctUINT32 i;
+
+ gcmkONERROR(gckOS_ReadRegisterEx(Os, Core, 0x00660, State1));
+ gcmkONERROR(gckOS_ReadRegisterEx(Os, Core, 0x00660, State1));
+ gcmkONERROR(gckOS_ReadRegisterEx(Os, Core, 0x00664, Address1));
+ gcmkONERROR(gckOS_ReadRegisterEx(Os, Core, 0x00664, Address1));
+
+ for (i = 0; i < 500; i += 1)
+ {
+ gcmkONERROR(gckOS_ReadRegisterEx(Os, Core, 0x00660, State2));
+ gcmkONERROR(gckOS_ReadRegisterEx(Os, Core, 0x00660, State2));
+ gcmkONERROR(gckOS_ReadRegisterEx(Os, Core, 0x00664, Address2));
+ gcmkONERROR(gckOS_ReadRegisterEx(Os, Core, 0x00664, Address2));
+
+ if (*Address1 != *Address2)
+ {
+ break;
+ }
+
+ if (*State1 != *State2)
+ {
+ break;
+ }
+ }
+
+OnError:
+ return status;
+}
+
+static gceSTATUS
+_DumpDebugRegisters(
+ IN gckOS Os,
+ IN gceCORE Core,
+ IN gcsiDEBUG_REGISTERS_PTR Descriptor
+ )
+{
+/* If this value is changed, print formats need to be changed too. */
+#define REG_PER_LINE 8
+ gceSTATUS status = gcvSTATUS_OK;
+ gctUINT32 select;
+ gctUINT i, j, pipe;
+ gctUINT32 datas[REG_PER_LINE];
+ gctUINT32 oldControl, control;
+
+ gcmkHEADER_ARG("Os=0x%X Descriptor=0x%X", Os, Descriptor);
+
+ /* Record control. */
+ gckOS_ReadRegisterEx(Os, Core, 0x0, &oldControl);
+
+ for (pipe = 0; pipe < 2; pipe++)
+ {
+ if (!(Descriptor->pipeMask & (1 << pipe)))
+ {
+ continue;
+ }
+
+ gcmkPRINT_N(8, " %s[%d] debug registers:\n", Descriptor->module, pipe);
+
+ /* Switch pipe. */
+ gcmkONERROR(gckOS_ReadRegisterEx(Os, Core, 0x0, &control));
+ control &= ~(0xF << 20);
+ control |= (pipe << 20);
+ gcmkONERROR(gckOS_WriteRegisterEx(Os, Core, 0x0, control));
+
+ gcmkASSERT(!(Descriptor->count % REG_PER_LINE));
+
+ for (i = 0; i < Descriptor->count; i += REG_PER_LINE)
+ {
+ /* Select of first one in the group. */
+ select = i + Descriptor->selectStart;
+
+ /* Read a group of registers. */
+ for (j = 0; j < REG_PER_LINE; j++)
+ {
+ /* Shift select to right position. */
+ gcmkONERROR(gckOS_WriteRegisterEx(Os, Core, Descriptor->index, (select + j) << Descriptor->shift));
+ gcmkONERROR(gckOS_ReadRegisterEx(Os, Core, Descriptor->data, &datas[j]));
+ }
+
+ gcmkPRINT_N(32, " [%02X] %08X %08X %08X %08X %08X %08X %08X %08X\n",
+ select, datas[0], datas[1], datas[2], datas[3], datas[4], datas[5], datas[6], datas[7]);
+ }
+ }
+
+ /* Restore control. */
+ gcmkONERROR(gckOS_WriteRegisterEx(Os, Core, 0x0, oldControl));
+
+OnError:
+ /* Return the error. */
+ gcmkFOOTER();
+ return status;
+}
+
+static gceSTATUS
+_DumpLinkStack(
+ IN gckOS Os,
+ IN gceCORE Core,
+ IN gcsiDEBUG_REGISTERS_PTR Descriptor
+ )
+{
+ /* Get wrptr */
+ gctUINT32 shift = Descriptor->shift;
+ gctUINT32 pointerSelect = 0xE << shift;
+ gctUINT32 pointer, wrPtr, rdPtr, links[16];
+ gctUINT32 stackSize = 16;
+ gctUINT32 oldestPtr = 0;
+ gctUINT32 i;
+
+ gcmkVERIFY_OK(gckOS_WriteRegisterEx(Os, Core, Descriptor->index, pointerSelect));
+ gcmkVERIFY_OK(gckOS_ReadRegisterEx(Os, Core, Descriptor->data, &pointer));
+
+ wrPtr = (pointer & 0xF0) >> 4;
+ rdPtr = pointer & 0xF;
+
+ /* Move rdptr to the oldest one (next one to the latest one. ) */
+ oldestPtr = (wrPtr + 1) % stackSize;
+
+ while (rdPtr != oldestPtr)
+ {
+ gcmkVERIFY_OK(gckOS_WriteRegisterEx(Os, Core, Descriptor->index, 0x0));
+ gcmkVERIFY_OK(gckOS_WriteRegisterEx(Os, Core, Descriptor->index, 0xF << shift));
+
+
+ gcmkVERIFY_OK(gckOS_WriteRegisterEx(Os, Core, Descriptor->index, pointerSelect));
+ gcmkVERIFY_OK(gckOS_ReadRegisterEx(Os, Core, Descriptor->data, &pointer));
+
+ rdPtr = pointer & 0xF;
+ }
+
+ gcmkPRINT(" Link stack:");
+
+ /* Read from stack bottom*/
+ for (i = 0; i < stackSize; i++)
+ {
+ gcmkVERIFY_OK(gckOS_WriteRegisterEx(Os, Core, Descriptor->index, 0xD << shift));
+ gcmkVERIFY_OK(gckOS_ReadRegisterEx(Os, Core, Descriptor->data, &links[i]));
+
+ /* Advance rdPtr. */
+ gcmkVERIFY_OK(gckOS_WriteRegisterEx(Os, Core, Descriptor->index, 0x0));
+ gcmkVERIFY_OK(gckOS_WriteRegisterEx(Os, Core, Descriptor->index, 0xF << shift));
+ }
+
+ /* Print. */
+ for (i = 0; i < stackSize; i += 4)
+ {
+ gcmkPRINT_N(32, " [0x%02X] 0x%08X [0x%02X] 0x%08X [0x%02X] 0x%08X [0x%02X] 0x%08X\n",
+ i, links[i], i + 1, links[i + 1], i + 2, links[i + 2], i + 3, links[i + 3]);
+ }
+
+ return gcvSTATUS_OK;
+}
+
+static gceSTATUS
+_DumpFEStack(
+ IN gckOS Os,
+ IN gceCORE Core,
+ IN gcsiDEBUG_REGISTERS_PTR Descriptor
+ )
+{
+ gctUINT i;
+ gctINT j;
+ gctUINT32 stack[32][2];
+ gctUINT32 link[32];
+
+ static gcsFE_STACK _feStacks[] =
+ {
+ { "PRE_STACK", 32, 0x1A, 0x9A, 0x00, 0x1B, 0x1E },
+ { "CMD_STACK", 32, 0x1C, 0x9C, 0x1E, 0x1D, 0x1E },
+ };
+
+ for (i = 0; i < gcmCOUNTOF(_feStacks); i++)
+ {
+ gckOS_WriteRegisterEx(Os, Core, Descriptor->index, _feStacks[i].clear);
+
+ for (j = 0; j < _feStacks[i].count; j++)
+ {
+ gckOS_WriteRegisterEx(Os, Core, Descriptor->index, _feStacks[i].highSelect);
+
+ gckOS_ReadRegisterEx(Os, Core, Descriptor->data, &stack[j][0]);
+
+ gckOS_WriteRegisterEx(Os, Core, Descriptor->index, _feStacks[i].lowSelect);
+
+ gckOS_ReadRegisterEx(Os, Core, Descriptor->data, &stack[j][1]);
+
+ gckOS_WriteRegisterEx(Os, Core, Descriptor->index, _feStacks[i].next);
+
+ if (_feStacks[i].linkSelect)
+ {
+ gckOS_WriteRegisterEx(Os, Core, Descriptor->index, _feStacks[i].linkSelect);
+
+ gckOS_ReadRegisterEx(Os, Core, Descriptor->data, &link[j]);
+ }
+ }
+
+ gcmkPRINT(" %s:", _feStacks[i].name);
+
+ for (j = 31; j >= 3; j -= 4)
+ {
+ gcmkPRINT(" %08X %08X %08X %08X %08X %08X %08X %08X",
+ stack[j][0], stack[j][1], stack[j - 1][0], stack[j - 1][1],
+ stack[j - 2][0], stack[j - 2][1], stack[j - 3][0], stack[j - 3][1]);
+ }
+
+ if (_feStacks[i].linkSelect)
+ {
+ gcmkPRINT(" LINK_STACK:");
+
+ for (j = 31; j >= 3; j -= 4)
+ {
+ gcmkPRINT(" %08X %08X %08X %08X %08X %08X %08X %08X",
+ link[j], link[j], link[j - 1], link[j - 1],
+ link[j - 2], link[j - 2], link[j - 3], link[j - 3]);
+ }
+ }
+
+ }
+
+ return gcvSTATUS_OK;
+}
+
+static gceSTATUS
+_IsGPUPresent(
+ IN gckHARDWARE Hardware
+ )
+{
+ gceSTATUS status;
+ gcsHARDWARE_SIGNATURE signature;
+ gctUINT32 control;
+
+ gcmkHEADER_ARG("Hardware=0x%x", Hardware);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
+
+ gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x00000,
+ &control));
+
+ control = ((((gctUINT32) (control)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 1:1) - (0 ?
+ 1:1) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 1:1) - (0 ?
+ 1:1) + 1))))))) << (0 ?
+ 1:1))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ?
+ 1:1) - (0 ?
+ 1:1) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1)));
+ control = ((((gctUINT32) (control)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1))))))) << (0 ?
+ 0:0))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)));
+
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x00000,
+ control));
+
+ gckOS_ZeroMemory((gctPOINTER)&signature, gcmSIZEOF(gcsHARDWARE_SIGNATURE));
+
+ /* Identify the hardware. */
+ gcmkONERROR(_GetHardwareSignature(Hardware,
+ Hardware->os,
+ Hardware->core,
+ &signature));
+
+ /* Check if these are the same values as saved before. */
+ if ((Hardware->signature.chipModel != signature.chipModel)
+ || (Hardware->signature.chipRevision != signature.chipRevision)
+ || (Hardware->signature.chipFeatures != signature.chipFeatures)
+ || (Hardware->signature.chipMinorFeatures != signature.chipMinorFeatures)
+ || (Hardware->signature.chipMinorFeatures1 != signature.chipMinorFeatures1)
+ || (Hardware->signature.chipMinorFeatures2 != signature.chipMinorFeatures2)
+ )
+ {
+ gcmkPRINT("[galcore]: GPU is not present.");
+ gcmkONERROR(gcvSTATUS_GPU_NOT_RESPONDING);
+ }
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ /* Return the error. */
+ gcmkFOOTER();
+ return status;
+}
+
+gceSTATUS
+_FlushCache(
+ gckHARDWARE Hardware,
+ gckCOMMAND Command
+ )
+{
+ gceSTATUS status;
+ gctUINT32 bytes, requested;
+ gctPOINTER buffer;
+
+ /* Get the size of the flush command. */
+ gcmkONERROR(gckHARDWARE_Flush(Hardware,
+ gcvFLUSH_ALL,
+ gcvNULL,
+ &requested));
+
+ /* Reserve space in the command queue. */
+ gcmkONERROR(gckCOMMAND_Reserve(Command,
+ requested,
+ &buffer,
+ &bytes));
+
+ /* Append a flush. */
+ gcmkONERROR(gckHARDWARE_Flush(
+ Hardware, gcvFLUSH_ALL, buffer, &bytes
+ ));
+
+ /* Execute the command queue. */
+ gcmkONERROR(gckCOMMAND_Execute(Command, requested));
+
+ return gcvSTATUS_OK;
+
+OnError:
+ return status;
+}
+
+static gctBOOL
+_IsGPUIdle(
+ IN gctUINT32 Idle
+ )
+{
+ return Idle == 0x7FFFFFFF;
+}
+
+gctBOOL
+_QueryFeatureDatabase(
+ IN gckHARDWARE Hardware,
+ IN gceFEATURE Feature
+ )
+{
+ gctBOOL available;
+
+ gcsFEATURE_DATABASE *database = Hardware->featureDatabase;
+
+ gcmkHEADER_ARG("Hardware=0x%x Feature=%d", Hardware, Feature);
+
+ /* Only features needed by common kernel logic added here. */
+ switch (Feature)
+ {
+ case gcvFEATURE_END_EVENT:
+ available = gcvFALSE;
+ break;
+
+ case gcvFEATURE_MC20:
+ available = database->REG_MC20;
+ break;
+
+ case gcvFEATURE_EARLY_Z:
+ available = database->REG_NoEZ == 0;
+ break;
+
+ case gcvFEATURE_HZ:
+ available = database->REG_HierarchicalZ;
+ break;
+
+ case gcvFEATURE_NEW_HZ:
+ available = database->REG_NewHZ;
+ break;
+
+ case gcvFEATURE_FAST_MSAA:
+ available = database->REG_FastMSAA;
+ break;
+
+ case gcvFEATURE_SMALL_MSAA:
+ available = database->REG_SmallMSAA;
+ break;
+
+ case gcvFEATURE_DYNAMIC_FREQUENCY_SCALING:
+ /* This feature doesn't apply for 2D cores. */
+ available = database->REG_DynamicFrequencyScaling && database->REG_Pipe3D;
+
+ if (Hardware->identity.chipModel == gcv1000 &&
+ (Hardware->identity.chipRevision == 0x5039 ||
+ Hardware->identity.chipRevision == 0x5040))
+ {
+ available = gcvFALSE;
+ }
+ break;
+
+ case gcvFEATURE_ACE:
+ available = database->REG_ACE;
+ break;
+
+ case gcvFEATURE_HALTI2:
+ available = database->REG_Halti2;
+ break;
+
+ case gcvFEATURE_PIPE_2D:
+ available = database->REG_Pipe2D;
+ break;
+
+ case gcvFEATURE_PIPE_3D:
+#if gcdENABLE_3D
+ available = database->REG_Pipe3D;
+#else
+ available = gcvFALSE;
+#endif
+ break;
+
+ case gcvFEATURE_FC_FLUSH_STALL:
+ available = database->REG_FcFlushStall;
+ break;
+
+ case gcvFEATURE_BLT_ENGINE:
+ available = database->REG_BltEngine;
+ break;
+
+ case gcvFEATURE_HALTI0:
+ available = database->REG_Halti0;
+ break;
+
+ case gcvFEATURE_FE_ALLOW_STALL_PREFETCH_ENG:
+ available = database->REG_FEAllowStallPrefetchEng;
+ break;
+
+ case gcvFEATURE_MMU:
+ available = database->REG_MMU;
+ break;
+
+ case gcvFEATURE_FENCE_64BIT:
+ available = database->FENCE_64BIT;
+ break;
+
+ case gcvFEATURE_TEX_BASELOD:
+ available = database->REG_Halti2;
+
+ if (_IsHardwareMatch(Hardware, gcv900, 0x5250))
+ {
+ available = gcvTRUE;
+ }
+ break;
+
+ case gcvFEATURE_TEX_CACHE_FLUSH_FIX:
+ available = database->REG_Halti5;
+ break;
+
+ case gcvFEATURE_BUG_FIXES1:
+ available = database->REG_BugFixes1;
+ break;
+
+ case gcvFEATURE_MULTI_SOURCE_BLT:
+ available = database->REG_MultiSourceBlt;
+ break;
+
+ case gcvFEATURE_HALTI5:
+ available = database->REG_Halti5;
+ break;
+
+ case gcvFEATURE_FAST_CLEAR:
+ available = database->REG_FastClear;
+
+ if (Hardware->identity.chipModel == gcv700)
+ {
+ available = gcvFALSE;
+ }
+ break;
+
+ case gcvFEATURE_BUG_FIXES7:
+ available = database->REG_BugFixes7;
+ break;
+
+ case gcvFEATURE_ZCOMPRESSION:
+ available = database->REG_ZCompression;
+ break;
+
+ case gcvFEATURE_SHADER_HAS_INSTRUCTION_CACHE:
+ available = database->REG_InstructionCache;
+ break;
+
+ case gcvFEATURE_YUV420_TILER:
+ available = database->REG_YUV420Tiler;
+ break;
+
+ case gcvFEATURE_2DPE20:
+ available = database->REG_2DPE20;
+ break;
+
+ case gcvFEATURE_DITHER_AND_FILTER_PLUS_ALPHA_2D:
+ available = database->REG_DitherAndFilterPlusAlpha2D;
+ break;
+
+ case gcvFEATURE_ONE_PASS_2D_FILTER:
+ available = database->REG_OnePass2DFilter;
+ break;
+
+ case gcvFEATURE_HALTI1:
+ available = database->REG_Halti1;
+ break;
+
+ case gcvFEATURE_HALTI3:
+ available = database->REG_Halti3;
+ break;
+
+ case gcvFEATURE_HALTI4:
+ available = database->REG_Halti4;
+ break;
+
+ case gcvFEATURE_GEOMETRY_SHADER:
+ available = database->REG_GeometryShader;
+ break;
+
+ case gcvFEATURE_TESSELLATION:
+ available = database->REG_TessellationShaders;
+ break;
+
+ case gcvFEATURE_GENERIC_ATTRIB:
+ available = database->REG_Generics;
+ break;
+
+ case gcvFEATURE_TEXTURE_LINEAR:
+ available = database->REG_LinearTextureSupport;
+ break;
+
+ case gcvFEATURE_TX_FILTER:
+ available = database->REG_TXFilter;
+ break;
+
+ case gcvFEATURE_TX_SUPPORT_DEC:
+ available = database->REG_TXSupportDEC;
+ break;
+
+ case gcvFEATURE_TX_FRAC_PRECISION_6BIT:
+ available = database->REG_TX6bitFrac;
+ break;
+
+ case gcvFEATURE_TEXTURE_ASTC:
+ available = database->REG_TXEnhancements4 && !database->NO_ASTC;
+ break;
+
+ case gcvFEATURE_SHADER_ENHANCEMENTS2:
+ available = database->REG_SHEnhancements2;
+ break;
+
+ case gcvFEATURE_BUG_FIXES18:
+ available = database->REG_BugFixes18;
+ break;
+
+ case gcvFEATURE_64K_L2_CACHE:
+ available = gcvFALSE;
+ break;
+
+ case gcvFEATURE_BUG_FIXES4:
+ available = database->REG_BugFixes4;
+ break;
+
+ case gcvFEATURE_BUG_FIXES12:
+ available = database->REG_BugFixes12;
+ break;
+
+ case gcvFEATURE_HW_TFB:
+ available = database->HWTFB;
+ break;
+
+ case gcvFEATURE_SNAPPAGE_CMD_FIX:
+ available = database->SH_SNAP2PAGE_FIX;
+ break;
+
+ case gcvFEATURE_SECURITY:
+ available = database->SECURITY;
+ break;
+
+ case gcvFEATURE_TX_DESCRIPTOR:
+ available = database->REG_Halti5;
+ break;
+
+ case gcvFEATURE_TX_DESC_CACHE_CLOCKGATE_FIX:
+ available = database->TX_DESC_CACHE_CLOCKGATE_FIX;
+ break;
+
+ case gcvFEATURE_ROBUSTNESS:
+ available = database->ROBUSTNESS;
+ break;
+
+ case gcvFEATURE_SNAPPAGE_CMD:
+ available = database->SNAPPAGE_CMD;
+ break;
+
+ case gcvFEATURE_HALF_FLOAT_PIPE:
+ available = database->REG_HalfFloatPipe;
+ break;
+
+ case gcvFEATURE_SH_INSTRUCTION_PREFETCH:
+ available = database->SH_ICACHE_PREFETCH;
+ break;
+
+ case gcvFEATURE_FE_NEED_DUMMYDRAW:
+ available = database->FE_NEED_DUMMYDRAW;
+ break;
+
+ case gcvFEATURE_DEC300_COMPRESSION:
+ available = database->REG_DEC;
+ break;
+
+ case gcvFEATURE_DEC400_COMPRESSION:
+ available = database->G2D_DEC400;
+ break;
+
+ case gcvFEATURE_TPC_COMPRESSION:
+ available = database->REG_ThirdPartyCompression;
+ break;
+
+ case gcvFEATURE_TPCV11_COMPRESSION:
+ available = database->G2D_3rd_PARTY_COMPRESSION_1_1;
+ break;
+
+ case gcvFEATURE_USC_DEFER_FILL_FIX:
+ available = database->USC_DEFER_FILL_FIX;
+ break;
+
+ case gcvFEATURE_USC:
+ available = database->REG_Halti5;
+ break;
+
+ case gcvFEATURE_RA_CG_FIX:
+ available = database->RA_CG_FIX;
+ break;
+
+ case gcvFEATURE_ZERO_ATTRIB_SUPPORT:
+ available = database->REG_Halti4;
+ break;
+
+ case gcvFEATURE_SH_CLOCK_GATE_FIX:
+ available = database->SH_CLOCK_GATE_FIX;
+ break;
+
+ case gcvFEATURE_GPIPE_CLOCK_GATE_FIX:
+ available = gcvTRUE;
+ break;
+
+ case gcvFEATURE_NEW_GPIPE:
+ available = database->NEW_GPIPE;
+ break;
+
+ case gcvFEATURE_MULTI_CORE_BLOCK_SET_CONFIG2:
+ available = database->MULTI_CORE_BLOCK_SET_CONFIG2;
+ break;
+
+ case gcvFEATURE_SECURITY_AHB:
+ available = database->SECURITY_AHB;
+ break;
+
+ case gcvFEATURE_ASYNC_BLIT:
+ available = database->ASYNC_BLT;
+ break;
+
+ case gcvFEATURE_COMPUTE_ONLY:
+ available = database->COMPUTE_ONLY;
+ break;
+
+ case gcvFEATURE_USC_FULLCACHE_FIX:
+ available = database->USC_FULL_CACHE_FIX;
+ break;
+
+ case gcvFEATURE_PE_TILE_CACHE_FLUSH_FIX:
+ available = database->PE_TILE_CACHE_FLUSH_FIX;
+ break;
+
+ case gcvFEATURE_TILE_STATUS_2BITS:
+ available = database->REG_TileStatus2Bits;
+ break;
+
+ case gcvFEATURE_COMPRESSION_DEC400:
+ available = database->DEC400;
+ break;
+
+ default:
+ gcmkFATAL("Invalid feature has been requested.");
+ available = gcvFALSE;
+ }
+
+ gcmkFOOTER_ARG("%d", available ? gcvSTATUS_TRUE : gcvSTATUS_FALSE);
+ return available;
+}
+
+static void
+_ConfigurePolicyID(
+ IN gckHARDWARE Hardware
+ )
+{
+ gceSTATUS status;
+ gctUINT32 policyID;
+ gctUINT32 auxBit = ~0U;
+ gctUINT32 axiConfig;
+ gckOS os = Hardware->os;
+ gceCORE core = Hardware->core;
+ gctUINT32 i;
+ gctUINT32 offset;
+ gctUINT32 shift;
+ gctUINT32 currentAxiConfig;
+
+ status = gckOS_GetPolicyID(os, gcvSURF_TYPE_UNKNOWN, &policyID, &axiConfig);
+
+ if (status == gcvSTATUS_NOT_SUPPORTED)
+ {
+ /* No customized policyID setting. */
+ return;
+ }
+
+ for (i = 0; i < 16; i++)
+ {
+ /* Mapping 16 surface type.*/
+ status = gckOS_GetPolicyID(os, (gceSURF_TYPE) i, &policyID, &axiConfig);
+
+ if (gcmIS_SUCCESS(status))
+ {
+ if (auxBit == ~0U)
+ {
+ /* There is a customized policyID setting for this type. */
+ auxBit = (policyID >> 4) & 0x1;
+ }
+ else
+ {
+ /* Check whether this bit changes. */
+ if (auxBit != ((policyID >> 4) & 0x1))
+ {
+ gcmkPRINT("[galcore]: AUX_BIT changes");
+ return;
+ }
+ }
+
+ offset = policyID >> 1;
+
+ shift = (policyID & 0x1) * 16;
+
+ axiConfig &= 0xFFFF;
+
+ gcmkVERIFY_OK(gckOS_ReadRegisterEx(
+ os,
+ core,
+ (0x0070 + offset) << 2,
+ &currentAxiConfig
+ ));
+
+ currentAxiConfig |= (axiConfig << shift);
+
+ gcmkVERIFY_OK(gckOS_WriteRegisterEx(
+ os,
+ core,
+ (0x0070 + offset) << 2,
+ currentAxiConfig
+ ));
+ }
+ }
+
+ if (auxBit != ~0U)
+ {
+ gcmkVERIFY_OK(gckOS_WriteRegisterEx(
+ os,
+ core,
+ 0x000EC,
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1))))))) << (0 ?
+ 7:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 8:8) - (0 ?
+ 8:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 8:8) - (0 ?
+ 8:8) + 1))))))) << (0 ?
+ 8:8))) | (((gctUINT32) ((gctUINT32) (auxBit) & ((gctUINT32) ((((1 ?
+ 8:8) - (0 ?
+ 8:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 8:8) - (0 ? 8:8) + 1))))))) << (0 ? 8:8)))
+ ));
+ }
+}
+/****************************
+** Initialise hardware options
+*/
+static void
+_SetHardwareOptions(
+ IN gckHARDWARE Hardware
+ )
+{
+ gceSTATUS status;
+ gcsHAL_QUERY_CHIP_OPTIONS *options = &Hardware->options;
+
+ status = gckOS_QueryOption(Hardware->os, "powerManagement", (gctUINT32*)&options->powerManagement);
+
+ if (status == gcvSTATUS_NOT_SUPPORTED)
+ {
+ /* Enable power management by default. */
+ Hardware->options.powerManagement = gcvTRUE;
+ }
+
+ /* Disable profiler by default */
+ status = gckOS_QueryOption(Hardware->os, "gpuProfiler", (gctUINT32*)&options->gpuProfiler);
+ if (status == gcvSTATUS_NOT_SUPPORTED)
+ {
+ /* Disable profiler by default */
+ Hardware->options.gpuProfiler= gcvFALSE;
+ }
+ gckOS_QueryOption(Hardware->os, "mmu", (gctUINT32_PTR)&options->enableMMU);
+
+ if (gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_USC))
+ {
+ gctUINT L1cacheSize;
+ gcsFEATURE_DATABASE *database = Hardware->featureDatabase;
+
+ if (gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_COMPUTE_ONLY))
+ {
+ L1cacheSize = database->L1CacheSize;
+ }
+ else
+ {
+ gctUINT attribBufSizeInKB;
+ if (gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_TESSELLATION))
+ {
+ /* GS/TS must be bundled. */
+ gcmkASSERT(gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_GEOMETRY_SHADER));
+ attribBufSizeInKB = 42;
+ }
+ else
+ {
+ gcmkASSERT(!gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_GEOMETRY_SHADER));
+ attribBufSizeInKB = 8;
+ }
+
+ if (attribBufSizeInKB < database->USC_MAX_PAGES)
+ {
+ L1cacheSize = database->USC_MAX_PAGES - attribBufSizeInKB;
+ }
+ else
+ {
+ attribBufSizeInKB -= 4;
+ L1cacheSize = 4;
+ }
+ }
+ gcmkASSERT(L1cacheSize);
+ if (L1cacheSize >= database->L1CacheSize)
+ {
+ Hardware->options.uscL1CacheRatio = 0x0;
+ gcmkASSERT(gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_USC_FULLCACHE_FIX));
+ }
+ else
+ {
+ static const gctINT s_uscCacheRatio[] =
+ {
+ 100000,/* 1.0f */
+ 50000, /* 0.5f */
+ 25000, /* 0.25f */
+ 12500, /* 0.125f */
+ 62500, /* 0.0625f */
+ 3125, /* 0.03125f */
+ 75000, /* 0.75f */
+ 0, /*0.0f */
+ };
+ gctINT maxL1cacheSize = L1cacheSize * 100000;
+ gctINT delta = 2147483647; /* start with very big delta */
+ gctINT i = 0;
+ gctINT curIndex = -1;
+ for (; i < gcmCOUNTOF(s_uscCacheRatio); ++i)
+ {
+ gctINT curL1cacheSize = database->L1CacheSize * s_uscCacheRatio[i];
+
+ if ((maxL1cacheSize >= curL1cacheSize) &&
+ ((maxL1cacheSize - curL1cacheSize) < delta))
+ {
+ curIndex = i;
+ delta = maxL1cacheSize - curL1cacheSize;
+ }
+ }
+ gcmkASSERT(-1 != curIndex);
+ Hardware->options.uscL1CacheRatio = curIndex;
+ }
+ }
+
+ options->secureMode = gcvSECURE_NONE;
+
+ if (gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_SECURITY))
+ {
+ gctUINT32 ta = 0;
+
+ gcmkASSERT(gcvSTATUS_TRUE == gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_SECURITY_AHB));
+
+ options->secureMode = gcvSECURE_IN_NORMAL;
+
+ status = gckOS_QueryOption(Hardware->os, "TA", &ta);
+
+ if (gcmIS_SUCCESS(status) && ta)
+ {
+ options->secureMode = gcvSECURE_IN_TA;
+ }
+ }
+ else if (gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_SECURITY_AHB))
+ {
+ options->secureMode = gcvSECURE_IN_NORMAL;
+ }
+
+ return;
+}
+
+/*
+* State timer helper must be called with powerMutex held.
+*/
+void
+gckSTATETIMER_Reset(
+ IN gcsSTATETIMER * StateTimer,
+ IN gctUINT64 Start
+ )
+{
+ gctUINT64 now;
+
+ if (Start)
+ {
+ now = Start;
+ }
+ else
+ {
+ gckOS_GetProfileTick(&now);
+ }
+
+ StateTimer->recent = StateTimer->start = now;
+
+ gckOS_ZeroMemory(StateTimer->elapse, gcmSIZEOF(StateTimer->elapse));
+}
+
+void
+gckSTATETIMER_Accumulate(
+ IN gcsSTATETIMER * StateTimer,
+ IN gceCHIPPOWERSTATE OldState
+ )
+{
+ gctUINT64 now;
+ gctUINT64 elapse;
+
+ gckOS_GetProfileTick(&now);
+
+ elapse = now - StateTimer->recent;
+
+ StateTimer->recent = now;
+
+ StateTimer->elapse[OldState] += elapse;
+}
+
+void
+gckSTATETIMER_Query(
+ IN gcsSTATETIMER * StateTimer,
+ IN gceCHIPPOWERSTATE State,
+ OUT gctUINT64_PTR Start,
+ OUT gctUINT64_PTR End,
+ OUT gctUINT64_PTR On,
+ OUT gctUINT64_PTR Off,
+ OUT gctUINT64_PTR Idle,
+ OUT gctUINT64_PTR Suspend
+ )
+{
+ *Start = StateTimer->start;
+
+ gckSTATETIMER_Accumulate(StateTimer, State);
+
+ *End = StateTimer->recent;
+
+ *On = StateTimer->elapse[gcvPOWER_ON];
+ *Off = StateTimer->elapse[gcvPOWER_OFF];
+ *Idle = StateTimer->elapse[gcvPOWER_IDLE];
+ *Suspend = StateTimer->elapse[gcvPOWER_SUSPEND];
+
+ gckSTATETIMER_Reset(StateTimer, StateTimer->recent);
+}
+
+/******************************************************************************\
+****************************** gckHARDWARE API code *****************************
+\******************************************************************************/
+
+/*******************************************************************************
+**
+** gckHARDWARE_Construct
+**
+** Construct a new gckHARDWARE object.
+**
+** INPUT:
+**
+** gckOS Os
+** Pointer to an initialized gckOS object.
+**
+** gceCORE Core
+** Specified core.
+**
+** OUTPUT:
+**
+** gckHARDWARE * Hardware
+** Pointer to a variable that will hold the pointer to the gckHARDWARE
+** object.
+*/
+gceSTATUS
+gckHARDWARE_Construct(
+ IN gckOS Os,
+ IN gceCORE Core,
+ OUT gckHARDWARE * Hardware
+ )
+{
+ gceSTATUS status;
+ gckHARDWARE hardware = gcvNULL;
+ gctUINT16 data = 0xff00;
+ gctPOINTER pointer = gcvNULL;
+ gctUINT i;
+
+ gcmkHEADER_ARG("Os=0x%x", Os);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
+ gcmkVERIFY_ARGUMENT(Hardware != gcvNULL);
+
+ /* Enable the GPU. */
+ gcmkONERROR(gckOS_SetGPUPower(Os, Core, gcvTRUE, gcvTRUE));
+ gcmkONERROR(gckOS_WriteRegisterEx(Os,
+ Core,
+ 0x00000,
+ 0x00000900));
+
+ /* Allocate the gckHARDWARE object. */
+ gcmkONERROR(gckOS_Allocate(Os,
+ gcmSIZEOF(struct _gckHARDWARE),
+ &pointer));
+
+ gckOS_ZeroMemory(pointer, gcmSIZEOF(struct _gckHARDWARE));
+
+ hardware = (gckHARDWARE) pointer;
+
+ /* Initialize the gckHARDWARE object. */
+ hardware->object.type = gcvOBJ_HARDWARE;
+ hardware->os = Os;
+ hardware->core = Core;
+
+ gcmkONERROR(_GetHardwareSignature(hardware, Os, Core, &hardware->signature));
+
+ /* Identify the hardware. */
+ gcmkONERROR(_IdentifyHardwareByDatabase(hardware, Os, Core, &hardware->identity));
+
+ _SetHardwareOptions(hardware);
+
+ hardware->mmuVersion = gckHARDWARE_IsFeatureAvailable(hardware, gcvFEATURE_MMU);
+
+ /* Get the system's physical base address for old MMU */
+ if (hardware->mmuVersion == 0)
+ {
+ gcmkONERROR(gckOS_GetBaseAddress(Os, &hardware->baseAddress));
+ }
+
+ /* Determine the hardware type */
+ if (gckHARDWARE_IsFeatureAvailable(hardware, gcvFEATURE_PIPE_3D)
+ && gckHARDWARE_IsFeatureAvailable(hardware, gcvFEATURE_PIPE_2D)
+ )
+ {
+ hardware->type = gcvHARDWARE_3D2D;
+ }
+ else
+ if (gckHARDWARE_IsFeatureAvailable(hardware, gcvFEATURE_PIPE_2D))
+ {
+ hardware->type = gcvHARDWARE_2D;
+ }
+ else
+ {
+ hardware->type = gcvHARDWARE_3D;
+ }
+
+ hardware->powerBaseAddress
+ = ((hardware->identity.chipModel == gcv300)
+ && (hardware->identity.chipRevision < 0x2000))
+ ? 0x0100
+ : 0x0000;
+
+
+ /* _ResetGPU need powerBaseAddress. */
+ status = _ResetGPU(hardware, Os, Core);
+ if (status != gcvSTATUS_OK)
+ {
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE, "_ResetGPU failed: status=%d\n", status);
+ }
+
+#if gcdDEC_ENABLE_AHB
+ gcmkONERROR(gckOS_WriteRegisterEx(Os, gcvCORE_DEC, 0x18180, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 22:22) - (0 ?
+ 22:22) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 22:22) - (0 ?
+ 22:22) + 1))))))) << (0 ?
+ 22:22))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 22:22) - (0 ?
+ 22:22) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 22:22) - (0 ? 22:22) + 1))))))) << (0 ? 22:22)))));
+#endif
+
+ hardware->hasL2Cache = gckHARDWARE_IsFeatureAvailable(hardware, gcvFEATURE_64K_L2_CACHE);
+
+ if (!hardware->hasL2Cache)
+ {
+ gcmkONERROR(gckOS_WriteRegisterEx(Os,
+ Core,
+ 0x0055C,
+ 0x00FFFFFF));
+ }
+
+ hardware->powerMutex = gcvNULL;
+
+ /* Determine whether bug fixes #1 are present. */
+ hardware->extraEventStates = (gckHARDWARE_IsFeatureAvailable(hardware, gcvFEATURE_BUG_FIXES1) == gcvFALSE);
+
+ /* Check if big endian */
+ hardware->bigEndian = (*(gctUINT8 *)&data == 0xff);
+
+ /* Initialize the fast clear. */
+ gcmkONERROR(gckHARDWARE_SetFastClear(hardware, -1, -1));
+
+#if !gcdENABLE_128B_MERGE
+ if (gckHARDWARE_IsFeatureAvailable(hardware, gcvFEATURE_MULTI_SOURCE_BLT))
+ {
+ /* 128B merge is turned on by default. Disable it. */
+ gcmkONERROR(gckOS_WriteRegisterEx(Os, Core, 0x00558, 0));
+ }
+#endif
+
+#if (gcdFPGA_BUILD && 1)
+ if (gckHARDWARE_IsFeatureAvailable(hardware, gcvFEATURE_TPCV11_COMPRESSION))
+ {
+ gctUINT32 data;
+ gcmkONERROR(gckOS_ReadRegisterEx(Os, Core, 0x00558, &data));
+ data |= 0x1 << 27;
+ gcmkONERROR(gckOS_WriteRegisterEx(Os, Core, 0x00558, data));
+ }
+#endif
+
+ {
+ gctUINT32 value;
+ gcmkONERROR(gckOS_ReadRegisterEx(Os, Core, 0x00090, &value));
+#if gcdDEC_ENABLE_AHB
+ if (gckHARDWARE_IsFeatureAvailable(hardware, gcvFEATURE_DEC300_COMPRESSION))
+ {
+ value |= ~0xFFFFFFBF;
+ }
+ else
+#endif
+ {
+ value &= 0xFFFFFFBF;
+ }
+ gcmkONERROR(gckOS_WriteRegisterEx(Os, Core, 0x00090, value));
+ }
+
+ /* Set power state to ON. */
+ hardware->chipPowerState = gcvPOWER_ON;
+ hardware->clockState = gcvTRUE;
+ hardware->powerState = gcvTRUE;
+ hardware->lastWaitLink = ~0U;
+ hardware->lastEnd = ~0U;
+ hardware->globalSemaphore = gcvNULL;
+#if gcdENABLE_FSCALE_VAL_ADJUST
+ hardware->powerOnFscaleVal = 64;
+#endif
+
+ gcmkONERROR(gckOS_CreateMutex(Os, &hardware->powerMutex));
+ gcmkONERROR(gckOS_CreateSemaphore(Os, &hardware->globalSemaphore));
+
+#if gcdPOWEROFF_TIMEOUT
+ hardware->powerOffTimeout = gcdPOWEROFF_TIMEOUT;
+
+ gcmkVERIFY_OK(gckOS_CreateTimer(Os,
+ _PowerTimerFunction,
+ (gctPOINTER)hardware,
+ &hardware->powerOffTimer));
+#endif
+
+ for (i = 0; i < gcvENGINE_GPU_ENGINE_COUNT; i++)
+ {
+ gcmkONERROR(gckOS_AtomConstruct(Os, &hardware->pageTableDirty[i]));
+ }
+
+ gcmkONERROR(gckOS_AtomConstruct(Os, &hardware->pendingEvent));
+
+#if defined(LINUX) || defined(__QNXNTO__) || defined(UNDER_CE)
+ if (hardware->mmuVersion)
+ {
+ hardware->stallFEPrefetch
+ = gckHARDWARE_IsFeatureAvailable(hardware, gcvFEATURE_FE_ALLOW_STALL_PREFETCH_ENG);
+ }
+ else
+#endif
+ {
+ hardware->stallFEPrefetch = gcvTRUE;
+ }
+
+ hardware->hasAsyncFe
+ = gckHARDWARE_IsFeatureAvailable(hardware, gcvFEATURE_ASYNC_BLIT);
+
+ hardware->minFscaleValue = 1;
+ hardware->waitCount = 200;
+
+ gckSTATETIMER_Reset(&hardware->powerStateTimer, 0);
+
+#if gcdLINK_QUEUE_SIZE
+ gcmkONERROR(gckQUEUE_Allocate(hardware->os, &hardware->linkQueue, gcdLINK_QUEUE_SIZE));
+#endif
+
+ if (hardware->options.secureMode == gcvSECURE_IN_NORMAL)
+ {
+ hardware->pagetableArray.size = 4096;
+
+ gcmkONERROR(gckOS_AllocateNonPagedMemory(
+ hardware->os,
+ gcvFALSE,
+ gcvALLOC_FLAG_CONTIGUOUS,
+ &hardware->pagetableArray.size,
+ &hardware->pagetableArray.physical,
+ &hardware->pagetableArray.logical
+ ));
+
+ gcmkONERROR(gckOS_GetPhysicalAddress(
+ hardware->os,
+ hardware->pagetableArray.logical,
+ &hardware->pagetableArray.address
+ ));
+
+ gcmkVERIFY_OK(gckOS_CPUPhysicalToGPUPhysical(
+ hardware->os,
+ hardware->pagetableArray.address,
+ &hardware->pagetableArray.address
+ ));
+ }
+
+ /* Return pointer to the gckHARDWARE object. */
+ *Hardware = hardware;
+
+ /* Success. */
+ gcmkFOOTER_ARG("*Hardware=0x%x", *Hardware);
+ return gcvSTATUS_OK;
+
+OnError:
+ /* Roll back. */
+ if (hardware != gcvNULL)
+ {
+ /* Turn off the power. */
+ gcmkVERIFY_OK(gckOS_SetGPUPower(Os, Core, gcvFALSE, gcvFALSE));
+
+ if (hardware->globalSemaphore != gcvNULL)
+ {
+ /* Destroy the global semaphore. */
+ gcmkVERIFY_OK(gckOS_DestroySemaphore(Os,
+ hardware->globalSemaphore));
+ }
+
+ if (hardware->powerMutex != gcvNULL)
+ {
+ /* Destroy the power mutex. */
+ gcmkVERIFY_OK(gckOS_DeleteMutex(Os, hardware->powerMutex));
+ }
+
+#if gcdPOWEROFF_TIMEOUT
+ if (hardware->powerOffTimer != gcvNULL)
+ {
+ gcmkVERIFY_OK(gckOS_StopTimer(Os, hardware->powerOffTimer));
+ gcmkVERIFY_OK(gckOS_DestroyTimer(Os, hardware->powerOffTimer));
+ }
+#endif
+
+ for (i = 0; i < gcvENGINE_GPU_ENGINE_COUNT; i++)
+ {
+ if (hardware->pageTableDirty[i] != gcvNULL)
+ {
+ gcmkVERIFY_OK(gckOS_AtomDestroy(Os, hardware->pageTableDirty[i]));
+ }
+ }
+
+ if (hardware->pendingEvent != gcvNULL)
+ {
+ gcmkVERIFY_OK(gckOS_AtomDestroy(Os, hardware->pendingEvent));
+ }
+
+ if (hardware->pagetableArray.logical != gcvNULL)
+ {
+ gcmkVERIFY_OK(gckOS_FreeNonPagedMemory(
+ Os,
+ hardware->pagetableArray.size,
+ hardware->pagetableArray.physical,
+ hardware->pagetableArray.logical
+ ));
+ }
+
+ gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Os, hardware));
+ }
+
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+/*******************************************************************************
+**
+** gckHARDWARE_Destroy
+**
+** Destroy an gckHARDWARE object.
+**
+** INPUT:
+**
+** gckHARDWARE Hardware
+** Pointer to the gckHARDWARE object that needs to be destroyed.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckHARDWARE_Destroy(
+ IN gckHARDWARE Hardware
+ )
+{
+ gceSTATUS status;
+ gctUINT i;
+
+ gcmkHEADER_ARG("Hardware=0x%x", Hardware);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
+
+ /* Destroy the power semaphore. */
+ gcmkVERIFY_OK(gckOS_DestroySemaphore(Hardware->os,
+ Hardware->globalSemaphore));
+
+ /* Destroy the power mutex. */
+ gcmkVERIFY_OK(gckOS_DeleteMutex(Hardware->os, Hardware->powerMutex));
+
+#if gcdPOWEROFF_TIMEOUT
+ gcmkVERIFY_OK(gckOS_StopTimer(Hardware->os, Hardware->powerOffTimer));
+ gcmkVERIFY_OK(gckOS_DestroyTimer(Hardware->os, Hardware->powerOffTimer));
+#endif
+
+ for (i = 0; i < gcvENGINE_GPU_ENGINE_COUNT; i++)
+ {
+ gcmkVERIFY_OK(gckOS_AtomDestroy(Hardware->os, Hardware->pageTableDirty[i]));
+ }
+
+ gcmkVERIFY_OK(gckOS_AtomDestroy(Hardware->os, Hardware->pendingEvent));
+
+#if gcdLINK_QUEUE_SIZE
+ gckQUEUE_Free(Hardware->os, &Hardware->linkQueue);
+#endif
+
+ if (Hardware->pagetableArray.logical != gcvNULL)
+ {
+ gcmkVERIFY_OK(gckOS_FreeNonPagedMemory(
+ Hardware->os,
+ Hardware->pagetableArray.size,
+ Hardware->pagetableArray.physical,
+ Hardware->pagetableArray.logical
+ ));
+ }
+
+ /* Mark the object as unknown. */
+ Hardware->object.type = gcvOBJ_UNKNOWN;
+
+ /* Free the object. */
+ gcmkONERROR(gcmkOS_SAFE_FREE(Hardware->os, Hardware));
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ gcmkFOOTER();
+ return status;
+}
+
+/*******************************************************************************
+**
+** gckHARDWARE_GetType
+**
+** Get the hardware type.
+**
+** INPUT:
+**
+** gckHARDWARE Harwdare
+** Pointer to an gckHARDWARE object.
+**
+** OUTPUT:
+**
+** gceHARDWARE_TYPE * Type
+** Pointer to a variable that receives the type of hardware object.
+*/
+gceSTATUS
+gckHARDWARE_GetType(
+ IN gckHARDWARE Hardware,
+ OUT gceHARDWARE_TYPE * Type
+ )
+{
+ gcmkHEADER_ARG("Hardware=0x%x", Hardware);
+ gcmkVERIFY_ARGUMENT(Type != gcvNULL);
+
+ *Type = Hardware->type;
+
+ gcmkFOOTER_ARG("*Type=%d", *Type);
+ return gcvSTATUS_OK;
+}
+
+/*******************************************************************************
+**
+** gckHARDWARE_InitializeHardware
+**
+** Initialize the hardware.
+**
+** INPUT:
+**
+** gckHARDWARE Hardware
+** Pointer to the gckHARDWARE object.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckHARDWARE_InitializeHardware(
+ IN gckHARDWARE Hardware
+ )
+{
+ gceSTATUS status;
+ gctUINT32 control;
+ gctUINT32 data;
+ gctUINT32 regPMC = 0;
+
+ gcmkHEADER_ARG("Hardware=0x%x", Hardware);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
+
+ /* Disable isolate GPU bit. */
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x00000,
+ ((((gctUINT32) (0x00000900)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 19:19) - (0 ?
+ 19:19) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 19:19) - (0 ?
+ 19:19) + 1))))))) << (0 ?
+ 19:19))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ?
+ 19:19) - (0 ?
+ 19:19) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 19:19) - (0 ? 19:19) + 1))))))) << (0 ? 19:19)))));
+
+ gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x00000,
+ &control));
+
+ /* Enable debug register. */
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x00000,
+ ((((gctUINT32) (control)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 11:11) - (0 ?
+ 11:11) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 11:11) - (0 ?
+ 11:11) + 1))))))) << (0 ?
+ 11:11))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ?
+ 11:11) - (0 ?
+ 11:11) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 11:11) - (0 ? 11:11) + 1))))))) << (0 ? 11:11)))));
+
+ if (gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_SECURITY_AHB) &&
+ (Hardware->options.secureMode == gcvSECURE_IN_NORMAL))
+ {
+ gctUINT32 ahbControl = 0;
+
+ gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x003A8,
+ &ahbControl));
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x003A8,
+ ((((gctUINT32) (ahbControl)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 1:1) - (0 ?
+ 1:1) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 1:1) - (0 ?
+ 1:1) + 1))))))) << (0 ?
+ 1:1))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 1:1) - (0 ?
+ 1:1) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1)))));
+ }
+
+ /* Reset memory counters. */
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x0003C,
+ ~0U));
+
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x0003C,
+ 0));
+
+ if (Hardware->mmuVersion == 0)
+ {
+ /* Program the base addesses. */
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x0041C,
+ Hardware->baseAddress));
+
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x00418,
+ Hardware->baseAddress));
+
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x00428,
+ Hardware->baseAddress));
+
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x00420,
+ Hardware->baseAddress));
+
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x00424,
+ Hardware->baseAddress));
+ }
+
+ gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
+ Hardware->core,
+ Hardware->powerBaseAddress +
+ 0x00100,
+ &data));
+
+ /* Enable clock gating. */
+ data = ((((gctUINT32) (data)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1))))))) << (0 ?
+ 0:0))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)));
+
+ if ((Hardware->identity.chipRevision == 0x4301)
+ || (Hardware->identity.chipRevision == 0x4302)
+ )
+ {
+ /* Disable stall module level clock gating for 4.3.0.1 and 4.3.0.2
+ ** revisions. */
+ data = ((((gctUINT32) (data)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 1:1) - (0 ?
+ 1:1) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 1:1) - (0 ?
+ 1:1) + 1))))))) << (0 ?
+ 1:1))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 1:1) - (0 ?
+ 1:1) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1)));
+ }
+
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
+ Hardware->core,
+ Hardware->powerBaseAddress
+ + 0x00100,
+ data));
+
+#if gcdENABLE_3D
+ /* Disable PE clock gating on revs < 5.0 when HZ is present without a
+ ** bug fix. */
+ if ((Hardware->identity.chipRevision < 0x5000)
+ && gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_HZ)
+ && !gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_BUG_FIXES4)
+ )
+ {
+ if (regPMC == 0)
+ {
+ gcmkONERROR(
+ gckOS_ReadRegisterEx(Hardware->os,
+ Hardware->core,
+ Hardware->powerBaseAddress
+ + 0x00104,
+ &regPMC));
+ }
+
+ /* Disable PE clock gating. */
+ regPMC = ((((gctUINT32) (regPMC)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 2:2) - (0 ?
+ 2:2) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 2:2) - (0 ?
+ 2:2) + 1))))))) << (0 ?
+ 2:2))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 2:2) - (0 ?
+ 2:2) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 2:2) - (0 ? 2:2) + 1))))))) << (0 ? 2:2)));
+ }
+#endif
+
+ if (Hardware->identity.chipModel == gcv4000 &&
+ ((Hardware->identity.chipRevision == 0x5208) || (Hardware->identity.chipRevision == 0x5222)))
+ {
+ gcmkONERROR(
+ gckOS_WriteRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x0010C,
+ ((((gctUINT32) (0x01590880)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 23:23) - (0 ?
+ 23:23) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 23:23) - (0 ?
+ 23:23) + 1))))))) << (0 ?
+ 23:23))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 23:23) - (0 ?
+ 23:23) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 23:23) - (0 ? 23:23) + 1))))))) << (0 ? 23:23)))));
+ }
+
+ if ((Hardware->identity.chipModel == gcv1000 &&
+ (Hardware->identity.chipRevision == 0x5039 ||
+ Hardware->identity.chipRevision == 0x5040))
+ ||
+ (Hardware->identity.chipModel == gcv2000 &&
+ Hardware->identity.chipRevision == 0x5140)
+ )
+ {
+ gctUINT32 pulseEater;
+
+ pulseEater = ((((gctUINT32) (0x01590880)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 16:16) - (0 ?
+ 16:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 16:16) - (0 ?
+ 16:16) + 1))))))) << (0 ?
+ 16:16))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ?
+ 16:16) - (0 ?
+ 16:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 16:16) - (0 ? 16:16) + 1))))))) << (0 ? 16:16)));
+
+ gcmkONERROR(
+ gckOS_WriteRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x0010C,
+ ((((gctUINT32) (pulseEater)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 17:17) - (0 ?
+ 17:17) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 17:17) - (0 ?
+ 17:17) + 1))))))) << (0 ?
+ 17:17))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 17:17) - (0 ?
+ 17:17) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 17:17) - (0 ? 17:17) + 1))))))) << (0 ? 17:17)))));
+ }
+
+ if ((gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_HALTI2) == gcvSTATUS_FALSE)
+ || (Hardware->identity.chipRevision < 0x5422)
+ )
+ {
+ if (regPMC == 0)
+ {
+ gcmkONERROR(
+ gckOS_ReadRegisterEx(Hardware->os,
+ Hardware->core,
+ Hardware->powerBaseAddress
+ + 0x00104,
+ &regPMC));
+ }
+
+ regPMC = ((((gctUINT32) (regPMC)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:15) - (0 ?
+ 15:15) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:15) - (0 ?
+ 15:15) + 1))))))) << (0 ?
+ 15:15))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 15:15) - (0 ?
+ 15:15) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:15) - (0 ? 15:15) + 1))))))) << (0 ? 15:15)));
+ }
+
+ if (_IsHardwareMatch(Hardware, gcv2000, 0x5108))
+ {
+ gcmkONERROR(
+ gckOS_ReadRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x00480,
+ &data));
+
+ /* Set FE bus to one, TX bus to zero */
+ data = ((((gctUINT32) (data)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 3:3) - (0 ?
+ 3:3) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 3:3) - (0 ?
+ 3:3) + 1))))))) << (0 ?
+ 3:3))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 3:3) - (0 ?
+ 3:3) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 3:3) - (0 ? 3:3) + 1))))))) << (0 ? 3:3)));
+ data = ((((gctUINT32) (data)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 7:7) - (0 ?
+ 7:7) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 7:7) - (0 ?
+ 7:7) + 1))))))) << (0 ?
+ 7:7))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ?
+ 7:7) - (0 ?
+ 7:7) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 7:7) - (0 ? 7:7) + 1))))))) << (0 ? 7:7)));
+
+ gcmkONERROR(
+ gckOS_WriteRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x00480,
+ data));
+ }
+
+ gcmkONERROR(
+ gckHARDWARE_SetMMU(Hardware,
+ Hardware->kernel->mmu->area[0].pageTableLogical));
+
+ if (Hardware->identity.chipModel >= gcv400
+ && Hardware->identity.chipModel != gcv420
+ && !gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_BUG_FIXES12))
+ {
+ if (regPMC == 0)
+ {
+ gcmkONERROR(
+ gckOS_ReadRegisterEx(Hardware->os,
+ Hardware->core,
+ Hardware->powerBaseAddress
+ + 0x00104,
+ &regPMC));
+ }
+
+ /* Disable PA clock gating. */
+ regPMC = ((((gctUINT32) (regPMC)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 4:4) - (0 ?
+ 4:4) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 4:4) - (0 ?
+ 4:4) + 1))))))) << (0 ?
+ 4:4))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 4:4) - (0 ?
+ 4:4) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 4:4) - (0 ? 4:4) + 1))))))) << (0 ? 4:4)));
+ }
+
+ /* Limit 2D outstanding request. */
+ if (Hardware->maxOutstandingReads)
+ {
+ gctUINT32 data;
+
+ gcmkONERROR(
+ gckOS_ReadRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x00414,
+ &data));
+
+ data = ((((gctUINT32) (data)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1))))))) << (0 ?
+ 7:0))) | (((gctUINT32) ((gctUINT32) (Hardware->maxOutstandingReads & 0xFF) & ((gctUINT32) ((((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0)));
+
+ gcmkONERROR(
+ gckOS_WriteRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x00414,
+ data));
+ }
+
+ if (_IsHardwareMatch(Hardware, gcv1000, 0x5035))
+ {
+ gcmkONERROR(
+ gckOS_ReadRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x00414,
+ &data));
+
+ /* Disable HZ-L2. */
+ data = ((((gctUINT32) (data)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 12:12) - (0 ?
+ 12:12) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 12:12) - (0 ?
+ 12:12) + 1))))))) << (0 ?
+ 12:12))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 12:12) - (0 ?
+ 12:12) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 12:12) - (0 ? 12:12) + 1))))))) << (0 ? 12:12)));
+
+ gcmkONERROR(
+ gckOS_WriteRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x00414,
+ data));
+ }
+
+ if (_IsHardwareMatch(Hardware, gcv4000, 0x5222)
+ || _IsHardwareMatch(Hardware, gcv2000, 0x5108)
+ || (gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_TX_DESCRIPTOR)
+ && !gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_TX_DESC_CACHE_CLOCKGATE_FIX)
+ )
+ )
+ {
+ if (regPMC == 0)
+ {
+ gcmkONERROR(
+ gckOS_ReadRegisterEx(Hardware->os,
+ Hardware->core,
+ Hardware->powerBaseAddress
+ + 0x00104,
+ &regPMC));
+ }
+
+ /* Disable TX clock gating. */
+ regPMC = ((((gctUINT32) (regPMC)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 7:7) - (0 ?
+ 7:7) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 7:7) - (0 ?
+ 7:7) + 1))))))) << (0 ?
+ 7:7))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 7:7) - (0 ?
+ 7:7) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 7:7) - (0 ? 7:7) + 1))))))) << (0 ? 7:7)));
+ }
+
+ if (gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_NEW_GPIPE) &&
+ !gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_GPIPE_CLOCK_GATE_FIX))
+ {
+ if (regPMC == 0)
+ {
+ gcmkONERROR(
+ gckOS_ReadRegisterEx(Hardware->os,
+ Hardware->core,
+ Hardware->powerBaseAddress
+ + 0x00104,
+ &regPMC));
+ }
+
+ /* Disable GPIPE clock gating. */
+ regPMC = ((((gctUINT32) (regPMC)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 22:22) - (0 ?
+ 22:22) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 22:22) - (0 ?
+ 22:22) + 1))))))) << (0 ?
+ 22:22))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 22:22) - (0 ?
+ 22:22) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 22:22) - (0 ? 22:22) + 1))))))) << (0 ? 22:22)));
+ }
+
+ if (_IsHardwareMatch(Hardware, gcv880, 0x5106))
+ {
+ Hardware->kernel->timeOut = 140 * 1000;
+ }
+
+ if (regPMC == 0)
+ {
+ gcmkONERROR(
+ gckOS_ReadRegisterEx(Hardware->os,
+ Hardware->core,
+ Hardware->powerBaseAddress
+ + 0x00104,
+ &regPMC));
+ }
+
+ /* Disable RA HZ clock gating. */
+ regPMC = ((((gctUINT32) (regPMC)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 17:17) - (0 ?
+ 17:17) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 17:17) - (0 ?
+ 17:17) + 1))))))) << (0 ?
+ 17:17))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 17:17) - (0 ?
+ 17:17) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 17:17) - (0 ? 17:17) + 1))))))) << (0 ? 17:17)));
+
+ /* Disable RA EZ clock gating. */
+ regPMC = ((((gctUINT32) (regPMC)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 16:16) - (0 ?
+ 16:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 16:16) - (0 ?
+ 16:16) + 1))))))) << (0 ?
+ 16:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 16:16) - (0 ?
+ 16:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 16:16) - (0 ? 16:16) + 1))))))) << (0 ? 16:16)));
+
+ if ((gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_HALTI5)
+ && !gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_RA_CG_FIX)
+ )
+ )
+ {
+ if (regPMC == 0)
+ {
+ gcmkONERROR(
+ gckOS_ReadRegisterEx(Hardware->os,
+ Hardware->core,
+ Hardware->powerBaseAddress
+ + 0x00104,
+ &regPMC));
+ }
+
+ /* Disable RA clock gating. */
+ regPMC = ((((gctUINT32) (regPMC)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 6:6) - (0 ?
+ 6:6) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 6:6) - (0 ?
+ 6:6) + 1))))))) << (0 ?
+ 6:6))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 6:6) - (0 ?
+ 6:6) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 6:6) - (0 ? 6:6) + 1))))))) << (0 ? 6:6)));
+ }
+
+ if ((gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_HALTI5)
+ && !gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_SH_CLOCK_GATE_FIX)
+ )
+ )
+ {
+ if (regPMC == 0)
+ {
+ gcmkONERROR(
+ gckOS_ReadRegisterEx(Hardware->os,
+ Hardware->core,
+ Hardware->powerBaseAddress
+ + 0x00104,
+ &regPMC));
+ }
+
+ /* Disable SH clock gating. */
+ regPMC = ((((gctUINT32) (regPMC)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 3:3) - (0 ?
+ 3:3) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 3:3) - (0 ?
+ 3:3) + 1))))))) << (0 ?
+ 3:3))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 3:3) - (0 ?
+ 3:3) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 3:3) - (0 ? 3:3) + 1))))))) << (0 ? 3:3)));
+ }
+
+ if (regPMC != 0)
+ {
+ gcmkONERROR(
+ gckOS_WriteRegisterEx(Hardware->os,
+ Hardware->core,
+ Hardware->powerBaseAddress
+ + 0x00104,
+ regPMC));
+ }
+
+ if (_IsHardwareMatch(Hardware, gcv2000, 0x5108)
+ || (_IsHardwareMatch(Hardware, gcv2000, 0xffff5450))
+ || _IsHardwareMatch(Hardware, gcv320, 0x5007)
+ || _IsHardwareMatch(Hardware, gcv320, 0x5303)
+ || _IsHardwareMatch(Hardware, gcv880, 0x5106)
+ || _IsHardwareMatch(Hardware, gcv400, 0x4645)
+ )
+ {
+ /* Update GPU AXI cache atttribute. */
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x00008,
+ 0x00002200));
+ }
+
+ if ((Hardware->identity.chipRevision > 0x5420)
+ && gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_PIPE_3D))
+ {
+ gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x0010C,
+ &data));
+
+ /* Disable internal DFS. */
+ data =
+#if gcdDVFS
+ ((((gctUINT32) (data)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 18:18) - (0 ?
+ 18:18) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 18:18) - (0 ?
+ 18:18) + 1))))))) << (0 ?
+ 18:18))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 18:18) - (0 ?
+ 18:18) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 18:18) - (0 ? 18:18) + 1))))))) << (0 ? 18:18))) |
+#endif
+ ((((gctUINT32) (data)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 16:16) - (0 ?
+ 16:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 16:16) - (0 ?
+ 16:16) + 1))))))) << (0 ?
+ 16:16))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ?
+ 16:16) - (0 ?
+ 16:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 16:16) - (0 ? 16:16) + 1))))))) << (0 ? 16:16))) |
+ ((((gctUINT32) (data)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 17:17) - (0 ?
+ 17:17) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 17:17) - (0 ?
+ 17:17) + 1))))))) << (0 ?
+ 17:17))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 17:17) - (0 ?
+ 17:17) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 17:17) - (0 ? 17:17) + 1))))))) << (0 ? 17:17)));
+
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x0010C,
+ data));
+ }
+
+ if (_IsHardwareMatch(Hardware, gcv2500, 0x5422))
+ {
+ gcmkONERROR(gckOS_ReadRegisterEx(
+ Hardware->os, Hardware->core, 0x00090, &data));
+
+ /* AXI switch setup to SPLIT_TO64 mode */
+ data = ((((gctUINT32) (data)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 1:0) - (0 ?
+ 1:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 1:0) - (0 ?
+ 1:0) + 1))))))) << (0 ?
+ 1:0))) | (((gctUINT32) (0x2 & ((gctUINT32) ((((1 ?
+ 1:0) - (0 ?
+ 1:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 1:0) - (0 ? 1:0) + 1))))))) << (0 ? 1:0)));
+
+ gcmkONERROR(gckOS_WriteRegisterEx(
+ Hardware->os, Hardware->core, 0x00090, data));
+ }
+
+ _ConfigurePolicyID(Hardware);
+
+#if gcdDEBUG_MODULE_CLOCK_GATING
+ _ConfigureModuleLevelClockGating(Hardware);
+#endif
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ /* Return the error. */
+ gcmkFOOTER();
+ return status;
+}
+
+/*******************************************************************************
+**
+** gckHARDWARE_QueryMemory
+**
+** Query the amount of memory available on the hardware.
+**
+** INPUT:
+**
+** gckHARDWARE Hardware
+** Pointer to the gckHARDWARE object.
+**
+** OUTPUT:
+**
+** gctSIZE_T * InternalSize
+** Pointer to a variable that will hold the size of the internal video
+** memory in bytes. If 'InternalSize' is gcvNULL, no information of the
+** internal memory will be returned.
+**
+** gctUINT32 * InternalBaseAddress
+** Pointer to a variable that will hold the hardware's base address for
+** the internal video memory. This pointer cannot be gcvNULL if
+** 'InternalSize' is also non-gcvNULL.
+**
+** gctUINT32 * InternalAlignment
+** Pointer to a variable that will hold the hardware's base address for
+** the internal video memory. This pointer cannot be gcvNULL if
+** 'InternalSize' is also non-gcvNULL.
+**
+** gctSIZE_T * ExternalSize
+** Pointer to a variable that will hold the size of the external video
+** memory in bytes. If 'ExternalSize' is gcvNULL, no information of the
+** external memory will be returned.
+**
+** gctUINT32 * ExternalBaseAddress
+** Pointer to a variable that will hold the hardware's base address for
+** the external video memory. This pointer cannot be gcvNULL if
+** 'ExternalSize' is also non-gcvNULL.
+**
+** gctUINT32 * ExternalAlignment
+** Pointer to a variable that will hold the hardware's base address for
+** the external video memory. This pointer cannot be gcvNULL if
+** 'ExternalSize' is also non-gcvNULL.
+**
+** gctUINT32 * HorizontalTileSize
+** Number of horizontal pixels per tile. If 'HorizontalTileSize' is
+** gcvNULL, no horizontal pixel per tile will be returned.
+**
+** gctUINT32 * VerticalTileSize
+** Number of vertical pixels per tile. If 'VerticalTileSize' is
+** gcvNULL, no vertical pixel per tile will be returned.
+*/
+gceSTATUS
+gckHARDWARE_QueryMemory(
+ IN gckHARDWARE Hardware,
+ OUT gctSIZE_T * InternalSize,
+ OUT gctUINT32 * InternalBaseAddress,
+ OUT gctUINT32 * InternalAlignment,
+ OUT gctSIZE_T * ExternalSize,
+ OUT gctUINT32 * ExternalBaseAddress,
+ OUT gctUINT32 * ExternalAlignment,
+ OUT gctUINT32 * HorizontalTileSize,
+ OUT gctUINT32 * VerticalTileSize
+ )
+{
+ gcmkHEADER_ARG("Hardware=0x%x", Hardware);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
+
+ if (InternalSize != gcvNULL)
+ {
+ /* No internal memory. */
+ *InternalSize = 0;
+ }
+
+ if (ExternalSize != gcvNULL)
+ {
+ /* No external memory. */
+ *ExternalSize = 0;
+ }
+
+ if (HorizontalTileSize != gcvNULL)
+ {
+ /* 4x4 tiles. */
+ *HorizontalTileSize = 4;
+ }
+
+ if (VerticalTileSize != gcvNULL)
+ {
+ /* 4x4 tiles. */
+ *VerticalTileSize = 4;
+ }
+
+ /* Success. */
+ gcmkFOOTER_ARG("*InternalSize=%lu *InternalBaseAddress=0x%08x "
+ "*InternalAlignment=0x%08x *ExternalSize=%lu "
+ "*ExternalBaseAddress=0x%08x *ExtenalAlignment=0x%08x "
+ "*HorizontalTileSize=%u *VerticalTileSize=%u",
+ gcmOPT_VALUE(InternalSize),
+ gcmOPT_VALUE(InternalBaseAddress),
+ gcmOPT_VALUE(InternalAlignment),
+ gcmOPT_VALUE(ExternalSize),
+ gcmOPT_VALUE(ExternalBaseAddress),
+ gcmOPT_VALUE(ExternalAlignment),
+ gcmOPT_VALUE(HorizontalTileSize),
+ gcmOPT_VALUE(VerticalTileSize));
+ return gcvSTATUS_OK;
+}
+
+/*******************************************************************************
+**
+** gckHARDWARE_QueryChipIdentity
+**
+** Query the identity of the hardware.
+**
+** INPUT:
+**
+** gckHARDWARE Hardware
+** Pointer to the gckHARDWARE object.
+**
+** OUTPUT:
+**
+** gcsHAL_QUERY_CHIP_IDENTITY_PTR Identity
+** Pointer to the identity structure.
+**
+*/
+gceSTATUS
+gckHARDWARE_QueryChipIdentity(
+ IN gckHARDWARE Hardware,
+ OUT gcsHAL_QUERY_CHIP_IDENTITY_PTR Identity
+ )
+{
+ gcmkHEADER_ARG("Hardware=0x%x", Hardware);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
+ gcmkVERIFY_ARGUMENT(Identity != gcvNULL);
+
+ *Identity = Hardware->identity;
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+}
+
+/*******************************************************************************
+**
+** gckHARDWARE_QueryChipOptions
+**
+** Query the options of the hardware.
+**
+** INPUT:
+**
+** gckHARDWARE Hardware
+** Pointer to the gckHARDWARE object.
+**
+** OUTPUT:
+**
+** gcsHAL_QUERY_CHIP_OPTIONS_PTR Options
+** Pointer to the identity structure.
+**
+*/
+gceSTATUS
+gckHARDWARE_QueryChipOptions(
+ IN gckHARDWARE Hardware,
+ OUT gcsHAL_QUERY_CHIP_OPTIONS_PTR Options
+ )
+{
+ gcmkHEADER_ARG("Hardware=0x%x", Hardware);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
+ gcmkVERIFY_ARGUMENT(Options != gcvNULL);
+
+ *Options = Hardware->options;
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+}
+
+
+/*******************************************************************************
+**
+** gckHARDWARE_SplitMemory
+**
+** Split a hardware specific memory address into a pool and offset.
+**
+** INPUT:
+**
+** gckHARDWARE Hardware
+** Pointer to the gckHARDWARE object.
+**
+** gctUINT32 Address
+** Address in hardware specific format.
+**
+** OUTPUT:
+**
+** gcePOOL * Pool
+** Pointer to a variable that will hold the pool type for the address.
+**
+** gctUINT32 * Offset
+** Pointer to a variable that will hold the offset for the address.
+*/
+gceSTATUS
+gckHARDWARE_SplitMemory(
+ IN gckHARDWARE Hardware,
+ IN gctUINT32 Address,
+ OUT gcePOOL * Pool,
+ OUT gctUINT32 * Offset
+ )
+{
+ gcmkHEADER_ARG("Hardware=0x%x Addres=0x%08x", Hardware, Address);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
+ gcmkVERIFY_ARGUMENT(Pool != gcvNULL);
+ gcmkVERIFY_ARGUMENT(Offset != gcvNULL);
+
+ if (Hardware->mmuVersion == 0)
+ {
+ /* Dispatch on memory type. */
+ switch ((((((gctUINT32) (Address)) >> (0 ? 31:31)) & ((gctUINT32) ((((1 ? 31:31) - (0 ? 31:31) + 1) == 32) ? ~0U : (~(~0U << ((1 ? 31:31) - (0 ? 31:31) + 1)))))) ))
+ {
+ case 0x0:
+ /* System memory. */
+ *Pool = gcvPOOL_SYSTEM;
+ break;
+
+ case 0x1:
+ /* Virtual memory. */
+ *Pool = gcvPOOL_VIRTUAL;
+ break;
+
+ default:
+ /* Invalid memory type. */
+ gcmkFOOTER_ARG("status=%d", gcvSTATUS_INVALID_ARGUMENT);
+ return gcvSTATUS_INVALID_ARGUMENT;
+ }
+
+ /* Return offset of address. */
+ *Offset = (((((gctUINT32) (Address)) >> (0 ? 30:0)) & ((gctUINT32) ((((1 ? 30:0) - (0 ? 30:0) + 1) == 32) ? ~0U : (~(~0U << ((1 ? 30:0) - (0 ? 30:0) + 1)))))) );
+ }
+ else
+ {
+ *Pool = gcvPOOL_SYSTEM;
+ *Offset = Address;
+ }
+
+ /* Success. */
+ gcmkFOOTER_ARG("*Pool=%d *Offset=0x%08x", *Pool, *Offset);
+ return gcvSTATUS_OK;
+}
+
+/*******************************************************************************
+**
+** gckHARDWARE_Execute
+**
+** Kickstart the hardware's command processor with an initialized command
+** buffer.
+**
+** INPUT:
+**
+** gckHARDWARE Hardware
+** Pointer to the gckHARDWARE object.
+**
+** gctUINT32 Address
+** Hardware address of command buffer.
+**
+** gctSIZE_T Bytes
+** Number of bytes for the prefetch unit (until after the first LINK).
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckHARDWARE_Execute(
+ IN gckHARDWARE Hardware,
+ IN gctUINT32 Address,
+ IN gctSIZE_T Bytes
+ )
+{
+ gceSTATUS status;
+ gctUINT32 control;
+
+ gcmkHEADER_ARG("Hardware=0x%x Address=0x%x Bytes=%lu",
+ Hardware, Address, Bytes);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
+
+ /* Enable all events. */
+ gcmkONERROR(
+ gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00014, ~0U));
+
+ /* Write address register. */
+ gcmkONERROR(
+ gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00654, Address));
+
+ /* Build control register. */
+ control = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 16:16) - (0 ?
+ 16:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 16:16) - (0 ?
+ 16:16) + 1))))))) << (0 ?
+ 16:16))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 16:16) - (0 ?
+ 16:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 16:16) - (0 ? 16:16) + 1))))))) << (0 ? 16:16)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) ((Bytes + 7) >> 3) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+
+ /* Set big endian */
+ if (Hardware->bigEndian)
+ {
+ control |= ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 21:20) - (0 ?
+ 21:20) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 21:20) - (0 ?
+ 21:20) + 1))))))) << (0 ?
+ 21:20))) | (((gctUINT32) (0x2 & ((gctUINT32) ((((1 ?
+ 21:20) - (0 ?
+ 21:20) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 21:20) - (0 ? 21:20) + 1))))))) << (0 ? 21:20)));
+ }
+
+ /* Make sure writing to command buffer and previous AHB register is done. */
+ gcmkONERROR(gckOS_MemoryBarrier(Hardware->os, gcvNULL));
+
+ /* Write control register. */
+ switch (Hardware->options.secureMode)
+ {
+ case gcvSECURE_NONE:
+ gcmkONERROR(
+ gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00658, control));
+ break;
+ case gcvSECURE_IN_NORMAL:
+
+#if defined(__KERNEL__)
+ gcmkONERROR(
+ gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00658, control));
+#endif
+ gcmkONERROR(
+ gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x003A4, control));
+
+ break;
+#if gcdENABLE_TRUST_APPLICATION
+ case gcvSECURE_IN_TA:
+ /* Send message to TA. */
+ gcmkONERROR(gckKERNEL_SecurityStartCommand(Hardware->kernel, Address, (gctUINT32)Bytes));
+ break;
+#endif
+ default:
+ break;
+ }
+
+ /* Increase execute count. */
+ Hardware->executeCount++;
+
+ /* Record last execute address. */
+ Hardware->lastExecuteAddress = Address;
+
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
+ "Started command buffer @ 0x%08x",
+ Address);
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+/* Atomic version of Execute, for IRQ routine. */
+static gceSTATUS
+gckHARDWARE_AtomicExecute(
+ IN gckHARDWARE Hardware,
+ IN gctUINT32 Address,
+ IN gctSIZE_T Bytes
+ )
+{
+ gctUINT32 control;
+
+ /* Enable all events. */
+ gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00014, ~0U);
+
+ /* Write address register. */
+ gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00654, Address);
+
+ /* Build control register. */
+ control = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 16:16) - (0 ?
+ 16:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 16:16) - (0 ?
+ 16:16) + 1))))))) << (0 ?
+ 16:16))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 16:16) - (0 ?
+ 16:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 16:16) - (0 ? 16:16) + 1))))))) << (0 ? 16:16)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) ((Bytes + 7) >> 3) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+
+ /* Set big endian */
+ if (Hardware->bigEndian)
+ {
+ control |= ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 21:20) - (0 ?
+ 21:20) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 21:20) - (0 ?
+ 21:20) + 1))))))) << (0 ?
+ 21:20))) | (((gctUINT32) (0x2 & ((gctUINT32) ((((1 ?
+ 21:20) - (0 ?
+ 21:20) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 21:20) - (0 ? 21:20) + 1))))))) << (0 ? 21:20)));
+ }
+
+ /* Make sure writing to command buffer and previous AHB register is done. */
+ gckOS_MemoryBarrier(Hardware->os, gcvNULL);
+
+ /* Write control register. */
+ switch (Hardware->options.secureMode)
+ {
+ case gcvSECURE_NONE:
+ gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00658, control);
+ break;
+ case gcvSECURE_IN_NORMAL:
+
+#if defined(__KERNEL__)
+ gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00658, control);
+#endif
+ gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x003A4, control);
+
+ break;
+#if gcdENABLE_TRUST_APPLICATION
+ case gcvSECURE_IN_TA:
+ /* Send message to TA. */
+ gckKERNEL_SecurityStartCommand(Hardware->kernel, Address, (gctUINT32)Bytes);
+ break;
+#endif
+ default:
+ break;
+ }
+
+ /* Increase execute count. */
+ Hardware->executeCount++;
+
+ /* Record last execute address. */
+ Hardware->lastExecuteAddress = Address;
+
+ /* Success. */
+ return gcvSTATUS_OK;
+}
+
+/*******************************************************************************
+**
+** gckHARDWARE_WaitLink
+**
+** Append a WAIT/LINK command sequence at the specified location in the command
+** queue.
+**
+** INPUT:
+**
+** gckHARDWARE Hardware
+** Pointer to an gckHARDWARE object.
+**
+** gctPOINTER Logical
+** Pointer to the current location inside the command queue to append
+** WAIT/LINK command sequence at or gcvNULL just to query the size of the
+** WAIT/LINK command sequence.
+**
+** gctUINT32 Address
+** GPU address of current location inside the command queue.
+**
+** gctUINT32 Offset
+** Offset into command buffer required for alignment.
+**
+** gctSIZE_T * Bytes
+** Pointer to the number of bytes available for the WAIT/LINK command
+** sequence. If 'Logical' is gcvNULL, this argument will be ignored.
+**
+** OUTPUT:
+**
+** gctSIZE_T * Bytes
+** Pointer to a variable that will receive the number of bytes required
+** by the WAIT/LINK command sequence. If 'Bytes' is gcvNULL, nothing will
+** be returned.
+**
+** gctUINT32 * WaitOffset
+** Pointer to a variable that will receive the offset of the WAIT command
+** from the specified logcial pointer.
+** If 'WaitOffset' is gcvNULL nothing will be returned.
+**
+** gctSIZE_T * WaitSize
+** Pointer to a variable that will receive the number of bytes used by
+** the WAIT command. If 'LinkSize' is gcvNULL nothing will be returned.
+*/
+gceSTATUS
+gckHARDWARE_WaitLink(
+ IN gckHARDWARE Hardware,
+ IN gctPOINTER Logical,
+ IN gctUINT32 Address,
+ IN gctUINT32 Offset,
+ IN OUT gctUINT32 * Bytes,
+ OUT gctUINT32 * WaitOffset,
+ OUT gctUINT32 * WaitSize
+ )
+{
+ gceSTATUS status;
+ gctUINT32_PTR logical;
+ gctUINT32 bytes;
+ gctBOOL useL2;
+
+ gcmkHEADER_ARG("Hardware=0x%x Logical=0x%x Offset=0x%08x *Bytes=%lu",
+ Hardware, Logical, Offset, gcmOPT_VALUE(Bytes));
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
+ gcmkVERIFY_ARGUMENT((Logical != gcvNULL) || (Bytes != gcvNULL));
+
+ useL2 = Hardware->hasL2Cache;
+
+ /* Compute number of bytes required. */
+ if (useL2)
+ {
+ bytes = gcmALIGN(Offset + 24, 8) - Offset;
+ }
+ else
+ {
+ bytes = gcmALIGN(Offset + 16, 8) - Offset;
+ }
+
+ /* Cast the input pointer. */
+ logical = (gctUINT32_PTR) Logical;
+
+ if (logical != gcvNULL)
+ {
+ /* Not enough space? */
+ if (*Bytes < bytes)
+ {
+ /* Command queue too small. */
+ gcmkONERROR(gcvSTATUS_BUFFER_TOO_SMALL);
+ }
+
+ gcmkASSERT(Address != ~0U);
+
+ /* Store the WAIT/LINK address. */
+ Hardware->lastWaitLink = Address;
+
+ /* Append WAIT(count). */
+ *logical++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (Hardware->waitCount) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+
+ logical++;
+
+ if (useL2)
+ {
+ /* LoadState(AQFlush, 1), flush. */
+ *logical++ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E03) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
+
+ *logical++ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 6:6) - (0 ?
+ 6:6) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 6:6) - (0 ?
+ 6:6) + 1))))))) << (0 ?
+ 6:6))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 6:6) - (0 ?
+ 6:6) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 6:6) - (0 ? 6:6) + 1))))))) << (0 ? 6:6)));
+ }
+
+ /* Append LINK(2, address). */
+ *logical++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x08 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (bytes >> 3) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+
+ *logical++ = Address;
+
+ gcmkTRACE_ZONE(
+ gcvLEVEL_INFO, gcvZONE_HARDWARE,
+ "0x%08x: WAIT %u", Address, Hardware->waitCount
+ );
+
+ gcmkTRACE_ZONE(
+ gcvLEVEL_INFO, gcvZONE_HARDWARE,
+ "0x%08x: LINK 0x%08x, #%lu",
+ Address + 8, Address, bytes
+ );
+
+ if (WaitOffset != gcvNULL)
+ {
+ /* Return the offset pointer to WAIT command. */
+ *WaitOffset = 0;
+ }
+
+ if (WaitSize != gcvNULL)
+ {
+ /* Return number of bytes used by the WAIT command. */
+ if (useL2)
+ {
+ *WaitSize = 16;
+ }
+ else
+ {
+ *WaitSize = 8;
+ }
+ }
+ }
+
+ if (Bytes != gcvNULL)
+ {
+ /* Return number of bytes required by the WAIT/LINK command
+ ** sequence. */
+ *Bytes = bytes;
+ }
+
+ /* Success. */
+ gcmkFOOTER_ARG("*Bytes=%lu *WaitOffset=0x%x *WaitSize=%lu",
+ gcmOPT_VALUE(Bytes), gcmOPT_VALUE(WaitOffset),
+ gcmOPT_VALUE(WaitSize));
+ return gcvSTATUS_OK;
+
+OnError:
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+/*******************************************************************************
+**
+** gckHARDWARE_End
+**
+** Append an END command at the specified location in the command queue.
+**
+** INPUT:
+**
+** gckHARDWARE Hardware
+** Pointer to an gckHARDWARE object.
+**
+** gctPOINTER Logical
+** Pointer to the current location inside the command queue to append
+** END command at or gcvNULL just to query the size of the END command.
+**
+** gctUINT32 Address
+** GPU address of current location inside the command queue.
+**
+** gctSIZE_T * Bytes
+** Pointer to the number of bytes available for the END command. If
+** 'Logical' is gcvNULL, this argument will be ignored.
+**
+** OUTPUT:
+**
+** gctSIZE_T * Bytes
+** Pointer to a variable that will receive the number of bytes required
+** for the END command. If 'Bytes' is gcvNULL, nothing will be returned.
+*/
+gceSTATUS
+gckHARDWARE_End(
+ IN gckHARDWARE Hardware,
+ IN gctPOINTER Logical,
+ IN gctUINT32 Address,
+ IN OUT gctUINT32 * Bytes
+ )
+{
+ gctUINT32_PTR logical = (gctUINT32_PTR) Logical;
+ gctUINT32 address;
+ gceSTATUS status;
+
+ gcmkHEADER_ARG("Hardware=0x%x Logical=0x%x *Bytes=%lu",
+ Hardware, Logical, gcmOPT_VALUE(Bytes));
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
+ gcmkVERIFY_ARGUMENT((Logical == gcvNULL) || (Bytes != gcvNULL));
+
+ if (Logical != gcvNULL)
+ {
+ if (*Bytes < 8)
+ {
+ /* Command queue too small. */
+ gcmkONERROR(gcvSTATUS_BUFFER_TOO_SMALL);
+ }
+
+ /* Append END. */
+ logical[0] =
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x02 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)));
+
+ /* Record the count of execution which is finised by this END. */
+ logical[1] =
+ Hardware->executeCount;
+
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE, "0x%x: END", Logical);
+
+ /* Make sure the CPU writes out the data to memory. */
+ gcmkONERROR(
+ gckOS_MemoryBarrier(Hardware->os, Logical));
+
+
+ gcmkASSERT(Address != ~0U);
+ address = Address;
+
+ Hardware->lastEnd = address;
+ }
+
+ if (Bytes != gcvNULL)
+ {
+ /* Return number of bytes required by the END command. */
+ *Bytes = 8;
+ }
+
+ /* Success. */
+ gcmkFOOTER_ARG("*Bytes=%lu", gcmOPT_VALUE(Bytes));
+ return gcvSTATUS_OK;
+
+OnError:
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+gceSTATUS
+gckHARDWARE_ChipEnable(
+ IN gckHARDWARE Hardware,
+ IN gctPOINTER Logical,
+ IN gceCORE_3D_MASK ChipEnable,
+ IN OUT gctSIZE_T * Bytes
+ )
+{
+ gckOS os = Hardware->os;
+ gctUINT32_PTR logical = (gctUINT32_PTR) Logical;
+ gceSTATUS status;
+
+ gcmkHEADER_ARG("Hardware=0x%x Logical=0x%x ChipEnable=0x%x *Bytes=%lu",
+ Hardware, Logical, ChipEnable, gcmOPT_VALUE(Bytes));
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
+ gcmkVERIFY_ARGUMENT((Logical == gcvNULL) || (Bytes != gcvNULL));
+
+ if (Logical != gcvNULL)
+ {
+ if (*Bytes < 8)
+ {
+ /* Command queue too small. */
+ gcmkONERROR(gcvSTATUS_BUFFER_TOO_SMALL);
+ }
+
+ /* Append CHIPENABLE. */
+ gcmkWRITE_MEMORY(
+ logical,
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x0D & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | ChipEnable
+ );
+
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE, "0x%x: CHIPENABLE 0x%x", Logical, ChipEnable);
+ }
+
+ if (Bytes != gcvNULL)
+ {
+ /* Return number of bytes required by the CHIPENABLE command. */
+ *Bytes = 8;
+ }
+
+ /* Success. */
+ gcmkFOOTER_ARG("*Bytes=%lu", gcmOPT_VALUE(Bytes));
+ return gcvSTATUS_OK;
+
+OnError:
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+/*******************************************************************************
+**
+** gckHARDWARE_Nop
+**
+** Append a NOP command at the specified location in the command queue.
+**
+** INPUT:
+**
+** gckHARDWARE Hardware
+** Pointer to an gckHARDWARE object.
+**
+** gctPOINTER Logical
+** Pointer to the current location inside the command queue to append
+** NOP command at or gcvNULL just to query the size of the NOP command.
+**
+** gctSIZE_T * Bytes
+** Pointer to the number of bytes available for the NOP command. If
+** 'Logical' is gcvNULL, this argument will be ignored.
+**
+** OUTPUT:
+**
+** gctSIZE_T * Bytes
+** Pointer to a variable that will receive the number of bytes required
+** for the NOP command. If 'Bytes' is gcvNULL, nothing will be returned.
+*/
+gceSTATUS
+gckHARDWARE_Nop(
+ IN gckHARDWARE Hardware,
+ IN gctPOINTER Logical,
+ IN OUT gctSIZE_T * Bytes
+ )
+{
+ gctUINT32_PTR logical = (gctUINT32_PTR) Logical;
+ gceSTATUS status;
+
+ gcmkHEADER_ARG("Hardware=0x%x Logical=0x%x *Bytes=%lu",
+ Hardware, Logical, gcmOPT_VALUE(Bytes));
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
+ gcmkVERIFY_ARGUMENT((Logical == gcvNULL) || (Bytes != gcvNULL));
+
+ if (Logical != gcvNULL)
+ {
+ if (*Bytes < 8)
+ {
+ /* Command queue too small. */
+ gcmkONERROR(gcvSTATUS_BUFFER_TOO_SMALL);
+ }
+
+ /* Append NOP. */
+ logical[0] = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x03 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)));
+
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE, "0x%x: NOP", Logical);
+ }
+
+ if (Bytes != gcvNULL)
+ {
+ /* Return number of bytes required by the NOP command. */
+ *Bytes = 8;
+ }
+
+ /* Success. */
+ gcmkFOOTER_ARG("*Bytes=%lu", gcmOPT_VALUE(Bytes));
+ return gcvSTATUS_OK;
+
+OnError:
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+/*******************************************************************************
+**
+** gckHARDWARE_Event
+**
+** Append an EVENT command at the specified location in the command queue.
+**
+** INPUT:
+**
+** gckHARDWARE Hardware
+** Pointer to an gckHARDWARE object.
+**
+** gctPOINTER Logical
+** Pointer to the current location inside the command queue to append
+** the EVENT command at or gcvNULL just to query the size of the EVENT
+** command.
+**
+** gctUINT8 Event
+** Event ID to program.
+**
+** gceKERNEL_WHERE FromWhere
+** Location of the pipe to send the event.
+**
+** gctSIZE_T * Bytes
+** Pointer to the number of bytes available for the EVENT command. If
+** 'Logical' is gcvNULL, this argument will be ignored.
+**
+** OUTPUT:
+**
+** gctSIZE_T * Bytes
+** Pointer to a variable that will receive the number of bytes required
+** for the EVENT command. If 'Bytes' is gcvNULL, nothing will be
+** returned.
+*/
+gceSTATUS
+gckHARDWARE_Event(
+ IN gckHARDWARE Hardware,
+ IN gctPOINTER Logical,
+ IN gctUINT8 Event,
+ IN gceKERNEL_WHERE FromWhere,
+ IN OUT gctUINT32 * Bytes
+ )
+{
+ gctUINT size;
+ gctUINT32 destination = 0;
+ gctUINT32_PTR logical = (gctUINT32_PTR) Logical;
+ gceSTATUS status;
+ gctBOOL blt;
+ gctBOOL extraEventStates;
+
+ gcmkHEADER_ARG("Hardware=0x%x Logical=0x%x Event=%u FromWhere=%d *Bytes=%lu",
+ Hardware, Logical, Event, FromWhere, gcmOPT_VALUE(Bytes));
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
+ gcmkVERIFY_ARGUMENT((Logical == gcvNULL) || (Bytes != gcvNULL));
+ gcmkVERIFY_ARGUMENT(Event < 32);
+
+ if (gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_BLT_ENGINE))
+ {
+ /* Send all event from blt. */
+ if (FromWhere == gcvKERNEL_PIXEL)
+ {
+ FromWhere = gcvKERNEL_BLT;
+ }
+ }
+
+ blt = FromWhere == gcvKERNEL_BLT ? gcvTRUE : gcvFALSE;
+
+ /* Determine the size of the command. */
+
+ extraEventStates = Hardware->extraEventStates && (FromWhere == gcvKERNEL_PIXEL);
+
+ size = extraEventStates
+ ? gcmALIGN(8 + (1 + 5) * 4, 8) /* EVENT + 5 STATES */
+ : 8;
+
+ if (blt)
+ {
+ size += 16;
+ }
+
+ if (Logical != gcvNULL)
+ {
+ if (*Bytes < size)
+ {
+ /* Command queue too small. */
+ gcmkONERROR(gcvSTATUS_BUFFER_TOO_SMALL);
+ }
+
+ switch (FromWhere)
+ {
+ case gcvKERNEL_COMMAND:
+ /* From command processor. */
+ destination = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 5:5) - (0 ?
+ 5:5) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 5:5) - (0 ?
+ 5:5) + 1))))))) << (0 ?
+ 5:5))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 5:5) - (0 ?
+ 5:5) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 5:5) - (0 ? 5:5) + 1))))))) << (0 ? 5:5)));
+ break;
+
+ case gcvKERNEL_PIXEL:
+ /* From pixel engine. */
+ destination = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 6:6) - (0 ?
+ 6:6) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 6:6) - (0 ?
+ 6:6) + 1))))))) << (0 ?
+ 6:6))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 6:6) - (0 ?
+ 6:6) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 6:6) - (0 ? 6:6) + 1))))))) << (0 ? 6:6)));
+ break;
+
+ case gcvKERNEL_BLT:
+ destination = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 7:7) - (0 ?
+ 7:7) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 7:7) - (0 ?
+ 7:7) + 1))))))) << (0 ?
+ 7:7))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 7:7) - (0 ?
+ 7:7) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 7:7) - (0 ? 7:7) + 1))))))) << (0 ? 7:7)));
+ break;
+
+ default:
+ gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
+ }
+
+ if (blt)
+ {
+ *logical++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x502E) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+
+ *logical++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1))))))) << (0 ?
+ 0:0))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)));
+ }
+
+ /* Append EVENT(Event, destination). */
+ *logical++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E01) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
+
+ *logical++
+ = ((((gctUINT32) (destination)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1))))))) << (0 ?
+ 4:0))) | (((gctUINT32) ((gctUINT32) (Event) & ((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)));
+
+ if (blt)
+ {
+ *logical++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x502E) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+
+ *logical++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1))))))) << (0 ?
+ 0:0))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)));
+ }
+
+
+ /* Make sure the event ID gets written out before GPU can access it. */
+ gcmkONERROR(
+ gckOS_MemoryBarrier(Hardware->os, logical + 1));
+
+#if gcmIS_DEBUG(gcdDEBUG_TRACE)
+ {
+ gctPHYS_ADDR_T phys;
+ gckOS_GetPhysicalAddress(Hardware->os, Logical, &phys);
+ gckOS_CPUPhysicalToGPUPhysical(Hardware->os, phys, &phys);
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
+ "0x%08x: EVENT %d", phys, Event);
+ }
+#endif
+
+ /* Append the extra states. These are needed for the chips that do not
+ ** support back-to-back events due to the async interface. The extra
+ ** states add the necessary delay to ensure that event IDs do not
+ ** collide. */
+ if (extraEventStates)
+ {
+ *logical++ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x0100) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (5) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
+ *logical++ = 0;
+ *logical++ = 0;
+ *logical++ = 0;
+ *logical++ = 0;
+ *logical++ = 0;
+ }
+
+#if gcdINTERRUPT_STATISTIC
+ if (Event < gcmCOUNTOF(Hardware->kernel->eventObj->queues))
+ {
+ gckOS_AtomSetMask(Hardware->pendingEvent, 1 << Event);
+ }
+#endif
+ }
+
+ if (Bytes != gcvNULL)
+ {
+ /* Return number of bytes required by the EVENT command. */
+ *Bytes = size;
+ }
+
+ /* Success. */
+ gcmkFOOTER_ARG("*Bytes=%lu", gcmOPT_VALUE(Bytes));
+ return gcvSTATUS_OK;
+
+OnError:
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+/*******************************************************************************
+**
+** gckHARDWARE_PipeSelect
+**
+** Append a PIPESELECT command at the specified location in the command queue.
+**
+** INPUT:
+**
+** gckHARDWARE Hardware
+** Pointer to an gckHARDWARE object.
+**
+** gctPOINTER Logical
+** Pointer to the current location inside the command queue to append
+** the PIPESELECT command at or gcvNULL just to query the size of the
+** PIPESELECT command.
+**
+** gcePIPE_SELECT Pipe
+** Pipe value to select.
+**
+** gctSIZE_T * Bytes
+** Pointer to the number of bytes available for the PIPESELECT command.
+** If 'Logical' is gcvNULL, this argument will be ignored.
+**
+** OUTPUT:
+**
+** gctSIZE_T * Bytes
+** Pointer to a variable that will receive the number of bytes required
+** for the PIPESELECT command. If 'Bytes' is gcvNULL, nothing will be
+** returned.
+*/
+gceSTATUS
+gckHARDWARE_PipeSelect(
+ IN gckHARDWARE Hardware,
+ IN gctPOINTER Logical,
+ IN gcePIPE_SELECT Pipe,
+ IN OUT gctUINT32 * Bytes
+ )
+{
+ gctUINT32_PTR logical = (gctUINT32_PTR) Logical;
+ gceSTATUS status;
+
+ gcmkHEADER_ARG("Hardware=0x%x Logical=0x%x Pipe=%d *Bytes=%lu",
+ Hardware, Logical, Pipe, gcmOPT_VALUE(Bytes));
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
+ gcmkVERIFY_ARGUMENT((Logical == gcvNULL) || (Bytes != gcvNULL));
+
+ /* Append a PipeSelect. */
+ if (Logical != gcvNULL)
+ {
+ gctUINT32 flush, stall;
+
+ if (*Bytes < 32)
+ {
+ /* Command queue too small. */
+ gcmkONERROR(gcvSTATUS_BUFFER_TOO_SMALL);
+ }
+
+ flush = (Pipe == gcvPIPE_2D)
+ ?
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 1:1) - (0 ?
+ 1:1) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 1:1) - (0 ?
+ 1:1) + 1))))))) << (0 ?
+ 1:1))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 1:1) - (0 ?
+ 1:1) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1))))))) << (0 ?
+ 0:0))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)))
+ : ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 3:3) - (0 ?
+ 3:3) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 3:3) - (0 ?
+ 3:3) + 1))))))) << (0 ?
+ 3:3))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 3:3) - (0 ?
+ 3:3) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 3:3) - (0 ? 3:3) + 1))))))) << (0 ? 3:3)));
+
+ stall = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1))))))) << (0 ?
+ 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1))))))) << (0 ?
+ 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
+
+ /* LoadState(AQFlush, 1), flush. */
+ gcmkONERROR(gckOS_WriteMemory(
+ Hardware->os,
+ logical,
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E03) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+ ));
+
+ gcmkONERROR(gckOS_WriteMemory(
+ Hardware->os,
+ logical + 1,
+ flush
+ ));
+
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
+ "0x%x: FLUSH 0x%x", logical, flush);
+
+ /* LoadState(AQSempahore, 1), stall. */
+ gcmkONERROR(gckOS_WriteMemory(
+ Hardware->os,
+ logical + 2,
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E02) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+ ));
+
+ gcmkONERROR(gckOS_WriteMemory(
+ Hardware->os,
+ logical + 3,
+ stall
+ ));
+
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
+ "0x%x: SEMAPHORE 0x%x", logical + 2, stall);
+
+ /* Stall, stall. */
+ gcmkONERROR(gckOS_WriteMemory(
+ Hardware->os,
+ logical + 4,
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x09 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ ));
+
+ gcmkONERROR(gckOS_WriteMemory(
+ Hardware->os,
+ logical + 5,
+ stall
+ ));
+
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
+ "0x%x: STALL 0x%x", logical + 4, stall);
+
+ /* LoadState(AQPipeSelect, 1), pipe. */
+ gcmkONERROR(gckOS_WriteMemory(
+ Hardware->os,
+ logical + 6,
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E00) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+ ));
+
+ gcmkONERROR(gckOS_WriteMemory(
+ Hardware->os,
+ logical + 7,
+ (Pipe == gcvPIPE_2D)
+ ? 0x1
+ : 0x0
+ ));
+
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
+ "0x%x: PIPE %d", logical + 6, Pipe);
+ }
+
+ if (Bytes != gcvNULL)
+ {
+ /* Return number of bytes required by the PIPESELECT command. */
+ *Bytes = 32;
+ }
+
+ /* Success. */
+ gcmkFOOTER_ARG("*Bytes=%lu", gcmOPT_VALUE(Bytes));
+ return gcvSTATUS_OK;
+
+OnError:
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+/*******************************************************************************
+**
+** gckHARDWARE_Link
+**
+** Append a LINK command at the specified location in the command queue.
+**
+** INPUT:
+**
+** gckHARDWARE Hardware
+** Pointer to an gckHARDWARE object.
+**
+** gctPOINTER Logical
+** Pointer to the current location inside the command queue to append
+** the LINK command at or gcvNULL just to query the size of the LINK
+** command.
+**
+** gctUINT32 FetchAddress
+** Hardware address of destination of LINK.
+**
+** gctSIZE_T FetchSize
+** Number of bytes in destination of LINK.
+**
+** gctSIZE_T * Bytes
+** Pointer to the number of bytes available for the LINK command. If
+** 'Logical' is gcvNULL, this argument will be ignored.
+**
+** OUTPUT:
+**
+** gctSIZE_T * Bytes
+** Pointer to a variable that will receive the number of bytes required
+** for the LINK command. If 'Bytes' is gcvNULL, nothing will be returned.
+*/
+gceSTATUS
+gckHARDWARE_Link(
+ IN gckHARDWARE Hardware,
+ IN gctPOINTER Logical,
+ IN gctUINT32 FetchAddress,
+ IN gctUINT32 FetchSize,
+ IN OUT gctUINT32 * Bytes,
+ OUT gctUINT32 * Low,
+ OUT gctUINT32 * High
+ )
+{
+ gceSTATUS status;
+ gctSIZE_T bytes;
+ gctUINT32 link;
+ gctUINT32_PTR logical = (gctUINT32_PTR) Logical;
+
+ gcmkHEADER_ARG("Hardware=0x%x Logical=0x%x FetchAddress=0x%x FetchSize=%lu "
+ "*Bytes=%lu",
+ Hardware, Logical, FetchAddress, FetchSize,
+ gcmOPT_VALUE(Bytes));
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
+ gcmkVERIFY_ARGUMENT((Logical == gcvNULL) || (Bytes != gcvNULL));
+
+ if (Logical != gcvNULL)
+ {
+ if (*Bytes < 8)
+ {
+ /* Command queue too small. */
+ gcmkONERROR(gcvSTATUS_BUFFER_TOO_SMALL);
+ }
+
+ gcmkONERROR(
+ gckOS_WriteMemory(Hardware->os, logical + 1, FetchAddress));
+
+ if (High)
+ {
+ *High = FetchAddress;
+ }
+
+ /* Make sure the address got written before the LINK command. */
+ gcmkONERROR(
+ gckOS_MemoryBarrier(Hardware->os, logical + 1));
+
+ /* Compute number of 64-byte aligned bytes to fetch. */
+ bytes = gcmALIGN(FetchAddress + FetchSize, 64) - FetchAddress;
+
+ /* Append LINK(bytes / 8), FetchAddress. */
+ link = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x08 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (bytes >> 3) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+
+ gcmkONERROR(
+ gckOS_WriteMemory(Hardware->os, logical, link));
+
+ if (Low)
+ {
+ *Low = link;
+ }
+
+ /* Memory barrier. */
+ gcmkONERROR(
+ gckOS_MemoryBarrier(Hardware->os, logical));
+ }
+
+ if (Bytes != gcvNULL)
+ {
+ /* Return number of bytes required by the LINK command. */
+ *Bytes = 8;
+ }
+
+ /* Success. */
+ gcmkFOOTER_ARG("*Bytes=%lu", gcmOPT_VALUE(Bytes));
+ return gcvSTATUS_OK;
+
+OnError:
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+gceSTATUS
+gckHARDWARE_FenceRender(
+ IN gckHARDWARE Hardware,
+ IN gctPOINTER Logical,
+ IN gctUINT32 FenceAddress,
+ IN gctUINT64 FenceData,
+ IN OUT gctUINT32 * Bytes
+ )
+{
+ gckOS os = Hardware->os;
+ gctUINT32_PTR logical = (gctUINT32_PTR)Logical;
+
+ gctUINT32 dataLow = (gctUINT32)FenceData;
+ gctUINT32 dataHigh = (gctUINT32)(FenceData >> 32);
+
+ if (logical)
+ {
+ gcmkWRITE_MEMORY(
+ logical,
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E1A) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+ );
+
+ gcmkWRITE_MEMORY(
+ logical,
+ FenceAddress
+ );
+
+ gcmkWRITE_MEMORY(
+ logical,
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E26) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+ );
+
+ gcmkWRITE_MEMORY(
+ logical,
+ dataHigh
+ );
+
+ gcmkWRITE_MEMORY(
+ logical,
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E1B) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+ );
+
+ gcmkWRITE_MEMORY(
+ logical,
+ dataLow
+ );
+ }
+ else
+ {
+ *Bytes = gcdRENDER_FENCE_LENGTH;
+ }
+
+ return gcvSTATUS_OK;
+}
+
+gceSTATUS
+gckHARDWARE_FenceBlt(
+ IN gckHARDWARE Hardware,
+ IN gctPOINTER Logical,
+ IN gctUINT32 FenceAddress,
+ IN gctUINT64 FenceData,
+ IN OUT gctUINT32 * Bytes
+ )
+{
+ gckOS os = Hardware->os;
+ gctUINT32_PTR logical = (gctUINT32_PTR)Logical;
+
+ gctUINT32 dataLow = (gctUINT32)FenceData;
+ gctUINT32 dataHigh = (gctUINT32)(FenceData >> 32);
+
+ if (logical)
+ {
+ gcmkWRITE_MEMORY(
+ logical,
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x502E) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+ );
+
+ gcmkWRITE_MEMORY(
+ logical,
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1))))))) << (0 ?
+ 0:0))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)))
+ );
+
+ gcmkWRITE_MEMORY(
+ logical,
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x5029) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+ );
+
+ gcmkWRITE_MEMORY(
+ logical,
+ FenceAddress
+ );
+
+ gcmkWRITE_MEMORY(
+ logical,
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x502D) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+ );
+
+ gcmkWRITE_MEMORY(
+ logical,
+ dataHigh
+ );
+
+ gcmkWRITE_MEMORY(
+ logical,
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x502A) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+ );
+
+ gcmkWRITE_MEMORY(
+ logical,
+ dataLow
+ );
+
+ gcmkWRITE_MEMORY(
+ logical,
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x502E) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+ );
+
+ gcmkWRITE_MEMORY(
+ logical,
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1))))))) << (0 ?
+ 0:0))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)))
+ );
+ }
+ else
+ {
+ *Bytes = gcdBLT_FENCE_LENGTH;
+ }
+
+ return gcvSTATUS_OK;
+}
+
+gceSTATUS
+gckHARDWARE_Fence(
+ IN gckHARDWARE Hardware,
+ IN gceENGINE Engine,
+ IN gctPOINTER Logical,
+ IN gctUINT32 FenceAddress,
+ IN gctUINT64 FenceData,
+ IN OUT gctUINT32 * Bytes
+ )
+{
+ if (Engine == gcvENGINE_RENDER)
+ {
+ return gckHARDWARE_FenceRender(Hardware, Logical, FenceAddress, FenceData, Bytes);
+ }
+ else
+ {
+ return gckHARDWARE_FenceBlt(Hardware, Logical, FenceAddress, FenceData, Bytes);
+ }
+}
+
+/*******************************************************************************
+**
+** gckHARDWARE_UpdateQueueTail
+**
+** Update the tail of the command queue.
+**
+** INPUT:
+**
+** gckHARDWARE Hardware
+** Pointer to an gckHARDWARE object.
+**
+** gctPOINTER Logical
+** Logical address of the start of the command queue.
+**
+** gctUINT32 Offset
+** Offset into the command queue of the tail (last command).
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckHARDWARE_UpdateQueueTail(
+ IN gckHARDWARE Hardware,
+ IN gctPOINTER Logical,
+ IN gctUINT32 Offset
+ )
+{
+ gceSTATUS status;
+
+ gcmkHEADER_ARG("Hardware=0x%x Logical=0x%x Offset=0x%08x",
+ Hardware, Logical, Offset);
+
+ /* Verify the hardware. */
+ gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
+
+ /* Force a barrier. */
+ gcmkONERROR(
+ gckOS_MemoryBarrier(Hardware->os, Logical));
+
+ /* Notify gckKERNEL object of change. */
+ gcmkONERROR(
+ gckKERNEL_Notify(Hardware->kernel,
+ gcvNOTIFY_COMMAND_QUEUE,
+ gcvFALSE));
+
+ if (status == gcvSTATUS_CHIP_NOT_READY)
+ {
+ gcmkONERROR(gcvSTATUS_DEVICE);
+ }
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+/*******************************************************************************
+**
+** gckHARDWARE_ConvertLogical
+**
+** Convert a logical system address into a hardware specific address.
+**
+** INPUT:
+**
+** gckHARDWARE Hardware
+** Pointer to an gckHARDWARE object.
+**
+** gctPOINTER Logical
+** Logical address to convert.
+**
+** gctBOOL InUserSpace
+** gcvTRUE if the memory in user space.
+**
+** gctUINT32* Address
+** Return hardware specific address.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckHARDWARE_ConvertLogical(
+ IN gckHARDWARE Hardware,
+ IN gctPOINTER Logical,
+ IN gctBOOL InUserSpace,
+ OUT gctUINT32 * Address
+ )
+{
+ gctUINT32 address;
+ gceSTATUS status;
+ gctPHYS_ADDR_T physical;
+
+ gcmkHEADER_ARG("Hardware=0x%x Logical=0x%x InUserSpace=%d",
+ Hardware, Logical, InUserSpace);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
+ gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
+ gcmkVERIFY_ARGUMENT(Address != gcvNULL);
+
+ /* Convert logical address into a physical address. */
+ if (InUserSpace)
+ {
+ gcmkONERROR(gckOS_UserLogicalToPhysical(Hardware->os, Logical, &physical));
+ }
+ else
+ {
+ gcmkONERROR(gckOS_GetPhysicalAddress(Hardware->os, Logical, &physical));
+ }
+
+ gcmkVERIFY_OK(gckOS_CPUPhysicalToGPUPhysical(Hardware->os, physical, &physical));
+
+ gcmkSAFECASTPHYSADDRT(address, physical);
+
+ /* For old MMU, get GPU address according to baseAddress. */
+ if (Hardware->mmuVersion == 0)
+ {
+ /* Subtract base address to get a GPU address. */
+ gcmkASSERT(address >= Hardware->baseAddress);
+ address -= Hardware->baseAddress;
+ }
+
+ /* Return hardware specific address. */
+ *Address = (Hardware->mmuVersion == 0)
+ ?
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:31) - (0 ?
+ 31:31) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:31) - (0 ?
+ 31:31) + 1))))))) << (0 ?
+ 31:31))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ?
+ 31:31) - (0 ?
+ 31:31) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:31) - (0 ? 31:31) + 1))))))) << (0 ? 31:31)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 30:0) - (0 ?
+ 30:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 30:0) - (0 ?
+ 30:0) + 1))))))) << (0 ?
+ 30:0))) | (((gctUINT32) ((gctUINT32) (address) & ((gctUINT32) ((((1 ?
+ 30:0) - (0 ?
+ 30:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 30:0) - (0 ? 30:0) + 1))))))) << (0 ? 30:0)))
+ : address;
+
+ /* Success. */
+ gcmkFOOTER_ARG("*Address=0x%08x", *Address);
+ return gcvSTATUS_OK;
+
+OnError:
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+static void
+_ResumeWaitLinkFE(
+ gckHARDWARE Hardware
+ )
+{
+ gctUINT32 resume;
+ gctUINT32 bytes;
+ gctUINT32 idle;
+
+ /* Make sure FE is idle. */
+ do
+ {
+ gckOS_ReadRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x00004,
+ &idle);
+ }
+ while (idle != 0x7FFFFFFF);
+
+ gckOS_ReadRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x00664,
+ &resume);
+
+ gckOS_ReadRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x00664,
+ &resume);
+
+ /* Determine the wait-link command size. */
+ bytes = Hardware->hasL2Cache ? 24 : 16;
+
+ /* Start Command Parser. */
+ gckHARDWARE_AtomicExecute(Hardware, resume, bytes);
+}
+
+/*******************************************************************************
+**
+** gckHARDWARE_Interrupt
+**
+** Process an interrupt.
+**
+** INPUT:
+**
+** gckHARDWARE Hardware
+** Pointer to an gckHARDWARE object.
+**
+** gctBOOL InterruptValid
+** If gcvTRUE, this function will read the interrupt acknowledge
+** register, stores the data, and return whether or not the interrupt
+** is ours or not. If gcvFALSE, this functions will read the interrupt
+** acknowledge register and combine it with any stored value to handle
+** the event notifications.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckHARDWARE_Interrupt(
+ IN gckHARDWARE Hardware,
+ IN gctBOOL InterruptValid
+ )
+{
+ gckEVENT eventObj;
+ gctUINT32 data = 0;
+ gctUINT32 dataEx;
+ gceSTATUS status;
+ gceSTATUS statusEx;
+
+ /* Extract gckEVENT object. */
+ eventObj = Hardware->kernel->eventObj;
+
+ if (InterruptValid)
+ {
+ /*
+ * Notice:
+ * In isr here.
+ * We should return success when either FE or AsyncFE reports correct
+ * interrupts, so that isr can wake up threadRoutine for either FE.
+ * That means, only need return ERROR when both FEs reports ERROR.
+ */
+ /* Read AQIntrAcknowledge register. */
+ status = gckOS_ReadRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x00010,
+ &data);
+
+ if (gcmIS_ERROR(status))
+ {
+ goto OnError;
+ }
+
+ if (data == 0)
+ {
+ /* Not our interrupt. */
+ status = gcvSTATUS_NOT_OUR_INTERRUPT;
+ }
+ else
+ {
+#if gcdINTERRUPT_STATISTIC
+ gckOS_AtomClearMask(Hardware->pendingEvent, data);
+#endif
+ if (data & (1 << 29))
+ {
+ /* Event ID 29 is not a normal event, but for invalidating pipe. */
+ _ResumeWaitLinkFE(Hardware);
+ data &= ~(1 << 29);
+ }
+
+ /* Inform gckEVENT of the interrupt. */
+ status = gckEVENT_Interrupt(eventObj, data);
+ }
+
+ if (!Hardware->hasAsyncFe)
+ {
+ /* Done. */
+ goto OnError;
+ }
+
+ /* Read BLT interrupt. */
+ statusEx = gckOS_ReadRegisterEx(
+ Hardware->os,
+ Hardware->core,
+ 0x000D4,
+ &dataEx
+ );
+
+ if (gcmIS_ERROR(statusEx))
+ {
+ /*
+ * Do not overwrite status here, so that former status from
+ * AQIntrAck is returned.
+ */
+ goto OnError;
+ }
+
+ /*
+ * This bit looks useless now, we can use this check if this interrupt
+ * is from FE.
+ */
+ dataEx &= ~0x80000000;
+
+ /*
+ * Descriptor fetched, update counter.
+ * We can't do this at dataEx != 0 only, because read HW acknowledge
+ * register will overwrite 0x007E4. If one
+ * interrupt we don't read it, we will miss it for ever.
+ */
+ gckFE_UpdateAvaiable(Hardware, &Hardware->kernel->asyncCommand->fe);
+
+ /* Do not need report NOT_OUT_INTERRUPT error if dataEx is 0. */
+ if (dataEx)
+ {
+ statusEx = gckEVENT_Interrupt(Hardware->kernel->asyncEvent, dataEx);
+
+ if (gcmIS_SUCCESS(statusEx))
+ {
+ /* At least AsyncFE is success, treat all as success. */
+ status = gcvSTATUS_OK;
+ }
+ }
+ }
+ else
+ {
+ /* Handle events. */
+ status = gckEVENT_Notify(eventObj, 0);
+
+ if (Hardware->hasAsyncFe)
+ {
+ status = gckEVENT_Notify(Hardware->kernel->asyncEvent, 0);
+ }
+ }
+
+OnError:
+ /* Return the status. */
+ return status;
+}
+
+/*******************************************************************************
+**
+** gckHARDWARE_QueryCommandBuffer
+**
+** Query the command buffer alignment and number of reserved bytes.
+**
+** INPUT:
+**
+** gckHARDWARE Harwdare
+** Pointer to an gckHARDWARE object.
+**
+** OUTPUT:
+**
+** gctSIZE_T * Alignment
+** Pointer to a variable receiving the alignment for each command.
+**
+** gctSIZE_T * ReservedHead
+** Pointer to a variable receiving the number of reserved bytes at the
+** head of each command buffer.
+**
+** gctSIZE_T * ReservedTail
+** Pointer to a variable receiving the number of bytes reserved at the
+** tail of each command buffer.
+*/
+gceSTATUS
+gckHARDWARE_QueryCommandBuffer(
+ IN gckHARDWARE Hardware,
+ IN gceENGINE Engine,
+ OUT gctUINT32 * Alignment,
+ OUT gctUINT32 * ReservedHead,
+ OUT gctUINT32 * ReservedTail
+ )
+{
+ gcmkHEADER_ARG("Hardware=0x%x", Hardware);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
+
+ if (Alignment != gcvNULL)
+ {
+ /* Align every 8 bytes. */
+ *Alignment = 8;
+ }
+
+ if (ReservedHead != gcvNULL)
+ {
+ /* Reserve space for SelectPipe(). */
+ *ReservedHead = 32;
+ }
+
+ if (ReservedTail != gcvNULL)
+ {
+ if (Engine == gcvENGINE_RENDER)
+ {
+ gcmkFOOTER_NO();
+ return gcvSTATUS_NOT_SUPPORTED;
+ }
+ else
+ {
+ *ReservedTail = gcdBLT_FENCE_LENGTH;
+ }
+ }
+
+ /* Success. */
+ gcmkFOOTER_ARG("*Alignment=%lu *ReservedHead=%lu *ReservedTail=%lu",
+ gcmOPT_VALUE(Alignment), gcmOPT_VALUE(ReservedHead),
+ gcmOPT_VALUE(ReservedTail));
+ return gcvSTATUS_OK;
+}
+
+/*******************************************************************************
+**
+** gckHARDWARE_QuerySystemMemory
+**
+** Query the command buffer alignment and number of reserved bytes.
+**
+** INPUT:
+**
+** gckHARDWARE Harwdare
+** Pointer to an gckHARDWARE object.
+**
+** OUTPUT:
+**
+** gctSIZE_T * SystemSize
+** Pointer to a variable that receives the maximum size of the system
+** memory.
+**
+** gctUINT32 * SystemBaseAddress
+** Poinetr to a variable that receives the base address for system
+** memory.
+*/
+gceSTATUS
+gckHARDWARE_QuerySystemMemory(
+ IN gckHARDWARE Hardware,
+ OUT gctSIZE_T * SystemSize,
+ OUT gctUINT32 * SystemBaseAddress
+ )
+{
+ gcmkHEADER_ARG("Hardware=0x%x", Hardware);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
+
+ if (SystemSize != gcvNULL)
+ {
+ /* Maximum system memory can be 2GB. */
+ *SystemSize = 1U << 31;
+ }
+
+ if (SystemBaseAddress != gcvNULL)
+ {
+ /* Set system memory base address. */
+ *SystemBaseAddress = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:31) - (0 ?
+ 31:31) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:31) - (0 ?
+ 31:31) + 1))))))) << (0 ?
+ 31:31))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ?
+ 31:31) - (0 ?
+ 31:31) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:31) - (0 ? 31:31) + 1))))))) << (0 ? 31:31)));
+ }
+
+ /* Success. */
+ gcmkFOOTER_ARG("*SystemSize=%lu *SystemBaseAddress=%lu",
+ gcmOPT_VALUE(SystemSize), gcmOPT_VALUE(SystemBaseAddress));
+ return gcvSTATUS_OK;
+}
+
+#if gcdENABLE_3D
+/*******************************************************************************
+**
+** gckHARDWARE_QueryShaderCaps
+**
+** Query the shader capabilities.
+**
+** INPUT:
+**
+** Nothing.
+**
+** OUTPUT:
+**
+** gctUINT * VertexUniforms
+** Pointer to a variable receiving the number of uniforms in the vertex
+** shader.
+**
+** gctUINT * FragmentUniforms
+** Pointer to a variable receiving the number of uniforms in the
+** fragment shader.
+**
+** gctBOOL * UnifiedUnforms
+** Pointer to a variable receiving whether the uniformas are unified.
+*/
+gceSTATUS
+gckHARDWARE_QueryShaderCaps(
+ IN gckHARDWARE Hardware,
+ OUT gctUINT * VertexUniforms,
+ OUT gctUINT * FragmentUniforms,
+ OUT gctBOOL * UnifiedUnforms
+ )
+{
+ gctBOOL unifiedConst;
+ gctUINT32 vsConstMax;
+ gctUINT32 psConstMax;
+ gctUINT32 vsConstBase;
+ gctUINT32 psConstBase;
+ gctUINT32 ConstMax;
+ gctBOOL halti5;
+
+ gcmkHEADER_ARG("Hardware=0x%x VertexUniforms=0x%x "
+ "FragmentUniforms=0x%x UnifiedUnforms=0x%x",
+ Hardware, VertexUniforms,
+ FragmentUniforms, UnifiedUnforms);
+
+ halti5 = gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_HALTI5);
+
+ {if (Hardware->identity.numConstants > 256){ unifiedConst = gcvTRUE;
+if (halti5){ vsConstBase = 0xD000;
+ psConstBase = 0xD800;
+}else{ vsConstBase = 0xC000;
+ psConstBase = 0xC000;
+}if ((Hardware->identity.chipModel == gcv880) && ((Hardware->identity.chipRevision & 0xfff0) == 0x5120)){ vsConstMax = 512;
+ psConstMax = 64;
+ ConstMax = 576;
+}else{ vsConstMax = gcmMIN(512, Hardware->identity.numConstants - 64);
+ psConstMax = gcmMIN(512, Hardware->identity.numConstants - 64);
+ ConstMax = Hardware->identity.numConstants;
+}}else if (Hardware->identity.numConstants == 256){ if (Hardware->identity.chipModel == gcv2000 && (Hardware->identity.chipRevision == 0x5118 || Hardware->identity.chipRevision == 0x5140)) { unifiedConst = gcvFALSE;
+ vsConstBase = 0x1400;
+ psConstBase = 0x1C00;
+ vsConstMax = 256;
+ psConstMax = 64;
+ ConstMax = 320;
+ } else { unifiedConst = gcvFALSE;
+ vsConstBase = 0x1400;
+ psConstBase = 0x1C00;
+ vsConstMax = 256;
+ psConstMax = 256;
+ ConstMax = 512;
+ }}else{ unifiedConst = gcvFALSE;
+ vsConstBase = 0x1400;
+ psConstBase = 0x1C00;
+ vsConstMax = 168;
+ psConstMax = 64;
+ ConstMax = 232;
+}};
+
+
+ if (VertexUniforms != gcvNULL)
+ {
+ /* Return the vs shader const count. */
+ *VertexUniforms = vsConstMax;
+ }
+
+ if (FragmentUniforms != gcvNULL)
+ {
+ /* Return the ps shader const count. */
+ *FragmentUniforms = psConstMax;
+ }
+
+ if (UnifiedUnforms != gcvNULL)
+ {
+ /* Return whether the uniformas are unified. */
+ *UnifiedUnforms = unifiedConst;
+ }
+
+ psConstBase = psConstBase;
+ vsConstBase = vsConstBase;
+ ConstMax = ConstMax;
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+}
+#endif
+
+/*******************************************************************************
+**
+** gckHARDWARE_SetMMU
+**
+** Set the page table base address.
+**
+** INPUT:
+**
+** gckHARDWARE Harwdare
+** Pointer to an gckHARDWARE object.
+**
+** gctPOINTER Logical
+** Logical address of the page table.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckHARDWARE_SetMMU(
+ IN gckHARDWARE Hardware,
+ IN gctPOINTER Logical
+ )
+{
+ gceSTATUS status;
+ gctUINT32 address = 0;
+ gctUINT32 idle;
+ gctUINT32 timer = 0, delay = 1;
+ gctPHYS_ADDR_T physical;
+
+ gcmkHEADER_ARG("Hardware=0x%x Logical=0x%x", Hardware, Logical);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
+
+ if (Hardware->mmuVersion == 0)
+ {
+ gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
+
+ /* Convert the logical address into physical address. */
+ gcmkONERROR(gckOS_GetPhysicalAddress(Hardware->os, Logical, &physical));
+
+ gcmkVERIFY_OK(gckOS_CPUPhysicalToGPUPhysical(Hardware->os, physical, &physical));
+
+ gcmkSAFECASTPHYSADDRT(address, physical);
+
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
+ "Setting page table to 0x%08X",
+ address);
+
+ /* Write the AQMemoryFePageTable register. */
+ gcmkONERROR(
+ gckOS_WriteRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x00400,
+ address));
+
+ /* Write the AQMemoryRaPageTable register. */
+ gcmkONERROR(
+ gckOS_WriteRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x00410,
+ address));
+
+ /* Write the AQMemoryTxPageTable register. */
+ gcmkONERROR(
+ gckOS_WriteRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x00404,
+ address));
+
+
+ /* Write the AQMemoryPePageTable register. */
+ gcmkONERROR(
+ gckOS_WriteRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x00408,
+ address));
+
+ /* Write the AQMemoryPezPageTable register. */
+ gcmkONERROR(
+ gckOS_WriteRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x0040C,
+ address));
+ }
+ else if (Hardware->options.enableMMU &&
+ (Hardware->options.secureMode != gcvSECURE_IN_TA))
+ {
+ gctBOOL hwMmuDisabled = gcvTRUE;
+
+ /* Force Disable MMU to guarantee setup command be read from physical addr */
+ if (Hardware->options.secureMode == gcvSECURE_IN_NORMAL)
+ {
+ gctUINT32 regMmuCtrl = 0;
+ gcmkONERROR(gckOS_ReadRegisterEx(
+ Hardware->os,
+ Hardware->core,
+ 0x00388,
+ &regMmuCtrl
+ ));
+
+ hwMmuDisabled = ((((((gctUINT32) (regMmuCtrl)) >> (0 ? 0:0)) & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1)))))) ) == 0x1)
+ ? gcvFALSE
+ : gcvTRUE;
+ }
+ else
+ {
+ gctUINT32 regMmuCtrl = 0;
+
+ gcmkONERROR(gckOS_ReadRegisterEx(
+ Hardware->os,
+ Hardware->core,
+ 0x0018C,
+ &regMmuCtrl
+ ));
+
+ hwMmuDisabled = ((((((gctUINT32) (regMmuCtrl)) >> (0 ? 0:0)) & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1)))))) ) == 0x1)
+ ? gcvFALSE
+ : gcvTRUE;
+ }
+
+ if (hwMmuDisabled)
+ {
+ /* Prepared command sequence contains an END,
+ ** so update lastEnd and store executeCount to END command.
+ */
+ gcsHARDWARE_FUNCTION *function = &Hardware->functions[gcvHARDWARE_FUNCTION_MMU];
+ gctUINT32_PTR endLogical = (gctUINT32_PTR)function->endLogical;
+
+ Hardware->lastEnd = function->endAddress;
+
+ *(endLogical + 1) = Hardware->executeCount + 1;
+
+ if (Hardware->options.secureMode == gcvSECURE_IN_NORMAL)
+ {
+ gctUINT32_PTR safeLogical = Hardware->kernel->mmu->safePageLogical;
+ gctUINT32 extSafeAddress;
+ /* Set up base address of page table array. */
+ gcmkONERROR(gckOS_WriteRegisterEx(
+ Hardware->os,
+ Hardware->core,
+ 0x0038C,
+ (gctUINT32)(Hardware->pagetableArray.address & 0xFFFFFFFF)
+ ));
+
+ gcmkONERROR(gckOS_WriteRegisterEx(
+ Hardware->os,
+ Hardware->core,
+ 0x00390,
+ (gctUINT32)((Hardware->pagetableArray.address >> 32) & 0xFFFFFFFF)
+ ));
+
+ gcmkONERROR(gckOS_WriteRegisterEx(
+ Hardware->os,
+ Hardware->core,
+ 0x00394,
+ 1
+ ));
+
+ gcmkONERROR(
+ gckOS_GetPhysicalAddress(Hardware->os, safeLogical, &physical));
+
+ gcmkVERIFY_OK(
+ gckOS_CPUPhysicalToGPUPhysical(Hardware->os, physical, &physical));
+
+ address = (gctUINT32)(physical & 0xFFFFFFFF);
+ extSafeAddress = (gctUINT32)(physical >> 32);
+
+ if (address & 0x3F)
+ {
+ gcmkONERROR(gcvSTATUS_NOT_ALIGNED);
+ }
+
+ /* more than 40bit physical address */
+ if (extSafeAddress & 0xFFFFFF00)
+ {
+ gcmkONERROR(gcvSTATUS_NOT_SUPPORTED);
+ }
+
+ gckOS_WriteRegisterEx(
+ Hardware->os,
+ Hardware->core,
+ 0x0039C,
+ address
+ );
+
+ gckOS_WriteRegisterEx(
+ Hardware->os,
+ Hardware->core,
+ 0x00398,
+ address
+ );
+
+ gckOS_WriteRegisterEx(
+ Hardware->os,
+ Hardware->core,
+ 0x003A0,
+ (((((gctUINT32) (~0U)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 23:16) - (0 ?
+ 23:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 23:16) - (0 ?
+ 23:16) + 1))))))) << (0 ?
+ 23:16))) | (((gctUINT32) ((gctUINT32) ((gctUINT32)extSafeAddress) & ((gctUINT32) ((((1 ?
+ 23:16) - (0 ?
+ 23:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 23:16) - (0 ?
+ 23:16) + 1))))))) << (0 ?
+ 23:16))) &((((gctUINT32) (~0U)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:31) - (0 ?
+ 31:31) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:31) - (0 ?
+ 31:31) + 1))))))) << (0 ?
+ 31:31))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ?
+ 31:31) - (0 ?
+ 31:31) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:31) - (0 ? 31:31) + 1))))))) << (0 ? 31:31))))
+ | (((((gctUINT32) (~0U)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1))))))) << (0 ?
+ 7:0))) | (((gctUINT32) ((gctUINT32) ((gctUINT32)extSafeAddress) & ((gctUINT32) ((((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1))))))) << (0 ?
+ 7:0))) &((((gctUINT32) (~0U)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:15) - (0 ?
+ 15:15) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:15) - (0 ?
+ 15:15) + 1))))))) << (0 ?
+ 15:15))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ?
+ 15:15) - (0 ?
+ 15:15) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:15) - (0 ? 15:15) + 1))))))) << (0 ? 15:15))))
+ );
+ }
+
+ /* Execute prepared command sequence. */
+ gcmkONERROR(gckHARDWARE_Execute(
+ Hardware,
+ function->address,
+ function->bytes
+ ));
+
+#if gcdLINK_QUEUE_SIZE
+ {
+ gcuQUEUEDATA data;
+
+ gcmkVERIFY_OK(gckOS_GetProcessID(&data.linkData.pid));
+
+ data.linkData.start = function->address;
+ data.linkData.end = function->address + function->bytes;
+ data.linkData.linkLow = 0;
+ data.linkData.linkHigh = 0;
+
+ gckQUEUE_Enqueue(&Hardware->linkQueue, &data);
+ }
+#endif
+
+ /* Wait until MMU configure finishes. */
+ do
+ {
+ gckOS_Delay(Hardware->os, delay);
+
+ gcmkONERROR(gckOS_ReadRegisterEx(
+ Hardware->os,
+ Hardware->core,
+ 0x00004,
+ &idle));
+
+ timer += delay;
+ delay *= 2;
+
+#if gcdGPU_TIMEOUT
+ if (timer >= Hardware->kernel->timeOut)
+ {
+ gckHARDWARE_DumpGPUState(Hardware);
+ gckCOMMAND_DumpExecutingBuffer(Hardware->kernel->command);
+
+ /* Even if hardware is not reset correctly, let software
+ ** continue to avoid software stuck. Software will timeout again
+ ** and try to recover GPU in next timeout.
+ */
+ gcmkONERROR(gcvSTATUS_DEVICE);
+ }
+#endif
+ }
+ while (!(((((gctUINT32) (idle)) >> (0 ? 0:0)) & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1)))))) ));
+
+ /* Enable MMU. */
+ if (Hardware->options.secureMode == gcvSECURE_IN_NORMAL)
+ {
+ gcmkONERROR(gckOS_WriteRegisterEx(
+ Hardware->os,
+ Hardware->core,
+ 0x00388,
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1))))))) << (0 ?
+ 0:0))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)))
+ ));
+ }
+ else
+ {
+ gcmkONERROR(gckOS_WriteRegisterEx(
+ Hardware->os,
+ Hardware->core,
+ 0x0018C,
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1))))))) << (0 ?
+ 0:0))) | (((gctUINT32) ((gctUINT32) (gcvTRUE) & ((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)))
+ ));
+ }
+ }
+ }
+
+ /* Return the status. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+gceSTATUS
+gckHARDWARE_FlushAsyncMMU(
+ IN gckHARDWARE Hardware,
+ IN gctPOINTER Logical,
+ IN OUT gctUINT32 * Bytes
+ )
+{
+ gctUINT32 semaphore, stall;
+ gctUINT32_PTR buffer;
+ gceSTATUS status;
+
+ gcmkHEADER_ARG("Hardware=0x%x Logical=0x%x *Bytes=%lu",
+ Hardware, Logical, gcmOPT_VALUE(Bytes));
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
+ gcmkVERIFY_ARGUMENT((Logical == gcvNULL) || (Bytes != gcvNULL));
+
+ if (Logical != gcvNULL)
+ {
+ buffer = (gctUINT32_PTR) Logical;
+
+ gcmkONERROR(gckOS_WriteMemory(
+ Hardware->os,
+ buffer,
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x502E) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+ ));
+
+ gcmkONERROR(gckOS_WriteMemory(
+ Hardware->os,
+ buffer + 1,
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1))))))) << (0 ?
+ 0:0))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)))
+ ));
+
+ gcmkONERROR(gckOS_WriteMemory(
+ Hardware->os,
+ buffer + 2,
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x0061) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+ ));
+
+ gcmkONERROR(gckOS_WriteMemory(
+ Hardware->os,
+ buffer + 3,
+ (((((gctUINT32) (~0U)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 4:4) - (0 ?
+ 4:4) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 4:4) - (0 ?
+ 4:4) + 1))))))) << (0 ?
+ 4:4))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 4:4) - (0 ?
+ 4:4) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 4:4) - (0 ?
+ 4:4) + 1))))))) << (0 ?
+ 4:4))) & ((((gctUINT32) (~0U)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 7:7) - (0 ?
+ 7:7) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 7:7) - (0 ?
+ 7:7) + 1))))))) << (0 ?
+ 7:7))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ?
+ 7:7) - (0 ?
+ 7:7) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 7:7) - (0 ? 7:7) + 1))))))) << (0 ? 7:7))))
+ ));
+
+ gcmkONERROR(gckOS_WriteMemory(
+ Hardware->os,
+ buffer + 4,
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E02) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+ ));
+
+ semaphore = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1))))))) << (0 ?
+ 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1))))))) << (0 ?
+ 12:8))) | (((gctUINT32) (0x10 & ((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
+
+ if (Hardware->stallFEPrefetch)
+ {
+ semaphore |= ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 29:28) - (0 ?
+ 29:28) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 29:28) - (0 ?
+ 29:28) + 1))))))) << (0 ?
+ 29:28))) | (((gctUINT32) (0x3 & ((gctUINT32) ((((1 ?
+ 29:28) - (0 ?
+ 29:28) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 29:28) - (0 ? 29:28) + 1))))))) << (0 ? 29:28)));
+ }
+
+ gcmkONERROR(gckOS_WriteMemory(
+ Hardware->os,
+ buffer + 5,
+ semaphore));
+
+ gcmkONERROR(gckOS_WriteMemory(
+ Hardware->os,
+ buffer + 6,
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x09 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ ));
+
+ stall = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1))))))) << (0 ?
+ 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1))))))) << (0 ?
+ 12:8))) | (((gctUINT32) (0x10 & ((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
+
+ if (Hardware->stallFEPrefetch)
+ {
+ stall |= ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 29:28) - (0 ?
+ 29:28) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 29:28) - (0 ?
+ 29:28) + 1))))))) << (0 ?
+ 29:28))) | (((gctUINT32) (0x3 & ((gctUINT32) ((((1 ?
+ 29:28) - (0 ?
+ 29:28) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 29:28) - (0 ? 29:28) + 1))))))) << (0 ? 29:28)));
+ }
+
+ gcmkONERROR(gckOS_WriteMemory(
+ Hardware->os,
+ buffer + 7,
+ stall));
+
+ gcmkONERROR(gckOS_WriteMemory(
+ Hardware->os,
+ buffer + 8,
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x502E) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+ ));
+
+ gcmkONERROR(gckOS_WriteMemory(
+ Hardware->os,
+ buffer + 9,
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1))))))) << (0 ?
+ 0:0))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)))
+ ));
+ }
+
+ if (Bytes != gcvNULL)
+ {
+ /* Return number of bytes required by the PIPESELECT command. */
+ *Bytes = 40;
+ }
+
+ /* Success. */
+ gcmkFOOTER_ARG("*Bytes=%lu", gcmOPT_VALUE(Bytes));
+ return gcvSTATUS_OK;
+
+OnError:
+ /* Success. */
+ gcmkFOOTER_ARG("*Bytes=%lu", gcmOPT_VALUE(Bytes));
+ return status;
+}
+
+/*******************************************************************************
+**
+** gckHARDWARE_FlushMMU
+**
+** Flush the page table.
+**
+** INPUT:
+**
+** gckHARDWARE Harwdare
+** Pointer to an gckHARDWARE object.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckHARDWARE_FlushMMU(
+ IN gckHARDWARE Hardware
+ )
+{
+ gceSTATUS status;
+ gckCOMMAND command;
+ gctUINT32_PTR buffer;
+ gctUINT32 bufferSize;
+ gctPOINTER pointer = gcvNULL;
+ gctUINT32 flushSize;
+ gctUINT32 count, offset;
+ gctUINT32 address;
+ gctUINT32 semaphore, stall;
+
+ gcmkHEADER_ARG("Hardware=0x%x", Hardware);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
+
+ /* Verify the gckCOMMAND object pointer. */
+ command = Hardware->kernel->command;
+
+ /* Flush the memory controller. */
+ if (Hardware->mmuVersion == 0)
+ {
+ gcmkONERROR(gckCOMMAND_Reserve(
+ command, 8, &pointer, &bufferSize
+ ));
+
+ buffer = (gctUINT32_PTR) pointer;
+
+ buffer[0]
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E04) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
+
+ buffer[1]
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1))))))) << (0 ?
+ 0:0))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 1:1) - (0 ?
+ 1:1) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 1:1) - (0 ?
+ 1:1) + 1))))))) << (0 ?
+ 1:1))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 1:1) - (0 ?
+ 1:1) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 2:2) - (0 ?
+ 2:2) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 2:2) - (0 ?
+ 2:2) + 1))))))) << (0 ?
+ 2:2))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 2:2) - (0 ?
+ 2:2) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 2:2) - (0 ? 2:2) + 1))))))) << (0 ? 2:2)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 3:3) - (0 ?
+ 3:3) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 3:3) - (0 ?
+ 3:3) + 1))))))) << (0 ?
+ 3:3))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 3:3) - (0 ?
+ 3:3) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 3:3) - (0 ? 3:3) + 1))))))) << (0 ? 3:3)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 4:4) - (0 ?
+ 4:4) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 4:4) - (0 ?
+ 4:4) + 1))))))) << (0 ?
+ 4:4))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 4:4) - (0 ?
+ 4:4) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 4:4) - (0 ? 4:4) + 1))))))) << (0 ? 4:4)));
+
+ gcmkONERROR(gckCOMMAND_Execute(command, 8));
+ }
+ else
+ {
+ gctUINT32 prefetchCount = 4;
+ gctBOOL bltEngine = gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_BLT_ENGINE);
+
+ flushSize = 10 * 4;
+ offset = 2;
+
+ if (bltEngine)
+ {
+ flushSize += 4 * 4;
+ prefetchCount += 2;
+ }
+
+ gcmkONERROR(gckCOMMAND_Reserve(
+ command, flushSize, &pointer, &bufferSize
+ ));
+
+ buffer = (gctUINT32_PTR) pointer;
+
+ count = ((gctUINT)bufferSize - flushSize + 7) >> 3;
+
+ address = command->address + command->offset;
+
+ /* LINK to next slot to flush FE FIFO. */
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x08 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (prefetchCount) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+
+ *buffer++
+ = address + offset * gcmSIZEOF(gctUINT32);
+
+ /* Flush MMU cache. */
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x0061) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
+
+ *buffer++
+ = (((((gctUINT32) (~0U)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 4:4) - (0 ?
+ 4:4) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 4:4) - (0 ?
+ 4:4) + 1))))))) << (0 ?
+ 4:4))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 4:4) - (0 ?
+ 4:4) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 4:4) - (0 ?
+ 4:4) + 1))))))) << (0 ?
+ 4:4))) & ((((gctUINT32) (~0U)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 7:7) - (0 ?
+ 7:7) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 7:7) - (0 ?
+ 7:7) + 1))))))) << (0 ?
+ 7:7))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ?
+ 7:7) - (0 ?
+ 7:7) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 7:7) - (0 ? 7:7) + 1))))))) << (0 ? 7:7))));
+
+ if (bltEngine)
+ {
+ /* Blt lock. */
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x502E) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1))))))) << (0 ?
+ 0:0))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)));
+ }
+
+ /* Arm the PE-FE Semaphore. */
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E02) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+
+ semaphore = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1))))))) << (0 ?
+ 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)));
+
+ if (Hardware->stallFEPrefetch)
+ {
+ semaphore |= ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 29:28) - (0 ?
+ 29:28) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 29:28) - (0 ?
+ 29:28) + 1))))))) << (0 ?
+ 29:28))) | (((gctUINT32) (0x3 & ((gctUINT32) ((((1 ?
+ 29:28) - (0 ?
+ 29:28) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 29:28) - (0 ? 29:28) + 1))))))) << (0 ? 29:28)));
+ }
+
+ if (bltEngine)
+ {
+ semaphore |= ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1))))))) << (0 ?
+ 12:8))) | (((gctUINT32) (0x10 & ((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
+ }
+ else
+ {
+ semaphore |= ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1))))))) << (0 ?
+ 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
+ }
+
+ *buffer++
+ = semaphore;
+
+ /* STALL FE until PE is done flushing. */
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x09 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)));
+
+ stall = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1))))))) << (0 ?
+ 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)));
+
+ if (Hardware->stallFEPrefetch)
+ {
+ stall |= ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 29:28) - (0 ?
+ 29:28) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 29:28) - (0 ?
+ 29:28) + 1))))))) << (0 ?
+ 29:28))) | (((gctUINT32) (0x3 & ((gctUINT32) ((((1 ?
+ 29:28) - (0 ?
+ 29:28) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 29:28) - (0 ? 29:28) + 1))))))) << (0 ? 29:28)));
+ }
+
+ if (bltEngine)
+ {
+ stall |= ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1))))))) << (0 ?
+ 12:8))) | (((gctUINT32) (0x10 & ((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
+ }
+ else
+ {
+ stall |= ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1))))))) << (0 ?
+ 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
+ }
+
+ *buffer++
+ = stall;
+
+ if (bltEngine)
+ {
+ /* Blt unlock. */
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x502E) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1))))))) << (0 ?
+ 0:0))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)));
+ }
+
+ /* LINK to next slot to flush FE FIFO. */
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x08 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (count) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+
+ *buffer++
+ = address + flushSize;
+
+ gcmkONERROR(gckCOMMAND_Execute(command, flushSize));
+ }
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+gceSTATUS
+gckHARDWARE_SetMMUStates(
+ IN gckHARDWARE Hardware,
+ IN gctPOINTER MtlbAddress,
+ IN gceMMU_MODE Mode,
+ IN gctPOINTER SafeAddress,
+ IN gctPOINTER Logical,
+ IN OUT gctUINT32 * Bytes
+ )
+{
+ gceSTATUS status;
+ gctUINT32 config, address;
+ gctUINT32 extMtlb, extSafeAddress, configEx = 0;
+ gctPHYS_ADDR_T physical;
+ gctUINT32_PTR buffer;
+ gctBOOL ace;
+ gctUINT32 reserveBytes = 0;
+ gcsMMU_TABLE_ARRAY_ENTRY * entry;
+
+ gctBOOL config2D;
+
+ gcmkHEADER_ARG("Hardware=0x%x", Hardware);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
+ gcmkVERIFY_ARGUMENT(Hardware->mmuVersion != 0);
+
+ entry = (gcsMMU_TABLE_ARRAY_ENTRY *) Hardware->pagetableArray.logical;
+
+ ace = gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_ACE);
+
+ switch (Hardware->options.secureMode)
+ {
+ case gcvSECURE_IN_NORMAL:
+ reserveBytes = 8 + 4 * 4;
+ break;
+ case gcvSECURE_NONE:
+ reserveBytes = 16 + 4 * 4;
+ if (ace)
+ {
+ reserveBytes += 8;
+ }
+ break;
+ case gcvSECURE_IN_TA:
+ default:
+ gcmkASSERT(gcvFALSE);
+ gcmkPRINT("%s(%d): secureMode is wrong", __FUNCTION__, __LINE__);
+ break;
+ }
+
+ config2D = gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_PIPE_3D)
+ && gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_PIPE_2D);
+
+ if (config2D)
+ {
+ reserveBytes +=
+ /* Pipe Select. */
+ 4 * 4
+ /* Configure MMU States. */
+ + 4 * 4
+ /* Semaphore stall */
+ + 4 * 8;
+
+ if (ace)
+ {
+ reserveBytes += 8;
+ }
+ }
+
+ reserveBytes += 8;
+
+ /* Convert logical address into physical address. */
+ gcmkONERROR(
+ gckOS_GetPhysicalAddress(Hardware->os, MtlbAddress, &physical));
+
+ gcmkVERIFY_OK(
+ gckOS_CPUPhysicalToGPUPhysical(Hardware->os, physical, &physical));
+
+ config = (gctUINT32)(physical & 0xFFFFFFFF);
+ extMtlb = (gctUINT32)(physical >> 32);
+
+ /* more than 40bit physical address */
+ if (extMtlb & 0xFFFFFF00)
+ {
+ gcmkONERROR(gcvSTATUS_NOT_SUPPORTED);
+ }
+
+ gcmkONERROR(
+ gckOS_GetPhysicalAddress(Hardware->os, SafeAddress, &physical));
+
+ gcmkVERIFY_OK(
+ gckOS_CPUPhysicalToGPUPhysical(Hardware->os, physical, &physical));
+
+ address = (gctUINT32)(physical & 0xFFFFFFFF);
+ extSafeAddress = (gctUINT32)(physical >> 32);
+
+ if (address & 0x3F)
+ {
+ gcmkONERROR(gcvSTATUS_NOT_ALIGNED);
+ }
+
+ /* more than 40bit physical address */
+ if (extSafeAddress & 0xFFFFFF00)
+ {
+ gcmkONERROR(gcvSTATUS_NOT_SUPPORTED);
+ }
+
+ if (ace)
+ {
+ configEx = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1))))))) << (0 ?
+ 7:0))) | (((gctUINT32) ((gctUINT32) (extSafeAddress) & ((gctUINT32) ((((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 23:16) - (0 ?
+ 23:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 23:16) - (0 ?
+ 23:16) + 1))))))) << (0 ?
+ 23:16))) | (((gctUINT32) ((gctUINT32) (extMtlb) & ((gctUINT32) ((((1 ?
+ 23:16) - (0 ?
+ 23:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16)));
+ }
+
+ switch (Mode)
+ {
+ case gcvMMU_MODE_1K:
+ if (config & 0x3FF)
+ {
+ gcmkONERROR(gcvSTATUS_NOT_ALIGNED);
+ }
+
+ config |= ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1))))))) << (0 ?
+ 0:0))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)));
+
+ break;
+
+ case gcvMMU_MODE_4K:
+ if (config & 0xFFF)
+ {
+ gcmkONERROR(gcvSTATUS_NOT_ALIGNED);
+ }
+
+ config |= ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1))))))) << (0 ?
+ 0:0))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)));
+
+ break;
+
+ default:
+ gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
+ }
+
+ if (Logical != gcvNULL)
+ {
+ buffer = Logical;
+
+ if (Hardware->options.secureMode == gcvSECURE_IN_NORMAL)
+ {
+ /* Setup page table array entry. */
+ if (Hardware->bigEndian)
+ {
+ entry->low = gcmBSWAP32(config);
+ entry->high = gcmBSWAP32(extMtlb);
+ }
+ else
+ {
+ entry->low = config;
+ entry->high = extMtlb;
+ }
+
+ /* Setup command buffer to load index 0 of page table array. */
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x006B) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
+
+ *buffer++
+ = (((((gctUINT32) (~0U)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) &((((gctUINT32) (~0U)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 16:16) - (0 ?
+ 16:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 16:16) - (0 ?
+ 16:16) + 1))))))) << (0 ?
+ 16:16))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ?
+ 16:16) - (0 ?
+ 16:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 16:16) - (0 ? 16:16) + 1))))))) << (0 ? 16:16))));
+ }
+ else
+ {
+ gcmkASSERT(Hardware->options.secureMode == gcvSECURE_NONE);
+
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x0061) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
+
+ *buffer++ = config;
+
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x0060) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
+
+ *buffer++ = address;
+
+ if (ace)
+ {
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x0068) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
+
+ *buffer++
+ = configEx;
+ }
+ }
+
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E12) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
+
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 16:16) - (0 ?
+ 16:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 16:16) - (0 ?
+ 16:16) + 1))))))) << (0 ?
+ 16:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 16:16) - (0 ?
+ 16:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 16:16) - (0 ? 16:16) + 1))))))) << (0 ? 16:16)));
+
+ do{*buffer++ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E02) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))); *buffer++ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1))))))) << (0 ?
+ 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1))))))) << (0 ?
+ 4:0))) | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1))))))) << (0 ?
+ 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))); *buffer++ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x09 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))); *buffer++ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1))))))) << (0 ?
+ 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1))))))) << (0 ?
+ 4:0))) | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1))))))) << (0 ?
+ 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));} while(0);
+;
+
+
+ if (config2D)
+ {
+ /* LoadState(AQPipeSelect, 1), pipe. */
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E00) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
+
+ *buffer++ = 0x1;
+
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x0061) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
+
+ *buffer++ = config;
+
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x0060) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
+
+ *buffer++ = address;
+
+ if (ace)
+ {
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x0068) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
+
+ *buffer++
+ = configEx;
+ }
+
+ do{*buffer++ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E02) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))); *buffer++ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1))))))) << (0 ?
+ 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1))))))) << (0 ?
+ 4:0))) | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1))))))) << (0 ?
+ 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))); *buffer++ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x09 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))); *buffer++ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1))))))) << (0 ?
+ 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1))))))) << (0 ?
+ 4:0))) | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1))))))) << (0 ?
+ 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));} while(0);
+;
+
+
+ /* LoadState(AQPipeSelect, 1), pipe. */
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E00) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
+
+ *buffer++ = 0x0;
+
+ do{*buffer++ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E02) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))); *buffer++ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1))))))) << (0 ?
+ 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1))))))) << (0 ?
+ 4:0))) | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1))))))) << (0 ?
+ 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))); *buffer++ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x09 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))); *buffer++ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1))))))) << (0 ?
+ 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1))))))) << (0 ?
+ 4:0))) | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1))))))) << (0 ?
+ 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));} while(0);
+;
+
+ }
+
+ }
+
+ if (Bytes != gcvNULL)
+ {
+ *Bytes = reserveBytes;
+ }
+
+ /* Return the status. */
+ gcmkFOOTER_NO();
+ return status;
+
+OnError:
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+#if gcdPROCESS_ADDRESS_SPACE
+/*******************************************************************************
+**
+** gckHARDWARE_ConfigMMU
+**
+** Append a MMU Configuration command sequence at the specified location in the command
+** queue. That command sequence consists of mmu configuration, LINK and WAIT/LINK.
+** LINK is fetched and paresed with new mmu configuration.
+**
+** If MMU Configuration is not changed between commit, change last WAIT/LINK to
+** link to ENTRY.
+**
+** -+-----------+-----------+-----------------------------------------
+** | WAIT/LINK | WAIT/LINK |
+** -+-----------+-----------+-----------------------------------------
+** | /|\
+** \|/ |
+** +--------------------+
+** | ENTRY | ... | LINK |
+** +--------------------+
+**
+** If MMU Configuration is changed between commit, change last WAIT/LINK to
+** link to MMU CONFIGURATION command sequence, and there are an EVNET and
+** an END at the end of this command sequence, when interrupt handler
+** receives this event, it will start FE at ENTRY to continue the command
+** buffer execution.
+**
+** -+-----------+-------------------+---------+---------+-----------+--
+** | WAIT/LINK | MMU CONFIGURATION | EVENT | END | WAIT/LINK |
+** -+-----------+-------------------+---------+---------+-----------+--
+** | /|\ /|\
+** +-------------+ |
+** +--------------------+
+** | ENTRY | ... | LINK |
+** +--------------------+
+** INPUT:
+**
+** gckHARDWARE Hardware
+** Pointer to an gckHARDWARE object.
+**
+** gctPOINTER Logical
+** Pointer to the current location inside the command queue to append
+** command sequence at or gcvNULL just to query the size of the
+** command sequence.
+**
+** gctPOINTER MtlbLogical
+** Pointer to the current Master TLB.
+**
+** gctUINT32 Offset
+** Offset into command buffer required for alignment.
+**
+** gctSIZE_T * Bytes
+** Pointer to the number of bytes available for the command
+** sequence. If 'Logical' is gcvNULL, this argument will be ignored.
+**
+** OUTPUT:
+**
+** gctSIZE_T * Bytes
+** Pointer to a variable that will receive the number of bytes required
+** by the command sequence. If 'Bytes' is gcvNULL, nothing will
+** be returned.
+**
+** gctUINT32 * WaitLinkOffset
+** Pointer to a variable that will receive the offset of the WAIT/LINK command
+** from the specified logcial pointer.
+** If 'WaitLinkOffset' is gcvNULL nothing will be returned.
+**
+** gctSIZE_T * WaitLinkBytes
+** Pointer to a variable that will receive the number of bytes used by
+** the WAIT command.
+** If 'WaitLinkBytes' is gcvNULL nothing will be returned.
+*/
+gceSTATUS
+gckHARDWARE_ConfigMMU(
+ IN gckHARDWARE Hardware,
+ IN gctPOINTER Logical,
+ IN gctPOINTER MtlbLogical,
+ IN gctUINT32 Offset,
+ IN OUT gctSIZE_T * Bytes,
+ OUT gctSIZE_T * WaitLinkOffset,
+ OUT gctSIZE_T * WaitLinkBytes
+ )
+{
+ gceSTATUS status;
+ gctSIZE_T bytes, bytesAligned;
+ gctUINT32 config;
+ gctUINT32_PTR buffer = (gctUINT32_PTR) Logical;
+ gctPHYS_ADDR_T physical;
+ gctUINT32 address;
+ gctUINT32 event;
+ gctSIZE_T stCmds; /* semaphore stall cmd size */;
+
+ gcmkHEADER_ARG("Hardware=0x%08X Logical=0x%08x MtlbLogical=0x%08X",
+ Hardware, Logical, MtlbLogical);
+
+ stCmds = gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_TEX_CACHE_FLUSH_FIX) ? 0 : 4;
+
+ bytes
+ /* Semaphore stall states. */
+ = stCmds * 4
+ /* Flush cache states. */
+ + 20 * 4
+ /* MMU configuration states. */
+ + 6 * 4
+ /* EVENT. */
+ + 2 * 4
+ /* END. */
+ + 2 * 4
+ /* WAIT/LINK. */
+ + 4 * 4;
+
+ /* Compute number of bytes required. */
+ bytesAligned = gcmALIGN(Offset + bytes, 8) - Offset;
+
+ if (buffer != gcvNULL)
+ {
+ if (MtlbLogical == gcvNULL)
+ {
+ gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
+ }
+
+ /* Get physical address of this command buffer segment. */
+ gcmkONERROR(gckOS_GetPhysicalAddress(Hardware->os, buffer, &physical));
+
+ gcmkVERIFY_OK(gckOS_CPUPhysicalToGPUPhysical(
+ Hardware->os,
+ physical,
+ &physical
+ ));
+
+ gcmkSAFECASTPHYSADDRT(address, physical);
+
+ /* Get physical address of Master TLB. */
+ gcmkONERROR(gckOS_GetPhysicalAddress(Hardware->os, MtlbLogical, &physical));
+
+ gcmkVERIFY_OK(gckOS_CPUPhysicalToGPUPhysical(
+ Hardware->os,
+ physical,
+ &physical
+ ));
+
+ gcmkSAFECASTPHYSADDRT(config, physical);
+
+ config |= ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1))))))) << (0 ?
+ 0:0))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 4:4) - (0 ?
+ 4:4) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 4:4) - (0 ?
+ 4:4) + 1))))))) << (0 ?
+ 4:4))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 4:4) - (0 ?
+ 4:4) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 4:4) - (0 ? 4:4) + 1))))))) << (0 ? 4:4)));
+
+ if (stCmds)
+ {
+ /* Arm the PE-FE Semaphore. */
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E02) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1))))))) << (0 ?
+ 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1))))))) << (0 ?
+ 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
+
+ /* STALL FE until PE is done flushing. */
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x09 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)));
+
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1))))))) << (0 ?
+ 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1))))))) << (0 ?
+ 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
+ }
+
+ /* Flush cache. */
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E03) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 3:3) - (0 ?
+ 3:3) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 3:3) - (0 ?
+ 3:3) + 1))))))) << (0 ?
+ 3:3))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 3:3) - (0 ?
+ 3:3) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 3:3) - (0 ? 3:3) + 1))))))) << (0 ? 3:3)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 1:1) - (0 ?
+ 1:1) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 1:1) - (0 ?
+ 1:1) + 1))))))) << (0 ?
+ 1:1))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 1:1) - (0 ?
+ 1:1) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1))))))) << (0 ?
+ 0:0))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 2:2) - (0 ?
+ 2:2) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 2:2) - (0 ?
+ 2:2) + 1))))))) << (0 ?
+ 2:2))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 2:2) - (0 ?
+ 2:2) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 2:2) - (0 ? 2:2) + 1))))))) << (0 ? 2:2)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 5:5) - (0 ?
+ 5:5) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 5:5) - (0 ?
+ 5:5) + 1))))))) << (0 ?
+ 5:5))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 5:5) - (0 ?
+ 5:5) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 5:5) - (0 ? 5:5) + 1))))))) << (0 ? 5:5)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ AQ_FLUSH_VSHL1_CACHE) - (0 ?
+ AQ_FLUSH_VSHL1_CACHE) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ AQ_FLUSH_VSHL1_CACHE) - (0 ?
+ AQ_FLUSH_VSHL1_CACHE) + 1))))))) << (0 ?
+ AQ_FLUSH_VSHL1_CACHE))) | (((gctUINT32) (AQ_FLUSH_VSHL1_CACHE_ENABLE & ((gctUINT32) ((((1 ?
+ AQ_FLUSH_VSHL1_CACHE) - (0 ?
+ AQ_FLUSH_VSHL1_CACHE) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ AQ_FLUSH_VSHL1_CACHE) - (0 ?
+ AQ_FLUSH_VSHL1_CACHE) + 1))))))) << (0 ? AQ_FLUSH_VSHL1_CACHE)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ AQ_FLUSH_PSHL1_CACHE) - (0 ?
+ AQ_FLUSH_PSHL1_CACHE) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ AQ_FLUSH_PSHL1_CACHE) - (0 ?
+ AQ_FLUSH_PSHL1_CACHE) + 1))))))) << (0 ?
+ AQ_FLUSH_PSHL1_CACHE))) | (((gctUINT32) (AQ_FLUSH_PSHL1_CACHE_ENABLE & ((gctUINT32) ((((1 ?
+ AQ_FLUSH_PSHL1_CACHE) - (0 ?
+ AQ_FLUSH_PSHL1_CACHE) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ AQ_FLUSH_PSHL1_CACHE) - (0 ?
+ AQ_FLUSH_PSHL1_CACHE) + 1))))))) << (0 ? AQ_FLUSH_PSHL1_CACHE)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 6:6) - (0 ?
+ 6:6) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 6:6) - (0 ?
+ 6:6) + 1))))))) << (0 ?
+ 6:6))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 6:6) - (0 ?
+ 6:6) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 6:6) - (0 ? 6:6) + 1))))))) << (0 ? 6:6)));
+
+ /* Flush VTS in separate command */
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E03) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 4:4) - (0 ?
+ 4:4) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 4:4) - (0 ?
+ 4:4) + 1))))))) << (0 ?
+ 4:4))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 4:4) - (0 ?
+ 4:4) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 4:4) - (0 ? 4:4) + 1))))))) << (0 ? 4:4)));
+
+ /* Flush tile status cache. */
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x0594) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1))))))) << (0 ?
+ 0:0))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)));
+
+ /* Arm the PE-FE Semaphore. */
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E02) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1))))))) << (0 ?
+ 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1))))))) << (0 ?
+ 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
+
+ /* STALL FE until PE is done flushing. */
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x09 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)));
+
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1))))))) << (0 ?
+ 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1))))))) << (0 ?
+ 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
+
+ /* LINK to next slot to flush FE FIFO. */
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x08 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (4) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+
+ *buffer++
+ = address + (stCmds + 12) * gcmSIZEOF(gctUINT32);
+
+ /* Configure MMU. */
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x0061) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
+
+ *buffer++
+ = (((((gctUINT32) (~0U)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 4:4) - (0 ?
+ 4:4) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 4:4) - (0 ?
+ 4:4) + 1))))))) << (0 ?
+ 4:4))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 4:4) - (0 ?
+ 4:4) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 4:4) - (0 ?
+ 4:4) + 1))))))) << (0 ?
+ 4:4))) & ((((gctUINT32) (~0U)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 7:7) - (0 ?
+ 7:7) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 7:7) - (0 ?
+ 7:7) + 1))))))) << (0 ?
+ 7:7))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ?
+ 7:7) - (0 ?
+ 7:7) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 7:7) - (0 ? 7:7) + 1))))))) << (0 ? 7:7))));
+
+ /* Arm the PE-FE Semaphore. */
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E02) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1))))))) << (0 ?
+ 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1))))))) << (0 ?
+ 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
+
+ /* STALL FE until PE is done flushing. */
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x09 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)));
+
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1))))))) << (0 ?
+ 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1))))))) << (0 ?
+ 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
+
+ /* LINK to next slot to flush FE FIFO. */
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x08 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (5) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+
+ *buffer++
+ = physical + (stCmds + 20) * 4;
+
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x0061) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
+
+ *buffer++
+ = config;
+
+ /* Arm the PE-FE Semaphore. */
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E02) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1))))))) << (0 ?
+ 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1))))))) << (0 ?
+ 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
+
+ /* STALL FE until PE is done flushing. */
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x09 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)));
+
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1))))))) << (0 ?
+ 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1))))))) << (0 ?
+ 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
+
+ /* Event 29. */
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E01) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
+
+ event = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 6:6) - (0 ?
+ 6:6) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 6:6) - (0 ?
+ 6:6) + 1))))))) << (0 ?
+ 6:6))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 6:6) - (0 ?
+ 6:6) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 6:6) - (0 ? 6:6) + 1))))))) << (0 ? 6:6)));
+ event = ((((gctUINT32) (event)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1))))))) << (0 ?
+ 4:0))) | (((gctUINT32) ((gctUINT32) (29) & ((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)));
+
+ *buffer++
+ = event;
+
+ /* Append END. */
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x02 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)));
+ }
+
+ if (Bytes != gcvNULL)
+ {
+ *Bytes = bytesAligned;
+ }
+
+ if (WaitLinkOffset != gcvNULL)
+ {
+ *WaitLinkOffset = bytes - 4 * 4;
+ }
+
+ if (WaitLinkBytes != gcvNULL)
+ {
+ *WaitLinkBytes = 4 * 4;
+ }
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ gcmkFOOTER();
+ return status;
+}
+#endif
+
+/*******************************************************************************
+**
+** gckHARDWARE_BuildVirtualAddress
+**
+** Build a virtual address.
+**
+** INPUT:
+**
+** gckHARDWARE Harwdare
+** Pointer to an gckHARDWARE object.
+**
+** gctUINT32 Index
+** Index into page table.
+**
+** gctUINT32 Offset
+** Offset into page.
+**
+** OUTPUT:
+**
+** gctUINT32 * Address
+** Pointer to a variable receiving te hardware address.
+*/
+gceSTATUS
+gckHARDWARE_BuildVirtualAddress(
+ IN gckHARDWARE Hardware,
+ IN gctUINT32 Index,
+ IN gctUINT32 Offset,
+ OUT gctUINT32 * Address
+ )
+{
+ gcmkHEADER_ARG("Hardware=0x%x Index=%u Offset=%u", Hardware, Index, Offset);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
+ gcmkVERIFY_ARGUMENT(Address != gcvNULL);
+
+ /* Build virtual address. */
+ *Address = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:31) - (0 ?
+ 31:31) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:31) - (0 ?
+ 31:31) + 1))))))) << (0 ?
+ 31:31))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 31:31) - (0 ?
+ 31:31) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:31) - (0 ? 31:31) + 1))))))) << (0 ? 31:31)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 30:0) - (0 ?
+ 30:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 30:0) - (0 ?
+ 30:0) + 1))))))) << (0 ?
+ 30:0))) | (((gctUINT32) ((gctUINT32) (Offset | (Index << 12)) & ((gctUINT32) ((((1 ?
+ 30:0) - (0 ?
+ 30:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 30:0) - (0 ? 30:0) + 1))))))) << (0 ? 30:0)));
+
+ /* Success. */
+ gcmkFOOTER_ARG("*Address=0x%08x", *Address);
+ return gcvSTATUS_OK;
+}
+
+gceSTATUS
+gckHARDWARE_GetIdle(
+ IN gckHARDWARE Hardware,
+ IN gctBOOL Wait,
+ OUT gctUINT32 * Data
+ )
+{
+ gceSTATUS status;
+ gctUINT32 idle = 0;
+ gctINT retry, poll, pollCount;
+ gctUINT32 address;
+
+ gcmkHEADER_ARG("Hardware=0x%x Wait=%d", Hardware, Wait);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
+ gcmkVERIFY_ARGUMENT(Data != gcvNULL);
+
+
+ /* If we have to wait, try 100 polls per millisecond. */
+ pollCount = Wait ? 100 : 1;
+
+ /* At most, try for 1 second. */
+ for (retry = 0; retry < 1000; ++retry)
+ {
+ /* If we have to wait, try 100 polls per millisecond. */
+ for (poll = pollCount; poll > 0; --poll)
+ {
+ /* Read register. */
+ gcmkONERROR(
+ gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00004, &idle));
+
+ /* Read the current FE address. */
+ gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x00664,
+ &address));
+
+ gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x00664,
+ &address));
+
+ /* See if we have to wait for FE idle. */
+ if (_IsGPUIdle(idle)
+ && (address == Hardware->lastEnd + 8)
+ )
+ {
+ /* FE is idle. */
+ break;
+ }
+ }
+
+ /* Check if we need to wait for FE and FE is busy. */
+ if (Wait && !_IsGPUIdle(idle))
+ {
+ /* Wait a little. */
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
+ "%s: Waiting for idle: 0x%08X",
+ __FUNCTION__, idle);
+
+ gcmkVERIFY_OK(gckOS_Delay(Hardware->os, 1));
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ /* Return idle to caller. */
+ *Data = idle;
+
+#if defined(EMULATOR)
+ /* Wait a little while until CModel FE gets END.
+ * END is supposed to be appended by caller.
+ */
+ gckOS_Delay(Hardware->os, 100);
+#endif
+
+ /* Success. */
+ gcmkFOOTER_ARG("*Data=0x%08x", *Data);
+ return gcvSTATUS_OK;
+
+OnError:
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+/* Flush the caches. */
+gceSTATUS
+gckHARDWARE_Flush(
+ IN gckHARDWARE Hardware,
+ IN gceKERNEL_FLUSH Flush,
+ IN gctPOINTER Logical,
+ IN OUT gctUINT32 * Bytes
+ )
+{
+ gctUINT32 pipe;
+ gctUINT32 flush = 0;
+ gctUINT32 flushVST = 0;
+ gctBOOL flushTileStatus;
+ gctUINT32_PTR logical = (gctUINT32_PTR) Logical;
+ gceSTATUS status;
+ gctBOOL halti5;
+ gctBOOL flushICache;
+ gctBOOL flushTXDescCache;
+ gctBOOL flushTFB;
+ gctBOOL hwTFB;
+ gctBOOL blt;
+ gctBOOL peTSFlush;
+
+ gcmkHEADER_ARG("Hardware=0x%x Flush=0x%x Logical=0x%x *Bytes=%lu",
+ Hardware, Flush, Logical, gcmOPT_VALUE(Bytes));
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
+
+ /* Get current pipe. */
+ pipe = Hardware->kernel->command->pipeSelect;
+
+ halti5 = gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_HALTI5);
+
+ hwTFB = gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_HW_TFB);
+
+ blt = gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_BLT_ENGINE);
+
+ peTSFlush = gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_PE_TILE_CACHE_FLUSH_FIX);
+
+ /* Flush tile status cache. */
+ flushTileStatus = Flush & gcvFLUSH_TILE_STATUS;
+
+ /* Flush Icache for halti5 hardware as we dont do it when program or context switches*/
+ flushICache = (Flush & gcvFLUSH_ICACHE) && halti5;
+
+ /* Flush texture descriptor cache */
+ flushTXDescCache = Flush & gcvFLUSH_TXDESC;
+
+ /* Flush USC cache for TFB client */
+ flushTFB = (Flush & gcvFLUSH_TFBHEADER) && hwTFB;
+
+ /* Flush TFB for vertex buffer */
+ if (hwTFB && (Flush & gcvFLUSH_VERTEX))
+ {
+ flushTFB = gcvTRUE;
+ }
+
+ /* Flush 3D color cache. */
+ if ((Flush & gcvFLUSH_COLOR) && (pipe == 0x0))
+ {
+ flush |= ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 1:1) - (0 ?
+ 1:1) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 1:1) - (0 ?
+ 1:1) + 1))))))) << (0 ?
+ 1:1))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 1:1) - (0 ?
+ 1:1) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1)));
+ }
+
+ /* Flush 3D depth cache. */
+ if ((Flush & gcvFLUSH_DEPTH) && (pipe == 0x0))
+ {
+ flush |= ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1))))))) << (0 ?
+ 0:0))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)));
+ }
+
+ /* Flush 3D texture cache. */
+ if ((Flush & gcvFLUSH_TEXTURE) && (pipe == 0x0))
+ {
+ flush |= ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 2:2) - (0 ?
+ 2:2) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 2:2) - (0 ?
+ 2:2) + 1))))))) << (0 ?
+ 2:2))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 2:2) - (0 ?
+ 2:2) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 2:2) - (0 ? 2:2) + 1))))))) << (0 ? 2:2)));
+ flushVST = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 4:4) - (0 ?
+ 4:4) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 4:4) - (0 ?
+ 4:4) + 1))))))) << (0 ?
+ 4:4))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 4:4) - (0 ?
+ 4:4) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 4:4) - (0 ? 4:4) + 1))))))) << (0 ? 4:4)));
+ }
+
+ /* Flush 2D cache. */
+ if ((Flush & gcvFLUSH_2D) && (pipe == 0x1))
+ {
+ flush |= ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 3:3) - (0 ?
+ 3:3) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 3:3) - (0 ?
+ 3:3) + 1))))))) << (0 ?
+ 3:3))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 3:3) - (0 ?
+ 3:3) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 3:3) - (0 ? 3:3) + 1))))))) << (0 ? 3:3)));
+ }
+
+ /* Flush L2 cache. */
+ if ((Flush & gcvFLUSH_L2) && (pipe == 0x0))
+ {
+ flush |= ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 6:6) - (0 ?
+ 6:6) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 6:6) - (0 ?
+ 6:6) + 1))))))) << (0 ?
+ 6:6))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 6:6) - (0 ?
+ 6:6) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 6:6) - (0 ? 6:6) + 1))))))) << (0 ? 6:6)));
+ }
+
+ /* Vertex buffer and texture could be touched by SHL1 for SSBO and image load/store */
+ if ((Flush & (gcvFLUSH_VERTEX | gcvFLUSH_TEXTURE)) && (pipe == 0x0))
+ {
+ flush |= ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 5:5) - (0 ?
+ 5:5) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 5:5) - (0 ?
+ 5:5) + 1))))))) << (0 ?
+ 5:5))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 5:5) - (0 ?
+ 5:5) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 5:5) - (0 ? 5:5) + 1))))))) << (0 ? 5:5)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 10:10) - (0 ?
+ 10:10) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 10:10) - (0 ?
+ 10:10) + 1))))))) << (0 ?
+ 10:10))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 10:10) - (0 ?
+ 10:10) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 10:10) - (0 ? 10:10) + 1))))))) << (0 ? 10:10)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 11:11) - (0 ?
+ 11:11) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 11:11) - (0 ?
+ 11:11) + 1))))))) << (0 ?
+ 11:11))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 11:11) - (0 ?
+ 11:11) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 11:11) - (0 ? 11:11) + 1))))))) << (0 ? 11:11)));
+ }
+
+ /* See if there is a valid flush. */
+ if ((flush == 0) &&
+ (flushTileStatus == gcvFALSE) &&
+ (flushICache == gcvFALSE) &&
+ (flushTXDescCache == gcvFALSE) &&
+ (flushTFB == gcvFALSE))
+ {
+ if (Bytes != gcvNULL)
+ {
+ /* No bytes required. */
+ *Bytes = 0;
+ }
+ }
+ else
+ {
+ gctUINT32 reserveBytes = 0;
+ gctBOOL txCacheFix = gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_TEX_CACHE_FLUSH_FIX)
+ ? gcvTRUE : gcvFALSE;
+
+ /* Determine reserve bytes. */
+ if (!txCacheFix || flushICache || flushTXDescCache)
+ {
+ /* Semaphore/Stall */
+ reserveBytes += blt ? (8 * gcmSIZEOF(gctUINT32)) : (4 * gcmSIZEOF(gctUINT32));
+ }
+
+ if (flush)
+ {
+ reserveBytes += 2 * gcmSIZEOF(gctUINT32);
+ }
+
+ if (flushVST)
+ {
+ reserveBytes += 2 * gcmSIZEOF(gctUINT32);
+ }
+
+ if (flushTileStatus)
+ {
+ reserveBytes += (!peTSFlush && blt) ? 6 * gcmSIZEOF(gctUINT32) : 2 * gcmSIZEOF(gctUINT32);
+ }
+
+ if (flushICache)
+ {
+ reserveBytes += 2 * gcmSIZEOF(gctUINT32);
+ }
+
+ if (flushTXDescCache)
+ {
+ reserveBytes += 2 * gcmSIZEOF(gctUINT32);
+ }
+
+ if (flushTFB)
+ {
+ reserveBytes += 2 * gcmSIZEOF(gctUINT32);
+ }
+
+ /* Semaphore/Stall */
+ reserveBytes += blt ? (8 * gcmSIZEOF(gctUINT32)) : (4 * gcmSIZEOF(gctUINT32));
+
+ /* Copy to command queue. */
+ if (Logical != gcvNULL)
+ {
+ if (*Bytes < reserveBytes)
+ {
+ /* Command queue too small. */
+ gcmkONERROR(gcvSTATUS_BUFFER_TOO_SMALL);
+ }
+
+ if (!txCacheFix || flushICache || flushTXDescCache)
+ {
+ if (blt)
+ {
+ /* Semaphore from FE to BLT. */
+ *logical++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x502E) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+
+ *logical++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1))))))) << (0 ?
+ 0:0))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)));
+
+ *logical++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E02) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+
+ *logical++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1))))))) << (0 ?
+ 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1))))))) << (0 ?
+ 12:8))) | (((gctUINT32) (0x10 & ((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
+
+ /* Stall from FE to BLT. */
+ *logical++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x09 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)));
+
+ *logical++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1))))))) << (0 ?
+ 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1))))))) << (0 ?
+ 12:8))) | (((gctUINT32) (0x10 & ((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
+
+ *logical++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x502E) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+
+ *logical++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1))))))) << (0 ?
+ 0:0))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)));
+ }
+ else
+ {
+ /* Semaphore. */
+ *logical++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E02) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+
+ *logical++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1))))))) << (0 ?
+ 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1))))))) << (0 ?
+ 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
+
+ /* Stall. */
+ *logical++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x09 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)));
+
+ *logical++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1))))))) << (0 ?
+ 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1))))))) << (0 ?
+ 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
+ }
+ }
+
+ if (flush)
+ {
+ /* Append LOAD_STATE to AQFlush. */
+ *logical++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E03) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
+
+ *logical++ = flush;
+
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE, "0x%x: FLUSH 0x%x", logical - 1, flush);
+ }
+
+ if (flushVST)
+ {
+ /* Append LOAD_STATE to AQFlush. */
+ *logical++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E03) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
+
+ *logical++ = flushVST;
+
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE, "0x%x: FLUSH 0x%x", logical - 1, flush);
+ }
+
+ if (flushTileStatus)
+ {
+ if (!peTSFlush && blt)
+ {
+ *logical++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x502E) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+
+ *logical++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1))))))) << (0 ?
+ 0:0))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)));
+
+ *logical++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x502B) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
+
+ *logical++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1))))))) << (0 ?
+ 0:0))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)));
+
+ *logical++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x502E) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+
+ *logical++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1))))))) << (0 ?
+ 0:0))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)));
+ }
+ else
+ {
+ *logical++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x0594) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
+
+ *logical++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1))))))) << (0 ?
+ 0:0))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)));
+ }
+
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
+ "0x%x: FLUSH TILE STATUS 0x%x", logical - 1, logical[-1]);
+ }
+
+ if (flushICache)
+ {
+ *logical++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x022C) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
+
+ *logical++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1))))))) << (0 ?
+ 0:0))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 1:1) - (0 ?
+ 1:1) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 1:1) - (0 ?
+ 1:1) + 1))))))) << (0 ?
+ 1:1))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 1:1) - (0 ?
+ 1:1) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 2:2) - (0 ?
+ 2:2) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 2:2) - (0 ?
+ 2:2) + 1))))))) << (0 ?
+ 2:2))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 2:2) - (0 ?
+ 2:2) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 2:2) - (0 ? 2:2) + 1))))))) << (0 ? 2:2)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 3:3) - (0 ?
+ 3:3) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 3:3) - (0 ?
+ 3:3) + 1))))))) << (0 ?
+ 3:3))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 3:3) - (0 ?
+ 3:3) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 3:3) - (0 ? 3:3) + 1))))))) << (0 ? 3:3)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 4:4) - (0 ?
+ 4:4) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 4:4) - (0 ?
+ 4:4) + 1))))))) << (0 ?
+ 4:4))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 4:4) - (0 ?
+ 4:4) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 4:4) - (0 ? 4:4) + 1))))))) << (0 ? 4:4)));
+
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
+ "0x%x: FLUSH Icache 0x%x", logical - 1, logical[-1]);
+
+ }
+
+ if (flushTXDescCache)
+ {
+ *logical++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x5311) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
+
+ *logical++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:28) - (0 ?
+ 31:28) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:28) - (0 ?
+ 31:28) + 1))))))) << (0 ?
+ 31:28))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ?
+ 31:28) - (0 ?
+ 31:28) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:28) - (0 ? 31:28) + 1))))))) << (0 ? 31:28)));
+
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
+ "0x%x: FLUSH Icache 0x%x", logical - 1, logical[-1]);
+
+ }
+
+ if (flushTFB)
+ {
+ *logical++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x7003) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
+
+ *logical++
+ = 0x12345678;
+
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
+ "0x%x: FLUSH TFB cache 0x%x", logical - 1, logical[-1]);
+
+ }
+
+ if (blt)
+ {
+ /* Semaphore from FE to BLT. */
+ *logical++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x502E) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+
+ *logical++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1))))))) << (0 ?
+ 0:0))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)));
+
+ *logical++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E02) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+
+ *logical++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1))))))) << (0 ?
+ 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1))))))) << (0 ?
+ 12:8))) | (((gctUINT32) (0x10 & ((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
+
+ /* Stall from FE to BLT. */
+ *logical++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x09 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)));
+
+ *logical++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1))))))) << (0 ?
+ 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1))))))) << (0 ?
+ 12:8))) | (((gctUINT32) (0x10 & ((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
+
+ *logical++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x502E) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+
+ *logical++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1))))))) << (0 ?
+ 0:0))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)));
+ }
+ else
+ {
+ /* Semaphore. */
+ *logical++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E02) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+
+ *logical++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1))))))) << (0 ?
+ 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1))))))) << (0 ?
+ 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
+
+ /* Stall. */
+ *logical++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x09 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)));
+
+ *logical++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1))))))) << (0 ?
+ 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1))))))) << (0 ?
+ 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
+ }
+ }
+
+ if (Bytes != gcvNULL)
+ {
+ /* bytes required. */
+ *Bytes = reserveBytes;
+ }
+ }
+
+ /* Success. */
+ gcmkFOOTER_ARG("*Bytes=%lu", gcmOPT_VALUE(Bytes));
+ return gcvSTATUS_OK;
+
+OnError:
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+gceSTATUS
+gckHARDWARE_SetFastClear(
+ IN gckHARDWARE Hardware,
+ IN gctINT Enable,
+ IN gctINT Compression
+ )
+{
+#if gcdENABLE_3D
+ gctUINT32 debug;
+ gceSTATUS status;
+ gceCOMPRESSION_OPTION compression = (Compression == -1) ? gcvCOMPRESSION_OPTION_DEFAULT : (gceCOMPRESSION_OPTION)Compression;
+
+ gcmkHEADER_ARG("Hardware=0x%x Enable=%d Compression=%d",
+ Hardware, Enable, Compression);
+
+ /* Only process if fast clear is available. */
+ if (gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_FAST_CLEAR))
+ {
+ if (Enable == -1)
+ {
+ /* Determine automatic value for fast clear. */
+ Enable = ((Hardware->identity.chipModel != gcv500)
+ || (Hardware->identity.chipRevision >= 3)
+ ) ? 1 : 0;
+ }
+
+ if (compression == gcvCOMPRESSION_OPTION_DEFAULT)
+ {
+ /* Determine automatic value for compression. */
+ if (Enable)
+ {
+ if (gcvSTATUS_FALSE == gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_ZCOMPRESSION))
+ {
+ compression &= ~gcvCOMPRESSION_OPTION_DEPTH;
+ }
+ }
+ else
+ {
+ compression = gcvCOMPRESSION_OPTION_NONE;
+ }
+ }
+
+ /* Read AQMemoryDebug register. */
+ gcmkONERROR(
+ gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00414, &debug));
+
+ /* Set fast clear bypass. */
+ debug = ((((gctUINT32) (debug)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 20:20) - (0 ?
+ 20:20) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 20:20) - (0 ?
+ 20:20) + 1))))))) << (0 ?
+ 20:20))) | (((gctUINT32) ((gctUINT32) (Enable == 0) & ((gctUINT32) ((((1 ?
+ 20:20) - (0 ?
+ 20:20) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 20:20) - (0 ? 20:20) + 1))))))) << (0 ? 20:20)));
+
+ if (gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_BUG_FIXES7) ||
+ (Hardware->identity.chipModel >= gcv4000))
+ {
+ /* Set compression bypass. */
+ debug = ((((gctUINT32) (debug)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 21:21) - (0 ?
+ 21:21) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 21:21) - (0 ?
+ 21:21) + 1))))))) << (0 ?
+ 21:21))) | (((gctUINT32) ((gctUINT32) ((gcvCOMPRESSION_OPTION_NONE == compression) ?
+ 1 : 0) & ((gctUINT32) ((((1 ?
+ 21:21) - (0 ?
+ 21:21) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 21:21) - (0 ? 21:21) + 1))))))) << (0 ? 21:21)));
+ }
+
+ /* Write back AQMemoryDebug register. */
+ gcmkONERROR(
+ gckOS_WriteRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x00414,
+ debug));
+
+ /* Store fast clear and comprersison flags. */
+ Hardware->options.allowFastClear = Enable;
+ Hardware->options.allowCompression = compression;
+
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
+ "FastClear=%d Compression=%d", Enable, Compression);
+ }
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+#else
+ return gcvSTATUS_OK;
+#endif
+}
+
+typedef enum
+{
+ gcvPOWER_FLAG_INITIALIZE = 1 << 0,
+ gcvPOWER_FLAG_STALL = 1 << 1,
+ gcvPOWER_FLAG_STOP = 1 << 2,
+ gcvPOWER_FLAG_START = 1 << 3,
+ gcvPOWER_FLAG_RELEASE = 1 << 4,
+ gcvPOWER_FLAG_DELAY = 1 << 5,
+ gcvPOWER_FLAG_SAVE = 1 << 6,
+ gcvPOWER_FLAG_ACQUIRE = 1 << 7,
+ gcvPOWER_FLAG_POWER_OFF = 1 << 8,
+ gcvPOWER_FLAG_CLOCK_OFF = 1 << 9,
+ gcvPOWER_FLAG_CLOCK_ON = 1 << 10,
+}
+gcePOWER_FLAGS;
+
+#if gcmIS_DEBUG(gcdDEBUG_TRACE)
+static gctCONST_STRING
+_PowerEnum(gceCHIPPOWERSTATE State)
+{
+ const gctCONST_STRING states[] =
+ {
+ gcmSTRING(gcvPOWER_ON),
+ gcmSTRING(gcvPOWER_OFF),
+ gcmSTRING(gcvPOWER_IDLE),
+ gcmSTRING(gcvPOWER_SUSPEND),
+ gcmSTRING(gcvPOWER_IDLE_BROADCAST),
+ gcmSTRING(gcvPOWER_SUSPEND_BROADCAST),
+ gcmSTRING(gcvPOWER_OFF_BROADCAST),
+ gcmSTRING(gcvPOWER_OFF_TIMEOUT),
+ gcmSTRING(gcvPOWER_ON_AUTO)
+ };
+
+ if ((State >= gcvPOWER_ON) && (State <= gcvPOWER_ON_AUTO))
+ {
+ return states[State - gcvPOWER_ON];
+ }
+
+ return "unknown";
+}
+#endif
+
+/*******************************************************************************
+**
+** gckHARDWARE_SetPowerManagementState
+**
+** Set GPU to a specified power state.
+**
+** INPUT:
+**
+** gckHARDWARE Harwdare
+** Pointer to an gckHARDWARE object.
+**
+** gceCHIPPOWERSTATE State
+** Power State.
+**
+*/
+gceSTATUS
+gckHARDWARE_SetPowerManagementState(
+ IN gckHARDWARE Hardware,
+ IN gceCHIPPOWERSTATE State
+ )
+{
+ gceSTATUS status;
+ gckCOMMAND command = gcvNULL;
+ gckOS os;
+ gctUINT flag, clock;
+ gctBOOL acquired = gcvFALSE;
+ gctBOOL mutexAcquired = gcvFALSE;
+ gctBOOL broadcast = gcvFALSE;
+#if gcdPOWEROFF_TIMEOUT
+ gctBOOL timeout = gcvFALSE;
+ gctBOOL isAfter = gcvFALSE;
+ gctUINT32 currentTime;
+#endif
+ gctUINT32 process, thread;
+ gctBOOL commandStarted = gcvFALSE;
+
+#if gcdENABLE_PROFILING
+ gctUINT64 time, freq, mutexTime, onTime, stallTime, stopTime, delayTime,
+ initTime, offTime, startTime, totalTime;
+#endif
+ gctBOOL global = gcvFALSE;
+ gctBOOL globalAcquired = gcvFALSE;
+
+ /* State transition flags. */
+ static const gctUINT flags[4][4] =
+ {
+ /* gcvPOWER_ON */
+ { /* ON */ 0,
+ /* OFF */ gcvPOWER_FLAG_ACQUIRE |
+ gcvPOWER_FLAG_STALL |
+ gcvPOWER_FLAG_STOP |
+ gcvPOWER_FLAG_POWER_OFF |
+ gcvPOWER_FLAG_CLOCK_OFF,
+ /* IDLE */ gcvPOWER_FLAG_ACQUIRE |
+ gcvPOWER_FLAG_STALL,
+ /* SUSPEND */ gcvPOWER_FLAG_ACQUIRE |
+ gcvPOWER_FLAG_STALL |
+ gcvPOWER_FLAG_STOP |
+ gcvPOWER_FLAG_CLOCK_OFF,
+ },
+
+ /* gcvPOWER_OFF */
+ { /* ON */ gcvPOWER_FLAG_INITIALIZE |
+ gcvPOWER_FLAG_START |
+ gcvPOWER_FLAG_RELEASE |
+ gcvPOWER_FLAG_DELAY,
+ /* OFF */ 0,
+ /* IDLE */ gcvPOWER_FLAG_INITIALIZE |
+ gcvPOWER_FLAG_START |
+ gcvPOWER_FLAG_DELAY,
+ /* SUSPEND */ gcvPOWER_FLAG_INITIALIZE |
+ gcvPOWER_FLAG_CLOCK_OFF,
+ },
+
+ /* gcvPOWER_IDLE */
+ { /* ON */ gcvPOWER_FLAG_RELEASE,
+ /* OFF */ gcvPOWER_FLAG_STOP |
+ gcvPOWER_FLAG_POWER_OFF |
+ gcvPOWER_FLAG_CLOCK_OFF,
+ /* IDLE */ 0,
+ /* SUSPEND */ gcvPOWER_FLAG_STOP |
+ gcvPOWER_FLAG_CLOCK_OFF,
+ },
+
+ /* gcvPOWER_SUSPEND */
+ { /* ON */ gcvPOWER_FLAG_START |
+ gcvPOWER_FLAG_RELEASE |
+ gcvPOWER_FLAG_DELAY |
+ gcvPOWER_FLAG_CLOCK_ON,
+ /* OFF */ gcvPOWER_FLAG_SAVE |
+ gcvPOWER_FLAG_POWER_OFF |
+ gcvPOWER_FLAG_CLOCK_OFF,
+ /* IDLE */ gcvPOWER_FLAG_START |
+ gcvPOWER_FLAG_DELAY |
+ gcvPOWER_FLAG_CLOCK_ON,
+ /* SUSPEND */ 0,
+ },
+ };
+
+ /* Clocks. */
+ static const gctUINT clocks[4] =
+ {
+ /* gcvPOWER_ON */
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1))))))) << (0 ?
+ 0:0))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) |
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 1:1) - (0 ?
+ 1:1) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 1:1) - (0 ?
+ 1:1) + 1))))))) << (0 ?
+ 1:1))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ?
+ 1:1) - (0 ?
+ 1:1) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1))) |
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 8:2) - (0 ?
+ 8:2) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 8:2) - (0 ?
+ 8:2) + 1))))))) << (0 ?
+ 8:2))) | (((gctUINT32) ((gctUINT32) (64) & ((gctUINT32) ((((1 ?
+ 8:2) - (0 ?
+ 8:2) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 8:2) - (0 ? 8:2) + 1))))))) << (0 ? 8:2))) |
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 9:9) - (0 ?
+ 9:9) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 9:9) - (0 ?
+ 9:9) + 1))))))) << (0 ?
+ 9:9))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 9:9) - (0 ?
+ 9:9) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 9:9) - (0 ? 9:9) + 1))))))) << (0 ? 9:9))),
+
+ /* gcvPOWER_OFF */
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1))))))) << (0 ?
+ 0:0))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) |
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 1:1) - (0 ?
+ 1:1) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 1:1) - (0 ?
+ 1:1) + 1))))))) << (0 ?
+ 1:1))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 1:1) - (0 ?
+ 1:1) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1))) |
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 8:2) - (0 ?
+ 8:2) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 8:2) - (0 ?
+ 8:2) + 1))))))) << (0 ?
+ 8:2))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 8:2) - (0 ?
+ 8:2) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 8:2) - (0 ? 8:2) + 1))))))) << (0 ? 8:2))) |
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 9:9) - (0 ?
+ 9:9) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 9:9) - (0 ?
+ 9:9) + 1))))))) << (0 ?
+ 9:9))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 9:9) - (0 ?
+ 9:9) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 9:9) - (0 ? 9:9) + 1))))))) << (0 ? 9:9))),
+
+ /* gcvPOWER_IDLE */
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1))))))) << (0 ?
+ 0:0))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) |
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 1:1) - (0 ?
+ 1:1) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 1:1) - (0 ?
+ 1:1) + 1))))))) << (0 ?
+ 1:1))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ?
+ 1:1) - (0 ?
+ 1:1) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1))) |
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 8:2) - (0 ?
+ 8:2) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 8:2) - (0 ?
+ 8:2) + 1))))))) << (0 ?
+ 8:2))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 8:2) - (0 ?
+ 8:2) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 8:2) - (0 ? 8:2) + 1))))))) << (0 ? 8:2))) |
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 9:9) - (0 ?
+ 9:9) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 9:9) - (0 ?
+ 9:9) + 1))))))) << (0 ?
+ 9:9))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 9:9) - (0 ?
+ 9:9) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 9:9) - (0 ? 9:9) + 1))))))) << (0 ? 9:9))),
+
+ /* gcvPOWER_SUSPEND */
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1))))))) << (0 ?
+ 0:0))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) |
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 1:1) - (0 ?
+ 1:1) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 1:1) - (0 ?
+ 1:1) + 1))))))) << (0 ?
+ 1:1))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 1:1) - (0 ?
+ 1:1) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1))) |
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 8:2) - (0 ?
+ 8:2) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 8:2) - (0 ?
+ 8:2) + 1))))))) << (0 ?
+ 8:2))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 8:2) - (0 ?
+ 8:2) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 8:2) - (0 ? 8:2) + 1))))))) << (0 ? 8:2))) |
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 9:9) - (0 ?
+ 9:9) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 9:9) - (0 ?
+ 9:9) + 1))))))) << (0 ?
+ 9:9))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 9:9) - (0 ?
+ 9:9) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 9:9) - (0 ? 9:9) + 1))))))) << (0 ? 9:9))),
+ };
+
+ gcmkHEADER_ARG("Hardware=0x%x State=%d", Hardware, State);
+#if gcmIS_DEBUG(gcdDEBUG_TRACE)
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
+ "Switching to power state %d(%s)",
+ State, _PowerEnum(State));
+#endif
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
+
+ /* Get the gckOS object pointer. */
+ os = Hardware->os;
+ gcmkVERIFY_OBJECT(os, gcvOBJ_OS);
+
+ /* Get the gckCOMMAND object pointer. */
+ gcmkVERIFY_OBJECT(Hardware->kernel, gcvOBJ_KERNEL);
+ command = Hardware->kernel->command;
+ gcmkVERIFY_OBJECT(command, gcvOBJ_COMMAND);
+
+ /* Start profiler. */
+ gcmkPROFILE_INIT(freq, time);
+
+
+ /* Convert the broadcast power state. */
+ switch (State)
+ {
+ case gcvPOWER_IDLE_BROADCAST:
+ /* Convert to IDLE and note we are inside broadcast. */
+ State = gcvPOWER_IDLE;
+ broadcast = gcvTRUE;
+ break;
+
+ case gcvPOWER_SUSPEND_BROADCAST:
+ /* Convert to SUSPEND and note we are inside broadcast. */
+ State = gcvPOWER_SUSPEND;
+ broadcast = gcvTRUE;
+ break;
+
+ case gcvPOWER_OFF_BROADCAST:
+ /* Convert to OFF and note we are inside broadcast. */
+ State = gcvPOWER_OFF;
+ broadcast = gcvTRUE;
+ break;
+
+ case gcvPOWER_ON_AUTO:
+ /* Convert to ON and note we are inside recovery. */
+ State = gcvPOWER_ON;
+ break;
+
+ case gcvPOWER_ON:
+ case gcvPOWER_IDLE:
+ case gcvPOWER_SUSPEND:
+ case gcvPOWER_OFF:
+ /* Mark as global power management. */
+ global = gcvTRUE;
+ break;
+
+#if gcdPOWEROFF_TIMEOUT
+ case gcvPOWER_OFF_TIMEOUT:
+ /* Convert to OFF and note we are inside broadcast. */
+ State = gcvPOWER_OFF;
+ broadcast = gcvTRUE;
+ /* Check time out */
+ timeout = gcvTRUE;
+ break;
+#endif
+
+ default:
+ break;
+ }
+
+ if (Hardware->options.powerManagement == gcvFALSE
+ && State != gcvPOWER_ON
+ )
+ {
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+ }
+
+ /* Get current process and thread IDs. */
+ gcmkONERROR(gckOS_GetProcessID(&process));
+ gcmkONERROR(gckOS_GetThreadID(&thread));
+
+ if (broadcast)
+ {
+ /* Try to acquire the power mutex. */
+ status = gckOS_AcquireMutex(os, Hardware->powerMutex, 0);
+
+ if (gcmIS_SUCCESS(status))
+ {
+ mutexAcquired = gcvTRUE;
+ }
+ else if (status == gcvSTATUS_TIMEOUT)
+ {
+ /* Check if we already own this mutex. */
+ if ((Hardware->powerProcess == process)
+ && (Hardware->powerThread == thread)
+ )
+ {
+ /* Bail out on recursive power management. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+ }
+ else if (State != gcvPOWER_ON)
+ {
+ /* Called from IST,
+ ** so waiting here will cause deadlock,
+ ** if lock holder call gckCOMMAND_Stall() */
+ status = gcvSTATUS_OK;
+ goto OnError;
+ }
+ }
+ }
+
+ if (!mutexAcquired)
+ {
+ /* Acquire the power mutex. */
+ gcmkONERROR(gckOS_AcquireMutex(os, Hardware->powerMutex, gcvINFINITE));
+ mutexAcquired = gcvTRUE;
+ }
+
+ /* Get time until mtuex acquired. */
+ gcmkPROFILE_QUERY(time, mutexTime);
+
+ Hardware->powerProcess = process;
+ Hardware->powerThread = thread;
+ mutexAcquired = gcvTRUE;
+
+ /* Grab control flags and clock. */
+ flag = flags[Hardware->chipPowerState][State];
+ clock = clocks[State];
+
+#if gcdENABLE_FSCALE_VAL_ADJUST
+ if (State == gcvPOWER_ON)
+ {
+ clock = ((((gctUINT32) (clock)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 8:2) - (0 ?
+ 8:2) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 8:2) - (0 ?
+ 8:2) + 1))))))) << (0 ?
+ 8:2))) | (((gctUINT32) ((gctUINT32) (Hardware->powerOnFscaleVal) & ((gctUINT32) ((((1 ?
+ 8:2) - (0 ?
+ 8:2) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 8:2) - (0 ? 8:2) + 1))))))) << (0 ? 8:2)));
+ }
+#endif
+
+ if (State == gcvPOWER_SUSPEND && Hardware->chipPowerState == gcvPOWER_OFF && broadcast)
+ {
+#if gcdPOWER_SUSPEND_WHEN_IDLE
+ /* Do nothing */
+
+ /* Release the power mutex. */
+ gcmkONERROR(gckOS_ReleaseMutex(os, Hardware->powerMutex));
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+#else
+ /* Clock should be on when switch power from off to suspend */
+ clock = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1))))))) << (0 ?
+ 0:0))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) |
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 1:1) - (0 ?
+ 1:1) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 1:1) - (0 ?
+ 1:1) + 1))))))) << (0 ?
+ 1:1))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ?
+ 1:1) - (0 ?
+ 1:1) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1))) |
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 8:2) - (0 ?
+ 8:2) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 8:2) - (0 ?
+ 8:2) + 1))))))) << (0 ?
+ 8:2))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 8:2) - (0 ?
+ 8:2) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 8:2) - (0 ? 8:2) + 1))))))) << (0 ? 8:2))) |
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 9:9) - (0 ?
+ 9:9) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 9:9) - (0 ?
+ 9:9) + 1))))))) << (0 ?
+ 9:9))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 9:9) - (0 ?
+ 9:9) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 9:9) - (0 ? 9:9) + 1))))))) << (0 ? 9:9))) ;
+#endif
+ }
+
+#if gcdPOWEROFF_TIMEOUT
+ if (timeout)
+ {
+ gcmkONERROR(gckOS_GetTicks(&currentTime));
+
+ gcmkONERROR(
+ gckOS_TicksAfter(Hardware->powerOffTime, currentTime, &isAfter));
+
+ /* powerOffTime is pushed forward, give up.*/
+ if (isAfter
+ /* Expect a transition start from IDLE or SUSPEND. */
+ || (Hardware->chipPowerState == gcvPOWER_ON)
+ || (Hardware->chipPowerState == gcvPOWER_OFF)
+ )
+ {
+ /* Release the power mutex. */
+ gcmkONERROR(gckOS_ReleaseMutex(os, Hardware->powerMutex));
+
+ /* No need to do anything. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+ }
+
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
+ "Power Off GPU[%d] at %u [supposed to be at %u]",
+ Hardware->core, currentTime, Hardware->powerOffTime);
+ }
+#endif
+
+ if (flag == 0)
+ {
+ /* Release the power mutex. */
+ gcmkONERROR(gckOS_ReleaseMutex(os, Hardware->powerMutex));
+
+ /* No need to do anything. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+ }
+
+ /* If this is an internal power management, we have to check if we can grab
+ ** the global power semaphore. If we cannot, we have to wait until the
+ ** external world changes power management. */
+ if (!global)
+ {
+ /* Try to acquire the global semaphore. */
+ status = gckOS_TryAcquireSemaphore(os, Hardware->globalSemaphore);
+ if (status == gcvSTATUS_TIMEOUT)
+ {
+ if (State == gcvPOWER_IDLE || State == gcvPOWER_SUSPEND)
+ {
+ /* Called from thread routine which should NEVER sleep.*/
+ status = gcvSTATUS_OK;
+ goto OnError;
+ }
+
+ /* Release the power mutex. */
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
+ "Releasing the power mutex.");
+ gcmkONERROR(gckOS_ReleaseMutex(os, Hardware->powerMutex));
+ mutexAcquired = gcvFALSE;
+
+ /* Wait for the semaphore. */
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
+ "Waiting for global semaphore.");
+ gcmkONERROR(gckOS_AcquireSemaphore(os, Hardware->globalSemaphore));
+ globalAcquired = gcvTRUE;
+
+ /* Acquire the power mutex. */
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
+ "Reacquiring the power mutex.");
+ gcmkONERROR(gckOS_AcquireMutex(os,
+ Hardware->powerMutex,
+ gcvINFINITE));
+ mutexAcquired = gcvTRUE;
+
+ /* chipPowerState may be changed by external world during the time
+ ** we give up powerMutex, so updating flag now is necessary. */
+ flag = flags[Hardware->chipPowerState][State];
+
+ if (flag == 0)
+ {
+ gcmkONERROR(gckOS_ReleaseSemaphore(os, Hardware->globalSemaphore));
+ globalAcquired = gcvFALSE;
+
+ gcmkONERROR(gckOS_ReleaseMutex(os, Hardware->powerMutex));
+ mutexAcquired = gcvFALSE;
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+ }
+ }
+ else
+ {
+ /* Error. */
+ gcmkONERROR(status);
+ }
+
+ /* Release the global semaphore again. */
+ gcmkONERROR(gckOS_ReleaseSemaphore(os, Hardware->globalSemaphore));
+ globalAcquired = gcvFALSE;
+
+ /* Try to acquire the semaphore to make sure commit is not in progress
+ ** Otherwise, we just abort. */
+ if (flag & gcvPOWER_FLAG_ACQUIRE)
+ {
+ /* ON -> Other, boardcast. */
+ /* Try to acquire the power management semaphore. */
+ status = gckOS_TryAcquireSemaphore(os, command->powerSemaphore);
+
+ if (status == gcvSTATUS_OK)
+ {
+ acquired = gcvTRUE;
+
+ /* avoid acquiring again. */
+ flag &= ~gcvPOWER_FLAG_ACQUIRE;
+ }
+ else
+ {
+ /* Not ready to swith. */
+ status = gcvSTATUS_CHIP_NOT_READY;
+ goto OnError;
+ }
+ }
+ }
+ else
+ {
+ if (State == gcvPOWER_OFF || State == gcvPOWER_SUSPEND || State == gcvPOWER_IDLE)
+ {
+ /* Acquire the global semaphore if it has not been acquired. */
+ status = gckOS_TryAcquireSemaphore(os, Hardware->globalSemaphore);
+ if (status == gcvSTATUS_OK)
+ {
+ globalAcquired = gcvTRUE;
+ }
+ else if (status != gcvSTATUS_TIMEOUT)
+ {
+ /* Other errors. */
+ gcmkONERROR(status);
+ }
+ /* Ignore gcvSTATUS_TIMEOUT and leave globalAcquired as gcvFALSE.
+ ** gcvSTATUS_TIMEOUT means global semaphore has already
+ ** been acquired before this operation, so even if we fail,
+ ** we should not release it in our error handling. It should be
+ ** released by the next successful global gcvPOWER_ON. */
+ }
+
+ /* Global power management can't be aborted, so sync with
+ ** proceeding last commit. */
+ if (flag & gcvPOWER_FLAG_ACQUIRE)
+ {
+ /* Acquire the power management semaphore. */
+ gcmkONERROR(gckOS_AcquireSemaphore(os, command->powerSemaphore));
+ acquired = gcvTRUE;
+
+ /* avoid acquiring again. */
+ flag &= ~gcvPOWER_FLAG_ACQUIRE;
+ }
+ }
+
+ if (flag & (gcvPOWER_FLAG_INITIALIZE | gcvPOWER_FLAG_CLOCK_ON))
+ {
+ /* Turn on the power. */
+ gcmkONERROR(gckOS_SetGPUPower(os, Hardware->core, gcvTRUE, gcvTRUE));
+
+ /* Mark clock and power as enabled. */
+ Hardware->clockState = gcvTRUE;
+ Hardware->powerState = gcvTRUE;
+
+ for (;;)
+ {
+ /* Check if GPU is present and awake. */
+ status = _IsGPUPresent(Hardware);
+
+ /* Check if the GPU is not responding. */
+ if (status == gcvSTATUS_GPU_NOT_RESPONDING)
+ {
+ /* Turn off the power and clock. */
+ gcmkONERROR(gckOS_SetGPUPower(os, Hardware->core, gcvFALSE, gcvFALSE));
+
+ Hardware->clockState = gcvFALSE;
+ Hardware->powerState = gcvFALSE;
+
+ /* Wait a little. */
+ gckOS_Delay(os, 1);
+
+ /* Turn on the power and clock. */
+ gcmkONERROR(gckOS_SetGPUPower(os, Hardware->core, gcvTRUE, gcvTRUE));
+
+ Hardware->clockState = gcvTRUE;
+ Hardware->powerState = gcvTRUE;
+
+ /* We need to initialize the hardware and start the command
+ * processor. */
+ flag |= gcvPOWER_FLAG_INITIALIZE | gcvPOWER_FLAG_START;
+ }
+ else
+ {
+ /* Test for error. */
+ gcmkONERROR(status);
+
+ /* Break out of loop. */
+ break;
+ }
+ }
+ }
+
+ /* Get time until powered on. */
+ gcmkPROFILE_QUERY(time, onTime);
+
+ if (flag & gcvPOWER_FLAG_STALL)
+ {
+ gctBOOL idle;
+ gctINT32 atomValue;
+
+ /* For global operation, all pending commits have already been
+ ** blocked by globalSemaphore or powerSemaphore.*/
+ if (!global)
+ {
+ /* Check commit atom. */
+ gcmkONERROR(gckOS_AtomGet(os, command->atomCommit, &atomValue));
+
+ if (atomValue > 0)
+ {
+ /* Commits are pending - abort power management. */
+ status = broadcast ? gcvSTATUS_CHIP_NOT_READY
+ : gcvSTATUS_MORE_DATA;
+ goto OnError;
+ }
+ }
+
+ if (broadcast)
+ {
+ /* Check for idle. */
+ gcmkONERROR(gckHARDWARE_QueryIdle(Hardware, &idle));
+
+ if (!idle)
+ {
+ status = gcvSTATUS_CHIP_NOT_READY;
+ goto OnError;
+ }
+ }
+
+ else
+ {
+ /* Wait to finish all commands. */
+ gcmkONERROR(gckCOMMAND_Stall(command, gcvTRUE));
+
+ for (;;)
+ {
+ gcmkONERROR(gckHARDWARE_QueryIdle(Hardware, &idle));
+
+ if (idle)
+ {
+ break;
+ }
+
+ gcmkVERIFY_OK(gckOS_Delay(Hardware->os, 1));
+ }
+ }
+ }
+
+ /* Get time until stalled. */
+ gcmkPROFILE_QUERY(time, stallTime);
+
+ if (flag & gcvPOWER_FLAG_ACQUIRE)
+ {
+ /* Acquire the power management semaphore. */
+ gcmkONERROR(gckOS_AcquireSemaphore(os, command->powerSemaphore));
+ acquired = gcvTRUE;
+ }
+
+ if (flag & gcvPOWER_FLAG_STOP)
+ {
+ /* Stop the command parser. */
+ gcmkONERROR(gckCOMMAND_Stop(command));
+ }
+
+ /* Flush Cache before Power Off. */
+ if (flag & gcvPOWER_FLAG_POWER_OFF)
+ {
+ if (Hardware->clockState == gcvFALSE)
+ {
+ /* Turn off the GPU power. */
+ gcmkONERROR(
+ gckOS_SetGPUPower(os,
+ Hardware->core,
+ gcvTRUE,
+ gcvTRUE));
+
+ Hardware->clockState = gcvTRUE;
+#if gcdDVFS
+ if (gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_DYNAMIC_FREQUENCY_SCALING) != gcvTRUE)
+#endif
+ {
+ /* Write the clock control register. */
+ gcmkONERROR(gckOS_WriteRegisterEx(os,
+ Hardware->core,
+ 0x00000,
+ clocks[0]));
+
+ /* Done loading the frequency scaler. */
+ gcmkONERROR(gckOS_WriteRegisterEx(os,
+ Hardware->core,
+ 0x00000,
+ ((((gctUINT32) (clocks[0])) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 9:9) - (0 ?
+ 9:9) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 9:9) - (0 ?
+ 9:9) + 1))))))) << (0 ?
+ 9:9))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ?
+ 9:9) - (0 ?
+ 9:9) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 9:9) - (0 ? 9:9) + 1))))))) << (0 ? 9:9)))));
+ }
+ }
+
+ if(_IsHardwareMatch(Hardware, gcv400, 0x4645))
+ {
+ gcmkONERROR(gckCOMMAND_Start(command));
+
+ gcmkONERROR(_FlushCache(Hardware, command));
+
+ gckOS_Delay(gcvNULL, 1);
+
+ /* Stop the command parser. */
+ gcmkONERROR(gckCOMMAND_Stop(command));
+ }
+ else
+ {
+ gckHARDWARE_ExecuteFunctions(Hardware, gcvHARDWARE_FUNCTION_FLUSH);
+ gckOS_Delay(gcvNULL, 1);
+ }
+
+ flag |= gcvPOWER_FLAG_CLOCK_OFF;
+ }
+
+ /* Get time until stopped. */
+ gcmkPROFILE_QUERY(time, stopTime);
+
+ /* Only process this when hardware is enabled. */
+ if (Hardware->clockState && Hardware->powerState
+#if gcdDVFS
+ /* Don't touch clock control if dynamic frequency scaling is available. */
+ && gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_DYNAMIC_FREQUENCY_SCALING) != gcvTRUE
+#endif
+ )
+ {
+ if (flag & (gcvPOWER_FLAG_POWER_OFF | gcvPOWER_FLAG_CLOCK_OFF))
+ {
+ if (Hardware->identity.chipModel == gcv4000
+ && ((Hardware->identity.chipRevision == 0x5208) || (Hardware->identity.chipRevision == 0x5222)))
+ {
+ clock &= ~2U;
+ }
+ }
+
+ /* Write the clock control register. */
+ gcmkONERROR(gckOS_WriteRegisterEx(os,
+ Hardware->core,
+ 0x00000,
+ clock));
+
+ /* Done loading the frequency scaler. */
+ gcmkONERROR(gckOS_WriteRegisterEx(os,
+ Hardware->core,
+ 0x00000,
+ ((((gctUINT32) (clock)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 9:9) - (0 ?
+ 9:9) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 9:9) - (0 ?
+ 9:9) + 1))))))) << (0 ?
+ 9:9))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ?
+ 9:9) - (0 ?
+ 9:9) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 9:9) - (0 ? 9:9) + 1))))))) << (0 ? 9:9)))));
+ }
+
+ if (flag & gcvPOWER_FLAG_DELAY)
+ {
+ /* Wait for the specified amount of time to settle coming back from
+ ** power-off or suspend state. */
+ gcmkONERROR(gckOS_Delay(os, gcdPOWER_CONTROL_DELAY));
+ }
+
+ /* Get time until delayed. */
+ gcmkPROFILE_QUERY(time, delayTime);
+
+ if (flag & gcvPOWER_FLAG_INITIALIZE)
+ {
+ /* Initialize hardware. */
+ gcmkONERROR(gckHARDWARE_InitializeHardware(Hardware));
+
+ gcmkONERROR(gckHARDWARE_SetFastClear(Hardware,
+ Hardware->options.allowFastClear,
+ Hardware->options.allowCompression));
+
+ /* Force the command queue to reload the next context. */
+ command->currContext = gcvNULL;
+
+ /* Trigger a possible dummy draw. */
+ command->dummyDraw = gcvTRUE;
+ }
+
+ /* Get time until initialized. */
+ gcmkPROFILE_QUERY(time, initTime);
+
+ if (flag & (gcvPOWER_FLAG_POWER_OFF | gcvPOWER_FLAG_CLOCK_OFF))
+ {
+ /* Turn off the GPU power. */
+ gcmkONERROR(
+ gckOS_SetGPUPower(os,
+ Hardware->core,
+ (flag & gcvPOWER_FLAG_CLOCK_OFF) ? gcvFALSE
+ : gcvTRUE,
+ (flag & gcvPOWER_FLAG_POWER_OFF) ? gcvFALSE
+ : gcvTRUE));
+
+ /* Save current hardware power and clock states. */
+ Hardware->clockState = (flag & gcvPOWER_FLAG_CLOCK_OFF) ? gcvFALSE
+ : gcvTRUE;
+ Hardware->powerState = (flag & gcvPOWER_FLAG_POWER_OFF) ? gcvFALSE
+ : gcvTRUE;
+ }
+
+ /* Get time until off. */
+ gcmkPROFILE_QUERY(time, offTime);
+
+ if (flag & gcvPOWER_FLAG_START)
+ {
+ /* Start the command processor. */
+ gcmkONERROR(gckCOMMAND_Start(command));
+ commandStarted = gcvTRUE;
+ }
+
+ /* Get time until started. */
+ gcmkPROFILE_QUERY(time, startTime);
+
+ if (flag & gcvPOWER_FLAG_RELEASE)
+ {
+ /* Release the power management semaphore. */
+ gcmkONERROR(gckOS_ReleaseSemaphore(os, command->powerSemaphore));
+ acquired = gcvFALSE;
+
+ if (global)
+ {
+ /* Verify global semaphore has been acquired already before
+ ** we release it.
+ ** If it was acquired, gckOS_TryAcquireSemaphore will return
+ ** gcvSTATUS_TIMEOUT and we release it. Otherwise, global
+ ** semaphore will be acquried now, but it still is released
+ ** immediately. */
+ status = gckOS_TryAcquireSemaphore(os, Hardware->globalSemaphore);
+ if (status != gcvSTATUS_TIMEOUT)
+ {
+ gcmkONERROR(status);
+ }
+
+ /* Release the global semaphore. */
+ gcmkONERROR(gckOS_ReleaseSemaphore(os, Hardware->globalSemaphore));
+ globalAcquired = gcvFALSE;
+ }
+ }
+
+ gckSTATETIMER_Accumulate(&Hardware->powerStateTimer, Hardware->chipPowerState);
+
+ /* Save the new power state. */
+ Hardware->chipPowerState = State;
+
+#if gcdDVFS
+ if (State == gcvPOWER_ON && Hardware->kernel->dvfs)
+ {
+ gckDVFS_Start(Hardware->kernel->dvfs);
+ }
+#endif
+
+#if gcdPOWEROFF_TIMEOUT
+ /* Reset power off time */
+ gcmkONERROR(gckOS_GetTicks(&currentTime));
+
+ Hardware->powerOffTime = currentTime + Hardware->powerOffTimeout;
+
+ if (State == gcvPOWER_IDLE || State == gcvPOWER_SUSPEND)
+ {
+ /* Start a timer to power off GPU when GPU enters IDLE or SUSPEND. */
+ gcmkVERIFY_OK(gckOS_StartTimer(os,
+ Hardware->powerOffTimer,
+ Hardware->powerOffTimeout));
+ }
+ else
+ {
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE, "Cancel powerOfftimer");
+
+ /* Cancel running timer when GPU enters ON or OFF. */
+ gcmkVERIFY_OK(gckOS_StopTimer(os, Hardware->powerOffTimer));
+ }
+#endif
+
+ /* Release the power mutex. */
+ gcmkONERROR(gckOS_ReleaseMutex(os, Hardware->powerMutex));
+
+ /* Get total time. */
+ gcmkPROFILE_QUERY(time, totalTime);
+#if gcdENABLE_PROFILING
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
+ "PROF(%llu): mutex:%llu on:%llu stall:%llu stop:%llu",
+ freq, mutexTime, onTime, stallTime, stopTime);
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
+ " delay:%llu init:%llu off:%llu start:%llu total:%llu",
+ delayTime, initTime, offTime, startTime, totalTime);
+#endif
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ if (commandStarted)
+ {
+ gcmkVERIFY_OK(gckCOMMAND_Stop(command));
+ }
+
+ if (acquired)
+ {
+ /* Release semaphore. */
+ gcmkVERIFY_OK(gckOS_ReleaseSemaphore(Hardware->os,
+ command->powerSemaphore));
+ }
+
+ if (globalAcquired)
+ {
+ gcmkVERIFY_OK(gckOS_ReleaseSemaphore(Hardware->os,
+ Hardware->globalSemaphore));
+ }
+
+ if (mutexAcquired)
+ {
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(Hardware->os, Hardware->powerMutex));
+ }
+
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+/*******************************************************************************
+**
+** gckHARDWARE_QueryPowerManagementState
+**
+** Get GPU power state.
+**
+** INPUT:
+**
+** gckHARDWARE Harwdare
+** Pointer to an gckHARDWARE object.
+**
+** gceCHIPPOWERSTATE* State
+** Power State.
+**
+*/
+gceSTATUS
+gckHARDWARE_QueryPowerManagementState(
+ IN gckHARDWARE Hardware,
+ OUT gceCHIPPOWERSTATE* State
+ )
+{
+ gcmkHEADER_ARG("Hardware=0x%x", Hardware);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
+ gcmkVERIFY_ARGUMENT(State != gcvNULL);
+
+ /* Return the statue. */
+ *State = Hardware->chipPowerState;
+
+ /* Success. */
+ gcmkFOOTER_ARG("*State=%d", *State);
+ return gcvSTATUS_OK;
+}
+
+/*******************************************************************************
+**
+** gckHARDWARE_SetPowerManagement
+**
+** Configure GPU power management function.
+** Only used in driver initialization stage.
+**
+** INPUT:
+**
+** gckHARDWARE Harwdare
+** Pointer to an gckHARDWARE object.
+**
+** gctBOOL PowerManagement
+** Power Mangement State.
+**
+*/
+gceSTATUS
+gckHARDWARE_SetPowerManagement(
+ IN gckHARDWARE Hardware,
+ IN gctBOOL PowerManagement
+ )
+{
+ gcmkHEADER_ARG("Hardware=0x%x", Hardware);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
+
+ if(_IsHardwareMatch(Hardware, gcv7000, 0x6008))
+ {
+ PowerManagement = gcvFALSE;
+ }
+
+ gcmkVERIFY_OK(
+ gckOS_AcquireMutex(Hardware->os, Hardware->powerMutex, gcvINFINITE));
+
+ Hardware->options.powerManagement = PowerManagement;
+
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(Hardware->os, Hardware->powerMutex));
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+}
+
+/*******************************************************************************
+**
+** gckHARDWARE_SetGpuProfiler
+**
+** Configure GPU profiler function.
+** Only used in driver initialization stage.
+**
+** INPUT:
+**
+** gckHARDWARE Harwdare
+** Pointer to an gckHARDWARE object.
+**
+** gctBOOL GpuProfiler
+** GOU Profiler State.
+**
+*/
+gceSTATUS
+gckHARDWARE_SetGpuProfiler(
+ IN gckHARDWARE Hardware,
+ IN gctBOOL GpuProfiler
+ )
+{
+ gcmkHEADER_ARG("Hardware=0x%x", Hardware);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
+
+ if (GpuProfiler == gcvTRUE)
+ {
+ gctUINT32 data = 0;
+
+ /* Need to disable clock gating when doing profiling. */
+ gcmkVERIFY_OK(
+ gckOS_ReadRegisterEx(Hardware->os,
+ Hardware->core,
+ Hardware->powerBaseAddress +
+ 0x00100,
+ &data));
+
+ data = ((((gctUINT32) (data)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1))))))) << (0 ?
+ 0:0))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)));
+
+
+ gcmkVERIFY_OK(
+ gckOS_WriteRegisterEx(Hardware->os,
+ Hardware->core,
+ Hardware->powerBaseAddress
+ + 0x00100,
+ data));
+ }
+
+ Hardware->options.gpuProfiler= GpuProfiler;
+
+ if (GpuProfiler == gcvTRUE)
+ {
+ Hardware->waitCount = 200 * 100;
+ }
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+}
+
+#if gcdENABLE_FSCALE_VAL_ADJUST
+gceSTATUS
+gckHARDWARE_SetFscaleValue(
+ IN gckHARDWARE Hardware,
+ IN gctUINT32 FscaleValue
+ )
+{
+ gceSTATUS status;
+ gctUINT32 clock;
+ gctBOOL acquired = gcvFALSE;
+
+ gcmkHEADER_ARG("Hardware=0x%x FscaleValue=%d", Hardware, FscaleValue);
+
+ gcmkVERIFY_ARGUMENT(FscaleValue > 0 && FscaleValue <= 64);
+
+ gcmkONERROR(
+ gckOS_AcquireMutex(Hardware->os, Hardware->powerMutex, gcvINFINITE));
+ acquired = gcvTRUE;
+
+ Hardware->powerOnFscaleVal = FscaleValue;
+
+ if (Hardware->chipPowerState == gcvPOWER_ON)
+ {
+ gctUINT32 data;
+
+ gcmkONERROR(
+ gckOS_ReadRegisterEx(Hardware->os,
+ Hardware->core,
+ Hardware->powerBaseAddress
+ + 0x00104,
+ &data));
+
+ /* Disable all clock gating. */
+ gcmkONERROR(
+ gckOS_WriteRegisterEx(Hardware->os,
+ Hardware->core,
+ Hardware->powerBaseAddress
+ + 0x00104,
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1))))))) << (0 ?
+ 0:0))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 1:1) - (0 ?
+ 1:1) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 1:1) - (0 ?
+ 1:1) + 1))))))) << (0 ?
+ 1:1))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 1:1) - (0 ?
+ 1:1) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 2:2) - (0 ?
+ 2:2) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 2:2) - (0 ?
+ 2:2) + 1))))))) << (0 ?
+ 2:2))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 2:2) - (0 ?
+ 2:2) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 2:2) - (0 ? 2:2) + 1))))))) << (0 ? 2:2)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 3:3) - (0 ?
+ 3:3) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 3:3) - (0 ?
+ 3:3) + 1))))))) << (0 ?
+ 3:3))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 3:3) - (0 ?
+ 3:3) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 3:3) - (0 ? 3:3) + 1))))))) << (0 ? 3:3)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 4:4) - (0 ?
+ 4:4) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 4:4) - (0 ?
+ 4:4) + 1))))))) << (0 ?
+ 4:4))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 4:4) - (0 ?
+ 4:4) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 4:4) - (0 ? 4:4) + 1))))))) << (0 ? 4:4)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 5:5) - (0 ?
+ 5:5) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 5:5) - (0 ?
+ 5:5) + 1))))))) << (0 ?
+ 5:5))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 5:5) - (0 ?
+ 5:5) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 5:5) - (0 ? 5:5) + 1))))))) << (0 ? 5:5)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 6:6) - (0 ?
+ 6:6) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 6:6) - (0 ?
+ 6:6) + 1))))))) << (0 ?
+ 6:6))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 6:6) - (0 ?
+ 6:6) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 6:6) - (0 ? 6:6) + 1))))))) << (0 ? 6:6)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 7:7) - (0 ?
+ 7:7) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 7:7) - (0 ?
+ 7:7) + 1))))))) << (0 ?
+ 7:7))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 7:7) - (0 ?
+ 7:7) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 7:7) - (0 ? 7:7) + 1))))))) << (0 ? 7:7)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 8:8) - (0 ?
+ 8:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 8:8) - (0 ?
+ 8:8) + 1))))))) << (0 ?
+ 8:8))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 8:8) - (0 ?
+ 8:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 8:8) - (0 ? 8:8) + 1))))))) << (0 ? 8:8)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 9:9) - (0 ?
+ 9:9) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 9:9) - (0 ?
+ 9:9) + 1))))))) << (0 ?
+ 9:9))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 9:9) - (0 ?
+ 9:9) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 9:9) - (0 ? 9:9) + 1))))))) << (0 ? 9:9)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 11:11) - (0 ?
+ 11:11) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 11:11) - (0 ?
+ 11:11) + 1))))))) << (0 ?
+ 11:11))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 11:11) - (0 ?
+ 11:11) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 11:11) - (0 ? 11:11) + 1))))))) << (0 ? 11:11)))));
+
+ clock = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1))))))) << (0 ?
+ 0:0))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 1:1) - (0 ?
+ 1:1) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 1:1) - (0 ?
+ 1:1) + 1))))))) << (0 ?
+ 1:1))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ?
+ 1:1) - (0 ?
+ 1:1) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 8:2) - (0 ?
+ 8:2) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 8:2) - (0 ?
+ 8:2) + 1))))))) << (0 ?
+ 8:2))) | (((gctUINT32) ((gctUINT32) (FscaleValue) & ((gctUINT32) ((((1 ?
+ 8:2) - (0 ?
+ 8:2) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 8:2) - (0 ? 8:2) + 1))))))) << (0 ? 8:2)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 9:9) - (0 ?
+ 9:9) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 9:9) - (0 ?
+ 9:9) + 1))))))) << (0 ?
+ 9:9))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 9:9) - (0 ?
+ 9:9) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 9:9) - (0 ? 9:9) + 1))))))) << (0 ? 9:9)));
+
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x00000,
+ clock));
+
+ /* Done loading the frequency scaler. */
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x00000,
+ ((((gctUINT32) (clock)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 9:9) - (0 ?
+ 9:9) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 9:9) - (0 ?
+ 9:9) + 1))))))) << (0 ?
+ 9:9))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ?
+ 9:9) - (0 ?
+ 9:9) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 9:9) - (0 ? 9:9) + 1))))))) << (0 ? 9:9)))));
+
+ /* Restore all clock gating. */
+ gcmkONERROR(
+ gckOS_WriteRegisterEx(Hardware->os,
+ Hardware->core,
+ Hardware->powerBaseAddress
+ + 0x00104,
+ data));
+ }
+
+ gcmkVERIFY(gckOS_ReleaseMutex(Hardware->os, Hardware->powerMutex));
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ if (acquired)
+ {
+ gcmkVERIFY(gckOS_ReleaseMutex(Hardware->os, Hardware->powerMutex));
+ }
+
+ gcmkFOOTER();
+ return status;
+}
+
+gceSTATUS
+gckHARDWARE_GetFscaleValue(
+ IN gckHARDWARE Hardware,
+ IN gctUINT * FscaleValue,
+ IN gctUINT * MinFscaleValue,
+ IN gctUINT * MaxFscaleValue
+ )
+{
+ *FscaleValue = Hardware->powerOnFscaleVal;
+ *MinFscaleValue = Hardware->minFscaleValue;
+ *MaxFscaleValue = 64;
+
+ return gcvSTATUS_OK;
+}
+
+gceSTATUS
+gckHARDWARE_SetMinFscaleValue(
+ IN gckHARDWARE Hardware,
+ IN gctUINT MinFscaleValue
+ )
+{
+ if (MinFscaleValue >= 1 && MinFscaleValue <= 64)
+ {
+ Hardware->minFscaleValue = MinFscaleValue;
+ }
+
+ return gcvSTATUS_OK;
+}
+#endif
+
+#if gcdPOWEROFF_TIMEOUT
+gceSTATUS
+gckHARDWARE_SetPowerOffTimeout(
+ IN gckHARDWARE Hardware,
+ IN gctUINT32 Timeout
+)
+{
+ gcmkHEADER_ARG("Hardware=0x%x Timeout=%d", Hardware, Timeout);
+
+ Hardware->powerOffTimeout = Timeout;
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+}
+
+
+gceSTATUS
+gckHARDWARE_QueryPowerOffTimeout(
+ IN gckHARDWARE Hardware,
+ OUT gctUINT32* Timeout
+)
+{
+ gcmkHEADER_ARG("Hardware=0x%x", Hardware);
+
+ *Timeout = Hardware->powerOffTimeout;
+
+ gcmkFOOTER_ARG("*Timeout=%d", *Timeout);
+ return gcvSTATUS_OK;
+}
+#endif
+
+gceSTATUS
+gckHARDWARE_QueryIdle(
+ IN gckHARDWARE Hardware,
+ OUT gctBOOL_PTR IsIdle
+ )
+{
+ gceSTATUS status;
+ gctUINT32 idle;
+#if !gcdSECURITY
+ gctUINT32 address;
+ gctUINT32 dmaLow;
+ gctUINT32 opCode;
+#endif
+ gctBOOL isIdle = gcvFALSE;
+
+#if gcdINTERRUPT_STATISTIC
+ gckEVENT eventObj = Hardware->kernel->eventObj;
+ gctINT32 pendingInterrupt;
+#endif
+
+ gcmkHEADER_ARG("Hardware=0x%x", Hardware);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
+ gcmkVERIFY_ARGUMENT(IsIdle != gcvNULL);
+
+ do
+ {
+ /* We are idle when the power is not ON. */
+ if (Hardware->chipPowerState != gcvPOWER_ON)
+ {
+ isIdle = gcvTRUE;
+ break;
+ }
+
+ /* Read idle register. */
+ gcmkONERROR(
+ gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00004, &idle));
+
+ /* Pipe must be idle. */
+ if ((idle | (1 << 14)) != 0x7ffffffe)
+ {
+ /* Something is busy. */
+ break;
+ }
+
+#if gcdSECURITY
+ isIdle = gcvTRUE;
+ break;
+#else
+ /* Read the current FE address. */
+ gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x00664,
+ &address));
+
+ gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x00664,
+ &address));
+
+ /* Test if address is inside the last WAIT/LINK sequence. */
+ if ((address < Hardware->lastWaitLink) ||
+ (address >= (gctUINT64)Hardware->lastWaitLink + 16))
+ {
+ /* FE is not in WAIT/LINK yet. */
+ break;
+ }
+
+ gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x00668,
+ &dmaLow));
+
+ gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x00668,
+ &dmaLow));
+
+ opCode = dmaLow >> 27;
+
+ /* Test if current command buffer is WAIT/LINK . */
+ if (opCode != 0x7 && opCode != 0x8)
+ {
+ /* FE is not in WAIT/LINK yet. */
+ break;
+ }
+#endif
+
+#if gcdINTERRUPT_STATISTIC
+ gcmkONERROR(gckOS_AtomGet(
+ Hardware->os,
+ eventObj->interruptCount,
+ &pendingInterrupt
+ ));
+
+ if (pendingInterrupt)
+ {
+ /* Pending interrupts, not idle. */
+ break;
+ }
+
+ if (Hardware->hasAsyncFe)
+ {
+ gckEVENT asyncEvent = Hardware->kernel->asyncEvent;
+
+ gcmkONERROR(gckOS_AtomGet(
+ Hardware->os,
+ asyncEvent->interruptCount,
+ &pendingInterrupt
+ ));
+
+ if (pendingInterrupt)
+ {
+ /* Pending async FE interrupts, not idle. */
+ break;
+ }
+ }
+#endif
+
+ /* Is really idle. */
+ isIdle = gcvTRUE;
+ }
+ while (gcvFALSE);
+
+ *IsIdle = isIdle;
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+/*******************************************************************************
+** Handy macros that will help in reading those debug registers.
+*/
+#define gcmkREAD_DEBUG_REGISTER_PART1(control, block, index, data) \
+ gcmkONERROR(\
+ gckOS_WriteRegisterEx(Hardware->os, \
+ Hardware->core, \
+ GC_DEBUG_CONTROL##control##_Address, \
+ gcmSETFIELD(0, \
+ GC_DEBUG_CONTROL##control, \
+ block, \
+ index))); \
+ gcmkONERROR(\
+ gckOS_ReadRegisterEx(Hardware->os, \
+ Hardware->core, \
+ GC_DEBUG_SIGNALS_##block##_Address, \
+ &profiler_part1->data))
+
+#define gcmkREAD_DEBUG_REGISTER_PART2(control, block, index, data) \
+ gcmkONERROR(\
+ gckOS_WriteRegisterEx(Hardware->os, \
+ Hardware->core, \
+ GC_DEBUG_CONTROL##control##_Address, \
+ gcmSETFIELD(0, \
+ GC_DEBUG_CONTROL##control, \
+ block, \
+ index))); \
+ gcmkONERROR(\
+ gckOS_ReadRegisterEx(Hardware->os, \
+ Hardware->core, \
+ GC_DEBUG_SIGNALS_##block##_Address, \
+ &profiler_part2->data))
+
+#define gcmkREAD_DEBUG_REGISTER_N(control, block, index, data) \
+ gcmkONERROR(\
+ gckOS_WriteRegisterEx(Hardware->os, \
+ Hardware->core, \
+ GC_DEBUG_CONTROL##control##_Address, \
+ gcmSETFIELD(0, \
+ GC_DEBUG_CONTROL##control, \
+ block, \
+ index))); \
+ gcmkONERROR(\
+ gckOS_ReadRegisterEx(Hardware->os, \
+ Hardware->core, \
+ GC_DEBUG_SIGNALS_##block##_Address, \
+ &data))
+
+#define gcmkRESET_DEBUG_REGISTER(control, block, value) \
+ gcmkONERROR(\
+ gckOS_WriteRegisterEx(Hardware->os, \
+ Hardware->core, \
+ GC_DEBUG_CONTROL##control##_Address, \
+ gcmSETFIELD(0, \
+ GC_DEBUG_CONTROL##control, \
+ block, \
+ value))); \
+ gcmkONERROR(\
+ gckOS_WriteRegisterEx(Hardware->os, \
+ Hardware->core, \
+ GC_DEBUG_CONTROL##control##_Address, \
+ gcmSETFIELD(0, \
+ GC_DEBUG_CONTROL##control, \
+ block, \
+ 0)))
+
+static gctUINT32
+CalcDelta(
+ IN gctUINT32 new,
+ IN gctUINT32 old
+ )
+{
+ if (new >= old)
+ {
+ return new - old;
+ }
+ else
+ {
+ return (gctUINT32)((gctUINT64)new + 0x100000000ll - old);
+ }
+}
+
+
+#if USE_SW_RESET
+#define gcmkRESET_PROFILE_DATA_PART1(counterName) \
+ temp = profiler_part1->counterName; \
+ profiler_part1->counterName = CalcDelta(temp, Context->preProfiler_part1.counterName); \
+ Context->preProfiler_part1.counterName = temp
+#endif
+
+#define gcmkUPDATE_PROFILE_DATA_PART1(data) \
+ profilerHistroy_part1->data += profiler_part1->data
+#define gcmkUPDATE_PROFILE_DATA_PART2(data) \
+ profilerHistroy_part2->data += profiler_part2->data
+
+gceSTATUS
+gckHARDWARE_QueryContextProfile(
+ IN gckHARDWARE Hardware,
+ IN gctBOOL Reset,
+ IN gckCONTEXT Context,
+ OUT gcsPROFILER_COUNTERS_PART1 * Counters_part1,
+ OUT gcsPROFILER_COUNTERS_PART2 * Counters_part2
+)
+{
+ gceSTATUS status;
+ gckCOMMAND command = Hardware->kernel->command;
+ gcsPROFILER_COUNTERS_PART1 * profiler_part1 = Counters_part1;
+ gcsPROFILER_COUNTERS_PART2 * profiler_part2 = Counters_part2;
+
+ gcmkHEADER_ARG("Hardware=0x%x Counters_part1=0x%x, Counters_part2=0x%x", Hardware, Counters_part1, Counters_part2);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
+
+ if (!Context)
+ {
+ gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
+ }
+ /* Acquire the context sequnence mutex. */
+ gcmkONERROR(gckOS_AcquireMutex(
+ command->os, command->mutexContextSeq, gcvINFINITE
+ ));
+
+ /* Read the counters. */
+ if (Counters_part1)
+ {
+ gcmkVERIFY_OK(gckOS_MemCopy(
+ profiler_part1, &Context->histroyProfiler_part1, gcmSIZEOF(gcsPROFILER_COUNTERS_PART1)
+ ));
+ }
+ else if (Counters_part2)
+ {
+ gcmkVERIFY_OK(gckOS_MemCopy(
+ profiler_part2, &Context->histroyProfiler_part2, gcmSIZEOF(gcsPROFILER_COUNTERS_PART2)
+ ));
+ }
+
+ /* Reset counters. */
+ if (Reset)
+ {
+ if (Counters_part1)
+ {
+ gcmkVERIFY_OK(gckOS_ZeroMemory(
+ &Context->histroyProfiler_part1, gcmSIZEOF(gcsPROFILER_COUNTERS_PART1)
+ ));
+ }
+ else if (Counters_part2)
+ {
+ gcmkVERIFY_OK(gckOS_ZeroMemory(
+ &Context->histroyProfiler_part2, gcmSIZEOF(gcsPROFILER_COUNTERS_PART2)
+ ));
+ }
+ }
+
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(
+ command->os, command->mutexContextSeq
+ ));
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+gceSTATUS
+gckHARDWARE_UpdateContextProfile(
+ IN gckHARDWARE Hardware,
+ IN gckCONTEXT Context
+)
+{
+ gceSTATUS status;
+ gcsPROFILER_COUNTERS_PART1 * profiler_part1 = &Context->latestProfiler_part1;
+ gcsPROFILER_COUNTERS_PART1 * profilerHistroy_part1 = &Context->histroyProfiler_part1;
+ gcsPROFILER_COUNTERS_PART2 * profiler_part2 = &Context->latestProfiler_part2;
+ gcsPROFILER_COUNTERS_PART2 * profilerHistroy_part2 = &Context->histroyProfiler_part2;
+ gceCHIPMODEL chipModel;
+ gctUINT32 chipRevision;
+ gctUINT32 i;
+ gctUINT32 resetValue = 0xF;
+ gctBOOL hasNewCounters = gcvFALSE;
+ gctUINT32 clock;
+ gctUINT32 colorKilled = 0, colorDrawn = 0, depthKilled = 0, depthDrawn = 0;
+ gctUINT32 totalRead, totalWrite;
+ gctUINT32 mc_axi_max_min_latency;
+ gctUINT32 temp;
+ gckCOMMAND command = Hardware->kernel->command;
+ gctBOOL mutexAcquired = gcvFALSE;
+
+ gcmkHEADER_ARG("Hardware=0x%x Context=0x%x", Hardware, Context);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
+ gcmkVERIFY_OBJECT(Context, gcvOBJ_CONTEXT);
+
+ /* Acquire the context sequnence mutex. */
+ gcmkONERROR(gckOS_AcquireMutex(
+ command->os, command->mutexContextSeq, gcvINFINITE
+ ));
+ mutexAcquired = gcvTRUE;
+
+ chipModel = Hardware->identity.chipModel;
+ chipRevision = Hardware->identity.chipRevision;
+ if ((chipModel == gcv5000 && chipRevision == 0x5434) || (chipModel == gcv3000 && chipRevision == 0x5435))
+ {
+ resetValue = 0xFF;
+ hasNewCounters = gcvTRUE;
+ }
+
+ if (chipModel == gcv2100 || chipModel == gcv2000 || chipModel == gcv880)
+ {
+ gcmkONERROR(
+ gckOS_ReadRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x00438,
+ &profiler_part2->hi_total_cycle_count));
+
+ gcmkONERROR(
+ gckOS_ReadRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x00078,
+ &profiler_part2->hi_total_idle_cycle_count));
+ }
+ else
+ {
+ gcmkONERROR(
+ gckOS_ReadRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x00078,
+ &profiler_part2->hi_total_cycle_count));
+
+ gcmkONERROR(
+ gckOS_ReadRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x0007C,
+ &profiler_part2->hi_total_idle_cycle_count));
+ }
+ gcmkUPDATE_PROFILE_DATA_PART2(hi_total_cycle_count);
+ gcmkUPDATE_PROFILE_DATA_PART2(hi_total_idle_cycle_count);
+
+ /* Read clock control register. */
+ gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x00000,
+ &clock));
+
+ profiler_part2->hi_total_read_8B_count = 0;
+ profiler_part2->hi_total_write_8B_count = 0;
+ profiler_part1->pe0_pixel_count_drawn_by_color_pipe = 0;
+ profiler_part1->pe0_pixel_count_drawn_by_depth_pipe = 0;
+ profiler_part1->pe0_pixel_count_killed_by_color_pipe = 0;
+ profiler_part1->pe0_pixel_count_killed_by_depth_pipe = 0;
+ profiler_part1->pe1_pixel_count_drawn_by_color_pipe = 0;
+ profiler_part1->pe1_pixel_count_drawn_by_depth_pipe = 0;
+ profiler_part1->pe1_pixel_count_killed_by_color_pipe = 0;
+ profiler_part1->pe1_pixel_count_killed_by_depth_pipe = 0;
+
+ /* Walk through all avaiable pixel pipes. */
+ for (i = 0; i < Hardware->identity.pixelPipes; ++i)
+ {
+ /* Select proper pipe. */
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x00000,
+ ((((gctUINT32) (clock)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 23:20) - (0 ?
+ 23:20) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 23:20) - (0 ?
+ 23:20) + 1))))))) << (0 ?
+ 23:20))) | (((gctUINT32) ((gctUINT32) (i) & ((gctUINT32) ((((1 ?
+ 23:20) - (0 ?
+ 23:20) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 23:20) - (0 ? 23:20) + 1))))))) << (0 ? 23:20)))));
+
+ /* BW */
+ gcmkONERROR(
+ gckOS_ReadRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x00040,
+ &totalRead));
+ gcmkONERROR(
+ gckOS_ReadRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x00044,
+ &totalWrite));
+
+ profiler_part2->hi_total_read_8B_count += totalRead;
+ profiler_part2->hi_total_write_8B_count += totalWrite;
+
+ /* PE */
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 23:16) - (0 ?
+ 23:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 23:16) - (0 ?
+ 23:16) + 1))))))) << (0 ?
+ 23:16))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ?
+ 23:16) - (0 ?
+ 23:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16)))));gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00454, &colorKilled));
+
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 23:16) - (0 ?
+ 23:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 23:16) - (0 ?
+ 23:16) + 1))))))) << (0 ?
+ 23:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 23:16) - (0 ?
+ 23:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16)))));gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00454, &depthKilled));
+
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 23:16) - (0 ?
+ 23:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 23:16) - (0 ?
+ 23:16) + 1))))))) << (0 ?
+ 23:16))) | (((gctUINT32) ((gctUINT32) (2) & ((gctUINT32) ((((1 ?
+ 23:16) - (0 ?
+ 23:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16)))));gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00454, &colorDrawn));
+
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 23:16) - (0 ?
+ 23:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 23:16) - (0 ?
+ 23:16) + 1))))))) << (0 ?
+ 23:16))) | (((gctUINT32) ((gctUINT32) (3) & ((gctUINT32) ((((1 ?
+ 23:16) - (0 ?
+ 23:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16)))));gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00454, &depthDrawn));
+
+
+ if (i == 0)
+ {
+ profiler_part1->pe0_pixel_count_killed_by_color_pipe = colorKilled;
+ profiler_part1->pe0_pixel_count_killed_by_depth_pipe = depthKilled;
+ profiler_part1->pe0_pixel_count_drawn_by_color_pipe = colorDrawn;
+ profiler_part1->pe0_pixel_count_drawn_by_depth_pipe = depthDrawn;
+ }
+ else if (i == 1)
+ {
+ profiler_part1->pe1_pixel_count_killed_by_color_pipe = colorKilled;
+ profiler_part1->pe1_pixel_count_killed_by_depth_pipe = depthKilled;
+ profiler_part1->pe1_pixel_count_drawn_by_color_pipe = colorDrawn;
+ profiler_part1->pe1_pixel_count_drawn_by_depth_pipe = depthDrawn;
+ }
+ }
+
+ gcmkUPDATE_PROFILE_DATA_PART2(hi_total_read_8B_count);
+ gcmkUPDATE_PROFILE_DATA_PART2(hi_total_write_8B_count);
+#if USE_SW_RESET
+ gcmkRESET_PROFILE_DATA_PART1(pe0_pixel_count_killed_by_color_pipe);
+ gcmkRESET_PROFILE_DATA_PART1(pe0_pixel_count_killed_by_depth_pipe);
+ gcmkRESET_PROFILE_DATA_PART1(pe0_pixel_count_drawn_by_color_pipe);
+ gcmkRESET_PROFILE_DATA_PART1(pe0_pixel_count_drawn_by_depth_pipe);
+ gcmkRESET_PROFILE_DATA_PART1(pe1_pixel_count_killed_by_color_pipe);
+ gcmkRESET_PROFILE_DATA_PART1(pe1_pixel_count_killed_by_depth_pipe);
+ gcmkRESET_PROFILE_DATA_PART1(pe1_pixel_count_drawn_by_color_pipe);
+ gcmkRESET_PROFILE_DATA_PART1(pe1_pixel_count_drawn_by_depth_pipe);
+#endif
+ gcmkUPDATE_PROFILE_DATA_PART1(pe0_pixel_count_killed_by_color_pipe);
+ gcmkUPDATE_PROFILE_DATA_PART1(pe0_pixel_count_killed_by_depth_pipe);
+ gcmkUPDATE_PROFILE_DATA_PART1(pe0_pixel_count_drawn_by_color_pipe);
+ gcmkUPDATE_PROFILE_DATA_PART1(pe0_pixel_count_drawn_by_depth_pipe);
+ gcmkUPDATE_PROFILE_DATA_PART1(pe1_pixel_count_killed_by_color_pipe);
+ gcmkUPDATE_PROFILE_DATA_PART1(pe1_pixel_count_killed_by_depth_pipe);
+ gcmkUPDATE_PROFILE_DATA_PART1(pe1_pixel_count_drawn_by_color_pipe);
+ gcmkUPDATE_PROFILE_DATA_PART1(pe1_pixel_count_drawn_by_depth_pipe);
+
+ /* Reset clock control register. */
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x00000,
+ clock));
+
+ gcmkONERROR(
+ gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00438, 0));
+ gcmkONERROR(
+ gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00078, 0));
+
+#if !USE_SW_RESET
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 23:16) - (0 ?
+ 23:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 23:16) - (0 ?
+ 23:16) + 1))))))) << (0 ?
+ 23:16))) | (((gctUINT32) ((gctUINT32) (resetValue) & ((gctUINT32) ((((1 ?
+ 23:16) - (0 ?
+ 23:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) ));
+gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 23:16) - (0 ?
+ 23:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 23:16) - (0 ?
+ 23:16) + 1))))))) << (0 ?
+ 23:16))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ?
+ 23:16) - (0 ?
+ 23:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16)))
+));
+#endif
+
+ /* FE */
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1))))))) << (0 ?
+ 7:0))) | (((gctUINT32) ((gctUINT32) (10) & ((gctUINT32) ((((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00450, &profiler_part1->fe_draw_count));
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1))))))) << (0 ?
+ 7:0))) | (((gctUINT32) ((gctUINT32) (11) & ((gctUINT32) ((((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00450, &profiler_part1->fe_out_vertex_count));
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1))))))) << (0 ?
+ 7:0))) | (((gctUINT32) ((gctUINT32) (12) & ((gctUINT32) ((((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00450, &profiler_part1->fe_cache_miss_count));
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1))))))) << (0 ?
+ 7:0))) | (((gctUINT32) ((gctUINT32) (16) & ((gctUINT32) ((((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00450, &profiler_part1->fe_cache_lk_count));
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1))))))) << (0 ?
+ 7:0))) | (((gctUINT32) ((gctUINT32) (17) & ((gctUINT32) ((((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00450, &profiler_part1->fe_stall_count));
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1))))))) << (0 ?
+ 7:0))) | (((gctUINT32) ((gctUINT32) (18) & ((gctUINT32) ((((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00450, &profiler_part1->fe_process_count));
+
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1))))))) << (0 ?
+ 7:0))) | (((gctUINT32) ((gctUINT32) (resetValue) & ((gctUINT32) ((((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) ));
+gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1))))))) << (0 ?
+ 7:0))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0)))
+));
+
+ gcmkUPDATE_PROFILE_DATA_PART1(fe_draw_count);
+ gcmkUPDATE_PROFILE_DATA_PART1(fe_out_vertex_count);
+ gcmkUPDATE_PROFILE_DATA_PART1(fe_cache_miss_count);
+ gcmkUPDATE_PROFILE_DATA_PART1(fe_cache_lk_count);
+ gcmkUPDATE_PROFILE_DATA_PART1(fe_process_count);
+
+ /* SH */
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:24) - (0 ?
+ 31:24) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:24) - (0 ?
+ 31:24) + 1))))))) << (0 ?
+ 31:24))) | (((gctUINT32) ((gctUINT32) (7) & ((gctUINT32) ((((1 ?
+ 31:24) - (0 ?
+ 31:24) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0045C, &profiler_part1->ps_inst_counter));
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:24) - (0 ?
+ 31:24) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:24) - (0 ?
+ 31:24) + 1))))))) << (0 ?
+ 31:24))) | (((gctUINT32) ((gctUINT32) (8) & ((gctUINT32) ((((1 ?
+ 31:24) - (0 ?
+ 31:24) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0045C, &profiler_part1->ps_rendered_pixel_counter));
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:24) - (0 ?
+ 31:24) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:24) - (0 ?
+ 31:24) + 1))))))) << (0 ?
+ 31:24))) | (((gctUINT32) ((gctUINT32) (9) & ((gctUINT32) ((((1 ?
+ 31:24) - (0 ?
+ 31:24) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0045C, &profiler_part1->vs_inst_counter));
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:24) - (0 ?
+ 31:24) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:24) - (0 ?
+ 31:24) + 1))))))) << (0 ?
+ 31:24))) | (((gctUINT32) ((gctUINT32) (10) & ((gctUINT32) ((((1 ?
+ 31:24) - (0 ?
+ 31:24) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0045C, &profiler_part1->vs_rendered_vertice_counter));
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:24) - (0 ?
+ 31:24) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:24) - (0 ?
+ 31:24) + 1))))))) << (0 ?
+ 31:24))) | (((gctUINT32) ((gctUINT32) (11) & ((gctUINT32) ((((1 ?
+ 31:24) - (0 ?
+ 31:24) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0045C, &profiler_part1->vs_branch_inst_counter));
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:24) - (0 ?
+ 31:24) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:24) - (0 ?
+ 31:24) + 1))))))) << (0 ?
+ 31:24))) | (((gctUINT32) ((gctUINT32) (12) & ((gctUINT32) ((((1 ?
+ 31:24) - (0 ?
+ 31:24) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0045C, &profiler_part1->vs_texld_inst_counter));
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:24) - (0 ?
+ 31:24) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:24) - (0 ?
+ 31:24) + 1))))))) << (0 ?
+ 31:24))) | (((gctUINT32) ((gctUINT32) (13) & ((gctUINT32) ((((1 ?
+ 31:24) - (0 ?
+ 31:24) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0045C, &profiler_part1->ps_branch_inst_counter));
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:24) - (0 ?
+ 31:24) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:24) - (0 ?
+ 31:24) + 1))))))) << (0 ?
+ 31:24))) | (((gctUINT32) ((gctUINT32) (14) & ((gctUINT32) ((((1 ?
+ 31:24) - (0 ?
+ 31:24) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0045C, &profiler_part1->ps_texld_inst_counter));
+ if (hasNewCounters)
+ {
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:24) - (0 ?
+ 31:24) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:24) - (0 ?
+ 31:24) + 1))))))) << (0 ?
+ 31:24))) | (((gctUINT32) ((gctUINT32) (19) & ((gctUINT32) ((((1 ?
+ 31:24) - (0 ?
+ 31:24) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0045C, &profiler_part1->vs_non_idle_starve_count));
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:24) - (0 ?
+ 31:24) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:24) - (0 ?
+ 31:24) + 1))))))) << (0 ?
+ 31:24))) | (((gctUINT32) ((gctUINT32) (15) & ((gctUINT32) ((((1 ?
+ 31:24) - (0 ?
+ 31:24) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0045C, &profiler_part1->vs_starve_count));
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:24) - (0 ?
+ 31:24) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:24) - (0 ?
+ 31:24) + 1))))))) << (0 ?
+ 31:24))) | (((gctUINT32) ((gctUINT32) (16) & ((gctUINT32) ((((1 ?
+ 31:24) - (0 ?
+ 31:24) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0045C, &profiler_part1->vs_stall_count));
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:24) - (0 ?
+ 31:24) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:24) - (0 ?
+ 31:24) + 1))))))) << (0 ?
+ 31:24))) | (((gctUINT32) ((gctUINT32) (21) & ((gctUINT32) ((((1 ?
+ 31:24) - (0 ?
+ 31:24) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0045C, &profiler_part1->vs_process_count));
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:24) - (0 ?
+ 31:24) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:24) - (0 ?
+ 31:24) + 1))))))) << (0 ?
+ 31:24))) | (((gctUINT32) ((gctUINT32) (20) & ((gctUINT32) ((((1 ?
+ 31:24) - (0 ?
+ 31:24) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0045C, &profiler_part1->ps_non_idle_starve_count));
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:24) - (0 ?
+ 31:24) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:24) - (0 ?
+ 31:24) + 1))))))) << (0 ?
+ 31:24))) | (((gctUINT32) ((gctUINT32) (17) & ((gctUINT32) ((((1 ?
+ 31:24) - (0 ?
+ 31:24) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0045C, &profiler_part1->ps_starve_count));
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:24) - (0 ?
+ 31:24) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:24) - (0 ?
+ 31:24) + 1))))))) << (0 ?
+ 31:24))) | (((gctUINT32) ((gctUINT32) (18) & ((gctUINT32) ((((1 ?
+ 31:24) - (0 ?
+ 31:24) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0045C, &profiler_part1->ps_stall_count));
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:24) - (0 ?
+ 31:24) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:24) - (0 ?
+ 31:24) + 1))))))) << (0 ?
+ 31:24))) | (((gctUINT32) ((gctUINT32) (22) & ((gctUINT32) ((((1 ?
+ 31:24) - (0 ?
+ 31:24) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0045C, &profiler_part1->ps_process_count));
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:24) - (0 ?
+ 31:24) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:24) - (0 ?
+ 31:24) + 1))))))) << (0 ?
+ 31:24))) | (((gctUINT32) ((gctUINT32) (4) & ((gctUINT32) ((((1 ?
+ 31:24) - (0 ?
+ 31:24) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0045C, &profiler_part1->shader_cycle_count));
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:24) - (0 ?
+ 31:24) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:24) - (0 ?
+ 31:24) + 1))))))) << (0 ?
+ 31:24))) | (((gctUINT32) ((gctUINT32) (23) & ((gctUINT32) ((((1 ?
+ 31:24) - (0 ?
+ 31:24) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0045C, &profiler_part1->tx_non_idle_starve_count));
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:24) - (0 ?
+ 31:24) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:24) - (0 ?
+ 31:24) + 1))))))) << (0 ?
+ 31:24))) | (((gctUINT32) ((gctUINT32) (24) & ((gctUINT32) ((((1 ?
+ 31:24) - (0 ?
+ 31:24) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0045C, &profiler_part1->tx_starve_count));
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:24) - (0 ?
+ 31:24) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:24) - (0 ?
+ 31:24) + 1))))))) << (0 ?
+ 31:24))) | (((gctUINT32) ((gctUINT32) (25) & ((gctUINT32) ((((1 ?
+ 31:24) - (0 ?
+ 31:24) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0045C, &profiler_part1->tx_stall_count));
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:24) - (0 ?
+ 31:24) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:24) - (0 ?
+ 31:24) + 1))))))) << (0 ?
+ 31:24))) | (((gctUINT32) ((gctUINT32) (26) & ((gctUINT32) ((((1 ?
+ 31:24) - (0 ?
+ 31:24) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0045C, &profiler_part1->tx_process_count));
+ }
+#if USE_SW_RESET
+ gcmkRESET_PROFILE_DATA_PART1(ps_inst_counter);
+ gcmkRESET_PROFILE_DATA_PART1(ps_rendered_pixel_counter);
+ gcmkRESET_PROFILE_DATA_PART1(vs_inst_counter);
+ gcmkRESET_PROFILE_DATA_PART1(vs_rendered_vertice_counter);
+ gcmkRESET_PROFILE_DATA_PART1(vs_branch_inst_counter);
+ gcmkRESET_PROFILE_DATA_PART1(vs_texld_inst_counter);
+ gcmkRESET_PROFILE_DATA_PART1(ps_branch_inst_counter);
+ gcmkRESET_PROFILE_DATA_PART1(ps_texld_inst_counter);
+ if (hasNewCounters)
+ {
+ gcmkRESET_PROFILE_DATA_PART1(vs_non_idle_starve_count);
+ gcmkRESET_PROFILE_DATA_PART1(vs_starve_count);
+ gcmkRESET_PROFILE_DATA_PART1(vs_stall_count);
+ gcmkRESET_PROFILE_DATA_PART1(vs_process_count);
+ gcmkRESET_PROFILE_DATA_PART1(ps_non_idle_starve_count);
+ gcmkRESET_PROFILE_DATA_PART1(ps_starve_count);
+ gcmkRESET_PROFILE_DATA_PART1(ps_stall_count);
+ gcmkRESET_PROFILE_DATA_PART1(ps_process_count);
+ gcmkRESET_PROFILE_DATA_PART1(shader_cycle_count);
+ gcmkRESET_PROFILE_DATA_PART1(tx_non_idle_starve_count);
+ gcmkRESET_PROFILE_DATA_PART1(tx_starve_count);
+ gcmkRESET_PROFILE_DATA_PART1(tx_stall_count);
+ gcmkRESET_PROFILE_DATA_PART1(tx_process_count);
+ }
+#endif
+ gcmkUPDATE_PROFILE_DATA_PART1(ps_inst_counter);
+ gcmkUPDATE_PROFILE_DATA_PART1(ps_rendered_pixel_counter);
+ gcmkUPDATE_PROFILE_DATA_PART1(vs_inst_counter);
+ gcmkUPDATE_PROFILE_DATA_PART1(vs_rendered_vertice_counter);
+ gcmkUPDATE_PROFILE_DATA_PART1(vs_branch_inst_counter);
+ gcmkUPDATE_PROFILE_DATA_PART1(vs_texld_inst_counter);
+ gcmkUPDATE_PROFILE_DATA_PART1(ps_branch_inst_counter);
+ gcmkUPDATE_PROFILE_DATA_PART1(ps_texld_inst_counter);
+ if (hasNewCounters)
+ {
+ gcmkUPDATE_PROFILE_DATA_PART1(vs_non_idle_starve_count);
+ gcmkUPDATE_PROFILE_DATA_PART1(vs_starve_count);
+ gcmkUPDATE_PROFILE_DATA_PART1(vs_stall_count);
+ gcmkUPDATE_PROFILE_DATA_PART1(vs_process_count);
+ gcmkUPDATE_PROFILE_DATA_PART1(ps_non_idle_starve_count);
+ gcmkUPDATE_PROFILE_DATA_PART1(ps_starve_count);
+ gcmkUPDATE_PROFILE_DATA_PART1(ps_stall_count);
+ gcmkUPDATE_PROFILE_DATA_PART1(ps_process_count);
+ gcmkUPDATE_PROFILE_DATA_PART1(shader_cycle_count);
+ gcmkUPDATE_PROFILE_DATA_PART1(tx_non_idle_starve_count);
+ gcmkUPDATE_PROFILE_DATA_PART1(tx_starve_count);
+ gcmkUPDATE_PROFILE_DATA_PART1(tx_stall_count);
+ gcmkUPDATE_PROFILE_DATA_PART1(tx_process_count);
+ }
+#if !USE_SW_RESET
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:24) - (0 ?
+ 31:24) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:24) - (0 ?
+ 31:24) + 1))))))) << (0 ?
+ 31:24))) | (((gctUINT32) ((gctUINT32) (resetValue) & ((gctUINT32) ((((1 ?
+ 31:24) - (0 ?
+ 31:24) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) ));
+gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:24) - (0 ?
+ 31:24) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:24) - (0 ?
+ 31:24) + 1))))))) << (0 ?
+ 31:24))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ?
+ 31:24) - (0 ?
+ 31:24) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24)))
+));
+#endif
+
+ /* PA */
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1))))))) << (0 ?
+ 7:0))) | (((gctUINT32) ((gctUINT32) (3) & ((gctUINT32) ((((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00460, &profiler_part1->pa_input_vtx_counter));
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1))))))) << (0 ?
+ 7:0))) | (((gctUINT32) ((gctUINT32) (4) & ((gctUINT32) ((((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00460, &profiler_part1->pa_input_prim_counter));
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1))))))) << (0 ?
+ 7:0))) | (((gctUINT32) ((gctUINT32) (5) & ((gctUINT32) ((((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00460, &profiler_part1->pa_output_prim_counter));
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1))))))) << (0 ?
+ 7:0))) | (((gctUINT32) ((gctUINT32) (6) & ((gctUINT32) ((((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00460, &profiler_part1->pa_depth_clipped_counter));
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1))))))) << (0 ?
+ 7:0))) | (((gctUINT32) ((gctUINT32) (7) & ((gctUINT32) ((((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00460, &profiler_part1->pa_trivial_rejected_counter));
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1))))))) << (0 ?
+ 7:0))) | (((gctUINT32) ((gctUINT32) (8) & ((gctUINT32) ((((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00460, &profiler_part1->pa_culled_prim_counter));
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1))))))) << (0 ?
+ 7:0))) | (((gctUINT32) ((gctUINT32) (9) & ((gctUINT32) ((((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00460, &profiler_part1->pa_droped_prim_counter));
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1))))))) << (0 ?
+ 7:0))) | (((gctUINT32) ((gctUINT32) (10) & ((gctUINT32) ((((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00460, &profiler_part1->pa_frustum_clipped_prim_counter));
+ if (hasNewCounters)
+ {
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1))))))) << (0 ?
+ 7:0))) | (((gctUINT32) ((gctUINT32) (12) & ((gctUINT32) ((((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00460, &profiler_part1->pa_non_idle_starve_count));
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1))))))) << (0 ?
+ 7:0))) | (((gctUINT32) ((gctUINT32) (13) & ((gctUINT32) ((((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00460, &profiler_part1->pa_starve_count));
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1))))))) << (0 ?
+ 7:0))) | (((gctUINT32) ((gctUINT32) (14) & ((gctUINT32) ((((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00460, &profiler_part1->pa_stall_count));
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1))))))) << (0 ?
+ 7:0))) | (((gctUINT32) ((gctUINT32) (15) & ((gctUINT32) ((((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00460, &profiler_part1->pa_process_count));
+ }
+#if USE_SW_RESET
+ gcmkRESET_PROFILE_DATA_PART1(pa_input_vtx_counter);
+ gcmkRESET_PROFILE_DATA_PART1(pa_input_prim_counter);
+ gcmkRESET_PROFILE_DATA_PART1(pa_output_prim_counter);
+ gcmkRESET_PROFILE_DATA_PART1(pa_depth_clipped_counter);
+ gcmkRESET_PROFILE_DATA_PART1(pa_trivial_rejected_counter);
+ gcmkRESET_PROFILE_DATA_PART1(pa_culled_prim_counter);
+ gcmkRESET_PROFILE_DATA_PART1(pa_droped_prim_counter);
+ gcmkRESET_PROFILE_DATA_PART1(pa_frustum_clipped_prim_counter);
+ if (hasNewCounters)
+ {
+ gcmkRESET_PROFILE_DATA_PART1(pa_non_idle_starve_count);
+ gcmkRESET_PROFILE_DATA_PART1(pa_starve_count);
+ gcmkRESET_PROFILE_DATA_PART1(pa_stall_count);
+ gcmkRESET_PROFILE_DATA_PART1(pa_process_count);
+ }
+#endif
+ gcmkUPDATE_PROFILE_DATA_PART1(pa_input_vtx_counter);
+ gcmkUPDATE_PROFILE_DATA_PART1(pa_input_prim_counter);
+ gcmkUPDATE_PROFILE_DATA_PART1(pa_output_prim_counter);
+ gcmkUPDATE_PROFILE_DATA_PART1(pa_depth_clipped_counter);
+ gcmkUPDATE_PROFILE_DATA_PART1(pa_trivial_rejected_counter);
+ gcmkUPDATE_PROFILE_DATA_PART1(pa_culled_prim_counter);
+ gcmkUPDATE_PROFILE_DATA_PART1(pa_droped_prim_counter);
+ gcmkUPDATE_PROFILE_DATA_PART1(pa_frustum_clipped_prim_counter);
+ if (hasNewCounters)
+ {
+ gcmkUPDATE_PROFILE_DATA_PART1(pa_non_idle_starve_count);
+ gcmkUPDATE_PROFILE_DATA_PART1(pa_starve_count);
+ gcmkUPDATE_PROFILE_DATA_PART1(pa_stall_count);
+ gcmkUPDATE_PROFILE_DATA_PART1(pa_process_count);
+ }
+#if !USE_SW_RESET
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1))))))) << (0 ?
+ 7:0))) | (((gctUINT32) ((gctUINT32) (resetValue) & ((gctUINT32) ((((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) ));
+gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1))))))) << (0 ?
+ 7:0))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0)))
+));
+#endif
+
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:8) - (0 ?
+ 15:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:8) - (0 ?
+ 15:8) + 1))))))) << (0 ?
+ 15:8))) | (((gctUINT32) ((gctUINT32) (15) & ((gctUINT32) ((((1 ?
+ 15:8) - (0 ?
+ 15:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00464, &profiler_part1->se_clipped_triangle_count));
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:8) - (0 ?
+ 15:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:8) - (0 ?
+ 15:8) + 1))))))) << (0 ?
+ 15:8))) | (((gctUINT32) ((gctUINT32) (16) & ((gctUINT32) ((((1 ?
+ 15:8) - (0 ?
+ 15:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00464, &profiler_part1->se_clipped_line_count));
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:8) - (0 ?
+ 15:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:8) - (0 ?
+ 15:8) + 1))))))) << (0 ?
+ 15:8))) | (((gctUINT32) ((gctUINT32) (17) & ((gctUINT32) ((((1 ?
+ 15:8) - (0 ?
+ 15:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00464, &profiler_part1->se_culled_triangle_count));
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:8) - (0 ?
+ 15:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:8) - (0 ?
+ 15:8) + 1))))))) << (0 ?
+ 15:8))) | (((gctUINT32) ((gctUINT32) (18) & ((gctUINT32) ((((1 ?
+ 15:8) - (0 ?
+ 15:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00464, &profiler_part1->se_culled_lines_count));
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:8) - (0 ?
+ 15:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:8) - (0 ?
+ 15:8) + 1))))))) << (0 ?
+ 15:8))) | (((gctUINT32) ((gctUINT32) (19) & ((gctUINT32) ((((1 ?
+ 15:8) - (0 ?
+ 15:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00464, &profiler_part1->se_trivial_rejected_line_count));
+ if (hasNewCounters)
+ {
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:8) - (0 ?
+ 15:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:8) - (0 ?
+ 15:8) + 1))))))) << (0 ?
+ 15:8))) | (((gctUINT32) ((gctUINT32) (8) & ((gctUINT32) ((((1 ?
+ 15:8) - (0 ?
+ 15:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00464, &profiler_part1->se_starve_count));
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:8) - (0 ?
+ 15:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:8) - (0 ?
+ 15:8) + 1))))))) << (0 ?
+ 15:8))) | (((gctUINT32) ((gctUINT32) (9) & ((gctUINT32) ((((1 ?
+ 15:8) - (0 ?
+ 15:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00464, &profiler_part1->se_stall_count));
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:8) - (0 ?
+ 15:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:8) - (0 ?
+ 15:8) + 1))))))) << (0 ?
+ 15:8))) | (((gctUINT32) ((gctUINT32) (10) & ((gctUINT32) ((((1 ?
+ 15:8) - (0 ?
+ 15:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00464, &profiler_part1->se_receive_triangle_count));
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:8) - (0 ?
+ 15:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:8) - (0 ?
+ 15:8) + 1))))))) << (0 ?
+ 15:8))) | (((gctUINT32) ((gctUINT32) (11) & ((gctUINT32) ((((1 ?
+ 15:8) - (0 ?
+ 15:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00464, &profiler_part1->se_send_triangle_count));
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:8) - (0 ?
+ 15:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:8) - (0 ?
+ 15:8) + 1))))))) << (0 ?
+ 15:8))) | (((gctUINT32) ((gctUINT32) (12) & ((gctUINT32) ((((1 ?
+ 15:8) - (0 ?
+ 15:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00464, &profiler_part1->se_receive_lines_count));
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:8) - (0 ?
+ 15:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:8) - (0 ?
+ 15:8) + 1))))))) << (0 ?
+ 15:8))) | (((gctUINT32) ((gctUINT32) (13) & ((gctUINT32) ((((1 ?
+ 15:8) - (0 ?
+ 15:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00464, &profiler_part1->se_send_lines_count));
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:8) - (0 ?
+ 15:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:8) - (0 ?
+ 15:8) + 1))))))) << (0 ?
+ 15:8))) | (((gctUINT32) ((gctUINT32) (14) & ((gctUINT32) ((((1 ?
+ 15:8) - (0 ?
+ 15:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00464, &profiler_part1->se_process_count));
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:8) - (0 ?
+ 15:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:8) - (0 ?
+ 15:8) + 1))))))) << (0 ?
+ 15:8))) | (((gctUINT32) ((gctUINT32) (20) & ((gctUINT32) ((((1 ?
+ 15:8) - (0 ?
+ 15:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00464, &profiler_part1->se_non_idle_starve_count));
+ }
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:8) - (0 ?
+ 15:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:8) - (0 ?
+ 15:8) + 1))))))) << (0 ?
+ 15:8))) | (((gctUINT32) ((gctUINT32) (resetValue) & ((gctUINT32) ((((1 ?
+ 15:8) - (0 ?
+ 15:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8))) ));
+gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:8) - (0 ?
+ 15:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:8) - (0 ?
+ 15:8) + 1))))))) << (0 ?
+ 15:8))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ?
+ 15:8) - (0 ?
+ 15:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8)))
+));
+
+ gcmkUPDATE_PROFILE_DATA_PART1(se_clipped_triangle_count);
+ gcmkUPDATE_PROFILE_DATA_PART1(se_clipped_line_count);
+ gcmkUPDATE_PROFILE_DATA_PART1(se_culled_triangle_count);
+ gcmkUPDATE_PROFILE_DATA_PART1(se_culled_lines_count);
+ gcmkUPDATE_PROFILE_DATA_PART1(se_trivial_rejected_line_count);
+ if (hasNewCounters)
+ {
+ gcmkUPDATE_PROFILE_DATA_PART1(se_starve_count);
+ gcmkUPDATE_PROFILE_DATA_PART1(se_stall_count);
+ gcmkUPDATE_PROFILE_DATA_PART1(se_receive_triangle_count);
+ gcmkUPDATE_PROFILE_DATA_PART1(se_send_triangle_count);
+ gcmkUPDATE_PROFILE_DATA_PART1(se_receive_lines_count);
+ gcmkUPDATE_PROFILE_DATA_PART1(se_send_lines_count);
+ gcmkUPDATE_PROFILE_DATA_PART1(se_process_count);
+ gcmkUPDATE_PROFILE_DATA_PART1(se_non_idle_starve_count);
+ }
+
+ /* RA */
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 23:16) - (0 ?
+ 23:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 23:16) - (0 ?
+ 23:16) + 1))))))) << (0 ?
+ 23:16))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ?
+ 23:16) - (0 ?
+ 23:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00448, &profiler_part1->ra_valid_pixel_count_to_render));
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 23:16) - (0 ?
+ 23:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 23:16) - (0 ?
+ 23:16) + 1))))))) << (0 ?
+ 23:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 23:16) - (0 ?
+ 23:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00448, &profiler_part1->ra_total_quad_count));
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 23:16) - (0 ?
+ 23:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 23:16) - (0 ?
+ 23:16) + 1))))))) << (0 ?
+ 23:16))) | (((gctUINT32) ((gctUINT32) (2) & ((gctUINT32) ((((1 ?
+ 23:16) - (0 ?
+ 23:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00448, &profiler_part1->ra_valid_quad_count_after_early_z));
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 23:16) - (0 ?
+ 23:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 23:16) - (0 ?
+ 23:16) + 1))))))) << (0 ?
+ 23:16))) | (((gctUINT32) ((gctUINT32) (3) & ((gctUINT32) ((((1 ?
+ 23:16) - (0 ?
+ 23:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00448, &profiler_part1->ra_input_prim_count));
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 23:16) - (0 ?
+ 23:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 23:16) - (0 ?
+ 23:16) + 1))))))) << (0 ?
+ 23:16))) | (((gctUINT32) ((gctUINT32) (9) & ((gctUINT32) ((((1 ?
+ 23:16) - (0 ?
+ 23:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00448, &profiler_part1->ra_pipe_cache_miss_counter));
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 23:16) - (0 ?
+ 23:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 23:16) - (0 ?
+ 23:16) + 1))))))) << (0 ?
+ 23:16))) | (((gctUINT32) ((gctUINT32) (10) & ((gctUINT32) ((((1 ?
+ 23:16) - (0 ?
+ 23:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00448, &profiler_part1->ra_prefetch_cache_miss_counter));
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 23:16) - (0 ?
+ 23:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 23:16) - (0 ?
+ 23:16) + 1))))))) << (0 ?
+ 23:16))) | (((gctUINT32) ((gctUINT32) (11) & ((gctUINT32) ((((1 ?
+ 23:16) - (0 ?
+ 23:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00448, &profiler_part1->ra_eez_culled_counter));
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 23:16) - (0 ?
+ 23:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 23:16) - (0 ?
+ 23:16) + 1))))))) << (0 ?
+ 23:16))) | (((gctUINT32) ((gctUINT32) (17) & ((gctUINT32) ((((1 ?
+ 23:16) - (0 ?
+ 23:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00448, &profiler_part1->ra_pipe_hz_cache_miss_counter));
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 23:16) - (0 ?
+ 23:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 23:16) - (0 ?
+ 23:16) + 1))))))) << (0 ?
+ 23:16))) | (((gctUINT32) ((gctUINT32) (18) & ((gctUINT32) ((((1 ?
+ 23:16) - (0 ?
+ 23:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00448, &profiler_part1->ra_prefetch_hz_cache_miss_counter));
+ if (hasNewCounters)
+ {
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 23:16) - (0 ?
+ 23:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 23:16) - (0 ?
+ 23:16) + 1))))))) << (0 ?
+ 23:16))) | (((gctUINT32) ((gctUINT32) (13) & ((gctUINT32) ((((1 ?
+ 23:16) - (0 ?
+ 23:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00448, &profiler_part1->ra_non_idle_starve_count));
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 23:16) - (0 ?
+ 23:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 23:16) - (0 ?
+ 23:16) + 1))))))) << (0 ?
+ 23:16))) | (((gctUINT32) ((gctUINT32) (14) & ((gctUINT32) ((((1 ?
+ 23:16) - (0 ?
+ 23:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00448, &profiler_part1->ra_starve_count));
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 23:16) - (0 ?
+ 23:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 23:16) - (0 ?
+ 23:16) + 1))))))) << (0 ?
+ 23:16))) | (((gctUINT32) ((gctUINT32) (15) & ((gctUINT32) ((((1 ?
+ 23:16) - (0 ?
+ 23:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00448, &profiler_part1->ra_stall_count));
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 23:16) - (0 ?
+ 23:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 23:16) - (0 ?
+ 23:16) + 1))))))) << (0 ?
+ 23:16))) | (((gctUINT32) ((gctUINT32) (16) & ((gctUINT32) ((((1 ?
+ 23:16) - (0 ?
+ 23:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00448, &profiler_part1->ra_process_count));
+ }
+#if USE_SW_RESET
+ gcmkRESET_PROFILE_DATA_PART1(ra_valid_pixel_count_to_render);
+ gcmkRESET_PROFILE_DATA_PART1(ra_total_quad_count);
+ gcmkRESET_PROFILE_DATA_PART1(ra_valid_quad_count_after_early_z);
+ gcmkRESET_PROFILE_DATA_PART1(ra_input_prim_count);
+ gcmkRESET_PROFILE_DATA_PART1(ra_pipe_cache_miss_counter);
+ gcmkRESET_PROFILE_DATA_PART1(ra_prefetch_cache_miss_counter);
+ gcmkRESET_PROFILE_DATA_PART1(ra_eez_culled_counter);
+ gcmkRESET_PROFILE_DATA_PART1(ra_pipe_hz_cache_miss_counter);
+ gcmkRESET_PROFILE_DATA_PART1(ra_prefetch_hz_cache_miss_counter);
+ if (hasNewCounters)
+ {
+ gcmkRESET_PROFILE_DATA_PART1(ra_non_idle_starve_count);
+ gcmkRESET_PROFILE_DATA_PART1(ra_starve_count);
+ gcmkRESET_PROFILE_DATA_PART1(ra_stall_count);
+ gcmkRESET_PROFILE_DATA_PART1(ra_process_count);
+ }
+#endif
+ gcmkUPDATE_PROFILE_DATA_PART1(ra_valid_pixel_count_to_render);
+ gcmkUPDATE_PROFILE_DATA_PART1(ra_total_quad_count);
+ gcmkUPDATE_PROFILE_DATA_PART1(ra_valid_quad_count_after_early_z);
+ gcmkUPDATE_PROFILE_DATA_PART1(ra_input_prim_count);
+ gcmkUPDATE_PROFILE_DATA_PART1(ra_pipe_cache_miss_counter);
+ gcmkUPDATE_PROFILE_DATA_PART1(ra_prefetch_cache_miss_counter);
+ gcmkUPDATE_PROFILE_DATA_PART1(ra_eez_culled_counter);
+ gcmkUPDATE_PROFILE_DATA_PART1(ra_pipe_hz_cache_miss_counter);
+ gcmkUPDATE_PROFILE_DATA_PART1(ra_prefetch_hz_cache_miss_counter);
+ if (hasNewCounters)
+ {
+ gcmkUPDATE_PROFILE_DATA_PART1(ra_non_idle_starve_count);
+ gcmkUPDATE_PROFILE_DATA_PART1(ra_starve_count);
+ gcmkUPDATE_PROFILE_DATA_PART1(ra_stall_count);
+ gcmkUPDATE_PROFILE_DATA_PART1(ra_process_count);
+ }
+#if !USE_SW_RESET
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 23:16) - (0 ?
+ 23:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 23:16) - (0 ?
+ 23:16) + 1))))))) << (0 ?
+ 23:16))) | (((gctUINT32) ((gctUINT32) (resetValue) & ((gctUINT32) ((((1 ?
+ 23:16) - (0 ?
+ 23:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) ));
+gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 23:16) - (0 ?
+ 23:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 23:16) - (0 ?
+ 23:16) + 1))))))) << (0 ?
+ 23:16))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ?
+ 23:16) - (0 ?
+ 23:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16)))
+));
+#endif
+
+ /* TX */
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:24) - (0 ?
+ 31:24) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:24) - (0 ?
+ 31:24) + 1))))))) << (0 ?
+ 31:24))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ?
+ 31:24) - (0 ?
+ 31:24) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0044C, &profiler_part1->tx_total_bilinear_requests));
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:24) - (0 ?
+ 31:24) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:24) - (0 ?
+ 31:24) + 1))))))) << (0 ?
+ 31:24))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 31:24) - (0 ?
+ 31:24) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0044C, &profiler_part1->tx_total_trilinear_requests));
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:24) - (0 ?
+ 31:24) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:24) - (0 ?
+ 31:24) + 1))))))) << (0 ?
+ 31:24))) | (((gctUINT32) ((gctUINT32) (2) & ((gctUINT32) ((((1 ?
+ 31:24) - (0 ?
+ 31:24) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0044C, &profiler_part1->tx_total_discarded_texture_requests));
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:24) - (0 ?
+ 31:24) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:24) - (0 ?
+ 31:24) + 1))))))) << (0 ?
+ 31:24))) | (((gctUINT32) ((gctUINT32) (3) & ((gctUINT32) ((((1 ?
+ 31:24) - (0 ?
+ 31:24) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0044C, &profiler_part1->tx_total_texture_requests));
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:24) - (0 ?
+ 31:24) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:24) - (0 ?
+ 31:24) + 1))))))) << (0 ?
+ 31:24))) | (((gctUINT32) ((gctUINT32) (5) & ((gctUINT32) ((((1 ?
+ 31:24) - (0 ?
+ 31:24) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0044C, &profiler_part1->tx_mc0_miss_count));
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:24) - (0 ?
+ 31:24) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:24) - (0 ?
+ 31:24) + 1))))))) << (0 ?
+ 31:24))) | (((gctUINT32) ((gctUINT32) (6) & ((gctUINT32) ((((1 ?
+ 31:24) - (0 ?
+ 31:24) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0044C, &profiler_part1->tx_mc0_request_byte_count));
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:24) - (0 ?
+ 31:24) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:24) - (0 ?
+ 31:24) + 1))))))) << (0 ?
+ 31:24))) | (((gctUINT32) ((gctUINT32) (7) & ((gctUINT32) ((((1 ?
+ 31:24) - (0 ?
+ 31:24) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0044C, &profiler_part1->tx_mc1_miss_count));
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:24) - (0 ?
+ 31:24) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:24) - (0 ?
+ 31:24) + 1))))))) << (0 ?
+ 31:24))) | (((gctUINT32) ((gctUINT32) (8) & ((gctUINT32) ((((1 ?
+ 31:24) - (0 ?
+ 31:24) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0044C, &profiler_part1->tx_mc1_request_byte_count));
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:24) - (0 ?
+ 31:24) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:24) - (0 ?
+ 31:24) + 1))))))) << (0 ?
+ 31:24))) | (((gctUINT32) ((gctUINT32) (resetValue) & ((gctUINT32) ((((1 ?
+ 31:24) - (0 ?
+ 31:24) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) ));
+gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:24) - (0 ?
+ 31:24) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:24) - (0 ?
+ 31:24) + 1))))))) << (0 ?
+ 31:24))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ?
+ 31:24) - (0 ?
+ 31:24) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24)))
+));
+
+ gcmkUPDATE_PROFILE_DATA_PART1(tx_total_bilinear_requests);
+ gcmkUPDATE_PROFILE_DATA_PART1(tx_total_trilinear_requests);
+ gcmkUPDATE_PROFILE_DATA_PART1(tx_total_discarded_texture_requests);
+ gcmkUPDATE_PROFILE_DATA_PART1(tx_total_texture_requests);
+ gcmkUPDATE_PROFILE_DATA_PART1(tx_mc0_miss_count);
+ gcmkUPDATE_PROFILE_DATA_PART1(tx_mc0_request_byte_count);
+ gcmkUPDATE_PROFILE_DATA_PART1(tx_mc1_miss_count);
+ gcmkUPDATE_PROFILE_DATA_PART1(tx_mc1_request_byte_count);
+
+ /* MC */
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00478, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1))))))) << (0 ?
+ 7:0))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00468, &profiler_part2->mcc_total_read_req_8B_from_colorpipe));
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00478, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1))))))) << (0 ?
+ 7:0))) | (((gctUINT32) ((gctUINT32) (2) & ((gctUINT32) ((((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00468, &profiler_part2->mcc_total_read_req_8B_sentout_from_colorpipe));
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00478, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1))))))) << (0 ?
+ 7:0))) | (((gctUINT32) ((gctUINT32) (3) & ((gctUINT32) ((((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00468, &profiler_part2->mcc_total_write_req_8B_from_colorpipe));
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00478, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1))))))) << (0 ?
+ 7:0))) | (((gctUINT32) ((gctUINT32) (4) & ((gctUINT32) ((((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00468, &profiler_part2->mcc_total_read_req_sentout_from_colorpipe));
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00478, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1))))))) << (0 ?
+ 7:0))) | (((gctUINT32) ((gctUINT32) (5) & ((gctUINT32) ((((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00468, &profiler_part2->mcc_total_write_req_from_colorpipe));
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00478, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1))))))) << (0 ?
+ 7:0))) | (((gctUINT32) ((gctUINT32) (7) & ((gctUINT32) ((((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00468, &profiler_part2->mcc_total_read_req_8B_from_depthpipe));
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00478, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1))))))) << (0 ?
+ 7:0))) | (((gctUINT32) ((gctUINT32) (8) & ((gctUINT32) ((((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00468, &profiler_part2->mcc_total_read_req_8B_sentout_from_depthpipe));
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00478, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1))))))) << (0 ?
+ 7:0))) | (((gctUINT32) ((gctUINT32) (9) & ((gctUINT32) ((((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00468, &profiler_part2->mcc_total_write_req_8B_from_depthpipe));
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00478, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1))))))) << (0 ?
+ 7:0))) | (((gctUINT32) ((gctUINT32) (10) & ((gctUINT32) ((((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00468, &profiler_part2->mcc_total_read_req_sentout_from_depthpipe));
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00478, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1))))))) << (0 ?
+ 7:0))) | (((gctUINT32) ((gctUINT32) (11) & ((gctUINT32) ((((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00468, &profiler_part2->mcc_total_write_req_from_depthpipe));
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00478, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1))))))) << (0 ?
+ 7:0))) | (((gctUINT32) ((gctUINT32) (12) & ((gctUINT32) ((((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00468, &profiler_part2->mcc_total_read_req_8B_from_others));
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00478, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1))))))) << (0 ?
+ 7:0))) | (((gctUINT32) ((gctUINT32) (13) & ((gctUINT32) ((((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00468, &profiler_part2->mcc_total_write_req_8B_from_others));
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00478, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1))))))) << (0 ?
+ 7:0))) | (((gctUINT32) ((gctUINT32) (14) & ((gctUINT32) ((((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00468, &profiler_part2->mcc_total_read_req_from_others));
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00478, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1))))))) << (0 ?
+ 7:0))) | (((gctUINT32) ((gctUINT32) (15) & ((gctUINT32) ((((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00468, &profiler_part2->mcc_total_write_req_from_others));
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00478, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1))))))) << (0 ?
+ 7:0))) | (((gctUINT32) ((gctUINT32) (21) & ((gctUINT32) ((((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00468, &profiler_part2->mc_fe_read_bandwidth));
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00478, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1))))))) << (0 ?
+ 7:0))) | (((gctUINT32) ((gctUINT32) (22) & ((gctUINT32) ((((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00468, &profiler_part2->mc_mmu_read_bandwidth));
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00478, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1))))))) << (0 ?
+ 7:0))) | (((gctUINT32) ((gctUINT32) (23) & ((gctUINT32) ((((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00468, &profiler_part2->mc_blt_read_bandwidth));
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00478, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1))))))) << (0 ?
+ 7:0))) | (((gctUINT32) ((gctUINT32) (24) & ((gctUINT32) ((((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00468, &profiler_part2->mc_sh0_read_bandwidth));
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00478, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1))))))) << (0 ?
+ 7:0))) | (((gctUINT32) ((gctUINT32) (25) & ((gctUINT32) ((((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00468, &profiler_part2->mc_sh1_read_bandwidth));
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00478, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1))))))) << (0 ?
+ 7:0))) | (((gctUINT32) ((gctUINT32) (26) & ((gctUINT32) ((((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00468, &profiler_part2->mc_pe_write_bandwidth));
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00478, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1))))))) << (0 ?
+ 7:0))) | (((gctUINT32) ((gctUINT32) (27) & ((gctUINT32) ((((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00468, &profiler_part2->mc_blt_write_bandwidth));
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00478, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1))))))) << (0 ?
+ 7:0))) | (((gctUINT32) ((gctUINT32) (28) & ((gctUINT32) ((((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00468, &profiler_part2->mc_sh0_write_bandwidth));
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00478, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1))))))) << (0 ?
+ 7:0))) | (((gctUINT32) ((gctUINT32) (29) & ((gctUINT32) ((((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00468, &profiler_part2->mc_sh1_write_bandwidth));
+
+ /* Reset counters. */
+ gcmkONERROR(
+ gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x0003C, 1));
+ gcmkONERROR(
+ gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x0003C, 0));
+
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00478, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1))))))) << (0 ?
+ 7:0))) | (((gctUINT32) ((gctUINT32) (resetValue) & ((gctUINT32) ((((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) ));
+gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00478, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1))))))) << (0 ?
+ 7:0))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0)))
+));
+
+ gcmkUPDATE_PROFILE_DATA_PART2(mcc_total_read_req_8B_from_colorpipe);
+ gcmkUPDATE_PROFILE_DATA_PART2(mcc_total_read_req_8B_sentout_from_colorpipe);
+ gcmkUPDATE_PROFILE_DATA_PART2(mcc_total_write_req_8B_from_colorpipe);
+ gcmkUPDATE_PROFILE_DATA_PART2(mcc_total_read_req_sentout_from_colorpipe);
+ gcmkUPDATE_PROFILE_DATA_PART2(mcc_total_write_req_from_colorpipe);
+ gcmkUPDATE_PROFILE_DATA_PART2(mcc_total_read_req_8B_from_depthpipe);
+ gcmkUPDATE_PROFILE_DATA_PART2(mcc_total_read_req_8B_sentout_from_depthpipe);
+ gcmkUPDATE_PROFILE_DATA_PART2(mcc_total_write_req_8B_from_depthpipe);
+ gcmkUPDATE_PROFILE_DATA_PART2(mcc_total_read_req_sentout_from_depthpipe);
+ gcmkUPDATE_PROFILE_DATA_PART2(mcc_total_write_req_from_depthpipe);
+ gcmkUPDATE_PROFILE_DATA_PART2(mcc_total_read_req_8B_from_others);
+ gcmkUPDATE_PROFILE_DATA_PART2(mcc_total_write_req_8B_from_others);
+ gcmkUPDATE_PROFILE_DATA_PART2(mcc_total_read_req_from_others);
+ gcmkUPDATE_PROFILE_DATA_PART2(mcc_total_write_req_from_others);
+ gcmkUPDATE_PROFILE_DATA_PART2(mc_fe_read_bandwidth);
+ gcmkUPDATE_PROFILE_DATA_PART2(mc_mmu_read_bandwidth);
+ gcmkUPDATE_PROFILE_DATA_PART2(mc_blt_read_bandwidth);
+ gcmkUPDATE_PROFILE_DATA_PART2(mc_sh0_read_bandwidth);
+ gcmkUPDATE_PROFILE_DATA_PART2(mc_sh1_read_bandwidth);
+ gcmkUPDATE_PROFILE_DATA_PART2(mc_pe_write_bandwidth);
+ gcmkUPDATE_PROFILE_DATA_PART2(mc_blt_write_bandwidth);
+ gcmkUPDATE_PROFILE_DATA_PART2(mc_sh0_write_bandwidth);
+ gcmkUPDATE_PROFILE_DATA_PART2(mc_sh1_write_bandwidth);
+
+ /* read latency counters */
+ if (hasNewCounters)
+ {
+ /* latency */
+ gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x0056C,
+ &mc_axi_max_min_latency));
+
+ gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x00570,
+ &profiler_part2->mcc_axi_total_latency));
+
+ gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x00574,
+ &profiler_part2->mcc_axi_sample_count));
+
+ /* Reset Latency counters */
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x00568,
+ 0x10a));
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x00568,
+ 0xa));
+
+ profiler_part2->mcc_axi_min_latency = (mc_axi_max_min_latency & 0xffff0000) >> 16;
+ profiler_part2->mcc_axi_max_latency = (mc_axi_max_min_latency & 0x0000ffff);
+ if (profiler_part2->mcc_axi_min_latency == 4095)
+ profiler_part2->mcc_axi_min_latency = 0;
+
+ gcmkUPDATE_PROFILE_DATA_PART2(mcc_axi_min_latency);
+ gcmkUPDATE_PROFILE_DATA_PART2(mcc_axi_max_latency);
+ gcmkUPDATE_PROFILE_DATA_PART2(mcc_axi_total_latency);
+ gcmkUPDATE_PROFILE_DATA_PART2(mcc_axi_sample_count);
+ }
+
+ /* HI */
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00478, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:8) - (0 ?
+ 15:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:8) - (0 ?
+ 15:8) + 1))))))) << (0 ?
+ 15:8))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ?
+ 15:8) - (0 ?
+ 15:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0046C, &profiler_part2->hi0_axi_cycles_read_request_stalled));
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00478, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:8) - (0 ?
+ 15:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:8) - (0 ?
+ 15:8) + 1))))))) << (0 ?
+ 15:8))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 15:8) - (0 ?
+ 15:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0046C, &profiler_part2->hi0_axi_cycles_write_request_stalled));
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00478, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:8) - (0 ?
+ 15:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:8) - (0 ?
+ 15:8) + 1))))))) << (0 ?
+ 15:8))) | (((gctUINT32) ((gctUINT32) (2) & ((gctUINT32) ((((1 ?
+ 15:8) - (0 ?
+ 15:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0046C, &profiler_part2->hi0_axi_cycles_write_data_stalled));
+
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00478, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:8) - (0 ?
+ 15:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:8) - (0 ?
+ 15:8) + 1))))))) << (0 ?
+ 15:8))) | (((gctUINT32) ((gctUINT32) (resetValue) & ((gctUINT32) ((((1 ?
+ 15:8) - (0 ?
+ 15:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8))) ));
+gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00478, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:8) - (0 ?
+ 15:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:8) - (0 ?
+ 15:8) + 1))))))) << (0 ?
+ 15:8))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ?
+ 15:8) - (0 ?
+ 15:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8)))
+));
+
+ gcmkUPDATE_PROFILE_DATA_PART2(hi0_axi_cycles_read_request_stalled);
+ gcmkUPDATE_PROFILE_DATA_PART2(hi0_axi_cycles_write_request_stalled);
+ gcmkUPDATE_PROFILE_DATA_PART2(hi0_axi_cycles_write_data_stalled);
+
+ /* L2 */
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00478, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 23:16) - (0 ?
+ 23:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 23:16) - (0 ?
+ 23:16) + 1))))))) << (0 ?
+ 23:16))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ?
+ 23:16) - (0 ?
+ 23:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00564, &profiler_part2->l2_total_axi0_read_request_count));
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00478, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 23:16) - (0 ?
+ 23:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 23:16) - (0 ?
+ 23:16) + 1))))))) << (0 ?
+ 23:16))) | (((gctUINT32) ((gctUINT32) (4) & ((gctUINT32) ((((1 ?
+ 23:16) - (0 ?
+ 23:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00564, &profiler_part2->l2_total_axi0_write_request_count));
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00478, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 23:16) - (0 ?
+ 23:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 23:16) - (0 ?
+ 23:16) + 1))))))) << (0 ?
+ 23:16))) | (((gctUINT32) ((gctUINT32) (5) & ((gctUINT32) ((((1 ?
+ 23:16) - (0 ?
+ 23:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00564, &profiler_part2->l2_total_axi1_write_request_count));
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00478, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 23:16) - (0 ?
+ 23:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 23:16) - (0 ?
+ 23:16) + 1))))))) << (0 ?
+ 23:16))) | (((gctUINT32) ((gctUINT32) (8) & ((gctUINT32) ((((1 ?
+ 23:16) - (0 ?
+ 23:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00564, &profiler_part2->l2_total_read_transactions_request_by_axi0));
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00478, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 23:16) - (0 ?
+ 23:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 23:16) - (0 ?
+ 23:16) + 1))))))) << (0 ?
+ 23:16))) | (((gctUINT32) ((gctUINT32) (9) & ((gctUINT32) ((((1 ?
+ 23:16) - (0 ?
+ 23:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00564, &profiler_part2->l2_total_read_transactions_request_by_axi1));
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00478, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 23:16) - (0 ?
+ 23:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 23:16) - (0 ?
+ 23:16) + 1))))))) << (0 ?
+ 23:16))) | (((gctUINT32) ((gctUINT32) (12) & ((gctUINT32) ((((1 ?
+ 23:16) - (0 ?
+ 23:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00564, &profiler_part2->l2_total_write_transactions_request_by_axi0));
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00478, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 23:16) - (0 ?
+ 23:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 23:16) - (0 ?
+ 23:16) + 1))))))) << (0 ?
+ 23:16))) | (((gctUINT32) ((gctUINT32) (13) & ((gctUINT32) ((((1 ?
+ 23:16) - (0 ?
+ 23:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00564, &profiler_part2->l2_total_write_transactions_request_by_axi1));
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00478, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 23:16) - (0 ?
+ 23:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 23:16) - (0 ?
+ 23:16) + 1))))))) << (0 ?
+ 23:16))) | (((gctUINT32) ((gctUINT32) (16) & ((gctUINT32) ((((1 ?
+ 23:16) - (0 ?
+ 23:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00564, &profiler_part2->l2_axi0_minmax_latency));
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00478, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 23:16) - (0 ?
+ 23:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 23:16) - (0 ?
+ 23:16) + 1))))))) << (0 ?
+ 23:16))) | (((gctUINT32) ((gctUINT32) (17) & ((gctUINT32) ((((1 ?
+ 23:16) - (0 ?
+ 23:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00564, &profiler_part2->l2_axi0_total_latency));
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00478, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 23:16) - (0 ?
+ 23:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 23:16) - (0 ?
+ 23:16) + 1))))))) << (0 ?
+ 23:16))) | (((gctUINT32) ((gctUINT32) (18) & ((gctUINT32) ((((1 ?
+ 23:16) - (0 ?
+ 23:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00564, &profiler_part2->l2_axi0_total_request_count));
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00478, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 23:16) - (0 ?
+ 23:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 23:16) - (0 ?
+ 23:16) + 1))))))) << (0 ?
+ 23:16))) | (((gctUINT32) ((gctUINT32) (19) & ((gctUINT32) ((((1 ?
+ 23:16) - (0 ?
+ 23:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00564, &profiler_part2->l2_axi1_minmax_latency));
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00478, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 23:16) - (0 ?
+ 23:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 23:16) - (0 ?
+ 23:16) + 1))))))) << (0 ?
+ 23:16))) | (((gctUINT32) ((gctUINT32) (20) & ((gctUINT32) ((((1 ?
+ 23:16) - (0 ?
+ 23:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00564, &profiler_part2->l2_axi1_total_latency));
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00478, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 23:16) - (0 ?
+ 23:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 23:16) - (0 ?
+ 23:16) + 1))))))) << (0 ?
+ 23:16))) | (((gctUINT32) ((gctUINT32) (21) & ((gctUINT32) ((((1 ?
+ 23:16) - (0 ?
+ 23:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00564, &profiler_part2->l2_axi1_total_request_count));
+
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00478, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 23:16) - (0 ?
+ 23:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 23:16) - (0 ?
+ 23:16) + 1))))))) << (0 ?
+ 23:16))) | (((gctUINT32) ((gctUINT32) (resetValue) & ((gctUINT32) ((((1 ?
+ 23:16) - (0 ?
+ 23:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) ));
+gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00478, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 23:16) - (0 ?
+ 23:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 23:16) - (0 ?
+ 23:16) + 1))))))) << (0 ?
+ 23:16))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ?
+ 23:16) - (0 ?
+ 23:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16)))
+));
+
+ profiler_part2->l2_axi0_min_latency = (profiler_part2->l2_axi0_minmax_latency & 0xffff0000) >> 16;
+ profiler_part2->l2_axi0_max_latency = (profiler_part2->l2_axi0_minmax_latency & 0x0000ffff);
+ profiler_part2->l2_axi1_min_latency = (profiler_part2->l2_axi0_minmax_latency & 0xffff0000) >> 16;
+ profiler_part2->l2_axi1_max_latency = (profiler_part2->l2_axi0_minmax_latency & 0x0000ffff);
+ gcmkUPDATE_PROFILE_DATA_PART2(l2_total_axi0_read_request_count);
+ gcmkUPDATE_PROFILE_DATA_PART2(l2_total_axi1_read_request_count);
+ gcmkUPDATE_PROFILE_DATA_PART2(l2_total_axi0_write_request_count);
+ gcmkUPDATE_PROFILE_DATA_PART2(l2_total_axi1_write_request_count);
+ gcmkUPDATE_PROFILE_DATA_PART2(l2_total_read_transactions_request_by_axi0);
+ gcmkUPDATE_PROFILE_DATA_PART2(l2_total_read_transactions_request_by_axi1);
+ gcmkUPDATE_PROFILE_DATA_PART2(l2_total_write_transactions_request_by_axi0);
+ gcmkUPDATE_PROFILE_DATA_PART2(l2_total_write_transactions_request_by_axi1);
+ gcmkUPDATE_PROFILE_DATA_PART2(l2_axi0_min_latency);
+ gcmkUPDATE_PROFILE_DATA_PART2(l2_axi0_max_latency);
+ gcmkUPDATE_PROFILE_DATA_PART2(l2_axi0_total_latency);
+ gcmkUPDATE_PROFILE_DATA_PART2(l2_axi0_total_request_count);
+ gcmkUPDATE_PROFILE_DATA_PART2(l2_axi1_min_latency);
+ gcmkUPDATE_PROFILE_DATA_PART2(l2_axi1_max_latency);
+ gcmkUPDATE_PROFILE_DATA_PART2(l2_axi1_total_latency);
+ gcmkUPDATE_PROFILE_DATA_PART2(l2_axi1_total_request_count);
+
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(
+ command->os, command->mutexContextSeq
+ ));
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ if (mutexAcquired)
+ {
+ gckOS_ReleaseMutex(
+ command->os, command->mutexContextSeq
+ );
+ }
+
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+
+gceSTATUS
+gckHARDWARE_InitProfiler(
+ IN gckHARDWARE Hardware
+ )
+{
+ gceSTATUS status;
+ gctUINT32 control;
+
+ gcmkHEADER_ARG("Hardware=0x%x", Hardware);
+ gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x00000,
+ &control));
+ /* Enable debug register. */
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x00000,
+ ((((gctUINT32) (control)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 11:11) - (0 ?
+ 11:11) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 11:11) - (0 ?
+ 11:11) + 1))))))) << (0 ?
+ 11:11))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ?
+ 11:11) - (0 ?
+ 11:11) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 11:11) - (0 ? 11:11) + 1))))))) << (0 ? 11:11)))));
+
+OnError:
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+static gceSTATUS
+_ResetGPU(
+ IN gckHARDWARE Hardware,
+ IN gckOS Os,
+ IN gceCORE Core
+ )
+{
+ gctUINT32 control, idle;
+ gceSTATUS status;
+
+ for (;;)
+ {
+ /* Disable clock gating. */
+ gcmkONERROR(gckOS_WriteRegisterEx(Os,
+ Core,
+ Hardware->powerBaseAddress +
+ 0x00104,
+ 0x00000000));
+
+ control = ((((gctUINT32) (0x01590880)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 17:17) - (0 ?
+ 17:17) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 17:17) - (0 ?
+ 17:17) + 1))))))) << (0 ?
+ 17:17))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 17:17) - (0 ?
+ 17:17) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 17:17) - (0 ? 17:17) + 1))))))) << (0 ? 17:17)));
+
+ /* Disable pulse-eater. */
+ gcmkONERROR(gckOS_WriteRegisterEx(Os,
+ Core,
+ 0x0010C,
+ control));
+
+ gcmkONERROR(gckOS_WriteRegisterEx(Os,
+ Core,
+ 0x0010C,
+ ((((gctUINT32) (control)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1))))))) << (0 ?
+ 0:0))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)))));
+
+ gcmkONERROR(gckOS_WriteRegisterEx(Os,
+ Core,
+ 0x0010C,
+ control));
+
+ gcmkONERROR(gckOS_WriteRegisterEx(Os,
+ Core,
+ 0x00000,
+ ((((gctUINT32) (0x00000900)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 9:9) - (0 ?
+ 9:9) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 9:9) - (0 ?
+ 9:9) + 1))))))) << (0 ?
+ 9:9))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 9:9) - (0 ?
+ 9:9) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 9:9) - (0 ? 9:9) + 1))))))) << (0 ? 9:9)))));
+
+ gcmkONERROR(gckOS_WriteRegisterEx(Os,
+ Core,
+ 0x00000,
+ 0x00000900));
+
+ /* Wait for clock being stable. */
+ gcmkONERROR(gckOS_Delay(Os, 1));
+
+ /* Isolate the GPU. */
+ control = ((((gctUINT32) (0x00000900)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 19:19) - (0 ?
+ 19:19) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 19:19) - (0 ?
+ 19:19) + 1))))))) << (0 ?
+ 19:19))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 19:19) - (0 ?
+ 19:19) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 19:19) - (0 ? 19:19) + 1))))))) << (0 ? 19:19)));
+
+ gcmkONERROR(gckOS_WriteRegisterEx(Os,
+ Core,
+ 0x00000,
+ control));
+
+ if (gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_SECURITY_AHB) &&
+ (Hardware->options.secureMode == gcvSECURE_IN_NORMAL))
+ {
+ gcmkONERROR(gckOS_WriteRegisterEx(Os,
+ Core,
+ 0x003A8,
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1))))))) << (0 ?
+ 0:0))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)))));
+ }
+ else
+ {
+ /* Set soft reset. */
+ gcmkONERROR(gckOS_WriteRegisterEx(Os,
+ Core,
+ 0x00000,
+ ((((gctUINT32) (control)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 12:12) - (0 ?
+ 12:12) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 12:12) - (0 ?
+ 12:12) + 1))))))) << (0 ?
+ 12:12))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 12:12) - (0 ?
+ 12:12) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 12:12) - (0 ? 12:12) + 1))))))) << (0 ? 12:12)))));
+ }
+
+ /* Wait for reset. */
+ gcmkONERROR(gckOS_Delay(Os, 1));
+
+ /* Reset soft reset bit. */
+ gcmkONERROR(gckOS_WriteRegisterEx(Os,
+ Core,
+ 0x00000,
+ ((((gctUINT32) (control)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 12:12) - (0 ?
+ 12:12) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 12:12) - (0 ?
+ 12:12) + 1))))))) << (0 ?
+ 12:12))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ?
+ 12:12) - (0 ?
+ 12:12) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 12:12) - (0 ? 12:12) + 1))))))) << (0 ? 12:12)))));
+
+ /* Reset GPU isolation. */
+ control = ((((gctUINT32) (control)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 19:19) - (0 ?
+ 19:19) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 19:19) - (0 ?
+ 19:19) + 1))))))) << (0 ?
+ 19:19))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ?
+ 19:19) - (0 ?
+ 19:19) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 19:19) - (0 ? 19:19) + 1))))))) << (0 ? 19:19)));
+
+ gcmkONERROR(gckOS_WriteRegisterEx(Os,
+ Core,
+ 0x00000,
+ control));
+
+ /* Read idle register. */
+ gcmkONERROR(gckOS_ReadRegisterEx(Os,
+ Core,
+ 0x00004,
+ &idle));
+
+ if ((((((gctUINT32) (idle)) >> (0 ? 0:0)) & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1)))))) ) == 0)
+ {
+ continue;
+ }
+
+ /* Read reset register. */
+ gcmkONERROR(gckOS_ReadRegisterEx(Os,
+ Core,
+ 0x00000,
+ &control));
+
+ if (((((((gctUINT32) (control)) >> (0 ? 16:16)) & ((gctUINT32) ((((1 ? 16:16) - (0 ? 16:16) + 1) == 32) ? ~0U : (~(~0U << ((1 ? 16:16) - (0 ? 16:16) + 1)))))) ) == 0)
+ || ((((((gctUINT32) (control)) >> (0 ? 17:17)) & ((gctUINT32) ((((1 ? 17:17) - (0 ? 17:17) + 1) == 32) ? ~0U : (~(~0U << ((1 ? 17:17) - (0 ? 17:17) + 1)))))) ) == 0)
+ )
+ {
+ continue;
+ }
+
+ /* GPU is idle. */
+ break;
+ }
+
+ /* Success. */
+ return gcvSTATUS_OK;
+
+OnError:
+
+ /* Return the error. */
+ return status;
+}
+
+gceSTATUS
+gckHARDWARE_Reset(
+ IN gckHARDWARE Hardware
+ )
+{
+ gceSTATUS status;
+
+ gcmkHEADER_ARG("Hardware=0x%x", Hardware);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
+ gcmkVERIFY_OBJECT(Hardware->kernel, gcvOBJ_KERNEL);
+
+ /* Record context ID in debug register before reset. */
+ gcmkONERROR(gckHARDWARE_UpdateContextID(Hardware));
+
+ /* Hardware reset. */
+ status = gckOS_ResetGPU(Hardware->os, Hardware->core);
+
+ if (gcmIS_ERROR(status))
+ {
+ if (Hardware->identity.chipRevision < 0x4600)
+ {
+ /* Not supported - we need the isolation bit. */
+ gcmkONERROR(gcvSTATUS_NOT_SUPPORTED);
+ }
+
+ /* Soft reset. */
+ gcmkONERROR(_ResetGPU(Hardware, Hardware->os, Hardware->core));
+ }
+
+ /* Force the command queue to reload the next context. */
+ Hardware->kernel->command->currContext = gcvNULL;
+
+ /* Initialize hardware. */
+ gcmkONERROR(gckHARDWARE_InitializeHardware(Hardware));
+
+ /* Jump to address into which GPU should run if it doesn't stuck. */
+ gcmkONERROR(gckHARDWARE_Execute(Hardware, Hardware->kernel->restoreAddress, 16));
+
+ gcmkPRINT("[galcore]: recovery done");
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ gcmkPRINT("[galcore]: Hardware not reset successfully, give up");
+
+ /* Return the error. */
+ gcmkFOOTER();
+ return status;
+}
+
+gceSTATUS
+gckHARDWARE_GetBaseAddress(
+ IN gckHARDWARE Hardware,
+ OUT gctUINT32_PTR BaseAddress
+ )
+{
+ gcmkHEADER_ARG("Hardware=0x%x", Hardware);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
+ gcmkVERIFY_ARGUMENT(BaseAddress != gcvNULL);
+
+ /* Test if we have a new Memory Controller. */
+ if (gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_MC20))
+ {
+ /* No base address required. */
+ *BaseAddress = 0;
+ }
+ else
+ {
+ /* Get the base address from the OS. */
+ *BaseAddress = Hardware->baseAddress;
+ }
+
+ /* Success. */
+ gcmkFOOTER_ARG("*BaseAddress=0x%08x", *BaseAddress);
+ return gcvSTATUS_OK;
+}
+
+gceSTATUS
+gckHARDWARE_NeedBaseAddress(
+ IN gckHARDWARE Hardware,
+ IN gctUINT32 State,
+ OUT gctBOOL_PTR NeedBase
+ )
+{
+ gctBOOL need = gcvFALSE;
+
+ gcmkHEADER_ARG("Hardware=0x%x State=0x%08x", Hardware, State);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
+ gcmkVERIFY_ARGUMENT(NeedBase != gcvNULL);
+
+ /* Make sure this is a load state. */
+ if (((((gctUINT32) (State)) >> (0 ?
+ 31:27) & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1)))))) == (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ? ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))))
+ {
+#if gcdENABLE_3D
+ /* Get the state address. */
+ switch ((((((gctUINT32) (State)) >> (0 ? 15:0)) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1)))))) ))
+ {
+ case 0x0596:
+ case 0x0597:
+ case 0x0599:
+ case 0x059A:
+ case 0x05A9:
+ /* These states need a TRUE physical address. */
+ need = gcvTRUE;
+ break;
+ }
+#else
+ /* 2D addresses don't need a base address. */
+#endif
+ }
+
+ /* Return the flag. */
+ *NeedBase = need;
+
+ /* Success. */
+ gcmkFOOTER_ARG("*NeedBase=%d", *NeedBase);
+ return gcvSTATUS_OK;
+}
+
+/*******************************************************************************
+**
+** gckHARDWARE_IsFeatureAvailable
+**
+** Verifies whether the specified feature is available in hardware.
+**
+** INPUT:
+**
+** gckHARDWARE Hardware
+** Pointer to an gckHARDWARE object.
+**
+** gceFEATURE Feature
+** Feature to be verified.
+*/
+gceSTATUS
+gckHARDWARE_IsFeatureAvailable(
+ IN gckHARDWARE Hardware,
+ IN gceFEATURE Feature
+ )
+{
+ gctBOOL available;
+
+ gcmkHEADER_ARG("Hardware=0x%x Feature=%d", Hardware, Feature);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
+
+ available = _QueryFeatureDatabase(Hardware, Feature);
+
+ /* Return result. */
+ gcmkFOOTER_ARG("%d", available ? gcvSTATUS_TRUE : gcvSTATUS_FALSE);
+ return available ? gcvSTATUS_TRUE : gcvSTATUS_FALSE;
+}
+
+/*******************************************************************************
+**
+** gckHARDWARE_DumpMMUException
+**
+** Dump the MMU debug info on an MMU exception.
+**
+** INPUT:
+**
+** gckHARDWARE Harwdare
+** Pointer to an gckHARDWARE object.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckHARDWARE_DumpMMUException(
+ IN gckHARDWARE Hardware
+ )
+{
+ gctUINT32 mmu = 0;
+ gctUINT32 mmuStatus = 0;
+ gctUINT32 address = 0;
+ gctUINT32 i = 0;
+ gctUINT32 mtlb = 0;
+ gctUINT32 stlb = 0;
+ gctUINT32 offset = 0;
+#if gcdPROCESS_ADDRESS_SPACE
+ gcsDATABASE_PTR database;
+#endif
+ gctUINT32 mmuStatusRegAddress;
+ gctUINT32 mmuExceptionAddress;
+
+ gcmkHEADER_ARG("Hardware=0x%x", Hardware);
+
+#if gcdENABLE_TRUST_APPLICATION
+ if (Hardware->options.secureMode == gcvSECURE_IN_TA)
+ {
+ gcmkVERIFY_OK(gckKERNEL_SecurityDumpMMUException(Hardware->kernel));
+
+ gckMMU_DumpRecentFreedAddress(Hardware->kernel->mmu);
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+ }
+ else
+#endif
+ if (Hardware->options.secureMode == gcvSECURE_NONE)
+ {
+ mmuStatusRegAddress = 0x00188;
+ mmuExceptionAddress = 0x00190;
+ }
+ else
+ {
+ mmuStatusRegAddress = 0x00384;
+ mmuExceptionAddress = 0x00380;
+ }
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
+
+ gcmkPRINT("GPU[%d](ChipModel=0x%x ChipRevision=0x%x):\n",
+ Hardware->core,
+ Hardware->identity.chipModel,
+ Hardware->identity.chipRevision);
+
+ gcmkPRINT("**************************\n");
+ gcmkPRINT("*** MMU ERROR DUMP ***\n");
+ gcmkPRINT("**************************\n");
+
+
+ gcmkVERIFY_OK(
+ gckOS_ReadRegisterEx(Hardware->os,
+ Hardware->core,
+ mmuStatusRegAddress,
+ &mmuStatus));
+
+ gcmkPRINT(" MMU status = 0x%08X\n", mmuStatus);
+
+ for (i = 0; i < 4; i += 1)
+ {
+ mmu = mmuStatus & 0xF;
+ mmuStatus >>= 4;
+
+ if (mmu == 0)
+ {
+ continue;
+ }
+
+ switch (mmu)
+ {
+ case 1:
+ gcmkPRINT(" MMU%d: slave not present\n", i);
+ break;
+
+ case 2:
+ gcmkPRINT(" MMU%d: page not present\n", i);
+ break;
+
+ case 3:
+ gcmkPRINT(" MMU%d: write violation\n", i);
+ break;
+
+ case 4:
+ gcmkPRINT(" MMU%d: out of bound", i);
+ break;
+
+ case 5:
+ gcmkPRINT(" MMU%d: read security violation", i);
+ break;
+
+ case 6:
+ gcmkPRINT(" MMU%d: write security violation", i);
+ break;
+
+ default:
+ gcmkPRINT(" MMU%d: unknown state\n", i);
+ }
+
+ gcmkVERIFY_OK(
+ gckOS_ReadRegisterEx(Hardware->os,
+ Hardware->core,
+ mmuExceptionAddress + i * 4,
+ &address));
+
+ mtlb = (address & gcdMMU_MTLB_MASK) >> gcdMMU_MTLB_SHIFT;
+ stlb = (address & gcdMMU_STLB_4K_MASK) >> gcdMMU_STLB_4K_SHIFT;
+ offset = address & gcdMMU_OFFSET_4K_MASK;
+
+ gcmkPRINT(" MMU%d: exception address = 0x%08X\n", i, address);
+
+ gcmkPRINT(" MTLB entry = %d\n", mtlb);
+
+ gcmkPRINT(" STLB entry = %d\n", stlb);
+
+ gcmkPRINT(" Offset = 0x%08X (%d)\n", offset, offset);
+
+ gckMMU_DumpPageTableEntry(Hardware->kernel->mmu, address);
+
+#if gcdPROCESS_ADDRESS_SPACE
+ for (i = 0; i < gcmCOUNTOF(Hardware->kernel->db->db); ++i)
+ {
+ for (database = Hardware->kernel->db->db[i];
+ database != gcvNULL;
+ database = database->next)
+ {
+ gcmkPRINT(" database [%d] :", database->processID);
+ gckMMU_DumpPageTableEntry(database->mmu, address);
+ }
+ }
+#endif
+
+ gckMMU_DumpRecentFreedAddress(Hardware->kernel->mmu);
+ }
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+}
+
+gceSTATUS
+gckHARDWARE_HandleFault(
+ IN gckHARDWARE Hardware
+ )
+{
+ gceSTATUS status = gcvSTATUS_NOT_SUPPORTED;
+ gctUINT32 mmu, mmuStatus, address = gcvINVALID_ADDRESS, i = 0;
+ gctUINT32 mmuStatusRegAddress;
+ gctUINT32 mmuExceptionAddress;
+
+ gcuVIDMEM_NODE_PTR node;
+ gctUINT32 entryValue;
+
+ gcmkHEADER_ARG("Hardware=0x%x", Hardware);
+
+ if (Hardware->options.secureMode == gcvSECURE_NONE)
+ {
+ mmuStatusRegAddress = 0x00188;
+ mmuExceptionAddress = 0x00190;
+ }
+ else
+ {
+ mmuStatusRegAddress = 0x00384;
+ mmuExceptionAddress = 0x00380;
+ }
+
+ /* Get MMU exception address. */
+#if gcdENABLE_TRUST_APPLICATION
+ if (Hardware->options.secureMode == gcvSECURE_IN_TA)
+ {
+ gckKERNEL_ReadMMUException(Hardware->kernel, &mmuStatus, &address);
+ }
+ else
+#endif
+ {
+ gcmkVERIFY_OK(gckOS_ReadRegisterEx(Hardware->os,
+ Hardware->core,
+ mmuStatusRegAddress,
+ &mmuStatus
+ ));
+
+ gcmkPRINT(" MMU status = 0x%08X\n", mmuStatus);
+
+ for (i = 0; i < 4; i += 1)
+ {
+ mmu = mmuStatus & 0xF;
+ mmuStatus >>= 4;
+
+ if (mmu == 0)
+ {
+ continue;
+ }
+
+ gcmkVERIFY_OK(gckOS_ReadRegisterEx(
+ Hardware->os,
+ Hardware->core,
+ mmuExceptionAddress + i * 4,
+ &address
+ ));
+
+ break;
+ }
+ }
+
+ if (address != gcvINVALID_ADDRESS)
+ {
+ address &= ~gcdMMU_PAGE_4K_MASK;
+
+ /* Try to allocate memory and setup map for exception address. */
+ gcmkONERROR(gckVIDMEM_FindVIDMEM(Hardware->kernel, address, &node, &entryValue));
+
+#if gcdENABLE_TRUST_APPLICATION
+ if (Hardware->options.secureMode == gcvSECURE_IN_TA)
+ {
+ gckKERNEL_HandleMMUException(
+ Hardware->kernel,
+ mmuStatus,
+ entryValue,
+ address
+ );
+ }
+ else
+#endif
+ {
+ gctUINT32_PTR entry;
+
+ /* Setup page table. */
+ gcmkONERROR(gckMMU_GetPageEntry(Hardware->kernel->mmu, address, &entry));
+
+ gckMMU_SetPage(Hardware->kernel->mmu, entryValue, gcvTRUE, entry);
+
+ /* Resume hardware execution. */
+ gcmkVERIFY_OK(gckOS_WriteRegisterEx(
+ Hardware->os,
+ Hardware->core,
+ mmuExceptionAddress + i * 4,
+ *entry
+ ));
+ }
+ }
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ gcmkFOOTER();
+ return status;
+}
+
+/*******************************************************************************
+**
+** gckHARDWARE_DumpGPUState
+**
+** Dump the GPU debug registers.
+**
+** INPUT:
+**
+** gckHARDWARE Harwdare
+** Pointer to an gckHARDWARE object.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckHARDWARE_DumpGPUState(
+ IN gckHARDWARE Hardware
+ )
+{
+ static gctCONST_STRING _cmdState[] =
+ {
+ "PAR_IDLE_ST", "PAR_DEC_ST", "PAR_ADR0_ST", "PAR_LOAD0_ST",
+ "PAR_ADR1_ST", "PAR_LOAD1_ST", "PAR_3DADR_ST", "PAR_3DCMD_ST",
+ "PAR_3DCNTL_ST", "PAR_3DIDXCNTL_ST", "PAR_INITREQDMA_ST",
+ "PAR_DRAWIDX_ST", "PAR_DRAW_ST", "PAR_2DRECT0_ST", "PAR_2DRECT1_ST",
+ "PAR_2DDATA0_ST", "PAR_2DDATA1_ST", "PAR_WAITFIFO_ST", "PAR_WAIT_ST",
+ "PAR_LINK_ST", "PAR_END_ST", "PAR_STALL_ST"
+ };
+
+ static gctCONST_STRING _cmdDmaState[] =
+ {
+ "CMD_IDLE_ST", "CMD_START_ST", "CMD_REQ_ST", "CMD_END_ST"
+ };
+
+ static gctCONST_STRING _cmdFetState[] =
+ {
+ "FET_IDLE_ST", "FET_RAMVALID_ST", "FET_VALID_ST"
+ };
+
+ static gctCONST_STRING _reqDmaState[] =
+ {
+ "REQ_IDLE_ST", "REQ_WAITIDX_ST", "REQ_CAL_ST"
+ };
+
+ static gctCONST_STRING _calState[] =
+ {
+ "CAL_IDLE_ST", "CAL_LDADR_ST", "CAL_IDXCALC_ST"
+ };
+
+ static gctCONST_STRING _veReqState[] =
+ {
+ "VER_IDLE_ST", "VER_CKCACHE_ST", "VER_MISS_ST"
+ };
+
+ static gcsiDEBUG_REGISTERS _dbgRegs[] =
+ {
+ { "RA", 0x474, 16, 0x448, 256, 0x1, 0x00 },
+ { "TX", 0x474, 24, 0x44C, 128, 0x1, 0x00 },
+ { "FE", 0x470, 0, 0x450, 256, 0x1, 0x00 },
+ { "PE", 0x470, 16, 0x454, 256, 0x3, 0x00 },
+ { "DE", 0x470, 8, 0x458, 256, 0x1, 0x00 },
+ { "SH", 0x470, 24, 0x45C, 256, 0x1, 0x00 },
+ { "PA", 0x474, 0, 0x460, 256, 0x1, 0x00 },
+ { "SE", 0x474, 8, 0x464, 256, 0x1, 0x00 },
+ { "MC", 0x478, 0, 0x468, 256, 0x3, 0x00 },
+ { "HI", 0x478, 8, 0x46C, 256, 0x1, 0x00 },
+ { "TPG", 0x474, 24, 0x44C, 32, 0x2, 0x80 },
+ { "TFB", 0x474, 24, 0x44C, 32, 0x2, 0xA0 },
+ { "USC", 0x474, 24, 0x44C, 64, 0x2, 0xC0 },
+ { "L2", 0x478, 0, 0x564, 256, 0x1, 0x00 },
+ { "BLT", 0x478, 24, 0x1A4, 256, 0x1, 0x00 }
+ };
+
+ static gctUINT32 _otherRegs[] =
+ {
+ 0x040, 0x044, 0x04C, 0x050, 0x054, 0x058, 0x05C, 0x060,
+ 0x43c, 0x440, 0x444, 0x414, 0x100
+ };
+
+ gceSTATUS status;
+ gckKERNEL kernel = gcvNULL;
+ gctUINT32 idle = 0, axi = 0;
+ gctUINT32 dmaAddress1 = 0, dmaAddress2 = 0;
+ gctUINT32 dmaState1 = 0, dmaState2 = 0;
+ gctUINT32 dmaLow = 0, dmaHigh = 0;
+ gctUINT32 cmdState = 0, cmdDmaState = 0, cmdFetState = 0;
+ gctUINT32 dmaReqState = 0, calState = 0, veReqState = 0;
+ gctUINT i;
+ gctUINT pipe = 0, pixelPipes = 0;
+ gctUINT32 control = 0, oldControl = 0;
+ gckOS os = Hardware->os;
+ gceCORE core = Hardware->core;
+
+ gcmkHEADER_ARG("Hardware=0x%X", Hardware);
+
+ kernel = Hardware->kernel;
+
+ gcmkPRINT_N(12, "GPU[%d](ChipModel=0x%x ChipRevision=0x%x):\n",
+ core,
+ Hardware->identity.chipModel,
+ Hardware->identity.chipRevision);
+
+ pixelPipes = Hardware->identity.pixelPipes
+ ? Hardware->identity.pixelPipes
+ : 1;
+
+ /* Reset register values. */
+ idle = axi =
+ dmaState1 = dmaState2 =
+ dmaAddress1 = dmaAddress2 =
+ dmaLow = dmaHigh = 0;
+
+ /* Verify whether DMA is running. */
+ gcmkONERROR(_VerifyDMA(
+ os, core, &dmaAddress1, &dmaAddress2, &dmaState1, &dmaState2
+ ));
+
+ cmdState = dmaState2 & 0x1F;
+ cmdDmaState = (dmaState2 >> 8) & 0x03;
+ cmdFetState = (dmaState2 >> 10) & 0x03;
+ dmaReqState = (dmaState2 >> 12) & 0x03;
+ calState = (dmaState2 >> 14) & 0x03;
+ veReqState = (dmaState2 >> 16) & 0x03;
+
+ gcmkONERROR(gckOS_ReadRegisterEx(os, core, 0x00004, &idle));
+ gcmkONERROR(gckOS_ReadRegisterEx(os, core, 0x0000C, &axi));
+ gcmkONERROR(gckOS_ReadRegisterEx(os, core, 0x00668, &dmaLow));
+ gcmkONERROR(gckOS_ReadRegisterEx(os, core, 0x00668, &dmaLow));
+ gcmkONERROR(gckOS_ReadRegisterEx(os, core, 0x0066C, &dmaHigh));
+ gcmkONERROR(gckOS_ReadRegisterEx(os, core, 0x0066C, &dmaHigh));
+
+ gcmkPRINT_N(0, "**************************\n");
+ gcmkPRINT_N(0, "*** GPU STATE DUMP ***\n");
+ gcmkPRINT_N(0, "**************************\n");
+
+ gcmkPRINT_N(4, " axi = 0x%08X\n", axi);
+
+ gcmkPRINT_N(4, " idle = 0x%08X\n", idle);
+ if ((idle & 0x00000001) == 0) gcmkPRINT_N(0, " FE not idle\n");
+ if ((idle & 0x00000002) == 0) gcmkPRINT_N(0, " DE not idle\n");
+ if ((idle & 0x00000004) == 0) gcmkPRINT_N(0, " PE not idle\n");
+ if ((idle & 0x00000008) == 0) gcmkPRINT_N(0, " SH not idle\n");
+ if ((idle & 0x00000010) == 0) gcmkPRINT_N(0, " PA not idle\n");
+ if ((idle & 0x00000020) == 0) gcmkPRINT_N(0, " SE not idle\n");
+ if ((idle & 0x00000040) == 0) gcmkPRINT_N(0, " RA not idle\n");
+ if ((idle & 0x00000080) == 0) gcmkPRINT_N(0, " TX not idle\n");
+ if ((idle & 0x00000100) == 0) gcmkPRINT_N(0, " VG not idle\n");
+ if ((idle & 0x00000200) == 0) gcmkPRINT_N(0, " IM not idle\n");
+ if ((idle & 0x00000400) == 0) gcmkPRINT_N(0, " FP not idle\n");
+ if ((idle & 0x00000800) == 0) gcmkPRINT_N(0, " TS not idle\n");
+ if ((idle & 0x00001000) == 0) gcmkPRINT_N(0, " BL not idle\n");
+ if ((idle & 0x00002000) == 0) gcmkPRINT_N(0, " BP not idle\n");
+ if ((idle & 0x00004000) == 0) gcmkPRINT_N(0, " MC not idle\n");
+ if ((idle & 0x80000000) != 0) gcmkPRINT_N(0, " AXI low power mode\n");
+
+ if (
+ (dmaAddress1 == dmaAddress2)
+ && (dmaState1 == dmaState2)
+ )
+ {
+ gcmkPRINT_N(0, " DMA appears to be stuck at this address:\n");
+ gcmkPRINT_N(4, " 0x%08X\n", dmaAddress1);
+ }
+ else
+ {
+ if (dmaAddress1 == dmaAddress2)
+ {
+ gcmkPRINT_N(0, " DMA address is constant, but state is changing:\n");
+ gcmkPRINT_N(4, " 0x%08X\n", dmaState1);
+ gcmkPRINT_N(4, " 0x%08X\n", dmaState2);
+ }
+ else
+ {
+ gcmkPRINT_N(0, " DMA is running; known addresses are:\n");
+ gcmkPRINT_N(4, " 0x%08X\n", dmaAddress1);
+ gcmkPRINT_N(4, " 0x%08X\n", dmaAddress2);
+ }
+ }
+
+ gcmkPRINT_N(4, " dmaLow = 0x%08X\n", dmaLow);
+ gcmkPRINT_N(4, " dmaHigh = 0x%08X\n", dmaHigh);
+ gcmkPRINT_N(4, " dmaState = 0x%08X\n", dmaState2);
+ gcmkPRINT_N(8, " command state = %d (%s)\n", cmdState, _cmdState [cmdState]);
+ gcmkPRINT_N(8, " command DMA state = %d (%s)\n", cmdDmaState, _cmdDmaState[cmdDmaState]);
+ gcmkPRINT_N(8, " command fetch state = %d (%s)\n", cmdFetState, _cmdFetState[cmdFetState]);
+ gcmkPRINT_N(8, " DMA request state = %d (%s)\n", dmaReqState, _reqDmaState[dmaReqState]);
+ gcmkPRINT_N(8, " cal state = %d (%s)\n", calState, _calState [calState]);
+ gcmkPRINT_N(8, " VE request state = %d (%s)\n", veReqState, _veReqState [veReqState]);
+
+ gcmkPRINT_N(0, " Debug registers:\n");
+
+ for (i = 0; i < gcmCOUNTOF(_dbgRegs); i += 1)
+ {
+ gcmkONERROR(_DumpDebugRegisters(os, core, &_dbgRegs[i]));
+ }
+
+ /* Record control. */
+ gckOS_ReadRegisterEx(os, core, 0x0, &oldControl);
+
+ for (pipe = 0; pipe < pixelPipes; pipe++)
+ {
+ gcmkPRINT_N(4, " Other Registers[%d]:\n", pipe);
+
+ /* Switch pipe. */
+ gcmkONERROR(gckOS_ReadRegisterEx(os, core, 0x0, &control));
+ control &= ~(0xF << 20);
+ control |= (pipe << 20);
+ gcmkONERROR(gckOS_WriteRegisterEx(os, core, 0x0, control));
+
+ for (i = 0; i < gcmCOUNTOF(_otherRegs); i += 1)
+ {
+ gctUINT32 read;
+ gcmkONERROR(gckOS_ReadRegisterEx(os, core, _otherRegs[i], &read));
+ gcmkPRINT_N(12, " [0x%04X] 0x%08X\n", _otherRegs[i], read);
+ }
+
+ if (Hardware->mmuVersion)
+ {
+ gcmkPRINT(" MMU status from MC[%d]:", pipe);
+
+ gckHARDWARE_DumpMMUException(Hardware);
+ }
+ }
+
+ /* Restore control. */
+ gcmkONERROR(gckOS_WriteRegisterEx(os, core, 0x0, oldControl));
+
+ if (gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_HALTI0))
+ {
+ /* FE debug register. */
+ gcmkVERIFY_OK(_DumpLinkStack(os, core, &_dbgRegs[2]));
+ }
+
+ _DumpFEStack(os, core, &_dbgRegs[2]);
+
+ gcmkPRINT_N(0, "**************************\n");
+ gcmkPRINT_N(0, "***** SW COUNTERS *****\n");
+ gcmkPRINT_N(0, "**************************\n");
+ gcmkPRINT_N(4, " Execute Count = 0x%08X\n", Hardware->executeCount);
+ gcmkPRINT_N(4, " Execute Addr = 0x%08X\n", Hardware->lastExecuteAddress);
+ gcmkPRINT_N(4, " End Addr = 0x%08X\n", Hardware->lastEnd);
+
+ /* dump stack. */
+ gckOS_DumpCallStack(os);
+
+OnError:
+
+ /* Return the error. */
+ gcmkFOOTER();
+ return status;
+}
+
+static gceSTATUS
+gckHARDWARE_ReadPerformanceRegister(
+ IN gckHARDWARE Hardware,
+ IN gctUINT PerformanceAddress,
+ IN gctUINT IndexAddress,
+ IN gctUINT IndexShift,
+ IN gctUINT Index,
+ OUT gctUINT32_PTR Value
+ )
+{
+ gceSTATUS status;
+
+ gcmkHEADER_ARG("Hardware=0x%x PerformanceAddress=0x%x IndexAddress=0x%x "
+ "IndexShift=%u Index=%u",
+ Hardware, PerformanceAddress, IndexAddress, IndexShift,
+ Index);
+
+ /* Write the index. */
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
+ Hardware->core,
+ IndexAddress,
+ Index << IndexShift));
+
+ /* Read the register. */
+ gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
+ Hardware->core,
+ PerformanceAddress,
+ Value));
+
+ /* Test for reset. */
+ if (Index == 15)
+ {
+ /* Index another register to get out of reset. */
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, IndexAddress, 0));
+ }
+
+ /* Success. */
+ gcmkFOOTER_ARG("*Value=0x%x", *Value);
+ return gcvSTATUS_OK;
+
+OnError:
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+gceSTATUS
+gckHARDWARE_GetFrameInfo(
+ IN gckHARDWARE Hardware,
+ OUT gcsHAL_FRAME_INFO * FrameInfo
+ )
+{
+ gceSTATUS status;
+ gctUINT i, clock;
+ gcsHAL_FRAME_INFO info;
+#if gcdFRAME_DB_RESET
+ gctUINT reset;
+#endif
+
+ gcmkHEADER_ARG("Hardware=0x%x", Hardware);
+
+ /* Get profile tick. */
+ gcmkONERROR(gckOS_GetProfileTick(&info.ticks));
+
+ /* Read SH counters and reset them. */
+ gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
+ Hardware,
+ 0x0045C,
+ 0x00470,
+ 24,
+ 4,
+ &info.shaderCycles));
+ gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
+ Hardware,
+ 0x0045C,
+ 0x00470,
+ 24,
+ 9,
+ &info.vsInstructionCount));
+ gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
+ Hardware,
+ 0x0045C,
+ 0x00470,
+ 24,
+ 12,
+ &info.vsTextureCount));
+ gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
+ Hardware,
+ 0x0045C,
+ 0x00470,
+ 24,
+ 7,
+ &info.psInstructionCount));
+ gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
+ Hardware,
+ 0x0045C,
+ 0x00470,
+ 24,
+ 14,
+ &info.psTextureCount));
+#if gcdFRAME_DB_RESET
+ gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
+ Hardware,
+ 0x0045C,
+ 0x00470,
+ 24,
+ 15,
+ &reset));
+#endif
+
+ /* Read PA counters and reset them. */
+ gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
+ Hardware,
+ 0x00460,
+ 0x00474,
+ 0,
+ 3,
+ &info.vertexCount));
+ gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
+ Hardware,
+ 0x00460,
+ 0x00474,
+ 0,
+ 4,
+ &info.primitiveCount));
+ gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
+ Hardware,
+ 0x00460,
+ 0x00474,
+ 0,
+ 7,
+ &info.rejectedPrimitives));
+ gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
+ Hardware,
+ 0x00460,
+ 0x00474,
+ 0,
+ 8,
+ &info.culledPrimitives));
+ gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
+ Hardware,
+ 0x00460,
+ 0x00474,
+ 0,
+ 6,
+ &info.clippedPrimitives));
+ gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
+ Hardware,
+ 0x00460,
+ 0x00474,
+ 0,
+ 5,
+ &info.outPrimitives));
+#if gcdFRAME_DB_RESET
+ gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
+ Hardware,
+ 0x00460,
+ 0x00474,
+ 0,
+ 15,
+ &reset));
+#endif
+
+ /* Read RA counters and reset them. */
+ gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
+ Hardware,
+ 0x00448,
+ 0x00474,
+ 16,
+ 3,
+ &info.inPrimitives));
+ gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
+ Hardware,
+ 0x00448,
+ 0x00474,
+ 16,
+ 11,
+ &info.culledQuadCount));
+ gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
+ Hardware,
+ 0x00448,
+ 0x00474,
+ 16,
+ 1,
+ &info.totalQuadCount));
+ gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
+ Hardware,
+ 0x00448,
+ 0x00474,
+ 16,
+ 2,
+ &info.quadCount));
+ gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
+ Hardware,
+ 0x00448,
+ 0x00474,
+ 16,
+ 0,
+ &info.totalPixelCount));
+#if gcdFRAME_DB_RESET
+ gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
+ Hardware,
+ 0x00448,
+ 0x00474,
+ 16,
+ 15,
+ &reset));
+#endif
+
+ /* Read TX counters and reset them. */
+ gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
+ Hardware,
+ 0x0044C,
+ 0x00474,
+ 24,
+ 0,
+ &info.bilinearRequests));
+ gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
+ Hardware,
+ 0x0044C,
+ 0x00474,
+ 24,
+ 1,
+ &info.trilinearRequests));
+ gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
+ Hardware,
+ 0x0044C,
+ 0x00474,
+ 24,
+ 8,
+ &info.txHitCount));
+ gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
+ Hardware,
+ 0x0044C,
+ 0x00474,
+ 24,
+ 9,
+ &info.txMissCount));
+ gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
+ Hardware,
+ 0x0044C,
+ 0x00474,
+ 24,
+ 6,
+ &info.txBytes8));
+#if gcdFRAME_DB_RESET
+ gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
+ Hardware,
+ 0x0044C,
+ 0x00474,
+ 24,
+ 15,
+ &reset));
+#endif
+
+ /* Read clock control register. */
+ gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x00000,
+ &clock));
+
+ /* Walk through all avaiable pixel pipes. */
+ for (i = 0; i < Hardware->identity.pixelPipes; ++i)
+ {
+ /* Select proper pipe. */
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x00000,
+ ((((gctUINT32) (clock)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 23:20) - (0 ?
+ 23:20) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 23:20) - (0 ?
+ 23:20) + 1))))))) << (0 ?
+ 23:20))) | (((gctUINT32) ((gctUINT32) (i) & ((gctUINT32) ((((1 ?
+ 23:20) - (0 ?
+ 23:20) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 23:20) - (0 ? 23:20) + 1))))))) << (0 ? 23:20)))));
+
+ /* Read cycle registers. */
+ gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x00078,
+ &info.cycles[i]));
+ gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x0007C,
+ &info.idleCycles[i]));
+ gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x00438,
+ &info.mcCycles[i]));
+
+ /* Read bandwidth registers. */
+ gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x0005C,
+ &info.readRequests[i]));
+ gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x00040,
+ &info.readBytes8[i]));
+ gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x00050,
+ &info.writeRequests[i]));
+ gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x00044,
+ &info.writeBytes8[i]));
+
+ /* Read PE counters. */
+ gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
+ Hardware,
+ 0x00454,
+ 0x00470,
+ 16,
+ 0,
+ &info.colorKilled[i]));
+ gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
+ Hardware,
+ 0x00454,
+ 0x00470,
+ 16,
+ 2,
+ &info.colorDrawn[i]));
+ gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
+ Hardware,
+ 0x00454,
+ 0x00470,
+ 16,
+ 1,
+ &info.depthKilled[i]));
+ gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
+ Hardware,
+ 0x00454,
+ 0x00470,
+ 16,
+ 3,
+ &info.depthDrawn[i]));
+ }
+
+ /* Zero out remaning reserved counters. */
+ for (; i < 8; ++i)
+ {
+ info.readBytes8[i] = 0;
+ info.writeBytes8[i] = 0;
+ info.cycles[i] = 0;
+ info.idleCycles[i] = 0;
+ info.mcCycles[i] = 0;
+ info.readRequests[i] = 0;
+ info.writeRequests[i] = 0;
+ info.colorKilled[i] = 0;
+ info.colorDrawn[i] = 0;
+ info.depthKilled[i] = 0;
+ info.depthDrawn[i] = 0;
+ }
+
+ /* Reset clock control register. */
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x00000,
+ clock));
+
+ /* Reset cycle and bandwidth counters. */
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x0003C,
+ 1));
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x0003C,
+ 0));
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x00078,
+ 0));
+
+#if gcdFRAME_DB_RESET
+ /* Reset PE counters. */
+ gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
+ Hardware,
+ 0x00454,
+ 0x00470,
+ 16,
+ 15,
+ &reset));
+#endif
+
+ /* Copy to user. */
+ gcmkONERROR(gckOS_CopyToUserData(Hardware->os,
+ &info,
+ FrameInfo,
+ gcmSIZEOF(info)));
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+gceSTATUS
+gckHARDWARE_DumpGpuProfile(
+ IN gckHARDWARE Hardware
+ )
+{
+ gceSTATUS status = gcvSTATUS_OK;
+ gctUINT clock, i;
+ gctUINT32 totalRead, totalWrite, read, write;
+
+ gcmkHEADER_ARG("Hardware=0x%x", Hardware);
+
+ /* Read clock control register. */
+ gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x00000,
+ &clock));
+
+ totalRead = 0;
+ totalWrite = 0;
+
+ /* Walk through all avaiable pixel pipes. */
+ for (i = 0; i < Hardware->identity.pixelPipes; ++i)
+ {
+ /* Select proper pipe. */
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x00000,
+ ((((gctUINT32) (clock)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 23:20) - (0 ?
+ 23:20) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 23:20) - (0 ?
+ 23:20) + 1))))))) << (0 ?
+ 23:20))) | (((gctUINT32) ((gctUINT32) (i) & ((gctUINT32) ((((1 ?
+ 23:20) - (0 ?
+ 23:20) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 23:20) - (0 ? 23:20) + 1))))))) << (0 ? 23:20)))));
+
+ /* BW */
+ gcmkONERROR(
+ gckOS_ReadRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x00040,
+ &read));
+ totalRead += read;
+
+ gcmkONERROR(
+ gckOS_ReadRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x00044,
+ &write));
+ totalWrite += write;
+ }
+
+ gcmkPRINT("==============GPU Profile: read request : %d\n", totalRead);
+ gcmkPRINT("==============GPU Profile: write request: %d\n", totalWrite);
+
+ /* Reset clock control register. */
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x00000,
+ clock));
+ /* Reset counters. */
+ gcmkONERROR(
+ gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x0003C, 1));
+ gcmkONERROR(
+ gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x0003C, 0));
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+#if gcdDVFS
+#define READ_FROM_EATER1 0
+
+gceSTATUS
+gckHARDWARE_QueryLoad(
+ IN gckHARDWARE Hardware,
+ OUT gctUINT32 * Load
+ )
+{
+ gctUINT32 debug1;
+ gceSTATUS status;
+ gcmkHEADER_ARG("Hardware=0x%X", Hardware);
+
+ gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
+ gcmkVERIFY_ARGUMENT(Load != gcvNULL);
+
+ gckOS_AcquireMutex(Hardware->os, Hardware->powerMutex, gcvINFINITE);
+
+ if (Hardware->chipPowerState == gcvPOWER_ON)
+ {
+ gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x00110,
+ Load));
+#if READ_FROM_EATER1
+ gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x00134,
+ Load));
+#endif
+
+ gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x00114,
+ &debug1));
+
+ /* Patch result of 0x110 with result of 0x114. */
+ if ((debug1 & 0xFF) == 1)
+ {
+ *Load &= ~0xFF;
+ *Load |= 1;
+ }
+
+ if (((debug1 & 0xFF00) >> 8) == 1)
+ {
+ *Load &= ~(0xFF << 8);
+ *Load |= 1 << 8;
+ }
+
+ if (((debug1 & 0xFF0000) >> 16) == 1)
+ {
+ *Load &= ~(0xFF << 16);
+ *Load |= 1 << 16;
+ }
+
+ if (((debug1 & 0xFF000000) >> 24) == 1)
+ {
+ *Load &= ~(0xFF << 24);
+ *Load |= 1 << 24;
+ }
+ }
+ else
+ {
+ status = gcvSTATUS_INVALID_REQUEST;
+ }
+
+OnError:
+
+ gckOS_ReleaseMutex(Hardware->os, Hardware->powerMutex);
+
+ gcmkFOOTER();
+ return status;
+}
+
+gceSTATUS
+gckHARDWARE_SetDVFSPeroid(
+ IN gckHARDWARE Hardware,
+ OUT gctUINT32 Frequency
+ )
+{
+ gceSTATUS status;
+ gctUINT32 period;
+ gctUINT32 eater;
+
+#if READ_FROM_EATER1
+ gctUINT32 period1;
+ gctUINT32 eater1;
+#endif
+
+ gcmkHEADER_ARG("Hardware=0x%X Frequency=%d", Hardware, Frequency);
+
+ gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
+
+ period = 0;
+
+ while((64 << period) < (gcdDVFS_ANAYLSE_WINDOW * Frequency * 1000) )
+ {
+ period++;
+ }
+
+#if READ_FROM_EATER1
+ /*
+ * Peroid = F * 1000 * 1000 / (60 * 16 * 1024);
+ */
+ period1 = Frequency * 6250 / 6114;
+#endif
+
+ gckOS_AcquireMutex(Hardware->os, Hardware->powerMutex, gcvINFINITE);
+
+ if (Hardware->chipPowerState == gcvPOWER_ON)
+ {
+ /* Get current configure. */
+ gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x0010C,
+ &eater));
+
+ /* Change peroid. */
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x0010C,
+ ((((gctUINT32) (eater)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:8) - (0 ?
+ 15:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:8) - (0 ?
+ 15:8) + 1))))))) << (0 ?
+ 15:8))) | (((gctUINT32) ((gctUINT32) (period) & ((gctUINT32) ((((1 ?
+ 15:8) - (0 ?
+ 15:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8)))));
+
+#if READ_FROM_EATER1
+ /* Config eater1. */
+ gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x00130,
+ &eater1));
+
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x00130,
+ ((((gctUINT32) (eater1)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:16) - (0 ?
+ 31:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:16) - (0 ?
+ 31:16) + 1))))))) << (0 ?
+ 31:16))) | (((gctUINT32) ((gctUINT32) (period1) & ((gctUINT32) ((((1 ?
+ 31:16) - (0 ?
+ 31:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:16) - (0 ? 31:16) + 1))))))) << (0 ? 31:16)))));
+#endif
+ }
+ else
+ {
+ status = gcvSTATUS_INVALID_REQUEST;
+ }
+
+OnError:
+ gckOS_ReleaseMutex(Hardware->os, Hardware->powerMutex);
+
+ gcmkFOOTER();
+ return status;
+}
+
+gceSTATUS
+gckHARDWARE_InitDVFS(
+ IN gckHARDWARE Hardware
+ )
+{
+ gceSTATUS status;
+ gctUINT32 data;
+
+ gcmkHEADER_ARG("Hardware=0x%X", Hardware);
+
+ gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
+
+ gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x0010C,
+ &data));
+
+ data = ((((gctUINT32) (data)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 16:16) - (0 ?
+ 16:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 16:16) - (0 ?
+ 16:16) + 1))))))) << (0 ?
+ 16:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 16:16) - (0 ?
+ 16:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 16:16) - (0 ? 16:16) + 1))))))) << (0 ? 16:16)));
+ data = ((((gctUINT32) (data)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 18:18) - (0 ?
+ 18:18) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 18:18) - (0 ?
+ 18:18) + 1))))))) << (0 ?
+ 18:18))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 18:18) - (0 ?
+ 18:18) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 18:18) - (0 ? 18:18) + 1))))))) << (0 ? 18:18)));
+ data = ((((gctUINT32) (data)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 19:19) - (0 ?
+ 19:19) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 19:19) - (0 ?
+ 19:19) + 1))))))) << (0 ?
+ 19:19))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ?
+ 19:19) - (0 ?
+ 19:19) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 19:19) - (0 ? 19:19) + 1))))))) << (0 ? 19:19)));
+ data = ((((gctUINT32) (data)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 20:20) - (0 ?
+ 20:20) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 20:20) - (0 ?
+ 20:20) + 1))))))) << (0 ?
+ 20:20))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 20:20) - (0 ?
+ 20:20) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 20:20) - (0 ? 20:20) + 1))))))) << (0 ? 20:20)));
+ data = ((((gctUINT32) (data)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 23:23) - (0 ?
+ 23:23) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 23:23) - (0 ?
+ 23:23) + 1))))))) << (0 ?
+ 23:23))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 23:23) - (0 ?
+ 23:23) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 23:23) - (0 ? 23:23) + 1))))))) << (0 ? 23:23)));
+ data = ((((gctUINT32) (data)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 22:22) - (0 ?
+ 22:22) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 22:22) - (0 ?
+ 22:22) + 1))))))) << (0 ?
+ 22:22))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ?
+ 22:22) - (0 ?
+ 22:22) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 22:22) - (0 ? 22:22) + 1))))))) << (0 ? 22:22)));
+
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
+ "DVFS Configure=0x%X",
+ data);
+
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x0010C,
+ data));
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ gcmkFOOTER();
+ return status;
+}
+#endif
+
+/*******************************************************************************
+**
+** gckHARDWARE_PrepareFunctions
+**
+** Generate command buffer snippets which will be used by gckHARDWARE, by which
+** gckHARDWARE can manipulate GPU by FE command without using gckCOMMAND to avoid
+** race condition and deadlock.
+**
+** Notice:
+** 1. Each snippet can only be executed when GPU is idle.
+** 2. Execution is triggered by AHB (0x658)
+** 3. Each snippet followed by END so software can sync with GPU by checking GPU
+** idle
+** 4. It is transparent to gckCOMMAND command buffer.
+**
+** Existing Snippets:
+** 1. MMU Configure
+** For new MMU, after GPU is reset, FE execute this command sequence to enable MMU.
+*/
+gceSTATUS
+gckHARDWARE_PrepareFunctions(
+ gckHARDWARE Hardware
+ )
+{
+ gckOS os;
+ gceSTATUS status;
+ gctUINT32 offset = 0;
+ gctUINT32 endBytes;
+ gctUINT32 flushBytes;
+ gctUINT8_PTR logical;
+ gctUINT32 address;
+ gcsHARDWARE_FUNCTION *function;
+ gceDUMMY_DRAW_TYPE dummyDrawType = gcvDUMMY_DRAW_INVALID;
+
+ gcmkHEADER_ARG("%x", Hardware);
+
+ os = Hardware->os;
+
+ gcmkVERIFY_OK(gckOS_GetPageSize(os, &Hardware->mmuFuncBytes));
+ Hardware->auxFuncBytes = Hardware->mmuFuncBytes;
+
+ gcmkONERROR(gckHARDWARE_End(
+ Hardware,
+ gcvNULL,
+ ~0U,
+ &endBytes
+ ));
+
+ if ((Hardware->mmuVersion > 0) &&
+ Hardware->options.enableMMU &&
+ (Hardware->options.secureMode != gcvSECURE_IN_TA))
+ {
+ gctUINT32 mmuBytes;
+ gctPHYS_ADDR_T physical = 0;
+ gctUINT32 flags = gcvALLOC_FLAG_CONTIGUOUS;
+
+#if defined(CONFIG_ZONE_DMA32)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)
+ flags |= gcvALLOC_FLAG_4GB_ADDR;
+#endif
+#endif
+
+#if gcdENABLE_CACHEABLE_COMMAND_BUFFER
+ flags |= gcvALLOC_FLAG_CACHEABLE;
+#endif
+
+ /* Allocate mmu command buffer within 32bit space */
+ gcmkONERROR(gckOS_AllocateNonPagedMemory(
+ os,
+ gcvFALSE,
+ flags,
+ &Hardware->mmuFuncBytes,
+ &Hardware->mmuFuncPhysical,
+ &Hardware->mmuFuncLogical
+ ));
+
+ gcmkONERROR(gckOS_GetPhysicalAddress(
+ os,
+ Hardware->mmuFuncLogical,
+ &physical
+ ));
+
+ gcmkVERIFY_OK(gckOS_CPUPhysicalToGPUPhysical(
+ os,
+ physical,
+ &physical
+ ));
+
+ if (!(flags & gcvALLOC_FLAG_4GB_ADDR) && (physical & 0xFFFFFFFF00000000ULL))
+ {
+ gcmkFATAL("%s(%d): Command buffer physical address (0x%llx) for MMU setup exceeds 32bits, "
+ "please rebuild kernel with CONFIG_ZONE_DMA32=y.",
+ __FUNCTION__, __LINE__, physical);
+ }
+
+ function = &Hardware->functions[gcvHARDWARE_FUNCTION_MMU];
+ function->logical = (gctUINT8_PTR)Hardware->mmuFuncLogical;
+ gcmkSAFECASTPHYSADDRT(function->address, physical);
+
+ gcmkONERROR(gckHARDWARE_SetMMUStates(
+ Hardware,
+ Hardware->kernel->mmu->mtlbLogical,
+ gcvMMU_MODE_4K,
+ Hardware->kernel->mmu->safePageLogical,
+ function->logical,
+ &mmuBytes
+ ));
+
+ function->endAddress = function->address + mmuBytes;
+ function->endLogical = function->logical + mmuBytes;
+
+ gcmkONERROR(gckHARDWARE_End(
+ Hardware,
+ function->endLogical,
+ function->endAddress,
+ &endBytes
+ ));
+
+ function->bytes = mmuBytes + endBytes;
+
+ gcmkONERROR(gckOS_CacheClean(
+ Hardware->os,
+ 0,
+ Hardware->mmuFuncPhysical,
+ 0,
+ Hardware->mmuFuncLogical,
+ function->bytes
+ ));
+ }
+
+#if USE_KERNEL_VIRTUAL_BUFFERS
+ if (Hardware->kernel->virtualCommandBuffer)
+ {
+ gckVIRTUAL_COMMAND_BUFFER_PTR commandBuffer = gcvNULL;
+ gcmkONERROR(gckKERNEL_AllocateVirtualCommandBuffer(
+ Hardware->kernel,
+ gcvFALSE,
+ &Hardware->auxFuncBytes,
+ &Hardware->auxFuncPhysical,
+ &Hardware->auxFuncLogical
+ ));
+
+ gcmkONERROR(gckKERNEL_GetGPUAddress(
+ Hardware->kernel,
+ Hardware->auxFuncLogical,
+ gcvFALSE,
+ Hardware->auxFuncPhysical,
+ &Hardware->auxFuncAddress
+ ));
+
+ commandBuffer = (gckVIRTUAL_COMMAND_BUFFER_PTR) Hardware->auxFuncPhysical;
+
+ Hardware->auxPhysHandle = commandBuffer->virtualBuffer.physical;
+ }
+ else
+#endif
+ {
+ gctPHYS_ADDR_T physical = 0;
+ gctUINT32 allocFlag = gcvALLOC_FLAG_CONTIGUOUS;
+
+#if gcdENABLE_CACHEABLE_COMMAND_BUFFER
+ allocFlag |= gcvALLOC_FLAG_CACHEABLE;
+#endif
+
+ /* Allocate a command buffer. */
+ gcmkONERROR(gckOS_AllocateNonPagedMemory(
+ os,
+ gcvFALSE,
+ allocFlag,
+ &Hardware->auxFuncBytes,
+ &Hardware->auxFuncPhysical,
+ &Hardware->auxFuncLogical
+ ));
+
+ gcmkONERROR(gckOS_GetPhysicalAddress(
+ os,
+ Hardware->auxFuncLogical,
+ &physical
+ ));
+
+ gcmkVERIFY_OK(gckOS_CPUPhysicalToGPUPhysical(
+ os,
+ physical,
+ &physical
+ ));
+
+ gcmkSAFECASTPHYSADDRT(Hardware->auxFuncAddress, physical);
+
+ gcmkONERROR(gckMMU_FillFlatMapping(
+ Hardware->kernel->mmu,
+ Hardware->auxFuncAddress,
+ Hardware->auxFuncBytes
+ ));
+
+ Hardware->auxPhysHandle = Hardware->auxFuncPhysical;
+ }
+
+ /*
+ ** All cache flush command sequence.
+ */
+ function = &Hardware->functions[gcvHARDWARE_FUNCTION_FLUSH];
+
+ function->logical = logical = (gctUINT8_PTR)Hardware->auxFuncLogical + offset;
+
+ function->address = Hardware->auxFuncAddress + offset;
+
+ /* Get the size of the flush command. */
+ gcmkONERROR(gckHARDWARE_Flush(Hardware, gcvFLUSH_ALL, gcvNULL, &flushBytes));
+
+ /* Append a flush. */
+ gcmkONERROR(gckHARDWARE_Flush(Hardware, gcvFLUSH_ALL, logical, &flushBytes));
+
+ offset += flushBytes;
+
+ logical = (gctUINT8_PTR)Hardware->auxFuncLogical + offset;
+ address = Hardware->auxFuncAddress + offset;
+
+ gcmkONERROR(gckHARDWARE_End(Hardware, logical, address, &endBytes));
+
+#if USE_KERNEL_VIRTUAL_BUFFERS
+ if (Hardware->kernel->virtualCommandBuffer)
+ {
+ gcmkONERROR(gckKERNEL_GetGPUAddress(
+ Hardware->kernel,
+ logical,
+ gcvFALSE,
+ Hardware->auxFuncPhysical,
+ &Hardware->lastEnd
+ ));
+ }
+#endif
+
+ offset += endBytes;
+
+ function->bytes = flushBytes + endBytes;
+
+ function->endAddress = function->address + flushBytes;
+ function->endLogical = function->logical + flushBytes;
+
+ /*
+ ** ASYNC-BLT Engine event command
+ */
+ if (gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_ASYNC_BLIT))
+ {
+ gctUINT8 i;
+ gctUINT32 eventBytes;
+
+ function = &Hardware->functions[gcvHARDWARE_FUNCTION_BLT_EVENT];
+
+ function->logical = logical = (gctUINT8_PTR)Hardware->auxFuncLogical + offset;
+ function->address = Hardware->auxFuncAddress + offset;
+
+ gcmkONERROR(gckHARDWARE_Event(Hardware, gcvNULL, 0, gcvKERNEL_BLT, &eventBytes));
+
+ for (i = 0; i < 29; i++)
+ {
+ gcmkONERROR(gckHARDWARE_Event(
+ Hardware,
+ logical + i * eventBytes,
+ i,
+ gcvKERNEL_BLT,
+ &eventBytes
+ ));
+
+ offset += eventBytes;
+ }
+
+ function->bytes = eventBytes * 29;
+ }
+
+
+ /************************************************************************************
+ * Dummy draw.
+ */
+ if (gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_FE_NEED_DUMMYDRAW))
+ {
+ dummyDrawType = gcvDUMMY_DRAW_GC400;
+ }
+
+ if (!gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_USC_DEFER_FILL_FIX) &&
+ gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_USC))
+ {
+ dummyDrawType = gcvDUMMY_DRAW_V60;
+ }
+
+ if (dummyDrawType != gcvDUMMY_DRAW_INVALID)
+ {
+ gctUINT32 dummyDrawBytes;
+
+ function = &Hardware->functions[gcvHARDWARE_FUNCTION_DUMMY_DRAW];
+
+ function->logical = logical = (gctUINT8_PTR)Hardware->auxFuncLogical + offset;
+ function->address = Hardware->auxFuncAddress + offset;
+
+ /* Append a dummy draw. */
+ gcmkONERROR(gckHARDWARE_DummyDraw(Hardware, logical, function->address, dummyDrawType, &dummyDrawBytes));
+
+ offset += dummyDrawBytes;
+
+ logical += dummyDrawBytes;
+ address = function->address + dummyDrawBytes;
+
+ gcmkONERROR(gckHARDWARE_End(Hardware, logical, address, &endBytes));
+
+ offset += endBytes;
+
+ function->endAddress = function->address + dummyDrawBytes;
+ function->endLogical = function->logical + dummyDrawBytes;
+
+ function->bytes = dummyDrawBytes + endBytes;
+ }
+ gcmkASSERT(offset < Hardware->auxFuncBytes);
+
+ gcmkONERROR(gckOS_CacheClean(
+ Hardware->os,
+ 0,
+ Hardware->auxPhysHandle,
+ 0,
+ Hardware->auxFuncLogical,
+ Hardware->auxFuncBytes
+ ));
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ gcmkFOOTER();
+ return status;
+}
+
+gceSTATUS
+gckHARDWARE_DestroyFunctions(
+ gckHARDWARE Hardware
+ )
+{
+ gcmkHEADER_ARG("%x", Hardware);
+
+ if (Hardware->auxFuncPhysical)
+ {
+#if USE_KERNEL_VIRTUAL_BUFFERS
+ if (Hardware->kernel->virtualCommandBuffer)
+ {
+ gcmkVERIFY_OK(gckKERNEL_FreeVirtualMemory(
+ Hardware->auxFuncPhysical,
+ Hardware->auxFuncLogical,
+ gcvFALSE
+ ));
+ }
+ else
+#endif
+ {
+ gcmkVERIFY_OK(gckOS_FreeNonPagedMemory(
+ Hardware->os,
+ Hardware->auxFuncBytes,
+ Hardware->auxFuncPhysical,
+ Hardware->auxFuncLogical
+ ));
+ }
+ }
+
+ if (Hardware->mmuFuncPhysical)
+ {
+ gcmkVERIFY_OK(gckOS_FreeNonPagedMemory(
+ Hardware->os,
+ Hardware->mmuFuncBytes,
+ Hardware->mmuFuncPhysical,
+ Hardware->mmuFuncLogical
+ ));
+ }
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+}
+
+gceSTATUS
+gckHARDWARE_ExecuteFunctions(
+ IN gckHARDWARE Hardware,
+ IN gceHARDWARE_FUNCTION Function
+ )
+{
+ gceSTATUS status;
+ gctUINT32 idle;
+ gctUINT32 timer = 0, delay = 1;
+ gcsHARDWARE_FUNCTION * function = &Hardware->functions[Function];
+ gctUINT32 address;
+
+#if USE_KERNEL_VIRTUAL_BUFFERS
+ if (Hardware->kernel->virtualCommandBuffer)
+ {
+ address = function->address;
+ }
+ else
+#endif
+ {
+ address = function->address - Hardware->baseAddress;
+ }
+
+ /* Execute prepared command sequence. */
+ gcmkONERROR(gckHARDWARE_Execute(
+ Hardware,
+ address,
+ function->bytes
+ ));
+
+#if gcdLINK_QUEUE_SIZE
+ {
+ gcuQUEUEDATA data;
+
+ gcmkVERIFY_OK(gckOS_GetProcessID(&data.linkData.pid));
+
+ data.linkData.start = address;
+ data.linkData.end = address + function->bytes;
+ data.linkData.linkLow = 0;
+ data.linkData.linkHigh = 0;
+
+ gckQUEUE_Enqueue(&Hardware->linkQueue, &data);
+ }
+#endif
+
+ gcmkDUMPCOMMAND(
+ Hardware->os,
+ function->logical,
+ function->bytes,
+ gcvDUMP_BUFFER_KERNEL,
+ gcvTRUE
+ );
+
+#if gcdDUMP_COMMAND
+ gcmkPRINT("@[kernel.execute]");
+#endif
+
+ /* Wait until GPU idle. */
+ do
+ {
+ gckOS_Delay(Hardware->os, delay);
+
+ gcmkONERROR(gckOS_ReadRegisterEx(
+ Hardware->os,
+ Hardware->core,
+ 0x00004,
+ &idle));
+
+ timer += delay;
+ delay *= 2;
+
+#if gcdGPU_TIMEOUT
+ if (timer >= Hardware->kernel->timeOut)
+ {
+ gckHARDWARE_DumpGPUState(Hardware);
+ gckCOMMAND_DumpExecutingBuffer(Hardware->kernel->command);
+
+ /* Even if hardware is not reset correctly, let software
+ ** continue to avoid software stuck. Software will timeout again
+ ** and try to recover GPU in next timeout.
+ */
+ gcmkONERROR(gcvSTATUS_DEVICE);
+ }
+#endif
+ }
+ while (!_IsGPUIdle(idle));
+
+ return gcvSTATUS_OK;
+
+OnError:
+ return status;
+}
+
+gceSTATUS
+gckHARDWARE_AddressInHardwareFuncions(
+ IN gckHARDWARE Hardware,
+ IN gctUINT32 Address,
+ OUT gctPOINTER *Pointer
+ )
+{
+ if (Address >= Hardware->auxFuncAddress && Address <= Hardware->auxFuncAddress - 1 + Hardware->auxFuncBytes)
+ {
+ *Pointer = (gctUINT8_PTR)Hardware->auxFuncLogical
+ + (Address - Hardware->auxFuncAddress)
+ ;
+
+ return gcvSTATUS_OK;
+ }
+
+ return gcvSTATUS_NOT_FOUND;
+}
+
+gceSTATUS
+gckHARDWARE_QueryStateTimer(
+ IN gckHARDWARE Hardware,
+ OUT gctUINT64_PTR Start,
+ OUT gctUINT64_PTR End,
+ OUT gctUINT64_PTR On,
+ OUT gctUINT64_PTR Off,
+ OUT gctUINT64_PTR Idle,
+ OUT gctUINT64_PTR Suspend
+ )
+{
+ gckOS_AcquireMutex(Hardware->os, Hardware->powerMutex, gcvINFINITE);
+
+ gckSTATETIMER_Query(
+ &Hardware->powerStateTimer, Hardware->chipPowerState, Start, End, On, Off, Idle, Suspend);
+
+ gckOS_ReleaseMutex(Hardware->os, Hardware->powerMutex);
+
+ return gcvSTATUS_OK;
+}
+
+gceSTATUS
+gckHARDWARE_WaitFence(
+ IN gckHARDWARE Hardware,
+ IN gctPOINTER Logical,
+ IN gctUINT64 FenceData,
+ IN gctUINT32 FenceAddress,
+ OUT gctUINT32 *Bytes
+ )
+{
+ gctUINT32_PTR logical = (gctUINT32_PTR)Logical;
+
+ gctUINT32 dataLow = (gctUINT32)FenceData;
+ gctUINT32 dataHigh = (gctUINT32)(FenceData >> 32);
+
+ if (logical)
+ {
+ *logical++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x01FD) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
+
+ *logical++
+ = dataHigh;
+
+ *logical++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x01FA) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
+
+ *logical++
+ = dataLow;
+
+ *logical++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x0F & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (Hardware->waitCount) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 17:16) - (0 ?
+ 17:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 17:16) - (0 ?
+ 17:16) + 1))))))) << (0 ?
+ 17:16))) | (((gctUINT32) (0x2 & ((gctUINT32) ((((1 ?
+ 17:16) - (0 ?
+ 17:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 17:16) - (0 ? 17:16) + 1))))))) << (0 ? 17:16)));
+
+ *logical++
+ = FenceAddress;
+ }
+ else
+ {
+ *Bytes = 6 * gcmSIZEOF(gctUINT32);
+ }
+
+ return gcvSTATUS_OK;
+}
+
+gceSTATUS
+gckHARDWARE_UpdateContextID(
+ IN gckHARDWARE Hardware
+ )
+{
+ static gcsiDEBUG_REGISTERS fe = { "FE", 0x470, 0, 0x450, 256, 0x1, 0x00 };
+ gckOS os = Hardware->os;
+ gceCORE core = Hardware->core;
+ gctUINT32 contextIDLow, contextIDHigh;
+ gceSTATUS status;
+
+ gcmkONERROR(gckOS_WriteRegisterEx(os, core, fe.index, 0x53 << fe.shift));
+ gcmkONERROR(gckOS_ReadRegisterEx(os, core, fe.data, &contextIDLow));
+
+ gcmkONERROR(gckOS_WriteRegisterEx(os, core, fe.index, 0x54 << fe.shift));
+ gcmkONERROR(gckOS_ReadRegisterEx(os, core, fe.data, &contextIDHigh));
+
+ Hardware->contextID = ((gctUINT64)contextIDHigh << 32) + contextIDLow;
+
+ return gcvSTATUS_OK;
+
+OnError:
+ return status;
+}
+
+gceSTATUS
+gckFE_Initialize(
+ IN gckHARDWARE Hardware,
+ OUT gckFE FE
+ )
+{
+ gceSTATUS status;
+ gctUINT32 data;
+
+ gcmkHEADER();
+
+ gckOS_ZeroMemory(FE, gcmSIZEOF(gcsFE));
+
+ gcmkVERIFY_OK(gckOS_ReadRegisterEx(
+ Hardware->os,
+ Hardware->core,
+ 0x007E4,
+ &data
+ ));
+
+ gcmkONERROR(gckOS_AtomConstruct(Hardware->os, &FE->freeDscriptors));
+
+ data = (((((gctUINT32) (data)) >> (0 ? 6:0)) & ((gctUINT32) ((((1 ? 6:0) - (0 ? 6:0) + 1) == 32) ? ~0U : (~(~0U << ((1 ? 6:0) - (0 ? 6:0) + 1)))))) );
+
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, _GC_OBJ_ZONE, "free descriptor=%d", data);
+
+ gcmkONERROR(gckOS_AtomSet(Hardware->os, FE->freeDscriptors, data));
+
+ /* Enable interrupts. */
+ gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x000D8, ~0U);
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+
+ if (FE->freeDscriptors)
+ {
+ gckOS_AtomDestroy(Hardware->os, FE->freeDscriptors);
+ }
+
+ gcmkFOOTER();
+ return status;
+}
+
+void
+gckFE_UpdateAvaiable(
+ IN gckHARDWARE Hardware,
+ OUT gckFE FE
+ )
+{
+ gceSTATUS status;
+ gctUINT32 data;
+ gctINT32 oldValue;
+
+ status = gckOS_ReadRegisterEx(
+ Hardware->os,
+ Hardware->core,
+ 0x007E4,
+ &data
+ );
+
+ if (gcmIS_SUCCESS(status))
+ {
+ data = (((((gctUINT32) (data)) >> (0 ? 6:0)) & ((gctUINT32) ((((1 ? 6:0) - (0 ? 6:0) + 1) == 32) ? ~0U : (~(~0U << ((1 ? 6:0) - (0 ? 6:0) + 1)))))) );
+
+ while (data--)
+ {
+ gckOS_AtomIncrement(Hardware->os, FE->freeDscriptors, &oldValue);
+ }
+ }
+}
+
+gceSTATUS
+gckFE_ReserveSlot(
+ IN gckHARDWARE Hardware,
+ IN gckFE FE,
+ OUT gctBOOL * Available
+ )
+{
+ gctINT32 oldValue;
+
+ gckOS_AtomDecrement(Hardware->os, FE->freeDscriptors, &oldValue);
+
+ if (oldValue > 0)
+ {
+ /* Get one slot. */
+ *Available = gcvTRUE;
+ }
+ else
+ {
+ /* No available slot, restore decreased one.*/
+ gckOS_AtomIncrement(Hardware->os, FE->freeDscriptors, &oldValue);
+ *Available = gcvFALSE;
+ }
+
+ return gcvSTATUS_OK;
+}
+
+void
+gckFE_Execute(
+ IN gckHARDWARE Hardware,
+ IN gckFE FE,
+ IN gcsFEDescriptor * Desc
+ )
+{
+ gckOS_WriteRegisterEx(
+ Hardware->os,
+ Hardware->core,
+ 0x007DC,
+ Desc->start
+ );
+
+ gckOS_MemoryBarrier(
+ Hardware->os,
+ gcvNULL
+ );
+
+ gckOS_WriteRegisterEx(
+ Hardware->os,
+ Hardware->core,
+ 0x007E0,
+ Desc->end
+ );
+}
+
+gceSTATUS
+gckHARDWARE_DummyDraw(
+ IN gckHARDWARE Hardware,
+ IN gctPOINTER Logical,
+ IN gctUINT32 Address,
+ IN gceDUMMY_DRAW_TYPE DummyDrawType,
+ IN OUT gctUINT32 * Bytes
+ )
+{
+ gctUINT32 dummyDraw_gc400[] = {
+
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x0193) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))),
+ 0x000000,
+
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x0194) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))),
+ 0,
+
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x0180) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))),
+
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 3:0) - (0 ?
+ 3:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 3:0) - (0 ?
+ 3:0) + 1))))))) << (0 ?
+ 3:0))) | (((gctUINT32) (0x8 & ((gctUINT32) ((((1 ?
+ 3:0) - (0 ?
+ 3:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 3:0) - (0 ? 3:0) + 1))))))) << (0 ? 3:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 13:12) - (0 ?
+ 13:12) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 13:12) - (0 ?
+ 13:12) + 1))))))) << (0 ?
+ 13:12))) | (((gctUINT32) ((gctUINT32) (4) & ((gctUINT32) ((((1 ?
+ 13:12) - (0 ?
+ 13:12) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 13:12) - (0 ? 13:12) + 1))))))) << (0 ? 13:12)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 23:16) - (0 ?
+ 23:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 23:16) - (0 ?
+ 23:16) + 1))))))) << (0 ?
+ 23:16))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ?
+ 23:16) - (0 ?
+ 23:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:24) - (0 ?
+ 31:24) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:24) - (0 ?
+ 31:24) + 1))))))) << (0 ?
+ 31:24))) | (((gctUINT32) ((gctUINT32) (4 * gcmSIZEOF(float)) & ((gctUINT32) ((((1 ?
+ 31:24) - (0 ?
+ 31:24) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 7:7) - (0 ?
+ 7:7) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 7:7) - (0 ?
+ 7:7) + 1))))))) << (0 ?
+ 7:7))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 7:7) - (0 ?
+ 7:7) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 7:7) - (0 ? 7:7) + 1))))))) << (0 ? 7:7))),
+
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E05) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))),
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 1:0) - (0 ?
+ 1:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 1:0) - (0 ?
+ 1:0) + 1))))))) << (0 ?
+ 1:0))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 1:0) - (0 ?
+ 1:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 1:0) - (0 ? 1:0) + 1))))))) << (0 ? 1:0))),
+
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x0202) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))),
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 5:0) - (0 ?
+ 5:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 5:0) - (0 ?
+ 5:0) + 1))))))) << (0 ?
+ 5:0))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 5:0) - (0 ?
+ 5:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 5:0) - (0 ? 5:0) + 1))))))) << (0 ? 5:0))),
+
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x0208) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))),
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 5:0) - (0 ?
+ 5:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 5:0) - (0 ?
+ 5:0) + 1))))))) << (0 ?
+ 5:0))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ?
+ 5:0) - (0 ?
+ 5:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 5:0) - (0 ? 5:0) + 1))))))) << (0 ? 5:0))),
+
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x0201) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))),
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 5:0) - (0 ?
+ 5:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 5:0) - (0 ?
+ 5:0) + 1))))))) << (0 ?
+ 5:0))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 5:0) - (0 ?
+ 5:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 5:0) - (0 ? 5:0) + 1))))))) << (0 ? 5:0))),
+
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x0204) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))),
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 5:0) - (0 ?
+ 5:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 5:0) - (0 ?
+ 5:0) + 1))))))) << (0 ?
+ 5:0))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ?
+ 5:0) - (0 ?
+ 5:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 5:0) - (0 ? 5:0) + 1))))))) << (0 ? 5:0))),
+
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x1000) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (4) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))),
+ 0x0, 0x0, 0x0, 0x0,
+ 0xDEADDEAD,
+
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x0203) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))),
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 6:0) - (0 ?
+ 6:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 6:0) - (0 ?
+ 6:0) + 1))))))) << (0 ?
+ 6:0))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 6:0) - (0 ?
+ 6:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 6:0) - (0 ? 6:0) + 1))))))) << (0 ? 6:0))),
+
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x020E) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))),
+ 0,
+
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x0200) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))),
+ 1,
+
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x020C) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))),
+ 0x000F003F,
+
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x028C) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))),
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 11:8) - (0 ?
+ 11:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 11:8) - (0 ?
+ 11:8) + 1))))))) << (0 ?
+ 11:8))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 11:8) - (0 ?
+ 11:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 11:8) - (0 ? 11:8) + 1))))))) << (0 ? 11:8))),
+
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x0500) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))),
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 1:0) - (0 ?
+ 1:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 1:0) - (0 ?
+ 1:0) + 1))))))) << (0 ?
+ 1:0))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ?
+ 1:0) - (0 ?
+ 1:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 1:0) - (0 ? 1:0) + 1))))))) << (0 ? 1:0))),
+
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x028D) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))),
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 13:12) - (0 ?
+ 13:12) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 13:12) - (0 ?
+ 13:12) + 1))))))) << (0 ?
+ 13:12))) | (((gctUINT32) (0x2 & ((gctUINT32) ((((1 ?
+ 13:12) - (0 ?
+ 13:12) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 13:12) - (0 ? 13:12) + 1))))))) << (0 ? 13:12)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 9:8) - (0 ?
+ 9:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 9:8) - (0 ?
+ 9:8) + 1))))))) << (0 ?
+ 9:8))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ?
+ 9:8) - (0 ?
+ 9:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 9:8) - (0 ? 9:8) + 1))))))) << (0 ? 9:8)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 17:16) - (0 ?
+ 17:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 17:16) - (0 ?
+ 17:16) + 1))))))) << (0 ?
+ 17:16))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 17:16) - (0 ?
+ 17:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 17:16) - (0 ? 17:16) + 1))))))) << (0 ? 17:16))),
+
+
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x0300) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))),
+ 0,
+
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x0301) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))),
+ 0,
+
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x0302) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))),
+ 0,
+
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x0303) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))),
+ 0,
+
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x0289) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))),
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 3:0) - (0 ?
+ 3:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 3:0) - (0 ?
+ 3:0) + 1))))))) << (0 ?
+ 3:0))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 3:0) - (0 ?
+ 3:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 3:0) - (0 ? 3:0) + 1))))))) << (0 ? 3:0))),
+
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x05 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))),
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 3:0) - (0 ?
+ 3:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 3:0) - (0 ?
+ 3:0) + 1))))))) << (0 ?
+ 3:0))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 3:0) - (0 ?
+ 3:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 3:0) - (0 ? 3:0) + 1))))))) << (0 ? 3:0))),
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 23:0) - (0 ?
+ 23:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 23:0) - (0 ?
+ 23:0) + 1))))))) << (0 ?
+ 23:0))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ?
+ 23:0) - (0 ?
+ 23:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 23:0) - (0 ? 23:0) + 1))))))) << (0 ? 23:0))),
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 23:0) - (0 ?
+ 23:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 23:0) - (0 ?
+ 23:0) + 1))))))) << (0 ?
+ 23:0))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 23:0) - (0 ?
+ 23:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 23:0) - (0 ? 23:0) + 1))))))) << (0 ? 23:0))),
+ };
+
+ gctUINT32 dummyDraw_v60[] = {
+
+ /* Semaphore from FE to PE. */
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E02) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))),
+
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1))))))) << (0 ?
+ 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1))))))) << (0 ?
+ 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))),
+
+ /* Stall from FE to PE. */
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x09 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))),
+
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1))))))) << (0 ?
+ 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1))))))) << (0 ?
+ 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))),
+
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x021A) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))),
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1))))))) << (0 ?
+ 0:0))) | (((gctUINT32) ((gctUINT32) (0x0) & ((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))),
+
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E06) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))),
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 1:0) - (0 ?
+ 1:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 1:0) - (0 ?
+ 1:0) + 1))))))) << (0 ?
+ 1:0))) | (((gctUINT32) ((gctUINT32) (0x0) & ((gctUINT32) ((((1 ?
+ 1:0) - (0 ?
+ 1:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 1:0) - (0 ? 1:0) + 1))))))) << (0 ? 1:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 14:12) - (0 ?
+ 14:12) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 14:12) - (0 ?
+ 14:12) + 1))))))) << (0 ?
+ 14:12))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ?
+ 14:12) - (0 ?
+ 14:12) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 14:12) - (0 ? 14:12) + 1))))))) << (0 ? 14:12)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 17:16) - (0 ?
+ 17:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 17:16) - (0 ?
+ 17:16) + 1))))))) << (0 ?
+ 17:16))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ?
+ 17:16) - (0 ?
+ 17:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 17:16) - (0 ? 17:16) + 1))))))) << (0 ? 17:16)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 7:4) - (0 ?
+ 7:4) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 7:4) - (0 ?
+ 7:4) + 1))))))) << (0 ?
+ 7:4))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ?
+ 7:4) - (0 ?
+ 7:4) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 7:4) - (0 ? 7:4) + 1))))))) << (0 ? 7:4))),
+
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x0401) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (6) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))),
+ 0x0,
+ 0x2,
+ 0x0,
+ 0x0,
+ 0x0,
+ 0x0,
+ (gctUINT32)~0x0,
+
+
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x020C) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))),
+ 0xffffffff,
+
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E07) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))),
+ 2,
+
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E08) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))),
+ 2,
+
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x0420) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))),
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 2:0) - (0 ?
+ 2:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 2:0) - (0 ?
+ 2:0) + 1))))))) << (0 ?
+ 2:0))) | (((gctUINT32) ((gctUINT32) (2) & ((gctUINT32) ((((1 ?
+ 2:0) - (0 ?
+ 2:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 2:0) - (0 ? 2:0) + 1))))))) << (0 ? 2:0))),
+
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x0424) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))),
+ 1,
+
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x0403) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))),
+ 3,
+
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E21) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))),
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 2:0) - (0 ?
+ 2:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 2:0) - (0 ?
+ 2:0) + 1))))))) << (0 ?
+ 2:0))) | (((gctUINT32) (0x2 & ((gctUINT32) ((((1 ?
+ 2:0) - (0 ?
+ 2:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 2:0) - (0 ? 2:0) + 1))))))) << (0 ? 2:0))),
+
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x040A) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))),
+ 0,
+
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x2000) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1 << 2) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))),
+ 0x07801033,0x3fc00900,0x00000040,0x00390008,
+ (gctUINT32)~0,
+
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x021F) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))),
+ 0x0,
+
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x0240) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))),
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 1:0) - (0 ?
+ 1:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 1:0) - (0 ?
+ 1:0) + 1))))))) << (0 ?
+ 1:0))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 1:0) - (0 ?
+ 1:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 1:0) - (0 ? 1:0) + 1))))))) << (0 ? 1:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 6:4) - (0 ?
+ 6:4) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 6:4) - (0 ?
+ 6:4) + 1))))))) << (0 ?
+ 6:4))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ?
+ 6:4) - (0 ?
+ 6:4) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 6:4) - (0 ? 6:4) + 1))))))) << (0 ? 6:4)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 8:8) - (0 ?
+ 8:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 8:8) - (0 ?
+ 8:8) + 1))))))) << (0 ?
+ 8:8))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ?
+ 8:8) - (0 ?
+ 8:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 8:8) - (0 ? 8:8) + 1))))))) << (0 ? 8:8)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 26:24) - (0 ?
+ 26:24) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 26:24) - (0 ?
+ 26:24) + 1))))))) << (0 ?
+ 26:24))) | (((gctUINT32) (0x3 & ((gctUINT32) ((((1 ?
+ 26:24) - (0 ?
+ 26:24) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 26:24) - (0 ? 26:24) + 1))))))) << (0 ? 26:24))),
+
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x0241) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))),
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (31) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:16) - (0 ?
+ 31:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:16) - (0 ?
+ 31:16) + 1))))))) << (0 ?
+ 31:16))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ?
+ 31:16) - (0 ?
+ 31:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:16) - (0 ? 31:16) + 1))))))) << (0 ? 31:16))),
+
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x0244) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))),
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 9:0) - (0 ?
+ 9:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 9:0) - (0 ?
+ 9:0) + 1))))))) << (0 ?
+ 9:0))) | (((gctUINT32) ((gctUINT32) (31) & ((gctUINT32) ((((1 ?
+ 9:0) - (0 ?
+ 9:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 9:0) - (0 ? 9:0) + 1))))))) << (0 ? 9:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:16) - (0 ?
+ 31:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:16) - (0 ?
+ 31:16) + 1))))))) << (0 ?
+ 31:16))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ?
+ 31:16) - (0 ?
+ 31:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:16) - (0 ? 31:16) + 1))))))) << (0 ? 31:16))),
+
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x0247) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))),
+
+ (32+(4*(((gcsFEATURE_DATABASE *)Hardware->featureDatabase)->NumShaderCores)-1))/(4*(((gcsFEATURE_DATABASE *)Hardware->featureDatabase)->NumShaderCores)),
+
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x0248) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))),
+ 1,
+
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E03) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))),
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 5:5) - (0 ?
+ 5:5) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 5:5) - (0 ?
+ 5:5) + 1))))))) << (0 ?
+ 5:5))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 5:5) - (0 ?
+ 5:5) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 5:5) - (0 ? 5:5) + 1))))))) << (0 ? 5:5))),
+
+ /* Semaphore from FE to PE. */
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E02) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))),
+
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1))))))) << (0 ?
+ 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1))))))) << (0 ?
+ 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))),
+
+ /* Stall from FE to PE. */
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x09 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))),
+
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1))))))) << (0 ?
+ 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1))))))) << (0 ?
+ 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))),
+
+ /* Invalidate I cache.*/
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x022C) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))),
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1))))))) << (0 ?
+ 0:0))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 1:1) - (0 ?
+ 1:1) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 1:1) - (0 ?
+ 1:1) + 1))))))) << (0 ?
+ 1:1))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 1:1) - (0 ?
+ 1:1) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 2:2) - (0 ?
+ 2:2) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 2:2) - (0 ?
+ 2:2) + 1))))))) << (0 ?
+ 2:2))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 2:2) - (0 ?
+ 2:2) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 2:2) - (0 ? 2:2) + 1))))))) << (0 ? 2:2)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 3:3) - (0 ?
+ 3:3) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 3:3) - (0 ?
+ 3:3) + 1))))))) << (0 ?
+ 3:3))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 3:3) - (0 ?
+ 3:3) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 3:3) - (0 ? 3:3) + 1))))))) << (0 ? 3:3)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 4:4) - (0 ?
+ 4:4) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 4:4) - (0 ?
+ 4:4) + 1))))))) << (0 ?
+ 4:4))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 4:4) - (0 ?
+ 4:4) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 4:4) - (0 ? 4:4) + 1))))))) << (0 ? 4:4))),
+ };
+
+ gctUINT32 bytes = 0;
+ gctUINT32_PTR dummyDraw = gcvNULL;
+
+
+ switch(DummyDrawType)
+ {
+ case gcvDUMMY_DRAW_GC400:
+ dummyDraw = dummyDraw_gc400;
+ bytes = gcmSIZEOF(dummyDraw_gc400);
+ *(dummyDraw + 1) = Address;
+ break;
+ case gcvDUMMY_DRAW_V60:
+ dummyDraw = dummyDraw_v60;
+ bytes = gcmSIZEOF(dummyDraw_v60);
+ break;
+ default:
+ /* other chip no need dummy draw.*/
+ gcmkASSERT(0);
+ break;
+ };
+
+ if (Logical != gcvNULL)
+ {
+ gckOS_MemCopy(Logical, dummyDraw, bytes);
+ }
+
+ *Bytes = bytes;
+
+ return gcvSTATUS_OK;
+}
+
+gceSTATUS
+gckHARDWARE_EnterQueryClock(
+ IN gckHARDWARE Hardware,
+ OUT gctUINT64 *McStart,
+ OUT gctUINT64 *ShStart
+ )
+{
+ gceSTATUS status = gcvSTATUS_OK;
+ gctUINT64 mcStart, shStart;
+
+ gcmkONERROR(gckOS_GetTime(&mcStart));
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00438, 0));
+
+ *McStart = mcStart;
+
+ if (Hardware->core <= gcvCORE_3D_MAX)
+ {
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470, 0xFFU << 24));
+
+ gcmkONERROR(gckOS_GetTime(&shStart));
+
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470, 0x4U << 24));
+
+ *ShStart = shStart;
+ }
+
+OnError:
+ return status;
+}
+
+gceSTATUS
+gckHARDWARE_ExitQueryClock(
+ IN gckHARDWARE Hardware,
+ IN gctUINT64 McStart,
+ IN gctUINT64 ShStart,
+ OUT gctUINT32 *McClk,
+ OUT gctUINT32 *ShClk
+ )
+{
+ gceSTATUS status = gcvSTATUS_OK;
+ gctUINT64 mcEnd, shEnd;
+ gctUINT32 mcCycle, shCycle;
+ gctUINT64 mcFreq, shFreq = 0;
+
+ gcmkONERROR(gckOS_GetTime(&mcEnd));
+ gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00438, &mcCycle));
+
+ if (mcCycle == 0)
+ {
+ gcmkONERROR(gcvSTATUS_GENERIC_IO);
+ }
+
+ /* cycle = (gctUINT64)cycle * 1000000 / (end - start); */
+ mcFreq = ((gctUINT64)mcCycle * ((1000000U << 12) / (gctUINT32)(mcEnd - McStart))) >> 12;
+
+ *McClk = (gctUINT32)mcFreq;
+
+ if (Hardware->core <= gcvCORE_3D_MAX)
+ {
+ gcmkONERROR(gckOS_GetTime(&shEnd));
+ gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0045C, &shCycle));
+
+ if (!shCycle)
+ {
+ /*TODO: [VIV] Query SH cycle not support for old chips */
+ *ShClk = *McClk;
+ return gcvSTATUS_OK;
+ }
+
+ if (!ShStart)
+ {
+ gcmkONERROR(gcvSTATUS_GENERIC_IO);
+ }
+
+ shFreq = ((gctUINT64)shCycle * ((1000000U << 12) / (gctUINT32)(shEnd - ShStart))) >> 12;
+ }
+
+ *ShClk = (gctUINT32)shFreq;
+
+OnError:
+ return status;
+}
+
+/*******************************************************************************
+**
+** gckHARDWARE_QueryFrequency
+**
+** Query current hardware frequency.
+**
+** INPUT:
+**
+** gckHARDWARE Hardware
+** Pointer to an gckHARDWARE object.
+**
+*/
+gceSTATUS
+gckHARDWARE_QueryFrequency(
+ IN gckHARDWARE Hardware
+ )
+{
+ gctUINT64 mcStart, shStart;
+ gctUINT32 mcClk, shClk;
+ gceSTATUS status;
+ gctUINT32 powerManagement = 0;
+ gctBOOL globalAcquired = gcvFALSE;
+ gceCHIPPOWERSTATE statesStored, state;
+
+ gcmkHEADER_ARG("Hardware=0x%p", Hardware);
+
+ gcmkVERIFY_ARGUMENT(Hardware != NULL);
+
+ mcStart = shStart = 0;
+ mcClk = shClk = 0;
+
+ gckOS_QueryOption(Hardware->os, "powerManagement", &powerManagement);
+
+ if (powerManagement)
+ {
+ gcmkONERROR(gckHARDWARE_SetPowerManagement(
+ Hardware, gcvFALSE
+ ));
+ }
+
+ gcmkONERROR(gckHARDWARE_QueryPowerManagementState(
+ Hardware, &statesStored
+ ));
+
+ gcmkONERROR(gckHARDWARE_SetPowerManagementState(
+ Hardware, gcvPOWER_ON_AUTO
+ ));
+
+ /* Grab the global semaphore. */
+ gcmkONERROR(gckOS_AcquireSemaphore(
+ Hardware->os, Hardware->globalSemaphore
+ ));
+
+ globalAcquired = gcvTRUE;
+
+ gckHARDWARE_EnterQueryClock(Hardware, &mcStart, &shStart);
+
+ gcmkONERROR(gckOS_Delay(Hardware->os, 50));
+
+ if (mcStart)
+ {
+ gckHARDWARE_ExitQueryClock(Hardware,
+ mcStart, shStart,
+ &mcClk, &shClk);
+
+ Hardware->mcClk = mcClk;
+ Hardware->shClk = shClk;
+ }
+
+ /* Release the global semaphore. */
+ gcmkONERROR(gckOS_ReleaseSemaphore(
+ Hardware->os, Hardware->globalSemaphore
+ ));
+
+ globalAcquired = gcvFALSE;
+
+ switch(statesStored)
+ {
+ case gcvPOWER_OFF:
+ state = gcvPOWER_OFF_BROADCAST;
+ break;
+ case gcvPOWER_IDLE:
+ state = gcvPOWER_IDLE_BROADCAST;
+ break;
+ case gcvPOWER_SUSPEND:
+ state = gcvPOWER_SUSPEND_BROADCAST;
+ break;
+ case gcvPOWER_ON:
+ state = gcvPOWER_ON_AUTO;
+ break;
+ default:
+ state = statesStored;
+ break;
+ }
+
+ if (powerManagement)
+ {
+ gcmkONERROR(gckHARDWARE_SetPowerManagement(
+ Hardware, gcvTRUE
+ ));
+ }
+
+ gcmkONERROR(gckHARDWARE_SetPowerManagementState(
+ Hardware, state
+ ));
+
+ gcmkFOOTER_NO();
+
+ return gcvSTATUS_OK;
+
+OnError:
+ if (globalAcquired)
+ {
+ /* Release the global semaphore. */
+ gcmkVERIFY_OK(gckOS_ReleaseSemaphore(
+ Hardware->os, Hardware->globalSemaphore
+ ));
+ }
+
+ gcmkFOOTER();
+
+ return status;
+}
+
+
diff --git a/drivers/mxc/gpu-viv/hal/kernel/arch/gc_hal_kernel_hardware.h b/drivers/mxc/gpu-viv/hal/kernel/arch/gc_hal_kernel_hardware.h
new file mode 100644
index 000000000000..5c08acef3fe1
--- /dev/null
+++ b/drivers/mxc/gpu-viv/hal/kernel/arch/gc_hal_kernel_hardware.h
@@ -0,0 +1,376 @@
+/****************************************************************************
+*
+* The MIT License (MIT)
+*
+* Copyright (c) 2014 - 2018 Vivante 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 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 GPL License (GPL)
+*
+* Copyright (C) 2014 - 2018 Vivante 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.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+*****************************************************************************
+*
+* Note: This software is released under dual MIT and GPL licenses. A
+* recipient may use this file under the terms of either the MIT license or
+* GPL License. If you wish to use only one license not the other, you can
+* indicate your decision by deleting one of the above license notices in your
+* version of this file.
+*
+*****************************************************************************/
+
+
+#ifndef __gc_hal_kernel_hardware_h_
+#define __gc_hal_kernel_hardware_h_
+
+#if gcdENABLE_VG
+#include "gc_hal_kernel_hardware_vg.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum {
+ gcvHARDWARE_FUNCTION_MMU,
+ gcvHARDWARE_FUNCTION_FLUSH,
+
+ /* BLT engine command sequence. */
+ gcvHARDWARE_FUNCTION_BLT_EVENT,
+ gcvHARDWARE_FUNCTION_DUMMY_DRAW,
+ gcvHARDWARE_FUNCTION_NUM,
+}
+gceHARDWARE_FUNCTION;
+
+
+typedef struct _gcsHARWARE_FUNCTION
+{
+ /* Entry of the function. */
+ gctUINT32 address;
+
+ /* CPU address of the function. */
+ gctUINT8_PTR logical;
+
+ /* Bytes of the function. */
+ gctUINT32 bytes;
+
+ /* Hardware address of END in this function. */
+ gctUINT32 endAddress;
+
+ /* Logical of END in this function. */
+ gctUINT8_PTR endLogical;
+}
+gcsHARDWARE_FUNCTION;
+
+typedef struct _gcsSTATETIMER
+{
+ gctUINT64 start;
+ gctUINT64 recent;
+
+ /* Elapse of each power state. */
+ gctUINT64 elapse[4];
+}
+gcsSTATETIMER;
+
+typedef struct _gcsHARDWARE_SIGNATURE
+{
+ /* Chip model. */
+ gceCHIPMODEL chipModel;
+
+ /* Revision value.*/
+ gctUINT32 chipRevision;
+
+ /* Supported feature fields. */
+ gctUINT32 chipFeatures;
+
+ /* Supported minor feature fields. */
+ gctUINT32 chipMinorFeatures;
+
+ /* Supported minor feature 1 fields. */
+ gctUINT32 chipMinorFeatures1;
+
+ /* Supported minor feature 2 fields. */
+ gctUINT32 chipMinorFeatures2;
+}
+gcsHARDWARE_SIGNATURE;
+
+typedef struct _gcsMMU_TABLE_ARRAY_ENTRY
+{
+ gctUINT32 low;
+ gctUINT32 high;
+}
+gcsMMU_TABLE_ARRAY_ENTRY;
+
+typedef struct _gcsHARDWARE_PAGETABLE_ARRAY
+{
+ /* Number of entries in page table array. */
+ gctUINT num;
+
+ /* Size in bytes of array. */
+ gctSIZE_T size;
+
+ /* Physical address of array. */
+ gctPHYS_ADDR_T address;
+
+ /* Memory descriptor. */
+ gctPHYS_ADDR physical;
+
+ /* Logical address of array. */
+ gctPOINTER logical;
+}
+gcsHARDWARE_PAGETABLE_ARRAY;
+
+/* gckHARDWARE object. */
+struct _gckHARDWARE
+{
+ /* Object. */
+ gcsOBJECT object;
+
+ /* Pointer to gctKERNEL object. */
+ gckKERNEL kernel;
+
+ /* Pointer to gctOS object. */
+ gckOS os;
+
+ /* Core */
+ gceCORE core;
+
+ /* Chip characteristics. */
+ gcsHAL_QUERY_CHIP_IDENTITY identity;
+ gcsHAL_QUERY_CHIP_OPTIONS options;
+ gctUINT32 powerBaseAddress;
+ gctBOOL extraEventStates;
+
+ /* Big endian */
+ gctBOOL bigEndian;
+
+ /* Base address. */
+ gctUINT32 baseAddress;
+
+ /* Chip status */
+ gctPOINTER powerMutex;
+ gctUINT32 powerProcess;
+ gctUINT32 powerThread;
+ gceCHIPPOWERSTATE chipPowerState;
+ gctUINT32 lastWaitLink;
+ gctUINT32 lastEnd;
+ gctBOOL clockState;
+ gctBOOL powerState;
+ gctPOINTER globalSemaphore;
+
+ gctUINT32 mmuVersion;
+
+ /* Type */
+ gceHARDWARE_TYPE type;
+
+#if gcdPOWEROFF_TIMEOUT
+ gctUINT32 powerOffTime;
+ gctUINT32 powerOffTimeout;
+ gctPOINTER powerOffTimer;
+#endif
+
+#if gcdENABLE_FSCALE_VAL_ADJUST
+ gctUINT32 powerOnFscaleVal;
+#endif
+ gctPOINTER pageTableDirty[gcvENGINE_GPU_ENGINE_COUNT];
+
+#if gcdLINK_QUEUE_SIZE
+ struct _gckQUEUE linkQueue;
+#endif
+ gctBOOL stallFEPrefetch;
+
+ gctUINT32 minFscaleValue;
+ gctUINT waitCount;
+
+ gctUINT32 mcClk;
+ gctUINT32 shClk;
+
+ gctPOINTER pendingEvent;
+
+ /* Function used by gckHARDWARE. */
+ gctPHYS_ADDR mmuFuncPhysical;
+ gctPOINTER mmuFuncLogical;
+ gctSIZE_T mmuFuncBytes;
+
+ gctPHYS_ADDR auxFuncPhysical;
+ gctPHYS_ADDR auxPhysHandle;
+ gctPOINTER auxFuncLogical;
+ gctUINT32 auxFuncAddress;
+ gctSIZE_T auxFuncBytes;
+
+ gcsHARDWARE_FUNCTION functions[gcvHARDWARE_FUNCTION_NUM];
+
+ gcsSTATETIMER powerStateTimer;
+ gctUINT32 executeCount;
+ gctUINT32 lastExecuteAddress;
+
+ /* Head for hardware list in gckMMU. */
+ gcsLISTHEAD mmuHead;
+
+ gctPOINTER featureDatabase;
+ gctBOOL hasAsyncFe;
+ gctBOOL hasL2Cache;
+
+ gcsHARDWARE_SIGNATURE signature;
+
+ gctUINT32 maxOutstandingReads;
+
+ gcsHARDWARE_PAGETABLE_ARRAY pagetableArray;
+
+ gctUINT64 contextID;
+};
+
+typedef struct _gcsFEDescriptor
+{
+ gctUINT32 start;
+ gctUINT32 end;
+}
+gcsFEDescriptor;
+
+typedef struct _gcsFE * gckFE;
+typedef struct _gcsFE
+{
+ gckOS os;
+
+ /* Number of free descriptors. */
+ gctPOINTER freeDscriptors;
+}
+gcsFE;
+
+gceSTATUS
+gckFE_Initialize(
+ IN gckHARDWARE Hardware,
+ OUT gckFE FE
+ );
+
+gceSTATUS
+gckFE_ReserveSlot(
+ IN gckHARDWARE Hardware,
+ IN gckFE FE,
+ OUT gctBOOL * Available
+ );
+
+void
+gckFE_UpdateAvaiable(
+ IN gckHARDWARE Hardware,
+ OUT gckFE FE
+ );
+
+void
+gckFE_Execute(
+ IN gckHARDWARE Hardware,
+ IN gckFE FE,
+ IN gcsFEDescriptor * Desc
+ );
+
+gceSTATUS
+gckHARDWARE_GetBaseAddress(
+ IN gckHARDWARE Hardware,
+ OUT gctUINT32_PTR BaseAddress
+ );
+
+gceSTATUS
+gckHARDWARE_NeedBaseAddress(
+ IN gckHARDWARE Hardware,
+ IN gctUINT32 State,
+ OUT gctBOOL_PTR NeedBase
+ );
+
+gceSTATUS
+gckHARDWARE_GetFrameInfo(
+ IN gckHARDWARE Hardware,
+ OUT gcsHAL_FRAME_INFO * FrameInfo
+ );
+
+gceSTATUS
+gckHARDWARE_DumpGpuProfile(
+ IN gckHARDWARE Hardware
+ );
+
+gceSTATUS
+gckHARDWARE_HandleFault(
+ IN gckHARDWARE Hardware
+ );
+
+gceSTATUS
+gckHARDWARE_ExecuteFunctions(
+ IN gckHARDWARE Hardware,
+ IN gceHARDWARE_FUNCTION Function
+ );
+
+gceSTATUS
+gckHARDWARE_DummyDraw(
+ IN gckHARDWARE Hardware,
+ IN gctPOINTER Logical,
+ IN gctUINT32 Address,
+ IN gceDUMMY_DRAW_TYPE DummyDrawType,
+ IN OUT gctUINT32 * Bytes
+ );
+
+gceSTATUS
+gckHARDWARE_EnterQueryClock(
+ IN gckHARDWARE Hardware,
+ OUT gctUINT64 *McStart,
+ OUT gctUINT64 *ShStart
+ );
+
+gceSTATUS
+gckHARDWARE_ExitQueryClock(
+ IN gckHARDWARE Hardware,
+ IN gctUINT64 McStart,
+ IN gctUINT64 ShStart,
+ OUT gctUINT32 *McClk,
+ OUT gctUINT32 *ShClk
+ );
+
+gceSTATUS
+gckHARDWARE_QueryFrequency(
+ IN gckHARDWARE Hardware
+ );
+
+#define gcmkWRITE_MEMORY(logical, data) \
+ do { \
+ gcmkVERIFY_OK(gckOS_WriteMemory(os, logical, data)); \
+ logical++; \
+ }\
+ while (0) ; \
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __gc_hal_kernel_hardware_h_ */
+
diff --git a/drivers/mxc/gpu-viv/hal/kernel/arch/gc_hal_kernel_recorder.c b/drivers/mxc/gpu-viv/hal/kernel/arch/gc_hal_kernel_recorder.c
new file mode 100644
index 000000000000..b6c2ce05cb15
--- /dev/null
+++ b/drivers/mxc/gpu-viv/hal/kernel/arch/gc_hal_kernel_recorder.c
@@ -0,0 +1,728 @@
+/****************************************************************************
+*
+* The MIT License (MIT)
+*
+* Copyright (c) 2014 - 2018 Vivante 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 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 GPL License (GPL)
+*
+* Copyright (C) 2014 - 2018 Vivante 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.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+*****************************************************************************
+*
+* Note: This software is released under dual MIT and GPL licenses. A
+* recipient may use this file under the terms of either the MIT license or
+* GPL License. If you wish to use only one license not the other, you can
+* indicate your decision by deleting one of the above license notices in your
+* version of this file.
+*
+*****************************************************************************/
+
+
+#include "gc_hal.h"
+#include "gc_hal_kernel.h"
+#include "gc_hal_kernel_context.h"
+
+/*
+ * -----------------------
+ * HARDWARE STATE RECORDER
+ * -----------------------
+ *
+ * State mirror buffer is used to 'mirror' hardware states since hardware
+ * states can't be dumpped. It is a context buffer which stores 'global'
+ * context.
+ *
+ * For each commit, state recorder
+ * 1) Records context buffer (if there is) and command buffers in this commit.
+ * 2) Parse those buffers to estimate the state changed.
+ * 3) Stores result to a mirror buffer.
+ *
+ * == Commit 0 ====================================================================
+ *
+ * Context Buffer 0
+ *
+ * Command Buffer 0
+ *
+ * Mirror Buffer 0 <- Context Buffer 0 + Command Buffer 0
+ *
+ * == Commit 1 ====================================================================
+ *
+ * Command Buffer 1
+ *
+ * Mirror Buffer 1 <- Command buffer 1 + Mirror Buffer 0
+ *
+ * == Commit 2 ====================================================================
+ *
+ * Context Buffer 2 (optional)
+ *
+ * Command Buffer 2
+ *
+ * Mirror Buffer 2 <- Command buffer 2 + Context Buffer 2 + Mirror Buffer 1
+ *
+ * == Commit N ====================================================================
+ *
+ * For Commit N, these buffers are needed to reproduce hardware's behavior in
+ * this commit.
+ *
+ * Mirror Buffer [N - 1] : State Mirror accumlated by past commits,
+ * which is used to restore hardware state.
+ * Context Buffer [N] :
+ * Command Buffer [N] : Command buffer executed by hardware in this commit.
+ *
+ * If sequence of states programming matters, hardware's behavior can't be reproduced,
+ * but the state values stored in mirror buffer are assuring.
+ */
+
+/* Queue size. */
+#define gcdNUM_RECORDS 6
+
+typedef struct _gcsPARSER_HANDLER * gckPARSER_HANDLER;
+
+typedef void
+(*HandlerFunction)(
+ IN gckPARSER_HANDLER Handler,
+ IN gctUINT32 Addr,
+ IN gctUINT32 Data
+ );
+
+typedef struct _gcsPARSER_HANDLER
+{
+ gctUINT32 type;
+ gctUINT32 cmd;
+ gctPOINTER private;
+ HandlerFunction function;
+}
+gcsPARSER_HANDLER;
+
+typedef struct _gcsPARSER * gckPARSER;
+typedef struct _gcsPARSER
+{
+ gctUINT8_PTR currentCmdBufferAddr;
+
+ /* Current command. */
+ gctUINT32 lo;
+ gctUINT32 hi;
+
+ gctUINT8 cmdOpcode;
+ gctUINT16 cmdAddr;
+ gctUINT32 cmdSize;
+ gctUINT32 cmdRectCount;
+ gctUINT8 skip;
+ gctUINT32 skipCount;
+
+ gctBOOL allow;
+ gctBOOL stop;
+
+ /* Callback used by parser to handle a command. */
+ gckPARSER_HANDLER commandHandler;
+}
+gcsPARSER;
+
+typedef struct _gcsMIRROR
+{
+ gctUINT32_PTR logical[gcdNUM_RECORDS];
+ gctUINT32 bytes;
+ gcsSTATE_MAP_PTR map;
+ gctSIZE_T maxState;
+}
+gcsMIRROR;
+
+typedef struct _gcsDELTA
+{
+ gctUINT64 commitStamp;
+ gctUINT32_PTR command;
+ gctUINT32 commandBytes;
+ gctUINT32_PTR context;
+ gctUINT32 contextBytes;
+}
+gcsDELTA;
+
+typedef struct _gcsRECORDER
+{
+ gckOS os;
+ gcsMIRROR mirror;
+ gcsDELTA deltas[gcdNUM_RECORDS];
+
+ /* Index of current record. */
+ gctUINT index;
+
+ /* Number of records. */
+ gctUINT num;
+
+ /* Plugin used by gckPARSER. */
+ gcsPARSER_HANDLER recorderHandler;
+ gckPARSER parser;
+}
+gcsRECORDER;
+
+
+/******************************************************************************\
+***************************** Command Buffer Parser ****************************
+\******************************************************************************/
+
+/*
+** Command buffer parser checks command buffer in FE's view to make sure there
+** is no format error.
+**
+** Parser provide a callback mechnisam, so plug-in can be added to implement
+** other functions.
+*/
+
+static void
+_HandleLoadState(
+ IN OUT gckPARSER Parser
+ )
+{
+ gctUINT i;
+ gctUINT32_PTR data = (gctUINT32_PTR)Parser->currentCmdBufferAddr;
+ gctUINT32 cmdAddr = Parser->cmdAddr;
+
+ if (Parser->commandHandler == gcvNULL
+ || Parser->commandHandler->cmd != 0x01
+ )
+ {
+ /* No handler for this command. */
+ return;
+ }
+
+ for (i = 0; i < Parser->cmdSize; i++)
+ {
+ Parser->commandHandler->function(Parser->commandHandler, cmdAddr, *data);
+
+ /* Advance to next state. */
+ cmdAddr++;
+ data++;
+ }
+}
+
+static void
+_GetCommand(
+ IN OUT gckPARSER Parser
+ )
+{
+ gctUINT32 * buffer = (gctUINT32 *)Parser->currentCmdBufferAddr;
+
+ gctUINT16 cmdRectCount;
+ gctUINT16 cmdDataCount;
+
+ Parser->hi = buffer[0];
+ Parser->lo = buffer[1];
+
+ Parser->cmdOpcode = (((((gctUINT32) (Parser->hi)) >> (0 ? 31:27)) & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1)))))) );
+ Parser->cmdRectCount = 1;
+
+ switch (Parser->cmdOpcode)
+ {
+ case 0x01:
+ /* Extract count. */
+ Parser->cmdSize = (((((gctUINT32) (Parser->hi)) >> (0 ? 25:16)) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1)))))) );
+ if (Parser->cmdSize == 0)
+ {
+ /* 0 means 1024. */
+ Parser->cmdSize = 1024;
+ }
+ Parser->skip = (Parser->cmdSize & 0x1) ? 0 : 1;
+
+ /* Extract address. */
+ Parser->cmdAddr = (((((gctUINT32) (Parser->hi)) >> (0 ? 15:0)) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1)))))) );
+
+ Parser->currentCmdBufferAddr = Parser->currentCmdBufferAddr + 4;
+ Parser->skipCount = Parser->cmdSize + Parser->skip;
+ break;
+
+ case 0x05:
+ Parser->cmdSize = 4;
+ Parser->skipCount = gcmALIGN(Parser->cmdSize, 2);
+ break;
+
+ case 0x06:
+ Parser->cmdSize = 5;
+ Parser->skipCount = gcmALIGN(Parser->cmdSize, 2);
+ break;
+
+ case 0x0C:
+ Parser->cmdSize = 3;
+ Parser->skipCount = gcmALIGN(Parser->cmdSize, 2);
+ break;
+
+ case 0x09:
+ Parser->cmdSize = 2;
+ Parser->cmdAddr = 0x0F16;
+ Parser->skipCount = gcmALIGN(Parser->cmdSize, 2);
+ break;
+
+ case 0x04:
+ Parser->cmdSize = 1;
+ Parser->cmdAddr = 0x0F06;
+
+ cmdRectCount = (((((gctUINT32) (Parser->hi)) >> (0 ? 15:8)) & ((gctUINT32) ((((1 ? 15:8) - (0 ? 15:8) + 1) == 32) ? ~0U : (~(~0U << ((1 ? 15:8) - (0 ? 15:8) + 1)))))) );
+ cmdDataCount = (((((gctUINT32) (Parser->hi)) >> (0 ? 26:16)) & ((gctUINT32) ((((1 ? 26:16) - (0 ? 26:16) + 1) == 32) ? ~0U : (~(~0U << ((1 ? 26:16) - (0 ? 26:16) + 1)))))) );
+
+ Parser->skipCount = gcmALIGN(Parser->cmdSize, 2)
+ + cmdRectCount * 2
+ + gcmALIGN(cmdDataCount, 2);
+
+ Parser->cmdRectCount = cmdRectCount;
+ break;
+
+ case 0x03:
+ Parser->currentCmdBufferAddr = Parser->currentCmdBufferAddr + 8;
+ Parser->skipCount = 0;
+ break;
+
+ case 0x02:
+ Parser->currentCmdBufferAddr = Parser->currentCmdBufferAddr + 8;
+ Parser->skipCount = 0;
+ break;
+
+ case 0x07:
+ Parser->currentCmdBufferAddr = Parser->currentCmdBufferAddr + 8;
+ Parser->skipCount = 0;
+ break;
+
+ case 0x08:
+ /* Commands after LINK isn't executed, skip them. */
+ Parser->stop = gcvTRUE;
+ break;
+
+ default:
+ /* Unknown command is a risk. */
+ Parser->allow = gcvFALSE;
+ break;
+ }
+}
+
+static void
+_ParseCommand(
+ IN OUT gckPARSER Parser
+ )
+{
+ switch(Parser->cmdOpcode)
+ {
+ case 0x01:
+ _HandleLoadState(Parser);
+ break;
+ case 0x05:
+ case 0x06:
+ case 0x0C:
+ break;
+ case 0x04:
+ break;
+ default:
+ break;
+ }
+
+ /* Advance to next command. */
+ Parser->currentCmdBufferAddr = Parser->currentCmdBufferAddr
+ + (Parser->skipCount << 2);
+}
+
+gceSTATUS
+gckPARSER_Parse(
+ IN gckPARSER Parser,
+ IN gctUINT8_PTR Buffer,
+ IN gctUINT32 Bytes
+ )
+{
+ gckPARSER parser = Parser;
+ gctUINT8_PTR end = (gctUINT8_PTR)Buffer + Bytes;
+
+ /* Initialize parser. */
+ parser->currentCmdBufferAddr = (gctUINT8_PTR)Buffer;
+ parser->skip = 0;
+ parser->allow = gcvTRUE;
+ parser->stop = gcvFALSE;
+
+ /* Go through command buffer until reaching the end
+ ** or meeting an error. */
+ do
+ {
+ _GetCommand(parser);
+
+ _ParseCommand(parser);
+ }
+ while ((parser->currentCmdBufferAddr < end)
+ && (parser->allow == gcvTRUE)
+ && (parser->stop == gcvFALSE)
+ );
+
+ if (parser->allow == gcvFALSE)
+ {
+ /* Error detected. */
+ return gcvSTATUS_NOT_SUPPORTED;
+ }
+
+ return gcvSTATUS_OK;
+}
+
+/*******************************************************************************
+**
+** gckPARSER_RegisterCommandHandler
+**
+** Register a command handler which will be called when parser get a command.
+**
+*/
+gceSTATUS
+gckPARSER_RegisterCommandHandler(
+ IN gckPARSER Parser,
+ IN gckPARSER_HANDLER Handler
+ )
+{
+ Parser->commandHandler = Handler;
+
+ return gcvSTATUS_OK;
+}
+
+gceSTATUS
+gckPARSER_Construct(
+ IN gckOS Os,
+ IN gckPARSER_HANDLER Handler,
+ OUT gckPARSER * Parser
+ )
+{
+ gceSTATUS status;
+ gckPARSER pointer;
+
+ gcmkONERROR(gckOS_Allocate(Os, gcmSIZEOF(gcsPARSER), (gctPOINTER *)&pointer));
+
+ /* Put it here temp, should have a more general plug-in mechnisam. */
+ pointer->commandHandler = Handler;
+
+ *Parser = pointer;
+
+ return gcvSTATUS_OK;
+
+OnError:
+ return status;
+}
+
+void
+gckPARSER_Destroy(
+ IN gckOS Os,
+ IN gckPARSER Parser
+ )
+{
+ gcmkOS_SAFE_FREE(Os, Parser);
+}
+
+/******************************************************************************\
+**************************** Hardware States Recorder **************************
+\******************************************************************************/
+
+static void
+_RecodeState(
+ IN gckPARSER_HANDLER Handler,
+ IN gctUINT32 Addr,
+ IN gctUINT32 Data
+ )
+{
+ gcmkVERIFY_OK(gckRECORDER_UpdateMirror(Handler->private, Addr, Data));
+}
+
+static gctUINT
+_Previous(
+ IN gctUINT Index
+ )
+{
+ if (Index == 0)
+ {
+ return gcdNUM_RECORDS - 1;
+ }
+
+ return Index - 1;
+}
+
+static gctUINT
+_Next(
+ IN gctUINT Index
+ )
+{
+ return (Index + 1) % gcdNUM_RECORDS;
+}
+
+gceSTATUS
+gckRECORDER_Construct(
+ IN gckOS Os,
+ IN gckHARDWARE Hardware,
+ OUT gckRECORDER * Recorder
+ )
+{
+ gceSTATUS status;
+ gckCONTEXT context = gcvNULL;
+ gckRECORDER recorder = gcvNULL;
+ gctSIZE_T mapSize;
+ gctUINT i;
+ gctBOOL virtualCommandBuffer = Hardware->kernel->virtualCommandBuffer;
+
+ /* MMU is not ready now. */
+ Hardware->kernel->virtualCommandBuffer = gcvFALSE;
+
+ gcmkONERROR(gckCONTEXT_Construct(Os, Hardware, 0, &context));
+
+ /* Restore. */
+ Hardware->kernel->virtualCommandBuffer = virtualCommandBuffer;
+
+ gcmkONERROR(gckOS_Allocate(Os, gcmSIZEOF(gcsRECORDER), (gctPOINTER *)&recorder));
+
+ gckOS_ZeroMemory(recorder, gcmSIZEOF(gcsRECORDER));
+
+ /* Copy state map. */
+ recorder->mirror.maxState = context->maxState;
+
+ mapSize = context->maxState * gcmSIZEOF(gcsSTATE_MAP);
+
+ gcmkONERROR(gckOS_Allocate(Os, mapSize, (gctPOINTER *)&recorder->mirror.map));
+
+ gckOS_MemCopy(recorder->mirror.map, context->map, mapSize);
+
+ /* Copy context buffer. */
+ recorder->mirror.bytes = context->totalSize;
+
+ for (i = 0; i < gcdNUM_RECORDS; i++)
+ {
+ gcmkONERROR(gckOS_Allocate(Os, context->totalSize, (gctPOINTER *)&recorder->mirror.logical[i]));
+ gckOS_MemCopy(recorder->mirror.logical[i], context->buffer->logical, context->totalSize);
+ }
+
+ for (i = 0; i < gcdNUM_RECORDS; i++)
+ {
+ gcmkONERROR(gckOS_Allocate(Os, gcdCMD_BUFFER_SIZE, (gctPOINTER *)&recorder->deltas[i].command));
+ gcmkONERROR(gckOS_Allocate(Os, context->totalSize, (gctPOINTER *)&recorder->deltas[i].context));
+ }
+
+ recorder->index = 0;
+ recorder->num = 0;
+
+ /* Initialize Parser plugin. */
+ recorder->recorderHandler.cmd = 0x01;
+ recorder->recorderHandler.private = recorder;
+ recorder->recorderHandler.function = _RecodeState;
+
+ gcmkONERROR(gckPARSER_Construct(Os, &recorder->recorderHandler, &recorder->parser));
+
+ recorder->os = Os;
+
+ *Recorder = recorder;
+
+ gckCONTEXT_Destroy(context);
+ return gcvSTATUS_OK;
+
+OnError:
+ if (context)
+ {
+ gckCONTEXT_Destroy(context);
+ }
+
+ if (recorder)
+ {
+ gckRECORDER_Destory(Os, recorder);
+ }
+
+ return status;
+}
+
+gceSTATUS
+gckRECORDER_Destory(
+ IN gckOS Os,
+ IN gckRECORDER Recorder
+ )
+{
+ gctUINT i;
+
+ if (Recorder->mirror.map)
+ {
+ gcmkOS_SAFE_FREE(Os, Recorder->mirror.map);
+ }
+
+ for (i = 0; i < gcdNUM_RECORDS; i++)
+ {
+ if (Recorder->mirror.logical[i])
+ {
+ gcmkOS_SAFE_FREE(Os, Recorder->mirror.logical[i]);
+ }
+ }
+
+ for (i = 0; i < gcdNUM_RECORDS; i++)
+ {
+ if (Recorder->deltas[i].command)
+ {
+ gcmkOS_SAFE_FREE(Os, Recorder->deltas[i].command);
+ }
+
+ if (Recorder->deltas[i].context)
+ {
+ gcmkOS_SAFE_FREE(Os, Recorder->deltas[i].context);
+ }
+ }
+
+ if (Recorder->parser)
+ {
+ gckPARSER_Destroy(Os, Recorder->parser);
+ }
+
+ gcmkOS_SAFE_FREE(Os, Recorder);
+
+ return gcvSTATUS_OK;
+}
+
+gceSTATUS
+gckRECORDER_UpdateMirror(
+ IN gckRECORDER Recorder,
+ IN gctUINT32 State,
+ IN gctUINT32 Data
+ )
+{
+ gctUINT32 index;
+ gcsSTATE_MAP_PTR map = Recorder->mirror.map;
+ gctUINT32_PTR buffer = Recorder->mirror.logical[Recorder->index];
+
+ if (State >= Recorder->mirror.maxState)
+ {
+ /* Ignore them just like HW does. */
+ return gcvSTATUS_OK;
+ }
+
+ index = map[State].index;
+
+ if (index)
+ {
+ buffer[index] = Data;
+ }
+
+ return gcvSTATUS_OK;
+}
+
+void
+gckRECORDER_AdvanceIndex(
+ IN gckRECORDER Recorder,
+ IN gctUINT64 CommitStamp
+ )
+{
+ /* Get next record. */
+ gctUINT next = (Recorder->index + 1) % gcdNUM_RECORDS;
+
+ /* Record stamp of this commit. */
+ Recorder->deltas[Recorder->index].commitStamp = CommitStamp;
+
+ /* Mirror of next record is mirror of this record and delta in next record. */
+ gckOS_MemCopy(Recorder->mirror.logical[next],
+ Recorder->mirror.logical[Recorder->index], Recorder->mirror.bytes);
+
+ /* Advance to next record. */
+ Recorder->index = next;
+
+ Recorder->num = gcmMIN(Recorder->num + 1, gcdNUM_RECORDS - 1);
+
+
+ /* Reset delta. */
+ Recorder->deltas[Recorder->index].commandBytes = 0;
+ Recorder->deltas[Recorder->index].contextBytes = 0;
+}
+
+void
+gckRECORDER_Record(
+ IN gckRECORDER Recorder,
+ IN gctUINT8_PTR CommandBuffer,
+ IN gctUINT32 CommandBytes,
+ IN gctUINT8_PTR ContextBuffer,
+ IN gctUINT32 ContextBytes
+ )
+{
+ gcsDELTA * delta = &Recorder->deltas[Recorder->index];
+
+ if (CommandBytes != 0xFFFFFFFF)
+ {
+ gckPARSER_Parse(Recorder->parser, CommandBuffer, CommandBytes);
+ gckOS_MemCopy(delta->command, CommandBuffer, CommandBytes);
+ delta->commandBytes = CommandBytes;
+ }
+
+ if (ContextBytes != 0xFFFFFFFF)
+ {
+ gckPARSER_Parse(Recorder->parser, ContextBuffer, ContextBytes);
+ gckOS_MemCopy(delta->context, ContextBuffer, ContextBytes);
+ delta->contextBytes = ContextBytes;
+ }
+}
+
+void
+gckRECORDER_Dump(
+ IN gckRECORDER Recorder
+ )
+{
+ gctUINT last = Recorder->index;
+ gctUINT previous;
+ gctUINT i;
+ gcsMIRROR *mirror = &Recorder->mirror;
+ gcsDELTA *delta;
+ gckOS os = Recorder->os;
+
+ for (i = 0; i < Recorder->num; i++)
+ {
+ last = _Previous(last);
+ }
+
+ for (i = 0; i < Recorder->num; i++)
+ {
+ delta = &Recorder->deltas[last];
+
+ /* Dump record */
+ gcmkPRINT("#[commit %llu]", delta->commitStamp);
+
+ if (delta->commitStamp)
+ {
+ previous = _Previous(last);
+
+ gcmkPRINT("#[mirror]");
+ gckOS_DumpBuffer(os, mirror->logical[previous], mirror->bytes, gcvDUMP_BUFFER_CONTEXT, gcvTRUE);
+ gcmkPRINT("@[kernel.execute]");
+ }
+
+ if (delta->contextBytes)
+ {
+ gckOS_DumpBuffer(os, delta->context, delta->contextBytes, gcvDUMP_BUFFER_CONTEXT, gcvTRUE);
+ gcmkPRINT("@[kernel.execute]");
+ }
+
+ gckOS_DumpBuffer(os, delta->command, delta->commandBytes, gcvDUMP_BUFFER_USER, gcvTRUE);
+ gcmkPRINT("@[kernel.execute]");
+
+ last = _Next(last);
+ }
+}
+
+
diff --git a/drivers/mxc/gpu-viv/hal/kernel/archvg/gc_hal_kernel_hardware_command_vg.c b/drivers/mxc/gpu-viv/hal/kernel/archvg/gc_hal_kernel_hardware_command_vg.c
new file mode 100644
index 000000000000..f510b30a1eb7
--- /dev/null
+++ b/drivers/mxc/gpu-viv/hal/kernel/archvg/gc_hal_kernel_hardware_command_vg.c
@@ -0,0 +1,1411 @@
+/****************************************************************************
+*
+* The MIT License (MIT)
+*
+* Copyright (c) 2014 - 2018 Vivante 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 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 GPL License (GPL)
+*
+* Copyright (C) 2014 - 2018 Vivante 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.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+*****************************************************************************
+*
+* Note: This software is released under dual MIT and GPL licenses. A
+* recipient may use this file under the terms of either the MIT license or
+* GPL License. If you wish to use only one license not the other, you can
+* indicate your decision by deleting one of the above license notices in your
+* version of this file.
+*
+*****************************************************************************/
+
+
+#include "gc_hal.h"
+#include "gc_hal_kernel.h"
+
+#if gcdENABLE_VG
+
+#include "gc_hal_kernel_hardware_command_vg.h"
+
+#define _GC_OBJ_ZONE gcvZONE_COMMAND
+
+/******************************************************************************\
+****************************** gckVGCOMMAND API code *****************************
+\******************************************************************************/
+
+/*******************************************************************************
+**
+** gckVGCOMMAND_InitializeInfo
+**
+** Initialize architecture dependent command buffer information.
+**
+** INPUT:
+**
+** gckVGCOMMAND Command
+** Pointer to the Command object.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckVGCOMMAND_InitializeInfo(
+ IN gckVGCOMMAND Command
+ )
+{
+ gceSTATUS status;
+ gcmkHEADER_ARG("Command=0x%x", Command);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Command, gcvOBJ_COMMAND);
+
+ do
+ {
+ /* Reset interrupts. */
+ Command->info.feBufferInt = -1;
+ Command->info.tsOverflowInt = -1;
+
+ /* Set command buffer attributes. */
+ Command->info.addressAlignment = 64;
+ Command->info.commandAlignment = 8;
+
+ /* Determine command alignment address mask. */
+ Command->info.addressMask = ((((gctUINT32) (Command->info.addressAlignment - 1)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 1:0) - (0 ?
+ 1:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 1:0) - (0 ?
+ 1:0) + 1))))))) << (0 ?
+ 1:0))) | (((gctUINT32) ((gctUINT32) (0 ) & ((gctUINT32) ((((1 ?
+ 1:0) - (0 ?
+ 1:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 1:0) - (0 ? 1:0) + 1))))))) << (0 ? 1:0)));
+
+ /* Query the number of bytes needed by the STATE command. */
+ gcmkERR_BREAK(gckVGCOMMAND_StateCommand(
+ Command, 0x0, gcvNULL, (gctUINT32)~0, 0,
+ &Command->info.stateCommandSize
+ ));
+
+ /* Query the number of bytes needed by the RESTART command. */
+ gcmkERR_BREAK(gckVGCOMMAND_RestartCommand(
+ Command, gcvNULL, (gctUINT32)~0, 0,
+ &Command->info.restartCommandSize
+ ));
+
+ /* Query the number of bytes needed by the FETCH command. */
+ gcmkERR_BREAK(gckVGCOMMAND_FetchCommand(
+ Command, gcvNULL, (gctUINT32)~0, 0,
+ &Command->info.fetchCommandSize
+ ));
+
+ /* Query the number of bytes needed by the CALL command. */
+ gcmkERR_BREAK(gckVGCOMMAND_CallCommand(
+ Command, gcvNULL, (gctUINT32)~0, 0,
+ &Command->info.callCommandSize
+ ));
+
+ /* Query the number of bytes needed by the RETURN command. */
+ gcmkERR_BREAK(gckVGCOMMAND_ReturnCommand(
+ Command, gcvNULL,
+ &Command->info.returnCommandSize
+ ));
+
+ /* Query the number of bytes needed by the EVENT command. */
+ gcmkERR_BREAK(gckVGCOMMAND_EventCommand(
+ Command, gcvNULL, gcvBLOCK_PIXEL, -1,
+ &Command->info.eventCommandSize
+ ));
+
+ /* Query the number of bytes needed by the END command. */
+ gcmkERR_BREAK(gckVGCOMMAND_EndCommand(
+ Command, gcvNULL, -1,
+ &Command->info.endCommandSize
+ ));
+
+ /* Determine the tail reserve size. */
+ Command->info.staticTailSize = gcmMAX(
+ Command->info.fetchCommandSize,
+ gcmMAX(
+ Command->info.returnCommandSize,
+ Command->info.endCommandSize
+ )
+ );
+
+ /* Determine the maximum tail size. */
+ Command->info.dynamicTailSize
+ = Command->info.staticTailSize
+ + Command->info.eventCommandSize * gcvBLOCK_COUNT;
+ }
+ while (gcvFALSE);
+
+ gcmkFOOTER();
+ /* Return status. */
+ return status;
+}
+
+/*******************************************************************************
+**
+** gckVGCOMMAND_StateCommand
+**
+** Append a STATE command at the specified location in the command buffer.
+**
+** INPUT:
+**
+** gckVGCOMMAND Command
+** Pointer to an gckVGCOMMAND object.
+**
+** gctUINT32 Pipe
+** Harwdare destination pipe.
+**
+** gctPOINTER Logical
+** Pointer to the current location inside the command buffer to append
+** STATE command at or gcvNULL to query the size of the command.
+**
+** gctUINT32 Address
+** Starting register address of the state buffer.
+** If 'Logical' is gcvNULL, this argument is ignored.
+**
+** gctUINT32 Count
+** Number of states in state buffer.
+** If 'Logical' is gcvNULL, this argument is ignored.
+**
+** gctSIZE_T * Bytes
+** Pointer to the number of bytes available for the STATE command.
+** If 'Logical' is gcvNULL, the value from this argument is ignored.
+**
+** OUTPUT:
+**
+** gctSIZE_T * Bytes
+** Pointer to a variable that will receive the number of bytes required
+** for the STATE command. If 'Bytes' is gcvNULL, nothing is returned.
+*/
+gceSTATUS
+gckVGCOMMAND_StateCommand(
+ IN gckVGCOMMAND Command,
+ IN gctUINT32 Pipe,
+ IN gctPOINTER Logical,
+ IN gctUINT32 Address,
+ IN gctUINT32 Count,
+ IN OUT gctUINT32 * Bytes
+ )
+{
+ gcmkHEADER_ARG("Command=0x%x Pipe=0x%x Logical=0x%x Address=0x%x Count=0x%x Bytes = 0x%x",
+ Command, Pipe, Logical, Address, Count, Bytes);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Command, gcvOBJ_COMMAND);
+
+ if (Command->fe20)
+ {
+ if (Logical != gcvNULL)
+ {
+ gctUINT32_PTR buffer;
+
+ /* Cast the buffer pointer. */
+ buffer = (gctUINT32_PTR) Logical;
+
+ /* Append STATE. */
+ gckOS_WriteMemory(
+ Command->os,
+ &buffer[0],
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:28) - (0 ?
+ 31:28) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:28) - (0 ?
+ 31:28) + 1))))))) << (0 ?
+ 31:28))) | (((gctUINT32) (0x3 & ((gctUINT32) ((((1 ?
+ 31:28) - (0 ?
+ 31:28) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:28) - (0 ? 31:28) + 1))))))) << (0 ? 31:28)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 11:0) - (0 ?
+ 11:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 11:0) - (0 ?
+ 11:0) + 1))))))) << (0 ?
+ 11:0))) | (((gctUINT32) ((gctUINT32) (Address) & ((gctUINT32) ((((1 ?
+ 11:0) - (0 ?
+ 11:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 11:0) - (0 ? 11:0) + 1))))))) << (0 ? 11:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 27:16) - (0 ?
+ 27:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 27:16) - (0 ?
+ 27:16) + 1))))))) << (0 ?
+ 27:16))) | (((gctUINT32) ((gctUINT32) (Count) & ((gctUINT32) ((((1 ?
+ 27:16) - (0 ?
+ 27:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 27:16) - (0 ? 27:16) + 1))))))) << (0 ? 27:16)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 13:12) - (0 ?
+ 13:12) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 13:12) - (0 ?
+ 13:12) + 1))))))) << (0 ?
+ 13:12))) | (((gctUINT32) ((gctUINT32) (Pipe) & ((gctUINT32) ((((1 ?
+ 13:12) - (0 ?
+ 13:12) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 13:12) - (0 ? 13:12) + 1))))))) << (0 ? 13:12)))
+ );
+ }
+
+ if (Bytes != gcvNULL)
+ {
+ /* Return number of bytes required by the STATE command. */
+ *Bytes = 4 * (Count + 1);
+ }
+ }
+ else
+ {
+ if (Logical != gcvNULL)
+ {
+ gctUINT32_PTR buffer;
+
+ /* Cast the buffer pointer. */
+ buffer = (gctUINT32_PTR) Logical;
+
+ /* Append LOAD_STATE. */
+ gckOS_WriteMemory(
+ Command->os,
+ &buffer[0],
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (Count) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (Address) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+ );
+ }
+
+ if (Bytes != gcvNULL)
+ {
+ /* Return number of bytes required by the STATE command. */
+ *Bytes = 4 * (Count + 1);
+ }
+ }
+
+ gcmkFOOTER_NO();
+ /* Success. */
+ return gcvSTATUS_OK;
+}
+
+/*******************************************************************************
+**
+** gckVGCOMMAND_RestartCommand
+**
+** Form a RESTART command at the specified location in the command buffer.
+**
+** INPUT:
+**
+** gckVGCOMMAND Command
+** Pointer to an gckVGCOMMAND object.
+**
+** gctPOINTER Logical
+** Pointer to the current location inside the command buffer to append
+** RESTART command at or gcvNULL to query the size of the command.
+**
+** gctUINT32 FetchAddress
+** The address of another command buffer to be executed by this RESTART
+** command. If 'Logical' is gcvNULL, this argument is ignored.
+**
+** gctUINT FetchCount
+** The number of 64-bit data quantities in another command buffer to
+** be executed by this RESTART command. If 'Logical' is gcvNULL, this
+** argument is ignored.
+**
+** gctSIZE_T * Bytes
+** Pointer to the number of bytes available for the RESTART command.
+** If 'Logical' is gcvNULL, the value from this argument is ignored.
+**
+** OUTPUT:
+**
+** gctSIZE_T * Bytes
+** Pointer to a variable that will receive the number of bytes required
+** for the RESTART command. If 'Bytes' is gcvNULL, nothing is returned.
+*/
+gceSTATUS
+gckVGCOMMAND_RestartCommand(
+ IN gckVGCOMMAND Command,
+ IN gctPOINTER Logical,
+ IN gctUINT32 FetchAddress,
+ IN gctUINT FetchCount,
+ IN OUT gctUINT32 * Bytes
+ )
+{
+ gcmkHEADER_ARG("Command=0x%x Logical=0x%x FetchAddress=0x%x FetchCount=0x%x Bytes = 0x%x",
+ Command, Logical, FetchAddress, FetchCount, Bytes);
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Command, gcvOBJ_COMMAND);
+
+ if (Command->fe20)
+ {
+ if (Logical != gcvNULL)
+ {
+ gctUINT32_PTR buffer;
+ gctUINT32 beginEndMark;
+
+ /* Cast the buffer pointer. */
+ buffer = (gctUINT32_PTR) Logical;
+
+ /* Determine Begin/End flag. */
+ beginEndMark = (FetchCount > 0)
+ ?
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 24:24) - (0 ?
+ 24:24) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 24:24) - (0 ?
+ 24:24) + 1))))))) << (0 ?
+ 24:24))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ?
+ 24:24) - (0 ?
+ 24:24) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 24:24) - (0 ? 24:24) + 1))))))) << (0 ? 24:24)))
+ : ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 24:24) - (0 ?
+ 24:24) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 24:24) - (0 ?
+ 24:24) + 1))))))) << (0 ?
+ 24:24))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 24:24) - (0 ?
+ 24:24) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 24:24) - (0 ? 24:24) + 1))))))) << (0 ? 24:24)));
+
+ /* Append RESTART. */
+ gckOS_WriteMemory(
+ Command->os,
+ &buffer[0],
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:28) - (0 ?
+ 31:28) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:28) - (0 ?
+ 31:28) + 1))))))) << (0 ?
+ 31:28))) | (((gctUINT32) (0x9 & ((gctUINT32) ((((1 ?
+ 31:28) - (0 ?
+ 31:28) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:28) - (0 ? 31:28) + 1))))))) << (0 ? 31:28)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 20:0) - (0 ?
+ 20:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 20:0) - (0 ?
+ 20:0) + 1))))))) << (0 ?
+ 20:0))) | (((gctUINT32) ((gctUINT32) (FetchCount) & ((gctUINT32) ((((1 ?
+ 20:0) - (0 ?
+ 20:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 20:0) - (0 ? 20:0) + 1))))))) << (0 ? 20:0)))
+ | beginEndMark
+ );
+
+ gckOS_WriteMemory(
+ Command->os,
+ &buffer[1],
+ FetchAddress
+ );
+ }
+
+ if (Bytes != gcvNULL)
+ {
+ /* Return number of bytes required by the RESTART command. */
+ *Bytes = 8;
+ }
+ }
+ else
+ {
+ gcmkFOOTER_NO();
+ return gcvSTATUS_NOT_SUPPORTED;
+ }
+
+
+ gcmkFOOTER_NO();
+ /* Success. */
+ return gcvSTATUS_OK;
+}
+
+/*******************************************************************************
+**
+** gckVGCOMMAND_FetchCommand
+**
+** Form a FETCH command at the specified location in the command buffer.
+**
+** INPUT:
+**
+** gckVGCOMMAND Command
+** Pointer to an gckVGCOMMAND object.
+**
+** gctPOINTER Logical
+** Pointer to the current location inside the command buffer to append
+** FETCH command at or gcvNULL to query the size of the command.
+**
+** gctUINT32 FetchAddress
+** The address of another command buffer to be executed by this FETCH
+** command. If 'Logical' is gcvNULL, this argument is ignored.
+**
+** gctUINT FetchCount
+** The number of 64-bit data quantities in another command buffer to
+** be executed by this FETCH command. If 'Logical' is gcvNULL, this
+** argument is ignored.
+**
+** gctSIZE_T * Bytes
+** Pointer to the number of bytes available for the FETCH command.
+** If 'Logical' is gcvNULL, the value from this argument is ignored.
+**
+** OUTPUT:
+**
+** gctSIZE_T * Bytes
+** Pointer to a variable that will receive the number of bytes required
+** for the FETCH command. If 'Bytes' is gcvNULL, nothing is returned.
+*/
+gceSTATUS
+gckVGCOMMAND_FetchCommand(
+ IN gckVGCOMMAND Command,
+ IN gctPOINTER Logical,
+ IN gctUINT32 FetchAddress,
+ IN gctUINT FetchCount,
+ IN OUT gctUINT32 * Bytes
+ )
+{
+ gcmkHEADER_ARG("Command=0x%x Logical=0x%x FetchAddress=0x%x FetchCount=0x%x Bytes = 0x%x",
+ Command, Logical, FetchAddress, FetchCount, Bytes);
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Command, gcvOBJ_COMMAND);
+
+ if (Command->fe20)
+ {
+ if (Logical != gcvNULL)
+ {
+ gctUINT32_PTR buffer;
+
+ /* Cast the buffer pointer. */
+ buffer = (gctUINT32_PTR) Logical;
+
+ /* Append FETCH. */
+ gckOS_WriteMemory(
+ Command->os,
+ &buffer[0],
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:28) - (0 ?
+ 31:28) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:28) - (0 ?
+ 31:28) + 1))))))) << (0 ?
+ 31:28))) | (((gctUINT32) (0x5 & ((gctUINT32) ((((1 ?
+ 31:28) - (0 ?
+ 31:28) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:28) - (0 ? 31:28) + 1))))))) << (0 ? 31:28)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 20:0) - (0 ?
+ 20:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 20:0) - (0 ?
+ 20:0) + 1))))))) << (0 ?
+ 20:0))) | (((gctUINT32) ((gctUINT32) (FetchCount) & ((gctUINT32) ((((1 ?
+ 20:0) - (0 ?
+ 20:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 20:0) - (0 ? 20:0) + 1))))))) << (0 ? 20:0)))
+ );
+
+ gckOS_WriteMemory(
+ Command->os,
+ &buffer[1],
+ gcmkFIXADDRESS(FetchAddress)
+ );
+ }
+
+ if (Bytes != gcvNULL)
+ {
+ /* Return number of bytes required by the FETCH command. */
+ *Bytes = 8;
+ }
+ }
+ else
+ {
+ if (Logical != gcvNULL)
+ {
+ gctUINT32_PTR buffer;
+
+ /* Cast the buffer pointer. */
+ buffer = (gctUINT32_PTR) Logical;
+
+ /* Append LINK. */
+ gckOS_WriteMemory(
+ Command->os,
+ &buffer[0],
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x08 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (FetchCount) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+ );
+
+ gckOS_WriteMemory(
+ Command->os,
+ &buffer[1],
+ gcmkFIXADDRESS(FetchAddress)
+ );
+ }
+
+ if (Bytes != gcvNULL)
+ {
+ /* Return number of bytes required by the LINK command. */
+ *Bytes = 8;
+ }
+ }
+
+ gcmkFOOTER_NO();
+ /* Success. */
+ return gcvSTATUS_OK;
+}
+
+/*******************************************************************************
+**
+** gckVGCOMMAND_CallCommand
+**
+** Append a CALL command at the specified location in the command buffer.
+**
+** INPUT:
+**
+** gckVGCOMMAND Command
+** Pointer to an gckVGCOMMAND object.
+**
+** gctPOINTER Logical
+** Pointer to the current location inside the command buffer to append
+** CALL command at or gcvNULL to query the size of the command.
+**
+** gctUINT32 FetchAddress
+** The address of another command buffer to be executed by this CALL
+** command. If 'Logical' is gcvNULL, this argument is ignored.
+**
+** gctUINT FetchCount
+** The number of 64-bit data quantities in another command buffer to
+** be executed by this CALL command. If 'Logical' is gcvNULL, this
+** argument is ignored.
+**
+** gctSIZE_T * Bytes
+** Pointer to the number of bytes available for the CALL command.
+** If 'Logical' is gcvNULL, the value from this argument is ignored.
+**
+** OUTPUT:
+**
+** gctSIZE_T * Bytes
+** Pointer to a variable that will receive the number of bytes required
+** for the CALL command. If 'Bytes' is gcvNULL, nothing is returned.
+*/
+gceSTATUS
+gckVGCOMMAND_CallCommand(
+ IN gckVGCOMMAND Command,
+ IN gctPOINTER Logical,
+ IN gctUINT32 FetchAddress,
+ IN gctUINT FetchCount,
+ IN OUT gctUINT32 * Bytes
+ )
+{
+ gcmkHEADER_ARG("Command=0x%x Logical=0x%x FetchAddress=0x%x FetchCount=0x%x Bytes = 0x%x",
+ Command, Logical, FetchAddress, FetchCount, Bytes);
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Command, gcvOBJ_COMMAND);
+
+ if (Command->fe20)
+ {
+ if (Logical != gcvNULL)
+ {
+ gctUINT32_PTR buffer;
+
+ /* Cast the buffer pointer. */
+ buffer = (gctUINT32_PTR) Logical;
+
+ /* Append CALL. */
+ gckOS_WriteMemory(
+ Command->os,
+ &buffer[0],
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:28) - (0 ?
+ 31:28) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:28) - (0 ?
+ 31:28) + 1))))))) << (0 ?
+ 31:28))) | (((gctUINT32) (0x6 & ((gctUINT32) ((((1 ?
+ 31:28) - (0 ?
+ 31:28) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:28) - (0 ? 31:28) + 1))))))) << (0 ? 31:28)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 20:0) - (0 ?
+ 20:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 20:0) - (0 ?
+ 20:0) + 1))))))) << (0 ?
+ 20:0))) | (((gctUINT32) ((gctUINT32) (FetchCount) & ((gctUINT32) ((((1 ?
+ 20:0) - (0 ?
+ 20:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 20:0) - (0 ? 20:0) + 1))))))) << (0 ? 20:0)))
+ );
+
+ gckOS_WriteMemory(
+ Command->os,
+ &buffer[1],
+ gcmkFIXADDRESS(FetchAddress)
+ );
+ }
+
+ if (Bytes != gcvNULL)
+ {
+ /* Return number of bytes required by the CALL command. */
+ *Bytes = 8;
+ }
+ }
+ else
+ {
+ gcmkFOOTER_NO();
+ return gcvSTATUS_NOT_SUPPORTED;
+ }
+
+ gcmkFOOTER_NO();
+ /* Success. */
+ return gcvSTATUS_OK;
+}
+
+/*******************************************************************************
+**
+** gckVGCOMMAND_ReturnCommand
+**
+** Append a RETURN command at the specified location in the command buffer.
+**
+** INPUT:
+**
+** gckVGCOMMAND Command
+** Pointer to an gckVGCOMMAND object.
+**
+** gctPOINTER Logical
+** Pointer to the current location inside the command buffer to append
+** RETURN command at or gcvNULL to query the size of the command.
+**
+** gctSIZE_T * Bytes
+** Pointer to the number of bytes available for the RETURN command.
+** If 'Logical' is gcvNULL, the value from this argument is ignored.
+**
+** OUTPUT:
+**
+** gctSIZE_T * Bytes
+** Pointer to a variable that will receive the number of bytes required
+** for the RETURN command. If 'Bytes' is gcvNULL, nothing is returned.
+*/
+gceSTATUS
+gckVGCOMMAND_ReturnCommand(
+ IN gckVGCOMMAND Command,
+ IN gctPOINTER Logical,
+ IN OUT gctUINT32 * Bytes
+ )
+{
+ gcmkHEADER_ARG("Command=0x%x Logical=0x%x Bytes = 0x%x",
+ Command, Logical, Bytes);
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Command, gcvOBJ_COMMAND);
+
+ if (Command->fe20)
+ {
+ if (Logical != gcvNULL)
+ {
+ gctUINT32_PTR buffer;
+
+ /* Cast the buffer pointer. */
+ buffer = (gctUINT32_PTR) Logical;
+
+ /* Append RETURN. */
+ gckOS_WriteMemory(
+ Command->os,
+ &buffer[0],
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:28) - (0 ?
+ 31:28) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:28) - (0 ?
+ 31:28) + 1))))))) << (0 ?
+ 31:28))) | (((gctUINT32) (0x7 & ((gctUINT32) ((((1 ?
+ 31:28) - (0 ?
+ 31:28) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:28) - (0 ? 31:28) + 1))))))) << (0 ? 31:28)))
+ );
+ }
+
+ if (Bytes != gcvNULL)
+ {
+ /* Return number of bytes required by the RETURN command. */
+ *Bytes = 8;
+ }
+ }
+ else
+ {
+ gcmkFOOTER_NO();
+ return gcvSTATUS_NOT_SUPPORTED;
+ }
+
+ gcmkFOOTER_NO();
+ /* Success. */
+ return gcvSTATUS_OK;
+}
+
+/*******************************************************************************
+**
+** gckVGCOMMAND_EventCommand
+**
+** Form an EVENT command at the specified location in the command buffer.
+**
+** INPUT:
+**
+** gckVGCOMMAND Command
+** Pointer to the Command object.
+**
+** gctPOINTER Logical
+** Pointer to the current location inside the command buffer to append
+** EVENT command at or gcvNULL to query the size of the command.
+**
+** gctINT32 InterruptId
+** The ID of the interrupt to generate.
+** If 'Logical' is gcvNULL, this argument is ignored.
+**
+** gceBLOCK Block
+** Block that will generate the interrupt.
+**
+** gctSIZE_T * Bytes
+** Pointer to the number of bytes available for the EVENT command.
+** If 'Logical' is gcvNULL, the value from this argument is ignored.
+**
+** OUTPUT:
+**
+** gctSIZE_T * Bytes
+** Pointer to a variable that will receive the number of bytes required
+** for the END command. If 'Bytes' is gcvNULL, nothing is returned.
+*/
+gceSTATUS
+gckVGCOMMAND_EventCommand(
+ IN gckVGCOMMAND Command,
+ IN gctPOINTER Logical,
+ IN gceBLOCK Block,
+ IN gctINT32 InterruptId,
+ IN OUT gctUINT32 * Bytes
+ )
+{
+ gcmkHEADER_ARG("Command=0x%x Logical=0x%x Block=0x%x InterruptId=0x%x Bytes = 0x%x",
+ Command, Logical, Block, InterruptId, Bytes);
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Command, gcvOBJ_COMMAND);
+
+ if (Command->fe20)
+ {
+ typedef struct _gcsEVENTSTATES
+ {
+ /* Chips before VG21 use these values. */
+ gctUINT eventFromFE;
+ gctUINT eventFromPE;
+
+ /* VG21 chips and later use SOURCE field. */
+ gctUINT eventSource;
+ }
+ gcsEVENTSTATES;
+
+ static gcsEVENTSTATES states[] =
+ {
+ /* gcvBLOCK_COMMAND */
+ {
+ (gctUINT)~0,
+ (gctUINT)~0,
+ (gctUINT)~0
+ },
+
+ /* gcvBLOCK_TESSELLATOR */
+ {
+ 0x0,
+ 0x1,
+ 0x10
+ },
+
+ /* gcvBLOCK_TESSELLATOR2 */
+ {
+ 0x0,
+ 0x1,
+ 0x12
+ },
+
+ /* gcvBLOCK_TESSELLATOR3 */
+ {
+ 0x0,
+ 0x1,
+ 0x14
+ },
+
+ /* gcvBLOCK_RASTER */
+ {
+ 0x0,
+ 0x1,
+ 0x07,
+ },
+
+ /* gcvBLOCK_VG */
+ {
+ 0x0,
+ 0x1,
+ 0x0F
+ },
+
+ /* gcvBLOCK_VG2 */
+ {
+ 0x0,
+ 0x1,
+ 0x11
+ },
+
+ /* gcvBLOCK_VG3 */
+ {
+ 0x0,
+ 0x1,
+ 0x13
+ },
+
+ /* gcvBLOCK_PIXEL */
+ {
+ 0x0,
+ 0x1,
+ 0x07
+ },
+ };
+
+ /* Verify block ID. */
+ gcmkVERIFY_ARGUMENT(gcmIS_VALID_INDEX(Block, states));
+
+ if (Logical != gcvNULL)
+ {
+ gctUINT32_PTR buffer;
+
+ /* Verify the event ID. */
+ gcmkVERIFY_ARGUMENT(InterruptId >= 0);
+ gcmkVERIFY_ARGUMENT(InterruptId <= ((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0U : (~(~0U << ((1 ? 4:0) - (0 ? 4:0) + 1))))));
+
+ /* Cast the buffer pointer. */
+ buffer = (gctUINT32_PTR) Logical;
+
+ /* Append EVENT. */
+ gckOS_WriteMemory(
+ Command->os,
+ &buffer[0],
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:28) - (0 ?
+ 31:28) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:28) - (0 ?
+ 31:28) + 1))))))) << (0 ?
+ 31:28))) | (((gctUINT32) (0x3 & ((gctUINT32) ((((1 ?
+ 31:28) - (0 ?
+ 31:28) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:28) - (0 ? 31:28) + 1))))))) << (0 ? 31:28)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 11:0) - (0 ?
+ 11:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 11:0) - (0 ?
+ 11:0) + 1))))))) << (0 ?
+ 11:0))) | (((gctUINT32) ((gctUINT32) (0x0E01) & ((gctUINT32) ((((1 ?
+ 11:0) - (0 ?
+ 11:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 11:0) - (0 ? 11:0) + 1))))))) << (0 ? 11:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 27:16) - (0 ?
+ 27:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 27:16) - (0 ?
+ 27:16) + 1))))))) << (0 ?
+ 27:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 27:16) - (0 ?
+ 27:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 27:16) - (0 ? 27:16) + 1))))))) << (0 ? 27:16)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 13:12) - (0 ?
+ 13:12) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 13:12) - (0 ?
+ 13:12) + 1))))))) << (0 ?
+ 13:12))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ?
+ 13:12) - (0 ?
+ 13:12) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 13:12) - (0 ? 13:12) + 1))))))) << (0 ? 13:12)))
+ );
+
+ /* Determine chip version. */
+ if (Command->vg21)
+ {
+ /* Get the event source for the block. */
+ gctUINT eventSource = states[Block].eventSource;
+
+ /* Supported? */
+ if (eventSource == ~0)
+ {
+ gcmkFOOTER_NO();
+ return gcvSTATUS_NOT_SUPPORTED;
+ }
+
+ buffer[1]
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1))))))) << (0 ?
+ 4:0))) | (((gctUINT32) ((gctUINT32) (InterruptId) & ((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1))))))) << (0 ?
+ 12:8))) | (((gctUINT32) ((gctUINT32) (eventSource) & ((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
+ }
+ else
+ {
+ /* Get the event source for the block. */
+ gctUINT eventFromFE = states[Block].eventFromFE;
+ gctUINT eventFromPE = states[Block].eventFromPE;
+
+ /* Supported? */
+ if (eventFromFE == ~0)
+ {
+ gcmkFOOTER_NO();
+ return gcvSTATUS_NOT_SUPPORTED;
+ }
+
+ buffer[1]
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1))))))) << (0 ?
+ 4:0))) | (((gctUINT32) ((gctUINT32) (InterruptId) & ((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 5:5) - (0 ?
+ 5:5) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 5:5) - (0 ?
+ 5:5) + 1))))))) << (0 ?
+ 5:5))) | (((gctUINT32) ((gctUINT32) (eventFromFE) & ((gctUINT32) ((((1 ?
+ 5:5) - (0 ?
+ 5:5) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 5:5) - (0 ? 5:5) + 1))))))) << (0 ? 5:5)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 6:6) - (0 ?
+ 6:6) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 6:6) - (0 ?
+ 6:6) + 1))))))) << (0 ?
+ 6:6))) | (((gctUINT32) ((gctUINT32) (eventFromPE) & ((gctUINT32) ((((1 ?
+ 6:6) - (0 ?
+ 6:6) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 6:6) - (0 ? 6:6) + 1))))))) << (0 ? 6:6)));
+ }
+ }
+
+ if (Bytes != gcvNULL)
+ {
+ /* Make sure the events are directly supported for the block. */
+ if (states[Block].eventSource == ~0)
+ {
+ gcmkFOOTER_NO();
+ return gcvSTATUS_NOT_SUPPORTED;
+ }
+
+ /* Return number of bytes required by the END command. */
+ *Bytes = 8;
+ }
+ }
+ else
+ {
+ if (Logical != gcvNULL)
+ {
+ gctUINT32_PTR buffer;
+
+ /* Verify the event ID. */
+ gcmkVERIFY_ARGUMENT(InterruptId >= 0);
+ gcmkVERIFY_ARGUMENT(InterruptId <= ((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0U : (~(~0U << ((1 ? 4:0) - (0 ? 4:0) + 1))))));
+
+ /* Cast the buffer pointer. */
+ buffer = (gctUINT32_PTR) Logical;
+
+ /* Append EVENT. */
+ gckOS_WriteMemory(
+ Command->os,
+ &buffer[0],
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E01) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+ );
+
+ /* Determine event source. */
+ if (Block == gcvBLOCK_COMMAND)
+ {
+ gckOS_WriteMemory(
+ Command->os,
+ &buffer[1],
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1))))))) << (0 ?
+ 4:0))) | (((gctUINT32) ((gctUINT32) (InterruptId) & ((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 5:5) - (0 ?
+ 5:5) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 5:5) - (0 ?
+ 5:5) + 1))))))) << (0 ?
+ 5:5))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 5:5) - (0 ?
+ 5:5) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 5:5) - (0 ? 5:5) + 1))))))) << (0 ? 5:5)))
+ );
+ }
+ else
+ {
+ gckOS_WriteMemory(
+ Command->os,
+ &buffer[1],
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1))))))) << (0 ?
+ 4:0))) | (((gctUINT32) ((gctUINT32) (InterruptId) & ((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 6:6) - (0 ?
+ 6:6) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 6:6) - (0 ?
+ 6:6) + 1))))))) << (0 ?
+ 6:6))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 6:6) - (0 ?
+ 6:6) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 6:6) - (0 ? 6:6) + 1))))))) << (0 ? 6:6)))
+ );
+ }
+ }
+
+ if (Bytes != gcvNULL)
+ {
+ /* Return number of bytes required by the EVENT and END commands. */
+ *Bytes = 8;
+ }
+ }
+
+ gcmkFOOTER_NO();
+ /* Success. */
+ return gcvSTATUS_OK;
+}
+
+/*******************************************************************************
+**
+** gckVGCOMMAND_EndCommand
+**
+** Form an END command at the specified location in the command buffer.
+**
+** INPUT:
+**
+** gckVGCOMMAND Command
+** Pointer to the Command object.
+**
+** gctPOINTER Logical
+** Pointer to the current location inside the command buffer to append
+** END command at or gcvNULL to query the size of the command.
+**
+** gctINT32 InterruptId
+** The ID of the interrupt to generate.
+** If 'Logical' is gcvNULL, this argument will be ignored.
+**
+** gctSIZE_T * Bytes
+** Pointer to the number of bytes available for the END command.
+** If 'Logical' is gcvNULL, the value from this argument is ignored.
+**
+** OUTPUT:
+**
+** gctSIZE_T * Bytes
+** Pointer to a variable that will receive the number of bytes required
+** for the END command. If 'Bytes' is gcvNULL, nothing is returned.
+*/
+gceSTATUS
+gckVGCOMMAND_EndCommand(
+ IN gckVGCOMMAND Command,
+ IN gctPOINTER Logical,
+ IN gctINT32 InterruptId,
+ IN OUT gctUINT32 * Bytes
+ )
+{
+ gcmkHEADER_ARG("Command=0x%x Logical=0x%x InterruptId=0x%x Bytes = 0x%x",
+ Command, Logical, InterruptId, Bytes);
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Command, gcvOBJ_COMMAND);
+
+ if (Command->fe20)
+ {
+ if (Logical != gcvNULL)
+ {
+ gctUINT32_PTR buffer;
+
+ /* Verify the event ID. */
+ gcmkVERIFY_ARGUMENT(InterruptId >= 0);
+
+ /* Cast the buffer pointer. */
+ buffer = (gctUINT32_PTR) Logical;
+
+ /* Append END. */
+ gckOS_WriteMemory(
+ Command->os,
+ &buffer[0],
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:28) - (0 ?
+ 31:28) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:28) - (0 ?
+ 31:28) + 1))))))) << (0 ?
+ 31:28))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ?
+ 31:28) - (0 ?
+ 31:28) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:28) - (0 ? 31:28) + 1))))))) << (0 ? 31:28)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1))))))) << (0 ?
+ 4:0))) | (((gctUINT32) ((gctUINT32) (InterruptId) & ((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
+ );
+ }
+
+ if (Bytes != gcvNULL)
+ {
+ /* Return number of bytes required by the END command. */
+ *Bytes = 8;
+ }
+ }
+ else
+ {
+ if (Logical != gcvNULL)
+ {
+ gctUINT32_PTR memory;
+
+ /* Verify the event ID. */
+ gcmkVERIFY_ARGUMENT(InterruptId >= 0);
+
+ /* Cast the buffer pointer. */
+ memory = (gctUINT32_PTR) Logical;
+
+ /* Append EVENT. */
+ gckOS_WriteMemory(
+ Command->os,
+ &memory[0],
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E01) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+ );
+
+ gckOS_WriteMemory(
+ Command->os,
+ &memory[1],
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1))))))) << (0 ?
+ 4:0))) | (((gctUINT32) ((gctUINT32) (InterruptId) & ((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 6:6) - (0 ?
+ 6:6) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 6:6) - (0 ?
+ 6:6) + 1))))))) << (0 ?
+ 6:6))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 6:6) - (0 ?
+ 6:6) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 6:6) - (0 ? 6:6) + 1))))))) << (0 ? 6:6)))
+ );
+
+ /* Append END. */
+ gckOS_WriteMemory(
+ Command->os,
+ &memory[2],
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x02 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ );
+ }
+
+ if (Bytes != gcvNULL)
+ {
+ /* Return number of bytes required by the EVENT and END commands. */
+ *Bytes = 16;
+ }
+ }
+
+ gcmkFOOTER_NO();
+ /* Success. */
+ return gcvSTATUS_OK;
+}
+
+#endif /* gcdENABLE_VG */
+
diff --git a/drivers/mxc/gpu-viv/hal/kernel/archvg/gc_hal_kernel_hardware_command_vg.h b/drivers/mxc/gpu-viv/hal/kernel/archvg/gc_hal_kernel_hardware_command_vg.h
new file mode 100644
index 000000000000..ab495f57b512
--- /dev/null
+++ b/drivers/mxc/gpu-viv/hal/kernel/archvg/gc_hal_kernel_hardware_command_vg.h
@@ -0,0 +1,353 @@
+/****************************************************************************
+*
+* The MIT License (MIT)
+*
+* Copyright (c) 2014 - 2018 Vivante 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 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 GPL License (GPL)
+*
+* Copyright (C) 2014 - 2018 Vivante 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.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+*****************************************************************************
+*
+* Note: This software is released under dual MIT and GPL licenses. A
+* recipient may use this file under the terms of either the MIT license or
+* GPL License. If you wish to use only one license not the other, you can
+* indicate your decision by deleting one of the above license notices in your
+* version of this file.
+*
+*****************************************************************************/
+
+
+#ifndef __gc_hal_kernel_hardware_command_vg_h_
+#define __gc_hal_kernel_hardware_command_vg_h_
+
+/******************************************************************************\
+******************* Task and Interrupt Management Structures. ******************
+\******************************************************************************/
+
+/* Task storage header. */
+typedef struct _gcsTASK_STORAGE * gcsTASK_STORAGE_PTR;
+typedef struct _gcsTASK_STORAGE
+{
+ /* Next allocated storage buffer. */
+ gcsTASK_STORAGE_PTR next;
+}
+gcsTASK_STORAGE;
+
+/* Task container header. */
+typedef struct _gcsTASK_CONTAINER * gcsTASK_CONTAINER_PTR;
+typedef struct _gcsTASK_CONTAINER
+{
+ /* The number of tasks left to be processed in the container. */
+ gctINT referenceCount;
+
+ /* Size of the buffer. */
+ gctUINT size;
+
+ /* Link to the previous and the next allocated containers. */
+ gcsTASK_CONTAINER_PTR allocPrev;
+ gcsTASK_CONTAINER_PTR allocNext;
+
+ /* Link to the previous and the next containers in the free list. */
+ gcsTASK_CONTAINER_PTR freePrev;
+ gcsTASK_CONTAINER_PTR freeNext;
+}
+gcsTASK_CONTAINER;
+
+/* Kernel space task master table entry. */
+typedef struct _gcsBLOCK_TASK_ENTRY * gcsBLOCK_TASK_ENTRY_PTR;
+typedef struct _gcsBLOCK_TASK_ENTRY
+{
+ /* Pointer to the current task container for the block. */
+ gcsTASK_CONTAINER_PTR container;
+
+ /* Pointer to the current task data within the container. */
+ gcsTASK_HEADER_PTR task;
+
+ /* Pointer to the last link task within the container. */
+ gcsTASK_LINK_PTR link;
+
+ /* Number of interrupts allocated for this block. */
+ gctUINT interruptCount;
+
+ /* The index of the current interrupt. */
+ gctUINT interruptIndex;
+
+ /* Interrupt semaphore. */
+ gctSEMAPHORE interruptSemaphore;
+
+ /* Interrupt value array. */
+ gctINT32 interruptArray[32];
+}
+gcsBLOCK_TASK_ENTRY;
+
+
+/******************************************************************************\
+********************* Command Queue Management Structures. *********************
+\******************************************************************************/
+
+/* Command queue kernel element pointer. */
+typedef struct _gcsKERNEL_CMDQUEUE * gcsKERNEL_CMDQUEUE_PTR;
+
+/* Command queue object handler function type. */
+typedef gceSTATUS (* gctOBJECT_HANDLER) (
+ gckVGKERNEL Kernel,
+ gcsKERNEL_CMDQUEUE_PTR Entry
+ );
+
+/* Command queue kernel element. */
+typedef struct _gcsKERNEL_CMDQUEUE
+{
+ /* The number of buffers in the queue. */
+ gcsCMDBUFFER_PTR commandBuffer;
+
+ /* Pointer to the object handler function. */
+ gctOBJECT_HANDLER handler;
+}
+gcsKERNEL_CMDQUEUE;
+
+/* Command queue header. */
+typedef struct _gcsKERNEL_QUEUE_HEADER * gcsKERNEL_QUEUE_HEADER_PTR;
+typedef struct _gcsKERNEL_QUEUE_HEADER
+{
+ /* The size of the buffer in bytes. */
+ gctUINT size;
+
+ /* The number of pending entries to be processed. */
+ volatile gctUINT pending;
+
+ /* The current command queue entry. */
+ gcsKERNEL_CMDQUEUE_PTR currentEntry;
+
+ /* Next buffer. */
+ gcsKERNEL_QUEUE_HEADER_PTR next;
+}
+gcsKERNEL_QUEUE_HEADER;
+
+
+/******************************************************************************\
+******************************* gckVGCOMMAND Object *******************************
+\******************************************************************************/
+
+/* gckVGCOMMAND object. */
+struct _gckVGCOMMAND
+{
+ /***************************************************************************
+ ** Object data and pointers.
+ */
+
+ gcsOBJECT object;
+ gckVGKERNEL kernel;
+ gckOS os;
+ gckVGHARDWARE hardware;
+
+ /* Features. */
+ gctBOOL fe20;
+ gctBOOL vg20;
+ gctBOOL vg21;
+
+
+ /***************************************************************************
+ ** Enable command queue dumping.
+ */
+
+ gctBOOL enableDumping;
+
+
+ /***************************************************************************
+ ** Bus Error interrupt.
+ */
+
+ gctINT32 busErrorInt;
+
+
+ /***************************************************************************
+ ** Command buffer information.
+ */
+
+ gcsCOMMAND_BUFFER_INFO info;
+
+
+ /***************************************************************************
+ ** Synchronization objects.
+ */
+
+ gctPOINTER queueMutex;
+ gctPOINTER taskMutex;
+ gctPOINTER commitMutex;
+
+
+ /***************************************************************************
+ ** Task management.
+ */
+
+ /* The head of the storage buffer linked list. */
+ gcsTASK_STORAGE_PTR taskStorage;
+
+ /* Allocation size. */
+ gctUINT taskStorageGranularity;
+ gctUINT taskStorageUsable;
+
+ /* The free container list. */
+ gcsTASK_CONTAINER_PTR taskFreeHead;
+ gcsTASK_CONTAINER_PTR taskFreeTail;
+
+ /* Task table */
+ gcsBLOCK_TASK_ENTRY taskTable[gcvBLOCK_COUNT];
+
+
+ /***************************************************************************
+ ** Command queue.
+ */
+
+ /* Pointer to the allocated queue memory. */
+ gcsKERNEL_QUEUE_HEADER_PTR queue;
+
+ /* Pointer to the current available queue from which new queue entries
+ will be allocated. */
+ gcsKERNEL_QUEUE_HEADER_PTR queueHead;
+
+ /* If different from queueHead, points to the command queue which is
+ currently being executed by the hardware. */
+ gcsKERNEL_QUEUE_HEADER_PTR queueTail;
+
+ /* Points to the queue to merge the tail with when the tail is processed. */
+ gcsKERNEL_QUEUE_HEADER_PTR mergeQueue;
+
+ /* Queue overflow counter. */
+ gctUINT queueOverflow;
+
+
+ /***************************************************************************
+ ** Context.
+ */
+
+ /* Context counter used for unique ID. */
+ gctUINT64 contextCounter;
+
+ /* Current context ID. */
+ gctUINT64 currentContext;
+
+ /* Command queue power semaphore. */
+ gctPOINTER powerSemaphore;
+ gctINT32 powerStallInt;
+ gcsCMDBUFFER_PTR powerStallBuffer;
+ gctSIGNAL powerStallSignal;
+
+};
+
+/******************************************************************************\
+************************ gckVGCOMMAND Object Internal API. ***********************
+\******************************************************************************/
+
+/* Initialize architecture dependent command buffer information. */
+gceSTATUS
+gckVGCOMMAND_InitializeInfo(
+ IN gckVGCOMMAND Command
+ );
+
+/* Form a STATE command at the specified location in the command buffer. */
+gceSTATUS
+gckVGCOMMAND_StateCommand(
+ IN gckVGCOMMAND Command,
+ IN gctUINT32 Pipe,
+ IN gctPOINTER Logical,
+ IN gctUINT32 Address,
+ IN gctUINT32 Count,
+ IN OUT gctUINT32 * Bytes
+ );
+
+/* Form a RESTART command at the specified location in the command buffer. */
+gceSTATUS
+gckVGCOMMAND_RestartCommand(
+ IN gckVGCOMMAND Command,
+ IN gctPOINTER Logical,
+ IN gctUINT32 FetchAddress,
+ IN gctUINT FetchCount,
+ IN OUT gctUINT32 * Bytes
+ );
+
+/* Form a FETCH command at the specified location in the command buffer. */
+gceSTATUS
+gckVGCOMMAND_FetchCommand(
+ IN gckVGCOMMAND Command,
+ IN gctPOINTER Logical,
+ IN gctUINT32 FetchAddress,
+ IN gctUINT FetchCount,
+ IN OUT gctUINT32 * Bytes
+ );
+
+/* Form a CALL command at the specified location in the command buffer. */
+gceSTATUS
+gckVGCOMMAND_CallCommand(
+ IN gckVGCOMMAND Command,
+ IN gctPOINTER Logical,
+ IN gctUINT32 FetchAddress,
+ IN gctUINT FetchCount,
+ IN OUT gctUINT32 * Bytes
+ );
+
+/* Form a RETURN command at the specified location in the command buffer. */
+gceSTATUS
+gckVGCOMMAND_ReturnCommand(
+ IN gckVGCOMMAND Command,
+ IN gctPOINTER Logical,
+ IN OUT gctUINT32 * Bytes
+ );
+
+/* Form an EVENT command at the specified location in the command buffer. */
+gceSTATUS
+gckVGCOMMAND_EventCommand(
+ IN gckVGCOMMAND Command,
+ IN gctPOINTER Logical,
+ IN gceBLOCK Block,
+ IN gctINT32 InterruptId,
+ IN OUT gctUINT32 * Bytes
+ );
+
+/* Form an END command at the specified location in the command buffer. */
+gceSTATUS
+gckVGCOMMAND_EndCommand(
+ IN gckVGCOMMAND Command,
+ IN gctPOINTER Logical,
+ IN gctINT32 InterruptId,
+ IN OUT gctUINT32 * Bytes
+ );
+
+#endif /* __gc_hal_kernel_hardware_command_h_ */
+
diff --git a/drivers/mxc/gpu-viv/hal/kernel/archvg/gc_hal_kernel_hardware_vg.c b/drivers/mxc/gpu-viv/hal/kernel/archvg/gc_hal_kernel_hardware_vg.c
new file mode 100644
index 000000000000..3b96bc0f3d73
--- /dev/null
+++ b/drivers/mxc/gpu-viv/hal/kernel/archvg/gc_hal_kernel_hardware_vg.c
@@ -0,0 +1,2450 @@
+/****************************************************************************
+*
+* The MIT License (MIT)
+*
+* Copyright (c) 2014 - 2018 Vivante 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 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 GPL License (GPL)
+*
+* Copyright (C) 2014 - 2018 Vivante 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.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+*****************************************************************************
+*
+* Note: This software is released under dual MIT and GPL licenses. A
+* recipient may use this file under the terms of either the MIT license or
+* GPL License. If you wish to use only one license not the other, you can
+* indicate your decision by deleting one of the above license notices in your
+* version of this file.
+*
+*****************************************************************************/
+
+
+#include "gc_hal.h"
+#include "gc_hal_kernel.h"
+#include "gc_hal_kernel_hardware_command_vg.h"
+
+#include "gc_feature_database.h"
+
+#if gcdENABLE_VG
+
+#define _GC_OBJ_ZONE gcvZONE_HARDWARE
+
+typedef enum
+{
+ gcvPOWER_FLAG_INITIALIZE = 1 << 0,
+ gcvPOWER_FLAG_STALL = 1 << 1,
+ gcvPOWER_FLAG_STOP = 1 << 2,
+ gcvPOWER_FLAG_START = 1 << 3,
+ gcvPOWER_FLAG_RELEASE = 1 << 4,
+ gcvPOWER_FLAG_DELAY = 1 << 5,
+ gcvPOWER_FLAG_SAVE = 1 << 6,
+ gcvPOWER_FLAG_ACQUIRE = 1 << 7,
+ gcvPOWER_FLAG_POWER_OFF = 1 << 8,
+ gcvPOWER_FLAG_CLOCK_OFF = 1 << 9,
+ gcvPOWER_FLAG_CLOCK_ON = 1 << 10,
+ gcvPOWER_FLAG_NOP = 1 << 11,
+}
+gcePOWER_FLAGS;
+
+/******************************************************************************\
+********************************* Support Code *********************************
+\******************************************************************************/
+static gceSTATUS
+_ResetGPU(
+ IN gckOS Os
+ )
+{
+ gctUINT32 control, idle;
+ gceSTATUS status;
+
+ /* Read register. */
+ gcmkONERROR(gckOS_ReadRegisterEx(Os,
+ gcvCORE_VG,
+ 0x00000,
+ &control));
+
+ for (;;)
+ {
+ /* Disable clock gating. */
+ gcmkONERROR(gckOS_WriteRegisterEx(Os,
+ gcvCORE_VG,
+ 0x00104,
+ 0x00000000));
+
+ /* Wait for clock being stable. */
+ gcmkONERROR(gckOS_Delay(Os, 1));
+
+ /* Isolate the GPU. */
+ control = ((((gctUINT32) (control)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 19:19) - (0 ?
+ 19:19) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 19:19) - (0 ?
+ 19:19) + 1))))))) << (0 ?
+ 19:19))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 19:19) - (0 ?
+ 19:19) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 19:19) - (0 ? 19:19) + 1))))))) << (0 ? 19:19)));
+
+ gcmkONERROR(gckOS_WriteRegisterEx(Os,
+ gcvCORE_VG,
+ 0x00000,
+ control));
+
+ /* Set soft reset. */
+ gcmkONERROR(gckOS_WriteRegisterEx(Os,
+ gcvCORE_VG,
+ 0x00000,
+ ((((gctUINT32) (control)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 12:12) - (0 ?
+ 12:12) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 12:12) - (0 ?
+ 12:12) + 1))))))) << (0 ?
+ 12:12))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 12:12) - (0 ?
+ 12:12) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 12:12) - (0 ? 12:12) + 1))))))) << (0 ? 12:12)))));
+
+ /* Wait for reset. */
+ gcmkONERROR(gckOS_Delay(Os, 1));
+
+ /* Reset soft reset bit. */
+ gcmkONERROR(gckOS_WriteRegisterEx(Os,
+ gcvCORE_VG,
+ 0x00000,
+ ((((gctUINT32) (control)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 12:12) - (0 ?
+ 12:12) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 12:12) - (0 ?
+ 12:12) + 1))))))) << (0 ?
+ 12:12))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ?
+ 12:12) - (0 ?
+ 12:12) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 12:12) - (0 ? 12:12) + 1))))))) << (0 ? 12:12)))));
+
+ /* Reset GPU isolation. */
+ control = ((((gctUINT32) (control)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 19:19) - (0 ?
+ 19:19) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 19:19) - (0 ?
+ 19:19) + 1))))))) << (0 ?
+ 19:19))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ?
+ 19:19) - (0 ?
+ 19:19) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 19:19) - (0 ? 19:19) + 1))))))) << (0 ? 19:19)));
+
+ gcmkONERROR(gckOS_WriteRegisterEx(Os,
+ gcvCORE_VG,
+ 0x00000,
+ control));
+
+ /* Read idle register. */
+ gcmkONERROR(gckOS_ReadRegisterEx(Os,
+ gcvCORE_VG,
+ 0x00004,
+ &idle));
+
+ if ((((((gctUINT32) (idle)) >> (0 ? 0:0)) & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1)))))) ) == 0)
+ {
+ continue;
+ }
+
+ /* Read reset register. */
+ gcmkONERROR(gckOS_ReadRegisterEx(Os,
+ gcvCORE_VG,
+ 0x00000,
+ &control));
+
+ if (((((((gctUINT32) (control)) >> (0 ? 16:16)) & ((gctUINT32) ((((1 ? 16:16) - (0 ? 16:16) + 1) == 32) ? ~0U : (~(~0U << ((1 ? 16:16) - (0 ? 16:16) + 1)))))) ) == 0)
+ || ((((((gctUINT32) (control)) >> (0 ? 17:17)) & ((gctUINT32) ((((1 ? 17:17) - (0 ? 17:17) + 1) == 32) ? ~0U : (~(~0U << ((1 ? 17:17) - (0 ? 17:17) + 1)))))) ) == 0)
+ )
+ {
+ continue;
+ }
+
+ /* GPU is idle. */
+ break;
+ }
+
+ /* Success. */
+ return gcvSTATUS_OK;
+
+OnError:
+
+ /* Return the error. */
+ return status;
+}
+
+
+static gceSTATUS
+_IdentifyHardware(
+ IN gckOS Os,
+ IN gckVGHARDWARE Hardware,
+ OUT gceCHIPMODEL * ChipModel,
+ OUT gctUINT32 * ChipRevision,
+ OUT gctUINT32 * ChipFeatures,
+ OUT gctUINT32 * ChipMinorFeatures,
+ OUT gctUINT32 * ChipMinorFeatures2
+ )
+{
+ gceSTATUS status;
+ gctUINT32 chipIdentity;
+
+ do
+ {
+ /* Read chip identity register. */
+ gcmkERR_BREAK(gckOS_ReadRegisterEx(Os, gcvCORE_VG, 0x00018, &chipIdentity));
+
+ /* Special case for older graphic cores. */
+ if (((((gctUINT32) (chipIdentity)) >> (0 ?
+ 31:24) & ((gctUINT32) ((((1 ?
+ 31:24) - (0 ?
+ 31:24) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:24) - (0 ?
+ 31:24) + 1)))))) == (0x01 & ((gctUINT32) ((((1 ?
+ 31:24) - (0 ?
+ 31:24) + 1) == 32) ? ~0U : (~(~0U << ((1 ? 31:24) - (0 ? 31:24) + 1))))))))
+ {
+ *ChipModel = gcv500;
+ *ChipRevision = (((((gctUINT32) (chipIdentity)) >> (0 ? 15:12)) & ((gctUINT32) ((((1 ? 15:12) - (0 ? 15:12) + 1) == 32) ? ~0U : (~(~0U << ((1 ? 15:12) - (0 ? 15:12) + 1)))))) );
+ }
+
+ else
+ {
+ /* Read chip identity register. */
+ gcmkERR_BREAK(gckOS_ReadRegisterEx(Os, gcvCORE_VG,
+ 0x00020,
+ (gctUINT32 *) ChipModel));
+
+ /* Read CHIP_REV register. */
+ gcmkERR_BREAK(gckOS_ReadRegisterEx(Os, gcvCORE_VG,
+ 0x00024,
+ ChipRevision));
+ }
+
+ /* Read chip feature register. */
+ gcmkERR_BREAK(gckOS_ReadRegisterEx(
+ Os, gcvCORE_VG, 0x0001C, ChipFeatures
+ ));
+
+ /* Read chip minor feature register. */
+ gcmkERR_BREAK(gckOS_ReadRegisterEx(
+ Os, gcvCORE_VG, 0x00034, ChipMinorFeatures
+ ));
+
+ /* Read chip minor feature register #2. */
+ gcmkERR_BREAK(gckOS_ReadRegisterEx(
+ Os, gcvCORE_VG, 0x00074, ChipMinorFeatures2
+ ));
+
+ gcmkERR_BREAK(gckOS_ReadRegisterEx(
+ Os, gcvCORE_VG, 0x000A8, &Hardware->productID
+ ));
+
+ gcmkERR_BREAK(gckOS_ReadRegisterEx(
+ Os, gcvCORE_VG, 0x000E8, &Hardware->ecoID
+ ));
+
+ gcmkERR_BREAK(gckOS_ReadRegisterEx(
+ Os, gcvCORE_VG, 0x00030, &Hardware->customerID
+ ));
+
+ gcmkTRACE(
+ gcvLEVEL_VERBOSE,
+ "ChipModel=0x%08X\n"
+ "ChipRevision=0x%08X\n"
+ "ChipFeatures=0x%08X\n"
+ "ChipMinorFeatures=0x%08X\n"
+ "ChipMinorFeatures2=0x%08X\n",
+ *ChipModel,
+ *ChipRevision,
+ *ChipFeatures,
+ *ChipMinorFeatures,
+ *ChipMinorFeatures2
+ );
+
+ /* Success. */
+ return gcvSTATUS_OK;
+ }
+ while (gcvFALSE);
+
+ /* Return the status. */
+ return status;
+}
+
+#if gcdPOWEROFF_TIMEOUT
+void
+_VGPowerTimerFunction(
+ gctPOINTER Data
+ )
+{
+ gckVGHARDWARE hardware = (gckVGHARDWARE)Data;
+ gcmkVERIFY_OK(
+ gckVGHARDWARE_SetPowerManagementState(hardware, gcvPOWER_OFF_TIMEOUT));
+}
+#endif
+
+/******************************************************************************\
+****************************** gckVGHARDWARE API code *****************************
+\******************************************************************************/
+
+/*******************************************************************************
+**
+** gckVGHARDWARE_Construct
+**
+** Construct a new gckVGHARDWARE object.
+**
+** INPUT:
+**
+** gckOS Os
+** Pointer to an initialized gckOS object.
+**
+** OUTPUT:
+**
+** gckVGHARDWARE * Hardware
+** Pointer to a variable that will hold the pointer to the gckVGHARDWARE
+** object.
+*/
+gceSTATUS
+gckVGHARDWARE_Construct(
+ IN gckOS Os,
+ OUT gckVGHARDWARE * Hardware
+ )
+{
+ gckVGHARDWARE hardware = gcvNULL;
+ gceSTATUS status;
+ gceCHIPMODEL chipModel;
+ gctUINT32 chipRevision;
+ gctUINT32 chipFeatures;
+ gctUINT32 chipMinorFeatures;
+ gctUINT32 chipMinorFeatures2;
+ gcsFEATURE_DATABASE * database;
+
+ gcmkHEADER_ARG("Os=0x%x Hardware=0x%x ", Os, Hardware);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
+ gcmkVERIFY_ARGUMENT(Hardware != gcvNULL);
+
+ do
+ {
+ gcmkERR_BREAK(gckOS_SetGPUPower(Os, gcvCORE_VG, gcvTRUE, gcvTRUE));
+
+ status = _ResetGPU(Os);
+
+ if (status != gcvSTATUS_OK)
+ {
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
+ "_ResetGPU failed: status=%d\n", status);
+ }
+
+ /* Allocate the gckVGHARDWARE object. */
+ gcmkERR_BREAK(gckOS_Allocate(Os,
+ gcmSIZEOF(struct _gckVGHARDWARE), (gctPOINTER *) &hardware
+ ));
+
+ /* Identify the hardware. */
+ gcmkERR_BREAK(_IdentifyHardware(Os, hardware,
+ &chipModel, &chipRevision,
+ &chipFeatures, &chipMinorFeatures, &chipMinorFeatures2
+ ));
+
+ /* Initialize the gckVGHARDWARE object. */
+ hardware->object.type = gcvOBJ_HARDWARE;
+ hardware->os = Os;
+
+ /* Set chip identity. */
+ hardware->chipModel = chipModel;
+ hardware->chipRevision = chipRevision;
+ hardware->chipFeatures = chipFeatures;
+ hardware->chipMinorFeatures = chipMinorFeatures;
+ hardware->chipMinorFeatures2 = chipMinorFeatures2;
+
+ hardware->powerMutex = gcvNULL;
+ hardware->chipPowerState = gcvPOWER_ON;
+ hardware->chipPowerStateGlobal = gcvPOWER_ON;
+ hardware->clockState = gcvTRUE;
+ hardware->powerState = gcvTRUE;
+
+#if gcdPOWEROFF_TIMEOUT
+ hardware->powerOffTime = 0;
+ hardware->powerOffTimeout = gcdPOWEROFF_TIMEOUT;
+
+ gcmkVERIFY_OK(gckOS_CreateTimer(Os,
+ _VGPowerTimerFunction,
+ (gctPOINTER)hardware,
+ &hardware->powerOffTimer));
+#endif
+
+ database = hardware->featureDatabase = gcQueryFeatureDB(
+ hardware->chipModel,
+ hardware->chipRevision,
+ hardware->productID,
+ hardware->ecoID,
+ hardware->customerID
+ );
+
+ if (database == gcvNULL)
+ {
+ gcmkPRINT("[galcore]: Feature database is not found,"
+ "chipModel=0x%0x, chipRevision=0x%x, productID=0x%x, ecoID=0x%x",
+ hardware->chipModel,
+ hardware->chipRevision,
+ hardware->productID,
+ hardware->ecoID);
+ /* gcmkERR_BREAK(gcvSTATUS_NOT_FOUND); */
+ }
+
+ /* Determine whether FE 2.0 is present. */
+ hardware->fe20 = ((((gctUINT32) (hardware->chipFeatures)) >> (0 ?
+ 28:28) & ((gctUINT32) ((((1 ?
+ 28:28) - (0 ?
+ 28:28) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 28:28) - (0 ?
+ 28:28) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ?
+ 28:28) - (0 ?
+ 28:28) + 1) == 32) ? ~0U : (~(~0U << ((1 ? 28:28) - (0 ? 28:28) + 1)))))));
+
+ /* Determine whether VG 2.0 is present. */
+ hardware->vg20 = ((((gctUINT32) (hardware->chipMinorFeatures)) >> (0 ?
+ 13:13) & ((gctUINT32) ((((1 ?
+ 13:13) - (0 ?
+ 13:13) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 13:13) - (0 ?
+ 13:13) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ?
+ 13:13) - (0 ?
+ 13:13) + 1) == 32) ? ~0U : (~(~0U << ((1 ? 13:13) - (0 ? 13:13) + 1)))))));
+
+ /* Determine whether VG 2.1 is present. */
+ hardware->vg21 = ((((gctUINT32) (hardware->chipMinorFeatures)) >> (0 ?
+ 18:18) & ((gctUINT32) ((((1 ?
+ 18:18) - (0 ?
+ 18:18) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 18:18) - (0 ?
+ 18:18) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ?
+ 18:18) - (0 ?
+ 18:18) + 1) == 32) ? ~0U : (~(~0U << ((1 ? 18:18) - (0 ? 18:18) + 1)))))));
+
+ /* Determine whether fc is present. */
+ hardware->fc = (((((gctUINT32) (hardware->chipFeatures)) >> (0 ? 0:0 )) & ((gctUINT32) ((((1 ? 0:0 ) - (0 ? 0:0 ) + 1) == 32) ? ~0U : (~(~0U << ((1 ? 0:0 ) - (0 ? 0:0 ) + 1)))))) );
+
+
+ /* Set default event mask. */
+ hardware->eventMask = 0xFFFFFFFF;
+
+ gcmkERR_BREAK(gckOS_AtomConstruct(Os, &hardware->pageTableDirty));
+
+ /* Set fast clear to auto. */
+ gcmkVERIFY_OK(gckVGHARDWARE_SetFastClear(hardware, -1));
+
+ gcmkERR_BREAK(gckOS_CreateMutex(Os, &hardware->powerMutex));
+
+ /* Enable power management by default. */
+ hardware->options.powerManagement = gcvTRUE;
+
+ /* Return pointer to the gckVGHARDWARE object. */
+ *Hardware = hardware;
+
+ gcmkFOOTER_NO();
+ /* Success. */
+ return gcvSTATUS_OK;
+ }
+ while (gcvFALSE);
+
+#if gcdPOWEROFF_TIMEOUT
+ if (hardware != gcvNULL && hardware->powerOffTimer != gcvNULL)
+ {
+ gcmkVERIFY_OK(gckOS_StopTimer(Os, hardware->powerOffTimer));
+ gcmkVERIFY_OK(gckOS_DestroyTimer(Os, hardware->powerOffTimer));
+ }
+#endif
+
+ gcmkVERIFY_OK(gckOS_SetGPUPower(Os, gcvCORE_VG, gcvFALSE, gcvFALSE));
+
+ if (hardware != gcvNULL && hardware->pageTableDirty != gcvNULL)
+ {
+ gcmkVERIFY_OK(gckOS_AtomDestroy(Os, hardware->pageTableDirty));
+ }
+
+ if (hardware != gcvNULL)
+ {
+ gcmkVERIFY_OK(gckOS_Free(Os, hardware));
+ }
+
+ gcmkFOOTER();
+ /* Return the status. */
+ return status;
+}
+
+/*******************************************************************************
+**
+** gckVGHARDWARE_Destroy
+**
+** Destroy an gckVGHARDWARE object.
+**
+** INPUT:
+**
+** gckVGHARDWARE Hardware
+** Pointer to the gckVGHARDWARE object that needs to be destroyed.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckVGHARDWARE_Destroy(
+ IN gckVGHARDWARE Hardware
+ )
+{
+ gceSTATUS status;
+ gcmkHEADER_ARG("Hardware=0x%x ", Hardware);
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
+
+ /* Mark the object as unknown. */
+ Hardware->object.type = gcvOBJ_UNKNOWN;
+
+ if (Hardware->powerMutex != gcvNULL)
+ {
+ gcmkVERIFY_OK(gckOS_DeleteMutex(
+ Hardware->os, Hardware->powerMutex));
+ }
+
+#if gcdPOWEROFF_TIMEOUT
+ gcmkVERIFY_OK(gckOS_StopTimer(Hardware->os, Hardware->powerOffTimer));
+ gcmkVERIFY_OK(gckOS_DestroyTimer(Hardware->os, Hardware->powerOffTimer));
+#endif
+
+ if (Hardware->pageTableDirty != gcvNULL)
+ {
+ gcmkVERIFY_OK(gckOS_AtomDestroy(Hardware->os, Hardware->pageTableDirty));
+ }
+
+ /* Free the object. */
+ status = gckOS_Free(Hardware->os, Hardware);
+ gcmkFOOTER();
+ return status;
+}
+
+/*******************************************************************************
+**
+** gckVGHARDWARE_QueryMemory
+**
+** Query the amount of memory available on the hardware.
+**
+** INPUT:
+**
+** gckVGHARDWARE Hardware
+** Pointer to the gckVGHARDWARE object.
+**
+** OUTPUT:
+**
+** gctSIZE_T * InternalSize
+** Pointer to a variable that will hold the size of the internal video
+** memory in bytes. If 'InternalSize' is gcvNULL, no information of the
+** internal memory will be returned.
+**
+** gctUINT32 * InternalBaseAddress
+** Pointer to a variable that will hold the hardware's base address for
+** the internal video memory. This pointer cannot be gcvNULL if
+** 'InternalSize' is also non-gcvNULL.
+**
+** gctUINT32 * InternalAlignment
+** Pointer to a variable that will hold the hardware's base address for
+** the internal video memory. This pointer cannot be gcvNULL if
+** 'InternalSize' is also non-gcvNULL.
+**
+** gctSIZE_T * ExternalSize
+** Pointer to a variable that will hold the size of the external video
+** memory in bytes. If 'ExternalSize' is gcvNULL, no information of the
+** external memory will be returned.
+**
+** gctUINT32 * ExternalBaseAddress
+** Pointer to a variable that will hold the hardware's base address for
+** the external video memory. This pointer cannot be gcvNULL if
+** 'ExternalSize' is also non-gcvNULL.
+**
+** gctUINT32 * ExternalAlignment
+** Pointer to a variable that will hold the hardware's base address for
+** the external video memory. This pointer cannot be gcvNULL if
+** 'ExternalSize' is also non-gcvNULL.
+**
+** gctUINT32 * HorizontalTileSize
+** Number of horizontal pixels per tile. If 'HorizontalTileSize' is
+** gcvNULL, no horizontal pixel per tile will be returned.
+**
+** gctUINT32 * VerticalTileSize
+** Number of vertical pixels per tile. If 'VerticalTileSize' is
+** gcvNULL, no vertical pixel per tile will be returned.
+*/
+gceSTATUS
+gckVGHARDWARE_QueryMemory(
+ IN gckVGHARDWARE Hardware,
+ OUT gctSIZE_T * InternalSize,
+ OUT gctUINT32 * InternalBaseAddress,
+ OUT gctUINT32 * InternalAlignment,
+ OUT gctSIZE_T * ExternalSize,
+ OUT gctUINT32 * ExternalBaseAddress,
+ OUT gctUINT32 * ExternalAlignment,
+ OUT gctUINT32 * HorizontalTileSize,
+ OUT gctUINT32 * VerticalTileSize
+ )
+{
+ gcmkHEADER_ARG("Hardware=0x%x InternalSize=0x%x InternalBaseAddress=0x%x InternalAlignment=0x%x"
+ "ExternalSize=0x%x ExternalBaseAddress=0x%x ExternalAlignment=0x%x HorizontalTileSize=0x%x VerticalTileSize=0x%x",
+ Hardware, InternalSize, InternalBaseAddress, InternalAlignment,
+ ExternalSize, ExternalBaseAddress, ExternalAlignment, HorizontalTileSize, VerticalTileSize);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
+
+ if (InternalSize != gcvNULL)
+ {
+ /* No internal memory. */
+ *InternalSize = 0;
+ }
+
+ if (ExternalSize != gcvNULL)
+ {
+ /* No external memory. */
+ *ExternalSize = 0;
+ }
+
+ if (HorizontalTileSize != gcvNULL)
+ {
+ /* 4x4 tiles. */
+ *HorizontalTileSize = 4;
+ }
+
+ if (VerticalTileSize != gcvNULL)
+ {
+ /* 4x4 tiles. */
+ *VerticalTileSize = 4;
+ }
+
+ gcmkFOOTER_NO();
+ /* Success. */
+ return gcvSTATUS_OK;
+}
+
+/*******************************************************************************
+**
+** gckVGHARDWARE_QueryChipIdentity
+**
+** Query the identity of the hardware.
+**
+** INPUT:
+**
+** gckVGHARDWARE Hardware
+** Pointer to the gckVGHARDWARE object.
+**
+** OUTPUT:
+**
+** gceCHIPMODEL * ChipModel
+** If 'ChipModel' is not gcvNULL, the variable it points to will
+** receive the model of the chip.
+**
+** gctUINT32 * ChipRevision
+** If 'ChipRevision' is not gcvNULL, the variable it points to will
+** receive the revision of the chip.
+**
+** gctUINT32 * ChipFeatures
+** If 'ChipFeatures' is not gcvNULL, the variable it points to will
+** receive the feature set of the chip.
+**
+** gctUINT32 * ChipMinorFeatures
+** If 'ChipMinorFeatures' is not gcvNULL, the variable it points to
+** will receive the minor feature set of the chip.
+**
+** gctUINT32 * ChipMinorFeatures2
+** If 'ChipMinorFeatures2' is not gcvNULL, the variable it points to
+** will receive the minor feature set of the chip.
+**
+*/
+gceSTATUS
+gckVGHARDWARE_QueryChipIdentity(
+ IN gckVGHARDWARE Hardware,
+ OUT gceCHIPMODEL * ChipModel,
+ OUT gctUINT32 * ChipRevision,
+ OUT gctUINT32 * ProductID,
+ OUT gctUINT32 * EcoID,
+ OUT gctUINT32* CustomerID,
+ OUT gctUINT32* ChipFeatures,
+ OUT gctUINT32* ChipMinorFeatures,
+ OUT gctUINT32* ChipMinorFeatures2
+ )
+{
+ gcmkHEADER_ARG("Hardware=0x%x ChipModel=0x%x ChipRevision=0x%x ChipFeatures = 0x%x ChipMinorFeatures = 0x%x ChipMinorFeatures2 = 0x%x",
+ Hardware, ChipModel, ChipRevision, ChipFeatures, ChipMinorFeatures, ChipMinorFeatures2);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
+
+ /* Return chip model. */
+ if (ChipModel != gcvNULL)
+ {
+ *ChipModel = Hardware->chipModel;
+ }
+
+ /* Return revision number. */
+ if (ChipRevision != gcvNULL)
+ {
+ *ChipRevision = Hardware->chipRevision;
+ }
+
+ /* Return feature set. */
+ if (ChipFeatures != gcvNULL)
+ {
+ gctUINT32 features = Hardware->chipFeatures;
+
+ if (Hardware->fc)
+ {
+ features = ((((gctUINT32) (features)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1))))))) << (0 ?
+ 0:0))) | (((gctUINT32) ((gctUINT32) (Hardware->options.allowFastClear) & ((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)));
+ }
+
+ /* Mark 2D pipe as available for GC500.0 since it did not have this *\
+ \* bit. */
+ if ((Hardware->chipModel == gcv500)
+ && (Hardware->chipRevision == 0)
+ )
+ {
+ features = ((((gctUINT32) (features)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 9:9) - (0 ?
+ 9:9) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 9:9) - (0 ?
+ 9:9) + 1))))))) << (0 ?
+ 9:9))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 9:9) - (0 ?
+ 9:9) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 9:9) - (0 ? 9:9) + 1))))))) << (0 ? 9:9)));
+ }
+
+ /* Mark 2D pipe as available for GC300 since it did not have this *\
+ \* bit. */
+ if (Hardware->chipModel == gcv300)
+ {
+ features = ((((gctUINT32) (features)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 9:9) - (0 ?
+ 9:9) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 9:9) - (0 ?
+ 9:9) + 1))))))) << (0 ?
+ 9:9))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 9:9) - (0 ?
+ 9:9) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 9:9) - (0 ? 9:9) + 1))))))) << (0 ? 9:9)));
+ }
+
+ *ChipFeatures = features;
+ }
+
+ /* Return minor feature set. */
+ if (ChipMinorFeatures != gcvNULL)
+ {
+ *ChipMinorFeatures = Hardware->chipMinorFeatures;
+ }
+
+ /* Return minor feature set #2. */
+ if (ChipMinorFeatures2 != gcvNULL)
+ {
+ *ChipMinorFeatures2 = Hardware->chipMinorFeatures2;
+ }
+
+ if (ProductID != gcvNULL)
+ {
+ *ProductID = Hardware->productID;
+ }
+
+ if (EcoID != gcvNULL)
+ {
+ *EcoID = Hardware->ecoID;
+ }
+
+ if (CustomerID != gcvNULL)
+ {
+ *CustomerID = Hardware->customerID;
+ }
+
+ gcmkFOOTER_NO();
+ /* Success. */
+ return gcvSTATUS_OK;
+}
+
+/*******************************************************************************
+**
+** gckVGHARDWARE_ConvertFormat
+**
+** Convert an API format to hardware parameters.
+**
+** INPUT:
+**
+** gckVGHARDWARE Hardware
+** Pointer to the gckVGHARDWARE object.
+**
+** gceSURF_FORMAT Format
+** API format to convert.
+**
+** OUTPUT:
+**
+** gctUINT32 * BitsPerPixel
+** Pointer to a variable that will hold the number of bits per pixel.
+**
+** gctUINT32 * BytesPerTile
+** Pointer to a variable that will hold the number of bytes per tile.
+*/
+gceSTATUS
+gckVGHARDWARE_ConvertFormat(
+ IN gckVGHARDWARE Hardware,
+ IN gceSURF_FORMAT Format,
+ OUT gctUINT32 * BitsPerPixel,
+ OUT gctUINT32 * BytesPerTile
+ )
+{
+ gctUINT32 bitsPerPixel;
+ gctUINT32 bytesPerTile;
+
+ gcmkHEADER_ARG("Hardware=0x%x Format=0x%x BitsPerPixel=0x%x BytesPerTile = 0x%x",
+ Hardware, Format, BitsPerPixel, BytesPerTile);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
+
+ /* Dispatch on format. */
+ switch (Format)
+ {
+ case gcvSURF_A1:
+ case gcvSURF_L1:
+ /* 1-bpp format. */
+ bitsPerPixel = 1;
+ bytesPerTile = (1 * 4 * 4) / 8;
+ break;
+
+ case gcvSURF_A4:
+ /* 4-bpp format. */
+ bitsPerPixel = 4;
+ bytesPerTile = (4 * 4 * 4) / 8;
+ break;
+
+ case gcvSURF_INDEX8:
+ case gcvSURF_A8:
+ case gcvSURF_L8:
+ /* 8-bpp format. */
+ bitsPerPixel = 8;
+ bytesPerTile = (8 * 4 * 4) / 8;
+ break;
+
+ case gcvSURF_YV12:
+ /* 12-bpp planar YUV formats. */
+ bitsPerPixel = 12;
+ bytesPerTile = (12 * 4 * 4) / 8;
+ break;
+
+ case gcvSURF_NV12:
+ /* 12-bpp planar YUV formats. */
+ bitsPerPixel = 12;
+ bytesPerTile = (12 * 4 * 4) / 8;
+ break;
+
+ /* 4444 variations. */
+ case gcvSURF_X4R4G4B4:
+ case gcvSURF_A4R4G4B4:
+ case gcvSURF_R4G4B4X4:
+ case gcvSURF_R4G4B4A4:
+ case gcvSURF_B4G4R4X4:
+ case gcvSURF_B4G4R4A4:
+ case gcvSURF_X4B4G4R4:
+ case gcvSURF_A4B4G4R4:
+
+ /* 1555 variations. */
+ case gcvSURF_X1R5G5B5:
+ case gcvSURF_A1R5G5B5:
+ case gcvSURF_R5G5B5X1:
+ case gcvSURF_R5G5B5A1:
+ case gcvSURF_X1B5G5R5:
+ case gcvSURF_A1B5G5R5:
+ case gcvSURF_B5G5R5X1:
+ case gcvSURF_B5G5R5A1:
+
+ /* 565 variations. */
+ case gcvSURF_R5G6B5:
+ case gcvSURF_B5G6R5:
+
+ case gcvSURF_A8L8:
+ case gcvSURF_YUY2:
+ case gcvSURF_UYVY:
+ case gcvSURF_D16:
+ /* 16-bpp format. */
+ bitsPerPixel = 16;
+ bytesPerTile = (16 * 4 * 4) / 8;
+ break;
+
+ case gcvSURF_X8R8G8B8:
+ case gcvSURF_A8R8G8B8:
+ case gcvSURF_X8B8G8R8:
+ case gcvSURF_A8B8G8R8:
+ case gcvSURF_R8G8B8X8:
+ case gcvSURF_R8G8B8A8:
+ case gcvSURF_B8G8R8X8:
+ case gcvSURF_B8G8R8A8:
+ case gcvSURF_D32:
+ /* 32-bpp format. */
+ bitsPerPixel = 32;
+ bytesPerTile = (32 * 4 * 4) / 8;
+ break;
+
+ case gcvSURF_D24S8:
+ /* 24-bpp format. */
+ bitsPerPixel = 32;
+ bytesPerTile = (32 * 4 * 4) / 8;
+ break;
+
+ case gcvSURF_DXT1:
+ case gcvSURF_ETC1:
+ bitsPerPixel = 4;
+ bytesPerTile = (4 * 4 * 4) / 8;
+ break;
+
+ case gcvSURF_DXT2:
+ case gcvSURF_DXT3:
+ case gcvSURF_DXT4:
+ case gcvSURF_DXT5:
+ bitsPerPixel = 8;
+ bytesPerTile = (8 * 4 * 4) / 8;
+ break;
+
+ default:
+ /* Invalid format. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_INVALID_ARGUMENT;
+ }
+
+ /* Set the result. */
+ if (BitsPerPixel != gcvNULL)
+ {
+ * BitsPerPixel = bitsPerPixel;
+ }
+
+ if (BytesPerTile != gcvNULL)
+ {
+ * BytesPerTile = bytesPerTile;
+ }
+
+ gcmkFOOTER_NO();
+ /* Success. */
+ return gcvSTATUS_OK;
+}
+
+/*******************************************************************************
+**
+** gckVGHARDWARE_SplitMemory
+**
+** Split a hardware specific memory address into a pool and offset.
+**
+** INPUT:
+**
+** gckVGHARDWARE Hardware
+** Pointer to the gckVGHARDWARE object.
+**
+** gctUINT32 Address
+** Address in hardware specific format.
+**
+** OUTPUT:
+**
+** gcePOOL * Pool
+** Pointer to a variable that will hold the pool type for the address.
+**
+** gctUINT32 * Offset
+** Pointer to a variable that will hold the offset for the address.
+*/
+gceSTATUS
+gckVGHARDWARE_SplitMemory(
+ IN gckVGHARDWARE Hardware,
+ IN gctUINT32 Address,
+ OUT gcePOOL * Pool,
+ OUT gctUINT32 * Offset
+ )
+{
+ gcmkHEADER_ARG("Hardware=0x%x Address=0x%x Pool=0x%x Offset = 0x%x",
+ Hardware, Address, Pool, Offset);
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
+ gcmkVERIFY_ARGUMENT(Pool != gcvNULL);
+ gcmkVERIFY_ARGUMENT(Offset != gcvNULL);
+
+ /* Dispatch on memory type. */
+ switch ((((((gctUINT32) (Address)) >> (0 ? 1:0)) & ((gctUINT32) ((((1 ? 1:0) - (0 ? 1:0) + 1) == 32) ? ~0U : (~(~0U << ((1 ? 1:0) - (0 ? 1:0) + 1)))))) ))
+ {
+ case 0x0:
+ /* System memory. */
+ *Pool = gcvPOOL_SYSTEM;
+ break;
+
+ case 0x2:
+ /* Virtual memory. */
+ *Pool = gcvPOOL_VIRTUAL;
+ break;
+
+ default:
+ /* Invalid memory type. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_INVALID_ARGUMENT;
+ }
+
+ /* Return offset of address. */
+ *Offset = ((((gctUINT32) (Address)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 1:0) - (0 ?
+ 1:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 1:0) - (0 ?
+ 1:0) + 1))))))) << (0 ?
+ 1:0))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ?
+ 1:0) - (0 ?
+ 1:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 1:0) - (0 ? 1:0) + 1))))))) << (0 ? 1:0)));
+
+ gcmkFOOTER_NO();
+ /* Success. */
+ return gcvSTATUS_OK;
+}
+
+/*******************************************************************************
+**
+** gckVGHARDWARE_Execute
+**
+** Kickstart the hardware's command processor with an initialized command
+** buffer.
+**
+** INPUT:
+**
+** gckVGHARDWARE Hardware
+** Pointer to the gckVGHARDWARE object.
+**
+** gctUINT32 Address
+** Address of the command buffer.
+**
+** gctSIZE_T Count
+** Number of command-sized data units to be executed.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckVGHARDWARE_Execute(
+ IN gckVGHARDWARE Hardware,
+ IN gctUINT32 Address,
+ IN gctUINT32 Count
+ )
+{
+ gceSTATUS status;
+
+ gcmkHEADER_ARG("Hardware=0x%x Address=0x%x Count=0x%x",
+ Hardware, Address, Count);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
+
+ do
+ {
+ /* Enable all events. */
+ gcmkERR_BREAK(gckOS_WriteRegisterEx(
+ Hardware->os,
+ gcvCORE_VG,
+ 0x00014,
+ Hardware->eventMask
+ ));
+
+ if (Hardware->fe20)
+ {
+ /* Write address register. */
+ gcmkERR_BREAK(gckOS_WriteRegisterEx(
+ Hardware->os,
+ gcvCORE_VG,
+ 0x00500,
+ gcmkFIXADDRESS(Address)
+ ));
+
+ /* Write control register. */
+ gcmkERR_BREAK(gckOS_WriteRegisterEx(
+ Hardware->os,
+ gcvCORE_VG,
+ 0x00504,
+ Count
+ ));
+ }
+ else
+ {
+ /* Write address register. */
+ gcmkERR_BREAK(gckOS_WriteRegisterEx(
+ Hardware->os,
+ gcvCORE_VG,
+ 0x00654,
+ gcmkFIXADDRESS(Address)
+ ));
+
+ /* Write control register. */
+ gcmkERR_BREAK(gckOS_WriteRegisterEx(
+ Hardware->os,
+ gcvCORE_VG,
+ 0x00658,
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 16:16) - (0 ?
+ 16:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 16:16) - (0 ?
+ 16:16) + 1))))))) << (0 ?
+ 16:16))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 16:16) - (0 ?
+ 16:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 16:16) - (0 ? 16:16) + 1))))))) << (0 ? 16:16))) |
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (Count) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+ ));
+ }
+
+ /* Success. */
+ gcmkFOOTER();
+ return gcvSTATUS_OK;
+ }
+ while (gcvFALSE);
+
+
+ gcmkFOOTER();
+ /* Return the status. */
+ return status;
+}
+
+/*******************************************************************************
+**
+** gckVGHARDWARE_AlignToTile
+**
+** Align the specified width and height to tile boundaries.
+**
+** INPUT:
+**
+** gckVGHARDWARE Hardware
+** Pointer to an gckVGHARDWARE object.
+**
+** gceSURF_TYPE Type
+** Type of alignment.
+**
+** gctUINT32 * Width
+** Pointer to the width to be aligned. If 'Width' is gcvNULL, no width
+** will be aligned.
+**
+** gctUINT32 * Height
+** Pointer to the height to be aligned. If 'Height' is gcvNULL, no height
+** will be aligned.
+**
+** OUTPUT:
+**
+** gctUINT32 * Width
+** Pointer to a variable that will receive the aligned width.
+**
+** gctUINT32 * Height
+** Pointer to a variable that will receive the aligned height.
+*/
+gceSTATUS
+gckVGHARDWARE_AlignToTile(
+ IN gckVGHARDWARE Hardware,
+ IN gceSURF_TYPE Type,
+ IN OUT gctUINT32 * Width,
+ IN OUT gctUINT32 * Height
+ )
+{
+ gcmkHEADER_ARG("Hardware=0x%x Type=0x%x Width=0x%x Height=0x%x",
+ Hardware, Type, Width, Height);
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
+
+ if (Width != gcvNULL)
+ {
+ /* Align the width. */
+ *Width = gcmALIGN(*Width, (Type == gcvSURF_TEXTURE) ? 4 : 16);
+ }
+
+ if (Height != gcvNULL)
+ {
+ /* Special case for VG images. */
+ if ((*Height == 0) && (Type == gcvSURF_IMAGE))
+ {
+ *Height = 4;
+ }
+ else
+ {
+ /* Align the height. */
+ *Height = gcmALIGN(*Height, 4);
+ }
+ }
+
+ gcmkFOOTER_NO();
+ /* Success. */
+ return gcvSTATUS_OK;
+}
+
+/*******************************************************************************
+**
+** gckVGHARDWARE_ConvertLogical
+**
+** Convert a logical system address into a hardware specific address.
+**
+** INPUT:
+**
+** gckVGHARDWARE Hardware
+** Pointer to an gckVGHARDWARE object.
+**
+** gctPOINTER Logical
+** Logical address to convert.
+**
+** gctBOOL InUserSpace
+** gcvTRUE if the memory in user space.
+**
+** gctUINT32* Address
+** Return hardware specific address.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckVGHARDWARE_ConvertLogical(
+ IN gckVGHARDWARE Hardware,
+ IN gctPOINTER Logical,
+ IN gctBOOL InUserSpace,
+ OUT gctUINT32 * Address
+ )
+{
+ gctPHYS_ADDR_T physical;
+ gctUINT32 address;
+ gceSTATUS status;
+
+ gcmkHEADER_ARG("Hardware=0x%x Logical=0x%x InUserSpace=%d Address=0x%x",
+ Hardware, Logical, InUserSpace, Address);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
+ gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
+ gcmkVERIFY_ARGUMENT(Address != gcvNULL);
+
+ do
+ {
+ /* Convert logical address into a physical address. */
+ if (InUserSpace)
+ {
+ gcmkERR_BREAK(gckOS_UserLogicalToPhysical(
+ Hardware->os, Logical, &physical
+ ));
+ }
+ else
+ {
+ gcmkERR_BREAK(gckOS_GetPhysicalAddress(
+ Hardware->os, Logical, &physical
+ ));
+ }
+
+ gcmkVERIFY_OK(gckOS_CPUPhysicalToGPUPhysical(Hardware->os, physical, &physical));
+
+ gcmkSAFECASTPHYSADDRT(address, physical);
+
+ /* Return hardware specific address. */
+ *Address = ((((gctUINT32) (address)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 1:0) - (0 ?
+ 1:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 1:0) - (0 ?
+ 1:0) + 1))))))) << (0 ?
+ 1:0))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ?
+ 1:0) - (0 ?
+ 1:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 1:0) - (0 ? 1:0) + 1))))))) << (0 ? 1:0)));
+
+ /* Success. */
+ gcmkFOOTER();
+ return gcvSTATUS_OK;
+ }
+ while (gcvFALSE);
+
+ gcmkFOOTER();
+ /* Return the status. */
+ return status;
+}
+
+/*******************************************************************************
+**
+** gckVGHARDWARE_QuerySystemMemory
+**
+** Query the command buffer alignment and number of reserved bytes.
+**
+** INPUT:
+**
+** gckVGHARDWARE Harwdare
+** Pointer to an gckVGHARDWARE object.
+**
+** OUTPUT:
+**
+** gctSIZE_T * SystemSize
+** Pointer to a variable that receives the maximum size of the system
+** memory.
+**
+** gctUINT32 * SystemBaseAddress
+** Poinetr to a variable that receives the base address for system
+** memory.
+*/
+gceSTATUS gckVGHARDWARE_QuerySystemMemory(
+ IN gckVGHARDWARE Hardware,
+ OUT gctSIZE_T * SystemSize,
+ OUT gctUINT32 * SystemBaseAddress
+ )
+{
+ gcmkHEADER_ARG("Hardware=0x%x SystemSize=0x%x SystemBaseAddress=0x%x",
+ Hardware, SystemSize, SystemBaseAddress);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
+
+ if (SystemSize != gcvNULL)
+ {
+ /* Maximum system memory can be 2GB. */
+ *SystemSize = (gctSIZE_T)(1 << 31);
+ }
+
+ if (SystemBaseAddress != gcvNULL)
+ {
+ /* Set system memory base address. */
+ *SystemBaseAddress = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 1:0) - (0 ?
+ 1:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 1:0) - (0 ?
+ 1:0) + 1))))))) << (0 ?
+ 1:0))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ?
+ 1:0) - (0 ?
+ 1:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 1:0) - (0 ? 1:0) + 1))))))) << (0 ? 1:0)));
+ }
+
+ gcmkFOOTER_NO();
+ /* Success. */
+ return gcvSTATUS_OK;
+}
+
+/*******************************************************************************
+**
+** gckVGHARDWARE_SetMMU
+**
+** Set the page table base address.
+**
+** INPUT:
+**
+** gckVGHARDWARE Harwdare
+** Pointer to an gckVGHARDWARE object.
+**
+** gctPOINTER Logical
+** Logical address of the page table.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS gckVGHARDWARE_SetMMU(
+ IN gckVGHARDWARE Hardware,
+ IN gctPOINTER Logical
+ )
+{
+ gceSTATUS status;
+ gctUINT32 address = 0;
+
+ gcmkHEADER_ARG("Hardware=0x%x Logical=0x%x",
+ Hardware, Logical);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
+ gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
+
+ do
+ {
+ /* Convert the logical address into an hardware address. */
+ gcmkERR_BREAK(gckVGHARDWARE_ConvertLogical(Hardware, Logical,
+ gcvFALSE, &address));
+
+ /* Write the AQMemoryFePageTable register. */
+ gcmkERR_BREAK(gckOS_WriteRegisterEx(Hardware->os, gcvCORE_VG,
+ 0x00400,
+ gcmkFIXADDRESS(address)));
+
+ /* Write the AQMemoryTxPageTable register. */
+ gcmkERR_BREAK(gckOS_WriteRegisterEx(Hardware->os, gcvCORE_VG,
+ 0x00404,
+ gcmkFIXADDRESS(address)));
+
+ /* Write the AQMemoryPePageTable register. */
+ gcmkERR_BREAK(gckOS_WriteRegisterEx(Hardware->os, gcvCORE_VG,
+ 0x00408,
+ gcmkFIXADDRESS(address)));
+
+ /* Write the AQMemoryPezPageTable register. */
+ gcmkERR_BREAK(gckOS_WriteRegisterEx(Hardware->os, gcvCORE_VG,
+ 0x0040C,
+ gcmkFIXADDRESS(address)));
+
+ /* Write the AQMemoryRaPageTable register. */
+ gcmkERR_BREAK(gckOS_WriteRegisterEx(Hardware->os, gcvCORE_VG,
+ 0x00410,
+ gcmkFIXADDRESS(address)));
+ }
+ while (gcvFALSE);
+
+ gcmkFOOTER();
+ /* Return the status. */
+ return status;
+}
+
+/*******************************************************************************
+**
+** gckVGHARDWARE_FlushMMU
+**
+** Flush the page table.
+**
+** INPUT:
+**
+** gckVGHARDWARE Harwdare
+** Pointer to an gckVGHARDWARE object.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS gckVGHARDWARE_FlushMMU(
+ IN gckVGHARDWARE Hardware
+ )
+{
+ gceSTATUS status;
+ gckVGCOMMAND command;
+
+ gcmkHEADER_ARG("Hardware=0x%x ", Hardware);
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
+
+ do
+ {
+ gcsCMDBUFFER_PTR commandBuffer;
+ gctUINT32_PTR buffer;
+
+ /* Create a shortcut to the command buffer object. */
+ command = Hardware->kernel->command;
+
+ /* Allocate command buffer space. */
+ gcmkERR_BREAK(gckVGCOMMAND_Allocate(
+ command, 8, &commandBuffer, (gctPOINTER *) &buffer
+ ));
+
+ gckOS_WriteMemory(
+ Hardware->os,
+ &buffer[0],
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E04) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+ );
+
+ gckOS_WriteMemory(
+ Hardware->os,
+ &buffer[1],
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1))))))) << (0 ?
+ 0:0))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 1:1) - (0 ?
+ 1:1) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 1:1) - (0 ?
+ 1:1) + 1))))))) << (0 ?
+ 1:1))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 1:1) - (0 ?
+ 1:1) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 2:2) - (0 ?
+ 2:2) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 2:2) - (0 ?
+ 2:2) + 1))))))) << (0 ?
+ 2:2))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 2:2) - (0 ?
+ 2:2) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 2:2) - (0 ? 2:2) + 1))))))) << (0 ? 2:2)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 3:3) - (0 ?
+ 3:3) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 3:3) - (0 ?
+ 3:3) + 1))))))) << (0 ?
+ 3:3))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 3:3) - (0 ?
+ 3:3) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 3:3) - (0 ? 3:3) + 1))))))) << (0 ? 3:3)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 4:4) - (0 ?
+ 4:4) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 4:4) - (0 ?
+ 4:4) + 1))))))) << (0 ?
+ 4:4))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 4:4) - (0 ?
+ 4:4) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 4:4) - (0 ? 4:4) + 1))))))) << (0 ? 4:4)))
+ );
+
+ gcmkERR_BREAK(gckVGCOMMAND_Execute(
+ command,
+ commandBuffer
+ ));
+ }
+ while(gcvFALSE);
+
+ gcmkFOOTER();
+ /* Return the status. */
+ return status;
+}
+
+/*******************************************************************************
+**
+** gckVGHARDWARE_BuildVirtualAddress
+**
+** Build a virtual address.
+**
+** INPUT:
+**
+** gckVGHARDWARE Harwdare
+** Pointer to an gckVGHARDWARE object.
+**
+** gctUINT32 Index
+** Index into page table.
+**
+** gctUINT32 Offset
+** Offset into page.
+**
+** OUTPUT:
+**
+** gctUINT32 * Address
+** Pointer to a variable receiving te hardware address.
+*/
+gceSTATUS gckVGHARDWARE_BuildVirtualAddress(
+ IN gckVGHARDWARE Hardware,
+ IN gctUINT32 Index,
+ IN gctUINT32 Offset,
+ OUT gctUINT32 * Address
+ )
+{
+ gctUINT32 address;
+
+ gcmkHEADER_ARG("Hardware=0x%x Index=0x%x Offset=0x%x Address=0x%x",
+ Hardware, Index, Offset, Address);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
+ gcmkVERIFY_ARGUMENT(Address != gcvNULL);
+
+ /* Build virtual address. */
+ address = (Index << 12) | Offset;
+
+ /* Set virtual type. */
+ address = ((((gctUINT32) (address)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 1:0) - (0 ?
+ 1:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 1:0) - (0 ?
+ 1:0) + 1))))))) << (0 ?
+ 1:0))) | (((gctUINT32) (0x2 & ((gctUINT32) ((((1 ?
+ 1:0) - (0 ?
+ 1:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 1:0) - (0 ? 1:0) + 1))))))) << (0 ? 1:0)));
+
+ /* Set the result. */
+ *Address = address;
+
+ gcmkFOOTER_NO();
+ /* Success. */
+ return gcvSTATUS_OK;
+}
+
+gceSTATUS
+gckVGHARDWARE_GetIdle(
+ IN gckVGHARDWARE Hardware,
+ OUT gctUINT32 * Data
+ )
+{
+ gceSTATUS status;
+ gcmkHEADER_ARG("Hardware=0x%x Data=0x%x", Hardware, Data);
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
+ gcmkVERIFY_ARGUMENT(Data != gcvNULL);
+
+ /* Read register and return. */
+ status = gckOS_ReadRegisterEx(Hardware->os, gcvCORE_VG, 0x00004, Data);
+ gcmkFOOTER();
+ return status;
+}
+
+gceSTATUS
+gckVGHARDWARE_SetFastClear(
+ IN gckVGHARDWARE Hardware,
+ IN gctINT Enable
+ )
+{
+ gctUINT32 debug;
+ gceSTATUS status;
+
+ if (!Hardware->fc)
+ {
+ return gcvSTATUS_OK;
+ }
+
+ do
+ {
+ if (Enable == -1)
+ {
+ Enable = (Hardware->chipModel > gcv500) ||
+ ((Hardware->chipModel == gcv500) && (Hardware->chipRevision >= 3));
+ }
+
+ gcmkERR_BREAK(gckOS_ReadRegisterEx(Hardware->os, gcvCORE_VG,
+ 0x00414,
+ &debug));
+
+ debug = ((((gctUINT32) (debug)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 20:20) - (0 ?
+ 20:20) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 20:20) - (0 ?
+ 20:20) + 1))))))) << (0 ?
+ 20:20))) | (((gctUINT32) ((gctUINT32) (Enable == 0) & ((gctUINT32) ((((1 ?
+ 20:20) - (0 ?
+ 20:20) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 20:20) - (0 ? 20:20) + 1))))))) << (0 ? 20:20)));
+
+#ifdef AQ_MEMORY_DEBUG_DISABLE_Z_COMPRESSION
+ debug = ((((gctUINT32) (debug)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ AQ_MEMORY_DEBUG_DISABLE_Z_COMPRESSION) - (0 ?
+ AQ_MEMORY_DEBUG_DISABLE_Z_COMPRESSION) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ AQ_MEMORY_DEBUG_DISABLE_Z_COMPRESSION) - (0 ?
+ AQ_MEMORY_DEBUG_DISABLE_Z_COMPRESSION) + 1))))))) << (0 ?
+ AQ_MEMORY_DEBUG_DISABLE_Z_COMPRESSION))) | (((gctUINT32) ((gctUINT32) (Enable == 0) & ((gctUINT32) ((((1 ?
+ AQ_MEMORY_DEBUG_DISABLE_Z_COMPRESSION) - (0 ?
+ AQ_MEMORY_DEBUG_DISABLE_Z_COMPRESSION) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ AQ_MEMORY_DEBUG_DISABLE_Z_COMPRESSION) - (0 ?
+ AQ_MEMORY_DEBUG_DISABLE_Z_COMPRESSION) + 1))))))) << (0 ?
+ AQ_MEMORY_DEBUG_DISABLE_Z_COMPRESSION)));
+#endif
+
+ gcmkERR_BREAK(gckOS_WriteRegisterEx(Hardware->os, gcvCORE_VG,
+ 0x00414,
+ debug));
+
+ Hardware->options.allowFastClear = Enable;
+
+ status = gcvFALSE;
+ }
+ while (gcvFALSE);
+
+ return status;
+}
+
+gceSTATUS
+gckVGHARDWARE_ReadInterrupt(
+ IN gckVGHARDWARE Hardware,
+ OUT gctUINT32_PTR IDs
+ )
+{
+ gceSTATUS status;
+ gcmkHEADER_ARG("Hardware=0x%x IDs=0x%x", Hardware, IDs);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
+ gcmkVERIFY_ARGUMENT(IDs != gcvNULL);
+
+ /* Read AQIntrAcknowledge register. */
+ status = gckOS_ReadRegisterEx(Hardware->os, gcvCORE_VG,
+ 0x00010,
+ IDs);
+ gcmkFOOTER();
+ return status;
+}
+
+static gceSTATUS _CommandStall(
+ gckVGHARDWARE Hardware)
+{
+ gceSTATUS status;
+ gckVGCOMMAND command;
+
+ gcmkHEADER_ARG("Hardware=0x%x", Hardware);
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
+
+ do
+ {
+ gctUINT32_PTR buffer;
+ command = Hardware->kernel->command;
+
+ /* Allocate command buffer space. */
+ gcmkERR_BREAK(gckVGCOMMAND_Allocate(
+ command, 8, &command->powerStallBuffer,
+ (gctPOINTER *) &buffer
+ ));
+
+ gcmkERR_BREAK(gckVGCOMMAND_EventCommand(
+ command, buffer, gcvBLOCK_PIXEL,
+ command->powerStallInt, gcvNULL));
+
+ gcmkERR_BREAK(gckVGCOMMAND_Execute(
+ command,
+ command->powerStallBuffer
+ ));
+
+ /* Wait the signal. */
+ gcmkERR_BREAK(gckOS_WaitSignal(
+ command->os,
+ command->powerStallSignal,
+ gcvFALSE,
+ command->kernel->kernel->timeOut));
+
+
+ }
+ while(gcvFALSE);
+
+ gcmkFOOTER();
+ /* Return the status. */
+ return status;
+}
+
+/*******************************************************************************
+**
+** gckHARDWARE_SetPowerManagementState
+**
+** Set GPU to a specified power state.
+**
+** INPUT:
+**
+** gckHARDWARE Harwdare
+** Pointer to an gckHARDWARE object.
+**
+** gceCHIPPOWERSTATE State
+** Power State.
+**
+*/
+gceSTATUS
+gckVGHARDWARE_SetPowerManagementState(
+ IN gckVGHARDWARE Hardware,
+ IN gceCHIPPOWERSTATE State
+ )
+{
+ gceSTATUS status;
+ gckVGCOMMAND command = gcvNULL;
+ gckOS os;
+ gctUINT flag/*, clock*/;
+
+ gctBOOL acquired = gcvFALSE;
+ gctBOOL stall = gcvTRUE;
+ gctBOOL commitMutex = gcvFALSE;
+ gctBOOL mutexAcquired = gcvFALSE;
+
+#if gcdPOWEROFF_TIMEOUT
+ gctBOOL timeout = gcvFALSE;
+ gctBOOL isAfter = gcvFALSE;
+ gctUINT32 currentTime;
+#endif
+
+ gctBOOL broadcast = gcvFALSE;
+ gctUINT32 process, thread;
+ gctBOOL global = gcvFALSE;
+
+#if gcdENABLE_PROFILING
+ gctUINT64 time, freq, mutexTime, onTime, stallTime, stopTime, delayTime,
+ initTime, offTime, startTime, totalTime;
+#endif
+
+ /* State transition flags. */
+ static const gctUINT flags[4][4] =
+ {
+ /* gcvPOWER_ON */
+ { /* ON */ 0,
+ /* OFF */ gcvPOWER_FLAG_ACQUIRE |
+ gcvPOWER_FLAG_STALL |
+ gcvPOWER_FLAG_STOP |
+ gcvPOWER_FLAG_POWER_OFF |
+ gcvPOWER_FLAG_CLOCK_OFF,
+ /* IDLE */ gcvPOWER_FLAG_NOP,
+ /* SUSPEND */ gcvPOWER_FLAG_ACQUIRE |
+ gcvPOWER_FLAG_STALL |
+ gcvPOWER_FLAG_STOP |
+ gcvPOWER_FLAG_CLOCK_OFF,
+ },
+
+ /* gcvPOWER_OFF */
+ { /* ON */ gcvPOWER_FLAG_INITIALIZE |
+ gcvPOWER_FLAG_START |
+ gcvPOWER_FLAG_RELEASE |
+ gcvPOWER_FLAG_DELAY,
+ /* OFF */ 0,
+ /* IDLE */ gcvPOWER_FLAG_INITIALIZE |
+ gcvPOWER_FLAG_START |
+ gcvPOWER_FLAG_RELEASE |
+ gcvPOWER_FLAG_DELAY,
+ /* SUSPEND */ gcvPOWER_FLAG_INITIALIZE |
+ gcvPOWER_FLAG_CLOCK_OFF,
+ },
+
+ /* gcvPOWER_IDLE */
+ { /* ON */ gcvPOWER_FLAG_NOP,
+ /* OFF */ gcvPOWER_FLAG_ACQUIRE |
+ gcvPOWER_FLAG_STOP |
+ gcvPOWER_FLAG_POWER_OFF |
+ gcvPOWER_FLAG_CLOCK_OFF,
+ /* IDLE */ 0,
+ /* SUSPEND */ gcvPOWER_FLAG_ACQUIRE |
+ gcvPOWER_FLAG_STOP |
+ gcvPOWER_FLAG_CLOCK_OFF,
+ },
+
+ /* gcvPOWER_SUSPEND */
+ { /* ON */ gcvPOWER_FLAG_START |
+ gcvPOWER_FLAG_RELEASE |
+ gcvPOWER_FLAG_DELAY |
+ gcvPOWER_FLAG_CLOCK_ON,
+ /* OFF */ gcvPOWER_FLAG_SAVE |
+ gcvPOWER_FLAG_POWER_OFF |
+ gcvPOWER_FLAG_CLOCK_OFF,
+ /* IDLE */ gcvPOWER_FLAG_START |
+ gcvPOWER_FLAG_DELAY |
+ gcvPOWER_FLAG_RELEASE |
+ gcvPOWER_FLAG_CLOCK_ON,
+ /* SUSPEND */ 0,
+ },
+ };
+
+ gcmkHEADER_ARG("Hardware=0x%x State=%d", Hardware, State);
+#if gcmIS_DEBUG(gcdDEBUG_TRACE)
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
+ "Switching to power state %d",
+ State);
+#endif
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
+
+ /* Get the gckOS object pointer. */
+ os = Hardware->os;
+ gcmkVERIFY_OBJECT(os, gcvOBJ_OS);
+
+ /* Get the gckCOMMAND object pointer. */
+ gcmkVERIFY_OBJECT(Hardware->kernel, gcvOBJ_KERNEL);
+ command = Hardware->kernel->command;
+ gcmkVERIFY_OBJECT(command, gcvOBJ_COMMAND);
+
+ if (Hardware->options.powerManagement == gcvFALSE)
+ {
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+ }
+
+ /* Start profiler. */
+ gcmkPROFILE_INIT(freq, time);
+
+ /* Convert the broadcast power state. */
+ switch (State)
+ {
+ case gcvPOWER_IDLE_BROADCAST:
+ /* Convert to IDLE and note we are inside broadcast. */
+ State = gcvPOWER_IDLE;
+ broadcast = gcvTRUE;
+ break;
+
+ case gcvPOWER_SUSPEND_BROADCAST:
+ /* Convert to SUSPEND and note we are inside broadcast. */
+ State = gcvPOWER_SUSPEND;
+ broadcast = gcvTRUE;
+ break;
+
+ case gcvPOWER_OFF_BROADCAST:
+ /* Convert to OFF and note we are inside broadcast. */
+ State = gcvPOWER_OFF;
+ broadcast = gcvTRUE;
+ break;
+
+ case gcvPOWER_ON_AUTO:
+ /* Convert to ON and note we are inside recovery. */
+ State = gcvPOWER_ON;
+ break;
+
+ case gcvPOWER_ON:
+ case gcvPOWER_IDLE:
+ case gcvPOWER_SUSPEND:
+ case gcvPOWER_OFF:
+ /* Mark as global power management. */
+ global = gcvTRUE;
+ break;
+
+#if gcdPOWEROFF_TIMEOUT
+ case gcvPOWER_OFF_TIMEOUT:
+ /* Convert to OFF and note we are inside broadcast. */
+ State = gcvPOWER_OFF;
+ broadcast = gcvTRUE;
+ /* Check time out */
+ timeout = gcvTRUE;
+ break;
+#endif
+
+ default:
+ break;
+ }
+
+ /* Get current process and thread IDs. */
+ gcmkONERROR(gckOS_GetProcessID(&process));
+ gcmkONERROR(gckOS_GetThreadID(&thread));
+
+ /* Acquire the power mutex. */
+ if (broadcast)
+ {
+ /* Try to acquire the power mutex. */
+ status = gckOS_AcquireMutex(os, Hardware->powerMutex, 0);
+
+ if (status == gcvSTATUS_TIMEOUT)
+ {
+ /* Check if we already own this mutex. */
+ if ((Hardware->powerProcess == process)
+ && (Hardware->powerThread == thread)
+ )
+ {
+ /* Bail out on recursive power management. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+ }
+ else if (State == gcvPOWER_IDLE)
+ {
+ /* gcvPOWER_IDLE_BROADCAST is from IST,
+ ** so waiting here will cause deadlock,
+ ** if lock holder call gckCOMMAND_Stall() */
+ gcmkONERROR(gcvSTATUS_INVALID_REQUEST);
+ }
+ else
+ {
+ /* Acquire the power mutex. */
+ gcmkONERROR(gckOS_AcquireMutex(os,
+ Hardware->powerMutex,
+ gcvINFINITE));
+ }
+ }
+ }
+ else
+ {
+ /* Acquire the power mutex. */
+ gcmkONERROR(gckOS_AcquireMutex(os, Hardware->powerMutex, gcvINFINITE));
+ }
+
+ /* Get time until mtuex acquired. */
+ gcmkPROFILE_QUERY(time, mutexTime);
+
+ Hardware->powerProcess = process;
+ Hardware->powerThread = thread;
+ mutexAcquired = gcvTRUE;
+
+ /* Grab control flags and clock. */
+ flag = flags[Hardware->chipPowerState][State];
+ /*clock = clocks[State];*/
+
+#if gcdPOWEROFF_TIMEOUT
+ if (timeout)
+ {
+ gcmkONERROR(gckOS_GetTicks(&currentTime));
+
+ gcmkONERROR(
+ gckOS_TicksAfter(Hardware->powerOffTime, currentTime, &isAfter));
+
+ /* powerOffTime is pushed forward, give up.*/
+ if (isAfter
+ /* Expect a transition start from IDLE. */
+ || (Hardware->chipPowerState == gcvPOWER_ON)
+ || (Hardware->chipPowerState == gcvPOWER_OFF)
+ )
+ {
+ /* Release the power mutex. */
+ gcmkONERROR(gckOS_ReleaseMutex(os, Hardware->powerMutex));
+
+ /* No need to do anything. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+ }
+ }
+#endif
+
+ if (flag == 0)
+ {
+ /* Release the power mutex. */
+ gcmkONERROR(gckOS_ReleaseMutex(os, Hardware->powerMutex));
+
+ /* No need to do anything. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+ }
+
+ /* internal power control */
+ if (!global)
+ {
+ if (Hardware->chipPowerStateGlobal == gcvPOWER_OFF)
+ {
+ /* Release the power mutex. */
+ gcmkONERROR(gckOS_ReleaseMutex(os, Hardware->powerMutex));
+
+ /* No need to do anything. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+ }
+ }
+ else
+ {
+ if (flag & gcvPOWER_FLAG_ACQUIRE)
+ {
+ /* Acquire the power management semaphore. */
+ gcmkONERROR(gckOS_AcquireSemaphore(os, command->powerSemaphore));
+ acquired = gcvTRUE;
+
+ /* avoid acquiring again. */
+ flag &= ~gcvPOWER_FLAG_ACQUIRE;
+ }
+ }
+
+ if (flag & (gcvPOWER_FLAG_INITIALIZE | gcvPOWER_FLAG_CLOCK_ON))
+ {
+ /* Turn on the power. */
+ gcmkONERROR(gckOS_SetGPUPower(os, gcvCORE_VG, gcvTRUE, gcvTRUE));
+
+ /* Mark clock and power as enabled. */
+ Hardware->clockState = gcvTRUE;
+ Hardware->powerState = gcvTRUE;
+ }
+
+ /* Get time until powered on. */
+ gcmkPROFILE_QUERY(time, onTime);
+
+ if ((flag & gcvPOWER_FLAG_STALL) && stall)
+ {
+ /* Acquire the mutex. */
+ gcmkONERROR(gckOS_AcquireMutex(
+ command->os,
+ command->commitMutex,
+ gcvINFINITE
+ ));
+
+ commitMutex = gcvTRUE;
+
+ gcmkONERROR(_CommandStall(Hardware));
+ }
+
+ /* Get time until stalled. */
+ gcmkPROFILE_QUERY(time, stallTime);
+
+ if (flag & gcvPOWER_FLAG_ACQUIRE)
+ {
+ /* Acquire the power management semaphore. */
+ gcmkONERROR(gckOS_AcquireSemaphore(os, command->powerSemaphore));
+
+ acquired = gcvTRUE;
+ }
+
+
+ /* Get time until stopped. */
+ gcmkPROFILE_QUERY(time, stopTime);
+
+
+ if (flag & gcvPOWER_FLAG_DELAY)
+ {
+ /* Wait for the specified amount of time to settle coming back from
+ ** power-off or suspend state. */
+ gcmkONERROR(gckOS_Delay(os, gcdPOWER_CONTROL_DELAY));
+ }
+
+ /* Get time until delayed. */
+ gcmkPROFILE_QUERY(time, delayTime);
+
+ if (flag & gcvPOWER_FLAG_INITIALIZE)
+ {
+
+ /* Initialize GPU here, replaced by InitializeHardware later */
+ gcmkONERROR(gckVGHARDWARE_SetMMU(Hardware, Hardware->kernel->mmu->pageTableLogical));
+ gcmkVERIFY_OK(gckVGHARDWARE_SetFastClear(Hardware, -1));
+
+ /* Force the command queue to reload the next context. */
+ command->currentContext = 0;
+ }
+
+ /* Get time until initialized. */
+ gcmkPROFILE_QUERY(time, initTime);
+
+ if (flag & (gcvPOWER_FLAG_POWER_OFF | gcvPOWER_FLAG_CLOCK_OFF))
+ {
+ /* Turn off the GPU power. */
+ gcmkONERROR(
+ gckOS_SetGPUPower(os,
+ gcvCORE_VG,
+ (flag & gcvPOWER_FLAG_CLOCK_OFF) ? gcvFALSE
+ : gcvTRUE,
+ (flag & gcvPOWER_FLAG_POWER_OFF) ? gcvFALSE
+ : gcvTRUE));
+
+ /* Save current hardware power and clock states. */
+ Hardware->clockState = (flag & gcvPOWER_FLAG_CLOCK_OFF) ? gcvFALSE
+ : gcvTRUE;
+ Hardware->powerState = (flag & gcvPOWER_FLAG_POWER_OFF) ? gcvFALSE
+ : gcvTRUE;
+ }
+
+ /* Get time until off. */
+ gcmkPROFILE_QUERY(time, offTime);
+
+
+ /* Get time until started. */
+ gcmkPROFILE_QUERY(time, startTime);
+
+ if (flag & gcvPOWER_FLAG_RELEASE)
+ {
+ /* Release the power management semaphore. */
+ gcmkONERROR(gckOS_ReleaseSemaphore(os, command->powerSemaphore));
+ acquired = gcvFALSE;
+ }
+
+ /* Save the new power state. */
+ Hardware->chipPowerState = State;
+
+ if (global)
+ {
+ /* Save the new power state. */
+ Hardware->chipPowerStateGlobal = State;
+ }
+
+ if (commitMutex)
+ {
+ /* Acquire the mutex. */
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(
+ command->os,
+ command->commitMutex
+ ));
+ }
+
+#if gcdPOWEROFF_TIMEOUT
+ /* Reset power off time */
+ gcmkONERROR(gckOS_GetTicks(&currentTime));
+
+ Hardware->powerOffTime = currentTime + Hardware->powerOffTimeout;
+
+ if (State == gcvPOWER_IDLE)
+ {
+ /* Start a timer to power off GPU when GPU enters IDLE or SUSPEND. */
+ gcmkVERIFY_OK(gckOS_StartTimer(os,
+ Hardware->powerOffTimer,
+ Hardware->powerOffTimeout));
+ }
+ else
+ {
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE, "Cancel powerOfftimer");
+
+ /* Cancel running timer when GPU enters ON or OFF. */
+ gcmkVERIFY_OK(gckOS_StopTimer(os, Hardware->powerOffTimer));
+ }
+#endif
+
+ /* Release the power mutex. */
+ gcmkONERROR(gckOS_ReleaseMutex(os, Hardware->powerMutex));
+
+ /* Get total time. */
+ gcmkPROFILE_QUERY(time, totalTime);
+#if gcdENABLE_PROFILING
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
+ "PROF(%llu): mutex:%llu on:%llu stall:%llu stop:%llu",
+ freq, mutexTime, onTime, stallTime, stopTime);
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
+ " delay:%llu init:%llu off:%llu start:%llu total:%llu",
+ delayTime, initTime, offTime, startTime, totalTime);
+#endif
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+
+ if (acquired)
+ {
+ /* Release semaphore. */
+ gcmkVERIFY_OK(gckOS_ReleaseSemaphore(Hardware->os,
+ command->powerSemaphore));
+ }
+
+ if (mutexAcquired)
+ {
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(Hardware->os, Hardware->powerMutex));
+ }
+
+ if (commitMutex)
+ {
+ /* Acquire the mutex. */
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(
+ command->os,
+ command->commitMutex
+ ));
+ }
+
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+/*******************************************************************************
+**
+** gckHARDWARE_QueryPowerManagementState
+**
+** Get GPU power state.
+**
+** INPUT:
+**
+** gckHARDWARE Harwdare
+** Pointer to an gckHARDWARE object.
+**
+** gceCHIPPOWERSTATE* State
+** Power State.
+**
+*/
+gceSTATUS
+gckVGHARDWARE_QueryPowerManagementState(
+ IN gckVGHARDWARE Hardware,
+ OUT gceCHIPPOWERSTATE* State
+ )
+{
+ gcmkHEADER_ARG("Hardware=0x%x", Hardware);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
+ gcmkVERIFY_ARGUMENT(State != gcvNULL);
+
+ /* Return the statue. */
+ *State = Hardware->chipPowerState;
+
+ /* Success. */
+ gcmkFOOTER_ARG("*State=%d", *State);
+ return gcvSTATUS_OK;
+}
+
+/*******************************************************************************
+**
+** gckVGHARDWARE_SetPowerManagement
+**
+** Configure GPU power management function.
+** Only used in driver initialization stage.
+**
+** INPUT:
+**
+** gckVGHARDWARE Harwdare
+** Pointer to an gckHARDWARE object.
+**
+** gctBOOL PowerManagement
+** Power Mangement State.
+**
+*/
+gceSTATUS
+gckVGHARDWARE_SetPowerManagement(
+ IN gckVGHARDWARE Hardware,
+ IN gctBOOL PowerManagement
+ )
+{
+ gcmkHEADER_ARG("Hardware=0x%x", Hardware);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
+
+ Hardware->options.powerManagement = PowerManagement;
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+}
+
+#if gcdPOWEROFF_TIMEOUT
+gceSTATUS
+gckVGHARDWARE_SetPowerOffTimeout(
+ IN gckVGHARDWARE Hardware,
+ IN gctUINT32 Timeout
+ )
+{
+ gcmkHEADER_ARG("Hardware=0x%x Timeout=%d", Hardware, Timeout);
+
+ Hardware->powerOffTimeout = Timeout;
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+}
+
+
+gceSTATUS
+gckVGHARDWARE_QueryPowerOffTimeout(
+ IN gckVGHARDWARE Hardware,
+ OUT gctUINT32* Timeout
+ )
+{
+ gcmkHEADER_ARG("Hardware=0x%x", Hardware);
+
+ *Timeout = Hardware->powerOffTimeout;
+
+ gcmkFOOTER_ARG("*Timeout=%d", *Timeout);
+ return gcvSTATUS_OK;
+}
+#endif
+
+gceSTATUS
+gckVGHARDWARE_QueryIdle(
+ IN gckVGHARDWARE Hardware,
+ OUT gctBOOL_PTR IsIdle
+ )
+{
+ gceSTATUS status;
+ gctUINT32 idle;
+
+ gcmkHEADER_ARG("Hardware=0x%x", Hardware);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
+ gcmkVERIFY_ARGUMENT(IsIdle != gcvNULL);
+
+ /* We are idle when the power is not ON. */
+ if (Hardware->chipPowerState != gcvPOWER_ON)
+ {
+ *IsIdle = gcvTRUE;
+ }
+
+ else
+ {
+ /* Read idle register. */
+ gcmkONERROR(
+ gckOS_ReadRegisterEx(Hardware->os, gcvCORE_VG, 0x00004, &idle));
+
+ /* Pipe must be idle. */
+ if (((((((gctUINT32) (idle)) >> (0 ? 0:0)) & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1)))))) ) != 1)
+ || ((((((gctUINT32) (idle)) >> (0 ? 8:8)) & ((gctUINT32) ((((1 ? 8:8) - (0 ? 8:8) + 1) == 32) ? ~0U : (~(~0U << ((1 ? 8:8) - (0 ? 8:8) + 1)))))) ) != 1)
+ || ((((((gctUINT32) (idle)) >> (0 ? 9:9)) & ((gctUINT32) ((((1 ? 9:9) - (0 ? 9:9) + 1) == 32) ? ~0U : (~(~0U << ((1 ? 9:9) - (0 ? 9:9) + 1)))))) ) != 1)
+ || ((((((gctUINT32) (idle)) >> (0 ? 10:10)) & ((gctUINT32) ((((1 ? 10:10) - (0 ? 10:10) + 1) == 32) ? ~0U : (~(~0U << ((1 ? 10:10) - (0 ? 10:10) + 1)))))) ) != 1)
+ || ((((((gctUINT32) (idle)) >> (0 ? 11:11)) & ((gctUINT32) ((((1 ? 11:11) - (0 ? 11:11) + 1) == 32) ? ~0U : (~(~0U << ((1 ? 11:11) - (0 ? 11:11) + 1)))))) ) != 1)
+ )
+ {
+ /* Something is busy. */
+ *IsIdle = gcvFALSE;
+ }
+
+ else
+ {
+ *IsIdle = gcvTRUE;
+ }
+ }
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+#endif /* gcdENABLE_VG */
+
diff --git a/drivers/mxc/gpu-viv/hal/kernel/archvg/gc_hal_kernel_hardware_vg.h b/drivers/mxc/gpu-viv/hal/kernel/archvg/gc_hal_kernel_hardware_vg.h
new file mode 100644
index 000000000000..236c0afb14e6
--- /dev/null
+++ b/drivers/mxc/gpu-viv/hal/kernel/archvg/gc_hal_kernel_hardware_vg.h
@@ -0,0 +1,110 @@
+/****************************************************************************
+*
+* The MIT License (MIT)
+*
+* Copyright (c) 2014 - 2018 Vivante 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 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 GPL License (GPL)
+*
+* Copyright (C) 2014 - 2018 Vivante 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.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+*****************************************************************************
+*
+* Note: This software is released under dual MIT and GPL licenses. A
+* recipient may use this file under the terms of either the MIT license or
+* GPL License. If you wish to use only one license not the other, you can
+* indicate your decision by deleting one of the above license notices in your
+* version of this file.
+*
+*****************************************************************************/
+
+
+#ifndef __gc_hal_kernel_hardware_vg_h_
+#define __gc_hal_kernel_hardware_vg_h_
+
+/* gckHARDWARE object. */
+struct _gckVGHARDWARE
+{
+ /* Object. */
+ gcsOBJECT object;
+
+ /* Pointer to gckKERNEL object. */
+ gckVGKERNEL kernel;
+
+ /* Pointer to gckOS object. */
+ gckOS os;
+
+ /* Chip characteristics. */
+ gceCHIPMODEL chipModel;
+ gctUINT32 chipRevision;
+ gctUINT32 productID;
+ gctUINT32 ecoID;
+ gctUINT32 customerID;
+ gctUINT32 chipFeatures;
+ gctUINT32 chipMinorFeatures;
+ gctUINT32 chipMinorFeatures2;
+
+ /* Features. */
+ gctBOOL fe20;
+ gctBOOL vg20;
+ gctBOOL vg21;
+ gctBOOL fc;
+
+ /* Event mask. */
+ gctUINT32 eventMask;
+
+ gctBOOL clockState;
+ gctBOOL powerState;
+ gctPOINTER powerMutex;
+ gctUINT32 powerProcess;
+ gctUINT32 powerThread;
+ gceCHIPPOWERSTATE chipPowerState;
+ gceCHIPPOWERSTATE chipPowerStateGlobal;
+ gctPOINTER pageTableDirty;
+#if gcdPOWEROFF_TIMEOUT
+ gctUINT32 powerOffTime;
+ gctUINT32 powerOffTimeout;
+ gctPOINTER powerOffTimer;
+#endif
+
+ gcsHAL_QUERY_CHIP_OPTIONS options;
+
+ gctPOINTER featureDatabase;
+};
+
+#endif /* __gc_hal_kernel_hardware_h_ */
+
diff --git a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.c b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.c
new file mode 100644
index 000000000000..5260aef60149
--- /dev/null
+++ b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.c
@@ -0,0 +1,6637 @@
+/****************************************************************************
+*
+* The MIT License (MIT)
+*
+* Copyright (c) 2014 - 2018 Vivante 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 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 GPL License (GPL)
+*
+* Copyright (C) 2014 - 2018 Vivante 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.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+*****************************************************************************
+*
+* Note: This software is released under dual MIT and GPL licenses. A
+* recipient may use this file under the terms of either the MIT license or
+* GPL License. If you wish to use only one license not the other, you can
+* indicate your decision by deleting one of the above license notices in your
+* version of this file.
+*
+*****************************************************************************/
+
+
+#include "gc_hal_kernel_precomp.h"
+
+#if gcdDEC_ENABLE_AHB
+#include "viv_dec300_main.h"
+#endif
+
+#define _GC_OBJ_ZONE gcvZONE_KERNEL
+
+/*******************************************************************************
+***** Version Signature *******************************************************/
+
+#define _gcmTXT2STR(t) #t
+#define gcmTXT2STR(t) _gcmTXT2STR(t)
+const char * _VERSION = "\n\0$VERSION$"
+ gcmTXT2STR(gcvVERSION_MAJOR) "."
+ gcmTXT2STR(gcvVERSION_MINOR) "."
+ gcmTXT2STR(gcvVERSION_PATCH) ":"
+ gcmTXT2STR(gcvVERSION_BUILD) "$\n";
+
+/******************************************************************************\
+******************************* gckKERNEL API Code ******************************
+\******************************************************************************/
+
+#if gcmIS_DEBUG(gcdDEBUG_TRACE)
+#define gcmDEFINE2TEXT(d) #d
+gctCONST_STRING _DispatchText[] =
+{
+ gcmDEFINE2TEXT(gcvHAL_QUERY_VIDEO_MEMORY),
+ gcmDEFINE2TEXT(gcvHAL_QUERY_CHIP_IDENTITY),
+ gcmDEFINE2TEXT(gcvHAL_QUERY_CHIP_FREQUENCY),
+ gcmDEFINE2TEXT(gcvHAL_ALLOCATE_NON_PAGED_MEMORY),
+ gcmDEFINE2TEXT(gcvHAL_FREE_NON_PAGED_MEMORY),
+ gcmDEFINE2TEXT(gcvHAL_ALLOCATE_CONTIGUOUS_MEMORY),
+ gcmDEFINE2TEXT(gcvHAL_FREE_CONTIGUOUS_MEMORY),
+ gcmDEFINE2TEXT(gcvHAL_ALLOCATE_VIDEO_MEMORY),
+ gcmDEFINE2TEXT(gcvHAL_ALLOCATE_LINEAR_VIDEO_MEMORY),
+ gcmDEFINE2TEXT(gcvHAL_RELEASE_VIDEO_MEMORY),
+ gcmDEFINE2TEXT(gcvHAL_MAP_MEMORY),
+ gcmDEFINE2TEXT(gcvHAL_UNMAP_MEMORY),
+ gcmDEFINE2TEXT(gcvHAL_MAP_USER_MEMORY),
+ gcmDEFINE2TEXT(gcvHAL_UNMAP_USER_MEMORY),
+ gcmDEFINE2TEXT(gcvHAL_LOCK_VIDEO_MEMORY),
+ gcmDEFINE2TEXT(gcvHAL_UNLOCK_VIDEO_MEMORY),
+ gcmDEFINE2TEXT(gcvHAL_EVENT_COMMIT),
+ gcmDEFINE2TEXT(gcvHAL_USER_SIGNAL),
+ gcmDEFINE2TEXT(gcvHAL_SIGNAL),
+ gcmDEFINE2TEXT(gcvHAL_WRITE_DATA),
+ gcmDEFINE2TEXT(gcvHAL_COMMIT),
+ gcmDEFINE2TEXT(gcvHAL_STALL),
+ gcmDEFINE2TEXT(gcvHAL_READ_REGISTER),
+ gcmDEFINE2TEXT(gcvHAL_WRITE_REGISTER),
+ gcmDEFINE2TEXT(gcvHAL_GET_PROFILE_SETTING),
+ gcmDEFINE2TEXT(gcvHAL_SET_PROFILE_SETTING),
+ gcmDEFINE2TEXT(gcvHAL_PROFILE_REGISTERS_2D),
+ gcmDEFINE2TEXT(gcvHAL_READ_ALL_PROFILE_REGISTERS_PART1),
+ gcmDEFINE2TEXT(gcvHAL_READ_ALL_PROFILE_REGISTERS_PART2),
+ gcmDEFINE2TEXT(gcvHAL_READ_PROFILER_REGISTER_SETTING),
+ gcmDEFINE2TEXT(gcvHAL_SET_POWER_MANAGEMENT_STATE),
+ gcmDEFINE2TEXT(gcvHAL_QUERY_POWER_MANAGEMENT_STATE),
+ gcmDEFINE2TEXT(gcvHAL_GET_BASE_ADDRESS),
+ gcmDEFINE2TEXT(gcvHAL_SET_IDLE),
+ gcmDEFINE2TEXT(gcvHAL_QUERY_KERNEL_SETTINGS),
+ gcmDEFINE2TEXT(gcvHAL_RESET),
+ gcmDEFINE2TEXT(gcvHAL_MAP_PHYSICAL),
+ gcmDEFINE2TEXT(gcvHAL_DEBUG),
+ gcmDEFINE2TEXT(gcvHAL_CACHE),
+ gcmDEFINE2TEXT(gcvHAL_TIMESTAMP),
+ gcmDEFINE2TEXT(gcvHAL_DATABASE),
+ gcmDEFINE2TEXT(gcvHAL_VERSION),
+ gcmDEFINE2TEXT(gcvHAL_CHIP_INFO),
+ gcmDEFINE2TEXT(gcvHAL_ATTACH),
+ gcmDEFINE2TEXT(gcvHAL_DETACH),
+ gcmDEFINE2TEXT(gcvHAL_SET_TIMEOUT),
+ gcmDEFINE2TEXT(gcvHAL_GET_FRAME_INFO),
+ gcmDEFINE2TEXT(gcvHAL_DUMP_GPU_PROFILE),
+ gcmDEFINE2TEXT(gcvHAL_QUERY_COMMAND_BUFFER),
+ gcmDEFINE2TEXT(gcvHAL_COMMIT_DONE),
+ gcmDEFINE2TEXT(gcvHAL_DUMP_GPU_STATE),
+ gcmDEFINE2TEXT(gcvHAL_DUMP_EVENT),
+ gcmDEFINE2TEXT(gcvHAL_ALLOCATE_VIRTUAL_COMMAND_BUFFER),
+ gcmDEFINE2TEXT(gcvHAL_FREE_VIRTUAL_COMMAND_BUFFER),
+ gcmDEFINE2TEXT(gcvHAL_SET_FSCALE_VALUE),
+ gcmDEFINE2TEXT(gcvHAL_GET_FSCALE_VALUE),
+ gcmDEFINE2TEXT(gcvHAL_EXPORT_VIDEO_MEMORY),
+ gcmDEFINE2TEXT(gcvHAL_NAME_VIDEO_MEMORY),
+ gcmDEFINE2TEXT(gcvHAL_IMPORT_VIDEO_MEMORY),
+ gcmDEFINE2TEXT(gcvHAL_QUERY_RESET_TIME_STAMP),
+ gcmDEFINE2TEXT(gcvHAL_READ_REGISTER_EX),
+ gcmDEFINE2TEXT(gcvHAL_WRITE_REGISTER_EX),
+ gcmDEFINE2TEXT(gcvHAL_CREATE_NATIVE_FENCE),
+ gcmDEFINE2TEXT(gcvHAL_WAIT_NATIVE_FENCE),
+ gcmDEFINE2TEXT(gcvHAL_DESTROY_MMU),
+ gcmDEFINE2TEXT(gcvHAL_SHBUF),
+ gcmDEFINE2TEXT(gcvHAL_GET_GRAPHIC_BUFFER_FD),
+ gcmDEFINE2TEXT(gcvHAL_SET_VIDEO_MEMORY_METADATA),
+ gcmDEFINE2TEXT(gcvHAL_GET_VIDEO_MEMORY_FD),
+ gcmDEFINE2TEXT(gcvHAL_CONFIG_POWER_MANAGEMENT),
+ gcmDEFINE2TEXT(gcvHAL_WRAP_USER_MEMORY),
+ gcmDEFINE2TEXT(gcvHAL_WAIT_FENCE),
+#if gcdDEC_ENABLE_AHB
+ gcmDEFINE2TEXT(gcvHAL_DEC300_READ),
+ gcmDEFINE2TEXT(gcvHAL_DEC300_WRITE),
+ gcmDEFINE2TEXT(gcvHAL_DEC300_FLUSH),
+ gcmDEFINE2TEXT(gcvHAL_DEC300_FLUSH_WAIT),
+#endif
+ gcmDEFINE2TEXT(gcvHAL_BOTTOM_HALF_UNLOCK_VIDEO_MEMORY),
+ gcmDEFINE2TEXT(gcvHAL_QUERY_CHIP_OPTION),
+};
+#endif
+
+#if gcdGPU_TIMEOUT && gcdINTERRUPT_STATISTIC
+void
+_MonitorTimerFunction(
+ gctPOINTER Data
+ )
+{
+ gckKERNEL kernel = (gckKERNEL)Data;
+ gctINT32 pendingInterrupt;
+ gctBOOL reset = gcvFALSE;
+ gctINT32 mask;
+ gctUINT32 advance = kernel->timeOut/2;
+
+#if gcdENABLE_VG
+ if (kernel->core == gcvCORE_VG)
+ {
+ return;
+ }
+#endif
+
+ if (kernel->monitorTimerStop)
+ {
+ /* Stop. */
+ return;
+ }
+
+ gckOS_AtomGet(kernel->os, kernel->eventObj->interruptCount, &pendingInterrupt);
+
+ if (pendingInterrupt < 0)
+ {
+ gctINT i = 0 - pendingInterrupt;
+ gctINT pendingMask;
+
+ gcmkVERIFY_OK(gckOS_AtomGet(
+ kernel->os,
+ kernel->hardware->pendingEvent,
+ &pendingMask
+ ));
+
+ gcmkPRINT("[galcore]: Number of pending interrupt is %d mask is %x",
+ pendingInterrupt, pendingMask);
+
+ while (i--)
+ {
+ /* Ignore counting which should not exist. */
+ gckOS_AtomIncrement(kernel->os, kernel->eventObj->interruptCount, &pendingInterrupt);
+ }
+
+ gckOS_AtomGet(kernel->os, kernel->eventObj->interruptCount, &pendingInterrupt);
+ }
+
+ if (kernel->monitoring == gcvFALSE)
+ {
+ if (pendingInterrupt)
+ {
+ /* Begin to mointor GPU state. */
+ kernel->monitoring = gcvTRUE;
+
+ /* Record current state. */
+ kernel->lastCommitStamp = kernel->eventObj->lastCommitStamp;
+ kernel->restoreAddress = kernel->hardware->lastWaitLink;
+ gcmkVERIFY_OK(gckOS_AtomGet(
+ kernel->os,
+ kernel->hardware->pendingEvent,
+ &kernel->restoreMask
+ ));
+
+ /* Clear timeout. */
+ kernel->timer = 0;
+ }
+ }
+ else
+ {
+ if (pendingInterrupt)
+ {
+ gcmkVERIFY_OK(gckOS_AtomGet(
+ kernel->os,
+ kernel->hardware->pendingEvent,
+ &mask
+ ));
+
+ if (kernel->eventObj->lastCommitStamp == kernel->lastCommitStamp
+ && kernel->hardware->lastWaitLink == kernel->restoreAddress
+ && mask == kernel->restoreMask
+ )
+ {
+ /* GPU state is not changed, accumlate timeout. */
+ kernel->timer += advance;
+
+ if (kernel->timer >= kernel->timeOut)
+ {
+ /* GPU stuck, trigger reset. */
+ reset = gcvTRUE;
+ }
+ }
+ else
+ {
+ /* GPU state changed, cancel current timeout.*/
+ kernel->monitoring = gcvFALSE;
+ }
+ }
+ else
+ {
+ /* GPU finish all jobs, cancel current timeout*/
+ kernel->monitoring = gcvFALSE;
+ }
+ }
+
+ if (reset)
+ {
+ gckKERNEL_Recovery(kernel);
+
+ /* Work in this timeout is done. */
+ kernel->monitoring = gcvFALSE;
+ }
+
+ gcmkVERIFY_OK(gckOS_StartTimer(kernel->os, kernel->monitorTimer, advance));
+}
+#endif
+
+#if gcdPROCESS_ADDRESS_SPACE
+gceSTATUS
+_MapCommandBuffer(
+ IN gckKERNEL Kernel
+ )
+{
+ gceSTATUS status;
+ gctUINT32 i;
+ gctPHYS_ADDR_T physical;
+ gctUINT32 address;
+ gckMMU mmu;
+
+ gcmkONERROR(gckKERNEL_GetProcessMMU(Kernel, &mmu));
+
+ for (i = 0; i < gcdCOMMAND_QUEUES; i++)
+ {
+ gcmkONERROR(gckOS_GetPhysicalAddress(
+ Kernel->os,
+ Kernel->command->queues[i].logical,
+ &physical
+ ));
+
+ gcmkVERIFY_OK(gckOS_CPUPhysicalToGPUPhysical(Kernel->os, physical, &physical));
+
+ gcmkSAFECASTPHYSADDRT(address, physical);
+
+ gcmkONERROR(gckMMU_FlatMapping(mmu, address, 1));
+ }
+
+ return gcvSTATUS_OK;
+
+OnError:
+ return status;
+}
+#endif
+
+void
+_DumpDriverConfigure(
+ IN gckKERNEL Kernel
+ )
+{
+ gcmkPRINT_N(0, "**************************\n");
+ gcmkPRINT_N(0, "*** GPU DRV CONFIG ***\n");
+ gcmkPRINT_N(0, "**************************\n");
+
+ gcmkPRINT("Galcore version %d.%d.%d.%d\n",
+ gcvVERSION_MAJOR, gcvVERSION_MINOR, gcvVERSION_PATCH, gcvVERSION_BUILD);
+
+ gckOS_DumpParam();
+}
+
+void
+_DumpState(
+ IN gckKERNEL Kernel
+ )
+{
+ /* Dump GPU Debug registers. */
+ gcmkVERIFY_OK(gckHARDWARE_DumpGPUState(Kernel->hardware));
+
+ gcmkVERIFY_OK(gckCOMMAND_DumpExecutingBuffer(Kernel->command));
+
+ /* Dump Pending event. */
+ gcmkVERIFY_OK(gckEVENT_Dump(Kernel->eventObj));
+
+ /* Dump Process DB. */
+ gcmkVERIFY_OK(gckKERNEL_DumpProcessDB(Kernel));
+
+#if gcdRECORD_COMMAND
+ /* Dump record. */
+ gckRECORDER_Dump(Kernel->command->recorder);
+#endif
+}
+
+static gceHARDWARE_TYPE
+_GetHardwareType(
+ IN gckKERNEL Kernel
+ )
+{
+ gceHARDWARE_TYPE type;
+ gcmkHEADER();
+ gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
+
+#if gcdENABLE_VG
+ if (Kernel->vg)
+ {
+ type = gcvHARDWARE_VG;
+ }
+ else
+#endif
+ {
+ type = Kernel->hardware->type;
+ }
+
+ gcmkFOOTER_ARG("type=%d", type);
+ return type;
+}
+
+gceSTATUS
+_SetRecovery(
+ IN gckKERNEL Kernel,
+ IN gctBOOL Recovery,
+ IN gctUINT32 StuckDump
+ )
+{
+ Kernel->recovery = Recovery;
+
+ if (Recovery == gcvFALSE)
+ {
+ /* Dump stuck information if Recovery is disabled. */
+ Kernel->stuckDump = gcmMAX(StuckDump, gcvSTUCK_DUMP_USER_COMMAND);
+ }
+
+ return gcvSTATUS_OK;
+}
+
+/*******************************************************************************
+**
+** gckKERNEL_Construct
+**
+** Construct a new gckKERNEL object.
+**
+** INPUT:
+**
+** gckOS Os
+** Pointer to an gckOS object.
+**
+** gceCORE Core
+** Specified core.
+**
+** IN gctPOINTER Context
+** Pointer to a driver defined context.
+**
+** IN gckDB SharedDB,
+** Pointer to a shared DB.
+**
+** OUTPUT:
+**
+** gckKERNEL * Kernel
+** Pointer to a variable that will hold the pointer to the gckKERNEL
+** object.
+*/
+
+gceSTATUS
+gckKERNEL_Construct(
+ IN gckOS Os,
+ IN gceCORE Core,
+ IN gctUINT ChipID,
+ IN gctPOINTER Context,
+ IN gckDEVICE Device,
+ IN gckDB SharedDB,
+ OUT gckKERNEL * Kernel
+ )
+{
+ gckKERNEL kernel = gcvNULL;
+ gceSTATUS status;
+ gctSIZE_T i;
+ gctPOINTER pointer = gcvNULL;
+ gctUINT32 recovery;
+ gctUINT32 stuckDump;
+
+ gcmkHEADER_ARG("Os=0x%x Context=0x%x", Os, Context);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
+ gcmkVERIFY_ARGUMENT(Kernel != gcvNULL);
+
+ /* Allocate the gckKERNEL object. */
+ gcmkONERROR(gckOS_Allocate(Os,
+ gcmSIZEOF(struct _gckKERNEL),
+ &pointer));
+
+ /* Zero the object. */
+ gckOS_ZeroMemory(pointer, gcmSIZEOF(struct _gckKERNEL));
+
+ kernel = pointer;
+
+ /* Initialize the gckKERNEL object. */
+ kernel->object.type = gcvOBJ_KERNEL;
+ kernel->os = Os;
+ kernel->core = Core;
+ kernel->device = Device;
+ kernel->chipID = ChipID;
+
+#if gcdENABLE_TRUST_APPLICATION
+ /* Connect to security service for this GPU. */
+ gcmkONERROR(gckKERNEL_SecurityOpen(kernel, kernel->core, &kernel->securityChannel));
+#endif
+
+ if (SharedDB == gcvNULL)
+ {
+ gcmkONERROR(gckOS_Allocate(Os,
+ gcmSIZEOF(struct _gckDB),
+ &pointer));
+
+ kernel->db = pointer;
+ kernel->dbCreated = gcvTRUE;
+ kernel->db->freeDatabase = gcvNULL;
+ kernel->db->freeRecord = gcvNULL;
+ kernel->db->dbMutex = gcvNULL;
+ kernel->db->lastDatabase = gcvNULL;
+ kernel->db->idleTime = 0;
+ kernel->db->lastIdle = 0;
+ kernel->db->lastSlowdown = 0;
+
+ for (i = 0; i < gcmCOUNTOF(kernel->db->db); ++i)
+ {
+ kernel->db->db[i] = gcvNULL;
+ }
+
+ /* Construct a database mutex. */
+ gcmkONERROR(gckOS_CreateMutex(Os, &kernel->db->dbMutex));
+
+ /* Construct a video memory name database. */
+ gcmkONERROR(gckKERNEL_CreateIntegerDatabase(kernel, &kernel->db->nameDatabase));
+
+ /* Construct a video memory name database mutex. */
+ gcmkONERROR(gckOS_CreateMutex(Os, &kernel->db->nameDatabaseMutex));
+
+ /* Construct a pointer name database. */
+ gcmkONERROR(gckKERNEL_CreateIntegerDatabase(kernel, &kernel->db->pointerDatabase));
+
+ /* Construct a pointer name database mutex. */
+ gcmkONERROR(gckOS_CreateMutex(Os, &kernel->db->pointerDatabaseMutex));
+
+ /* Initialize on fault vidmem list. */
+ gcsLIST_Init(&kernel->db->onFaultVidmemList);
+ }
+ else
+ {
+ kernel->db = SharedDB;
+ kernel->dbCreated = gcvFALSE;
+ }
+
+ for (i = 0; i < gcmCOUNTOF(kernel->timers); ++i)
+ {
+ kernel->timers[i].startTime = 0;
+ kernel->timers[i].stopTime = 0;
+ }
+
+ /* Save context. */
+ kernel->context = Context;
+
+ /* Construct atom holding number of clients. */
+ kernel->atomClients = gcvNULL;
+ gcmkONERROR(gckOS_AtomConstruct(Os, &kernel->atomClients));
+
+ kernel->recovery = gcvTRUE;
+ kernel->stuckDump = gcvSTUCK_DUMP_NONE;
+
+ /* Override default recovery and stuckDump setting. */
+ status = gckOS_QueryOption(Os, "recovery", &recovery);
+
+ if (gcmIS_SUCCESS(status))
+ {
+ status = gckOS_QueryOption(Os, "stuckDump", &stuckDump);
+
+ gcmkASSERT(status == gcvSTATUS_OK);
+
+ _SetRecovery(kernel, recovery, stuckDump);
+ }
+
+ /* Need the kernel reference before gckKERNEL_Construct() completes.
+ gckOS_MapPagesEx() is called to map kernel virtual command buffers. */
+ *Kernel = kernel;
+
+ kernel->virtualBufferHead =
+ kernel->virtualBufferTail = gcvNULL;
+
+ gcmkONERROR(
+ gckOS_CreateMutex(Os, (gctPOINTER)&kernel->virtualBufferLock));
+
+#if gcdENABLE_VG
+ kernel->vg = gcvNULL;
+
+ if (Core == gcvCORE_VG)
+ {
+ gctUINT32 contiguousBase;
+ gctUINT32 contiguousSize = 0;
+
+ /* Construct the gckMMU object. */
+ gcmkONERROR(
+ gckVGKERNEL_Construct(Os, Context, kernel, &kernel->vg));
+
+ kernel->timeOut = gcdGPU_TIMEOUT;
+
+ status = gckOS_QueryOption(Os, "contiguousBase", &contiguousBase);
+
+ if (gcmIS_SUCCESS(status))
+ {
+ status = gckOS_QueryOption(Os, "contiguousSize", &contiguousSize);
+ }
+
+ if (gcmIS_SUCCESS(status) && contiguousSize)
+ {
+ gctUINT64 gpuContiguousBase;
+
+ gcmkONERROR(gckOS_CPUPhysicalToGPUPhysical(Os, contiguousBase, &gpuContiguousBase));
+
+ gcmkSAFECASTPHYSADDRT(kernel->contiguousBaseAddress, gpuContiguousBase);
+ }
+ }
+ else
+#endif
+ {
+ /* Construct the gckHARDWARE object. */
+ gcmkONERROR(
+ gckHARDWARE_Construct(Os, kernel->core, &kernel->hardware));
+
+ /* Set pointer to gckKERNEL object in gckHARDWARE object. */
+ kernel->hardware->kernel = kernel;
+
+ kernel->timeOut = kernel->hardware->type == gcvHARDWARE_2D
+ ? gcdGPU_2D_TIMEOUT
+ : gcdGPU_TIMEOUT
+ ;
+
+ /* Initialize virtual command buffer. */
+#if gcdALLOC_CMD_FROM_RESERVE || gcdSECURITY || gcdDISABLE_GPU_VIRTUAL_ADDRESS || !USE_KERNEL_VIRTUAL_BUFFERS
+ kernel->virtualCommandBuffer = gcvFALSE;
+#else
+ kernel->virtualCommandBuffer = kernel->hardware->options.enableMMU;
+#endif
+
+#if gcdSHARED_PAGETABLE
+ /* Construct the gckMMU object. */
+ gcmkONERROR(
+ gckMMU_Construct(kernel, gcdMMU_SIZE, &kernel->mmu));
+#else
+ if (Device == gcvNULL)
+ {
+ /* Construct the gckMMU object. */
+ gcmkONERROR(
+ gckMMU_Construct(kernel, gcdMMU_SIZE, &kernel->mmu));
+ }
+ else
+ {
+ gcmkONERROR(gckDEVICE_GetMMU(Device, kernel->hardware->type, &kernel->mmu));
+
+ if (kernel->mmu == gcvNULL)
+ {
+ gcmkONERROR(
+ gckMMU_Construct(kernel, gcdMMU_SIZE, &kernel->mmu));
+
+ gcmkONERROR(
+ gckDEVICE_SetMMU(Device, kernel->hardware->type, kernel->mmu));
+ }
+ }
+
+ gcmkVERIFY_OK(gckMMU_AttachHardware(kernel->mmu, kernel->hardware));
+#endif
+
+ kernel->contiguousBaseAddress = kernel->mmu->contiguousBaseAddress;
+ kernel->externalBaseAddress = kernel->mmu->externalBaseAddress;
+
+ /* Construct the gckCOMMAND object. */
+ gcmkONERROR(
+ gckCOMMAND_Construct(kernel, &kernel->command));
+
+ if (gckHARDWARE_IsFeatureAvailable(kernel->hardware, gcvFEATURE_ASYNC_BLIT))
+ {
+ /* Construct the gckASYNC_COMMAND object for BLT engine. */
+ gcmkONERROR(gckASYNC_COMMAND_Construct(kernel, &kernel->asyncCommand));
+
+ /* Construct gckEVENT for BLT. */
+ gcmkONERROR(gckEVENT_Construct(kernel, &kernel->asyncEvent));
+
+ kernel->asyncEvent->asyncCommand = kernel->asyncCommand;
+
+ kernel->command->asyncCommand = kernel->asyncCommand;
+ }
+
+ /* Construct the gckEVENT object. */
+ gcmkONERROR(
+ gckEVENT_Construct(kernel, &kernel->eventObj));
+
+ gcmkVERIFY_OK(gckOS_GetTime(&kernel->resetTimeStamp));
+
+ gcmkONERROR(gckHARDWARE_PrepareFunctions(kernel->hardware));
+
+ /* Initialize the hardware. */
+ gcmkONERROR(
+ gckHARDWARE_InitializeHardware(kernel->hardware));
+
+#if gcdDVFS
+ if (gckHARDWARE_IsFeatureAvailable(kernel->hardware,
+ gcvFEATURE_DYNAMIC_FREQUENCY_SCALING))
+ {
+ gcmkONERROR(gckDVFS_Construct(kernel->hardware, &kernel->dvfs));
+ gcmkONERROR(gckDVFS_Start(kernel->dvfs));
+ }
+#endif
+
+#if COMMAND_PROCESSOR_VERSION == 1
+ /* Start the command queue. */
+ gcmkONERROR(gckCOMMAND_Start(kernel->command));
+#endif
+ }
+
+#if VIVANTE_PROFILER
+ /* Initialize profile setting */
+ kernel->profileEnable = gcvFALSE;
+ kernel->profileCleanRegister = gcvTRUE;
+#endif
+
+#if gcdLINUX_SYNC_FILE
+ gcmkONERROR(gckOS_CreateSyncTimeline(Os, Core, &kernel->timeline));
+#endif
+
+#if gcdSECURITY
+ /* Connect to security service for this GPU. */
+ gcmkONERROR(gckKERNEL_SecurityOpen(kernel, kernel->core, &kernel->securityChannel));
+#endif
+
+#if gcdGPU_TIMEOUT && gcdINTERRUPT_STATISTIC
+ if (kernel->timeOut)
+ {
+ gcmkVERIFY_OK(gckOS_CreateTimer(
+ Os,
+ (gctTIMERFUNCTION)_MonitorTimerFunction,
+ (gctPOINTER)kernel,
+ &kernel->monitorTimer
+ ));
+
+ kernel->monitoring = gcvFALSE;
+
+ kernel->monitorTimerStop = gcvFALSE;
+
+ gcmkVERIFY_OK(gckOS_StartTimer(
+ Os,
+ kernel->monitorTimer,
+ 100
+ ));
+ }
+#endif
+
+ /* Return pointer to the gckKERNEL object. */
+ *Kernel = kernel;
+
+ /* Success. */
+ gcmkFOOTER_ARG("*Kernel=0x%x", *Kernel);
+ return gcvSTATUS_OK;
+
+OnError:
+ *Kernel = gcvNULL;
+
+ if (kernel != gcvNULL)
+ {
+ gckKERNEL_Destroy(kernel);
+ }
+
+ /* Return the error. */
+ gcmkFOOTER();
+ return status;
+}
+
+/*******************************************************************************
+**
+** gckKERNEL_Destroy
+**
+** Destroy an gckKERNEL object.
+**
+** INPUT:
+**
+** gckKERNEL Kernel
+** Pointer to an gckKERNEL object to destroy.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckKERNEL_Destroy(
+ IN gckKERNEL Kernel
+ )
+{
+ gctSIZE_T i;
+ gcsDATABASE_PTR database, databaseNext;
+ gcsDATABASE_RECORD_PTR record, recordNext;
+
+ gcmkHEADER_ARG("Kernel=0x%x", Kernel);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
+#if QNX_SINGLE_THREADED_DEBUGGING
+ gcmkVERIFY_OK(gckOS_DeleteMutex(Kernel->os, Kernel->debugMutex));
+#endif
+
+ /* Destroy the database. */
+ if (Kernel->dbCreated)
+ {
+ for (i = 0; i < gcmCOUNTOF(Kernel->db->db); ++i)
+ {
+ if (Kernel->db->db[i] != gcvNULL)
+ {
+ gcmkVERIFY_OK(
+ gckKERNEL_DestroyProcessDB(Kernel, Kernel->db->db[i]->processID));
+ }
+ }
+
+ /* Free all databases. */
+ for (database = Kernel->db->freeDatabase;
+ database != gcvNULL;
+ database = databaseNext)
+ {
+ databaseNext = database->next;
+
+ if (database->counterMutex)
+ {
+ gcmkVERIFY_OK(gckOS_DeleteMutex(Kernel->os, database->counterMutex));
+ }
+
+ gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Kernel->os, database));
+ }
+
+ if (Kernel->db->lastDatabase != gcvNULL)
+ {
+ if (Kernel->db->lastDatabase->counterMutex)
+ {
+ gcmkVERIFY_OK(gckOS_DeleteMutex(Kernel->os, Kernel->db->lastDatabase->counterMutex));
+ }
+
+ gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Kernel->os, Kernel->db->lastDatabase));
+ }
+
+ /* Free all database records. */
+ for (record = Kernel->db->freeRecord; record != gcvNULL; record = recordNext)
+ {
+ recordNext = record->next;
+ gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Kernel->os, record));
+ }
+
+ if (Kernel->db->dbMutex)
+ {
+ /* Destroy the database mutex. */
+ gcmkVERIFY_OK(gckOS_DeleteMutex(Kernel->os, Kernel->db->dbMutex));
+ }
+
+ if (Kernel->db->nameDatabase)
+ {
+ /* Destroy video memory name database. */
+ gcmkVERIFY_OK(gckKERNEL_DestroyIntegerDatabase(Kernel, Kernel->db->nameDatabase));
+ }
+
+ if (Kernel->db->nameDatabaseMutex)
+ {
+ /* Destroy video memory name database mutex. */
+ gcmkVERIFY_OK(gckOS_DeleteMutex(Kernel->os, Kernel->db->nameDatabaseMutex));
+ }
+
+ if (Kernel->db->pointerDatabase)
+ {
+ /* Destroy id-pointer database. */
+ gcmkVERIFY_OK(gckKERNEL_DestroyIntegerDatabase(Kernel, Kernel->db->pointerDatabase));
+ }
+
+ if (Kernel->db->pointerDatabaseMutex)
+ {
+ /* Destroy id-pointer database mutex. */
+ gcmkVERIFY_OK(gckOS_DeleteMutex(Kernel->os, Kernel->db->pointerDatabaseMutex));
+ }
+
+ if (Kernel->db)
+ {
+ /* Destroy the database. */
+ gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Kernel->os, Kernel->db));
+ }
+
+ /* Notify stuck timer to quit. */
+ Kernel->monitorTimerStop = gcvTRUE;
+ }
+
+ if (Kernel->monitorTimer)
+ {
+ /* Stop and destroy monitor timer. */
+ gcmkVERIFY_OK(gckOS_StopTimer(Kernel->os, Kernel->monitorTimer));
+ gcmkVERIFY_OK(gckOS_DestroyTimer(Kernel->os, Kernel->monitorTimer));
+ }
+
+#if gcdENABLE_VG
+ if (Kernel->vg)
+ {
+ gcmkVERIFY_OK(gckVGKERNEL_Destroy(Kernel->vg));
+ }
+ else
+#endif
+ {
+ if (Kernel->command)
+ {
+ /* Destroy the gckCOMMNAND object. */
+ gcmkVERIFY_OK(gckCOMMAND_Destroy(Kernel->command));
+ }
+
+ if (Kernel->asyncCommand)
+ {
+ gcmkVERIFY_OK(gckASYNC_COMMAND_Destroy(Kernel->asyncCommand));
+ }
+
+ if (Kernel->asyncEvent)
+ {
+ gcmkVERIFY_OK(gckEVENT_Destroy(Kernel->asyncEvent));
+ }
+
+ if (Kernel->eventObj)
+ {
+ /* Destroy the gckEVENT object. */
+ gcmkVERIFY_OK(gckEVENT_Destroy(Kernel->eventObj));
+ }
+
+ gcmkVERIFY_OK(gckHARDWARE_DestroyFunctions(Kernel->hardware));
+
+ if (Kernel->mmu)
+ {
+#if gcdSHARED_PAGETABLE
+ /* Destroy the gckMMU object. */
+ gcmkVERIFY_OK(gckMMU_Destroy(Kernel->mmu));
+#else
+ if (Kernel->mmu->hardware == Kernel->hardware)
+ {
+ /* Destroy the gckMMU object. */
+ gcmkVERIFY_OK(gckMMU_Destroy(Kernel->mmu));
+ }
+#endif
+ }
+
+ if (Kernel->hardware)
+ {
+ /* Destroy the gckHARDWARE object. */
+ gcmkVERIFY_OK(gckHARDWARE_Destroy(Kernel->hardware));
+ }
+ }
+
+ if (Kernel->atomClients)
+ {
+ /* Detsroy the client atom. */
+ gcmkVERIFY_OK(gckOS_AtomDestroy(Kernel->os, Kernel->atomClients));
+ }
+
+ if (Kernel->virtualBufferLock)
+ {
+ gcmkVERIFY_OK(gckOS_DeleteMutex(Kernel->os, Kernel->virtualBufferLock));
+ }
+
+#if gcdDVFS
+ if (Kernel->dvfs)
+ {
+ gcmkVERIFY_OK(gckDVFS_Stop(Kernel->dvfs));
+ gcmkVERIFY_OK(gckDVFS_Destroy(Kernel->dvfs));
+ }
+#endif
+
+#if gcdLINUX_SYNC_FILE
+ if (Kernel->timeline)
+ {
+ gcmkVERIFY_OK(gckOS_DestroySyncTimeline(Kernel->os, Kernel->timeline));
+ }
+#endif
+
+#if gcdSECURITY
+ if (Kernel->securityChannel)
+ {
+ gcmkVERIFY_OK(gckKERNEL_SecurityClose(Kernel->securityChannel));
+ }
+#endif
+
+ /* Mark the gckKERNEL object as unknown. */
+ Kernel->object.type = gcvOBJ_UNKNOWN;
+
+ /* Free the gckKERNEL object. */
+ gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Kernel->os, Kernel));
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+}
+
+/*******************************************************************************
+**
+** _AllocateMemory
+**
+** Private function to walk all required memory pools to allocate the requested
+** amount of video memory.
+**
+** INPUT:
+**
+** gckKERNEL Kernel
+** Pointer to an gckKERNEL object.
+**
+** gcsHAL_INTERFACE * Interface
+** Pointer to a gcsHAL_INTERFACE structure that defines the command to
+** be dispatched.
+**
+** OUTPUT:
+**
+** gcsHAL_INTERFACE * Interface
+** Pointer to a gcsHAL_INTERFACE structure that receives any data to be
+** returned.
+*/
+gceSTATUS
+gckKERNEL_AllocateLinearMemory(
+ IN gckKERNEL Kernel,
+ IN gctUINT32 ProcessID,
+ IN OUT gcePOOL * Pool,
+ IN gctSIZE_T Bytes,
+ IN gctUINT32 Alignment,
+ IN gceSURF_TYPE Type,
+ IN gctUINT32 Flag,
+ OUT gctUINT32 * Node
+ )
+{
+ gcePOOL pool;
+ gceSTATUS status;
+ gckVIDMEM videoMemory;
+ gctINT loopCount;
+ gcuVIDMEM_NODE_PTR node = gcvNULL;
+ gctBOOL tileStatusInVirtual;
+ gctBOOL contiguous = gcvFALSE;
+ gctBOOL cacheable = gcvFALSE;
+ gctBOOL secure = gcvFALSE;
+ gctBOOL fastPools = gcvFALSE;
+ gctBOOL hasFastPools = gcvFALSE;
+ gctSIZE_T bytes = Bytes;
+ gctUINT32 handle = 0;
+ gceDATABASE_TYPE type;
+
+ gcmkHEADER_ARG("Kernel=0x%x *Pool=%d Bytes=%lu Alignment=%lu Type=%d",
+ Kernel, *Pool, Bytes, Alignment, Type);
+
+ gcmkVERIFY_ARGUMENT(Pool != gcvNULL);
+ gcmkVERIFY_ARGUMENT(Bytes != 0);
+
+ /* Get basic type. */
+ Type &= 0xFF;
+
+ /* Check flags. */
+ contiguous = Flag & gcvALLOC_FLAG_CONTIGUOUS;
+ cacheable = Flag & gcvALLOC_FLAG_CACHEABLE;
+ secure = Flag & gcvALLOC_FLAG_SECURITY;
+ if (Flag & gcvALLOC_FLAG_FAST_POOLS)
+ {
+ fastPools = gcvTRUE;
+ Flag &= ~gcvALLOC_FLAG_FAST_POOLS;
+ }
+
+#if gcdALLOC_ON_FAULT
+ if (Type == gcvSURF_RENDER_TARGET)
+ {
+ Flag |= gcvALLOC_FLAG_ALLOC_ON_FAULT;
+ }
+#endif
+
+ if (Flag & gcvALLOC_FLAG_ALLOC_ON_FAULT)
+ {
+ *Pool = gcvPOOL_VIRTUAL;
+ }
+
+ if (Flag & gcvALLOC_FLAG_DMABUF_EXPORTABLE)
+ {
+ gctSIZE_T pageSize = 0;
+ gckOS_GetPageSize(Kernel->os, &pageSize);
+
+ /* Usually, the exported dmabuf might be later imported to DRM,
+ ** while DRM requires input size to be page aligned.
+ */
+ Bytes = gcmALIGN(Bytes, pageSize);
+ }
+
+AllocateMemory:
+
+ /* Get initial pool. */
+ switch (pool = *Pool)
+ {
+ case gcvPOOL_DEFAULT:
+ case gcvPOOL_LOCAL:
+ pool = gcvPOOL_LOCAL_INTERNAL;
+ loopCount = (gctINT) gcvPOOL_NUMBER_OF_POOLS;
+ break;
+
+ case gcvPOOL_UNIFIED:
+ pool = gcvPOOL_SYSTEM;
+ loopCount = (gctINT) gcvPOOL_NUMBER_OF_POOLS;
+ break;
+
+ case gcvPOOL_CONTIGUOUS:
+ loopCount = (gctINT) gcvPOOL_NUMBER_OF_POOLS;
+ break;
+
+ default:
+ loopCount = 1;
+ break;
+ }
+
+ while (loopCount-- > 0)
+ {
+ if (pool == gcvPOOL_VIRTUAL)
+ {
+ /* Create a gcuVIDMEM_NODE for virtual memory. */
+ gcmkONERROR(
+ gckVIDMEM_ConstructVirtual(Kernel, Flag | gcvALLOC_FLAG_NON_CONTIGUOUS, Bytes, &node));
+
+ bytes = node->Virtual.bytes;
+ node->Virtual.type = Type;
+
+ /* Success. */
+ break;
+ }
+
+ else
+ if (pool == gcvPOOL_CONTIGUOUS)
+ {
+#if gcdCONTIGUOUS_SIZE_LIMIT
+ if (Bytes > gcdCONTIGUOUS_SIZE_LIMIT && contiguous == gcvFALSE)
+ {
+ status = gcvSTATUS_OUT_OF_MEMORY;
+ }
+ else
+#endif
+ {
+ /* Create a gcuVIDMEM_NODE from contiguous memory. */
+ status = gckVIDMEM_ConstructVirtual(
+ Kernel,
+ Flag | gcvALLOC_FLAG_CONTIGUOUS,
+ Bytes,
+ &node);
+ }
+
+ if (gcmIS_SUCCESS(status))
+ {
+ bytes = node->Virtual.bytes;
+ node->Virtual.type = Type;
+
+ /* Memory allocated. */
+ break;
+ }
+ }
+
+ else
+ /* gcvPOOL_SYSTEM can't be cacheable. */
+ if (cacheable == gcvFALSE && secure == gcvFALSE)
+ {
+ /* Get pointer to gckVIDMEM object for pool. */
+ status = gckKERNEL_GetVideoMemoryPool(Kernel, pool, &videoMemory);
+
+ if (gcmIS_SUCCESS(status))
+ {
+ /* Allocate memory. */
+#if defined(gcdLINEAR_SIZE_LIMIT)
+ /* 512 KB */
+ if (Bytes > gcdLINEAR_SIZE_LIMIT)
+ {
+ status = gcvSTATUS_OUT_OF_MEMORY;
+ }
+ else
+#endif
+ {
+ hasFastPools = gcvTRUE;
+ status = gckVIDMEM_AllocateLinear(Kernel,
+ videoMemory,
+ Bytes,
+ Alignment,
+ Type,
+ (*Pool == gcvPOOL_SYSTEM),
+ &node);
+ }
+
+ if (gcmIS_SUCCESS(status))
+ {
+ /* Memory allocated. */
+ node->VidMem.pool = pool;
+ bytes = node->VidMem.bytes;
+ break;
+ }
+ }
+ }
+
+ if (pool == gcvPOOL_LOCAL_INTERNAL)
+ {
+ /* Advance to external memory. */
+ pool = gcvPOOL_LOCAL_EXTERNAL;
+ }
+
+ else
+ if (pool == gcvPOOL_LOCAL_EXTERNAL)
+ {
+ /* Advance to contiguous system memory. */
+ pool = gcvPOOL_SYSTEM;
+ }
+
+ else
+ if (pool == gcvPOOL_SYSTEM)
+ {
+ /* Do not go ahead to try relative slow pools */
+ if (fastPools && hasFastPools)
+ {
+ status = gcvSTATUS_OUT_OF_MEMORY;
+ break;
+ }
+
+ /* Advance to contiguous memory. */
+ pool = gcvPOOL_CONTIGUOUS;
+ }
+
+ else
+ if (pool == gcvPOOL_CONTIGUOUS)
+ {
+#if gcdENABLE_VG
+ if (Kernel->vg)
+ {
+ tileStatusInVirtual = gcvFALSE;
+ }
+ else
+#endif
+ {
+ tileStatusInVirtual =
+ gckHARDWARE_IsFeatureAvailable(Kernel->hardware,
+ gcvFEATURE_MC20);
+ }
+
+ if (Type == gcvSURF_TILE_STATUS && tileStatusInVirtual != gcvTRUE)
+ {
+ gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
+ }
+
+ if (contiguous)
+ {
+ break;
+ }
+
+ /* Advance to virtual memory. */
+ pool = gcvPOOL_VIRTUAL;
+ }
+
+ else
+ {
+ /* Out of pools. */
+ gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
+ }
+ }
+
+ if (node == gcvNULL)
+ {
+ if (contiguous)
+ {
+ /* Broadcast OOM message. */
+ status = gckOS_Broadcast(Kernel->os, Kernel->hardware, gcvBROADCAST_OUT_OF_MEMORY);
+
+ if (gcmIS_SUCCESS(status))
+ {
+ /* Get some memory. */
+ gckOS_Delay(gcvNULL, 1);
+ goto AllocateMemory;
+ }
+ }
+
+ /* Nothing allocated. */
+ gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
+ }
+
+ /* Allocate handle for this video memory. */
+ gcmkONERROR(
+ gckVIDMEM_NODE_Allocate(Kernel, node, Type, pool, &handle));
+
+ /* Return node and pool used for allocation. */
+ *Node = handle;
+ *Pool = pool;
+
+ /* Encode surface type and pool to database type. */
+ type = gcvDB_VIDEO_MEMORY
+ | (Type << gcdDB_VIDEO_MEMORY_TYPE_SHIFT)
+ | (pool << gcdDB_VIDEO_MEMORY_POOL_SHIFT);
+
+ /* Record in process db. */
+ gcmkONERROR(
+ gckKERNEL_AddProcessDB(Kernel,
+ ProcessID,
+ type,
+ gcmINT2PTR(handle),
+ gcvNULL,
+ bytes));
+
+
+ /* Return status. */
+ gcmkFOOTER_ARG("*Pool=%d *Node=0x%x", *Pool, *Node);
+ return gcvSTATUS_OK;
+
+OnError:
+ if (handle)
+ {
+ /* Destroy handle allocated. */
+ gcmkVERIFY_OK(gckVIDMEM_HANDLE_Dereference(Kernel, ProcessID, handle));
+ }
+
+ if (node)
+ {
+ /* Free video memory allocated. */
+ gcmkVERIFY_OK(gckVIDMEM_Free(Kernel, node));
+ }
+
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+/*******************************************************************************
+**
+** gckKERNEL_ReleaseVideoMemory
+**
+** Release handle of a video memory.
+**
+** INPUT:
+**
+** gckKERNEL Kernel
+** Pointer to an gckKERNEL object.
+**
+** gctUINT32 ProcessID
+** ProcessID of current process.
+**
+** gctUINT32 Handle
+** Handle of video memory.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckKERNEL_ReleaseVideoMemory(
+ IN gckKERNEL Kernel,
+ IN gctUINT32 ProcessID,
+ IN gctUINT32 Handle
+ )
+{
+ gceSTATUS status;
+ gckVIDMEM_NODE nodeObject;
+ gceDATABASE_TYPE type;
+
+ gcmkHEADER_ARG("Kernel=0x%08X ProcessID=%d Handle=%d",
+ Kernel, ProcessID, Handle);
+
+ gcmkONERROR(
+ gckVIDMEM_HANDLE_Lookup(Kernel, ProcessID, Handle, &nodeObject));
+
+ type = gcvDB_VIDEO_MEMORY
+ | (nodeObject->type << gcdDB_VIDEO_MEMORY_TYPE_SHIFT)
+ | (nodeObject->pool << gcdDB_VIDEO_MEMORY_POOL_SHIFT);
+
+ gcmkONERROR(
+ gckKERNEL_RemoveProcessDB(Kernel,
+ ProcessID,
+ type,
+ gcmINT2PTR(Handle)));
+
+ gckVIDMEM_HANDLE_Dereference(Kernel, ProcessID, Handle);
+
+ gckVIDMEM_NODE_Dereference(Kernel, nodeObject);
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ gcmkFOOTER();
+ return status;
+}
+
+/*******************************************************************************
+**
+** gckKERNEL_LockVideoMemory
+**
+** Lock a video memory node. It will generate a cpu virtual address used
+** by software and a GPU address used by GPU.
+**
+** INPUT:
+**
+** gckKERNEL Kernel
+** Pointer to an gckKERNEL object.
+**
+** gceCORE Core
+** GPU to which video memory is locked.
+**
+** gcsHAL_INTERFACE * Interface
+** Pointer to a gcsHAL_INTERFACE structure that defines the command to
+** be dispatched.
+**
+** OUTPUT:
+**
+** gcsHAL_INTERFACE * Interface
+** Pointer to a gcsHAL_INTERFACE structure that receives any data to be
+** returned.
+*/
+gceSTATUS
+gckKERNEL_LockVideoMemory(
+ IN gckKERNEL Kernel,
+ IN gceCORE Core,
+ IN gctUINT32 ProcessID,
+ IN gctBOOL FromUser,
+ IN OUT gcsHAL_INTERFACE * Interface
+ )
+{
+ gceSTATUS status;
+ gckVIDMEM_NODE nodeObject = gcvNULL;
+ gcuVIDMEM_NODE_PTR node = gcvNULL;
+ gctBOOL locked = gcvFALSE;
+ gctBOOL asynchronous = gcvFALSE;
+#ifndef __QNXNTO__
+ gctPOINTER pointer = gcvNULL;
+#endif
+
+ gcmkHEADER_ARG("Kernel=0x%08X ProcessID=%d",
+ Kernel, ProcessID);
+
+ gcmkONERROR(
+ gckVIDMEM_HANDLE_LookupAndReference(Kernel,
+ Interface->u.LockVideoMemory.node,
+ &nodeObject));
+
+ node = nodeObject->node;
+
+ Interface->u.LockVideoMemory.gid = 0;
+
+ /* Lock video memory. */
+ gcmkONERROR(
+ gckVIDMEM_Lock(Kernel,
+ nodeObject,
+ Interface->u.LockVideoMemory.cacheable,
+ &Interface->u.LockVideoMemory.address,
+ &Interface->u.LockVideoMemory.gid,
+ &Interface->u.LockVideoMemory.physicalAddress));
+
+ locked = gcvTRUE;
+
+ if (node->VidMem.memory->object.type == gcvOBJ_VIDMEM)
+ {
+ /* Map video memory address into user space. */
+#ifdef __QNXNTO__
+ if (node->VidMem.logical == gcvNULL)
+ {
+ gcmkONERROR(
+ gckKERNEL_MapVideoMemory(Kernel,
+ FromUser,
+ Interface->u.LockVideoMemory.address,
+ ProcessID,
+ node->VidMem.bytes,
+ &node->VidMem.logical));
+ }
+ gcmkASSERT(node->VidMem.logical != gcvNULL);
+
+ Interface->u.LockVideoMemory.memory = gcmPTR_TO_UINT64(node->VidMem.logical);
+#else
+ gcmkONERROR(
+ gckKERNEL_MapVideoMemoryEx(Kernel,
+ Core,
+ FromUser,
+ Interface->u.LockVideoMemory.address,
+ node->VidMem.pool,
+ &pointer));
+
+ Interface->u.LockVideoMemory.memory = gcmPTR_TO_UINT64(pointer);
+#endif
+ }
+ else
+ {
+ Interface->u.LockVideoMemory.memory = gcmPTR_TO_UINT64(node->Virtual.logical);
+
+ /* Success. */
+ status = gcvSTATUS_OK;
+ }
+
+#if gcdPROCESS_ADDRESS_SPACE
+ gcmkONERROR(gckVIDMEM_Node_Lock(
+ Kernel,
+ nodeObject,
+ &Interface->u.LockVideoMemory.address
+ ));
+#endif
+
+
+#if gcdSECURE_USER
+ /* Return logical address as physical address. */
+ Interface->u.LockVideoMemory.address =
+ (gctUINT32)(Interface->u.LockVideoMemory.memory);
+#endif
+ gcmkONERROR(
+ gckKERNEL_AddProcessDB(Kernel,
+ ProcessID, gcvDB_VIDEO_MEMORY_LOCKED,
+ gcmINT2PTR(Interface->u.LockVideoMemory.node),
+ gcvNULL,
+ 0));
+
+ gckVIDMEM_HANDLE_Reference(
+ Kernel, ProcessID, (gctUINT32)Interface->u.LockVideoMemory.node);
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ if (locked)
+ {
+ /* Roll back the lock. */
+ gcmkVERIFY_OK(gckVIDMEM_Unlock(Kernel,
+ nodeObject,
+ gcvSURF_TYPE_UNKNOWN,
+ &asynchronous));
+
+ if (gcvTRUE == asynchronous)
+ {
+ /* Bottom Half */
+ gcmkVERIFY_OK(gckVIDMEM_Unlock(Kernel,
+ nodeObject,
+ gcvSURF_TYPE_UNKNOWN,
+ gcvNULL));
+ }
+ }
+
+ if (nodeObject != gcvNULL)
+ {
+ gckVIDMEM_NODE_Dereference(Kernel, nodeObject);
+ }
+
+ gcmkFOOTER();
+ return status;
+}
+
+/*******************************************************************************
+**
+** gckKERNEL_UnlockVideoMemory
+**
+** Unlock a video memory node.
+**
+** INPUT:
+**
+** gckKERNEL Kernel
+** Pointer to an gckKERNEL object.
+**
+** gctUINT32 ProcessID
+** ProcessID of current process.
+**
+** gcsHAL_INTERFACE * Interface
+** Pointer to a gcsHAL_INTERFACE structure that defines the command to
+** be dispatched.
+**
+** OUTPUT:
+**
+** gcsHAL_INTERFACE * Interface
+** Pointer to a gcsHAL_INTERFACE structure that receives any data to be
+** returned.
+*/
+gceSTATUS
+gckKERNEL_UnlockVideoMemory(
+ IN gckKERNEL Kernel,
+ IN gctUINT32 ProcessID,
+ IN OUT gcsHAL_INTERFACE * Interface
+ )
+{
+ gceSTATUS status;
+ gckVIDMEM_NODE nodeObject;
+ gcuVIDMEM_NODE_PTR node;
+ gctSIZE_T bytes;
+
+ gcmkHEADER_ARG("Kernel=0x%08X ProcessID=%d",
+ Kernel, ProcessID);
+
+ Interface->u.UnlockVideoMemory.pool = gcvPOOL_UNKNOWN;
+ Interface->u.UnlockVideoMemory.bytes = 0;
+
+ gcmkONERROR(gckVIDMEM_HANDLE_Lookup(
+ Kernel,
+ ProcessID,
+ (gctUINT32)Interface->u.UnlockVideoMemory.node,
+ &nodeObject));
+
+ node = nodeObject->node;
+ bytes = (node->VidMem.memory->object.type == gcvOBJ_VIDMEM)
+ ? node->VidMem.bytes
+ : node->Virtual.bytes;
+
+ /* Unlock video memory. */
+ gcmkONERROR(gckVIDMEM_Unlock(
+ Kernel,
+ nodeObject,
+ Interface->u.UnlockVideoMemory.type,
+ &Interface->u.UnlockVideoMemory.asynchroneous));
+
+#if gcdSECURE_USER
+ /* Flush the translation cache for virtual surfaces. */
+ if (node->VidMem.memory->object.type != gcvOBJ_VIDMEM)
+ {
+ gcmkVERIFY_OK(gckKERNEL_FlushTranslationCache(Kernel,
+ cache,
+ node->Virtual.logical,
+ bytes));
+ }
+#endif
+
+ Interface->u.UnlockVideoMemory.pool = nodeObject->pool;
+ Interface->u.UnlockVideoMemory.bytes = (gctUINT)bytes;
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ gcmkFOOTER();
+ return status;
+}
+
+/*******************************************************************************
+**
+** gckKERNEL_BottomHalfUnlockVideoMemory
+**
+** Unlock video memory from gpu.
+**
+** INPUT:
+**
+** gckKERNEL Kernel
+** Pointer to an gckKERNEL object.
+**
+** gctUINT32 ProcessID
+** Process ID owning this memory.
+**
+** gctPOINTER Pointer
+** Video memory to be unlock.
+*/
+gceSTATUS
+gckKERNEL_BottomHalfUnlockVideoMemory(
+ IN gckKERNEL Kernel,
+ IN gctUINT32 ProcessID,
+ IN gctUINT32 Node
+ )
+{
+ gceSTATUS status;
+ gckVIDMEM_NODE nodeObject = gcvNULL;
+
+ /* Remove record from process db. */
+ gcmkVERIFY_OK(gckKERNEL_RemoveProcessDB(
+ Kernel,
+ ProcessID,
+ gcvDB_VIDEO_MEMORY_LOCKED,
+ gcmINT2PTR(Node)));
+
+ gcmkONERROR(gckVIDMEM_HANDLE_Lookup(
+ Kernel,
+ ProcessID,
+ Node,
+ &nodeObject));
+
+ gckVIDMEM_HANDLE_Dereference(Kernel, ProcessID, Node);
+
+ /* Unlock video memory. */
+ gcmkONERROR(gckVIDMEM_Unlock(
+ Kernel,
+ nodeObject,
+ gcvSURF_TYPE_UNKNOWN,
+ gcvNULL));
+
+ gcmkONERROR(gckVIDMEM_NODE_Dereference(
+ Kernel,
+ nodeObject));
+
+ return gcvSTATUS_OK;
+
+OnError:
+ return status;
+}
+
+/*******************************************************************************
+**
+** gckKERNEL_SetVidMemMetadata
+**
+** Set/Get metadata to/from gckVIDMEM_NODE object.
+**
+** INPUT:
+**
+** gckKERNEL Kernel
+** Pointer to an gckKERNEL object.
+**
+** gctUINT32 ProcessID
+** ProcessID of current process.
+**
+** INOUT:
+**
+** gcsHAL_INTERFACE * Interface
+** Pointer to a interface structure
+*/
+#if defined(CONFIG_DMA_SHARED_BUFFER)
+#include <linux/dma-buf.h>
+
+gceSTATUS
+gckKERNEL_SetVidMemMetadata(
+ IN gckKERNEL Kernel,
+ IN gctUINT32 ProcessID,
+ INOUT gcsHAL_INTERFACE * Interface
+ )
+{
+ gceSTATUS status = gcvSTATUS_NOT_SUPPORTED;
+ gckVIDMEM_NODE nodeObj = gcvNULL;
+
+ gcmkHEADER_ARG("Kernel=0x%X ProcessID=%d", Kernel, ProcessID);
+
+ gcmkONERROR(gckVIDMEM_HANDLE_Lookup(Kernel, ProcessID, Interface->u.SetVidMemMetadata.node, &nodeObj));
+
+ if (Interface->u.SetVidMemMetadata.readback)
+ {
+ Interface->u.SetVidMemMetadata.ts_fd = nodeObj->metadata.ts_fd;
+ Interface->u.SetVidMemMetadata.fc_enabled = nodeObj->metadata.fc_enabled;
+ Interface->u.SetVidMemMetadata.fc_value = nodeObj->metadata.fc_value;
+ Interface->u.SetVidMemMetadata.fc_value_upper = nodeObj->metadata.fc_value_upper;
+ Interface->u.SetVidMemMetadata.compressed = nodeObj->metadata.compressed;
+ Interface->u.SetVidMemMetadata.compress_format = nodeObj->metadata.compress_format;
+ }
+ else
+ {
+#ifdef gcdANDROID
+ if (nodeObj->metadata.ts_address == 0 && nodeObj->tsNode != NULL)
+ {
+ gctUINT32 Address = 0;
+ gctUINT32 Gid = 0;
+ gctUINT64 PhysicalAddress = 0;
+
+ gcmkONERROR(gckVIDMEM_Lock(Kernel,
+ nodeObj->tsNode,
+ gcvFALSE,
+ &Address,
+ &Gid,
+ &PhysicalAddress));
+
+ nodeObj->metadata.ts_address = (
+ PhysicalAddress + Kernel->hardware->baseAddress);
+ gcmkONERROR(gckVIDMEM_Unlock(Kernel,
+ nodeObj->tsNode,
+ gcvSURF_TYPE_UNKNOWN,
+ gcvNULL));
+ }
+#else
+ nodeObj->metadata.ts_fd = Interface->u.SetVidMemMetadata.ts_fd;
+
+ if (nodeObj->metadata.ts_fd >= 0)
+ {
+ nodeObj->metadata.ts_dma_buf = dma_buf_get(nodeObj->metadata.ts_fd);
+
+ if (IS_ERR(nodeObj->metadata.ts_dma_buf))
+ {
+ gcmkONERROR(gcvSTATUS_NOT_FOUND);
+ }
+
+ dma_buf_put(nodeObj->metadata.ts_dma_buf);
+ }
+ else
+ {
+ nodeObj->metadata.ts_dma_buf = NULL;
+ }
+#endif
+
+ nodeObj->metadata.fc_enabled = Interface->u.SetVidMemMetadata.fc_enabled;
+ nodeObj->metadata.fc_value = Interface->u.SetVidMemMetadata.fc_value;
+ nodeObj->metadata.fc_value_upper = Interface->u.SetVidMemMetadata.fc_value_upper;
+ nodeObj->metadata.compressed = Interface->u.SetVidMemMetadata.compressed;
+ nodeObj->metadata.compress_format = Interface->u.SetVidMemMetadata.compress_format;
+ }
+
+OnError:
+ gcmkFOOTER();
+ return status;
+}
+
+#else
+
+gceSTATUS
+gckKERNEL_SetVidMemMetadata(
+ IN gckKERNEL Kernel,
+ IN gctUINT32 ProcessID,
+ INOUT gcsHAL_INTERFACE * Interface
+ )
+{
+ gcmkFATAL("The kernel did NOT support CONFIG_DMA_SHARED_BUFFER");
+ return gcvSTATUS_NOT_SUPPORTED;
+}
+#endif
+
+/*******************************************************************************
+**
+** gckKERNEL_QueryVidMemPoolNodes
+**
+** Loop all databases to query used memory nodes of a specific pool.
+**
+** INPUT:
+**
+** Pool The memory pool for query.
+
+** TotalSize Total size of the used contiguous memory.
+**
+** MemoryBlocks Used contiguous memory block info.
+**
+** NumMaxBlock The count of memory blocks array provided by the caller.
+**
+** NumBlocks The actual number of memory blocks returned.
+**
+** OUTPUT:
+**
+** Error status. Should always be gcvSTATUS_SUCCESS since a query should always succeed.
+*/
+gceSTATUS
+gckKERNEL_QueryVidMemPoolNodes(
+ gckKERNEL Kernel,
+ gcePOOL Pool,
+ gctUINT32 * TotalSize,
+ gcsContiguousBlock * MemoryBlocks,
+ gctUINT32 NumMaxBlocks,
+ gctUINT32 * NumBlocks
+ )
+{
+ gceSTATUS status = gcvSTATUS_OK;
+ gctINT i;
+ gctINT bcount;
+ gctUINT32 num_blocks = 0;
+ gctSIZE_T total_size = 0;
+ gckVIDMEM memory;
+ gcuVIDMEM_NODE_PTR nodes, node;
+
+ do
+ {
+ /* Get the heap and nodes. */
+ status = gckKERNEL_GetVideoMemoryPool(Kernel, Pool, &memory);
+ if (status != gcvSTATUS_OK)
+ break;
+
+ status = gckVIDMEM_QueryNodes(Kernel, Pool, &bcount, &nodes);
+ if (status != gcvSTATUS_OK)
+ break;
+
+ /* Iterate all nodes. */
+ for (i = 0; i < bcount; i++)
+ {
+ node = nodes[i].VidMem.next;
+ do
+ {
+ if (node == gcvNULL)
+ {
+ break;
+ }
+
+ /* Is it in the "free" list? */
+ if (node->VidMem.nextFree == gcvNULL)
+ {
+ if (num_blocks < NumMaxBlocks)
+ {
+ MemoryBlocks[num_blocks].ptr = (gctUINT32)node->VidMem.offset + memory->baseAddress;
+ MemoryBlocks[num_blocks].size = node->VidMem.bytes;
+ }
+ total_size += node->VidMem.bytes;
+ num_blocks++;
+ }
+
+ node = node->VidMem.next;
+ } while (node != &nodes[i]);
+ }
+ }
+ while (gcvFALSE);
+
+ if (TotalSize != gcvNULL)
+ *TotalSize = (gctUINT32)total_size;
+
+ if (NumBlocks != gcvNULL)
+ *NumBlocks = num_blocks;
+
+ return status;
+}
+
+gceSTATUS
+gckKERNEL_QueryDatabase(
+ IN gckKERNEL Kernel,
+ IN gctUINT32 ProcessID,
+ IN OUT gcsHAL_INTERFACE * Interface
+ )
+{
+ gceSTATUS status;
+ gctINT i;
+
+ gceDATABASE_TYPE type[3] = {
+ gcvDB_VIDEO_MEMORY | (gcvPOOL_SYSTEM << gcdDB_VIDEO_MEMORY_POOL_SHIFT),
+ gcvDB_VIDEO_MEMORY | (gcvPOOL_CONTIGUOUS << gcdDB_VIDEO_MEMORY_POOL_SHIFT),
+ gcvDB_VIDEO_MEMORY | (gcvPOOL_VIRTUAL << gcdDB_VIDEO_MEMORY_POOL_SHIFT),
+ };
+
+ gcmkHEADER();
+
+ /* Query video memory. */
+ gcmkONERROR(
+ gckKERNEL_QueryProcessDB(Kernel,
+ Interface->u.Database.processID,
+ !Interface->u.Database.validProcessID,
+ gcvDB_VIDEO_MEMORY,
+ &Interface->u.Database.vidMem));
+
+ /* Query non-paged memory. */
+ gcmkONERROR(
+ gckKERNEL_QueryProcessDB(Kernel,
+ Interface->u.Database.processID,
+ !Interface->u.Database.validProcessID,
+ gcvDB_NON_PAGED,
+ &Interface->u.Database.nonPaged));
+
+ /* Query contiguous memory. */
+ gcmkONERROR(
+ gckKERNEL_QueryProcessDB(Kernel,
+ Interface->u.Database.processID,
+ !Interface->u.Database.validProcessID,
+ gcvDB_CONTIGUOUS,
+ &Interface->u.Database.contiguous));
+
+ /* Query GPU idle time. */
+ gcmkONERROR(
+ gckKERNEL_QueryProcessDB(Kernel,
+ Interface->u.Database.processID,
+ !Interface->u.Database.validProcessID,
+ gcvDB_IDLE,
+ &Interface->u.Database.gpuIdle));
+ for (i = 0; i < 3; i++)
+ {
+ /* Query each video memory pool. */
+ gcmkONERROR(
+ gckKERNEL_QueryProcessDB(Kernel,
+ Interface->u.Database.processID,
+ !Interface->u.Database.validProcessID,
+ type[i],
+ &Interface->u.Database.vidMemPool[i]));
+ }
+
+#if gcmIS_DEBUG(gcdDEBUG_TRACE)
+ gckKERNEL_DumpVidMemUsage(Kernel, Interface->u.Database.processID);
+#endif
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ gcmkFOOTER();
+ return status;
+}
+
+gceSTATUS
+gckKERNEL_ConfigPowerManagement(
+ IN gckKERNEL Kernel,
+ IN OUT gcsHAL_INTERFACE * Interface
+)
+{
+ gceSTATUS status;
+ gctBOOL enable = Interface->u.ConfigPowerManagement.enable;
+
+ gcmkHEADER();
+
+ gcmkONERROR(gckHARDWARE_SetPowerManagement(Kernel->hardware, enable));
+
+ if (enable == gcvFALSE)
+ {
+ gcmkONERROR(
+ gckHARDWARE_SetPowerManagementState(Kernel->hardware, gcvPOWER_ON));
+ }
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ gcmkFOOTER();
+ return status;
+}
+
+static gceSTATUS
+gckKERNEL_CacheOperation(
+ IN gckKERNEL Kernel,
+ IN gctUINT32 ProcessID,
+ IN gctUINT32 Node,
+ IN gceCACHEOPERATION Operation,
+ IN gctPOINTER Logical,
+ IN gctSIZE_T Bytes
+ )
+{
+ gceSTATUS status;
+ gckVIDMEM_NODE nodeObject = gcvNULL;
+ gcuVIDMEM_NODE_PTR node = gcvNULL;
+ void *memHandle;
+
+ gcmkHEADER_ARG("Kernel=%p pid=%u Node=%u op=%d Logical=%p Bytes=0x%lx",
+ Kernel, ProcessID, Node, Operation, Logical, Bytes);
+
+ gcmkONERROR(gckVIDMEM_HANDLE_Lookup(Kernel,
+ ProcessID,
+ Node,
+ &nodeObject));
+
+ node = nodeObject->node;
+
+ if (node->VidMem.memory->object.type == gcvOBJ_VIDMEM)
+ {
+ static gctBOOL printed;
+
+ if (!printed)
+ {
+ printed = gcvTRUE;
+ gcmkPRINT("[galcore]: %s: Flush Video Memory", __FUNCTION__);
+ }
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+ }
+ else
+ {
+ memHandle = node->Virtual.physical;
+ }
+
+ switch (Operation)
+ {
+ case gcvCACHE_FLUSH:
+ /* Clean and invalidate the cache. */
+ status = gckOS_CacheFlush(Kernel->os,
+ ProcessID,
+ memHandle,
+ gcvINVALID_PHYSICAL_ADDRESS,
+ Logical,
+ Bytes);
+ break;
+ case gcvCACHE_CLEAN:
+ /* Clean the cache. */
+ status = gckOS_CacheClean(Kernel->os,
+ ProcessID,
+ memHandle,
+ gcvINVALID_PHYSICAL_ADDRESS,
+ Logical,
+ Bytes);
+ break;
+ case gcvCACHE_INVALIDATE:
+ /* Invalidate the cache. */
+ status = gckOS_CacheInvalidate(Kernel->os,
+ ProcessID,
+ memHandle,
+ gcvINVALID_PHYSICAL_ADDRESS,
+ Logical,
+ Bytes);
+ break;
+
+ case gcvCACHE_MEMORY_BARRIER:
+ status = gckOS_MemoryBarrier(Kernel->os, Logical);
+ break;
+
+ default:
+ gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
+ break;
+ }
+
+OnError:
+ gcmkFOOTER();
+ return status;
+}
+
+gceSTATUS
+gckKERNEL_WaitFence(
+ IN gckKERNEL Kernel,
+ IN gctUINT32 Handle,
+ IN gctUINT32 TimeOut
+ )
+{
+ gceSTATUS status;
+ gckVIDMEM_NODE node;
+ gctUINT32 processID;
+ gckCOMMAND command = Kernel->command;
+ gckASYNC_COMMAND asyncCommand = Kernel->asyncCommand;
+ gckFENCE fence = gcvNULL;
+ gctUINT i;
+
+ gckOS_GetProcessID(&processID);
+
+ gcmkONERROR(gckVIDMEM_HANDLE_LookupAndReference(Kernel, Handle, &node));
+
+ /* Wait for fence of all engines. */
+ for (i = 0; i < gcvENGINE_GPU_ENGINE_COUNT; i++)
+ {
+ gckFENCE_SYNC sync = &node->sync[i];
+
+ if (i == gcvENGINE_RENDER)
+ {
+ fence = command->fence;
+ }
+ else
+ {
+ fence = asyncCommand->fence;
+ }
+
+#if USE_KERNEL_VIRTUAL_BUFFERS
+ if (Kernel->virtualCommandBuffer)
+ {
+ gckVIRTUAL_COMMAND_BUFFER_PTR commandBuffer = (gckVIRTUAL_COMMAND_BUFFER_PTR) fence->physical;
+
+ fence->physHandle = commandBuffer->virtualBuffer.physical;
+ }
+ else
+#endif
+ {
+ fence->physHandle = fence->physical;
+ }
+
+ gcmkONERROR(gckOS_CacheInvalidate(
+ Kernel->os,
+ 0,
+ fence->physHandle,
+ 0,
+ fence->logical,
+ 8
+ ));
+
+ if (sync->commitStamp <= *(gctUINT64_PTR)fence->logical)
+ {
+ continue;
+ }
+ else
+ {
+ gckOS_Signal(Kernel->os, sync->signal, gcvFALSE);
+
+ gcmkVERIFY_OK(gckOS_AcquireMutex(Kernel->os, &fence->mutex, gcvINFINITE));
+
+ /* Add to waiting list. */
+ gcsLIST_AddTail(&sync->head, &fence->waitingList);
+
+ gcmkASSERT(sync->inList == gcvFALSE);
+
+ sync->inList = gcvTRUE;
+
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, &fence->mutex));
+
+ /* Wait. */
+ status = gckOS_WaitSignal(Kernel->os, sync->signal, gcvTRUE, TimeOut);
+
+ gcmkVERIFY_OK(gckOS_AcquireMutex(Kernel->os, &fence->mutex, gcvINFINITE));
+
+ if (sync->inList)
+ {
+ gcsLIST_Del(&sync->head);
+ sync->inList = gcvFALSE;
+ }
+
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, &fence->mutex));
+ }
+ }
+
+ gckVIDMEM_NODE_Dereference(Kernel, node);
+
+OnError:
+ return status;
+}
+
+#ifdef __linux__
+
+typedef struct _gcsGRRAPHIC_BUFFER_PARCLE
+{
+ gcsFDPRIVATE base;
+ gckKERNEL kernel;
+
+ gckVIDMEM_NODE node[3];
+ gctSHBUF shBuf;
+ gctINT32 signal;
+}
+gcsGRAPHIC_BUFFER_PARCLE;
+
+static void
+_ReleaseGraphicBuffer(
+ gckKERNEL Kernel,
+ gcsGRAPHIC_BUFFER_PARCLE * Parcle
+ )
+{
+ gctUINT i;
+
+ for (i = 0; i < 3; i++)
+ {
+ if (Parcle->node[i])
+ {
+ gckVIDMEM_NODE_Dereference(Kernel, Parcle->node[i]);
+ }
+ }
+
+ if (Parcle->shBuf)
+ {
+ gckKERNEL_DestroyShBuffer(Kernel, Parcle->shBuf);
+ }
+
+ if (Parcle->signal)
+ {
+ gckOS_DestroyUserSignal(Kernel->os, Parcle->signal);
+ }
+
+ gcmkOS_SAFE_FREE(Kernel->os, Parcle);
+}
+
+static gctINT
+_FdReleaseGraphicBuffer(
+ gcsFDPRIVATE_PTR Private
+ )
+{
+ gcsGRAPHIC_BUFFER_PARCLE * parcle = (gcsGRAPHIC_BUFFER_PARCLE *) Private;
+
+ _ReleaseGraphicBuffer(parcle->kernel, parcle);
+ return 0;
+}
+
+static gceSTATUS
+_GetGraphicBufferFd(
+ IN gckKERNEL Kernel,
+ IN gctUINT32 ProcessID,
+ IN gctUINT32 Node[3],
+ IN gctUINT64 ShBuf,
+ IN gctUINT64 Signal,
+ OUT gctINT32 * Fd
+ )
+{
+ gceSTATUS status;
+ gctUINT i;
+ gcsGRAPHIC_BUFFER_PARCLE * parcle = gcvNULL;
+
+ gcmkONERROR(gckOS_Allocate(
+ Kernel->os,
+ gcmSIZEOF(gcsGRAPHIC_BUFFER_PARCLE),
+ (gctPOINTER *)&parcle
+ ));
+
+ gckOS_ZeroMemory(parcle, sizeof(gcsGRAPHIC_BUFFER_PARCLE));
+
+ parcle->base.release = _FdReleaseGraphicBuffer;
+ parcle->kernel = Kernel;
+
+ for (i = 0; i < 3; i++)
+ {
+ if (Node[i] != 0)
+ {
+ gcmkONERROR(
+ gckVIDMEM_HANDLE_LookupAndReference(Kernel, Node[i], &parcle->node[i]));
+ }
+ }
+
+ if (ShBuf)
+ {
+ gctSHBUF shBuf = gcmUINT64_TO_PTR(ShBuf);
+
+ gcmkONERROR(gckKERNEL_MapShBuffer(Kernel, shBuf));
+ parcle->shBuf = shBuf;
+ }
+
+ if (Signal)
+ {
+ gctSIGNAL signal = gcmUINT64_TO_PTR(Signal);
+
+ gcmkONERROR(
+ gckOS_MapSignal(Kernel->os,
+ signal,
+ (gctHANDLE)(gctUINTPTR_T)ProcessID,
+ &signal));
+
+ parcle->signal= (gctINT32)Signal;
+ }
+
+ gcmkONERROR(gckOS_GetFd("viv-gr", &parcle->base, Fd));
+
+ return gcvSTATUS_OK;
+
+OnError:
+ if (parcle)
+ {
+ _ReleaseGraphicBuffer(Kernel, parcle);
+ }
+ return status;
+}
+#endif
+
+/*******************************************************************************
+**
+** gckKERNEL_Dispatch
+**
+** Dispatch a command received from the user HAL layer.
+**
+** INPUT:
+**
+** gckKERNEL Kernel
+** Pointer to an gckKERNEL object.
+**
+** gctBOOL FromUser
+** whether the call is from the user space.
+**
+** gcsHAL_INTERFACE * Interface
+** Pointer to a gcsHAL_INTERFACE structure that defines the command to
+** be dispatched.
+**
+** OUTPUT:
+**
+** gcsHAL_INTERFACE * Interface
+** Pointer to a gcsHAL_INTERFACE structure that receives any data to be
+** returned.
+*/
+gceSTATUS
+gckKERNEL_Dispatch(
+ IN gckKERNEL Kernel,
+ IN gckDEVICE Device,
+ IN gctBOOL FromUser,
+ IN OUT gcsHAL_INTERFACE * Interface
+ )
+{
+ gceSTATUS status = gcvSTATUS_OK;
+ gctPHYS_ADDR physical = gcvNULL;
+ gctSIZE_T bytes;
+ gctPOINTER logical = gcvNULL;
+#if (gcdENABLE_3D || gcdENABLE_2D)
+ gckCONTEXT context = gcvNULL;
+#endif
+ gckKERNEL kernel = Kernel;
+ gctUINT32 processID;
+#if gcdSECURE_USER
+ gcskSECURE_CACHE_PTR cache;
+ gctPOINTER logical;
+#endif
+#if !USE_NEW_LINUX_SIGNAL
+ gctSIGNAL signal;
+#endif
+ gckVIRTUAL_COMMAND_BUFFER_PTR buffer;
+
+ gctBOOL powerMutexAcquired = gcvFALSE;
+ gctBOOL commitMutexAcquired = gcvFALSE;
+
+ gcmkHEADER_ARG("Kernel=0x%x FromUser=%d Interface=0x%x",
+ Kernel, FromUser, Interface);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
+ gcmkVERIFY_ARGUMENT(Interface != gcvNULL);
+
+#if gcmIS_DEBUG(gcdDEBUG_TRACE)
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_KERNEL,
+ "Dispatching command %d (%s)",
+ Interface->command, _DispatchText[Interface->command]);
+#endif
+#if QNX_SINGLE_THREADED_DEBUGGING
+ gckOS_AcquireMutex(Kernel->os, Kernel->debugMutex, gcvINFINITE);
+#endif
+
+ /* Get the current process ID. */
+ gcmkONERROR(gckOS_GetProcessID(&processID));
+
+#if gcdSECURE_USER
+ gcmkONERROR(gckKERNEL_GetProcessDBCache(Kernel, processID, &cache));
+#endif
+
+ /* Dispatch on command. */
+ switch (Interface->command)
+ {
+ case gcvHAL_GET_BASE_ADDRESS:
+ /* Get base address. */
+ Interface->u.GetBaseAddress.baseAddress = Kernel->hardware->baseAddress;
+ Interface->u.GetBaseAddress.flatMappingRangeCount = Kernel->mmu->flatMappingRangeCount;
+ if (Kernel->mmu->flatMappingRangeCount)
+ {
+ gckOS_MemCopy(Interface->u.GetBaseAddress.flatMappingRanges, Kernel->mmu->flatMappingRanges,
+ gcmSIZEOF(gcsFLAT_MAPPING_RANGE) * Kernel->mmu->flatMappingRangeCount);
+ }
+ break;
+
+ case gcvHAL_QUERY_VIDEO_MEMORY:
+ /* Query video memory size. */
+ gcmkONERROR(gckKERNEL_QueryVideoMemory(Kernel, Interface));
+ break;
+
+ case gcvHAL_QUERY_CHIP_IDENTITY:
+ /* Query chip identity. */
+ gcmkONERROR(
+ gckHARDWARE_QueryChipIdentity(
+ Kernel->hardware,
+ &Interface->u.QueryChipIdentity));
+ break;
+
+ case gcvHAL_QUERY_CHIP_FREQUENCY:
+ /* Query chip clock. */
+ gcmkONERROR(
+ gckHARDWARE_QueryFrequency(Kernel->hardware));
+
+ Interface->u.QueryChipFrequency.mcClk = Kernel->hardware->mcClk;
+ Interface->u.QueryChipFrequency.shClk = Kernel->hardware->shClk;
+ break;
+
+ case gcvHAL_MAP_MEMORY:
+ physical = gcmINT2PTR(Interface->u.MapMemory.physical);
+
+ /* Map memory. */
+ gcmkONERROR(
+ gckKERNEL_MapMemory(Kernel,
+ physical,
+ (gctSIZE_T) Interface->u.MapMemory.bytes,
+ &logical));
+
+ Interface->u.MapMemory.logical = gcmPTR_TO_UINT64(logical);
+
+ gcmkVERIFY_OK(
+ gckKERNEL_AddProcessDB(Kernel,
+ processID, gcvDB_MAP_MEMORY,
+ logical,
+ physical,
+ (gctSIZE_T) Interface->u.MapMemory.bytes));
+ break;
+
+ case gcvHAL_UNMAP_MEMORY:
+ physical = gcmINT2PTR(Interface->u.UnmapMemory.physical);
+
+ gcmkVERIFY_OK(
+ gckKERNEL_RemoveProcessDB(Kernel,
+ processID, gcvDB_MAP_MEMORY,
+ gcmUINT64_TO_PTR(Interface->u.UnmapMemory.logical)));
+
+ /* Unmap memory. */
+ gcmkONERROR(
+ gckKERNEL_UnmapMemory(Kernel,
+ physical,
+ (gctSIZE_T) Interface->u.UnmapMemory.bytes,
+ gcmUINT64_TO_PTR(Interface->u.UnmapMemory.logical),
+ processID));
+ break;
+
+ case gcvHAL_ALLOCATE_NON_PAGED_MEMORY:
+ bytes = (gctSIZE_T) Interface->u.AllocateNonPagedMemory.bytes;
+
+ /* Allocate non-paged memory. */
+ gcmkONERROR(
+ gckOS_AllocateNonPagedMemory(
+ Kernel->os,
+ FromUser,
+ gcvALLOC_FLAG_CONTIGUOUS,
+ &bytes,
+ &physical,
+ &logical));
+
+ Interface->u.AllocateNonPagedMemory.bytes = bytes;
+ Interface->u.AllocateNonPagedMemory.logical = gcmPTR_TO_UINT64(logical);
+ Interface->u.AllocateNonPagedMemory.physical = gcmPTR_TO_NAME(physical);
+
+ gcmkVERIFY_OK(
+ gckKERNEL_AddProcessDB(Kernel,
+ processID, gcvDB_NON_PAGED,
+ logical,
+ gcmINT2PTR(Interface->u.AllocateNonPagedMemory.physical),
+ bytes));
+ break;
+
+ case gcvHAL_ALLOCATE_VIRTUAL_COMMAND_BUFFER:
+ bytes = (gctSIZE_T) Interface->u.AllocateVirtualCommandBuffer.bytes;
+
+ gcmkONERROR(
+ gckKERNEL_AllocateVirtualCommandBuffer(
+ Kernel,
+ FromUser,
+ &bytes,
+ &physical,
+ &logical));
+
+ Interface->u.AllocateVirtualCommandBuffer.bytes = bytes;
+ Interface->u.AllocateVirtualCommandBuffer.logical = gcmPTR_TO_UINT64(logical);
+ Interface->u.AllocateVirtualCommandBuffer.physical = gcmPTR_TO_NAME(physical);
+
+ gcmkVERIFY_OK(
+ gckKERNEL_AddProcessDB(Kernel,
+ processID, gcvDB_COMMAND_BUFFER,
+ logical,
+ gcmINT2PTR(Interface->u.AllocateVirtualCommandBuffer.physical),
+ bytes));
+ break;
+
+ case gcvHAL_FREE_NON_PAGED_MEMORY:
+ physical = gcmNAME_TO_PTR(Interface->u.FreeNonPagedMemory.physical);
+
+ gcmkVERIFY_OK(
+ gckKERNEL_RemoveProcessDB(Kernel,
+ processID, gcvDB_NON_PAGED,
+ gcmUINT64_TO_PTR(Interface->u.FreeNonPagedMemory.logical)));
+
+ /* Unmap user logical out of physical memory first. */
+ gcmkONERROR(gckOS_UnmapUserLogical(Kernel->os,
+ physical,
+ (gctSIZE_T) Interface->u.FreeNonPagedMemory.bytes,
+ gcmUINT64_TO_PTR(Interface->u.FreeNonPagedMemory.logical)));
+
+ /* Free non-paged memory. */
+ gcmkONERROR(
+ gckOS_FreeNonPagedMemory(Kernel->os,
+ (gctSIZE_T) Interface->u.FreeNonPagedMemory.bytes,
+ physical,
+ gcmUINT64_TO_PTR(Interface->u.FreeNonPagedMemory.logical)));
+
+#if gcdSECURE_USER
+ gcmkVERIFY_OK(gckKERNEL_FlushTranslationCache(
+ Kernel,
+ cache,
+ gcmUINT64_TO_PTR(Interface->u.FreeNonPagedMemory.logical),
+ (gctSIZE_T) Interface->u.FreeNonPagedMemory.bytes));
+#endif
+
+ gcmRELEASE_NAME(Interface->u.FreeNonPagedMemory.physical);
+ break;
+
+ case gcvHAL_ALLOCATE_CONTIGUOUS_MEMORY:
+ bytes = (gctSIZE_T) Interface->u.AllocateContiguousMemory.bytes;
+
+ /* Allocate contiguous memory. */
+ gcmkONERROR(gckOS_AllocateContiguous(
+ Kernel->os,
+ FromUser,
+ &bytes,
+ &physical,
+ &logical));
+
+ Interface->u.AllocateContiguousMemory.bytes = bytes;
+ Interface->u.AllocateContiguousMemory.logical = gcmPTR_TO_UINT64(logical);
+ Interface->u.AllocateContiguousMemory.physical = gcmPTR_TO_NAME(physical);
+
+ gcmkONERROR(gckHARDWARE_ConvertLogical(
+ Kernel->hardware,
+ logical,
+ gcvTRUE,
+ &Interface->u.AllocateContiguousMemory.address));
+
+ gcmkVERIFY_OK(gckKERNEL_AddProcessDB(
+ Kernel,
+ processID, gcvDB_CONTIGUOUS,
+ logical,
+ gcmINT2PTR(Interface->u.AllocateContiguousMemory.physical),
+ bytes));
+ break;
+
+ case gcvHAL_FREE_CONTIGUOUS_MEMORY:
+ physical = gcmNAME_TO_PTR(Interface->u.FreeContiguousMemory.physical);
+
+ gcmkVERIFY_OK(
+ gckKERNEL_RemoveProcessDB(Kernel,
+ processID, gcvDB_CONTIGUOUS,
+ gcmUINT64_TO_PTR(Interface->u.FreeNonPagedMemory.logical)));
+
+ /* Unmap user logical out of physical memory first. */
+ gcmkONERROR(gckOS_UnmapUserLogical(Kernel->os,
+ physical,
+ (gctSIZE_T) Interface->u.FreeContiguousMemory.bytes,
+ gcmUINT64_TO_PTR(Interface->u.FreeContiguousMemory.logical)));
+
+ /* Free contiguous memory. */
+ gcmkONERROR(
+ gckOS_FreeContiguous(Kernel->os,
+ physical,
+ gcmUINT64_TO_PTR(Interface->u.FreeContiguousMemory.logical),
+ (gctSIZE_T) Interface->u.FreeContiguousMemory.bytes));
+
+#if gcdSECURE_USER
+ gcmkVERIFY_OK(gckKERNEL_FlushTranslationCache(
+ Kernel,
+ cache,
+ gcmUINT64_TO_PTR(Interface->u.FreeContiguousMemory.logical),
+ (gctSIZE_T) Interface->u.FreeContiguousMemory.bytes));
+#endif
+
+ gcmRELEASE_NAME(Interface->u.FreeContiguousMemory.physical);
+ break;
+
+ case gcvHAL_ALLOCATE_VIDEO_MEMORY:
+
+ gcmkONERROR(gcvSTATUS_NOT_SUPPORTED);
+
+ break;
+
+ case gcvHAL_ALLOCATE_LINEAR_VIDEO_MEMORY:
+ /* Allocate memory. */
+ gcmkONERROR(
+ gckKERNEL_AllocateLinearMemory(Kernel, processID,
+ &Interface->u.AllocateLinearVideoMemory.pool,
+ Interface->u.AllocateLinearVideoMemory.bytes,
+ Interface->u.AllocateLinearVideoMemory.alignment,
+ Interface->u.AllocateLinearVideoMemory.type,
+ Interface->u.AllocateLinearVideoMemory.flag,
+ &Interface->u.AllocateLinearVideoMemory.node));
+ break;
+
+ case gcvHAL_RELEASE_VIDEO_MEMORY:
+ /* Release video memory. */
+ gcmkONERROR(gckKERNEL_ReleaseVideoMemory(
+ Kernel, processID,
+ (gctUINT32)Interface->u.ReleaseVideoMemory.node
+ ));
+ break;
+
+ case gcvHAL_LOCK_VIDEO_MEMORY:
+ /* Lock video memory. */
+ gcmkONERROR(gckKERNEL_LockVideoMemory(Kernel, Kernel->core, processID, FromUser, Interface));
+ break;
+
+ case gcvHAL_UNLOCK_VIDEO_MEMORY:
+ /* Unlock video memory. */
+ gcmkONERROR(gckKERNEL_UnlockVideoMemory(Kernel, processID, Interface));
+ break;
+
+ case gcvHAL_BOTTOM_HALF_UNLOCK_VIDEO_MEMORY:
+ gcmkERR_BREAK(gckKERNEL_BottomHalfUnlockVideoMemory(Kernel, processID,
+ Interface->u.BottomHalfUnlockVideoMemory.node));
+ break;
+
+ case gcvHAL_EVENT_COMMIT:
+ if (!Interface->commitMutex)
+ {
+ gcmkONERROR(gckOS_AcquireMutex(Kernel->os,
+ Kernel->device->commitMutex,
+ gcvINFINITE
+ ));
+
+ commitMutexAcquired = gcvTRUE;
+ }
+ /* Commit an event queue. */
+ if (Interface->engine == gcvENGINE_BLT)
+ {
+ if (!gckHARDWARE_IsFeatureAvailable(Kernel->hardware, gcvFEATURE_ASYNC_BLIT))
+ {
+ gcmkONERROR(gcvSTATUS_NOT_SUPPORTED);
+ }
+
+ gcmkONERROR(gckEVENT_Commit(
+ Kernel->asyncEvent, gcmUINT64_TO_PTR(Interface->u.Event.queue), gcvFALSE));
+ }
+ else
+ {
+ gcmkONERROR(gckEVENT_Commit(
+ Kernel->eventObj, gcmUINT64_TO_PTR(Interface->u.Event.queue), gcvFALSE));
+ }
+
+ if (!Interface->commitMutex)
+ {
+ gcmkONERROR(gckOS_ReleaseMutex(Kernel->os, Kernel->device->commitMutex));
+ commitMutexAcquired = gcvFALSE;
+ }
+ break;
+
+ case gcvHAL_COMMIT:
+ if (!Interface->commitMutex)
+ {
+ gcmkONERROR(gckOS_AcquireMutex(Kernel->os,
+ Kernel->device->commitMutex,
+ gcvINFINITE
+ ));
+ commitMutexAcquired = gcvTRUE;
+ }
+
+ /* Commit a command and context buffer. */
+ if (Interface->engine == gcvENGINE_BLT)
+ {
+ gctUINT64 *commandBuffers = gcmUINT64_TO_PTR(Interface->u.Commit.commandBuffer);
+
+ if (!gckHARDWARE_IsFeatureAvailable(Kernel->hardware, gcvFEATURE_ASYNC_BLIT))
+ {
+ gcmkONERROR(gcvSTATUS_NOT_SUPPORTED);
+ }
+
+ gcmkONERROR(gckASYNC_COMMAND_Commit(
+ Kernel->asyncCommand,
+ gcmUINT64_TO_PTR(commandBuffers[0]),
+ gcmUINT64_TO_PTR(Interface->u.Commit.queue)
+ ));
+
+ gcmkONERROR(gckEVENT_Commit(
+ Kernel->asyncEvent,
+ gcmUINT64_TO_PTR(Interface->u.Commit.queue),
+ gcvFALSE
+ ));
+ }
+ else
+ {
+ gctUINT32 i;
+
+ if (Interface->u.Commit.count > 1 && Interface->engine == gcvENGINE_RENDER)
+ {
+ for (i = 0; i < Interface->u.Commit.count; i++)
+ {
+ gceHARDWARE_TYPE type = Interface->hardwareType;
+ gckKERNEL kernel = Device->map[type].kernels[i];
+
+ gcmkONERROR(gckOS_Broadcast(kernel->os,
+ kernel->hardware,
+ gcvBROADCAST_GPU_COMMIT));
+ }
+ }
+
+ status = gckCOMMAND_Commit(Kernel->command,
+ Interface->u.Commit.contexts[0] ?
+ gcmNAME_TO_PTR(Interface->u.Commit.contexts[0]) : gcvNULL,
+ gcmUINT64_TO_PTR(Interface->u.Commit.commandBuffers[0]),
+ gcmUINT64_TO_PTR(Interface->u.Commit.deltas[0]),
+ processID,
+ Interface->u.Commit.shared,
+ Interface->u.Commit.index,
+ &Interface->u.Commit.commitStamp,
+ &Interface->u.Commit.contextSwitched
+ );
+
+ if (status != gcvSTATUS_INTERRUPTED)
+ {
+ gcmkONERROR(status);
+ }
+
+ /* Force an event if powerManagement is on. */
+ status = gckEVENT_Commit(Kernel->eventObj,
+ gcmUINT64_TO_PTR(Interface->u.Commit.queue),
+ Kernel->hardware->options.powerManagement);
+
+ if (status != gcvSTATUS_INTERRUPTED)
+ {
+ gcmkONERROR(status);
+ }
+
+ if (Interface->u.Commit.count > 1 && Interface->engine == gcvENGINE_RENDER)
+ {
+ for (i = 1; i < Interface->u.Commit.count; i++)
+ {
+ gceHARDWARE_TYPE type = Interface->hardwareType;
+ gckKERNEL kernel = Device->map[type].kernels[i];
+
+ status = gckCOMMAND_Commit(kernel->command,
+ Interface->u.Commit.contexts[i] ?
+ gcmNAME_TO_PTR(Interface->u.Commit.contexts[i]) : gcvNULL,
+ Interface->u.Commit.commandBuffers[i] ?
+ gcmUINT64_TO_PTR(Interface->u.Commit.commandBuffers[i]) : gcmUINT64_TO_PTR(Interface->u.Commit.commandBuffers[0]),
+ gcmUINT64_TO_PTR(Interface->u.Commit.deltas[i]),
+ processID,
+ Interface->u.Commit.shared,
+ Interface->u.Commit.commandBuffers[i] ?
+ Interface->u.Commit.index : i,
+ &Interface->u.Commit.commitStamp,
+ &Interface->u.Commit.contextSwitched
+ );
+
+ if (status != gcvSTATUS_INTERRUPTED)
+ {
+ gcmkONERROR(status);
+ }
+
+ /* Force an event if powerManagement is on. */
+ status = gckEVENT_Commit(kernel->eventObj,
+ gcvNULL,
+ kernel->hardware->options.powerManagement);
+
+ if (status != gcvSTATUS_INTERRUPTED)
+ {
+ gcmkONERROR(status);
+ }
+ }
+ }
+
+ for (i = 0; i < Interface->u.Commit.count; i++)
+ {
+ gceHARDWARE_TYPE type = Interface->hardwareType;
+ gckKERNEL kernel = Device->map[type].kernels[i];
+
+ if ((kernel->hardware->options.gpuProfiler == gcvTRUE) &&
+ (kernel->profileEnable == gcvTRUE))
+ {
+ gcmkONERROR(gckCOMMAND_Stall(kernel->command, gcvTRUE));
+
+ if (kernel->command->currContext)
+ {
+ gcmkONERROR(gckHARDWARE_UpdateContextProfile(
+ kernel->hardware,
+ kernel->command->currContext));
+ }
+ }
+ }
+ }
+
+ if (!Interface->commitMutex)
+ {
+ gcmkONERROR(gckOS_ReleaseMutex(Kernel->os, Kernel->device->commitMutex));
+ commitMutexAcquired = gcvFALSE;
+ }
+ break;
+
+ case gcvHAL_STALL:
+ /* Stall the command queue. */
+ gcmkONERROR(gckCOMMAND_Stall(Kernel->command, gcvFALSE));
+
+ break;
+
+ case gcvHAL_MAP_USER_MEMORY:
+
+ gcmkONERROR(gcvSTATUS_NOT_SUPPORTED);
+
+ break;
+
+ case gcvHAL_UNMAP_USER_MEMORY:
+
+ gcmkONERROR(gcvSTATUS_NOT_SUPPORTED);
+
+ break;
+
+#if !USE_NEW_LINUX_SIGNAL
+ case gcvHAL_USER_SIGNAL:
+ /* Dispatch depends on the user signal subcommands. */
+ switch(Interface->u.UserSignal.command)
+ {
+ case gcvUSER_SIGNAL_CREATE:
+ /* Create a signal used in the user space. */
+ gcmkONERROR(
+ gckOS_CreateUserSignal(Kernel->os,
+ Interface->u.UserSignal.manualReset,
+ &Interface->u.UserSignal.id));
+
+ gcmkVERIFY_OK(
+ gckKERNEL_AddProcessDB(Kernel,
+ processID, gcvDB_SIGNAL,
+ gcmINT2PTR(Interface->u.UserSignal.id),
+ gcvNULL,
+ 0));
+ break;
+
+ case gcvUSER_SIGNAL_DESTROY:
+ gcmkVERIFY_OK(gckKERNEL_RemoveProcessDB(
+ Kernel,
+ processID, gcvDB_SIGNAL,
+ gcmINT2PTR(Interface->u.UserSignal.id)));
+
+ /* Destroy the signal. */
+ gcmkONERROR(
+ gckOS_DestroyUserSignal(Kernel->os,
+ Interface->u.UserSignal.id));
+ break;
+
+ case gcvUSER_SIGNAL_SIGNAL:
+ /* Signal the signal. */
+ gcmkONERROR(
+ gckOS_SignalUserSignal(Kernel->os,
+ Interface->u.UserSignal.id,
+ Interface->u.UserSignal.state));
+ break;
+
+ case gcvUSER_SIGNAL_WAIT:
+ /* Wait on the signal. */
+ status = gckOS_WaitUserSignal(Kernel->os,
+ Interface->u.UserSignal.id,
+ Interface->u.UserSignal.wait);
+ break;
+
+ case gcvUSER_SIGNAL_MAP:
+ gcmkONERROR(
+ gckOS_MapSignal(Kernel->os,
+ (gctSIGNAL)(gctUINTPTR_T)Interface->u.UserSignal.id,
+ (gctHANDLE)(gctUINTPTR_T)processID,
+ &signal));
+
+ gcmkVERIFY_OK(
+ gckKERNEL_AddProcessDB(Kernel,
+ processID, gcvDB_SIGNAL,
+ gcmINT2PTR(Interface->u.UserSignal.id),
+ gcvNULL,
+ 0));
+ break;
+
+ case gcvUSER_SIGNAL_UNMAP:
+ gcmkVERIFY_OK(gckKERNEL_RemoveProcessDB(
+ Kernel,
+ processID, gcvDB_SIGNAL,
+ gcmINT2PTR(Interface->u.UserSignal.id)));
+
+ /* Destroy the signal. */
+ gcmkONERROR(
+ gckOS_DestroyUserSignal(Kernel->os,
+ Interface->u.UserSignal.id));
+ break;
+
+ default:
+ /* Invalid user signal command. */
+ gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
+ }
+ break;
+#endif
+
+ case gcvHAL_SET_POWER_MANAGEMENT_STATE:
+ /* Set the power management state. */
+ gcmkONERROR(
+ gckHARDWARE_SetPowerManagementState(
+ Kernel->hardware,
+ Interface->u.SetPowerManagement.state));
+ break;
+
+ case gcvHAL_QUERY_POWER_MANAGEMENT_STATE:
+ /* Chip is not idle. */
+ Interface->u.QueryPowerManagement.isIdle = gcvFALSE;
+
+ /* Query the power management state. */
+ gcmkONERROR(gckHARDWARE_QueryPowerManagementState(
+ Kernel->hardware,
+ &Interface->u.QueryPowerManagement.state));
+
+ /* Query the idle state. */
+ gcmkONERROR(
+ gckHARDWARE_QueryIdle(Kernel->hardware,
+ &Interface->u.QueryPowerManagement.isIdle));
+ break;
+
+ case gcvHAL_READ_REGISTER:
+#if gcdREGISTER_ACCESS_FROM_USER
+ {
+ gceCHIPPOWERSTATE power;
+
+ gcmkONERROR(gckOS_AcquireMutex(Kernel->os, Kernel->hardware->powerMutex, gcvINFINITE));
+ powerMutexAcquired = gcvTRUE;
+ gcmkONERROR(gckHARDWARE_QueryPowerManagementState(Kernel->hardware,
+ &power));
+ if (power == gcvPOWER_ON)
+ {
+ /* Read a register. */
+ gcmkONERROR(gckOS_ReadRegisterEx(
+ Kernel->os,
+ Kernel->core,
+ Interface->u.ReadRegisterData.address,
+ &Interface->u.ReadRegisterData.data));
+ }
+ else
+ {
+ /* Chip is in power-state. */
+ Interface->u.ReadRegisterData.data = 0;
+ status = gcvSTATUS_CHIP_NOT_READY;
+ }
+ gcmkONERROR(gckOS_ReleaseMutex(Kernel->os, Kernel->hardware->powerMutex));
+ powerMutexAcquired = gcvFALSE;
+ }
+#else
+ /* No access from user land to read registers. */
+ Interface->u.ReadRegisterData.data = 0;
+ status = gcvSTATUS_NOT_SUPPORTED;
+#endif
+ break;
+
+ case gcvHAL_WRITE_REGISTER:
+#if gcdREGISTER_ACCESS_FROM_USER
+ {
+ gceCHIPPOWERSTATE power;
+
+ gcmkONERROR(gckOS_AcquireMutex(Kernel->os, Kernel->hardware->powerMutex, gcvINFINITE));
+ powerMutexAcquired = gcvTRUE;
+ gcmkONERROR(gckHARDWARE_QueryPowerManagementState(Kernel->hardware,
+ &power));
+ if (power == gcvPOWER_ON)
+ {
+ /* Write a register. */
+ gcmkONERROR(
+ gckOS_WriteRegisterEx(Kernel->os,
+ Kernel->core,
+ Interface->u.WriteRegisterData.address,
+ Interface->u.WriteRegisterData.data));
+ }
+ else
+ {
+ /* Chip is in power-state. */
+ Interface->u.WriteRegisterData.data = 0;
+ status = gcvSTATUS_CHIP_NOT_READY;
+ }
+ gcmkONERROR(gckOS_ReleaseMutex(Kernel->os, Kernel->hardware->powerMutex));
+ powerMutexAcquired = gcvFALSE;
+ }
+#else
+ /* No access from user land to write registers. */
+ status = gcvSTATUS_NOT_SUPPORTED;
+#endif
+ break;
+
+ case gcvHAL_READ_ALL_PROFILE_REGISTERS_PART1:
+ /* Read profile data according to the context. */
+ gcmkONERROR(
+ gckHARDWARE_QueryContextProfile(
+ Kernel->hardware,
+ Kernel->profileCleanRegister,
+ gcmNAME_TO_PTR(Interface->u.RegisterProfileData_part1.context),
+ &Interface->u.RegisterProfileData_part1.Counters,
+ gcvNULL));
+ break;
+ case gcvHAL_READ_ALL_PROFILE_REGISTERS_PART2:
+ /* Read profile data according to the context. */
+ gcmkONERROR(
+ gckHARDWARE_QueryContextProfile(
+ Kernel->hardware,
+ Kernel->profileCleanRegister,
+ gcmNAME_TO_PTR(Interface->u.RegisterProfileData_part2.context),
+ gcvNULL,
+ &Interface->u.RegisterProfileData_part2.Counters));
+ break;
+
+ case gcvHAL_GET_PROFILE_SETTING:
+#if VIVANTE_PROFILER
+ /* Get profile setting */
+ Interface->u.GetProfileSetting.enable = Kernel->profileEnable;
+#endif
+
+ status = gcvSTATUS_OK;
+ break;
+
+ case gcvHAL_SET_PROFILE_SETTING:
+#if VIVANTE_PROFILER
+ /* Set profile setting */
+ if(Kernel->hardware->options.gpuProfiler)
+ {
+ Kernel->profileEnable = Interface->u.SetProfileSetting.enable;
+
+ if (Kernel->profileEnable)
+ {
+ gcmkONERROR(gckHARDWARE_InitProfiler(Kernel->hardware));
+ }
+
+ }
+ else
+ {
+ status = gcvSTATUS_NOT_SUPPORTED;
+ break;
+ }
+#endif
+
+ status = gcvSTATUS_OK;
+ break;
+
+ case gcvHAL_READ_PROFILER_REGISTER_SETTING:
+ Kernel->profileCleanRegister = Interface->u.SetProfilerRegisterClear.bclear;
+ status = gcvSTATUS_OK;
+ break;
+
+ case gcvHAL_QUERY_KERNEL_SETTINGS:
+ /* Get kernel settings. */
+ gcmkONERROR(
+ gckKERNEL_QuerySettings(Kernel,
+ &Interface->u.QueryKernelSettings.settings));
+ break;
+
+ case gcvHAL_RESET:
+ /* Reset the hardware. */
+ gcmkONERROR(
+ gckHARDWARE_Reset(Kernel->hardware));
+ break;
+
+ case gcvHAL_DEBUG:
+ /* Set debug level and zones. */
+ if (Interface->u.Debug.set)
+ {
+ gckOS_SetDebugLevel(Interface->u.Debug.level);
+ gckOS_SetDebugZones(Interface->u.Debug.zones,
+ Interface->u.Debug.enable);
+ }
+
+ if (Interface->u.Debug.message[0] != '\0')
+ {
+ /* Print a message to the debugger. */
+ if (Interface->u.Debug.type == gcvMESSAGE_TEXT)
+ {
+ gckOS_DumpBuffer(Kernel->os,
+ Interface->u.Debug.message,
+ gcmSIZEOF(Interface->u.Debug.message),
+ gcvDUMP_BUFFER_FROM_USER,
+ gcvTRUE);
+ }
+ else
+ {
+ gckOS_DumpBuffer(Kernel->os,
+ Interface->u.Debug.message,
+ Interface->u.Debug.messageSize,
+ gcvDUMP_BUFFER_FROM_USER,
+ gcvTRUE);
+ }
+ }
+ status = gcvSTATUS_OK;
+ break;
+
+ case gcvHAL_DUMP_GPU_STATE:
+ {
+ gceCHIPPOWERSTATE power;
+
+ _DumpDriverConfigure(Kernel);
+
+ gcmkONERROR(gckHARDWARE_QueryPowerManagementState(
+ Kernel->hardware,
+ &power
+ ));
+
+ if (power == gcvPOWER_ON)
+ {
+ Interface->u.ReadRegisterData.data = 1;
+
+ _DumpState(Kernel);
+ }
+ else
+ {
+ Interface->u.ReadRegisterData.data = 0;
+ status = gcvSTATUS_CHIP_NOT_READY;
+
+ gcmkPRINT("[galcore]: Can't dump state if GPU isn't POWER ON.");
+ }
+ }
+ break;
+
+ case gcvHAL_DUMP_EVENT:
+ break;
+
+ case gcvHAL_CACHE:
+ logical = gcmUINT64_TO_PTR(Interface->u.Cache.logical);
+ bytes = (gctSIZE_T) Interface->u.Cache.bytes;
+
+ gcmkONERROR(gckKERNEL_CacheOperation(Kernel,
+ processID,
+ Interface->u.Cache.node,
+ Interface->u.Cache.operation,
+ logical,
+ bytes));
+ break;
+
+ case gcvHAL_TIMESTAMP:
+ /* Check for invalid timer. */
+ if ((Interface->u.TimeStamp.timer >= gcmCOUNTOF(Kernel->timers))
+ || (Interface->u.TimeStamp.request != 2))
+ {
+ Interface->u.TimeStamp.timeDelta = 0;
+ gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
+ }
+
+ /* Return timer results and reset timer. */
+ {
+ gcsTIMER_PTR timer = &(Kernel->timers[Interface->u.TimeStamp.timer]);
+ gctUINT64 timeDelta = 0;
+
+ if (timer->stopTime < timer->startTime )
+ {
+ Interface->u.TimeStamp.timeDelta = 0;
+ gcmkONERROR(gcvSTATUS_TIMER_OVERFLOW);
+ }
+
+ timeDelta = timer->stopTime - timer->startTime;
+
+ /* Check truncation overflow. */
+ Interface->u.TimeStamp.timeDelta = (gctINT32) timeDelta;
+ /*bit0~bit30 is available*/
+ if (timeDelta>>31)
+ {
+ Interface->u.TimeStamp.timeDelta = 0;
+ gcmkONERROR(gcvSTATUS_TIMER_OVERFLOW);
+ }
+
+ status = gcvSTATUS_OK;
+ }
+ break;
+
+ case gcvHAL_DATABASE:
+ gcmkONERROR(gckKERNEL_QueryDatabase(Kernel, processID, Interface));
+ break;
+
+ case gcvHAL_VERSION:
+ Interface->u.Version.major = gcvVERSION_MAJOR;
+ Interface->u.Version.minor = gcvVERSION_MINOR;
+ Interface->u.Version.patch = gcvVERSION_PATCH;
+ Interface->u.Version.build = gcvVERSION_BUILD;
+#if gcmIS_DEBUG(gcdDEBUG_TRACE)
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_KERNEL,
+ "KERNEL version %d.%d.%d build %u",
+ gcvVERSION_MAJOR, gcvVERSION_MINOR,
+ gcvVERSION_PATCH, gcvVERSION_BUILD);
+#endif
+ break;
+
+ case gcvHAL_CHIP_INFO:
+ /* Only if not support multi-core */
+ Interface->u.ChipInfo.count = 1;
+ Interface->u.ChipInfo.types[0] = Kernel->hardware->type;
+ break;
+
+#if (gcdENABLE_3D || gcdENABLE_2D)
+ case gcvHAL_ATTACH:
+ /* Attach user process. */
+ gcmkONERROR(
+ gckCOMMAND_Attach(Kernel->command,
+ &context,
+ &bytes,
+ &Interface->u.Attach.numStates,
+ processID));
+
+ Interface->u.Attach.maxState = bytes;
+ Interface->u.Attach.context = gcmPTR_TO_NAME(context);
+
+ if (Interface->u.Attach.map == gcvTRUE)
+ {
+ gcmkVERIFY_OK(
+ gckCONTEXT_MapBuffer(context,
+ Interface->u.Attach.physicals,
+ Interface->u.Attach.logicals,
+ &Interface->u.Attach.bytes));
+ }
+
+ gcmkVERIFY_OK(
+ gckKERNEL_AddProcessDB(Kernel,
+ processID, gcvDB_CONTEXT,
+ gcmINT2PTR(Interface->u.Attach.context),
+ gcvNULL,
+ 0));
+ break;
+#endif
+
+ case gcvHAL_DETACH:
+ gcmkVERIFY_OK(
+ gckKERNEL_RemoveProcessDB(Kernel,
+ processID, gcvDB_CONTEXT,
+ gcmINT2PTR(Interface->u.Detach.context)));
+
+ /* Detach user process. */
+ gcmkONERROR(
+ gckCOMMAND_Detach(Kernel->command,
+ gcmNAME_TO_PTR(Interface->u.Detach.context)));
+
+ gcmRELEASE_NAME(Interface->u.Detach.context);
+ gcmkONERROR(gckOS_AcquireMutex(Kernel->os,
+ Kernel->device->commitMutex,
+ gcvINFINITE
+ ));
+
+ commitMutexAcquired = gcvTRUE;
+
+ gcmkONERROR(gckEVENT_Submit(
+ Kernel->eventObj,
+ gcvTRUE,
+ gcvFALSE
+ ));
+
+ gcmkONERROR(gckOS_ReleaseMutex(Kernel->os,
+ Kernel->device->commitMutex
+ ));
+
+ commitMutexAcquired = gcvFALSE;
+ break;
+
+ case gcvHAL_GET_FRAME_INFO:
+ gcmkONERROR(gckHARDWARE_GetFrameInfo(
+ Kernel->hardware,
+ gcmUINT64_TO_PTR(Interface->u.GetFrameInfo.frameInfo)));
+ break;
+
+ case gcvHAL_DUMP_GPU_PROFILE:
+ gcmkONERROR(gckHARDWARE_DumpGpuProfile(Kernel->hardware));
+ break;
+
+ case gcvHAL_SET_FSCALE_VALUE:
+#if gcdENABLE_FSCALE_VAL_ADJUST
+ status = gckHARDWARE_SetFscaleValue(Kernel->hardware,
+ Interface->u.SetFscaleValue.value);
+#else
+ status = gcvSTATUS_NOT_SUPPORTED;
+#endif
+ break;
+ case gcvHAL_GET_FSCALE_VALUE:
+#if gcdENABLE_FSCALE_VAL_ADJUST
+ status = gckHARDWARE_GetFscaleValue(Kernel->hardware,
+ &Interface->u.GetFscaleValue.value,
+ &Interface->u.GetFscaleValue.minValue,
+ &Interface->u.GetFscaleValue.maxValue);
+#else
+ status = gcvSTATUS_NOT_SUPPORTED;
+#endif
+ break;
+
+ case gcvHAL_EXPORT_VIDEO_MEMORY:
+ /* Unlock video memory. */
+ gcmkONERROR(gckVIDMEM_NODE_Export(Kernel,
+ Interface->u.ExportVideoMemory.node,
+ Interface->u.ExportVideoMemory.flags,
+ gcvNULL,
+ &Interface->u.ExportVideoMemory.fd));
+ break;
+
+ case gcvHAL_NAME_VIDEO_MEMORY:
+ gcmkONERROR(gckVIDMEM_NODE_Name(Kernel,
+ Interface->u.NameVideoMemory.handle,
+ &Interface->u.NameVideoMemory.name));
+ break;
+
+ case gcvHAL_IMPORT_VIDEO_MEMORY:
+ gcmkONERROR(gckVIDMEM_NODE_Import(Kernel,
+ Interface->u.ImportVideoMemory.name,
+ &Interface->u.ImportVideoMemory.handle));
+
+ gcmkONERROR(
+ gckKERNEL_AddProcessDB(Kernel,
+ processID, gcvDB_VIDEO_MEMORY,
+ gcmINT2PTR(Interface->u.ImportVideoMemory.handle),
+ gcvNULL,
+ 0));
+ break;
+
+ case gcvHAL_SET_VIDEO_MEMORY_METADATA:
+ gcmkONERROR(gckKERNEL_SetVidMemMetadata(Kernel, processID, Interface));
+ break;
+
+ case gcvHAL_GET_VIDEO_MEMORY_FD:
+ gcmkONERROR(gckVIDMEM_NODE_GetFd(
+ Kernel,
+ Interface->u.GetVideoMemoryFd.handle,
+ &Interface->u.GetVideoMemoryFd.fd
+ ));
+
+ /* No need to add it to processDB because OS will release all fds when
+ ** process quits.
+ */
+ break;
+
+ case gcvHAL_QUERY_RESET_TIME_STAMP:
+ Interface->u.QueryResetTimeStamp.timeStamp = Kernel->resetTimeStamp;
+ Interface->u.QueryResetTimeStamp.contextID = Kernel->hardware->contextID;
+ break;
+
+ case gcvHAL_FREE_VIRTUAL_COMMAND_BUFFER:
+ buffer = (gckVIRTUAL_COMMAND_BUFFER_PTR)gcmNAME_TO_PTR(Interface->u.FreeVirtualCommandBuffer.physical);
+
+ gcmkVERIFY_OK(gckKERNEL_RemoveProcessDB(
+ Kernel,
+ processID,
+ gcvDB_COMMAND_BUFFER,
+ gcmUINT64_TO_PTR(Interface->u.FreeVirtualCommandBuffer.logical)));
+
+ gcmkONERROR(gckOS_DestroyUserVirtualMapping(
+ Kernel->os,
+ buffer->virtualBuffer.physical,
+ (gctSIZE_T)Interface->u.FreeVirtualCommandBuffer.bytes,
+ gcmUINT64_TO_PTR(Interface->u.FreeVirtualCommandBuffer.logical)));
+
+ gcmkONERROR(gckKERNEL_DestroyVirtualCommandBuffer(
+ Kernel,
+ (gctSIZE_T)Interface->u.FreeVirtualCommandBuffer.bytes,
+ (gctPHYS_ADDR)buffer,
+ gcmUINT64_TO_PTR(Interface->u.FreeVirtualCommandBuffer.logical)));
+
+ gcmRELEASE_NAME(Interface->u.FreeVirtualCommandBuffer.physical);
+ break;
+
+#if gcdLINUX_SYNC_FILE
+ case gcvHAL_CREATE_NATIVE_FENCE:
+ {
+ gctINT fenceFD;
+ gctSIGNAL signal =
+ gcmUINT64_TO_PTR(Interface->u.CreateNativeFence.signal);
+
+ gcmkONERROR(
+ gckOS_CreateNativeFence(Kernel->os,
+ Kernel->timeline,
+ signal,
+ &fenceFD));
+
+ Interface->u.CreateNativeFence.fenceFD = fenceFD;
+ }
+ break;
+
+ case gcvHAL_WAIT_NATIVE_FENCE:
+ {
+ gctINT fenceFD;
+ gctUINT32 timeout;
+
+ fenceFD = Interface->u.WaitNativeFence.fenceFD;
+ timeout = Interface->u.WaitNativeFence.timeout;
+
+ gcmkONERROR(
+ gckOS_WaitNativeFence(Kernel->os,
+ Kernel->timeline,
+ fenceFD,
+ timeout));
+ }
+ break;
+#endif
+
+ case gcvHAL_SHBUF:
+ {
+ gctSHBUF shBuf;
+ gctPOINTER uData;
+ gctUINT32 bytes;
+
+ switch (Interface->u.ShBuf.command)
+ {
+ case gcvSHBUF_CREATE:
+ bytes = Interface->u.ShBuf.bytes;
+
+ /* Create. */
+ gcmkONERROR(gckKERNEL_CreateShBuffer(Kernel, bytes, &shBuf));
+
+ Interface->u.ShBuf.id = gcmPTR_TO_UINT64(shBuf);
+
+ gcmkVERIFY_OK(
+ gckKERNEL_AddProcessDB(Kernel,
+ processID,
+ gcvDB_SHBUF,
+ shBuf,
+ gcvNULL,
+ 0));
+ break;
+
+ case gcvSHBUF_DESTROY:
+ shBuf = gcmUINT64_TO_PTR(Interface->u.ShBuf.id);
+
+ /* Check db first to avoid illegal destroy in the process. */
+ gcmkONERROR(
+ gckKERNEL_RemoveProcessDB(Kernel,
+ processID,
+ gcvDB_SHBUF,
+ shBuf));
+
+ gcmkONERROR(gckKERNEL_DestroyShBuffer(Kernel, shBuf));
+ break;
+
+ case gcvSHBUF_MAP:
+ shBuf = gcmUINT64_TO_PTR(Interface->u.ShBuf.id);
+
+ /* Map for current process access. */
+ gcmkONERROR(gckKERNEL_MapShBuffer(Kernel, shBuf));
+
+ gcmkVERIFY_OK(
+ gckKERNEL_AddProcessDB(Kernel,
+ processID,
+ gcvDB_SHBUF,
+ shBuf,
+ gcvNULL,
+ 0));
+ break;
+
+ case gcvSHBUF_WRITE:
+ shBuf = gcmUINT64_TO_PTR(Interface->u.ShBuf.id);
+ uData = gcmUINT64_TO_PTR(Interface->u.ShBuf.data);
+ bytes = Interface->u.ShBuf.bytes;
+
+ /* Write. */
+ gcmkONERROR(
+ gckKERNEL_WriteShBuffer(Kernel, shBuf, uData, bytes));
+ break;
+
+ case gcvSHBUF_READ:
+ shBuf = gcmUINT64_TO_PTR(Interface->u.ShBuf.id);
+ uData = gcmUINT64_TO_PTR(Interface->u.ShBuf.data);
+ bytes = Interface->u.ShBuf.bytes;
+
+ /* Read. */
+ gcmkONERROR(
+ gckKERNEL_ReadShBuffer(Kernel,
+ shBuf,
+ uData,
+ bytes,
+ &bytes));
+
+ /* Return copied size. */
+ Interface->u.ShBuf.bytes = bytes;
+ break;
+
+ default:
+ gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
+ break;
+ }
+ }
+ break;
+
+#ifdef __linux__
+ case gcvHAL_GET_GRAPHIC_BUFFER_FD:
+ gcmkONERROR(_GetGraphicBufferFd(
+ Kernel,
+ processID,
+ Interface->u.GetGraphicBufferFd.node,
+ Interface->u.GetGraphicBufferFd.shBuf,
+ Interface->u.GetGraphicBufferFd.signal,
+ &Interface->u.GetGraphicBufferFd.fd
+ ));
+ break;
+#endif
+
+
+ case gcvHAL_CONFIG_POWER_MANAGEMENT:
+ gcmkONERROR(gckKERNEL_ConfigPowerManagement(Kernel, Interface));
+ break;
+
+ case gcvHAL_WRAP_USER_MEMORY:
+ gcmkONERROR(gckVIDMEM_NODE_WrapUserMemory(Kernel,
+ &Interface->u.WrapUserMemory.desc,
+ &Interface->u.WrapUserMemory.node,
+ &Interface->u.WrapUserMemory.bytes));
+
+ gcmkONERROR(
+ gckKERNEL_AddProcessDB(Kernel,
+ processID,
+ gcvDB_VIDEO_MEMORY,
+ gcmINT2PTR(Interface->u.WrapUserMemory.node),
+ gcvNULL,
+ 0));
+ break;
+
+ case gcvHAL_WAIT_FENCE:
+ gcmkONERROR(gckKERNEL_WaitFence(
+ Kernel,
+ Interface->u.WaitFence.handle,
+ Interface->u.WaitFence.timeOut
+ ));
+ break;
+
+ case gcvHAL_DEVICE_MUTEX:
+ if (Interface->u.DeviceMutex.isMutexLocked)
+ {
+ gcmkONERROR(gckOS_AcquireMutex(Kernel->os,
+ Kernel->device->commitMutex,
+ gcvINFINITE
+ ));
+ }
+ else
+ {
+ gcmkONERROR(gckOS_ReleaseMutex(Kernel->os, Kernel->device->commitMutex));
+ }
+ break;
+
+#if gcdDEC_ENABLE_AHB
+ case gcvHAL_DEC300_READ:
+ gcmkONERROR(viv_dec300_read(
+ Interface->u.DEC300Read.enable,
+ Interface->u.DEC300Read.readId,
+ Interface->u.DEC300Read.format,
+ Interface->u.DEC300Read.strides,
+ Interface->u.DEC300Read.is3D,
+ Interface->u.DEC300Read.isMSAA,
+ Interface->u.DEC300Read.clearValue,
+ Interface->u.DEC300Read.isTPC,
+ Interface->u.DEC300Read.isTPCCompressed,
+ Interface->u.DEC300Read.surfAddrs,
+ Interface->u.DEC300Read.tileAddrs
+ ));
+ break;
+
+ case gcvHAL_DEC300_WRITE:
+ gcmkONERROR(viv_dec300_write(
+ Interface->u.DEC300Write.enable,
+ Interface->u.DEC300Write.readId,
+ Interface->u.DEC300Write.writeId,
+ Interface->u.DEC300Write.format,
+ Interface->u.DEC300Write.surfAddr,
+ Interface->u.DEC300Write.tileAddr
+ ));
+ break;
+
+ case gcvHAL_DEC300_FLUSH:
+ gcmkONERROR(viv_dec300_flush(0));
+ break;
+
+ case gcvHAL_DEC300_FLUSH_WAIT:
+ gcmkONERROR(viv_dec300_flush_done(&Interface->u.DEC300FlushWait.done));
+ break;
+#endif
+
+
+ case gcvHAL_QUERY_CHIP_OPTION:
+ /* Query chip options. */
+ gcmkONERROR(
+ gckHARDWARE_QueryChipOptions(
+ Kernel->hardware,
+ &Interface->u.QueryChipOptions));
+ break;
+
+ default:
+ /* Invalid command. */
+ gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
+ }
+
+OnError:
+ /* Save status. */
+ Interface->status = status;
+
+#if QNX_SINGLE_THREADED_DEBUGGING
+ gckOS_ReleaseMutex(Kernel->os, Kernel->debugMutex);
+#endif
+
+ if (powerMutexAcquired == gcvTRUE)
+ {
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, Kernel->hardware->powerMutex));
+ }
+
+ if (commitMutexAcquired == gcvTRUE)
+ {
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, Kernel->device->commitMutex));
+ }
+
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+/*******************************************************************************
+** gckKERNEL_AttachProcess
+**
+** Attach or detach a process.
+**
+** INPUT:
+**
+** gckKERNEL Kernel
+** Pointer to an gckKERNEL object.
+**
+** gctBOOL Attach
+** gcvTRUE if a new process gets attached or gcFALSE when a process
+** gets detatched.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckKERNEL_AttachProcess(
+ IN gckKERNEL Kernel,
+ IN gctBOOL Attach
+ )
+{
+ gceSTATUS status;
+ gctUINT32 processID;
+
+ gcmkHEADER_ARG("Kernel=0x%x Attach=%d", Kernel, Attach);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
+
+ /* Get current process ID. */
+ gcmkONERROR(gckOS_GetProcessID(&processID));
+
+ gcmkONERROR(gckKERNEL_AttachProcessEx(Kernel, Attach, processID));
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+/*******************************************************************************
+** gckKERNEL_AttachProcessEx
+**
+** Attach or detach a process with the given PID. Can be paired with gckKERNEL_AttachProcess
+** provided the programmer is aware of the consequences.
+**
+** INPUT:
+**
+** gckKERNEL Kernel
+** Pointer to an gckKERNEL object.
+**
+** gctBOOL Attach
+** gcvTRUE if a new process gets attached or gcFALSE when a process
+** gets detatched.
+**
+** gctUINT32 PID
+** PID of the process to attach or detach.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckKERNEL_AttachProcessEx(
+ IN gckKERNEL Kernel,
+ IN gctBOOL Attach,
+ IN gctUINT32 PID
+ )
+{
+ gceSTATUS status;
+ gctINT32 old;
+
+ gcmkHEADER_ARG("Kernel=0x%x Attach=%d PID=%d", Kernel, Attach, PID);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
+
+ if (Attach)
+ {
+ /* Increment the number of clients attached. */
+ gcmkONERROR(
+ gckOS_AtomIncrement(Kernel->os, Kernel->atomClients, &old));
+
+ if (old == 0)
+ {
+#if gcdENABLE_VG
+ if (Kernel->vg == gcvNULL)
+#endif
+ {
+ gcmkONERROR(gckOS_Broadcast(Kernel->os,
+ Kernel->hardware,
+ gcvBROADCAST_FIRST_PROCESS));
+ }
+ }
+
+ if (Kernel->dbCreated)
+ {
+ /* Create the process database. */
+ gcmkONERROR(gckKERNEL_CreateProcessDB(Kernel, PID));
+ }
+
+#if gcdPROCESS_ADDRESS_SPACE
+ /* Map kernel command buffer in the process's own MMU. */
+ gcmkONERROR(_MapCommandBuffer(Kernel));
+#endif
+ }
+ else
+ {
+ if (Kernel->dbCreated)
+ {
+ /* Clean up the process database. */
+ gcmkONERROR(gckKERNEL_DestroyProcessDB(Kernel, PID));
+
+ /* Save the last know process ID. */
+ Kernel->db->lastProcessID = PID;
+ }
+
+#if gcdENABLE_VG
+ if (Kernel->vg == gcvNULL)
+#endif
+ {
+ status = gckEVENT_Submit(Kernel->eventObj, gcvTRUE, gcvFALSE);
+
+ if (status == gcvSTATUS_INTERRUPTED && Kernel->eventObj->submitTimer)
+ {
+ gcmkONERROR(gckOS_StartTimer(Kernel->os,
+ Kernel->eventObj->submitTimer,
+ 1));
+ }
+ else
+ {
+ gcmkONERROR(status);
+ }
+ }
+
+ /* Decrement the number of clients attached. */
+ gcmkONERROR(
+ gckOS_AtomDecrement(Kernel->os, Kernel->atomClients, &old));
+
+ if (old == 1)
+ {
+#if gcdENABLE_VG
+ if (Kernel->vg == gcvNULL)
+#endif
+ {
+ /* Last client detached, switch to SUSPEND power state. */
+ gcmkONERROR(gckOS_Broadcast(Kernel->os,
+ Kernel->hardware,
+ gcvBROADCAST_LAST_PROCESS));
+ }
+
+ /* Flush the debug cache. */
+ gcmkDEBUGFLUSH(~0U);
+ }
+ }
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+#if gcdSECURE_USER
+gceSTATUS
+gckKERNEL_MapLogicalToPhysical(
+ IN gckKERNEL Kernel,
+ IN gcskSECURE_CACHE_PTR Cache,
+ IN OUT gctPOINTER * Data
+ )
+{
+ gceSTATUS status;
+ static gctBOOL baseAddressValid = gcvFALSE;
+ static gctUINT32 baseAddress;
+ gctBOOL needBase;
+ gcskLOGICAL_CACHE_PTR slot;
+
+ gcmkHEADER_ARG("Kernel=0x%x Cache=0x%x *Data=0x%x",
+ Kernel, Cache, gcmOPT_POINTER(Data));
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
+
+ if (!baseAddressValid)
+ {
+ /* Get base address. */
+ gcmkONERROR(gckHARDWARE_GetBaseAddress(Kernel->hardware, &baseAddress));
+
+ baseAddressValid = gcvTRUE;
+ }
+
+ /* Does this state load need a base address? */
+ gcmkONERROR(gckHARDWARE_NeedBaseAddress(Kernel->hardware,
+ ((gctUINT32_PTR) Data)[-1],
+ &needBase));
+
+#if gcdSECURE_CACHE_METHOD == gcdSECURE_CACHE_LRU
+ {
+ gcskLOGICAL_CACHE_PTR next;
+ gctINT i;
+
+ /* Walk all used cache slots. */
+ for (i = 1, slot = Cache->cache[0].next, next = gcvNULL;
+ (i <= gcdSECURE_CACHE_SLOTS) && (slot->logical != gcvNULL);
+ ++i, slot = slot->next
+ )
+ {
+ if (slot->logical == *Data)
+ {
+ /* Bail out. */
+ next = slot;
+ break;
+ }
+ }
+
+ /* See if we had a miss. */
+ if (next == gcvNULL)
+ {
+ /* Use the tail of the cache. */
+ slot = Cache->cache[0].prev;
+
+ /* Initialize the cache line. */
+ slot->logical = *Data;
+
+ /* Map the logical address to a DMA address. */
+ gcmkONERROR(
+ gckOS_GetPhysicalAddress(Kernel->os, *Data, &slot->dma));
+
+ gcmkVERIFY_OK(gckOS_CPUPhysicalToGPUPhysical(Kernel->os, slot->dma, &slot->dma));
+ }
+
+ /* Move slot to head of list. */
+ if (slot != Cache->cache[0].next)
+ {
+ /* Unlink. */
+ slot->prev->next = slot->next;
+ slot->next->prev = slot->prev;
+
+ /* Move to head of chain. */
+ slot->prev = &Cache->cache[0];
+ slot->next = Cache->cache[0].next;
+ slot->prev->next = slot;
+ slot->next->prev = slot;
+ }
+ }
+#elif gcdSECURE_CACHE_METHOD == gcdSECURE_CACHE_LINEAR
+ {
+ gctINT i;
+ gcskLOGICAL_CACHE_PTR next = gcvNULL;
+ gcskLOGICAL_CACHE_PTR oldestSlot = gcvNULL;
+ slot = gcvNULL;
+
+ if (Cache->cacheIndex != gcvNULL)
+ {
+ /* Walk the cache forwards. */
+ for (i = 1, slot = Cache->cacheIndex;
+ (i <= gcdSECURE_CACHE_SLOTS) && (slot->logical != gcvNULL);
+ ++i, slot = slot->next)
+ {
+ if (slot->logical == *Data)
+ {
+ /* Bail out. */
+ next = slot;
+ break;
+ }
+
+ /* Determine age of this slot. */
+ if ((oldestSlot == gcvNULL)
+ || (oldestSlot->stamp > slot->stamp)
+ )
+ {
+ oldestSlot = slot;
+ }
+ }
+
+ if (next == gcvNULL)
+ {
+ /* Walk the cache backwards. */
+ for (slot = Cache->cacheIndex->prev;
+ (i <= gcdSECURE_CACHE_SLOTS) && (slot->logical != gcvNULL);
+ ++i, slot = slot->prev)
+ {
+ if (slot->logical == *Data)
+ {
+ /* Bail out. */
+ next = slot;
+ break;
+ }
+
+ /* Determine age of this slot. */
+ if ((oldestSlot == gcvNULL)
+ || (oldestSlot->stamp > slot->stamp)
+ )
+ {
+ oldestSlot = slot;
+ }
+ }
+ }
+ }
+
+ /* See if we had a miss. */
+ if (next == gcvNULL)
+ {
+ if (Cache->cacheFree != 0)
+ {
+ slot = &Cache->cache[Cache->cacheFree];
+ gcmkASSERT(slot->logical == gcvNULL);
+
+ ++ Cache->cacheFree;
+ if (Cache->cacheFree >= gcmCOUNTOF(Cache->cache))
+ {
+ Cache->cacheFree = 0;
+ }
+ }
+ else
+ {
+ /* Use the oldest cache slot. */
+ gcmkASSERT(oldestSlot != gcvNULL);
+ slot = oldestSlot;
+
+ /* Unlink from the chain. */
+ slot->prev->next = slot->next;
+ slot->next->prev = slot->prev;
+
+ /* Append to the end. */
+ slot->prev = Cache->cache[0].prev;
+ slot->next = &Cache->cache[0];
+ slot->prev->next = slot;
+ slot->next->prev = slot;
+ }
+
+ /* Initialize the cache line. */
+ slot->logical = *Data;
+
+ /* Map the logical address to a DMA address. */
+ gcmkONERROR(
+ gckOS_GetPhysicalAddress(Kernel->os, *Data, &slot->dma));
+
+ gcmkVERIFY_OK(gckOS_CPUPhysicalToGPUPhysical(Kernel->os, slot->dma, &slot->dma));
+ }
+
+ /* Save time stamp. */
+ slot->stamp = ++ Cache->cacheStamp;
+
+ /* Save current slot for next lookup. */
+ Cache->cacheIndex = slot;
+ }
+#elif gcdSECURE_CACHE_METHOD == gcdSECURE_CACHE_HASH
+ {
+ gctINT i;
+ gctUINT32 data = gcmPTR2INT32(*Data);
+ gctUINT32 key, index;
+ gcskLOGICAL_CACHE_PTR hash;
+
+ /* Generate a hash key. */
+ key = (data >> 24) + (data >> 16) + (data >> 8) + data;
+ index = key % gcmCOUNTOF(Cache->hash);
+
+ /* Get the hash entry. */
+ hash = &Cache->hash[index];
+
+ for (slot = hash->nextHash, i = 0;
+ (slot != gcvNULL) && (i < gcdSECURE_CACHE_SLOTS);
+ slot = slot->nextHash, ++i
+ )
+ {
+ if (slot->logical == (*Data))
+ {
+ break;
+ }
+ }
+
+ if (slot == gcvNULL)
+ {
+ /* Grab from the tail of the cache. */
+ slot = Cache->cache[0].prev;
+
+ /* Unlink slot from any hash table it is part of. */
+ if (slot->prevHash != gcvNULL)
+ {
+ slot->prevHash->nextHash = slot->nextHash;
+ }
+ if (slot->nextHash != gcvNULL)
+ {
+ slot->nextHash->prevHash = slot->prevHash;
+ }
+
+ /* Initialize the cache line. */
+ slot->logical = *Data;
+
+ /* Map the logical address to a DMA address. */
+ gcmkONERROR(
+ gckOS_GetPhysicalAddress(Kernel->os, *Data, &slot->dma));
+
+ gcmkVERIFY_OK(gckOS_CPUPhysicalToGPUPhysical(Kernel->os, slot->dma, &slot->dma));
+
+ if (hash->nextHash != gcvNULL)
+ {
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_KERNEL,
+ "Hash Collision: logical=0x%x key=0x%08x",
+ *Data, key);
+ }
+
+ /* Insert the slot at the head of the hash list. */
+ slot->nextHash = hash->nextHash;
+ if (slot->nextHash != gcvNULL)
+ {
+ slot->nextHash->prevHash = slot;
+ }
+ slot->prevHash = hash;
+ hash->nextHash = slot;
+ }
+
+ /* Move slot to head of list. */
+ if (slot != Cache->cache[0].next)
+ {
+ /* Unlink. */
+ slot->prev->next = slot->next;
+ slot->next->prev = slot->prev;
+
+ /* Move to head of chain. */
+ slot->prev = &Cache->cache[0];
+ slot->next = Cache->cache[0].next;
+ slot->prev->next = slot;
+ slot->next->prev = slot;
+ }
+ }
+#elif gcdSECURE_CACHE_METHOD == gcdSECURE_CACHE_TABLE
+ {
+ gctUINT32 index = (gcmPTR2INT32(*Data) % gcdSECURE_CACHE_SLOTS) + 1;
+
+ /* Get cache slot. */
+ slot = &Cache->cache[index];
+
+ /* Check for cache miss. */
+ if (slot->logical != *Data)
+ {
+ /* Initialize the cache line. */
+ slot->logical = *Data;
+
+ /* Map the logical address to a DMA address. */
+ gcmkONERROR(
+ gckOS_GetPhysicalAddress(Kernel->os, *Data, &slot->dma));
+
+ gcmkVERIFY_OK(gckOS_CPUPhysicalToGPUPhysical(Kernel->os, slot->dma, &slot->dma));
+ }
+ }
+#endif
+
+ /* Return DMA address. */
+ *Data = gcmINT2PTR(slot->dma + (needBase ? baseAddress : 0));
+
+ /* Success. */
+ gcmkFOOTER_ARG("*Data=0x%08x", *Data);
+ return gcvSTATUS_OK;
+
+OnError:
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+gceSTATUS
+gckKERNEL_FlushTranslationCache(
+ IN gckKERNEL Kernel,
+ IN gcskSECURE_CACHE_PTR Cache,
+ IN gctPOINTER Logical,
+ IN gctSIZE_T Bytes
+ )
+{
+ gctINT i;
+ gcskLOGICAL_CACHE_PTR slot;
+ gctUINT8_PTR ptr;
+
+ gcmkHEADER_ARG("Kernel=0x%x Cache=0x%x Logical=0x%x Bytes=%lu",
+ Kernel, Cache, Logical, Bytes);
+
+ /* Do we need to flush the entire cache? */
+ if (Logical == gcvNULL)
+ {
+ /* Clear all cache slots. */
+ for (i = 1; i <= gcdSECURE_CACHE_SLOTS; ++i)
+ {
+ Cache->cache[i].logical = gcvNULL;
+
+#if gcdSECURE_CACHE_METHOD == gcdSECURE_CACHE_HASH
+ Cache->cache[i].nextHash = gcvNULL;
+ Cache->cache[i].prevHash = gcvNULL;
+#endif
+}
+
+#if gcdSECURE_CACHE_METHOD == gcdSECURE_CACHE_HASH
+ /* Zero the hash table. */
+ for (i = 0; i < gcmCOUNTOF(Cache->hash); ++i)
+ {
+ Cache->hash[i].nextHash = gcvNULL;
+ }
+#endif
+
+ /* Reset the cache functionality. */
+ Cache->cacheIndex = gcvNULL;
+ Cache->cacheFree = 1;
+ Cache->cacheStamp = 0;
+ }
+
+ else
+ {
+ gctUINT8_PTR low = (gctUINT8_PTR) Logical;
+ gctUINT8_PTR high = low + Bytes;
+
+#if gcdSECURE_CACHE_METHOD == gcdSECURE_CACHE_LRU
+ gcskLOGICAL_CACHE_PTR next;
+
+ /* Walk all used cache slots. */
+ for (i = 1, slot = Cache->cache[0].next;
+ (i <= gcdSECURE_CACHE_SLOTS) && (slot->logical != gcvNULL);
+ ++i, slot = next
+ )
+ {
+ /* Save pointer to next slot. */
+ next = slot->next;
+
+ /* Test if this slot falls within the range to flush. */
+ ptr = (gctUINT8_PTR) slot->logical;
+ if ((ptr >= low) && (ptr < high))
+ {
+ /* Unlink slot. */
+ slot->prev->next = slot->next;
+ slot->next->prev = slot->prev;
+
+ /* Append slot to tail of cache. */
+ slot->prev = Cache->cache[0].prev;
+ slot->next = &Cache->cache[0];
+ slot->prev->next = slot;
+ slot->next->prev = slot;
+
+ /* Mark slot as empty. */
+ slot->logical = gcvNULL;
+ }
+ }
+
+#elif gcdSECURE_CACHE_METHOD == gcdSECURE_CACHE_LINEAR
+ gcskLOGICAL_CACHE_PTR next;
+
+ for (i = 1, slot = Cache->cache[0].next;
+ (i <= gcdSECURE_CACHE_SLOTS) && (slot->logical != gcvNULL);
+ ++i, slot = next)
+ {
+ /* Save pointer to next slot. */
+ next = slot->next;
+
+ /* Test if this slot falls within the range to flush. */
+ ptr = (gctUINT8_PTR) slot->logical;
+ if ((ptr >= low) && (ptr < high))
+ {
+ /* Test if this slot is the current slot. */
+ if (slot == Cache->cacheIndex)
+ {
+ /* Move to next or previous slot. */
+ Cache->cacheIndex = (slot->next->logical != gcvNULL)
+ ? slot->next
+ : (slot->prev->logical != gcvNULL)
+ ? slot->prev
+ : gcvNULL;
+ }
+
+ /* Unlink slot from cache. */
+ slot->prev->next = slot->next;
+ slot->next->prev = slot->prev;
+
+ /* Insert slot to head of cache. */
+ slot->prev = &Cache->cache[0];
+ slot->next = Cache->cache[0].next;
+ slot->prev->next = slot;
+ slot->next->prev = slot;
+
+ /* Mark slot as empty. */
+ slot->logical = gcvNULL;
+ slot->stamp = 0;
+ }
+ }
+
+#elif gcdSECURE_CACHE_METHOD == gcdSECURE_CACHE_HASH
+ gctINT j;
+ gcskLOGICAL_CACHE_PTR hash, next;
+
+ /* Walk all hash tables. */
+ for (i = 0, hash = Cache->hash;
+ i < gcmCOUNTOF(Cache->hash);
+ ++i, ++hash)
+ {
+ /* Walk all slots in the hash. */
+ for (j = 0, slot = hash->nextHash;
+ (j < gcdSECURE_CACHE_SLOTS) && (slot != gcvNULL);
+ ++j, slot = next)
+ {
+ /* Save pointer to next slot. */
+ next = slot->next;
+
+ /* Test if this slot falls within the range to flush. */
+ ptr = (gctUINT8_PTR) slot->logical;
+ if ((ptr >= low) && (ptr < high))
+ {
+ /* Unlink slot from hash table. */
+ if (slot->prevHash == hash)
+ {
+ hash->nextHash = slot->nextHash;
+ }
+ else
+ {
+ slot->prevHash->nextHash = slot->nextHash;
+ }
+
+ if (slot->nextHash != gcvNULL)
+ {
+ slot->nextHash->prevHash = slot->prevHash;
+ }
+
+ /* Unlink slot from cache. */
+ slot->prev->next = slot->next;
+ slot->next->prev = slot->prev;
+
+ /* Append slot to tail of cache. */
+ slot->prev = Cache->cache[0].prev;
+ slot->next = &Cache->cache[0];
+ slot->prev->next = slot;
+ slot->next->prev = slot;
+
+ /* Mark slot as empty. */
+ slot->logical = gcvNULL;
+ slot->prevHash = gcvNULL;
+ slot->nextHash = gcvNULL;
+ }
+ }
+ }
+
+#elif gcdSECURE_CACHE_METHOD == gcdSECURE_CACHE_TABLE
+ gctUINT32 index;
+
+ /* Loop while inside the range. */
+ for (i = 1; (low < high) && (i <= gcdSECURE_CACHE_SLOTS); ++i)
+ {
+ /* Get index into cache for this range. */
+ index = (gcmPTR2INT32(low) % gcdSECURE_CACHE_SLOTS) + 1;
+ slot = &Cache->cache[index];
+
+ /* Test if this slot falls within the range to flush. */
+ ptr = (gctUINT8_PTR) slot->logical;
+ if ((ptr >= low) && (ptr < high))
+ {
+ /* Remove entry from cache. */
+ slot->logical = gcvNULL;
+ }
+
+ /* Next block. */
+ low += gcdSECURE_CACHE_SLOTS;
+ }
+#endif
+ }
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+}
+#endif
+
+/*******************************************************************************
+**
+** gckKERNEL_Recovery
+**
+** Try to recover the GPU from a fatal error.
+**
+** INPUT:
+**
+** gckKERNEL Kernel
+** Pointer to an gckKERNEL object.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckKERNEL_Recovery(
+ IN gckKERNEL Kernel
+ )
+{
+ gceSTATUS status;
+ gckEVENT eventObj;
+ gckHARDWARE hardware;
+#if gcdSECURE_USER
+ gctUINT32 processID;
+ gcskSECURE_CACHE_PTR cache;
+#endif
+ gctUINT32 mask = 0;
+ gctUINT32 i = 0, count = 0;
+#if gcdINTERRUPT_STATISTIC
+ gctINT32 oldValue;
+#endif
+
+ gcmkHEADER_ARG("Kernel=0x%x", Kernel);
+
+ /* Validate the arguemnts. */
+ gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
+
+ /* Grab gckEVENT object. */
+ eventObj = Kernel->eventObj;
+ gcmkVERIFY_OBJECT(eventObj, gcvOBJ_EVENT);
+
+ /* Grab gckHARDWARE object. */
+ hardware = Kernel->hardware;
+ gcmkVERIFY_OBJECT(hardware, gcvOBJ_HARDWARE);
+
+#if gcdSECURE_USER
+ /* Flush the secure mapping cache. */
+ gcmkONERROR(gckOS_GetProcessID(&processID));
+ gcmkONERROR(gckKERNEL_GetProcessDBCache(Kernel, processID, &cache));
+ gcmkONERROR(gckKERNEL_FlushTranslationCache(Kernel, cache, gcvNULL, 0));
+#endif
+
+ if (Kernel->stuckDump == gcvSTUCK_DUMP_NONE)
+ {
+ gcmkPRINT("[galcore]: GPU[%d] hang, automatic recovery.", Kernel->core);
+ }
+ else
+ {
+ gcmkVERIFY_OK(gckOS_AcquireMutex(Kernel->os, Kernel->device->stuckDumpMutex, gcvINFINITE));
+
+ _DumpDriverConfigure(Kernel);
+ _DumpState(Kernel);
+
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, Kernel->device->stuckDumpMutex));
+ }
+
+ if (Kernel->recovery == gcvFALSE)
+ {
+ gcmkPRINT("[galcore]: Stop driver to keep scene.");
+
+ /* Stop monitor timer. */
+ Kernel->monitorTimerStop = gcvTRUE;
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+ }
+
+ /* Issuing a soft reset for the GPU. */
+ gcmkONERROR(gckHARDWARE_Reset(hardware));
+
+ mask = Kernel->restoreMask;
+
+ for (i = 0; i < 32; i++)
+ {
+ if (mask & (1 << i))
+ {
+ count++;
+ }
+ }
+
+ /* Handle all outstanding events now. */
+ gcmkONERROR(gckOS_AtomSet(Kernel->os, eventObj->pending, mask));
+
+#if gcdINTERRUPT_STATISTIC
+ while (count--)
+ {
+ gcmkONERROR(gckOS_AtomDecrement(
+ Kernel->os,
+ eventObj->interruptCount,
+ &oldValue
+ ));
+ }
+
+ gckOS_AtomClearMask(Kernel->hardware->pendingEvent, mask);
+#endif
+
+ gcmkONERROR(gckEVENT_Notify(eventObj, 1));
+
+ gcmkVERIFY_OK(gckOS_GetTime(&Kernel->resetTimeStamp));
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+/*******************************************************************************
+**
+** gckKERNEL_OpenUserData
+**
+** Get access to the user data.
+**
+** INPUT:
+**
+** gckKERNEL Kernel
+** Pointer to an gckKERNEL object.
+**
+** gctBOOL NeedCopy
+** The flag indicating whether or not the data should be copied.
+**
+** gctPOINTER StaticStorage
+** Pointer to the kernel storage where the data is to be copied if
+** NeedCopy is gcvTRUE.
+**
+** gctPOINTER UserPointer
+** User pointer to the data.
+**
+** gctSIZE_T Size
+** Size of the data.
+**
+** OUTPUT:
+**
+** gctPOINTER * KernelPointer
+** Pointer to the kernel pointer that will be pointing to the data.
+*/
+gceSTATUS
+gckKERNEL_OpenUserData(
+ IN gckKERNEL Kernel,
+ IN gctBOOL NeedCopy,
+ IN gctPOINTER StaticStorage,
+ IN gctPOINTER UserPointer,
+ IN gctSIZE_T Size,
+ OUT gctPOINTER * KernelPointer
+ )
+{
+ gceSTATUS status;
+
+ gcmkHEADER_ARG(
+ "Kernel=0x%08X NeedCopy=%d StaticStorage=0x%08X "
+ "UserPointer=0x%08X Size=%lu KernelPointer=0x%08X",
+ Kernel, NeedCopy, StaticStorage, UserPointer, Size, KernelPointer
+ );
+
+ /* Validate the arguemnts. */
+ gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
+ gcmkVERIFY_ARGUMENT(!NeedCopy || (StaticStorage != gcvNULL));
+ gcmkVERIFY_ARGUMENT(UserPointer != gcvNULL);
+ gcmkVERIFY_ARGUMENT(KernelPointer != gcvNULL);
+ gcmkVERIFY_ARGUMENT(Size > 0);
+
+ if (NeedCopy)
+ {
+ /* Copy the user data to the static storage. */
+ gcmkONERROR(gckOS_CopyFromUserData(
+ Kernel->os, StaticStorage, UserPointer, Size
+ ));
+
+ /* Set the kernel pointer. */
+ * KernelPointer = StaticStorage;
+ }
+ else
+ {
+ gctPOINTER pointer = gcvNULL;
+
+ /* Map the user pointer. */
+ gcmkONERROR(gckOS_MapUserPointer(
+ Kernel->os, UserPointer, Size, &pointer
+ ));
+
+ /* Set the kernel pointer. */
+ * KernelPointer = pointer;
+ }
+
+OnError:
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+/*******************************************************************************
+**
+** gckKERNEL_CloseUserData
+**
+** Release resources associated with the user data connection opened by
+** gckKERNEL_OpenUserData.
+**
+** INPUT:
+**
+** gckKERNEL Kernel
+** Pointer to an gckKERNEL object.
+**
+** gctBOOL NeedCopy
+** The flag indicating whether or not the data should be copied.
+**
+** gctBOOL FlushData
+** If gcvTRUE, the data is written back to the user.
+**
+** gctPOINTER UserPointer
+** User pointer to the data.
+**
+** gctSIZE_T Size
+** Size of the data.
+**
+** OUTPUT:
+**
+** gctPOINTER * KernelPointer
+** Kernel pointer to the data.
+*/
+gceSTATUS
+gckKERNEL_CloseUserData(
+ IN gckKERNEL Kernel,
+ IN gctBOOL NeedCopy,
+ IN gctBOOL FlushData,
+ IN gctPOINTER UserPointer,
+ IN gctSIZE_T Size,
+ OUT gctPOINTER * KernelPointer
+ )
+{
+ gceSTATUS status = gcvSTATUS_OK;
+ gctPOINTER pointer;
+
+ gcmkHEADER_ARG(
+ "Kernel=0x%08X NeedCopy=%d FlushData=%d "
+ "UserPointer=0x%08X Size=%lu KernelPointer=0x%08X",
+ Kernel, NeedCopy, FlushData, UserPointer, Size, KernelPointer
+ );
+
+ /* Validate the arguemnts. */
+ gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
+ gcmkVERIFY_ARGUMENT(UserPointer != gcvNULL);
+ gcmkVERIFY_ARGUMENT(KernelPointer != gcvNULL);
+ gcmkVERIFY_ARGUMENT(Size > 0);
+
+ /* Get a shortcut to the kernel pointer. */
+ pointer = * KernelPointer;
+
+ if (pointer != gcvNULL)
+ {
+ if (NeedCopy)
+ {
+ if (FlushData)
+ {
+ gcmkONERROR(gckOS_CopyToUserData(
+ Kernel->os, * KernelPointer, UserPointer, Size
+ ));
+ }
+ }
+ else
+ {
+ /* Unmap record from kernel memory. */
+ gcmkONERROR(gckOS_UnmapUserPointer(
+ Kernel->os,
+ UserPointer,
+ Size,
+ * KernelPointer
+ ));
+ }
+
+ /* Reset the kernel pointer. */
+ * KernelPointer = gcvNULL;
+ }
+
+OnError:
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+gceSTATUS
+gckKERNEL_AllocateVirtualCommandBuffer(
+ IN gckKERNEL Kernel,
+ IN gctBOOL InUserSpace,
+ IN OUT gctSIZE_T * Bytes,
+ OUT gctPHYS_ADDR * Physical,
+ OUT gctPOINTER * Logical
+ )
+{
+ gceSTATUS status;
+ gckOS os = Kernel->os;
+ gckVIRTUAL_COMMAND_BUFFER_PTR buffer;
+
+ gcmkHEADER_ARG("Os=0x%X InUserSpace=%d *Bytes=%lu",
+ os, InUserSpace, gcmOPT_VALUE(Bytes));
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(os, gcvOBJ_OS);
+ gcmkVERIFY_ARGUMENT(Bytes != gcvNULL);
+ gcmkVERIFY_ARGUMENT(*Bytes > 0);
+ gcmkVERIFY_ARGUMENT(Physical != gcvNULL);
+ gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
+
+ gcmkONERROR(
+ gckOS_Allocate(
+ os,
+ sizeof(gckVIRTUAL_COMMAND_BUFFER),
+ (gctPOINTER)&buffer
+ ));
+
+ gcmkONERROR(gckOS_ZeroMemory(buffer, sizeof(gckVIRTUAL_COMMAND_BUFFER)));
+
+ gcmkONERROR(
+ gckKERNEL_AllocateVirtualMemory(
+ Kernel,
+ gcvFALSE,
+ InUserSpace,
+ Bytes,
+ (gctPHYS_ADDR *)&buffer,
+ Logical
+ ));
+
+ gcmkVERIFY_OK(gckOS_AcquireMutex(os, Kernel->virtualBufferLock, gcvINFINITE));
+
+ if (Kernel->virtualBufferHead == gcvNULL)
+ {
+ Kernel->virtualBufferHead =
+ Kernel->virtualBufferTail = buffer;
+ }
+ else
+ {
+ buffer->prev = Kernel->virtualBufferTail;
+ Kernel->virtualBufferTail->next = buffer;
+ Kernel->virtualBufferTail = buffer;
+ }
+
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(os, Kernel->virtualBufferLock));
+
+ *Physical = buffer;
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ gcmkVERIFY_OK(gckOS_Free(os, buffer));
+
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+gceSTATUS
+gckKERNEL_DestroyVirtualCommandBuffer(
+ IN gckKERNEL Kernel,
+ IN gctSIZE_T Bytes,
+ IN gctPHYS_ADDR Physical,
+ IN gctPOINTER Logical
+ )
+{
+ gckOS os;
+ gckKERNEL kernel;
+ gckVIRTUAL_COMMAND_BUFFER_PTR buffer = (gckVIRTUAL_COMMAND_BUFFER_PTR)Physical;
+
+ gcmkHEADER();
+ gcmkVERIFY_ARGUMENT(buffer != gcvNULL);
+
+ kernel = buffer->virtualBuffer.kernel;
+ os = kernel->os;
+
+ gcmkVERIFY_OK(gckOS_AcquireMutex(os, kernel->virtualBufferLock, gcvINFINITE));
+
+ if (buffer == kernel->virtualBufferHead)
+ {
+ if ((kernel->virtualBufferHead = buffer->next) == gcvNULL)
+ {
+ kernel->virtualBufferTail = gcvNULL;
+ }
+ }
+ else
+ {
+ buffer->prev->next = buffer->next;
+
+ if (buffer == kernel->virtualBufferTail)
+ {
+ kernel->virtualBufferTail = buffer->prev;
+ }
+ else
+ {
+ buffer->next->prev = buffer->prev;
+ }
+ }
+
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(os, kernel->virtualBufferLock));
+
+ gcmkVERIFY_OK(
+ gckKERNEL_FreeVirtualMemory(
+ Physical,
+ Logical,
+ gcvFALSE
+ ));
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+}
+
+gceSTATUS
+gckKERNEL_AllocateVirtualMemory(
+ IN gckKERNEL Kernel,
+ IN gctBOOL NonPaged,
+ IN gctBOOL InUserSpace,
+ IN OUT gctSIZE_T * Bytes,
+ OUT gctPHYS_ADDR * Physical,
+ OUT gctPOINTER * Logical
+ )
+{
+ gckOS os = Kernel->os;
+ gceSTATUS status;
+ gctPOINTER logical = gcvNULL;
+ gctSIZE_T pageCount;
+ gctSIZE_T bytes = *Bytes;
+ gckVIRTUAL_BUFFER_PTR buffer = gcvNULL;
+ gckMMU mmu = gcvNULL;
+ gctUINT32 allocFlag = 0;
+
+ gcmkHEADER_ARG("Os=0x%X InUserSpace=%d *Bytes=%lu",
+ os, InUserSpace, gcmOPT_VALUE(Bytes));
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(os, gcvOBJ_OS);
+ gcmkVERIFY_ARGUMENT(Bytes != gcvNULL);
+ gcmkVERIFY_ARGUMENT(*Bytes > 0);
+ gcmkVERIFY_ARGUMENT(Physical != gcvNULL);
+ gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
+
+ if (*Physical == gcvNULL)
+ {
+ gcmkONERROR(gckOS_Allocate(os,
+ sizeof(gckVIRTUAL_BUFFER),
+ (gctPOINTER)&buffer));
+
+ gcmkONERROR(gckOS_ZeroMemory(buffer, sizeof(gckVIRTUAL_BUFFER)));
+ }
+ else
+ {
+ buffer = *Physical;
+ }
+
+ buffer->bytes = bytes;
+
+#if gcdENABLE_CACHEABLE_COMMAND_BUFFER
+ allocFlag = gcvALLOC_FLAG_CACHEABLE;
+#endif
+
+ if (NonPaged)
+ {
+ gcmkONERROR(gckOS_AllocateNonPagedMemory(
+ os,
+ InUserSpace,
+ allocFlag | gcvALLOC_FLAG_CONTIGUOUS,
+ &bytes,
+ &buffer->physical,
+ &logical
+ ));
+ }
+ else
+ {
+ gcmkONERROR(gckOS_AllocatePagedMemoryEx(
+ os,
+ allocFlag | gcvALLOC_FLAG_NON_CONTIGUOUS,
+ bytes,
+ gcvNULL,
+ &buffer->physical
+ ));
+ }
+
+ if (NonPaged)
+ {
+ gctSIZE_T pageSize;
+ gcmkONERROR(gckOS_GetPageSize(os, &pageSize));
+
+ pageCount = (bytes + pageSize - 1) / pageSize;
+
+ if (InUserSpace)
+ {
+ *Logical =
+ buffer->userLogical = logical;
+ }
+ else
+ {
+ *Logical =
+ buffer->kernelLogical = logical;
+ }
+ }
+ else
+ {
+ if (InUserSpace)
+ {
+ gcmkONERROR(gckOS_CreateUserVirtualMapping(os,
+ buffer->physical,
+ bytes,
+ &logical,
+ &pageCount));
+
+ *Logical =
+ buffer->userLogical = logical;
+ }
+ else
+ {
+ gcmkONERROR(gckOS_CreateKernelVirtualMapping(os,
+ buffer->physical,
+ bytes,
+ &logical,
+ &pageCount));
+
+ *Logical =
+ buffer->kernelLogical = logical;
+ }
+
+ }
+
+ buffer->pageCount = pageCount;
+ buffer->kernel = Kernel;
+
+ gcmkONERROR(gckOS_GetProcessID(&buffer->pid));
+
+#if gcdPROCESS_ADDRESS_SPACE
+ gcmkONERROR(gckKERNEL_GetProcessMMU(Kernel, &mmu));
+ buffer->mmu = mmu;
+#else
+ mmu = Kernel->mmu;
+#endif
+
+ gcmkONERROR(gckMMU_AllocatePages(mmu,
+ pageCount,
+ &buffer->pageTable,
+ &buffer->gpuAddress));
+
+#if gcdENABLE_TRUST_APPLICATION
+ if (Kernel->hardware->options.secureMode == gcvSECURE_IN_TA)
+ {
+ gcmkONERROR(gckKERNEL_MapInTrustApplicaiton(
+ Kernel,
+ logical,
+ buffer->physical,
+ buffer->gpuAddress,
+ pageCount
+ ));
+ }
+ else
+#endif
+ {
+ gcmkONERROR(gckOS_MapPagesEx(os,
+ Kernel->core,
+ buffer->physical,
+ pageCount,
+ buffer->gpuAddress,
+ buffer->pageTable,
+ gcvFALSE,
+ gcvSURF_TYPE_UNKNOWN
+ ));
+ }
+
+ gcmkONERROR(gckMMU_Flush(mmu, gcvSURF_INDEX));
+
+ if (*Physical == gcvNULL)
+ *Physical = buffer;
+
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_KERNEL,
+ "gpuAddress = %x pageCount = %d kernelLogical = %x userLogical=%x",
+ buffer->gpuAddress, buffer->pageCount,
+ buffer->kernelLogical, buffer->userLogical);
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ if (buffer && buffer->gpuAddress)
+ {
+ gcmkVERIFY_OK(
+ gckMMU_FreePages(mmu, gcvFALSE, buffer->gpuAddress, buffer->pageTable, buffer->pageCount));
+ }
+
+ if (NonPaged && buffer->physical)
+ {
+ gcmkVERIFY_OK(gckOS_FreeNonPagedMemory(
+ os,
+ bytes,
+ buffer->physical,
+ logical
+ ));
+ }
+ else
+ {
+ if (buffer && buffer->userLogical)
+ {
+ gcmkVERIFY_OK(
+ gckOS_DestroyUserVirtualMapping(os,
+ buffer->physical,
+ bytes,
+ (NonPaged ? 0 : buffer->userLogical)));
+ }
+
+ if (buffer && buffer->kernelLogical)
+ {
+ gcmkVERIFY_OK(
+ gckOS_DestroyKernelVirtualMapping(os,
+ buffer->physical,
+ bytes,
+ (NonPaged ? 0 : buffer->kernelLogical)));
+ }
+
+ if (buffer && buffer->physical)
+ {
+ gcmkVERIFY_OK(gckOS_FreePagedMemory(os, buffer->physical, bytes));
+ }
+ }
+
+ if (*Physical == gcvNULL)
+ gcmkVERIFY_OK(gckOS_Free(os, buffer));
+
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+
+}
+
+gceSTATUS
+gckKERNEL_FreeVirtualMemory(
+ IN gctPHYS_ADDR Physical,
+ IN gctPOINTER Logical,
+ IN gctBOOL NonPaged
+ )
+{
+ gckOS os;
+ gckKERNEL kernel;
+ gckMMU mmu;
+ gckVIRTUAL_BUFFER_PTR buffer = (gckVIRTUAL_BUFFER_PTR)Physical;
+
+ gcmkHEADER();
+ gcmkVERIFY_ARGUMENT(buffer != gcvNULL);
+
+ kernel = buffer->kernel;
+ os = kernel->os;
+
+#if gcdPROCESS_ADDRESS_SPACE
+ gcmkONERROR(gckKERNEL_GetProcessMMU(Kernel, &mmu));
+#else
+ mmu = kernel->mmu;
+#endif
+
+ if (!buffer->userLogical && !NonPaged)
+ {
+ gcmkVERIFY_OK(gckOS_DestroyKernelVirtualMapping(os,
+ buffer->physical,
+ buffer->bytes,
+ Logical));
+ }
+
+ gcmkVERIFY_OK(
+ gckMMU_FreePages(mmu, gcvFALSE, buffer->gpuAddress, buffer->pageTable, buffer->pageCount));
+
+ gcmkVERIFY_OK(gckOS_UnmapPages(os, buffer->pageCount, buffer->gpuAddress));
+
+ if (NonPaged)
+ {
+ gcmkVERIFY_OK(gckOS_FreeNonPagedMemory(
+ os,
+ buffer->bytes,
+ buffer->physical,
+ Logical
+ ));
+ }
+ else
+ {
+ gcmkVERIFY_OK(gckOS_FreePagedMemory(os, buffer->physical, buffer->bytes));
+ }
+
+ gcmkVERIFY_OK(gckOS_Free(os, buffer));
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+}
+
+gceSTATUS
+gckKERNEL_GetGPUAddress(
+ IN gckKERNEL Kernel,
+ IN gctPOINTER Logical,
+ IN gctBOOL InUserSpace,
+ IN gctPHYS_ADDR Physical,
+ OUT gctUINT32 * Address
+ )
+{
+ gckVIRTUAL_BUFFER_PTR buffer = Physical;
+ gctPOINTER start;
+
+ gcmkHEADER_ARG("Logical = %x InUserSpace=%d.", Logical, InUserSpace);
+
+ if (InUserSpace)
+ {
+ start = buffer->userLogical;
+ }
+ else
+ {
+ start = buffer->kernelLogical;
+ }
+
+ gcmkASSERT(Logical >= start
+ && (Logical < (gctPOINTER)((gctUINT8_PTR)start + buffer->bytes)));
+
+ * Address = buffer->gpuAddress + (gctUINT32)((gctUINT8_PTR)Logical - (gctUINT8_PTR)start);
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+}
+
+gceSTATUS
+gckKERNEL_QueryGPUAddress(
+ IN gckKERNEL Kernel,
+ IN gctUINT32 GpuAddress,
+ OUT gckVIRTUAL_COMMAND_BUFFER_PTR * Buffer
+ )
+{
+ gckVIRTUAL_COMMAND_BUFFER_PTR buffer;
+ gctUINT32 start;
+ gceSTATUS status = gcvSTATUS_NOT_SUPPORTED;
+
+ gcmkVERIFY_OK(gckOS_AcquireMutex(Kernel->os, Kernel->virtualBufferLock, gcvINFINITE));
+
+ /* Walk all command buffers. */
+ for (buffer = Kernel->virtualBufferHead; buffer != gcvNULL; buffer = buffer->next)
+ {
+ start = (gctUINT32)buffer->virtualBuffer.gpuAddress;
+
+ if (GpuAddress >= start && GpuAddress <= (start - 1 + buffer->virtualBuffer.pageCount * 4096))
+ {
+ /* Find a range matched. */
+ *Buffer = buffer;
+ status = gcvSTATUS_OK;
+ break;
+ }
+ }
+
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, Kernel->virtualBufferLock));
+
+ return status;
+}
+
+static void
+gckQUEUE_Dequeue(
+ IN gckQUEUE LinkQueue
+ )
+{
+ gcmkASSERT(LinkQueue->count == LinkQueue->size);
+
+ LinkQueue->count--;
+ LinkQueue->front = (LinkQueue->front + 1) % gcdLINK_QUEUE_SIZE;
+}
+
+void
+gckQUEUE_Enqueue(
+ IN gckQUEUE LinkQueue,
+ IN gcuQUEUEDATA *Data
+ )
+{
+ gcuQUEUEDATA * datas = LinkQueue->datas;
+
+ if (LinkQueue->count == LinkQueue->size)
+ {
+ gckQUEUE_Dequeue(LinkQueue);
+ }
+
+ gcmkASSERT(LinkQueue->count < LinkQueue->size);
+
+ LinkQueue->count++;
+
+ datas[LinkQueue->rear] = *Data;
+
+ LinkQueue->rear = (LinkQueue->rear + 1) % LinkQueue->size;
+}
+
+void
+gckQUEUE_GetData(
+ IN gckQUEUE LinkQueue,
+ IN gctUINT32 Index,
+ OUT gcuQUEUEDATA ** Data
+ )
+{
+ gcuQUEUEDATA * datas = LinkQueue->datas;
+
+ gcmkASSERT(Index >= 0 && Index < LinkQueue->size);
+
+ *Data = &datas[(Index + LinkQueue->front) % LinkQueue->size];
+}
+
+gceSTATUS
+gckQUEUE_Allocate(
+ IN gckOS Os,
+ IN gckQUEUE Queue,
+ IN gctUINT32 Size
+ )
+{
+ gceSTATUS status;
+
+ gcmkONERROR(gckOS_Allocate(
+ Os,
+ gcmSIZEOF(struct _gckLINKDATA) * Size,
+ (gctPOINTER *)&Queue->datas
+ ));
+
+ Queue->size = Size;
+
+ return gcvSTATUS_OK;
+
+OnError:
+ return status;
+}
+
+gceSTATUS
+gckQUEUE_Free(
+ IN gckOS Os,
+ IN gckQUEUE Queue
+ )
+{
+ if (Queue->datas)
+ {
+ gcmkVERIFY_OK(gckOS_Free(Os, (gctPOINTER)Queue->datas));
+ }
+
+ return gcvSTATUS_OK;
+}
+
+/******************************************************************************\
+*************************** Pointer - ID translation ***************************
+\******************************************************************************/
+#define gcdID_TABLE_LENGTH 1024
+typedef struct _gcsINTEGERDB * gckINTEGERDB;
+typedef struct _gcsINTEGERDB
+{
+ gckOS os;
+ gctPOINTER* table;
+ gctPOINTER mutex;
+ gctUINT32 tableLen;
+ gctUINT32 currentID;
+ gctUINT32 unused;
+}
+gcsINTEGERDB;
+
+gceSTATUS
+gckKERNEL_CreateIntegerDatabase(
+ IN gckKERNEL Kernel,
+ OUT gctPOINTER * Database
+ )
+{
+ gceSTATUS status;
+ gckINTEGERDB database = gcvNULL;
+
+ gcmkHEADER_ARG("Kernel=0x%08X Datbase=0x%08X", Kernel, Database);
+
+ gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
+ gcmkVERIFY_ARGUMENT(Database != gcvNULL);
+
+ /* Allocate a database. */
+ gcmkONERROR(gckOS_Allocate(
+ Kernel->os, gcmSIZEOF(gcsINTEGERDB), (gctPOINTER *)&database));
+
+ gcmkONERROR(gckOS_ZeroMemory(database, gcmSIZEOF(gcsINTEGERDB)));
+
+ /* Allocate a pointer table. */
+ gcmkONERROR(gckOS_Allocate(
+ Kernel->os, gcmSIZEOF(gctPOINTER) * gcdID_TABLE_LENGTH, (gctPOINTER *)&database->table));
+
+ gcmkONERROR(gckOS_ZeroMemory(database->table, gcmSIZEOF(gctPOINTER) * gcdID_TABLE_LENGTH));
+
+ /* Allocate a database mutex. */
+ gcmkONERROR(gckOS_CreateMutex(Kernel->os, &database->mutex));
+
+ /* Initialize. */
+ database->currentID = 0;
+ database->unused = gcdID_TABLE_LENGTH;
+ database->os = Kernel->os;
+ database->tableLen = gcdID_TABLE_LENGTH;
+
+ *Database = database;
+
+ gcmkFOOTER_ARG("*Database=0x%08X", *Database);
+ return gcvSTATUS_OK;
+
+OnError:
+ /* Rollback. */
+ if (database)
+ {
+ if (database->table)
+ {
+ gcmkOS_SAFE_FREE(Kernel->os, database->table);
+ }
+
+ gcmkOS_SAFE_FREE(Kernel->os, database);
+ }
+
+ gcmkFOOTER();
+ return status;
+}
+
+gceSTATUS
+gckKERNEL_DestroyIntegerDatabase(
+ IN gckKERNEL Kernel,
+ IN gctPOINTER Database
+ )
+{
+ gckINTEGERDB database = Database;
+
+ gcmkHEADER_ARG("Kernel=0x%08X Datbase=0x%08X", Kernel, Database);
+
+ gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
+ gcmkVERIFY_ARGUMENT(Database != gcvNULL);
+
+ /* Destroy pointer table. */
+ gcmkOS_SAFE_FREE(Kernel->os, database->table);
+
+ /* Destroy database mutex. */
+ gcmkVERIFY_OK(gckOS_DeleteMutex(Kernel->os, database->mutex));
+
+ /* Destroy database. */
+ gcmkOS_SAFE_FREE(Kernel->os, database);
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+}
+
+gceSTATUS
+gckKERNEL_AllocateIntegerId(
+ IN gctPOINTER Database,
+ IN gctPOINTER Pointer,
+ OUT gctUINT32 * Id
+ )
+{
+ gceSTATUS status;
+ gckINTEGERDB database = Database;
+ gctUINT32 i, unused, currentID, tableLen;
+ gctPOINTER * table;
+ gckOS os = database->os;
+ gctBOOL acquired = gcvFALSE;
+
+ gcmkHEADER_ARG("Database=0x%08X Pointer=0x%08X", Database, Pointer);
+
+ gcmkVERIFY_ARGUMENT(Id != gcvNULL);
+
+ gcmkVERIFY_OK(gckOS_AcquireMutex(os, database->mutex, gcvINFINITE));
+ acquired = gcvTRUE;
+
+ if (database->unused < 1)
+ {
+ /* Extend table. */
+ gcmkONERROR(
+ gckOS_Allocate(os,
+ gcmSIZEOF(gctPOINTER) * (database->tableLen + gcdID_TABLE_LENGTH),
+ (gctPOINTER *)&table));
+
+ gcmkONERROR(gckOS_ZeroMemory(table + database->tableLen,
+ gcmSIZEOF(gctPOINTER) * gcdID_TABLE_LENGTH));
+
+ /* Copy data from old table. */
+ gckOS_MemCopy(table,
+ database->table,
+ database->tableLen * gcmSIZEOF(gctPOINTER));
+
+ gcmkOS_SAFE_FREE(os, database->table);
+
+ /* Update databse with new allocated table. */
+ database->table = table;
+ database->currentID = database->tableLen;
+ database->tableLen += gcdID_TABLE_LENGTH;
+ database->unused += gcdID_TABLE_LENGTH;
+ }
+
+ table = database->table;
+ currentID = database->currentID;
+ tableLen = database->tableLen;
+ unused = database->unused;
+
+ /* Connect id with pointer. */
+ table[currentID] = Pointer;
+
+ *Id = currentID + 1;
+
+ /* Update the currentID. */
+ if (--unused > 0)
+ {
+ for (i = 0; i < tableLen; i++)
+ {
+ if (++currentID >= tableLen)
+ {
+ /* Wrap to the begin. */
+ currentID = 0;
+ }
+
+ if (table[currentID] == gcvNULL)
+ {
+ break;
+ }
+ }
+ }
+
+ database->table = table;
+ database->currentID = currentID;
+ database->tableLen = tableLen;
+ database->unused = unused;
+
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(os, database->mutex));
+ acquired = gcvFALSE;
+
+ gcmkFOOTER_ARG("*Id=%d", *Id);
+ return gcvSTATUS_OK;
+
+OnError:
+ if (acquired)
+ {
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(os, database->mutex));
+ }
+
+ gcmkFOOTER();
+ return status;
+}
+
+gceSTATUS
+gckKERNEL_FreeIntegerId(
+ IN gctPOINTER Database,
+ IN gctUINT32 Id
+ )
+{
+ gceSTATUS status;
+ gckINTEGERDB database = Database;
+ gckOS os = database->os;
+ gctBOOL acquired = gcvFALSE;
+
+ gcmkHEADER_ARG("Database=0x%08X Id=%d", Database, Id);
+
+ gcmkVERIFY_OK(gckOS_AcquireMutex(os, database->mutex, gcvINFINITE));
+ acquired = gcvTRUE;
+
+ if (!(Id > 0 && Id <= database->tableLen))
+ {
+ gcmkONERROR(gcvSTATUS_NOT_FOUND);
+ }
+
+ Id -= 1;
+
+ database->table[Id] = gcvNULL;
+
+ if (database->unused++ == 0)
+ {
+ database->currentID = Id;
+ }
+
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(os, database->mutex));
+ acquired = gcvFALSE;
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ if (acquired)
+ {
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(os, database->mutex));
+ }
+
+ gcmkFOOTER();
+ return status;
+}
+
+gceSTATUS
+gckKERNEL_QueryIntegerId(
+ IN gctPOINTER Database,
+ IN gctUINT32 Id,
+ OUT gctPOINTER * Pointer
+ )
+{
+ gceSTATUS status;
+ gckINTEGERDB database = Database;
+ gctPOINTER pointer;
+ gckOS os = database->os;
+ gctBOOL acquired = gcvFALSE;
+
+ gcmkHEADER_ARG("Database=0x%08X Id=%d", Database, Id);
+ gcmkVERIFY_ARGUMENT(Pointer != gcvNULL);
+
+ gcmkVERIFY_OK(gckOS_AcquireMutex(os, database->mutex, gcvINFINITE));
+ acquired = gcvTRUE;
+
+ if (!(Id > 0 && Id <= database->tableLen))
+ {
+ gcmkONERROR(gcvSTATUS_NOT_FOUND);
+ }
+
+ Id -= 1;
+
+ pointer = database->table[Id];
+
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(os, database->mutex));
+ acquired = gcvFALSE;
+
+ if (pointer)
+ {
+ *Pointer = pointer;
+ }
+ else
+ {
+ gcmkONERROR(gcvSTATUS_NOT_FOUND);
+ }
+
+ gcmkFOOTER_ARG("*Pointer=0x%08X", *Pointer);
+ return gcvSTATUS_OK;
+
+OnError:
+ if (acquired)
+ {
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(os, database->mutex));
+ }
+
+ gcmkFOOTER();
+ return status;
+}
+
+
+gctUINT32
+gckKERNEL_AllocateNameFromPointer(
+ IN gckKERNEL Kernel,
+ IN gctPOINTER Pointer
+ )
+{
+ gceSTATUS status;
+ gctUINT32 name;
+ gctPOINTER database = Kernel->db->pointerDatabase;
+
+ gcmkHEADER_ARG("Kernel=0x%X Pointer=0x%X", Kernel, Pointer);
+
+ gcmkONERROR(
+ gckKERNEL_AllocateIntegerId(database, Pointer, &name));
+
+ gcmkFOOTER_ARG("name=%d", name);
+ return name;
+
+OnError:
+ gcmkFOOTER();
+ return 0;
+}
+
+gctPOINTER
+gckKERNEL_QueryPointerFromName(
+ IN gckKERNEL Kernel,
+ IN gctUINT32 Name
+ )
+{
+ gceSTATUS status;
+ gctPOINTER pointer = gcvNULL;
+ gctPOINTER database = Kernel->db->pointerDatabase;
+
+ gcmkHEADER_ARG("Kernel=0x%X Name=%d", Kernel, Name);
+
+ /* Lookup in database to get pointer. */
+ gcmkONERROR(gckKERNEL_QueryIntegerId(database, Name, &pointer));
+
+ gcmkFOOTER_ARG("pointer=0x%X", pointer);
+ return pointer;
+
+OnError:
+ gcmkFOOTER();
+ return gcvNULL;
+}
+
+gceSTATUS
+gckKERNEL_DeleteName(
+ IN gckKERNEL Kernel,
+ IN gctUINT32 Name
+ )
+{
+ gctPOINTER database = Kernel->db->pointerDatabase;
+
+ gcmkHEADER_ARG("Kernel=0x%X Name=0x%X", Kernel, Name);
+
+ /* Free name if exists. */
+ gcmkVERIFY_OK(gckKERNEL_FreeIntegerId(database, Name));
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+}
+
+/*******************************************************************************
+***** Shared Buffer ************************************************************
+*******************************************************************************/
+
+/*******************************************************************************
+**
+** gckKERNEL_CreateShBuffer
+**
+** Create shared buffer.
+** The shared buffer can be used across processes. Other process needs call
+** gckKERNEL_MapShBuffer before use it.
+**
+** INPUT:
+**
+** gckKERNEL Kernel
+** Pointer to an gckKERNEL object.
+**
+** gctUINT32 Size
+** Specify the shared buffer size.
+**
+** OUTPUT:
+**
+** gctSHBUF * ShBuf
+** Pointer to hold return shared buffer handle.
+*/
+gceSTATUS
+gckKERNEL_CreateShBuffer(
+ IN gckKERNEL Kernel,
+ IN gctUINT32 Size,
+ OUT gctSHBUF * ShBuf
+ )
+{
+ gceSTATUS status;
+ gcsSHBUF_PTR shBuf = gcvNULL;
+
+ gcmkHEADER_ARG("Kernel=0x%X, Size=%u", Kernel, Size);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
+
+ if (Size == 0)
+ {
+ /* Invalid size. */
+ gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
+ }
+ else if (Size > 1024)
+ {
+ /* Limite shared buffer size. */
+ gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
+ }
+
+ /* Create a shared buffer structure. */
+ gcmkONERROR(
+ gckOS_Allocate(Kernel->os,
+ sizeof (gcsSHBUF),
+ (gctPOINTER *)&shBuf));
+
+ /* Initialize shared buffer. */
+ shBuf->id = 0;
+ shBuf->reference = gcvNULL;
+ shBuf->size = Size;
+ shBuf->data = gcvNULL;
+
+ /* Allocate integer id for this shared buffer. */
+ gcmkONERROR(
+ gckKERNEL_AllocateIntegerId(Kernel->db->pointerDatabase,
+ shBuf,
+ &shBuf->id));
+
+ /* Allocate atom. */
+ gcmkONERROR(gckOS_AtomConstruct(Kernel->os, &shBuf->reference));
+
+ /* Set default reference count to 1. */
+ gcmkVERIFY_OK(gckOS_AtomSet(Kernel->os, shBuf->reference, 1));
+
+ /* Return integer id. */
+ *ShBuf = (gctSHBUF)(gctUINTPTR_T)shBuf->id;
+
+ gcmkFOOTER_ARG("*ShBuf=%u", shBuf->id);
+ return gcvSTATUS_OK;
+
+OnError:
+ /* Error roll back. */
+ if (shBuf != gcvNULL)
+ {
+ if (shBuf->id != 0)
+ {
+ gcmkVERIFY_OK(
+ gckKERNEL_FreeIntegerId(Kernel->db->pointerDatabase,
+ shBuf->id));
+ }
+
+ gcmkOS_SAFE_FREE(Kernel->os, shBuf);
+ }
+
+ gcmkFOOTER();
+ return status;
+}
+
+/*******************************************************************************
+**
+** gckKERNEL_DestroyShBuffer
+**
+** Destroy shared buffer.
+** This will decrease reference of specified shared buffer and do actual
+** destroy when no reference on it.
+**
+** INPUT:
+**
+** gckKERNEL Kernel
+** Pointer to an gckKERNEL object.
+**
+** gctSHBUF ShBuf
+** Specify the shared buffer to be destroyed.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckKERNEL_DestroyShBuffer(
+ IN gckKERNEL Kernel,
+ IN gctSHBUF ShBuf
+ )
+{
+ gceSTATUS status;
+ gcsSHBUF_PTR shBuf;
+ gctINT32 oldValue = 0;
+ gctBOOL acquired = gcvFALSE;
+
+ gcmkHEADER_ARG("Kernel=0x%X ShBuf=%u",
+ Kernel, (gctUINT32)(gctUINTPTR_T) ShBuf);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
+ gcmkVERIFY_ARGUMENT(ShBuf != gcvNULL);
+
+ /* Acquire mutex. */
+ gcmkONERROR(
+ gckOS_AcquireMutex(Kernel->os,
+ Kernel->db->pointerDatabaseMutex,
+ gcvINFINITE));
+ acquired = gcvTRUE;
+
+ /* Find shared buffer structure. */
+ gcmkONERROR(
+ gckKERNEL_QueryIntegerId(Kernel->db->pointerDatabase,
+ (gctUINT32)(gctUINTPTR_T)ShBuf,
+ (gctPOINTER)&shBuf));
+
+ gcmkASSERT(shBuf->id == (gctUINT32)(gctUINTPTR_T)ShBuf);
+
+ /* Decrease the reference count. */
+ gckOS_AtomDecrement(Kernel->os, shBuf->reference, &oldValue);
+
+ if (oldValue == 1)
+ {
+ /* Free integer id. */
+ gcmkVERIFY_OK(
+ gckKERNEL_FreeIntegerId(Kernel->db->pointerDatabase,
+ shBuf->id));
+
+ /* Free atom. */
+ gcmkVERIFY_OK(gckOS_AtomDestroy(Kernel->os, shBuf->reference));
+
+ if (shBuf->data)
+ {
+ gcmkOS_SAFE_FREE(Kernel->os, shBuf->data);
+ shBuf->data = gcvNULL;
+ }
+
+ /* Free the shared buffer. */
+ gcmkOS_SAFE_FREE(Kernel->os, shBuf);
+ }
+
+ /* Release the mutex. */
+ gcmkVERIFY_OK(
+ gckOS_ReleaseMutex(Kernel->os, Kernel->db->pointerDatabaseMutex));
+ acquired = gcvFALSE;
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ if (acquired)
+ {
+ /* Release the mutex. */
+ gcmkVERIFY_OK(
+ gckOS_ReleaseMutex(Kernel->os, Kernel->db->pointerDatabaseMutex));
+ }
+
+ gcmkFOOTER();
+ return status;
+}
+
+/*******************************************************************************
+**
+** gckKERNEL_MapShBuffer
+**
+** Map shared buffer into this process so that it can be used in this process.
+** This will increase reference count on the specified shared buffer.
+** Call gckKERNEL_DestroyShBuffer to dereference.
+**
+** INPUT:
+**
+** gckKERNEL Kernel
+** Pointer to an gckKERNEL object.
+**
+** gctSHBUF ShBuf
+** Specify the shared buffer to be mapped.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckKERNEL_MapShBuffer(
+ IN gckKERNEL Kernel,
+ IN gctSHBUF ShBuf
+ )
+{
+ gceSTATUS status;
+ gcsSHBUF_PTR shBuf;
+ gctINT32 oldValue = 0;
+ gctBOOL acquired = gcvFALSE;
+
+ gcmkHEADER_ARG("Kernel=0x%X ShBuf=%u",
+ Kernel, (gctUINT32)(gctUINTPTR_T) ShBuf);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
+ gcmkVERIFY_ARGUMENT(ShBuf != gcvNULL);
+
+ /* Acquire mutex. */
+ gcmkONERROR(
+ gckOS_AcquireMutex(Kernel->os,
+ Kernel->db->pointerDatabaseMutex,
+ gcvINFINITE));
+ acquired = gcvTRUE;
+
+ /* Find shared buffer structure. */
+ gcmkONERROR(
+ gckKERNEL_QueryIntegerId(Kernel->db->pointerDatabase,
+ (gctUINT32)(gctUINTPTR_T)ShBuf,
+ (gctPOINTER)&shBuf));
+
+ gcmkASSERT(shBuf->id == (gctUINT32)(gctUINTPTR_T)ShBuf);
+
+ /* Increase the reference count. */
+ gckOS_AtomIncrement(Kernel->os, shBuf->reference, &oldValue);
+
+ /* Release the mutex. */
+ gcmkVERIFY_OK(
+ gckOS_ReleaseMutex(Kernel->os, Kernel->db->pointerDatabaseMutex));
+ acquired = gcvFALSE;
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ if (acquired)
+ {
+ /* Release the mutex. */
+ gcmkVERIFY_OK(
+ gckOS_ReleaseMutex(Kernel->os, Kernel->db->pointerDatabaseMutex));
+ }
+
+ gcmkFOOTER();
+ return status;
+}
+
+/*******************************************************************************
+**
+** gckKERNEL_WriteShBuffer
+**
+** Write user data into shared buffer.
+**
+** INPUT:
+**
+** gckKERNEL Kernel
+** Pointer to an gckKERNEL object.
+**
+** gctSHBUF ShBuf
+** Specify the shared buffer to be written to.
+**
+** gctPOINTER UserData
+** User mode pointer to hold the source data.
+**
+** gctUINT32 ByteCount
+** Specify number of bytes to write. If this is larger than
+** shared buffer size, gcvSTATUS_INVALID_ARGUMENT is returned.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckKERNEL_WriteShBuffer(
+ IN gckKERNEL Kernel,
+ IN gctSHBUF ShBuf,
+ IN gctPOINTER UserData,
+ IN gctUINT32 ByteCount
+ )
+{
+ gceSTATUS status;
+ gcsSHBUF_PTR shBuf = gcvNULL;
+ gctBOOL acquired = gcvFALSE;
+
+ gcmkHEADER_ARG("Kernel=0x%X ShBuf=%u UserData=0x%X ByteCount=%u",
+ Kernel, (gctUINT32)(gctUINTPTR_T) ShBuf, UserData, ByteCount);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
+ gcmkVERIFY_ARGUMENT(ShBuf != gcvNULL);
+
+ /* Acquire mutex. */
+ gcmkONERROR(
+ gckOS_AcquireMutex(Kernel->os,
+ Kernel->db->pointerDatabaseMutex,
+ gcvINFINITE));
+ acquired = gcvTRUE;
+
+ /* Find shared buffer structure. */
+ gcmkONERROR(
+ gckKERNEL_QueryIntegerId(Kernel->db->pointerDatabase,
+ (gctUINT32)(gctUINTPTR_T)ShBuf,
+ (gctPOINTER)&shBuf));
+
+ gcmkASSERT(shBuf->id == (gctUINT32)(gctUINTPTR_T)ShBuf);
+
+ if ((ByteCount > shBuf->size) ||
+ (ByteCount == 0) ||
+ (UserData == gcvNULL))
+ {
+ /* Exceeds buffer max size or invalid. */
+ gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
+ }
+
+ if (shBuf->data == gcvNULL)
+ {
+ /* Allocate buffer data when first time write. */
+ gcmkONERROR(gckOS_Allocate(Kernel->os, ByteCount, &shBuf->data));
+ }
+
+ /* Copy data from user. */
+ gcmkONERROR(
+ gckOS_CopyFromUserData(Kernel->os,
+ shBuf->data,
+ UserData,
+ ByteCount));
+
+ /* Release the mutex. */
+ gcmkVERIFY_OK(
+ gckOS_ReleaseMutex(Kernel->os, Kernel->db->pointerDatabaseMutex));
+ acquired = gcvFALSE;
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ if (shBuf && shBuf->data)
+ {
+ gcmkOS_SAFE_FREE(Kernel->os, shBuf->data);
+ shBuf->data = gcvNULL;
+ }
+
+ if (acquired)
+ {
+ /* Release the mutex. */
+ gcmkVERIFY_OK(
+ gckOS_ReleaseMutex(Kernel->os, Kernel->db->pointerDatabaseMutex));
+ }
+
+ gcmkFOOTER();
+ return status;
+}
+
+/*******************************************************************************
+**
+** gckKERNEL_ReadShBuffer
+**
+** Read data from shared buffer and copy to user pointer.
+**
+** INPUT:
+**
+** gckKERNEL Kernel
+** Pointer to an gckKERNEL object.
+**
+** gctSHBUF ShBuf
+** Specify the shared buffer to be read from.
+**
+** gctPOINTER UserData
+** User mode pointer to save output data.
+**
+** gctUINT32 ByteCount
+** Specify number of bytes to read.
+** If this is larger than shared buffer size, only avaiable bytes are
+** copied. If smaller, copy requested size.
+**
+** OUTPUT:
+**
+** gctUINT32 * BytesRead
+** Pointer to hold how many bytes actually read from shared buffer.
+*/
+gceSTATUS
+gckKERNEL_ReadShBuffer(
+ IN gckKERNEL Kernel,
+ IN gctSHBUF ShBuf,
+ IN gctPOINTER UserData,
+ IN gctUINT32 ByteCount,
+ OUT gctUINT32 * BytesRead
+ )
+{
+ gceSTATUS status;
+ gcsSHBUF_PTR shBuf;
+ gctUINT32 bytes;
+ gctBOOL acquired = gcvFALSE;
+
+ gcmkHEADER_ARG("Kernel=0x%X ShBuf=%u UserData=0x%X ByteCount=%u",
+ Kernel, (gctUINT32)(gctUINTPTR_T) ShBuf, UserData, ByteCount);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
+ gcmkVERIFY_ARGUMENT(ShBuf != gcvNULL);
+
+ /* Acquire mutex. */
+ gcmkONERROR(
+ gckOS_AcquireMutex(Kernel->os,
+ Kernel->db->pointerDatabaseMutex,
+ gcvINFINITE));
+ acquired = gcvTRUE;
+
+ /* Find shared buffer structure. */
+ gcmkONERROR(
+ gckKERNEL_QueryIntegerId(Kernel->db->pointerDatabase,
+ (gctUINT32)(gctUINTPTR_T)ShBuf,
+ (gctPOINTER)&shBuf));
+
+ gcmkASSERT(shBuf->id == (gctUINT32)(gctUINTPTR_T)ShBuf);
+
+ if (shBuf->data == gcvNULL)
+ {
+ *BytesRead = 0;
+
+ /* No data in shared buffer, skip copy. */
+ status = gcvSTATUS_SKIP;
+ goto OnError;
+ }
+ else if (ByteCount == 0)
+ {
+ /* Invalid size to read. */
+ gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
+ }
+
+ /* Determine bytes to copy. */
+ bytes = (ByteCount < shBuf->size) ? ByteCount : shBuf->size;
+
+ /* Copy data to user. */
+ gcmkONERROR(
+ gckOS_CopyToUserData(Kernel->os,
+ shBuf->data,
+ UserData,
+ bytes));
+
+ /* Return copied size. */
+ *BytesRead = bytes;
+
+ /* Release the mutex. */
+ gcmkVERIFY_OK(
+ gckOS_ReleaseMutex(Kernel->os, Kernel->db->pointerDatabaseMutex));
+ acquired = gcvFALSE;
+
+ gcmkFOOTER_ARG("*BytesRead=%u", bytes);
+ return gcvSTATUS_OK;
+
+OnError:
+ if (acquired)
+ {
+ /* Release the mutex. */
+ gcmkVERIFY_OK(
+ gckOS_ReleaseMutex(Kernel->os, Kernel->db->pointerDatabaseMutex));
+ }
+
+ gcmkFOOTER();
+ return status;
+}
+
+/*******************************************************************************\
+*************************** List Helper *****************************************
+\*******************************************************************************/
+
+static void
+_ListAdd(
+ gcsLISTHEAD_PTR New,
+ gcsLISTHEAD_PTR Prev,
+ gcsLISTHEAD_PTR Next
+ )
+{
+ Next->prev = New;
+ New->next = Next;
+ New->prev = Prev;
+ Prev->next = New;
+}
+
+void
+_ListDel(
+ gcsLISTHEAD_PTR Prev,
+ gcsLISTHEAD_PTR Next
+ )
+{
+ Next->prev = Prev;
+ Prev->next = Next;
+}
+
+void
+gcsLIST_Init(
+ gcsLISTHEAD_PTR Node
+ )
+{
+ Node->prev = Node;
+ Node->next = Node;
+}
+
+void
+gcsLIST_Add(
+ gcsLISTHEAD_PTR New,
+ gcsLISTHEAD_PTR Head
+ )
+{
+ _ListAdd(New, Head, Head->next);
+}
+
+void
+gcsLIST_AddTail(
+ gcsLISTHEAD_PTR New,
+ gcsLISTHEAD_PTR Head
+ )
+{
+ _ListAdd(New, Head->prev, Head);
+}
+
+void
+gcsLIST_Del(
+ gcsLISTHEAD_PTR Node
+ )
+{
+ _ListDel(Node->prev, Node->next);
+}
+
+gctBOOL
+gcsLIST_Empty(
+ gcsLISTHEAD_PTR Head
+ )
+{
+ return Head->next == Head;
+}
+
+/*******************************************************************************\
+********************************* Fence *****************************************
+\*******************************************************************************/
+
+gceSTATUS
+gckFENCE_Create(
+ IN gckOS Os,
+ IN gckKERNEL Kernel,
+ OUT gckFENCE * Fence
+ )
+{
+ gceSTATUS status;
+ gckFENCE fence = gcvNULL;
+ gctSIZE_T pageSize = 4096;
+
+ gcmkONERROR(gckOS_Allocate(Os, gcmSIZEOF(gcsFENCE), (gctPOINTER *)&fence));
+ gcmkONERROR(gckOS_ZeroMemory(fence, gcmSIZEOF(gcsFENCE)));
+ gcmkONERROR(gckOS_CreateMutex(Os, (gctPOINTER *)&fence->mutex));
+
+ fence->kernel = Kernel;
+
+#if USE_KERNEL_VIRTUAL_BUFFERS
+ if (Kernel->virtualCommandBuffer)
+ {
+ gcmkONERROR(gckKERNEL_AllocateVirtualMemory(
+ Kernel,
+ gcvFALSE,
+ gcvFALSE,
+ &pageSize,
+ &fence->physical,
+ &fence->logical
+ ));
+
+ gcmkONERROR(gckKERNEL_GetGPUAddress(
+ Kernel,
+ fence->logical,
+ gcvFALSE,
+ fence->physical,
+ &fence->address
+ ));
+ }
+ else
+#endif
+ {
+ gctUINT32 allocFlag = gcvALLOC_FLAG_CONTIGUOUS;
+
+#if gcdENABLE_CACHEABLE_COMMAND_BUFFER
+ allocFlag |= gcvALLOC_FLAG_CACHEABLE;
+#endif
+
+ gcmkONERROR(gckOS_AllocateNonPagedMemory(
+ Os,
+ gcvFALSE,
+ allocFlag,
+ &pageSize,
+ &fence->physical,
+ &fence->logical
+ ));
+
+ gcmkONERROR(gckHARDWARE_ConvertLogical(
+ Kernel->hardware,
+ fence->logical,
+ gcvFALSE,
+ &fence->address
+ ));
+
+ gcmkONERROR(gckMMU_FillFlatMapping(
+ Kernel->mmu, fence->address, pageSize
+ ));
+ }
+
+ gcsLIST_Init(&fence->waitingList);
+
+ *Fence = fence;
+
+ return gcvSTATUS_OK;
+OnError:
+ if (fence)
+ {
+ gckFENCE_Destory(Os, fence);
+ }
+
+ return status;
+}
+
+gceSTATUS
+gckFENCE_Destory(
+ IN gckOS Os,
+ OUT gckFENCE Fence
+ )
+{
+ if (Fence->mutex)
+ {
+ gcmkVERIFY_OK(gckOS_DeleteMutex(Os, Fence->mutex));
+ }
+
+ if (Fence->logical)
+ {
+#if USE_KERNEL_VIRTUAL_BUFFERS
+ if (Fence->kernel->virtualCommandBuffer)
+ {
+ gcmkVERIFY_OK(gckKERNEL_FreeVirtualMemory(
+ Fence->physical,
+ Fence->logical,
+ gcvFALSE
+ ));
+ }
+ else
+#endif
+ {
+ gcmkVERIFY_OK(gckOS_FreeNonPagedMemory(
+ Os,
+ 4096,
+ Fence->physical,
+ Fence->logical
+ ));
+ }
+ }
+
+ gcmkOS_SAFE_FREE(Os, Fence);
+
+ return gcvSTATUS_OK;
+}
+
+/*******************************************************************************
+**
+** gckFENCE_Signal
+**
+** Signal all completed nodes.
+**
+**
+*/
+gceSTATUS
+gckFENCE_Signal(
+ IN gckOS Os,
+ IN gckFENCE Fence
+ )
+{
+ gcsLISTHEAD_PTR list = &Fence->waitingList;
+ gcsLISTHEAD_PTR nodeHead, nodeTemp;
+ gckFENCE_SYNC sync;
+ gckOS os = Os;
+ gctUINT64 stamp = *(gctUINT64 *)Fence->logical;
+
+ gcmkVERIFY_OK(gckOS_AcquireMutex(os, Fence->mutex, gcvINFINITE));
+
+ gcmkLIST_FOR_EACH_SAFE(nodeHead, nodeTemp, list)
+ {
+ sync = gcmCONTAINEROF(nodeHead, _gcsFENCE_SYNC, head);
+
+ /* Signal all nodes which are complete. */
+ if (sync->commitStamp <= stamp && sync->inList)
+ {
+ /* Signal. */
+ gckOS_Signal(os, sync->signal, gcvTRUE);
+
+ /* Remove from wait list. */
+ gcsLIST_Del(nodeHead);
+
+ /* Mark node not in waiting list. */
+ sync->inList = gcvFALSE;
+ }
+ }
+
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(os, Fence->mutex));
+
+ return gcvSTATUS_OK;
+}
+
+gceSTATUS
+gckDEVICE_Construct(
+ IN gckOS Os,
+ OUT gckDEVICE * Device
+ )
+{
+ gceSTATUS status;
+ gckDEVICE device;
+ gctUINT i;
+
+ gcmkHEADER();
+
+ gcmkONERROR(gckOS_Allocate(Os, gcmSIZEOF(gcsDEVICE), (gctPOINTER *)&device));
+
+ for (i = 0; i < gcvCORE_COUNT; i++)
+ {
+ device->coreInfoArray[i].type = gcvHARDWARE_INVALID;
+ }
+ device->defaultHwType = gcvHARDWARE_INVALID;
+
+ gckOS_ZeroMemory(device, gcmSIZEOF(gcsDEVICE));
+
+ gcmkONERROR(gckOS_CreateMutex(Os, &device->stuckDumpMutex));
+ gcmkONERROR(gckOS_CreateMutex(Os, &device->commitMutex));
+
+ device->os = Os;
+
+ *Device = device;
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+
+ if (device != gcvNULL)
+ {
+ gckDEVICE_Destroy(Os, device);
+ }
+
+ gcmkFOOTER();
+ return status;
+}
+
+gceSTATUS
+gckDEVICE_AddCore(
+ IN gckDEVICE Device,
+ IN gceCORE Core,
+ IN gctUINT ChipID,
+ IN gctPOINTER Context,
+ IN gckKERNEL * Kernel
+ )
+{
+ gceSTATUS status;
+ gcsCORE_INFO * info = Device->coreInfoArray;
+ gceHARDWARE_TYPE type = (gceHARDWARE_TYPE)((gctUINT)gcvHARDWARE_INVALID);
+ gctUINT32 index = Device->coreNum;
+ gctUINT32 i;
+ gcsCORE_LIST *coreList;
+ gceHARDWARE_TYPE kernelType;
+ gceHARDWARE_TYPE defaultHwType;
+ gckKERNEL kernel;
+
+ gcmkASSERT(Device->coreNum < gcvCORE_COUNT);
+
+ if (Core >= gcvCORE_MAJOR && Core <= gcvCORE_3D_MAX)
+ {
+ /* Chip ID is only used for 3D cores. */
+ if (ChipID == gcvCHIP_ID_DEFAULT)
+ {
+ /* Apply default chipID if it is not set. */
+ ChipID = Core;
+ }
+ }
+
+ /* Construct gckKERNEL for this core. */
+ gcmkONERROR(gckKERNEL_Construct(
+ Device->os, Core, ChipID, Context, Device, Device->database, Kernel));
+
+ kernel = *Kernel;
+
+ if (Device->database == gcvNULL)
+ {
+ Device->database = kernel->db;
+ }
+
+ kernelType = _GetHardwareType(kernel);
+
+ if (kernelType >= gcvHARDWARE_NUM_TYPES)
+ {
+ gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
+ }
+
+ info[index].type = kernelType;
+ info[index].core = Core;
+ info[index].kernel = kernel;
+ info[index].chipID = ChipID;
+
+ if (index == 0)
+ {
+ /* First core, map all type/core to it. */
+ for (; type != gcvHARDWARE_NUM_TYPES; type = (gceHARDWARE_TYPE)((gctUINT)type + 1))
+ {
+ Device->map[type].num = 0;
+
+ for (i = 0 ; i < 4; i++)
+ {
+ Device->map[type].kernels[i] = kernel;
+ }
+ }
+ }
+
+ /* Get core list of this type. */
+ coreList = &Device->map[kernelType];
+
+ /* Setup gceHARDWARE_TYPE to gceCORE mapping. */
+ coreList->kernels[coreList->num++] = kernel;
+
+ defaultHwType = kernelType;
+ if (kernelType == gcvHARDWARE_3D2D)
+ {
+ coreList = &Device->map[gcvHARDWARE_3D];
+ coreList->kernels[coreList->num++] = kernel;
+ defaultHwType = gcvHARDWARE_3D;
+ }
+
+ /* Advance total core number. */
+ Device->coreNum++;
+
+ /* Default HW type was chosen: 3D > 2D > VG */
+ if (Device->defaultHwType == gcvHARDWARE_INVALID)
+ {
+ Device->defaultHwType = defaultHwType;
+ }
+ else if (Device->defaultHwType > defaultHwType)
+ {
+ Device->defaultHwType = defaultHwType;
+ }
+
+ return gcvSTATUS_OK;
+
+OnError:
+ return status;
+}
+
+gceSTATUS
+gckDEVICE_ChipInfo(
+ IN gckDEVICE Device,
+ IN gcsHAL_INTERFACE_PTR Interface
+ )
+{
+ gctUINT i;
+ gcsCORE_INFO * info = Device->coreInfoArray;
+
+ for (i = 0; i < Device->coreNum; i++)
+ {
+ Interface->u.ChipInfo.types[i] = info[i].type;
+ Interface->u.ChipInfo.ids[i] = info[i].chipID;
+ }
+
+ Interface->u.ChipInfo.count = Device->coreNum;
+
+ return gcvSTATUS_OK;
+}
+
+gceSTATUS
+gckDEVICE_Version(
+ IN gckDEVICE Device,
+ IN gcsHAL_INTERFACE_PTR Interface
+ )
+{
+ Interface->u.Version.major = gcvVERSION_MAJOR;
+ Interface->u.Version.minor = gcvVERSION_MINOR;
+ Interface->u.Version.patch = gcvVERSION_PATCH;
+ Interface->u.Version.build = gcvVERSION_BUILD;
+#if gcmIS_DEBUG(gcdDEBUG_TRACE)
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_KERNEL,
+ "KERNEL version %d.%d.%d build %u",
+ gcvVERSION_MAJOR, gcvVERSION_MINOR,
+ gcvVERSION_PATCH, gcvVERSION_BUILD);
+#endif
+
+ return gcvSTATUS_OK;
+}
+
+gceSTATUS
+gckDEVICE_Destroy(
+ IN gckOS Os,
+ IN gckDEVICE Device
+ )
+{
+ gctINT i;
+ gcsCORE_INFO * info = Device->coreInfoArray;
+
+ for (i = Device->coreNum - 1; i >= 0 ; i--)
+ {
+ if (info[i].kernel != gcvNULL)
+ {
+ gckKERNEL_Destroy(info[i].kernel);
+ }
+ }
+
+ if (Device->commitMutex)
+ {
+ gcmkVERIFY_OK(gckOS_DeleteMutex(Os, Device->commitMutex));
+ }
+ if (Device->stuckDumpMutex)
+ {
+ gcmkVERIFY_OK(gckOS_DeleteMutex(Os, Device->stuckDumpMutex));
+ }
+
+ gcmkOS_SAFE_FREE(Os, Device);
+
+ return gcvSTATUS_OK;
+}
+
+static gceSTATUS
+gckDEVICE_SetTimeOut(
+ IN gckDEVICE Device,
+ IN gcsHAL_INTERFACE_PTR Interface
+ )
+{
+#if gcdGPU_TIMEOUT
+ gckKERNEL kernel;
+ gctUINT i;
+ gceHARDWARE_TYPE type = Interface->hardwareType;
+ gcsCORE_LIST *coreList;
+
+ coreList = &Device->map[type];
+
+ for (i = 0; i < coreList->num; i++)
+ {
+ kernel = coreList->kernels[i];
+
+ kernel->timeOut = Interface->u.SetTimeOut.timeOut;
+ }
+#endif
+
+ return gcvSTATUS_OK;
+}
+
+
+gceSTATUS
+gckDEVICE_Dispatch(
+ IN gckDEVICE Device,
+ IN gcsHAL_INTERFACE_PTR Interface
+ )
+{
+ gceSTATUS status = gcvSTATUS_NOT_SUPPORTED;
+ gckKERNEL kernel;
+ gceHARDWARE_TYPE type = Interface->hardwareType;
+ gctUINT32 coreIndex = Interface->coreIndex;
+
+ switch (Interface->command)
+ {
+ case gcvHAL_CHIP_INFO:
+ status = gckDEVICE_ChipInfo(Device, Interface);
+ break;
+
+ case gcvHAL_VERSION:
+ status = gckDEVICE_Version(Device, Interface);
+ break;
+
+ case gcvHAL_SET_TIMEOUT:
+ status = gckDEVICE_SetTimeOut(Device, Interface);
+ break;
+
+ default:
+ status = gcvSTATUS_NOT_SUPPORTED;
+ break;
+ }
+
+ if (gcmIS_SUCCESS(status))
+ {
+ /* Dispatch handled in this layer. */
+ Interface->status = status;
+ }
+ else
+ {
+ /* Need go through gckKERNEL dispatch. */
+ kernel = Device->map[type].kernels[coreIndex];
+
+
+#if gcdENABLE_VG
+ if (kernel->vg)
+ {
+ status = gckVGKERNEL_Dispatch(kernel, gcvTRUE, Interface);
+ }
+ else
+#endif
+ {
+ status = gckKERNEL_Dispatch(kernel, Device, gcvTRUE, Interface);
+ }
+
+ /* Interface->status is handled in gckKERNEL_Dispatch(). */
+ }
+
+ return status;
+}
+
+gceSTATUS
+gckDEVICE_GetMMU(
+ IN gckDEVICE Device,
+ IN gceHARDWARE_TYPE Type,
+ IN gckMMU *Mmu
+ )
+{
+ gcmkHEADER();
+ gcmkVERIFY_ARGUMENT(Type < gcvHARDWARE_NUM_TYPES);
+
+ *Mmu = Device->mmus[Type];
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+}
+
+gceSTATUS
+gckDEVICE_SetMMU(
+ IN gckDEVICE Device,
+ IN gceHARDWARE_TYPE Type,
+ IN gckMMU Mmu
+ )
+{
+ gcmkHEADER();
+ gcmkVERIFY_ARGUMENT(Type < gcvHARDWARE_NUM_TYPES);
+
+ Device->mmus[Type] = Mmu;
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+}
+
+/*******************************************************************************
+**
+** gckDEVICE_QueryGPUAddress
+**
+** Search GPUAddress in other core's address space, whose type is same as current
+** core. It is used to find correct command buffer which is shared by mulitple
+** core.
+**
+*/
+gceSTATUS
+gckDEVICE_QueryGPUAddress(
+ IN gckDEVICE Device,
+ IN gckKERNEL Kernel,
+ IN gctUINT32 GPUAddress,
+ OUT gckVIRTUAL_COMMAND_BUFFER_PTR * Buffer
+ )
+{
+ gceSTATUS status = gcvSTATUS_NOT_FOUND;
+ gctUINT i;
+ gceHARDWARE_TYPE kernelType;
+
+ kernelType = _GetHardwareType(Kernel);
+
+ if (Device != gcvNULL)
+ {
+ for (i = 0; i < Device->coreNum; i++)
+ {
+ if (Device->coreInfoArray[i].type == kernelType)
+ {
+ /* Search other core's command buffer list whose type is same. */
+ status = gckKERNEL_QueryGPUAddress(
+ Device->coreInfoArray[i].kernel, GPUAddress, Buffer);
+
+ if (gcmIS_SUCCESS(status))
+ {
+ break;
+ }
+ }
+ }
+ }
+ else
+ {
+ status = gckKERNEL_QueryGPUAddress(Kernel, GPUAddress, Buffer);
+ }
+
+ return status;
+}
+
+#if gcdENABLE_TRUST_APPLICATION
+gceSTATUS
+gckKERNEL_MapInTrustApplicaiton(
+ IN gckKERNEL Kernel,
+ IN gctPOINTER Logical,
+ IN gctPHYS_ADDR Physical,
+ IN gctUINT32 GPUAddress,
+ IN gctSIZE_T PageCount
+ )
+{
+ gceSTATUS status;
+ gctUINT32 * physicalArrayLogical = gcvNULL;
+ gctSIZE_T bytes;
+ gctPOINTER logical = Logical;
+ gctUINT32 i;
+ gctSIZE_T pageSize;
+ gctUINT32 pageMask;
+
+ gcmkHEADER();
+
+ gcmkVERIFY_OK(gckOS_GetPageSize(Kernel->os, &pageSize));
+
+ pageMask = (gctUINT32)pageSize - 1;
+
+ bytes = PageCount * gcmSIZEOF(gctUINT32);
+
+ gcmkONERROR(gckOS_Allocate(
+ Kernel->os,
+ bytes,
+ (gctPOINTER *)&physicalArrayLogical
+ ));
+
+ /* Fill in physical array. */
+ for (i = 0; i < PageCount; i++)
+ {
+ gctPHYS_ADDR_T phys;
+ status = gckOS_PhysicalToPhysicalAddress(
+ Kernel->os,
+ Physical,
+ i * 4096,
+ &phys
+ );
+
+ if (status == gcvSTATUS_NOT_SUPPORTED)
+ {
+ gcmkONERROR(gckOS_GetPhysicalAddress(
+ Kernel->os,
+ logical,
+ &phys
+ ));
+
+ gcmkVERIFY_OK(gckOS_CPUPhysicalToGPUPhysical(Kernel->os, phys, &phys));
+ }
+
+ phys &= ~pageMask;
+
+ gcmkSAFECASTPHYSADDRT(physicalArrayLogical[i], phys);
+
+ logical = (gctUINT8_PTR)logical + 4096;
+ }
+
+ gcmkONERROR(gckKERNEL_SecurityMapMemory(
+ Kernel,
+ physicalArrayLogical,
+ 0,
+ (gctUINT32)PageCount,
+ &GPUAddress
+ ));
+
+ gcmkVERIFY_OK(gckOS_Free(
+ Kernel->os,
+ physicalArrayLogical
+ ))
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ if(physicalArrayLogical != gcvNULL)
+ gcmkVERIFY_OK(gckOS_Free(
+ Kernel->os,
+ (gctPOINTER)physicalArrayLogical
+ ));
+ gcmkFOOTER();
+ return status;
+}
+#endif
+
+/*******************************************************************************
+***** Test Code ****************************************************************
+*******************************************************************************/
+
diff --git a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.h b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.h
new file mode 100644
index 000000000000..1aad1ef9f781
--- /dev/null
+++ b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.h
@@ -0,0 +1,2113 @@
+/****************************************************************************
+*
+* The MIT License (MIT)
+*
+* Copyright (c) 2014 - 2018 Vivante 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 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 GPL License (GPL)
+*
+* Copyright (C) 2014 - 2018 Vivante 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.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+*****************************************************************************
+*
+* Note: This software is released under dual MIT and GPL licenses. A
+* recipient may use this file under the terms of either the MIT license or
+* GPL License. If you wish to use only one license not the other, you can
+* indicate your decision by deleting one of the above license notices in your
+* version of this file.
+*
+*****************************************************************************/
+
+
+#ifndef __gc_hal_kernel_h_
+#define __gc_hal_kernel_h_
+
+#include "gc_hal.h"
+#include "gc_hal_kernel_hardware.h"
+#include "gc_hal_driver.h"
+#include "gc_hal_kernel_mutex.h"
+#include "gc_hal_metadata.h"
+#include "gc_hal_kernel_buffer.h"
+
+
+#if gcdENABLE_VG
+#include "gc_hal_kernel_vg.h"
+#endif
+
+#if gcdSECURITY || gcdENABLE_TRUST_APPLICATION
+#include "gc_hal_security_interface.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*******************************************************************************
+***** New MMU Defination *******************************************************/
+#define gcdMMU_MTLB_SHIFT 22
+#define gcdMMU_STLB_4K_SHIFT 12
+#define gcdMMU_STLB_64K_SHIFT 16
+
+#define gcdMMU_MTLB_BITS (32 - gcdMMU_MTLB_SHIFT)
+#define gcdMMU_PAGE_4K_BITS gcdMMU_STLB_4K_SHIFT
+#define gcdMMU_STLB_4K_BITS (32 - gcdMMU_MTLB_BITS - gcdMMU_PAGE_4K_BITS)
+#define gcdMMU_PAGE_64K_BITS gcdMMU_STLB_64K_SHIFT
+#define gcdMMU_STLB_64K_BITS (32 - gcdMMU_MTLB_BITS - gcdMMU_PAGE_64K_BITS)
+
+#define gcdMMU_MTLB_ENTRY_NUM (1 << gcdMMU_MTLB_BITS)
+#define gcdMMU_MTLB_SIZE (gcdMMU_MTLB_ENTRY_NUM << 2)
+#define gcdMMU_STLB_4K_ENTRY_NUM (1 << gcdMMU_STLB_4K_BITS)
+#define gcdMMU_STLB_4K_SIZE (gcdMMU_STLB_4K_ENTRY_NUM << 2)
+#define gcdMMU_PAGE_4K_SIZE (1 << gcdMMU_STLB_4K_SHIFT)
+#define gcdMMU_STLB_64K_ENTRY_NUM (1 << gcdMMU_STLB_64K_BITS)
+#define gcdMMU_STLB_64K_SIZE (gcdMMU_STLB_64K_ENTRY_NUM << 2)
+#define gcdMMU_PAGE_64K_SIZE (1 << gcdMMU_STLB_64K_SHIFT)
+
+#define gcdMMU_MTLB_MASK (~((1U << gcdMMU_MTLB_SHIFT)-1))
+#define gcdMMU_STLB_4K_MASK ((~0U << gcdMMU_STLB_4K_SHIFT) ^ gcdMMU_MTLB_MASK)
+#define gcdMMU_PAGE_4K_MASK (gcdMMU_PAGE_4K_SIZE - 1)
+#define gcdMMU_STLB_64K_MASK ((~((1U << gcdMMU_STLB_64K_SHIFT)-1)) ^ gcdMMU_MTLB_MASK)
+#define gcdMMU_PAGE_64K_MASK (gcdMMU_PAGE_64K_SIZE - 1)
+
+/* Page offset definitions. */
+#define gcdMMU_OFFSET_4K_BITS (32 - gcdMMU_MTLB_BITS - gcdMMU_STLB_4K_BITS)
+#define gcdMMU_OFFSET_4K_MASK ((1U << gcdMMU_OFFSET_4K_BITS) - 1)
+#define gcdMMU_OFFSET_16K_BITS (32 - gcdMMU_MTLB_BITS - gcdMMU_STLB_16K_BITS)
+#define gcdMMU_OFFSET_16K_MASK ((1U << gcdMMU_OFFSET_16K_BITS) - 1)
+
+#define gcdMMU_MTLB_ENTRY_HINTS_BITS 6
+#define gcdMMU_MTLB_ENTRY_STLB_MASK (~((1U << gcdMMU_MTLB_ENTRY_HINTS_BITS) - 1))
+
+#define gcdMMU_MTLB_PRESENT 0x00000001
+#define gcdMMU_MTLB_EXCEPTION 0x00000002
+#define gcdMMU_MTLB_4K_PAGE 0x00000000
+
+#define gcdMMU_STLB_PRESENT 0x00000001
+#define gcdMMU_STLB_EXCEPTION 0x00000002
+#define gcdMMU_STLB_4K_PAGE 0x00000000
+
+/*******************************************************************************
+***** Stuck Dump Level ********************************************************/
+
+/* Dump nonthing when stuck happens. */
+#define gcvSTUCK_DUMP_NONE 0
+
+/* Dump GPU state and memory near stuck point. */
+#define gcvSTUCK_DUMP_NEARBY_MEMORY 1
+
+/* Beside gcvSTUCK_DUMP_NEARBY_MEMORY, dump context buffer and user command buffer. */
+#define gcvSTUCK_DUMP_USER_COMMAND 2
+
+/* Beside gcvSTUCK_DUMP_USER_COMMAND, commit will be stall
+** to make sure command causing stuck isn't missed. */
+#define gcvSTUCK_DUMP_STALL_COMMAND 3
+
+/* Beside gcvSTUCK_DUMP_USER_COMMAND, dump kernel command buffer. */
+#define gcvSTUCK_DUMP_ALL_COMMAND 4
+
+/*******************************************************************************
+***** Process Secure Cache ****************************************************/
+
+#define gcdSECURE_CACHE_LRU 1
+#define gcdSECURE_CACHE_LINEAR 2
+#define gcdSECURE_CACHE_HASH 3
+#define gcdSECURE_CACHE_TABLE 4
+
+#define gcvPAGE_TABLE_DIRTY_BIT_OTHER (1 << 0)
+#define gcvPAGE_TABLE_DIRTY_BIT_FE (1 << 1)
+
+typedef struct _gcskLOGICAL_CACHE * gcskLOGICAL_CACHE_PTR;
+typedef struct _gcskLOGICAL_CACHE gcskLOGICAL_CACHE;
+struct _gcskLOGICAL_CACHE
+{
+ /* Logical address. */
+ gctPOINTER logical;
+
+ /* DMAable address. */
+ gctUINT32 dma;
+
+#if gcdSECURE_CACHE_METHOD == gcdSECURE_CACHE_HASH
+ /* Pointer to the previous and next hash tables. */
+ gcskLOGICAL_CACHE_PTR nextHash;
+ gcskLOGICAL_CACHE_PTR prevHash;
+#endif
+
+#if gcdSECURE_CACHE_METHOD != gcdSECURE_CACHE_TABLE
+ /* Pointer to the previous and next slot. */
+ gcskLOGICAL_CACHE_PTR next;
+ gcskLOGICAL_CACHE_PTR prev;
+#endif
+
+#if gcdSECURE_CACHE_METHOD == gcdSECURE_CACHE_LINEAR
+ /* Time stamp. */
+ gctUINT64 stamp;
+#endif
+};
+
+typedef struct _gcskSECURE_CACHE * gcskSECURE_CACHE_PTR;
+typedef struct _gcskSECURE_CACHE
+{
+ /* Cache memory. */
+ gcskLOGICAL_CACHE cache[1 + gcdSECURE_CACHE_SLOTS];
+
+ /* Last known index for LINEAR mode. */
+ gcskLOGICAL_CACHE_PTR cacheIndex;
+
+ /* Current free slot for LINEAR mode. */
+ gctUINT32 cacheFree;
+
+ /* Time stamp for LINEAR mode. */
+ gctUINT64 cacheStamp;
+
+#if gcdSECURE_CACHE_METHOD == gcdSECURE_CACHE_HASH
+ /* Hash table for HASH mode. */
+ gcskLOGICAL_CACHE hash[256];
+#endif
+}
+gcskSECURE_CACHE;
+
+/*******************************************************************************
+***** Process Database Management *********************************************/
+
+typedef enum _gceDATABASE_TYPE
+{
+ gcvDB_VIDEO_MEMORY = 1, /* Video memory created. */
+ gcvDB_COMMAND_BUFFER, /* Command Buffer. */
+ gcvDB_NON_PAGED, /* Non paged memory. */
+ gcvDB_CONTIGUOUS, /* Contiguous memory. */
+ gcvDB_SIGNAL, /* Signal. */
+ gcvDB_VIDEO_MEMORY_LOCKED, /* Video memory locked. */
+ gcvDB_CONTEXT, /* Context */
+ gcvDB_IDLE, /* GPU idle. */
+ gcvDB_MAP_MEMORY, /* Map memory */
+ gcvDB_MAP_USER_MEMORY, /* Map user memory */
+ gcvDB_SHBUF, /* Shared buffer. */
+
+ gcvDB_NUM_TYPES,
+}
+gceDATABASE_TYPE;
+
+#define gcdDATABASE_TYPE_MASK 0x000000FF
+#define gcdDB_VIDEO_MEMORY_TYPE_MASK 0x0000FF00
+#define gcdDB_VIDEO_MEMORY_TYPE_SHIFT 8
+
+#define gcdDB_VIDEO_MEMORY_POOL_MASK 0x00FF0000
+#define gcdDB_VIDEO_MEMORY_POOL_SHIFT 16
+
+typedef struct _gcsDATABASE_RECORD * gcsDATABASE_RECORD_PTR;
+typedef struct _gcsDATABASE_RECORD
+{
+ /* Pointer to kernel. */
+ gckKERNEL kernel;
+
+ /* Pointer to next database record. */
+ gcsDATABASE_RECORD_PTR next;
+
+ /* Type of record. */
+ gceDATABASE_TYPE type;
+
+ /* Data for record. */
+ gctPOINTER data;
+ gctPHYS_ADDR physical;
+ gctSIZE_T bytes;
+}
+gcsDATABASE_RECORD;
+
+typedef struct _gcsDATABASE * gcsDATABASE_PTR;
+typedef struct _gcsDATABASE
+{
+ /* Pointer to next entry is hash list. */
+ gcsDATABASE_PTR next;
+ gctSIZE_T slot;
+
+ /* Process ID. */
+ gctUINT32 processID;
+
+ /* Open-Close ref count */
+ gctPOINTER refs;
+
+ /* Already mark for delete and cannot reenter */
+ gctBOOL deleted;
+
+ /* Sizes to query. */
+ gcsDATABASE_COUNTERS vidMem;
+ gcsDATABASE_COUNTERS nonPaged;
+ gcsDATABASE_COUNTERS contiguous;
+ gcsDATABASE_COUNTERS mapUserMemory;
+ gcsDATABASE_COUNTERS mapMemory;
+
+ gcsDATABASE_COUNTERS vidMemType[gcvSURF_NUM_TYPES];
+ /* Counter for each video memory pool. */
+ gcsDATABASE_COUNTERS vidMemPool[gcvPOOL_NUMBER_OF_POOLS];
+ gctPOINTER counterMutex;
+
+ /* Idle time management. */
+ gctUINT64 lastIdle;
+ gctUINT64 idle;
+
+ /* Pointer to database. */
+ gcsDATABASE_RECORD_PTR list[48];
+
+#if gcdSECURE_USER
+ /* Secure cache. */
+ gcskSECURE_CACHE cache;
+#endif
+
+ gctPOINTER handleDatabase;
+ gctPOINTER handleDatabaseMutex;
+
+#if gcdPROCESS_ADDRESS_SPACE
+ gckMMU mmu;
+#endif
+}
+gcsDATABASE;
+
+typedef struct _gcsFDPRIVATE * gcsFDPRIVATE_PTR;
+typedef struct _gcsFDPRIVATE
+{
+ gctINT (* release) (gcsFDPRIVATE_PTR Private);
+}
+gcsFDPRIVATE;
+
+typedef struct _gcsRECORDER * gckRECORDER;
+
+
+/* Create a process database that will contain all its allocations. */
+gceSTATUS
+gckKERNEL_CreateProcessDB(
+ IN gckKERNEL Kernel,
+ IN gctUINT32 ProcessID
+ );
+
+/* Add a record to the process database. */
+gceSTATUS
+gckKERNEL_AddProcessDB(
+ IN gckKERNEL Kernel,
+ IN gctUINT32 ProcessID,
+ IN gceDATABASE_TYPE Type,
+ IN gctPOINTER Pointer,
+ IN gctPHYS_ADDR Physical,
+ IN gctSIZE_T Size
+ );
+
+/* Remove a record to the process database. */
+gceSTATUS
+gckKERNEL_RemoveProcessDB(
+ IN gckKERNEL Kernel,
+ IN gctUINT32 ProcessID,
+ IN gceDATABASE_TYPE Type,
+ IN gctPOINTER Pointer
+ );
+
+/* Destroy the process database. */
+gceSTATUS
+gckKERNEL_DestroyProcessDB(
+ IN gckKERNEL Kernel,
+ IN gctUINT32 ProcessID
+ );
+
+/* Find a record to the process database. */
+gceSTATUS
+gckKERNEL_FindProcessDB(
+ IN gckKERNEL Kernel,
+ IN gctUINT32 ProcessID,
+ IN gctUINT32 ThreadID,
+ IN gceDATABASE_TYPE Type,
+ IN gctPOINTER Pointer,
+ OUT gcsDATABASE_RECORD_PTR Record
+ );
+
+/* Query the process database. */
+gceSTATUS
+gckKERNEL_QueryProcessDB(
+ IN gckKERNEL Kernel,
+ IN gctUINT32 ProcessID,
+ IN gctBOOL LastProcessID,
+ IN gceDATABASE_TYPE Type,
+ OUT gcuDATABASE_INFO * Info
+ );
+
+/* Dump the process database. */
+gceSTATUS
+gckKERNEL_DumpProcessDB(
+ IN gckKERNEL Kernel
+ );
+
+/* Dump the video memory usage for process specified. */
+gceSTATUS
+gckKERNEL_DumpVidMemUsage(
+ IN gckKERNEL Kernel,
+ IN gctINT32 ProcessID
+ );
+
+gceSTATUS
+gckKERNEL_FindDatabase(
+ IN gckKERNEL Kernel,
+ IN gctUINT32 ProcessID,
+ IN gctBOOL LastProcessID,
+ OUT gcsDATABASE_PTR * Database
+ );
+
+gceSTATUS
+gckKERNEL_FindHandleDatbase(
+ IN gckKERNEL Kernel,
+ IN gctUINT32 ProcessID,
+ OUT gctPOINTER * HandleDatabase,
+ OUT gctPOINTER * HandleDatabaseMutex
+ );
+
+gceSTATUS
+gckKERNEL_GetProcessMMU(
+ IN gckKERNEL Kernel,
+ OUT gckMMU * Mmu
+ );
+
+gceSTATUS
+gckMMU_FlatMapping(
+ IN gckMMU Mmu,
+ IN gctUINT32 Physical,
+ IN gctUINT32 NumPages
+ );
+
+gceSTATUS
+gckMMU_GetPageEntry(
+ IN gckMMU Mmu,
+ IN gctUINT32 Address,
+ IN gctUINT32_PTR *PageTable
+ );
+
+gceSTATUS
+gckMMU_FreePagesEx(
+ IN gckMMU Mmu,
+ IN gctUINT32 Address,
+ IN gctSIZE_T PageCount
+ );
+
+gceSTATUS
+gckMMU_AttachHardware(
+ IN gckMMU Mmu,
+ IN gckHARDWARE Hardware
+ );
+
+void
+gckMMU_DumpRecentFreedAddress(
+ IN gckMMU Mmu
+ );
+
+gceSTATUS
+gckKERNEL_CreateIntegerDatabase(
+ IN gckKERNEL Kernel,
+ OUT gctPOINTER * Database
+ );
+
+gceSTATUS
+gckKERNEL_DestroyIntegerDatabase(
+ IN gckKERNEL Kernel,
+ IN gctPOINTER Database
+ );
+
+gceSTATUS
+gckKERNEL_AllocateIntegerId(
+ IN gctPOINTER Database,
+ IN gctPOINTER Pointer,
+ OUT gctUINT32 * Id
+ );
+
+gceSTATUS
+gckKERNEL_FreeIntegerId(
+ IN gctPOINTER Database,
+ IN gctUINT32 Id
+ );
+
+gceSTATUS
+gckKERNEL_QueryIntegerId(
+ IN gctPOINTER Database,
+ IN gctUINT32 Id,
+ OUT gctPOINTER * Pointer
+ );
+
+/* Pointer rename */
+gctUINT32
+gckKERNEL_AllocateNameFromPointer(
+ IN gckKERNEL Kernel,
+ IN gctPOINTER Pointer
+ );
+
+gctPOINTER
+gckKERNEL_QueryPointerFromName(
+ IN gckKERNEL Kernel,
+ IN gctUINT32 Name
+ );
+
+gceSTATUS
+gckKERNEL_DeleteName(
+ IN gckKERNEL Kernel,
+ IN gctUINT32 Name
+ );
+
+#if gcdSECURE_USER
+/* Get secure cache from the process database. */
+gceSTATUS
+gckKERNEL_GetProcessDBCache(
+ IN gckKERNEL Kernel,
+ IN gctUINT32 ProcessID,
+ OUT gcskSECURE_CACHE_PTR * Cache
+ );
+#endif
+
+/*******************************************************************************
+********* Timer Management ****************************************************/
+typedef struct _gcsTIMER * gcsTIMER_PTR;
+typedef struct _gcsTIMER
+{
+ /* Start and Stop time holders. */
+ gctUINT64 startTime;
+ gctUINT64 stopTime;
+}
+gcsTIMER;
+
+/******************************************************************************\
+********************************** Structures **********************************
+\******************************************************************************/
+
+/* gckDB object. */
+struct _gckDB
+{
+ /* Database management. */
+ gcsDATABASE_PTR db[16];
+ gctPOINTER dbMutex;
+ gcsDATABASE_PTR freeDatabase;
+ gcsDATABASE_RECORD_PTR freeRecord;
+ gcsDATABASE_PTR lastDatabase;
+ gctUINT32 lastProcessID;
+ gctUINT64 lastIdle;
+ gctUINT64 idleTime;
+ gctUINT64 lastSlowdown;
+ gctUINT64 lastSlowdownIdle;
+ gctPOINTER nameDatabase;
+ gctPOINTER nameDatabaseMutex;
+
+ gctPOINTER pointerDatabase;
+ gctPOINTER pointerDatabaseMutex;
+
+ gcsLISTHEAD onFaultVidmemList;
+ gctPOINTER onFaultVidmemListMutex;
+};
+
+typedef struct _gckVIRTUAL_BUFFER * gckVIRTUAL_BUFFER_PTR;
+typedef struct _gckVIRTUAL_BUFFER
+{
+ gctPHYS_ADDR physical;
+ gctPOINTER userLogical;
+ gctPOINTER kernelLogical;
+ gctSIZE_T bytes;
+ gctSIZE_T pageCount;
+ gctPOINTER pageTable;
+ gctUINT32 gpuAddress;
+ gctUINT pid;
+ gckKERNEL kernel;
+#if gcdPROCESS_ADDRESS_SPACE
+ gckMMU mmu;
+#endif
+}
+gckVIRTUAL_BUFFER;
+
+typedef struct _gckVIRTUAL_COMMAND_BUFFER * gckVIRTUAL_COMMAND_BUFFER_PTR;
+typedef struct _gckVIRTUAL_COMMAND_BUFFER
+{
+ gckVIRTUAL_BUFFER virtualBuffer;
+ gckVIRTUAL_COMMAND_BUFFER_PTR next;
+ gckVIRTUAL_COMMAND_BUFFER_PTR prev;
+}
+gckVIRTUAL_COMMAND_BUFFER;
+
+/* gckKERNEL object. */
+struct _gckKERNEL
+{
+ /* Object. */
+ gcsOBJECT object;
+
+ /* Pointer to gckOS object. */
+ gckOS os;
+
+ /* Core */
+ gceCORE core;
+
+ /* Pointer to gckHARDWARE object. */
+ gckHARDWARE hardware;
+
+ /* Pointer to gckCOMMAND object. */
+ gckCOMMAND command;
+
+ /* Pointer to gckEVENT object. */
+ gckEVENT eventObj;
+
+ /* Pointer to context. */
+ gctPOINTER context;
+
+ /* Pointer to gckMMU object. */
+ gckMMU mmu;
+
+ /* Arom holding number of clients. */
+ gctPOINTER atomClients;
+
+#if VIVANTE_PROFILER
+ /* Enable profiling */
+ gctBOOL profileEnable;
+ /* Clear profile register or not*/
+ gctBOOL profileCleanRegister;
+#endif
+
+#ifdef QNX_SINGLE_THREADED_DEBUGGING
+ gctPOINTER debugMutex;
+#endif
+
+ /* Database management. */
+ gckDB db;
+ gctBOOL dbCreated;
+
+ gctUINT64 resetTimeStamp;
+
+ /* Pointer to gckEVENT object. */
+ gcsTIMER timers[8];
+ gctUINT32 timeOut;
+
+#if gcdENABLE_VG
+ gckVGKERNEL vg;
+#endif
+
+ /* Virtual command buffer list. */
+ gckVIRTUAL_COMMAND_BUFFER_PTR virtualBufferHead;
+ gckVIRTUAL_COMMAND_BUFFER_PTR virtualBufferTail;
+ gctPOINTER virtualBufferLock;
+
+ /* Enable virtual command buffer. */
+ gctBOOL virtualCommandBuffer;
+
+#if gcdDVFS
+ gckDVFS dvfs;
+#endif
+
+#if gcdLINUX_SYNC_FILE
+ gctHANDLE timeline;
+#endif
+
+ /* Enable recovery. */
+ gctBOOL recovery;
+
+ /* Level of dump information after stuck. */
+ gctUINT stuckDump;
+
+#if gcdSECURITY || gcdENABLE_TRUST_APPLICATION
+ gctUINT32 securityChannel;
+#endif
+
+ /* Timer to monitor GPU stuck. */
+ gctPOINTER monitorTimer;
+
+ /* Flag to quit monitor timer. */
+ gctBOOL monitorTimerStop;
+
+ /* Monitor states. */
+ gctBOOL monitoring;
+ gctUINT32 lastCommitStamp;
+ gctUINT32 timer;
+ gctUINT32 restoreAddress;
+ gctINT32 restoreMask;
+
+ /* 3DBLIT */
+ gckASYNC_COMMAND asyncCommand;
+ gckEVENT asyncEvent;
+
+ /* Pointer to gckDEVICE object. */
+ gckDEVICE device;
+
+ gctUINT chipID;
+
+ gctUINT32 contiguousBaseAddress;
+ gctUINT32 externalBaseAddress;
+};
+
+struct _FrequencyHistory
+{
+ gctUINT32 frequency;
+ gctUINT32 count;
+};
+
+/* gckDVFS object. */
+struct _gckDVFS
+{
+ gckOS os;
+ gckHARDWARE hardware;
+ gctPOINTER timer;
+ gctUINT32 pollingTime;
+ gctBOOL stop;
+ gctUINT32 totalConfig;
+ gctUINT32 loads[8];
+ gctUINT8 currentScale;
+ struct _FrequencyHistory frequencyHistory[16];
+};
+
+typedef struct _gcsFENCE * gckFENCE;
+typedef struct _gcsFENCE
+{
+ /* Pointer to required object. */
+ gckKERNEL kernel;
+
+ /* Fence location. */
+ gctPHYS_ADDR physical;
+ gctPHYS_ADDR physHandle;
+ gctPOINTER logical;
+ gctUINT32 address;
+
+ gcsLISTHEAD waitingList;
+ gctPOINTER mutex;
+}
+gcsFENCE;
+
+/* A sync point attached to fence. */
+typedef struct _gcsFENCE_SYNC * gckFENCE_SYNC;
+typedef struct _gcsFENCE_SYNC
+{
+ /* Stamp of commit access this node. */
+ gctUINT64 commitStamp;
+
+ /* Attach to waiting list. */
+ gcsLISTHEAD head;
+
+ gctPOINTER signal;
+
+ gctBOOL inList;
+}
+gcsFENCE_SYNC;
+
+/* gckCOMMAND object. */
+struct _gckCOMMAND
+{
+ /* Object. */
+ gcsOBJECT object;
+
+ /* Pointer to required object. */
+ gckKERNEL kernel;
+ gckOS os;
+
+ /* Number of bytes per page. */
+ gctUINT32 pageSize;
+
+ /* Current pipe select. */
+ gcePIPE_SELECT pipeSelect;
+
+ /* Command queue running flag. */
+ gctBOOL running;
+
+ /* Idle flag and commit stamp. */
+ gctBOOL idle;
+ gctUINT64 commitStamp;
+
+ /* Command queue mutex. */
+ gctPOINTER mutexQueue;
+
+ /* Context switching mutex. */
+ gctPOINTER mutexContext;
+
+ /* Context sequence mutex. */
+ gctPOINTER mutexContextSeq;
+
+ /* Command queue power semaphore. */
+ gctPOINTER powerSemaphore;
+
+ /* Current command queue. */
+ struct _gcskCOMMAND_QUEUE
+ {
+ gctSIGNAL signal;
+ gctPHYS_ADDR physical;
+ gctPOINTER logical;
+ gctUINT32 address;
+ }
+ queues[gcdCOMMAND_QUEUES];
+
+ gctPHYS_ADDR virtualMemory;
+ gctPHYS_ADDR physHandle;
+ gctUINT32 physical;
+ gctPOINTER logical;
+ gctUINT32 address;
+ gctUINT32 offset;
+ gctINT index;
+#if gcmIS_DEBUG(gcdDEBUG_TRACE)
+ gctUINT wrapCount;
+#endif
+
+ /* The command queue is new. */
+ gctBOOL newQueue;
+
+ /* Context management. */
+ gckCONTEXT currContext;
+ gctPOINTER stateMap;
+
+ /* Pointer to last WAIT command. */
+ gctUINT32 waitPhysical;
+ gctPOINTER waitLogical;
+ gctUINT32 waitAddress;
+ gctUINT32 waitSize;
+ gctUINT32 waitOffset;
+
+ /* Command buffer alignment. */
+ gctUINT32 alignment;
+ gctUINT32 reservedHead;
+
+ /* Commit counter. */
+ gctPOINTER atomCommit;
+
+ /* Kernel process ID. */
+ gctUINT32 kernelProcessID;
+
+ /* End Event signal. */
+ gctSIGNAL endEventSignal;
+
+#if gcdSECURE_USER
+ /* Hint array copy buffer. */
+ gctBOOL hintArrayAllocated;
+ gctUINT hintArraySize;
+ gctUINT32_PTR hintArray;
+#endif
+
+#if gcdPROCESS_ADDRESS_SPACE
+ gckMMU currentMmu;
+#endif
+
+#if gcdRECORD_COMMAND
+ gckRECORDER recorder;
+#endif
+
+ gctPOINTER kList;
+
+ gckFENCE fence;
+
+ /* For getting state from async command buffer. */
+ gckASYNC_COMMAND asyncCommand;
+
+ gctBOOL dummyDraw;
+
+ /* a copy in kernel space for current committing command buffer
+ * avoid occupyting stack space.
+ */
+ struct _gcoCMDBUF _commandBufferObject;
+
+ struct _gcoCMDBUF _nextCMDBUF;
+};
+
+typedef struct _gcsEVENT * gcsEVENT_PTR;
+
+/* Structure holding one event to be processed. */
+typedef struct _gcsEVENT
+{
+ /* Pointer to next event in queue. */
+ gcsEVENT_PTR next;
+
+ /* Event information. */
+ gcsHAL_INTERFACE info;
+
+ /* Process ID owning the event. */
+ gctUINT32 processID;
+
+#ifdef __QNXNTO__
+ /* Kernel. */
+ gckKERNEL kernel;
+#endif
+
+ gctBOOL fromKernel;
+}
+gcsEVENT;
+
+/* Structure holding a list of events to be processed by an interrupt. */
+typedef struct _gcsEVENT_QUEUE * gcsEVENT_QUEUE_PTR;
+typedef struct _gcsEVENT_QUEUE
+{
+ /* Time stamp. */
+ gctUINT64 stamp;
+
+ /* Source of the event. */
+ gceKERNEL_WHERE source;
+
+ /* Pointer to head of event queue. */
+ gcsEVENT_PTR head;
+
+ /* Pointer to tail of event queue. */
+ gcsEVENT_PTR tail;
+
+ /* Next list of events. */
+ gcsEVENT_QUEUE_PTR next;
+
+ /* Current commit stamp. */
+ gctUINT64 commitStamp;
+}
+gcsEVENT_QUEUE;
+
+/*
+ gcdREPO_LIST_COUNT defines the maximum number of event queues with different
+ hardware module sources that may coexist at the same time. Only two sources
+ are supported - gcvKERNEL_COMMAND and gcvKERNEL_PIXEL. gcvKERNEL_COMMAND
+ source is used only for managing the kernel command queue and is only issued
+ when the current command queue gets full. Since we commit event queues every
+ time we commit command buffers, in the worst case we can have up to three
+ pending event queues:
+ - gcvKERNEL_PIXEL
+ - gcvKERNEL_COMMAND (queue overflow)
+ - gcvKERNEL_PIXEL
+*/
+#define gcdREPO_LIST_COUNT 3
+
+/* gckEVENT object. */
+struct _gckEVENT
+{
+ /* The object. */
+ gcsOBJECT object;
+
+ /* Pointer to required objects. */
+ gckOS os;
+ gckKERNEL kernel;
+
+ /* Pointer to gckASYNC_COMMAND object. */
+ gckASYNC_COMMAND asyncCommand;
+
+ /* Time stamp. */
+ gctUINT64 stamp;
+ gctUINT32 lastCommitStamp;
+
+ /* Queue mutex. */
+ gctPOINTER eventQueueMutex;
+
+ /* Array of event queues. */
+ gcsEVENT_QUEUE queues[29];
+ gctINT32 freeQueueCount;
+ gctUINT8 lastID;
+
+ /* Pending events. */
+ gctPOINTER pending;
+
+ /* List of free event structures and its mutex. */
+ gcsEVENT_PTR freeEventList;
+ gctSIZE_T freeEventCount;
+ gctPOINTER freeEventMutex;
+
+ /* Event queues. */
+ gcsEVENT_QUEUE_PTR queueHead;
+ gcsEVENT_QUEUE_PTR queueTail;
+ gcsEVENT_QUEUE_PTR freeList;
+ gcsEVENT_QUEUE repoList[gcdREPO_LIST_COUNT];
+ gctPOINTER eventListMutex;
+
+ gctPOINTER submitTimer;
+
+#if gcdINTERRUPT_STATISTIC
+ gctPOINTER interruptCount;
+#endif
+
+ gctINT notifyState;
+};
+
+/* Free all events belonging to a process. */
+gceSTATUS
+gckEVENT_FreeProcess(
+ IN gckEVENT Event,
+ IN gctUINT32 ProcessID
+ );
+
+gceSTATUS
+gckEVENT_Stop(
+ IN gckEVENT Event,
+ IN gctUINT32 ProcessID,
+ IN gctPHYS_ADDR Handle,
+ IN gctSIZE_T Offset,
+ IN gctPOINTER Logical,
+ IN gctUINT32 Address,
+ IN gctSIGNAL Signal,
+ IN OUT gctUINT32 * waitSize
+ );
+
+typedef struct _gcsLOCK_INFO * gcsLOCK_INFO_PTR;
+typedef struct _gcsLOCK_INFO
+{
+ gctUINT32 GPUAddresses[gcdMAX_GPU_COUNT];
+ gctPOINTER pageTables[gcdMAX_GPU_COUNT];
+ gctUINT32 lockeds[gcdMAX_GPU_COUNT];
+ gckKERNEL lockKernels[gcdMAX_GPU_COUNT];
+ gckMMU lockMmus[gcdMAX_GPU_COUNT];
+}
+gcsLOCK_INFO;
+
+typedef struct _gcsGPU_MAP * gcsGPU_MAP_PTR;
+typedef struct _gcsGPU_MAP
+{
+ gctINT pid;
+ gcsLOCK_INFO lockInfo;
+ gcsGPU_MAP_PTR prev;
+ gcsGPU_MAP_PTR next;
+}
+gcsGPU_MAP;
+
+/* gcuVIDMEM_NODE structure. */
+typedef union _gcuVIDMEM_NODE
+{
+ /* Allocated from gckVIDMEM. */
+ struct _gcsVIDMEM_NODE_VIDMEM
+ {
+ /* Owner of this node. */
+ gckVIDMEM memory;
+
+ /* Dual-linked list of nodes. */
+ gcuVIDMEM_NODE_PTR next;
+ gcuVIDMEM_NODE_PTR prev;
+
+ /* Dual linked list of free nodes. */
+ gcuVIDMEM_NODE_PTR nextFree;
+ gcuVIDMEM_NODE_PTR prevFree;
+
+ /* Information for this node. */
+ gctSIZE_T offset;
+ gctSIZE_T bytes;
+ gctUINT32 alignment;
+
+#ifdef __QNXNTO__
+ /* Client virtual address. */
+ gctPOINTER logical;
+#endif
+
+ /* Locked counter. */
+ gctINT32 locked;
+
+ /* Memory pool. */
+ gcePOOL pool;
+ gctUINT32 physical;
+
+ /* Process ID owning this memory. */
+ gctUINT32 processID;
+
+#if gcdENABLE_VG
+ gctPOINTER kernelVirtual;
+#endif
+ }
+ VidMem;
+
+ /* Allocated from gckOS. */
+ struct _gcsVIDMEM_NODE_VIRTUAL
+ {
+ /* Pointer to gckKERNEL object. */
+ gckKERNEL kernel;
+
+ /* Information for this node. */
+ /* Contiguously allocated? */
+ gctBOOL contiguous;
+ /* mdl record pointer... a kmalloc address. Process agnostic. */
+ gctPHYS_ADDR physical;
+ gctSIZE_T bytes;
+ /* do_mmap_pgoff address... mapped per-process. */
+ gctPOINTER logical;
+
+#if gcdENABLE_VG
+ /* Physical address of this node, only meaningful when it is contiguous. */
+ gctUINT64 physicalAddress;
+
+ /* Kernel logical of this node. */
+ gctPOINTER kernelVirtual;
+#endif
+
+ /* Customer private handle */
+ gctUINT32 gid;
+
+ /* Page table information. */
+ /* Used only when node is not contiguous */
+ gctSIZE_T pageCount;
+
+ /* Used only when node is not contiguous */
+ gctPOINTER pageTables[gcdMAX_GPU_COUNT];
+ /* Actual physical address */
+ gctUINT32 addresses[gcdMAX_GPU_COUNT];
+
+ /* Locked counter. */
+ gctINT32 lockeds[gcdMAX_GPU_COUNT];
+
+ /* Surface type. */
+ gceSURF_TYPE type;
+
+ /* Secure GPU virtual address. */
+ gctBOOL secure;
+
+ gctBOOL onFault;
+
+ gcsLISTHEAD head;
+ }
+ Virtual;
+}
+gcuVIDMEM_NODE;
+
+/* gckVIDMEM object. */
+struct _gckVIDMEM
+{
+ /* Object. */
+ gcsOBJECT object;
+
+ /* Pointer to gckOS object. */
+ gckOS os;
+
+ /* mdl record pointer... a kmalloc address. Process agnostic. */
+ gctPHYS_ADDR physical;
+
+ /* Information for this video memory heap. */
+ gctUINT32 baseAddress;
+ gctSIZE_T bytes;
+ gctSIZE_T freeBytes;
+ gctSIZE_T minFreeBytes;
+
+ /* Mapping for each type of surface. */
+ gctINT mapping[gcvSURF_NUM_TYPES];
+
+ /* Sentinel nodes for up to 8 banks. */
+ gcuVIDMEM_NODE sentinel[8];
+
+ /* Allocation threshold. */
+ gctSIZE_T threshold;
+
+ /* The heap mutex. */
+ gctPOINTER mutex;
+};
+
+typedef struct _gcsVIDMEM_NODE
+{
+ _VIV_VIDMEM_METADATA metadata;
+
+ /* Pointer to gcuVIDMEM_NODE. */
+ gcuVIDMEM_NODE_PTR node;
+
+ /* Pointer to gckKERNEL object. */
+ gckKERNEL kernel;
+
+ /* Mutex to protect node. */
+ gctPOINTER mutex;
+
+ /* Reference count. */
+ gctPOINTER reference;
+
+ /* Name for client to import. */
+ gctUINT32 name;
+
+ /* dma_buf */
+ gctPOINTER dmabuf;
+
+#if gcdPROCESS_ADDRESS_SPACE
+ /* Head of mapping list. */
+ gcsGPU_MAP_PTR mapHead;
+
+ /* Tail of mapping list. */
+ gcsGPU_MAP_PTR mapTail;
+
+ gctPOINTER mapMutex;
+#endif
+
+ /* Surface Type. */
+ gceSURF_TYPE type;
+
+ /* Pool from which node is allocated. */
+ gcePOOL pool;
+
+ gcsFENCE_SYNC sync[gcvENGINE_GPU_ENGINE_COUNT];
+
+ /* For DRM usage */
+ gctUINT64 timeStamp;
+ gckVIDMEM_NODE tsNode;
+ gctUINT32 tilingMode;
+ gctUINT32 tsMode;
+ gctUINT64 clearValue;
+}
+gcsVIDMEM_NODE;
+
+typedef struct _gcsVIDMEM_HANDLE * gckVIDMEM_HANDLE;
+typedef struct _gcsVIDMEM_HANDLE
+{
+ /* Pointer to gckVIDMEM_NODE. */
+ gckVIDMEM_NODE node;
+
+ /* Handle for current process. */
+ gctUINT32 handle;
+
+ /* Reference count for this handle. */
+ gctPOINTER reference;
+}
+gcsVIDMEM_HANDLE;
+
+typedef struct _gcsSHBUF * gcsSHBUF_PTR;
+typedef struct _gcsSHBUF
+{
+ /* ID. */
+ gctUINT32 id;
+
+ /* Reference count. */
+ gctPOINTER reference;
+
+ /* Data size. */
+ gctUINT32 size;
+
+ /* Data. */
+ gctPOINTER data;
+}
+gcsSHBUF;
+
+typedef struct _gcsCORE_INFO
+{
+ gceHARDWARE_TYPE type;
+ gceCORE core;
+ gckKERNEL kernel;
+ gctUINT chipID;
+}
+gcsCORE_INFO;
+
+typedef struct _gcsCORE_LIST
+{
+ gckKERNEL kernels[gcvCORE_COUNT];
+ gctUINT32 num;
+}
+gcsCORE_LIST;
+
+/* A gckDEVICE is a group of cores (gckKERNEL in software). */
+typedef struct _gcsDEVICE
+{
+ gcsCORE_INFO coreInfoArray[gcvCORE_COUNT];
+ gctUINT32 coreNum;
+ gcsCORE_LIST map[gcvHARDWARE_NUM_TYPES];
+ gceHARDWARE_TYPE defaultHwType;
+
+ gckOS os;
+
+ /* Process resource database. */
+ gckDB database;
+
+ /* Same hardware type shares one MMU. */
+ gckMMU mmus[gcvHARDWARE_NUM_TYPES];
+
+ /* Mutex to make sure stuck dump for multiple cores doesn't interleave. */
+ gctPOINTER stuckDumpMutex;
+
+ /* Mutex for multi-core combine mode command submission */
+ gctPOINTER commitMutex;
+}
+gcsDEVICE;
+
+gceSTATUS
+gckVIDMEM_HANDLE_Allocate(
+ IN gckKERNEL Kernel,
+ IN gckVIDMEM_NODE Node,
+ OUT gctUINT32 * Handle
+ );
+
+gceSTATUS
+gckVIDMEM_HANDLE_Reference(
+ IN gckKERNEL Kernel,
+ IN gctUINT32 ProcessID,
+ IN gctUINT32 Handle
+ );
+
+gceSTATUS
+gckVIDMEM_HANDLE_Dereference(
+ IN gckKERNEL Kernel,
+ IN gctUINT32 ProcessID,
+ IN gctUINT32 Handle
+ );
+
+gceSTATUS
+gckVIDMEM_NODE_Allocate(
+ IN gckKERNEL Kernel,
+ IN gcuVIDMEM_NODE_PTR VideoNode,
+ IN gceSURF_TYPE Type,
+ IN gcePOOL Pool,
+ IN gctUINT32 * Handle
+ );
+
+gceSTATUS
+gckVIDMEM_NODE_LockCPU(
+ IN gckKERNEL Kernel,
+ IN gctUINT32 Handle,
+ OUT gctPOINTER * Logical
+ );
+
+gceSTATUS
+gckVIDMEM_NODE_UnlockCPU(
+ IN gckKERNEL Kernel,
+ IN gctUINT32 Handle,
+ OUT gctPOINTER Logical
+ );
+
+gceSTATUS
+gckVIDMEM_Node_Lock(
+ IN gckKERNEL Kernel,
+ IN gckVIDMEM_NODE Node,
+ OUT gctUINT32 *Address
+ );
+
+gceSTATUS
+gckVIDMEM_NODE_Unlock(
+ IN gckKERNEL Kernel,
+ IN gckVIDMEM_NODE Node,
+ IN gctUINT32 ProcessID
+ );
+
+gceSTATUS
+gckVIDMEM_NODE_Reference(
+ IN gckKERNEL Kernel,
+ IN gckVIDMEM_NODE Node
+ );
+
+gceSTATUS
+gckVIDMEM_NODE_Dereference(
+ IN gckKERNEL Kernel,
+ IN gckVIDMEM_NODE Node
+ );
+
+gceSTATUS
+gckVIDMEM_NODE_Export(
+ IN gckKERNEL Kernel,
+ IN gctUINT32 Handle,
+ IN gctINT32 Flags,
+ OUT gctPOINTER *DmaBuf,
+ OUT gctINT32 *FD
+ );
+
+gceSTATUS
+gckVIDMEM_NODE_Name(
+ IN gckKERNEL Kernel,
+ IN gctUINT32 Handle,
+ OUT gctUINT32 * Name
+ );
+
+gceSTATUS
+gckVIDMEM_NODE_Import(
+ IN gckKERNEL Kernel,
+ IN gctUINT32 Name,
+ OUT gctUINT32 * Handle
+ );
+
+gceSTATUS
+gckVIDMEM_NODE_GetFd(
+ IN gckKERNEL Kernel,
+ IN gctUINT32 Handle,
+ OUT gctINT * Fd
+ );
+
+gceSTATUS
+gckVIDMEM_HANDLE_LookupAndReference(
+ IN gckKERNEL Kernel,
+ IN gctUINT32 Handle,
+ OUT gckVIDMEM_NODE * Node
+ );
+
+gceSTATUS
+gckVIDMEM_HANDLE_Lookup(
+ IN gckKERNEL Kernel,
+ IN gctUINT32 ProcessID,
+ IN gctUINT32 Handle,
+ OUT gckVIDMEM_NODE * Node
+ );
+
+gceSTATUS
+gckVIDMEM_NODE_WrapUserMemory(
+ IN gckKERNEL Kernel,
+ IN gcsUSER_MEMORY_DESC_PTR Desc,
+ OUT gctUINT32 * Handle,
+ OUT gctUINT64 * Bytes
+ );
+
+gceSTATUS
+gckVIDMEM_FindVIDMEM(
+ IN gckKERNEL Kernel,
+ IN gctUINT32 HardwareAddress,
+ OUT gcuVIDMEM_NODE_PTR * Node,
+ OUT gctUINT32_PTR PageTableEntryValue
+ );
+
+gceSTATUS
+gckVIDMEM_QueryNodes(
+ IN gckKERNEL Kernel,
+ IN gcePOOL Pool,
+ OUT gctINT32 *Count,
+ OUT gcuVIDMEM_NODE_PTR *Nodes
+ );
+
+#if gcdPROCESS_ADDRESS_SPACE
+gceSTATUS
+gckEVENT_DestroyMmu(
+ IN gckEVENT Event,
+ IN gckMMU Mmu,
+ IN gceKERNEL_WHERE FromWhere
+ );
+#endif
+
+typedef struct _gcsADDRESS_AREA * gcsADDRESS_AREA_PTR;
+typedef struct _gcsADDRESS_AREA
+{
+ /* Page table information. */
+ gctSIZE_T pageTableSize;
+ gctPHYS_ADDR pageTablePhysical;
+ gctUINT32_PTR pageTableLogical;
+ gctUINT32 pageTableEntries;
+
+ /* Free entries. */
+ gctUINT32 heapList;
+ gctBOOL freeNodes;
+
+ gctUINT32 dynamicMappingStart;
+ gctUINT32 dynamicMappingEnd;
+
+ gctUINT32_PTR mapLogical;
+}
+gcsADDRESS_AREA;
+
+/* gckMMU object. */
+struct _gckMMU
+{
+ /* The object. */
+ gcsOBJECT object;
+
+ /* Pointer to gckOS object. */
+ gckOS os;
+
+ /* Pointer to gckHARDWARE object. */
+ gckHARDWARE hardware;
+
+ /* The page table mutex. */
+ gctPOINTER pageTableMutex;
+
+ /* Master TLB information. */
+ gctSIZE_T mtlbSize;
+ gctPHYS_ADDR mtlbPhysical;
+ gctUINT32_PTR mtlbLogical;
+ gctUINT32 mtlbEntries;
+
+ gctPOINTER staticSTLB;
+ gctBOOL enabled;
+
+#if gcdPROCESS_ADDRESS_SPACE
+ gctPOINTER pageTableDirty[gcdMAX_GPU_COUNT];
+ gctPOINTER stlbs;
+#endif
+
+ gctPOINTER safePageLogical;
+ gctPHYS_ADDR safePagePhysical;
+ gctUINT32 safeAddress;
+ gctSIZE_T safePageSize;
+
+ /* physBase,physSize flat mapping area. */
+ gctUINT32 flatMappingRangeCount;
+ gcsFLAT_MAPPING_RANGE flatMappingRanges[gcdMAX_FLAT_MAPPING_COUNT];
+
+ /* List of hardware which uses this MMU. */
+ gcsLISTHEAD hardwareList;
+
+ struct _gckQUEUE recentFreedAddresses;
+
+ gcsADDRESS_AREA area[gcvADDRESS_AREA_COUNT];
+
+ gctUINT32 contiguousBaseAddress;
+ gctUINT32 externalBaseAddress;
+};
+
+typedef struct _gcsASYNC_COMMAND
+{
+ gckOS os;
+ gckHARDWARE hardware;
+ gckKERNEL kernel;
+
+ gctPOINTER mutex;
+ gcsFE fe;
+
+ gctUINT32 reservedTail;
+ gctUINT64 commitStamp;
+
+ gckFENCE fence;
+
+ gctPOINTER kList;
+}
+gcsASYNC_COMMAND;
+
+gceSTATUS
+gckOS_CreateKernelMapping(
+ IN gckOS Os,
+ IN gctPHYS_ADDR Physical,
+ IN gctSIZE_T Offset,
+ IN gctSIZE_T Bytes,
+ OUT gctPOINTER * Logical
+ );
+
+gceSTATUS
+gckOS_DestroyKernelMapping(
+ IN gckOS Os,
+ IN gctPHYS_ADDR Physical,
+ IN gctPOINTER Logical
+ );
+
+gceSTATUS
+gckOS_CreateKernelVirtualMapping(
+ IN gckOS Os,
+ IN gctPHYS_ADDR Physical,
+ IN gctSIZE_T Bytes,
+ OUT gctPOINTER * Logical,
+ OUT gctSIZE_T * PageCount
+ );
+
+gceSTATUS
+gckOS_DestroyKernelVirtualMapping(
+ IN gckOS Os,
+ IN gctPHYS_ADDR Physical,
+ IN gctSIZE_T Bytes,
+ IN gctPOINTER Logical
+ );
+
+gceSTATUS
+gckOS_CreateUserVirtualMapping(
+ IN gckOS Os,
+ IN gctPHYS_ADDR Physical,
+ IN gctSIZE_T Bytes,
+ OUT gctPOINTER * Logical,
+ OUT gctSIZE_T * PageCount
+ );
+
+gceSTATUS
+gckOS_DestroyUserVirtualMapping(
+ IN gckOS Os,
+ IN gctPHYS_ADDR Physical,
+ IN gctSIZE_T Bytes,
+ IN gctPOINTER Logical
+ );
+
+gceSTATUS
+gckOS_GetFd(
+ IN gctSTRING Name,
+ IN gcsFDPRIVATE_PTR Private,
+ OUT gctINT *Fd
+ );
+
+/*******************************************************************************
+**
+** gckOS_ReadMappedPointer
+**
+** Read pointer mapped from user pointer which returned by gckOS_MapUserPointer.
+**
+** INPUT:
+**
+** gckOS Os
+** Pointer to an gckOS object.
+**
+** gctPOINTER Address
+** Pointer returned by gckOS_MapUserPointer.
+**
+** gctUINT32_PTR Data
+** Pointer to hold 32 bits data.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckOS_ReadMappedPointer(
+ IN gckOS Os,
+ IN gctPOINTER Address,
+ IN gctUINT32_PTR Data
+ );
+
+gceSTATUS
+gckKERNEL_AllocateVirtualCommandBuffer(
+ IN gckKERNEL Kernel,
+ IN gctBOOL InUserSpace,
+ IN OUT gctSIZE_T * Bytes,
+ OUT gctPHYS_ADDR * Physical,
+ OUT gctPOINTER * Logical
+ );
+
+gceSTATUS
+gckKERNEL_DestroyVirtualCommandBuffer(
+ IN gckKERNEL Kernel,
+ IN gctSIZE_T Bytes,
+ IN gctPHYS_ADDR Physical,
+ IN gctPOINTER Logical
+ );
+
+gceSTATUS
+gckKERNEL_AllocateVirtualMemory(
+ IN gckKERNEL Kernel,
+ IN gctBOOL NonPaged,
+ IN gctBOOL InUserSpace,
+ IN OUT gctSIZE_T * Bytes,
+ OUT gctPHYS_ADDR * Physical,
+ OUT gctPOINTER * Logical
+ );
+
+gceSTATUS
+gckKERNEL_FreeVirtualMemory(
+ IN gctPHYS_ADDR Physical,
+ IN gctPOINTER Logical,
+ IN gctBOOL NonPaged
+ );
+
+gceSTATUS
+gckKERNEL_GetGPUAddress(
+ IN gckKERNEL Kernel,
+ IN gctPOINTER Logical,
+ IN gctBOOL InUserSpace,
+ IN gctPHYS_ADDR Physical,
+ OUT gctUINT32 * Address
+ );
+
+gceSTATUS
+gckKERNEL_QueryGPUAddress(
+ IN gckKERNEL Kernel,
+ IN gctUINT32 GpuAddress,
+ OUT gckVIRTUAL_COMMAND_BUFFER_PTR * Buffer
+ );
+
+gceSTATUS
+gckKERNEL_AttachProcess(
+ IN gckKERNEL Kernel,
+ IN gctBOOL Attach
+ );
+
+gceSTATUS
+gckKERNEL_AttachProcessEx(
+ IN gckKERNEL Kernel,
+ IN gctBOOL Attach,
+ IN gctUINT32 PID
+ );
+
+#if gcdSECURE_USER
+gceSTATUS
+gckKERNEL_MapLogicalToPhysical(
+ IN gckKERNEL Kernel,
+ IN gcskSECURE_CACHE_PTR Cache,
+ IN OUT gctPOINTER * Data
+ );
+
+gceSTATUS
+gckKERNEL_FlushTranslationCache(
+ IN gckKERNEL Kernel,
+ IN gcskSECURE_CACHE_PTR Cache,
+ IN gctPOINTER Logical,
+ IN gctSIZE_T Bytes
+ );
+#endif
+
+gceSTATUS
+gckHARDWARE_QueryIdle(
+ IN gckHARDWARE Hardware,
+ OUT gctBOOL_PTR IsIdle
+ );
+
+gceSTATUS
+gckHARDWARE_WaitFence(
+ IN gckHARDWARE Hardware,
+ IN gctPOINTER Logical,
+ IN gctUINT64 FenceData,
+ IN gctUINT32 FenceAddress,
+ OUT gctUINT32 *Bytes
+ );
+
+gceSTATUS
+gckHARDWARE_AddressInHardwareFuncions(
+ IN gckHARDWARE Hardware,
+ IN gctUINT32 Address,
+ OUT gctPOINTER *Pointer
+ );
+
+gceSTATUS
+gckHARDWARE_UpdateContextID(
+ IN gckHARDWARE Hardware
+ );
+
+#if gcdSECURITY
+gceSTATUS
+gckKERNEL_SecurityOpen(
+ IN gckKERNEL Kernel,
+ IN gctUINT32 GPU,
+ OUT gctUINT32 *Channel
+ );
+
+/*
+** Close a security service channel
+*/
+gceSTATUS
+gckKERNEL_SecurityClose(
+ IN gctUINT32 Channel
+ );
+
+/*
+** Security service interface.
+*/
+gceSTATUS
+gckKERNEL_SecurityCallService(
+ IN gctUINT32 Channel,
+ IN OUT gcsTA_INTERFACE * Interface
+ );
+
+gceSTATUS
+gckKERNEL_SecurityStartCommand(
+ IN gckKERNEL Kernel
+ );
+
+gceSTATUS
+gckKERNEL_SecurityAllocateSecurityMemory(
+ IN gckKERNEL Kernel,
+ IN gctUINT32 Bytes,
+ OUT gctUINT32 * Handle
+ );
+
+gceSTATUS
+gckKERNEL_SecurityExecute(
+ IN gckKERNEL Kernel,
+ IN gctPOINTER Buffer,
+ IN gctUINT32 Bytes
+ );
+
+gceSTATUS
+gckKERNEL_SecurityMapMemory(
+ IN gckKERNEL Kernel,
+ IN gctUINT32 *PhysicalArray,
+ IN gctUINT32 PageCount,
+ OUT gctUINT32 * GPUAddress
+ );
+
+gceSTATUS
+gckKERNEL_SecurityUnmapMemory(
+ IN gckKERNEL Kernel,
+ IN gctUINT32 GPUAddress,
+ IN gctUINT32 PageCount
+ );
+
+#endif
+
+#if gcdENABLE_TRUST_APPLICATION
+gceSTATUS
+gckKERNEL_SecurityOpen(
+ IN gckKERNEL Kernel,
+ IN gctUINT32 GPU,
+ OUT gctUINT32 *Channel
+ );
+
+/*
+** Close a security service channel
+*/
+gceSTATUS
+gckKERNEL_SecurityClose(
+ IN gctUINT32 Channel
+ );
+
+/*
+** Security service interface.
+*/
+gceSTATUS
+gckKERNEL_SecurityCallService(
+ IN gctUINT32 Channel,
+ IN OUT gcsTA_INTERFACE * Interface
+ );
+
+gceSTATUS
+gckKERNEL_SecurityStartCommand(
+ IN gckKERNEL Kernel,
+ IN gctUINT32 Address,
+ IN gctUINT32 Bytes
+ );
+
+gceSTATUS
+gckKERNEL_SecurityMapMemory(
+ IN gckKERNEL Kernel,
+ IN gctUINT32 *PhysicalArray,
+ IN gctPHYS_ADDR_T Physical,
+ IN gctUINT32 PageCount,
+ OUT gctUINT32 * GPUAddress
+ );
+
+gceSTATUS
+gckKERNEL_SecurityUnmapMemory(
+ IN gckKERNEL Kernel,
+ IN gctUINT32 GPUAddress,
+ IN gctUINT32 PageCount
+ );
+
+gceSTATUS
+gckKERNEL_SecurityDumpMMUException(
+ IN gckKERNEL Kernel
+ );
+
+gceSTATUS
+gckKERNEL_ReadMMUException(
+ IN gckKERNEL Kernel,
+ IN gctUINT32_PTR MMUStatus,
+ IN gctUINT32_PTR MMUException
+ );
+
+gceSTATUS
+gckKERNEL_HandleMMUException(
+ IN gckKERNEL Kernel,
+ IN gctUINT32 MMUStatus,
+ IN gctPHYS_ADDR_T Physical,
+ IN gctUINT32 GPUAddres
+ );
+#endif
+
+gceSTATUS
+gckKERNEL_CreateShBuffer(
+ IN gckKERNEL Kernel,
+ IN gctUINT32 Size,
+ OUT gctSHBUF * ShBuf
+ );
+
+gceSTATUS
+gckKERNEL_DestroyShBuffer(
+ IN gckKERNEL Kernel,
+ IN gctSHBUF ShBuf
+ );
+
+gceSTATUS
+gckKERNEL_MapShBuffer(
+ IN gckKERNEL Kernel,
+ IN gctSHBUF ShBuf
+ );
+
+gceSTATUS
+gckKERNEL_WriteShBuffer(
+ IN gckKERNEL Kernel,
+ IN gctSHBUF ShBuf,
+ IN gctPOINTER UserData,
+ IN gctUINT32 ByteCount
+ );
+
+gceSTATUS
+gckKERNEL_ReadShBuffer(
+ IN gckKERNEL Kernel,
+ IN gctSHBUF ShBuf,
+ IN gctPOINTER UserData,
+ IN gctUINT32 ByteCount,
+ OUT gctUINT32 * BytesRead
+ );
+
+
+/******************************************************************************\
+******************************* gckCONTEXT Object *******************************
+\******************************************************************************/
+
+gceSTATUS
+gckCONTEXT_Construct(
+ IN gckOS Os,
+ IN gckHARDWARE Hardware,
+ IN gctUINT32 ProcessID,
+ OUT gckCONTEXT * Context
+ );
+
+gceSTATUS
+gckCONTEXT_Destroy(
+ IN gckCONTEXT Context
+ );
+
+gceSTATUS
+gckCONTEXT_Update(
+ IN gckCONTEXT Context,
+ IN gctUINT32 ProcessID,
+ IN gcsSTATE_DELTA_PTR StateDelta
+ );
+
+gceSTATUS
+gckCONTEXT_MapBuffer(
+ IN gckCONTEXT Context,
+ OUT gctUINT32 *Physicals,
+ OUT gctUINT64 *Logicals,
+ OUT gctUINT32 *Bytes
+ );
+
+void
+gckQUEUE_Enqueue(
+ IN gckQUEUE LinkQueue,
+ IN gcuQUEUEDATA *Data
+ );
+
+void
+gckQUEUE_GetData(
+ IN gckQUEUE LinkQueue,
+ IN gctUINT32 Index,
+ OUT gcuQUEUEDATA ** Data
+ );
+
+gceSTATUS
+gckQUEUE_Allocate(
+ IN gckOS Os,
+ IN gckQUEUE Queue,
+ IN gctUINT32 Size
+ );
+
+gceSTATUS
+gckQUEUE_Free(
+ IN gckOS Os,
+ IN gckQUEUE Queue
+ );
+
+/******************************************************************************\
+****************************** gckRECORDER Object ******************************
+\******************************************************************************/
+gceSTATUS
+gckRECORDER_Construct(
+ IN gckOS Os,
+ IN gckHARDWARE Hardware,
+ OUT gckRECORDER * Recorder
+ );
+
+gceSTATUS
+gckRECORDER_Destory(
+ IN gckOS Os,
+ IN gckRECORDER Recorder
+ );
+
+void
+gckRECORDER_AdvanceIndex(
+ gckRECORDER Recorder,
+ gctUINT64 CommitStamp
+ );
+
+void
+gckRECORDER_Record(
+ gckRECORDER Recorder,
+ gctUINT8_PTR CommandBuffer,
+ gctUINT32 CommandBytes,
+ gctUINT8_PTR ContextBuffer,
+ gctUINT32 ContextBytes
+ );
+
+void
+gckRECORDER_Dump(
+ gckRECORDER Recorder
+ );
+
+gceSTATUS
+gckRECORDER_UpdateMirror(
+ gckRECORDER Recorder,
+ gctUINT32 State,
+ gctUINT32 Data
+ );
+
+/******************************************************************************\
+*************************** gckASYNC_COMMAND Object ****************************
+\******************************************************************************/
+gceSTATUS
+gckASYNC_COMMAND_Construct(
+ IN gckKERNEL Kernel,
+ OUT gckASYNC_COMMAND * Command
+ );
+
+gceSTATUS
+gckASYNC_COMMAND_Destroy(
+ IN gckASYNC_COMMAND Command
+ );
+
+gceSTATUS
+gckASYNC_COMMAND_Commit(
+ IN gckASYNC_COMMAND Command,
+ IN gcoCMDBUF CommandBuffer,
+ IN gcsQUEUE_PTR EventQueue
+ );
+
+gceSTATUS
+gckASYNC_COMMAND_EnterCommit(
+ IN gckASYNC_COMMAND Command
+ );
+
+gceSTATUS
+gckASYNC_COMMAND_ExitCommit(
+ IN gckASYNC_COMMAND Command
+ );
+
+gceSTATUS
+gckASYNC_COMMAND_Execute(
+ IN gckASYNC_COMMAND Command,
+ IN gctUINT32 Start,
+ IN gctUINT32 End
+ );
+
+void
+gcsLIST_Init(
+ gcsLISTHEAD_PTR Node
+ );
+
+void
+gcsLIST_Add(
+ gcsLISTHEAD_PTR New,
+ gcsLISTHEAD_PTR Head
+ );
+
+void
+gcsLIST_AddTail(
+ gcsLISTHEAD_PTR New,
+ gcsLISTHEAD_PTR Head
+ );
+
+void
+gcsLIST_Del(
+ gcsLISTHEAD_PTR Node
+ );
+
+gctBOOL
+gcsLIST_Empty(
+ gcsLISTHEAD_PTR Head
+ );
+
+#define gcmkLIST_FOR_EACH(pos, head) \
+ for (pos = (head)->next; pos != (head); pos = pos->next)
+
+#define gcmkLIST_FOR_EACH_SAFE(pos, n, head) \
+ for (pos = (head)->next, n = pos->next; pos != (head); \
+ pos = n, n = pos->next)
+
+gceSTATUS
+gckFENCE_Create(
+ IN gckOS Os,
+ IN gckKERNEL Kernel,
+ OUT gckFENCE * Fence
+ );
+
+gceSTATUS
+gckFENCE_Destory(
+ IN gckOS Os,
+ OUT gckFENCE Fence
+ );
+
+gceSTATUS
+gckFENCE_Signal(
+ IN gckOS Os,
+ IN gckFENCE Fence
+ );
+
+gceSTATUS
+gckDEVICE_Construct(
+ IN gckOS Os,
+ OUT gckDEVICE * Device
+ );
+
+gceSTATUS
+gckDEVICE_AddCore(
+ IN gckDEVICE Device,
+ IN gceCORE Core,
+ IN gctUINT chipID,
+ IN gctPOINTER Context,
+ IN gckKERNEL * Kernel
+ );
+
+gceSTATUS
+gckDEVICE_Destroy(
+ IN gckOS Os,
+ IN gckDEVICE Device
+ );
+
+gceSTATUS
+gckDEVICE_Dispatch(
+ IN gckDEVICE Device,
+ IN gcsHAL_INTERFACE_PTR Interface
+ );
+
+gceSTATUS
+gckDEVICE_GetMMU(
+ IN gckDEVICE Device,
+ IN gceHARDWARE_TYPE Type,
+ IN gckMMU *Mmu
+ );
+
+gceSTATUS
+gckDEVICE_SetMMU(
+ IN gckDEVICE Device,
+ IN gceHARDWARE_TYPE Type,
+ IN gckMMU Mmu
+ );
+
+gceSTATUS
+gckDEVICE_QueryGPUAddress(
+ IN gckDEVICE Device,
+ IN gckKERNEL Kernel,
+ IN gctUINT32 GPUAddress,
+ OUT gckVIRTUAL_COMMAND_BUFFER_PTR * Buffer
+ );
+
+#if gcdENABLE_TRUST_APPLICATION
+gceSTATUS
+gckKERNEL_MapInTrustApplicaiton(
+ IN gckKERNEL Kernel,
+ IN gctPOINTER Logical,
+ IN gctPHYS_ADDR Physical,
+ IN gctUINT32 GPUAddress,
+ IN gctSIZE_T PageCount
+ );
+#endif
+
+#if gcdSECURITY || gcdENABLE_TRUST_APPLICATION
+gceSTATUS
+gckOS_OpenSecurityChannel(
+ IN gckOS Os,
+ IN gceCORE Core,
+ OUT gctUINT32 *Channel
+ );
+
+gceSTATUS
+gckOS_CloseSecurityChannel(
+ IN gctUINT32 Channel
+ );
+
+gceSTATUS
+gckOS_CallSecurityService(
+ IN gctUINT32 Channel,
+ IN gcsTA_INTERFACE * Interface
+ );
+
+gceSTATUS
+gckOS_InitSecurityChannel(
+ OUT gctUINT32 Channel
+ );
+
+gceSTATUS
+gckOS_AllocatePageArray(
+ IN gckOS Os,
+ IN gctPHYS_ADDR Physical,
+ IN gctSIZE_T PageCount,
+ OUT gctPOINTER * PageArrayLogical,
+ OUT gctPHYS_ADDR * PageArrayPhysical
+ );
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __gc_hal_kernel_h_ */
diff --git a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_async_command.c b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_async_command.c
new file mode 100644
index 000000000000..2a0c5547215e
--- /dev/null
+++ b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_async_command.c
@@ -0,0 +1,477 @@
+/****************************************************************************
+*
+* The MIT License (MIT)
+*
+* Copyright (c) 2014 - 2018 Vivante 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 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 GPL License (GPL)
+*
+* Copyright (C) 2014 - 2018 Vivante 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.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+*****************************************************************************
+*
+* Note: This software is released under dual MIT and GPL licenses. A
+* recipient may use this file under the terms of either the MIT license or
+* GPL License. If you wish to use only one license not the other, you can
+* indicate your decision by deleting one of the above license notices in your
+* version of this file.
+*
+*****************************************************************************/
+
+
+#include "gc_hal_kernel_precomp.h"
+#include "gc_hal_kernel_context.h"
+
+#define _GC_OBJ_ZONE gcvZONE_ASYNC_COMMAND
+
+static gceSTATUS
+_HandlePatchList(
+ IN gckASYNC_COMMAND Command,
+ IN gcoCMDBUF CommandBuffer,
+ IN gctBOOL NeedCopy
+ )
+{
+ gceSTATUS status;
+ gcsPATCH_LIST * uList;
+ gcsPATCH_LIST * previous;
+ gcsPATCH_LIST * kList;
+
+ gcmkHEADER_ARG(
+ "Command=0x%x CommandBuffer=0x%x NeedCopy=%d",
+ Command, CommandBuffer, NeedCopy
+ );
+
+ uList = gcmUINT64_TO_PTR(CommandBuffer->patchHead);
+
+ while (uList)
+ {
+ gctUINT i;
+
+ kList = gcvNULL;
+ previous = uList;
+
+ gcmkONERROR(gckKERNEL_OpenUserData(
+ Command->kernel,
+ NeedCopy,
+ Command->kList,
+ uList,
+ gcmSIZEOF(gcsPATCH_LIST),
+ (gctPOINTER *)&kList
+ ));
+
+ for (i = 0; i < kList->count; i++)
+ {
+ gcsPATCH * patch = &kList->patch[i];
+
+ /* Touch video memory node. */
+ gcmkVERIFY_OK(gckVIDMEM_SetCommitStamp(Command->kernel, gcvENGINE_BLT, patch->handle, Command->commitStamp));
+ }
+
+ uList = kList->next;
+
+ gcmkVERIFY_OK(gckKERNEL_CloseUserData(
+ Command->kernel,
+ NeedCopy,
+ gcvFALSE,
+ previous,
+ gcmSIZEOF(gcsPATCH_LIST),
+ (gctPOINTER *)&kList
+ ));
+ }
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ if (kList)
+ {
+ gcmkVERIFY_OK(gckKERNEL_CloseUserData(
+ Command->kernel,
+ NeedCopy,
+ gcvFALSE,
+ previous,
+ gcmSIZEOF(gcsPATCH_LIST),
+ (gctPOINTER *)&kList
+ ));
+ }
+
+ gcmkFOOTER();
+ return status;
+}
+
+
+gceSTATUS
+gckASYNC_COMMAND_Construct(
+ IN gckKERNEL Kernel,
+ OUT gckASYNC_COMMAND * Command
+ )
+{
+ gceSTATUS status;
+ gckASYNC_COMMAND command;
+ gckOS os = Kernel->os;
+
+ gcmkHEADER();
+
+ /* Allocate gckASYNC_COMMAND object. */
+ gcmkONERROR(gckOS_Allocate(os, gcmSIZEOF(gcsASYNC_COMMAND), (gctPOINTER *)&command));
+
+ gckOS_ZeroMemory(command, gcmSIZEOF(gcsASYNC_COMMAND));
+
+ /* Mutex to protect gckFE. */
+ gcmkONERROR(gckOS_CreateMutex(os, &command->mutex));
+
+ /* Initialize gckFE. */
+ gckFE_Initialize(Kernel->hardware, &command->fe);
+
+ /* Initialize gckASYNC_COMMAND object. */
+ command->os = os;
+ command->kernel = Kernel;
+ command->hardware = Kernel->hardware;
+
+ gcmkVERIFY_OK(gckHARDWARE_QueryCommandBuffer(
+ Kernel->hardware,
+ gcvENGINE_BLT,
+ gcvNULL,
+ gcvNULL,
+ &command->reservedTail
+ ));
+
+ gcmkONERROR(gckFENCE_Create(
+ os, Kernel, &command->fence
+ ));
+
+ gcmkONERROR(gckOS_Allocate(os, gcmSIZEOF(gcsPATCH_LIST), &command->kList));
+
+ /* Commit stamp start from 1. */
+ command->commitStamp = 1;
+
+ *Command = command;
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ /* Rollback. */
+ gckASYNC_COMMAND_Destroy(command);
+
+ gcmkFOOTER();
+ return status;
+}
+
+gceSTATUS
+gckASYNC_COMMAND_Destroy(
+ IN gckASYNC_COMMAND Command
+ )
+{
+ gcmkHEADER();
+
+ if (Command)
+ {
+ if (Command->mutex)
+ {
+ gcmkVERIFY_OK(gckOS_DeleteMutex(Command->os, Command->mutex));
+ }
+
+ if (Command->fence)
+ {
+ gcmkVERIFY_OK(gckFENCE_Destory(Command->os, Command->fence));
+ }
+
+ if (Command->kList)
+ {
+ gcmkOS_SAFE_FREE(Command->os, Command->kList);
+ }
+
+ if (Command->fe.freeDscriptors)
+ {
+ gcmkOS_SAFE_FREE(Command->os, Command->fe.freeDscriptors);
+ }
+
+ gcmkOS_SAFE_FREE(Command->os, Command);
+ }
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+}
+
+gceSTATUS
+gckASYNC_COMMAND_Commit(
+ IN gckASYNC_COMMAND Command,
+ IN gcoCMDBUF CommandBuffer,
+ IN gcsQUEUE_PTR EventQueue
+ )
+{
+ gceSTATUS status;
+ gctBOOL available = gcvFALSE;
+ gctBOOL acquired = gcvFALSE;
+ gcoCMDBUF commandBufferObject = gcvNULL;
+ struct _gcoCMDBUF _commandBufferObject;
+ gctUINT8_PTR commandBufferLogical;
+ gctUINT8_PTR commandBufferTail;
+ gctUINT commandBufferSize;
+ gctUINT32 commandBufferAddress;
+ gcsFEDescriptor descriptor;
+ gctUINT32 skipFlushBytes;
+ gctUINT32 fenceBytes;
+ gctBOOL needCopy;
+ gctUINT32 oldValue;
+ gctUINT32 flushBytes;
+
+ gcmkHEADER();
+
+ gckOS_QueryNeedCopy(Command->os, 0, &needCopy);
+
+ gcmkVERIFY_OK(_HandlePatchList(Command, CommandBuffer, needCopy));
+
+ /* Open user passed gcoCMDBUF object. */
+ gcmkONERROR(gckKERNEL_OpenUserData(
+ Command->kernel,
+ needCopy,
+ &_commandBufferObject,
+ CommandBuffer,
+ gcmSIZEOF(struct _gcoCMDBUF),
+ (gctPOINTER *)&commandBufferObject
+ ));
+
+ gcmkVERIFY_OBJECT(commandBufferObject, gcvOBJ_COMMANDBUFFER);
+
+ gckHARDWARE_FlushAsyncMMU(Command->hardware, gcvNULL, &flushBytes);
+
+ gcmkONERROR(gckOS_AtomicExchange(Command->os,
+ Command->hardware->pageTableDirty[gcvENGINE_BLT],
+ 0,
+ &oldValue));
+
+ if (oldValue)
+ {
+ commandBufferLogical
+ = (gctUINT8_PTR) gcmUINT64_TO_PTR(commandBufferObject->logical)
+ + commandBufferObject->startOffset;
+
+ gckHARDWARE_FlushAsyncMMU(Command->hardware, commandBufferLogical, &flushBytes);
+
+ skipFlushBytes = 0;
+ }
+ else
+ {
+ skipFlushBytes = flushBytes;
+ }
+
+ /* Compute the command buffer entry and the size. */
+ commandBufferLogical
+ = (gctUINT8_PTR) gcmUINT64_TO_PTR(commandBufferObject->logical)
+ + commandBufferObject->startOffset
+ + skipFlushBytes;
+
+ commandBufferSize
+ = commandBufferObject->offset
+ + Command->reservedTail
+ - commandBufferObject->startOffset
+ - skipFlushBytes;
+
+ commandBufferTail
+ = commandBufferLogical
+ + commandBufferSize
+ - Command->reservedTail;
+
+ /* Get the hardware address. */
+ if (Command->kernel && Command->kernel->virtualCommandBuffer)
+ {
+ gckKERNEL kernel = Command->kernel;
+ gckVIRTUAL_COMMAND_BUFFER_PTR virtualCommandBuffer
+ = gcmNAME_TO_PTR(commandBufferObject->physical);
+
+ if (virtualCommandBuffer == gcvNULL)
+ {
+ gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
+ }
+
+ gcmkONERROR(gckKERNEL_GetGPUAddress(
+ Command->kernel,
+ commandBufferLogical,
+ gcvTRUE,
+ virtualCommandBuffer,
+ &commandBufferAddress
+ ));
+ }
+ else
+ {
+ gcmkONERROR(gckHARDWARE_ConvertLogical(
+ Command->hardware,
+ commandBufferLogical,
+ gcvTRUE,
+ &commandBufferAddress
+ ));
+ }
+
+ gcmkONERROR(gckHARDWARE_Fence(
+ Command->hardware,
+ gcvENGINE_BLT,
+ commandBufferTail,
+ Command->fence->address,
+ Command->commitStamp,
+ &fenceBytes
+ ));
+
+ descriptor.start = commandBufferAddress;
+ descriptor.end = commandBufferAddress + commandBufferSize;
+
+ gcmkDUMPCOMMAND(
+ Command->os,
+ commandBufferLogical,
+ commandBufferSize,
+ gcvDUMP_BUFFER_USER,
+ gcvFALSE
+ );
+
+ gckOS_AcquireMutex(Command->os, Command->mutex, gcvINFINITE);
+ acquired = gcvTRUE;
+
+ /* Acquire a slot. */
+ for(;;)
+ {
+ gcmkONERROR(gckFE_ReserveSlot(Command->hardware, &Command->fe, &available));
+
+ if (available)
+ {
+ break;
+ }
+ else
+ {
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, _GC_OBJ_ZONE, "No available slot, have to wait");
+
+ gckOS_Delay(Command->os, 1);
+ }
+ }
+
+ /* Send descriptor. */
+ gckFE_Execute(Command->hardware, &Command->fe, &descriptor);
+
+ Command->commitStamp++;
+
+ gckOS_ReleaseMutex(Command->os, Command->mutex);
+ acquired = gcvFALSE;
+
+ gcmkVERIFY_OK(gckKERNEL_CloseUserData(
+ Command->kernel,
+ needCopy,
+ gcvFALSE,
+ CommandBuffer,
+ gcmSIZEOF(struct _gcoCMDBUF),
+ (gctPOINTER *)&commandBufferObject
+ ));
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ if (acquired)
+ {
+ gckOS_ReleaseMutex(Command->os, Command->mutex);
+ }
+
+ if (commandBufferObject)
+ {
+ gcmkVERIFY_OK(gckKERNEL_CloseUserData(
+ Command->kernel,
+ needCopy,
+ gcvFALSE,
+ CommandBuffer,
+ gcmSIZEOF(struct _gcoCMDBUF),
+ (gctPOINTER *)&commandBufferObject
+ ));
+ }
+
+ gcmkFOOTER();
+ return status;
+}
+
+gceSTATUS
+gckASYNC_COMMAND_EnterCommit(
+ IN gckASYNC_COMMAND Command
+ )
+{
+ return gckOS_AcquireMutex(Command->os, Command->mutex, gcvINFINITE);
+}
+
+
+gceSTATUS
+gckASYNC_COMMAND_ExitCommit(
+ IN gckASYNC_COMMAND Command
+ )
+{
+ return gckOS_ReleaseMutex(Command->os, Command->mutex);
+}
+
+gceSTATUS
+gckASYNC_COMMAND_Execute(
+ IN gckASYNC_COMMAND Command,
+ IN gctUINT32 Start,
+ IN gctUINT32 End
+ )
+{
+ gceSTATUS status;
+ gcsFEDescriptor descriptor;
+ gctBOOL available;
+
+ descriptor.start = Start;
+ descriptor.end = End;
+
+ /* Acquire a slot. */
+ for(;;)
+ {
+ gcmkONERROR(gckFE_ReserveSlot(Command->hardware, &Command->fe, &available));
+
+ if (available)
+ {
+ break;
+ }
+ else
+ {
+ gckOS_Delay(Command->os, 1);
+ }
+ }
+
+ /* Send descriptor. */
+ gckFE_Execute(Command->hardware, &Command->fe, &descriptor);
+
+ return gcvSTATUS_OK;
+
+OnError:
+ return status;
+}
+
diff --git a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_command.c b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_command.c
new file mode 100644
index 000000000000..a5e81c229ed5
--- /dev/null
+++ b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_command.c
@@ -0,0 +1,3472 @@
+/****************************************************************************
+*
+* The MIT License (MIT)
+*
+* Copyright (c) 2014 - 2018 Vivante 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 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 GPL License (GPL)
+*
+* Copyright (C) 2014 - 2018 Vivante 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.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+*****************************************************************************
+*
+* Note: This software is released under dual MIT and GPL licenses. A
+* recipient may use this file under the terms of either the MIT license or
+* GPL License. If you wish to use only one license not the other, you can
+* indicate your decision by deleting one of the above license notices in your
+* version of this file.
+*
+*****************************************************************************/
+
+
+#include "gc_hal_kernel_precomp.h"
+#include "gc_hal_kernel_context.h"
+
+#define _GC_OBJ_ZONE gcvZONE_COMMAND
+
+/******************************************************************************\
+********************************* Support Code *********************************
+\******************************************************************************/
+
+/*******************************************************************************
+**
+** _NewQueue
+**
+** Allocate a new command queue.
+**
+** INPUT:
+**
+** gckCOMMAND Command
+** Pointer to an gckCOMMAND object.
+**
+** gctBOOL Stalled
+** Indicate if hardware is stalled already.
+**
+** OUTPUT:
+**
+** gckCOMMAND Command
+** gckCOMMAND object has been updated with a new command queue.
+*/
+gceSTATUS
+_NewQueue(
+ IN OUT gckCOMMAND Command,
+ IN gctBOOL Stalled
+ )
+{
+ gceSTATUS status;
+ gctINT currentIndex, newIndex;
+ gctPHYS_ADDR_T physical;
+
+ gcmkHEADER_ARG("Command=0x%x", Command);
+
+ /* Switch to the next command buffer. */
+ currentIndex = Command->index;
+ newIndex = (currentIndex + 1) % gcdCOMMAND_QUEUES;
+
+ /* Wait for availability. */
+#if gcdDUMP_COMMAND
+ gcmkPRINT("@[kernel.waitsignal]");
+#endif
+
+ gcmkONERROR(gckOS_WaitSignal(
+ Command->os,
+ Command->queues[newIndex].signal,
+ gcvFALSE,
+ gcvINFINITE
+ ));
+
+#if gcmIS_DEBUG(gcdDEBUG_TRACE)
+ if (newIndex < currentIndex)
+ {
+ Command->wrapCount += 1;
+
+ gcmkTRACE_ZONE_N(
+ gcvLEVEL_INFO, gcvZONE_COMMAND,
+ 2 * 4,
+ "%s(%d): queue array wrapped around.\n",
+ __FUNCTION__, __LINE__
+ );
+ }
+
+ gcmkTRACE_ZONE_N(
+ gcvLEVEL_INFO, gcvZONE_COMMAND,
+ 3 * 4,
+ "%s(%d): total queue wrap arounds %d.\n",
+ __FUNCTION__, __LINE__, Command->wrapCount
+ );
+
+ gcmkTRACE_ZONE_N(
+ gcvLEVEL_INFO, gcvZONE_COMMAND,
+ 3 * 4,
+ "%s(%d): switched to queue %d.\n",
+ __FUNCTION__, __LINE__, newIndex
+ );
+#endif
+
+ /* Update gckCOMMAND object with new command queue. */
+ Command->index = newIndex;
+ Command->newQueue = gcvTRUE;
+#if USE_KERNEL_VIRTUAL_BUFFERS
+ if (Command->kernel->virtualCommandBuffer)
+ {
+ gckVIRTUAL_COMMAND_BUFFER_PTR commandBuffer = gcvNULL;
+
+ Command->virtualMemory = Command->queues[newIndex].physical;
+
+ commandBuffer = (gckVIRTUAL_COMMAND_BUFFER_PTR) Command->virtualMemory;
+
+ Command->physHandle = commandBuffer->virtualBuffer.physical;
+ }
+ else
+#endif
+ {
+ Command->physHandle = Command->queues[newIndex].physical;
+ }
+
+ Command->logical = Command->queues[newIndex].logical;
+ Command->address = Command->queues[newIndex].address;
+ Command->offset = 0;
+
+ gcmkONERROR(gckOS_GetPhysicalAddress(
+ Command->os,
+ Command->logical,
+ &physical
+ ));
+
+ gcmkVERIFY_OK(gckOS_CPUPhysicalToGPUPhysical(
+ Command->os,
+ physical,
+ &physical
+ ));
+
+ gcmkSAFECASTPHYSADDRT(Command->physical, physical);
+
+ if (currentIndex != -1)
+ {
+ if (Stalled)
+ {
+ gckOS_Signal(
+ Command->os,
+ Command->queues[currentIndex].signal,
+ gcvTRUE
+ );
+ }
+ else
+ {
+ /* Mark the command queue as available. */
+ gcmkONERROR(gckEVENT_Signal(
+ Command->kernel->eventObj,
+ Command->queues[currentIndex].signal,
+ gcvKERNEL_COMMAND
+ ));
+ }
+ }
+
+ /* Success. */
+ gcmkFOOTER_ARG("Command->index=%d", Command->index);
+ return gcvSTATUS_OK;
+
+OnError:
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+gceSTATUS
+_IncrementCommitAtom(
+ IN gckCOMMAND Command,
+ IN gctBOOL Increment
+ )
+{
+ gceSTATUS status;
+ gckHARDWARE hardware;
+ gctINT32 atomValue;
+ gctBOOL powerAcquired = gcvFALSE;
+
+ gcmkHEADER_ARG("Command=0x%x", Command);
+
+ /* Extract the gckHARDWARE and gckEVENT objects. */
+ hardware = Command->kernel->hardware;
+ gcmkVERIFY_OBJECT(hardware, gcvOBJ_HARDWARE);
+
+ /* Grab the power mutex. */
+ gcmkONERROR(gckOS_AcquireMutex(
+ Command->os, hardware->powerMutex, gcvINFINITE
+ ));
+ powerAcquired = gcvTRUE;
+
+ /* Increment the commit atom. */
+ if (Increment)
+ {
+ gcmkONERROR(gckOS_AtomIncrement(
+ Command->os, Command->atomCommit, &atomValue
+ ));
+ }
+ else
+ {
+ gcmkONERROR(gckOS_AtomDecrement(
+ Command->os, Command->atomCommit, &atomValue
+ ));
+ }
+
+ /* Release the power mutex. */
+ gcmkONERROR(gckOS_ReleaseMutex(
+ Command->os, hardware->powerMutex
+ ));
+ powerAcquired = gcvFALSE;
+
+ /* Success. */
+ gcmkFOOTER();
+ return gcvSTATUS_OK;
+
+OnError:
+ if (powerAcquired)
+ {
+ /* Release the power mutex. */
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(
+ Command->os, hardware->powerMutex
+ ));
+ }
+
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+#if gcdSECURE_USER
+gceSTATUS
+_ProcessHints(
+ IN gckCOMMAND Command,
+ IN gctUINT32 ProcessID,
+ IN gcoCMDBUF CommandBuffer
+ )
+{
+ gceSTATUS status = gcvSTATUS_OK;
+ gckKERNEL kernel;
+ gctBOOL needCopy = gcvFALSE;
+ gcskSECURE_CACHE_PTR cache;
+ gctUINT8_PTR commandBufferLogical;
+ gctUINT8_PTR hintedData;
+ gctUINT32_PTR hintArray;
+ gctUINT i, hintCount;
+
+ gcmkHEADER_ARG(
+ "Command=0x%08X ProcessID=%d CommandBuffer=0x%08X",
+ Command, ProcessID, CommandBuffer
+ );
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Command, gcvOBJ_COMMAND);
+
+ /* Reset state array pointer. */
+ hintArray = gcvNULL;
+
+ /* Get the kernel object. */
+ kernel = Command->kernel;
+
+ /* Get the cache form the database. */
+ gcmkONERROR(gckKERNEL_GetProcessDBCache(kernel, ProcessID, &cache));
+
+ /* Determine the start of the command buffer. */
+ commandBufferLogical
+ = (gctUINT8_PTR) CommandBuffer->logical
+ + CommandBuffer->startOffset;
+
+ /* Determine the number of records in the state array. */
+ hintCount = CommandBuffer->hintArrayTail - CommandBuffer->hintArray;
+
+ /* Check wehther we need to copy the structures or not. */
+ gcmkONERROR(gckOS_QueryNeedCopy(Command->os, ProcessID, &needCopy));
+
+ /* Get access to the state array. */
+ if (needCopy)
+ {
+ gctUINT copySize;
+
+ if (Command->hintArrayAllocated &&
+ (Command->hintArraySize < CommandBuffer->hintArraySize))
+ {
+ gcmkONERROR(gcmkOS_SAFE_FREE(Command->os, gcmUINT64_TO_PTR(Command->hintArray)));
+ Command->hintArraySize = gcvFALSE;
+ }
+
+ if (!Command->hintArrayAllocated)
+ {
+ gctPOINTER pointer = gcvNULL;
+
+ gcmkONERROR(gckOS_Allocate(
+ Command->os,
+ CommandBuffer->hintArraySize,
+ &pointer
+ ));
+
+ Command->hintArray = gcmPTR_TO_UINT64(pointer);
+ Command->hintArrayAllocated = gcvTRUE;
+ Command->hintArraySize = CommandBuffer->hintArraySize;
+ }
+
+ hintArray = gcmUINT64_TO_PTR(Command->hintArray);
+ copySize = hintCount * gcmSIZEOF(gctUINT32);
+
+ gcmkONERROR(gckOS_CopyFromUserData(
+ Command->os,
+ hintArray,
+ gcmUINT64_TO_PTR(CommandBuffer->hintArray),
+ copySize
+ ));
+ }
+ else
+ {
+ gctPOINTER pointer = gcvNULL;
+
+ gcmkONERROR(gckOS_MapUserPointer(
+ Command->os,
+ gcmUINT64_TO_PTR(CommandBuffer->hintArray),
+ CommandBuffer->hintArraySize,
+ &pointer
+ ));
+
+ hintArray = pointer;
+ }
+
+ /* Scan through the buffer. */
+ for (i = 0; i < hintCount; i += 1)
+ {
+ /* Determine the location of the hinted data. */
+ hintedData = commandBufferLogical + hintArray[i];
+
+ /* Map handle into physical address. */
+ gcmkONERROR(gckKERNEL_MapLogicalToPhysical(
+ kernel, cache, (gctPOINTER) hintedData
+ ));
+ }
+
+OnError:
+ /* Get access to the state array. */
+ if (!needCopy && (hintArray != gcvNULL))
+ {
+ gcmkVERIFY_OK(gckOS_UnmapUserPointer(
+ Command->os,
+ gcmUINT64_TO_PTR(CommandBuffer->hintArray),
+ CommandBuffer->hintArraySize,
+ hintArray
+ ));
+ }
+
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+#endif
+
+#if !gcdNULL_DRIVER
+gceSTATUS
+_FlushMMU(
+ IN gckCOMMAND Command
+ )
+{
+#if gcdSECURITY
+ return gcvSTATUS_OK;
+#else
+ gceSTATUS status;
+ gctUINT32 oldValue;
+ gckHARDWARE hardware = Command->kernel->hardware;
+ gctBOOL pause = gcvFALSE;
+
+ gctUINT8_PTR pointer;
+ gctUINT32 address;
+ gctUINT32 eventBytes;
+ gctUINT32 endBytes;
+ gctUINT32 bufferSize;
+ gctUINT32 executeBytes;
+ gctUINT32 waitLinkBytes;
+
+ gcmkONERROR(gckOS_AtomicExchange(Command->os,
+ hardware->pageTableDirty[gcvENGINE_RENDER],
+ 0,
+ &oldValue));
+
+ if (oldValue)
+ {
+ /* Page Table is upated, flush mmu before commit. */
+ gcmkONERROR(gckHARDWARE_FlushMMU(hardware));
+
+ if ((oldValue & gcvPAGE_TABLE_DIRTY_BIT_FE)
+ && (!hardware->stallFEPrefetch)
+ )
+ {
+ pause = gcvTRUE;
+ }
+ }
+
+ if (pause)
+ {
+ /* Query size. */
+ gcmkONERROR(gckHARDWARE_Event(hardware, gcvNULL, 0, gcvKERNEL_PIXEL, &eventBytes));
+ gcmkONERROR(gckHARDWARE_End(hardware, gcvNULL, ~0U, &endBytes));
+
+ executeBytes = eventBytes + endBytes;
+
+ gcmkONERROR(gckHARDWARE_WaitLink(
+ hardware,
+ gcvNULL,
+ ~0U,
+ Command->offset + executeBytes,
+ &waitLinkBytes,
+ gcvNULL,
+ gcvNULL
+ ));
+
+ /* Reserve space. */
+ gcmkONERROR(gckCOMMAND_Reserve(
+ Command,
+ executeBytes,
+ (gctPOINTER *)&pointer,
+ &bufferSize
+ ));
+
+ /* Pointer to reserved address. */
+ address = Command->address + Command->offset;
+
+ /* Append EVENT(29). */
+ gcmkONERROR(gckHARDWARE_Event(
+ hardware,
+ pointer,
+ 29,
+ gcvKERNEL_PIXEL,
+ &eventBytes
+ ));
+
+ /* Append END. */
+ pointer += eventBytes;
+ address += eventBytes;
+
+ gcmkONERROR(gckHARDWARE_End(hardware, pointer, address, &endBytes));
+
+#if USE_KERNEL_VIRTUAL_BUFFERS
+ if (hardware->kernel->virtualCommandBuffer)
+ {
+ gcmkONERROR(gckKERNEL_GetGPUAddress(
+ hardware->kernel,
+ pointer,
+ gcvFALSE,
+ Command->virtualMemory,
+ &hardware->lastEnd
+ ));
+ }
+#endif
+
+ gcmkONERROR(gckCOMMAND_Execute(Command, executeBytes));
+ }
+
+ return gcvSTATUS_OK;
+OnError:
+ return status;
+#endif
+}
+
+gceSTATUS
+_DummyDraw(
+ IN gckCOMMAND Command
+ )
+{
+#if gcdSECURITY
+ return gcvSTATUS_OK;
+#else
+ gceSTATUS status;
+ gckHARDWARE hardware = Command->kernel->hardware;
+
+ gctUINT8_PTR pointer;
+ gctUINT32 bufferSize;
+
+ gctUINT32 dummyDrawBytes;
+ gceDUMMY_DRAW_TYPE dummyDrawType = gcvDUMMY_DRAW_INVALID;
+
+ if (gckHARDWARE_IsFeatureAvailable(hardware, gcvFEATURE_FE_NEED_DUMMYDRAW))
+ {
+ dummyDrawType = gcvDUMMY_DRAW_GC400;
+ }
+
+ if (!gckHARDWARE_IsFeatureAvailable(hardware, gcvFEATURE_USC_DEFER_FILL_FIX) &&
+ gckHARDWARE_IsFeatureAvailable(hardware, gcvFEATURE_USC))
+ {
+ dummyDrawType = gcvDUMMY_DRAW_V60;
+ }
+
+ if (dummyDrawType != gcvDUMMY_DRAW_INVALID)
+ {
+ gckHARDWARE_DummyDraw(hardware, gcvNULL, Command->queues[0].address, dummyDrawType, &dummyDrawBytes);
+
+ /* Reserve space. */
+ gcmkONERROR(gckCOMMAND_Reserve(
+ Command,
+ dummyDrawBytes,
+ (gctPOINTER *)&pointer,
+ &bufferSize
+ ));
+
+ gckHARDWARE_DummyDraw(hardware, pointer, Command->queues[0].address, dummyDrawType, &dummyDrawBytes);
+
+ gcmkONERROR(gckCOMMAND_Execute(Command, dummyDrawBytes));
+ }
+
+ return gcvSTATUS_OK;
+OnError:
+ return status;
+#endif
+}
+
+#endif
+
+static void
+_DumpBuffer(
+ IN gctPOINTER Buffer,
+ IN gctUINT32 GpuAddress,
+ IN gctSIZE_T Size
+ )
+{
+ gctSIZE_T i, line, left;
+ gctUINT32_PTR data = Buffer;
+
+ line = Size / 32;
+ left = Size % 32;
+
+ for (i = 0; i < line; i++)
+ {
+ gcmkPRINT("%08X : %08X %08X %08X %08X %08X %08X %08X %08X",
+ GpuAddress, data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7]);
+ data += 8;
+ GpuAddress += 8 * 4;
+ }
+
+ switch(left)
+ {
+ case 28:
+ gcmkPRINT("%08X : %08X %08X %08X %08X %08X %08X %08X",
+ GpuAddress, data[0], data[1], data[2], data[3], data[4], data[5], data[6]);
+ break;
+ case 24:
+ gcmkPRINT("%08X : %08X %08X %08X %08X %08X %08X",
+ GpuAddress, data[0], data[1], data[2], data[3], data[4], data[5]);
+ break;
+ case 20:
+ gcmkPRINT("%08X : %08X %08X %08X %08X %08X",
+ GpuAddress, data[0], data[1], data[2], data[3], data[4]);
+ break;
+ case 16:
+ gcmkPRINT("%08X : %08X %08X %08X %08X",
+ GpuAddress, data[0], data[1], data[2], data[3]);
+ break;
+ case 12:
+ gcmkPRINT("%08X : %08X %08X %08X",
+ GpuAddress, data[0], data[1], data[2]);
+ break;
+ case 8:
+ gcmkPRINT("%08X : %08X %08X",
+ GpuAddress, data[0], data[1]);
+ break;
+ case 4:
+ gcmkPRINT("%08X : %08X",
+ GpuAddress, data[0]);
+ break;
+ default:
+ break;
+ }
+}
+
+void
+_DumpKernelCommandBuffer(
+ IN gckCOMMAND Command
+ )
+{
+ gctINT i;
+ gctUINT64 physical = 0;
+ gctUINT32 address;
+ gctPOINTER entry = gcvNULL;
+
+ for (i = 0; i < gcdCOMMAND_QUEUES; i++)
+ {
+ entry = Command->queues[i].logical;
+
+ gckOS_GetPhysicalAddress(Command->os, entry, &physical);
+
+ gckOS_CPUPhysicalToGPUPhysical(Command->os, physical, &physical);
+
+ gcmkPRINT("Kernel command buffer %d\n", i);
+
+ gcmkSAFECASTPHYSADDRT(address, physical);
+
+ _DumpBuffer(entry, address, Command->pageSize);
+ }
+}
+
+#if !gcdNULL_DRIVER
+gceSTATUS
+_HandlePatchList(
+ IN gckCOMMAND Command,
+ IN gcoCMDBUF CommandBuffer,
+ IN gctBOOL NeedCopy,
+ OUT gctUINT64 *AsyncCommandStamp
+ )
+{
+ gceSTATUS status;
+ gcsPATCH_LIST * uList;
+ gcsPATCH_LIST * previous;
+ gcsPATCH_LIST * kList;
+ gctUINT64 asyncStamp = 0;
+
+ gcmkHEADER_ARG(
+ "Command=0x%x CommandBuffer=0x%x NeedCopy=%d",
+ Command, CommandBuffer, NeedCopy
+ );
+
+ uList = gcmUINT64_TO_PTR(CommandBuffer->patchHead);
+
+ while (uList)
+ {
+ gctUINT i;
+
+ kList = gcvNULL;
+ previous = uList;
+
+ gcmkONERROR(gckKERNEL_OpenUserData(
+ Command->kernel,
+ NeedCopy,
+ Command->kList,
+ uList,
+ gcmSIZEOF(gcsPATCH_LIST),
+ (gctPOINTER *)&kList
+ ));
+
+ for (i = 0; i < kList->count; i++)
+ {
+ gctUINT64 stamp = 0;
+ gcsPATCH * patch = &kList->patch[i];
+
+ /* Touch video memory node. */
+ gcmkVERIFY_OK(gckVIDMEM_SetCommitStamp(Command->kernel, gcvENGINE_RENDER, patch->handle, Command->commitStamp));
+
+ /* Get stamp touched async command buffer. */
+ gcmkVERIFY_OK(gckVIDMEM_GetCommitStamp(Command->kernel, gcvENGINE_BLT, patch->handle, &stamp));
+
+ /* Find latest one. */
+ asyncStamp = gcmMAX(asyncStamp, stamp);
+ }
+
+ uList = kList->next;
+
+ gcmkVERIFY_OK(gckKERNEL_CloseUserData(
+ Command->kernel,
+ NeedCopy,
+ gcvFALSE,
+ previous,
+ gcmSIZEOF(gcsPATCH_LIST),
+ (gctPOINTER *)&kList
+ ));
+ }
+
+ if ((Command->asyncCommand != gcvNULL)
+ && (*(gctUINT64 *)Command->asyncCommand->fence->logical > asyncStamp)
+ )
+ {
+ /* No need to wait for async command buffer. */
+ *AsyncCommandStamp = 0;
+ }
+ else
+ {
+ /* Need to add a fence wait. */
+ *AsyncCommandStamp = asyncStamp;
+ }
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ if (kList)
+ {
+ gcmkVERIFY_OK(gckKERNEL_CloseUserData(
+ Command->kernel,
+ NeedCopy,
+ gcvFALSE,
+ previous,
+ gcmSIZEOF(gcsPATCH_LIST),
+ (gctPOINTER *)&kList
+ ));
+ }
+
+ gcmkFOOTER();
+ return status;
+}
+
+gceSTATUS
+_WaitForAsyncCommandStamp(
+ IN gckCOMMAND Command,
+ IN gctUINT64 Stamp
+ )
+{
+ gctUINT32 bytes;
+ gceSTATUS status;
+ gctUINT32 fenceAddress;
+ gctUINT32 bufferSize;
+ gctPOINTER pointer;
+ gcmkHEADER_ARG("Stamp = 0x%llx", Stamp);
+
+ fenceAddress = Command->asyncCommand->fence->address;
+
+ gcmkONERROR(gckHARDWARE_WaitFence(Command->kernel->hardware,
+ gcvNULL,
+ Stamp,
+ fenceAddress,
+ &bytes
+ ));
+
+ gcmkONERROR(gckCOMMAND_Reserve(
+ Command,
+ bytes,
+ &pointer,
+ &bufferSize
+ ));
+
+ gcmkONERROR(gckHARDWARE_WaitFence(
+ Command->kernel->hardware,
+ pointer,
+ Stamp,
+ fenceAddress,
+ &bytes
+ ));
+
+ gcmkONERROR(gckCOMMAND_Execute(Command, bytes));
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ gcmkFOOTER();
+ return status;
+}
+
+/******************************************************************************\
+**************** Helper functions for parsing gcoCMDBUF ************************
+\******************************************************************************/
+static void
+_GetCMDBUFSize(
+ IN gcoCMDBUF CommandBuffer,
+ OUT gctUINT_PTR CommandBufferSize
+ )
+{
+ *CommandBufferSize
+ = CommandBuffer->offset
+ + CommandBuffer->reservedTail
+ - CommandBuffer->startOffset;
+}
+
+static void
+_GetCMDBUFTail(
+ IN gcoCMDBUF CommandBuffer,
+ OUT gctUINT8_PTR * Tail
+ )
+{
+ gctUINT8_PTR commandBufferLogical;
+ gctUINT commandBufferSize;
+
+ commandBufferLogical
+ = (gctUINT8_PTR) gcmUINT64_TO_PTR(CommandBuffer->logical)
+ + CommandBuffer->startOffset;
+
+ _GetCMDBUFSize(CommandBuffer, &commandBufferSize);
+
+ *Tail
+ = commandBufferLogical
+ + commandBufferSize
+ - CommandBuffer->reservedTail;
+}
+
+static void
+_ParseCMDBUFTail(
+ IN gckHARDWARE Hardware,
+ IN gcoCMDBUF CommandBuffer,
+ OUT gctUINT8_PTR * Fence,
+ OUT gctUINT8_PTR * Link
+ )
+{
+ gctUINT8_PTR tail;
+
+ _GetCMDBUFTail(CommandBuffer, &tail);
+
+ if (gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_FENCE_64BIT))
+ {
+ *Fence = tail;
+ *Link = tail + gcdRENDER_FENCE_LENGTH;
+ }
+ else
+ {
+ *Fence = gcvNULL;
+ *Link = tail;
+ }
+}
+
+gceSTATUS
+_GetCMDBUFEntry(
+ IN gckCOMMAND Command,
+ IN gcoCMDBUF CommandBuffer,
+ OUT gctUINT32_PTR EntryAddress,
+ OUT gctUINT32_PTR EntryBytes
+ )
+{
+ gceSTATUS status;
+ gctUINT8_PTR commandBufferLogical;
+ gctUINT commandBufferSize;
+ gckVIRTUAL_COMMAND_BUFFER_PTR virtualCommandBuffer;
+ gctUINT32 commandBufferAddress;
+ gctUINT offset;
+
+ commandBufferLogical
+ = (gctUINT8_PTR) gcmUINT64_TO_PTR(CommandBuffer->logical)
+ + CommandBuffer->startOffset;
+
+ /* Get the hardware address. */
+ if (Command->kernel->virtualCommandBuffer)
+ {
+ gckKERNEL kernel = Command->kernel;
+
+ virtualCommandBuffer = gcmNAME_TO_PTR(CommandBuffer->physical);
+
+ if (virtualCommandBuffer == gcvNULL)
+ {
+ gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
+ }
+
+ gcmkONERROR(gckKERNEL_GetGPUAddress(
+ Command->kernel,
+ commandBufferLogical,
+ gcvTRUE,
+ virtualCommandBuffer,
+ &commandBufferAddress
+ ));
+ }
+ else
+ {
+ gcmkONERROR(gckHARDWARE_ConvertLogical(
+ Command->kernel->hardware,
+ commandBufferLogical,
+ gcvTRUE,
+ &commandBufferAddress
+ ));
+ }
+
+ /* Get offset. */
+ gcmkONERROR(gckHARDWARE_PipeSelect(
+ Command->kernel->hardware, gcvNULL, gcvPIPE_3D, &offset
+ ));
+
+ _GetCMDBUFSize(CommandBuffer, &commandBufferSize);
+
+ *EntryAddress = commandBufferAddress + offset;
+ *EntryBytes = commandBufferSize - offset;
+
+ return gcvSTATUS_OK;
+
+OnError:
+ return status;
+}
+
+/*******************************************************************************
+**
+** Link a list of command buffer together to make them atomic.
+** Fence will be added in the last command buffer.
+*/
+gceSTATUS
+_ProcessUserCommandBufferList(
+ IN gckCOMMAND Command,
+ IN gcoCMDBUF CommandBufferListHead,
+ OUT gcoCMDBUF * CommandBufferListTail
+ )
+{
+ gceSTATUS status;
+ gctBOOL needCopy;
+
+ gcoCMDBUF currentCMDBUF;
+ gcoCMDBUF currentCMDBUFUser = CommandBufferListHead;
+
+ gckOS_QueryNeedCopy(Command->os, 0, &needCopy);
+
+ /* Open first gcoCMDBUF object as currentCMDBUF. */
+ gcmkONERROR(gckKERNEL_OpenUserData(
+ Command->kernel,
+ needCopy,
+ &Command->_commandBufferObject,
+ currentCMDBUFUser,
+ gcmSIZEOF(struct _gcoCMDBUF),
+ (gctPOINTER *)&currentCMDBUF
+ ));
+
+ /* Iterate the list. */
+ while (currentCMDBUF->nextCMDBUF != 0)
+ {
+ gcoCMDBUF nextCMDBUFUser;
+ gcoCMDBUF nextCMDBUF;
+ gctUINT8_PTR fenceLogical = gcvNULL;
+ gctUINT8_PTR linkLogical;
+ gctUINT32 linkBytes = 8;
+ gctUINT32 linkLow;
+ gctUINT32 linkHigh;
+
+ gctUINT32 entryAddress = 0;
+ gctUINT32 entryBytes = 0;
+
+ nextCMDBUFUser
+ = gcmUINT64_TO_PTR(currentCMDBUF->nextCMDBUF);
+
+ /* Open next gcoCMDBUF object as nextCMDBUF. */
+ gcmkONERROR(gckKERNEL_OpenUserData(
+ Command->kernel,
+ needCopy,
+ &Command->_nextCMDBUF,
+ nextCMDBUFUser,
+ gcmSIZEOF(struct _gcoCMDBUF),
+ (gctPOINTER *)&nextCMDBUF
+ ));
+
+ /* Get the start hardware address of nextCMDBUF. */
+ gcmkONERROR(_GetCMDBUFEntry(Command,
+ nextCMDBUF,
+ &entryAddress,
+ &entryBytes
+ ));
+
+ /* Process current gcoCMDBUF object. */
+ _ParseCMDBUFTail(
+ Command->kernel->hardware,
+ currentCMDBUF,
+ &fenceLogical,
+ &linkLogical
+ );
+
+ /* Don't send fence in the middle of gcoCMDBUF list. */
+ if (fenceLogical != gcvNULL)
+ {
+ gctUINT i = gcdRENDER_FENCE_LENGTH / gcmSIZEOF(gctUINT32) / 2;
+
+ /* Fill NOPs in space reserved for fence. */
+ while (i--)
+ {
+ gctSIZE_T nopBytes = 8;
+ gcmkONERROR(gckHARDWARE_Nop(Command->kernel->hardware, fenceLogical, &nopBytes));
+ fenceLogical += nopBytes;
+ }
+ }
+
+ /* Generate a LINK from the end of current command buffer
+ ** to the start of next command buffer. */
+ gcmkONERROR(gckHARDWARE_Link(
+ Command->kernel->hardware,
+ linkLogical,
+ entryAddress,
+ entryBytes,
+ &linkBytes,
+ &linkLow,
+ &linkHigh
+ ));
+
+ /* Close current gcoCMDBUF object which is processed. */
+ gcmkVERIFY_OK(gckKERNEL_CloseUserData(
+ Command->kernel,
+ needCopy,
+ gcvFALSE,
+ currentCMDBUFUser,
+ gcmSIZEOF(struct _gcoCMDBUF),
+ (gctPOINTER *)&currentCMDBUF
+ ));
+
+ /* Advance to next gcoCMDBUF object. */
+ currentCMDBUFUser = nextCMDBUFUser;
+ currentCMDBUF = nextCMDBUF;
+ }
+
+ gcmkVERIFY_OK(gckKERNEL_CloseUserData(
+ Command->kernel,
+ needCopy,
+ gcvFALSE,
+ currentCMDBUFUser,
+ gcmSIZEOF(struct _gcoCMDBUF),
+ (gctPOINTER *)&currentCMDBUF
+ ));
+
+ /* Return the tail of the list. */
+ *CommandBufferListTail = currentCMDBUFUser;
+
+ return gcvSTATUS_OK;
+
+OnError:
+ return status;
+}
+#endif
+
+/******************************************************************************\
+****************************** gckCOMMAND API Code ******************************
+\******************************************************************************/
+
+/*******************************************************************************
+**
+** gckCOMMAND_Construct
+**
+** Construct a new gckCOMMAND object.
+**
+** INPUT:
+**
+** gckKERNEL Kernel
+** Pointer to an gckKERNEL object.
+**
+** OUTPUT:
+**
+** gckCOMMAND * Command
+** Pointer to a variable that will hold the pointer to the gckCOMMAND
+** object.
+*/
+gceSTATUS
+gckCOMMAND_Construct(
+ IN gckKERNEL Kernel,
+ OUT gckCOMMAND * Command
+ )
+{
+ gckOS os;
+ gckCOMMAND command = gcvNULL;
+ gceSTATUS status;
+ gctINT i;
+ gctPOINTER pointer = gcvNULL;
+ gctSIZE_T pageSize;
+
+ gcmkHEADER_ARG("Kernel=0x%x", Kernel);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
+ gcmkVERIFY_ARGUMENT(Command != gcvNULL);
+
+ /* Extract the gckOS object. */
+ os = Kernel->os;
+
+ /* Allocate the gckCOMMAND structure. */
+ gcmkONERROR(gckOS_Allocate(os, gcmSIZEOF(struct _gckCOMMAND), &pointer));
+ command = pointer;
+
+ /* Reset the entire object. */
+ gcmkONERROR(gckOS_ZeroMemory(command, gcmSIZEOF(struct _gckCOMMAND)));
+
+ /* Initialize the gckCOMMAND object.*/
+ command->object.type = gcvOBJ_COMMAND;
+ command->kernel = Kernel;
+ command->os = os;
+
+ /* Get the command buffer requirements. */
+ gcmkONERROR(gckHARDWARE_QueryCommandBuffer(
+ Kernel->hardware,
+ gcvENGINE_RENDER,
+ &command->alignment,
+ &command->reservedHead,
+ gcvNULL
+ ));
+
+ /* Create the command queue mutex. */
+ gcmkONERROR(gckOS_CreateMutex(os, &command->mutexQueue));
+
+ /* Create the context switching mutex. */
+ gcmkONERROR(gckOS_CreateMutex(os, &command->mutexContext));
+
+ /* Create the context switching mutex. */
+ gcmkONERROR(gckOS_CreateMutex(os, &command->mutexContextSeq));
+
+ /* Create the power management semaphore. */
+ gcmkONERROR(gckOS_CreateSemaphore(os, &command->powerSemaphore));
+
+ /* Create the commit atom. */
+ gcmkONERROR(gckOS_AtomConstruct(os, &command->atomCommit));
+
+ /* Get the page size from teh OS. */
+ gcmkONERROR(gckOS_GetPageSize(os, &pageSize));
+
+ gcmkSAFECASTSIZET(command->pageSize, pageSize);
+
+ /* Get process ID. */
+ gcmkONERROR(gckOS_GetProcessID(&command->kernelProcessID));
+
+ /* Set hardware to pipe 0. */
+ command->pipeSelect = gcvPIPE_INVALID;
+
+ /* Pre-allocate the command queues. */
+ for (i = 0; i < gcdCOMMAND_QUEUES; ++i)
+ {
+#if USE_KERNEL_VIRTUAL_BUFFERS
+ if (Kernel->virtualCommandBuffer)
+ {
+ gcmkONERROR(gckKERNEL_AllocateVirtualCommandBuffer(
+ Kernel,
+ gcvFALSE,
+ &pageSize,
+ &command->queues[i].physical,
+ &command->queues[i].logical
+ ));
+
+ gcmkONERROR(gckKERNEL_GetGPUAddress(
+ Kernel,
+ command->queues[i].logical,
+ gcvFALSE,
+ command->queues[i].physical,
+ &command->queues[i].address
+ ));
+ }
+ else
+#endif
+ {
+ gctUINT32 allocFlag;
+
+#if gcdENABLE_CACHEABLE_COMMAND_BUFFER
+ allocFlag = gcvALLOC_FLAG_CACHEABLE | gcvALLOC_FLAG_CONTIGUOUS;
+#else
+ allocFlag = gcvALLOC_FLAG_CONTIGUOUS;
+#endif
+
+ gcmkONERROR(gckOS_AllocateNonPagedMemory(
+ os,
+ gcvFALSE,
+ allocFlag,
+ &pageSize,
+ &command->queues[i].physical,
+ &command->queues[i].logical
+ ));
+
+ gcmkONERROR(gckHARDWARE_ConvertLogical(
+ Kernel->hardware,
+ command->queues[i].logical,
+ gcvFALSE,
+ &command->queues[i].address
+ ));
+
+ gcmkONERROR(gckMMU_FillFlatMapping(
+ Kernel->mmu, command->queues[i].address, pageSize
+ ));
+ }
+
+ gcmkONERROR(gckOS_CreateSignal(
+ os, gcvFALSE, &command->queues[i].signal
+ ));
+
+ gcmkONERROR(gckOS_Signal(
+ os, command->queues[i].signal, gcvTRUE
+ ));
+ }
+
+#if gcdRECORD_COMMAND
+ gcmkONERROR(gckRECORDER_Construct(os, Kernel->hardware, &command->recorder));
+#endif
+
+ gcmkONERROR(gckOS_Allocate(os, gcmSIZEOF(gcsPATCH_LIST), &command->kList));
+
+ gcmkONERROR(gckFENCE_Create(
+ os, Kernel, &command->fence
+ ));
+
+ /* No command queue in use yet. */
+ command->index = -1;
+ command->logical = gcvNULL;
+ command->newQueue = gcvFALSE;
+
+ /* Command is not yet running. */
+ command->running = gcvFALSE;
+
+ /* Command queue is idle. */
+ command->idle = gcvTRUE;
+
+ /* Commit stamp start from 1. */
+ command->commitStamp = 1;
+
+ /* END event signal not created. */
+ command->endEventSignal = gcvNULL;
+
+ command->dummyDraw = gcvTRUE;
+
+ /* Return pointer to the gckCOMMAND object. */
+ *Command = command;
+
+ /* Success. */
+ gcmkFOOTER_ARG("*Command=0x%x", *Command);
+ return gcvSTATUS_OK;
+
+OnError:
+ /* Roll back. */
+ if (command != gcvNULL)
+ {
+ gcmkVERIFY_OK(gckCOMMAND_Destroy(command));
+ }
+
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+/*******************************************************************************
+**
+** gckCOMMAND_Destroy
+**
+** Destroy an gckCOMMAND object.
+**
+** INPUT:
+**
+** gckCOMMAND Command
+** Pointer to an gckCOMMAND object to destroy.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckCOMMAND_Destroy(
+ IN gckCOMMAND Command
+ )
+{
+ gctINT i;
+
+ gcmkHEADER_ARG("Command=0x%x", Command);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Command, gcvOBJ_COMMAND);
+
+ /* Stop the command queue. */
+ gcmkVERIFY_OK(gckCOMMAND_Stop(Command));
+
+ for (i = 0; i < gcdCOMMAND_QUEUES; ++i)
+ {
+ if (Command->queues[i].signal)
+ {
+ gcmkVERIFY_OK(gckOS_DestroySignal(
+ Command->os, Command->queues[i].signal
+ ));
+ }
+
+ if (Command->queues[i].logical)
+ {
+#if USE_KERNEL_VIRTUAL_BUFFERS
+ if (Command->kernel->virtualCommandBuffer)
+ {
+ gcmkVERIFY_OK(gckKERNEL_DestroyVirtualCommandBuffer(
+ Command->kernel,
+ Command->pageSize,
+ Command->queues[i].physical,
+ Command->queues[i].logical
+ ));
+ }
+ else
+#endif
+ {
+ gcmkVERIFY_OK(gckOS_FreeNonPagedMemory(
+ Command->os,
+ Command->pageSize,
+ Command->queues[i].physical,
+ Command->queues[i].logical
+ ));
+ }
+ }
+ }
+
+ /* END event signal. */
+ if (Command->endEventSignal != gcvNULL)
+ {
+ gcmkVERIFY_OK(gckOS_DestroySignal(
+ Command->os, Command->endEventSignal
+ ));
+ }
+
+ if (Command->mutexContext)
+ {
+ /* Delete the context switching mutex. */
+ gcmkVERIFY_OK(gckOS_DeleteMutex(Command->os, Command->mutexContext));
+ }
+
+ if (Command->mutexContextSeq != gcvNULL)
+ gcmkVERIFY_OK(gckOS_DeleteMutex(Command->os, Command->mutexContextSeq));
+
+ if (Command->mutexQueue)
+ {
+ /* Delete the command queue mutex. */
+ gcmkVERIFY_OK(gckOS_DeleteMutex(Command->os, Command->mutexQueue));
+ }
+
+ if (Command->powerSemaphore)
+ {
+ /* Destroy the power management semaphore. */
+ gcmkVERIFY_OK(gckOS_DestroySemaphore(Command->os, Command->powerSemaphore));
+ }
+
+ if (Command->atomCommit)
+ {
+ /* Destroy the commit atom. */
+ gcmkVERIFY_OK(gckOS_AtomDestroy(Command->os, Command->atomCommit));
+ }
+
+#if gcdSECURE_USER
+ /* Free state array. */
+ if (Command->hintArrayAllocated)
+ {
+ gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Command->os, gcmUINT64_TO_PTR(Command->hintArray)));
+ Command->hintArrayAllocated = gcvFALSE;
+ }
+#endif
+
+#if gcdRECORD_COMMAND
+ gckRECORDER_Destory(Command->os, Command->recorder);
+#endif
+
+ if (Command->stateMap)
+ {
+ gcmkOS_SAFE_FREE(Command->os, Command->stateMap);
+ }
+
+ if (Command->kList)
+ {
+ gcmkOS_SAFE_FREE(Command->os, Command->kList);
+ }
+
+ if (Command->fence)
+ {
+ gcmkVERIFY_OK(gckFENCE_Destory(Command->os, Command->fence));
+ }
+
+ /* Mark object as unknown. */
+ Command->object.type = gcvOBJ_UNKNOWN;
+
+ /* Free the gckCOMMAND object. */
+ gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Command->os, Command));
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+}
+
+/*******************************************************************************
+**
+** gckCOMMAND_EnterCommit
+**
+** Acquire command queue synchronization objects.
+**
+** INPUT:
+**
+** gckCOMMAND Command
+** Pointer to an gckCOMMAND object to destroy.
+**
+** gctBOOL FromPower
+** Determines whether the call originates from inside the power
+** management or not.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckCOMMAND_EnterCommit(
+ IN gckCOMMAND Command,
+ IN gctBOOL FromPower
+ )
+{
+ gceSTATUS status;
+ gckHARDWARE hardware;
+ gctBOOL atomIncremented = gcvFALSE;
+ gctBOOL semaAcquired = gcvFALSE;
+
+ gcmkHEADER_ARG("Command=0x%x", Command);
+
+ /* Extract the gckHARDWARE and gckEVENT objects. */
+ hardware = Command->kernel->hardware;
+ gcmkVERIFY_OBJECT(hardware, gcvOBJ_HARDWARE);
+
+ if (!FromPower)
+ {
+ /* Increment COMMIT atom to let power management know that a commit is
+ ** in progress. */
+ gcmkONERROR(_IncrementCommitAtom(Command, gcvTRUE));
+ atomIncremented = gcvTRUE;
+
+ /* Notify the system the GPU has a commit. */
+ gcmkONERROR(gckOS_Broadcast(Command->os,
+ hardware,
+ gcvBROADCAST_GPU_COMMIT));
+
+ /* Acquire the power management semaphore. */
+ gcmkONERROR(gckOS_AcquireSemaphore(Command->os,
+ Command->powerSemaphore));
+ semaAcquired = gcvTRUE;
+ }
+
+ /* Grab the conmmand queue mutex. */
+ gcmkONERROR(gckOS_AcquireMutex(Command->os,
+ Command->mutexQueue,
+ gcvINFINITE));
+
+ /* Success. */
+ gcmkFOOTER();
+ return gcvSTATUS_OK;
+
+OnError:
+ if (semaAcquired)
+ {
+ /* Release the power management semaphore. */
+ gcmkVERIFY_OK(gckOS_ReleaseSemaphore(
+ Command->os, Command->powerSemaphore
+ ));
+ }
+
+ if (atomIncremented)
+ {
+ /* Decrement the commit atom. */
+ gcmkVERIFY_OK(_IncrementCommitAtom(
+ Command, gcvFALSE
+ ));
+ }
+
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+/*******************************************************************************
+**
+** gckCOMMAND_ExitCommit
+**
+** Release command queue synchronization objects.
+**
+** INPUT:
+**
+** gckCOMMAND Command
+** Pointer to an gckCOMMAND object to destroy.
+**
+** gctBOOL FromPower
+** Determines whether the call originates from inside the power
+** management or not.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckCOMMAND_ExitCommit(
+ IN gckCOMMAND Command,
+ IN gctBOOL FromPower
+ )
+{
+ gceSTATUS status;
+
+ gcmkHEADER_ARG("Command=0x%x", Command);
+
+ /* Release the power mutex. */
+ gcmkONERROR(gckOS_ReleaseMutex(Command->os, Command->mutexQueue));
+
+ if (!FromPower)
+ {
+ /* Release the power management semaphore. */
+ gcmkONERROR(gckOS_ReleaseSemaphore(Command->os,
+ Command->powerSemaphore));
+
+ /* Decrement the commit atom. */
+ gcmkONERROR(_IncrementCommitAtom(Command, gcvFALSE));
+ }
+
+ /* Success. */
+ gcmkFOOTER();
+ return gcvSTATUS_OK;
+
+OnError:
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+/*******************************************************************************
+**
+** gckCOMMAND_Start
+**
+** Start up the command queue.
+**
+** INPUT:
+**
+** gckCOMMAND Command
+** Pointer to an gckCOMMAND object to start.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckCOMMAND_Start(
+ IN gckCOMMAND Command
+ )
+{
+ gceSTATUS status;
+ gckHARDWARE hardware;
+ gctUINT32 waitOffset = 0;
+ gctUINT32 waitLinkBytes;
+ gctPOINTER logical;
+ gctUINT32 physical;
+ gctUINT32 address;
+
+ gcmkHEADER_ARG("Command=0x%x", Command);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Command, gcvOBJ_COMMAND);
+
+ if (Command->running)
+ {
+ /* Command queue already running. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+ }
+
+ /* Extract the gckHARDWARE object. */
+ hardware = Command->kernel->hardware;
+ gcmkVERIFY_OBJECT(hardware, gcvOBJ_HARDWARE);
+
+ /* Query the size of WAIT/LINK command sequence. */
+ gcmkONERROR(gckHARDWARE_WaitLink(
+ hardware,
+ gcvNULL,
+ ~0U,
+ Command->offset,
+ &waitLinkBytes,
+ gcvNULL,
+ gcvNULL
+ ));
+
+ if ((Command->pageSize - Command->offset < waitLinkBytes)
+ || (Command->logical == gcvNULL)
+ )
+ {
+ /* Start at beginning of a new queue. */
+ gcmkONERROR(_NewQueue(Command, gcvTRUE));
+ }
+
+ logical = (gctUINT8_PTR) Command->logical + Command->offset;
+ physical = Command->physical + Command->offset;
+ address = Command->address + Command->offset;
+
+ /* Append WAIT/LINK. */
+ gcmkONERROR(gckHARDWARE_WaitLink(
+ hardware,
+ logical,
+ address,
+ 0,
+ &waitLinkBytes,
+ &waitOffset,
+ &Command->waitSize
+ ));
+
+ Command->waitLogical = (gctUINT8_PTR) logical + waitOffset;
+ Command->waitPhysical = physical + waitOffset;
+ Command->waitAddress = address + waitOffset;
+ Command->waitOffset = waitOffset;
+
+ /* Flush the cache for the wait/link. */
+ gcmkONERROR(gckOS_CacheClean(
+ Command->os,
+ 0,
+ Command->physHandle,
+ Command->offset,
+ logical,
+ waitLinkBytes
+ ));
+
+ /* Adjust offset. */
+ Command->offset += waitLinkBytes;
+ Command->newQueue = gcvFALSE;
+
+#if gcdSECURITY
+ /* Start FE by calling security service. */
+ gckKERNEL_SecurityStartCommand(
+ Command->kernel
+ );
+#else
+ /* Enable command processor. */
+ gcmkONERROR(gckHARDWARE_Execute(
+ hardware,
+ address,
+ waitLinkBytes
+ ));
+#endif
+
+ /* Command queue is running. */
+ Command->running = gcvTRUE;
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+/*******************************************************************************
+**
+** gckCOMMAND_Stop
+**
+** Stop the command queue.
+**
+** INPUT:
+**
+** gckCOMMAND Command
+** Pointer to an gckCOMMAND object to stop.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckCOMMAND_Stop(
+ IN gckCOMMAND Command
+ )
+{
+ gckHARDWARE hardware;
+ gceSTATUS status;
+ gctUINT32 idle;
+
+ gcmkHEADER_ARG("Command=0x%x", Command);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Command, gcvOBJ_COMMAND);
+
+ if (!Command->running)
+ {
+ /* Command queue is not running. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+ }
+
+ /* Extract the gckHARDWARE object. */
+ hardware = Command->kernel->hardware;
+ gcmkVERIFY_OBJECT(hardware, gcvOBJ_HARDWARE);
+
+ if (gckHARDWARE_IsFeatureAvailable(hardware,
+ gcvFEATURE_END_EVENT) == gcvSTATUS_TRUE)
+ {
+ /* Allocate the signal. */
+ if (Command->endEventSignal == gcvNULL)
+ {
+ gcmkONERROR(gckOS_CreateSignal(Command->os,
+ gcvTRUE,
+ &Command->endEventSignal));
+ }
+
+ /* Append the END EVENT command to trigger the signal. */
+ gcmkONERROR(gckEVENT_Stop(Command->kernel->eventObj,
+ Command->kernelProcessID,
+ Command->physHandle,
+ Command->offset + Command->waitOffset,
+ Command->waitLogical,
+ Command->waitAddress,
+ Command->endEventSignal,
+ &Command->waitSize));
+ }
+ else
+ {
+ /* Replace last WAIT with END. */
+ gcmkONERROR(gckHARDWARE_End(
+ hardware,
+ Command->waitLogical,
+ Command->waitAddress,
+ &Command->waitSize
+ ));
+
+#if USE_KERNEL_VIRTUAL_BUFFERS
+ if (hardware->kernel->virtualCommandBuffer)
+ {
+ gcmkONERROR(gckKERNEL_GetGPUAddress(
+ hardware->kernel,
+ Command->waitLogical,
+ gcvFALSE,
+ Command->virtualMemory,
+ &hardware->lastEnd
+ ));
+ }
+#endif
+
+#if gcdSECURITY
+ gcmkONERROR(gckKERNEL_SecurityExecute(
+ Command->kernel, Command->waitLogical, 8
+ ));
+#endif
+
+ /* Update queue tail pointer. */
+ gcmkONERROR(gckHARDWARE_UpdateQueueTail(Command->kernel->hardware,
+ Command->logical,
+ Command->offset));
+
+ /* Flush the cache for the END. */
+ gcmkONERROR(gckOS_CacheClean(
+ Command->os,
+ 0,
+ Command->physHandle,
+ Command->offset + Command->waitOffset,
+ Command->waitLogical,
+ Command->waitSize
+ ));
+
+ /* Wait for idle. */
+ gcmkONERROR(gckHARDWARE_GetIdle(hardware, gcvTRUE, &idle));
+ }
+
+ /* Command queue is no longer running. */
+ Command->running = gcvFALSE;
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+/*******************************************************************************
+**
+** gckCOMMAND_Commit
+**
+** Commit a command buffer to the command queue.
+**
+** INPUT:
+**
+** gckCOMMAND Command
+** Pointer to a gckCOMMAND object.
+**
+** gckCONTEXT Context
+** Pointer to a gckCONTEXT object.
+**
+** gcoCMDBUF CommandBuffer
+** Pointer to a gcoCMDBUF object.
+**
+** gcsSTATE_DELTA_PTR StateDelta
+** Pointer to the state delta.
+**
+** gctUINT32 ProcessID
+** Current process ID.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckCOMMAND_Commit(
+ IN gckCOMMAND Command,
+ IN gckCONTEXT Context,
+ IN gcoCMDBUF CommandBuffer,
+ IN gcsSTATE_DELTA_PTR StateDelta,
+ IN gctUINT32 ProcessID,
+ IN gctBOOL Shared,
+ IN gctUINT32 Index,
+ OUT gctUINT64_PTR CommitStamp,
+ OUT gctBOOL_PTR ContextSwitched
+ )
+{
+ gceSTATUS status;
+ gctBOOL commitEntered = gcvFALSE;
+ gctBOOL contextAcquired = gcvFALSE;
+ gckHARDWARE hardware;
+ gctBOOL needCopy = gcvFALSE;
+ gctBOOL commandBufferMapped = gcvFALSE;
+ gcoCMDBUF commandBufferObject = gcvNULL;
+ gctBOOL stall = gcvFALSE;
+ gctBOOL contextSwitched = gcvFALSE;
+
+#if !gcdNULL_DRIVER
+ gcsCONTEXT_PTR contextBuffer;
+ gctPHYS_ADDR_T commandBufferPhysical;
+ gctUINT8_PTR commandBufferLogical = gcvNULL;
+ gctUINT32 commandBufferAddress = 0;
+ gctUINT8_PTR commandBufferTail = gcvNULL;
+ gctUINT commandBufferSize;
+ gctSIZE_T nopBytes;
+ gctUINT32 pipeBytes;
+ gctUINT32 linkBytes;
+ gctSIZE_T bytes;
+ gctUINT32 offset;
+ gctPOINTER entryLogical;
+ gctUINT32 entryAddress;
+ gctUINT32 entryBytes;
+ gctUINT32 exitOffset;
+ gctPOINTER exitLogical;
+ gctUINT32 exitAddress;
+ gctUINT32 exitBytes;
+ gctUINT32 waitLinkPhysical;
+ gctPOINTER waitLinkLogical;
+ gctUINT32 waitLinkAddress;
+ gctUINT32 waitLinkBytes;
+ gctUINT32 waitOffset;
+ gctUINT32 waitSize;
+
+#ifdef __QNXNTO__
+ gctPOINTER userCommandBufferLogical = gcvNULL;
+ gctBOOL userCommandBufferLogicalMapped = gcvFALSE;
+#endif
+
+#if gcdPROCESS_ADDRESS_SPACE
+ gckMMU mmu;
+ gctUINT32 oldValue;
+#endif
+
+#if gcdDUMP_COMMAND
+ gctPOINTER contextDumpLogical = gcvNULL;
+ gctSIZE_T contextDumpBytes = 0;
+ gctPOINTER bufferDumpLogical = gcvNULL;
+ gctSIZE_T bufferDumpBytes = 0;
+# endif
+ gctUINT32 exitLinkLow = 0, exitLinkHigh = 0;
+ gctUINT32 entryLinkLow = 0, entryLinkHigh = 0;
+ gctUINT32 commandLinkLow = 0, commandLinkHigh = 0;
+
+ gckVIRTUAL_COMMAND_BUFFER_PTR virtualCommandBuffer = gcvNULL;
+ gctUINT64 asyncCommandStamp = 0;
+ gcoCMDBUF lastCommandBuffer = gcvNULL;
+ gctPOINTER pointer = gcvNULL;
+ gckKERNEL kernel = Command->kernel;
+
+ gctPHYS_ADDR contextPhysHandle = gcvNULL;
+ gctPHYS_ADDR physHandle = gcvNULL;
+#endif
+
+ gcmkHEADER_ARG(
+ "Command=0x%x CommandBuffer=0x%x ProcessID=%d",
+ Command, CommandBuffer, ProcessID
+ );
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Command, gcvOBJ_COMMAND);
+
+#if gcdPROCESS_ADDRESS_SPACE
+ gcmkONERROR(gckKERNEL_GetProcessMMU(Command->kernel, &mmu));
+
+ gcmkONERROR(gckOS_AtomicExchange(Command->os,
+ mmu->pageTableDirty[Command->kernel->core],
+ 0,
+ &oldValue));
+#else
+#endif
+
+ /* Acquire the command queue. */
+ gcmkONERROR(gckCOMMAND_EnterCommit(Command, gcvFALSE));
+ commitEntered = gcvTRUE;
+
+#if !gcdNULL_DRIVER
+ gcmkONERROR(_ProcessUserCommandBufferList(
+ Command,
+ CommandBuffer,
+ &lastCommandBuffer
+ ));
+#endif
+
+ /* Acquire the context switching mutex. */
+ gcmkONERROR(gckOS_AcquireMutex(
+ Command->os, Command->mutexContext, gcvINFINITE
+ ));
+ contextAcquired = gcvTRUE;
+
+ /* Extract the gckHARDWARE and gckEVENT objects. */
+ hardware = Command->kernel->hardware;
+
+ /* Check wehther we need to copy the structures or not. */
+ gcmkONERROR(gckOS_QueryNeedCopy(Command->os, ProcessID, &needCopy));
+
+#if gcdNULL_DRIVER
+ /* Context switch required? */
+ if ((Context != gcvNULL) && (Command->currContext != Context))
+ {
+ /* Yes, merge in the deltas. */
+ gckCONTEXT_Update(Context, ProcessID, StateDelta);
+
+ /* Update the current context. */
+ Command->currContext = Context;
+
+ contextSwitched = gcvTRUE;
+ }
+#else
+ if (needCopy)
+ {
+ commandBufferObject = &Command->_commandBufferObject;
+
+ gcmkONERROR(gckOS_CopyFromUserData(
+ Command->os,
+ commandBufferObject,
+ CommandBuffer,
+ gcmSIZEOF(struct _gcoCMDBUF)
+ ));
+
+ gcmkVERIFY_OBJECT(commandBufferObject, gcvOBJ_COMMANDBUFFER);
+ }
+ else
+ {
+ gcmkONERROR(gckOS_MapUserPointer(
+ Command->os,
+ CommandBuffer,
+ gcmSIZEOF(struct _gcoCMDBUF),
+ &pointer
+ ));
+
+ commandBufferObject = pointer;
+
+ gcmkVERIFY_OBJECT(commandBufferObject, gcvOBJ_COMMANDBUFFER);
+ commandBufferMapped = gcvTRUE;
+ }
+
+ gcmkONERROR(_HandlePatchList(Command, commandBufferObject, needCopy, &asyncCommandStamp));
+
+ /* Query the size of NOP command. */
+ gcmkONERROR(gckHARDWARE_Nop(
+ hardware, gcvNULL, &nopBytes
+ ));
+
+ /* Query the size of pipe select command sequence. */
+ gcmkONERROR(gckHARDWARE_PipeSelect(
+ hardware, gcvNULL, gcvPIPE_3D, &pipeBytes
+ ));
+
+ /* Query the size of LINK command. */
+ gcmkONERROR(gckHARDWARE_Link(
+ hardware, gcvNULL, 0, 0, &linkBytes, gcvNULL, gcvNULL
+ ));
+
+ /* Compute the command buffer entry and the size. */
+ commandBufferLogical
+ = (gctUINT8_PTR) gcmUINT64_TO_PTR(commandBufferObject->logical)
+ + commandBufferObject->startOffset;
+
+
+ /* Get the hardware address. */
+ if (Command->kernel->virtualCommandBuffer)
+ {
+ virtualCommandBuffer = gcmNAME_TO_PTR(commandBufferObject->physical);
+ physHandle = virtualCommandBuffer->virtualBuffer.physical;
+
+ if (virtualCommandBuffer == gcvNULL)
+ {
+ gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
+ }
+
+ gcmkONERROR(gckKERNEL_GetGPUAddress(
+ Command->kernel,
+ commandBufferLogical,
+ gcvTRUE,
+ virtualCommandBuffer,
+ &commandBufferAddress
+ ));
+ }
+ else
+ {
+ physHandle = gcmNAME_TO_PTR(commandBufferObject->physical);
+
+ gcmkONERROR(gckHARDWARE_ConvertLogical(
+ hardware,
+ commandBufferLogical,
+ gcvTRUE,
+ &commandBufferAddress
+ ));
+ }
+
+#ifdef __QNXNTO__
+ userCommandBufferLogical = (gctPOINTER) commandBufferLogical;
+
+ gcmkONERROR(gckOS_MapUserPointer(
+ Command->os,
+ userCommandBufferLogical,
+ 0,
+ &pointer));
+
+ commandBufferLogical = pointer;
+
+ userCommandBufferLogicalMapped = gcvTRUE;
+
+ gcmkONERROR(gckOS_GetPhysicalAddress(
+ Command->os,
+ commandBufferLogical,
+ &commandBufferPhysical
+ ));
+
+#else
+ /* Get the physical address. */
+ gcmkONERROR(gckOS_UserLogicalToPhysical(
+ Command->os,
+ commandBufferLogical,
+ &commandBufferPhysical
+ ));
+#endif
+
+ commandBufferSize
+ = commandBufferObject->offset
+ + commandBufferObject->reservedTail
+ - commandBufferObject->startOffset;
+
+ gcmkONERROR(_FlushMMU(Command));
+
+ if (Command->dummyDraw == gcvTRUE &&
+ Context != gcvNULL)
+ {
+ Command->dummyDraw = gcvFALSE;
+ gcmkONERROR(_DummyDraw(Command));
+ }
+
+ if (gckHARDWARE_IsFeatureAvailable(hardware, gcvFEATURE_FENCE_64BIT) && asyncCommandStamp != 0)
+ {
+ gcmkONERROR(_WaitForAsyncCommandStamp(Command, asyncCommandStamp));
+ }
+
+ /* Get the current offset. */
+ offset = Command->offset;
+
+ /* Compute number of bytes left in current kernel command queue. */
+ bytes = Command->pageSize - offset;
+
+ /* Query the size of WAIT/LINK command sequence. */
+ gcmkONERROR(gckHARDWARE_WaitLink(
+ hardware,
+ gcvNULL,
+ ~0U,
+ offset,
+ &waitLinkBytes,
+ gcvNULL,
+ gcvNULL
+ ));
+
+ /* Is there enough space in the current command queue? */
+ if (bytes < waitLinkBytes)
+ {
+ /* No, create a new one. */
+ gcmkONERROR(_NewQueue(Command, gcvFALSE));
+
+ /* Get the new current offset. */
+ offset = Command->offset;
+
+ /* Recompute the number of bytes in the new kernel command queue. */
+ bytes = Command->pageSize - offset;
+ gcmkASSERT(bytes >= waitLinkBytes);
+ }
+
+ /* Compute the location if WAIT/LINK command sequence. */
+ waitLinkPhysical = Command->physical + offset;
+ waitLinkLogical = (gctUINT8_PTR) Command->logical + offset;
+ waitLinkAddress = Command->address + offset;
+
+ /* Context switch required? */
+ if (Context == gcvNULL)
+ {
+ /* See if we have to switch pipes for the command buffer. */
+ if (commandBufferObject->entryPipe == Command->pipeSelect)
+ {
+ /* Skip pipe switching sequence. */
+ offset = pipeBytes;
+ }
+ else
+ {
+ /* The current hardware and the entry command buffer pipes
+ ** are different, switch to the correct pipe. */
+ gcmkONERROR(gckHARDWARE_PipeSelect(
+ Command->kernel->hardware,
+ commandBufferLogical,
+ commandBufferObject->entryPipe,
+ &pipeBytes
+ ));
+
+ /* Do not skip pipe switching sequence. */
+ offset = 0;
+ }
+
+ /* Compute the entry. */
+ entryLogical = commandBufferLogical + offset;
+ entryAddress = commandBufferAddress + offset;
+ entryBytes = commandBufferSize - offset;
+
+ Command->currContext = gcvNULL;
+ }
+#if gcdDEBUG_OPTION && gcdDEBUG_FORCE_CONTEXT_UPDATE
+ else if (1)
+#else
+ else if (Command->currContext != Context)
+#endif
+ {
+ /* Get the current context buffer. */
+ contextBuffer = Context->buffer;
+
+ /* Yes, merge in the deltas. */
+ gcmkONERROR(gckCONTEXT_Update(Context, ProcessID, StateDelta));
+
+ contextSwitched = gcvTRUE;
+
+ /***************************************************************
+ ** SWITCHING CONTEXT.
+ */
+
+ /* Determine context buffer entry offset. */
+ offset = (Command->pipeSelect == gcvPIPE_3D)
+
+ /* Skip pipe switching sequence. */
+ ? Context->entryOffset3D + Context->pipeSelectBytes
+
+ /* Do not skip pipe switching sequence. */
+ : Context->entryOffset3D;
+
+ /* Compute the entry. */
+ entryLogical = (gctUINT8_PTR) contextBuffer->logical + offset;
+ entryAddress = contextBuffer->address + offset;
+ entryBytes = Context->bufferSize - offset;
+
+ /* See if we have to switch pipes between the context
+ and command buffers. */
+ if (commandBufferObject->entryPipe == gcvPIPE_3D)
+ {
+ /* Skip pipe switching sequence. */
+ offset = pipeBytes;
+ }
+ else
+ {
+ /* The current hardware and the initial context pipes are
+ different, switch to the correct pipe. */
+ gcmkONERROR(gckHARDWARE_PipeSelect(
+ Command->kernel->hardware,
+ commandBufferLogical,
+ commandBufferObject->entryPipe,
+ &pipeBytes
+ ));
+
+ /* Do not skip pipe switching sequence. */
+ offset = 0;
+ }
+
+ /* Generate a LINK from the context buffer to
+ the command buffer. */
+ gcmkONERROR(gckHARDWARE_Link(
+ hardware,
+ contextBuffer->link3D,
+ commandBufferAddress + offset,
+ commandBufferSize - offset,
+ &linkBytes,
+ &commandLinkLow,
+ &commandLinkHigh
+ ));
+
+#if USE_KERNEL_VIRTUAL_BUFFERS
+ if (Command->kernel->virtualCommandBuffer)
+ {
+ gckVIRTUAL_COMMAND_BUFFER_PTR commandBuffer = (gckVIRTUAL_COMMAND_BUFFER_PTR) contextBuffer->physical;
+
+ contextPhysHandle = commandBuffer->virtualBuffer.physical;
+ }
+ else
+#endif
+ {
+ contextPhysHandle = contextBuffer->physical;
+ }
+
+ /* Flush the context buffer cache. */
+ gcmkONERROR(gckOS_CacheClean(
+ Command->os,
+ 0,
+ contextPhysHandle,
+ entryAddress - contextBuffer->address,
+ entryLogical,
+ entryBytes
+ ));
+
+ /* Update the current context. */
+ Command->currContext = Context;
+
+#if gcdDUMP_COMMAND
+ contextDumpLogical = entryLogical;
+ contextDumpBytes = entryBytes;
+#endif
+
+#if gcdSECURITY
+ /* Commit context buffer to trust zone. */
+ gckKERNEL_SecurityExecute(
+ Command->kernel,
+ entryLogical,
+ entryBytes - 8
+ );
+#endif
+
+#if gcdRECORD_COMMAND
+ gckRECORDER_Record(
+ Command->recorder,
+ gcvNULL,
+ 0xFFFFFFFF,
+ entryLogical,
+ entryBytes
+ );
+#endif
+ }
+
+ /* Same context. */
+ else
+ {
+ /* See if we have to switch pipes for the command buffer. */
+ if (commandBufferObject->entryPipe == Command->pipeSelect)
+ {
+ /* Skip pipe switching sequence. */
+ offset = pipeBytes;
+ }
+ else
+ {
+ /* The current hardware and the entry command buffer pipes
+ ** are different, switch to the correct pipe. */
+ gcmkONERROR(gckHARDWARE_PipeSelect(
+ Command->kernel->hardware,
+ commandBufferLogical,
+ commandBufferObject->entryPipe,
+ &pipeBytes
+ ));
+
+ /* Do not skip pipe switching sequence. */
+ offset = 0;
+ }
+
+ /* Compute the entry. */
+ entryLogical = commandBufferLogical + offset;
+ entryAddress = commandBufferAddress + offset;
+ entryBytes = commandBufferSize - offset;
+ }
+
+#if gcdDUMP_COMMAND
+ bufferDumpLogical = commandBufferLogical + offset;
+ bufferDumpBytes = commandBufferSize - offset;
+#endif
+
+#if gcdSECURE_USER
+ /* Process user hints. */
+ gcmkONERROR(_ProcessHints(Command, ProcessID, commandBufferObject));
+#endif
+
+ /* Determine the location to jump to for the command buffer being
+ ** scheduled. */
+ if (Command->newQueue)
+ {
+ /* New command queue, jump to the beginning of it. */
+ exitOffset = 0;
+ exitLogical = Command->logical;
+ exitAddress = Command->address;
+ exitBytes = Command->offset + waitLinkBytes;
+ }
+ else
+ {
+ /* Still within the preexisting command queue, jump to the new
+ WAIT/LINK command sequence. */
+ exitOffset = offset;
+ exitLogical = waitLinkLogical;
+ exitAddress = waitLinkAddress;
+ exitBytes = waitLinkBytes;
+ }
+
+ /* Add a new WAIT/LINK command sequence. When the command buffer which is
+ currently being scheduled is fully executed by the GPU, the FE will
+ jump to this WAIT/LINK sequence. */
+ gcmkONERROR(gckHARDWARE_WaitLink(
+ hardware,
+ waitLinkLogical,
+ waitLinkAddress,
+ offset,
+ &waitLinkBytes,
+ &waitOffset,
+ &waitSize
+ ));
+
+ /* Flush the command queue cache. */
+ gcmkONERROR(gckOS_CacheClean(
+ Command->os,
+ 0,
+ Command->physHandle,
+ exitOffset,
+ exitLogical,
+ exitBytes
+ ));
+
+ /* Determine the location of the TAIL in the command buffer. */
+ commandBufferTail
+ = commandBufferLogical
+ + commandBufferSize
+ - commandBufferObject->reservedTail;
+
+ /* Generate command which writes out commit stamp. */
+ if (gckHARDWARE_IsFeatureAvailable(hardware, gcvFEATURE_FENCE_64BIT))
+ {
+ gctUINT32 bytes;
+
+ gcmkONERROR(gckHARDWARE_Fence(
+ hardware,
+ gcvENGINE_RENDER,
+ commandBufferTail,
+ Command->fence->address,
+ Command->commitStamp,
+ &bytes
+ ));
+
+ commandBufferTail += gcdRENDER_FENCE_LENGTH;
+ }
+
+ /* Generate a LINK from the end of the command buffer being scheduled
+ back to the kernel command queue. */
+#if !gcdSECURITY
+ if (Shared == gcvFALSE)
+ {
+ gcmkONERROR(gckHARDWARE_Link(
+ hardware,
+ commandBufferTail,
+ exitAddress,
+ exitBytes,
+ &linkBytes,
+ &exitLinkLow,
+ &exitLinkHigh
+ ));
+ }
+ else
+ {
+ gctUINT8_PTR link = commandBufferTail + Index * 16;
+ gctSIZE_T bytes = 8;
+
+ gcmkONERROR(gckHARDWARE_ChipEnable(
+ hardware,
+ link,
+ (gceCORE_3D_MASK)(1 << hardware->kernel->chipID),
+ &bytes
+ ));
+
+ link += bytes;
+
+ gcmkONERROR(gckHARDWARE_Link(
+ hardware,
+ link,
+ exitAddress,
+ exitBytes,
+ &linkBytes,
+ &exitLinkLow,
+ &exitLinkHigh
+ ));
+
+ link += linkBytes;
+ }
+#endif
+
+ /* Flush the command buffer cache. */
+ gcmkONERROR(gckOS_CacheClean(
+ Command->os,
+ ProcessID,
+ physHandle,
+ commandBufferObject->startOffset,
+ commandBufferLogical,
+ commandBufferSize
+ ));
+
+#if gcdRECORD_COMMAND
+ gckRECORDER_Record(
+ Command->recorder,
+ commandBufferLogical + offset,
+ commandBufferSize - offset,
+ gcvNULL,
+ 0xFFFFFFFF
+ );
+
+ gckRECORDER_AdvanceIndex(Command->recorder, Command->commitStamp);
+#endif
+
+#if gcdSECURITY
+ /* Submit command buffer to trust zone. */
+ gckKERNEL_SecurityExecute(
+ Command->kernel,
+ commandBufferLogical + offset,
+ commandBufferSize - offset - 8
+ );
+#else
+ /* Generate a LINK from the previous WAIT/LINK command sequence to the
+ entry determined above (either the context or the command buffer).
+ This LINK replaces the WAIT instruction from the previous WAIT/LINK
+ pair, therefore we use WAIT metrics for generation of this LINK.
+ This action will execute the entire sequence. */
+ gcmkONERROR(gckHARDWARE_Link(
+ hardware,
+ Command->waitLogical,
+ entryAddress,
+ entryBytes,
+ &Command->waitSize,
+ &entryLinkLow,
+ &entryLinkHigh
+ ));
+#endif
+
+#if gcdLINK_QUEUE_SIZE
+ if (Command->kernel->stuckDump >= gcvSTUCK_DUMP_USER_COMMAND)
+ {
+ gcuQUEUEDATA data;
+
+ gcmkVERIFY_OK(gckOS_GetProcessID(&data.linkData.pid));
+
+ data.linkData.start = entryAddress;
+ data.linkData.end = entryAddress + entryBytes;
+ data.linkData.linkLow = entryLinkLow;
+ data.linkData.linkHigh = entryLinkHigh;
+
+ gckQUEUE_Enqueue(&hardware->linkQueue, &data);
+
+ if (commandBufferAddress + offset != entryAddress)
+ {
+ data.linkData.start = commandBufferAddress + offset;
+ data.linkData.end = commandBufferAddress + commandBufferSize;
+ data.linkData.linkLow = commandLinkLow;
+ data.linkData.linkHigh = commandLinkHigh;
+
+ gckQUEUE_Enqueue(&hardware->linkQueue, &data);
+ }
+
+ if (Command->kernel->stuckDump >= gcvSTUCK_DUMP_ALL_COMMAND)
+ {
+ data.linkData.start = exitAddress;
+ data.linkData.end = exitAddress + exitBytes;
+ data.linkData.linkLow = exitLinkLow;
+ data.linkData.linkHigh = exitLinkHigh;
+
+ /* Dump kernel command.*/
+ gckQUEUE_Enqueue(&hardware->linkQueue, &data);
+ }
+ }
+#endif
+
+ /* Flush the cache for the link. */
+ gcmkONERROR(gckOS_CacheClean(
+ Command->os,
+ 0,
+ Command->physHandle,
+ Command->offset + waitOffset,
+ Command->waitLogical,
+ Command->waitSize
+ ));
+
+ gcmkDUMPCOMMAND(
+ Command->os,
+ Command->waitLogical,
+ Command->waitSize,
+ gcvDUMP_BUFFER_LINK,
+ gcvFALSE
+ );
+
+ gcmkDUMPCOMMAND(
+ Command->os,
+ contextDumpLogical,
+ contextDumpBytes,
+ gcvDUMP_BUFFER_CONTEXT,
+ gcvFALSE
+ );
+
+ gcmkDUMPCOMMAND(
+ Command->os,
+ bufferDumpLogical,
+ bufferDumpBytes,
+ gcvDUMP_BUFFER_USER,
+ gcvFALSE
+ );
+
+ gcmkDUMPCOMMAND(
+ Command->os,
+ waitLinkLogical,
+ waitLinkBytes,
+ gcvDUMP_BUFFER_WAITLINK,
+ gcvFALSE
+ );
+
+ /* Update the current pipe. */
+ Command->pipeSelect = commandBufferObject->exitPipe;
+
+ /* Update command queue offset. */
+ Command->offset += waitLinkBytes;
+ Command->newQueue = gcvFALSE;
+
+ /* Update address of last WAIT. */
+ Command->waitPhysical = waitLinkPhysical + waitOffset;
+ Command->waitLogical = (gctUINT8_PTR)waitLinkLogical + waitOffset;
+ Command->waitAddress = waitLinkAddress + waitOffset;
+ Command->waitSize = waitSize;
+
+ /* Update queue tail pointer. */
+ gcmkONERROR(gckHARDWARE_UpdateQueueTail(
+ hardware, Command->logical, Command->offset
+ ));
+
+#if gcdDUMP_COMMAND
+ gcmkPRINT("@[kernel.commit]");
+#endif
+#endif /* gcdNULL_DRIVER */
+
+ /* Release the context switching mutex. */
+ gcmkONERROR(gckOS_ReleaseMutex(Command->os, Command->mutexContext));
+ contextAcquired = gcvFALSE;
+
+ *CommitStamp = Command->commitStamp;
+ *ContextSwitched = contextSwitched;
+
+ Command->commitStamp++;
+
+ stall = gcvFALSE;
+
+#if gcdLINK_QUEUE_SIZE
+ if (Command->kernel->stuckDump == gcvSTUCK_DUMP_STALL_COMMAND)
+ {
+ if ((Command->commitStamp % (gcdLINK_QUEUE_SIZE/2)) == 0)
+ {
+ /* If only context buffer and command buffer is recorded,
+ ** each commit costs 2 slot in queue, to make sure command
+ ** causing stuck is recorded, number of pending command buffer
+ ** is limited to (gckLINK_QUEUE_SIZE/2)
+ */
+ stall = gcvTRUE;
+ }
+ }
+#endif
+
+ /* Release the command queue. */
+ gcmkONERROR(gckCOMMAND_ExitCommit(Command, gcvFALSE));
+ commitEntered = gcvFALSE;
+
+ if (status == gcvSTATUS_INTERRUPTED)
+ {
+ gcmkTRACE(
+ gcvLEVEL_INFO,
+ "%s(%d): Intterupted in gckEVENT_Submit",
+ __FUNCTION__, __LINE__
+ );
+ status = gcvSTATUS_OK;
+ }
+ else
+ {
+ gcmkONERROR(status);
+ }
+
+#ifdef __QNXNTO__
+ if (userCommandBufferLogicalMapped)
+ {
+ gcmkONERROR(gckOS_UnmapUserPointer(
+ Command->os,
+ userCommandBufferLogical,
+ 0,
+ commandBufferLogical));
+
+ userCommandBufferLogicalMapped = gcvFALSE;
+ }
+#endif
+
+ /* Unmap the command buffer pointer. */
+ if (commandBufferMapped)
+ {
+ gcmkONERROR(gckOS_UnmapUserPointer(
+ Command->os,
+ CommandBuffer,
+ gcmSIZEOF(struct _gcoCMDBUF),
+ commandBufferObject
+ ));
+
+ commandBufferMapped = gcvFALSE;
+ }
+
+ /* Return status. */
+ gcmkFOOTER();
+ return gcvSTATUS_OK;
+
+OnError:
+ if (contextAcquired)
+ {
+ /* Release the context switching mutex. */
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(Command->os, Command->mutexContext));
+ }
+
+ if (commitEntered)
+ {
+ /* Release the command queue mutex. */
+ gcmkVERIFY_OK(gckCOMMAND_ExitCommit(Command, gcvFALSE));
+ }
+
+#ifdef __QNXNTO__
+ if (userCommandBufferLogicalMapped)
+ {
+ gcmkVERIFY_OK(gckOS_UnmapUserPointer(
+ Command->os,
+ userCommandBufferLogical,
+ 0,
+ commandBufferLogical));
+ }
+#endif
+
+ /* Unmap the command buffer pointer. */
+ if (commandBufferMapped)
+ {
+ gcmkVERIFY_OK(gckOS_UnmapUserPointer(
+ Command->os,
+ CommandBuffer,
+ gcmSIZEOF(struct _gcoCMDBUF),
+ commandBufferObject
+ ));
+ }
+
+ /* Return status. */
+ gcmkFOOTER();
+ return status;
+}
+
+/*******************************************************************************
+**
+** gckCOMMAND_Reserve
+**
+** Reserve space in the command queue. Also acquire the command queue mutex.
+**
+** INPUT:
+**
+** gckCOMMAND Command
+** Pointer to an gckCOMMAND object.
+**
+** gctSIZE_T RequestedBytes
+** Number of bytes previously reserved.
+**
+** OUTPUT:
+**
+** gctPOINTER * Buffer
+** Pointer to a variable that will receive the address of the reserved
+** space.
+**
+** gctSIZE_T * BufferSize
+** Pointer to a variable that will receive the number of bytes
+** available in the command queue.
+*/
+gceSTATUS
+gckCOMMAND_Reserve(
+ IN gckCOMMAND Command,
+ IN gctUINT32 RequestedBytes,
+ OUT gctPOINTER * Buffer,
+ OUT gctUINT32 * BufferSize
+ )
+{
+ gceSTATUS status;
+ gctUINT32 bytes;
+ gctUINT32 requiredBytes;
+ gctUINT32 requestedAligned;
+
+ gcmkHEADER_ARG("Command=0x%x RequestedBytes=%lu", Command, RequestedBytes);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Command, gcvOBJ_COMMAND);
+
+ /* Compute aligned number of reuested bytes. */
+ requestedAligned = gcmALIGN(RequestedBytes, Command->alignment);
+
+ /* Another WAIT/LINK command sequence will have to be appended after
+ the requested area being reserved. Compute the number of bytes
+ required for WAIT/LINK at the location after the reserved area. */
+ gcmkONERROR(gckHARDWARE_WaitLink(
+ Command->kernel->hardware,
+ gcvNULL,
+ ~0U,
+ Command->offset + requestedAligned,
+ &requiredBytes,
+ gcvNULL,
+ gcvNULL
+ ));
+
+ /* Compute total number of bytes required. */
+ requiredBytes += requestedAligned;
+
+ /* Compute number of bytes available in command queue. */
+ bytes = Command->pageSize - Command->offset;
+
+ /* Is there enough space in the current command queue? */
+ if (bytes < requiredBytes)
+ {
+ /* Create a new command queue. */
+ gcmkONERROR(_NewQueue(Command, gcvFALSE));
+
+ /* Recompute the number of bytes in the new kernel command queue. */
+ bytes = Command->pageSize - Command->offset;
+
+ /* Still not enough space? */
+ if (bytes < requiredBytes)
+ {
+ /* Rare case, not enough room in command queue. */
+ gcmkONERROR(gcvSTATUS_BUFFER_TOO_SMALL);
+ }
+ }
+
+ /* Return pointer to empty slot command queue. */
+ *Buffer = (gctUINT8 *) Command->logical + Command->offset;
+
+ /* Return number of bytes left in command queue. */
+ *BufferSize = bytes;
+
+ /* Success. */
+ gcmkFOOTER_ARG("*Buffer=0x%x *BufferSize=%lu", *Buffer, *BufferSize);
+ return gcvSTATUS_OK;
+
+OnError:
+ /* Return status. */
+ gcmkFOOTER();
+ return status;
+}
+
+/*******************************************************************************
+**
+** gckCOMMAND_Execute
+**
+** Execute a previously reserved command queue by appending a WAIT/LINK command
+** sequence after it and modifying the last WAIT into a LINK command. The
+** command FIFO mutex will be released whether this function succeeds or not.
+**
+** INPUT:
+**
+** gckCOMMAND Command
+** Pointer to an gckCOMMAND object.
+**
+** gctSIZE_T RequestedBytes
+** Number of bytes previously reserved.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckCOMMAND_Execute(
+ IN gckCOMMAND Command,
+ IN gctUINT32 RequestedBytes
+ )
+{
+ gceSTATUS status;
+
+ gctUINT32 waitLinkPhysical;
+ gctUINT8_PTR waitLinkLogical;
+ gctUINT32 waitLinkAddress;
+ gctUINT32 waitLinkOffset;
+ gctUINT32 waitLinkBytes;
+
+ gctUINT32 waitPhysical;
+ gctPOINTER waitLogical;
+ gctUINT32 waitAddress;
+ gctUINT32 waitOffset;
+ gctUINT32 waitBytes;
+
+ gctUINT32 linkLow, linkHigh;
+
+ gctUINT32 execOffset;
+ gctPOINTER execLogical;
+ gctUINT32 execAddress;
+ gctUINT32 execBytes;
+
+ gcmkHEADER_ARG("Command=0x%x RequestedBytes=%lu", Command, RequestedBytes);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Command, gcvOBJ_COMMAND);
+
+ /* Compute offset for WAIT/LINK. */
+ waitLinkOffset = Command->offset + RequestedBytes;
+
+ /* Compute number of bytes left in command queue. */
+ waitLinkBytes = Command->pageSize - waitLinkOffset;
+
+ /* Compute the location if WAIT/LINK command sequence. */
+ waitLinkPhysical = Command->physical + waitLinkOffset;
+ waitLinkLogical = (gctUINT8_PTR) Command->logical + waitLinkOffset;
+ waitLinkAddress = Command->address + waitLinkOffset;
+
+ /* Append WAIT/LINK in command queue. */
+ gcmkONERROR(gckHARDWARE_WaitLink(
+ Command->kernel->hardware,
+ waitLinkLogical,
+ waitLinkAddress,
+ waitLinkOffset,
+ &waitLinkBytes,
+ &waitOffset,
+ &waitBytes
+ ));
+
+ /* Compute the location if WAIT command. */
+ waitPhysical = waitLinkPhysical + waitOffset;
+ waitLogical = waitLinkLogical + waitOffset;
+ waitAddress = waitLinkAddress + waitOffset;
+
+ /* Determine the location to jump to for the command buffer being
+ ** scheduled. */
+ if (Command->newQueue)
+ {
+ /* New command queue, jump to the beginning of it. */
+ execOffset = 0;
+ execLogical = Command->logical;
+ execAddress = Command->address;
+ execBytes = waitLinkOffset + waitLinkBytes;
+ }
+ else
+ {
+ /* Still within the preexisting command queue, jump directly to the
+ reserved area. */
+ execOffset = Command->offset;
+ execLogical = (gctUINT8 *) Command->logical + Command->offset;
+ execAddress = Command->address + Command->offset;
+ execBytes = RequestedBytes + waitLinkBytes;
+ }
+
+ /* Flush the cache. */
+ gcmkONERROR(gckOS_CacheClean(
+ Command->os,
+ 0,
+ Command->physHandle,
+ execOffset,
+ execLogical,
+ execBytes
+ ));
+
+ /* Convert the last WAIT into a LINK. */
+ gcmkONERROR(gckHARDWARE_Link(
+ Command->kernel->hardware,
+ Command->waitLogical,
+ execAddress,
+ execBytes,
+ &Command->waitSize,
+ &linkLow,
+ &linkHigh
+ ));
+
+ /* Flush the cache. */
+ gcmkONERROR(gckOS_CacheClean(
+ Command->os,
+ 0,
+ Command->physHandle,
+ waitLinkOffset + waitOffset,
+ Command->waitLogical,
+ Command->waitSize
+ ));
+
+#if gcdLINK_QUEUE_SIZE
+ if (Command->kernel->stuckDump >= gcvSTUCK_DUMP_ALL_COMMAND)
+ {
+ gcuQUEUEDATA data;
+
+ gcmkVERIFY_OK(gckOS_GetProcessID(&data.linkData.pid));
+
+ data.linkData.start = execAddress;
+ data.linkData.end = execAddress + execBytes;
+ data.linkData.linkLow = linkLow;
+ data.linkData.linkHigh = linkHigh;
+
+ gckQUEUE_Enqueue(&Command->kernel->hardware->linkQueue, &data);
+ }
+#endif
+
+ gcmkDUMPCOMMAND(
+ Command->os,
+ Command->waitLogical,
+ Command->waitSize,
+ gcvDUMP_BUFFER_LINK,
+ gcvFALSE
+ );
+
+ gcmkDUMPCOMMAND(
+ Command->os,
+ execLogical,
+ execBytes,
+ gcvDUMP_BUFFER_KERNEL,
+ gcvFALSE
+ );
+
+ /* Update the pointer to the last WAIT. */
+ Command->waitPhysical = waitPhysical;
+ Command->waitLogical = waitLogical;
+ Command->waitAddress = waitAddress;
+ Command->waitSize = waitBytes;
+
+ /* Update the command queue. */
+ Command->offset += RequestedBytes + waitLinkBytes;
+ Command->newQueue = gcvFALSE;
+
+ /* Update queue tail pointer. */
+ gcmkONERROR(gckHARDWARE_UpdateQueueTail(
+ Command->kernel->hardware, Command->logical, Command->offset
+ ));
+
+#if gcdDUMP_COMMAND
+ gcmkPRINT("@[kernel.execute]");
+#endif
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+/*******************************************************************************
+**
+** gckCOMMAND_Stall
+**
+** The calling thread will be suspended until the command queue has been
+** completed.
+**
+** INPUT:
+**
+** gckCOMMAND Command
+** Pointer to an gckCOMMAND object.
+**
+** gctBOOL FromPower
+** Determines whether the call originates from inside the power
+** management or not.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckCOMMAND_Stall(
+ IN gckCOMMAND Command,
+ IN gctBOOL FromPower
+ )
+{
+#if gcdNULL_DRIVER
+ /* Do nothing with infinite hardware. */
+ return gcvSTATUS_OK;
+#else
+ gckOS os;
+ gckHARDWARE hardware;
+ gckEVENT eventObject;
+ gceSTATUS status;
+ gctSIGNAL signal = gcvNULL;
+ gctUINT timer = 0;
+
+ gcmkHEADER_ARG("Command=0x%x", Command);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Command, gcvOBJ_COMMAND);
+
+ /* Extract the gckOS object pointer. */
+ os = Command->os;
+ gcmkVERIFY_OBJECT(os, gcvOBJ_OS);
+
+ /* Extract the gckHARDWARE object pointer. */
+ hardware = Command->kernel->hardware;
+ gcmkVERIFY_OBJECT(hardware, gcvOBJ_HARDWARE);
+
+ /* Extract the gckEVENT object pointer. */
+ eventObject = Command->kernel->eventObj;
+ gcmkVERIFY_OBJECT(eventObject, gcvOBJ_EVENT);
+
+ /* Allocate the signal. */
+ gcmkONERROR(gckOS_CreateSignal(os, gcvTRUE, &signal));
+
+ /* Append the EVENT command to trigger the signal. */
+ gcmkONERROR(gckEVENT_Signal(eventObject, signal, gcvKERNEL_PIXEL));
+
+ /* Submit the event queue. */
+ gcmkONERROR(gckEVENT_Submit(eventObject, gcvTRUE, FromPower));
+
+#if gcdDUMP_COMMAND
+ gcmkPRINT("@[kernel.stall]");
+#endif
+
+ if (status == gcvSTATUS_CHIP_NOT_READY)
+ {
+ /* Error. */
+ goto OnError;
+ }
+
+ do
+ {
+ /* Wait for the signal. */
+ status = gckOS_WaitSignal(os, signal, !FromPower, gcdGPU_ADVANCETIMER);
+
+ if (status == gcvSTATUS_TIMEOUT)
+ {
+#if gcmIS_DEBUG(gcdDEBUG_CODE)
+ gctUINT32 idle;
+
+ /* Read idle register. */
+ gcmkVERIFY_OK(gckHARDWARE_GetIdle(
+ hardware, gcvFALSE, &idle
+ ));
+
+ gcmkTRACE(
+ gcvLEVEL_ERROR,
+ "%s(%d): idle=%08x",
+ __FUNCTION__, __LINE__, idle
+ );
+
+ gcmkVERIFY_OK(gckOS_MemoryBarrier(os, gcvNULL));
+#endif
+
+ /* Advance timer. */
+ timer += gcdGPU_ADVANCETIMER;
+ }
+ else if (status == gcvSTATUS_INTERRUPTED)
+ {
+ gcmkONERROR(gcvSTATUS_INTERRUPTED);
+ }
+
+ }
+ while (gcmIS_ERROR(status));
+
+ /* Bail out on timeout. */
+ if (gcmIS_ERROR(status))
+ {
+ /* Broadcast the stuck GPU. */
+ gcmkONERROR(gckOS_Broadcast(
+ os, hardware, gcvBROADCAST_GPU_STUCK
+ ));
+ }
+
+ /* Delete the signal. */
+ gcmkVERIFY_OK(gckOS_DestroySignal(os, signal));
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ if (signal != gcvNULL)
+ {
+ /* Free the signal. */
+ gcmkVERIFY_OK(gckOS_DestroySignal(os, signal));
+ }
+
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+#endif
+}
+
+/*******************************************************************************
+**
+** gckCOMMAND_Attach
+**
+** Attach user process.
+**
+** INPUT:
+**
+** gckCOMMAND Command
+** Pointer to a gckCOMMAND object.
+**
+** gctUINT32 ProcessID
+** Current process ID.
+**
+** OUTPUT:
+**
+** gckCONTEXT * Context
+** Pointer to a variable that will receive a pointer to a new
+** gckCONTEXT object.
+**
+** gctSIZE_T * StateCount
+** Pointer to a variable that will receive the number of states
+** in the context buffer.
+*/
+#if (gcdENABLE_3D || gcdENABLE_2D)
+gceSTATUS
+gckCOMMAND_Attach(
+ IN gckCOMMAND Command,
+ OUT gckCONTEXT * Context,
+ OUT gctSIZE_T * MaxState,
+ OUT gctUINT32 * NumStates,
+ IN gctUINT32 ProcessID
+ )
+{
+ gceSTATUS status;
+ gctBOOL acquired = gcvFALSE;
+
+ gcmkHEADER_ARG("Command=0x%x", Command);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Command, gcvOBJ_COMMAND);
+
+ /* Acquire the context switching mutex. */
+ gcmkONERROR(gckOS_AcquireMutex(
+ Command->os, Command->mutexContext, gcvINFINITE
+ ));
+ acquired = gcvTRUE;
+
+ /* Construct a gckCONTEXT object. */
+ gcmkONERROR(gckCONTEXT_Construct(
+ Command->os,
+ Command->kernel->hardware,
+ ProcessID,
+ Context
+ ));
+
+ /* Return the number of states in the context. */
+ * MaxState = (* Context)->maxState;
+ * NumStates = (* Context)->numStates;
+
+ /* Release the context switching mutex. */
+ gcmkONERROR(gckOS_ReleaseMutex(Command->os, Command->mutexContext));
+ acquired = gcvFALSE;
+
+ /* Success. */
+ gcmkFOOTER_ARG("*Context=0x%x", *Context);
+ return gcvSTATUS_OK;
+
+OnError:
+ /* Release mutex. */
+ if (acquired)
+ {
+ /* Release the context switching mutex. */
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(Command->os, Command->mutexContext));
+ acquired = gcvFALSE;
+ }
+
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+#endif
+
+/*******************************************************************************
+**
+** gckCOMMAND_Detach
+**
+** Detach user process.
+**
+** INPUT:
+**
+** gckCOMMAND Command
+** Pointer to a gckCOMMAND object.
+**
+** gckCONTEXT Context
+** Pointer to a gckCONTEXT object to be destroyed.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckCOMMAND_Detach(
+ IN gckCOMMAND Command,
+ IN gckCONTEXT Context
+ )
+{
+ gceSTATUS status;
+ gctBOOL acquired = gcvFALSE;
+
+ gcmkHEADER_ARG("Command=0x%x Context=0x%x", Command, Context);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Command, gcvOBJ_COMMAND);
+
+ /* Acquire the context switching mutex. */
+ gcmkONERROR(gckOS_AcquireMutex(
+ Command->os, Command->mutexContext, gcvINFINITE
+ ));
+ acquired = gcvTRUE;
+
+ /* Construct a gckCONTEXT object. */
+ gcmkONERROR(gckCONTEXT_Destroy(Context));
+
+ if (Command->currContext == Context)
+ {
+ /* Detach from gckCOMMAND object if the destoryed context is current context. */
+ Command->currContext = gcvNULL;
+ }
+
+ /* Release the context switching mutex. */
+ gcmkONERROR(gckOS_ReleaseMutex(Command->os, Command->mutexContext));
+ acquired = gcvFALSE;
+
+ /* Return the status. */
+ gcmkFOOTER();
+ return gcvSTATUS_OK;
+
+OnError:
+ /* Release mutex. */
+ if (acquired)
+ {
+ /* Release the context switching mutex. */
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(Command->os, Command->mutexContext));
+ acquired = gcvFALSE;
+ }
+
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+/*******************************************************************************
+**
+** gckCOMMAND_DumpExecutingBuffer
+**
+** Dump the command buffer which GPU is executing.
+**
+** INPUT:
+**
+** gckCOMMAND Command
+** Pointer to a gckCOMMAND object.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckCOMMAND_DumpExecutingBuffer(
+ IN gckCOMMAND Command
+ )
+{
+ gceSTATUS status;
+ gckVIRTUAL_COMMAND_BUFFER_PTR buffer = gcvNULL;
+ gctUINT32 gpuAddress;
+ gctSIZE_T pageCount;
+ gctPOINTER entry = gcvNULL;
+ gckOS os = Command->os;
+ gckKERNEL kernel = Command->kernel;
+ gctUINT32 i;
+ gctUINT32 dumpRear;
+ gckQUEUE queue = &kernel->hardware->linkQueue;
+ gctSIZE_T bytes;
+ gckLINKDATA linkData;
+ gcuQUEUEDATA * queueData;
+ gctUINT32 offset;
+ gctPOINTER entryDump;
+ gctUINT32 pid;
+ gctUINT8 processName[24] = {0};
+ gctPHYS_ADDR_T cpuPhysical;
+
+ gcmkPRINT("**************************\n");
+ gcmkPRINT("**** COMMAND BUF DUMP ****\n");
+ gcmkPRINT("**************************\n");
+
+ gcmkPRINT(" Submitted commit stamp = %lld", Command->commitStamp - 1);
+ gcmkPRINT(" Executed commit stamp = %lld", *(gctUINT64_PTR)Command->fence->logical);
+
+ gcmkVERIFY_OK(gckOS_ReadRegisterEx(os, kernel->core, 0x664, &gpuAddress));
+ gcmkVERIFY_OK(gckOS_ReadRegisterEx(os, kernel->core, 0x664, &gpuAddress));
+
+ gcmkPRINT("DMA Address 0x%08X, memory around:", gpuAddress);
+
+ /* Search and dump memory around DMA address. */
+ if (kernel->virtualCommandBuffer)
+ {
+ status = gckDEVICE_QueryGPUAddress(kernel->device, kernel, gpuAddress, &buffer);
+ }
+ else
+ {
+ status = gcvSTATUS_OK;
+ }
+
+ if (gcmIS_SUCCESS(status))
+ {
+ if (kernel->virtualCommandBuffer)
+ {
+ gcmkVERIFY_OK(gckOS_CreateKernelVirtualMapping(
+ os, buffer->virtualBuffer.physical, buffer->virtualBuffer.bytes, &entry, &pageCount));
+
+ offset = gpuAddress - buffer->virtualBuffer.gpuAddress;
+
+ entryDump = entry;
+
+ /* Dump one pages. */
+ bytes = 4096;
+
+ /* Align to page. */
+ offset &= 0xfffff000;
+
+ /* Kernel address of page where stall point stay. */
+ entryDump = (gctUINT8_PTR)entryDump + offset;
+
+ /* Align to page. */
+ gpuAddress &= 0xfffff000;
+ }
+ else
+ {
+ gcmkVERIFY_OK(gckOS_GPUPhysicalToCPUPhysical(os, gpuAddress, &cpuPhysical));
+
+ gcmkVERIFY_OK(gckOS_MapPhysical(os, (gctUINT32) cpuPhysical, 4096, &entry));
+
+ /* Align to page start. */
+ entryDump = (gctPOINTER)((gctUINTPTR_T)entry & ~0xFFF);
+ gpuAddress = gpuAddress & ~0xFFF;
+ bytes = 4096;
+ }
+
+ gcmkPRINT("User Command Buffer:\n");
+ _DumpBuffer(entryDump, gpuAddress, bytes);
+
+ if (kernel->virtualCommandBuffer)
+ {
+ gcmkVERIFY_OK(gckOS_DestroyKernelVirtualMapping(
+ os, buffer->virtualBuffer.physical, buffer->virtualBuffer.bytes, entry));
+ }
+ else
+ {
+ gcmkVERIFY_OK(gckOS_UnmapPhysical(os, entry, 4096));
+ }
+ }
+ else
+ {
+ _DumpKernelCommandBuffer(Command);
+ }
+
+ /* Dump link queue. */
+ if (queue->count)
+ {
+ gcmkPRINT("Dump Level is %d, dump %d valid record in link queue:",
+ Command->kernel->stuckDump, queue->count);
+
+ dumpRear = queue->count;
+
+ for (i = 0; i < dumpRear; i++)
+ {
+ gckQUEUE_GetData(queue, i, &queueData);
+
+ linkData = &queueData->linkData;
+
+ /* Get gpu address of this command buffer. */
+ gpuAddress = linkData->start;
+ bytes = linkData->end - gpuAddress;
+
+ pid = linkData->pid;
+
+ gckOS_GetProcessNameByPid(pid, 16, processName);
+
+ if (kernel->virtualCommandBuffer)
+ {
+ buffer = gcvNULL;
+
+ /* Get the whole buffer. */
+ status = gckDEVICE_QueryGPUAddress(kernel->device, kernel, gpuAddress, &buffer);
+
+ if (gcmIS_ERROR(status))
+ {
+ /* Get kernel address of kernel command buffer. */
+ status = gckCOMMAND_AddressInKernelCommandBuffer(
+ kernel->command, gpuAddress, &entry);
+
+ if (gcmIS_ERROR(status))
+ {
+ status = gckHARDWARE_AddressInHardwareFuncions(
+ kernel->hardware, gpuAddress, &entry);
+
+ if (gcmIS_ERROR(status))
+ {
+ gcmkPRINT("Buffer [%08X - %08X] not found, may be freed",
+ linkData->start,
+ linkData->end);
+ continue;
+ }
+ }
+
+ offset = 0;
+ gcmkPRINT("Kernel Command Buffer: %08X, %08X", linkData->linkLow, linkData->linkHigh);
+ }
+ else
+ {
+ /* Get kernel logical for dump. */
+ if (buffer->virtualBuffer.kernelLogical)
+ {
+ /* Get kernel logical directly if it is a context buffer. */
+ entry = buffer->virtualBuffer.kernelLogical;
+ gcmkPRINT("Context Buffer: %08X, %08X PID:%d %s",
+ linkData->linkLow, linkData->linkHigh, linkData->pid, processName);
+ }
+ else
+ {
+ /* Make it accessiable by kernel if it is a user command buffer. */
+ gcmkVERIFY_OK(
+ gckOS_CreateKernelVirtualMapping(os,
+ buffer->virtualBuffer.physical,
+ buffer->virtualBuffer.bytes,
+ &entry,
+ &pageCount));
+ gcmkPRINT("User Command Buffer: %08X, %08X PID:%d %s",
+ linkData->linkLow, linkData->linkHigh, linkData->pid, processName);
+ }
+
+ offset = gpuAddress - buffer->virtualBuffer.gpuAddress;
+ }
+
+ /* Dump from the entry. */
+ _DumpBuffer((gctUINT8_PTR)entry + offset, gpuAddress, bytes);
+
+ /* Release kernel logical address if neccessary. */
+ if (buffer && !buffer->virtualBuffer.kernelLogical)
+ {
+ gcmkVERIFY_OK(
+ gckOS_DestroyKernelVirtualMapping(os,
+ buffer->virtualBuffer.physical,
+ buffer->virtualBuffer.bytes,
+ entry));
+ }
+ }
+ else
+ {
+ gcmkVERIFY_OK(gckOS_GPUPhysicalToCPUPhysical(os, gpuAddress, &cpuPhysical));
+
+ gcmkVERIFY_OK(gckOS_MapPhysical(os, (gctUINT32) cpuPhysical, bytes, &entry));
+
+ gcmkPRINT("Command Buffer: %08X, %08X PID:%d %s",
+ linkData->linkLow, linkData->linkHigh, linkData->pid, processName);
+
+ _DumpBuffer((gctUINT8_PTR)entry, gpuAddress, bytes);
+
+ gcmkVERIFY_OK(gckOS_UnmapPhysical(os, entry, bytes));
+ }
+ }
+ }
+
+ return gcvSTATUS_OK;
+}
+
+gceSTATUS
+gckCOMMAND_AddressInKernelCommandBuffer(
+ IN gckCOMMAND Command,
+ IN gctUINT32 Address,
+ OUT gctPOINTER * Pointer
+ )
+{
+ gctINT i;
+
+ for (i = 0; i < gcdCOMMAND_QUEUES; i++)
+ {
+ if ((Address >= Command->queues[i].address)
+ && (Address < (Command->queues[i].address + Command->pageSize))
+ )
+ {
+ *Pointer = (gctUINT8_PTR)Command->queues[i].logical
+ + (Address - Command->queues[i].address)
+ ;
+
+ return gcvSTATUS_OK;
+ }
+ }
+
+ return gcvSTATUS_NOT_FOUND;
+}
+
diff --git a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_command_vg.c b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_command_vg.c
new file mode 100644
index 000000000000..6c30ceb5027a
--- /dev/null
+++ b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_command_vg.c
@@ -0,0 +1,3950 @@
+/****************************************************************************
+*
+* The MIT License (MIT)
+*
+* Copyright (c) 2014 - 2018 Vivante 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 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 GPL License (GPL)
+*
+* Copyright (C) 2014 - 2018 Vivante 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.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+*****************************************************************************
+*
+* Note: This software is released under dual MIT and GPL licenses. A
+* recipient may use this file under the terms of either the MIT license or
+* GPL License. If you wish to use only one license not the other, you can
+* indicate your decision by deleting one of the above license notices in your
+* version of this file.
+*
+*****************************************************************************/
+
+
+#include "gc_hal_kernel_precomp.h"
+
+#if gcdENABLE_VG
+
+#include "gc_hal_kernel_hardware_command_vg.h"
+
+#define _GC_OBJ_ZONE gcvZONE_COMMAND
+
+#ifdef __QNXNTO__
+extern gceSTATUS
+drv_signal_mgr_add(
+ gctUINT32 Pid,
+ gctINT32 Coid,
+ gctINT32 Rcvid,
+ gctUINT64 Signal,
+ gctPOINTER *Handle);
+#endif
+
+/******************************************************************************\
+*********************************** Debugging **********************************
+\******************************************************************************/
+
+#define gcvDISABLE_TIMEOUT 1
+#define gcvDUMP_COMMAND_BUFFER 0
+#define gcvDUMP_COMMAND_LINES 0
+
+
+#if gcvDEBUG || defined(EMULATOR) || gcvDISABLE_TIMEOUT
+# define gcvQUEUE_TIMEOUT ~0
+#else
+# define gcvQUEUE_TIMEOUT 10
+#endif
+
+
+/******************************************************************************\
+********************************** Definitions *********************************
+\******************************************************************************/
+
+/* Minimum buffer size. */
+#define gcvMINUMUM_BUFFER \
+ gcmSIZEOF(gcsKERNEL_QUEUE_HEADER) + \
+ gcmSIZEOF(gcsKERNEL_CMDQUEUE) * 2
+
+#define gcmDECLARE_INTERRUPT_HANDLER(Block, Number) \
+ static gceSTATUS \
+ _EventHandler_##Block##_##Number( \
+ IN gckVGKERNEL Kernel \
+ )
+
+#define gcmDEFINE_INTERRUPT_HANDLER(Block, Number) \
+ gcmDECLARE_INTERRUPT_HANDLER(Block, Number) \
+ { \
+ return _EventHandler_Block( \
+ Kernel, \
+ &Kernel->command->taskTable[gcvBLOCK_##Block], \
+ gcvFALSE \
+ ); \
+ }
+
+#define gcmDEFINE_INTERRUPT_HANDLER_ENTRY(Block, Number) \
+ { gcvBLOCK_##Block, _EventHandler_##Block##_##Number }
+
+/* Block interrupt handling table entry. */
+typedef struct _gcsBLOCK_INTERRUPT_HANDLER * gcsBLOCK_INTERRUPT_HANDLER_PTR;
+typedef struct _gcsBLOCK_INTERRUPT_HANDLER
+{
+ gceBLOCK block;
+ gctINTERRUPT_HANDLER handler;
+}
+gcsBLOCK_INTERRUPT_HANDLER;
+
+/* Queue control functions. */
+typedef struct _gcsQUEUE_UPDATE_CONTROL * gcsQUEUE_UPDATE_CONTROL_PTR;
+typedef struct _gcsQUEUE_UPDATE_CONTROL
+{
+ gctOBJECT_HANDLER execute;
+ gctOBJECT_HANDLER update;
+ gctOBJECT_HANDLER lastExecute;
+ gctOBJECT_HANDLER lastUpdate;
+}
+gcsQUEUE_UPDATE_CONTROL;
+
+
+/******************************************************************************\
+********************************* Support Code *********************************
+\******************************************************************************/
+static gceSTATUS
+_FlushMMU(
+ IN gckVGCOMMAND Command
+ )
+{
+ gceSTATUS status;
+ gctUINT32 oldValue;
+ gckVGHARDWARE hardware = Command->hardware;
+
+ gcmkONERROR(gckOS_AtomicExchange(Command->os,
+ hardware->pageTableDirty,
+ 0,
+ &oldValue));
+
+ if (oldValue)
+ {
+ /* Page Table is upated, flush mmu before commit. */
+ gcmkONERROR(gckVGHARDWARE_FlushMMU(hardware));
+ }
+
+ return gcvSTATUS_OK;
+OnError:
+ return status;
+}
+
+static gceSTATUS
+_WaitForIdle(
+ IN gckVGCOMMAND Command,
+ IN gcsKERNEL_QUEUE_HEADER_PTR Queue
+ )
+{
+ gceSTATUS status = gcvSTATUS_OK;
+ gctUINT32 idle;
+ gctUINT timeout = 0;
+
+ /* Loop while not idle. */
+ while (Queue->pending)
+ {
+ /* Did we reach the timeout limit? */
+ if (timeout == gcvQUEUE_TIMEOUT)
+ {
+ /* Hardware is probably dead... */
+ return gcvSTATUS_TIMEOUT;
+ }
+
+ /* Sleep for 100ms. */
+ gcmkERR_BREAK(gckOS_Delay(Command->os, 100));
+
+ /* Not the first loop? */
+ if (timeout > 0)
+ {
+ /* Read IDLE register. */
+ gcmkVERIFY_OK(gckVGHARDWARE_GetIdle(Command->hardware, &idle));
+
+ gcmkTRACE_ZONE(
+ gcvLEVEL_ERROR, gcvZONE_COMMAND,
+ "%s: timeout, IDLE=%08X\n",
+ __FUNCTION__, idle
+ );
+ }
+
+ /* Increment the timeout counter. */
+ timeout += 1;
+ }
+
+ /* Return status. */
+ return status;
+}
+
+static gctINT32
+_GetNextInterrupt(
+ IN gckVGCOMMAND Command,
+ IN gceBLOCK Block
+ )
+{
+ gctUINT index;
+ gcsBLOCK_TASK_ENTRY_PTR entry;
+ gctINT32 interrupt;
+
+ /* Get the block entry. */
+ entry = &Command->taskTable[Block];
+
+ /* Make sure we have initialized interrupts. */
+ gcmkASSERT(entry->interruptCount > 0);
+
+ /* Decrement the interrupt usage semaphore. */
+ gcmkVERIFY_OK(gckOS_DecrementSemaphore(
+ Command->os, entry->interruptSemaphore
+ ));
+
+ /* Get the value index. */
+ index = entry->interruptIndex;
+
+ /* Get the interrupt value. */
+ interrupt = entry->interruptArray[index];
+
+ /* Must be a valid value. */
+ gcmkASSERT((interrupt >= 0) && (interrupt <= 31));
+
+ /* Advance the index to the next value. */
+ index += 1;
+
+ /* Set the new index. */
+ entry->interruptIndex = (index == entry->interruptCount)
+ ? 0
+ : index;
+
+ /* Return interrupt value. */
+ return interrupt;
+}
+
+
+/******************************************************************************\
+***************************** Task Storage Management **************************
+\******************************************************************************/
+
+/* Minimum task buffer size. */
+#define gcvMIN_TASK_BUFFER \
+( \
+ gcmSIZEOF(gcsTASK_CONTAINER) + 128 \
+)
+
+/* Free list terminator. */
+#define gcvFREE_TASK_TERMINATOR \
+( \
+ (gcsTASK_CONTAINER_PTR) gcmINT2PTR(~0) \
+)
+
+
+/*----------------------------------------------------------------------------*/
+/*------------------- Allocated Task Buffer List Management ------------------*/
+
+static void
+_InsertTaskBuffer(
+ IN gcsTASK_CONTAINER_PTR AddAfter,
+ IN gcsTASK_CONTAINER_PTR Buffer
+ )
+{
+ gcsTASK_CONTAINER_PTR addBefore;
+
+ /* Cannot add before the first buffer. */
+ gcmkASSERT(AddAfter != gcvNULL);
+
+ /* Create a shortcut to the next buffer. */
+ addBefore = AddAfter->allocNext;
+
+ /* Initialize the links. */
+ Buffer->allocPrev = AddAfter;
+ Buffer->allocNext = addBefore;
+
+ /* Link to the previous buffer. */
+ AddAfter->allocNext = Buffer;
+
+ /* Link to the next buffer. */
+ if (addBefore != gcvNULL)
+ {
+ addBefore->allocPrev = Buffer;
+ }
+}
+
+static void
+_RemoveTaskBuffer(
+ IN gcsTASK_CONTAINER_PTR Buffer
+ )
+{
+ gcsTASK_CONTAINER_PTR prev;
+ gcsTASK_CONTAINER_PTR next;
+
+ /* Cannot remove the first buffer. */
+ gcmkASSERT(Buffer->allocPrev != gcvNULL);
+
+ /* Create shortcuts to the previous and next buffers. */
+ prev = Buffer->allocPrev;
+ next = Buffer->allocNext;
+
+ /* Tail buffer? */
+ if (next == gcvNULL)
+ {
+ /* Remove from the list. */
+ prev->allocNext = gcvNULL;
+ }
+
+ /* Buffer from the middle. */
+ else
+ {
+ prev->allocNext = next;
+ next->allocPrev = prev;
+ }
+}
+
+
+/*----------------------------------------------------------------------------*/
+/*--------------------- Free Task Buffer List Management ---------------------*/
+
+static void
+_AppendToFreeList(
+ IN gckVGCOMMAND Command,
+ IN gcsTASK_CONTAINER_PTR Buffer
+ )
+{
+ /* Cannot be a part of the free list already. */
+ gcmkASSERT(Buffer->freePrev == gcvNULL);
+ gcmkASSERT(Buffer->freeNext == gcvNULL);
+
+ /* First buffer to add? */
+ if (Command->taskFreeHead == gcvNULL)
+ {
+ /* Terminate the links. */
+ Buffer->freePrev = gcvFREE_TASK_TERMINATOR;
+ Buffer->freeNext = gcvFREE_TASK_TERMINATOR;
+
+ /* Initialize the list pointer. */
+ Command->taskFreeHead = Command->taskFreeTail = Buffer;
+ }
+
+ /* Not the first, add after the tail. */
+ else
+ {
+ /* Initialize the new tail buffer. */
+ Buffer->freePrev = Command->taskFreeTail;
+ Buffer->freeNext = gcvFREE_TASK_TERMINATOR;
+
+ /* Add after the tail. */
+ Command->taskFreeTail->freeNext = Buffer;
+ Command->taskFreeTail = Buffer;
+ }
+}
+
+static void
+_RemoveFromFreeList(
+ IN gckVGCOMMAND Command,
+ IN gcsTASK_CONTAINER_PTR Buffer
+ )
+{
+ /* Has to be a part of the free list. */
+ gcmkASSERT(Buffer->freePrev != gcvNULL);
+ gcmkASSERT(Buffer->freeNext != gcvNULL);
+
+ /* Head buffer? */
+ if (Buffer->freePrev == gcvFREE_TASK_TERMINATOR)
+ {
+ /* Tail buffer as well? */
+ if (Buffer->freeNext == gcvFREE_TASK_TERMINATOR)
+ {
+ /* Reset the list pointer. */
+ Command->taskFreeHead = Command->taskFreeTail = gcvNULL;
+ }
+
+ /* No, just the head. */
+ else
+ {
+ /* Update the head. */
+ Command->taskFreeHead = Buffer->freeNext;
+
+ /* Terminate the next buffer. */
+ Command->taskFreeHead->freePrev = gcvFREE_TASK_TERMINATOR;
+ }
+ }
+
+ /* Not the head. */
+ else
+ {
+ /* Tail buffer? */
+ if (Buffer->freeNext == gcvFREE_TASK_TERMINATOR)
+ {
+ /* Update the tail. */
+ Command->taskFreeTail = Buffer->freePrev;
+
+ /* Terminate the previous buffer. */
+ Command->taskFreeTail->freeNext = gcvFREE_TASK_TERMINATOR;
+ }
+
+ /* A buffer in the middle. */
+ else
+ {
+ /* Remove the buffer from the list. */
+ Buffer->freePrev->freeNext = Buffer->freeNext;
+ Buffer->freeNext->freePrev = Buffer->freePrev;
+ }
+ }
+
+ /* Reset free list pointers. */
+ Buffer->freePrev = gcvNULL;
+ Buffer->freeNext = gcvNULL;
+}
+
+
+/*----------------------------------------------------------------------------*/
+/*-------------------------- Task Buffer Allocation --------------------------*/
+
+static void
+_SplitTaskBuffer(
+ IN gckVGCOMMAND Command,
+ IN gcsTASK_CONTAINER_PTR Buffer,
+ IN gctUINT Size
+ )
+{
+ /* Determine the size of the new buffer. */
+ gctINT splitBufferSize = Buffer->size - Size;
+ gcmkASSERT(splitBufferSize >= 0);
+
+ /* Is the split buffer big enough to become a separate buffer? */
+ if (splitBufferSize >= gcvMIN_TASK_BUFFER)
+ {
+ /* Place the new path data. */
+ gcsTASK_CONTAINER_PTR splitBuffer = (gcsTASK_CONTAINER_PTR)
+ (
+ (gctUINT8_PTR) Buffer + Size
+ );
+
+ /* Set the trimmed buffer size. */
+ Buffer->size = Size;
+
+ /* Initialize the split buffer. */
+ splitBuffer->referenceCount = 0;
+ splitBuffer->size = splitBufferSize;
+ splitBuffer->freePrev = gcvNULL;
+ splitBuffer->freeNext = gcvNULL;
+
+ /* Link in. */
+ _InsertTaskBuffer(Buffer, splitBuffer);
+ _AppendToFreeList(Command, splitBuffer);
+ }
+}
+
+static gceSTATUS
+_AllocateTaskContainer(
+ IN gckVGCOMMAND Command,
+ IN gctUINT Size,
+ OUT gcsTASK_CONTAINER_PTR * Buffer
+ )
+{
+ gceSTATUS status;
+
+ gcmkHEADER_ARG("Command=0x%x Size=0x%x, Buffer ==0x%x", Command, Size, Buffer);
+
+ /* Verify arguments. */
+ gcmkVERIFY_ARGUMENT(Buffer != gcvNULL);
+
+ do
+ {
+ gcsTASK_STORAGE_PTR storage;
+ gcsTASK_CONTAINER_PTR buffer;
+
+ /* Adjust the size. */
+ Size += gcmSIZEOF(gcsTASK_CONTAINER);
+
+ /* Adjust the allocation size if not big enough. */
+ if (Size > Command->taskStorageUsable)
+ {
+ Command->taskStorageGranularity
+ = gcmALIGN(Size + gcmSIZEOF(gcsTASK_STORAGE), 1024);
+
+ Command->taskStorageUsable
+ = Command->taskStorageGranularity - gcmSIZEOF(gcsTASK_STORAGE);
+ }
+
+ /* Is there a free buffer available? */
+ else if (Command->taskFreeHead != gcvNULL)
+ {
+ /* Set the initial free buffer. */
+ gcsTASK_CONTAINER_PTR buffer = Command->taskFreeHead;
+
+ do
+ {
+ /* Is the buffer big enough? */
+ if (buffer->size >= Size)
+ {
+ /* Remove the buffer from the free list. */
+ _RemoveFromFreeList(Command, buffer);
+
+ /* Split the buffer. */
+ _SplitTaskBuffer(Command, buffer, Size);
+
+ /* Set the result. */
+ * Buffer = buffer;
+
+ gcmkFOOTER_ARG("*Buffer=0x%x",*Buffer);
+ /* Success. */
+ return gcvSTATUS_OK;
+ }
+
+ /* Get the next free buffer. */
+ buffer = buffer->freeNext;
+ }
+ while (buffer != gcvFREE_TASK_TERMINATOR);
+ }
+
+ /* Allocate a container. */
+ gcmkERR_BREAK(gckOS_Allocate(
+ Command->os,
+ Command->taskStorageGranularity,
+ (gctPOINTER *) &storage
+ ));
+
+ /* Link in the storage buffer. */
+ storage->next = Command->taskStorage;
+ Command->taskStorage = storage;
+
+ /* Place the task buffer. */
+ buffer = (gcsTASK_CONTAINER_PTR) (storage + 1);
+
+ /* Determine the size of the buffer. */
+ buffer->size
+ = Command->taskStorageGranularity
+ - gcmSIZEOF(gcsTASK_STORAGE);
+
+ /* Initialize the task buffer. */
+ buffer->referenceCount = 0;
+ buffer->allocPrev = gcvNULL;
+ buffer->allocNext = gcvNULL;
+ buffer->freePrev = gcvNULL;
+ buffer->freeNext = gcvNULL;
+
+ /* Split the buffer. */
+ _SplitTaskBuffer(Command, buffer, Size);
+
+ /* Set the result. */
+ * Buffer = buffer;
+
+ gcmkFOOTER_ARG("*Buffer=0x%x",*Buffer);
+ /* Success. */
+ return gcvSTATUS_OK;
+ }
+ while (gcvFALSE);
+
+ gcmkFOOTER();
+ /* Return status. */
+ return status;
+}
+
+static void
+_FreeTaskContainer(
+ IN gckVGCOMMAND Command,
+ IN gcsTASK_CONTAINER_PTR Buffer
+ )
+{
+ gcsTASK_CONTAINER_PTR prev;
+ gcsTASK_CONTAINER_PTR next;
+ gcsTASK_CONTAINER_PTR merged;
+
+ gctUINT32 mergedSize;
+
+ /* Verify arguments. */
+ gcmkASSERT(Buffer != gcvNULL);
+ gcmkASSERT(Buffer->freePrev == gcvNULL);
+ gcmkASSERT(Buffer->freeNext == gcvNULL);
+
+ /* Get shortcuts to the previous and next path data buffers. */
+ prev = Buffer->allocPrev;
+ next = Buffer->allocNext;
+
+ /* Is the previous path data buffer already free? */
+ if (prev && prev->freeNext)
+ {
+ /* The previous path data buffer is the one that remains. */
+ merged = prev;
+
+ /* Is the next path data buffer already free? */
+ if (next && next->freeNext)
+ {
+ /* Merge all three path data buffers into the previous. */
+ mergedSize = prev->size + Buffer->size + next->size;
+
+ /* Remove the next path data buffer. */
+ _RemoveFromFreeList(Command, next);
+ _RemoveTaskBuffer(next);
+ }
+ else
+ {
+ /* Merge the current path data buffer into the previous. */
+ mergedSize = prev->size + Buffer->size;
+ }
+
+ /* Delete the current path data buffer. */
+ _RemoveTaskBuffer(Buffer);
+
+ /* Set new size. */
+ merged->size = mergedSize;
+ }
+ else
+ {
+ /* The current path data buffer is the one that remains. */
+ merged = Buffer;
+
+ /* Is the next buffer already free? */
+ if (next && next->freeNext)
+ {
+ /* Merge the next into the current. */
+ mergedSize = Buffer->size + next->size;
+
+ /* Remove the next buffer. */
+ _RemoveFromFreeList(Command, next);
+ _RemoveTaskBuffer(next);
+
+ /* Set new size. */
+ merged->size = mergedSize;
+ }
+
+ /* Add the current buffer into the free list. */
+ _AppendToFreeList(Command, merged);
+ }
+}
+
+gceSTATUS
+_RemoveRecordFromProcesDB(
+ IN gckVGCOMMAND Command,
+ IN gcsTASK_HEADER_PTR Task
+ )
+{
+ gceSTATUS status;
+ gcsTASK_PTR task = (gcsTASK_PTR)((gctUINT8_PTR)Task - sizeof(gcsTASK));
+ gcsTASK_FREE_VIDEO_MEMORY_PTR freeVideoMemory;
+ gcsTASK_UNLOCK_VIDEO_MEMORY_PTR unlockVideoMemory;
+ gctINT pid;
+ gctUINT32 size,id;
+ gctUINT32 handle;
+ gckKERNEL kernel = Command->kernel->kernel;
+ gckVIDMEM_NODE unlockNode = gcvNULL;
+ gckVIDMEM_NODE nodeObject = gcvNULL;
+ gceDATABASE_TYPE type;
+
+ /* Get the total size of all tasks. */
+
+ gcmkVERIFY_OK(gckOS_GetProcessID((gctUINT32_PTR)&pid));
+ gcmkVERIFY_OK(gckOS_ReadMappedPointer(Command->os, &task->size, &size));
+
+ do
+ {
+ gcmkVERIFY_OK(gckOS_ReadMappedPointer(Command->os, &Task->id, &id));
+ switch (id)
+ {
+ case gcvTASK_FREE_VIDEO_MEMORY:
+ freeVideoMemory = (gcsTASK_FREE_VIDEO_MEMORY_PTR)Task;
+
+ gcmkVERIFY_OK(gckOS_ReadMappedPointer(Command->os, &freeVideoMemory->node, &handle));
+
+ status = gckVIDMEM_HANDLE_Lookup(
+ Command->kernel->kernel,
+ pid,
+ handle,
+ &nodeObject);
+
+ if (gcmIS_ERROR(status))
+ {
+ return status;
+ }
+
+ gckVIDMEM_HANDLE_Dereference(kernel, pid, handle);
+ gcmkVERIFY_OK(gckOS_WriteMemory(Command->os, &freeVideoMemory->node, gcmALL_TO_UINT32(nodeObject)));
+
+ type = gcvDB_VIDEO_MEMORY
+ | (nodeObject->type << gcdDB_VIDEO_MEMORY_TYPE_SHIFT)
+ | (nodeObject->pool << gcdDB_VIDEO_MEMORY_POOL_SHIFT);
+
+ /* Remove record from process db. */
+ gcmkVERIFY_OK(gckKERNEL_RemoveProcessDB(
+ Command->kernel->kernel,
+ pid,
+ type,
+ gcmINT2PTR(handle)));
+
+ /* Advance to next task. */
+ size -= sizeof(gcsTASK_FREE_VIDEO_MEMORY);
+ Task = (gcsTASK_HEADER_PTR)(freeVideoMemory + 1);
+
+ break;
+ case gcvTASK_UNLOCK_VIDEO_MEMORY:
+ unlockVideoMemory = (gcsTASK_UNLOCK_VIDEO_MEMORY_PTR)Task;
+
+ gcmkVERIFY_OK(gckOS_ReadMappedPointer(Command->os, &unlockVideoMemory->node, &handle));
+ /* Remove record from process db. */
+ gcmkVERIFY_OK(gckKERNEL_RemoveProcessDB(
+ Command->kernel->kernel,
+ pid,
+ gcvDB_VIDEO_MEMORY_LOCKED,
+ gcmUINT64_TO_PTR(handle)));
+
+
+ status = gckVIDMEM_HANDLE_Lookup(
+ Command->kernel->kernel,
+ pid,
+ handle,
+ &unlockNode);
+
+ if (gcmIS_ERROR(status))
+ {
+ return status;
+ }
+
+ gckVIDMEM_HANDLE_Dereference(kernel, pid, handle);
+ gcmkVERIFY_OK(gckOS_WriteMemory(Command->os, &unlockVideoMemory->node, gcmALL_TO_UINT32(unlockNode)));
+
+ /* Advance to next task. */
+ size -= sizeof(gcsTASK_UNLOCK_VIDEO_MEMORY);
+ Task = (gcsTASK_HEADER_PTR)(unlockVideoMemory + 1);
+
+ break;
+ default:
+ /* Skip the whole task. */
+ size = 0;
+ break;
+ }
+ }
+ while(size);
+
+ return gcvSTATUS_OK;
+}
+
+/******************************************************************************\
+********************************* Task Scheduling ******************************
+\******************************************************************************/
+
+static gceSTATUS
+_ScheduleTasks(
+ IN gckVGCOMMAND Command,
+ IN gcsTASK_MASTER_TABLE_PTR TaskTable,
+ IN gctUINT8_PTR PreviousEnd
+ )
+{
+ gceSTATUS status;
+
+ do
+ {
+ gctINT block;
+ gcsTASK_CONTAINER_PTR container;
+ gcsTASK_MASTER_ENTRY_PTR userTaskEntry;
+ gcsBLOCK_TASK_ENTRY_PTR kernelTaskEntry;
+ gcsTASK_PTR userTask;
+ gcsTASK userTaskObject;
+ gctUINT8_PTR kernelTask;
+ gctINT32 interrupt;
+ gctUINT8_PTR eventCommand;
+ gctBOOL needCopy = gcvFALSE;
+ gctINT pid;
+#ifdef __QNXNTO__
+ gcsTASK_PTR oldUserTask = gcvNULL;
+ gctPOINTER pointer;
+#endif
+
+ /* Nothing to schedule? */
+ if (TaskTable->size == 0)
+ {
+ status = gcvSTATUS_OK;
+ break;
+ }
+
+ /* Acquire the mutex. */
+ gcmkERR_BREAK(gckOS_AcquireMutex(
+ Command->os,
+ Command->taskMutex,
+ gcvINFINITE
+ ));
+
+ gcmkTRACE_ZONE(
+ gcvLEVEL_VERBOSE, gcvZONE_COMMAND,
+ "%s(%d)\n",
+ __FUNCTION__, __LINE__
+ );
+
+ gcmkVERIFY_OK(gckOS_GetProcessID((gctUINT32_PTR)&pid));
+ gcmkVERIFY_OK(gckOS_QueryNeedCopy(Command->os, pid, &needCopy));
+ do
+ {
+ gcmkTRACE_ZONE(
+ gcvLEVEL_VERBOSE, gcvZONE_COMMAND,
+ " number of tasks scheduled = %d\n"
+ " size of event data in bytes = %d\n",
+ TaskTable->count,
+ TaskTable->size
+ );
+
+ /* Allocate task buffer. */
+ gcmkERR_BREAK(_AllocateTaskContainer(
+ Command,
+ TaskTable->size,
+ &container
+ ));
+
+ /* Determine the task data pointer. */
+ kernelTask = (gctUINT8_PTR) (container + 1);
+
+ /* Initialize the reference count. */
+ container->referenceCount = TaskTable->count;
+
+ /* Process tasks. */
+ for (block = gcvBLOCK_COUNT - 1; block >= 0; block -= 1)
+ {
+ /* Get the current user table entry. */
+ userTaskEntry = &TaskTable->table[block];
+
+ /* Are there tasks scheduled? */
+ if (userTaskEntry->head == gcvNULL)
+ {
+ /* No, skip to the next block. */
+ continue;
+ }
+
+ gcmkTRACE_ZONE(
+ gcvLEVEL_VERBOSE, gcvZONE_COMMAND,
+ " processing tasks for block %d\n",
+ block
+ );
+
+ /* Get the current kernel table entry. */
+ kernelTaskEntry = &Command->taskTable[block];
+
+ /* Are there tasks for the current block scheduled? */
+ if (kernelTaskEntry->container == gcvNULL)
+ {
+ gcmkTRACE_ZONE(
+ gcvLEVEL_VERBOSE, gcvZONE_COMMAND,
+ " first task container for the block added\n",
+ block
+ );
+
+ /* Nothing yet, set the container buffer pointer. */
+ kernelTaskEntry->container = container;
+ kernelTaskEntry->task = (gcsTASK_HEADER_PTR) kernelTask;
+ }
+
+ /* Yes, append to the end. */
+ else
+ {
+ kernelTaskEntry->link->cotainer = container;
+ kernelTaskEntry->link->task = (gcsTASK_HEADER_PTR) kernelTask;
+ }
+
+ /* Set initial task. */
+ userTask = userTaskEntry->head;
+
+ gcmkTRACE_ZONE(
+ gcvLEVEL_VERBOSE, gcvZONE_COMMAND,
+ " copying user tasks over to the kernel\n"
+ );
+
+ /* Copy tasks. */
+ do
+ {
+ gcsTASK_HEADER_PTR taskHeader;
+#ifdef __QNXNTO__
+ oldUserTask = userTask;
+
+ gcmkERR_BREAK(gckOS_MapUserPointer(
+ Command->os,
+ oldUserTask,
+ 0,
+ &pointer));
+
+ userTask = pointer;
+#endif
+ taskHeader = (gcsTASK_HEADER_PTR) (userTask + 1);
+ if(needCopy)
+ {
+ gcmkERR_BREAK(gckOS_CopyFromUserData(
+ Command->os,
+ &userTaskObject,
+ userTask,
+ gcmSIZEOF(gcsTASK)
+ ));
+ userTask = &userTaskObject;
+ }
+
+ gcmkVERIFY_OK(_RemoveRecordFromProcesDB(Command, taskHeader));
+
+ gcmkTRACE_ZONE(
+ gcvLEVEL_VERBOSE, gcvZONE_COMMAND,
+ " task ID = %d, size = %d\n",
+ ((gcsTASK_HEADER_PTR) (userTask + 1))->id,
+ userTask->size
+ );
+
+ /* Copy the task data. */
+ if(needCopy)
+ {
+ gcmkERR_BREAK(gckOS_CopyFromUserData(
+ Command->os,
+ kernelTask,
+ taskHeader,
+ userTask->size
+ ));
+ }
+ else
+ {
+
+ gcmkERR_BREAK(gckOS_MemCopy(
+ kernelTask, taskHeader, userTask->size
+ ));
+ }
+#ifdef __QNXNTO__
+ if (taskHeader->id == gcvTASK_SIGNAL)
+ {
+ gcsTASK_SIGNAL_PTR taskSignal = (gcsTASK_SIGNAL_PTR)kernelTask;
+ gctPOINTER signal;
+ gctUINT32 pid;
+
+ gcmkVERIFY_OK(gckOS_GetProcessID(&pid));
+
+ taskSignal->coid = TaskTable->coid;
+ taskSignal->rcvid = TaskTable->rcvid;
+
+ gcmkERR_BREAK(drv_signal_mgr_add(
+ pid,
+ taskSignal->coid,
+ taskSignal->rcvid,
+ gcmPTR_TO_UINT64(taskSignal->signal),
+ &signal));
+
+ taskSignal->signal = signal;
+ }
+#endif
+
+ /* Advance to the next task. */
+ kernelTask += userTask->size;
+ userTask = userTask->next;
+
+#ifdef __QNXNTO__
+ gcmkERR_BREAK(gckOS_UnmapUserPointer(
+ Command->os,
+ oldUserTask,
+ 0,
+ pointer));
+#endif
+ }
+ while (userTask != gcvNULL);
+
+ /* Update link pointer in the header. */
+ kernelTaskEntry->link = (gcsTASK_LINK_PTR) kernelTask;
+
+ /* Initialize link task. */
+ kernelTaskEntry->link->id = gcvTASK_LINK;
+ kernelTaskEntry->link->cotainer = gcvNULL;
+ kernelTaskEntry->link->task = gcvNULL;
+
+ /* Advance the task data pointer. */
+ kernelTask += gcmSIZEOF(gcsTASK_LINK);
+ }
+ }
+ while (gcvFALSE);
+
+ /* Release the mutex. */
+ gcmkERR_BREAK(gckOS_ReleaseMutex(
+ Command->os,
+ Command->taskMutex
+ ));
+
+ /* Assign interrupts to the blocks. */
+ eventCommand = PreviousEnd;
+
+ for (block = gcvBLOCK_COUNT - 1; block >= 0; block -= 1)
+ {
+ /* Get the current user table entry. */
+ userTaskEntry = &TaskTable->table[block];
+
+ /* Are there tasks scheduled? */
+ if (userTaskEntry->head == gcvNULL)
+ {
+ /* No, skip to the next block. */
+ continue;
+ }
+
+ /* Get the interrupt number. */
+ interrupt = _GetNextInterrupt(Command, block);
+
+ gcmkTRACE_ZONE(
+ gcvLEVEL_VERBOSE, gcvZONE_COMMAND,
+ "%s(%d): block = %d interrupt = %d\n",
+ __FUNCTION__, __LINE__,
+ block, interrupt
+ );
+
+ /* Determine the command position. */
+ eventCommand -= Command->info.eventCommandSize;
+
+ /* Append an EVENT command. */
+ gcmkERR_BREAK(gckVGCOMMAND_EventCommand(
+ Command, eventCommand, block, interrupt, gcvNULL
+ ));
+ }
+ }
+ while (gcvFALSE);
+
+ /* Return status. */
+ return status;
+}
+
+
+/******************************************************************************\
+******************************** Memory Management *****************************
+\******************************************************************************/
+
+static gceSTATUS
+_HardwareToKernel(
+ IN gckOS Os,
+ IN gcuVIDMEM_NODE_PTR Node,
+ IN gctUINT32 Address,
+ OUT gctPOINTER * KernelPointer
+ )
+{
+ gceSTATUS status;
+ gckVIDMEM memory;
+ gctUINT32 offset;
+ gctUINT32 nodePhysical;
+ gctPOINTER *logical;
+ gctSIZE_T bytes;
+ status = gcvSTATUS_OK;
+
+ memory = Node->VidMem.memory;
+
+ if (memory->object.type == gcvOBJ_VIDMEM)
+ {
+ nodePhysical = memory->baseAddress
+ + (gctUINT32)Node->VidMem.offset
+ + Node->VidMem.alignment;
+ bytes = Node->VidMem.bytes;
+ logical = &Node->VidMem.kernelVirtual;
+ }
+ else
+ {
+ gcmkSAFECASTPHYSADDRT(nodePhysical, Node->Virtual.physicalAddress);
+ bytes = Node->Virtual.bytes;
+ logical = &Node->Virtual.kernelVirtual;
+ }
+
+ if (*logical == gcvNULL)
+ {
+ status = gckOS_MapPhysical(Os, nodePhysical, bytes, logical);
+
+ if (gcmkIS_ERROR(status))
+ {
+ return status;
+ }
+ }
+
+ offset = Address - nodePhysical;
+ *KernelPointer = (gctPOINTER)((gctUINT8_PTR)(*logical) + offset);
+
+ /* Return status. */
+ return status;
+}
+
+static gceSTATUS
+_ConvertUserCommandBufferPointer(
+ IN gckVGCOMMAND Command,
+ IN gcsCMDBUFFER_PTR UserCommandBuffer,
+ OUT gcsCMDBUFFER_PTR * KernelCommandBuffer
+ )
+{
+ gceSTATUS status, last;
+ gcsCMDBUFFER_PTR mappedUserCommandBuffer = gcvNULL;
+ gcsCMDBUFFER _CommandBufferObject;
+ gckKERNEL kernel = Command->kernel->kernel;
+ gctUINT32 pid;
+ gckVIDMEM_NODE node;
+ gctBOOL needCopy = gcvFALSE;
+
+ gckOS_GetProcessID(&pid);
+
+ do
+ {
+ gctUINT32 headerAddress;
+
+ gcmkERR_BREAK(gckOS_QueryNeedCopy(Command->os, pid, &needCopy));
+ if(needCopy)
+ {
+ gcmkERR_BREAK(gckOS_CopyFromUserData(
+ Command->os,
+ &_CommandBufferObject,
+ UserCommandBuffer,
+ gcmSIZEOF(gcsCMDBUFFER)
+ ));
+ mappedUserCommandBuffer = &_CommandBufferObject;
+ }
+ else
+ {
+ /* Map the command buffer structure into the kernel space. */
+ gcmkERR_BREAK(gckOS_MapUserPointer(
+ Command->os,
+ UserCommandBuffer,
+ gcmSIZEOF(gcsCMDBUFFER),
+ (gctPOINTER *) &mappedUserCommandBuffer
+ ));
+ }
+ /* Determine the address of the header. */
+ headerAddress
+ = mappedUserCommandBuffer->address
+ - mappedUserCommandBuffer->bufferOffset;
+
+ gcmkERR_BREAK(gckVIDMEM_HANDLE_Lookup(
+ kernel,
+ pid,
+ gcmPTR2INT32(mappedUserCommandBuffer->node),
+ &node));
+
+ /* Translate the logical address to the kernel space. */
+ gcmkERR_BREAK(_HardwareToKernel(
+ Command->os,
+ node->node,
+ headerAddress,
+ (gctPOINTER *) KernelCommandBuffer
+ ));
+ }
+ while (gcvFALSE);
+
+ /* Unmap the user command buffer. */
+ if (mappedUserCommandBuffer != gcvNULL && needCopy == gcvFALSE)
+ {
+ gcmkCHECK_STATUS(gckOS_UnmapUserPointer(
+ Command->os,
+ UserCommandBuffer,
+ gcmSIZEOF(gcsCMDBUFFER),
+ mappedUserCommandBuffer
+ ));
+ }
+
+ /* Return status. */
+ return status;
+}
+
+static gceSTATUS
+_AllocateLinear(
+ IN gckVGCOMMAND Command,
+ IN gctUINT Size,
+ IN gctUINT Alignment,
+ OUT gcuVIDMEM_NODE_PTR * Node,
+ OUT gctUINT32 * Address,
+ OUT gctPOINTER * Logical
+ )
+{
+ gceSTATUS status, last;
+ gctPOINTER logical;
+ gctPHYS_ADDR physical;
+ gctUINT32 address;
+ gctSIZE_T size = Size;
+ gctPHYS_ADDR_T paddr;
+
+ do
+ {
+ gcmkERR_BREAK(gckOS_AllocateContiguous(
+ Command->os,
+ gcvFALSE,
+ &size,
+ &physical,
+ &logical
+ ));
+
+ gcmkERR_BREAK(gckOS_GetPhysicalAddress(Command->os, logical, &paddr));
+
+ gcmkVERIFY_OK(gckOS_CPUPhysicalToGPUPhysical(Command->os, paddr, &paddr));
+
+ gcmkSAFECASTPHYSADDRT(address, paddr);
+
+ /* Set return values. */
+ * Node = physical;
+ * Address = address;
+ * Logical = logical;
+
+ /* Success. */
+ return gcvSTATUS_OK;
+ }
+ while (gcvFALSE);
+
+ /* Roll back. */
+ if (physical != gcvNULL)
+ {
+ /* Free the command buffer. */
+ gcmkCHECK_STATUS(gckOS_FreeContiguous(Command->os, physical, logical, size));
+ }
+
+ /* Return status. */
+ return status;
+}
+
+static gceSTATUS
+_FreeLinear(
+ IN gckVGKERNEL Kernel,
+ IN gcuVIDMEM_NODE_PTR Node,
+ IN gctPOINTER Logical
+ )
+{
+ gceSTATUS status = gcvSTATUS_OK;
+
+ do
+ {
+ gcmkERR_BREAK(gckOS_FreeContiguous(Kernel->os, Node, Logical, 1));
+ }
+ while (gcvFALSE);
+
+ /* Return status. */
+ return status;
+}
+
+gceSTATUS
+_AllocateCommandBuffer(
+ IN gckVGCOMMAND Command,
+ IN gctSIZE_T Size,
+ OUT gcsCMDBUFFER_PTR * CommandBuffer
+ )
+{
+ gceSTATUS status, last;
+ gcuVIDMEM_NODE_PTR node = gcvNULL;
+ gcsCMDBUFFER_PTR commandBuffer = gcvNULL;
+
+ do
+ {
+ gctUINT alignedHeaderSize;
+ gctUINT requestedSize;
+ gctUINT allocationSize;
+ gctUINT32 address = 0;
+ gctUINT8_PTR endCommand;
+
+ /* Determine the aligned header size. */
+ alignedHeaderSize
+ = (gctUINT32)gcmALIGN(gcmSIZEOF(gcsCMDBUFFER), Command->info.addressAlignment);
+
+ /* Align the requested size. */
+ requestedSize
+ = (gctUINT32)gcmALIGN(Size, Command->info.commandAlignment);
+
+ /* Determine the size of the buffer to allocate. */
+ allocationSize
+ = alignedHeaderSize
+ + requestedSize
+ + (gctUINT32)Command->info.staticTailSize;
+
+ /* Allocate the command buffer. */
+ gcmkERR_BREAK(_AllocateLinear(
+ Command,
+ allocationSize,
+ Command->info.addressAlignment,
+ &node,
+ &address,
+ (gctPOINTER *) &commandBuffer
+ ));
+
+ /* Initialize the structure. */
+ commandBuffer->completion = gcvVACANT_BUFFER;
+ commandBuffer->node = node;
+ commandBuffer->address = address + alignedHeaderSize;
+ commandBuffer->bufferOffset = alignedHeaderSize;
+ commandBuffer->size = requestedSize;
+ commandBuffer->offset = requestedSize;
+ commandBuffer->nextAllocated = gcvNULL;
+ commandBuffer->nextSubBuffer = gcvNULL;
+
+ /* Determine the data count. */
+ commandBuffer->dataCount
+ = (requestedSize + Command->info.staticTailSize)
+ / Command->info.commandAlignment;
+
+ /* Determine the location of the END command. */
+ endCommand
+ = (gctUINT8_PTR) commandBuffer
+ + alignedHeaderSize
+ + requestedSize;
+
+ /* Append an END command. */
+ gcmkERR_BREAK(gckVGCOMMAND_EndCommand(
+ Command,
+ endCommand,
+ Command->info.feBufferInt,
+ gcvNULL
+ ));
+
+ /* Set the return pointer. */
+ * CommandBuffer = commandBuffer;
+
+ /* Success. */
+ return gcvSTATUS_OK;
+ }
+ while (gcvFALSE);
+
+ /* Roll back. */
+ if (node != gcvNULL)
+ {
+ /* Free the command buffer. */
+ gcmkCHECK_STATUS(_FreeLinear(Command->kernel, node, commandBuffer));
+ }
+
+ /* Return status. */
+ return status;
+}
+
+static gceSTATUS
+_FreeCommandBuffer(
+ IN gckVGKERNEL Kernel,
+ IN gcsCMDBUFFER_PTR CommandBuffer
+ )
+{
+ gceSTATUS status;
+
+ /* Free the buffer. */
+ status = _FreeLinear(Kernel, CommandBuffer->node, CommandBuffer);
+
+ /* Return status. */
+ return status;
+}
+
+
+/******************************************************************************\
+****************************** TS Overflow Handler *****************************
+\******************************************************************************/
+
+static gceSTATUS
+_EventHandler_TSOverflow(
+ IN gckVGKERNEL Kernel
+ )
+{
+ gcmkTRACE(
+ gcvLEVEL_ERROR,
+ "%s(%d): **** TS OVERFLOW ENCOUNTERED ****\n",
+ __FUNCTION__, __LINE__
+ );
+
+ return gcvSTATUS_OK;
+}
+
+
+/******************************************************************************\
+****************************** Bus Error Handler *******************************
+\******************************************************************************/
+
+static gceSTATUS
+_EventHandler_BusError(
+ IN gckVGKERNEL Kernel
+ )
+{
+ gcmkTRACE(
+ gcvLEVEL_ERROR,
+ "%s(%d): **** BUS ERROR ENCOUNTERED ****\n",
+ __FUNCTION__, __LINE__
+ );
+
+ return gcvSTATUS_OK;
+}
+
+/******************************************************************************\
+****************************** Power Stall Handler *******************************
+\******************************************************************************/
+
+static gceSTATUS
+_EventHandler_PowerStall(
+ IN gckVGKERNEL Kernel
+ )
+{
+ /* Signal. */
+ return gckOS_Signal(
+ Kernel->os,
+ Kernel->command->powerStallSignal,
+ gcvTRUE);
+}
+
+/******************************************************************************\
+******************************** Task Routines *********************************
+\******************************************************************************/
+
+typedef gceSTATUS (* gctTASKROUTINE) (
+ gckVGCOMMAND Command,
+ gcsBLOCK_TASK_ENTRY_PTR TaskHeader
+ );
+
+static gceSTATUS
+_TaskLink(
+ gckVGCOMMAND Command,
+ gcsBLOCK_TASK_ENTRY_PTR TaskHeader
+ );
+
+static gceSTATUS
+_TaskCluster(
+ gckVGCOMMAND Command,
+ gcsBLOCK_TASK_ENTRY_PTR TaskHeader
+ );
+
+static gceSTATUS
+_TaskIncrement(
+ gckVGCOMMAND Command,
+ gcsBLOCK_TASK_ENTRY_PTR TaskHeader
+ );
+
+static gceSTATUS
+_TaskDecrement(
+ gckVGCOMMAND Command,
+ gcsBLOCK_TASK_ENTRY_PTR TaskHeader
+ );
+
+static gceSTATUS
+_TaskSignal(
+ gckVGCOMMAND Command,
+ gcsBLOCK_TASK_ENTRY_PTR TaskHeader
+ );
+
+static gceSTATUS
+_TaskLockdown(
+ gckVGCOMMAND Command,
+ gcsBLOCK_TASK_ENTRY_PTR TaskHeader
+ );
+
+static gceSTATUS
+_TaskUnlockVideoMemory(
+ gckVGCOMMAND Command,
+ gcsBLOCK_TASK_ENTRY_PTR TaskHeader
+ );
+
+static gceSTATUS
+_TaskFreeVideoMemory(
+ gckVGCOMMAND Command,
+ gcsBLOCK_TASK_ENTRY_PTR TaskHeader
+ );
+
+static gceSTATUS
+_TaskFreeContiguousMemory(
+ gckVGCOMMAND Command,
+ gcsBLOCK_TASK_ENTRY_PTR TaskHeader
+ );
+
+static gceSTATUS
+_TaskUnmapUserMemory(
+ gckVGCOMMAND Command,
+ gcsBLOCK_TASK_ENTRY_PTR TaskHeader
+ );
+
+static gctTASKROUTINE _taskRoutine[] =
+{
+ _TaskLink, /* gcvTASK_LINK */
+ _TaskCluster, /* gcvTASK_CLUSTER */
+ _TaskIncrement, /* gcvTASK_INCREMENT */
+ _TaskDecrement, /* gcvTASK_DECREMENT */
+ _TaskSignal, /* gcvTASK_SIGNAL */
+ _TaskLockdown, /* gcvTASK_LOCKDOWN */
+ _TaskUnlockVideoMemory, /* gcvTASK_UNLOCK_VIDEO_MEMORY */
+ _TaskFreeVideoMemory, /* gcvTASK_FREE_VIDEO_MEMORY */
+ _TaskFreeContiguousMemory, /* gcvTASK_FREE_CONTIGUOUS_MEMORY */
+ _TaskUnmapUserMemory, /* gcvTASK_UNMAP_USER_MEMORY */
+};
+
+static gceSTATUS
+_TaskLink(
+ gckVGCOMMAND Command,
+ gcsBLOCK_TASK_ENTRY_PTR TaskHeader
+ )
+{
+ /* Cast the task pointer. */
+ gcsTASK_LINK_PTR task = (gcsTASK_LINK_PTR) TaskHeader->task;
+
+ /* Save the pointer to the container. */
+ gcsTASK_CONTAINER_PTR container = TaskHeader->container;
+
+ /* No more tasks in the list? */
+ if (task->task == gcvNULL)
+ {
+ /* Reset the entry. */
+ TaskHeader->container = gcvNULL;
+ TaskHeader->task = gcvNULL;
+ TaskHeader->link = gcvNULL;
+ }
+ else
+ {
+ /* Update the entry. */
+ TaskHeader->container = task->cotainer;
+ TaskHeader->task = task->task;
+ }
+
+ /* Decrement the task buffer reference. */
+ gcmkASSERT(container->referenceCount >= 0);
+ if (container->referenceCount == 0)
+ {
+ /* Free the container. */
+ _FreeTaskContainer(Command, container);
+ }
+
+ /* Success. */
+ return gcvSTATUS_OK;
+}
+
+static gceSTATUS
+_TaskCluster(
+ gckVGCOMMAND Command,
+ gcsBLOCK_TASK_ENTRY_PTR TaskHeader
+ )
+{
+ gceSTATUS status = gcvSTATUS_OK;
+
+ /* Cast the task pointer. */
+ gcsTASK_CLUSTER_PTR cluster = (gcsTASK_CLUSTER_PTR) TaskHeader->task;
+
+ /* Get the number of tasks. */
+ gctUINT taskCount = cluster->taskCount;
+
+ /* Advance to the next task. */
+ TaskHeader->task = (gcsTASK_HEADER_PTR) (cluster + 1);
+
+ /* Perform all tasks in the cluster. */
+ while (taskCount)
+ {
+ /* Perform the current task. */
+ gcmkERR_BREAK(_taskRoutine[TaskHeader->task->id](
+ Command,
+ TaskHeader
+ ));
+
+ /* Update the task count. */
+ taskCount -= 1;
+ }
+
+ /* Return status. */
+ return status;
+}
+
+static gceSTATUS
+_TaskIncrement(
+ gckVGCOMMAND Command,
+ gcsBLOCK_TASK_ENTRY_PTR TaskHeader
+ )
+{
+ gceSTATUS status;
+
+ do
+ {
+ /* Cast the task pointer. */
+ gcsTASK_INCREMENT_PTR task = (gcsTASK_INCREMENT_PTR) TaskHeader->task;
+
+ /* Convert physical into logical address. */
+ gctUINT32_PTR logical;
+ gcmkERR_BREAK(gckOS_MapPhysical(
+ Command->os,
+ task->address,
+ gcmSIZEOF(gctUINT32),
+ (gctPOINTER *) &logical
+ ));
+
+ /* Increment data. */
+ (* logical) += 1;
+
+ /* Unmap the physical memory. */
+ gcmkERR_BREAK(gckOS_UnmapPhysical(
+ Command->os,
+ logical,
+ gcmSIZEOF(gctUINT32)
+ ));
+
+ /* Update the reference counter. */
+ TaskHeader->container->referenceCount -= 1;
+
+ /* Update the task pointer. */
+ TaskHeader->task = (gcsTASK_HEADER_PTR) (task + 1);
+ }
+ while (gcvFALSE);
+
+ /* Return status. */
+ return status;
+}
+
+static gceSTATUS
+_TaskDecrement(
+ gckVGCOMMAND Command,
+ gcsBLOCK_TASK_ENTRY_PTR TaskHeader
+ )
+{
+ gceSTATUS status;
+
+ do
+ {
+ /* Cast the task pointer. */
+ gcsTASK_DECREMENT_PTR task = (gcsTASK_DECREMENT_PTR) TaskHeader->task;
+
+ /* Convert physical into logical address. */
+ gctUINT32_PTR logical;
+ gcmkERR_BREAK(gckOS_MapPhysical(
+ Command->os,
+ task->address,
+ gcmSIZEOF(gctUINT32),
+ (gctPOINTER *) &logical
+ ));
+
+ /* Decrement data. */
+ (* logical) -= 1;
+
+ /* Unmap the physical memory. */
+ gcmkERR_BREAK(gckOS_UnmapPhysical(
+ Command->os,
+ logical,
+ gcmSIZEOF(gctUINT32)
+ ));
+
+ /* Update the reference counter. */
+ TaskHeader->container->referenceCount -= 1;
+
+ /* Update the task pointer. */
+ TaskHeader->task = (gcsTASK_HEADER_PTR) (task + 1);
+ }
+ while (gcvFALSE);
+
+ /* Return status. */
+ return status;
+}
+
+static gceSTATUS
+_TaskSignal(
+ gckVGCOMMAND Command,
+ gcsBLOCK_TASK_ENTRY_PTR TaskHeader
+ )
+{
+ gceSTATUS status;
+
+ do
+ {
+ /* Cast the task pointer. */
+ gcsTASK_SIGNAL_PTR task = (gcsTASK_SIGNAL_PTR) TaskHeader->task;
+
+
+ /* Map the signal into kernel space. */
+#ifdef __QNXNTO__
+ status = gckOS_UserSignal(
+ Command->os, task->signal, task->rcvid, task->coid
+ );
+#else
+ status = gckOS_UserSignal(
+ Command->os, task->signal, task->process
+ );
+#endif /* __QNXNTO__ */
+
+ if (gcmIS_ERROR(status))
+ {
+ if (status == gcvSTATUS_NOT_FOUND)
+ {
+ status = gcvSTATUS_OK;
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ /* Update the reference counter. */
+ TaskHeader->container->referenceCount -= 1;
+
+ /* Update the task pointer. */
+ TaskHeader->task = (gcsTASK_HEADER_PTR) (task + 1);
+ }
+ while (gcvFALSE);
+
+ /* Return status. */
+ return status;
+}
+
+static gceSTATUS
+_TaskLockdown(
+ gckVGCOMMAND Command,
+ gcsBLOCK_TASK_ENTRY_PTR TaskHeader
+ )
+{
+ gceSTATUS status;
+ gctUINT32_PTR userCounter = gcvNULL;
+ gctUINT32_PTR kernelCounter = gcvNULL;
+ gctSIGNAL signal = gcvNULL;
+
+ do
+ {
+ /* Cast the task pointer. */
+ gcsTASK_LOCKDOWN_PTR task = (gcsTASK_LOCKDOWN_PTR) TaskHeader->task;
+
+ /* Convert physical addresses into logical. */
+ gcmkERR_BREAK(gckOS_MapPhysical(
+ Command->os,
+ task->userCounter,
+ gcmSIZEOF(gctUINT32),
+ (gctPOINTER *) &userCounter
+ ));
+
+ gcmkERR_BREAK(gckOS_MapPhysical(
+ Command->os,
+ task->kernelCounter,
+ gcmSIZEOF(gctUINT32),
+ (gctPOINTER *) &kernelCounter
+ ));
+
+ /* Update the kernel counter. */
+ (* kernelCounter) += 1;
+
+ /* Are the counters equal? */
+ if ((* userCounter) == (* kernelCounter))
+ {
+ /* Map the signal into kernel space. */
+ gcmkERR_BREAK(gckOS_MapSignal(
+ Command->os, task->signal, task->process, &signal
+ ));
+
+ if (signal == gcvNULL)
+ {
+ /* Signal. */
+ gcmkERR_BREAK(gckOS_Signal(
+ Command->os, task->signal, gcvTRUE
+ ));
+ }
+ else
+ {
+ /* Signal. */
+ gcmkERR_BREAK(gckOS_Signal(
+ Command->os, signal, gcvTRUE
+ ));
+ }
+ }
+
+ /* Update the reference counter. */
+ TaskHeader->container->referenceCount -= 1;
+
+ /* Update the task pointer. */
+ TaskHeader->task = (gcsTASK_HEADER_PTR) (task + 1);
+ }
+ while (gcvFALSE);
+
+ /* Destroy the mapped signal. */
+ if (signal != gcvNULL)
+ {
+ gcmkVERIFY_OK(gckOS_DestroySignal(
+ Command->os, signal
+ ));
+ }
+
+ /* Unmap the physical memory. */
+ if (kernelCounter != gcvNULL)
+ {
+ gcmkVERIFY_OK(gckOS_UnmapPhysical(
+ Command->os,
+ kernelCounter,
+ gcmSIZEOF(gctUINT32)
+ ));
+ }
+
+ if (userCounter != gcvNULL)
+ {
+ gcmkVERIFY_OK(gckOS_UnmapPhysical(
+ Command->os,
+ userCounter,
+ gcmSIZEOF(gctUINT32)
+ ));
+ }
+
+ /* Return status. */
+ return status;
+}
+
+static gceSTATUS
+_TaskUnlockVideoMemory(
+ gckVGCOMMAND Command,
+ gcsBLOCK_TASK_ENTRY_PTR TaskHeader
+ )
+{
+ gceSTATUS status;
+
+ do
+ {
+ /* Cast the task pointer. */
+ gcsTASK_UNLOCK_VIDEO_MEMORY_PTR task
+ = (gcsTASK_UNLOCK_VIDEO_MEMORY_PTR) TaskHeader->task;
+
+ /* Unlock video memory. */
+ gcmkERR_BREAK(gckVIDMEM_Unlock(
+ Command->kernel->kernel,
+ (gckVIDMEM_NODE)gcmUINT64_TO_PTR(task->node),
+ gcvSURF_TYPE_UNKNOWN,
+ gcvNULL));
+
+ gcmkERR_BREAK(gckVIDMEM_NODE_Dereference(
+ Command->kernel->kernel,
+ gcmUINT64_TO_PTR(task->node)));
+
+ /* Update the reference counter. */
+ TaskHeader->container->referenceCount -= 1;
+
+ /* Update the task pointer. */
+ TaskHeader->task = (gcsTASK_HEADER_PTR) (task + 1);
+ }
+ while (gcvFALSE);
+
+ /* Return status. */
+ return status;
+}
+
+static gceSTATUS
+_TaskFreeVideoMemory(
+ gckVGCOMMAND Command,
+ gcsBLOCK_TASK_ENTRY_PTR TaskHeader
+ )
+{
+ gceSTATUS status;
+
+ do
+ {
+ /* Cast the task pointer. */
+ gcsTASK_FREE_VIDEO_MEMORY_PTR task
+ = (gcsTASK_FREE_VIDEO_MEMORY_PTR) TaskHeader->task;
+
+ /* Free video memory. */
+ gcmkERR_BREAK(gckVIDMEM_NODE_Dereference(
+ Command->kernel->kernel,
+ gcmINT2PTR(task->node)));
+
+ /* Update the reference counter. */
+ TaskHeader->container->referenceCount -= 1;
+
+ /* Update the task pointer. */
+ TaskHeader->task = (gcsTASK_HEADER_PTR) (task + 1);
+ }
+ while (gcvFALSE);
+
+ /* Return status. */
+ return status;
+}
+
+static gceSTATUS
+_TaskFreeContiguousMemory(
+ gckVGCOMMAND Command,
+ gcsBLOCK_TASK_ENTRY_PTR TaskHeader
+ )
+{
+ gceSTATUS status;
+
+ do
+ {
+ /* Cast the task pointer. */
+ gcsTASK_FREE_CONTIGUOUS_MEMORY_PTR task
+ = (gcsTASK_FREE_CONTIGUOUS_MEMORY_PTR) TaskHeader->task;
+
+ /* Free contiguous memory. */
+ gcmkERR_BREAK(gckOS_FreeContiguous(
+ Command->os, task->physical, task->logical, task->bytes
+ ));
+
+ /* Update the reference counter. */
+ TaskHeader->container->referenceCount -= 1;
+
+ /* Update the task pointer. */
+ TaskHeader->task = (gcsTASK_HEADER_PTR) (task + 1);
+ }
+ while (gcvFALSE);
+
+ /* Return status. */
+ return status;
+}
+
+static gceSTATUS
+_TaskUnmapUserMemory(
+ gckVGCOMMAND Command,
+ gcsBLOCK_TASK_ENTRY_PTR TaskHeader
+ )
+{
+ gceSTATUS status;
+ gctPOINTER info;
+
+ do
+ {
+ /* Cast the task pointer. */
+ gcsTASK_UNMAP_USER_MEMORY_PTR task
+ = (gcsTASK_UNMAP_USER_MEMORY_PTR) TaskHeader->task;
+
+ info = gckKERNEL_QueryPointerFromName(
+ Command->kernel->kernel, gcmALL_TO_UINT32(task->info));
+
+ /* Unmap the user memory. */
+ gcmkERR_BREAK(gckOS_UnmapUserMemory(
+ Command->os, gcvCORE_VG, task->memory, task->size, info, task->address
+ ));
+
+ /* Update the reference counter. */
+ TaskHeader->container->referenceCount -= 1;
+
+ /* Update the task pointer. */
+ TaskHeader->task = (gcsTASK_HEADER_PTR) (task + 1);
+ }
+ while (gcvFALSE);
+
+ /* Return status. */
+ return status;
+}
+
+/******************************************************************************\
+************ Hardware Block Interrupt Handlers For Scheduled Events ************
+\******************************************************************************/
+
+static gceSTATUS
+_EventHandler_Block(
+ IN gckVGKERNEL Kernel,
+ IN gcsBLOCK_TASK_ENTRY_PTR TaskHeader,
+ IN gctBOOL ProcessAll
+ )
+{
+ gceSTATUS status = gcvSTATUS_OK, last;
+
+ gcmkHEADER_ARG("Kernel=0x%x TaskHeader=0x%x ProcessAll=0x%x", Kernel, TaskHeader, ProcessAll);
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
+
+ if (TaskHeader->task == gcvNULL)
+ {
+ gcmkFOOTER();
+ return gcvSTATUS_OK;
+ }
+
+ do
+ {
+ gckVGCOMMAND command;
+
+ /* Get the command buffer object. */
+ command = Kernel->command;
+
+ /* Increment the interrupt usage semaphore. */
+ gcmkERR_BREAK(gckOS_IncrementSemaphore(
+ command->os, TaskHeader->interruptSemaphore
+ ));
+
+ /* Acquire the mutex. */
+ gcmkERR_BREAK(gckOS_AcquireMutex(
+ command->os,
+ command->taskMutex,
+ gcvINFINITE
+ ));
+
+ /* Verify inputs. */
+ gcmkASSERT(TaskHeader != gcvNULL);
+ gcmkASSERT(TaskHeader->container != gcvNULL);
+ gcmkASSERT(TaskHeader->task != gcvNULL);
+ gcmkASSERT(TaskHeader->link != gcvNULL);
+
+ /* Process tasks. */
+ do
+ {
+ /* Process the current task. */
+ gcmkERR_BREAK(_taskRoutine[TaskHeader->task->id](
+ command,
+ TaskHeader
+ ));
+
+ /* Is the next task is LINK? */
+ if (TaskHeader->task->id == gcvTASK_LINK)
+ {
+ gcmkERR_BREAK(_taskRoutine[TaskHeader->task->id](
+ command,
+ TaskHeader
+ ));
+
+ /* Done. */
+ break;
+ }
+ }
+ while (ProcessAll);
+
+ /* Release the mutex. */
+ gcmkCHECK_STATUS(gckOS_ReleaseMutex(
+ command->os,
+ command->taskMutex
+ ));
+ }
+ while (gcvFALSE);
+
+ gcmkFOOTER();
+ /* Return status. */
+ return status;
+}
+
+gcmDECLARE_INTERRUPT_HANDLER(COMMAND, 0)
+{
+ gceSTATUS status, last;
+
+ gcmkHEADER_ARG("Kernel=0x%x ", Kernel);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
+
+
+ do
+ {
+ gckVGCOMMAND command;
+ gcsKERNEL_QUEUE_HEADER_PTR mergeQueue;
+ gcsKERNEL_QUEUE_HEADER_PTR queueTail;
+ gcsKERNEL_CMDQUEUE_PTR entry;
+ gctUINT entryCount;
+
+ /* Get the command buffer object. */
+ command = Kernel->command;
+
+ /* Acquire the mutex. */
+ gcmkERR_BREAK(gckOS_AcquireMutex(
+ command->os,
+ command->queueMutex,
+ gcvINFINITE
+ ));
+
+ /* Get the current queue. */
+ queueTail = command->queueTail;
+
+ /* Get the current queue entry. */
+ entry = queueTail->currentEntry;
+
+ /* Get the number of entries in the queue. */
+ entryCount = queueTail->pending;
+
+ /* Process all entries. */
+ while (entryCount > 0)
+ {
+ /* Call post-execution function. */
+ status = entry->handler(Kernel, entry);
+
+ /* Failed? */
+ if (gcmkIS_ERROR(status))
+ {
+ gcmkTRACE_ZONE(
+ gcvLEVEL_ERROR,
+ gcvZONE_COMMAND,
+ "[%s] line %d: post action failed.\n",
+ __FUNCTION__, __LINE__
+ );
+ }
+
+ /* Executed the next buffer? */
+ if (status == gcvSTATUS_EXECUTED)
+ {
+ /* Update the queue. */
+ queueTail->pending = entryCount;
+ queueTail->currentEntry = entry;
+
+ /* Success. */
+ status = gcvSTATUS_OK;
+
+ /* Break out of the loop. */
+ break;
+ }
+
+ /* Advance to the next entry. */
+ entry += 1;
+ entryCount -= 1;
+
+ /* Last entry? */
+ if (entryCount == 0)
+ {
+ /* Reset the queue to idle. */
+ queueTail->pending = 0;
+
+ /* Get a shortcut to the queue to merge with. */
+ mergeQueue = command->mergeQueue;
+
+ /* Merge the queues if necessary. */
+ if (mergeQueue != queueTail)
+ {
+ gcmkASSERT(mergeQueue < queueTail);
+ gcmkASSERT(mergeQueue->next == queueTail);
+
+ mergeQueue->size
+ += gcmSIZEOF(gcsKERNEL_QUEUE_HEADER)
+ + queueTail->size;
+
+ mergeQueue->next = queueTail->next;
+ }
+
+ /* Advance to the next queue. */
+ queueTail = queueTail->next;
+
+ /* Did it wrap around? */
+ if (command->queue == queueTail)
+ {
+ /* Reset merge queue. */
+ command->mergeQueue = queueTail;
+ }
+
+ /* Set new queue. */
+ command->queueTail = queueTail;
+
+ /* Is the next queue scheduled? */
+ if (queueTail->pending > 0)
+ {
+ gcsCMDBUFFER_PTR commandBuffer;
+
+ /* The first entry must be a command buffer. */
+ commandBuffer = queueTail->currentEntry->commandBuffer;
+
+ /* Start the command processor. */
+ status = gckVGHARDWARE_Execute(
+ command->hardware,
+ commandBuffer->address,
+ commandBuffer->dataCount
+ );
+
+ /* Failed? */
+ if (gcmkIS_ERROR(status))
+ {
+ gcmkTRACE_ZONE(
+ gcvLEVEL_ERROR,
+ gcvZONE_COMMAND,
+ "[%s] line %d: failed to start the next queue.\n",
+ __FUNCTION__, __LINE__
+ );
+ }
+ }
+ else
+ {
+ status = gckVGHARDWARE_SetPowerManagementState(
+ Kernel->command->hardware, gcvPOWER_IDLE_BROADCAST
+ );
+ }
+
+ /* Break out of the loop. */
+ break;
+ }
+ }
+
+ /* Release the mutex. */
+ gcmkCHECK_STATUS(gckOS_ReleaseMutex(
+ command->os,
+ command->queueMutex
+ ));
+ }
+ while (gcvFALSE);
+
+
+ gcmkFOOTER();
+ /* Return status. */
+ return status;
+}
+
+/* Define standard block interrupt handlers. */
+gcmDEFINE_INTERRUPT_HANDLER(TESSELLATOR, 0)
+gcmDEFINE_INTERRUPT_HANDLER(VG, 0)
+gcmDEFINE_INTERRUPT_HANDLER(PIXEL, 0)
+gcmDEFINE_INTERRUPT_HANDLER(PIXEL, 1)
+gcmDEFINE_INTERRUPT_HANDLER(PIXEL, 2)
+gcmDEFINE_INTERRUPT_HANDLER(PIXEL, 3)
+gcmDEFINE_INTERRUPT_HANDLER(PIXEL, 4)
+gcmDEFINE_INTERRUPT_HANDLER(PIXEL, 5)
+gcmDEFINE_INTERRUPT_HANDLER(PIXEL, 6)
+gcmDEFINE_INTERRUPT_HANDLER(PIXEL, 7)
+gcmDEFINE_INTERRUPT_HANDLER(PIXEL, 8)
+gcmDEFINE_INTERRUPT_HANDLER(PIXEL, 9)
+
+/* The entries in the array are arranged by event priority. */
+static gcsBLOCK_INTERRUPT_HANDLER _blockHandlers[] =
+{
+ gcmDEFINE_INTERRUPT_HANDLER_ENTRY(TESSELLATOR, 0),
+ gcmDEFINE_INTERRUPT_HANDLER_ENTRY(VG, 0),
+ gcmDEFINE_INTERRUPT_HANDLER_ENTRY(PIXEL, 0),
+ gcmDEFINE_INTERRUPT_HANDLER_ENTRY(PIXEL, 1),
+ gcmDEFINE_INTERRUPT_HANDLER_ENTRY(PIXEL, 2),
+ gcmDEFINE_INTERRUPT_HANDLER_ENTRY(PIXEL, 3),
+ gcmDEFINE_INTERRUPT_HANDLER_ENTRY(PIXEL, 4),
+ gcmDEFINE_INTERRUPT_HANDLER_ENTRY(PIXEL, 5),
+ gcmDEFINE_INTERRUPT_HANDLER_ENTRY(PIXEL, 6),
+ gcmDEFINE_INTERRUPT_HANDLER_ENTRY(PIXEL, 7),
+ gcmDEFINE_INTERRUPT_HANDLER_ENTRY(PIXEL, 8),
+ gcmDEFINE_INTERRUPT_HANDLER_ENTRY(PIXEL, 9),
+ gcmDEFINE_INTERRUPT_HANDLER_ENTRY(COMMAND, 0),
+};
+
+
+/******************************************************************************\
+************************* Static Command Buffer Handlers ***********************
+\******************************************************************************/
+
+static gceSTATUS
+_UpdateStaticCommandBuffer(
+ IN gckVGKERNEL Kernel,
+ IN gcsKERNEL_CMDQUEUE_PTR Entry
+ )
+{
+ gcmkTRACE_ZONE(
+ gcvLEVEL_VERBOSE, gcvZONE_COMMAND,
+ "%s(%d)\n",
+ __FUNCTION__, __LINE__
+ );
+
+ /* Success. */
+ return gcvSTATUS_OK;
+}
+
+static gceSTATUS
+_ExecuteStaticCommandBuffer(
+ IN gckVGKERNEL Kernel,
+ IN gcsKERNEL_CMDQUEUE_PTR Entry
+ )
+{
+ gceSTATUS status;
+
+ do
+ {
+ gcsCMDBUFFER_PTR commandBuffer;
+
+ /* Cast the command buffer header. */
+ commandBuffer = Entry->commandBuffer;
+
+ /* Set to update the command buffer next time. */
+ Entry->handler = _UpdateStaticCommandBuffer;
+
+ gcmkTRACE_ZONE(
+ gcvLEVEL_VERBOSE, gcvZONE_COMMAND,
+ "%s(%d): executing next buffer @ 0x%08X, data count = %d\n",
+ __FUNCTION__, __LINE__,
+ commandBuffer->address,
+ commandBuffer->dataCount
+ );
+
+ /* Start the command processor. */
+ gcmkERR_BREAK(gckVGHARDWARE_Execute(
+ Kernel->hardware,
+ commandBuffer->address,
+ commandBuffer->dataCount
+ ));
+
+ /* Success. */
+ return gcvSTATUS_EXECUTED;
+ }
+ while (gcvFALSE);
+
+ /* Return status. */
+ return status;
+}
+
+static gceSTATUS
+_UpdateLastStaticCommandBuffer(
+ IN gckVGKERNEL Kernel,
+ IN gcsKERNEL_CMDQUEUE_PTR Entry
+ )
+{
+#if gcvDEBUG || gcdFORCE_MESSAGES
+ /* Get the command buffer header. */
+ gcsCMDBUFFER_PTR commandBuffer = Entry->commandBuffer;
+
+ /* Validate the command buffer. */
+ gcmkASSERT(commandBuffer->completion != gcvNULL);
+ gcmkASSERT(commandBuffer->completion != gcvVACANT_BUFFER);
+
+#endif
+
+ gcmkTRACE_ZONE(
+ gcvLEVEL_VERBOSE, gcvZONE_COMMAND,
+ "%s(%d): processing all tasks scheduled for FE.\n",
+ __FUNCTION__, __LINE__
+ );
+
+ /* Perform scheduled tasks. */
+ return _EventHandler_Block(
+ Kernel,
+ &Kernel->command->taskTable[gcvBLOCK_COMMAND],
+ gcvTRUE
+ );
+}
+
+static gceSTATUS
+_ExecuteLastStaticCommandBuffer(
+ IN gckVGKERNEL Kernel,
+ IN gcsKERNEL_CMDQUEUE_PTR Entry
+ )
+{
+ gceSTATUS status;
+
+ do
+ {
+ /* Cast the command buffer header. */
+ gcsCMDBUFFER_PTR commandBuffer = Entry->commandBuffer;
+
+ /* Set to update the command buffer next time. */
+ Entry->handler = _UpdateLastStaticCommandBuffer;
+
+ gcmkTRACE_ZONE(
+ gcvLEVEL_VERBOSE, gcvZONE_COMMAND,
+ "%s(%d): executing next buffer @ 0x%08X, data count = %d\n",
+ __FUNCTION__, __LINE__,
+ commandBuffer->address,
+ commandBuffer->dataCount
+ );
+
+ /* Start the command processor. */
+ gcmkERR_BREAK(gckVGHARDWARE_Execute(
+ Kernel->hardware,
+ commandBuffer->address,
+ commandBuffer->dataCount
+ ));
+
+ /* Success. */
+ return gcvSTATUS_EXECUTED;
+ }
+ while (gcvFALSE);
+
+ /* Return status. */
+ return status;
+}
+
+
+/******************************************************************************\
+************************* Dynamic Command Buffer Handlers **********************
+\******************************************************************************/
+
+static gceSTATUS
+_UpdateDynamicCommandBuffer(
+ IN gckVGKERNEL Kernel,
+ IN gcsKERNEL_CMDQUEUE_PTR Entry
+ )
+{
+ gcmkTRACE_ZONE(
+ gcvLEVEL_VERBOSE, gcvZONE_COMMAND,
+ "%s(%d)\n",
+ __FUNCTION__, __LINE__
+ );
+
+ /* Success. */
+ return gcvSTATUS_OK;
+}
+
+static gceSTATUS
+_ExecuteDynamicCommandBuffer(
+ IN gckVGKERNEL Kernel,
+ IN gcsKERNEL_CMDQUEUE_PTR Entry
+ )
+{
+ gceSTATUS status;
+
+ do
+ {
+ /* Cast the command buffer header. */
+ gcsCMDBUFFER_PTR commandBuffer = Entry->commandBuffer;
+
+ /* Set to update the command buffer next time. */
+ Entry->handler = _UpdateDynamicCommandBuffer;
+
+ gcmkTRACE_ZONE(
+ gcvLEVEL_VERBOSE, gcvZONE_COMMAND,
+ "%s(%d): executing next buffer @ 0x%08X, data count = %d\n",
+ __FUNCTION__, __LINE__,
+ commandBuffer->address,
+ commandBuffer->dataCount
+ );
+
+ /* Start the command processor. */
+ gcmkERR_BREAK(gckVGHARDWARE_Execute(
+ Kernel->hardware,
+ commandBuffer->address,
+ commandBuffer->dataCount
+ ));
+
+ /* Success. */
+ return gcvSTATUS_EXECUTED;
+ }
+ while (gcvFALSE);
+
+ /* Return status. */
+ return status;
+}
+
+static gceSTATUS
+_UpdateLastDynamicCommandBuffer(
+ IN gckVGKERNEL Kernel,
+ IN gcsKERNEL_CMDQUEUE_PTR Entry
+ )
+{
+#if gcvDEBUG || gcdFORCE_MESSAGES
+ /* Get the command buffer header. */
+ gcsCMDBUFFER_PTR commandBuffer = Entry->commandBuffer;
+
+ /* Validate the command buffer. */
+ gcmkASSERT(commandBuffer->completion != gcvNULL);
+ gcmkASSERT(commandBuffer->completion != gcvVACANT_BUFFER);
+
+#endif
+
+ gcmkTRACE_ZONE(
+ gcvLEVEL_VERBOSE, gcvZONE_COMMAND,
+ "%s(%d): processing all tasks scheduled for FE.\n",
+ __FUNCTION__, __LINE__
+ );
+
+ /* Perform scheduled tasks. */
+ return _EventHandler_Block(
+ Kernel,
+ &Kernel->command->taskTable[gcvBLOCK_COMMAND],
+ gcvTRUE
+ );
+}
+
+static gceSTATUS
+_ExecuteLastDynamicCommandBuffer(
+ IN gckVGKERNEL Kernel,
+ IN gcsKERNEL_CMDQUEUE_PTR Entry
+ )
+{
+ gceSTATUS status;
+
+ do
+ {
+ /* Cast the command buffer header. */
+ gcsCMDBUFFER_PTR commandBuffer = Entry->commandBuffer;
+
+ /* Set to update the command buffer next time. */
+ Entry->handler = _UpdateLastDynamicCommandBuffer;
+
+ gcmkTRACE_ZONE(
+ gcvLEVEL_VERBOSE, gcvZONE_COMMAND,
+ "%s(%d): executing next buffer @ 0x%08X, data count = %d\n",
+ __FUNCTION__, __LINE__,
+ commandBuffer->address,
+ commandBuffer->dataCount
+ );
+
+ /* Start the command processor. */
+ gcmkERR_BREAK(gckVGHARDWARE_Execute(
+ Kernel->hardware,
+ commandBuffer->address,
+ commandBuffer->dataCount
+ ));
+
+ /* Success. */
+ return gcvSTATUS_EXECUTED;
+ }
+ while (gcvFALSE);
+
+ /* Return status. */
+ return status;
+}
+
+
+/******************************************************************************\
+********************************* Other Handlers *******************************
+\******************************************************************************/
+
+static gceSTATUS
+_FreeKernelCommandBuffer(
+ IN gckVGKERNEL Kernel,
+ IN gcsKERNEL_CMDQUEUE_PTR Entry
+ )
+{
+ gceSTATUS status;
+
+ /* Free the command buffer. */
+ status = _FreeCommandBuffer(Kernel, Entry->commandBuffer);
+
+ /* Return status. */
+ return status;
+}
+
+
+/******************************************************************************\
+******************************* Queue Management *******************************
+\******************************************************************************/
+
+#if gcvDUMP_COMMAND_BUFFER
+static void
+_DumpCommandQueue(
+ IN gckVGCOMMAND Command,
+ IN gcsKERNEL_QUEUE_HEADER_PTR QueueHeader,
+ IN gctUINT EntryCount
+ )
+{
+ gcsKERNEL_CMDQUEUE_PTR entry;
+ gctUINT queueIndex;
+
+#if defined(gcvCOMMAND_BUFFER_NAME)
+ static gctUINT arrayCount = 0;
+#endif
+
+ /* Is dumpinng enabled? */
+ if (!Commad->enableDumping)
+ {
+ return;
+ }
+
+#if !defined(gcvCOMMAND_BUFFER_NAME)
+ gcmkTRACE_ZONE(
+ gcvLEVEL_INFO, gcvZONE_COMMAND,
+ "COMMAND QUEUE DUMP: %d entries\n", EntryCount
+ );
+#endif
+
+ /* Get the pointer to the first entry. */
+ entry = QueueHeader->currentEntry;
+
+ /* Iterate through the queue. */
+ for (queueIndex = 0; queueIndex < EntryCount; queueIndex += 1)
+ {
+ gcsCMDBUFFER_PTR buffer;
+ gctUINT bufferCount;
+ gctUINT bufferIndex;
+ gctUINT i, count;
+ gctUINT size;
+ gctUINT32_PTR data;
+
+#if gcvDUMP_COMMAND_LINES
+ gctUINT lineNumber;
+#endif
+
+#if !defined(gcvCOMMAND_BUFFER_NAME)
+ gcmkTRACE_ZONE(
+ gcvLEVEL_INFO, gcvZONE_COMMAND,
+ "ENTRY %d\n", queueIndex
+ );
+#endif
+
+ /* Reset the count. */
+ bufferCount = 0;
+
+ /* Set the initial buffer. */
+ buffer = entry->commandBuffer;
+
+ /* Loop through all subbuffers. */
+ while (buffer)
+ {
+ /* Update the count. */
+ bufferCount += 1;
+
+ /* Advance to the next subbuffer. */
+ buffer = buffer->nextSubBuffer;
+ }
+
+#if !defined(gcvCOMMAND_BUFFER_NAME)
+ if (bufferCount > 1)
+ {
+ gcmkTRACE_ZONE(
+ gcvLEVEL_INFO,
+ gcvZONE_COMMAND,
+ " COMMAND BUFFER SET: %d buffers.\n",
+ bufferCount
+ );
+ }
+#endif
+
+ /* Reset the buffer index. */
+ bufferIndex = 0;
+
+ /* Set the initial buffer. */
+ buffer = entry->commandBuffer;
+
+ /* Loop through all subbuffers. */
+ while (buffer)
+ {
+ /* Determine the size of the buffer. */
+ size = buffer->dataCount * Command->info.commandAlignment;
+
+#if !defined(gcvCOMMAND_BUFFER_NAME)
+ /* A single buffer? */
+ if (bufferCount == 1)
+ {
+ gcmkTRACE_ZONE(
+ gcvLEVEL_INFO,
+ gcvZONE_COMMAND,
+ " COMMAND BUFFER: count=%d (0x%X), size=%d bytes @ %08X.\n",
+ buffer->dataCount,
+ buffer->dataCount,
+ size,
+ buffer->address
+ );
+ }
+ else
+ {
+ gcmkTRACE_ZONE(
+ gcvLEVEL_INFO,
+ gcvZONE_COMMAND,
+ " COMMAND BUFFER %d: count=%d (0x%X), size=%d bytes @ %08X\n",
+ bufferIndex,
+ buffer->dataCount,
+ buffer->dataCount,
+ size,
+ buffer->address
+ );
+ }
+#endif
+
+ /* Determine the number of double words to print. */
+ count = size / 4;
+
+ /* Determine the buffer location. */
+ data = (gctUINT32_PTR)
+ (
+ (gctUINT8_PTR) buffer + buffer->bufferOffset
+ );
+
+#if defined(gcvCOMMAND_BUFFER_NAME)
+ gcmkTRACE_ZONE(
+ gcvLEVEL_INFO,
+ gcvZONE_COMMAND,
+ "unsigned int _" gcvCOMMAND_BUFFER_NAME "_%d[] =\n",
+ arrayCount
+ );
+
+ gcmkTRACE_ZONE(
+ gcvLEVEL_INFO,
+ gcvZONE_COMMAND,
+ "{\n"
+ );
+
+ arrayCount += 1;
+#endif
+
+#if gcvDUMP_COMMAND_LINES
+ /* Reset the line number. */
+ lineNumber = 0;
+#endif
+
+#if defined(gcvCOMMAND_BUFFER_NAME)
+ count -= 2;
+#endif
+
+ for (i = 0; i < count; i += 1)
+ {
+ if ((i % 8) == 0)
+ {
+#if defined(gcvCOMMAND_BUFFER_NAME)
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_COMMAND, "\t");
+#else
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_COMMAND, " ");
+#endif
+ }
+
+#if gcvDUMP_COMMAND_LINES
+ if (lineNumber == gcvDUMP_COMMAND_LINES)
+ {
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_COMMAND, " . . . . . . . . .\n");
+ break;
+ }
+#endif
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_COMMAND, "0x%08X", data[i]);
+
+ if (i + 1 == count)
+ {
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_COMMAND, "\n");
+
+#if gcvDUMP_COMMAND_LINES
+ lineNumber += 1;
+#endif
+ }
+ else
+ {
+ if (((i + 1) % 8) == 0)
+ {
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_COMMAND, ",\n");
+
+#if gcvDUMP_COMMAND_LINES
+ lineNumber += 1;
+#endif
+ }
+ else
+ {
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_COMMAND, ", ");
+ }
+ }
+ }
+
+#if defined(gcvCOMMAND_BUFFER_NAME)
+ gcmkTRACE_ZONE(
+ gcvLEVEL_INFO,
+ gcvZONE_COMMAND,
+ "};\n\n"
+ );
+#endif
+
+ /* Advance to the next subbuffer. */
+ buffer = buffer->nextSubBuffer;
+ bufferIndex += 1;
+ }
+
+ /* Advance to the next entry. */
+ entry += 1;
+ }
+}
+#endif
+
+static gceSTATUS
+_LockCurrentQueue(
+ IN gckVGCOMMAND Command,
+ OUT gcsKERNEL_CMDQUEUE_PTR * Entries,
+ OUT gctUINT_PTR EntryCount
+ )
+{
+ gceSTATUS status;
+
+ do
+ {
+ gcsKERNEL_QUEUE_HEADER_PTR queueHead;
+
+ /* Get a shortcut to the head of the queue. */
+ queueHead = Command->queueHead;
+
+ /* Is the head buffer still being worked on? */
+ if (queueHead->pending)
+ {
+ /* Increment overflow count. */
+ Command->queueOverflow += 1;
+
+ /* Wait until the head becomes idle. */
+ gcmkERR_BREAK(_WaitForIdle(Command, queueHead));
+ }
+
+ /* Acquire the mutex. */
+ gcmkERR_BREAK(gckOS_AcquireMutex(
+ Command->os,
+ Command->queueMutex,
+ gcvINFINITE
+ ));
+
+ /* Determine the first queue entry. */
+ queueHead->currentEntry = (gcsKERNEL_CMDQUEUE_PTR)
+ (
+ (gctUINT8_PTR) queueHead + gcmSIZEOF(gcsKERNEL_QUEUE_HEADER)
+ );
+
+ /* Set the pointer to the first entry. */
+ * Entries = queueHead->currentEntry;
+
+ /* Determine the number of available entries. */
+ * EntryCount = queueHead->size / gcmSIZEOF(gcsKERNEL_CMDQUEUE);
+
+ /* Success. */
+ return gcvSTATUS_OK;
+ }
+ while (gcvFALSE);
+
+ /* Return status. */
+ return status;
+}
+
+static gceSTATUS
+_UnlockCurrentQueue(
+ IN gckVGCOMMAND Command,
+ IN gctUINT EntryCount
+ )
+{
+ gceSTATUS status;
+
+ do
+ {
+#if !gcdENABLE_INFINITE_SPEED_HW
+ gcsKERNEL_QUEUE_HEADER_PTR queueTail;
+ gcsKERNEL_QUEUE_HEADER_PTR queueHead;
+ gcsKERNEL_QUEUE_HEADER_PTR queueNext;
+ gctUINT queueSize;
+ gctUINT newSize;
+ gctUINT unusedSize;
+
+ /* Get shortcut to the head and to the tail of the queue. */
+ queueTail = Command->queueTail;
+ queueHead = Command->queueHead;
+
+ /* Dump the command buffer. */
+#if gcvDUMP_COMMAND_BUFFER
+ _DumpCommandQueue(Command, queueHead, EntryCount);
+#endif
+
+ /* Get a shortcut to the current queue size. */
+ queueSize = queueHead->size;
+
+ /* Determine the new queue size. */
+ newSize = EntryCount * gcmSIZEOF(gcsKERNEL_CMDQUEUE);
+ gcmkASSERT(newSize <= queueSize);
+
+ /* Determine the size of the unused area. */
+ unusedSize = queueSize - newSize;
+
+ /* Is the unused area big enough to become a buffer? */
+ if (unusedSize >= gcvMINUMUM_BUFFER)
+ {
+ gcsKERNEL_QUEUE_HEADER_PTR nextHead;
+
+ /* Place the new header. */
+ nextHead = (gcsKERNEL_QUEUE_HEADER_PTR)
+ (
+ (gctUINT8_PTR) queueHead
+ + gcmSIZEOF(gcsKERNEL_QUEUE_HEADER)
+ + newSize
+ );
+
+ /* Initialize the buffer. */
+ nextHead->size = unusedSize - gcmSIZEOF(gcsKERNEL_QUEUE_HEADER);
+ nextHead->pending = 0;
+
+ /* Link the buffer in. */
+ nextHead->next = queueHead->next;
+ queueHead->next = nextHead;
+ queueNext = nextHead;
+
+ /* Update the size of the current buffer. */
+ queueHead->size = newSize;
+ }
+
+ /* Not big enough. */
+ else
+ {
+ /* Determine the next queue. */
+ queueNext = queueHead->next;
+ }
+
+ /* Mark the buffer as busy. */
+ queueHead->pending = EntryCount;
+
+ /* Advance to the next buffer. */
+ Command->queueHead = queueNext;
+
+ /* Start the command processor if the queue was empty. */
+ if (queueTail == queueHead)
+ {
+ gcsCMDBUFFER_PTR commandBuffer;
+
+ /* The first entry must be a command buffer. */
+ commandBuffer = queueTail->currentEntry->commandBuffer;
+
+ /* Start the command processor. */
+ gcmkERR_BREAK(gckVGHARDWARE_Execute(
+ Command->hardware,
+ commandBuffer->address,
+ commandBuffer->dataCount
+ ));
+ }
+
+ /* The queue was not empty. */
+ else
+ {
+ /* Advance the merge buffer if needed. */
+ if (queueHead == Command->mergeQueue)
+ {
+ Command->mergeQueue = queueNext;
+ }
+ }
+#endif
+
+ /* Release the mutex. */
+ gcmkERR_BREAK(gckOS_ReleaseMutex(
+ Command->os,
+ Command->queueMutex
+ ));
+
+ /* Success. */
+ return gcvSTATUS_OK;
+ }
+ while (gcvFALSE);
+
+ /* Return status. */
+ return status;
+}
+
+
+
+/******************************************************************************\
+****************************** gckVGCOMMAND API Code *****************************
+\******************************************************************************/
+gceSTATUS
+gckVGCOMMAND_Construct(
+ IN gckVGKERNEL Kernel,
+ IN gctUINT TaskGranularity,
+ IN gctUINT QueueSize,
+ OUT gckVGCOMMAND * Command
+ )
+{
+ gceSTATUS status, last;
+ gckVGCOMMAND command = gcvNULL;
+ gcsKERNEL_QUEUE_HEADER_PTR queue;
+ gctUINT i, j;
+
+ gcmkHEADER_ARG("Kernel=0x%x TaskGranularity=0x%x QueueSize=0x%x Command=0x%x",
+ Kernel, TaskGranularity, QueueSize, Command);
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
+ gcmkVERIFY_ARGUMENT(QueueSize >= gcvMINUMUM_BUFFER);
+ gcmkVERIFY_ARGUMENT(Command != gcvNULL);
+
+ do
+ {
+ /***********************************************************************
+ ** Generic object initialization.
+ */
+
+ /* Allocate the gckVGCOMMAND structure. */
+ gcmkERR_BREAK(gckOS_Allocate(
+ Kernel->os,
+ gcmSIZEOF(struct _gckVGCOMMAND),
+ (gctPOINTER *) &command
+ ));
+
+ /* Initialize the object. */
+ command->object.type = gcvOBJ_COMMAND;
+
+ /* Set the object pointers. */
+ command->kernel = Kernel;
+ command->os = Kernel->os;
+ command->hardware = Kernel->hardware;
+
+ /* Reset pointers. */
+ command->queue = gcvNULL;
+ command->queueMutex = gcvNULL;
+ command->taskMutex = gcvNULL;
+ command->commitMutex = gcvNULL;
+
+ command->powerStallBuffer = gcvNULL;
+ command->powerStallSignal = gcvNULL;
+ command->powerSemaphore = gcvNULL;
+
+ /* Reset context states. */
+ command->contextCounter = 0;
+ command->currentContext = 0;
+
+ /* Enable command buffer dumping. */
+ command->enableDumping = gcvTRUE;
+
+ /* Set features. */
+ command->fe20 = Kernel->hardware->fe20;
+ command->vg20 = Kernel->hardware->vg20;
+ command->vg21 = Kernel->hardware->vg21;
+
+ /* Reset task table .*/
+ gcmkVERIFY_OK(gckOS_ZeroMemory(
+ command->taskTable, gcmSIZEOF(command->taskTable)
+ ));
+
+ /* Query command buffer attributes. */
+ gcmkERR_BREAK(gckVGCOMMAND_InitializeInfo(command));
+
+ /* Create the control mutexes. */
+ gcmkERR_BREAK(gckOS_CreateMutex(Kernel->os, &command->queueMutex));
+ gcmkERR_BREAK(gckOS_CreateMutex(Kernel->os, &command->taskMutex));
+ gcmkERR_BREAK(gckOS_CreateMutex(Kernel->os, &command->commitMutex));
+
+ /* Create the power management semaphore. */
+ gcmkERR_BREAK(gckOS_CreateSemaphore(Kernel->os,
+ &command->powerSemaphore));
+
+ gcmkERR_BREAK(gckOS_CreateSignal(Kernel->os,
+ gcvFALSE, &command->powerStallSignal));
+
+ /***********************************************************************
+ ** Command queue initialization.
+ */
+
+ /* Allocate the command queue. */
+ gcmkERR_BREAK(gckOS_Allocate(
+ Kernel->os,
+ QueueSize,
+ (gctPOINTER *) &command->queue
+ ));
+
+ /* Initialize the command queue. */
+ queue = command->queue;
+
+ queue->size = QueueSize - gcmSIZEOF(gcsKERNEL_QUEUE_HEADER);
+ queue->pending = 0;
+ queue->next = queue;
+
+ command->queueHead =
+ command->queueTail =
+ command->mergeQueue = command->queue;
+
+ command->queueOverflow = 0;
+
+
+ /***********************************************************************
+ ** Enable TS overflow interrupt.
+ */
+
+ command->info.tsOverflowInt = 0;
+ gcmkERR_BREAK(gckVGINTERRUPT_Enable(
+ Kernel->interrupt,
+ &command->info.tsOverflowInt,
+ _EventHandler_TSOverflow
+ ));
+
+ /* Mask out the interrupt. */
+ /* Kernel->hardware->eventMask &= ~(1 << command->info.tsOverflowInt); */
+
+
+ /***********************************************************************
+ ** Enable Bus Error interrupt.
+ */
+
+ /* Hardwired to bit 31. */
+ command->busErrorInt = 31;
+
+ /* Enable the interrupt. */
+ gcmkERR_BREAK(gckVGINTERRUPT_Enable(
+ Kernel->interrupt,
+ &command->busErrorInt,
+ _EventHandler_BusError
+ ));
+
+
+ command->powerStallInt = 30;
+ /* Enable the interrupt. */
+ gcmkERR_BREAK(gckVGINTERRUPT_Enable(
+ Kernel->interrupt,
+ &command->powerStallInt,
+ _EventHandler_PowerStall
+ ));
+
+ /***********************************************************************
+ ** Task management initialization.
+ */
+
+ command->taskStorage = gcvNULL;
+ command->taskStorageGranularity = TaskGranularity;
+ command->taskStorageUsable = TaskGranularity - gcmSIZEOF(gcsTASK_STORAGE);
+
+ command->taskFreeHead = gcvNULL;
+ command->taskFreeTail = gcvNULL;
+
+ /* Enable block handlers. */
+ for (i = 0; i < gcmCOUNTOF(_blockHandlers); i += 1)
+ {
+ /* Get the target hardware block. */
+ gceBLOCK block = _blockHandlers[i].block;
+
+ /* Get the interrupt array entry. */
+ gcsBLOCK_TASK_ENTRY_PTR entry = &command->taskTable[block];
+
+ /* Determine the interrupt value index. */
+ gctUINT index = entry->interruptCount;
+
+ /* Create the block semaphore. */
+ if (entry->interruptSemaphore == gcvNULL)
+ {
+ gcmkERR_BREAK(gckOS_CreateSemaphoreVG(
+ command->os, &entry->interruptSemaphore
+ ));
+ }
+
+ /* Enable auto-detection. */
+ entry->interruptArray[index] = -1;
+
+ /* Enable interrupt for the block. */
+ gcmkERR_BREAK(gckVGINTERRUPT_Enable(
+ Kernel->interrupt,
+ &entry->interruptArray[index],
+ _blockHandlers[i].handler
+ ));
+
+ /* Update the number of registered interrupts. */
+ entry->interruptCount += 1;
+
+ /* Inrement the semaphore to allow the usage of the registered
+ interrupt. */
+ gcmkERR_BREAK(gckOS_IncrementSemaphore(
+ command->os, entry->interruptSemaphore
+ ));
+
+ }
+
+ /* Error? */
+ if (gcmkIS_ERROR(status))
+ {
+ break;
+ }
+
+ /* Get the FE interrupt. */
+ command->info.feBufferInt
+ = command->taskTable[gcvBLOCK_COMMAND].interruptArray[0];
+
+ /* Return gckVGCOMMAND object pointer. */
+ *Command = command;
+
+ gcmkFOOTER_ARG("*Command=0x%x",*Command);
+ /* Success. */
+ return gcvSTATUS_OK;
+ }
+ while (gcvFALSE);
+
+ /* Roll back. */
+ if (command != gcvNULL)
+ {
+ /* Disable block handlers. */
+ for (i = 0; i < gcvBLOCK_COUNT; i += 1)
+ {
+ /* Get the task table entry. */
+ gcsBLOCK_TASK_ENTRY_PTR entry = &command->taskTable[i];
+
+ /* Destroy the semaphore. */
+ if (entry->interruptSemaphore != gcvNULL)
+ {
+ gcmkCHECK_STATUS(gckOS_DestroySemaphore(
+ command->os, entry->interruptSemaphore
+ ));
+ }
+
+ /* Disable all enabled interrupts. */
+ for (j = 0; j < entry->interruptCount; j += 1)
+ {
+ /* Must be a valid value. */
+ gcmkASSERT(entry->interruptArray[j] >= 0);
+ gcmkASSERT(entry->interruptArray[j] <= 31);
+
+ /* Disable the interrupt. */
+ gcmkCHECK_STATUS(gckVGINTERRUPT_Disable(
+ Kernel->interrupt,
+ entry->interruptArray[j]
+ ));
+ }
+ }
+
+ /* Disable the bus error interrupt. */
+ gcmkCHECK_STATUS(gckVGINTERRUPT_Disable(
+ Kernel->interrupt,
+ command->busErrorInt
+ ));
+
+ /* Disable TS overflow interrupt. */
+ if (command->info.tsOverflowInt != -1)
+ {
+ gcmkCHECK_STATUS(gckVGINTERRUPT_Disable(
+ Kernel->interrupt,
+ command->info.tsOverflowInt
+ ));
+ }
+
+ /* Delete the commit mutex. */
+ if (command->commitMutex != gcvNULL)
+ {
+ gcmkCHECK_STATUS(gckOS_DeleteMutex(
+ Kernel->os, command->commitMutex
+ ));
+ }
+
+ /* Delete the command queue mutex. */
+ if (command->taskMutex != gcvNULL)
+ {
+ gcmkCHECK_STATUS(gckOS_DeleteMutex(
+ Kernel->os, command->taskMutex
+ ));
+ }
+
+ /* Delete the command queue mutex. */
+ if (command->queueMutex != gcvNULL)
+ {
+ gcmkCHECK_STATUS(gckOS_DeleteMutex(
+ Kernel->os, command->queueMutex
+ ));
+ }
+
+ /* Delete the command queue. */
+ if (command->queue != gcvNULL)
+ {
+ gcmkCHECK_STATUS(gckOS_Free(
+ Kernel->os, command->queue
+ ));
+ }
+
+ if (command->powerSemaphore != gcvNULL)
+ {
+ gcmkVERIFY_OK(gckOS_DestroySemaphore(
+ Kernel->os, command->powerSemaphore));
+ }
+
+ if (command->powerStallSignal != gcvNULL)
+ {
+ /* Create the power management semaphore. */
+ gcmkVERIFY_OK(gckOS_DestroySignal(
+ Kernel->os,
+ command->powerStallSignal));
+ }
+
+ /* Free the gckVGCOMMAND structure. */
+ gcmkCHECK_STATUS(gckOS_Free(
+ Kernel->os, command
+ ));
+ }
+
+ gcmkFOOTER();
+ /* Return the error. */
+ return status;
+}
+
+gceSTATUS
+gckVGCOMMAND_Destroy(
+ OUT gckVGCOMMAND Command
+ )
+{
+ gceSTATUS status = gcvSTATUS_OK;
+
+ gcmkHEADER_ARG("Command=0x%x", Command);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Command, gcvOBJ_COMMAND);
+
+ do
+ {
+ gctUINT i;
+ gcsTASK_STORAGE_PTR nextStorage;
+
+ if (Command->queueHead != gcvNULL)
+ {
+ /* Wait until the head becomes idle. */
+ gcmkERR_BREAK(_WaitForIdle(Command, Command->queueHead));
+ }
+
+ /* Disable block handlers. */
+ for (i = 0; i < gcvBLOCK_COUNT; i += 1)
+ {
+ /* Get the interrupt array entry. */
+ gcsBLOCK_TASK_ENTRY_PTR entry = &Command->taskTable[i];
+
+ /* Determine the index of the last interrupt in the array. */
+ gctINT index = entry->interruptCount - 1;
+
+ /* Destroy the semaphore. */
+ if (entry->interruptSemaphore != gcvNULL)
+ {
+ gcmkERR_BREAK(gckOS_DestroySemaphore(
+ Command->os, entry->interruptSemaphore
+ ));
+ }
+
+ /* Disable all enabled interrupts. */
+ while (index >= 0)
+ {
+ /* Must be a valid value. */
+ gcmkASSERT(entry->interruptArray[index] >= 0);
+ gcmkASSERT(entry->interruptArray[index] <= 31);
+
+ /* Disable the interrupt. */
+ gcmkERR_BREAK(gckVGINTERRUPT_Disable(
+ Command->kernel->interrupt,
+ entry->interruptArray[index]
+ ));
+
+ /* Update to the next interrupt. */
+ index -= 1;
+ entry->interruptCount -= 1;
+ }
+
+ /* Error? */
+ if (gcmkIS_ERROR(status))
+ {
+ break;
+ }
+ }
+
+ /* Error? */
+ if (gcmkIS_ERROR(status))
+ {
+ break;
+ }
+
+ /* Disable the bus error interrupt. */
+ gcmkERR_BREAK(gckVGINTERRUPT_Disable(
+ Command->kernel->interrupt,
+ Command->busErrorInt
+ ));
+
+ /* Disable TS overflow interrupt. */
+ if (Command->info.tsOverflowInt != -1)
+ {
+ gcmkERR_BREAK(gckVGINTERRUPT_Disable(
+ Command->kernel->interrupt,
+ Command->info.tsOverflowInt
+ ));
+
+ Command->info.tsOverflowInt = -1;
+ }
+
+ /* Delete the commit mutex. */
+ if (Command->commitMutex != gcvNULL)
+ {
+ gcmkERR_BREAK(gckOS_DeleteMutex(
+ Command->os, Command->commitMutex
+ ));
+
+ Command->commitMutex = gcvNULL;
+ }
+
+ /* Delete the command queue mutex. */
+ if (Command->taskMutex != gcvNULL)
+ {
+ gcmkERR_BREAK(gckOS_DeleteMutex(
+ Command->os, Command->taskMutex
+ ));
+
+ Command->taskMutex = gcvNULL;
+ }
+
+ /* Delete the command queue mutex. */
+ if (Command->queueMutex != gcvNULL)
+ {
+ gcmkERR_BREAK(gckOS_DeleteMutex(
+ Command->os, Command->queueMutex
+ ));
+
+ Command->queueMutex = gcvNULL;
+ }
+
+ if (Command->powerSemaphore != gcvNULL)
+ {
+ /* Destroy the power management semaphore. */
+ gcmkERR_BREAK(gckOS_DestroySemaphore(
+ Command->os, Command->powerSemaphore));
+ }
+
+ if (Command->powerStallSignal != gcvNULL)
+ {
+ /* Create the power management semaphore. */
+ gcmkERR_BREAK(gckOS_DestroySignal(
+ Command->os,
+ Command->powerStallSignal));
+ }
+
+ if (Command->queue != gcvNULL)
+ {
+ /* Delete the command queue. */
+ gcmkERR_BREAK(gckOS_Free(
+ Command->os, Command->queue
+ ));
+ }
+
+ /* Destroy all allocated buffers. */
+ while (Command->taskStorage)
+ {
+ /* Copy the buffer pointer. */
+ nextStorage = Command->taskStorage->next;
+
+ /* Free the current container. */
+ gcmkERR_BREAK(gckOS_Free(
+ Command->os, Command->taskStorage
+ ));
+
+ /* Advance to the next one. */
+ Command->taskStorage = nextStorage;
+ }
+
+ /* Error? */
+ if (gcmkIS_ERROR(status))
+ {
+ break;
+ }
+
+ /* Mark the object as unknown. */
+ Command->object.type = gcvOBJ_UNKNOWN;
+
+ /* Free the gckVGCOMMAND structure. */
+ gcmkERR_BREAK(gckOS_Free(Command->os, Command));
+
+ gcmkFOOTER_NO();
+ /* Success. */
+ return gcvSTATUS_OK;
+ }
+ while (gcvFALSE);
+
+ /* Restore the object type if failed. */
+ Command->object.type = gcvOBJ_COMMAND;
+
+ gcmkFOOTER();
+ /* Return the error. */
+ return status;
+}
+
+gceSTATUS
+gckVGCOMMAND_QueryCommandBuffer(
+ IN gckVGCOMMAND Command,
+ OUT gcsCOMMAND_BUFFER_INFO_PTR Information
+ )
+{
+ gcmkHEADER_ARG("Command=0x%x Information=0x%x", Command, Information);
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Command, gcvOBJ_COMMAND);
+ gcmkVERIFY_ARGUMENT(Information != gcvNULL);
+
+ /* Copy the information. */
+ gcmkVERIFY_OK(gckOS_MemCopy(
+ Information, &Command->info, sizeof(gcsCOMMAND_BUFFER_INFO)
+ ));
+
+ gcmkFOOTER_NO();
+ /* Success. */
+ return gcvSTATUS_OK;
+}
+
+gceSTATUS
+gckVGCOMMAND_Allocate(
+ IN gckVGCOMMAND Command,
+ IN gctSIZE_T Size,
+ OUT gcsCMDBUFFER_PTR * CommandBuffer,
+ OUT gctPOINTER * Data
+ )
+{
+ gceSTATUS status;
+
+ gcmkHEADER_ARG("Command=0x%x Size=0x%x CommandBuffer=0x%x Data=0x%x",
+ Command, Size, CommandBuffer, Data);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Command, gcvOBJ_COMMAND);
+ gcmkVERIFY_ARGUMENT(Data != gcvNULL);
+
+ do
+ {
+ /* Allocate the buffer. */
+ gcmkERR_BREAK(_AllocateCommandBuffer(Command, Size, CommandBuffer));
+
+ /* Determine the data pointer. */
+ * Data = (gctUINT8_PTR) (*CommandBuffer) + (* CommandBuffer)->bufferOffset;
+ }
+ while (gcvFALSE);
+
+ gcmkFOOTER();
+ /* Return status. */
+ return status;
+}
+
+gceSTATUS
+gckVGCOMMAND_Free(
+ IN gckVGCOMMAND Command,
+ IN gcsCMDBUFFER_PTR CommandBuffer
+ )
+{
+ gceSTATUS status;
+
+ gcmkHEADER_ARG("Command=0x%x CommandBuffer=0x%x",
+ Command, CommandBuffer);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Command, gcvOBJ_COMMAND);
+ gcmkVERIFY_ARGUMENT(CommandBuffer != gcvNULL);
+
+ /* Free command buffer. */
+ status = _FreeCommandBuffer(Command->kernel, CommandBuffer);
+
+ gcmkFOOTER();
+ /* Return status. */
+ return status;
+}
+
+gceSTATUS
+gckVGCOMMAND_Execute(
+ IN gckVGCOMMAND Command,
+ IN gcsCMDBUFFER_PTR CommandBuffer
+ )
+{
+ gceSTATUS status;
+
+ gcmkHEADER_ARG("Command=0x%x CommandBuffer=0x%x",
+ Command, CommandBuffer);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Command, gcvOBJ_COMMAND);
+ gcmkVERIFY_ARGUMENT(CommandBuffer != gcvNULL);
+
+ do
+ {
+ gctUINT queueLength;
+ gcsKERNEL_CMDQUEUE_PTR kernelEntry;
+
+ /* Lock the current queue. */
+ gcmkERR_BREAK(_LockCurrentQueue(
+ Command, &kernelEntry, &queueLength
+ ));
+
+ /* Set the buffer. */
+ kernelEntry->commandBuffer = CommandBuffer;
+ kernelEntry->handler = _FreeKernelCommandBuffer;
+
+ /* Lock the current queue. */
+ gcmkERR_BREAK(_UnlockCurrentQueue(
+ Command, 1
+ ));
+ }
+ while (gcvFALSE);
+
+ gcmkFOOTER();
+ /* Return status. */
+ return status;
+}
+
+gceSTATUS
+gckVGCOMMAND_Commit(
+ IN gckVGCOMMAND Command,
+ IN gcsVGCONTEXT_PTR Context,
+ IN gcsVGCMDQUEUE_PTR Queue,
+ IN gctUINT EntryCount,
+ IN gcsTASK_MASTER_TABLE_PTR TaskTable
+ )
+{
+ /*
+ The first buffer is executed through a direct gckVGHARDWARE_Execute call,
+ therefore only an update is needed after the execution is over. All
+ consequent buffers need to be executed upon the first update call from
+ the FE interrupt handler.
+ */
+ static gcsQUEUE_UPDATE_CONTROL _dynamicBuffer[] =
+ {
+ {
+ _UpdateDynamicCommandBuffer,
+ _UpdateDynamicCommandBuffer,
+ _UpdateLastDynamicCommandBuffer,
+ _UpdateLastDynamicCommandBuffer
+ },
+ {
+ _ExecuteDynamicCommandBuffer,
+ _UpdateDynamicCommandBuffer,
+ _ExecuteLastDynamicCommandBuffer,
+ _UpdateLastDynamicCommandBuffer
+ }
+ };
+
+ static gcsQUEUE_UPDATE_CONTROL _staticBuffer[] =
+ {
+ {
+ _UpdateStaticCommandBuffer,
+ _UpdateStaticCommandBuffer,
+ _UpdateLastStaticCommandBuffer,
+ _UpdateLastStaticCommandBuffer
+ },
+ {
+ _ExecuteStaticCommandBuffer,
+ _UpdateStaticCommandBuffer,
+ _ExecuteLastStaticCommandBuffer,
+ _UpdateLastStaticCommandBuffer
+ }
+ };
+
+ gceSTATUS status, last;
+ struct _gcsTASK_MASTER_TABLE _TaskTable;
+#ifdef __QNXNTO__
+ gcsVGCONTEXT_PTR userContext = gcvNULL;
+ gctBOOL userContextMapped = gcvFALSE;
+ gcsTASK_MASTER_TABLE_PTR userTaskTable = gcvNULL;
+ gctBOOL userTaskTableMapped = gcvFALSE;
+ gctPOINTER pointer = gcvNULL;
+#endif
+ struct _gcsVGCONTEXT _Context;
+ gctBOOL needCopy = gcvFALSE;
+
+ gcmkHEADER_ARG("Command=0x%x Context=0x%x Queue=0x%x EntryCount=0x%x TaskTable=0x%x",
+ Command, Context, Queue, EntryCount, TaskTable);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Command, gcvOBJ_COMMAND);
+ gcmkVERIFY_ARGUMENT(Context != gcvNULL);
+ gcmkVERIFY_ARGUMENT(Queue != gcvNULL);
+ gcmkVERIFY_ARGUMENT(EntryCount > 1);
+
+ do
+ {
+ gctBOOL haveFETasks;
+ gctUINT queueSize = 0;
+ gcsVGCMDQUEUE_PTR mappedQueue=gcvNULL;
+ gcsVGCMDQUEUE_PTR userEntry=gcvNULL;
+ gcsKERNEL_CMDQUEUE_PTR kernelEntry;
+ gcsQUEUE_UPDATE_CONTROL_PTR queueControl;
+ gctUINT currentLength;
+ gctUINT queueLength;
+ gctUINT entriesQueued;
+ gctUINT8_PTR previousEnd;
+ gctBOOL previousDynamic;
+ gctBOOL previousExecuted;
+ gctUINT controlIndex;
+ gctINT pid;
+#ifdef __QNXNTO__
+ /* Map the context into the kernel space. */
+ userContext = Context;
+
+ gcmkERR_BREAK(gckOS_MapUserPointer(
+ Command->os,
+ userContext,
+ gcmSIZEOF(*userContext),
+ &pointer));
+
+ Context = pointer;
+
+ userContextMapped = gcvTRUE;
+
+ /* Map the taskTable into the kernel space. */
+ userTaskTable = TaskTable;
+
+ gcmkERR_BREAK(gckOS_MapUserPointer(
+ Command->os,
+ userTaskTable,
+ gcmSIZEOF(*userTaskTable),
+ &pointer));
+
+ TaskTable = pointer;
+
+ userTaskTableMapped = gcvTRUE;
+
+ /* Update the signal info. */
+ TaskTable->coid = Context->coid;
+ TaskTable->rcvid = Context->rcvid;
+#endif
+
+ gcmkERR_BREAK(gckOS_GetProcessID((gctUINT32_PTR)&pid));
+ gcmkERR_BREAK(gckOS_QueryNeedCopy(Command->os, pid, &needCopy));
+ if(needCopy)
+ {
+ gcmkERR_BREAK(gckOS_CopyFromUserData(
+ Command->os,
+ &_TaskTable,
+ TaskTable,
+ gcmSIZEOF(struct _gcsTASK_MASTER_TABLE)
+ ));
+ TaskTable = &_TaskTable;
+ /* Determine whether there are FE tasks to be performed. */
+ gcmkERR_BREAK(gckOS_CopyFromUserData(
+ Command->os,
+ &_Context,
+ Context,
+ gcmSIZEOF(struct _gcsVGCONTEXT)
+ ));
+ Context = &_Context;
+ }
+
+ gcmkERR_BREAK(gckVGHARDWARE_SetPowerManagementState(
+ Command->hardware, gcvPOWER_ON_AUTO
+ ));
+
+ /* Acquire the power semaphore. */
+ gcmkERR_BREAK(gckOS_AcquireSemaphore(
+ Command->os, Command->powerSemaphore
+ ));
+
+ /* Acquire the mutex. */
+ status = gckOS_AcquireMutex(
+ Command->os,
+ Command->commitMutex,
+ gcvINFINITE
+ );
+
+ if (gcmIS_ERROR(status))
+ {
+ gcmkVERIFY_OK(gckOS_ReleaseSemaphore(
+ Command->os, Command->powerSemaphore));
+ break;
+ }
+
+ do
+ {
+ gcmkERR_BREAK(_FlushMMU(Command));
+
+ /* Assign a context ID if not yet assigned. */
+ if (Context->id == 0)
+ {
+ /* Assign the next context number. */
+ Context->id = ++ Command->contextCounter;
+ /* See if we overflowed. */
+ if (Command->contextCounter == 0)
+ {
+ /* We actually did overflow, wow... */
+ status = gcvSTATUS_OUT_OF_RESOURCES;
+ break;
+ }
+ }
+
+ /* The first entry in the queue is always the context buffer.
+ Verify whether the user context is the same as the current
+ context and if that's the case, skip the first entry. */
+ if (Context->id == Command->currentContext)
+ {
+ /* Same context as before, skip the first entry. */
+ EntryCount -= 1;
+ Queue += 1;
+
+ /* Set the signal to avoid user waiting. */
+#ifdef __QNXNTO__
+ gcmkERR_BREAK(gckOS_UserSignal(
+ Command->os,
+ Context->userSignal,
+ Context->rcvid,
+ Context->coid
+ ));
+#else
+ gcmkERR_BREAK(gckOS_UserSignal(
+ Command->os, Context->signal, Context->process
+ ));
+#endif
+ }
+ else
+ {
+ /* Different user context - keep the first entry.
+ Set the user context as the current one. */
+ Command->currentContext = Context->id;
+ }
+
+ /* Reset pointers. */
+ queueControl = gcvNULL;
+ previousEnd = gcvNULL;
+
+ haveFETasks = (TaskTable->table[gcvBLOCK_COMMAND].head != gcvNULL);
+
+ /* Determine the size of the queue. */
+ queueSize = EntryCount * gcmSIZEOF(gcsVGCMDQUEUE);
+ if(needCopy)
+ {
+ gctPOINTER pointer = gcvNULL;
+ gcmkERR_BREAK(gckOS_Allocate(
+ Command->os,
+ queueSize,
+ &pointer
+ ));
+ userEntry = pointer;
+ mappedQueue = pointer;
+ gcmkERR_BREAK(gckOS_CopyFromUserData(
+ Command->os,
+ userEntry,
+ Queue,
+ queueSize
+ ));
+ }
+ else
+ {
+ /* Map the command queue into the kernel space. */
+ gcmkERR_BREAK(gckOS_MapUserPointer(
+ Command->os,
+ Queue,
+ queueSize,
+ (gctPOINTER *) &mappedQueue
+ ));
+ userEntry = mappedQueue;
+ }
+ /* Set the first entry. */
+
+ /* Process the command queue. */
+ while (EntryCount)
+ {
+ /* Lock the current queue. */
+ gcmkERR_BREAK(_LockCurrentQueue(
+ Command, &kernelEntry, &queueLength
+ ));
+
+ /* Determine the number of entries to process. */
+ currentLength = (queueLength < EntryCount)
+ ? queueLength
+ : EntryCount;
+
+ /* Update the number of the entries left to process. */
+ EntryCount -= currentLength;
+
+ /* Reset previous flags. */
+ previousDynamic = gcvFALSE;
+ previousExecuted = gcvFALSE;
+
+ /* Set the initial control index. */
+ controlIndex = 0;
+
+ /* Process entries. */
+ for (entriesQueued = 0; entriesQueued < currentLength; entriesQueued += 1)
+ {
+ /* Get the kernel pointer to the command buffer header. */
+ gcsCMDBUFFER_PTR commandBuffer = gcvNULL;
+ gcmkERR_BREAK(_ConvertUserCommandBufferPointer(
+ Command,
+ userEntry->commandBuffer,
+ &commandBuffer
+ ));
+
+ /* Is it a dynamic command buffer? */
+ if (userEntry->dynamic)
+ {
+ /* Select dynamic buffer control functions. */
+ queueControl = &_dynamicBuffer[controlIndex];
+ }
+
+ /* No, a static command buffer. */
+ else
+ {
+ /* Select static buffer control functions. */
+ queueControl = &_staticBuffer[controlIndex];
+ }
+
+ /* Set the command buffer pointer to the entry. */
+ kernelEntry->commandBuffer = commandBuffer;
+
+ /* If the previous entry was a dynamic command buffer,
+ link it to the current. */
+ if (previousDynamic)
+ {
+ gcmkERR_BREAK(gckVGCOMMAND_FetchCommand(
+ Command,
+ previousEnd,
+ commandBuffer->address,
+ commandBuffer->dataCount,
+ gcvNULL
+ ));
+
+ /* The buffer will be auto-executed, only need to
+ update it after it has been executed. */
+ kernelEntry->handler = queueControl->update;
+
+ /* The buffer is only being updated. */
+ previousExecuted = gcvFALSE;
+ }
+ else
+ {
+ /* Set the buffer up for execution. */
+ kernelEntry->handler = queueControl->execute;
+
+ /* The buffer is being updated. */
+ previousExecuted = gcvTRUE;
+ }
+
+ /* The current buffer's END command becomes the last END. */
+ previousEnd
+ = ((gctUINT8_PTR) commandBuffer)
+ + commandBuffer->bufferOffset
+ + commandBuffer->dataCount * Command->info.commandAlignment
+ - Command->info.staticTailSize;
+
+ /* Update the last entry info. */
+ previousDynamic = userEntry->dynamic;
+
+ /* Advance entries. */
+ userEntry ++;
+ kernelEntry ++;
+
+ /* Update the control index. */
+ controlIndex = 1;
+ }
+
+ /* If the previous entry was a dynamic command buffer,
+ terminate it with an END. */
+ if (previousDynamic)
+ {
+ gcmkERR_BREAK(gckVGCOMMAND_EndCommand(
+ Command,
+ previousEnd,
+ Command->info.feBufferInt,
+ gcvNULL
+ ));
+ }
+
+ /* Last buffer? */
+ if (EntryCount == 0)
+ {
+ /* Modify the last command buffer's routines to handle
+ tasks if any.*/
+ if (haveFETasks)
+ {
+ if (previousExecuted)
+ {
+ kernelEntry[-1].handler = queueControl->lastExecute;
+ }
+ else
+ {
+ kernelEntry[-1].handler = queueControl->lastUpdate;
+ }
+ }
+
+ /* Release the mutex. */
+ gcmkERR_BREAK(gckOS_ReleaseMutex(
+ Command->os,
+ Command->queueMutex
+ ));
+ /* Schedule tasks. */
+ gcmkERR_BREAK(_ScheduleTasks(Command, TaskTable, previousEnd));
+
+ /* Acquire the mutex. */
+ gcmkERR_BREAK(gckOS_AcquireMutex(
+ Command->os,
+ Command->queueMutex,
+ gcvINFINITE
+ ));
+ }
+
+ /* Unkock and schedule the current queue for execution. */
+ gcmkERR_BREAK(_UnlockCurrentQueue(
+ Command, currentLength
+ ));
+ }
+ }
+ while (gcvFALSE);
+
+ if (mappedQueue)
+ {
+ if(!needCopy)
+ {
+ /* Unmap the user command buffer. */
+ gcmkERR_BREAK(gckOS_UnmapUserPointer(
+ Command->os,
+ Queue,
+ queueSize,
+ mappedQueue
+ ));
+ }
+ else
+ {
+ gcmkERR_BREAK(gckOS_Free(Command->os, mappedQueue));
+ }
+ }
+
+ /* Release the mutex. */
+ gcmkCHECK_STATUS(gckOS_ReleaseMutex(
+ Command->os,
+ Command->commitMutex
+ ));
+
+ gcmkVERIFY_OK(gckOS_ReleaseSemaphore(
+ Command->os, Command->powerSemaphore));
+ }
+ while (gcvFALSE);
+#ifdef __QNXNTO__
+ if (userContextMapped)
+ {
+ /* Unmap the user context. */
+ gcmkVERIFY_OK(gckOS_UnmapUserPointer(
+ Command->os,
+ userContext,
+ gcmSIZEOF(*userContext),
+ Context));
+ }
+
+ if (userTaskTableMapped)
+ {
+ /* Unmap the user taskTable. */
+ gcmkVERIFY_OK(gckOS_UnmapUserPointer(
+ Command->os,
+ userTaskTable,
+ gcmSIZEOF(*userTaskTable),
+ TaskTable));
+ }
+#endif
+
+ gcmkFOOTER();
+ /* Return status. */
+ return status;
+}
+
+#endif /* gcdENABLE_VG */
diff --git a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_db.c b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_db.c
new file mode 100644
index 000000000000..49c261a633f0
--- /dev/null
+++ b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_db.c
@@ -0,0 +1,1877 @@
+/****************************************************************************
+*
+* The MIT License (MIT)
+*
+* Copyright (c) 2014 - 2018 Vivante 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 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 GPL License (GPL)
+*
+* Copyright (C) 2014 - 2018 Vivante 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.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+*****************************************************************************
+*
+* Note: This software is released under dual MIT and GPL licenses. A
+* recipient may use this file under the terms of either the MIT license or
+* GPL License. If you wish to use only one license not the other, you can
+* indicate your decision by deleting one of the above license notices in your
+* version of this file.
+*
+*****************************************************************************/
+
+
+#include "gc_hal_kernel_precomp.h"
+
+#define _GC_OBJ_ZONE gcvZONE_DATABASE
+
+/*******************************************************************************
+***** Private fuctions ********************************************************/
+
+#define _GetSlot(database, x) \
+ (gctUINT32)(gcmPTR_TO_UINT64(x) % gcmCOUNTOF(database->list))
+
+/*******************************************************************************
+** gckKERNEL_FindDatabase
+**
+** Find a database identified by a process ID and move it to the head of the
+** hash list.
+**
+** INPUT:
+**
+** gckKERNEL Kernel
+** Pointer to a gckKERNEL object.
+**
+** gctUINT32 ProcessID
+** ProcessID that identifies the database.
+**
+** gctBOOL LastProcessID
+** gcvTRUE if searching for the last known process ID. gcvFALSE if
+** we need to search for the process ID specified by the ProcessID
+** argument.
+**
+** OUTPUT:
+**
+** gcsDATABASE_PTR * Database
+** Pointer to a variable receiving the database structure pointer on
+** success.
+*/
+gceSTATUS
+gckKERNEL_FindDatabase(
+ IN gckKERNEL Kernel,
+ IN gctUINT32 ProcessID,
+ IN gctBOOL LastProcessID,
+ OUT gcsDATABASE_PTR * Database
+ )
+{
+ gceSTATUS status;
+ gcsDATABASE_PTR database, previous;
+ gctSIZE_T slot;
+ gctBOOL acquired = gcvFALSE;
+
+ gcmkHEADER_ARG("Kernel=0x%x ProcessID=%d LastProcessID=%d",
+ Kernel, ProcessID, LastProcessID);
+
+ /* Compute the hash for the database. */
+ slot = ProcessID % gcmCOUNTOF(Kernel->db->db);
+
+ /* Acquire the database mutex. */
+ gcmkONERROR(
+ gckOS_AcquireMutex(Kernel->os, Kernel->db->dbMutex, gcvINFINITE));
+ acquired = gcvTRUE;
+
+ /* Check whether we are getting the last known database. */
+ if (LastProcessID)
+ {
+ /* Use last database. */
+ database = Kernel->db->lastDatabase;
+
+ if (database == gcvNULL)
+ {
+ /* Database not found. */
+ gcmkONERROR(gcvSTATUS_INVALID_DATA);
+ }
+ }
+ else
+ {
+ /* Walk the hash list. */
+ for (previous = gcvNULL, database = Kernel->db->db[slot];
+ database != gcvNULL;
+ database = database->next)
+ {
+ if (database->processID == ProcessID)
+ {
+ /* Found it! */
+ break;
+ }
+
+ previous = database;
+ }
+
+ if (database == gcvNULL)
+ {
+ /* Database not found. */
+ gcmkONERROR(gcvSTATUS_INVALID_DATA);
+ }
+
+ if (previous != gcvNULL)
+ {
+ /* Move database to the head of the hash list. */
+ previous->next = database->next;
+ database->next = Kernel->db->db[slot];
+ Kernel->db->db[slot] = database;
+ }
+ }
+
+ /* Release the database mutex. */
+ gcmkONERROR(gckOS_ReleaseMutex(Kernel->os, Kernel->db->dbMutex));
+
+ /* Return the database. */
+ *Database = database;
+
+ /* Success. */
+ gcmkFOOTER_ARG("*Database=0x%x", *Database);
+ return gcvSTATUS_OK;
+
+OnError:
+ if (acquired)
+ {
+ /* Release the database mutex. */
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, Kernel->db->dbMutex));
+ }
+
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+/*******************************************************************************
+** gckKERNEL_DeinitDatabase
+**
+** De-init a database structure.
+**
+** INPUT:
+**
+** gckKERNEL Kernel
+** Pointer to a gckKERNEL object.
+**
+** gcsDATABASE_PTR Database
+** Pointer to the database structure to deinit.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+static gceSTATUS
+gckKERNEL_DeinitDatabase(
+ IN gckKERNEL Kernel,
+ IN gcsDATABASE_PTR Database
+ )
+{
+ gcmkHEADER_ARG("Kernel=0x%x Database=0x%x", Kernel, Database);
+
+ if (Database)
+ {
+ Database->deleted = gcvFALSE;
+
+ /* Destory handle db. */
+ if (Database->refs)
+ {
+ gcmkVERIFY_OK(gckOS_AtomDestroy(Kernel->os, Database->refs));
+ Database->refs = gcvNULL;
+ }
+
+ if (Database->handleDatabase)
+ {
+ gcmkVERIFY_OK(gckKERNEL_DestroyIntegerDatabase(Kernel, Database->handleDatabase));
+ Database->handleDatabase = gcvNULL;
+ }
+
+ if (Database->handleDatabaseMutex)
+ {
+ gcmkVERIFY_OK(gckOS_DeleteMutex(Kernel->os, Database->handleDatabaseMutex));
+ Database->handleDatabaseMutex = gcvNULL;
+ }
+
+#if gcdPROCESS_ADDRESS_SPACE
+ if (Database->mmu)
+ {
+ gcmkONERROR(gckEVENT_DestroyMmu(Kernel->eventObj, Database->mmu, gcvKERNEL_PIXEL));
+ Database->mmu = gcvNULL;
+ }
+#endif
+ }
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+}
+
+/*******************************************************************************
+** gckKERNEL_NewRecord
+**
+** Create a new database record structure and insert it to the head of the
+** database.
+**
+** INPUT:
+**
+** gckKERNEL Kernel
+** Pointer to a gckKERNEL object.
+**
+** gcsDATABASE_PTR Database
+** Pointer to a database structure.
+**
+** OUTPUT:
+**
+** gcsDATABASE_RECORD_PTR * Record
+** Pointer to a variable receiving the database record structure
+** pointer on success.
+*/
+static gceSTATUS
+gckKERNEL_NewRecord(
+ IN gckKERNEL Kernel,
+ IN gcsDATABASE_PTR Database,
+ IN gctUINT32 Slot,
+ OUT gcsDATABASE_RECORD_PTR * Record
+ )
+{
+ gceSTATUS status;
+ gctBOOL acquired = gcvFALSE;
+ gcsDATABASE_RECORD_PTR record = gcvNULL;
+
+ gcmkHEADER_ARG("Kernel=0x%x Database=0x%x", Kernel, Database);
+
+ /* Acquire the database mutex. */
+ gcmkONERROR(
+ gckOS_AcquireMutex(Kernel->os, Kernel->db->dbMutex, gcvINFINITE));
+ acquired = gcvTRUE;
+
+ if (Kernel->db->freeRecord != gcvNULL)
+ {
+ /* Allocate the record from the free list. */
+ record = Kernel->db->freeRecord;
+ Kernel->db->freeRecord = record->next;
+ }
+ else
+ {
+ gctPOINTER pointer = gcvNULL;
+
+ /* Allocate the record from the heap. */
+ gcmkONERROR(gckOS_Allocate(Kernel->os,
+ gcmSIZEOF(gcsDATABASE_RECORD),
+ &pointer));
+
+ record = pointer;
+ }
+
+ /* Insert the record in the database. */
+ record->next = Database->list[Slot];
+ Database->list[Slot] = record;
+
+ /* Release the database mutex. */
+ gcmkONERROR(gckOS_ReleaseMutex(Kernel->os, Kernel->db->dbMutex));
+
+ /* Return the record. */
+ *Record = record;
+
+ /* Success. */
+ gcmkFOOTER_ARG("*Record=0x%x", *Record);
+ return gcvSTATUS_OK;
+
+OnError:
+ if (acquired)
+ {
+ /* Release the database mutex. */
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, Kernel->db->dbMutex));
+ }
+ if (record != gcvNULL)
+ {
+ gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Kernel->os, record));
+ }
+
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+/*******************************************************************************
+** gckKERNEL_DeleteRecord
+**
+** Remove a database record from the database and delete its structure.
+**
+** INPUT:
+**
+** gckKERNEL Kernel
+** Pointer to a gckKERNEL object.
+**
+** gcsDATABASE_PTR Database
+** Pointer to a database structure.
+**
+** gceDATABASE_TYPE Type
+** Type of the record to remove.
+**
+** gctPOINTER Data
+** Data of the record to remove.
+**
+** OUTPUT:
+**
+** gctSIZE_T_PTR Bytes
+** Pointer to a variable that receives the size of the record deleted.
+** Can be gcvNULL if the size is not required.
+*/
+static gceSTATUS
+gckKERNEL_DeleteRecord(
+ IN gckKERNEL Kernel,
+ IN gcsDATABASE_PTR Database,
+ IN gceDATABASE_TYPE Type,
+ IN gctPOINTER Data,
+ OUT gctSIZE_T_PTR Bytes OPTIONAL
+ )
+{
+ gceSTATUS status;
+ gctBOOL acquired = gcvFALSE;
+ gcsDATABASE_RECORD_PTR record, previous;
+ gctUINT32 slot = _GetSlot(Database, Data);
+
+ gcmkHEADER_ARG("Kernel=0x%x Database=0x%x Type=%d Data=0x%x",
+ Kernel, Database, Type, Data);
+
+ /* Acquire the database mutex. */
+ gcmkONERROR(
+ gckOS_AcquireMutex(Kernel->os, Kernel->db->dbMutex, gcvINFINITE));
+ acquired = gcvTRUE;
+
+ /* Scan the database for this record. */
+ for (record = Database->list[slot], previous = gcvNULL;
+ record != gcvNULL;
+ record = record->next
+ )
+ {
+ if ((record->type == Type)
+ && (record->data == Data)
+ )
+ {
+ /* Found it! */
+ break;
+ }
+
+ previous = record;
+ }
+
+ if (record == gcvNULL)
+ {
+ /* Ouch! This record is not found? */
+ gcmkONERROR(gcvSTATUS_INVALID_DATA);
+ }
+
+ if (Bytes != gcvNULL)
+ {
+ /* Return size of record. */
+ *Bytes = record->bytes;
+ }
+
+ /* Remove record from database. */
+ if (previous == gcvNULL)
+ {
+ Database->list[slot] = record->next;
+ }
+ else
+ {
+ previous->next = record->next;
+ }
+
+ /* Insert record in free list. */
+ record->next = Kernel->db->freeRecord;
+ Kernel->db->freeRecord = record;
+
+ /* Release the database mutex. */
+ gcmkONERROR(gckOS_ReleaseMutex(Kernel->os, Kernel->db->dbMutex));
+
+ /* Success. */
+ gcmkFOOTER_ARG("*Bytes=%lu", gcmOPT_VALUE(Bytes));
+ return gcvSTATUS_OK;
+
+OnError:
+ if (acquired)
+ {
+ /* Release the database mutex. */
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, Kernel->db->dbMutex));
+ }
+
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+/*******************************************************************************
+** gckKERNEL_FindRecord
+**
+** Find a database record from the database.
+**
+** INPUT:
+**
+** gckKERNEL Kernel
+** Pointer to a gckKERNEL object.
+**
+** gcsDATABASE_PTR Database
+** Pointer to a database structure.
+**
+** gceDATABASE_TYPE Type
+** Type of the record to remove.
+**
+** gctPOINTER Data
+** Data of the record to remove.
+**
+** OUTPUT:
+**
+** gctSIZE_T_PTR Bytes
+** Pointer to a variable that receives the size of the record deleted.
+** Can be gcvNULL if the size is not required.
+*/
+static gceSTATUS
+gckKERNEL_FindRecord(
+ IN gckKERNEL Kernel,
+ IN gcsDATABASE_PTR Database,
+ IN gceDATABASE_TYPE Type,
+ IN gctPOINTER Data,
+ OUT gcsDATABASE_RECORD_PTR Record
+ )
+{
+ gceSTATUS status;
+ gctBOOL acquired = gcvFALSE;
+ gcsDATABASE_RECORD_PTR record;
+ gctUINT32 slot = _GetSlot(Database, Data);
+
+ gcmkHEADER_ARG("Kernel=0x%x Database=0x%x Type=%d Data=0x%x",
+ Kernel, Database, Type, Data);
+
+ /* Acquire the database mutex. */
+ gcmkONERROR(
+ gckOS_AcquireMutex(Kernel->os, Kernel->db->dbMutex, gcvINFINITE));
+ acquired = gcvTRUE;
+
+ /* Scan the database for this record. */
+ for (record = Database->list[slot];
+ record != gcvNULL;
+ record = record->next
+ )
+ {
+ if ((record->type == Type)
+ && (record->data == Data)
+ )
+ {
+ /* Found it! */
+ break;
+ }
+ }
+
+ if (record == gcvNULL)
+ {
+ /* Ouch! This record is not found? */
+ gcmkONERROR(gcvSTATUS_INVALID_DATA);
+ }
+
+ if (Record != gcvNULL)
+ {
+ /* Return information of record. */
+ gcmkONERROR(
+ gckOS_MemCopy(Record, record, sizeof(gcsDATABASE_RECORD)));
+ }
+
+ /* Release the database mutex. */
+ gcmkONERROR(gckOS_ReleaseMutex(Kernel->os, Kernel->db->dbMutex));
+
+ /* Success. */
+ gcmkFOOTER_ARG("Record=0x%x", Record);
+ return gcvSTATUS_OK;
+
+OnError:
+ if (acquired)
+ {
+ /* Release the database mutex. */
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, Kernel->db->dbMutex));
+ }
+
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+/*******************************************************************************
+***** Public API **************************************************************/
+
+/*******************************************************************************
+** gckKERNEL_CreateProcessDB
+**
+** Create a new process database.
+**
+** INPUT:
+**
+** gckKERNEL Kernel
+** Pointer to a gckKERNEL object.
+**
+** gctUINT32 ProcessID
+** Process ID used to identify the database.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckKERNEL_CreateProcessDB(
+ IN gckKERNEL Kernel,
+ IN gctUINT32 ProcessID
+ )
+{
+ gceSTATUS status = gcvSTATUS_OK;
+ gcsDATABASE_PTR database = gcvNULL;
+ gctPOINTER pointer = gcvNULL;
+ gctBOOL acquired = gcvFALSE;
+ gctSIZE_T slot;
+ gctUINT32 i;
+
+ gcmkHEADER_ARG("Kernel=0x%x ProcessID=%d", Kernel, ProcessID);
+
+ /* Compute the hash for the database. */
+ slot = ProcessID % gcmCOUNTOF(Kernel->db->db);
+
+ /* Acquire the database mutex. */
+ gcmkONERROR(gckOS_AcquireMutex(Kernel->os, Kernel->db->dbMutex, gcvINFINITE));
+ acquired = gcvTRUE;
+
+ /* Walk the hash list. */
+ for (database = Kernel->db->db[slot];
+ database != gcvNULL;
+ database = database->next)
+ {
+ if (database->processID == ProcessID)
+ {
+ gctINT32 oldVal = 0;
+
+ if (database->deleted)
+ {
+ gcmkFATAL("%s(%d): DB of Process=0x%x cannot be reentered since it was in deletion\n",
+ __FUNCTION__, __LINE__, ProcessID);
+ gcmkONERROR(gcvSTATUS_INVALID_REQUEST);
+ }
+
+ gcmkVERIFY_OK(gckOS_AtomIncrement(Kernel->os, database->refs, &oldVal));
+ goto OnExit;
+ }
+ }
+
+ if (Kernel->db->freeDatabase)
+ {
+ /* Allocate a database from the free list. */
+ database = Kernel->db->freeDatabase;
+ Kernel->db->freeDatabase = database->next;
+ }
+ else
+ {
+ /* Allocate a new database from the heap. */
+ gcmkONERROR(gckOS_Allocate(Kernel->os,
+ gcmSIZEOF(gcsDATABASE),
+ &pointer));
+
+ gckOS_ZeroMemory(pointer, gcmSIZEOF(gcsDATABASE));
+
+ database = pointer;
+
+ gcmkONERROR(gckOS_CreateMutex(Kernel->os, &database->counterMutex));
+ }
+
+ /* Initialize the database. */
+ /* Save the hash slot. */
+ database->slot = slot;
+ database->processID = ProcessID;
+ database->vidMem.bytes = 0;
+ database->vidMem.maxBytes = 0;
+ database->vidMem.totalBytes = 0;
+ database->nonPaged.bytes = 0;
+ database->nonPaged.maxBytes = 0;
+ database->nonPaged.totalBytes = 0;
+ database->contiguous.bytes = 0;
+ database->contiguous.maxBytes = 0;
+ database->contiguous.totalBytes = 0;
+ database->mapMemory.bytes = 0;
+ database->mapMemory.maxBytes = 0;
+ database->mapMemory.totalBytes = 0;
+ database->mapUserMemory.bytes = 0;
+ database->mapUserMemory.maxBytes = 0;
+ database->mapUserMemory.totalBytes = 0;
+
+ for (i = 0; i < gcmCOUNTOF(database->list); i++)
+ {
+ database->list[i] = gcvNULL;
+ }
+
+ for (i = 0; i < gcvSURF_NUM_TYPES; i++)
+ {
+ database->vidMemType[i].bytes = 0;
+ database->vidMemType[i].maxBytes = 0;
+ database->vidMemType[i].totalBytes = 0;
+ }
+
+ for (i = 0; i < gcvPOOL_NUMBER_OF_POOLS; i++)
+ {
+ database->vidMemPool[i].bytes = 0;
+ database->vidMemPool[i].maxBytes = 0;
+ database->vidMemPool[i].totalBytes = 0;
+ }
+
+ gcmkASSERT(database->refs == gcvNULL);
+ gcmkONERROR(gckOS_AtomConstruct(Kernel->os, &database->refs));
+ gcmkONERROR(gckOS_AtomSet(Kernel->os, database->refs, 1));
+
+ gcmkASSERT(database->handleDatabase == gcvNULL);
+ gcmkONERROR(gckKERNEL_CreateIntegerDatabase(Kernel, &database->handleDatabase));
+
+ gcmkASSERT(database->handleDatabaseMutex == gcvNULL);
+ gcmkONERROR(gckOS_CreateMutex(Kernel->os, &database->handleDatabaseMutex));
+
+#if gcdPROCESS_ADDRESS_SPACE
+ gcmkASSERT(database->mmu == gcvNULL);
+ gcmkONERROR(gckMMU_Construct(Kernel, gcdMMU_SIZE, &database->mmu));
+#endif
+
+#if gcdSECURE_USER
+ {
+ gctINT idx;
+ gcskSECURE_CACHE * cache = &database->cache;
+
+ /* Setup the linked list of cache nodes. */
+ for (idx = 1; idx <= gcdSECURE_CACHE_SLOTS; ++idx)
+ {
+ cache->cache[idx].logical = gcvNULL;
+
+#if gcdSECURE_CACHE_METHOD != gcdSECURE_CACHE_TABLE
+ cache->cache[idx].prev = &cache->cache[idx - 1];
+ cache->cache[idx].next = &cache->cache[idx + 1];
+# endif
+#if gcdSECURE_CACHE_METHOD == gcdSECURE_CACHE_HASH
+ cache->cache[idx].nextHash = gcvNULL;
+ cache->cache[idx].prevHash = gcvNULL;
+# endif
+ }
+
+#if gcdSECURE_CACHE_METHOD != gcdSECURE_CACHE_TABLE
+ /* Setup the head and tail of the cache. */
+ cache->cache[0].next = &cache->cache[1];
+ cache->cache[0].prev = &cache->cache[gcdSECURE_CACHE_SLOTS];
+ cache->cache[0].logical = gcvNULL;
+
+ /* Fix up the head and tail pointers. */
+ cache->cache[0].next->prev = &cache->cache[0];
+ cache->cache[0].prev->next = &cache->cache[0];
+# endif
+
+#if gcdSECURE_CACHE_METHOD == gcdSECURE_CACHE_HASH
+ /* Zero out the hash table. */
+ for (idx = 0; idx < gcmCOUNTOF(cache->hash); ++idx)
+ {
+ cache->hash[idx].logical = gcvNULL;
+ cache->hash[idx].nextHash = gcvNULL;
+ }
+# endif
+
+ /* Initialize cache index. */
+ cache->cacheIndex = gcvNULL;
+ cache->cacheFree = 1;
+ cache->cacheStamp = 0;
+ }
+#endif
+
+ /* Insert the database into the hash. */
+ database->next = Kernel->db->db[slot];
+ Kernel->db->db[slot] = database;
+
+ /* Reset idle timer. */
+ Kernel->db->lastIdle = 0;
+
+OnError:
+ if (gcmIS_ERROR(status))
+ {
+ gcmkVERIFY_OK(gckKERNEL_DeinitDatabase(Kernel, database));
+
+ if (pointer)
+ {
+ gcmkOS_SAFE_FREE(Kernel->os, pointer);
+ }
+ }
+
+OnExit:
+ if (acquired)
+ {
+ /* Release the database mutex. */
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, Kernel->db->dbMutex));
+ }
+
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+/*******************************************************************************
+** gckKERNEL_AddProcessDB
+**
+** Add a record to a process database.
+**
+** INPUT:
+**
+** gckKERNEL Kernel
+** Pointer to a gckKERNEL object.
+**
+** gctUINT32 ProcessID
+** Process ID used to identify the database.
+**
+** gceDATABASE_TYPE TYPE
+** Type of the record to add.
+**
+** gctPOINTER Pointer
+** Data of the record to add.
+**
+** gctPHYS_ADDR Physical
+** Physical address of the record to add.
+**
+** gctSIZE_T Size
+** Size of the record to add.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckKERNEL_AddProcessDB(
+ IN gckKERNEL Kernel,
+ IN gctUINT32 ProcessID,
+ IN gceDATABASE_TYPE Type,
+ IN gctPOINTER Pointer,
+ IN gctPHYS_ADDR Physical,
+ IN gctSIZE_T Size
+ )
+{
+ gceSTATUS status;
+ gcsDATABASE_PTR database;
+ gcsDATABASE_RECORD_PTR record = gcvNULL;
+ gcsDATABASE_COUNTERS * count;
+ gctUINT32 vidMemType;
+ gcePOOL vidMemPool;
+
+ gcmkHEADER_ARG("Kernel=0x%x ProcessID=%d Type=%d Pointer=0x%x "
+ "Physical=0x%x Size=%lu",
+ Kernel, ProcessID, Type, Pointer, Physical, Size);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
+
+ /* Decode type. */
+ vidMemType = (Type & gcdDB_VIDEO_MEMORY_TYPE_MASK) >> gcdDB_VIDEO_MEMORY_TYPE_SHIFT;
+ vidMemPool = (Type & gcdDB_VIDEO_MEMORY_POOL_MASK) >> gcdDB_VIDEO_MEMORY_POOL_SHIFT;
+
+ Type &= gcdDATABASE_TYPE_MASK;
+
+ /* Special case the idle record. */
+ if (Type == gcvDB_IDLE)
+ {
+ gctUINT64 time;
+
+ /* Get the current profile time. */
+ gcmkONERROR(gckOS_GetProfileTick(&time));
+
+ if ((ProcessID == 0) && (Kernel->db->lastIdle != 0))
+ {
+ /* Out of idle, adjust time it was idle. */
+ Kernel->db->idleTime += time - Kernel->db->lastIdle;
+ Kernel->db->lastIdle = 0;
+ }
+ else if (ProcessID == 1)
+ {
+ /* Save current idle time. */
+ Kernel->db->lastIdle = time;
+ }
+
+#if gcdDYNAMIC_SPEED
+ {
+ /* Test for first call. */
+ if (Kernel->db->lastSlowdown == 0)
+ {
+ /* Save milliseconds. */
+ Kernel->db->lastSlowdown = time;
+ Kernel->db->lastSlowdownIdle = Kernel->db->idleTime;
+ }
+ else
+ {
+ /* Compute ellapsed time in milliseconds. */
+ gctUINT delta = gckOS_ProfileToMS(time - Kernel->db->lastSlowdown);
+
+ /* Test for end of period. */
+ if (delta >= gcdDYNAMIC_SPEED)
+ {
+ /* Compute number of idle milliseconds. */
+ gctUINT idle = gckOS_ProfileToMS(
+ Kernel->db->idleTime - Kernel->db->lastSlowdownIdle);
+
+ /* Broadcast to slow down the GPU. */
+ gcmkONERROR(gckOS_BroadcastCalibrateSpeed(Kernel->os,
+ Kernel->hardware,
+ idle,
+ delta));
+
+ /* Save current time. */
+ Kernel->db->lastSlowdown = time;
+ Kernel->db->lastSlowdownIdle = Kernel->db->idleTime;
+ }
+ }
+ }
+#endif
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+ }
+
+ /* Verify the arguments. */
+ gcmkVERIFY_ARGUMENT(Pointer != gcvNULL);
+
+ /* Find the database. */
+ gcmkONERROR(gckKERNEL_FindDatabase(Kernel, ProcessID, gcvFALSE, &database));
+
+ /* Create a new record in the database. */
+ gcmkONERROR(gckKERNEL_NewRecord(Kernel, database, _GetSlot(database, Pointer), &record));
+
+ /* Initialize the record. */
+ record->kernel = Kernel;
+ record->type = Type;
+ record->data = Pointer;
+ record->physical = Physical;
+ record->bytes = Size;
+
+ /* Get pointer to counters. */
+ switch (Type)
+ {
+ case gcvDB_VIDEO_MEMORY:
+ count = &database->vidMem;
+ break;
+
+ case gcvDB_NON_PAGED:
+ count = &database->nonPaged;
+ break;
+
+ case gcvDB_CONTIGUOUS:
+ count = &database->contiguous;
+ break;
+
+ case gcvDB_MAP_MEMORY:
+ count = &database->mapMemory;
+ break;
+
+ case gcvDB_MAP_USER_MEMORY:
+ count = &database->mapUserMemory;
+ break;
+
+ default:
+ count = gcvNULL;
+ break;
+ }
+
+ gcmkVERIFY_OK(gckOS_AcquireMutex(Kernel->os, database->counterMutex, gcvINFINITE));
+
+ if (count != gcvNULL)
+ {
+ /* Adjust counters. */
+ count->totalBytes += Size;
+ count->bytes += Size;
+ count->allocCount++;
+
+ if (count->bytes > count->maxBytes)
+ {
+ count->maxBytes = count->bytes;
+ }
+ }
+
+ if (Type == gcvDB_VIDEO_MEMORY)
+ {
+ count = &database->vidMemType[vidMemType];
+
+ /* Adjust counters. */
+ count->totalBytes += Size;
+ count->bytes += Size;
+ count->allocCount++;
+
+ if (count->bytes > count->maxBytes)
+ {
+ count->maxBytes = count->bytes;
+ }
+
+ count = &database->vidMemPool[vidMemPool];
+
+ /* Adjust counters. */
+ count->totalBytes += Size;
+ count->bytes += Size;
+ count->allocCount++;
+
+ if (count->bytes > count->maxBytes)
+ {
+ count->maxBytes = count->bytes;
+ }
+ }
+
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, database->counterMutex));
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+/*******************************************************************************
+** gckKERNEL_RemoveProcessDB
+**
+** Remove a record from a process database.
+**
+** INPUT:
+**
+** gckKERNEL Kernel
+** Pointer to a gckKERNEL object.
+**
+** gctUINT32 ProcessID
+** Process ID used to identify the database.
+**
+** gceDATABASE_TYPE TYPE
+** Type of the record to remove.
+**
+** gctPOINTER Pointer
+** Data of the record to remove.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckKERNEL_RemoveProcessDB(
+ IN gckKERNEL Kernel,
+ IN gctUINT32 ProcessID,
+ IN gceDATABASE_TYPE Type,
+ IN gctPOINTER Pointer
+ )
+{
+ gceSTATUS status;
+ gcsDATABASE_PTR database;
+ gctSIZE_T bytes = 0;
+ gctUINT32 vidMemType;
+ gcePOOL vidMemPool;
+
+ gcmkHEADER_ARG("Kernel=0x%x ProcessID=%d Type=%d Pointer=0x%x",
+ Kernel, ProcessID, Type, Pointer);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
+ gcmkVERIFY_ARGUMENT(Pointer != gcvNULL);
+
+ /* Decode type. */
+ vidMemType = (Type & gcdDB_VIDEO_MEMORY_TYPE_MASK) >> gcdDB_VIDEO_MEMORY_TYPE_SHIFT;
+ vidMemPool = (Type & gcdDB_VIDEO_MEMORY_POOL_MASK) >> gcdDB_VIDEO_MEMORY_POOL_SHIFT;
+
+ Type &= gcdDATABASE_TYPE_MASK;
+
+ /* Find the database. */
+ gcmkONERROR(gckKERNEL_FindDatabase(Kernel, ProcessID, gcvFALSE, &database));
+
+ /* Delete the record. */
+ gcmkONERROR(
+ gckKERNEL_DeleteRecord(Kernel, database, Type, Pointer, &bytes));
+
+ gcmkVERIFY_OK(gckOS_AcquireMutex(Kernel->os, database->counterMutex, gcvINFINITE));
+
+ /* Update counters. */
+ switch (Type)
+ {
+ case gcvDB_VIDEO_MEMORY:
+ database->vidMem.bytes -= bytes;
+ database->vidMem.freeCount++;
+ database->vidMemType[vidMemType].bytes -= bytes;
+ database->vidMemType[vidMemType].freeCount++;
+ database->vidMemPool[vidMemPool].bytes -= bytes;
+ database->vidMemPool[vidMemPool].freeCount++;
+ break;
+
+ case gcvDB_NON_PAGED:
+ database->nonPaged.bytes -= bytes;
+ database->nonPaged.freeCount++;
+ break;
+
+ case gcvDB_CONTIGUOUS:
+ database->contiguous.bytes -= bytes;
+ database->contiguous.freeCount++;
+ break;
+
+ case gcvDB_MAP_MEMORY:
+ database->mapMemory.bytes -= bytes;
+ database->mapMemory.freeCount++;
+ break;
+
+ case gcvDB_MAP_USER_MEMORY:
+ database->mapUserMemory.bytes -= bytes;
+ database->mapUserMemory.freeCount++;
+ break;
+
+ default:
+ break;
+ }
+
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, database->counterMutex));
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+/*******************************************************************************
+** gckKERNEL_FindProcessDB
+**
+** Find a record from a process database.
+**
+** INPUT:
+**
+** gckKERNEL Kernel
+** Pointer to a gckKERNEL object.
+**
+** gctUINT32 ProcessID
+** Process ID used to identify the database.
+**
+** gceDATABASE_TYPE TYPE
+** Type of the record to remove.
+**
+** gctPOINTER Pointer
+** Data of the record to remove.
+**
+** OUTPUT:
+**
+** gcsDATABASE_RECORD_PTR Record
+** Copy of record.
+*/
+gceSTATUS
+gckKERNEL_FindProcessDB(
+ IN gckKERNEL Kernel,
+ IN gctUINT32 ProcessID,
+ IN gctUINT32 ThreadID,
+ IN gceDATABASE_TYPE Type,
+ IN gctPOINTER Pointer,
+ OUT gcsDATABASE_RECORD_PTR Record
+ )
+{
+ gceSTATUS status;
+ gcsDATABASE_PTR database;
+
+ gcmkHEADER_ARG("Kernel=0x%x ProcessID=%d Type=%d Pointer=0x%x",
+ Kernel, ProcessID, ThreadID, Type, Pointer);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
+ gcmkVERIFY_ARGUMENT(Pointer != gcvNULL);
+
+ /* Find the database. */
+ gcmkONERROR(gckKERNEL_FindDatabase(Kernel, ProcessID, gcvFALSE, &database));
+
+ /* Find the record. */
+ gcmkONERROR(
+ gckKERNEL_FindRecord(Kernel, database, Type, Pointer, Record));
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+/*******************************************************************************
+** gckKERNEL_DestroyProcessDB
+**
+** Destroy a process database. If the database contains any records, the data
+** inside those records will be deleted as well. This aids in the cleanup if
+** a process has died unexpectedly or has memory leaks.
+**
+** INPUT:
+**
+** gckKERNEL Kernel
+** Pointer to a gckKERNEL object.
+**
+** gctUINT32 ProcessID
+** Process ID used to identify the database.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckKERNEL_DestroyProcessDB(
+ IN gckKERNEL Kernel,
+ IN gctUINT32 ProcessID
+ )
+{
+ gceSTATUS status = gcvSTATUS_OK;
+ gckKERNEL kernel = Kernel;
+ gcsDATABASE_PTR previous = gcvNULL;
+ gcsDATABASE_PTR database = gcvNULL;
+ gcsDATABASE_PTR db = gcvNULL;
+ gctBOOL acquired = gcvFALSE;
+ gctSIZE_T slot;
+ gctUINT32 i;
+
+ gcmkHEADER_ARG("Kernel=0x%x ProcessID=%d", Kernel, ProcessID);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
+
+ /* Compute the hash for the database. */
+ slot = ProcessID % gcmCOUNTOF(Kernel->db->db);
+
+ /* Acquire the database mutex. */
+ gcmkONERROR(gckOS_AcquireMutex(Kernel->os, Kernel->db->dbMutex, gcvINFINITE));
+ acquired = gcvTRUE;
+
+ /* Walk the hash list. */
+ for (database = Kernel->db->db[slot];
+ database != gcvNULL;
+ database = database->next)
+ {
+ if (database->processID == ProcessID)
+ {
+ break;
+ }
+ }
+
+ if (database)
+ {
+ gctINT32 oldVal = 0;
+ gcmkONERROR(gckOS_AtomDecrement(Kernel->os, database->refs, &oldVal));
+ if (oldVal != 1)
+ {
+ goto OnExit;
+ }
+
+ /* Mark it for delete so disallow reenter until really delete it */
+ gcmkASSERT(!database->deleted);
+ database->deleted = gcvTRUE;
+ }
+ else
+ {
+ gcmkFATAL("%s(%d): DB destroy of Process=0x%x cannot match with creation\n",
+ __FUNCTION__, __LINE__, ProcessID);
+ gcmkONERROR(gcvSTATUS_NOT_FOUND);
+ }
+
+ /* Cannot remove the database from the hash list
+ ** since later records deinit need to access from the hash
+ */
+
+ gcmkONERROR(gckOS_ReleaseMutex(Kernel->os, Kernel->db->dbMutex));
+ acquired = gcvFALSE;
+
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_DATABASE,
+ "DB(%d): VidMem: total=%lu max=%lu",
+ ProcessID, database->vidMem.totalBytes,
+ database->vidMem.maxBytes);
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_DATABASE,
+ "DB(%d): NonPaged: total=%lu max=%lu",
+ ProcessID, database->nonPaged.totalBytes,
+ database->nonPaged.maxBytes);
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_DATABASE,
+ "DB(%d): Contiguous: total=%lu max=%lu",
+ ProcessID, database->contiguous.totalBytes,
+ database->contiguous.maxBytes);
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_DATABASE,
+ "DB(%d): Idle time=%llu",
+ ProcessID, Kernel->db->idleTime);
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_DATABASE,
+ "DB(%d): Map: total=%lu max=%lu",
+ ProcessID, database->mapMemory.totalBytes,
+ database->mapMemory.maxBytes);
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_DATABASE,
+ "DB(%d): Map: total=%lu max=%lu",
+ ProcessID, database->mapUserMemory.totalBytes,
+ database->mapUserMemory.maxBytes);
+
+ if (database->list != gcvNULL)
+ {
+ gcmkTRACE_ZONE(gcvLEVEL_WARNING, gcvZONE_DATABASE,
+ "Process %d has entries in its database:",
+ ProcessID);
+ }
+
+ for (i = 0; i < gcmCOUNTOF(database->list); i++)
+ {
+ gcsDATABASE_RECORD_PTR record, next;
+
+ /* Walk all records. */
+ for (record = database->list[i]; record != gcvNULL; record = next)
+ {
+ gctBOOL asynchronous = gcvTRUE;
+ gckVIDMEM_NODE nodeObject;
+ gctPHYS_ADDR physical;
+ gctUINT32 handle;
+
+ /* Next next record. */
+ next = record->next;
+
+ /* Dispatch on record type. */
+ switch (record->type)
+ {
+ case gcvDB_VIDEO_MEMORY:
+ gcmkERR_BREAK(gckVIDMEM_HANDLE_Lookup(record->kernel,
+ ProcessID,
+ gcmPTR2INT32(record->data),
+ &nodeObject));
+
+ /* Free the video memory. */
+ gcmkVERIFY_OK(gckVIDMEM_HANDLE_Dereference(record->kernel,
+ ProcessID,
+ gcmPTR2INT32(record->data)));
+
+ gcmkVERIFY_OK(gckVIDMEM_NODE_Dereference(record->kernel,
+ nodeObject));
+
+ gcmkTRACE_ZONE(gcvLEVEL_WARNING, gcvZONE_DATABASE,
+ "DB: VIDEO_MEMORY 0x%x (status=%d)",
+ record->data, status);
+ break;
+
+ case gcvDB_NON_PAGED:
+ physical = gcmNAME_TO_PTR(record->physical);
+ /* Unmap user logical memory first. */
+ status = gckOS_UnmapUserLogical(Kernel->os,
+ physical,
+ record->bytes,
+ record->data);
+
+ /* Free the non paged memory. */
+ status = gckEVENT_FreeNonPagedMemory(record->kernel->eventObj,
+ record->bytes,
+ physical,
+ record->data,
+ gcvKERNEL_PIXEL);
+ gcmRELEASE_NAME(record->physical);
+
+ gcmkTRACE_ZONE(gcvLEVEL_WARNING, gcvZONE_DATABASE,
+ "DB: NON_PAGED 0x%x, bytes=%lu (status=%d)",
+ record->data, record->bytes, status);
+ break;
+
+ case gcvDB_COMMAND_BUFFER:
+ /* Free the command buffer. */
+ status = gckEVENT_DestroyVirtualCommandBuffer(record->kernel->eventObj,
+ record->bytes,
+ gcmNAME_TO_PTR(record->physical),
+ record->data,
+ gcvKERNEL_PIXEL);
+ gcmRELEASE_NAME(record->physical);
+
+ gcmkTRACE_ZONE(gcvLEVEL_WARNING, gcvZONE_DATABASE,
+ "DB: COMMAND_BUFFER 0x%x, bytes=%lu (status=%d)",
+ record->data, record->bytes, status);
+ break;
+
+ case gcvDB_CONTIGUOUS:
+ physical = gcmNAME_TO_PTR(record->physical);
+ /* Unmap user logical memory first. */
+ status = gckOS_UnmapUserLogical(Kernel->os,
+ physical,
+ record->bytes,
+ record->data);
+
+ /* Free the contiguous memory. */
+ status = gckEVENT_FreeContiguousMemory(record->kernel->eventObj,
+ record->bytes,
+ physical,
+ record->data,
+ gcvKERNEL_PIXEL);
+ gcmRELEASE_NAME(record->physical);
+
+ gcmkTRACE_ZONE(gcvLEVEL_WARNING, gcvZONE_DATABASE,
+ "DB: CONTIGUOUS 0x%x bytes=%lu (status=%d)",
+ record->data, record->bytes, status);
+ break;
+
+ case gcvDB_SIGNAL:
+#if USE_NEW_LINUX_SIGNAL
+ status = gcvSTATUS_NOT_SUPPORTED;
+#else
+ /* Free the user signal. */
+ status = gckOS_DestroyUserSignal(Kernel->os,
+ gcmPTR2INT32(record->data));
+#endif /* USE_NEW_LINUX_SIGNAL */
+
+ gcmkTRACE_ZONE(gcvLEVEL_WARNING, gcvZONE_DATABASE,
+ "DB: SIGNAL %d (status=%d)",
+ (gctINT)(gctUINTPTR_T)record->data, status);
+ break;
+
+ case gcvDB_VIDEO_MEMORY_LOCKED:
+ handle = gcmPTR2INT32(record->data);
+
+ gcmkERR_BREAK(gckVIDMEM_HANDLE_Lookup(record->kernel,
+ ProcessID,
+ handle,
+ &nodeObject));
+
+ /* Unlock what we still locked */
+ status = gckVIDMEM_Unlock(record->kernel,
+ nodeObject,
+ nodeObject->type,
+ &asynchronous);
+
+#if gcdENABLE_VG
+ if (record->kernel->core == gcvCORE_VG)
+ {
+ if (gcmIS_SUCCESS(status) && (gcvTRUE == asynchronous))
+ {
+ status = gckVIDMEM_Unlock(record->kernel,
+ nodeObject,
+ nodeObject->type,
+ gcvNULL);
+ }
+
+ gcmkVERIFY_OK(gckVIDMEM_HANDLE_Dereference(record->kernel,
+ ProcessID,
+ handle));
+
+ gcmkVERIFY_OK(gckVIDMEM_NODE_Dereference(record->kernel,
+ nodeObject));
+ }
+ else
+#endif
+ {
+ gcmkVERIFY_OK(gckVIDMEM_HANDLE_Dereference(record->kernel,
+ ProcessID,
+ handle));
+
+ if (gcmIS_SUCCESS(status) && (gcvTRUE == asynchronous))
+ {
+ status = gckEVENT_Unlock(record->kernel->eventObj,
+ gcvKERNEL_PIXEL,
+ nodeObject,
+ nodeObject->type);
+ }
+ else
+ {
+ gcmkVERIFY_OK(gckVIDMEM_NODE_Dereference(record->kernel,
+ nodeObject));
+ }
+ }
+
+ gcmkTRACE_ZONE(gcvLEVEL_WARNING, gcvZONE_DATABASE,
+ "DB: VIDEO_MEMORY_LOCKED 0x%x (status=%d)",
+ record->data, status);
+ break;
+
+ case gcvDB_CONTEXT:
+ status = gckCOMMAND_Detach(record->kernel->command, gcmNAME_TO_PTR(record->data));
+ gcmRELEASE_NAME(record->data);
+
+ gcmkTRACE_ZONE(gcvLEVEL_WARNING, gcvZONE_DATABASE,
+ "DB: CONTEXT 0x%x (status=%d)",
+ record->data, status);
+ break;
+
+ case gcvDB_MAP_MEMORY:
+ /* Unmap memory. */
+ status = gckKERNEL_UnmapMemory(record->kernel,
+ record->physical,
+ record->bytes,
+ record->data,
+ ProcessID);
+
+ gcmkTRACE_ZONE(gcvLEVEL_WARNING, gcvZONE_DATABASE,
+ "DB: MAP MEMORY %d (status=%d)",
+ gcmPTR2INT32(record->data), status);
+ break;
+
+ case gcvDB_MAP_USER_MEMORY:
+ status = gckOS_UnmapUserMemory(Kernel->os,
+ Kernel->core,
+ record->physical,
+ record->bytes,
+ gcmNAME_TO_PTR(record->data),
+ 0);
+ gcmRELEASE_NAME(record->data);
+
+ gcmkTRACE_ZONE(gcvLEVEL_WARNING, gcvZONE_DATABASE,
+ "DB: MAP USER MEMORY %d (status=%d)",
+ gcmPTR2INT32(record->data), status);
+ break;
+
+ case gcvDB_SHBUF:
+ /* Free shared buffer. */
+ status = gckKERNEL_DestroyShBuffer(record->kernel,
+ (gctSHBUF) record->data);
+
+ gcmkTRACE_ZONE(gcvLEVEL_WARNING, gcvZONE_DATABASE,
+ "DB: SHBUF %u (status=%d)",
+ (gctUINT32)(gctUINTPTR_T) record->data, status);
+ break;
+
+ default:
+ gcmkTRACE_ZONE(gcvLEVEL_ERROR, gcvZONE_DATABASE,
+ "DB: Correcupted record=0x%08x type=%d",
+ record, record->type);
+ break;
+ }
+
+ /* Delete the record. */
+ gcmkONERROR(gckKERNEL_DeleteRecord(Kernel,
+ database,
+ record->type,
+ record->data,
+ gcvNULL));
+ }
+ }
+
+ /* Acquire the database mutex. */
+ gcmkONERROR(gckOS_AcquireMutex(Kernel->os, Kernel->db->dbMutex, gcvINFINITE));
+ acquired = gcvTRUE;
+
+ /* Walk the hash list. */
+ for (db = Kernel->db->db[slot];
+ db != gcvNULL;
+ db = db->next)
+ {
+ if (db->processID == ProcessID)
+ {
+ break;
+ }
+ previous = db;
+ }
+
+ if (db != database || !db->deleted)
+ {
+ gcmkFATAL("%s(%d): DB of Process=0x%x corrupted after found in deletion\n",
+ __FUNCTION__, __LINE__, ProcessID);
+ gcmkONERROR(gcvSTATUS_NOT_FOUND);
+ }
+
+ /* Remove the database from the hash list. */
+ if (previous)
+ {
+ previous->next = database->next;
+ }
+ else
+ {
+ Kernel->db->db[slot] = database->next;
+ }
+
+ /* Deinit current database. */
+ gcmkVERIFY_OK(gckKERNEL_DeinitDatabase(Kernel, database));
+
+ if (Kernel->db->lastDatabase)
+ {
+ /* Insert last database to the free list. */
+ Kernel->db->lastDatabase->next = Kernel->db->freeDatabase;
+ Kernel->db->freeDatabase = Kernel->db->lastDatabase;
+ }
+
+ /* Update last database to current one. */
+ Kernel->db->lastDatabase = database;
+
+OnError:
+OnExit:
+ if (acquired)
+ {
+ /* Release the database mutex. */
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, Kernel->db->dbMutex));
+ }
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+/*******************************************************************************
+** gckKERNEL_QueryProcessDB
+**
+** Query a process database for the current usage of a particular record type.
+**
+** INPUT:
+**
+** gckKERNEL Kernel
+** Pointer to a gckKERNEL object.
+**
+** gctUINT32 ProcessID
+** Process ID used to identify the database.
+**
+** gctBOOL LastProcessID
+** gcvTRUE if searching for the last known process ID. gcvFALSE if
+** we need to search for the process ID specified by the ProcessID
+** argument.
+**
+** gceDATABASE_TYPE Type
+** Type of the record to query.
+**
+** OUTPUT:
+**
+** gcuDATABASE_INFO * Info
+** Pointer to a variable that receives the requested information.
+*/
+gceSTATUS
+gckKERNEL_QueryProcessDB(
+ IN gckKERNEL Kernel,
+ IN gctUINT32 ProcessID,
+ IN gctBOOL LastProcessID,
+ IN gceDATABASE_TYPE Type,
+ OUT gcuDATABASE_INFO * Info
+ )
+{
+ gceSTATUS status;
+ gcsDATABASE_PTR database;
+ gcePOOL vidMemPool;
+
+ gcmkHEADER_ARG("Kernel=0x%x ProcessID=%d Type=%d Info=0x%x",
+ Kernel, ProcessID, Type, Info);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
+ gcmkVERIFY_ARGUMENT(Info != gcvNULL);
+
+ /* Deocde pool. */
+ vidMemPool = (Type & gcdDB_VIDEO_MEMORY_POOL_MASK) >> gcdDB_VIDEO_MEMORY_POOL_SHIFT;
+
+ Type &= gcdDATABASE_TYPE_MASK;
+
+ /* Find the database. */
+ gcmkONERROR(gckKERNEL_FindDatabase(Kernel, ProcessID, LastProcessID, &database));
+
+ gcmkVERIFY_OK(gckOS_AcquireMutex(Kernel->os, database->counterMutex, gcvINFINITE));
+
+ /* Get pointer to counters. */
+ switch (Type)
+ {
+ case gcvDB_VIDEO_MEMORY:
+ if (vidMemPool != gcvPOOL_UNKNOWN)
+ {
+ gckOS_MemCopy(&Info->counters,
+ &database->vidMemPool[vidMemPool],
+ gcmSIZEOF(database->vidMemPool[vidMemPool]));
+ }
+ else
+ {
+ gckOS_MemCopy(&Info->counters,
+ &database->vidMem,
+ gcmSIZEOF(database->vidMem));
+ }
+ break;
+
+ case gcvDB_NON_PAGED:
+ gckOS_MemCopy(&Info->counters,
+ &database->nonPaged,
+ gcmSIZEOF(database->vidMem));
+ break;
+
+ case gcvDB_CONTIGUOUS:
+ gckOS_MemCopy(&Info->counters,
+ &database->contiguous,
+ gcmSIZEOF(database->vidMem));
+ break;
+
+ case gcvDB_IDLE:
+ Info->time = Kernel->db->idleTime;
+ Kernel->db->idleTime = 0;
+ break;
+
+ case gcvDB_MAP_MEMORY:
+ gckOS_MemCopy(&Info->counters,
+ &database->mapMemory,
+ gcmSIZEOF(database->mapMemory));
+ break;
+
+ case gcvDB_MAP_USER_MEMORY:
+ gckOS_MemCopy(&Info->counters,
+ &database->mapUserMemory,
+ gcmSIZEOF(database->mapUserMemory));
+ break;
+
+ default:
+ break;
+ }
+
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, database->counterMutex));
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+gceSTATUS
+gckKERNEL_FindHandleDatbase(
+ IN gckKERNEL Kernel,
+ IN gctUINT32 ProcessID,
+ OUT gctPOINTER * HandleDatabase,
+ OUT gctPOINTER * HandleDatabaseMutex
+ )
+{
+ gceSTATUS status;
+ gcsDATABASE_PTR database;
+
+ gcmkHEADER_ARG("Kernel=0x%x ProcessID=%d",
+ Kernel, ProcessID);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
+
+ /* Find the database. */
+ gcmkONERROR(gckKERNEL_FindDatabase(Kernel, ProcessID, gcvFALSE, &database));
+
+ *HandleDatabase = database->handleDatabase;
+ *HandleDatabaseMutex = database->handleDatabaseMutex;
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+#if gcdPROCESS_ADDRESS_SPACE
+gceSTATUS
+gckKERNEL_GetProcessMMU(
+ IN gckKERNEL Kernel,
+ OUT gckMMU * Mmu
+ )
+{
+ gceSTATUS status;
+ gcsDATABASE_PTR database;
+ gctUINT32 processID;
+
+ gcmkONERROR(gckOS_GetProcessID(&processID));
+
+ gcmkONERROR(gckKERNEL_FindDatabase(Kernel, processID, gcvFALSE, &database));
+
+ *Mmu = database->mmu;
+
+ return gcvSTATUS_OK;
+
+OnError:
+ return status;
+}
+#endif
+
+#if gcdSECURE_USER
+/*******************************************************************************
+** gckKERNEL_GetProcessDBCache
+**
+** Get teh secure cache from a process database.
+**
+** INPUT:
+**
+** gckKERNEL Kernel
+** Pointer to a gckKERNEL object.
+**
+** gctUINT32 ProcessID
+** Process ID used to identify the database.
+**
+** OUTPUT:
+**
+** gcskSECURE_CACHE_PTR * Cache
+** Pointer to a variable that receives the secure cache pointer.
+*/
+gceSTATUS
+gckKERNEL_GetProcessDBCache(
+ IN gckKERNEL Kernel,
+ IN gctUINT32 ProcessID,
+ OUT gcskSECURE_CACHE_PTR * Cache
+ )
+{
+ gceSTATUS status;
+ gcsDATABASE_PTR database;
+
+ gcmkHEADER_ARG("Kernel=0x%x ProcessID=%d", Kernel, ProcessID);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
+ gcmkVERIFY_ARGUMENT(Cache != gcvNULL);
+
+ /* Find the database. */
+ gcmkONERROR(gckKERNEL_FindDatabase(Kernel, ProcessID, gcvFALSE, &database));
+
+ /* Return the pointer to the cache. */
+ *Cache = &database->cache;
+
+ /* Success. */
+ gcmkFOOTER_ARG("*Cache=0x%x", *Cache);
+ return gcvSTATUS_OK;
+
+OnError:
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+#endif
+
+gceSTATUS
+gckKERNEL_DumpProcessDB(
+ IN gckKERNEL Kernel
+ )
+{
+ gcsDATABASE_PTR database;
+ gctINT i, pid;
+ gctUINT8 name[24];
+
+ gcmkHEADER_ARG("Kernel=0x%x", Kernel);
+
+ /* Acquire the database mutex. */
+ gcmkVERIFY_OK(
+ gckOS_AcquireMutex(Kernel->os, Kernel->db->dbMutex, gcvINFINITE));
+
+ gcmkPRINT("**************************\n");
+ gcmkPRINT("*** PROCESS DB DUMP ***\n");
+ gcmkPRINT("**************************\n");
+
+ gcmkPRINT_N(8, "%-8s%s\n", "PID", "NAME");
+ /* Walk the databases. */
+ for (i = 0; i < gcmCOUNTOF(Kernel->db->db); ++i)
+ {
+ for (database = Kernel->db->db[i];
+ database != gcvNULL;
+ database = database->next)
+ {
+ pid = database->processID;
+
+ gcmkVERIFY_OK(gckOS_ZeroMemory(name, gcmSIZEOF(name)));
+
+ gcmkVERIFY_OK(gckOS_GetProcessNameByPid(pid, gcmSIZEOF(name), name));
+
+ gcmkPRINT_N(8, "%-8d%s\n", pid, name);
+ }
+ }
+
+ /* Release the database mutex. */
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, Kernel->db->dbMutex));
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+}
+
+void
+_DumpCounter(
+ IN gcsDATABASE_COUNTERS * Counter,
+ IN gctCONST_STRING Name
+ )
+{
+ gcmkPRINT("%s:", Name);
+ gcmkPRINT(" Currently allocated : %10lld", Counter->bytes);
+ gcmkPRINT(" Maximum allocated : %10lld", Counter->maxBytes);
+ gcmkPRINT(" Total allocated : %10lld", Counter->totalBytes);
+}
+
+gceSTATUS
+gckKERNEL_DumpVidMemUsage(
+ IN gckKERNEL Kernel,
+ IN gctINT32 ProcessID
+ )
+{
+ gceSTATUS status;
+ gcsDATABASE_PTR database;
+ gcsDATABASE_COUNTERS * counter;
+ gctUINT32 i = 0;
+
+ static gctCONST_STRING surfaceTypes[] = {
+ "UNKNOWN",
+ "INDEX",
+ "VERTEX",
+ "TEXTURE",
+ "RENDER_TARGET",
+ "DEPTH",
+ "BITMAP",
+ "TILE_STATUS",
+ "IMAGE",
+ "MASK",
+ "SCISSOR",
+ "HIERARCHICAL_DEPTH",
+ "ICACHE",
+ "TXDESC",
+ "FENCE",
+ "TFBHEADER",
+ };
+
+ gcmkHEADER_ARG("Kernel=0x%x ProcessID=%d",
+ Kernel, ProcessID);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
+
+ /* Find the database. */
+ gcmkONERROR(
+ gckKERNEL_FindDatabase(Kernel, ProcessID, gcvFALSE, &database));
+
+ gcmkPRINT("VidMem Usage (Process %d):", ProcessID);
+
+ /* Get pointer to counters. */
+ counter = &database->vidMem;
+
+ _DumpCounter(counter, "Total Video Memory");
+
+ for (i = 0; i < gcvSURF_NUM_TYPES; i++)
+ {
+ counter = &database->vidMemType[i];
+
+ _DumpCounter(counter, surfaceTypes[i]);
+ }
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
diff --git a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_debug.c b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_debug.c
new file mode 100644
index 000000000000..78ead5dce551
--- /dev/null
+++ b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_debug.c
@@ -0,0 +1,2871 @@
+/****************************************************************************
+*
+* The MIT License (MIT)
+*
+* Copyright (c) 2014 - 2018 Vivante 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 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 GPL License (GPL)
+*
+* Copyright (C) 2014 - 2018 Vivante 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.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+*****************************************************************************
+*
+* Note: This software is released under dual MIT and GPL licenses. A
+* recipient may use this file under the terms of either the MIT license or
+* GPL License. If you wish to use only one license not the other, you can
+* indicate your decision by deleting one of the above license notices in your
+* version of this file.
+*
+*****************************************************************************/
+
+
+#include "gc_hal_kernel_precomp.h"
+#include <gc_hal_kernel_debug.h>
+
+/******************************************************************************\
+******************************** Debug Variables *******************************
+\******************************************************************************/
+
+static gceSTATUS _lastError = gcvSTATUS_OK;
+static gctUINT32 _debugLevel = gcvLEVEL_ERROR;
+/*
+_debugZones config value
+Please Reference define in gc_hal_base.h
+*/
+static gctUINT32 _debugZones = gcvZONE_NONE;
+
+/******************************************************************************\
+********************************* Debug Switches *******************************
+\******************************************************************************/
+
+/*
+ gcdBUFFERED_OUTPUT
+
+ When set to non-zero, all output is collected into a buffer with the
+ specified size. Once the buffer gets full, the debug buffer will be
+ printed to the console. gcdBUFFERED_SIZE determines the size of the buffer.
+*/
+#define gcdBUFFERED_OUTPUT 0
+
+/*
+ gcdBUFFERED_SIZE
+
+ When set to non-zero, all output is collected into a buffer with the
+ specified size. Once the buffer gets full, the debug buffer will be
+ printed to the console.
+*/
+#define gcdBUFFERED_SIZE (1024 * 1024 * 2)
+
+/*
+ gcdDMA_BUFFER_COUNT
+
+ If greater then zero, the debugger will attempt to find the command buffer
+ where DMA is currently executing and then print this buffer and
+ (gcdDMA_BUFFER_COUNT - 1) buffers before the current one. If set to zero
+ or the current buffer is not found, all buffers are printed.
+*/
+#define gcdDMA_BUFFER_COUNT 0
+
+/*
+ gcdTHREAD_BUFFERS
+
+ When greater then one, will accumulate messages from the specified number
+ of threads in separate output buffers.
+*/
+#define gcdTHREAD_BUFFERS 1
+
+/*
+ gcdENABLE_OVERFLOW
+
+ When set to non-zero, and the output buffer gets full, instead of being
+ printed, it will be allowed to overflow removing the oldest messages.
+*/
+#define gcdENABLE_OVERFLOW 1
+
+/*
+ gcdSHOW_LINE_NUMBER
+
+ When enabledm each print statement will be preceeded with the current
+ line number.
+*/
+#define gcdSHOW_LINE_NUMBER 0
+
+/*
+ gcdSHOW_PROCESS_ID
+
+ When enabledm each print statement will be preceeded with the current
+ process ID.
+*/
+#define gcdSHOW_PROCESS_ID 0
+
+/*
+ gcdSHOW_THREAD_ID
+
+ When enabledm each print statement will be preceeded with the current
+ thread ID.
+*/
+#define gcdSHOW_THREAD_ID 0
+
+/*
+ gcdSHOW_TIME
+
+ When enabled each print statement will be preceeded with the current
+ high-resolution time.
+*/
+#define gcdSHOW_TIME 0
+
+
+/******************************************************************************\
+****************************** Miscellaneous Macros ****************************
+\******************************************************************************/
+
+#if gcmIS_DEBUG(gcdDEBUG_TRACE)
+# define gcmDBGASSERT(Expression, Format, Value) \
+ if (!(Expression)) \
+ { \
+ _DirectPrint( \
+ "*** gcmDBGASSERT ***************************\n" \
+ " function : %s\n" \
+ " line : %d\n" \
+ " expression : " #Expression "\n" \
+ " actual value : " Format "\n", \
+ __FUNCTION__, __LINE__, Value \
+ ); \
+ }
+#else
+# define gcmDBGASSERT(Expression, Format, Value)
+#endif
+
+#define gcmPTRALIGNMENT(Pointer, Alignemnt) \
+( \
+ gcmALIGN(gcmPTR2INT32(Pointer), Alignemnt) - gcmPTR2INT32(Pointer) \
+)
+
+#if gcdALIGNBYSIZE
+# define gcmISALIGNED(Offset, Alignment) \
+ (((Offset) & ((Alignment) - 1)) == 0)
+
+# define gcmkALIGNPTR(Type, Pointer, Alignment) \
+ Pointer = (Type) gcmINT2PTR(gcmALIGN(gcmPTR2INT32(Pointer), Alignment))
+#else
+# define gcmISALIGNED(Offset, Alignment) \
+ gcvTRUE
+
+# define gcmkALIGNPTR(Type, Pointer, Alignment)
+#endif
+
+#define gcmALIGNSIZE(Offset, Size) \
+ ((Size - Offset) + Size)
+
+#define gcdHAVEPREFIX \
+( \
+ gcdSHOW_TIME \
+ || gcdSHOW_LINE_NUMBER \
+ || gcdSHOW_PROCESS_ID \
+ || gcdSHOW_THREAD_ID \
+)
+
+#if gcdHAVEPREFIX
+
+# define gcdOFFSET 0
+
+#if gcdSHOW_TIME
+#if gcmISALIGNED(gcdOFFSET, 8)
+# define gcdTIMESIZE gcmSIZEOF(gctUINT64)
+# elif gcdOFFSET == 4
+# define gcdTIMESIZE gcmALIGNSIZE(4, gcmSIZEOF(gctUINT64))
+# else
+# error "Unexpected offset value."
+# endif
+# undef gcdOFFSET
+# define gcdOFFSET 8
+#if !defined(gcdPREFIX_LEADER)
+# define gcdPREFIX_LEADER gcmSIZEOF(gctUINT64)
+# define gcdTIMEFORMAT "0x%016llX"
+# else
+# define gcdTIMEFORMAT ", 0x%016llX"
+# endif
+# else
+# define gcdTIMESIZE 0
+# define gcdTIMEFORMAT
+# endif
+
+#if gcdSHOW_LINE_NUMBER
+#if gcmISALIGNED(gcdOFFSET, 8)
+# define gcdNUMSIZE gcmSIZEOF(gctUINT64)
+# elif gcdOFFSET == 4
+# define gcdNUMSIZE gcmALIGNSIZE(4, gcmSIZEOF(gctUINT64))
+# else
+# error "Unexpected offset value."
+# endif
+# undef gcdOFFSET
+# define gcdOFFSET 8
+#if !defined(gcdPREFIX_LEADER)
+# define gcdPREFIX_LEADER gcmSIZEOF(gctUINT64)
+# define gcdNUMFORMAT "%8llu"
+# else
+# define gcdNUMFORMAT ", %8llu"
+# endif
+# else
+# define gcdNUMSIZE 0
+# define gcdNUMFORMAT
+# endif
+
+#if gcdSHOW_PROCESS_ID
+#if gcmISALIGNED(gcdOFFSET, 4)
+# define gcdPIDSIZE gcmSIZEOF(gctUINT32)
+# else
+# error "Unexpected offset value."
+# endif
+# undef gcdOFFSET
+# define gcdOFFSET 4
+#if !defined(gcdPREFIX_LEADER)
+# define gcdPREFIX_LEADER gcmSIZEOF(gctUINT32)
+# define gcdPIDFORMAT "pid=%5d"
+# else
+# define gcdPIDFORMAT ", pid=%5d"
+# endif
+# else
+# define gcdPIDSIZE 0
+# define gcdPIDFORMAT
+# endif
+
+#if gcdSHOW_THREAD_ID
+#if gcmISALIGNED(gcdOFFSET, 4)
+# define gcdTIDSIZE gcmSIZEOF(gctUINT32)
+# else
+# error "Unexpected offset value."
+# endif
+# undef gcdOFFSET
+# define gcdOFFSET 4
+#if !defined(gcdPREFIX_LEADER)
+# define gcdPREFIX_LEADER gcmSIZEOF(gctUINT32)
+# define gcdTIDFORMAT "tid=%5d"
+# else
+# define gcdTIDFORMAT ", tid=%5d"
+# endif
+# else
+# define gcdTIDSIZE 0
+# define gcdTIDFORMAT
+# endif
+
+# define gcdPREFIX_SIZE \
+ ( \
+ gcdTIMESIZE \
+ + gcdNUMSIZE \
+ + gcdPIDSIZE \
+ + gcdTIDSIZE \
+ )
+
+ static const char * _prefixFormat =
+ "["
+ gcdTIMEFORMAT
+ gcdNUMFORMAT
+ gcdPIDFORMAT
+ gcdTIDFORMAT
+ "] ";
+
+#else
+
+# define gcdPREFIX_LEADER gcmSIZEOF(gctUINT32)
+# define gcdPREFIX_SIZE 0
+
+#endif
+
+/* Assumed largest variable argument leader size. */
+#define gcdVARARG_LEADER gcmSIZEOF(gctUINT64)
+
+/* Alignnments. */
+#if gcdALIGNBYSIZE
+# define gcdPREFIX_ALIGNMENT gcdPREFIX_LEADER
+# define gcdVARARG_ALIGNMENT gcdVARARG_LEADER
+#else
+# define gcdPREFIX_ALIGNMENT 0
+# define gcdVARARG_ALIGNMENT 0
+#endif
+
+#if gcdBUFFERED_OUTPUT
+# define gcdOUTPUTPREFIX _AppendPrefix
+# define gcdOUTPUTSTRING _AppendString
+# define gcdOUTPUTCOPY _AppendCopy
+# define gcdOUTPUTBUFFER _AppendBuffer
+#else
+# define gcdOUTPUTPREFIX _PrintPrefix
+# define gcdOUTPUTSTRING _PrintString
+# define gcdOUTPUTCOPY _PrintString
+# define gcdOUTPUTBUFFER _PrintBuffer
+#endif
+
+/******************************************************************************\
+****************************** Private Structures ******************************
+\******************************************************************************/
+
+typedef enum _gceBUFITEM
+{
+ gceBUFITEM_NONE,
+ gcvBUFITEM_PREFIX,
+ gcvBUFITEM_STRING,
+ gcvBUFITEM_COPY,
+ gcvBUFITEM_BUFFER
+}
+gceBUFITEM;
+
+/* Common item head/buffer terminator. */
+typedef struct _gcsBUFITEM_HEAD * gcsBUFITEM_HEAD_PTR;
+typedef struct _gcsBUFITEM_HEAD
+{
+ gceBUFITEM type;
+}
+gcsBUFITEM_HEAD;
+
+/* String prefix (for ex. [ 1,tid=0x019A]) */
+typedef struct _gcsBUFITEM_PREFIX * gcsBUFITEM_PREFIX_PTR;
+typedef struct _gcsBUFITEM_PREFIX
+{
+ gceBUFITEM type;
+#if gcdHAVEPREFIX
+ gctPOINTER prefixData;
+#endif
+}
+gcsBUFITEM_PREFIX;
+
+/* Buffered string. */
+typedef struct _gcsBUFITEM_STRING * gcsBUFITEM_STRING_PTR;
+typedef struct _gcsBUFITEM_STRING
+{
+ gceBUFITEM type;
+ gctINT indent;
+ gctCONST_STRING message;
+ gctPOINTER messageData;
+ gctUINT messageDataSize;
+}
+gcsBUFITEM_STRING;
+
+/* Buffered string (copy of the string is included with the record). */
+typedef struct _gcsBUFITEM_COPY * gcsBUFITEM_COPY_PTR;
+typedef struct _gcsBUFITEM_COPY
+{
+ gceBUFITEM type;
+ gctINT indent;
+ gctPOINTER messageData;
+ gctUINT messageDataSize;
+}
+gcsBUFITEM_COPY;
+
+/* Memory buffer. */
+typedef struct _gcsBUFITEM_BUFFER * gcsBUFITEM_BUFFER_PTR;
+typedef struct _gcsBUFITEM_BUFFER
+{
+ gceBUFITEM type;
+ gctINT indent;
+ gceDUMP_BUFFER bufferType;
+
+#if gcdDMA_BUFFER_COUNT && (gcdTHREAD_BUFFERS == 1)
+ gctUINT32 dmaAddress;
+#endif
+
+ gctUINT dataSize;
+ gctUINT32 address;
+#if gcdHAVEPREFIX
+ gctPOINTER prefixData;
+#endif
+}
+gcsBUFITEM_BUFFER;
+
+typedef struct _gcsBUFFERED_OUTPUT * gcsBUFFERED_OUTPUT_PTR;
+typedef struct _gcsBUFFERED_OUTPUT
+{
+#if gcdTHREAD_BUFFERS > 1
+ gctUINT32 threadID;
+#endif
+
+#if gcdSHOW_LINE_NUMBER
+ gctUINT64 lineNumber;
+#endif
+
+ gctINT indent;
+
+#if gcdBUFFERED_OUTPUT
+ gctINT start;
+ gctINT index;
+ gctINT count;
+ gctUINT8 buffer[gcdBUFFERED_SIZE];
+#endif
+
+ gcsBUFFERED_OUTPUT_PTR prev;
+ gcsBUFFERED_OUTPUT_PTR next;
+}
+gcsBUFFERED_OUTPUT;
+
+typedef gctUINT (* gcfPRINTSTRING) (
+ IN gcsBUFFERED_OUTPUT_PTR OutputBuffer,
+ IN gcsBUFITEM_HEAD_PTR Item
+ );
+
+typedef gctINT (* gcfGETITEMSIZE) (
+ IN gcsBUFITEM_HEAD_PTR Item
+ );
+
+/******************************************************************************\
+******************************* Private Variables ******************************
+\******************************************************************************/
+
+static gcsBUFFERED_OUTPUT _outputBuffer[gcdTHREAD_BUFFERS];
+static gcsBUFFERED_OUTPUT_PTR _outputBufferHead = gcvNULL;
+static gcsBUFFERED_OUTPUT_PTR _outputBufferTail = gcvNULL;
+
+/******************************************************************************\
+****************************** Item Size Functions *****************************
+\******************************************************************************/
+
+#if gcdBUFFERED_OUTPUT
+static gctINT
+_GetTerminatorItemSize(
+ IN gcsBUFITEM_HEAD_PTR Item
+ )
+{
+ return gcmSIZEOF(gcsBUFITEM_HEAD);
+}
+
+static gctINT
+_GetPrefixItemSize(
+ IN gcsBUFITEM_HEAD_PTR Item
+ )
+{
+#if gcdHAVEPREFIX
+ gcsBUFITEM_PREFIX_PTR item = (gcsBUFITEM_PREFIX_PTR) Item;
+ gctUINT vlen = ((gctUINT8_PTR) item->prefixData) - ((gctUINT8_PTR) item);
+ return vlen + gcdPREFIX_SIZE;
+#else
+ return gcmSIZEOF(gcsBUFITEM_PREFIX);
+#endif
+}
+
+static gctINT
+_GetStringItemSize(
+ IN gcsBUFITEM_HEAD_PTR Item
+ )
+{
+ gcsBUFITEM_STRING_PTR item = (gcsBUFITEM_STRING_PTR) Item;
+ gctUINT vlen = ((gctUINT8_PTR) item->messageData) - ((gctUINT8_PTR) item);
+ return vlen + item->messageDataSize;
+}
+
+static gctINT
+_GetCopyItemSize(
+ IN gcsBUFITEM_HEAD_PTR Item
+ )
+{
+ gcsBUFITEM_COPY_PTR item = (gcsBUFITEM_COPY_PTR) Item;
+ gctUINT vlen = ((gctUINT8_PTR) item->messageData) - ((gctUINT8_PTR) item);
+ return vlen + item->messageDataSize;
+}
+
+static gctINT
+_GetBufferItemSize(
+ IN gcsBUFITEM_HEAD_PTR Item
+ )
+{
+#if gcdHAVEPREFIX
+ gcsBUFITEM_BUFFER_PTR item = (gcsBUFITEM_BUFFER_PTR) Item;
+ gctUINT vlen = ((gctUINT8_PTR) item->prefixData) - ((gctUINT8_PTR) item);
+ return vlen + gcdPREFIX_SIZE + item->dataSize;
+#else
+ gcsBUFITEM_BUFFER_PTR item = (gcsBUFITEM_BUFFER_PTR) Item;
+ return gcmSIZEOF(gcsBUFITEM_BUFFER) + item->dataSize;
+#endif
+}
+
+static gcfGETITEMSIZE _itemSize[] =
+{
+ _GetTerminatorItemSize,
+ _GetPrefixItemSize,
+ _GetStringItemSize,
+ _GetCopyItemSize,
+ _GetBufferItemSize
+};
+#endif
+
+/******************************************************************************\
+******************************* Printing Functions *****************************
+\******************************************************************************/
+
+#if gcmIS_DEBUG(gcdDEBUG_TRACE) || gcdBUFFERED_OUTPUT
+static void
+_DirectPrint(
+ gctCONST_STRING Message,
+ ...
+ )
+{
+ gctINT len;
+ char buffer[768];
+ gctARGUMENTS arguments;
+
+ gcmkARGUMENTS_START(arguments, Message);
+ len = gcmkVSPRINTF(buffer, gcmSIZEOF(buffer), Message, &arguments);
+ gcmkARGUMENTS_END(arguments);
+
+ buffer[len] = '\0';
+ gcmkOUTPUT_STRING(buffer);
+}
+#endif
+
+static int
+_AppendIndent(
+ IN gctINT Indent,
+ IN char * Buffer,
+ IN int BufferSize
+ )
+{
+ gctINT i;
+
+ gctINT len = 0;
+ gctINT indent = Indent % 40;
+
+ for (i = 0; i < indent; i += 1)
+ {
+ Buffer[len++] = ' ';
+ }
+
+ if (indent != Indent)
+ {
+ len += gcmkSPRINTF(
+ Buffer + len, BufferSize - len, " <%d> ", Indent
+ );
+
+ Buffer[len] = '\0';
+ }
+
+ return len;
+}
+
+#if gcdHAVEPREFIX
+static void
+_PrintPrefix(
+ IN gcsBUFFERED_OUTPUT_PTR OutputBuffer,
+ IN gctPOINTER Data
+ )
+{
+ char buffer[768];
+ gctINT len;
+
+ /* Format the string. */
+ len = gcmkVSPRINTF(buffer, gcmSIZEOF(buffer), _prefixFormat, Data);
+ buffer[len] = '\0';
+
+ /* Print the string. */
+ gcmkOUTPUT_STRING(buffer);
+}
+#endif
+
+static void
+_PrintString(
+ IN gcsBUFFERED_OUTPUT_PTR OutputBuffer,
+ IN gctINT Indent,
+ IN gctCONST_STRING Message,
+ IN gctUINT ArgumentSize,
+ IN gctPOINTER Data
+ )
+{
+ char buffer[768];
+ gctINT len;
+
+ /* Append the indent string. */
+ len = _AppendIndent(Indent, buffer, gcmSIZEOF(buffer));
+
+ /* Format the string. */
+ len += gcmkVSPRINTF(buffer + len, gcmSIZEOF(buffer) - len, Message, Data);
+ buffer[len] = '\0';
+
+ /* Add end-of-line if missing. */
+ if (buffer[len - 1] != '\n')
+ {
+ buffer[len++] = '\n';
+ buffer[len] = '\0';
+ }
+
+ /* Print the string. */
+ gcmkOUTPUT_STRING(buffer);
+}
+
+static void
+_PrintBuffer(
+ IN gcsBUFFERED_OUTPUT_PTR OutputBuffer,
+ IN gctINT Indent,
+ IN gctPOINTER PrefixData,
+ IN gctPOINTER Data,
+ IN gctUINT Address,
+ IN gctSIZE_T DataSize,
+ IN gceDUMP_BUFFER Type,
+ IN gctUINT32 DmaAddress
+ )
+{
+ static gctCONST_STRING _titleString[] =
+ {
+ "CONTEXT BUFFER",
+ "USER COMMAND BUFFER",
+ "KERNEL COMMAND BUFFER",
+ "LINK BUFFER",
+ "WAIT LINK BUFFER",
+ ""
+ };
+
+ static const gctINT COLUMN_COUNT = 8;
+
+ gctUINT i, column, address;
+ gctSIZE_T count;
+ gctUINT32_PTR data;
+ gctCHAR buffer[768];
+ gctUINT indent, len;
+ gctBOOL command;
+
+ /* Append space for the prefix. */
+#if gcdHAVEPREFIX
+ indent = gcmkVSPRINTF(buffer, gcmSIZEOF(buffer), _prefixFormat, PrefixData);
+ buffer[indent] = '\0';
+#else
+ indent = 0;
+#endif
+
+ /* Append the indent string. */
+ indent += _AppendIndent(
+ Indent, buffer + indent, gcmSIZEOF(buffer) - indent
+ );
+
+ switch (Type)
+ {
+ case gcvDUMP_BUFFER_CONTEXT:
+ case gcvDUMP_BUFFER_USER:
+ case gcvDUMP_BUFFER_KERNEL:
+ case gcvDUMP_BUFFER_LINK:
+ case gcvDUMP_BUFFER_WAITLINK:
+ /* Form and print the title string. */
+ gcmkSPRINTF2(
+ buffer + indent, gcmSIZEOF(buffer) - indent,
+ "%s%s\n", _titleString[Type],
+ ((DmaAddress >= Address) && (DmaAddress < Address + DataSize))
+ ? " (CURRENT)" : ""
+ );
+
+ gcmkOUTPUT_STRING(buffer);
+
+ /* Terminate the string. */
+ buffer[indent] = '\0';
+
+ /* This is a command buffer. */
+ command = gcvTRUE;
+ break;
+
+ case gcvDUMP_BUFFER_FROM_USER:
+ /* This is not a command buffer. */
+ command = gcvFALSE;
+
+ /* No title. */
+ break;
+
+ default:
+ gcmDBGASSERT(gcvFALSE, "%s", "invalid buffer type");
+
+ /* This is not a command buffer. */
+ command = gcvFALSE;
+ }
+
+ /* Overwrite the prefix with spaces. */
+ for (i = 0; i < indent; i += 1)
+ {
+ buffer[i] = ' ';
+ }
+
+ /* Form and print the opening string. */
+ if (command)
+ {
+ gcmkSPRINTF2(
+ buffer + indent, gcmSIZEOF(buffer) - indent,
+ "@[kernel.command %08X %08X\n", Address, (gctUINT32)DataSize
+ );
+
+ gcmkOUTPUT_STRING(buffer);
+
+ /* Terminate the string. */
+ buffer[indent] = '\0';
+ }
+
+ /* Get initial address. */
+ address = Address;
+
+ /* Cast the data pointer. */
+ data = (gctUINT32_PTR) Data;
+
+ /* Compute the number of double words. */
+ count = DataSize / gcmSIZEOF(gctUINT32);
+
+ /* Print the buffer. */
+ for (i = 0, len = indent, column = 0; i < count; i += 1)
+ {
+ /* Append the address. */
+ if (column == 0)
+ {
+ len += gcmkSPRINTF(
+ buffer + len, gcmSIZEOF(buffer) - len, "0x%08X:", address
+ );
+ }
+
+ /* Append the data value. */
+ len += gcmkSPRINTF2(
+ buffer + len, gcmSIZEOF(buffer) - len, "%c%08X",
+ (address == DmaAddress)? '>' : ' ', data[i]
+ );
+
+ buffer[len] = '\0';
+
+ /* Update the address. */
+ address += gcmSIZEOF(gctUINT32);
+
+ /* Advance column count. */
+ column += 1;
+
+ /* End of line? */
+ if ((column % COLUMN_COUNT) == 0)
+ {
+ /* Append EOL. */
+ gcmkSTRCATSAFE(buffer, gcmSIZEOF(buffer), "\n");
+
+ /* Print the string. */
+ gcmkOUTPUT_STRING(buffer);
+
+ /* Reset. */
+ len = indent;
+ column = 0;
+ }
+ }
+
+ /* Print the last partial string. */
+ if (column != 0)
+ {
+ /* Append EOL. */
+ gcmkSTRCATSAFE(buffer, gcmSIZEOF(buffer), "\n");
+
+ /* Print the string. */
+ gcmkOUTPUT_STRING(buffer);
+ }
+
+ /* Form and print the opening string. */
+ if (command)
+ {
+ buffer[indent] = '\0';
+ gcmkSTRCATSAFE(buffer, gcmSIZEOF(buffer), "] -- command\n");
+ gcmkOUTPUT_STRING(buffer);
+ }
+}
+
+#if gcdBUFFERED_OUTPUT
+static gctUINT
+_PrintNone(
+ IN gcsBUFFERED_OUTPUT_PTR OutputBuffer,
+ IN gcsBUFITEM_HEAD_PTR Item
+ )
+{
+ /* Return the size of the node. */
+ return gcmSIZEOF(gcsBUFITEM_HEAD);
+}
+
+static gctUINT
+_PrintPrefixWrapper(
+ IN gcsBUFFERED_OUTPUT_PTR OutputBuffer,
+ IN gcsBUFITEM_HEAD_PTR Item
+ )
+{
+#if gcdHAVEPREFIX
+ gcsBUFITEM_PREFIX_PTR item;
+ gctUINT vlen;
+
+ /* Get access to the data. */
+ item = (gcsBUFITEM_PREFIX_PTR) Item;
+
+ /* Print the message. */
+ _PrintPrefix(OutputBuffer, item->prefixData);
+
+ /* Compute the size of the variable portion of the structure. */
+ vlen = ((gctUINT8_PTR) item->prefixData) - ((gctUINT8_PTR) item);
+
+ /* Return the size of the node. */
+ return vlen + gcdPREFIX_SIZE;
+#else
+ return gcmSIZEOF(gcsBUFITEM_PREFIX);
+#endif
+}
+
+static gctUINT
+_PrintStringWrapper(
+ IN gcsBUFFERED_OUTPUT_PTR OutputBuffer,
+ IN gcsBUFITEM_HEAD_PTR Item
+ )
+{
+ gcsBUFITEM_STRING_PTR item;
+ gctUINT vlen;
+
+ /* Get access to the data. */
+ item = (gcsBUFITEM_STRING_PTR) Item;
+
+ /* Print the message. */
+ _PrintString(
+ OutputBuffer,
+ item->indent, item->message, item->messageDataSize, item->messageData
+ );
+
+ /* Compute the size of the variable portion of the structure. */
+ vlen = ((gctUINT8_PTR) item->messageData) - ((gctUINT8_PTR) item);
+
+ /* Return the size of the node. */
+ return vlen + item->messageDataSize;
+}
+
+static gctUINT
+_PrintCopyWrapper(
+ IN gcsBUFFERED_OUTPUT_PTR OutputBuffer,
+ IN gcsBUFITEM_HEAD_PTR Item
+ )
+{
+ gcsBUFITEM_COPY_PTR item;
+ gctCONST_STRING message;
+ gctUINT vlen;
+
+ /* Get access to the data. */
+ item = (gcsBUFITEM_COPY_PTR) Item;
+
+ /* Determine the string pointer. */
+ message = (gctCONST_STRING) (item + 1);
+
+ /* Print the message. */
+ _PrintString(
+ OutputBuffer,
+ item->indent, message, item->messageDataSize, item->messageData
+ );
+
+ /* Compute the size of the variable portion of the structure. */
+ vlen = ((gctUINT8_PTR) item->messageData) - ((gctUINT8_PTR) item);
+
+ /* Return the size of the node. */
+ return vlen + item->messageDataSize;
+}
+
+static gctUINT
+_PrintBufferWrapper(
+ IN gcsBUFFERED_OUTPUT_PTR OutputBuffer,
+ IN gcsBUFITEM_HEAD_PTR Item
+ )
+{
+#if gcdHAVEPREFIX
+ gctUINT32 dmaAddress;
+ gcsBUFITEM_BUFFER_PTR item;
+ gctPOINTER data;
+ gctUINT vlen;
+
+ /* Get access to the data. */
+ item = (gcsBUFITEM_BUFFER_PTR) Item;
+
+#if gcdDMA_BUFFER_COUNT && (gcdTHREAD_BUFFERS == 1)
+ dmaAddress = item->dmaAddress;
+#else
+ dmaAddress = 0xFFFFFFFF;
+#endif
+
+ if (dmaAddress != 0)
+ {
+ /* Compute the data address. */
+ data = ((gctUINT8_PTR) item->prefixData) + gcdPREFIX_SIZE;
+
+ /* Print buffer. */
+ _PrintBuffer(
+ OutputBuffer,
+ item->indent, item->prefixData,
+ data, item->address, item->dataSize,
+ item->bufferType, dmaAddress
+ );
+ }
+
+ /* Compute the size of the variable portion of the structure. */
+ vlen = ((gctUINT8_PTR) item->prefixData) - ((gctUINT8_PTR) item);
+
+ /* Return the size of the node. */
+ return vlen + gcdPREFIX_SIZE + item->dataSize;
+#else
+ gctUINT32 dmaAddress;
+ gcsBUFITEM_BUFFER_PTR item;
+
+ /* Get access to the data. */
+ item = (gcsBUFITEM_BUFFER_PTR) Item;
+
+#if gcdDMA_BUFFER_COUNT && (gcdTHREAD_BUFFERS == 1)
+ dmaAddress = item->dmaAddress;
+#else
+ dmaAddress = 0xFFFFFFFF;
+#endif
+
+ if (dmaAddress != 0)
+ {
+ /* Print buffer. */
+ _PrintBuffer(
+ OutputBuffer,
+ item->indent, gcvNULL,
+ item + 1, item->address, item->dataSize,
+ item->bufferType, dmaAddress
+ );
+ }
+
+ /* Return the size of the node. */
+ return gcmSIZEOF(gcsBUFITEM_BUFFER) + item->dataSize;
+#endif
+}
+
+static gcfPRINTSTRING _printArray[] =
+{
+ _PrintNone,
+ _PrintPrefixWrapper,
+ _PrintStringWrapper,
+ _PrintCopyWrapper,
+ _PrintBufferWrapper
+};
+#endif
+
+/******************************************************************************\
+******************************* Private Functions ******************************
+\******************************************************************************/
+
+#if gcdBUFFERED_OUTPUT
+
+#if gcdDMA_BUFFER_COUNT && (gcdTHREAD_BUFFERS == 1)
+static gcsBUFITEM_BUFFER_PTR
+_FindCurrentDMABuffer(
+ gctUINT32 DmaAddress
+ )
+{
+ gctINT i, skip;
+ gcsBUFITEM_HEAD_PTR item;
+ gcsBUFITEM_BUFFER_PTR dmaCurrent;
+
+ /* Reset the current buffer. */
+ dmaCurrent = gcvNULL;
+
+ /* Get the first stored item. */
+ item = (gcsBUFITEM_HEAD_PTR) &_outputBufferHead->buffer[_outputBufferHead->start];
+
+ /* Run through all items. */
+ for (i = 0; i < _outputBufferHead->count; i += 1)
+ {
+ /* Buffer item? */
+ if (item->type == gcvBUFITEM_BUFFER)
+ {
+ gcsBUFITEM_BUFFER_PTR buffer = (gcsBUFITEM_BUFFER_PTR) item;
+
+ if ((DmaAddress >= buffer->address) &&
+ (DmaAddress < buffer->address + buffer->dataSize))
+ {
+ dmaCurrent = buffer;
+ }
+ }
+
+ /* Get the item size and skip it. */
+ skip = (* _itemSize[item->type]) (item);
+ item = (gcsBUFITEM_HEAD_PTR) ((gctUINT8_PTR) item + skip);
+
+ /* End of the buffer? Wrap around. */
+ if (item->type == gceBUFITEM_NONE)
+ {
+ item = (gcsBUFITEM_HEAD_PTR) _outputBufferHead->buffer;
+ }
+ }
+
+ /* Return result. */
+ return dmaCurrent;
+}
+
+static void
+_EnableAllDMABuffers(
+ void
+ )
+{
+ gctINT i, skip;
+ gcsBUFITEM_HEAD_PTR item;
+
+ /* Get the first stored item. */
+ item = (gcsBUFITEM_HEAD_PTR) &_outputBufferHead->buffer[_outputBufferHead->start];
+
+ /* Run through all items. */
+ for (i = 0; i < _outputBufferHead->count; i += 1)
+ {
+ /* Buffer item? */
+ if (item->type == gcvBUFITEM_BUFFER)
+ {
+ gcsBUFITEM_BUFFER_PTR buffer = (gcsBUFITEM_BUFFER_PTR) item;
+
+ /* Enable the buffer. */
+ buffer->dmaAddress = ~0U;
+ }
+
+ /* Get the item size and skip it. */
+ skip = (* _itemSize[item->type]) (item);
+ item = (gcsBUFITEM_HEAD_PTR) ((gctUINT8_PTR) item + skip);
+
+ /* End of the buffer? Wrap around. */
+ if (item->type == gceBUFITEM_NONE)
+ {
+ item = (gcsBUFITEM_HEAD_PTR) _outputBufferHead->buffer;
+ }
+ }
+}
+
+static void
+_EnableDMABuffers(
+ gctUINT32 DmaAddress,
+ gcsBUFITEM_BUFFER_PTR CurrentDMABuffer
+ )
+{
+ gctINT i, skip, index;
+ gcsBUFITEM_HEAD_PTR item;
+ gcsBUFITEM_BUFFER_PTR buffers[gcdDMA_BUFFER_COUNT];
+
+ /* Reset buffer pointers. */
+ gckOS_ZeroMemory(buffers, gcmSIZEOF(buffers));
+
+ /* Set the current buffer index. */
+ index = -1;
+
+ /* Get the first stored item. */
+ item = (gcsBUFITEM_HEAD_PTR) &_outputBufferHead->buffer[_outputBufferHead->start];
+
+ /* Run through all items until the current DMA buffer is found. */
+ for (i = 0; i < _outputBufferHead->count; i += 1)
+ {
+ /* Buffer item? */
+ if (item->type == gcvBUFITEM_BUFFER)
+ {
+ /* Advance the index. */
+ index = (index + 1) % gcdDMA_BUFFER_COUNT;
+
+ /* Add to the buffer array. */
+ buffers[index] = (gcsBUFITEM_BUFFER_PTR) item;
+
+ /* Stop if this is the current DMA buffer. */
+ if ((gcsBUFITEM_BUFFER_PTR) item == CurrentDMABuffer)
+ {
+ break;
+ }
+ }
+
+ /* Get the item size and skip it. */
+ skip = (* _itemSize[item->type]) (item);
+ item = (gcsBUFITEM_HEAD_PTR) ((gctUINT8_PTR) item + skip);
+
+ /* End of the buffer? Wrap around. */
+ if (item->type == gceBUFITEM_NONE)
+ {
+ item = (gcsBUFITEM_HEAD_PTR) _outputBufferHead->buffer;
+ }
+ }
+
+ /* Enable the found buffers. */
+ gcmDBGASSERT(index != -1, "%d", index);
+
+ for (i = 0; i < gcdDMA_BUFFER_COUNT; i += 1)
+ {
+ if (buffers[index] == gcvNULL)
+ {
+ break;
+ }
+
+ buffers[index]->dmaAddress = DmaAddress;
+
+ index -= 1;
+
+ if (index == -1)
+ {
+ index = gcdDMA_BUFFER_COUNT - 1;
+ }
+ }
+}
+#endif
+
+static void
+_Flush(
+ gctUINT32 DmaAddress
+ )
+{
+ gctINT i, skip;
+ gcsBUFITEM_HEAD_PTR item;
+
+ gcsBUFFERED_OUTPUT_PTR outputBuffer = _outputBufferHead;
+
+#if gcdDMA_BUFFER_COUNT && (gcdTHREAD_BUFFERS == 1)
+ if ((outputBuffer != gcvNULL) && (outputBuffer->count != 0))
+ {
+ /* Find the current DMA buffer. */
+ gcsBUFITEM_BUFFER_PTR dmaCurrent = _FindCurrentDMABuffer(DmaAddress);
+
+ /* Was the current buffer found? */
+ if (dmaCurrent == gcvNULL)
+ {
+ /* No, print all buffers. */
+ _EnableAllDMABuffers();
+ }
+ else
+ {
+ /* Yes, enable only specified number of buffers. */
+ _EnableDMABuffers(DmaAddress, dmaCurrent);
+ }
+ }
+#endif
+
+ while (outputBuffer != gcvNULL)
+ {
+ if (outputBuffer->count != 0)
+ {
+ _DirectPrint("********************************************************************************\n");
+ _DirectPrint("FLUSHING DEBUG OUTPUT BUFFER (%d elements).\n", outputBuffer->count);
+ _DirectPrint("********************************************************************************\n");
+
+ item = (gcsBUFITEM_HEAD_PTR) &outputBuffer->buffer[outputBuffer->start];
+
+ for (i = 0; i < outputBuffer->count; i += 1)
+ {
+ skip = (* _printArray[item->type]) (outputBuffer, item);
+
+ item = (gcsBUFITEM_HEAD_PTR) ((gctUINT8_PTR) item + skip);
+
+ if (item->type == gceBUFITEM_NONE)
+ {
+ item = (gcsBUFITEM_HEAD_PTR) outputBuffer->buffer;
+ }
+ }
+
+ outputBuffer->start = 0;
+ outputBuffer->index = 0;
+ outputBuffer->count = 0;
+ }
+
+ outputBuffer = outputBuffer->next;
+ }
+}
+
+static gcsBUFITEM_HEAD_PTR
+_AllocateItem(
+ IN gcsBUFFERED_OUTPUT_PTR OutputBuffer,
+ IN gctINT Size
+ )
+{
+ gctINT skip;
+ gcsBUFITEM_HEAD_PTR item, next;
+
+#if gcdENABLE_OVERFLOW
+ if (
+ (OutputBuffer->index + Size >= gcdBUFFERED_SIZE - gcmSIZEOF(gcsBUFITEM_HEAD))
+ ||
+ (
+ (OutputBuffer->index < OutputBuffer->start) &&
+ (OutputBuffer->index + Size >= OutputBuffer->start)
+ )
+ )
+ {
+ if (OutputBuffer->index + Size >= gcdBUFFERED_SIZE - gcmSIZEOF(gcsBUFITEM_HEAD))
+ {
+ if (OutputBuffer->index < OutputBuffer->start)
+ {
+ item = (gcsBUFITEM_HEAD_PTR) &OutputBuffer->buffer[OutputBuffer->start];
+
+ while (item->type != gceBUFITEM_NONE)
+ {
+ skip = (* _itemSize[item->type]) (item);
+
+ OutputBuffer->start += skip;
+ OutputBuffer->count -= 1;
+
+ item->type = gceBUFITEM_NONE;
+ item = (gcsBUFITEM_HEAD_PTR) ((gctUINT8_PTR) item + skip);
+ }
+
+ OutputBuffer->start = 0;
+ }
+
+ OutputBuffer->index = 0;
+ }
+
+ item = (gcsBUFITEM_HEAD_PTR) &OutputBuffer->buffer[OutputBuffer->start];
+
+ while (OutputBuffer->start - OutputBuffer->index <= Size)
+ {
+ skip = (* _itemSize[item->type]) (item);
+
+ OutputBuffer->start += skip;
+ OutputBuffer->count -= 1;
+
+ item->type = gceBUFITEM_NONE;
+ item = (gcsBUFITEM_HEAD_PTR) ((gctUINT8_PTR) item + skip);
+
+ if (item->type == gceBUFITEM_NONE)
+ {
+ OutputBuffer->start = 0;
+ break;
+ }
+ }
+ }
+#else
+ if (OutputBuffer->index + Size > gcdBUFFERED_SIZE - gcmSIZEOF(gcsBUFITEM_HEAD))
+ {
+ _DirectPrint("\nMessage buffer full; forcing message flush.\n\n");
+ _Flush(~0U);
+ }
+#endif
+
+ item = (gcsBUFITEM_HEAD_PTR) &OutputBuffer->buffer[OutputBuffer->index];
+
+ OutputBuffer->index += Size;
+ OutputBuffer->count += 1;
+
+ next = (gcsBUFITEM_HEAD_PTR) ((gctUINT8_PTR) item + Size);
+ next->type = gceBUFITEM_NONE;
+
+ return item;
+}
+
+#if gcdALIGNBYSIZE
+static void
+_FreeExtraSpace(
+ IN gcsBUFFERED_OUTPUT_PTR OutputBuffer,
+ IN gctPOINTER Item,
+ IN gctINT ItemSize,
+ IN gctINT FreeSize
+ )
+{
+ gcsBUFITEM_HEAD_PTR next;
+
+ OutputBuffer->index -= FreeSize;
+
+ next = (gcsBUFITEM_HEAD_PTR) ((gctUINT8_PTR) Item + ItemSize);
+ next->type = gceBUFITEM_NONE;
+}
+#endif
+
+#if gcdHAVEPREFIX
+static void
+_AppendPrefix(
+ IN gcsBUFFERED_OUTPUT_PTR OutputBuffer,
+ IN gctPOINTER Data
+ )
+{
+ gctUINT8_PTR prefixData;
+ gcsBUFITEM_PREFIX_PTR item;
+ gctINT allocSize;
+
+#if gcdALIGNBYSIZE
+ gctUINT alignment;
+ gctINT size, freeSize;
+#endif
+
+ gcmDBGASSERT(Data != gcvNULL, "%p", Data);
+
+ /* Determine the maximum item size. */
+ allocSize
+ = gcmSIZEOF(gcsBUFITEM_PREFIX)
+ + gcdPREFIX_SIZE
+ + gcdPREFIX_ALIGNMENT;
+
+ /* Allocate prefix item. */
+ item = (gcsBUFITEM_PREFIX_PTR) _AllocateItem(OutputBuffer, allocSize);
+
+ /* Compute the initial prefix data pointer. */
+ prefixData = (gctUINT8_PTR) (item + 1);
+
+ /* Align the data pointer as necessary. */
+#if gcdALIGNBYSIZE
+ alignment = gcmPTRALIGNMENT(prefixData, gcdPREFIX_ALIGNMENT);
+ prefixData += alignment;
+#endif
+
+ /* Set item data. */
+ item->type = gcvBUFITEM_PREFIX;
+ item->prefixData = prefixData;
+
+ /* Copy argument value. */
+ gcmkMEMCPY(prefixData, Data, gcdPREFIX_SIZE);
+
+#if gcdALIGNBYSIZE
+ /* Compute the actual node size. */
+ size = gcmSIZEOF(gcsBUFITEM_PREFIX) + gcdPREFIX_SIZE + alignment;
+
+ /* Free extra memory if any. */
+ freeSize = allocSize - size;
+ if (freeSize != 0)
+ {
+ _FreeExtraSpace(OutputBuffer, item, size, freeSize);
+ }
+#endif
+}
+#endif
+
+static void
+_AppendString(
+ IN gcsBUFFERED_OUTPUT_PTR OutputBuffer,
+ IN gctINT Indent,
+ IN gctCONST_STRING Message,
+ IN gctUINT ArgumentSize,
+ IN gctPOINTER Data
+ )
+{
+ gctUINT8_PTR messageData;
+ gcsBUFITEM_STRING_PTR item;
+ gctINT allocSize;
+
+#if gcdALIGNBYSIZE
+ gctUINT alignment;
+ gctINT size, freeSize;
+#endif
+
+ /* Determine the maximum item size. */
+ allocSize
+ = gcmSIZEOF(gcsBUFITEM_STRING)
+ + ArgumentSize
+ + gcdVARARG_ALIGNMENT;
+
+ /* Allocate prefix item. */
+ item = (gcsBUFITEM_STRING_PTR) _AllocateItem(OutputBuffer, allocSize);
+
+ /* Compute the initial message data pointer. */
+ messageData = (gctUINT8_PTR) (item + 1);
+
+ /* Align the data pointer as necessary. */
+#if gcdALIGNBYSIZE
+ alignment = gcmPTRALIGNMENT(messageData, gcdVARARG_ALIGNMENT);
+ messageData += alignment;
+#endif
+
+ /* Set item data. */
+ item->type = gcvBUFITEM_STRING;
+ item->indent = Indent;
+ item->message = Message;
+ item->messageData = messageData;
+ item->messageDataSize = ArgumentSize;
+
+ /* Copy argument value. */
+ if (ArgumentSize != 0)
+ {
+ gcmkMEMCPY(messageData, Data, ArgumentSize);
+ }
+
+#if gcdALIGNBYSIZE
+ /* Compute the actual node size. */
+ size = gcmSIZEOF(gcsBUFITEM_STRING) + ArgumentSize + alignment;
+
+ /* Free extra memory if any. */
+ freeSize = allocSize - size;
+ if (freeSize != 0)
+ {
+ _FreeExtraSpace(OutputBuffer, item, size, freeSize);
+ }
+#endif
+}
+
+static void
+_AppendCopy(
+ IN gcsBUFFERED_OUTPUT_PTR OutputBuffer,
+ IN gctINT Indent,
+ IN gctCONST_STRING Message,
+ IN gctUINT ArgumentSize,
+ IN gctPOINTER Data
+ )
+{
+ gctUINT8_PTR messageData;
+ gcsBUFITEM_COPY_PTR item;
+ gctINT allocSize;
+ gctINT messageLength;
+ gctCONST_STRING message;
+
+#if gcdALIGNBYSIZE
+ gctUINT alignment;
+ gctINT size, freeSize;
+#endif
+
+ /* Get the length of the string. */
+ messageLength = strlen(Message) + 1;
+
+ /* Determine the maximum item size. */
+ allocSize
+ = gcmSIZEOF(gcsBUFITEM_COPY)
+ + messageLength
+ + ArgumentSize
+ + gcdVARARG_ALIGNMENT;
+
+ /* Allocate prefix item. */
+ item = (gcsBUFITEM_COPY_PTR) _AllocateItem(OutputBuffer, allocSize);
+
+ /* Determine the message placement. */
+ message = (gctCONST_STRING) (item + 1);
+
+ /* Compute the initial message data pointer. */
+ messageData = (gctUINT8_PTR) message + messageLength;
+
+ /* Align the data pointer as necessary. */
+#if gcdALIGNBYSIZE
+ if (ArgumentSize == 0)
+ {
+ alignment = 0;
+ }
+ else
+ {
+ alignment = gcmPTRALIGNMENT(messageData, gcdVARARG_ALIGNMENT);
+ messageData += alignment;
+ }
+#endif
+
+ /* Set item data. */
+ item->type = gcvBUFITEM_COPY;
+ item->indent = Indent;
+ item->messageData = messageData;
+ item->messageDataSize = ArgumentSize;
+
+ /* Copy the message. */
+ gcmkMEMCPY((gctPOINTER) message, Message, messageLength);
+
+ /* Copy argument value. */
+ if (ArgumentSize != 0)
+ {
+ gcmkMEMCPY(messageData, Data, ArgumentSize);
+ }
+
+#if gcdALIGNBYSIZE
+ /* Compute the actual node size. */
+ size
+ = gcmSIZEOF(gcsBUFITEM_COPY)
+ + messageLength
+ + ArgumentSize
+ + alignment;
+
+ /* Free extra memory if any. */
+ freeSize = allocSize - size;
+ if (freeSize != 0)
+ {
+ _FreeExtraSpace(OutputBuffer, item, size, freeSize);
+ }
+#endif
+}
+
+static void
+_AppendBuffer(
+ IN gcsBUFFERED_OUTPUT_PTR OutputBuffer,
+ IN gctINT Indent,
+ IN gctPOINTER PrefixData,
+ IN gctPOINTER Data,
+ IN gctUINT Address,
+ IN gctUINT DataSize,
+ IN gceDUMP_BUFFER Type,
+ IN gctUINT32 DmaAddress
+ )
+{
+#if gcdHAVEPREFIX
+ gctUINT8_PTR prefixData;
+ gcsBUFITEM_BUFFER_PTR item;
+ gctINT allocSize;
+ gctPOINTER data;
+
+#if gcdALIGNBYSIZE
+ gctUINT alignment;
+ gctINT size, freeSize;
+#endif
+
+ gcmDBGASSERT(DataSize != 0, "%d", DataSize);
+ gcmDBGASSERT(Data != gcvNULL, "%p", Data);
+
+ /* Determine the maximum item size. */
+ allocSize
+ = gcmSIZEOF(gcsBUFITEM_BUFFER)
+ + gcdPREFIX_SIZE
+ + gcdPREFIX_ALIGNMENT
+ + DataSize;
+
+ /* Allocate prefix item. */
+ item = (gcsBUFITEM_BUFFER_PTR) _AllocateItem(OutputBuffer, allocSize);
+
+ /* Compute the initial prefix data pointer. */
+ prefixData = (gctUINT8_PTR) (item + 1);
+
+#if gcdALIGNBYSIZE
+ /* Align the data pointer as necessary. */
+ alignment = gcmPTRALIGNMENT(prefixData, gcdPREFIX_ALIGNMENT);
+ prefixData += alignment;
+#endif
+
+ /* Set item data. */
+ item->type = gcvBUFITEM_BUFFER;
+ item->indent = Indent;
+ item->bufferType = Type;
+ item->dataSize = DataSize;
+ item->address = Address;
+ item->prefixData = prefixData;
+
+#if gcdDMA_BUFFER_COUNT && (gcdTHREAD_BUFFERS == 1)
+ item->dmaAddress = DmaAddress;
+#endif
+
+ /* Copy prefix data. */
+ gcmkMEMCPY(prefixData, PrefixData, gcdPREFIX_SIZE);
+
+ /* Compute the data pointer. */
+ data = prefixData + gcdPREFIX_SIZE;
+
+ /* Copy argument value. */
+ gcmkMEMCPY(data, Data, DataSize);
+
+#if gcdALIGNBYSIZE
+ /* Compute the actual node size. */
+ size
+ = gcmSIZEOF(gcsBUFITEM_BUFFER)
+ + gcdPREFIX_SIZE
+ + alignment
+ + DataSize;
+
+ /* Free extra memory if any. */
+ freeSize = allocSize - size;
+ if (freeSize != 0)
+ {
+ _FreeExtraSpace(OutputBuffer, item, size, freeSize);
+ }
+#endif
+#else
+ gcsBUFITEM_BUFFER_PTR item;
+ gctINT size;
+
+ gcmDBGASSERT(DataSize != 0, "%d", DataSize);
+ gcmDBGASSERT(Data != gcvNULL, "%p", Data);
+
+ /* Determine the maximum item size. */
+ size = gcmSIZEOF(gcsBUFITEM_BUFFER) + DataSize;
+
+ /* Allocate prefix item. */
+ item = (gcsBUFITEM_BUFFER_PTR) _AllocateItem(OutputBuffer, size);
+
+ /* Set item data. */
+ item->type = gcvBUFITEM_BUFFER;
+ item->indent = Indent;
+ item->dataSize = DataSize;
+ item->address = Address;
+
+ /* Copy argument value. */
+ gcmkMEMCPY(item + 1, Data, DataSize);
+#endif
+}
+#endif
+
+static gcmINLINE void
+_InitBuffers(
+ void
+ )
+{
+ int i;
+
+ if (_outputBufferHead == gcvNULL)
+ {
+ for (i = 0; i < gcdTHREAD_BUFFERS; i += 1)
+ {
+ if (_outputBufferTail == gcvNULL)
+ {
+ _outputBufferHead = &_outputBuffer[i];
+ }
+ else
+ {
+ _outputBufferTail->next = &_outputBuffer[i];
+ }
+
+#if gcdTHREAD_BUFFERS > 1
+ _outputBuffer[i].threadID = ~0U;
+#endif
+
+ _outputBuffer[i].prev = _outputBufferTail;
+ _outputBuffer[i].next = gcvNULL;
+
+ _outputBufferTail = &_outputBuffer[i];
+ }
+ }
+}
+
+static gcmINLINE gcsBUFFERED_OUTPUT_PTR
+_GetOutputBuffer(
+ void
+ )
+{
+ gcsBUFFERED_OUTPUT_PTR outputBuffer;
+
+#if gcdTHREAD_BUFFERS > 1
+ /* Get the current thread ID. */
+ gctUINT32 ThreadID = gcmkGETTHREADID();
+
+ /* Locate the output buffer for the thread. */
+ outputBuffer = _outputBufferHead;
+
+ while (outputBuffer != gcvNULL)
+ {
+ if (outputBuffer->threadID == ThreadID)
+ {
+ break;
+ }
+
+ outputBuffer = outputBuffer->next;
+ }
+
+ /* No matching buffer found? */
+ if (outputBuffer == gcvNULL)
+ {
+ /* Get the tail for the buffer. */
+ outputBuffer = _outputBufferTail;
+
+ /* Move it to the head. */
+ _outputBufferTail = _outputBufferTail->prev;
+ _outputBufferTail->next = gcvNULL;
+
+ outputBuffer->prev = gcvNULL;
+ outputBuffer->next = _outputBufferHead;
+
+ _outputBufferHead->prev = outputBuffer;
+ _outputBufferHead = outputBuffer;
+
+ /* Reset the buffer. */
+ outputBuffer->threadID = ThreadID;
+#if gcdBUFFERED_OUTPUT
+ outputBuffer->start = 0;
+ outputBuffer->index = 0;
+ outputBuffer->count = 0;
+#endif
+#if gcdSHOW_LINE_NUMBER
+ outputBuffer->lineNumber = 0;
+#endif
+ }
+#else
+ outputBuffer = _outputBufferHead;
+#endif
+
+ return outputBuffer;
+}
+
+static gcmINLINE int _GetArgumentSize(
+ IN gctCONST_STRING Message
+ )
+{
+ int i, count;
+
+ gcmDBGASSERT(Message != gcvNULL, "%p", Message);
+
+ for (i = 0, count = 0; Message[i]; i += 1)
+ {
+ if (Message[i] == '%')
+ {
+ count += 1;
+ }
+ }
+
+ return count * gcmSIZEOF(gctUINT32);
+}
+
+#if gcdHAVEPREFIX
+static void
+_InitPrefixData(
+ IN gcsBUFFERED_OUTPUT_PTR OutputBuffer,
+ IN gctPOINTER Data
+ )
+{
+ gctUINT8_PTR data = (gctUINT8_PTR) Data;
+
+#if gcdSHOW_TIME
+ {
+ gctUINT64 time;
+ gckOS_GetProfileTick(&time);
+ gcmkALIGNPTR(gctUINT8_PTR, data, gcmSIZEOF(gctUINT64));
+ * ((gctUINT64_PTR) data) = time;
+ data += gcmSIZEOF(gctUINT64);
+ }
+#endif
+
+#if gcdSHOW_LINE_NUMBER
+ {
+ gcmkALIGNPTR(gctUINT8_PTR, data, gcmSIZEOF(gctUINT64));
+ * ((gctUINT64_PTR) data) = OutputBuffer->lineNumber;
+ data += gcmSIZEOF(gctUINT64);
+ }
+#endif
+
+#if gcdSHOW_PROCESS_ID
+ {
+ gcmkALIGNPTR(gctUINT8_PTR, data, gcmSIZEOF(gctUINT32));
+ * ((gctUINT32_PTR) data) = gcmkGETPROCESSID();
+ data += gcmSIZEOF(gctUINT32);
+ }
+#endif
+
+#if gcdSHOW_THREAD_ID
+ {
+ gcmkALIGNPTR(gctUINT8_PTR, data, gcmSIZEOF(gctUINT32));
+ * ((gctUINT32_PTR) data) = gcmkGETTHREADID();
+ }
+#endif
+}
+#endif
+
+static void
+_Print(
+ IN gctUINT ArgumentSize,
+ IN gctBOOL CopyMessage,
+ IN gctCONST_STRING Message,
+ IN gctARGUMENTS * Arguments
+ )
+{
+ gcsBUFFERED_OUTPUT_PTR outputBuffer;
+ static gcmkDECLARE_MUTEX(lockHandle);
+
+ gcmkMUTEX_LOCK(lockHandle);
+
+ /* Initialize output buffer list. */
+ _InitBuffers();
+
+ /* Locate the proper output buffer. */
+ outputBuffer = _GetOutputBuffer();
+
+ /* Update the line number. */
+#if gcdSHOW_LINE_NUMBER
+ outputBuffer->lineNumber += 1;
+#endif
+
+ /* Print prefix. */
+#if gcdHAVEPREFIX
+ {
+ gctUINT8_PTR alignedPrefixData;
+ gctUINT8 prefixData[gcdPREFIX_SIZE + gcdPREFIX_ALIGNMENT];
+
+ /* Compute aligned pointer. */
+ alignedPrefixData = prefixData;
+ gcmkALIGNPTR(gctUINT8_PTR, alignedPrefixData, gcdPREFIX_ALIGNMENT);
+
+ /* Initialize the prefix data. */
+ _InitPrefixData(outputBuffer, alignedPrefixData);
+
+ /* Print the prefix. */
+ gcdOUTPUTPREFIX(outputBuffer, alignedPrefixData);
+ }
+#endif
+
+ /* Form the indent string. */
+ if (strncmp(Message, "--", 2) == 0)
+ {
+ outputBuffer->indent -= 2;
+ }
+
+ /* Print the message. */
+ if (CopyMessage)
+ {
+ gcdOUTPUTCOPY(
+ outputBuffer, outputBuffer->indent,
+ Message, ArgumentSize, (gctPOINTER) Arguments
+ );
+ }
+ else
+ {
+ gcdOUTPUTSTRING(
+ outputBuffer, outputBuffer->indent,
+ Message, ArgumentSize, ((gctPOINTER) Arguments)
+ );
+ }
+
+ /* Check increasing indent. */
+ if (strncmp(Message, "++", 2) == 0)
+ {
+ outputBuffer->indent += 2;
+ }
+
+ gcmkMUTEX_UNLOCK(lockHandle);
+}
+
+
+/******************************************************************************\
+********************************* Debug Macros *********************************
+\******************************************************************************/
+
+#ifdef __QNXNTO__
+
+extern volatile unsigned g_nQnxInIsrs;
+
+#define gcmDEBUGPRINT(ArgumentSize, CopyMessage, Message) \
+{ \
+ if (atomic_add_value(&g_nQnxInIsrs, 1) == 0) \
+ { \
+ gctARGUMENTS __arguments__; \
+ gcmkARGUMENTS_START(__arguments__, Message); \
+ _Print(ArgumentSize, CopyMessage, Message, &__arguments__); \
+ gcmkARGUMENTS_END(__arguments__); \
+ } \
+ atomic_sub(&g_nQnxInIsrs, 1); \
+}
+
+#elif defined(__VXWORKS__)
+#define gcmDEBUGPRINT(ArgumentSize, CopyMessage, Message) \
+{ \
+ printf(Message); \
+}
+
+#else
+#define gcmDEBUGPRINT(ArgumentSize, CopyMessage, Message) \
+{ \
+ gctARGUMENTS __arguments__; \
+ gcmkARGUMENTS_START(__arguments__, Message); \
+ _Print(ArgumentSize, CopyMessage, Message, &__arguments__); \
+ gcmkARGUMENTS_END(__arguments__); \
+}
+
+#endif
+
+/******************************************************************************\
+********************************** Debug Code **********************************
+\******************************************************************************/
+
+/*******************************************************************************
+**
+** gckOS_Print
+**
+** Send a message to the debugger.
+**
+** INPUT:
+**
+** gctCONST_STRING Message
+** Pointer to message.
+**
+** ...
+** Optional arguments.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+
+void
+gckOS_Print(
+ IN gctCONST_STRING Message,
+ ...
+ )
+{
+ gcmDEBUGPRINT(_GetArgumentSize(Message), gcvFALSE, Message);
+}
+
+/*******************************************************************************
+**
+** gckOS_PrintN
+**
+** Send a message to the debugger.
+**
+** INPUT:
+**
+** gctUINT ArgumentSize
+** The size of the optional arguments in bytes.
+**
+** gctCONST_STRING Message
+** Pointer to message.
+**
+** ...
+** Optional arguments.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+
+void
+gckOS_PrintN(
+ IN gctUINT ArgumentSize,
+ IN gctCONST_STRING Message,
+ ...
+ )
+{
+ gcmDEBUGPRINT(ArgumentSize, gcvFALSE, Message);
+}
+
+/*******************************************************************************
+**
+** gckOS_CopyPrint
+**
+** Send a message to the debugger. If in buffered output mode, the entire
+** message will be copied into the buffer instead of using the pointer to
+** the string.
+**
+** INPUT:
+**
+** gctCONST_STRING Message
+** Pointer to message.
+**
+** ...
+** Optional arguments.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+
+void
+gckOS_CopyPrint(
+ IN gctCONST_STRING Message,
+ ...
+ )
+{
+ gcmDEBUGPRINT(_GetArgumentSize(Message), gcvTRUE, Message);
+}
+
+/*******************************************************************************
+**
+** gckOS_DumpBuffer
+**
+** Print the contents of the specified buffer.
+**
+** INPUT:
+**
+** gckOS Os
+** Pointer to gckOS object.
+**
+** gctPOINTER Buffer
+** Pointer to the buffer to print.
+**
+** gctUINT Size
+** Size of the buffer.
+**
+** gceDUMP_BUFFER Type
+** Buffer type.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+
+void
+gckOS_DumpBuffer(
+ IN gckOS Os,
+ IN gctPOINTER Buffer,
+ IN gctSIZE_T Size,
+ IN gceDUMP_BUFFER Type,
+ IN gctBOOL CopyMessage
+ )
+{
+ gctPHYS_ADDR_T physical;
+ gctUINT32 address = 0;
+ gcsBUFFERED_OUTPUT_PTR outputBuffer = gcvNULL;
+ gctCHAR *buffer = (gctCHAR*)Buffer;
+ gctPOINTER pAllocated = gcvNULL;
+ gctPOINTER pMapped = gcvNULL;
+ gceSTATUS status = gcvSTATUS_OK;
+
+ static gcmkDECLARE_MUTEX(lockHandle);
+
+ gcmkMUTEX_LOCK(lockHandle);
+
+ /* Request lock when not coming from user,
+ or coming from user and not yet locked
+ and message is starting with @[. */
+ if (Type == gcvDUMP_BUFFER_FROM_USER)
+ {
+ /* Some format check. */
+ if ((Size > 2)
+ && (buffer[0] == '@' || buffer[0] == '#')
+ && (buffer[1] != '[')
+ )
+ {
+ gcmkMUTEX_UNLOCK(lockHandle);
+
+ /* No error tolerence in parser, so we stop on error to make noise. */
+ for (;;)
+ {
+ gcmkPRINT(
+ "[galcore]: %s(%d): Illegal dump message %s\n",
+ __FUNCTION__, __LINE__,
+ buffer
+ );
+
+ gckOS_Delay(Os, 10 * 1000);
+ }
+ }
+ }
+
+ if (Buffer != gcvNULL)
+ {
+ /* Initialize output buffer list. */
+ _InitBuffers();
+
+ /* Locate the proper output buffer. */
+ outputBuffer = _GetOutputBuffer();
+
+ /* Update the line number. */
+#if gcdSHOW_LINE_NUMBER
+ outputBuffer->lineNumber += 1;
+#endif
+
+ /* Get the physical address of the buffer. */
+ if (Type != gcvDUMP_BUFFER_FROM_USER)
+ {
+ gcmkVERIFY_OK(gckOS_GetPhysicalAddress(Os, Buffer, &physical));
+ gcmkVERIFY_OK(gckOS_CPUPhysicalToGPUPhysical(Os, physical, &physical));
+ gcmkSAFECASTPHYSADDRT(address, physical);
+ }
+ else
+ {
+ address = 0;
+ }
+
+ if (Type == gcvDUMP_BUFFER_USER)
+ {
+ gctBOOL needCopy = gcvTRUE;
+
+ gcmkONERROR(gckOS_QueryNeedCopy(Os, 0, &needCopy));
+
+ if (needCopy)
+ {
+ gcmkONERROR(gckOS_Allocate(
+ Os,
+ Size,
+ &pAllocated
+ ));
+
+ gcmkONERROR(gckOS_CopyFromUserData(
+ Os,
+ pAllocated,
+ Buffer,
+ Size
+ ));
+
+ Buffer = pAllocated;
+ }
+ else
+ {
+ gcmkONERROR(gckOS_MapUserPointer(
+ Os,
+ Buffer,
+ Size,
+ &pMapped
+ ));
+
+ Buffer = pMapped;
+ }
+ }
+
+#if gcdHAVEPREFIX
+ {
+ gctUINT8_PTR alignedPrefixData;
+ gctUINT8 prefixData[gcdPREFIX_SIZE + gcdPREFIX_ALIGNMENT];
+
+ /* Compute aligned pointer. */
+ alignedPrefixData = prefixData;
+ gcmkALIGNPTR(gctUINT8_PTR, alignedPrefixData, gcdPREFIX_ALIGNMENT);
+
+ /* Initialize the prefix data. */
+ _InitPrefixData(outputBuffer, alignedPrefixData);
+
+ /* Print/schedule the buffer. */
+ gcdOUTPUTBUFFER(
+ outputBuffer, outputBuffer->indent,
+ alignedPrefixData, Buffer, address, Size, Type, 0
+ );
+ }
+#else
+ /* Print/schedule the buffer. */
+ if (Type == gcvDUMP_BUFFER_FROM_USER)
+ {
+ gckOS_CopyPrint(Buffer);
+ }
+ else
+ {
+ gcdOUTPUTBUFFER(
+ outputBuffer, outputBuffer->indent,
+ gcvNULL, Buffer, address, Size, Type, 0
+ );
+ }
+#endif
+ }
+
+OnError:
+ gcmkMUTEX_UNLOCK(lockHandle);
+
+ if (pAllocated)
+ {
+ gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Os, pAllocated));
+ }
+ else if (pMapped)
+ {
+ gckOS_UnmapUserPointer(Os, buffer, Size, pMapped);
+ }
+}
+
+/*******************************************************************************
+**
+** gckOS_DebugTrace
+**
+** Send a leveled message to the debugger.
+**
+** INPUT:
+**
+** gctUINT32 Level
+** Debug level of message.
+**
+** gctCONST_STRING Message
+** Pointer to message.
+**
+** ...
+** Optional arguments.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+
+void
+gckOS_DebugTrace(
+ IN gctUINT32 Level,
+ IN gctCONST_STRING Message,
+ ...
+ )
+{
+ if (Level > _debugLevel)
+ {
+ return;
+ }
+
+ gcmDEBUGPRINT(_GetArgumentSize(Message), gcvFALSE, Message);
+}
+
+/*******************************************************************************
+**
+** gckOS_DebugTraceN
+**
+** Send a leveled message to the debugger.
+**
+** INPUT:
+**
+** gctUINT32 Level
+** Debug level of message.
+**
+** gctUINT ArgumentSize
+** The size of the optional arguments in bytes.
+**
+** gctCONST_STRING Message
+** Pointer to message.
+**
+** ...
+** Optional arguments.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+
+void
+gckOS_DebugTraceN(
+ IN gctUINT32 Level,
+ IN gctUINT ArgumentSize,
+ IN gctCONST_STRING Message,
+ ...
+ )
+{
+ if (Level > _debugLevel)
+ {
+ return;
+ }
+
+ gcmDEBUGPRINT(ArgumentSize, gcvFALSE, Message);
+}
+
+/*******************************************************************************
+**
+** gckOS_DebugTraceZone
+**
+** Send a leveled and zoned message to the debugger.
+**
+** INPUT:
+**
+** gctUINT32 Level
+** Debug level for message.
+**
+** gctUINT32 Zone
+** Debug zone for message.
+**
+** gctCONST_STRING Message
+** Pointer to message.
+**
+** ...
+** Optional arguments.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+
+void
+gckOS_DebugTraceZone(
+ IN gctUINT32 Level,
+ IN gctUINT32 Zone,
+ IN gctCONST_STRING Message,
+ ...
+ )
+{
+ if ((Level > _debugLevel) || !(Zone & _debugZones))
+ {
+ return;
+ }
+
+ gcmDEBUGPRINT(_GetArgumentSize(Message), gcvFALSE, Message);
+}
+
+/*******************************************************************************
+**
+** gckOS_DebugTraceZoneN
+**
+** Send a leveled and zoned message to the debugger.
+**
+** INPUT:
+**
+** gctUINT32 Level
+** Debug level for message.
+**
+** gctUINT32 Zone
+** Debug zone for message.
+**
+** gctUINT ArgumentSize
+** The size of the optional arguments in bytes.
+**
+** gctCONST_STRING Message
+** Pointer to message.
+**
+** ...
+** Optional arguments.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+
+void
+gckOS_DebugTraceZoneN(
+ IN gctUINT32 Level,
+ IN gctUINT32 Zone,
+ IN gctUINT ArgumentSize,
+ IN gctCONST_STRING Message,
+ ...
+ )
+{
+ if ((Level > _debugLevel) || !(Zone & _debugZones))
+ {
+ return;
+ }
+
+ gcmDEBUGPRINT(ArgumentSize, gcvFALSE, Message);
+}
+
+/*******************************************************************************
+**
+** gckOS_DebugBreak
+**
+** Break into the debugger.
+**
+** INPUT:
+**
+** Nothing.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+void
+gckOS_DebugBreak(
+ void
+ )
+{
+ gckOS_DebugTrace(gcvLEVEL_ERROR, "%s(%d)", __FUNCTION__, __LINE__);
+}
+
+/*******************************************************************************
+**
+** gckOS_DebugFatal
+**
+** Send a message to the debugger and break into the debugger.
+**
+** INPUT:
+**
+** gctCONST_STRING Message
+** Pointer to message.
+**
+** ...
+** Optional arguments.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+void
+gckOS_DebugFatal(
+ IN gctCONST_STRING Message,
+ ...
+ )
+{
+ gcmkPRINT_VERSION();
+ gcmDEBUGPRINT(_GetArgumentSize(Message), gcvFALSE, Message);
+
+ /* Break into the debugger. */
+ gckOS_DebugBreak();
+}
+
+/*******************************************************************************
+**
+** gckOS_SetDebugLevel
+**
+** Set the debug level.
+**
+** INPUT:
+**
+** gctUINT32 Level
+** New debug level.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+
+void
+gckOS_SetDebugLevel(
+ IN gctUINT32 Level
+ )
+{
+ _debugLevel = Level;
+}
+
+/*******************************************************************************
+**
+** gckOS_SetDebugZone
+**
+** Set the debug zone.
+**
+** INPUT:
+**
+** gctUINT32 Zone
+** New debug zone.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+void
+gckOS_SetDebugZone(
+ IN gctUINT32 Zone
+ )
+{
+ _debugZones = Zone;
+}
+
+/*******************************************************************************
+**
+** gckOS_SetDebugLevelZone
+**
+** Set the debug level and zone.
+**
+** INPUT:
+**
+** gctUINT32 Level
+** New debug level.
+**
+** gctUINT32 Zone
+** New debug zone.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+
+void
+gckOS_SetDebugLevelZone(
+ IN gctUINT32 Level,
+ IN gctUINT32 Zone
+ )
+{
+ _debugLevel = Level;
+ _debugZones = Zone;
+}
+
+/*******************************************************************************
+**
+** gckOS_SetDebugZones
+**
+** Enable or disable debug zones.
+**
+** INPUT:
+**
+** gctUINT32 Zones
+** Debug zones to enable or disable.
+**
+** gctBOOL Enable
+** Set to gcvTRUE to enable the zones (or the Zones with the current
+** zones) or gcvFALSE to disable the specified Zones.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+
+void
+gckOS_SetDebugZones(
+ IN gctUINT32 Zones,
+ IN gctBOOL Enable
+ )
+{
+ if (Enable)
+ {
+ /* Enable the zones. */
+ _debugZones |= Zones;
+ }
+ else
+ {
+ /* Disable the zones. */
+ _debugZones &= ~Zones;
+ }
+}
+
+/*******************************************************************************
+**
+** gckOS_Verify
+**
+** Called to verify the result of a function call.
+**
+** INPUT:
+**
+** gceSTATUS Status
+** Function call result.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+
+void
+gckOS_Verify(
+ IN gceSTATUS status
+ )
+{
+ _lastError = status;
+}
+
+/*******************************************************************************
+**
+** gckOS_DebugFlush
+**
+** Force messages to be flushed out.
+**
+** INPUT:
+**
+** gctCONST_STRING CallerName
+** Name of the caller function.
+**
+** gctUINT LineNumber
+** Line number of the caller.
+**
+** gctUINT32 DmaAddress
+** The current DMA address or ~0U to ignore.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+
+void
+gckOS_DebugFlush(
+ gctCONST_STRING CallerName,
+ gctUINT LineNumber,
+ gctUINT32 DmaAddress
+ )
+{
+#if gcdBUFFERED_OUTPUT
+ _DirectPrint("\nFlush requested by %s(%d).\n\n", CallerName, LineNumber);
+ _Flush(DmaAddress);
+#endif
+}
+gctCONST_STRING
+gckOS_DebugStatus2Name(
+ gceSTATUS status
+ )
+{
+ switch (status)
+ {
+ case gcvSTATUS_OK:
+ return "gcvSTATUS_OK";
+ case gcvSTATUS_TRUE:
+ return "gcvSTATUS_TRUE";
+ case gcvSTATUS_NO_MORE_DATA:
+ return "gcvSTATUS_NO_MORE_DATA";
+ case gcvSTATUS_CACHED:
+ return "gcvSTATUS_CACHED";
+ case gcvSTATUS_MIPMAP_TOO_LARGE:
+ return "gcvSTATUS_MIPMAP_TOO_LARGE";
+ case gcvSTATUS_NAME_NOT_FOUND:
+ return "gcvSTATUS_NAME_NOT_FOUND";
+ case gcvSTATUS_NOT_OUR_INTERRUPT:
+ return "gcvSTATUS_NOT_OUR_INTERRUPT";
+ case gcvSTATUS_MISMATCH:
+ return "gcvSTATUS_MISMATCH";
+ case gcvSTATUS_MIPMAP_TOO_SMALL:
+ return "gcvSTATUS_MIPMAP_TOO_SMALL";
+ case gcvSTATUS_LARGER:
+ return "gcvSTATUS_LARGER";
+ case gcvSTATUS_SMALLER:
+ return "gcvSTATUS_SMALLER";
+ case gcvSTATUS_CHIP_NOT_READY:
+ return "gcvSTATUS_CHIP_NOT_READY";
+ case gcvSTATUS_NEED_CONVERSION:
+ return "gcvSTATUS_NEED_CONVERSION";
+ case gcvSTATUS_SKIP:
+ return "gcvSTATUS_SKIP";
+ case gcvSTATUS_DATA_TOO_LARGE:
+ return "gcvSTATUS_DATA_TOO_LARGE";
+ case gcvSTATUS_INVALID_CONFIG:
+ return "gcvSTATUS_INVALID_CONFIG";
+ case gcvSTATUS_CHANGED:
+ return "gcvSTATUS_CHANGED";
+ case gcvSTATUS_NOT_SUPPORT_DITHER:
+ return "gcvSTATUS_NOT_SUPPORT_DITHER";
+
+ case gcvSTATUS_INVALID_ARGUMENT:
+ return "gcvSTATUS_INVALID_ARGUMENT";
+ case gcvSTATUS_INVALID_OBJECT:
+ return "gcvSTATUS_INVALID_OBJECT";
+ case gcvSTATUS_OUT_OF_MEMORY:
+ return "gcvSTATUS_OUT_OF_MEMORY";
+ case gcvSTATUS_MEMORY_LOCKED:
+ return "gcvSTATUS_MEMORY_LOCKED";
+ case gcvSTATUS_MEMORY_UNLOCKED:
+ return "gcvSTATUS_MEMORY_UNLOCKED";
+ case gcvSTATUS_HEAP_CORRUPTED:
+ return "gcvSTATUS_HEAP_CORRUPTED";
+ case gcvSTATUS_GENERIC_IO:
+ return "gcvSTATUS_GENERIC_IO";
+ case gcvSTATUS_INVALID_ADDRESS:
+ return "gcvSTATUS_INVALID_ADDRESS";
+ case gcvSTATUS_CONTEXT_LOSSED:
+ return "gcvSTATUS_CONTEXT_LOSSED";
+ case gcvSTATUS_TOO_COMPLEX:
+ return "gcvSTATUS_TOO_COMPLEX";
+ case gcvSTATUS_BUFFER_TOO_SMALL:
+ return "gcvSTATUS_BUFFER_TOO_SMALL";
+ case gcvSTATUS_INTERFACE_ERROR:
+ return "gcvSTATUS_INTERFACE_ERROR";
+ case gcvSTATUS_NOT_SUPPORTED:
+ return "gcvSTATUS_NOT_SUPPORTED";
+ case gcvSTATUS_MORE_DATA:
+ return "gcvSTATUS_MORE_DATA";
+ case gcvSTATUS_TIMEOUT:
+ return "gcvSTATUS_TIMEOUT";
+ case gcvSTATUS_OUT_OF_RESOURCES:
+ return "gcvSTATUS_OUT_OF_RESOURCES";
+ case gcvSTATUS_INVALID_DATA:
+ return "gcvSTATUS_INVALID_DATA";
+ case gcvSTATUS_INVALID_MIPMAP:
+ return "gcvSTATUS_INVALID_MIPMAP";
+ case gcvSTATUS_NOT_FOUND:
+ return "gcvSTATUS_NOT_FOUND";
+ case gcvSTATUS_NOT_ALIGNED:
+ return "gcvSTATUS_NOT_ALIGNED";
+ case gcvSTATUS_INVALID_REQUEST:
+ return "gcvSTATUS_INVALID_REQUEST";
+ case gcvSTATUS_GPU_NOT_RESPONDING:
+ return "gcvSTATUS_GPU_NOT_RESPONDING";
+ case gcvSTATUS_TIMER_OVERFLOW:
+ return "gcvSTATUS_TIMER_OVERFLOW";
+ case gcvSTATUS_VERSION_MISMATCH:
+ return "gcvSTATUS_VERSION_MISMATCH";
+ case gcvSTATUS_LOCKED:
+ return "gcvSTATUS_LOCKED";
+ case gcvSTATUS_INTERRUPTED:
+ return "gcvSTATUS_INTERRUPTED";
+ case gcvSTATUS_DEVICE:
+ return "gcvSTATUS_DEVICE";
+ case gcvSTATUS_NOT_MULTI_PIPE_ALIGNED:
+ return "gcvSTATUS_NOT_MULTI_PIPE_ALIGNED";
+
+ /* Linker errors. */
+ case gcvSTATUS_GLOBAL_TYPE_MISMATCH:
+ return "gcvSTATUS_GLOBAL_TYPE_MISMATCH";
+ case gcvSTATUS_TOO_MANY_ATTRIBUTES:
+ return "gcvSTATUS_TOO_MANY_ATTRIBUTES";
+ case gcvSTATUS_TOO_MANY_UNIFORMS:
+ return "gcvSTATUS_TOO_MANY_UNIFORMS";
+ case gcvSTATUS_TOO_MANY_VARYINGS:
+ return "gcvSTATUS_TOO_MANY_VARYINGS";
+ case gcvSTATUS_UNDECLARED_VARYING:
+ return "gcvSTATUS_UNDECLARED_VARYING";
+ case gcvSTATUS_VARYING_TYPE_MISMATCH:
+ return "gcvSTATUS_VARYING_TYPE_MISMATCH";
+ case gcvSTATUS_MISSING_MAIN:
+ return "gcvSTATUS_MISSING_MAIN";
+ case gcvSTATUS_NAME_MISMATCH:
+ return "gcvSTATUS_NAME_MISMATCH";
+ case gcvSTATUS_INVALID_INDEX:
+ return "gcvSTATUS_INVALID_INDEX";
+ case gcvSTATUS_UNIFORM_MISMATCH:
+ return "gcvSTATUS_UNIFORM_MISMATCH";
+ case gcvSTATUS_UNSAT_LIB_SYMBOL:
+ return "gcvSTATUS_UNSAT_LIB_SYMBOL";
+ case gcvSTATUS_TOO_MANY_SHADERS:
+ return "gcvSTATUS_TOO_MANY_SHADERS";
+ case gcvSTATUS_LINK_INVALID_SHADERS:
+ return "gcvSTATUS_LINK_INVALID_SHADERS";
+ case gcvSTATUS_CS_NO_WORKGROUP_SIZE:
+ return "gcvSTATUS_CS_NO_WORKGROUP_SIZE";
+ case gcvSTATUS_LINK_LIB_ERROR:
+ return "gcvSTATUS_LINK_LIB_ERROR";
+ case gcvSTATUS_SHADER_VERSION_MISMATCH:
+ return "gcvSTATUS_SHADER_VERSION_MISMATCH";
+ case gcvSTATUS_TOO_MANY_INSTRUCTION:
+ return "gcvSTATUS_TOO_MANY_INSTRUCTION";
+ case gcvSTATUS_SSBO_MISMATCH:
+ return "gcvSTATUS_SSBO_MISMATCH";
+ case gcvSTATUS_TOO_MANY_OUTPUT:
+ return "gcvSTATUS_TOO_MANY_OUTPUT";
+ case gcvSTATUS_TOO_MANY_INPUT:
+ return "gcvSTATUS_TOO_MANY_INPUT";
+ case gcvSTATUS_NOT_SUPPORT_CL:
+ return "gcvSTATUS_NOT_SUPPORT_CL";
+ case gcvSTATUS_NOT_SUPPORT_INTEGER:
+ return "gcvSTATUS_NOT_SUPPORT_INTEGER";
+ case gcvSTATUS_UNIFORM_TYPE_MISMATCH:
+ return "gcvSTATUS_UNIFORM_TYPE_MISMATCH";
+ case gcvSTATUS_MISSING_PRIMITIVE_TYPE:
+ return "gcvSTATUS_MISSING_PRIMITIVE_TYPE";
+ case gcvSTATUS_MISSING_OUTPUT_VERTEX_COUNT:
+ return "gcvSTATUS_MISSING_OUTPUT_VERTEX_COUNT";
+ case gcvSTATUS_NON_INVOCATION_ID_AS_INDEX:
+ return "gcvSTATUS_NON_INVOCATION_ID_AS_INDEX";
+ case gcvSTATUS_INPUT_ARRAY_SIZE_MISMATCH:
+ return "gcvSTATUS_INPUT_ARRAY_SIZE_MISMATCH";
+ case gcvSTATUS_OUTPUT_ARRAY_SIZE_MISMATCH:
+ return "gcvSTATUS_OUTPUT_ARRAY_SIZE_MISMATCH";
+
+ /* Compiler errors. */
+ case gcvSTATUS_COMPILER_FE_PREPROCESSOR_ERROR:
+ return "gcvSTATUS_COMPILER_FE_PREPROCESSOR_ERROR";
+ case gcvSTATUS_COMPILER_FE_PARSER_ERROR:
+ return "gcvSTATUS_COMPILER_FE_PARSER_ERROR";
+ default:
+ return "nil";
+ }
+}
+
+/*******************************************************************************
+***** Binary Trace *************************************************************
+*******************************************************************************/
+
+/*******************************************************************************
+** _VerifyMessage
+**
+** Verify a binary trace message, decode it to human readable string and print
+** it.
+**
+** ARGUMENTS:
+**
+** gctCONST_STRING Buffer
+** Pointer to buffer to store.
+**
+** gctSIZE_T Bytes
+** Buffer length.
+*/
+void
+_VerifyMessage(
+ IN gctCONST_STRING Buffer,
+ IN gctSIZE_T Bytes
+ )
+{
+ char arguments[150] = {0};
+ char format[100] = {0};
+
+ gctSTRING function;
+ gctPOINTER args;
+ gctUINT32 numArguments;
+ int i = 0;
+ gctUINT32 functionBytes;
+
+ gcsBINARY_TRACE_MESSAGE_PTR message = (gcsBINARY_TRACE_MESSAGE_PTR)Buffer;
+
+ /* Check signature. */
+ if (message->signature != 0x7FFFFFFF)
+ {
+ gcmkPRINT("Signature error");
+ return;
+ }
+
+ /* Get function name. */
+ function = (gctSTRING)&message->payload;
+ functionBytes = (gctUINT32)strlen(function) + 1;
+
+ /* Get arguments number. */
+ numArguments = message->numArguments;
+
+ /* Get arguments . */
+ args = function + functionBytes;
+
+ /* Prepare format string. */
+ while (numArguments--)
+ {
+ format[i++] = '%';
+ format[i++] = 'x';
+ format[i++] = ' ';
+ }
+
+ format[i] = '\0';
+
+ if (numArguments)
+ {
+ gcmkVSPRINTF(arguments, 150, format, (gctARGUMENTS *) &args);
+ }
+
+ gcmkPRINT("[%d](%d): %s(%d) %s",
+ message->pid,
+ message->tid,
+ function,
+ message->line,
+ arguments);
+}
+
+
+/*******************************************************************************
+** gckOS_WriteToRingBuffer
+**
+** Store a buffer to ring buffer.
+**
+** ARGUMENTS:
+**
+** gctCONST_STRING Buffer
+** Pointer to buffer to store.
+**
+** gctSIZE_T Bytes
+** Buffer length.
+*/
+void
+gckOS_WriteToRingBuffer(
+ IN gctCONST_STRING Buffer,
+ IN gctSIZE_T Bytes
+ )
+{
+
+}
+
+/*******************************************************************************
+** gckOS_BinaryTrace
+**
+** Output a binary trace message.
+**
+** ARGUMENTS:
+**
+** gctCONST_STRING Function
+** Pointer to function name.
+**
+** gctINT Line
+** Line number.
+**
+** gctCONST_STRING Text OPTIONAL
+** Optional pointer to a descriptive text.
+**
+** ...
+** Optional arguments to the descriptive text.
+*/
+void
+gckOS_BinaryTrace(
+ IN gctCONST_STRING Function,
+ IN gctINT Line,
+ IN gctCONST_STRING Text OPTIONAL,
+ ...
+ )
+{
+ static gctUINT32 messageSignature = 0x7FFFFFFF;
+ char buffer[gcdBINARY_TRACE_MESSAGE_SIZE];
+ gctUINT32 numArguments = 0;
+ gctUINT32 functionBytes;
+ gctUINT32 i = 0;
+ gctSTRING payload;
+ gcsBINARY_TRACE_MESSAGE_PTR message = (gcsBINARY_TRACE_MESSAGE_PTR)buffer;
+
+ /* Calculate arguments number. */
+ if (Text)
+ {
+ while (Text[i] != '\0')
+ {
+ if (Text[i] == '%')
+ {
+ numArguments++;
+ }
+ i++;
+ }
+ }
+
+ message->signature = messageSignature;
+ message->pid = gcmkGETPROCESSID();
+ message->tid = gcmkGETTHREADID();
+ message->line = Line;
+ message->numArguments = numArguments;
+
+ payload = (gctSTRING)&message->payload;
+
+ /* Function name. */
+ functionBytes = (gctUINT32)gcmkSTRLEN(Function) + 1;
+ gcmkMEMCPY(payload, Function, functionBytes);
+
+ /* Advance to next payload. */
+ payload += functionBytes;
+
+ /* Arguments value. */
+ if (numArguments)
+ {
+ gctARGUMENTS p;
+ gcmkARGUMENTS_START(p, Text);
+
+ for (i = 0; i < numArguments; ++i)
+ {
+ gctPOINTER value = gcmkARGUMENTS_ARG(p, gctPOINTER);
+ gcmkMEMCPY(payload, &value, gcmSIZEOF(gctPOINTER));
+ payload += gcmSIZEOF(gctPOINTER);
+ }
+
+ gcmkARGUMENTS_END(p);
+ }
+
+ gcmkASSERT(payload - buffer <= gcdBINARY_TRACE_MESSAGE_SIZE);
+
+
+ /* Send buffer to ring buffer. */
+ gckOS_WriteToRingBuffer(buffer, (gctUINT32)(payload - buffer));
+}
+
diff --git a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_event.c b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_event.c
new file mode 100644
index 000000000000..67400d0a41a9
--- /dev/null
+++ b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_event.c
@@ -0,0 +1,3017 @@
+/****************************************************************************
+*
+* The MIT License (MIT)
+*
+* Copyright (c) 2014 - 2018 Vivante 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 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 GPL License (GPL)
+*
+* Copyright (C) 2014 - 2018 Vivante 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.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+*****************************************************************************
+*
+* Note: This software is released under dual MIT and GPL licenses. A
+* recipient may use this file under the terms of either the MIT license or
+* GPL License. If you wish to use only one license not the other, you can
+* indicate your decision by deleting one of the above license notices in your
+* version of this file.
+*
+*****************************************************************************/
+
+
+#include "gc_hal_kernel_precomp.h"
+#include "gc_hal_kernel_buffer.h"
+
+#ifdef __QNXNTO__
+#include "gc_hal_kernel_qnx.h"
+#endif
+
+#define _GC_OBJ_ZONE gcvZONE_EVENT
+
+#define gcdEVENT_ALLOCATION_COUNT (4096 / gcmSIZEOF(gcsHAL_INTERFACE))
+#define gcdEVENT_MIN_THRESHOLD 4
+
+/******************************************************************************\
+********************************* Support Code *********************************
+\******************************************************************************/
+
+static gcmINLINE gceSTATUS
+gckEVENT_AllocateQueue(
+ IN gckEVENT Event,
+ OUT gcsEVENT_QUEUE_PTR * Queue
+ )
+{
+ gceSTATUS status;
+
+ gcmkHEADER_ARG("Event=0x%x", Event);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Event, gcvOBJ_EVENT);
+ gcmkVERIFY_ARGUMENT(Queue != gcvNULL);
+
+ /* Do we have free queues? */
+ if (Event->freeList == gcvNULL)
+ {
+ gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
+ }
+
+ /* Move one free queue from the free list. */
+ * Queue = Event->freeList;
+ Event->freeList = Event->freeList->next;
+
+ /* Success. */
+ gcmkFOOTER_ARG("*Queue=0x%x", gcmOPT_POINTER(Queue));
+ return gcvSTATUS_OK;
+
+OnError:
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+static gceSTATUS
+gckEVENT_FreeQueue(
+ IN gckEVENT Event,
+ OUT gcsEVENT_QUEUE_PTR Queue
+ )
+{
+ gceSTATUS status = gcvSTATUS_OK;
+
+ gcmkHEADER_ARG("Event=0x%x", Event);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Event, gcvOBJ_EVENT);
+ gcmkVERIFY_ARGUMENT(Queue != gcvNULL);
+
+ /* Move one free queue from the free list. */
+ Queue->next = Event->freeList;
+ Event->freeList = Queue;
+
+ /* Success. */
+ gcmkFOOTER();
+ return status;
+}
+
+static gceSTATUS
+gckEVENT_FreeRecord(
+ IN gckEVENT Event,
+ IN gcsEVENT_PTR Record
+ )
+{
+ gceSTATUS status;
+ gctBOOL acquired = gcvFALSE;
+
+ gcmkHEADER_ARG("Event=0x%x Record=0x%x", Event, Record);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Event, gcvOBJ_EVENT);
+ gcmkVERIFY_ARGUMENT(Record != gcvNULL);
+
+ /* Acquire the mutex. */
+ gcmkONERROR(gckOS_AcquireMutex(Event->os,
+ Event->freeEventMutex,
+ gcvINFINITE));
+ acquired = gcvTRUE;
+
+ /* Push the record on the free list. */
+ Record->next = Event->freeEventList;
+ Event->freeEventList = Record;
+ Event->freeEventCount += 1;
+
+ /* Release the mutex. */
+ gcmkONERROR(gckOS_ReleaseMutex(Event->os, Event->freeEventMutex));
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ /* Roll back. */
+ if (acquired)
+ {
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(Event->os, Event->freeEventMutex));
+ }
+
+ /* Return the status. */
+ gcmkFOOTER();
+ return gcvSTATUS_OK;
+}
+
+static gceSTATUS
+gckEVENT_IsEmpty(
+ IN gckEVENT Event,
+ OUT gctBOOL_PTR IsEmpty
+ )
+{
+ gceSTATUS status;
+ gctSIZE_T i;
+
+ gcmkHEADER_ARG("Event=0x%x", Event);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Event, gcvOBJ_EVENT);
+ gcmkVERIFY_ARGUMENT(IsEmpty != gcvNULL);
+
+ /* Assume the event queue is empty. */
+ *IsEmpty = gcvTRUE;
+
+ /* Walk the event queue. */
+ for (i = 0; i < gcmCOUNTOF(Event->queues); ++i)
+ {
+ /* Check whether this event is in use. */
+ if (Event->queues[i].head != gcvNULL)
+ {
+ /* The event is in use, hence the queue is not empty. */
+ *IsEmpty = gcvFALSE;
+ break;
+ }
+ }
+
+ /* Try acquiring the mutex. */
+ status = gckOS_AcquireMutex(Event->os, Event->eventQueueMutex, 0);
+ if (status == gcvSTATUS_TIMEOUT)
+ {
+ /* Timeout - queue is no longer empty. */
+ *IsEmpty = gcvFALSE;
+ }
+ else
+ {
+ /* Bail out on error. */
+ gcmkONERROR(status);
+
+ /* Release the mutex. */
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(Event->os, Event->eventQueueMutex));
+ }
+
+ /* Success. */
+ gcmkFOOTER_ARG("*IsEmpty=%d", gcmOPT_VALUE(IsEmpty));
+ return gcvSTATUS_OK;
+
+OnError:
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+static gceSTATUS
+_TryToIdleGPU(
+ IN gckEVENT Event
+)
+{
+ gceSTATUS status;
+ gctBOOL empty = gcvFALSE, idle = gcvFALSE;
+ gctBOOL powerLocked = gcvFALSE;
+ gckHARDWARE hardware;
+
+ gcmkHEADER_ARG("Event=0x%x", Event);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Event, gcvOBJ_EVENT);
+
+ /* Grab gckHARDWARE object. */
+ hardware = Event->kernel->hardware;
+ gcmkVERIFY_OBJECT(hardware, gcvOBJ_HARDWARE);
+
+ /* Check whether the event queue is empty. */
+ gcmkONERROR(gckEVENT_IsEmpty(Event, &empty));
+
+ if (empty)
+ {
+ status = gckOS_AcquireMutex(hardware->os, hardware->powerMutex, 0);
+ if (status == gcvSTATUS_TIMEOUT)
+ {
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+ }
+
+ powerLocked = gcvTRUE;
+
+ /* Query whether the hardware is idle. */
+ gcmkONERROR(gckHARDWARE_QueryIdle(Event->kernel->hardware, &idle));
+
+ gcmkONERROR(gckOS_ReleaseMutex(hardware->os, hardware->powerMutex));
+ powerLocked = gcvFALSE;
+
+ if (idle)
+ {
+ /* Inform the system of idle GPU. */
+ gcmkONERROR(gckOS_Broadcast(Event->os,
+ Event->kernel->hardware,
+ gcvBROADCAST_GPU_IDLE));
+ }
+ }
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ if (powerLocked)
+ {
+ gcmkONERROR(gckOS_ReleaseMutex(hardware->os, hardware->powerMutex));
+ }
+
+ gcmkFOOTER();
+ return status;
+}
+
+static gceSTATUS
+__RemoveRecordFromProcessDB(
+ IN gckEVENT Event,
+ IN gcsEVENT_PTR Record
+ )
+{
+ gcmkHEADER_ARG("Event=0x%x Record=0x%x", Event, Record);
+ gcmkVERIFY_ARGUMENT(Record != gcvNULL);
+
+ switch (Record->info.command)
+ {
+ case gcvHAL_FREE_NON_PAGED_MEMORY:
+ gcmkVERIFY_OK(gckKERNEL_RemoveProcessDB(
+ Event->kernel,
+ Record->processID,
+ gcvDB_NON_PAGED,
+ gcmUINT64_TO_PTR(Record->info.u.FreeNonPagedMemory.logical)));
+ break;
+
+ case gcvHAL_FREE_CONTIGUOUS_MEMORY:
+ gcmkVERIFY_OK(gckKERNEL_RemoveProcessDB(
+ Event->kernel,
+ Record->processID,
+ gcvDB_CONTIGUOUS,
+ gcmUINT64_TO_PTR(Record->info.u.FreeContiguousMemory.logical)));
+ break;
+
+ case gcvHAL_UNLOCK_VIDEO_MEMORY:
+ gcmkVERIFY_OK(gckKERNEL_RemoveProcessDB(
+ Event->kernel,
+ Record->processID,
+ gcvDB_VIDEO_MEMORY_LOCKED,
+ gcmUINT64_TO_PTR(Record->info.u.UnlockVideoMemory.node)));
+ break;
+
+ case gcvHAL_UNMAP_USER_MEMORY:
+ gcmkVERIFY_OK(gckKERNEL_RemoveProcessDB(
+ Event->kernel,
+ Record->processID,
+ gcvDB_MAP_USER_MEMORY,
+ gcmINT2PTR(Record->info.u.UnmapUserMemory.info)));
+ break;
+
+ case gcvHAL_FREE_VIRTUAL_COMMAND_BUFFER:
+ gcmkVERIFY_OK(gckKERNEL_RemoveProcessDB(
+ Event->kernel,
+ Record->processID,
+ gcvDB_COMMAND_BUFFER,
+ gcmUINT64_TO_PTR(Record->info.u.FreeVirtualCommandBuffer.logical)));
+ break;
+
+ default:
+ break;
+ }
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+}
+
+static gceSTATUS
+_ReleaseVideoMemoryHandle(
+ IN gckKERNEL Kernel,
+ IN OUT gcsEVENT_PTR Record,
+ IN OUT gcsHAL_INTERFACE * Interface
+ )
+{
+ gceSTATUS status;
+ gckVIDMEM_NODE nodeObject;
+ gctUINT32 handle;
+
+ switch(Interface->command)
+ {
+ case gcvHAL_UNLOCK_VIDEO_MEMORY:
+ handle = (gctUINT32)Interface->u.UnlockVideoMemory.node;
+
+ gcmkONERROR(gckVIDMEM_HANDLE_Lookup(
+ Kernel, Record->processID, handle, &nodeObject));
+
+ Record->info.u.UnlockVideoMemory.node = gcmPTR_TO_UINT64(nodeObject);
+
+ gckVIDMEM_HANDLE_Dereference(Kernel, Record->processID, handle);
+ break;
+
+ default:
+ break;
+ }
+
+ return gcvSTATUS_OK;
+OnError:
+ return status;
+}
+
+/*******************************************************************************
+**
+** _QueryFlush
+**
+** Check the type of surfaces which will be released by current event and
+** determine the cache needed to flush.
+**
+*/
+static gceSTATUS
+_QueryFlush(
+ IN gckEVENT Event,
+ IN gcsEVENT_PTR Record,
+ OUT gceKERNEL_FLUSH *Flush
+ )
+{
+ gceKERNEL_FLUSH flush = 0;
+ gcmkHEADER_ARG("Event=0x%x Record=0x%x", Event, Record);
+ gcmkVERIFY_ARGUMENT(Record != gcvNULL);
+
+ while (Record != gcvNULL)
+ {
+ switch (Record->info.command)
+ {
+ case gcvHAL_UNLOCK_VIDEO_MEMORY:
+ switch(Record->info.u.UnlockVideoMemory.type)
+ {
+ case gcvSURF_TILE_STATUS:
+ flush |= gcvFLUSH_TILE_STATUS;
+ break;
+ case gcvSURF_RENDER_TARGET:
+ flush |= gcvFLUSH_COLOR;
+ break;
+ case gcvSURF_DEPTH:
+ flush |= gcvFLUSH_DEPTH;
+ break;
+ case gcvSURF_TEXTURE:
+ flush |= gcvFLUSH_TEXTURE;
+ break;
+ case gcvSURF_ICACHE:
+ flush |= gcvFLUSH_ICACHE;
+ break;
+ case gcvSURF_TXDESC:
+ flush |= gcvFLUSH_TXDESC;
+ break;
+ case gcvSURF_FENCE:
+ flush |= gcvFLUSH_FENCE;
+ break;
+ case gcvSURF_VERTEX:
+ flush |= gcvFLUSH_VERTEX;
+ break;
+ case gcvSURF_TFBHEADER:
+ flush |= gcvFLUSH_TFBHEADER;
+ break;
+ case gcvSURF_TYPE_UNKNOWN:
+ *Flush = gcvFLUSH_ALL;
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+ default:
+ break;
+ }
+ break;
+ case gcvHAL_UNMAP_USER_MEMORY:
+ *Flush = gcvFLUSH_ALL;
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+ default:
+ break;
+ }
+
+ Record = Record->next;
+ }
+
+ *Flush = flush;
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+}
+
+void
+_SubmitTimerFunction(
+ gctPOINTER Data
+ )
+{
+ gckEVENT event = (gckEVENT)Data;
+ gcmkVERIFY_OK(gckEVENT_Submit(event, gcvTRUE, gcvFALSE));
+}
+
+/******************************************************************************\
+******************************* gckEVENT API Code *******************************
+\******************************************************************************/
+
+/*******************************************************************************
+**
+** gckEVENT_Construct
+**
+** Construct a new gckEVENT object.
+**
+** INPUT:
+**
+** gckKERNEL Kernel
+** Pointer to an gckKERNEL object.
+**
+** OUTPUT:
+**
+** gckEVENT * Event
+** Pointer to a variable that receives the gckEVENT object pointer.
+*/
+gceSTATUS
+gckEVENT_Construct(
+ IN gckKERNEL Kernel,
+ OUT gckEVENT * Event
+ )
+{
+ gckOS os;
+ gceSTATUS status;
+ gckEVENT eventObj = gcvNULL;
+ int i;
+ gcsEVENT_PTR record;
+ gctPOINTER pointer = gcvNULL;
+
+ gcmkHEADER_ARG("Kernel=0x%x", Kernel);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
+ gcmkVERIFY_ARGUMENT(Event != gcvNULL);
+
+ /* Extract the pointer to the gckOS object. */
+ os = Kernel->os;
+ gcmkVERIFY_OBJECT(os, gcvOBJ_OS);
+
+ /* Allocate the gckEVENT object. */
+ gcmkONERROR(gckOS_Allocate(os, gcmSIZEOF(struct _gckEVENT), &pointer));
+
+ eventObj = pointer;
+
+ /* Reset the object. */
+ gcmkVERIFY_OK(gckOS_ZeroMemory(eventObj, gcmSIZEOF(struct _gckEVENT)));
+
+ /* Initialize the gckEVENT object. */
+ eventObj->object.type = gcvOBJ_EVENT;
+ eventObj->kernel = Kernel;
+ eventObj->os = os;
+
+ /* Create the mutexes. */
+ gcmkONERROR(gckOS_CreateMutex(os, &eventObj->eventQueueMutex));
+ gcmkONERROR(gckOS_CreateMutex(os, &eventObj->freeEventMutex));
+ gcmkONERROR(gckOS_CreateMutex(os, &eventObj->eventListMutex));
+
+ /* Create a bunch of event reccords. */
+ for (i = 0; i < gcdEVENT_ALLOCATION_COUNT; i += 1)
+ {
+ /* Allocate an event record. */
+ gcmkONERROR(gckOS_Allocate(os, gcmSIZEOF(gcsEVENT), &pointer));
+
+ record = pointer;
+
+ /* Push it on the free list. */
+ record->next = eventObj->freeEventList;
+ eventObj->freeEventList = record;
+ eventObj->freeEventCount += 1;
+ }
+
+ /* Initialize the free list of event queues. */
+ for (i = 0; i < gcdREPO_LIST_COUNT; i += 1)
+ {
+ eventObj->repoList[i].next = eventObj->freeList;
+ eventObj->freeList = &eventObj->repoList[i];
+ }
+
+ eventObj->freeQueueCount = gcmCOUNTOF(eventObj->queues);
+
+ gcmkONERROR(gckOS_AtomConstruct(os, &eventObj->pending));
+
+ gcmkVERIFY_OK(gckOS_CreateTimer(os,
+ _SubmitTimerFunction,
+ (gctPOINTER)eventObj,
+ &eventObj->submitTimer));
+
+#if gcdINTERRUPT_STATISTIC
+ gcmkONERROR(gckOS_AtomConstruct(os, &eventObj->interruptCount));
+ gcmkONERROR(gckOS_AtomSet(os,eventObj->interruptCount, 0));
+#endif
+
+ eventObj->notifyState = -1;
+
+ /* Return pointer to the gckEVENT object. */
+ *Event = eventObj;
+
+ /* Success. */
+ gcmkFOOTER_ARG("*Event=0x%x", *Event);
+ return gcvSTATUS_OK;
+
+OnError:
+ /* Roll back. */
+ if (eventObj != gcvNULL)
+ {
+ if (eventObj->eventQueueMutex != gcvNULL)
+ {
+ gcmkVERIFY_OK(gckOS_DeleteMutex(os, eventObj->eventQueueMutex));
+ }
+
+ if (eventObj->freeEventMutex != gcvNULL)
+ {
+ gcmkVERIFY_OK(gckOS_DeleteMutex(os, eventObj->freeEventMutex));
+ }
+
+ if (eventObj->eventListMutex != gcvNULL)
+ {
+ gcmkVERIFY_OK(gckOS_DeleteMutex(os, eventObj->eventListMutex));
+ }
+
+ while (eventObj->freeEventList != gcvNULL)
+ {
+ record = eventObj->freeEventList;
+ eventObj->freeEventList = record->next;
+
+ gcmkVERIFY_OK(gcmkOS_SAFE_FREE(os, record));
+ }
+
+ if (eventObj->pending != gcvNULL)
+ {
+ gcmkVERIFY_OK(gckOS_AtomDestroy(os, eventObj->pending));
+ }
+
+#if gcdINTERRUPT_STATISTIC
+ if (eventObj->interruptCount)
+ {
+ gcmkVERIFY_OK(gckOS_AtomDestroy(os, eventObj->interruptCount));
+ }
+#endif
+ gcmkVERIFY_OK(gcmkOS_SAFE_FREE(os, eventObj));
+ }
+
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+/*******************************************************************************
+**
+** gckEVENT_Destroy
+**
+** Destroy an gckEVENT object.
+**
+** INPUT:
+**
+** gckEVENT Event
+** Pointer to an gckEVENT object.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckEVENT_Destroy(
+ IN gckEVENT Event
+ )
+{
+ gcsEVENT_PTR record;
+ gcsEVENT_QUEUE_PTR queue;
+
+ gcmkHEADER_ARG("Event=0x%x", Event);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Event, gcvOBJ_EVENT);
+
+ if (Event->submitTimer != gcvNULL)
+ {
+ gcmkVERIFY_OK(gckOS_StopTimer(Event->os, Event->submitTimer));
+ gcmkVERIFY_OK(gckOS_DestroyTimer(Event->os, Event->submitTimer));
+ }
+
+ /* Delete the queue mutex. */
+ gcmkVERIFY_OK(gckOS_DeleteMutex(Event->os, Event->eventQueueMutex));
+
+ /* Free all free events. */
+ while (Event->freeEventList != gcvNULL)
+ {
+ record = Event->freeEventList;
+ Event->freeEventList = record->next;
+
+ gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Event->os, record));
+ }
+
+ /* Delete the free mutex. */
+ gcmkVERIFY_OK(gckOS_DeleteMutex(Event->os, Event->freeEventMutex));
+
+ /* Free all pending queues. */
+ while (Event->queueHead != gcvNULL)
+ {
+ /* Get the current queue. */
+ queue = Event->queueHead;
+
+ /* Free all pending events. */
+ while (queue->head != gcvNULL)
+ {
+ record = queue->head;
+ queue->head = record->next;
+
+ gcmkTRACE_ZONE_N(
+ gcvLEVEL_WARNING, gcvZONE_EVENT,
+ gcmSIZEOF(record) + gcmSIZEOF(queue->source),
+ "Event record 0x%x is still pending for %d.",
+ record, queue->source
+ );
+
+ gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Event->os, record));
+ }
+
+ /* Remove the top queue from the list. */
+ if (Event->queueHead == Event->queueTail)
+ {
+ Event->queueHead =
+ Event->queueTail = gcvNULL;
+ }
+ else
+ {
+ Event->queueHead = Event->queueHead->next;
+ }
+
+ /* Free the queue. */
+ gcmkVERIFY_OK(gckEVENT_FreeQueue(Event, queue));
+ }
+
+ /* Delete the list mutex. */
+ gcmkVERIFY_OK(gckOS_DeleteMutex(Event->os, Event->eventListMutex));
+
+ gcmkVERIFY_OK(gckOS_AtomDestroy(Event->os, Event->pending));
+
+#if gcdINTERRUPT_STATISTIC
+ gcmkVERIFY_OK(gckOS_AtomDestroy(Event->os, Event->interruptCount));
+#endif
+
+ /* Mark the gckEVENT object as unknown. */
+ Event->object.type = gcvOBJ_UNKNOWN;
+
+ /* Free the gckEVENT object. */
+ gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Event->os, Event));
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+}
+
+/*******************************************************************************
+**
+** gckEVENT_GetEvent
+**
+** Reserve the next available hardware event.
+**
+** INPUT:
+**
+** gckEVENT Event
+** Pointer to an gckEVENT object.
+**
+** gctBOOL Wait
+** Set to gcvTRUE to force the function to wait if no events are
+** immediately available.
+**
+** gceKERNEL_WHERE Source
+** Source of the event.
+**
+** OUTPUT:
+**
+** gctUINT8 * EventID
+** Reserved event ID.
+*/
+#define gcdINVALID_EVENT_PTR ((gcsEVENT_PTR)gcvMAXUINTPTR_T)
+
+gceSTATUS
+gckEVENT_GetEvent(
+ IN gckEVENT Event,
+ IN gctBOOL Wait,
+ OUT gctUINT8 * EventID,
+ IN gceKERNEL_WHERE Source
+ )
+{
+ gctINT i, id;
+ gceSTATUS status;
+ gctBOOL acquired = gcvFALSE;
+ gctINT32 free;
+
+ gcmkHEADER_ARG("Event=0x%x Source=%d", Event, Source);
+
+ while (gcvTRUE)
+ {
+ /* Grab the queue mutex. */
+ gcmkONERROR(gckOS_AcquireMutex(Event->os,
+ Event->eventQueueMutex,
+ gcvINFINITE));
+ acquired = gcvTRUE;
+
+ /* Walk through all events. */
+ id = Event->lastID;
+ for (i = 0; i < gcmCOUNTOF(Event->queues); ++i)
+ {
+ gctINT nextID = id + 1;
+
+ if (nextID == gcmCOUNTOF(Event->queues))
+ {
+ nextID = 0;
+ }
+
+ if (Event->queues[id].head == gcvNULL)
+ {
+ *EventID = (gctUINT8) id;
+
+ Event->lastID = (gctUINT8) nextID;
+
+ /* Save time stamp of event. */
+ Event->queues[id].head = gcdINVALID_EVENT_PTR;
+ Event->queues[id].stamp = ++(Event->stamp);
+ Event->queues[id].source = Source;
+
+ /* Decrease the number of free events. */
+ free = --Event->freeQueueCount;
+
+ /* Make compiler happy. */
+ free = free;
+
+#if gcdDYNAMIC_SPEED
+ if (free <= gcdDYNAMIC_EVENT_THRESHOLD)
+ {
+ gcmkONERROR(gckOS_BroadcastHurry(
+ Event->os,
+ Event->kernel->hardware,
+ gcdDYNAMIC_EVENT_THRESHOLD - free));
+ }
+#endif
+
+ /* Release the queue mutex. */
+ gcmkONERROR(gckOS_ReleaseMutex(Event->os,
+ Event->eventQueueMutex));
+
+ /* Success. */
+ gcmkTRACE_ZONE_N(
+ gcvLEVEL_INFO, gcvZONE_EVENT,
+ gcmSIZEOF(id),
+ "Using id=%d",
+ id
+ );
+
+ gcmkFOOTER_ARG("*EventID=%u", *EventID);
+ return gcvSTATUS_OK;
+ }
+
+ id = nextID;
+ }
+
+#if gcdDYNAMIC_SPEED
+ /* No free events, speed up the GPU right now! */
+ gcmkONERROR(gckOS_BroadcastHurry(Event->os,
+ Event->kernel->hardware,
+ gcdDYNAMIC_EVENT_THRESHOLD));
+#endif
+
+ /* Release the queue mutex. */
+ gcmkONERROR(gckOS_ReleaseMutex(Event->os, Event->eventQueueMutex));
+ acquired = gcvFALSE;
+
+ /* Fail if wait is not requested. */
+ if (!Wait)
+ {
+ /* Out of resources. */
+ gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
+ }
+
+ /* Delay a while. */
+ gcmkONERROR(gckOS_Delay(Event->os, 1));
+ }
+
+OnError:
+ if (acquired)
+ {
+ /* Release the queue mutex. */
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(Event->os, Event->eventQueueMutex));
+ }
+
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+/*******************************************************************************
+**
+** gckEVENT_AllocateRecord
+**
+** Allocate a record for the new event.
+**
+** INPUT:
+**
+** gckEVENT Event
+** Pointer to an gckEVENT object.
+**
+** gctBOOL AllocateAllowed
+** State for allocation if out of free events.
+**
+** OUTPUT:
+**
+** gcsEVENT_PTR * Record
+** Allocated event record.
+*/
+static gcmINLINE gceSTATUS
+gckEVENT_AllocateRecord(
+ IN gckEVENT Event,
+ IN gctBOOL AllocateAllowed,
+ OUT gcsEVENT_PTR * Record
+ )
+{
+ gceSTATUS status;
+ gctBOOL acquired = gcvFALSE;
+ gctINT i;
+ gcsEVENT_PTR record;
+ gctPOINTER pointer = gcvNULL;
+
+ gcmkHEADER_ARG("Event=0x%x AllocateAllowed=%d", Event, AllocateAllowed);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Event, gcvOBJ_EVENT);
+ gcmkVERIFY_ARGUMENT(Record != gcvNULL);
+
+ /* Acquire the mutex. */
+ gcmkONERROR(gckOS_AcquireMutex(Event->os, Event->freeEventMutex, gcvINFINITE));
+ acquired = gcvTRUE;
+
+ /* Test if we are below the allocation threshold. */
+ if ( (AllocateAllowed && (Event->freeEventCount < gcdEVENT_MIN_THRESHOLD)) ||
+ (Event->freeEventCount == 0) )
+ {
+ /* Allocate a bunch of records. */
+ for (i = 0; i < gcdEVENT_ALLOCATION_COUNT; i += 1)
+ {
+ /* Allocate an event record. */
+ gcmkONERROR(gckOS_Allocate(Event->os,
+ gcmSIZEOF(gcsEVENT),
+ &pointer));
+
+ record = pointer;
+
+ /* Push it on the free list. */
+ record->next = Event->freeEventList;
+ Event->freeEventList = record;
+ Event->freeEventCount += 1;
+ }
+ }
+
+ *Record = Event->freeEventList;
+ Event->freeEventList = Event->freeEventList->next;
+ Event->freeEventCount -= 1;
+
+ /* Release the mutex. */
+ gcmkONERROR(gckOS_ReleaseMutex(Event->os, Event->freeEventMutex));
+
+ /* Success. */
+ gcmkFOOTER_ARG("*Record=0x%x", gcmOPT_POINTER(Record));
+ return gcvSTATUS_OK;
+
+OnError:
+ /* Roll back. */
+ if (acquired)
+ {
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(Event->os, Event->freeEventMutex));
+ }
+
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+/*******************************************************************************
+**
+** gckEVENT_AddList
+**
+** Add a new event to the list of events.
+**
+** INPUT:
+**
+** gckEVENT Event
+** Pointer to an gckEVENT object.
+**
+** gcsHAL_INTERFACE_PTR Interface
+** Pointer to the interface for the event to be added.
+**
+** gceKERNEL_WHERE FromWhere
+** Place in the pipe where the event needs to be generated.
+**
+** gctBOOL AllocateAllowed
+** State for allocation if out of free events.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckEVENT_AddList(
+ IN gckEVENT Event,
+ IN gcsHAL_INTERFACE_PTR Interface,
+ IN gceKERNEL_WHERE FromWhere,
+ IN gctBOOL AllocateAllowed,
+ IN gctBOOL FromKernel
+ )
+{
+ gceSTATUS status;
+ gctBOOL acquired = gcvFALSE;
+ gcsEVENT_PTR record = gcvNULL;
+ gcsEVENT_QUEUE_PTR queue;
+ gckVIRTUAL_COMMAND_BUFFER_PTR buffer;
+ gckKERNEL kernel = Event->kernel;
+
+ gcmkHEADER_ARG("Event=0x%x Interface=0x%x",
+ Event, Interface);
+
+ gcmkTRACE_ZONE(gcvLEVEL_VERBOSE, _GC_OBJ_ZONE,
+ "FromWhere=%d AllocateAllowed=%d",
+ FromWhere, AllocateAllowed);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Event, gcvOBJ_EVENT);
+ gcmkVERIFY_ARGUMENT(Interface != gcvNULL);
+
+ /* Verify the event command. */
+ gcmkASSERT
+ ( (Interface->command == gcvHAL_FREE_NON_PAGED_MEMORY)
+ || (Interface->command == gcvHAL_FREE_CONTIGUOUS_MEMORY)
+ || (Interface->command == gcvHAL_WRITE_DATA)
+ || (Interface->command == gcvHAL_UNLOCK_VIDEO_MEMORY)
+ || (Interface->command == gcvHAL_SIGNAL)
+ || (Interface->command == gcvHAL_UNMAP_USER_MEMORY)
+ || (Interface->command == gcvHAL_TIMESTAMP)
+ || (Interface->command == gcvHAL_COMMIT_DONE)
+ || (Interface->command == gcvHAL_FREE_VIRTUAL_COMMAND_BUFFER)
+ || (Interface->command == gcvHAL_DESTROY_MMU)
+ );
+
+ /* Validate the source. */
+ if ((FromWhere != gcvKERNEL_COMMAND) && (FromWhere != gcvKERNEL_PIXEL))
+ {
+ /* Invalid argument. */
+ gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
+ }
+
+ /* Allocate a free record. */
+ gcmkONERROR(gckEVENT_AllocateRecord(Event, AllocateAllowed, &record));
+
+ /* Termninate the record. */
+ record->next = gcvNULL;
+
+ /* Record the committer. */
+ record->fromKernel = FromKernel;
+
+ /* Copy the event interface into the record. */
+ gckOS_MemCopy(&record->info, Interface, gcmSIZEOF(record->info));
+
+ /* Get process ID. */
+ gcmkONERROR(gckOS_GetProcessID(&record->processID));
+
+ if (FromKernel == gcvFALSE)
+ {
+ gcmkONERROR(__RemoveRecordFromProcessDB(Event, record));
+
+ /* Handle is belonged to current process, it must be released now. */
+ status = _ReleaseVideoMemoryHandle(Event->kernel, record, Interface);
+
+ if (gcmIS_ERROR(status))
+ {
+ /* Ingore error because there are other events in the queue. */
+ status = gcvSTATUS_OK;
+ goto OnError;
+ }
+ }
+
+#ifdef __QNXNTO__
+ record->kernel = Event->kernel;
+#endif
+
+ /* Unmap user space logical address.
+ * Linux kernel does not support unmap the memory of other process any more since 3.5.
+ * Let's unmap memory of self process before submit the event to gpu.
+ * */
+ switch(Interface->command)
+ {
+ case gcvHAL_FREE_NON_PAGED_MEMORY:
+ gcmkONERROR(gckOS_UnmapUserLogical(
+ Event->os,
+ gcmNAME_TO_PTR(Interface->u.FreeNonPagedMemory.physical),
+ (gctSIZE_T) Interface->u.FreeNonPagedMemory.bytes,
+ gcmUINT64_TO_PTR(Interface->u.FreeNonPagedMemory.logical)));
+ break;
+ case gcvHAL_FREE_CONTIGUOUS_MEMORY:
+ gcmkONERROR(gckOS_UnmapUserLogical(
+ Event->os,
+ gcmNAME_TO_PTR(Interface->u.FreeContiguousMemory.physical),
+ (gctSIZE_T) Interface->u.FreeContiguousMemory.bytes,
+ gcmUINT64_TO_PTR(Interface->u.FreeContiguousMemory.logical)));
+ break;
+
+ case gcvHAL_FREE_VIRTUAL_COMMAND_BUFFER:
+ buffer = (gckVIRTUAL_COMMAND_BUFFER_PTR)gcmNAME_TO_PTR(Interface->u.FreeVirtualCommandBuffer.physical);
+ if (buffer != gcvNULL && buffer->virtualBuffer.userLogical)
+ {
+ gcmkONERROR(gckOS_DestroyUserVirtualMapping(
+ Event->os,
+ buffer->virtualBuffer.physical,
+ (gctSIZE_T) Interface->u.FreeVirtualCommandBuffer.bytes,
+ gcmUINT64_TO_PTR(Interface->u.FreeVirtualCommandBuffer.logical)));
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ /* Acquire the mutex. */
+ gcmkONERROR(gckOS_AcquireMutex(Event->os, Event->eventListMutex, gcvINFINITE));
+ acquired = gcvTRUE;
+
+ /* Do we need to allocate a new queue? */
+ if ((Event->queueTail == gcvNULL) || (Event->queueTail->source < FromWhere))
+ {
+ /* Allocate a new queue. */
+ gcmkONERROR(gckEVENT_AllocateQueue(Event, &queue));
+
+ /* Initialize the queue. */
+ queue->source = FromWhere;
+ queue->head = gcvNULL;
+ queue->next = gcvNULL;
+
+ /* Attach it to the list of allocated queues. */
+ if (Event->queueTail == gcvNULL)
+ {
+ Event->queueHead =
+ Event->queueTail = queue;
+ }
+ else
+ {
+ Event->queueTail->next = queue;
+ Event->queueTail = queue;
+ }
+ }
+ else
+ {
+ queue = Event->queueTail;
+ }
+
+ /* Attach the record to the queue. */
+ if (queue->head == gcvNULL)
+ {
+ queue->head = record;
+ queue->tail = record;
+ }
+ else
+ {
+ queue->tail->next = record;
+ queue->tail = record;
+ }
+
+ /* Release the mutex. */
+ gcmkONERROR(gckOS_ReleaseMutex(Event->os, Event->eventListMutex));
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ /* Roll back. */
+ if (acquired)
+ {
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(Event->os, Event->eventListMutex));
+ }
+
+ if (record != gcvNULL)
+ {
+ gcmkVERIFY_OK(gckEVENT_FreeRecord(Event, record));
+ }
+
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+/*******************************************************************************
+**
+** gckEVENT_Unlock
+**
+** Schedule an event to unlock virtual memory.
+**
+** INPUT:
+**
+** gckEVENT Event
+** Pointer to an gckEVENT object.
+**
+** gceKERNEL_WHERE FromWhere
+** Place in the pipe where the event needs to be generated.
+**
+** gcuVIDMEM_NODE_PTR Node
+** Pointer to a gcuVIDMEM_NODE union that specifies the virtual memory
+** to unlock.
+**
+** gceSURF_TYPE Type
+** Type of surface to unlock.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckEVENT_Unlock(
+ IN gckEVENT Event,
+ IN gceKERNEL_WHERE FromWhere,
+ IN gctPOINTER Node,
+ IN gceSURF_TYPE Type
+ )
+{
+ gceSTATUS status;
+ gcsHAL_INTERFACE iface;
+
+ gcmkHEADER_ARG("Event=0x%x FromWhere=%d Node=0x%x Type=%d",
+ Event, FromWhere, Node, Type);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Event, gcvOBJ_EVENT);
+ gcmkVERIFY_ARGUMENT(Node != gcvNULL);
+
+ /* Mark the event as an unlock. */
+ iface.command = gcvHAL_UNLOCK_VIDEO_MEMORY;
+ iface.u.UnlockVideoMemory.node = gcmPTR_TO_UINT64(Node);
+ iface.u.UnlockVideoMemory.type = Type;
+ iface.u.UnlockVideoMemory.asynchroneous = 0;
+
+ /* Append it to the queue. */
+ gcmkONERROR(gckEVENT_AddList(Event, &iface, FromWhere, gcvFALSE, gcvTRUE));
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+/*******************************************************************************
+**
+** gckEVENT_FreeNonPagedMemory
+**
+** Schedule an event to free non-paged memory.
+**
+** INPUT:
+**
+** gckEVENT Event
+** Pointer to an gckEVENT object.
+**
+** gctSIZE_T Bytes
+** Number of bytes of non-paged memory to free.
+**
+** gctPHYS_ADDR Physical
+** Physical address of non-paged memory to free.
+**
+** gctPOINTER Logical
+** Logical address of non-paged memory to free.
+**
+** gceKERNEL_WHERE FromWhere
+** Place in the pipe where the event needs to be generated.
+*/
+gceSTATUS
+gckEVENT_FreeNonPagedMemory(
+ IN gckEVENT Event,
+ IN gctSIZE_T Bytes,
+ IN gctPHYS_ADDR Physical,
+ IN gctPOINTER Logical,
+ IN gceKERNEL_WHERE FromWhere
+ )
+{
+ gceSTATUS status;
+ gcsHAL_INTERFACE iface;
+ gckKERNEL kernel = Event->kernel;
+
+ gcmkHEADER_ARG("Event=0x%x Bytes=%lu Physical=0x%x Logical=0x%x "
+ "FromWhere=%d",
+ Event, Bytes, Physical, Logical, FromWhere);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Event, gcvOBJ_EVENT);
+ gcmkVERIFY_ARGUMENT(Physical != gcvNULL);
+ gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
+ gcmkVERIFY_ARGUMENT(Bytes > 0);
+
+ /* Create an event. */
+ iface.command = gcvHAL_FREE_NON_PAGED_MEMORY;
+ iface.u.FreeNonPagedMemory.bytes = Bytes;
+ iface.u.FreeNonPagedMemory.physical = gcmPTR_TO_NAME(Physical);
+ iface.u.FreeNonPagedMemory.logical = gcmPTR_TO_UINT64(Logical);
+
+ /* Append it to the queue. */
+ gcmkONERROR(gckEVENT_AddList(Event, &iface, FromWhere, gcvFALSE, gcvTRUE));
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+gceSTATUS
+gckEVENT_DestroyVirtualCommandBuffer(
+ IN gckEVENT Event,
+ IN gctSIZE_T Bytes,
+ IN gctPHYS_ADDR Physical,
+ IN gctPOINTER Logical,
+ IN gceKERNEL_WHERE FromWhere
+ )
+{
+ gceSTATUS status;
+ gcsHAL_INTERFACE iface;
+ gckKERNEL kernel = Event->kernel;
+
+ gcmkHEADER_ARG("Event=0x%x Bytes=%lu Physical=0x%x Logical=0x%x "
+ "FromWhere=%d",
+ Event, Bytes, Physical, Logical, FromWhere);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Event, gcvOBJ_EVENT);
+ gcmkVERIFY_ARGUMENT(Physical != gcvNULL);
+ gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
+ gcmkVERIFY_ARGUMENT(Bytes > 0);
+
+ /* Create an event. */
+ iface.command = gcvHAL_FREE_VIRTUAL_COMMAND_BUFFER;
+ iface.u.FreeVirtualCommandBuffer.bytes = Bytes;
+ iface.u.FreeVirtualCommandBuffer.physical = gcmPTR_TO_NAME(Physical);
+ iface.u.FreeVirtualCommandBuffer.logical = gcmPTR_TO_UINT64(Logical);
+
+ /* Append it to the queue. */
+ gcmkONERROR(gckEVENT_AddList(Event, &iface, FromWhere, gcvFALSE, gcvTRUE));
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+/*******************************************************************************
+**
+** gckEVENT_FreeContigiuousMemory
+**
+** Schedule an event to free contiguous memory.
+**
+** INPUT:
+**
+** gckEVENT Event
+** Pointer to an gckEVENT object.
+**
+** gctSIZE_T Bytes
+** Number of bytes of contiguous memory to free.
+**
+** gctPHYS_ADDR Physical
+** Physical address of contiguous memory to free.
+**
+** gctPOINTER Logical
+** Logical address of contiguous memory to free.
+**
+** gceKERNEL_WHERE FromWhere
+** Place in the pipe where the event needs to be generated.
+*/
+gceSTATUS
+gckEVENT_FreeContiguousMemory(
+ IN gckEVENT Event,
+ IN gctSIZE_T Bytes,
+ IN gctPHYS_ADDR Physical,
+ IN gctPOINTER Logical,
+ IN gceKERNEL_WHERE FromWhere
+ )
+{
+ gceSTATUS status;
+ gcsHAL_INTERFACE iface;
+ gckKERNEL kernel = Event->kernel;
+
+ gcmkHEADER_ARG("Event=0x%x Bytes=%lu Physical=0x%x Logical=0x%x "
+ "FromWhere=%d",
+ Event, Bytes, Physical, Logical, FromWhere);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Event, gcvOBJ_EVENT);
+ gcmkVERIFY_ARGUMENT(Physical != gcvNULL);
+ gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
+ gcmkVERIFY_ARGUMENT(Bytes > 0);
+
+ /* Create an event. */
+ iface.command = gcvHAL_FREE_CONTIGUOUS_MEMORY;
+ iface.u.FreeContiguousMemory.bytes = Bytes;
+ iface.u.FreeContiguousMemory.physical = gcmPTR_TO_NAME(Physical);
+ iface.u.FreeContiguousMemory.logical = gcmPTR_TO_UINT64(Logical);
+
+ /* Append it to the queue. */
+ gcmkONERROR(gckEVENT_AddList(Event, &iface, FromWhere, gcvFALSE, gcvTRUE));
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+/*******************************************************************************
+**
+** gckEVENT_Signal
+**
+** Schedule an event to trigger a signal.
+**
+** INPUT:
+**
+** gckEVENT Event
+** Pointer to an gckEVENT object.
+**
+** gctSIGNAL Signal
+** Pointer to the signal to trigger.
+**
+** gceKERNEL_WHERE FromWhere
+** Place in the pipe where the event needs to be generated.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckEVENT_Signal(
+ IN gckEVENT Event,
+ IN gctSIGNAL Signal,
+ IN gceKERNEL_WHERE FromWhere
+ )
+{
+ gceSTATUS status;
+ gcsHAL_INTERFACE iface;
+
+ gcmkHEADER_ARG("Event=0x%x Signal=0x%x FromWhere=%d",
+ Event, Signal, FromWhere);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Event, gcvOBJ_EVENT);
+ gcmkVERIFY_ARGUMENT(Signal != gcvNULL);
+
+ /* Mark the event as a signal. */
+ iface.command = gcvHAL_SIGNAL;
+ iface.u.Signal.signal = gcmPTR_TO_UINT64(Signal);
+ iface.u.Signal.auxSignal = 0;
+ iface.u.Signal.process = 0;
+
+#ifdef __QNXNTO__
+ iface.u.Signal.coid = 0;
+ iface.u.Signal.rcvid = 0;
+
+ gcmkONERROR(gckOS_SignalPending(Event->os, Signal));
+#endif
+
+ /* Append it to the queue. */
+ gcmkONERROR(gckEVENT_AddList(Event, &iface, FromWhere, gcvFALSE, gcvTRUE));
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+#if gcdPROCESS_ADDRESS_SPACE
+gceSTATUS
+gckEVENT_DestroyMmu(
+ IN gckEVENT Event,
+ IN gckMMU Mmu,
+ IN gceKERNEL_WHERE FromWhere
+ )
+{
+ gceSTATUS status;
+ gcsHAL_INTERFACE iface;
+
+ gcmkHEADER_ARG("Event=0x%x FromWhere=%d", Event, FromWhere);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Event, gcvOBJ_EVENT);
+
+ iface.command = gcvHAL_DESTROY_MMU;
+ iface.u.DestroyMmu.mmu = gcmPTR_TO_UINT64(Mmu);
+
+ /* Append it to the queue. */
+ gcmkONERROR(gckEVENT_AddList(Event, &iface, FromWhere, gcvFALSE, gcvTRUE));
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+#endif
+
+gceSTATUS
+gckEVENT_SubmitAsync(
+ IN gckEVENT Event,
+ IN gctBOOL Wait,
+ IN gctBOOL FromPower
+ )
+{
+ gceSTATUS status;
+ gctUINT8 id = 0xFF;
+ gcsEVENT_QUEUE_PTR queue;
+ gctBOOL acquired = gcvFALSE;
+ gctBOOL commitEntered = gcvFALSE;
+ gctUINT32 start, end;
+ gctUINT8_PTR startLogical;
+ gctUINT32 eventBytes;
+
+ gckHARDWARE hardware;
+ gckASYNC_COMMAND asyncCommand;
+
+ gcmkHEADER_ARG("Event=0x%x Wait=%d", Event, Wait);
+
+ /* Get gckCOMMAND object. */
+ hardware = Event->kernel->hardware;
+ asyncCommand = Event->asyncCommand;
+
+ gcmkVERIFY_OBJECT(hardware, gcvOBJ_HARDWARE);
+
+ /* Are there event queues? */
+ if (Event->queueHead != gcvNULL)
+ {
+ /* Acquire the command queue. */
+ gcmkONERROR(gckASYNC_COMMAND_EnterCommit(asyncCommand));
+ commitEntered = gcvTRUE;
+
+ /* Process all queues. */
+ while (Event->queueHead != gcvNULL)
+ {
+ /* Acquire the list mutex. */
+ gcmkONERROR(gckOS_AcquireMutex(Event->os,
+ Event->eventListMutex,
+ gcvINFINITE));
+ acquired = gcvTRUE;
+
+ /* Get the current queue. */
+ queue = Event->queueHead;
+
+ /* Allocate an event ID. */
+ gcmkONERROR(gckEVENT_GetEvent(Event, Wait, &id, queue->source));
+
+ /* Copy event list to event ID queue. */
+ Event->queues[id].head = queue->head;
+
+ /* Remove the top queue from the list. */
+ if (Event->queueHead == Event->queueTail)
+ {
+ Event->queueHead = gcvNULL;
+ Event->queueTail = gcvNULL;
+ }
+ else
+ {
+ Event->queueHead = Event->queueHead->next;
+ }
+
+ /* Free the queue. */
+ gcmkONERROR(gckEVENT_FreeQueue(Event, queue));
+
+ /* Release the list mutex. */
+ gcmkONERROR(gckOS_ReleaseMutex(Event->os, Event->eventListMutex));
+ acquired = gcvFALSE;
+
+ gcmkONERROR(gckHARDWARE_Event(Event->kernel->hardware, gcvNULL, id, gcvKERNEL_BLT, &eventBytes));
+
+ /* Get command sequence. */
+ start = hardware->functions[gcvHARDWARE_FUNCTION_BLT_EVENT].address + id * eventBytes;
+ end = start + 24;
+
+ startLogical = hardware->functions[gcvHARDWARE_FUNCTION_BLT_EVENT].logical + id * eventBytes;
+
+ gcmkDUMPCOMMAND(
+ Event->os,
+ startLogical,
+ end - start,
+ gcvDUMP_BUFFER_KERNEL,
+ gcvFALSE
+ );
+
+ gcmkONERROR(gckASYNC_COMMAND_Execute(asyncCommand, start, end));
+ }
+
+ /* Release the command queue. */
+ gcmkONERROR(gckASYNC_COMMAND_ExitCommit(asyncCommand));
+ }
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ if (acquired)
+ {
+ /* Need to unroll the mutex acquire. */
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(Event->os, Event->eventListMutex));
+ }
+
+ if (commitEntered)
+ {
+ /* Release the command queue mutex. */
+ gcmkVERIFY_OK(gckASYNC_COMMAND_ExitCommit(asyncCommand));
+ }
+
+ if (id != 0xFF)
+ {
+ /* Need to unroll the event allocation. */
+ Event->queues[id].head = gcvNULL;
+ }
+
+ if (status == gcvSTATUS_GPU_NOT_RESPONDING)
+ {
+ /* Broadcast GPU stuck. */
+ status = gckOS_Broadcast(Event->os,
+ Event->kernel->hardware,
+ gcvBROADCAST_GPU_STUCK);
+ }
+
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+/*******************************************************************************
+**
+** gckEVENT_Submit
+**
+** Submit the current event queue to the GPU.
+**
+** INPUT:
+**
+** gckEVENT Event
+** Pointer to an gckEVENT object.
+**
+** gctBOOL Wait
+** Submit requires one vacant event; if Wait is set to not zero,
+** and there are no vacant events at this time, the function will
+** wait until an event becomes vacant so that submission of the
+** queue is successful.
+**
+** gctBOOL FromPower
+** Determines whether the call originates from inside the power
+** management or not.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckEVENT_Submit(
+ IN gckEVENT Event,
+ IN gctBOOL Wait,
+ IN gctBOOL FromPower
+ )
+{
+ gceSTATUS status;
+ gctUINT8 id = 0xFF;
+ gcsEVENT_QUEUE_PTR queue;
+ gctBOOL acquired = gcvFALSE;
+ gckCOMMAND command = gcvNULL;
+ gctBOOL commitEntered = gcvFALSE;
+#if !gcdNULL_DRIVER
+ gctUINT32 bytes;
+ gctPOINTER buffer;
+ gctUINT32 executeBytes;
+ gctUINT32 flushBytes;
+#endif
+
+#if gcdINTERRUPT_STATISTIC
+ gctINT32 oldValue;
+#endif
+
+#if gcdSECURITY
+ gctPOINTER reservedBuffer;
+#endif
+
+ gckHARDWARE hardware;
+
+ gceKERNEL_FLUSH flush = gcvFALSE;
+ gctUINT64 commitStamp;
+
+ gcmkHEADER_ARG("Event=0x%x Wait=%d", Event, Wait);
+
+ /* Get gckCOMMAND object. */
+ command = Event->kernel->command;
+ hardware = Event->kernel->hardware;
+
+ gcmkVERIFY_OBJECT(hardware, gcvOBJ_HARDWARE);
+
+ if (Event->asyncCommand)
+ {
+ /* Call async submit path. */
+ gcmkONERROR(gckEVENT_SubmitAsync(Event, Wait, FromPower));
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+ }
+
+ gckOS_GetTicks(&Event->lastCommitStamp);
+
+ /* Are there event queues? */
+ if (Event->queueHead != gcvNULL)
+ {
+ /* Acquire the command queue. */
+ gcmkONERROR(gckCOMMAND_EnterCommit(command, FromPower));
+ commitEntered = gcvTRUE;
+
+ /* Get current commit stamp. */
+ commitStamp = Event->kernel->command->commitStamp;
+
+ if (commitStamp)
+ {
+ commitStamp -= 1;
+ }
+
+ /* Process all queues. */
+ while (Event->queueHead != gcvNULL)
+ {
+ /* Acquire the list mutex. */
+ gcmkONERROR(gckOS_AcquireMutex(Event->os,
+ Event->eventListMutex,
+ gcvINFINITE));
+ acquired = gcvTRUE;
+
+ /* Get the current queue. */
+ queue = Event->queueHead;
+
+ /* Allocate an event ID. */
+ gcmkONERROR(gckEVENT_GetEvent(Event, Wait, &id, queue->source));
+
+ /* Copy event list to event ID queue. */
+ Event->queues[id].head = queue->head;
+
+ /* Update current commit stamp. */
+ Event->queues[id].commitStamp = commitStamp;
+
+ /* Remove the top queue from the list. */
+ if (Event->queueHead == Event->queueTail)
+ {
+ Event->queueHead = gcvNULL;
+ Event->queueTail = gcvNULL;
+ }
+ else
+ {
+ Event->queueHead = Event->queueHead->next;
+ }
+
+ /* Free the queue. */
+ gcmkONERROR(gckEVENT_FreeQueue(Event, queue));
+
+ /* Release the list mutex. */
+ gcmkONERROR(gckOS_ReleaseMutex(Event->os, Event->eventListMutex));
+ acquired = gcvFALSE;
+
+ /* Determine cache needed to flush. */
+ gcmkVERIFY_OK(_QueryFlush(Event, Event->queues[id].head, &flush));
+
+#if gcdNULL_DRIVER
+#if gcdINTERRUPT_STATISTIC
+ gcmkVERIFY_OK(gckOS_AtomIncrement(
+ Event->os,
+ Event->interruptCount,
+ &oldValue
+ ));
+#endif
+
+ /* Notify immediately on infinite hardware. */
+ gcmkONERROR(gckEVENT_Interrupt(Event, 1 << id));
+
+ gcmkONERROR(gckEVENT_Notify(Event, 0));
+#else
+ /* Get the size of the hardware event. */
+ gcmkONERROR(gckHARDWARE_Event(
+ hardware,
+ gcvNULL,
+ id,
+ Event->queues[id].source,
+ &bytes
+ ));
+
+ /* Get the size of flush command. */
+ gcmkONERROR(gckHARDWARE_Flush(
+ hardware,
+ flush,
+ gcvNULL,
+ &flushBytes
+ ));
+
+ bytes += flushBytes;
+
+ /* Total bytes need to execute. */
+ executeBytes = bytes;
+
+ /* Reserve space in the command queue. */
+ gcmkONERROR(gckCOMMAND_Reserve(command, bytes, &buffer, &bytes));
+#if gcdSECURITY
+ reservedBuffer = buffer;
+#endif
+
+ /* Set the flush in the command queue. */
+ gcmkONERROR(gckHARDWARE_Flush(
+ hardware,
+ flush,
+ buffer,
+ &flushBytes
+ ));
+
+ /* Advance to next command. */
+ buffer = (gctUINT8_PTR)buffer + flushBytes;
+
+ /* Set the hardware event in the command queue. */
+ gcmkONERROR(gckHARDWARE_Event(
+ hardware,
+ buffer,
+ id,
+ Event->queues[id].source,
+ &bytes
+ ));
+
+ /* Advance to next command. */
+ buffer = (gctUINT8_PTR)buffer + bytes;
+
+#if gcdINTERRUPT_STATISTIC
+ gcmkVERIFY_OK(gckOS_AtomIncrement(
+ Event->os,
+ Event->interruptCount,
+ &oldValue
+ ));
+#endif
+
+#if gcdSECURITY
+ gckKERNEL_SecurityExecute(
+ Event->kernel,
+ reservedBuffer,
+ executeBytes
+ );
+#else
+ /* Execute the hardware event. */
+ gcmkONERROR(gckCOMMAND_Execute(command, executeBytes));
+#endif
+#endif
+ }
+
+ /* Release the command queue. */
+ gcmkONERROR(gckCOMMAND_ExitCommit(command, FromPower));
+
+#if !gcdNULL_DRIVER
+ if (!FromPower)
+ {
+ gcmkVERIFY_OK(_TryToIdleGPU(Event));
+ }
+#endif
+ }
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ if (acquired)
+ {
+ /* Need to unroll the mutex acquire. */
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(Event->os, Event->eventListMutex));
+ }
+
+ if (commitEntered)
+ {
+ /* Release the command queue mutex. */
+ gcmkVERIFY_OK(gckCOMMAND_ExitCommit(command, FromPower));
+ }
+
+ if (id != 0xFF)
+ {
+ /* Need to unroll the event allocation. */
+ Event->queues[id].head = gcvNULL;
+ }
+
+ if (status == gcvSTATUS_GPU_NOT_RESPONDING)
+ {
+ /* Broadcast GPU stuck. */
+ status = gckOS_Broadcast(Event->os,
+ Event->kernel->hardware,
+ gcvBROADCAST_GPU_STUCK);
+ }
+
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+/*******************************************************************************
+**
+** gckEVENT_Commit
+**
+** Commit an event queue from the user.
+**
+** INPUT:
+**
+** gckEVENT Event
+** Pointer to an gckEVENT object.
+**
+** gcsQUEUE_PTR Queue
+** User event queue.
+**
+** gctBOOL Forced
+** Force fire a event. There won't be interrupt if there's no events
+ queued. Force a event by append a dummy one if this parameter is on.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckEVENT_Commit(
+ IN gckEVENT Event,
+ IN gcsQUEUE_PTR Queue,
+ IN gctBOOL Forced
+ )
+{
+ gceSTATUS status;
+ gcsQUEUE_PTR record = gcvNULL, next;
+ gctUINT32 processID;
+ gctBOOL needCopy = gcvFALSE;
+ gctPOINTER pointer = gcvNULL;
+
+ gcmkHEADER_ARG("Event=0x%x Queue=0x%x", Event, Queue);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Event, gcvOBJ_EVENT);
+
+ /* Get the current process ID. */
+ gcmkONERROR(gckOS_GetProcessID(&processID));
+
+ /* Query if we need to copy the client data. */
+ gcmkONERROR(gckOS_QueryNeedCopy(Event->os, processID, &needCopy));
+
+ /* Loop while there are records in the queue. */
+ while (Queue != gcvNULL)
+ {
+ gcsQUEUE queue;
+
+ if (needCopy)
+ {
+ /* Point to stack record. */
+ record = &queue;
+
+ /* Copy the data from the client. */
+ gcmkONERROR(gckOS_CopyFromUserData(Event->os,
+ record,
+ Queue,
+ gcmSIZEOF(gcsQUEUE)));
+ }
+ else
+ {
+
+ /* Map record into kernel memory. */
+ gcmkONERROR(gckOS_MapUserPointer(Event->os,
+ Queue,
+ gcmSIZEOF(gcsQUEUE),
+ &pointer));
+
+ record = pointer;
+ }
+
+ /* Append event record to event queue. */
+ gcmkONERROR(
+ gckEVENT_AddList(Event, &record->iface, gcvKERNEL_PIXEL, gcvTRUE, gcvFALSE));
+
+ /* Next record in the queue. */
+ next = gcmUINT64_TO_PTR(record->next);
+
+ if (!needCopy)
+ {
+ /* Unmap record from kernel memory. */
+ gcmkONERROR(
+ gckOS_UnmapUserPointer(Event->os,
+ Queue,
+ gcmSIZEOF(gcsQUEUE),
+ (gctPOINTER *) record));
+ record = gcvNULL;
+ }
+
+ Queue = next;
+ }
+
+ if (Forced && Event->queueHead == gcvNULL)
+ {
+ gcsHAL_INTERFACE iface;
+ iface.command = gcvHAL_COMMIT_DONE;
+
+ gcmkONERROR(gckEVENT_AddList(Event, &iface, gcvKERNEL_PIXEL, gcvFALSE, gcvTRUE));
+ }
+
+ /* Submit the event list. */
+ gcmkONERROR(gckEVENT_Submit(Event, gcvTRUE, gcvFALSE));
+
+ /* Success */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ if (pointer)
+ {
+ /* Roll back. */
+ gcmkVERIFY_OK(gckOS_UnmapUserPointer(Event->os,
+ Queue,
+ gcmSIZEOF(gcsQUEUE),
+ (gctPOINTER*)pointer));
+ }
+
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+/*******************************************************************************
+**
+** gckEVENT_Interrupt
+**
+** Called by the interrupt service routine to store the triggered interrupt
+** mask to be later processed by gckEVENT_Notify.
+**
+** INPUT:
+**
+** gckEVENT Event
+** Pointer to an gckEVENT object.
+**
+** gctUINT32 Data
+** Mask for the 32 interrupts.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckEVENT_Interrupt(
+ IN gckEVENT Event,
+ IN gctUINT32 Data
+ )
+{
+ /* Combine current interrupt status with pending flags. */
+ gckOS_AtomSetMask(Event->pending, Data);
+
+#if gcdINTERRUPT_STATISTIC
+ {
+ gctINT j = 0;
+ gctINT32 oldValue;
+
+ for (j = 0; j < gcmCOUNTOF(Event->queues); j++)
+ {
+ if ((Data & (1 << j)))
+ {
+ gckOS_AtomDecrement(
+ Event->os,
+ Event->interruptCount,
+ &oldValue
+ );
+ }
+ }
+ }
+#endif
+
+ /* Success. */
+ return gcvSTATUS_OK;
+}
+
+/*******************************************************************************
+**
+** gckEVENT_Notify
+**
+** Process all triggered interrupts.
+**
+** INPUT:
+**
+** gckEVENT Event
+** Pointer to an gckEVENT object.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckEVENT_Notify(
+ IN gckEVENT Event,
+ IN gctUINT32 IDs
+ )
+{
+ gceSTATUS status = gcvSTATUS_OK;
+ gctINT i;
+ gcsEVENT_QUEUE * queue;
+ gctUINT mask = 0;
+ gctBOOL acquired = gcvFALSE;
+ gctSIGNAL signal;
+ gctUINT pending = 0;
+ gckKERNEL kernel = Event->kernel;
+
+#if gcmIS_DEBUG(gcdDEBUG_TRACE)
+ gctINT eventNumber = 0;
+#endif
+#if gcdSECURE_USER
+ gcskSECURE_CACHE_PTR cache;
+ gcuVIDMEM_NODE_PTR node;
+#endif
+ gckVIDMEM_NODE nodeObject;
+
+ gcmkHEADER_ARG("Event=0x%x IDs=0x%x", Event, IDs);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Event, gcvOBJ_EVENT);
+
+ gcmDEBUG_ONLY(
+ if (IDs != 0)
+ {
+ for (i = 0; i < gcmCOUNTOF(Event->queues); ++i)
+ {
+ if (Event->queues[i].head != gcvNULL)
+ {
+ gcmkTRACE_ZONE(gcvLEVEL_VERBOSE, gcvZONE_EVENT,
+ "Queue(%d): stamp=%llu source=%d",
+ i,
+ Event->queues[i].stamp,
+ Event->queues[i].source);
+ }
+ }
+ }
+ );
+
+ /* Begin of event handling. */
+ Event->notifyState = 0;
+
+ for (;;)
+ {
+ gcsEVENT_PTR record;
+
+ /* Grab the mutex queue. */
+ gcmkONERROR(gckOS_AcquireMutex(Event->os,
+ Event->eventQueueMutex,
+ gcvINFINITE));
+ acquired = gcvTRUE;
+
+ gckOS_AtomGet(Event->os, Event->pending, (gctINT32_PTR)&pending);
+
+ if (pending == 0)
+ {
+ /* Release the mutex queue. */
+ gcmkONERROR(gckOS_ReleaseMutex(Event->os, Event->eventQueueMutex));
+ acquired = gcvFALSE;
+
+ /* No more pending interrupts - done. */
+ break;
+ }
+
+ if (pending & 0x80000000)
+ {
+ gcmkPRINT("AXI BUS ERROR");
+ gckHARDWARE_DumpGPUState(Event->kernel->hardware);
+ pending &= 0x7FFFFFFF;
+ }
+
+ if ((pending & 0x40000000) && Event->kernel->hardware->mmuVersion)
+ {
+#if gcdUSE_MMU_EXCEPTION
+#if gcdALLOC_ON_FAULT
+ status = gckHARDWARE_HandleFault(Event->kernel->hardware);
+#endif
+ if (gcmIS_ERROR(status))
+ {
+ /* Dump error is fault can't be handle. */
+ gckHARDWARE_DumpMMUException(Event->kernel->hardware);
+
+ gckHARDWARE_DumpGPUState(Event->kernel->hardware);
+ }
+#endif
+
+ pending &= 0xBFFFFFFF;
+ }
+
+ gcmkTRACE_ZONE_N(
+ gcvLEVEL_INFO, gcvZONE_EVENT,
+ gcmSIZEOF(pending),
+ "Pending interrupts 0x%x",
+ pending
+ );
+
+ queue = gcvNULL;
+
+ gcmDEBUG_ONLY(
+ if (IDs == 0)
+ {
+ for (i = 0; i < gcmCOUNTOF(Event->queues); ++i)
+ {
+ if (Event->queues[i].head != gcvNULL)
+ {
+ gcmkTRACE_ZONE(gcvLEVEL_VERBOSE, gcvZONE_EVENT,
+ "Queue(%d): stamp=%llu source=%d",
+ i,
+ Event->queues[i].stamp,
+ Event->queues[i].source);
+ }
+ }
+ }
+ );
+
+ /* Find the oldest pending interrupt. */
+ for (i = 0; i < gcmCOUNTOF(Event->queues); ++i)
+ {
+ if ((Event->queues[i].head != gcvNULL)
+ && (pending & (1 << i))
+ )
+ {
+ if ((queue == gcvNULL)
+ || (Event->queues[i].stamp < queue->stamp)
+ )
+ {
+ queue = &Event->queues[i];
+ mask = 1 << i;
+#if gcmIS_DEBUG(gcdDEBUG_TRACE)
+ eventNumber = i;
+#endif
+ }
+ }
+ }
+
+ if (queue == gcvNULL)
+ {
+ gcmkTRACE_ZONE_N(
+ gcvLEVEL_ERROR, gcvZONE_EVENT,
+ gcmSIZEOF(pending),
+ "Interrupts 0x%x are not pending.",
+ pending
+ );
+
+ gckOS_AtomClearMask(Event->pending, pending);
+
+ /* Release the mutex queue. */
+ gcmkONERROR(gckOS_ReleaseMutex(Event->os, Event->eventQueueMutex));
+ acquired = gcvFALSE;
+ break;
+ }
+
+ /* Check whether there is a missed interrupt. */
+ for (i = 0; i < gcmCOUNTOF(Event->queues); ++i)
+ {
+ if ((Event->queues[i].head != gcvNULL)
+ && (Event->queues[i].stamp < queue->stamp)
+ && (Event->queues[i].source <= queue->source)
+ )
+ {
+ gcmkTRACE_N(
+ gcvLEVEL_ERROR,
+ gcmSIZEOF(i) + gcmSIZEOF(Event->queues[i].stamp),
+ "Event %d lost (stamp %llu)",
+ i, Event->queues[i].stamp
+ );
+
+ /* Use this event instead. */
+ queue = &Event->queues[i];
+ mask = 0;
+ }
+ }
+
+ if (mask != 0)
+ {
+#if gcmIS_DEBUG(gcdDEBUG_TRACE)
+ gcmkTRACE_ZONE_N(
+ gcvLEVEL_INFO, gcvZONE_EVENT,
+ gcmSIZEOF(eventNumber),
+ "Processing interrupt %d",
+ eventNumber
+ );
+#endif
+ }
+
+ gckOS_AtomClearMask(Event->pending, mask);
+
+ if (!gckHARDWARE_IsFeatureAvailable(Event->kernel->hardware, gcvFEATURE_FENCE_64BIT))
+ {
+ /* Write out commit stamp.*/
+ *(gctUINT64 *)(Event->kernel->command->fence->logical) = queue->commitStamp;
+ }
+
+ /* Signal clients waiting for fence. */
+ gcmkVERIFY_OK(gckFENCE_Signal(
+ Event->os,
+ Event->kernel->command->fence
+ ));
+
+ /* Grab the event head. */
+ record = queue->head;
+
+ /* Now quickly clear its event list. */
+ queue->head = gcvNULL;
+
+ /* Increase the number of free events. */
+ Event->freeQueueCount++;
+
+ /* Release the mutex queue. */
+ gcmkONERROR(gckOS_ReleaseMutex(Event->os, Event->eventQueueMutex));
+ acquired = gcvFALSE;
+
+ /* Walk all events for this interrupt. */
+ while (record != gcvNULL)
+ {
+ gcsEVENT_PTR recordNext;
+#ifndef __QNXNTO__
+ gctPOINTER logical;
+#endif
+#if gcdSECURE_USER
+ gctSIZE_T bytes;
+#endif
+
+ /* Grab next record. */
+ recordNext = record->next;
+
+#ifdef __QNXNTO__
+ /*
+ * Assign record->processID as the pid for this galcore thread.
+ * Used in the OS calls which do not take a pid.
+ */
+ drv_thread_specific_key_assign(record->processID, 0);
+#endif
+
+#if gcdSECURE_USER
+ /* Get the cache that belongs to this process. */
+ gcmkONERROR(gckKERNEL_GetProcessDBCache(Event->kernel,
+ record->processID,
+ &cache));
+#endif
+
+ gcmkTRACE_ZONE_N(
+ gcvLEVEL_INFO, gcvZONE_EVENT,
+ gcmSIZEOF(record->info.command),
+ "Processing event type: %d",
+ record->info.command
+ );
+
+ switch (record->info.command)
+ {
+ case gcvHAL_FREE_NON_PAGED_MEMORY:
+ gcmkTRACE_ZONE(gcvLEVEL_VERBOSE, gcvZONE_EVENT,
+ "gcvHAL_FREE_NON_PAGED_MEMORY: 0x%x",
+ gcmNAME_TO_PTR(record->info.u.FreeNonPagedMemory.physical));
+
+ /* Free non-paged memory. */
+ status = gckOS_FreeNonPagedMemory(
+ Event->os,
+ (gctSIZE_T) record->info.u.FreeNonPagedMemory.bytes,
+ gcmNAME_TO_PTR(record->info.u.FreeNonPagedMemory.physical),
+ gcmUINT64_TO_PTR(record->info.u.FreeNonPagedMemory.logical));
+
+ if (gcmIS_SUCCESS(status))
+ {
+#if gcdSECURE_USER
+ gcmkVERIFY_OK(gckKERNEL_FlushTranslationCache(
+ Event->kernel,
+ cache,
+ gcmUINT64_TO_PTR(record->record.u.FreeNonPagedMemory.logical),
+ (gctSIZE_T) record->record.u.FreeNonPagedMemory.bytes));
+#endif
+ }
+ gcmRELEASE_NAME(record->info.u.FreeNonPagedMemory.physical);
+ break;
+
+ case gcvHAL_FREE_CONTIGUOUS_MEMORY:
+ gcmkTRACE_ZONE(
+ gcvLEVEL_VERBOSE, gcvZONE_EVENT,
+ "gcvHAL_FREE_CONTIGUOUS_MEMORY: 0x%x",
+ gcmNAME_TO_PTR(record->info.u.FreeContiguousMemory.physical));
+
+ /* Unmap the user memory. */
+ status = gckOS_FreeContiguous(
+ Event->os,
+ gcmNAME_TO_PTR(record->info.u.FreeContiguousMemory.physical),
+ gcmUINT64_TO_PTR(record->info.u.FreeContiguousMemory.logical),
+ (gctSIZE_T) record->info.u.FreeContiguousMemory.bytes);
+
+ if (gcmIS_SUCCESS(status))
+ {
+#if gcdSECURE_USER
+ gcmkVERIFY_OK(gckKERNEL_FlushTranslationCache(
+ Event->kernel,
+ cache,
+ gcmUINT64_TO_PTR(event->event.u.FreeContiguousMemory.logical),
+ (gctSIZE_T) event->event.u.FreeContiguousMemory.bytes));
+#endif
+ }
+ gcmRELEASE_NAME(record->info.u.FreeContiguousMemory.physical);
+ break;
+
+ case gcvHAL_WRITE_DATA:
+#ifndef __QNXNTO__
+ /* Convert physical into logical address. */
+ gcmkERR_BREAK(
+ gckOS_MapPhysical(Event->os,
+ record->info.u.WriteData.address,
+ gcmSIZEOF(gctUINT32),
+ &logical));
+
+ /* Write data. */
+ gcmkERR_BREAK(
+ gckOS_WriteMemory(Event->os,
+ logical,
+ record->info.u.WriteData.data));
+
+ /* Unmap the physical memory. */
+ gcmkERR_BREAK(
+ gckOS_UnmapPhysical(Event->os,
+ logical,
+ gcmSIZEOF(gctUINT32)));
+#else
+ /* Write data. */
+ gcmkERR_BREAK(
+ gckOS_WriteMemory(Event->os,
+ gcmUINT64_TO_PTR(record->info.u.WriteData.address),
+ record->info.u.WriteData.data));
+#endif
+ break;
+
+ case gcvHAL_UNLOCK_VIDEO_MEMORY:
+ gcmkTRACE_ZONE(gcvLEVEL_VERBOSE, gcvZONE_EVENT,
+ "gcvHAL_UNLOCK_VIDEO_MEMORY: 0x%x",
+ record->info.u.UnlockVideoMemory.node);
+
+ nodeObject = gcmUINT64_TO_PTR(record->info.u.UnlockVideoMemory.node);
+
+#if gcdSECURE_USER
+ node = nodeObject->node;
+
+ /* Save node information before it disappears. */
+ node = event->event.u.UnlockVideoMemory.node;
+ if (node->VidMem.memory->object.type == gcvOBJ_VIDMEM)
+ {
+ logical = gcvNULL;
+ bytes = 0;
+ }
+ else
+ {
+ logical = node->Virtual.logical;
+ bytes = node->Virtual.bytes;
+ }
+#endif
+
+ /* Unlock. */
+ status = gckVIDMEM_Unlock(
+ Event->kernel,
+ nodeObject,
+ record->info.u.UnlockVideoMemory.type,
+ gcvNULL);
+
+#if gcdSECURE_USER
+ if (gcmIS_SUCCESS(status) && (logical != gcvNULL))
+ {
+ gcmkVERIFY_OK(gckKERNEL_FlushTranslationCache(
+ Event->kernel,
+ cache,
+ logical,
+ bytes));
+ }
+#endif
+
+#if gcdPROCESS_ADDRESS_SPACE
+ gcmkVERIFY_OK(gckVIDMEM_NODE_Unlock(
+ Event->kernel,
+ nodeObject,
+ record->processID
+ ));
+#endif
+
+ status = gckVIDMEM_NODE_Dereference(Event->kernel, nodeObject);
+ break;
+
+ case gcvHAL_SIGNAL:
+ signal = gcmUINT64_TO_PTR(record->info.u.Signal.signal);
+ gcmkTRACE_ZONE(gcvLEVEL_VERBOSE, gcvZONE_EVENT,
+ "gcvHAL_SIGNAL: 0x%x",
+ signal);
+
+#ifdef __QNXNTO__
+ if ((record->info.u.Signal.coid == 0)
+ && (record->info.u.Signal.rcvid == 0)
+ )
+ {
+ /* Kernel signal. */
+ gcmkERR_BREAK(
+ gckOS_SignalPulse(Event->os,
+ signal));
+ }
+ else
+ {
+ /* User signal. */
+ gcmkERR_BREAK(
+ gckOS_UserSignal(Event->os,
+ signal,
+ record->info.u.Signal.rcvid,
+ record->info.u.Signal.coid));
+ }
+#else
+ /* Set signal. */
+ if (gcmUINT64_TO_PTR(record->info.u.Signal.process) == gcvNULL)
+ {
+ /* Kernel signal. */
+ gcmkERR_BREAK(
+ gckOS_Signal(Event->os,
+ signal,
+ gcvTRUE));
+ }
+ else
+ {
+ /* User signal. */
+ gcmkERR_BREAK(
+ gckOS_UserSignal(Event->os,
+ signal,
+ gcmUINT64_TO_PTR(record->info.u.Signal.process)));
+ }
+
+ gcmkASSERT(record->info.u.Signal.auxSignal == 0);
+#endif
+ break;
+
+ case gcvHAL_TIMESTAMP:
+ gcmkTRACE_ZONE(gcvLEVEL_VERBOSE, gcvZONE_EVENT,
+ "gcvHAL_TIMESTAMP: %d %d",
+ record->info.u.TimeStamp.timer,
+ record->info.u.TimeStamp.request);
+
+ /* Process the timestamp. */
+ switch (record->info.u.TimeStamp.request)
+ {
+ case 0:
+ status = gckOS_GetTime(&Event->kernel->timers[
+ record->info.u.TimeStamp.timer].
+ stopTime);
+ break;
+
+ case 1:
+ status = gckOS_GetTime(&Event->kernel->timers[
+ record->info.u.TimeStamp.timer].
+ startTime);
+ break;
+
+ default:
+ gcmkTRACE_ZONE_N(
+ gcvLEVEL_ERROR, gcvZONE_EVENT,
+ gcmSIZEOF(record->info.u.TimeStamp.request),
+ "Invalid timestamp request: %d",
+ record->info.u.TimeStamp.request
+ );
+
+ status = gcvSTATUS_INVALID_ARGUMENT;
+ break;
+ }
+ break;
+
+ case gcvHAL_FREE_VIRTUAL_COMMAND_BUFFER:
+ gcmkVERIFY_OK(
+ gckKERNEL_DestroyVirtualCommandBuffer(Event->kernel,
+ (gctSIZE_T) record->info.u.FreeVirtualCommandBuffer.bytes,
+ gcmNAME_TO_PTR(record->info.u.FreeVirtualCommandBuffer.physical),
+ gcmUINT64_TO_PTR(record->info.u.FreeVirtualCommandBuffer.logical)
+ ));
+ gcmRELEASE_NAME(record->info.u.FreeVirtualCommandBuffer.physical);
+ break;
+
+#if gcdPROCESS_ADDRESS_SPACE
+ case gcvHAL_DESTROY_MMU:
+ status = gckMMU_Destroy(gcmUINT64_TO_PTR(record->info.u.DestroyMmu.mmu));
+ break;
+#endif
+
+ case gcvHAL_COMMIT_DONE:
+ break;
+
+ default:
+ /* Invalid argument. */
+ gcmkTRACE_ZONE_N(
+ gcvLEVEL_ERROR, gcvZONE_EVENT,
+ gcmSIZEOF(record->info.command),
+ "Unknown event type: %d",
+ record->info.command
+ );
+
+ status = gcvSTATUS_INVALID_ARGUMENT;
+ break;
+ }
+
+ /* Make sure there are no errors generated. */
+ if (gcmIS_ERROR(status))
+ {
+ gcmkTRACE_ZONE_N(
+ gcvLEVEL_WARNING, gcvZONE_EVENT,
+ gcmSIZEOF(status),
+ "Event produced status: %d(%s)",
+ status, gckOS_DebugStatus2Name(status));
+ }
+
+ /* Free the event. */
+ gcmkVERIFY_OK(gckEVENT_FreeRecord(Event, record));
+
+ /* Advance to next record. */
+ record = recordNext;
+ }
+
+ gcmkTRACE_ZONE(gcvLEVEL_VERBOSE, gcvZONE_EVENT,
+ "Handled interrupt 0x%x", mask);
+ }
+
+ if (IDs == 0)
+ {
+ gcmkONERROR(_TryToIdleGPU(Event));
+ }
+
+ /* End of event handling. */
+ Event->notifyState = -1;
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ if (acquired)
+ {
+ /* Release mutex. */
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(Event->os, Event->eventQueueMutex));
+ }
+
+ /* End of event handling. */
+ Event->notifyState = -1;
+
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+/*******************************************************************************
+** gckEVENT_FreeProcess
+**
+** Free all events owned by a particular process ID.
+**
+** INPUT:
+**
+** gckEVENT Event
+** Pointer to an gckEVENT object.
+**
+** gctUINT32 ProcessID
+** Process ID of the process to be freed up.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckEVENT_FreeProcess(
+ IN gckEVENT Event,
+ IN gctUINT32 ProcessID
+ )
+{
+ gctSIZE_T i;
+ gctBOOL acquired = gcvFALSE;
+ gcsEVENT_PTR record, next;
+ gceSTATUS status;
+ gcsEVENT_PTR deleteHead, deleteTail;
+
+ gcmkHEADER_ARG("Event=0x%x ProcessID=%d", Event, ProcessID);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Event, gcvOBJ_EVENT);
+
+ /* Walk through all queues. */
+ for (i = 0; i < gcmCOUNTOF(Event->queues); ++i)
+ {
+ if (Event->queues[i].head != gcvNULL)
+ {
+ /* Grab the event queue mutex. */
+ gcmkONERROR(gckOS_AcquireMutex(Event->os,
+ Event->eventQueueMutex,
+ gcvINFINITE));
+ acquired = gcvTRUE;
+
+ /* Grab the mutex head. */
+ record = Event->queues[i].head;
+ Event->queues[i].head = gcvNULL;
+ Event->queues[i].tail = gcvNULL;
+ deleteHead = gcvNULL;
+ deleteTail = gcvNULL;
+
+ while (record != gcvNULL)
+ {
+ next = record->next;
+ if (record->processID == ProcessID)
+ {
+ if (deleteHead == gcvNULL)
+ {
+ deleteHead = record;
+ }
+ else
+ {
+ deleteTail->next = record;
+ }
+
+ deleteTail = record;
+ }
+ else
+ {
+ if (Event->queues[i].head == gcvNULL)
+ {
+ Event->queues[i].head = record;
+ }
+ else
+ {
+ Event->queues[i].tail->next = record;
+ }
+
+ Event->queues[i].tail = record;
+ }
+
+ record->next = gcvNULL;
+ record = next;
+ }
+
+ /* Release the mutex queue. */
+ gcmkONERROR(gckOS_ReleaseMutex(Event->os, Event->eventQueueMutex));
+ acquired = gcvFALSE;
+
+ /* Loop through the entire list of events. */
+ for (record = deleteHead; record != gcvNULL; record = next)
+ {
+ /* Get the next event record. */
+ next = record->next;
+
+ /* Free the event record. */
+ gcmkONERROR(gckEVENT_FreeRecord(Event, record));
+ }
+ }
+ }
+
+ gcmkONERROR(_TryToIdleGPU(Event));
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ /* Release the event queue mutex. */
+ if (acquired)
+ {
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(Event->os, Event->eventQueueMutex));
+ }
+
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+/*******************************************************************************
+** gckEVENT_Stop
+**
+** Stop the hardware using the End event mechanism.
+**
+** INPUT:
+**
+** gckEVENT Event
+** Pointer to an gckEVENT object.
+**
+** gctUINT32 ProcessID
+** Process ID Logical belongs.
+**
+** gctPHYS_ADDR Handle
+** Physical address handle. If gcvNULL it is video memory.
+**
+** gctSIZE_T Offset,
+** Offset to this memory block.
+**
+** gctPOINTER Logical
+** Logical address to flush.
+**
+** gctSIGNAL Signal
+** Pointer to the signal to trigger.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckEVENT_Stop(
+ IN gckEVENT Event,
+ IN gctUINT32 ProcessID,
+ IN gctPHYS_ADDR Handle,
+ IN gctSIZE_T Offset,
+ IN gctPOINTER Logical,
+ IN gctUINT32 Address,
+ IN gctSIGNAL Signal,
+ IN OUT gctUINT32 * waitSize
+ )
+{
+ gceSTATUS status;
+ /* gctSIZE_T waitSize;*/
+ gcsEVENT_PTR record = gcvNULL;
+ gctUINT8 id = 0xFF;
+
+ gcmkHEADER_ARG("Event=0x%x ProcessID=%u Handle=0x%x Logical=0x%x "
+ "Address=0x%x Signal=0x%x",
+ Event, ProcessID, Handle, Logical, Address, Signal);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Event, gcvOBJ_EVENT);
+
+ /* Submit the current event queue. */
+ gcmkONERROR(gckEVENT_Submit(Event, gcvTRUE, gcvFALSE));
+ gcmkONERROR(gckEVENT_GetEvent(Event, gcvTRUE, &id, gcvKERNEL_PIXEL));
+
+ /* Allocate a record. */
+ gcmkONERROR(gckEVENT_AllocateRecord(Event, gcvTRUE, &record));
+
+ /* Initialize the record. */
+ record->next = gcvNULL;
+ record->processID = ProcessID;
+ record->info.command = gcvHAL_SIGNAL;
+ record->info.u.Signal.signal = gcmPTR_TO_UINT64(Signal);
+#ifdef __QNXNTO__
+ record->info.u.Signal.coid = 0;
+ record->info.u.Signal.rcvid = 0;
+#endif
+ record->info.u.Signal.auxSignal = 0;
+ record->info.u.Signal.process = 0;
+
+ /* Append the record. */
+ Event->queues[id].head = record;
+
+ /* Replace last WAIT with END. */
+ gcmkONERROR(gckHARDWARE_End(
+ Event->kernel->hardware, Logical, Address, waitSize
+ ));
+
+#if USE_KERNEL_VIRTUAL_BUFFERS
+ if (Event->kernel->virtualCommandBuffer)
+ {
+ gcmkONERROR(gckKERNEL_GetGPUAddress(
+ Event->kernel,
+ Logical,
+ gcvFALSE,
+ Event->kernel->command->virtualMemory,
+ &Event->kernel->hardware->lastEnd
+ ));
+ }
+#endif
+
+ /* Flush the cache for the END. */
+ gcmkONERROR(gckOS_CacheClean(
+ Event->os,
+ 0,
+ Handle,
+ Offset,
+ Logical,
+ *waitSize
+ ));
+
+ /* Wait for the signal. */
+ gcmkONERROR(gckOS_WaitSignal(Event->os, Signal, gcvFALSE, gcvINFINITE));
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+static void
+_PrintRecord(
+ gcsEVENT_PTR record
+ )
+{
+ switch (record->info.command)
+ {
+ case gcvHAL_FREE_NON_PAGED_MEMORY:
+ gcmkPRINT(" gcvHAL_FREE_NON_PAGED_MEMORY");
+ break;
+
+ case gcvHAL_FREE_CONTIGUOUS_MEMORY:
+ gcmkPRINT(" gcvHAL_FREE_CONTIGUOUS_MEMORY");
+ break;
+
+ case gcvHAL_WRITE_DATA:
+ gcmkPRINT(" gcvHAL_WRITE_DATA");
+ break;
+
+ case gcvHAL_UNLOCK_VIDEO_MEMORY:
+ gcmkPRINT(" gcvHAL_UNLOCK_VIDEO_MEMORY");
+ break;
+
+ case gcvHAL_SIGNAL:
+ gcmkPRINT(" gcvHAL_SIGNAL process=%d signal=0x%x",
+ record->info.u.Signal.process,
+ record->info.u.Signal.signal);
+ break;
+
+ case gcvHAL_UNMAP_USER_MEMORY:
+ gcmkPRINT(" gcvHAL_UNMAP_USER_MEMORY");
+ break;
+
+ case gcvHAL_TIMESTAMP:
+ gcmkPRINT(" gcvHAL_TIMESTAMP");
+ break;
+
+ case gcvHAL_COMMIT_DONE:
+ gcmkPRINT(" gcvHAL_COMMIT_DONE");
+ break;
+
+ case gcvHAL_FREE_VIRTUAL_COMMAND_BUFFER:
+ gcmkPRINT(" gcvHAL_FREE_VIRTUAL_COMMAND_BUFFER logical=0x%08x",
+ record->info.u.FreeVirtualCommandBuffer.logical);
+ break;
+
+ case gcvHAL_DESTROY_MMU:
+ gcmkPRINT(" gcvHAL_DESTORY_MMU mmu=0x%08x",
+ gcmUINT64_TO_PTR(record->info.u.DestroyMmu.mmu));
+
+ break;
+ default:
+ gcmkPRINT(" Illegal Event %d", record->info.command);
+ break;
+ }
+}
+
+/*******************************************************************************
+** gckEVENT_Dump
+**
+** Dump record in event queue when stuck happens.
+** No protection for the event queue.
+**/
+gceSTATUS
+gckEVENT_Dump(
+ IN gckEVENT Event
+ )
+{
+ gcsEVENT_QUEUE_PTR queueHead = Event->queueHead;
+ gcsEVENT_QUEUE_PTR queue;
+ gcsEVENT_PTR record = gcvNULL;
+ gctINT i;
+#if gcdINTERRUPT_STATISTIC
+ gctINT32 pendingInterrupt;
+ gctUINT32 intrAcknowledge;
+#endif
+ gctINT32 pending;
+
+ gcmkHEADER_ARG("Event=0x%x", Event);
+
+ gcmkPRINT("**************************\n");
+ gcmkPRINT("*** EVENT STATE DUMP ***\n");
+ gcmkPRINT("**************************\n");
+
+ gcmkPRINT(" Unsumbitted Event:");
+ while(queueHead)
+ {
+ queue = queueHead;
+ record = queueHead->head;
+
+ gcmkPRINT(" [%x]:", queue);
+ while(record)
+ {
+ _PrintRecord(record);
+ record = record->next;
+ }
+
+ if (queueHead == Event->queueTail)
+ {
+ queueHead = gcvNULL;
+ }
+ else
+ {
+ queueHead = queueHead->next;
+ }
+ }
+
+ gcmkPRINT(" Untriggered Event:");
+ for (i = 0; i < gcmCOUNTOF(Event->queues); i++)
+ {
+ queue = &Event->queues[i];
+ record = queue->head;
+
+ gcmkPRINT(" [%d]:", i);
+ while(record)
+ {
+ _PrintRecord(record);
+ record = record->next;
+ }
+ }
+
+#if gcdINTERRUPT_STATISTIC
+ gckOS_AtomGet(Event->os, Event->interruptCount, &pendingInterrupt);
+ gcmkPRINT(" Number of Pending Interrupt: %d", pendingInterrupt);
+
+ if (Event->kernel->recovery == 0)
+ {
+ gckOS_ReadRegisterEx(
+ Event->os,
+ Event->kernel->core,
+ 0x10,
+ &intrAcknowledge
+ );
+
+ gcmkPRINT(" INTR_ACKNOWLEDGE=0x%x", intrAcknowledge);
+ }
+#endif
+
+ gcmkPRINT(" Notify State=%d", Event->notifyState);
+
+ gckOS_AtomGet(Event->os, Event->pending, &pending);
+
+ gcmkPRINT(" Pending=0x%x", pending);
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+}
diff --git a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_heap.c b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_heap.c
new file mode 100644
index 000000000000..5c4835abb3e0
--- /dev/null
+++ b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_heap.c
@@ -0,0 +1,892 @@
+/****************************************************************************
+*
+* The MIT License (MIT)
+*
+* Copyright (c) 2014 - 2018 Vivante 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 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 GPL License (GPL)
+*
+* Copyright (C) 2014 - 2018 Vivante 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.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+*****************************************************************************
+*
+* Note: This software is released under dual MIT and GPL licenses. A
+* recipient may use this file under the terms of either the MIT license or
+* GPL License. If you wish to use only one license not the other, you can
+* indicate your decision by deleting one of the above license notices in your
+* version of this file.
+*
+*****************************************************************************/
+
+
+/**
+** @file
+** gckHEAP object for kernel HAL layer. The heap implemented here is an arena-
+** based memory allocation. An arena-based memory heap allocates data quickly
+** from specified arenas and reduces memory fragmentation.
+**
+*/
+#include "gc_hal_kernel_precomp.h"
+
+#define _GC_OBJ_ZONE gcvZONE_HEAP
+
+/*******************************************************************************
+***** Structures ***************************************************************
+*******************************************************************************/
+#define gcdIN_USE ((gcskNODE_PTR)gcvMAXUINTPTR_T)
+
+typedef struct _gcskNODE * gcskNODE_PTR;
+typedef struct _gcskNODE
+{
+ /* Number of byets in node. */
+ gctSIZE_T bytes;
+
+ /* Pointer to next free node, or gcvNULL to mark the node as freed, or
+ ** gcdIN_USE to mark the node as used. */
+ gcskNODE_PTR next;
+
+#if gcmIS_DEBUG(gcdDEBUG_CODE)
+ /* Time stamp of allocation. */
+ gctUINT64 timeStamp;
+#endif
+}
+gcskNODE;
+
+typedef struct _gcskHEAP * gcskHEAP_PTR;
+typedef struct _gcskHEAP
+{
+ /* Linked list. */
+ gcskHEAP_PTR next;
+ gcskHEAP_PTR prev;
+
+ /* Heap size. */
+ gctSIZE_T size;
+
+ /* Free list. */
+ gcskNODE_PTR freeList;
+}
+gcskHEAP;
+
+struct _gckHEAP
+{
+ /* Object. */
+ gcsOBJECT object;
+
+ /* Pointer to a gckOS object. */
+ gckOS os;
+
+ /* Locking mutex. */
+ gctPOINTER mutex;
+
+ /* Allocation parameters. */
+ gctSIZE_T allocationSize;
+
+ /* Heap list. */
+ gcskHEAP_PTR heap;
+#if gcmIS_DEBUG(gcdDEBUG_CODE)
+ gctUINT64 timeStamp;
+#endif
+
+#if VIVANTE_PROFILER || gcmIS_DEBUG(gcdDEBUG_CODE)
+ /* Profile information. */
+ gctUINT32 allocCount;
+ gctUINT64 allocBytes;
+ gctUINT64 allocBytesMax;
+ gctUINT64 allocBytesTotal;
+ gctUINT32 heapCount;
+ gctUINT32 heapCountMax;
+ gctUINT64 heapMemory;
+ gctUINT64 heapMemoryMax;
+#endif
+};
+
+/*******************************************************************************
+***** Static Support Functions *************************************************
+*******************************************************************************/
+
+#if gcmIS_DEBUG(gcdDEBUG_CODE)
+static gctSIZE_T
+_DumpHeap(
+ IN gcskHEAP_PTR Heap
+ )
+{
+ gctPOINTER p;
+ gctSIZE_T leaked = 0;
+
+ /* Start at first node. */
+ for (p = Heap + 1;;)
+ {
+ /* Convert the pointer. */
+ gcskNODE_PTR node = (gcskNODE_PTR) p;
+
+ /* Check if this is a used node. */
+ if (node->next == gcdIN_USE)
+ {
+ /* Print the leaking node. */
+ gcmkTRACE_ZONE(gcvLEVEL_WARNING, gcvZONE_HEAP,
+ "Detected leaking: node=0x%x bytes=%lu timeStamp=%llu "
+ "(%08X %c%c%c%c)",
+ node, node->bytes, node->timeStamp,
+ ((gctUINT32_PTR) (node + 1))[0],
+ gcmPRINTABLE(((gctUINT8_PTR) (node + 1))[0]),
+ gcmPRINTABLE(((gctUINT8_PTR) (node + 1))[1]),
+ gcmPRINTABLE(((gctUINT8_PTR) (node + 1))[2]),
+ gcmPRINTABLE(((gctUINT8_PTR) (node + 1))[3]));
+
+ /* Add leaking byte count. */
+ leaked += node->bytes;
+ }
+
+ /* Test for end of heap. */
+ if (node->bytes == 0)
+ {
+ break;
+ }
+
+ else
+ {
+ /* Move to next node. */
+ p = (gctUINT8_PTR) node + node->bytes;
+ }
+ }
+
+ /* Return the number of leaked bytes. */
+ return leaked;
+}
+#endif
+
+static gceSTATUS
+_CompactKernelHeap(
+ IN gckHEAP Heap
+ )
+{
+ gcskHEAP_PTR heap, next;
+ gctPOINTER p;
+ gcskHEAP_PTR freeList = gcvNULL;
+
+ gcmkHEADER_ARG("Heap=0x%x", Heap);
+
+ /* Walk all the heaps. */
+ for (heap = Heap->heap; heap != gcvNULL; heap = next)
+ {
+ gcskNODE_PTR lastFree = gcvNULL;
+
+ /* Zero out the free list. */
+ heap->freeList = gcvNULL;
+
+ /* Start at the first node. */
+ for (p = (gctUINT8_PTR) (heap + 1);;)
+ {
+ /* Convert the pointer. */
+ gcskNODE_PTR node = (gcskNODE_PTR) p;
+
+ gcmkASSERT(p <= (gctPOINTER) ((gctUINT8_PTR) (heap + 1) + heap->size));
+
+ /* Test if this node not used. */
+ if (node->next != gcdIN_USE)
+ {
+ /* Test if this is the end of the heap. */
+ if (node->bytes == 0)
+ {
+ break;
+ }
+
+ /* Test of this is the first free node. */
+ else if (lastFree == gcvNULL)
+ {
+ /* Initialzie the free list. */
+ heap->freeList = node;
+ lastFree = node;
+ }
+
+ else
+ {
+ /* Test if this free node is contiguous with the previous
+ ** free node. */
+ if ((gctUINT8_PTR) lastFree + lastFree->bytes == p)
+ {
+ /* Just increase the size of the previous free node. */
+ lastFree->bytes += node->bytes;
+ }
+ else
+ {
+ /* Add to linked list. */
+ lastFree->next = node;
+ lastFree = node;
+ }
+ }
+ }
+
+ /* Move to next node. */
+ p = (gctUINT8_PTR) node + node->bytes;
+ }
+
+ /* Mark the end of the chain. */
+ if (lastFree != gcvNULL)
+ {
+ lastFree->next = gcvNULL;
+ }
+
+ /* Get next heap. */
+ next = heap->next;
+
+ /* Check if the entire heap is free. */
+ if ((heap->freeList != gcvNULL)
+ && (heap->freeList->bytes == heap->size - gcmSIZEOF(gcskNODE))
+ )
+ {
+ /* Remove the heap from the linked list. */
+ if (heap->prev == gcvNULL)
+ {
+ Heap->heap = next;
+ }
+ else
+ {
+ heap->prev->next = next;
+ }
+
+ if (heap->next != gcvNULL)
+ {
+ heap->next->prev = heap->prev;
+ }
+
+#if VIVANTE_PROFILER || gcmIS_DEBUG(gcdDEBUG_CODE)
+ /* Update profiling. */
+ Heap->heapCount -= 1;
+ Heap->heapMemory -= heap->size + gcmSIZEOF(gcskHEAP);
+#endif
+
+ /* Add this heap to the list of heaps that need to be freed. */
+ heap->next = freeList;
+ freeList = heap;
+ }
+ }
+
+ if (freeList != gcvNULL)
+ {
+ /* Release the mutex, remove any chance for a dead lock. */
+ gcmkVERIFY_OK(
+ gckOS_ReleaseMutex(Heap->os, Heap->mutex));
+
+ /* Free all heaps in the free list. */
+ for (heap = freeList; heap != gcvNULL; heap = next)
+ {
+ /* Get pointer to the next heap. */
+ next = heap->next;
+
+ /* Free the heap. */
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HEAP,
+ "Freeing heap 0x%x (%lu bytes)",
+ heap, heap->size + gcmSIZEOF(gcskHEAP));
+ gcmkVERIFY_OK(gckOS_FreeMemory(Heap->os, heap));
+ }
+
+ /* Acquire the mutex again. */
+ gcmkVERIFY_OK(
+ gckOS_AcquireMutex(Heap->os, Heap->mutex, gcvINFINITE));
+ }
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+}
+
+/*******************************************************************************
+***** gckHEAP API Code *********************************************************
+*******************************************************************************/
+
+/*******************************************************************************
+**
+** gckHEAP_Construct
+**
+** Construct a new gckHEAP object.
+**
+** INPUT:
+**
+** gckOS Os
+** Pointer to a gckOS object.
+**
+** gctSIZE_T AllocationSize
+** Minimum size per arena.
+**
+** OUTPUT:
+**
+** gckHEAP * Heap
+** Pointer to a variable that will hold the pointer to the gckHEAP
+** object.
+*/
+gceSTATUS
+gckHEAP_Construct(
+ IN gckOS Os,
+ IN gctSIZE_T AllocationSize,
+ OUT gckHEAP * Heap
+ )
+{
+ gceSTATUS status;
+ gckHEAP heap = gcvNULL;
+ gctPOINTER pointer = gcvNULL;
+
+ gcmkHEADER_ARG("Os=0x%x AllocationSize=%lu", Os, AllocationSize);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
+ gcmkVERIFY_ARGUMENT(Heap != gcvNULL);
+
+ /* Allocate the gckHEAP object. */
+ gcmkONERROR(gckOS_AllocateMemory(Os,
+ gcmSIZEOF(struct _gckHEAP),
+ &pointer));
+
+ heap = pointer;
+
+ /* Initialize the gckHEAP object. */
+ heap->object.type = gcvOBJ_HEAP;
+ heap->os = Os;
+ heap->allocationSize = AllocationSize;
+ heap->heap = gcvNULL;
+#if gcmIS_DEBUG(gcdDEBUG_CODE)
+ heap->timeStamp = 0;
+#endif
+
+#if VIVANTE_PROFILER || gcmIS_DEBUG(gcdDEBUG_CODE)
+ /* Zero the counters. */
+ heap->allocCount = 0;
+ heap->allocBytes = 0;
+ heap->allocBytesMax = 0;
+ heap->allocBytesTotal = 0;
+ heap->heapCount = 0;
+ heap->heapCountMax = 0;
+ heap->heapMemory = 0;
+ heap->heapMemoryMax = 0;
+#endif
+
+ /* Create the mutex. */
+ gcmkONERROR(gckOS_CreateMutex(Os, &heap->mutex));
+
+ /* Return the pointer to the gckHEAP object. */
+ *Heap = heap;
+
+ /* Success. */
+ gcmkFOOTER_ARG("*Heap=0x%x", *Heap);
+ return gcvSTATUS_OK;
+
+OnError:
+ /* Roll back. */
+ if (heap != gcvNULL)
+ {
+ /* Free the heap structure. */
+ gcmkVERIFY_OK(gckOS_FreeMemory(Os, heap));
+ }
+
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+/*******************************************************************************
+**
+** gckHEAP_Destroy
+**
+** Destroy a gckHEAP object.
+**
+** INPUT:
+**
+** gckHEAP Heap
+** Pointer to a gckHEAP object to destroy.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckHEAP_Destroy(
+ IN gckHEAP Heap
+ )
+{
+ gcskHEAP_PTR heap;
+#if gcmIS_DEBUG(gcdDEBUG_CODE)
+ gctSIZE_T leaked = 0;
+#endif
+
+ gcmkHEADER_ARG("Heap=0x%x", Heap);
+
+ for (heap = Heap->heap; heap != gcvNULL; heap = Heap->heap)
+ {
+ /* Unlink heap from linked list. */
+ Heap->heap = heap->next;
+
+#if gcmIS_DEBUG(gcdDEBUG_CODE)
+ /* Check for leaked memory. */
+ leaked += _DumpHeap(heap);
+#endif
+
+ /* Free the heap. */
+ gcmkVERIFY_OK(gckOS_FreeMemory(Heap->os, heap));
+ }
+
+ /* Free the mutex. */
+ gcmkVERIFY_OK(gckOS_DeleteMutex(Heap->os, Heap->mutex));
+
+ /* Free the heap structure. */
+ gcmkVERIFY_OK(gckOS_FreeMemory(Heap->os, Heap));
+
+ /* Success. */
+#if gcmIS_DEBUG(gcdDEBUG_CODE)
+ gcmkFOOTER_ARG("leaked=%lu", leaked);
+#else
+ gcmkFOOTER_NO();
+#endif
+ return gcvSTATUS_OK;
+}
+
+/*******************************************************************************
+**
+** gckHEAP_Allocate
+**
+** Allocate data from the heap.
+**
+** INPUT:
+**
+** gckHEAP Heap
+** Pointer to a gckHEAP object.
+**
+** IN gctSIZE_T Bytes
+** Number of byte to allocate.
+**
+** OUTPUT:
+**
+** gctPOINTER * Memory
+** Pointer to a variable that will hold the address of the allocated
+** memory.
+*/
+gceSTATUS
+gckHEAP_Allocate(
+ IN gckHEAP Heap,
+ IN gctSIZE_T Bytes,
+ OUT gctPOINTER * Memory
+ )
+{
+ gctBOOL acquired = gcvFALSE;
+ gcskHEAP_PTR heap;
+ gceSTATUS status;
+ gctSIZE_T bytes;
+ gcskNODE_PTR node, used, prevFree = gcvNULL;
+ gctPOINTER memory = gcvNULL;
+
+ gcmkHEADER_ARG("Heap=0x%x Bytes=%lu", Heap, Bytes);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Heap, gcvOBJ_HEAP);
+ gcmkVERIFY_ARGUMENT(Bytes > 0);
+ gcmkVERIFY_ARGUMENT(Memory != gcvNULL);
+
+ /* Determine number of bytes required for a node. */
+ bytes = gcmALIGN(Bytes + gcmSIZEOF(gcskNODE), 8);
+
+ /* Acquire the mutex. */
+ gcmkONERROR(
+ gckOS_AcquireMutex(Heap->os, Heap->mutex, gcvINFINITE));
+
+ acquired = gcvTRUE;
+
+ /* Check if this allocation is bigger than the default allocation size. */
+ if (bytes > Heap->allocationSize - gcmSIZEOF(gcskHEAP) - gcmSIZEOF(gcskNODE))
+ {
+ /* Adjust allocation size. */
+ Heap->allocationSize = bytes * 2;
+ }
+
+ else if (Heap->heap != gcvNULL)
+ {
+ gctINT i;
+
+ /* 2 retries, since we might need to compact. */
+ for (i = 0; i < 2; ++i)
+ {
+ /* Walk all the heaps. */
+ for (heap = Heap->heap; heap != gcvNULL; heap = heap->next)
+ {
+ /* Check if this heap has enough bytes to hold the request. */
+ if (bytes <= heap->size - gcmSIZEOF(gcskNODE))
+ {
+ prevFree = gcvNULL;
+
+ /* Walk the chain of free nodes. */
+ for (node = heap->freeList;
+ node != gcvNULL;
+ node = node->next
+ )
+ {
+ gcmkASSERT(node->next != gcdIN_USE);
+
+ /* Check if this free node has enough bytes. */
+ if (node->bytes >= bytes)
+ {
+ /* Use the node. */
+ goto UseNode;
+ }
+
+ /* Save current free node for linked list management. */
+ prevFree = node;
+ }
+ }
+ }
+
+ if (i == 0)
+ {
+ /* Compact the heap. */
+ gcmkVERIFY_OK(_CompactKernelHeap(Heap));
+
+#if gcmIS_DEBUG(gcdDEBUG_CODE)
+ gcmkTRACE_ZONE(gcvLEVEL_VERBOSE, gcvZONE_HEAP,
+ "===== KERNEL HEAP =====");
+ gcmkTRACE_ZONE(gcvLEVEL_VERBOSE, gcvZONE_HEAP,
+ "Number of allocations : %12u",
+ Heap->allocCount);
+ gcmkTRACE_ZONE(gcvLEVEL_VERBOSE, gcvZONE_HEAP,
+ "Number of bytes allocated : %12llu",
+ Heap->allocBytes);
+ gcmkTRACE_ZONE(gcvLEVEL_VERBOSE, gcvZONE_HEAP,
+ "Maximum allocation size : %12llu",
+ Heap->allocBytesMax);
+ gcmkTRACE_ZONE(gcvLEVEL_VERBOSE, gcvZONE_HEAP,
+ "Total number of bytes allocated : %12llu",
+ Heap->allocBytesTotal);
+ gcmkTRACE_ZONE(gcvLEVEL_VERBOSE, gcvZONE_HEAP,
+ "Number of heaps : %12u",
+ Heap->heapCount);
+ gcmkTRACE_ZONE(gcvLEVEL_VERBOSE, gcvZONE_HEAP,
+ "Heap memory in bytes : %12llu",
+ Heap->heapMemory);
+ gcmkTRACE_ZONE(gcvLEVEL_VERBOSE, gcvZONE_HEAP,
+ "Maximum number of heaps : %12u",
+ Heap->heapCountMax);
+ gcmkTRACE_ZONE(gcvLEVEL_VERBOSE, gcvZONE_HEAP,
+ "Maximum heap memory in bytes : %12llu",
+ Heap->heapMemoryMax);
+#endif
+ }
+ }
+ }
+
+ /* Release the mutex. */
+ gcmkONERROR(
+ gckOS_ReleaseMutex(Heap->os, Heap->mutex));
+
+ acquired = gcvFALSE;
+
+ /* Allocate a new heap. */
+ gcmkONERROR(
+ gckOS_AllocateMemory(Heap->os,
+ Heap->allocationSize,
+ &memory));
+
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HEAP,
+ "Allocated heap 0x%x (%lu bytes)",
+ memory, Heap->allocationSize);
+
+ /* Acquire the mutex. */
+ gcmkONERROR(
+ gckOS_AcquireMutex(Heap->os, Heap->mutex, gcvINFINITE));
+
+ acquired = gcvTRUE;
+
+ /* Use the allocated memory as the heap. */
+ heap = (gcskHEAP_PTR) memory;
+
+ /* Insert this heap to the head of the chain. */
+ heap->next = Heap->heap;
+ heap->prev = gcvNULL;
+ heap->size = Heap->allocationSize - gcmSIZEOF(gcskHEAP);
+
+ if (heap->next != gcvNULL)
+ {
+ heap->next->prev = heap;
+ }
+ Heap->heap = heap;
+
+ /* Mark the end of the heap. */
+ node = (gcskNODE_PTR) ( (gctUINT8_PTR) heap
+ + Heap->allocationSize
+ - gcmSIZEOF(gcskNODE)
+ );
+ node->bytes = 0;
+ node->next = gcvNULL;
+
+ /* Create a free list. */
+ node = (gcskNODE_PTR) (heap + 1);
+ heap->freeList = node;
+
+ /* Initialize the free list. */
+ node->bytes = heap->size - gcmSIZEOF(gcskNODE);
+ node->next = gcvNULL;
+
+ /* No previous free. */
+ prevFree = gcvNULL;
+
+#if VIVANTE_PROFILER || gcmIS_DEBUG(gcdDEBUG_CODE)
+ /* Update profiling. */
+ Heap->heapCount += 1;
+ Heap->heapMemory += Heap->allocationSize;
+
+ if (Heap->heapCount > Heap->heapCountMax)
+ {
+ Heap->heapCountMax = Heap->heapCount;
+ }
+ if (Heap->heapMemory > Heap->heapMemoryMax)
+ {
+ Heap->heapMemoryMax = Heap->heapMemory;
+ }
+#endif
+
+UseNode:
+ /* Verify some stuff. */
+ gcmkASSERT(heap != gcvNULL);
+ gcmkASSERT(node != gcvNULL);
+ gcmkASSERT(node->bytes >= bytes);
+
+ if (heap->prev != gcvNULL)
+ {
+ /* Unlink the heap from the linked list. */
+ heap->prev->next = heap->next;
+ if (heap->next != gcvNULL)
+ {
+ heap->next->prev = heap->prev;
+ }
+
+ /* Move the heap to the front of the list. */
+ heap->next = Heap->heap;
+ heap->prev = gcvNULL;
+ Heap->heap = heap;
+ heap->next->prev = heap;
+ }
+
+ /* Check if there is enough free space left after usage for another free
+ ** node. */
+ if (node->bytes - bytes >= gcmSIZEOF(gcskNODE))
+ {
+ /* Allocated used space from the back of the free list. */
+ used = (gcskNODE_PTR) ((gctUINT8_PTR) node + node->bytes - bytes);
+
+ /* Adjust the number of free bytes. */
+ node->bytes -= bytes;
+ gcmkASSERT(node->bytes >= gcmSIZEOF(gcskNODE));
+ }
+ else
+ {
+ /* Remove this free list from the chain. */
+ if (prevFree == gcvNULL)
+ {
+ heap->freeList = node->next;
+ }
+ else
+ {
+ prevFree->next = node->next;
+ }
+
+ /* Consume the entire free node. */
+ used = (gcskNODE_PTR) node;
+ bytes = node->bytes;
+ }
+
+ /* Mark node as used. */
+ used->bytes = bytes;
+ used->next = gcdIN_USE;
+#if gcmIS_DEBUG(gcdDEBUG_CODE)
+ used->timeStamp = ++Heap->timeStamp;
+#endif
+
+#if VIVANTE_PROFILER || gcmIS_DEBUG(gcdDEBUG_CODE)
+ /* Update profile counters. */
+ Heap->allocCount += 1;
+ Heap->allocBytes += bytes;
+ Heap->allocBytesMax = gcmMAX(Heap->allocBytes, Heap->allocBytesMax);
+ Heap->allocBytesTotal += bytes;
+#endif
+
+ /* Release the mutex. */
+ gcmkVERIFY_OK(
+ gckOS_ReleaseMutex(Heap->os, Heap->mutex));
+
+ /* Return pointer to memory. */
+ *Memory = used + 1;
+
+ /* Success. */
+ gcmkFOOTER_ARG("*Memory=0x%x", *Memory);
+ return gcvSTATUS_OK;
+
+OnError:
+ if (acquired)
+ {
+ /* Release the mutex. */
+ gcmkVERIFY_OK(
+ gckOS_ReleaseMutex(Heap->os, Heap->mutex));
+ }
+
+ if (memory != gcvNULL)
+ {
+ /* Free the heap memory. */
+ gckOS_FreeMemory(Heap->os, memory);
+ }
+
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+/*******************************************************************************
+**
+** gckHEAP_Free
+**
+** Free allocated memory from the heap.
+**
+** INPUT:
+**
+** gckHEAP Heap
+** Pointer to a gckHEAP object.
+**
+** IN gctPOINTER Memory
+** Pointer to memory to free.
+**
+** OUTPUT:
+**
+** NOTHING.
+*/
+gceSTATUS
+gckHEAP_Free(
+ IN gckHEAP Heap,
+ IN gctPOINTER Memory
+ )
+{
+ gcskNODE_PTR node;
+ gceSTATUS status;
+
+ gcmkHEADER_ARG("Heap=0x%x Memory=0x%x", Heap, Memory);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Heap, gcvOBJ_HEAP);
+ gcmkVERIFY_ARGUMENT(Memory != gcvNULL);
+
+ /* Acquire the mutex. */
+ gcmkONERROR(
+ gckOS_AcquireMutex(Heap->os, Heap->mutex, gcvINFINITE));
+
+ /* Pointer to structure. */
+ node = (gcskNODE_PTR) Memory - 1;
+
+ /* Mark the node as freed. */
+ node->next = gcvNULL;
+
+#if VIVANTE_PROFILER || gcmIS_DEBUG(gcdDEBUG_CODE)
+ /* Update profile counters. */
+ Heap->allocBytes -= node->bytes;
+#endif
+
+ /* Release the mutex. */
+ gcmkVERIFY_OK(
+ gckOS_ReleaseMutex(Heap->os, Heap->mutex));
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+#if VIVANTE_PROFILER
+gceSTATUS
+gckHEAP_ProfileStart(
+ IN gckHEAP Heap
+ )
+{
+ gcmkHEADER_ARG("Heap=0x%x", Heap);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Heap, gcvOBJ_HEAP);
+
+ /* Zero the counters. */
+ Heap->allocCount = 0;
+ Heap->allocBytes = 0;
+ Heap->allocBytesMax = 0;
+ Heap->allocBytesTotal = 0;
+ Heap->heapCount = 0;
+ Heap->heapCountMax = 0;
+ Heap->heapMemory = 0;
+ Heap->heapMemoryMax = 0;
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+}
+
+gceSTATUS
+gckHEAP_ProfileEnd(
+ IN gckHEAP Heap,
+ IN gctCONST_STRING Title
+ )
+{
+ gcmkHEADER_ARG("Heap=0x%x Title=0x%x", Heap, Title);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Heap, gcvOBJ_HEAP);
+ gcmkVERIFY_ARGUMENT(Title != gcvNULL);
+
+ gcmkPRINT("");
+ gcmkPRINT("=====[ HEAP - %s ]=====", Title);
+ gcmkPRINT("Number of allocations : %12u", Heap->allocCount);
+ gcmkPRINT("Number of bytes allocated : %12llu", Heap->allocBytes);
+ gcmkPRINT("Maximum allocation size : %12llu", Heap->allocBytesMax);
+ gcmkPRINT("Total number of bytes allocated : %12llu", Heap->allocBytesTotal);
+ gcmkPRINT("Number of heaps : %12u", Heap->heapCount);
+ gcmkPRINT("Heap memory in bytes : %12llu", Heap->heapMemory);
+ gcmkPRINT("Maximum number of heaps : %12u", Heap->heapCountMax);
+ gcmkPRINT("Maximum heap memory in bytes : %12llu", Heap->heapMemoryMax);
+ gcmkPRINT("==============================================");
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+}
+#endif /* VIVANTE_PROFILER */
+
+/*******************************************************************************
+***** Test Code ****************************************************************
+*******************************************************************************/
+
diff --git a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_interrupt_vg.c b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_interrupt_vg.c
new file mode 100644
index 000000000000..057fad6b559d
--- /dev/null
+++ b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_interrupt_vg.c
@@ -0,0 +1,911 @@
+/****************************************************************************
+*
+* The MIT License (MIT)
+*
+* Copyright (c) 2014 - 2018 Vivante 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 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 GPL License (GPL)
+*
+* Copyright (C) 2014 - 2018 Vivante 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.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+*****************************************************************************
+*
+* Note: This software is released under dual MIT and GPL licenses. A
+* recipient may use this file under the terms of either the MIT license or
+* GPL License. If you wish to use only one license not the other, you can
+* indicate your decision by deleting one of the above license notices in your
+* version of this file.
+*
+*****************************************************************************/
+
+
+#include "gc_hal_kernel_precomp.h"
+
+#if gcdENABLE_VG
+
+/******************************************************************************\
+*********************** Support Functions and Definitions **********************
+\******************************************************************************/
+
+/* Interruot statistics will be accumulated if not zero. */
+#define gcmENABLE_INTERRUPT_STATISTICS 0
+
+#define _GC_OBJ_ZONE gcvZONE_INTERRUPT
+
+/* Object structure. */
+struct _gckVGINTERRUPT
+{
+ /* Object. */
+ gcsOBJECT object;
+
+ /* gckVGKERNEL pointer. */
+ gckVGKERNEL kernel;
+
+ /* gckOS pointer. */
+ gckOS os;
+
+ /* Interrupt handlers. */
+ gctINTERRUPT_HANDLER handlers[32];
+
+ /* Main interrupt handler thread. */
+ gctTHREAD handler;
+ gctBOOL terminate;
+
+ /* Interrupt FIFO. */
+ gctSEMAPHORE fifoValid;
+ gctUINT32 fifo[256];
+ gctUINT fifoItems;
+ gctUINT8 head;
+ gctUINT8 tail;
+
+ /* Interrupt statistics. */
+#if gcmENABLE_INTERRUPT_STATISTICS
+ gctUINT maxFifoItems;
+ gctUINT fifoOverflow;
+ gctUINT maxSimultaneous;
+ gctUINT multipleCount;
+#endif
+};
+
+
+/*******************************************************************************
+**
+** _ProcessInterrupt
+**
+** The interrupt processor.
+**
+** INPUT:
+**
+** ThreadParameter
+** Pointer to the gckVGINTERRUPT object.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+
+#if gcmENABLE_INTERRUPT_STATISTICS
+static void
+_ProcessInterrupt(
+ gckVGINTERRUPT Interrupt,
+ gctUINT_PTR TriggeredCount
+ )
+#else
+static void
+_ProcessInterrupt(
+ gckVGINTERRUPT Interrupt
+ )
+#endif
+{
+ gceSTATUS status;
+ gctUINT32 triggered;
+ gctUINT i;
+
+ /* Advance to the next entry. */
+ Interrupt->tail += 1;
+ Interrupt->fifoItems -= 1;
+
+ /* Get the interrupt value. */
+ triggered = Interrupt->fifo[Interrupt->tail];
+ gcmkASSERT(triggered != 0);
+
+ gcmkTRACE_ZONE(
+ gcvLEVEL_VERBOSE, gcvZONE_COMMAND,
+ "%s: triggered=0x%08X\n",
+ __FUNCTION__,
+ triggered
+ );
+
+ /* Walk through all possible interrupts. */
+ for (i = 0; i < gcmSIZEOF(Interrupt->handlers); i += 1)
+ {
+ /* Test if interrupt happened. */
+ if ((triggered & 1) == 1)
+ {
+#if gcmENABLE_INTERRUPT_STATISTICS
+ if (TriggeredCount != gcvNULL)
+ {
+ (* TriggeredCount) += 1;
+ }
+#endif
+
+ /* Make sure we have valid handler. */
+ if (Interrupt->handlers[i] == gcvNULL)
+ {
+ gcmkTRACE(
+ gcvLEVEL_ERROR,
+ "%s: Interrupt %d isn't registered.\n",
+ __FUNCTION__, i
+ );
+ }
+ else
+ {
+ gcmkTRACE_ZONE(
+ gcvLEVEL_VERBOSE, gcvZONE_COMMAND,
+ "%s: interrupt=%d\n",
+ __FUNCTION__,
+ i
+ );
+
+ /* Call the handler. */
+ status = Interrupt->handlers[i] (Interrupt->kernel);
+
+ if (gcmkIS_ERROR(status))
+ {
+ /* Failed to signal the semaphore. */
+ gcmkTRACE(
+ gcvLEVEL_ERROR,
+ "%s: Error %d incrementing the semaphore #%d.\n",
+ __FUNCTION__, status, i
+ );
+ }
+ }
+ }
+
+ /* Next interrupt. */
+ triggered >>= 1;
+
+ /* No more interrupts to handle? */
+ if (triggered == 0)
+ {
+ break;
+ }
+ }
+}
+
+
+/*******************************************************************************
+**
+** _MainInterruptHandler
+**
+** The main interrupt thread serves the interrupt FIFO and calls registered
+** handlers for the interrupts that occured. The handlers are called in the
+** sequence interrupts occured with the exception when multiple interrupts
+** occured at the same time. In that case the handler calls are "sorted" by
+** the interrupt number therefore giving the interrupts with lower numbers
+** higher priority.
+**
+** INPUT:
+**
+** ThreadParameter
+** Pointer to the gckVGINTERRUPT object.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+
+static gctTHREADFUNCRESULT gctTHREADFUNCTYPE
+_MainInterruptHandler(
+ gctTHREADFUNCPARAMETER ThreadParameter
+ )
+{
+ gceSTATUS status;
+ gckVGINTERRUPT interrupt;
+
+#if gcmENABLE_INTERRUPT_STATISTICS
+ gctUINT count;
+#endif
+
+ /* Cast the object. */
+ interrupt = (gckVGINTERRUPT) ThreadParameter;
+
+ /* Enter the loop. */
+ while (gcvTRUE)
+ {
+ /* Wait for an interrupt. */
+ status = gckOS_DecrementSemaphore(interrupt->os, interrupt->fifoValid);
+
+ /* Error? */
+ if (gcmkIS_ERROR(status))
+ {
+ break;
+ }
+
+ /* System termination request? */
+ if (status == gcvSTATUS_TERMINATE)
+ {
+ break;
+ }
+
+ /* Driver is shutting down? */
+ if (interrupt->terminate)
+ {
+ break;
+ }
+
+#if gcmENABLE_INTERRUPT_STATISTICS
+ /* Reset triggered count. */
+ count = 0;
+
+ /* Process the interrupt. */
+ _ProcessInterrupt(interrupt, &count);
+
+ /* Update conters. */
+ if (count > interrupt->maxSimultaneous)
+ {
+ interrupt->maxSimultaneous = count;
+ }
+
+ if (count > 1)
+ {
+ interrupt->multipleCount += 1;
+ }
+#else
+ /* Process the interrupt. */
+ _ProcessInterrupt(interrupt);
+#endif
+ }
+
+ return 0;
+}
+
+
+/*******************************************************************************
+**
+** _StartInterruptHandler / _StopInterruptHandler
+**
+** Main interrupt handler routine control.
+**
+** INPUT:
+**
+** ThreadParameter
+** Pointer to the gckVGINTERRUPT object.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+
+static gceSTATUS
+_StartInterruptHandler(
+ gckVGINTERRUPT Interrupt
+ )
+{
+ gceSTATUS status, last;
+
+ do
+ {
+ /* Objects must not be already created. */
+ gcmkASSERT(Interrupt->fifoValid == gcvNULL);
+ gcmkASSERT(Interrupt->handler == gcvNULL);
+
+ /* Reset the termination request. */
+ Interrupt->terminate = gcvFALSE;
+
+#if !gcdENABLE_INFINITE_SPEED_HW
+ /* Construct the fifo semaphore. */
+ gcmkERR_BREAK(gckOS_CreateSemaphoreVG(
+ Interrupt->os, &Interrupt->fifoValid
+ ));
+
+ /* Start the interrupt handler thread. */
+ gcmkERR_BREAK(gckOS_StartThread(
+ Interrupt->os,
+ _MainInterruptHandler,
+ Interrupt,
+ &Interrupt->handler
+ ));
+#endif
+
+ /* Success. */
+ return gcvSTATUS_OK;
+ }
+ while (gcvFALSE);
+
+ /* Roll back. */
+ if (Interrupt->fifoValid != gcvNULL)
+ {
+ gcmkCHECK_STATUS(gckOS_DestroySemaphore(
+ Interrupt->os, Interrupt->fifoValid
+ ));
+
+ Interrupt->fifoValid = gcvNULL;
+ }
+
+ /* Return the status. */
+ return status;
+}
+
+static gceSTATUS
+_StopInterruptHandler(
+ gckVGINTERRUPT Interrupt
+ )
+{
+ gceSTATUS status;
+
+ do
+ {
+ /* Does the thread exist? */
+ if (Interrupt->handler == gcvNULL)
+ {
+ /* The semaphore must be NULL as well. */
+ gcmkASSERT(Interrupt->fifoValid == gcvNULL);
+
+ /* Success. */
+ status = gcvSTATUS_OK;
+ break;
+ }
+
+ /* The semaphore must exist as well. */
+ gcmkASSERT(Interrupt->fifoValid != gcvNULL);
+
+ /* Set the termination request. */
+ Interrupt->terminate = gcvTRUE;
+
+ /* Unlock the thread. */
+ gcmkERR_BREAK(gckOS_IncrementSemaphore(
+ Interrupt->os, Interrupt->fifoValid
+ ));
+
+ /* Wait until the thread quits. */
+ gcmkERR_BREAK(gckOS_StopThread(
+ Interrupt->os,
+ Interrupt->handler
+ ));
+
+ /* Destroy the semaphore. */
+ gcmkERR_BREAK(gckOS_DestroySemaphore(
+ Interrupt->os, Interrupt->fifoValid
+ ));
+
+ /* Reset handles. */
+ Interrupt->handler = gcvNULL;
+ Interrupt->fifoValid = gcvNULL;
+ }
+ while (gcvFALSE);
+
+ /* Return the status. */
+ return status;
+}
+
+
+/******************************************************************************\
+***************************** Interrupt Object API *****************************
+\******************************************************************************/
+
+/*******************************************************************************
+**
+** gckVGINTERRUPT_Construct
+**
+** Construct an interrupt object.
+**
+** INPUT:
+**
+** Kernel
+** Pointer to the gckVGKERNEL object.
+**
+** OUTPUT:
+**
+** Interrupt
+** Pointer to the new gckVGINTERRUPT object.
+*/
+
+gceSTATUS
+gckVGINTERRUPT_Construct(
+ IN gckVGKERNEL Kernel,
+ OUT gckVGINTERRUPT * Interrupt
+ )
+{
+ gceSTATUS status;
+ gckVGINTERRUPT interrupt = gcvNULL;
+
+ gcmkHEADER_ARG("Kernel=0x%x Interrupt=0x%x", Kernel, Interrupt);
+
+ /* Verify argeuments. */
+ gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
+ gcmkVERIFY_ARGUMENT(Interrupt != gcvNULL);
+
+ do
+ {
+ /* Allocate the gckVGINTERRUPT structure. */
+ gcmkERR_BREAK(gckOS_Allocate(
+ Kernel->os,
+ gcmSIZEOF(struct _gckVGINTERRUPT),
+ (gctPOINTER *) &interrupt
+ ));
+
+ /* Reset the object data. */
+ gcmkVERIFY_OK(gckOS_ZeroMemory(
+ interrupt, gcmSIZEOF(struct _gckVGINTERRUPT)
+ ));
+
+ /* Initialize the object. */
+ interrupt->object.type = gcvOBJ_INTERRUPT;
+
+ /* Initialize the object pointers. */
+ interrupt->kernel = Kernel;
+ interrupt->os = Kernel->os;
+
+ /* Initialize the current FIFO position. */
+ interrupt->head = (gctUINT8)~0;
+ interrupt->tail = (gctUINT8)~0;
+
+ /* Start the thread. */
+ gcmkERR_BREAK(_StartInterruptHandler(interrupt));
+
+ /* Return interrupt object. */
+ *Interrupt = interrupt;
+
+ gcmkFOOTER_ARG("*Interrup=0x%x", *Interrupt);
+ /* Success. */
+ return gcvSTATUS_OK;
+ }
+ while (gcvFALSE);
+
+ /* Roll back. */
+ if (interrupt != gcvNULL)
+ {
+ /* Free the gckVGINTERRUPT structure. */
+ gcmkVERIFY_OK(gckOS_Free(interrupt->os, interrupt));
+ }
+
+ gcmkFOOTER();
+
+ /* Return the status. */
+ return status;
+}
+
+
+/*******************************************************************************
+**
+** gckVGINTERRUPT_Destroy
+**
+** Destroy an interrupt object.
+**
+** INPUT:
+**
+** Interrupt
+** Pointer to the gckVGINTERRUPT object to destroy.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+
+gceSTATUS
+gckVGINTERRUPT_Destroy(
+ IN gckVGINTERRUPT Interrupt
+ )
+{
+ gceSTATUS status;
+
+ gcmkHEADER_ARG("Interrupt=0x%x", Interrupt);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Interrupt, gcvOBJ_INTERRUPT);
+
+ do
+ {
+ /* Stop the interrupt thread. */
+ gcmkERR_BREAK(_StopInterruptHandler(Interrupt));
+
+ /* Mark the object as unknown. */
+ Interrupt->object.type = gcvOBJ_UNKNOWN;
+
+ /* Free the gckVGINTERRUPT structure. */
+ gcmkERR_BREAK(gckOS_Free(Interrupt->os, Interrupt));
+ }
+ while (gcvFALSE);
+
+ gcmkFOOTER();
+
+ /* Return the status. */
+ return status;
+}
+
+
+/*******************************************************************************
+**
+** gckVGINTERRUPT_DumpState
+**
+** Print the current state of the interrupt manager.
+**
+** INPUT:
+**
+** Interrupt
+** Pointer to a gckVGINTERRUPT object.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+
+#if gcvDEBUG
+gceSTATUS
+gckVGINTERRUPT_DumpState(
+ IN gckVGINTERRUPT Interrupt
+ )
+{
+ gcmkHEADER_ARG("Interrupt=0x%x", Interrupt);
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Interrupt, gcvOBJ_INTERRUPT);
+
+ /* Print the header. */
+ gcmkTRACE_ZONE(
+ gcvLEVEL_VERBOSE, gcvZONE_COMMAND,
+ "%s: INTERRUPT OBJECT STATUS\n",
+ __FUNCTION__
+ );
+
+ /* Print statistics. */
+#if gcmENABLE_INTERRUPT_STATISTICS
+ gcmkTRACE_ZONE(
+ gcvLEVEL_VERBOSE, gcvZONE_COMMAND,
+ " Maximum number of FIFO items accumulated at a single time: %d\n",
+ Interrupt->maxFifoItems
+ );
+
+ gcmkTRACE_ZONE(
+ gcvLEVEL_VERBOSE, gcvZONE_COMMAND,
+ " Interrupt FIFO overflow happened times: %d\n",
+ Interrupt->fifoOverflow
+ );
+
+ gcmkTRACE_ZONE(
+ gcvLEVEL_VERBOSE, gcvZONE_COMMAND,
+ " Maximum number of interrupts simultaneously generated: %d\n",
+ Interrupt->maxSimultaneous
+ );
+
+ gcmkTRACE_ZONE(
+ gcvLEVEL_VERBOSE, gcvZONE_COMMAND,
+ " Number of times when there were multiple interrupts generated: %d\n",
+ Interrupt->multipleCount
+ );
+#endif
+
+ gcmkTRACE_ZONE(
+ gcvLEVEL_VERBOSE, gcvZONE_COMMAND,
+ " The current number of entries in the FIFO: %d\n",
+ Interrupt->fifoItems
+ );
+
+ /* Print the FIFO contents. */
+ if (Interrupt->fifoItems != 0)
+ {
+ gctUINT8 index;
+ gctUINT8 last;
+
+ gcmkTRACE_ZONE(
+ gcvLEVEL_VERBOSE, gcvZONE_COMMAND,
+ " FIFO current contents:\n"
+ );
+
+ /* Get the current pointers. */
+ index = Interrupt->tail;
+ last = Interrupt->head;
+
+ while (index != last)
+ {
+ /* Advance to the next entry. */
+ index += 1;
+
+ gcmkTRACE_ZONE(
+ gcvLEVEL_VERBOSE, gcvZONE_COMMAND,
+ " %d: 0x%08X\n",
+ index, Interrupt->fifo[index]
+ );
+ }
+ }
+
+ gcmkFOOTER_NO();
+ /* Success. */
+ return gcvSTATUS_OK;
+}
+#endif
+
+
+/*******************************************************************************
+**
+** gckVGINTERRUPT_Enable
+**
+** Enable the specified interrupt.
+**
+** INPUT:
+**
+** Interrupt
+** Pointer to a gckVGINTERRUPT object.
+**
+** Id
+** Pointer to the variable that holds the interrupt number to be
+** registered in range 0..31.
+** If the value is less then 0, gckVGINTERRUPT_Enable will attempt
+** to find an unused interrupt. If such interrupt is found, the number
+** will be assigned to the variable if the functuion call succeedes.
+**
+** Handler
+** Pointer to the handler to register for the interrupt.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+
+gceSTATUS
+gckVGINTERRUPT_Enable(
+ IN gckVGINTERRUPT Interrupt,
+ IN OUT gctINT32_PTR Id,
+ IN gctINTERRUPT_HANDLER Handler
+ )
+{
+ gceSTATUS status;
+ gctINT32 i;
+
+ gcmkHEADER_ARG("Interrupt=0x%x Id=0x%x Handler=0x%x", Interrupt, Id, Handler);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Interrupt, gcvOBJ_INTERRUPT);
+ gcmkVERIFY_ARGUMENT(Id != gcvNULL);
+ gcmkVERIFY_ARGUMENT(Handler != gcvNULL);
+
+ do
+ {
+ /* See if we need to allocate an ID. */
+ if (*Id < 0)
+ {
+ /* Find the first unused interrupt handler. */
+ for (i = 0; i < gcmCOUNTOF(Interrupt->handlers); ++i)
+ {
+ if (Interrupt->handlers[i] == gcvNULL)
+ {
+ break;
+ }
+ }
+
+ /* No unused innterrupts? */
+ if (i == gcmCOUNTOF(Interrupt->handlers))
+ {
+ status = gcvSTATUS_OUT_OF_RESOURCES;
+ break;
+ }
+
+ /* Update the interrupt ID. */
+ *Id = i;
+ }
+
+ /* Make sure the ID is in range. */
+ else if (*Id >= gcmCOUNTOF(Interrupt->handlers))
+ {
+ status = gcvSTATUS_INVALID_ARGUMENT;
+ break;
+ }
+
+ /* Set interrupt handler. */
+ Interrupt->handlers[*Id] = Handler;
+
+ /* Success. */
+ status = gcvSTATUS_OK;
+ }
+ while (gcvFALSE);
+
+ gcmkFOOTER();
+ /* Return the status. */
+ return status;
+}
+
+
+/*******************************************************************************
+**
+** gckVGINTERRUPT_Disable
+**
+** Disable the specified interrupt.
+**
+** INPUT:
+**
+** Interrupt
+** Pointer to a gckVGINTERRUPT object.
+**
+** Id
+** Interrupt number to be disabled in range 0..31.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+
+gceSTATUS
+gckVGINTERRUPT_Disable(
+ IN gckVGINTERRUPT Interrupt,
+ IN gctINT32 Id
+ )
+{
+ gcmkHEADER_ARG("Interrupt=0x%x Id=0x%x", Interrupt, Id);
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Interrupt, gcvOBJ_INTERRUPT);
+ gcmkVERIFY_ARGUMENT((Id >= 0) && (Id < gcmCOUNTOF(Interrupt->handlers)));
+
+ /* Reset interrupt handler. */
+ Interrupt->handlers[Id] = gcvNULL;
+
+ gcmkFOOTER_NO();
+ /* Success. */
+ return gcvSTATUS_OK;
+}
+
+
+/*******************************************************************************
+**
+** gckVGINTERRUPT_Enque
+**
+** Read the interrupt status register and put the value in the interrupt FIFO.
+**
+** INPUT:
+**
+** Interrupt
+** Pointer to a gckVGINTERRUPT object.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+
+#ifndef __QNXNTO__
+gceSTATUS
+gckVGINTERRUPT_Enque(
+ IN gckVGINTERRUPT Interrupt
+ )
+#else
+gceSTATUS
+gckVGINTERRUPT_Enque(
+ IN gckVGINTERRUPT Interrupt,
+ OUT gckOS *Os,
+ OUT gctSEMAPHORE *Semaphore
+ )
+#endif
+{
+ gceSTATUS status;
+ gctUINT32 triggered;
+
+ gcmkHEADER_ARG("Interrupt=0x%x", Interrupt);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Interrupt, gcvOBJ_INTERRUPT);
+
+#ifdef __QNXNTO__
+ *Os = gcvNULL;
+ *Semaphore = gcvNULL;
+#endif
+
+ do
+ {
+ /* Read interrupt status register. */
+ gcmkERR_BREAK(gckVGHARDWARE_ReadInterrupt(
+ Interrupt->kernel->hardware, &triggered
+ ));
+
+ /* Mask out TS overflow interrupt */
+ triggered &= 0xfffffffe;
+
+ /* No interrupts to process? */
+ if (triggered == 0)
+ {
+ status = gcvSTATUS_NOT_OUR_INTERRUPT;
+ break;
+ }
+
+ /* FIFO overflow? */
+ if (Interrupt->fifoItems == gcmCOUNTOF(Interrupt->fifo))
+ {
+#if gcmENABLE_INTERRUPT_STATISTICS
+ Interrupt->fifoOverflow += 1;
+#endif
+
+ /* OR the interrupt with the last value in the FIFO. */
+ Interrupt->fifo[Interrupt->head] |= triggered;
+
+ /* Success (kind of). */
+ status = gcvSTATUS_OK;
+ }
+ else
+ {
+ /* Advance to the next entry. */
+ Interrupt->head += 1;
+ Interrupt->fifoItems += 1;
+
+#if gcmENABLE_INTERRUPT_STATISTICS
+ if (Interrupt->fifoItems > Interrupt->maxFifoItems)
+ {
+ Interrupt->maxFifoItems = Interrupt->fifoItems;
+ }
+#endif
+
+ /* Set the new value. */
+ Interrupt->fifo[Interrupt->head] = triggered;
+
+#ifndef __QNXNTO__
+ /* Increment the FIFO semaphore. */
+ gcmkERR_BREAK(gckOS_IncrementSemaphore(
+ Interrupt->os, Interrupt->fifoValid
+ ));
+#else
+ *Os = Interrupt->os;
+ *Semaphore = Interrupt->fifoValid;
+#endif
+
+ /* Windows kills our threads prematurely when the application
+ exists. Verify here that the thread is still alive. */
+ status = gckOS_VerifyThread(Interrupt->os, Interrupt->handler);
+
+ /* Has the thread been prematurely terminated? */
+ if (status != gcvSTATUS_OK)
+ {
+ /* Process all accumulated interrupts. */
+ while (Interrupt->head != Interrupt->tail)
+ {
+#if gcmENABLE_INTERRUPT_STATISTICS
+ /* Process the interrupt. */
+ _ProcessInterrupt(Interrupt, gcvNULL);
+#else
+ /* Process the interrupt. */
+ _ProcessInterrupt(Interrupt);
+#endif
+ }
+
+ /* Set success. */
+ status = gcvSTATUS_OK;
+ }
+ }
+ }
+ while (gcvFALSE);
+
+ gcmkFOOTER();
+ /* Return status. */
+ return status;
+}
+
+#endif /* gcdENABLE_VG */
diff --git a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_mmu.c b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_mmu.c
new file mode 100644
index 000000000000..dd2a58adeb7f
--- /dev/null
+++ b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_mmu.c
@@ -0,0 +1,2990 @@
+/****************************************************************************
+*
+* The MIT License (MIT)
+*
+* Copyright (c) 2014 - 2018 Vivante 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 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 GPL License (GPL)
+*
+* Copyright (C) 2014 - 2018 Vivante 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.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+*****************************************************************************
+*
+* Note: This software is released under dual MIT and GPL licenses. A
+* recipient may use this file under the terms of either the MIT license or
+* GPL License. If you wish to use only one license not the other, you can
+* indicate your decision by deleting one of the above license notices in your
+* version of this file.
+*
+*****************************************************************************/
+
+
+#include "gc_hal_kernel_precomp.h"
+
+#define _GC_OBJ_ZONE gcvZONE_MMU
+
+typedef enum _gceMMU_TYPE
+{
+ gcvMMU_USED = (0 << 4),
+ gcvMMU_SINGLE = (1 << 4),
+ gcvMMU_FREE = (2 << 4),
+}
+gceMMU_TYPE;
+
+#define gcmENTRY_TYPE(x) (x & 0xF0)
+
+#define gcmENTRY_COUNT(x) ((x & 0xFFFFFF00) >> 8)
+
+#define gcdMMU_TABLE_DUMP 0
+
+#define gcdVERTEX_START (128 << 10)
+
+typedef struct _gcsMMU_STLB_CHUNK *gcsMMU_STLB_CHUNK_PTR;
+
+typedef struct _gcsMMU_STLB_CHUNK
+{
+ gctPHYS_ADDR physical;
+ gctUINT32_PTR logical;
+ gctSIZE_T size;
+ gctPHYS_ADDR_T physBase;
+ gctSIZE_T pageCount;
+ gctUINT32 mtlbIndex;
+ gctUINT32 mtlbEntryNum;
+ gcsMMU_STLB_CHUNK_PTR next;
+} gcsMMU_STLB_CHUNK;
+
+#if gcdSHARED_PAGETABLE
+typedef struct _gcsSharedPageTable * gcsSharedPageTable_PTR;
+typedef struct _gcsSharedPageTable
+{
+ /* Shared gckMMU object. */
+ gckMMU mmu;
+
+ /* Hardwares which use this shared pagetable. */
+ gckHARDWARE hardwares[gcdMAX_GPU_COUNT];
+
+ /* Number of cores use this shared pagetable. */
+ gctUINT32 reference;
+}
+gcsSharedPageTable;
+
+static gcsSharedPageTable_PTR sharedPageTable = gcvNULL;
+#endif
+
+typedef struct _gcsFreeSpaceNode * gcsFreeSpaceNode_PTR;
+typedef struct _gcsFreeSpaceNode
+{
+ gctUINT32 start;
+ gctINT32 entries;
+}
+gcsFreeSpaceNode;
+
+#if gcdENDIAN_BIG
+
+# define _WritePageEntry(pageEntry, entryValue) \
+ *(gctUINT32_PTR)(pageEntry) = gcmBSWAP32((gctUINT32)(entryValue))
+
+# define _ReadPageEntry(pageEntry) \
+ gcmBSWAP32(*(gctUINT32_PTR)(pageEntry))
+
+#else
+
+# define _WritePageEntry(pageEntry, entryValue) \
+ *(gctUINT32_PTR)(pageEntry) = (gctUINT32)(entryValue)
+
+# define _ReadPageEntry(pageEntry) \
+ *(gctUINT32_PTR)(pageEntry)
+
+#endif
+
+static gceSTATUS
+_FillPageTable(
+ IN gctUINT32_PTR PageTable,
+ IN gctUINT32 PageCount,
+ IN gctUINT32 EntryValue
+)
+{
+ gctUINT i;
+
+ for (i = 0; i < PageCount; i++)
+ {
+ _WritePageEntry(PageTable + i, EntryValue);
+ }
+
+ return gcvSTATUS_OK;
+}
+
+static gceSTATUS
+_FillMap(
+ IN gctUINT32_PTR Map,
+ IN gctUINT32 PageCount,
+ IN gctUINT32 EntryValue
+)
+{
+ gctUINT i;
+
+ for (i = 0; i < PageCount; i++)
+ {
+ Map[i] = EntryValue;
+ }
+
+ return gcvSTATUS_OK;
+}
+
+static gceSTATUS
+_Link(
+ IN gcsADDRESS_AREA_PTR Area,
+ IN gctUINT32 Index,
+ IN gctUINT32 Next
+ )
+{
+ if (Index >= Area->pageTableEntries)
+ {
+ /* Just move heap pointer. */
+ Area->heapList = Next;
+ }
+ else
+ {
+ /* Address page table. */
+ gctUINT32_PTR map = Area->mapLogical;
+
+ /* Dispatch on node type. */
+ switch (gcmENTRY_TYPE(map[Index]))
+ {
+ case gcvMMU_SINGLE:
+ /* Set single index. */
+ map[Index] = (Next << 8) | gcvMMU_SINGLE;
+ break;
+
+ case gcvMMU_FREE:
+ /* Set index. */
+ map[Index + 1] = Next;
+ break;
+
+ default:
+ gcmkFATAL("MMU table correcupted at index %u!", Index);
+ return gcvSTATUS_HEAP_CORRUPTED;
+ }
+ }
+
+ /* Success. */
+ return gcvSTATUS_OK;
+}
+
+static gceSTATUS
+_AddFree(
+ IN gcsADDRESS_AREA_PTR Area,
+ IN gctUINT32 Index,
+ IN gctUINT32 Node,
+ IN gctUINT32 Count
+ )
+{
+ gctUINT32_PTR map = Area->mapLogical;
+
+ if (Count == 1)
+ {
+ /* Initialize a single page node. */
+ map[Node] = (~((1U<<8)-1)) | gcvMMU_SINGLE;
+ }
+ else
+ {
+ /* Initialize the node. */
+ map[Node + 0] = (Count << 8) | gcvMMU_FREE;
+ map[Node + 1] = ~0U;
+ }
+
+ /* Append the node. */
+ return _Link(Area, Index, Node);
+}
+
+static gceSTATUS
+_Collect(
+ IN gcsADDRESS_AREA_PTR Area
+ )
+{
+ gctUINT32_PTR map = Area->mapLogical;
+ gceSTATUS status;
+ gctUINT32 i, previous, start = 0, count = 0;
+
+ previous = Area->heapList = ~0U;
+ Area->freeNodes = gcvFALSE;
+
+ /* Walk the entire page table. */
+ for (i = 0; i < Area->pageTableEntries; ++i)
+ {
+ /* Dispatch based on type of page. */
+ switch (gcmENTRY_TYPE(map[i]))
+ {
+ case gcvMMU_USED:
+ /* Used page, so close any open node. */
+ if (count > 0)
+ {
+ /* Add the node. */
+ gcmkONERROR(_AddFree(Area, previous, start, count));
+
+ /* Reset the node. */
+ previous = start;
+ count = 0;
+ }
+ break;
+
+ case gcvMMU_SINGLE:
+ /* Single free node. */
+ if (count++ == 0)
+ {
+ /* Start a new node. */
+ start = i;
+ }
+ break;
+
+ case gcvMMU_FREE:
+ /* A free node. */
+ if (count == 0)
+ {
+ /* Start a new node. */
+ start = i;
+ }
+
+ /* Advance the count. */
+ count += map[i] >> 8;
+
+ /* Advance the index into the page table. */
+ i += (map[i] >> 8) - 1;
+ break;
+
+ default:
+ gcmkFATAL("MMU page table correcupted at index %u!", i);
+ return gcvSTATUS_HEAP_CORRUPTED;
+ }
+ }
+
+ /* See if we have an open node left. */
+ if (count > 0)
+ {
+ /* Add the node to the list. */
+ gcmkONERROR(_AddFree(Area, previous, start, count));
+ }
+
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_MMU,
+ "Performed a garbage collection of the MMU heap.");
+
+ /* Success. */
+ return gcvSTATUS_OK;
+
+OnError:
+ /* Return the staus. */
+ return status;
+}
+
+static gctUINT32
+_SetPage(gctUINT32 PageAddress, gctUINT32 PageAddressExt, gctBOOL Writable)
+{
+ gctUINT32 entry = PageAddress
+ /* AddressExt */
+ | (PageAddressExt << 4)
+ /* Ignore exception */
+ | (0 << 1)
+ /* Present */
+ | (1 << 0);
+
+ if (Writable)
+ {
+ /* writable */
+ entry |= (1 << 2);
+ }
+#if gcdUSE_MMU_EXCEPTION
+ else
+ {
+ /* If this page is read only, set exception bit to make exception happens
+ ** when writing to it. */
+ entry |= gcdMMU_STLB_EXCEPTION;
+ }
+#endif
+
+ return entry;
+}
+
+static gctUINT32
+_MtlbOffset(
+ gctUINT32 Address
+ )
+{
+ return (Address & gcdMMU_MTLB_MASK) >> gcdMMU_MTLB_SHIFT;
+}
+
+gctUINT32
+_AddressToIndex(
+ IN gcsADDRESS_AREA_PTR Area,
+ IN gctUINT32 Address
+ )
+{
+ gctUINT32 mtlbOffset = (Address & gcdMMU_MTLB_MASK) >> gcdMMU_MTLB_SHIFT;
+ gctUINT32 stlbOffset = (Address & gcdMMU_STLB_4K_MASK) >> gcdMMU_STLB_4K_SHIFT;
+
+ return (mtlbOffset - Area->dynamicMappingStart) * gcdMMU_STLB_4K_ENTRY_NUM + stlbOffset;
+}
+
+static gctUINT32_PTR
+_StlbEntry(
+ gcsADDRESS_AREA_PTR Area,
+ gctUINT32 Address
+ )
+{
+ gctUINT32 index = _AddressToIndex(Area, Address);
+
+ return &Area->pageTableLogical[index];
+}
+
+static gceSTATUS
+_FillFlatMappingInMap(
+ gcsADDRESS_AREA_PTR Area,
+ gctUINT32 Index,
+ gctUINT32 NumPages
+ )
+{
+ gceSTATUS status;
+ gctUINT32 i;
+ gctBOOL gotIt = gcvFALSE;
+ gctUINT32 index = Index;
+ gctUINT32_PTR map = Area->mapLogical;
+ gctUINT32 previous = ~0U;
+
+ /* Find node which contains index. */
+ for (i = 0; !gotIt && (i < Area->pageTableEntries);)
+ {
+ gctUINT32 numPages;
+
+ switch (gcmENTRY_TYPE(map[i]))
+ {
+ case gcvMMU_SINGLE:
+ if (i == index)
+ {
+ gotIt = gcvTRUE;
+ }
+ else
+ {
+ previous = i;
+ i = map[i] >> 8;
+ }
+ break;
+
+ case gcvMMU_FREE:
+ numPages = map[i] >> 8;
+ if (index >= i && index + NumPages - 1 < i + numPages)
+ {
+ gotIt = gcvTRUE;
+ }
+ else
+ {
+ previous = i;
+ i = map[i + 1];
+ }
+ break;
+
+ case gcvMMU_USED:
+ i++;
+ break;
+
+ default:
+ gcmkFATAL("MMU table correcupted at index %u!", index);
+ gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
+ }
+ }
+
+ switch (gcmENTRY_TYPE(map[i]))
+ {
+ case gcvMMU_SINGLE:
+ /* Unlink single node from free list. */
+ gcmkONERROR(
+ _Link(Area, previous, map[i] >> 8));
+ break;
+
+ case gcvMMU_FREE:
+ /* Split the node. */
+ {
+ gctUINT32 start;
+ gctUINT32 next = map[i+1];
+ gctUINT32 total = map[i] >> 8;
+ gctUINT32 countLeft = index - i;
+ gctUINT32 countRight = total - countLeft - NumPages;
+
+ if (countLeft)
+ {
+ start = i;
+ _AddFree(Area, previous, start, countLeft);
+ previous = start;
+ }
+
+ if (countRight)
+ {
+ start = index + NumPages;
+ _AddFree(Area, previous, start, countRight);
+ previous = start;
+ }
+
+ _Link(Area, previous, next);
+ }
+ break;
+ }
+
+ _FillMap(&map[index], NumPages, gcvMMU_USED);
+
+ return gcvSTATUS_OK;
+OnError:
+ return status;
+}
+
+static gceSTATUS
+_CollectFreeSpace(
+ IN gckMMU Mmu,
+ OUT gcsFreeSpaceNode_PTR *Array,
+ OUT gctINT * Size
+ )
+{
+ gceSTATUS status = gcvSTATUS_OK;
+ gctPOINTER pointer = gcvNULL;
+ gcsFreeSpaceNode_PTR array = gcvNULL;
+ gcsFreeSpaceNode_PTR node = gcvNULL;
+ gctINT size = 0;
+ gctINT i = 0;
+
+ for (i = 0; i < gcdMMU_MTLB_ENTRY_NUM; i++)
+ {
+ if (!Mmu->mtlbLogical[i])
+ {
+ if (!node)
+ {
+ /* This is the first entry of the free space. */
+ node += 1;
+ size++;
+
+ }
+ }
+ else if (node)
+ {
+ /* Reset the start. */
+ node = gcvNULL;
+ }
+ }
+
+ /* Allocate memory for the array. */
+ gcmkONERROR(gckOS_Allocate(Mmu->os,
+ gcmSIZEOF(*array) * size,
+ &pointer));
+
+ array = (gcsFreeSpaceNode_PTR)pointer;
+ node = gcvNULL;
+
+ for (i = 0, size = 0; i < gcdMMU_MTLB_ENTRY_NUM; i++)
+ {
+ if (!Mmu->mtlbLogical[i])
+ {
+ if (!node)
+ {
+ /* This is the first entry of the free space. */
+ node = &array[size++];
+
+ node->start = i;
+ node->entries = 0;
+ }
+
+ node->entries++;
+ }
+ else if (node)
+ {
+ /* Reset the start. */
+ node = gcvNULL;
+ }
+ }
+
+#if gcdMMU_TABLE_DUMP
+ for (i = 0; i < size; i++)
+ {
+ gckOS_Print("%s(%d): [%d]: start=%d, entries=%d.\n",
+ __FUNCTION__, __LINE__,
+ i,
+ array[i].start,
+ array[i].entries);
+ }
+#endif
+
+ *Array = array;
+ *Size = size;
+
+ return gcvSTATUS_OK;
+
+OnError:
+ if (pointer != gcvNULL)
+ {
+ gckOS_Free(Mmu->os, pointer);
+ }
+
+ return status;
+}
+
+gceSTATUS
+_GetMtlbFreeSpace(
+ IN gckMMU Mmu,
+ IN gctUINT32 NumEntries,
+ OUT gctUINT32 *MtlbStart,
+ OUT gctUINT32 *MtlbEnd
+ )
+{
+ gceSTATUS status = gcvSTATUS_OK;
+ gcsFreeSpaceNode_PTR nodeArray = gcvNULL;
+ gctINT i, nodeArraySize = 0;
+ gctINT numEntries = gcdMMU_MTLB_ENTRY_NUM;
+ gctINT32 mStart = -1;
+ gctINT32 mEnd = -1;
+
+ gcmkONERROR(_CollectFreeSpace(Mmu, &nodeArray, &nodeArraySize));
+
+ /* Find the smallest space for NumEntries */
+ for (i = 0; i < nodeArraySize; i++)
+ {
+ if (nodeArray[i].entries < numEntries && NumEntries <= (gctUINT32)nodeArray[i].entries)
+ {
+ numEntries = nodeArray[i].entries;
+
+ mStart = nodeArray[i].start;
+ mEnd = nodeArray[i].start + NumEntries - 1;
+ }
+ }
+
+ if (mStart == -1 && mEnd == -1)
+ {
+ gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
+ }
+
+ *MtlbStart = (gctUINT32)mStart;
+ *MtlbEnd = (gctUINT32)mEnd;
+
+OnError:
+ if (nodeArray)
+ {
+ gckOS_Free(Mmu->os, (gctPOINTER)nodeArray);
+ }
+
+ return status;
+}
+
+#if gcdPROCESS_ADDRESS_SPACE
+gctUINT32
+_StlbOffset(
+ gctUINT32 Address
+ )
+{
+ return (Address & gcdMMU_STLB_4K_MASK) >> gcdMMU_STLB_4K_SHIFT;
+}
+
+static gceSTATUS
+_AllocateStlb(
+ IN gckOS Os,
+ OUT gcsMMU_STLB_PTR *Stlb
+ )
+{
+ gceSTATUS status;
+ gcsMMU_STLB_PTR stlb;
+ gctPOINTER pointer;
+
+ /* Allocate slave TLB record. */
+ gcmkONERROR(gckOS_Allocate(Os, gcmSIZEOF(gcsMMU_STLB), &pointer));
+ stlb = pointer;
+
+ stlb->size = gcdMMU_STLB_4K_SIZE;
+
+ /* Allocate slave TLB entries. */
+ gcmkONERROR(gckOS_AllocateContiguous(
+ Os,
+ gcvFALSE,
+ &stlb->size,
+ &stlb->physical,
+ (gctPOINTER)&stlb->logical
+ ));
+
+ gcmkONERROR(gckOS_GetPhysicalAddress(Os, stlb->logical, &stlb->physBase));
+
+ gcmkVERIFY_OK(gckOS_CPUPhysicalToGPUPhysical(Os, stlb->physBase, &stlb->physBase));
+
+#if gcdUSE_MMU_EXCEPTION
+ _FillPageTable(stlb->logical, stlb->size / 4, gcdMMU_STLB_EXCEPTION);
+#else
+ gckOS_ZeroMemory(stlb->logical, stlb->size);
+#endif
+
+ *Stlb = stlb;
+
+ return gcvSTATUS_OK;
+
+OnError:
+ return status;
+}
+
+gceSTATUS
+_SetupProcessAddressSpace(
+ IN gckMMU Mmu
+ )
+{
+ gceSTATUS status;
+ gctINT numEntries = 0;
+ gctUINT32_PTR map;
+
+ numEntries = gcdPROCESS_ADDRESS_SPACE_SIZE
+ /* Address space mapped by one MTLB entry. */
+ / (1 << gcdMMU_MTLB_SHIFT);
+
+ area->dynamicMappingStart = 0;
+
+ area->pageTableSize = numEntries * 4096;
+
+ area->pageTableEntries = area->pageTableSize / gcmSIZEOF(gctUINT32);
+
+ gcmkONERROR(gckOS_Allocate(Mmu->os,
+ area->pageTableSize,
+ (void **)&area->mapLogical));
+
+ /* Initialization. */
+ map = area->mapLogical;
+ map[0] = (area->pageTableEntries << 8) | gcvMMU_FREE;
+ map[1] = ~0U;
+ area->heapList = 0;
+ area->freeNodes = gcvFALSE;
+
+ return gcvSTATUS_OK;
+
+OnError:
+ return status;
+}
+#else
+static gceSTATUS
+_FillFlatMapping(
+ IN gckMMU Mmu,
+ IN gctUINT64 PhysBase,
+ OUT gctSIZE_T Size,
+ OUT gctUINT32 *GpuBaseAddress
+ )
+{
+ gceSTATUS status;
+ gctUINT32 mtlb;
+ gctUINT32 physBase;
+ gcsADDRESS_AREA_PTR area = &Mmu->area[0];
+
+ /************************ look up existing flat mapping ranges. ****************/
+ gctUINT64 flatBase = PhysBase;
+ gctUINT32 flatSize = (gctUINT32)Size;
+ gctUINT64 base = flatBase;
+ gctUINT32 size = flatSize;
+ gctUINT64 end = base + size;
+ gctUINT32 i;
+
+ for (i = 0; i < Mmu->flatMappingRangeCount; i++)
+ {
+ if (base < Mmu->flatMappingRanges[i].start)
+ {
+ end = gcmMIN(end, Mmu->flatMappingRanges[i].start);
+ flatSize = (gctUINT32) (end - base);
+ }
+ else if (end > Mmu->flatMappingRanges[i].end)
+ {
+ base = gcmMAX(base, Mmu->flatMappingRanges[i].end);
+
+ flatBase = base;
+ flatSize = (gctUINT32) (end - base);
+ }
+ else
+ {
+ /* it is already inside existing flat mapping ranges. */
+ flatSize = 0;
+ }
+
+ if (flatSize == 0)
+ {
+ if (GpuBaseAddress)
+ {
+ *GpuBaseAddress = (gctUINT32) PhysBase;
+ }
+
+ return gcvSTATUS_OK;
+ }
+ }
+
+ Mmu->flatMappingRanges[Mmu->flatMappingRangeCount].start = flatBase;
+ Mmu->flatMappingRanges[Mmu->flatMappingRangeCount].end = flatBase + flatSize;
+ Mmu->flatMappingRangeCount++;
+
+ gcmkASSERT(Mmu->flatMappingRangeCount <= gcdMAX_FLAT_MAPPING_COUNT);
+
+ /* overwrite the orignal parameters */
+ PhysBase = flatBase;
+ physBase = (gctUINT32)flatBase;
+ Size = (gctSIZE_T)flatSize;
+
+ mtlb = _MtlbOffset(physBase);
+
+ /************************ Setup flat mapping in dynamic range. ****************/
+
+ if (area->dynamicMappingStart != gcvINVALID_ADDRESS && mtlb >= area->dynamicMappingStart &&
+ _MtlbOffset(PhysBase + Size - 1) < area->dynamicMappingEnd)
+ {
+ gctUINT32_PTR stlbEntry;
+ gctUINT i;
+
+ stlbEntry = _StlbEntry(area, physBase);
+
+ /* Must be aligned to page. */
+ gcmkASSERT((Size & 0xFFF) == 0);
+
+ for (i = 0; i < (Size / 4096); i++)
+ {
+ /* Flat mapping in page table. */
+ _WritePageEntry(stlbEntry, _SetPage(physBase + i * 4096, 0, gcvTRUE));
+ }
+
+ gcmkSAFECASTSIZET(size, Size);
+
+ /* Flat mapping in map. */
+ _FillFlatMappingInMap(area, _AddressToIndex(area, physBase), size / 4096);
+
+ return gcvSTATUS_OK;
+ }
+
+ /************************ Setup flat mapping in non dynamic range. **************/
+ {
+ gctBOOL mutex = gcvFALSE;
+ gctUINT32 physBaseExt = (gctUINT32) (PhysBase >> 32);
+ gctUINT32 start = physBase & ~gcdMMU_PAGE_64K_MASK;
+ gctUINT32 end = (gctUINT32) (physBase + Size - 1) & ~gcdMMU_PAGE_64K_MASK;
+ gctUINT32 mStart = start >> gcdMMU_MTLB_SHIFT;
+ gctUINT32 mEnd = end >> gcdMMU_MTLB_SHIFT;
+ gctUINT32 sStart = (start & gcdMMU_STLB_64K_MASK) >> gcdMMU_STLB_64K_SHIFT;
+ gctUINT32 sEnd = (end & gcdMMU_STLB_64K_MASK) >> gcdMMU_STLB_64K_SHIFT;
+ gctPHYS_ADDR_T physical;
+ gcsMMU_STLB_CHUNK_PTR newStlbChunk = gcvNULL;
+ gctUINT32 stlbIndex = 0;
+ gctUINT32 totalNewStlbs = 0;
+ gctINT32 firstMtlbEntry = -1;
+ gctUINT32 mtlbCurEntry;
+ gcsMMU_STLB_CHUNK_PTR curStlbChunk = gcvNULL;
+ gctUINT32 seqs[2] = {0, 0};
+ gctUINT32 seqIdx = 0;
+
+ /* Grab the mutex. */
+ gcmkONERROR(gckOS_AcquireMutex(Mmu->os, Mmu->pageTableMutex, gcvINFINITE));
+ mutex = gcvTRUE;
+
+ if (PhysBase + Size - 1 > 0xffffffff)
+ {
+ gctUINT32 mEntries;
+ gctUINT32 sEntries;
+
+ mEntries = (gctUINT32)(Size + (1 << gcdMMU_MTLB_SHIFT) - 1) / (1 << gcdMMU_MTLB_SHIFT);
+
+ gcmkONERROR(_GetMtlbFreeSpace(Mmu, mEntries, &mStart, &mEnd));
+
+ sStart = 0;
+ sEntries = (gctUINT32)(Size + gcdMMU_PAGE_64K_SIZE - 1) / gcdMMU_PAGE_64K_SIZE;
+ sEnd = (sEntries - 1) % gcdMMU_STLB_64K_ENTRY_NUM;
+ }
+
+ if (GpuBaseAddress)
+ {
+ *GpuBaseAddress = (mStart << gcdMMU_MTLB_SHIFT)
+ | (sStart << gcdMMU_STLB_64K_SHIFT)
+ | (physBase & gcdMMU_PAGE_64K_MASK);
+ }
+
+ mtlbCurEntry = mStart;
+
+ /* find all new stlbs, part of new flat mapping range may already have stlbs*/
+ while (mtlbCurEntry <= mEnd)
+ {
+ if (*(Mmu->mtlbLogical + mtlbCurEntry) == 0)
+ {
+ if (seqIdx < 2)
+ {
+ if (seqs[seqIdx] != 2)
+ {
+ seqs[seqIdx] = 1;
+ }
+ else if (seqIdx < 1)
+ {
+ seqs[++seqIdx] = 1;
+ }
+ else
+ {
+ gcmkASSERT(gcvFALSE);
+ }
+ }
+ else if (seqs[1] != 1)
+ {
+ gcmkPRINT("There is a hole in new flat mapping range, which is not correct");
+ }
+ totalNewStlbs++;
+ if (-1 == firstMtlbEntry)
+ {
+ firstMtlbEntry = mtlbCurEntry;
+ }
+ }
+ else
+ {
+ if (seqIdx < 2)
+ {
+ if (seqs[seqIdx] != 1)
+ {
+ seqs[seqIdx] = 2;
+ }
+ else if (seqIdx < 1)
+ {
+ seqs[++seqIdx] = 2;
+ }
+ else
+ {
+ gcmkASSERT(gcvFALSE);
+ }
+ }
+ else if (seqs[1] != 2)
+ {
+ gcmkPRINT("There is a hole in new flat mapping range, which is not correct");
+ }
+ }
+ mtlbCurEntry++;
+ }
+
+ /* Need allocate a new chunk of stlbs */
+ if (totalNewStlbs)
+ {
+ gctUINT32 allocFlag = gcvALLOC_FLAG_CONTIGUOUS;
+
+ gcmkONERROR(
+ gckOS_Allocate(Mmu->os,
+ sizeof(struct _gcsMMU_STLB_CHUNK),
+ (gctPOINTER *)&newStlbChunk));
+
+ newStlbChunk->mtlbEntryNum = totalNewStlbs;
+ newStlbChunk->next = gcvNULL;
+ newStlbChunk->physical = gcvNULL;
+ newStlbChunk->logical = gcvNULL;
+ newStlbChunk->size = gcdMMU_STLB_64K_SIZE * newStlbChunk->mtlbEntryNum;
+ newStlbChunk->pageCount = 0;
+ newStlbChunk->mtlbIndex = firstMtlbEntry;
+
+#if gcdENABLE_CACHEABLE_COMMAND_BUFFER
+ allocFlag |= gcvALLOC_FLAG_CACHEABLE;
+#endif
+
+ gcmkONERROR(
+ gckOS_AllocateNonPagedMemory(Mmu->os,
+ gcvFALSE,
+ allocFlag,
+ &newStlbChunk->size,
+ &newStlbChunk->physical,
+ (gctPOINTER)&newStlbChunk->logical));
+
+ gcmkONERROR(gckOS_ZeroMemory(newStlbChunk->logical, newStlbChunk->size));
+
+ gcmkONERROR(gckOS_GetPhysicalAddress(
+ Mmu->os,
+ newStlbChunk->logical,
+ &physical));
+
+ gcmkVERIFY_OK(gckOS_CPUPhysicalToGPUPhysical(
+ Mmu->os,
+ physical,
+ &physical));
+
+ gcmkSAFECASTPHYSADDRT(newStlbChunk->physBase, physical);
+
+ if (newStlbChunk->physBase & (gcdMMU_STLB_64K_SIZE - 1))
+ {
+ gcmkONERROR(gcvSTATUS_NOT_ALIGNED);
+ }
+ }
+
+ while (mStart <= mEnd)
+ {
+ gctUINT32 last = (mStart == mEnd) ? sEnd : (gcdMMU_STLB_64K_ENTRY_NUM - 1);
+ gctPHYS_ADDR_T stlbPhyBase;
+ gctUINT32_PTR stlbLogical;
+
+ gcmkASSERT(mStart < gcdMMU_MTLB_ENTRY_NUM);
+
+ if (*(Mmu->mtlbLogical + mStart) == 0)
+ {
+ gctUINT32 mtlbEntry;
+ curStlbChunk = newStlbChunk;
+ stlbPhyBase = curStlbChunk->physBase + (stlbIndex * gcdMMU_STLB_64K_SIZE);
+ stlbLogical = (gctUINT32_PTR)((gctUINT8_PTR)curStlbChunk->logical + (stlbIndex * gcdMMU_STLB_64K_SIZE));
+ physical = stlbPhyBase
+ /* 64KB page size */
+ | (1 << 2)
+ /* Ignore exception */
+ | (0 << 1)
+ /* Present */
+ | (1 << 0);
+
+ gcmkSAFECASTPHYSADDRT(mtlbEntry, physical);
+
+ _WritePageEntry(Mmu->mtlbLogical + mStart, mtlbEntry);
+
+#if gcdMMU_TABLE_DUMP
+ gckOS_Print("%s(%d): insert MTLB[%d]: %08x\n",
+ __FUNCTION__, __LINE__,
+ mStart,
+ _ReadPageEntry(Mmu->mtlbLogical + mStart));
+#endif
+
+#if gcdMMU_TABLE_DUMP
+ gckOS_Print("%s(%d): STLB: logical:%08x -> physical:%08x\n",
+ __FUNCTION__, __LINE__,
+ stlbLogical,
+ stlbPhyBase);
+#endif
+ ++stlbIndex;
+ }
+ else
+ {
+ gctUINT32 mtlbEntry = _ReadPageEntry(Mmu->mtlbLogical + mStart);
+ gctUINT stlbOffset;
+
+ curStlbChunk = (gcsMMU_STLB_CHUNK_PTR)Mmu->staticSTLB;
+
+ while (curStlbChunk)
+ {
+ if ((mStart >= curStlbChunk->mtlbIndex) &&
+ (mStart < (curStlbChunk->mtlbIndex + curStlbChunk->mtlbEntryNum)))
+ {
+ break;
+ }
+ curStlbChunk = curStlbChunk->next;
+ }
+ gcmkASSERT(curStlbChunk);
+ stlbOffset = mStart - curStlbChunk->mtlbIndex;
+
+ stlbPhyBase = curStlbChunk->physBase + (stlbOffset * gcdMMU_STLB_64K_SIZE);
+ stlbLogical = (gctUINT32_PTR)((gctUINT8_PTR)curStlbChunk->logical + (stlbOffset * gcdMMU_STLB_64K_SIZE));
+ if (stlbPhyBase != (mtlbEntry & gcdMMU_MTLB_ENTRY_STLB_MASK))
+ {
+ gcmkASSERT(0);
+ }
+ }
+
+ while (sStart <= last)
+ {
+ gcmkASSERT(!(start & gcdMMU_PAGE_64K_MASK));
+
+ _WritePageEntry(stlbLogical + sStart, _SetPage(start, physBaseExt, gcvTRUE));
+
+#if gcdMMU_TABLE_DUMP
+ gckOS_Print("%s(%d): insert STLB[%d]: %08x\n",
+ __FUNCTION__, __LINE__,
+ sStart,
+ _ReadPageEntry(stlbLogical + sStart));
+#endif
+ /* next page. */
+ start += gcdMMU_PAGE_64K_SIZE;
+ if (start == 0)
+ {
+ physBaseExt++;
+ }
+ sStart++;
+ curStlbChunk->pageCount++;
+ }
+
+ /* Flush STLB table. */
+ gcmkONERROR(gckOS_CacheClean(
+ Mmu->os,
+ 0,
+ curStlbChunk->physical,
+ 0,
+ curStlbChunk->logical,
+ curStlbChunk->size
+ ));
+
+ sStart = 0;
+ ++mStart;
+ }
+
+ gcmkASSERT(totalNewStlbs == stlbIndex);
+
+ if (newStlbChunk)
+ {
+ /* Insert the stlbChunk into staticSTLB. */
+ if (Mmu->staticSTLB == gcvNULL)
+ {
+ Mmu->staticSTLB = newStlbChunk;
+ }
+ else
+ {
+ gcmkASSERT(newStlbChunk != gcvNULL);
+ gcmkASSERT(newStlbChunk->next == gcvNULL);
+ newStlbChunk->next = Mmu->staticSTLB;
+ Mmu->staticSTLB = newStlbChunk;
+ }
+ }
+
+ /* Release the mutex. */
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(Mmu->os, Mmu->pageTableMutex));
+
+#if gcdENABLE_TRUST_APPLICATION
+ if (Mmu->hardware->options.secureMode == gcvSECURE_IN_TA)
+ {
+ gckKERNEL_SecurityMapMemory(Mmu->hardware->kernel, gcvNULL, physBase, (gctUINT32)Size/4096, &physBase);
+ }
+#endif
+
+ return gcvSTATUS_OK;
+OnError:
+ /* Roll back the allocation.
+ ** We don't need roll back mtlb programming as gckmONERROR
+ ** is only used during allocation time.
+ */
+ if (newStlbChunk)
+ {
+ if (newStlbChunk->physical)
+ {
+ gcmkVERIFY_OK(
+ gckOS_FreeContiguous(Mmu->os,
+ newStlbChunk->physical,
+ newStlbChunk->logical,
+ newStlbChunk->size));
+ }
+ gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Mmu->os, newStlbChunk));
+ }
+ if (mutex)
+ {
+ /* Release the mutex. */
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(Mmu->os, Mmu->pageTableMutex));
+ }
+ return status;
+ }
+}
+
+static gceSTATUS
+_SetupAddressArea(
+ IN gckOS Os,
+ IN gcsADDRESS_AREA_PTR Area,
+ IN gctUINT32 NumMTLBEntries
+ )
+{
+ gceSTATUS status;
+ gctUINT32_PTR map;
+
+ gcmkHEADER();
+ Area->pageTableSize = NumMTLBEntries * 4096;
+
+ gcmkSAFECASTSIZET(Area->pageTableEntries, Area->pageTableSize / gcmSIZEOF(gctUINT32));
+
+ gcmkONERROR(gckOS_Allocate(Os, Area->pageTableSize, (void **)&Area->mapLogical));
+
+ /* Initialization. */
+ map = Area->mapLogical;
+ map[0] = (Area->pageTableEntries << 8) | gcvMMU_FREE;
+ map[1] = ~0U;
+ Area->heapList = 0;
+ Area->freeNodes = gcvFALSE;
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ gcmkFOOTER();
+ return status;
+}
+
+static gceSTATUS
+_SetupDynamicSpace(
+ IN gckMMU Mmu
+ )
+{
+ gceSTATUS status;
+ gcsFreeSpaceNode_PTR nodeArray = gcvNULL;
+ gctINT i, nodeArraySize = 0;
+ gctPHYS_ADDR_T physical;
+ gctUINT32 address;
+ gctINT numEntries = 0;
+ gctBOOL acquired = gcvFALSE;
+ gctUINT32 mtlbEntry;
+ gcsADDRESS_AREA_PTR area = &Mmu->area[0];
+ gcsADDRESS_AREA_PTR areaSecure = &Mmu->area[gcvADDRESS_AREA_SECURE];
+ gctUINT32 secureAreaSize = 0;
+ gctUINT32 allocFlag = gcvALLOC_FLAG_CONTIGUOUS;
+
+ /* Find all the free address space. */
+ gcmkONERROR(_CollectFreeSpace(Mmu, &nodeArray, &nodeArraySize));
+
+ for (i = 0; i < nodeArraySize; i++)
+ {
+ if (nodeArray[i].entries > numEntries)
+ {
+ area->dynamicMappingStart = nodeArray[i].start;
+ numEntries = nodeArray[i].entries;
+ area->dynamicMappingEnd = area->dynamicMappingStart + numEntries;
+ }
+ }
+
+ gckOS_Free(Mmu->os, (gctPOINTER)nodeArray);
+
+#if gcdENABLE_TRUST_APPLICATION
+ if (gckHARDWARE_IsFeatureAvailable(Mmu->hardware, gcvFEATURE_SECURITY) == gcvSTATUS_TRUE)
+ {
+ secureAreaSize = gcdMMU_SECURE_AREA_SIZE;
+ }
+#endif
+
+ /* Setup secure address area if need. */
+ if (secureAreaSize > 0)
+ {
+ gcmkASSERT(numEntries > (gctINT)secureAreaSize);
+
+ areaSecure->dynamicMappingStart = area->dynamicMappingStart
+ + (numEntries - secureAreaSize);
+
+ gcmkONERROR(_SetupAddressArea(Mmu->os, areaSecure, secureAreaSize));
+
+ numEntries -= secureAreaSize;
+ }
+
+ /* Setup normal address area. */
+ gcmkONERROR(_SetupAddressArea(Mmu->os, area, numEntries));
+
+#if gcdENABLE_CACHEABLE_COMMAND_BUFFER
+ allocFlag |= gcvALLOC_FLAG_CACHEABLE;
+#endif
+
+ /* Construct Slave TLB. */
+ gcmkONERROR(gckOS_AllocateNonPagedMemory(Mmu->os,
+ gcvFALSE,
+ allocFlag,
+ &area->pageTableSize,
+ &area->pageTablePhysical,
+ (gctPOINTER)&area->pageTableLogical));
+
+#if gcdUSE_MMU_EXCEPTION
+ gcmkONERROR(_FillPageTable(area->pageTableLogical,
+ area->pageTableEntries,
+ /* Enable exception */
+ 1 << 1));
+#else
+ /* Invalidate all entries. */
+ gcmkONERROR(gckOS_ZeroMemory(area->pageTableLogical,
+ area->pageTableSize));
+#endif
+
+ gcmkONERROR(gckOS_GetPhysicalAddress(Mmu->os,
+ area->pageTableLogical,
+ &physical));
+
+ gcmkVERIFY_OK(gckOS_CPUPhysicalToGPUPhysical(Mmu->os,
+ physical,
+ &physical));
+
+ gcmkSAFECASTPHYSADDRT(address, physical);
+
+ /* Grab the mutex. */
+ gcmkONERROR(gckOS_AcquireMutex(Mmu->os, Mmu->pageTableMutex, gcvINFINITE));
+ acquired = gcvTRUE;
+
+ /* Map to Master TLB. */
+ for (i = (gctINT)area->dynamicMappingStart;
+ i < (gctINT)area->dynamicMappingStart + numEntries;
+ i++)
+ {
+ mtlbEntry = address
+ /* 4KB page size */
+ | (0 << 2)
+ /* Ignore exception */
+ | (0 << 1)
+ /* Present */
+ | (1 << 0);
+
+ _WritePageEntry(Mmu->mtlbLogical + i, mtlbEntry);
+
+#if gcdMMU_TABLE_DUMP
+ gckOS_Print("%s(%d): insert MTLB[%d]: %08x\n",
+ __FUNCTION__, __LINE__,
+ i,
+ _ReadPageEntry(Mmu->mtlbLogical + i));
+#endif
+ address += gcdMMU_STLB_4K_SIZE;
+ }
+
+ /* Release the mutex. */
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(Mmu->os, Mmu->pageTableMutex));
+
+ return gcvSTATUS_OK;
+
+OnError:
+ if (area->mapLogical)
+ {
+ gcmkVERIFY_OK(
+ gckOS_Free(Mmu->os, (gctPOINTER) area->mapLogical));
+
+
+ gcmkVERIFY_OK(
+ gckOS_FreeContiguous(Mmu->os,
+ area->pageTablePhysical,
+ (gctPOINTER) area->pageTableLogical,
+ area->pageTableSize));
+ }
+
+ if (acquired)
+ {
+ /* Release the mutex. */
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(Mmu->os, Mmu->pageTableMutex));
+ }
+
+ return status;
+}
+#endif
+
+gctUINT32
+_GetPageCountOfUsedNode(
+ gctUINT32_PTR Node
+ )
+{
+ gctUINT32 count;
+
+ count = gcmENTRY_COUNT(*Node);
+
+ if ((count << 8) == (~((1U<<8)-1)))
+ {
+ count = 1;
+ }
+
+ return count;
+}
+
+static gcsADDRESS_AREA_PTR
+_GetProcessArea(
+ IN gckMMU Mmu,
+ IN gctBOOL Secure
+ )
+{
+ gceADDRESS_AREA area = gcvADDRESS_AREA_NORMAL;
+
+#if gcdENABLE_TRUST_APPLICATION
+ if (Secure == gcvTRUE)
+ {
+ area = gcvADDRESS_AREA_SECURE;
+ }
+#endif
+
+ return &Mmu->area[area];
+}
+
+/*******************************************************************************
+**
+** _Construct
+**
+** Construct a new gckMMU object.
+**
+** INPUT:
+**
+** gckKERNEL Kernel
+** Pointer to an gckKERNEL object.
+**
+** gctSIZE_T MmuSize
+** Number of bytes for the page table.
+**
+** OUTPUT:
+**
+** gckMMU * Mmu
+** Pointer to a variable that receives the gckMMU object pointer.
+*/
+gceSTATUS
+_Construct(
+ IN gckKERNEL Kernel,
+ IN gctSIZE_T MmuSize,
+ OUT gckMMU * Mmu
+ )
+{
+ gckOS os;
+ gckHARDWARE hardware;
+ gceSTATUS status;
+ gckMMU mmu = gcvNULL;
+ gctUINT32_PTR map;
+ gctPOINTER pointer = gcvNULL;
+ gctUINT32 physBase;
+ gctUINT32 physSize;
+ gctUINT32 contiguousBase;
+ gctUINT32 contiguousSize = 0;
+ gctUINT32 externalBase;
+ gctUINT32 externalSize = 0;
+ gctUINT32 gpuAddress;
+ gctPHYS_ADDR_T gpuPhysical;
+ gcsADDRESS_AREA_PTR area = gcvNULL;
+ gctUINT32 allocFlag = gcvALLOC_FLAG_CONTIGUOUS;
+
+ gcmkHEADER_ARG("Kernel=0x%x MmuSize=%lu", Kernel, MmuSize);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
+ gcmkVERIFY_ARGUMENT(MmuSize > 0);
+ gcmkVERIFY_ARGUMENT(Mmu != gcvNULL);
+
+ /* Extract the gckOS object pointer. */
+ os = Kernel->os;
+ gcmkVERIFY_OBJECT(os, gcvOBJ_OS);
+
+ /* Extract the gckHARDWARE object pointer. */
+ hardware = Kernel->hardware;
+ gcmkVERIFY_OBJECT(hardware, gcvOBJ_HARDWARE);
+
+ /* Allocate memory for the gckMMU object. */
+ gcmkONERROR(gckOS_Allocate(os, sizeof(struct _gckMMU), &pointer));
+
+ gckOS_ZeroMemory(pointer, sizeof(struct _gckMMU));
+
+ mmu = pointer;
+
+ /* Initialize the gckMMU object. */
+ mmu->object.type = gcvOBJ_MMU;
+ mmu->os = os;
+ mmu->hardware = hardware;
+ mmu->pageTableMutex = gcvNULL;
+ mmu->mtlbLogical = gcvNULL;
+ mmu->staticSTLB = gcvNULL;
+ mmu->enabled = gcvFALSE;
+ gcsLIST_Init(&mmu->hardwareList);
+
+
+ area = &mmu->area[0];
+ area->mapLogical = gcvNULL;
+ area->pageTableLogical = gcvNULL;
+
+ /* Create the page table mutex. */
+ gcmkONERROR(gckOS_CreateMutex(os, &mmu->pageTableMutex));
+
+ if (hardware->mmuVersion == 0)
+ {
+ area->pageTableSize = MmuSize;
+
+ /* Construct address space management table. */
+ gcmkONERROR(gckOS_Allocate(mmu->os,
+ area->pageTableSize,
+ &pointer));
+
+ area->mapLogical = pointer;
+
+#if gcdENABLE_CACHEABLE_COMMAND_BUFFER
+ allocFlag |= gcvALLOC_FLAG_CACHEABLE;
+#endif
+
+ /* Construct page table read by GPU. */
+ gcmkONERROR(gckOS_AllocateNonPagedMemory(mmu->os,
+ gcvFALSE,
+ allocFlag,
+ &area->pageTableSize,
+ &area->pageTablePhysical,
+ (gctPOINTER)&area->pageTableLogical));
+
+
+ /* Compute number of entries in page table. */
+ gcmkSAFECASTSIZET(area->pageTableEntries, area->pageTableSize / sizeof(gctUINT32));
+
+ /* Mark all pages as free. */
+ map = area->mapLogical;
+
+ _FillPageTable(area->pageTableLogical, area->pageTableEntries, mmu->safeAddress);
+
+ map[0] = (area->pageTableEntries << 8) | gcvMMU_FREE;
+ map[1] = ~0U;
+ area->heapList = 0;
+ area->freeNodes = gcvFALSE;
+
+ status = gckOS_QueryOption(mmu->os, "contiguousBase", &contiguousBase);
+
+ if (gcmIS_SUCCESS(status))
+ {
+ status = gckOS_QueryOption(mmu->os, "contiguousSize", &contiguousSize);
+ }
+
+ if (gcmIS_SUCCESS(status) && contiguousSize)
+ {
+ mmu->contiguousBaseAddress = contiguousBase - Kernel->hardware->baseAddress;
+ }
+
+ }
+ else
+ {
+ /* Allocate the 4K mode MTLB table. */
+ mmu->mtlbSize = gcdMMU_MTLB_SIZE;
+
+#if gcdENABLE_CACHEABLE_COMMAND_BUFFER
+ allocFlag |= gcvALLOC_FLAG_CACHEABLE;
+#endif
+
+ gcmkONERROR(
+ gckOS_AllocateNonPagedMemory(os,
+ gcvFALSE,
+ allocFlag,
+ &mmu->mtlbSize,
+ &mmu->mtlbPhysical,
+ &pointer));
+
+ mmu->mtlbLogical = pointer;
+
+ area->dynamicMappingStart = gcvINVALID_ADDRESS;
+
+#if gcdPROCESS_ADDRESS_SPACE
+ _FillPageTable(pointer, mmu->mtlbSize / 4, gcdMMU_MTLB_EXCEPTION);
+
+ /* Allocate a array to store stlbs. */
+ gcmkONERROR(gckOS_Allocate(os, mmu->mtlbSize, &mmu->stlbs));
+
+ gckOS_ZeroMemory(mmu->stlbs, mmu->mtlbSize);
+
+ for (i = 0; i < gcdMAX_GPU_COUNT; i++)
+ {
+ gcmkONERROR(gckOS_AtomConstruct(os, &mmu->pageTableDirty[i]));
+ }
+
+ _SetupProcessAddressSpace(mmu);
+
+ /* Map kernel command buffer in MMU. */
+ for (i = 0; i < gcdCOMMAND_QUEUES; i++)
+ {
+ gcmkONERROR(gckOS_GetPhysicalAddress(
+ mmu->os,
+ Kernel->command->queues[i].logical,
+ &gpuPhysical
+ ));
+
+ gcmkVERIFY_OK(gckOS_CPUPhysicalToGPUPhysical(
+ mmu->os,
+ gpuPhysical,
+ &gpuPhysical
+ ));
+
+ gcmkSAFECASTPHYSADDRT(gpuAddress, gpuPhysical);
+
+ gcmkONERROR(gckMMU_FlatMapping(mmu, gpuAddress, 1));
+ }
+#else
+ /* Invalid all the entries. */
+ gcmkONERROR(
+ gckOS_ZeroMemory(pointer, mmu->mtlbSize));
+
+ gcmkONERROR(
+ gckOS_QueryOption(mmu->os, "physBase", &physBase));
+
+ gcmkONERROR(
+ gckOS_QueryOption(mmu->os, "physSize", &physSize));
+
+ gcmkONERROR(
+ gckOS_CPUPhysicalToGPUPhysical(mmu->os, physBase, &gpuPhysical));
+
+ gcmkSAFECASTPHYSADDRT(gpuAddress, gpuPhysical);
+
+ if (physSize)
+ {
+ /* Setup user specified flat mapping. */
+ gcmkONERROR(_FillFlatMapping(mmu, gpuAddress, physSize, gcvNULL));
+ }
+
+#ifndef EMULATOR
+ if (!_ReadPageEntry(mmu->mtlbLogical + 0))
+ {
+ gctUINT32 mtlbEntry;
+ /*
+ * Reserved 0~4MB space.
+ * 64KB page size, Ingore exception, Not Present.
+ */
+ mtlbEntry = (1 << 2)
+ | (0 << 1)
+ | (0 << 0);
+
+ _WritePageEntry(mmu->mtlbLogical + 0, mtlbEntry);
+ }
+#endif
+
+ status = gckOS_QueryOption(mmu->os, "contiguousBase", &contiguousBase);
+
+ if (gcmIS_SUCCESS(status))
+ {
+ status = gckOS_QueryOption(mmu->os, "contiguousSize", &contiguousSize);
+ }
+
+ if (gcmIS_SUCCESS(status) && contiguousSize)
+ {
+ gctUINT64 gpuContiguousBase;
+ gctUINT32 contiguousBaseAddress;
+
+ gcmkONERROR(gckOS_CPUPhysicalToGPUPhysical(mmu->os, contiguousBase, &gpuContiguousBase));
+
+ /* Setup flat mapping for reserved memory (VIDMEM). */
+ gcmkONERROR(_FillFlatMapping(mmu, gpuContiguousBase, contiguousSize, &contiguousBaseAddress));
+
+ mmu->contiguousBaseAddress = contiguousBaseAddress;
+ }
+
+ status = gckOS_QueryOption(mmu->os, "externalBase", &externalBase);
+
+ if (gcmIS_SUCCESS(status))
+ {
+ status = gckOS_QueryOption(mmu->os, "externalSize", &externalSize);
+ }
+
+ if (gcmIS_SUCCESS(status) && externalSize)
+ {
+ gctUINT64 gpuExternalBase;
+ gctUINT32 externalBaseAddress;
+
+ gcmkONERROR(gckOS_CPUPhysicalToGPUPhysical(mmu->os, externalBase, &gpuExternalBase));
+
+ /* Setup flat mapping for external memory. */
+ gcmkONERROR(_FillFlatMapping(mmu, gpuExternalBase, externalSize, &externalBaseAddress));
+
+ mmu->externalBaseAddress = externalBaseAddress;
+ }
+
+ gcmkONERROR(_SetupDynamicSpace(mmu));
+#endif
+
+ /* Flush MTLB table. */
+ gcmkONERROR(gckOS_CacheClean(
+ os,
+ 0,
+ mmu->mtlbPhysical,
+ 0,
+ mmu->mtlbLogical,
+ mmu->mtlbSize
+ ));
+ }
+
+ mmu->safePageSize = 4096;
+
+ gcmkONERROR(gckOS_AllocateContiguous(
+ os,
+ gcvFALSE,
+ &mmu->safePageSize,
+ &mmu->safePagePhysical,
+ &mmu->safePageLogical
+ ));
+
+ gcmkONERROR(gckOS_GetPhysicalAddress(
+ os,
+ mmu->safePageLogical,
+ &gpuPhysical
+ ));
+
+ gcmkVERIFY_OK(gckOS_CPUPhysicalToGPUPhysical(
+ os,
+ gpuPhysical,
+ &gpuPhysical
+ ));
+
+ gcmkSAFECASTPHYSADDRT(mmu->safeAddress, gpuPhysical);
+
+ gckOS_ZeroMemory(mmu->safePageLogical, mmu->safePageSize);
+
+ gcmkONERROR(gckQUEUE_Allocate(os, &mmu->recentFreedAddresses, 16));
+
+ /* Return the gckMMU object pointer. */
+ *Mmu = mmu;
+
+ /* Success. */
+ gcmkFOOTER_ARG("*Mmu=0x%x", *Mmu);
+ return gcvSTATUS_OK;
+
+OnError:
+ /* Roll back. */
+ if (mmu != gcvNULL)
+ {
+ if (area != gcvNULL && area->mapLogical != gcvNULL)
+ {
+ gcmkVERIFY_OK(
+ gckOS_Free(os, (gctPOINTER) area->mapLogical));
+
+
+ gcmkVERIFY_OK(
+ gckOS_FreeContiguous(os,
+ area->pageTablePhysical,
+ (gctPOINTER) area->pageTableLogical,
+ area->pageTableSize));
+ }
+
+ if (mmu->mtlbLogical != gcvNULL)
+ {
+ gcmkVERIFY_OK(
+ gckOS_FreeContiguous(os,
+ mmu->mtlbPhysical,
+ (gctPOINTER) mmu->mtlbLogical,
+ mmu->mtlbSize));
+ }
+
+ if (mmu->pageTableMutex != gcvNULL)
+ {
+ /* Delete the mutex. */
+ gcmkVERIFY_OK(
+ gckOS_DeleteMutex(os, mmu->pageTableMutex));
+ }
+
+ gcmkVERIFY_OK(gckQUEUE_Free(os, &mmu->recentFreedAddresses));
+
+ /* Mark the gckMMU object as unknown. */
+ mmu->object.type = gcvOBJ_UNKNOWN;
+
+ /* Free the allocates memory. */
+ gcmkVERIFY_OK(gcmkOS_SAFE_FREE(os, mmu));
+ }
+
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+/*******************************************************************************
+**
+** _Destroy
+**
+** Destroy a gckMMU object.
+**
+** INPUT:
+**
+** gckMMU Mmu
+** Pointer to an gckMMU object.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+_Destroy(
+ IN gckMMU Mmu
+ )
+{
+ gctUINT32 i;
+ gcmkHEADER_ARG("Mmu=0x%x", Mmu);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Mmu, gcvOBJ_MMU);
+
+ while (Mmu->staticSTLB != gcvNULL)
+ {
+ gcsMMU_STLB_CHUNK_PTR pre = Mmu->staticSTLB;
+ Mmu->staticSTLB = pre->next;
+
+ if (pre->physical != gcvNULL)
+ {
+ gcmkVERIFY_OK(
+ gckOS_FreeContiguous(Mmu->os,
+ pre->physical,
+ pre->logical,
+ pre->size));
+ }
+
+ if (pre->mtlbEntryNum != 0)
+ {
+ gctUINT i;
+ for (i = 0; i < pre->mtlbEntryNum; ++i)
+ {
+ _WritePageEntry(Mmu->mtlbLogical + pre->mtlbIndex + i, 0);
+#if gcdMMU_TABLE_DUMP
+ gckOS_Print("%s(%d): clean MTLB[%d]\n",
+ __FUNCTION__, __LINE__,
+ pre->mtlbIndex + i);
+#endif
+ }
+ }
+
+ gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Mmu->os, pre));
+ }
+
+ if (Mmu->hardware->mmuVersion != 0)
+ {
+ gcmkVERIFY_OK(
+ gckOS_FreeContiguous(Mmu->os,
+ Mmu->mtlbPhysical,
+ (gctPOINTER) Mmu->mtlbLogical,
+ Mmu->mtlbSize));
+ }
+
+ for (i = 0; i < gcvADDRESS_AREA_COUNT; i++)
+ {
+ gcsADDRESS_AREA_PTR area = &Mmu->area[i];
+
+ /* Free address space management table. */
+ if (area->mapLogical != gcvNULL)
+ {
+ gcmkVERIFY_OK(
+ gckOS_Free(Mmu->os, (gctPOINTER) area->mapLogical));
+ }
+
+ if (area->pageTableLogical != gcvNULL)
+ {
+ /* Free page table. */
+ gcmkVERIFY_OK(
+ gckOS_FreeContiguous(Mmu->os,
+ area->pageTablePhysical,
+ (gctPOINTER) area->pageTableLogical,
+ area->pageTableSize));
+ }
+ }
+
+ /* Delete the page table mutex. */
+ gcmkVERIFY_OK(gckOS_DeleteMutex(Mmu->os, Mmu->pageTableMutex));
+
+#if gcdPROCESS_ADDRESS_SPACE
+ for (i = 0; i < Mmu->mtlbSize / 4; i++)
+ {
+ struct _gcsMMU_STLB_CHUNK *stlb = ((struct _gcsMMU_STLB_CHUNK **)Mmu->stlbs)[i];
+
+ if (stlb)
+ {
+ gcmkVERIFY_OK(gckOS_FreeContiguous(
+ Mmu->os,
+ stlb->physical,
+ stlb->logical,
+ stlb->size));
+
+ gcmkOS_SAFE_FREE(Mmu->os, stlb);
+ }
+ }
+
+ gcmkOS_SAFE_FREE(Mmu->os, Mmu->stlbs);
+#endif
+
+ if (Mmu->safePageLogical != gcvNULL)
+ {
+ gcmkVERIFY_OK(gckOS_FreeContiguous(
+ Mmu->os,
+ Mmu->safePagePhysical,
+ Mmu->safePageLogical,
+ Mmu->safePageSize
+ ));
+ }
+
+ gcmkVERIFY_OK(gckQUEUE_Free(Mmu->os, &Mmu->recentFreedAddresses));
+
+ /* Mark the gckMMU object as unknown. */
+ Mmu->object.type = gcvOBJ_UNKNOWN;
+
+ /* Free the gckMMU object. */
+ gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Mmu->os, Mmu));
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+}
+
+/*******************************************************************************
+** _AdjstIndex
+**
+** Adjust the index from which we search for a usable node to make sure
+** index allocated is greater than Start.
+*/
+gceSTATUS
+_AdjustIndex(
+ IN gckMMU Mmu,
+ IN gctUINT32 Index,
+ IN gctUINT32 PageCount,
+ IN gctUINT32 Start,
+ OUT gctUINT32 * IndexAdjusted
+ )
+{
+ gceSTATUS status;
+ gctUINT32 index = Index;
+ gcsADDRESS_AREA_PTR area = &Mmu->area[0];
+ gctUINT32_PTR map = area->mapLogical;
+
+ gcmkHEADER();
+
+ for (; index < area->pageTableEntries;)
+ {
+ gctUINT32 result = 0;
+ gctUINT32 nodeSize = 0;
+
+ if (index >= Start)
+ {
+ break;
+ }
+
+ switch (gcmENTRY_TYPE(map[index]))
+ {
+ case gcvMMU_SINGLE:
+ nodeSize = 1;
+ break;
+
+ case gcvMMU_FREE:
+ nodeSize = map[index] >> 8;
+ break;
+
+ default:
+ gcmkFATAL("MMU table correcupted at index %u!", index);
+ gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
+ }
+
+ if (nodeSize > PageCount)
+ {
+ result = index + (nodeSize - PageCount);
+
+ if (result >= Start)
+ {
+ break;
+ }
+ }
+
+ switch (gcmENTRY_TYPE(map[index]))
+ {
+ case gcvMMU_SINGLE:
+ index = map[index] >> 8;
+ break;
+
+ case gcvMMU_FREE:
+ index = map[index + 1];
+ break;
+
+ default:
+ gcmkFATAL("MMU table correcupted at index %u!", index);
+ gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
+ }
+ }
+
+ *IndexAdjusted = index;
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ gcmkFOOTER();
+ return status;
+}
+
+gceSTATUS
+gckMMU_Construct(
+ IN gckKERNEL Kernel,
+ IN gctSIZE_T MmuSize,
+ OUT gckMMU * Mmu
+ )
+{
+#if gcdSHARED_PAGETABLE
+ gceSTATUS status;
+ gctPOINTER pointer;
+
+ gcmkHEADER_ARG("Kernel=0x%08x", Kernel);
+
+ if (sharedPageTable == gcvNULL)
+ {
+ gcmkONERROR(
+ gckOS_Allocate(Kernel->os,
+ sizeof(struct _gcsSharedPageTable),
+ &pointer));
+ sharedPageTable = pointer;
+
+ gcmkONERROR(
+ gckOS_ZeroMemory(sharedPageTable,
+ sizeof(struct _gcsSharedPageTable)));
+
+ gcmkONERROR(_Construct(Kernel, MmuSize, &sharedPageTable->mmu));
+ }
+
+ *Mmu = sharedPageTable->mmu;
+
+ sharedPageTable->hardwares[sharedPageTable->reference] = Kernel->hardware;
+
+ sharedPageTable->reference++;
+
+ gcmkFOOTER_ARG("sharedPageTable->reference=%lu", sharedPageTable->reference);
+ return gcvSTATUS_OK;
+
+OnError:
+ if (sharedPageTable)
+ {
+ if (sharedPageTable->mmu)
+ {
+ gcmkVERIFY_OK(gckMMU_Destroy(sharedPageTable->mmu));
+ }
+
+ gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Kernel->os, sharedPageTable));
+ }
+
+ gcmkFOOTER();
+ return status;
+#else
+ return _Construct(Kernel, MmuSize, Mmu);
+#endif
+}
+
+gceSTATUS
+gckMMU_Destroy(
+ IN gckMMU Mmu
+ )
+{
+#if gcdSHARED_PAGETABLE
+ gckOS os = Mmu->os;
+
+ sharedPageTable->reference--;
+
+ if (sharedPageTable->reference == 0)
+ {
+ if (sharedPageTable->mmu)
+ {
+ gcmkVERIFY_OK(_Destroy(Mmu));
+ }
+
+ gcmkVERIFY_OK(gcmkOS_SAFE_FREE(os, sharedPageTable));
+ }
+
+ return gcvSTATUS_OK;
+#else
+ return _Destroy(Mmu);
+#endif
+}
+
+/*******************************************************************************
+**
+** gckMMU_AllocatePages
+**
+** Allocate pages inside the page table.
+**
+** INPUT:
+**
+** gckMMU Mmu
+** Pointer to an gckMMU object.
+**
+** gctSIZE_T PageCount
+** Number of pages to allocate.
+**
+** OUTPUT:
+**
+** gctPOINTER * PageTable
+** Pointer to a variable that receives the base address of the page
+** table.
+**
+** gctUINT32 * Address
+** Pointer to a variable that receives the hardware specific address.
+*/
+gceSTATUS
+_AllocatePages(
+ IN gckMMU Mmu,
+ IN gctSIZE_T PageCount,
+ IN gceSURF_TYPE Type,
+ IN gctBOOL Secure,
+ OUT gctPOINTER * PageTable,
+ OUT gctUINT32 * Address
+ )
+{
+ gceSTATUS status;
+ gctBOOL mutex = gcvFALSE;
+ gctUINT32 index = 0, previous = ~0U, left;
+ gctUINT32_PTR map;
+ gctBOOL gotIt;
+ gctUINT32 address;
+ gctUINT32 pageCount;
+ gcsADDRESS_AREA_PTR area = _GetProcessArea(Mmu, Secure);
+
+ gcmkHEADER_ARG("Mmu=0x%x PageCount=%lu", Mmu, PageCount);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Mmu, gcvOBJ_MMU);
+ gcmkVERIFY_ARGUMENT(PageCount > 0);
+ gcmkVERIFY_ARGUMENT(PageTable != gcvNULL);
+
+ if (PageCount > area->pageTableEntries)
+ {
+ /* Not enough pages avaiable. */
+ gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
+ }
+
+ gcmkSAFECASTSIZET(pageCount, PageCount);
+
+#if gcdBOUNDARY_CHECK
+ /* Extra pages as bounary. */
+ pageCount += gcdBOUNDARY_CHECK * 2;
+#endif
+
+ /* Grab the mutex. */
+ gcmkONERROR(gckOS_AcquireMutex(Mmu->os, Mmu->pageTableMutex, gcvINFINITE));
+ mutex = gcvTRUE;
+
+ /* Cast pointer to page table. */
+ for (map = area->mapLogical, gotIt = gcvFALSE; !gotIt;)
+ {
+ index = area->heapList;
+
+ if ((Mmu->hardware->mmuVersion == 0) && (Type == gcvSURF_VERTEX))
+ {
+ gcmkONERROR(_AdjustIndex(
+ Mmu,
+ index,
+ pageCount,
+ gcdVERTEX_START / gcmSIZEOF(gctUINT32),
+ &index
+ ));
+ }
+
+ /* Walk the heap list. */
+ for (; !gotIt && (index < area->pageTableEntries);)
+ {
+ /* Check the node type. */
+ switch (gcmENTRY_TYPE(map[index]))
+ {
+ case gcvMMU_SINGLE:
+ /* Single odes are valid if we only need 1 page. */
+ if (pageCount == 1)
+ {
+ gotIt = gcvTRUE;
+ }
+ else
+ {
+ /* Move to next node. */
+ previous = index;
+ index = map[index] >> 8;
+ }
+ break;
+
+ case gcvMMU_FREE:
+ /* Test if the node has enough space. */
+ if (pageCount <= (map[index] >> 8))
+ {
+ gotIt = gcvTRUE;
+ }
+ else
+ {
+ /* Move to next node. */
+ previous = index;
+ index = map[index + 1];
+ }
+ break;
+
+ default:
+ gcmkFATAL("MMU table correcupted at index %u!", index);
+ gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
+ }
+ }
+
+ /* Test if we are out of memory. */
+ if (index >= area->pageTableEntries)
+ {
+ if (area->freeNodes)
+ {
+ /* Time to move out the trash! */
+ gcmkONERROR(_Collect(area));
+
+ /* We are going to search from start, so reset previous to start. */
+ previous = ~0U;
+ }
+ else
+ {
+ /* Out of resources. */
+ gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
+ }
+ }
+ }
+
+ switch (gcmENTRY_TYPE(map[index]))
+ {
+ case gcvMMU_SINGLE:
+ /* Unlink single node from free list. */
+ gcmkONERROR(
+ _Link(area, previous, map[index] >> 8));
+ break;
+
+ case gcvMMU_FREE:
+ /* Check how many pages will be left. */
+ left = (map[index] >> 8) - pageCount;
+ switch (left)
+ {
+ case 0:
+ /* The entire node is consumed, just unlink it. */
+ gcmkONERROR(
+ _Link(area, previous, map[index + 1]));
+ break;
+
+ case 1:
+ /* One page will remain. Convert the node to a single node and
+ ** advance the index. */
+ map[index] = (map[index + 1] << 8) | gcvMMU_SINGLE;
+ index ++;
+ break;
+
+ default:
+ /* Enough pages remain for a new node. However, we will just adjust
+ ** the size of the current node and advance the index. */
+ map[index] = (left << 8) | gcvMMU_FREE;
+ index += left;
+ break;
+ }
+ break;
+ }
+
+ /* Mark node as used. */
+ gcmkONERROR(_FillMap(&map[index], pageCount, gcvMMU_USED));
+
+#if gcdBOUNDARY_CHECK
+ index += gcdBOUNDARY_CHECK;
+#endif
+
+ /* Record pageCount of allocated node at the beginning of node. */
+ if (pageCount == 1)
+ {
+ map[index] = (~((1U<<8)-1)) | gcvMMU_USED;
+ }
+ else
+ {
+ map[index] = (pageCount << 8) | gcvMMU_USED;
+ }
+
+ if (area->pageTableLogical != gcvNULL)
+ {
+ /* Return pointer to page table. */
+ *PageTable = &area->pageTableLogical[index];
+ }
+ else
+ {
+ /* Page table for secure area is handled in trust application. */
+ *PageTable = gcvNULL;
+ }
+
+ /* Build virtual address. */
+ if (Mmu->hardware->mmuVersion == 0)
+ {
+ gcmkONERROR(
+ gckHARDWARE_BuildVirtualAddress(Mmu->hardware, index, 0, &address));
+ }
+ else
+ {
+ gctUINT32 masterOffset = index / gcdMMU_STLB_4K_ENTRY_NUM
+ + area->dynamicMappingStart;
+ gctUINT32 slaveOffset = index % gcdMMU_STLB_4K_ENTRY_NUM;
+
+ address = (masterOffset << gcdMMU_MTLB_SHIFT)
+ | (slaveOffset << gcdMMU_STLB_4K_SHIFT);
+ }
+
+ if (Address != gcvNULL)
+ {
+ *Address = address;
+ }
+
+ /* Release the mutex. */
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(Mmu->os, Mmu->pageTableMutex));
+
+ /* Success. */
+ gcmkFOOTER_ARG("*PageTable=0x%x *Address=%08x",
+ *PageTable, gcmOPT_VALUE(Address));
+ return gcvSTATUS_OK;
+
+OnError:
+
+ if (mutex)
+ {
+ /* Release the mutex. */
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(Mmu->os, Mmu->pageTableMutex));
+ }
+
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+/*******************************************************************************
+**
+** gckMMU_FreePages
+**
+** Free pages inside the page table.
+**
+** INPUT:
+**
+** gckMMU Mmu
+** Pointer to an gckMMU object.
+**
+** gctPOINTER PageTable
+** Base address of the page table to free.
+**
+** gctSIZE_T PageCount
+** Number of pages to free.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+_FreePages(
+ IN gckMMU Mmu,
+ IN gctBOOL Secure,
+ IN gctUINT32 Address,
+ IN gctPOINTER PageTable,
+ IN gctSIZE_T PageCount
+ )
+{
+ gctUINT32_PTR node;
+ gceSTATUS status;
+ gctBOOL acquired = gcvFALSE;
+ gctUINT32 pageCount;
+ gcuQUEUEDATA data;
+ gcsADDRESS_AREA_PTR area = _GetProcessArea(Mmu, Secure);
+
+ gcmkHEADER_ARG("Mmu=0x%x PageTable=0x%x PageCount=%lu",
+ Mmu, PageTable, PageCount);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Mmu, gcvOBJ_MMU);
+ gcmkVERIFY_ARGUMENT(PageCount > 0);
+
+ gcmkSAFECASTSIZET(pageCount, PageCount);
+
+#if gcdBOUNDARY_CHECK
+ pageCount += gcdBOUNDARY_CHECK * 2;
+#endif
+
+ /* Get the node by index. */
+ node = area->mapLogical + ((gctUINT32_PTR)PageTable - area->pageTableLogical);
+
+ if (pageCount != _GetPageCountOfUsedNode(node))
+ {
+ gcmkONERROR(gcvSTATUS_INVALID_REQUEST);
+ }
+
+#if gcdBOUNDARY_CHECK
+ node -= gcdBOUNDARY_CHECK;
+#endif
+
+ gcmkONERROR(gckOS_AcquireMutex(Mmu->os, Mmu->pageTableMutex, gcvINFINITE));
+ acquired = gcvTRUE;
+
+ if (Mmu->hardware->mmuVersion == 0)
+ {
+ _FillPageTable(PageTable, pageCount, Mmu->safeAddress);
+ }
+
+ if (pageCount == 1)
+ {
+ /* Single page node. */
+ node[0] = (~((1U<<8)-1)) | gcvMMU_SINGLE;
+
+ if (PageTable != gcvNULL)
+ {
+#if gcdUSE_MMU_EXCEPTION
+ /* Enable exception */
+ _WritePageEntry(PageTable, (1 << 1));
+#else
+ _WritePageEntry(PageTable, 0);
+#endif
+ }
+ }
+ else
+ {
+ /* Mark the node as free. */
+ node[0] = (pageCount << 8) | gcvMMU_FREE;
+ node[1] = ~0U;
+
+ if (PageTable != gcvNULL)
+ {
+#if gcdUSE_MMU_EXCEPTION
+ /* Enable exception */
+ gcmkVERIFY_OK(_FillPageTable(PageTable, (gctUINT32)PageCount, 1 << 1));
+#else
+ gcmkVERIFY_OK(_FillPageTable(PageTable, (gctUINT32)PageCount, 0));
+#endif
+ }
+ }
+
+ /* We have free nodes. */
+ area->freeNodes = gcvTRUE;
+
+ /* Record freed address range. */
+ data.addressData.start = Address;
+ data.addressData.end = Address + (gctUINT32)PageCount * 4096;
+ gckQUEUE_Enqueue(&Mmu->recentFreedAddresses, &data);
+
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(Mmu->os, Mmu->pageTableMutex));
+ acquired = gcvFALSE;
+
+#if gcdENABLE_TRUST_APPLICATION
+ if (Mmu->hardware->options.secureMode == gcvSECURE_IN_TA)
+ {
+ gckKERNEL_SecurityUnmapMemory(Mmu->hardware->kernel, Address, (gctUINT32)PageCount);
+ }
+#endif
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ if (acquired)
+ {
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(Mmu->os, Mmu->pageTableMutex));
+ }
+
+ gcmkFOOTER();
+ return status;
+}
+
+gceSTATUS
+gckMMU_AllocatePages(
+ IN gckMMU Mmu,
+ IN gctSIZE_T PageCount,
+ OUT gctPOINTER * PageTable,
+ OUT gctUINT32 * Address
+ )
+{
+ return gckMMU_AllocatePagesEx(
+ Mmu, PageCount, gcvSURF_TYPE_UNKNOWN, gcvFALSE, PageTable, Address);
+}
+
+gceSTATUS
+gckMMU_AllocatePagesEx(
+ IN gckMMU Mmu,
+ IN gctSIZE_T PageCount,
+ IN gceSURF_TYPE Type,
+ IN gctBOOL Secure,
+ OUT gctPOINTER * PageTable,
+ OUT gctUINT32 * Address
+ )
+{
+#if gcdDISABLE_GPU_VIRTUAL_ADDRESS
+ gcmkPRINT("GPU virtual address is disabled.");
+ return gcvSTATUS_NOT_SUPPORTED;
+#else
+ return _AllocatePages(Mmu, PageCount, Type, Secure, PageTable, Address);
+#endif
+}
+
+gceSTATUS
+gckMMU_FreePages(
+ IN gckMMU Mmu,
+ IN gctBOOL Secure,
+ IN gctUINT32 Address,
+ IN gctPOINTER PageTable,
+ IN gctSIZE_T PageCount
+ )
+{
+ return _FreePages(Mmu, Secure, Address, PageTable, PageCount);
+}
+
+gceSTATUS
+gckMMU_SetPage(
+ IN gckMMU Mmu,
+ IN gctPHYS_ADDR_T PageAddress,
+ IN gctBOOL Writable,
+ IN gctUINT32 *PageEntry
+ )
+{
+ gctUINT32 addressExt;
+ gctUINT32 address;
+
+ gcmkHEADER_ARG("Mmu=0x%x", Mmu);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Mmu, gcvOBJ_MMU);
+ gcmkVERIFY_ARGUMENT(PageEntry != gcvNULL);
+ gcmkVERIFY_ARGUMENT(!(PageAddress & 0xFFF));
+
+ /* [31:0]. */
+ address = (gctUINT32)(PageAddress & 0xFFFFFFFF);
+ /* [39:32]. */
+ addressExt = (gctUINT32)((PageAddress >> 32) & 0xFF);
+
+ if (Mmu->hardware->mmuVersion == 0)
+ {
+ _WritePageEntry(PageEntry, address);
+ }
+ else
+ {
+ _WritePageEntry(PageEntry, _SetPage(address, addressExt, gcvTRUE));
+ }
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+}
+
+#if gcdPROCESS_ADDRESS_SPACE
+gceSTATUS
+gckMMU_GetPageEntry(
+ IN gckMMU Mmu,
+ IN gctUINT32 Address,
+ IN gctUINT32_PTR *PageTable
+ )
+{
+ gceSTATUS status;
+ struct _gcsMMU_STLB_CHUNK *stlb;
+ struct _gcsMMU_STLB_CHUNK **stlbs = Mmu->stlbs;
+ gctUINT32 offset = _MtlbOffset(Address);
+ gctUINT32 mtlbEntry;
+ gctBOOL ace = gckHARDWARE_IsFeatureAvailable(Mmu->hardware, gcvFEATURE_ACE);
+
+ gcmkHEADER_ARG("Mmu=0x%x", Mmu);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Mmu, gcvOBJ_MMU);
+ gcmkVERIFY_ARGUMENT((Address & 0xFFF) == 0);
+
+ stlb = stlbs[offset];
+
+ if (stlb == gcvNULL)
+ {
+ gcmkONERROR(_AllocateStlb(Mmu->os, &stlb));
+
+ mtlbEntry = stlb->physBase
+ | gcdMMU_MTLB_4K_PAGE
+ | gcdMMU_MTLB_PRESENT
+ ;
+
+ /* Insert Slave TLB address to Master TLB entry.*/
+ _WritePageEntry(Mmu->mtlbLogical + offset, mtlbEntry);
+
+ /* Record stlb. */
+ stlbs[offset] = stlb;
+ }
+
+ *PageTable = &stlb->logical[_StlbOffset(Address)];
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ gcmkFOOTER();
+ return status;
+}
+
+gceSTATUS
+_CheckMap(
+ IN gckMMU Mmu
+ )
+{
+ gceSTATUS status;
+ gctUINT32_PTR map = area->mapLogical;
+ gctUINT32 index;
+
+ for (index = area->heapList; index < area->pageTableEntries;)
+ {
+ /* Check the node type. */
+ switch (gcmENTRY_TYPE(map[index]))
+ {
+ case gcvMMU_SINGLE:
+ /* Move to next node. */
+ index = map[index] >> 8;
+ break;
+
+ case gcvMMU_FREE:
+ /* Move to next node. */
+ index = map[index + 1];
+ break;
+
+ default:
+ gcmkFATAL("MMU table correcupted at index [%u] = %x!", index, map[index]);
+ gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
+ }
+ }
+
+ return gcvSTATUS_OK;
+
+OnError:
+ return status;
+}
+
+gceSTATUS
+gckMMU_FlatMapping(
+ IN gckMMU Mmu,
+ IN gctUINT32 Physical,
+ IN gctUINT32 NumPages
+ )
+{
+ gceSTATUS status;
+ gctUINT32 index = _AddressToIndex(Mmu, Physical);
+ gctUINT32 i;
+ gctUINT32_PTR pageTable;
+
+ for (i = 0; i < NumPages; i++)
+ {
+ gckMMU_GetPageEntry(Mmu, Physical + i * 4096, &pageTable);
+
+ _WritePageEntry(pageTable, _SetPage(Physical + i * 4096, 0));
+ }
+
+ gcmkONERROR(_FillFlatMapping(Mmu, PhysBase, Size, gcvNULL));
+
+ return gcvSTATUS_OK;
+
+OnError:
+
+ /* Roll back. */
+ return status;
+}
+
+gceSTATUS
+gckMMU_FreePagesEx(
+ IN gckMMU Mmu,
+ IN gctUINT32 Address,
+ IN gctSIZE_T PageCount
+ )
+{
+ gctUINT32_PTR node;
+ gceSTATUS status;
+
+#if gcdUSE_MMU_EXCEPTION
+ gctUINT32 i;
+ struct _gcsMMU_STLB_CHUNK *stlb;
+ struct _gcsMMU_STLB_CHUNK **stlbs = Mmu->stlbs;
+#endif
+
+ gcmkHEADER_ARG("Mmu=0x%x Address=0x%x PageCount=%lu",
+ Mmu, Address, PageCount);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Mmu, gcvOBJ_MMU);
+ gcmkVERIFY_ARGUMENT(PageCount > 0);
+
+ /* Get the node by index. */
+ node = area->mapLogical + _AddressToIndex(Mmu, Address);
+
+ gcmkONERROR(gckOS_AcquireMutex(Mmu->os, Mmu->pageTableMutex, gcvINFINITE));
+
+ if (PageCount == 1)
+ {
+ /* Single page node. */
+ node[0] = (~((1U<<8)-1)) | gcvMMU_SINGLE;
+ }
+ else
+ {
+ /* Mark the node as free. */
+ node[0] = (PageCount << 8) | gcvMMU_FREE;
+ node[1] = ~0U;
+ }
+
+ /* We have free nodes. */
+ area->freeNodes = gcvTRUE;
+
+#if gcdUSE_MMU_EXCEPTION
+ for (i = 0; i < PageCount; i++)
+ {
+ /* Get */
+ stlb = stlbs[_MtlbOffset(Address)];
+
+ /* Enable exception */
+ stlb->logical[_StlbOffset(Address)] = gcdMMU_STLB_EXCEPTION;
+ }
+#endif
+
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(Mmu->os, Mmu->pageTableMutex));
+
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ gcmkFOOTER();
+ return status;
+}
+#endif
+
+gceSTATUS
+gckMMU_Flush(
+ IN gckMMU Mmu,
+ IN gceSURF_TYPE Type
+ )
+{
+#if !gcdPROCESS_ADDRESS_SPACE
+ gckHARDWARE hardware;
+#endif
+ gctUINT32 mask;
+ gctINT i;
+ gctUINT j;
+
+ if (Type == gcvSURF_VERTEX || Type == gcvSURF_INDEX)
+ {
+ mask = gcvPAGE_TABLE_DIRTY_BIT_FE;
+ }
+ else
+ {
+ mask = gcvPAGE_TABLE_DIRTY_BIT_OTHER;
+ }
+
+ i = 0;
+
+#if gcdPROCESS_ADDRESS_SPACE
+ for (i = 0; i < gcdMAX_GPU_COUNT; i++)
+ {
+ gcmkVERIFY_OK(
+ gckOS_AtomSetMask(Mmu->pageTableDirty[i], mask));
+ }
+#else
+#if gcdSHARED_PAGETABLE
+ for (i = 0; i < gcdMAX_GPU_COUNT; i++)
+ {
+ hardware = sharedPageTable->hardwares[i];
+ if (hardware)
+ {
+ for (j = 0; j < gcvENGINE_GPU_ENGINE_COUNT; j++)
+ {
+ gcmkVERIFY_OK(gckOS_AtomSetMask(hardware->pageTableDirty[j], mask));
+ }
+ }
+ }
+#else
+ hardware = Mmu->hardware;
+
+ for (j = 0 ; j < gcvENGINE_GPU_ENGINE_COUNT; j++)
+ {
+ gcmkVERIFY_OK(
+ gckOS_AtomSetMask(hardware->pageTableDirty[j], mask));
+ }
+
+ {
+ gcsLISTHEAD_PTR hardwareHead;
+ gcmkLIST_FOR_EACH(hardwareHead, &Mmu->hardwareList)
+ {
+ hardware = gcmCONTAINEROF(hardwareHead, _gckHARDWARE, mmuHead);
+
+ if (hardware != Mmu->hardware)
+ {
+ for (j = 0 ; j < gcvENGINE_GPU_ENGINE_COUNT; j++)
+ {
+ gcmkVERIFY_OK(
+ gckOS_AtomSetMask(hardware->pageTableDirty[j], mask));
+ }
+ }
+ }
+ }
+#endif
+#endif
+
+ return gcvSTATUS_OK;
+}
+
+gceSTATUS
+gckMMU_DumpPageTableEntry(
+ IN gckMMU Mmu,
+ IN gctUINT32 Address
+ )
+{
+#if gcdPROCESS_ADDRESS_SPACE
+ gcsMMU_STLB_PTR *stlbs = Mmu->stlbs;
+ gcsMMU_STLB_PTR stlbDesc = stlbs[_MtlbOffset(Address)];
+#else
+ gctUINT32_PTR pageTable;
+ gctUINT32 index;
+ gctUINT32 mtlb, stlb;
+#endif
+ gcsADDRESS_AREA_PTR area = &Mmu->area[0];
+
+ gcmkHEADER_ARG("Mmu=0x%08X Address=0x%08X", Mmu, Address);
+ gcmkVERIFY_OBJECT(Mmu, gcvOBJ_MMU);
+
+ gcmkASSERT(Mmu->hardware->mmuVersion > 0);
+
+#if gcdPROCESS_ADDRESS_SPACE
+ if (stlbDesc)
+ {
+ gcmkPRINT(" STLB entry = 0x%08X",
+ _ReadPageEntry(&stlbDesc->logical[_StlbOffset(Address)]));
+ }
+ else
+ {
+ gcmkPRINT(" MTLB entry is empty.");
+ }
+#else
+ mtlb = (Address & gcdMMU_MTLB_MASK) >> gcdMMU_MTLB_SHIFT;
+
+ if (mtlb >= area->dynamicMappingStart)
+ {
+ stlb = (Address & gcdMMU_STLB_4K_MASK) >> gcdMMU_STLB_4K_SHIFT;
+
+ pageTable = area->pageTableLogical;
+
+ index = (mtlb - area->dynamicMappingStart)
+ * gcdMMU_STLB_4K_ENTRY_NUM
+ + stlb;
+
+ gcmkPRINT(" Page table entry = 0x%08X", _ReadPageEntry(pageTable + index));
+ }
+ else
+ {
+ gcsMMU_STLB_CHUNK_PTR stlbChunkObj = Mmu->staticSTLB;
+ gctUINT32 entry = Mmu->mtlbLogical[mtlb];
+
+ stlb = (Address & gcdMMU_STLB_64K_MASK) >> gcdMMU_STLB_64K_SHIFT;
+
+ entry &= 0xFFFFFFF0;
+
+ while (stlbChunkObj)
+ {
+ gctUINT i;
+ gctBOOL found = gcvFALSE;
+ for (i = 0; i < stlbChunkObj->mtlbEntryNum; ++i)
+ {
+ gctPHYS_ADDR_T stlbPhysBase = stlbChunkObj->physBase + (i * gcdMMU_STLB_64K_SIZE);
+ gctUINT32_PTR stlbLogical =
+ (gctUINT32_PTR)((gctUINT8_PTR)stlbChunkObj->logical + (i * gcdMMU_STLB_64K_SIZE));
+ if (entry == stlbPhysBase)
+ {
+ gcmkPRINT(" Page table entry = 0x%08X", stlbLogical[stlb]);
+ found = gcvTRUE;
+ break;
+ }
+ }
+ if (found)
+ break;
+ stlbChunkObj = stlbChunkObj->next;
+ }
+ }
+#endif
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+}
+
+void
+gckMMU_CheckSaftPage(
+ IN gckMMU Mmu
+ )
+{
+ gctUINT8_PTR safeLogical = Mmu->safePageLogical;
+ gctUINT32 offsets[] = {
+ 0,
+ 64,
+ 128,
+ 256,
+ 2560,
+ 4000
+ };
+
+ gctUINT32 i = 0;
+
+ while (i < gcmCOUNTOF(offsets))
+ {
+ if (safeLogical[offsets[i]] != 0)
+ {
+ gcmkPRINT("%s(%d) safe page is over written [%d] = %x",
+ __FUNCTION__, __LINE__, i, safeLogical[offsets[i]]);
+ }
+ }
+}
+
+void
+gckMMU_DumpAddressSpace(
+ IN gckMMU Mmu
+ )
+{
+ gctUINT i;
+ gctUINT next;
+ gcsADDRESS_AREA_PTR area = &Mmu->area[0];
+ gctUINT32_PTR map = area->mapLogical;
+ gctBOOL used = gcvFALSE;
+ gctUINT32 numPages;
+
+ /* Grab the mutex. */
+ gcmkVERIFY_OK(gckOS_AcquireMutex(Mmu->os, Mmu->pageTableMutex, gcvINFINITE));
+
+ /* Find node which contains index. */
+ for (i = 0; i < area->pageTableEntries; i = next)
+ {
+ switch (gcmENTRY_TYPE(map[i]))
+ {
+ case gcvMMU_SINGLE:
+ numPages = 1;
+ next = i + numPages;
+ used = gcvFALSE;
+ break;
+
+ case gcvMMU_FREE:
+ numPages = map[i] >> 8;
+ next = i + numPages;
+ used = gcvFALSE;
+ break;
+
+ case gcvMMU_USED:
+ numPages = 1;
+ next = i + numPages;
+ used = gcvTRUE;
+ break;
+
+ default:
+ gcmkFATAL("MMU table correcupted at index %u!", i);
+ return;
+ }
+
+ if (!used)
+ {
+ gcmkPRINT("Available Range [%d - %d)", i, i + numPages);
+ }
+ }
+
+ /* Release the mutex. */
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(Mmu->os, Mmu->pageTableMutex));
+
+}
+
+void
+gckMMU_DumpRecentFreedAddress(
+ IN gckMMU Mmu
+ )
+{
+ gckQUEUE queue = &Mmu->recentFreedAddresses;
+ gctUINT32 i;
+ gcuQUEUEDATA *data;
+
+ if (queue->count)
+ {
+ gcmkPRINT(" Recent %d freed GPU address ranges:", queue->count);
+
+ for (i = 0; i < queue->count; i++)
+ {
+ gckQUEUE_GetData(queue, i, &data);
+
+ gcmkPRINT(" [%08X - %08X]", data->addressData.start, data->addressData.end);
+ }
+ }
+}
+
+gceSTATUS
+gckMMU_FillFlatMapping(
+ IN gckMMU Mmu,
+ IN gctUINT32 PhysBase,
+ IN gctSIZE_T Size
+ )
+{
+ gceSTATUS status;
+ gckHARDWARE hardware = Mmu->hardware;
+
+ if (hardware->mmuVersion)
+ {
+ gcmkONERROR(_FillFlatMapping(Mmu, PhysBase, Size, gcvNULL));
+ }
+
+ return gcvSTATUS_OK;
+
+OnError:
+ return status;
+}
+
+gceSTATUS
+gckMMU_IsFlatMapped(
+ IN gckMMU Mmu,
+ OUT gctUINT32 Physical,
+ OUT gctBOOL *In
+ )
+{
+ gceSTATUS status;
+ gctUINT32 i;
+ gctBOOL inFlatmapping = gcvFALSE;
+ gcmkHEADER();
+
+ gcmkVERIFY_ARGUMENT(In != gcvNULL);
+
+ if (gckHARDWARE_IsFeatureAvailable(Mmu->hardware, gcvFEATURE_MMU) == gcvFALSE)
+ {
+ gcmkONERROR(gcvSTATUS_NOT_SUPPORTED);
+ }
+
+ for (i = 0; i < Mmu->flatMappingRangeCount; i++)
+ {
+ if ((Physical >= Mmu->flatMappingRanges[i].start) &&
+ (Physical < Mmu->flatMappingRanges[i].end))
+ {
+ inFlatmapping = gcvTRUE;
+ break;
+ }
+ }
+
+ *In = inFlatmapping;
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ gcmkFOOTER();
+ return status;
+}
+
+gceSTATUS
+gckMMU_AttachHardware(
+ IN gckMMU Mmu,
+ IN gckHARDWARE Hardware
+ )
+{
+ gcmkHEADER();
+
+ gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
+
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, _GC_OBJ_ZONE, "Attach core %d", Hardware->core);
+
+ gcsLIST_Add(&Hardware->mmuHead, &Mmu->hardwareList);
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+}
+
+
+#if !gcdPROCESS_ADDRESS_SPACE
+gceSTATUS
+gckMMU_GetPageEntry(
+ IN gckMMU Mmu,
+ IN gctUINT32 Address,
+ IN gctUINT32_PTR *PageTable
+ )
+{
+ gctUINT32_PTR pageTable;
+ gctUINT32 index;
+ gctUINT32 mtlb, stlb;
+ gcsADDRESS_AREA_PTR area = &Mmu->area[0];
+
+ gcmkHEADER_ARG("Mmu=0x%08X Address=0x%08X", Mmu, Address);
+ gcmkVERIFY_OBJECT(Mmu, gcvOBJ_MMU);
+
+ gcmkASSERT(Mmu->hardware->mmuVersion > 0);
+
+ mtlb = (Address & gcdMMU_MTLB_MASK) >> gcdMMU_MTLB_SHIFT;
+
+ if (mtlb >= area->dynamicMappingStart)
+ {
+ stlb = (Address & gcdMMU_STLB_4K_MASK) >> gcdMMU_STLB_4K_SHIFT;
+
+ pageTable = area->pageTableLogical;
+
+ index = (mtlb - area->dynamicMappingStart)
+ * gcdMMU_STLB_4K_ENTRY_NUM
+ + stlb;
+
+ *PageTable = pageTable + index;
+ }
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+}
+#endif
+
+/******************************************************************************
+****************************** T E S T C O D E ******************************
+******************************************************************************/
+
diff --git a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_mmu_vg.c b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_mmu_vg.c
new file mode 100644
index 000000000000..f6e687b22af2
--- /dev/null
+++ b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_mmu_vg.c
@@ -0,0 +1,556 @@
+/****************************************************************************
+*
+* The MIT License (MIT)
+*
+* Copyright (c) 2014 - 2018 Vivante 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 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 GPL License (GPL)
+*
+* Copyright (C) 2014 - 2018 Vivante 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.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+*****************************************************************************
+*
+* Note: This software is released under dual MIT and GPL licenses. A
+* recipient may use this file under the terms of either the MIT license or
+* GPL License. If you wish to use only one license not the other, you can
+* indicate your decision by deleting one of the above license notices in your
+* version of this file.
+*
+*****************************************************************************/
+
+
+#include "gc_hal_kernel_precomp.h"
+
+#if gcdENABLE_VG
+
+#define _GC_OBJ_ZONE gcvZONE_MMU
+
+/*******************************************************************************
+**
+** gckVGMMU_Construct
+**
+** Construct a new gckVGMMU object.
+**
+** INPUT:
+**
+** gckVGKERNEL Kernel
+** Pointer to an gckVGKERNEL object.
+**
+** gctSIZE_T MmuSize
+** Number of bytes for the page table.
+**
+** OUTPUT:
+**
+** gckVGMMU * Mmu
+** Pointer to a variable that receives the gckVGMMU object pointer.
+*/
+gceSTATUS gckVGMMU_Construct(
+ IN gckVGKERNEL Kernel,
+ IN gctUINT32 MmuSize,
+ OUT gckVGMMU * Mmu
+ )
+{
+ gckOS os;
+ gckVGHARDWARE hardware;
+ gceSTATUS status;
+ gckVGMMU mmu;
+ gctUINT32 * pageTable;
+ gctUINT32 i;
+
+ gcmkHEADER_ARG("Kernel=0x%x MmuSize=0x%x Mmu=0x%x", Kernel, MmuSize, Mmu);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
+ gcmkVERIFY_ARGUMENT(MmuSize > 0);
+ gcmkVERIFY_ARGUMENT(Mmu != gcvNULL);
+
+ /* Extract the gckOS object pointer. */
+ os = Kernel->os;
+ gcmkVERIFY_OBJECT(os, gcvOBJ_OS);
+
+ /* Extract the gckVGHARDWARE object pointer. */
+ hardware = Kernel->hardware;
+ gcmkVERIFY_OBJECT(hardware, gcvOBJ_HARDWARE);
+
+ /* Allocate memory for the gckVGMMU object. */
+ status = gckOS_Allocate(os, sizeof(struct _gckVGMMU), (gctPOINTER *) &mmu);
+
+ if (status < 0)
+ {
+ /* Error. */
+ gcmkFATAL(
+ "%s(%d): could not allocate gckVGMMU object.",
+ __FUNCTION__, __LINE__
+ );
+
+ gcmkFOOTER();
+ return status;
+ }
+
+ /* Initialize the gckVGMMU object. */
+ mmu->object.type = gcvOBJ_MMU;
+ mmu->os = os;
+ mmu->hardware = hardware;
+
+ /* Create the mutex. */
+ status = gckOS_CreateMutex(os, &mmu->mutex);
+
+ if (status < 0)
+ {
+ /* Roll back. */
+ mmu->object.type = gcvOBJ_UNKNOWN;
+ gcmkVERIFY_OK(gckOS_Free(os, mmu));
+
+ gcmkFOOTER();
+ /* Error. */
+ return status;
+ }
+
+ /* Allocate the page table. */
+ mmu->pageTableSize = (gctUINT32)MmuSize;
+ status = gckOS_AllocateContiguous(os,
+ gcvFALSE,
+ &mmu->pageTableSize,
+ &mmu->pageTablePhysical,
+ &mmu->pageTableLogical);
+
+ if (status < 0)
+ {
+ /* Roll back. */
+ gcmkVERIFY_OK(gckOS_DeleteMutex(os, mmu->mutex));
+
+ mmu->object.type = gcvOBJ_UNKNOWN;
+ gcmkVERIFY_OK(gckOS_Free(os, mmu));
+
+ /* Error. */
+ gcmkFATAL(
+ "%s(%d): could not allocate page table.",
+ __FUNCTION__, __LINE__
+ );
+
+ gcmkFOOTER();
+ return status;
+ }
+
+ /* Compute number of entries in page table. */
+ mmu->entryCount = (gctUINT32)mmu->pageTableSize / sizeof(gctUINT32);
+ mmu->entry = 0;
+
+ /* Mark the entire page table as available. */
+ pageTable = (gctUINT32 *) mmu->pageTableLogical;
+ for (i = 0; i < mmu->entryCount; i++)
+ {
+ pageTable[i] = (gctUINT32)~0;
+ }
+
+ /* Set page table address. */
+ status = gckVGHARDWARE_SetMMU(hardware, mmu->pageTableLogical);
+
+ if (status < 0)
+ {
+ /* Free the page table. */
+ gcmkVERIFY_OK(gckOS_FreeContiguous(mmu->os,
+ mmu->pageTablePhysical,
+ mmu->pageTableLogical,
+ mmu->pageTableSize));
+
+ /* Roll back. */
+ gcmkVERIFY_OK(gckOS_DeleteMutex(os, mmu->mutex));
+
+ mmu->object.type = gcvOBJ_UNKNOWN;
+ gcmkVERIFY_OK(gckOS_Free(os, mmu));
+
+ /* Error. */
+ gcmkFATAL(
+ "%s(%d): could not program page table.",
+ __FUNCTION__, __LINE__
+ );
+
+ gcmkFOOTER();
+ return status;
+ }
+
+ /* Return the gckVGMMU object pointer. */
+ *Mmu = mmu;
+
+ gcmkTRACE_ZONE(
+ gcvLEVEL_INFO, gcvZONE_MMU,
+ "%s(%d): %u entries at %p.(0x%08X)\n",
+ __FUNCTION__, __LINE__,
+ mmu->entryCount,
+ mmu->pageTableLogical,
+ mmu->pageTablePhysical
+ );
+
+ gcmkFOOTER_NO();
+ /* Success. */
+ return gcvSTATUS_OK;
+}
+
+/*******************************************************************************
+**
+** gckVGMMU_Destroy
+**
+** Destroy a nAQMMU object.
+**
+** INPUT:
+**
+** gckVGMMU Mmu
+** Pointer to an gckVGMMU object.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS gckVGMMU_Destroy(
+ IN gckVGMMU Mmu
+ )
+{
+ gcmkHEADER_ARG("Mmu=0x%x", Mmu);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Mmu, gcvOBJ_MMU);
+
+ /* Free the page table. */
+ gcmkVERIFY_OK(gckOS_FreeContiguous(Mmu->os,
+ Mmu->pageTablePhysical,
+ Mmu->pageTableLogical,
+ Mmu->pageTableSize));
+
+ /* Roll back. */
+ gcmkVERIFY_OK(gckOS_DeleteMutex(Mmu->os, Mmu->mutex));
+
+ /* Mark the gckVGMMU object as unknown. */
+ Mmu->object.type = gcvOBJ_UNKNOWN;
+
+ /* Free the gckVGMMU object. */
+ gcmkVERIFY_OK(gckOS_Free(Mmu->os, Mmu));
+
+ gcmkFOOTER_NO();
+ /* Success. */
+ return gcvSTATUS_OK;
+}
+
+/*******************************************************************************
+**
+** gckVGMMU_AllocatePages
+**
+** Allocate pages inside the page table.
+**
+** INPUT:
+**
+** gckVGMMU Mmu
+** Pointer to an gckVGMMU object.
+**
+** gctSIZE_T PageCount
+** Number of pages to allocate.
+**
+** OUTPUT:
+**
+** gctPOINTER * PageTable
+** Pointer to a variable that receives the base address of the page
+** table.
+**
+** gctUINT32 * Address
+** Pointer to a variable that receives the hardware specific address.
+*/
+gceSTATUS gckVGMMU_AllocatePages(
+ IN gckVGMMU Mmu,
+ IN gctSIZE_T PageCount,
+ OUT gctPOINTER * PageTable,
+ OUT gctUINT32 * Address
+ )
+{
+ gceSTATUS status;
+ gctUINT32 tail, index, i;
+ gctUINT32 * table;
+ gctBOOL allocated = gcvFALSE;
+
+ gcmkHEADER_ARG("Mmu=0x%x PageCount=0x%x PageTable=0x%x Address=0x%x",
+ Mmu, PageCount, PageTable, Address);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Mmu, gcvOBJ_MMU);
+ gcmkVERIFY_ARGUMENT(PageCount > 0);
+ gcmkVERIFY_ARGUMENT(PageTable != gcvNULL);
+ gcmkVERIFY_ARGUMENT(Address != gcvNULL);
+
+ gcmkTRACE_ZONE(
+ gcvLEVEL_INFO, gcvZONE_MMU,
+ "%s(%d): %u pages.\n",
+ __FUNCTION__, __LINE__,
+ PageCount
+ );
+
+ if (PageCount > Mmu->entryCount)
+ {
+ gcmkTRACE_ZONE(
+ gcvLEVEL_ERROR, gcvZONE_MMU,
+ "%s(%d): page table too small for %u pages.\n",
+ __FUNCTION__, __LINE__,
+ PageCount
+ );
+
+ gcmkFOOTER_NO();
+ /* Not enough pages avaiable. */
+ return gcvSTATUS_OUT_OF_RESOURCES;
+ }
+
+ /* Grab the mutex. */
+ status = gckOS_AcquireMutex(Mmu->os, Mmu->mutex, gcvINFINITE);
+
+ if (status < 0)
+ {
+ gcmkTRACE_ZONE(
+ gcvLEVEL_ERROR, gcvZONE_MMU,
+ "%s(%d): could not acquire mutex.\n"
+ ,__FUNCTION__, __LINE__
+ );
+
+ gcmkFOOTER();
+ /* Error. */
+ return status;
+ }
+
+ /* Compute the tail for this allocation. */
+ tail = Mmu->entryCount - (gctUINT32)PageCount;
+
+ /* Walk all entries until we find enough slots. */
+ for (index = Mmu->entry; index <= tail;)
+ {
+ /* Access page table. */
+ table = (gctUINT32 *) Mmu->pageTableLogical + index;
+
+ /* See if all slots are available. */
+ for (i = 0; i < PageCount; i++, table++)
+ {
+ if (*table != ~0)
+ {
+ /* Start from next slot. */
+ index += i + 1;
+ break;
+ }
+ }
+
+ if (i == PageCount)
+ {
+ /* Bail out if we have enough page entries. */
+ allocated = gcvTRUE;
+ break;
+ }
+ }
+
+ if (!allocated)
+ {
+ if (status >= 0)
+ {
+ /* Walk all entries until we find enough slots. */
+ for (index = 0; index <= tail;)
+ {
+ /* Access page table. */
+ table = (gctUINT32 *) Mmu->pageTableLogical + index;
+
+ /* See if all slots are available. */
+ for (i = 0; i < PageCount; i++, table++)
+ {
+ if (*table != ~0)
+ {
+ /* Start from next slot. */
+ index += i + 1;
+ break;
+ }
+ }
+
+ if (i == PageCount)
+ {
+ /* Bail out if we have enough page entries. */
+ allocated = gcvTRUE;
+ break;
+ }
+ }
+ }
+ }
+
+ if (!allocated && (status >= 0))
+ {
+ gcmkTRACE_ZONE(
+ gcvLEVEL_ERROR, gcvZONE_MMU,
+ "%s(%d): not enough free pages for %u pages.\n",
+ __FUNCTION__, __LINE__,
+ PageCount
+ );
+
+ /* Not enough empty slots available. */
+ status = gcvSTATUS_OUT_OF_RESOURCES;
+ }
+
+ if (status >= 0)
+ {
+ /* Build virtual address. */
+ status = gckVGHARDWARE_BuildVirtualAddress(Mmu->hardware,
+ index,
+ 0,
+ Address);
+
+ if (status >= 0)
+ {
+ /* Update current entry into page table. */
+ Mmu->entry = index + (gctUINT32)PageCount;
+
+ /* Return pointer to page table. */
+ *PageTable = (gctUINT32 *) Mmu->pageTableLogical + index;
+
+ gcmkTRACE_ZONE(
+ gcvLEVEL_INFO, gcvZONE_MMU,
+ "%s(%d): allocated %u pages at index %u (0x%08X) @ %p.\n",
+ __FUNCTION__, __LINE__,
+ PageCount,
+ index,
+ *Address,
+ *PageTable
+ );
+ }
+ }
+
+ /* Release the mutex. */
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(Mmu->os, Mmu->mutex));
+ gcmkFOOTER();
+
+ /* Return status. */
+ return status;
+}
+
+/*******************************************************************************
+**
+** gckVGMMU_FreePages
+**
+** Free pages inside the page table.
+**
+** INPUT:
+**
+** gckVGMMU Mmu
+** Pointer to an gckVGMMU object.
+**
+** gctPOINTER PageTable
+** Base address of the page table to free.
+**
+** gctSIZE_T PageCount
+** Number of pages to free.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS gckVGMMU_FreePages(
+ IN gckVGMMU Mmu,
+ IN gctPOINTER PageTable,
+ IN gctSIZE_T PageCount
+ )
+{
+ gctUINT32 * table;
+
+ gcmkHEADER_ARG("Mmu=0x%x PageTable=0x%x PageCount=0x%x",
+ Mmu, PageTable, PageCount);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Mmu, gcvOBJ_MMU);
+ gcmkVERIFY_ARGUMENT(PageTable != gcvNULL);
+ gcmkVERIFY_ARGUMENT(PageCount > 0);
+
+ gcmkTRACE_ZONE(
+ gcvLEVEL_INFO, gcvZONE_MMU,
+ "%s(%d): freeing %u pages at index %u @ %p.\n",
+ __FUNCTION__, __LINE__,
+ PageCount,
+ ((gctUINT32 *) PageTable - (gctUINT32 *) Mmu->pageTableLogical),
+ PageTable
+ );
+
+ /* Convert pointer. */
+ table = (gctUINT32 *) PageTable;
+
+ /* Mark the page table entries as available. */
+ while (PageCount-- > 0)
+ {
+ *table++ = (gctUINT32)~0;
+ }
+
+ gcmkFOOTER_NO();
+ /* Success. */
+ return gcvSTATUS_OK;
+}
+
+gceSTATUS
+gckVGMMU_SetPage(
+ IN gckVGMMU Mmu,
+ IN gctUINT32 PageAddress,
+ IN gctUINT32 *PageEntry
+ )
+{
+ gcmkHEADER_ARG("Mmu=0x%x", Mmu);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Mmu, gcvOBJ_MMU);
+ gcmkVERIFY_ARGUMENT(PageEntry != gcvNULL);
+ gcmkVERIFY_ARGUMENT(!(PageAddress & 0xFFF));
+
+ *PageEntry = PageAddress;
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+}
+
+gceSTATUS
+gckVGMMU_Flush(
+ IN gckVGMMU Mmu
+ )
+{
+ gckVGHARDWARE hardware;
+
+ gcmkHEADER_ARG("Mmu=0x%x", Mmu);
+
+ hardware = Mmu->hardware;
+ gcmkVERIFY_OK(
+ gckOS_AtomSet(hardware->os, hardware->pageTableDirty, 1));
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+}
+
+#endif /* gcdENABLE_VG */
diff --git a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_power.c b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_power.c
new file mode 100644
index 000000000000..92839cb6227f
--- /dev/null
+++ b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_power.c
@@ -0,0 +1,381 @@
+/****************************************************************************
+*
+* The MIT License (MIT)
+*
+* Copyright (c) 2014 - 2018 Vivante 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 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 GPL License (GPL)
+*
+* Copyright (C) 2014 - 2018 Vivante 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.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+*****************************************************************************
+*
+* Note: This software is released under dual MIT and GPL licenses. A
+* recipient may use this file under the terms of either the MIT license or
+* GPL License. If you wish to use only one license not the other, you can
+* indicate your decision by deleting one of the above license notices in your
+* version of this file.
+*
+*****************************************************************************/
+
+
+#include "gc_hal_kernel_precomp.h"
+
+#define _GC_OBJ_ZONE gcvZONE_POWER
+
+/******************************************************************************\
+************************ Dynamic Voltage Frequency Setting *********************
+\******************************************************************************/
+#if gcdDVFS
+static gctUINT32
+_GetLoadHistory(
+ IN gckDVFS Dvfs,
+ IN gctUINT32 Select,
+ IN gctUINT32 Index
+)
+{
+ return Dvfs->loads[Index];
+}
+
+static void
+_IncreaseScale(
+ IN gckDVFS Dvfs,
+ IN gctUINT32 Load,
+ OUT gctUINT8 *Scale
+ )
+{
+ if (Dvfs->currentScale < 32)
+ {
+ *Scale = Dvfs->currentScale + 8;
+ }
+ else
+ {
+ *Scale = Dvfs->currentScale + 8;
+ *Scale = gcmMIN(64, *Scale);
+ }
+}
+
+static void
+_RecordFrequencyHistory(
+ gckDVFS Dvfs,
+ gctUINT32 Frequency
+ )
+{
+ gctUINT32 i = 0;
+
+ struct _FrequencyHistory *history = Dvfs->frequencyHistory;
+
+ for (i = 0; i < 16; i++)
+ {
+ if (history->frequency == Frequency)
+ {
+ break;
+ }
+
+ if (history->frequency == 0)
+ {
+ history->frequency = Frequency;
+ break;
+ }
+
+ history++;
+ }
+
+ if (i < 16)
+ {
+ history->count++;
+ }
+}
+
+static gctUINT32
+_GetFrequencyHistory(
+ gckDVFS Dvfs,
+ gctUINT32 Frequency
+ )
+{
+ gctUINT32 i = 0;
+
+ struct _FrequencyHistory * history = Dvfs->frequencyHistory;
+
+ for (i = 0; i < 16; i++)
+ {
+ if (history->frequency == Frequency)
+ {
+ break;
+ }
+
+ history++;
+ }
+
+ if (i < 16)
+ {
+ return history->count;
+ }
+
+ return 0;
+}
+
+static void
+_Policy(
+ IN gckDVFS Dvfs,
+ IN gctUINT32 Load,
+ OUT gctUINT8 *Scale
+ )
+{
+ gctUINT8 load[4], nextLoad;
+ gctUINT8 scale;
+
+ /* Last 4 history. */
+ load[0] = (Load & 0xFF);
+ load[1] = (Load & 0xFF00) >> 8;
+ load[2] = (Load & 0xFF0000) >> 16;
+ load[3] = (Load & 0xFF000000) >> 24;
+
+ /* Determine target scale. */
+ if (load[0] > 54)
+ {
+ _IncreaseScale(Dvfs, Load, &scale);
+ }
+ else
+ {
+ nextLoad = (load[0] + load[1] + load[2] + load[3])/4;
+
+ scale = Dvfs->currentScale * (nextLoad) / 54;
+
+ scale = gcmMAX(1, scale);
+ scale = gcmMIN(64, scale);
+ }
+
+ Dvfs->totalConfig++;
+
+ Dvfs->loads[(load[0]-1)/8]++;
+
+ *Scale = scale;
+
+
+ if (Dvfs->totalConfig % 100 == 0)
+ {
+ gcmkPRINT("=======================================================");
+ gcmkPRINT("GPU Load: %-8d %-8d %-8d %-8d %-8d %-8d %-8d %-8d",
+ 8, 16, 24, 32, 40, 48, 56, 64);
+ gcmkPRINT(" %-8d %-8d %-8d %-8d %-8d %-8d %-8d %-8d",
+ _GetLoadHistory(Dvfs,2, 0),
+ _GetLoadHistory(Dvfs,2, 1),
+ _GetLoadHistory(Dvfs,2, 2),
+ _GetLoadHistory(Dvfs,2, 3),
+ _GetLoadHistory(Dvfs,2, 4),
+ _GetLoadHistory(Dvfs,2, 5),
+ _GetLoadHistory(Dvfs,2, 6),
+ _GetLoadHistory(Dvfs,2, 7)
+ );
+
+ gcmkPRINT("Frequency(MHz) %-8d %-8d %-8d %-8d %-8d",
+ 58, 120, 240, 360, 480);
+ gcmkPRINT(" %-8d %-8d %-8d %-8d %-8d",
+ _GetFrequencyHistory(Dvfs, 58),
+ _GetFrequencyHistory(Dvfs,120),
+ _GetFrequencyHistory(Dvfs,240),
+ _GetFrequencyHistory(Dvfs,360),
+ _GetFrequencyHistory(Dvfs,480)
+ );
+ }
+}
+
+static void
+_TimerFunction(
+ gctPOINTER Data
+ )
+{
+ gceSTATUS status;
+ gckDVFS dvfs = (gckDVFS) Data;
+ gckHARDWARE hardware = dvfs->hardware;
+ gctUINT32 value;
+ gctUINT32 frequency;
+ gctUINT8 scale;
+ gctUINT32 t1, t2, consumed;
+
+ gckOS_GetTicks(&t1);
+
+ gcmkONERROR(gckHARDWARE_QueryLoad(hardware, &value));
+
+ /* determine target sacle. */
+ _Policy(dvfs, value, &scale);
+
+ /* Set frequency and voltage. */
+ gcmkONERROR(gckOS_SetGPUFrequency(hardware->os, hardware->core, scale));
+
+ /* Query real frequency. */
+ gcmkONERROR(
+ gckOS_QueryGPUFrequency(hardware->os,
+ hardware->core,
+ &frequency,
+ &dvfs->currentScale));
+
+ _RecordFrequencyHistory(dvfs, frequency);
+
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_POWER,
+ "Current frequency = %d",
+ frequency);
+
+ /* Set period. */
+ gcmkONERROR(gckHARDWARE_SetDVFSPeroid(hardware, frequency));
+
+OnError:
+ /* Determine next querying time. */
+ gckOS_GetTicks(&t2);
+
+ consumed = gcmMIN(((long)t2 - (long)t1), 5);
+
+ if (dvfs->stop == gcvFALSE)
+ {
+ gcmkVERIFY_OK(gckOS_StartTimer(hardware->os,
+ dvfs->timer,
+ dvfs->pollingTime - consumed));
+ }
+
+ return;
+}
+
+gceSTATUS
+gckDVFS_Construct(
+ IN gckHARDWARE Hardware,
+ OUT gckDVFS * Dvfs
+ )
+{
+ gceSTATUS status;
+ gctPOINTER pointer;
+ gckDVFS dvfs = gcvNULL;
+ gckOS os = Hardware->os;
+
+ gcmkHEADER_ARG("Hardware=0x%X", Hardware);
+
+ gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
+ gcmkVERIFY_ARGUMENT(Dvfs != gcvNULL);
+
+ /* Allocate a gckDVFS manager. */
+ gcmkONERROR(gckOS_Allocate(os, gcmSIZEOF(struct _gckDVFS), &pointer));
+
+ gckOS_ZeroMemory(pointer, gcmSIZEOF(struct _gckDVFS));
+
+ dvfs = pointer;
+
+ /* Initialization. */
+ dvfs->hardware = Hardware;
+ dvfs->pollingTime = gcdDVFS_POLLING_TIME;
+ dvfs->os = Hardware->os;
+ dvfs->currentScale = 64;
+
+ /* Create a polling timer. */
+ gcmkONERROR(gckOS_CreateTimer(os, _TimerFunction, pointer, &dvfs->timer));
+
+ /* Initialize frequency and voltage adjustment helper. */
+ gcmkONERROR(gckOS_PrepareGPUFrequency(os, Hardware->core));
+
+ /* Return result. */
+ *Dvfs = dvfs;
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ /* Roll back. */
+ if (dvfs)
+ {
+ if (dvfs->timer)
+ {
+ gcmkVERIFY_OK(gckOS_DestroyTimer(os, dvfs->timer));
+ }
+
+ gcmkOS_SAFE_FREE(os, dvfs);
+ }
+
+ gcmkFOOTER();
+ return status;
+}
+
+gceSTATUS
+gckDVFS_Destroy(
+ IN gckDVFS Dvfs
+ )
+{
+ gcmkHEADER_ARG("Dvfs=0x%X", Dvfs);
+ gcmkVERIFY_ARGUMENT(Dvfs != gcvNULL);
+
+ /* Deinitialize helper fuunction. */
+ gcmkVERIFY_OK(gckOS_FinishGPUFrequency(Dvfs->os, Dvfs->hardware->core));
+
+ /* DestroyTimer. */
+ gcmkVERIFY_OK(gckOS_DestroyTimer(Dvfs->os, Dvfs->timer));
+
+ gcmkOS_SAFE_FREE(Dvfs->os, Dvfs);
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+}
+
+gceSTATUS
+gckDVFS_Start(
+ IN gckDVFS Dvfs
+ )
+{
+ gcmkHEADER_ARG("Dvfs=0x%X", Dvfs);
+ gcmkVERIFY_ARGUMENT(Dvfs != gcvNULL);
+
+ gckHARDWARE_InitDVFS(Dvfs->hardware);
+
+ Dvfs->stop = gcvFALSE;
+
+ gckOS_StartTimer(Dvfs->os, Dvfs->timer, Dvfs->pollingTime);
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+}
+
+gceSTATUS
+gckDVFS_Stop(
+ IN gckDVFS Dvfs
+ )
+{
+ gcmkHEADER_ARG("Dvfs=0x%X", Dvfs);
+ gcmkVERIFY_ARGUMENT(Dvfs != gcvNULL);
+
+ Dvfs->stop = gcvTRUE;
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+}
+#endif
diff --git a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_precomp.h b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_precomp.h
new file mode 100644
index 000000000000..ee2b12245e8c
--- /dev/null
+++ b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_precomp.h
@@ -0,0 +1,63 @@
+/****************************************************************************
+*
+* The MIT License (MIT)
+*
+* Copyright (c) 2014 - 2018 Vivante 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 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 GPL License (GPL)
+*
+* Copyright (C) 2014 - 2018 Vivante 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.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+*****************************************************************************
+*
+* Note: This software is released under dual MIT and GPL licenses. A
+* recipient may use this file under the terms of either the MIT license or
+* GPL License. If you wish to use only one license not the other, you can
+* indicate your decision by deleting one of the above license notices in your
+* version of this file.
+*
+*****************************************************************************/
+
+
+#ifndef __gc_hal_kernel_precomp_h_
+#define __gc_hal_kernel_precomp_h_
+
+#include "gc_hal.h"
+#include "gc_hal_driver.h"
+#include "gc_hal_kernel.h"
+
+#endif /* __gc_hal_kernel_precomp_h_ */
diff --git a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_security.c b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_security.c
new file mode 100644
index 000000000000..abf5485052ae
--- /dev/null
+++ b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_security.c
@@ -0,0 +1,286 @@
+/****************************************************************************
+*
+* The MIT License (MIT)
+*
+* Copyright (c) 2014 - 2018 Vivante 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 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 GPL License (GPL)
+*
+* Copyright (C) 2014 - 2018 Vivante 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.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+*****************************************************************************
+*
+* Note: This software is released under dual MIT and GPL licenses. A
+* recipient may use this file under the terms of either the MIT license or
+* GPL License. If you wish to use only one license not the other, you can
+* indicate your decision by deleting one of the above license notices in your
+* version of this file.
+*
+*****************************************************************************/
+
+
+#include "gc_hal_kernel_precomp.h"
+
+
+
+
+#define _GC_OBJ_ZONE gcvZONE_KERNEL
+
+#if gcdSECURITY
+
+/*
+** Open a security service channel.
+*/
+gceSTATUS
+gckKERNEL_SecurityOpen(
+ IN gckKERNEL Kernel,
+ IN gctUINT32 GPU,
+ OUT gctUINT32 *Channel
+ )
+{
+ gceSTATUS status;
+
+ gcmkONERROR(gckOS_OpenSecurityChannel(Kernel->os, Kernel->core, Channel));
+ gcmkONERROR(gckOS_InitSecurityChannel(*Channel));
+
+ return gcvSTATUS_OK;
+
+OnError:
+ return status;
+}
+
+/*
+** Close a security service channel
+*/
+gceSTATUS
+gckKERNEL_SecurityClose(
+ IN gctUINT32 Channel
+ )
+{
+ return gcvSTATUS_OK;
+}
+
+/*
+** Security service interface.
+*/
+gceSTATUS
+gckKERNEL_SecurityCallService(
+ IN gctUINT32 Channel,
+ IN OUT gcsTA_INTERFACE * Interface
+)
+{
+ gceSTATUS status;
+ gcmkHEADER();
+
+ gcmkVERIFY_ARGUMENT(Interface != gcvNULL);
+
+ gckOS_CallSecurityService(Channel, Interface);
+
+ status = Interface->result;
+
+ gcmkONERROR(status);
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ gcmkFOOTER();
+ return status;
+}
+
+gceSTATUS
+gckKERNEL_SecurityStartCommand(
+ IN gckKERNEL Kernel
+ )
+{
+ gceSTATUS status;
+ gcsTA_INTERFACE iface;
+
+ gcmkHEADER();
+
+ iface.command = KERNEL_START_COMMAND;
+ iface.u.StartCommand.gpu = Kernel->core;
+
+ gcmkONERROR(gckKERNEL_SecurityCallService(Kernel->securityChannel, &iface));
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ gcmkFOOTER();
+ return status;
+}
+
+gceSTATUS
+gckKERNEL_SecurityAllocateSecurityMemory(
+ IN gckKERNEL Kernel,
+ IN gctUINT32 Bytes,
+ OUT gctUINT32 * Handle
+ )
+{
+ gceSTATUS status;
+ gcsTA_INTERFACE iface;
+
+ gcmkHEADER();
+
+ iface.command = KERNEL_ALLOCATE_SECRUE_MEMORY;
+ iface.u.AllocateSecurityMemory.bytes = Bytes;
+
+ gcmkONERROR(gckKERNEL_SecurityCallService(Kernel->securityChannel, &iface));
+
+ *Handle = iface.u.AllocateSecurityMemory.memory_handle;
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ gcmkFOOTER();
+ return status;
+}
+
+gceSTATUS
+gckKERNEL_SecurityExecute(
+ IN gckKERNEL Kernel,
+ IN gctPOINTER Buffer,
+ IN gctUINT32 Bytes
+ )
+{
+ gceSTATUS status;
+#if defined(LINUX)
+ gctPHYS_ADDR_T physical;
+ gctUINT32 address;
+#endif
+ gcsTA_INTERFACE iface;
+
+ gcmkHEADER();
+
+ iface.command = KERNEL_EXECUTE;
+ iface.u.Execute.command_buffer = (gctUINT32 *)Buffer;
+ iface.u.Execute.gpu = Kernel->core;
+ iface.u.Execute.command_buffer_length = Bytes;
+
+#if defined(LINUX)
+ gcmkONERROR(gckOS_GetPhysicalAddress(Kernel->os, Buffer, &physical));
+ gcmkVERIFY_OK(gckOS_CPUPhysicalToGPUPhysical(Kernel->os, physical, &physical));
+ gcmkSAFECASTPHYSADDRT(address, physical);
+
+ iface.u.Execute.command_buffer = (gctUINT32 *)address;
+#endif
+
+ gcmkONERROR(gckKERNEL_SecurityCallService(Kernel->securityChannel, &iface));
+
+ /* Update queue tail pointer. */
+ gcmkONERROR(gckHARDWARE_UpdateQueueTail(
+ Kernel->hardware, 0, 0
+ ));
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ gcmkFOOTER();
+ return status;
+}
+
+gceSTATUS
+gckKERNEL_SecurityMapMemory(
+ IN gckKERNEL Kernel,
+ IN gctUINT32 *PhysicalArray,
+ IN gctUINT32 PageCount,
+ OUT gctUINT32 * GPUAddress
+ )
+{
+ gceSTATUS status;
+ gcsTA_INTERFACE iface;
+#if defined(LINUX)
+ gctPHYS_ADDR_T physical;
+ gctUINT32 address;
+#endif
+
+ gcmkHEADER();
+
+ iface.command = KERNEL_MAP_MEMORY;
+
+#if defined(LINUX)
+ gcmkONERROR(gckOS_GetPhysicalAddress(Kernel->os, PhysicalArray, &physical));
+ gcmkVERIFY_OK(gckOS_CPUPhysicalToGPUPhysical(Kernel->os, physical, &physical));
+ gcmkSAFECASTPHYSADDRT(address, physical);
+ iface.u.MapMemory.physicals = (gctUINT32 *)address;
+#endif
+
+ iface.u.MapMemory.pageCount = PageCount;
+
+ gcmkONERROR(gckKERNEL_SecurityCallService(Kernel->securityChannel, &iface));
+
+ *GPUAddress = iface.u.MapMemory.gpuAddress;
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ gcmkFOOTER();
+ return status;
+}
+
+gceSTATUS
+gckKERNEL_SecurityUnmapMemory(
+ IN gckKERNEL Kernel,
+ IN gctUINT32 GPUAddress,
+ IN gctUINT32 PageCount
+ )
+{
+ gceSTATUS status;
+ gcsTA_INTERFACE iface;
+
+ gcmkHEADER();
+
+ iface.command = KERNEL_UNMAP_MEMORY;
+
+ iface.u.UnmapMemory.gpuAddress = GPUAddress;
+ iface.u.UnmapMemory.pageCount = PageCount;
+
+ gcmkONERROR(gckKERNEL_SecurityCallService(Kernel->securityChannel, &iface));
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ gcmkFOOTER();
+ return status;
+}
+
+#endif
diff --git a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_security_v1.c b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_security_v1.c
new file mode 100644
index 000000000000..89a4333f6f2f
--- /dev/null
+++ b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_security_v1.c
@@ -0,0 +1,320 @@
+/****************************************************************************
+*
+* The MIT License (MIT)
+*
+* Copyright (c) 2014 - 2018 Vivante 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 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 GPL License (GPL)
+*
+* Copyright (C) 2014 - 2018 Vivante 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.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+*****************************************************************************
+*
+* Note: This software is released under dual MIT and GPL licenses. A
+* recipient may use this file under the terms of either the MIT license or
+* GPL License. If you wish to use only one license not the other, you can
+* indicate your decision by deleting one of the above license notices in your
+* version of this file.
+*
+*****************************************************************************/
+
+
+#include "gc_hal_kernel_precomp.h"
+
+
+
+
+#define _GC_OBJ_ZONE gcvZONE_KERNEL
+
+#if gcdENABLE_TRUST_APPLICATION
+
+/*
+** Open a security service channel.
+*/
+gceSTATUS
+gckKERNEL_SecurityOpen(
+ IN gckKERNEL Kernel,
+ IN gctUINT32 GPU,
+ OUT gctUINT32 *Channel
+ )
+{
+ gceSTATUS status;
+
+ gcmkONERROR(gckOS_OpenSecurityChannel(Kernel->os, Kernel->core, Channel));
+ gcmkONERROR(gckOS_InitSecurityChannel(*Channel));
+
+ return gcvSTATUS_OK;
+
+OnError:
+ return status;
+}
+
+/*
+** Close a security service channel
+*/
+gceSTATUS
+gckKERNEL_SecurityClose(
+ IN gctUINT32 Channel
+ )
+{
+ return gcvSTATUS_OK;
+}
+
+/*
+** Security service interface.
+*/
+gceSTATUS
+gckKERNEL_SecurityCallService(
+ IN gctUINT32 Channel,
+ IN OUT gcsTA_INTERFACE * Interface
+)
+{
+ gceSTATUS status;
+ gcmkHEADER();
+
+ gcmkVERIFY_ARGUMENT(Interface != gcvNULL);
+
+ gckOS_CallSecurityService(Channel, Interface);
+
+ status = Interface->result;
+
+ gcmkONERROR(status);
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ gcmkFOOTER();
+ return status;
+}
+
+gceSTATUS
+gckKERNEL_SecurityStartCommand(
+ IN gckKERNEL Kernel,
+ IN gctUINT32 Address,
+ IN gctUINT32 Bytes
+ )
+{
+ gceSTATUS status;
+ gcsTA_INTERFACE iface;
+
+ gcmkHEADER();
+
+ iface.command = KERNEL_START_COMMAND;
+ iface.u.StartCommand.gpu = Kernel->core;
+ iface.u.StartCommand.address = Address;
+ iface.u.StartCommand.bytes = Bytes;
+
+ gcmkONERROR(gckKERNEL_SecurityCallService(Kernel->securityChannel, &iface));
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ gcmkFOOTER();
+ return status;
+}
+
+gceSTATUS
+gckKERNEL_SecurityAllocateSecurityMemory(
+ IN gckKERNEL Kernel,
+ IN gctUINT32 Bytes,
+ OUT gctUINT32 * Handle
+ )
+{
+ gceSTATUS status;
+ gcsTA_INTERFACE iface;
+
+ gcmkHEADER();
+
+ iface.command = KERNEL_ALLOCATE_SECRUE_MEMORY;
+ iface.u.AllocateSecurityMemory.bytes = Bytes;
+
+ gcmkONERROR(gckKERNEL_SecurityCallService(Kernel->securityChannel, &iface));
+
+ *Handle = iface.u.AllocateSecurityMemory.memory_handle;
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ gcmkFOOTER();
+ return status;
+}
+
+gceSTATUS
+gckKERNEL_SecurityMapMemory(
+ IN gckKERNEL Kernel,
+ IN gctUINT32 *PhysicalArray,
+ IN gctPHYS_ADDR_T Physical,
+ IN gctUINT32 PageCount,
+ OUT gctUINT32 * GPUAddress
+ )
+{
+ gceSTATUS status;
+ gcsTA_INTERFACE iface;
+
+ gcmkHEADER();
+
+ iface.command = KERNEL_MAP_MEMORY;
+
+ iface.u.MapMemory.physicals = PhysicalArray;
+ iface.u.MapMemory.physical = Physical;
+ iface.u.MapMemory.pageCount = PageCount;
+ iface.u.MapMemory.gpuAddress = *GPUAddress;
+
+ gcmkONERROR(gckKERNEL_SecurityCallService(Kernel->securityChannel, &iface));
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ gcmkFOOTER();
+ return status;
+}
+
+gceSTATUS
+gckKERNEL_SecurityDumpMMUException(
+ IN gckKERNEL Kernel
+ )
+{
+ gceSTATUS status;
+ gcsTA_INTERFACE iface;
+
+ gcmkHEADER();
+
+ iface.command = KERNEL_DUMP_MMU_EXCEPTION;
+
+ gcmkONERROR(gckKERNEL_SecurityCallService(Kernel->securityChannel, &iface));
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ gcmkFOOTER();
+ return status;
+}
+
+
+
+gceSTATUS
+gckKERNEL_SecurityUnmapMemory(
+ IN gckKERNEL Kernel,
+ IN gctUINT32 GPUAddress,
+ IN gctUINT32 PageCount
+ )
+{
+ gceSTATUS status;
+ gcsTA_INTERFACE iface;
+
+ gcmkHEADER();
+
+ iface.command = KERNEL_UNMAP_MEMORY;
+
+ iface.u.UnmapMemory.gpuAddress = GPUAddress;
+ iface.u.UnmapMemory.pageCount = PageCount;
+
+ gcmkONERROR(gckKERNEL_SecurityCallService(Kernel->securityChannel, &iface));
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ gcmkFOOTER();
+ return status;
+}
+
+gceSTATUS
+gckKERNEL_ReadMMUException(
+ IN gckKERNEL Kernel,
+ IN gctUINT32_PTR MMUStatus,
+ IN gctUINT32_PTR MMUException
+ )
+{
+ gceSTATUS status;
+ gcsTA_INTERFACE iface;
+
+ gcmkHEADER();
+
+ iface.command = KERNEL_READ_MMU_EXCEPTION;
+
+ gcmkONERROR(gckKERNEL_SecurityCallService(Kernel->securityChannel, &iface));
+
+ *MMUStatus = iface.u.ReadMMUException.mmuStatus;
+ *MMUException = iface.u.ReadMMUException.mmuException;
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ gcmkFOOTER();
+ return status;
+}
+
+gceSTATUS
+gckKERNEL_HandleMMUException(
+ IN gckKERNEL Kernel,
+ IN gctUINT32 MMUStatus,
+ IN gctPHYS_ADDR_T Physical,
+ IN gctUINT32 GPUAddress
+ )
+{
+ gceSTATUS status;
+ gcsTA_INTERFACE iface;
+
+ gcmkHEADER();
+
+ iface.command = KERNEL_HANDLE_MMU_EXCEPTION;
+
+ iface.u.HandleMMUException.mmuStatus = MMUStatus;
+ iface.u.HandleMMUException.physical = Physical;
+ iface.u.HandleMMUException.gpuAddress = GPUAddress;
+
+ gcmkONERROR(gckKERNEL_SecurityCallService(Kernel->securityChannel, &iface));
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ gcmkFOOTER();
+ return status;
+}
+
+
+
+
+#endif
diff --git a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_vg.c b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_vg.c
new file mode 100644
index 000000000000..44a1bb0861eb
--- /dev/null
+++ b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_vg.c
@@ -0,0 +1,644 @@
+/****************************************************************************
+*
+* The MIT License (MIT)
+*
+* Copyright (c) 2014 - 2018 Vivante 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 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 GPL License (GPL)
+*
+* Copyright (C) 2014 - 2018 Vivante 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.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+*****************************************************************************
+*
+* Note: This software is released under dual MIT and GPL licenses. A
+* recipient may use this file under the terms of either the MIT license or
+* GPL License. If you wish to use only one license not the other, you can
+* indicate your decision by deleting one of the above license notices in your
+* version of this file.
+*
+*****************************************************************************/
+
+
+#include "gc_hal_kernel_precomp.h"
+
+#if gcdENABLE_VG
+
+#define _GC_OBJ_ZONE gcvZONE_VG
+
+/******************************************************************************\
+******************************* gckKERNEL API Code ******************************
+\******************************************************************************/
+
+/*******************************************************************************
+**
+** gckKERNEL_Construct
+**
+** Construct a new gckKERNEL object.
+**
+** INPUT:
+**
+** gckOS Os
+** Pointer to an gckOS object.
+**
+** IN gctPOINTER Context
+** Pointer to a driver defined context.
+**
+** OUTPUT:
+**
+** gckKERNEL * Kernel
+** Pointer to a variable that will hold the pointer to the gckKERNEL
+** object.
+*/
+gceSTATUS gckVGKERNEL_Construct(
+ IN gckOS Os,
+ IN gctPOINTER Context,
+ IN gckKERNEL inKernel,
+ OUT gckVGKERNEL * Kernel
+ )
+{
+ gceSTATUS status;
+ gckVGKERNEL kernel = gcvNULL;
+
+ gcmkHEADER_ARG("Os=0x%x Context=0x%x", Os, Context);
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
+ gcmkVERIFY_ARGUMENT(Kernel != gcvNULL);
+
+ do
+ {
+ /* Allocate the gckKERNEL object. */
+ gcmkERR_BREAK(gckOS_Allocate(
+ Os,
+ sizeof(struct _gckVGKERNEL),
+ (gctPOINTER *) &kernel
+ ));
+
+ /* Initialize the gckKERNEL object. */
+ kernel->object.type = gcvOBJ_KERNEL;
+ kernel->os = Os;
+ kernel->context = Context;
+ kernel->hardware = gcvNULL;
+ kernel->interrupt = gcvNULL;
+ kernel->command = gcvNULL;
+ kernel->mmu = gcvNULL;
+ kernel->kernel = inKernel;
+
+ /* Construct the gckVGHARDWARE object. */
+ gcmkERR_BREAK(gckVGHARDWARE_Construct(
+ Os, &kernel->hardware
+ ));
+
+ /* Set pointer to gckKERNEL object in gckVGHARDWARE object. */
+ kernel->hardware->kernel = kernel;
+
+ /* Construct the gckVGINTERRUPT object. */
+ gcmkERR_BREAK(gckVGINTERRUPT_Construct(
+ kernel, &kernel->interrupt
+ ));
+
+ /* Construct the gckVGCOMMAND object. */
+ gcmkERR_BREAK(gckVGCOMMAND_Construct(
+ kernel, gcmKB2BYTES(8), gcmKB2BYTES(2), &kernel->command
+ ));
+
+ /* Construct the gckVGMMU object. */
+ gcmkERR_BREAK(gckVGMMU_Construct(
+ kernel, gcmKB2BYTES(gcdGC355_VGMMU_MEMORY_SIZE_KB), &kernel->mmu
+ ));
+
+ /* Return pointer to the gckKERNEL object. */
+ *Kernel = kernel;
+
+ gcmkFOOTER_ARG("*Kernel=0x%x", *Kernel);
+ /* Success. */
+ return gcvSTATUS_OK;
+ }
+ while (gcvFALSE);
+
+ /* Roll back. */
+ if (kernel != gcvNULL)
+ {
+ if (kernel->mmu != gcvNULL)
+ {
+ gcmkVERIFY_OK(gckVGMMU_Destroy(kernel->mmu));
+ }
+
+ if (kernel->command != gcvNULL)
+ {
+ gcmkVERIFY_OK(gckVGCOMMAND_Destroy(kernel->command));
+ }
+
+ if (kernel->interrupt != gcvNULL)
+ {
+ gcmkVERIFY_OK(gckVGINTERRUPT_Destroy(kernel->interrupt));
+ }
+
+ if (kernel->hardware != gcvNULL)
+ {
+ gcmkVERIFY_OK(gckVGHARDWARE_Destroy(kernel->hardware));
+ }
+
+ gcmkVERIFY_OK(gckOS_Free(Os, kernel));
+ }
+
+ gcmkFOOTER();
+ /* Return status. */
+ return status;
+}
+
+/*******************************************************************************
+**
+** gckKERNEL_Destroy
+**
+** Destroy an gckKERNEL object.
+**
+** INPUT:
+**
+** gckKERNEL Kernel
+** Pointer to an gckKERNEL object to destroy.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS gckVGKERNEL_Destroy(
+ IN gckVGKERNEL Kernel
+ )
+{
+ gceSTATUS status;
+
+ gcmkHEADER_ARG("Kernel=0x%x", Kernel);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
+
+ do
+ {
+ /* Destroy the gckVGMMU object. */
+ if (Kernel->mmu != gcvNULL)
+ {
+ gcmkERR_BREAK(gckVGMMU_Destroy(Kernel->mmu));
+ Kernel->mmu = gcvNULL;
+ }
+
+ /* Destroy the gckVGCOMMAND object. */
+ if (Kernel->command != gcvNULL)
+ {
+ gcmkERR_BREAK(gckVGCOMMAND_Destroy(Kernel->command));
+ Kernel->command = gcvNULL;
+ }
+
+ /* Destroy the gckVGINTERRUPT object. */
+ if (Kernel->interrupt != gcvNULL)
+ {
+ gcmkERR_BREAK(gckVGINTERRUPT_Destroy(Kernel->interrupt));
+ Kernel->interrupt = gcvNULL;
+ }
+
+ /* Destroy the gckVGHARDWARE object. */
+ if (Kernel->hardware != gcvNULL)
+ {
+ gcmkERR_BREAK(gckVGHARDWARE_Destroy(Kernel->hardware));
+ Kernel->hardware = gcvNULL;
+ }
+
+ /* Mark the gckKERNEL object as unknown. */
+ Kernel->object.type = gcvOBJ_UNKNOWN;
+
+ /* Free the gckKERNEL object. */
+ gcmkERR_BREAK(gckOS_Free(Kernel->os, Kernel));
+ }
+ while (gcvFALSE);
+
+ gcmkFOOTER();
+
+ /* Return status. */
+ return status;
+}
+
+/*******************************************************************************
+**
+** gckKERNEL_Dispatch
+**
+** Dispatch a command received from the user HAL layer.
+**
+** INPUT:
+**
+** gckKERNEL Kernel
+** Pointer to an gckKERNEL object.
+**
+** gcsHAL_INTERFACE * Interface
+** Pointer to a gcsHAL_INTERFACE structure that defines the command to
+** be dispatched.
+**
+** OUTPUT:
+**
+** gcsHAL_INTERFACE * Interface
+** Pointer to a gcsHAL_INTERFACE structure that receives any data to be
+** returned.
+*/
+gceSTATUS gckVGKERNEL_Dispatch(
+ IN gckKERNEL Kernel,
+ IN gctBOOL FromUser,
+ IN OUT gcsHAL_INTERFACE * Interface
+ )
+{
+ gceSTATUS status;
+ gcsHAL_INTERFACE * kernelInterface = Interface;
+ gctUINT32 processID;
+ gckKERNEL kernel = Kernel;
+ gctPHYS_ADDR physical = gcvNULL;
+ gctPOINTER logical = gcvNULL;
+ gctSIZE_T bytes = 0;
+ gctBOOL powerMutexAcquired = gcvFALSE;
+
+ gcmkHEADER_ARG("Kernel=0x%x Interface=0x%x ", Kernel, Interface);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
+ gcmkVERIFY_ARGUMENT(Interface != gcvNULL);
+
+ gcmkONERROR(gckOS_GetProcessID(&processID));
+
+ /* Dispatch on command. */
+ switch (Interface->command)
+ {
+ case gcvHAL_QUERY_CHIP_IDENTITY:
+ /* Query chip identity. */
+ gcmkERR_BREAK(gckVGHARDWARE_QueryChipIdentity(
+ Kernel->vg->hardware,
+ &kernelInterface->u.QueryChipIdentity.chipModel,
+ &kernelInterface->u.QueryChipIdentity.chipRevision,
+ &kernelInterface->u.QueryChipIdentity.productID,
+ &kernelInterface->u.QueryChipIdentity.ecoID,
+ &kernelInterface->u.QueryChipIdentity.customerID,
+ &kernelInterface->u.QueryChipIdentity.chipFeatures,
+ &kernelInterface->u.QueryChipIdentity.chipMinorFeatures,
+ &kernelInterface->u.QueryChipIdentity.chipMinorFeatures2
+ ));
+ break;
+
+ case gcvHAL_QUERY_COMMAND_BUFFER:
+ /* Query command buffer information. */
+ gcmkERR_BREAK(gckKERNEL_QueryCommandBuffer(
+ Kernel,
+ &kernelInterface->u.QueryCommandBuffer.information
+ ));
+ break;
+
+ case gcvHAL_ALLOCATE_NON_PAGED_MEMORY:
+ bytes = (gctSIZE_T) kernelInterface->u.AllocateNonPagedMemory.bytes;
+ /* Allocate non-paged memory. */
+ gcmkERR_BREAK(gckOS_AllocateNonPagedMemory(
+ Kernel->os,
+ gcvTRUE,
+ gcvALLOC_FLAG_CONTIGUOUS,
+ &bytes,
+ &physical,
+ &logical
+ ));
+
+ kernelInterface->u.AllocateNonPagedMemory.bytes = bytes;
+ kernelInterface->u.AllocateNonPagedMemory.logical = gcmPTR_TO_UINT64(logical);
+ kernelInterface->u.AllocateNonPagedMemory.physical = gcmPTR_TO_NAME(physical);
+ break;
+
+ case gcvHAL_FREE_NON_PAGED_MEMORY:
+ physical = gcmNAME_TO_PTR(kernelInterface->u.FreeNonPagedMemory.physical);
+
+ /* Unmap user logical out of physical memory first. */
+ gcmkERR_BREAK(gckOS_UnmapUserLogical(
+ Kernel->os,
+ physical,
+ (gctSIZE_T) kernelInterface->u.FreeNonPagedMemory.bytes,
+ gcmUINT64_TO_PTR(kernelInterface->u.FreeNonPagedMemory.logical)));
+
+
+ /* Free non-paged memory. */
+ gcmkERR_BREAK(gckOS_FreeNonPagedMemory(
+ Kernel->os,
+ (gctSIZE_T) kernelInterface->u.FreeNonPagedMemory.bytes,
+ physical,
+ gcmUINT64_TO_PTR(kernelInterface->u.FreeNonPagedMemory.logical)
+ ));
+
+ gcmRELEASE_NAME(kernelInterface->u.FreeNonPagedMemory.physical);
+ break;
+
+ case gcvHAL_ALLOCATE_CONTIGUOUS_MEMORY:
+ bytes = (gctSIZE_T) kernelInterface->u.AllocateContiguousMemory.bytes;
+ /* Allocate contiguous memory. */
+ gcmkERR_BREAK(gckOS_AllocateContiguous(
+ Kernel->os,
+ gcvTRUE,
+ &bytes,
+ &physical,
+ &logical
+ ));
+
+ kernelInterface->u.AllocateContiguousMemory.bytes = bytes;
+ kernelInterface->u.AllocateContiguousMemory.logical = gcmPTR_TO_UINT64(logical);
+ kernelInterface->u.AllocateContiguousMemory.physical = gcmPTR_TO_NAME(physical);
+ break;
+
+ case gcvHAL_FREE_CONTIGUOUS_MEMORY:
+ physical = gcmNAME_TO_PTR(kernelInterface->u.FreeContiguousMemory.physical);
+ /* Unmap user logical out of physical memory first. */
+ gcmkERR_BREAK(gckOS_UnmapUserLogical(
+ Kernel->os,
+ physical,
+ (gctSIZE_T) kernelInterface->u.FreeContiguousMemory.bytes,
+ gcmUINT64_TO_PTR(kernelInterface->u.FreeContiguousMemory.logical)
+ ));
+
+ /* Free contiguous memory. */
+ gcmkERR_BREAK(gckOS_FreeContiguous(
+ Kernel->os,
+ physical,
+ gcmUINT64_TO_PTR(kernelInterface->u.FreeContiguousMemory.logical),
+ (gctSIZE_T) kernelInterface->u.FreeContiguousMemory.bytes
+ ));
+
+ gcmRELEASE_NAME(kernelInterface->u.FreeContiguousMemory.physical);
+ break;
+
+ case gcvHAL_ALLOCATE_VIDEO_MEMORY:
+ gcmkERR_BREAK(gcvSTATUS_NOT_SUPPORTED);
+ break;
+
+ case gcvHAL_MAP_MEMORY:
+ /* Map memory. */
+ gcmkERR_BREAK(gckKERNEL_MapMemory(
+ Kernel,
+ gcmINT2PTR(kernelInterface->u.MapMemory.physical),
+ (gctSIZE_T) kernelInterface->u.MapMemory.bytes,
+ &logical
+ ));
+ kernelInterface->u.MapMemory.logical = gcmPTR_TO_UINT64(logical);
+ break;
+
+ case gcvHAL_UNMAP_MEMORY:
+ /* Unmap memory. */
+ gcmkERR_BREAK(gckKERNEL_UnmapMemory(
+ Kernel,
+ gcmINT2PTR(kernelInterface->u.MapMemory.physical),
+ (gctSIZE_T) kernelInterface->u.MapMemory.bytes,
+ gcmUINT64_TO_PTR(kernelInterface->u.MapMemory.logical),
+ processID
+ ));
+ break;
+
+ case gcvHAL_MAP_USER_MEMORY:
+
+ gcmkONERROR(gcvSTATUS_NOT_SUPPORTED);
+
+ break;
+
+ case gcvHAL_UNMAP_USER_MEMORY:
+
+ gcmkONERROR(gcvSTATUS_NOT_SUPPORTED);
+
+ break;
+
+ case gcvHAL_LOCK_VIDEO_MEMORY:
+ gcmkONERROR(gckKERNEL_LockVideoMemory(Kernel, gcvCORE_VG, processID, FromUser, Interface));
+ break;
+
+ case gcvHAL_BOTTOM_HALF_UNLOCK_VIDEO_MEMORY:
+ gcmkERR_BREAK(gckKERNEL_BottomHalfUnlockVideoMemory(Kernel, processID,
+ kernelInterface->u.BottomHalfUnlockVideoMemory.node));
+ break;
+
+ case gcvHAL_USER_SIGNAL:
+#if !USE_NEW_LINUX_SIGNAL
+ /* Dispatch depends on the user signal subcommands. */
+ switch(Interface->u.UserSignal.command)
+ {
+ case gcvUSER_SIGNAL_CREATE:
+ /* Create a signal used in the user space. */
+ gcmkERR_BREAK(
+ gckOS_CreateUserSignal(Kernel->os,
+ Interface->u.UserSignal.manualReset,
+ &Interface->u.UserSignal.id));
+
+ gcmkVERIFY_OK(
+ gckKERNEL_AddProcessDB(Kernel,
+ processID, gcvDB_SIGNAL,
+ gcmINT2PTR(Interface->u.UserSignal.id),
+ gcvNULL,
+ 0));
+ break;
+
+ case gcvUSER_SIGNAL_DESTROY:
+ gcmkVERIFY_OK(gckKERNEL_RemoveProcessDB(
+ Kernel,
+ processID, gcvDB_SIGNAL,
+ gcmINT2PTR(Interface->u.UserSignal.id)));
+
+ /* Destroy the signal. */
+ gcmkERR_BREAK(
+ gckOS_DestroyUserSignal(Kernel->os,
+ Interface->u.UserSignal.id));
+
+ break;
+
+ case gcvUSER_SIGNAL_SIGNAL:
+ /* Signal the signal. */
+ gcmkERR_BREAK(
+ gckOS_SignalUserSignal(Kernel->os,
+ Interface->u.UserSignal.id,
+ Interface->u.UserSignal.state));
+ break;
+
+ case gcvUSER_SIGNAL_WAIT:
+ /* Wait on the signal. */
+ status = gckOS_WaitUserSignal(Kernel->os,
+ Interface->u.UserSignal.id,
+ Interface->u.UserSignal.wait);
+ break;
+
+ default:
+ /* Invalid user signal command. */
+ gcmkERR_BREAK(gcvSTATUS_INVALID_ARGUMENT);
+ }
+#endif
+ break;
+
+ case gcvHAL_COMMIT:
+ /* Commit a command and context buffer. */
+ gcmkERR_BREAK(gckVGCOMMAND_Commit(
+ Kernel->vg->command,
+ gcmUINT64_TO_PTR(kernelInterface->u.VGCommit.context),
+ gcmUINT64_TO_PTR(kernelInterface->u.VGCommit.queue),
+ kernelInterface->u.VGCommit.entryCount,
+ gcmUINT64_TO_PTR(kernelInterface->u.VGCommit.taskTable)
+ ));
+ break;
+
+ case gcvHAL_GET_BASE_ADDRESS:
+ /* Get base address. */
+ gcmkONERROR(
+ gckOS_GetBaseAddress(Kernel->os,
+ &Interface->u.GetBaseAddress.baseAddress));
+ break;
+
+ case gcvHAL_EVENT_COMMIT:
+ gcmkERR_BREAK(gcvSTATUS_NOT_SUPPORTED);
+ break;
+ case gcvHAL_READ_REGISTER:
+#if gcdREGISTER_ACCESS_FROM_USER
+ {
+ gceCHIPPOWERSTATE power;
+
+ gcmkONERROR(gckOS_AcquireMutex(Kernel->os, Kernel->vg->hardware->powerMutex, gcvINFINITE));
+ powerMutexAcquired = gcvTRUE;
+ gcmkONERROR(gckVGHARDWARE_QueryPowerManagementState(Kernel->vg->hardware,
+ &power));
+ if (power == gcvPOWER_ON)
+ {
+ /* Read a register. */
+ gcmkONERROR(gckOS_ReadRegisterEx(
+ Kernel->os,
+ Kernel->core,
+ Interface->u.ReadRegisterData.address,
+ &Interface->u.ReadRegisterData.data));
+ }
+ else
+ {
+ /* Chip is in power-state. */
+ Interface->u.ReadRegisterData.data = 0;
+ status = gcvSTATUS_CHIP_NOT_READY;
+ }
+ gcmkONERROR(gckOS_ReleaseMutex(Kernel->os, Kernel->vg->hardware->powerMutex));
+ powerMutexAcquired = gcvFALSE;
+ }
+#else
+ /* No access from user land to read registers. */
+ Interface->u.ReadRegisterData.data = 0;
+ status = gcvSTATUS_NOT_SUPPORTED;
+#endif
+ break;
+
+ case gcvHAL_WRITE_REGISTER:
+#if gcdREGISTER_ACCESS_FROM_USER
+ {
+ gceCHIPPOWERSTATE power;
+
+ gcmkONERROR(gckOS_AcquireMutex(Kernel->os, Kernel->vg->hardware->powerMutex, gcvINFINITE));
+ powerMutexAcquired = gcvTRUE;
+ gcmkONERROR(gckVGHARDWARE_QueryPowerManagementState(Kernel->vg->hardware,
+ &power));
+ if (power == gcvPOWER_ON)
+ {
+ /* Write a register. */
+ gcmkONERROR(
+ gckOS_WriteRegisterEx(Kernel->os,
+ Kernel->core,
+ Interface->u.WriteRegisterData.address,
+ Interface->u.WriteRegisterData.data));
+ }
+ else
+ {
+ /* Chip is in power-state. */
+ Interface->u.WriteRegisterData.data = 0;
+ status = gcvSTATUS_CHIP_NOT_READY;
+ }
+ gcmkONERROR(gckOS_ReleaseMutex(Kernel->os, Kernel->vg->hardware->powerMutex));
+ powerMutexAcquired = gcvFALSE;
+ }
+#else
+ /* No access from user land to write registers. */
+ status = gcvSTATUS_NOT_SUPPORTED;
+#endif
+ break;
+ default:
+ /* Invalid command, try gckKERNEL_Dispatch */
+ status = gckKERNEL_Dispatch(Kernel, gcvNULL, gcvTRUE, Interface);
+ }
+
+OnError:
+ /* Save status. */
+ kernelInterface->status = status;
+ if (powerMutexAcquired == gcvTRUE)
+ {
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, Kernel->vg->hardware->powerMutex));
+ }
+
+ gcmkFOOTER();
+
+ /* Return the status. */
+ return status;
+}
+
+/*******************************************************************************
+**
+** gckKERNEL_QueryCommandBuffer
+**
+** Query command buffer attributes.
+**
+** INPUT:
+**
+** gckKERNEL Kernel
+** Pointer to an gckVGHARDWARE object.
+**
+** OUTPUT:
+**
+** gcsCOMMAND_BUFFER_INFO_PTR Information
+** Pointer to the information structure to receive buffer attributes.
+*/
+gceSTATUS
+gckKERNEL_QueryCommandBuffer(
+ IN gckKERNEL Kernel,
+ OUT gcsCOMMAND_BUFFER_INFO_PTR Information
+ )
+{
+ gceSTATUS status;
+
+ gcmkHEADER_ARG("Kernel=0x%x *Pool=0x%x",
+ Kernel, Information);
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
+
+ /* Get the information. */
+ status = gckVGCOMMAND_QueryCommandBuffer(Kernel->vg->command, Information);
+
+ gcmkFOOTER();
+ /* Return status. */
+ return status;
+}
+
+#endif /* gcdENABLE_VG */
diff --git a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_vg.h b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_vg.h
new file mode 100644
index 000000000000..63da8837d67c
--- /dev/null
+++ b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_vg.h
@@ -0,0 +1,119 @@
+/****************************************************************************
+*
+* The MIT License (MIT)
+*
+* Copyright (c) 2014 - 2018 Vivante 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 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 GPL License (GPL)
+*
+* Copyright (C) 2014 - 2018 Vivante 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.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+*****************************************************************************
+*
+* Note: This software is released under dual MIT and GPL licenses. A
+* recipient may use this file under the terms of either the MIT license or
+* GPL License. If you wish to use only one license not the other, you can
+* indicate your decision by deleting one of the above license notices in your
+* version of this file.
+*
+*****************************************************************************/
+
+
+#ifndef __gc_hal_kernel_vg_h_
+#define __gc_hal_kernel_vg_h_
+
+#include "gc_hal.h"
+#include "gc_hal_driver.h"
+#include "gc_hal_kernel_hardware.h"
+
+/******************************************************************************\
+********************************** Structures **********************************
+\******************************************************************************/
+
+/* gckKERNEL object. */
+struct _gckVGKERNEL
+{
+ /* Object. */
+ gcsOBJECT object;
+
+ /* Pointer to gckOS object. */
+ gckOS os;
+
+ /* Pointer to gckHARDWARE object. */
+ gckVGHARDWARE hardware;
+
+ /* Pointer to gckINTERRUPT object. */
+ gckVGINTERRUPT interrupt;
+
+ /* Pointer to gckCOMMAND object. */
+ gckVGCOMMAND command;
+
+ /* Pointer to context. */
+ gctPOINTER context;
+
+ /* Pointer to gckMMU object. */
+ gckVGMMU mmu;
+
+ gckKERNEL kernel;
+};
+
+/* gckMMU object. */
+struct _gckVGMMU
+{
+ /* The object. */
+ gcsOBJECT object;
+
+ /* Pointer to gckOS object. */
+ gckOS os;
+
+ /* Pointer to gckHARDWARE object. */
+ gckVGHARDWARE hardware;
+
+ /* The page table mutex. */
+ gctPOINTER mutex;
+
+ /* Page table information. */
+ gctSIZE_T pageTableSize;
+ gctPHYS_ADDR pageTablePhysical;
+ gctPOINTER pageTableLogical;
+
+ /* Allocation index. */
+ gctUINT32 entryCount;
+ gctUINT32 entry;
+};
+
+#endif /* __gc_hal_kernel_h_ */
diff --git a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_video_memory.c b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_video_memory.c
new file mode 100644
index 000000000000..5c27cbac4fba
--- /dev/null
+++ b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_video_memory.c
@@ -0,0 +1,3590 @@
+/****************************************************************************
+*
+* The MIT License (MIT)
+*
+* Copyright (c) 2014 - 2018 Vivante 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 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 GPL License (GPL)
+*
+* Copyright (C) 2014 - 2018 Vivante 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.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+*****************************************************************************
+*
+* Note: This software is released under dual MIT and GPL licenses. A
+* recipient may use this file under the terms of either the MIT license or
+* GPL License. If you wish to use only one license not the other, you can
+* indicate your decision by deleting one of the above license notices in your
+* version of this file.
+*
+*****************************************************************************/
+
+
+#include "gc_hal_kernel_precomp.h"
+
+#if defined(__QNXNTO__)
+#include <stdlib.h>
+#include <sys/slogcodes.h>
+#include <time.h>
+
+extern unsigned int slogUsageInterval;
+#endif
+
+#define _GC_OBJ_ZONE gcvZONE_VIDMEM
+
+/******************************************************************************\
+******************************* Private Functions ******************************
+\******************************************************************************/
+
+/*******************************************************************************
+**
+** _Split
+**
+** Split a node on the required byte boundary.
+**
+** INPUT:
+**
+** gckOS Os
+** Pointer to an gckOS object.
+**
+** gcuVIDMEM_NODE_PTR Node
+** Pointer to the node to split.
+**
+** gctSIZE_T Bytes
+** Number of bytes to keep in the node.
+**
+** OUTPUT:
+**
+** Nothing.
+**
+** RETURNS:
+**
+** gctBOOL
+** gcvTRUE if the node was split successfully, or gcvFALSE if there is an
+** error.
+**
+*/
+static gctBOOL
+_Split(
+ IN gckOS Os,
+ IN gcuVIDMEM_NODE_PTR Node,
+ IN gctSIZE_T Bytes
+ )
+{
+ gcuVIDMEM_NODE_PTR node;
+ gctPOINTER pointer = gcvNULL;
+
+ /* Make sure the byte boundary makes sense. */
+ if ((Bytes <= 0) || (Bytes > Node->VidMem.bytes))
+ {
+ return gcvFALSE;
+ }
+
+ /* Allocate a new gcuVIDMEM_NODE object. */
+ if (gcmIS_ERROR(gckOS_Allocate(Os,
+ gcmSIZEOF(gcuVIDMEM_NODE),
+ &pointer)))
+ {
+ /* Error. */
+ return gcvFALSE;
+ }
+
+ node = pointer;
+
+ /* Initialize gcuVIDMEM_NODE structure. */
+ node->VidMem.offset = Node->VidMem.offset + Bytes;
+ node->VidMem.bytes = Node->VidMem.bytes - Bytes;
+ node->VidMem.alignment = 0;
+ node->VidMem.locked = 0;
+ node->VidMem.memory = Node->VidMem.memory;
+ node->VidMem.pool = Node->VidMem.pool;
+ node->VidMem.physical = Node->VidMem.physical;
+#ifdef __QNXNTO__
+ node->VidMem.processID = 0;
+ node->VidMem.logical = gcvNULL;
+#endif
+
+ /* Insert node behind specified node. */
+ node->VidMem.next = Node->VidMem.next;
+ node->VidMem.prev = Node;
+ Node->VidMem.next = node->VidMem.next->VidMem.prev = node;
+
+ /* Insert free node behind specified node. */
+ node->VidMem.nextFree = Node->VidMem.nextFree;
+ node->VidMem.prevFree = Node;
+ Node->VidMem.nextFree = node->VidMem.nextFree->VidMem.prevFree = node;
+
+ /* Adjust size of specified node. */
+ Node->VidMem.bytes = Bytes;
+
+ /* Success. */
+ return gcvTRUE;
+}
+
+/*******************************************************************************
+**
+** _Merge
+**
+** Merge two adjacent nodes together.
+**
+** INPUT:
+**
+** gckOS Os
+** Pointer to an gckOS object.
+**
+** gcuVIDMEM_NODE_PTR Node
+** Pointer to the first of the two nodes to merge.
+**
+** OUTPUT:
+**
+** Nothing.
+**
+*/
+static gceSTATUS
+_Merge(
+ IN gckOS Os,
+ IN gcuVIDMEM_NODE_PTR Node
+ )
+{
+ gcuVIDMEM_NODE_PTR node;
+ gceSTATUS status;
+
+ /* Save pointer to next node. */
+ node = Node->VidMem.next;
+
+ /* This is a good time to make sure the heap is not corrupted. */
+ if (Node->VidMem.offset + Node->VidMem.bytes != node->VidMem.offset)
+ {
+ /* Corrupted heap. */
+ gcmkASSERT(
+ Node->VidMem.offset + Node->VidMem.bytes == node->VidMem.offset);
+ return gcvSTATUS_HEAP_CORRUPTED;
+ }
+
+ /* Adjust byte count. */
+ Node->VidMem.bytes += node->VidMem.bytes;
+
+ /* Unlink next node from linked list. */
+ Node->VidMem.next = node->VidMem.next;
+ Node->VidMem.nextFree = node->VidMem.nextFree;
+
+ Node->VidMem.next->VidMem.prev =
+ Node->VidMem.nextFree->VidMem.prevFree = Node;
+
+ /* Free next node. */
+ status = gcmkOS_SAFE_FREE(Os, node);
+ return status;
+}
+
+/******************************************************************************\
+******************************* gckVIDMEM API Code ******************************
+\******************************************************************************/
+
+/*******************************************************************************
+**
+** gckVIDMEM_ConstructVirtual
+**
+** Construct a new gcuVIDMEM_NODE union for virtual memory.
+**
+** INPUT:
+**
+** gckKERNEL Kernel
+** Pointer to an gckKERNEL object.
+**
+** gctSIZE_T Bytes
+** Number of byte to allocate.
+**
+** OUTPUT:
+**
+** gcuVIDMEM_NODE_PTR * Node
+** Pointer to a variable that receives the gcuVIDMEM_NODE union pointer.
+*/
+gceSTATUS
+gckVIDMEM_ConstructVirtual(
+ IN gckKERNEL Kernel,
+ IN gctUINT32 Flag,
+ IN gctSIZE_T Bytes,
+ OUT gcuVIDMEM_NODE_PTR * Node
+ )
+{
+ gckOS os;
+ gceSTATUS status;
+ gcuVIDMEM_NODE_PTR node = gcvNULL;
+ gctPOINTER pointer = gcvNULL;
+ gctINT i;
+
+ gcmkHEADER_ARG("Kernel=0x%x Flag=%x Bytes=%lu", Kernel, Flag, Bytes);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
+ gcmkVERIFY_ARGUMENT(Bytes > 0);
+ gcmkVERIFY_ARGUMENT(Node != gcvNULL);
+
+ /* Extract the gckOS object pointer. */
+ os = Kernel->os;
+ gcmkVERIFY_OBJECT(os, gcvOBJ_OS);
+
+ /* Allocate an gcuVIDMEM_NODE union. */
+ gcmkONERROR(gckOS_Allocate(os, gcmSIZEOF(gcuVIDMEM_NODE), &pointer));
+
+ node = pointer;
+
+ /* Initialize gcuVIDMEM_NODE union for virtual memory. */
+ node->Virtual.kernel = Kernel;
+ node->Virtual.contiguous = Flag & gcvALLOC_FLAG_CONTIGUOUS;
+ node->Virtual.logical = gcvNULL;
+#if gcdENABLE_VG
+ node->Virtual.kernelVirtual = gcvNULL;
+#endif
+ node->Virtual.secure = (Flag & gcvALLOC_FLAG_SECURITY) != 0;
+ node->Virtual.onFault = (Flag & gcvALLOC_FLAG_ALLOC_ON_FAULT) != 0;
+
+ for (i = 0; i < gcdMAX_GPU_COUNT; i++)
+ {
+ node->Virtual.lockeds[i] = 0;
+ node->Virtual.pageTables[i] = gcvNULL;
+ }
+
+ /* Allocate the virtual memory. */
+ gcmkONERROR(
+ gckOS_AllocatePagedMemoryEx(os,
+ Flag,
+ node->Virtual.bytes = Bytes,
+ &node->Virtual.gid,
+ &node->Virtual.physical));
+
+ if (node->Virtual.onFault == gcvTRUE)
+ {
+ gcsLIST_Add(&node->Virtual.head, &Kernel->db->onFaultVidmemList);
+ }
+
+ /* Return pointer to the gcuVIDMEM_NODE union. */
+ *Node = node;
+
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_VIDMEM,
+ "Created virtual node 0x%x for %u bytes @ 0x%x",
+ node, Bytes, node->Virtual.physical);
+
+ /* Success. */
+ gcmkFOOTER_ARG("*Node=0x%x", *Node);
+ return gcvSTATUS_OK;
+
+OnError:
+ /* Roll back. */
+ if (node != gcvNULL)
+ {
+ /* Free the structure. */
+ gcmkVERIFY_OK(gcmkOS_SAFE_FREE(os, node));
+ }
+
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+/*******************************************************************************
+**
+** gckVIDMEM_DestroyVirtual
+**
+** Destroy an gcuVIDMEM_NODE union for virtual memory.
+**
+** INPUT:
+**
+** gcuVIDMEM_NODE_PTR Node
+** Pointer to a gcuVIDMEM_NODE union.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckVIDMEM_DestroyVirtual(
+ IN gcuVIDMEM_NODE_PTR Node
+ )
+{
+ gckOS os;
+
+ gcmkHEADER_ARG("Node=0x%x", Node);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Node->Virtual.kernel, gcvOBJ_KERNEL);
+
+ /* Extact the gckOS object pointer. */
+ os = Node->Virtual.kernel->os;
+ gcmkVERIFY_OBJECT(os, gcvOBJ_OS);
+
+ if (Node->Virtual.onFault == gcvTRUE)
+ {
+ gcsLIST_Del(&Node->Virtual.head);
+ }
+
+ /* Delete the gcuVIDMEM_NODE union. */
+ gcmkVERIFY_OK(gcmkOS_SAFE_FREE(os, Node));
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+}
+
+/*******************************************************************************
+**
+** gckVIDMEM_Construct
+**
+** Construct a new gckVIDMEM object.
+**
+** INPUT:
+**
+** gckOS Os
+** Pointer to an gckOS object.
+**
+** gctUINT32 BaseAddress
+** Base address for the video memory heap.
+**
+** gctSIZE_T Bytes
+** Number of bytes in the video memory heap.
+**
+** gctSIZE_T Threshold
+** Minimum number of bytes beyond am allocation before the node is
+** split. Can be used as a minimum alignment requirement.
+**
+** gctSIZE_T BankSize
+** Number of bytes per physical memory bank. Used by bank
+** optimization.
+**
+** OUTPUT:
+**
+** gckVIDMEM * Memory
+** Pointer to a variable that will hold the pointer to the gckVIDMEM
+** object.
+*/
+gceSTATUS
+gckVIDMEM_Construct(
+ IN gckOS Os,
+ IN gctUINT32 BaseAddress,
+ IN gctSIZE_T Bytes,
+ IN gctSIZE_T Threshold,
+ IN gctSIZE_T BankSize,
+ OUT gckVIDMEM * Memory
+ )
+{
+ gckVIDMEM memory = gcvNULL;
+ gceSTATUS status;
+ gcuVIDMEM_NODE_PTR node;
+ gctINT i, banks = 0;
+ gctPOINTER pointer = gcvNULL;
+ gctUINT32 heapBytes;
+ gctUINT32 bankSize;
+
+ gcmkHEADER_ARG("Os=0x%x BaseAddress=%08x Bytes=%lu Threshold=%lu "
+ "BankSize=%lu",
+ Os, BaseAddress, Bytes, Threshold, BankSize);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
+ gcmkVERIFY_ARGUMENT(Bytes > 0);
+ gcmkVERIFY_ARGUMENT(Memory != gcvNULL);
+
+ gcmkSAFECASTSIZET(heapBytes, Bytes);
+ gcmkSAFECASTSIZET(bankSize, BankSize);
+
+ /* Allocate the gckVIDMEM object. */
+ gcmkONERROR(gckOS_Allocate(Os, gcmSIZEOF(struct _gckVIDMEM), &pointer));
+ gckOS_ZeroMemory(pointer, gcmSIZEOF(struct _gckVIDMEM));
+
+ memory = pointer;
+
+ /* Initialize the gckVIDMEM object. */
+ memory->object.type = gcvOBJ_VIDMEM;
+ memory->os = Os;
+
+ /* Set video memory heap information. */
+ memory->baseAddress = BaseAddress;
+ memory->bytes = heapBytes;
+ memory->freeBytes = heapBytes;
+ memory->minFreeBytes = heapBytes;
+ memory->threshold = Threshold;
+ memory->mutex = gcvNULL;
+
+ BaseAddress = 0;
+
+ /* Walk all possible banks. */
+ for (i = 0; i < gcmCOUNTOF(memory->sentinel); ++i)
+ {
+ gctUINT32 bytes;
+
+ if (BankSize == 0)
+ {
+ /* Use all bytes for the first bank. */
+ bytes = heapBytes;
+ }
+ else
+ {
+ /* Compute number of bytes for this bank. */
+ bytes = gcmALIGN(BaseAddress + 1, bankSize) - BaseAddress;
+
+ if (bytes > heapBytes)
+ {
+ /* Make sure we don't exceed the total number of bytes. */
+ bytes = heapBytes;
+ }
+ }
+
+ if (bytes == 0)
+ {
+ /* Mark heap is not used. */
+ memory->sentinel[i].VidMem.next =
+ memory->sentinel[i].VidMem.prev =
+ memory->sentinel[i].VidMem.nextFree =
+ memory->sentinel[i].VidMem.prevFree = gcvNULL;
+ continue;
+ }
+
+ /* Allocate one gcuVIDMEM_NODE union. */
+ gcmkONERROR(gckOS_Allocate(Os, gcmSIZEOF(gcuVIDMEM_NODE), &pointer));
+
+ node = pointer;
+
+ /* Initialize gcuVIDMEM_NODE union. */
+ node->VidMem.memory = memory;
+
+ node->VidMem.next =
+ node->VidMem.prev =
+ node->VidMem.nextFree =
+ node->VidMem.prevFree = &memory->sentinel[i];
+
+ node->VidMem.offset = BaseAddress;
+ node->VidMem.bytes = bytes;
+ node->VidMem.alignment = 0;
+ node->VidMem.physical = 0;
+ node->VidMem.pool = gcvPOOL_UNKNOWN;
+
+ node->VidMem.locked = 0;
+
+#ifdef __QNXNTO__
+ node->VidMem.processID = 0;
+ node->VidMem.logical = gcvNULL;
+#endif
+
+#if gcdENABLE_VG
+ node->VidMem.kernelVirtual = gcvNULL;
+#endif
+
+ /* Initialize the linked list of nodes. */
+ memory->sentinel[i].VidMem.next =
+ memory->sentinel[i].VidMem.prev =
+ memory->sentinel[i].VidMem.nextFree =
+ memory->sentinel[i].VidMem.prevFree = node;
+
+ /* Mark sentinel. */
+ memory->sentinel[i].VidMem.bytes = 0;
+
+ /* Adjust address for next bank. */
+ BaseAddress += bytes;
+ heapBytes -= bytes;
+ banks ++;
+ }
+
+ /* Assign all the bank mappings. */
+ memory->mapping[gcvSURF_RENDER_TARGET] = banks - 1;
+ memory->mapping[gcvSURF_BITMAP] = banks - 1;
+ if (banks > 1) --banks;
+ memory->mapping[gcvSURF_DEPTH] = banks - 1;
+ memory->mapping[gcvSURF_HIERARCHICAL_DEPTH] = banks - 1;
+ if (banks > 1) --banks;
+ memory->mapping[gcvSURF_TEXTURE] = banks - 1;
+ if (banks > 1) --banks;
+ memory->mapping[gcvSURF_VERTEX] = banks - 1;
+ if (banks > 1) --banks;
+ memory->mapping[gcvSURF_INDEX] = banks - 1;
+ if (banks > 1) --banks;
+ memory->mapping[gcvSURF_TILE_STATUS] = banks - 1;
+ if (banks > 1) --banks;
+ memory->mapping[gcvSURF_TYPE_UNKNOWN] = 0;
+
+#if gcdENABLE_VG
+ memory->mapping[gcvSURF_IMAGE] = 0;
+ memory->mapping[gcvSURF_MASK] = 0;
+ memory->mapping[gcvSURF_SCISSOR] = 0;
+#endif
+ memory->mapping[gcvSURF_ICACHE] = 0;
+ memory->mapping[gcvSURF_TXDESC] = 0;
+ memory->mapping[gcvSURF_FENCE] = 0;
+ memory->mapping[gcvSURF_TFBHEADER] = 0;
+
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_VIDMEM,
+ "[GALCORE] INDEX: bank %d",
+ memory->mapping[gcvSURF_INDEX]);
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_VIDMEM,
+ "[GALCORE] VERTEX: bank %d",
+ memory->mapping[gcvSURF_VERTEX]);
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_VIDMEM,
+ "[GALCORE] TEXTURE: bank %d",
+ memory->mapping[gcvSURF_TEXTURE]);
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_VIDMEM,
+ "[GALCORE] RENDER_TARGET: bank %d",
+ memory->mapping[gcvSURF_RENDER_TARGET]);
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_VIDMEM,
+ "[GALCORE] DEPTH: bank %d",
+ memory->mapping[gcvSURF_DEPTH]);
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_VIDMEM,
+ "[GALCORE] TILE_STATUS: bank %d",
+ memory->mapping[gcvSURF_TILE_STATUS]);
+
+ /* Allocate the mutex. */
+ gcmkONERROR(gckOS_CreateMutex(Os, &memory->mutex));
+
+ /* Return pointer to the gckVIDMEM object. */
+ *Memory = memory;
+
+ /* Success. */
+ gcmkFOOTER_ARG("*Memory=0x%x", *Memory);
+ return gcvSTATUS_OK;
+
+OnError:
+ /* Roll back. */
+ if (memory != gcvNULL)
+ {
+ if (memory->mutex != gcvNULL)
+ {
+ /* Delete the mutex. */
+ gcmkVERIFY_OK(gckOS_DeleteMutex(Os, memory->mutex));
+ }
+
+ for (i = 0; i < banks; ++i)
+ {
+ /* Free the heap. */
+ gcmkASSERT(memory->sentinel[i].VidMem.next != gcvNULL);
+ gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Os, memory->sentinel[i].VidMem.next));
+ }
+
+ /* Free the object. */
+ gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Os, memory));
+ }
+
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+/*******************************************************************************
+**
+** gckVIDMEM_Destroy
+**
+** Destroy an gckVIDMEM object.
+**
+** INPUT:
+**
+** gckVIDMEM Memory
+** Pointer to an gckVIDMEM object to destroy.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckVIDMEM_Destroy(
+ IN gckVIDMEM Memory
+ )
+{
+ gcuVIDMEM_NODE_PTR node, next;
+ gctINT i;
+
+ gcmkHEADER_ARG("Memory=0x%x", Memory);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Memory, gcvOBJ_VIDMEM);
+
+ /* Walk all sentinels. */
+ for (i = 0; i < gcmCOUNTOF(Memory->sentinel); ++i)
+ {
+ /* Bail out of the heap is not used. */
+ if (Memory->sentinel[i].VidMem.next == gcvNULL)
+ {
+ break;
+ }
+
+ /* Walk all the nodes until we reach the sentinel. */
+ for (node = Memory->sentinel[i].VidMem.next;
+ node->VidMem.bytes != 0;
+ node = next)
+ {
+ /* Save pointer to the next node. */
+ next = node->VidMem.next;
+
+ /* Free the node. */
+ gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Memory->os, node));
+ }
+ }
+
+ /* Free the mutex. */
+ gcmkVERIFY_OK(gckOS_DeleteMutex(Memory->os, Memory->mutex));
+
+ /* Mark the object as unknown. */
+ Memory->object.type = gcvOBJ_UNKNOWN;
+
+ /* Free the gckVIDMEM object. */
+ gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Memory->os, Memory));
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+}
+
+#if gcdENABLE_BANK_ALIGNMENT
+
+#if !gcdBANK_BIT_START
+#error gcdBANK_BIT_START not defined.
+#endif
+
+#if !gcdBANK_BIT_END
+#error gcdBANK_BIT_END not defined.
+#endif
+/*******************************************************************************
+** _GetSurfaceBankAlignment
+**
+** Return the required offset alignment required to the make BaseAddress
+** aligned properly.
+**
+** INPUT:
+**
+** gckOS Os
+** Pointer to gcoOS object.
+**
+** gceSURF_TYPE Type
+** Type of allocation.
+**
+** gctUINT32 BaseAddress
+** Base address of current video memory node.
+**
+** OUTPUT:
+**
+** gctUINT32_PTR AlignmentOffset
+** Pointer to a variable that will hold the number of bytes to skip in
+** the current video memory node in order to make the alignment bank
+** aligned.
+*/
+static gceSTATUS
+_GetSurfaceBankAlignment(
+ IN gckKERNEL Kernel,
+ IN gceSURF_TYPE Type,
+ IN gctUINT32 BaseAddress,
+ OUT gctUINT32_PTR AlignmentOffset
+ )
+{
+ gctUINT32 bank;
+ /* To retrieve the bank. */
+ static const gctUINT32 bankMask = (0xFFFFFFFF << gcdBANK_BIT_START)
+ ^ (0xFFFFFFFF << (gcdBANK_BIT_END + 1));
+
+ /* To retrieve the bank and all the lower bytes. */
+ static const gctUINT32 byteMask = ~(0xFFFFFFFF << (gcdBANK_BIT_END + 1));
+
+ gcmkHEADER_ARG("Type=%d BaseAddress=0x%x ", Type, BaseAddress);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_ARGUMENT(AlignmentOffset != gcvNULL);
+
+ switch (Type)
+ {
+ case gcvSURF_RENDER_TARGET:
+ bank = (BaseAddress & bankMask) >> (gcdBANK_BIT_START);
+
+ /* Align to the first bank. */
+ *AlignmentOffset = (bank == 0) ?
+ 0 :
+ ((1 << (gcdBANK_BIT_END + 1)) + 0) - (BaseAddress & byteMask);
+ break;
+
+ case gcvSURF_DEPTH:
+ bank = (BaseAddress & bankMask) >> (gcdBANK_BIT_START);
+
+ /* Align to the third bank. */
+ *AlignmentOffset = (bank == 2) ?
+ 0 :
+ ((1 << (gcdBANK_BIT_END + 1)) + (2 << gcdBANK_BIT_START)) - (BaseAddress & byteMask);
+
+ /* Minimum 256 byte alignment needed for fast_msaa. */
+ if ((gcdBANK_CHANNEL_BIT > 7) ||
+ ((gckHARDWARE_IsFeatureAvailable(Kernel->hardware, gcvFEATURE_FAST_MSAA) != gcvSTATUS_TRUE) &&
+ (gckHARDWARE_IsFeatureAvailable(Kernel->hardware, gcvFEATURE_SMALL_MSAA) != gcvSTATUS_TRUE)))
+ {
+ /* Add a channel offset at the channel bit. */
+ *AlignmentOffset += (1 << gcdBANK_CHANNEL_BIT);
+ }
+ break;
+
+ default:
+ /* no alignment needed. */
+ *AlignmentOffset = 0;
+ }
+
+ /* Return the status. */
+ gcmkFOOTER_ARG("*AlignmentOffset=%u", *AlignmentOffset);
+ return gcvSTATUS_OK;
+}
+#endif
+
+static gcuVIDMEM_NODE_PTR
+_FindNode(
+ IN gckKERNEL Kernel,
+ IN gckVIDMEM Memory,
+ IN gctINT Bank,
+ IN gctSIZE_T Bytes,
+ IN gceSURF_TYPE Type,
+ IN OUT gctUINT32_PTR Alignment
+ )
+{
+ gcuVIDMEM_NODE_PTR node;
+ gctUINT32 alignment;
+
+#if gcdENABLE_BANK_ALIGNMENT
+ gctUINT32 bankAlignment;
+ gceSTATUS status;
+#endif
+
+ if (Memory->sentinel[Bank].VidMem.nextFree == gcvNULL)
+ {
+ /* No free nodes left. */
+ return gcvNULL;
+ }
+
+#if gcdENABLE_BANK_ALIGNMENT
+ /* Walk all free nodes until we have one that is big enough or we have
+ ** reached the sentinel. */
+ for (node = Memory->sentinel[Bank].VidMem.nextFree;
+ node->VidMem.bytes != 0;
+ node = node->VidMem.nextFree)
+ {
+ if (node->VidMem.bytes < Bytes)
+ {
+ continue;
+ }
+
+ gcmkONERROR(_GetSurfaceBankAlignment(
+ Kernel,
+ Type,
+ node->VidMem.memory->baseAddress + node->VidMem.offset,
+ &bankAlignment));
+
+ bankAlignment = gcmALIGN(bankAlignment, *Alignment);
+
+ /* Compute number of bytes to skip for alignment. */
+ alignment = (*Alignment == 0)
+ ? 0
+ : (*Alignment - (node->VidMem.offset % *Alignment));
+
+ if (alignment == *Alignment)
+ {
+ /* Node is already aligned. */
+ alignment = 0;
+ }
+
+ if (node->VidMem.bytes >= Bytes + alignment + bankAlignment)
+ {
+ /* This node is big enough. */
+ *Alignment = alignment + bankAlignment;
+ return node;
+ }
+ }
+#endif
+
+ /* Walk all free nodes until we have one that is big enough or we have
+ reached the sentinel. */
+ for (node = Memory->sentinel[Bank].VidMem.nextFree;
+ node->VidMem.bytes != 0;
+ node = node->VidMem.nextFree)
+ {
+ gctUINT offset;
+
+ gctINT modulo;
+
+ gcmkSAFECASTSIZET(offset, node->VidMem.offset);
+
+ modulo = gckMATH_ModuloInt(offset, *Alignment);
+
+ /* Compute number of bytes to skip for alignment. */
+ alignment = (*Alignment == 0) ? 0 : (*Alignment - modulo);
+
+ if (alignment == *Alignment)
+ {
+ /* Node is already aligned. */
+ alignment = 0;
+ }
+
+ if (node->VidMem.bytes >= Bytes + alignment)
+ {
+ /* This node is big enough. */
+ *Alignment = alignment;
+ return node;
+ }
+ }
+
+#if gcdENABLE_BANK_ALIGNMENT
+OnError:
+#endif
+ /* Not enough memory. */
+ return gcvNULL;
+}
+
+/*******************************************************************************
+**
+** gckVIDMEM_AllocateLinear
+**
+** Allocate linear memory from the gckVIDMEM object.
+**
+** INPUT:
+**
+** gckVIDMEM Memory
+** Pointer to an gckVIDMEM object.
+**
+** gctSIZE_T Bytes
+** Number of bytes to allocate.
+**
+** gctUINT32 Alignment
+** Byte alignment for allocation.
+**
+** gceSURF_TYPE Type
+** Type of surface to allocate (use by bank optimization).
+**
+** gctBOOL Specified
+** If user must use this pool, it should set Specified to gcvTRUE,
+** otherwise allocator may reserve some memory for other usage, such
+** as small block size allocation request.
+**
+** OUTPUT:
+**
+** gcuVIDMEM_NODE_PTR * Node
+** Pointer to a variable that will hold the allocated memory node.
+*/
+gceSTATUS
+gckVIDMEM_AllocateLinear(
+ IN gckKERNEL Kernel,
+ IN gckVIDMEM Memory,
+ IN gctSIZE_T Bytes,
+ IN gctUINT32 Alignment,
+ IN gceSURF_TYPE Type,
+ IN gctBOOL Specified,
+ OUT gcuVIDMEM_NODE_PTR * Node
+ )
+{
+ gceSTATUS status;
+ gcuVIDMEM_NODE_PTR node;
+ gctUINT32 alignment;
+ gctINT bank, i;
+ gctBOOL acquired = gcvFALSE;
+
+ gcmkHEADER_ARG("Memory=0x%x Bytes=%lu Alignment=%u Type=%d",
+ Memory, Bytes, Alignment, Type);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Memory, gcvOBJ_VIDMEM);
+ gcmkVERIFY_ARGUMENT(Bytes > 0);
+ gcmkVERIFY_ARGUMENT(Node != gcvNULL);
+ gcmkVERIFY_ARGUMENT(Type < gcvSURF_NUM_TYPES);
+
+ /* Acquire the mutex. */
+ gcmkONERROR(gckOS_AcquireMutex(Memory->os, Memory->mutex, gcvINFINITE));
+
+ acquired = gcvTRUE;
+#if defined(__QNXNTO__)
+ if (slogUsageInterval > 0) {
+ static gctSIZE_T lowwaterFPC = ~0;
+ static time_t last_slog_time;
+ int do_slog_now = 0;
+ time_t this_slog_time = time(NULL);
+
+ if (Memory->freeBytes < lowwaterFPC) {
+ do_slog_now = 1;
+ lowwaterFPC = Memory->freeBytes;
+ }
+
+ if (abs(this_slog_time - last_slog_time) > slogUsageInterval) {
+ do_slog_now = 1;
+ }
+
+ if (do_slog_now) {
+ last_slog_time = this_slog_time;
+ slogf(_SLOGC_GRAPHICS_GL, _SLOG_INFO, "%s: Memory->freeBytes = %u, lowest Memory->freeBytes = %u",
+ __FUNCTION__, (unsigned) Memory->freeBytes, (unsigned) lowwaterFPC);
+ }
+ }
+#endif
+ if (Bytes > Memory->freeBytes)
+ {
+ /* Not enough memory. */
+ status = gcvSTATUS_OUT_OF_MEMORY;
+ goto OnError;
+ }
+
+#if gcdSMALL_BLOCK_SIZE
+ if ((Memory->freeBytes < (Memory->bytes/gcdRATIO_FOR_SMALL_MEMORY))
+ && (Bytes >= gcdSMALL_BLOCK_SIZE)
+ && (Specified == gcvFALSE)
+ )
+ {
+ /* The left memory is for small memory.*/
+ status = gcvSTATUS_OUT_OF_MEMORY;
+ goto OnError;
+ }
+#endif
+
+ /* Find the default bank for this surface type. */
+ gcmkASSERT((gctINT) Type < gcmCOUNTOF(Memory->mapping));
+ bank = Memory->mapping[Type];
+ alignment = Alignment;
+
+ /* Find a free node in the default bank. */
+ node = _FindNode(Kernel, Memory, bank, Bytes, Type, &alignment);
+
+ /* Out of memory? */
+ if (node == gcvNULL)
+ {
+ /* Walk all lower banks. */
+ for (i = bank - 1; i >= 0; --i)
+ {
+ /* Find a free node inside the current bank. */
+ node = _FindNode(Kernel, Memory, i, Bytes, Type, &alignment);
+ if (node != gcvNULL)
+ {
+ break;
+ }
+ }
+ }
+
+ if (node == gcvNULL)
+ {
+ /* Walk all upper banks. */
+ for (i = bank + 1; i < gcmCOUNTOF(Memory->sentinel); ++i)
+ {
+ if (Memory->sentinel[i].VidMem.nextFree == gcvNULL)
+ {
+ /* Abort when we reach unused banks. */
+ break;
+ }
+
+ /* Find a free node inside the current bank. */
+ node = _FindNode(Kernel, Memory, i, Bytes, Type, &alignment);
+ if (node != gcvNULL)
+ {
+ break;
+ }
+ }
+ }
+
+ if (node == gcvNULL)
+ {
+ /* Out of memory. */
+ status = gcvSTATUS_OUT_OF_MEMORY;
+ goto OnError;
+ }
+
+ /* Do we have an alignment? */
+ if (alignment > 0)
+ {
+ /* Split the node so it is aligned. */
+ if (_Split(Memory->os, node, alignment))
+ {
+ /* Successful split, move to aligned node. */
+ node = node->VidMem.next;
+
+ /* Remove alignment. */
+ alignment = 0;
+ }
+ }
+
+ /* Do we have enough memory after the allocation to split it? */
+ if (node->VidMem.bytes - Bytes > Memory->threshold)
+ {
+ /* Adjust the node size. */
+ _Split(Memory->os, node, Bytes);
+ }
+
+ /* Remove the node from the free list. */
+ node->VidMem.prevFree->VidMem.nextFree = node->VidMem.nextFree;
+ node->VidMem.nextFree->VidMem.prevFree = node->VidMem.prevFree;
+ node->VidMem.nextFree =
+ node->VidMem.prevFree = gcvNULL;
+
+ /* Fill in the information. */
+ node->VidMem.alignment = alignment;
+ node->VidMem.memory = Memory;
+#ifdef __QNXNTO__
+ node->VidMem.logical = gcvNULL;
+ gcmkONERROR(gckOS_GetProcessID(&node->VidMem.processID));
+#endif
+
+ /* Adjust the number of free bytes. */
+ Memory->freeBytes -= node->VidMem.bytes;
+
+ if (Memory->freeBytes < Memory->minFreeBytes)
+ {
+ Memory->minFreeBytes = Memory->freeBytes;
+ }
+
+#if gcdENABLE_VG
+ node->VidMem.kernelVirtual = gcvNULL;
+#endif
+
+ /* Release the mutex. */
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(Memory->os, Memory->mutex));
+
+ /* Return the pointer to the node. */
+ *Node = node;
+
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_VIDMEM,
+ "Allocated %u bytes @ 0x%x [0x%08X]",
+ node->VidMem.bytes, node, node->VidMem.offset);
+
+ /* Success. */
+ gcmkFOOTER_ARG("*Node=0x%x", *Node);
+ return gcvSTATUS_OK;
+
+OnError:
+ if (acquired)
+ {
+ /* Release the mutex. */
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(Memory->os, Memory->mutex));
+ }
+
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+/*******************************************************************************
+**
+** gckVIDMEM_Free
+**
+** Free an allocated video memory node.
+**
+** INPUT:
+**
+** gckKERNEL Kernel
+** Pointer to an gckKERNEL object.
+**
+** gcuVIDMEM_NODE_PTR Node
+** Pointer to a gcuVIDMEM_NODE object.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckVIDMEM_Free(
+ IN gckKERNEL Kernel,
+ IN gcuVIDMEM_NODE_PTR Node
+ )
+{
+ gceSTATUS status;
+ gckKERNEL kernel = gcvNULL;
+ gckVIDMEM memory = gcvNULL;
+ gcuVIDMEM_NODE_PTR node;
+ gctBOOL mutexAcquired = gcvFALSE;
+
+ gcmkHEADER_ARG("Node=0x%x", Node);
+
+ /* Verify the arguments. */
+ if ((Node == gcvNULL)
+ || (Node->VidMem.memory == gcvNULL)
+ )
+ {
+ /* Invalid object. */
+ gcmkONERROR(gcvSTATUS_INVALID_OBJECT);
+ }
+
+ /**************************** Video Memory ********************************/
+
+ if (Node->VidMem.memory->object.type == gcvOBJ_VIDMEM)
+ {
+ /* Extract pointer to gckVIDMEM object owning the node. */
+ memory = Node->VidMem.memory;
+
+ /* Acquire the mutex. */
+ gcmkONERROR(
+ gckOS_AcquireMutex(memory->os, memory->mutex, gcvINFINITE));
+
+ mutexAcquired = gcvTRUE;
+
+#ifdef __QNXNTO__
+ /* Unmap the video memory. */
+ if (Node->VidMem.logical != gcvNULL)
+ {
+ gckKERNEL_UnmapVideoMemory(
+ Kernel,
+ Node->VidMem.logical,
+ Node->VidMem.processID,
+ Node->VidMem.bytes);
+ Node->VidMem.logical = gcvNULL;
+ }
+
+ /* Reset. */
+ Node->VidMem.processID = 0;
+
+ /* Don't try to re-free an already freed node. */
+ if ((Node->VidMem.nextFree == gcvNULL)
+ && (Node->VidMem.prevFree == gcvNULL)
+ )
+#endif
+ {
+#if gcdENABLE_VG
+ if (Node->VidMem.kernelVirtual)
+ {
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_VIDMEM,
+ "%s(%d) Unmap %x from kernel space.",
+ __FUNCTION__, __LINE__,
+ Node->VidMem.kernelVirtual);
+
+ gcmkVERIFY_OK(
+ gckOS_UnmapPhysical(memory->os,
+ Node->VidMem.kernelVirtual,
+ Node->VidMem.bytes));
+
+ Node->VidMem.kernelVirtual = gcvNULL;
+ }
+#endif
+
+ /* Check if Node is already freed. */
+ if (Node->VidMem.nextFree)
+ {
+ /* Node is alread freed. */
+ gcmkONERROR(gcvSTATUS_INVALID_DATA);
+ }
+
+ /* Update the number of free bytes. */
+ memory->freeBytes += Node->VidMem.bytes;
+
+ /* Find the next free node. */
+ for (node = Node->VidMem.next;
+ node != gcvNULL && node->VidMem.nextFree == gcvNULL;
+ node = node->VidMem.next) ;
+
+ /* Insert this node in the free list. */
+ Node->VidMem.nextFree = node;
+ Node->VidMem.prevFree = node->VidMem.prevFree;
+
+ Node->VidMem.prevFree->VidMem.nextFree =
+ node->VidMem.prevFree = Node;
+
+ /* Is the next node a free node and not the sentinel? */
+ if ((Node->VidMem.next == Node->VidMem.nextFree)
+ && (Node->VidMem.next->VidMem.bytes != 0)
+ )
+ {
+ /* Merge this node with the next node. */
+ gcmkONERROR(_Merge(memory->os, node = Node));
+ gcmkASSERT(node->VidMem.nextFree != node);
+ gcmkASSERT(node->VidMem.prevFree != node);
+ }
+
+ /* Is the previous node a free node and not the sentinel? */
+ if ((Node->VidMem.prev == Node->VidMem.prevFree)
+ && (Node->VidMem.prev->VidMem.bytes != 0)
+ )
+ {
+ /* Merge this node with the previous node. */
+ gcmkONERROR(_Merge(memory->os, node = Node->VidMem.prev));
+ gcmkASSERT(node->VidMem.nextFree != node);
+ gcmkASSERT(node->VidMem.prevFree != node);
+ }
+ }
+
+ /* Release the mutex. */
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(memory->os, memory->mutex));
+
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_VIDMEM,
+ "Node 0x%x is freed.",
+ Node);
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+ }
+
+ /*************************** Virtual Memory *******************************/
+
+ /* Get gckKERNEL object. */
+ kernel = Node->Virtual.kernel;
+
+ /* Verify the gckKERNEL object pointer. */
+ gcmkVERIFY_OBJECT(kernel, gcvOBJ_KERNEL);
+
+#if gcdENABLE_VG
+ if (Node->Virtual.kernelVirtual)
+ {
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_VIDMEM,
+ "%s(%d) Unmap %x from kernel space.",
+ __FUNCTION__, __LINE__,
+ Node->Virtual.kernelVirtual);
+
+ gcmkVERIFY_OK(
+ gckOS_UnmapPhysical(kernel->os,
+ Node->Virtual.kernelVirtual,
+ Node->Virtual.bytes));
+
+ Node->Virtual.kernelVirtual = gcvNULL;
+ }
+#endif
+
+ /* Free the virtual memory. */
+ gcmkVERIFY_OK(gckOS_FreePagedMemory(kernel->os,
+ Node->Virtual.physical,
+ Node->Virtual.bytes));
+
+ /* Destroy the gcuVIDMEM_NODE union. */
+ gcmkVERIFY_OK(gckVIDMEM_DestroyVirtual(Node));
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ if (mutexAcquired)
+ {
+ /* Release the mutex. */
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(
+ memory->os, memory->mutex
+ ));
+ }
+
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+/*map to kernel space*/
+gceSTATUS
+gckVIDMEM_NODE_LockCPU(
+ IN gckKERNEL Kernel,
+ IN gctUINT32 Handle,
+ OUT gctPOINTER * Logical
+ )
+{
+ gceSTATUS status = gcvSTATUS_FALSE;
+ gckVIDMEM_NODE ObjNode = gcvNULL;
+ gcuVIDMEM_NODE_PTR node = gcvNULL;
+ gctPOINTER logical = gcvNULL;
+ gctBOOL acquired = gcvFALSE;
+ gckOS os = Kernel->os;
+
+ gcmkONERROR(gckVIDMEM_HANDLE_LookupAndReference(Kernel, Handle, &ObjNode));
+ node = ObjNode->node;
+ gcmkONERROR(gckOS_AcquireMutex(os, ObjNode->mutex, gcvINFINITE));
+ acquired = gcvTRUE;
+ if (node->VidMem.memory->object.type == gcvOBJ_VIDMEM){
+ gcmkONERROR(
+ gckOS_CreateKernelMapping(os,
+ node->VidMem.memory->physical,
+ node->VidMem.offset,
+ node->VidMem.bytes,
+ &logical));
+ }else{
+ gcmkONERROR(
+ gckOS_CreateKernelMapping(os,
+ node->Virtual.physical,
+ 0,
+ node->Virtual.bytes,
+ &logical));
+ }
+ *Logical = logical;
+ gcmkONERROR(gckVIDMEM_NODE_Dereference(Kernel, ObjNode));
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(os, ObjNode->mutex));
+ return gcvSTATUS_OK;
+OnError:
+ if (acquired)
+ {
+ /* Release the mutex. */
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(os, ObjNode->mutex));
+ }
+
+ /* Return the status. */
+ return status;
+}
+
+gceSTATUS
+gckVIDMEM_NODE_UnlockCPU(
+ IN gckKERNEL Kernel,
+ IN gctUINT32 Handle,
+ OUT gctPOINTER Logical
+ )
+{
+ gceSTATUS status = gcvSTATUS_FALSE;
+ gckVIDMEM_NODE ObjNode = gcvNULL;
+ gcuVIDMEM_NODE_PTR node = gcvNULL;
+ gctBOOL acquired = gcvFALSE;
+ gckOS os = Kernel->os;
+
+ gcmkONERROR(gckVIDMEM_HANDLE_LookupAndReference(Kernel, Handle, &ObjNode));
+ node = ObjNode->node;
+ gcmkONERROR(gckOS_AcquireMutex(os, ObjNode->mutex, gcvINFINITE));
+ acquired = gcvTRUE;
+ if (node->VidMem.memory->object.type == gcvOBJ_VIDMEM){
+ gcmkONERROR(
+ gckOS_DestroyKernelMapping(os,
+ node->VidMem.memory->physical,
+ Logical));
+ }else{
+ gcmkONERROR(
+ gckOS_DestroyKernelMapping(os,
+ node->Virtual.physical,
+ Logical));
+ }
+ gcmkONERROR(gckVIDMEM_NODE_Dereference(Kernel, ObjNode));
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(os, ObjNode->mutex));
+ return gcvSTATUS_OK;
+OnError:
+ if (acquired)
+ {
+ /* Release the mutex. */
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(os, ObjNode->mutex));
+ }
+ /* Return the status. */
+ return status;
+}
+
+
+#if !gcdPROCESS_ADDRESS_SPACE
+/*******************************************************************************
+**
+** _NeedVirtualMapping
+**
+** Whether setup GPU page table for video node.
+**
+** INPUT:
+** gckKERNEL Kernel
+** Pointer to an gckKERNEL object.
+**
+** gcuVIDMEM_NODE_PTR Node
+** Pointer to a gcuVIDMEM_NODE union.
+**
+** gceCORE Core
+** Id of current GPU.
+**
+** OUTPUT:
+** gctBOOL * NeedMapping
+** A pointer hold the result whether Node should be mapping.
+*/
+static gceSTATUS
+_NeedVirtualMapping(
+ IN gckKERNEL Kernel,
+ IN gceCORE Core,
+ IN gcuVIDMEM_NODE_PTR Node,
+ OUT gctBOOL * NeedMapping
+)
+{
+ gceSTATUS status;
+ gctPHYS_ADDR_T phys;
+ gctUINT32 address;
+ gctUINT32 end;
+ gcePOOL pool;
+ gctUINT32 offset;
+ gctUINT32 bytes;
+
+ gcmkHEADER_ARG("Node=0x%X", Node);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_ARGUMENT(Kernel != gcvNULL);
+ gcmkVERIFY_ARGUMENT(Node != gcvNULL);
+ gcmkVERIFY_ARGUMENT(NeedMapping != gcvNULL);
+ gcmkVERIFY_ARGUMENT(Core < gcdMAX_GPU_COUNT);
+
+ if (Node->Virtual.contiguous)
+ {
+#if gcdENABLE_VG
+ if (Core == gcvCORE_VG)
+ {
+ *NeedMapping = gcvFALSE;
+ }
+ else
+#endif
+ if (Node->Virtual.secure)
+ {
+ *NeedMapping = gcvTRUE;
+ }
+ else
+ {
+ /* Convert logical address into a physical address. */
+ gcmkONERROR(gckOS_UserLogicalToPhysical(
+ Kernel->os, Node->Virtual.logical, &phys
+ ));
+
+ if (phys > gcvMAXUINT32)
+ {
+ *NeedMapping = gcvTRUE;
+ }
+ else
+ {
+ gcmkSAFECASTPHYSADDRT(address, phys);
+
+ if (!gckHARDWARE_IsFeatureAvailable(Kernel->hardware, gcvFEATURE_MMU))
+ {
+ gcmkASSERT(address >= Kernel->hardware->baseAddress);
+
+ /* Subtract baseAddress to get a GPU address used for programming. */
+ address -= Kernel->hardware->baseAddress;
+
+ /* If part of region is belong to gcvPOOL_VIRTUAL,
+ ** whole region has to be mapped. */
+ gcmkSAFECASTSIZET(bytes, Node->Virtual.bytes);
+ end = address + bytes - 1;
+
+ gcmkONERROR(gckHARDWARE_SplitMemory(
+ Kernel->hardware, end, &pool, &offset
+ ));
+
+ *NeedMapping = (pool == gcvPOOL_VIRTUAL);
+ }
+ else
+ {
+ gctBOOL flatMapped;
+
+ gcmkONERROR(gckMMU_IsFlatMapped(Kernel->mmu, address, &flatMapped));
+
+ *NeedMapping = !flatMapped;
+ }
+ }
+ }
+ }
+ else
+ {
+ *NeedMapping = gcvTRUE;
+ }
+
+ gcmkFOOTER_ARG("*NeedMapping=%d", *NeedMapping);
+ return gcvSTATUS_OK;
+
+OnError:
+ gcmkFOOTER();
+ return status;
+}
+#endif
+
+#if gcdPROCESS_ADDRESS_SPACE
+gcsGPU_MAP_PTR
+_FindGPUMap(
+ IN gcsGPU_MAP_PTR Head,
+ IN gctINT ProcessID
+ )
+{
+ gcsGPU_MAP_PTR map = Head;
+
+ while (map)
+ {
+ if (map->pid == ProcessID)
+ {
+ return map;
+ }
+
+ map = map->next;
+ }
+
+ return gcvNULL;
+}
+
+gcsGPU_MAP_PTR
+_CreateGPUMap(
+ IN gckOS Os,
+ IN gcsGPU_MAP_PTR *Head,
+ IN gcsGPU_MAP_PTR *Tail,
+ IN gctINT ProcessID
+ )
+{
+ gcsGPU_MAP_PTR gpuMap;
+ gctPOINTER pointer = gcvNULL;
+
+ gckOS_Allocate(Os, sizeof(gcsGPU_MAP), &pointer);
+
+ if (pointer == gcvNULL)
+ {
+ return gcvNULL;
+ }
+
+ gpuMap = pointer;
+
+ gckOS_ZeroMemory(pointer, sizeof(gcsGPU_MAP));
+
+ gpuMap->pid = ProcessID;
+
+ if (!*Head)
+ {
+ *Head = *Tail = gpuMap;
+ }
+ else
+ {
+ gpuMap->prev = *Tail;
+ (*Tail)->next = gpuMap;
+ *Tail = gpuMap;
+ }
+
+ return gpuMap;
+}
+
+void
+_DestroyGPUMap(
+ IN gckOS Os,
+ IN gcsGPU_MAP_PTR *Head,
+ IN gcsGPU_MAP_PTR *Tail,
+ IN gcsGPU_MAP_PTR gpuMap
+ )
+{
+
+ if (gpuMap == *Head)
+ {
+ if ((*Head = gpuMap->next) == gcvNULL)
+ {
+ *Tail = gcvNULL;
+ }
+ }
+ else
+ {
+ gpuMap->prev->next = gpuMap->next;
+ if (gpuMap == *Tail)
+ {
+ *Tail = gpuMap->prev;
+ }
+ else
+ {
+ gpuMap->next->prev = gpuMap->prev;
+ }
+ }
+
+ gcmkOS_SAFE_FREE(Os, gpuMap);
+}
+#endif
+
+/*******************************************************************************
+**
+** gckVIDMEM_Lock
+**
+** Lock a video memory node and return its hardware specific address.
+**
+** INPUT:
+**
+** gckKERNEL Kernel
+** Pointer to an gckKERNEL object.
+**
+** gcuVIDMEM_NODE_PTR Node
+** Pointer to a gcuVIDMEM_NODE union.
+**
+** OUTPUT:
+**
+** gctUINT32 * Address
+** Pointer to a variable that will hold the hardware specific address.
+**
+** gctUINT32 * PhysicalAddress
+** Pointer to a variable that will hold the bus address of a contiguous
+** video node.
+*/
+gceSTATUS
+gckVIDMEM_Lock(
+ IN gckKERNEL Kernel,
+ IN gckVIDMEM_NODE Node,
+ IN gctBOOL Cacheable,
+ OUT gctUINT32 * Address,
+ OUT gctUINT32 * Gid,
+ OUT gctUINT64 * PhysicalAddress
+ )
+{
+ gceSTATUS status;
+ gctBOOL acquired = gcvFALSE;
+ gctBOOL locked = gcvFALSE;
+ gckOS os = gcvNULL;
+#if !gcdPROCESS_ADDRESS_SPACE
+ gctBOOL needMapping = gcvFALSE;
+#endif
+ gctUINT64 physicalAddress = ~0ULL;
+ gcuVIDMEM_NODE_PTR node = Node->node;
+ gctSIZE_T pageSize;
+ gctUINT32 pageMask;
+
+ gcmkHEADER_ARG("Node=0x%x", Node);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_ARGUMENT(Address != gcvNULL);
+ gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
+
+ /* Extract the gckOS object pointer. */
+ os = Kernel->os;
+ gcmkVERIFY_OBJECT(os, gcvOBJ_OS);
+
+ if ((node == gcvNULL)
+ || (node->VidMem.memory == gcvNULL)
+ )
+ {
+ /* Invalid object. */
+ gcmkONERROR(gcvSTATUS_INVALID_OBJECT);
+ }
+
+ /* Grab the mutex. */
+ gcmkONERROR(gckOS_AcquireMutex(os, Node->mutex, gcvINFINITE));
+ acquired = gcvTRUE;
+
+ /**************************** Video Memory ********************************/
+
+ if (node->VidMem.memory->object.type == gcvOBJ_VIDMEM)
+ {
+ gctUINT32 offset;
+
+ if (Cacheable == gcvTRUE)
+ {
+ gcmkONERROR(gcvSTATUS_INVALID_REQUEST);
+ }
+
+ /* Increment the lock count. */
+ node->VidMem.locked ++;
+
+ gcmkSAFECASTSIZET(offset, node->VidMem.offset);
+ physicalAddress = node->VidMem.memory->baseAddress
+ + offset
+ + node->VidMem.alignment;
+
+ if (node->VidMem.pool == gcvPOOL_LOCAL_EXTERNAL)
+ {
+ *Address = Kernel->externalBaseAddress + offset;
+ }
+ else
+ {
+ gcmkASSERT(node->VidMem.pool == gcvPOOL_SYSTEM);
+ *Address = Kernel->contiguousBaseAddress + offset;
+ }
+
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_VIDMEM,
+ "Locked node 0x%x (%d) @ 0x%08X",
+ node,
+ node->VidMem.locked,
+ *Address);
+ }
+
+ /*************************** Virtual Memory *******************************/
+
+ else
+ {
+
+ *Gid = node->Virtual.gid;
+
+#if gcdPAGED_MEMORY_CACHEABLE
+ /* Force video memory cacheable. */
+ Cacheable = gcvTRUE;
+#endif
+
+ gcmkONERROR(
+ gckOS_LockPages(os,
+ node->Virtual.physical,
+ node->Virtual.bytes,
+ Cacheable,
+ &node->Virtual.logical,
+ &node->Virtual.pageCount));
+
+ gcmkONERROR(gckOS_UserLogicalToPhysical(
+ os,
+ node->Virtual.logical,
+ &physicalAddress
+ ));
+
+#if gcdENABLE_VG
+ node->Virtual.physicalAddress = physicalAddress;
+#endif
+
+#if !gcdPROCESS_ADDRESS_SPACE
+ /* Increment the lock count. */
+ if (node->Virtual.lockeds[Kernel->core] ++ == 0)
+ {
+ locked = gcvTRUE;
+
+ gcmkONERROR(_NeedVirtualMapping(Kernel, Kernel->core, node, &needMapping));
+
+ if (needMapping == gcvFALSE)
+ {
+ /* Get hardware specific address. */
+#if gcdENABLE_VG
+ if (Kernel->vg != gcvNULL)
+ {
+ gcmkONERROR(gckVGHARDWARE_ConvertLogical(
+ Kernel->vg->hardware,
+ node->Virtual.logical,
+ gcvTRUE,
+ &node->Virtual.addresses[Kernel->core]));
+ }
+ else
+#endif
+ {
+ gcmkONERROR(gckHARDWARE_ConvertLogical(
+ Kernel->hardware,
+ node->Virtual.logical,
+ gcvTRUE,
+ &node->Virtual.addresses[Kernel->core]));
+ }
+ }
+ else
+ {
+#if gcdSECURITY
+ gctPHYS_ADDR physicalArrayPhysical;
+ gctPOINTER physicalArrayLogical;
+
+ gcmkONERROR(gckOS_AllocatePageArray(
+ os,
+ node->Virtual.physical,
+ node->Virtual.pageCount,
+ &physicalArrayLogical,
+ &physicalArrayPhysical
+ ));
+
+ gcmkONERROR(gckKERNEL_SecurityMapMemory(
+ Kernel,
+ physicalArrayLogical,
+ node->Virtual.pageCount,
+ &node->Virtual.addresses[Kernel->core]
+ ));
+
+ gcmkONERROR(gckOS_FreeNonPagedMemory(
+ os,
+ 1,
+ physicalArrayPhysical,
+ physicalArrayLogical
+ ));
+#else
+#if gcdENABLE_VG
+ if (Kernel->vg != gcvNULL)
+ {
+ /* Allocate pages inside the MMU. */
+ gcmkONERROR(
+ gckVGMMU_AllocatePages(Kernel->vg->mmu,
+ node->Virtual.pageCount,
+ &node->Virtual.pageTables[Kernel->core],
+ &node->Virtual.addresses[Kernel->core]));
+ }
+ else
+#endif
+ {
+ /* Allocate pages inside the MMU. */
+ gcmkONERROR(
+ gckMMU_AllocatePagesEx(Kernel->mmu,
+ node->Virtual.pageCount,
+ node->Virtual.type,
+ node->Virtual.secure,
+ &node->Virtual.pageTables[Kernel->core],
+ &node->Virtual.addresses[Kernel->core]));
+ }
+
+ if (node->Virtual.onFault != gcvTRUE)
+ {
+#if gcdENABLE_TRUST_APPLICATION
+#if gcdENABLE_VG
+ if (Kernel->core != gcvCORE_VG && Kernel->hardware->options.secureMode == gcvSECURE_IN_TA)
+#else
+ if (Kernel->hardware->options.secureMode == gcvSECURE_IN_TA)
+#endif
+ {
+ gcmkONERROR(gckKERNEL_MapInTrustApplicaiton(
+ Kernel,
+ node->Virtual.logical,
+ node->Virtual.physical,
+ node->Virtual.addresses[Kernel->core],
+ node->Virtual.pageCount
+ ));
+ }
+ else
+#endif
+ {
+ /* Map the pages. */
+ gcmkONERROR(gckOS_MapPagesEx(os,
+ Kernel->core,
+ node->Virtual.physical,
+ node->Virtual.pageCount,
+ node->Virtual.addresses[Kernel->core],
+ node->Virtual.pageTables[Kernel->core],
+ gcvTRUE,
+ node->Virtual.type));
+ }
+ }
+
+#if gcdENABLE_VG
+ if (Kernel->core == gcvCORE_VG)
+ {
+ gcmkONERROR(gckVGMMU_Flush(Kernel->vg->mmu));
+ }
+ else
+#endif
+ {
+ gcmkONERROR(gckMMU_Flush(Kernel->mmu, node->Virtual.type));
+ }
+#endif
+ }
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_VIDMEM,
+ "Mapped virtual node 0x%x to 0x%08X",
+ node,
+ node->Virtual.addresses[Kernel->core]);
+ }
+
+ /* Return hardware address. */
+ *Address = node->Virtual.addresses[Kernel->core];
+
+ if (needMapping == gcvTRUE)
+ {
+
+#if gcdENABLE_VG
+ if (Kernel->core == gcvCORE_VG)
+ {
+ gcmkVERIFY_OK(gckOS_GetPageSize(os, &pageSize));
+ }
+ else
+#endif
+ {
+ pageSize = Kernel->command->pageSize;
+ }
+
+ pageMask = (gctUINT32)pageSize - 1;
+
+ *Address += (gctUINT32)physicalAddress & pageMask;
+
+ /* Need mark invalid address for virtual memory */
+ if (node->Virtual.contiguous == gcvFALSE)
+ {
+ physicalAddress = gcvINVALID_ADDRESS;
+ }
+ }
+#endif
+ }
+
+ /* Release the mutex. */
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(os, Node->mutex));
+
+ *PhysicalAddress = (gctUINT64)physicalAddress;
+
+ /* Success. */
+ gcmkFOOTER_ARG("*Address=%08x", *Address);
+ return gcvSTATUS_OK;
+
+OnError:
+ if (locked)
+ {
+ if (node->Virtual.pageTables[Kernel->core] != gcvNULL)
+ {
+#if gcdENABLE_VG
+ if (Kernel->vg != gcvNULL)
+ {
+ /* Free the pages from the MMU. */
+ gcmkVERIFY_OK(
+ gckVGMMU_FreePages(Kernel->vg->mmu,
+ node->Virtual.pageTables[Kernel->core],
+ node->Virtual.pageCount));
+ }
+ else
+#endif
+ {
+ /* Free the pages from the MMU. */
+ gcmkVERIFY_OK(
+ gckMMU_FreePages(Kernel->mmu,
+ node->Virtual.secure,
+ node->Virtual.addresses[Kernel->core],
+ node->Virtual.pageTables[Kernel->core],
+ node->Virtual.pageCount));
+ }
+ node->Virtual.pageTables[Kernel->core] = gcvNULL;
+ }
+
+ /* Unlock the pages. */
+ gcmkVERIFY_OK(
+ gckOS_UnlockPages(os,
+ node->Virtual.physical,
+ node->Virtual.bytes,
+ node->Virtual.logical
+ ));
+
+ node->Virtual.lockeds[Kernel->core]--;
+ }
+
+ if (acquired)
+ {
+ /* Release the mutex. */
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(os, Node->mutex));
+ }
+
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+/*******************************************************************************
+**
+** gckVIDMEM_Unlock
+**
+** Unlock a video memory node.
+**
+** INPUT:
+**
+** gckKERNEL Kernel
+** Pointer to an gckKERNEL object.
+**
+** gcuVIDMEM_NODE_PTR Node
+** Pointer to a locked gcuVIDMEM_NODE union.
+**
+** gceSURF_TYPE Type
+** Type of surface to unlock.
+**
+** gctBOOL * Asynchroneous
+** Pointer to a variable specifying whether the surface should be
+** unlocked asynchroneously or not.
+**
+** OUTPUT:
+**
+** gctBOOL * Asynchroneous
+** Pointer to a variable receiving the number of bytes used in the
+** command buffer specified by 'Commands'. If gcvNULL, there is no
+** command buffer.
+*/
+gceSTATUS
+gckVIDMEM_Unlock(
+ IN gckKERNEL Kernel,
+ IN gckVIDMEM_NODE Node,
+ IN gceSURF_TYPE Type,
+ IN OUT gctBOOL * Asynchroneous
+ )
+{
+ gceSTATUS status;
+ gckOS os = gcvNULL;
+ gctBOOL acquired = gcvFALSE;
+ gcuVIDMEM_NODE_PTR node = Node->node;
+
+ gcmkHEADER_ARG("Node=0x%x Type=%d *Asynchroneous=%d",
+ Node, Type, gcmOPT_VALUE(Asynchroneous));
+
+ gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
+
+ /* Get the gckOS object pointer. */
+ os = Kernel->os;
+ gcmkVERIFY_OBJECT(os, gcvOBJ_OS);
+
+ /* Verify the arguments. */
+ if ((node == gcvNULL)
+ || (node->VidMem.memory == gcvNULL)
+ )
+ {
+ /* Invalid object. */
+ gcmkONERROR(gcvSTATUS_INVALID_OBJECT);
+ }
+
+ /* Grab the mutex. */
+ gcmkONERROR(gckOS_AcquireMutex(os, Node->mutex, gcvINFINITE));
+ acquired = gcvTRUE;
+
+ /**************************** Video Memory ********************************/
+
+ if (node->VidMem.memory->object.type == gcvOBJ_VIDMEM)
+ {
+ if (node->VidMem.locked <= 0)
+ {
+ /* The surface was not locked. */
+ status = gcvSTATUS_MEMORY_UNLOCKED;
+ goto OnError;
+ }
+
+ if (Asynchroneous != gcvNULL)
+ {
+ /* Schedule an event to sync with GPU. */
+ *Asynchroneous = gcvTRUE;
+ }
+ else
+ {
+ /* Decrement the lock count. */
+ node->VidMem.locked --;
+ }
+
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_VIDMEM,
+ "Unlocked node 0x%x (%d)",
+ node,
+ node->VidMem.locked);
+ }
+
+ /*************************** Virtual Memory *******************************/
+
+ else
+ {
+
+
+ if (Asynchroneous == gcvNULL)
+ {
+#if !gcdPROCESS_ADDRESS_SPACE
+ if (node->Virtual.lockeds[Kernel->core] == 0)
+ {
+ status = gcvSTATUS_MEMORY_UNLOCKED;
+ goto OnError;
+ }
+
+ /* Decrement lock count. */
+ -- node->Virtual.lockeds[Kernel->core];
+
+ /* See if we can unlock the resources. */
+ if (node->Virtual.lockeds[Kernel->core] == 0)
+ {
+#if gcdSECURITY
+ if (node->Virtual.addresses[Kernel->core] > 0x80000000)
+ {
+ gcmkONERROR(gckKERNEL_SecurityUnmapMemory(
+ Kernel,
+ node->Virtual.addresses[Kernel->core],
+ node->Virtual.pageCount
+ ));
+ }
+#else
+ /* Free the page table. */
+ if (node->Virtual.pageTables[Kernel->core] != gcvNULL)
+ {
+#if gcdENABLE_VG
+ if (Kernel->vg != gcvNULL)
+ {
+ gcmkONERROR(
+ gckVGMMU_FreePages(Kernel->vg->mmu,
+ node->Virtual.pageTables[Kernel->core],
+ node->Virtual.pageCount));
+ }
+ else
+#endif
+ {
+ gcmkONERROR(
+ gckMMU_FreePages(Kernel->mmu,
+ node->Virtual.secure,
+ node->Virtual.addresses[Kernel->core],
+ node->Virtual.pageTables[Kernel->core],
+ node->Virtual.pageCount));
+ }
+
+ gcmkONERROR(gckOS_UnmapPages(
+ Kernel->os,
+ node->Virtual.pageCount,
+ node->Virtual.addresses[Kernel->core]
+ ));
+
+ /* Mark page table as freed. */
+ node->Virtual.pageTables[Kernel->core] = gcvNULL;
+ }
+#endif
+ }
+
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_VIDMEM,
+ "Unmapped virtual node 0x%x from 0x%08X",
+ node, node->Virtual.addresses[Kernel->core]);
+#endif
+
+ }
+
+ else
+ {
+ gcmkONERROR(
+ gckOS_UnlockPages(os,
+ node->Virtual.physical,
+ node->Virtual.bytes,
+ node->Virtual.logical));
+
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_VIDMEM,
+ "Scheduled unlock for virtual node 0x%x",
+ node);
+
+ /* Schedule the surface to be unlocked. */
+ *Asynchroneous = gcvTRUE;
+ }
+ }
+
+ /* Release the mutex. */
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(os, Node->mutex));
+ acquired = gcvFALSE;
+
+ /* Success. */
+ gcmkFOOTER_ARG("*Asynchroneous=%d", gcmOPT_VALUE(Asynchroneous));
+ return gcvSTATUS_OK;
+
+OnError:
+ if (acquired)
+ {
+ /* Release the mutex. */
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(os, Node->mutex));
+ }
+
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+#if gcdPROCESS_ADDRESS_SPACE
+gceSTATUS
+gckVIDMEM_Node_Lock(
+ IN gckKERNEL Kernel,
+ IN gckVIDMEM_NODE Node,
+ OUT gctUINT32 *Address
+ )
+{
+ gceSTATUS status;
+ gckOS os;
+ gcuVIDMEM_NODE_PTR node = Node->node;
+ gcsGPU_MAP_PTR gpuMap;
+ gctPHYS_ADDR physical = gcvNULL;
+ gctUINT32 phys = gcvINVALID_ADDRESS;
+ gctUINT32 processID;
+ gcsLOCK_INFO_PTR lockInfo;
+ gctUINT32 pageCount;
+ gckMMU mmu;
+ gctUINT32 i;
+ gctUINT32_PTR pageTableEntry;
+ gctUINT32 offset = 0;
+ gctBOOL acquired = gcvFALSE;
+
+ gcmkHEADER_ARG("Node = %x", Node);
+
+ gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
+ gcmkVERIFY_ARGUMENT(Node != gcvNULL);
+ gcmkVERIFY_ARGUMENT(Address != gcvNULL);
+
+ os = Kernel->os;
+ gcmkVERIFY_OBJECT(os, gcvOBJ_OS);
+
+ gcmkONERROR(gckOS_GetProcessID(&processID));
+
+ gcmkONERROR(gckKERNEL_GetProcessMMU(Kernel, &mmu));
+
+ gcmkONERROR(gckOS_AcquireMutex(os, Node->mapMutex, gcvINFINITE));
+ acquired = gcvTRUE;
+
+ /* Get map information for current process. */
+ gpuMap = _FindGPUMap(Node->mapHead, processID);
+
+ if (gpuMap == gcvNULL)
+ {
+ gpuMap = _CreateGPUMap(os, &Node->mapHead, &Node->mapTail, processID);
+
+ if (gpuMap == gcvNULL)
+ {
+ gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
+ }
+ }
+
+ lockInfo = &gpuMap->lockInfo;
+
+ if (lockInfo->lockeds[Kernel->core] ++ == 0)
+ {
+ /* Get necessary information. */
+ if (node->VidMem.memory->object.type == gcvOBJ_VIDMEM)
+ {
+ phys = node->VidMem.memory->baseAddress
+ + node->VidMem.offset
+ + node->VidMem.alignment;
+
+ /* GPU page table use 4K page. */
+ pageCount = ((phys + node->VidMem.bytes + 4096 - 1) >> 12)
+ - (phys >> 12);
+
+ offset = phys & 0xFFF;
+ }
+ else
+ {
+ pageCount = node->Virtual.pageCount;
+ physical = node->Virtual.physical;
+ }
+
+ /* Allocate pages inside the MMU. */
+ gcmkONERROR(gckMMU_AllocatePages(
+ mmu,
+ pageCount,
+ &lockInfo->pageTables[Kernel->core],
+ &lockInfo->GPUAddresses[Kernel->core]));
+
+ /* Record MMU from which pages are allocated. */
+ lockInfo->lockMmus[Kernel->core] = mmu;
+
+ pageTableEntry = lockInfo->pageTables[Kernel->core];
+
+ /* Fill page table entries. */
+ if (phys != gcvINVALID_ADDRESS)
+ {
+ gctUINT32 address = lockInfo->GPUAddresses[Kernel->core];
+ for (i = 0; i < pageCount; i++)
+ {
+ gckMMU_GetPageEntry(mmu, address, &pageTableEntry);
+ gckMMU_SetPage(mmu, phys & 0xFFFFF000, pageTableEntry);
+ phys += 4096;
+ address += 4096;
+ pageTableEntry += 1;
+ }
+ }
+ else
+ {
+ gctUINT32 address = lockInfo->GPUAddresses[Kernel->core];
+ gcmkASSERT(physical != gcvNULL);
+ gcmkONERROR(gckOS_MapPagesEx(os,
+ Kernel->core,
+ physical,
+ pageCount,
+ address,
+ pageTableEntry));
+ }
+
+ gcmkONERROR(gckMMU_Flush(mmu, Node->type));
+ }
+
+ *Address = lockInfo->GPUAddresses[Kernel->core] + offset;
+
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(os, Node->mapMutex));
+ acquired = gcvFALSE;
+
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ if (acquired)
+ {
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(os, Node->mapMutex));
+ }
+
+ gcmkFOOTER();
+ return status;
+}
+
+gceSTATUS
+gckVIDMEM_NODE_Unlock(
+ IN gckKERNEL Kernel,
+ IN gckVIDMEM_NODE Node,
+ IN gctUINT32 ProcessID
+ )
+{
+ gceSTATUS status;
+ gcsGPU_MAP_PTR gpuMap;
+ gcsLOCK_INFO_PTR lockInfo;
+ gckMMU mmu;
+ gcuVIDMEM_NODE_PTR node;
+ gctUINT32 pageCount;
+ gctBOOL acquired = gcvFALSE;
+
+ gcmkHEADER_ARG("Kernel=0x%08X, Node = %x, ProcessID=%d",
+ Kernel, Node, ProcessID);
+
+ gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
+ gcmkVERIFY_ARGUMENT(Node != gcvNULL);
+
+ gcmkONERROR(gckOS_AcquireMutex(Kernel->os, Node->mapMutex, gcvINFINITE));
+ acquired = gcvTRUE;
+
+ /* Get map information for current process. */
+ gpuMap = _FindGPUMap(Node->mapHead, ProcessID);
+
+ if (gpuMap == gcvNULL)
+ {
+ /* No mapping for this process. */
+ gcmkONERROR(gcvSTATUS_INVALID_DATA);
+ }
+
+ lockInfo = &gpuMap->lockInfo;
+
+ if (--lockInfo->lockeds[Kernel->core] == 0)
+ {
+ node = Node->node;
+
+ /* Get necessary information. */
+ if (node->VidMem.memory->object.type == gcvOBJ_VIDMEM)
+ {
+ gctUINT32 phys = node->VidMem.memory->baseAddress
+ + node->VidMem.offset
+ + node->VidMem.alignment;
+
+ /* GPU page table use 4K page. */
+ pageCount = ((phys + node->VidMem.bytes + 4096 - 1) >> 12)
+ - (phys >> 12);
+ }
+ else
+ {
+ pageCount = node->Virtual.pageCount;
+ }
+
+ /* Get MMU which allocates pages. */
+ mmu = lockInfo->lockMmus[Kernel->core];
+
+ /* Free virtual spaces in page table. */
+ gcmkVERIFY_OK(gckMMU_FreePagesEx(
+ mmu,
+ lockInfo->GPUAddresses[Kernel->core],
+ pageCount
+ ));
+
+ _DestroyGPUMap(Kernel->os, &Node->mapHead, &Node->mapTail, gpuMap);
+ }
+
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, Node->mapMutex));
+ acquired = gcvFALSE;
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ if (acquired)
+ {
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, Node->mapMutex));
+ }
+
+ gcmkFOOTER();
+ return status;
+}
+#endif
+
+/*******************************************************************************
+**
+** gckVIDMEM_HANDLE_Allocate
+**
+** Allocate a handle for a gckVIDMEM_NODE object.
+**
+** INPUT:
+**
+** gckKERNEL Kernel
+** Pointer to an gckKERNEL object.
+**
+** gckVIDMEM_NODE Node
+** Pointer to a gckVIDMEM_NODE object.
+**
+** OUTPUT:
+**
+** gctUINT32 * Handle
+** Pointer to a variable receiving a handle represent this
+** gckVIDMEM_NODE in userspace.
+*/
+gceSTATUS
+gckVIDMEM_HANDLE_Allocate(
+ IN gckKERNEL Kernel,
+ IN gckVIDMEM_NODE Node,
+ OUT gctUINT32 * Handle
+ )
+{
+ gceSTATUS status;
+ gctUINT32 processID = 0;
+ gctPOINTER pointer = gcvNULL;
+ gctPOINTER handleDatabase = gcvNULL;
+ gctPOINTER mutex = gcvNULL;
+ gctUINT32 handle = 0;
+ gckVIDMEM_HANDLE handleObject = gcvNULL;
+ gckOS os = Kernel->os;
+
+ gcmkHEADER_ARG("Kernel=0x%X, Node=0x%X", Kernel, Node);
+
+ gcmkVERIFY_OBJECT(os, gcvOBJ_OS);
+
+ /* Allocate a gckVIDMEM_HANDLE object. */
+ gcmkONERROR(gckOS_Allocate(os, gcmSIZEOF(gcsVIDMEM_HANDLE), &pointer));
+
+ gcmkVERIFY_OK(gckOS_ZeroMemory(pointer, gcmSIZEOF(gcsVIDMEM_HANDLE)));
+
+ handleObject = pointer;
+
+ gcmkONERROR(gckOS_AtomConstruct(os, &handleObject->reference));
+
+ /* Set default reference count to 1. */
+ gckOS_AtomSet(os, handleObject->reference, 1);
+
+ gcmkVERIFY_OK(gckOS_GetProcessID(&processID));
+
+ gcmkONERROR(
+ gckKERNEL_FindHandleDatbase(Kernel,
+ processID,
+ &handleDatabase,
+ &mutex));
+
+ /* Allocate a handle for this object. */
+ gcmkONERROR(
+ gckKERNEL_AllocateIntegerId(handleDatabase, handleObject, &handle));
+
+ handleObject->node = Node;
+ handleObject->handle = handle;
+
+ *Handle = handle;
+
+ gcmkFOOTER_ARG("*Handle=%d", *Handle);
+ return gcvSTATUS_OK;
+
+OnError:
+ if (handleObject != gcvNULL)
+ {
+ if (handleObject->reference != gcvNULL)
+ {
+ gcmkVERIFY_OK(gckOS_AtomDestroy(os, handleObject->reference));
+ }
+
+ gcmkVERIFY_OK(gcmkOS_SAFE_FREE(os, handleObject));
+ }
+
+ gcmkFOOTER();
+ return status;
+}
+
+gceSTATUS
+gckVIDMEM_NODE_Reference(
+ IN gckKERNEL Kernel,
+ IN gckVIDMEM_NODE Node
+ )
+{
+ gctINT32 oldValue;
+ gcmkHEADER_ARG("Kernel=0x%X Node=0x%X", Kernel, Node);
+
+ gckOS_AtomIncrement(Kernel->os, Node->reference, &oldValue);
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+}
+
+gceSTATUS
+gckVIDMEM_HANDLE_Reference(
+ IN gckKERNEL Kernel,
+ IN gctUINT32 ProcessID,
+ IN gctUINT32 Handle
+ )
+{
+ gceSTATUS status;
+ gckVIDMEM_HANDLE handleObject = gcvNULL;
+ gctPOINTER database = gcvNULL;
+ gctPOINTER mutex = gcvNULL;
+ gctINT32 oldValue = 0;
+ gctBOOL acquired = gcvFALSE;
+
+ gcmkHEADER_ARG("Handle=%d PrcoessID=%d", Handle, ProcessID);
+
+ gcmkONERROR(
+ gckKERNEL_FindHandleDatbase(Kernel, ProcessID, &database, &mutex));
+
+ gcmkVERIFY_OK(gckOS_AcquireMutex(Kernel->os, mutex, gcvINFINITE));
+ acquired = gcvTRUE;
+
+ /* Translate handle to gckVIDMEM_HANDLE object. */
+ gcmkONERROR(
+ gckKERNEL_QueryIntegerId(database, Handle, (gctPOINTER *)&handleObject));
+
+ /* Increase the reference count. */
+ gckOS_AtomIncrement(Kernel->os, handleObject->reference, &oldValue);
+
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, mutex));
+ acquired = gcvFALSE;
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ if (acquired)
+ {
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, mutex));
+ }
+
+ gcmkFOOTER();
+ return status;
+}
+
+gceSTATUS
+gckVIDMEM_HANDLE_Dereference(
+ IN gckKERNEL Kernel,
+ IN gctUINT32 ProcessID,
+ IN gctUINT32 Handle
+ )
+{
+ gceSTATUS status;
+ gctPOINTER handleDatabase = gcvNULL;
+ gctPOINTER mutex = gcvNULL;
+ gctINT32 oldValue = 0;
+ gckVIDMEM_HANDLE handleObject = gcvNULL;
+ gctBOOL acquired = gcvFALSE;
+
+ gcmkHEADER_ARG("Handle=%d PrcoessID=%d", Handle, ProcessID);
+
+ gcmkONERROR(
+ gckKERNEL_FindHandleDatbase(Kernel,
+ ProcessID,
+ &handleDatabase,
+ &mutex));
+
+ gcmkVERIFY_OK(gckOS_AcquireMutex(Kernel->os, mutex, gcvINFINITE));
+ acquired = gcvTRUE;
+
+ /* Translate handle to gckVIDMEM_HANDLE. */
+ gcmkONERROR(
+ gckKERNEL_QueryIntegerId(handleDatabase, Handle, (gctPOINTER *)&handleObject));
+
+ gckOS_AtomDecrement(Kernel->os, handleObject->reference, &oldValue);
+
+ if (oldValue == 1)
+ {
+ /* Remove handle from database if this is the last reference. */
+ gcmkVERIFY_OK(gckKERNEL_FreeIntegerId(handleDatabase, Handle));
+ }
+
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, mutex));
+ acquired = gcvFALSE;
+
+ if (oldValue == 1)
+ {
+ gcmkVERIFY_OK(gckOS_AtomDestroy(Kernel->os, handleObject->reference));
+ gcmkOS_SAFE_FREE(Kernel->os, handleObject);
+ }
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ if (acquired)
+ {
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, mutex));
+ }
+
+ gcmkFOOTER();
+ return status;
+}
+
+gceSTATUS
+gckVIDMEM_HANDLE_LookupAndReference(
+ IN gckKERNEL Kernel,
+ IN gctUINT32 Handle,
+ OUT gckVIDMEM_NODE * Node
+ )
+{
+ gceSTATUS status;
+ gckVIDMEM_HANDLE handleObject = gcvNULL;
+ gckVIDMEM_NODE node = gcvNULL;
+ gctPOINTER database = gcvNULL;
+ gctPOINTER mutex = gcvNULL;
+ gctUINT32 processID = 0;
+ gctBOOL acquired = gcvFALSE;
+
+ gcmkHEADER_ARG("Kernel=0x%X Handle=%d", Kernel, Handle);
+
+ gckOS_GetProcessID(&processID);
+
+ gcmkONERROR(
+ gckKERNEL_FindHandleDatbase(Kernel, processID, &database, &mutex));
+
+ gcmkVERIFY_OK(gckOS_AcquireMutex(Kernel->os, mutex, gcvINFINITE));
+ acquired = gcvTRUE;
+
+ /* Translate handle to gckVIDMEM_HANDLE object. */
+ gcmkONERROR(
+ gckKERNEL_QueryIntegerId(database, Handle, (gctPOINTER *)&handleObject));
+
+ /* Get gckVIDMEM_NODE object. */
+ node = handleObject->node;
+
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, mutex));
+ acquired = gcvFALSE;
+
+ /* Reference this gckVIDMEM_NODE object. */
+ gcmkVERIFY_OK(gckVIDMEM_NODE_Reference(Kernel, node));
+
+ /* Return result. */
+ *Node = node;
+
+ gcmkFOOTER_ARG("*Node=%d", *Node);
+ return gcvSTATUS_OK;
+
+OnError:
+ if (acquired)
+ {
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, mutex));
+ }
+
+ gcmkFOOTER();
+ return status;
+}
+
+gceSTATUS
+gckVIDMEM_HANDLE_Lookup(
+ IN gckKERNEL Kernel,
+ IN gctUINT32 ProcessID,
+ IN gctUINT32 Handle,
+ OUT gckVIDMEM_NODE * Node
+ )
+{
+ gceSTATUS status;
+ gckVIDMEM_HANDLE handleObject = gcvNULL;
+ gckVIDMEM_NODE node = gcvNULL;
+ gctPOINTER database = gcvNULL;
+ gctPOINTER mutex = gcvNULL;
+ gctBOOL acquired = gcvFALSE;
+
+ gcmkHEADER_ARG("Kernel=0x%X ProcessID=%d Handle=%d",
+ Kernel, ProcessID, Handle);
+
+ gcmkONERROR(
+ gckKERNEL_FindHandleDatbase(Kernel, ProcessID, &database, &mutex));
+
+ gcmkVERIFY_OK(gckOS_AcquireMutex(Kernel->os, mutex, gcvINFINITE));
+ acquired = gcvTRUE;
+
+ gcmkONERROR(
+ gckKERNEL_QueryIntegerId(database, Handle, (gctPOINTER *)&handleObject));
+
+ node = handleObject->node;
+
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, mutex));
+ acquired = gcvFALSE;
+
+ *Node = node;
+
+ gcmkFOOTER_ARG("*Node=%d", *Node);
+ return gcvSTATUS_OK;
+
+OnError:
+ if (acquired)
+ {
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, mutex));
+ }
+
+ gcmkFOOTER();
+ return status;
+}
+
+/*******************************************************************************
+**
+** gckVIDMEM_NODE_Allocate
+**
+** Allocate a gckVIDMEM_NODE object.
+**
+** INPUT:
+**
+** gckKERNEL Kernel
+** Pointer to an gckKERNEL object.
+**
+** gcuVIDMEM_NODE_PTR Node
+** Pointer to a gcuVIDMEM_NODE union.
+**
+** OUTPUT:
+**
+** gctUINT32 * Handle
+** Pointer to a variable receiving a handle represent this
+** gckVIDMEM_NODE in userspace.
+*/
+gceSTATUS
+gckVIDMEM_NODE_Allocate(
+ IN gckKERNEL Kernel,
+ IN gcuVIDMEM_NODE_PTR VideoNode,
+ IN gceSURF_TYPE Type,
+ IN gcePOOL Pool,
+ IN gctUINT32 * Handle
+ )
+{
+ gceSTATUS status;
+ gckVIDMEM_NODE node = gcvNULL;
+ gctPOINTER pointer = gcvNULL;
+ gctUINT32 handle = 0;
+ gckOS os = Kernel->os;
+ gctUINT i;
+
+ gcmkHEADER_ARG("Kernel=0x%X VideoNode=0x%X", Kernel, VideoNode);
+
+ /* Construct a node. */
+ gcmkONERROR(gckOS_Allocate(os, gcmSIZEOF(gcsVIDMEM_NODE), &pointer));
+
+ gcmkVERIFY_OK(gckOS_ZeroMemory(pointer, gcmSIZEOF(gcsVIDMEM_NODE)));
+
+ node = pointer;
+
+ node->metadata.magic = VIV_VIDMEM_METADATA_MAGIC;
+ node->metadata.ts_fd = -1;
+#ifdef gcdANDROID
+ node->metadata.ts_address = 0;
+#endif
+
+ node->node = VideoNode;
+ node->kernel = Kernel;
+ node->type = Type;
+ node->pool = Pool;
+
+#if gcdPROCESS_ADDRESS_SPACE
+ gcmkONERROR(gckOS_CreateMutex(os, &node->mapMutex));
+#endif
+
+ gcmkONERROR(gckOS_AtomConstruct(os, &node->reference));
+
+ gcmkONERROR(gckOS_CreateMutex(os, &node->mutex));
+
+ for (i = 0; i < gcvENGINE_GPU_ENGINE_COUNT; i++)
+ {
+ gcmkONERROR(gckOS_CreateSignal(os, gcvFALSE, &node->sync[i].signal));
+ }
+
+ /* Reference is 1 by default . */
+ gckOS_AtomSet(os, node->reference, 1);
+
+ /* Create a handle to represent this node. */
+ gcmkONERROR(gckVIDMEM_HANDLE_Allocate(Kernel, node, &handle));
+
+ *Handle = handle;
+
+ gcmkFOOTER_ARG("*Handle=%d", *Handle);
+ return gcvSTATUS_OK;
+
+OnError:
+ if (node != gcvNULL)
+ {
+#if gcdPROCESS_ADDRESS_SPACE
+ if (node->mapMutex != gcvNULL)
+ {
+ gcmkVERIFY_OK(gckOS_DeleteMutex(os, node->mapMutex));
+ }
+#endif
+
+ if (node->mutex)
+ {
+ gcmkVERIFY_OK(gckOS_DeleteMutex(os, node->mutex));
+ }
+
+ if (node->reference != gcvNULL)
+ {
+ gcmkVERIFY_OK(gckOS_AtomDestroy(os, node->reference));
+ }
+
+ for (i = 0; i < gcvENGINE_GPU_ENGINE_COUNT; i++)
+ {
+ if (node->sync[i].signal != gcvNULL)
+ {
+ gcmkVERIFY_OK(gckOS_DestroySignal(os, node->sync[i].signal));
+ }
+ }
+
+ gcmkVERIFY_OK(gcmkOS_SAFE_FREE(os, node));
+ }
+
+ gcmkFOOTER();
+ return status;
+}
+
+gceSTATUS
+gckVIDMEM_NODE_Dereference(
+ IN gckKERNEL Kernel,
+ IN gckVIDMEM_NODE Node
+ )
+{
+ gctINT32 oldValue = 0;
+ gctPOINTER database = Kernel->db->nameDatabase;
+ gctPOINTER mutex = Kernel->db->nameDatabaseMutex;
+ gctUINT i;
+
+ gcmkHEADER_ARG("Kernel=0x%X Node=0x%X", Kernel, Node);
+
+ gcmkVERIFY_OK(gckOS_AcquireMutex(Kernel->os, mutex, gcvINFINITE));
+
+ gcmkVERIFY_OK(gckOS_AtomDecrement(Kernel->os, Node->reference, &oldValue));
+
+ if (oldValue == 1 && Node->name)
+ {
+ /* Free name if exists. */
+ gcmkVERIFY_OK(gckKERNEL_FreeIntegerId(database, Node->name));
+ }
+
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, mutex));
+
+ if (oldValue == 1)
+ {
+ /* Free gcuVIDMEM_NODE. */
+ gcmkVERIFY_OK(gckVIDMEM_Free(Kernel, Node->node));
+ gcmkVERIFY_OK(gckOS_AtomDestroy(Kernel->os, Node->reference));
+#if gcdPROCESS_ADDRESS_SPACE
+ gcmkVERIFY_OK(gckOS_DeleteMutex(Kernel->os, Node->mapMutex));
+#endif
+ gcmkVERIFY_OK(gckOS_DeleteMutex(Kernel->os, Node->mutex));
+
+ for (i = 0; i < gcvENGINE_GPU_ENGINE_COUNT; i++)
+ {
+ if (Node->sync[i].signal != gcvNULL)
+ {
+ gcmkVERIFY_OK(gckOS_DestroySignal(Kernel->os, Node->sync[i].signal));
+ }
+ }
+
+ /* Should not cause recursive call since tsNode->tsNode should be NULL */
+ if (Node->tsNode)
+ {
+ gcmkASSERT(!Node->tsNode->tsNode);
+ gckVIDMEM_NODE_Dereference(Kernel, Node->tsNode);
+ }
+
+ gcmkOS_SAFE_FREE(Kernel->os, Node);
+ }
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+}
+
+#if defined(CONFIG_DMA_SHARED_BUFFER)
+
+/*******************************************************************************
+**
+**
+** Code for dma_buf ops
+**
+**
+*******************************************************************************/
+
+#include <linux/slab.h>
+#include <linux/mm_types.h>
+#include <linux/dma-buf.h>
+
+static struct sg_table *_dmabuf_map(struct dma_buf_attachment *attachment,
+ enum dma_data_direction direction)
+{
+ struct sg_table *sgt = gcvNULL;
+ struct dma_buf *dmabuf = attachment->dmabuf;
+ gckVIDMEM_NODE nodeObject = dmabuf->priv;
+ gceSTATUS status = gcvSTATUS_OK;
+
+ do
+ {
+ gcuVIDMEM_NODE_PTR node = nodeObject->node;
+ gctPHYS_ADDR physical = gcvNULL;
+ gctSIZE_T offset = 0;
+ gctSIZE_T bytes = 0;
+
+ if (node->VidMem.memory->object.type == gcvOBJ_VIDMEM)
+ {
+ physical = node->VidMem.memory->physical;
+ offset = node->VidMem.offset;
+ bytes = node->VidMem.bytes;
+ }
+ else
+ {
+ physical = node->Virtual.physical;
+ offset = 0;
+ bytes = node->Virtual.bytes;
+ }
+
+ gcmkERR_BREAK(gckOS_MemoryGetSGT(nodeObject->kernel->os, physical, offset, bytes, (gctPOINTER*)&sgt));
+
+ if (dma_map_sg(attachment->dev, sgt->sgl, sgt->nents, direction) == 0)
+ {
+ sg_free_table(sgt);
+ kfree(sgt);
+ sgt = gcvNULL;
+ gcmkERR_BREAK(gcvSTATUS_GENERIC_IO);
+ }
+ }
+ while (gcvFALSE);
+
+ return sgt;
+}
+
+static void _dmabuf_unmap(struct dma_buf_attachment *attachment,
+ struct sg_table *sgt,
+ enum dma_data_direction direction)
+{
+ dma_unmap_sg(attachment->dev, sgt->sgl, sgt->nents, direction);
+
+ sg_free_table(sgt);
+ kfree(sgt);
+}
+
+static int _dmabuf_mmap(struct dma_buf *dmabuf, struct vm_area_struct *vma)
+{
+ gckVIDMEM_NODE nodeObject = dmabuf->priv;
+ gcuVIDMEM_NODE_PTR node = nodeObject->node;
+ gctPHYS_ADDR physical = gcvNULL;
+ gctSIZE_T skipPages = vma->vm_pgoff;
+ gctSIZE_T numPages = PAGE_ALIGN(vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
+ gceSTATUS status = gcvSTATUS_OK;
+
+ if (node->VidMem.memory->object.type == gcvOBJ_VIDMEM)
+ {
+ physical = node->VidMem.memory->physical;
+ skipPages += (node->VidMem.offset >> PAGE_SHIFT);
+ }
+ else
+ {
+ physical = node->Virtual.physical;
+ }
+
+ gcmkONERROR(gckOS_MemoryMmap(nodeObject->kernel->os, physical, skipPages, numPages, vma));
+
+OnError:
+ return gcmIS_ERROR(status) ? -EINVAL : 0;
+}
+
+static void _dmabuf_release(struct dma_buf *dmabuf)
+{
+ gckVIDMEM_NODE nodeObject = dmabuf->priv;
+
+ gcmkVERIFY_OK(gckVIDMEM_NODE_Dereference(nodeObject->kernel, nodeObject));
+}
+
+static void *_dmabuf_kmap(struct dma_buf *dmabuf, unsigned long offset)
+{
+ gckVIDMEM_NODE nodeObject = dmabuf->priv;
+ gcuVIDMEM_NODE_PTR node = nodeObject->node;
+ gctINT8_PTR kvaddr = gcvNULL;
+ gctPHYS_ADDR physical = gcvNULL;
+ gctSIZE_T bytes = 0;
+ gctSIZE_T pageCount = 0;
+
+ offset = (offset << PAGE_SHIFT);
+ if (node->VidMem.memory->object.type == gcvOBJ_VIDMEM)
+ {
+ physical = node->VidMem.memory->physical;
+ offset += node->VidMem.offset;
+ bytes = node->VidMem.bytes;
+ }
+ else
+ {
+ physical = node->Virtual.physical;
+ bytes = node->Virtual.bytes;
+ }
+
+ if (gcmIS_SUCCESS(gckOS_CreateKernelVirtualMapping(
+ nodeObject->kernel->os, physical, bytes, (gctPOINTER*)&kvaddr, &pageCount)))
+ {
+ kvaddr += offset;
+ }
+
+ return (gctPOINTER)kvaddr;
+}
+
+static void _dmabuf_kunmap(struct dma_buf *dmabuf, unsigned long offset, void *ptr)
+{
+ gckVIDMEM_NODE nodeObject = dmabuf->priv;
+ gcuVIDMEM_NODE_PTR node = nodeObject->node;
+ gctINT8_PTR kvaddr = (gctINT8_PTR)ptr - (offset << PAGE_SHIFT);
+ gctPHYS_ADDR physical = gcvNULL;
+ gctSIZE_T bytes = 0;
+
+ if (node->VidMem.memory->object.type == gcvOBJ_VIDMEM)
+ {
+ physical = node->VidMem.memory->physical;
+ kvaddr -= node->VidMem.offset;
+ bytes = node->VidMem.bytes;
+ }
+ else
+ {
+ physical = node->Virtual.physical;
+ bytes = node->Virtual.bytes;
+ }
+
+ gcmkVERIFY_OK(gckOS_DestroyKernelVirtualMapping(
+ nodeObject->kernel->os, physical, bytes, (gctPOINTER*)&kvaddr));
+}
+
+static struct dma_buf_ops _dmabuf_ops =
+{
+ .map_dma_buf = _dmabuf_map,
+ .unmap_dma_buf = _dmabuf_unmap,
+ .mmap = _dmabuf_mmap,
+ .release = _dmabuf_release,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,19,0)
+ .map = _dmabuf_kmap,
+ .unmap = _dmabuf_kunmap,
+# elif LINUX_VERSION_CODE >= KERNEL_VERSION(4,12,0)
+ .map_atomic = _dmabuf_kmap,
+ .unmap_atomic = _dmabuf_kunmap,
+ .map = _dmabuf_kmap,
+ .unmap = _dmabuf_kunmap,
+# else
+ .kmap_atomic = _dmabuf_kmap,
+ .kunmap_atomic = _dmabuf_kunmap,
+ .kmap = _dmabuf_kmap,
+ .kunmap = _dmabuf_kunmap,
+# endif
+};
+#endif
+
+gceSTATUS
+gckVIDMEM_NODE_Export(
+ IN gckKERNEL Kernel,
+ IN gctUINT32 Handle,
+ IN gctINT32 Flags,
+ OUT gctPOINTER *DmaBuf,
+ OUT gctINT32 *FD
+ )
+{
+#if defined(CONFIG_DMA_SHARED_BUFFER)
+ gceSTATUS status = gcvSTATUS_OK;
+ gckVIDMEM_NODE nodeObject = gcvNULL;
+ gctUINT32 processID = 0;
+ struct dma_buf *dmabuf = gcvNULL;
+
+ gcmkHEADER_ARG("Kernel=%p Handle=0x%x", Kernel, Handle);
+
+ gckOS_GetProcessID(&processID);
+ gcmkONERROR(gckVIDMEM_HANDLE_Lookup(Kernel, processID, Handle, &nodeObject));
+
+ dmabuf = nodeObject->dmabuf;
+ if (!dmabuf)
+ {
+ gctSIZE_T bytes = 0;
+ gctPHYS_ADDR physical = gcvNULL;
+ gcuVIDMEM_NODE_PTR node = nodeObject->node;
+
+ if (node->VidMem.memory->object.type == gcvOBJ_VIDMEM)
+ {
+ physical = node->VidMem.memory->physical;
+ bytes = node->VidMem.bytes;
+ /* Align export size. when allocate memory from VIDMEM, the actual node size may not same with aligned size. */
+ bytes = bytes & ~(PAGE_SIZE - 1);
+ }
+ else
+ {
+ physical = node->Virtual.physical;
+ bytes = node->Virtual.bytes;
+ }
+
+ /* Donot really get SGT, just check if the allocator support GetSGT. */
+ gcmkONERROR(gckOS_MemoryGetSGT(Kernel->os, physical, 0, 0, NULL));
+
+ {
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,1,0)
+ DEFINE_DMA_BUF_EXPORT_INFO(exp_info);
+ exp_info.ops = &_dmabuf_ops;
+ exp_info.size = bytes;
+ exp_info.flags = Flags;
+ exp_info.priv = nodeObject;
+ dmabuf = dma_buf_export(&exp_info);
+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0)
+ dmabuf = dma_buf_export(nodeObject, &_dmabuf_ops, bytes, Flags, NULL);
+#else
+ dmabuf = dma_buf_export(nodeObject, &_dmabuf_ops, bytes, Flags);
+#endif
+ }
+
+ if (IS_ERR(dmabuf))
+ {
+ gcmkONERROR(gcvSTATUS_GENERIC_IO);
+ }
+
+ /* Reference this gckVIDMEM_NODE object. */
+ gckVIDMEM_NODE_Reference(Kernel, nodeObject);
+ nodeObject->dmabuf = dmabuf;
+ }
+
+ if (DmaBuf)
+ {
+ *DmaBuf = nodeObject->dmabuf;
+ }
+
+ if (FD)
+ {
+ gctINT fd = dma_buf_fd(dmabuf, Flags);
+
+ if (fd < 0)
+ {
+ gcmkONERROR(gcvSTATUS_GENERIC_IO);
+ }
+
+ *FD = fd;
+ }
+
+OnError:
+ gcmkFOOTER_ARG("*DmaBuf=%p *FD=0x%x", gcmOPT_POINTER(DmaBuf), gcmOPT_VALUE(FD));
+ return status;
+#else
+ gcmkFATAL("The kernel did NOT support CONFIG_DMA_SHARED_BUFFER");
+ return gcvSTATUS_NOT_SUPPORTED;
+#endif
+}
+
+
+/*******************************************************************************
+**
+** gckVIDMEM_NODE_Name
+**
+** Naming a gckVIDMEM_NODE object.
+**
+** INPUT:
+**
+** gckKERNEL Kernel
+** Pointer to an gckKERNEL object.
+**
+** gctUINT32 Handle
+** Handle to a gckVIDMEM_NODE object.
+**
+** OUTPUT:
+**
+** gctUINT32 * Name
+** Pointer to a variable receiving a name which can be pass to another
+** process.
+*/
+gceSTATUS
+gckVIDMEM_NODE_Name(
+ IN gckKERNEL Kernel,
+ IN gctUINT32 Handle,
+ OUT gctUINT32 * Name
+ )
+{
+ gceSTATUS status;
+ gckVIDMEM_NODE node = gcvNULL;
+ gctUINT32 name = 0;
+ gctUINT32 processID = 0;
+ gctPOINTER database = Kernel->db->nameDatabase;
+ gctPOINTER mutex = Kernel->db->nameDatabaseMutex;
+ gctBOOL acquired = gcvFALSE;
+ gctBOOL referenced = gcvFALSE;
+ gcmkHEADER_ARG("Kernel=0x%X Handle=%d", Kernel, Handle);
+
+ gcmkVERIFY_ARGUMENT(Name != gcvNULL);
+
+ gcmkONERROR(gckOS_GetProcessID(&processID));
+
+ gcmkONERROR(gckOS_AcquireMutex(Kernel->os, mutex, gcvINFINITE));
+ acquired = gcvTRUE;
+
+ gcmkONERROR(gckVIDMEM_HANDLE_LookupAndReference(Kernel, Handle, &node));
+ referenced = gcvTRUE;
+
+ if (node->name == 0)
+ {
+ /* Name this node. */
+ gcmkONERROR(gckKERNEL_AllocateIntegerId(database, node, &name));
+ node->name = name;
+ }
+ else
+ {
+ name = node->name;
+ }
+
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, mutex));
+ acquired = gcvFALSE;
+
+ gcmkVERIFY_OK(gckVIDMEM_NODE_Dereference(Kernel, node));
+
+ *Name = name;
+
+ gcmkFOOTER_ARG("*Name=%d", *Name);
+ return gcvSTATUS_OK;
+
+OnError:
+ if (referenced)
+ {
+ gcmkVERIFY_OK(gckVIDMEM_NODE_Dereference(Kernel, node));
+ }
+
+ if (acquired)
+ {
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, mutex));
+ }
+
+ gcmkFOOTER();
+ return status;
+}
+
+/*******************************************************************************
+**
+** gckVIDMEM_NODE_Import
+**
+** Import a gckVIDMEM_NODE object.
+**
+** INPUT:
+**
+** gckKERNEL Kernel
+** Pointer to an gckKERNEL object.
+**
+** gctUINT32 Name
+** Name of a gckVIDMEM_NODE object.
+**
+** OUTPUT:
+**
+** gctUINT32 * Handle
+** Pointer to a variable receiving a handle represent this
+** gckVIDMEM_NODE in userspace.
+*/
+gceSTATUS
+gckVIDMEM_NODE_Import(
+ IN gckKERNEL Kernel,
+ IN gctUINT32 Name,
+ OUT gctUINT32 * Handle
+ )
+{
+ gceSTATUS status;
+ gckVIDMEM_NODE node = gcvNULL;
+ gctPOINTER database = Kernel->db->nameDatabase;
+ gctPOINTER mutex = Kernel->db->nameDatabaseMutex;
+ gctBOOL acquired = gcvFALSE;
+ gctBOOL referenced = gcvFALSE;
+
+ gcmkHEADER_ARG("Kernel=0x%X Name=%d", Kernel, Name);
+
+ gcmkONERROR(gckOS_AcquireMutex(Kernel->os, mutex, gcvINFINITE));
+ acquired = gcvTRUE;
+
+ /* Lookup in database to get the node. */
+ gcmkONERROR(gckKERNEL_QueryIntegerId(database, Name, (gctPOINTER *)&node));
+
+ /* Reference the node. */
+ gcmkONERROR(gckVIDMEM_NODE_Reference(Kernel, node));
+ referenced = gcvTRUE;
+
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, mutex));
+ acquired = gcvFALSE;
+
+ /* Allocate a handle for current process. */
+ gcmkONERROR(gckVIDMEM_HANDLE_Allocate(Kernel, node, Handle));
+
+ gcmkFOOTER_ARG("*Handle=%d", *Handle);
+ return gcvSTATUS_OK;
+
+OnError:
+ if (referenced)
+ {
+ gcmkVERIFY_OK(gckVIDMEM_NODE_Dereference(Kernel, node));
+ }
+
+ if (acquired)
+ {
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, mutex));
+ }
+
+ gcmkFOOTER();
+ return status;
+}
+
+typedef struct _gcsVIDMEM_NODE_FDPRIVATE
+{
+ gcsFDPRIVATE base;
+ gckKERNEL kernel;
+ gckVIDMEM_NODE node;
+}
+gcsVIDMEM_NODE_FDPRIVATE;
+
+
+static gctINT
+_ReleaseFdPrivate(
+ gcsFDPRIVATE_PTR FdPrivate
+ )
+{
+ /* Cast private info. */
+ gcsVIDMEM_NODE_FDPRIVATE * private = (gcsVIDMEM_NODE_FDPRIVATE *) FdPrivate;
+
+ gckVIDMEM_NODE_Dereference(private->kernel, private->node);
+ gckOS_Free(private->kernel->os, private);
+
+ return 0;
+}
+
+
+/*******************************************************************************
+**
+** gckVIDMEM_NODE_GetFd
+**
+** Attach a gckVIDMEM_NODE object to a native fd.
+**
+** INPUT:
+**
+** gckKERNEL Kernel
+** Pointer to an gckKERNEL object.
+**
+** gctUINT32 Handle
+** Handle to a gckVIDMEM_NODE object.
+**
+** OUTPUT:
+**
+** gctUINT32 * Fd
+** Pointer to a variable receiving a native fd from os.
+*/
+gceSTATUS
+gckVIDMEM_NODE_GetFd(
+ IN gckKERNEL Kernel,
+ IN gctUINT32 Handle,
+ OUT gctINT * Fd
+ )
+{
+ gceSTATUS status;
+ gckVIDMEM_NODE node = gcvNULL;
+ gctBOOL referenced = gcvFALSE;
+ gcsVIDMEM_NODE_FDPRIVATE * fdPrivate = gcvNULL;
+ gcmkHEADER_ARG("Kernel=0x%X Handle=%d", Kernel, Handle);
+
+ /* Query and reference handle. */
+ gcmkONERROR(gckVIDMEM_HANDLE_LookupAndReference(Kernel, Handle, &node));
+ referenced = gcvTRUE;
+
+ /* Allocated fd owns a reference. */
+ gcmkONERROR(gckOS_Allocate(
+ Kernel->os,
+ gcmSIZEOF(gcsVIDMEM_NODE_FDPRIVATE),
+ (gctPOINTER *)&fdPrivate
+ ));
+
+ fdPrivate->base.release = _ReleaseFdPrivate;
+ fdPrivate->kernel = Kernel;
+ fdPrivate->node = node;
+
+ /* Allocated fd owns a reference. */
+ gcmkONERROR(gckOS_GetFd("vidmem", &fdPrivate->base, Fd));
+
+ gcmkFOOTER_ARG("*Fd=%d", *Fd);
+ return gcvSTATUS_OK;
+
+OnError:
+ if (referenced)
+ {
+ gcmkVERIFY_OK(gckVIDMEM_NODE_Dereference(Kernel, node));
+ }
+
+ if (fdPrivate)
+ {
+ gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Kernel->os, fdPrivate));
+ }
+
+ gcmkFOOTER();
+ return status;
+}
+
+gceSTATUS
+gckVIDMEM_NODE_WrapUserMemory(
+ IN gckKERNEL Kernel,
+ IN gcsUSER_MEMORY_DESC_PTR Desc,
+ OUT gctUINT32 * Handle,
+ OUT gctUINT64 * Bytes
+ )
+{
+ gceSTATUS status = gcvSTATUS_OK;
+ gctBOOL found = gcvFALSE;
+
+ gcmkHEADER_ARG("Kernel=0x%x", Kernel);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
+ gcmkVERIFY_ARGUMENT(Desc);
+ gcmkVERIFY_ARGUMENT(Handle);
+ gcmkVERIFY_ARGUMENT(Bytes);
+
+#if defined(CONFIG_DMA_SHARED_BUFFER)
+ if (Desc->flag & gcvALLOC_FLAG_DMABUF)
+ {
+ struct dma_buf *dmabuf;
+ int fd = (int)Desc->handle;
+
+ if (fd >= 0)
+ {
+ /* Import dma buf handle. */
+ dmabuf = dma_buf_get(fd);
+
+ if (IS_ERR(dmabuf))
+ return PTR_ERR(dmabuf);
+
+ Desc->handle = -1;
+ Desc->dmabuf = gcmPTR_TO_UINT64(dmabuf);
+
+ dma_buf_put(dmabuf);
+ }
+ else
+ {
+ dmabuf = gcmUINT64_TO_PTR(Desc->dmabuf);
+ }
+
+ if (dmabuf->ops == &_dmabuf_ops)
+ {
+ gctBOOL referenced = gcvFALSE;
+ gckVIDMEM_NODE nodeObject = dmabuf->priv;
+
+ do
+ {
+ /* Reference the node. */
+ gcmkERR_BREAK(gckVIDMEM_NODE_Reference(Kernel, nodeObject));
+ referenced = gcvTRUE;
+ /* Allocate a handle for current process. */
+ gcmkERR_BREAK(gckVIDMEM_HANDLE_Allocate(Kernel, nodeObject, Handle));
+ found = gcvTRUE;
+
+ *Bytes = (gctUINT64)dmabuf->size;
+ }
+ while (gcvFALSE);
+
+ if (gcmIS_ERROR(status) && referenced)
+ {
+ gcmkVERIFY_OK(gckVIDMEM_NODE_Dereference(Kernel, nodeObject));
+ }
+ }
+ }
+#endif
+
+ if (!found)
+ {
+ gckOS os = Kernel->os;
+ gcuVIDMEM_NODE_PTR node = gcvNULL;
+
+ gcmkVERIFY_OBJECT(os, gcvOBJ_OS);
+
+ do {
+ /* Allocate an gcuVIDMEM_NODE union. */
+ gcmkERR_BREAK(gckOS_Allocate(os, gcmSIZEOF(gcuVIDMEM_NODE), (gctPOINTER*)&node));
+ gckOS_ZeroMemory(node, gcmSIZEOF(gcuVIDMEM_NODE));
+
+ /* Initialize gcuVIDMEM_NODE union for virtual memory. */
+ node->Virtual.kernel = Kernel;
+
+ /* Wrap Memory. */
+ gcmkERR_BREAK(gckOS_WrapMemory(os, Desc, &node->Virtual.bytes,
+ &node->Virtual.physical, &node->Virtual.contiguous));
+
+ /* Allocate handle for this video memory. */
+ gcmkERR_BREAK(gckVIDMEM_NODE_Allocate(
+ Kernel,
+ node,
+ gcvSURF_BITMAP,
+ gcvPOOL_VIRTUAL,
+ Handle
+ ));
+
+ *Bytes = (gctUINT64)node->Virtual.bytes;
+ }
+ while (gcvFALSE);
+
+ if (gcmIS_ERROR(status) && node)
+ {
+ /* Free the structure. */
+ gcmkVERIFY_OK(gcmkOS_SAFE_FREE(os, node));
+ }
+ }
+
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+gceSTATUS
+gckVIDMEM_SetCommitStamp(
+ IN gckKERNEL Kernel,
+ IN gceENGINE Engine,
+ IN gctUINT32 Handle,
+ IN gctUINT64 CommitStamp
+ )
+{
+ gceSTATUS status;
+ gckVIDMEM_NODE node;
+ gctUINT32 processID;
+
+ gckOS_GetProcessID(&processID);
+
+ gcmkONERROR(gckVIDMEM_HANDLE_LookupAndReference(Kernel, Handle, &node));
+
+ node->sync[Engine].commitStamp = CommitStamp;
+
+ gckVIDMEM_NODE_Dereference(Kernel, node);
+
+ return gcvSTATUS_OK;
+
+OnError:
+ return status;
+}
+
+gceSTATUS
+gckVIDMEM_GetCommitStamp(
+ IN gckKERNEL Kernel,
+ IN gceENGINE Engine,
+ IN gctUINT32 Handle,
+ OUT gctUINT64_PTR CommitStamp
+ )
+{
+ gceSTATUS status;
+ gckVIDMEM_NODE node;
+ gctUINT32 processID;
+
+ gckOS_GetProcessID(&processID);
+
+ gcmkONERROR(gckVIDMEM_HANDLE_LookupAndReference(Kernel, Handle, &node));
+
+ *CommitStamp = node->sync[Engine].commitStamp;
+
+ gckVIDMEM_NODE_Dereference(Kernel, node);
+
+ return gcvSTATUS_OK;
+
+OnError:
+ return status;
+}
+
+gceSTATUS
+gckVIDMEM_FindVIDMEM(
+ IN gckKERNEL Kernel,
+ IN gctUINT32 HardwareAddress,
+ OUT gcuVIDMEM_NODE_PTR * Node,
+ OUT gctUINT32_PTR PageTableEntryValue
+ )
+{
+ gceSTATUS status = gcvSTATUS_NOT_FOUND;
+ gcuVIDMEM_NODE_PTR node = gcvNULL;
+
+ gcsLISTHEAD_PTR pos;
+
+ gcmkLIST_FOR_EACH(pos, &Kernel->db->onFaultVidmemList)
+ {
+ node = (gcuVIDMEM_NODE_PTR)gcmCONTAINEROF(pos, _gcsVIDMEM_NODE_VIRTUAL, head);
+
+ if (HardwareAddress >= node->Virtual.addresses[Kernel->core]
+ && (HardwareAddress <= node->Virtual.addresses[Kernel->core] - 1 + node->Virtual.bytes)
+ )
+ {
+ *Node = node;
+ status = gcvSTATUS_OK;
+ break;
+ }
+ }
+
+ if (gcmIS_SUCCESS(status))
+ {
+ /* Setup map for fault address. */
+ gctUINT32 offset = HardwareAddress - node->Virtual.addresses[Kernel->core];
+ gctPHYS_ADDR_T physicalAddress;
+
+ offset &= ~gcdMMU_PAGE_4K_MASK;
+
+ gckOS_PhysicalToPhysicalAddress(Kernel->os, node->Virtual.physical, offset, &physicalAddress);
+
+ gcmkSAFECASTPHYSADDRT(*PageTableEntryValue, physicalAddress);
+ }
+
+ return status;
+}
+
+/* Get the nodes of all banks. */
+gceSTATUS
+gckVIDMEM_QueryNodes(
+ IN gckKERNEL Kernel,
+ IN gcePOOL Pool,
+ OUT gctINT32 *Count,
+ OUT gcuVIDMEM_NODE_PTR *Nodes
+ )
+{
+ gceSTATUS status = gcvSTATUS_OK;
+ gckVIDMEM memory = gcvNULL;
+
+ do
+ {
+ status = gckKERNEL_GetVideoMemoryPool(Kernel, Pool, &memory);
+ if (status != gcvSTATUS_OK)
+ break;
+
+ if (memory != gcvNULL)
+ {
+ *Count = gcmCOUNTOF(memory->sentinel);
+ *Nodes = memory->sentinel;
+ }
+ }
+ while (gcvFALSE);
+
+ return status;
+}
diff --git a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_feature_database.h b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_feature_database.h
new file mode 100644
index 000000000000..e3bac048bcb8
--- /dev/null
+++ b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_feature_database.h
@@ -0,0 +1,108065 @@
+/****************************************************************************
+*
+* The MIT License (MIT)
+*
+* Copyright (c) 2014 - 2018 Vivante 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 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 GPL License (GPL)
+*
+* Copyright (C) 2014 - 2018 Vivante 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.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+*****************************************************************************
+*
+* Note: This software is released under dual MIT and GPL licenses. A
+* recipient may use this file under the terms of either the MIT license or
+* GPL License. If you wish to use only one license not the other, you can
+* indicate your decision by deleting one of the above license notices in your
+* version of this file.
+*
+*****************************************************************************/
+
+
+/*Auto created on 2018-12-18 14:20*/
+#ifndef _gc_feature_database_h_
+#define _gc_feature_database_h_
+
+typedef struct
+{
+ /* Chip ID. */
+ gctUINT32 chipID;
+ gctUINT32 chipVersion;
+ gctUINT32 productID;
+ gctUINT32 ecoID;
+ gctUINT32 customerID;
+ gctUINT32 patchVersion;
+ const char *productName;
+ gctUINT32 formalRelease;
+ gctUINT32 TempRegisters;
+ gctUINT32 ThreadCount;
+ gctUINT32 NumShaderCores;
+ gctUINT32 InstructionCount;
+ gctUINT32 NumberOfConstants;
+ gctUINT32 CoreCount;
+ gctUINT32 LocalStorageSize;
+ gctUINT32 L1CacheSize;
+ gctUINT32 InstructionMemorySize;
+ gctUINT32 ShaderPCLength;
+ gctUINT32 USC_MAX_PAGES;
+ gctUINT32 NumPixelPipes;
+ gctUINT32 USC_CACHE_CONTROLLERS;
+ gctUINT32 USC_BANKS;
+ gctUINT32 Streams;
+ gctUINT32 VaryingCount;
+ gctUINT32 VertexOutputBufferSize;
+ gctUINT32 BufferSize;
+ gctUINT32 VertexCacheSize;
+ gctUINT32 NumResolvePipes;
+ gctUINT32 RESULT_WINDOW_MAX_SIZE;
+ gctUINT32 ClusterAliveMask;
+ gctUINT32 NNMadPerCore;
+ gctUINT32 NNCoreCount;
+ gctUINT32 NNCoreCount_INT8;
+ gctUINT32 NNCoreCount_INT16;
+ gctUINT32 NNCoreCount_FLOAT16;
+ gctUINT32 NNInputBufferDepth;
+ gctUINT32 NNAccumBufferDepth;
+ gctUINT32 TPEngine_PwlLUTCount;
+ gctUINT32 TPEngine_PwlLUTSize;
+ gctUINT32 VIP_SRAM_SIZE;
+ gctUINT32 TPEngine_CoreCount;
+ gctUINT32 AXI_SRAM_SIZE;
+ gctUINT32 NN_INIMAGE_OFFSET_BITS;
+ gctUINT32 TP_REORDER_INIMAGE_SIZE;
+ gctUINT32 TPLite_CoreCount;
+ gctUINT32 NNFP16_XYDP_X;
+ gctUINT32 NNFP16_XYDP_Y;
+ gctUINT32 NNFP16_ZDP;
+ gctUINT32 NN_LANES_PER_OUT_CYCLE;
+ gctUINT32 MAX_OT_NUMBER;
+ gctUINT32 VIP_SRAM_WIDTH_INBYTE;
+ gctUINT32 TP_ZRL_BITS;
+ gctUINT32 REG_FastClear:1;
+ gctUINT32 REG_SpecialAntiAliasing:1;
+ gctUINT32 REG_Pipe3D:1;
+ gctUINT32 REG_DXTTextureCompression:1;
+ gctUINT32 REG_DebugMode:1;
+ gctUINT32 REG_ZCompression:1;
+ gctUINT32 REG_YUV420Filter:1;
+ gctUINT32 REG_MSAA:1;
+ gctUINT32 REG_DC:1;
+ gctUINT32 REG_Pipe2D:1;
+ gctUINT32 REG_ETC1TextureCompression:1;
+ gctUINT32 REG_FastScaler:1;
+ gctUINT32 REG_HighDynamicRange:1;
+ gctUINT32 REG_YUV420Tiler:1;
+ gctUINT32 REG_ModuleCG:1;
+ gctUINT32 REG_MinArea:1;
+ gctUINT32 REG_NoEZ:1;
+ gctUINT32 REG_No422Texture:1;
+ gctUINT32 REG_BufferInterleaving:1;
+ gctUINT32 REG_ByteWrite2D:1;
+ gctUINT32 REG_NoScaler:1;
+ gctUINT32 REG_YUY2Averaging:1;
+ gctUINT32 REG_HalfPECache:1;
+ gctUINT32 REG_HalfTXCache:1;
+ gctUINT32 REG_YUY2RenderTarget:1;
+ gctUINT32 REG_Mem32BitSupport:1;
+ gctUINT32 REG_PipeVG:1;
+ gctUINT32 REG_VGTS:1;
+ gctUINT32 REG_FE20:1;
+ gctUINT32 REG_ByteWrite3D:1;
+ gctUINT32 REG_RsYuvTarget:1;
+ gctUINT32 REG_FE20BitIndex:1;
+ gctUINT32 REG_FlipY:1;
+ gctUINT32 REG_DualReturnBus:1;
+ gctUINT32 REG_EndiannessConfig:1;
+ gctUINT32 REG_Texture8K:1;
+ gctUINT32 REG_CorrectTextureConverter:1;
+ gctUINT32 REG_SpecialMsaaLod:1;
+ gctUINT32 REG_FastClearFlush:1;
+ gctUINT32 REG_2DPE20:1;
+ gctUINT32 REG_CorrectAutoDisable:1;
+ gctUINT32 REG_Render8K:1;
+ gctUINT32 REG_TileStatus2Bits:1;
+ gctUINT32 REG_SeparateTileStatusWhenInterleaved:1;
+ gctUINT32 REG_SuperTiled32x32:1;
+ gctUINT32 REG_VG20:1;
+ gctUINT32 REG_TSExtendedCommands:1;
+ gctUINT32 REG_CompressionFifoFixed:1;
+ gctUINT32 REG_ExtraShaderInstructions0:1;
+ gctUINT32 REG_VGFilter:1;
+ gctUINT32 REG_VG21:1;
+ gctUINT32 REG_ShaderGetsW:1;
+ gctUINT32 REG_ExtraShaderInstructions1:1;
+ gctUINT32 REG_DefaultReg0:1;
+ gctUINT32 REG_MC20:1;
+ gctUINT32 REG_ShaderMSAASideband:1;
+ gctUINT32 REG_BugFixes0:1;
+ gctUINT32 REG_VAA:1;
+ gctUINT32 REG_BypassInMSAA:1;
+ gctUINT32 REG_HierarchicalZ:1;
+ gctUINT32 REG_NewTexture:1;
+ gctUINT32 REG_A8TargetSupport:1;
+ gctUINT32 REG_CorrectStencil:1;
+ gctUINT32 REG_EnhanceVR:1;
+ gctUINT32 REG_RSUVSwizzle:1;
+ gctUINT32 REG_V2Compression:1;
+ gctUINT32 REG_VGDoubleBuffer:1;
+ gctUINT32 REG_BugFixes1:1;
+ gctUINT32 REG_BugFixes2:1;
+ gctUINT32 REG_TextureStride:1;
+ gctUINT32 REG_BugFixes3:1;
+ gctUINT32 REG_CorrectAutoDisable1:1;
+ gctUINT32 REG_AutoRestartTS:1;
+ gctUINT32 REG_BugFixes4:1;
+ gctUINT32 REG_L2Windowing:1;
+ gctUINT32 REG_HalfFloatPipe:1;
+ gctUINT32 REG_PixelDither:1;
+ gctUINT32 REG_TwoStencilReference:1;
+ gctUINT32 REG_ExtendedPixelFormat:1;
+ gctUINT32 REG_CorrectMinMaxDepth:1;
+ gctUINT32 REG_DitherAndFilterPlusAlpha2D:1;
+ gctUINT32 REG_BugFixes5:1;
+ gctUINT32 REG_New2D:1;
+ gctUINT32 REG_NewFloatingPointArithmetic:1;
+ gctUINT32 REG_TextureHorizontalAlignmentSelect:1;
+ gctUINT32 REG_NonPowerOfTwo:1;
+ gctUINT32 REG_LinearTextureSupport:1;
+ gctUINT32 REG_Halti0:1;
+ gctUINT32 REG_CorrectOverflowVG:1;
+ gctUINT32 REG_NegativeLogFix:1;
+ gctUINT32 REG_ResolveOffset:1;
+ gctUINT32 REG_OkToGateAxiClock:1;
+ gctUINT32 REG_MMU:1;
+ gctUINT32 REG_WideLine:1;
+ gctUINT32 REG_BugFixes6:1;
+ gctUINT32 REG_FcFlushStall:1;
+ gctUINT32 REG_LineLoop:1;
+ gctUINT32 REG_LogicOp:1;
+ gctUINT32 REG_SeamlessCubeMap:1;
+ gctUINT32 REG_SuperTiledTexture:1;
+ gctUINT32 REG_LinearPE:1;
+ gctUINT32 REG_RectPrimitive:1;
+ gctUINT32 REG_Composition:1;
+ gctUINT32 REG_CorrectAutoDisableCountWidth:1;
+ gctUINT32 REG_PESwizzle:1;
+ gctUINT32 REG_EndEvent:1;
+ gctUINT32 REG_S1S8:1;
+ gctUINT32 REG_Halti1:1;
+ gctUINT32 REG_RGB888:1;
+ gctUINT32 REG_TX_YUVAssembler:1;
+ gctUINT32 REG_DynamicFrequencyScaling:1;
+ gctUINT32 REG_TXFilter:1;
+ gctUINT32 REG_FullDirectFB:1;
+ gctUINT32 REG_OnePass2DFilter:1;
+ gctUINT32 REG_ThreadWalkerInPS:1;
+ gctUINT32 REG_TileFiller:1;
+ gctUINT32 REG_YUVStandard:1;
+ gctUINT32 REG_MultiSourceBlt:1;
+ gctUINT32 REG_YUVConversion:1;
+ gctUINT32 REG_FlushFixed2D:1;
+ gctUINT32 REG_Interleaver:1;
+ gctUINT32 REG_MixedStreams:1;
+ gctUINT32 REG_L2CacheFor2D420:1;
+ gctUINT32 REG_BugFixes7:1;
+ gctUINT32 REG_NoIndexPattern:1;
+ gctUINT32 REG_TextureTileStatus:1;
+ gctUINT32 REG_DecompressZ16:1;
+ gctUINT32 REG_BugFixes8:1;
+ gctUINT32 REG_DERotationStallFix:1;
+ gctUINT32 REG_OclOnly:1;
+ gctUINT32 REG_NewFeatures0:1;
+ gctUINT32 REG_InstructionCache:1;
+ gctUINT32 REG_GeometryShader:1;
+ gctUINT32 REG_TexCompressionSupertiled:1;
+ gctUINT32 REG_Generics:1;
+ gctUINT32 REG_BugFixes9:1;
+ gctUINT32 REG_FastMSAA:1;
+ gctUINT32 REG_WClip:1;
+ gctUINT32 REG_BugFixes10:1;
+ gctUINT32 REG_UnifiedSamplers:1;
+ gctUINT32 REG_BugFixes11:1;
+ gctUINT32 REG_PerformanceCounters:1;
+ gctUINT32 REG_ExtraShaderInstructions2:1;
+ gctUINT32 REG_BugFixes12:1;
+ gctUINT32 REG_BugFixes13:1;
+ gctUINT32 REG_DEEnhancements1:1;
+ gctUINT32 REG_ACE:1;
+ gctUINT32 REG_TXEnhancements1:1;
+ gctUINT32 REG_SHEnhancements1:1;
+ gctUINT32 REG_SHEnhancements2:1;
+ gctUINT32 REG_PEEnhancements1:1;
+ gctUINT32 REG_DEEnhancements2:1;
+ gctUINT32 REG_BugFixes14:1;
+ gctUINT32 REG_PowerOptimizations0:1;
+ gctUINT32 REG_NewHZ:1;
+ gctUINT32 REG_BugFixes15:1;
+ gctUINT32 REG_DEEnhancements3:1;
+ gctUINT32 REG_SHEnhancements3:1;
+ gctUINT32 REG_SHEnhancements4:1;
+ gctUINT32 REG_TXEnhancements2:1;
+ gctUINT32 REG_FEEnhancements1:1;
+ gctUINT32 REG_PEEnhancements2:1;
+ gctUINT32 REG_PAEnhancements1:1;
+ gctUINT32 REG_DENoGamma:1;
+ gctUINT32 REG_PAEnhancements2:1;
+ gctUINT32 REG_DEEnhancements4:1;
+ gctUINT32 REG_PEEnhancements3:1;
+ gctUINT32 REG_HIEnhancements1:1;
+ gctUINT32 REG_TXEnhancements3:1;
+ gctUINT32 REG_SHEnhancements5:1;
+ gctUINT32 REG_FEEnhancements2:1;
+ gctUINT32 REG_BugFixes16:1;
+ gctUINT32 REG_DEEnhancements5:1;
+ gctUINT32 REG_TXEnhancements4:1;
+ gctUINT32 REG_PEEnhancements4:1;
+ gctUINT32 REG_MCEnhancements1:1;
+ gctUINT32 REG_Halti2:1;
+ gctUINT32 REG_DEMirrorRotate:1;
+ gctUINT32 REG_SmallMSAA:1;
+ gctUINT32 REG_BugFixes17:1;
+ gctUINT32 REG_Rasterizer2:1;
+ gctUINT32 REG_DualPipeOPF:1;
+ gctUINT32 REG_MultiSrcV2:1;
+ gctUINT32 REG_CSCV2:1;
+ gctUINT32 REG_PAEnhancements3:1;
+ gctUINT32 REG_BugFixes18:1;
+ gctUINT32 REG_Compression2D:1;
+ gctUINT32 REG_Probe:1;
+ gctUINT32 REG_MediumPrecision:1;
+ gctUINT32 REG_DESupertile:1;
+ gctUINT32 REG_BugFixes19:1;
+ gctUINT32 REG_SHEnhancements6:1;
+ gctUINT32 REG_SHEnhancements7:1;
+ gctUINT32 REG_BugFixes20:1;
+ gctUINT32 REG_DEAddress40:1;
+ gctUINT32 REG_MiniMMUFix:1;
+ gctUINT32 REG_EEZ:1;
+ gctUINT32 REG_BugFixes21:1;
+ gctUINT32 REG_ExtraVgCaps:1;
+ gctUINT32 REG_MultiSrcV15:1;
+ gctUINT32 REG_BugFixes22:1;
+ gctUINT32 REG_Halti3:1;
+ gctUINT32 REG_TessellationShaders:1;
+ gctUINT32 REG_OPF9Tap:1;
+ gctUINT32 REG_MultiSrcV2StrQuad:1;
+ gctUINT32 REG_SeperateSRCAndDstCache:1;
+ gctUINT32 REG_Halti4:1;
+ gctUINT32 REG_RAWriteDepth:1;
+ gctUINT32 REG_AndroidOnly:1;
+ gctUINT32 REG_HasChipProductReg:1;
+ gctUINT32 REG_TXSupportDEC:1;
+ gctUINT32 REG_S8MSAACompression:1;
+ gctUINT32 REG_BugFixesIn544:1;
+ gctUINT32 REG_L2CacheRemove:1;
+ gctUINT32 REG_FEAllowRndVtxCnt:1;
+ gctUINT32 REG_CubeMapFL28:1;
+ gctUINT32 REG_TX6bitFrac:1;
+ gctUINT32 REG_FEAllowStallPrefetchEng:1;
+ gctUINT32 REG_ThirdPartyCompression:1;
+ gctUINT32 REG_RSS8:1;
+ gctUINT32 REG_MSAACoherencyCheck:1;
+ gctUINT32 REG_Halti5:1;
+ gctUINT32 REG_Evis:1;
+ gctUINT32 REG_BltEngine:1;
+ gctUINT32 REG_BugFixes23:1;
+ gctUINT32 REG_BugFixes24:1;
+ gctUINT32 REG_DEC:1;
+ gctUINT32 REG_VSTileNV12:1;
+ gctUINT32 REG_VSTileNV12_10BIT:1;
+ gctUINT32 RenderTarget8:1;
+ gctUINT32 TxLodFlowCorrection:1;
+ gctUINT32 FaceLod:1;
+ gctUINT32 MultiCoreSemaphoreStallV2:1;
+ gctUINT32 VMSAA:1;
+ gctUINT32 ChipEnableLink:1;
+ gctUINT32 MULTI_SRC_BLT_1_5_ENHANCEMENT:1;
+ gctUINT32 MULTI_SRC_BLT_BILINEAR_FILTER:1;
+ gctUINT32 RA_HZEZ_CLOCK_CONTROL:1;
+ gctUINT32 CACHE128B256BPERLINE:1;
+ gctUINT32 V4Compression:1;
+ gctUINT32 PE2D_MAJOR_SUPER_TILE:1;
+ gctUINT32 PE_32BPC_COLORMASK_FIX:1;
+ gctUINT32 ALPHA_BLENDING_OPT:1;
+ gctUINT32 NEW_GPIPE:1;
+ gctUINT32 PIPELINE_32_ATTRIBUTES:1;
+ gctUINT32 MSAA_SHADING:1;
+ gctUINT32 NO_ANISTRO_FILTER:1;
+ gctUINT32 NO_ASTC:1;
+ gctUINT32 NO_DXT:1;
+ gctUINT32 HWTFB:1;
+ gctUINT32 RA_DEPTH_WRITE_MSAA1X_FIX:1;
+ gctUINT32 EZHZ_CLOCKGATE_FIX:1;
+ gctUINT32 SH_SNAP2PAGE_FIX:1;
+ gctUINT32 SH_HALFDEPENDENCY_FIX:1;
+ gctUINT32 USC_MCFILL_FIX:1;
+ gctUINT32 TPG_TCPERF_FIX:1;
+ gctUINT32 USC_MDFIFO_OVERFLOW_FIX:1;
+ gctUINT32 SH_TEXLD_BARRIER_IN_CS_FIX:1;
+ gctUINT32 RS_NEW_BASEADDR:1;
+ gctUINT32 PE_8bpp_DUALPIPE_FIX:1;
+ gctUINT32 SH_ADVANCED_INSTR:1;
+ gctUINT32 SH_FLAT_INTERPOLATION_DUAL16_FIX:1;
+ gctUINT32 USC_CONTINUOUS_FLUS_FIX:1;
+ gctUINT32 SH_SUPPORT_V4:1;
+ gctUINT32 SH_SUPPORT_ALPHA_KILL:1;
+ gctUINT32 PE_NO_ALPHA_TEST:1;
+ gctUINT32 TX_LOD_NEAREST_SELECT:1;
+ gctUINT32 SH_FIX_LDEXP:1;
+ gctUINT32 SUPPORT_MOVAI:1;
+ gctUINT32 SH_SNAP2PAGE_MAXPAGES_FIX:1;
+ gctUINT32 PE_RGBA16I_FIX:1;
+ gctUINT32 BLT_8bpp_256TILE_FC_FIX:1;
+ gctUINT32 PE_64bit_FENCE_FIX:1;
+ gctUINT32 USC_FULL_CACHE_FIX:1;
+ gctUINT32 TX_YUV_ASSEMBLER_10BIT:1;
+ gctUINT32 FE_32bit_INDEX_FIX:1;
+ gctUINT32 BLT_64bpp_MASKED_CLEAR_FIX:1;
+ gctUINT32 SECURITY:1;
+ gctUINT32 ROBUSTNESS:1;
+ gctUINT32 USC_ATOMIC_FIX:1;
+ gctUINT32 SH_PSO_MSAA1x_FIX:1;
+ gctUINT32 USC_VX_PERF_FIX:1;
+ gctUINT32 USC_GOS_ADDR_FIX:1;
+ gctUINT32 TX_8bit_UVFrac:1;
+ gctUINT32 TX_DESC_CACHE_CLOCKGATE_FIX:1;
+ gctUINT32 RSBLT_MSAA_DECOMPRESSION:1;
+ gctUINT32 TX_INTEGER_COORDINATE:1;
+ gctUINT32 DRAWID:1;
+ gctUINT32 PSIO_SAMPLEMASK_IN_R0ZW_FIX:1;
+ gctUINT32 TX_INTEGER_COORDINATE_V2:1;
+ gctUINT32 MULTI_CORE_BLOCK_SET_CONFIG:1;
+ gctUINT32 SNAPPAGE_CMD:1;
+ gctUINT32 SH_NO_INDEX_CONST_ON_A0:1;
+ gctUINT32 SH_NO_ONECONST_LIMIT:1;
+ gctUINT32 SH_IMG_LDST_ON_TEMP:1;
+ gctUINT32 COMPUTE_ONLY:1;
+ gctUINT32 SH_IMG_LDST_CLAMP:1;
+ gctUINT32 SH_ICACHE_ALLOC_COUNT_FIX:1;
+ gctUINT32 SH_ICACHE_PREFETCH:1;
+ gctUINT32 PE2D_SEPARATE_CACHE:1;
+ gctUINT32 PE_MSAA_OQ_FIX:1;
+ gctUINT32 PSIO_MSAA_CL_FIX:1;
+ gctUINT32 USC_DEFER_FILL_FIX:1;
+ gctUINT32 SH_CLOCK_GATE_FIX:1;
+ gctUINT32 FE_NEED_DUMMYDRAW:1;
+ gctUINT32 PE2D_LINEAR_YUV420_OUTPUT:1;
+ gctUINT32 PE2D_LINEAR_YUV420_10BIT:1;
+ gctUINT32 MULTI_CLUSTER:1;
+ gctUINT32 SH_MULTI_WG_PACK:1;
+ gctUINT32 SH_DUAL16_SAMPLEMASK_ZW:1;
+ gctUINT32 TPG_TRIVIAL_MODE_FIX:1;
+ gctUINT32 TX_ASTC_MULTISLICE_FIX:1;
+ gctUINT32 FE_ROBUST_FIX:1;
+ gctUINT32 SH_GPIPE_ACCESS_FULLTEMPS:1;
+ gctUINT32 PSIO_INTERLOCK:1;
+ gctUINT32 PA_WIDELINE_FIX:1;
+ gctUINT32 WIDELINE_HELPER_FIX:1;
+ gctUINT32 G2D_3rd_PARTY_COMPRESSION_1_1:1;
+ gctUINT32 TX_FLUSH_L1CACHE:1;
+ gctUINT32 PE_DITHER_FIX2:1;
+ gctUINT32 SH_TEXLD_U_FIX:1;
+ gctUINT32 MC_FCCACHE_BYTEMASK:1;
+ gctUINT32 SH_MULTI_WG_PACK_FIX:1;
+ gctUINT32 PE_ADVANCE_BLEND_PART0:1;
+ gctUINT32 FE_PATCHLIST_FETCH_FIX:1;
+ gctUINT32 RA_CG_FIX:1;
+ gctUINT32 DEC400:1;
+ gctUINT32 LS_SUPPORT_PERCOMP_DEPENDENCY:1;
+ gctUINT32 MULTI_CORE_BLOCK_SET_CONFIG2:1;
+ gctUINT32 PE_VMSAA_COVERAGE_CACHE_FIX:1;
+ gctUINT32 SECURITY_AHB:1;
+ gctUINT32 MULTICORE_SEMAPHORESTALL_V3:1;
+ gctUINT32 SMALLBATCH:1;
+ gctUINT32 SH_CMPLX:1;
+ gctUINT32 SH_IDIV0_SWZL_EHS:1;
+ gctUINT32 TX_LERP_LESS_BIT:1;
+ gctUINT32 SH_GM_ENDIAN:1;
+ gctUINT32 SH_GM_USC_UNALLOC:1;
+ gctUINT32 SH_END_OF_BB:1;
+ gctUINT32 TX_BORDER_CLAMP_FIX:1;
+ gctUINT32 SH_IMG_LD_LASTPIXEL_FIX:1;
+ gctUINT32 ASYNC_BLT:1;
+ gctUINT32 ASYNC_FE_FENCE_FIX:1;
+ gctUINT32 PSCS_THROTTLE:1;
+ gctUINT32 SEPARATE_LS:1;
+ gctUINT32 WIDELINE_TRIANGLE_EMU:1;
+ gctUINT32 FENCE_32BIT:1;
+ gctUINT32 FENCE_64BIT:1;
+ gctUINT32 PE_DEPTH_ONLY_OQFIX:1;
+ gctUINT32 TX_SEAMLESS_CUBE:1;
+ gctUINT32 TX_SNORM_SUPPORT:1;
+ gctUINT32 SH_SCATTER_GATHER:1;
+ gctUINT32 HWMANAGED_LS:1;
+ gctUINT32 SH_IMAGE_ENABLE_FIX:1;
+ gctUINT32 MSAA_FRAGMENT_OPERATION:1;
+ gctUINT32 PE_TILE_CACHE_FLUSH_FIX:1;
+ gctUINT32 BLT_YUV_OUTPUT:1;
+ gctUINT32 SH_IO_CG_FIX:1;
+ gctUINT32 PE_SWIZZLE:1;
+ gctUINT32 SH_ROBUSTNESS_FIX:1;
+ gctUINT32 USC_ATOMIC_FIX2:1;
+ gctUINT32 PE_A8B8G8R8:1;
+ gctUINT32 MULTIVIEW_RENDER:1;
+ gctUINT32 FE_DRAW_DIRECT:1;
+ gctUINT32 TX_VKBORDER_MODE:1;
+ gctUINT32 TX_UNNORMALIZED_COORD:1;
+ gctUINT32 PA_LINECLIP_FIX:1;
+ gctUINT32 TX_8bit_UVFrac_ROUNDING_FIX:1;
+ gctUINT32 MP_ARCH:1;
+ gctUINT32 VG_TS_CULLING:1;
+ gctUINT32 VG_FP25:1;
+ gctUINT32 VG_AYUV_INPUT_OUTPUT:1;
+ gctUINT32 VG_DOUBLE_IMAGE:1;
+ gctUINT32 VG_RECTANGLE_STRIPE_MODE:1;
+ gctUINT32 VG_MMU:1;
+ gctUINT32 VG_IM_FILTER:1;
+ gctUINT32 VG_IM_YUV_PACKET:1;
+ gctUINT32 VG_IM_YUV_PLANAR:1;
+ gctUINT32 VG_PE_YUV_PACKET:1;
+ gctUINT32 VG_COLOR_PRECISION_8_BIT:1;
+ gctUINT32 VG_RESOLVE_ENGINE:1;
+ gctUINT32 VG_PE_COLOR_KEY:1;
+ gctUINT32 VG_IM_INDEX_FORMAT:1;
+ gctUINT32 VG_RESOLUTION_8K:1;
+ gctUINT32 VG_IMAGE_16K:1;
+ gctUINT32 VG_FORMAT_ARGB2222:1;
+ gctUINT32 G2D_DEC400:1;
+ gctUINT32 DC_OVERLAY_SCALING:1;
+ gctUINT32 DC_SOURCE_ROTATION:1;
+ gctUINT32 DC_TILED:1;
+ gctUINT32 DC_YUV_L1:1;
+ gctUINT32 DC_D30_OUTPUT:1;
+ gctUINT32 DC_MMU:1;
+ gctUINT32 DC_COMPRESSION:1;
+ gctUINT32 DC_QOS:1;
+ gctUINT32 EVIS_NO_ABSDIFF:1;
+ gctUINT32 EVIS_NO_BITREPLACE:1;
+ gctUINT32 EVIS_NO_BOXFILTER:1;
+ gctUINT32 EVIS_NO_CORDIAC:1;
+ gctUINT32 EVIS_NO_DP32:1;
+ gctUINT32 EVIS_NO_FILTER:1;
+ gctUINT32 EVIS_NO_IADD:1;
+ gctUINT32 EVIS_NO_SELECTADD:1;
+ gctUINT32 EVIS_LERP_7OUTPUT:1;
+ gctUINT32 EVIS_ACCSQ_8OUTPUT:1;
+ gctUINT32 EVIS_VX2:1;
+ gctUINT32 NN_FLOAT:1;
+ gctUINT32 TP_ENGINE:1;
+ gctUINT32 VIP_V7:1;
+ gctUINT32 MCFE:1;
+ gctUINT32 NN_INTERLEVE8:1;
+ gctUINT32 TP_REORDER:1;
+ gctUINT32 TP_LRN:1;
+ gctUINT32 TP_MAX_POOLING_STRIDE1:1;
+ gctUINT32 NN_FP16_ALU:1;
+ gctUINT32 NN_INT16_ALU:1;
+ gctUINT32 TP_ROI_POOLING:1;
+ gctUINT32 NN_ZDP3:1;
+ gctUINT32 NN_ZDP6:1;
+ gctUINT32 NN_XYDP9:1;
+ gctUINT32 NN_INT8_SCALE:1;
+ gctUINT32 NN_POWER_ISOLATION:1;
+ gctUINT32 SWTILING_PHASE1:1;
+ gctUINT32 TF_QUANTIZATION:1;
+ gctUINT32 TP_SIMPLE_INT16:1;
+ gctUINT32 TP_REAL_INT16:1;
+ gctUINT32 NN_FIRST_PIXEL_POOLING:1;
+ gctUINT32 SWTILING_PHASE2:1;
+ gctUINT32 NN_STRIDE_SUPPORT:1;
+ gctUINT32 NN_XYDP6:1;
+ gctUINT32 TP_REORDER_FIX:1;
+ gctUINT32 NN_CONV1x1_PERF_FIX:1;
+ gctUINT32 NN_CACHELINE_MODE_PERF_FIX:1;
+ gctUINT32 NN_PER3DTILE_BUBBLE_FIX:1;
+ gctUINT32 NN_CONVOUT_FIFO_DEPTH_FIX:1;
+ gctUINT32 SWTILING_PHASE3:1;
+ gctUINT32 USC_STAY_LRU:1;
+ gctUINT32 NN_NONZERO_MIRROR_BORDER:1;
+ gctUINT32 NN_COEF_DECOMPRESS_PERF2X:1;
+ gctUINT32 INPUT_4BIT:1;
+ gctUINT32 COEF_COMPRESSION_ENHANCEMENT:1;
+ gctUINT32 NN_ZXDP3_KERNEL_READ_CONFLICT_FIX:1;
+ gctUINT32 NN_ZDP3_NO_COMPRESS_FIX:1;
+ gctUINT32 NN_ASYNC_COPY_PERF_FIX:1;
+ gctUINT32 OCB_COUNTER:1;
+ gctUINT32 NN_XYDP0:1;
+ gctUINT32 ZRL_7BIT:1;
+ gctUINT32 NN_ASYNC_COPY_MERGE_FIX:1;
+ gctUINT32 NN_SMALLBATCH_PHASE1:1;
+ gctUINT32 TP_SMALLBATCH_PHASE1:1;
+ gctUINT32 SCALER:1;
+ gctUINT32 NN_REQ_SLOWARBITRATION_FIX:1;
+ gctUINT32 IMAGE_PARTIAL_CACHE:1;
+ gctUINT32 FULLCACHE_KERNELHEAD_FIX:1;
+ gctUINT32 NN_SINGLEPORT_ACCUMBUFFER:1;
+ gctUINT32 NN_SMALLBATCH:1;
+ gctUINT32 TP_SMALLBATCH:1;
+ gctUINT32 ZRL_8BIT:1;
+ gctUINT32 NN_DEPTHWISE_SUPPORT:1;
+ gctUINT32 NN_WRITE_WITHOUT_USC:1;
+ gctUINT32 NN_ZDP_INIMAGE_SIZE_FIX:1;
+ gctUINT32 HI_REORDER_FIX:1;
+ gctUINT32 TP_COEF_COMPRESSION_ENHANCEMENT:1;
+ gctUINT32 VIP_DEC400:1;
+} gcsFEATURE_DATABASE;
+
+static gcsFEATURE_DATABASE gChipInfo[] = {
+ /* dc0000_5550 */
+ {
+ 0x0, /* ChipID */
+ 0x5550, /* ChipRevision */
+ 0x12000000, /* ProductID */
+ 0x0, /* EcoID */
+ 0x300, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x0, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x100, /* gcFEATURE_VALUE_ThreadCount */
+ 0x1, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x100, /* gcFEATURE_VALUE_InstructionCount */
+ 0xa8, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x0, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x0, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x0, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x0, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x0, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x1, /* gcFEATURE_VALUE_Streams */
+ 0x8, /* gcFEATURE_VALUE_VaryingCount */
+ 0x200, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x8, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x1, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x0, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x0, /* gcFEATURE_BIT_REG_FastClear */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x0, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x1, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x0, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x1, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x0, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x0, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x0, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x0, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x0, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x0, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x0, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x0, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x0, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x0, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x0, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x0, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x0, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x0, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x0, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x0, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x0, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x0, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x0, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x0, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x1, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x0, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x0, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x0, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x0, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x0, /* gcFEATURE_BIT_REG_Generics */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x0, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x0, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_ACE */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x0, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x0, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x1, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x0, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x0, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x1, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x0, /* gcFEATURE_BIT_REG_EEZ */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x1, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x0, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x0, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x0, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x0, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x0, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x0, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x0, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x0, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x0, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x0, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x0, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x0, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x0, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x0, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x0, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x0, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x0, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x0, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x0, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x0, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x0, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x0, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x0, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x0, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x0, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x0, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x0, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY */
+ 0x0, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x0, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x0, /* gcFEATURE_BIT_DRAWID */
+ 0x0, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x0, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x0, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x0, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x0, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x0, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x0, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x1, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x1, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x1, /* gcFEATURE_BIT_DC_MMU */
+ 0x1, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x1, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x0, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x0, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* dc0000_5560 */
+ {
+ 0x0, /* ChipID */
+ 0x5560, /* ChipRevision */
+ 0x2000002, /* ProductID */
+ 0x0, /* EcoID */
+ 0x302, /* CustomerID */
+ 0x3, /* PatchVersion */
+ "", /* ProductName */
+ 0x0, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x100, /* gcFEATURE_VALUE_ThreadCount */
+ 0x1, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x100, /* gcFEATURE_VALUE_InstructionCount */
+ 0xa8, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x0, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x0, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x0, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x0, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x0, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x1, /* gcFEATURE_VALUE_Streams */
+ 0x8, /* gcFEATURE_VALUE_VaryingCount */
+ 0x200, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x8, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x1, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x0, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x0, /* gcFEATURE_BIT_REG_FastClear */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x0, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x1, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x0, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x1, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x0, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x0, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x0, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x0, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x0, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x0, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x0, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x0, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x0, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x0, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x0, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x0, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x0, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x0, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x0, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x0, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x0, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x0, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x0, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x0, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x1, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x0, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x0, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x0, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x0, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x0, /* gcFEATURE_BIT_REG_Generics */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x0, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x0, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_ACE */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x0, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x0, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x1, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x0, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x0, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x1, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x0, /* gcFEATURE_BIT_REG_EEZ */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x1, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x0, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x0, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x0, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x0, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x0, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x0, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x0, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x0, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x0, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x0, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x0, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x0, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x0, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x0, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x0, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x0, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x0, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x0, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x0, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x0, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x0, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x0, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x0, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x0, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x0, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x0, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x0, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY */
+ 0x0, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x0, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x0, /* gcFEATURE_BIT_DRAWID */
+ 0x0, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x0, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x0, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x0, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x0, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x0, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x0, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x1, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x1, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x1, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x0, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x0, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* gc200_4650 */
+ {
+ 0x200, /* ChipID */
+ 0x4650, /* ChipRevision */
+ 0x0, /* ProductID */
+ 0x0, /* EcoID */
+ 0x0, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x0, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x100, /* gcFEATURE_VALUE_ThreadCount */
+ 0x1, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x100, /* gcFEATURE_VALUE_InstructionCount */
+ 0xa8, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x0, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x0, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x0, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x0, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x0, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x1, /* gcFEATURE_VALUE_Streams */
+ 0x8, /* gcFEATURE_VALUE_VaryingCount */
+ 0x200, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x8, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x1, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x0, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x0, /* gcFEATURE_BIT_REG_FastClear */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x0, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x1, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x0, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x1, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x0, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x0, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x0, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x0, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x0, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x0, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x0, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x0, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x0, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x0, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x0, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x0, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x0, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x0, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x0, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x0, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x0, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x0, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x0, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x0, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x1, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x0, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x0, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x0, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x0, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x0, /* gcFEATURE_BIT_REG_Generics */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x0, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x0, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_ACE */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x0, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x0, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x1, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x0, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x0, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x1, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x0, /* gcFEATURE_BIT_REG_EEZ */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x1, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x0, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x0, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x0, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x0, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x0, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x0, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x0, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x0, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x0, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x0, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x0, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x0, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x0, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x0, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x0, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x0, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x0, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x0, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x0, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x0, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x0, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x0, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x0, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x0, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x0, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x0, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x0, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY */
+ 0x0, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x0, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x0, /* gcFEATURE_BIT_DRAWID */
+ 0x0, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x0, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x0, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x0, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x0, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x0, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x0, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x0, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x0, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* gc200_4621 */
+ {
+ 0x200, /* ChipID */
+ 0x4621, /* ChipRevision */
+ 0x0, /* ProductID */
+ 0x0, /* EcoID */
+ 0x0, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x0, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x100, /* gcFEATURE_VALUE_ThreadCount */
+ 0x1, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x100, /* gcFEATURE_VALUE_InstructionCount */
+ 0xa8, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x0, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x0, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x0, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x0, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x0, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x1, /* gcFEATURE_VALUE_Streams */
+ 0x8, /* gcFEATURE_VALUE_VaryingCount */
+ 0x200, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x8, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x1, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x0, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x0, /* gcFEATURE_BIT_REG_FastClear */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x0, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x1, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x0, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x1, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x0, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x0, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x0, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x0, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x0, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x0, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x0, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x0, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x0, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x0, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x0, /* gcFEATURE_BIT_REG_MMU */
+ 0x0, /* gcFEATURE_BIT_REG_WideLine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x0, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x0, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x0, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x0, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x0, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x0, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x0, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x0, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x0, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x0, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x0, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x0, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x0, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x0, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x0, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x0, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x0, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x0, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x0, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x0, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x0, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x0, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x0, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x0, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x0, /* gcFEATURE_BIT_REG_Generics */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x0, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x0, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_ACE */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x0, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x0, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x0, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x0, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x0, /* gcFEATURE_BIT_REG_EEZ */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x0, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x0, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x0, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x0, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x0, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x0, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x0, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x0, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x0, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x0, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x0, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x0, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x0, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x0, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x0, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x0, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x0, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x0, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x0, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x0, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x0, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x0, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x0, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x0, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x0, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x0, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x0, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY */
+ 0x0, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x0, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x0, /* gcFEATURE_BIT_DRAWID */
+ 0x0, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x0, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x0, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x0, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x0, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x0, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x0, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x0, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x0, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* gc300_4650 */
+ {
+ 0x300, /* ChipID */
+ 0x4650, /* ChipRevision */
+ 0x5203, /* ProductID */
+ 0x0, /* EcoID */
+ 0x0, /* CustomerID */
+ 0x5, /* PatchVersion */
+ "", /* ProductName */
+ 0x1, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x100, /* gcFEATURE_VALUE_ThreadCount */
+ 0x1, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x100, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x0, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x0, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x0, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x0, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x0, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x4, /* gcFEATURE_VALUE_Streams */
+ 0x8, /* gcFEATURE_VALUE_VaryingCount */
+ 0x200, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x8, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x1, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x0, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x0, /* gcFEATURE_BIT_REG_FastClear */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x0, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x1, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x0, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x1, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x0, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x0, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x0, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x0, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x0, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x0, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x0, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x0, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x0, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x0, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x0, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x0, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x0, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x0, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x0, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x0, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x0, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x0, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x0, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x1, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x0, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x0, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x0, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x0, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x0, /* gcFEATURE_BIT_REG_Generics */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x0, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x0, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_ACE */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x0, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x0, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x1, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x0, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x0, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x1, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x0, /* gcFEATURE_BIT_REG_EEZ */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x1, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x0, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x0, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x0, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x0, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x0, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x0, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x0, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x0, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x0, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x0, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x0, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x0, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x0, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x0, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x0, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x0, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x0, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x0, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x0, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x0, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x0, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x0, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x0, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x0, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x0, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x0, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY */
+ 0x0, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x0, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x0, /* gcFEATURE_BIT_DRAWID */
+ 0x0, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x0, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x0, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x0, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x0, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x0, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x0, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x0, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x0, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* gc300_4650_guoke */
+ {
+ 0x300, /* ChipID */
+ 0x4650, /* ChipRevision */
+ 0x0, /* ProductID */
+ 0x0, /* EcoID */
+ 0x0, /* CustomerID */
+ 0x4, /* PatchVersion */
+ "", /* ProductName */
+ 0x1, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x100, /* gcFEATURE_VALUE_ThreadCount */
+ 0x1, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x100, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x0, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x0, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x0, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x0, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x0, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x4, /* gcFEATURE_VALUE_Streams */
+ 0x8, /* gcFEATURE_VALUE_VaryingCount */
+ 0x200, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x8, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x1, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x0, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x0, /* gcFEATURE_BIT_REG_FastClear */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x0, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x1, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x0, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x1, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x0, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x0, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x0, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x0, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x0, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x0, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x0, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x0, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x0, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x0, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x0, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x0, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x0, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x0, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x0, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x0, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x0, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x0, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x0, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x1, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x0, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x0, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x0, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x0, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x0, /* gcFEATURE_BIT_REG_Generics */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x0, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x0, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_ACE */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x0, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x0, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x1, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x0, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x0, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x1, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x0, /* gcFEATURE_BIT_REG_EEZ */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x1, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x0, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x0, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x0, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x0, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x0, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x0, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x0, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x0, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x0, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x0, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x0, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x0, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x0, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x0, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x0, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x0, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x0, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x0, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x0, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x0, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x0, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x0, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x0, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x0, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x0, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x0, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY */
+ 0x0, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x0, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x0, /* gcFEATURE_BIT_DRAWID */
+ 0x0, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x0, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x0, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x0, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x0, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x0, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x0, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x0, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x0, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* gc300_4_6_6_rc0 */
+ {
+ 0x300, /* ChipID */
+ 0x4660, /* ChipRevision */
+ 0x5203, /* ProductID */
+ 0x0, /* EcoID */
+ 0x0, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x0, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x100, /* gcFEATURE_VALUE_ThreadCount */
+ 0x1, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x100, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x0, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x0, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x0, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x0, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x0, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x4, /* gcFEATURE_VALUE_Streams */
+ 0x8, /* gcFEATURE_VALUE_VaryingCount */
+ 0x200, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x8, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x1, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x0, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x0, /* gcFEATURE_BIT_REG_FastClear */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x0, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x1, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x0, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x1, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x0, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x0, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x0, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x0, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x0, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x0, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x0, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x0, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x0, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x0, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x0, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x0, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x0, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x0, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x0, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x0, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x0, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x0, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x0, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x1, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x0, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x0, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x0, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x0, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x0, /* gcFEATURE_BIT_REG_Generics */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x0, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x0, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_ACE */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x0, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x0, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x1, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x0, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x0, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x1, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x0, /* gcFEATURE_BIT_REG_EEZ */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x1, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x0, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x0, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x0, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x0, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x0, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x0, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x0, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x0, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x0, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x0, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x0, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x0, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x0, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x0, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x0, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x0, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x0, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x0, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x0, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x0, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x0, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x0, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x0, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x0, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x0, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x0, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x0, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY */
+ 0x0, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x0, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x0, /* gcFEATURE_BIT_DRAWID */
+ 0x0, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x0, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x0, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x0, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x1, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x0, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x0, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x0, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x0, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x0, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* gc320_5007 */
+ {
+ 0x320, /* ChipID */
+ 0x5007, /* ChipRevision */
+ 0x0, /* ProductID */
+ 0x0, /* EcoID */
+ 0x0, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x1, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x400, /* gcFEATURE_VALUE_ThreadCount */
+ 0x4, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x100, /* gcFEATURE_VALUE_InstructionCount */
+ 0x100, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x0, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x0, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x0, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x0, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x2, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x0, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x1, /* gcFEATURE_VALUE_Streams */
+ 0x8, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x8, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x1, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x0, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x0, /* gcFEATURE_BIT_REG_FastClear */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x0, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x1, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x0, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x0, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x0, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x1, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x0, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x0, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x0, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x0, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x0, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x0, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x0, /* gcFEATURE_BIT_REG_MMU */
+ 0x0, /* gcFEATURE_BIT_REG_WideLine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x0, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x0, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x0, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x0, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x0, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x0, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x0, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x0, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x0, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x0, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x0, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x0, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x0, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x0, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x0, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x0, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x0, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x0, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x0, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x0, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x0, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x0, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x0, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x0, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x0, /* gcFEATURE_BIT_REG_Generics */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x0, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x0, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_ACE */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x0, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x0, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x0, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x0, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x0, /* gcFEATURE_BIT_REG_EEZ */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x0, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x0, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x0, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x0, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x0, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x0, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x0, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x0, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x0, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x0, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x0, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x0, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x0, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x0, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x0, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x0, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x0, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x0, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x0, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x0, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x0, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x0, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x0, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x0, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x0, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x0, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY */
+ 0x0, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x0, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x0, /* gcFEATURE_BIT_DRAWID */
+ 0x0, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x0, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x0, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x0, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x0, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x0, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x0, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x0, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x0, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* gc320_5220 */
+ {
+ 0x320, /* ChipID */
+ 0x5220, /* ChipRevision */
+ 0x0, /* ProductID */
+ 0x0, /* EcoID */
+ 0x0, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x1, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x100, /* gcFEATURE_VALUE_ThreadCount */
+ 0x1, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x100, /* gcFEATURE_VALUE_InstructionCount */
+ 0xa8, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x0, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x0, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x0, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x0, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x0, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x1, /* gcFEATURE_VALUE_Streams */
+ 0x8, /* gcFEATURE_VALUE_VaryingCount */
+ 0x200, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x8, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x1, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x0, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x0, /* gcFEATURE_BIT_REG_FastClear */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x0, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x1, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x0, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x0, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x0, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x1, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x0, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x0, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x0, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x0, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x0, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x0, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x0, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x0, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x0, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x0, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x0, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x0, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x0, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x1, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x1, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x1, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x0, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x0, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x0, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x0, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x0, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x0, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x0, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x0, /* gcFEATURE_BIT_REG_Generics */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x0, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x0, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_ACE */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x0, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x0, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x0, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x0, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x0, /* gcFEATURE_BIT_REG_EEZ */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x0, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x0, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x0, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x0, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x0, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x0, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x0, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x0, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x0, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x0, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x0, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x0, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x0, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x0, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x0, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x0, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x0, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x0, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x0, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x0, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x0, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x0, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x0, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x0, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x0, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x0, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY */
+ 0x0, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x0, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x0, /* gcFEATURE_BIT_DRAWID */
+ 0x0, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x0, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x0, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x0, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x0, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x0, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x0, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x0, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x0, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* gc320_5303 */
+ {
+ 0x320, /* ChipID */
+ 0x5303, /* ChipRevision */
+ 0x0, /* ProductID */
+ 0x0, /* EcoID */
+ 0x0, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x1, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x100, /* gcFEATURE_VALUE_ThreadCount */
+ 0x1, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x100, /* gcFEATURE_VALUE_InstructionCount */
+ 0xa8, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x0, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x0, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x0, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x0, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x0, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x1, /* gcFEATURE_VALUE_Streams */
+ 0x8, /* gcFEATURE_VALUE_VaryingCount */
+ 0x200, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x8, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x1, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x0, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x0, /* gcFEATURE_BIT_REG_FastClear */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x0, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x1, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x0, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x1, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x0, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x0, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x1, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x0, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x0, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x0, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x0, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x0, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x0, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x0, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x0, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x0, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x0, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x0, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x0, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x0, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x1, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x1, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x1, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x0, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x1, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x0, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x0, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x0, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x0, /* gcFEATURE_BIT_REG_Generics */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x0, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x0, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_ACE */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x0, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x0, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x0, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x0, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x0, /* gcFEATURE_BIT_REG_EEZ */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x0, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x0, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x0, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x0, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x0, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x0, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x0, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x0, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x0, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x0, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x0, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x0, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x0, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x0, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x0, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x0, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x0, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x0, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x0, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x0, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x0, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x0, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x0, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x0, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x0, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x0, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY */
+ 0x0, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x0, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x0, /* gcFEATURE_BIT_DRAWID */
+ 0x0, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x0, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x0, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x0, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x0, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x0, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x0, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x0, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x0, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* gc320_5303_1 */
+ {
+ 0x320, /* ChipID */
+ 0x5303, /* ChipRevision */
+ 0x5202, /* ProductID */
+ 0x1, /* EcoID */
+ 0x0, /* CustomerID */
+ 0x4, /* PatchVersion */
+ "", /* ProductName */
+ 0x1, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x100, /* gcFEATURE_VALUE_ThreadCount */
+ 0x1, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x100, /* gcFEATURE_VALUE_InstructionCount */
+ 0xa8, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x0, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x0, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x0, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x0, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x0, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x1, /* gcFEATURE_VALUE_Streams */
+ 0x8, /* gcFEATURE_VALUE_VaryingCount */
+ 0x200, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x8, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x1, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x0, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x0, /* gcFEATURE_BIT_REG_FastClear */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x0, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x1, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x0, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x1, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x0, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x0, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x1, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x0, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x0, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x0, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x0, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x0, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x0, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x0, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x0, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x0, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x0, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x0, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x0, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x0, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x1, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x1, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x1, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x0, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x1, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x0, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x0, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x0, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x0, /* gcFEATURE_BIT_REG_Generics */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x0, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x0, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_ACE */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x0, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x0, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x0, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x0, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x0, /* gcFEATURE_BIT_REG_EEZ */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x0, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x0, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x0, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x0, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x0, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x0, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x0, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x0, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x0, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x0, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x0, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x0, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x0, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x0, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x0, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x0, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x0, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x0, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x0, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x0, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x0, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x0, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x0, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x0, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x0, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY */
+ 0x0, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x0, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x0, /* gcFEATURE_BIT_DRAWID */
+ 0x0, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x0, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x0, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x0, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x0, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x0, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x0, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x0, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x0, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* gc320_5340 */
+ {
+ 0x320, /* ChipID */
+ 0x5340, /* ChipRevision */
+ 0x0, /* ProductID */
+ 0x0, /* EcoID */
+ 0x0, /* CustomerID */
+ 0x4, /* PatchVersion */
+ "", /* ProductName */
+ 0x1, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x100, /* gcFEATURE_VALUE_ThreadCount */
+ 0x1, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x100, /* gcFEATURE_VALUE_InstructionCount */
+ 0xa8, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x0, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x0, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x0, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x0, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x0, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x1, /* gcFEATURE_VALUE_Streams */
+ 0x8, /* gcFEATURE_VALUE_VaryingCount */
+ 0x200, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x8, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x1, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x0, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x0, /* gcFEATURE_BIT_REG_FastClear */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x0, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x1, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x0, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x1, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x0, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x0, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x1, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x0, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x0, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x0, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x0, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x0, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x0, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x0, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x0, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x0, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x0, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x0, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x0, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x0, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x1, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x1, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x1, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x0, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x1, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x0, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x0, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x0, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x0, /* gcFEATURE_BIT_REG_Generics */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x0, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x0, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_ACE */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x0, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x0, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x0, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x1, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x0, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x0, /* gcFEATURE_BIT_REG_EEZ */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x0, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x0, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x0, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x0, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x0, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x0, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x0, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x0, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x0, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x0, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x0, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x0, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x0, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x0, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x0, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x0, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x0, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x0, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x0, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x0, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x0, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x0, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x0, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x0, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x0, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x0, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY */
+ 0x0, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x0, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x0, /* gcFEATURE_BIT_DRAWID */
+ 0x0, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x0, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x0, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x0, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x0, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x0, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x0, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x0, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x0, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* gc320c_5341 */
+ {
+ 0x320, /* ChipID */
+ 0x5341, /* ChipRevision */
+ 0x0, /* ProductID */
+ 0x0, /* EcoID */
+ 0x0, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x0, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x100, /* gcFEATURE_VALUE_ThreadCount */
+ 0x1, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x100, /* gcFEATURE_VALUE_InstructionCount */
+ 0xa8, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x0, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x0, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x0, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x0, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x0, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x1, /* gcFEATURE_VALUE_Streams */
+ 0xc, /* gcFEATURE_VALUE_VaryingCount */
+ 0x200, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x8, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x1, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x0, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x0, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x1, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x1, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x1, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x0, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x1, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x0, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x0, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x0, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x1, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x0, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x0, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x0, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x0, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x0, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x0, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x0, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x0, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x0, /* gcFEATURE_BIT_REG_Generics */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x0, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x0, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_ACE */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x0, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x0, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x0, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x0, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x0, /* gcFEATURE_BIT_REG_EEZ */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x0, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x0, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x0, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x0, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x0, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x0, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x0, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x0, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x0, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x1, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x1, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x1, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x0, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x1, /* gcFEATURE_BIT_V4Compression */
+ 0x1, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x0, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x0, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x0, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x0, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x0, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x0, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x0, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x0, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x0, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x0, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x0, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x0, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x0, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY */
+ 0x0, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x0, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x0, /* gcFEATURE_BIT_DRAWID */
+ 0x0, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x0, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x0, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x0, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x0, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x0, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x0, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x0, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x0, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* gc320_5341 */
+ {
+ 0x320, /* ChipID */
+ 0x5341, /* ChipRevision */
+ 0x3202, /* ProductID */
+ 0x0, /* EcoID */
+ 0x0, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x0, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x100, /* gcFEATURE_VALUE_ThreadCount */
+ 0x1, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x100, /* gcFEATURE_VALUE_InstructionCount */
+ 0xa8, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x0, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x0, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x0, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x0, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x0, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x1, /* gcFEATURE_VALUE_Streams */
+ 0x8, /* gcFEATURE_VALUE_VaryingCount */
+ 0x200, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x8, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x1, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x0, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x0, /* gcFEATURE_BIT_REG_FastClear */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x0, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x1, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x0, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x1, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x0, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x0, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x1, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x0, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x0, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x0, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x0, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x0, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x0, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x0, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x0, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x0, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x0, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x0, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x0, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x0, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x1, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x1, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x0, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x1, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x0, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x0, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x0, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x0, /* gcFEATURE_BIT_REG_Generics */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x0, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x0, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_ACE */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x0, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x0, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x0, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x0, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x0, /* gcFEATURE_BIT_REG_EEZ */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x1, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x0, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x0, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x0, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x0, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x0, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x0, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x0, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x0, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x0, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x0, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x0, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x0, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x0, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x0, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x0, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x0, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x0, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x0, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x0, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x0, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x0, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x0, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x0, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x0, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x0, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY */
+ 0x0, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x0, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x0, /* gcFEATURE_BIT_DRAWID */
+ 0x0, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x0, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x0, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x0, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x0, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x0, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x0, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x0, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x0, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* gc520l_5_3_5_rc0 */
+ {
+ 0x320, /* ChipID */
+ 0x5350, /* ChipRevision */
+ 0x5202, /* ProductID */
+ 0x0, /* EcoID */
+ 0x206, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x0, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x100, /* gcFEATURE_VALUE_ThreadCount */
+ 0x1, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x100, /* gcFEATURE_VALUE_InstructionCount */
+ 0xa8, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x0, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x0, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x0, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x0, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x0, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x1, /* gcFEATURE_VALUE_Streams */
+ 0x8, /* gcFEATURE_VALUE_VaryingCount */
+ 0x200, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x8, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x1, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x0, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x0, /* gcFEATURE_BIT_REG_FastClear */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x0, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x1, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x0, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x1, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x0, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x0, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x1, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x0, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x0, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x0, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x0, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x0, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x0, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x0, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x0, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x0, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x0, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x0, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x0, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x0, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x1, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x1, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x1, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x0, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x1, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x0, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x0, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x0, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x0, /* gcFEATURE_BIT_REG_Generics */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x0, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x0, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_ACE */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x0, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x0, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x0, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x0, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x0, /* gcFEATURE_BIT_REG_EEZ */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x0, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x0, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x0, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x0, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x0, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x0, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x0, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x0, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x0, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x0, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x0, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x0, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x0, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x0, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x0, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x0, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x0, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x0, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x0, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x0, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x0, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x0, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x0, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x0, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x0, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY */
+ 0x0, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x0, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x0, /* gcFEATURE_BIT_DRAWID */
+ 0x0, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x0, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x0, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x0, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x0, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x0, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x0, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x0, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x0, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* gc355_v121_rc5 */
+ {
+ 0x355, /* ChipID */
+ 0x1215, /* ChipRevision */
+ 0x0, /* ProductID */
+ 0x0, /* EcoID */
+ 0x0, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x0, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x100, /* gcFEATURE_VALUE_ThreadCount */
+ 0x1, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x100, /* gcFEATURE_VALUE_InstructionCount */
+ 0xa8, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x0, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x0, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x0, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x0, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x0, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x1, /* gcFEATURE_VALUE_Streams */
+ 0x8, /* gcFEATURE_VALUE_VaryingCount */
+ 0x200, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x8, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x1, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x0, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x0, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x0, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x1, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x1, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x1, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x1, /* gcFEATURE_BIT_REG_VGTS */
+ 0x1, /* gcFEATURE_BIT_REG_FE20 */
+ 0x0, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x0, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x0, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x0, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x0, /* gcFEATURE_BIT_REG_Render8K */
+ 0x0, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x0, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x0, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x1, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x0, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x1, /* gcFEATURE_BIT_REG_VG21 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x0, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x0, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x0, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x1, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x1, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x0, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x0, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x0, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x0, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x0, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x0, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x0, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x0, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x0, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x0, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x0, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x0, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x0, /* gcFEATURE_BIT_REG_MMU */
+ 0x0, /* gcFEATURE_BIT_REG_WideLine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x0, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x0, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x0, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x0, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x0, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x0, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x0, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x0, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x0, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x0, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x0, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x0, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x0, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x0, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x0, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x0, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x0, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x0, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x0, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x0, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x0, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x0, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x0, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x0, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x0, /* gcFEATURE_BIT_REG_Generics */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x0, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x0, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_ACE */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x0, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x0, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x0, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x0, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x0, /* gcFEATURE_BIT_REG_EEZ */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x0, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x0, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x0, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x0, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x0, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x0, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x0, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x0, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x0, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x0, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x0, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x0, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x0, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x0, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x0, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x0, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x0, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x0, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x0, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x0, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x0, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x0, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x0, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x0, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x0, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x0, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x0, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY */
+ 0x0, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x0, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x0, /* gcFEATURE_BIT_DRAWID */
+ 0x0, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x0, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x0, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x0, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x0, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x0, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x0, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x0, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x0, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* gc355_v121x */
+ {
+ 0x355, /* ChipID */
+ 0x1217, /* ChipRevision */
+ 0x3003550, /* ProductID */
+ 0x0, /* EcoID */
+ 0x0, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x0, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x100, /* gcFEATURE_VALUE_ThreadCount */
+ 0x1, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x100, /* gcFEATURE_VALUE_InstructionCount */
+ 0xa8, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x0, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x0, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x0, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x0, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x0, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x1, /* gcFEATURE_VALUE_Streams */
+ 0x8, /* gcFEATURE_VALUE_VaryingCount */
+ 0x200, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x8, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x1, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x0, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x0, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x0, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x1, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x1, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x1, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x1, /* gcFEATURE_BIT_REG_VGTS */
+ 0x1, /* gcFEATURE_BIT_REG_FE20 */
+ 0x0, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x0, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x0, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x0, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x0, /* gcFEATURE_BIT_REG_Render8K */
+ 0x0, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x0, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x0, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x1, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x0, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x1, /* gcFEATURE_BIT_REG_VG21 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x0, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x0, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x0, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x1, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x1, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x0, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x0, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x0, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x0, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x0, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x0, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x0, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x0, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x0, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x0, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x0, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x0, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x0, /* gcFEATURE_BIT_REG_MMU */
+ 0x0, /* gcFEATURE_BIT_REG_WideLine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x0, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x0, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x0, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x0, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x0, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x0, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x0, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x0, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x0, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x0, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x0, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x0, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x0, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x0, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x0, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x0, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x0, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x0, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x0, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x0, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x0, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x0, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x0, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x0, /* gcFEATURE_BIT_REG_Generics */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x0, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x0, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_ACE */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x0, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x0, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x0, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x0, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x0, /* gcFEATURE_BIT_REG_EEZ */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x0, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x0, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x0, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x0, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x0, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x0, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x0, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x0, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x0, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x0, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x0, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x0, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x0, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x0, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x0, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x0, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x0, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x0, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x0, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x0, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x0, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x0, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x0, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x0, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x0, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x0, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x0, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY */
+ 0x0, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x0, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x0, /* gcFEATURE_BIT_DRAWID */
+ 0x0, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x0, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x0, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x0, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x0, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x0, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x0, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x1, /* gcFEATURE_BIT_VG_MMU */
+ 0x1, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x1, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x1, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x1, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x1, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x1, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x1, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x0, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x0, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* gc355_8Kx8K */
+ {
+ 0x355, /* ChipID */
+ 0x1217, /* ChipRevision */
+ 0x3003550, /* ProductID */
+ 0x0, /* EcoID */
+ 0x407, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x0, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x100, /* gcFEATURE_VALUE_ThreadCount */
+ 0x1, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x100, /* gcFEATURE_VALUE_InstructionCount */
+ 0xa8, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x0, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x0, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x0, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x0, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x0, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x1, /* gcFEATURE_VALUE_Streams */
+ 0x8, /* gcFEATURE_VALUE_VaryingCount */
+ 0x200, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x8, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x1, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x0, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x0, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x0, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x1, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x1, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x1, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x1, /* gcFEATURE_BIT_REG_VGTS */
+ 0x1, /* gcFEATURE_BIT_REG_FE20 */
+ 0x0, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x0, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x0, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x0, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x0, /* gcFEATURE_BIT_REG_Render8K */
+ 0x0, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x0, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x0, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x1, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x0, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x1, /* gcFEATURE_BIT_REG_VG21 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x0, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x0, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x0, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x1, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x1, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x0, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x0, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x0, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x0, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x0, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x0, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x0, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x0, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x0, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x0, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x0, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x0, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x0, /* gcFEATURE_BIT_REG_MMU */
+ 0x0, /* gcFEATURE_BIT_REG_WideLine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x0, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x0, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x0, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x0, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x0, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x0, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x0, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x0, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x0, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x0, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x0, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x0, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x0, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x0, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x0, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x0, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x0, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x0, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x0, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x0, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x0, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x0, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x0, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x0, /* gcFEATURE_BIT_REG_Generics */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x0, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x0, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_ACE */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x0, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x0, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x0, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x0, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x0, /* gcFEATURE_BIT_REG_EEZ */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x0, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x0, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x0, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x0, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x0, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x0, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x0, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x0, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x0, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x0, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x0, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x0, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x0, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x0, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x0, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x0, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x0, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x0, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x0, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x0, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x0, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x0, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x0, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x0, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x0, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x0, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x0, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY */
+ 0x0, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x0, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x0, /* gcFEATURE_BIT_DRAWID */
+ 0x0, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x0, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x0, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x0, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x0, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x0, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x0, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x1, /* gcFEATURE_BIT_VG_MMU */
+ 0x1, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x1, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x1, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x1, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x1, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x1, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x1, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x1, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x0, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x0, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* gc355_16K */
+ {
+ 0x355, /* ChipID */
+ 0x1217, /* ChipRevision */
+ 0x3003550, /* ProductID */
+ 0x0, /* EcoID */
+ 0x408, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x0, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x100, /* gcFEATURE_VALUE_ThreadCount */
+ 0x1, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x100, /* gcFEATURE_VALUE_InstructionCount */
+ 0xa8, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x0, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x0, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x0, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x0, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x0, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x1, /* gcFEATURE_VALUE_Streams */
+ 0x8, /* gcFEATURE_VALUE_VaryingCount */
+ 0x200, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x8, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x1, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x0, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x0, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x0, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x1, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x1, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x1, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x1, /* gcFEATURE_BIT_REG_VGTS */
+ 0x1, /* gcFEATURE_BIT_REG_FE20 */
+ 0x0, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x0, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x0, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x0, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x0, /* gcFEATURE_BIT_REG_Render8K */
+ 0x0, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x0, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x0, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x1, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x0, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x1, /* gcFEATURE_BIT_REG_VG21 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x0, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x0, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x0, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x1, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x1, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x0, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x0, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x0, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x0, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x0, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x0, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x0, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x0, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x0, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x0, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x0, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x0, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x0, /* gcFEATURE_BIT_REG_MMU */
+ 0x0, /* gcFEATURE_BIT_REG_WideLine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x0, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x0, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x0, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x0, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x0, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x0, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x0, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x0, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x0, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x0, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x0, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x0, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x0, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x0, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x0, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x0, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x0, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x0, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x0, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x0, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x0, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x0, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x0, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x0, /* gcFEATURE_BIT_REG_Generics */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x0, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x0, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_ACE */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x0, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x0, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x0, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x0, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x0, /* gcFEATURE_BIT_REG_EEZ */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x0, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x0, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x0, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x0, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x0, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x0, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x0, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x0, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x0, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x0, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x0, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x0, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x0, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x0, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x0, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x0, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x0, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x0, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x0, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x0, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x0, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x0, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x0, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x0, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x0, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x0, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x0, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY */
+ 0x0, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x0, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x0, /* gcFEATURE_BIT_DRAWID */
+ 0x0, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x0, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x0, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x0, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x0, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x0, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x0, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x1, /* gcFEATURE_BIT_VG_MMU */
+ 0x1, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x1, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x1, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x1, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x1, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x1, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x1, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x1, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x1, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x0, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x0, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* gc400_4633 */
+ {
+ 0x400, /* ChipID */
+ 0x4633, /* ChipRevision */
+ 0x0, /* ProductID */
+ 0x0, /* EcoID */
+ 0x0, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x1, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x80, /* gcFEATURE_VALUE_ThreadCount */
+ 0x1, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x100, /* gcFEATURE_VALUE_InstructionCount */
+ 0xa8, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x0, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x0, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x0, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x0, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x0, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x4, /* gcFEATURE_VALUE_Streams */
+ 0x8, /* gcFEATURE_VALUE_VaryingCount */
+ 0x80, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x8, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x1, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x0, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x0, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x0, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x0, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x0, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x1, /* gcFEATURE_BIT_REG_MinArea */
+ 0x1, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x1, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x0, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x0, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x1, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x0, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x0, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x0, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x0, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x0, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x0, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x0, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x0, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x0, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x0, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x0, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x0, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x0, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x0, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x0, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x0, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x0, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x0, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x0, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x0, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x0, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x0, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x0, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x0, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x0, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x0, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x0, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x0, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x0, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x0, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x0, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x0, /* gcFEATURE_BIT_REG_Generics */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x0, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x0, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_ACE */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x0, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x0, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x0, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x0, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x0, /* gcFEATURE_BIT_REG_EEZ */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x0, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x0, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x0, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x0, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x0, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x0, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x0, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x0, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x0, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x0, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x0, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x0, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x0, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x0, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x0, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x0, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x0, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x0, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x0, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x0, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x0, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x0, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x0, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x0, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x0, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x0, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x0, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY */
+ 0x0, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x0, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x0, /* gcFEATURE_BIT_DRAWID */
+ 0x0, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x0, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x0, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x0, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x0, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x0, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x0, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x0, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x0, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* gc600_4633 */
+ {
+ 0x600, /* ChipID */
+ 0x4633, /* ChipRevision */
+ 0x0, /* ProductID */
+ 0x0, /* EcoID */
+ 0x0, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x1, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x80, /* gcFEATURE_VALUE_ThreadCount */
+ 0x1, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x100, /* gcFEATURE_VALUE_InstructionCount */
+ 0xa8, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x0, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x0, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x0, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x0, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x0, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x4, /* gcFEATURE_VALUE_Streams */
+ 0x8, /* gcFEATURE_VALUE_VaryingCount */
+ 0x80, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x8, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x1, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x0, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x0, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x0, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x0, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x1, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x0, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x0, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x0, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x0, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x0, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x0, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x0, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x0, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x0, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x0, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x0, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x0, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x0, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x0, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x0, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x0, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x0, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x0, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x0, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x0, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x0, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x0, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x0, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x0, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x0, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x0, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x0, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x0, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x0, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x0, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x0, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x0, /* gcFEATURE_BIT_REG_Generics */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x0, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x0, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_ACE */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x0, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x0, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x0, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x0, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x0, /* gcFEATURE_BIT_REG_EEZ */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x0, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x0, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x0, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x0, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x0, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x0, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x0, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x0, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x0, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x0, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x0, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x0, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x0, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x0, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x0, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x0, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x0, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x0, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x0, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x0, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x0, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x0, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x0, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x0, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x0, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x0, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x0, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY */
+ 0x0, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x0, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x0, /* gcFEATURE_BIT_DRAWID */
+ 0x0, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x0, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x0, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x0, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x0, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x0, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x1, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x0, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x0, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x0, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* gc400_4645 */
+ {
+ 0x400, /* ChipID */
+ 0x4645, /* ChipRevision */
+ 0x0, /* ProductID */
+ 0x0, /* EcoID */
+ 0x0, /* CustomerID */
+ 0x4, /* PatchVersion */
+ "", /* ProductName */
+ 0x1, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x80, /* gcFEATURE_VALUE_ThreadCount */
+ 0x1, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x100, /* gcFEATURE_VALUE_InstructionCount */
+ 0x240, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x0, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x0, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x0, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x0, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x0, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x4, /* gcFEATURE_VALUE_Streams */
+ 0x8, /* gcFEATURE_VALUE_VaryingCount */
+ 0x80, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x8, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x1, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x0, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x0, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x1, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x1, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x0, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x0, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x1, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x0, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x0, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x0, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x0, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x0, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x0, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x0, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x0, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x0, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x0, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x0, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x0, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x0, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x0, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x0, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x0, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x0, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x0, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x0, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x0, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x0, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x0, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x0, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x0, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x0, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x0, /* gcFEATURE_BIT_REG_Generics */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x0, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x0, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_ACE */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x0, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x0, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x0, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x0, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x0, /* gcFEATURE_BIT_REG_EEZ */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x0, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x0, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x0, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x0, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x0, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x0, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x0, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x0, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x0, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x0, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x0, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x0, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x0, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x0, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x0, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x0, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x0, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x0, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x0, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x0, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x0, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x0, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x0, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x0, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x0, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x0, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x0, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY */
+ 0x0, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x0, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x0, /* gcFEATURE_BIT_DRAWID */
+ 0x0, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x0, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x0, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x0, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x1, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x0, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x0, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x0, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x0, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x0, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* gc400L_0x465x */
+ {
+ 0x400, /* ChipID */
+ 0x4652, /* ChipRevision */
+ 0x70001, /* ProductID */
+ 0x0, /* EcoID */
+ 0x0, /* CustomerID */
+ 0x7, /* PatchVersion */
+ "", /* ProductName */
+ 0x0, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x80, /* gcFEATURE_VALUE_ThreadCount */
+ 0x1, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x100, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x0, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x0, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x0, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x0, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x0, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x4, /* gcFEATURE_VALUE_Streams */
+ 0x8, /* gcFEATURE_VALUE_VaryingCount */
+ 0x80, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x8, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x1, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x0, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x0, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x0, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x0, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x0, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x0, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x0, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x1, /* gcFEATURE_BIT_REG_MinArea */
+ 0x1, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x1, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x1, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x0, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x0, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x1, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x0, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x0, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x0, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x0, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x0, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x0, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x0, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x0, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x0, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x0, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x0, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x0, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x0, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x0, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x0, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x0, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x0, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x0, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x0, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x1, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x0, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x0, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x0, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x0, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x0, /* gcFEATURE_BIT_REG_Generics */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x0, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x0, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_ACE */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x0, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x0, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x1, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x0, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x0, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x0, /* gcFEATURE_BIT_REG_EEZ */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x0, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x0, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x0, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x0, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x0, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x0, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x0, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x0, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x0, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x0, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x0, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x0, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x0, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x0, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x0, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x0, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x0, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x0, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x0, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x0, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x0, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x0, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x0, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x0, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x0, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x0, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY */
+ 0x0, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x0, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x0, /* gcFEATURE_BIT_DRAWID */
+ 0x0, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x0, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x0, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x0, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x0, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x0, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x0, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x0, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x0, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* gc7000nano_0x4652 */
+ {
+ 0x400, /* ChipID */
+ 0x4652, /* ChipRevision */
+ 0x70001, /* ProductID */
+ 0x0, /* EcoID */
+ 0x0, /* CustomerID */
+ 0x7, /* PatchVersion */
+ "", /* ProductName */
+ 0x1, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x80, /* gcFEATURE_VALUE_ThreadCount */
+ 0x1, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x100, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x0, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x0, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x0, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x0, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x0, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x4, /* gcFEATURE_VALUE_Streams */
+ 0x8, /* gcFEATURE_VALUE_VaryingCount */
+ 0x80, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x8, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x1, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x0, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x0, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x0, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x0, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x0, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x0, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x0, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x1, /* gcFEATURE_BIT_REG_MinArea */
+ 0x1, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x1, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x1, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x0, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x0, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x1, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x0, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x0, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x0, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x0, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x0, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x0, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x0, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x0, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x0, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x0, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x0, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x0, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x0, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x0, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x0, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x0, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x0, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x0, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x0, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x1, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x0, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x0, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x0, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x0, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x0, /* gcFEATURE_BIT_REG_Generics */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x0, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x0, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_ACE */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x0, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x0, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x1, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x0, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x0, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x0, /* gcFEATURE_BIT_REG_EEZ */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x0, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x0, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x0, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x0, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x0, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x0, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x0, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x0, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x0, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x0, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x0, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x0, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x0, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x0, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x0, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x0, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x0, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x0, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x0, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x0, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x0, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x0, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x0, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x0, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x0, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x0, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY */
+ 0x0, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x0, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x0, /* gcFEATURE_BIT_DRAWID */
+ 0x0, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x0, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x0, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x0, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x0, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x0, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x0, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x0, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x0, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* gc7000nano_0x4652 */
+ {
+ 0x400, /* ChipID */
+ 0x4652, /* ChipRevision */
+ 0x70001, /* ProductID */
+ 0x0, /* EcoID */
+ 0x100, /* CustomerID */
+ 0x9, /* PatchVersion */
+ "", /* ProductName */
+ 0x1, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x80, /* gcFEATURE_VALUE_ThreadCount */
+ 0x1, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x100, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x0, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x0, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x0, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x0, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x0, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x4, /* gcFEATURE_VALUE_Streams */
+ 0x8, /* gcFEATURE_VALUE_VaryingCount */
+ 0x80, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x8, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x1, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x0, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x0, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x0, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x0, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x0, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x0, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x0, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x1, /* gcFEATURE_BIT_REG_MinArea */
+ 0x1, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x1, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x1, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x0, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x0, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x1, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x0, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x0, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x0, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x0, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x0, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x0, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x0, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x0, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x0, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x0, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x0, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x0, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x0, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x0, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x0, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x0, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x0, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x0, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x0, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x1, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x0, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x0, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x0, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x0, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x0, /* gcFEATURE_BIT_REG_Generics */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x0, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x0, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_ACE */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x0, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x0, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x1, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x0, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x0, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x0, /* gcFEATURE_BIT_REG_EEZ */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x0, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x0, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x0, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x0, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x0, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x0, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x0, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x0, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x0, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x0, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x0, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x0, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x0, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x0, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x0, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x0, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x0, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x0, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x0, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x0, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x0, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x0, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x0, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x0, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x0, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x0, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY */
+ 0x0, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x0, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x0, /* gcFEATURE_BIT_DRAWID */
+ 0x0, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x0, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x0, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x0, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x0, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x0, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x0, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x0, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x0, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* gc420_5325 */
+ {
+ 0x420, /* ChipID */
+ 0x5325, /* ChipRevision */
+ 0x0, /* ProductID */
+ 0x0, /* EcoID */
+ 0x0, /* CustomerID */
+ 0x2, /* PatchVersion */
+ "", /* ProductName */
+ 0x1, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x100, /* gcFEATURE_VALUE_ThreadCount */
+ 0x1, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x100, /* gcFEATURE_VALUE_InstructionCount */
+ 0xa8, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x0, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x0, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x0, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x0, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x0, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x1, /* gcFEATURE_VALUE_Streams */
+ 0x8, /* gcFEATURE_VALUE_VaryingCount */
+ 0x200, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x8, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x1, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x0, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x1, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x0, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x0, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x1, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x0, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x0, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x1, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x0, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x0, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x0, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x0, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x0, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x0, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x0, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x0, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x0, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x0, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x0, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x0, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x0, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x1, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x1, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x1, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x0, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x1, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x0, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x0, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x0, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x0, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x0, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x0, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x0, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x0, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x0, /* gcFEATURE_BIT_REG_EEZ */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x0, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x0, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x0, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x0, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x0, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x0, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x0, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x0, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x0, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x0, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x0, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x0, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x0, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x0, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x0, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x0, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x0, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x0, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x0, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x0, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x0, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x0, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x0, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x0, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x0, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x0, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY */
+ 0x0, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x0, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x0, /* gcFEATURE_BIT_DRAWID */
+ 0x0, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x0, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x0, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x0, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x0, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x0, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x0, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x0, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x0, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* gc420_5336 */
+ {
+ 0x420, /* ChipID */
+ 0x5336, /* ChipRevision */
+ 0x0, /* ProductID */
+ 0x0, /* EcoID */
+ 0x0, /* CustomerID */
+ 0x3, /* PatchVersion */
+ "", /* ProductName */
+ 0x1, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x100, /* gcFEATURE_VALUE_ThreadCount */
+ 0x1, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x100, /* gcFEATURE_VALUE_InstructionCount */
+ 0xa8, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x0, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x0, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x0, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x0, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x0, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x1, /* gcFEATURE_VALUE_Streams */
+ 0x8, /* gcFEATURE_VALUE_VaryingCount */
+ 0x200, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x8, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x1, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x0, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x1, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x0, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x0, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x1, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x0, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x0, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x1, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x0, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x0, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x0, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x0, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x0, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x0, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x0, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x0, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x0, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x0, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x0, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x0, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x0, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x1, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x0, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x1, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x1, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x0, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x1, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x0, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x0, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x0, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x0, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x0, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x0, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x0, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x1, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x0, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x1, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x1, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x0, /* gcFEATURE_BIT_REG_EEZ */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x0, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x0, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x0, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x0, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x0, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x0, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x0, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x0, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x0, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x0, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x0, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x0, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x0, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x0, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x0, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x0, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x0, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x0, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x0, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x0, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x0, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x0, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x0, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x0, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x0, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x0, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY */
+ 0x0, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x0, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x0, /* gcFEATURE_BIT_DRAWID */
+ 0x0, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x0, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x0, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x0, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x0, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x0, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x0, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x0, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x0, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* gc420cpd_533rc7a */
+ {
+ 0x420, /* ChipID */
+ 0x5337, /* ChipRevision */
+ 0x0, /* ProductID */
+ 0x0, /* EcoID */
+ 0x0, /* CustomerID */
+ 0x1, /* PatchVersion */
+ "", /* ProductName */
+ 0x0, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x100, /* gcFEATURE_VALUE_ThreadCount */
+ 0x1, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x100, /* gcFEATURE_VALUE_InstructionCount */
+ 0xa8, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x0, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x0, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x0, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x0, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x0, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x1, /* gcFEATURE_VALUE_Streams */
+ 0x8, /* gcFEATURE_VALUE_VaryingCount */
+ 0x200, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x8, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x1, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x0, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x1, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x0, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x0, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x1, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x0, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x0, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x1, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x0, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x0, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x0, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x0, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x0, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x0, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x0, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x0, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x0, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x0, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x0, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x0, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x0, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x1, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x0, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x1, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x1, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x0, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x1, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x0, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x0, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x0, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x0, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x0, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x0, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x0, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x1, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x1, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x0, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x1, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x1, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x0, /* gcFEATURE_BIT_REG_EEZ */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x0, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x0, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x0, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x0, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x0, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x0, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x0, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x0, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x0, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x0, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x0, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x0, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x0, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x0, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x0, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x0, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x0, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x0, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x0, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x0, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x0, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x0, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x0, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x0, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x0, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x0, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY */
+ 0x0, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x0, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x0, /* gcFEATURE_BIT_DRAWID */
+ 0x0, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x0, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x0, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x0, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x0, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x0, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x0, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x0, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x0, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* gc428_5421 */
+ {
+ 0x428, /* ChipID */
+ 0x5421, /* ChipRevision */
+ 0x0, /* ProductID */
+ 0x0, /* EcoID */
+ 0x0, /* CustomerID */
+ 0x1, /* PatchVersion */
+ "", /* ProductName */
+ 0x1, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x100, /* gcFEATURE_VALUE_ThreadCount */
+ 0x1, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x100, /* gcFEATURE_VALUE_InstructionCount */
+ 0xa8, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x0, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x0, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x0, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x0, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x0, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x1, /* gcFEATURE_VALUE_Streams */
+ 0x8, /* gcFEATURE_VALUE_VaryingCount */
+ 0x200, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x8, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x1, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x0, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x0, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x0, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x0, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x0, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x0, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x1, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x1, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x0, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x0, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x0, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x0, /* gcFEATURE_BIT_REG_FlipY */
+ 0x0, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x0, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x0, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x0, /* gcFEATURE_BIT_REG_Render8K */
+ 0x0, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x0, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x0, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x0, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x1, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x0, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x0, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x0, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x0, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x0, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x1, /* gcFEATURE_BIT_REG_New2D */
+ 0x0, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x0, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x0, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x0, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x0, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x0, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x0, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x0, /* gcFEATURE_BIT_REG_WideLine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x0, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x0, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x0, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x0, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x0, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x0, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x0, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x0, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x0, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x0, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x0, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x1, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x0, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x0, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x1, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x1, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x0, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x0, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x1, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x0, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x0, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x0, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x0, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x0, /* gcFEATURE_BIT_REG_Generics */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x0, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x0, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x0, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x0, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x0, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x1, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x1, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x0, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x0, /* gcFEATURE_BIT_REG_EEZ */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x0, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x0, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x0, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x0, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x0, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x0, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x0, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x0, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x0, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x0, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x0, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x0, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x0, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x0, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x0, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x0, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x0, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x0, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x0, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x0, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x0, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x0, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x0, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x0, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x0, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x0, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY */
+ 0x0, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x0, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x0, /* gcFEATURE_BIT_DRAWID */
+ 0x0, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x0, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x0, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x0, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x0, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x0, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x0, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x0, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x0, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* gc428c_5_4_2_rc3a */
+ {
+ 0x428, /* ChipID */
+ 0x5423, /* ChipRevision */
+ 0x0, /* ProductID */
+ 0x0, /* EcoID */
+ 0x0, /* CustomerID */
+ 0x1, /* PatchVersion */
+ "", /* ProductName */
+ 0x0, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x100, /* gcFEATURE_VALUE_ThreadCount */
+ 0x1, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x100, /* gcFEATURE_VALUE_InstructionCount */
+ 0xa8, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x0, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x0, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x0, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x0, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x0, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x1, /* gcFEATURE_VALUE_Streams */
+ 0x8, /* gcFEATURE_VALUE_VaryingCount */
+ 0x200, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x8, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x1, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x0, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x0, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x0, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x0, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x0, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x0, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x1, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x1, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x0, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x0, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x0, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x0, /* gcFEATURE_BIT_REG_FlipY */
+ 0x0, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x0, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x0, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x0, /* gcFEATURE_BIT_REG_Render8K */
+ 0x0, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x0, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x0, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x0, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x1, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x0, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x0, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x0, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x0, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x0, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x1, /* gcFEATURE_BIT_REG_New2D */
+ 0x0, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x0, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x0, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x0, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x0, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x0, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x0, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x0, /* gcFEATURE_BIT_REG_WideLine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x0, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x0, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x0, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x0, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x0, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x0, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x0, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x0, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x0, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x0, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x0, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x1, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x0, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x0, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x1, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x1, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x0, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x0, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x1, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x0, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x0, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x0, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x0, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x0, /* gcFEATURE_BIT_REG_Generics */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x0, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x0, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x0, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x0, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x1, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x0, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x1, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x1, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x1, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x1, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x0, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x1, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x1, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x1, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x0, /* gcFEATURE_BIT_REG_EEZ */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x1, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x1, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x0, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x0, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x0, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x0, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x0, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x0, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x0, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x0, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x0, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x0, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x0, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x0, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x0, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x0, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x0, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x0, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x0, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x0, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x0, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x0, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x0, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x0, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x0, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x0, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x0, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x0, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY */
+ 0x0, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x0, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x0, /* gcFEATURE_BIT_DRAWID */
+ 0x0, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x0, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x0, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x0, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x0, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x0, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x0, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x0, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x0, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* gc520_5341 */
+ {
+ 0x520, /* ChipID */
+ 0x5341, /* ChipRevision */
+ 0x0, /* ProductID */
+ 0x0, /* EcoID */
+ 0x0, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x0, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x100, /* gcFEATURE_VALUE_ThreadCount */
+ 0x1, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x100, /* gcFEATURE_VALUE_InstructionCount */
+ 0xa8, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x0, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x0, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x0, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x0, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x0, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x1, /* gcFEATURE_VALUE_Streams */
+ 0x8, /* gcFEATURE_VALUE_VaryingCount */
+ 0x200, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x8, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x1, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x0, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x0, /* gcFEATURE_BIT_REG_FastClear */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x0, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x1, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x0, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x1, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x0, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x0, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x1, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x0, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x0, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x0, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x0, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x0, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x0, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x0, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x0, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x0, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x0, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x0, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x0, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x0, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x1, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x1, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x0, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x1, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x0, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x0, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x0, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x0, /* gcFEATURE_BIT_REG_Generics */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x0, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x0, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_ACE */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x0, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x0, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x0, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x0, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x0, /* gcFEATURE_BIT_REG_EEZ */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x1, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x0, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x0, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x0, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x0, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x0, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x0, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x0, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x0, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x0, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x0, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x0, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x0, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x0, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x0, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x0, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x0, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x0, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x0, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x0, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x0, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x0, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x0, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x0, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x0, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x0, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY */
+ 0x0, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x0, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x0, /* gcFEATURE_BIT_DRAWID */
+ 0x0, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x0, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x0, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x0, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x0, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x0, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x0, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x0, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x0, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* gc520l_5341_rc1b */
+ {
+ 0x520, /* ChipID */
+ 0x5341, /* ChipRevision */
+ 0x5202, /* ProductID */
+ 0x0, /* EcoID */
+ 0x0, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x0, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x100, /* gcFEATURE_VALUE_ThreadCount */
+ 0x1, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x100, /* gcFEATURE_VALUE_InstructionCount */
+ 0xa8, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x0, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x0, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x0, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x0, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x0, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x1, /* gcFEATURE_VALUE_Streams */
+ 0x8, /* gcFEATURE_VALUE_VaryingCount */
+ 0x200, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x8, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x1, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x0, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x0, /* gcFEATURE_BIT_REG_FastClear */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x0, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x1, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x0, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x1, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x0, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x0, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x1, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x0, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x0, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x0, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x0, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x0, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x0, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x0, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x0, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x0, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x0, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x0, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x0, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x0, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x1, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x1, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x0, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x1, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x0, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x0, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x0, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x0, /* gcFEATURE_BIT_REG_Generics */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x0, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x0, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_ACE */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x0, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x0, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x0, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x0, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x0, /* gcFEATURE_BIT_REG_EEZ */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x1, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x0, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x0, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x0, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x0, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x0, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x0, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x0, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x0, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x0, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x0, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x0, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x0, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x0, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x0, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x0, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x0, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x0, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x0, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x0, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x0, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x0, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x0, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x0, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x0, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x0, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY */
+ 0x0, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x0, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x0, /* gcFEATURE_BIT_DRAWID */
+ 0x0, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x0, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x0, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x0, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x0, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x0, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x0, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x0, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x0, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* gc520l_5341_rc1c */
+ {
+ 0x520, /* ChipID */
+ 0x5341, /* ChipRevision */
+ 0x5202, /* ProductID */
+ 0x0, /* EcoID */
+ 0x204, /* CustomerID */
+ 0x3, /* PatchVersion */
+ "", /* ProductName */
+ 0x0, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x100, /* gcFEATURE_VALUE_ThreadCount */
+ 0x1, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x100, /* gcFEATURE_VALUE_InstructionCount */
+ 0xa8, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x0, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x0, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x0, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x0, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x0, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x1, /* gcFEATURE_VALUE_Streams */
+ 0x8, /* gcFEATURE_VALUE_VaryingCount */
+ 0x200, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x8, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x1, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x0, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x0, /* gcFEATURE_BIT_REG_FastClear */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x0, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x1, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x0, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x1, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x0, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x0, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x1, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x0, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x0, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x0, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x0, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x0, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x0, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x0, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x0, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x0, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x0, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x0, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x0, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x0, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x1, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x1, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x0, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x1, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x0, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x0, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x0, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x0, /* gcFEATURE_BIT_REG_Generics */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x0, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x0, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_ACE */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x0, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x0, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x0, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x0, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x0, /* gcFEATURE_BIT_REG_EEZ */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x1, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x0, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x0, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x0, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x0, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x0, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x0, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x0, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x0, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x0, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x0, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x0, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x0, /* gcFEATURE_BIT_V4Compression */
+ 0x1, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x0, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x0, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x0, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x0, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x0, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x0, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x0, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x0, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x0, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x0, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x0, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x0, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x0, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY */
+ 0x0, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x0, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x0, /* gcFEATURE_BIT_DRAWID */
+ 0x0, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x0, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x0, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x0, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x0, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x0, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x0, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x0, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x0, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* gc520_5540_rc0 */
+ {
+ 0x520, /* ChipID */
+ 0x5540, /* ChipRevision */
+ 0x5200, /* ProductID */
+ 0x0, /* EcoID */
+ 0x0, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x0, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x100, /* gcFEATURE_VALUE_ThreadCount */
+ 0x1, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x100, /* gcFEATURE_VALUE_InstructionCount */
+ 0xa8, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x0, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x0, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x0, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x0, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x0, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x1, /* gcFEATURE_VALUE_Streams */
+ 0x8, /* gcFEATURE_VALUE_VaryingCount */
+ 0x200, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x8, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x1, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x0, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x0, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x0, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x0, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x0, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x0, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x1, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x1, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x0, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x0, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x0, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x0, /* gcFEATURE_BIT_REG_FlipY */
+ 0x0, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x0, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x0, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x0, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x0, /* gcFEATURE_BIT_REG_Render8K */
+ 0x0, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x0, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x0, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x0, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x1, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x0, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x0, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x0, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x0, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x0, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x1, /* gcFEATURE_BIT_REG_New2D */
+ 0x0, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x0, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x0, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x0, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x0, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x0, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x0, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x0, /* gcFEATURE_BIT_REG_WideLine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x0, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x0, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x0, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x0, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x0, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x0, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x0, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x0, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x0, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x0, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x0, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x1, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x0, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x0, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x1, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x1, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x0, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x0, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x1, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x1, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x0, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x0, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x0, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x0, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x0, /* gcFEATURE_BIT_REG_Generics */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x0, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x0, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x0, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x0, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x1, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x0, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x1, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x1, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x0, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x1, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x1, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x1, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x0, /* gcFEATURE_BIT_REG_EEZ */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x1, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x1, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x0, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x0, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x1, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x0, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x0, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x0, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x0, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x0, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x0, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x1, /* gcFEATURE_BIT_REG_DEC */
+ 0x1, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x0, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x0, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x0, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x0, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x0, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x0, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x0, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x0, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x0, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x0, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x0, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x0, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x0, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x0, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x0, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x0, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x0, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY */
+ 0x0, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x0, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x0, /* gcFEATURE_BIT_DRAWID */
+ 0x0, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x0, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x0, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x0, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x0, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x0, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x0, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x0, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x0, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* gc520l_5_3_4_rc2b */
+ {
+ 0x520, /* ChipID */
+ 0x5342, /* ChipRevision */
+ 0x5202, /* ProductID */
+ 0x0, /* EcoID */
+ 0x0, /* CustomerID */
+ 0x2, /* PatchVersion */
+ "", /* ProductName */
+ 0x0, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x100, /* gcFEATURE_VALUE_ThreadCount */
+ 0x1, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x100, /* gcFEATURE_VALUE_InstructionCount */
+ 0xa8, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x0, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x0, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x0, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x0, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x0, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x1, /* gcFEATURE_VALUE_Streams */
+ 0x8, /* gcFEATURE_VALUE_VaryingCount */
+ 0x200, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x8, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x1, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x0, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x0, /* gcFEATURE_BIT_REG_FastClear */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x0, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x1, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x1, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x0, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x1, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x0, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x0, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x1, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x0, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x0, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x0, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x0, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x0, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x0, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x0, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x0, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x0, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x0, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x0, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x0, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x0, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x1, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x1, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x0, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x1, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x0, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x0, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x0, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x0, /* gcFEATURE_BIT_REG_Generics */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x0, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x0, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_ACE */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x0, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x0, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x0, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x0, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x0, /* gcFEATURE_BIT_REG_EEZ */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x0, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x0, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x0, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x0, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x0, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x0, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x0, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x0, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x1, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x1, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x0, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x1, /* gcFEATURE_BIT_V4Compression */
+ 0x1, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x0, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x0, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x0, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x0, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x0, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x0, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x0, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x0, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x0, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x0, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x0, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x0, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x0, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY */
+ 0x0, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x0, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x0, /* gcFEATURE_BIT_DRAWID */
+ 0x0, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x0, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x0, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x0, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x0, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x0, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x0, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x0, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x0, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* gc520c_5_5_0 */
+ {
+ 0x520, /* ChipID */
+ 0x5501, /* ChipRevision */
+ 0x5200, /* ProductID */
+ 0x0, /* EcoID */
+ 0x3, /* CustomerID */
+ 0x2, /* PatchVersion */
+ "", /* ProductName */
+ 0x0, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x100, /* gcFEATURE_VALUE_ThreadCount */
+ 0x1, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x100, /* gcFEATURE_VALUE_InstructionCount */
+ 0xa8, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x0, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x0, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x0, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x0, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x0, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x1, /* gcFEATURE_VALUE_Streams */
+ 0x8, /* gcFEATURE_VALUE_VaryingCount */
+ 0x200, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x8, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x1, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x0, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x0, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x0, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x0, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x0, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x0, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x1, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x1, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x1, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x0, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x0, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x0, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x0, /* gcFEATURE_BIT_REG_FlipY */
+ 0x0, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x0, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x0, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x0, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x0, /* gcFEATURE_BIT_REG_Render8K */
+ 0x0, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x0, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x0, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x0, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x1, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x0, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x0, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x0, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x0, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x0, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x1, /* gcFEATURE_BIT_REG_New2D */
+ 0x0, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x0, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x0, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x0, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x0, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x0, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x0, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x0, /* gcFEATURE_BIT_REG_WideLine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x0, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x0, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x0, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x0, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x0, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x0, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x0, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x0, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x0, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x0, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x0, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x1, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x0, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x0, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x1, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x0, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x0, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x1, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x1, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x0, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x0, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x0, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x0, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x0, /* gcFEATURE_BIT_REG_Generics */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x0, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x0, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x0, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x0, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x1, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x0, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x1, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x1, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x1, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x0, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x1, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x1, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x1, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x0, /* gcFEATURE_BIT_REG_EEZ */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x1, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x1, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x0, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x0, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x1, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x0, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x0, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x0, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x0, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x0, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x0, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x1, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x0, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x0, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x1, /* gcFEATURE_BIT_V4Compression */
+ 0x1, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x0, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x0, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x0, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x0, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x0, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x0, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x0, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x0, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x0, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x0, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x0, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x0, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x0, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x0, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY */
+ 0x0, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x0, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x0, /* gcFEATURE_BIT_DRAWID */
+ 0x0, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x0, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x0, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x1, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x0, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x0, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x0, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x0, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x0, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x0, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* gc520c_5_5_4_rc1 */
+ {
+ 0x520, /* ChipID */
+ 0x5541, /* ChipRevision */
+ 0x5200, /* ProductID */
+ 0x0, /* EcoID */
+ 0x202, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x0, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x100, /* gcFEATURE_VALUE_ThreadCount */
+ 0x1, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x100, /* gcFEATURE_VALUE_InstructionCount */
+ 0xa8, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x0, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x0, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x0, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x0, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x0, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x1, /* gcFEATURE_VALUE_Streams */
+ 0x8, /* gcFEATURE_VALUE_VaryingCount */
+ 0x200, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x8, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x1, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x0, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x0, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x0, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x0, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x0, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x0, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x0, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x1, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x1, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x0, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x0, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x0, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x0, /* gcFEATURE_BIT_REG_FlipY */
+ 0x0, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x0, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x0, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x0, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x0, /* gcFEATURE_BIT_REG_Render8K */
+ 0x0, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x0, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x0, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x0, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x1, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x0, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x0, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x0, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x0, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x0, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x1, /* gcFEATURE_BIT_REG_New2D */
+ 0x0, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x0, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x0, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x0, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x0, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x0, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x0, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x0, /* gcFEATURE_BIT_REG_WideLine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x0, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x0, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x0, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x0, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x0, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x0, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x0, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x0, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x0, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x0, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x0, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x1, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x0, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x0, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x1, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x1, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x0, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x0, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x1, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x1, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x0, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x0, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x0, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x0, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x0, /* gcFEATURE_BIT_REG_Generics */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x0, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x0, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x0, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x0, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x1, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x0, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x1, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x1, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x0, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x1, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x1, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x1, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x0, /* gcFEATURE_BIT_REG_EEZ */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x1, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x1, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x0, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x0, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x1, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x0, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x0, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x0, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x0, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x0, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x0, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x1, /* gcFEATURE_BIT_REG_DEC */
+ 0x1, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x0, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x0, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x0, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x0, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x0, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x0, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x0, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x0, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x0, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x0, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x0, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x0, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x0, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x0, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x0, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x0, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x0, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY */
+ 0x0, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x0, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x0, /* gcFEATURE_BIT_DRAWID */
+ 0x0, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x0, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x0, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x0, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x0, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x0, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x0, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x0, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x0, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* gc520sp_5_5_2_rc0a */
+ {
+ 0x520, /* ChipID */
+ 0x5520, /* ChipRevision */
+ 0x5200, /* ProductID */
+ 0x0, /* EcoID */
+ 0x0, /* CustomerID */
+ 0x1, /* PatchVersion */
+ "", /* ProductName */
+ 0x1, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x100, /* gcFEATURE_VALUE_ThreadCount */
+ 0x1, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x100, /* gcFEATURE_VALUE_InstructionCount */
+ 0xa8, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x0, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x0, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x0, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x0, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x0, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x1, /* gcFEATURE_VALUE_Streams */
+ 0x8, /* gcFEATURE_VALUE_VaryingCount */
+ 0x200, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x8, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x1, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x0, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x0, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x0, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x0, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x0, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x0, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x0, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x1, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x1, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x1, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x0, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x0, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x0, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x0, /* gcFEATURE_BIT_REG_FlipY */
+ 0x0, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x0, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x0, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x0, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x0, /* gcFEATURE_BIT_REG_Render8K */
+ 0x0, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x0, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x0, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x0, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x1, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x0, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x0, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x0, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x0, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x0, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x1, /* gcFEATURE_BIT_REG_New2D */
+ 0x0, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x0, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x0, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x0, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x0, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x0, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x0, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x0, /* gcFEATURE_BIT_REG_WideLine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x0, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x0, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x0, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x0, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x0, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x0, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x0, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x0, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x0, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x0, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x0, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x1, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x0, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x0, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x1, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x1, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x0, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x0, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x1, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x0, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x0, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x0, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x0, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x0, /* gcFEATURE_BIT_REG_Generics */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x0, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x0, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x0, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x0, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x1, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x0, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x1, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x1, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x0, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x1, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x1, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x1, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x0, /* gcFEATURE_BIT_REG_EEZ */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x1, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x1, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x0, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x0, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x1, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x0, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x0, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x1, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x0, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x0, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x0, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x0, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x0, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x0, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x0, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x0, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x0, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x0, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x0, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x0, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x0, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x0, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x0, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x0, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x0, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x0, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x0, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x0, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x0, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x0, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY */
+ 0x0, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x0, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x0, /* gcFEATURE_BIT_DRAWID */
+ 0x0, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x0, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x0, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x0, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x0, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x0, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x0, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x0, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x0, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* gc520_v552_rc1 */
+ {
+ 0x520, /* ChipID */
+ 0x5521, /* ChipRevision */
+ 0x5200, /* ProductID */
+ 0x0, /* EcoID */
+ 0x0, /* CustomerID */
+ 0x1, /* PatchVersion */
+ "", /* ProductName */
+ 0x1, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x100, /* gcFEATURE_VALUE_ThreadCount */
+ 0x1, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x100, /* gcFEATURE_VALUE_InstructionCount */
+ 0xa8, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x0, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x0, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x0, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x0, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x0, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x1, /* gcFEATURE_VALUE_Streams */
+ 0x8, /* gcFEATURE_VALUE_VaryingCount */
+ 0x200, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x8, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x1, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x0, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x0, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x0, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x0, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x0, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x0, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x0, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x1, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x1, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x1, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x0, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x0, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x0, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x0, /* gcFEATURE_BIT_REG_FlipY */
+ 0x0, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x0, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x0, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x0, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x0, /* gcFEATURE_BIT_REG_Render8K */
+ 0x0, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x0, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x0, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x0, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x1, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x0, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x0, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x0, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x0, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x0, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x1, /* gcFEATURE_BIT_REG_New2D */
+ 0x0, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x0, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x0, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x0, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x0, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x0, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x0, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x0, /* gcFEATURE_BIT_REG_WideLine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x0, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x0, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x0, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x0, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x0, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x0, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x0, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x0, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x0, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x0, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x0, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x1, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x0, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x0, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x1, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x1, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x0, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x0, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x1, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x0, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x0, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x0, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x0, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x0, /* gcFEATURE_BIT_REG_Generics */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x0, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x0, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x0, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x0, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x1, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x0, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x1, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x1, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x0, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x1, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x1, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x1, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x0, /* gcFEATURE_BIT_REG_EEZ */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x1, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x1, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x0, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x0, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x1, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x0, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x0, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x1, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x0, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x0, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x0, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x0, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x0, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x0, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x0, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x0, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x0, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x0, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x0, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x0, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x0, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x0, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x0, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x0, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x0, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x0, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x0, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x0, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x0, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x0, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY */
+ 0x0, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x0, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x0, /* gcFEATURE_BIT_DRAWID */
+ 0x0, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x0, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x0, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x0, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x0, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x0, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x0, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x0, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x0, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* gc520_5_5_3_rc2a */
+ {
+ 0x520, /* ChipID */
+ 0x5532, /* ChipRevision */
+ 0x5200, /* ProductID */
+ 0x0, /* EcoID */
+ 0x0, /* CustomerID */
+ 0x1, /* PatchVersion */
+ "", /* ProductName */
+ 0x0, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x100, /* gcFEATURE_VALUE_ThreadCount */
+ 0x1, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x100, /* gcFEATURE_VALUE_InstructionCount */
+ 0xa8, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x0, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x0, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x0, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x0, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x0, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x1, /* gcFEATURE_VALUE_Streams */
+ 0x8, /* gcFEATURE_VALUE_VaryingCount */
+ 0x200, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x8, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x1, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x0, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x0, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x0, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x0, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x0, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x0, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x1, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x1, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x0, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x0, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x0, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x0, /* gcFEATURE_BIT_REG_FlipY */
+ 0x0, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x0, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x0, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x0, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x0, /* gcFEATURE_BIT_REG_Render8K */
+ 0x0, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x0, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x0, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x0, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x1, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x0, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x0, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x0, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x0, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x0, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x1, /* gcFEATURE_BIT_REG_New2D */
+ 0x0, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x0, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x0, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x0, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x0, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x0, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x0, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x0, /* gcFEATURE_BIT_REG_WideLine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x0, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x0, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x0, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x0, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x0, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x0, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x0, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x0, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x0, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x0, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x0, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x1, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x0, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x0, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x1, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x1, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x0, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x0, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x1, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x1, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x0, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x0, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x0, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x0, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x0, /* gcFEATURE_BIT_REG_Generics */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x0, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x0, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x0, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x0, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x1, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x0, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x1, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x1, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x0, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x1, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x1, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x1, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x0, /* gcFEATURE_BIT_REG_EEZ */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x1, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x1, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x0, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x0, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x1, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x0, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x0, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x0, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x0, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x0, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x0, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x1, /* gcFEATURE_BIT_REG_DEC */
+ 0x1, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x0, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x0, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x0, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x0, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x0, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x0, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x0, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x0, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x0, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x0, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x0, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x0, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x0, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x0, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x0, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x0, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x0, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x0, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY */
+ 0x0, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x0, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x0, /* gcFEATURE_BIT_DRAWID */
+ 0x0, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x0, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x0, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x0, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x0, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x0, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x0, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x0, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x0, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* gc600L_0x465x */
+ {
+ 0x600, /* ChipID */
+ 0x4652, /* ChipRevision */
+ 0x70005, /* ProductID */
+ 0x0, /* EcoID */
+ 0x0, /* CustomerID */
+ 0x7, /* PatchVersion */
+ "", /* ProductName */
+ 0x0, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x100, /* gcFEATURE_VALUE_ThreadCount */
+ 0x1, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x100, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x0, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x0, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x0, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x0, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x0, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x4, /* gcFEATURE_VALUE_Streams */
+ 0x8, /* gcFEATURE_VALUE_VaryingCount */
+ 0x200, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x8, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x1, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x0, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x0, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x0, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x0, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x0, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x1, /* gcFEATURE_BIT_REG_MinArea */
+ 0x1, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x1, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x1, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x0, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x0, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x1, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x0, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x0, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x0, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x0, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x0, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x0, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x0, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x0, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x0, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x0, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x0, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x0, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x0, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x0, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x0, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x0, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x0, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x0, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x0, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x0, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x0, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x0, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x0, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x0, /* gcFEATURE_BIT_REG_Generics */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x0, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x0, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_ACE */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x0, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x0, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x1, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x0, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x0, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x0, /* gcFEATURE_BIT_REG_EEZ */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x0, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x0, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x0, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x0, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x0, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x0, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x0, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x0, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x0, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x0, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x0, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x0, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x0, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x0, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x0, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x0, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x0, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x0, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x0, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x0, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x0, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x0, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x0, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x0, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x0, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x0, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY */
+ 0x0, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x0, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x0, /* gcFEATURE_BIT_DRAWID */
+ 0x0, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x0, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x0, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x0, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x0, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x0, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x0, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x0, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x0, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* gc7000nanoultra_4_6_5_rc3a */
+ {
+ 0x600, /* ChipID */
+ 0x4653, /* ChipRevision */
+ 0x70005, /* ProductID */
+ 0x0, /* EcoID */
+ 0x0, /* CustomerID */
+ 0x1, /* PatchVersion */
+ "", /* ProductName */
+ 0x1, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x100, /* gcFEATURE_VALUE_ThreadCount */
+ 0x1, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x100, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x0, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x0, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x0, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x0, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x0, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x4, /* gcFEATURE_VALUE_Streams */
+ 0x8, /* gcFEATURE_VALUE_VaryingCount */
+ 0x200, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x8, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x1, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x0, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x0, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x1, /* gcFEATURE_BIT_REG_MinArea */
+ 0x1, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x1, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x1, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x0, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x0, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x1, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x0, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x0, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x0, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x0, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x0, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x0, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x0, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x0, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x0, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x0, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x0, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x0, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x0, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x0, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x0, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x0, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x0, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x0, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x0, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x0, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x0, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x0, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x0, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x0, /* gcFEATURE_BIT_REG_Generics */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x0, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x0, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_ACE */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x0, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x0, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x1, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x0, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x0, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x0, /* gcFEATURE_BIT_REG_EEZ */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x0, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x0, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x0, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x0, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x0, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x0, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x0, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x0, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x0, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x0, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x0, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x0, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x0, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x0, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x0, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x0, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x0, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x0, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x0, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x0, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x0, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x0, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x0, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x0, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x0, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x0, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY */
+ 0x0, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x0, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x0, /* gcFEATURE_BIT_DRAWID */
+ 0x0, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x0, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x0, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x0, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x0, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x0, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x1, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x0, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x0, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x0, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* gc7000nanoultra_4_6_5_rc3b */
+ {
+ 0x600, /* ChipID */
+ 0x4653, /* ChipRevision */
+ 0x70005, /* ProductID */
+ 0x0, /* EcoID */
+ 0x101, /* CustomerID */
+ 0x2, /* PatchVersion */
+ "", /* ProductName */
+ 0x1, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x100, /* gcFEATURE_VALUE_ThreadCount */
+ 0x1, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x100, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x0, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x0, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x0, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x0, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x0, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x4, /* gcFEATURE_VALUE_Streams */
+ 0x8, /* gcFEATURE_VALUE_VaryingCount */
+ 0x200, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x8, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x1, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x0, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x0, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x1, /* gcFEATURE_BIT_REG_MinArea */
+ 0x1, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x1, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x1, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x0, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x0, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x1, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x0, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x0, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x0, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x0, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x0, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x0, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x0, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x0, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x0, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x0, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x0, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x0, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x0, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x0, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x0, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x0, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x0, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x0, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x0, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x0, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x0, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x0, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x0, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x0, /* gcFEATURE_BIT_REG_Generics */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x0, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x0, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_ACE */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x0, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x0, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x1, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x0, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x0, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x0, /* gcFEATURE_BIT_REG_EEZ */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x0, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x0, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x0, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x0, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x0, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x0, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x0, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x0, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x0, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x0, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x0, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x0, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x0, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x0, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x0, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x0, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x0, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x0, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x0, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x0, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x0, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x0, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x0, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x0, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x0, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x0, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY */
+ 0x0, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x0, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x0, /* gcFEATURE_BIT_DRAWID */
+ 0x0, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x0, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x0, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x0, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x0, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x0, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x1, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x0, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x0, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x0, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* gc7000nanoultra_4_6_5_rc3e */
+ {
+ 0x600, /* ChipID */
+ 0x4653, /* ChipRevision */
+ 0x70005, /* ProductID */
+ 0x0, /* EcoID */
+ 0x102, /* CustomerID */
+ 0x5, /* PatchVersion */
+ "", /* ProductName */
+ 0x1, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x100, /* gcFEATURE_VALUE_ThreadCount */
+ 0x1, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x100, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x0, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x0, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x0, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x0, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x0, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x4, /* gcFEATURE_VALUE_Streams */
+ 0x8, /* gcFEATURE_VALUE_VaryingCount */
+ 0x200, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x8, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x1, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x0, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x0, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x1, /* gcFEATURE_BIT_REG_MinArea */
+ 0x1, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x1, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x1, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x0, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x0, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x1, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x0, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x0, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x0, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x0, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x0, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x0, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x0, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x0, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x0, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x0, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x0, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x0, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x0, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x0, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x0, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x0, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x0, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x0, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x0, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x0, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x0, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x0, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x0, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x0, /* gcFEATURE_BIT_REG_Generics */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x0, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x0, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_ACE */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x0, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x0, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x1, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x0, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x0, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x0, /* gcFEATURE_BIT_REG_EEZ */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x0, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x0, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x0, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x0, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x0, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x0, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x0, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x0, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x0, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x0, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x0, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x0, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x0, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x0, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x0, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x0, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x0, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x0, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x0, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x0, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x0, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x0, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x0, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x0, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x0, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x0, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY */
+ 0x0, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x0, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x0, /* gcFEATURE_BIT_DRAWID */
+ 0x0, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x0, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x0, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x0, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x0, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x0, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x0, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x0, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x0, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* gc7000nanoultra_4_6_5_rc3e */
+ {
+ 0x600, /* ChipID */
+ 0x4653, /* ChipRevision */
+ 0x70005, /* ProductID */
+ 0x0, /* EcoID */
+ 0x104, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x0, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x100, /* gcFEATURE_VALUE_ThreadCount */
+ 0x1, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x100, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x0, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x0, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x0, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x0, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x0, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x4, /* gcFEATURE_VALUE_Streams */
+ 0x8, /* gcFEATURE_VALUE_VaryingCount */
+ 0x200, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x8, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x1, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x0, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x0, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x1, /* gcFEATURE_BIT_REG_MinArea */
+ 0x1, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x1, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x1, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x0, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x0, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x1, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x0, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x0, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x0, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x0, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x0, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x0, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x0, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x0, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x0, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x0, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x0, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x0, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x0, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x0, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x0, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x0, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x0, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x0, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x0, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x0, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x0, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x0, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x0, /* gcFEATURE_BIT_REG_Generics */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x0, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x0, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_ACE */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x0, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x0, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x1, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x0, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x0, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x0, /* gcFEATURE_BIT_REG_EEZ */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x0, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x0, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x0, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x0, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x0, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x0, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x0, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x0, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x0, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x0, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x0, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x0, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x0, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x0, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x0, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x0, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x0, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x0, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x0, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x0, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x0, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x0, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x0, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x0, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x0, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x0, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY */
+ 0x0, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x0, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x0, /* gcFEATURE_BIT_DRAWID */
+ 0x0, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x0, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x0, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x0, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x0, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x0, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x0, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x1, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x0, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x0, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* gc620_5_5_3_rc0 */
+ {
+ 0x620, /* ChipID */
+ 0x5530, /* ChipRevision */
+ 0x6200, /* ProductID */
+ 0x0, /* EcoID */
+ 0x200, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x0, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x100, /* gcFEATURE_VALUE_ThreadCount */
+ 0x1, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x100, /* gcFEATURE_VALUE_InstructionCount */
+ 0xa8, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x0, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x0, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x0, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x0, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x0, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x1, /* gcFEATURE_VALUE_Streams */
+ 0x8, /* gcFEATURE_VALUE_VaryingCount */
+ 0x200, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x8, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x1, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x0, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x0, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x0, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x0, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x0, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x0, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x0, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x1, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x1, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x0, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x0, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x0, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x0, /* gcFEATURE_BIT_REG_FlipY */
+ 0x0, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x0, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x0, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x0, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x0, /* gcFEATURE_BIT_REG_Render8K */
+ 0x0, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x0, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x0, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x0, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x1, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x0, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x0, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x0, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x0, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x0, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x1, /* gcFEATURE_BIT_REG_New2D */
+ 0x0, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x0, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x0, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x0, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x0, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x0, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x0, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x0, /* gcFEATURE_BIT_REG_WideLine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x0, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x0, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x0, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x0, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x0, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x0, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x0, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x0, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x0, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x0, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x0, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x1, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x0, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x0, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x1, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x1, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x0, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x0, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x1, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x0, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x0, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x0, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x0, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x0, /* gcFEATURE_BIT_REG_Generics */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x0, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x0, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x0, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x0, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x1, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x0, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x1, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x1, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x0, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x1, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x1, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x1, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x0, /* gcFEATURE_BIT_REG_EEZ */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x1, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x1, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x0, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x0, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x0, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x0, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x0, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x0, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x0, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x0, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x0, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x0, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x0, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x0, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x0, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x0, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x0, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x0, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x0, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x0, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x0, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x0, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x0, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x0, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x0, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x0, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x0, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY */
+ 0x0, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x0, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x0, /* gcFEATURE_BIT_DRAWID */
+ 0x0, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x0, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x0, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x0, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x1, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x1, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x0, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x0, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x0, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x1, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x0, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x0, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* gc620_5_5_5_rc0d */
+ {
+ 0x620, /* ChipID */
+ 0x5550, /* ChipRevision */
+ 0x6200, /* ProductID */
+ 0x0, /* EcoID */
+ 0x201, /* CustomerID */
+ 0x4, /* PatchVersion */
+ "", /* ProductName */
+ 0x0, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x100, /* gcFEATURE_VALUE_ThreadCount */
+ 0x1, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x100, /* gcFEATURE_VALUE_InstructionCount */
+ 0xa8, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x0, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x0, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x0, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x0, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x0, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x1, /* gcFEATURE_VALUE_Streams */
+ 0x8, /* gcFEATURE_VALUE_VaryingCount */
+ 0x200, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x8, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x1, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x0, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x0, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x0, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x0, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x0, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x0, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x0, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x1, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x1, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x1, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x0, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x0, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x0, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x0, /* gcFEATURE_BIT_REG_FlipY */
+ 0x0, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x0, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x0, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x0, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x0, /* gcFEATURE_BIT_REG_Render8K */
+ 0x0, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x0, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x0, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x0, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x1, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x0, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x0, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x0, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x0, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x0, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x1, /* gcFEATURE_BIT_REG_New2D */
+ 0x0, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x0, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x0, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x0, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x0, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x0, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x0, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x0, /* gcFEATURE_BIT_REG_WideLine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x0, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x0, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x0, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x0, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x0, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x0, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x0, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x0, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x0, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x0, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x0, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x1, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x0, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x0, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x1, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x1, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x0, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x0, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x1, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x0, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x0, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x0, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x0, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x0, /* gcFEATURE_BIT_REG_Generics */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x0, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x0, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x0, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x0, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x1, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x0, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x1, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x1, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x0, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x1, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x1, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x1, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x0, /* gcFEATURE_BIT_REG_EEZ */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x1, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x1, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x0, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x0, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x1, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x0, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x0, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x0, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x0, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x0, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x0, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x0, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x0, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x0, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x0, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x0, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x0, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x0, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x0, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x0, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x0, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x0, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x0, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x0, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x0, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x0, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x0, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x0, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY */
+ 0x0, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x0, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x0, /* gcFEATURE_BIT_DRAWID */
+ 0x0, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x0, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x0, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x0, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x1, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x0, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x0, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x0, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x1, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x0, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x0, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* gc620s_5_5_5_rc1b */
+ {
+ 0x620, /* ChipID */
+ 0x5551, /* ChipRevision */
+ 0x6200, /* ProductID */
+ 0x0, /* EcoID */
+ 0x203, /* CustomerID */
+ 0x2, /* PatchVersion */
+ "", /* ProductName */
+ 0x0, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x100, /* gcFEATURE_VALUE_ThreadCount */
+ 0x1, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x100, /* gcFEATURE_VALUE_InstructionCount */
+ 0xa8, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x0, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x0, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x0, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x0, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x0, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x1, /* gcFEATURE_VALUE_Streams */
+ 0x8, /* gcFEATURE_VALUE_VaryingCount */
+ 0x200, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x8, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x1, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x0, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x0, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x0, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x0, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x0, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x0, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x0, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x1, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x1, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x1, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x0, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x0, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x0, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x0, /* gcFEATURE_BIT_REG_FlipY */
+ 0x0, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x0, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x0, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x0, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x0, /* gcFEATURE_BIT_REG_Render8K */
+ 0x0, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x0, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x0, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x0, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x1, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x0, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x0, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x0, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x0, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x0, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x1, /* gcFEATURE_BIT_REG_New2D */
+ 0x0, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x0, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x0, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x0, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x0, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x0, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x0, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x0, /* gcFEATURE_BIT_REG_WideLine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x0, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x0, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x0, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x0, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x0, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x0, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x0, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x0, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x0, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x0, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x0, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x1, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x0, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x0, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x1, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x1, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x0, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x0, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x1, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x0, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x0, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x0, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x0, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x0, /* gcFEATURE_BIT_REG_Generics */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x0, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x0, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x0, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x0, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x1, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x0, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x1, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x1, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x0, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x1, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x1, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x1, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x0, /* gcFEATURE_BIT_REG_EEZ */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x1, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x1, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x0, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x0, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x1, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x0, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x0, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x0, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x0, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x0, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x0, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x0, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x0, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x0, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x0, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x0, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x0, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x0, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x0, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x0, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x0, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x0, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x0, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x0, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x0, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x0, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x0, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x0, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY */
+ 0x0, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x0, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x0, /* gcFEATURE_BIT_DRAWID */
+ 0x0, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x0, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x0, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x0, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x1, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x1, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x0, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x0, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x0, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x0, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x0, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* gc620tpc_5_5_6_rc0a */
+ {
+ 0x620, /* ChipID */
+ 0x5560, /* ChipRevision */
+ 0x6200, /* ProductID */
+ 0x0, /* EcoID */
+ 0x200, /* CustomerID */
+ 0x1, /* PatchVersion */
+ "", /* ProductName */
+ 0x0, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x100, /* gcFEATURE_VALUE_ThreadCount */
+ 0x1, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x100, /* gcFEATURE_VALUE_InstructionCount */
+ 0xa8, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x0, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x0, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x0, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x0, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x0, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x1, /* gcFEATURE_VALUE_Streams */
+ 0x8, /* gcFEATURE_VALUE_VaryingCount */
+ 0x200, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x8, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x1, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x0, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x0, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x0, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x0, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x0, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x0, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x0, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x1, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x1, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x1, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x0, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x0, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x0, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x0, /* gcFEATURE_BIT_REG_FlipY */
+ 0x0, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x0, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x0, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x0, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x0, /* gcFEATURE_BIT_REG_Render8K */
+ 0x0, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x0, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x0, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x0, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x1, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x0, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x0, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x0, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x0, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x0, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x1, /* gcFEATURE_BIT_REG_New2D */
+ 0x0, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x0, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x0, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x0, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x0, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x0, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x0, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x0, /* gcFEATURE_BIT_REG_WideLine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x0, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x0, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x0, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x0, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x0, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x0, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x0, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x0, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x0, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x0, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x0, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x1, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x0, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x0, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x1, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x1, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x0, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x0, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x1, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x0, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x0, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x0, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x0, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x0, /* gcFEATURE_BIT_REG_Generics */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x0, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x0, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x0, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x0, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x1, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x0, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x1, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x1, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x0, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x1, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x1, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x1, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x0, /* gcFEATURE_BIT_REG_EEZ */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x1, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x1, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x0, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x0, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x1, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x0, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x0, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x0, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x0, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x0, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x0, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x0, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x0, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x0, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x0, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x0, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x0, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x0, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x0, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x0, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x0, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x0, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x0, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x0, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x0, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x0, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x0, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x0, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY */
+ 0x0, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x0, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x0, /* gcFEATURE_BIT_DRAWID */
+ 0x0, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x0, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x0, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x0, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x1, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x1, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x0, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x1, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x0, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x0, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x0, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x0, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* gc860L_0x464x */
+ {
+ 0x860, /* ChipID */
+ 0x4647, /* ChipRevision */
+ 0x0, /* ProductID */
+ 0x0, /* EcoID */
+ 0x0, /* CustomerID */
+ 0x4, /* PatchVersion */
+ "", /* ProductName */
+ 0x0, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x100, /* gcFEATURE_VALUE_ThreadCount */
+ 0x1, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x100, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x0, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x0, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x0, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x0, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x0, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x4, /* gcFEATURE_VALUE_Streams */
+ 0x8, /* gcFEATURE_VALUE_VaryingCount */
+ 0x200, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x8, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x1, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x0, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x0, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x0, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x1, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x0, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x0, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x0, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x0, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x0, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x0, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x0, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x0, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x0, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x0, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x0, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x0, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x0, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x0, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x0, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x0, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x0, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x0, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x0, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x0, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x0, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x0, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x0, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x0, /* gcFEATURE_BIT_REG_Generics */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x0, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x0, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_ACE */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x0, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x0, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x1, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x0, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x0, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x0, /* gcFEATURE_BIT_REG_EEZ */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x0, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x0, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x0, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x0, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x0, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x0, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x0, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x0, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x0, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x0, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x0, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x0, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x0, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x0, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x0, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x0, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x0, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x0, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x0, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x0, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x0, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x0, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x0, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x0, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x0, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x0, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x0, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY */
+ 0x0, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x0, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x0, /* gcFEATURE_BIT_DRAWID */
+ 0x0, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x0, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x0, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x0, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x0, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x0, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x0, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x0, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x0, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* gc880_5106 */
+ {
+ 0x880, /* ChipID */
+ 0x5106, /* ChipRevision */
+ 0x0, /* ProductID */
+ 0x0, /* EcoID */
+ 0x0, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x1, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x100, /* gcFEATURE_VALUE_ThreadCount */
+ 0x1, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x100, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x0, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x0, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x0, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x0, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x0, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x8, /* gcFEATURE_VALUE_Streams */
+ 0xb, /* gcFEATURE_VALUE_VaryingCount */
+ 0x200, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x8, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x1, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x0, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x0, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x0, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x0, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x0, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x0, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x0, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x0, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x0, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x0, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x0, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x0, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x0, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x0, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x0, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x0, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x0, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x0, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x0, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x0, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x0, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x0, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x0, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x0, /* gcFEATURE_BIT_REG_Generics */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x0, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x0, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_ACE */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x0, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x0, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x0, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x0, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x0, /* gcFEATURE_BIT_REG_EEZ */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x0, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x0, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x0, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x0, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x0, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x0, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x0, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x0, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x0, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x0, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x0, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x0, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x0, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x0, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x0, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x0, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x0, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x0, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x0, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x0, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x0, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x0, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x0, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x0, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x0, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x0, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY */
+ 0x0, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x0, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x0, /* gcFEATURE_BIT_DRAWID */
+ 0x0, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x0, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x0, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x0, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x0, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x0, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x0, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x0, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x0, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* gc880_5122 */
+ {
+ 0x880, /* ChipID */
+ 0x5122, /* ChipRevision */
+ 0x70007, /* ProductID */
+ 0x0, /* EcoID */
+ 0x0, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x0, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x100, /* gcFEATURE_VALUE_ThreadCount */
+ 0x1, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x240, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x0, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x0, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x0, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x0, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x0, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x10, /* gcFEATURE_VALUE_Streams */
+ 0xc, /* gcFEATURE_VALUE_VaryingCount */
+ 0x200, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x8, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x1, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x0, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x0, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x1, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x0, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x0, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x0, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x0, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x0, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x0, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x0, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x0, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x0, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x0, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x0, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x0, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x0, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x0, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x0, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x0, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x0, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x0, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x0, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x0, /* gcFEATURE_BIT_REG_Generics */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x0, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x0, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_ACE */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x0, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x0, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x0, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x0, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x0, /* gcFEATURE_BIT_REG_EEZ */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x0, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x0, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x0, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x0, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x0, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x0, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x0, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x0, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x0, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x0, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x0, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x0, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x0, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x0, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x0, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x0, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x0, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x0, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x0, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x0, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x0, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x0, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x0, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x0, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x0, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY */
+ 0x0, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x0, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x0, /* gcFEATURE_BIT_DRAWID */
+ 0x0, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x0, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x0, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x0, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x0, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x0, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x0, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x0, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x0, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* gc880TM_0x512x */
+ {
+ 0x880, /* ChipID */
+ 0x5124, /* ChipRevision */
+ 0x70007, /* ProductID */
+ 0x0, /* EcoID */
+ 0x0, /* CustomerID */
+ 0x2, /* PatchVersion */
+ "", /* ProductName */
+ 0x0, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x100, /* gcFEATURE_VALUE_ThreadCount */
+ 0x1, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x240, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x0, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x0, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x0, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x0, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x0, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x8, /* gcFEATURE_VALUE_Streams */
+ 0xc, /* gcFEATURE_VALUE_VaryingCount */
+ 0x200, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x8, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x1, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x0, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x0, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x0, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x1, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x0, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x0, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x0, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x0, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x0, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x0, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x0, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x0, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x0, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x0, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x0, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x0, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x0, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x0, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x0, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x0, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x0, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x0, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x0, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x0, /* gcFEATURE_BIT_REG_Generics */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x0, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x0, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_ACE */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x0, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x0, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x0, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x0, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x0, /* gcFEATURE_BIT_REG_EEZ */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x0, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x0, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x0, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x0, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x0, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x0, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x0, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x0, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x0, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x0, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x0, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x0, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x0, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x0, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x0, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x0, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x0, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x0, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x0, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x0, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x0, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x0, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x0, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x0, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x0, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY */
+ 0x0, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x0, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x0, /* gcFEATURE_BIT_DRAWID */
+ 0x0, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x0, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x0, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x0, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x0, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x0, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x0, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x0, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x0, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* gc880TM_0x512x */
+ {
+ 0x880, /* ChipID */
+ 0x5124, /* ChipRevision */
+ 0x70007, /* ProductID */
+ 0x0, /* EcoID */
+ 0x103, /* CustomerID */
+ 0x2, /* PatchVersion */
+ "", /* ProductName */
+ 0x0, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x100, /* gcFEATURE_VALUE_ThreadCount */
+ 0x1, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x240, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x0, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x0, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x0, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x0, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x0, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x8, /* gcFEATURE_VALUE_Streams */
+ 0xf, /* gcFEATURE_VALUE_VaryingCount */
+ 0x200, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x8, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x1, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x0, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x0, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x0, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x1, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x0, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x0, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x0, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x0, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x0, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x0, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x0, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x0, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x0, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x0, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x0, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x0, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x0, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x0, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x0, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x0, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x0, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x0, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x0, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x0, /* gcFEATURE_BIT_REG_Generics */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x0, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_ACE */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x0, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x0, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x0, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x0, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x0, /* gcFEATURE_BIT_REG_EEZ */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x0, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x0, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x0, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x0, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x0, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x0, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x0, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x0, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x0, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x0, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x0, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x0, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x0, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x0, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x0, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x0, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x0, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x0, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x0, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x0, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x0, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x0, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x0, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x0, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x0, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY */
+ 0x0, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x0, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x0, /* gcFEATURE_BIT_DRAWID */
+ 0x0, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x0, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x0, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x0, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x0, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x0, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x1, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x1, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x0, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x0, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* gc900_5250 */
+ {
+ 0x900, /* ChipID */
+ 0x5250, /* ChipRevision */
+ 0x0, /* ProductID */
+ 0x0, /* EcoID */
+ 0x0, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x0, /* FormalRelease */
+ 0x200, /* gcFEATURE_VALUE_TempRegisters */
+ 0x100, /* gcFEATURE_VALUE_ThreadCount */
+ 0x1, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x1, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x2, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x0, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x0, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x0, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x0, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x8, /* gcFEATURE_VALUE_Streams */
+ 0x10, /* gcFEATURE_VALUE_VaryingCount */
+ 0x200, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x8, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x1, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x0, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x0, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x0, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x0, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x0, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x1, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x0, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x0, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x0, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x0, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x0, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x0, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x0, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x0, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x0, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x0, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x0, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x0, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x0, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x0, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x0, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x0, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x0, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x0, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x0, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x0, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x0, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x0, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x0, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x0, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x0, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x0, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x0, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x0, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x0, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x0, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x0, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x0, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x0, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x0, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY */
+ 0x0, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x0, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x0, /* gcFEATURE_BIT_DRAWID */
+ 0x0, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x0, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x0, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x0, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x0, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x0, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x1, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x1, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x0, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x0, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x0, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* gc1000_5036 */
+ {
+ 0x1000, /* ChipID */
+ 0x5036, /* ChipRevision */
+ 0x0, /* ProductID */
+ 0x0, /* EcoID */
+ 0x0, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x1, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x200, /* gcFEATURE_VALUE_ThreadCount */
+ 0x2, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x100, /* gcFEATURE_VALUE_InstructionCount */
+ 0x240, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x0, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x0, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x0, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x0, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x0, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x4, /* gcFEATURE_VALUE_Streams */
+ 0x8, /* gcFEATURE_VALUE_VaryingCount */
+ 0x200, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x8, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x1, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x0, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x0, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x1, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x0, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x0, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x0, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x0, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x0, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x0, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x0, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x0, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x0, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x0, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x0, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x0, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x0, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x0, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x0, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x0, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x0, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x0, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x0, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x0, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x0, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x0, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x0, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x0, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x0, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_ACE */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x1, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x0, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x0, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x0, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x0, /* gcFEATURE_BIT_REG_EEZ */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x0, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x0, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x0, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x0, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x0, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x0, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x0, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x0, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x0, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x0, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x0, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x0, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x0, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x0, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x0, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x0, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x0, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x0, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x0, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x0, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x0, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x0, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x0, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x0, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x0, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x0, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x0, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY */
+ 0x0, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x0, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x0, /* gcFEATURE_BIT_DRAWID */
+ 0x0, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x0, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x0, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x0, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x0, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x0, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x0, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x0, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x0, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* gc1000_5037 */
+ {
+ 0x1000, /* ChipID */
+ 0x5037, /* ChipRevision */
+ 0x0, /* ProductID */
+ 0x0, /* EcoID */
+ 0x0, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x1, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x200, /* gcFEATURE_VALUE_ThreadCount */
+ 0x2, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x100, /* gcFEATURE_VALUE_InstructionCount */
+ 0x240, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x0, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x0, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x0, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x0, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x0, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x4, /* gcFEATURE_VALUE_Streams */
+ 0x8, /* gcFEATURE_VALUE_VaryingCount */
+ 0x200, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x8, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x1, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x0, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x0, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x1, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x0, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x0, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x0, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x0, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x0, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x0, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x0, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x0, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x0, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x0, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x0, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x0, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x0, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x0, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x0, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x0, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x0, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x0, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x0, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x0, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x0, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x0, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x0, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x0, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x0, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_ACE */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x1, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x0, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x0, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x0, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x0, /* gcFEATURE_BIT_REG_EEZ */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x0, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x0, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x0, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x0, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x0, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x0, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x0, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x0, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x0, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x0, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x0, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x0, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x0, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x0, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x0, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x0, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x0, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x0, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x0, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x0, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x0, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x0, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x0, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x0, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x0, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x0, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x0, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY */
+ 0x0, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x0, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x0, /* gcFEATURE_BIT_DRAWID */
+ 0x0, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x0, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x0, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x0, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x0, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x0, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x0, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x0, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x0, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* gc1000_5037_1 */
+ {
+ 0x1000, /* ChipID */
+ 0x5037, /* ChipRevision */
+ 0x0, /* ProductID */
+ 0x1, /* EcoID */
+ 0x0, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x1, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x200, /* gcFEATURE_VALUE_ThreadCount */
+ 0x2, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x100, /* gcFEATURE_VALUE_InstructionCount */
+ 0x240, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x0, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x0, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x0, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x0, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x0, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x4, /* gcFEATURE_VALUE_Streams */
+ 0x8, /* gcFEATURE_VALUE_VaryingCount */
+ 0x200, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x8, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x1, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x0, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x0, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x1, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x0, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x0, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x0, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x0, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x0, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x0, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x0, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x0, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x0, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x0, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x0, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x0, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x0, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x0, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x0, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x0, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x0, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x0, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x0, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x0, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x0, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x0, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x0, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x0, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x0, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_ACE */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x1, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x0, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x0, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x0, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x0, /* gcFEATURE_BIT_REG_EEZ */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x0, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x0, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x0, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x0, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x0, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x0, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x0, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x0, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x0, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x0, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x0, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x0, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x0, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x0, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x0, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x0, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x0, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x0, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x0, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x0, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x0, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x0, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x0, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x0, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x0, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x0, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x0, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY */
+ 0x0, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x0, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x0, /* gcFEATURE_BIT_DRAWID */
+ 0x0, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x0, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x0, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x0, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x0, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x0, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x0, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x0, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x0, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* gc1000_5039 */
+ {
+ 0x1000, /* ChipID */
+ 0x5039, /* ChipRevision */
+ 0x0, /* ProductID */
+ 0x0, /* EcoID */
+ 0x0, /* CustomerID */
+ 0x11, /* PatchVersion */
+ "", /* ProductName */
+ 0x1, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x200, /* gcFEATURE_VALUE_ThreadCount */
+ 0x2, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x100, /* gcFEATURE_VALUE_InstructionCount */
+ 0x240, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x0, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x0, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x0, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x0, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x0, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x4, /* gcFEATURE_VALUE_Streams */
+ 0x8, /* gcFEATURE_VALUE_VaryingCount */
+ 0x200, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x8, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x1, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x0, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x0, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x1, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x0, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x0, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x0, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x0, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x0, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x0, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x0, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x0, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x0, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x0, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x0, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x0, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x0, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x0, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x0, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x0, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x0, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x0, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x0, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x0, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x0, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x0, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_ACE */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x1, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x0, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x0, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x0, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x0, /* gcFEATURE_BIT_REG_EEZ */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x0, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x0, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x0, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x0, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x0, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x0, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x0, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x0, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x0, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x0, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x0, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x0, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x0, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x0, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x0, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x0, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x0, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x0, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x0, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x0, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x0, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x0, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x0, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x0, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x0, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x0, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x0, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY */
+ 0x0, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x0, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x0, /* gcFEATURE_BIT_DRAWID */
+ 0x0, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x0, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x0, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x0, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x0, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x0, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x0, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x0, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x0, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* gc1500_5246 */
+ {
+ 0x1500, /* ChipID */
+ 0x5246, /* ChipRevision */
+ 0x70003, /* ProductID */
+ 0x0, /* EcoID */
+ 0x0, /* CustomerID */
+ 0x6, /* PatchVersion */
+ "", /* ProductName */
+ 0x1, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x200, /* gcFEATURE_VALUE_ThreadCount */
+ 0x2, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x400, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x1, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x2, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x0, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x0, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x0, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x0, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x8, /* gcFEATURE_VALUE_Streams */
+ 0xf, /* gcFEATURE_VALUE_VaryingCount */
+ 0x200, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x1, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x0, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x0, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x0, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x0, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x0, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x1, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x0, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x0, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x0, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x0, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x0, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x0, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_ACE */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x0, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x0, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x0, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x0, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x0, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x0, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x0, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x0, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x0, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x0, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x0, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x0, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x0, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x0, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x0, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x0, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x0, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x0, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x0, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x0, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x0, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x0, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x0, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x0, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x0, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x0, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x0, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY */
+ 0x0, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x0, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x0, /* gcFEATURE_BIT_DRAWID */
+ 0x0, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x0, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x0, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x0, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x0, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x0, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x1, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x0, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x0, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x0, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* gc2000_5108 */
+ {
+ 0x2000, /* ChipID */
+ 0x5108, /* ChipRevision */
+ 0x0, /* ProductID */
+ 0x0, /* EcoID */
+ 0x0, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x1, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x400, /* gcFEATURE_VALUE_ThreadCount */
+ 0x4, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0xa8, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x1, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x4, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x0, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x0, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x0, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x2, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x0, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x8, /* gcFEATURE_VALUE_Streams */
+ 0xb, /* gcFEATURE_VALUE_VaryingCount */
+ 0x200, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x2, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x0, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x0, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x1, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x0, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x0, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x0, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x0, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x0, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x0, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x0, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x0, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x0, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x0, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x0, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x0, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x0, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x0, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x0, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x0, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x0, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x0, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x0, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x0, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x0, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x0, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x0, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x0, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x0, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x0, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x0, /* gcFEATURE_BIT_REG_Generics */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x0, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x0, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_ACE */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x0, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x0, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x0, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x0, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x0, /* gcFEATURE_BIT_REG_EEZ */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x0, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x0, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x0, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x0, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x0, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x0, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x0, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x0, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x0, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x0, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x0, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x0, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x0, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x0, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x0, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x0, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x0, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x0, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x0, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x0, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x0, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x0, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x0, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x0, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x0, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY */
+ 0x0, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x0, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x0, /* gcFEATURE_BIT_DRAWID */
+ 0x0, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x0, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x0, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x0, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x0, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x0, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x0, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x0, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x0, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* gc2000_5140 */
+ {
+ 0x2000, /* ChipID */
+ 0x5140, /* ChipRevision */
+ 0x0, /* ProductID */
+ 0x0, /* EcoID */
+ 0x0, /* CustomerID */
+ 0x5, /* PatchVersion */
+ "", /* ProductName */
+ 0x0, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x400, /* gcFEATURE_VALUE_ThreadCount */
+ 0x4, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x100, /* gcFEATURE_VALUE_InstructionCount */
+ 0x100, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x1, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x8, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x0, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x0, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x0, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x2, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x0, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x8, /* gcFEATURE_VALUE_Streams */
+ 0x8, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x2, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x0, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x0, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x1, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x0, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x0, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x0, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x0, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x0, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x0, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x0, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x0, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x0, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x0, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x0, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x0, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x0, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x0, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x0, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x0, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x0, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x0, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x0, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x0, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_ACE */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x0, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x0, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x0, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x0, /* gcFEATURE_BIT_REG_EEZ */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x0, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x0, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x0, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x0, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x0, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x0, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x0, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x0, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x0, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x0, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x0, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x0, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x0, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x0, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x0, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x0, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x0, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x0, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x0, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x0, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x0, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x0, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x0, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x0, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x0, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY */
+ 0x0, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x0, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x0, /* gcFEATURE_BIT_DRAWID */
+ 0x0, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x0, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x0, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x0, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x0, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x0, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x0, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x0, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x0, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* gc2000w_5_1_4_rc0e */
+ {
+ 0x2000, /* ChipID */
+ 0x5140, /* ChipRevision */
+ 0x20000, /* ProductID */
+ 0x0, /* EcoID */
+ 0x0, /* CustomerID */
+ 0x5, /* PatchVersion */
+ "", /* ProductName */
+ 0x1, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x400, /* gcFEATURE_VALUE_ThreadCount */
+ 0x4, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x100, /* gcFEATURE_VALUE_InstructionCount */
+ 0x100, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x1, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x8, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x0, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x0, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x0, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x2, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x0, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x8, /* gcFEATURE_VALUE_Streams */
+ 0x8, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x2, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x0, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x0, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x1, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x0, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x0, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x0, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x0, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x0, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x0, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x0, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x0, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x0, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x0, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x0, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x0, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x0, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x0, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x0, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x0, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x0, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x0, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x0, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x0, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x0, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_ACE */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x0, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x0, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x0, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x0, /* gcFEATURE_BIT_REG_EEZ */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x0, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x0, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x0, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x0, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x0, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x0, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x0, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x0, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x0, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x0, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x0, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x0, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x0, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x0, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x0, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x0, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x0, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x0, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x0, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x0, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x0, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x0, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x0, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x0, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY */
+ 0x0, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x0, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x0, /* gcFEATURE_BIT_DRAWID */
+ 0x0, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x0, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x0, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x0, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x0, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x0, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x0, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x0, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x0, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* gc2500_5422 */
+ {
+ 0x2500, /* ChipID */
+ 0x5422, /* ChipRevision */
+ 0x0, /* ProductID */
+ 0x0, /* EcoID */
+ 0x0, /* CustomerID */
+ 0x12, /* PatchVersion */
+ "", /* ProductName */
+ 0x1, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x400, /* gcFEATURE_VALUE_ThreadCount */
+ 0x4, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x1, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x4, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x0, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x2, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x0, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x10, /* gcFEATURE_VALUE_Streams */
+ 0xf, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x2, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x0, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x0, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x0, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x0, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x0, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x0, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x0, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x0, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x0, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x0, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x0, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x0, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x0, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x0, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x0, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x0, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x0, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x0, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x0, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x0, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x0, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x0, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x0, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x0, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x0, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x0, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x0, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x0, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x0, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x0, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY */
+ 0x0, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x0, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x0, /* gcFEATURE_BIT_DRAWID */
+ 0x0, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x0, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x0, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x0, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x0, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x0, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x1, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x1, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x1, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x0, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x0, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x0, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* gc6400_5422 */
+ {
+ 0x6400, /* ChipID */
+ 0x5422, /* ChipRevision */
+ 0x0, /* ProductID */
+ 0x0, /* EcoID */
+ 0x0, /* CustomerID */
+ 0x16, /* PatchVersion */
+ "", /* ProductName */
+ 0x1, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x800, /* gcFEATURE_VALUE_ThreadCount */
+ 0x8, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x1, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x8, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x0, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x2, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x0, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x10, /* gcFEATURE_VALUE_Streams */
+ 0xf, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x2, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x0, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x0, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x0, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x0, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x0, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x0, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x0, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x0, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x0, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x0, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x0, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x0, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x0, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x0, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x0, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x0, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x0, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x0, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x0, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x0, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x0, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x0, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x0, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x0, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x0, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x0, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x0, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x0, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x0, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x0, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY */
+ 0x0, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x0, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x0, /* gcFEATURE_BIT_DRAWID */
+ 0x0, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x0, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x0, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x0, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x0, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x0, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x1, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x1, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x1, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x0, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x0, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x0, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* gc3000_5435 */
+ {
+ 0x3000, /* ChipID */
+ 0x5435, /* ChipRevision */
+ 0x0, /* ProductID */
+ 0x0, /* EcoID */
+ 0x0, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x1, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x400, /* gcFEATURE_VALUE_ThreadCount */
+ 0x4, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x1, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x4, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x0, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x2, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x0, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x10, /* gcFEATURE_VALUE_Streams */
+ 0xf, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x2, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x0, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x0, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x0, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x0, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x0, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x0, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x0, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x0, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x0, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x0, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x0, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x0, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x0, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x0, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x0, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x0, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x0, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x0, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x0, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x0, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x0, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x0, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x0, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x0, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x0, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x0, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x0, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x0, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x0, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x0, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY */
+ 0x0, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x0, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x0, /* gcFEATURE_BIT_DRAWID */
+ 0x0, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x0, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x0, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x0, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x0, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x0, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x1, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x1, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x1, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x1, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x0, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x0, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x0, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* gc2000_ffff5450 */
+ {
+ 0x2000, /* ChipID */
+ 0xffff5450, /* ChipRevision */
+ 0x0, /* ProductID */
+ 0x0, /* EcoID */
+ 0x0, /* CustomerID */
+ 0x8, /* PatchVersion */
+ "", /* ProductName */
+ 0x1, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x400, /* gcFEATURE_VALUE_ThreadCount */
+ 0x4, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x1, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x4, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x0, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x2, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x0, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x10, /* gcFEATURE_VALUE_Streams */
+ 0x10, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x2, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x0, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x0, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x0, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x0, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x0, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x0, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x0, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x0, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x0, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x0, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x0, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x0, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x0, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x0, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x0, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x0, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x0, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x0, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x0, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x0, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x0, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x0, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x0, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x0, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x0, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x0, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x0, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x0, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x0, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY */
+ 0x0, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x0, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x0, /* gcFEATURE_BIT_DRAWID */
+ 0x0, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x0, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x0, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x0, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x0, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x0, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x1, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x1, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x1, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x0, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x0, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x0, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* gc3000_5450 */
+ {
+ 0x3000, /* ChipID */
+ 0x5450, /* ChipRevision */
+ 0x0, /* ProductID */
+ 0x0, /* EcoID */
+ 0x0, /* CustomerID */
+ 0x8, /* PatchVersion */
+ "", /* ProductName */
+ 0x1, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x400, /* gcFEATURE_VALUE_ThreadCount */
+ 0x4, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x1, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x4, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x0, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x2, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x0, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x10, /* gcFEATURE_VALUE_Streams */
+ 0x10, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x2, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x0, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x0, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x0, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x0, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x0, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x0, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x0, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x0, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x0, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x0, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x0, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x0, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x0, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x0, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x0, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x0, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x0, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x0, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x0, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x0, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x0, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x0, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x0, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x0, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x0, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x0, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x0, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x0, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x0, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY */
+ 0x0, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x0, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x0, /* gcFEATURE_BIT_DRAWID */
+ 0x0, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x0, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x0, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x0, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x0, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x0, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x1, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x1, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x1, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x0, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x0, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x0, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* gc3000_5451 */
+ {
+ 0x3000, /* ChipID */
+ 0x5451, /* ChipRevision */
+ 0x0, /* ProductID */
+ 0x0, /* EcoID */
+ 0x0, /* CustomerID */
+ 0x4, /* PatchVersion */
+ "", /* ProductName */
+ 0x1, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x400, /* gcFEATURE_VALUE_ThreadCount */
+ 0x4, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x1, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x4, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x0, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x2, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x0, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x10, /* gcFEATURE_VALUE_Streams */
+ 0x10, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x2, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x0, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x0, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x0, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x0, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x0, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x0, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x0, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x0, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x1, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x0, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x0, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x0, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x0, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x0, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x0, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x0, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x0, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x0, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x0, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x0, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x0, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x0, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x0, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x0, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x0, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x0, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x0, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x0, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x0, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY */
+ 0x0, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x0, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x0, /* gcFEATURE_BIT_DRAWID */
+ 0x0, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x0, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x0, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x0, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x0, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x0, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x1, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x1, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x1, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x0, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x0, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x0, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* gc7000L_551x */
+ {
+ 0x3000, /* ChipID */
+ 0x5512, /* ChipRevision */
+ 0x70002, /* ProductID */
+ 0x0, /* EcoID */
+ 0x0, /* CustomerID */
+ 0x3, /* PatchVersion */
+ "", /* ProductName */
+ 0x0, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x400, /* gcFEATURE_VALUE_ThreadCount */
+ 0x4, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x1, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x4, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x0, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x2, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x0, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x10, /* gcFEATURE_VALUE_Streams */
+ 0x10, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x2, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x0, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x0, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x1, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x0, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x0, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x1, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x0, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x0, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x0, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x0, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x0, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x0, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x0, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x0, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x0, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x0, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x0, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x0, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x0, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x0, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x0, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x0, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x0, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x0, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY */
+ 0x0, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x0, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x0, /* gcFEATURE_BIT_DRAWID */
+ 0x0, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x0, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x0, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x0, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x0, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x0, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x1, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x1, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x1, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x1, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x0, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x0, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* gc7000L_5512 */
+ {
+ 0x3000, /* ChipID */
+ 0x5512, /* ChipRevision */
+ 0x70002, /* ProductID */
+ 0x0, /* EcoID */
+ 0x0, /* CustomerID */
+ 0x3, /* PatchVersion */
+ "", /* ProductName */
+ 0x1, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x400, /* gcFEATURE_VALUE_ThreadCount */
+ 0x4, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x1, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x4, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x0, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x2, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x0, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x10, /* gcFEATURE_VALUE_Streams */
+ 0x10, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x2, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x0, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x0, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x1, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x0, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x0, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x1, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x0, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x0, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x0, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x0, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x0, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x0, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x0, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x0, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x0, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x0, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x0, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x0, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x0, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x0, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x0, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x0, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x0, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x0, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY */
+ 0x0, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x0, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x0, /* gcFEATURE_BIT_DRAWID */
+ 0x0, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x0, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x0, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x0, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x0, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x0, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x1, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x1, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x1, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x1, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x0, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x0, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* gc7000L_5514 */
+ {
+ 0x3000, /* ChipID */
+ 0x5514, /* ChipRevision */
+ 0x70002, /* ProductID */
+ 0x0, /* EcoID */
+ 0x0, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x1, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x400, /* gcFEATURE_VALUE_ThreadCount */
+ 0x4, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x1, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x4, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x0, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x2, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x0, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x10, /* gcFEATURE_VALUE_Streams */
+ 0x10, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x2, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x0, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x0, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x1, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x0, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x0, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x1, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x0, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x0, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x0, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x0, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x0, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x0, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x0, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x0, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x0, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x0, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x0, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x0, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x0, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x0, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x0, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x0, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x0, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x0, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY */
+ 0x0, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x0, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x0, /* gcFEATURE_BIT_DRAWID */
+ 0x0, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x0, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x0, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x0, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x1, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x1, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x1, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x1, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x0, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x0, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* gc4000_5222 */
+ {
+ 0x4000, /* ChipID */
+ 0x5222, /* ChipRevision */
+ 0x0, /* ProductID */
+ 0x0, /* EcoID */
+ 0x0, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x1, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x800, /* gcFEATURE_VALUE_ThreadCount */
+ 0x8, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x800, /* gcFEATURE_VALUE_InstructionCount */
+ 0x200, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x8, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x10, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x0, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x0, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x0, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x2, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x0, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x8, /* gcFEATURE_VALUE_Streams */
+ 0xb, /* gcFEATURE_VALUE_VaryingCount */
+ 0x800, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x2, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x0, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x0, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x1, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x0, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x0, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x0, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x1, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x0, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x0, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x0, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x0, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x0, /* gcFEATURE_BIT_REG_Generics */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x0, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x0, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_ACE */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x0, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x0, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x0, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x0, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x0, /* gcFEATURE_BIT_REG_EEZ */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x0, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x0, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x0, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x0, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x0, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x0, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x0, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x0, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x0, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x0, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x0, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x0, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x0, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x0, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x0, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x0, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x0, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x0, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x0, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x0, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x0, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x0, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x0, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x0, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x0, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY */
+ 0x0, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x0, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x0, /* gcFEATURE_BIT_DRAWID */
+ 0x0, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x0, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x0, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x0, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x0, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x0, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x1, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x0, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x0, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x0, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* gc4000_5245 */
+ {
+ 0x4000, /* ChipID */
+ 0x5245, /* ChipRevision */
+ 0x0, /* ProductID */
+ 0x0, /* EcoID */
+ 0x0, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x1, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x800, /* gcFEATURE_VALUE_ThreadCount */
+ 0x8, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x400, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x8, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x8, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x0, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x0, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x0, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x2, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x0, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x8, /* gcFEATURE_VALUE_Streams */
+ 0xf, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x2, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x0, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x0, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x0, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x0, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x0, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x1, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x0, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x0, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x0, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x0, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_ACE */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x0, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x0, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x0, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x0, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x0, /* gcFEATURE_BIT_REG_EEZ */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x0, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x0, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x0, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x0, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x0, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x0, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x0, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x0, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x0, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x0, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x0, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x0, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x0, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x0, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x0, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x0, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x0, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x0, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x0, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x0, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x0, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x0, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x0, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x0, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x0, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY */
+ 0x0, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x0, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x0, /* gcFEATURE_BIT_DRAWID */
+ 0x0, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x0, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x0, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x0, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x0, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x0, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x1, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x0, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x0, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x0, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* gc5000_5434 */
+ {
+ 0x5000, /* ChipID */
+ 0x5434, /* ChipRevision */
+ 0x0, /* ProductID */
+ 0x0, /* EcoID */
+ 0x0, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x1, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x800, /* gcFEATURE_VALUE_ThreadCount */
+ 0x8, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x1, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x8, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x0, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x2, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x0, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x10, /* gcFEATURE_VALUE_Streams */
+ 0xf, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x2, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x0, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x0, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x0, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x0, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x0, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x0, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x0, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x0, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x0, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x0, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x0, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x0, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x0, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x0, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x0, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x0, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x0, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x0, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x0, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x0, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x0, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x0, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x0, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x0, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x0, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x0, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x0, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x0, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x0, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x0, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x0, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x0, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY */
+ 0x0, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x0, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x0, /* gcFEATURE_BIT_DRAWID */
+ 0x0, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x0, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x0, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x0, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x0, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x0, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x0, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x1, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x1, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x0, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x0, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x0, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* gc7000_551x */
+ {
+ 0x5000, /* ChipID */
+ 0x5513, /* ChipRevision */
+ 0x70000, /* ProductID */
+ 0x0, /* EcoID */
+ 0x0, /* CustomerID */
+ 0x1, /* PatchVersion */
+ "", /* ProductName */
+ 0x0, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x800, /* gcFEATURE_VALUE_ThreadCount */
+ 0x8, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x1, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x8, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x0, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x2, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x0, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x10, /* gcFEATURE_VALUE_Streams */
+ 0x10, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x2, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x0, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x0, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x1, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x0, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x0, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x1, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x0, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x0, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x0, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x0, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x0, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x0, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x0, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x0, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x0, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x0, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x0, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x0, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x0, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x0, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x0, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x0, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x0, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x0, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY */
+ 0x0, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x0, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x0, /* gcFEATURE_BIT_DRAWID */
+ 0x0, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x0, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x0, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x0, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x0, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x0, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x1, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x1, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x1, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x1, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x0, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x0, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* gc7000_5513 */
+ {
+ 0x5000, /* ChipID */
+ 0x5513, /* ChipRevision */
+ 0x70000, /* ProductID */
+ 0x0, /* EcoID */
+ 0x0, /* CustomerID */
+ 0x1, /* PatchVersion */
+ "", /* ProductName */
+ 0x1, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x800, /* gcFEATURE_VALUE_ThreadCount */
+ 0x8, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x1, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x8, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x0, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x2, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x0, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x10, /* gcFEATURE_VALUE_Streams */
+ 0x10, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x2, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x0, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x0, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x1, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x0, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x0, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x1, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x0, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x0, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x0, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x0, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x0, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x0, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x0, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x0, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x0, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x0, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x0, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x0, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x0, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x0, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x0, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x0, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x0, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x0, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY */
+ 0x0, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x0, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x0, /* gcFEATURE_BIT_DRAWID */
+ 0x0, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x0, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x0, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x0, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x0, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x0, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x1, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x1, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x1, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x1, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x0, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x0, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* gcXAQ2_CMODEL */
+ {
+ 0x7000, /* ChipID */
+ 0x0, /* ChipRevision */
+ 0x0, /* ProductID */
+ 0x0, /* EcoID */
+ 0x0, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x0, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x800, /* gcFEATURE_VALUE_ThreadCount */
+ 0x8, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x40, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x40, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x100, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x40, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x2, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x0, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x10, /* gcFEATURE_VALUE_Streams */
+ 0x1f, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x2, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x1, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x1, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x1, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x0, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x1, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x1, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x0, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x1, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x1, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x0, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x0, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x1, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x0, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x1, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x0, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x0, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x1, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x1, /* gcFEATURE_BIT_REG_Evis */
+ 0x1, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x0, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x0, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x0, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x0, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x0, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x0, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x1, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x0, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x0, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x0, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x0, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x0, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x0, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x0, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x0, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x0, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x0, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY */
+ 0x0, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x0, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x0, /* gcFEATURE_BIT_DRAWID */
+ 0x0, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x0, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x0, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x0, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x0, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x1, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x1, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x1, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x1, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x1, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x0, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x0, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* gc7000XS_600x */
+ {
+ 0x7000, /* ChipID */
+ 0x6008, /* ChipRevision */
+ 0x70004, /* ProductID */
+ 0x0, /* EcoID */
+ 0x0, /* CustomerID */
+ 0xb, /* PatchVersion */
+ "", /* ProductName */
+ 0x0, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x800, /* gcFEATURE_VALUE_ThreadCount */
+ 0x8, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x40, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x40, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x40, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x2, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x0, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x10, /* gcFEATURE_VALUE_Streams */
+ 0x1f, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x2, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x0, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x1, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x1, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x1, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x1, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x0, /* gcFEATURE_BIT_REG_Evis */
+ 0x1, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x0, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x0, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x0, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x0, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x0, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x1, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x1, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x0, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x1, /* gcFEATURE_BIT_HWTFB */
+ 0x0, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x0, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x0, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x0, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x0, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x0, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x0, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x0, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY */
+ 0x0, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x0, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x1, /* gcFEATURE_BIT_DRAWID */
+ 0x0, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x1, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x0, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x0, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x0, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x0, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x1, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x1, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x1, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x1, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x0, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x0, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* gc7000XS_6008 */
+ {
+ 0x7000, /* ChipID */
+ 0x6008, /* ChipRevision */
+ 0x70004, /* ProductID */
+ 0x0, /* EcoID */
+ 0x0, /* CustomerID */
+ 0xb, /* PatchVersion */
+ "", /* ProductName */
+ 0x1, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x800, /* gcFEATURE_VALUE_ThreadCount */
+ 0x8, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x40, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x40, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x40, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x2, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x0, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x10, /* gcFEATURE_VALUE_Streams */
+ 0x1f, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x2, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x0, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x1, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x1, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x1, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x1, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x0, /* gcFEATURE_BIT_REG_Evis */
+ 0x1, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x0, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x0, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x0, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x0, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x0, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x1, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x1, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x0, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x1, /* gcFEATURE_BIT_HWTFB */
+ 0x0, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x0, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x0, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x0, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x0, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x0, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x0, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x0, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY */
+ 0x0, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x0, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x1, /* gcFEATURE_BIT_DRAWID */
+ 0x0, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x1, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x0, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x0, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x0, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x0, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x1, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x1, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x1, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x1, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x0, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x0, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* gc7000XSVX_600x */
+ {
+ 0x7000, /* ChipID */
+ 0x6008, /* ChipRevision */
+ 0x70008, /* ProductID */
+ 0x0, /* EcoID */
+ 0x0, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x0, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x800, /* gcFEATURE_VALUE_ThreadCount */
+ 0x8, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x40, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x40, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x40, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x2, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x0, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x10, /* gcFEATURE_VALUE_Streams */
+ 0x1f, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x2, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x0, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x1, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x1, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x1, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x1, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x1, /* gcFEATURE_BIT_REG_Evis */
+ 0x1, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x0, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x0, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x0, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x0, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x0, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x1, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x1, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x0, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x1, /* gcFEATURE_BIT_HWTFB */
+ 0x0, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x0, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x0, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x0, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x0, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x0, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x0, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x0, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY */
+ 0x0, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x0, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x1, /* gcFEATURE_BIT_DRAWID */
+ 0x0, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x1, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x0, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x0, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x0, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x0, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x1, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x1, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x1, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x1, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x0, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x0, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* gc7000XSVX_6008 */
+ {
+ 0x7000, /* ChipID */
+ 0x6008, /* ChipRevision */
+ 0x70008, /* ProductID */
+ 0x0, /* EcoID */
+ 0x0, /* CustomerID */
+ 0x7, /* PatchVersion */
+ "", /* ProductName */
+ 0x1, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x800, /* gcFEATURE_VALUE_ThreadCount */
+ 0x8, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x40, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x40, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x40, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x2, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x0, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x10, /* gcFEATURE_VALUE_Streams */
+ 0x1f, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x2, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x0, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x1, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x1, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x1, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x1, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x1, /* gcFEATURE_BIT_REG_Evis */
+ 0x1, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x0, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x0, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x0, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x0, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x0, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x1, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x1, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x0, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x1, /* gcFEATURE_BIT_HWTFB */
+ 0x0, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x0, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x0, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x0, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x0, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x0, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x0, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x0, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY */
+ 0x0, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x0, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x1, /* gcFEATURE_BIT_DRAWID */
+ 0x0, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x1, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x0, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x0, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x0, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x0, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x1, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x1, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x1, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x1, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x0, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x0, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* gc7000XSVX_6009 */
+ {
+ 0x7000, /* ChipID */
+ 0x6009, /* ChipRevision */
+ 0x70008, /* ProductID */
+ 0x0, /* EcoID */
+ 0x0, /* CustomerID */
+ 0x9, /* PatchVersion */
+ "", /* ProductName */
+ 0x1, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x800, /* gcFEATURE_VALUE_ThreadCount */
+ 0x8, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x40, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x40, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x40, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x2, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x0, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x10, /* gcFEATURE_VALUE_Streams */
+ 0x1f, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x2, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x0, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x1, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x1, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x1, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x1, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x1, /* gcFEATURE_BIT_REG_Evis */
+ 0x1, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x0, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x0, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x0, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x0, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x0, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x1, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x1, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x0, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x1, /* gcFEATURE_BIT_HWTFB */
+ 0x0, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x0, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x0, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x0, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x0, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x0, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x0, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY */
+ 0x0, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x0, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x1, /* gcFEATURE_BIT_DRAWID */
+ 0x0, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x1, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x0, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x0, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x0, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x1, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x1, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x1, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x1, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x1, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x0, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x0, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* gc7000XSVX_6009 */
+ {
+ 0x7000, /* ChipID */
+ 0x6009, /* ChipRevision */
+ 0x70008, /* ProductID */
+ 0x1, /* EcoID */
+ 0x0, /* CustomerID */
+ 0x9, /* PatchVersion */
+ "", /* ProductName */
+ 0x1, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x800, /* gcFEATURE_VALUE_ThreadCount */
+ 0x8, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x40, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x40, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x40, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x2, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x0, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x10, /* gcFEATURE_VALUE_Streams */
+ 0x1f, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x2, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x0, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x1, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x1, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x1, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x1, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x1, /* gcFEATURE_BIT_REG_Evis */
+ 0x1, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x0, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x0, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x0, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x0, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x0, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x1, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x1, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x0, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x1, /* gcFEATURE_BIT_HWTFB */
+ 0x0, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x0, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x0, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x0, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x0, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x0, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x0, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY */
+ 0x0, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x0, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x1, /* gcFEATURE_BIT_DRAWID */
+ 0x0, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x1, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x0, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x0, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x0, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x1, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x1, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x1, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x1, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x1, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x0, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x0, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* gc7000_6100 */
+ {
+ 0x7000, /* ChipID */
+ 0x6100, /* ChipRevision */
+ 0x70000, /* ProductID */
+ 0x0, /* EcoID */
+ 0x0, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x0, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x800, /* gcFEATURE_VALUE_ThreadCount */
+ 0x8, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x20, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x20, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x20, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x2, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x0, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x10, /* gcFEATURE_VALUE_Streams */
+ 0x10, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x1, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x0, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x0, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x1, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x1, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x0, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x0, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x0, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x0, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x0, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x0, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x1, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x0, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x0, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY */
+ 0x0, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x0, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x1, /* gcFEATURE_BIT_DRAWID */
+ 0x0, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x1, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x0, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x0, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x0, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x1, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x1, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x1, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x1, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x1, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x0, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x0, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* gc7000L_6100 */
+ {
+ 0x7000, /* ChipID */
+ 0x6100, /* ChipRevision */
+ 0x70002, /* ProductID */
+ 0x0, /* EcoID */
+ 0x0, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x0, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x400, /* gcFEATURE_VALUE_ThreadCount */
+ 0x4, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x10, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x10, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x2, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x0, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x10, /* gcFEATURE_VALUE_Streams */
+ 0x10, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x1, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x0, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x0, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x1, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x1, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x0, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x0, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x0, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x0, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x0, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x0, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x1, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x0, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x0, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY */
+ 0x0, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x0, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x1, /* gcFEATURE_BIT_DRAWID */
+ 0x0, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x1, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x0, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x0, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x0, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x1, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x1, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x1, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x1, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x1, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x0, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x0, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* gc7000XS_6100 */
+ {
+ 0x7000, /* ChipID */
+ 0x6100, /* ChipRevision */
+ 0x70004, /* ProductID */
+ 0x0, /* EcoID */
+ 0x0, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x0, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x800, /* gcFEATURE_VALUE_ThreadCount */
+ 0x8, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x40, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x40, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x40, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x2, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x0, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x10, /* gcFEATURE_VALUE_Streams */
+ 0x1f, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x2, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x0, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x0, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x1, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x1, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x1, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x1, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x0, /* gcFEATURE_BIT_REG_Evis */
+ 0x1, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x0, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x0, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x0, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x0, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x0, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x1, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x1, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x0, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x1, /* gcFEATURE_BIT_HWTFB */
+ 0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x0, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x0, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY */
+ 0x0, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x0, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x1, /* gcFEATURE_BIT_DRAWID */
+ 0x0, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x1, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x0, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x0, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x0, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x1, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x1, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x1, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x1, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x1, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x0, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x0, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* gc7000_6200 */
+ {
+ 0x7000, /* ChipID */
+ 0x6200, /* ChipRevision */
+ 0x70000, /* ProductID */
+ 0x0, /* EcoID */
+ 0x0, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x0, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x800, /* gcFEATURE_VALUE_ThreadCount */
+ 0x8, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x28, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x20, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x28, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x0, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x10, /* gcFEATURE_VALUE_Streams */
+ 0x10, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x1, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x0, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x1, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x1, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x0, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x1, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x1, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x1, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY */
+ 0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x1, /* gcFEATURE_BIT_DRAWID */
+ 0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x1, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x0, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x0, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x1, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x1, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x0, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x0, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* gc7000UL_6200 */
+ {
+ 0x7000, /* ChipID */
+ 0x6200, /* ChipRevision */
+ 0x70003, /* ProductID */
+ 0x0, /* EcoID */
+ 0x0, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x0, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x200, /* gcFEATURE_VALUE_ThreadCount */
+ 0x2, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x10, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x10, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x0, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x8, /* gcFEATURE_VALUE_Streams */
+ 0x10, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x1, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x10, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x0, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x1, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x1, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x0, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x1, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x1, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x1, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x1, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY */
+ 0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x1, /* gcFEATURE_BIT_DRAWID */
+ 0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x1, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x0, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x0, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x1, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x1, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x0, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x0, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* gc7000ULVX_6200 */
+ {
+ 0x7000, /* ChipID */
+ 0x6200, /* ChipRevision */
+ 0x7000f, /* ProductID */
+ 0x0, /* EcoID */
+ 0x0, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x0, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x200, /* gcFEATURE_VALUE_ThreadCount */
+ 0x2, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x10, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x8, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x0, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x8, /* gcFEATURE_VALUE_Streams */
+ 0x10, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x1, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x10, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x1, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x1, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x1, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x1, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x1, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x1, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x1, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x1, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY */
+ 0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x1, /* gcFEATURE_BIT_DRAWID */
+ 0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x1, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x0, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x0, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x1, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x1, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x1, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x1, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x1, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x1, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x1, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x1, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x1, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x1, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x1, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x1, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x0, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x0, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* gc7400_551x */
+ {
+ 0x7400, /* ChipID */
+ 0x5515, /* ChipRevision */
+ 0x74000, /* ProductID */
+ 0x0, /* EcoID */
+ 0x0, /* CustomerID */
+ 0x6, /* PatchVersion */
+ "", /* ProductName */
+ 0x0, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x800, /* gcFEATURE_VALUE_ThreadCount */
+ 0x8, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x8, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x0, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x2, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x0, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x10, /* gcFEATURE_VALUE_Streams */
+ 0x10, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x2, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x0, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x0, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x0, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x1, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x0, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x0, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x0, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x0, /* gcFEATURE_BIT_REG_Evis */
+ 0x1, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x1, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x0, /* gcFEATURE_BIT_VMSAA */
+ 0x1, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x0, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x0, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x0, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x0, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x0, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x0, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x0, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x0, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x0, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x0, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x0, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x0, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x0, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x0, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY */
+ 0x0, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x0, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x1, /* gcFEATURE_BIT_DRAWID */
+ 0x0, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x1, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x0, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x0, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x0, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x0, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x1, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x1, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x1, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x1, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x0, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x0, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* gc8000UL_6200 */
+ {
+ 0x8000, /* ChipID */
+ 0x6200, /* ChipRevision */
+ 0x80003, /* ProductID */
+ 0x0, /* EcoID */
+ 0x0, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x0, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x200, /* gcFEATURE_VALUE_ThreadCount */
+ 0x2, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x8, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x8, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x8, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x0, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x8, /* gcFEATURE_VALUE_Streams */
+ 0x10, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x1, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x10, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x1, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x1, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x1, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x0, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x1, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x1, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x1, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x0, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY */
+ 0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x1, /* gcFEATURE_BIT_DRAWID */
+ 0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x1, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x0, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x0, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x1, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x1, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x1, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x1, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x0, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x0, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* v630 */
+ {
+ 0x7000, /* ChipID */
+ 0x6300, /* ChipRevision */
+ 0x0, /* ProductID */
+ 0x0, /* EcoID */
+ 0x0, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x0, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x800, /* gcFEATURE_VALUE_ThreadCount */
+ 0x8, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x40, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x20, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x40, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x0, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x10, /* gcFEATURE_VALUE_Streams */
+ 0x1f, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x1, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x0, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x1, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x1, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x1, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x1, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x0, /* gcFEATURE_BIT_REG_Evis */
+ 0x1, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x1, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x1, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x1, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x1, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x0, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x1, /* gcFEATURE_BIT_HWTFB */
+ 0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY */
+ 0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x1, /* gcFEATURE_BIT_DRAWID */
+ 0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x1, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x0, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x0, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x1, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x1, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x1, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x1, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x1, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x0, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x0, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* gc7000XS_6200 */
+ {
+ 0x7000, /* ChipID */
+ 0x6200, /* ChipRevision */
+ 0x70004, /* ProductID */
+ 0x0, /* EcoID */
+ 0x0, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x0, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x800, /* gcFEATURE_VALUE_ThreadCount */
+ 0x8, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x40, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x20, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x40, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x2, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x0, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x10, /* gcFEATURE_VALUE_Streams */
+ 0x1f, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x1, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x0, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x1, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x1, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x1, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x1, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x0, /* gcFEATURE_BIT_REG_Evis */
+ 0x1, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x1, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x1, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x1, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x1, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x0, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x1, /* gcFEATURE_BIT_HWTFB */
+ 0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY */
+ 0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x1, /* gcFEATURE_BIT_DRAWID */
+ 0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x1, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x0, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x0, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x1, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x1, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x1, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x1, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x1, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x0, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x0, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* gc7000L_6200 */
+ {
+ 0x7000, /* ChipID */
+ 0x6200, /* ChipRevision */
+ 0x70002, /* ProductID */
+ 0x0, /* EcoID */
+ 0x0, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x0, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x400, /* gcFEATURE_VALUE_ThreadCount */
+ 0x4, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x10, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x10, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x2, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x0, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x10, /* gcFEATURE_VALUE_Streams */
+ 0x10, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x1, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x0, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x1, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x1, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x0, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x1, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x1, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x1, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY */
+ 0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x1, /* gcFEATURE_BIT_DRAWID */
+ 0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x1, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x0, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x0, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x1, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x1, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x1, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x1, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x0, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x0, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* gc7000LXS_6200 */
+ {
+ 0x7000, /* ChipID */
+ 0x6200, /* ChipRevision */
+ 0x7000a, /* ProductID */
+ 0x0, /* EcoID */
+ 0x0, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x0, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x400, /* gcFEATURE_VALUE_ThreadCount */
+ 0x4, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x40, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x20, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x40, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x2, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x0, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x10, /* gcFEATURE_VALUE_Streams */
+ 0x1f, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x1, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x0, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x1, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x1, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x1, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x1, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x0, /* gcFEATURE_BIT_REG_Evis */
+ 0x1, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x1, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x1, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x1, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x1, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x0, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x1, /* gcFEATURE_BIT_HWTFB */
+ 0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY */
+ 0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x1, /* gcFEATURE_BIT_DRAWID */
+ 0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x1, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x0, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x0, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x1, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x1, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x1, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x1, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x0, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x0, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* gc7000ULVX_V11_6200 */
+ {
+ 0x7000, /* ChipID */
+ 0x6200, /* ChipRevision */
+ 0x7000f, /* ProductID */
+ 0x0, /* EcoID */
+ 0x1, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x0, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x200, /* gcFEATURE_VALUE_ThreadCount */
+ 0x2, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x10, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x8, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x0, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x8, /* gcFEATURE_VALUE_Streams */
+ 0x10, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x1, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x10, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x0, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x1, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x1, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x1, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x1, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x0, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x0, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x1, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x1, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY */
+ 0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x1, /* gcFEATURE_BIT_DRAWID */
+ 0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x1, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x0, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x0, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x0, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x1, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x1, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x1, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x1, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x1, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x1, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x1, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x1, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x1, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x1, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x1, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x1, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x1, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x1, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x0, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x0, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* gc7000ULVX_V12_6200 */
+ {
+ 0x7000, /* ChipID */
+ 0x6200, /* ChipRevision */
+ 0x7000f, /* ProductID */
+ 0x0, /* EcoID */
+ 0x2, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x0, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x200, /* gcFEATURE_VALUE_ThreadCount */
+ 0x2, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x10, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x8, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x0, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x8, /* gcFEATURE_VALUE_Streams */
+ 0x10, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x1, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x10, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x0, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x0, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x1, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x1, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x1, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x0, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x0, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x1, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x1, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY */
+ 0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x1, /* gcFEATURE_BIT_DRAWID */
+ 0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x1, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x0, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x0, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x0, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x1, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x1, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x1, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x1, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x1, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x0, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x0, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* gc8000ULVX */
+ {
+ 0x8000, /* ChipID */
+ 0x6200, /* ChipRevision */
+ 0x8000f, /* ProductID */
+ 0x0, /* EcoID */
+ 0x3, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x0, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x200, /* gcFEATURE_VALUE_ThreadCount */
+ 0x2, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x10, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x8, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x0, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x10, /* gcFEATURE_VALUE_Streams */
+ 0x10, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x1, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x10, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x0, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x0, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x1, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x1, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x1, /* gcFEATURE_BIT_REG_Evis */
+ 0x1, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x0, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x0, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x1, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x1, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY */
+ 0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x1, /* gcFEATURE_BIT_DRAWID */
+ 0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x1, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x1, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x1, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x1, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x1, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x1, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x1, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x1, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x1, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x1, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x1, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x1, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x1, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x1, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x1, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x1, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x1, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x1, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x1, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x1, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x1, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x1, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x1, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x1, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x1, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x1, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x1, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x0, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x0, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* GCNANOULTRA31_VIP2 */
+ {
+ 0x7000, /* ChipID */
+ 0x6204, /* ChipRevision */
+ 0x70007, /* ProductID */
+ 0x0, /* EcoID */
+ 0x13, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "GCNANOULTRA31_VIP2", /* ProductName */
+ 0x0, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x200, /* gcFEATURE_VALUE_ThreadCount */
+ 0x2, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x10, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x8, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x0, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x10, /* gcFEATURE_VALUE_Streams */
+ 0x10, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x1, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x10, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x40, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x2, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x2, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x6, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x2, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x1, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x180, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x7, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x0, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x0, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x1, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x1, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x1, /* gcFEATURE_BIT_REG_Evis */
+ 0x1, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x0, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x0, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x1, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x1, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY */
+ 0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x1, /* gcFEATURE_BIT_DRAWID */
+ 0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x1, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x1, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x1, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x1, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x1, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x1, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x1, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x1, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x1, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x1, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x1, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x1, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x1, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x1, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x1, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x1, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x1, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x1, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x1, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x1, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x1, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x1, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x1, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x1, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x1, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x1, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x1, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x1, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x1, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x1, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x1, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x1, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER */
+ 0x1, /* gcFEATURE_BIT_TP_LRN */
+ 0x1, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x1, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x1, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x1, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x1, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x1, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x1, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x1, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x1, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x1, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x1, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x1, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x1, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x1, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x1, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* gc7000ULVX_6200_pid0x60 */
+ {
+ 0x7000, /* ChipID */
+ 0x6203, /* ChipRevision */
+ 0x7000f, /* ProductID */
+ 0x0, /* EcoID */
+ 0x60, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x0, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x200, /* gcFEATURE_VALUE_ThreadCount */
+ 0x2, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x10, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x8, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x0, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x8, /* gcFEATURE_VALUE_Streams */
+ 0x10, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x1, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x10, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x0, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x0, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x1, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x1, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x1, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x0, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x0, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x1, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x1, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY */
+ 0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x1, /* gcFEATURE_BIT_DRAWID */
+ 0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x1, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x0, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x0, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x1, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x1, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x1, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x1, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x1, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x1, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x1, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x0, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x0, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* gc7000ULN_v122 */
+ {
+ 0x7000, /* ChipID */
+ 0x6203, /* ChipRevision */
+ 0x70003, /* ProductID */
+ 0x0, /* EcoID */
+ 0x4, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x0, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x200, /* gcFEATURE_VALUE_ThreadCount */
+ 0x2, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x8, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x8, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x8, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x0, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x10, /* gcFEATURE_VALUE_Streams */
+ 0x10, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x1, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x10, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x0, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x0, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x1, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x1, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x0, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x0, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x0, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x1, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x1, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY */
+ 0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x1, /* gcFEATURE_BIT_DRAWID */
+ 0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x1, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x0, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x0, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x1, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x1, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x1, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x1, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x1, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x1, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x1, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x1, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x1, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x1, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x1, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x1, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x1, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x1, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x1, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x0, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x0, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* gc7000ULN_v123 */
+ {
+ 0x7000, /* ChipID */
+ 0x6203, /* ChipRevision */
+ 0x70003, /* ProductID */
+ 0x0, /* EcoID */
+ 0x11, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x0, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x200, /* gcFEATURE_VALUE_ThreadCount */
+ 0x2, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x8, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x8, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x8, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x0, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x10, /* gcFEATURE_VALUE_Streams */
+ 0x10, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x1, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x10, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x0, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x0, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x1, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x1, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x0, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x0, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x0, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x1, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x1, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY */
+ 0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x1, /* gcFEATURE_BIT_DRAWID */
+ 0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x1, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x0, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x0, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x1, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x1, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x1, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x1, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x1, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x1, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x1, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x1, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x1, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x1, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x1, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x1, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x1, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x1, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x1, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x1, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x1, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x0, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x0, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* gc7000XS_6FFF */
+ {
+ 0x7000, /* ChipID */
+ 0x6fff, /* ChipRevision */
+ 0x70004, /* ProductID */
+ 0x0, /* EcoID */
+ 0x0, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x0, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x800, /* gcFEATURE_VALUE_ThreadCount */
+ 0x8, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x40, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x20, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x40, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x2, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x0, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x10, /* gcFEATURE_VALUE_Streams */
+ 0x1f, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x1, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x0, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x1, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x1, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x1, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x1, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x0, /* gcFEATURE_BIT_REG_Evis */
+ 0x1, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x1, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x1, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x1, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x1, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x0, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x1, /* gcFEATURE_BIT_HWTFB */
+ 0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY */
+ 0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x1, /* gcFEATURE_BIT_DRAWID */
+ 0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x1, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x0, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x0, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x1, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x1, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x1, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x1, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x0, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x0, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* gc7000_6210 */
+ {
+ 0x7000, /* ChipID */
+ 0x6210, /* ChipRevision */
+ 0x70000, /* ProductID */
+ 0x0, /* EcoID */
+ 0x6, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x0, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x800, /* gcFEATURE_VALUE_ThreadCount */
+ 0x8, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x10, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x10, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x2, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x0, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x10, /* gcFEATURE_VALUE_Streams */
+ 0x10, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x1, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x0, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x1, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x1, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x0, /* gcFEATURE_BIT_REG_Evis */
+ 0x1, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x1, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x1, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x1, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY */
+ 0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x1, /* gcFEATURE_BIT_DRAWID */
+ 0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x1, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x1, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x1, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x1, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x1, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x1, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x1, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x1, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x1, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x1, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x1, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x0, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x0, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* gc7000_6210 */
+ {
+ 0x7000, /* ChipID */
+ 0x6210, /* ChipRevision */
+ 0x70000, /* ProductID */
+ 0x0, /* EcoID */
+ 0xa, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x0, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x800, /* gcFEATURE_VALUE_ThreadCount */
+ 0x8, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x10, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x10, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x2, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x0, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x10, /* gcFEATURE_VALUE_Streams */
+ 0x10, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x1, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x0, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x1, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x1, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x0, /* gcFEATURE_BIT_REG_Evis */
+ 0x1, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x1, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x1, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x1, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY */
+ 0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x1, /* gcFEATURE_BIT_DRAWID */
+ 0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x1, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x1, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x1, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x1, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x1, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x1, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x1, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x1, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x1, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x1, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x1, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x1, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x1, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x1, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x1, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x1, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x0, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x0, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* gc7000XS_6210 */
+ {
+ 0x7000, /* ChipID */
+ 0x6210, /* ChipRevision */
+ 0x70004, /* ProductID */
+ 0x0, /* EcoID */
+ 0x8, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x0, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x800, /* gcFEATURE_VALUE_ThreadCount */
+ 0x8, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x30, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x10, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x30, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x2, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x0, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x10, /* gcFEATURE_VALUE_Streams */
+ 0x10, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x1, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x0, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x1, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x1, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x1, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x1, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x0, /* gcFEATURE_BIT_REG_Evis */
+ 0x1, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x1, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x1, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x1, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x0, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x1, /* gcFEATURE_BIT_HWTFB */
+ 0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY */
+ 0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x1, /* gcFEATURE_BIT_DRAWID */
+ 0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x1, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x1, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x1, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x1, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x1, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x1, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x1, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x1, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x1, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x1, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x1, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x1, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x1, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x1, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x1, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x1, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x1, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x0, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x0, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* gc8000XS_6210 */
+ {
+ 0x8000, /* ChipID */
+ 0x6210, /* ChipRevision */
+ 0x80004, /* ProductID */
+ 0x0, /* EcoID */
+ 0xd, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x0, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x800, /* gcFEATURE_VALUE_ThreadCount */
+ 0x8, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x30, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x10, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x30, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x2, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x0, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x10, /* gcFEATURE_VALUE_Streams */
+ 0x10, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x1, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x0, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x1, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x1, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x1, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x1, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x0, /* gcFEATURE_BIT_REG_Evis */
+ 0x1, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x1, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x1, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x1, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x0, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x1, /* gcFEATURE_BIT_HWTFB */
+ 0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY */
+ 0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x1, /* gcFEATURE_BIT_DRAWID */
+ 0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x1, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x1, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x1, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x1, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x1, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x1, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x1, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x1, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x1, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x1, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x1, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x1, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x1, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x1, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x1, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x1, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x0, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x0, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* gc8200LXS */
+ {
+ 0x8200, /* ChipID */
+ 0x6212, /* ChipRevision */
+ 0x8200a, /* ProductID */
+ 0x0, /* EcoID */
+ 0xe, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x0, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x800, /* gcFEATURE_VALUE_ThreadCount */
+ 0x8, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x2, /* gcFEATURE_VALUE_CoreCount */
+ 0x30, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x10, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x30, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x2, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x0, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x10, /* gcFEATURE_VALUE_Streams */
+ 0x10, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x1, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x0, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x1, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x1, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x1, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x1, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x0, /* gcFEATURE_BIT_REG_Evis */
+ 0x1, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x1, /* gcFEATURE_BIT_VMSAA */
+ 0x1, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x1, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x1, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x0, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x1, /* gcFEATURE_BIT_HWTFB */
+ 0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY */
+ 0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x1, /* gcFEATURE_BIT_DRAWID */
+ 0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x1, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x1, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x1, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x1, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x1, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x1, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x1, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x1, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x1, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x1, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x1, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x1, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x1, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x1, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x1, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x1, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x0, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x0, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* gc7000XS_6210 */
+ {
+ 0x7000, /* ChipID */
+ 0x6210, /* ChipRevision */
+ 0x70004, /* ProductID */
+ 0x0, /* EcoID */
+ 0xc, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x0, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x800, /* gcFEATURE_VALUE_ThreadCount */
+ 0x8, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x30, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x10, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x30, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x2, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x0, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x10, /* gcFEATURE_VALUE_Streams */
+ 0x10, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x1, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x0, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x1, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x1, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x1, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x1, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x0, /* gcFEATURE_BIT_REG_Evis */
+ 0x1, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x1, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x1, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x1, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x0, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x1, /* gcFEATURE_BIT_HWTFB */
+ 0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY */
+ 0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x1, /* gcFEATURE_BIT_DRAWID */
+ 0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x1, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x1, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x1, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x1, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x1, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x1, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x1, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x1, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x1, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x1, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x1, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x1, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x1, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x1, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x1, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x1, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x1, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x0, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x0, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* gc7000L_6210 */
+ {
+ 0x7000, /* ChipID */
+ 0x6210, /* ChipRevision */
+ 0x70002, /* ProductID */
+ 0x0, /* EcoID */
+ 0x5, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x0, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x400, /* gcFEATURE_VALUE_ThreadCount */
+ 0x4, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x10, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x8, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x2, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x0, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x10, /* gcFEATURE_VALUE_Streams */
+ 0x10, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x1, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x0, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x1, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x1, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x0, /* gcFEATURE_BIT_REG_Evis */
+ 0x1, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x1, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x1, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x1, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY */
+ 0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x1, /* gcFEATURE_BIT_DRAWID */
+ 0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x1, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x1, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x1, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x1, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x1, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x1, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x1, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x1, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x1, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x1, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x1, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x1, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x0, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x0, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* gc7000L_6210 */
+ {
+ 0x7000, /* ChipID */
+ 0x6210, /* ChipRevision */
+ 0x70002, /* ProductID */
+ 0x0, /* EcoID */
+ 0x9, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x0, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x400, /* gcFEATURE_VALUE_ThreadCount */
+ 0x4, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x10, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x8, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x2, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x0, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x10, /* gcFEATURE_VALUE_Streams */
+ 0x10, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x1, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x0, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x1, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x1, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x0, /* gcFEATURE_BIT_REG_Evis */
+ 0x1, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x1, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x1, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x1, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY */
+ 0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x1, /* gcFEATURE_BIT_DRAWID */
+ 0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x1, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x1, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x1, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x1, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x1, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x1, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x1, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x1, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x1, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x1, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x1, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x1, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x1, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x1, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x1, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x1, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x0, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x0, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* gc7000LXS_6210 */
+ {
+ 0x7000, /* ChipID */
+ 0x6210, /* ChipRevision */
+ 0x7000a, /* ProductID */
+ 0x0, /* EcoID */
+ 0x0, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x0, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x400, /* gcFEATURE_VALUE_ThreadCount */
+ 0x4, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x30, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x8, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x30, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x2, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x0, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x10, /* gcFEATURE_VALUE_Streams */
+ 0x10, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x1, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x0, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x1, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x1, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x1, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x1, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x0, /* gcFEATURE_BIT_REG_Evis */
+ 0x1, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x1, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x1, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x1, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x0, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x1, /* gcFEATURE_BIT_HWTFB */
+ 0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY */
+ 0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x1, /* gcFEATURE_BIT_DRAWID */
+ 0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x1, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x1, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x1, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x1, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x1, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x1, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x1, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x1, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x1, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x1, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x1, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x1, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x1, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x1, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x1, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x1, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x0, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x0, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* gc7000XSVX_6210 */
+ {
+ 0x7000, /* ChipID */
+ 0x6210, /* ChipRevision */
+ 0x70008, /* ProductID */
+ 0x0, /* EcoID */
+ 0x7, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x0, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x800, /* gcFEATURE_VALUE_ThreadCount */
+ 0x8, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x40, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x20, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x40, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x2, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x0, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x10, /* gcFEATURE_VALUE_Streams */
+ 0x10, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x1, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x0, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x1, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x1, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x1, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x1, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x1, /* gcFEATURE_BIT_REG_Evis */
+ 0x1, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x1, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x1, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x1, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x0, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x1, /* gcFEATURE_BIT_HWTFB */
+ 0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY */
+ 0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x1, /* gcFEATURE_BIT_DRAWID */
+ 0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x1, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x1, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x1, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x1, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x1, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x1, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x1, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x1, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x1, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x1, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x1, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x1, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x1, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x1, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x1, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x1, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x1, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x0, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x0, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* gc7000XSVX_6210 */
+ {
+ 0x7000, /* ChipID */
+ 0x6210, /* ChipRevision */
+ 0x70008, /* ProductID */
+ 0x0, /* EcoID */
+ 0xb, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x0, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x800, /* gcFEATURE_VALUE_ThreadCount */
+ 0x8, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x40, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x20, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x40, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x2, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x0, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x10, /* gcFEATURE_VALUE_Streams */
+ 0x10, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x1, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x0, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x1, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x1, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x1, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x1, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x1, /* gcFEATURE_BIT_REG_Evis */
+ 0x1, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x1, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x1, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x1, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x0, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x1, /* gcFEATURE_BIT_HWTFB */
+ 0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY */
+ 0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x1, /* gcFEATURE_BIT_DRAWID */
+ 0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x1, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x1, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x1, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x1, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x1, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x1, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x1, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x1, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x1, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x1, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x1, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x1, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x1, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x1, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x1, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x1, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x1, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x0, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x0, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* gc7000L_DEC400 */
+ {
+ 0x7000, /* ChipID */
+ 0x6214, /* ChipRevision */
+ 0x70002, /* ProductID */
+ 0x0, /* EcoID */
+ 0x30, /* CustomerID */
+ 0x8, /* PatchVersion */
+ "", /* ProductName */
+ 0x1, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x400, /* gcFEATURE_VALUE_ThreadCount */
+ 0x4, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x10, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x8, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x2, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x0, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x10, /* gcFEATURE_VALUE_Streams */
+ 0x10, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x1, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x0, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x1, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x1, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x0, /* gcFEATURE_BIT_REG_Evis */
+ 0x1, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x1, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x1, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x1, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY */
+ 0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x1, /* gcFEATURE_BIT_DRAWID */
+ 0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x1, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x1, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x1, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x1, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x1, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x1, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x1, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x1, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x1, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x1, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x1, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x1, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x1, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x1, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x1, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x1, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x1, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x1, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x0, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x0, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* gc7000L_DEC400 */
+ {
+ 0x7000, /* ChipID */
+ 0x6214, /* ChipRevision */
+ 0x70002, /* ProductID */
+ 0x1, /* EcoID */
+ 0x30, /* CustomerID */
+ 0x8, /* PatchVersion */
+ "", /* ProductName */
+ 0x1, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x400, /* gcFEATURE_VALUE_ThreadCount */
+ 0x4, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x10, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x8, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x2, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x0, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x10, /* gcFEATURE_VALUE_Streams */
+ 0x10, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x1, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x0, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x1, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x1, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x0, /* gcFEATURE_BIT_REG_Evis */
+ 0x1, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x1, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x1, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x1, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY */
+ 0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x1, /* gcFEATURE_BIT_DRAWID */
+ 0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x1, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x1, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x1, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x1, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x1, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x1, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x1, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x1, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x1, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x1, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x1, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x1, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x1, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x1, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x1, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x1, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x1, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x1, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x0, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x0, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* gc7400_0002 */
+ {
+ 0x8400, /* ChipID */
+ 0x6310, /* ChipRevision */
+ 0x8400a, /* ProductID */
+ 0x0, /* EcoID */
+ 0x44, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x0, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x800, /* gcFEATURE_VALUE_ThreadCount */
+ 0x8, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x30, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x10, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x30, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x2, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x0, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x8, /* gcFEATURE_VALUE_Streams */
+ 0x10, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x1, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x0, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x1, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x1, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x1, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x1, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x0, /* gcFEATURE_BIT_REG_Evis */
+ 0x1, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x1, /* gcFEATURE_BIT_VMSAA */
+ 0x1, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x1, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x1, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x0, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x1, /* gcFEATURE_BIT_HWTFB */
+ 0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY */
+ 0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x1, /* gcFEATURE_BIT_DRAWID */
+ 0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x1, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x1, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x1, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x1, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x1, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x1, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x1, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x1, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x1, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x1, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x1, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x1, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x1, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x1, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x1, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x1, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x1, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x1, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x0, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x0, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* gc7400_0003 */
+ {
+ 0x8400, /* ChipID */
+ 0x6310, /* ChipRevision */
+ 0x8400a, /* ProductID */
+ 0x0, /* EcoID */
+ 0x45, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x0, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x400, /* gcFEATURE_VALUE_ThreadCount */
+ 0x4, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x30, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x8, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x30, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x2, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x0, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x8, /* gcFEATURE_VALUE_Streams */
+ 0x10, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x1, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x0, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x1, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x1, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x1, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x1, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x0, /* gcFEATURE_BIT_REG_Evis */
+ 0x1, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x1, /* gcFEATURE_BIT_VMSAA */
+ 0x1, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x1, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x1, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x0, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x1, /* gcFEATURE_BIT_HWTFB */
+ 0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY */
+ 0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x1, /* gcFEATURE_BIT_DRAWID */
+ 0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x1, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x1, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x1, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x1, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x1, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x1, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x1, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x1, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x1, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x1, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x1, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x1, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x1, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x1, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x1, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x1, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x1, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x1, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x0, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x0, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* gc8400_6300 */
+ {
+ 0x8400, /* ChipID */
+ 0x6300, /* ChipRevision */
+ 0x84004, /* ProductID */
+ 0x0, /* EcoID */
+ 0x41, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x0, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x800, /* gcFEATURE_VALUE_ThreadCount */
+ 0x10, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x40, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x40, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x40, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x2, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x0, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x10, /* gcFEATURE_VALUE_Streams */
+ 0x10, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x1, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0xf, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x0, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x1, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x0, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x1, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x1, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x1, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x1, /* gcFEATURE_BIT_REG_Evis */
+ 0x1, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x1, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x1, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x1, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x0, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x1, /* gcFEATURE_BIT_HWTFB */
+ 0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY */
+ 0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x1, /* gcFEATURE_BIT_DRAWID */
+ 0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x1, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x1, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x1, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x1, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x1, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x1, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x1, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x1, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x1, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x1, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x1, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x1, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x1, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x1, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x1, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x1, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x1, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x1, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x1, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x0, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x0, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* gc8100_6300_pid0x43 */
+ {
+ 0x8100, /* ChipID */
+ 0x6300, /* ChipRevision */
+ 0x81004, /* ProductID */
+ 0x0, /* EcoID */
+ 0x43, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x0, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x800, /* gcFEATURE_VALUE_ThreadCount */
+ 0x10, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x40, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x40, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x40, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x2, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x0, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x10, /* gcFEATURE_VALUE_Streams */
+ 0x10, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x1, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x1, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x0, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x1, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x0, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x1, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x1, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x1, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x1, /* gcFEATURE_BIT_REG_Evis */
+ 0x1, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x1, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x1, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x1, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x0, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x1, /* gcFEATURE_BIT_HWTFB */
+ 0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY */
+ 0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x1, /* gcFEATURE_BIT_DRAWID */
+ 0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x1, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x1, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x1, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x1, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x1, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x1, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x1, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x1, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x1, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x1, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x1, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x1, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x1, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x1, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x1, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x1, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x1, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x1, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x1, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x0, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x0, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* gc8200_6300_pid0x46 */
+ {
+ 0x8200, /* ChipID */
+ 0x6300, /* ChipRevision */
+ 0x82004, /* ProductID */
+ 0x0, /* EcoID */
+ 0x46, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x0, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x800, /* gcFEATURE_VALUE_ThreadCount */
+ 0x10, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x40, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x40, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x40, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x2, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x0, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x10, /* gcFEATURE_VALUE_Streams */
+ 0x10, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x1, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x3, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x0, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x0, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x1, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x0, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x1, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x1, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x1, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x1, /* gcFEATURE_BIT_REG_Evis */
+ 0x1, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x1, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x1, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x1, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x0, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x1, /* gcFEATURE_BIT_HWTFB */
+ 0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY */
+ 0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x1, /* gcFEATURE_BIT_DRAWID */
+ 0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x1, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x1, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x1, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x1, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x1, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x1, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x1, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x1, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x1, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x1, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x1, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x1, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x1, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x1, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x1, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x1, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x1, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x1, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x1, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x0, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x0, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* cc8000_6330 */
+ {
+ 0x8000, /* ChipID */
+ 0x6330, /* ChipRevision */
+ 0x6080000, /* ProductID */
+ 0x0, /* EcoID */
+ 0x51, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x0, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x800, /* gcFEATURE_VALUE_ThreadCount */
+ 0x8, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x20, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x20, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x20, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x0, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x10, /* gcFEATURE_VALUE_Streams */
+ 0x1f, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x0, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x1, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x1, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x0, /* gcFEATURE_BIT_REG_Evis */
+ 0x1, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x1, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x1, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x1, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY */
+ 0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x1, /* gcFEATURE_BIT_DRAWID */
+ 0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x1, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x1, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x1, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x1, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x1, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x1, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x1, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x1, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x1, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x1, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x1, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x1, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x0, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x0, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* vip7000UL_6100 */
+ {
+ 0x7000, /* ChipID */
+ 0x6100, /* ChipRevision */
+ 0x5070003, /* ProductID */
+ 0x0, /* EcoID */
+ 0x0, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x0, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x200, /* gcFEATURE_VALUE_ThreadCount */
+ 0x2, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x10, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x10, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x2, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x2, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x8, /* gcFEATURE_VALUE_Streams */
+ 0x10, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x0, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x1, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x1, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x1, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x1, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x0, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x0, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x0, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x0, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x0, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x1, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x1, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x0, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x1, /* gcFEATURE_BIT_HWTFB */
+ 0x0, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x0, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x0, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x0, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x0, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x0, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x0, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x0, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY */
+ 0x0, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x0, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x1, /* gcFEATURE_BIT_DRAWID */
+ 0x0, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x1, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x0, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x0, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x1, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x0, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x1, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x0, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x0, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x1, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* vip7000L_6200 */
+ {
+ 0x7000, /* ChipID */
+ 0x6200, /* ChipRevision */
+ 0x5070002, /* ProductID */
+ 0x0, /* EcoID */
+ 0x0, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x0, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x400, /* gcFEATURE_VALUE_ThreadCount */
+ 0x4, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x20, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x20, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x20, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x2, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x2, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x8, /* gcFEATURE_VALUE_Streams */
+ 0x10, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x0, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x1, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x1, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x1, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x1, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x1, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x1, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY */
+ 0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x1, /* gcFEATURE_BIT_DRAWID */
+ 0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x1, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x1, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x1, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x0, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x0, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x1, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* vip7000UL_6200 */
+ {
+ 0x7000, /* ChipID */
+ 0x6201, /* ChipRevision */
+ 0x5070003, /* ProductID */
+ 0x0, /* EcoID */
+ 0x0, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x1, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x200, /* gcFEATURE_VALUE_ThreadCount */
+ 0x2, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x10, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x10, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x2, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x2, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x8, /* gcFEATURE_VALUE_Streams */
+ 0x10, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x0, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x1, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x1, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x1, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x1, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x1, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x1, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY */
+ 0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x1, /* gcFEATURE_BIT_DRAWID */
+ 0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x1, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x1, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x1, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x0, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x0, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x0, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x1, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* vip8000UL_6211 */
+ {
+ 0x8000, /* ChipID */
+ 0x6212, /* ChipRevision */
+ 0x5080003, /* ProductID */
+ 0x0, /* EcoID */
+ 0x21, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x0, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x200, /* gcFEATURE_VALUE_ThreadCount */
+ 0x2, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x10, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x8, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x2, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x2, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x8, /* gcFEATURE_VALUE_Streams */
+ 0x10, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x0, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x40, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x1, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x1, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x6, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0xe0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x3, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x1, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x1, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x1, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x1, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x1, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x1, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY */
+ 0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x1, /* gcFEATURE_BIT_DRAWID */
+ 0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x1, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x1, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x1, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x1, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x1, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x0, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x1, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x1, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* vip8000ULFN_6211 */
+ {
+ 0x8000, /* ChipID */
+ 0x6211, /* ChipRevision */
+ 0x5080003, /* ProductID */
+ 0x0, /* EcoID */
+ 0x22, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x0, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x200, /* gcFEATURE_VALUE_ThreadCount */
+ 0x2, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x10, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x8, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x2, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x2, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x8, /* gcFEATURE_VALUE_Streams */
+ 0x10, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x0, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x40, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x1, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x1, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x6, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0xe0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x3, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x1, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x1, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x1, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x1, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x1, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x1, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY */
+ 0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x1, /* gcFEATURE_BIT_DRAWID */
+ 0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x1, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x1, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x1, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x1, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x1, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x0, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x1, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x1, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* vip8000UL_6211 */
+ {
+ 0x8000, /* ChipID */
+ 0x6211, /* ChipRevision */
+ 0x5080003, /* ProductID */
+ 0x0, /* EcoID */
+ 0x0, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x0, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x200, /* gcFEATURE_VALUE_ThreadCount */
+ 0x2, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x10, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x8, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x2, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x2, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x8, /* gcFEATURE_VALUE_Streams */
+ 0x10, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x0, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x40, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x1, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x1, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x1, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x6, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0xe0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x3, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x1, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x1, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x1, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x1, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x1, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x1, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY */
+ 0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x1, /* gcFEATURE_BIT_DRAWID */
+ 0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x1, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x1, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x1, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x1, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x1, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x0, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x1, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x1, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x1, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* vipnano */
+ {
+ 0x8000, /* ChipID */
+ 0x7000, /* ChipRevision */
+ 0x5080001, /* ProductID */
+ 0x0, /* EcoID */
+ 0x29, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x0, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x100, /* gcFEATURE_VALUE_ThreadCount */
+ 0x1, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x10, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x8, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x2, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x2, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x8, /* gcFEATURE_VALUE_Streams */
+ 0x10, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x0, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x40, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x1, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x1, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x1, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x6, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0xe0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x1, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x3, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x1, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x1, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x1, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x1, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x1, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x1, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY */
+ 0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x1, /* gcFEATURE_BIT_DRAWID */
+ 0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x1, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x1, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x1, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x1, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x1, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x1, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x1, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x1, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x1, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x1, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* gcnanovip */
+ {
+ 0x8000, /* ChipID */
+ 0x7000, /* ChipRevision */
+ 0x424f5343, /* ProductID */
+ 0x0, /* EcoID */
+ 0x0, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x0, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x100, /* gcFEATURE_VALUE_ThreadCount */
+ 0x1, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x10, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x8, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x2, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x2, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x8, /* gcFEATURE_VALUE_Streams */
+ 0x10, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x1, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x3, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x1, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x1, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x1, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x1, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x1, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x1, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY */
+ 0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x1, /* gcFEATURE_BIT_DRAWID */
+ 0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x1, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x1, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x1, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x1, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x1, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x1, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x0, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x1, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x1, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* vipnano-q */
+ {
+ 0x8000, /* ChipID */
+ 0x7100, /* ChipRevision */
+ 0x45080001, /* ProductID */
+ 0x0, /* EcoID */
+ 0x24, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x0, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x100, /* gcFEATURE_VALUE_ThreadCount */
+ 0x1, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x10, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x10, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x2, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x2, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x8, /* gcFEATURE_VALUE_Streams */
+ 0x10, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x0, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x40, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x8, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x8, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x8, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x8, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x10, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x200, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x4, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x800, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x180, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x1, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x1, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x1, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x1, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x1, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x1, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY */
+ 0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x1, /* gcFEATURE_BIT_DRAWID */
+ 0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x1, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x1, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x1, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x1, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x1, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x1, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x1, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x1, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER */
+ 0x1, /* gcFEATURE_BIT_TP_LRN */
+ 0x1, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x1, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x1, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x1, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x1, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x1, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x1, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x1, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x1, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* vipnano-q */
+ {
+ 0x8000, /* ChipID */
+ 0x7100, /* ChipRevision */
+ 0x45080001, /* ProductID */
+ 0x0, /* EcoID */
+ 0x82, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x0, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x100, /* gcFEATURE_VALUE_ThreadCount */
+ 0x1, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x10, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x10, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x2, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x2, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x8, /* gcFEATURE_VALUE_Streams */
+ 0x10, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x0, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x40, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0xa, /* gcFEATURE_VALUE_NNCoreCount */
+ 0xa, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x2, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x2, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0xc, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x200, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x6, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x800, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x180, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x1, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x1, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x1, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x1, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x1, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x1, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY */
+ 0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x1, /* gcFEATURE_BIT_DRAWID */
+ 0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x1, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x1, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x1, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x1, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x1, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x1, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x1, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x1, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER */
+ 0x1, /* gcFEATURE_BIT_TP_LRN */
+ 0x1, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x1, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x1, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x1, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x1, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x1, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x1, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x1, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x1, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x1, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x1, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* vipnano-d */
+ {
+ 0x8000, /* ChipID */
+ 0x7110, /* ChipRevision */
+ 0x25080001, /* ProductID */
+ 0x0, /* EcoID */
+ 0x89, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x0, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x100, /* gcFEATURE_VALUE_ThreadCount */
+ 0x1, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x10, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x10, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x2, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x2, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x8, /* gcFEATURE_VALUE_Streams */
+ 0x10, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x0, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x40, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x6, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x6, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x6, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x6, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0xc, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x100, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x6, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x100, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x200, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x3, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x3, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x1, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x1, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x1, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x1, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x1, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x1, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY */
+ 0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x1, /* gcFEATURE_BIT_DRAWID */
+ 0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x1, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x1, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x1, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x1, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x1, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x1, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x1, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x1, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER */
+ 0x1, /* gcFEATURE_BIT_TP_LRN */
+ 0x1, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x1, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x1, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x1, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x1, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x1, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x1, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x1, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x1, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x1, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x1, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x1, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* vip8000UL-s */
+ {
+ 0x8000, /* ChipID */
+ 0x7000, /* ChipRevision */
+ 0x15080003, /* ProductID */
+ 0x0, /* EcoID */
+ 0x25, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x0, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x200, /* gcFEATURE_VALUE_ThreadCount */
+ 0x2, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x18, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x10, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x18, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x2, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x2, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x8, /* gcFEATURE_VALUE_Streams */
+ 0x10, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x0, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x40, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x2, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x2, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x2, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x6, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0xe0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x80, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x1, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x3, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x1, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x1, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x1, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x1, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x1, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x1, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY */
+ 0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x1, /* gcFEATURE_BIT_DRAWID */
+ 0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x1, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x1, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x1, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x1, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x1, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x1, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x1, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x1, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x1, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x1, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* vip8000UL-s */
+ {
+ 0x8000, /* ChipID */
+ 0x7005, /* ChipRevision */
+ 0x15080003, /* ProductID */
+ 0x0, /* EcoID */
+ 0x83, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x0, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x200, /* gcFEATURE_VALUE_ThreadCount */
+ 0x2, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x2, /* gcFEATURE_VALUE_CoreCount */
+ 0x18, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x10, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x18, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x2, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x2, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x8, /* gcFEATURE_VALUE_Streams */
+ 0x10, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x0, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x40, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x2, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x2, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x2, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x6, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0xe0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x80, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x1, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x3, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x1, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x1, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x1, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x1, /* gcFEATURE_BIT_VMSAA */
+ 0x1, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x1, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x1, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY */
+ 0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x1, /* gcFEATURE_BIT_DRAWID */
+ 0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x1, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x1, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x1, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x1, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x1, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x1, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x1, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x1, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x1, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x1, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x1, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x1, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* vip8000UL-q */
+ {
+ 0x8000, /* ChipID */
+ 0x7000, /* ChipRevision */
+ 0x45080003, /* ProductID */
+ 0x0, /* EcoID */
+ 0x26, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x0, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x200, /* gcFEATURE_VALUE_ThreadCount */
+ 0x2, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x18, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x10, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x18, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x2, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x2, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x8, /* gcFEATURE_VALUE_Streams */
+ 0x10, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x0, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x40, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x8, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x8, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x8, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x6, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x200, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x2, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x3, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x1, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x1, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x1, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x1, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x1, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x1, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY */
+ 0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x1, /* gcFEATURE_BIT_DRAWID */
+ 0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x1, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x1, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x1, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x1, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x1, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x1, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x1, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x1, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x1, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* vip8000UL */
+ {
+ 0x8000, /* ChipID */
+ 0x7000, /* ChipRevision */
+ 0x5080003, /* ProductID */
+ 0x0, /* EcoID */
+ 0x0, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x0, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x200, /* gcFEATURE_VALUE_ThreadCount */
+ 0x2, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x18, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x10, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x18, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x2, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x2, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x8, /* gcFEATURE_VALUE_Streams */
+ 0x10, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x0, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x40, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x1, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x1, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x1, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x6, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0xe0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x80, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x1, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x3, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x1, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x1, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x1, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x1, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x1, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x1, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY */
+ 0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x1, /* gcFEATURE_BIT_DRAWID */
+ 0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x1, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x1, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x1, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x1, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x1, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x1, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x1, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x1, /* gcFEATURE_BIT_VIP_V7 */
+ 0x1, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x1, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x1, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* vip8000-q */
+ {
+ 0x8000, /* ChipID */
+ 0x7000, /* ChipRevision */
+ 0x45080000, /* ProductID */
+ 0x0, /* EcoID */
+ 0x72, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x0, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x800, /* gcFEATURE_VALUE_ThreadCount */
+ 0x8, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x40, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x20, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x40, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x2, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x2, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x8, /* gcFEATURE_VALUE_Streams */
+ 0x10, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x0, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x40, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x8, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x8, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x8, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x6, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x200, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x2, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x3, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x1, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x1, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x1, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x1, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x1, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x1, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY */
+ 0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x1, /* gcFEATURE_BIT_DRAWID */
+ 0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x1, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x1, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x1, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x1, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x1, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x1, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x1, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x1, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x1, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x1, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* vipnano-d */
+ {
+ 0x8000, /* ChipID */
+ 0x7003, /* ChipRevision */
+ 0x25080001, /* ProductID */
+ 0x0, /* EcoID */
+ 0x2a, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x0, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x100, /* gcFEATURE_VALUE_ThreadCount */
+ 0x1, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x10, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x10, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x2, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x2, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x8, /* gcFEATURE_VALUE_Streams */
+ 0x10, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x0, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x40, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x4, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x4, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x4, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x6, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x100, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x4, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x3, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x1, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x1, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x1, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x1, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x1, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x1, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY */
+ 0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x1, /* gcFEATURE_BIT_DRAWID */
+ 0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x1, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x1, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x1, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x1, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x1, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x1, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x1, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x1, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x1, /* gcFEATURE_BIT_TP_LRN */
+ 0x1, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x1, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x1, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x1, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* vipnano-d */
+ {
+ 0x8000, /* ChipID */
+ 0x7000, /* ChipRevision */
+ 0x25080001, /* ProductID */
+ 0x0, /* EcoID */
+ 0x76, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x0, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x100, /* gcFEATURE_VALUE_ThreadCount */
+ 0x1, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x10, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x10, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x2, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x2, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x8, /* gcFEATURE_VALUE_Streams */
+ 0x10, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x0, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x40, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x4, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x4, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x4, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x4, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x6, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x100, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x2, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x3, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x1, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x1, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x1, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x1, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x1, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x1, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY */
+ 0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x1, /* gcFEATURE_BIT_DRAWID */
+ 0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x1, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x1, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x1, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x1, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x1, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x1, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x1, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x1, /* gcFEATURE_BIT_VIP_V7 */
+ 0x1, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER */
+ 0x1, /* gcFEATURE_BIT_TP_LRN */
+ 0x1, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x1, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x1, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x1, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x1, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* vip8000L-O */
+ {
+ 0x8000, /* ChipID */
+ 0x7000, /* ChipRevision */
+ 0x85080002, /* ProductID */
+ 0x0, /* EcoID */
+ 0x2f, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x0, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x400, /* gcFEATURE_VALUE_ThreadCount */
+ 0x4, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x20, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x20, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x20, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x2, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x2, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x4, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x8, /* gcFEATURE_VALUE_Streams */
+ 0x10, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x0, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x40, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x10, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x10, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x10, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x10, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0xc, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x200, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x4, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x1, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x1, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x1, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x1, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x1, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x1, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY */
+ 0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x1, /* gcFEATURE_BIT_DRAWID */
+ 0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x1, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x1, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x1, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x1, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x1, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x1, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x1, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x1, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x1, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x1, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x1, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x1, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x1, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x1, /* gcFEATURE_BIT_VIP_V7 */
+ 0x1, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER */
+ 0x1, /* gcFEATURE_BIT_TP_LRN */
+ 0x1, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x1, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x1, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x1, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x1, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x1, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x1, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x1, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x1, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x1, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x1, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* vip8000L-qi */
+ {
+ 0x8000, /* ChipID */
+ 0x7200, /* ChipRevision */
+ 0x4508000a, /* ProductID */
+ 0x0, /* EcoID */
+ 0x85, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x0, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x400, /* gcFEATURE_VALUE_ThreadCount */
+ 0x4, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x20, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x20, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x20, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x2, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x2, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x4, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x8, /* gcFEATURE_VALUE_Streams */
+ 0x10, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x0, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x40, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0xc, /* gcFEATURE_VALUE_NNCoreCount */
+ 0xc, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0xc, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0xc, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x400, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x4, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x200, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x1, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x1, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x1, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x1, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x1, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x1, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY */
+ 0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x1, /* gcFEATURE_BIT_DRAWID */
+ 0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x1, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x1, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x1, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x1, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x1, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x1, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x1, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x1, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x1, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x1, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x1, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x1, /* gcFEATURE_BIT_VIP_V7 */
+ 0x1, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER */
+ 0x1, /* gcFEATURE_BIT_TP_LRN */
+ 0x1, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x1, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x1, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x1, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x1, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x1, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x1, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x1, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x1, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x1, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x1, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x1, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x1, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x1, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x1, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x1, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x1, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* vip8000L-di */
+ {
+ 0x8000, /* ChipID */
+ 0x7200, /* ChipRevision */
+ 0x508000a, /* ProductID */
+ 0x4000000, /* EcoID */
+ 0x91, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x0, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x400, /* gcFEATURE_VALUE_ThreadCount */
+ 0x4, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x20, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x20, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x20, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x2, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x2, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x4, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x8, /* gcFEATURE_VALUE_Streams */
+ 0x10, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x0, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x40, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x4, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x4, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x4, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0xc, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x100, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x4, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x200, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x1, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x1, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x1, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x1, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x1, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x1, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY */
+ 0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x1, /* gcFEATURE_BIT_DRAWID */
+ 0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x1, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x1, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x1, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x1, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x1, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x1, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x1, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x1, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x1, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x1, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x1, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x1, /* gcFEATURE_BIT_VIP_V7 */
+ 0x1, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER */
+ 0x1, /* gcFEATURE_BIT_TP_LRN */
+ 0x1, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x1, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x1, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x1, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x1, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x1, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x1, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x1, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x1, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x1, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x1, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x1, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x1, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x1, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x1, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x1, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x1, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* vipnano-s */
+ {
+ 0x8000, /* ChipID */
+ 0x7003, /* ChipRevision */
+ 0x15080001, /* ProductID */
+ 0x0, /* EcoID */
+ 0x23, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x0, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x100, /* gcFEATURE_VALUE_ThreadCount */
+ 0x1, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x10, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x10, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x2, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x2, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x8, /* gcFEATURE_VALUE_Streams */
+ 0x10, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x0, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x40, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x2, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x2, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x2, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x6, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0xe0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x80, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x1, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x3, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x1, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x1, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x1, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x1, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x1, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x1, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY */
+ 0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x1, /* gcFEATURE_BIT_DRAWID */
+ 0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x1, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x1, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x1, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x1, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x1, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x1, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x1, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x1, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x1, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x1, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* vipnano-si */
+ {
+ 0x8000, /* ChipID */
+ 0x7005, /* ChipRevision */
+ 0x5080009, /* ProductID */
+ 0x2000000, /* EcoID */
+ 0x96, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x0, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x100, /* gcFEATURE_VALUE_ThreadCount */
+ 0x1, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x10, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x10, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x2, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x2, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x8, /* gcFEATURE_VALUE_Streams */
+ 0x10, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x0, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x40, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x2, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x2, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x6, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x80, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x1, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x3, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x1, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x1, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x1, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x1, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x1, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x1, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY */
+ 0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x1, /* gcFEATURE_BIT_DRAWID */
+ 0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x1, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x1, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x1, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x1, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x1, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x1, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x1, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x0, /* gcFEATURE_BIT_TP_LRN */
+ 0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x1, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x1, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* vipnano-qi */
+ {
+ 0x8000, /* ChipID */
+ 0x7004, /* ChipRevision */
+ 0x45080009, /* ProductID */
+ 0x0, /* EcoID */
+ 0x7d, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x0, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x100, /* gcFEATURE_VALUE_ThreadCount */
+ 0x1, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x10, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x10, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x2, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x2, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x8, /* gcFEATURE_VALUE_Streams */
+ 0x10, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x0, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x40, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x8, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x8, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x8, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0xc, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x200, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x4, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x400, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x3, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x180, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x1, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x1, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x1, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x1, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x1, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x1, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY */
+ 0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x1, /* gcFEATURE_BIT_DRAWID */
+ 0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x1, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x1, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x1, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x1, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x1, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x1, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x1, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x1, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER */
+ 0x1, /* gcFEATURE_BIT_TP_LRN */
+ 0x1, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x1, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x1, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x1, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x1, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x1, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x1, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x1, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x1, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* vipnano-qi */
+ {
+ 0x8000, /* ChipID */
+ 0x7004, /* ChipRevision */
+ 0x45080009, /* ProductID */
+ 0x1, /* EcoID */
+ 0x7d, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x0, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x100, /* gcFEATURE_VALUE_ThreadCount */
+ 0x1, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x10, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x10, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x2, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x2, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x8, /* gcFEATURE_VALUE_Streams */
+ 0x10, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x0, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x40, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x8, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x8, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x8, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0xc, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x200, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x4, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x400, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x3, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x180, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x1, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x1, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x1, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x1, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x1, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x1, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY */
+ 0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x1, /* gcFEATURE_BIT_DRAWID */
+ 0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x1, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x1, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x1, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x1, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x1, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x1, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x1, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x1, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER */
+ 0x1, /* gcFEATURE_BIT_TP_LRN */
+ 0x1, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x1, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x1, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x1, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x1, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x1, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x1, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x1, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x1, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* vipnano-di */
+ {
+ 0x8000, /* ChipID */
+ 0x7000, /* ChipRevision */
+ 0x25080009, /* ProductID */
+ 0x0, /* EcoID */
+ 0x7e, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x0, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x100, /* gcFEATURE_VALUE_ThreadCount */
+ 0x1, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x10, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x10, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x2, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x2, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x8, /* gcFEATURE_VALUE_Streams */
+ 0x10, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x0, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x40, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x4, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x4, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x4, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x6, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x100, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x4, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x800, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x3, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x200, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x1, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x1, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x1, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x1, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x1, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x1, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY */
+ 0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x1, /* gcFEATURE_BIT_DRAWID */
+ 0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x1, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x1, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x1, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x1, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x1, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x1, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x1, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x1, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER */
+ 0x1, /* gcFEATURE_BIT_TP_LRN */
+ 0x1, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x1, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x1, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x1, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x1, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x1, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x1, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x1, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x1, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* vipnano-si */
+ {
+ 0x8000, /* ChipID */
+ 0x7120, /* ChipRevision */
+ 0x15080009, /* ProductID */
+ 0x0, /* EcoID */
+ 0x80, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x0, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x100, /* gcFEATURE_VALUE_ThreadCount */
+ 0x1, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x10, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x10, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x2, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x2, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x8, /* gcFEATURE_VALUE_Streams */
+ 0x10, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x0, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x40, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x2, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x2, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x2, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0xc, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0xe0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x100, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x2, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x180, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x1, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x1, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x1, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x1, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x1, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x1, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY */
+ 0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x1, /* gcFEATURE_BIT_DRAWID */
+ 0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x1, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x1, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x1, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x1, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x1, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x1, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x1, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x1, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER */
+ 0x1, /* gcFEATURE_BIT_TP_LRN */
+ 0x1, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x1, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x1, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x1, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x1, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x1, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x1, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x1, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x1, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x1, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x1, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* vip8000UL-si */
+ {
+ 0x8000, /* ChipID */
+ 0x7121, /* ChipRevision */
+ 0x508000b, /* ProductID */
+ 0x2000000, /* EcoID */
+ 0x98, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x0, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x200, /* gcFEATURE_VALUE_ThreadCount */
+ 0x2, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x10, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x10, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x2, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x2, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x8, /* gcFEATURE_VALUE_Streams */
+ 0x10, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x0, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x40, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x2, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x2, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x2, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0xc, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0xe0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x100, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x2, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x100, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x180, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x1, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x1, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x1, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x1, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x1, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x1, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY */
+ 0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x1, /* gcFEATURE_BIT_DRAWID */
+ 0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x1, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x1, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x1, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x1, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x1, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x1, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x1, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x1, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER */
+ 0x1, /* gcFEATURE_BIT_TP_LRN */
+ 0x1, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x1, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x1, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x1, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x1, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x1, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x1, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x1, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x1, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x1, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x1, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* vipnano-si */
+ {
+ 0x8000, /* ChipID */
+ 0x7120, /* ChipRevision */
+ 0x5080009, /* ProductID */
+ 0x2000000, /* EcoID */
+ 0x97, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x0, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x100, /* gcFEATURE_VALUE_ThreadCount */
+ 0x1, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x10, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x10, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x2, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x2, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x8, /* gcFEATURE_VALUE_Streams */
+ 0x10, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x0, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x40, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x2, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x2, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x2, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0xc, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x100, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x2, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x180, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x1, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x1, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x1, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x1, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x1, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x1, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY */
+ 0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x1, /* gcFEATURE_BIT_DRAWID */
+ 0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x1, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x1, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x1, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x1, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x1, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x1, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x1, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x1, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER */
+ 0x1, /* gcFEATURE_BIT_TP_LRN */
+ 0x1, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x1, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x1, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x1, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x1, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x1, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x1, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x1, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x1, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x1, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x1, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* vippico_v1 */
+ {
+ 0x8000, /* ChipID */
+ 0x7120, /* ChipRevision */
+ 0x8000001, /* ProductID */
+ 0x1000000, /* EcoID */
+ 0x87, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x0, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x100, /* gcFEATURE_VALUE_ThreadCount */
+ 0x1, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x10, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x10, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x2, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x2, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x8, /* gcFEATURE_VALUE_Streams */
+ 0x10, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x0, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x40, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x1, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x1, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x6, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x20, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x2, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x180, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x1, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x1, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x1, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x1, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x1, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x1, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY */
+ 0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x1, /* gcFEATURE_BIT_DRAWID */
+ 0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x1, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x1, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x1, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x1, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x1, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x1, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x0, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x1, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER */
+ 0x1, /* gcFEATURE_BIT_TP_LRN */
+ 0x1, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x1, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x1, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x1, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x1, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x1, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x1, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x1, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x1, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x1, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* vippico_v2 */
+ {
+ 0x8000, /* ChipID */
+ 0x7130, /* ChipRevision */
+ 0x8000001, /* ProductID */
+ 0x1000000, /* EcoID */
+ 0x93, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x0, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x100, /* gcFEATURE_VALUE_ThreadCount */
+ 0x1, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x10, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x10, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x2, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x2, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x8, /* gcFEATURE_VALUE_Streams */
+ 0x10, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x0, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x40, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x1, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x1, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x6, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x200, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x1, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x180, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x7, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x1, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x1, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x1, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x1, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x1, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x1, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY */
+ 0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x1, /* gcFEATURE_BIT_DRAWID */
+ 0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x1, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x1, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x1, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x1, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x1, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x1, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x1, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x1, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER */
+ 0x1, /* gcFEATURE_BIT_TP_LRN */
+ 0x1, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x1, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x1, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x1, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x1, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x1, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x1, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x1, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x1, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x1, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x1, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x1, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x1, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x1, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x1, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* vippico_v3 */
+ {
+ 0x8000, /* ChipID */
+ 0x7130, /* ChipRevision */
+ 0x8000001, /* ProductID */
+ 0x2000000, /* EcoID */
+ 0x99, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x0, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x100, /* gcFEATURE_VALUE_ThreadCount */
+ 0x1, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x10, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x10, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x2, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x2, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x8, /* gcFEATURE_VALUE_Streams */
+ 0x10, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x0, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x40, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x2, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x2, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x6, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x200, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x1, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x180, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x7, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x1, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x1, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x1, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x1, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x1, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x1, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY */
+ 0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x1, /* gcFEATURE_BIT_DRAWID */
+ 0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x1, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x1, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x1, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x1, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x1, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x1, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x1, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x1, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER */
+ 0x1, /* gcFEATURE_BIT_TP_LRN */
+ 0x1, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x1, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x1, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x1, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x1, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x1, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x1, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x1, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x1, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x1, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x1, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x1, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x1, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x1, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x1, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* vipnano-si */
+ {
+ 0x8000, /* ChipID */
+ 0x7130, /* ChipRevision */
+ 0x5000009, /* ProductID */
+ 0x2000000, /* EcoID */
+ 0x9e, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x0, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x100, /* gcFEATURE_VALUE_ThreadCount */
+ 0x1, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x10, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x10, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x1, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x2, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x8, /* gcFEATURE_VALUE_Streams */
+ 0x10, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x0, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x40, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x2, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x2, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x2, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x6, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x180, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x1, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x180, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x1, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x1, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x1, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x1, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x1, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x1, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY */
+ 0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x1, /* gcFEATURE_BIT_DRAWID */
+ 0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x1, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x1, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x1, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x1, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x1, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x1, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x1, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x1, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER */
+ 0x1, /* gcFEATURE_BIT_TP_LRN */
+ 0x1, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x1, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x1, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x1, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x1, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x1, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x1, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x1, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x1, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x1, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x1, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x1, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x1, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x1, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x1, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x1, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* vip8000-oi MP */
+ {
+ 0x8000, /* ChipID */
+ 0x7300, /* ChipRevision */
+ 0x5080008, /* ProductID */
+ 0x10000000, /* EcoID */
+ 0x86, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x0, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x100, /* gcFEATURE_VALUE_ThreadCount */
+ 0x1, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x8, /* gcFEATURE_VALUE_CoreCount */
+ 0x9, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x9, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x9, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x2, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x2, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x8, /* gcFEATURE_VALUE_Streams */
+ 0x10, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x0, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x40, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x2, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x2, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x2, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0xc, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x80, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x1, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x800, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x180, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x1, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x1, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x1, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x1, /* gcFEATURE_BIT_VMSAA */
+ 0x1, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x1, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x1, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY */
+ 0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x1, /* gcFEATURE_BIT_DRAWID */
+ 0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x1, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x1, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x1, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x1, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x1, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x1, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x1, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x1, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x1, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x1, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER */
+ 0x1, /* gcFEATURE_BIT_TP_LRN */
+ 0x1, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x1, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x1, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x1, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x1, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x1, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x1, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x1, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x1, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x1, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x1, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* vip8000L-qi MP */
+ {
+ 0x8000, /* ChipID */
+ 0x7300, /* ChipRevision */
+ 0x508000a, /* ProductID */
+ 0x8000000, /* EcoID */
+ 0x9b, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x0, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x100, /* gcFEATURE_VALUE_ThreadCount */
+ 0x1, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x4, /* gcFEATURE_VALUE_CoreCount */
+ 0x9, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x9, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x9, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x2, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x2, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x8, /* gcFEATURE_VALUE_Streams */
+ 0x10, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x0, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x40, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x2, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x2, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x2, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0xc, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x80, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x1, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x800, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x180, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x1, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x1, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x1, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x1, /* gcFEATURE_BIT_VMSAA */
+ 0x1, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x1, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x1, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY */
+ 0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x1, /* gcFEATURE_BIT_DRAWID */
+ 0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x1, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x1, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x1, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x1, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x1, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x1, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x1, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x1, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x1, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x1, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER */
+ 0x1, /* gcFEATURE_BIT_TP_LRN */
+ 0x1, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x1, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x1, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x1, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x1, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x1, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x1, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x1, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x1, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x1, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x1, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* vip8000UL-di MP */
+ {
+ 0x8000, /* ChipID */
+ 0x7300, /* ChipRevision */
+ 0x508000b, /* ProductID */
+ 0x4000000, /* EcoID */
+ 0x9c, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x0, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x100, /* gcFEATURE_VALUE_ThreadCount */
+ 0x1, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x2, /* gcFEATURE_VALUE_CoreCount */
+ 0x9, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x9, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x9, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x2, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x2, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x8, /* gcFEATURE_VALUE_Streams */
+ 0x10, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x0, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x40, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x2, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x2, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x2, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0xc, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x80, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x1, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x800, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x180, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x1, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x1, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x1, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x1, /* gcFEATURE_BIT_VMSAA */
+ 0x1, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x1, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x1, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY */
+ 0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x1, /* gcFEATURE_BIT_DRAWID */
+ 0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x1, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x1, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x1, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x1, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x1, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x1, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x1, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x1, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x1, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x1, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER */
+ 0x1, /* gcFEATURE_BIT_TP_LRN */
+ 0x1, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x1, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x1, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x1, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x1, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x1, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x1, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x1, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x1, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x1, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x1, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* vipnano-si */
+ {
+ 0x8000, /* ChipID */
+ 0x7300, /* ChipRevision */
+ 0x5080008, /* ProductID */
+ 0x2000000, /* EcoID */
+ 0x90, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x0, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x100, /* gcFEATURE_VALUE_ThreadCount */
+ 0x1, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x10, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x10, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x2, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x2, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x8, /* gcFEATURE_VALUE_Streams */
+ 0x10, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x0, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x40, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x2, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x2, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x2, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0xc, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x80, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x1, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x800, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x180, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x1, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x1, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x1, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x1, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x1, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x1, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY */
+ 0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x1, /* gcFEATURE_BIT_DRAWID */
+ 0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x1, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x1, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x1, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x1, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x1, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x1, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x1, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x1, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x1, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER */
+ 0x1, /* gcFEATURE_BIT_TP_LRN */
+ 0x1, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x1, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x1, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x1, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x1, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x1, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x1, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x1, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x1, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x1, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x1, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* vipnano-qi */
+ {
+ 0x8000, /* ChipID */
+ 0x7120, /* ChipRevision */
+ 0x45080009, /* ProductID */
+ 0x0, /* EcoID */
+ 0x88, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x0, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x100, /* gcFEATURE_VALUE_ThreadCount */
+ 0x1, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x10, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x10, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x2, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x2, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x8, /* gcFEATURE_VALUE_Streams */
+ 0x10, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x0, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x40, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x8, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x8, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x8, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0xc, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x200, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x4, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x400, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x180, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x1, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x1, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x1, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x1, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x1, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x1, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY */
+ 0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x1, /* gcFEATURE_BIT_DRAWID */
+ 0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x1, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x1, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x1, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x1, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x1, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x1, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x1, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x1, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER */
+ 0x1, /* gcFEATURE_BIT_TP_LRN */
+ 0x1, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x1, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x1, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x1, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x1, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x1, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x1, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x1, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x1, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x1, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x1, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* vipnano-di */
+ {
+ 0x8000, /* ChipID */
+ 0x7110, /* ChipRevision */
+ 0x25080009, /* ProductID */
+ 0x0, /* EcoID */
+ 0x7f, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x0, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x100, /* gcFEATURE_VALUE_ThreadCount */
+ 0x1, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x10, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x10, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x2, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x2, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x8, /* gcFEATURE_VALUE_Streams */
+ 0x10, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x0, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x40, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x6, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x6, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x6, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0xc, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x100, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x6, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x200, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x200, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x1, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x1, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x1, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x1, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x1, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x1, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY */
+ 0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x1, /* gcFEATURE_BIT_DRAWID */
+ 0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x1, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x1, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x1, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x1, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x1, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x1, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x1, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x1, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER */
+ 0x1, /* gcFEATURE_BIT_TP_LRN */
+ 0x1, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x1, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x1, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x1, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x1, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x1, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x1, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x1, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x1, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x1, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* vip8000UL-di */
+ {
+ 0x8000, /* ChipID */
+ 0x7120, /* ChipRevision */
+ 0x508000b, /* ProductID */
+ 0x6000000, /* EcoID */
+ 0x92, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x0, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x200, /* gcFEATURE_VALUE_ThreadCount */
+ 0x2, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x10, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x10, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x2, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x2, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x8, /* gcFEATURE_VALUE_Streams */
+ 0x10, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x0, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x40, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x6, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x6, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x6, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0xc, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x100, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x6, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x200, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x200, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x1, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x1, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x1, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x1, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x1, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x1, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY */
+ 0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x1, /* gcFEATURE_BIT_DRAWID */
+ 0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x1, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x1, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x1, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x1, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x1, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x1, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x1, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x1, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER */
+ 0x1, /* gcFEATURE_BIT_TP_LRN */
+ 0x1, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x1, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x1, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x1, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x1, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x1, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x1, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x1, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x1, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x1, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x1, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x1, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* vipnano-di */
+ {
+ 0x8000, /* ChipID */
+ 0x7131, /* ChipRevision */
+ 0x25080009, /* ProductID */
+ 0x0, /* EcoID */
+ 0x84, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x0, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x100, /* gcFEATURE_VALUE_ThreadCount */
+ 0x1, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x10, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x10, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x2, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x2, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x8, /* gcFEATURE_VALUE_Streams */
+ 0x10, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x0, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x40, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x4, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x4, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x4, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0xc, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x80, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x4, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x200, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x1, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x1, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x1, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x1, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x1, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x1, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY */
+ 0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x1, /* gcFEATURE_BIT_DRAWID */
+ 0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x1, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x1, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x1, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x1, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x1, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x1, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x1, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x1, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER */
+ 0x1, /* gcFEATURE_BIT_TP_LRN */
+ 0x1, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x1, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x1, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x1, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x1, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x1, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x1, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x1, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x1, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x1, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x1, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x1, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x1, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x1, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* vipnano-si */
+ {
+ 0x8000, /* ChipID */
+ 0x7130, /* ChipRevision */
+ 0x5080009, /* ProductID */
+ 0x2000000, /* EcoID */
+ 0x9a, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x0, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x100, /* gcFEATURE_VALUE_ThreadCount */
+ 0x1, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x10, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x10, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x2, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x2, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x8, /* gcFEATURE_VALUE_Streams */
+ 0x10, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x0, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x40, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x2, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x2, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x2, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0xc, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x80, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x2, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x200, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x1, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x1, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x1, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x1, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x1, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x1, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY */
+ 0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x1, /* gcFEATURE_BIT_DRAWID */
+ 0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x1, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x1, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x1, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x1, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x1, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x1, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x1, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x1, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER */
+ 0x1, /* gcFEATURE_BIT_TP_LRN */
+ 0x1, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x1, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x1, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x1, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x1, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x1, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x1, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x1, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x1, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x1, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x1, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x1, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x1, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* vipnano-si+ */
+ {
+ 0x8000, /* ChipID */
+ 0x8000, /* ChipRevision */
+ 0x5000009, /* ProductID */
+ 0x3000000, /* EcoID */
+ 0x9f, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x0, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x100, /* gcFEATURE_VALUE_ThreadCount */
+ 0x1, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x10, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x10, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x1, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x2, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x8, /* gcFEATURE_VALUE_Streams */
+ 0x10, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x0, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x40, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x6, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x6, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x6, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x9, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x20, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x100, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x4, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x200, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x40, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x20, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x1, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x1, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x1, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x1, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x1, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x1, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY */
+ 0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x1, /* gcFEATURE_BIT_DRAWID */
+ 0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x1, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x1, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x1, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x1, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x1, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x1, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x1, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x1, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER */
+ 0x1, /* gcFEATURE_BIT_TP_LRN */
+ 0x1, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x1, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x1, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x1, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x1, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x1, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x1, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x1, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x1, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x1, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x1, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x1, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x1, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x1, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x1, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* vipnano-s */
+ {
+ 0x8000, /* ChipID */
+ 0x7010, /* ChipRevision */
+ 0x15080001, /* ProductID */
+ 0x0, /* EcoID */
+ 0x0, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x1, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x100, /* gcFEATURE_VALUE_ThreadCount */
+ 0x1, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x10, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x10, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x2, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x2, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x8, /* gcFEATURE_VALUE_Streams */
+ 0x10, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x0, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x40, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x2, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x2, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x2, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x2, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x6, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0xe0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x80, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x1, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x400, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x3, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x200, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x1, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x1, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x1, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x1, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x1, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x1, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY */
+ 0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x1, /* gcFEATURE_BIT_DRAWID */
+ 0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x1, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x1, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x1, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x1, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x1, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x1, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x1, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x1, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER */
+ 0x1, /* gcFEATURE_BIT_TP_LRN */
+ 0x1, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x1, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x1, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x1, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x1, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x1, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x1, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x1, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x1, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* vipnano-d */
+ {
+ 0x8000, /* ChipID */
+ 0x7010, /* ChipRevision */
+ 0x25080001, /* ProductID */
+ 0x0, /* EcoID */
+ 0x0, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x1, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x100, /* gcFEATURE_VALUE_ThreadCount */
+ 0x1, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x10, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x10, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x2, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x2, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x8, /* gcFEATURE_VALUE_Streams */
+ 0x10, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x0, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x40, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x4, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x4, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x4, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x4, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x6, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x100, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x2, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x400, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x3, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x200, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x1, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x1, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x1, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x1, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x1, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x1, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY */
+ 0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x1, /* gcFEATURE_BIT_DRAWID */
+ 0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x1, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x1, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x1, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x1, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x1, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x1, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x1, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x1, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER */
+ 0x1, /* gcFEATURE_BIT_TP_LRN */
+ 0x1, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x1, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x1, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x1, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x1, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x1, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x1, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x1, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x1, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* vipnano-q */
+ {
+ 0x8000, /* ChipID */
+ 0x7010, /* ChipRevision */
+ 0x45080001, /* ProductID */
+ 0x0, /* EcoID */
+ 0x0, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x1, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x100, /* gcFEATURE_VALUE_ThreadCount */
+ 0x1, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x10, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x10, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x2, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x2, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x8, /* gcFEATURE_VALUE_Streams */
+ 0x10, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x0, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x40, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x8, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x8, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x8, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x8, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x6, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x200, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x4, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x400, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x3, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x200, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x1, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x1, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x1, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x1, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x1, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x1, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY */
+ 0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x1, /* gcFEATURE_BIT_DRAWID */
+ 0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x1, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x1, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x1, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x1, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x1, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x1, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x1, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x1, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER */
+ 0x1, /* gcFEATURE_BIT_TP_LRN */
+ 0x1, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x1, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x1, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x1, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x1, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x1, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x1, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x1, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x1, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* vipnano-o */
+ {
+ 0x8000, /* ChipID */
+ 0x7010, /* ChipRevision */
+ 0x85080001, /* ProductID */
+ 0x0, /* EcoID */
+ 0x0, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x1, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x100, /* gcFEATURE_VALUE_ThreadCount */
+ 0x1, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x10, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x10, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x2, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x2, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x8, /* gcFEATURE_VALUE_Streams */
+ 0x10, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x0, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x40, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x10, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x10, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x10, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x10, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0x6, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x400, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x8, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x400, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x3, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x200, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x1, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x1, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x1, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x1, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x1, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x1, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY */
+ 0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x1, /* gcFEATURE_BIT_DRAWID */
+ 0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x1, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x1, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x1, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x1, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x1, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x1, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x1, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x1, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER */
+ 0x1, /* gcFEATURE_BIT_TP_LRN */
+ 0x1, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x1, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x1, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x1, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x1, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x1, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x1, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x1, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x1, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* vipnano-s */
+ {
+ 0x8000, /* ChipID */
+ 0x7100, /* ChipRevision */
+ 0x15080001, /* ProductID */
+ 0x0, /* EcoID */
+ 0x0, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x1, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x100, /* gcFEATURE_VALUE_ThreadCount */
+ 0x1, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x10, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x10, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x2, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x2, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x8, /* gcFEATURE_VALUE_Streams */
+ 0x10, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x0, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x40, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x2, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x2, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x2, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x2, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0xc, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x80, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x1, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x100, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x200, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x1, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x1, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x1, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x1, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x1, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x1, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY */
+ 0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x1, /* gcFEATURE_BIT_DRAWID */
+ 0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x1, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x1, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x1, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x1, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x1, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x1, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x1, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x1, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER */
+ 0x1, /* gcFEATURE_BIT_TP_LRN */
+ 0x1, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x1, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x1, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x1, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x1, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x1, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x1, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x1, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x1, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* vipnano-s+ */
+ {
+ 0x8000, /* ChipID */
+ 0x7100, /* ChipRevision */
+ 0x5080001, /* ProductID */
+ 0x3000000, /* EcoID */
+ 0x0, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x1, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x100, /* gcFEATURE_VALUE_ThreadCount */
+ 0x1, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x10, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x10, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x2, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x2, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x8, /* gcFEATURE_VALUE_Streams */
+ 0x10, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x0, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x40, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x3, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x3, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x3, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x3, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0xc, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x80, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x1, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x100, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x200, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x1, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x1, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x1, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x1, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x1, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x1, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY */
+ 0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x1, /* gcFEATURE_BIT_DRAWID */
+ 0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x1, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x1, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x1, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x1, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x1, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x1, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x1, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x1, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER */
+ 0x1, /* gcFEATURE_BIT_TP_LRN */
+ 0x1, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x1, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x1, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x1, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x1, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x1, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x1, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x1, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x1, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* vipnano-d */
+ {
+ 0x8000, /* ChipID */
+ 0x7100, /* ChipRevision */
+ 0x25080001, /* ProductID */
+ 0x0, /* EcoID */
+ 0x0, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x1, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x100, /* gcFEATURE_VALUE_ThreadCount */
+ 0x1, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x10, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x10, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x2, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x2, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x8, /* gcFEATURE_VALUE_Streams */
+ 0x10, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x0, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x40, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x4, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x4, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x4, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x4, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0xc, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x100, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x2, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x200, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x200, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x1, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x1, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x1, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x1, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x1, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x1, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY */
+ 0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x1, /* gcFEATURE_BIT_DRAWID */
+ 0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x1, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x1, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x1, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x1, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x1, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x1, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x1, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x1, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER */
+ 0x1, /* gcFEATURE_BIT_TP_LRN */
+ 0x1, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x1, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x1, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x1, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x1, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x1, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x1, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x1, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x1, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* vipnano-d+ */
+ {
+ 0x8000, /* ChipID */
+ 0x7100, /* ChipRevision */
+ 0x5080001, /* ProductID */
+ 0x6000000, /* EcoID */
+ 0x0, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x1, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x100, /* gcFEATURE_VALUE_ThreadCount */
+ 0x1, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x10, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x10, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x2, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x2, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x8, /* gcFEATURE_VALUE_Streams */
+ 0x10, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x0, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x40, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x6, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x6, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x6, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x6, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0xc, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x100, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x3, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x200, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x200, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x1, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x1, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x1, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x1, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x1, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x1, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY */
+ 0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x1, /* gcFEATURE_BIT_DRAWID */
+ 0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x1, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x1, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x1, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x1, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x1, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x1, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x1, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x1, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER */
+ 0x1, /* gcFEATURE_BIT_TP_LRN */
+ 0x1, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x1, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x1, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x1, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x1, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x1, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x1, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x1, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x1, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* vipnano-q */
+ {
+ 0x8000, /* ChipID */
+ 0x7100, /* ChipRevision */
+ 0x45080001, /* ProductID */
+ 0x0, /* EcoID */
+ 0x0, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x1, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x100, /* gcFEATURE_VALUE_ThreadCount */
+ 0x1, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x10, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x10, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x2, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x2, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x8, /* gcFEATURE_VALUE_Streams */
+ 0x10, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x0, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x40, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x8, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x8, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x8, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x8, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0xc, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x200, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x4, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x400, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x200, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x1, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x1, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x1, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x1, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x1, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x1, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY */
+ 0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x1, /* gcFEATURE_BIT_DRAWID */
+ 0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x1, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x1, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x1, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x1, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x1, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x1, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x1, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x1, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER */
+ 0x1, /* gcFEATURE_BIT_TP_LRN */
+ 0x1, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x1, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x1, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x1, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x1, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x1, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x1, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x1, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x1, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* vipnano-q+ */
+ {
+ 0x8000, /* ChipID */
+ 0x7100, /* ChipRevision */
+ 0x5080001, /* ProductID */
+ 0xc000000, /* EcoID */
+ 0x0, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x1, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x100, /* gcFEATURE_VALUE_ThreadCount */
+ 0x1, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x10, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x10, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x2, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x2, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x8, /* gcFEATURE_VALUE_Streams */
+ 0x10, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x0, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x40, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0xc, /* gcFEATURE_VALUE_NNCoreCount */
+ 0xc, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0xc, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0xc, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0xc, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x200, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x6, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x400, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x200, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x1, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x1, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x1, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x1, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x1, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x1, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY */
+ 0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x1, /* gcFEATURE_BIT_DRAWID */
+ 0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x1, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x1, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x1, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x1, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x1, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x1, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x1, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x1, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER */
+ 0x1, /* gcFEATURE_BIT_TP_LRN */
+ 0x1, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x1, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x1, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x1, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x1, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x1, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x1, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x1, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x1, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* vipnano-o */
+ {
+ 0x8000, /* ChipID */
+ 0x7100, /* ChipRevision */
+ 0x85080001, /* ProductID */
+ 0x0, /* EcoID */
+ 0x0, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x1, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x100, /* gcFEATURE_VALUE_ThreadCount */
+ 0x1, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x10, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x10, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x2, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x2, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x8, /* gcFEATURE_VALUE_Streams */
+ 0x10, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x0, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x40, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x10, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x10, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x10, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x10, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0xc, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x400, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x8, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x800, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x200, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x1, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x1, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x1, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x1, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x1, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x1, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY */
+ 0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x1, /* gcFEATURE_BIT_DRAWID */
+ 0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x1, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x1, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x1, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x1, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x1, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x1, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x1, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x1, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER */
+ 0x1, /* gcFEATURE_BIT_TP_LRN */
+ 0x1, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x1, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x1, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x1, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x1, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x1, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x1, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x1, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x1, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* vipnano-o+ */
+ {
+ 0x8000, /* ChipID */
+ 0x7100, /* ChipRevision */
+ 0x5080001, /* ProductID */
+ 0x18000000, /* EcoID */
+ 0x0, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x1, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x100, /* gcFEATURE_VALUE_ThreadCount */
+ 0x1, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x10, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x10, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x2, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x2, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x8, /* gcFEATURE_VALUE_Streams */
+ 0x10, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x0, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x40, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x18, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x18, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x18, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x18, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0xc, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x400, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0xc, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x800, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x200, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x1, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x1, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x1, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x1, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x1, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x1, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY */
+ 0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x1, /* gcFEATURE_BIT_DRAWID */
+ 0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x1, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x1, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x1, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x1, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x1, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x1, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x1, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x1, /* gcFEATURE_BIT_VIP_V7 */
+ 0x0, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER */
+ 0x1, /* gcFEATURE_BIT_TP_LRN */
+ 0x1, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x1, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x1, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x1, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x1, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x1, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x1, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x1, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x1, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* vipnano-s */
+ {
+ 0x8000, /* ChipID */
+ 0x7200, /* ChipRevision */
+ 0x15080001, /* ProductID */
+ 0x0, /* EcoID */
+ 0x0, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x1, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x100, /* gcFEATURE_VALUE_ThreadCount */
+ 0x1, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x10, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x10, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x2, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x2, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x8, /* gcFEATURE_VALUE_Streams */
+ 0x10, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x0, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x40, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x2, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x2, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x2, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x2, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0xc, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x100, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x1, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x200, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x1, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x1, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x1, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x1, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x1, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x1, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY */
+ 0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x1, /* gcFEATURE_BIT_DRAWID */
+ 0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x1, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x1, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x1, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x1, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x1, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x1, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x1, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x1, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x1, /* gcFEATURE_BIT_VIP_V7 */
+ 0x1, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER */
+ 0x1, /* gcFEATURE_BIT_TP_LRN */
+ 0x1, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x1, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x1, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x1, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x1, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x1, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x1, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x1, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x1, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x1, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x1, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x1, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x1, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* vipnano-s+ */
+ {
+ 0x8000, /* ChipID */
+ 0x7200, /* ChipRevision */
+ 0x5080001, /* ProductID */
+ 0x3000000, /* EcoID */
+ 0x0, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x1, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x100, /* gcFEATURE_VALUE_ThreadCount */
+ 0x1, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x10, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x10, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x2, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x2, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x8, /* gcFEATURE_VALUE_Streams */
+ 0x10, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x0, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x40, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x3, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x3, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x3, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x3, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0xc, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x100, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x1, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x200, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x1, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x1, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x1, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x1, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x1, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x1, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY */
+ 0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x1, /* gcFEATURE_BIT_DRAWID */
+ 0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x1, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x1, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x1, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x1, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x1, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x1, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x1, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x1, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x1, /* gcFEATURE_BIT_VIP_V7 */
+ 0x1, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER */
+ 0x1, /* gcFEATURE_BIT_TP_LRN */
+ 0x1, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x1, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x1, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x1, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x1, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x1, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x1, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x1, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x1, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x1, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x1, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x1, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x1, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* vipnano-d */
+ {
+ 0x8000, /* ChipID */
+ 0x7200, /* ChipRevision */
+ 0x25080001, /* ProductID */
+ 0x0, /* EcoID */
+ 0x0, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x1, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x100, /* gcFEATURE_VALUE_ThreadCount */
+ 0x1, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x10, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x10, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x2, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x2, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x8, /* gcFEATURE_VALUE_Streams */
+ 0x10, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x0, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x40, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x4, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x4, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x4, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x4, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0xc, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x200, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x2, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x200, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x1, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x1, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x1, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x1, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x1, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x1, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY */
+ 0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x1, /* gcFEATURE_BIT_DRAWID */
+ 0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x1, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x1, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x1, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x1, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x1, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x1, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x1, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x1, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x1, /* gcFEATURE_BIT_VIP_V7 */
+ 0x1, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER */
+ 0x1, /* gcFEATURE_BIT_TP_LRN */
+ 0x1, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x1, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x1, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x1, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x1, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x1, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x1, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x1, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x1, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x1, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x1, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x1, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x1, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* vipnano-d+ */
+ {
+ 0x8000, /* ChipID */
+ 0x7200, /* ChipRevision */
+ 0x5080001, /* ProductID */
+ 0x6000000, /* EcoID */
+ 0x0, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x1, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x100, /* gcFEATURE_VALUE_ThreadCount */
+ 0x1, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x10, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x10, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x2, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x2, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x8, /* gcFEATURE_VALUE_Streams */
+ 0x10, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x0, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x40, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x6, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x6, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x6, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x6, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0xc, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x200, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x3, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x200, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x1, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x1, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x1, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x1, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x1, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x1, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY */
+ 0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x1, /* gcFEATURE_BIT_DRAWID */
+ 0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x1, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x1, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x1, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x1, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x1, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x1, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x1, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x1, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x1, /* gcFEATURE_BIT_VIP_V7 */
+ 0x1, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER */
+ 0x1, /* gcFEATURE_BIT_TP_LRN */
+ 0x1, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x1, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x1, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x1, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x1, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x1, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x1, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x1, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x1, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x1, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x1, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x1, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x1, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* vipnano-q */
+ {
+ 0x8000, /* ChipID */
+ 0x7200, /* ChipRevision */
+ 0x45080001, /* ProductID */
+ 0x0, /* EcoID */
+ 0x0, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x1, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x100, /* gcFEATURE_VALUE_ThreadCount */
+ 0x1, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x10, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x10, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x2, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x2, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x8, /* gcFEATURE_VALUE_Streams */
+ 0x10, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x0, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x40, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x8, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x8, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x8, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x8, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0xc, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x400, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x4, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x200, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x1, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x1, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x1, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x1, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x1, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x1, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY */
+ 0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x1, /* gcFEATURE_BIT_DRAWID */
+ 0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x1, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x1, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x1, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x1, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x1, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x1, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x1, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x1, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x1, /* gcFEATURE_BIT_VIP_V7 */
+ 0x1, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER */
+ 0x1, /* gcFEATURE_BIT_TP_LRN */
+ 0x1, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x1, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x1, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x1, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x1, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x1, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x1, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x1, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x1, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x1, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x1, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x1, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x1, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* vipnano-q+ */
+ {
+ 0x8000, /* ChipID */
+ 0x7200, /* ChipRevision */
+ 0x5080001, /* ProductID */
+ 0xc000000, /* EcoID */
+ 0x0, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x1, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x100, /* gcFEATURE_VALUE_ThreadCount */
+ 0x1, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x10, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x10, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x2, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x2, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x8, /* gcFEATURE_VALUE_Streams */
+ 0x10, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x0, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x40, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0xc, /* gcFEATURE_VALUE_NNCoreCount */
+ 0xc, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0xc, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0xc, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0xc, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x400, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x6, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x200, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x1, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x1, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x1, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x1, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x1, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x1, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY */
+ 0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x1, /* gcFEATURE_BIT_DRAWID */
+ 0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x1, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x1, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x1, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x1, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x1, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x1, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x1, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x1, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x1, /* gcFEATURE_BIT_VIP_V7 */
+ 0x1, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER */
+ 0x1, /* gcFEATURE_BIT_TP_LRN */
+ 0x1, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x1, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x1, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x1, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x1, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x1, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x1, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x1, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x1, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x1, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x1, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x1, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x1, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* vipnano-o */
+ {
+ 0x8000, /* ChipID */
+ 0x7200, /* ChipRevision */
+ 0x85080001, /* ProductID */
+ 0x0, /* EcoID */
+ 0x0, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x1, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x100, /* gcFEATURE_VALUE_ThreadCount */
+ 0x1, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x10, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x10, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x2, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x2, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x8, /* gcFEATURE_VALUE_Streams */
+ 0x10, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x0, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x40, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x10, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x10, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x10, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x10, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0xc, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x800, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x8, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x200, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x1, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x1, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x1, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x1, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x1, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x1, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY */
+ 0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x1, /* gcFEATURE_BIT_DRAWID */
+ 0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x1, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x1, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x1, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x1, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x1, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x1, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x1, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x1, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x1, /* gcFEATURE_BIT_VIP_V7 */
+ 0x1, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER */
+ 0x1, /* gcFEATURE_BIT_TP_LRN */
+ 0x1, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x1, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x1, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x1, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x1, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x1, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x1, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x1, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x1, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x1, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x1, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x1, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x1, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* vipnano-o+ */
+ {
+ 0x8000, /* ChipID */
+ 0x7200, /* ChipRevision */
+ 0x5080001, /* ProductID */
+ 0x18000000, /* EcoID */
+ 0x0, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x1, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x100, /* gcFEATURE_VALUE_ThreadCount */
+ 0x1, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x10, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x10, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x2, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x2, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x8, /* gcFEATURE_VALUE_Streams */
+ 0x10, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x0, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x40, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x18, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x18, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x18, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x18, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0xc, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x800, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0xc, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x200, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x1, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x1, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x1, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x1, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x1, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x1, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY */
+ 0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x1, /* gcFEATURE_BIT_DRAWID */
+ 0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x1, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x1, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x1, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x1, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x1, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x1, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x1, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x1, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x1, /* gcFEATURE_BIT_VIP_V7 */
+ 0x1, /* gcFEATURE_BIT_MCFE */
+ 0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER */
+ 0x1, /* gcFEATURE_BIT_TP_LRN */
+ 0x1, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x1, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x1, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x1, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x1, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x1, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x1, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x1, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x1, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x1, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x1, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x1, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x1, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* vipnano-s */
+ {
+ 0x8000, /* ChipID */
+ 0x7300, /* ChipRevision */
+ 0x15080001, /* ProductID */
+ 0x0, /* EcoID */
+ 0x0, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x1, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x100, /* gcFEATURE_VALUE_ThreadCount */
+ 0x1, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x10, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x10, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x2, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x2, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x8, /* gcFEATURE_VALUE_Streams */
+ 0x10, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x0, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x40, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x2, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x2, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x2, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x2, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0xc, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x100, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x1, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x200, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x1, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x1, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x1, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x1, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x1, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x1, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY */
+ 0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x1, /* gcFEATURE_BIT_DRAWID */
+ 0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x1, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x1, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x1, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x1, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x1, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x1, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x1, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x1, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x1, /* gcFEATURE_BIT_VIP_V7 */
+ 0x1, /* gcFEATURE_BIT_MCFE */
+ 0x1, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER */
+ 0x1, /* gcFEATURE_BIT_TP_LRN */
+ 0x1, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x1, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x1, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x1, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x1, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x1, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x1, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x1, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x1, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x1, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x1, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x1, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x1, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x1, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x1, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x1, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x1, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x1, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* vipnano-s+ */
+ {
+ 0x8000, /* ChipID */
+ 0x7300, /* ChipRevision */
+ 0x5080001, /* ProductID */
+ 0x3000000, /* EcoID */
+ 0x0, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x1, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x100, /* gcFEATURE_VALUE_ThreadCount */
+ 0x1, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x10, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x10, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x2, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x2, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x8, /* gcFEATURE_VALUE_Streams */
+ 0x10, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x0, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x40, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x3, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x3, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x3, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x3, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0xc, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x100, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x1, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x200, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x1, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x1, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x1, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x1, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x1, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x1, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY */
+ 0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x1, /* gcFEATURE_BIT_DRAWID */
+ 0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x1, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x1, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x1, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x1, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x1, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x1, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x1, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x1, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x1, /* gcFEATURE_BIT_VIP_V7 */
+ 0x1, /* gcFEATURE_BIT_MCFE */
+ 0x1, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER */
+ 0x1, /* gcFEATURE_BIT_TP_LRN */
+ 0x1, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x1, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x1, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x1, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x1, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x1, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x1, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x1, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x1, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x1, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x1, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x1, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x1, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x1, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x1, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x1, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x1, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x1, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* vipnano-d */
+ {
+ 0x8000, /* ChipID */
+ 0x7300, /* ChipRevision */
+ 0x25080001, /* ProductID */
+ 0x0, /* EcoID */
+ 0x0, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x1, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x100, /* gcFEATURE_VALUE_ThreadCount */
+ 0x1, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x10, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x10, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x2, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x2, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x8, /* gcFEATURE_VALUE_Streams */
+ 0x10, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x0, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x40, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x4, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x4, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x4, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x4, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0xc, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x200, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x2, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x200, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x1, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x1, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x1, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x1, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x1, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x1, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY */
+ 0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x1, /* gcFEATURE_BIT_DRAWID */
+ 0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x1, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x1, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x1, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x1, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x1, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x1, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x1, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x1, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x1, /* gcFEATURE_BIT_VIP_V7 */
+ 0x1, /* gcFEATURE_BIT_MCFE */
+ 0x1, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER */
+ 0x1, /* gcFEATURE_BIT_TP_LRN */
+ 0x1, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x1, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x1, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x1, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x1, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x1, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x1, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x1, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x1, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x1, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x1, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x1, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x1, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x1, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x1, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x1, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x1, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x1, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* vipnano-d+ */
+ {
+ 0x8000, /* ChipID */
+ 0x7300, /* ChipRevision */
+ 0x5080001, /* ProductID */
+ 0x6000000, /* EcoID */
+ 0x0, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x1, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x100, /* gcFEATURE_VALUE_ThreadCount */
+ 0x1, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x10, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x10, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x2, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x2, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x8, /* gcFEATURE_VALUE_Streams */
+ 0x10, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x0, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x40, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x6, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x6, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x6, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x6, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0xc, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x200, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x3, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x200, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x1, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x1, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x1, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x1, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x1, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x1, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY */
+ 0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x1, /* gcFEATURE_BIT_DRAWID */
+ 0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x1, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x1, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x1, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x1, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x1, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x1, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x1, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x1, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x1, /* gcFEATURE_BIT_VIP_V7 */
+ 0x1, /* gcFEATURE_BIT_MCFE */
+ 0x1, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER */
+ 0x1, /* gcFEATURE_BIT_TP_LRN */
+ 0x1, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x1, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x1, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x1, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x1, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x1, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x1, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x1, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x1, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x1, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x1, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x1, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x1, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x1, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x1, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x1, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x1, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x1, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* vipnano-q */
+ {
+ 0x8000, /* ChipID */
+ 0x7300, /* ChipRevision */
+ 0x45080001, /* ProductID */
+ 0x0, /* EcoID */
+ 0x0, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x1, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x100, /* gcFEATURE_VALUE_ThreadCount */
+ 0x1, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x10, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x10, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x2, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x2, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x8, /* gcFEATURE_VALUE_Streams */
+ 0x10, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x0, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x40, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x8, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x8, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x8, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x8, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0xc, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x400, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x4, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x200, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x1, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x1, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x1, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x1, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x1, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x1, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY */
+ 0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x1, /* gcFEATURE_BIT_DRAWID */
+ 0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x1, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x1, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x1, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x1, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x1, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x1, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x1, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x1, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x1, /* gcFEATURE_BIT_VIP_V7 */
+ 0x1, /* gcFEATURE_BIT_MCFE */
+ 0x1, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER */
+ 0x1, /* gcFEATURE_BIT_TP_LRN */
+ 0x1, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x1, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x1, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x1, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x1, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x1, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x1, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x1, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x1, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x1, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x1, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x1, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x1, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x1, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x1, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x1, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x1, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x1, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* vipnano-q+ */
+ {
+ 0x8000, /* ChipID */
+ 0x7300, /* ChipRevision */
+ 0x5080001, /* ProductID */
+ 0xc000000, /* EcoID */
+ 0x0, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x1, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x100, /* gcFEATURE_VALUE_ThreadCount */
+ 0x1, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x10, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x10, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x2, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x2, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x8, /* gcFEATURE_VALUE_Streams */
+ 0x10, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x0, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x40, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0xc, /* gcFEATURE_VALUE_NNCoreCount */
+ 0xc, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0xc, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0xc, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0xc, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x400, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x6, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x200, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x1, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x1, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x1, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x1, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x1, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x1, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY */
+ 0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x1, /* gcFEATURE_BIT_DRAWID */
+ 0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x1, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x1, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x1, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x1, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x1, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x1, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x1, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x1, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x1, /* gcFEATURE_BIT_VIP_V7 */
+ 0x1, /* gcFEATURE_BIT_MCFE */
+ 0x1, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER */
+ 0x1, /* gcFEATURE_BIT_TP_LRN */
+ 0x1, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x1, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x1, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x1, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x1, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x1, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x1, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x1, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x1, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x1, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x1, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x1, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x1, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x1, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x1, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x1, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x1, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x1, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* vipnano-o */
+ {
+ 0x8000, /* ChipID */
+ 0x7300, /* ChipRevision */
+ 0x85080001, /* ProductID */
+ 0x0, /* EcoID */
+ 0x0, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x1, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x100, /* gcFEATURE_VALUE_ThreadCount */
+ 0x1, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x10, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x10, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x2, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x2, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x8, /* gcFEATURE_VALUE_Streams */
+ 0x10, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x0, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x40, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x10, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x10, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x10, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x10, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0xc, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x7e2, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x8, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x200, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x1, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x1, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x1, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x1, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x1, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x1, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY */
+ 0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x1, /* gcFEATURE_BIT_DRAWID */
+ 0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x1, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x1, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x1, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x1, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x1, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x1, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x1, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x1, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x1, /* gcFEATURE_BIT_VIP_V7 */
+ 0x1, /* gcFEATURE_BIT_MCFE */
+ 0x1, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER */
+ 0x1, /* gcFEATURE_BIT_TP_LRN */
+ 0x1, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x1, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x1, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x1, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x1, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x1, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x1, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x1, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x1, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x1, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x1, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x1, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x1, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x1, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x1, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x1, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x1, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x1, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* vipnano-o+ */
+ {
+ 0x8000, /* ChipID */
+ 0x7300, /* ChipRevision */
+ 0x5080001, /* ProductID */
+ 0x18000000, /* EcoID */
+ 0x0, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x1, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x100, /* gcFEATURE_VALUE_ThreadCount */
+ 0x1, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x10, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x10, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x2, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x2, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x8, /* gcFEATURE_VALUE_Streams */
+ 0x10, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x0, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x40, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x18, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x18, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x18, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x18, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0xc, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x800, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0xc, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x200, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x1, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x1, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x1, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x1, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x1, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x1, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY */
+ 0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x1, /* gcFEATURE_BIT_DRAWID */
+ 0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x1, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x1, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x1, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x1, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x1, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x1, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x1, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x1, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x1, /* gcFEATURE_BIT_VIP_V7 */
+ 0x1, /* gcFEATURE_BIT_MCFE */
+ 0x1, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER */
+ 0x1, /* gcFEATURE_BIT_TP_LRN */
+ 0x1, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x1, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x1, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x1, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x1, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x1, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x1, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x1, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x1, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x1, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x1, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x1, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x1, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x1, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x1, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x1, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x1, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x1, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* vipnano-s */
+ {
+ 0x8000, /* ChipID */
+ 0x8000, /* ChipRevision */
+ 0x5080001, /* ProductID */
+ 0x2000000, /* EcoID */
+ 0x0, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x1, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x100, /* gcFEATURE_VALUE_ThreadCount */
+ 0x1, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x10, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x10, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x1, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x2, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x8, /* gcFEATURE_VALUE_Streams */
+ 0x10, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x0, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x40, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x4, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x4, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x4, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x4, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0xc, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x20, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x100, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x2, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x200, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x10, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x20, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x1, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x1, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x1, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x1, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x1, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x1, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY */
+ 0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x1, /* gcFEATURE_BIT_DRAWID */
+ 0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x1, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x1, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x1, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x1, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x1, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x1, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x1, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x1, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x1, /* gcFEATURE_BIT_VIP_V7 */
+ 0x1, /* gcFEATURE_BIT_MCFE */
+ 0x1, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER */
+ 0x1, /* gcFEATURE_BIT_TP_LRN */
+ 0x1, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x1, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x1, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x1, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x1, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x1, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x1, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x1, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x1, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x1, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x1, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x1, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x1, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x1, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x1, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x1, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x1, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x1, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x1, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x1, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x1, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x1, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x1, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x1, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* vipnano-s+ */
+ {
+ 0x8000, /* ChipID */
+ 0x8000, /* ChipRevision */
+ 0x5080001, /* ProductID */
+ 0x3000000, /* EcoID */
+ 0x0, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x1, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x100, /* gcFEATURE_VALUE_ThreadCount */
+ 0x1, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x10, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x10, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x1, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x2, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x8, /* gcFEATURE_VALUE_Streams */
+ 0x10, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x0, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x40, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x6, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x6, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x6, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x6, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0xc, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x20, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x100, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x3, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x200, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x10, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x20, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x1, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x1, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x1, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x1, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x1, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x1, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY */
+ 0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x1, /* gcFEATURE_BIT_DRAWID */
+ 0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x1, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x1, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x1, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x1, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x1, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x1, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x1, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x1, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x1, /* gcFEATURE_BIT_VIP_V7 */
+ 0x1, /* gcFEATURE_BIT_MCFE */
+ 0x1, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER */
+ 0x1, /* gcFEATURE_BIT_TP_LRN */
+ 0x1, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x1, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x1, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x1, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x1, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x1, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x1, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x1, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x1, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x1, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x1, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x1, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x1, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x1, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x1, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x1, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x1, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x1, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x1, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x1, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x1, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x1, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x1, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x1, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* vipnano-d */
+ {
+ 0x8000, /* ChipID */
+ 0x8000, /* ChipRevision */
+ 0x5080001, /* ProductID */
+ 0x4000000, /* EcoID */
+ 0x0, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x1, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x100, /* gcFEATURE_VALUE_ThreadCount */
+ 0x1, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x10, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x10, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x2, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x2, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x8, /* gcFEATURE_VALUE_Streams */
+ 0x10, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x0, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x40, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x8, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x8, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x8, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x8, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0xc, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x20, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x200, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x4, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x200, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x20, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x40, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x1, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x1, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x1, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x1, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x1, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x1, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY */
+ 0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x1, /* gcFEATURE_BIT_DRAWID */
+ 0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x1, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x1, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x1, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x1, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x1, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x1, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x1, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x1, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x1, /* gcFEATURE_BIT_VIP_V7 */
+ 0x1, /* gcFEATURE_BIT_MCFE */
+ 0x1, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER */
+ 0x1, /* gcFEATURE_BIT_TP_LRN */
+ 0x1, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x1, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x1, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x1, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x1, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x1, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x1, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x1, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x1, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x1, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x1, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x1, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x1, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x1, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x1, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x1, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x1, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x1, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x1, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x1, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x1, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x1, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x1, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x1, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* vipnano-d+ */
+ {
+ 0x8000, /* ChipID */
+ 0x8000, /* ChipRevision */
+ 0x5080001, /* ProductID */
+ 0x6000000, /* EcoID */
+ 0x0, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x1, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x100, /* gcFEATURE_VALUE_ThreadCount */
+ 0x1, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x10, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x10, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x2, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x2, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x8, /* gcFEATURE_VALUE_Streams */
+ 0x10, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x0, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x40, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0xc, /* gcFEATURE_VALUE_NNCoreCount */
+ 0xc, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0xc, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0xc, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0xc, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x20, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x200, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x6, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x200, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x20, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x40, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x1, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x1, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x1, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x1, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x1, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x1, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY */
+ 0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x1, /* gcFEATURE_BIT_DRAWID */
+ 0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x1, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x1, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x1, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x1, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x1, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x1, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x1, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x1, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x1, /* gcFEATURE_BIT_VIP_V7 */
+ 0x1, /* gcFEATURE_BIT_MCFE */
+ 0x1, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER */
+ 0x1, /* gcFEATURE_BIT_TP_LRN */
+ 0x1, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x1, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x1, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x1, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x1, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x1, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x1, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x1, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x1, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x1, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x1, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x1, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x1, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x1, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x1, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x1, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x1, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x1, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x1, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x1, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x1, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x1, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x1, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x1, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* vipnano-q */
+ {
+ 0x8000, /* ChipID */
+ 0x8000, /* ChipRevision */
+ 0x5080001, /* ProductID */
+ 0x8000000, /* EcoID */
+ 0x0, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x1, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x100, /* gcFEATURE_VALUE_ThreadCount */
+ 0x1, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x10, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x10, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x2, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x2, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x8, /* gcFEATURE_VALUE_Streams */
+ 0x10, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x0, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x40, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x10, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x10, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x10, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x10, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0xc, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x20, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x400, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x8, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x200, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x40, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x40, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x1, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x1, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x1, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x1, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x1, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x1, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY */
+ 0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x1, /* gcFEATURE_BIT_DRAWID */
+ 0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x1, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x1, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x1, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x1, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x1, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x1, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x1, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x1, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x1, /* gcFEATURE_BIT_VIP_V7 */
+ 0x1, /* gcFEATURE_BIT_MCFE */
+ 0x1, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER */
+ 0x1, /* gcFEATURE_BIT_TP_LRN */
+ 0x1, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x1, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x1, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x1, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x1, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x1, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x1, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x1, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x1, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x1, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x1, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x1, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x1, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x1, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x1, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x1, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x1, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x1, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x1, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x1, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x1, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x1, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x1, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x1, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* vipnano-q+ */
+ {
+ 0x8000, /* ChipID */
+ 0x8000, /* ChipRevision */
+ 0x5080001, /* ProductID */
+ 0xc000000, /* EcoID */
+ 0x0, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x1, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x100, /* gcFEATURE_VALUE_ThreadCount */
+ 0x1, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x10, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x10, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x4, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x2, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x8, /* gcFEATURE_VALUE_Streams */
+ 0x10, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x0, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x40, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x18, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x18, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x18, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x18, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0xc, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x20, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x400, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0xc, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x200, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x40, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x40, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x1, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x1, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x1, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x1, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x1, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x1, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY */
+ 0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x1, /* gcFEATURE_BIT_DRAWID */
+ 0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x1, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x1, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x1, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x1, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x1, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x1, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x1, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x1, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x1, /* gcFEATURE_BIT_VIP_V7 */
+ 0x1, /* gcFEATURE_BIT_MCFE */
+ 0x1, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER */
+ 0x1, /* gcFEATURE_BIT_TP_LRN */
+ 0x1, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x1, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x1, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x1, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x1, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x1, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x1, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x1, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x1, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x1, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x1, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x1, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x1, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x1, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x1, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x1, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x1, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x1, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x1, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x1, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x1, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x1, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x1, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x1, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* vipnano-o */
+ {
+ 0x8000, /* ChipID */
+ 0x8000, /* ChipRevision */
+ 0x5080001, /* ProductID */
+ 0x10000000, /* EcoID */
+ 0x0, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x1, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x100, /* gcFEATURE_VALUE_ThreadCount */
+ 0x1, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x10, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x10, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x4, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x2, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x8, /* gcFEATURE_VALUE_Streams */
+ 0x10, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x0, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x40, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x20, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x20, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x20, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x20, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0xc, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x20, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x800, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x10, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x200, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x40, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x40, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x1, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x1, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x1, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x1, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x1, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x1, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY */
+ 0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x1, /* gcFEATURE_BIT_DRAWID */
+ 0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x1, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x1, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x1, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x1, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x1, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x1, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x1, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x1, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x1, /* gcFEATURE_BIT_VIP_V7 */
+ 0x1, /* gcFEATURE_BIT_MCFE */
+ 0x1, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER */
+ 0x1, /* gcFEATURE_BIT_TP_LRN */
+ 0x1, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x1, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x1, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x1, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x1, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x1, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x1, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x1, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x1, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x1, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x1, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x1, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x1, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x1, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x1, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x1, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x1, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x1, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x1, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x1, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x1, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x1, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x1, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x1, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* vipnano-o+ */
+ {
+ 0x8000, /* ChipID */
+ 0x8000, /* ChipRevision */
+ 0x5080001, /* ProductID */
+ 0x18000000, /* EcoID */
+ 0x0, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x1, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x100, /* gcFEATURE_VALUE_ThreadCount */
+ 0x1, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x10, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x10, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x4, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x2, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x8, /* gcFEATURE_VALUE_Streams */
+ 0x10, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x0, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x40, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x30, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x30, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x30, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x30, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0xc, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x20, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x800, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x18, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x200, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x40, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x40, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x1, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x1, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x1, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x1, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x1, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x1, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY */
+ 0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x1, /* gcFEATURE_BIT_DRAWID */
+ 0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x1, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x1, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x1, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x1, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x1, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x1, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x1, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x1, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x1, /* gcFEATURE_BIT_VIP_V7 */
+ 0x1, /* gcFEATURE_BIT_MCFE */
+ 0x1, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER */
+ 0x1, /* gcFEATURE_BIT_TP_LRN */
+ 0x1, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x1, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x1, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x1, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x1, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x1, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x1, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x1, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x1, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x1, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x1, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x1, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x1, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x1, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x1, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x1, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x1, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x1, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x1, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x1, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x1, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x1, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x1, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x1, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* vip8000ulo_mp */
+ {
+ 0x8000, /* ChipID */
+ 0x8000, /* ChipRevision */
+ 0x5080003, /* ProductID */
+ 0x10000000, /* EcoID */
+ 0x0, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x1, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x100, /* gcFEATURE_VALUE_ThreadCount */
+ 0x1, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x2, /* gcFEATURE_VALUE_CoreCount */
+ 0x10, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x10, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x2, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x2, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x8, /* gcFEATURE_VALUE_Streams */
+ 0x10, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x0, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x40, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x10, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x10, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x10, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x10, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0xc, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x20, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x400, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x10, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x200, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x20, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x1, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x1, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x1, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x1, /* gcFEATURE_BIT_VMSAA */
+ 0x1, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x1, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x1, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY */
+ 0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x1, /* gcFEATURE_BIT_DRAWID */
+ 0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x1, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x1, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x1, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x1, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x1, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x1, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x1, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x1, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x1, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x1, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x1, /* gcFEATURE_BIT_VIP_V7 */
+ 0x1, /* gcFEATURE_BIT_MCFE */
+ 0x1, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER */
+ 0x1, /* gcFEATURE_BIT_TP_LRN */
+ 0x1, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x1, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x1, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x1, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x1, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x1, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x1, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x1, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x1, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x1, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x1, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x1, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x1, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x1, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x1, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x1, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x1, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x1, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x1, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x1, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x1, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x1, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x1, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x1, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* vip8000ulo+_mp */
+ {
+ 0x8000, /* ChipID */
+ 0x8000, /* ChipRevision */
+ 0x5080003, /* ProductID */
+ 0x18000000, /* EcoID */
+ 0x0, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x1, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x100, /* gcFEATURE_VALUE_ThreadCount */
+ 0x1, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x2, /* gcFEATURE_VALUE_CoreCount */
+ 0x10, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x10, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x2, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x2, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x8, /* gcFEATURE_VALUE_Streams */
+ 0x10, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x0, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x40, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x18, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x18, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x18, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x18, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0xc, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x20, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x400, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x18, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x200, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x20, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x1, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x1, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x1, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x1, /* gcFEATURE_BIT_VMSAA */
+ 0x1, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x1, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x1, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY */
+ 0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x1, /* gcFEATURE_BIT_DRAWID */
+ 0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x1, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x1, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x1, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x1, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x1, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x1, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x1, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x1, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x1, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x1, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x1, /* gcFEATURE_BIT_VIP_V7 */
+ 0x1, /* gcFEATURE_BIT_MCFE */
+ 0x1, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER */
+ 0x1, /* gcFEATURE_BIT_TP_LRN */
+ 0x1, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x1, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x1, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x1, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x1, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x1, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x1, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x1, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x1, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x1, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x1, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x1, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x1, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x1, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x1, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x1, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x1, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x1, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x1, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x1, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x1, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x1, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x1, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x1, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* vip8000lh_mp */
+ {
+ 0x8000, /* ChipID */
+ 0x8000, /* ChipRevision */
+ 0x5080002, /* ProductID */
+ 0x20000000, /* EcoID */
+ 0x0, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x1, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x100, /* gcFEATURE_VALUE_ThreadCount */
+ 0x1, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x4, /* gcFEATURE_VALUE_CoreCount */
+ 0x10, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x10, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x2, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x2, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x8, /* gcFEATURE_VALUE_Streams */
+ 0x10, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x0, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x40, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x10, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x10, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x10, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x10, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0xc, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x20, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x400, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x10, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x200, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x20, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x1, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x1, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x1, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x1, /* gcFEATURE_BIT_VMSAA */
+ 0x1, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x1, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x1, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY */
+ 0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x1, /* gcFEATURE_BIT_DRAWID */
+ 0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x1, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x1, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x1, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x1, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x1, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x1, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x1, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x1, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x1, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x1, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x1, /* gcFEATURE_BIT_VIP_V7 */
+ 0x1, /* gcFEATURE_BIT_MCFE */
+ 0x1, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER */
+ 0x1, /* gcFEATURE_BIT_TP_LRN */
+ 0x1, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x1, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x1, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x1, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x1, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x1, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x1, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x1, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x1, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x1, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x1, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x1, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x1, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x1, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x1, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x1, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x1, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x1, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x1, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x1, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x1, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x1, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x1, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x1, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* vip8000lh+_mp */
+ {
+ 0x8000, /* ChipID */
+ 0x8000, /* ChipRevision */
+ 0x5080002, /* ProductID */
+ 0x30000000, /* EcoID */
+ 0x0, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x1, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x100, /* gcFEATURE_VALUE_ThreadCount */
+ 0x1, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x4, /* gcFEATURE_VALUE_CoreCount */
+ 0x10, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x10, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x2, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x2, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x8, /* gcFEATURE_VALUE_Streams */
+ 0x10, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x0, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x40, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x18, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x18, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x18, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x18, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0xc, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x20, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x400, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x18, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x200, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x20, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x1, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x1, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x1, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x1, /* gcFEATURE_BIT_VMSAA */
+ 0x1, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x1, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x1, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY */
+ 0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x1, /* gcFEATURE_BIT_DRAWID */
+ 0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x1, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x1, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x1, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x1, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x1, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x1, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x1, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x1, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x1, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x1, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x1, /* gcFEATURE_BIT_VIP_V7 */
+ 0x1, /* gcFEATURE_BIT_MCFE */
+ 0x1, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER */
+ 0x1, /* gcFEATURE_BIT_TP_LRN */
+ 0x1, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x1, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x1, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x1, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x1, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x1, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x1, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x1, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x1, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x1, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x1, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x1, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x1, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x1, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x1, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x1, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x1, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x1, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x1, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x1, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x1, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x1, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x1, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x1, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+ /* vippico */
+ {
+ 0x8000, /* ChipID */
+ 0x8000, /* ChipRevision */
+ 0x8000001, /* ProductID */
+ 0x2000000, /* EcoID */
+ 0x0, /* CustomerID */
+ 0x0, /* PatchVersion */
+ "", /* ProductName */
+ 0x1, /* FormalRelease */
+ 0x40, /* gcFEATURE_VALUE_TempRegisters */
+ 0x100, /* gcFEATURE_VALUE_ThreadCount */
+ 0x1, /* gcFEATURE_VALUE_NumShaderCores */
+ 0x200, /* gcFEATURE_VALUE_InstructionCount */
+ 0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+ 0x1, /* gcFEATURE_VALUE_CoreCount */
+ 0x10, /* gcFEATURE_VALUE_LocalStorageSize */
+ 0x10, /* gcFEATURE_VALUE_L1CacheSize */
+ 0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+ 0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+ 0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+ 0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+ 0x2, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+ 0x2, /* gcFEATURE_VALUE_USC_BANKS */
+ 0x8, /* gcFEATURE_VALUE_Streams */
+ 0x10, /* gcFEATURE_VALUE_VaryingCount */
+ 0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+ 0x0, /* gcFEATURE_VALUE_BufferSize */
+ 0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+ 0x0, /* gcFEATURE_VALUE_NumResolvePipes */
+ 0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+ 0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+ 0x40, /* gcFEATURE_VALUE_NNMadPerCore */
+ 0x2, /* gcFEATURE_VALUE_NNCoreCount */
+ 0x2, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+ 0x2, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+ 0x2, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+ 0xc, /* gcFEATURE_VALUE_NNInputBufferDepth */
+ 0x20, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+ 0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+ 0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+ 0x80, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+ 0x1, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+ 0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+ 0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+ 0x200, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+ 0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+ 0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
+ 0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+ 0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+ 0x20, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+ 0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+ 0x1, /* gcFEATURE_BIT_REG_FastClear */
+ 0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+ 0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+ 0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+ 0x0, /* gcFEATURE_BIT_REG_DebugMode */
+ 0x1, /* gcFEATURE_BIT_REG_ZCompression */
+ 0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+ 0x1, /* gcFEATURE_BIT_REG_MSAA */
+ 0x0, /* gcFEATURE_BIT_REG_DC */
+ 0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+ 0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+ 0x1, /* gcFEATURE_BIT_REG_FastScaler */
+ 0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+ 0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+ 0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+ 0x0, /* gcFEATURE_BIT_REG_MinArea */
+ 0x0, /* gcFEATURE_BIT_REG_NoEZ */
+ 0x0, /* gcFEATURE_BIT_REG_No422Texture */
+ 0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+ 0x0, /* gcFEATURE_BIT_REG_NoScaler */
+ 0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+ 0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+ 0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+ 0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+ 0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+ 0x0, /* gcFEATURE_BIT_REG_PipeVG */
+ 0x0, /* gcFEATURE_BIT_REG_VGTS */
+ 0x0, /* gcFEATURE_BIT_REG_FE20 */
+ 0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+ 0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+ 0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+ 0x1, /* gcFEATURE_BIT_REG_FlipY */
+ 0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+ 0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+ 0x1, /* gcFEATURE_BIT_REG_Texture8K */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+ 0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+ 0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+ 0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+ 0x1, /* gcFEATURE_BIT_REG_Render8K */
+ 0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+ 0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+ 0x0, /* gcFEATURE_BIT_REG_VG20 */
+ 0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+ 0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+ 0x0, /* gcFEATURE_BIT_REG_VGFilter */
+ 0x0, /* gcFEATURE_BIT_REG_VG21 */
+ 0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+ 0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+ 0x1, /* gcFEATURE_BIT_REG_MC20 */
+ 0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+ 0x0, /* gcFEATURE_BIT_REG_VAA */
+ 0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+ 0x0, /* gcFEATURE_BIT_REG_NewTexture */
+ 0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+ 0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+ 0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_V2Compression */
+ 0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+ 0x0, /* gcFEATURE_BIT_REG_TextureStride */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+ 0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+ 0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+ 0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+ 0x1, /* gcFEATURE_BIT_REG_PixelDither */
+ 0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+ 0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+ 0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+ 0x0, /* gcFEATURE_BIT_REG_New2D */
+ 0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+ 0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+ 0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+ 0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+ 0x1, /* gcFEATURE_BIT_REG_Halti0 */
+ 0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+ 0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+ 0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+ 0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+ 0x1, /* gcFEATURE_BIT_REG_MMU */
+ 0x1, /* gcFEATURE_BIT_REG_WideLine */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+ 0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+ 0x1, /* gcFEATURE_BIT_REG_LineLoop */
+ 0x1, /* gcFEATURE_BIT_REG_LogicOp */
+ 0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+ 0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+ 0x1, /* gcFEATURE_BIT_REG_LinearPE */
+ 0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+ 0x0, /* gcFEATURE_BIT_REG_Composition */
+ 0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+ 0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+ 0x1, /* gcFEATURE_BIT_REG_EndEvent */
+ 0x1, /* gcFEATURE_BIT_REG_S1S8 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti1 */
+ 0x0, /* gcFEATURE_BIT_REG_RGB888 */
+ 0x1, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+ 0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+ 0x0, /* gcFEATURE_BIT_REG_TXFilter */
+ 0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+ 0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+ 0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+ 0x1, /* gcFEATURE_BIT_REG_TileFiller */
+ 0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+ 0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+ 0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+ 0x1, /* gcFEATURE_BIT_REG_Interleaver */
+ 0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+ 0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+ 0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+ 0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+ 0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+ 0x0, /* gcFEATURE_BIT_REG_OclOnly */
+ 0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+ 0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+ 0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+ 0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+ 0x1, /* gcFEATURE_BIT_REG_Generics */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+ 0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+ 0x0, /* gcFEATURE_BIT_REG_WClip */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+ 0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+ 0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+ 0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_ACE */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+ 0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+ 0x1, /* gcFEATURE_BIT_REG_NewHZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+ 0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+ 0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+ 0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+ 0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+ 0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+ 0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti2 */
+ 0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+ 0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+ 0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+ 0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+ 0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+ 0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+ 0x0, /* gcFEATURE_BIT_REG_Compression2D */
+ 0x0, /* gcFEATURE_BIT_REG_Probe */
+ 0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+ 0x0, /* gcFEATURE_BIT_REG_DESupertile */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+ 0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+ 0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+ 0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+ 0x1, /* gcFEATURE_BIT_REG_EEZ */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+ 0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+ 0x1, /* gcFEATURE_BIT_REG_Halti3 */
+ 0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+ 0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+ 0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+ 0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+ 0x1, /* gcFEATURE_BIT_REG_Halti4 */
+ 0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+ 0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+ 0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+ 0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+ 0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+ 0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+ 0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+ 0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+ 0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+ 0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+ 0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+ 0x1, /* gcFEATURE_BIT_REG_RSS8 */
+ 0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+ 0x1, /* gcFEATURE_BIT_REG_Halti5 */
+ 0x1, /* gcFEATURE_BIT_REG_Evis */
+ 0x0, /* gcFEATURE_BIT_REG_BltEngine */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+ 0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+ 0x0, /* gcFEATURE_BIT_REG_DEC */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+ 0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+ 0x0, /* gcFEATURE_BIT_RenderTarget8 */
+ 0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+ 0x0, /* gcFEATURE_BIT_FaceLod */
+ 0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+ 0x1, /* gcFEATURE_BIT_VMSAA */
+ 0x0, /* gcFEATURE_BIT_ChipEnableLink */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+ 0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+ 0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+ 0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+ 0x1, /* gcFEATURE_BIT_V4Compression */
+ 0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+ 0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+ 0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+ 0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+ 0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+ 0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+ 0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+ 0x1, /* gcFEATURE_BIT_NO_ASTC */
+ 0x0, /* gcFEATURE_BIT_NO_DXT */
+ 0x0, /* gcFEATURE_BIT_HWTFB */
+ 0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+ 0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+ 0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+ 0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+ 0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+ 0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+ 0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+ 0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+ 0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+ 0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+ 0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+ 0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+ 0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+ 0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+ 0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY */
+ 0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+ 0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+ 0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+ 0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+ 0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+ 0x1, /* gcFEATURE_BIT_DRAWID */
+ 0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+ 0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+ 0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+ 0x1, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+ 0x1, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+ 0x1, /* gcFEATURE_BIT_COMPUTE_ONLY */
+ 0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+ 0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+ 0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+ 0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+ 0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+ 0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+ 0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+ 0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+ 0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+ 0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+ 0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+ 0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+ 0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+ 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+ 0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+ 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+ 0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+ 0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+ 0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_DEC400 */
+ 0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+ 0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+ 0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+ 0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+ 0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+ 0x0, /* gcFEATURE_BIT_SMALLBATCH */
+ 0x0, /* gcFEATURE_BIT_SH_CMPLX */
+ 0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+ 0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+ 0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+ 0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+ 0x1, /* gcFEATURE_BIT_SH_END_OF_BB */
+ 0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+ 0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+ 0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+ 0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+ 0x1, /* gcFEATURE_BIT_PSCS_THROTTLE */
+ 0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+ 0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+ 0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+ 0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+ 0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+ 0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+ 0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+ 0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+ 0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+ 0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+ 0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+ 0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+ 0x1, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+ 0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+ 0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+ 0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+ 0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+ 0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+ 0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+ 0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+ 0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+ 0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+ 0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+ 0x0, /* gcFEATURE_BIT_MP_ARCH */
+ 0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+ 0x0, /* gcFEATURE_BIT_VG_FP25 */
+ 0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+ 0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+ 0x0, /* gcFEATURE_BIT_VG_MMU */
+ 0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+ 0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+ 0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+ 0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+ 0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+ 0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+ 0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+ 0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+ 0x0, /* gcFEATURE_BIT_DC_TILED */
+ 0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+ 0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+ 0x0, /* gcFEATURE_BIT_DC_MMU */
+ 0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+ 0x0, /* gcFEATURE_BIT_DC_QOS */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+ 0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+ 0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+ 0x1, /* gcFEATURE_BIT_EVIS_VX2 */
+ 0x1, /* gcFEATURE_BIT_NN_FLOAT */
+ 0x1, /* gcFEATURE_BIT_TP_ENGINE */
+ 0x1, /* gcFEATURE_BIT_VIP_V7 */
+ 0x1, /* gcFEATURE_BIT_MCFE */
+ 0x1, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER */
+ 0x1, /* gcFEATURE_BIT_TP_LRN */
+ 0x1, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+ 0x1, /* gcFEATURE_BIT_NN_FP16_ALU */
+ 0x1, /* gcFEATURE_BIT_NN_INT16_ALU */
+ 0x1, /* gcFEATURE_BIT_TP_ROI_POOLING */
+ 0x1, /* gcFEATURE_BIT_NN_ZDP3 */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+ 0x1, /* gcFEATURE_BIT_NN_INT8_SCALE */
+ 0x1, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+ 0x1, /* gcFEATURE_BIT_TF_QUANTIZATION */
+ 0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+ 0x1, /* gcFEATURE_BIT_TP_REAL_INT16 */
+ 0x1, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+ 0x1, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+ 0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+ 0x1, /* gcFEATURE_BIT_TP_REORDER_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+ 0x1, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+ 0x1, /* gcFEATURE_BIT_USC_STAY_LRU */
+ 0x1, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+ 0x1, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+ 0x1, /* gcFEATURE_BIT_INPUT_4BIT */
+ 0x1, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+ 0x1, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+ 0x1, /* gcFEATURE_BIT_OCB_COUNTER */
+ 0x1, /* gcFEATURE_BIT_NN_XYDP0 */
+ 0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+ 0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+ 0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+ 0x0, /* gcFEATURE_BIT_SCALER */
+ 0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+ 0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+ 0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+ 0x1, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+ 0x1, /* gcFEATURE_BIT_NN_SMALLBATCH */
+ 0x1, /* gcFEATURE_BIT_TP_SMALLBATCH */
+ 0x1, /* gcFEATURE_BIT_ZRL_8BIT */
+ 0x1, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+ 0x1, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+ 0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+ 0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
+ 0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+ 0x1, /* gcFEATURE_BIT_VIP_DEC400 */
+ },
+};
+
+static gcsFEATURE_DATABASE*
+gcQueryFeatureDB(
+ gctUINT32 ChipID,
+ gctUINT32 ChipVersion,
+ gctUINT32 ProductID,
+ gctUINT32 EcoID,
+ gctUINT32 CustomerID
+ )
+{
+ gctINT entryNum = sizeof(gChipInfo) / sizeof(gChipInfo[0]);
+ gctINT i;
+
+ /* check formal release entries first */
+ for (i = 0; i < entryNum; ++i)
+ {
+
+ if ((gChipInfo[i].chipID == ChipID)
+ && (gChipInfo[i].chipVersion == ChipVersion)
+ && (gChipInfo[i].productID == ProductID)
+ && (gChipInfo[i].ecoID == EcoID)
+ && (gChipInfo[i].customerID == CustomerID)
+ && (gChipInfo[i].formalRelease)
+ )
+ {
+ return &gChipInfo[i];
+ }
+ }
+
+ /* check informal release entries if we dont find in formal entries */
+ for (i = 0; i < entryNum; ++i)
+ {
+
+ if ((gChipInfo[i].chipID == ChipID)
+ && ((gChipInfo[i].chipVersion & 0xFFF0) == (ChipVersion & 0xFFF0))
+ && (gChipInfo[i].productID == ProductID)
+ && (gChipInfo[i].ecoID == EcoID)
+ && (gChipInfo[i].customerID == CustomerID)
+ && (!gChipInfo[i].formalRelease)
+ )
+ {
+ return &gChipInfo[i];
+ }
+ }
+
+ return gcvNULL;
+}
+#endif /* _gc_feature_database_h_ */
+
+
diff --git a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal.h b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal.h
new file mode 100644
index 000000000000..b2b83c36516a
--- /dev/null
+++ b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal.h
@@ -0,0 +1,2854 @@
+/****************************************************************************
+*
+* The MIT License (MIT)
+*
+* Copyright (c) 2014 - 2018 Vivante 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 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 GPL License (GPL)
+*
+* Copyright (C) 2014 - 2018 Vivante 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.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+*****************************************************************************
+*
+* Note: This software is released under dual MIT and GPL licenses. A
+* recipient may use this file under the terms of either the MIT license or
+* GPL License. If you wish to use only one license not the other, you can
+* indicate your decision by deleting one of the above license notices in your
+* version of this file.
+*
+*****************************************************************************/
+
+
+#ifndef __gc_hal_h_
+#define __gc_hal_h_
+
+#include "gc_hal_rename.h"
+#include "gc_hal_types.h"
+#include "gc_hal_enum.h"
+#include "gc_hal_base.h"
+#include "gc_hal_profiler.h"
+#include "gc_hal_driver.h"
+#if gcdENABLE_3D
+#include "gc_hal_statistics.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/******************************************************************************\
+******************************* Alignment Macros *******************************
+\******************************************************************************/
+
+/* Alignment with a non-power of two value. */
+#define gcmALIGN_NP2(n, align) \
+(\
+ ((n) + (align) - 1) - (((n) + (align) - 1) % (align)) \
+)
+
+/* Alignment with a power of two value. */
+#define gcmALIGN(n, align) \
+(\
+ ((n) + ((align) - 1)) & ~((align) - 1) \
+)
+
+#define gcmALIGN_BASE(n, align) \
+(\
+ ((n) & ~((align) - 1)) \
+)
+
+/******************************************************************************\
+***************************** Element Count Macro *****************************
+\******************************************************************************/
+
+#define gcmSIZEOF(a) \
+(\
+ (gctSIZE_T) (sizeof(a)) \
+)
+
+#define gcmCOUNTOF(a) \
+(\
+ sizeof(a) / sizeof(a[0]) \
+)
+
+/******************************************************************************\
+********************************* Cast Macro **********************************
+\******************************************************************************/
+#define gcmNAME_TO_PTR(na) \
+ gckKERNEL_QueryPointerFromName(kernel, gcmALL_TO_UINT32(na))
+
+#define gcmPTR_TO_NAME(ptr) \
+ gckKERNEL_AllocateNameFromPointer(kernel, ptr)
+
+#define gcmRELEASE_NAME(na) \
+ gckKERNEL_DeleteName(kernel, gcmALL_TO_UINT32(na))
+
+#define gcmALL_TO_UINT32(t) \
+(\
+ (gctUINT32) (gctUINTPTR_T) (t)\
+)
+
+#define gcmPTR_TO_UINT64(p) \
+(\
+ (gctUINT64) (gctUINTPTR_T) (p)\
+)
+
+#define gcmUINT64_TO_PTR(u) \
+(\
+ (gctPOINTER) (gctUINTPTR_T) (u)\
+)
+
+#define gcmUINT64_TO_TYPE(u, t) \
+(\
+ (t) (gctUINTPTR_T) (u)\
+)
+
+/******************************************************************************\
+******************************** Useful Macro *********************************
+\******************************************************************************/
+
+#define gcvINVALID_ADDRESS ~0U
+#define gcvINVALID_VALUE 0xCCCCCCCC
+
+#define gcvINVALID_PHYSICAL_ADDRESS ~0U
+
+#define gcmGET_PRE_ROTATION(rotate) \
+ ((rotate) & (~(gcvSURF_POST_FLIP_X | gcvSURF_POST_FLIP_Y)))
+
+#define gcmGET_POST_ROTATION(rotate) \
+ ((rotate) & (gcvSURF_POST_FLIP_X | gcvSURF_POST_FLIP_Y))
+
+/******************************************************************************\
+******************************** gcsOBJECT Object *******************************
+\******************************************************************************/
+
+/* Type of objects. */
+typedef enum _gceOBJECT_TYPE
+{
+ gcvOBJ_UNKNOWN = 0,
+ gcvOBJ_2D = gcmCC('2','D',' ',' '),
+ gcvOBJ_3D = gcmCC('3','D',' ',' '),
+ gcvOBJ_ATTRIBUTE = gcmCC('A','T','T','R'),
+ gcvOBJ_BRUSHCACHE = gcmCC('B','R','U','$'),
+ gcvOBJ_BRUSHNODE = gcmCC('B','R','U','n'),
+ gcvOBJ_BRUSH = gcmCC('B','R','U','o'),
+ gcvOBJ_BUFFER = gcmCC('B','U','F','R'),
+ gcvOBJ_COMMAND = gcmCC('C','M','D',' '),
+ gcvOBJ_COMMANDBUFFER = gcmCC('C','M','D','B'),
+ gcvOBJ_CONTEXT = gcmCC('C','T','X','T'),
+ gcvOBJ_DEVICE = gcmCC('D','E','V',' '),
+ gcvOBJ_DUMP = gcmCC('D','U','M','P'),
+ gcvOBJ_EVENT = gcmCC('E','V','N','T'),
+ gcvOBJ_FUNCTION = gcmCC('F','U','N','C'),
+ gcvOBJ_HAL = gcmCC('H','A','L',' '),
+ gcvOBJ_HARDWARE = gcmCC('H','A','R','D'),
+ gcvOBJ_HEAP = gcmCC('H','E','A','P'),
+ gcvOBJ_INDEX = gcmCC('I','N','D','X'),
+ gcvOBJ_INTERRUPT = gcmCC('I','N','T','R'),
+ gcvOBJ_KERNEL = gcmCC('K','E','R','N'),
+ gcvOBJ_KERNEL_FUNCTION = gcmCC('K','F','C','N'),
+ gcvOBJ_MEMORYBUFFER = gcmCC('M','E','M','B'),
+ gcvOBJ_MMU = gcmCC('M','M','U',' '),
+ gcvOBJ_OS = gcmCC('O','S',' ',' '),
+ gcvOBJ_OUTPUT = gcmCC('O','U','T','P'),
+ gcvOBJ_PAINT = gcmCC('P','N','T',' '),
+ gcvOBJ_PATH = gcmCC('P','A','T','H'),
+ gcvOBJ_QUEUE = gcmCC('Q','U','E',' '),
+ gcvOBJ_SAMPLER = gcmCC('S','A','M','P'),
+ gcvOBJ_SHADER = gcmCC('S','H','D','R'),
+ gcvOBJ_VIR_SHADER = gcmCC('V','S','D','R'),
+ gcvOBJ_STREAM = gcmCC('S','T','R','M'),
+ gcvOBJ_SURF = gcmCC('S','U','R','F'),
+ gcvOBJ_TEXTURE = gcmCC('T','X','T','R'),
+ gcvOBJ_UNIFORM = gcmCC('U','N','I','F'),
+ gcvOBJ_VARIABLE = gcmCC('V','A','R','I'),
+ gcvOBJ_VERTEX = gcmCC('V','R','T','X'),
+ gcvOBJ_VIDMEM = gcmCC('V','M','E','M'),
+ gcvOBJ_VG = gcmCC('V','G',' ',' '),
+ gcvOBJ_BUFOBJ = gcmCC('B','U','F','O'),
+ gcvOBJ_UNIFORM_BLOCK = gcmCC('U','B','L','K'),
+ gcvOBJ_CL = gcmCC('C','L',' ',' '),
+ gcvOBJ_STORAGE_BLOCK = gcmCC('S','B','L','K'),
+ gcvOBJ_IO_BLOCK = gcmCC('I','O','B','K'),
+}
+gceOBJECT_TYPE;
+
+/* gcsOBJECT object defintinon. */
+typedef struct _gcsOBJECT
+{
+ /* Type of an object. */
+ gceOBJECT_TYPE type;
+}
+gcsOBJECT;
+
+typedef struct _gckHARDWARE * gckHARDWARE;
+
+
+#define gcdMAX_GPU_COUNT gcvCORE_COUNT
+
+#define gcdMAX_SURF_LAYERS 4
+
+#define gcdMAX_DRAW_BUFFERS 8
+
+/*******************************************************************************
+**
+** gcmVERIFY_OBJECT
+**
+** Assert if an object is invalid or is not of the specified type. If the
+** object is invalid or not of the specified type, gcvSTATUS_INVALID_OBJECT
+** will be returned from the current function. In retail mode this macro
+** does nothing.
+**
+** ARGUMENTS:
+**
+** obj Object to test.
+** t Expected type of the object.
+*/
+#if gcmIS_DEBUG(gcdDEBUG_TRACE)
+#define _gcmVERIFY_OBJECT(prefix, obj, t) \
+ if ((obj) == gcvNULL) \
+ { \
+ prefix##TRACE(gcvLEVEL_ERROR, \
+ #prefix "VERIFY_OBJECT failed: NULL"); \
+ prefix##TRACE(gcvLEVEL_ERROR, " expected: %c%c%c%c", \
+ gcmCC_PRINT(t)); \
+ prefix##ASSERT((obj) != gcvNULL); \
+ prefix##FOOTER_ARG("status=%d", gcvSTATUS_INVALID_OBJECT); \
+ return gcvSTATUS_INVALID_OBJECT; \
+ } \
+ else if (((gcsOBJECT*) (obj))->type != t) \
+ { \
+ prefix##TRACE(gcvLEVEL_ERROR, \
+ #prefix "VERIFY_OBJECT failed: %c%c%c%c", \
+ gcmCC_PRINT(((gcsOBJECT*) (obj))->type)); \
+ prefix##TRACE(gcvLEVEL_ERROR, " expected: %c%c%c%c", \
+ gcmCC_PRINT(t)); \
+ prefix##ASSERT(((gcsOBJECT*)(obj))->type == t); \
+ prefix##FOOTER_ARG("status=%d", gcvSTATUS_INVALID_OBJECT); \
+ return gcvSTATUS_INVALID_OBJECT; \
+ }
+
+# define gcmVERIFY_OBJECT(obj, t) _gcmVERIFY_OBJECT(gcm, obj, t)
+# define gcmkVERIFY_OBJECT(obj, t) _gcmVERIFY_OBJECT(gcmk, obj, t)
+#else
+# define gcmVERIFY_OBJECT(obj, t) do {} while (gcvFALSE)
+# define gcmkVERIFY_OBJECT(obj, t) do {} while (gcvFALSE)
+#endif
+
+/******************************************************************************/
+/*VERIFY_OBJECT if special return expected*/
+/******************************************************************************/
+#ifndef EGL_API_ANDROID
+# define _gcmVERIFY_OBJECT_RETURN(prefix, obj, t, retVal) \
+ do \
+ { \
+ if ((obj) == gcvNULL) \
+ { \
+ prefix##PRINT_VERSION(); \
+ prefix##TRACE(gcvLEVEL_ERROR, \
+ #prefix "VERIFY_OBJECT_RETURN failed: NULL"); \
+ prefix##TRACE(gcvLEVEL_ERROR, " expected: %c%c%c%c", \
+ gcmCC_PRINT(t)); \
+ prefix##ASSERT((obj) != gcvNULL); \
+ prefix##FOOTER_ARG("retVal=%d", retVal); \
+ return retVal; \
+ } \
+ else if (((gcsOBJECT*) (obj))->type != t) \
+ { \
+ prefix##PRINT_VERSION(); \
+ prefix##TRACE(gcvLEVEL_ERROR, \
+ #prefix "VERIFY_OBJECT_RETURN failed: %c%c%c%c", \
+ gcmCC_PRINT(((gcsOBJECT*) (obj))->type)); \
+ prefix##TRACE(gcvLEVEL_ERROR, " expected: %c%c%c%c", \
+ gcmCC_PRINT(t)); \
+ prefix##ASSERT(((gcsOBJECT*)(obj))->type == t); \
+ prefix##FOOTER_ARG("retVal=%d", retVal); \
+ return retVal; \
+ } \
+ } \
+ while (gcvFALSE)
+# define gcmVERIFY_OBJECT_RETURN(obj, t, retVal) \
+ _gcmVERIFY_OBJECT_RETURN(gcm, obj, t, retVal)
+# define gcmkVERIFY_OBJECT_RETURN(obj, t, retVal) \
+ _gcmVERIFY_OBJECT_RETURN(gcmk, obj, t, retVal)
+#else
+# define gcmVERIFY_OBJECT_RETURN(obj, t) do {} while (gcvFALSE)
+# define gcmVERIFY_OBJECT_RETURN(obj, t) do {} while (gcvFALSE)
+#endif
+
+typedef struct _gcsContiguousBlock
+{
+ gctUINT32 ptr;
+ gctSIZE_T size;
+}
+gcsContiguousBlock;
+
+
+/******************************************************************************\
+********************************** gckOS Object *********************************
+\******************************************************************************/
+
+/* Construct a new gckOS object. */
+gceSTATUS
+gckOS_Construct(
+ IN gctPOINTER Context,
+ OUT gckOS * Os
+ );
+
+/* Destroy an gckOS object. */
+gceSTATUS
+gckOS_Destroy(
+ IN gckOS Os
+ );
+
+/* Query the video memory. */
+gceSTATUS
+gckOS_QueryVideoMemory(
+ IN gckOS Os,
+ OUT gctPHYS_ADDR * InternalAddress,
+ OUT gctSIZE_T * InternalSize,
+ OUT gctPHYS_ADDR * ExternalAddress,
+ OUT gctSIZE_T * ExternalSize,
+ OUT gctPHYS_ADDR * ContiguousAddress,
+ OUT gctSIZE_T * ContiguousSize
+ );
+
+/* Allocate memory from the heap. */
+gceSTATUS
+gckOS_Allocate(
+ IN gckOS Os,
+ IN gctSIZE_T Bytes,
+ OUT gctPOINTER * Memory
+ );
+
+/* Free allocated memory. */
+gceSTATUS
+gckOS_Free(
+ IN gckOS Os,
+ IN gctPOINTER Memory
+ );
+
+/* Wrapper for allocation memory.. */
+gceSTATUS
+gckOS_AllocateMemory(
+ IN gckOS Os,
+ IN gctSIZE_T Bytes,
+ OUT gctPOINTER * Memory
+ );
+
+/* Wrapper for freeing memory. */
+gceSTATUS
+gckOS_FreeMemory(
+ IN gckOS Os,
+ IN gctPOINTER Memory
+ );
+
+/* Allocate paged memory. */
+gceSTATUS
+gckOS_AllocatePagedMemory(
+ IN gckOS Os,
+ IN gctSIZE_T Bytes,
+ OUT gctPHYS_ADDR * Physical
+ );
+
+/* Allocate paged memory. */
+gceSTATUS
+gckOS_AllocatePagedMemoryEx(
+ IN gckOS Os,
+ IN gctUINT32 Flag,
+ IN gctSIZE_T Bytes,
+ OUT gctUINT32 * Gid,
+ OUT gctPHYS_ADDR * Physical
+ );
+
+/* Lock pages. */
+gceSTATUS
+gckOS_LockPages(
+ IN gckOS Os,
+ IN gctPHYS_ADDR Physical,
+ IN gctSIZE_T Bytes,
+ IN gctBOOL Cacheable,
+ OUT gctPOINTER * Logical,
+ OUT gctSIZE_T * PageCount
+ );
+
+/* Map pages. */
+gceSTATUS
+gckOS_MapPages(
+ IN gckOS Os,
+ IN gctPHYS_ADDR Physical,
+ IN gctSIZE_T PageCount,
+ IN gctPOINTER PageTable
+ );
+
+/* Map pages. */
+gceSTATUS
+gckOS_MapPagesEx(
+ IN gckOS Os,
+ IN gceCORE Core,
+ IN gctPHYS_ADDR Physical,
+ IN gctSIZE_T PageCount,
+ IN gctUINT32 Address,
+ IN gctPOINTER PageTable,
+ IN gctBOOL Writable,
+ IN gceSURF_TYPE Type
+ );
+
+gceSTATUS
+gckOS_UnmapPages(
+ IN gckOS Os,
+ IN gctSIZE_T PageCount,
+ IN gctUINT32 Address
+ );
+
+/* Unlock pages. */
+gceSTATUS
+gckOS_UnlockPages(
+ IN gckOS Os,
+ IN gctPHYS_ADDR Physical,
+ IN gctSIZE_T Bytes,
+ IN gctPOINTER Logical
+ );
+
+/* Free paged memory. */
+gceSTATUS
+gckOS_FreePagedMemory(
+ IN gckOS Os,
+ IN gctPHYS_ADDR Physical,
+ IN gctSIZE_T Bytes
+ );
+
+/* Allocate non-paged memory. */
+gceSTATUS
+gckOS_AllocateNonPagedMemory(
+ IN gckOS Os,
+ IN gctBOOL InUserSpace,
+ IN gctUINT32 Flag,
+ IN OUT gctSIZE_T * Bytes,
+ OUT gctPHYS_ADDR * Physical,
+ OUT gctPOINTER * Logical
+ );
+
+/* Free non-paged memory. */
+gceSTATUS
+gckOS_FreeNonPagedMemory(
+ IN gckOS Os,
+ IN gctSIZE_T Bytes,
+ IN gctPHYS_ADDR Physical,
+ IN gctPOINTER Logical
+ );
+
+/* Allocate contiguous memory. */
+gceSTATUS
+gckOS_AllocateContiguous(
+ IN gckOS Os,
+ IN gctBOOL InUserSpace,
+ IN OUT gctSIZE_T * Bytes,
+ OUT gctPHYS_ADDR * Physical,
+ OUT gctPOINTER * Logical
+ );
+
+/* Free contiguous memory. */
+gceSTATUS
+gckOS_FreeContiguous(
+ IN gckOS Os,
+ IN gctPHYS_ADDR Physical,
+ IN gctPOINTER Logical,
+ IN gctSIZE_T Bytes
+ );
+
+/* Get the number fo bytes per page. */
+gceSTATUS
+gckOS_GetPageSize(
+ IN gckOS Os,
+ OUT gctSIZE_T * PageSize
+ );
+
+/* Get the physical address of a corresponding logical address. */
+gceSTATUS
+gckOS_GetPhysicalAddress(
+ IN gckOS Os,
+ IN gctPOINTER Logical,
+ OUT gctPHYS_ADDR_T * Address
+ );
+
+/* Get the physical address of a corresponding user logical address. */
+gceSTATUS
+gckOS_UserLogicalToPhysical(
+ IN gckOS Os,
+ IN gctPOINTER Logical,
+ OUT gctPHYS_ADDR_T * Address
+ );
+
+
+/* Map a physical address into kernel space.*/
+gceSTATUS
+gckOS_MapPhysicalToKernelSpace(
+ IN gckOS Os,
+ IN gckVIDMEM_NODE NodeObject,
+ OUT gctPOINTER * Logical
+ );
+
+/* Map physical memory. */
+gceSTATUS
+gckOS_MapPhysical(
+ IN gckOS Os,
+ IN gctUINT32 Physical,
+ IN gctSIZE_T Bytes,
+ OUT gctPOINTER * Logical
+ );
+
+/* Unmap previously mapped physical memory. */
+gceSTATUS
+gckOS_UnmapPhysical(
+ IN gckOS Os,
+ IN gctPOINTER Logical,
+ IN gctSIZE_T Bytes
+ );
+
+/* Get real physical address from descriptor. */
+gceSTATUS
+gckOS_PhysicalToPhysicalAddress(
+ IN gckOS Os,
+ IN gctPOINTER Physical,
+ IN gctUINT32 Offset,
+ OUT gctPHYS_ADDR_T * PhysicalAddress
+ );
+
+/* Read data from a hardware register. */
+gceSTATUS
+gckOS_ReadRegister(
+ IN gckOS Os,
+ IN gctUINT32 Address,
+ OUT gctUINT32 * Data
+ );
+
+/* Read data from a hardware register. */
+gceSTATUS
+gckOS_ReadRegisterEx(
+ IN gckOS Os,
+ IN gceCORE Core,
+ IN gctUINT32 Address,
+ OUT gctUINT32 * Data
+ );
+
+/* Write data to a hardware register. */
+gceSTATUS
+gckOS_WriteRegister(
+ IN gckOS Os,
+ IN gctUINT32 Address,
+ IN gctUINT32 Data
+ );
+
+/* Write data to a hardware register. */
+gceSTATUS
+gckOS_WriteRegisterEx(
+ IN gckOS Os,
+ IN gceCORE Core,
+ IN gctUINT32 Address,
+ IN gctUINT32 Data
+ );
+
+#ifdef __QNXNTO__
+static gcmINLINE gceSTATUS
+gckOS_WriteMemory(
+ IN gckOS Os,
+ IN gctPOINTER Address,
+ IN gctUINT32 Data
+ )
+{
+ /* Write memory. */
+ *(gctUINT32 *)Address = Data;
+ return gcvSTATUS_OK;
+}
+
+#else
+/* Write data to a 32-bit memory location. */
+gceSTATUS
+gckOS_WriteMemory(
+ IN gckOS Os,
+ IN gctPOINTER Address,
+ IN gctUINT32 Data
+ );
+#endif
+
+/* Map physical memory into the process space. */
+gceSTATUS
+gckOS_MapMemory(
+ IN gckOS Os,
+ IN gctPHYS_ADDR Physical,
+ IN gctSIZE_T Bytes,
+ OUT gctPOINTER * Logical
+ );
+
+/* Unmap physical memory from the specified process space. */
+gceSTATUS
+gckOS_UnmapMemoryEx(
+ IN gckOS Os,
+ IN gctPHYS_ADDR Physical,
+ IN gctSIZE_T Bytes,
+ IN gctPOINTER Logical,
+ IN gctUINT32 PID
+ );
+
+/* Unmap physical memory from the process space. */
+gceSTATUS
+gckOS_UnmapMemory(
+ IN gckOS Os,
+ IN gctPHYS_ADDR Physical,
+ IN gctSIZE_T Bytes,
+ IN gctPOINTER Logical
+ );
+
+/* Unmap user logical memory out of physical memory.
+ * This function is only supported in Linux currently.
+ */
+gceSTATUS
+gckOS_UnmapUserLogical(
+ IN gckOS Os,
+ IN gctPHYS_ADDR Physical,
+ IN gctSIZE_T Bytes,
+ IN gctPOINTER Logical
+ );
+
+/* Delete a mutex. */
+gceSTATUS
+gckOS_DeleteMutex(
+ IN gckOS Os,
+ IN gctPOINTER Mutex
+ );
+
+/* Acquire a mutex. */
+gceSTATUS
+gckOS_AcquireMutex(
+ IN gckOS Os,
+ IN gctPOINTER Mutex,
+ IN gctUINT32 Timeout
+ );
+
+/* Release a mutex. */
+gceSTATUS
+gckOS_ReleaseMutex(
+ IN gckOS Os,
+ IN gctPOINTER Mutex
+ );
+
+/* Atomically exchange a pair of 32-bit values. */
+gceSTATUS
+gckOS_AtomicExchange(
+ IN gckOS Os,
+ IN OUT gctUINT32_PTR Target,
+ IN gctUINT32 NewValue,
+ OUT gctUINT32_PTR OldValue
+ );
+
+/* Atomically exchange a pair of pointers. */
+gceSTATUS
+gckOS_AtomicExchangePtr(
+ IN gckOS Os,
+ IN OUT gctPOINTER * Target,
+ IN gctPOINTER NewValue,
+ OUT gctPOINTER * OldValue
+ );
+
+gceSTATUS
+gckOS_AtomSetMask(
+ IN gctPOINTER Atom,
+ IN gctUINT32 Mask
+ );
+
+gceSTATUS
+gckOS_AtomClearMask(
+ IN gctPOINTER Atom,
+ IN gctUINT32 Mask
+ );
+
+gceSTATUS
+gckOS_DumpCallStack(
+ IN gckOS Os
+ );
+
+gceSTATUS
+gckOS_GetProcessNameByPid(
+ IN gctINT Pid,
+ IN gctSIZE_T Length,
+ OUT gctUINT8_PTR String
+ );
+
+/*******************************************************************************
+**
+** gckOS_AtomConstruct
+**
+** Create an atom.
+**
+** INPUT:
+**
+** gckOS Os
+** Pointer to a gckOS object.
+**
+** OUTPUT:
+**
+** gctPOINTER * Atom
+** Pointer to a variable receiving the constructed atom.
+*/
+gceSTATUS
+gckOS_AtomConstruct(
+ IN gckOS Os,
+ OUT gctPOINTER * Atom
+ );
+
+/*******************************************************************************
+**
+** gckOS_AtomDestroy
+**
+** Destroy an atom.
+**
+** INPUT:
+**
+** gckOS Os
+** Pointer to a gckOS object.
+**
+** gctPOINTER Atom
+** Pointer to the atom to destroy.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckOS_AtomDestroy(
+ IN gckOS Os,
+ OUT gctPOINTER Atom
+ );
+
+/*******************************************************************************
+**
+** gckOS_AtomGet
+**
+** Get the 32-bit value protected by an atom.
+**
+** INPUT:
+**
+** gckOS Os
+** Pointer to a gckOS object.
+**
+** gctPOINTER Atom
+** Pointer to the atom.
+**
+** OUTPUT:
+**
+** gctINT32_PTR Value
+** Pointer to a variable the receives the value of the atom.
+*/
+gceSTATUS
+gckOS_AtomGet(
+ IN gckOS Os,
+ IN gctPOINTER Atom,
+ OUT gctINT32_PTR Value
+ );
+
+/*******************************************************************************
+**
+** gckOS_AtomSet
+**
+** Set the 32-bit value protected by an atom.
+**
+** INPUT:
+**
+** gckOS Os
+** Pointer to a gckOS object.
+**
+** gctPOINTER Atom
+** Pointer to the atom.
+**
+** gctINT32 Value
+** The value of the atom.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckOS_AtomSet(
+ IN gckOS Os,
+ IN gctPOINTER Atom,
+ IN gctINT32 Value
+ );
+
+/*******************************************************************************
+**
+** gckOS_AtomIncrement
+**
+** Atomically increment the 32-bit integer value inside an atom.
+**
+** INPUT:
+**
+** gckOS Os
+** Pointer to a gckOS object.
+**
+** gctPOINTER Atom
+** Pointer to the atom.
+**
+** OUTPUT:
+**
+** gctINT32_PTR Value
+** Pointer to a variable the receives the original value of the atom.
+*/
+gceSTATUS
+gckOS_AtomIncrement(
+ IN gckOS Os,
+ IN gctPOINTER Atom,
+ OUT gctINT32_PTR Value
+ );
+
+/*******************************************************************************
+**
+** gckOS_AtomDecrement
+**
+** Atomically decrement the 32-bit integer value inside an atom.
+**
+** INPUT:
+**
+** gckOS Os
+** Pointer to a gckOS object.
+**
+** gctPOINTER Atom
+** Pointer to the atom.
+**
+** OUTPUT:
+**
+** gctINT32_PTR Value
+** Pointer to a variable the receives the original value of the atom.
+*/
+gceSTATUS
+gckOS_AtomDecrement(
+ IN gckOS Os,
+ IN gctPOINTER Atom,
+ OUT gctINT32_PTR Value
+ );
+
+/* Delay a number of milliseconds. */
+gceSTATUS
+gckOS_Delay(
+ IN gckOS Os,
+ IN gctUINT32 Delay
+ );
+
+/* Get time in milliseconds. */
+gceSTATUS
+gckOS_GetTicks(
+ OUT gctUINT32_PTR Time
+ );
+
+/* Compare time value. */
+gceSTATUS
+gckOS_TicksAfter(
+ IN gctUINT32 Time1,
+ IN gctUINT32 Time2,
+ OUT gctBOOL_PTR IsAfter
+ );
+
+/* Get time in microseconds. */
+gceSTATUS
+gckOS_GetTime(
+ OUT gctUINT64_PTR Time
+ );
+
+/* Memory barrier. */
+gceSTATUS
+gckOS_MemoryBarrier(
+ IN gckOS Os,
+ IN gctPOINTER Address
+ );
+
+/* Map user pointer. */
+gceSTATUS
+gckOS_MapUserPointer(
+ IN gckOS Os,
+ IN gctPOINTER Pointer,
+ IN gctSIZE_T Size,
+ OUT gctPOINTER * KernelPointer
+ );
+
+/* Unmap user pointer. */
+gceSTATUS
+gckOS_UnmapUserPointer(
+ IN gckOS Os,
+ IN gctPOINTER Pointer,
+ IN gctSIZE_T Size,
+ IN gctPOINTER KernelPointer
+ );
+
+/*******************************************************************************
+**
+** gckOS_QueryNeedCopy
+**
+** Query whether the memory can be accessed or mapped directly or it has to be
+** copied.
+**
+** INPUT:
+**
+** gckOS Os
+** Pointer to an gckOS object.
+**
+** gctUINT32 ProcessID
+** Process ID of the current process.
+**
+** OUTPUT:
+**
+** gctBOOL_PTR NeedCopy
+** Pointer to a boolean receiving gcvTRUE if the memory needs a copy or
+** gcvFALSE if the memory can be accessed or mapped dircetly.
+*/
+gceSTATUS
+gckOS_QueryNeedCopy(
+ IN gckOS Os,
+ IN gctUINT32 ProcessID,
+ OUT gctBOOL_PTR NeedCopy
+ );
+
+/*******************************************************************************
+**
+** gckOS_CopyFromUserData
+**
+** Copy data from user to kernel memory.
+**
+** INPUT:
+**
+** gckOS Os
+** Pointer to an gckOS object.
+**
+** gctPOINTER KernelPointer
+** Pointer to kernel memory.
+**
+** gctPOINTER Pointer
+** Pointer to user memory.
+**
+** gctSIZE_T Size
+** Number of bytes to copy.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckOS_CopyFromUserData(
+ IN gckOS Os,
+ IN gctPOINTER KernelPointer,
+ IN gctPOINTER Pointer,
+ IN gctSIZE_T Size
+ );
+
+/*******************************************************************************
+**
+** gckOS_CopyToUserData
+**
+** Copy data from kernel to user memory.
+**
+** INPUT:
+**
+** gckOS Os
+** Pointer to an gckOS object.
+**
+** gctPOINTER KernelPointer
+** Pointer to kernel memory.
+**
+** gctPOINTER Pointer
+** Pointer to user memory.
+**
+** gctSIZE_T Size
+** Number of bytes to copy.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckOS_CopyToUserData(
+ IN gckOS Os,
+ IN gctPOINTER KernelPointer,
+ IN gctPOINTER Pointer,
+ IN gctSIZE_T Size
+ );
+
+gceSTATUS
+gckOS_SuspendInterrupt(
+ IN gckOS Os
+ );
+
+gceSTATUS
+gckOS_SuspendInterruptEx(
+ IN gckOS Os,
+ IN gceCORE Core
+ );
+
+gceSTATUS
+gckOS_ResumeInterrupt(
+ IN gckOS Os
+ );
+
+gceSTATUS
+gckOS_ResumeInterruptEx(
+ IN gckOS Os,
+ IN gceCORE Core
+ );
+
+/* Get the base address for the physical memory. */
+gceSTATUS
+gckOS_GetBaseAddress(
+ IN gckOS Os,
+ OUT gctUINT32_PTR BaseAddress
+ );
+
+/* Perform a memory copy. */
+gceSTATUS
+gckOS_MemCopy(
+ IN gctPOINTER Destination,
+ IN gctCONST_POINTER Source,
+ IN gctSIZE_T Bytes
+ );
+
+/* Zero memory. */
+gceSTATUS
+gckOS_ZeroMemory(
+ IN gctPOINTER Memory,
+ IN gctSIZE_T Bytes
+ );
+
+/* Device I/O control to the kernel HAL layer. */
+gceSTATUS
+gckOS_DeviceControl(
+ IN gckOS Os,
+ IN gctBOOL FromUser,
+ IN gctUINT32 IoControlCode,
+ IN gctPOINTER InputBuffer,
+ IN gctSIZE_T InputBufferSize,
+ OUT gctPOINTER OutputBuffer,
+ IN gctSIZE_T OutputBufferSize
+ );
+
+/*******************************************************************************
+**
+** gckOS_GetProcessID
+**
+** Get current process ID.
+**
+** INPUT:
+**
+** Nothing.
+**
+** OUTPUT:
+**
+** gctUINT32_PTR ProcessID
+** Pointer to the variable that receives the process ID.
+*/
+gceSTATUS
+gckOS_GetProcessID(
+ OUT gctUINT32_PTR ProcessID
+ );
+
+gceSTATUS
+gckOS_GetCurrentProcessID(
+ OUT gctUINT32_PTR ProcessID
+ );
+
+/*******************************************************************************
+**
+** gckOS_GetThreadID
+**
+** Get current thread ID.
+**
+** INPUT:
+**
+** Nothing.
+**
+** OUTPUT:
+**
+** gctUINT32_PTR ThreadID
+** Pointer to the variable that receives the thread ID.
+*/
+gceSTATUS
+gckOS_GetThreadID(
+ OUT gctUINT32_PTR ThreadID
+ );
+
+/******************************************************************************\
+********************************** Signal Object *********************************
+\******************************************************************************/
+
+/* Create a signal. */
+gceSTATUS
+gckOS_CreateSignal(
+ IN gckOS Os,
+ IN gctBOOL ManualReset,
+ OUT gctSIGNAL * Signal
+ );
+
+/* Destroy a signal. */
+gceSTATUS
+gckOS_DestroySignal(
+ IN gckOS Os,
+ IN gctSIGNAL Signal
+ );
+
+/* Signal a signal. */
+gceSTATUS
+gckOS_Signal(
+ IN gckOS Os,
+ IN gctSIGNAL Signal,
+ IN gctBOOL State
+ );
+
+/* Wait for a signal. */
+gceSTATUS
+gckOS_WaitSignal(
+ IN gckOS Os,
+ IN gctSIGNAL Signal,
+ IN gctBOOL Interruptable,
+ IN gctUINT32 Wait
+ );
+
+#ifdef __QNXNTO__
+gceSTATUS
+gckOS_SignalPulse(
+ IN gckOS Os,
+ IN gctSIGNAL Signal
+ );
+
+gceSTATUS
+gckOS_SignalPending(
+ IN gckOS Os,
+ IN gctSIGNAL Signal
+ );
+#endif
+
+/* Map a user signal to the kernel space. */
+gceSTATUS
+gckOS_MapSignal(
+ IN gckOS Os,
+ IN gctSIGNAL Signal,
+ IN gctHANDLE Process,
+ OUT gctSIGNAL * MappedSignal
+ );
+
+/* Unmap a user signal */
+gceSTATUS
+gckOS_UnmapSignal(
+ IN gckOS Os,
+ IN gctSIGNAL Signal
+ );
+
+/* Map user memory. */
+gceSTATUS
+gckOS_MapUserMemory(
+ IN gckOS Os,
+ IN gceCORE Core,
+ IN gctPOINTER Memory,
+ IN gctUINT32 Physical,
+ IN gctSIZE_T Size,
+ OUT gctPOINTER * Info,
+ OUT gctUINT32_PTR Address
+ );
+
+/* Unmap user memory. */
+gceSTATUS
+gckOS_UnmapUserMemory(
+ IN gckOS Os,
+ IN gceCORE Core,
+ IN gctPOINTER Memory,
+ IN gctSIZE_T Size,
+ IN gctPOINTER Info,
+ IN gctUINT32 Address
+ );
+
+/* Get scatter-gather table from memory. */
+gceSTATUS
+gckOS_MemoryGetSGT(
+ IN gckOS Os,
+ IN gctPHYS_ADDR Physical,
+ IN gctSIZE_T Offset,
+ IN gctSIZE_T Bytes,
+ OUT gctPOINTER *SGT
+ );
+
+/* Map a page range of memory to user space. */
+gceSTATUS
+gckOS_MemoryMmap(
+ IN gckOS Os,
+ IN gctPHYS_ADDR Physical,
+ IN gctSIZE_T skipPages,
+ IN gctSIZE_T numPages,
+ INOUT gctPOINTER Vma
+ );
+
+/* Wrap a user memory to gctPHYS_ADDR. */
+gceSTATUS
+gckOS_WrapMemory(
+ IN gckOS Os,
+ IN gcsUSER_MEMORY_DESC_PTR Desc,
+ OUT gctSIZE_T *Bytes,
+ OUT gctPHYS_ADDR * Physical,
+ OUT gctBOOL *Contiguous
+ );
+
+gceSTATUS
+gckOS_GetPolicyID(
+ IN gckOS Os,
+ IN gceSURF_TYPE Type,
+ OUT gctUINT32_PTR PolicyID,
+ OUT gctUINT32_PTR AXIConfig
+ );
+
+/******************************************************************************\
+************************** Android Native Fence Sync ***************************
+\******************************************************************************/
+gceSTATUS
+gckOS_CreateSyncTimeline(
+ IN gckOS Os,
+ IN gceCORE Core,
+ OUT gctHANDLE * Timeline
+ );
+
+gceSTATUS
+gckOS_DestroySyncTimeline(
+ IN gckOS Os,
+ IN gctHANDLE Timeline
+ );
+
+gceSTATUS
+gckOS_CreateNativeFence(
+ IN gckOS Os,
+ IN gctHANDLE Timeline,
+ IN gctSIGNAL Signal,
+ OUT gctINT * FenceFD
+ );
+
+gceSTATUS
+gckOS_WaitNativeFence(
+ IN gckOS Os,
+ IN gctHANDLE Timeline,
+ IN gctINT FenceFD,
+ IN gctUINT32 Timeout
+ );
+
+#if !USE_NEW_LINUX_SIGNAL
+/* Create signal to be used in the user space. */
+gceSTATUS
+gckOS_CreateUserSignal(
+ IN gckOS Os,
+ IN gctBOOL ManualReset,
+ OUT gctINT * SignalID
+ );
+
+/* Destroy signal used in the user space. */
+gceSTATUS
+gckOS_DestroyUserSignal(
+ IN gckOS Os,
+ IN gctINT SignalID
+ );
+
+/* Wait for signal used in the user space. */
+gceSTATUS
+gckOS_WaitUserSignal(
+ IN gckOS Os,
+ IN gctINT SignalID,
+ IN gctUINT32 Wait
+ );
+
+/* Signal a signal used in the user space. */
+gceSTATUS
+gckOS_SignalUserSignal(
+ IN gckOS Os,
+ IN gctINT SignalID,
+ IN gctBOOL State
+ );
+#endif /* USE_NEW_LINUX_SIGNAL */
+
+/* Set a signal owned by a process. */
+#if defined(__QNXNTO__)
+gceSTATUS
+gckOS_UserSignal(
+ IN gckOS Os,
+ IN gctSIGNAL Signal,
+ IN gctINT Recvid,
+ IN gctINT Coid
+ );
+#else
+gceSTATUS
+gckOS_UserSignal(
+ IN gckOS Os,
+ IN gctSIGNAL Signal,
+ IN gctHANDLE Process
+ );
+#endif
+
+/******************************************************************************\
+** Cache Support
+*/
+
+gceSTATUS
+gckOS_CacheClean(
+ gckOS Os,
+ gctUINT32 ProcessID,
+ gctPHYS_ADDR Handle,
+ gctSIZE_T Offset,
+ gctPOINTER Logical,
+ gctSIZE_T Bytes
+ );
+
+gceSTATUS
+gckOS_CacheFlush(
+ gckOS Os,
+ gctUINT32 ProcessID,
+ gctPHYS_ADDR Handle,
+ gctSIZE_T Offset,
+ gctPOINTER Logical,
+ gctSIZE_T Bytes
+ );
+
+gceSTATUS
+gckOS_CacheInvalidate(
+ gckOS Os,
+ gctUINT32 ProcessID,
+ gctPHYS_ADDR Handle,
+ gctSIZE_T Offset,
+ gctPOINTER Logical,
+ gctSIZE_T Bytes
+ );
+
+gceSTATUS
+gckOS_CPUPhysicalToGPUPhysical(
+ IN gckOS Os,
+ IN gctPHYS_ADDR_T CPUPhysical,
+ IN gctPHYS_ADDR_T * GPUPhysical
+ );
+
+gceSTATUS
+gckOS_GPUPhysicalToCPUPhysical(
+ IN gckOS Os,
+ IN gctUINT32 GPUPhysical,
+ IN gctPHYS_ADDR_T * CPUPhysical
+ );
+
+gceSTATUS
+gckOS_QueryOption(
+ IN gckOS Os,
+ IN gctCONST_STRING Option,
+ OUT gctUINT32 * Value
+ );
+
+/******************************************************************************\
+** Debug Support
+*/
+
+void
+gckOS_SetDebugLevel(
+ IN gctUINT32 Level
+ );
+
+void
+gckOS_SetDebugZone(
+ IN gctUINT32 Zone
+ );
+
+void
+gckOS_SetDebugLevelZone(
+ IN gctUINT32 Level,
+ IN gctUINT32 Zone
+ );
+
+void
+gckOS_SetDebugZones(
+ IN gctUINT32 Zones,
+ IN gctBOOL Enable
+ );
+
+void
+gckOS_SetDebugFile(
+ IN gctCONST_STRING FileName
+ );
+
+/*******************************************************************************
+** Broadcast interface.
+*/
+
+typedef enum _gceBROADCAST
+{
+ /* GPU might be idle. */
+ gcvBROADCAST_GPU_IDLE,
+
+ /* A commit is going to happen. */
+ gcvBROADCAST_GPU_COMMIT,
+
+ /* GPU seems to be stuck. */
+ gcvBROADCAST_GPU_STUCK,
+
+ /* First process gets attached. */
+ gcvBROADCAST_FIRST_PROCESS,
+
+ /* Last process gets detached. */
+ gcvBROADCAST_LAST_PROCESS,
+
+ /* AXI bus error. */
+ gcvBROADCAST_AXI_BUS_ERROR,
+
+ /* Out of memory. */
+ gcvBROADCAST_OUT_OF_MEMORY,
+}
+gceBROADCAST;
+
+gceSTATUS
+gckOS_Broadcast(
+ IN gckOS Os,
+ IN gckHARDWARE Hardware,
+ IN gceBROADCAST Reason
+ );
+
+gceSTATUS
+gckOS_BroadcastHurry(
+ IN gckOS Os,
+ IN gckHARDWARE Hardware,
+ IN gctUINT Urgency
+ );
+
+gceSTATUS
+gckOS_BroadcastCalibrateSpeed(
+ IN gckOS Os,
+ IN gckHARDWARE Hardware,
+ IN gctUINT Idle,
+ IN gctUINT Time
+ );
+
+/*******************************************************************************
+**
+** gckOS_SetGPUPower
+**
+** Set the power of the GPU on or off.
+**
+** INPUT:
+**
+** gckOS Os
+** Pointer to a gckOS object.
+**
+** gceCORE Core
+** GPU whose power is set.
+**
+** gctBOOL Clock
+** gcvTRUE to turn on the clock, or gcvFALSE to turn off the clock.
+**
+** gctBOOL Power
+** gcvTRUE to turn on the power, or gcvFALSE to turn off the power.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckOS_SetGPUPower(
+ IN gckOS Os,
+ IN gceCORE Core,
+ IN gctBOOL Clock,
+ IN gctBOOL Power
+ );
+
+gceSTATUS
+gckOS_ResetGPU(
+ IN gckOS Os,
+ IN gceCORE Core
+ );
+
+gceSTATUS
+gckOS_PrepareGPUFrequency(
+ IN gckOS Os,
+ IN gceCORE Core
+ );
+
+gceSTATUS
+gckOS_FinishGPUFrequency(
+ IN gckOS Os,
+ IN gceCORE Core
+ );
+
+gceSTATUS
+gckOS_QueryGPUFrequency(
+ IN gckOS Os,
+ IN gceCORE Core,
+ OUT gctUINT32 * Frequency,
+ OUT gctUINT8 * Scale
+ );
+
+gceSTATUS
+gckOS_SetGPUFrequency(
+ IN gckOS Os,
+ IN gceCORE Core,
+ IN gctUINT8 Scale
+ );
+
+/*******************************************************************************
+** Semaphores.
+*/
+
+/* Create a new semaphore. */
+gceSTATUS
+gckOS_CreateSemaphore(
+ IN gckOS Os,
+ OUT gctPOINTER * Semaphore
+ );
+
+#if gcdENABLE_VG
+gceSTATUS
+gckOS_CreateSemaphoreVG(
+ IN gckOS Os,
+ OUT gctPOINTER * Semaphore
+ );
+#endif
+
+/* Delete a semahore. */
+gceSTATUS
+gckOS_DestroySemaphore(
+ IN gckOS Os,
+ IN gctPOINTER Semaphore
+ );
+
+/* Acquire a semahore. */
+gceSTATUS
+gckOS_AcquireSemaphore(
+ IN gckOS Os,
+ IN gctPOINTER Semaphore
+ );
+
+/* Try to acquire a semahore. */
+gceSTATUS
+gckOS_TryAcquireSemaphore(
+ IN gckOS Os,
+ IN gctPOINTER Semaphore
+ );
+
+/* Release a semahore. */
+gceSTATUS
+gckOS_ReleaseSemaphore(
+ IN gckOS Os,
+ IN gctPOINTER Semaphore
+ );
+
+/*******************************************************************************
+** Timer API.
+*/
+
+typedef void (*gctTIMERFUNCTION)(gctPOINTER);
+
+/* Create a timer. */
+gceSTATUS
+gckOS_CreateTimer(
+ IN gckOS Os,
+ IN gctTIMERFUNCTION Function,
+ IN gctPOINTER Data,
+ OUT gctPOINTER * Timer
+ );
+
+/* Destory a timer. */
+gceSTATUS
+gckOS_DestroyTimer(
+ IN gckOS Os,
+ IN gctPOINTER Timer
+ );
+
+/* Start a timer. */
+gceSTATUS
+gckOS_StartTimer(
+ IN gckOS Os,
+ IN gctPOINTER Timer,
+ IN gctUINT32 Delay
+ );
+
+/* Stop a timer. */
+gceSTATUS
+gckOS_StopTimer(
+ IN gckOS Os,
+ IN gctPOINTER Timer
+ );
+
+/******************************************************************************\
+********************************* gckHEAP Object ********************************
+\******************************************************************************/
+
+typedef struct _gckHEAP * gckHEAP;
+
+/* Construct a new gckHEAP object. */
+gceSTATUS
+gckHEAP_Construct(
+ IN gckOS Os,
+ IN gctSIZE_T AllocationSize,
+ OUT gckHEAP * Heap
+ );
+
+/* Destroy an gckHEAP object. */
+gceSTATUS
+gckHEAP_Destroy(
+ IN gckHEAP Heap
+ );
+
+/* Allocate memory. */
+gceSTATUS
+gckHEAP_Allocate(
+ IN gckHEAP Heap,
+ IN gctSIZE_T Bytes,
+ OUT gctPOINTER * Node
+ );
+
+/* Free memory. */
+gceSTATUS
+gckHEAP_Free(
+ IN gckHEAP Heap,
+ IN gctPOINTER Node
+ );
+
+/* Profile the heap. */
+gceSTATUS
+gckHEAP_ProfileStart(
+ IN gckHEAP Heap
+ );
+
+gceSTATUS
+gckHEAP_ProfileEnd(
+ IN gckHEAP Heap,
+ IN gctCONST_STRING Title
+ );
+
+
+/******************************************************************************\
+******************************** gckVIDMEM Object ******************************
+\******************************************************************************/
+
+typedef struct _gckVIDMEM * gckVIDMEM;
+typedef struct _gckKERNEL * gckKERNEL;
+typedef struct _gckDB * gckDB;
+typedef struct _gckDVFS * gckDVFS;
+typedef struct _gcsASYNC_COMMAND * gckASYNC_COMMAND;
+typedef struct _gckMMU * gckMMU;
+typedef struct _gcsDEVICE * gckDEVICE;
+
+/* Construct a new gckVIDMEM object. */
+gceSTATUS
+gckVIDMEM_Construct(
+ IN gckOS Os,
+ IN gctUINT32 BaseAddress,
+ IN gctSIZE_T Bytes,
+ IN gctSIZE_T Threshold,
+ IN gctSIZE_T Banking,
+ OUT gckVIDMEM * Memory
+ );
+
+/* Destroy an gckVDIMEM object. */
+gceSTATUS
+gckVIDMEM_Destroy(
+ IN gckVIDMEM Memory
+ );
+
+/* Allocate linear memory. */
+gceSTATUS
+gckVIDMEM_AllocateLinear(
+ IN gckKERNEL Kernel,
+ IN gckVIDMEM Memory,
+ IN gctSIZE_T Bytes,
+ IN gctUINT32 Alignment,
+ IN gceSURF_TYPE Type,
+ IN gctBOOL Specified,
+ OUT gcuVIDMEM_NODE_PTR * Node
+ );
+
+/* Free memory. */
+gceSTATUS
+gckVIDMEM_Free(
+ IN gckKERNEL Kernel,
+ IN gcuVIDMEM_NODE_PTR Node
+ );
+
+/* Lock memory. */
+gceSTATUS
+gckVIDMEM_Lock(
+ IN gckKERNEL Kernel,
+ IN gckVIDMEM_NODE Node,
+ IN gctBOOL Cacheable,
+ OUT gctUINT32 * Address,
+ OUT gctUINT32 * Gid,
+ OUT gctUINT64 * PhysicalAddress
+ );
+
+/* Unlock memory. */
+gceSTATUS
+gckVIDMEM_Unlock(
+ IN gckKERNEL Kernel,
+ IN gckVIDMEM_NODE Node,
+ IN gceSURF_TYPE Type,
+ IN OUT gctBOOL * Asynchroneous
+ );
+
+/* Construct a gcuVIDMEM_NODE union for virtual memory. */
+gceSTATUS
+gckVIDMEM_ConstructVirtual(
+ IN gckKERNEL Kernel,
+ IN gctUINT32 Flag,
+ IN gctSIZE_T Bytes,
+ OUT gcuVIDMEM_NODE_PTR * Node
+ );
+
+/* Destroy a gcuVIDMEM_NODE union for virtual memory. */
+gceSTATUS
+gckVIDMEM_DestroyVirtual(
+ IN gcuVIDMEM_NODE_PTR Node
+ );
+
+gceSTATUS
+gckVIDMEM_SetCommitStamp(
+ IN gckKERNEL Kernel,
+ IN gceENGINE Engine,
+ IN gctUINT32 Handle,
+ IN gctUINT64 CommitStamp
+ );
+
+gceSTATUS
+gckVIDMEM_GetCommitStamp(
+ IN gckKERNEL Kernel,
+ IN gceENGINE Engine,
+ IN gctUINT32 Handle,
+ OUT gctUINT64_PTR CommitStamp
+ );
+
+/******************************************************************************\
+******************************** gckKERNEL Object ******************************
+\******************************************************************************/
+
+struct _gcsHAL_INTERFACE;
+
+/* Notifications. */
+typedef enum _gceNOTIFY
+{
+ gcvNOTIFY_INTERRUPT,
+ gcvNOTIFY_COMMAND_QUEUE,
+}
+gceNOTIFY;
+
+/* Flush flags. */
+typedef enum _gceKERNEL_FLUSH
+{
+ gcvFLUSH_COLOR = 0x01,
+ gcvFLUSH_DEPTH = 0x02,
+ gcvFLUSH_TEXTURE = 0x04,
+ gcvFLUSH_2D = 0x08,
+ gcvFLUSH_L2 = 0x10,
+ gcvFLUSH_TILE_STATUS = 0x20,
+ gcvFLUSH_ICACHE = 0x40,
+ gcvFLUSH_TXDESC = 0x80,
+ gcvFLUSH_FENCE = 0x100,
+ gcvFLUSH_VERTEX = 0x200,
+ gcvFLUSH_TFBHEADER = 0x400,
+ gcvFLUSH_ALL = gcvFLUSH_COLOR
+ | gcvFLUSH_DEPTH
+ | gcvFLUSH_TEXTURE
+ | gcvFLUSH_2D
+ | gcvFLUSH_L2
+ | gcvFLUSH_TILE_STATUS
+ | gcvFLUSH_ICACHE
+ | gcvFLUSH_TXDESC
+ | gcvFLUSH_FENCE
+ | gcvFLUSH_VERTEX
+ | gcvFLUSH_TFBHEADER
+}
+gceKERNEL_FLUSH;
+
+/* Construct a new gckKERNEL object. */
+gceSTATUS
+gckKERNEL_Construct(
+ IN gckOS Os,
+ IN gceCORE Core,
+ IN gctUINT ChipID,
+ IN gctPOINTER Context,
+ IN gckDEVICE Device,
+ IN gckDB SharedDB,
+ OUT gckKERNEL * Kernel
+ );
+
+/* Destroy an gckKERNEL object. */
+gceSTATUS
+gckKERNEL_Destroy(
+ IN gckKERNEL Kernel
+ );
+
+/* Dispatch a user-level command. */
+gceSTATUS
+gckKERNEL_Dispatch(
+ IN gckKERNEL Kernel,
+ IN gckDEVICE Device,
+ IN gctBOOL FromUser,
+ IN OUT struct _gcsHAL_INTERFACE * Interface
+ );
+
+/* Query Database requirements. */
+gceSTATUS
+ gckKERNEL_QueryDatabase(
+ IN gckKERNEL Kernel,
+ IN gctUINT32 ProcessID,
+ IN OUT gcsHAL_INTERFACE * Interface
+ );
+
+/* Query the video memory. */
+gceSTATUS
+gckKERNEL_QueryVideoMemory(
+ IN gckKERNEL Kernel,
+ OUT struct _gcsHAL_INTERFACE * Interface
+ );
+
+/* Query used memory nodes of a specific pool. */
+gceSTATUS
+gckKERNEL_QueryVidMemPoolNodes(
+ gckKERNEL Kernel,
+ gcePOOL Pool,
+ gctUINT32 * TotalSize, /* sum of the sizes of the contiguous blocks (i.e. total memory used at current time) : to be filled by the called function */
+ gcsContiguousBlock * MemoryBlocks, /* previously allocated by the calling function : to be filled by the called function */
+ gctUINT32 NumMaxBlocks, /* provided by the calling function */
+ gctUINT32 * NumBlocks /* actual number of contiguous blocks : to be filled by the called function */
+ );
+
+/* Lookup the gckVIDMEM object for a pool. */
+gceSTATUS
+gckKERNEL_GetVideoMemoryPool(
+ IN gckKERNEL Kernel,
+ IN gcePOOL Pool,
+ OUT gckVIDMEM * VideoMemory
+ );
+
+gceSTATUS
+gckKERNEL_AllocateLinearMemory(
+ IN gckKERNEL Kernel,
+ IN gctUINT32 ProcessID,
+ IN OUT gcePOOL * Pool,
+ IN gctSIZE_T Bytes,
+ IN gctUINT32 Alignment,
+ IN gceSURF_TYPE Type,
+ IN gctUINT32 Flag,
+ OUT gctUINT32 * Node
+ );
+
+gceSTATUS
+gckKERNEL_ReleaseVideoMemory(
+ IN gckKERNEL Kernel,
+ IN gctUINT32 ProcessID,
+ IN gctUINT32 Handle
+ );
+
+gceSTATUS
+gckKERNEL_LockVideoMemory(
+ IN gckKERNEL Kernel,
+ IN gceCORE Core,
+ IN gctUINT32 ProcessID,
+ IN gctBOOL FromUser,
+ IN OUT gcsHAL_INTERFACE * Interface
+ );
+
+gceSTATUS
+gckKERNEL_UnlockVideoMemory(
+ IN gckKERNEL Kernel,
+ IN gctUINT32 ProcessID,
+ IN OUT gcsHAL_INTERFACE * Interface
+ );
+
+/* Unlock video memory from gpu immediately w/o considering gpu cache flush. */
+gceSTATUS
+gckKERNEL_BottomHalfUnlockVideoMemory(
+ IN gckKERNEL Kernel,
+ IN gctUINT32 ProcessID,
+ IN gctUINT32 Node
+ );
+
+/* Map video memory. */
+gceSTATUS
+gckKERNEL_MapVideoMemory(
+ IN gckKERNEL Kernel,
+ IN gctBOOL InUserSpace,
+ IN gctUINT32 Address,
+#ifdef __QNXNTO__
+ IN gctUINT32 Pid,
+ IN gctUINT32 Bytes,
+#endif
+ OUT gctPOINTER * Logical
+ );
+
+/* Map video memory. */
+gceSTATUS
+gckKERNEL_MapVideoMemoryEx(
+ IN gckKERNEL Kernel,
+ IN gceCORE Core,
+ IN gctBOOL InUserSpace,
+ IN gctUINT32 Address,
+#ifdef __QNXNTO__
+ IN gctUINT32 Pid,
+ IN gctUINT32 Bytes,
+#endif
+ IN gcePOOL Pool,
+ OUT gctPOINTER * Logical
+ );
+
+#ifdef __QNXNTO__
+/* Unmap video memory. */
+gceSTATUS
+gckKERNEL_UnmapVideoMemory(
+ IN gckKERNEL Kernel,
+ IN gctPOINTER Logical,
+ IN gctUINT32 Pid,
+ IN gctUINT32 Bytes
+ );
+#endif
+
+/* Map memory. */
+gceSTATUS
+gckKERNEL_MapMemory(
+ IN gckKERNEL Kernel,
+ IN gctPHYS_ADDR Physical,
+ IN gctSIZE_T Bytes,
+ OUT gctPOINTER * Logical
+ );
+
+/* Unmap memory. */
+gceSTATUS
+gckKERNEL_UnmapMemory(
+ IN gckKERNEL Kernel,
+ IN gctPHYS_ADDR Physical,
+ IN gctSIZE_T Bytes,
+ IN gctPOINTER Logical,
+ IN gctUINT32 ProcessID
+ );
+
+/* Notification of events. */
+gceSTATUS
+gckKERNEL_Notify(
+ IN gckKERNEL Kernel,
+ IN gceNOTIFY Notifcation,
+ IN gctBOOL Data
+ );
+
+gceSTATUS
+gckKERNEL_QuerySettings(
+ IN gckKERNEL Kernel,
+ OUT gcsKERNEL_SETTINGS * Settings
+ );
+
+/*******************************************************************************
+**
+** gckKERNEL_Recovery
+**
+** Try to recover the GPU from a fatal error.
+**
+** INPUT:
+**
+** gckKERNEL Kernel
+** Pointer to an gckKERNEL object.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckKERNEL_Recovery(
+ IN gckKERNEL Kernel
+ );
+
+/* Get access to the user data. */
+gceSTATUS
+gckKERNEL_OpenUserData(
+ IN gckKERNEL Kernel,
+ IN gctBOOL NeedCopy,
+ IN gctPOINTER StaticStorage,
+ IN gctPOINTER UserPointer,
+ IN gctSIZE_T Size,
+ OUT gctPOINTER * KernelPointer
+ );
+
+/* Release resources associated with the user data connection. */
+gceSTATUS
+gckKERNEL_CloseUserData(
+ IN gckKERNEL Kernel,
+ IN gctBOOL NeedCopy,
+ IN gctBOOL FlushData,
+ IN gctPOINTER UserPointer,
+ IN gctSIZE_T Size,
+ OUT gctPOINTER * KernelPointer
+ );
+
+gceSTATUS
+gckDVFS_Construct(
+ IN gckHARDWARE Hardware,
+ OUT gckDVFS * Frequency
+ );
+
+gceSTATUS
+gckDVFS_Destroy(
+ IN gckDVFS Dvfs
+ );
+
+gceSTATUS
+gckDVFS_Start(
+ IN gckDVFS Dvfs
+ );
+
+gceSTATUS
+gckDVFS_Stop(
+ IN gckDVFS Dvfs
+ );
+
+/******************************************************************************\
+******************************* gckHARDWARE Object *****************************
+\******************************************************************************/
+
+/* Construct a new gckHARDWARE object. */
+gceSTATUS
+gckHARDWARE_Construct(
+ IN gckOS Os,
+ IN gceCORE Core,
+ OUT gckHARDWARE * Hardware
+ );
+
+/* Destroy an gckHARDWARE object. */
+gceSTATUS
+gckHARDWARE_Destroy(
+ IN gckHARDWARE Hardware
+ );
+
+/* Get hardware type. */
+gceSTATUS
+gckHARDWARE_GetType(
+ IN gckHARDWARE Hardware,
+ OUT gceHARDWARE_TYPE * Type
+ );
+
+/* Query system memory requirements. */
+gceSTATUS
+gckHARDWARE_QuerySystemMemory(
+ IN gckHARDWARE Hardware,
+ OUT gctSIZE_T * SystemSize,
+ OUT gctUINT32 * SystemBaseAddress
+ );
+
+/* Build virtual address. */
+gceSTATUS
+gckHARDWARE_BuildVirtualAddress(
+ IN gckHARDWARE Hardware,
+ IN gctUINT32 Index,
+ IN gctUINT32 Offset,
+ OUT gctUINT32 * Address
+ );
+
+/* Query command buffer requirements. */
+gceSTATUS
+gckHARDWARE_QueryCommandBuffer(
+ IN gckHARDWARE Hardware,
+ IN gceENGINE Engine,
+ OUT gctUINT32 * Alignment,
+ OUT gctUINT32 * ReservedHead,
+ OUT gctUINT32 * ReservedTail
+ );
+
+/* Add a WAIT/LINK pair in the command queue. */
+gceSTATUS
+gckHARDWARE_WaitLink(
+ IN gckHARDWARE Hardware,
+ IN gctPOINTER Logical,
+ IN gctUINT32 Address,
+ IN gctUINT32 Offset,
+ IN OUT gctUINT32 * Bytes,
+ OUT gctUINT32 * WaitOffset,
+ OUT gctUINT32 * WaitBytes
+ );
+
+/* Kickstart the command processor. */
+gceSTATUS
+gckHARDWARE_Execute(
+ IN gckHARDWARE Hardware,
+ IN gctUINT32 Address,
+ IN gctSIZE_T Bytes
+ );
+
+/* Add an END command in the command queue. */
+gceSTATUS
+gckHARDWARE_End(
+ IN gckHARDWARE Hardware,
+ IN gctPOINTER Logical,
+ IN gctUINT32 Address,
+ IN OUT gctUINT32 * Bytes
+ );
+
+gceSTATUS
+gckHARDWARE_ChipEnable(
+ IN gckHARDWARE Hardware,
+ IN gctPOINTER Logical,
+ IN gceCORE_3D_MASK ChipEnable,
+ IN OUT gctSIZE_T * Bytes
+ );
+
+/* Add a NOP command in the command queue. */
+gceSTATUS
+gckHARDWARE_Nop(
+ IN gckHARDWARE Hardware,
+ IN gctPOINTER Logical,
+ IN OUT gctSIZE_T * Bytes
+ );
+
+/* Add a PIPESELECT command in the command queue. */
+gceSTATUS
+gckHARDWARE_PipeSelect(
+ IN gckHARDWARE Hardware,
+ IN gctPOINTER Logical,
+ IN gcePIPE_SELECT Pipe,
+ IN OUT gctUINT32 * Bytes
+ );
+
+/* Add a LINK command in the command queue. */
+gceSTATUS
+gckHARDWARE_Link(
+ IN gckHARDWARE Hardware,
+ IN gctPOINTER Logical,
+ IN gctUINT32 FetchAddress,
+ IN gctUINT32 FetchSize,
+ IN OUT gctUINT32 * Bytes,
+ OUT gctUINT32 * Low,
+ OUT gctUINT32 * High
+ );
+
+/* Add an EVENT command in the command queue. */
+gceSTATUS
+gckHARDWARE_Event(
+ IN gckHARDWARE Hardware,
+ IN gctPOINTER Logical,
+ IN gctUINT8 Event,
+ IN gceKERNEL_WHERE FromWhere,
+ IN OUT gctUINT32 * Bytes
+ );
+
+/* Query the available memory. */
+gceSTATUS
+gckHARDWARE_QueryMemory(
+ IN gckHARDWARE Hardware,
+ OUT gctSIZE_T * InternalSize,
+ OUT gctUINT32 * InternalBaseAddress,
+ OUT gctUINT32 * InternalAlignment,
+ OUT gctSIZE_T * ExternalSize,
+ OUT gctUINT32 * ExternalBaseAddress,
+ OUT gctUINT32 * ExternalAlignment,
+ OUT gctUINT32 * HorizontalTileSize,
+ OUT gctUINT32 * VerticalTileSize
+ );
+
+/* Query the identity of the hardware. */
+gceSTATUS
+gckHARDWARE_QueryChipIdentity(
+ IN gckHARDWARE Hardware,
+ OUT gcsHAL_QUERY_CHIP_IDENTITY_PTR Identity
+ );
+
+gceSTATUS
+gckHARDWARE_QueryChipOptions(
+ IN gckHARDWARE Hardware,
+ OUT gcsHAL_QUERY_CHIP_OPTIONS_PTR Options
+ );
+
+/* Query the shader uniforms support. */
+gceSTATUS
+gckHARDWARE_QueryShaderCaps(
+ IN gckHARDWARE Hardware,
+ OUT gctUINT * VertexUniforms,
+ OUT gctUINT * FragmentUniforms,
+ OUT gctBOOL * UnifiedUnforms
+ );
+
+/* Split a harwdare specific address into API stuff. */
+gceSTATUS
+gckHARDWARE_SplitMemory(
+ IN gckHARDWARE Hardware,
+ IN gctUINT32 Address,
+ OUT gcePOOL * Pool,
+ OUT gctUINT32 * Offset
+ );
+
+/* Update command queue tail pointer. */
+gceSTATUS
+gckHARDWARE_UpdateQueueTail(
+ IN gckHARDWARE Hardware,
+ IN gctPOINTER Logical,
+ IN gctUINT32 Offset
+ );
+
+/* Convert logical address to hardware specific address. */
+gceSTATUS
+gckHARDWARE_ConvertLogical(
+ IN gckHARDWARE Hardware,
+ IN gctPOINTER Logical,
+ IN gctBOOL InUserSpace,
+ OUT gctUINT32 * Address
+ );
+
+/* Interrupt manager. */
+gceSTATUS
+gckHARDWARE_Interrupt(
+ IN gckHARDWARE Hardware,
+ IN gctBOOL InterruptValid
+ );
+
+/* Program MMU. */
+gceSTATUS
+gckHARDWARE_SetMMU(
+ IN gckHARDWARE Hardware,
+ IN gctPOINTER Logical
+ );
+
+/* Flush the MMU. */
+gceSTATUS
+gckHARDWARE_FlushMMU(
+ IN gckHARDWARE Hardware
+ );
+
+gceSTATUS
+gckHARDWARE_FlushAsyncMMU(
+ IN gckHARDWARE Hardware,
+ IN gctPOINTER Logical,
+ IN OUT gctUINT32 * Bytes
+ );
+
+/* Set the page table base address. */
+gceSTATUS
+gckHARDWARE_SetMMUv2(
+ IN gckHARDWARE Hardware,
+ IN gctBOOL Enable,
+ IN gctPOINTER MtlbAddress,
+ IN gceMMU_MODE Mode,
+ IN gctPOINTER SafeAddress,
+ IN gctBOOL FromPower
+ );
+
+#if gcdPROCESS_ADDRESS_SPACE
+/* Configure mmu configuration. */
+gceSTATUS
+gckHARDWARE_ConfigMMU(
+ IN gckHARDWARE Hardware,
+ IN gctPOINTER Logical,
+ IN gctPOINTER MtlbLogical,
+ IN gctUINT32 Offset,
+ IN OUT gctSIZE_T * Bytes,
+ OUT gctSIZE_T * WaitLinkOffset,
+ OUT gctSIZE_T * WaitLinkBytes
+ );
+#endif
+
+/* Get idle register. */
+gceSTATUS
+gckHARDWARE_GetIdle(
+ IN gckHARDWARE Hardware,
+ IN gctBOOL Wait,
+ OUT gctUINT32 * Data
+ );
+
+/* Flush the caches. */
+gceSTATUS
+gckHARDWARE_Flush(
+ IN gckHARDWARE Hardware,
+ IN gceKERNEL_FLUSH Flush,
+ IN gctPOINTER Logical,
+ IN OUT gctUINT32 * Bytes
+ );
+
+/* Enable/disable fast clear. */
+gceSTATUS
+gckHARDWARE_SetFastClear(
+ IN gckHARDWARE Hardware,
+ IN gctINT Enable,
+ IN gctINT Compression
+ );
+
+gceSTATUS
+gckHARDWARE_ReadInterrupt(
+ IN gckHARDWARE Hardware,
+ OUT gctUINT32_PTR IDs
+ );
+
+/* Power management. */
+gceSTATUS
+gckHARDWARE_SetPowerManagementState(
+ IN gckHARDWARE Hardware,
+ IN gceCHIPPOWERSTATE State
+ );
+
+gceSTATUS
+gckHARDWARE_QueryPowerManagementState(
+ IN gckHARDWARE Hardware,
+ OUT gceCHIPPOWERSTATE* State
+ );
+
+gceSTATUS
+gckHARDWARE_SetPowerManagement(
+ IN gckHARDWARE Hardware,
+ IN gctBOOL PowerManagement
+ );
+
+gceSTATUS
+gckHARDWARE_SetGpuProfiler(
+ IN gckHARDWARE Hardware,
+ IN gctBOOL GpuProfiler
+ );
+
+#if gcdENABLE_FSCALE_VAL_ADJUST
+gceSTATUS
+gckHARDWARE_SetFscaleValue(
+ IN gckHARDWARE Hardware,
+ IN gctUINT32 FscaleValue
+ );
+
+gceSTATUS
+gckHARDWARE_GetFscaleValue(
+ IN gckHARDWARE Hardware,
+ IN gctUINT * FscaleValue,
+ IN gctUINT * MinFscaleValue,
+ IN gctUINT * MaxFscaleValue
+ );
+
+gceSTATUS
+gckHARDWARE_SetMinFscaleValue(
+ IN gckHARDWARE Hardware,
+ IN gctUINT MinFscaleValue
+ );
+#endif
+
+#if gcdPOWEROFF_TIMEOUT
+gceSTATUS
+gckHARDWARE_SetPowerOffTimeout(
+ IN gckHARDWARE Hardware,
+ IN gctUINT32 Timeout
+);
+
+gceSTATUS
+gckHARDWARE_QueryPowerOffTimeout(
+ IN gckHARDWARE Hardware,
+ OUT gctUINT32* Timeout
+);
+#endif
+
+/* Profile 2D Engine. */
+gceSTATUS
+gckHARDWARE_ProfileEngine2D(
+ IN gckHARDWARE Hardware,
+ OUT gcs2D_PROFILE_PTR Profile
+ );
+
+gceSTATUS
+gckHARDWARE_InitializeHardware(
+ IN gckHARDWARE Hardware
+ );
+
+gceSTATUS
+gckHARDWARE_Reset(
+ IN gckHARDWARE Hardware
+ );
+
+/* Check for Hardware features. */
+gceSTATUS
+gckHARDWARE_IsFeatureAvailable(
+ IN gckHARDWARE Hardware,
+ IN gceFEATURE Feature
+ );
+
+gceSTATUS
+gckHARDWARE_DumpMMUException(
+ IN gckHARDWARE Hardware
+ );
+
+gceSTATUS
+gckHARDWARE_DumpGPUState(
+ IN gckHARDWARE Hardware
+ );
+
+gceSTATUS
+gckHARDWARE_InitDVFS(
+ IN gckHARDWARE Hardware
+ );
+
+gceSTATUS
+gckHARDWARE_QueryLoad(
+ IN gckHARDWARE Hardware,
+ OUT gctUINT32 * Load
+ );
+
+gceSTATUS
+gckHARDWARE_SetDVFSPeroid(
+ IN gckHARDWARE Hardware,
+ IN gctUINT32 Frequency
+ );
+
+gceSTATUS
+gckHARDWARE_PrepareFunctions(
+ gckHARDWARE Hardware
+ );
+
+gceSTATUS
+gckHARDWARE_DestroyFunctions(
+ gckHARDWARE Hardware
+ );
+
+gceSTATUS
+gckHARDWARE_SetMMUStates(
+ IN gckHARDWARE Hardware,
+ IN gctPOINTER MtlbAddress,
+ IN gceMMU_MODE Mode,
+ IN gctPOINTER SafeAddress,
+ IN gctPOINTER Logical,
+ IN OUT gctUINT32 * Bytes
+ );
+
+gceSTATUS
+gckHARDWARE_QueryStateTimer(
+ IN gckHARDWARE Hardware,
+ OUT gctUINT64_PTR Start,
+ OUT gctUINT64_PTR End,
+ OUT gctUINT64_PTR On,
+ OUT gctUINT64_PTR Off,
+ OUT gctUINT64_PTR Idle,
+ OUT gctUINT64_PTR Suspend
+ );
+
+gceSTATUS
+gckHARDWARE_Fence(
+ IN gckHARDWARE Hardware,
+ IN gceENGINE Engine,
+ IN gctPOINTER Logical,
+ IN gctUINT32 FenceAddress,
+ IN gctUINT64 FenceData,
+ IN OUT gctUINT32 * Bytes
+ );
+
+#if !gcdENABLE_VG
+/******************************************************************************\
+***************************** gckINTERRUPT Object ******************************
+\******************************************************************************/
+
+typedef struct _gckINTERRUPT * gckINTERRUPT;
+
+typedef gceSTATUS (* gctINTERRUPT_HANDLER)(
+ IN gckKERNEL Kernel
+ );
+
+gceSTATUS
+gckINTERRUPT_Construct(
+ IN gckKERNEL Kernel,
+ OUT gckINTERRUPT * Interrupt
+ );
+
+gceSTATUS
+gckINTERRUPT_Destroy(
+ IN gckINTERRUPT Interrupt
+ );
+
+gceSTATUS
+gckINTERRUPT_SetHandler(
+ IN gckINTERRUPT Interrupt,
+ IN OUT gctINT32_PTR Id,
+ IN gctINTERRUPT_HANDLER Handler
+ );
+
+gceSTATUS
+gckINTERRUPT_Notify(
+ IN gckINTERRUPT Interrupt,
+ IN gctBOOL Valid
+ );
+#endif
+/******************************************************************************\
+******************************** gckEVENT Object *******************************
+\******************************************************************************/
+
+typedef struct _gckEVENT * gckEVENT;
+
+/* Construct a new gckEVENT object. */
+gceSTATUS
+gckEVENT_Construct(
+ IN gckKERNEL Kernel,
+ OUT gckEVENT * Event
+ );
+
+/* Destroy an gckEVENT object. */
+gceSTATUS
+gckEVENT_Destroy(
+ IN gckEVENT Event
+ );
+
+/* Reserve the next available hardware event. */
+gceSTATUS
+gckEVENT_GetEvent(
+ IN gckEVENT Event,
+ IN gctBOOL Wait,
+ OUT gctUINT8 * EventID,
+ IN gceKERNEL_WHERE Source
+ );
+
+/* Add a new event to the list of events. */
+gceSTATUS
+gckEVENT_AddList(
+ IN gckEVENT Event,
+ IN gcsHAL_INTERFACE_PTR Interface,
+ IN gceKERNEL_WHERE FromWhere,
+ IN gctBOOL AllocateAllowed,
+ IN gctBOOL FromKernel
+ );
+
+/* Schedule a FreeNonPagedMemory event. */
+gceSTATUS
+gckEVENT_FreeNonPagedMemory(
+ IN gckEVENT Event,
+ IN gctSIZE_T Bytes,
+ IN gctPHYS_ADDR Physical,
+ IN gctPOINTER Logical,
+ IN gceKERNEL_WHERE FromWhere
+ );
+
+/* Schedule a FreeContiguousMemory event. */
+gceSTATUS
+gckEVENT_FreeContiguousMemory(
+ IN gckEVENT Event,
+ IN gctSIZE_T Bytes,
+ IN gctPHYS_ADDR Physical,
+ IN gctPOINTER Logical,
+ IN gceKERNEL_WHERE FromWhere
+ );
+
+/* Schedule a FreeVideoMemory event. */
+gceSTATUS
+gckEVENT_FreeVideoMemory(
+ IN gckEVENT Event,
+ IN gcuVIDMEM_NODE_PTR VideoMemory,
+ IN gceKERNEL_WHERE FromWhere
+ );
+
+/* Schedule a signal event. */
+gceSTATUS
+gckEVENT_Signal(
+ IN gckEVENT Event,
+ IN gctSIGNAL Signal,
+ IN gceKERNEL_WHERE FromWhere
+ );
+
+/* Schedule an Unlock event. */
+gceSTATUS
+gckEVENT_Unlock(
+ IN gckEVENT Event,
+ IN gceKERNEL_WHERE FromWhere,
+ IN gctPOINTER Node,
+ IN gceSURF_TYPE Type
+ );
+
+/* Schedule a FreeVirtualCommandBuffer event. */
+gceSTATUS
+gckEVENT_DestroyVirtualCommandBuffer(
+ IN gckEVENT Event,
+ IN gctSIZE_T Bytes,
+ IN gctPHYS_ADDR Physical,
+ IN gctPOINTER Logical,
+ IN gceKERNEL_WHERE FromWhere
+ );
+
+gceSTATUS
+gckEVENT_Submit(
+ IN gckEVENT Event,
+ IN gctBOOL Wait,
+ IN gctBOOL FromPower
+ );
+
+gceSTATUS
+gckEVENT_Commit(
+ IN gckEVENT Event,
+ IN gcsQUEUE_PTR Queue,
+ IN gctBOOL Forced
+ );
+
+/* Event callback routine. */
+gceSTATUS
+gckEVENT_Notify(
+ IN gckEVENT Event,
+ IN gctUINT32 IDs
+ );
+
+/* Event callback routine. */
+gceSTATUS
+gckEVENT_Interrupt(
+ IN gckEVENT Event,
+ IN gctUINT32 IDs
+ );
+
+gceSTATUS
+gckEVENT_Dump(
+ IN gckEVENT Event
+ );
+/******************************************************************************\
+******************************* gckCOMMAND Object ******************************
+\******************************************************************************/
+
+typedef struct _gckCOMMAND * gckCOMMAND;
+
+/* Construct a new gckCOMMAND object. */
+gceSTATUS
+gckCOMMAND_Construct(
+ IN gckKERNEL Kernel,
+ OUT gckCOMMAND * Command
+ );
+
+/* Destroy an gckCOMMAND object. */
+gceSTATUS
+gckCOMMAND_Destroy(
+ IN gckCOMMAND Command
+ );
+
+/* Acquire command queue synchronization objects. */
+gceSTATUS
+gckCOMMAND_EnterCommit(
+ IN gckCOMMAND Command,
+ IN gctBOOL FromPower
+ );
+
+/* Release command queue synchronization objects. */
+gceSTATUS
+gckCOMMAND_ExitCommit(
+ IN gckCOMMAND Command,
+ IN gctBOOL FromPower
+ );
+
+/* Start the command queue. */
+gceSTATUS
+gckCOMMAND_Start(
+ IN gckCOMMAND Command
+ );
+
+/* Stop the command queue. */
+gceSTATUS
+gckCOMMAND_Stop(
+ IN gckCOMMAND Command
+ );
+
+gceSTATUS
+gckCOMMAND_Commit(
+ IN gckCOMMAND Command,
+ IN gckCONTEXT Context,
+ IN gcoCMDBUF CommandBuffer,
+ IN gcsSTATE_DELTA_PTR StateDelta,
+ IN gctUINT32 ProcessID,
+ IN gctBOOL Shared,
+ IN gctUINT32 Index,
+ OUT gctUINT64_PTR CommitStamp,
+ OUT gctBOOL_PTR ContextSwitched
+ );
+
+/* Reserve space in the command buffer. */
+gceSTATUS
+gckCOMMAND_Reserve(
+ IN gckCOMMAND Command,
+ IN gctUINT32 RequestedBytes,
+ OUT gctPOINTER * Buffer,
+ OUT gctUINT32 * BufferSize
+ );
+
+/* Execute reserved space in the command buffer. */
+gceSTATUS
+gckCOMMAND_Execute(
+ IN gckCOMMAND Command,
+ IN gctUINT32 RequstedBytes
+ );
+
+/* Stall the command queue. */
+gceSTATUS
+gckCOMMAND_Stall(
+ IN gckCOMMAND Command,
+ IN gctBOOL FromPower
+ );
+
+/* Attach user process. */
+gceSTATUS
+gckCOMMAND_Attach(
+ IN gckCOMMAND Command,
+ OUT gckCONTEXT * Context,
+ OUT gctSIZE_T * MaxState,
+ OUT gctUINT32 * NumStates,
+ IN gctUINT32 ProcessID
+ );
+
+/* Detach user process. */
+gceSTATUS
+gckCOMMAND_Detach(
+ IN gckCOMMAND Command,
+ IN gckCONTEXT Context
+ );
+
+/* Dump command buffer being executed by GPU. */
+gceSTATUS
+gckCOMMAND_DumpExecutingBuffer(
+ IN gckCOMMAND Command
+ );
+
+/* Whether a kernel command buffer address. */
+gceSTATUS
+gckCOMMAND_AddressInKernelCommandBuffer(
+ IN gckCOMMAND Command,
+ IN gctUINT32 Address,
+ OUT gctPOINTER * Pointer
+ );
+
+/******************************************************************************\
+********************************* gckMMU Object ********************************
+\******************************************************************************/
+
+/* Construct a new gckMMU object. */
+gceSTATUS
+gckMMU_Construct(
+ IN gckKERNEL Kernel,
+ IN gctSIZE_T MmuSize,
+ OUT gckMMU * Mmu
+ );
+
+/* Destroy an gckMMU object. */
+gceSTATUS
+gckMMU_Destroy(
+ IN gckMMU Mmu
+ );
+
+/* Allocate pages inside the MMU. */
+gceSTATUS
+gckMMU_AllocatePages(
+ IN gckMMU Mmu,
+ IN gctSIZE_T PageCount,
+ OUT gctPOINTER * PageTable,
+ OUT gctUINT32 * Address
+ );
+
+gceSTATUS
+gckMMU_AllocatePagesEx(
+ IN gckMMU Mmu,
+ IN gctSIZE_T PageCount,
+ IN gceSURF_TYPE Type,
+ IN gctBOOL Secure,
+ OUT gctPOINTER * PageTable,
+ OUT gctUINT32 * Address
+ );
+
+/* Remove a page table from the MMU. */
+gceSTATUS
+gckMMU_FreePages(
+ IN gckMMU Mmu,
+ IN gctBOOL Secure,
+ IN gctUINT32 Address,
+ IN gctPOINTER PageTable,
+ IN gctSIZE_T PageCount
+ );
+
+/* Set the MMU page with info. */
+gceSTATUS
+gckMMU_SetPage(
+ IN gckMMU Mmu,
+ IN gctPHYS_ADDR_T PageAddress,
+ IN gctBOOL Writable,
+ IN gctUINT32 *PageEntry
+ );
+
+gceSTATUS
+gckMMU_Flush(
+ IN gckMMU Mmu,
+ IN gceSURF_TYPE Type
+ );
+
+gceSTATUS
+gckMMU_DumpPageTableEntry(
+ IN gckMMU Mmu,
+ IN gctUINT32 Address
+ );
+
+gceSTATUS
+gckMMU_FillFlatMapping(
+ IN gckMMU Mmu,
+ IN gctUINT32 PhysBase,
+ IN gctSIZE_T Size
+ );
+
+gceSTATUS
+gckMMU_IsFlatMapped(
+ IN gckMMU Mmu,
+ OUT gctUINT32 Physical,
+ OUT gctBOOL *In
+ );
+
+
+gceSTATUS
+gckHARDWARE_QueryContextProfile(
+ IN gckHARDWARE Hardware,
+ IN gctBOOL Reset,
+ IN gckCONTEXT Context,
+ OUT gcsPROFILER_COUNTERS_PART1 * Counters_part1,
+ OUT gcsPROFILER_COUNTERS_PART2 * Counters_part2
+ );
+
+gceSTATUS
+gckHARDWARE_UpdateContextProfile(
+ IN gckHARDWARE Hardware,
+ IN gckCONTEXT Context
+ );
+
+gceSTATUS
+gckHARDWARE_InitProfiler(
+ IN gckHARDWARE Hardware
+ );
+
+gceSTATUS
+gckOS_DetectProcessByName(
+ IN gctCONST_POINTER Name
+ );
+
+void
+gckOS_DumpParam(
+ void
+ );
+
+#ifdef __cplusplus
+}
+#endif
+
+#if gcdENABLE_VG
+#include "gc_hal_vg.h"
+#endif
+
+#endif /* __gc_hal_h_ */
+
+
diff --git a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_base.h b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_base.h
new file mode 100644
index 000000000000..fd52383e417d
--- /dev/null
+++ b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_base.h
@@ -0,0 +1,6048 @@
+/****************************************************************************
+*
+* The MIT License (MIT)
+*
+* Copyright (c) 2014 - 2018 Vivante 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 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 GPL License (GPL)
+*
+* Copyright (C) 2014 - 2018 Vivante 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.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+*****************************************************************************
+*
+* Note: This software is released under dual MIT and GPL licenses. A
+* recipient may use this file under the terms of either the MIT license or
+* GPL License. If you wish to use only one license not the other, you can
+* indicate your decision by deleting one of the above license notices in your
+* version of this file.
+*
+*****************************************************************************/
+
+
+#ifndef __gc_hal_base_h_
+#define __gc_hal_base_h_
+
+#include "gc_hal_enum.h"
+#include "gc_hal_types.h"
+#include "gc_hal_dump.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/******************************************************************************\
+****************************** Object Declarations *****************************
+\******************************************************************************/
+
+typedef struct _gckOS * gckOS;
+typedef struct _gcoHAL * gcoHAL;
+typedef struct _gcoOS * gcoOS;
+typedef struct _gco2D * gco2D;
+typedef struct gcsATOM * gcsATOM_PTR;
+
+typedef struct _gco3D * gco3D;
+typedef struct _gcoCL * gcoCL;
+typedef struct _gcsFAST_FLUSH * gcsFAST_FLUSH_PTR;
+
+typedef struct _gcoSURF * gcoSURF;
+typedef struct _gcsSURF_NODE * gcsSURF_NODE_PTR;
+typedef struct _gcsSURF_FORMAT_INFO * gcsSURF_FORMAT_INFO_PTR;
+typedef struct _gcsPOINT * gcsPOINT_PTR;
+typedef struct _gcsSIZE * gcsSIZE_PTR;
+typedef struct _gcsRECT * gcsRECT_PTR;
+typedef struct _gcsBOUNDARY * gcsBOUNDARY_PTR;
+typedef struct _gcoDUMP * gcoDUMP;
+typedef struct _gcoHARDWARE * gcoHARDWARE;
+typedef union _gcuVIDMEM_NODE * gcuVIDMEM_NODE_PTR;
+typedef struct _gcsVIDMEM_NODE * gckVIDMEM_NODE;
+
+#if gcdENABLE_VG
+typedef struct _gcoVG * gcoVG;
+typedef struct _gcsCOMPLETION_SIGNAL * gcsCOMPLETION_SIGNAL_PTR;
+typedef struct _gcsCONTEXT_MAP * gcsCONTEXT_MAP_PTR;
+#else
+typedef void * gcoVG;
+#endif
+
+typedef struct _gcoFENCE * gcoFENCE;
+typedef struct _gcsSYNC_CONTEXT * gcsSYNC_CONTEXT_PTR;
+
+typedef enum {
+ gcvFENCE_TYPE_READ = 0x1,
+ gcvFENCE_TYPE_WRITE = 0x2,
+ gcvFENCE_TYPE_ALL = gcvFENCE_TYPE_READ | gcvFENCE_TYPE_WRITE,
+ gcvFNECE_TYPE_INVALID = 0x10000,
+}
+gceFENCE_TYPE;
+
+typedef struct _gcsUSER_MEMORY_DESC * gcsUSER_MEMORY_DESC_PTR;
+
+
+/******************************************************************************\
+********************* Share obj lock/unlock macros. ****************************
+\******************************************************************************/
+#define gcmLOCK_SHARE_OBJ(Obj) \
+{ \
+ if(Obj->sharedLock != gcvNULL)\
+ {\
+ (gcoOS_AcquireMutex(\
+ gcvNULL, Obj->sharedLock, gcvINFINITE));\
+ }\
+}
+
+
+#define gcmUNLOCK_SHARE_OBJ(Obj)\
+{\
+ if(Obj->sharedLock != gcvNULL)\
+ {\
+ (gcoOS_ReleaseMutex(gcvNULL, Obj->sharedLock));\
+ }\
+}
+
+typedef struct _gcsSystemInfo
+{
+ /* memory latency number for SH data fetch, in SH cycle*/
+ gctUINT32 memoryLatencySH;
+}
+gcsSystemInfo;
+
+
+#if gcdENABLE_3D
+#if gcdSYNC
+#define gcPLS_INITIALIZER \
+{ \
+ gcvNULL, /* gcoOS object. */ \
+ gcvNULL, /* gcoHAL object. */ \
+ 0, /* internalSize */ \
+ gcvNULL, /* internalPhysical */ \
+ gcvNULL, /* internalLogical */ \
+ 0, /* externalSize */ \
+ gcvNULL, /* externalPhysical */ \
+ gcvNULL, /* externalLogical */ \
+ 0, /* contiguousSize */ \
+ gcvNULL, /* contiguousPhysical */ \
+ gcvNULL, /* contiguousLogical */ \
+ gcvNULL, /* eglDisplayInfo */ \
+ gcvNULL, /* eglSurfaceInfo */ \
+ gcvSURF_A8R8G8B8,/* eglConfigFormat */ \
+ gcvNULL, /* reference */ \
+ 0, /* processID */ \
+ 0, /* threadID */ \
+ gcvFALSE, /* exiting */ \
+ gcvFALSE, /* Special flag for NP2 texture. */ \
+ gcvFALSE, /* device open. */ \
+ gcvNULL, /* destructor */ \
+ gcvNULL, /* accessLock */ \
+ gcvNULL, /* GL FE compiler lock*/ \
+ gcvNULL, /* CL FE compiler lock*/ \
+ gcvPATCH_NOTINIT,/* global patchID */ \
+ gcvNULL, /* global fenceID*/ \
+}
+#else
+#define gcPLS_INITIALIZER \
+{ \
+ gcvNULL, /* gcoOS object. */ \
+ gcvNULL, /* gcoHAL object. */ \
+ 0, /* internalSize */ \
+ gcvNULL, /* internalPhysical */ \
+ gcvNULL, /* internalLogical */ \
+ 0, /* externalSize */ \
+ gcvNULL, /* externalPhysical */ \
+ gcvNULL, /* externalLogical */ \
+ 0, /* contiguousSize */ \
+ gcvNULL, /* contiguousPhysical */ \
+ gcvNULL, /* contiguousLogical */ \
+ gcvNULL, /* eglDisplayInfo */ \
+ gcvNULL, /* eglSurfaceInfo */ \
+ gcvSURF_A8R8G8B8,/* eglConfigFormat */ \
+ gcvNULL, /* reference */ \
+ 0, /* processID */ \
+ 0, /* threadID */ \
+ gcvFALSE, /* exiting */ \
+ gcvFALSE, /* Special flag for NP2 texture. */ \
+ gcvFALSE, /* device open. */ \
+ gcvNULL, /* destructor */ \
+ gcvNULL, /* accessLock */ \
+ gcvNULL, /* GL FE compiler lock*/ \
+ gcvNULL, /* CL FE compiler lock*/ \
+ gcvPATCH_NOTINIT,/* global patchID */ \
+}
+#endif
+#else
+#define gcPLS_INITIALIZER \
+{ \
+ gcvNULL, /* gcoOS object. */ \
+ gcvNULL, /* gcoHAL object. */ \
+ 0, /* internalSize */ \
+ gcvNULL, /* internalPhysical */ \
+ gcvNULL, /* internalLogical */ \
+ 0, /* externalSize */ \
+ gcvNULL, /* externalPhysical */ \
+ gcvNULL, /* externalLogical */ \
+ 0, /* contiguousSize */ \
+ gcvNULL, /* contiguousPhysical */ \
+ gcvNULL, /* contiguousLogical */ \
+ gcvNULL, /* eglDisplayInfo */ \
+ gcvNULL, /* eglSurfaceInfo */ \
+ gcvSURF_A8R8G8B8,/* eglConfigFormat */ \
+ gcvNULL, /* reference */ \
+ 0, /* processID */ \
+ 0, /* threadID */ \
+ gcvFALSE, /* exiting */ \
+ gcvFALSE, /* Special flag for NP2 texture. */ \
+ gcvFALSE, /* device open. */ \
+ gcvNULL, /* destructor */ \
+ gcvNULL, /* accessLock */ \
+}
+#endif
+
+/******************************************************************************\
+******************************* Thread local storage *************************
+\******************************************************************************/
+
+typedef struct _gcsDRIVER_TLS * gcsDRIVER_TLS_PTR;
+
+typedef struct _gcsDRIVER_TLS
+{
+ void (* destructor)(gcsDRIVER_TLS_PTR Tls);
+}
+gcsDRIVER_TLS;
+
+typedef enum _gceTLS_KEY
+{
+ gcvTLS_KEY_EGL,
+ gcvTLS_KEY_OPENGL_ES,
+ gcvTLS_KEY_OPENVG,
+ gcvTLS_KEY_OPENGL,
+ gcvTLS_KEY_OPENCL,
+ gcvTLS_KEY_OPENVX,
+
+ gcvTLS_KEY_COUNT
+}
+gceTLS_KEY;
+
+typedef struct _gcsTLS * gcsTLS_PTR;
+
+typedef struct _gcsTLS
+{
+ gceHARDWARE_TYPE currentType;
+
+ /* To which core device control is called,
+ * it is index in a hardware type.
+ */
+ gctUINT32 currentCoreIndex;
+
+ /* Current 3D hardwre of this thread */
+ gcoHARDWARE currentHardware;
+
+ /* Default 3D hardware of this thread */
+ gcoHARDWARE defaultHardware;
+
+ /* Only for separated 3D and 2D */
+ gcoHARDWARE hardware2D;
+#if gcdENABLE_VG
+ gcoVGHARDWARE vg;
+ gcoVG engineVG;
+#endif /* gcdENABLE_VG */
+#if gcdENABLE_3D
+ gco3D engine3D;
+#endif
+#if gcdENABLE_2D
+ gco2D engine2D;
+#if gcdDUMP_2D
+ gctUINT32 newDump2DFlag;
+#endif
+#endif
+
+ gctBOOL copied;
+
+ /* libGAL.so handle */
+ gctHANDLE handle;
+
+ /* If true, do not releas 2d engine and hardware in hal layer */
+ gctBOOL release2DUpper;
+
+ /* Driver tls. */
+ gcsDRIVER_TLS_PTR driverTLS[gcvTLS_KEY_COUNT];
+}
+gcsTLS;
+
+/******************************************************************************\
+********************************* Enumerations *********************************
+\******************************************************************************/
+
+typedef enum _gcePLS_VALUE
+{
+ gcePLS_VALUE_EGL_DISPLAY_INFO,
+ gcePLS_VALUE_EGL_CONFIG_FORMAT_INFO,
+ gcePLS_VALUE_EGL_DESTRUCTOR_INFO,
+}
+gcePLS_VALUE;
+
+/* Video memory pool type. */
+typedef enum _gcePOOL
+{
+ gcvPOOL_UNKNOWN = 0,
+ gcvPOOL_DEFAULT,
+ gcvPOOL_LOCAL,
+ gcvPOOL_LOCAL_INTERNAL,
+ gcvPOOL_LOCAL_EXTERNAL,
+ gcvPOOL_UNIFIED,
+ gcvPOOL_SYSTEM,
+ gcvPOOL_VIRTUAL,
+ gcvPOOL_USER,
+ gcvPOOL_CONTIGUOUS,
+
+ gcvPOOL_NUMBER_OF_POOLS
+}
+gcePOOL;
+
+#if gcdENABLE_3D
+/* Blending functions. */
+typedef enum _gceBLEND_FUNCTION
+{
+ gcvBLEND_ZERO,
+ gcvBLEND_ONE,
+ gcvBLEND_SOURCE_COLOR,
+ gcvBLEND_INV_SOURCE_COLOR,
+ gcvBLEND_SOURCE_ALPHA,
+ gcvBLEND_INV_SOURCE_ALPHA,
+ gcvBLEND_TARGET_COLOR,
+ gcvBLEND_INV_TARGET_COLOR,
+ gcvBLEND_TARGET_ALPHA,
+ gcvBLEND_INV_TARGET_ALPHA,
+ gcvBLEND_SOURCE_ALPHA_SATURATE,
+ gcvBLEND_CONST_COLOR,
+ gcvBLEND_INV_CONST_COLOR,
+ gcvBLEND_CONST_ALPHA,
+ gcvBLEND_INV_CONST_ALPHA,
+}
+gceBLEND_FUNCTION;
+
+/* Blending modes. */
+typedef enum _gceBLEND_MODE
+{
+ gcvBLEND_ADD = 0,
+ gcvBLEND_SUBTRACT,
+ gcvBLEND_REVERSE_SUBTRACT,
+ gcvBLEND_MIN,
+ gcvBLEND_MAX,
+ gcvBLEND_MULTIPLY,
+ gcvBLEND_SCREEN,
+ gcvBLEND_OVERLAY,
+ gcvBLEND_DARKEN,
+ gcvBLEND_LIGHTEN,
+ gcvBLEND_COLORDODGE,
+ gcvBLEND_COLORBURN,
+ gcvBLEND_HARDLIGHT,
+ gcvBLEND_SOFTLIGHT,
+ gcvBLEND_DIFFERENCE,
+ gcvBLEND_EXCLUSION,
+ gcvBLEND_HSL_HUE,
+ gcvBLEND_HSL_SATURATION,
+ gcvBLEND_HSL_COLOR,
+ gcvBLEND_HSL_LUMINOSITY,
+
+ gcvBLEND_TOTAL
+}
+gceBLEND_MODE;
+
+/* Depth modes. */
+typedef enum _gceDEPTH_MODE
+{
+ gcvDEPTH_NONE,
+ gcvDEPTH_Z,
+ gcvDEPTH_W,
+}
+gceDEPTH_MODE;
+#endif /* gcdENABLE_3D */
+
+
+/* API flags. */
+typedef enum _gceAPI
+{
+ gcvAPI_D3D = 1,
+ gcvAPI_OPENGL_ES11,
+ gcvAPI_OPENGL_ES20,
+ gcvAPI_OPENGL_ES30,
+ gcvAPI_OPENGL_ES31,
+ gcvAPI_OPENGL_ES32,
+ gcvAPI_OPENGL,
+ gcvAPI_OPENVG,
+ gcvAPI_OPENCL,
+ gcvAPI_OPENVK,
+}
+gceAPI;
+
+typedef enum _gceWHERE
+{
+ gcvWHERE_COMMAND_PREFETCH = 0,
+ gcvWHERE_COMMAND,
+ gcvWHERE_RASTER,
+ gcvWHERE_PIXEL,
+ gcvWHERE_BLT,
+}
+gceWHERE;
+
+typedef enum _gceHOW
+{
+ gcvHOW_SEMAPHORE = 0x1,
+ gcvHOW_STALL = 0x2,
+ gcvHOW_SEMAPHORE_STALL = 0x3,
+}
+gceHOW;
+
+typedef enum _gceSignalHandlerType
+{
+ gcvHANDLE_SIGFPE_WHEN_SIGNAL_CODE_IS_0 = 0x1,
+}
+gceSignalHandlerType;
+
+typedef struct _gcsSURF_VIEW
+{
+ gcoSURF surf;
+ gctUINT firstSlice;
+ gctUINT numSlices;
+}gcsSURF_VIEW;
+
+/* gcsHAL_Limits*/
+typedef struct _gcsHAL_LIMITS
+{
+ /* chip info */
+ gceCHIPMODEL chipModel;
+ gctUINT32 chipRevision;
+ gctUINT32 featureCount;
+ gctUINT32 *chipFeatures;
+
+ /* target caps */
+ gctUINT32 maxWidth;
+ gctUINT32 maxHeight;
+ gctUINT32 multiTargetCount;
+ gctUINT32 maxSamples;
+
+}gcsHAL_LIMITS;
+
+
+typedef struct _gcsHAL_CHIPIDENTITY
+{
+ gceCHIPMODEL chipModel;
+ gctUINT32 chipRevision;
+ gctUINT32 productID;
+ gctUINT32 customerID;
+ gctUINT32 ecoID;
+ gceCHIP_FLAG chipFlags;
+ gctUINT32 platformFlagBits;
+}
+gcsHAL_CHIPIDENTITY;
+
+
+#define gcdEXTERNAL_MEMORY_NAME_MAX 32
+#define gcdEXTERNAL_MEMORY_DATA_MAX 8
+
+typedef struct _gcsEXTERNAL_MEMORY_INFO
+{
+ /* Name of allocator used to attach this memory. */
+ gctCHAR allocatorName[gcdEXTERNAL_MEMORY_NAME_MAX];
+
+ /* User defined data which will be passed to allocator. */
+ gctUINT32 userData[gcdEXTERNAL_MEMORY_DATA_MAX];
+}
+gcsEXTERNAL_MEMORY_INFO;
+
+/******************************************************************************\
+********************************* gcoHAL Object *********************************
+\******************************************************************************/
+
+/* Construct a new gcoHAL object. */
+gceSTATUS
+gcoHAL_ConstructEx(
+ IN gctPOINTER Context,
+ IN gcoOS Os,
+ OUT gcoHAL * Hal
+ );
+
+/* Destroy an gcoHAL object. */
+gceSTATUS
+gcoHAL_DestroyEx(
+ IN gcoHAL Hal
+ );
+
+/* Empty function for compatibility. */
+gceSTATUS
+gcoHAL_Construct(
+ IN gctPOINTER Context,
+ IN gcoOS Os,
+ OUT gcoHAL * Hal
+ );
+
+/* Empty function for compatibility. */
+gceSTATUS
+gcoHAL_Destroy(
+ IN gcoHAL Hal
+ );
+
+/* Get HAL options */
+gceSTATUS
+gcoHAL_GetOption(
+ IN gcoHAL Hal,
+ IN gceOPTION Option
+ );
+
+gceSTATUS
+gcoHAL_FrameInfoOps(
+ IN gcoHAL Hal,
+ IN gceFRAMEINFO FrameInfo,
+ IN gceFRAMEINFO_OP Op,
+ IN OUT gctUINT * Val
+ );
+
+/* Set HAL options */
+gceSTATUS
+gcoHAL_SetOption(
+ IN gcoHAL Hal,
+ IN gceOPTION Option,
+ IN gctBOOL Value
+ );
+
+gceSTATUS
+gcoHAL_GetHardware(
+ IN gcoHAL Hal,
+ OUT gcoHARDWARE* Hw
+ );
+
+#if gcdENABLE_2D
+/* Get pointer to gco2D object. */
+gceSTATUS
+gcoHAL_Get2DEngine(
+ IN gcoHAL Hal,
+ OUT gco2D * Engine
+ );
+#endif
+
+#if gcdENABLE_3D
+gceSTATUS
+gcoHAL_GetSpecialHintData(
+ IN gcoHAL Hal,
+ OUT gctINT * Hint
+ );
+/*
+** Deprecated(Don't use it), keep it here for external library(libgcu.so)
+*/
+gceSTATUS
+gcoHAL_Get3DEngine(
+ IN gcoHAL Hal,
+ OUT gco3D * Engine
+ );
+#endif /* gcdENABLE_3D */
+
+
+gceSTATUS
+gcoHAL_GetProductName(
+ IN gcoHAL Hal,
+ OUT gctSTRING *ProductName
+ );
+
+gceSTATUS
+gcoHAL_SetFscaleValue(
+ IN gctUINT FscaleValue
+ );
+
+gceSTATUS
+gcoHAL_GetFscaleValue(
+ OUT gctUINT * FscaleValue,
+ OUT gctUINT * MinFscaleValue,
+ OUT gctUINT * MaxFscaleValue
+ );
+
+gceSTATUS
+gcoHAL_SetBltNP2Texture(
+ gctBOOL enable
+ );
+
+gceSTATUS
+gcoHAL_ExportVideoMemory(
+ IN gctUINT32 Handle,
+ IN gctUINT32 Flags,
+ OUT gctINT32 * FD
+ );
+
+gceSTATUS
+gcoHAL_NameVideoMemory(
+ IN gctUINT32 Handle,
+ OUT gctUINT32 * Name
+ );
+
+gceSTATUS
+gcoHAL_ImportVideoMemory(
+ IN gctUINT32 Name,
+ OUT gctUINT32 * Handle
+ );
+
+gceSTATUS
+gcoHAL_GetVideoMemoryFd(
+ IN gctUINT32 Handle,
+ OUT gctINT * Fd
+ );
+
+/* Verify whether the specified feature is available in hardware. */
+gceSTATUS
+gcoHAL_IsFeatureAvailable(
+ IN gcoHAL Hal,
+ IN gceFEATURE Feature
+ );
+
+gceSTATUS
+gcoHAL_IsSwwaNeeded(
+ IN gcoHAL Hal,
+ IN gceSWWA Swwa
+ );
+
+gceSTATUS
+gcoHAL_IsFeatureAvailable1(
+ IN gcoHAL Hal,
+ IN gceFEATURE Feature
+ );
+
+/* Query the identity of the hardware. */
+gceSTATUS
+gcoHAL_QueryChipIdentity(
+ IN gcoHAL Hal,
+ OUT gceCHIPMODEL* ChipModel,
+ OUT gctUINT32* ChipRevision,
+ OUT gctUINT32* ChipFeatures,
+ OUT gctUINT32* ChipMinorFeatures
+ );
+
+gceSTATUS gcoHAL_QueryChipIdentityEx(
+ IN gcoHAL Hal,
+ IN gctUINT32 SizeOfParam,
+ OUT gcsHAL_CHIPIDENTITY *ChipIdentity
+ );
+
+
+gceSTATUS
+gcoHAL_QuerySuperTileMode(
+ OUT gctUINT32_PTR SuperTileMode
+ );
+
+gceSTATUS
+gcoHAL_QueryChipAxiBusWidth(
+ OUT gctBOOL * AXI128Bits
+ );
+
+gceSTATUS
+gcoHAL_QueryMultiGPUAffinityConfig(
+ IN gceHARDWARE_TYPE Type,
+ OUT gceMULTI_GPU_MODE *Mode,
+ OUT gctUINT32_PTR CoreIndex
+ );
+
+#ifdef LINUX
+gctINT32
+gcoOS_EndRecordAllocation(void);
+void
+gcoOS_RecordAllocation(void);
+void
+gcoOS_AddRecordAllocation(gctSIZE_T Size);
+#endif
+
+/* Query the amount of video memory. */
+gceSTATUS
+gcoHAL_QueryVideoMemory(
+ IN gcoHAL Hal,
+ OUT gctPHYS_ADDR * InternalAddress,
+ OUT gctSIZE_T * InternalSize,
+ OUT gctPHYS_ADDR * ExternalAddress,
+ OUT gctSIZE_T * ExternalSize,
+ OUT gctPHYS_ADDR * ContiguousAddress,
+ OUT gctSIZE_T * ContiguousSize
+ );
+
+/* Map video memory. */
+gceSTATUS
+gcoHAL_MapMemory(
+ IN gcoHAL Hal,
+ IN gctPHYS_ADDR Physical,
+ IN gctSIZE_T NumberOfBytes,
+ OUT gctPOINTER * Logical
+ );
+
+/* Unmap video memory. */
+gceSTATUS
+gcoHAL_UnmapMemory(
+ IN gcoHAL Hal,
+ IN gctPHYS_ADDR Physical,
+ IN gctSIZE_T NumberOfBytes,
+ IN gctPOINTER Logical
+ );
+
+/* Schedule an unmap of a buffer mapped through its physical address. */
+gceSTATUS
+gcoHAL_ScheduleUnmapMemory(
+ IN gcoHAL Hal,
+ IN gctPHYS_ADDR Physical,
+ IN gctSIZE_T NumberOfBytes,
+ IN gctPOINTER Logical
+ );
+
+/* Allocate video memory. */
+gceSTATUS
+gcoOS_AllocateVideoMemory(
+ IN gcoOS Os,
+ IN gctBOOL InUserSpace,
+ IN gctBOOL InCacheable,
+ IN OUT gctSIZE_T * Bytes,
+ OUT gctUINT32 * Physical,
+ OUT gctPOINTER * Logical,
+ OUT gctPOINTER * Handle
+ );
+
+/* Free video memory. */
+gceSTATUS
+gcoOS_FreeVideoMemory(
+ IN gcoOS Os,
+ IN gctPOINTER Handle
+ );
+
+/* Lock video memory. */
+gceSTATUS
+gcoOS_LockVideoMemory(
+ IN gcoOS Os,
+ IN gctPOINTER Handle,
+ IN gctBOOL InUserSpace,
+ IN gctBOOL InCacheable,
+ OUT gctUINT32 * Physical,
+ OUT gctPOINTER * Logical
+ );
+
+/* Map user memory. */
+gceSTATUS
+gcoHAL_MapUserMemory(
+ IN gctPOINTER Logical,
+ IN gctUINT32 Physical,
+ IN gctSIZE_T Size,
+ OUT gctPOINTER * Info,
+ OUT gctUINT32_PTR GPUAddress
+ );
+
+/* Unmap user memory. */
+gceSTATUS
+gcoHAL_UnmapUserMemory(
+ IN gctPOINTER Logical,
+ IN gctSIZE_T Size,
+ IN gctPOINTER Info,
+ IN gctUINT32 GPUAddress
+ );
+
+/* Schedule an unmap of a user buffer using event mechanism. */
+gceSTATUS
+gcoHAL_ScheduleUnmapUserMemory(
+ IN gcoHAL Hal,
+ IN gctPOINTER Info,
+ IN gctSIZE_T Size,
+ IN gctUINT32 Address,
+ IN gctPOINTER Memory
+ );
+
+/* Commit the current command buffer. */
+gceSTATUS
+gcoHAL_Commit(
+ IN gcoHAL Hal,
+ IN gctBOOL Stall
+ );
+
+#if gcdENABLE_3D
+/* Sencd fence command. */
+gceSTATUS
+gcoHAL_SendFence(
+ IN gcoHAL Hal
+ );
+#endif /* gcdENABLE_3D */
+
+/* Query the tile capabilities. */
+gceSTATUS
+gcoHAL_QueryTiled(
+ IN gcoHAL Hal,
+ OUT gctINT32 * TileWidth2D,
+ OUT gctINT32 * TileHeight2D,
+ OUT gctINT32 * TileWidth3D,
+ OUT gctINT32 * TileHeight3D
+ );
+
+gceSTATUS
+gcoHAL_Compact(
+ IN gcoHAL Hal
+ );
+
+#if VIVANTE_PROFILER
+gceSTATUS
+gcoHAL_ProfileStart(
+ IN gcoHAL Hal
+ );
+
+gceSTATUS
+gcoHAL_ProfileEnd(
+ IN gcoHAL Hal,
+ IN gctCONST_STRING Title
+ );
+#endif
+
+/* Power Management */
+gceSTATUS
+gcoHAL_SetPowerManagementState(
+ IN gcoHAL Hal,
+ IN gceCHIPPOWERSTATE State
+ );
+
+gceSTATUS
+gcoHAL_QueryPowerManagementState(
+ IN gcoHAL Hal,
+ OUT gceCHIPPOWERSTATE *State
+ );
+
+/* Set the filter type for filter blit. */
+gceSTATUS
+gcoHAL_SetFilterType(
+ IN gcoHAL Hal,
+ IN gceFILTER_TYPE FilterType
+ );
+
+gceSTATUS
+gcoHAL_GetDump(
+ IN gcoHAL Hal,
+ OUT gcoDUMP * Dump
+ );
+
+/* Call the kernel HAL layer. */
+gceSTATUS
+gcoHAL_Call(
+ IN gcoHAL Hal,
+ IN OUT gcsHAL_INTERFACE_PTR Interface
+ );
+
+/* Schedule an event. */
+gceSTATUS
+gcoHAL_ScheduleEvent(
+ IN gcoHAL Hal,
+ IN OUT gcsHAL_INTERFACE_PTR Interface
+ );
+
+/* Request a start/stop timestamp. */
+gceSTATUS
+gcoHAL_SetTimer(
+ IN gcoHAL Hal,
+ IN gctUINT32 Index,
+ IN gctBOOL Start
+ );
+
+/* Get Time delta from a Timer in microseconds. */
+gceSTATUS
+gcoHAL_GetTimerTime(
+ IN gcoHAL Hal,
+ IN gctUINT32 Timer,
+ OUT gctINT32_PTR TimeDelta
+ );
+
+/* set timeout value. */
+gceSTATUS
+gcoHAL_SetTimeOut(
+ IN gcoHAL Hal,
+ IN gctUINT32 timeOut
+ );
+
+gceSTATUS
+gcoHAL_SetHardwareType(
+ IN gcoHAL Hal,
+ IN gceHARDWARE_TYPE HardwardType
+ );
+
+gceSTATUS
+gcoHAL_GetHardwareType(
+ IN gcoHAL Hal,
+ OUT gceHARDWARE_TYPE * HardwardType
+ );
+
+gceSTATUS
+gcoHAL_QueryChipCount(
+ IN gcoHAL Hal,
+ OUT gctINT32 * Count
+ );
+
+gceSTATUS
+gcoHAL_Query3DCoreCount(
+ IN gcoHAL Hal,
+ OUT gctUINT32 *Count
+ );
+
+gceSTATUS
+gcoHAL_QueryCoreCount(
+ IN gcoHAL Hal,
+ IN gceHARDWARE_TYPE Type,
+ OUT gctUINT *Count,
+ OUT gctUINT_PTR ChipIDs
+ );
+
+gceSTATUS
+gcoHAL_QuerySeparated2D(
+ IN gcoHAL Hal
+ );
+
+gceSTATUS
+gcoHAL_QueryHybrid2D(
+ IN gcoHAL Hal
+ );
+
+gceSTATUS
+gcoHAL_Is3DAvailable(
+ IN gcoHAL Hal
+ );
+
+/* Get pointer to gcoVG object. */
+gceSTATUS
+gcoHAL_GetVGEngine(
+ IN gcoHAL Hal,
+ OUT gcoVG * Engine
+ );
+
+gceSTATUS
+gcoHAL_QueryChipLimits(
+ IN gcoHAL Hal,
+ IN gctINT32 Chip,
+ OUT gcsHAL_LIMITS *Limits);
+
+gceSTATUS
+gcoHAL_QueryChipFeature(
+ IN gcoHAL Hal,
+ IN gctINT32 Chip,
+ IN gceFEATURE Feature);
+
+gceSTATUS
+gcoHAL_SetCoreIndex(
+ IN gcoHAL Hal,
+ IN gctUINT32 Core
+ );
+
+gceSTATUS
+gcoHAL_GetCurrentCoreIndex(
+ IN gcoHAL Hal,
+ OUT gctUINT32 *Core
+ );
+
+/*----------------------------------------------------------------------------*/
+/*----- Shared Buffer --------------------------------------------------------*/
+
+/* Create shared buffer. */
+gceSTATUS
+gcoHAL_CreateShBuffer(
+ IN gctUINT32 Size,
+ OUT gctSHBUF * ShBuf
+ );
+
+/* Destroy shared buffer. */
+gceSTATUS
+gcoHAL_DestroyShBuffer(
+ IN gctSHBUF ShBuf
+ );
+
+/* Map shared buffer to current process. */
+gceSTATUS
+gcoHAL_MapShBuffer(
+ IN gctSHBUF ShBuf
+ );
+
+/* Write user data to shared buffer. */
+gceSTATUS
+gcoHAL_WriteShBuffer(
+ IN gctSHBUF ShBuf,
+ IN gctCONST_POINTER Data,
+ IN gctUINT32 ByteCount
+ );
+
+/* Read user data from shared buffer. */
+gceSTATUS
+gcoHAL_ReadShBuffer(
+ IN gctSHBUF ShBuf,
+ IN gctPOINTER Data,
+ IN gctUINT32 BytesCount,
+ OUT gctUINT32 * BytesRead
+ );
+
+/* Config power management to be enabled or disabled. */
+gceSTATUS
+gcoHAL_ConfigPowerManagement(
+ IN gctBOOL Enable
+ );
+
+gceSTATUS
+gcoHAL_AllocateVideoMemory(
+ IN gctUINT Alignment,
+ IN gceSURF_TYPE Type,
+ IN gctUINT32 Flag,
+ IN gcePOOL Pool,
+ IN OUT gctSIZE_T * Bytes,
+ OUT gctUINT32_PTR Node
+ );
+
+gceSTATUS
+gcoHAL_LockVideoMemory(
+ IN gctUINT32 Node,
+ IN gctBOOL Cacheable,
+ IN gceENGINE engine,
+ OUT gctUINT32 * Physical,
+ OUT gctPOINTER * Logical
+ );
+
+gceSTATUS
+gcoHAL_UnlockVideoMemory(
+ IN gctUINT32 Node,
+ IN gceSURF_TYPE Type,
+ IN gceENGINE engine
+ );
+
+gceSTATUS
+gcoHAL_ReleaseVideoMemory(
+ IN gctUINT32 Node
+ );
+
+gceSTATUS
+gcoHAL_AllocateContiguous(
+ IN gcoOS Os,
+ IN OUT gctSIZE_T * Bytes,
+ OUT gctPHYS_ADDR * Physical,
+ OUT gctPOINTER * Logical
+ );
+
+#if gcdENABLE_3D || gcdENABLE_VG
+/* Query the target capabilities. */
+gceSTATUS
+gcoHAL_QueryTargetCaps(
+ IN gcoHAL Hal,
+ OUT gctUINT * MaxWidth,
+ OUT gctUINT * MaxHeight,
+ OUT gctUINT * MultiTargetCount,
+ OUT gctUINT * MaxSamples
+ );
+#endif
+
+gceSTATUS
+gcoHAL_WrapUserMemory(
+ IN gcsUSER_MEMORY_DESC_PTR UserMemoryDesc,
+ OUT gctUINT32_PTR Node
+ );
+
+gceSTATUS
+gcoHAL_QueryResetTimeStamp(
+ OUT gctUINT64_PTR ResetTimeStamp,
+ OUT gctUINT64_PTR ContextID
+ );
+
+gceSTATUS
+gcoHAL_WaitFence(
+ IN gctUINT32 Handle,
+ IN gctUINT32 TimeOut
+ );
+
+#if gcdENABLE_2D
+gceSTATUS
+gcoHAL_AttachExternalMemory(
+ IN gcoHAL Hal,
+ IN gcsEXTERNAL_MEMORY_INFO * External,
+ OUT gctPOINTER * Handle,
+ OUT gctUINT32_PTR GPU2DAddress
+ );
+
+gceSTATUS
+gcoHAL_DetachExternalMemory(
+ IN gcoHAL Hal,
+ IN gctPOINTER * Handle
+ );
+#endif
+
+gceSTATUS
+gcoHAL_ScheduleSignal(
+ IN gctSIGNAL Signal,
+ IN gctSIGNAL AuxSignal,
+ IN gctINT ProcessID,
+ IN gceKERNEL_WHERE FromWhere
+ );
+
+gceSTATUS
+gcoHAL_GetGraphicBufferFd(
+ IN gctUINT32 Node[3],
+ IN gctSHBUF ShBuf,
+ IN gctSIGNAL Signal,
+ OUT gctINT32 * Fd
+ );
+
+gceSTATUS
+gcoHAL_AlignToTile(
+ IN OUT gctUINT32 * Width,
+ IN OUT gctUINT32 * Height,
+ IN gceSURF_TYPE Type,
+ IN gceSURF_FORMAT Format
+ );
+
+/******************************************************************************\
+********************************** gcoOS Object *********************************
+\******************************************************************************/
+/* Lock PLS access */
+gceSTATUS
+gcoOS_LockPLS(
+ void
+ );
+
+/* Unlock PLS access */
+gceSTATUS
+gcoOS_UnLockPLS(
+ void
+ );
+
+/* Get PLS value for given key */
+gctPOINTER
+gcoOS_GetPLSValue(
+ IN gcePLS_VALUE key
+ );
+
+/* Set PLS value of a given key */
+void
+gcoOS_SetPLSValue(
+ IN gcePLS_VALUE key,
+ OUT gctPOINTER value
+ );
+
+/* Lock GL FE compiler access */
+gceSTATUS
+gcoOS_LockGLFECompiler(
+ void
+ );
+
+/* Unlock GL FE compiler access */
+gceSTATUS
+gcoOS_UnLockGLFECompiler(
+ void
+ );
+
+/* Lock CL FE compiler access */
+gceSTATUS
+gcoOS_LockCLFECompiler(
+ void
+ );
+
+/* Unlock CL FE compiler access */
+gceSTATUS
+gcoOS_UnLockCLFECompiler(
+ void
+ );
+
+gceSTATUS
+gcoOS_GetTLS(
+ OUT gcsTLS_PTR * TLS
+ );
+
+/* Copy the TLS from a source thread. */
+gceSTATUS
+gcoOS_CopyTLS(
+ IN gcsTLS_PTR Source
+ );
+
+/* Query the thread local storage. */
+gceSTATUS
+gcoOS_QueryTLS(
+ OUT gcsTLS_PTR * TLS
+ );
+
+/* Get access to driver tls. */
+gceSTATUS
+gcoOS_GetDriverTLS(
+ IN gceTLS_KEY Key,
+ OUT gcsDRIVER_TLS_PTR * TLS
+ );
+
+/*
+ * Set driver tls.
+ * May cause memory leak if 'destructor' not set.
+ */
+gceSTATUS
+gcoOS_SetDriverTLS(
+ IN gceTLS_KEY Key,
+ IN gcsDRIVER_TLS * TLS
+ );
+
+/* Destroy the objects associated with the current thread. */
+void
+gcoOS_FreeThreadData(
+ void
+ );
+
+/* Empty function for compatibility. */
+gceSTATUS
+gcoOS_Construct(
+ IN gctPOINTER Context,
+ OUT gcoOS * Os
+ );
+
+/* Empty function for compatibility. */
+gceSTATUS
+gcoOS_Destroy(
+ IN gcoOS Os
+ );
+
+/* Get the base address for the physical memory. */
+gceSTATUS
+gcoOS_GetBaseAddress(
+ IN gcoOS Os,
+ OUT gctUINT32_PTR BaseAddress
+ );
+
+/* Allocate memory from the heap. */
+gceSTATUS
+gcoOS_Allocate(
+ IN gcoOS Os,
+ IN gctSIZE_T Bytes,
+ OUT gctPOINTER * Memory
+ );
+
+/* Get allocated memory size. */
+gceSTATUS
+gcoOS_GetMemorySize(
+ IN gcoOS Os,
+ IN gctPOINTER Memory,
+ OUT gctSIZE_T_PTR MemorySize
+ );
+
+/* Free allocated memory. */
+gceSTATUS
+gcoOS_Free(
+ IN gcoOS Os,
+ IN gctPOINTER Memory
+ );
+
+/* Allocate memory. */
+gceSTATUS
+gcoOS_AllocateSharedMemory(
+ IN gcoOS Os,
+ IN gctSIZE_T Bytes,
+ OUT gctPOINTER * Memory
+ );
+
+/* Free memory. */
+gceSTATUS
+gcoOS_FreeSharedMemory(
+ IN gcoOS Os,
+ IN gctPOINTER Memory
+ );
+
+/* Allocate memory. */
+gceSTATUS
+gcoOS_AllocateMemory(
+ IN gcoOS Os,
+ IN gctSIZE_T Bytes,
+ OUT gctPOINTER * Memory
+ );
+
+/* Free memory. */
+gceSTATUS
+gcoOS_FreeMemory(
+ IN gcoOS Os,
+ IN gctPOINTER Memory
+ );
+
+/* Free contiguous memory. */
+gceSTATUS
+gcoOS_FreeContiguous(
+ IN gcoOS Os,
+ IN gctPHYS_ADDR Physical,
+ IN gctPOINTER Logical,
+ IN gctSIZE_T Bytes
+ );
+
+/* Map user memory. */
+gceSTATUS
+gcoOS_MapUserMemory(
+ IN gcoOS Os,
+ IN gctPOINTER Memory,
+ IN gctSIZE_T Size,
+ OUT gctPOINTER * Info,
+ OUT gctUINT32_PTR Address
+ );
+
+/* Map user memory. */
+gceSTATUS
+gcoOS_MapUserMemoryEx(
+ IN gcoOS Os,
+ IN gctPOINTER Memory,
+ IN gctUINT32 Physical,
+ IN gctSIZE_T Size,
+ OUT gctPOINTER * Info,
+ OUT gctUINT32_PTR Address
+ );
+
+/* Unmap user memory. */
+gceSTATUS
+gcoOS_UnmapUserMemory(
+ IN gcoOS Os,
+ IN gctPOINTER Memory,
+ IN gctSIZE_T Size,
+ IN gctPOINTER Info,
+ IN gctUINT32 Address
+ );
+
+gceSTATUS
+gcoOS_CPUPhysicalToGPUPhysical(
+ IN gctUINT32 CPUPhysical,
+ OUT gctUINT32_PTR GPUPhysical
+ );
+
+/* Device I/O Control call to the kernel HAL layer. */
+gceSTATUS
+gcoOS_DeviceControl(
+ IN gcoOS Os,
+ IN gctUINT32 IoControlCode,
+ IN gctPOINTER InputBuffer,
+ IN gctSIZE_T InputBufferSize,
+ IN gctPOINTER OutputBuffer,
+ IN gctSIZE_T OutputBufferSize
+ );
+
+/* Allocate non paged memory. */
+gceSTATUS
+gcoOS_AllocateNonPagedMemory(
+ IN gcoOS Os,
+ IN gctBOOL InUserSpace,
+ IN OUT gctSIZE_T * Bytes,
+ OUT gctPHYS_ADDR * Physical,
+ OUT gctPOINTER * Logical
+ );
+
+/* Free non paged memory. */
+gceSTATUS
+gcoOS_FreeNonPagedMemory(
+ IN gcoOS Os,
+ IN gctSIZE_T Bytes,
+ IN gctPHYS_ADDR Physical,
+ IN gctPOINTER Logical
+ );
+
+#define gcmOS_SAFE_FREE(os, mem) \
+ gcoOS_Free(os, mem); \
+ mem = gcvNULL
+
+#define gcmOS_SAFE_FREE_SHARED_MEMORY(os, mem) \
+ gcoOS_FreeSharedMemory(os, mem); \
+ mem = gcvNULL
+
+#define gcmkOS_SAFE_FREE(os, mem) \
+ gckOS_Free(os, mem); \
+ mem = gcvNULL
+
+#define gcdMAX_PATH 512
+
+typedef enum _gceFILE_MODE
+{
+ gcvFILE_CREATE = 0,
+ gcvFILE_APPEND,
+ gcvFILE_READ,
+ gcvFILE_CREATETEXT,
+ gcvFILE_APPENDTEXT,
+ gcvFILE_READTEXT,
+}
+gceFILE_MODE;
+
+/* Open a file. */
+gceSTATUS
+gcoOS_Open(
+ IN gcoOS Os,
+ IN gctCONST_STRING FileName,
+ IN gceFILE_MODE Mode,
+ OUT gctFILE * File
+ );
+
+/* Close a file. */
+gceSTATUS
+gcoOS_Close(
+ IN gcoOS Os,
+ IN gctFILE File
+ );
+
+/* Read data from a file. */
+gceSTATUS
+gcoOS_Read(
+ IN gcoOS Os,
+ IN gctFILE File,
+ IN gctSIZE_T ByteCount,
+ IN gctPOINTER Data,
+ OUT gctSIZE_T * ByteRead
+ );
+
+/* Write data to a file. */
+gceSTATUS
+gcoOS_Write(
+ IN gcoOS Os,
+ IN gctFILE File,
+ IN gctSIZE_T ByteCount,
+ IN gctCONST_POINTER Data
+ );
+
+/* Flush data to a file. */
+gceSTATUS
+gcoOS_Flush(
+ IN gcoOS Os,
+ IN gctFILE File
+ );
+
+/* Close a file descriptor. */
+gceSTATUS
+gcoOS_CloseFD(
+ IN gcoOS Os,
+ IN gctINT FD
+ );
+
+/* Scan a file. */
+gceSTATUS
+gcoOS_FscanfI(
+ IN gcoOS Os,
+ IN gctFILE File,
+ IN gctCONST_STRING Format,
+ OUT gctUINT *result
+ );
+
+/* Dup file descriptor to another. */
+gceSTATUS
+gcoOS_DupFD(
+ IN gcoOS Os,
+ IN gctINT FD,
+ OUT gctINT * FD2
+ );
+
+/* Create an endpoint for communication. */
+gceSTATUS
+gcoOS_Socket(
+ IN gcoOS Os,
+ IN gctINT Domain,
+ IN gctINT Type,
+ IN gctINT Protocol,
+ OUT gctINT *SockFd
+ );
+
+/* Close a socket. */
+gceSTATUS
+gcoOS_CloseSocket(
+ IN gcoOS Os,
+ IN gctINT SockFd
+ );
+
+/* Initiate a connection on a socket. */
+gceSTATUS
+gcoOS_Connect(
+ IN gcoOS Os,
+ IN gctINT SockFd,
+ IN gctCONST_POINTER HostName,
+ IN gctUINT Port);
+
+/* Shut down part of connection on a socket. */
+gceSTATUS
+gcoOS_Shutdown(
+ IN gcoOS Os,
+ IN gctINT SockFd,
+ IN gctINT How
+ );
+
+/* Send a message on a socket. */
+gceSTATUS
+gcoOS_Send(
+ IN gcoOS Os,
+ IN gctINT SockFd,
+ IN gctSIZE_T ByteCount,
+ IN gctCONST_POINTER Data,
+ IN gctINT Flags
+ );
+
+/* Initiate a connection on a socket. */
+gceSTATUS
+gcoOS_WaitForSend(
+ IN gcoOS Os,
+ IN gctINT SockFd,
+ IN gctINT Seconds,
+ IN gctINT MicroSeconds);
+
+/* Get environment variable value. */
+gceSTATUS
+gcoOS_GetEnv(
+ IN gcoOS Os,
+ IN gctCONST_STRING VarName,
+ OUT gctSTRING * Value
+ );
+
+/* Set environment variable value. */
+gceSTATUS
+gcoOS_SetEnv(
+ IN gcoOS Os,
+ IN gctCONST_STRING VarName,
+ IN gctSTRING Value
+ );
+
+/* Get current working directory. */
+gceSTATUS
+gcoOS_GetCwd(
+ IN gcoOS Os,
+ IN gctINT SizeInBytes,
+ OUT gctSTRING Buffer
+ );
+
+/* Get file status info. */
+gceSTATUS
+gcoOS_Stat(
+ IN gcoOS Os,
+ IN gctCONST_STRING FileName,
+ OUT gctPOINTER Buffer
+ );
+
+typedef enum _gceFILE_WHENCE
+{
+ gcvFILE_SEEK_SET,
+ gcvFILE_SEEK_CUR,
+ gcvFILE_SEEK_END
+}
+gceFILE_WHENCE;
+
+/* Set the current position of a file. */
+gceSTATUS
+gcoOS_Seek(
+ IN gcoOS Os,
+ IN gctFILE File,
+ IN gctUINT32 Offset,
+ IN gceFILE_WHENCE Whence
+ );
+
+/* Set the current position of a file. */
+gceSTATUS
+gcoOS_SetPos(
+ IN gcoOS Os,
+ IN gctFILE File,
+ IN gctUINT32 Position
+ );
+
+/* Get the current position of a file. */
+gceSTATUS
+gcoOS_GetPos(
+ IN gcoOS Os,
+ IN gctFILE File,
+ OUT gctUINT32 * Position
+ );
+
+/* Same as strstr. */
+gceSTATUS
+gcoOS_StrStr(
+ IN gctCONST_STRING String,
+ IN gctCONST_STRING SubString,
+ OUT gctSTRING * Output
+ );
+
+/* Find the last occurance of a character inside a string. */
+gceSTATUS
+gcoOS_StrFindReverse(
+ IN gctCONST_STRING String,
+ IN gctINT8 Character,
+ OUT gctSTRING * Output
+ );
+
+gceSTATUS
+gcoOS_StrDup(
+ IN gcoOS Os,
+ IN gctCONST_STRING String,
+ OUT gctSTRING * Target
+ );
+
+/* Copy a string. */
+gceSTATUS
+gcoOS_StrCopySafe(
+ IN gctSTRING Destination,
+ IN gctSIZE_T DestinationSize,
+ IN gctCONST_STRING Source
+ );
+
+/* Append a string. */
+gceSTATUS
+gcoOS_StrCatSafe(
+ IN gctSTRING Destination,
+ IN gctSIZE_T DestinationSize,
+ IN gctCONST_STRING Source
+ );
+
+/* Compare two strings. */
+gceSTATUS
+gcoOS_StrCmp(
+ IN gctCONST_STRING String1,
+ IN gctCONST_STRING String2
+ );
+
+/* Compare characters of two strings. */
+gceSTATUS
+gcoOS_StrNCmp(
+ IN gctCONST_STRING String1,
+ IN gctCONST_STRING String2,
+ IN gctSIZE_T Count
+ );
+
+/* Convert string to float. */
+gceSTATUS
+gcoOS_StrToFloat(
+ IN gctCONST_STRING String,
+ OUT gctFLOAT * Float
+ );
+
+/* Convert hex string to integer. */
+gceSTATUS gcoOS_HexStrToInt(
+ IN gctCONST_STRING String,
+ OUT gctINT * Int
+ );
+
+/* Convert hex string to float. */
+gceSTATUS
+gcoOS_HexStrToFloat(
+ IN gctCONST_STRING String,
+ OUT gctFLOAT * Float
+ );
+
+/* Convert string to integer. */
+gceSTATUS
+gcoOS_StrToInt(
+ IN gctCONST_STRING String,
+ OUT gctINT * Int
+ );
+
+gceSTATUS
+gcoOS_MemCmp(
+ IN gctCONST_POINTER Memory1,
+ IN gctCONST_POINTER Memory2,
+ IN gctSIZE_T Bytes
+ );
+
+gceSTATUS
+gcoOS_PrintStrSafe(
+ OUT gctSTRING String,
+ IN gctSIZE_T StringSize,
+ IN OUT gctUINT * Offset,
+ IN gctCONST_STRING Format,
+ ...
+ );
+
+gceSTATUS
+gcoOS_LoadLibrary(
+ IN gcoOS Os,
+ IN gctCONST_STRING Library,
+ OUT gctHANDLE * Handle
+ );
+
+gceSTATUS
+gcoOS_FreeLibrary(
+ IN gcoOS Os,
+ IN gctHANDLE Handle
+ );
+
+gceSTATUS
+gcoOS_GetProcAddress(
+ IN gcoOS Os,
+ IN gctHANDLE Handle,
+ IN gctCONST_STRING Name,
+ OUT gctPOINTER * Function
+ );
+
+gceSTATUS
+gcoOS_Compact(
+ IN gcoOS Os
+ );
+
+gceSTATUS
+gcoOS_AddSignalHandler (
+ IN gceSignalHandlerType SignalHandlerType
+ );
+
+#if VIVANTE_PROFILER
+gceSTATUS
+gcoOS_ProfileStart(
+ IN gcoOS Os
+ );
+
+gceSTATUS
+gcoOS_ProfileEnd(
+ IN gcoOS Os,
+ IN gctCONST_STRING Title
+ );
+
+gceSTATUS
+gcoOS_SetProfileSetting(
+ IN gcoOS Os,
+ IN gctBOOL Enable,
+ IN gctCONST_STRING FileName
+ );
+#endif
+
+/* Get the amount of physical system memory */
+gceSTATUS
+gcoOS_GetPhysicalSystemMemorySize(
+ OUT gctSIZE_T * PhysicalSystemMemorySize
+ );
+
+/* Query the video memory. */
+gceSTATUS
+gcoOS_QueryVideoMemory(
+ IN gcoOS Os,
+ OUT gctPHYS_ADDR * InternalAddress,
+ OUT gctSIZE_T * InternalSize,
+ OUT gctPHYS_ADDR * ExternalAddress,
+ OUT gctSIZE_T * ExternalSize,
+ OUT gctPHYS_ADDR * ContiguousAddress,
+ OUT gctSIZE_T * ContiguousSize
+ );
+
+gceSTATUS
+gcoOS_QueryCurrentProcessName(
+ OUT gctSTRING Name,
+ IN gctSIZE_T Size
+ );
+
+
+/*----------------------------------------------------------------------------*/
+/*----- Atoms ----------------------------------------------------------------*/
+
+/* Construct an atom. */
+gceSTATUS
+gcoOS_AtomConstruct(
+ IN gcoOS Os,
+ OUT gcsATOM_PTR * Atom
+ );
+
+/* Destroy an atom. */
+gceSTATUS
+gcoOS_AtomDestroy(
+ IN gcoOS Os,
+ IN gcsATOM_PTR Atom
+ );
+
+/* Get the 32-bit value protected by an atom. */
+gceSTATUS
+gcoOS_AtomGet(
+ IN gcoOS Os,
+ IN gcsATOM_PTR Atom,
+ OUT gctINT32_PTR Value
+ );
+
+/* Set the 32-bit value protected by an atom. */
+gceSTATUS
+gcoOS_AtomSet(
+ IN gcoOS Os,
+ IN gcsATOM_PTR Atom,
+ IN gctINT32 Value
+ );
+
+/* Increment an atom. */
+gceSTATUS
+gcoOS_AtomIncrement(
+ IN gcoOS Os,
+ IN gcsATOM_PTR Atom,
+ OUT gctINT32_PTR OldValue
+ );
+
+/* Decrement an atom. */
+gceSTATUS
+gcoOS_AtomDecrement(
+ IN gcoOS Os,
+ IN gcsATOM_PTR Atom,
+ OUT gctINT32_PTR OldValue
+ );
+
+gctHANDLE
+gcoOS_GetCurrentProcessID(
+ void
+ );
+
+gctHANDLE
+gcoOS_GetCurrentThreadID(
+ void
+ );
+
+/*----------------------------------------------------------------------------*/
+/*----- Time -----------------------------------------------------------------*/
+
+/* Get the number of milliseconds since the system started. */
+gctUINT32
+gcoOS_GetTicks(
+ void
+ );
+
+/* Get time in microseconds. */
+gceSTATUS
+gcoOS_GetTime(
+ gctUINT64_PTR Time
+ );
+
+/* Get CPU usage in microseconds. */
+gceSTATUS
+gcoOS_GetCPUTime(
+ gctUINT64_PTR CPUTime
+ );
+
+/* Get memory usage. */
+gceSTATUS
+gcoOS_GetMemoryUsage(
+ gctUINT32_PTR MaxRSS,
+ gctUINT32_PTR IxRSS,
+ gctUINT32_PTR IdRSS,
+ gctUINT32_PTR IsRSS
+ );
+
+/* Delay a number of microseconds. */
+gceSTATUS
+gcoOS_Delay(
+ IN gcoOS Os,
+ IN gctUINT32 Delay
+ );
+
+/*----------------------------------------------------------------------------*/
+/*----- Threads --------------------------------------------------------------*/
+
+#ifdef _WIN32
+/* Cannot include windows.h here becuase "near" and "far"
+ * which are used in gcsDEPTH_INFO, are defined to nothing in WinDef.h.
+ * So, use the real value of DWORD and WINAPI, instead.
+ * DWORD is unsigned long, and WINAPI is __stdcall.
+ * If these two are change in WinDef.h, the following two typdefs
+ * need to be changed, too.
+ */
+typedef unsigned long gctTHREAD_RETURN;
+typedef unsigned long (__stdcall * gcTHREAD_ROUTINE)(void * Argument);
+#else
+typedef void * gctTHREAD_RETURN;
+typedef void * (* gcTHREAD_ROUTINE)(void *);
+#endif
+
+/* Create a new thread. */
+gceSTATUS
+gcoOS_CreateThread(
+ IN gcoOS Os,
+ IN gcTHREAD_ROUTINE Worker,
+ IN gctPOINTER Argument,
+ OUT gctPOINTER * Thread
+ );
+
+/* Close a thread. */
+gceSTATUS
+gcoOS_CloseThread(
+ IN gcoOS Os,
+ IN gctPOINTER Thread
+ );
+
+/*----------------------------------------------------------------------------*/
+/*----- Mutexes --------------------------------------------------------------*/
+
+/* Create a new mutex. */
+gceSTATUS
+gcoOS_CreateMutex(
+ IN gcoOS Os,
+ OUT gctPOINTER * Mutex
+ );
+
+/* Delete a mutex. */
+gceSTATUS
+gcoOS_DeleteMutex(
+ IN gcoOS Os,
+ IN gctPOINTER Mutex
+ );
+
+/* Acquire a mutex. */
+gceSTATUS
+gcoOS_AcquireMutex(
+ IN gcoOS Os,
+ IN gctPOINTER Mutex,
+ IN gctUINT32 Timeout
+ );
+
+/* Release a mutex. */
+gceSTATUS
+gcoOS_ReleaseMutex(
+ IN gcoOS Os,
+ IN gctPOINTER Mutex
+ );
+
+/*----------------------------------------------------------------------------*/
+/*----- Signals --------------------------------------------------------------*/
+
+/* Create a signal. */
+gceSTATUS
+gcoOS_CreateSignal(
+ IN gcoOS Os,
+ IN gctBOOL ManualReset,
+ OUT gctSIGNAL * Signal
+ );
+
+/* Destroy a signal. */
+gceSTATUS
+gcoOS_DestroySignal(
+ IN gcoOS Os,
+ IN gctSIGNAL Signal
+ );
+
+/* Signal a signal. */
+gceSTATUS
+gcoOS_Signal(
+ IN gcoOS Os,
+ IN gctSIGNAL Signal,
+ IN gctBOOL State
+ );
+
+/* Wait for a signal. */
+gceSTATUS
+gcoOS_WaitSignal(
+ IN gcoOS Os,
+ IN gctSIGNAL Signal,
+ IN gctUINT32 Wait
+ );
+
+/* Map a signal from another process */
+gceSTATUS
+gcoOS_MapSignal(
+ IN gctSIGNAL RemoteSignal,
+ OUT gctSIGNAL * LocalSignal
+ );
+
+/* Unmap a signal mapped from another process */
+gceSTATUS
+gcoOS_UnmapSignal(
+ IN gctSIGNAL Signal
+ );
+
+/*----------------------------------------------------------------------------*/
+/*----- Android Native Fence -------------------------------------------------*/
+
+/* Create native fence. */
+gceSTATUS
+gcoOS_CreateNativeFence(
+ IN gcoOS Os,
+ IN gctSIGNAL Signal,
+ OUT gctINT * FenceFD
+ );
+
+/* (CPU) Wait on native fence. */
+gceSTATUS
+gcoOS_ClientWaitNativeFence(
+ IN gcoOS Os,
+ IN gctINT FenceFD,
+ IN gctUINT32 Timeout
+ );
+
+/* (GPU) Wait on native fence. */
+gceSTATUS
+gcoOS_WaitNativeFence(
+ IN gcoOS Os,
+ IN gctINT FenceFD,
+ IN gctUINT32 Timeout
+ );
+
+/*----------------------------------------------------------------------------*/
+/*----- Memory Access and Cache ----------------------------------------------*/
+
+/* Write a register. */
+gceSTATUS
+gcoOS_WriteRegister(
+ IN gcoOS Os,
+ IN gctUINT32 Address,
+ IN gctUINT32 Data
+ );
+
+/* Read a register. */
+gceSTATUS
+gcoOS_ReadRegister(
+ IN gcoOS Os,
+ IN gctUINT32 Address,
+ OUT gctUINT32 * Data
+ );
+
+gceSTATUS
+gcoOS_CacheClean(
+ IN gcoOS Os,
+ IN gctUINT32 Node,
+ IN gctPOINTER Logical,
+ IN gctSIZE_T Bytes
+ );
+
+gceSTATUS
+gcoOS_CacheFlush(
+ IN gcoOS Os,
+ IN gctUINT32 Node,
+ IN gctPOINTER Logical,
+ IN gctSIZE_T Bytes
+ );
+
+gceSTATUS
+gcoOS_CacheInvalidate(
+ IN gcoOS Os,
+ IN gctUINT32 Node,
+ IN gctPOINTER Logical,
+ IN gctSIZE_T Bytes
+ );
+
+gceSTATUS
+gcoOS_MemoryBarrier(
+ IN gcoOS Os,
+ IN gctPOINTER Logical
+ );
+
+gceSTATUS
+gcoOS_CPUPhysicalToGPUPhysical(
+ IN gctUINT32 CPUPhysical,
+ OUT gctUINT32_PTR GPUPhysical
+ );
+
+gceSTATUS
+gcoOS_QuerySystemInfo(
+ IN gcoOS Os,
+ OUT gcsSystemInfo *Info
+ );
+
+/*----------------------------------------------------------------------------*/
+/*----- Profile --------------------------------------------------------------*/
+
+gceSTATUS
+gckOS_GetProfileTick(
+ OUT gctUINT64_PTR Tick
+ );
+
+gceSTATUS
+gckOS_QueryProfileTickRate(
+ OUT gctUINT64_PTR TickRate
+ );
+
+gctUINT32
+gckOS_ProfileToMS(
+ IN gctUINT64 Ticks
+ );
+
+gceSTATUS
+gcoOS_GetProfileTick(
+ OUT gctUINT64_PTR Tick
+ );
+
+gceSTATUS
+gcoOS_QueryProfileTickRate(
+ OUT gctUINT64_PTR TickRate
+ );
+
+#define _gcmPROFILE_INIT(prefix, freq, start) \
+ do { \
+ prefix ## OS_QueryProfileTickRate(&(freq)); \
+ prefix ## OS_GetProfileTick(&(start)); \
+ } while (gcvFALSE)
+
+#define _gcmPROFILE_QUERY(prefix, start, ticks) \
+ do { \
+ prefix ## OS_GetProfileTick(&(ticks)); \
+ (ticks) = ((ticks) > (start)) ? ((ticks) - (start)) \
+ : (~0ull - (start) + (ticks) + 1); \
+ } while (gcvFALSE)
+
+#if gcdENABLE_PROFILING
+# define gcmkPROFILE_INIT(freq, start) _gcmPROFILE_INIT(gck, freq, start)
+# define gcmkPROFILE_QUERY(start, ticks) _gcmPROFILE_QUERY(gck, start, ticks)
+# define gcmPROFILE_INIT(freq, start) _gcmPROFILE_INIT(gco, freq, start)
+# define gcmPROFILE_QUERY(start, ticks) _gcmPROFILE_QUERY(gco, start, ticks)
+# define gcmPROFILE_ONLY(x) x
+# define gcmPROFILE_ELSE(x) do { } while (gcvFALSE)
+# define gcmPROFILE_DECLARE_ONLY(x) x
+# define gcmPROFILE_DECLARE_ELSE(x) typedef x
+#else
+# define gcmkPROFILE_INIT(start, freq) do { } while (gcvFALSE)
+# define gcmkPROFILE_QUERY(start, ticks) do { } while (gcvFALSE)
+# define gcmPROFILE_INIT(start, freq) do { } while (gcvFALSE)
+# define gcmPROFILE_QUERY(start, ticks) do { } while (gcvFALSE)
+# define gcmPROFILE_ONLY(x) do { } while (gcvFALSE)
+# define gcmPROFILE_ELSE(x) x
+# define gcmPROFILE_DECLARE_ONLY(x) do { } while (gcvFALSE)
+# define gcmPROFILE_DECLARE_ELSE(x) x
+#endif
+
+/*******************************************************************************
+** gcoMATH object
+*/
+
+#define gcdPI 3.14159265358979323846f
+
+/* Kernel. */
+gctINT
+gckMATH_ModuloInt(
+ IN gctINT X,
+ IN gctINT Y
+ );
+
+/* User. */
+gctUINT32
+gcoMATH_Log2in5dot5(
+ IN gctINT X
+ );
+
+
+gctFLOAT
+gcoMATH_UIntAsFloat(
+ IN gctUINT32 X
+ );
+
+gctUINT32
+gcoMATH_FloatAsUInt(
+ IN gctFLOAT X
+ );
+
+gctBOOL
+gcoMATH_CompareEqualF(
+ IN gctFLOAT X,
+ IN gctFLOAT Y
+ );
+
+gctUINT16
+gcoMATH_UInt8AsFloat16(
+ IN gctUINT8 X
+ );
+
+gctUINT32
+gcoMATH_Float16ToFloat(
+ IN gctUINT16 In
+ );
+
+gctUINT16
+gcoMATH_FloatToFloat16(
+ IN gctUINT32 In
+ );
+
+gctUINT32
+gcoMATH_Float11ToFloat(
+ IN gctUINT32 In
+ );
+
+gctUINT16
+gcoMATH_FloatToFloat11(
+ IN gctUINT32 In
+ );
+
+gctUINT32
+gcoMATH_Float10ToFloat(
+ IN gctUINT32 In
+ );
+
+gctUINT16
+gcoMATH_FloatToFloat10(
+ IN gctUINT32 In
+ );
+
+gctUINT32
+gcoMATH_Float14ToFloat(
+ IN gctUINT16 In
+ );
+
+/******************************************************************************\
+**************************** Coordinate Structures *****************************
+\******************************************************************************/
+
+typedef struct _gcsPOINT
+{
+ gctINT32 x;
+ gctINT32 y;
+}
+gcsPOINT;
+
+typedef struct _gcsSIZE
+{
+ gctINT32 width;
+ gctINT32 height;
+}
+gcsSIZE;
+
+typedef struct _gcsRECT
+{
+ gctINT32 left;
+ gctINT32 top;
+ gctINT32 right;
+ gctINT32 bottom;
+}
+gcsRECT;
+
+typedef struct _gcsPIXEL
+{
+ union
+ {
+ struct
+ {
+ gctFLOAT r, g, b, a;
+ } f;
+ struct
+ {
+ gctINT32 r, g, b, a;
+ } i;
+ struct
+ {
+ gctUINT32 r, g, b, a;
+ } ui;
+ } color;
+
+ gctFLOAT d;
+ gctUINT32 s;
+
+} gcsPIXEL;
+
+/******************************************************************************\
+********************************* gcoSURF Object ********************************
+\******************************************************************************/
+
+/*----------------------------------------------------------------------------*/
+/*------------------------------- gcoSURF Common ------------------------------*/
+
+/* Color format classes. */
+typedef enum _gceFORMAT_CLASS
+{
+ gcvFORMAT_CLASS_RGBA = 4500,
+ gcvFORMAT_CLASS_YUV,
+ gcvFORMAT_CLASS_INDEX,
+ gcvFORMAT_CLASS_LUMINANCE,
+ gcvFORMAT_CLASS_BUMP,
+ gcvFORMAT_CLASS_DEPTH,
+ gcvFORMAT_CLASS_ASTC,
+ gcvFORMAT_CLASS_COMPRESSED,
+ gcvFORMAT_CLASS_OTHER
+}
+gceFORMAT_CLASS;
+
+/* Color format data type */
+typedef enum _gceFORMAT_DATATYPE
+{
+ gcvFORMAT_DATATYPE_UNSIGNED_NORMALIZED,
+ gcvFORMAT_DATATYPE_SIGNED_NORMALIZED,
+ gcvFORMAT_DATATYPE_UNSIGNED_INTEGER,
+ gcvFORMAT_DATATYPE_SIGNED_INTEGER,
+ gcvFORMAT_DATATYPE_FLOAT16,
+ gcvFORMAT_DATATYPE_FLOAT32,
+ gcvFORMAT_DATATYPE_FLOAT_E5B9G9R9,
+ gcvFORMAT_DATATYPE_FLOAT_B10G11R11F,
+ gcvFORMAT_DATATYPE_INDEX,
+ gcvFORMAT_DATATYPE_SRGB,
+ gcvFORMAT_DATATYPE_FLOAT32_UINT,
+}
+gceFORMAT_DATATYPE;
+
+/* Special enums for width field in gcsFORMAT_COMPONENT. */
+typedef enum _gceCOMPONENT_CONTROL
+{
+ gcvCOMPONENT_NOTPRESENT = 0x00,
+ gcvCOMPONENT_DONTCARE = 0x80,
+ gcvCOMPONENT_WIDTHMASK = 0x7F,
+ gcvCOMPONENT_ODD = 0x80
+}
+gceCOMPONENT_CONTROL;
+
+/* Color format component parameters. */
+typedef struct _gcsFORMAT_COMPONENT
+{
+ gctUINT8 start;
+ gctUINT8 width;
+}
+gcsFORMAT_COMPONENT;
+
+/* RGBA color format class. */
+typedef struct _gcsFORMAT_CLASS_TYPE_RGBA
+{
+ gcsFORMAT_COMPONENT alpha;
+ gcsFORMAT_COMPONENT red;
+ gcsFORMAT_COMPONENT green;
+ gcsFORMAT_COMPONENT blue;
+}
+gcsFORMAT_CLASS_TYPE_RGBA;
+
+/* YUV color format class. */
+typedef struct _gcsFORMAT_CLASS_TYPE_YUV
+{
+ gcsFORMAT_COMPONENT y;
+ gcsFORMAT_COMPONENT u;
+ gcsFORMAT_COMPONENT v;
+}
+gcsFORMAT_CLASS_TYPE_YUV;
+
+/* Index color format class. */
+typedef struct _gcsFORMAT_CLASS_TYPE_INDEX
+{
+ gcsFORMAT_COMPONENT value;
+}
+gcsFORMAT_CLASS_TYPE_INDEX;
+
+/* Luminance color format class. */
+typedef struct _gcsFORMAT_CLASS_TYPE_LUMINANCE
+{
+ gcsFORMAT_COMPONENT alpha;
+ gcsFORMAT_COMPONENT value;
+}
+gcsFORMAT_CLASS_TYPE_LUMINANCE;
+
+/* Bump map color format class. */
+typedef struct _gcsFORMAT_CLASS_TYPE_BUMP
+{
+ gcsFORMAT_COMPONENT alpha;
+ gcsFORMAT_COMPONENT l;
+ gcsFORMAT_COMPONENT v;
+ gcsFORMAT_COMPONENT u;
+ gcsFORMAT_COMPONENT q;
+ gcsFORMAT_COMPONENT w;
+}
+gcsFORMAT_CLASS_TYPE_BUMP;
+
+/* Depth and stencil format class. */
+typedef struct _gcsFORMAT_CLASS_TYPE_DEPTH
+{
+ gcsFORMAT_COMPONENT depth;
+ gcsFORMAT_COMPONENT stencil;
+}
+gcsFORMAT_CLASS_TYPE_DEPTH;
+
+typedef union _gcuPIXEL_FORMAT_CLASS
+{
+ gcsFORMAT_CLASS_TYPE_BUMP bump;
+ gcsFORMAT_CLASS_TYPE_RGBA rgba;
+ gcsFORMAT_CLASS_TYPE_YUV yuv;
+ gcsFORMAT_CLASS_TYPE_LUMINANCE lum;
+ gcsFORMAT_CLASS_TYPE_INDEX index;
+ gcsFORMAT_CLASS_TYPE_DEPTH depth;
+}
+gcuPIXEL_FORMAT_CLASS;
+
+/* Format parameters. */
+typedef struct _gcsSURF_FORMAT_INFO
+{
+ /* Name of the format */
+ gctCONST_STRING formatName;
+
+ /* Format code and class. */
+ gceSURF_FORMAT format;
+ gceFORMAT_CLASS fmtClass;
+
+ /* Format data type */
+ gceFORMAT_DATATYPE fmtDataType;
+
+ /* The size of one pixel in bits. */
+ gctUINT8 bitsPerPixel;
+
+ /* Pixel block dimensions. */
+ gctUINT blockWidth;
+ gctUINT blockHeight;
+
+ /* Pixel block size in bits. */
+ gctUINT blockSize;
+
+ /* Some formats are larger than what the GPU can support. */
+ /* These formats are read in the number of layers specified. */
+ gctUINT8 layers;
+
+ /* The format is faked and software will interpret it differently
+ ** with HW. Most of them can't be blendable(PE) or filterable(TX).
+ */
+ gctBOOL fakedFormat;
+
+ /* Some formats have two neighbour pixels interleaved together. */
+ /* To describe such format, set the flag to 1 and add another */
+ /* like this one describing the odd pixel format. */
+ gctBOOL interleaved;
+
+ /* sRGB format. */
+ gctBOOL sRGB;
+
+ /* How GPU read from big-endian host memory */
+ gceENDIAN_HINT endian;
+
+ /* Format components. */
+ gcuPIXEL_FORMAT_CLASS u;
+
+ /* Format components. */
+ gcuPIXEL_FORMAT_CLASS uOdd;
+
+ /* Render format. */
+ gceSURF_FORMAT closestRenderFormat;
+ /*gctCLOSEST_FORMAT dynamicClosestRenderFormat;*/
+ gctUINT renderFormat;
+ const gceTEXTURE_SWIZZLE * pixelSwizzle;
+
+ /* Texture format. */
+ gceSURF_FORMAT closestTXFormat;
+ gctUINT txFormat;
+ const gceTEXTURE_SWIZZLE * txSwizzle;
+ gctBOOL txIntFilter;
+}
+gcsSURF_FORMAT_INFO;
+
+/* Frame buffer information. */
+typedef struct _gcsSURF_FRAMEBUFFER
+{
+ gctPOINTER logical;
+ gctUINT width, height;
+ gctINT stride;
+ gceSURF_FORMAT format;
+}
+gcsSURF_FRAMEBUFFER;
+
+/* Generic pixel component descriptors. */
+extern gcsFORMAT_COMPONENT gcvPIXEL_COMP_XXX8;
+extern gcsFORMAT_COMPONENT gcvPIXEL_COMP_XX8X;
+extern gcsFORMAT_COMPONENT gcvPIXEL_COMP_X8XX;
+extern gcsFORMAT_COMPONENT gcvPIXEL_COMP_8XXX;
+
+typedef enum _gceORIENTATION
+{
+ gcvORIENTATION_TOP_BOTTOM,
+ gcvORIENTATION_BOTTOM_TOP,
+}
+gceORIENTATION;
+
+
+/* Construct a new gcoSURF object. */
+gceSTATUS
+gcoSURF_Construct(
+ IN gcoHAL Hal,
+ IN gctUINT Width,
+ IN gctUINT Height,
+ IN gctUINT Depth,
+ IN gceSURF_TYPE Type,
+ IN gceSURF_FORMAT Format,
+ IN gcePOOL Pool,
+ OUT gcoSURF * Surface
+ );
+
+/* Destroy an gcoSURF object. */
+gceSTATUS
+gcoSURF_Destroy(
+ IN gcoSURF Surface
+ );
+
+/* Map user-allocated surface. */
+gceSTATUS
+gcoSURF_MapUserSurface(
+ IN gcoSURF Surface,
+ IN gctUINT Alignment,
+ IN gctPOINTER Logical,
+ IN gctUINT32 Physical
+ );
+
+/* Wrapp surface with known logical/GPU address */
+gceSTATUS
+gcoSURF_WrapSurface(
+ IN gcoSURF Surface,
+ IN gctUINT Alignment,
+ IN gctPOINTER Logical,
+ IN gctUINT32 Physical
+ );
+
+
+/* Query vid mem node info. */
+gceSTATUS
+gcoSURF_QueryVidMemNode(
+ IN gcoSURF Surface,
+ OUT gctUINT32 * Node,
+ OUT gcePOOL * Pool,
+ OUT gctSIZE_T_PTR Bytes,
+ OUT gctUINT32 * TsNode,
+ OUT gcePOOL * TsPool,
+ OUT gctSIZE_T_PTR TsBytes
+ );
+
+/* Set the color type of the surface. */
+gceSTATUS
+gcoSURF_SetColorType(
+ IN gcoSURF Surface,
+ IN gceSURF_COLOR_TYPE ColorType
+ );
+
+/* Get the color type of the surface. */
+gceSTATUS
+gcoSURF_GetColorType(
+ IN gcoSURF Surface,
+ OUT gceSURF_COLOR_TYPE *ColorType
+ );
+
+/* Set the color space of the surface. */
+gceSTATUS
+gcoSURF_SetColorSpace(
+ IN gcoSURF Surface,
+ IN gceSURF_COLOR_SPACE ColorSpace
+ );
+
+/* Get the color space of the surface. */
+gceSTATUS
+gcoSURF_GetColorSpace(
+ IN gcoSURF Surface,
+ OUT gceSURF_COLOR_SPACE *ColorSpace
+ );
+
+
+/* Set the surface ration angle. */
+gceSTATUS
+gcoSURF_SetRotation(
+ IN gcoSURF Surface,
+ IN gceSURF_ROTATION Rotation
+ );
+
+gceSTATUS
+gcoSURF_IsValid(
+ IN gcoSURF Surface
+ );
+
+#if gcdENABLE_3D
+/* Verify and return the state of the tile status mechanism. */
+gceSTATUS
+gcoSURF_IsTileStatusSupported(
+ IN gcoSURF Surface
+ );
+
+/* Verify if surface has tile status enabled. */
+gceSTATUS
+gcoSURF_IsTileStatusEnabled(
+ IN gcsSURF_VIEW *SurfView
+ );
+
+/* Verify if surface is compressed. */
+gceSTATUS
+gcoSURF_IsCompressed(
+ IN gcsSURF_VIEW *SurfView
+ );
+
+/* Enable tile status for the specified surface on zero slot. */
+gceSTATUS
+gcoSURF_EnableTileStatus(
+ IN gcsSURF_VIEW *Surface
+ );
+
+/* Enable tile status for the specified surface on specified slot. */
+gceSTATUS
+gcoSURF_EnableTileStatusEx(
+ IN gcsSURF_VIEW *surfView,
+ IN gctUINT RtIndex
+ );
+
+/* Disable tile status for the specified surface. */
+gceSTATUS
+gcoSURF_DisableTileStatus(
+ IN gcsSURF_VIEW *SurfView,
+ IN gctBOOL Decompress
+ );
+
+/* Flush tile status cache for the specified surface. */
+gceSTATUS
+gcoSURF_FlushTileStatus(
+ IN gcsSURF_VIEW *SurfView,
+ IN gctBOOL Decompress
+ );
+#endif /* gcdENABLE_3D */
+
+/* Get surface size. */
+gceSTATUS
+gcoSURF_GetSize(
+ IN gcoSURF Surface,
+ OUT gctUINT * Width,
+ OUT gctUINT * Height,
+ OUT gctUINT * Depth
+ );
+
+/* Get surface information */
+gceSTATUS
+gcoSURF_GetInfo(
+ IN gcoSURF Surface,
+ IN gceSURF_INFO_TYPE InfoType,
+ IN OUT gctINT32 *Value
+ );
+
+/* Get surface aligned sizes. */
+gceSTATUS
+gcoSURF_GetAlignedSize(
+ IN gcoSURF Surface,
+ OUT gctUINT * Width,
+ OUT gctUINT * Height,
+ OUT gctINT * Stride
+ );
+
+/* Get alignments. */
+gceSTATUS
+gcoSURF_GetAlignment(
+ IN gceSURF_TYPE Type,
+ IN gceSURF_FORMAT Format,
+ OUT gctUINT * AddressAlignment,
+ OUT gctUINT * XAlignment,
+ OUT gctUINT * YAlignment
+ );
+
+gceSTATUS
+gcoSURF_AlignResolveRect(
+ IN gcoSURF Surf,
+ IN gcsPOINT_PTR RectOrigin,
+ IN gcsPOINT_PTR RectSize,
+ OUT gcsPOINT_PTR AlignedOrigin,
+ OUT gcsPOINT_PTR AlignedSize
+ );
+
+/* Get surface type and format. */
+gceSTATUS
+gcoSURF_GetFormat(
+ IN gcoSURF Surface,
+ OUT OPTIONAL gceSURF_TYPE * Type,
+ OUT OPTIONAL gceSURF_FORMAT * Format
+ );
+
+/* Get surface information */
+gceSTATUS
+gcoSURF_GetFormatInfo(
+ IN gcoSURF Surface,
+ OUT gcsSURF_FORMAT_INFO_PTR * formatInfo
+ );
+
+/* Get Surface pack format */
+gceSTATUS
+gcoSURF_GetPackedFormat(
+ IN gcoSURF Surface,
+ OUT gceSURF_FORMAT * Format
+ );
+
+/* Get surface tiling. */
+gceSTATUS
+gcoSURF_GetTiling(
+ IN gcoSURF Surface,
+ OUT gceTILING * Tiling
+ );
+
+/* Get bottom buffer offset bytes. */
+gceSTATUS
+gcoSURF_GetBottomBufferOffset(
+ IN gcoSURF Surface,
+ OUT gctUINT_PTR BottomBufferOffset
+ );
+
+/* Lock the surface. */
+gceSTATUS
+gcoSURF_Lock(
+ IN gcoSURF Surface,
+ IN OUT gctUINT32 * Address,
+ IN OUT gctPOINTER * Memory
+ );
+
+/* Unlock the surface. */
+gceSTATUS
+gcoSURF_Unlock(
+ IN gcoSURF Surface,
+ IN gctPOINTER Memory
+ );
+
+/*. Query surface flags.*/
+gceSTATUS
+gcoSURF_QueryFlags(
+ IN gcoSURF Surface,
+ IN gceSURF_FLAG Flag
+ );
+
+gceSTATUS
+gcoSURF_QueryHints(
+ IN gcoSURF Surface,
+ IN gceSURF_TYPE Hints
+ );
+
+/* Return pixel format parameters; Info is required to be a pointer to an
+ * array of at least two items because some formats have up to two records
+ * of description. */
+gceSTATUS
+gcoSURF_QueryFormat(
+ IN gceSURF_FORMAT Format,
+ OUT gcsSURF_FORMAT_INFO_PTR * Info
+ );
+
+/* Compute the color pixel mask. */
+gceSTATUS
+gcoSURF_ComputeColorMask(
+ IN gcsSURF_FORMAT_INFO_PTR Format,
+ OUT gctUINT32_PTR ColorMask
+ );
+
+/* Flush the surface. */
+gceSTATUS
+gcoSURF_Flush(
+ IN gcoSURF Surface
+ );
+
+/* Fill surface from it's tile status buffer. */
+gceSTATUS
+gcoSURF_FillFromTile(
+ IN gcsSURF_VIEW *SurView
+ );
+
+/* Fill surface with a value. */
+gceSTATUS
+gcoSURF_Fill(
+ IN gcoSURF Surface,
+ IN gcsPOINT_PTR Origin,
+ IN gcsSIZE_PTR Size,
+ IN gctUINT32 Value,
+ IN gctUINT32 Mask
+ );
+
+/* Alpha blend two surfaces together. */
+gceSTATUS
+gcoSURF_Blend(
+ IN gcoSURF SrcSurf,
+ IN gcoSURF DstSurf,
+ IN gcsPOINT_PTR SrcOrigin,
+ IN gcsPOINT_PTR DstOrigin,
+ IN gcsSIZE_PTR Size,
+ IN gceSURF_BLEND_MODE Mode
+ );
+
+/* Create a new gcoSURF wrapper object. */
+gceSTATUS
+gcoSURF_ConstructWrapper(
+ IN gcoHAL Hal,
+ OUT gcoSURF * Surface
+ );
+
+/* Set surface flags.*/
+gceSTATUS
+gcoSURF_SetFlags(
+ IN gcoSURF Surface,
+ IN gceSURF_FLAG Flag,
+ IN gctBOOL Value
+ );
+
+/* Set the underlying buffer for the surface wrapper. */
+gceSTATUS
+gcoSURF_SetBuffer(
+ IN gcoSURF Surface,
+ IN gceSURF_TYPE Type,
+ IN gceSURF_FORMAT Format,
+ IN gctUINT Stride,
+ IN gctPOINTER Logical,
+ IN gctUINT32 Physical
+ );
+
+/* Set the size of the surface in pixels and map the underlying buffer. */
+gceSTATUS
+gcoSURF_SetWindow(
+ IN gcoSURF Surface,
+ IN gctUINT X,
+ IN gctUINT Y,
+ IN gctUINT Width,
+ IN gctUINT Height
+ );
+
+/* Set the size of the surface in pixels and map the underlying buffer. */
+gceSTATUS
+gcoSURF_SetImage(
+ IN gcoSURF Surface,
+ IN gctUINT X,
+ IN gctUINT Y,
+ IN gctUINT Width,
+ IN gctUINT Height,
+ IN gctUINT Depth
+ );
+
+/* Set width/height alignment of the surface directly and calculate stride/size. This is only for dri backend now. Please be careful before use. */
+gceSTATUS
+gcoSURF_SetAlignment(
+ IN gcoSURF Surface,
+ IN gctUINT Width,
+ IN gctUINT Height
+ );
+
+/* Increase reference count of the surface. */
+gceSTATUS
+gcoSURF_ReferenceSurface(
+ IN gcoSURF Surface
+ );
+
+/* Get surface reference count. */
+gceSTATUS
+gcoSURF_QueryReferenceCount(
+ IN gcoSURF Surface,
+ OUT gctINT32 * ReferenceCount
+ );
+
+/* Set surface orientation. */
+gceSTATUS
+gcoSURF_SetOrientation(
+ IN gcoSURF Surface,
+ IN gceORIENTATION Orientation
+ );
+
+/* Query surface orientation. */
+gceSTATUS
+gcoSURF_QueryOrientation(
+ IN gcoSURF Surface,
+ OUT gceORIENTATION * Orientation
+ );
+
+gceSTATUS
+gcoSURF_NODE_Cache(
+ IN gcsSURF_NODE_PTR Node,
+ IN gctPOINTER Logical,
+ IN gctSIZE_T Bytes,
+ IN gceCACHEOPERATION Operation
+ );
+
+gceSTATUS
+gcsSURF_NODE_SetHardwareAddress(
+ IN gcsSURF_NODE_PTR Node,
+ IN gctUINT32 Address
+ );
+
+gceSTATUS
+gcsSURF_NODE_GetHardwareAddress(
+ IN gcsSURF_NODE_PTR Node,
+ OUT gctUINT32_PTR Physical,
+ OUT gctUINT32_PTR Physical2,
+ OUT gctUINT32_PTR Physical3,
+ OUT gctUINT32_PTR PhysicalBottom
+ );
+
+gctUINT32
+gcsSURF_NODE_GetHWAddress(
+ IN gcsSURF_NODE_PTR Node
+ );
+
+/* Lock and unlock surface node */
+gceSTATUS
+gcoSURF_LockNode(
+ IN gcsSURF_NODE_PTR Node,
+ OUT gctUINT32 * Address,
+ OUT gctPOINTER * Memory
+ );
+
+gceSTATUS
+gcoSURF_UnLockNode(
+ IN gcsSURF_NODE_PTR Node,
+ IN gceSURF_TYPE Type
+ );
+
+/* Perform CPU cache operation on surface node */
+gceSTATUS
+gcoSURF_NODE_CPUCacheOperation(
+ IN gcsSURF_NODE_PTR Node,
+ IN gceSURF_TYPE Type,
+ IN gctSIZE_T Offset,
+ IN gctSIZE_T Length,
+ IN gceCACHEOPERATION Operation
+ );
+
+/* Perform CPU cache operation on surface */
+gceSTATUS
+gcoSURF_CPUCacheOperation(
+ IN gcoSURF Surface,
+ IN gceCACHEOPERATION Operation
+ );
+
+
+gceSTATUS
+gcoSURF_Swap(
+ IN gcoSURF Surface1,
+ IN gcoSURF Surface2
+ );
+
+gceSTATUS
+gcoSURF_ResetSurWH(
+ IN gcoSURF Surface,
+ IN gctUINT oriw,
+ IN gctUINT orih,
+ IN gctUINT alignw,
+ IN gctUINT alignh,
+ IN gceSURF_FORMAT fmt
+);
+
+/* Update surface timestamp. */
+gceSTATUS
+gcoSURF_UpdateTimeStamp(
+ IN gcoSURF Surface
+ );
+
+/* Query surface current timestamp. */
+gceSTATUS
+gcoSURF_QueryTimeStamp(
+ IN gcoSURF Surface,
+ OUT gctUINT64 * TimeStamp
+ );
+
+/*
+ * Allocate shared buffer for this surface, so that
+ * surface states can be shared across processes.
+ */
+gceSTATUS
+gcoSURF_AllocShBuffer(
+ IN gcoSURF Surface,
+ OUT gctSHBUF * ShBuf
+ );
+
+/* Bind shared buffer to this surface */
+gceSTATUS
+gcoSURF_BindShBuffer(
+ IN gcoSURF Surface,
+ IN gctSHBUF ShBuf
+ );
+
+/* Push surface shared states to shared buffer. */
+gceSTATUS
+gcoSURF_PushSharedInfo(
+ IN gcoSURF Surface
+ );
+
+/* Pop shared states from shared buffer. */
+gceSTATUS
+gcoSURF_PopSharedInfo(
+ IN gcoSURF Surface
+ );
+
+#if (gcdENABLE_3D || gcdENABLE_VG)
+/* Copy surface. */
+gceSTATUS
+gcoSURF_Copy(
+ IN gcoSURF Surface,
+ IN gcoSURF Source
+ );
+
+/* Set number of samples for a gcoSURF object. */
+gceSTATUS
+gcoSURF_SetSamples(
+ IN gcoSURF Surface,
+ IN gctUINT Samples
+ );
+
+/* Get the number of samples per pixel. */
+gceSTATUS
+gcoSURF_GetSamples(
+ IN gcoSURF Surface,
+ OUT gctUINT_PTR Samples
+ );
+
+/* Append tile status buffer to user pool surface. */
+gceSTATUS
+gcoSURF_AppendTileStatus(
+ IN gcoSURF Surface
+ );
+#endif
+
+gceSTATUS
+gcoSURF_WrapUserMemory(
+ IN gcoHAL Hal,
+ IN gctUINT Width,
+ IN gctUINT Height,
+ IN gctUINT Stride,
+ IN gctUINT Depth,
+ IN gceSURF_TYPE Type,
+ IN gceSURF_FORMAT Format,
+ IN gctUINT32 Handle,
+ IN gctUINT32 Flag,
+ OUT gcoSURF * Surface
+ );
+
+gceSTATUS
+gcoSURF_WrapUserMultiBuffer(
+ IN gcoHAL Hal,
+ IN gctUINT Width,
+ IN gctUINT Height,
+ IN gceSURF_TYPE Type,
+ IN gceSURF_FORMAT Format,
+ IN gctUINT Stride[3],
+ IN gctUINT32 Handle[3],
+ IN gctUINT BufferOffset[3],
+ IN gctUINT32 Flag,
+ OUT gcoSURF * Surface
+ );
+
+gceSTATUS
+gcoSURF_UpdateMetadata(
+ IN gcoSURF Surface,
+ IN gctINT TsFD
+ );
+
+#define MAX_SURF_MIX_SRC_NUM 64
+gceSTATUS
+gcoSURF_MixSurfacesCPU(
+ IN gcoSURF TargetSurface,
+ IN gctUINT TargetSliceIndex,
+ IN gcoSURF *SourceSurface,
+ IN gctUINT *SourceSliceIndices,
+ IN gctFLOAT *Weights,
+ IN gctINT Count
+ );
+
+
+/******************************************************************************\
+********************************* gcoDUMP Object ********************************
+\******************************************************************************/
+
+/* Construct a new gcoDUMP object. */
+gceSTATUS
+gcoDUMP_Construct(
+ IN gcoOS Os,
+ IN gcoHAL Hal,
+ OUT gcoDUMP * Dump
+ );
+
+/* Destroy a gcoDUMP object. */
+gceSTATUS
+gcoDUMP_Destroy(
+ IN gcoDUMP Dump
+ );
+
+/* Enable/disable dumping. */
+gceSTATUS
+gcoDUMP_Control(
+ IN gcoDUMP Dump,
+ IN gctSTRING FileName
+ );
+
+gceSTATUS
+gcoDUMP_IsEnabled(
+ IN gcoDUMP Dump,
+ OUT gctBOOL * Enabled
+ );
+
+/* Add surface. */
+gceSTATUS
+gcoDUMP_AddSurface(
+ IN gcoDUMP Dump,
+ IN gctINT32 Width,
+ IN gctINT32 Height,
+ IN gceSURF_FORMAT PixelFormat,
+ IN gctUINT32 Address,
+ IN gctSIZE_T ByteCount
+ );
+
+/* Mark the beginning of a frame. */
+gceSTATUS
+gcoDUMP_FrameBegin(
+ IN gcoDUMP Dump
+ );
+
+/* Mark the end of a frame. */
+gceSTATUS
+gcoDUMP_FrameEnd(
+ IN gcoDUMP Dump
+ );
+
+/* Dump data. */
+gceSTATUS
+gcoDUMP_DumpData(
+ IN gcoDUMP Dump,
+ IN gceDUMP_TAG Type,
+ IN gctUINT32 Address,
+ IN gctSIZE_T ByteCount,
+ IN gctCONST_POINTER Data
+ );
+
+/* Delete an address. */
+gceSTATUS
+gcoDUMP_Delete(
+ IN gcoDUMP Dump,
+ IN gctUINT32 Address
+ );
+
+/* Enable dump or not. */
+gceSTATUS
+gcoDUMP_SetDumpFlag(
+ IN gctBOOL DumpState
+ );
+
+/******************************************************************************\
+******************************* gcsRECT Structure ******************************
+\******************************************************************************/
+
+/* Initialize rectangle structure. */
+gceSTATUS
+gcsRECT_Set(
+ OUT gcsRECT_PTR Rect,
+ IN gctINT32 Left,
+ IN gctINT32 Top,
+ IN gctINT32 Right,
+ IN gctINT32 Bottom
+ );
+
+/* Return the width of the rectangle. */
+gceSTATUS
+gcsRECT_Width(
+ IN gcsRECT_PTR Rect,
+ OUT gctINT32 * Width
+ );
+
+/* Return the height of the rectangle. */
+gceSTATUS
+gcsRECT_Height(
+ IN gcsRECT_PTR Rect,
+ OUT gctINT32 * Height
+ );
+
+/* Ensure that top left corner is to the left and above the right bottom. */
+gceSTATUS
+gcsRECT_Normalize(
+ IN OUT gcsRECT_PTR Rect
+ );
+
+/* Compare two rectangles. */
+gceSTATUS
+gcsRECT_IsEqual(
+ IN gcsRECT_PTR Rect1,
+ IN gcsRECT_PTR Rect2,
+ OUT gctBOOL * Equal
+ );
+
+/* Compare the sizes of two rectangles. */
+gceSTATUS
+gcsRECT_IsOfEqualSize(
+ IN gcsRECT_PTR Rect1,
+ IN gcsRECT_PTR Rect2,
+ OUT gctBOOL * EqualSize
+ );
+
+gceSTATUS
+gcsRECT_RelativeRotation(
+ IN gceSURF_ROTATION Orientation,
+ IN OUT gceSURF_ROTATION *Relation);
+
+gceSTATUS
+
+gcsRECT_Rotate(
+
+ IN OUT gcsRECT_PTR Rect,
+
+ IN gceSURF_ROTATION Rotation,
+
+ IN gceSURF_ROTATION toRotation,
+
+ IN gctINT32 SurfaceWidth,
+
+ IN gctINT32 SurfaceHeight
+
+ );
+
+/******************************************************************************\
+**************************** gcsBOUNDARY Structure *****************************
+\******************************************************************************/
+
+typedef struct _gcsBOUNDARY
+{
+ gctINT x;
+ gctINT y;
+ gctINT width;
+ gctINT height;
+}
+gcsBOUNDARY;
+
+/******************************************************************************\
+********************************* gcoHEAP Object ********************************
+\******************************************************************************/
+
+typedef struct _gcoHEAP * gcoHEAP;
+
+/* Construct a new gcoHEAP object. */
+gceSTATUS
+gcoHEAP_Construct(
+ IN gcoOS Os,
+ IN gctSIZE_T AllocationSize,
+ OUT gcoHEAP * Heap
+ );
+
+/* Destroy an gcoHEAP object. */
+gceSTATUS
+gcoHEAP_Destroy(
+ IN gcoHEAP Heap
+ );
+
+/* Allocate memory. */
+gceSTATUS
+gcoHEAP_Allocate(
+ IN gcoHEAP Heap,
+ IN gctSIZE_T Bytes,
+ OUT gctPOINTER * Node
+ );
+
+gceSTATUS
+gcoHEAP_GetMemorySize(
+ IN gcoHEAP Heap,
+ IN gctPOINTER Memory,
+ OUT gctSIZE_T_PTR MemorySize
+ );
+
+/* Free memory. */
+gceSTATUS
+gcoHEAP_Free(
+ IN gcoHEAP Heap,
+ IN gctPOINTER Node
+ );
+
+#if (VIVANTE_PROFILER || gcdDEBUG)
+/* Profile the heap. */
+gceSTATUS
+gcoHEAP_ProfileStart(
+ IN gcoHEAP Heap
+ );
+
+gceSTATUS
+gcoHEAP_ProfileEnd(
+ IN gcoHEAP Heap,
+ IN gctCONST_STRING Title
+ );
+#endif
+
+
+/******************************************************************************\
+******************************* Debugging Macros *******************************
+\******************************************************************************/
+
+void
+gcoOS_SetDebugLevel(
+ IN gctUINT32 Level
+ );
+
+void
+gcoOS_GetDebugLevel(
+ OUT gctUINT32_PTR DebugLevel
+ );
+
+void
+gcoOS_SetDebugZone(
+ IN gctUINT32 Zone
+ );
+
+void
+gcoOS_GetDebugZone(
+ IN gctUINT32 Zone,
+ OUT gctUINT32_PTR DebugZone
+ );
+
+void
+gcoOS_SetDebugLevelZone(
+ IN gctUINT32 Level,
+ IN gctUINT32 Zone
+ );
+
+void
+gcoOS_SetDebugZones(
+ IN gctUINT32 Zones,
+ IN gctBOOL Enable
+ );
+
+void
+gcoOS_SetDebugFile(
+ IN gctCONST_STRING FileName
+ );
+
+gctFILE
+gcoOS_ReplaceDebugFile(
+ IN gctFILE fp
+ );
+
+/*******************************************************************************
+**
+** gcmFATAL
+**
+** Print a message to the debugger and execute a break point.
+**
+** ARGUMENTS:
+**
+** message Message.
+** ... Optional arguments.
+*/
+
+void
+gckOS_DebugFatal(
+ IN gctCONST_STRING Message,
+ ...
+ );
+
+void
+gcoOS_DebugFatal(
+ IN gctCONST_STRING Message,
+ ...
+ );
+
+#if gcmIS_DEBUG(gcdDEBUG_FATAL)
+# define gcmFATAL gcoOS_DebugFatal
+# define gcmkFATAL gckOS_DebugFatal
+#elif gcdHAS_ELLIPSIS
+# define gcmFATAL(...)
+# define gcmkFATAL(...)
+#else
+ gcmINLINE static void
+ __dummy_fatal(
+ IN gctCONST_STRING Message,
+ ...
+ )
+ {
+ }
+# define gcmFATAL __dummy_fatal
+# define gcmkFATAL __dummy_fatal
+#endif
+
+#define gcmENUM2TEXT(e) case e: return #e
+
+/*******************************************************************************
+**
+** gcmTRACE
+**
+** Print a message to the debugfer if the correct level has been set. In
+** retail mode this macro does nothing.
+**
+** ARGUMENTS:
+**
+** level Level of message.
+** message Message.
+** ... Optional arguments.
+*/
+#define gcvLEVEL_NONE -1
+#define gcvLEVEL_ERROR 0
+#define gcvLEVEL_WARNING 1
+#define gcvLEVEL_INFO 2
+#define gcvLEVEL_VERBOSE 3
+
+void
+gckOS_DebugTrace(
+ IN gctUINT32 Level,
+ IN gctCONST_STRING Message,
+ ...
+ );
+
+void
+gckOS_DebugTraceN(
+ IN gctUINT32 Level,
+ IN gctUINT ArgumentSize,
+ IN gctCONST_STRING Message,
+ ...
+ );
+
+void
+gcoOS_DebugTrace(
+ IN gctUINT32 Level,
+ IN gctCONST_STRING Message,
+ ...
+ );
+
+#if gcmIS_DEBUG(gcdDEBUG_TRACE)
+# define gcmTRACE gcoOS_DebugTrace
+# define gcmkTRACE gckOS_DebugTrace
+# define gcmkTRACE_N gckOS_DebugTraceN
+#elif gcdHAS_ELLIPSIS
+# define gcmTRACE(...)
+# define gcmkTRACE(...)
+# define gcmkTRACE_N(...)
+#else
+ gcmINLINE static void
+ __dummy_trace(
+ IN gctUINT32 Level,
+ IN gctCONST_STRING Message,
+ ...
+ )
+ {
+ }
+
+ gcmINLINE static void
+ __dummy_trace_n(
+ IN gctUINT32 Level,
+ IN gctUINT ArgumentSize,
+ IN gctCONST_STRING Message,
+ ...
+ )
+ {
+ }
+
+# define gcmTRACE __dummy_trace
+# define gcmkTRACE __dummy_trace
+# define gcmkTRACE_N __dummy_trace_n
+#endif
+
+/* Zones common for kernel and user. */
+#define gcvZONE_OS (1 << 0)
+#define gcvZONE_HARDWARE (1 << 1)
+#define gcvZONE_HEAP (1 << 2)
+#define gcvZONE_SIGNAL (1 << 3)
+
+/* Kernel zones. */
+#define gcvZONE_KERNEL (1 << 4)
+#define gcvZONE_VIDMEM (1 << 5)
+#define gcvZONE_COMMAND (1 << 6)
+#define gcvZONE_DRIVER (1 << 7)
+#define gcvZONE_CMODEL (1 << 8)
+#define gcvZONE_MMU (1 << 9)
+#define gcvZONE_EVENT (1 << 10)
+#define gcvZONE_DEVICE (1 << 11)
+#define gcvZONE_DATABASE (1 << 12)
+#define gcvZONE_INTERRUPT (1 << 13)
+#define gcvZONE_POWER (1 << 14)
+#define gcvZONE_ASYNC_COMMAND (1 << 15)
+#define gcvZONE_ALLOCATOR (1 << 16)
+
+/* User zones. */
+#define gcvZONE_HAL (1 << 4)
+#define gcvZONE_BUFFER (1 << 5)
+#define gcvZONE_CONTEXT (1 << 6)
+#define gcvZONE_SURFACE (1 << 7)
+#define gcvZONE_INDEX (1 << 8)
+#define gcvZONE_STREAM (1 << 9)
+#define gcvZONE_TEXTURE (1 << 10)
+#define gcvZONE_2D (1 << 11)
+#define gcvZONE_3D (1 << 12)
+#define gcvZONE_COMPILER (1 << 13)
+#define gcvZONE_MEMORY (1 << 14)
+#define gcvZONE_STATE (1 << 15)
+#define gcvZONE_AUX (1 << 16)
+#define gcvZONE_VERTEX (1 << 17)
+#define gcvZONE_CL (1 << 18)
+#define gcvZONE_VG (1 << 19)
+#define gcvZONE_VX (1 << 20)
+#define gcvZONE_IMAGE (1 << 21)
+#define gcvZONE_UTILITY (1 << 22)
+#define gcvZONE_PARAMETERS (1 << 23)
+#define gcvZONE_BUFOBJ (1 << 24)
+#define gcvZONE_SHADER (1 << 25)
+#define gcvZONE_STREAM_OUT (1 << 26)
+
+/* API definitions. */
+#define gcvZONE_API_HAL ((gctUINT32) 1 << 28)
+#define gcvZONE_API_EGL ((gctUINT32) 2 << 28)
+#define gcvZONE_API_ES11 ((gctUINT32) 3 << 28)
+#define gcvZONE_API_ES20 ((gctUINT32) 4 << 28)
+#define gcvZONE_API_ES30 ((gctUINT32) 4 << 28)
+#define gcvZONE_API_VG11 ((gctUINT32) 5 << 28)
+#define gcvZONE_API_GL ((gctUINT32) 6 << 28)
+#define gcvZONE_API_DFB ((gctUINT32) 7 << 28)
+#define gcvZONE_API_GDI ((gctUINT32) 8 << 28)
+#define gcvZONE_API_D3D ((gctUINT32) 9 << 28)
+#define gcvZONE_API_CL ((gctUINT32) 10 << 28)
+#define gcvZONE_API_VX ((gctUINT32) 11 << 28)
+
+
+#define gcmZONE_GET_API(zone) ((zone) >> 28)
+/*Set gcdZONE_MASE like 0x0 | gcvZONE_API_EGL
+will enable print EGL module debug info*/
+#define gcdZONE_MASK 0x0FFFFFFF
+
+/* Handy zones. */
+#define gcvZONE_NONE 0
+#define gcvZONE_ALL 0x0FFFFFFF
+
+/*Dump API depth set 1 for API, 2 for API and API behavior*/
+#define gcvDUMP_API_DEPTH 1
+
+
+/*******************************************************************************
+**
+** gcmTRACE_ZONE
+**
+** Print a message to the debugger if the correct level and zone has been
+** set. In retail mode this macro does nothing.
+**
+** ARGUMENTS:
+**
+** Level Level of message.
+** Zone Zone of message.
+** Message Message.
+** ... Optional arguments.
+*/
+
+void
+gckOS_DebugTraceZone(
+ IN gctUINT32 Level,
+ IN gctUINT32 Zone,
+ IN gctCONST_STRING Message,
+ ...
+ );
+
+void
+gckOS_DebugTraceZoneN(
+ IN gctUINT32 Level,
+ IN gctUINT32 Zone,
+ IN gctUINT ArgumentSize,
+ IN gctCONST_STRING Message,
+ ...
+ );
+
+void
+gcoOS_DebugTraceZone(
+ IN gctUINT32 Level,
+ IN gctUINT32 Zone,
+ IN gctCONST_STRING Message,
+ ...
+ );
+
+#if gcmIS_DEBUG(gcdDEBUG_TRACE)
+# define gcmTRACE_ZONE gcoOS_DebugTraceZone
+# define gcmkTRACE_ZONE gckOS_DebugTraceZone
+# define gcmkTRACE_ZONE_N gckOS_DebugTraceZoneN
+#elif gcdHAS_ELLIPSIS
+# define gcmTRACE_ZONE(...)
+# define gcmkTRACE_ZONE(...)
+# define gcmkTRACE_ZONE_N(...)
+#else
+ gcmINLINE static void
+ __dummy_trace_zone(
+ IN gctUINT32 Level,
+ IN gctUINT32 Zone,
+ IN gctCONST_STRING Message,
+ ...
+ )
+ {
+ }
+
+ gcmINLINE static void
+ __dummy_trace_zone_n(
+ IN gctUINT32 Level,
+ IN gctUINT32 Zone,
+ IN gctUINT ArgumentSize,
+ IN gctCONST_STRING Message,
+ ...
+ )
+ {
+ }
+
+# define gcmTRACE_ZONE __dummy_trace_zone
+# define gcmkTRACE_ZONE __dummy_trace_zone
+# define gcmkTRACE_ZONE_N __dummy_trace_zone_n
+#endif
+
+
+/*******************************************************************************
+**
+** gcmDEBUG_ONLY
+**
+** Execute a statement or function only in DEBUG mode.
+**
+** ARGUMENTS:
+**
+** f Statement or function to execute.
+*/
+#if gcmIS_DEBUG(gcdDEBUG_CODE)
+# define gcmDEBUG_ONLY(f) f
+#else
+# define gcmDEBUG_ONLY(f)
+#endif
+
+
+/*******************************************************************************
+**
+** gcmSTACK_PUSH
+** gcmSTACK_POP
+** gcmSTACK_DUMP
+** gcmSTACK_REMOVE
+**
+** Push or pop a function with entry arguments on the trace stack.
+**
+** ARGUMENTS:
+**
+** Function Name of function.
+** Line Line number.
+** Text Optional text.
+** ... Optional arguments for text.
+**
+** Thread Thread id.
+*/
+void
+gcoOS_StackPush(
+ IN gctINT8_PTR Identity,
+ IN gctCONST_STRING Function,
+ IN gctINT Line,
+ IN gctCONST_STRING Text,
+ ...
+ );
+
+void
+gcoOS_StackPop(
+ IN gctINT8_PTR Identity,
+ IN gctCONST_STRING Function
+ );
+
+void
+gcoOS_StackDump(
+ void);
+
+void
+gcoOS_StackRemove(
+ IN gctHANDLE Thread
+ );
+
+#if gcmIS_DEBUG(gcdDEBUG_STACK)
+# define gcmSTACK_PUSH gcoOS_StackPush
+# define gcmSTACK_POP gcoOS_StackPop
+# define gcmSTACK_DUMP gcoOS_StackDump
+# define gcmSTACK_REMOVE gcoOS_StackRemove
+#elif gcdHAS_ELLIPSIS
+# define gcmSTACK_PUSH(...)
+# define gcmSTACK_POP(...)
+# define gcmSTACK_DUMP()
+# define gcmSTACK_REMOVE(...)
+#else
+ gcmINLINE static void
+ __dummy_stack_push(
+ IN gctCONST_STRING Function,
+ IN gctINT Line,
+ IN gctCONST_STRING Text,
+ ...
+ )
+ {
+ }
+
+ gcmINLINE static void
+ __dummy_stack_pop(
+ IN gctINT8_PTR Identity,
+ IN gctCONST_STRING Function
+ );
+
+ gcmINLINE static void
+ __dummy_stack_remove(
+ IN gctHANDLE Thread
+ );
+
+# define gcmSTACK_PUSH __dummy_stack_push
+# define gcmSTACK_POP(a,b) __dummy_stack_pop
+# define gcmSTACK_DUMP()
+# define gcmSTACK_REMOVE(a) __dummy_stack_remove
+#endif
+
+
+/*******************************************************************************
+**
+** gcmBINARY_TRACE
+**
+** Push or pop a function with entry arguments on the trace stack.
+**
+** ARGUMENTS:
+**
+** Function Name of function
+** Line Line number
+** Text Optional text
+** ... Optional arguments for text.
+*/
+typedef struct _gcsBINARY_TRACE_MESSAGE * gcsBINARY_TRACE_MESSAGE_PTR;
+typedef struct _gcsBINARY_TRACE_MESSAGE
+{
+ gctUINT32 signature;
+ gctUINT32 pid;
+ gctUINT32 tid;
+ gctUINT32 line;
+ gctUINT32 numArguments;
+ gctUINT8 payload;
+}
+gcsBINARY_TRACE_MESSAGE;
+
+void
+gcoOS_BinaryTrace(
+ IN gctCONST_STRING Function,
+ IN gctINT Line,
+ IN gctCONST_STRING Text OPTIONAL,
+ ...
+ );
+
+void
+gckOS_BinaryTrace(
+ IN gctCONST_STRING Function,
+ IN gctINT Line,
+ IN gctCONST_STRING Text OPTIONAL,
+ ...
+ );
+
+#define gcdBINARY_TRACE_MESSAGE_SIZE 240
+
+#if gcdBINARY_TRACE
+# define gcmBINARY_TRACE gcoOS_BinaryTrace
+# define gcmkBINARY_TRACE gckOS_BinaryTrace
+#elif gcdHAS_ELLIPSIS
+# define gcmBINARY_TRACE(Function, Line, Text, ...)
+# define gcmkBINARY_TRACE(Function, Line, Text, ...)
+#else
+ gcmINLINE static void
+ __dummy_binary_trace(
+ IN gctCONST_STRING Function,
+ IN gctINT Line,
+ IN gctCONST_STRING Text,
+ )
+ {
+ }
+
+# define gcmBINARY_TRACE __dummy_binary_trace
+# define gcmkBINARY_TRACE __dummy_binary_trace
+#endif
+
+
+/*******************************************************************************
+**
+** gcmSYSTRACE_BEGIN
+** gcmSYSTRACE_END
+**
+** Systrace is a performance tunning tool on linux.
+**
+** ARGUMENTS:
+**
+** FuncName Function name
+** Zone Systrace zone. Only specified zones are traced.
+*/
+
+void
+gcoOS_SysTraceBegin(
+ IN gctUINT32 Zone,
+ IN gctCONST_STRING FuncName
+ );
+
+void
+gcoOS_SysTraceEnd(
+ IN gctUINT32 Zone
+ );
+
+#if defined(LINUX) && gcdSYSTRACE
+# define gcmSYSTRACE_BEGIN gcoOS_SysTraceBegin
+# define gcmSYSTRACE_END gcoOS_SysTraceEnd
+#elif gcdHAS_ELLIPSIS
+# define gcmSYSTRACE_BEGIN(...)
+# define gcmSYSTRACE_END(...)
+#else
+ gcmINLINE static void
+ __dummy_systrace_begin(
+ IN gctUINT32 Zone,
+ IN gctCONST_STRING FuncName
+ )
+ {
+ }
+
+ gcmINLINE static void
+ __dummy_systrace_end(
+ IN gctUINT32 Zone
+ )
+ {
+ }
+
+# define gcmSYSTRACE_BEGIN __dummy_systrace_begin
+# define gcmSYSTRACE_END __dummy_systrace_end
+#endif
+
+
+/******************************************************************************\
+******************************** Logging Macros ********************************
+\******************************************************************************/
+
+#define gcdHEADER_LEVEL gcvLEVEL_VERBOSE
+
+/* Always enable header/footer when systrace build is on */
+#if defined(LINUX) && gcdSYSTRACE
+#undef gcdEMPTY_HEADER_FOOTER
+#endif
+
+#ifndef gcdEMPTY_HEADER_FOOTER
+#define gcdEMPTY_HEADER_FOOTER 0
+#endif
+
+#if gcdENABLE_PROFILING
+void
+gcoOS_ProfileDB(
+ IN gctCONST_STRING Function,
+ IN OUT gctBOOL_PTR Initialized
+ );
+
+#define gcmHEADER() \
+ gctINT8 __user__ = 1; \
+ static gctBOOL __profile__initialized__ = gcvFALSE; \
+ gcmSTACK_PUSH(&__user__, __FUNCTION__, __LINE__, gcvNULL, gcvNULL); \
+ gcoOS_ProfileDB(__FUNCTION__, &__profile__initialized__)
+
+#define gcmHEADER_ARG(...) \
+ gctINT8 __user__ = 1; \
+ static gctBOOL __profile__initialized__ = gcvFALSE; \
+ gcmSTACK_PUSH(&__user__, __FUNCTION__, __LINE__, Text, __VA_ARGS__); \
+ gcoOS_ProfileDB(__FUNCTION__, &__profile__initialized__)
+
+#define gcmFOOTER() \
+ gcmSTACK_POP(&__user__, __FUNCTION__); \
+ gcoOS_ProfileDB(__FUNCTION__, gcvNULL)
+
+#define gcmFOOTER_NO() \
+ gcmSTACK_POP(&__user__, __FUNCTION__); \
+ gcoOS_ProfileDB(__FUNCTION__, gcvNULL)
+
+#define gcmFOOTER_ARG(...) \
+ gcmSTACK_POP(&__user__, __FUNCTION__); \
+ gcoOS_ProfileDB(__FUNCTION__, gcvNULL)
+
+#define gcmFOOTER_KILL() \
+ gcmSTACK_POP(&__user__, __FUNCTION__); \
+ gcoOS_ProfileDB(gcvNULL, gcvNULL)
+
+#else /* !gcdENABLE_PROFILING */
+
+#if gcdEMPTY_HEADER_FOOTER
+# define gcmHEADER()
+#elif gcdHAS_ELLIPSIS
+#define gcmHEADER() \
+ gctINT8 __user__ = 1; \
+ gctINT8_PTR __user_ptr__ = &__user__; \
+ gcmSTACK_PUSH(__user_ptr__, __FUNCTION__, __LINE__, gcvNULL, gcvNULL); \
+ gcmSYSTRACE_BEGIN(_GC_OBJ_ZONE, __FUNCTION__); \
+ gcmBINARY_TRACE(__FUNCTION__, __LINE__, gcvNULL, gcvNULL); \
+ gcmTRACE_ZONE(gcdHEADER_LEVEL, _GC_OBJ_ZONE, \
+ "++%s(%d)", __FUNCTION__, __LINE__)
+#else
+ gcmINLINE static void
+ __dummy_header(void)
+ {
+ }
+# define gcmHEADER __dummy_header
+#endif
+
+#if gcdHAS_ELLIPSIS
+#if gcdEMPTY_HEADER_FOOTER
+# define gcmHEADER_ARG(Text, ...)
+#else
+# define gcmHEADER_ARG(Text, ...) \
+ gctINT8 __user__ = 1; \
+ gctINT8_PTR __user_ptr__ = &__user__; \
+ gcmSTACK_PUSH(__user_ptr__, __FUNCTION__, __LINE__, Text, __VA_ARGS__); \
+ gcmSYSTRACE_BEGIN(_GC_OBJ_ZONE, __FUNCTION__); \
+ gcmBINARY_TRACE(__FUNCTION__, __LINE__, Text, __VA_ARGS__); \
+ gcmTRACE_ZONE(gcdHEADER_LEVEL, _GC_OBJ_ZONE, \
+ "++%s(%d): " Text, __FUNCTION__, __LINE__, __VA_ARGS__)
+#endif
+#else
+ gcmINLINE static void
+ __dummy_header_arg(
+ IN gctCONST_STRING Text,
+ ...
+ )
+ {
+ }
+# define gcmHEADER_ARG __dummy_header_arg
+#endif
+
+#if gcdEMPTY_HEADER_FOOTER
+# define gcmFOOTER()
+#elif gcdHAS_ELLIPSIS
+# define gcmFOOTER() \
+ gcmSTACK_POP(__user_ptr__, __FUNCTION__); \
+ gcmSYSTRACE_END(_GC_OBJ_ZONE); \
+ gcmBINARY_TRACE(__FUNCTION__, __LINE__, gcvNULL, gcvNULL); \
+ gcmTRACE_ZONE(gcdHEADER_LEVEL, _GC_OBJ_ZONE, \
+ "--%s(%d): status=%d(%s)", \
+ __FUNCTION__, __LINE__, \
+ status, gcmSTATUS2NAME(status)); \
+ *__user_ptr__ -= 1
+#else
+ gcmINLINE static void
+ __dummy_footer(void)
+ {
+ }
+# define gcmFOOTER __dummy_footer
+#endif
+
+#if gcdEMPTY_HEADER_FOOTER
+# define gcmFOOTER_NO()
+#elif gcdHAS_ELLIPSIS
+#define gcmFOOTER_NO() \
+ gcmSTACK_POP(__user_ptr__, __FUNCTION__); \
+ gcmSYSTRACE_END(_GC_OBJ_ZONE); \
+ gcmBINARY_TRACE(__FUNCTION__, __LINE__, gcvNULL, gcvNULL); \
+ gcmTRACE_ZONE(gcdHEADER_LEVEL, _GC_OBJ_ZONE, \
+ "--%s(%d)", __FUNCTION__, __LINE__); \
+ *__user_ptr__ -= 1
+#else
+ gcmINLINE static void
+ __dummy_footer_no(void)
+ {
+ }
+# define gcmFOOTER_NO __dummy_footer_no
+#endif
+
+#if gcdEMPTY_HEADER_FOOTER
+# define gcmFOOTER_KILL()
+#elif gcdHAS_ELLIPSIS
+#define gcmFOOTER_KILL() \
+ gcmSTACK_POP(__user_ptr__, __FUNCTION__); \
+ gcmSYSTRACE_END(_GC_OBJ_ZONE); \
+ gcmBINARY_TRACE(__FUNCTION__, __LINE__, gcvNULL, gcvNULL); \
+ gcmTRACE_ZONE(gcdHEADER_LEVEL, _GC_OBJ_ZONE, \
+ "--%s(%d)", __FUNCTION__, __LINE__); \
+ *__user_ptr__ -= 1
+#else
+ gcmINLINE static void
+ __dummy_footer_kill(void)
+ {
+ }
+# define gcmFOOTER_KILL __dummy_footer_kill
+#endif
+
+#if gcdHAS_ELLIPSIS
+#if gcdEMPTY_HEADER_FOOTER
+# define gcmFOOTER_ARG(Text, ...)
+#else
+# define gcmFOOTER_ARG(Text, ...) \
+ gcmSTACK_POP(__user_ptr__, __FUNCTION__); \
+ gcmSYSTRACE_END(_GC_OBJ_ZONE); \
+ gcmBINARY_TRACE(__FUNCTION__, __LINE__, Text, __VA_ARGS__); \
+ gcmTRACE_ZONE(gcdHEADER_LEVEL, _GC_OBJ_ZONE, \
+ "--%s(%d): " Text, __FUNCTION__, __LINE__, __VA_ARGS__); \
+ *__user_ptr__ -= 1
+#endif
+#else
+ gcmINLINE static void
+ __dummy_footer_arg(
+ IN gctCONST_STRING Text,
+ ...
+ )
+ {
+ }
+# define gcmFOOTER_ARG __dummy_footer_arg
+#endif
+
+#endif /* gcdENABLE_PROFILING */
+
+#if gcdHAS_ELLIPSIS
+#define gcmkHEADER() \
+ gctINT8 __kernel__ = 1; \
+ gctINT8_PTR __kernel_ptr__ = &__kernel__; \
+ gcmkBINARY_TRACE(__FUNCTION__, __LINE__, gcvNULL, gcvNULL); \
+ gcmkTRACE_ZONE(gcdHEADER_LEVEL, _GC_OBJ_ZONE, \
+ "++%s(%d)", __FUNCTION__, __LINE__)
+#else
+ gcmINLINE static void
+ __dummy_kheader(void)
+ {
+ }
+# define gcmkHEADER __dummy_kheader
+#endif
+
+#if gcdHAS_ELLIPSIS
+# define gcmkHEADER_ARG(Text, ...) \
+ gctINT8 __kernel__ = 1; \
+ gctINT8_PTR __kernel_ptr__ = &__kernel__; \
+ gcmkBINARY_TRACE(__FUNCTION__, __LINE__, Text, __VA_ARGS__); \
+ gcmkTRACE_ZONE(gcdHEADER_LEVEL, _GC_OBJ_ZONE, \
+ "++%s(%d): " Text, __FUNCTION__, __LINE__, __VA_ARGS__)
+#else
+ gcmINLINE static void
+ __dummy_kheader_arg(
+ IN gctCONST_STRING Text,
+ ...
+ )
+ {
+ }
+# define gcmkHEADER_ARG __dummy_kheader_arg
+#endif
+
+#if gcdHAS_ELLIPSIS
+#define gcmkFOOTER() \
+ gcmkBINARY_TRACE(__FUNCTION__, __LINE__, gcvNULL, status); \
+ gcmkTRACE_ZONE(gcdHEADER_LEVEL, _GC_OBJ_ZONE, \
+ "--%s(%d): status=%d(%s)", \
+ __FUNCTION__, __LINE__, status, gcmkSTATUS2NAME(status)); \
+ *__kernel_ptr__ -= 1
+#else
+ gcmINLINE static void
+ __dummy_kfooter(void)
+ {
+ }
+# define gcmkFOOTER __dummy_kfooter
+#endif
+
+#if gcdHAS_ELLIPSIS
+#define gcmkFOOTER_NO() \
+ gcmkBINARY_TRACE(__FUNCTION__, __LINE__, gcvNULL, gcvNULL); \
+ gcmkTRACE_ZONE(gcdHEADER_LEVEL, _GC_OBJ_ZONE, \
+ "--%s(%d)", __FUNCTION__, __LINE__); \
+ *__kernel_ptr__ -= 1
+#else
+ gcmINLINE static void
+ __dummy_kfooter_no(void)
+ {
+ }
+# define gcmkFOOTER_NO __dummy_kfooter_no
+#endif
+
+#if gcdHAS_ELLIPSIS
+# define gcmkFOOTER_ARG(Text, ...) \
+ gcmkBINARY_TRACE(__FUNCTION__, __LINE__, Text, __VA_ARGS__); \
+ gcmkTRACE_ZONE(gcdHEADER_LEVEL, _GC_OBJ_ZONE, \
+ "--%s(%d): " Text, \
+ __FUNCTION__, __LINE__, __VA_ARGS__); \
+ *__kernel_ptr__ -= 1
+#else
+ gcmINLINE static void
+ __dummy_kfooter_arg(
+ IN gctCONST_STRING Text,
+ ...
+ )
+ {
+ }
+# define gcmkFOOTER_ARG __dummy_kfooter_arg
+#endif
+
+#define gcmOPT_VALUE(ptr) (((ptr) == gcvNULL) ? 0 : *(ptr))
+#define gcmOPT_VALUE_INDEX(ptr, index) (((ptr) == gcvNULL) ? 0 : ptr[index])
+#define gcmOPT_POINTER(ptr) (((ptr) == gcvNULL) ? gcvNULL : *(ptr))
+#define gcmOPT_STRING(ptr) (((ptr) == gcvNULL) ? "(nil)" : (ptr))
+
+void
+gckOS_Print(
+ IN gctCONST_STRING Message,
+ ...
+ );
+
+void
+gckOS_PrintN(
+ IN gctUINT ArgumentSize,
+ IN gctCONST_STRING Message,
+ ...
+ );
+
+void
+gckOS_CopyPrint(
+ IN gctCONST_STRING Message,
+ ...
+ );
+
+void
+gcoOS_Print(
+ IN gctCONST_STRING Message,
+ ...
+ );
+
+#define gcmPRINT gcoOS_Print
+#define gcmkPRINT gckOS_Print
+#define gcmkPRINT_N gckOS_PrintN
+
+#if gcdPRINT_VERSION
+# define gcmPRINT_VERSION() do { \
+ _gcmPRINT_VERSION(gcm); \
+ gcmSTACK_DUMP(); \
+ } while (0)
+# define gcmkPRINT_VERSION() _gcmPRINT_VERSION(gcmk)
+# define _gcmPRINT_VERSION(prefix) \
+ prefix##TRACE(gcvLEVEL_ERROR, \
+ "Vivante HAL version %d.%d.%d build %d", \
+ gcvVERSION_MAJOR, gcvVERSION_MINOR, \
+ gcvVERSION_PATCH, gcvVERSION_BUILD)
+#else
+# define gcmPRINT_VERSION() do { gcmSTACK_DUMP(); } while (gcvFALSE)
+# define gcmkPRINT_VERSION() do { } while (gcvFALSE)
+#endif
+
+typedef enum _gceDUMP_BUFFER
+{
+ gcvDUMP_BUFFER_CONTEXT,
+ gcvDUMP_BUFFER_USER,
+ gcvDUMP_BUFFER_KERNEL,
+ gcvDUMP_BUFFER_LINK,
+ gcvDUMP_BUFFER_WAITLINK,
+ gcvDUMP_BUFFER_FROM_USER,
+}
+gceDUMP_BUFFER;
+
+void
+gckOS_DumpBuffer(
+ IN gckOS Os,
+ IN gctPOINTER Buffer,
+ IN gctSIZE_T Size,
+ IN gceDUMP_BUFFER Type,
+ IN gctBOOL CopyMessage
+ );
+
+#define gcmkDUMPBUFFER gckOS_DumpBuffer
+
+#if gcdDUMP_COMMAND
+# define gcmkDUMPCOMMAND(Os, Buffer, Size, Type, CopyMessage) \
+ gcmkDUMPBUFFER(Os, Buffer, Size, Type, CopyMessage)
+#else
+# define gcmkDUMPCOMMAND(Os, Buffer, Size, Type, CopyMessage)
+#endif
+
+#if gcmIS_DEBUG(gcdDEBUG_CODE)
+
+void
+gckOS_DebugFlush(
+ gctCONST_STRING CallerName,
+ gctUINT LineNumber,
+ gctUINT32 DmaAddress
+ );
+
+# define gcmkDEBUGFLUSH(DmaAddress) \
+ gckOS_DebugFlush(__FUNCTION__, __LINE__, DmaAddress)
+#else
+# define gcmkDEBUGFLUSH(DmaAddress)
+#endif
+
+/*******************************************************************************
+**
+** gcmDUMP_FRAMERATE
+**
+** Print average frame rate
+**
+*/
+#if gcdDUMP_FRAMERATE
+ gceSTATUS
+ gcfDumpFrameRate(
+ void
+ );
+# define gcmDUMP_FRAMERATE gcfDumpFrameRate
+#elif gcdHAS_ELLIPSIS
+# define gcmDUMP_FRAMERATE(...)
+#else
+ gcmINLINE static void
+ __dummy_dump_frame_rate(
+ void
+ )
+ {
+ }
+# define gcmDUMP_FRAMERATE __dummy_dump_frame_rate
+#endif
+
+
+/*******************************************************************************
+**
+** gcmDUMP
+**
+** Print a dump message.
+**
+** ARGUMENTS:
+**
+** gctSTRING Message.
+**
+** ... Optional arguments.
+*/
+
+#if gcdDUMP || gcdDUMP_2DVG
+ gceSTATUS
+ gcfDump(
+ IN gcoOS Os,
+ IN gctCONST_STRING String,
+ ...
+ );
+# define gcmDUMP gcfDump
+#elif gcdHAS_ELLIPSIS
+# define gcmDUMP(...)
+#else
+ gcmINLINE static void
+ __dummy_dump(
+ IN gcoOS Os,
+ IN gctCONST_STRING Message,
+ ...
+ )
+ {
+ }
+# define gcmDUMP __dummy_dump
+#endif
+
+/*******************************************************************************
+**
+** gcmDUMP_DATA
+**
+** Add data to the dump.
+**
+** ARGUMENTS:
+**
+** gctSTRING Tag
+** Tag for dump.
+**
+** gctPOINTER Logical
+** Logical address of buffer.
+**
+** gctSIZE_T Bytes
+** Number of bytes.
+*/
+
+#if gcdDUMP || gcdDUMP_COMMAND
+ gceSTATUS
+ gcfDumpData(
+ IN gcoOS Os,
+ IN gctSTRING Tag,
+ IN gctPOINTER Logical,
+ IN gctSIZE_T Bytes
+ );
+# define gcmDUMP_DATA gcfDumpData
+#elif gcdHAS_ELLIPSIS
+# define gcmDUMP_DATA(...)
+#else
+ gcmINLINE static void
+ __dummy_dump_data(
+ IN gcoOS Os,
+ IN gctSTRING Tag,
+ IN gctPOINTER Logical,
+ IN gctSIZE_T Bytes
+ )
+ {
+ }
+# define gcmDUMP_DATA __dummy_dump_data
+#endif
+
+/*******************************************************************************
+**
+** gcmDUMP_BUFFER
+**
+** Print a buffer to the dump.
+**
+** ARGUMENTS:
+**
+** gctSTRING Tag
+** Tag for dump.
+**
+** gctUINT32 Physical
+** Physical address of buffer.
+**
+** gctPOINTER Logical
+** Logical address of buffer.
+**
+** gctUINT32 Offset
+** Offset into buffer.
+**
+** gctSIZE_T Bytes
+** Number of bytes.
+*/
+
+#if gcdDUMP || gcdDUMP_COMMAND || gcdDUMP_2DVG
+gceSTATUS
+gcfDumpBuffer(
+ IN gcoOS Os,
+ IN gctSTRING Tag,
+ IN gctUINT32 Physical,
+ IN gctPOINTER Logical,
+ IN gctSIZE_T Offset,
+ IN gctSIZE_T Bytes
+ );
+# define gcmDUMP_BUFFER gcfDumpBuffer
+#elif gcdHAS_ELLIPSIS
+# define gcmDUMP_BUFFER(...)
+#else
+ gcmINLINE static void
+ __dummy_dump_buffer(
+ IN gcoOS Os,
+ IN gctSTRING Tag,
+ IN gctUINT32 Physical,
+ IN gctPOINTER Logical,
+ IN gctUINT32 Offset,
+ IN gctSIZE_T Bytes
+ )
+ {
+ }
+# define gcmDUMP_BUFFER __dummy_dump_buffer
+#endif
+
+#if gcdDUMP
+void
+gcfDumpLock(
+ void
+ );
+# define gcmDUMP_LOCK gcfDumpLock
+#elif gcdHAS_ELLIPSIS
+# define gcmDUMP_LOCK(...)
+#else
+ gcmINLINE static void
+ __dummy_dump_lock(
+ void
+ )
+ {
+ }
+# define gcmDUMP_LOCK __dummy_dump_lock
+#endif
+
+#if gcdDUMP
+void
+gcfDumpUnlock(
+ void
+ );
+# define gcmDUMP_UNLOCK gcfDumpUnlock
+#elif gcdHAS_ELLIPSIS
+# define gcmDUMP_UNLOCK(...)
+#else
+ gcmINLINE static void
+ __dummy_dump_unlock(
+ void
+ )
+ {
+ }
+# define gcmDUMP_UNLOCK __dummy_dump_unlock
+#endif
+
+/*******************************************************************************
+**
+** gcmDUMP_API
+**
+** Print a dump message for a high level API prefixed by the function name.
+**
+** ARGUMENTS:
+**
+** gctSTRING Message.
+**
+** ... Optional arguments.
+*/
+gceSTATUS gcfDumpApi(IN gctCONST_STRING String, ...);
+#if gcdDUMP_API
+# define gcmDUMP_API gcfDumpApi
+#elif gcdHAS_ELLIPSIS
+# define gcmDUMP_API(...)
+#else
+ gcmINLINE static void
+ __dummy_dump_api(
+ IN gctCONST_STRING Message,
+ ...
+ )
+ {
+ }
+# define gcmDUMP_API __dummy_dump_api
+#endif
+
+/*******************************************************************************
+**
+** gcmDUMP_API_ARRAY
+**
+** Print an array of data.
+**
+** ARGUMENTS:
+**
+** gctUINT32_PTR Pointer to array.
+** gctUINT32 Size.
+*/
+gceSTATUS gcfDumpArray(IN gctCONST_POINTER Data, IN gctUINT32 Size);
+#if gcdDUMP_API
+# define gcmDUMP_API_ARRAY gcfDumpArray
+#elif gcdHAS_ELLIPSIS
+# define gcmDUMP_API_ARRAY(...)
+#else
+ gcmINLINE static void
+ __dummy_dump_api_array(
+ IN gctCONST_POINTER Data,
+ IN gctUINT32 Size
+ )
+ {
+ }
+# define gcmDUMP_API_ARRAY __dummy_dump_api_array
+#endif
+
+/*******************************************************************************
+**
+** gcmDUMP_API_ARRAY_TOKEN
+**
+** Print an array of data terminated by a token.
+**
+** ARGUMENTS:
+**
+** gctUINT32_PTR Pointer to array.
+** gctUINT32 Termination.
+*/
+gceSTATUS gcfDumpArrayToken(IN gctCONST_POINTER Data, IN gctUINT32 Termination);
+#if gcdDUMP_API
+# define gcmDUMP_API_ARRAY_TOKEN gcfDumpArrayToken
+#elif gcdHAS_ELLIPSIS
+# define gcmDUMP_API_ARRAY_TOKEN(...)
+#else
+ gcmINLINE static void
+ __dummy_dump_api_array_token(
+ IN gctCONST_POINTER Data,
+ IN gctUINT32 Termination
+ )
+ {
+ }
+# define gcmDUMP_API_ARRAY_TOKEN __dummy_dump_api_array_token
+#endif
+
+/*******************************************************************************
+**
+** gcmDUMP_API_DATA
+**
+** Print an array of bytes.
+**
+** ARGUMENTS:
+**
+** gctCONST_POINTER Pointer to array.
+** gctSIZE_T Size.
+*/
+gceSTATUS gcfDumpApiData(IN gctCONST_POINTER Data, IN gctSIZE_T Size);
+#if gcdDUMP_API
+# define gcmDUMP_API_DATA gcfDumpApiData
+#elif gcdHAS_ELLIPSIS
+# define gcmDUMP_API_DATA(...)
+#else
+ gcmINLINE static void
+ __dummy_dump_api_data(
+ IN gctCONST_POINTER Data,
+ IN gctSIZE_T Size
+ )
+ {
+ }
+# define gcmDUMP_API_DATA __dummy_dump_api_data
+#endif
+
+/*******************************************************************************
+** gcmDUMP_2D_COMMAND
+**
+** Print the 2D command buffer.
+**
+** ARGUMENTS:
+**
+** gctUINT32_PTR Pointer to the command buffer.
+** gctUINT32 Command buffer size.
+*/
+gceSTATUS gcfDump2DCommand(IN gctUINT32_PTR Command, IN gctUINT32 Size);
+#if gcdDUMP_2D
+# define gcmDUMP_2D_COMMAND(cmd, size) \
+ if (Hardware->newDump2DLevel > 1) \
+ gcfDump2DCommand(cmd, size)
+#elif gcdHAS_ELLIPSIS
+# define gcmDUMP_2D_COMMAND(...)
+#else
+ gcmINLINE static void
+ __dummy_dump_2d_command(
+ IN gctUINT32_PTR Command,
+ IN gctUINT32 Size
+ )
+ {
+ }
+# define gcmDUMP_2D_COMMAND __dummy_dump_2d_command
+#endif
+
+/*******************************************************************************
+** gcmDUMP_2D_SURFACE
+**
+** Print the 2D surface memory.
+**
+** ARGUMENTS:
+**
+** gctBOOL Src.
+** gctUINT32 Address.
+*/
+gceSTATUS gcfDump2DSurface(IN gctBOOL Src, IN gctUINT32 Address);
+#if gcdDUMP_2D
+# define gcmDUMP_2D_SURFACE(src, addr) \
+ if (Hardware->newDump2DLevel > 2) \
+ gcfDump2DSurface(src, addr)
+#elif gcdHAS_ELLIPSIS
+# define gcmDUMP_2D_SURFACE(...)
+#else
+ gcmINLINE static void
+ __dummy_dump_2d_surface(
+ IN gctBOOL Src,
+ IN gctUINT32 Address
+ )
+ {
+ }
+# define gcmDUMP_2D_SURFACE __dummy_dump_2d_surface
+#endif
+
+/*******************************************************************************
+** gcmDUMP_ADD_MEMORY_INFO
+**
+** Record the memory info.
+**
+** ARGUMENTS:
+**
+** gctUINT32 Address.
+** gctSIZE_T Size.
+*/
+gceSTATUS gcfAddMemoryInfo(IN gctUINT32 GPUAddress, IN gctPOINTER Logical, IN gctUINT32 Physical, IN gctUINT32 Size);
+#if gcdDUMP_2D
+# define gcmDUMP_ADD_MEMORY_INFO gcfAddMemoryInfo
+#elif gcdHAS_ELLIPSIS
+# define gcmDUMP_ADD_MEMORY_INFO(...)
+#else
+ gcmINLINE static void
+ __dummy_dump_add_memory_info(
+ IN gctUINT32 GPUAddress,
+ IN gctPOINTER Logical,
+ IN gctUINT32 Physical,
+ IN gctUINT32 Size
+ )
+ {
+ }
+# define gcmDUMP_ADD_MEMORY_INFO __dummy_dump_add_memory_info
+#endif
+
+/*******************************************************************************
+** gcmDUMP_DEL_MEMORY_INFO
+**
+** Record the memory info.
+**
+** ARGUMENTS:
+**
+** gctUINT32 Address.
+*/
+gceSTATUS gcfDelMemoryInfo(IN gctUINT32 Address);
+#if gcdDUMP_2D
+# define gcmDUMP_DEL_MEMORY_INFO gcfDelMemoryInfo
+#elif gcdHAS_ELLIPSIS
+# define gcmDUMP_DEL_MEMORY_INFO(...)
+#else
+ gcmINLINE static void
+ __dummy_dump_del_memory_info(
+ IN gctUINT32 Address
+ )
+ {
+ }
+# define gcmDUMP_DEL_MEMORY_INFO __dummy_dump_del_memory_info
+#endif
+
+/*******************************************************************************
+**
+** gcmTRACE_RELEASE
+**
+** Print a message to the shader debugger.
+**
+** ARGUMENTS:
+**
+** message Message.
+** ... Optional arguments.
+*/
+
+#define gcmTRACE_RELEASE gcoOS_DebugShaderTrace
+
+void
+gcoOS_DebugShaderTrace(
+ IN gctCONST_STRING Message,
+ ...
+ );
+
+void
+gcoOS_SetDebugShaderFiles(
+ IN gctCONST_STRING VSFileName,
+ IN gctCONST_STRING FSFileName
+ );
+
+void
+gcoOS_SetDebugShaderFileType(
+ IN gctUINT32 ShaderType
+ );
+
+void
+gcoOS_EnableDebugBuffer(
+ IN gctBOOL Enable
+ );
+
+/*******************************************************************************
+**
+** gcmBREAK
+**
+** Break into the debugger. In retail mode this macro does nothing.
+**
+** ARGUMENTS:
+**
+** None.
+*/
+
+void
+gcoOS_DebugBreak(
+ void
+ );
+
+void
+gckOS_DebugBreak(
+ void
+ );
+
+#if gcmIS_DEBUG(gcdDEBUG_BREAK)
+# define gcmBREAK gcoOS_DebugBreak
+# define gcmkBREAK gckOS_DebugBreak
+#else
+# define gcmBREAK()
+# define gcmkBREAK()
+#endif
+
+/*******************************************************************************
+**
+** gcmASSERT
+**
+** Evaluate an expression and break into the debugger if the expression
+** evaluates to false. In retail mode this macro does nothing.
+**
+** ARGUMENTS:
+**
+** exp Expression to evaluate.
+*/
+#if gcmIS_DEBUG(gcdDEBUG_ASSERT)
+# define _gcmASSERT(prefix, exp) \
+ do \
+ { \
+ if (!(exp)) \
+ { \
+ prefix##TRACE(gcvLEVEL_ERROR, \
+ #prefix "ASSERT at %s(%d)", \
+ __FUNCTION__, __LINE__); \
+ prefix##TRACE(gcvLEVEL_ERROR, \
+ "(%s)", #exp); \
+ prefix##BREAK(); \
+ } \
+ } \
+ while (gcvFALSE)
+# define gcmASSERT(exp) _gcmASSERT(gcm, exp)
+# define gcmkASSERT(exp) _gcmASSERT(gcmk, exp)
+#else
+# define gcmASSERT(exp)
+# define gcmkASSERT(exp)
+#endif
+
+/*******************************************************************************
+**
+** gcmVERIFY
+**
+** Verify if an expression returns true. If the expression does not
+** evaluates to true, an assertion will happen in debug mode.
+**
+** ARGUMENTS:
+**
+** exp Expression to evaluate.
+*/
+#if gcmIS_DEBUG(gcdDEBUG_ASSERT)
+# define gcmVERIFY(exp) gcmASSERT(exp)
+# define gcmkVERIFY(exp) gcmkASSERT(exp)
+#else
+# define gcmVERIFY(exp) exp
+# define gcmkVERIFY(exp) exp
+#endif
+
+/*******************************************************************************
+**
+** gcmVERIFY_OK
+**
+** Verify a fucntion returns gcvSTATUS_OK. If the function does not return
+** gcvSTATUS_OK, an assertion will happen in debug mode.
+**
+** ARGUMENTS:
+**
+** func Function to evaluate.
+*/
+
+void
+gcoOS_Verify(
+ IN gceSTATUS status
+ );
+
+void
+gckOS_Verify(
+ IN gceSTATUS status
+ );
+
+#if gcmIS_DEBUG(gcdDEBUG_ASSERT)
+# define gcmVERIFY_OK(func) \
+ do \
+ { \
+ gceSTATUS verifyStatus = func; \
+ gcoOS_Verify(verifyStatus); \
+ if (verifyStatus != gcvSTATUS_OK) \
+ { \
+ gcmTRACE(\
+ gcvLEVEL_ERROR, \
+ "gcmVERIFY_OK(%d): function returned %d", \
+ __LINE__, verifyStatus \
+ ); \
+ } \
+ gcmASSERT(verifyStatus == gcvSTATUS_OK); \
+ } \
+ while (gcvFALSE)
+# define gcmkVERIFY_OK(func) \
+ do \
+ { \
+ gceSTATUS verifyStatus = func; \
+ if (verifyStatus != gcvSTATUS_OK) \
+ { \
+ gcmkTRACE(\
+ gcvLEVEL_ERROR, \
+ "gcmkVERIFY_OK(%d): function returned %d", \
+ __LINE__, verifyStatus \
+ ); \
+ } \
+ gckOS_Verify(verifyStatus); \
+ gcmkASSERT(verifyStatus == gcvSTATUS_OK); \
+ } \
+ while (gcvFALSE)
+#else
+# define gcmVERIFY_OK(func) (void)func
+# define gcmkVERIFY_OK(func) (void)func
+#endif
+
+gctCONST_STRING
+gcoOS_DebugStatus2Name(
+ gceSTATUS status
+ );
+
+gctCONST_STRING
+gckOS_DebugStatus2Name(
+ gceSTATUS status
+ );
+
+#if gcmIS_DEBUG(gcdDEBUG)
+# define gcmSTATUS2NAME gcoOS_DebugStatus2Name
+# define gcmkSTATUS2NAME gckOS_DebugStatus2Name
+#else
+# define gcmSTATUS2NAME(status) status
+# define gcmkSTATUS2NAME(status) status
+#endif
+
+/*******************************************************************************
+**
+** gcmERR_BREAK
+**
+** Executes a break statement on error.
+**
+** ASSUMPTIONS:
+**
+** 'status' variable of gceSTATUS type must be defined.
+**
+** ARGUMENTS:
+**
+** func Function to evaluate.
+*/
+#define _gcmERR_BREAK(prefix, func) \
+ status = func; \
+ if (gcmIS_ERROR(status)) \
+ { \
+ prefix##PRINT_VERSION(); \
+ prefix##TRACE(gcvLEVEL_ERROR, \
+ #prefix "ERR_BREAK: status=%d(%s) @ %s(%d)", \
+ status, gcmSTATUS2NAME(status), __FUNCTION__, __LINE__); \
+ break; \
+ } \
+ do { } while (gcvFALSE)
+#define _gcmkERR_BREAK(prefix, func) \
+ status = func; \
+ if (gcmIS_ERROR(status)) \
+ { \
+ prefix##PRINT_VERSION(); \
+ prefix##TRACE(gcvLEVEL_ERROR, \
+ #prefix "ERR_BREAK: status=%d(%s) @ %s(%d)", \
+ status, gckOS_DebugStatus2Name(status), __FUNCTION__, __LINE__); \
+ break; \
+ } \
+ do { } while (gcvFALSE)
+#define gcmERR_BREAK(func) _gcmERR_BREAK(gcm, func)
+#define gcmkERR_BREAK(func) _gcmkERR_BREAK(gcmk, func)
+
+/*******************************************************************************
+**
+** gcmERR_RETURN
+**
+** Executes a return on error.
+**
+** ASSUMPTIONS:
+**
+** 'status' variable of gceSTATUS type must be defined.
+**
+** ARGUMENTS:
+**
+** func Function to evaluate.
+*/
+#define _gcmERR_RETURN(prefix, func) \
+ status = func; \
+ if (gcmIS_ERROR(status)) \
+ { \
+ prefix##PRINT_VERSION(); \
+ prefix##TRACE(gcvLEVEL_ERROR, \
+ #prefix "ERR_RETURN: status=%d(%s) @ %s(%d)", \
+ status, gcmSTATUS2NAME(status), __FUNCTION__, __LINE__); \
+ prefix##FOOTER(); \
+ return status; \
+ } \
+ do { } while (gcvFALSE)
+#define _gcmkERR_RETURN(prefix, func) \
+ status = func; \
+ if (gcmIS_ERROR(status)) \
+ { \
+ prefix##PRINT_VERSION(); \
+ prefix##TRACE(gcvLEVEL_ERROR, \
+ #prefix "ERR_RETURN: status=%d(%s) @ %s(%d)", \
+ status, gcmkSTATUS2NAME(status), __FUNCTION__, __LINE__); \
+ prefix##FOOTER(); \
+ return status; \
+ } \
+ do { } while (gcvFALSE)
+#define gcmERR_RETURN(func) _gcmERR_RETURN(gcm, func)
+#define gcmkERR_RETURN(func) _gcmkERR_RETURN(gcmk, func)
+
+
+/*******************************************************************************
+**
+** gcmONERROR
+**
+** Jump to the error handler in case there is an error.
+**
+** ASSUMPTIONS:
+**
+** 'status' variable of gceSTATUS type must be defined.
+**
+** ARGUMENTS:
+**
+** func Function to evaluate.
+*/
+#define _gcmONERROR(prefix, func) \
+ do \
+ { \
+ status = func; \
+ if (gcmIS_ERROR(status)) \
+ { \
+ prefix##PRINT_VERSION(); \
+ prefix##TRACE(gcvLEVEL_ERROR, \
+ #prefix "ONERROR: status=%d(%s) @ %s(%d)", \
+ status, gcmSTATUS2NAME(status), __FUNCTION__, __LINE__); \
+ goto OnError; \
+ } \
+ } \
+ while (gcvFALSE)
+#define _gcmkONERROR(prefix, func) \
+ do \
+ { \
+ status = func; \
+ if (gcmIS_ERROR(status)) \
+ { \
+ prefix##PRINT_VERSION(); \
+ prefix##TRACE(gcvLEVEL_ERROR, \
+ #prefix "ONERROR: status=%d(%s) @ %s(%d)", \
+ status, gcmkSTATUS2NAME(status), __FUNCTION__, __LINE__); \
+ goto OnError; \
+ } \
+ } \
+ while (gcvFALSE)
+#define gcmONERROR(func) _gcmONERROR(gcm, func)
+#define gcmkONERROR(func) _gcmkONERROR(gcmk, func)
+
+#define gcmGET_INDEX_SIZE(type, size) \
+ switch (type) \
+ { \
+ case gcvINDEX_8: \
+ size = 1; \
+ break; \
+ case gcvINDEX_16: \
+ size = 2; \
+ break; \
+ case gcvINDEX_32: \
+ size = 4; \
+ break; \
+ default: \
+ gcmONERROR(gcvSTATUS_INVALID_ARGUMENT); \
+ } \
+
+/*******************************************************************************
+**
+** gcmkSAFECASTSIZET
+**
+** Check wether value of a gctSIZE_T varible beyond the capability
+** of 32bits GPU hardware.
+**
+** ASSUMPTIONS:
+**
+**
+**
+** ARGUMENTS:
+**
+** x A gctUINT32 variable
+** y A gctSIZE_T variable
+*/
+#define gcmkSAFECASTSIZET(x, y) \
+ do \
+ { \
+ gctUINT32 tmp = (gctUINT32)(y); \
+ if (gcmSIZEOF(gctSIZE_T) > gcmSIZEOF(gctUINT32)) \
+ { \
+ gcmkASSERT(tmp <= gcvMAXUINT32); \
+ } \
+ (x) = tmp; \
+ } \
+ while (gcvFALSE)
+
+#define gcmSAFECASTSIZET(x, y) \
+ do \
+ { \
+ gctUINT32 tmp = (gctUINT32)(y); \
+ if (gcmSIZEOF(gctSIZE_T) > gcmSIZEOF(gctUINT32)) \
+ { \
+ gcmASSERT(tmp <= gcvMAXUINT32); \
+ } \
+ (x) = tmp; \
+ } \
+ while (gcvFALSE)
+
+/*******************************************************************************
+**
+** gcmkSAFECASTPHYSADDRT
+**
+** Check whether value of a gctPHYS_ADDR_T variable beyond the capability
+** of 32bits GPU hardware.
+**
+** ASSUMPTIONS:
+**
+**
+**
+** ARGUMENTS:
+**
+** x A gctUINT32 variable
+** y A gctPHYS_ADDR_T variable
+*/
+#define gcmkSAFECASTPHYSADDRT(x, y) \
+ do \
+ { \
+ gctUINT32 tmp = (gctUINT32)(y); \
+ if (gcmSIZEOF(gctPHYS_ADDR_T) > gcmSIZEOF(gctUINT32)) \
+ { \
+ gcmkASSERT(tmp <= gcvMAXUINT32); \
+ } \
+ (x) = tmp; \
+ } \
+ while (gcvFALSE)
+
+/*******************************************************************************
+**
+** gcmSAFECASTPHYSADDRT
+**
+** Check whether value of a gctPHYS_ADDR_T variable beyond the capability
+** of 32bits GPU hardware.
+**
+** ASSUMPTIONS:
+**
+**
+**
+** ARGUMENTS:
+**
+** x A gctUINT32 variable
+** y A gctPHYS_ADDR_T variable
+*/
+#define gcmSAFECASTPHYSADDRT(x, y) \
+ do \
+ { \
+ gctUINT32 tmp = (gctUINT32)(y); \
+ if (gcmSIZEOF(gctPHYS_ADDR_T) > gcmSIZEOF(gctUINT32)) \
+ { \
+ gcmASSERT(tmp <= gcvMAXUINT32); \
+ } \
+ (x) = tmp; \
+ } \
+ while (gcvFALSE)
+
+/*******************************************************************************
+**
+** gcmVERIFY_LOCK
+**
+** Verifies whether the surface is locked.
+**
+** ARGUMENTS:
+**
+** surfaceInfo Pointer to the surface iniformational structure.
+*/
+#define gcmVERIFY_LOCK(surfaceInfo) \
+ if (!surfaceInfo->node.valid) \
+ { \
+ gcmONERROR(gcvSTATUS_MEMORY_UNLOCKED); \
+ } \
+
+/*******************************************************************************
+**
+** gcmVERIFY_NODE_LOCK
+**
+** Verifies whether the surface node is locked.
+**
+** ARGUMENTS:
+**
+** surfaceInfo Pointer to the surface iniformational structure.
+*/
+#define gcmVERIFY_NODE_LOCK(surfaceNode) \
+ if (!(surfaceNode)->valid) \
+ { \
+ status = gcvSTATUS_MEMORY_UNLOCKED; \
+ break; \
+ } \
+ do { } while (gcvFALSE)
+
+/*******************************************************************************
+**
+** gcmBADOBJECT_BREAK
+**
+** Executes a break statement on bad object.
+**
+** ARGUMENTS:
+**
+** obj Object to test.
+** t Expected type of the object.
+*/
+#define gcmBADOBJECT_BREAK(obj, t) \
+ if ((obj == gcvNULL) \
+ || (((gcsOBJECT *)(obj))->type != t) \
+ ) \
+ { \
+ status = gcvSTATUS_INVALID_OBJECT; \
+ break; \
+ } \
+ do { } while (gcvFALSE)
+
+/*******************************************************************************
+**
+** gcmCHECK_STATUS
+**
+** Executes a break statement on error.
+**
+** ASSUMPTIONS:
+**
+** 'status' variable of gceSTATUS type must be defined.
+**
+** ARGUMENTS:
+**
+** func Function to evaluate.
+*/
+#define _gcmCHECK_STATUS(prefix, func) \
+ do \
+ { \
+ last = func; \
+ if (gcmIS_ERROR(last)) \
+ { \
+ prefix##TRACE(gcvLEVEL_ERROR, \
+ #prefix "CHECK_STATUS: status=%d(%s) @ %s(%d)", \
+ last, gcmSTATUS2NAME(last), __FUNCTION__, __LINE__); \
+ status = last; \
+ } \
+ } \
+ while (gcvFALSE)
+#define _gcmkCHECK_STATUS(prefix, func) \
+ do \
+ { \
+ last = func; \
+ if (gcmIS_ERROR(last)) \
+ { \
+ prefix##TRACE(gcvLEVEL_ERROR, \
+ #prefix "CHECK_STATUS: status=%d(%s) @ %s(%d)", \
+ last, gcmkSTATUS2NAME(last), __FUNCTION__, __LINE__); \
+ status = last; \
+ } \
+ } \
+ while (gcvFALSE)
+#define gcmCHECK_STATUS(func) _gcmCHECK_STATUS(gcm, func)
+#define gcmkCHECK_STATUS(func) _gcmkCHECK_STATUS(gcmk, func)
+
+/*******************************************************************************
+**
+** gcmVERIFY_ARGUMENT
+**
+** Assert if an argument does not apply to the specified expression. If
+** the argument evaluates to false, gcvSTATUS_INVALID_ARGUMENT will be
+** returned from the current function. In retail mode this macro does
+** nothing.
+**
+** ARGUMENTS:
+**
+** arg Argument to evaluate.
+*/
+# define _gcmVERIFY_ARGUMENT(prefix, arg) \
+ do \
+ { \
+ if (!(arg)) \
+ { \
+ prefix##TRACE(gcvLEVEL_ERROR, #prefix "VERIFY_ARGUMENT failed:"); \
+ prefix##ASSERT(arg); \
+ prefix##FOOTER_ARG("status=%d", gcvSTATUS_INVALID_ARGUMENT); \
+ return gcvSTATUS_INVALID_ARGUMENT; \
+ } \
+ } \
+ while (gcvFALSE)
+# define gcmVERIFY_ARGUMENT(arg) _gcmVERIFY_ARGUMENT(gcm, arg)
+# define gcmkVERIFY_ARGUMENT(arg) _gcmVERIFY_ARGUMENT(gcmk, arg)
+
+/*******************************************************************************
+**
+** gcmDEBUG_VERIFY_ARGUMENT
+**
+** Works just like gcmVERIFY_ARGUMENT, but is only valid in debug mode.
+** Use this to verify arguments inside non-public API functions.
+*/
+#if gcdDEBUG
+# define gcmDEBUG_VERIFY_ARGUMENT(arg) _gcmVERIFY_ARGUMENT(gcm, arg)
+# define gcmkDEBUG_VERIFY_ARGUMENT(arg) _gcmkVERIFY_ARGUMENT(gcm, arg)
+#else
+# define gcmDEBUG_VERIFY_ARGUMENT(arg)
+# define gcmkDEBUG_VERIFY_ARGUMENT(arg)
+#endif
+
+/*******************************************************************************
+**
+** gcmVERIFY_ARGUMENT_RETURN
+**
+** Assert if an argument does not apply to the specified expression. If
+** the argument evaluates to false, gcvSTATUS_INVALID_ARGUMENT will be
+** returned from the current function. In retail mode this macro does
+** nothing.
+**
+** ARGUMENTS:
+**
+** arg Argument to evaluate.
+*/
+# define _gcmVERIFY_ARGUMENT_RETURN(prefix, arg, value) \
+ do \
+ { \
+ if (!(arg)) \
+ { \
+ prefix##TRACE(gcvLEVEL_ERROR, \
+ #prefix "gcmVERIFY_ARGUMENT_RETURN failed:"); \
+ prefix##ASSERT(arg); \
+ prefix##FOOTER_ARG("value=%d", value); \
+ return value; \
+ } \
+ } \
+ while (gcvFALSE)
+# define gcmVERIFY_ARGUMENT_RETURN(arg, value) \
+ _gcmVERIFY_ARGUMENT_RETURN(gcm, arg, value)
+# define gcmkVERIFY_ARGUMENT_RETURN(arg, value) \
+ _gcmVERIFY_ARGUMENT_RETURN(gcmk, arg, value)
+
+#define MAX_LOOP_COUNT 0x7FFFFFFF
+
+/******************************************************************************\
+****************************** User Debug Option ******************************
+\******************************************************************************/
+
+/* User option. */
+typedef enum _gceDEBUG_MSG
+{
+ gcvDEBUG_MSG_NONE,
+ gcvDEBUG_MSG_ERROR,
+ gcvDEBUG_MSG_WARNING
+}
+gceDEBUG_MSG;
+
+typedef struct _gcsUSER_DEBUG_OPTION
+{
+ gceDEBUG_MSG debugMsg;
+}
+gcsUSER_DEBUG_OPTION;
+
+gcsUSER_DEBUG_OPTION *
+gcoHAL_GetUserDebugOption(
+ void
+ );
+
+#if gcdHAS_ELLIPSIS
+#define gcmUSER_DEBUG_MSG(level, ...) \
+ do \
+ { \
+ if (level <= gcoHAL_GetUserDebugOption()->debugMsg) \
+ { \
+ gcoOS_Print(__VA_ARGS__); \
+ } \
+ } while (gcvFALSE)
+
+#define gcmUSER_DEBUG_ERROR_MSG(...) gcmUSER_DEBUG_MSG(gcvDEBUG_MSG_ERROR, "Error: " __VA_ARGS__)
+#define gcmUSER_DEBUG_WARNING_MSG(...) gcmUSER_DEBUG_MSG(gcvDEBUG_MSG_WARNING, "Warring: " __VA_ARGS__)
+#else
+#define gcmUSER_DEBUG_MSG
+#define gcmUSER_DEBUG_ERROR_MSG
+#define gcmUSER_DEBUG_WARNING_MSG
+#endif
+
+/*******************************************************************************
+**
+** A set of macros to aid state loading.
+**
+** ARGUMENTS:
+**
+** CommandBuffer Pointer to a gcoCMDBUF object.
+** StateDelta Pointer to a gcsSTATE_DELTA state delta structure.
+** Memory Destination memory pointer of gctUINT32_PTR type.
+** PartOfContext Whether or not the state is a part of the context.
+** FixedPoint Whether or not the state is of the fixed point format.
+** Count Number of consecutive states to be loaded.
+** Address State address.
+** Data Data to be set to the state.
+*/
+
+/*----------------------------------------------------------------------------*/
+
+#if gcmIS_DEBUG(gcdDEBUG_CODE)
+
+# define gcmSTORELOADSTATE(CommandBuffer, Memory, Address, Count) \
+ CommandBuffer->lastLoadStatePtr = gcmPTR_TO_UINT64(Memory); \
+ CommandBuffer->lastLoadStateAddress = Address; \
+ CommandBuffer->lastLoadStateCount = Count
+
+# define gcmVERIFYLOADSTATE(CommandBuffer, Memory, Address) \
+ gcmASSERT(\
+ (gctUINT) (Memory - gcmUINT64_TO_TYPE(CommandBuffer->lastLoadStatePtr, gctUINT32_PTR) - 1) \
+ == \
+ (gctUINT) (Address - CommandBuffer->lastLoadStateAddress) \
+ ); \
+ \
+ gcmASSERT(CommandBuffer->lastLoadStateCount > 0); \
+ \
+ CommandBuffer->lastLoadStateCount -= 1
+
+# define gcmVERIFYLOADSTATEDONE(CommandBuffer) \
+ gcmASSERT(CommandBuffer->lastLoadStateCount == 0);
+
+# define gcmDEFINELOADSTATEBASE() \
+ gctUINT32_PTR LoadStateBase;
+
+# define gcmSETLOADSTATEBASE(CommandBuffer, OutSide) \
+ if (OutSide) \
+ {\
+ LoadStateBase = (gctUINT32_PTR)*OutSide; \
+ }\
+ else\
+ {\
+ LoadStateBase = (gctUINT_PTR)CommandBuffer->buffer;\
+ }
+
+
+# define gcmVERIFYLOADSTATEALIGNED(CommandBuffer, Memory) \
+ gcmASSERT(((Memory - LoadStateBase) & 1) == 0);
+
+# define gcmUNSETLOADSTATEBASE() \
+ LoadStateBase = LoadStateBase;
+
+#else
+
+# define gcmSTORELOADSTATE(CommandBuffer, Memory, Address, Count)
+# define gcmVERIFYLOADSTATE(CommandBuffer, Memory, Address)
+# define gcmVERIFYLOADSTATEDONE(CommandBuffer)
+
+# define gcmDEFINELOADSTATEBASE()
+# define gcmSETLOADSTATEBASE(CommandBuffer, OutSide)
+# define gcmVERIFYLOADSTATEALIGNED(CommandBuffer, Memory)
+# define gcmUNSETLOADSTATEBASE()
+
+#endif
+
+#if gcdSECURE_USER
+
+# define gcmDEFINESECUREUSER() \
+ gctUINT __secure_user_offset__; \
+ gctUINT32_PTR __secure_user_hintArray__;
+
+# define gcmBEGINSECUREUSER() \
+ __secure_user_offset__ = reserve->lastOffset; \
+ \
+ __secure_user_hintArray__ = gcmUINT64_TO_PTR(reserve->hintArrayTail)
+
+# define gcmENDSECUREUSER() \
+ reserve->hintArrayTail = gcmPTR_TO_UINT64(__secure_user_hintArray__)
+
+# define gcmSKIPSECUREUSER() \
+ __secure_user_offset__ += gcmSIZEOF(gctUINT32)
+
+# define gcmUPDATESECUREUSER() \
+ *__secure_user_hintArray__ = __secure_user_offset__; \
+ \
+ __secure_user_offset__ += gcmSIZEOF(gctUINT32); \
+ __secure_user_hintArray__ += 1
+
+#else
+
+# define gcmDEFINESECUREUSER()
+# define gcmBEGINSECUREUSER()
+# define gcmENDSECUREUSER()
+# define gcmSKIPSECUREUSER()
+# define gcmUPDATESECUREUSER()
+
+#endif
+
+/*----------------------------------------------------------------------------*/
+
+#if gcdDUMP
+# define gcmDUMPSTATEDATA(StateDelta, FixedPoint, Address, Data) \
+ if (FixedPoint) \
+ { \
+ gcmDUMP(gcvNULL, "#[state.x 0x%04X 0x%08X]", \
+ Address, Data \
+ ); \
+ } \
+ else \
+ { \
+ gcmDUMP(gcvNULL, "#[state 0x%04X 0x%08X]", \
+ Address, Data \
+ ); \
+ }
+#else
+# define gcmDUMPSTATEDATA(StateDelta, FixedPoint, Address, Data)
+#endif
+
+#define gcmDEFINESTATEBUFFER(CommandBuffer, StateDelta, Memory, ReserveSize) \
+ gcmDEFINESECUREUSER() \
+ gctSIZE_T ReserveSize; \
+ gcoCMDBUF CommandBuffer; \
+ gctUINT32_PTR Memory; \
+ gcsSTATE_DELTA_PTR StateDelta; \
+ gceENGINE CurrentEngine = gcvENGINE_RENDER
+
+#define gcmBEGINSTATEBUFFER(Hardware, CommandBuffer, StateDelta, Memory, ReserveSize) \
+{ \
+ gcmONERROR(gcoBUFFER_Reserve(\
+ Hardware->engine[CurrentEngine].buffer, ReserveSize, gcvTRUE, gcvCOMMAND_3D, &CommandBuffer \
+ )); \
+ \
+ Memory = (gctUINT32_PTR) gcmUINT64_TO_PTR(CommandBuffer->lastReserve); \
+ \
+ StateDelta = Hardware->delta; \
+ \
+ gcmBEGINSECUREUSER(); \
+}
+
+#define gcmENDSTATEBUFFER(Hardware, CommandBuffer, Memory, ReserveSize) \
+{ \
+ gcmENDSECUREUSER(); \
+ \
+ gcmASSERT(\
+ gcmUINT64_TO_TYPE(CommandBuffer->lastReserve, gctUINT8_PTR) + ReserveSize \
+ == \
+ (gctUINT8_PTR) Memory \
+ ); \
+}
+
+/*----------------------------------------------------------------------------*/
+
+#define gcmBEGINSTATEBATCH(CommandBuffer, Memory, FixedPoint, Address, Count) \
+{ \
+ gcmASSERT(((Memory - gcmUINT64_TO_TYPE(CommandBuffer->lastReserve, gctUINT32_PTR)) & 1) == 0); \
+ gcmASSERT((gctUINT32)Count <= 1024); \
+ \
+ gcmVERIFYLOADSTATEDONE(CommandBuffer); \
+ \
+ gcmSTORELOADSTATE(CommandBuffer, Memory, Address, Count); \
+ \
+ *Memory++ \
+ = gcmSETFIELDVALUE(0, AQ_COMMAND_LOAD_STATE_COMMAND, OPCODE, LOAD_STATE) \
+ | gcmSETFIELD (0, AQ_COMMAND_LOAD_STATE_COMMAND, FLOAT, FixedPoint) \
+ | gcmSETFIELD (0, AQ_COMMAND_LOAD_STATE_COMMAND, COUNT, Count) \
+ | gcmSETFIELD (0, AQ_COMMAND_LOAD_STATE_COMMAND, ADDRESS, Address); \
+ \
+ gcmSKIPSECUREUSER(); \
+}
+
+#define gcmENDSTATEBATCH(CommandBuffer, Memory) \
+{ \
+ gcmVERIFYLOADSTATEDONE(CommandBuffer); \
+ \
+ gcmASSERT(((Memory - gcmUINT64_TO_TYPE(CommandBuffer->lastReserve, gctUINT32_PTR)) & 1) == 0); \
+}
+
+/*----------------------------------------------------------------------------*/
+
+#define gcmSETSTATEDATA(StateDelta, CommandBuffer, Memory, FixedPoint, \
+ Address, Data) \
+{ \
+ gctUINT32 __temp_data32__; \
+ \
+ gcmVERIFYLOADSTATE(CommandBuffer, Memory, Address); \
+ \
+ gcmSAFECASTSIZET(__temp_data32__, Data); \
+ \
+ *Memory++ = __temp_data32__; \
+ \
+ gcoHARDWARE_UpdateDelta(\
+ StateDelta, Address, 0, __temp_data32__ \
+ ); \
+ \
+ gcmDUMPSTATEDATA(StateDelta, FixedPoint, Address, __temp_data32__); \
+ \
+ gcmUPDATESECUREUSER(); \
+}
+
+#define gcmSETSTATEDATAWITHMASK(StateDelta, CommandBuffer, Memory, FixedPoint, \
+ Address, Mask, Data) \
+{ \
+ gctUINT32 __temp_data32__; \
+ \
+ gcmVERIFYLOADSTATE(CommandBuffer, Memory, Address); \
+ \
+ __temp_data32__ = Data; \
+ \
+ *Memory++ = __temp_data32__; \
+ \
+ gcoHARDWARE_UpdateDelta(\
+ StateDelta, Address, Mask, __temp_data32__ \
+ ); \
+ \
+ gcmDUMPSTATEDATA(StateDelta, FixedPoint, Address, __temp_data32__); \
+ \
+ gcmUPDATESECUREUSER(); \
+}
+
+
+#define gcmSETCTRLSTATE(StateDelta, CommandBuffer, Memory, Address, Data) \
+{ \
+ gctUINT32 __temp_data32__; \
+ \
+ gcmVERIFYLOADSTATE(CommandBuffer, Memory, Address); \
+ \
+ __temp_data32__ = Data; \
+ \
+ *Memory++ = __temp_data32__; \
+ \
+ gcmDUMPSTATEDATA(StateDelta, gcvFALSE, Address, __temp_data32__); \
+ \
+ gcmSKIPSECUREUSER(); \
+}
+
+#define gcmSETFILLER(CommandBuffer, Memory) \
+{ \
+ gcmVERIFYLOADSTATEDONE(CommandBuffer); \
+ \
+ Memory += 1; \
+ \
+ gcmSKIPSECUREUSER(); \
+}
+
+/*----------------------------------------------------------------------------*/
+
+#define gcmSETSINGLESTATE(StateDelta, CommandBuffer, Memory, FixedPoint, \
+ Address, Data) \
+{ \
+ gcmBEGINSTATEBATCH(CommandBuffer, Memory, FixedPoint, Address, 1); \
+ gcmSETSTATEDATA(StateDelta, CommandBuffer, Memory, FixedPoint, \
+ Address, Data); \
+ gcmENDSTATEBATCH(CommandBuffer, Memory); \
+}
+
+#define gcmSETSINGLESTATEWITHMASK(StateDelta, CommandBuffer, Memory, FixedPoint, \
+ Address, Mask, Data) \
+{ \
+ gcmBEGINSTATEBATCH(CommandBuffer, Memory, FixedPoint, Address, 1); \
+ gcmSETSTATEDATAWITHMASK(StateDelta, CommandBuffer, Memory, FixedPoint, \
+ Address, Mask, Data); \
+ gcmENDSTATEBATCH(CommandBuffer, Memory); \
+}
+
+
+#define gcmSETSINGLECTRLSTATE(StateDelta, CommandBuffer, Memory, FixedPoint, \
+ Address, Data) \
+{ \
+ gcmBEGINSTATEBATCH(CommandBuffer, Memory, FixedPoint, Address, 1); \
+ gcmSETCTRLSTATE(StateDelta, CommandBuffer, Memory, Address, Data); \
+ gcmENDSTATEBATCH(CommandBuffer, Memory); \
+}
+
+
+
+#define gcmSETSEMASTALLPIPE(StateDelta, CommandBuffer, Memory, Data) \
+{ \
+ gcmSETSINGLECTRLSTATE(StateDelta, CommandBuffer, Memory, gcvFALSE, 0x0E02, Data); \
+ \
+ *Memory++ = gcmSETFIELDVALUE(0, STALL_COMMAND, OPCODE, STALL); \
+ \
+ *Memory++ = Data; \
+ \
+ gcmDUMP(gcvNULL, "#[stall 0x%08X 0x%08X]", \
+ gcmSETFIELDVALUE(0, AQ_SEMAPHORE, SOURCE, FRONT_END), \
+ gcmSETFIELDVALUE(0, AQ_SEMAPHORE, DESTINATION, PIXEL_ENGINE)); \
+ \
+ gcmSKIPSECUREUSER(); \
+}
+
+/*******************************************************************************
+**
+** gcmSETSTARTDECOMMAND
+**
+** Form a START_DE command.
+**
+** ARGUMENTS:
+**
+** Memory Destination memory pointer of gctUINT32_PTR type.
+** Count Number of the rectangles.
+*/
+
+#define gcmSETSTARTDECOMMAND(Memory, Count) \
+{ \
+ *Memory++ \
+ = gcmSETFIELDVALUE(0, AQ_COMMAND_START_DE_COMMAND, OPCODE, START_DE) \
+ | gcmSETFIELD (0, AQ_COMMAND_START_DE_COMMAND, COUNT, Count) \
+ | gcmSETFIELD (0, AQ_COMMAND_START_DE_COMMAND, DATA_COUNT, 0); \
+ \
+ *Memory++ = 0xDEADDEED; \
+}
+
+/*****************************************
+** Temp command buffer macro
+*/
+#define gcmDEFINESTATEBUFFER_NEW(CommandBuffer, StateDelta, Memory) \
+ gcmDEFINESECUREUSER() \
+ gcmDEFINELOADSTATEBASE() \
+ gcsTEMPCMDBUF CommandBuffer = gcvNULL; \
+ gctUINT32_PTR Memory; \
+ gcsSTATE_DELTA_PTR StateDelta; \
+ gceENGINE CurrentEngine = gcvENGINE_RENDER
+
+
+#define gcmBEGINSTATEBUFFER_NEW(Hardware, CommandBuffer, StateDelta, Memory, OutSide) \
+{ \
+ if (OutSide) \
+ {\
+ Memory = (gctUINT32_PTR)*OutSide; \
+ }\
+ else \
+ {\
+ gcmONERROR(gcoBUFFER_StartTEMPCMDBUF(\
+ Hardware->engine[CurrentEngine].buffer, &CommandBuffer \
+ ));\
+ \
+ Memory = (gctUINT32_PTR)(CommandBuffer->buffer); \
+ \
+ }\
+ StateDelta = Hardware->delta; \
+ \
+ gcmBEGINSECUREUSER(); \
+ gcmSETLOADSTATEBASE(CommandBuffer,OutSide);\
+}
+
+#define gcmENDSTATEBUFFER_NEW(Hardware, CommandBuffer, Memory, OutSide) \
+{ \
+ gcmENDSECUREUSER(); \
+ \
+ if (OutSide) \
+ {\
+ *OutSide = Memory; \
+ }\
+ else \
+ {\
+ CommandBuffer->currentByteSize = (gctUINT32)((gctUINT8_PTR)Memory - \
+ (gctUINT8_PTR)CommandBuffer->buffer); \
+ \
+ gcmONERROR(gcoBUFFER_EndTEMPCMDBUF(Hardware->engine[CurrentEngine].buffer, gcvFALSE));\
+ }\
+ gcmUNSETLOADSTATEBASE()\
+}
+
+#define gcmDEFINECTRLSTATEBUFFER(CommandBuffer, Memory) \
+ gcmDEFINESECUREUSER() \
+ gcmDEFINELOADSTATEBASE() \
+ gcsTEMPCMDBUF CommandBuffer = gcvNULL; \
+ gctUINT32_PTR Memory; \
+ gceENGINE CurrentEngine = gcvENGINE_RENDER
+
+#define gcmBEGINCTRLSTATEBUFFER(Hardware, CommandBuffer, Memory, OutSide) \
+{ \
+ if (OutSide) \
+ { \
+ Memory = (gctUINT32_PTR)*OutSide; \
+ } \
+ else \
+ { \
+ gcmONERROR(gcoBUFFER_StartTEMPCMDBUF(\
+ Hardware->engine[CurrentEngine].buffer, &CommandBuffer \
+ )); \
+ \
+ Memory = (gctUINT32_PTR)(CommandBuffer->buffer); \
+ } \
+ gcmBEGINSECUREUSER(); \
+ gcmSETLOADSTATEBASE(CommandBuffer,OutSide); \
+}
+
+/*----------------------------------------------------------------------------*/
+
+#define gcmBEGINSTATEBATCH_NEW(CommandBuffer, Memory, FixedPoint, Address, Count) \
+{ \
+ gcmVERIFYLOADSTATEALIGNED(CommandBuffer,Memory);\
+ gcmASSERT((gctUINT32)Count <= 1024); \
+ \
+ *Memory++ \
+ = gcmSETFIELDVALUE(0, AQ_COMMAND_LOAD_STATE_COMMAND, OPCODE, LOAD_STATE) \
+ | gcmSETFIELD (0, AQ_COMMAND_LOAD_STATE_COMMAND, FLOAT, FixedPoint) \
+ | gcmSETFIELD (0, AQ_COMMAND_LOAD_STATE_COMMAND, COUNT, Count) \
+ | gcmSETFIELD (0, AQ_COMMAND_LOAD_STATE_COMMAND, ADDRESS, Address); \
+ \
+ gcmSKIPSECUREUSER(); \
+}
+
+#define gcmENDSTATEBATCH_NEW(CommandBuffer, Memory) \
+ gcmVERIFYLOADSTATEALIGNED(CommandBuffer,Memory);
+
+/*----------------------------------------------------------------------------*/
+
+#define gcmSETSTATEDATA_NEW(StateDelta, CommandBuffer, Memory, FixedPoint, \
+ Address, Data) \
+{ \
+ gctUINT32 __temp_data32__; \
+ \
+ gcmSAFECASTSIZET(__temp_data32__, Data); \
+ \
+ *Memory++ = __temp_data32__; \
+ \
+ gcoHARDWARE_UpdateDelta(\
+ StateDelta, Address, 0, __temp_data32__ \
+ ); \
+ \
+ gcmDUMPSTATEDATA(StateDelta, FixedPoint, Address, __temp_data32__); \
+ \
+ gcmUPDATESECUREUSER(); \
+}
+
+#define gcmSETSTATEDATAWITHMASK_NEW(StateDelta, CommandBuffer, Memory, FixedPoint, \
+ Address, Mask, Data) \
+{ \
+ gctUINT32 __temp_data32__; \
+ \
+ __temp_data32__ = Data; \
+ \
+ *Memory++ = __temp_data32__; \
+ \
+ gcoHARDWARE_UpdateDelta(\
+ StateDelta, Address, Mask, __temp_data32__ \
+ ); \
+ \
+ gcmDUMPSTATEDATA(StateDelta, FixedPoint, Address, __temp_data32__); \
+ \
+ gcmUPDATESECUREUSER(); \
+}
+
+
+#define gcmSETCTRLSTATE_NEW(StateDelta, CommandBuffer, Memory, Address, Data) \
+{ \
+ gctUINT32 __temp_data32__; \
+ \
+ __temp_data32__ = Data; \
+ \
+ *Memory++ = __temp_data32__; \
+ \
+ gcmDUMPSTATEDATA(StateDelta, gcvFALSE, Address, __temp_data32__); \
+ \
+ gcmSKIPSECUREUSER(); \
+}
+
+#define gcmSETFILLER_NEW(CommandBuffer, Memory) \
+{ \
+ Memory += 1; \
+ \
+ gcmSKIPSECUREUSER(); \
+}
+
+/*----------------------------------------------------------------------------*/
+
+#define gcmSETSINGLESTATE_NEW(StateDelta, CommandBuffer, Memory, FixedPoint, \
+ Address, Data) \
+{ \
+ gcmBEGINSTATEBATCH_NEW(CommandBuffer, Memory, FixedPoint, Address, 1); \
+ gcmSETSTATEDATA_NEW(StateDelta, CommandBuffer, Memory, FixedPoint, \
+ Address, Data); \
+ gcmENDSTATEBATCH_NEW(CommandBuffer, Memory); \
+}
+
+#define gcmSETSINGLESTATEWITHMASK_NEW(StateDelta, CommandBuffer, Memory, FixedPoint, \
+ Address, Mask, Data) \
+{ \
+ gcmBEGINSTATEBATCH_NEW(CommandBuffer, Memory, FixedPoint, Address, 1); \
+ gcmSETSTATEDATAWITHMASK_NEW(StateDelta, CommandBuffer, Memory, FixedPoint, \
+ Address, Mask, Data); \
+ gcmENDSTATEBATCH_NEW(CommandBuffer, Memory); \
+}
+
+
+#define gcmSETSINGLECTRLSTATE_NEW(StateDelta, CommandBuffer, Memory, FixedPoint, \
+ Address, Data) \
+{ \
+ gcmBEGINSTATEBATCH_NEW(CommandBuffer, Memory, FixedPoint, Address, 1); \
+ gcmSETCTRLSTATE_NEW(StateDelta, CommandBuffer, Memory, Address, Data); \
+ gcmENDSTATEBATCH_NEW(CommandBuffer, Memory); \
+}
+
+
+
+#define gcmSETSEMASTALLPIPE_NEW(StateDelta, CommandBuffer, Memory, Data) \
+{ \
+ gcmSETSINGLECTRLSTATE_NEW(StateDelta, CommandBuffer, Memory, gcvFALSE, 0x0E02, Data); \
+ \
+ *Memory++ = gcmSETFIELDVALUE(0, STALL_COMMAND, OPCODE, STALL); \
+ \
+ *Memory++ = Data; \
+ \
+ gcmDUMP(gcvNULL, "#[stall 0x%08X 0x%08X]", \
+ gcmSETFIELDVALUE(0, AQ_SEMAPHORE, SOURCE, FRONT_END), \
+ gcmSETFIELDVALUE(0, AQ_SEMAPHORE, DESTINATION, PIXEL_ENGINE)); \
+ \
+ gcmSKIPSECUREUSER(); \
+}
+
+#define gcmSETSTARTDECOMMAND_NEW(CommandBuffer, Memory, Count) \
+{ \
+ *Memory++ \
+ = gcmSETFIELDVALUE(0, AQ_COMMAND_START_DE_COMMAND, OPCODE, START_DE) \
+ | gcmSETFIELD (0, AQ_COMMAND_START_DE_COMMAND, COUNT, Count) \
+ | gcmSETFIELD (0, AQ_COMMAND_START_DE_COMMAND, DATA_COUNT, 0); \
+ \
+ *Memory++ = 0xDEADDEED; \
+ \
+}
+
+#define gcmSETSTATEDATA_NEW_FAST(StateDelta, CommandBuffer, Memory, FixedPoint, \
+ Address, Data) \
+{ \
+ gctUINT32 __temp_data32__; \
+ \
+ __temp_data32__ = Data; \
+ \
+ *Memory++ = __temp_data32__; \
+ \
+ gcmDUMPSTATEDATA(StateDelta, FixedPoint, Address, __temp_data32__); \
+ \
+ gcmUPDATESECUREUSER(); \
+}
+
+#define gcmSETSTATEDATAWITHMASK_NEW_FAST(StateDelta, CommandBuffer, Memory, FixedPoint, \
+ Address, Mask, Data) \
+{ \
+ gctUINT32 __temp_data32__; \
+ \
+ __temp_data32__ = Data; \
+ \
+ *Memory++ = __temp_data32__; \
+ \
+ gcmDUMPSTATEDATA(StateDelta, FixedPoint, Address, __temp_data32__); \
+ \
+ gcmUPDATESECUREUSER(); \
+}
+
+#define gcmSETSINGLESTATE_NEW_FAST(StateDelta, CommandBuffer, Memory, FixedPoint, \
+ Address, Data) \
+{ \
+ gcmBEGINSTATEBATCH_NEW(CommandBuffer, Memory, FixedPoint, Address, 1); \
+ gcmSETSTATEDATA_NEW_FAST(StateDelta, CommandBuffer, Memory, FixedPoint, \
+ Address, Data); \
+ gcmENDSTATEBATCH_NEW(CommandBuffer, Memory); \
+}
+
+#define gcmSETSINGLESTATEWITHMASK_NEW_FAST(StateDelta, CommandBuffer, Memory, FixedPoint, \
+ Address, Mask, Data) \
+{ \
+ gcmBEGINSTATEBATCH_NEW(CommandBuffer, Memory, FixedPoint, Address, 1); \
+ gcmSETSTATEDATAWITHMASK_NEW_FAST(StateDelta, CommandBuffer, Memory, FixedPoint, \
+ Address, Mask, Data); \
+ gcmENDSTATEBATCH_NEW(CommandBuffer, Memory); \
+}
+
+#define gcmSETSTATEDATA_FAST(StateDelta, CommandBuffer, Memory, FixedPoint, \
+ Address, Data) \
+{ \
+ gctUINT32 __temp_data32__; \
+ \
+ gcmVERIFYLOADSTATE(CommandBuffer, Memory, Address); \
+ \
+ gcmSAFECASTSIZET(__temp_data32__, Data); \
+ \
+ *Memory++ = __temp_data32__; \
+ \
+ gcmDUMPSTATEDATA(StateDelta, FixedPoint, Address, __temp_data32__); \
+ \
+ gcmUPDATESECUREUSER(); \
+}
+
+#define gcmSETSTATEDATAWITHMASK_FAST(StateDelta, CommandBuffer, Memory, FixedPoint, \
+ Address, Mask, Data) \
+{ \
+ gctUINT32 __temp_data32__; \
+ \
+ gcmVERIFYLOADSTATE(CommandBuffer, Memory, Address); \
+ \
+ __temp_data32__ = Data; \
+ \
+ *Memory++ = __temp_data32__; \
+ \
+ gcmDUMPSTATEDATA(StateDelta, FixedPoint, Address, __temp_data32__); \
+ \
+ gcmUPDATESECUREUSER(); \
+}
+
+#define gcmSETSINGLESTATE_FAST(StateDelta, CommandBuffer, Memory, FixedPoint, \
+ Address, Data) \
+{ \
+ gcmBEGINSTATEBATCH(CommandBuffer, Memory, FixedPoint, Address, 1); \
+ gcmSETSTATEDATA_FAST(StateDelta, CommandBuffer, Memory, FixedPoint, \
+ Address, Data); \
+ gcmENDSTATEBATCH(CommandBuffer, Memory); \
+}
+
+#define gcmSETSINGLESTATEWITHMASK_FAST(StateDelta, CommandBuffer, Memory, FixedPoint, \
+ Address, Mask, Data) \
+{ \
+ gcmBEGINSTATEBATCH(CommandBuffer, Memory, FixedPoint, Address, 1); \
+ gcmSETSTATEDATAWITHMASK_FAST(StateDelta, CommandBuffer, Memory, FixedPoint, \
+ Address, Mask, Data); \
+ gcmENDSTATEBATCH(CommandBuffer, Memory); \
+}
+
+#define gcmDEFINESTATEBUFFER_NEW_FAST(CommandBuffer, Memory) \
+ gcmDEFINESECUREUSER() \
+ gcmDEFINELOADSTATEBASE() \
+ gcsTEMPCMDBUF CommandBuffer = gcvNULL; \
+ gctUINT32_PTR Memory;
+
+#define gcmDEFINESTATEBUFFER_FAST(CommandBuffer, Memory, ReserveSize) \
+ gcmDEFINESECUREUSER() \
+ gctSIZE_T ReserveSize; \
+ gcoCMDBUF CommandBuffer; \
+ gctUINT32_PTR Memory;
+
+#define gcmBEGINSTATEBUFFER_FAST(Hardware, CommandBuffer, Memory, ReserveSize) \
+{ \
+ gcmONERROR(gcoBUFFER_Reserve(\
+ Hardware->engine[gcvENGINE_RENDER].buffer, ReserveSize, gcvTRUE, &CommandBuffer \
+ )); \
+ \
+ Memory = (gctUINT32_PTR) gcmUINT64_TO_PTR(CommandBuffer->lastReserve); \
+ \
+ gcmBEGINSECUREUSER(); \
+}
+
+#define gcmBEGINSTATEBUFFER_NEW_FAST(Hardware, CommandBuffer, Memory, OutSide) \
+{ \
+ if (OutSide) \
+ {\
+ Memory = (gctUINT32_PTR)*OutSide; \
+ }\
+ else \
+ {\
+ gcmONERROR(gcoBUFFER_StartTEMPCMDBUF(\
+ Hardware->engine[gcvENGINE_RENDER].buffer, &CommandBuffer \
+ ));\
+ \
+ Memory = (gctUINT32_PTR)(CommandBuffer->buffer); \
+ \
+ }\
+ \
+ gcmBEGINSECUREUSER(); \
+ gcmSETLOADSTATEBASE(CommandBuffer,OutSide);\
+}
+
+#define gcmENDSTATEBUFFER_NEW_FAST(Hardware, CommandBuffer, Memory, OutSide) \
+{ \
+ gcmENDSECUREUSER(); \
+ \
+ if (OutSide) \
+ {\
+ *OutSide = Memory; \
+ }\
+ else \
+ {\
+ CommandBuffer->currentByteSize = (gctUINT32)((gctUINT8_PTR)Memory - \
+ (gctUINT8_PTR)CommandBuffer->buffer); \
+ \
+ gcmONERROR(gcoBUFFER_EndTEMPCMDBUF(Hardware->engine[gcvENGINE_RENDER].buffer, gcvFALSE));\
+ }\
+ gcmUNSETLOADSTATEBASE()\
+}
+
+/*******************************************************************************
+**
+** gcmCONFIGUREUNIFORMS
+**
+** Configure uniforms according to chip and numConstants.
+*/
+#if !gcdENABLE_UNIFIED_CONSTANT
+#define gcmCONFIGUREUNIFORMS(ChipModel, ChipRevision, NumConstants, \
+ UnifiedConst, VsConstBase, PsConstBase, VsConstMax, PsConstMax, ConstMax) \
+{ \
+ if (ChipModel == gcv2000 && (ChipRevision == 0x5118 || ChipRevision == 0x5140)) \
+ { \
+ UnifiedConst = gcvFALSE; \
+ VsConstBase = 0x1400; \
+ PsConstBase = 0x1C00; \
+ VsConstMax = 256; \
+ PsConstMax = 64; \
+ ConstMax = 320; \
+ } \
+ else if (NumConstants == 320) \
+ { \
+ UnifiedConst = gcvFALSE; \
+ VsConstBase = 0x1400; \
+ PsConstBase = 0x1C00; \
+ VsConstMax = 256; \
+ PsConstMax = 64; \
+ ConstMax = 320; \
+ } \
+ /* All GC1000 series chips can only support 64 uniforms for ps on non-unified const mode. */ \
+ else if (NumConstants > 256 && ChipModel == gcv1000) \
+ { \
+ UnifiedConst = gcvFALSE; \
+ VsConstBase = 0x1400; \
+ PsConstBase = 0x1C00; \
+ VsConstMax = 256; \
+ PsConstMax = 64; \
+ ConstMax = 320; \
+ } \
+ else if (NumConstants > 256) \
+ { \
+ UnifiedConst = gcvFALSE; \
+ VsConstBase = 0x1400; \
+ PsConstBase = 0x1C00; \
+ VsConstMax = 256; \
+ PsConstMax = 256; \
+ ConstMax = 512; \
+ } \
+ else if (NumConstants == 256) \
+ { \
+ UnifiedConst = gcvFALSE; \
+ VsConstBase = 0x1400; \
+ PsConstBase = 0x1C00; \
+ VsConstMax = 256; \
+ PsConstMax = 256; \
+ ConstMax = 512; \
+ } \
+ else \
+ { \
+ UnifiedConst = gcvFALSE; \
+ VsConstBase = 0x1400; \
+ PsConstBase = 0x1C00; \
+ VsConstMax = 168; \
+ PsConstMax = 64; \
+ ConstMax = 232; \
+ } \
+}
+#else
+#define gcmCONFIGUREUNIFORMS(ChipModel, ChipRevision, Halti5Avail, NumConstants, \
+ UnifiedConst, VsConstBase, PsConstBase, VsConstMax, PsConstMax, ConstMax) \
+{ \
+ if (NumConstants > 256) \
+ { \
+ UnifiedConst = gcvTRUE; \
+ if (Halti5Avail) \
+ { \
+ VsConstBase = 0xD000; \
+ PsConstBase = 0xD800; \
+ } \
+ else \
+ {\
+ VsConstBase = 0xC000; \
+ PsConstBase = 0xC000; \
+ }\
+ if ((ChipModel == gcv880) && ((ChipRevision & 0xfff0) == 0x5120)) \
+ { \
+ VsConstMax = 512; \
+ PsConstMax = 64; \
+ ConstMax = 576; \
+ } \
+ else \
+ { \
+ VsConstMax = gcmMIN(512, NumConstants - 64); \
+ PsConstMax = gcmMIN(512, NumConstants - 64); \
+ ConstMax = NumConstants; \
+ } \
+ } \
+ else if (NumConstants == 256) \
+ { \
+ if (ChipModel == gcv2000 && (ChipRevision == 0x5118 || ChipRevision == 0x5140)) \
+ { \
+ UnifiedConst = gcvFALSE; \
+ VsConstBase = 0x1400; \
+ PsConstBase = 0x1C00; \
+ VsConstMax = 256; \
+ PsConstMax = 64; \
+ ConstMax = 320; \
+ } \
+ else \
+ { \
+ UnifiedConst = gcvFALSE; \
+ VsConstBase = 0x1400; \
+ PsConstBase = 0x1C00; \
+ VsConstMax = 256; \
+ PsConstMax = 256; \
+ ConstMax = 512; \
+ } \
+ } \
+ else \
+ { \
+ UnifiedConst = gcvFALSE; \
+ VsConstBase = 0x1400; \
+ PsConstBase = 0x1C00; \
+ VsConstMax = 168; \
+ PsConstMax = 64; \
+ ConstMax = 232; \
+ } \
+}
+#endif
+
+#define gcmAnyTileStatusEnableForFullMultiSlice(SurfView, anyTsEnableForMultiSlice)\
+{\
+ gctUINT i = 0; \
+ for (; i < (SurfView->surf->requestD); i++)\
+ {\
+ if ((SurfView->surf->tileStatusNode.pool != gcvPOOL_UNKNOWN) && \
+ (SurfView->surf->tileStatusDisabled[i] == gcvFALSE))\
+ {\
+ *anyTsEnableForMultiSlice = gcvTRUE;\
+ break;\
+ }\
+ }\
+}\
+
+#define gcmAnyTileStatusEnableForMultiSlice(SurfView, anyTsEnableForMultiSlice)\
+{\
+ gctUINT i = SurfView->firstSlice; \
+ for (; i < (SurfView->firstSlice + SurfView->numSlices); i++)\
+ {\
+ if ((SurfView->surf->tileStatusNode.pool != gcvPOOL_UNKNOWN) && \
+ (SurfView->surf->tileStatusDisabled[i] == gcvFALSE))\
+ {\
+ *anyTsEnableForMultiSlice = gcvTRUE;\
+ break;\
+ }\
+ }\
+}\
+
+#define gcmCanTileStatusEnabledForMultiSlice(SurfView, canTsEnabled)\
+{\
+ if (SurfView->numSlices > 1)\
+ {\
+ if (SurfView->surf->tileStatusNode.pool != gcvPOOL_UNKNOWN) \
+ {\
+ gctUINT i = 0;\
+ for (; i < SurfView->numSlices; i++)\
+ {\
+ if (SurfView->surf->tileStatusDisabled[i] == gcvTRUE)\
+ {\
+ *canTsEnabled = gcvFALSE;\
+ break;\
+ }\
+ if (SurfView->surf->fcValue[i] != SurfView->surf->fcValue[0])\
+ {\
+ *canTsEnabled = gcvFALSE;\
+ break;\
+ }\
+ \
+ if (SurfView->surf->fcValueUpper[i] != SurfView->surf->fcValueUpper[0])\
+ {\
+ *canTsEnabled = gcvFALSE;\
+ break;\
+ }\
+ }\
+ }\
+ else\
+ {\
+ *canTsEnabled = gcvFALSE;\
+ }\
+ }\
+ else\
+ {\
+ if ((SurfView->surf->tileStatusNode.pool == gcvPOOL_UNKNOWN) || (SurfView->surf->tileStatusDisabled[SurfView->firstSlice] == gcvTRUE))\
+ {\
+ *canTsEnabled = gcvFALSE;\
+ }\
+ }\
+}\
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __gc_hal_base_h_ */
+
+
diff --git a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_driver.h b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_driver.h
new file mode 100644
index 000000000000..a8acea293cc5
--- /dev/null
+++ b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_driver.h
@@ -0,0 +1,1402 @@
+/****************************************************************************
+*
+* The MIT License (MIT)
+*
+* Copyright (c) 2014 - 2018 Vivante 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 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 GPL License (GPL)
+*
+* Copyright (C) 2014 - 2018 Vivante 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.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+*****************************************************************************
+*
+* Note: This software is released under dual MIT and GPL licenses. A
+* recipient may use this file under the terms of either the MIT license or
+* GPL License. If you wish to use only one license not the other, you can
+* indicate your decision by deleting one of the above license notices in your
+* version of this file.
+*
+*****************************************************************************/
+
+
+#ifndef __gc_hal_driver_h_
+#define __gc_hal_driver_h_
+
+#include "gc_hal_enum.h"
+#include "gc_hal_types.h"
+
+#if gcdENABLE_VG
+#include "gc_hal_driver_vg.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/******************************************************************************\
+******************************* I/O Control Codes ******************************
+\******************************************************************************/
+
+#define gcvHAL_CLASS "galcore"
+#define IOCTL_GCHAL_INTERFACE 30000
+#define IOCTL_GCHAL_KERNEL_INTERFACE 30001
+#define IOCTL_GCHAL_TERMINATE 30002
+
+#undef CONFIG_ANDROID_RESERVED_MEMORY_ACCOUNT
+/******************************************************************************\
+********************************* Command Codes ********************************
+\******************************************************************************/
+
+typedef enum _gceHAL_COMMAND_CODES
+{
+ /* Generic query. */
+ gcvHAL_QUERY_VIDEO_MEMORY,
+ gcvHAL_QUERY_CHIP_IDENTITY,
+ gcvHAL_QUERY_CHIP_FREQUENCY,
+
+ /* Contiguous memory. */
+ gcvHAL_ALLOCATE_NON_PAGED_MEMORY,
+ gcvHAL_FREE_NON_PAGED_MEMORY,
+ gcvHAL_ALLOCATE_CONTIGUOUS_MEMORY,
+ gcvHAL_FREE_CONTIGUOUS_MEMORY,
+
+ /* Video memory allocation. */
+ gcvHAL_ALLOCATE_VIDEO_MEMORY, /* Enforced alignment. */
+ gcvHAL_ALLOCATE_LINEAR_VIDEO_MEMORY, /* No alignment. */
+ gcvHAL_RELEASE_VIDEO_MEMORY,
+
+ /* Physical-to-logical mapping. */
+ gcvHAL_MAP_MEMORY,
+ gcvHAL_UNMAP_MEMORY,
+
+ /* Logical-to-physical mapping. */
+ gcvHAL_MAP_USER_MEMORY,
+ gcvHAL_UNMAP_USER_MEMORY,
+
+ /* Surface lock/unlock. */
+ gcvHAL_LOCK_VIDEO_MEMORY,
+ gcvHAL_UNLOCK_VIDEO_MEMORY,
+
+ /* Event queue. */
+ gcvHAL_EVENT_COMMIT,
+
+ gcvHAL_USER_SIGNAL,
+ gcvHAL_SIGNAL,
+ gcvHAL_WRITE_DATA,
+
+ gcvHAL_COMMIT,
+ gcvHAL_STALL,
+
+ gcvHAL_READ_REGISTER,
+ gcvHAL_WRITE_REGISTER,
+
+ gcvHAL_GET_PROFILE_SETTING,
+ gcvHAL_SET_PROFILE_SETTING,
+
+ gcvHAL_PROFILE_REGISTERS_2D,
+ gcvHAL_READ_ALL_PROFILE_REGISTERS_PART1,
+ gcvHAL_READ_ALL_PROFILE_REGISTERS_PART2,
+ gcvHAL_READ_PROFILER_REGISTER_SETTING,
+
+ /* Power management. */
+ gcvHAL_SET_POWER_MANAGEMENT_STATE,
+ gcvHAL_QUERY_POWER_MANAGEMENT_STATE,
+
+ gcvHAL_GET_BASE_ADDRESS,
+
+ gcvHAL_SET_IDLE, /* reserved */
+
+ /* Queries. */
+ gcvHAL_QUERY_KERNEL_SETTINGS,
+
+ /* Reset. */
+ gcvHAL_RESET,
+
+ /* Map physical address into handle. */
+ gcvHAL_MAP_PHYSICAL,
+
+ /* Debugger stuff. */
+ gcvHAL_DEBUG,
+
+ /* Cache stuff. */
+ gcvHAL_CACHE,
+
+ /* TimeStamp */
+ gcvHAL_TIMESTAMP,
+
+ /* Database. */
+ gcvHAL_DATABASE,
+
+ /* Version. */
+ gcvHAL_VERSION,
+
+ /* Chip info */
+ gcvHAL_CHIP_INFO,
+
+ /* Process attaching/detaching. */
+ gcvHAL_ATTACH,
+ gcvHAL_DETACH,
+
+ /* Set timeOut value */
+ gcvHAL_SET_TIMEOUT,
+
+ /* Frame database. */
+ gcvHAL_GET_FRAME_INFO,
+
+ /* GPU profile dump */
+ gcvHAL_DUMP_GPU_PROFILE,
+
+ gcvHAL_QUERY_COMMAND_BUFFER,
+
+ gcvHAL_COMMIT_DONE,
+
+ /* GPU and event dump */
+ gcvHAL_DUMP_GPU_STATE,
+ gcvHAL_DUMP_EVENT,
+
+ /* Virtual command buffer. */
+ gcvHAL_ALLOCATE_VIRTUAL_COMMAND_BUFFER,
+ gcvHAL_FREE_VIRTUAL_COMMAND_BUFFER,
+
+ /* FSCALE_VAL. */
+ gcvHAL_SET_FSCALE_VALUE,
+ gcvHAL_GET_FSCALE_VALUE,
+
+ /* Export video memory as dma_buf fd */
+ gcvHAL_EXPORT_VIDEO_MEMORY,
+ gcvHAL_NAME_VIDEO_MEMORY,
+ gcvHAL_IMPORT_VIDEO_MEMORY,
+
+ /* Reset time stamp. */
+ gcvHAL_QUERY_RESET_TIME_STAMP,
+
+ /* Multi-GPU read/write. */
+ gcvHAL_READ_REGISTER_EX,
+ gcvHAL_WRITE_REGISTER_EX,
+
+ /* Create native fence and return its fd. */
+ gcvHAL_CREATE_NATIVE_FENCE,
+
+ /* Let GPU wait on native fence. */
+ gcvHAL_WAIT_NATIVE_FENCE,
+
+ /* Destory MMU. */
+ gcvHAL_DESTROY_MMU,
+
+ /* Shared buffer. */
+ gcvHAL_SHBUF,
+
+ /*
+ * Fd representation of android graphic buffer contents.
+ * Currently, it is only to reference video nodes, signal, etc to avoid being
+ * destroyed when trasfering across processes.
+ */
+ gcvHAL_GET_GRAPHIC_BUFFER_FD,
+
+
+ gcvHAL_SET_VIDEO_MEMORY_METADATA,
+
+ /* Connect a video node to an OS native fd. */
+ gcvHAL_GET_VIDEO_MEMORY_FD,
+
+ /* Config power management. */
+ gcvHAL_CONFIG_POWER_MANAGEMENT,
+
+ /* Wrap a user memory into a video memory node. */
+ gcvHAL_WRAP_USER_MEMORY,
+
+ /* Wait until GPU finishes access to a resource. */
+ gcvHAL_WAIT_FENCE,
+
+ /* Mutex Operation. */
+ gcvHAL_DEVICE_MUTEX,
+
+#if gcdDEC_ENABLE_AHB
+ gcvHAL_DEC300_READ,
+ gcvHAL_DEC300_WRITE,
+ gcvHAL_DEC300_FLUSH,
+ gcvHAL_DEC300_FLUSH_WAIT,
+#endif
+
+ gcvHAL_BOTTOM_HALF_UNLOCK_VIDEO_MEMORY,
+ gcvHAL_QUERY_CHIP_OPTION
+
+}
+gceHAL_COMMAND_CODES;
+
+/******************************************************************************\
+****************************** Interface Structure *****************************
+\******************************************************************************/
+
+#define gcdMAX_PROFILE_FILE_NAME 128
+
+/* Kernel settings. */
+typedef struct _gcsKERNEL_SETTINGS
+{
+ /* Used RealTime signal between kernel and user. */
+ gctINT signal;
+}
+gcsKERNEL_SETTINGS;
+
+typedef struct _gcsUSER_MEMORY_DESC
+{
+ /* Import flag. */
+ gctUINT32 flag;
+
+ /* gcvALLOC_FLAG_DMABUF */
+ gctUINT32 handle;
+ gctUINT64 dmabuf;
+
+ /* gcvALLOC_FLAG_USERMEMORY */
+ gctUINT64 logical;
+ gctUINT32 physical;
+ gctUINT32 size;
+
+ /* gcvALLOC_FLAG_EXTERNAL_MEMORY */
+ gcsEXTERNAL_MEMORY_INFO externalMemoryInfo;
+}
+gcsUSER_MEMORY_DESC;
+
+
+enum
+{
+ /* GPU can't issue more that 32bit physical address */
+ gcvPLATFORM_FLAG_LIMIT_4G_ADDRESS = 1 << 0,
+
+ gcvPLATFORM_FLAG_IMX_MM = 1 << 1,
+};
+
+
+#define gcdMAX_FLAT_MAPPING_COUNT 16
+
+typedef struct _gcsFLAT_MAPPING_RANGE
+{
+ gctUINT64 start;
+ gctUINT64 end;
+}
+gcsFLAT_MAPPING_RANGE;
+
+/* gcvHAL_QUERY_CHIP_IDENTITY */
+typedef struct _gcsHAL_QUERY_CHIP_IDENTITY * gcsHAL_QUERY_CHIP_IDENTITY_PTR;
+typedef struct _gcsHAL_QUERY_CHIP_IDENTITY
+{
+
+ /* Chip model. */
+ gceCHIPMODEL chipModel;
+
+ /* Revision value.*/
+ gctUINT32 chipRevision;
+
+ /* Chip date. */
+ gctUINT32 chipDate;
+
+#if gcdENABLE_VG
+ /* Supported feature fields. */
+ gctUINT32 chipFeatures;
+
+ /* Supported minor feature fields. */
+ gctUINT32 chipMinorFeatures;
+
+ /* Supported minor feature 1 fields. */
+ gctUINT32 chipMinorFeatures1;
+
+ /* Supported minor feature 2 fields. */
+ gctUINT32 chipMinorFeatures2;
+
+ /* Supported minor feature 3 fields. */
+ gctUINT32 chipMinorFeatures3;
+
+ /* Supported minor feature 4 fields. */
+ gctUINT32 chipMinorFeatures4;
+
+ /* Supported minor feature 5 fields. */
+ gctUINT32 chipMinorFeatures5;
+
+ /* Supported minor feature 6 fields. */
+ gctUINT32 chipMinorFeatures6;
+#endif
+
+ /* Number of streams supported. */
+ gctUINT32 streamCount;
+
+ /* Number of pixel pipes. */
+ gctUINT32 pixelPipes;
+
+ /* Number of resolve pipes. */
+ gctUINT32 resolvePipes;
+
+ /* Number of instructions. */
+ gctUINT32 instructionCount;
+
+ /* Number of constants. */
+ gctUINT32 numConstants;
+
+ /* Number of varyings */
+ gctUINT32 varyingsCount;
+
+ /* Number of 3D GPUs */
+ gctUINT32 gpuCoreCount;
+
+ /* Product ID */
+ gctUINT32 productID;
+
+ /* Special chip flag bits */
+ gceCHIP_FLAG chipFlags;
+
+ /* ECO ID. */
+ gctUINT32 ecoID;
+
+ /* Customer ID. */
+ gctUINT32 customerID;
+
+ gctUINT32 platformFlagBits;
+}
+gcsHAL_QUERY_CHIP_IDENTITY;
+
+typedef struct _gcsHAL_QUERY_CHIP_OPTIONS * gcsHAL_QUERY_CHIP_OPTIONS_PTR;
+typedef struct _gcsHAL_QUERY_CHIP_OPTIONS
+{
+ gctBOOL gpuProfiler;
+ gctBOOL allowFastClear;
+ gctBOOL powerManagement;
+ /* Whether use new MMU. It is meaningless
+ ** for old MMU since old MMU is always enabled.
+ */
+ gctBOOL enableMMU;
+ gceCOMPRESSION_OPTION allowCompression;
+ gctUINT uscL1CacheRatio;
+ gceSECURE_MODE secureMode;
+
+}
+gcsHAL_QUERY_CHIP_OPTIONS;
+
+typedef struct _gcsHAL_INTERFACE
+{
+ /* Command code. */
+ gceHAL_COMMAND_CODES command;
+
+ /* Hardware type. */
+ gceHARDWARE_TYPE hardwareType;
+
+ /* Core index for current hardware type. */
+ gctUINT32 coreIndex;
+
+ /* Status value. */
+ gceSTATUS status;
+
+ /* Handle to this interface channel. */
+ gctUINT64 handle;
+
+ /* Pid of the client. */
+ gctUINT32 pid;
+
+ /* Engine */
+ gceENGINE engine;
+
+ /* Ignore information from TSL when doing IO control */
+ gctBOOL ignoreTLS;
+
+ /* The mutext already acquired */
+ IN gctBOOL commitMutex;
+
+ /* Union of command structures. */
+ union _u
+ {
+ /* gcvHAL_GET_BASE_ADDRESS */
+ struct _gcsHAL_GET_BASE_ADDRESS
+ {
+ /* Physical memory address of internal memory. */
+ OUT gctUINT32 baseAddress;
+
+ OUT gctUINT32 flatMappingRangeCount;
+
+ OUT gcsFLAT_MAPPING_RANGE flatMappingRanges[gcdMAX_FLAT_MAPPING_COUNT];
+ }
+ GetBaseAddress;
+
+ /* gcvHAL_QUERY_VIDEO_MEMORY */
+ struct _gcsHAL_QUERY_VIDEO_MEMORY
+ {
+ /* Physical memory address of internal memory. Just a name. */
+ OUT gctUINT32 internalPhysical;
+
+ /* Size in bytes of internal memory. */
+ OUT gctUINT64 internalSize;
+
+ /* Physical memory address of external memory. Just a name. */
+ OUT gctUINT32 externalPhysical;
+
+ /* Size in bytes of external memory.*/
+ OUT gctUINT64 externalSize;
+
+ /* Physical memory address of contiguous memory. Just a name. */
+ OUT gctUINT32 contiguousPhysical;
+
+ /* Size in bytes of contiguous memory.*/
+ OUT gctUINT64 contiguousSize;
+ }
+ QueryVideoMemory;
+
+ /* gcvHAL_QUERY_CHIP_IDENTITY */
+ gcsHAL_QUERY_CHIP_IDENTITY QueryChipIdentity;
+
+ struct _gcsHAL_QUERY_CHIP_FREQUENCY
+ {
+ OUT gctUINT32 mcClk;
+ OUT gctUINT32 shClk;
+ }
+ QueryChipFrequency;
+
+ /* gcvHAL_MAP_MEMORY */
+ struct _gcsHAL_MAP_MEMORY
+ {
+ /* Physical memory address to map. Just a name on Linux/Qnx. */
+ IN gctUINT32 physical;
+
+ /* Number of bytes in physical memory to map. */
+ IN gctUINT64 bytes;
+
+ /* Address of mapped memory. */
+ OUT gctUINT64 logical;
+ }
+ MapMemory;
+
+ /* gcvHAL_UNMAP_MEMORY */
+ struct _gcsHAL_UNMAP_MEMORY
+ {
+ /* Physical memory address to unmap. Just a name on Linux/Qnx. */
+ IN gctUINT32 physical;
+
+ /* Number of bytes in physical memory to unmap. */
+ IN gctUINT64 bytes;
+
+ /* Address of mapped memory to unmap. */
+ IN gctUINT64 logical;
+ }
+ UnmapMemory;
+
+ /* gcvHAL_ALLOCATE_LINEAR_VIDEO_MEMORY */
+ struct _gcsHAL_ALLOCATE_LINEAR_VIDEO_MEMORY
+ {
+ /* Number of bytes to allocate. */
+ IN OUT gctUINT bytes;
+
+ /* Buffer alignment. */
+ IN gctUINT alignment;
+
+ /* Type of allocation. */
+ IN gceSURF_TYPE type;
+
+ /* Flag of allocation. */
+ IN gctUINT32 flag;
+
+ /* Memory pool to allocate from. */
+ IN OUT gcePOOL pool;
+
+ /* Allocated video memory. */
+ OUT gctUINT32 node;
+ }
+ AllocateLinearVideoMemory;
+
+ /* gcvHAL_ALLOCATE_VIDEO_MEMORY */
+ struct _gcsHAL_ALLOCATE_VIDEO_MEMORY
+ {
+ /* Width of rectangle to allocate. */
+ IN OUT gctUINT width;
+
+ /* Height of rectangle to allocate. */
+ IN OUT gctUINT height;
+
+ /* Depth of rectangle to allocate. */
+ IN gctUINT depth;
+
+ /* Format rectangle to allocate in gceSURF_FORMAT. */
+ IN gceSURF_FORMAT format;
+
+ /* Type of allocation. */
+ IN gceSURF_TYPE type;
+
+ /* Memory pool to allocate from. */
+ IN OUT gcePOOL pool;
+
+ /* Allocated video memory. */
+ OUT gctUINT32 node;
+ }
+ AllocateVideoMemory;
+
+ /* gcvHAL_RELEASE_VIDEO_MEMORY */
+ struct _gcsHAL_RELEASE_VIDEO_MEMORY
+ {
+ /* Allocated video memory. */
+ IN gctUINT32 node;
+
+#ifdef __QNXNTO__
+ /* Mapped logical address to unmap in user space. */
+ OUT gctUINT64 memory;
+
+ /* Number of bytes to allocated. */
+ OUT gctUINT64 bytes;
+#endif
+ }
+ ReleaseVideoMemory;
+
+ /* gcvHAL_LOCK_VIDEO_MEMORY */
+ struct _gcsHAL_LOCK_VIDEO_MEMORY
+ {
+ /* Allocated video memory. */
+ IN gctUINT32 node;
+
+ /* Cache configuration. */
+ /* Only gcvPOOL_CONTIGUOUS and gcvPOOL_VIRUTAL
+ ** can be configured */
+ IN gctBOOL cacheable;
+
+ /* Hardware specific address. */
+ OUT gctUINT32 address;
+
+ /* Mapped logical address. */
+ OUT gctUINT64 memory;
+
+ /* Customer priviate handle*/
+ OUT gctUINT32 gid;
+
+ /* Bus address of a contiguous video node. */
+ OUT gctUINT64 physicalAddress;
+ }
+ LockVideoMemory;
+
+ /* gcvHAL_UNLOCK_VIDEO_MEMORY */
+ struct _gcsHAL_UNLOCK_VIDEO_MEMORY
+ {
+ /* Allocated video memory. */
+ IN gctUINT64 node;
+
+ /* Type of surface. */
+ IN gceSURF_TYPE type;
+
+ /* Pool of the unlock node */
+ OUT gcePOOL pool;
+
+ /* Bytes of the unlock node */
+ OUT gctUINT bytes;
+
+ /* Flag to unlock surface asynchroneously. */
+ IN OUT gctBOOL asynchroneous;
+ }
+ UnlockVideoMemory;
+
+ /* gcvHAL_ALLOCATE_NON_PAGED_MEMORY */
+ struct _gcsHAL_ALLOCATE_NON_PAGED_MEMORY
+ {
+ /* Number of bytes to allocate. */
+ IN OUT gctUINT64 bytes;
+
+ /* Physical address of allocation. Just a name. */
+ OUT gctUINT32 physical;
+
+ /* Logical address of allocation. */
+ OUT gctUINT64 logical;
+ }
+ AllocateNonPagedMemory;
+
+ /* gcvHAL_FREE_NON_PAGED_MEMORY */
+ struct _gcsHAL_FREE_NON_PAGED_MEMORY
+ {
+ /* Number of bytes allocated. */
+ IN gctUINT64 bytes;
+
+ /* Physical address of allocation. Just a name. */
+ IN gctUINT32 physical;
+
+ /* Logical address of allocation. */
+ IN gctUINT64 logical;
+ }
+ FreeNonPagedMemory;
+
+ /* gcvHAL_ALLOCATE_NON_PAGED_MEMORY */
+ struct _gcsHAL_ALLOCATE_VIRTUAL_COMMAND_BUFFER
+ {
+ /* Number of bytes to allocate. */
+ IN OUT gctUINT64 bytes;
+
+ /* Physical address of allocation. Just a name. */
+ OUT gctUINT32 physical;
+
+ /* Logical address of allocation. */
+ OUT gctUINT64 logical;
+ }
+ AllocateVirtualCommandBuffer;
+
+ /* gcvHAL_FREE_NON_PAGED_MEMORY */
+ struct _gcsHAL_FREE_VIRTUAL_COMMAND_BUFFER
+ {
+ /* Number of bytes allocated. */
+ IN gctUINT64 bytes;
+
+ /* Physical address of allocation. Just a name. */
+ IN gctUINT32 physical;
+
+ /* Logical address of allocation. */
+ IN gctUINT64 logical;
+ }
+ FreeVirtualCommandBuffer;
+
+ /* gcvHAL_EVENT_COMMIT. */
+ struct _gcsHAL_EVENT_COMMIT
+ {
+ /* Event queue in gcsQUEUE. */
+ IN gctUINT64 queue;
+ }
+ Event;
+
+ /* gcvHAL_COMMIT */
+ struct _gcsHAL_COMMIT
+ {
+ /* Context buffer object gckCONTEXT. */
+ IN gctUINT64 context;
+
+ /* Command buffer gcoCMDBUF. */
+ IN gctUINT64 commandBuffer;
+
+ /* State delta buffer in gcsSTATE_DELTA. */
+ gctUINT64 delta;
+
+ gctUINT64 deltas[gcvCORE_COUNT];
+
+ gctUINT64 contexts[gcvCORE_COUNT];
+
+ gctUINT64 commandBuffers[gcvCORE_COUNT];
+
+
+ /* Event queue in gcsQUEUE. */
+ IN gctUINT64 queue;
+
+ /* Used to distinguish different FE. */
+ IN gceENGINE engine1;
+
+ /* The command buffer is linked to multiple command queue. */
+ IN gctBOOL shared;
+
+ /* Index of command queue. */
+ IN gctUINT32 index;
+
+ /* Count of gpu core. */
+ IN gctUINT32 count;
+
+ /* Commit stamp of this commit. */
+ OUT gctUINT64 commitStamp;
+
+ /* If context switch for this commit */
+ OUT gctBOOL contextSwitched;
+ }
+ Commit;
+
+ /* gcvHAL_MAP_USER_MEMORY */
+ struct _gcsHAL_MAP_USER_MEMORY
+ {
+ /* Base address of user memory to map. */
+ IN gctUINT64 memory;
+
+ /* Physical address of user memory to map. */
+ IN gctUINT32 physical;
+
+ /* Size of user memory in bytes to map. */
+ IN gctUINT64 size;
+
+ /* Info record required by gcvHAL_UNMAP_USER_MEMORY. Just a name. */
+ OUT gctUINT32 info;
+
+ /* Physical address of mapped memory. */
+ OUT gctUINT32 address;
+ }
+ MapUserMemory;
+
+ /* gcvHAL_UNMAP_USER_MEMORY */
+ struct _gcsHAL_UNMAP_USER_MEMORY
+ {
+ /* Base address of user memory to unmap. */
+ IN gctUINT64 memory;
+
+ /* Size of user memory in bytes to unmap. */
+ IN gctUINT64 size;
+
+ /* Info record returned by gcvHAL_MAP_USER_MEMORY. Just a name. */
+ IN gctUINT32 info;
+
+ /* Physical address of mapped memory as returned by
+ gcvHAL_MAP_USER_MEMORY. */
+ IN gctUINT32 address;
+ }
+ UnmapUserMemory;
+#if !USE_NEW_LINUX_SIGNAL
+ /* gcsHAL_USER_SIGNAL */
+ struct _gcsHAL_USER_SIGNAL
+ {
+ /* Command. */
+ gceUSER_SIGNAL_COMMAND_CODES command;
+
+ /* Signal ID. */
+ IN OUT gctINT id;
+
+ /* Reset mode. */
+ IN gctBOOL manualReset;
+
+ /* Wait timedout. */
+ IN gctUINT32 wait;
+
+ /* State. */
+ IN gctBOOL state;
+ }
+ UserSignal;
+#endif
+
+ /* gcvHAL_SIGNAL. */
+ struct _gcsHAL_SIGNAL
+ {
+ /* Signal handle to signal gctSIGNAL. */
+ IN gctUINT64 signal;
+
+ /* Reserved gctSIGNAL. */
+ IN gctUINT64 auxSignal;
+
+ /* Process owning the signal gctHANDLE. */
+ IN gctUINT64 process;
+
+#if defined(__QNXNTO__)
+ /* Client pulse side-channel connection ID. Set by client in gcoOS_CreateSignal. */
+ IN gctINT32 coid;
+
+ /* Set by server. */
+ IN gctINT32 rcvid;
+#endif
+ /* Event generated from where of pipeline */
+ IN gceKERNEL_WHERE fromWhere;
+ }
+ Signal;
+
+ /* gcvHAL_WRITE_DATA. */
+ struct _gcsHAL_WRITE_DATA
+ {
+ /* Address to write data to. */
+ IN gctUINT32 address;
+
+ /* Data to write. */
+ IN gctUINT32 data;
+ }
+ WriteData;
+
+ /* gcvHAL_ALLOCATE_CONTIGUOUS_MEMORY */
+ struct _gcsHAL_ALLOCATE_CONTIGUOUS_MEMORY
+ {
+ /* Number of bytes to allocate. */
+ IN OUT gctUINT64 bytes;
+
+ /* Hardware address of allocation. */
+ OUT gctUINT32 address;
+
+ /* Physical address of allocation. Just a name. */
+ OUT gctUINT32 physical;
+
+ /* Logical address of allocation. */
+ OUT gctUINT64 logical;
+ }
+ AllocateContiguousMemory;
+
+ /* gcvHAL_FREE_CONTIGUOUS_MEMORY */
+ struct _gcsHAL_FREE_CONTIGUOUS_MEMORY
+ {
+ /* Number of bytes allocated. */
+ IN gctUINT64 bytes;
+
+ /* Physical address of allocation. Just a name. */
+ IN gctUINT32 physical;
+
+ /* Logical address of allocation. */
+ IN gctUINT64 logical;
+ }
+ FreeContiguousMemory;
+
+ /* gcvHAL_READ_REGISTER */
+ struct _gcsHAL_READ_REGISTER
+ {
+ /* Logical address of memory to write data to. */
+ IN gctUINT32 address;
+
+ /* Data read. */
+ OUT gctUINT32 data;
+ }
+ ReadRegisterData;
+
+ /* gcvHAL_WRITE_REGISTER */
+ struct _gcsHAL_WRITE_REGISTER
+ {
+ /* Logical address of memory to write data to. */
+ IN gctUINT32 address;
+
+ /* Data read. */
+ IN gctUINT32 data;
+ }
+ WriteRegisterData;
+
+ /* gcvHAL_READ_REGISTER_EX */
+ struct _gcsHAL_READ_REGISTER_EX
+ {
+ /* Logical address of memory to write data to. */
+ IN gctUINT32 address;
+
+ IN gctUINT32 coreSelect;
+
+ /* Data read. */
+ OUT gctUINT32 data[4];
+ }
+ ReadRegisterDataEx;
+
+ /* gcvHAL_WRITE_REGISTER_EX */
+ struct _gcsHAL_WRITE_REGISTER_EX
+ {
+ /* Logical address of memory to write data to. */
+ IN gctUINT32 address;
+
+ IN gctUINT32 coreSelect;
+
+ /* Data read. */
+ IN gctUINT32 data[4];
+ }
+ WriteRegisterDataEx;
+
+#if VIVANTE_PROFILER
+ /* gcvHAL_GET_PROFILE_SETTING */
+ struct _gcsHAL_GET_PROFILE_SETTING
+ {
+ /* Enable profiling */
+ OUT gctBOOL enable;
+ }
+ GetProfileSetting;
+
+ /* gcvHAL_SET_PROFILE_SETTING */
+ struct _gcsHAL_SET_PROFILE_SETTING
+ {
+ /* Enable profiling */
+ IN gctBOOL enable;
+ }
+ SetProfileSetting;
+
+ /* gcvHAL_READ_PROFILER_REGISTER_SETTING */
+ struct _gcsHAL_READ_PROFILER_REGISTER_SETTING
+ {
+ /*Should Clear Register*/
+ IN gctBOOL bclear;
+ }
+ SetProfilerRegisterClear;
+
+ struct _gcsHAL_READ_ALL_PROFILE_REGISTERS_PART1
+ {
+ /* Context buffer object gckCONTEXT. Just a name. */
+ IN gctUINT32 context;
+
+ /* Data read. */
+ OUT gcsPROFILER_COUNTERS_PART1 Counters;
+ }
+ RegisterProfileData_part1;
+
+ struct _gcsHAL_READ_ALL_PROFILE_REGISTERS_PART2
+ {
+ /* Context buffer object gckCONTEXT. Just a name. */
+ IN gctUINT32 context;
+
+ /* Data read. */
+ OUT gcsPROFILER_COUNTERS_PART2 Counters;
+ }
+ RegisterProfileData_part2;
+
+ /* gcvHAL_PROFILE_REGISTERS_2D */
+ struct _gcsHAL_PROFILE_REGISTERS_2D
+ {
+ /* Data read in gcs2D_PROFILE. */
+ OUT gctUINT64 hwProfile2D;
+ }
+ RegisterProfileData2D;
+#endif
+
+ /* Power management. */
+ /* gcvHAL_SET_POWER_MANAGEMENT_STATE */
+ struct _gcsHAL_SET_POWER_MANAGEMENT
+ {
+ /* Data read. */
+ IN gceCHIPPOWERSTATE state;
+ }
+ SetPowerManagement;
+
+ /* gcvHAL_QUERY_POWER_MANAGEMENT_STATE */
+ struct _gcsHAL_QUERY_POWER_MANAGEMENT
+ {
+ /* Data read. */
+ OUT gceCHIPPOWERSTATE state;
+
+ /* Idle query. */
+ OUT gctBOOL isIdle;
+ }
+ QueryPowerManagement;
+
+ /* gcvHAL_QUERY_KERNEL_SETTINGS */
+ struct _gcsHAL_QUERY_KERNEL_SETTINGS
+ {
+ /* Settings.*/
+ OUT gcsKERNEL_SETTINGS settings;
+ }
+ QueryKernelSettings;
+
+ /* gcvHAL_MAP_PHYSICAL */
+ struct _gcsHAL_MAP_PHYSICAL
+ {
+ /* gcvTRUE to map, gcvFALSE to unmap. */
+ IN gctBOOL map;
+
+ /* Physical address. */
+ IN OUT gctUINT64 physical;
+ }
+ MapPhysical;
+
+ /* gcvHAL_DEBUG */
+ struct _gcsHAL_DEBUG
+ {
+ /* If gcvTRUE, set the debug information. */
+ IN gctBOOL set;
+ IN gctUINT32 level;
+ IN gctUINT32 zones;
+ IN gctBOOL enable;
+
+ IN gceDEBUG_MESSAGE_TYPE type;
+ IN gctUINT32 messageSize;
+
+ /* Message to print if not empty. */
+ IN gctCHAR message[80];
+
+ }
+ Debug;
+
+ /* gcvHAL_CACHE */
+ struct _gcsHAL_CACHE
+ {
+ IN gceCACHEOPERATION operation;
+ IN gctUINT64 process;
+ IN gctUINT64 logical;
+ IN gctUINT64 bytes;
+ IN gctUINT32 node;
+ }
+ Cache;
+
+ /* gcvHAL_TIMESTAMP */
+ struct _gcsHAL_TIMESTAMP
+ {
+ /* Timer select. */
+ IN gctUINT32 timer;
+
+ /* Timer request type (0-stop, 1-start, 2-send delta). */
+ IN gctUINT32 request;
+
+ /* Result of delta time in microseconds. */
+ OUT gctINT32 timeDelta;
+ }
+ TimeStamp;
+
+ /* gcvHAL_DATABASE */
+ struct _gcsHAL_DATABASE
+ {
+ /* Set to gcvTRUE if you want to query a particular process ID.
+ ** Set to gcvFALSE to query the last detached process. */
+ IN gctBOOL validProcessID;
+
+ /* Process ID to query. */
+ IN gctUINT32 processID;
+
+ /* Information. */
+ OUT gcuDATABASE_INFO vidMem;
+ OUT gcuDATABASE_INFO nonPaged;
+ OUT gcuDATABASE_INFO contiguous;
+ OUT gcuDATABASE_INFO gpuIdle;
+
+ /* Detail information about video memory. */
+ OUT gcuDATABASE_INFO vidMemPool[3];
+ }
+ Database;
+
+ /* gcvHAL_VERSION */
+ struct _gcsHAL_VERSION
+ {
+ /* Major version: N.n.n. */
+ OUT gctINT32 major;
+
+ /* Minor version: n.N.n. */
+ OUT gctINT32 minor;
+
+ /* Patch version: n.n.N. */
+ OUT gctINT32 patch;
+
+ /* Build version. */
+ OUT gctUINT32 build;
+ }
+ Version;
+
+ /* gcvHAL_CHIP_INFO */
+ struct _gcsHAL_CHIP_INFO
+ {
+ /* Chip count. */
+ OUT gctINT32 count;
+
+ /* Chip types. */
+ OUT gceHARDWARE_TYPE types[gcdCHIP_COUNT];
+
+ /* Chip IDs. */
+ OUT gctUINT32 ids[gcvCORE_COUNT];
+ }
+ ChipInfo;
+
+ /* gcvHAL_ATTACH */
+ struct _gcsHAL_ATTACH
+ {
+ /* Handle of context buffer object. */
+ OUT gctUINT32 context;
+
+ /* Maximum state in the buffer. */
+ OUT gctUINT64 maxState;
+
+ /* Number of states in the buffer. */
+ OUT gctUINT32 numStates;
+
+ /* Map context buffer to user or not. */
+ IN gctBOOL map;
+
+ /* Physical of context buffer. */
+ OUT gctUINT32 physicals[2];
+
+ /* Physical of context buffer. */
+ OUT gctUINT64 logicals[2];
+
+ /* Bytes of context buffer. */
+ OUT gctUINT32 bytes;
+ }
+ Attach;
+
+ /* gcvHAL_DETACH */
+ struct _gcsHAL_DETACH
+ {
+ /* Context buffer object gckCONTEXT. Just a name. */
+ IN gctUINT32 context;
+ }
+ Detach;
+
+ /* gcvHAL_GET_FRAME_INFO. */
+ struct _gcsHAL_GET_FRAME_INFO
+ {
+ /* gcsHAL_FRAME_INFO* */
+ OUT gctUINT64 frameInfo;
+ }
+ GetFrameInfo;
+
+ /* gcvHAL_SET_TIME_OUT. */
+ struct _gcsHAL_SET_TIMEOUT
+ {
+ gctUINT32 timeOut;
+ }
+ SetTimeOut;
+
+#if gcdENABLE_VG
+ /* gcvHAL_COMMIT */
+ struct _gcsHAL_VGCOMMIT
+ {
+ /* Context buffer. gcsVGCONTEXT_PTR */
+ IN gctUINT64 context;
+
+ /* Command queue. gcsVGCMDQUEUE_PTR */
+ IN gctUINT64 queue;
+
+ /* Number of entries in the queue. */
+ IN gctUINT entryCount;
+
+ /* Task table. gcsTASK_MASTER_TABLE_PTR */
+ IN gctUINT64 taskTable;
+ }
+ VGCommit;
+
+ /* gcvHAL_QUERY_COMMAND_BUFFER */
+ struct _gcsHAL_QUERY_COMMAND_BUFFER
+ {
+ /* Command buffer attributes. */
+ OUT gcsCOMMAND_BUFFER_INFO information;
+ }
+ QueryCommandBuffer;
+
+#endif
+
+ struct _gcsHAL_SET_FSCALE_VALUE
+ {
+ IN gctUINT value;
+ }
+ SetFscaleValue;
+
+ struct _gcsHAL_GET_FSCALE_VALUE
+ {
+ OUT gctUINT value;
+ OUT gctUINT minValue;
+ OUT gctUINT maxValue;
+ }
+ GetFscaleValue;
+
+ /* gcvHAL_EXPORT_VIDEO_MEMORY */
+ struct _gcsHAL_EXPORT_VIDEO_MEMORY
+ {
+ /* Allocated video memory. */
+ IN gctUINT32 node;
+
+ /* Export flags */
+ IN gctUINT32 flags;
+
+ /* Exported dma_buf fd */
+ OUT gctINT32 fd;
+ }
+ ExportVideoMemory;
+
+ struct _gcsHAL_NAME_VIDEO_MEMORY
+ {
+ IN gctUINT32 handle;
+ OUT gctUINT32 name;
+ }
+ NameVideoMemory;
+
+ struct _gcsHAL_IMPORT_VIDEO_MEMORY
+ {
+ IN gctUINT32 name;
+ OUT gctUINT32 handle;
+ }
+ ImportVideoMemory;
+
+ struct _gcsHAL_QUERY_RESET_TIME_STAMP
+ {
+ OUT gctUINT64 timeStamp;
+ OUT gctUINT64 contextID;
+ }
+ QueryResetTimeStamp;
+
+ struct _gcsHAL_CREATE_NATIVE_FENCE
+ {
+ /* Signal id. */
+ IN gctUINT64 signal;
+
+ /* Native fence file descriptor. */
+ OUT gctINT fenceFD;
+
+ }
+ CreateNativeFence;
+
+ struct _gcsHAL_WAIT_NATIVE_FENCE
+ {
+ /* Native fence file descriptor. */
+ IN gctINT fenceFD;
+
+ /* Wait timeout. */
+ IN gctUINT32 timeout;
+ }
+ WaitNativeFence;
+
+ struct _gcsHAL_DESTROY_MMU
+ {
+ /* Mmu object. */
+ IN gctUINT64 mmu;
+ }
+ DestroyMmu;
+
+ struct _gcsHAL_SHBUF
+ {
+ gceSHBUF_COMMAND_CODES command;
+
+ /* Shared buffer. */
+ IN OUT gctUINT64 id;
+
+ /* User data to be shared. */
+ IN gctUINT64 data;
+
+ /* Data size. */
+ IN OUT gctUINT32 bytes;
+ }
+ ShBuf;
+
+ struct _gcsHAL_GET_GRAPHIC_BUFFER_FD
+ {
+ /* Max 3 video nodes, node handle here. */
+ IN gctUINT32 node[3];
+
+ /* A shBuf. */
+ IN gctUINT64 shBuf;
+
+ /* A signal. */
+ IN gctUINT64 signal;
+
+ OUT gctINT32 fd;
+ }
+ GetGraphicBufferFd;
+
+
+ struct _gcsHAL_VIDEO_MEMORY_METADATA
+ {
+ /* Allocated video memory. */
+ IN gctUINT32 node;
+
+ IN gctUINT32 readback;
+
+ INOUT gctINT32 ts_fd;
+ INOUT gctUINT32 fc_enabled;
+ INOUT gctUINT32 fc_value;
+ INOUT gctUINT32 fc_value_upper;
+
+ INOUT gctUINT32 compressed;
+ INOUT gctUINT32 compress_format;
+ }
+ SetVidMemMetadata;
+
+ struct _gcsHAL_GET_VIDEO_MEMORY_FD
+ {
+ IN gctUINT32 handle;
+ OUT gctINT fd;
+ }
+ GetVideoMemoryFd;
+
+ struct _gcsHAL_CONFIG_POWER_MANAGEMENT
+ {
+ IN gctBOOL enable;
+ }
+ ConfigPowerManagement;
+
+ struct _gcsHAL_WRAP_USER_MEMORY
+ {
+ /* Description of user memory. */
+ IN gcsUSER_MEMORY_DESC desc;
+
+ /* Output video mmory node. */
+ OUT gctUINT32 node;
+
+ /* size of the node in bytes */
+ OUT gctUINT64 bytes;
+ }
+ WrapUserMemory;
+
+ struct _gcsHAL_WAIT_FENCE
+ {
+ IN gctUINT32 handle;
+ IN gctUINT32 timeOut;
+ }
+ WaitFence;
+
+ struct _gcsHAL_COMMIT_DONE
+ {
+ IN gctUINT64 context;
+ }
+ CommitDone;
+
+#if gcdDEC_ENABLE_AHB
+ struct _gcsHAL_DEC300_READ
+ {
+ gctUINT32 enable;
+ gctUINT32 readId;
+ gctUINT32 format;
+ gctUINT32 strides[3];
+ gctUINT32 is3D;
+ gctUINT32 isMSAA;
+ gctUINT32 clearValue;
+ gctUINT32 isTPC;
+ gctUINT32 isTPCCompressed;
+ gctUINT32 surfAddrs[3];
+ gctUINT32 tileAddrs[3];
+ }
+ DEC300Read;
+
+ struct _gcsHAL_DEC300_WRITE
+ {
+ gctUINT32 enable;
+ gctUINT32 readId;
+ gctUINT32 writeId;
+ gctUINT32 format;
+ gctUINT32 surfAddr;
+ gctUINT32 tileAddr;
+ }
+ DEC300Write;
+
+ struct _gcsHAL_DEC300_FLUSH
+ {
+ IN gctUINT8 useless;
+ }
+ DEC300Flush;
+
+ struct _gcsHAL_DEC300_FLUSH_WAIT
+ {
+ IN gctUINT32 done;
+ }
+ DEC300FlushWait;
+#endif
+ /* gcvHAL_BOTTOM_HALF_UNLOCK_VIDEO_MEMORY: */
+ struct _gcsHAL_BOTTOM_HALF_UNLOCK_VIDEO_MEMORY
+ {
+ /* Allocated video memory. */
+ IN gctUINT32 node;
+
+ /* Type of surface. */
+ IN gceSURF_TYPE type;
+ }
+ BottomHalfUnlockVideoMemory;
+
+ /* gcvHAL_DEVICE_MUTEX: */
+ struct _gcsHAL_DEVICE_MUTEX
+ {
+ /* Lock or Release device mutex. */
+ gctBOOL isMutexLocked;
+ }
+ DeviceMutex;
+
+ gcsHAL_QUERY_CHIP_OPTIONS QueryChipOptions;
+ }
+ u;
+}
+gcsHAL_INTERFACE;
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __gc_hal_driver_h_ */
+
+
diff --git a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_driver_vg.h b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_driver_vg.h
new file mode 100644
index 000000000000..4fd5d0121947
--- /dev/null
+++ b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_driver_vg.h
@@ -0,0 +1,302 @@
+/****************************************************************************
+*
+* The MIT License (MIT)
+*
+* Copyright (c) 2014 - 2018 Vivante 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 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 GPL License (GPL)
+*
+* Copyright (C) 2014 - 2018 Vivante 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.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+*****************************************************************************
+*
+* Note: This software is released under dual MIT and GPL licenses. A
+* recipient may use this file under the terms of either the MIT license or
+* GPL License. If you wish to use only one license not the other, you can
+* indicate your decision by deleting one of the above license notices in your
+* version of this file.
+*
+*****************************************************************************/
+
+
+#ifndef __gc_hal_driver_vg_h_
+#define __gc_hal_driver_vg_h_
+
+
+
+#include "gc_hal_types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/******************************************************************************\
+******************************* I/O Control Codes ******************************
+\******************************************************************************/
+
+#define gcvHAL_CLASS "galcore"
+#define IOCTL_GCHAL_INTERFACE 30000
+
+/******************************************************************************\
+********************* Command buffer information structure. ********************
+\******************************************************************************/
+
+typedef struct _gcsCOMMAND_BUFFER_INFO * gcsCOMMAND_BUFFER_INFO_PTR;
+typedef struct _gcsCOMMAND_BUFFER_INFO
+{
+ /* FE command buffer interrupt ID. */
+ gctINT32 feBufferInt;
+
+ /* TS overflow interrupt ID. */
+ gctINT32 tsOverflowInt;
+
+ /* Alignment and mask for the buffer address. */
+ gctUINT addressMask;
+ gctUINT32 addressAlignment;
+
+ /* Alignment for each command. */
+ gctUINT32 commandAlignment;
+
+ /* Number of bytes required by the STATE command. */
+ gctUINT32 stateCommandSize;
+
+ /* Number of bytes required by the RESTART command. */
+ gctUINT32 restartCommandSize;
+
+ /* Number of bytes required by the FETCH command. */
+ gctUINT32 fetchCommandSize;
+
+ /* Number of bytes required by the CALL command. */
+ gctUINT32 callCommandSize;
+
+ /* Number of bytes required by the RETURN command. */
+ gctUINT32 returnCommandSize;
+
+ /* Number of bytes required by the EVENT command. */
+ gctUINT32 eventCommandSize;
+
+ /* Number of bytes required by the END command. */
+ gctUINT32 endCommandSize;
+
+ /* Number of bytes reserved at the tail of a static command buffer. */
+ gctUINT32 staticTailSize;
+
+ /* Number of bytes reserved at the tail of a dynamic command buffer. */
+ gctUINT32 dynamicTailSize;
+}
+gcsCOMMAND_BUFFER_INFO;
+
+/******************************************************************************\
+******************************** Task Structures *******************************
+\******************************************************************************/
+
+typedef enum _gceTASK
+{
+ gcvTASK_LINK,
+ gcvTASK_CLUSTER,
+ gcvTASK_INCREMENT,
+ gcvTASK_DECREMENT,
+ gcvTASK_SIGNAL,
+ gcvTASK_LOCKDOWN,
+ gcvTASK_UNLOCK_VIDEO_MEMORY,
+ gcvTASK_FREE_VIDEO_MEMORY,
+ gcvTASK_FREE_CONTIGUOUS_MEMORY,
+ gcvTASK_UNMAP_USER_MEMORY
+}
+gceTASK;
+
+typedef struct _gcsTASK_HEADER * gcsTASK_HEADER_PTR;
+typedef struct _gcsTASK_HEADER
+{
+ /* Task ID. */
+ IN gceTASK id;
+}
+gcsTASK_HEADER;
+
+typedef struct _gcsTASK_LINK * gcsTASK_LINK_PTR;
+typedef struct _gcsTASK_LINK
+{
+ /* Task ID (gcvTASK_LINK). */
+ IN gceTASK id;
+
+ /* Pointer to the next task container. */
+ IN gctPOINTER cotainer;
+
+ /* Pointer to the next task from the next task container. */
+ IN gcsTASK_HEADER_PTR task;
+}
+gcsTASK_LINK;
+
+typedef struct _gcsTASK_CLUSTER * gcsTASK_CLUSTER_PTR;
+typedef struct _gcsTASK_CLUSTER
+{
+ /* Task ID (gcvTASK_CLUSTER). */
+ IN gceTASK id;
+
+ /* Number of tasks in the cluster. */
+ IN gctUINT taskCount;
+}
+gcsTASK_CLUSTER;
+
+typedef struct _gcsTASK_INCREMENT * gcsTASK_INCREMENT_PTR;
+typedef struct _gcsTASK_INCREMENT
+{
+ /* Task ID (gcvTASK_INCREMENT). */
+ IN gceTASK id;
+
+ /* Address of the variable to increment. */
+ IN gctUINT32 address;
+}
+gcsTASK_INCREMENT;
+
+typedef struct _gcsTASK_DECREMENT * gcsTASK_DECREMENT_PTR;
+typedef struct _gcsTASK_DECREMENT
+{
+ /* Task ID (gcvTASK_DECREMENT). */
+ IN gceTASK id;
+
+ /* Address of the variable to decrement. */
+ IN gctUINT32 address;
+}
+gcsTASK_DECREMENT;
+
+typedef struct _gcsTASK_SIGNAL * gcsTASK_SIGNAL_PTR;
+typedef struct _gcsTASK_SIGNAL
+{
+ /* Task ID (gcvTASK_SIGNAL). */
+ IN gceTASK id;
+
+ /* Process owning the signal. */
+ IN gctHANDLE process;
+
+ /* Signal handle to signal. */
+ IN gctSIGNAL signal;
+
+#if defined(__QNXNTO__)
+ IN gctINT32 coid;
+ IN gctINT32 rcvid;
+#endif
+}
+gcsTASK_SIGNAL;
+
+typedef struct _gcsTASK_LOCKDOWN * gcsTASK_LOCKDOWN_PTR;
+typedef struct _gcsTASK_LOCKDOWN
+{
+ /* Task ID (gcvTASK_LOCKDOWN). */
+ IN gceTASK id;
+
+ /* Address of the user space counter. */
+ IN gctUINT32 userCounter;
+
+ /* Address of the kernel space counter. */
+ IN gctUINT32 kernelCounter;
+
+ /* Process owning the signal. */
+ IN gctHANDLE process;
+
+ /* Signal handle to signal. */
+ IN gctSIGNAL signal;
+}
+gcsTASK_LOCKDOWN;
+
+typedef struct _gcsTASK_UNLOCK_VIDEO_MEMORY * gcsTASK_UNLOCK_VIDEO_MEMORY_PTR;
+typedef struct _gcsTASK_UNLOCK_VIDEO_MEMORY
+{
+ /* Task ID (gcvTASK_UNLOCK_VIDEO_MEMORY). */
+ IN gceTASK id;
+
+ /* Allocated video memory. */
+ IN gctUINT64 node;
+}
+gcsTASK_UNLOCK_VIDEO_MEMORY;
+
+typedef struct _gcsTASK_FREE_VIDEO_MEMORY * gcsTASK_FREE_VIDEO_MEMORY_PTR;
+typedef struct _gcsTASK_FREE_VIDEO_MEMORY
+{
+ /* Task ID (gcvTASK_FREE_VIDEO_MEMORY). */
+ IN gceTASK id;
+
+ /* Allocated video memory. */
+ IN gctUINT32 node;
+}
+gcsTASK_FREE_VIDEO_MEMORY;
+
+typedef struct _gcsTASK_FREE_CONTIGUOUS_MEMORY * gcsTASK_FREE_CONTIGUOUS_MEMORY_PTR;
+typedef struct _gcsTASK_FREE_CONTIGUOUS_MEMORY
+{
+ /* Task ID (gcvTASK_FREE_CONTIGUOUS_MEMORY). */
+ IN gceTASK id;
+
+ /* Number of bytes allocated. */
+ IN gctSIZE_T bytes;
+
+ /* Physical address of allocation. */
+ IN gctPHYS_ADDR physical;
+
+ /* Logical address of allocation. */
+ IN gctPOINTER logical;
+}
+gcsTASK_FREE_CONTIGUOUS_MEMORY;
+
+typedef struct _gcsTASK_UNMAP_USER_MEMORY * gcsTASK_UNMAP_USER_MEMORY_PTR;
+typedef struct _gcsTASK_UNMAP_USER_MEMORY
+{
+ /* Task ID (gcvTASK_UNMAP_USER_MEMORY). */
+ IN gceTASK id;
+
+ /* Base address of user memory to unmap. */
+ IN gctPOINTER memory;
+
+ /* Size of user memory in bytes to unmap. */
+ IN gctSIZE_T size;
+
+ /* Info record returned by gcvHAL_MAP_USER_MEMORY. */
+ IN gctPOINTER info;
+
+ /* Physical address of mapped memory as returned by
+ gcvHAL_MAP_USER_MEMORY. */
+ IN gctUINT32 address;
+}
+gcsTASK_UNMAP_USER_MEMORY;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __gc_hal_driver_h_ */
+
+
diff --git a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_drm.h b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_drm.h
new file mode 100644
index 000000000000..cc8eab7aeb6a
--- /dev/null
+++ b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_drm.h
@@ -0,0 +1,200 @@
+/****************************************************************************
+*
+* The MIT License (MIT)
+*
+* Copyright (c) 2014 - 2018 Vivante 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 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 GPL License (GPL)
+*
+* Copyright (C) 2014 - 2018 Vivante 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.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+*****************************************************************************
+*
+* Note: This software is released under dual MIT and GPL licenses. A
+* recipient may use this file under the terms of either the MIT license or
+* GPL License. If you wish to use only one license not the other, you can
+* indicate your decision by deleting one of the above license notices in your
+* version of this file.
+*
+*****************************************************************************/
+
+
+#ifndef __VIVNATE_DRM_H__
+#define __VIVNATE_DRM_H__
+
+#if !defined(__KERNEL__)
+#include <drm.h>
+#endif
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+/* creation flag bits. */
+#define DRM_VIV_GEM_CONTIGUOUS (1u << 0)
+#define DRM_VIV_GEM_CACHED (1u << 1)
+#define DRM_VIV_GEM_SECURE (1u << 2)
+#define DRM_VIV_GEM_CMA_LIMIT (1u << 3)
+#define DRM_VIV_GEM_VIRTUAL_POOL (1u << 4)
+
+struct drm_viv_gem_create {
+ __u64 size;
+ __u32 flags;
+ __u32 handle;
+};
+
+struct drm_viv_gem_lock {
+ __u32 handle;
+ __u32 cacheable;
+ __u64 logical;
+};
+
+struct drm_viv_gem_unlock {
+ __u32 handle;
+};
+
+
+#define DRM_VIV_GEM_CLEAN_CACHE 0x01
+#define DRM_VIV_GEM_INVALIDATE_CACHE 0x02
+#define DRM_VIV_GEM_FLUSH_CACHE 0x03
+#define DRM_VIV_GEM_MEMORY_BARRIER 0x04
+
+struct drm_viv_gem_cache {
+ __u32 handle;
+ __u32 op;
+ __u64 logical;
+ __u64 bytes;
+};
+
+
+#define DRM_VIV_GEM_PARAM_POOL 0x00
+#define DRM_VIV_GEM_PARAM_SIZE 0x01
+
+struct drm_viv_gem_query {
+ __u32 handle;
+ __u32 param;
+ __u64 value;
+};
+
+
+struct drm_viv_gem_timestamp {
+ __u32 handle;
+ /* inc count, 0 for query current. */
+ __u32 inc;
+ /* output inc'ed timestamp. */
+ __u64 timestamp;
+};
+
+
+/* basic tiling mode. */
+#define DRM_VIV_GEM_TILING_LINEAR 0x01
+#define DRM_VIV_GEM_TILING_TILED 0x02
+#define DRM_VIV_GEM_TILING_SUPERTILED 0x04
+#define DRM_VIV_GEM_TILING_MINORTILED 0x08
+
+/* tiling mode modifiers. */
+#define DRM_VIV_GEM_TILING_SPLIT 0x10
+#define DRM_VIV_GEM_TILING_X_MAJOR 0x20
+#define DRM_VIV_GEM_TILING_Y_MAJOR 0x40
+#define DRM_VIV_GEM_TILING_SWAP 0x80
+
+/* ts mode. */
+#define DRM_VIV_GEM_TS_NONE 0x00
+#define DRM_VIV_GEM_TS_DISABLED 0x01
+#define DRM_VIV_GEM_TS_NORMAL 0x02
+#define DRM_VIV_GEM_TS_COMPRESSED 0x03
+
+struct drm_viv_gem_set_tiling {
+ __u32 handle;
+ __u32 tiling_mode;
+
+ __u32 ts_mode;
+ __u64 clear_value;
+};
+
+struct drm_viv_gem_get_tiling {
+ __u32 handle;
+ __u32 tiling_mode;
+
+ __u32 ts_mode;
+ __u64 clear_value;
+};
+
+
+struct drm_viv_gem_attach_aux {
+ __u32 handle;
+ __u32 ts_handle;
+};
+
+
+struct drm_viv_gem_ref_node {
+ __u32 handle;
+
+ /* output. */
+ __u32 node;
+ __u32 ts_node;
+};
+
+
+#define DRM_VIV_GEM_CREATE 0x00
+#define DRM_VIV_GEM_LOCK 0x01
+#define DRM_VIV_GEM_UNLOCK 0x02
+#define DRM_VIV_GEM_CACHE 0x03
+#define DRM_VIV_GEM_QUERY 0x04
+#define DRM_VIV_GEM_TIMESTAMP 0x05
+#define DRM_VIV_GEM_SET_TILING 0x06
+#define DRM_VIV_GEM_GET_TILING 0x07
+#define DRM_VIV_GEM_ATTACH_AUX 0x08
+#define DRM_VIV_GEM_REF_NODE 0x09
+#define DRM_VIV_NUM_IOCTLS 0x0A
+
+#define DRM_IOCTL_VIV_GEM_CREATE DRM_IOWR(DRM_COMMAND_BASE + DRM_VIV_GEM_CREATE, struct drm_viv_gem_create)
+#define DRM_IOCTL_VIV_GEM_LOCK DRM_IOWR(DRM_COMMAND_BASE + DRM_VIV_GEM_LOCK, struct drm_viv_gem_lock)
+#define DRM_IOCTL_VIV_GEM_UNLOCK DRM_IOWR(DRM_COMMAND_BASE + DRM_VIV_GEM_UNLOCK, struct drm_viv_gem_unlock)
+#define DRM_IOCTL_VIV_GEM_CACHE DRM_IOWR(DRM_COMMAND_BASE + DRM_VIV_GEM_CACHE, struct drm_viv_gem_cache)
+#define DRM_IOCTL_VIV_GEM_QUERY DRM_IOWR(DRM_COMMAND_BASE + DRM_VIV_GEM_QUERY, struct drm_viv_gem_query)
+#define DRM_IOCTL_VIV_GEM_TIMESTAMP DRM_IOWR(DRM_COMMAND_BASE + DRM_VIV_GEM_TIMESTAMP, struct drm_viv_gem_timestamp)
+#define DRM_IOCTL_VIV_GEM_SET_TILING DRM_IOWR(DRM_COMMAND_BASE + DRM_VIV_GEM_SET_TILING, struct drm_viv_gem_set_tiling)
+#define DRM_IOCTL_VIV_GEM_GET_TILING DRM_IOWR(DRM_COMMAND_BASE + DRM_VIV_GEM_GET_TILING, struct drm_viv_gem_get_tiling)
+#define DRM_IOCTL_VIV_GEM_ATTACH_AUX DRM_IOWR(DRM_COMMAND_BASE + DRM_VIV_GEM_ATTACH_AUX, struct drm_viv_gem_attach_aux)
+#define DRM_IOCTL_VIV_GEM_REF_NODE DRM_IOWR(DRM_COMMAND_BASE + DRM_VIV_GEM_REF_NODE, struct drm_viv_gem_ref_node)
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* __VIVNATE_DRM_H__ */
diff --git a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_dump.h b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_dump.h
new file mode 100644
index 000000000000..b8c9ffab9ad3
--- /dev/null
+++ b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_dump.h
@@ -0,0 +1,125 @@
+/****************************************************************************
+*
+* The MIT License (MIT)
+*
+* Copyright (c) 2014 - 2018 Vivante 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 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 GPL License (GPL)
+*
+* Copyright (C) 2014 - 2018 Vivante 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.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+*****************************************************************************
+*
+* Note: This software is released under dual MIT and GPL licenses. A
+* recipient may use this file under the terms of either the MIT license or
+* GPL License. If you wish to use only one license not the other, you can
+* indicate your decision by deleting one of the above license notices in your
+* version of this file.
+*
+*****************************************************************************/
+
+
+#ifndef __gc_hal_dump_h_
+#define __gc_hal_dump_h_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+** FILE LAYOUT:
+**
+** gcsDUMP_FILE structure
+**
+** gcsDUMP_DATA frame
+** gcsDUMP_DATA or gcDUMP_DATA_SIZE records rendingring the frame
+** gctUINT8 data[length]
+*/
+
+#define gcvDUMP_FILE_SIGNATURE gcmCC('g','c','D','B')
+
+typedef struct _gcsDUMP_FILE
+{
+ gctUINT32 signature; /* File signature */
+ gctSIZE_T length; /* Length of file */
+ gctUINT32 frames; /* Number of frames in file */
+}
+gcsDUMP_FILE;
+
+typedef enum _gceDUMP_TAG
+{
+ gcvTAG_SURFACE = gcmCC('s','u','r','f'),
+ gcvTAG_FRAME = gcmCC('f','r','m',' '),
+ gcvTAG_COMMAND = gcmCC('c','m','d',' '),
+ gcvTAG_INDEX = gcmCC('i','n','d','x'),
+ gcvTAG_STREAM = gcmCC('s','t','r','m'),
+ gcvTAG_TEXTURE = gcmCC('t','e','x','t'),
+ gcvTAG_RENDER_TARGET = gcmCC('r','n','d','r'),
+ gcvTAG_DEPTH = gcmCC('z','b','u','f'),
+ gcvTAG_RESOLVE = gcmCC('r','s','l','v'),
+ gcvTAG_DELETE = gcmCC('d','e','l',' '),
+ gcvTAG_BUFOBJ = gcmCC('b','u','f','o'),
+}
+gceDUMP_TAG;
+
+typedef struct _gcsDUMP_SURFACE
+{
+ gceDUMP_TAG type; /* Type of record. */
+ gctUINT32 address; /* Address of the surface. */
+ gctINT16 width; /* Width of surface. */
+ gctINT16 height; /* Height of surface. */
+ gceSURF_FORMAT format; /* Surface pixel format. */
+ gctSIZE_T length; /* Number of bytes inside the surface. */
+}
+gcsDUMP_SURFACE;
+
+typedef struct _gcsDUMP_DATA
+{
+ gceDUMP_TAG type; /* Type of record. */
+ gctSIZE_T length; /* Number of bytes of data. */
+ gctUINT32 address; /* Address for the data. */
+}
+gcsDUMP_DATA;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __gc_hal_dump_h_ */
+
+
+
diff --git a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_eglplatform.h b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_eglplatform.h
new file mode 100644
index 000000000000..7d2a6fa35e25
--- /dev/null
+++ b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_eglplatform.h
@@ -0,0 +1,589 @@
+/****************************************************************************
+*
+* The MIT License (MIT)
+*
+* Copyright (c) 2014 - 2018 Vivante 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 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 GPL License (GPL)
+*
+* Copyright (C) 2014 - 2018 Vivante 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.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+*****************************************************************************
+*
+* Note: This software is released under dual MIT and GPL licenses. A
+* recipient may use this file under the terms of either the MIT license or
+* GPL License. If you wish to use only one license not the other, you can
+* indicate your decision by deleting one of the above license notices in your
+* version of this file.
+*
+*****************************************************************************/
+
+
+#ifndef __gc_hal_eglplatform_h_
+#define __gc_hal_eglplatform_h_
+
+#include "gc_hal_types.h"
+#include "gc_hal_base.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#if defined(_WIN32) || defined(__VC32__) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__)
+#ifndef WIN32_LEAN_AND_MEAN
+/* #define WIN32_LEAN_AND_MEAN 1 */
+#endif
+#include <windows.h>
+
+typedef HDC HALNativeDisplayType;
+typedef HWND HALNativeWindowType;
+typedef HBITMAP HALNativePixmapType;
+
+typedef struct __BITFIELDINFO
+{
+ BITMAPINFO bmi;
+ RGBQUAD bmiColors[2];
+}
+BITFIELDINFO;
+
+#elif /* defined(__APPLE__) || */ defined(__WINSCW__) || defined(__SYMBIAN32__) /* Symbian */
+
+#elif defined(WL_EGL_PLATFORM) || defined(EGL_API_WL) /* Wayland */
+
+#elif defined(__GBM__) /* GBM */
+
+#elif defined(__ANDROID__) || defined(ANDROID)
+
+#elif defined(MIR_EGL_PLATFORM) /* Mir */
+
+#elif defined(__QNXNTO__)
+
+#elif defined(__unix__) || defined(__APPLE__)
+
+#if defined(EGL_API_DFB)
+
+#elif defined(EGL_API_FB)
+
+#elif defined(EGL_API_NULLWS)
+
+
+#else
+
+/* X11 (tetative). */
+#endif
+
+#else
+#error "Platform not recognized"
+#endif
+
+#if defined(_WIN32) || defined(__VC32__) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__)
+
+#include "gc_hal_eglplatform_type.h"
+
+/*******************************************************************************
+** Display. ********************************************************************
+*/
+
+gceSTATUS
+gcoOS_GetDisplay(
+ OUT HALNativeDisplayType * Display,
+ IN gctPOINTER Context
+ );
+
+gceSTATUS
+gcoOS_GetDisplayByIndex(
+ IN gctINT DisplayIndex,
+ OUT HALNativeDisplayType * Display,
+ IN gctPOINTER Context
+ );
+
+gceSTATUS
+gcoOS_GetDisplayInfo(
+ IN HALNativeDisplayType Display,
+ OUT gctINT * Width,
+ OUT gctINT * Height,
+ OUT gctSIZE_T * Physical,
+ OUT gctINT * Stride,
+ OUT gctINT * BitsPerPixel
+ );
+
+
+
+gceSTATUS
+gcoOS_GetDisplayInfoEx(
+ IN HALNativeDisplayType Display,
+ IN HALNativeWindowType Window,
+ IN gctUINT DisplayInfoSize,
+ OUT halDISPLAY_INFO * DisplayInfo
+ );
+
+gceSTATUS
+gcoOS_GetDisplayVirtual(
+ IN HALNativeDisplayType Display,
+ OUT gctINT * Width,
+ OUT gctINT * Height
+ );
+
+gceSTATUS
+gcoOS_GetDisplayBackbuffer(
+ IN HALNativeDisplayType Display,
+ IN HALNativeWindowType Window,
+ OUT gctPOINTER * context,
+ OUT gcoSURF * surface,
+ OUT gctUINT * Offset,
+ OUT gctINT * X,
+ OUT gctINT * Y
+ );
+
+gceSTATUS
+gcoOS_SetDisplayVirtual(
+ IN HALNativeDisplayType Display,
+ IN HALNativeWindowType Window,
+ IN gctUINT Offset,
+ IN gctINT X,
+ IN gctINT Y
+ );
+
+gceSTATUS
+gcoOS_SetDisplayVirtualEx(
+ IN HALNativeDisplayType Display,
+ IN HALNativeWindowType Window,
+ IN gctPOINTER Context,
+ IN gcoSURF Surface,
+ IN gctUINT Offset,
+ IN gctINT X,
+ IN gctINT Y
+ );
+
+gceSTATUS
+gcoOS_CancelDisplayBackbuffer(
+ IN HALNativeDisplayType Display,
+ IN HALNativeWindowType Window,
+ IN gctPOINTER Context,
+ IN gcoSURF Surface,
+ IN gctUINT Offset,
+ IN gctINT X,
+ IN gctINT Y
+ );
+
+gceSTATUS
+gcoOS_SetSwapInterval(
+ IN HALNativeDisplayType Display,
+ IN gctINT Interval
+);
+
+gceSTATUS
+gcoOS_SetSwapIntervalEx(
+ IN HALNativeDisplayType Display,
+ IN gctINT Interval,
+ IN gctPOINTER localDisplay);
+
+gceSTATUS
+gcoOS_GetSwapInterval(
+ IN HALNativeDisplayType Display,
+ IN gctINT_PTR Min,
+ IN gctINT_PTR Max
+);
+
+gceSTATUS
+gcoOS_DisplayBufferRegions(
+ IN HALNativeDisplayType Display,
+ IN HALNativeWindowType Window,
+ IN gctINT NumRects,
+ IN gctINT_PTR Rects
+ );
+
+gceSTATUS
+gcoOS_DestroyDisplay(
+ IN HALNativeDisplayType Display
+ );
+
+gceSTATUS
+gcoOS_InitLocalDisplayInfo(
+ IN HALNativeDisplayType Display,
+ IN OUT gctPOINTER * localDisplay
+ );
+
+gceSTATUS
+gcoOS_DeinitLocalDisplayInfo(
+ IN HALNativeDisplayType Display,
+ IN OUT gctPOINTER * localDisplay
+ );
+
+gceSTATUS
+gcoOS_GetDisplayInfoEx2(
+ IN HALNativeDisplayType Display,
+ IN HALNativeWindowType Window,
+ IN gctPOINTER localDisplay,
+ IN gctUINT DisplayInfoSize,
+ OUT halDISPLAY_INFO * DisplayInfo
+ );
+
+gceSTATUS
+gcoOS_GetDisplayBackbufferEx(
+ IN HALNativeDisplayType Display,
+ IN HALNativeWindowType Window,
+ IN gctPOINTER localDisplay,
+ OUT gctPOINTER * context,
+ OUT gcoSURF * surface,
+ OUT gctUINT * Offset,
+ OUT gctINT * X,
+ OUT gctINT * Y
+ );
+
+gceSTATUS
+gcoOS_IsValidDisplay(
+ IN HALNativeDisplayType Display
+ );
+
+gceSTATUS
+gcoOS_GetNativeVisualId(
+ IN HALNativeDisplayType Display,
+ OUT gctINT* nativeVisualId
+ );
+
+gctBOOL
+gcoOS_SynchronousFlip(
+ IN HALNativeDisplayType Display
+ );
+
+/*******************************************************************************
+** Windows. ********************************************************************
+*/
+
+gceSTATUS
+gcoOS_CreateWindow(
+ IN HALNativeDisplayType Display,
+ IN gctINT X,
+ IN gctINT Y,
+ IN gctINT Width,
+ IN gctINT Height,
+ OUT HALNativeWindowType * Window
+ );
+
+gceSTATUS
+gcoOS_GetWindowInfo(
+ IN HALNativeDisplayType Display,
+ IN HALNativeWindowType Window,
+ OUT gctINT * X,
+ OUT gctINT * Y,
+ OUT gctINT * Width,
+ OUT gctINT * Height,
+ OUT gctINT * BitsPerPixel,
+ OUT gctUINT * Offset
+ );
+
+gceSTATUS
+gcoOS_DestroyWindow(
+ IN HALNativeDisplayType Display,
+ IN HALNativeWindowType Window
+ );
+
+gceSTATUS
+gcoOS_DrawImage(
+ IN HALNativeDisplayType Display,
+ IN HALNativeWindowType Window,
+ IN gctINT Left,
+ IN gctINT Top,
+ IN gctINT Right,
+ IN gctINT Bottom,
+ IN gctINT Width,
+ IN gctINT Height,
+ IN gctINT BitsPerPixel,
+ IN gctPOINTER Bits
+ );
+
+gceSTATUS
+gcoOS_GetImage(
+ IN HALNativeWindowType Window,
+ IN gctINT Left,
+ IN gctINT Top,
+ IN gctINT Right,
+ IN gctINT Bottom,
+ OUT gctINT * BitsPerPixel,
+ OUT gctPOINTER * Bits
+ );
+
+gceSTATUS
+gcoOS_GetWindowInfoEx(
+ IN HALNativeDisplayType Display,
+ IN HALNativeWindowType Window,
+ OUT gctINT * X,
+ OUT gctINT * Y,
+ OUT gctINT * Width,
+ OUT gctINT * Height,
+ OUT gctINT * BitsPerPixel,
+ OUT gctUINT * Offset,
+ OUT gceSURF_FORMAT * Format,
+ OUT gceSURF_TYPE * Type
+ );
+
+gceSTATUS
+gcoOS_DrawImageEx(
+ IN HALNativeDisplayType Display,
+ IN HALNativeWindowType Window,
+ IN gctINT Left,
+ IN gctINT Top,
+ IN gctINT Right,
+ IN gctINT Bottom,
+ IN gctINT Width,
+ IN gctINT Height,
+ IN gctINT BitsPerPixel,
+ IN gctPOINTER Bits,
+ IN gceSURF_FORMAT Format
+ );
+
+/*
+ * Possiable types:
+ * gcvSURF_BITMAP
+ * gcvSURF_RENDER_TARGET
+ * gcvSURF_RENDER_TARGET_NO_COMPRESSION
+ * gcvSURF_RENDER_TARGET_NO_TILE_STATUS
+ */
+gceSTATUS
+gcoOS_SetWindowFormat(
+ IN HALNativeDisplayType Display,
+ IN HALNativeWindowType Window,
+ IN gceSURF_TYPE Type,
+ IN gceSURF_FORMAT Format
+ );
+
+
+/*******************************************************************************
+** Pixmaps. ********************************************************************
+*/
+
+gceSTATUS
+gcoOS_CreatePixmap(
+ IN HALNativeDisplayType Display,
+ IN gctINT Width,
+ IN gctINT Height,
+ IN gctINT BitsPerPixel,
+ OUT HALNativePixmapType * Pixmap
+ );
+
+gceSTATUS
+gcoOS_GetPixmapInfo(
+ IN HALNativeDisplayType Display,
+ IN HALNativePixmapType Pixmap,
+ OUT gctINT * Width,
+ OUT gctINT * Height,
+ OUT gctINT * BitsPerPixel,
+ OUT gctINT * Stride,
+ OUT gctPOINTER * Bits
+ );
+
+gceSTATUS
+gcoOS_DrawPixmap(
+ IN HALNativeDisplayType Display,
+ IN HALNativePixmapType Pixmap,
+ IN gctINT Left,
+ IN gctINT Top,
+ IN gctINT Right,
+ IN gctINT Bottom,
+ IN gctINT Width,
+ IN gctINT Height,
+ IN gctINT BitsPerPixel,
+ IN gctPOINTER Bits
+ );
+
+gceSTATUS
+gcoOS_DestroyPixmap(
+ IN HALNativeDisplayType Display,
+ IN HALNativePixmapType Pixmap
+ );
+
+gceSTATUS
+gcoOS_GetPixmapInfoEx(
+ IN HALNativeDisplayType Display,
+ IN HALNativePixmapType Pixmap,
+ OUT gctINT * Width,
+ OUT gctINT * Height,
+ OUT gctINT * BitsPerPixel,
+ OUT gctINT * Stride,
+ OUT gctPOINTER * Bits,
+ OUT gceSURF_FORMAT * Format
+ );
+
+gceSTATUS
+gcoOS_CopyPixmapBits(
+ IN HALNativeDisplayType Display,
+ IN HALNativePixmapType Pixmap,
+ IN gctUINT DstWidth,
+ IN gctUINT DstHeight,
+ IN gctINT DstStride,
+ IN gceSURF_FORMAT DstFormat,
+ OUT gctPOINTER DstBits
+ );
+
+/*******************************************************************************
+** OS relative. ****************************************************************
+*/
+gceSTATUS
+gcoOS_LoadEGLLibrary(
+ OUT gctHANDLE * Handle
+ );
+
+gceSTATUS
+gcoOS_FreeEGLLibrary(
+ IN gctHANDLE Handle
+ );
+
+gceSTATUS
+gcoOS_ShowWindow(
+ IN HALNativeDisplayType Display,
+ IN HALNativeWindowType Window
+ );
+
+gceSTATUS
+gcoOS_HideWindow(
+ IN HALNativeDisplayType Display,
+ IN HALNativeWindowType Window
+ );
+
+gceSTATUS
+gcoOS_SetWindowTitle(
+ IN HALNativeDisplayType Display,
+ IN HALNativeWindowType Window,
+ IN gctCONST_STRING Title
+ );
+
+gceSTATUS
+gcoOS_CapturePointer(
+ IN HALNativeDisplayType Display,
+ IN HALNativeWindowType Window
+ );
+
+gceSTATUS
+gcoOS_GetEvent(
+ IN HALNativeDisplayType Display,
+ IN HALNativeWindowType Window,
+ OUT halEvent * Event
+ );
+
+gceSTATUS
+gcoOS_CreateClientBuffer(
+ IN gctINT Width,
+ IN gctINT Height,
+ IN gctINT Format,
+ IN gctINT Type,
+ OUT gctPOINTER * ClientBuffer
+ );
+
+gceSTATUS
+gcoOS_GetClientBufferInfo(
+ IN gctPOINTER ClientBuffer,
+ OUT gctINT * Width,
+ OUT gctINT * Height,
+ OUT gctINT * Stride,
+ OUT gctPOINTER * Bits
+ );
+
+gceSTATUS
+gcoOS_DestroyClientBuffer(
+ IN gctPOINTER ClientBuffer
+ );
+
+gceSTATUS
+gcoOS_DestroyContext(
+ IN gctPOINTER Display,
+ IN gctPOINTER Context
+ );
+
+gceSTATUS
+gcoOS_CreateContext(
+ IN gctPOINTER LocalDisplay,
+ IN gctPOINTER Context
+ );
+
+gceSTATUS
+gcoOS_MakeCurrent(
+ IN gctPOINTER LocalDisplay,
+ IN HALNativeWindowType DrawDrawable,
+ IN HALNativeWindowType ReadDrawable,
+ IN gctPOINTER Context,
+ IN gcoSURF ResolveTarget
+ );
+
+gceSTATUS
+gcoOS_CreateDrawable(
+ IN gctPOINTER LocalDisplay,
+ IN HALNativeWindowType Drawable
+ );
+
+gceSTATUS
+gcoOS_DestroyDrawable(
+ IN gctPOINTER LocalDisplay,
+ IN HALNativeWindowType Drawable
+ );
+gceSTATUS
+gcoOS_SwapBuffers(
+ IN gctPOINTER LocalDisplay,
+ IN HALNativeWindowType Drawable,
+ IN gcoSURF RenderTarget,
+ IN gcoSURF ResolveTarget,
+ IN gctPOINTER ResolveBits,
+ OUT gctUINT *Width,
+ OUT gctUINT *Height
+ );
+
+gceSTATUS
+gcoOS_ResizeWindow(
+ IN gctPOINTER localDisplay,
+ IN HALNativeWindowType Drawable,
+ IN gctUINT Width,
+ IN gctUINT Height
+ );
+
+gceSTATUS
+gcoOS_RSForSwap(
+ IN gctPOINTER localDisplay,
+ IN HALNativeWindowType Drawable,
+ IN gctPOINTER resolve
+ );
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __gc_hal_eglplatform_h_ */
+
+
+
diff --git a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_eglplatform_type.h b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_eglplatform_type.h
new file mode 100644
index 000000000000..c35cab5a613b
--- /dev/null
+++ b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_eglplatform_type.h
@@ -0,0 +1,326 @@
+/****************************************************************************
+*
+* The MIT License (MIT)
+*
+* Copyright (c) 2014 - 2018 Vivante 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 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 GPL License (GPL)
+*
+* Copyright (C) 2014 - 2018 Vivante 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.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+*****************************************************************************
+*
+* Note: This software is released under dual MIT and GPL licenses. A
+* recipient may use this file under the terms of either the MIT license or
+* GPL License. If you wish to use only one license not the other, you can
+* indicate your decision by deleting one of the above license notices in your
+* version of this file.
+*
+*****************************************************************************/
+
+
+#ifndef __gc_hal_eglplatform_type_h_
+#define __gc_hal_eglplatform_type_h_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*******************************************************************************
+** Events. *********************************************************************
+*/
+
+typedef enum _halEventType
+{
+ /* Keyboard event. */
+ HAL_KEYBOARD,
+
+ /* Mouse move event. */
+ HAL_POINTER,
+
+ /* Mouse button event. */
+ HAL_BUTTON,
+
+ /* Application close event. */
+ HAL_CLOSE,
+
+ /* Application window has been updated. */
+ HAL_WINDOW_UPDATE
+}
+halEventType;
+
+/* Scancodes for keyboard. */
+typedef enum _halKeys
+{
+ HAL_UNKNOWN = -1,
+
+ HAL_BACKSPACE = 0x08,
+ HAL_TAB,
+ HAL_ENTER = 0x0D,
+ HAL_ESCAPE = 0x1B,
+
+ HAL_SPACE = 0x20,
+ HAL_SINGLEQUOTE = 0x27,
+ HAL_PAD_ASTERISK = 0x2A,
+ HAL_COMMA = 0x2C,
+ HAL_HYPHEN,
+ HAL_PERIOD,
+ HAL_SLASH,
+ HAL_0,
+ HAL_1,
+ HAL_2,
+ HAL_3,
+ HAL_4,
+ HAL_5,
+ HAL_6,
+ HAL_7,
+ HAL_8,
+ HAL_9,
+ HAL_SEMICOLON = 0x3B,
+ HAL_EQUAL = 0x3D,
+ HAL_A = 0x41,
+ HAL_B,
+ HAL_C,
+ HAL_D,
+ HAL_E,
+ HAL_F,
+ HAL_G,
+ HAL_H,
+ HAL_I,
+ HAL_J,
+ HAL_K,
+ HAL_L,
+ HAL_M,
+ HAL_N,
+ HAL_O,
+ HAL_P,
+ HAL_Q,
+ HAL_R,
+ HAL_S,
+ HAL_T,
+ HAL_U,
+ HAL_V,
+ HAL_W,
+ HAL_X,
+ HAL_Y,
+ HAL_Z,
+ HAL_LBRACKET,
+ HAL_BACKSLASH,
+ HAL_RBRACKET,
+ HAL_BACKQUOTE = 0x60,
+
+ HAL_F1 = 0x80,
+ HAL_F2,
+ HAL_F3,
+ HAL_F4,
+ HAL_F5,
+ HAL_F6,
+ HAL_F7,
+ HAL_F8,
+ HAL_F9,
+ HAL_F10,
+ HAL_F11,
+ HAL_F12,
+
+ HAL_LCTRL,
+ HAL_RCTRL,
+ HAL_LSHIFT,
+ HAL_RSHIFT,
+ HAL_LALT,
+ HAL_RALT,
+ HAL_CAPSLOCK,
+ HAL_NUMLOCK,
+ HAL_SCROLLLOCK,
+ HAL_PAD_0,
+ HAL_PAD_1,
+ HAL_PAD_2,
+ HAL_PAD_3,
+ HAL_PAD_4,
+ HAL_PAD_5,
+ HAL_PAD_6,
+ HAL_PAD_7,
+ HAL_PAD_8,
+ HAL_PAD_9,
+ HAL_PAD_HYPHEN,
+ HAL_PAD_PLUS,
+ HAL_PAD_SLASH,
+ HAL_PAD_PERIOD,
+ HAL_PAD_ENTER,
+ HAL_SYSRQ,
+ HAL_PRNTSCRN,
+ HAL_BREAK,
+ HAL_UP,
+ HAL_LEFT,
+ HAL_RIGHT,
+ HAL_DOWN,
+ HAL_HOME,
+ HAL_END,
+ HAL_PGUP,
+ HAL_PGDN,
+ HAL_INSERT,
+ HAL_DELETE,
+ HAL_LWINDOW,
+ HAL_RWINDOW,
+ HAL_MENU,
+ HAL_POWER,
+ HAL_SLEEP,
+ HAL_WAKE
+}
+halKeys;
+
+/* Structure that defined keyboard mapping. */
+typedef struct _halKeyMap
+{
+ /* Normal key. */
+ halKeys normal;
+
+ /* Extended key. */
+ halKeys extended;
+}
+halKeyMap;
+
+/* Event structure. */
+typedef struct _halEvent
+{
+ /* Event type. */
+ halEventType type;
+
+ /* Event data union. */
+ union _halEventData
+ {
+ /* Event data for keyboard. */
+ struct _halKeyboard
+ {
+ /* Scancode. */
+ halKeys scancode;
+
+ /* ASCII characte of the key pressed. */
+ char key;
+
+ /* Flag whether the key was pressed (1) or released (0). */
+ char pressed;
+ }
+ keyboard;
+
+ /* Event data for pointer. */
+ struct _halPointer
+ {
+ /* Current pointer coordinate. */
+ int x;
+ int y;
+ }
+ pointer;
+
+ /* Event data for mouse buttons. */
+ struct _halButton
+ {
+ /* Left button state. */
+ int left;
+
+ /* Middle button state. */
+ int middle;
+
+ /* Right button state. */
+ int right;
+
+ /* Current pointer coordinate. */
+ int x;
+ int y;
+ }
+ button;
+ }
+ data;
+}
+halEvent;
+
+/* VFK_DISPLAY_INFO structure defining information returned by
+ vdkGetDisplayInfoEx. */
+typedef struct _halDISPLAY_INFO
+{
+ /* The size of the display in pixels. */
+ int width;
+ int height;
+
+ /* The stride of the dispay. -1 is returned if the stride is not known
+ ** for the specified display.*/
+ int stride;
+
+ /* The color depth of the display in bits per pixel. */
+ int bitsPerPixel;
+
+ /* The logical pointer to the display memory buffer. NULL is returned
+ ** if the pointer is not known for the specified display. */
+ void * logical;
+
+ /* The physical address of the display memory buffer. ~0 is returned
+ ** if the address is not known for the specified display. */
+ unsigned long physical;
+
+ /* Can be wraped as surface. */
+ int wrapFB;
+
+ /* FB_MULTI_BUFFER support */
+ int multiBuffer;
+ int backBufferY;
+
+ /* Tiled buffer / tile status support. */
+ int tiledBuffer;
+ int tileStatus;
+ int compression;
+
+ /* The color info of the display. */
+ unsigned int alphaLength;
+ unsigned int alphaOffset;
+ unsigned int redLength;
+ unsigned int redOffset;
+ unsigned int greenLength;
+ unsigned int greenOffset;
+ unsigned int blueLength;
+ unsigned int blueOffset;
+
+ /* Display flip support. */
+ int flip;
+}
+halDISPLAY_INFO;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __gc_hal_eglplatform_type_h_ */
+
+
diff --git a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_engine.h b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_engine.h
new file mode 100644
index 000000000000..4c2f92599047
--- /dev/null
+++ b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_engine.h
@@ -0,0 +1,2977 @@
+/****************************************************************************
+*
+* The MIT License (MIT)
+*
+* Copyright (c) 2014 - 2018 Vivante 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 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 GPL License (GPL)
+*
+* Copyright (C) 2014 - 2018 Vivante 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.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+*****************************************************************************
+*
+* Note: This software is released under dual MIT and GPL licenses. A
+* recipient may use this file under the terms of either the MIT license or
+* GPL License. If you wish to use only one license not the other, you can
+* indicate your decision by deleting one of the above license notices in your
+* version of this file.
+*
+*****************************************************************************/
+
+
+#ifndef __gc_hal_engine_h_
+#define __gc_hal_engine_h_
+
+#include "gc_hal_types.h"
+#include "gc_hal_enum.h"
+
+
+#if gcdENABLE_3D && gcdENABLE_VG
+#include "gc_hal_engine_vg.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct _gcsSURF_RESOLVE_ARGS
+{
+ gceHAL_ARG_VERSION version;
+
+ union _gcsSURF_RESOLVE_ARGS_UNION
+ {
+
+ struct _gcsSURF_RESOLVE_ARG_v2
+ {
+ gctBOOL yInverted;
+ gctBOOL directCopy;
+ gctBOOL resample;
+ gctBOOL bUploadTex; /* used for upload tex.*/
+ gctBOOL visualizeDepth; /* convert depth to visible color */
+ gcsPOINT srcOrigin;
+ gcsPOINT dstOrigin;
+ gcsPOINT rectSize;
+ gctUINT numSlices;
+ gceENGINE engine; /* 3DBlit engine */
+ gctBOOL gpuOnly; /* need only try HW path.*/
+
+ gctBOOL dump; /* need dump for verify */
+ gctBOOL srcSwizzle; /* src surface format swizzle infomation */
+ gctBOOL dstSwizzle; /* dst surface format swizzle infomation */
+ gctBOOL srcCompressed; /* src compressed format*/
+ gctBOOL dstCompressed; /* dst compressed format*/
+ } v2;
+ } uArgs;
+}
+gcsSURF_RESOLVE_ARGS;
+
+typedef struct _gscBUFFER_VIEW
+{
+ gctUINT32 cmd;
+}gcsBUFFER_VIEW, *gcsBUFFER_VIEW_PTR;
+
+typedef struct _gcsIMAGE_VIEW
+{
+ gctUINT32 cmd;
+}gcsIMAGE_VIEW, *gcsIMAGE_VIEW_PTR;
+
+#if gcdENABLE_3D
+/******************************************************************************\
+****************************** Object Declarations *****************************
+\******************************************************************************/
+
+typedef struct _gcoSTREAM * gcoSTREAM;
+typedef struct _gcoVERTEX * gcoVERTEX;
+typedef struct _gcoTEXTURE * gcoTEXTURE;
+typedef struct _gcoINDEX * gcoINDEX;
+typedef struct _gcsVERTEX_ATTRIBUTES * gcsVERTEX_ATTRIBUTES_PTR;
+typedef struct _gcoVERTEXARRAY * gcoVERTEXARRAY;
+typedef struct _gcoBUFOBJ * gcoBUFOBJ;
+
+#define gcdATTRIBUTE_COUNT 32
+#define gcdVERTEXARRAY_POOL_CAPACITY 32
+
+typedef enum _gcePROGRAM_STAGE
+{
+ gcvPROGRAM_STAGE_VERTEX = 0x0,
+ gcvPROGRAM_STAGE_TCS = 0x1,
+ gcvPROGRAM_STAGE_TES = 0x2,
+ gcvPROGRAM_STAGE_GEOMETRY = 0x3,
+ gcvPROGRAM_STAGE_FRAGMENT = 0x4,
+ gcvPROGRAM_STAGE_COMPUTE = 0x5,
+ gcvPROGRAM_STAGE_OPENCL = 0x6,
+ gcvPROGRAM_STAGE_LAST
+}
+gcePROGRAM_STAGE;
+
+typedef enum _gcePROGRAM_STAGE_BIT
+{
+ gcvPROGRAM_STAGE_VERTEX_BIT = 1 << gcvPROGRAM_STAGE_VERTEX,
+ gcvPROGRAM_STAGE_TCS_BIT = 1 << gcvPROGRAM_STAGE_TCS,
+ gcvPROGRAM_STAGE_TES_BIT = 1 << gcvPROGRAM_STAGE_TES,
+ gcvPROGRAM_STAGE_GEOMETRY_BIT = 1 << gcvPROGRAM_STAGE_GEOMETRY,
+ gcvPROGRAM_STAGE_FRAGMENT_BIT = 1 << gcvPROGRAM_STAGE_FRAGMENT,
+ gcvPROGRAM_STAGE_COMPUTE_BIT = 1 << gcvPROGRAM_STAGE_COMPUTE,
+ gcvPROGRAM_STAGE_OPENCL_BIT = 1 << gcvPROGRAM_STAGE_OPENCL,
+}
+gcePROGRAM_STAGE_BIT;
+
+
+#define gcvPORGRAM_STAGE_GPIPE (gcvPROGRAM_STAGE_VERTEX_BIT | \
+ gcvPROGRAM_STAGE_TCS_BIT | \
+ gcvPROGRAM_STAGE_TES_BIT | \
+ gcvPROGRAM_STAGE_GEOMETRY_BIT)
+
+/******************************************************************************\
+********************************* gcoHAL Object *********************************
+\******************************************************************************/
+
+gceSTATUS
+gcoHAL_QueryShaderCaps(
+ IN gcoHAL Hal,
+ OUT gctUINT * UnifiedUniforms,
+ OUT gctUINT * VertUniforms,
+ OUT gctUINT * FragUniforms,
+ OUT gctUINT * Varyings,
+ OUT gctUINT * ShaderCoreCount,
+ OUT gctUINT * ThreadCount,
+ OUT gctUINT * VertInstructionCount,
+ OUT gctUINT * FragInstructionCount
+ );
+
+gceSTATUS
+gcoHAL_QuerySamplerBase(
+ IN gcoHAL Hal,
+ OUT gctUINT32 * VertexCount,
+ OUT gctINT_PTR VertexBase,
+ OUT gctUINT32 * FragmentCount,
+ OUT gctINT_PTR FragmentBase
+ );
+
+gceSTATUS
+gcoHAL_QueryUniformBase(
+ IN gcoHAL Hal,
+ OUT gctUINT32 * VertexBase,
+ OUT gctUINT32 * FragmentBase
+ );
+
+gceSTATUS
+gcoHAL_QueryTextureCaps(
+ IN gcoHAL Hal,
+ OUT gctUINT * MaxWidth,
+ OUT gctUINT * MaxHeight,
+ OUT gctUINT * MaxDepth,
+ OUT gctBOOL * Cubic,
+ OUT gctBOOL * NonPowerOfTwo,
+ OUT gctUINT * VertexSamplers,
+ OUT gctUINT * PixelSamplers
+ );
+
+gceSTATUS
+gcoHAL_QueryTextureMaxAniso(
+ IN gcoHAL Hal,
+ OUT gctUINT * MaxAnisoValue
+ );
+
+gceSTATUS
+gcoHAL_QueryStreamCaps(
+ IN gcoHAL Hal,
+ OUT gctUINT32 * MaxAttributes,
+ OUT gctUINT32 * MaxStreamStride,
+ OUT gctUINT32 * NumberOfStreams,
+ OUT gctUINT32 * Alignment,
+ OUT gctUINT32 * MaxAttribOffset
+ );
+
+/******************************************************************************\
+********************************* gcoSURF Object ********************************
+\******************************************************************************/
+
+/*----------------------------------------------------------------------------*/
+/*--------------------------------- gcoSURF 3D --------------------------------*/
+typedef enum _gceBLIT_FLAG
+{
+ gcvBLIT_FLAG_SKIP_DEPTH_WRITE = 1 << 0,
+ gcvBLIT_FLAG_SKIP_STENCIL_WRITE = 1 << 1,
+} gceBLIT_FLAG;
+
+typedef struct _gcsSURF_BLIT_ARGS
+{
+ gcoSURF srcSurface;
+ gctINT srcX, srcY, srcZ;
+ gctINT srcWidth, srcHeight, srcDepth;
+ gcoSURF dstSurface;
+ gctINT dstX, dstY, dstZ;
+ gctINT dstWidth, dstHeight, dstDepth;
+ gctBOOL xReverse;
+ gctBOOL yReverse;
+ gctBOOL scissorTest;
+ gcsRECT scissor;
+ gctUINT flags;
+ gctUINT srcNumSlice, dstNumSlice;
+ gctBOOL needDecode;
+}
+gcsSURF_BLIT_ARGS;
+
+
+
+
+/* Clear flags. */
+typedef enum _gceCLEAR
+{
+ gcvCLEAR_COLOR = 0x1,
+ gcvCLEAR_DEPTH = 0x2,
+ gcvCLEAR_STENCIL = 0x4,
+ gcvCLEAR_HZ = 0x8,
+ gcvCLEAR_WITH_GPU_ONLY = 0x100,
+ gcvCLEAR_WITH_CPU_ONLY = 0x200,
+ gcvCLEAR_MULTI_SLICES = 0x400,
+}
+gceCLEAR;
+
+typedef struct _gcsSURF_CLEAR_ARGS
+{
+ /*
+ ** Color to fill the color portion of the framebuffer when clear
+ ** is called.
+ */
+ struct {
+ gcuVALUE r;
+ gcuVALUE g;
+ gcuVALUE b;
+ gcuVALUE a;
+ /* Color has multiple value type so we must specify it. */
+ gceVALUE_TYPE valueType;
+ } color;
+
+ gcuVALUE depth;
+ gctUINT stencil;
+
+ gctUINT8 stencilMask; /* stencil bit-wise mask */
+ gctBOOL depthMask; /* Depth Write Mask */
+ gctUINT8 colorMask; /* 4-bit channel Mask: ABGR:MSB->LSB */
+ gcsRECT_PTR clearRect; /* NULL means full clear */
+ gceCLEAR flags; /* clear flags */
+
+ gctUINT32 offset; /* Offset in surface to cube/array/3D, obsolete in v2 version */
+
+} gcsSURF_CLEAR_ARGS, *gcsSURF_CLEAR_ARGS_PTR;
+
+
+typedef struct _gscSURF_BLITDRAW_BLIT
+{
+ gcoSURF srcSurface;
+ gcoSURF dstSurface;
+ gcsRECT srcRect;
+ gcsRECT dstRect;
+ gceTEXTURE_FILTER filterMode;
+ gctBOOL xReverse;
+ gctBOOL yReverse;
+ gctBOOL scissorEnabled;
+ gcsRECT scissor;
+}gscSURF_BLITDRAW_BLIT;
+
+
+typedef enum _gceBLITDRAW_TYPE
+{
+ gcvBLITDRAW_CLEAR = 0,
+ gcvBLITDRAW_BLIT = 1,
+
+ /* last number, not a real type */
+ gcvBLITDRAW_NUM_TYPE
+ }
+gceBLITDRAW_TYPE;
+
+typedef enum _gceSPLIT_DRAW_TYPE
+{
+ gcvSPLIT_DRAW_UNKNOWN = 0x0,
+ gcvSPLIT_DRAW_1,
+ gcvSPLIT_DRAW_2,
+ gcvSPLIT_DRAW_3,
+ gcvSPLIT_DRAW_4,
+ gcvSPLIT_DRAW_XFB,
+ gcvSPLIT_DRAW_INDEX_FETCH,
+ gcvSPLIT_DRAW_TCS,
+ gcvSPLIT_DRAW_WIDE_LINE,
+ gcvSPLIT_DRAW_STIPPLE,
+ gcvSPLIT_DRAW_LAST
+}
+gceSPLIT_DRAW_TYPE;
+
+typedef gceSTATUS (* gctSPLIT_DRAW_FUNC_PTR)(
+ IN gctPOINTER gc,
+ IN gctPOINTER instantDraw,
+ IN gctPOINTER splitDrawInfo
+ );
+
+typedef struct _gcsSPLIT_DRAW_INFO
+{
+ gceSPLIT_DRAW_TYPE splitDrawType;
+ gctSPLIT_DRAW_FUNC_PTR splitDrawFunc;
+
+ union _gcsSPLIT_DRAW_UNION
+ {
+ /* This path will split many draw.*/
+ struct __gcsSPLIT_DRAW_INFO_TCS
+ {
+ gctPOINTER indexPtr;
+ gctUINT indexPerPatch;
+ }info_tcs;
+
+ /* This path split into two draw at most.
+ ** es11 path follow the old code, es30 path
+ ** add more info parameter to record
+ */
+ struct __gcsSPLIT_DRAW_INFO_INDEX_FETCH
+ {
+ gctSIZE_T instanceCount;
+ gctSIZE_T splitCount;
+ gcePRIMITIVE splitPrimMode;
+ gctSIZE_T splitPrimCount;
+ }info_index_fetch;
+ }u;
+} gcsSPLIT_DRAW_INFO,
+*gcsSPLIT_DRAW_INFO_PTR;
+
+typedef struct _gscSURF_BLITDRAW_ARGS
+{
+ /* always the fist member */
+ gceHAL_ARG_VERSION version;
+
+ union _gcsSURF_BLITDRAW_ARGS_UNION
+ {
+ struct _gscSURF_BLITDRAW_ARG_v1
+ {
+ /* Whether it's clear or blit operation, can be extended. */
+ gceBLITDRAW_TYPE type;
+
+ union _gscSURF_BLITDRAW_UNION
+ {
+ gscSURF_BLITDRAW_BLIT blit;
+
+ struct _gscSURF_BLITDRAW_CLEAR
+ {
+ gcsSURF_CLEAR_ARGS clearArgs;
+ gcoSURF rtSurface;
+ gcoSURF dsSurface;
+ } clear;
+ } u;
+ } v1;
+ } uArgs;
+}
+gcsSURF_BLITDRAW_ARGS;
+
+typedef struct _gcsSURF_BLITBLT_ARGS
+{
+ gctCONST_POINTER buf;
+ gceSURF_FORMAT format;
+ gctUINT32 stride;
+ gcoSURF dstSurf;
+ gcsPOINT dstOrigin;
+ gcsPOINT rectSize;
+ gctUINT32 dstOffset;
+}
+gcsSURF_BLITBLT_ARGS;
+
+
+/* CPU Blit with format (including linear <-> tile) conversion*/
+gceSTATUS
+gcoSURF_BlitCPU(
+ gcsSURF_BLIT_ARGS* args
+ );
+
+/* Copy a rectangular area with format conversion. */
+gceSTATUS
+gcoSURF_CopyPixels(
+ IN gcsSURF_VIEW *SrcView,
+ IN gcsSURF_VIEW *DstView,
+ IN gcsSURF_RESOLVE_ARGS *Args
+ );
+
+/* Clear surface function. */
+gceSTATUS
+gcoSURF_Clear(
+ IN gcsSURF_VIEW *SurfView,
+ IN gcsSURF_CLEAR_ARGS_PTR ClearArgs
+ );
+
+/* Preserve pixels from source. */
+gceSTATUS
+gcoSURF_Preserve(
+ IN gcoSURF SrcSurf,
+ IN gcoSURF DstSurf,
+ IN gcsRECT_PTR MaskRect
+ );
+
+/* TO BE REMOVED */
+gceSTATUS
+depr_gcoSURF_Resolve(
+ IN gcoSURF SrcSurface,
+ IN gcoSURF DestSurface,
+ IN gctUINT32 DestAddress,
+ IN gctPOINTER DestBits,
+ IN gctINT DestStride,
+ IN gceSURF_TYPE DestType,
+ IN gceSURF_FORMAT DestFormat,
+ IN gctUINT DestWidth,
+ IN gctUINT DestHeight
+ );
+
+gceSTATUS
+depr_gcoSURF_ResolveRect(
+ IN gcoSURF SrcSurface,
+ IN gcoSURF DstSurface,
+ IN gctUINT32 DstAddress,
+ IN gctPOINTER DstBits,
+ IN gctINT DstStride,
+ IN gceSURF_TYPE DstType,
+ IN gceSURF_FORMAT DstFormat,
+ IN gctUINT DstWidth,
+ IN gctUINT DstHeight,
+ IN gcsPOINT_PTR SrcOrigin,
+ IN gcsPOINT_PTR gcoSURF,
+ IN gcsPOINT_PTR RectSize
+ );
+
+/* Resample surface. */
+gceSTATUS
+gcoSURF_Resample(
+ IN gcoSURF SrcSurf,
+ IN gcoSURF DstSurf
+ );
+
+/* Resolve rectangular area of a surface. */
+gceSTATUS
+gcoSURF_ResolveRect(
+ IN gcsSURF_VIEW *SrcView,
+ IN gcsSURF_VIEW *DstView,
+ IN gcsSURF_RESOLVE_ARGS *Args
+ );
+
+gceSTATUS
+gcoSURF_GetResolveAlignment(
+ IN gcoSURF Surface,
+ OUT gctUINT *originX,
+ OUT gctUINT *originY,
+ OUT gctUINT *sizeX,
+ OUT gctUINT *sizeY
+ );
+
+gceSTATUS
+gcoSURF_IsHWResolveable(
+ IN gcoSURF SrcSurf,
+ IN gcoSURF DstSurf,
+ IN gcsPOINT_PTR SrcOrigin,
+ IN gcsPOINT_PTR DstOrigin,
+ IN gcsPOINT_PTR RectSize
+ );
+
+/* Set surface resolvability. */
+gceSTATUS
+gcoSURF_SetResolvability(
+ IN gcoSURF Surface,
+ IN gctBOOL Resolvable
+ );
+
+gceSTATUS
+gcoSURF_IsRenderable(
+ IN gcoSURF Surface
+ );
+
+gceSTATUS
+gcoSURF_IsFormatRenderableAsRT(
+ IN gcoSURF Surface
+ );
+
+gceSTATUS
+gcoBUFOBJ_GetFence(
+ IN gcoBUFOBJ BufObj,
+ IN gceFENCE_TYPE Type
+ );
+
+gceSTATUS
+gcoBUFOBJ_WaitFence(
+ IN gcoBUFOBJ BufObj,
+ IN gceFENCE_TYPE Type
+ );
+
+gceSTATUS
+gcoBUFOBJ_IsFenceEnabled(
+ IN gcoBUFOBJ BufObj
+ );
+
+gceSTATUS
+gcoSURF_GetFence(
+ IN gcoSURF Surface,
+ IN gceFENCE_TYPE Type
+ );
+
+gceSTATUS
+gcoSURF_WaitFence(
+ IN gcoSURF Surface
+ );
+
+gceSTATUS
+gcoSTREAM_GetFence(
+ IN gcoSTREAM stream
+ );
+
+gceSTATUS
+gcoSTREAM_WaitFence(
+ IN gcoSTREAM stream
+ );
+
+gceSTATUS
+gcoINDEX_GetFence(
+ IN gcoINDEX Index
+ );
+
+gceSTATUS
+gcoINDEX_WaitFence(
+ IN gcoINDEX Index,
+ IN gceFENCE_TYPE Type
+ );
+
+gceSTATUS
+gcoSURF_DrawBlit(
+ gcsSURF_VIEW *SrcView,
+ gcsSURF_VIEW *DstView,
+ gscSURF_BLITDRAW_BLIT *Args
+ );
+
+
+/******************************************************************************\
+******************************** gcoINDEX Object *******************************
+\******************************************************************************/
+
+/* Construct a new gcoINDEX object. */
+gceSTATUS
+gcoINDEX_Construct(
+ IN gcoHAL Hal,
+ OUT gcoINDEX * Index
+ );
+
+/* Destroy a gcoINDEX object. */
+gceSTATUS
+gcoINDEX_Destroy(
+ IN gcoINDEX Index
+ );
+
+/* Lock index in memory. */
+gceSTATUS
+gcoINDEX_Lock(
+ IN gcoINDEX Index,
+ OUT gctUINT32 * Address,
+ OUT gctPOINTER * Memory
+ );
+
+/* Unlock index that was previously locked with gcoINDEX_Lock. */
+gceSTATUS
+gcoINDEX_Unlock(
+ IN gcoINDEX Index
+ );
+
+/* Upload index data into the memory. */
+gceSTATUS
+gcoINDEX_Load(
+ IN gcoINDEX Index,
+ IN gceINDEX_TYPE IndexType,
+ IN gctUINT32 IndexCount,
+ IN gctPOINTER IndexBuffer
+ );
+
+/* Bind an index object to the hardware. */
+gceSTATUS
+gcoINDEX_Bind(
+ IN gcoINDEX Index,
+ IN gceINDEX_TYPE Type
+ );
+
+/* Bind an index object to the hardware. */
+gceSTATUS
+gcoINDEX_BindOffset(
+ IN gcoINDEX Index,
+ IN gceINDEX_TYPE Type,
+ IN gctUINT32 Offset
+ );
+
+/* Free existing index buffer. */
+gceSTATUS
+gcoINDEX_Free(
+ IN gcoINDEX Index
+ );
+
+/* Upload data into an index buffer. */
+gceSTATUS
+gcoINDEX_Upload(
+ IN gcoINDEX Index,
+ IN gctCONST_POINTER Buffer,
+ IN gctSIZE_T Bytes
+ );
+
+/* Upload data into an index buffer starting at an offset. */
+gceSTATUS
+gcoINDEX_UploadOffset(
+ IN gcoINDEX Index,
+ IN gctSIZE_T Offset,
+ IN gctCONST_POINTER Buffer,
+ IN gctSIZE_T Bytes
+ );
+
+/*Merge index2 to index1 from 0, index2 must subset of inex1*/
+gceSTATUS
+gcoINDEX_Merge(
+ IN gcoINDEX Index1,
+ IN gcoINDEX Index2
+ );
+
+/*check if index buffer is enough for this draw*/
+gctBOOL
+gcoINDEX_CheckRange(
+ IN gcoINDEX Index,
+ IN gceINDEX_TYPE Type,
+ IN gctINT Count,
+ IN gctUINT32 Indices
+ );
+
+/* Query the index capabilities. */
+gceSTATUS
+gcoINDEX_QueryCaps(
+ OUT gctBOOL * Index8,
+ OUT gctBOOL * Index16,
+ OUT gctBOOL * Index32,
+ OUT gctUINT * MaxIndex
+ );
+
+/* Determine the index range in the current index buffer. */
+gceSTATUS
+gcoINDEX_GetIndexRange(
+ IN gcoINDEX Index,
+ IN gceINDEX_TYPE Type,
+ IN gctUINT32 Offset,
+ IN gctUINT32 Count,
+ OUT gctUINT32 * MinimumIndex,
+ OUT gctUINT32 * MaximumIndex
+ );
+
+/* Dynamic buffer management. */
+gceSTATUS
+gcoINDEX_SetDynamic(
+ IN gcoINDEX Index,
+ IN gctSIZE_T Bytes,
+ IN gctUINT Buffers
+ );
+
+gceSTATUS
+gcoCLHardware_Construct(void);
+/******************************************************************************\
+********************************** gco3D Object *********************************
+\******************************************************************************/
+
+/* Blending targets. */
+typedef enum _gceBLEND_UNIT
+{
+ gcvBLEND_SOURCE,
+ gcvBLEND_TARGET,
+}
+gceBLEND_UNIT;
+
+/* Construct a new gco3D object. */
+gceSTATUS
+gco3D_Construct(
+ IN gcoHAL Hal,
+ IN gctBOOL Robust,
+ OUT gco3D * Engine
+ );
+
+/* Destroy an gco3D object. */
+gceSTATUS
+gco3D_Destroy(
+ IN gco3D Engine
+ );
+
+/* Set 3D API type. */
+gceSTATUS
+gco3D_SetAPI(
+ IN gco3D Engine,
+ IN gceAPI ApiType
+ );
+
+/* Get 3D API type. */
+gceSTATUS
+gco3D_GetAPI(
+ IN gco3D Engine,
+ OUT gceAPI * ApiType
+ );
+
+gceSTATUS
+gco3D_SetTarget(
+ IN gco3D Engine,
+ IN gctUINT32 TargetIndex,
+ IN gcsSURF_VIEW *SurfView,
+ IN gctUINT32 LayerIndex
+ );
+
+gceSTATUS
+gco3D_UnsetTarget(
+ IN gco3D Engine,
+ IN gctUINT32 TargetIndex,
+ IN gcoSURF Surface
+ );
+
+gceSTATUS
+gco3D_SetPSOutputMapping(
+ IN gco3D Engine,
+ IN gctINT32 * psOutputMapping
+ );
+
+gceSTATUS
+gco3D_SetRenderLayered(
+ IN gco3D Engine,
+ IN gctBOOL Enable,
+ IN gctUINT MaxLayers
+ );
+
+gceSTATUS
+gco3D_SetShaderLayered(
+ IN gco3D Engine,
+ IN gctBOOL Enable
+ );
+
+gceSTATUS
+gco3D_IsProgramSwitched(
+ IN gco3D Engine
+ );
+
+/* Set depth buffer. */
+gceSTATUS
+gco3D_SetDepth(
+ IN gco3D Engine,
+ IN gcsSURF_VIEW *SurfView
+ );
+
+/* Unset depth buffer. */
+gceSTATUS
+gco3D_UnsetDepth(
+ IN gco3D Engine,
+ IN gcoSURF Surface
+ );
+
+/* Set viewport. */
+gceSTATUS
+gco3D_SetViewport(
+ IN gco3D Engine,
+ IN gctINT32 Left,
+ IN gctINT32 Top,
+ IN gctINT32 Right,
+ IN gctINT32 Bottom
+ );
+
+/* Set scissors. */
+gceSTATUS
+gco3D_SetScissors(
+ IN gco3D Engine,
+ IN gctINT32 Left,
+ IN gctINT32 Top,
+ IN gctINT32 Right,
+ IN gctINT32 Bottom
+ );
+
+/* Set clear color. */
+gceSTATUS
+gco3D_SetClearColor(
+ IN gco3D Engine,
+ IN gctUINT8 Red,
+ IN gctUINT8 Green,
+ IN gctUINT8 Blue,
+ IN gctUINT8 Alpha
+ );
+
+/* Set fixed point clear color. */
+gceSTATUS
+gco3D_SetClearColorX(
+ IN gco3D Engine,
+ IN gctFIXED_POINT Red,
+ IN gctFIXED_POINT Green,
+ IN gctFIXED_POINT Blue,
+ IN gctFIXED_POINT Alpha
+ );
+
+/* Set floating point clear color. */
+gceSTATUS
+gco3D_SetClearColorF(
+ IN gco3D Engine,
+ IN gctFLOAT Red,
+ IN gctFLOAT Green,
+ IN gctFLOAT Blue,
+ IN gctFLOAT Alpha
+ );
+
+/* Set fixed point clear depth. */
+gceSTATUS
+gco3D_SetClearDepthX(
+ IN gco3D Engine,
+ IN gctFIXED_POINT Depth
+ );
+
+/* Set floating point clear depth. */
+gceSTATUS
+gco3D_SetClearDepthF(
+ IN gco3D Engine,
+ IN gctFLOAT Depth
+ );
+
+/* Set clear stencil. */
+gceSTATUS
+gco3D_SetClearStencil(
+ IN gco3D Engine,
+ IN gctUINT32 Stencil
+ );
+
+/* Set shading mode. */
+gceSTATUS
+gco3D_SetShading(
+ IN gco3D Engine,
+ IN gceSHADING Shading
+ );
+
+/* Set blending mode. */
+gceSTATUS
+gco3D_EnableBlending(
+ IN gco3D Engine,
+ IN gctBOOL Enable
+ );
+
+/* Set blending function. */
+gceSTATUS
+gco3D_SetBlendFunction(
+ IN gco3D Engine,
+ IN gceBLEND_UNIT Unit,
+ IN gceBLEND_FUNCTION FunctionRGB,
+ IN gceBLEND_FUNCTION FunctionAlpha
+ );
+
+/* Set blending mode. */
+gceSTATUS
+gco3D_SetBlendMode(
+ IN gco3D Engine,
+ IN gceBLEND_MODE ModeRGB,
+ IN gceBLEND_MODE ModeAlpha
+ );
+
+/* Set blending mode for separate rt control */
+gceSTATUS
+gco3D_EnableBlendingIndexed(
+ IN gco3D Engine,
+ IN gctUINT Index,
+ IN gctBOOL Enable
+ );
+
+/* Set blending function for separate rt control */
+gceSTATUS
+gco3D_SetBlendFunctionIndexed(
+ IN gco3D Engine,
+ IN gctUINT Index,
+ IN gceBLEND_UNIT Unit,
+ IN gceBLEND_FUNCTION FunctionRGB,
+ IN gceBLEND_FUNCTION FunctionAlpha
+ );
+
+/* Set blending mode for separate rt control*/
+gceSTATUS
+gco3D_SetBlendModeIndexed(
+ IN gco3D Engine,
+ IN gctUINT Index,
+ IN gceBLEND_MODE ModeRGB,
+ IN gceBLEND_MODE ModeAlpha
+ );
+
+/* Set blending color. */
+gceSTATUS
+gco3D_SetBlendColor(
+ IN gco3D Engine,
+ IN gctUINT Red,
+ IN gctUINT Green,
+ IN gctUINT Blue,
+ IN gctUINT Alpha
+ );
+
+/* Set fixed point blending color. */
+gceSTATUS
+gco3D_SetBlendColorX(
+ IN gco3D Engine,
+ IN gctFIXED_POINT Red,
+ IN gctFIXED_POINT Green,
+ IN gctFIXED_POINT Blue,
+ IN gctFIXED_POINT Alpha
+ );
+
+/* Set floating point blending color. */
+gceSTATUS
+gco3D_SetBlendColorF(
+ IN gco3D Engine,
+ IN gctFLOAT Red,
+ IN gctFLOAT Green,
+ IN gctFLOAT Blue,
+ IN gctFLOAT Alpha
+ );
+
+/* Set culling mode. */
+gceSTATUS
+gco3D_SetCulling(
+ IN gco3D Engine,
+ IN gceCULL Mode
+ );
+
+/* Enable point size */
+gceSTATUS
+gco3D_SetPointSizeEnable(
+ IN gco3D Engine,
+ IN gctBOOL Enable
+ );
+
+/* Set point sprite */
+gceSTATUS
+gco3D_SetPointSprite(
+ IN gco3D Engine,
+ IN gctBOOL Enable
+ );
+
+
+/* Enable/Disable primitive-id. */
+gceSTATUS
+gco3D_SetPrimitiveIdEnable(
+ IN gco3D Engine,
+ IN gctBOOL Enable
+ );
+
+/* Set fill mode. */
+gceSTATUS
+gco3D_SetFill(
+ IN gco3D Engine,
+ IN gceFILL Mode
+ );
+
+/* Set depth compare mode. */
+gceSTATUS
+gco3D_SetDepthCompare(
+ IN gco3D Engine,
+ IN gceCOMPARE Compare
+ );
+
+/* Enable depth writing. */
+gceSTATUS
+gco3D_EnableDepthWrite(
+ IN gco3D Engine,
+ IN gctBOOL Enable
+ );
+
+/* Set depth mode. */
+gceSTATUS
+gco3D_SetDepthMode(
+ IN gco3D Engine,
+ IN gceDEPTH_MODE Mode
+ );
+
+/* Set depth range. */
+gceSTATUS
+gco3D_SetDepthRangeX(
+ IN gco3D Engine,
+ IN gceDEPTH_MODE Mode,
+ IN gctFIXED_POINT Near,
+ IN gctFIXED_POINT Far
+ );
+
+/* Set depth range. */
+gceSTATUS
+gco3D_SetDepthRangeF(
+ IN gco3D Engine,
+ IN gceDEPTH_MODE Mode,
+ IN gctFLOAT Near,
+ IN gctFLOAT Far
+ );
+
+/* Set last pixel enable */
+gceSTATUS
+gco3D_SetLastPixelEnable(
+ IN gco3D Engine,
+ IN gctBOOL Enable
+ );
+
+/* Set depth Bias and Scale */
+gceSTATUS
+gco3D_SetDepthScaleBiasX(
+ IN gco3D Engine,
+ IN gctFIXED_POINT DepthScale,
+ IN gctFIXED_POINT DepthBias
+ );
+
+gceSTATUS
+gco3D_SetDepthScaleBiasF(
+ IN gco3D Engine,
+ IN gctFLOAT DepthScale,
+ IN gctFLOAT DepthBias
+ );
+
+/* Set depth near and far clipping plane. */
+gceSTATUS
+gco3D_SetDepthPlaneF(
+ IN gco3D Engine,
+ IN gctFLOAT Near,
+ IN gctFLOAT Far
+ );
+
+/* Enable or disable dithering. */
+gceSTATUS
+gco3D_EnableDither(
+ IN gco3D Engine,
+ IN gctBOOL Enable
+ );
+
+/* Set color write enable bits. */
+gceSTATUS
+gco3D_SetColorWrite(
+ IN gco3D Engine,
+ IN gctUINT8 Enable
+ );
+
+/* Set color write enable bits for separate rt control */
+gceSTATUS
+gco3D_SetColorWriteIndexed(
+ IN gco3D Engine,
+ IN gctUINT Index,
+ IN gctUINT8 Enable
+ );
+
+/* Enable or disable early depth. */
+gceSTATUS
+gco3D_SetEarlyDepth(
+ IN gco3D Engine,
+ IN gctBOOL Enable
+ );
+
+/* Deprecated: Enable or disable all early depth operations. */
+gceSTATUS
+gco3D_SetAllEarlyDepthModes(
+ IN gco3D Engine,
+ IN gctBOOL Disable
+ );
+
+
+gceSTATUS
+gco3D_SetEarlyDepthFromAPP(
+ IN gco3D Engine,
+ IN gctBOOL EarlyDepthFromAPP
+ );
+
+gceSTATUS
+gco3D_SetRADepthWrite(
+ IN gco3D Engine,
+ IN gctBOOL Disable,
+ IN gctBOOL psReadZ,
+ IN gctBOOL psReadW
+ );
+
+gceSTATUS
+gco3D_SetPatchVertices(
+ IN gco3D Engine,
+ IN gctINT PatchVertices
+ );
+
+
+/* Switch dynamic early mode */
+gceSTATUS
+gco3D_SwitchDynamicEarlyDepthMode(
+ IN gco3D Engine
+ );
+
+/* Set dynamic early mode */
+gceSTATUS
+gco3D_DisableDynamicEarlyDepthMode(
+ IN gco3D Engine,
+ IN gctBOOL Disable
+ );
+
+/* Enable or disable depth-only mode. */
+gceSTATUS
+gco3D_SetDepthOnly(
+ IN gco3D Engine,
+ IN gctBOOL Enable
+ );
+
+typedef struct _gcsSTENCIL_INFO * gcsSTENCIL_INFO_PTR;
+typedef struct _gcsSTENCIL_INFO
+{
+ gceSTENCIL_MODE mode;
+
+ gctUINT8 maskFront;
+ gctUINT8 maskBack;
+ gctUINT8 writeMaskFront;
+ gctUINT8 writeMaskBack;
+
+ gctUINT8 referenceFront;
+
+ gceCOMPARE compareFront;
+ gceSTENCIL_OPERATION passFront;
+ gceSTENCIL_OPERATION failFront;
+ gceSTENCIL_OPERATION depthFailFront;
+
+ gctUINT8 referenceBack;
+ gceCOMPARE compareBack;
+ gceSTENCIL_OPERATION passBack;
+ gceSTENCIL_OPERATION failBack;
+ gceSTENCIL_OPERATION depthFailBack;
+}
+gcsSTENCIL_INFO;
+
+/* Set stencil mode. */
+gceSTATUS
+gco3D_SetStencilMode(
+ IN gco3D Engine,
+ IN gceSTENCIL_MODE Mode
+ );
+
+/* Set stencil mask. */
+gceSTATUS
+gco3D_SetStencilMask(
+ IN gco3D Engine,
+ IN gctUINT8 Mask
+ );
+
+/* Set stencil back mask. */
+gceSTATUS
+gco3D_SetStencilMaskBack(
+ IN gco3D Engine,
+ IN gctUINT8 Mask
+ );
+
+/* Set stencil write mask. */
+gceSTATUS
+gco3D_SetStencilWriteMask(
+ IN gco3D Engine,
+ IN gctUINT8 Mask
+ );
+
+/* Set stencil back write mask. */
+gceSTATUS
+gco3D_SetStencilWriteMaskBack(
+ IN gco3D Engine,
+ IN gctUINT8 Mask
+ );
+
+/* Set stencil reference. */
+gceSTATUS
+gco3D_SetStencilReference(
+ IN gco3D Engine,
+ IN gctUINT8 Reference,
+ IN gctBOOL Front
+ );
+
+/* Set stencil compare. */
+gceSTATUS
+gco3D_SetStencilCompare(
+ IN gco3D Engine,
+ IN gceSTENCIL_WHERE Where,
+ IN gceCOMPARE Compare
+ );
+
+/* Set stencil operation on pass. */
+gceSTATUS
+gco3D_SetStencilPass(
+ IN gco3D Engine,
+ IN gceSTENCIL_WHERE Where,
+ IN gceSTENCIL_OPERATION Operation
+ );
+
+/* Set stencil operation on fail. */
+gceSTATUS
+gco3D_SetStencilFail(
+ IN gco3D Engine,
+ IN gceSTENCIL_WHERE Where,
+ IN gceSTENCIL_OPERATION Operation
+ );
+
+/* Set stencil operation on depth fail. */
+gceSTATUS
+gco3D_SetStencilDepthFail(
+ IN gco3D Engine,
+ IN gceSTENCIL_WHERE Where,
+ IN gceSTENCIL_OPERATION Operation
+ );
+
+/* Set all stencil states in one blow. */
+gceSTATUS
+gco3D_SetStencilAll(
+ IN gco3D Engine,
+ IN gcsSTENCIL_INFO_PTR Info
+ );
+
+typedef struct _gcsALPHA_INFO * gcsALPHA_INFO_PTR;
+typedef struct _gcsALPHA_INFO
+{
+ /* Alpha test states. */
+ gctBOOL test;
+ gceCOMPARE compare;
+ gctUINT8 reference;
+ gctFLOAT floatReference;
+
+ /* Alpha blending states. */
+ gctBOOL blend[gcdMAX_DRAW_BUFFERS];
+
+ gceBLEND_FUNCTION srcFuncColor[gcdMAX_DRAW_BUFFERS];
+ gceBLEND_FUNCTION srcFuncAlpha[gcdMAX_DRAW_BUFFERS];
+ gceBLEND_FUNCTION trgFuncColor[gcdMAX_DRAW_BUFFERS];
+ gceBLEND_FUNCTION trgFuncAlpha[gcdMAX_DRAW_BUFFERS];
+
+ gceBLEND_MODE modeColor[gcdMAX_DRAW_BUFFERS];
+ gceBLEND_MODE modeAlpha[gcdMAX_DRAW_BUFFERS];
+
+ gctUINT32 color;
+
+ gctBOOL anyBlendEnabled;
+}
+gcsALPHA_INFO;
+
+
+/* Enable or disable alpha test. */
+gceSTATUS
+gco3D_SetAlphaTest(
+ IN gco3D Engine,
+ IN gctBOOL Enable
+ );
+
+/* Set alpha test compare. */
+gceSTATUS
+gco3D_SetAlphaCompare(
+ IN gco3D Engine,
+ IN gceCOMPARE Compare
+ );
+
+/* Set alpha test reference in unsigned integer. */
+gceSTATUS
+gco3D_SetAlphaReference(
+ IN gco3D Engine,
+ IN gctUINT8 Reference,
+ IN gctFLOAT FloatReference
+ );
+
+/* Set alpha test reference in fixed point. */
+gceSTATUS
+gco3D_SetAlphaReferenceX(
+ IN gco3D Engine,
+ IN gctFIXED_POINT Reference
+ );
+
+/* Set alpha test reference in floating point. */
+gceSTATUS
+gco3D_SetAlphaReferenceF(
+ IN gco3D Engine,
+ IN gctFLOAT Reference
+ );
+
+#if gcdALPHA_KILL_IN_SHADER
+gceSTATUS
+gco3D_SetAlphaKill(
+ IN gco3D Engine,
+ IN gctBOOL AlphaKill,
+ IN gctBOOL ColorKill
+ );
+#endif
+
+/* Enable/Disable anti-alias line. */
+gceSTATUS
+gco3D_SetAntiAliasLine(
+ IN gco3D Engine,
+ IN gctBOOL Enable
+ );
+
+/* Set texture slot for anti-alias line. */
+gceSTATUS
+gco3D_SetAALineTexSlot(
+ IN gco3D Engine,
+ IN gctUINT TexSlot
+ );
+
+/* Set anti-alias line width scale. */
+gceSTATUS
+gco3D_SetAALineWidth(
+ IN gco3D Engine,
+ IN gctFLOAT Width
+ );
+
+/* Draw a number of primitives. */
+gceSTATUS
+gco3D_DrawPrimitives(
+ IN gco3D Engine,
+ IN gcePRIMITIVE Type,
+ IN gctSIZE_T StartVertex,
+ IN gctSIZE_T PrimitiveCount
+ );
+
+gceSTATUS
+gco3D_DrawIndirectPrimitives(
+ IN gco3D Engine,
+ IN gcePRIMITIVE Type,
+ IN gctBOOL DrawIndex,
+ IN gctINT BaseOffset,
+ IN gcoBUFOBJ BufObj
+ );
+
+gceSTATUS
+gco3D_MultiDrawIndirectPrimitives(
+ IN gco3D Engine,
+ IN gcePRIMITIVE Type,
+ IN gctBOOL DrawIndex,
+ IN gctINT BaseOffset,
+ IN gctINT DrawCount,
+ IN gctINT Stride,
+ IN gcoBUFOBJ BufObj
+ );
+
+gceSTATUS
+gco3D_DrawInstancedPrimitives(
+ IN gco3D Engine,
+ IN gcePRIMITIVE Type,
+ IN gctBOOL DrawIndex,
+ IN gctINT StartVertex,
+ IN gctSIZE_T StartIndex,
+ IN gctSIZE_T PrimitiveCount,
+ IN gctSIZE_T VertexCount,
+ IN gctSIZE_T InstanceCount
+ );
+
+gceSTATUS
+gco3D_DrawNullPrimitives(
+ IN gco3D Engine
+ );
+
+gceSTATUS
+gco3D_DrawPrimitivesCount(
+ IN gco3D Engine,
+ IN gcePRIMITIVE Type,
+ IN gctINT* StartVertex,
+ IN gctSIZE_T* VertexCount,
+ IN gctSIZE_T PrimitiveCount
+ );
+
+
+/* Draw a number of primitives using offsets. */
+gceSTATUS
+gco3D_DrawPrimitivesOffset(
+ IN gco3D Engine,
+ IN gcePRIMITIVE Type,
+ IN gctINT32 StartOffset,
+ IN gctSIZE_T PrimitiveCount
+ );
+
+/* Draw a number of indexed primitives. */
+gceSTATUS
+gco3D_DrawIndexedPrimitives(
+ IN gco3D Engine,
+ IN gcePRIMITIVE Type,
+ IN gctSIZE_T BaseVertex,
+ IN gctSIZE_T StartIndex,
+ IN gctSIZE_T PrimitiveCount
+ );
+
+/* Draw a number of indexed primitives using offsets. */
+gceSTATUS
+gco3D_DrawIndexedPrimitivesOffset(
+ IN gco3D Engine,
+ IN gcePRIMITIVE Type,
+ IN gctINT32 BaseOffset,
+ IN gctINT32 StartOffset,
+ IN gctSIZE_T PrimitiveCount
+ );
+
+/* Draw a element from pattern */
+gceSTATUS
+gco3D_DrawPattern(
+ IN gco3D Engine,
+ IN gcsFAST_FLUSH_PTR FastFlushInfo
+ );
+
+/* Enable or disable anti-aliasing. */
+gceSTATUS
+gco3D_SetAntiAlias(
+ IN gco3D Engine,
+ IN gctBOOL Enable
+ );
+
+/* Set msaa samples */
+gceSTATUS
+gco3D_SetSamples(
+ IN gco3D Engine,
+ IN gctUINT32 Samples
+ );
+
+
+/* Write data into the command buffer. */
+gceSTATUS
+gco3D_WriteBuffer(
+ IN gco3D Engine,
+ IN gctCONST_POINTER Data,
+ IN gctSIZE_T Bytes,
+ IN gctBOOL Aligned
+ );
+
+/* Send sempahore and stall until sempahore is signalled. */
+gceSTATUS
+gco3D_Semaphore(
+ IN gco3D Engine,
+ IN gceWHERE From,
+ IN gceWHERE To,
+ IN gceHOW How);
+
+
+/* Explicitly flush shader L1 cache */
+gceSTATUS
+gco3D_FlushSHL1Cache(
+ IN gco3D Engine
+ );
+
+/* Set the subpixels center. */
+gceSTATUS
+gco3D_SetCentroids(
+ IN gco3D Engine,
+ IN gctUINT32 Index,
+ IN gctPOINTER Centroids
+ );
+
+/* query msaa sample coordinates */
+gceSTATUS
+gco3D_GetSampleCoords(
+ IN gco3D Engine,
+ IN gctUINT32 SampleIndex,
+ IN gctBOOL yInverted,
+ OUT gctFLOAT_PTR Coords
+ );
+
+gceSTATUS
+gco3D_SetLogicOp(
+ IN gco3D Engine,
+ IN gctUINT8 Rop
+ );
+
+typedef enum _gceXfbCmd
+{
+ gcvXFBCMD_BEGIN = 0,
+ gcvXFBCMD_PAUSE = 1,
+ gcvXFBCMD_RESUME = 2,
+ gcvXFBCMD_END = 3,
+ gcvXFBCMD_PAUSE_INCOMMIT = 4,
+ gcvXFBCMD_RESUME_INCOMMIT = 5,
+ gcvXFBCMD_INVALID = 6,
+}
+gceXfbCmd;
+
+typedef enum _gceXfbStatus
+{
+ gcvXFB_Disabled = 0,
+ gcvXFB_Paused,
+ gcvXFB_Enabled,
+}
+gceXfbStatus;
+
+typedef enum _gceQueryStatus
+{
+ gcvQUERY_Disabled = 0,
+ gcvQUERY_Paused = 1,
+ gcvQUERY_Enabled = 2,
+}
+gceQueryStatus;
+
+typedef enum _gceQueryCmd
+{
+ gcvQUERYCMD_BEGIN = 0,
+ gcvQUERYCMD_PAUSE = 1,
+ gcvQUERYCMD_RESUME = 2,
+ gcvQUERYCMD_END = 3,
+ gcvQUERYCMD_INVALID = 4,
+}
+gceQueryCmd;
+
+typedef enum _gceQueryType
+{
+ gcvQUERY_OCCLUSION = 0,
+ gcvQUERY_XFB_WRITTEN = 1,
+ gcvQUERY_PRIM_GENERATED = 2,
+ gcvQUERY_MAX_NUM = 3,
+}
+gceQueryType;
+
+gceSTATUS
+gco3D_SetQuery(
+ IN gco3D Engine,
+ IN gctUINT32 QueryHeader,
+ IN gceQueryType Type,
+ IN gctBOOL Enable
+ );
+
+gceSTATUS
+gco3D_GetQuery(
+ IN gco3D Engine,
+ IN gceQueryType Type,
+ IN gcsSURF_NODE_PTR Node,
+ IN gctUINT32 Size,
+ IN gctPOINTER Locked,
+ OUT gctINT32 * Index
+ );
+
+gceSTATUS
+gco3D_SetXfbHeader(
+ IN gco3D Engine,
+ IN gctUINT32 Physical
+ );
+
+gceSTATUS
+gco3D_SetXfbBuffer(
+ IN gco3D Engine,
+ IN gctUINT32 Index,
+ IN gctUINT32 BufferAddr,
+ IN gctUINT32 BufferStride,
+ IN gctUINT32 BufferSize
+ );
+
+gceSTATUS
+gco3D_SetXfbCmd(
+ IN gco3D Engine,
+ IN gceXfbCmd Cmd
+ );
+
+gceSTATUS
+gco3D_SetRasterDiscard(
+ IN gco3D Engine,
+ IN gctBOOL Enable
+ );
+
+gceSTATUS
+gco3D_SetColorOutCount(
+ IN gco3D Engine,
+ IN gctUINT32 ColorOutCount
+ );
+
+gceSTATUS
+gco3D_SetColorCacheMode(
+ IN gco3D Engine
+ );
+
+gceSTATUS
+gco3D_Set3DEngine(
+ IN gco3D Engine
+ );
+
+gceSTATUS
+gco3D_UnSet3DEngine(
+ IN gco3D Engine
+ );
+
+gceSTATUS
+gco3D_Get3DEngine(
+ OUT gco3D * Engine
+ );
+
+gceSTATUS
+gco3D_QueryReset(
+ IN gco3D Engine,
+ OUT gctBOOL_PTR Innocent
+ );
+
+/* OCL thread walker information. */
+typedef struct _gcsTHREAD_WALKER_INFO * gcsTHREAD_WALKER_INFO_PTR;
+typedef struct _gcsTHREAD_WALKER_INFO
+{
+ gctUINT32 dimensions;
+ gctUINT32 traverseOrder;
+ gctUINT32 enableSwathX;
+ gctUINT32 enableSwathY;
+ gctUINT32 enableSwathZ;
+ gctUINT32 swathSizeX;
+ gctUINT32 swathSizeY;
+ gctUINT32 swathSizeZ;
+ gctUINT32 valueOrder;
+
+ gctUINT32 globalSizeX;
+ gctUINT32 globalOffsetX;
+ gctUINT32 globalSizeY;
+ gctUINT32 globalOffsetY;
+ gctUINT32 globalSizeZ;
+ gctUINT32 globalOffsetZ;
+
+ gctUINT32 globalScaleX;
+ gctUINT32 globalScaleY;
+ gctUINT32 globalScaleZ;
+
+ gctUINT32 workGroupSizeX;
+ gctUINT32 workGroupCountX;
+ gctUINT32 workGroupSizeY;
+ gctUINT32 workGroupCountY;
+ gctUINT32 workGroupSizeZ;
+ gctUINT32 workGroupCountZ;
+
+ gctUINT32 threadAllocation;
+ gctBOOL barrierUsed;
+
+ gctBOOL indirect;
+ gctUINT32 groupNumberUniformIdx;
+ gctUINT32 baseAddress;
+}
+gcsTHREAD_WALKER_INFO;
+
+#if gcdENABLE_3D && gcdUSE_VX
+/* VX thread walker parameters. */
+typedef struct _gcsVX_THREAD_WALKER_PARAMETERS * gcsVX_THREAD_WALKER_PARAMETERS_PTR;
+
+typedef struct _gcsVX_THREAD_WALKER_PARAMETERS
+{
+ gctUINT32 valueOrder;
+ gctUINT32 workDim;
+
+ gctUINT32 workGroupSizeX;
+ gctUINT32 workGroupCountX;
+
+ gctUINT32 workGroupSizeY;
+ gctUINT32 workGroupCountY;
+
+ gctUINT32 globalOffsetX;
+ gctUINT32 globalScaleX;
+
+ gctUINT32 globalOffsetY;
+ gctUINT32 globalScaleY;
+
+#if gcdVX_OPTIMIZER > 1
+ gctBOOL tileMode;
+#endif
+}
+gcsVX_THREAD_WALKER_PARAMETERS;
+
+typedef struct _gcsVX_IMAGE_INFO * gcsVX_IMAGE_INFO_PTR;
+
+typedef struct _gcsVX_IMAGE_INFO
+{
+ gctUINT32 format;
+ gctUINT32 rect[4];
+ gctUINT32 width;
+ gctUINT32 height;
+
+ /*arraySize, sliceSize is for imageArray / image3D */
+ gctUINT32 arraySize;
+ gctUINT32 sliceSize;
+
+ gctUINT32 bpp;
+ gctUINT32 planes;
+ gctUINT32 componentCount;
+ gctBOOL isFloat;
+
+ gctUINT32 uPixels;
+ gctUINT32 vPixels;
+ gceSURF_FORMAT internalFormat;
+ gctUINT32 border;
+
+ /*vx_imagepatch_addressing_t == (gctUINT32 * 8) */
+ gctUINT32 imagepatch[8 * 3];
+ void *base_addr[3];
+
+ gctUINT32 stride[3];
+
+ gctPOINTER logicals[3];
+ gctUINT32 physicals[3];
+ gctUINT32 bytes;
+
+ gcsSURF_NODE_PTR nodes[3];
+
+ gctBOOL isVXC;
+#if gcdVX_OPTIMIZER
+ gctUINT32 uniformData[3][4];
+#endif
+}
+gcsVX_IMAGE_INFO;
+typedef struct _gcsVX_DISTRIBUTION_INFO * gcsVX_DISTRIBUTION_INFO_PTR;
+
+typedef struct _gcsVX_DISTRIBUTION_INFO
+{
+
+ gctUINT32 logical;
+ gctUINT32 physical;
+ gctUINT32 bytes;
+
+ gcsSURF_NODE_PTR node;
+}
+gcsVX_DISTRIBUTION_INFO;
+#endif
+
+/* Start OCL thread walker. */
+gceSTATUS
+gco3D_InvokeThreadWalker(
+ IN gco3D Engine,
+ IN gcsTHREAD_WALKER_INFO_PTR Info
+ );
+
+gceSTATUS
+gco3D_GetClosestRenderFormat(
+ IN gco3D Engine,
+ IN gceSURF_FORMAT InFormat,
+ OUT gceSURF_FORMAT* OutFormat
+ );
+
+/* Set w clip and w plane limit value. */
+gceSTATUS
+gco3D_SetWClipEnable(
+ IN gco3D Engine,
+ IN gctBOOL Enable
+ );
+
+gceSTATUS
+gco3D_GetWClipEnable(
+ IN gco3D Engine,
+ OUT gctBOOL * Enable
+ );
+
+gceSTATUS
+gco3D_SetWPlaneLimitF(
+ IN gco3D Engine,
+ IN gctFLOAT Value
+ );
+
+gceSTATUS
+gco3D_SetWPlaneLimitX(
+ IN gco3D Engine,
+ IN gctFIXED_POINT Value
+ );
+
+gceSTATUS
+gco3D_SetWPlaneLimit(
+ IN gco3D Engine,
+ IN gctFLOAT Value
+ );
+
+gceSTATUS
+gco3D_PrimitiveRestart(
+ IN gco3D Engine,
+ IN gctBOOL PrimitiveRestart
+ );
+
+gceSTATUS
+gco3D_LoadProgram(
+ IN gco3D Engine,
+ IN gcePROGRAM_STAGE_BIT StageBits,
+ IN gctPOINTER ProgramState
+ );
+
+gceSTATUS
+gco3D_EnableAlphaToCoverage(
+ IN gco3D Engine,
+ IN gctBOOL Enable
+ );
+
+gceSTATUS
+gco3D_EnableSampleCoverage(
+ IN gco3D Engine,
+ IN gctBOOL Enable
+ );
+
+gceSTATUS
+gco3D_SetSampleCoverageValue(
+ IN gco3D Engine,
+ IN gctFLOAT CoverageValue,
+ IN gctBOOL Invert
+ );
+
+gceSTATUS
+gco3D_EnableSampleMask(
+ IN gco3D Engine,
+ IN gctBOOL Enable
+ );
+
+gceSTATUS
+gco3D_SetSampleMask(
+ IN gco3D Engine,
+ IN gctUINT32 SampleMask
+ );
+
+gceSTATUS
+gco3D_EnableSampleShading(
+ IN gco3D Engine,
+ IN gctBOOL Enable
+ );
+
+gceSTATUS
+gco3D_SetMinSampleShadingValue(
+ IN gco3D Engine,
+ IN gctFLOAT MinSampleShadingValue
+ );
+
+gceSTATUS
+gco3D_SetSampleShading(
+ IN gco3D Engine,
+ IN gctBOOL Enable,
+ IN gctBOOL IsSampleIn,
+ IN gctFLOAT SampleShadingValue
+ );
+
+gceSTATUS
+gco3D_EnableSampleMaskOut(
+ IN gco3D Engine,
+ IN gctBOOL Enable,
+ IN gctINT SampleMaskLoc
+ );
+
+/*----------------------------------------------------------------------------*/
+/*-------------------------- gco3D Fragment Processor ------------------------*/
+
+/* Set the fragment processor configuration. */
+gceSTATUS
+gco3D_SetFragmentConfiguration(
+ IN gco3D Engine,
+ IN gctBOOL ColorFromStream,
+ IN gctBOOL EnableFog,
+ IN gctBOOL EnableSmoothPoint,
+ IN gctUINT32 ClipPlanes
+ );
+
+/* Enable/disable texture stage operation. */
+gceSTATUS
+gco3D_EnableTextureStage(
+ IN gco3D Engine,
+ IN gctINT Stage,
+ IN gctBOOL Enable
+ );
+
+/* Program the channel enable masks for the color texture function. */
+gceSTATUS
+gco3D_SetTextureColorMask(
+ IN gco3D Engine,
+ IN gctINT Stage,
+ IN gctBOOL ColorEnabled,
+ IN gctBOOL AlphaEnabled
+ );
+
+/* Program the channel enable masks for the alpha texture function. */
+gceSTATUS
+gco3D_SetTextureAlphaMask(
+ IN gco3D Engine,
+ IN gctINT Stage,
+ IN gctBOOL ColorEnabled,
+ IN gctBOOL AlphaEnabled
+ );
+
+/* Program the constant fragment color. */
+gceSTATUS
+gco3D_SetFragmentColorX(
+ IN gco3D Engine,
+ IN gctFIXED_POINT Red,
+ IN gctFIXED_POINT Green,
+ IN gctFIXED_POINT Blue,
+ IN gctFIXED_POINT Alpha
+ );
+
+gceSTATUS
+gco3D_SetFragmentColorF(
+ IN gco3D Engine,
+ IN gctFLOAT Red,
+ IN gctFLOAT Green,
+ IN gctFLOAT Blue,
+ IN gctFLOAT Alpha
+ );
+
+/* Program the constant fog color. */
+gceSTATUS
+gco3D_SetFogColorX(
+ IN gco3D Engine,
+ IN gctFIXED_POINT Red,
+ IN gctFIXED_POINT Green,
+ IN gctFIXED_POINT Blue,
+ IN gctFIXED_POINT Alpha
+ );
+
+gceSTATUS
+gco3D_SetFogColorF(
+ IN gco3D Engine,
+ IN gctFLOAT Red,
+ IN gctFLOAT Green,
+ IN gctFLOAT Blue,
+ IN gctFLOAT Alpha
+ );
+
+/* Program the constant texture color. */
+gceSTATUS
+gco3D_SetTetxureColorX(
+ IN gco3D Engine,
+ IN gctINT Stage,
+ IN gctFIXED_POINT Red,
+ IN gctFIXED_POINT Green,
+ IN gctFIXED_POINT Blue,
+ IN gctFIXED_POINT Alpha
+ );
+
+gceSTATUS
+gco3D_SetTetxureColorF(
+ IN gco3D Engine,
+ IN gctINT Stage,
+ IN gctFLOAT Red,
+ IN gctFLOAT Green,
+ IN gctFLOAT Blue,
+ IN gctFLOAT Alpha
+ );
+
+/* Configure color texture function. */
+gceSTATUS
+gco3D_SetColorTextureFunction(
+ IN gco3D Engine,
+ IN gctINT Stage,
+ IN gceTEXTURE_FUNCTION Function,
+ IN gceTEXTURE_SOURCE Source0,
+ IN gceTEXTURE_CHANNEL Channel0,
+ IN gceTEXTURE_SOURCE Source1,
+ IN gceTEXTURE_CHANNEL Channel1,
+ IN gceTEXTURE_SOURCE Source2,
+ IN gceTEXTURE_CHANNEL Channel2,
+ IN gctINT Scale
+ );
+
+/* Configure alpha texture function. */
+gceSTATUS
+gco3D_SetAlphaTextureFunction(
+ IN gco3D Engine,
+ IN gctINT Stage,
+ IN gceTEXTURE_FUNCTION Function,
+ IN gceTEXTURE_SOURCE Source0,
+ IN gceTEXTURE_CHANNEL Channel0,
+ IN gceTEXTURE_SOURCE Source1,
+ IN gceTEXTURE_CHANNEL Channel1,
+ IN gceTEXTURE_SOURCE Source2,
+ IN gceTEXTURE_CHANNEL Channel2,
+ IN gctINT Scale
+ );
+
+/******************************************************************************\
+******************************* gcoTEXTURE Object *******************************
+\******************************************************************************/
+
+/* Cube faces. */
+typedef enum _gceTEXTURE_FACE
+{
+ gcvFACE_NONE = 0,
+ gcvFACE_POSITIVE_X,
+ gcvFACE_NEGATIVE_X,
+ gcvFACE_POSITIVE_Y,
+ gcvFACE_NEGATIVE_Y,
+ gcvFACE_POSITIVE_Z,
+ gcvFACE_NEGATIVE_Z,
+}
+gceTEXTURE_FACE;
+
+typedef struct _gcsTEXTURE
+{
+ /* Addressing modes. */
+ gceTEXTURE_ADDRESSING s;
+ gceTEXTURE_ADDRESSING t;
+ gceTEXTURE_ADDRESSING r;
+
+ gceTEXTURE_SWIZZLE swizzle[gcvTEXTURE_COMPONENT_NUM];
+
+ /* Border color. */
+ gctUINT8 border[gcvTEXTURE_COMPONENT_NUM];
+
+ /* Filters. */
+ gceTEXTURE_FILTER minFilter;
+ gceTEXTURE_FILTER magFilter;
+ gceTEXTURE_FILTER mipFilter;
+ gctUINT anisoFilter;
+
+ /* Level of detail. */
+ gctFLOAT lodBias;
+ gctFLOAT lodMin;
+ gctFLOAT lodMax;
+
+ /* base/max level */
+ gctINT32 baseLevel;
+ gctINT32 maxLevel;
+
+ /* depth texture comparison */
+ gceTEXTURE_COMPARE_MODE compareMode;
+ gceCOMPARE compareFunc;
+
+ gceTEXTURE_DS_MODE dsMode;
+
+ /* sRGB decode */
+ gceTEXTURE_SRGBDECODE sRGB;
+
+ gcuVALUE borderColor[4];
+}
+gcsTEXTURE, * gcsTEXTURE_PTR;
+
+typedef struct _gcsTEXTURE_BINDTEXTS_ARGS
+{
+ /* must be the first member */
+ gceHAL_ARG_VERSION version;
+
+}
+gcsTEXTURE_BINDTEXTS_ARGS;
+
+/* Construct a new gcoTEXTURE object. */
+gceSTATUS
+gcoTEXTURE_Construct(
+ IN gcoHAL Hal,
+ OUT gcoTEXTURE * Texture
+ );
+
+/* Construct a new gcoTEXTURE object with type information. */
+gceSTATUS
+gcoTEXTURE_ConstructEx(
+ IN gcoHAL Hal,
+ IN gceTEXTURE_TYPE Type,
+ OUT gcoTEXTURE * Texture
+ );
+
+
+/* Construct a new sized gcoTEXTURE object. */
+gceSTATUS
+gcoTEXTURE_ConstructSized(
+ IN gcoHAL Hal,
+ IN gceSURF_FORMAT Format,
+ IN gctUINT Width,
+ IN gctUINT Height,
+ IN gctUINT Depth,
+ IN gctUINT Faces,
+ IN gctUINT MipMapCount,
+ IN gcePOOL Pool,
+ OUT gcoTEXTURE * Texture
+ );
+
+/* Destroy an gcoTEXTURE object. */
+gceSTATUS
+gcoTEXTURE_Destroy(
+ IN gcoTEXTURE Texture
+ );
+
+/* Upload data to an gcoTEXTURE object. */
+gceSTATUS
+gcoTEXTURE_Upload(
+ IN gcoTEXTURE Texture,
+ IN gctINT MipMap,
+ IN gceTEXTURE_FACE Face,
+ IN gctSIZE_T Width,
+ IN gctSIZE_T Height,
+ IN gctUINT Slice,
+ IN gctCONST_POINTER Memory,
+ IN gctSIZE_T Stride,
+ IN gceSURF_FORMAT Format,
+ IN gceSURF_COLOR_SPACE SrcColorSpace
+ );
+
+/* Upload data to an gcoTEXTURE object. */
+gceSTATUS
+gcoTEXTURE_UploadSub(
+ IN gcoTEXTURE Texture,
+ IN gctINT MipMap,
+ IN gceTEXTURE_FACE Face,
+ IN gctSIZE_T X,
+ IN gctSIZE_T Y,
+ IN gctSIZE_T Width,
+ IN gctSIZE_T Height,
+ IN gctUINT Slice,
+ IN gctCONST_POINTER Memory,
+ IN gctSIZE_T Stride,
+ IN gceSURF_FORMAT Format,
+ IN gceSURF_COLOR_SPACE SrcColorSpace,
+ IN gctUINT32 PhysicalAddress
+ );
+
+
+/* Upload YUV data to an gcoTEXTURE object. */
+gceSTATUS
+gcoTEXTURE_UploadYUV(
+ IN gcoTEXTURE Texture,
+ IN gceTEXTURE_FACE Face,
+ IN gctUINT Width,
+ IN gctUINT Height,
+ IN gctUINT Slice,
+ IN gctPOINTER Memory[3],
+ IN gctINT Stride[3],
+ IN gceSURF_FORMAT Format
+ );
+
+/* Upload compressed data to an gcoTEXTURE object. */
+gceSTATUS
+gcoTEXTURE_UploadCompressed(
+ IN gcoTEXTURE Texture,
+ IN gctINT MipMap,
+ IN gceTEXTURE_FACE Face,
+ IN gctSIZE_T Width,
+ IN gctSIZE_T Height,
+ IN gctUINT Slice,
+ IN gctCONST_POINTER Memory,
+ IN gctSIZE_T Bytes
+ );
+
+/* Upload compressed sub data to an gcoTEXTURE object. */
+gceSTATUS
+gcoTEXTURE_UploadCompressedSub(
+ IN gcoTEXTURE Texture,
+ IN gctINT MipMap,
+ IN gceTEXTURE_FACE Face,
+ IN gctSIZE_T XOffset,
+ IN gctSIZE_T YOffset,
+ IN gctSIZE_T Width,
+ IN gctSIZE_T Height,
+ IN gctUINT Slice,
+ IN gctCONST_POINTER Memory,
+ IN gctSIZE_T Size
+ );
+
+/* Get gcoSURF object for a mipmap level. */
+gceSTATUS
+gcoTEXTURE_GetMipMap(
+ IN gcoTEXTURE Texture,
+ IN gctUINT MipMap,
+ OUT gcoSURF * Surface
+ );
+
+/* Get gcoSURF object for a mipmap level and face offset. */
+gceSTATUS
+gcoTEXTURE_GetMipMapFace(
+ IN gcoTEXTURE Texture,
+ IN gctUINT MipMap,
+ IN gceTEXTURE_FACE Face,
+ OUT gcoSURF * Surface,
+ OUT gctSIZE_T_PTR Offset
+ );
+
+gceSTATUS
+gcoTEXTURE_GetMipMapSlice(
+ IN gcoTEXTURE Texture,
+ IN gctUINT MipMap,
+ IN gctUINT Slice,
+ OUT gcoSURF * Surface,
+ OUT gctSIZE_T_PTR Offset
+ );
+
+gceSTATUS
+gcoTEXTURE_AddMipMap(
+ IN gcoTEXTURE Texture,
+ IN gctINT Level,
+ IN gctINT InternalFormat,
+ IN gceSURF_FORMAT Format,
+ IN gctSIZE_T Width,
+ IN gctSIZE_T Height,
+ IN gctSIZE_T Depth,
+ IN gctUINT Faces,
+ IN gcePOOL Pool,
+ IN gctBOOL Filterable,
+ OUT gcoSURF * Surface
+ );
+
+gceSTATUS
+gcoTEXTURE_AddMipMapEx(
+ IN gcoTEXTURE Texture,
+ IN gctINT Level,
+ IN gctINT InternalFormat,
+ IN gceSURF_FORMAT Format,
+ IN gctSIZE_T Width,
+ IN gctSIZE_T Height,
+ IN gctSIZE_T Depth,
+ IN gctUINT Faces,
+ IN gcePOOL Pool,
+ IN gctUINT32 Samples,
+ IN gctBOOL Protected,
+ IN gctBOOL Filterable,
+ OUT gcoSURF * Surface
+ );
+
+gceSTATUS
+gcoTEXTURE_AddMipMapFromClient(
+ IN gcoTEXTURE Texture,
+ IN gctINT Level,
+ IN gcoSURF Surface
+ );
+
+gceSTATUS
+gcoTEXTURE_AddMipMapFromSurface(
+ IN gcoTEXTURE Texture,
+ IN gctINT Level,
+ IN gcoSURF Surface
+ );
+
+gceSTATUS
+gcoTEXTURE_LockMipMap(
+ IN gcoTEXTURE Texture,
+ IN gctUINT MipMap,
+ OPTIONAL OUT gctUINT32 * Address,
+ OPTIONAL OUT gctPOINTER * Memory
+ );
+
+gceSTATUS
+gcoTEXTURE_SetEndianHint(
+ IN gcoTEXTURE Texture,
+ IN gceENDIAN_HINT EndianHint
+ );
+
+gceSTATUS
+gcoTEXTURE_Disable(
+ IN gcoHAL Hal,
+ IN gctINT Sampler,
+ IN gctBOOL DefaultInteger
+ );
+
+gceSTATUS
+gcoTEXTURE_Flush(
+ IN gcoTEXTURE Texture
+ );
+
+gceSTATUS
+gcoTEXTURE_FlushVS(
+ IN gcoTEXTURE Texture
+ );
+
+gceSTATUS
+gcoTEXTURE_QueryCaps(
+ IN gcoHAL Hal,
+ OUT gctUINT * MaxWidth,
+ OUT gctUINT * MaxHeight,
+ OUT gctUINT * MaxDepth,
+ OUT gctBOOL * Cubic,
+ OUT gctBOOL * NonPowerOfTwo,
+ OUT gctUINT * VertexSamplers,
+ OUT gctUINT * PixelSamplers
+ );
+
+gceSTATUS
+gcoTEXTURE_GetClosestFormat(
+ IN gcoHAL Hal,
+ IN gceSURF_FORMAT InFormat,
+ OUT gceSURF_FORMAT* OutFormat
+ );
+
+gceSTATUS
+gcoTEXTURE_GetClosestFormatEx(
+ IN gcoHAL Hal,
+ IN gceSURF_FORMAT InFormat,
+ IN gceTEXTURE_TYPE TextureType,
+ OUT gceSURF_FORMAT* OutFormat
+ );
+
+gceSTATUS
+gcoTEXTURE_GetFormatInfo(
+ IN gcoTEXTURE Texture,
+ IN gctINT preferLevel,
+ OUT gcsSURF_FORMAT_INFO_PTR * TxFormatInfo
+ );
+
+gceSTATUS
+gcoTEXTURE_GetTextureFormatName(
+ IN gcsSURF_FORMAT_INFO_PTR TxFormatInfo,
+ OUT gctCONST_STRING * TxName
+ );
+
+gceSTATUS
+gcoTEXTURE_RenderIntoMipMap(
+ IN gcoTEXTURE Texture,
+ IN gctINT Level
+ );
+
+gceSTATUS
+gcoTEXTURE_RenderIntoMipMap2(
+ IN gcoTEXTURE Texture,
+ IN gctINT Level,
+ IN gctBOOL Sync
+ );
+
+gceSTATUS
+gcoTEXTURE_IsRenderable(
+ IN gcoTEXTURE Texture,
+ IN gctUINT Level
+ );
+
+gceSTATUS
+gcoTEXTURE_IsComplete(
+ IN gcoTEXTURE Texture,
+ IN gcsTEXTURE_PTR Info,
+ IN gctINT BaseLevel,
+ IN gctINT MaxLevel
+ );
+
+gceSTATUS
+gcoTEXTURE_CheckTexLevel0Attrib(
+ IN gcoTEXTURE Texture,
+ IN gctINT MaxLevel,
+ IN gctINT usedLevel
+ );
+
+gceSTATUS
+gcoTEXTURE_BindTexture(
+ IN gcoTEXTURE Texture,
+ IN gctINT Target,
+ IN gctINT Sampler,
+ IN gcsTEXTURE_PTR Info
+ );
+
+gceSTATUS
+gcoTEXTURE_BindTextureEx(
+ IN gcoTEXTURE Texture,
+ IN gctINT Target,
+ IN gctINT Sampler,
+ IN gcsTEXTURE_PTR Info,
+ IN gctINT textureLayer
+ );
+
+gceSTATUS
+gcoTEXTURE_BindTextureDesc(
+ IN gcoTEXTURE Texture,
+ IN gctINT Sampler,
+ IN gcsTEXTURE_PTR Info,
+ IN gctINT TextureLayer
+ );
+
+gceSTATUS
+gcoTEXTURE_SetDescDirty(
+ IN gcoTEXTURE Texture
+ );
+
+gceSTATUS
+gcoTEXTURE_InitParams(
+ IN gcoHAL Hal,
+ IN gcsTEXTURE_PTR TexParams
+ );
+
+gceSTATUS
+gcoTEXTURE_SetDepthTextureFlag(
+ IN gcoTEXTURE Texture,
+ IN gctBOOL unsized
+ );
+
+gceSTATUS
+gcoTEXTURE_BindTextureTS(
+ IN gcsTEXTURE_BINDTEXTS_ARGS * args
+ );
+
+gceSTATUS
+gcoTEXTURE_GenerateMipMap(
+ IN gcoTEXTURE Texture,
+ IN gctINT BaseLevel,
+ IN gctINT MaxLevel,
+ IN gctBOOL sRGBDecode
+ );
+
+/******************************************************************************\
+******************************* gcoSTREAM Object ******************************
+\******************************************************************************/
+
+typedef enum _gceVERTEX_FORMAT
+{
+ gcvVERTEX_BYTE,
+ gcvVERTEX_UNSIGNED_BYTE,
+ gcvVERTEX_SHORT,
+ gcvVERTEX_UNSIGNED_SHORT,
+ gcvVERTEX_INT,
+ gcvVERTEX_UNSIGNED_INT,
+ gcvVERTEX_FIXED,
+ gcvVERTEX_HALF,
+ gcvVERTEX_FLOAT,
+ gcvVERTEX_UNSIGNED_INT_10_10_10_2,
+ gcvVERTEX_INT_10_10_10_2,
+ gcvVERTEX_UNSIGNED_INT_2_10_10_10_REV,
+ gcvVERTEX_INT_2_10_10_10_REV,
+ /* integer format */
+ gcvVERTEX_INT8,
+ gcvVERTEX_INT16,
+ gcvVERTEX_INT32,
+}
+gceVERTEX_FORMAT;
+
+/* What the SW converting scheme to create temp attrib */
+typedef enum _gceATTRIB_SCHEME
+{
+ gcvATTRIB_SCHEME_KEEP = 0,
+ gcvATTRIB_SCHEME_2_10_10_10_REV_TO_FLOAT,
+ gcvATTRIB_SCHEME_BYTE_TO_IVEC4,
+ gcvATTRIB_SCHEME_SHORT_TO_IVEC4,
+ gcvATTRIB_SCHEME_INT_TO_IVEC4,
+ gcvATTRIB_SCHEME_UBYTE_TO_UVEC4,
+ gcvATTRIB_SCHEME_USHORT_TO_UVEC4,
+ gcvATTRIB_SCHEME_UINT_TO_UVEC4,
+} gceATTRIB_SCHEME;
+
+gceSTATUS
+gcoSTREAM_Construct(
+ IN gcoHAL Hal,
+ OUT gcoSTREAM * Stream
+ );
+
+gceSTATUS
+gcoSTREAM_Destroy(
+ IN gcoSTREAM Stream
+ );
+
+gceSTATUS
+gcoSTREAM_Upload(
+ IN gcoSTREAM Stream,
+ IN gctCONST_POINTER Buffer,
+ IN gctSIZE_T Offset,
+ IN gctSIZE_T Bytes,
+ IN gctBOOL Dynamic
+ );
+
+gceSTATUS
+gcoSTREAM_ReAllocBufNode(
+ IN gcoSTREAM Stream
+ );
+
+gceSTATUS
+gcoSTREAM_SetStride(
+ IN gcoSTREAM Stream,
+ IN gctUINT32 Stride
+ );
+
+gceSTATUS
+gcoSTREAM_Node(
+ IN gcoSTREAM Stream,
+ OUT gcsSURF_NODE_PTR * Node
+ );
+
+gceSTATUS
+gcoSTREAM_Lock(
+ IN gcoSTREAM Stream,
+ OUT gctPOINTER * Logical,
+ OUT gctUINT32 * Physical
+ );
+
+gceSTATUS
+gcoSTREAM_Unlock(
+ IN gcoSTREAM Stream
+ );
+
+gceSTATUS
+gcoSTREAM_Reserve(
+ IN gcoSTREAM Stream,
+ IN gctSIZE_T Bytes
+ );
+
+gceSTATUS
+gcoSTREAM_Flush(
+ IN gcoSTREAM Stream
+ );
+
+typedef struct _gcsSTREAM_INFO
+{
+ gctUINT index;
+ gceVERTEX_FORMAT format;
+ gctBOOL normalized;
+ gctUINT components;
+ gctSIZE_T size;
+ gctCONST_POINTER data;
+ gctUINT stride;
+}
+gcsSTREAM_INFO, * gcsSTREAM_INFO_PTR;
+
+gceSTATUS
+gcoSTREAM_CPUCacheOperation(
+ IN gcoSTREAM Stream,
+ IN gceCACHEOPERATION Operation
+ );
+
+gceSTATUS
+gcoSTREAM_CPUCacheOperation_Range(
+ IN gcoSTREAM Stream,
+ IN gctSIZE_T Offset,
+ IN gctSIZE_T Length,
+ IN gceCACHEOPERATION Operation
+ );
+
+/******************************************************************************\
+******************************** gcoVERTEX Object ******************************
+\******************************************************************************/
+
+typedef struct _gcsVERTEX_ATTRIBUTES
+{
+ gceVERTEX_FORMAT format;
+ gctBOOL normalized;
+ gctUINT32 components;
+ gctSIZE_T size;
+ gctUINT32 stream;
+ gctUINT32 offset;
+ gctUINT32 stride;
+}
+gcsVERTEX_ATTRIBUTES;
+
+gceSTATUS
+gcoVERTEX_Construct(
+ IN gcoHAL Hal,
+ OUT gcoVERTEX * Vertex
+ );
+
+gceSTATUS
+gcoVERTEX_Destroy(
+ IN gcoVERTEX Vertex
+ );
+
+gceSTATUS
+gcoVERTEX_Reset(
+ IN gcoVERTEX Vertex
+ );
+
+gceSTATUS
+gcoVERTEX_EnableAttribute(
+ IN gcoVERTEX Vertex,
+ IN gctUINT32 Index,
+ IN gceVERTEX_FORMAT Format,
+ IN gctBOOL Normalized,
+ IN gctUINT32 Components,
+ IN gcoSTREAM Stream,
+ IN gctUINT32 Offset,
+ IN gctUINT32 Stride
+ );
+
+gceSTATUS
+gcoVERTEX_DisableAttribute(
+ IN gcoVERTEX Vertex,
+ IN gctUINT32 Index
+ );
+
+gceSTATUS
+gcoVERTEX_Bind(
+ IN gcoVERTEX Vertex
+ );
+
+/*******************************************************************************
+***** gcoVERTEXARRAY Object ***************************************************/
+
+typedef struct _gcsATTRIBUTE
+{
+ /* Enabled. */
+ gctBOOL enable;
+
+ /* Number of components. */
+ gctINT size;
+
+ /* Attribute format. */
+ gceVERTEX_FORMAT format;
+
+ /* Flag whether the attribute is normalized or not. */
+ gctBOOL normalized;
+
+ /* Stride of the component. */
+ gctSIZE_T stride;
+
+ /* Divisor of the attribute */
+ gctUINT divisor;
+
+ /* Pointer to the attribute data. */
+ gctCONST_POINTER pointer;
+
+ /* Stream object owning the attribute data. */
+ gcoBUFOBJ stream;
+
+ /* Generic values for attribute. */
+ gctFLOAT genericValue[4];
+
+ /* Generic size for attribute. */
+ gctINT genericSize;
+
+ /* Vertex shader linkage. */
+ gctUINT linkage;
+
+#if gcdUSE_WCLIP_PATCH
+ /* Does it hold positions? */
+ gctBOOL isPosition;
+#endif
+
+ /* Index to vertex array */
+ gctINT arrayIdx;
+
+ gceATTRIB_SCHEME convertScheme;
+
+ /* Pointer to the temporary buffer to be freed */
+ gcoBUFOBJ tempStream;
+
+ /* Pointer to the temporary memory to be freed */
+ gctCONST_POINTER tempMemory;
+}
+gcsATTRIBUTE,
+* gcsATTRIBUTE_PTR;
+
+typedef struct _gcsVERTEXARRAY
+{
+ /* Enabled. */
+ gctBOOL enable;
+
+ /* Number of components. */
+ gctINT size;
+
+ /* Attribute format. */
+ gceVERTEX_FORMAT format;
+
+ /* Flag whether the attribute is normalized or not. */
+ gctBOOL normalized;
+
+ /* Stride of the component. */
+ gctUINT stride;
+
+ /* Divisor of the attribute */
+ gctUINT divisor;
+
+ /* Pointer to the attribute data. */
+ gctCONST_POINTER pointer;
+
+ /* Stream object owning the attribute data. */
+ gcoSTREAM stream;
+
+ /* Generic values for attribute. */
+ gctFLOAT genericValue[4];
+
+ /* Generic size for attribute. */
+ gctINT genericSize;
+
+ /* Vertex shader linkage. */
+ gctUINT linkage;
+
+ gctBOOL isPosition;
+}
+gcsVERTEXARRAY,
+* gcsVERTEXARRAY_PTR;
+
+gceSTATUS
+gcoVERTEXARRAY_Construct(
+ IN gcoHAL Hal,
+ OUT gcoVERTEXARRAY * Vertex
+ );
+
+gceSTATUS
+gcoVERTEXARRAY_Destroy(
+ IN gcoVERTEXARRAY Vertex
+ );
+
+/* If don't consider isolation, STREAM_INFO / INDEX_INFO could be
+** include in the struct of instantDraw in chip level.*/
+typedef struct _gcsVERTEXARRAY_STREAM_INFO
+{
+ gctUINT attribMask;
+ gctSIZE_T first;
+ gctSIZE_T count;
+ gcePRIMITIVE primMode;
+ gctSIZE_T primCount;
+ gctINT vertexInstIndex;
+ gctBOOL instanced;
+ gctSIZE_T instanceCount;
+
+ union _gcsVERTEXARRAY_STREAM_INFO_UNION
+ {
+ struct _gcsVERTEXARRAY_STREAM_ES11_INFO
+ {
+ gcsVERTEXARRAY_PTR attributes;
+ }es11;
+
+ struct _gcsVERTEXARRAY_STREAM_ES30_INFO
+ {
+ gcsATTRIBUTE_PTR attributes;
+ }es30;
+ }u;
+}gcsVERTEXARRAY_STREAM_INFO,
+*gcsVERTEXARRAY_STREAM_INFO_PTR;
+
+typedef const struct _gcsVERTEXARRAY_STREAM_INFO* gcsVERTEXARRAY_STREAM_INFO_CONST_PTR;
+
+typedef struct _gcsVERTEXARRAY_INDEX_INFO
+{
+ gctSIZE_T count;
+ gceINDEX_TYPE indexType;
+ gctPOINTER indexMemory;
+
+ union _gcsVERTEXARRAY_INDEX_INFO_UNION
+ {
+ struct _gcsVERTEXARRAY_INDEX_ES11_INFO
+ {
+ gcoINDEX indexBuffer;
+ }es11;
+
+ struct _gcsVERTEXARRAY_INDEX_ES30_INFO
+ {
+ gcoBUFOBJ indexBuffer;
+ }es30;
+ }u;
+}gcsVERTEXARRAY_INDEX_INFO,
+*gcsVERTEXARRAY_INDEX_INFO_PTR;
+
+typedef const struct _gcsVERTEXARRAY_INDEX_INFO* gcsVERTEXARRAY_INDEX_INFO_CONST_PTR;
+
+gceSTATUS
+gcoVERTEXARRAY_IndexBind(
+ IN gcoVERTEXARRAY Vertex,
+ IN gcsVERTEXARRAY_INDEX_INFO_PTR IndexInfo
+ );
+
+gceSTATUS
+gcoVERTEXARRAY_StreamBind(
+ IN gcoVERTEXARRAY Vertex,
+#if gcdUSE_WCLIP_PATCH
+ IN OUT gctFLOAT * WLimitRms,
+ IN OUT gctBOOL * WLimitRmsDirty,
+#endif
+ IN gcsVERTEXARRAY_STREAM_INFO_CONST_PTR StreamInfo,
+ IN gcsVERTEXARRAY_INDEX_INFO_CONST_PTR IndexInfo
+ );
+
+gceSTATUS
+gcoVERTEXARRAY_IndexBind_Ex(
+ IN gcoVERTEXARRAY Vertex,
+ IN OUT gcsVERTEXARRAY_STREAM_INFO_PTR StreamInfo,
+ IN gcsVERTEXARRAY_INDEX_INFO_PTR IndexInfo
+ );
+
+gceSTATUS
+gcoVERTEXARRAY_StreamBind_Ex(
+ IN gcoVERTEXARRAY Vertex,
+#if gcdUSE_WCLIP_PATCH
+ IN OUT gctFLOAT * WLimitRms,
+ IN OUT gctBOOL * WLimitRmsDirty,
+#endif
+ IN OUT gcsVERTEXARRAY_STREAM_INFO_PTR StreamInfo,
+ IN gcsVERTEXARRAY_INDEX_INFO_PTR IndexInfo
+ );
+
+gceSTATUS
+gcoVERTEXARRAY_Bind(
+ IN gcoVERTEXARRAY Vertex,
+ IN gctUINT32 EnableBits,
+ IN gcsVERTEXARRAY_PTR VertexArray,
+ IN gctUINT First,
+ IN gctSIZE_T * Count,
+ IN gceINDEX_TYPE IndexType,
+ IN gcoINDEX IndexObject,
+ IN gctPOINTER IndexMemory,
+ IN OUT gcePRIMITIVE * PrimitiveType,
+#if gcdUSE_WCLIP_PATCH
+ IN OUT gctUINT * PrimitiveCount,
+ IN OUT gctFLOAT * wLimitRms,
+ IN OUT gctBOOL * wLimitDirty
+#else
+ IN OUT gctUINT * PrimitiveCount
+#endif
+ );
+
+/* Frame Database */
+gceSTATUS
+gcoHAL_AddFrameDB(
+ void
+ );
+
+gceSTATUS
+gcoHAL_DumpFrameDB(
+ gctCONST_STRING Filename OPTIONAL
+ );
+
+gceSTATUS
+gcoHAL_InitGPUProfile(
+ void
+ );
+
+gceSTATUS
+gcoHAL_DumpGPUProfile(
+ void
+ );
+
+/******************************************************************************
+**********************gcoBUFOBJ object*****************************************
+*******************************************************************************/
+typedef enum _gceBUFOBJ_TYPE
+{
+ gcvBUFOBJ_TYPE_ARRAY_BUFFER = 1,
+ gcvBUFOBJ_TYPE_ELEMENT_ARRAY_BUFFER = 2,
+ gcvBUFOBJ_TYPE_GENERIC_BUFFER = 100
+
+} gceBUFOBJ_TYPE;
+
+typedef enum _gceBUFOBJ_USAGE
+{
+ gcvBUFOBJ_USAGE_STREAM_DRAW = 1,
+ gcvBUFOBJ_USAGE_STREAM_READ,
+ gcvBUFOBJ_USAGE_STREAM_COPY,
+ gcvBUFOBJ_USAGE_STATIC_DRAW,
+ gcvBUFOBJ_USAGE_STATIC_READ,
+ gcvBUFOBJ_USAGE_STATIC_COPY,
+ gcvBUFOBJ_USAGE_DYNAMIC_DRAW,
+ gcvBUFOBJ_USAGE_DYNAMIC_READ,
+ gcvBUFOBJ_USAGE_DYNAMIC_COPY,
+
+ /* special patch for optimaize performance,
+ ** no fence and duplicate stream to ensure data correct
+ */
+ gcvBUFOBJ_USAGE_DISABLE_FENCE_DYNAMIC_STREAM = 256
+} gceBUFOBJ_USAGE;
+
+/* Construct a new gcoBUFOBJ object. */
+gceSTATUS
+gcoBUFOBJ_Construct(
+ IN gcoHAL Hal,
+ IN gceBUFOBJ_TYPE Type,
+ OUT gcoBUFOBJ * BufObj
+ );
+
+/* Destroy a gcoBUFOBJ object. */
+gceSTATUS
+gcoBUFOBJ_Destroy(
+ IN gcoBUFOBJ BufObj
+ );
+
+/* Lock pbo in memory. */
+gceSTATUS
+gcoBUFOBJ_Lock(
+ IN gcoBUFOBJ BufObj,
+ OUT gctUINT32 * Address,
+ OUT gctPOINTER * Memory
+ );
+
+/* Lock pbo in memory. */
+gceSTATUS
+gcoBUFOBJ_FastLock(
+ IN gcoBUFOBJ BufObj,
+ OUT gctUINT32 * Address,
+ OUT gctPOINTER * Memory
+ );
+
+/* Unlock pbo that was previously locked with gcoBUFOBJ_Lock. */
+gceSTATUS
+gcoBUFOBJ_Unlock(
+ IN gcoBUFOBJ BufObj
+ );
+
+/* Free existing pbo buffer. */
+gceSTATUS
+gcoBUFOBJ_Free(
+ IN gcoBUFOBJ BufObj
+ );
+
+/* Upload data into an pbo buffer. */
+gceSTATUS
+gcoBUFOBJ_Upload(
+ IN gcoBUFOBJ BufObj,
+ IN gctCONST_POINTER Buffer,
+ IN gctSIZE_T Offset,
+ IN gctSIZE_T Bytes,
+ IN gceBUFOBJ_USAGE Usage
+ );
+
+/* Bind an index object to the hardware. */
+gceSTATUS
+gcoBUFOBJ_IndexBind (
+ IN gcoBUFOBJ Index,
+ IN gceINDEX_TYPE Type,
+ IN gctUINT32 Offset,
+ IN gctSIZE_T Count
+ );
+
+/* Find min and max index for the index buffer */
+gceSTATUS
+gcoBUFOBJ_IndexGetRange(
+ IN gcoBUFOBJ Index,
+ IN gceINDEX_TYPE Type,
+ IN gctUINT32 Offset,
+ IN gctUINT32 Count,
+ OUT gctUINT32 * MinimumIndex,
+ OUT gctUINT32 * MaximumIndex
+ );
+
+/* Sets a buffer object as dirty */
+gceSTATUS
+gcoBUFOBJ_SetDirty(
+ IN gcoBUFOBJ BufObj
+ );
+
+/* Creates a new buffer if needed */
+gceSTATUS
+gcoBUFOBJ_AlignIndexBufferWhenNeeded(
+ IN gcoBUFOBJ BufObj,
+ IN gctSIZE_T Offset,
+ OUT gcoBUFOBJ * AlignedBufObj
+ );
+
+/* Cache operations on whole range */
+gceSTATUS
+gcoBUFOBJ_CPUCacheOperation(
+ IN gcoBUFOBJ BufObj,
+ IN gceCACHEOPERATION Operation
+ );
+
+/* Cache operations on a specified range */
+gceSTATUS
+gcoBUFOBJ_CPUCacheOperation_Range(
+ IN gcoBUFOBJ BufObj,
+ IN gctSIZE_T Offset,
+ IN gctSIZE_T Length,
+ IN gceCACHEOPERATION Operation
+ );
+
+/* Return size of the bufobj */
+gceSTATUS
+gcoBUFOBJ_GetSize(
+ IN gcoBUFOBJ BufObj,
+ OUT gctSIZE_T_PTR Size
+ );
+
+/* Return memory node of the bufobj */
+gceSTATUS
+gcoBUFOBJ_GetNode(
+ IN gcoBUFOBJ BufObj,
+ OUT gcsSURF_NODE_PTR * Node
+ );
+
+gceSTATUS
+gcoBUFOBJ_ReAllocBufNode(
+ IN gcoBUFOBJ BufObj
+ );
+
+/* Handle GPU cache operations */
+gceSTATUS
+gcoBUFOBJ_GPUCacheOperation(
+ gcoBUFOBJ BufObj
+ );
+
+/* Dump buffer. */
+void
+gcoBUFOBJ_Dump(
+ IN gcoBUFOBJ BufObj
+ );
+
+#endif /* gcdENABLE_3D */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __gc_hal_engine_h_ */
+
+
diff --git a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_engine_vg.h b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_engine_vg.h
new file mode 100644
index 000000000000..9bbbe05f0101
--- /dev/null
+++ b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_engine_vg.h
@@ -0,0 +1,1320 @@
+/****************************************************************************
+*
+* The MIT License (MIT)
+*
+* Copyright (c) 2014 - 2018 Vivante 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 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 GPL License (GPL)
+*
+* Copyright (C) 2014 - 2018 Vivante 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.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+*****************************************************************************
+*
+* Note: This software is released under dual MIT and GPL licenses. A
+* recipient may use this file under the terms of either the MIT license or
+* GPL License. If you wish to use only one license not the other, you can
+* indicate your decision by deleting one of the above license notices in your
+* version of this file.
+*
+*****************************************************************************/
+
+
+#ifndef __gc_hal_engine_vg_h_
+#define __gc_hal_engine_vg_h_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "gc_hal_types.h"
+
+/******************************************************************************\
+******************************** VG Enumerations *******************************
+\******************************************************************************/
+
+/**
+** @ingroup gcoVG
+**
+** @brief Tiling mode for painting and imagig.
+**
+** This enumeration defines the tiling modes supported by the HAL. This is
+** in fact a one-to-one mapping of the OpenVG 1.1 tile modes.
+*/
+typedef enum _gceTILE_MODE
+{
+ gcvTILE_FILL,
+ gcvTILE_PAD,
+ gcvTILE_REPEAT,
+ gcvTILE_REFLECT
+}
+gceTILE_MODE;
+
+/******************************************************************************/
+/** @ingroup gcoVG
+**
+** @brief The different paint modes.
+**
+** This enumeration lists the available paint modes.
+*/
+typedef enum _gcePAINT_TYPE
+{
+ /** Solid color. */
+ gcvPAINT_MODE_SOLID,
+
+ /** Linear gradient. */
+ gcvPAINT_MODE_LINEAR,
+
+ /** Radial gradient. */
+ gcvPAINT_MODE_RADIAL,
+
+ /** Pattern. */
+ gcvPAINT_MODE_PATTERN,
+
+ /** Mode count. */
+ gcvPAINT_MODE_COUNT
+}
+gcePAINT_TYPE;
+
+/**
+** @ingroup gcoVG
+**
+** @brief Types of path data supported by HAL.
+**
+** This enumeration defines the types of path data supported by the HAL.
+** This is in fact a one-to-one mapping of the OpenVG 1.1 path types.
+*/
+typedef enum _gcePATHTYPE
+{
+ gcePATHTYPE_UNKNOWN = -1,
+ gcePATHTYPE_INT8,
+ gcePATHTYPE_INT16,
+ gcePATHTYPE_INT32,
+ gcePATHTYPE_FLOAT
+}
+gcePATHTYPE;
+
+/**
+** @ingroup gcoVG
+**
+** @brief Supported path segment commands.
+**
+** This enumeration defines the path segment commands supported by the HAL.
+*/
+typedef enum _gceVGCMD
+{
+ gcvVGCMD_END, /* 0: 0x00 */
+ gcvVGCMD_CLOSE, /* 1: 0x01 */
+ gcvVGCMD_MOVE, /* 2: 0x02 */
+ gcvVGCMD_MOVE_REL, /* 3: 0x03 */
+ gcvVGCMD_LINE, /* 4: 0x04 */
+ gcvVGCMD_LINE_REL, /* 5: 0x05 */
+ gcvVGCMD_QUAD, /* 6: 0x06 */
+ gcvVGCMD_QUAD_REL, /* 7: 0x07 */
+ gcvVGCMD_CUBIC, /* 8: 0x08 */
+ gcvVGCMD_CUBIC_REL, /* 9: 0x09 */
+ gcvVGCMD_BREAK, /* 10: 0x0A */
+ gcvVGCMD_HLINE, /* 11: ******* R E S E R V E D *******/
+ gcvVGCMD_HLINE_REL, /* 12: ******* R E S E R V E D *******/
+ gcvVGCMD_VLINE, /* 13: ******* R E S E R V E D *******/
+ gcvVGCMD_VLINE_REL, /* 14: ******* R E S E R V E D *******/
+ gcvVGCMD_SQUAD, /* 15: ******* R E S E R V E D *******/
+ gcvVGCMD_SQUAD_REL, /* 16: ******* R E S E R V E D *******/
+ gcvVGCMD_SCUBIC, /* 17: ******* R E S E R V E D *******/
+ gcvVGCMD_SCUBIC_REL, /* 18: ******* R E S E R V E D *******/
+ gcvVGCMD_SCCWARC, /* 19: ******* R E S E R V E D *******/
+ gcvVGCMD_SCCWARC_REL, /* 20: ******* R E S E R V E D *******/
+ gcvVGCMD_SCWARC, /* 21: ******* R E S E R V E D *******/
+ gcvVGCMD_SCWARC_REL, /* 22: ******* R E S E R V E D *******/
+ gcvVGCMD_LCCWARC, /* 23: ******* R E S E R V E D *******/
+ gcvVGCMD_LCCWARC_REL, /* 24: ******* R E S E R V E D *******/
+ gcvVGCMD_LCWARC, /* 25: ******* R E S E R V E D *******/
+ gcvVGCMD_LCWARC_REL, /* 26: ******* R E S E R V E D *******/
+
+ /* The width of the command recognized by the hardware on bits. */
+ gcvVGCMD_WIDTH = 5,
+
+ /* Hardware command mask. */
+ gcvVGCMD_MASK = (1 << gcvVGCMD_WIDTH) - 1,
+
+ /* Command modifiers. */
+ gcvVGCMD_H_MOD = 1 << gcvVGCMD_WIDTH, /* = 32 */
+ gcvVGCMD_V_MOD = 2 << gcvVGCMD_WIDTH, /* = 64 */
+ gcvVGCMD_S_MOD = 3 << gcvVGCMD_WIDTH, /* = 96 */
+ gcvVGCMD_ARC_MOD = 4 << gcvVGCMD_WIDTH, /* = 128 */
+
+ /* Emulated LINE commands. */
+ gcvVGCMD_HLINE_EMUL = gcvVGCMD_H_MOD | gcvVGCMD_LINE, /* = 36 */
+ gcvVGCMD_HLINE_EMUL_REL = gcvVGCMD_H_MOD | gcvVGCMD_LINE_REL, /* = 37 */
+ gcvVGCMD_VLINE_EMUL = gcvVGCMD_V_MOD | gcvVGCMD_LINE, /* = 68 */
+ gcvVGCMD_VLINE_EMUL_REL = gcvVGCMD_V_MOD | gcvVGCMD_LINE_REL, /* = 69 */
+
+ /* Emulated SMOOTH commands. */
+ gcvVGCMD_SQUAD_EMUL = gcvVGCMD_S_MOD | gcvVGCMD_QUAD, /* = 102 */
+ gcvVGCMD_SQUAD_EMUL_REL = gcvVGCMD_S_MOD | gcvVGCMD_QUAD_REL, /* = 103 */
+ gcvVGCMD_SCUBIC_EMUL = gcvVGCMD_S_MOD | gcvVGCMD_CUBIC, /* = 104 */
+ gcvVGCMD_SCUBIC_EMUL_REL = gcvVGCMD_S_MOD | gcvVGCMD_CUBIC_REL, /* = 105 */
+
+ /* Emulation ARC commands. */
+ gcvVGCMD_ARC_LINE = gcvVGCMD_ARC_MOD | gcvVGCMD_LINE, /* = 132 */
+ gcvVGCMD_ARC_LINE_REL = gcvVGCMD_ARC_MOD | gcvVGCMD_LINE_REL, /* = 133 */
+ gcvVGCMD_ARC_QUAD = gcvVGCMD_ARC_MOD | gcvVGCMD_QUAD, /* = 134 */
+ gcvVGCMD_ARC_QUAD_REL = gcvVGCMD_ARC_MOD | gcvVGCMD_QUAD_REL /* = 135 */
+}
+gceVGCMD;
+typedef enum _gceVGCMD * gceVGCMD_PTR;
+
+/**
+** @ingroup gcoVG
+**
+** @brief Blending modes supported by the HAL.
+**
+** This enumeration defines the blending modes supported by the HAL. This is
+** in fact a one-to-one mapping of the OpenVG 1.1 blending modes.
+*/
+typedef enum _gceVG_BLEND
+{
+ gcvVG_BLEND_SRC,
+ gcvVG_BLEND_SRC_OVER,
+ gcvVG_BLEND_DST_OVER,
+ gcvVG_BLEND_SRC_IN,
+ gcvVG_BLEND_DST_IN,
+ gcvVG_BLEND_MULTIPLY,
+ gcvVG_BLEND_SCREEN,
+ gcvVG_BLEND_DARKEN,
+ gcvVG_BLEND_LIGHTEN,
+ gcvVG_BLEND_ADDITIVE,
+ gcvVG_BLEND_SUBTRACT,
+ gcvVG_BLEND_FILTER
+}
+gceVG_BLEND;
+
+/**
+** @ingroup gcoVG
+**
+** @brief Image modes supported by the HAL.
+**
+** This enumeration defines the image modes supported by the HAL. This is
+** in fact a one-to-one mapping of the OpenVG 1.1 image modes with the addition
+** of NO IMAGE.
+*/
+typedef enum _gceVG_IMAGE
+{
+ gcvVG_IMAGE_NONE,
+ gcvVG_IMAGE_NORMAL,
+ gcvVG_IMAGE_MULTIPLY,
+ gcvVG_IMAGE_STENCIL,
+ gcvVG_IMAGE_FILTER
+}
+gceVG_IMAGE;
+
+/**
+** @ingroup gcoVG
+**
+** @brief Filter mode patterns and imaging.
+**
+** This enumeration defines the filter modes supported by the HAL.
+*/
+typedef enum _gceIMAGE_FILTER
+{
+ gcvFILTER_POINT,
+ gcvFILTER_LINEAR,
+ gcvFILTER_BI_LINEAR
+}
+gceIMAGE_FILTER;
+
+/**
+** @ingroup gcoVG
+**
+** @brief Primitive modes supported by the HAL.
+**
+** This enumeration defines the primitive modes supported by the HAL.
+*/
+typedef enum _gceVG_PRIMITIVE
+{
+ gcvVG_SCANLINE,
+ gcvVG_RECTANGLE,
+ gcvVG_TESSELLATED,
+ gcvVG_TESSELLATED_TILED
+}
+gceVG_PRIMITIVE;
+
+/**
+** @ingroup gcoVG
+**
+** @brief Rendering quality modes supported by the HAL.
+**
+** This enumeration defines the rendering quality modes supported by the HAL.
+*/
+typedef enum _gceRENDER_QUALITY
+{
+ gcvVG_NONANTIALIASED,
+ gcvVG_2X2_MSAA,
+ gcvVG_2X4_MSAA,
+ gcvVG_4X4_MSAA
+}
+gceRENDER_QUALITY;
+
+/**
+** @ingroup gcoVG
+**
+** @brief Fill rules supported by the HAL.
+**
+** This enumeration defines the fill rules supported by the HAL.
+*/
+typedef enum _gceFILL_RULE
+{
+ gcvVG_EVEN_ODD,
+ gcvVG_NON_ZERO
+}
+gceFILL_RULE;
+
+/**
+** @ingroup gcoVG
+**
+** @brief Cap styles supported by the HAL.
+**
+** This enumeration defines the cap styles supported by the HAL.
+*/
+typedef enum _gceCAP_STYLE
+{
+ gcvCAP_BUTT,
+ gcvCAP_ROUND,
+ gcvCAP_SQUARE
+}
+gceCAP_STYLE;
+
+/**
+** @ingroup gcoVG
+**
+** @brief Join styles supported by the HAL.
+**
+** This enumeration defines the join styles supported by the HAL.
+*/
+typedef enum _gceJOIN_STYLE
+{
+ gcvJOIN_MITER,
+ gcvJOIN_ROUND,
+ gcvJOIN_BEVEL
+}
+gceJOIN_STYLE;
+
+/**
+** @ingroup gcoVG
+**
+** @brief Channel mask values.
+**
+** This enumeration defines the values for channel mask used in image
+** filtering.
+*/
+
+/* Base values for channel mask definitions. */
+#define gcvCHANNEL_X (0)
+#define gcvCHANNEL_R (1 << 0)
+#define gcvCHANNEL_G (1 << 1)
+#define gcvCHANNEL_B (1 << 2)
+#define gcvCHANNEL_A (1 << 3)
+
+typedef enum _gceCHANNEL
+{
+ gcvCHANNEL_XXXX = (gcvCHANNEL_X | gcvCHANNEL_X | gcvCHANNEL_X | gcvCHANNEL_X),
+ gcvCHANNEL_XXXA = (gcvCHANNEL_X | gcvCHANNEL_X | gcvCHANNEL_X | gcvCHANNEL_A),
+ gcvCHANNEL_XXBX = (gcvCHANNEL_X | gcvCHANNEL_X | gcvCHANNEL_B | gcvCHANNEL_X),
+ gcvCHANNEL_XXBA = (gcvCHANNEL_X | gcvCHANNEL_X | gcvCHANNEL_B | gcvCHANNEL_A),
+
+ gcvCHANNEL_XGXX = (gcvCHANNEL_X | gcvCHANNEL_G | gcvCHANNEL_X | gcvCHANNEL_X),
+ gcvCHANNEL_XGXA = (gcvCHANNEL_X | gcvCHANNEL_G | gcvCHANNEL_X | gcvCHANNEL_A),
+ gcvCHANNEL_XGBX = (gcvCHANNEL_X | gcvCHANNEL_G | gcvCHANNEL_B | gcvCHANNEL_X),
+ gcvCHANNEL_XGBA = (gcvCHANNEL_X | gcvCHANNEL_G | gcvCHANNEL_B | gcvCHANNEL_A),
+
+ gcvCHANNEL_RXXX = (gcvCHANNEL_R | gcvCHANNEL_X | gcvCHANNEL_X | gcvCHANNEL_X),
+ gcvCHANNEL_RXXA = (gcvCHANNEL_R | gcvCHANNEL_X | gcvCHANNEL_X | gcvCHANNEL_A),
+ gcvCHANNEL_RXBX = (gcvCHANNEL_R | gcvCHANNEL_X | gcvCHANNEL_B | gcvCHANNEL_X),
+ gcvCHANNEL_RXBA = (gcvCHANNEL_R | gcvCHANNEL_X | gcvCHANNEL_B | gcvCHANNEL_A),
+
+ gcvCHANNEL_RGXX = (gcvCHANNEL_R | gcvCHANNEL_G | gcvCHANNEL_X | gcvCHANNEL_X),
+ gcvCHANNEL_RGXA = (gcvCHANNEL_R | gcvCHANNEL_G | gcvCHANNEL_X | gcvCHANNEL_A),
+ gcvCHANNEL_RGBX = (gcvCHANNEL_R | gcvCHANNEL_G | gcvCHANNEL_B | gcvCHANNEL_X),
+ gcvCHANNEL_RGBA = (gcvCHANNEL_R | gcvCHANNEL_G | gcvCHANNEL_B | gcvCHANNEL_A),
+}
+gceCHANNEL;
+
+/******************************************************************************\
+******************************** VG Structures *******************************
+\******************************************************************************/
+
+/**
+** @ingroup gcoVG
+**
+** @brief Definition of the color ramp used by the gradient paints.
+**
+** The gcsCOLOR_RAMP structure defines the layout of one single color inside
+** a color ramp which is used by gradient paints.
+*/
+typedef struct _gcsCOLOR_RAMP
+{
+ /** Value for the color stop. */
+ gctFLOAT stop;
+
+ /** Red color channel value for the color stop. */
+ gctFLOAT red;
+
+ /** Green color channel value for the color stop. */
+ gctFLOAT green;
+
+ /** Blue color channel value for the color stop. */
+ gctFLOAT blue;
+
+ /** Alpha color channel value for the color stop. */
+ gctFLOAT alpha;
+}
+gcsCOLOR_RAMP, * gcsCOLOR_RAMP_PTR;
+
+/**
+** @ingroup gcoVG
+**
+** @brief Definition of the color ramp used by the gradient paints in fixed form.
+**
+** The gcsCOLOR_RAMP structure defines the layout of one single color inside
+** a color ramp which is used by gradient paints.
+*/
+typedef struct _gcsFIXED_COLOR_RAMP
+{
+ /** Value for the color stop. */
+ gctFIXED_POINT stop;
+
+ /** Red color channel value for the color stop. */
+ gctFIXED_POINT red;
+
+ /** Green color channel value for the color stop. */
+ gctFIXED_POINT green;
+
+ /** Blue color channel value for the color stop. */
+ gctFIXED_POINT blue;
+
+ /** Alpha color channel value for the color stop. */
+ gctFIXED_POINT alpha;
+}
+gcsFIXED_COLOR_RAMP, * gcsFIXED_COLOR_RAMP_PTR;
+
+
+/**
+** @ingroup gcoVG
+**
+** @brief Rectangle structure used by the gcoVG object.
+**
+** This structure defines the layout of a rectangle. Make sure width and
+** height are larger than 0.
+*/
+typedef struct _gcsVG_RECT * gcsVG_RECT_PTR;
+typedef struct _gcsVG_RECT
+{
+ /** Left location of the rectangle. */
+ gctINT x;
+
+ /** Top location of the rectangle. */
+ gctINT y;
+
+ /** Width of the rectangle. */
+ gctINT width;
+
+ /** Height of the rectangle. */
+ gctINT height;
+}
+gcsVG_RECT;
+
+/**
+** @ingroup gcoVG
+**
+** @brief Path command buffer attribute structure.
+**
+** The gcsPATH_BUFFER_INFO structure contains the specifics about
+** the layout of the path data command buffer.
+*/
+typedef struct _gcsPATH_BUFFER_INFO * gcsPATH_BUFFER_INFO_PTR;
+typedef struct _gcsPATH_BUFFER_INFO
+{
+ gctUINT reservedForHead;
+ gctUINT reservedForTail;
+}
+gcsPATH_BUFFER_INFO;
+
+/**
+** @ingroup gcoVG
+**
+** @brief Definition of the path data container structure.
+**
+** The gcsPATH structure defines the layout of the path data container.
+*/
+typedef struct _gcsPATH_DATA * gcsPATH_DATA_PTR;
+typedef struct _gcsPATH_DATA
+{
+ /* Data container in command buffer format. */
+ gcsCMDBUFFER data;
+
+ /* Path data type. */
+ gcePATHTYPE dataType;
+}
+gcsPATH_DATA;
+
+
+/******************************************************************************\
+********************************* gcoHAL Object ********************************
+\******************************************************************************/
+
+/* Query path data storage attributes. */
+gceSTATUS
+gcoHAL_QueryPathStorage(
+ IN gcoHAL Hal,
+#if gcdGC355_PROFILER
+ IN gcoVG Vg,
+ IN gctUINT TreeDepth,
+ IN gctUINT saveLayerTreeDepth,
+ IN gctUINT varTreeDepth,
+#endif
+ OUT gcsPATH_BUFFER_INFO_PTR Information
+ );
+
+/* Associate a completion signal with the command buffer. */
+gceSTATUS
+gcoHAL_AssociateCompletion(
+ IN gcoHAL Hal,
+#if gcdGC355_PROFILER
+ IN gcoVG Vg,
+ IN gctUINT TreeDepth,
+ IN gctUINT saveLayerTreeDepth,
+ IN gctUINT varTreeDepth,
+#endif
+ IN gcsPATH_DATA_PTR PathData
+ );
+
+/* Release the current command buffer completion signal. */
+gceSTATUS
+gcoHAL_DeassociateCompletion(
+ IN gcoHAL Hal,
+#if gcdGC355_PROFILER
+ IN gcoVG Vg,
+ IN gctUINT TreeDepth,
+ IN gctUINT saveLayerTreeDepth,
+ IN gctUINT varTreeDepth,
+#endif
+ IN gcsPATH_DATA_PTR PathData
+ );
+
+/* Verify whether the command buffer is still in use. */
+gceSTATUS
+gcoHAL_CheckCompletion(
+ IN gcoHAL Hal,
+#if gcdGC355_PROFILER
+ IN gcoVG Vg,
+ IN gctUINT TreeDepth,
+ IN gctUINT saveLayerTreeDepth,
+ IN gctUINT varTreeDepth,
+#endif
+ IN gcsPATH_DATA_PTR PathData
+ );
+
+/* Wait until the command buffer is no longer in use. */
+gceSTATUS
+gcoHAL_WaitCompletion(
+ IN gcoHAL Hal,
+#if gcdGC355_PROFILER
+ IN gcoVG Vg,
+ IN gctUINT TreeDepth,
+ IN gctUINT saveLayerTreeDepth,
+ IN gctUINT varTreeDepth,
+#endif
+ IN gcsPATH_DATA_PTR PathData
+ );
+
+/* Flush the pixel cache. */
+gceSTATUS
+gcoHAL_Flush(
+#if gcdGC355_PROFILER
+ IN gcoHAL Hal,
+ IN gcoVG Vg,
+ IN gctUINT TreeDepth,
+ IN gctUINT saveLayerTreeDepth,
+ IN gctUINT varTreeDepth
+#else
+ IN gcoHAL Hal
+#endif
+ );
+
+/* Split a harwdare address into pool and offset. */
+gceSTATUS
+gcoHAL_SplitAddress(
+ IN gcoHAL Hal,
+#if gcdGC355_PROFILER
+ IN gcoVG Vg,
+ IN gctUINT TreeDepth,
+ IN gctUINT saveLayerTreeDepth,
+ IN gctUINT varTreeDepth,
+#endif
+ IN gctUINT32 Address,
+ OUT gcePOOL * Pool,
+ OUT gctUINT32 * Offset
+ );
+
+/* Combine pool and offset into a harwdare address. */
+gceSTATUS
+gcoHAL_CombineAddress(
+ IN gcoHAL Hal,
+#if gcdGC355_PROFILER
+ IN gcoVG Vg,
+ IN gctUINT TreeDepth,
+ IN gctUINT saveLayerTreeDepth,
+ IN gctUINT varTreeDepth,
+#endif
+ IN gcePOOL Pool,
+ IN gctUINT32 Offset,
+ OUT gctUINT32 * Address
+ );
+
+/* Schedule to free linear video memory allocated. */
+gceSTATUS
+gcoHAL_ScheduleVideoMemory(
+ IN gcoHAL Hal,
+#if gcdGC355_PROFILER
+ IN gcoVG Vg,
+ IN gctUINT TreeDepth,
+ IN gctUINT saveLayerTreeDepth,
+ IN gctUINT varTreeDepth,
+#endif
+ IN gctUINT32 Node
+ );
+
+/* Free linear video memory allocated with gcoHAL_AllocateLinearVideoMemory. */
+gceSTATUS
+gcoHAL_FreeVideoMemory(
+ IN gcoHAL Hal,
+#if gcdGC355_PROFILER
+ IN gcoVG Vg,
+ IN gctUINT TreeDepth,
+ IN gctUINT saveLayerTreeDepth,
+ IN gctUINT varTreeDepth,
+#endif
+ IN gctUINT32 Node,
+ IN gctBOOL asynchroneous
+ );
+
+/* Query command buffer attributes. */
+gceSTATUS
+gcoHAL_QueryCommandBuffer(
+ IN gcoHAL Hal,
+#if gcdGC355_PROFILER
+ IN gcoVG Vg,
+ IN gctUINT TreeDepth,
+ IN gctUINT saveLayerTreeDepth,
+ IN gctUINT varTreeDepth,
+#endif
+ OUT gcsCOMMAND_BUFFER_INFO_PTR Information
+ );
+/* Allocate and lock linear video memory. */
+gceSTATUS
+gcoHAL_AllocateLinearVideoMemory(
+ IN gcoHAL Hal,
+#if gcdGC355_PROFILER
+ IN gcoVG Vg,
+ IN gctUINT TreeDepth,
+ IN gctUINT saveLayerTreeDepth,
+ IN gctUINT varTreeDepth,
+#endif
+ IN gctUINT Size,
+ IN gctUINT Alignment,
+ IN gcePOOL Pool,
+ OUT gctUINT32 * Node,
+ OUT gctUINT32 * Address,
+ OUT gctPOINTER * Memory
+ );
+
+/* Align the specified size accordingly to the hardware requirements. */
+gceSTATUS
+gcoHAL_GetAlignedSurfaceSize(
+ IN gcoHAL Hal,
+#if gcdGC355_PROFILER
+ IN gcoVG Vg,
+ IN gctUINT TreeDepth,
+ IN gctUINT saveLayerTreeDepth,
+ IN gctUINT varTreeDepth,
+#endif
+ IN gceSURF_TYPE Type,
+ IN OUT gctUINT32_PTR Width,
+ IN OUT gctUINT32_PTR Height
+ );
+
+gceSTATUS
+gcoHAL_ReserveTask(
+ IN gcoHAL Hal,
+#if gcdGC355_PROFILER
+ IN gcoVG Vg,
+ IN gctUINT TreeDepth,
+ IN gctUINT saveLayerTreeDepth,
+ IN gctUINT varTreeDepth,
+#endif
+ IN gceBLOCK Block,
+ IN gctUINT TaskCount,
+ IN gctUINT32 Bytes,
+ OUT gctPOINTER * Memory
+ );
+/******************************************************************************\
+********************************** gcoVG Object ********************************
+\******************************************************************************/
+
+/** @defgroup gcoVG gcoVG
+**
+** The gcoVG object abstracts the VG hardware pipe.
+*/
+#if gcdGC355_PROFILER
+void
+gcoVG_ProfilerEnableDisable(
+ IN gcoVG Vg,
+ IN gctUINT enableGetAPITimes,
+ IN gctFILE apiTimeFile
+ );
+
+void
+gcoVG_ProfilerTreeDepth(
+ IN gcoVG Vg,
+ IN gctUINT TreeDepth
+ );
+
+void
+gcoVG_ProfilerSetStates(
+ IN gcoVG Vg,
+ IN gctUINT treeDepth,
+ IN gctUINT saveLayerTreeDepth,
+ IN gctUINT varTreeDepth
+ );
+#endif
+
+gctBOOL
+gcoVG_IsMaskSupported(
+#if gcdGC355_PROFILER
+ IN gcoVG Vg,
+ IN gctUINT TreeDepth,
+ IN gctUINT saveLayerTreeDepth,
+ IN gctUINT varTreeDepth,
+#endif
+ IN gceSURF_FORMAT Format
+ );
+
+gctBOOL
+gcoVG_IsTargetSupported(
+#if gcdGC355_PROFILER
+ IN gcoVG Vg,
+ IN gctUINT TreeDepth,
+ IN gctUINT saveLayerTreeDepth,
+ IN gctUINT varTreeDepth,
+#endif
+ IN gceSURF_FORMAT Format
+ );
+
+gctBOOL
+gcoVG_IsImageSupported(
+#if gcdGC355_PROFILER
+ IN gcoVG Vg,
+ IN gctUINT TreeDepth,
+ IN gctUINT saveLayerTreeDepth,
+ IN gctUINT varTreeDepth,
+#endif
+ IN gceSURF_FORMAT Format
+ );
+
+gctUINT8 gcoVG_PackColorComponent(
+#if gcdGC355_PROFILER
+ gcoVG Vg,
+ gctUINT TreeDepth,
+ gctUINT saveLayerTreeDepth,
+ gctUINT varTreeDepth,
+#endif
+ gctFLOAT Value
+ );
+
+gceSTATUS
+gcoVG_Construct(
+ IN gcoHAL Hal,
+ OUT gcoVG * Vg
+ );
+
+gceSTATUS
+gcoVG_Destroy(
+ IN gcoVG Vg
+#if gcdGC355_PROFILER
+,
+ IN gctUINT TreeDepth,
+ IN gctUINT saveLayerTreeDepth,
+ IN gctUINT varTreeDepth
+#endif
+ );
+
+gceSTATUS
+gcoVG_SetTarget(
+ IN gcoVG Vg,
+#if gcdGC355_PROFILER
+ IN gctUINT TreeDepth,
+ IN gctUINT saveLayerTreeDepth,
+ IN gctUINT varTreeDepth,
+#endif
+ IN gcoSURF Target,
+ IN gceORIENTATION orientation
+ );
+
+gceSTATUS
+gcoVG_UnsetTarget(
+ IN gcoVG Vg,
+#if gcdGC355_PROFILER
+ IN gctUINT TreeDepth,
+ IN gctUINT saveLayerTreeDepth,
+ IN gctUINT varTreeDepth,
+#endif
+ IN gcoSURF Surface
+ );
+
+gceSTATUS
+gcoVG_SetUserToSurface(
+ IN gcoVG Vg,
+#if gcdGC355_PROFILER
+ IN gctUINT TreeDepth,
+ IN gctUINT saveLayerTreeDepth,
+ IN gctUINT varTreeDepth,
+#endif
+ IN gctFLOAT UserToSurface[9]
+ );
+
+gceSTATUS
+gcoVG_SetSurfaceToImage(
+ IN gcoVG Vg,
+#if gcdGC355_PROFILER
+ IN gctUINT TreeDepth,
+ IN gctUINT saveLayerTreeDepth,
+ IN gctUINT varTreeDepth,
+#endif
+ IN gctFLOAT SurfaceToImage[9]
+ );
+
+gceSTATUS
+gcoVG_EnableMask(
+ IN gcoVG Vg,
+#if gcdGC355_PROFILER
+ IN gctUINT TreeDepth,
+ IN gctUINT saveLayerTreeDepth,
+ IN gctUINT varTreeDepth,
+#endif
+ IN gctBOOL Enable
+ );
+
+gceSTATUS
+gcoVG_SetMask(
+ IN gcoVG Vg,
+#if gcdGC355_PROFILER
+ IN gctUINT TreeDepth,
+ IN gctUINT saveLayerTreeDepth,
+ IN gctUINT varTreeDepth,
+#endif
+ IN gcoSURF Mask
+ );
+
+gceSTATUS
+gcoVG_UnsetMask(
+ IN gcoVG Vg,
+#if gcdGC355_PROFILER
+ IN gctUINT TreeDepth,
+ IN gctUINT saveLayerTreeDepth,
+ IN gctUINT varTreeDepth,
+#endif
+ IN gcoSURF Surface
+ );
+
+gceSTATUS
+gcoVG_FlushMask(
+ IN gcoVG Vg
+#if gcdGC355_PROFILER
+,
+ IN gctUINT TreeDepth,
+ IN gctUINT saveLayerTreeDepth,
+ IN gctUINT varTreeDepth
+#endif
+ );
+
+gceSTATUS
+gcoVG_EnableScissor(
+ IN gcoVG Vg,
+#if gcdGC355_PROFILER
+ IN gctUINT TreeDepth,
+ IN gctUINT saveLayerTreeDepth,
+ IN gctUINT varTreeDepth,
+#endif
+ IN gctBOOL Enable
+ );
+
+gceSTATUS
+gcoVG_SetScissor(
+ IN gcoVG Vg,
+#if gcdGC355_PROFILER
+ IN gctUINT TreeDepth,
+ IN gctUINT saveLayerTreeDepth,
+ IN gctUINT varTreeDepth,
+#endif
+ IN gctSIZE_T RectangleCount,
+ IN gcsVG_RECT_PTR Rectangles
+ );
+
+gceSTATUS
+gcoVG_EnableColorTransform(
+ IN gcoVG Vg,
+#if gcdGC355_PROFILER
+ IN gctUINT TreeDepth,
+ IN gctUINT saveLayerTreeDepth,
+ IN gctUINT varTreeDepth,
+#endif
+ IN gctBOOL Enable
+ );
+
+gceSTATUS
+gcoVG_SetColorTransform(
+ IN gcoVG Vg,
+#if gcdGC355_PROFILER
+ IN gctUINT TreeDepth,
+ IN gctUINT saveLayerTreeDepth,
+ IN gctUINT varTreeDepth,
+#endif
+ IN gctFLOAT ColorTransform[8]
+ );
+
+gceSTATUS
+gcoVG_SetTileFillColor(
+ IN gcoVG Vg,
+#if gcdGC355_PROFILER
+ IN gctUINT TreeDepth,
+ IN gctUINT saveLayerTreeDepth,
+ IN gctUINT varTreeDepth,
+#endif
+ IN gctFLOAT Red,
+ IN gctFLOAT Green,
+ IN gctFLOAT Blue,
+ IN gctFLOAT Alpha
+ );
+
+gceSTATUS
+gcoVG_SetSolidPaint(
+ IN gcoVG Vg,
+#if gcdGC355_PROFILER
+ IN gctUINT TreeDepth,
+ IN gctUINT saveLayerTreeDepth,
+ IN gctUINT varTreeDepth,
+#endif
+ IN gctUINT8 Red,
+ IN gctUINT8 Green,
+ IN gctUINT8 Blue,
+ IN gctUINT8 Alpha
+ );
+
+gceSTATUS
+gcoVG_SetLinearPaint(
+ IN gcoVG Vg,
+#if gcdGC355_PROFILER
+ IN gctUINT TreeDepth,
+ IN gctUINT saveLayerTreeDepth,
+ IN gctUINT varTreeDepth,
+#endif
+ IN gctFLOAT Constant,
+ IN gctFLOAT StepX,
+ IN gctFLOAT StepY
+ );
+
+gceSTATUS
+gcoVG_SetRadialPaint(
+ IN gcoVG Vg,
+#if gcdGC355_PROFILER
+ IN gctUINT TreeDepth,
+ IN gctUINT saveLayerTreeDepth,
+ IN gctUINT varTreeDepth,
+#endif
+ IN gctFLOAT LinConstant,
+ IN gctFLOAT LinStepX,
+ IN gctFLOAT LinStepY,
+ IN gctFLOAT RadConstant,
+ IN gctFLOAT RadStepX,
+ IN gctFLOAT RadStepY,
+ IN gctFLOAT RadStepXX,
+ IN gctFLOAT RadStepYY,
+ IN gctFLOAT RadStepXY
+ );
+
+gceSTATUS
+gcoVG_SetPatternPaint(
+ IN gcoVG Vg,
+#if gcdGC355_PROFILER
+ IN gctUINT TreeDepth,
+ IN gctUINT saveLayerTreeDepth,
+ IN gctUINT varTreeDepth,
+#endif
+ IN gctFLOAT UConstant,
+ IN gctFLOAT UStepX,
+ IN gctFLOAT UStepY,
+ IN gctFLOAT VConstant,
+ IN gctFLOAT VStepX,
+ IN gctFLOAT VStepY,
+ IN gctBOOL Linear
+ );
+
+gceSTATUS
+gcoVG_SetColorRamp(
+ IN gcoVG Vg,
+#if gcdGC355_PROFILER
+ IN gctUINT TreeDepth,
+ IN gctUINT saveLayerTreeDepth,
+ IN gctUINT varTreeDepth,
+#endif
+ IN gcoSURF ColorRamp,
+ IN gceTILE_MODE ColorRampSpreadMode
+ );
+
+gceSTATUS
+gcoVG_SetPattern(
+ IN gcoVG Vg,
+#if gcdGC355_PROFILER
+ IN gctUINT TreeDepth,
+ IN gctUINT saveLayerTreeDepth,
+ IN gctUINT varTreeDepth,
+#endif
+ IN gctINT32 width,
+ IN gctINT32 height,
+ IN gcoSURF Pattern,
+ IN gceTILE_MODE TileMode,
+ IN gceIMAGE_FILTER Filter
+ );
+
+gceSTATUS
+gcoVG_SetImageMode(
+ IN gcoVG Vg,
+#if gcdGC355_PROFILER
+ IN gctUINT TreeDepth,
+ IN gctUINT saveLayerTreeDepth,
+ IN gctUINT varTreeDepth,
+#endif
+ IN gceVG_IMAGE Mode
+ );
+
+gceSTATUS
+gcoVG_SetBlendMode(
+ IN gcoVG Vg,
+#if gcdGC355_PROFILER
+ IN gctUINT TreeDepth,
+ IN gctUINT saveLayerTreeDepth,
+ IN gctUINT varTreeDepth,
+#endif
+ IN gceVG_BLEND Mode
+ );
+
+gceSTATUS
+gcoVG_SetRenderingQuality(
+ IN gcoVG Vg,
+#if gcdGC355_PROFILER
+ IN gctUINT TreeDepth,
+ IN gctUINT saveLayerTreeDepth,
+ IN gctUINT varTreeDepth,
+#endif
+ IN gceRENDER_QUALITY Quality
+ );
+
+gceSTATUS
+gcoVG_SetFillRule(
+ IN gcoVG Vg,
+#if gcdGC355_PROFILER
+ IN gctUINT TreeDepth,
+ IN gctUINT saveLayerTreeDepth,
+ IN gctUINT varTreeDepth,
+#endif
+ IN gceFILL_RULE FillRule
+ );
+
+gceSTATUS
+gcoVG_FinalizePath(
+ IN gcoVG Vg,
+ IN gcsPATH_DATA_PTR PathData
+ );
+
+gceSTATUS
+gcoVG_Clear(
+ IN gcoVG Vg,
+#if gcdGC355_PROFILER
+ IN gctUINT TreeDepth,
+ IN gctUINT saveLayerTreeDepth,
+ IN gctUINT varTreeDepth,
+#endif
+ IN gctINT X,
+ IN gctINT Y,
+ IN gctINT Width,
+ IN gctINT Height
+ );
+
+gceSTATUS
+gcoVG_DrawPath(
+ IN gcoVG Vg,
+#if gcdGC355_PROFILER
+ IN gctUINT TreeDepth,
+ IN gctUINT saveLayerTreeDepth,
+ IN gctUINT varTreeDepth,
+#endif
+ IN gcsPATH_DATA_PTR PathData,
+ IN gctFLOAT Scale,
+ IN gctFLOAT Bias,
+#if gcdMOVG
+ IN gctUINT32 Width,
+ IN gctUINT32 Height,
+ IN gctFLOAT *Bounds,
+#endif
+ IN gctBOOL SoftwareTesselation
+ );
+
+gceSTATUS
+gcoVG_DrawImage(
+ IN gcoVG Vg,
+#if gcdGC355_PROFILER
+ IN gctUINT TreeDepth,
+ IN gctUINT saveLayerTreeDepth,
+ IN gctUINT varTreeDepth,
+#endif
+ IN gceORIENTATION orientation,
+ IN gcoSURF Source,
+ IN gcsPOINT_PTR SourceOrigin,
+ IN gcsPOINT_PTR TargetOrigin,
+ IN gcsSIZE_PTR SourceSize,
+ IN gctINT SourceX,
+ IN gctINT SourceY,
+ IN gctINT TargetX,
+ IN gctINT TargetY,
+ IN gctINT Width,
+ IN gctINT Height,
+ IN gctBOOL Mask,
+ IN gctBOOL isDrawImage
+ );
+
+gceSTATUS
+gcoVG_TesselateImage(
+ IN gcoVG Vg,
+#if gcdGC355_PROFILER
+ IN gctUINT TreeDepth,
+ IN gctUINT saveLayerTreeDepth,
+ IN gctUINT varTreeDepth,
+#endif
+ IN gcoSURF Image,
+ IN gcsVG_RECT_PTR Rectangle,
+ IN gceIMAGE_FILTER Filter,
+ IN gctBOOL Mask,
+#if gcdMOVG
+ IN gctBOOL SoftwareTesselation,
+ IN gceVG_BLEND BlendMode,
+ IN gctINT Width,
+ IN gctINT Height
+#else
+ IN gctBOOL SoftwareTesselation
+#endif
+ );
+
+gceSTATUS
+gcoVG_DrawSurfaceToImage(
+ IN gcoVG Vg,
+#if gcdGC355_PROFILER
+ IN gctUINT TreeDepth,
+ IN gctUINT saveLayerTreeDepth,
+ IN gctUINT varTreeDepth,
+#endif
+ IN gcoSURF Image,
+ IN const gcsVG_RECT_PTR SrcRectangle,
+ IN const gcsVG_RECT_PTR DstRectangle,
+ IN const gctFLOAT Matrix[9],
+ IN gceIMAGE_FILTER Filter,
+ IN gctBOOL Mask,
+ IN gctBOOL FirstTime
+ );
+
+gceSTATUS
+gcoVG_Blit(
+ IN gcoVG Vg,
+#if gcdGC355_PROFILER
+ IN gctUINT TreeDepth,
+ IN gctUINT saveLayerTreeDepth,
+ IN gctUINT varTreeDepth,
+#endif
+ IN gcoSURF Source,
+ IN gcoSURF Target,
+ IN gcsVG_RECT_PTR SrcRect,
+ IN gcsVG_RECT_PTR TrgRect,
+ IN gceIMAGE_FILTER Filter,
+ IN gceVG_BLEND Mode
+ );
+
+gceSTATUS
+gcoVG_ColorMatrix(
+ IN gcoVG Vg,
+#if gcdGC355_PROFILER
+ IN gctUINT TreeDepth,
+ IN gctUINT saveLayerTreeDepth,
+ IN gctUINT varTreeDepth,
+#endif
+ IN gcoSURF Source,
+ IN gcoSURF Target,
+ IN const gctFLOAT * Matrix,
+ IN gceCHANNEL ColorChannels,
+ IN gctBOOL FilterLinear,
+ IN gctBOOL FilterPremultiplied,
+ IN gcsPOINT_PTR SourceOrigin,
+ IN gcsPOINT_PTR TargetOrigin,
+ IN gctINT Width,
+ IN gctINT Height
+ );
+
+gceSTATUS
+gcoVG_SeparableConvolve(
+ IN gcoVG Vg,
+#if gcdGC355_PROFILER
+ IN gctUINT TreeDepth,
+ IN gctUINT saveLayerTreeDepth,
+ IN gctUINT varTreeDepth,
+#endif
+ IN gcoSURF Source,
+ IN gcoSURF Target,
+ IN gctINT KernelWidth,
+ IN gctINT KernelHeight,
+ IN gctINT ShiftX,
+ IN gctINT ShiftY,
+ IN const gctINT16 * KernelX,
+ IN const gctINT16 * KernelY,
+ IN gctFLOAT Scale,
+ IN gctFLOAT Bias,
+ IN gceTILE_MODE TilingMode,
+ IN gctFLOAT_PTR FillColor,
+ IN gceCHANNEL ColorChannels,
+ IN gctBOOL FilterLinear,
+ IN gctBOOL FilterPremultiplied,
+ IN gcsPOINT_PTR SourceOrigin,
+ IN gcsPOINT_PTR TargetOrigin,
+ IN gcsSIZE_PTR SourceSize,
+ IN gctINT Width,
+ IN gctINT Height
+ );
+
+gceSTATUS
+gcoVG_GaussianBlur(
+ IN gcoVG Vg,
+#if gcdGC355_PROFILER
+ IN gctUINT TreeDepth,
+ IN gctUINT saveLayerTreeDepth,
+ IN gctUINT varTreeDepth,
+#endif
+ IN gcoSURF Source,
+ IN gcoSURF Target,
+ IN gctFLOAT StdDeviationX,
+ IN gctFLOAT StdDeviationY,
+ IN gceTILE_MODE TilingMode,
+ IN gctFLOAT_PTR FillColor,
+ IN gceCHANNEL ColorChannels,
+ IN gctBOOL FilterLinear,
+ IN gctBOOL FilterPremultiplied,
+ IN gcsPOINT_PTR SourceOrigin,
+ IN gcsPOINT_PTR TargetOrigin,
+ IN gcsSIZE_PTR SourceSize,
+ IN gctINT Width,
+ IN gctINT Height
+ );
+
+gceSTATUS
+gcoVG_EnableDither(
+ IN gcoVG Vg,
+#if gcdGC355_PROFILER
+ IN gctUINT TreeDepth,
+ IN gctUINT saveLayerTreeDepth,
+ IN gctUINT varTreeDepth,
+#endif
+ IN gctBOOL Enable
+ );
+
+/* Color Key States. */
+gceSTATUS
+gcoVG_SetColorKey(
+ IN gcoVG Vg,
+#if gcdGC355_PROFILER
+ IN gcsPROFILERFUNCNODE *DList,
+ IN gctUINT TreeDepth,
+ IN gctUINT saveLayerTreeDepth,
+ IN gctUINT varTreeDepth,
+#endif
+ IN gctUINT32* Values,
+ IN gctBOOL * Enables
+);
+
+/* Index Color States. */
+gceSTATUS
+gcoVG_SetColorIndexTable(
+ IN gcoVG Vg,
+#if gcdGC355_PROFILER
+ IN gcsPROFILERFUNCNODE *DList,
+ IN gctUINT TreeDepth,
+ IN gctUINT saveLayerTreeDepth,
+ IN gctUINT varTreeDepth,
+#endif
+ IN gctUINT32* Values,
+ IN gctINT32 Count
+);
+
+/* VG RS feature support: YUV format conversion. */
+gceSTATUS
+gcoVG_Resolve(
+ IN gcoVG Vg,
+ IN gcoSURF Source,
+ IN gcoSURF Target,
+ IN gctINT SX,
+ IN gctINT SY,
+ IN gctINT DX,
+ IN gctINT DY,
+ IN gctINT Width,
+ IN gctINT Height,
+ IN gctINT Src_uv,
+ IN gctINT Src_standard,
+ IN gctINT Dst_uv,
+ IN gctINT Dst_standard,
+ IN gctINT Dst_alpha
+);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __gc_hal_vg_h_ */
+
+
diff --git a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_enum.h b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_enum.h
new file mode 100644
index 000000000000..b854dc625e97
--- /dev/null
+++ b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_enum.h
@@ -0,0 +1,2194 @@
+/****************************************************************************
+*
+* The MIT License (MIT)
+*
+* Copyright (c) 2014 - 2018 Vivante 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 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 GPL License (GPL)
+*
+* Copyright (C) 2014 - 2018 Vivante 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.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+*****************************************************************************
+*
+* Note: This software is released under dual MIT and GPL licenses. A
+* recipient may use this file under the terms of either the MIT license or
+* GPL License. If you wish to use only one license not the other, you can
+* indicate your decision by deleting one of the above license notices in your
+* version of this file.
+*
+*****************************************************************************/
+
+
+#ifndef __gc_hal_enum_h_
+#define __gc_hal_enum_h_
+
+#include "gc_hal_options.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Chip models. */
+typedef enum _gceCHIPMODEL
+{
+ gcv200 = 0x0200,
+ gcv300 = 0x0300,
+ gcv320 = 0x0320,
+ gcv328 = 0x0328,
+ gcv350 = 0x0350,
+ gcv355 = 0x0355,
+ gcv400 = 0x0400,
+ gcv410 = 0x0410,
+ gcv420 = 0x0420,
+ gcv428 = 0x0428,
+ gcv450 = 0x0450,
+ gcv500 = 0x0500,
+ gcv520 = 0x0520,
+ gcv530 = 0x0530,
+ gcv600 = 0x0600,
+ gcv620 = 0x0620,
+ gcv700 = 0x0700,
+ gcv800 = 0x0800,
+ gcv860 = 0x0860,
+ gcv880 = 0x0880,
+ gcv900 = 0x0900,
+ gcv1000 = 0x1000,
+ gcv1500 = 0x1500,
+ gcv2000 = 0x2000,
+ gcv2100 = 0x2100,
+ gcv2200 = 0x2200,
+ gcv2500 = 0x2500,
+ gcv3000 = 0x3000,
+ gcv4000 = 0x4000,
+ gcv5000 = 0x5000,
+ gcv5200 = 0x5200,
+ gcv6400 = 0x6400,
+ gcv7000 = 0x7000,
+ gcv7400 = 0x7400,
+}
+gceCHIPMODEL;
+
+/* Chip features. */
+typedef enum _gceFEATURE
+{
+ gcvFEATURE_PIPE_2D = 0,
+ gcvFEATURE_PIPE_3D,
+ gcvFEATURE_PIPE_VG,
+ gcvFEATURE_DC,
+ gcvFEATURE_HIGH_DYNAMIC_RANGE,
+ gcvFEATURE_MODULE_CG,
+ gcvFEATURE_MIN_AREA,
+ gcvFEATURE_BUFFER_INTERLEAVING,
+ gcvFEATURE_BYTE_WRITE_2D,
+ gcvFEATURE_ENDIANNESS_CONFIG,
+ gcvFEATURE_DUAL_RETURN_BUS,
+ gcvFEATURE_DEBUG_MODE,
+ gcvFEATURE_YUY2_RENDER_TARGET,
+ gcvFEATURE_FRAGMENT_PROCESSOR,
+ gcvFEATURE_2DPE20,
+ gcvFEATURE_FAST_CLEAR,
+ gcvFEATURE_YUV420_TILER,
+ gcvFEATURE_YUY2_AVERAGING,
+ gcvFEATURE_FLIP_Y,
+ gcvFEATURE_EARLY_Z,
+ gcvFEATURE_COMPRESSION,
+ gcvFEATURE_MSAA,
+ gcvFEATURE_SPECIAL_ANTI_ALIASING,
+ gcvFEATURE_SPECIAL_MSAA_LOD,
+ gcvFEATURE_422_TEXTURE_COMPRESSION,
+ gcvFEATURE_DXT_TEXTURE_COMPRESSION,
+ gcvFEATURE_ETC1_TEXTURE_COMPRESSION,
+ gcvFEATURE_CORRECT_TEXTURE_CONVERTER,
+ gcvFEATURE_TEXTURE_8K,
+ gcvFEATURE_SCALER,
+ gcvFEATURE_YUV420_SCALER,
+ gcvFEATURE_SHADER_HAS_W,
+ gcvFEATURE_SHADER_HAS_SIGN,
+ gcvFEATURE_SHADER_HAS_FLOOR,
+ gcvFEATURE_SHADER_HAS_CEIL,
+ gcvFEATURE_SHADER_HAS_SQRT,
+ gcvFEATURE_SHADER_HAS_TRIG,
+ gcvFEATURE_HZ,
+ gcvFEATURE_CORRECT_STENCIL,
+ gcvFEATURE_VG20,
+ gcvFEATURE_VG_FILTER,
+ gcvFEATURE_VG21,
+ gcvFEATURE_VG_DOUBLE_BUFFER,
+ gcvFEATURE_MC20,
+ gcvFEATURE_SUPER_TILED,
+ gcvFEATURE_FAST_CLEAR_FLUSH,
+ gcvFEATURE_2D_FILTERBLIT_PLUS_ALPHABLEND,
+ gcvFEATURE_2D_DITHER,
+ gcvFEATURE_2D_A8_TARGET,
+ gcvFEATURE_2D_A8_NO_ALPHA,
+ gcvFEATURE_2D_FILTERBLIT_FULLROTATION,
+ gcvFEATURE_2D_BITBLIT_FULLROTATION,
+ gcvFEATURE_WIDE_LINE,
+ gcvFEATURE_FC_FLUSH_STALL,
+ gcvFEATURE_FULL_DIRECTFB,
+ gcvFEATURE_HALF_FLOAT_PIPE,
+ gcvFEATURE_LINE_LOOP,
+ gcvFEATURE_2D_YUV_BLIT,
+ gcvFEATURE_2D_TILING,
+ gcvFEATURE_NON_POWER_OF_TWO,
+ gcvFEATURE_3D_TEXTURE,
+ gcvFEATURE_TEXTURE_ARRAY,
+ gcvFEATURE_TILE_FILLER,
+ gcvFEATURE_LOGIC_OP,
+ gcvFEATURE_MIXED_STREAMS,
+ gcvFEATURE_2D_MULTI_SOURCE_BLT,
+ gcvFEATURE_END_EVENT,
+ gcvFEATURE_VERTEX_10_10_10_2,
+ gcvFEATURE_TEXTURE_10_10_10_2,
+ gcvFEATURE_TEXTURE_ANISOTROPIC_FILTERING,
+ gcvFEATURE_TEXTURE_FLOAT_HALF_FLOAT,
+ gcvFEATURE_2D_ROTATION_STALL_FIX,
+ gcvFEATURE_2D_MULTI_SOURCE_BLT_EX,
+ gcvFEATURE_BUG_FIXES10,
+ gcvFEATURE_2D_MINOR_TILING,
+ gcvFEATURE_TEX_COMPRRESSION_SUPERTILED, /* Supertiled compressed textures are supported. */
+ gcvFEATURE_FAST_MSAA,
+ gcvFEATURE_BUG_FIXED_INDEXED_TRIANGLE_STRIP,
+ gcvFEATURE_TEXTURE_TILE_STATUS_READ,
+ gcvFEATURE_DEPTH_BIAS_FIX,
+ gcvFEATURE_RECT_PRIMITIVE,
+ gcvFEATURE_BUG_FIXES11,
+ gcvFEATURE_SUPERTILED_TEXTURE,
+ gcvFEATURE_2D_NO_COLORBRUSH_INDEX8,
+ gcvFEATURE_RS_YUV_TARGET,
+ gcvFEATURE_2D_FC_SOURCE,
+ gcvFEATURE_2D_CC_NOAA_SOURCE,
+ gcvFEATURE_PE_DITHER_FIX,
+ gcvFEATURE_2D_YUV_SEPARATE_STRIDE,
+ gcvFEATURE_FRUSTUM_CLIP_FIX,
+ gcvFEATURE_TEXTURE_SWIZZLE,
+ gcvFEATURE_PRIMITIVE_RESTART,
+ gcvFEATURE_TEXTURE_LINEAR,
+ gcvFEATURE_TEXTURE_YUV_ASSEMBLER,
+ gcvFEATURE_LINEAR_RENDER_TARGET,
+ gcvFEATURE_SHADER_HAS_ATOMIC,
+ gcvFEATURE_SHADER_HAS_INSTRUCTION_CACHE,
+ gcvFEATURE_SHADER_ENHANCEMENTS2,
+ gcvFEATURE_BUG_FIXES7,
+ gcvFEATURE_SHADER_HAS_RTNE,
+ gcvFEATURE_SHADER_HAS_EXTRA_INSTRUCTIONS2,
+ gcvFEATURE_SHADER_ENHANCEMENTS3,
+ gcvFEATURE_DYNAMIC_FREQUENCY_SCALING,
+ gcvFEATURE_SINGLE_BUFFER,
+ gcvFEATURE_OCCLUSION_QUERY,
+ gcvFEATURE_2D_GAMMA,
+ gcvFEATURE_2D_COLOR_SPACE_CONVERSION,
+ gcvFEATURE_2D_SUPER_TILE_VERSION,
+ gcvFEATURE_HALTI0,
+ gcvFEATURE_HALTI1,
+ gcvFEATURE_HALTI2,
+ gcvFEATURE_SUPPORT_GCREGTX,
+ gcvFEATURE_2D_MIRROR_EXTENSION,
+ gcvFEATURE_TEXTURE_ASTC,
+ gcvFEATURE_TEXTURE_ASTC_DECODE_FIX,
+ gcvFEATURE_TEXTURE_ASTC_BASE_LOD_FIX,
+ gcvFEATURE_2D_SUPER_TILE_V1,
+ gcvFEATURE_2D_SUPER_TILE_V2,
+ gcvFEATURE_2D_SUPER_TILE_V3,
+ gcvFEATURE_2D_MULTI_SOURCE_BLT_EX2,
+ gcvFEATURE_NEW_RA,
+ gcvFEATURE_BUG_FIXED_IMPLICIT_PRIMITIVE_RESTART,
+ gcvFEATURE_PE_MULTI_RT_BLEND_ENABLE_CONTROL,
+ gcvFEATURE_SMALL_MSAA, /* An upgraded version of Fast MSAA */
+ gcvFEATURE_VERTEX_INST_ID_AS_ATTRIBUTE,
+ gcvFEATURE_DUAL_16,
+ gcvFEATURE_BRANCH_ON_IMMEDIATE_REG,
+ gcvFEATURE_2D_COMPRESSION,
+ gcvFEATURE_TPC_COMPRESSION,
+ gcvFEATURE_TPCV11_COMPRESSION,
+ gcvFEATURE_DEC_COMPRESSION,
+ gcvFEATURE_DEC300_COMPRESSION,
+ gcvFEATURE_DEC400_COMPRESSION,
+ gcvFEATURE_DEC_TPC_COMPRESSION,
+ gcvFEATURE_DEC_COMPRESSION_TILE_NV12_8BIT,
+ gcvFEATURE_DEC_COMPRESSION_TILE_NV12_10BIT,
+ gcvFEATURE_2D_OPF_YUV_OUTPUT,
+ gcvFEATURE_2D_FILTERBLIT_A8_ALPHA,
+ gcvFEATURE_2D_MULTI_SRC_BLT_TO_UNIFIED_DST_RECT,
+ gcvFEATURE_2D_MULTI_SRC_BLT_BILINEAR_FILTER,
+ gcvFEATURE_2D_MULTI_SRC_BLT_1_5_ENHANCEMENT,
+ gcvFEATURE_V2_COMPRESSION_Z16_FIX,
+ gcvFEATURE_VERTEX_INST_ID_AS_INTEGER,
+ gcvFEATURE_2D_YUV_MODE,
+ gcvFEATURE_2D_CACHE_128B256BPERLINE,
+ gcvFEATURE_2D_SEPARATE_CACHE,
+ gcvFEATURE_2D_MAJOR_SUPER_TILE,
+ gcvFEATURE_2D_V4COMPRESSION,
+ gcvFEATURE_2D_VMSAA,
+ gcvFEATURE_2D_10BIT_OUTPUT_LINEAR,
+ gcvFEATURE_2D_YUV420_OUTPUT_LINEAR,
+ gcvFEATURE_ACE,
+ gcvFEATURE_COLOR_COMPRESSION,
+ gcvFEATURE_32BPP_COMPONENT_TEXTURE_CHANNEL_SWIZZLE,
+ gcvFEATURE_64BPP_HW_CLEAR_SUPPORT,
+ gcvFEATURE_TX_LERP_PRECISION_FIX,
+ gcvFEATURE_COMPRESSION_V2,
+ gcvFEATURE_MMU,
+ gcvFEATURE_COMPRESSION_V3,
+ gcvFEATURE_TX_DECOMPRESSOR,
+ gcvFEATURE_MRT_TILE_STATUS_BUFFER,
+ gcvFEATURE_COMPRESSION_V1,
+ gcvFEATURE_V1_COMPRESSION_Z16_DECOMPRESS_FIX,
+ gcvFEATURE_RTT,
+ gcvFEATURE_GENERIC_ATTRIB,
+ gcvFEATURE_2D_ONE_PASS_FILTER,
+ gcvFEATURE_2D_ONE_PASS_FILTER_TAP,
+ gcvFEATURE_2D_POST_FLIP,
+ gcvFEATURE_2D_PIXEL_ALIGNMENT,
+ gcvFEATURE_CORRECT_AUTO_DISABLE_COUNT,
+ gcvFEATURE_CORRECT_AUTO_DISABLE_COUNT_WIDTH,
+ gcvFEATURE_8K_RT,
+ gcvFEATURE_HALTI3,
+ gcvFEATURE_EEZ,
+ gcvFEATURE_INTEGER_SIGNEXT_FIX,
+ gcvFEATURE_PSOUTPUT_MAPPING,
+ gcvFEATURE_8K_RT_FIX,
+ gcvFEATURE_TX_TILE_STATUS_MAPPING,
+ gcvFEATURE_SRGB_RT_SUPPORT,
+ gcvFEATURE_TEXTURE_16K,
+ gcvFEATURE_PA_FARZCLIPPING_FIX,
+ gcvFEATURE_PE_DITHER_COLORMASK_FIX,
+ gcvFEATURE_ZSCALE_FIX,
+ gcvFEATURE_MULTI_PIXELPIPES,
+ gcvFEATURE_PIPE_CL,
+ gcvFEATURE_BUG_FIXES18,
+ gcvFEATURE_UNIFIED_SAMPLERS,
+ gcvFEATURE_CL_PS_WALKER,
+ gcvFEATURE_NEW_HZ,
+ gcvFEATURE_TX_FRAC_PRECISION_6BIT,
+ gcvFEATURE_SH_INSTRUCTION_PREFETCH,
+ gcvFEATURE_PROBE,
+ gcvFEATURE_SINGLE_PIPE_HALTI1,
+ gcvFEATURE_BUG_FIXES8, /* This HW feature is wrong, we can't use this to check integer branch!!!*/
+ gcvFEATURE_2D_ALL_QUAD,
+ gcvFEATURE_SEPARATE_SRC_DST,
+ gcvFEATURE_TX_HOR_ALIGN_SEL,
+ gcvFEATURE_HALTI4,
+ gcvFEATURE_MRT_FC_FIX,
+ gcvFEATURE_TESSELLATION,
+ gcvFEATURE_DRAW_INDIRECT,
+ gcvFEATURE_COMPUTE_INDIRECT,
+ gcvFEATURE_MSAA_TEXTURE,
+ gcvFEATURE_STENCIL_TEXTURE,
+ gcvFEATURE_S8_ONLY_RENDERING,
+ gcvFEATURE_D24S8_SAMPLE_STENCIL,
+ gcvFEATURE_ADVANCED_BLEND_MODE_PART0,
+ gcvFEATURE_RA_DEPTH_WRITE,
+ gcvFEATURE_RS_DS_DOWNSAMPLE_NATIVE_SUPPORT,
+ gcvFEATURE_S8_MSAA_COMPRESSION,
+ gcvFEATURE_MSAA_FRAGMENT_OPERATION,
+ gcvFEATURE_FE_START_VERTEX_SUPPORT,
+ gcvFEATURE_DIVISOR_STREAM_ADDR_FIX,
+ gcvFEATURE_ZERO_ATTRIB_SUPPORT,
+ gcvFEATURE_DANGLING_VERTEX_FIX,
+ gcvFEATURE_PE_DISABLE_COLOR_PIPE,
+ gcvFEATURE_FE_12bit_stride,
+ gcvFEATURE_TX_LOD_GUARDBAND,
+ gcvFEATURE_HAS_PRODUCTID,
+ gcvFEATURE_INTEGER32_FIX,
+ gcvFEATURE_TEXTURE_GATHER,
+ gcvFEATURE_IMG_INSTRUCTION,
+ gcvFEATURE_HELPER_INVOCATION,
+ gcvFEATURE_NO_USER_CSC,
+ gcvFEATURE_ANDROID_ONLY,
+ gcvFEATURE_V2_MSAA_COHERENCY_FIX,
+ gcvFEATURE_BLOCK_SIZE_16x16,
+ gcvFEATURE_TX_SUPPORT_DEC,
+ gcvFEATURE_RSBLT_MSAA_DECOMPRESSION,
+ gcvFEATURE_TILEFILLER_32TILE_ALIGNED,
+ gcvFEATURE_GEOMETRY_SHADER,
+ gcvFEATURE_HALTI5,
+ gcvFEATURE_PIPELINE_32_ATTRIBUTES,
+ gcvFEATURE_USC,
+ gcvFEATURE_CUBEMAP_ARRAY,
+ gcvFEATURE_TX_DESCRIPTOR,
+ gcvFEATURE_SEPARATE_RT_CTRL,
+ gcvFEATURE_RENDER_ARRAY,
+ gcvFEATURE_BLT_ENGINE,
+ gcvFEATURE_SMALLDRAW_BATCH,
+ gcvFEATURE_TEXTURE_BUFFER,
+ gcvFEATURE_GS_SUPPORT_EMIT,
+ gcvFEATURE_SAMPLER_BASE_OFFSET,
+ gcvFEATURE_IMAGE_OUT_BOUNDARY_FIX,
+ gcvFEATURE_TX_BORDER_CLAMP,
+ gcvFEATURE_MSAA_SHADING,
+ gcvFEATURE_ADVANCED_SH_INST,
+ gcvFEATURE_LOD_FIX_FOR_BASELEVEL,
+ gcvFEATURE_MULTIDRAW_INDIRECT,
+ gcvFEATURE_DRAW_ELEMENTS_BASE_VERTEX,
+ gcvFEATURE_NEW_STEERING_AND_ICACHE_FLUSH, /* Steering base on register base. Trigger-style Icache flush state. */
+ gcvFEATURE_PE_DITHER_FIX2,
+ gcvFEATURE_INDEX_FETCH_FIX,
+ gcvFEATURE_TEX_BASELOD,
+ gcvFEATURE_TEX_SEAMLESS_CUBE,
+ gcvFEATURE_TEX_ETC2,
+ gcvFEATURE_TEX_CUBE_BORDER_LOD,
+ gcvFEATURE_FE_ALLOW_STALL_PREFETCH_ENG,
+ gcvFEATURE_TX_8BPP_TS_FIX,
+ gcvFEATURE_HW_TFB,
+ gcvFEATURE_COMPRESSION_V4,
+ gcvFEATURE_FENCE_32BIT,
+ gcvFEATURE_FENCE_64BIT,
+ gcvFEATURE_R8_UNORM,
+ gcvFEATURE_TX_DEFAULT_VALUE_FIX,
+ gcvFEATURE_TX_8bit_UVFrac,
+ gcvFEATURE_TX_MIPFILTER_NONE_FIX,
+ gcvFEATURE_MC_STENCIL_CTRL,
+ gcvFEATURE_DEPTH_MATH_FIX,
+ gcvFEATURE_PE_B2B_PIXEL_FIX,
+ gcvFEATURE_TEXTURE_GATHER_OFFSETS,
+ gcvFEATURE_TEX_CACHE_FLUSH_FIX,
+ gcvFEATURE_WIDELINE_HELPER_FIX,
+ gcvFEATURE_LINE_DIAMOND_RULE_FIX,
+ gcvFEATURE_MULTIGPU_SYNC_V2,
+ gcvFEATURE_DRAW_ID,
+ gcvFEATURE_SNAPPAGE_CMD,
+ gcvFEATURE_COMMAND_PREFETCH,
+ gcvFEATURE_SAMPLEPOS_SWIZZLE_FIX,
+ gcvFEATURE_SELECTMAP_SRC0_SWIZZLE_FIX,
+ gcvFEATURE_LOADATTR_OOB_FIX,
+ gcvFEATURE_RA_DEPTH_WRITE_MSAA1X_FIX,
+ gcvFEATURE_MRT_8BIT_DUAL_PIPE_FIX,
+ gcvFEATURE_BUG_FIXES1,
+ gcvFEATURE_MULTI_SOURCE_BLT,
+ gcvFEATURE_ZCOMPRESSION,
+ gcvFEATURE_DITHER_AND_FILTER_PLUS_ALPHA_2D,
+ gcvFEATURE_ONE_PASS_2D_FILTER,
+ gcvFEATURE_TX_FILTER,
+ gcvFEATURE_CHIPENABLE_LINK,
+ gcvFEATURE_TEXTURE_BIAS_LOD_FIX,
+ gcvFEATURE_USE_GL_Z,
+ gcvFEATURE_SUPPORT_INTEGER,
+ /* PARTLY_SUPPORT_INTEGER_BRANCH:
+ ** chips can support all integer types for compare instructions, e.g, CMP, SELECT.
+ ** FULLLY_SUPPORT_INTEGER_BRANCH:
+ ** chips can support all integer types for JMP instruction.
+ ** If PARTLY_SUPPORT_INTEGER_BRANCH is TRUE but FULLLY_SUPPORT_INTEGER_BRANCH is FALSE,
+ ** then this chip can only support INT32/UINT32 JMP instruction.
+ */
+ gcvFEATURE_PARTLY_SUPPORT_INTEGER_BRANCH,
+ gcvFEATURE_FULLLY_SUPPORT_INTEGER_BRANCH,
+ gcvFEATURE_SUPPORT_INTEGER_ATTRIBUTE,
+ gcvFEATURE_SUPPORT_MOVAI,
+ gcvFEATURE_NEED_FIX_FOR_CL_X,
+ gcvFEATURE_NEED_FIX_FOR_CL_XE,
+ gcvFEATURE_HAS_OUTPUT_COUNT_FIX,
+ gcvFEATURE_VARYING_PACKING_LIMITATION,
+ gcvFEATURE_HIGHP_VARYING_SHIFT,
+ gcvFEATURE_BUG_FIXES2,
+ gcvFEATURE_64K_L2_CACHE,
+ gcvFEATURE_128BTILE,
+ gcvFEATURE_ADVANCED_BLEND_OPT,
+ gcvFEATURE_SNAPPAGE_CMD_FIX,
+ gcvFEATURE_L2_CACHE_FOR_2D_420,
+ gcvFEATURE_TILE_STATUS_2BITS,
+ gcvFEATURE_EXTRA_SHADER_INSTRUCTIONS0,
+ gcvFEATURE_EXTRA_SHADER_INSTRUCTIONS1,
+ gcvFEATURE_EXTRA_SHADER_INSTRUCTIONS2,
+ gcvFEATURE_MEDIUM_PRECISION,
+ gcvFEATURE_FE20_BIT_INDEX,
+ gcvFEATURE_BUG_FIXES4,
+ gcvFEATURE_BUG_FIXES12,
+ gcvFEATURE_VMSAA,
+ gcvFEATURE_ROBUST_ATOMIC,
+ gcvFEATURE_32F_COLORMASK_FIX,
+ gcvFEATURE_NEW_GPIPE,
+ gcvFEATURE_RS_NEW_BASEADDR,
+ gcvFEATURE_TX_DXT,
+ gcvFEATURE_SH_FLAT_INTERPOLATION_DUAL16_FIX,
+ gcvFEATURE_EVIS,
+ gcvFEATURE_SH_SUPPORT_V4,
+ gcvFEATURE_SH_SUPPORT_ALPHA_KILL,
+ gcvFEATURE_PE_NO_ALPHA_TEST,
+ gcvFEATURE_SH_SNAP2PAGE_MAXPAGES_FIX,
+ gcvFEATURE_USC_FULLCACHE_FIX,
+ gcvFEATURE_PE_64bit_FENCE_FIX,
+ gcvFEATURE_BLT_8bit_256TILE_FC_FIX,
+ gcvFEATURE_PE_RGBA16I_FIX,
+ gcvFEATURE_BLT_64bpp_MASKED_CLEAR_FIX,
+ gcvFEATURE_SH_PSO_MSAA1x_FIX,
+ gcvFEATURE_USC_ATOMIC_FIX,
+ gcvFEATURE_INDEX_CONST_ON_B0,
+ gcvFEATURE_SH_NO_ONECONST_LIMIT,
+ gcvFEATURE_EVIS_NO_ABSDIFF,
+ gcvFEATURE_EVIS_NO_BITREPLACE,
+ gcvFEATURE_EVIS_NO_BOXFILTER,
+ gcvFEATURE_EVIS_NO_CORDIAC,
+ gcvFEATURE_EVIS_NO_DP32,
+ gcvFEATURE_EVIS_NO_FILTER,
+ gcvFEATURE_EVIS_NO_IADD,
+ gcvFEATURE_EVIS_NO_SELECTADD,
+ gcvFEATURE_EVIS_LERP_7OUTPUT,
+ gcvFEATURE_EVIS_ACCSQ_8OUTPUT,
+ gcvFEATURE_ROBUSTNESS,
+ gcvFEATURE_SECURITY,
+ gcvFEATURE_TX_YUV_ASSEMBLER_10BIT,
+ gcvFEATURE_USC_GOS_ADDR_FIX,
+ gcvFEATURE_SUPPORT_MSAA2X,
+ gcvFEATURE_TX_DESC_CACHE_CLOCKGATE_FIX,
+ gcvFEATURE_TX_INTEGER_COORDINATE,
+ gcvFEATURE_PSIO_SAMPLEMASK_IN_R0ZW_FIX,
+ gcvFEATURE_MULTI_CORE_BLOCK_SET_CONFIG,
+ gcvFEATURE_SH_IMG_LDST_ON_TEMP,
+ gcvFEATURE_TX_INTEGER_COORDINATE_V2,
+ gcvFEATURE_COMPUTE_ONLY,
+ gcvFEATURE_SH_IMG_LDST_CLAMP,
+ gcvFEATURE_SH_ICACHE_ALLOC_COUNT_FIX,
+ gcvFEATURE_MSAA_OQ_FIX,
+ gcvFEATURE_PE_ENHANCEMENTS2,
+ gcvFEATURE_PSIO_MSAA_CL_FIX,
+ gcvFEATURE_FE_NEED_DUMMYDRAW,
+ gcvFEATURE_MULTI_CLUSTER,
+ gcvFEATURE_PSIO_INTERLOCK,
+ gcvFEATURE_BLIT_COMPRESS_DEST,
+ gcvFEATURE_SH_MULTI_WG_PACK,
+ gcvFEATURE_FE_ROBUST_FIX,
+ gcvFEATURE_TX_ASTC_MULTISLICE_FIX,
+ gcvFEATURE_PSIO_DUAL16_32bpc_FIX,
+ gcvFEATURE_LS_SUPPORT_PER_COMP_DEPENDENCY,
+ gcvFEATURE_COMPRESSION_DEC400,
+ gcvFEATURE_SH_TEXLD_U_FIX,
+ gcvFEATURE_TX_FLUSH_L1CACHE,
+ gcvFEATURE_USC_DEFER_FILL_FIX,
+ gcvFEATURE_MC_FCCACHE_BYTEMASK,
+ gcvFEATURE_SH_MULTI_WG_PACK_FIX,
+ gcvFEATURE_FE_PATCHLIST_FETCH_FIX,
+ gcvFEATURE_RA_CG_FIX,
+ gcvFEATURE_EVIS_VX2,
+ gcvFEATURE_SH_HALF_DEPENDENCY_FIX,
+ gcvFEATURE_SH_CLOCK_GATE_FIX,
+ gcvFEATURE_GPIPE_CLOCK_GATE_FIX,
+ gcvFEATURE_TP_ENGINE,
+ gcvFEATURE_TX_BORDER_CLAMP_FIX,
+ gcvFEATURE_SH_IMAGE_LD_LAST_PIXEL_FIX,
+ gcvFEATURE_MULTI_CORE_BLOCK_SET_CONFIG2,
+ gcvFEATURE_MULTIGPU_SYNC_V3,
+ gcvFEATURE_PE_VMSAA_COVERAGE_CACHE_FIX,
+ gcvFEATURE_SECURITY_AHB,
+ gcvFEATURE_TX_LERP_LESS_BIT,
+ gcvFEATURE_VIP_V7,
+ gcvFEATURE_ASYNC_BLIT,
+ gcvFEATURE_ASYNC_FE_FENCE_FIX,
+ gcvFEATURE_PSCS_THROTTLE,
+ gcvFEATURE_WIDELINE_TRIANGLE_EMU,
+ gcvFEATURE_FENCE,
+ gcvFEATURE_PE_DEPTH_ONLY_OQFIX,
+ gcvFEATURE_VG_RESOLUTION_8K,
+ gcvFEATURE_IMAGE_LS_NO_FULLMASK_FIX,
+ gcvFEATURE_PE_TILE_CACHE_FLUSH_FIX,
+ gcvFEATURE_USC_ATOMIC_FIX2,
+ gcvFEATURE_PA_LINECLIP_FIX,
+ gcvFEATURE_MAX_POINTSIZE_CLAMP,
+
+ /* Insert features above this comment only. */
+ gcvFEATURE_COUNT /* Not a feature. */
+}
+gceFEATURE;
+
+/* dummy draw type.*/
+typedef enum _gceDUMMY_DRAW_TYPE
+{
+ gcvDUMMY_DRAW_INVALID = 0,
+ gcvDUMMY_DRAW_GC400,
+ gcvDUMMY_DRAW_V60,
+}
+gceDUMMY_DRAW_TYPE;
+
+/* Chip SWWA. */
+typedef enum _gceSWWA
+{
+ gcvSWWA_601 = 0,
+ gcvSWWA_706,
+ gcvSWWA_1163,
+ gcvSWWA_1165,
+ /* Insert SWWA above this comment only. */
+ gcvSWWA_COUNT /* Not a SWWA. */
+}
+gceSWWA;
+
+
+/* Option Set*/
+typedef enum _gceOPTION
+{
+ /* HW setting. */
+ gcvOPTION_PREFER_ZCONVERT_BYPASS = 0,
+ gcvOPTION_PREFER_TILED_DISPLAY_BUFFER = 1,
+ gcvOPTION_PREFER_GUARDBAND = 2,
+ gcvOPTION_PREFER_TPG_TRIVIALMODEL = 3,
+ gcvOPTION_PREFER_RA_DEPTH_WRITE = 4,
+ gcvOPTION_PREFER_USC_RECONFIG = 5,
+ gcvOPTION_PREFER_DISALBE_HZ = 6,
+
+ /* SW options */
+ gcvOPTION_HW_NULL = 50,
+ gcvOPTION_PRINT_OPTION = 51,
+ gcvOPTION_KERNEL_FENCE = 52,
+ gcvOPTION_ASYNC_PIPE = 53,
+ gcvOPTION_FBO_PREFER_MEM = 54,
+ gcvOPTION_GPU_TEX_UPLOAD = 55,
+ gcvOPTION_GPU_BUFOBJ_UPLOAD = 56,
+ gcvOPTION_OCL_ASYNC_BLT = 57,
+ gcvOPTION_OCL_IN_THREAD = 58,
+ gcvOPTION_COMPRESSION_DEC400 = 59,
+ gcvOPTION_NO_Y_INVERT = 60,
+ /* Insert option above this comment only */
+ gcvOPTION_COUNT /* Not a OPTION*/
+}
+gceOPTION;
+
+typedef enum _gceFRAMEINFO
+{
+ /* Total frame count in one run */
+ gcvFRAMEINFO_FRAME_NUM = 0,
+ /* Total draw count in current frame, including draw/compute */
+ gcvFRAMEINFO_DRAW_NUM = 1,
+ /* Total compute count in current frame, subset of drawNum */
+ gcvFRAMEINFO_COMPUTE_NUM = 2,
+ /* Total dual16 draw/compute count in current frame, subset of drawNum */
+ gcvFRAMEINFO_DUAL16_NUM = 3,
+ /* Current programID is being set. only valid for ES20 driver right now */
+ gcvFRAMEINFO_PROGRAM_ID = 4,
+
+ gcvFRAMEINFO_COUNT,
+}
+gceFRAMEINFO;
+
+typedef enum _gceFRAMEINFO_OP
+{
+ gcvFRAMEINFO_OP_INC = 0,
+ gcvFRAMEINFO_OP_DEC = 1,
+ gcvFRAMEINFO_OP_ZERO = 2,
+ gcvFRAMEINFO_OP_GET = 3,
+ gcvFRAMEINFO_OP_SET = 4,
+ gcvFRAMEINFO_OP_COUNT,
+}
+gceFRAMEINFO_OP;
+
+
+/* Chip Power Status. */
+typedef enum _gceCHIPPOWERSTATE
+{
+ gcvPOWER_ON = 0,
+ gcvPOWER_OFF,
+ gcvPOWER_IDLE,
+ gcvPOWER_SUSPEND,
+ gcvPOWER_IDLE_BROADCAST,
+ gcvPOWER_SUSPEND_BROADCAST,
+ gcvPOWER_OFF_BROADCAST,
+ gcvPOWER_OFF_TIMEOUT,
+ gcvPOWER_ON_AUTO
+}
+gceCHIPPOWERSTATE;
+
+/* CPU cache operations */
+typedef enum _gceCACHEOPERATION
+{
+ gcvCACHE_CLEAN = 0x01, /* Flush CPU cache to mem */
+ gcvCACHE_INVALIDATE = 0x02, /* Invalidte CPU cache */
+ gcvCACHE_FLUSH = gcvCACHE_CLEAN | gcvCACHE_INVALIDATE, /* Both flush & invalidate */
+ gcvCACHE_MEMORY_BARRIER = 0x04
+}
+gceCACHEOPERATION;
+
+/* Surface types. */
+typedef enum _gceSURF_TYPE
+{
+ gcvSURF_TYPE_UNKNOWN = 0,
+ gcvSURF_INDEX,
+ gcvSURF_VERTEX,
+ gcvSURF_TEXTURE,
+ gcvSURF_RENDER_TARGET,
+ gcvSURF_DEPTH,
+ gcvSURF_BITMAP,
+ gcvSURF_TILE_STATUS,
+ gcvSURF_IMAGE,
+ gcvSURF_MASK,
+ gcvSURF_SCISSOR,
+ gcvSURF_HIERARCHICAL_DEPTH,
+ gcvSURF_ICACHE,
+ gcvSURF_TXDESC,
+ gcvSURF_FENCE,
+ gcvSURF_TFBHEADER,
+ gcvSURF_NUM_TYPES, /* Make sure this is the last one! */
+
+ /* Combinations. */
+ gcvSURF_CMA_LIMIT = 0x80000000,
+ gcvSURF_NO_TILE_STATUS = 0x100,
+ gcvSURF_NO_VIDMEM = 0x200, /* Used to allocate surfaces with no underlying vidmem node.
+ In Android, vidmem node is allocated by another process. */
+ gcvSURF_CACHEABLE = 0x400, /* Used to allocate a cacheable surface */
+ gcvSURF_TILE_RLV_FENCE = 0x800, /* create texture fence as tile */
+ gcvSURF_TILE_STATUS_DIRTY = 0x1000, /* Init tile status to all dirty */
+ gcvSURF_LINEAR = 0x2000,
+ gcvSURF_CREATE_AS_TEXTURE = 0x4000, /* create it as a texture */
+ gcvSURF_PROTECTED_CONTENT = 0x8000, /* create it as content protected */
+ gcvSURF_CREATE_AS_DISPLAYBUFFER = 0x10000, /*create it as a display buffer surface */
+ gcvSURF_CONTIGUOUS = 0x20000, /*create it as contiguous */
+ gcvSURF_NO_COMPRESSION = 0x40000, /* Create it as no compression, valid on when it has tile status. */
+ gcvSURF_DEC = 0x80000, /* Surface is DEC compressed */
+ gcvSURF_NO_HZ = 0x100000,
+ gcvSURF_3D = 0x200000, /* It's 3d surface */
+ gcvSURF_DMABUF_EXPORTABLE = 0x400000, /* master node can be exported as dma-buf fd */
+ gcvSURF_CACHE_MODE_128 = 0x800000,
+
+ gcvSURF_TEXTURE_LINEAR = gcvSURF_TEXTURE
+ | gcvSURF_LINEAR,
+
+ gcvSURF_RENDER_TARGET_LINEAR = gcvSURF_RENDER_TARGET
+ | gcvSURF_LINEAR,
+
+ gcvSURF_RENDER_TARGET_NO_TILE_STATUS = gcvSURF_RENDER_TARGET
+ | gcvSURF_NO_TILE_STATUS,
+
+ gcvSURF_RENDER_TARGET_NO_COMPRESSION = gcvSURF_RENDER_TARGET
+ | gcvSURF_NO_COMPRESSION,
+
+ gcvSURF_RENDER_TARGET_TS_DIRTY = gcvSURF_RENDER_TARGET
+ | gcvSURF_TILE_STATUS_DIRTY,
+
+ gcvSURF_DEPTH_NO_TILE_STATUS = gcvSURF_DEPTH
+ | gcvSURF_NO_TILE_STATUS,
+
+ gcvSURF_DEPTH_TS_DIRTY = gcvSURF_DEPTH
+ | gcvSURF_TILE_STATUS_DIRTY,
+
+ /* Supported surface types with no vidmem node. */
+ gcvSURF_BITMAP_NO_VIDMEM = gcvSURF_BITMAP
+ | gcvSURF_NO_VIDMEM,
+
+ gcvSURF_TEXTURE_NO_VIDMEM = gcvSURF_TEXTURE
+ | gcvSURF_NO_VIDMEM,
+
+ /* Cacheable surface types with no vidmem node. */
+ gcvSURF_CACHEABLE_BITMAP_NO_VIDMEM = gcvSURF_BITMAP_NO_VIDMEM
+ | gcvSURF_CACHEABLE,
+
+ gcvSURF_CACHEABLE_BITMAP = gcvSURF_BITMAP
+ | gcvSURF_CACHEABLE,
+
+ gcvSURF_TEXTURE_3D = gcvSURF_TEXTURE
+ | gcvSURF_3D
+}
+gceSURF_TYPE;
+
+typedef enum _gceSURF_USAGE
+{
+ gcvSURF_USAGE_UNKNOWN,
+ gcvSURF_USAGE_RESOLVE_AFTER_CPU,
+ gcvSURF_USAGE_RESOLVE_AFTER_3D
+}
+gceSURF_USAGE;
+
+typedef enum _gceSURF_COLOR_SPACE
+{
+ gcvSURF_COLOR_SPACE_UNKNOWN,
+ gcvSURF_COLOR_SPACE_LINEAR,
+ gcvSURF_COLOR_SPACE_NONLINEAR,
+}
+gceSURF_COLOR_SPACE;
+
+typedef enum _gceSURF_COLOR_TYPE
+{
+ gcvSURF_COLOR_UNKNOWN = 0,
+ gcvSURF_COLOR_LINEAR = 0x01,
+ gcvSURF_COLOR_ALPHA_PRE = 0x02,
+}
+gceSURF_COLOR_TYPE;
+
+/* Rotation. */
+typedef enum _gceSURF_ROTATION
+{
+ gcvSURF_0_DEGREE = 0,
+ gcvSURF_90_DEGREE,
+ gcvSURF_180_DEGREE,
+ gcvSURF_270_DEGREE,
+ gcvSURF_FLIP_X,
+ gcvSURF_FLIP_Y,
+
+ gcvSURF_POST_FLIP_X = 0x40000000,
+ gcvSURF_POST_FLIP_Y = 0x80000000,
+}
+gceSURF_ROTATION;
+
+/* Surface flag */
+typedef enum _gceSURF_FLAG
+{
+ /* None flag */
+ gcvSURF_FLAG_NONE = 0x0,
+ /* content is preserved after swap */
+ gcvSURF_FLAG_CONTENT_PRESERVED = 0x1,
+ /* content is updated after swap*/
+ gcvSURF_FLAG_CONTENT_UPDATED = 0x2,
+ /* content is y inverted */
+ gcvSURF_FLAG_CONTENT_YINVERTED = 0x4,
+ /* surface has multiple nodes */
+ gcvSURF_FLAG_MULTI_NODE = 0x8,
+}
+gceSURF_FLAG;
+
+typedef enum _gceMIPMAP_IMAGE_FORMAT
+{
+ gcvUNKNOWN_MIPMAP_IMAGE_FORMAT = -2
+}
+gceMIPMAP_IMAGE_FORMAT;
+
+/* Surface formats.
+** Name rules is from MSB->LSB.
+*/
+typedef enum _gceSURF_FORMAT
+{
+ /* Unknown format. */
+ gcvSURF_UNKNOWN = 0,
+
+ /* Palettized formats. */
+ gcvSURF_INDEX1 = 100,
+ gcvSURF_INDEX4,
+ gcvSURF_INDEX8,
+#if gcdVG_ONLY
+ gcvSURF_INDEX2,
+#endif
+
+ /* RGB formats. */
+ gcvSURF_A2R2G2B2 = 200,
+ gcvSURF_R3G3B2,
+ gcvSURF_A8R3G3B2,
+ gcvSURF_X4R4G4B4,
+ gcvSURF_A4R4G4B4,
+ gcvSURF_R4G4B4A4,
+ gcvSURF_X1R5G5B5,
+ gcvSURF_A1R5G5B5,
+ gcvSURF_R5G5B5A1,
+ gcvSURF_R5G6B5,
+ gcvSURF_R8G8B8,
+ gcvSURF_X8R8G8B8,
+ gcvSURF_A8R8G8B8,
+ gcvSURF_R8G8B8A8,
+ gcvSURF_G8R8G8B8,
+ gcvSURF_R8G8B8G8,
+ gcvSURF_X2R10G10B10,
+ gcvSURF_A2R10G10B10,
+ gcvSURF_R10G10B10A2,
+ gcvSURF_X12R12G12B12,
+ gcvSURF_A12R12G12B12,
+ gcvSURF_X16R16G16B16,
+ gcvSURF_A16R16G16B16,
+ gcvSURF_A32R32G32B32,
+ gcvSURF_R8G8B8X8,
+ gcvSURF_R5G5B5X1,
+ gcvSURF_R4G4B4X4,
+ gcvSURF_X16R16G16B16_2_A8R8G8B8,
+ gcvSURF_A16R16G16B16_2_A8R8G8B8,
+ gcvSURF_A32R32G32B32_2_G32R32F,
+ gcvSURF_A32R32G32B32_4_A8R8G8B8,
+ /* BGR formats. */
+ gcvSURF_A4B4G4R4 = 300,
+ gcvSURF_A1B5G5R5,
+ gcvSURF_B5G6R5,
+ gcvSURF_B8G8R8,
+ gcvSURF_B16G16R16,
+ gcvSURF_X8B8G8R8,
+ gcvSURF_A8B8G8R8,
+ gcvSURF_A2B10G10R10,
+ gcvSURF_X16B16G16R16,
+ gcvSURF_A16B16G16R16,
+ gcvSURF_B32G32R32,
+ gcvSURF_X32B32G32R32,
+ gcvSURF_A32B32G32R32,
+ gcvSURF_B4G4R4A4,
+ gcvSURF_B5G5R5A1,
+ gcvSURF_B8G8R8X8,
+ gcvSURF_B8G8R8A8,
+ gcvSURF_B10G10R10A2,
+ gcvSURF_X4B4G4R4,
+ gcvSURF_X1B5G5R5,
+ gcvSURF_B4G4R4X4,
+ gcvSURF_B5G5R5X1,
+ gcvSURF_X2B10G10R10,
+ gcvSURF_B8G8R8_SNORM,
+ gcvSURF_X8B8G8R8_SNORM,
+ gcvSURF_A8B8G8R8_SNORM,
+ gcvSURF_A8B12G12R12_2_A8R8G8B8,
+
+ /* Compressed formats. */
+ gcvSURF_DXT1 = 400,
+ gcvSURF_DXT2,
+ gcvSURF_DXT3,
+ gcvSURF_DXT4,
+ gcvSURF_DXT5,
+ gcvSURF_CXV8U8,
+ gcvSURF_ETC1,
+ gcvSURF_R11_EAC,
+ gcvSURF_SIGNED_R11_EAC,
+ gcvSURF_RG11_EAC,
+ gcvSURF_SIGNED_RG11_EAC,
+ gcvSURF_RGB8_ETC2,
+ gcvSURF_SRGB8_ETC2,
+ gcvSURF_RGB8_PUNCHTHROUGH_ALPHA1_ETC2,
+ gcvSURF_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2,
+ gcvSURF_RGBA8_ETC2_EAC,
+ gcvSURF_SRGB8_ALPHA8_ETC2_EAC,
+
+ /* YUV formats. */
+ gcvSURF_YUY2 = 500,
+ gcvSURF_UYVY,
+ gcvSURF_YV12,
+ gcvSURF_I420,
+ gcvSURF_NV12,
+ gcvSURF_NV21,
+ gcvSURF_NV16,
+ gcvSURF_NV61,
+ gcvSURF_YVYU,
+ gcvSURF_VYUY,
+ gcvSURF_AYUV,
+ gcvSURF_YUV420_10_ST,
+ gcvSURF_YUV420_TILE_ST,
+ gcvSURF_YUV420_TILE_10_ST,
+ gcvSURF_NV12_10BIT,
+ gcvSURF_NV21_10BIT,
+ gcvSURF_NV16_10BIT,
+ gcvSURF_NV61_10BIT,
+ gcvSURF_P010,
+#if gcdVG_ONLY
+ gcvSURF_AYUY2,
+ gcvSURF_ANV12,
+ gcvSURF_ANV16,
+#endif
+
+ /* Depth formats. */
+ gcvSURF_D16 = 600,
+ gcvSURF_D24S8,
+ gcvSURF_D32,
+ gcvSURF_D24X8,
+ gcvSURF_D32F,
+ gcvSURF_S8D32F,
+ gcvSURF_S8D32F_1_G32R32F,
+ gcvSURF_S8D32F_2_A8R8G8B8,
+ gcvSURF_D24S8_1_A8R8G8B8,
+ gcvSURF_S8,
+ gcvSURF_X24S8,
+ gcvSURF_X24S8_1_A8R8G8B8,
+
+ /* Alpha formats. */
+ gcvSURF_A4 = 700,
+ gcvSURF_A8,
+ gcvSURF_A12,
+ gcvSURF_A16,
+ gcvSURF_A32,
+ gcvSURF_A1,
+
+ gcvSURF_A8_1_A8R8G8B8,
+
+ /* Luminance formats. */
+ gcvSURF_L4 = 800,
+ gcvSURF_L8,
+ gcvSURF_L12,
+ gcvSURF_L16,
+ gcvSURF_L32,
+ gcvSURF_L1,
+ gcvSURF_L8_RAW,
+
+ /* Alpha/Luminance formats. */
+ gcvSURF_A4L4 = 900,
+ gcvSURF_A2L6,
+ gcvSURF_A8L8,
+ gcvSURF_A4L12,
+ gcvSURF_A12L12,
+ gcvSURF_A16L16,
+
+ gcvSURF_A8L8_1_A8R8G8B8,
+
+ gcvSURF_A8L8_RAW,
+
+ /* Bump formats. */
+ gcvSURF_L6V5U5 = 1000,
+ gcvSURF_V8U8,
+ gcvSURF_X8L8V8U8,
+ gcvSURF_Q8W8V8U8,
+ gcvSURF_A2W10V10U10,
+ gcvSURF_V16U16,
+ gcvSURF_Q16W16V16U16,
+
+ /* R/RG/RA formats. */
+ gcvSURF_R8 = 1100,
+ gcvSURF_X8R8,
+ gcvSURF_G8R8,
+ gcvSURF_X8G8R8,
+ gcvSURF_A8R8,
+ gcvSURF_R16,
+ gcvSURF_X16R16,
+ gcvSURF_G16R16,
+ gcvSURF_X16G16R16,
+ gcvSURF_A16R16,
+ gcvSURF_R32,
+ gcvSURF_X32R32,
+ gcvSURF_G32R32,
+ gcvSURF_X32G32R32,
+ gcvSURF_A32R32,
+ gcvSURF_RG16,
+ gcvSURF_R8_SNORM,
+ gcvSURF_G8R8_SNORM,
+
+ gcvSURF_R8_1_X8R8G8B8,
+ gcvSURF_G8R8_1_X8R8G8B8,
+
+ /* Floating point formats. */
+ gcvSURF_R16F = 1200,
+ gcvSURF_X16R16F,
+ gcvSURF_G16R16F,
+ gcvSURF_X16G16R16F,
+ gcvSURF_B16G16R16F,
+ gcvSURF_X16B16G16R16F,
+ gcvSURF_A16B16G16R16F,
+ gcvSURF_R32F,
+ gcvSURF_X32R32F,
+ gcvSURF_G32R32F,
+ gcvSURF_X32G32R32F,
+ gcvSURF_B32G32R32F,
+ gcvSURF_X32B32G32R32F,
+ gcvSURF_A32B32G32R32F,
+ gcvSURF_A16F,
+ gcvSURF_L16F,
+ gcvSURF_A16L16F,
+ gcvSURF_A16R16F,
+ gcvSURF_A32F,
+ gcvSURF_L32F,
+ gcvSURF_A32L32F,
+ gcvSURF_A32R32F,
+ gcvSURF_E5B9G9R9,
+ gcvSURF_B10G11R11F,
+
+ gcvSURF_X16B16G16R16F_2_A8R8G8B8,
+ gcvSURF_A16B16G16R16F_2_A8R8G8B8,
+ gcvSURF_A16B16G16R16F_2_G16R16F,
+ gcvSURF_G32R32F_2_A8R8G8B8,
+ gcvSURF_X32B32G32R32F_2_G32R32F,
+ gcvSURF_A32B32G32R32F_2_G32R32F,
+ gcvSURF_X32B32G32R32F_4_A8R8G8B8,
+ gcvSURF_A32B32G32R32F_4_A8R8G8B8,
+
+ gcvSURF_R16F_1_A4R4G4B4,
+ gcvSURF_G16R16F_1_A8R8G8B8,
+ gcvSURF_B16G16R16F_2_A8R8G8B8,
+
+ gcvSURF_R32F_1_A8R8G8B8,
+ gcvSURF_B32G32R32F_3_A8R8G8B8,
+ gcvSURF_B10G11R11F_1_A8R8G8B8,
+
+ gcvSURF_A32F_1_R32F,
+ gcvSURF_L32F_1_R32F,
+ gcvSURF_A32L32F_1_G32R32F,
+
+
+
+ /* sRGB format. */
+ gcvSURF_SBGR8 = 1400,
+ gcvSURF_A8_SBGR8,
+ gcvSURF_X8_SBGR8,
+ gcvSURF_A8_SRGB8,
+ gcvSURF_X8_SRGB8,
+
+ /* Integer formats. */
+ gcvSURF_R8I = 1500,
+ gcvSURF_R8UI,
+ gcvSURF_R16I,
+ gcvSURF_R16UI,
+ gcvSURF_R32I,
+ gcvSURF_R32UI,
+ gcvSURF_X8R8I,
+ gcvSURF_G8R8I,
+ gcvSURF_X8R8UI,
+ gcvSURF_G8R8UI,
+ gcvSURF_X16R16I,
+ gcvSURF_G16R16I,
+ gcvSURF_X16R16UI,
+ gcvSURF_G16R16UI,
+ gcvSURF_X32R32I,
+ gcvSURF_G32R32I,
+ gcvSURF_X32R32UI,
+ gcvSURF_G32R32UI,
+ gcvSURF_X8G8R8I,
+ gcvSURF_B8G8R8I,
+ gcvSURF_X8G8R8UI,
+ gcvSURF_B8G8R8UI,
+ gcvSURF_X16G16R16I,
+ gcvSURF_B16G16R16I,
+ gcvSURF_X16G16R16UI,
+ gcvSURF_B16G16R16UI,
+ gcvSURF_X32G32R32I,
+ gcvSURF_B32G32R32I,
+ gcvSURF_X32G32R32UI,
+ gcvSURF_B32G32R32UI,
+ gcvSURF_X8B8G8R8I,
+ gcvSURF_A8B8G8R8I,
+ gcvSURF_X8B8G8R8UI,
+ gcvSURF_A8B8G8R8UI,
+ gcvSURF_X16B16G16R16I,
+ gcvSURF_A16B16G16R16I,
+ gcvSURF_X16B16G16R16UI,
+ gcvSURF_A16B16G16R16UI,
+ gcvSURF_X32B32G32R32I,
+ gcvSURF_A32B32G32R32I,
+ gcvSURF_X32B32G32R32UI,
+ gcvSURF_A32B32G32R32UI,
+ gcvSURF_A2B10G10R10UI,
+ gcvSURF_G32R32I_2_A8R8G8B8,
+ gcvSURF_G32R32I_1_G32R32F,
+ gcvSURF_G32R32UI_2_A8R8G8B8,
+ gcvSURF_G32R32UI_1_G32R32F,
+ gcvSURF_X16B16G16R16I_2_A8R8G8B8,
+ gcvSURF_X16B16G16R16I_1_G32R32F,
+ gcvSURF_A16B16G16R16I_2_A8R8G8B8,
+ gcvSURF_A16B16G16R16I_1_G32R32F,
+ gcvSURF_X16B16G16R16UI_2_A8R8G8B8,
+ gcvSURF_X16B16G16R16UI_1_G32R32F,
+ gcvSURF_A16B16G16R16UI_2_A8R8G8B8,
+ gcvSURF_A16B16G16R16UI_1_G32R32F,
+ gcvSURF_X32B32G32R32I_2_G32R32I,
+ gcvSURF_A32B32G32R32I_2_G32R32I,
+ gcvSURF_A32B32G32R32I_2_G32R32F,
+ gcvSURF_X32B32G32R32I_3_A8R8G8B8,
+ gcvSURF_A32B32G32R32I_4_A8R8G8B8,
+ gcvSURF_X32B32G32R32UI_2_G32R32UI,
+ gcvSURF_A32B32G32R32UI_2_G32R32UI,
+ gcvSURF_A32B32G32R32UI_2_G32R32F,
+ gcvSURF_X32B32G32R32UI_3_A8R8G8B8,
+ gcvSURF_A32B32G32R32UI_4_A8R8G8B8,
+ gcvSURF_A2B10G10R10UI_1_A8R8G8B8,
+ gcvSURF_A8B8G8R8I_1_A8R8G8B8,
+ gcvSURF_A8B8G8R8UI_1_A8R8G8B8,
+ gcvSURF_R8I_1_A4R4G4B4,
+ gcvSURF_R8UI_1_A4R4G4B4,
+ gcvSURF_R16I_1_A4R4G4B4,
+ gcvSURF_R16UI_1_A4R4G4B4,
+ gcvSURF_R32I_1_A8R8G8B8,
+ gcvSURF_R32UI_1_A8R8G8B8,
+ gcvSURF_X8R8I_1_A4R4G4B4,
+ gcvSURF_X8R8UI_1_A4R4G4B4,
+ gcvSURF_G8R8I_1_A4R4G4B4,
+ gcvSURF_G8R8UI_1_A4R4G4B4,
+ gcvSURF_X16R16I_1_A4R4G4B4,
+ gcvSURF_X16R16UI_1_A4R4G4B4,
+ gcvSURF_G16R16I_1_A8R8G8B8,
+ gcvSURF_G16R16UI_1_A8R8G8B8,
+ gcvSURF_X32R32I_1_A8R8G8B8,
+ gcvSURF_X32R32UI_1_A8R8G8B8,
+ gcvSURF_X8G8R8I_1_A4R4G4B4,
+ gcvSURF_X8G8R8UI_1_A4R4G4B4,
+ gcvSURF_B8G8R8I_1_A8R8G8B8,
+ gcvSURF_B8G8R8UI_1_A8R8G8B8,
+ gcvSURF_B16G16R16I_2_A8R8G8B8,
+ gcvSURF_B16G16R16I_1_G32R32F,
+ gcvSURF_B16G16R16UI_2_A8R8G8B8,
+ gcvSURF_B16G16R16UI_1_G32R32F,
+ gcvSURF_B32G32R32I_3_A8R8G8B8,
+ gcvSURF_B32G32R32UI_3_A8R8G8B8,
+ gcvSURF_A16B16G16R16_2_A8R8G8B8,
+ gcvSURF_R8G8B8_1_A8R8G8B8,
+ gcvSURF_G16R16_1_A8R8G8B8,
+ gcvSURF_A2B10G10R10_1_A8R8G8B8,
+ gcvSURF_A2R10G10B10_1_A8R8G8B8,
+ gcvSURF_A2W10V10U10_1_A8R8G8B8,
+
+ /* ASTC formats. */
+ gcvSURF_ASTC4x4 = 1600,
+ gcvSURF_ASTC5x4,
+ gcvSURF_ASTC5x5,
+ gcvSURF_ASTC6x5,
+ gcvSURF_ASTC6x6,
+ gcvSURF_ASTC8x5,
+ gcvSURF_ASTC8x6,
+ gcvSURF_ASTC8x8,
+ gcvSURF_ASTC10x5,
+ gcvSURF_ASTC10x6,
+ gcvSURF_ASTC10x8,
+ gcvSURF_ASTC10x10,
+ gcvSURF_ASTC12x10,
+ gcvSURF_ASTC12x12,
+ gcvSURF_ASTC4x4_SRGB,
+ gcvSURF_ASTC5x4_SRGB,
+ gcvSURF_ASTC5x5_SRGB,
+ gcvSURF_ASTC6x5_SRGB,
+ gcvSURF_ASTC6x6_SRGB,
+ gcvSURF_ASTC8x5_SRGB,
+ gcvSURF_ASTC8x6_SRGB,
+ gcvSURF_ASTC8x8_SRGB,
+ gcvSURF_ASTC10x5_SRGB,
+ gcvSURF_ASTC10x6_SRGB,
+ gcvSURF_ASTC10x8_SRGB,
+ gcvSURF_ASTC10x10_SRGB,
+ gcvSURF_ASTC12x10_SRGB,
+ gcvSURF_ASTC12x12_SRGB,
+
+ /* Recompile format*/
+ gcvSURF_L16_1_A4R4G4B4 = 1700,
+ gcvSURF_V16U16_1_A8R8G8B8,
+ gcvSURF_Q8W8V8U8_1_A8R8G8B8,
+ gcvSURF_X8L8V8U8_1_A8R8G8B8,
+ gcvSURF_R3G3B2_1_A8R8G8B8,
+ gcvSURF_A8R3G3B2_1_A8R8G8B8,
+ gcvSURF_W11V11U10_1_A8R8G8B8,
+ gcvSURF_Q16W16V16U16_2_A8R8G8B8,
+ gcvSURF_W11V11U10,
+ gcvSURF_V8U8_1_A4R4G4B4,
+ gcvSURF_A8B8G8R8_1_A8R8G8B8,
+ gcvSURF_A32R32G32B32_1_A8R8G8B8,
+ gcvSURF_X16B16G16R16F_1_A8R8G8B8,
+ gcvSURF_A16B16G16R16F_1_A8R8G8B8,
+ gcvSURF_G32R32F_1_A8R8G8B8,
+ gcvSURF_X32B32G32R32F_1_A8R8G8B8,
+ gcvSURF_A32B32G32R32F_1_A8R8G8B8,
+ gcvSURF_G32R32I_1_A8R8G8B8,
+ gcvSURF_G32R32UI_1_A8R8G8B8,
+ gcvSURF_A32B32G32R32I_1_A8R8G8B8,
+ gcvSURF_A32B32G32R32UI_1_A8R8G8B8,
+ gcvSURF_Q16W16V16U16_1_A8R8G8B8,
+ gcvSURF_A16B16G16R16_1_A8R8G8B8,
+ gcvSURF_FORMAT_COUNT
+}
+gceSURF_FORMAT;
+
+typedef enum _gceIMAGE_MEM_TYPE
+{
+ gcvIMAGE_MEM_DEFAULT,
+ gcvIMAGE_MEM_HOST_PTR,
+ gcvIMAGE_MEM_HOST_PTR_UNCACHED,
+}
+gceIMAGE_MEM_TYPE;
+
+typedef enum _gceSURF_YUV_COLOR_SPACE
+{
+ gcvSURF_ITU_REC601,
+ gcvSURF_ITU_REC709,
+ gcvSURF_ITU_REC2020,
+}
+gceSURF_YUV_COLOR_SPACE;
+
+typedef enum _gceSURF_YUV_SAMPLE_RANGE
+{
+ gcvSURF_YUV_FULL_RANGE,
+ gcvSURF_YUV_NARROW_RANGE,
+}
+gceSURF_YUV_SAMPLE_RANGE;
+
+typedef enum _gceSURF_YUV_CHROMA_SITING
+{
+ gcvSURF_YUV_CHROMA_SITING_0,
+ gcvSURF_YUV_CHROMA_SITING_0_5,
+}
+gceSURF_YUV_CHROMA_SITING;
+
+typedef enum _gceSURF_INFO_TYPE
+{
+ gcvSURF_INFO_UNKNOWN = 0,
+ gcvSURF_INFO_LAYERSIZE = 1,
+ gcvSURF_INFO_SLICESIZE = 2,
+}
+gceSURF_INFO_TYPE;
+
+/* Format modifiers. */
+typedef enum _gceSURF_FORMAT_MODE
+{
+ gcvSURF_FORMAT_OCL = 0x80000000,
+ gcvSURF_FORMAT_PATCH_BORDER = 0x40000000,
+}
+gceSURF_FORMAT_MODE;
+
+/* Pixel swizzle modes. */
+typedef enum _gceSURF_SWIZZLE
+{
+ gcvSURF_NOSWIZZLE = 0,
+ gcvSURF_ARGB,
+ gcvSURF_ABGR,
+ gcvSURF_RGBA,
+ gcvSURF_BGRA
+}
+gceSURF_SWIZZLE;
+
+/* Transparency modes. */
+typedef enum _gceSURF_TRANSPARENCY
+{
+ /* Valid only for PE 1.0 */
+ gcvSURF_OPAQUE = 0,
+ gcvSURF_SOURCE_MATCH,
+ gcvSURF_SOURCE_MASK,
+ gcvSURF_PATTERN_MASK,
+}
+gceSURF_TRANSPARENCY;
+
+/* Surface Alignment. */
+typedef enum _gceSURF_ALIGNMENT
+{
+ gcvSURF_FOUR = 0,
+ gcvSURF_SIXTEEN,
+ gcvSURF_SUPER_TILED,
+ gcvSURF_SPLIT_TILED,
+ gcvSURF_SPLIT_SUPER_TILED
+}
+gceSURF_ALIGNMENT;
+
+/* Surface Addressing. */
+typedef enum _gceSURF_ADDRESSING
+{
+ gcvSURF_NO_STRIDE_TILED = 0,
+ gcvSURF_NO_STRIDE_LINEAR,
+ gcvSURF_STRIDE_TILED,
+ gcvSURF_STRIDE_LINEAR
+}
+gceSURF_ADDRESSING;
+
+/* Transparency modes. */
+typedef enum _gce2D_TRANSPARENCY
+{
+ /* Valid only for PE 2.0 */
+ gcv2D_OPAQUE = 0,
+ gcv2D_KEYED,
+ gcv2D_MASKED
+}
+gce2D_TRANSPARENCY;
+
+/* Mono packing modes. */
+typedef enum _gceSURF_MONOPACK
+{
+ gcvSURF_PACKED8 = 0,
+ gcvSURF_PACKED16,
+ gcvSURF_PACKED32,
+ gcvSURF_UNPACKED,
+}
+gceSURF_MONOPACK;
+
+/* Blending modes. */
+typedef enum _gceSURF_BLEND_MODE
+{
+ /* Porter-Duff blending modes. */
+ /* Fsrc Fdst */
+ gcvBLEND_CLEAR = 0, /* 0 0 */
+ gcvBLEND_SRC, /* 1 0 */
+ gcvBLEND_DST, /* 0 1 */
+ gcvBLEND_SRC_OVER_DST, /* 1 1 - Asrc */
+ gcvBLEND_DST_OVER_SRC, /* 1 - Adst 1 */
+ gcvBLEND_SRC_IN_DST, /* Adst 0 */
+ gcvBLEND_DST_IN_SRC, /* 0 Asrc */
+ gcvBLEND_SRC_OUT_DST, /* 1 - Adst 0 */
+ gcvBLEND_DST_OUT_SRC, /* 0 1 - Asrc */
+ gcvBLEND_SRC_ATOP_DST, /* Adst 1 - Asrc */
+ gcvBLEND_DST_ATOP_SRC, /* 1 - Adst Asrc */
+ gcvBLEND_SRC_XOR_DST, /* 1 - Adst 1 - Asrc */
+
+ /* Special blending modes. */
+ gcvBLEND_SET, /* DST = 1 */
+ gcvBLEND_SUB /* DST = DST * (1 - SRC) */
+}
+gceSURF_BLEND_MODE;
+
+/* Per-pixel alpha modes. */
+typedef enum _gceSURF_PIXEL_ALPHA_MODE
+{
+ gcvSURF_PIXEL_ALPHA_STRAIGHT = 0,
+ gcvSURF_PIXEL_ALPHA_INVERSED
+}
+gceSURF_PIXEL_ALPHA_MODE;
+
+/* Global alpha modes. */
+typedef enum _gceSURF_GLOBAL_ALPHA_MODE
+{
+ gcvSURF_GLOBAL_ALPHA_OFF = 0,
+ gcvSURF_GLOBAL_ALPHA_ON,
+ gcvSURF_GLOBAL_ALPHA_SCALE
+}
+gceSURF_GLOBAL_ALPHA_MODE;
+
+/* Color component modes for alpha blending. */
+typedef enum _gceSURF_PIXEL_COLOR_MODE
+{
+ gcvSURF_COLOR_STRAIGHT = 0,
+ gcvSURF_COLOR_MULTIPLY
+}
+gceSURF_PIXEL_COLOR_MODE;
+
+/* Color component modes for alpha blending. */
+typedef enum _gce2D_PIXEL_COLOR_MULTIPLY_MODE
+{
+ gcv2D_COLOR_MULTIPLY_DISABLE = 0,
+ gcv2D_COLOR_MULTIPLY_ENABLE
+}
+gce2D_PIXEL_COLOR_MULTIPLY_MODE;
+
+/* Color component modes for alpha blending. */
+typedef enum _gce2D_GLOBAL_COLOR_MULTIPLY_MODE
+{
+ gcv2D_GLOBAL_COLOR_MULTIPLY_DISABLE = 0,
+ gcv2D_GLOBAL_COLOR_MULTIPLY_ALPHA,
+ gcv2D_GLOBAL_COLOR_MULTIPLY_COLOR
+}
+gce2D_GLOBAL_COLOR_MULTIPLY_MODE;
+
+/* Alpha blending factor modes. */
+typedef enum _gceSURF_BLEND_FACTOR_MODE
+{
+ gcvSURF_BLEND_ZERO = 0,
+ gcvSURF_BLEND_ONE,
+ gcvSURF_BLEND_STRAIGHT,
+ gcvSURF_BLEND_INVERSED,
+ gcvSURF_BLEND_COLOR,
+ gcvSURF_BLEND_COLOR_INVERSED,
+ gcvSURF_BLEND_SRC_ALPHA_SATURATED,
+ gcvSURF_BLEND_STRAIGHT_NO_CROSS,
+ gcvSURF_BLEND_INVERSED_NO_CROSS,
+ gcvSURF_BLEND_COLOR_NO_CROSS,
+ gcvSURF_BLEND_COLOR_INVERSED_NO_CROSS,
+ gcvSURF_BLEND_SRC_ALPHA_SATURATED_CROSS
+}
+gceSURF_BLEND_FACTOR_MODE;
+
+/* Alpha blending porter duff rules. */
+typedef enum _gce2D_PORTER_DUFF_RULE
+{
+ gcvPD_CLEAR = 0,
+ gcvPD_SRC,
+ gcvPD_SRC_OVER,
+ gcvPD_DST_OVER,
+ gcvPD_SRC_IN,
+ gcvPD_DST_IN,
+ gcvPD_SRC_OUT,
+ gcvPD_DST_OUT,
+ gcvPD_SRC_ATOP,
+ gcvPD_DST_ATOP,
+ gcvPD_ADD,
+ gcvPD_XOR,
+ gcvPD_DST
+}
+gce2D_PORTER_DUFF_RULE;
+
+/* Alpha blending factor modes. */
+typedef enum _gce2D_YUV_COLOR_MODE
+{
+ gcv2D_YUV_601= 0,
+ gcv2D_YUV_709,
+ gcv2D_YUV_USER_DEFINED,
+ gcv2D_YUV_USER_DEFINED_CLAMP,
+
+ /* Default setting is for src. gcv2D_YUV_DST
+ can be ORed to set dst.
+ */
+ gcv2D_YUV_DST = 0x80000000,
+}
+gce2D_YUV_COLOR_MODE;
+
+/* Nature rotation rules. */
+typedef enum _gce2D_NATURE_ROTATION
+{
+ gcvNR_0_DEGREE = 0,
+ gcvNR_LEFT_90_DEGREE,
+ gcvNR_RIGHT_90_DEGREE,
+ gcvNR_180_DEGREE,
+ gcvNR_FLIP_X,
+ gcvNR_FLIP_Y,
+ gcvNR_TOTAL_RULE,
+}
+gce2D_NATURE_ROTATION;
+
+typedef enum _gce2D_COMMAND
+{
+ gcv2D_CLEAR = 0,
+ gcv2D_LINE,
+ gcv2D_BLT,
+ gcv2D_STRETCH,
+ gcv2D_HOR_FILTER,
+ gcv2D_VER_FILTER,
+ gcv2D_MULTI_SOURCE_BLT,
+ gcv2D_FILTER_BLT,
+}
+gce2D_COMMAND;
+
+typedef enum _gce2D_TILE_STATUS_CONFIG
+{
+ gcv2D_TSC_DISABLE = 0,
+ gcv2D_TSC_ENABLE = 0x00000001,
+ gcv2D_TSC_COMPRESSED = 0x00000002,
+ gcv2D_TSC_DOWN_SAMPLER = 0x00000004,
+ gcv2D_TSC_2D_COMPRESSED = 0x00000008,
+
+ gcv2D_TSC_DEC_COMPRESSED = 0x00000020,
+ gcv2D_TSC_DEC_TPC = 0x00000040,
+ gcv2D_TSC_DEC_TPC_COMPRESSED = 0x00000080,
+
+ gcv2D_TSC_V4_COMPRESSED = 0x00000100,
+ gcv2D_TSC_V4_COMPRESSED_256B = 0x00000200 | gcv2D_TSC_V4_COMPRESSED,
+
+ gcv2D_TSC_DEC_TPC_TILED = gcv2D_TSC_DEC_COMPRESSED | gcv2D_TSC_DEC_TPC,
+ gcv2D_TSC_DEC_TPC_TILED_COMPRESSED = gcv2D_TSC_DEC_TPC_TILED | gcv2D_TSC_DEC_TPC_COMPRESSED,
+
+ gcv2D_TSC_TPC_COMPRESSED = 0x00001000,
+ gcv2D_TSC_TPC_COMPRESSED_V10 = gcv2D_TSC_TPC_COMPRESSED | 0x00000400,
+ gcv2D_TSC_TPC_COMPRESSED_V11 = gcv2D_TSC_TPC_COMPRESSED | 0x00000800,
+}
+gce2D_TILE_STATUS_CONFIG;
+
+typedef enum _gce2D_QUERY
+{
+ gcv2D_QUERY_RGB_ADDRESS_MIN_ALIGN = 0,
+ gcv2D_QUERY_RGB_STRIDE_MIN_ALIGN,
+ gcv2D_QUERY_YUV_ADDRESS_MIN_ALIGN,
+ gcv2D_QUERY_YUV_STRIDE_MIN_ALIGN,
+}
+gce2D_QUERY;
+
+typedef enum _gce2D_SUPER_TILE_VERSION
+{
+ gcv2D_SUPER_TILE_VERSION_V1 = 1,
+ gcv2D_SUPER_TILE_VERSION_V2 = 2,
+ gcv2D_SUPER_TILE_VERSION_V3 = 3,
+}
+gce2D_SUPER_TILE_VERSION;
+
+typedef enum _gce2D_STATE
+{
+ gcv2D_STATE_SPECIAL_FILTER_MIRROR_MODE = 1,
+ gcv2D_STATE_SUPER_TILE_VERSION,
+ gcv2D_STATE_EN_GAMMA,
+ gcv2D_STATE_DE_GAMMA,
+ gcv2D_STATE_MULTI_SRC_BLIT_UNIFIED_DST_RECT,
+ gcv2D_STATE_MULTI_SRC_BLIT_BILINEAR_FILTER,
+ gcv2D_STATE_PROFILE_ENABLE,
+ gcv2D_STATE_XRGB_ENABLE,
+
+ gcv2D_STATE_ARRAY_EN_GAMMA = 0x10001,
+ gcv2D_STATE_ARRAY_DE_GAMMA,
+ gcv2D_STATE_ARRAY_CSC_YUV_TO_RGB,
+ gcv2D_STATE_ARRAY_CSC_RGB_TO_YUV,
+
+ gcv2D_STATE_DEC_TPC_NV12_10BIT = 0x20001,
+ gcv2D_STATE_ARRAY_YUV_SRC_TILE_STATUS_ADDR,
+ gcv2D_STATE_ARRAY_YUV_DST_TILE_STATUS_ADDR,
+}
+gce2D_STATE;
+
+typedef enum _gce2D_STATE_PROFILE
+{
+ gcv2D_STATE_PROFILE_NONE = 0x0,
+ gcv2D_STATE_PROFILE_COMMAND = 0x1,
+ gcv2D_STATE_PROFILE_SURFACE = 0x2,
+ gcv2D_STATE_PROFILE_ALL = 0xFFFF,
+}
+gce2D_STATE_PROFILE;
+
+/* Texture object types */
+typedef enum _gceTEXTURE_TYPE
+{
+ gcvTEXTURE_UNKNOWN = 0,
+ gcvTEXTURE_1D,
+ gcvTEXTURE_2D,
+ gcvTEXTURE_3D,
+ gcvTEXTURE_CUBEMAP,
+ gcvTEXTURE_1D_ARRAY,
+ gcvTEXTURE_2D_ARRAY,
+ gcvTEXTURE_2D_MS,
+ gcvTEXTURE_2D_MS_ARRAY,
+ gcvTEXTURE_CUBEMAP_ARRAY,
+ gcvTEXTURE_EXTERNAL
+}
+gceTEXTURE_TYPE;
+
+#if gcdENABLE_3D
+/* Texture functions. */
+typedef enum _gceTEXTURE_FUNCTION
+{
+ gcvTEXTURE_DUMMY = 0,
+ gcvTEXTURE_REPLACE = 0,
+ gcvTEXTURE_MODULATE,
+ gcvTEXTURE_ADD,
+ gcvTEXTURE_ADD_SIGNED,
+ gcvTEXTURE_INTERPOLATE,
+ gcvTEXTURE_SUBTRACT,
+ gcvTEXTURE_DOT3
+}
+gceTEXTURE_FUNCTION;
+
+/* Texture sources. */
+typedef enum _gceTEXTURE_SOURCE
+{
+ gcvCOLOR_FROM_TEXTURE = 0,
+ gcvCOLOR_FROM_CONSTANT_COLOR,
+ gcvCOLOR_FROM_PRIMARY_COLOR,
+ gcvCOLOR_FROM_PREVIOUS_COLOR
+}
+gceTEXTURE_SOURCE;
+
+/* Texture source channels. */
+typedef enum _gceTEXTURE_CHANNEL
+{
+ gcvFROM_COLOR = 0,
+ gcvFROM_ONE_MINUS_COLOR,
+ gcvFROM_ALPHA,
+ gcvFROM_ONE_MINUS_ALPHA
+}
+gceTEXTURE_CHANNEL;
+#endif /* gcdENABLE_3D */
+
+/* Filter types. */
+typedef enum _gceFILTER_TYPE
+{
+ gcvFILTER_SYNC = 0,
+ gcvFILTER_BLUR,
+ gcvFILTER_USER
+}
+gceFILTER_TYPE;
+
+/* Filter pass types. */
+typedef enum _gceFILTER_PASS_TYPE
+{
+ gcvFILTER_HOR_PASS = 0,
+ gcvFILTER_VER_PASS
+}
+gceFILTER_PASS_TYPE;
+
+/* Endian hints. */
+typedef enum _gceENDIAN_HINT
+{
+ gcvENDIAN_NO_SWAP = 0,
+ gcvENDIAN_SWAP_WORD = 1,
+ gcvENDIAN_SWAP_DWORD = 2,
+ gcvENDIAN_SWAP_QWORD = 3,
+}
+gceENDIAN_HINT;
+
+/* Tiling modes. */
+typedef enum _gceTILING
+{
+ gcvINVALIDTILED = 0x0, /* Invalid tiling */
+ /* Tiling basic modes enum'ed in power of 2. */
+ gcvLINEAR = 0x1, /* No tiling. */
+ gcvTILED = 0x2, /* 4x4 tiling. */
+ gcvSUPERTILED = 0x4, /* 64x64 tiling. */
+ gcvMINORTILED = 0x8, /* 2x2 tiling. */
+
+ /* Tiling special layouts. */
+ gcvTILING_SPLIT_BUFFER = 0x10,
+ gcvTILING_X_MAJOR = 0x20,
+ gcvTILING_Y_MAJOR = 0x40,
+ gcvTILING_SWAP = 0x80,
+
+ /* Tiling combination layouts. */
+ gcvMULTI_TILED = gcvTILED
+ | gcvTILING_SPLIT_BUFFER,
+
+ gcvMULTI_SUPERTILED = gcvSUPERTILED
+ | gcvTILING_SPLIT_BUFFER,
+
+ gcvYMAJOR_SUPERTILED = gcvSUPERTILED
+ | gcvTILING_Y_MAJOR,
+
+ gcvTILED_8X4 = 0x0100,
+ gcvTILED_4X8 = 0x0100 | gcvTILING_SWAP,
+ gcvTILED_8X8 = 0x0200,
+ gcvTILED_16X4 = 0x0400,
+ gcvTILED_32X4 = 0x0800,
+ gcvTILED_64X4 = 0x1000,
+
+ gcvTILED_8X8_XMAJOR = gcvTILED_8X8 | gcvTILING_X_MAJOR,
+ gcvTILED_8X8_YMAJOR = gcvTILED_8X8 | gcvTILING_Y_MAJOR,
+
+ gcvSUPERTILED_128B = 0x10000 | gcvSUPERTILED,
+ gcvSUPERTILED_256B = 0x20000 | gcvSUPERTILED,
+}
+gceTILING;
+
+typedef enum _gceCACHE_MODE
+{
+ gcvCACHE_NONE,
+ gcvCACHE_128,
+ gcvCACHE_256,
+}
+gceCACHE_MODE;
+
+#define DEFAULT_CACHE_MODE gcvCACHE_256
+
+/* 2D pattern type. */
+typedef enum _gce2D_PATTERN
+{
+ gcv2D_PATTERN_SOLID = 0,
+ gcv2D_PATTERN_MONO,
+ gcv2D_PATTERN_COLOR,
+ gcv2D_PATTERN_INVALID
+}
+gce2D_PATTERN;
+
+/* 2D source type. */
+typedef enum _gce2D_SOURCE
+{
+ gcv2D_SOURCE_MASKED = 0,
+ gcv2D_SOURCE_MONO,
+ gcv2D_SOURCE_COLOR,
+ gcv2D_SOURCE_INVALID
+}
+gce2D_SOURCE;
+
+/* Pipes. */
+typedef enum _gcePIPE_SELECT
+{
+ gcvPIPE_INVALID = ~0,
+ gcvPIPE_3D = 0,
+ gcvPIPE_2D
+}
+gcePIPE_SELECT;
+
+/* Hardware type. */
+typedef enum _gceHARDWARE_TYPE
+{
+ gcvHARDWARE_INVALID,
+ gcvHARDWARE_3D,
+ gcvHARDWARE_2D,
+ gcvHARDWARE_VG,
+ gcvHARDWARE_3D2D,
+ gcvHARDWARE_NUM_TYPES,
+}
+gceHARDWARE_TYPE;
+
+#define gcdCHIP_COUNT gcvCORE_COUNT
+
+typedef enum _gceMMU_MODE
+{
+ gcvMMU_MODE_1K,
+ gcvMMU_MODE_4K,
+} gceMMU_MODE;
+
+/* User signal command codes. */
+typedef enum _gceUSER_SIGNAL_COMMAND_CODES
+{
+ gcvUSER_SIGNAL_CREATE,
+ gcvUSER_SIGNAL_DESTROY,
+ gcvUSER_SIGNAL_SIGNAL,
+ gcvUSER_SIGNAL_WAIT,
+ gcvUSER_SIGNAL_MAP,
+ gcvUSER_SIGNAL_UNMAP,
+}
+gceUSER_SIGNAL_COMMAND_CODES;
+
+/* Shared buffer command codes. */
+typedef enum _gceSHBUF_COMMAND_CODES
+{
+ gcvSHBUF_CREATE,
+ gcvSHBUF_DESTROY,
+ gcvSHBUF_MAP,
+ gcvSHBUF_WRITE,
+ gcvSHBUF_READ,
+}
+gceSHBUF_COMMAND_CODES;
+
+/* Event locations. */
+typedef enum _gceKERNEL_WHERE
+{
+ gcvKERNEL_COMMAND,
+ gcvKERNEL_VERTEX,
+ gcvKERNEL_TRIANGLE,
+ gcvKERNEL_TEXTURE,
+ gcvKERNEL_PIXEL,
+ gcvKERNEL_BLT,
+}
+gceKERNEL_WHERE;
+
+#if gcdENABLE_VG
+/* Hardware blocks. */
+typedef enum _gceBLOCK
+{
+ gcvBLOCK_COMMAND,
+ gcvBLOCK_TESSELLATOR,
+ gcvBLOCK_TESSELLATOR2,
+ gcvBLOCK_TESSELLATOR3,
+ gcvBLOCK_RASTER,
+ gcvBLOCK_VG,
+ gcvBLOCK_VG2,
+ gcvBLOCK_VG3,
+ gcvBLOCK_PIXEL,
+
+ /* Number of defined blocks. */
+ gcvBLOCK_COUNT
+}
+gceBLOCK;
+#endif
+
+/* gcdDUMP message type. */
+typedef enum _gceDEBUG_MESSAGE_TYPE
+{
+ gcvMESSAGE_TEXT,
+ gcvMESSAGE_DUMP
+}
+gceDEBUG_MESSAGE_TYPE;
+
+/* Shading format. */
+typedef enum _gceSHADING
+{
+ gcvSHADING_SMOOTH,
+ gcvSHADING_FLAT_D3D,
+ gcvSHADING_FLAT_OPENGL,
+}
+gceSHADING;
+
+/* Culling modes. */
+typedef enum _gceCULL
+{
+ gcvCULL_NONE,
+ gcvCULL_CCW,
+ gcvCULL_CW,
+}
+gceCULL;
+
+/* Fill modes. */
+typedef enum _gceFILL
+{
+ gcvFILL_POINT,
+ gcvFILL_WIRE_FRAME,
+ gcvFILL_SOLID,
+}
+gceFILL;
+
+/* Compare modes. */
+typedef enum _gceCOMPARE
+{
+ gcvCOMPARE_INVALID = 0,
+ gcvCOMPARE_NEVER,
+ gcvCOMPARE_NOT_EQUAL,
+ gcvCOMPARE_LESS,
+ gcvCOMPARE_LESS_OR_EQUAL,
+ gcvCOMPARE_EQUAL,
+ gcvCOMPARE_GREATER,
+ gcvCOMPARE_GREATER_OR_EQUAL,
+ gcvCOMPARE_ALWAYS,
+}
+gceCOMPARE;
+
+/* Stencil modes. */
+typedef enum _gceSTENCIL_MODE
+{
+ gcvSTENCIL_NONE,
+ gcvSTENCIL_SINGLE_SIDED,
+ gcvSTENCIL_DOUBLE_SIDED,
+}
+gceSTENCIL_MODE;
+
+/* Stencil operations. */
+typedef enum _gceSTENCIL_OPERATION
+{
+ gcvSTENCIL_KEEP,
+ gcvSTENCIL_REPLACE,
+ gcvSTENCIL_ZERO,
+ gcvSTENCIL_INVERT,
+ gcvSTENCIL_INCREMENT,
+ gcvSTENCIL_DECREMENT,
+ gcvSTENCIL_INCREMENT_SATURATE,
+ gcvSTENCIL_DECREMENT_SATURATE,
+ gcvSTENCIL_OPERATION_INVALID = -1
+}
+gceSTENCIL_OPERATION;
+
+/* Stencil selection. */
+typedef enum _gceSTENCIL_WHERE
+{
+ gcvSTENCIL_FRONT,
+ gcvSTENCIL_BACK,
+}
+gceSTENCIL_WHERE;
+
+/* Texture addressing selection. */
+typedef enum _gceTEXTURE_WHICH
+{
+ gcvTEXTURE_S,
+ gcvTEXTURE_T,
+ gcvTEXTURE_R,
+}
+gceTEXTURE_WHICH;
+
+/* Texture addressing modes. */
+typedef enum _gceTEXTURE_ADDRESSING
+{
+ gcvTEXTURE_INVALID = 0,
+ gcvTEXTURE_CLAMP,
+ gcvTEXTURE_WRAP,
+ gcvTEXTURE_MIRROR,
+ gcvTEXTURE_BORDER,
+ gcvTEXTURE_MIRROR_ONCE,
+}
+gceTEXTURE_ADDRESSING;
+
+/* Texture filters. */
+typedef enum _gceTEXTURE_FILTER
+{
+ gcvTEXTURE_NONE,
+ gcvTEXTURE_POINT,
+ gcvTEXTURE_LINEAR,
+ gcvTEXTURE_ANISOTROPIC,
+}
+gceTEXTURE_FILTER;
+
+typedef enum _gceTEXTURE_COMPONENT
+{
+ gcvTEXTURE_COMPONENT_R,
+ gcvTEXTURE_COMPONENT_G,
+ gcvTEXTURE_COMPONENT_B,
+ gcvTEXTURE_COMPONENT_A,
+
+ gcvTEXTURE_COMPONENT_NUM,
+} gceTEXTURE_COMPONENT;
+
+/* Texture swizzle modes. */
+typedef enum _gceTEXTURE_SWIZZLE
+{
+ gcvTEXTURE_SWIZZLE_R = 0,
+ gcvTEXTURE_SWIZZLE_G,
+ gcvTEXTURE_SWIZZLE_B,
+ gcvTEXTURE_SWIZZLE_A,
+ gcvTEXTURE_SWIZZLE_0,
+ gcvTEXTURE_SWIZZLE_1,
+
+ gcvTEXTURE_SWIZZLE_INVALID,
+} gceTEXTURE_SWIZZLE;
+
+typedef enum _gceTEXTURE_SRGBDECODE
+{
+ gcvTEXTURE_SRGB_INVALID = 0,
+ gcvTEXTURE_DECODE,
+ gcvTEXTURE_SKIP_DECODE,
+}gceTEXTURE_SRGBDECODE;
+
+typedef enum _gceTEXTURE_COMPARE_MODE
+{
+ gcvTEXTURE_COMPARE_MODE_INVALID = 0,
+ gcvTEXTURE_COMPARE_MODE_NONE,
+ gcvTEXTURE_COMPARE_MODE_REF,
+} gceTEXTURE_COMPARE_MODE;
+
+typedef enum _gceTEXTURE_DS_MODE
+{
+ gcvTEXTURE_DS_MODE_INVALID = 0,
+ gcvTEXTURE_DS_MODE_DEPTH = 1,
+ gcvTEXTURE_DS_MODE_STENCIL = 2,
+}gceTEXTURE_DS_MODE;
+
+
+/* Pixel output swizzle modes. */
+typedef enum _gcePIXEL_SWIZZLE
+{
+ gcvPIXEL_SWIZZLE_R = gcvTEXTURE_SWIZZLE_R,
+ gcvPIXEL_SWIZZLE_G = gcvTEXTURE_SWIZZLE_G,
+ gcvPIXEL_SWIZZLE_B = gcvTEXTURE_SWIZZLE_B,
+ gcvPIXEL_SWIZZLE_A = gcvTEXTURE_SWIZZLE_A,
+
+ gcvPIXEL_SWIZZLE_INVALID,
+} gcePIXEL_SWIZZLE;
+
+/* Primitive types. */
+typedef enum _gcePRIMITIVE
+{
+ gcvPRIMITIVE_POINT_LIST,
+ gcvPRIMITIVE_LINE_LIST,
+ gcvPRIMITIVE_LINE_STRIP,
+ gcvPRIMITIVE_LINE_LOOP,
+ gcvPRIMITIVE_TRIANGLE_LIST,
+ gcvPRIMITIVE_TRIANGLE_STRIP,
+ gcvPRIMITIVE_TRIANGLE_FAN,
+ gcvPRIMITIVE_RECTANGLE,
+ gcvPRIMITIVE_LINES_ADJACENCY,
+ gcvPRIMITIVE_LINE_STRIP_ADJACENCY,
+ gcvPRIMITIVE_TRIANGLES_ADJACENCY,
+ gcvPRIMITIVE_TRIANGLE_STRIP_ADJACENCY,
+ gcvPRIMITIVE_PATCH_LIST,
+}
+gcePRIMITIVE;
+
+/* Index types. */
+typedef enum _gceINDEX_TYPE
+{
+ gcvINDEX_8,
+ gcvINDEX_16,
+ gcvINDEX_32,
+}
+gceINDEX_TYPE;
+
+/* Multi GPU rendering modes. */
+typedef enum _gceMULTI_GPU_RENDERING_MODE
+{
+ gcvMULTI_GPU_RENDERING_MODE_OFF,
+ gcvMULTI_GPU_RENDERING_MODE_SPLIT_WIDTH,
+ gcvMULTI_GPU_RENDERING_MODE_SPLIT_HEIGHT,
+ gcvMULTI_GPU_RENDERING_MODE_INTERLEAVED_64x64,
+ gcvMULTI_GPU_RENDERING_MODE_INTERLEAVED_128x64,
+ gcvMULTI_GPU_RENDERING_MODE_INTERLEAVED_128x128,
+ gcvMULTI_GPU_RENDERING_MODE_INVALID
+}
+gceMULTI_GPU_RENDERING_MODE;
+
+typedef enum _gceCORE_3D_MASK
+{
+ gcvCORE_3D_0_MASK = (1 << 0),
+ gcvCORE_3D_1_MASK = (1 << 1),
+
+ gcvCORE_3D_ALL_MASK = (0xFFFF)
+}
+gceCORE_3D_MASK;
+
+typedef enum _gceCORE_3D_ID
+{
+ gcvCORE_3D_0_ID = 0,
+ gcvCORE_3D_1_ID = 1,
+
+ gcvCORE_3D_ID_INVALID = ~0UL
+}
+gceCORE_3D_ID;
+
+typedef enum _gceMULTI_GPU_MODE
+{
+ gcvMULTI_GPU_MODE_COMBINED = 0,
+ gcvMULTI_GPU_MODE_INDEPENDENT = 1
+}
+gceMULTI_GPU_MODE;
+
+typedef enum _gceMACHINECODE
+{
+ gcvMACHINECODE_ANTUTU0 = 0x0,
+
+ gcvMACHINECODE_GLB27_RELEASE_0,
+
+ gcvMACHINECODE_GLB25_RELEASE_0,
+ gcvMACHINECODE_GLB25_RELEASE_1,
+
+ /* keep it as the last enum */
+ gcvMACHINECODE_COUNT
+}
+gceMACHINECODE;
+
+typedef enum _gceUNIFORMCVT
+{
+ gcvUNIFORMCVT_NONE = 0,
+ gcvUNIFORMCVT_TO_BOOL,
+ gcvUNIFORMCVT_TO_FLOAT,
+} gceUNIFORMCVT;
+
+typedef enum _gceHAL_ARG_VERSION
+{
+ gcvHAL_ARG_VERSION_V1 = 0x0,
+ gcvHAL_ARG_VERSION_V2,
+}
+gceHAL_ARG_VERSION;
+
+
+typedef enum _gceCMDBUF_TYPE
+{
+ /* Contiguous command buffer. */
+ gcvCMDBUF_CONTIGUOUS,
+ /* Virtual command buffer. */
+ gcvCMDBUF_VIRTUAL,
+ /* Command buffer allocated from reserved memory. */
+ gcvCMDBUF_RESERVED,
+}
+gceCMDBUF_SOURCE;
+
+typedef enum _gceCHIP_FLAG
+{
+ gcvCHIP_FLAG_MSAA_COHERENCEY_ECO_FIX = 1 << 0,
+ gcvCHIP_FLAG_GC2000_R2 = 1 << 1,
+ gcvCHIP_AXI_BUS128_BITS = 1 << 2,
+}
+gceCHIP_FLAG;
+
+/* If different, choose render engine */
+#define PRIORITY_ENGINE(a, b) gcmMIN(a,b)
+
+typedef enum
+{
+ gcvENGINE_RENDER = 0,
+ gcvENGINE_BLT = 1,
+ gcvENGINE_GPU_ENGINE_COUNT = 2,
+ gcvENGINE_CPU = gcvENGINE_GPU_ENGINE_COUNT,
+ gcvENGINE_ALL_COUNT = gcvENGINE_CPU + 1,
+ gcvENGINE_INVALID = gcvENGINE_ALL_COUNT + 0x100
+}
+gceENGINE;
+
+/* CORE enum. */
+typedef enum _gceCORE
+{
+ gcvCORE_MAJOR,
+ gcvCORE_3D1,
+ gcvCORE_3D2,
+ gcvCORE_3D3,
+ gcvCORE_3D4,
+ gcvCORE_3D5,
+ gcvCORE_3D6,
+ gcvCORE_3D7,
+ gcvCORE_3D_MAX = gcvCORE_3D7,
+ gcvCORE_2D,
+ gcvCORE_VG,
+#if gcdDEC_ENABLE_AHB
+ gcvCORE_DEC,
+#endif
+ gcvCORE_COUNT
+}
+gceCORE;
+
+
+typedef enum _gceADDRESS_AREA
+{
+ gcvADDRESS_AREA_NORMAL,
+ gcvADDRESS_AREA_SECURE,
+
+ gcvADDRESS_AREA_COUNT
+}
+gceADDRESS_AREA;
+
+typedef enum _gceSECURE_MODE
+{
+ /* For cores without gcvFEATURE_SECURITY. */
+ gcvSECURE_NONE,
+
+ /* Use registers added in gcvFEATURE_SECURITY in normal driver,
+ ** In this mode, GPU always works under non secure mode and
+ ** should not touch secure buffer. It is used to test basic function.
+ */
+ gcvSECURE_IN_NORMAL,
+
+ /* Make use of gcvFEATURE_SECURITY in trust application. */
+ gcvSECURE_IN_TA
+}
+gceSECURE_MODE;
+
+/* kernel driver compression option, as it's a system global option,
+** it means kernel driver allows the options, NOT necessarily means it must be on.
+*/
+typedef enum _gceCOMPRESSION_OPTION
+{
+ gcvCOMPRESSION_OPTION_NONE = 0x0, /* No any compression */
+ gcvCOMPRESSION_OPTION_COLOR = 0x1, /* Compression for non-msaa color format */
+ gcvCOMPRESSION_OPTION_DEPTH = 0x2, /* Compression for non-msaa depth format */
+ gcvCOMPRESSION_OPTION_MSAA_COLOR = 0x4, /* Compression for msaa color */
+ gcvCOMPRESSION_OPTION_MSAA_DEPTH = 0x8, /* Compression for msaa depth */
+
+ /* default compressio option */
+ gcvCOMPRESSION_OPTION_DEFAULT = gcvCOMPRESSION_OPTION_DEPTH |
+ gcvCOMPRESSION_OPTION_COLOR |
+ gcvCOMPRESSION_OPTION_MSAA_COLOR |
+ gcvCOMPRESSION_OPTION_MSAA_DEPTH,
+}
+gceCOMPRESSION_OPTION;
+
+/* No special needs. */
+#define gcvALLOC_FLAG_NONE 0x00000000
+
+/* Physical contiguous. */
+#define gcvALLOC_FLAG_CONTIGUOUS 0x00000001
+/* Can be remapped as cacheable. */
+#define gcvALLOC_FLAG_CACHEABLE 0x00000002
+/* Secure buffer. */
+#define gcvALLOC_FLAG_SECURITY 0x00000004
+/* Physical non contiguous. */
+#define gcvALLOC_FLAG_NON_CONTIGUOUS 0x00000008
+/* Can be exported as dmabuf-fd */
+#define gcvALLOC_FLAG_DMABUF_EXPORTABLE 0x00000010
+
+#define gcvALLOC_FLAG_4GB_ADDR 0x00000020
+
+/* Do not try slow pools (gcvPOOL_VIRTUAL/gcvPOOL_CONTIGUOUS) */
+#define gcvALLOC_FLAG_FAST_POOLS 0x00000100
+
+/* Import DMABUF. */
+#define gcvALLOC_FLAG_DMABUF 0x00001000
+/* Import USERMEMORY. */
+#define gcvALLOC_FLAG_USERMEMORY 0x00002000
+/* Import an External Buffer. */
+#define gcvALLOC_FLAG_EXTERNAL_MEMORY 0x00004000
+/* Import linux reserved memory. */
+#define gcvALLOC_FLAG_LINUX_RESERVED_MEM 0x00008000
+
+/* Real allocation happens when GPU page fault. */
+#define gcvALLOC_FLAG_ALLOC_ON_FAULT 0x01000000
+/* Alloc with memory limit. */
+#define gcvALLOC_FLAG_MEMLIMIT 0x02000000
+
+/* CMA allocator only */
+#define gcvALLOC_FLAG_CMA_LIMIT 0x04000000
+
+#define gcvALLOC_FLAG_CMA_PREEMPT 0x08000000
+
+/* GL_VIV internal usage */
+#ifndef GL_MAP_BUFFER_OBJ_VIV
+#define GL_MAP_BUFFER_OBJ_VIV 0x10000
+#endif
+
+/* Command buffer usage. */
+#define gcvCOMMAND_2D (1 << 0)
+#define gcvCOMMAND_3D (1 << 1)
+
+/* Default chip ID means chip ID same as core index. */
+#define gcvCHIP_ID_DEFAULT (~0U)
+
+/******************************************************************************\
+****************************** Object Declarations *****************************
+\******************************************************************************/
+
+typedef struct _gckCONTEXT * gckCONTEXT;
+typedef struct _gcoCMDBUF * gcoCMDBUF;
+
+typedef struct _gcsSTATE_DELTA * gcsSTATE_DELTA_PTR;
+typedef struct _gcsQUEUE * gcsQUEUE_PTR;
+typedef struct _gcoQUEUE * gcoQUEUE;
+typedef struct _gcsHAL_INTERFACE * gcsHAL_INTERFACE_PTR;
+typedef struct _gcs2D_PROFILE * gcs2D_PROFILE_PTR;
+
+
+#if gcdENABLE_VG
+typedef struct _gcoVGHARDWARE * gcoVGHARDWARE;
+typedef struct _gcoVGBUFFER * gcoVGBUFFER;
+typedef struct _gckVGHARDWARE * gckVGHARDWARE;
+typedef struct _gcsVGCONTEXT * gcsVGCONTEXT_PTR;
+typedef struct _gcsVGCONTEXT_MAP * gcsVGCONTEXT_MAP_PTR;
+typedef struct _gcsVGCMDQUEUE * gcsVGCMDQUEUE_PTR;
+typedef struct _gcsTASK_MASTER_TABLE * gcsTASK_MASTER_TABLE_PTR;
+typedef struct _gckVGKERNEL * gckVGKERNEL;
+typedef void * gctTHREAD;
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __gc_hal_enum_h_ */
+
+
diff --git a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_kernel_buffer.h b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_kernel_buffer.h
new file mode 100644
index 000000000000..399eb8d2ac23
--- /dev/null
+++ b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_kernel_buffer.h
@@ -0,0 +1,314 @@
+/****************************************************************************
+*
+* The MIT License (MIT)
+*
+* Copyright (c) 2014 - 2018 Vivante 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 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 GPL License (GPL)
+*
+* Copyright (C) 2014 - 2018 Vivante 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.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+*****************************************************************************
+*
+* Note: This software is released under dual MIT and GPL licenses. A
+* recipient may use this file under the terms of either the MIT license or
+* GPL License. If you wish to use only one license not the other, you can
+* indicate your decision by deleting one of the above license notices in your
+* version of this file.
+*
+*****************************************************************************/
+
+
+#ifndef __gc_hal_kernel_buffer_h_
+#define __gc_hal_kernel_buffer_h_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/******************************************************************************\
+************************ Command Buffer and Event Objects **********************
+\******************************************************************************/
+
+/* The number of context buffers per user. */
+#define gcdCONTEXT_BUFFER_COUNT 2
+
+#define gcdRENDER_FENCE_LENGTH (6 * gcmSIZEOF(gctUINT32))
+#define gcdBLT_FENCE_LENGTH (10 * gcmSIZEOF(gctUINT32))
+#define gcdRESERVED_FLUSHCACHE_LENGTH (2 * gcmSIZEOF(gctUINT32))
+#define gcdRESERVED_PAUSE_OQ_LENGTH (2 * gcmSIZEOF(gctUINT32))
+#define gcdRESERVED_PAUSE_XFBWRITTEN_QUERY_LENGTH (4 * gcmSIZEOF(gctUINT32))
+#define gcdRESERVED_PAUSE_PRIMGEN_QUERY_LENGTH (4 * gcmSIZEOF(gctUINT32))
+#define gcdRESERVED_PAUSE_XFB_LENGTH (2 * gcmSIZEOF(gctUINT32))
+#define gcdRESERVED_HW_FENCE_32BIT (4 * gcmSIZEOF(gctUINT32))
+#define gcdRESERVED_HW_FENCE_64BIT (6 * gcmSIZEOF(gctUINT32))
+#define gcdRESERVED_PAUSE_PROBE_LENGTH (TOTAL_PROBE_NUMBER * 2 * gcmSIZEOF(gctUINT32))
+
+#define gcdRESUME_OQ_LENGTH (2 * gcmSIZEOF(gctUINT32))
+#define gcdRESUME_XFBWRITTEN_QUERY_LENGTH (4 * gcmSIZEOF(gctUINT32))
+#define gcdRESUME_PRIMGEN_QUERY_LENGTH (4 * gcmSIZEOF(gctUINT32))
+#define gcdRESUME_XFB_LENGH (2 * gcmSIZEOF(gctUINT32))
+#define gcdRESUME_PROBE_LENGH (TOTAL_PROBE_NUMBER * 2 * gcmSIZEOF(gctUINT32))
+
+
+/* State delta record. */
+typedef struct _gcsSTATE_DELTA_RECORD * gcsSTATE_DELTA_RECORD_PTR;
+typedef struct _gcsSTATE_DELTA_RECORD
+{
+ /* State address. */
+ gctUINT address;
+
+ /* State mask. */
+ gctUINT32 mask;
+
+ /* State data. */
+ gctUINT32 data;
+}
+gcsSTATE_DELTA_RECORD;
+
+/* State delta. */
+typedef struct _gcsSTATE_DELTA
+{
+ /* For debugging: the number of delta in the order of creation. */
+ gctUINT num;
+
+ /* Main state delta ID. Every time state delta structure gets reinitialized,
+ main ID is incremented. If main state ID overflows, all map entry IDs get
+ reinitialized to make sure there is no potential erroneous match after
+ the overflow.*/
+ gctUINT id;
+
+ /* Vertex element count for the delta buffer. */
+ gctUINT elementCount;
+
+ /* Number of states currently stored in the record array. */
+ gctUINT recordCount;
+
+ /* Record array; holds all modified states in gcsSTATE_DELTA_RECORD. */
+ gctUINT64 recordArray;
+ gctUINT recordSize;
+
+ /* Map entry ID is used for map entry validation. If map entry ID does not
+ match the main state delta ID, the entry and the corresponding state are
+ considered not in use. */
+ gctUINT64 mapEntryID;
+ gctUINT mapEntryIDSize;
+
+ /* If the map entry ID matches the main state delta ID, index points to
+ the state record in the record array. */
+ gctUINT64 mapEntryIndex;
+}
+gcsSTATE_DELTA;
+
+#define gcdPATCH_LIST_SIZE 1024
+
+/* Command buffer patch record. */
+typedef struct _gcsPATCH
+{
+ /* Handle of a video memory node. */
+ gctUINT32 handle;
+
+ /* Flag */
+ gctUINT32 flag;
+}
+gcsPATCH;
+
+/* List of patches for the command buffer. */
+typedef struct _gcsPATCH_LIST
+{
+ /* Array of patch records. */
+ struct _gcsPATCH patch[gcdPATCH_LIST_SIZE];
+
+ /* Number of patches in the array. */
+ gctUINT count;
+
+ /* Next item in the list. */
+ struct _gcsPATCH_LIST *next;
+}
+gcsPATCH_LIST;
+
+#define FENCE_NODE_LIST_INIT_COUNT 100
+
+typedef struct _gcsFENCE_APPEND_NODE
+{
+ gcsSURF_NODE_PTR node;
+ gceFENCE_TYPE type;
+
+}gcsFENCE_APPEND_NODE;
+
+typedef gcsFENCE_APPEND_NODE * gcsFENCE_APPEND_NODE_PTR;
+
+typedef struct _gcsFENCE_LIST * gcsFENCE_LIST_PTR;
+
+typedef struct _gcsFENCE_LIST
+{
+ /* Resource that need get fence, but command used this resource not generated */
+ gcsFENCE_APPEND_NODE_PTR pendingList;
+ gctUINT pendingCount;
+ gctUINT pendingAllocCount;
+
+ /* Resoure that already generated command in this command buffer but not get fence */
+ gcsFENCE_APPEND_NODE_PTR onIssueList;
+ gctUINT onIssueCount;
+ gctUINT onIssueAllocCount;
+}
+gcsFENCE_LIST;
+
+/* Command buffer object. */
+struct _gcoCMDBUF
+{
+ /* The object. */
+ gcsOBJECT object;
+
+ /* Commit count. */
+ gctUINT64 commitCount;
+
+ /* Command buffer entry and exit pipes. */
+ gcePIPE_SELECT entryPipe;
+ gcePIPE_SELECT exitPipe;
+
+ /* Feature usage flags. */
+ gctBOOL using2D;
+ gctBOOL using3D;
+
+ /* Size of reserved tail for each commit. */
+ gctUINT32 reservedTail;
+
+ /* Physical address of command buffer. Just a name. */
+ gctUINT32 physical;
+
+ /* Logical address of command buffer. */
+ gctUINT64 logical;
+
+ /* Number of bytes in command buffer. */
+ gctUINT32 bytes;
+
+ /* Start offset into the command buffer. */
+ gctUINT32 startOffset;
+
+ /* Current offset into the command buffer. */
+ gctUINT32 offset;
+
+ /* Number of free bytes in command buffer. */
+ gctUINT32 free;
+
+ /* Location of the last reserved area. */
+ gctUINT64 lastReserve;
+ gctUINT32 lastOffset;
+
+#if gcdSECURE_USER
+ /* Hint array for the current command buffer. */
+ gctUINT hintArraySize;
+ gctUINT64 hintArray;
+ gctUINT64 hintArrayTail;
+#endif
+
+ /* Last load state command location and hardware address. */
+ gctUINT64 lastLoadStatePtr;
+ gctUINT32 lastLoadStateAddress;
+ gctUINT32 lastLoadStateCount;
+
+ /* List of patches. */
+ gctUINT64 patchHead;
+
+ /* Link to next gcoCMDBUF object in one commit. */
+ gctUINT64 nextCMDBUF;
+
+ /*
+ * Put pointer type member after this line.
+ */
+
+ /* Completion signal. */
+ gctSIGNAL signal;
+
+ /* Link to the siblings. */
+ gcoCMDBUF prev;
+ gcoCMDBUF next;
+
+ /* Mirror command buffer(s). */
+ gcoCMDBUF *mirrors;
+ gctUINT32 mirrorCount;
+};
+
+typedef struct _gcsQUEUE
+{
+ /* Pointer to next gcsQUEUE structure in gcsQUEUE. */
+ gctUINT64 next;
+
+ /* Event information. */
+ gcsHAL_INTERFACE iface;
+}
+gcsQUEUE;
+
+/* Event queue. */
+struct _gcoQUEUE
+{
+ /* The object. */
+ gcsOBJECT object;
+
+ /* Pointer to current event queue. */
+ gcsQUEUE_PTR head;
+ gcsQUEUE_PTR tail;
+
+ /* chunks of the records. */
+ gctPOINTER chunks;
+
+ /* List of free records. */
+ gcsQUEUE_PTR freeList;
+
+ #define gcdIN_QUEUE_RECORD_LIMIT 16
+ /* Number of records currently in queue */
+ gctUINT32 recordCount;
+
+ /* Max size of pending unlock node in vidmem pool not committed */
+ gctUINT maxUnlockBytes;
+
+ gceENGINE engine;
+};
+
+struct _gcsTEMPCMDBUF
+{
+ gctUINT32 currentByteSize;
+ gctPOINTER buffer;
+ gctBOOL inUse;
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __gc_hal_kernel_buffer_h_ */
diff --git a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_mem.h b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_mem.h
new file mode 100644
index 000000000000..0adf62fe0f9a
--- /dev/null
+++ b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_mem.h
@@ -0,0 +1,566 @@
+/****************************************************************************
+*
+* The MIT License (MIT)
+*
+* Copyright (c) 2014 - 2018 Vivante 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 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 GPL License (GPL)
+*
+* Copyright (C) 2014 - 2018 Vivante 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.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+*****************************************************************************
+*
+* Note: This software is released under dual MIT and GPL licenses. A
+* recipient may use this file under the terms of either the MIT license or
+* GPL License. If you wish to use only one license not the other, you can
+* indicate your decision by deleting one of the above license notices in your
+* version of this file.
+*
+*****************************************************************************/
+
+
+/*
+** Include file for the local memory management.
+*/
+
+#ifndef __gc_hal_mem_h_
+#define __gc_hal_mem_h_
+#if (gcdENABLE_3D || gcdENABLE_VG)
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*******************************************************************************
+** Usage:
+
+ The macros to declare MemPool type and functions are
+ gcmMEM_DeclareFSMemPool (Type, TypeName, Prefix)
+ gcmMEM_DeclareVSMemPool (Type, TypeName, Prefix)
+ gcmMEM_DeclareAFSMemPool(Type, TypeName, Prefix)
+
+ The data structures for MemPool are
+ typedef struct _gcsMEM_FS_MEM_POOL * gcsMEM_FS_MEM_POOL;
+ typedef struct _gcsMEM_VS_MEM_POOL * gcsMEM_VS_MEM_POOL;
+ typedef struct _gcsMEM_AFS_MEM_POOL * gcsMEM_AFS_MEM_POOL;
+
+ The MemPool constructor and destructor functions are
+ gcfMEM_InitFSMemPool(gcsMEM_FS_MEM_POOL *, gcoOS, gctUINT, gctUINT);
+ gcfMEM_FreeFSMemPool(gcsMEM_FS_MEM_POOL *);
+ gcfMEM_InitVSMemPool(gcsMEM_VS_MEM_POOL *, gcoOS, gctUINT, gctBOOL);
+ gcfMEM_FreeVSMemPool(gcsMEM_VS_MEM_POOL *);
+ gcfMEM_InitAFSMemPool(gcsMEM_AFS_MEM_POOL *, gcoOS, gctUINT);
+ gcfMEM_FreeAFSMemPool(gcsMEM_AFS_MEM_POOL *);
+
+ FS: for Fixed-Size data structures
+ VS: for Variable-size data structures
+ AFS: for Array of Fixed-Size data structures
+
+
+ // Example 1: For a fixed-size data structure, struct gcsNode.
+ // It is used locally in a file, so the functions are static without prefix.
+ // At top level, declear allocate and free functions.
+ // The first argument is the data type.
+ // The second armument is the short name used in the fuctions.
+ gcmMEM_DeclareFSMemPool(struct gcsNode, Node, );
+
+ // The previous macro creates two inline functions,
+ // _AllocateNode and _FreeNode.
+
+ // In function or struct
+ gcsMEM_FS_MEM_POOL nodeMemPool;
+
+ // In function,
+ struct gcsNode * node;
+ gceSTATUS status;
+
+ // Before using the memory pool, initialize it.
+ // The second argument is the gcoOS object.
+ // The third argument is the number of data structures to allocate for each chunk.
+ status = gcfMEM_InitFSMemPool(&nodeMemPool, os, 100, sizeof(struct gcsNode));
+ ...
+
+ // Allocate a node.
+ status = _AllocateNode(nodeMemPool, &node);
+ ...
+ // Free a node.
+ _FreeNode(nodeMemPool, node);
+
+ // After using the memory pool, free it.
+ gcfMEM_FreeFSMemPool(&nodeMemPool);
+
+
+ // Example 2: For array of fixed-size data structures, struct gcsNode.
+ // It is used in several files, so the functions are extern with prefix.
+ // At top level, declear allocate and free functions.
+ // The first argument is the data type, and the second one is the short name
+ // used in the fuctions.
+ gcmMEM_DeclareAFSMemPool(struct gcsNode, NodeArray, gcfOpt);
+
+ // The previous macro creates two inline functions,
+ // gcfOpt_AllocateNodeArray and gcfOpt_FreeNodeArray.
+
+ // In function or struct
+ gcsMEM_AFS_MEM_POOL nodeArrayMemPool;
+
+ // In function,
+ struct gcsNode * nodeArray;
+ gceSTATUS status;
+
+ // Before using the array memory pool, initialize it.
+ // The second argument is the gcoOS object, the third is the number of data
+ // structures to allocate for each chunk.
+ status = gcfMEM_InitAFSMemPool(&nodeArrayMemPool, os, sizeof(struct gcsNode));
+ ...
+
+ // Allocate a node array of size 100.
+ status = gcfOpt_AllocateNodeArray(nodeArrayMemPool, &nodeArray, 100);
+ ...
+ // Free a node array.
+ gcfOpt_FreeNodeArray(&nodeArrayMemPool, nodeArray);
+
+ // After using the array memory pool, free it.
+ gcfMEM_FreeAFSMemPool(&nodeArrayMemPool);
+
+*******************************************************************************/
+
+/*******************************************************************************
+** To switch back to use gcoOS_Allocate and gcoOS_Free, add
+** #define USE_LOCAL_MEMORY_POOL 0
+** before including this file.
+*******************************************************************************/
+#ifndef USE_LOCAL_MEMORY_POOL
+/*
+ USE_LOCAL_MEMORY_POOL
+
+ This define enables the local memory management to improve performance.
+*/
+#define USE_LOCAL_MEMORY_POOL 1
+#endif
+
+/*******************************************************************************
+** Memory Pool Data Structures
+*******************************************************************************/
+#if USE_LOCAL_MEMORY_POOL
+ typedef struct _gcsMEM_FS_MEM_POOL * gcsMEM_FS_MEM_POOL;
+ typedef struct _gcsMEM_VS_MEM_POOL * gcsMEM_VS_MEM_POOL;
+ typedef struct _gcsMEM_AFS_MEM_POOL * gcsMEM_AFS_MEM_POOL;
+#else
+ typedef gcoOS gcsMEM_FS_MEM_POOL;
+ typedef gcoOS gcsMEM_VS_MEM_POOL;
+ typedef gcoOS gcsMEM_AFS_MEM_POOL;
+#endif
+
+/*******************************************************************************
+** Memory Pool Macros
+*******************************************************************************/
+#if USE_LOCAL_MEMORY_POOL
+#define gcmMEM_DeclareFSMemPool(Type, TypeName, Prefix) \
+gceSTATUS \
+Prefix##_Allocate##TypeName(\
+ gcsMEM_FS_MEM_POOL MemPool, \
+ Type ** Pointer \
+ ) \
+{ \
+ return(gcfMEM_FSMemPoolGetANode(MemPool, (gctPOINTER *) Pointer)); \
+} \
+ \
+gceSTATUS \
+Prefix##_CAllocate##TypeName(\
+ gcsMEM_FS_MEM_POOL MemPool, \
+ Type ** Pointer \
+ ) \
+{ \
+ gceSTATUS status; \
+ gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x", MemPool, Pointer); \
+ gcmERR_RETURN(gcfMEM_FSMemPoolGetANode(MemPool, (gctPOINTER *) Pointer)); \
+ gcoOS_ZeroMemory(*(gctPOINTER *) Pointer, gcmSIZEOF(Type)); \
+ gcmFOOTER(); \
+ return gcvSTATUS_OK; \
+} \
+ \
+gceSTATUS \
+Prefix##_Free##TypeName(\
+ gcsMEM_FS_MEM_POOL MemPool, \
+ Type * Pointer \
+ ) \
+{ \
+ gceSTATUS status; \
+ gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x", MemPool, Pointer); \
+ status = gcfMEM_FSMemPoolFreeANode(MemPool, (gctPOINTER) Pointer); \
+ gcmFOOTER(); \
+ return status; \
+} \
+ \
+gceSTATUS \
+Prefix##_Free##TypeName##List(\
+ gcsMEM_FS_MEM_POOL MemPool, \
+ Type * FirstPointer, \
+ Type * LastPointer \
+ ) \
+{ \
+ gceSTATUS status; \
+ gcmHEADER_ARG("MemPool=0x%x FirstPointer=0x%x LastPointer=0x%x", MemPool, FirstPointer, LastPointer); \
+ status = gcfMEM_FSMemPoolFreeAList(MemPool, (gctPOINTER) FirstPointer, (gctPOINTER) LastPointer); \
+ gcmFOOTER(); \
+ return status; \
+}
+
+#define gcmMEM_DeclareVSMemPool(Type, TypeName, Prefix) \
+gceSTATUS \
+Prefix##_Allocate##TypeName(\
+ gcsMEM_FS_MEM_POOL MemPool, \
+ Type ** Pointer, \
+ gctUINT Size \
+ ) \
+{ \
+ gceSTATUS status;\
+ gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x Size=%u", MemPool, Pointer, Size); \
+ status = gcfMEM_VSMemPoolGetANode(MemPool, Size, (gctPOINTER *) Pointer); \
+ gcmFOOTER(); \
+ return status; \
+} \
+ \
+gceSTATUS \
+ Prefix##_CAllocate##TypeName(\
+ gcsMEM_FS_MEM_POOL MemPool, \
+ Type ** Pointer, \
+ gctUINT Size \
+ ) \
+{ \
+ gceSTATUS status; \
+ gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x Size=%u", MemPool, Pointer, Size); \
+ gcmERR_RETURN(gcfMEM_VSMemPoolGetANode(MemPool, Size, (gctPOINTER *) Pointer)); \
+ gcoOS_ZeroMemory(*(gctPOINTER *) Pointer, size); \
+ gcmFOOTER(); \
+ return gcvSTATUS_OK; \
+} \
+ \
+gceSTATUS \
+Prefix##_Free##TypeName(\
+ gcsMEM_FS_MEM_POOL MemPool, \
+ Type * Pointer \
+ ) \
+{ \
+ gceSTATUS status; \
+ gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x", MemPool, Pinter); \
+ status = gcfMEM_VSMemPoolFreeANode(MemPool, (gctPOINTER) Pointer); \
+ gcmFOOTER(); \
+ return status; \
+}
+
+#define gcmMEM_DeclareAFSMemPool(Type, TypeName, Prefix) \
+gceSTATUS \
+Prefix##_Allocate##TypeName(\
+ gcsMEM_AFS_MEM_POOL MemPool, \
+ Type ** Pointer, \
+ gctUINT Count \
+ ) \
+{ \
+ gceSTATUS status; \
+ gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x Count=%u", MemPool, Pointer, Count); \
+ status = gcfMEM_AFSMemPoolGetANode(MemPool, Count, (gctPOINTER *) Pointer); \
+ gcmFOOTER(); \
+ return status; \
+} \
+ \
+gceSTATUS \
+Prefix##_CAllocate##TypeName(\
+ gcsMEM_AFS_MEM_POOL MemPool, \
+ Type ** Pointer, \
+ gctUINT Count \
+ ) \
+{ \
+ gceSTATUS status; \
+ gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x Count=%u", MemPool, Pointer, Count); \
+ gcmERR_RETURN(gcfMEM_AFSMemPoolGetANode(MemPool, Count, (gctPOINTER *) Pointer)); \
+ gcoOS_ZeroMemory(*(gctPOINTER *) Pointer, Count * gcmSIZEOF(Type)); \
+ gcmFOOTER(); \
+ return gcvSTATUS_OK; \
+} \
+ \
+gceSTATUS \
+Prefix##_Free##TypeName(\
+ gcsMEM_AFS_MEM_POOL MemPool, \
+ Type * Pointer \
+ ) \
+{ \
+ gceSTATUS status; \
+ gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x", MemPool, Pointer); \
+ status = gcfMEM_AFSMemPoolFreeANode(MemPool, (gctPOINTER) Pointer); \
+ gcmFOOTER(); \
+ return status; \
+}
+
+#else
+
+#define gcmMEM_DeclareFSMemPool(Type, TypeName, Prefix) \
+gceSTATUS \
+Prefix##_Allocate##TypeName(\
+ gcsMEM_FS_MEM_POOL MemPool, \
+ Type ** Pointer \
+ ) \
+{ \
+ gceSTATUS status; \
+ gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x", MemPool, Pointer); \
+ status = gcoOS_Allocate(MemPool, \
+ gcmSIZEOF(Type), \
+ (gctPOINTER *) Pointer); \
+ gcmFOOTER(); \
+ return status; \
+} \
+ \
+gceSTATUS \
+Prefix##_CAllocate##TypeName(\
+ gcsMEM_FS_MEM_POOL MemPool, \
+ Type ** Pointer \
+ ) \
+{ \
+ gceSTATUS status; \
+ gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x", MemPool, Pointer); \
+ gcmERR_RETURN(gcoOS_Allocate(MemPool, \
+ gcmSIZEOF(Type), \
+ (gctPOINTER *) Pointer)); \
+ gcoOS_ZeroMemory(*(gctPOINTER *) Pointer, gcmSIZEOF(Type)); \
+ gcmFOOTER(); \
+ return gcvSTATUS_OK; \
+} \
+ \
+gceSTATUS \
+Prefix##_Free##TypeName(\
+ gcsMEM_FS_MEM_POOL MemPool, \
+ Type * Pointer \
+ ) \
+{ \
+ gceSTATUS status; \
+ gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x", MemPool, Pointer); \
+ status = gcmOS_SAFE_FREE(MemPool, Pointer); \
+ gcmFOOTER(); \
+ return status; \
+}
+
+#define gcmMEM_DeclareVSMemPool(Type, TypeName, Prefix) \
+gceSTATUS \
+Prefix##_Allocate##TypeName(\
+ gcsMEM_VS_MEM_POOL MemPool, \
+ Type ** Pointer, \
+ gctUINT Size \
+ ) \
+{ \
+ gceSTATUS status; \
+ gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x Size=%u", MemPool, Pointer, Size); \
+ status = gcoOS_Allocate(MemPool, \
+ Size, \
+ (gctPOINTER *) Pointer); \
+ gcmFOOTER(); \
+ return status; \
+} \
+ \
+gceSTATUS \
+Prefix##_CAllocate##TypeName(\
+ gcsMEM_VS_MEM_POOL MemPool, \
+ Type ** Pointer, \
+ gctUINT Size \
+ ) \
+{ \
+ gceSTATUS status; \
+ gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x Size=%u", MemPool, Pointer, Size); \
+ gcmERR_RETURN(gcoOS_Allocate(MemPool, \
+ Size, \
+ (gctPOINTER *) Pointer)); \
+ gcoOS_ZeroMemory(*(gctPOINTER *) Pointer, Size); \
+ gcmFOOTER(); \
+ return gcvSTATUS_OK; \
+} \
+ \
+gceSTATUS \
+Prefix##_Free##TypeName(\
+ gcsMEM_VS_MEM_POOL MemPool, \
+ Type * Pointer \
+ ) \
+{ \
+ gceSTATUS status; \
+ gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x", MemPool, Pointer); \
+ status = gcmOS_SAFE_FREE(MemPool, Pointer); \
+ gcmFOOTER(); \
+ return status; \
+}
+
+#define gcmMEM_DeclareAFSMemPool(Type, TypeName, Prefix) \
+gceSTATUS \
+Prefix##_Allocate##TypeName(\
+ gcsMEM_AFS_MEM_POOL MemPool, \
+ Type ** Pointer, \
+ gctUINT Count \
+ ) \
+{ \
+ gceSTATUS status; \
+ gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x Count=%u", MemPool, Pointer, Count); \
+ status = gcoOS_Allocate(MemPool, \
+ Count * gcmSIZEOF(Type), \
+ (gctPOINTER *) Pointer); \
+ gcmFOOTER(); \
+ return status; \
+} \
+ \
+gceSTATUS \
+Prefix##_CAllocate##TypeName(\
+ gcsMEM_AFS_MEM_POOL MemPool, \
+ Type ** Pointer, \
+ gctUINT Count \
+ ) \
+{ \
+ gceSTATUS status; \
+ gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x Count=%u", MemPool, Pointer, Count); \
+ gcmERR_RETURN(gcoOS_Allocate(MemPool, \
+ Count * gcmSIZEOF(Type), \
+ (gctPOINTER *) Pointer)); \
+ gcoOS_ZeroMemory(*(gctPOINTER *) Pointer, Count * gcmSIZEOF(Type)); \
+ gcmFOOTER(); \
+ return gcvSTATUS_OK; \
+} \
+ \
+gceSTATUS \
+Prefix##_Free##TypeName(\
+ gcsMEM_AFS_MEM_POOL MemPool, \
+ Type * Pointer \
+ ) \
+{ \
+ gceSTATUS status; \
+ gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x", MemPool, Pointer); \
+ status = gcmOS_SAFE_FREE(MemPool, Pointer); \
+ gcmFOOTER(); \
+ return status; \
+}
+#endif
+
+/*******************************************************************************
+** Memory Pool Data Functions
+*******************************************************************************/
+gceSTATUS
+gcfMEM_InitFSMemPool(
+ IN gcsMEM_FS_MEM_POOL * MemPool,
+ IN gcoOS OS,
+ IN gctUINT NodeCount,
+ IN gctUINT NodeSize
+ );
+
+gceSTATUS
+gcfMEM_FreeFSMemPool(
+ IN gcsMEM_FS_MEM_POOL * MemPool
+ );
+
+gceSTATUS
+gcfMEM_FSMemPoolGetANode(
+ IN gcsMEM_FS_MEM_POOL MemPool,
+ OUT gctPOINTER * Node
+ );
+
+gceSTATUS
+gcfMEM_FSMemPoolFreeANode(
+ IN gcsMEM_FS_MEM_POOL MemPool,
+ IN gctPOINTER Node
+ );
+
+gceSTATUS
+gcfMEM_FSMemPoolFreeAList(
+ IN gcsMEM_FS_MEM_POOL MemPool,
+ IN gctPOINTER FirstNode,
+ IN gctPOINTER LastNode
+ );
+
+gceSTATUS
+gcfMEM_InitVSMemPool(
+ IN gcsMEM_VS_MEM_POOL * MemPool,
+ IN gcoOS OS,
+ IN gctUINT BlockSize,
+ IN gctBOOL RecycleFreeNode
+ );
+
+gceSTATUS
+gcfMEM_FreeVSMemPool(
+ IN gcsMEM_VS_MEM_POOL * MemPool
+ );
+
+gceSTATUS
+gcfMEM_VSMemPoolGetANode(
+ IN gcsMEM_VS_MEM_POOL MemPool,
+ IN gctUINT Size,
+ IN gctUINT Alignment,
+ OUT gctPOINTER * Node
+ );
+
+gceSTATUS
+gcfMEM_VSMemPoolFreeANode(
+ IN gcsMEM_VS_MEM_POOL MemPool,
+ IN gctPOINTER Node
+ );
+
+gceSTATUS
+gcfMEM_InitAFSMemPool(
+ IN gcsMEM_AFS_MEM_POOL *MemPool,
+ IN gcoOS OS,
+ IN gctUINT NodeCount,
+ IN gctUINT NodeSize
+ );
+
+gceSTATUS
+gcfMEM_FreeAFSMemPool(
+ IN gcsMEM_AFS_MEM_POOL *MemPool
+ );
+
+gceSTATUS
+gcfMEM_AFSMemPoolGetANode(
+ IN gcsMEM_AFS_MEM_POOL MemPool,
+ IN gctUINT Count,
+ OUT gctPOINTER * Node
+ );
+
+gceSTATUS
+gcfMEM_AFSMemPoolFreeANode(
+ IN gcsMEM_AFS_MEM_POOL MemPool,
+ IN gctPOINTER Node
+ );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* (gcdENABLE_3D || gcdENABLE_VG) */
+#endif /* __gc_hal_mem_h_ */
+
+
diff --git a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_metadata.h b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_metadata.h
new file mode 100644
index 000000000000..619c7a5198e9
--- /dev/null
+++ b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_metadata.h
@@ -0,0 +1,121 @@
+/****************************************************************************
+*
+* The MIT License (MIT)
+*
+* Copyright (c) 2014 - 2018 Vivante 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 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 GPL License (GPL)
+*
+* Copyright (C) 2014 - 2018 Vivante 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.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+*****************************************************************************
+*
+* Note: This software is released under dual MIT and GPL licenses. A
+* recipient may use this file under the terms of either the MIT license or
+* GPL License. If you wish to use only one license not the other, you can
+* indicate your decision by deleting one of the above license notices in your
+* version of this file.
+*
+*****************************************************************************/
+
+
+#ifndef __gc_hal_kernel_metadata_h_
+#define __gc_hal_kernel_metadata_h_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Macro to combine four characters into a Character Code. */
+#define __FOURCC(a, b, c, d) \
+ ((uint32_t)(a) | ((uint32_t)(b) << 8) | ((uint32_t)(c) << 16) | ((uint32_t)(d) << 24))
+
+#define VIV_VIDMEM_METADATA_MAGIC __FOURCC('v', 'i', 'v', 'm')
+
+/* Compressed format now was defined same as dec400d, should be general. */
+typedef enum _VIV_COMPRESS_FMT
+{
+ _VIV_CFMT_ARGB8 = 0,
+ _VIV_CFMT_XRGB8,
+ _VIV_CFMT_AYUV,
+ _VIV_CFMT_UYVY,
+ _VIV_CFMT_YUY2,
+ _VIV_CFMT_YUV_ONLY,
+ _VIV_CFMT_UV_MIX,
+ _VIV_CFMT_ARGB4,
+ _VIV_CFMT_XRGB4,
+ _VIV_CFMT_A1R5G5B5,
+ _VIV_CFMT_X1R5G5B5,
+ _VIV_CFMT_R5G6B5,
+ _VIV_CFMT_Z24S8,
+ _VIV_CFMT_Z24,
+ _VIV_CFMT_Z16,
+ _VIV_CFMT_A2R10G10B10,
+ _VIV_CFMT_BAYER,
+ _VIV_CFMT_SIGNED_BAYER,
+ _VIV_CFMT_VAA16,
+ _VIV_CFMT_S8,
+
+ _VIV_CFMT_MAX,
+} _VIV_COMPRESS_FMT;
+
+/* Metadata for cross-device fd share with additional (ts) info. */
+typedef struct _VIV_VIDMEM_METADATA
+{
+ uint32_t magic;
+
+ int32_t ts_fd;
+ void * ts_dma_buf;
+#ifdef gcdANDROID
+ dma_addr_t ts_address;
+#endif
+
+ uint32_t fc_enabled;
+ uint32_t fc_value;
+ uint32_t fc_value_upper;
+
+ uint32_t compressed;
+ uint32_t compress_format;
+} _VIV_VIDMEM_METADATA;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __gc_hal_kernel_metadata_h_ */
+
+
diff --git a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_options.h b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_options.h
new file mode 100644
index 000000000000..2c41d15bc012
--- /dev/null
+++ b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_options.h
@@ -0,0 +1,1408 @@
+/****************************************************************************
+*
+* The MIT License (MIT)
+*
+* Copyright (c) 2014 - 2018 Vivante 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 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 GPL License (GPL)
+*
+* Copyright (C) 2014 - 2018 Vivante 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.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+*****************************************************************************
+*
+* Note: This software is released under dual MIT and GPL licenses. A
+* recipient may use this file under the terms of either the MIT license or
+* GPL License. If you wish to use only one license not the other, you can
+* indicate your decision by deleting one of the above license notices in your
+* version of this file.
+*
+*****************************************************************************/
+
+
+#ifndef __gc_hal_options_h_
+#define __gc_hal_options_h_
+
+/*
+ gcdSECURITY
+
+*/
+#ifndef gcdSECURITY
+# define gcdSECURITY 0
+#endif
+
+/*
+ gcdPRINT_VERSION
+
+ Print HAL version.
+*/
+#ifndef gcdPRINT_VERSION
+# define gcdPRINT_VERSION 0
+#endif
+
+/*
+USE_KERNEL_VIRTUAL_BUFFERS
+
+This define enables the use of VM for gckCommand and fence buffers.
+*/
+#ifndef USE_KERNEL_VIRTUAL_BUFFERS
+#if defined(UNDER_CE)
+# define USE_KERNEL_VIRTUAL_BUFFERS 1
+#else
+# define USE_KERNEL_VIRTUAL_BUFFERS 1
+#endif
+#endif
+
+/*
+ USE_NEW_LINUX_SIGNAL
+
+ This define enables the Linux kernel signaling between kernel and user.
+*/
+#ifndef USE_NEW_LINUX_SIGNAL
+# define USE_NEW_LINUX_SIGNAL 0
+#endif
+
+/*
+ USE_LINUX_PCIE
+
+ This define enables galcore as a Linux PCIE driver.
+*/
+#ifndef USE_LINUX_PCIE
+# define USE_LINUX_PCIE 0
+#endif
+
+/*
+ VIVANTE_PROFILER
+
+ This define enables the profiler.
+*/
+#ifndef VIVANTE_PROFILER
+# define VIVANTE_PROFILER 1
+#endif
+
+/*
+ gcdUSE_VG
+
+ Enable VG HAL layer (only for GC350).
+*/
+#ifndef gcdUSE_VG
+# define gcdUSE_VG 0
+#endif
+
+/*
+ gcdUSE_VX
+
+ Enable VX HAL layer.
+*/
+#ifndef gcdUSE_VX
+# define gcdUSE_VX 1
+#endif
+
+/*
+ PROFILE_HAL_COUNTERS
+
+ This define enables HAL counter profiling support. HW and SHADER
+ counter profiling depends on this.
+*/
+#ifndef PROFILE_HAL_COUNTERS
+# define PROFILE_HAL_COUNTERS 1
+#endif
+
+/*
+ PROFILE_HW_COUNTERS
+
+ This define enables HW counter profiling support.
+*/
+#ifndef PROFILE_HW_COUNTERS
+# define PROFILE_HW_COUNTERS 1
+#endif
+
+/*
+ PROFILE_SHADER_COUNTERS
+
+ This define enables SHADER counter profiling support.
+*/
+#ifndef PROFILE_SHADER_COUNTERS
+# define PROFILE_SHADER_COUNTERS 1
+#endif
+
+/*
+ COMMAND_PROCESSOR_VERSION
+
+ The version of the command buffer and task manager.
+*/
+#define COMMAND_PROCESSOR_VERSION 1
+
+/*
+ gcdDUMP_KEY
+
+ Set this to a string that appears in 'cat /proc/<pid>/cmdline'. E.g. 'camera'.
+ HAL will create dumps for the processes matching this key.
+*/
+#ifndef gcdDUMP_KEY
+# define gcdDUMP_KEY "process"
+#endif
+
+/*
+ gcdDUMP_PATH
+
+ The dump file location. Some processes cannot write to the sdcard.
+ Try apps' data dir, e.g. /data/data/com.android.launcher
+*/
+#ifndef gcdDUMP_PATH
+#if defined(ANDROID)
+# define gcdDUMP_PATH "/mnt/sdcard/"
+#else
+# define gcdDUMP_PATH "./"
+#endif
+#endif
+
+/*
+ gcdDUMP
+
+ When set to 1, a dump of all states and memory uploads, as well as other
+ hardware related execution will be printed to the debug console. This
+ data can be used for playing back applications.
+
+ When set to 2, for vxc, all output memory will be dump.
+
+*/
+#ifndef gcdDUMP
+# define gcdDUMP 0
+#endif
+
+/*
+ gcdDUMP_API
+
+ When set to 1, a high level dump of the EGL and GL/VG APs's are
+ captured.
+*/
+#ifndef gcdDUMP_API
+# define gcdDUMP_API 0
+#endif
+
+#ifndef gcdDUMP_2DVG
+# define gcdDUMP_2DVG 0
+#endif
+
+/*
+ gcdDUMP_AHB_ACCESS
+
+ When set to 1, a dump of all AHB register access will be printed to kernel
+ message.
+*/
+#ifndef gcdDUMP_AHB_ACCESS
+# define gcdDUMP_AHB_ACCESS 0
+#endif
+
+/*
+ gcdDEBUG_OPTION
+ When set to 1, the debug options are enabled. We must set other MACRO to enable
+ sub case.
+*/
+#ifndef gcdDEBUG_OPTION
+# define gcdDEBUG_OPTION 0
+
+#if gcdDEBUG_OPTION
+/*
+ gcdDEBUG_OPTION_KEY
+ The process name of debug application.
+*/
+#ifndef gcdDEBUG_OPTION_KEY
+# define gcdDEBUG_OPTION_KEY "process"
+# endif
+/*
+ gcdDEBUG_OPTION_NO_GL_DRAWS
+ When set to 1, all glDrawArrays and glDrawElements will be skip.
+*/
+#ifndef gcdDEBUG_OPTION_NO_GL_DRAWS
+# define gcdDEBUG_OPTION_NO_GL_DRAWS 0
+# endif
+/*
+ gcdDEBUG_OPTION_NO_DRAW_PRIMITIVES
+ When set to 1, all DrawPrimitives will be skip.
+*/
+#ifndef gcdDEBUG_OPTION_NO_DRAW_PRIMITIVES
+# define gcdDEBUG_OPTION_NO_DRAW_PRIMITIVES 0
+# endif
+/*
+ gcdDEBUG_OPTION_SKIP_SWAP
+ When set to 1, just one out of gcdDEBUG_OPTION_SKIP_FRAMES(such as 1/10) eglSwapBuffers will be resolve,
+ others skip.
+*/
+#ifndef gcdDEBUG_OPTION_SKIP_SWAP
+# define gcdDEBUG_OPTION_SKIP_SWAP 0
+# define gcdDEBUG_OPTION_SKIP_FRAMES 10
+# endif
+/*
+ gcdDEBUG_OPTION_FORCE_16BIT_RENDER_TARGET
+ When set to 1, the format of render target will force to RGB565.
+*/
+#ifndef gcdDEBUG_OPTION_FORCE_16BIT_RENDER_TARGET
+# define gcdDEBUG_OPTION_FORCE_16BIT_RENDER_TARGET 0
+# endif
+/*
+ gcdDEBUG_OPTION_NONE_TEXTURE
+ When set to 1, the type of texture will be set to 0x0.
+*/
+#ifndef gcdDEBUG_OPTION_NONE_TEXTURE
+# define gcdDEBUG_OPTION_NONE_TEXTURE 0
+# endif
+/*
+ gcdDEBUG_OPTION_NONE_DEPTH
+ When set to 1, the depth format of surface will be set to gcvSURF_UNKNOWN.
+*/
+#ifndef gcdDEBUG_OPTION_NONE_DEPTH
+# define gcdDEBUG_OPTION_NONE_DEPTH 0
+# endif
+
+/*
+ gcdDEBUG_FORCE_CONTEXT_UPDATE
+ When set to 1, context will be updated before every commit.
+*/
+#ifndef gcdDEBUG_FORCE_CONTEXT_UPDATE
+# define gcdDEBUG_FORCE_CONTEXT_UPDATE 0
+# endif
+
+
+/*
+ gcdDEBUG_FORCE_CONTEXT_UPDATE
+ When set to 1, pool of each type surface can be specified by
+ changing poolPerType[] in gcsSURF_NODE_Construct.
+*/
+#ifndef gcdDEBUG_OPTION_SPECIFY_POOL
+# define gcdDEBUG_OPTION_SPECIFY_POOL 0
+# endif
+
+# endif
+#endif
+
+/*
+ gcdDUMP_VERIFY_PER_DRAW
+
+ When set to 1, verify RT and images(if used) for every single draw to ease simulation debug.
+ Only valid for ES3 driver for now.
+*/
+#ifndef gcdDUMP_VERIFY_PER_DRAW
+# define gcdDUMP_VERIFY_PER_DRAW 0
+#endif
+
+
+
+/*
+ gcdDUMP_FRAMERATE
+ When set to a value other than zero, averaqe frame rate will be dumped.
+ The value set is the starting frame that the average will be calculated.
+ This is needed because sometimes first few frames are too slow to be included
+ in the average. Frame count starts from 1.
+*/
+#ifndef gcdDUMP_FRAMERATE
+# define gcdDUMP_FRAMERATE 0
+#endif
+
+/*
+ gcdENABLE_FSCALE_VAL_ADJUST
+ When non-zero, FSCALE_VAL when gcvPOWER_ON can be adjusted externally.
+ */
+#ifndef gcdENABLE_FSCALE_VAL_ADJUST
+# define gcdENABLE_FSCALE_VAL_ADJUST 1
+#endif
+
+/*
+ gcdDUMP_IN_KERNEL
+
+ When set to 1, all dumps will happen in the kernel. This is handy if
+ you want the kernel to dump its command buffers as well and the data
+ needs to be in sync.
+*/
+#ifndef gcdDUMP_IN_KERNEL
+# define gcdDUMP_IN_KERNEL 0
+#endif
+
+/*
+ gcdDUMP_COMMAND
+
+ When set to non-zero, the command queue will dump all incoming command
+ and context buffers as well as all other modifications to the command
+ queue.
+*/
+#ifndef gcdDUMP_COMMAND
+# define gcdDUMP_COMMAND 0
+#endif
+
+/*
+ gcdDUMP_2D
+
+ When set to non-zero, it will dump the 2D command and surface.
+*/
+#ifndef gcdDUMP_2D
+# define gcdDUMP_2D 0
+#endif
+
+/*
+ gcdDUMP_FRAME_TGA
+
+ When set to a value other than 0, a dump of the frame specified by the value,
+ will be done into frame.tga. Frame count starts from 1.
+ */
+#ifndef gcdDUMP_FRAME_TGA
+# define gcdDUMP_FRAME_TGA 0
+#endif
+/*
+ gcdNULL_DRIVER
+
+ Set to 1 for infinite speed hardware.
+ Set to 2 for bypassing the HAL.
+*/
+#ifndef gcdNULL_DRIVER
+# define gcdNULL_DRIVER 0
+#endif
+
+/*
+ gcdENABLE_TIMEOUT_DETECTION
+
+ Enable timeout detection.
+*/
+#ifndef gcdENABLE_TIMEOUT_DETECTION
+# define gcdENABLE_TIMEOUT_DETECTION 0
+#endif
+
+/*
+ gcdCMD_BUFFER_SIZE
+
+ Number of bytes in a command buffer.
+*/
+#ifndef gcdCMD_BUFFER_SIZE
+# define gcdCMD_BUFFER_SIZE (128 << 10)
+#endif
+
+/*
+ gcdCMD_BLT_BUFFER_SIZE
+
+ Number of bytes in a command buffer.
+*/
+#ifndef gcdCMD_BLT_BUFFER_SIZE
+# define gcdCMD_BLT_BUFFER_SIZE (1 << 10)
+#endif
+
+/*
+ gcdCMD_BUFFERS
+
+ Number of command buffers to use per client.
+*/
+#ifndef gcdCMD_BUFFERS
+# define gcdCMD_BUFFERS 2
+#endif
+
+/*
+ gcdMAX_CMD_BUFFERS
+
+ Maximum number of command buffers to use per client.
+*/
+#ifndef gcdMAX_CMD_BUFFERS
+# define gcdMAX_CMD_BUFFERS 8
+#endif
+
+/*
+ gcdCOMMAND_QUEUES
+
+ Number of command queues in the kernel.
+*/
+#ifndef gcdCOMMAND_QUEUES
+# define gcdCOMMAND_QUEUES 2
+#endif
+
+/*
+ gcdPOWER_CONTROL_DELAY
+
+ The delay in milliseconds required to wait until the GPU has woke up
+ from a suspend or power-down state. This is system dependent because
+ the bus clock also needs to stabalize.
+*/
+#ifndef gcdPOWER_CONTROL_DELAY
+# define gcdPOWER_CONTROL_DELAY 0
+#endif
+
+/*
+ gcdMMU_SIZE
+
+ Size of the MMU page table in bytes. Each 4 bytes can hold 4kB worth of
+ virtual data.
+*/
+#ifndef gcdMMU_SIZE
+# define gcdMMU_SIZE (2048 << 10)
+#endif
+
+#ifndef gcdGC355_VGMMU_MEMORY_SIZE_KB
+# define gcdGC355_VGMMU_MEMORY_SIZE_KB 32
+#endif
+/*
+ gcdSECURE_USER
+
+ Use logical addresses instead of physical addresses in user land. In
+ this case a hint table is created for both command buffers and context
+ buffers, and that hint table will be used to patch up those buffers in
+ the kernel when they are ready to submit.
+*/
+#ifndef gcdSECURE_USER
+# define gcdSECURE_USER 0
+#endif
+
+/*
+ gcdSECURE_CACHE_SLOTS
+
+ Number of slots in the logical to DMA address cache table. Each time a
+ logical address needs to be translated into a DMA address for the GPU,
+ this cache will be walked. The replacement scheme is LRU.
+*/
+#ifndef gcdSECURE_CACHE_SLOTS
+# define gcdSECURE_CACHE_SLOTS 1024
+#endif
+
+/*
+ gcdSECURE_CACHE_METHOD
+
+ Replacement scheme used for Secure Cache. The following options are
+ available:
+
+ gcdSECURE_CACHE_LRU
+ A standard LRU cache.
+
+ gcdSECURE_CACHE_LINEAR
+ A linear walker with the idea that an application will always
+ render the scene in a similar way, so the next entry in the
+ cache should be a hit most of the time.
+
+ gcdSECURE_CACHE_HASH
+ A 256-entry hash table.
+
+ gcdSECURE_CACHE_TABLE
+ A simple cache but with potential of a lot of cache replacement.
+*/
+#ifndef gcdSECURE_CACHE_METHOD
+# define gcdSECURE_CACHE_METHOD gcdSECURE_CACHE_HASH
+#endif
+
+/*
+ gcdREGISTER_ACCESS_FROM_USER
+
+ Set to 1 to allow IOCTL calls to get through from user land. This
+ should only be in debug or development drops.
+*/
+#ifndef gcdREGISTER_ACCESS_FROM_USER
+# define gcdREGISTER_ACCESS_FROM_USER 1
+#endif
+
+/*
+ gcdHEAP_SIZE
+
+ Set the allocation size for the internal heaps. Each time a heap is
+ full, a new heap will be allocated with this minmimum amount of bytes.
+ The bigger this size, the fewer heaps there are to allocate, the better
+ the performance. However, heaps won't be freed until they are
+ completely free, so there might be some more memory waste if the size is
+ too big.
+*/
+#ifndef gcdHEAP_SIZE
+# define gcdHEAP_SIZE (64 << 10)
+#endif
+
+/*
+ gcdPOWER_SUSPEND_WHEN_IDLE
+
+ Set to 1 to make GPU enter gcvPOWER_SUSPEND when idle detected,
+ otherwise GPU will enter gcvPOWER_IDLE.
+*/
+#ifndef gcdPOWER_SUSPEND_WHEN_IDLE
+# define gcdPOWER_SUSPEND_WHEN_IDLE 1
+#endif
+
+#ifndef gcdFPGA_BUILD
+# define gcdFPGA_BUILD 0
+#endif
+
+/*
+ gcdGPU_TIMEOUT
+
+ This define specified the number of milliseconds the system will wait
+ before it broadcasts the GPU is stuck. In other words, it will define
+ the timeout of any operation that needs to wait for the GPU.
+
+ If the value is 0, no timeout will be checked for.
+*/
+#ifndef gcdGPU_TIMEOUT
+# define gcdGPU_TIMEOUT 20000
+#endif
+
+/*
+ gcdGPU_2D_TIMEOUT
+
+ This define specified the number of milliseconds the system will wait
+ before it broadcasts the 2D GPU is stuck. In other words, it will define
+ the timeout of any operation that needs to wait for the GPU.
+
+ If the value is 0, no timeout will be checked for.
+*/
+#ifndef gcdGPU_2D_TIMEOUT
+# define gcdGPU_2D_TIMEOUT 4000
+#endif
+
+
+/*
+ gcdGPU_ADVANCETIMER
+
+ it is advance timer.
+*/
+#ifndef gcdGPU_ADVANCETIMER
+# define gcdGPU_ADVANCETIMER 250
+#endif
+
+/*
+ gcdSTATIC_LINK
+
+ This define disalbes static linking;
+*/
+#ifndef gcdSTATIC_LINK
+# define gcdSTATIC_LINK 0
+#endif
+
+/*
+ gcdUSE_NEW_HEAP
+
+ Setting this define to 1 enables new heap.
+*/
+#ifndef gcdUSE_NEW_HEAP
+# define gcdUSE_NEW_HEAP 0
+#endif
+
+/*
+ gcdCMD_NO_2D_CONTEXT
+
+ This define enables no-context 2D command buffer.
+*/
+#ifndef gcdCMD_NO_2D_CONTEXT
+# define gcdCMD_NO_2D_CONTEXT 1
+#endif
+
+/*
+ gcdENABLE_BUFFER_ALIGNMENT
+
+ When enabled, video memory is allocated with atleast 16KB aligment
+ between multiple sub-buffers.
+*/
+#ifndef gcdENABLE_BUFFER_ALIGNMENT
+# define gcdENABLE_BUFFER_ALIGNMENT 1
+#endif
+
+/*
+ gcdENABLE_BANK_ALIGNMENT
+
+ When enabled, video memory is allocated bank aligned. The vendor can modify
+ _GetSurfaceBankAlignment() and _GetBankOffsetBytes() to define how
+ different types of allocations are bank and channel aligned.
+ When disabled (default), no bank alignment is done.
+*/
+#ifndef gcdENABLE_BANK_ALIGNMENT
+# define gcdENABLE_BANK_ALIGNMENT 0
+#endif
+
+/*
+ gcdBANK_BIT_START
+
+ Specifies the start bit of the bank (inclusive).
+*/
+#ifndef gcdBANK_BIT_START
+# define gcdBANK_BIT_START 12
+#endif
+
+/*
+ gcdBANK_BIT_END
+
+ Specifies the end bit of the bank (inclusive).
+*/
+#ifndef gcdBANK_BIT_END
+# define gcdBANK_BIT_END 14
+#endif
+
+/*
+ gcdBANK_CHANNEL_BIT
+
+ When set, video memory when allocated bank aligned is allocated such that
+ render and depth buffer addresses alternate on the channel bit specified.
+ This option has an effect only when gcdENABLE_BANK_ALIGNMENT is enabled.
+ When disabled (default), no alteration is done.
+*/
+#ifndef gcdBANK_CHANNEL_BIT
+# define gcdBANK_CHANNEL_BIT 7
+#endif
+
+/*
+ gcdDYNAMIC_SPEED
+
+ When non-zero, it informs the kernel driver to use the speed throttling
+ broadcasting functions to inform the system the GPU should be spet up or
+ slowed down. It will send a broadcast for slowdown each "interval"
+ specified by this define in milliseconds
+ (gckOS_BroadcastCalibrateSpeed).
+*/
+#ifndef gcdDYNAMIC_SPEED
+# define gcdDYNAMIC_SPEED 2000
+#endif
+
+/*
+ gcdDYNAMIC_EVENT_THRESHOLD
+
+ When non-zero, it specifies the maximum number of available events at
+ which the kernel driver will issue a broadcast to speed up the GPU
+ (gckOS_BroadcastHurry).
+*/
+#ifndef gcdDYNAMIC_EVENT_THRESHOLD
+# define gcdDYNAMIC_EVENT_THRESHOLD 5
+#endif
+
+/*
+ gcdENABLE_PROFILING
+
+ Enable profiling macros.
+*/
+#ifndef gcdENABLE_PROFILING
+# define gcdENABLE_PROFILING 0
+#endif
+
+/*
+ gcdENABLE_128B_MERGE
+
+ Enable 128B merge for the BUS control.
+*/
+#ifndef gcdENABLE_128B_MERGE
+# define gcdENABLE_128B_MERGE 0
+#endif
+
+/*
+ gcdFRAME_DB
+
+ When non-zero, it specified the number of frames inside the frame
+ database. The frame DB will collect per-frame timestamps and hardware
+ counters.
+*/
+#ifndef gcdFRAME_DB
+# define gcdFRAME_DB 0
+# define gcdFRAME_DB_RESET 0
+# define gcdFRAME_DB_NAME "/var/log/frameDB.log"
+#endif
+
+/*
+ gcdPAGED_MEMORY_CACHEABLE
+
+ When non-zero, paged memory will be cacheable.
+
+ Normally, driver will detemines whether a video memory
+ is cacheable or not. When cacheable is not neccessary,
+ it will be writecombine.
+
+ This option is only for those SOC which can't enable
+ writecombine without enabling cacheable.
+*/
+#ifndef gcdPAGED_MEMORY_CACHEABLE
+# define gcdPAGED_MEMORY_CACHEABLE 0
+#endif
+
+/*
+ gcdENABLE_CACHEABLE_COMMAND_BUFFER
+
+ When non-zero, command buffer will be cacheable.
+*/
+#ifndef gcdENABLE_CACHEABLE_COMMAND_BUFFER
+# define gcdENABLE_CACHEABLE_COMMAND_BUFFER 0
+#endif
+
+/*
+ gcdENABLE_BUFFERABLE_VIDEO_MEMORY
+
+ When non-zero, all video memory will be bufferable by default.
+*/
+#ifndef gcdENABLE_BUFFERABLE_VIDEO_MEMORY
+# define gcdENABLE_BUFFERABLE_VIDEO_MEMORY 1
+#endif
+
+/*
+ gcdENABLE_INFINITE_SPEED_HW
+ enable the Infinte HW, this is for 2D openVG
+*/
+#ifndef gcdENABLE_INFINITE_SPEED_HW
+# define gcdENABLE_INFINITE_SPEED_HW 0
+#endif
+
+/*
+ gcdPOWEROFF_TIMEOUT
+
+ When non-zero, GPU will power off automatically from
+ idle state, and gcdPOWEROFF_TIMEOUT is also the default
+ timeout in milliseconds.
+ */
+#ifndef gcdPOWEROFF_TIMEOUT
+# define gcdPOWEROFF_TIMEOUT 300
+#endif
+
+/*
+ QNX_SINGLE_THREADED_DEBUGGING
+*/
+#ifndef QNX_SINGLE_THREADED_DEBUGGING
+# define QNX_SINGLE_THREADED_DEBUGGING 0
+#endif
+
+/*
+ gcdSHARED_RESOLVE_BUFFER_ENABLED
+
+ Use shared resolve buffer for all app buffers.
+*/
+#ifndef gcdSHARED_RESOLVE_BUFFER_ENABLED
+# define gcdSHARED_RESOLVE_BUFFER_ENABLED 0
+#endif
+
+/*
+ gcdUSE_TRIANGLE_STRIP_PATCH
+ */
+#ifndef gcdUSE_TRIANGLE_STRIP_PATCH
+# define gcdUSE_TRIANGLE_STRIP_PATCH 1
+#endif
+
+/*
+ gcdPROCESS_ADDRESS_SPACE
+
+ When non-zero, every process which attaches to galcore has its own GPU
+ address space, size of which is gcdPROCESS_ADDRESS_SPACE_SIZE.
+*/
+#ifndef gcdPROCESS_ADDRESS_SPACE
+# define gcdPROCESS_ADDRESS_SPACE 0
+# define gcdPROCESS_ADDRESS_SPACE_SIZE 0x80000000
+#endif
+
+/*
+ gcdSHARED_PAGETABLE
+
+ When non-zero, multiple GPUs in one chip with same MMU use
+ one shared pagetable. So that when accessing same surface,
+ they can use same GPU virtual address.
+*/
+#ifndef gcdSHARED_PAGETABLE
+# define gcdSHARED_PAGETABLE 0
+#endif
+
+#ifndef gcdUSE_PVR
+# define gcdUSE_PVR 1
+#endif
+
+/*
+ gcdSMALL_BLOCK_SIZE
+
+ When non-zero, a part of VIDMEM will be reserved for requests
+ whose requesting size is less than gcdSMALL_BLOCK_SIZE.
+
+ For Linux, it's the size of a page. If this requeset fallbacks
+ to gcvPOOL_CONTIGUOUS or gcvPOOL_VIRTUAL, memory will be wasted
+ because they allocate a page at least.
+*/
+#ifndef gcdSMALL_BLOCK_SIZE
+# define gcdSMALL_BLOCK_SIZE 4096
+# define gcdRATIO_FOR_SMALL_MEMORY 32
+#endif
+
+/*
+ gcdCONTIGUOUS_SIZE_LIMIT
+ When non-zero, size of video node from gcvPOOL_CONTIGUOUS is
+ limited by gcdCONTIGUOUS_SIZE_LIMIT.
+*/
+#ifndef gcdCONTIGUOUS_SIZE_LIMIT
+# define gcdCONTIGUOUS_SIZE_LIMIT 0
+#endif
+
+/*
+ gcdLINK_QUEUE_SIZE
+
+ When non-zero, driver maintains a queue to record information of
+ latest lined context buffer and command buffer. Data in this queue
+ is be used to debug.
+*/
+#ifndef gcdLINK_QUEUE_SIZE
+# define gcdLINK_QUEUE_SIZE 64
+#endif
+
+/* gcdALPHA_KILL_IN_SHADER
+
+ Enable alpha kill inside the shader. This will be set automatically by the
+ HAL if certain states match a criteria.
+*/
+#ifndef gcdALPHA_KILL_IN_SHADER
+# define gcdALPHA_KILL_IN_SHADER 1
+#endif
+
+
+#ifndef gcdPRINT_SWAP_TIME
+# define gcdPRINT_SWAP_TIME 0
+#endif
+
+/*
+ gcdDVFS
+
+ When non-zero, software will make use of dynamic voltage and
+ frequency feature.
+ */
+#ifndef gcdDVFS
+# define gcdDVFS 0
+# define gcdDVFS_ANAYLSE_WINDOW 4
+# define gcdDVFS_POLLING_TIME (gcdDVFS_ANAYLSE_WINDOW * 4)
+#endif
+
+#ifndef gcdSYNC
+# define gcdSYNC 1
+#endif
+
+#ifndef gcdSHADER_SRC_BY_MACHINECODE
+# define gcdSHADER_SRC_BY_MACHINECODE 1
+#endif
+
+#ifndef gcdGLB27_SHADER_REPLACE_OPTIMIZATION
+# define gcdGLB27_SHADER_REPLACE_OPTIMIZATION 1
+#endif
+
+
+/*
+ gcdSUPPORT_SWAP_RECTANGLE
+
+ Support swap with a specific rectangle.
+
+ Set the rectangle with eglSetSwapRectangleVIV api.
+ Android only.
+*/
+#ifndef gcdSUPPORT_SWAP_RECTANGLE
+# define gcdSUPPORT_SWAP_RECTANGLE 1
+#endif
+
+/*
+ gcdGPU_LINEAR_BUFFER_ENABLED
+
+ Use linear buffer for GPU apps so HWC can do 2D composition.
+ Android only.
+*/
+#ifndef gcdGPU_LINEAR_BUFFER_ENABLED
+# define gcdGPU_LINEAR_BUFFER_ENABLED 1
+#endif
+
+/*
+ gcdENABLE_RENDER_INTO_WINDOW
+
+ Enable Render-Into-Window (ie, No-Resolve) feature on android.
+ NOTE that even if enabled, it still depends on hardware feature and
+ android application behavior. When hardware feature or application
+ behavior can not support render into window mode, it will fail back
+ to normal mode.
+ When Render-Into-Window is finally used, window back buffer of android
+ applications will be allocated matching render target tiling format.
+ Otherwise buffer tiling is decided by the above option
+ 'gcdGPU_LINEAR_BUFFER_ENABLED'.
+ Android only for now.
+*/
+#ifndef gcdENABLE_RENDER_INTO_WINDOW
+# define gcdENABLE_RENDER_INTO_WINDOW 1
+#endif
+
+/*
+ gcdENABLE_RENDER_INTO_WINDOW_WITH_FC
+
+ Enable Direct-rendering (ie, No-Resolve) with tile status.
+ This is expremental and in development stage.
+ This will dynamically check if color compression is available.
+*/
+#ifndef gcdENABLE_RENDER_INTO_WINDOW_WITH_FC
+# define gcdENABLE_RENDER_INTO_WINDOW_WITH_FC 1
+#endif
+
+/*
+ gcdENABLE_BLIT_BUFFER_PRESERVE
+
+ Render-Into-Window (ie, No-Resolve) does not include preserved swap
+ behavior. This feature can enable buffer preserve in No-Resolve mode.
+ When enabled, previous buffer (may be part of ) will be resolve-blitted
+ to current buffer.
+*/
+#ifndef gcdENABLE_BLIT_BUFFER_PRESERVE
+# define gcdENABLE_BLIT_BUFFER_PRESERVE 1
+#endif
+
+/*
+ gcdANDROID_NATIVE_FENCE_SYNC
+
+ Enable android native fence sync. It is introduced since jellybean-4.2.
+ Depends on linux kernel option: CONFIG_SYNC.
+
+ 0: Disabled
+ 1: Build framework for native fence sync feature, and EGL extension
+ 2: Enable async swap buffers for client
+ * Native fence sync for client 'queueBuffer' in EGL, which is
+ 'acquireFenceFd' for layer in compositor side.
+ 3. Enable async hwcomposer composition.
+ * 'releaseFenceFd' for layer in compositor side, which is native
+ fence sync when client 'dequeueBuffer'
+ * Native fence sync for compositor 'queueBuffer' in EGL, which is
+ 'acquireFenceFd' for framebuffer target for DC
+ */
+#ifndef gcdANDROID_NATIVE_FENCE_SYNC
+# define gcdANDROID_NATIVE_FENCE_SYNC 0
+#endif
+
+#ifndef gcdLINUX_SYNC_FILE
+# define gcdLINUX_SYNC_FILE 0
+#endif
+
+/*
+ gcdANDROID_IMPLICIT_NATIVE_BUFFER_SYNC
+
+ Enable implicit android native buffer sync.
+
+ For non-HW_RENDER buffer, CPU (or other hardware) and GPU can access
+ the buffer at the same time. This is to add implicit synchronization
+ between CPU (or the hardware) and GPU.
+
+ Eventually, please do not use implicit native buffer sync, but use
+ "fence sync" or "android native fence sync" instead in libgui, which
+ can be enabled in frameworks/native/libs/gui/Android.mk. This kind
+ of synchronization should be done by app but not driver itself.
+
+ Please disable this option when either "fence sync" or
+ "android native fence sync" is enabled.
+ */
+#ifndef gcdANDROID_IMPLICIT_NATIVE_BUFFER_SYNC
+# define gcdANDROID_IMPLICIT_NATIVE_BUFFER_SYNC 1
+#endif
+
+/*
+ * Implicit native buffer sync is not needed when ANDROID_native_fence_sync
+ * is available.
+ */
+#if gcdANDROID_NATIVE_FENCE_SYNC
+# undef gcdANDROID_IMPLICIT_NATIVE_BUFFER_SYNC
+# define gcdANDROID_IMPLICIT_NATIVE_BUFFER_SYNC 0
+#endif
+
+/*
+ gcdUSE_WCLIP_PATCH
+
+ Enable wclipping patch.
+*/
+#ifndef gcdUSE_WCLIP_PATCH
+# define gcdUSE_WCLIP_PATCH 1
+#endif
+
+#ifndef gcdUSE_NPOT_PATCH
+# define gcdUSE_NPOT_PATCH 1
+#endif
+
+/*
+ gcdINTERNAL_COMMENT
+
+ Wrap internal comment, content wrapped by it and the macor itself
+ will be removed in release driver.
+*/
+#ifndef gcdINTERNAL_COMMENT
+# define gcdINTERNAL_COMMENT 1
+#endif
+
+/*
+ gcdRTT_DISABLE_FC
+
+ Disable RTT FC support. For test only.
+*/
+#ifndef gcdRTT_DISABLE_FC
+# define gcdRTT_DISABLE_FC 0
+#endif
+
+/*
+ gcdFORCE_MIPMAP
+
+ Force generate mipmap for texture.
+*/
+#ifndef gcdFORCE_MIPMAP
+# define gcdFORCE_MIPMAP 0
+#endif
+
+/*
+ gcdFORCE_BILINEAR
+
+ Force bilinear for mipfilter.
+*/
+#ifndef gcdFORCE_BILINEAR
+# define gcdFORCE_BILINEAR 1
+#endif
+
+/*
+ gcdBINARY_TRACE
+
+ When non-zero, binary trace will be generated.
+
+ When gcdBINARY_TRACE_FILE_SIZE is non-zero, binary trace buffer will
+ be written to a file which size is limited to
+ gcdBINARY_TRACE_FILE_SIZE.
+*/
+#ifndef gcdBINARY_TRACE
+# define gcdBINARY_TRACE 0
+# define gcdBINARY_TRACE_FILE_SIZE 0
+#endif
+
+#ifndef gcdMOVG
+# define gcdMOVG 0
+# define gcdENABLE_TS_DOUBLE_BUFFER 1
+#else
+#if gcdMOVG
+# define gcdENABLE_TS_DOUBLE_BUFFER 0
+#else
+# define gcdENABLE_TS_DOUBLE_BUFFER 1
+#endif
+#endif
+
+/* gcdINTERRUPT_STATISTIC
+ *
+ * Monitor the event send to GPU and interrupt issued by GPU.
+ */
+
+#ifndef gcdINTERRUPT_STATISTIC
+#if defined(LINUX) || defined(__QNXNTO__) || defined(UNDER_CE) || defined(__VXWORKS__)
+# define gcdINTERRUPT_STATISTIC 1
+#else
+# define gcdINTERRUPT_STATISTIC 0
+#endif
+#endif
+
+/*
+ gcdFENCE_WAIT_LOOP_COUNT
+ Wait fence, loop count.
+*/
+#ifndef gcdFENCE_WAIT_LOOP_COUNT
+# define gcdFENCE_WAIT_LOOP_COUNT 100
+#endif
+
+/*
+ gcdPARTIAL_FAST_CLEAR
+ When it's not zero, partial fast clear is enabled.
+ Depends on gcdHAL_3D_DRAWBLIT, if gcdHAL_3D_DRAWBLIT is not enabled,
+ only available when scissor box is completely aligned.
+ Expremental, under test.
+*/
+#ifndef gcdPARTIAL_FAST_CLEAR
+# define gcdPARTIAL_FAST_CLEAR 1
+#endif
+
+/*
+ gcdREMOVE_SURF_ORIENTATION
+ When it's not zero, we will remove surface orientation function.
+ It wil become to a parameter of resolve function.
+*/
+#ifndef gcdREMOVE_SURF_ORIENTATION
+# define gcdREMOVE_SURF_ORIENTATION 1
+#endif
+
+
+
+/*
+ gcdTEST_DEC200
+ Test part for DEC200. Remove when release.
+*/
+#ifndef gcdTEST_DEC200
+# define gcdTEST_DEC200 0
+#endif
+
+/*
+ gcdPATTERN_FAST_PATH
+ For pattern match
+*/
+#ifndef gcdPATTERN_FAST_PATH
+# define gcdPATTERN_FAST_PATH 1
+#endif
+
+/*
+ gcdUSE_INPUT_DEVICE
+ disable input devices usage under fb mode to support fb+vdk multi-process
+*/
+#ifndef gcdUSE_INPUT_DEVICE
+# define gcdUSE_INPUT_DEVICE 0
+#endif
+
+/*
+ gcdPERFORMANCE_ANALYSIS
+
+ When set to 1, driver will pass information through loadstate
+ to HW. This loadstate does not impact HW execution.
+*/
+#ifndef gcdPERFORMANCE_ANALYSIS
+# define gcdPERFORMANCE_ANALYSIS 0
+#endif
+
+/*
+ gcdFRAMEINFO_STATISTIC
+ When enable, collect frame information.
+*/
+#ifndef gcdFRAMEINFO_STATISTIC
+
+#if (defined(DBG) && DBG) || defined(DEBUG) || \
+ defined(_DEBUG) || gcdDUMP || gcdPERFORMANCE_ANALYSIS || \
+ (defined(WIN32) && !defined(UNDER_CE)) || \
+ gcdFPGA_BUILD
+
+# define gcdFRAMEINFO_STATISTIC 1
+#else
+# define gcdFRAMEINFO_STATISTIC 0
+#endif
+
+#endif
+
+/*
+ gcdDEC_ENABLE_AHB
+ Enable DEC300 compression AHB mode or not.
+*/
+#ifndef gcdDEC_ENABLE_AHB
+# define gcdDEC_ENABLE_AHB 0
+#endif
+
+/*
+ gcdENABLE_UNIFIED_CONSTANT
+ Enable unified constant or not.
+*/
+#ifndef gcdENABLE_UNIFIED_CONSTANT
+# define gcdENABLE_UNIFIED_CONSTANT 1
+#endif
+
+/*
+ Core configurations. By default enable all cores.
+*/
+#ifndef gcdENABLE_3D
+# define gcdENABLE_3D 1
+#endif
+
+#ifndef gcdENABLE_2D
+# define gcdENABLE_2D 1
+#endif
+
+#ifndef gcdENABLE_VG
+# define gcdENABLE_VG 0
+#endif
+
+#ifndef gcdVG_ONLY
+# define gcdVG_ONLY (!gcdENABLE_3D && !gcdENABLE_2D && gcdENABLE_VG)
+#endif
+
+#if defined(WIN32) && !defined(UNDER_CE) && (gcdENABLE_VG == 1)
+
+#ifdef gcdUSE_VX
+#undef gcdUSE_VX
+#endif
+
+#ifdef COMMAND_PROCESSOR_VERSION
+#undef COMMAND_PROCESSOR_VERSION
+#endif
+
+#ifdef gcdENABLE_TRUST_APPLICATION
+#undef gcdENABLE_TRUST_APPLICATION
+#endif
+
+#ifdef gcdENABLE_3D
+#undef gcdENABLE_3D
+#endif
+
+#ifdef gcdENABLE_2D
+#undef gcdENABLE_2D
+#endif
+
+#define gcdENABLE_3D 0
+#define gcdENABLE_2D 0
+#define gcdUSE_VX 0
+#define COMMAND_PROCESSOR_VERSION 2
+#define gcdENABLE_TRUST_APPLICATION 0
+
+#endif /* Only for GC355 Cmodel build. */
+
+#ifndef gcdGC355_PROFILER
+# define gcdGC355_PROFILER 0
+#endif
+
+#ifndef gcdGC355_MEM_PRINT
+# define gcdGC355_MEM_PRINT 0
+#else
+#if (!((gcdENABLE_3D == 0) && (gcdENABLE_2D == 0) && (gcdENABLE_VG == 1)))
+# undef gcdGC355_MEM_PRINT
+# define gcdGC355_MEM_PRINT 0
+# endif
+#endif
+
+
+/*
+ gcdRECORD_COMMAND
+*/
+#ifndef gcdRECORD_COMMAND
+# define gcdRECORD_COMMAND 0
+#endif
+
+/*
+ gcdALLOC_CMD_FROM_RESERVE
+
+ Provide a way by which location of command buffer can be
+ specified. This is a DEBUG option to limit command buffer
+ to some memory range.
+*/
+#ifndef gcdALLOC_CMD_FROM_RESERVE
+# define gcdALLOC_CMD_FROM_RESERVE 0
+#endif
+
+/*
+ gcdBOUNDARY_CHECK
+
+ When enabled, add bounary before and after a range of
+ GPU address. So overflow can be trapped by MMU exception.
+ This is a debug option for new MMU and gcdUSE_MMU_EXCEPTION
+ is enabled.
+*/
+#ifndef gcdBOUNDARY_CHECK
+# define gcdBOUNDARY_CHECK 0
+#endif
+
+/*
+ gcdRENDER_QUALITY_CHECK
+
+ When enabled, we disable performance opt patch
+ to get know rendering quality comparing with other vendor.
+*/
+#ifndef gcdRENDER_QUALITY_CHECK
+# define gcdRENDER_QUALITY_CHECK 0
+#endif
+
+/*
+ gcdSYSTRACE
+
+ When enabled, we embed systrace in function header/footer
+ to gather time information on linux platforms include android.
+ '1' to trace API (EGL, ES11, ES2x, ES3x, etc)
+ '2' to trace HAL (except compiler)
+ '4' to trace HAL compiler
+ See gc_hal_user_debug.c for more detailed trace zones.
+*/
+#ifndef gcdSYSTRACE
+# define gcdSYSTRACE 0
+#endif
+
+#ifndef gcdENABLE_APPCTXT_BLITDRAW
+# define gcdENABLE_APPCTXT_BLITDRAW 0
+#endif
+
+/*
+ gcdENABLE_TRUST_APPLICATION
+
+ When enabled, trust application is used to handle 'security' registers.
+
+ 1) If HW doesn't have robust and security feature, this option is meaningless.
+ 2) If HW have robust and security and this option is not enable,
+ security registers are handled by non secure driver. It is for
+ platform doesn't want/need to use trust zone.
+*/
+#ifndef gcdENABLE_TRUST_APPLICATION
+#if (defined(_WIN32) && !defined(UNDER_CE)) || (defined (LINUX) && !defined(EMULATOR))
+# define gcdENABLE_TRUST_APPLICATION 1
+#else
+# define gcdENABLE_TRUST_APPLICATION 0
+#endif
+#endif
+
+/* Disable gcdENABLE_TRUST_APPLICATION when oboslete gcdSECURITY enabled. */
+#if gcdSECURITY
+#undef gcdENABLE_TRUST_APPLICATION
+#define gcdENABLE_TRUST_APPLICATION 0
+#endif
+
+#ifndef gcdMMU_SECURE_AREA_SIZE
+# define gcdMMU_SECURE_AREA_SIZE 128
+#endif
+
+/*
+VIV:gcdUSE_MMU_EXCEPTION
+
+ When enabled, enable and check exception interrupt raised by MMU.
+*/
+#ifndef gcdUSE_MMU_EXCEPTION
+# define gcdUSE_MMU_EXCEPTION 1
+#endif
+
+#ifndef gcdVX_OPTIMIZER
+# define gcdVX_OPTIMIZER 0
+#endif
+
+#ifndef gcdOCL_READ_IMAGE_OPTIMIZATION
+# define gcdOCL_READ_IMAGE_OPTIMIZATION 0
+#endif
+
+#ifndef gcdALLOC_ON_FAULT
+# define gcdALLOC_ON_FAULT 0
+#endif
+
+/*
+ gcdDISABLE_GPU_VIRTUAL_ADDRESS
+
+ When enabled, disable MMU and all virtual allocated from MMU.
+*/
+#ifndef gcdDISABLE_GPU_VIRTUAL_ADDRESS
+# define gcdDISABLE_GPU_VIRTUAL_ADDRESS 0
+#endif
+
+/*
+ gcd2D_COMPRESSION_DEC400_ALIGN_MODE
+
+ Only for DEC400 compression.
+ Set 0 as 16bytes aligned. 1 as 32bytes aligned. 2 as 64bytes aligned.
+ Default is 0 which means 32bytes aligned.
+*/
+#ifndef gcd2D_COMPRESSION_DEC400_ALIGN_MODE
+# define gcd2D_COMPRESSION_DEC400_ALIGN_MODE 1
+#endif
+
+/*
+ gcdENABLE_KERNEL_FENCE
+ When enabled, use kernel fence to do resource tracking.
+*/
+#ifndef gcdENABLE_KENREL_FENCE
+# define gcdENABLE_KERNEL_FENCE 0
+#endif
+
+
+#endif /* __gc_hal_options_h_ */
+
+
diff --git a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_profiler.h b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_profiler.h
new file mode 100644
index 000000000000..38f42709fc3e
--- /dev/null
+++ b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_profiler.h
@@ -0,0 +1,1175 @@
+/****************************************************************************
+*
+* The MIT License (MIT)
+*
+* Copyright (c) 2014 - 2018 Vivante 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 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 GPL License (GPL)
+*
+* Copyright (C) 2014 - 2018 Vivante 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.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+*****************************************************************************
+*
+* Note: This software is released under dual MIT and GPL licenses. A
+* recipient may use this file under the terms of either the MIT license or
+* GPL License. If you wish to use only one license not the other, you can
+* indicate your decision by deleting one of the above license notices in your
+* version of this file.
+*
+*****************************************************************************/
+
+
+#ifndef __gc_hal_profiler_h_
+#define __gc_hal_profiler_h_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define GLVERTEX_OBJECT 10
+#define GLVERTEX_OBJECT_BYTES 11
+
+#define GLINDEX_OBJECT 20
+#define GLINDEX_OBJECT_BYTES 21
+
+#define GLTEXTURE_OBJECT 30
+#define GLTEXTURE_OBJECT_BYTES 31
+
+#define GLBUFOBJ_OBJECT 40
+#define GLBUFOBJ_OBJECT_BYTES 41
+
+#define ES11_CALLS 151
+#define ES11_DRAWCALLS (ES11_CALLS + 1)
+#define ES11_STATECHANGECALLS (ES11_DRAWCALLS + 1)
+#define ES11_POINTCOUNT (ES11_STATECHANGECALLS + 1)
+#define ES11_LINECOUNT (ES11_POINTCOUNT + 1)
+#define ES11_TRIANGLECOUNT (ES11_LINECOUNT + 1)
+
+#define ES30_CALLS 159
+#define ES30_DRAWCALLS (ES30_CALLS + 1)
+#define ES30_STATECHANGECALLS (ES30_DRAWCALLS + 1)
+#define ES30_POINTCOUNT (ES30_STATECHANGECALLS + 1)
+#define ES30_LINECOUNT (ES30_POINTCOUNT + 1)
+#define ES30_TRIANGLECOUNT (ES30_LINECOUNT + 1)
+
+#define VG11_CALLS 88
+#define VG11_DRAWCALLS (VG11_CALLS + 1)
+#define VG11_STATECHANGECALLS (VG11_DRAWCALLS + 1)
+#define VG11_FILLCOUNT (VG11_STATECHANGECALLS + 1)
+#define VG11_STROKECOUNT (VG11_FILLCOUNT + 1)
+/* End of Driver API ID Definitions. */
+
+/* HAL & MISC IDs. */
+#define HAL_VERTBUFNEWBYTEALLOC 1
+#define HAL_VERTBUFTOTALBYTEALLOC (HAL_VERTBUFNEWBYTEALLOC + 1)
+#define HAL_VERTBUFNEWOBJALLOC (HAL_VERTBUFTOTALBYTEALLOC + 1)
+#define HAL_VERTBUFTOTALOBJALLOC (HAL_VERTBUFNEWOBJALLOC + 1)
+#define HAL_INDBUFNEWBYTEALLOC (HAL_VERTBUFTOTALOBJALLOC + 1)
+#define HAL_INDBUFTOTALBYTEALLOC (HAL_INDBUFNEWBYTEALLOC + 1)
+#define HAL_INDBUFNEWOBJALLOC (HAL_INDBUFTOTALBYTEALLOC + 1)
+#define HAL_INDBUFTOTALOBJALLOC (HAL_INDBUFNEWOBJALLOC + 1)
+#define HAL_TEXBUFNEWBYTEALLOC (HAL_INDBUFTOTALOBJALLOC + 1)
+#define HAL_TEXBUFTOTALBYTEALLOC (HAL_TEXBUFNEWBYTEALLOC + 1)
+#define HAL_TEXBUFNEWOBJALLOC (HAL_TEXBUFTOTALBYTEALLOC + 1)
+#define HAL_TEXBUFTOTALOBJALLOC (HAL_TEXBUFNEWOBJALLOC + 1)
+
+#define GPU_CYCLES 1
+#define GPU_READ64BYTE (GPU_CYCLES + 1)
+#define GPU_WRITE64BYTE (GPU_READ64BYTE + 1)
+#define GPU_TOTALCYCLES (GPU_WRITE64BYTE + 1)
+#define GPU_IDLECYCLES (GPU_TOTALCYCLES + 1)
+
+#define VS_INSTCOUNT 1
+#define VS_BRANCHINSTCOUNT (VS_INSTCOUNT + 1)
+#define VS_TEXLDINSTCOUNT (VS_BRANCHINSTCOUNT + 1)
+#define VS_RENDEREDVERTCOUNT (VS_TEXLDINSTCOUNT + 1)
+#define VS_SOURCE (VS_RENDEREDVERTCOUNT + 1)
+#define VS_NONIDLESTARVECOUNT (VS_SOURCE + 1)
+#define VS_STARVELCOUNT (VS_NONIDLESTARVECOUNT + 1)
+#define VS_STALLCOUNT (VS_STARVELCOUNT + 1)
+#define VS_PROCESSCOUNT (VS_STALLCOUNT + 1)
+
+#define PS_INSTCOUNT 1
+#define PS_BRANCHINSTCOUNT (PS_INSTCOUNT + 1)
+#define PS_TEXLDINSTCOUNT (PS_BRANCHINSTCOUNT + 1)
+#define PS_RENDEREDPIXCOUNT (PS_TEXLDINSTCOUNT + 1)
+#define PS_SOURCE (PS_RENDEREDPIXCOUNT + 1)
+#define PS_NONIDLESTARVECOUNT (PS_SOURCE + 1)
+#define PS_STARVELCOUNT (PS_NONIDLESTARVECOUNT + 1)
+#define PS_STALLCOUNT (PS_STARVELCOUNT + 1)
+#define PS_PROCESSCOUNT (PS_STALLCOUNT + 1)
+#define PS_SHADERCYCLECOUNT (PS_PROCESSCOUNT + 1)
+
+#define PA_INVERTCOUNT 1
+#define PA_INPRIMCOUNT (PA_INVERTCOUNT + 1)
+#define PA_OUTPRIMCOUNT (PA_INPRIMCOUNT + 1)
+#define PA_DEPTHCLIPCOUNT (PA_OUTPRIMCOUNT + 1)
+#define PA_TRIVIALREJCOUNT (PA_DEPTHCLIPCOUNT + 1)
+#define PA_CULLCOUNT (PA_TRIVIALREJCOUNT + 1)
+#define PA_NONIDLESTARVECOUNT (PA_CULLCOUNT + 1)
+#define PA_STARVELCOUNT (PA_NONIDLESTARVECOUNT + 1)
+#define PA_STALLCOUNT (PA_STARVELCOUNT + 1)
+#define PA_PROCESSCOUNT (PA_STALLCOUNT + 1)
+
+#define SE_TRIANGLECOUNT 1
+#define SE_LINECOUNT (SE_TRIANGLECOUNT + 1)
+#define SE_STARVECOUNT (SE_LINECOUNT + 1)
+#define SE_STALLCOUNT (SE_STARVECOUNT + 1)
+#define SE_RECEIVETRIANGLECOUNT (SE_STALLCOUNT + 1)
+#define SE_SENDTRIANGLECOUNT (SE_RECEIVETRIANGLECOUNT + 1)
+#define SE_RECEIVELINESCOUNT (SE_SENDTRIANGLECOUNT + 1)
+#define SE_SENDLINESCOUNT (SE_RECEIVELINESCOUNT + 1)
+#define SE_NONIDLESTARVECOUNT (SE_SENDLINESCOUNT + 1)
+#define SE_PROCESSCOUNT (SE_NONIDLESTARVECOUNT + 1)
+
+#define RA_VALIDPIXCOUNT 1
+#define RA_TOTALQUADCOUNT (RA_VALIDPIXCOUNT + 1)
+#define RA_VALIDQUADCOUNTEZ (RA_TOTALQUADCOUNT + 1)
+#define RA_TOTALPRIMCOUNT (RA_VALIDQUADCOUNTEZ + 1)
+#define RA_PIPECACHEMISSCOUNT (RA_TOTALPRIMCOUNT + 1)
+#define RA_PREFCACHEMISSCOUNT (RA_PIPECACHEMISSCOUNT + 1)
+#define RA_EEZCULLCOUNT (RA_PREFCACHEMISSCOUNT + 1)
+#define RA_NONIDLESTARVECOUNT (RA_EEZCULLCOUNT + 1)
+#define RA_STARVELCOUNT (RA_NONIDLESTARVECOUNT + 1)
+#define RA_STALLCOUNT (RA_STARVELCOUNT + 1)
+#define RA_PROCESSCOUNT (RA_STALLCOUNT + 1)
+
+#define TX_TOTBILINEARREQ 1
+#define TX_TOTTRILINEARREQ (TX_TOTBILINEARREQ + 1)
+#define TX_TOTDISCARDTEXREQ (TX_TOTTRILINEARREQ + 1)
+#define TX_TOTTEXREQ (TX_TOTDISCARDTEXREQ + 1)
+#define TX_MEMREADCOUNT (TX_TOTTEXREQ + 1)
+#define TX_MEMREADIN8BCOUNT (TX_MEMREADCOUNT + 1)
+#define TX_CACHEMISSCOUNT (TX_MEMREADIN8BCOUNT + 1)
+#define TX_CACHEHITTEXELCOUNT (TX_CACHEMISSCOUNT + 1)
+#define TX_CACHEMISSTEXELCOUNT (TX_CACHEHITTEXELCOUNT + 1)
+#define TX_NONIDLESTARVECOUNT (TX_CACHEMISSTEXELCOUNT+ 1)
+#define TX_STARVELCOUNT (TX_NONIDLESTARVECOUNT + 1)
+#define TX_STALLCOUNT (TX_STARVELCOUNT + 1)
+#define TX_PROCESSCOUNT (TX_STALLCOUNT + 1)
+
+#define PE_KILLEDBYCOLOR 1
+#define PE_KILLEDBYDEPTH (PE_KILLEDBYCOLOR + 1)
+#define PE_DRAWNBYCOLOR (PE_KILLEDBYDEPTH + 1)
+#define PE_DRAWNBYDEPTH (PE_DRAWNBYCOLOR + 1)
+
+#define MC_READREQ8BPIPE 1
+#define MC_READREQ8BIP (MC_READREQ8BPIPE + 1)
+#define MC_WRITEREQ8BPIPE (MC_READREQ8BIP + 1)
+#define MC_AXIMINLATENCY (MC_WRITEREQ8BPIPE + 1)
+#define MC_AXIMAXLATENCY (MC_AXIMINLATENCY + 1)
+#define MC_AXITOTALLATENCY (MC_AXIMAXLATENCY + 1)
+#define MC_AXISAMPLECOUNT (MC_AXITOTALLATENCY + 1)
+
+#define AXI_READREQSTALLED 1
+#define AXI_WRITEREQSTALLED (AXI_READREQSTALLED + 1)
+#define AXI_WRITEDATASTALLED (AXI_WRITEREQSTALLED + 1)
+
+#define FE_DRAWCOUNT 1
+#define FE_OUTVERTEXCOUNT (FE_DRAWCOUNT + 1)
+#define FE_STALLCOUNT (FE_OUTVERTEXCOUNT + 1)
+#define FE_STARVECOUNT (FE_STALLCOUNT + 1)
+
+#define PVS_INSTRCOUNT 1
+#define PVS_ALUINSTRCOUNT (PVS_INSTRCOUNT + 1)
+#define PVS_TEXINSTRCOUNT (PVS_ALUINSTRCOUNT + 1)
+#define PVS_ATTRIBCOUNT (PVS_TEXINSTRCOUNT + 1)
+#define PVS_UNIFORMCOUNT (PVS_ATTRIBCOUNT + 1)
+#define PVS_FUNCTIONCOUNT (PVS_UNIFORMCOUNT + 1)
+#define PVS_SOURCE (PVS_FUNCTIONCOUNT + 1)
+
+#define PPS_INSTRCOUNT 1
+#define PPS_ALUINSTRCOUNT (PPS_INSTRCOUNT + 1)
+#define PPS_TEXINSTRCOUNT (PPS_ALUINSTRCOUNT + 1)
+#define PPS_ATTRIBCOUNT (PPS_TEXINSTRCOUNT + 1)
+#define PPS_UNIFORMCOUNT (PPS_ATTRIBCOUNT + 1)
+#define PPS_FUNCTIONCOUNT (PPS_UNIFORMCOUNT + 1)
+#define PPS_SOURCE (PPS_FUNCTIONCOUNT + 1)
+/* End of MISC Counter IDs. */
+
+
+/* Category Constants. */
+#define VPHEADER 0x010000
+#define VPG_INFO 0x020000
+#define VPG_TIME 0x030000
+#define VPG_MEM 0x040000
+#define VPG_ES11 0x050000
+#define VPG_ES30 0x060000
+#define VPG_VG11 0x070000
+#define VPG_HAL 0x080000
+#define VPG_HW 0x090000
+#define VPG_GPU 0x0a0000
+#define VPG_VS 0x0b0000
+#define VPG_PS 0x0c0000
+#define VPG_PA 0x0d0000
+#define VPG_SETUP 0x0e0000
+#define VPG_RA 0x0f0000
+#define VPG_TX 0x100000
+#define VPG_PE 0x110000
+#define VPG_MC 0x120000
+#define VPG_AXI 0x130000
+#define VPG_PROG 0x140000
+#define VPG_PVS 0x150000
+#define VPG_PPS 0x160000
+#define VPG_ES11_TIME 0x170000
+#define VPG_ES30_TIME 0x180000
+#define VPG_FRAME 0x190000
+#define VPG_ES11_DRAW 0x200000
+#define VPG_ES30_DRAW 0x210000
+#define VPG_VG11_TIME 0x220000
+#define VPG_FE 0x230000
+#define VPG_MULTI_GPU 0x240000
+#define VPNG_FE 0x250000
+#define VPNG_VS 0x260000
+#define VPNG_PS 0x270000
+#define VPNG_PA 0x280000
+#define VPNG_SETUP 0x290000
+#define VPNG_RA 0x2a0000
+#define VPNG_TX 0x2b0000
+#define VPNG_PE 0x2c0000
+#define VPNG_MCC 0x2d0000
+#define VPNG_MCZ 0x2e0000
+#define VPNG_HI 0x2f0000
+#define VPNG_L2 0x300000
+#define VPG_FINISH 0x310000
+#define VPG_END 0xff0000
+
+/* Info. */
+#define VPC_INFOCOMPANY (VPG_INFO + 1)
+#define VPC_INFOVERSION (VPC_INFOCOMPANY + 1)
+#define VPC_INFORENDERER (VPC_INFOVERSION + 1)
+#define VPC_INFOREVISION (VPC_INFORENDERER + 1)
+#define VPC_INFODRIVER (VPC_INFOREVISION + 1)
+#define VPC_INFODRIVERMODE (VPC_INFODRIVER + 1)
+#define VPC_INFOSCREENSIZE (VPC_INFODRIVERMODE + 1)
+
+/* Counter Constants. */
+#define VPC_ELAPSETIME (VPG_TIME + 1)
+#define VPC_CPUTIME (VPC_ELAPSETIME + 1)
+
+#define VPC_MEMMAXRES (VPG_MEM + 1)
+#define VPC_MEMSHARED (VPC_MEMMAXRES + 1)
+#define VPC_MEMUNSHAREDDATA (VPC_MEMSHARED + 1)
+#define VPC_MEMUNSHAREDSTACK (VPC_MEMUNSHAREDDATA + 1)
+
+/* OpenGL ES11 Statics Counter IDs. */
+#define VPC_ES11CALLS (VPG_ES11 + ES11_CALLS)
+#define VPC_ES11DRAWCALLS (VPG_ES11 + ES11_DRAWCALLS)
+#define VPC_ES11STATECHANGECALLS (VPG_ES11 + ES11_STATECHANGECALLS)
+#define VPC_ES11POINTCOUNT (VPG_ES11 + ES11_POINTCOUNT)
+#define VPC_ES11LINECOUNT (VPG_ES11 + ES11_LINECOUNT)
+#define VPC_ES11TRIANGLECOUNT (VPG_ES11 + ES11_TRIANGLECOUNT)
+
+/* OpenGL ES30 Statistics Counter IDs. */
+#define VPC_ES30CALLS (VPG_ES30 + ES30_CALLS)
+#define VPC_ES30DRAWCALLS (VPG_ES30 + ES30_DRAWCALLS)
+#define VPC_ES30STATECHANGECALLS (VPG_ES30 + ES30_STATECHANGECALLS)
+#define VPC_ES30POINTCOUNT (VPG_ES30 + ES30_POINTCOUNT)
+#define VPC_ES30LINECOUNT (VPG_ES30 + ES30_LINECOUNT)
+#define VPC_ES30TRIANGLECOUNT (VPG_ES30 + ES30_TRIANGLECOUNT)
+
+/* OpenVG Statistics Counter IDs. */
+#define VPC_VG11CALLS (VPG_VG11 + VG11_CALLS)
+#define VPC_VG11DRAWCALLS (VPG_VG11 + VG11_DRAWCALLS)
+#define VPC_VG11STATECHANGECALLS (VPG_VG11 + VG11_STATECHANGECALLS)
+#define VPC_VG11FILLCOUNT (VPG_VG11 + VG11_FILLCOUNT)
+#define VPC_VG11STROKECOUNT (VPG_VG11 + VG11_STROKECOUNT)
+
+/* HAL Counters. */
+#define VPC_HALVERTBUFNEWBYTEALLOC (VPG_HAL + HAL_VERTBUFNEWBYTEALLOC)
+#define VPC_HALVERTBUFTOTALBYTEALLOC (VPG_HAL + HAL_VERTBUFTOTALBYTEALLOC)
+#define VPC_HALVERTBUFNEWOBJALLOC (VPG_HAL + HAL_VERTBUFNEWOBJALLOC)
+#define VPC_HALVERTBUFTOTALOBJALLOC (VPG_HAL + HAL_VERTBUFTOTALOBJALLOC)
+#define VPC_HALINDBUFNEWBYTEALLOC (VPG_HAL + HAL_INDBUFNEWBYTEALLOC)
+#define VPC_HALINDBUFTOTALBYTEALLOC (VPG_HAL + HAL_INDBUFTOTALBYTEALLOC)
+#define VPC_HALINDBUFNEWOBJALLOC (VPG_HAL + HAL_INDBUFNEWOBJALLOC)
+#define VPC_HALINDBUFTOTALOBJALLOC (VPG_HAL + HAL_INDBUFTOTALOBJALLOC)
+#define VPC_HALTEXBUFNEWBYTEALLOC (VPG_HAL + HAL_TEXBUFNEWBYTEALLOC)
+#define VPC_HALTEXBUFTOTALBYTEALLOC (VPG_HAL + HAL_TEXBUFTOTALBYTEALLOC)
+#define VPC_HALTEXBUFNEWOBJALLOC (VPG_HAL + HAL_TEXBUFNEWOBJALLOC)
+#define VPC_HALTEXBUFTOTALOBJALLOC (VPG_HAL + HAL_TEXBUFTOTALOBJALLOC)
+
+/* HW: GPU Counters. */
+#define VPC_GPUCYCLES (VPG_GPU + GPU_CYCLES)
+#define VPC_GPUREAD64BYTE (VPG_GPU + GPU_READ64BYTE)
+#define VPC_GPUWRITE64BYTE (VPG_GPU + GPU_WRITE64BYTE)
+#define VPC_GPUTOTALCYCLES (VPG_GPU + GPU_TOTALCYCLES)
+#define VPC_GPUIDLECYCLES (VPG_GPU + GPU_IDLECYCLES)
+
+/* HW: Shader Counters. */
+#define VPC_VSINSTCOUNT (VPG_VS + VS_INSTCOUNT)
+#define VPC_VSBRANCHINSTCOUNT (VPG_VS + VS_BRANCHINSTCOUNT)
+#define VPC_VSTEXLDINSTCOUNT (VPG_VS + VS_TEXLDINSTCOUNT)
+#define VPC_VSRENDEREDVERTCOUNT (VPG_VS + VS_RENDEREDVERTCOUNT)
+#define VPC_VSNONIDLESTARVECOUNT (VPG_VS + VS_NONIDLESTARVECOUNT)
+#define VPC_VSSTARVELCOUNT (VPG_VS + VS_STARVELCOUNT)
+#define VPC_VSSTALLCOUNT (VPG_VS + VS_STALLCOUNT)
+#define VPC_VSPROCESSCOUNT (VPG_VS + VS_PROCESSCOUNT)
+/* HW: PS Count. */
+#define VPC_PSINSTCOUNT (VPG_PS + PS_INSTCOUNT)
+#define VPC_PSBRANCHINSTCOUNT (VPG_PS + PS_BRANCHINSTCOUNT)
+#define VPC_PSTEXLDINSTCOUNT (VPG_PS + PS_TEXLDINSTCOUNT)
+#define VPC_PSRENDEREDPIXCOUNT (VPG_PS + PS_RENDEREDPIXCOUNT)
+#define VPC_PSNONIDLESTARVECOUNT (VPG_PS + PS_NONIDLESTARVECOUNT)
+#define VPC_PSSTARVELCOUNT (VPG_PS + PS_STARVELCOUNT)
+#define VPC_PSSTALLCOUNT (VPG_PS + PS_STALLCOUNT)
+#define VPC_PSPROCESSCOUNT (VPG_PS + PS_PROCESSCOUNT)
+#define VPC_PSSHADERCYCLECOUNT (VPG_PS + PS_SHADERCYCLECOUNT)
+
+/* HW: PA Counters. */
+#define VPC_PAINVERTCOUNT (VPG_PA + PA_INVERTCOUNT)
+#define VPC_PAINPRIMCOUNT (VPG_PA + PA_INPRIMCOUNT)
+#define VPC_PAOUTPRIMCOUNT (VPG_PA + PA_OUTPRIMCOUNT)
+#define VPC_PADEPTHCLIPCOUNT (VPG_PA + PA_DEPTHCLIPCOUNT)
+#define VPC_PATRIVIALREJCOUNT (VPG_PA + PA_TRIVIALREJCOUNT)
+#define VPC_PACULLCOUNT (VPG_PA + PA_CULLCOUNT)
+#define VPC_PANONIDLESTARVECOUNT (VPG_PA + PA_NONIDLESTARVECOUNT)
+#define VPC_PASTARVELCOUNT (VPG_PA + PA_STARVELCOUNT)
+#define VPC_PASTALLCOUNT (VPG_PA + PA_STALLCOUNT)
+#define VPC_PAPROCESSCOUNT (VPG_PA + PA_PROCESSCOUNT)
+
+/* HW: Setup Counters. */
+#define VPC_SETRIANGLECOUNT (VPG_SETUP + SE_TRIANGLECOUNT)
+#define VPC_SELINECOUNT (VPG_SETUP + SE_LINECOUNT)
+#define VPC_SESTARVECOUNT (VPG_SETUP + SE_STARVECOUNT)
+#define VPC_SESTALLCOUNT (VPG_SETUP + SE_STALLCOUNT)
+#define VPC_SERECEIVETRIANGLECOUNT (VPG_SETUP + SE_RECEIVETRIANGLECOUNT)
+#define VPC_SESENDTRIANGLECOUNT (VPG_SETUP + SE_SENDTRIANGLECOUNT)
+#define VPC_SERECEIVELINESCOUNT (VPG_SETUP + SE_RECEIVELINESCOUNT)
+#define VPC_SESENDLINESCOUNT (VPG_SETUP + SE_SENDLINESCOUNT)
+#define VPC_SENONIDLESTARVECOUNT (VPG_SETUP + SE_NONIDLESTARVECOUNT)
+#define VPC_SEPROCESSCOUNT (VPG_SETUP + SE_PROCESSCOUNT)
+
+/* HW: RA Counters. */
+#define VPC_RAVALIDPIXCOUNT (VPG_RA + RA_VALIDPIXCOUNT)
+#define VPC_RATOTALQUADCOUNT (VPG_RA + RA_TOTALQUADCOUNT)
+#define VPC_RAVALIDQUADCOUNTEZ (VPG_RA + RA_VALIDQUADCOUNTEZ)
+#define VPC_RATOTALPRIMCOUNT (VPG_RA + RA_TOTALPRIMCOUNT)
+#define VPC_RAPIPECACHEMISSCOUNT (VPG_RA + RA_PIPECACHEMISSCOUNT)
+#define VPC_RAPREFCACHEMISSCOUNT (VPG_RA + RA_PREFCACHEMISSCOUNT)
+#define VPC_RAEEZCULLCOUNT (VPG_RA + RA_EEZCULLCOUNT)
+#define VPC_RANONIDLESTARVECOUNT (VPG_RA + RA_NONIDLESTARVECOUNT)
+#define VPC_RASTARVELCOUNT (VPG_RA + RA_STARVELCOUNT)
+#define VPC_RASTALLCOUNT (VPG_RA + RA_STALLCOUNT)
+#define VPC_RAPROCESSCOUNT (VPG_RA + RA_PROCESSCOUNT)
+
+/* HW: TEX Counters. */
+#define VPC_TXTOTBILINEARREQ (VPG_TX + TX_TOTBILINEARREQ)
+#define VPC_TXTOTTRILINEARREQ (VPG_TX + TX_TOTTRILINEARREQ)
+#define VPC_TXTOTDISCARDTEXREQ (VPG_TX + TX_TOTDISCARDTEXREQ)
+#define VPC_TXTOTTEXREQ (VPG_TX + TX_TOTTEXREQ)
+#define VPC_TXMEMREADCOUNT (VPG_TX + TX_MEMREADCOUNT)
+#define VPC_TXMEMREADIN8BCOUNT (VPG_TX + TX_MEMREADIN8BCOUNT)
+#define VPC_TXCACHEMISSCOUNT (VPG_TX + TX_CACHEMISSCOUNT)
+#define VPC_TXCACHEHITTEXELCOUNT (VPG_TX + TX_CACHEHITTEXELCOUNT)
+#define VPC_TXCACHEMISSTEXELCOUNT (VPG_TX + TX_CACHEMISSTEXELCOUNT)
+#define VPC_TXNONIDLESTARVECOUNT (VPG_TX + TX_NONIDLESTARVECOUNT)
+#define VPC_TXSTARVELCOUNT (VPG_TX + TX_STARVELCOUNT)
+#define VPC_TXSTALLCOUNT (VPG_TX + TX_STALLCOUNT)
+#define VPC_TXPROCESSCOUNT (VPG_TX + TX_PROCESSCOUNT)
+
+/* HW: PE Counters. */
+#define VPC_PEKILLEDBYCOLOR (VPG_PE + PE_KILLEDBYCOLOR)
+#define VPC_PEKILLEDBYDEPTH (VPG_PE + PE_KILLEDBYDEPTH)
+#define VPC_PEDRAWNBYCOLOR (VPG_PE + PE_DRAWNBYCOLOR)
+#define VPC_PEDRAWNBYDEPTH (VPG_PE + PE_DRAWNBYDEPTH)
+
+/* HW: MC Counters. */
+#define VPC_MCREADREQ8BPIPE (VPG_MC + MC_READREQ8BPIPE)
+#define VPC_MCREADREQ8BIP (VPG_MC + MC_READREQ8BIP)
+#define VPC_MCWRITEREQ8BPIPE (VPG_MC + MC_WRITEREQ8BPIPE)
+#define VPC_MCAXIMINLATENCY (VPG_MC + MC_AXIMINLATENCY)
+#define VPC_MCAXIMAXLATENCY (VPG_MC + MC_AXIMAXLATENCY)
+#define VPC_MCAXITOTALLATENCY (VPG_MC + MC_AXITOTALLATENCY)
+#define VPC_MCAXISAMPLECOUNT (VPG_MC + MC_AXISAMPLECOUNT)
+
+/* HW: AXI Counters. */
+#define VPC_AXIREADREQSTALLED (VPG_AXI + AXI_READREQSTALLED)
+#define VPC_AXIWRITEREQSTALLED (VPG_AXI + AXI_WRITEREQSTALLED)
+#define VPC_AXIWRITEDATASTALLED (VPG_AXI + AXI_WRITEDATASTALLED)
+
+/* HW: FE Counters. */
+#define VPC_FEDRAWCOUNT (VPG_FE + FE_DRAWCOUNT)
+#define VPC_FEOUTVERTEXCOUNT (VPG_FE + FE_OUTVERTEXCOUNT)
+#define VPC_FESTALLCOUNT (VPG_FE + FE_STALLCOUNT)
+#define VPC_FESTARVECOUNT (VPG_FE + FE_STARVECOUNT)
+
+/* HW: Shader Counters. */
+#define VPNC_VSINSTCOUNT (VPNG_VS + 1)
+#define VPNC_VSBRANCHINSTCOUNT (VPNG_VS + 2)
+#define VPNC_VSTEXLDINSTCOUNT (VPNG_VS + 3)
+#define VPNC_VSRENDEREDVERTCOUNT (VPNG_VS + 4)
+#define VPNC_VSNONIDLESTARVECOUNT (VPNG_VS + 5)
+#define VPNC_VSSTARVELCOUNT (VPNG_VS + 6)
+#define VPNC_VSSTALLCOUNT (VPNG_VS + 7)
+#define VPNC_VSPROCESSCOUNT (VPNG_VS + 8)
+#define VPNC_VSSHADERCYCLECOUNT (VPNG_VS + 9)
+#define VPNC_VS_COUNT VPNC_VSSHADERCYCLECOUNT - VPNG_VS
+
+/* HW: PS Count. */
+#define VPNC_PSINSTCOUNT (VPNG_PS + 1)
+#define VPNC_PSBRANCHINSTCOUNT (VPNG_PS + 2)
+#define VPNC_PSTEXLDINSTCOUNT (VPNG_PS + 3)
+#define VPNC_PSRENDEREDPIXCOUNT (VPNG_PS + 4)
+#define VPNC_PSNONIDLESTARVECOUNT (VPNG_PS + 5)
+#define VPNC_PSSTARVELCOUNT (VPNG_PS + 6)
+#define VPNC_PSSTALLCOUNT (VPNG_PS + 7)
+#define VPNC_PSPROCESSCOUNT (VPNG_PS + 8)
+#define VPNC_PSSHADERCYCLECOUNT (VPNG_PS + 9)
+#define VPNC_PS_COUNT VPNC_PSSHADERCYCLECOUNT - VPNG_PS
+
+/* HW: PA Counters. */
+#define VPNC_PAINVERTCOUNT (VPNG_PA + 1)
+#define VPNC_PAINPRIMCOUNT (VPNG_PA + 2)
+#define VPNC_PAOUTPRIMCOUNT (VPNG_PA + 3)
+#define VPNC_PADEPTHCLIPCOUNT (VPNG_PA + 4)
+#define VPNC_PATRIVIALREJCOUNT (VPNG_PA + 5)
+#define VPNC_PACULLPRIMCOUNT (VPNG_PA + 6)
+#define VPNC_PADROPPRIMCOUNT (VPNG_PA + 7)
+#define VPNC_PAFRCLIPPRIMCOUNT (VPNG_PA + 8)
+#define VPNC_PAFRCLIPDROPPRIMCOUNT (VPNG_PA + 9)
+#define VPNC_PANONIDLESTARVECOUNT (VPNG_PA + 10)
+#define VPNC_PASTARVELCOUNT (VPNG_PA + 11)
+#define VPNC_PASTALLCOUNT (VPNG_PA + 12)
+#define VPNC_PAPROCESSCOUNT (VPNG_PA + 13)
+#define VPNC_PA_COUNT VPNC_PAPROCESSCOUNT - VPNG_PA
+
+/* HW: Setup Counters. */
+#define VPNC_SECULLTRIANGLECOUNT (VPNG_SETUP + 1)
+#define VPNC_SECULLLINECOUNT (VPNG_SETUP + 2)
+#define VPNC_SECLIPTRIANGLECOUNT (VPNG_SETUP + 3)
+#define VPNC_SECLIPLINECOUNT (VPNG_SETUP + 4)
+#define VPNC_SESTARVECOUNT (VPNG_SETUP + 5)
+#define VPNC_SESTALLCOUNT (VPNG_SETUP + 6)
+#define VPNC_SERECEIVETRIANGLECOUNT (VPNG_SETUP + 7)
+#define VPNC_SESENDTRIANGLECOUNT (VPNG_SETUP + 8)
+#define VPNC_SERECEIVELINESCOUNT (VPNG_SETUP + 9)
+#define VPNC_SESENDLINESCOUNT (VPNG_SETUP + 10)
+#define VPNC_SENONIDLESTARVECOUNT (VPNG_SETUP + 11)
+#define VPNC_SETRIVIALREJLINECOUNT (VPNG_SETUP + 12)
+#define VPNC_SEPROCESSCOUNT (VPNG_SETUP + 13)
+#define VPNC_SE_COUNT VPNC_SEPROCESSCOUNT - VPNG_SETUP
+
+/* HW: RA Counters. */
+#define VPNC_RAVALIDPIXCOUNT (VPNG_RA + 1)
+#define VPNC_RATOTALQUADCOUNT (VPNG_RA + 2)
+#define VPNC_RAVALIDQUADCOUNTEZ (VPNG_RA + 3)
+#define VPNC_RAINPUTPRIMCOUNT (VPNG_RA + 4)
+#define VPNC_RAPIPECACHEMISSCOUNT (VPNG_RA + 5)
+#define VPNC_RAPREFCACHEMISSCOUNT (VPNG_RA + 6)
+#define VPNC_RAPIPEHZCACHEMISSCOUNT (VPNG_RA + 7)
+#define VPNC_RAPREFHZCACHEMISSCOUNT (VPNG_RA + 8)
+#define VPNC_RAOUTPUTQUADCOUNT (VPNG_RA + 9)
+#define VPNC_RAOUTPUTPIXELCOUNT (VPNG_RA + 10)
+#define VPNC_RAEEZCULLCOUNT (VPNG_RA + 11)
+#define VPNC_RANONIDLESTARVECOUNT (VPNG_RA + 12)
+#define VPNC_RASTARVELCOUNT (VPNG_RA + 13)
+#define VPNC_RASTALLCOUNT (VPNG_RA + 14)
+#define VPNC_RAPROCESSCOUNT (VPNG_RA + 15)
+#define VPNC_RA_COUNT VPNC_RAPROCESSCOUNT - VPNG_RA
+
+/* HW: TEX Counters. */
+#define VPNC_TXTOTBILINEARREQ (VPNG_TX + 1)
+#define VPNC_TXTOTTRILINEARREQ (VPNG_TX + 2)
+#define VPNC_TXTOTDISCARDTEXREQ (VPNG_TX + 3)
+#define VPNC_TXTOTTEXREQ (VPNG_TX + 4)
+#define VPNC_TXMC0MISSCOUNT (VPNG_TX + 5)
+#define VPNC_TXMC0REQCOUNT (VPNG_TX + 6)
+#define VPNC_TXMC1MISSCOUNT (VPNG_TX + 7)
+#define VPNC_TXMC1REQCOUNT (VPNG_TX + 8)
+#define VPNC_TX_COUNT VPNC_TXMC1REQCOUNT - VPNG_TX
+
+/* HW: PE Counters. */
+#define VPNC_PE0KILLEDBYCOLOR (VPNG_PE + 1)
+#define VPNC_PE0KILLEDBYDEPTH (VPNG_PE + 2)
+#define VPNC_PE0DRAWNBYCOLOR (VPNG_PE + 3)
+#define VPNC_PE0DRAWNBYDEPTH (VPNG_PE + 4)
+#define VPNC_PE1KILLEDBYCOLOR (VPNG_PE + 5)
+#define VPNC_PE1KILLEDBYDEPTH (VPNG_PE + 6)
+#define VPNC_PE1DRAWNBYCOLOR (VPNG_PE + 7)
+#define VPNC_PE1DRAWNBYDEPTH (VPNG_PE + 8)
+#define VPNC_PE_COUNT VPNC_PE1DRAWNBYDEPTH - VPNG_PE
+
+/* HW: MCC Counters. */
+#define VPNC_MCCREADREQ8BCOLORPIPE (VPNG_MCC + 1)
+#define VPNC_MCCREADREQ8BSOCOLORPIPE (VPNG_MCC + 2)
+#define VPNC_MCCWRITEREQ8BCOLORPIPE (VPNG_MCC + 3)
+#define VPNC_MCCREADREQSOCOLORPIPE (VPNG_MCC + 4)
+#define VPNC_MCCWRITEREQCOLORPIPE (VPNG_MCC + 5)
+#define VPNC_MCCREADREQ8BDEPTHPIPE (VPNG_MCC + 6)
+#define VPNC_MCCREADREQ8BSFDEPTHPIPE (VPNG_MCC + 7)
+#define VPNC_MCCWRITEREQ8BDEPTHPIPE (VPNG_MCC + 8)
+#define VPNC_MCCREADREQSFDEPTHPIPE (VPNG_MCC + 9)
+#define VPNC_MCCWRITEREQDEPTHPIPE (VPNG_MCC + 10)
+#define VPNC_MCCREADREQ8BOTHERPIPE (VPNG_MCC + 11)
+#define VPNC_MCCWRITEREQ8BOTHERPIPE (VPNG_MCC + 12)
+#define VPNC_MCCREADREQOTHERPIPE (VPNG_MCC + 13)
+#define VPNC_MCCWRITEREQOTHERPIPE (VPNG_MCC + 14)
+#define VPNC_MCCAXIMINLATENCY (VPNG_MCC + 15)
+#define VPNC_MCCAXIMAXLATENCY (VPNG_MCC + 16)
+#define VPNC_MCCAXITOTALLATENCY (VPNG_MCC + 17)
+#define VPNC_MCCAXISAMPLECOUNT (VPNG_MCC + 18)
+#define VPNC_MCCFEREADBANDWIDTH (VPNG_MCC + 19)
+#define VPNC_MCCMMUREADBANDWIDTH (VPNG_MCC + 20)
+#define VPNC_MCCBLTREADBANDWIDTH (VPNG_MCC + 21)
+#define VPNC_MCCSH0READBANDWIDTH (VPNG_MCC + 22)
+#define VPNC_MCCSH1READBANDWIDTH (VPNG_MCC + 23)
+#define VPNC_MCCPEWRITEBANDWIDTH (VPNG_MCC + 24)
+#define VPNC_MCCBLTWRITEBANDWIDTH (VPNG_MCC + 25)
+#define VPNC_MCCSH0WRITEBANDWIDTH (VPNG_MCC + 26)
+#define VPNC_MCCSH1WRITEBANDWIDTH (VPNG_MCC + 27)
+#define VPNC_MCC_COUNT VPNC_MCCSH1WRITEBANDWIDTH - VPNG_MCC
+
+/* HW: MCZ Counters. */
+#define VPNC_MCZREADREQ8BCOLORPIPE (VPNG_MCZ + 1)
+#define VPNC_MCZREADREQ8BSOCOLORPIPE (VPNG_MCZ + 2)
+#define VPNC_MCZWRITEREQ8BCOLORPIPE (VPNG_MCZ + 3)
+#define VPNC_MCZREADREQSOCOLORPIPE (VPNG_MCZ + 4)
+#define VPNC_MCZWRITEREQCOLORPIPE (VPNG_MCZ + 5)
+#define VPNC_MCZREADREQ8BDEPTHPIPE (VPNG_MCZ + 6)
+#define VPNC_MCZREADREQ8BSFDEPTHPIPE (VPNG_MCZ + 7)
+#define VPNC_MCZWRITEREQ8BDEPTHPIPE (VPNG_MCZ + 8)
+#define VPNC_MCZREADREQSFDEPTHPIPE (VPNG_MCZ + 9)
+#define VPNC_MCZWRITEREQDEPTHPIPE (VPNG_MCZ + 10)
+#define VPNC_MCZREADREQ8BOTHERPIPE (VPNG_MCZ + 11)
+#define VPNC_MCZWRITEREQ8BOTHERPIPE (VPNG_MCZ + 12)
+#define VPNC_MCZREADREQOTHERPIPE (VPNG_MCZ + 13)
+#define VPNC_MCZWRITEREQOTHERPIPE (VPNG_MCZ + 14)
+#define VPNC_MCZAXIMINLATENCY (VPNG_MCZ + 15)
+#define VPNC_MCZAXIMAXLATENCY (VPNG_MCZ + 16)
+#define VPNC_MCZAXITOTALLATENCY (VPNG_MCZ + 17)
+#define VPNC_MCZAXISAMPLECOUNT (VPNG_MCZ + 18)
+#define VPNC_MCZ_COUNT VPNC_MCZAXISAMPLECOUNT - VPNG_MCZ
+
+/* HW: HI Counters. */
+#define VPNC_HI0READ8BYTE (VPNG_HI + 1)
+#define VPNC_HI0WRITE8BYTE (VPNG_HI + 2)
+#define VPNC_HI0READREQ (VPNG_HI + 3)
+#define VPNC_HI0WRITEREQ (VPNG_HI + 4)
+#define VPNC_HI0AXIREADREQSTALL (VPNG_HI + 5)
+#define VPNC_HI0AXIWRITEREQSTALL (VPNG_HI + 6)
+#define VPNC_HI0AXIWRITEDATASTALL (VPNG_HI + 7)
+#define VPNC_HI1READ8BYTE (VPNG_HI + 8)
+#define VPNC_HI1WRITE8BYTE (VPNG_HI + 9)
+#define VPNC_HI1READREQ (VPNG_HI + 10)
+#define VPNC_HI1WRITEREQ (VPNG_HI + 11)
+#define VPNC_HI1AXIREADREQSTALL (VPNG_HI + 12)
+#define VPNC_HI1AXIWRITEREQSTALL (VPNG_HI + 13)
+#define VPNC_HI1AXIWRITEDATASTALL (VPNG_HI + 14)
+#define VPNC_HITOTALCYCLES (VPNG_HI + 15)
+#define VPNC_HIIDLECYCLES (VPNG_HI + 16)
+#define VPNC_HIREAD8BYTE (VPNG_HI + 17)
+#define VPNC_HIWRITE8BYTE (VPNG_HI + 18)
+#define VPNC_HI_COUNT VPNC_HIWRITE8BYTE - VPNG_HI
+
+/* HW: L2 Counters. */
+#define VPNC_L2AXI0READREQCOUNT (VPNG_L2 + 1)
+#define VPNC_L2AXI1READREQCOUNT (VPNG_L2 + 2)
+#define VPNC_L2AXI0WRITEREQCOUNT (VPNG_L2 + 3)
+#define VPNC_L2AXI1WRITEREQCOUNT (VPNG_L2 + 4)
+#define VPNC_L2READTRANSREQBYAXI0 (VPNG_L2 + 5)
+#define VPNC_L2READTRANSREQBYAXI1 (VPNG_L2 + 6)
+#define VPNC_L2WRITETRANSREQBYAXI0 (VPNG_L2 + 7)
+#define VPNC_L2WRITETRANSREQBYAXI1 (VPNG_L2 + 8)
+#define VPNC_L2AXI0MINLATENCY (VPNG_L2 + 9)
+#define VPNC_L2AXI0MAXLATENCY (VPNG_L2 + 10)
+#define VPNC_L2AXI0TOTLATENCY (VPNG_L2 + 11)
+#define VPNC_L2AXI0TOTREQCOUNT (VPNG_L2 + 12)
+#define VPNC_L2AXI1MINLATENCY (VPNG_L2 + 13)
+#define VPNC_L2AXI1MAXLATENCY (VPNG_L2 + 14)
+#define VPNC_L2AXI1TOTLATENCY (VPNG_L2 + 15)
+#define VPNC_L2AXI1TOTREQCOUNT (VPNG_L2 + 16)
+#define VPNC_L2_COUNT VPNC_L2AXI1TOTREQCOUNT - VPNG_L2
+
+/* HW: FE Counters. */
+#define VPNC_FEDRAWCOUNT (VPNG_FE + 1)
+#define VPNC_FEOUTVERTEXCOUNT (VPNG_FE + 2)
+#define VPNC_FECACHEMISSCOUNT (VPNG_FE + 3)
+#define VPNC_FECACHELKCOUNT (VPNG_FE + 4)
+#define VPNC_FESTALLCOUNT (VPNG_FE + 5)
+#define VPNC_FESTARVECOUNT (VPNG_FE + 6)
+#define VPNC_FEPROCESSCOUNT (VPNG_FE + 7)
+#define VPNC_FE_COUNT VPNC_FEPROCESSCOUNT - VPNG_FE
+
+#define TOTAL_COUNTER_NUMBER (VPNC_FE_COUNT + VPNC_VS_COUNT + VPNC_PA_COUNT + VPNC_SE_COUNT + VPNC_RA_COUNT \
+ + VPNC_PS_COUNT + VPNC_TX_COUNT + VPNC_PE_COUNT + VPNC_MCC_COUNT + VPNC_MCZ_COUNT \
+ + VPNC_HI_COUNT + VPNC_L2_COUNT)
+
+#define TOTAL_MODULE_NUMBER 12
+
+/* PROGRAM: Shader program counters. */
+#define VPC_PVSINSTRCOUNT (VPG_PVS + PVS_INSTRCOUNT)
+#define VPC_PVSALUINSTRCOUNT (VPG_PVS + PVS_ALUINSTRCOUNT)
+#define VPC_PVSTEXINSTRCOUNT (VPG_PVS + PVS_TEXINSTRCOUNT)
+#define VPC_PVSATTRIBCOUNT (VPG_PVS + PVS_ATTRIBCOUNT)
+#define VPC_PVSUNIFORMCOUNT (VPG_PVS + PVS_UNIFORMCOUNT)
+#define VPC_PVSFUNCTIONCOUNT (VPG_PVS + PVS_FUNCTIONCOUNT)
+#define VPC_PVSSOURCE (VPG_PVS + PVS_SOURCE)
+
+#define VPC_PPSINSTRCOUNT (VPG_PPS + PPS_INSTRCOUNT)
+#define VPC_PPSALUINSTRCOUNT (VPG_PPS + PPS_ALUINSTRCOUNT)
+#define VPC_PPSTEXINSTRCOUNT (VPG_PPS + PPS_TEXINSTRCOUNT)
+#define VPC_PPSATTRIBCOUNT (VPG_PPS + PPS_ATTRIBCOUNT)
+#define VPC_PPSUNIFORMCOUNT (VPG_PPS + PPS_UNIFORMCOUNT)
+#define VPC_PPSFUNCTIONCOUNT (VPG_PPS + PPS_FUNCTIONCOUNT)
+#define VPC_PPSSOURCE (VPG_PPS + PPS_SOURCE)
+
+#define VPC_PROGRAMHANDLE (VPG_PROG + 1)
+
+#define VPC_ES30_DRAW_NO (VPG_ES30_DRAW + 1)
+#define VPC_ES11_DRAW_NO (VPG_ES11_DRAW + 1)
+#define VPC_ES30_GPU_NO (VPG_MULTI_GPU + 1)
+
+
+#define MODULE_FRONT_END_COUNTER_NUM 0x5
+#define MODULE_VERTEX_SHADER_COUNTER_NUM 0x9
+#define MODULE_PRIMITIVE_ASSEMBLY_COUNTER_NUM 0xC
+#define MODULE_SETUP_COUNTER_NUM 0xD
+#define MODULE_RASTERIZER_COUNTER_NUM 0xE
+#define MODULE_PIXEL_SHADER_COUNTER_NUM 0x9
+#define MODULE_TEXTURE_COUNTER_NUM 0x8
+#define MODULE_PIXEL_ENGINE_COUNTER_NUM 0x8
+#define MODULE_MEMORY_CONTROLLER_COLOR_COUNTER_NUM 0xC
+#define MODULE_MEMORY_CONTROLLER_DEPTH_COUNTER_NUM 0xC
+#define MODULE_HOST_INTERFACE0_COUNTER_NUM 0x9
+#define MODULE_HOST_INTERFACE1_COUNTER_NUM 0x7
+#define MODULE_GPUL2_CACHE_COUNTER_NUM 0xE
+#define TOTAL_PROBE_NUMBER (MODULE_FRONT_END_COUNTER_NUM + MODULE_VERTEX_SHADER_COUNTER_NUM + MODULE_PRIMITIVE_ASSEMBLY_COUNTER_NUM \
+ + MODULE_SETUP_COUNTER_NUM + MODULE_RASTERIZER_COUNTER_NUM + MODULE_PIXEL_SHADER_COUNTER_NUM \
+ + MODULE_TEXTURE_COUNTER_NUM + MODULE_PIXEL_ENGINE_COUNTER_NUM + MODULE_MEMORY_CONTROLLER_COLOR_COUNTER_NUM \
+ + MODULE_MEMORY_CONTROLLER_DEPTH_COUNTER_NUM + MODULE_HOST_INTERFACE0_COUNTER_NUM + MODULE_HOST_INTERFACE1_COUNTER_NUM \
+ + MODULE_GPUL2_CACHE_COUNTER_NUM)
+
+
+#ifdef ANDROID
+#define DEFAULT_PROFILE_FILE_NAME "/sdcard/vprofiler.vpd"
+#else
+#define DEFAULT_PROFILE_FILE_NAME "vprofiler.vpd"
+#endif
+
+#if gcdENDIAN_BIG
+#define BIG_ENDIAN_TRANS_INT(x) ((gctUINT32)(\
+ (((gctUINT32)(x) & (gctUINT32)0x000000FFUL) << 24) | \
+ (((gctUINT32)(x) & (gctUINT32)0x0000FF00UL) << 8) | \
+ (((gctUINT32)(x) & (gctUINT32)0x00FF0000UL) >> 8) | \
+ (((gctUINT32)(x) & (gctUINT32)0xFF000000UL) >> 24)))
+#else
+#define BIG_ENDIAN_TRANS_INT(x) x
+#endif
+
+/* Write a data value. */
+#define gcmWRITE_VALUE(IntData) \
+ do \
+ { \
+ gceSTATUS status; \
+ gctINT32 value = IntData; \
+ value = BIG_ENDIAN_TRANS_INT(value); \
+ gcmERR_BREAK(gcoPROFILER_Write(Profiler, gcmSIZEOF(value), &value)); \
+ } \
+ while (gcvFALSE)
+
+#define gcmWRITE_CONST(Const) \
+ do \
+ { \
+ gceSTATUS status; \
+ gctINT32 data = Const; \
+ data = BIG_ENDIAN_TRANS_INT(data); \
+ gcmERR_BREAK(gcoPROFILER_Write(Profiler, gcmSIZEOF(data), &data)); \
+ } \
+ while (gcvFALSE)
+
+#define gcmWRITE_COUNTER(Counter, Value) \
+ gcmWRITE_CONST(Counter); \
+ gcmWRITE_VALUE(Value)
+
+/* Write a data value. */
+#define gcmRECORD_VALUE(IntData) \
+ do \
+ { \
+ gctINT32 value = IntData; \
+ value = BIG_ENDIAN_TRANS_INT(value); \
+ counterData[counterIndex++] = value; \
+ } \
+ while (gcvFALSE)
+
+#define gcmRECORD_CONST(Const) \
+ do \
+ { \
+ gctINT32 data = Const; \
+ data = BIG_ENDIAN_TRANS_INT(data); \
+ counterData[counterIndex++] = data; \
+ } \
+ while (gcvFALSE)
+
+#define gcmRECORD_COUNTER(Counter, Value) \
+ gcmRECORD_CONST(Counter); \
+ gcmRECORD_VALUE(Value)
+
+/* Write a string value (char*). */
+#define gcmWRITE_STRING(String) \
+ do \
+ { \
+ gceSTATUS status; \
+ gctINT32 length; \
+ length = (gctINT32) gcoOS_StrLen((gctSTRING)String, gcvNULL); \
+ length = BIG_ENDIAN_TRANS_INT(length); \
+ gcmERR_BREAK(gcoPROFILER_Write(Profiler, gcmSIZEOF(length), &length)); \
+ gcmERR_BREAK(gcoPROFILER_Write(Profiler, length, String)); \
+ } \
+ while (gcvFALSE)
+
+#define gcmWRITE_BUFFER(Size, Buffer) \
+ do \
+ { \
+ gceSTATUS status; \
+ gcmERR_BREAK(gcoPROFILER_Write(Profiler, Size, Buffer)); \
+ } \
+ while (gcvFALSE)
+
+#define gcmGET_COUNTER(counter, counterId) \
+ do \
+ { \
+ if ((gctUINT32)*(memory + counterId + offset) == 0xdeaddead) \
+ { \
+ counter = 0xdeaddead; \
+ } \
+ else \
+ { \
+ gctUINT64_PTR Memory = memory; \
+ Memory += TOTAL_PROBE_NUMBER * CoreId; \
+ counter = (gctUINT32)*(Memory + counterId + offset); \
+ } \
+ } \
+ while (gcvFALSE)
+
+#define gcmGET_LATENCY_COUNTER(minLatency, maxLatency, counterId) \
+ do \
+ { \
+ if ((gctUINT32)*(memory + counterId + offset) == 0xdeaddead) \
+ { \
+ minLatency = maxLatency = 0xdeaddead; \
+ } \
+ else \
+ { \
+ gctUINT64_PTR Memory = memory; \
+ Memory += TOTAL_PROBE_NUMBER * CoreId; \
+ maxLatency = (((gctUINT32)*(Memory + counterId + offset) & 0xfff000) >> 12); \
+ minLatency = ((gctUINT32)*(Memory + counterId + offset) & 0x000fff); \
+ if (minLatency == 4095) \
+ minLatency = 0; \
+ } \
+ } \
+ while (gcvFALSE)
+
+typedef enum _gceCOUNTER
+{
+ gcvCOUNTER_FRONT_END,
+ gcvCOUNTER_VERTEX_SHADER,
+ gcvCOUNTER_PRIMITIVE_ASSEMBLY,
+ gcvCOUNTER_SETUP,
+ gcvCOUNTER_RASTERIZER,
+ gcvCOUNTER_PIXEL_SHADER,
+ gcvCOUNTER_TEXTURE,
+ gcvCOUNTER_PIXEL_ENGINE,
+ gcvCOUNTER_MEMORY_CONTROLLER_COLOR,
+ gcvCOUNTER_MEMORY_CONTROLLER_DEPTH,
+ gcvCOUNTER_HOST_INTERFACE0,
+ gcvCOUNTER_HOST_INTERFACE1,
+ gcvCOUNTER_GPUL2_CACHE,
+ gcvCOUNTER_COUNT
+}
+gceCOUNTER;
+
+typedef enum _gceProfilerClient
+{
+ gcvCLIENT_OPENGLES11 = 1,
+ gcvCLIENT_OPENGLES,
+ gcvCLIENT_OPENGL,
+ gcvCLIENT_OPENVG,
+ gcvCLIENT_OPENCL,
+ gcvCLIENT_OPENVX,
+ gcvCLIENT_OPENVK,
+}
+gceProfilerClient;
+
+/* HW profile information. */
+typedef struct _gcsPROFILER_COUNTERS_PART1
+{
+ gctUINT32 gpuTotalRead64BytesPerFrame;
+ gctUINT32 gpuTotalWrite64BytesPerFrame;
+
+ /* FE */
+ gctUINT32 fe_draw_count;
+ gctUINT32 fe_out_vertex_count;
+ gctUINT32 fe_cache_miss_count;
+ gctUINT32 fe_cache_lk_count;
+ gctUINT32 fe_stall_count;
+ gctUINT32 fe_starve_count;
+ gctUINT32 fe_process_count;
+
+ /* PE */
+ gctUINT32 pe0_pixel_count_killed_by_color_pipe;
+ gctUINT32 pe0_pixel_count_killed_by_depth_pipe;
+ gctUINT32 pe0_pixel_count_drawn_by_color_pipe;
+ gctUINT32 pe0_pixel_count_drawn_by_depth_pipe;
+ gctUINT32 pe1_pixel_count_killed_by_color_pipe;
+ gctUINT32 pe1_pixel_count_killed_by_depth_pipe;
+ gctUINT32 pe1_pixel_count_drawn_by_color_pipe;
+ gctUINT32 pe1_pixel_count_drawn_by_depth_pipe;
+
+ /* SH */
+ gctUINT32 shader_cycle_count;
+ gctUINT32 vs_shader_cycle_count;
+ gctUINT32 ps_shader_cycle_count;
+ gctUINT32 ps_inst_counter;
+ gctUINT32 ps_rendered_pixel_counter;
+ gctUINT32 vs_inst_counter;
+ gctUINT32 vs_rendered_vertice_counter;
+ gctUINT32 vs_branch_inst_counter;
+ gctUINT32 vs_texld_inst_counter;
+ gctUINT32 ps_branch_inst_counter;
+ gctUINT32 ps_texld_inst_counter;
+ gctUINT32 vs_non_idle_starve_count;
+ gctUINT32 vs_starve_count;
+ gctUINT32 vs_stall_count;
+ gctUINT32 vs_process_count;
+ gctUINT32 ps_non_idle_starve_count;
+ gctUINT32 ps_starve_count;
+ gctUINT32 ps_stall_count;
+ gctUINT32 ps_process_count;
+
+ /* PA */
+ gctUINT32 pa_input_vtx_counter;
+ gctUINT32 pa_input_prim_counter;
+ gctUINT32 pa_output_prim_counter;
+ gctUINT32 pa_depth_clipped_counter;
+ gctUINT32 pa_trivial_rejected_counter;
+ gctUINT32 pa_culled_prim_counter;
+ gctUINT32 pa_droped_prim_counter;
+ gctUINT32 pa_frustum_clipped_prim_counter;
+ gctUINT32 pa_frustum_clipdroped_prim_counter;
+ gctUINT32 pa_non_idle_starve_count;
+ gctUINT32 pa_starve_count;
+ gctUINT32 pa_stall_count;
+ gctUINT32 pa_process_count;
+
+ /* SE */
+ gctUINT32 se_culled_triangle_count;
+ gctUINT32 se_culled_lines_count;
+ gctUINT32 se_clipped_triangle_count;
+ gctUINT32 se_clipped_line_count;
+ gctUINT32 se_starve_count;
+ gctUINT32 se_stall_count;
+ gctUINT32 se_receive_triangle_count;
+ gctUINT32 se_send_triangle_count;
+ gctUINT32 se_receive_lines_count;
+ gctUINT32 se_send_lines_count;
+ gctUINT32 se_process_count;
+ gctUINT32 se_trivial_rejected_line_count;
+ gctUINT32 se_non_idle_starve_count;
+
+ /* RA */
+ gctUINT32 ra_input_prim_count;
+ gctUINT32 ra_total_quad_count;
+ gctUINT32 ra_valid_quad_count_after_early_z;
+ gctUINT32 ra_valid_pixel_count_to_render;
+ gctUINT32 ra_output_valid_quad_count;
+ gctUINT32 ra_output_valid_pixel_count;
+ gctUINT32 ra_pipe_cache_miss_counter;
+ gctUINT32 ra_pipe_hz_cache_miss_counter;
+ gctUINT32 ra_prefetch_cache_miss_counter;
+ gctUINT32 ra_prefetch_hz_cache_miss_counter;
+ gctUINT32 ra_eez_culled_counter;
+ gctUINT32 ra_non_idle_starve_count;
+ gctUINT32 ra_starve_count;
+ gctUINT32 ra_stall_count;
+ gctUINT32 ra_process_count;
+
+ /* TX */
+ gctUINT32 tx_total_bilinear_requests;
+ gctUINT32 tx_total_trilinear_requests;
+ gctUINT32 tx_total_discarded_texture_requests;
+ gctUINT32 tx_total_texture_requests;
+ gctUINT32 tx_mc0_miss_count;
+ gctUINT32 tx_mc0_request_byte_count;
+ gctUINT32 tx_mc1_miss_count;
+ gctUINT32 tx_mc1_request_byte_count;
+ gctUINT32 tx_non_idle_starve_count;
+ gctUINT32 tx_starve_count;
+ gctUINT32 tx_stall_count;
+ gctUINT32 tx_process_count;
+}
+gcsPROFILER_COUNTERS_PART1;
+
+typedef struct _gcsPROFILER_COUNTERS_PART2
+{
+ /* MCC */
+ gctUINT32 mcc_total_read_req_8B_from_colorpipe;
+ gctUINT32 mcc_total_read_req_8B_sentout_from_colorpipe;
+ gctUINT32 mcc_total_write_req_8B_from_colorpipe;
+ gctUINT32 mcc_total_read_req_sentout_from_colorpipe;
+ gctUINT32 mcc_total_write_req_from_colorpipe;
+ gctUINT32 mcc_total_read_req_8B_from_depthpipe;
+ gctUINT32 mcc_total_read_req_8B_sentout_from_depthpipe;
+ gctUINT32 mcc_total_write_req_8B_from_depthpipe;
+ gctUINT32 mcc_total_read_req_sentout_from_depthpipe;
+ gctUINT32 mcc_total_write_req_from_depthpipe;
+ gctUINT32 mcc_total_read_req_8B_from_others;
+ gctUINT32 mcc_total_write_req_8B_from_others;
+ gctUINT32 mcc_total_read_req_from_others;
+ gctUINT32 mcc_total_write_req_from_others;
+ gctUINT32 mcc_axi_total_latency;
+ gctUINT32 mcc_axi_sample_count;
+ gctUINT32 mcc_axi_max_latency;
+ gctUINT32 mcc_axi_min_latency;
+ gctUINT32 mc_fe_read_bandwidth;
+ gctUINT32 mc_mmu_read_bandwidth;
+ gctUINT32 mc_blt_read_bandwidth;
+ gctUINT32 mc_sh0_read_bandwidth;
+ gctUINT32 mc_sh1_read_bandwidth;
+ gctUINT32 mc_pe_write_bandwidth;
+ gctUINT32 mc_blt_write_bandwidth;
+ gctUINT32 mc_sh0_write_bandwidth;
+ gctUINT32 mc_sh1_write_bandwidth;
+
+ /* MCZ */
+ gctUINT32 mcz_total_read_req_8B_from_colorpipe;
+ gctUINT32 mcz_total_read_req_8B_sentout_from_colorpipe;
+ gctUINT32 mcz_total_write_req_8B_from_colorpipe;
+ gctUINT32 mcz_total_read_req_sentout_from_colorpipe;
+ gctUINT32 mcz_total_write_req_from_colorpipe;
+ gctUINT32 mcz_total_read_req_8B_from_depthpipe;
+ gctUINT32 mcz_total_read_req_8B_sentout_from_depthpipe;
+ gctUINT32 mcz_total_write_req_8B_from_depthpipe;
+ gctUINT32 mcz_total_read_req_sentout_from_depthpipe;
+ gctUINT32 mcz_total_write_req_from_depthpipe;
+ gctUINT32 mcz_total_read_req_8B_from_others;
+ gctUINT32 mcz_total_write_req_8B_from_others;
+ gctUINT32 mcz_total_read_req_from_others;
+ gctUINT32 mcz_total_write_req_from_others;
+ gctUINT32 mcz_axi_total_latency;
+ gctUINT32 mcz_axi_sample_count;
+ gctUINT32 mcz_axi_max_latency;
+ gctUINT32 mcz_axi_min_latency;
+
+ /* HI */
+ gctUINT32 hi0_total_read_8B_count;
+ gctUINT32 hi0_total_write_8B_count;
+ gctUINT32 hi0_total_read_request_count;
+ gctUINT32 hi0_total_write_request_count;
+ gctUINT32 hi0_axi_cycles_read_request_stalled;
+ gctUINT32 hi0_axi_cycles_write_request_stalled;
+ gctUINT32 hi0_axi_cycles_write_data_stalled;
+ gctUINT32 hi1_total_read_8B_count;
+ gctUINT32 hi1_total_write_8B_count;
+ gctUINT32 hi1_total_read_request_count;
+ gctUINT32 hi1_total_write_request_count;
+ gctUINT32 hi1_axi_cycles_read_request_stalled;
+ gctUINT32 hi1_axi_cycles_write_request_stalled;
+ gctUINT32 hi1_axi_cycles_write_data_stalled;
+ gctUINT32 hi_total_cycle_count;
+ gctUINT32 hi_total_idle_cycle_count;
+ gctUINT32 hi_total_read_8B_count;
+ gctUINT32 hi_total_write_8B_count;
+
+ /* L2 */
+ gctUINT32 l2_total_axi0_read_request_count;
+ gctUINT32 l2_total_axi1_read_request_count;
+ gctUINT32 l2_total_axi0_write_request_count;
+ gctUINT32 l2_total_axi1_write_request_count;
+ gctUINT32 l2_total_read_transactions_request_by_axi0;
+ gctUINT32 l2_total_read_transactions_request_by_axi1;
+ gctUINT32 l2_total_write_transactions_request_by_axi0;
+ gctUINT32 l2_total_write_transactions_request_by_axi1;
+ gctUINT32 l2_axi0_minmax_latency;
+ gctUINT32 l2_axi0_min_latency;
+ gctUINT32 l2_axi0_max_latency;
+ gctUINT32 l2_axi0_total_latency;
+ gctUINT32 l2_axi0_total_request_count;
+ gctUINT32 l2_axi1_minmax_latency;
+ gctUINT32 l2_axi1_min_latency;
+ gctUINT32 l2_axi1_max_latency;
+ gctUINT32 l2_axi1_total_latency;
+ gctUINT32 l2_axi1_total_request_count;
+}
+gcsPROFILER_COUNTERS_PART2;
+
+typedef struct _gcsPROFILER_COUNTERS
+{
+ gcsPROFILER_COUNTERS_PART1 counters_part1;
+ gcsPROFILER_COUNTERS_PART2 counters_part2;
+}
+gcsPROFILER_COUNTERS;
+
+#define NumOfPerFrameBuf 16
+#define NumOfPerDrawBuf 128
+
+typedef enum _gceCOUNTER_OPTYPE
+{
+ gcvCOUNTER_OP_DRAW = 0,
+ gcvCOUNTER_OP_BLT = 1,
+ gcvCOUNTER_OP_COMPUTE = 2,
+ gcvCOUNTER_OP_RS = 3,
+ gcvCOUNTER_OP_FINISH = 4,
+ gcvCOUNTER_OP_FRAME = 5,
+ gcvCOUNTER_OP_NONE = 6
+}
+gceCOUNTER_OPTYPE;
+
+typedef struct gcsCounterBuffer * gcsCounterBuffer_PTR;
+
+struct gcsCounterBuffer
+{
+ gcsPROFILER_COUNTERS *counters;
+ gctHANDLE couterBufobj;
+ gctUINT32 probeAddress;
+ gctPOINTER logicalAddress;
+ gceCOUNTER_OPTYPE opType;
+ gctUINT32 opID;
+ gctUINT32 startPos;
+ gctUINT32 endPos;
+ gctUINT32 dataSize;
+ gctBOOL available;
+ gctBOOL needDump;
+ gcsCounterBuffer_PTR next;
+ gcsCounterBuffer_PTR prev;
+};
+
+typedef struct _gcoPROFILER * gcoPROFILER;
+
+struct _gcoPROFILER
+{
+ gctBOOL enable;
+ gctBOOL enablePrint;
+ gctBOOL disableProbe;
+ gctBOOL probeMode;
+
+ gctFILE file;
+ gctCHAR* fileName;
+
+ gcsCounterBuffer_PTR counterBuf;
+ gctUINT32 bufferCount;
+
+ gctBOOL perDrawMode;
+ gctBOOL needDump;
+ gctBOOL counterEnable;
+
+ gceProfilerClient profilerClient;
+
+ /*query some features from hw*/
+ gctUINT32 coreCount;
+ gctUINT32 shaderCoreCount;
+ gctBOOL bHalti4;
+ gctBOOL psRenderPixelFix;
+ gctBOOL axiBus128bits;
+};
+
+typedef enum _gceProbeStatus
+{
+ gcvPROBE_Disabled = 0,
+ gcvPROBE_Paused = 1,
+ gcvPROBE_Enabled = 2,
+}
+gceProbeStatus;
+
+typedef enum _gceProbeCmd
+{
+ gcvPROBECMD_BEGIN = 0,
+ gcvPROBECMD_PAUSE = 1,
+ gcvPROBECMD_RESUME = 2,
+ gcvPROBECMD_END = 3,
+}
+gceProbeCmd;
+
+typedef struct _gcsPROBESTATES
+{
+ gceProbeStatus status;
+ gctUINT32 probeAddress;
+}gcsPROBESTATES;
+
+/* Construct a Profiler object per context. */
+gceSTATUS
+gcoPROFILER_Construct(
+ OUT gcoPROFILER * Profiler
+ );
+
+gceSTATUS
+gcoPROFILER_Destroy(
+ IN gcoPROFILER Profiler
+ );
+
+gceSTATUS
+gcoPROFILER_Enable(
+ IN gcoPROFILER Profiler
+ );
+
+gceSTATUS
+gcoPROFILER_Disable(
+ void
+ );
+
+gceSTATUS
+gcoPROFILER_Begin(
+ IN gcoPROFILER Profiler,
+ IN gceCOUNTER_OPTYPE operationType
+ );
+
+gceSTATUS
+gcoPROFILER_End(
+ IN gcoPROFILER Profiler,
+ IN gceCOUNTER_OPTYPE operationType,
+ IN gctUINT32 OpID
+ );
+
+gceSTATUS
+gcoPROFILER_Write(
+ IN gcoPROFILER Profiler,
+ IN gctSIZE_T ByteCount,
+ IN gctCONST_POINTER Data
+ );
+
+gceSTATUS
+gcoPROFILER_Flush(
+ IN gcoPROFILER Profiler
+ );
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __gc_hal_profiler_h_ */
+
+
diff --git a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_raster.h b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_raster.h
new file mode 100644
index 000000000000..988577ff9285
--- /dev/null
+++ b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_raster.h
@@ -0,0 +1,1109 @@
+/****************************************************************************
+*
+* The MIT License (MIT)
+*
+* Copyright (c) 2014 - 2018 Vivante 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 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 GPL License (GPL)
+*
+* Copyright (C) 2014 - 2018 Vivante 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.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+*****************************************************************************
+*
+* Note: This software is released under dual MIT and GPL licenses. A
+* recipient may use this file under the terms of either the MIT license or
+* GPL License. If you wish to use only one license not the other, you can
+* indicate your decision by deleting one of the above license notices in your
+* version of this file.
+*
+*****************************************************************************/
+
+
+#ifndef __gc_hal_raster_h_
+#define __gc_hal_raster_h_
+
+#include "gc_hal_enum.h"
+#include "gc_hal_types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/******************************************************************************\
+****************************** Object Declarations *****************************
+\******************************************************************************/
+
+typedef struct _gcoBRUSH * gcoBRUSH;
+typedef struct _gcoBRUSH_CACHE * gcoBRUSH_CACHE;
+
+/******************************************************************************\
+******************************** gcoBRUSH Object *******************************
+\******************************************************************************/
+
+/* Create a new solid color gcoBRUSH object. */
+gceSTATUS
+gcoBRUSH_ConstructSingleColor(
+ IN gcoHAL Hal,
+ IN gctUINT32 ColorConvert,
+ IN gctUINT32 Color,
+ IN gctUINT64 Mask,
+ gcoBRUSH * Brush
+ );
+
+/* Create a new monochrome gcoBRUSH object. */
+gceSTATUS
+gcoBRUSH_ConstructMonochrome(
+ IN gcoHAL Hal,
+ IN gctUINT32 OriginX,
+ IN gctUINT32 OriginY,
+ IN gctUINT32 ColorConvert,
+ IN gctUINT32 FgColor,
+ IN gctUINT32 BgColor,
+ IN gctUINT64 Bits,
+ IN gctUINT64 Mask,
+ gcoBRUSH * Brush
+ );
+
+/* Create a color gcoBRUSH object. */
+gceSTATUS
+gcoBRUSH_ConstructColor(
+ IN gcoHAL Hal,
+ IN gctUINT32 OriginX,
+ IN gctUINT32 OriginY,
+ IN gctPOINTER Address,
+ IN gceSURF_FORMAT Format,
+ IN gctUINT64 Mask,
+ gcoBRUSH * Brush
+ );
+
+/* Destroy an gcoBRUSH object. */
+gceSTATUS
+gcoBRUSH_Destroy(
+ IN gcoBRUSH Brush
+ );
+
+/******************************************************************************\
+******************************** gcoSURF Object *******************************
+\******************************************************************************/
+
+/* Set cipping rectangle. */
+gceSTATUS
+gcoSURF_SetClipping(
+ IN gcoSURF Surface
+ );
+
+/* Clear one or more rectangular areas. */
+gceSTATUS
+gcoSURF_Clear2D(
+ IN gcoSURF DestSurface,
+ IN gctUINT32 RectCount,
+ IN gcsRECT_PTR DestRect,
+ IN gctUINT32 LoColor,
+ IN gctUINT32 HiColor
+ );
+
+/* Draw one or more Bresenham lines. */
+gceSTATUS
+gcoSURF_Line(
+ IN gcoSURF Surface,
+ IN gctUINT32 LineCount,
+ IN gcsRECT_PTR Position,
+ IN gcoBRUSH Brush,
+ IN gctUINT8 FgRop,
+ IN gctUINT8 BgRop
+ );
+
+/* Generic rectangular blit. */
+gceSTATUS
+gcoSURF_Blit(
+ IN OPTIONAL gcoSURF SrcSurface,
+ IN gcoSURF DestSurface,
+ IN gctUINT32 RectCount,
+ IN OPTIONAL gcsRECT_PTR SrcRect,
+ IN gcsRECT_PTR DestRect,
+ IN OPTIONAL gcoBRUSH Brush,
+ IN gctUINT8 FgRop,
+ IN gctUINT8 BgRop,
+ IN OPTIONAL gceSURF_TRANSPARENCY Transparency,
+ IN OPTIONAL gctUINT32 TransparencyColor,
+ IN OPTIONAL gctPOINTER Mask,
+ IN OPTIONAL gceSURF_MONOPACK MaskPack
+ );
+
+/* Monochrome blit. */
+gceSTATUS
+gcoSURF_MonoBlit(
+ IN gcoSURF DestSurface,
+ IN gctPOINTER Source,
+ IN gceSURF_MONOPACK SourcePack,
+ IN gcsPOINT_PTR SourceSize,
+ IN gcsPOINT_PTR SourceOrigin,
+ IN gcsRECT_PTR DestRect,
+ IN OPTIONAL gcoBRUSH Brush,
+ IN gctUINT8 FgRop,
+ IN gctUINT8 BgRop,
+ IN gctBOOL ColorConvert,
+ IN gctUINT8 MonoTransparency,
+ IN gceSURF_TRANSPARENCY Transparency,
+ IN gctUINT32 FgColor,
+ IN gctUINT32 BgColor
+ );
+
+/* Filter blit. */
+gceSTATUS
+gcoSURF_FilterBlit(
+ IN gcoSURF SrcSurface,
+ IN gcoSURF DestSurface,
+ IN gcsRECT_PTR SrcRect,
+ IN gcsRECT_PTR DestRect,
+ IN gcsRECT_PTR DestSubRect
+ );
+
+/* Enable alpha blending engine in the hardware and disengage the ROP engine. */
+gceSTATUS
+gcoSURF_EnableAlphaBlend(
+ IN gcoSURF Surface,
+ IN gctUINT8 SrcGlobalAlphaValue,
+ IN gctUINT8 DstGlobalAlphaValue,
+ IN gceSURF_PIXEL_ALPHA_MODE SrcAlphaMode,
+ IN gceSURF_PIXEL_ALPHA_MODE DstAlphaMode,
+ IN gceSURF_GLOBAL_ALPHA_MODE SrcGlobalAlphaMode,
+ IN gceSURF_GLOBAL_ALPHA_MODE DstGlobalAlphaMode,
+ IN gceSURF_BLEND_FACTOR_MODE SrcFactorMode,
+ IN gceSURF_BLEND_FACTOR_MODE DstFactorMode,
+ IN gceSURF_PIXEL_COLOR_MODE SrcColorMode,
+ IN gceSURF_PIXEL_COLOR_MODE DstColorMode
+ );
+
+/* Disable alpha blending engine in the hardware and engage the ROP engine. */
+gceSTATUS
+gcoSURF_DisableAlphaBlend(
+ IN gcoSURF Surface
+ );
+
+gceSTATUS
+gcoSURF_SetDither(
+ IN gcoSURF Surface,
+ IN gctBOOL Dither
+ );
+
+gceSTATUS
+gcoSURF_Set2DSource(
+ gcoSURF Surface,
+ gceSURF_ROTATION Rotation
+ );
+
+gceSTATUS
+gcoSURF_Set2DTarget(
+ gcoSURF Surface,
+ gceSURF_ROTATION Rotation
+ );
+
+/******************************************************************************\
+********************************** gco2D Object *********************************
+\******************************************************************************/
+
+/* Construct a new gco2D object. */
+gceSTATUS
+gco2D_Construct(
+ IN gcoHAL Hal,
+ OUT gco2D * Hardware
+ );
+
+/* Destroy an gco2D object. */
+gceSTATUS
+gco2D_Destroy(
+ IN gco2D Hardware
+ );
+
+/* Sets the maximum number of brushes in the brush cache. */
+gceSTATUS
+gco2D_SetBrushLimit(
+ IN gco2D Hardware,
+ IN gctUINT MaxCount
+ );
+
+/* Flush the brush. */
+gceSTATUS
+gco2D_FlushBrush(
+ IN gco2D Engine,
+ IN gcoBRUSH Brush,
+ IN gceSURF_FORMAT Format
+ );
+
+/* Program the specified solid color brush. */
+gceSTATUS
+gco2D_LoadSolidBrush(
+ IN gco2D Engine,
+ IN gceSURF_FORMAT Format,
+ IN gctUINT32 ColorConvert,
+ IN gctUINT32 Color,
+ IN gctUINT64 Mask
+ );
+
+gceSTATUS
+gco2D_LoadMonochromeBrush(
+ IN gco2D Engine,
+ IN gctUINT32 OriginX,
+ IN gctUINT32 OriginY,
+ IN gctUINT32 ColorConvert,
+ IN gctUINT32 FgColor,
+ IN gctUINT32 BgColor,
+ IN gctUINT64 Bits,
+ IN gctUINT64 Mask
+ );
+
+gceSTATUS
+gco2D_LoadColorBrush(
+ IN gco2D Engine,
+ IN gctUINT32 OriginX,
+ IN gctUINT32 OriginY,
+ IN gctUINT32 Address,
+ IN gceSURF_FORMAT Format,
+ IN gctUINT64 Mask
+ );
+
+/* Configure monochrome source. */
+gceSTATUS
+gco2D_SetMonochromeSource(
+ IN gco2D Engine,
+ IN gctBOOL ColorConvert,
+ IN gctUINT8 MonoTransparency,
+ IN gceSURF_MONOPACK DataPack,
+ IN gctBOOL CoordRelative,
+ IN gceSURF_TRANSPARENCY Transparency,
+ IN gctUINT32 FgColor,
+ IN gctUINT32 BgColor
+ );
+
+/* Configure color source. */
+gceSTATUS
+gco2D_SetColorSource(
+ IN gco2D Engine,
+ IN gctUINT32 Address,
+ IN gctUINT32 Stride,
+ IN gceSURF_FORMAT Format,
+ IN gceSURF_ROTATION Rotation,
+ IN gctUINT32 SurfaceWidth,
+ IN gctBOOL CoordRelative,
+ IN gceSURF_TRANSPARENCY Transparency,
+ IN gctUINT32 TransparencyColor
+ );
+
+/* Configure color source extension for full rotation. */
+gceSTATUS
+gco2D_SetColorSourceEx(
+ IN gco2D Engine,
+ IN gctUINT32 Address,
+ IN gctUINT32 Stride,
+ IN gceSURF_FORMAT Format,
+ IN gceSURF_ROTATION Rotation,
+ IN gctUINT32 SurfaceWidth,
+ IN gctUINT32 SurfaceHeight,
+ IN gctBOOL CoordRelative,
+ IN gceSURF_TRANSPARENCY Transparency,
+ IN gctUINT32 TransparencyColor
+ );
+
+/* Same as gco2D_SetColorSourceEx, but with better 64bit SW-path support.
+** Please do NOT export the API now.
+*/
+gceSTATUS
+gco2D_SetColorSource64(
+ IN gco2D Engine,
+ IN gctUINT32 Address,
+ IN gctPOINTER Logical,
+ IN gctUINT32 Stride,
+ IN gceSURF_FORMAT Format,
+ IN gceSURF_ROTATION Rotation,
+ IN gctUINT32 SurfaceWidth,
+ IN gctUINT32 SurfaceHeight,
+ IN gctBOOL CoordRelative,
+ IN gceSURF_TRANSPARENCY Transparency,
+ IN gctUINT32 TransparencyColor
+ );
+
+/* Configure color source. */
+gceSTATUS
+gco2D_SetColorSourceAdvanced(
+ IN gco2D Engine,
+ IN gctUINT32 Address,
+ IN gctUINT32 Stride,
+ IN gceSURF_FORMAT Format,
+ IN gceSURF_ROTATION Rotation,
+ IN gctUINT32 SurfaceWidth,
+ IN gctUINT32 SurfaceHeight,
+ IN gctBOOL CoordRelative
+ );
+
+gceSTATUS
+gco2D_SetColorSourceN(
+ IN gco2D Engine,
+ IN gctUINT32 Address,
+ IN gctUINT32 Stride,
+ IN gceSURF_FORMAT Format,
+ IN gceSURF_ROTATION Rotation,
+ IN gctUINT32 SurfaceWidth,
+ IN gctUINT32 SurfaceHeight,
+ IN gctUINT32 SurfaceNumber
+ );
+
+/* Configure masked color source. */
+gceSTATUS
+gco2D_SetMaskedSource(
+ IN gco2D Engine,
+ IN gctUINT32 Address,
+ IN gctUINT32 Stride,
+ IN gceSURF_FORMAT Format,
+ IN gctBOOL CoordRelative,
+ IN gceSURF_MONOPACK MaskPack
+ );
+
+/* Configure masked color source extension for full rotation. */
+gceSTATUS
+gco2D_SetMaskedSourceEx(
+ IN gco2D Engine,
+ IN gctUINT32 Address,
+ IN gctUINT32 Stride,
+ IN gceSURF_FORMAT Format,
+ IN gctBOOL CoordRelative,
+ IN gceSURF_MONOPACK MaskPack,
+ IN gceSURF_ROTATION Rotation,
+ IN gctUINT32 SurfaceWidth,
+ IN gctUINT32 SurfaceHeight
+ );
+
+/* Same as gco2D_SetMaskedSourceEx, but with better 64bit SW-path support.
+** Please do NOT export the API now.
+*/
+gceSTATUS
+gco2D_SetMaskedSource64(
+ IN gco2D Engine,
+ IN gctUINT32 Address,
+ IN gctPOINTER Logical,
+ IN gctUINT32 Stride,
+ IN gceSURF_FORMAT Format,
+ IN gctBOOL CoordRelative,
+ IN gceSURF_MONOPACK MaskPack,
+ IN gceSURF_ROTATION Rotation,
+ IN gctUINT32 SurfaceWidth,
+ IN gctUINT32 SurfaceHeight
+ );
+
+/* Setup the source rectangle. */
+gceSTATUS
+gco2D_SetSource(
+ IN gco2D Engine,
+ IN gcsRECT_PTR SrcRect
+ );
+
+/* Set clipping rectangle. */
+gceSTATUS
+gco2D_SetClipping(
+ IN gco2D Engine,
+ IN gcsRECT_PTR Rect
+ );
+
+/* Configure destination. */
+gceSTATUS
+gco2D_SetTarget(
+ IN gco2D Engine,
+ IN gctUINT32 Address,
+ IN gctUINT32 Stride,
+ IN gceSURF_ROTATION Rotation,
+ IN gctUINT32 SurfaceWidth
+ );
+
+/* Configure destination extension for full rotation. */
+gceSTATUS
+gco2D_SetTargetEx(
+ IN gco2D Engine,
+ IN gctUINT32 Address,
+ IN gctUINT32 Stride,
+ IN gceSURF_ROTATION Rotation,
+ IN gctUINT32 SurfaceWidth,
+ IN gctUINT32 SurfaceHeight
+ );
+
+/* Same as gco2D_SetTargetEx, but with better 64bit SW-path support.
+** Please do NOT export the API now.
+*/
+gceSTATUS
+gco2D_SetTarget64(
+ IN gco2D Engine,
+ IN gctUINT32 Address,
+ IN gctPOINTER Logical,
+ IN gctUINT32 Stride,
+ IN gceSURF_ROTATION Rotation,
+ IN gctUINT32 SurfaceWidth,
+ IN gctUINT32 SurfaceHeight
+ );
+
+
+/* Calculate and program the stretch factors. */
+gceSTATUS
+gco2D_CalcStretchFactor(
+ IN gco2D Engine,
+ IN gctINT32 SrcSize,
+ IN gctINT32 DestSize,
+ OUT gctUINT32_PTR Factor
+ );
+
+gceSTATUS
+gco2D_SetStretchFactors(
+ IN gco2D Engine,
+ IN gctUINT32 HorFactor,
+ IN gctUINT32 VerFactor
+ );
+
+/* Calculate and program the stretch factors based on the rectangles. */
+gceSTATUS
+gco2D_SetStretchRectFactors(
+ IN gco2D Engine,
+ IN gcsRECT_PTR SrcRect,
+ IN gcsRECT_PTR DestRect
+ );
+
+/* Create a new solid color gcoBRUSH object. */
+gceSTATUS
+gco2D_ConstructSingleColorBrush(
+ IN gco2D Engine,
+ IN gctUINT32 ColorConvert,
+ IN gctUINT32 Color,
+ IN gctUINT64 Mask,
+ gcoBRUSH * Brush
+ );
+
+/* Create a new monochrome gcoBRUSH object. */
+gceSTATUS
+gco2D_ConstructMonochromeBrush(
+ IN gco2D Engine,
+ IN gctUINT32 OriginX,
+ IN gctUINT32 OriginY,
+ IN gctUINT32 ColorConvert,
+ IN gctUINT32 FgColor,
+ IN gctUINT32 BgColor,
+ IN gctUINT64 Bits,
+ IN gctUINT64 Mask,
+ gcoBRUSH * Brush
+ );
+
+/* Create a color gcoBRUSH object. */
+gceSTATUS
+gco2D_ConstructColorBrush(
+ IN gco2D Engine,
+ IN gctUINT32 OriginX,
+ IN gctUINT32 OriginY,
+ IN gctPOINTER Address,
+ IN gceSURF_FORMAT Format,
+ IN gctUINT64 Mask,
+ gcoBRUSH * Brush
+ );
+
+/* Clear one or more rectangular areas. */
+gceSTATUS
+gco2D_Clear(
+ IN gco2D Engine,
+ IN gctUINT32 RectCount,
+ IN gcsRECT_PTR Rect,
+ IN gctUINT32 Color32,
+ IN gctUINT8 FgRop,
+ IN gctUINT8 BgRop,
+ IN gceSURF_FORMAT DestFormat
+ );
+
+/* Draw one or more Bresenham lines. */
+gceSTATUS
+gco2D_Line(
+ IN gco2D Engine,
+ IN gctUINT32 LineCount,
+ IN gcsRECT_PTR Position,
+ IN gcoBRUSH Brush,
+ IN gctUINT8 FgRop,
+ IN gctUINT8 BgRop,
+ IN gceSURF_FORMAT DestFormat
+ );
+
+/* Draw one or more Bresenham lines based on the 32-bit color. */
+gceSTATUS
+gco2D_ColorLine(
+ IN gco2D Engine,
+ IN gctUINT32 LineCount,
+ IN gcsRECT_PTR Position,
+ IN gctUINT32 Color32,
+ IN gctUINT8 FgRop,
+ IN gctUINT8 BgRop,
+ IN gceSURF_FORMAT DestFormat
+ );
+
+/* Generic blit. */
+gceSTATUS
+gco2D_Blit(
+ IN gco2D Engine,
+ IN gctUINT32 RectCount,
+ IN gcsRECT_PTR Rect,
+ IN gctUINT8 FgRop,
+ IN gctUINT8 BgRop,
+ IN gceSURF_FORMAT DestFormat
+ );
+
+gceSTATUS
+gco2D_Blend(
+ IN gco2D Engine,
+ IN gctUINT32 SrcCount,
+ IN gctUINT32 RectCount,
+ IN gcsRECT_PTR Rect,
+ IN gctUINT8 FgRop,
+ IN gctUINT8 BgRop,
+ IN gceSURF_FORMAT DestFormat
+ );
+
+/* Batch blit. */
+gceSTATUS
+gco2D_BatchBlit(
+ IN gco2D Engine,
+ IN gctUINT32 RectCount,
+ IN gcsRECT_PTR SrcRect,
+ IN gcsRECT_PTR DestRect,
+ IN gctUINT8 FgRop,
+ IN gctUINT8 BgRop,
+ IN gceSURF_FORMAT DestFormat
+ );
+
+/* Stretch blit. */
+gceSTATUS
+gco2D_StretchBlit(
+ IN gco2D Engine,
+ IN gctUINT32 RectCount,
+ IN gcsRECT_PTR Rect,
+ IN gctUINT8 FgRop,
+ IN gctUINT8 BgRop,
+ IN gceSURF_FORMAT DestFormat
+ );
+
+/* Monochrome blit. */
+gceSTATUS
+gco2D_MonoBlit(
+ IN gco2D Engine,
+ IN gctPOINTER StreamBits,
+ IN gcsPOINT_PTR StreamSize,
+ IN gcsRECT_PTR StreamRect,
+ IN gceSURF_MONOPACK SrcStreamPack,
+ IN gceSURF_MONOPACK DestStreamPack,
+ IN gcsRECT_PTR DestRect,
+ IN gctUINT32 FgRop,
+ IN gctUINT32 BgRop,
+ IN gceSURF_FORMAT DestFormat
+ );
+
+gceSTATUS
+gco2D_MonoBlitEx(
+ IN gco2D Engine,
+ IN gctPOINTER StreamBits,
+ IN gctINT32 StreamStride,
+ IN gctINT32 StreamWidth,
+ IN gctINT32 StreamHeight,
+ IN gctINT32 StreamX,
+ IN gctINT32 StreamY,
+ IN gctUINT32 FgColor,
+ IN gctUINT32 BgColor,
+ IN gcsRECT_PTR SrcRect,
+ IN gcsRECT_PTR DstRect,
+ IN gctUINT8 FgRop,
+ IN gctUINT8 BgRop
+ );
+
+/* Set kernel size. */
+gceSTATUS
+gco2D_SetKernelSize(
+ IN gco2D Engine,
+ IN gctUINT8 HorKernelSize,
+ IN gctUINT8 VerKernelSize
+ );
+
+/* Set filter type. */
+gceSTATUS
+gco2D_SetFilterType(
+ IN gco2D Engine,
+ IN gceFILTER_TYPE FilterType
+ );
+
+/* Set the filter kernel by user. */
+gceSTATUS
+gco2D_SetUserFilterKernel(
+ IN gco2D Engine,
+ IN gceFILTER_PASS_TYPE PassType,
+ IN gctUINT16_PTR KernelArray
+ );
+
+/* Select the pass(es) to be done for user defined filter. */
+gceSTATUS
+gco2D_EnableUserFilterPasses(
+ IN gco2D Engine,
+ IN gctBOOL HorPass,
+ IN gctBOOL VerPass
+ );
+
+/* Frees the temporary buffer allocated by filter blit operation. */
+gceSTATUS
+gco2D_FreeFilterBuffer(
+ IN gco2D Engine
+ );
+
+/* Filter blit. */
+gceSTATUS
+gco2D_FilterBlit(
+ IN gco2D Engine,
+ IN gctUINT32 SrcAddress,
+ IN gctUINT SrcStride,
+ IN gctUINT32 SrcUAddress,
+ IN gctUINT SrcUStride,
+ IN gctUINT32 SrcVAddress,
+ IN gctUINT SrcVStride,
+ IN gceSURF_FORMAT SrcFormat,
+ IN gceSURF_ROTATION SrcRotation,
+ IN gctUINT32 SrcSurfaceWidth,
+ IN gcsRECT_PTR SrcRect,
+ IN gctUINT32 DestAddress,
+ IN gctUINT DestStride,
+ IN gceSURF_FORMAT DestFormat,
+ IN gceSURF_ROTATION DestRotation,
+ IN gctUINT32 DestSurfaceWidth,
+ IN gcsRECT_PTR DestRect,
+ IN gcsRECT_PTR DestSubRect
+ );
+
+/* Filter blit extension for full rotation. */
+gceSTATUS
+gco2D_FilterBlitEx(
+ IN gco2D Engine,
+ IN gctUINT32 SrcAddress,
+ IN gctUINT SrcStride,
+ IN gctUINT32 SrcUAddress,
+ IN gctUINT SrcUStride,
+ IN gctUINT32 SrcVAddress,
+ IN gctUINT SrcVStride,
+ IN gceSURF_FORMAT SrcFormat,
+ IN gceSURF_ROTATION SrcRotation,
+ IN gctUINT32 SrcSurfaceWidth,
+ IN gctUINT32 SrcSurfaceHeight,
+ IN gcsRECT_PTR SrcRect,
+ IN gctUINT32 DestAddress,
+ IN gctUINT DestStride,
+ IN gceSURF_FORMAT DestFormat,
+ IN gceSURF_ROTATION DestRotation,
+ IN gctUINT32 DestSurfaceWidth,
+ IN gctUINT32 DestSurfaceHeight,
+ IN gcsRECT_PTR DestRect,
+ IN gcsRECT_PTR DestSubRect
+ );
+
+gceSTATUS
+gco2D_FilterBlitEx2(
+ IN gco2D Engine,
+ IN gctUINT32_PTR SrcAddresses,
+ IN gctUINT32 SrcAddressNum,
+ IN gctUINT32_PTR SrcStrides,
+ IN gctUINT32 SrcStrideNum,
+ IN gceTILING SrcTiling,
+ IN gceSURF_FORMAT SrcFormat,
+ IN gceSURF_ROTATION SrcRotation,
+ IN gctUINT32 SrcSurfaceWidth,
+ IN gctUINT32 SrcSurfaceHeight,
+ IN gcsRECT_PTR SrcRect,
+ IN gctUINT32_PTR DestAddresses,
+ IN gctUINT32 DestAddressNum,
+ IN gctUINT32_PTR DestStrides,
+ IN gctUINT32 DestStrideNum,
+ IN gceTILING DestTiling,
+ IN gceSURF_FORMAT DestFormat,
+ IN gceSURF_ROTATION DestRotation,
+ IN gctUINT32 DestSurfaceWidth,
+ IN gctUINT32 DestSurfaceHeight,
+ IN gcsRECT_PTR DestRect,
+ IN gcsRECT_PTR DestSubRect
+ );
+
+/* Enable alpha blending engine in the hardware and disengage the ROP engine. */
+gceSTATUS
+gco2D_EnableAlphaBlend(
+ IN gco2D Engine,
+ IN gctUINT8 SrcGlobalAlphaValue,
+ IN gctUINT8 DstGlobalAlphaValue,
+ IN gceSURF_PIXEL_ALPHA_MODE SrcAlphaMode,
+ IN gceSURF_PIXEL_ALPHA_MODE DstAlphaMode,
+ IN gceSURF_GLOBAL_ALPHA_MODE SrcGlobalAlphaMode,
+ IN gceSURF_GLOBAL_ALPHA_MODE DstGlobalAlphaMode,
+ IN gceSURF_BLEND_FACTOR_MODE SrcFactorMode,
+ IN gceSURF_BLEND_FACTOR_MODE DstFactorMode,
+ IN gceSURF_PIXEL_COLOR_MODE SrcColorMode,
+ IN gceSURF_PIXEL_COLOR_MODE DstColorMode
+ );
+
+/* Enable alpha blending engine in the hardware. */
+gceSTATUS
+gco2D_EnableAlphaBlendAdvanced(
+ IN gco2D Engine,
+ IN gceSURF_PIXEL_ALPHA_MODE SrcAlphaMode,
+ IN gceSURF_PIXEL_ALPHA_MODE DstAlphaMode,
+ IN gceSURF_GLOBAL_ALPHA_MODE SrcGlobalAlphaMode,
+ IN gceSURF_GLOBAL_ALPHA_MODE DstGlobalAlphaMode,
+ IN gceSURF_BLEND_FACTOR_MODE SrcFactorMode,
+ IN gceSURF_BLEND_FACTOR_MODE DstFactorMode
+ );
+
+/* Enable alpha blending engine with Porter Duff rule. */
+gceSTATUS
+gco2D_SetPorterDuffBlending(
+ IN gco2D Engine,
+ IN gce2D_PORTER_DUFF_RULE Rule
+ );
+
+/* Disable alpha blending engine in the hardware and engage the ROP engine. */
+gceSTATUS
+gco2D_DisableAlphaBlend(
+ IN gco2D Engine
+ );
+
+/* Retrieve the maximum number of 32-bit data chunks for a single DE command. */
+gctUINT32
+gco2D_GetMaximumDataCount(
+ void
+ );
+
+/* Retrieve the maximum number of rectangles, that can be passed in a single DE command. */
+gctUINT32
+gco2D_GetMaximumRectCount(
+ void
+ );
+
+/* Returns the pixel alignment of the surface. */
+gceSTATUS
+gco2D_GetPixelAlignment(
+ gceSURF_FORMAT Format,
+ gcsPOINT_PTR Alignment
+ );
+
+/* Retrieve monochrome stream pack size. */
+gceSTATUS
+gco2D_GetPackSize(
+ IN gceSURF_MONOPACK StreamPack,
+ OUT gctUINT32 * PackWidth,
+ OUT gctUINT32 * PackHeight
+ );
+
+/* Flush the 2D pipeline. */
+gceSTATUS
+gco2D_Flush(
+ IN gco2D Engine
+ );
+
+/* Load 256-entry color table for INDEX8 source surfaces. */
+gceSTATUS
+gco2D_LoadPalette(
+ IN gco2D Engine,
+ IN gctUINT FirstIndex,
+ IN gctUINT IndexCount,
+ IN gctPOINTER ColorTable,
+ IN gctBOOL ColorConvert
+ );
+
+/* Enable/disable 2D BitBlt mirrorring. */
+gceSTATUS
+gco2D_SetBitBlitMirror(
+ IN gco2D Engine,
+ IN gctBOOL HorizontalMirror,
+ IN gctBOOL VerticalMirror
+ );
+
+/*
+ * Set the transparency for source, destination and pattern.
+ * It also enable or disable the DFB color key mode.
+ */
+gceSTATUS
+gco2D_SetTransparencyAdvancedEx(
+ IN gco2D Engine,
+ IN gce2D_TRANSPARENCY SrcTransparency,
+ IN gce2D_TRANSPARENCY DstTransparency,
+ IN gce2D_TRANSPARENCY PatTransparency,
+ IN gctBOOL EnableDFBColorKeyMode
+ );
+
+/* Set the transparency for source, destination and pattern. */
+gceSTATUS
+gco2D_SetTransparencyAdvanced(
+ IN gco2D Engine,
+ IN gce2D_TRANSPARENCY SrcTransparency,
+ IN gce2D_TRANSPARENCY DstTransparency,
+ IN gce2D_TRANSPARENCY PatTransparency
+ );
+
+/* Set the source color key. */
+gceSTATUS
+gco2D_SetSourceColorKeyAdvanced(
+ IN gco2D Engine,
+ IN gctUINT32 ColorKey
+ );
+
+/* Set the source color key range. */
+gceSTATUS
+gco2D_SetSourceColorKeyRangeAdvanced(
+ IN gco2D Engine,
+ IN gctUINT32 ColorKeyLow,
+ IN gctUINT32 ColorKeyHigh
+ );
+
+/* Set the target color key. */
+gceSTATUS
+gco2D_SetTargetColorKeyAdvanced(
+ IN gco2D Engine,
+ IN gctUINT32 ColorKey
+ );
+
+/* Set the target color key range. */
+gceSTATUS
+gco2D_SetTargetColorKeyRangeAdvanced(
+ IN gco2D Engine,
+ IN gctUINT32 ColorKeyLow,
+ IN gctUINT32 ColorKeyHigh
+ );
+
+/* Set the YUV color space mode. */
+gceSTATUS
+gco2D_SetYUVColorMode(
+ IN gco2D Engine,
+ IN gce2D_YUV_COLOR_MODE Mode
+ );
+
+/* Setup the source global color value in ARGB8 format. */
+gceSTATUS gco2D_SetSourceGlobalColorAdvanced(
+ IN gco2D Engine,
+ IN gctUINT32 Color32
+ );
+
+/* Setup the target global color value in ARGB8 format. */
+gceSTATUS gco2D_SetTargetGlobalColorAdvanced(
+ IN gco2D Engine,
+ IN gctUINT32 Color32
+ );
+
+/* Setup the source and target pixel multiply modes. */
+gceSTATUS
+gco2D_SetPixelMultiplyModeAdvanced(
+ IN gco2D Engine,
+ IN gce2D_PIXEL_COLOR_MULTIPLY_MODE SrcPremultiplySrcAlpha,
+ IN gce2D_PIXEL_COLOR_MULTIPLY_MODE DstPremultiplyDstAlpha,
+ IN gce2D_GLOBAL_COLOR_MULTIPLY_MODE SrcPremultiplyGlobalMode,
+ IN gce2D_PIXEL_COLOR_MULTIPLY_MODE DstDemultiplyDstAlpha
+ );
+
+/* Set the GPU clock cycles after which the idle engine will keep auto-flushing. */
+gceSTATUS
+gco2D_SetAutoFlushCycles(
+ IN gco2D Engine,
+ IN gctUINT32 Cycles
+ );
+
+#if VIVANTE_PROFILER
+/* Read the profile registers available in the 2D engine and sets them in the profile.
+ The function will also reset the pixelsRendered counter every time.
+*/
+gceSTATUS
+gco2D_ProfileEngine(
+ IN gco2D Engine,
+ OPTIONAL gcs2D_PROFILE_PTR Profile
+ );
+#endif
+
+/* Enable or disable 2D dithering. */
+gceSTATUS
+gco2D_EnableDither(
+ IN gco2D Engine,
+ IN gctBOOL Enable
+ );
+
+gceSTATUS
+gco2D_SetGenericSource(
+ IN gco2D Engine,
+ IN gctUINT32_PTR Addresses,
+ IN gctUINT32 AddressNum,
+ IN gctUINT32_PTR Strides,
+ IN gctUINT32 StrideNum,
+ IN gceTILING Tiling,
+ IN gceSURF_FORMAT Format,
+ IN gceSURF_ROTATION Rotation,
+ IN gctUINT32 SurfaceWidth,
+ IN gctUINT32 SurfaceHeight
+);
+
+gceSTATUS
+gco2D_SetGenericTarget(
+ IN gco2D Engine,
+ IN gctUINT32_PTR Addresses,
+ IN gctUINT32 AddressNum,
+ IN gctUINT32_PTR Strides,
+ IN gctUINT32 StrideNum,
+ IN gceTILING Tiling,
+ IN gceSURF_FORMAT Format,
+ IN gceSURF_ROTATION Rotation,
+ IN gctUINT32 SurfaceWidth,
+ IN gctUINT32 SurfaceHeight
+);
+
+gceSTATUS
+gco2D_SetCurrentSourceIndex(
+ IN gco2D Engine,
+ IN gctUINT32 SrcIndex
+ );
+
+gceSTATUS
+gco2D_MultiSourceBlit(
+ IN gco2D Engine,
+ IN gctUINT32 SourceMask,
+ IN gcsRECT_PTR DestRect,
+ IN gctUINT32 RectCount
+ );
+
+gceSTATUS
+gco2D_SetROP(
+ IN gco2D Engine,
+ IN gctUINT8 FgRop,
+ IN gctUINT8 BgRop
+ );
+
+gceSTATUS
+gco2D_SetGdiStretchMode(
+ IN gco2D Engine,
+ IN gctBOOL Enable
+ );
+
+gceSTATUS
+gco2D_SetSourceTileStatus(
+ IN gco2D Engine,
+ IN gce2D_TILE_STATUS_CONFIG TSControl,
+ IN gceSURF_FORMAT CompressedFormat,
+ IN gctUINT32 ClearValue,
+ IN gctUINT32 GpuAddress
+ );
+
+gceSTATUS
+gco2D_SetTargetTileStatus(
+ IN gco2D Engine,
+ IN gce2D_TILE_STATUS_CONFIG TileStatusConfig,
+ IN gceSURF_FORMAT CompressedFormat,
+ IN gctUINT32 ClearValue,
+ IN gctUINT32 GpuAddress
+ );
+
+gceSTATUS
+gco2D_QueryU32(
+ IN gco2D Engine,
+ IN gce2D_QUERY Item,
+ OUT gctUINT32_PTR Value
+ );
+
+gceSTATUS
+gco2D_SetStateU32(
+ IN gco2D Engine,
+ IN gce2D_STATE State,
+ IN gctUINT32 Value
+ );
+
+gceSTATUS
+gco2D_SetStateArrayI32(
+ IN gco2D Engine,
+ IN gce2D_STATE State,
+ IN gctINT32_PTR Array,
+ IN gctINT32 ArraySize
+ );
+
+gceSTATUS
+gco2D_SetStateArrayU32(
+ IN gco2D Engine,
+ IN gce2D_STATE State,
+ IN gctUINT32_PTR Array,
+ IN gctINT32 ArraySize
+ );
+
+gceSTATUS
+gco2D_SetTargetRect(
+ IN gco2D Engine,
+ IN gcsRECT_PTR Rect
+ );
+
+gceSTATUS
+gco2D_Set2DEngine(
+ IN gco2D Engine
+ );
+
+gceSTATUS
+gco2D_UnSet2DEngine(
+ IN gco2D Engine
+ );
+
+gceSTATUS
+gco2D_Get2DEngine(
+ OUT gco2D * Engine
+ );
+
+gceSTATUS
+gco2D_Commit(
+ IN gco2D Engine,
+ IN gctBOOL Stall
+ );
+
+gceSTATUS
+gco2D_NatureRotateTranslation(
+ IN gctBOOL IsSrcRot,
+ IN gce2D_NATURE_ROTATION NatureRotation,
+ IN gctINT32 SrcSurfaceWidth,
+ IN gctINT32 SrcSurfaceHeight,
+ IN gctINT32 DstSurfaceWidth,
+ IN gctINT32 DstSurfaceHeight,
+ IN OUT gcsRECT_PTR SrcRect,
+ IN OUT gcsRECT_PTR DstRect,
+ OUT gceSURF_ROTATION * SrcRotation,
+ OUT gceSURF_ROTATION * DstRotation
+ );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __gc_hal_raster_h_ */
+
+
diff --git a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_rename.h b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_rename.h
new file mode 100644
index 000000000000..df842afcbe61
--- /dev/null
+++ b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_rename.h
@@ -0,0 +1,279 @@
+/****************************************************************************
+*
+* The MIT License (MIT)
+*
+* Copyright (c) 2014 - 2018 Vivante 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 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 GPL License (GPL)
+*
+* Copyright (C) 2014 - 2018 Vivante 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.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+*****************************************************************************
+*
+* Note: This software is released under dual MIT and GPL licenses. A
+* recipient may use this file under the terms of either the MIT license or
+* GPL License. If you wish to use only one license not the other, you can
+* indicate your decision by deleting one of the above license notices in your
+* version of this file.
+*
+*****************************************************************************/
+
+
+#ifndef __gc_hal_rename_h_
+#define __gc_hal_rename_h_
+
+
+#if defined(_HAL2D_APPENDIX)
+
+#define _HAL2D_RENAME_2(api, appendix) api ## appendix
+#define _HAL2D_RENAME_1(api, appendix) _HAL2D_RENAME_2(api, appendix)
+#define gcmHAL2D(api) _HAL2D_RENAME_1(api, _HAL2D_APPENDIX)
+
+
+#define gckOS_Construct gcmHAL2D(gckOS_Construct)
+#define gckOS_Destroy gcmHAL2D(gckOS_Destroy)
+#define gckOS_QueryVideoMemory gcmHAL2D(gckOS_QueryVideoMemory)
+#define gckOS_Allocate gcmHAL2D(gckOS_Allocate)
+#define gckOS_Free gcmHAL2D(gckOS_Free)
+#define gckOS_AllocateMemory gcmHAL2D(gckOS_AllocateMemory)
+#define gckOS_FreeMemory gcmHAL2D(gckOS_FreeMemory)
+#define gckOS_AllocatePagedMemory gcmHAL2D(gckOS_AllocatePagedMemory)
+#define gckOS_AllocatePagedMemoryEx gcmHAL2D(gckOS_AllocatePagedMemoryEx)
+#define gckOS_LockPages gcmHAL2D(gckOS_LockPages)
+#define gckOS_MapPages gcmHAL2D(gckOS_MapPages)
+#define gckOS_UnlockPages gcmHAL2D(gckOS_UnlockPages)
+#define gckOS_FreePagedMemory gcmHAL2D(gckOS_FreePagedMemory)
+#define gckOS_AllocateNonPagedMemory gcmHAL2D(gckOS_AllocateNonPagedMemory)
+#define gckOS_FreeNonPagedMemory gcmHAL2D(gckOS_FreeNonPagedMemory)
+#define gckOS_AllocateContiguous gcmHAL2D(gckOS_AllocateContiguous)
+#define gckOS_FreeContiguous gcmHAL2D(gckOS_FreeContiguous)
+#define gckOS_GetPageSize gcmHAL2D(gckOS_GetPageSize)
+#define gckOS_GetPhysicalAddress gcmHAL2D(gckOS_GetPhysicalAddress)
+#define gckOS_UserLogicalToPhysical gcmHAL2D(gckOS_UserLogicalToPhysical)
+#define gckOS_GetPhysicalAddressProcess gcmHAL2D(gckOS_GetPhysicalAddressProcess)
+#define gckOS_MapPhysical gcmHAL2D(gckOS_MapPhysical)
+#define gckOS_UnmapPhysical gcmHAL2D(gckOS_UnmapPhysical)
+#define gckOS_ReadRegister gcmHAL2D(gckOS_ReadRegister)
+#define gckOS_WriteRegister gcmHAL2D(gckOS_WriteRegister)
+#define gckOS_WriteMemory gcmHAL2D(gckOS_WriteMemory)
+#define gckOS_MapMemory gcmHAL2D(gckOS_MapMemory)
+#define gckOS_UnmapMemory gcmHAL2D(gckOS_UnmapMemory)
+#define gckOS_UnmapMemoryEx gcmHAL2D(gckOS_UnmapMemoryEx)
+#define gckOS_CreateMutex gcmHAL2D(gckOS_CreateMutex)
+#define gckOS_DeleteMutex gcmHAL2D(gckOS_DeleteMutex)
+#define gckOS_AcquireMutex gcmHAL2D(gckOS_AcquireMutex)
+#define gckOS_ReleaseMutex gcmHAL2D(gckOS_ReleaseMutex)
+#define gckOS_AtomicExchange gcmHAL2D(gckOS_AtomicExchange)
+#define gckOS_AtomicExchangePtr gcmHAL2D(gckOS_AtomicExchangePtr)
+#define gckOS_AtomConstruct gcmHAL2D(gckOS_AtomConstruct)
+#define gckOS_AtomDestroy gcmHAL2D(gckOS_AtomDestroy)
+#define gckOS_AtomGet gcmHAL2D(gckOS_AtomGet)
+#define gckOS_AtomIncrement gcmHAL2D(gckOS_AtomIncrement)
+#define gckOS_AtomDecrement gcmHAL2D(gckOS_AtomDecrement)
+#define gckOS_Delay gcmHAL2D(gckOS_Delay)
+#define gckOS_GetTime gcmHAL2D(gckOS_GetTime)
+#define gckOS_MemoryBarrier gcmHAL2D(gckOS_MemoryBarrier)
+#define gckOS_MapUserPointer gcmHAL2D(gckOS_MapUserPointer)
+#define gckOS_UnmapUserPointer gcmHAL2D(gckOS_UnmapUserPointer)
+#define gckOS_QueryNeedCopy gcmHAL2D(gckOS_QueryNeedCopy)
+#define gckOS_CopyFromUserData gcmHAL2D(gckOS_CopyFromUserData)
+#define gckOS_CopyToUserData gcmHAL2D(gckOS_CopyToUserData)
+#define gckOS_SuspendInterrupt gcmHAL2D(gckOS_SuspendInterrupt)
+#define gckOS_ResumeInterrupt gcmHAL2D(gckOS_ResumeInterrupt)
+#define gckOS_GetBaseAddress gcmHAL2D(gckOS_GetBaseAddress)
+#define gckOS_MemCopy gcmHAL2D(gckOS_MemCopy)
+#define gckOS_ZeroMemory gcmHAL2D(gckOS_ZeroMemory)
+#define gckOS_DeviceControl gcmHAL2D(gckOS_DeviceControl)
+#define gckOS_GetProcessID gcmHAL2D(gckOS_GetProcessID)
+#define gckOS_GetThreadID gcmHAL2D(gckOS_GetThreadID)
+#define gckOS_CreateSignal gcmHAL2D(gckOS_CreateSignal)
+#define gckOS_DestroySignal gcmHAL2D(gckOS_DestroySignal)
+#define gckOS_Signal gcmHAL2D(gckOS_Signal)
+#define gckOS_WaitSignal gcmHAL2D(gckOS_WaitSignal)
+#define gckOS_MapSignal gcmHAL2D(gckOS_MapSignal)
+#define gckOS_MapUserMemory gcmHAL2D(gckOS_MapUserMemory)
+#define gckOS_UnmapUserMemory gcmHAL2D(gckOS_UnmapUserMemory)
+#define gckOS_CreateUserSignal gcmHAL2D(gckOS_CreateUserSignal)
+#define gckOS_DestroyUserSignal gcmHAL2D(gckOS_DestroyUserSignal)
+#define gckOS_WaitUserSignal gcmHAL2D(gckOS_WaitUserSignal)
+#define gckOS_SignalUserSignal gcmHAL2D(gckOS_SignalUserSignal)
+#define gckOS_UserSignal gcmHAL2D(gckOS_UserSignal)
+#define gckOS_UserSignal gcmHAL2D(gckOS_UserSignal)
+#define gckOS_CacheClean gcmHAL2D(gckOS_CacheClean)
+#define gckOS_CacheFlush gcmHAL2D(gckOS_CacheFlush)
+#define gckOS_SetDebugLevel gcmHAL2D(gckOS_SetDebugLevel)
+#define gckOS_SetDebugZone gcmHAL2D(gckOS_SetDebugZone)
+#define gckOS_SetDebugLevelZone gcmHAL2D(gckOS_SetDebugLevelZone)
+#define gckOS_SetDebugZones gcmHAL2D(gckOS_SetDebugZones)
+#define gckOS_SetDebugFile gcmHAL2D(gckOS_SetDebugFile)
+#define gckOS_Broadcast gcmHAL2D(gckOS_Broadcast)
+#define gckOS_SetGPUPower gcmHAL2D(gckOS_SetGPUPower)
+#define gckOS_CreateSemaphore gcmHAL2D(gckOS_CreateSemaphore)
+#define gckOS_DestroySemaphore gcmHAL2D(gckOS_DestroySemaphore)
+#define gckOS_AcquireSemaphore gcmHAL2D(gckOS_AcquireSemaphore)
+#define gckOS_ReleaseSemaphore gcmHAL2D(gckOS_ReleaseSemaphore)
+#define gckHEAP_Construct gcmHAL2D(gckHEAP_Construct)
+#define gckHEAP_Destroy gcmHAL2D(gckHEAP_Destroy)
+#define gckHEAP_Allocate gcmHAL2D(gckHEAP_Allocate)
+#define gckHEAP_Free gcmHAL2D(gckHEAP_Free)
+#define gckHEAP_ProfileStart gcmHAL2D(gckHEAP_ProfileStart)
+#define gckHEAP_ProfileEnd gcmHAL2D(gckHEAP_ProfileEnd)
+#define gckHEAP_Test gcmHAL2D(gckHEAP_Test)
+#define gckVIDMEM_Construct gcmHAL2D(gckVIDMEM_Construct)
+#define gckVIDMEM_Destroy gcmHAL2D(gckVIDMEM_Destroy)
+#define gckVIDMEM_Allocate gcmHAL2D(gckVIDMEM_Allocate)
+#define gckVIDMEM_AllocateLinear gcmHAL2D(gckVIDMEM_AllocateLinear)
+#define gckVIDMEM_Free gcmHAL2D(gckVIDMEM_Free)
+#define gckVIDMEM_Lock gcmHAL2D(gckVIDMEM_Lock)
+#define gckVIDMEM_Unlock gcmHAL2D(gckVIDMEM_Unlock)
+#define gckVIDMEM_ConstructVirtual gcmHAL2D(gckVIDMEM_ConstructVirtual)
+#define gckVIDMEM_DestroyVirtual gcmHAL2D(gckVIDMEM_DestroyVirtual)
+#define gckKERNEL_Construct gcmHAL2D(gckKERNEL_Construct)
+#define gckKERNEL_Destroy gcmHAL2D(gckKERNEL_Destroy)
+#define gckKERNEL_Dispatch gcmHAL2D(gckKERNEL_Dispatch)
+#define gckKERNEL_QueryVideoMemory gcmHAL2D(gckKERNEL_QueryVideoMemory)
+#define gckKERNEL_GetVideoMemoryPool gcmHAL2D(gckKERNEL_GetVideoMemoryPool)
+#define gckKERNEL_MapVideoMemory gcmHAL2D(gckKERNEL_MapVideoMemory)
+#define gckKERNEL_UnmapVideoMemory gcmHAL2D(gckKERNEL_UnmapVideoMemory)
+#define gckKERNEL_MapMemory gcmHAL2D(gckKERNEL_MapMemory)
+#define gckKERNEL_UnmapMemory gcmHAL2D(gckKERNEL_UnmapMemory)
+#define gckKERNEL_Notify gcmHAL2D(gckKERNEL_Notify)
+#define gckKERNEL_QuerySettings gcmHAL2D(gckKERNEL_QuerySettings)
+#define gckKERNEL_Recovery gcmHAL2D(gckKERNEL_Recovery)
+#define gckKERNEL_OpenUserData gcmHAL2D(gckKERNEL_OpenUserData)
+#define gckKERNEL_CloseUserData gcmHAL2D(gckKERNEL_CloseUserData)
+#define gckHARDWARE_Construct gcmHAL2D(gckHARDWARE_Construct)
+#define gckHARDWARE_Destroy gcmHAL2D(gckHARDWARE_Destroy)
+#define gckHARDWARE_QuerySystemMemory gcmHAL2D(gckHARDWARE_QuerySystemMemory)
+#define gckHARDWARE_BuildVirtualAddress gcmHAL2D(gckHARDWARE_BuildVirtualAddress)
+#define gckHARDWARE_QueryCommandBuffer gcmHAL2D(gckHARDWARE_QueryCommandBuffer)
+#define gckHARDWARE_WaitLink gcmHAL2D(gckHARDWARE_WaitLink)
+#define gckHARDWARE_Execute gcmHAL2D(gckHARDWARE_Execute)
+#define gckHARDWARE_End gcmHAL2D(gckHARDWARE_End)
+#define gckHARDWARE_Nop gcmHAL2D(gckHARDWARE_Nop)
+#define gckHARDWARE_PipeSelect gcmHAL2D(gckHARDWARE_PipeSelect)
+#define gckHARDWARE_Link gcmHAL2D(gckHARDWARE_Link)
+#define gckHARDWARE_Event gcmHAL2D(gckHARDWARE_Event)
+#define gckHARDWARE_QueryMemory gcmHAL2D(gckHARDWARE_QueryMemory)
+#define gckHARDWARE_QueryChipIdentity gcmHAL2D(gckHARDWARE_QueryChipIdentity)
+#define gckHARDWARE_QueryChipSpecs gcmHAL2D(gckHARDWARE_QueryChipSpecs)
+#define gckHARDWARE_QueryShaderCaps gcmHAL2D(gckHARDWARE_QueryShaderCaps)
+#define gckHARDWARE_ConvertFormat gcmHAL2D(gckHARDWARE_ConvertFormat)
+#define gckHARDWARE_SplitMemory gcmHAL2D(gckHARDWARE_SplitMemory)
+#define gckHARDWARE_AlignToTile gcmHAL2D(gckHARDWARE_AlignToTile)
+#define gckHARDWARE_UpdateQueueTail gcmHAL2D(gckHARDWARE_UpdateQueueTail)
+#define gckHARDWARE_ConvertLogical gcmHAL2D(gckHARDWARE_ConvertLogical)
+#define gckHARDWARE_Interrupt gcmHAL2D(gckHARDWARE_Interrupt)
+#define gckHARDWARE_SetMMU gcmHAL2D(gckHARDWARE_SetMMU)
+#define gckHARDWARE_FlushMMU gcmHAL2D(gckHARDWARE_FlushMMU)
+#define gckHARDWARE_GetIdle gcmHAL2D(gckHARDWARE_GetIdle)
+#define gckHARDWARE_Flush gcmHAL2D(gckHARDWARE_Flush)
+#define gckHARDWARE_SetFastClear gcmHAL2D(gckHARDWARE_SetFastClear)
+#define gckHARDWARE_ReadInterrupt gcmHAL2D(gckHARDWARE_ReadInterrupt)
+#define gckHARDWARE_SetPowerManagementState gcmHAL2D(gckHARDWARE_SetPowerManagementState)
+#define gckHARDWARE_QueryPowerManagementState gcmHAL2D(gckHARDWARE_QueryPowerManagementState)
+#define gckHARDWARE_ProfileEngine2D gcmHAL2D(gckHARDWARE_ProfileEngine2D)
+#define gckHARDWARE_InitializeHardware gcmHAL2D(gckHARDWARE_InitializeHardware)
+#define gckHARDWARE_Reset gcmHAL2D(gckHARDWARE_Reset)
+#define gckINTERRUPT_Construct gcmHAL2D(gckINTERRUPT_Construct)
+#define gckINTERRUPT_Destroy gcmHAL2D(gckINTERRUPT_Destroy)
+#define gckINTERRUPT_SetHandler gcmHAL2D(gckINTERRUPT_SetHandler)
+#define gckINTERRUPT_Notify gcmHAL2D(gckINTERRUPT_Notify)
+#define gckEVENT_Construct gcmHAL2D(gckEVENT_Construct)
+#define gckEVENT_Destroy gcmHAL2D(gckEVENT_Destroy)
+#define gckEVENT_AddList gcmHAL2D(gckEVENT_AddList)
+#define gckEVENT_FreeNonPagedMemory gcmHAL2D(gckEVENT_FreeNonPagedMemory)
+#define gckEVENT_FreeContiguousMemory gcmHAL2D(gckEVENT_FreeContiguousMemory)
+#define gckEVENT_FreeVideoMemory gcmHAL2D(gckEVENT_FreeVideoMemory)
+#define gckEVENT_Signal gcmHAL2D(gckEVENT_Signal)
+#define gckEVENT_Unlock gcmHAL2D(gckEVENT_Unlock)
+#define gckEVENT_Submit gcmHAL2D(gckEVENT_Submit)
+#define gckEVENT_Commit gcmHAL2D(gckEVENT_Commit)
+#define gckEVENT_Notify gcmHAL2D(gckEVENT_Notify)
+#define gckEVENT_Interrupt gcmHAL2D(gckEVENT_Interrupt)
+#define gckCOMMAND_Construct gcmHAL2D(gckCOMMAND_Construct)
+#define gckCOMMAND_Destroy gcmHAL2D(gckCOMMAND_Destroy)
+#define gckCOMMAND_EnterCommit gcmHAL2D(gckCOMMAND_EnterCommit)
+#define gckCOMMAND_ExitCommit gcmHAL2D(gckCOMMAND_ExitCommit)
+#define gckCOMMAND_Start gcmHAL2D(gckCOMMAND_Start)
+#define gckCOMMAND_Stop gcmHAL2D(gckCOMMAND_Stop)
+#define gckCOMMAND_Commit gcmHAL2D(gckCOMMAND_Commit)
+#define gckCOMMAND_Reserve gcmHAL2D(gckCOMMAND_Reserve)
+#define gckCOMMAND_Execute gcmHAL2D(gckCOMMAND_Execute)
+#define gckCOMMAND_Stall gcmHAL2D(gckCOMMAND_Stall)
+#define gckCOMMAND_Attach gcmHAL2D(gckCOMMAND_Attach)
+#define gckCOMMAND_Detach gcmHAL2D(gckCOMMAND_Detach)
+#define gckMMU_Construct gcmHAL2D(gckMMU_Construct)
+#define gckMMU_Destroy gcmHAL2D(gckMMU_Destroy)
+#define gckMMU_AllocatePages gcmHAL2D(gckMMU_AllocatePages)
+#define gckMMU_FreePages gcmHAL2D(gckMMU_FreePages)
+#define gckMMU_Test gcmHAL2D(gckMMU_Test)
+#define gckHARDWARE_QueryProfileRegisters gcmHAL2D(gckHARDWARE_QueryProfileRegisters)
+
+
+#define FindMdlMap gcmHAL2D(FindMdlMap)
+#define OnProcessExit gcmHAL2D(OnProcessExit)
+
+#define gckGALDEVICE_Destroy gcmHAL2D(gckGALDEVICE_Destroy)
+#define gckOS_Print gcmHAL2D(gckOS_Print)
+#define gckGALDEVICE_FreeMemory gcmHAL2D(gckGALDEVICE_FreeMemory)
+#define gckGALDEVICE_AllocateMemory gcmHAL2D(gckGALDEVICE_AllocateMemory)
+#define gckOS_DebugBreak gcmHAL2D(gckOS_DebugBreak)
+#define gckGALDEVICE_Release_ISR gcmHAL2D(gckGALDEVICE_Release_ISR)
+#define gckOS_Verify gcmHAL2D(gckOS_Verify)
+#define gckCOMMAND_Release gcmHAL2D(gckCOMMAND_Release)
+#define gckGALDEVICE_Stop gcmHAL2D(gckGALDEVICE_Stop)
+#define gckGALDEVICE_Construct gcmHAL2D(gckGALDEVICE_Construct)
+#define gckOS_DebugFatal gcmHAL2D(gckOS_DebugFatal)
+#define gckOS_DebugTrace gcmHAL2D(gckOS_DebugTrace)
+#define gckHARDWARE_GetBaseAddress gcmHAL2D(gckHARDWARE_GetBaseAddress)
+#define gckGALDEVICE_Setup_ISR gcmHAL2D(gckGALDEVICE_Setup_ISR)
+#define gckKERNEL_AttachProcess gcmHAL2D(gckKERNEL_AttachProcess)
+#define gckKERNEL_AttachProcessEx gcmHAL2D(gckKERNEL_AttachProcessEx)
+#define gckGALDEVICE_Start_Thread gcmHAL2D(gckGALDEVICE_Start_Thread)
+#define gckHARDWARE_QueryIdle gcmHAL2D(gckHARDWARE_QueryIdle)
+#define gckGALDEVICE_Start gcmHAL2D(gckGALDEVICE_Start)
+#define gckOS_GetKernelLogical gcmHAL2D(gckOS_GetKernelLogical)
+#define gckOS_DebugTraceZone gcmHAL2D(gckOS_DebugTraceZone)
+#define gckGALDEVICE_Stop_Thread gcmHAL2D(gckGALDEVICE_Stop_Thread)
+#define gckHARDWARE_NeedBaseAddress gcmHAL2D(gckHARDWARE_NeedBaseAddress)
+
+#endif
+
+#endif /* __gc_hal_rename_h_ */
+
+
diff --git a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_resource.h b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_resource.h
new file mode 100644
index 000000000000..01642229d869
--- /dev/null
+++ b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_resource.h
@@ -0,0 +1,69 @@
+/****************************************************************************
+*
+* The MIT License (MIT)
+*
+* Copyright (c) 2014 - 2018 Vivante 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 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 GPL License (GPL)
+*
+* Copyright (C) 2014 - 2018 Vivante 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.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+*****************************************************************************
+*
+* Note: This software is released under dual MIT and GPL licenses. A
+* recipient may use this file under the terms of either the MIT license or
+* GPL License. If you wish to use only one license not the other, you can
+* indicate your decision by deleting one of the above license notices in your
+* version of this file.
+*
+*****************************************************************************/
+
+
+#ifndef __gc_hal_resource_h_
+#define __gc_hal_resource_h_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __gc_hal_resource_h_ */
+
+
diff --git a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_security_interface.h b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_security_interface.h
new file mode 100644
index 000000000000..346dac955c9e
--- /dev/null
+++ b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_security_interface.h
@@ -0,0 +1,186 @@
+/****************************************************************************
+*
+* The MIT License (MIT)
+*
+* Copyright (c) 2014 - 2018 Vivante 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 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 GPL License (GPL)
+*
+* Copyright (C) 2014 - 2018 Vivante 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.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+*****************************************************************************
+*
+* Note: This software is released under dual MIT and GPL licenses. A
+* recipient may use this file under the terms of either the MIT license or
+* GPL License. If you wish to use only one license not the other, you can
+* indicate your decision by deleting one of the above license notices in your
+* version of this file.
+*
+*****************************************************************************/
+
+
+#ifndef _GC_HAL_SECURITY_INTERFACE_H_
+#define _GC_HAL_SECURITY_INTERFACE_H_
+/*!
+ @brief Command codes between kernel module and TrustZone
+ @discussion
+ Critical services must be done in TrustZone to avoid sensitive content leak. Most of kernel module is kept in non-Secure os to minimize
+ code in TrustZone.
+ */
+typedef enum kernel_packet_command {
+ KERNEL_START_COMMAND,
+ KERNEL_SUBMIT,
+ KERNEL_MAP_MEMORY, /* */
+ KERNEL_UNMAP_MEMORY,
+ KERNEL_ALLOCATE_SECRUE_MEMORY, /*! Security memory management. */
+ KERNEL_FREE_SECURE_MEMORY,
+ KERNEL_EXECUTE, /* Execute a command buffer. */
+ KERNEL_DUMP_MMU_EXCEPTION,
+ KERNEL_HANDLE_MMU_EXCEPTION,
+ KERNEL_READ_MMU_EXCEPTION,
+} kernel_packet_command_t;
+
+struct kernel_start_command {
+ kernel_packet_command_t command; /*! The command (always needs to be the first entry in a structure). */
+ gctUINT8 gpu; /*! Which GPU. */
+ gctUINT32 address;
+ gctUINT32 bytes;
+};
+
+/*!
+ @brief gckCOMMAND Object requests TrustZone to submit command buffer.
+ @discussion
+ Code in trustzone will check content of command buffer after copying command buffer to TrustZone.
+ */
+struct kernel_submit {
+ kernel_packet_command_t command; /*! The command (always needs to be the first entry in a structure). */
+ gctUINT8 gpu; /*! Which GPU. */
+ gctUINT8 kernel_command; /*! Whether it is a kernel command. */
+ gctUINT32 command_buffer_handle; /*! Handle to command buffer. */
+ gctUINT32 offset; /* Offset in command buffer. */
+ gctUINT32 * command_buffer; /*! Content of command buffer need to be submit. */
+ gctUINT32 command_buffer_length; /*! Length of command buffer. */
+};
+
+
+/*!
+ @brief gckVIDMEM Object requests TrustZone to allocate security memory.
+ @discussion
+ Allocate a buffer from security GPU memory.
+ */
+struct kernel_allocate_security_memory {
+ kernel_packet_command_t command; /*! The command (always needs to be the first entry in a structure). */
+ gctUINT32 bytes; /*! Requested bytes. */
+ gctUINT32 memory_handle; /*! Handle of allocated memory. */
+};
+
+/*!
+ @brief gckVIDMEM Object requests TrustZone to allocate security memory.
+ @discussion
+ Free a video memory buffer from security GPU memory.
+ */
+struct kernel_free_security_memory {
+ kernel_packet_command_t command; /*! The command (always needs to be the first entry in a structure). */
+ gctUINT32 memory_handle; /*! Handle of allocated memory. */
+};
+
+struct kernel_execute {
+ kernel_packet_command_t command; /*! The command (always needs to be the first entry in a structure). */
+ gctUINT8 gpu; /*! Which GPU. */
+ gctUINT8 kernel_command; /*! Whether it is a kernel command. */
+ gctUINT32 * command_buffer; /*! Content of command buffer need to be submit. */
+ gctUINT32 command_buffer_length; /*! Length of command buffer. */
+};
+
+typedef struct kernel_map_scatter_gather {
+ gctUINT32 bytes;
+ gctUINT32 physical;
+ struct kernel_map_scatter_gather *next;
+}
+kernel_map_scatter_gather_t;
+
+struct kernel_map_memory {
+ kernel_packet_command_t command;
+ kernel_map_scatter_gather_t *scatter;
+ gctUINT32 *physicals;
+ gctPHYS_ADDR_T physical; /*! Contiguous physical address range. */
+ gctUINT32 pageCount;
+ gctUINT32 gpuAddress;
+};
+
+struct kernel_unmap_memory {
+ gctUINT32 gpuAddress;
+ gctUINT32 pageCount;
+};
+
+struct kernel_read_mmu_exception {
+ gctUINT32 mmuStatus;
+ gctUINT32 mmuException;
+};
+
+struct kernel_handle_mmu_exception {
+ gctUINT32 mmuStatus;
+ gctPHYS_ADDR_T physical;
+ gctUINT32 gpuAddress;
+};
+
+typedef struct _gcsTA_INTERFACE {
+ kernel_packet_command_t command;
+ union {
+ struct kernel_submit Submit;
+ struct kernel_start_command StartCommand;
+ struct kernel_allocate_security_memory AllocateSecurityMemory;
+ struct kernel_execute Execute;
+ struct kernel_map_memory MapMemory;
+ struct kernel_unmap_memory UnmapMemory;
+ struct kernel_read_mmu_exception ReadMMUException;
+ struct kernel_handle_mmu_exception HandleMMUException;
+ } u;
+ gceSTATUS result;
+} gcsTA_INTERFACE;
+
+enum {
+ gcvTA_COMMAND_INIT,
+ gcvTA_COMMAND_DISPATCH,
+
+ gcvTA_CALLBACK_ALLOC_SECURE_MEM,
+ gcvTA_CALLBACK_FREE_SECURE_MEM,
+};
+
+#endif
+
+
diff --git a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_statistics.h b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_statistics.h
new file mode 100644
index 000000000000..94a1d3e674b3
--- /dev/null
+++ b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_statistics.h
@@ -0,0 +1,135 @@
+/****************************************************************************
+*
+* The MIT License (MIT)
+*
+* Copyright (c) 2014 - 2018 Vivante 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 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 GPL License (GPL)
+*
+* Copyright (C) 2014 - 2018 Vivante 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.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+*****************************************************************************
+*
+* Note: This software is released under dual MIT and GPL licenses. A
+* recipient may use this file under the terms of either the MIT license or
+* GPL License. If you wish to use only one license not the other, you can
+* indicate your decision by deleting one of the above license notices in your
+* version of this file.
+*
+*****************************************************************************/
+
+
+#ifndef __gc_hal_statistics_h_
+#define __gc_hal_statistics_h_
+
+
+#define VIV_STAT_ENABLE_STATISTICS 0
+
+/* Toal number of frames for which the frame time is accounted. We have storage
+ to keep frame times for last this many frames.
+*/
+#define VIV_STAT_FRAME_BUFFER_SIZE 30
+
+
+/*
+ Total number of frames sampled for a mode. This means
+
+ # of frames for HZ Current : VIV_STAT_EARLY_Z_SAMPLE_FRAMES
+ # of frames for HZ Switched : VIV_STAT_EARLY_Z_SAMPLE_FRAMES
+ +
+ --------------------------------------------------------
+ : (2 * VIV_STAT_EARLY_Z_SAMPLE_FRAMES) frames needed
+
+ IMPORTANT: This total must be smaller than VIV_STAT_FRAME_BUFFER_SIZE
+*/
+#define VIV_STAT_EARLY_Z_SAMPLE_FRAMES 7
+#define VIV_STAT_EARLY_Z_LATENCY_FRAMES 2
+
+/* Multiplication factor for previous Hz off mode. Make it more than 1.0 to advertise HZ on.*/
+#define VIV_STAT_EARLY_Z_FACTOR (1.05f)
+
+/* Defines the statistical data keys monitored by the statistics module */
+typedef enum _gceSTATISTICS
+{
+ gcvFRAME_FPS = 1,
+}
+gceSTATISTICS;
+
+/* HAL statistics information. */
+typedef struct _gcsSTATISTICS_EARLYZ
+{
+ gctUINT switchBackCount;
+ gctUINT nextCheckPoint;
+ gctBOOL disabled;
+}
+gcsSTATISTICS_EARLYZ;
+
+
+/* HAL statistics information. */
+typedef struct _gcsSTATISTICS
+{
+ gctUINT64 frameTime[VIV_STAT_FRAME_BUFFER_SIZE];
+ gctUINT64 previousFrameTime;
+ gctUINT frame;
+ gcsSTATISTICS_EARLYZ earlyZ;
+}
+gcsSTATISTICS;
+
+
+/* Add a frame based data into current statistics. */
+void
+gcfSTATISTICS_AddData(
+ IN gceSTATISTICS Key,
+ IN gctUINT Value
+ );
+
+/* Marks the frame end and triggers statistical calculations and decisions.*/
+void
+gcfSTATISTICS_MarkFrameEnd (
+ void
+ );
+
+/* Sets whether the dynmaic HZ is disabled or not .*/
+void
+gcfSTATISTICS_DisableDynamicEarlyZ (
+ IN gctBOOL Disabled
+ );
+
+#endif /*__gc_hal_statistics_h_ */
+
+
+
diff --git a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_types.h b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_types.h
new file mode 100644
index 000000000000..996811d82e8b
--- /dev/null
+++ b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_types.h
@@ -0,0 +1,1037 @@
+/****************************************************************************
+*
+* The MIT License (MIT)
+*
+* Copyright (c) 2014 - 2018 Vivante 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 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 GPL License (GPL)
+*
+* Copyright (C) 2014 - 2018 Vivante 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.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+*****************************************************************************
+*
+* Note: This software is released under dual MIT and GPL licenses. A
+* recipient may use this file under the terms of either the MIT license or
+* GPL License. If you wish to use only one license not the other, you can
+* indicate your decision by deleting one of the above license notices in your
+* version of this file.
+*
+*****************************************************************************/
+
+
+#ifndef __gc_hal_types_h_
+#define __gc_hal_types_h_
+
+#include "gc_hal_version.h"
+#include "gc_hal_options.h"
+
+#if !defined(VIV_KMD)
+#if defined(__KERNEL__)
+#include "linux/version.h"
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
+ typedef unsigned long uintptr_t;
+# endif
+# include "linux/types.h"
+#elif defined(UNDER_CE)
+#include <crtdefs.h>
+#elif defined(_MSC_VER) && (_MSC_VER <= 1500)
+#include <crtdefs.h>
+#include "vadefs.h"
+#elif defined(__QNXNTO__)
+#define _QNX_SOURCE
+#include <stdlib.h>
+#include <stdint.h>
+#include <stddef.h>
+#else
+#include <stdlib.h>
+#include <stddef.h>
+#include <stdint.h>
+#endif
+#endif
+
+#ifdef _WIN32
+#pragma warning(disable:4127) /* Conditional expression is constant (do { } while(0)). */
+#pragma warning(disable:4100) /* Unreferenced formal parameter. */
+#pragma warning(disable:4204) /* Non-constant aggregate initializer (C99). */
+#pragma warning(disable:4131) /* Uses old-style declarator. */
+#pragma warning(disable:4206) /* Translation unit is empty. */
+#pragma warning(disable:4214) /* Nonstandard extension used :
+ ** bit field types other than int. */
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/******************************************************************************\
+** Platform macros.
+*/
+
+#if defined(__GNUC__)
+# define gcdHAS_ELLIPSIS 1 /* GCC always has it. */
+#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)
+# define gcdHAS_ELLIPSIS 1 /* C99 has it. */
+#elif defined(_MSC_VER) && (_MSC_VER >= 1500)
+# define gcdHAS_ELLIPSIS 1 /* MSVC 2007+ has it. */
+#elif defined(UNDER_CE)
+#if UNDER_CE >= 600
+# define gcdHAS_ELLIPSIS 1
+# else
+# define gcdHAS_ELLIPSIS 0
+# endif
+#else
+# error "gcdHAS_ELLIPSIS: Platform could not be determined"
+#endif
+
+/******************************************************************************\
+************************************ Keyword ***********************************
+\******************************************************************************/
+
+#if defined(ANDROID) && defined(__BIONIC_FORTIFY)
+#if defined(__clang__)
+# define gcmINLINE __inline__ __attribute__ ((always_inline)) __attribute__ ((gnu_inline))
+# else
+# define gcmINLINE __inline__ __attribute__ ((always_inline)) __attribute__ ((gnu_inline)) __attribute__ ((artificial))
+# endif
+#elif ((defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || defined(__APPLE__))
+# define gcmINLINE inline /* C99 keyword. */
+#elif defined(__GNUC__)
+# define gcmINLINE __inline__ /* GNU keyword. */
+#elif defined(_MSC_VER) || defined(UNDER_CE)
+# define gcmINLINE __inline /* Internal keyword. */
+#else
+# error "gcmINLINE: Platform could not be determined"
+#endif
+
+/* Possible debug flags. */
+#define gcdDEBUG_NONE 0
+#define gcdDEBUG_ALL (1 << 0)
+#define gcdDEBUG_FATAL (1 << 1)
+#define gcdDEBUG_TRACE (1 << 2)
+#define gcdDEBUG_BREAK (1 << 3)
+#define gcdDEBUG_ASSERT (1 << 4)
+#define gcdDEBUG_CODE (1 << 5)
+#define gcdDEBUG_STACK (1 << 6)
+
+#define gcmIS_DEBUG(flag) (gcdDEBUG & (flag | gcdDEBUG_ALL) )
+
+#ifndef gcdDEBUG
+#if (defined(DBG) && DBG) || defined(DEBUG) || defined(_DEBUG)
+# define gcdDEBUG gcdDEBUG_ALL
+# else
+# define gcdDEBUG gcdDEBUG_NONE
+# endif
+#endif
+
+#ifdef _USRDLL
+#ifdef _MSC_VER
+#ifdef HAL_EXPORTS
+# define HALAPI __declspec(dllexport)
+# else
+# define HALAPI __declspec(dllimport)
+# endif
+# define HALDECL __cdecl
+# else
+#ifdef HAL_EXPORTS
+# define HALAPI
+# else
+# define HALAPI extern
+# endif
+# endif
+#else
+# define HALAPI
+# define HALDECL
+#endif
+
+/******************************************************************************\
+********************************** Common Types ********************************
+\******************************************************************************/
+
+#define gcvFALSE 0
+#define gcvTRUE 1
+
+#define gcvINFINITE ((gctUINT32) ~0U)
+
+#define gcvINVALID_HANDLE ((gctHANDLE) ~0U)
+
+typedef int gctBOOL;
+typedef gctBOOL * gctBOOL_PTR;
+
+typedef int gctINT;
+typedef signed char gctINT8;
+typedef signed short gctINT16;
+typedef signed int gctINT32;
+typedef signed long long gctINT64;
+
+typedef gctINT * gctINT_PTR;
+typedef gctINT8 * gctINT8_PTR;
+typedef gctINT16 * gctINT16_PTR;
+typedef gctINT32 * gctINT32_PTR;
+typedef gctINT64 * gctINT64_PTR;
+
+typedef unsigned int gctUINT;
+typedef unsigned char gctUINT8;
+typedef unsigned short gctUINT16;
+typedef unsigned int gctUINT32;
+typedef unsigned long long gctUINT64;
+typedef uintptr_t gctUINTPTR_T;
+typedef ptrdiff_t gctPTRDIFF_T;
+
+typedef gctUINT * gctUINT_PTR;
+typedef gctUINT8 * gctUINT8_PTR;
+typedef gctUINT16 * gctUINT16_PTR;
+typedef gctUINT32 * gctUINT32_PTR;
+typedef gctUINT64 * gctUINT64_PTR;
+
+typedef size_t gctSIZE_T;
+typedef gctSIZE_T * gctSIZE_T_PTR;
+typedef gctUINT32 gctTRACE;
+
+#ifdef __cplusplus
+# define gcvNULL 0
+#else
+# define gcvNULL ((void *) 0)
+#endif
+
+#define gcvMAXINT8 0x7f
+#define gcvMININT8 0x80
+#define gcvMAXINT16 0x7fff
+#define gcvMININT16 0x8000
+#define gcvMAXINT32 0x7fffffff
+#define gcvMININT32 0x80000000
+#define gcvMAXINT64 0x7fffffffffffffff
+#define gcvMININT64 0x8000000000000000
+#define gcvMAXUINT8 0xff
+#define gcvMINUINT8 0x0
+#define gcvMAXUINT16 0xffff
+#define gcvMINUINT16 0x0
+#define gcvMAXUINT32 0xffffffff
+#define gcvMINUINT32 0x0
+#define gcvMAXUINT64 0xffffffffffffffff
+#define gcvMINUINT64 0x0
+#define gcvMAXUINTPTR_T (~(gctUINTPTR_T)0)
+
+typedef float gctFLOAT;
+typedef signed int gctFIXED_POINT;
+typedef float * gctFLOAT_PTR;
+
+typedef void * gctPHYS_ADDR;
+typedef void * gctHANDLE;
+typedef void * gctFILE;
+typedef void * gctSIGNAL;
+typedef void * gctWINDOW;
+typedef void * gctIMAGE;
+typedef void * gctSHBUF;
+
+typedef void * gctSEMAPHORE;
+
+typedef void * gctPOINTER;
+typedef const void * gctCONST_POINTER;
+
+typedef char gctCHAR;
+typedef char * gctSTRING;
+typedef const char * gctCONST_STRING;
+
+typedef gctUINT64 gctPHYS_ADDR_T;
+
+typedef struct _gcsCOUNT_STRING
+{
+ gctSIZE_T Length;
+ gctCONST_STRING String;
+}
+gcsCOUNT_STRING;
+
+typedef union _gcuFLOAT_UINT32
+{
+ gctFLOAT f;
+ gctUINT32 u;
+}
+gcuFLOAT_UINT32;
+
+/* Fixed point constants. */
+#define gcvZERO_X ((gctFIXED_POINT) 0x00000000)
+#define gcvHALF_X ((gctFIXED_POINT) 0x00008000)
+#define gcvONE_X ((gctFIXED_POINT) 0x00010000)
+#define gcvNEGONE_X ((gctFIXED_POINT) 0xFFFF0000)
+#define gcvTWO_X ((gctFIXED_POINT) 0x00020000)
+
+
+
+#define gcmFIXEDCLAMP_NEG1_TO_1(_x) \
+ (((_x) < gcvNEGONE_X) \
+ ? gcvNEGONE_X \
+ : (((_x) > gcvONE_X) \
+ ? gcvONE_X \
+ : (_x)))
+
+#define gcmFLOATCLAMP_NEG1_TO_1(_f) \
+ (((_f) < -1.0f) \
+ ? -1.0f \
+ : (((_f) > 1.0f) \
+ ? 1.0f \
+ : (_f)))
+
+
+#define gcmFIXEDCLAMP_0_TO_1(_x) \
+ (((_x) < 0) \
+ ? 0 \
+ : (((_x) > gcvONE_X) \
+ ? gcvONE_X \
+ : (_x)))
+
+#define gcmFLOATCLAMP_0_TO_1(_f) \
+ (((_f) < 0.0f) \
+ ? 0.0f \
+ : (((_f) > 1.0f) \
+ ? 1.0f \
+ : (_f)))
+
+
+/******************************************************************************\
+******************************* Multicast Values *******************************
+\******************************************************************************/
+
+/* Value types. */
+typedef enum _gceVALUE_TYPE
+{
+ gcvVALUE_UINT = 0x0,
+ gcvVALUE_FIXED,
+ gcvVALUE_FLOAT,
+ gcvVALUE_INT,
+
+ /*
+ ** The value need be unsigned denormalized. clamp (0.0-1.0) should be done first.
+ */
+ gcvVALUE_FLAG_UNSIGNED_DENORM = 0x00010000,
+
+ /*
+ ** The value need be signed denormalized. clamp (-1.0-1.0) should be done first.
+ */
+ gcvVALUE_FLAG_SIGNED_DENORM = 0x00020000,
+
+ /*
+ ** The value need to gammar
+ */
+ gcvVALUE_FLAG_GAMMAR = 0x00040000,
+
+ /*
+ ** The value need to convert from float to float16
+ */
+ gcvVALUE_FLAG_FLOAT_TO_FLOAT16 = 0x0080000,
+
+ /*
+ ** Mask for flag field.
+ */
+ gcvVALUE_FLAG_MASK = 0xFFFF0000,
+}
+gceVALUE_TYPE;
+
+/* Value unions. */
+typedef union _gcuVALUE
+{
+ gctUINT uintValue;
+ gctFIXED_POINT fixedValue;
+ gctFLOAT floatValue;
+ gctINT intValue;
+}
+gcuVALUE;
+
+
+
+
+/* Stringizing macro. */
+#define gcmSTRING(Value) #Value
+
+/******************************************************************************\
+******************************* Fixed Point Math *******************************
+\******************************************************************************/
+
+#define gcmXMultiply(x1, x2) gcoMATH_MultiplyFixed(x1, x2)
+#define gcmXDivide(x1, x2) gcoMATH_DivideFixed(x1, x2)
+#define gcmXMultiplyDivide(x1, x2, x3) gcoMATH_MultiplyDivideFixed(x1, x2, x3)
+
+/* 2D Engine profile. */
+typedef struct _gcs2D_PROFILE
+{
+ /* Cycle count.
+ 32bit counter incremented every 2D clock cycle.
+ Wraps back to 0 when the counter overflows.
+ */
+ gctUINT32 cycleCount;
+
+ /* Pixels rendered by the 2D engine.
+ Resets to 0 every time it is read. */
+ gctUINT32 pixelsRendered;
+}
+gcs2D_PROFILE;
+
+/* Macro to combine four characters into a Charcater Code. */
+#define gcmCC(c1, c2, c3, c4) \
+(\
+ (char) (c1) \
+ | \
+ ((char) (c2) << 8) \
+ | \
+ ((char) (c3) << 16) \
+ | \
+ ((char) (c4) << 24) \
+)
+
+#define gcmPRINTABLE(c) ((((c) >= ' ') && ((c) <= '}')) ? ((c) != '%' ? (c) : ' ') : ' ')
+
+#define gcmCC_PRINT(cc) \
+ gcmPRINTABLE((char) ((cc) & 0xFF)), \
+ gcmPRINTABLE((char) (((cc) >> 8) & 0xFF)), \
+ gcmPRINTABLE((char) (((cc) >> 16) & 0xFF)), \
+ gcmPRINTABLE((char) (((cc) >> 24) & 0xFF))
+
+/******************************************************************************\
+****************************** Function Parameters *****************************
+\******************************************************************************/
+
+#define IN
+#define OUT
+#define INOUT
+#define OPTIONAL
+
+/******************************************************************************\
+********************************* Status Codes *********************************
+\******************************************************************************/
+
+typedef enum _gceSTATUS
+{
+ gcvSTATUS_OK = 0,
+ gcvSTATUS_FALSE = 0,
+ gcvSTATUS_TRUE = 1,
+ gcvSTATUS_NO_MORE_DATA = 2,
+ gcvSTATUS_CACHED = 3,
+ gcvSTATUS_MIPMAP_TOO_LARGE = 4,
+ gcvSTATUS_NAME_NOT_FOUND = 5,
+ gcvSTATUS_NOT_OUR_INTERRUPT = 6,
+ gcvSTATUS_MISMATCH = 7,
+ gcvSTATUS_MIPMAP_TOO_SMALL = 8,
+ gcvSTATUS_LARGER = 9,
+ gcvSTATUS_SMALLER = 10,
+ gcvSTATUS_CHIP_NOT_READY = 11,
+ gcvSTATUS_NEED_CONVERSION = 12,
+ gcvSTATUS_SKIP = 13,
+ gcvSTATUS_DATA_TOO_LARGE = 14,
+ gcvSTATUS_INVALID_CONFIG = 15,
+ gcvSTATUS_CHANGED = 16,
+ gcvSTATUS_NOT_SUPPORT_DITHER = 17,
+ gcvSTATUS_EXECUTED = 18,
+ gcvSTATUS_TERMINATE = 19,
+
+ gcvSTATUS_INVALID_ARGUMENT = -1,
+ gcvSTATUS_INVALID_OBJECT = -2,
+ gcvSTATUS_OUT_OF_MEMORY = -3,
+ gcvSTATUS_MEMORY_LOCKED = -4,
+ gcvSTATUS_MEMORY_UNLOCKED = -5,
+ gcvSTATUS_HEAP_CORRUPTED = -6,
+ gcvSTATUS_GENERIC_IO = -7,
+ gcvSTATUS_INVALID_ADDRESS = -8,
+ gcvSTATUS_CONTEXT_LOSSED = -9,
+ gcvSTATUS_TOO_COMPLEX = -10,
+ gcvSTATUS_BUFFER_TOO_SMALL = -11,
+ gcvSTATUS_INTERFACE_ERROR = -12,
+ gcvSTATUS_NOT_SUPPORTED = -13,
+ gcvSTATUS_MORE_DATA = -14,
+ gcvSTATUS_TIMEOUT = -15,
+ gcvSTATUS_OUT_OF_RESOURCES = -16,
+ gcvSTATUS_INVALID_DATA = -17,
+ gcvSTATUS_INVALID_MIPMAP = -18,
+ gcvSTATUS_NOT_FOUND = -19,
+ gcvSTATUS_NOT_ALIGNED = -20,
+ gcvSTATUS_INVALID_REQUEST = -21,
+ gcvSTATUS_GPU_NOT_RESPONDING = -22,
+ gcvSTATUS_TIMER_OVERFLOW = -23,
+ gcvSTATUS_VERSION_MISMATCH = -24,
+ gcvSTATUS_LOCKED = -25,
+ gcvSTATUS_INTERRUPTED = -26,
+ gcvSTATUS_DEVICE = -27,
+ gcvSTATUS_NOT_MULTI_PIPE_ALIGNED = -28,
+ gcvSTATUS_OUT_OF_SAMPLER = -29,
+ gcvSTATUS_CLOCK_ERROR = -30,
+
+ /* Linker errors. */
+ gcvSTATUS_GLOBAL_TYPE_MISMATCH = -1000,
+ gcvSTATUS_TOO_MANY_ATTRIBUTES = -1001,
+ gcvSTATUS_TOO_MANY_UNIFORMS = -1002,
+ gcvSTATUS_TOO_MANY_VARYINGS = -1003,
+ gcvSTATUS_UNDECLARED_VARYING = -1004,
+ gcvSTATUS_VARYING_TYPE_MISMATCH = -1005,
+ gcvSTATUS_MISSING_MAIN = -1006,
+ gcvSTATUS_NAME_MISMATCH = -1007,
+ gcvSTATUS_INVALID_INDEX = -1008,
+ gcvSTATUS_UNIFORM_MISMATCH = -1009,
+ gcvSTATUS_UNSAT_LIB_SYMBOL = -1010,
+ gcvSTATUS_TOO_MANY_SHADERS = -1011,
+ gcvSTATUS_LINK_INVALID_SHADERS = -1012,
+ gcvSTATUS_CS_NO_WORKGROUP_SIZE = -1013,
+ gcvSTATUS_LINK_LIB_ERROR = -1014,
+
+ gcvSTATUS_SHADER_VERSION_MISMATCH = -1015,
+ gcvSTATUS_TOO_MANY_INSTRUCTION = -1016,
+ gcvSTATUS_SSBO_MISMATCH = -1017,
+ gcvSTATUS_TOO_MANY_OUTPUT = -1018,
+ gcvSTATUS_TOO_MANY_INPUT = -1019,
+ gcvSTATUS_NOT_SUPPORT_CL = -1020,
+ gcvSTATUS_NOT_SUPPORT_INTEGER = -1021,
+ gcvSTATUS_UNIFORM_TYPE_MISMATCH = -1022,
+
+ gcvSTATUS_MISSING_PRIMITIVE_TYPE = -1023,
+ gcvSTATUS_MISSING_OUTPUT_VERTEX_COUNT = -1024,
+ gcvSTATUS_NON_INVOCATION_ID_AS_INDEX = -1025,
+ gcvSTATUS_INPUT_ARRAY_SIZE_MISMATCH = -1026,
+ gcvSTATUS_OUTPUT_ARRAY_SIZE_MISMATCH = -1027,
+ gcvSTATUS_LOCATION_ALIASED = -1028,
+
+ /* Compiler errors. */
+ gcvSTATUS_COMPILER_FE_PREPROCESSOR_ERROR = -2000,
+ gcvSTATUS_COMPILER_FE_PARSER_ERROR = -2001,
+
+ /* Recompilation Errors */
+ gcvSTATUS_RECOMPILER_CONVERT_UNIMPLEMENTED = -3000,
+}
+gceSTATUS;
+
+/******************************************************************************\
+********************************* Status Macros ********************************
+\******************************************************************************/
+
+#define gcmIS_ERROR(status) (status < 0)
+#define gcmNO_ERROR(status) (status >= 0)
+#define gcmIS_SUCCESS(status) (status == gcvSTATUS_OK)
+
+/******************************************************************************\
+********************************* Field Macros *********************************
+\******************************************************************************/
+
+#define __gcmSTART(reg_field) \
+ (0 ? reg_field)
+
+#define __gcmEND(reg_field) \
+ (1 ? reg_field)
+
+#define __gcmGETSIZE(reg_field) \
+ (__gcmEND(reg_field) - __gcmSTART(reg_field) + 1)
+
+#define __gcmALIGN(data, reg_field) \
+ (((gctUINT32) (data)) << __gcmSTART(reg_field))
+
+#define __gcmMASK(reg_field) \
+ ((gctUINT32) ((__gcmGETSIZE(reg_field) == 32) \
+ ? ~0U \
+ : (~(~0U << __gcmGETSIZE(reg_field)))))
+
+/*******************************************************************************
+**
+** gcmFIELDMASK
+**
+** Get aligned field mask.
+**
+** ARGUMENTS:
+**
+** reg Name of register.
+** field Name of field within register.
+*/
+#define gcmFIELDMASK(reg, field) \
+(\
+ __gcmALIGN(__gcmMASK(reg##_##field), reg##_##field) \
+)
+
+/*******************************************************************************
+**
+** gcmGETFIELD
+**
+** Extract the value of a field from specified data.
+**
+** ARGUMENTS:
+**
+** data Data value.
+** reg Name of register.
+** field Name of field within register.
+*/
+#define gcmGETFIELD(data, reg, field) \
+(\
+ ((((gctUINT32) (data)) >> __gcmSTART(reg##_##field)) \
+ & __gcmMASK(reg##_##field)) \
+)
+
+/*******************************************************************************
+**
+** gcmSETFIELD
+**
+** Set the value of a field within specified data.
+**
+** ARGUMENTS:
+**
+** data Data value.
+** reg Name of register.
+** field Name of field within register.
+** value Value for field.
+*/
+#define gcmSETFIELD(data, reg, field, value) \
+(\
+ (((gctUINT32) (data)) \
+ & ~__gcmALIGN(__gcmMASK(reg##_##field), reg##_##field)) \
+ | __gcmALIGN((gctUINT32) (value) \
+ & __gcmMASK(reg##_##field), reg##_##field) \
+)
+
+/*******************************************************************************
+**
+** gcmSETFIELDVALUE
+**
+** Set the value of a field within specified data with a
+** predefined value.
+**
+** ARGUMENTS:
+**
+** data Data value.
+** reg Name of register.
+** field Name of field within register.
+** value Name of the value within the field.
+*/
+#define gcmSETFIELDVALUE(data, reg, field, value) \
+(\
+ (((gctUINT32) (data)) \
+ & ~__gcmALIGN(__gcmMASK(reg##_##field), reg##_##field)) \
+ | __gcmALIGN(reg##_##field##_##value \
+ & __gcmMASK(reg##_##field), reg##_##field) \
+)
+
+/*******************************************************************************
+**
+** gcmGETMASKEDFIELDMASK
+**
+** Determine field mask of a masked field.
+**
+** ARGUMENTS:
+**
+** reg Name of register.
+** field Name of field within register.
+*/
+#define gcmGETMASKEDFIELDMASK(reg, field) \
+(\
+ gcmSETFIELD(0, reg, field, ~0U) | \
+ gcmSETFIELD(0, reg, MASK_ ## field, ~0U) \
+)
+
+/*******************************************************************************
+**
+** gcmSETMASKEDFIELD
+**
+** Set the value of a masked field with specified data.
+**
+** ARGUMENTS:
+**
+** reg Name of register.
+** field Name of field within register.
+** value Value for field.
+*/
+#define gcmSETMASKEDFIELD(reg, field, value) \
+(\
+ gcmSETFIELD (~0U, reg, field, value) & \
+ gcmSETFIELDVALUE(~0U, reg, MASK_ ## field, ENABLED) \
+)
+
+/*******************************************************************************
+**
+** gcmSETMASKEDFIELDVALUE
+**
+** Set the value of a masked field with specified data.
+**
+** ARGUMENTS:
+**
+** reg Name of register.
+** field Name of field within register.
+** value Value for field.
+*/
+#define gcmSETMASKEDFIELDVALUE(reg, field, value) \
+(\
+ gcmSETFIELDVALUE(~0U, reg, field, value) & \
+ gcmSETFIELDVALUE(~0U, reg, MASK_ ## field, ENABLED) \
+)
+
+/*******************************************************************************
+**
+** gcmVERIFYFIELDVALUE
+**
+** Verify if the value of a field within specified data equals a
+** predefined value.
+**
+** ARGUMENTS:
+**
+** data Data value.
+** reg Name of register.
+** field Name of field within register.
+** value Name of the value within the field.
+*/
+#define gcmVERIFYFIELDVALUE(data, reg, field, value) \
+(\
+ (((gctUINT32) (data)) >> __gcmSTART(reg##_##field) & \
+ __gcmMASK(reg##_##field)) \
+ == \
+ (reg##_##field##_##value & __gcmMASK(reg##_##field)) \
+)
+
+/*******************************************************************************
+** Bit field macros.
+*/
+
+#define __gcmSTARTBIT(Field) \
+ (1 ? Field )
+
+#define __gcmBITSIZE(Field) \
+ (0 ? Field )
+
+#define __gcmBITMASK(Field) \
+(\
+ (1 << __gcmBITSIZE(Field)) - 1 \
+)
+
+#define gcmGETBITS(Value, Type, Field) \
+(\
+ (((Type) (Value)) >> __gcmSTARTBIT(Field) ) \
+ & \
+ __gcmBITMASK(Field) \
+)
+
+#define gcmSETBITS(Value, Type, Field, NewValue) \
+(\
+ (((Type) (Value)) \
+ & ~(__gcmBITMASK(Field) << __gcmSTARTBIT(Field)) \
+ ) \
+ | \
+ ((((Type) (NewValue)) \
+ & __gcmBITMASK(Field) \
+ ) << __gcmSTARTBIT(Field) \
+ ) \
+)
+
+/*******************************************************************************
+**
+** gcmISINREGRANGE
+**
+** Verify whether the specified address is in the register range.
+**
+** ARGUMENTS:
+**
+** Address Address to be verified.
+** Name Name of a register.
+*/
+
+#define gcmISINREGRANGE(Address, Name) \
+(\
+ ((Address & (~0U << Name ## _LSB)) == (Name ## _Address >> 2)) \
+)
+
+/******************************************************************************\
+******************************** Ceiling Macro ********************************
+\******************************************************************************/
+#define gcmCEIL(x) (((x) - (gctUINT32)(x)) == 0 ? (gctUINT32)(x) : (gctUINT32)(x) + 1)
+
+/******************************************************************************\
+******************************** Min/Max Macros ********************************
+\******************************************************************************/
+
+#define gcmMIN(x, y) (((x) <= (y)) ? (x) : (y))
+#define gcmMAX(x, y) (((x) >= (y)) ? (x) : (y))
+#define gcmCLAMP(x, min, max) (((x) < (min)) ? (min) : \
+ ((x) > (max)) ? (max) : (x))
+#define gcmABS(x) (((x) < 0) ? -(x) : (x))
+#define gcmNEG(x) (((x) < 0) ? (x) : -(x))
+
+/******************************************************************************\
+******************************** Bit Macro ********************************
+\******************************************************************************/
+#define gcmBITSET(x, y) ((x) & (y))
+/*******************************************************************************
+**
+** gcmPTR2SIZE
+**
+** Convert a pointer to an integer value.
+**
+** ARGUMENTS:
+**
+** p Pointer value.
+*/
+#define gcmPTR2SIZE(p) \
+(\
+ (gctUINTPTR_T) (p) \
+)
+
+#define gcmPTR2INT32(p) \
+(\
+ (gctUINT32)(gctUINTPTR_T) (p) \
+)
+
+/*******************************************************************************
+**
+** gcmINT2PTR
+**
+** Convert an integer value into a pointer.
+**
+** ARGUMENTS:
+**
+** v Integer value.
+*/
+
+#define gcmINT2PTR(i) \
+(\
+ (gctPOINTER) (gctUINTPTR_T)(i) \
+)
+
+/*******************************************************************************
+**
+** gcmOFFSETOF
+**
+** Compute the byte offset of a field inside a structure.
+**
+** ARGUMENTS:
+**
+** s Structure name.
+** field Field name.
+*/
+#define gcmOFFSETOF(s, field) \
+(\
+ gcmPTR2INT32(& (((struct s *) 0)->field)) \
+)
+
+/*******************************************************************************
+**
+** gcmCONTAINEROF
+**
+** Get containing structure of a member.
+**
+** ARGUMENTS:
+**
+** Pointer Pointer of member.
+** Type Structure name.
+** Name Field name.
+*/
+#define gcmCONTAINEROF(Pointer, Type, Member) \
+(\
+ (struct Type *)((gctUINTPTR_T)Pointer - gcmOFFSETOF(Type, Member)) \
+)
+
+/*******************************************************************************
+**
+** gcmBSWAP32
+**
+** Return a value with all bytes in the 32 bit argument swapped.
+*/
+#if !defined(__KERNEL__) && defined(__GNUC__) && (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__ >= 40300) \
+ && !defined(__VXWORKS__)
+# define gcmBSWAP32(x) __builtin_bswap32(x)
+#else
+# define gcmBSWAP32(x) ((gctUINT32)(\
+ (((gctUINT32)(x) & (gctUINT32)0x000000FFUL) << 24) | \
+ (((gctUINT32)(x) & (gctUINT32)0x0000FF00UL) << 8) | \
+ (((gctUINT32)(x) & (gctUINT32)0x00FF0000UL) >> 8) | \
+ (((gctUINT32)(x) & (gctUINT32)0xFF000000UL) >> 24)))
+#endif
+
+/*******************************************************************************
+***** Database ****************************************************************/
+
+typedef struct _gcsDATABASE_COUNTERS
+{
+ /* Number of currently allocated bytes. */
+ gctUINT64 bytes;
+
+ /* Maximum number of bytes allocated (memory footprint). */
+ gctUINT64 maxBytes;
+
+ /* Total number of bytes allocated. */
+ gctUINT64 totalBytes;
+
+ /* The numbers of times video memory was allocated. */
+ gctUINT32 allocCount;
+
+ /* The numbers of times video memory was freed. */
+ gctUINT32 freeCount;
+}
+gcsDATABASE_COUNTERS;
+
+typedef struct _gcuDATABASE_INFO
+{
+ /* Counters. */
+ gcsDATABASE_COUNTERS counters;
+
+ /* Time value. */
+ gctUINT64 time;
+}
+gcuDATABASE_INFO;
+
+/*******************************************************************************
+***** Frame database **********************************************************/
+
+/* gcsHAL_FRAME_INFO */
+typedef struct _gcsHAL_FRAME_INFO
+{
+ /* Current timer tick. */
+ OUT gctUINT64 ticks;
+
+ /* Bandwidth counters. */
+ OUT gctUINT readBytes8[8];
+ OUT gctUINT writeBytes8[8];
+
+ /* Counters. */
+ OUT gctUINT cycles[8];
+ OUT gctUINT idleCycles[8];
+ OUT gctUINT mcCycles[8];
+ OUT gctUINT readRequests[8];
+ OUT gctUINT writeRequests[8];
+
+ /* 3D counters. */
+ OUT gctUINT vertexCount;
+ OUT gctUINT primitiveCount;
+ OUT gctUINT rejectedPrimitives;
+ OUT gctUINT culledPrimitives;
+ OUT gctUINT clippedPrimitives;
+ OUT gctUINT outPrimitives;
+ OUT gctUINT inPrimitives;
+ OUT gctUINT culledQuadCount;
+ OUT gctUINT totalQuadCount;
+ OUT gctUINT quadCount;
+ OUT gctUINT totalPixelCount;
+
+ /* PE counters. */
+ OUT gctUINT colorKilled[8];
+ OUT gctUINT colorDrawn[8];
+ OUT gctUINT depthKilled[8];
+ OUT gctUINT depthDrawn[8];
+
+ /* Shader counters. */
+ OUT gctUINT shaderCycles;
+ OUT gctUINT vsInstructionCount;
+ OUT gctUINT vsTextureCount;
+ OUT gctUINT psInstructionCount;
+ OUT gctUINT psTextureCount;
+
+ /* Texture counters. */
+ OUT gctUINT bilinearRequests;
+ OUT gctUINT trilinearRequests;
+ OUT gctUINT txBytes8;
+ OUT gctUINT txHitCount;
+ OUT gctUINT txMissCount;
+}
+gcsHAL_FRAME_INFO;
+
+typedef struct _gckLINKDATA * gckLINKDATA;
+struct _gckLINKDATA
+{
+ gctUINT32 start;
+ gctUINT32 end;
+ gctUINT32 pid;
+ gctUINT32 linkLow;
+ gctUINT32 linkHigh;
+};
+
+typedef struct _gckADDRESSDATA * gckADDRESSDATA;
+struct _gckADDRESSDATA
+{
+ gctUINT32 start;
+ gctUINT32 end;
+};
+
+typedef union _gcuQUEUEDATA
+{
+ struct _gckLINKDATA linkData;
+
+ struct _gckADDRESSDATA addressData;
+}
+gcuQUEUEDATA;
+
+typedef struct _gckQUEUE * gckQUEUE;
+struct _gckQUEUE
+{
+ gcuQUEUEDATA * datas;
+ gctUINT32 rear;
+ gctUINT32 front;
+ gctUINT32 count;
+ gctUINT32 size;
+};
+
+typedef enum _gceTRACEMODE
+{
+ gcvTRACEMODE_NONE = 0,
+ gcvTRACEMODE_FULL = 1,
+ gcvTRACEMODE_LOGGER = 2,
+ gcvTRACEMODE_PRE = 3,
+ gcvTRACEMODE_POST = 4,
+} gceTRACEMODE;
+
+typedef struct _gcsLISTHEAD * gcsLISTHEAD_PTR;
+typedef struct _gcsLISTHEAD
+{
+ gcsLISTHEAD_PTR prev;
+ gcsLISTHEAD_PTR next;
+}
+gcsLISTHEAD;
+
+/*
+ gcvFEATURE_DATABASE_DATE_MASK
+
+ Mask used to control which bits of chip date will be used to
+ query feature database, ignore release date for fpga and emulator.
+*/
+#if (gcdFPGA_BUILD || defined(EMULATOR))
+# define gcvFEATURE_DATABASE_DATE_MASK (0U)
+#else
+# define gcvFEATURE_DATABASE_DATE_MASK (~0U)
+#endif
+
+#if defined(__GNUC__)
+#if defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
+#define gcdENDIAN_BIG 1
+#else
+#define gcdENDIAN_BIG 0
+#endif
+#else
+#define gcdENDIAN_BIG 0
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __gc_hal_types_h_ */
+
+
diff --git a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_version.h b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_version.h
new file mode 100644
index 000000000000..660a8f147e79
--- /dev/null
+++ b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_version.h
@@ -0,0 +1,71 @@
+/****************************************************************************
+*
+* The MIT License (MIT)
+*
+* Copyright (c) 2014 - 2018 Vivante 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 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 GPL License (GPL)
+*
+* Copyright (C) 2014 - 2018 Vivante 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.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+*****************************************************************************
+*
+* Note: This software is released under dual MIT and GPL licenses. A
+* recipient may use this file under the terms of either the MIT license or
+* GPL License. If you wish to use only one license not the other, you can
+* indicate your decision by deleting one of the above license notices in your
+* version of this file.
+*
+*****************************************************************************/
+
+
+#ifndef __gc_hal_version_h_
+#define __gc_hal_version_h_
+
+#define gcvVERSION_MAJOR 6
+
+#define gcvVERSION_MINOR 2
+
+#define gcvVERSION_PATCH 4
+
+#define gcvVERSION_BUILD 190076
+
+#define gcvVERSION_STRING "6.2.4.p4.190076"
+
+#endif /* __gc_hal_version_h_ */
+
+
diff --git a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_vg.h b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_vg.h
new file mode 100644
index 000000000000..12d28b38cc65
--- /dev/null
+++ b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_vg.h
@@ -0,0 +1,918 @@
+/****************************************************************************
+*
+* The MIT License (MIT)
+*
+* Copyright (c) 2014 - 2018 Vivante 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 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 GPL License (GPL)
+*
+* Copyright (C) 2014 - 2018 Vivante 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.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+*****************************************************************************
+*
+* Note: This software is released under dual MIT and GPL licenses. A
+* recipient may use this file under the terms of either the MIT license or
+* GPL License. If you wish to use only one license not the other, you can
+* indicate your decision by deleting one of the above license notices in your
+* version of this file.
+*
+*****************************************************************************/
+
+
+#ifndef __gc_hal_vg_h_
+#define __gc_hal_vg_h_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#include "gc_hal_rename.h"
+#include "gc_hal_types.h"
+#include "gc_hal_enum.h"
+#include "gc_hal_base.h"
+
+#if gcdENABLE_VG
+
+/* Thread routine type. */
+#if defined(LINUX)
+ typedef gctINT gctTHREADFUNCRESULT;
+ typedef gctPOINTER gctTHREADFUNCPARAMETER;
+# define gctTHREADFUNCTYPE
+#elif defined(WIN32)
+ typedef gctUINT gctTHREADFUNCRESULT;
+ typedef gctPOINTER gctTHREADFUNCPARAMETER;
+# define gctTHREADFUNCTYPE __stdcall
+#elif defined(__QNXNTO__)
+ typedef void * gctTHREADFUNCRESULT;
+ typedef gctPOINTER gctTHREADFUNCPARAMETER;
+# define gctTHREADFUNCTYPE
+#endif
+
+typedef gctTHREADFUNCRESULT (gctTHREADFUNCTYPE * gctTHREADFUNC) (
+ gctTHREADFUNCPARAMETER ThreadParameter
+ );
+
+
+#if defined(gcvDEBUG)
+# undef gcvDEBUG
+#endif
+
+#define gcdFORCE_DEBUG 0
+#define gcdFORCE_MESSAGES 0
+
+
+#if DBG || defined(DEBUG) || defined(_DEBUG) || gcdFORCE_DEBUG
+# define gcvDEBUG 1
+#else
+# define gcvDEBUG 0
+#endif
+
+#define _gcmERROR_RETURN(prefix, func) \
+ status = func; \
+ if (gcmIS_ERROR(status)) \
+ { \
+ prefix##PRINT_VERSION(); \
+ prefix##TRACE(gcvLEVEL_ERROR, \
+ #prefix "ERR_RETURN: status=%d(%s) @ %s(%d)", \
+ status, gcoOS_DebugStatus2Name(status), __FUNCTION__, __LINE__); \
+ return status; \
+ } \
+ do { } while (gcvFALSE)
+
+#define gcmERROR_RETURN(func) _gcmERROR_RETURN(gcm, func)
+
+#define gcmLOG_LOCATION()
+
+#define gcmkIS_ERROR(status) (status < 0)
+
+#define gcmALIGNDOWN(n, align) \
+(\
+ (n) & ~((align) - 1) \
+)
+
+#define gcmIS_VALID_INDEX(Index, Array) \
+ (((gctUINT) (Index)) < gcmCOUNTOF(Array))
+
+
+#define gcmIS_NAN(x) \
+(\
+ ((* (gctUINT32_PTR) &(x)) & 0x7FFFFFFF) == 0x7FFFFFFF \
+)
+
+#define gcmLERP(v1, v2, w) \
+ ((v1) * (w) + (v2) * (1.0f - (w)))
+
+#define gcmINTERSECT(Start1, Start2, Length) \
+ (gcmABS((Start1) - (Start2)) < (Length))
+
+/*******************************************************************************
+**
+** gcmERR_GOTO
+**
+** Prints a message and terminates the current loop on error.
+**
+** ASSUMPTIONS:
+**
+** 'status' variable of gceSTATUS type must be defined.
+**
+** ARGUMENTS:
+**
+** Function
+** Function to evaluate.
+*/
+
+#define gcmERR_GOTO(Function) \
+ status = Function; \
+ if (gcmIS_ERROR(status)) \
+ { \
+ gcmTRACE(\
+ gcvLEVEL_ERROR, \
+ "gcmERR_GOTO: status=%d @ line=%d in function %s.\n", \
+ status, __LINE__, __FUNCTION__ \
+ ); \
+ goto ErrorHandler; \
+ }
+
+#if gcvDEBUG || gcdFORCE_MESSAGES
+# define gcmVERIFY_BOOLEAN(Expression) \
+ gcmASSERT(\
+ ((Expression) == gcvFALSE ) || \
+ ((Expression) == gcvTRUE ) \
+ )
+#else
+# define gcmVERIFY_BOOLEAN(Expression)
+#endif
+
+/*******************************************************************************
+**
+** gcmVERIFYFIELDFIT
+**
+** Verify whether the value fits in the field.
+**
+** ARGUMENTS:
+**
+** data Data value.
+** reg Name of register.
+** field Name of field within register.
+** value Value for field.
+*/
+#define gcmVERIFYFIELDFIT(reg, field, value) \
+ gcmASSERT(\
+ (value) <= gcmFIELDMAX(reg, field) \
+ )
+/*******************************************************************************
+**
+** gcmFIELDMAX
+**
+** Get field maximum value.
+**
+** ARGUMENTS:
+**
+** reg Name of register.
+** field Name of field within register.
+*/
+#define gcmFIELDMAX(reg, field) \
+(\
+ (gctUINT32) \
+ (\
+ (__gcmGETSIZE(reg##_##field) == 32) \
+ ? ~0U \
+ : (~(~0U << __gcmGETSIZE(reg##_##field))) \
+ ) \
+)
+
+
+/* ANSI C does not have the 'f' functions, define replacements here. */
+#define gcmSINF(x) ((gctFLOAT) sin(x))
+#define gcmCOSF(x) ((gctFLOAT) cos(x))
+#define gcmASINF(x) ((gctFLOAT) asin(x))
+#define gcmACOSF(x) ((gctFLOAT) acos(x))
+#define gcmSQRTF(x) ((gctFLOAT) sqrt(x))
+#define gcmFABSF(x) ((gctFLOAT) fabs(x))
+#define gcmFMODF(x, y) ((gctFLOAT) fmod((x), (y)))
+#define gcmCEILF(x) ((gctFLOAT) ceil(x))
+#define gcmFLOORF(x) ((gctFLOAT) floor(x))
+
+
+
+/* Fixed point constants. */
+#define gcvZERO_X ((gctFIXED_POINT) 0x00000000)
+#define gcvHALF_X ((gctFIXED_POINT) 0x00008000)
+#define gcvONE_X ((gctFIXED_POINT) 0x00010000)
+#define gcvNEGONE_X ((gctFIXED_POINT) 0xFFFF0000)
+#define gcvTWO_X ((gctFIXED_POINT) 0x00020000)
+
+/* Integer constants. */
+#define gcvMAX_POS_INT ((gctINT) 0x7FFFFFFF)
+#define gcvMAX_NEG_INT ((gctINT) 0x80000000)
+
+/* Float constants. */
+#define gcvMAX_POS_FLOAT ((gctFLOAT) 3.4028235e+038)
+#define gcvMAX_NEG_FLOAT ((gctFLOAT) -3.4028235e+038)
+
+/******************************************************************************\
+***************************** Miscellaneous Macro ******************************
+\******************************************************************************/
+
+#define gcmKB2BYTES(Kilobyte) \
+(\
+ (Kilobyte) << 10 \
+)
+
+#define gcmMB2BYTES(Megabyte) \
+(\
+ (Megabyte) << 20 \
+)
+
+#define gcmMAT(Matrix, Row, Column) \
+(\
+ (Matrix) [(Row) * 3 + (Column)] \
+)
+
+#define gcmMAKE2CHAR(Char1, Char2) \
+(\
+ ((gctUINT16) (gctUINT8) (Char1) << 0) | \
+ ((gctUINT16) (gctUINT8) (Char2) << 8) \
+)
+
+#define gcmMAKE4CHAR(Char1, Char2, Char3, Char4) \
+(\
+ ((gctUINT32)(gctUINT8) (Char1) << 0) | \
+ ((gctUINT32)(gctUINT8) (Char2) << 8) | \
+ ((gctUINT32)(gctUINT8) (Char3) << 16) | \
+ ((gctUINT32)(gctUINT8) (Char4) << 24) \
+)
+
+/* some platforms need to fix the physical address for HW to access*/
+#define gcmFIXADDRESS(address) \
+(\
+ (address)\
+)
+
+#define gcmkFIXADDRESS(address) \
+(\
+ (address)\
+)
+
+/******************************************************************************\
+****************************** Kernel Debug Macro ******************************
+\******************************************************************************/
+
+/* Return the kernel logical pointer for the given physical one. */
+gceSTATUS
+gckOS_GetKernelLogical(
+ IN gckOS Os,
+ IN gctUINT32 Address,
+ OUT gctPOINTER * KernelPointer
+ );
+
+/* Return the kernel logical pointer for the given physical one. */
+gceSTATUS
+gckOS_GetKernelLogicalEx(
+ IN gckOS Os,
+ IN gceCORE Core,
+ IN gctUINT32 Address,
+ OUT gctPOINTER * KernelPointer
+ );
+
+/*----------------------------------------------------------------------------*/
+/*----------------------------- Semaphore Object -----------------------------*/
+
+/* Increment the value of a semaphore. */
+gceSTATUS
+gckOS_IncrementSemaphore(
+ IN gckOS Os,
+ IN gctSEMAPHORE Semaphore
+ );
+
+/* Decrement the value of a semaphore (waiting might occur). */
+gceSTATUS
+gckOS_DecrementSemaphore(
+ IN gckOS Os,
+ IN gctSEMAPHORE Semaphore
+ );
+
+
+/*----------------------------------------------------------------------------*/
+/*------------------------------- Thread Object ------------------------------*/
+
+/* Start a thread. */
+gceSTATUS
+gckOS_StartThread(
+ IN gckOS Os,
+ IN gctTHREADFUNC ThreadFunction,
+ IN gctPOINTER ThreadParameter,
+ OUT gctTHREAD * Thread
+ );
+
+/* Stop a thread. */
+gceSTATUS
+gckOS_StopThread(
+ IN gckOS Os,
+ IN gctTHREAD Thread
+ );
+
+/* Verify whether the thread is still running. */
+gceSTATUS
+gckOS_VerifyThread(
+ IN gckOS Os,
+ IN gctTHREAD Thread
+ );
+
+
+/* Construct a new gckVGKERNEL object. */
+gceSTATUS
+gckVGKERNEL_Construct(
+ IN gckOS Os,
+ IN gctPOINTER Context,
+ IN gckKERNEL inKernel,
+ OUT gckVGKERNEL * Kernel
+ );
+
+/* Destroy an gckVGKERNEL object. */
+gceSTATUS
+gckVGKERNEL_Destroy(
+ IN gckVGKERNEL Kernel
+ );
+
+/* Unmap memory. */
+gceSTATUS
+gckKERNEL_UnmapMemory(
+ IN gckKERNEL Kernel,
+ IN gctPHYS_ADDR Physical,
+ IN gctSIZE_T Bytes,
+ IN gctPOINTER Logical,
+ IN gctUINT32 ProcessID
+ );
+
+/* Dispatch a user-level command. */
+gceSTATUS
+gckVGKERNEL_Dispatch(
+ IN gckKERNEL Kernel,
+ IN gctBOOL FromUser,
+ IN OUT struct _gcsHAL_INTERFACE * Interface
+ );
+
+/* Query command buffer requirements. */
+gceSTATUS
+gckKERNEL_QueryCommandBuffer(
+ IN gckKERNEL Kernel,
+ OUT gcsCOMMAND_BUFFER_INFO_PTR Information
+ );
+
+/******************************************************************************\
+******************************* gckVGHARDWARE Object ******************************
+\******************************************************************************/
+
+/* Construct a new gckVGHARDWARE object. */
+gceSTATUS
+gckVGHARDWARE_Construct(
+ IN gckOS Os,
+ OUT gckVGHARDWARE * Hardware
+ );
+
+/* Destroy an gckVGHARDWARE object. */
+gceSTATUS
+gckVGHARDWARE_Destroy(
+ IN gckVGHARDWARE Hardware
+ );
+
+/* Query system memory requirements. */
+gceSTATUS
+gckVGHARDWARE_QuerySystemMemory(
+ IN gckVGHARDWARE Hardware,
+ OUT gctSIZE_T * SystemSize,
+ OUT gctUINT32 * SystemBaseAddress
+ );
+
+/* Build virtual address. */
+gceSTATUS
+gckVGHARDWARE_BuildVirtualAddress(
+ IN gckVGHARDWARE Hardware,
+ IN gctUINT32 Index,
+ IN gctUINT32 Offset,
+ OUT gctUINT32 * Address
+ );
+
+/* Kickstart the command processor. */
+gceSTATUS
+gckVGHARDWARE_Execute(
+ IN gckVGHARDWARE Hardware,
+ IN gctUINT32 Address,
+ IN gctUINT32 Count
+ );
+
+/* Query the available memory. */
+gceSTATUS
+gckVGHARDWARE_QueryMemory(
+ IN gckVGHARDWARE Hardware,
+ OUT gctSIZE_T * InternalSize,
+ OUT gctUINT32 * InternalBaseAddress,
+ OUT gctUINT32 * InternalAlignment,
+ OUT gctSIZE_T * ExternalSize,
+ OUT gctUINT32 * ExternalBaseAddress,
+ OUT gctUINT32 * ExternalAlignment,
+ OUT gctUINT32 * HorizontalTileSize,
+ OUT gctUINT32 * VerticalTileSize
+ );
+
+/* Query the identity of the hardware. */
+gceSTATUS
+gckVGHARDWARE_QueryChipIdentity(
+ IN gckVGHARDWARE Hardware,
+ OUT gceCHIPMODEL* ChipModel,
+ OUT gctUINT32* ChipRevision,
+ OUT gctUINT32* ProductID,
+ OUT gctUINT32* EcoID,
+ OUT gctUINT32* CustomerID,
+ OUT gctUINT32* ChipFeatures,
+ OUT gctUINT32* ChipMinorFeatures,
+ OUT gctUINT32* ChipMinorFeatures1
+ );
+
+/* Convert an API format. */
+gceSTATUS
+gckVGHARDWARE_ConvertFormat(
+ IN gckVGHARDWARE Hardware,
+ IN gceSURF_FORMAT Format,
+ OUT gctUINT32 * BitsPerPixel,
+ OUT gctUINT32 * BytesPerTile
+ );
+
+/* Split a harwdare specific address into API stuff. */
+gceSTATUS
+gckVGHARDWARE_SplitMemory(
+ IN gckVGHARDWARE Hardware,
+ IN gctUINT32 Address,
+ OUT gcePOOL * Pool,
+ OUT gctUINT32 * Offset
+ );
+
+/* Align size to tile boundary. */
+gceSTATUS
+gckVGHARDWARE_AlignToTile(
+ IN gckVGHARDWARE Hardware,
+ IN gceSURF_TYPE Type,
+ IN OUT gctUINT32_PTR Width,
+ IN OUT gctUINT32_PTR Height
+ );
+
+/* Convert logical address to hardware specific address. */
+gceSTATUS
+gckVGHARDWARE_ConvertLogical(
+ IN gckVGHARDWARE Hardware,
+ IN gctPOINTER Logical,
+ IN gctBOOL InUserSpace,
+ OUT gctUINT32 * Address
+ );
+
+/* Program MMU. */
+gceSTATUS
+gckVGHARDWARE_SetMMU(
+ IN gckVGHARDWARE Hardware,
+ IN gctPOINTER Logical
+ );
+
+/* Flush the MMU. */
+gceSTATUS
+gckVGHARDWARE_FlushMMU(
+ IN gckVGHARDWARE Hardware
+ );
+
+/* Get idle register. */
+gceSTATUS
+gckVGHARDWARE_GetIdle(
+ IN gckVGHARDWARE Hardware,
+ OUT gctUINT32 * Data
+ );
+
+/* Flush the caches. */
+gceSTATUS
+gckVGHARDWARE_Flush(
+ IN gckVGHARDWARE Hardware,
+ IN gceKERNEL_FLUSH Flush,
+ IN gctPOINTER Logical,
+ IN OUT gctSIZE_T * Bytes
+ );
+
+/* Enable/disable fast clear. */
+gceSTATUS
+gckVGHARDWARE_SetFastClear(
+ IN gckVGHARDWARE Hardware,
+ IN gctINT Enable
+ );
+
+gceSTATUS
+gckVGHARDWARE_ReadInterrupt(
+ IN gckVGHARDWARE Hardware,
+ OUT gctUINT32_PTR IDs
+ );
+
+/* Power management. */
+gceSTATUS
+gckVGHARDWARE_SetPowerManagementState(
+ IN gckVGHARDWARE Hardware,
+ IN gceCHIPPOWERSTATE State
+ );
+
+gceSTATUS
+gckVGHARDWARE_QueryPowerManagementState(
+ IN gckVGHARDWARE Hardware,
+ OUT gceCHIPPOWERSTATE* State
+ );
+
+gceSTATUS
+gckVGHARDWARE_SetPowerManagement(
+ IN gckVGHARDWARE Hardware,
+ IN gctBOOL PowerManagement
+ );
+
+gceSTATUS
+gckVGHARDWARE_SetPowerOffTimeout(
+ IN gckVGHARDWARE Hardware,
+ IN gctUINT32 Timeout
+ );
+
+gceSTATUS
+gckVGHARDWARE_QueryPowerOffTimeout(
+ IN gckVGHARDWARE Hardware,
+ OUT gctUINT32* Timeout
+ );
+
+gceSTATUS
+gckVGHARDWARE_QueryIdle(
+ IN gckVGHARDWARE Hardware,
+ OUT gctBOOL_PTR IsIdle
+ );
+/******************************************************************************\
+*************************** Command Buffer Structures **************************
+\******************************************************************************/
+
+/* Vacant command buffer marker. */
+#define gcvVACANT_BUFFER ((gcsCOMPLETION_SIGNAL_PTR) ((gctSIZE_T)1))
+
+/* Command buffer header. */
+typedef struct _gcsCMDBUFFER * gcsCMDBUFFER_PTR;
+typedef struct _gcsCMDBUFFER
+{
+ /* Pointer to the completion signal. */
+ gcsCOMPLETION_SIGNAL_PTR completion;
+
+ /* The user sets this to the node of the container buffer whitin which
+ this particular command buffer resides. The kernel sets this to the
+ node of the internally allocated buffer. */
+ gcuVIDMEM_NODE_PTR node;
+
+ /* Command buffer hardware address. */
+ gctUINT32 address;
+
+ /* The offset of the buffer from the beginning of the header. */
+ gctUINT32 bufferOffset;
+
+ /* Size of the area allocated for the data portion of this particular
+ command buffer (headers and tail reserves are excluded). */
+ gctUINT32 size;
+
+ /* Offset into the buffer [0..size]; reflects exactly how much data has
+ been put into the command buffer. */
+ gctUINT offset;
+
+ /* The number of command units in the buffer for the hardware to
+ execute. */
+ gctUINT32 dataCount;
+
+ /* MANAGED BY : user HAL (gcoBUFFER object).
+ USED BY : user HAL (gcoBUFFER object).
+ Points to the immediate next allocated command buffer. */
+ gcsCMDBUFFER_PTR nextAllocated;
+
+ /* MANAGED BY : user layers (HAL and drivers).
+ USED BY : kernel HAL (gcoBUFFER object).
+ Points to the next subbuffer if any. A family of subbuffers are chained
+ together and are meant to be executed inseparably as a unit. Meaning
+ that context switching cannot occur while a chain of subbuffers is being
+ executed. */
+ gcsCMDBUFFER_PTR nextSubBuffer;
+}
+gcsCMDBUFFER;
+
+/* Command queue element. */
+typedef struct _gcsVGCMDQUEUE
+{
+ /* Pointer to the command buffer header. */
+ gcsCMDBUFFER_PTR commandBuffer;
+
+ /* Dynamic vs. static command buffer state. */
+ gctBOOL dynamic;
+}
+gcsVGCMDQUEUE;
+
+/* Context map entry. */
+typedef struct _gcsVGCONTEXT_MAP
+{
+ /* State index. */
+ gctUINT32 index;
+
+ /* New state value. */
+ gctUINT32 data;
+
+ /* Points to the next entry in the mod list. */
+ gcsVGCONTEXT_MAP_PTR next;
+}
+gcsVGCONTEXT_MAP;
+
+/* gcsVGCONTEXT structure that holds the current context. */
+typedef struct _gcsVGCONTEXT
+{
+ /* Context ID. */
+ gctUINT64 id;
+
+ /* State caching ebable flag. */
+ gctBOOL stateCachingEnabled;
+
+ /* Current pipe. */
+ gctUINT32 currentPipe;
+
+ /* State map/mod buffer. */
+ gctUINT32 mapFirst;
+ gctUINT32 mapLast;
+ gcsVGCONTEXT_MAP_PTR mapContainer;
+ gcsVGCONTEXT_MAP_PTR mapPrev;
+ gcsVGCONTEXT_MAP_PTR mapCurr;
+ gcsVGCONTEXT_MAP_PTR firstPrevMap;
+ gcsVGCONTEXT_MAP_PTR firstCurrMap;
+
+ /* Main context buffer. */
+ gcsCMDBUFFER_PTR header;
+ gctUINT32_PTR buffer;
+
+ /* Completion signal. */
+ gctHANDLE process;
+ gctSIGNAL signal;
+
+#if defined(__QNXNTO__)
+ gctSIGNAL userSignal;
+ gctINT32 coid;
+ gctINT32 rcvid;
+#endif
+}
+gcsVGCONTEXT;
+
+/* User space task header. */
+typedef struct _gcsTASK * gcsTASK_PTR;
+typedef struct _gcsTASK
+{
+ /* Pointer to the next task for the same interrupt in user space. */
+ gcsTASK_PTR next;
+
+ /* Size of the task data that immediately follows the structure. */
+ gctUINT size;
+
+ /* Task data starts here. */
+ /* ... */
+}
+gcsTASK;
+
+/* User space task master table entry. */
+typedef struct _gcsTASK_MASTER_ENTRY * gcsTASK_MASTER_ENTRY_PTR;
+typedef struct _gcsTASK_MASTER_ENTRY
+{
+ /* Pointers to the head and to the tail of the task chain. */
+ gcsTASK_PTR head;
+ gcsTASK_PTR tail;
+}
+gcsTASK_MASTER_ENTRY;
+
+/* User space task master table entry. */
+typedef struct _gcsTASK_MASTER_TABLE
+{
+ /* Table with one entry per block. */
+ gcsTASK_MASTER_ENTRY table[gcvBLOCK_COUNT];
+
+ /* The total number of tasks sckeduled. */
+ gctUINT count;
+
+ /* The total size of event data in bytes. */
+ gctUINT size;
+
+#if defined(__QNXNTO__)
+ gctINT32 coid;
+ gctINT32 rcvid;
+#endif
+}
+gcsTASK_MASTER_TABLE;
+
+/******************************************************************************\
+***************************** gckVGINTERRUPT Object ******************************
+\******************************************************************************/
+
+typedef struct _gckVGINTERRUPT * gckVGINTERRUPT;
+
+typedef gceSTATUS (* gctINTERRUPT_HANDLER)(
+ IN gckVGKERNEL Kernel
+ );
+
+gceSTATUS
+gckVGINTERRUPT_Construct(
+ IN gckVGKERNEL Kernel,
+ OUT gckVGINTERRUPT * Interrupt
+ );
+
+gceSTATUS
+gckVGINTERRUPT_Destroy(
+ IN gckVGINTERRUPT Interrupt
+ );
+
+gceSTATUS
+gckVGINTERRUPT_Enable(
+ IN gckVGINTERRUPT Interrupt,
+ IN OUT gctINT32_PTR Id,
+ IN gctINTERRUPT_HANDLER Handler
+ );
+
+gceSTATUS
+gckVGINTERRUPT_Disable(
+ IN gckVGINTERRUPT Interrupt,
+ IN gctINT32 Id
+ );
+
+#ifndef __QNXNTO__
+
+gceSTATUS
+gckVGINTERRUPT_Enque(
+ IN gckVGINTERRUPT Interrupt
+ );
+
+#else
+
+gceSTATUS
+gckVGINTERRUPT_Enque(
+ IN gckVGINTERRUPT Interrupt,
+ OUT gckOS *Os,
+ OUT gctSEMAPHORE *Semaphore
+ );
+
+#endif
+
+gceSTATUS
+gckVGINTERRUPT_DumpState(
+ IN gckVGINTERRUPT Interrupt
+ );
+
+
+/******************************************************************************\
+******************************* gckVGCOMMAND Object *******************************
+\******************************************************************************/
+
+typedef struct _gckVGCOMMAND * gckVGCOMMAND;
+
+/* Construct a new gckVGCOMMAND object. */
+gceSTATUS
+gckVGCOMMAND_Construct(
+ IN gckVGKERNEL Kernel,
+ IN gctUINT TaskGranularity,
+ IN gctUINT QueueSize,
+ OUT gckVGCOMMAND * Command
+ );
+
+/* Destroy an gckVGCOMMAND object. */
+gceSTATUS
+gckVGCOMMAND_Destroy(
+ IN gckVGCOMMAND Command
+ );
+
+/* Query command buffer attributes. */
+gceSTATUS
+gckVGCOMMAND_QueryCommandBuffer(
+ IN gckVGCOMMAND Command,
+ OUT gcsCOMMAND_BUFFER_INFO_PTR Information
+ );
+
+/* Allocate a command queue. */
+gceSTATUS
+gckVGCOMMAND_Allocate(
+ IN gckVGCOMMAND Command,
+ IN gctSIZE_T Size,
+ OUT gcsCMDBUFFER_PTR * CommandBuffer,
+ OUT gctPOINTER * Data
+ );
+
+/* Release memory held by the command queue. */
+gceSTATUS
+gckVGCOMMAND_Free(
+ IN gckVGCOMMAND Command,
+ IN gcsCMDBUFFER_PTR CommandBuffer
+ );
+
+/* Schedule the command queue for execution. */
+gceSTATUS
+gckVGCOMMAND_Execute(
+ IN gckVGCOMMAND Command,
+ IN gcsCMDBUFFER_PTR CommandBuffer
+ );
+
+/* Commit a buffer to the command queue. */
+gceSTATUS
+gckVGCOMMAND_Commit(
+ IN gckVGCOMMAND Command,
+ IN gcsVGCONTEXT_PTR Context,
+ IN gcsVGCMDQUEUE_PTR Queue,
+ IN gctUINT EntryCount,
+ IN gcsTASK_MASTER_TABLE_PTR TaskTable
+ );
+
+/******************************************************************************\
+********************************* gckVGMMU Object ********************************
+\******************************************************************************/
+
+typedef struct _gckVGMMU * gckVGMMU;
+
+/* Construct a new gckVGMMU object. */
+gceSTATUS
+gckVGMMU_Construct(
+ IN gckVGKERNEL Kernel,
+ IN gctUINT32 MmuSize,
+ OUT gckVGMMU * Mmu
+ );
+
+/* Destroy an gckVGMMU object. */
+gceSTATUS
+gckVGMMU_Destroy(
+ IN gckVGMMU Mmu
+ );
+
+/* Allocate pages inside the MMU. */
+gceSTATUS
+gckVGMMU_AllocatePages(
+ IN gckVGMMU Mmu,
+ IN gctSIZE_T PageCount,
+ OUT gctPOINTER * PageTable,
+ OUT gctUINT32 * Address
+ );
+
+/* Remove a page table from the MMU. */
+gceSTATUS
+gckVGMMU_FreePages(
+ IN gckVGMMU Mmu,
+ IN gctPOINTER PageTable,
+ IN gctSIZE_T PageCount
+ );
+
+/* Set the MMU page with info. */
+gceSTATUS
+gckVGMMU_SetPage(
+ IN gckVGMMU Mmu,
+ IN gctUINT32 PageAddress,
+ IN gctUINT32 *PageEntry
+ );
+
+/* Flush MMU */
+gceSTATUS
+gckVGMMU_Flush(
+ IN gckVGMMU Mmu
+ );
+
+#endif /* gcdENABLE_VG */
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* __gc_hal_h_ */
+
+
diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/allocator/default/gc_hal_kernel_allocator_array.h b/drivers/mxc/gpu-viv/hal/os/linux/kernel/allocator/default/gc_hal_kernel_allocator_array.h
new file mode 100644
index 000000000000..8abb7e52f5ce
--- /dev/null
+++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/allocator/default/gc_hal_kernel_allocator_array.h
@@ -0,0 +1,119 @@
+/****************************************************************************
+*
+* The MIT License (MIT)
+*
+* Copyright (c) 2014 - 2018 Vivante 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 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 GPL License (GPL)
+*
+* Copyright (C) 2014 - 2018 Vivante 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.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+*****************************************************************************
+*
+* Note: This software is released under dual MIT and GPL licenses. A
+* recipient may use this file under the terms of either the MIT license or
+* GPL License. If you wish to use only one license not the other, you can
+* indicate your decision by deleting one of the above license notices in your
+* version of this file.
+*
+*****************************************************************************/
+
+
+#ifndef __gc_hal_kernel_allocator_array_h_
+#define __gc_hal_kernel_allocator_array_h_
+
+extern gceSTATUS
+_GFPAlloctorInit(
+ IN gckOS Os,
+ IN gcsDEBUGFS_DIR *Parent,
+ OUT gckALLOCATOR * Allocator
+ );
+
+extern gceSTATUS
+_UserMemoryAlloctorInit(
+ IN gckOS Os,
+ IN gcsDEBUGFS_DIR *Parent,
+ OUT gckALLOCATOR * Allocator
+ );
+
+extern gceSTATUS
+_ReservedMemoryAllocatorInit(
+ IN gckOS Os,
+ IN gcsDEBUGFS_DIR *Parent,
+ OUT gckALLOCATOR * Allocator
+ );
+
+#ifdef CONFIG_DMA_SHARED_BUFFER
+extern gceSTATUS
+_DmabufAlloctorInit(
+ IN gckOS Os,
+ IN gcsDEBUGFS_DIR *Parent,
+ OUT gckALLOCATOR * Allocator
+ );
+#endif
+
+#ifndef NO_DMA_COHERENT
+extern gceSTATUS
+_DmaAlloctorInit(
+ IN gckOS Os,
+ IN gcsDEBUGFS_DIR *Parent,
+ OUT gckALLOCATOR * Allocator
+ );
+#endif
+
+/* Default allocator entry. */
+gcsALLOCATOR_DESC allocatorArray[] =
+{
+ /* GFP allocator. */
+ gcmkDEFINE_ALLOCATOR_DESC("gfp", _GFPAlloctorInit),
+
+ /* User memory importer. */
+ gcmkDEFINE_ALLOCATOR_DESC("user", _UserMemoryAlloctorInit),
+
+#ifdef CONFIG_DMA_SHARED_BUFFER
+ /* Dmabuf allocator. */
+ gcmkDEFINE_ALLOCATOR_DESC("dmabuf", _DmabufAlloctorInit),
+#endif
+
+#ifndef NO_DMA_COHERENT
+ gcmkDEFINE_ALLOCATOR_DESC("dma", _DmaAlloctorInit),
+#endif
+
+ gcmkDEFINE_ALLOCATOR_DESC("reserved-mem", _ReservedMemoryAllocatorInit),
+};
+
+#endif
diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/allocator/default/gc_hal_kernel_allocator_dma.c b/drivers/mxc/gpu-viv/hal/os/linux/kernel/allocator/default/gc_hal_kernel_allocator_dma.c
new file mode 100644
index 000000000000..36bf9c5552f0
--- /dev/null
+++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/allocator/default/gc_hal_kernel_allocator_dma.c
@@ -0,0 +1,604 @@
+/****************************************************************************
+*
+* The MIT License (MIT)
+*
+* Copyright (c) 2014 - 2018 Vivante 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 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 GPL License (GPL)
+*
+* Copyright (C) 2014 - 2018 Vivante 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.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+*****************************************************************************
+*
+* Note: This software is released under dual MIT and GPL licenses. A
+* recipient may use this file under the terms of either the MIT license or
+* GPL License. If you wish to use only one license not the other, you can
+* indicate your decision by deleting one of the above license notices in your
+* version of this file.
+*
+*****************************************************************************/
+
+
+#include "gc_hal_kernel_linux.h"
+#include "gc_hal_kernel_allocator.h"
+
+#include <linux/pagemap.h>
+#include <linux/seq_file.h>
+#include <linux/mman.h>
+#include <asm/atomic.h>
+#include <linux/dma-mapping.h>
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,19,0)
+#include <linux/dma-direct.h>
+#endif
+
+#include <linux/slab.h>
+#include <linux/platform_device.h>
+
+#define _GC_OBJ_ZONE gcvZONE_OS
+
+typedef struct _gcsDMA_PRIV * gcsDMA_PRIV_PTR;
+typedef struct _gcsDMA_PRIV {
+ atomic_t usage;
+}
+gcsDMA_PRIV;
+
+struct mdl_dma_priv {
+ gctPOINTER kvaddr;
+ dma_addr_t dmaHandle;
+};
+
+/*
+* Debugfs support.
+*/
+static int gc_dma_usage_show(struct seq_file* m, void* data)
+{
+ gcsINFO_NODE *node = m->private;
+ gckALLOCATOR Allocator = node->device;
+ gcsDMA_PRIV_PTR priv = Allocator->privateData;
+ long long usage = (long long)atomic_read(&priv->usage);
+
+ seq_printf(m, "type n pages bytes\n");
+ seq_printf(m, "normal %10llu %12llu\n", usage, usage * PAGE_SIZE);
+
+ return 0;
+}
+
+static gcsINFO InfoList[] =
+{
+ {"dmausage", gc_dma_usage_show},
+};
+
+static void
+_DebugfsInit(
+ IN gckALLOCATOR Allocator,
+ IN gckDEBUGFS_DIR Root
+ )
+{
+ gcmkVERIFY_OK(
+ gckDEBUGFS_DIR_Init(&Allocator->debugfsDir, Root->root, "dma"));
+
+ gcmkVERIFY_OK(gckDEBUGFS_DIR_CreateFiles(
+ &Allocator->debugfsDir,
+ InfoList,
+ gcmCOUNTOF(InfoList),
+ Allocator
+ ));
+}
+
+static void
+_DebugfsCleanup(
+ IN gckALLOCATOR Allocator
+ )
+{
+ gcmkVERIFY_OK(gckDEBUGFS_DIR_RemoveFiles(
+ &Allocator->debugfsDir,
+ InfoList,
+ gcmCOUNTOF(InfoList)
+ ));
+
+ gckDEBUGFS_DIR_Deinit(&Allocator->debugfsDir);
+}
+
+static gceSTATUS
+_DmaAlloc(
+ IN gckALLOCATOR Allocator,
+ INOUT PLINUX_MDL Mdl,
+ IN gctSIZE_T NumPages,
+ IN gctUINT32 Flags
+ )
+{
+ gceSTATUS status;
+ u32 gfp = GFP_KERNEL | gcdNOWARN;
+ gcsDMA_PRIV_PTR allocatorPriv = (gcsDMA_PRIV_PTR)Allocator->privateData;
+
+ struct mdl_dma_priv *mdlPriv=gcvNULL;
+ gckOS os = Allocator->os;
+
+ gcmkHEADER_ARG("Mdl=%p NumPages=0x%zx Flags=0x%x", Mdl, NumPages, Flags);
+
+ gcmkONERROR(gckOS_Allocate(os, sizeof(struct mdl_dma_priv), (gctPOINTER *)&mdlPriv));
+ mdlPriv->kvaddr = gcvNULL;
+
+#if defined(CONFIG_ZONE_DMA32) && LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)
+ if (Flags & gcvALLOC_FLAG_4GB_ADDR)
+ {
+ gfp |= __GFP_DMA32;
+ }
+#endif
+
+ mdlPriv->kvaddr
+#if defined CONFIG_MIPS || defined CONFIG_CPU_CSKYV2 || defined CONFIG_PPC || defined CONFIG_ARM64
+ = dma_alloc_coherent(galcore_device, NumPages * PAGE_SIZE, &mdlPriv->dmaHandle, gfp);
+#else
+ = dma_alloc_writecombine(galcore_device, NumPages * PAGE_SIZE, &mdlPriv->dmaHandle, gfp);
+#endif
+
+#ifdef CONFLICT_BETWEEN_BASE_AND_PHYS
+ if ((os->device->baseAddress & 0x80000000) != (mdlPriv->dmaHandle & 0x80000000))
+ {
+ mdlPriv->dmaHandle = (mdlPriv->dmaHandle & ~0x80000000)
+ | (os->device->baseAddress & 0x80000000);
+ }
+#endif
+
+ if (mdlPriv->kvaddr == gcvNULL)
+ {
+ gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
+ }
+
+ Mdl->priv = mdlPriv;
+
+ Mdl->dmaHandle = mdlPriv->dmaHandle;
+
+ /* Statistic. */
+ atomic_add(NumPages, &allocatorPriv->usage);
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ if (mdlPriv)
+ {
+ gckOS_Free(os, mdlPriv);
+ }
+
+ gcmkFOOTER();
+ return status;
+}
+
+static gceSTATUS
+_DmaGetSGT(
+ IN gckALLOCATOR Allocator,
+ IN PLINUX_MDL Mdl,
+ IN gctSIZE_T Offset,
+ IN gctSIZE_T Bytes,
+ OUT gctPOINTER *SGT
+ )
+{
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)
+ struct page ** pages = gcvNULL;
+ struct page * page = gcvNULL;
+ struct sg_table *sgt = NULL;
+ struct mdl_dma_priv *mdlPriv = (struct mdl_dma_priv*)Mdl->priv;
+
+ gceSTATUS status = gcvSTATUS_OK;
+ gctSIZE_T offset = Offset & ~PAGE_MASK; /* Offset to the first page */
+ gctINT skipPages = Offset >> PAGE_SHIFT; /* skipped pages */
+ gctINT numPages = (PAGE_ALIGN(Offset + Bytes) >> PAGE_SHIFT) - skipPages;
+ gctINT i;
+
+ gcmkASSERT(Offset + Bytes <= Mdl->numPages << PAGE_SHIFT);
+
+ sgt = kmalloc(sizeof(struct sg_table), GFP_KERNEL | gcdNOWARN);
+ if (!sgt)
+ {
+ gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
+ }
+
+ pages = kmalloc(sizeof(struct page*) * numPages, GFP_KERNEL | gcdNOWARN);
+ if (!pages)
+ {
+ gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
+ }
+
+#if !defined(phys_to_page)
+ page = virt_to_page(mdlPriv->kvaddr);
+#elif LINUX_VERSION_CODE < KERNEL_VERSION(3,13,0)
+ page = phys_to_page(mdlPriv->dmaHandle);
+#else
+ page = phys_to_page(dma_to_phys(&Allocator->os->device->platform->device->dev, mdlPriv->dmaHandle));
+#endif
+
+ for (i = 0; i < numPages; ++i)
+ {
+ pages[i] = nth_page(page, i + skipPages);
+ }
+
+ if (sg_alloc_table_from_pages(sgt, pages, numPages, offset, Bytes, GFP_KERNEL) < 0)
+ {
+ gcmkONERROR(gcvSTATUS_GENERIC_IO);
+ }
+
+ *SGT = (gctPOINTER)sgt;
+
+OnError:
+ if (pages)
+ {
+ kfree(pages);
+ }
+
+ if (gcmIS_ERROR(status) && sgt)
+ {
+ kfree(sgt);
+ }
+
+ return status;
+#else
+ return gcvSTATUS_NOT_SUPPORTED;
+#endif
+}
+
+static void
+_DmaFree(
+ IN gckALLOCATOR Allocator,
+ IN OUT PLINUX_MDL Mdl
+ )
+{
+ gckOS os = Allocator->os;
+ struct mdl_dma_priv *mdlPriv=(struct mdl_dma_priv *)Mdl->priv;
+ gcsDMA_PRIV_PTR allocatorPriv = (gcsDMA_PRIV_PTR)Allocator->privateData;
+
+#if defined CONFIG_MIPS || defined CONFIG_CPU_CSKYV2 || defined CONFIG_PPC || defined CONFIG_ARM64
+ dma_free_coherent(galcore_device, Mdl->numPages * PAGE_SIZE, mdlPriv->kvaddr, mdlPriv->dmaHandle);
+#else
+ dma_free_writecombine(galcore_device, Mdl->numPages * PAGE_SIZE, mdlPriv->kvaddr, mdlPriv->dmaHandle);
+#endif
+
+ gckOS_Free(os, mdlPriv);
+
+ /* Statistic. */
+ atomic_sub(Mdl->numPages, &allocatorPriv->usage);
+}
+
+static gceSTATUS
+_DmaMmap(
+ IN gckALLOCATOR Allocator,
+ IN PLINUX_MDL Mdl,
+ IN gctBOOL Cacheable,
+ IN gctSIZE_T skipPages,
+ IN gctSIZE_T numPages,
+ IN struct vm_area_struct *vma
+ )
+{
+ struct mdl_dma_priv *mdlPriv = (struct mdl_dma_priv*)Mdl->priv;
+ gceSTATUS status = gcvSTATUS_OK;
+
+ gcmkHEADER_ARG("Allocator=%p Mdl=%p vma=%p", Allocator, Mdl, vma);
+
+ gcmkASSERT(skipPages + numPages <= Mdl->numPages);
+
+ /* map kernel memory to user space.. */
+#if defined CONFIG_MIPS || defined CONFIG_CPU_CSKYV2 || defined CONFIG_PPC
+ if (remap_pfn_range(
+ vma,
+ vma->vm_start,
+ (mdlPriv->dmaHandle >> PAGE_SHIFT) + skipPages,
+ numPages << PAGE_SHIFT,
+ pgprot_writecombine(vma->vm_page_prot)) < 0)
+#else
+ /* map kernel memory to user space.. */
+ if (dma_mmap_writecombine(gcvNULL,
+ vma,
+ (gctINT8_PTR)mdlPriv->kvaddr + (skipPages << PAGE_SHIFT),
+ mdlPriv->dmaHandle + (skipPages << PAGE_SHIFT),
+ numPages << PAGE_SHIFT) < 0)
+#endif
+ {
+ gcmkTRACE_ZONE(
+ gcvLEVEL_WARNING, gcvZONE_OS,
+ "%s(%d): dma_mmap_attrs error",
+ __FUNCTION__, __LINE__
+ );
+
+ status = gcvSTATUS_OUT_OF_MEMORY;
+ }
+
+ gcmkFOOTER();
+ return status;
+}
+
+static void
+_DmaUnmapUser(
+ IN gckALLOCATOR Allocator,
+ IN PLINUX_MDL Mdl,
+ IN PLINUX_MDL_MAP MdlMap,
+ IN gctUINT32 Size
+ )
+{
+ if (unlikely(current->mm == gcvNULL))
+ {
+ /* Do nothing if process is exiting. */
+ return;
+ }
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0)
+ if (vm_munmap((unsigned long)MdlMap->vmaAddr, Size) < 0)
+ {
+ gcmkTRACE_ZONE(
+ gcvLEVEL_WARNING, gcvZONE_OS,
+ "%s(%d): vm_munmap failed",
+ __FUNCTION__, __LINE__
+ );
+ }
+#else
+ down_write(&current->mm->mmap_sem);
+ if (do_munmap(current->mm, (unsigned long)MdlMap->vmaAddr, Size) < 0)
+ {
+ gcmkTRACE_ZONE(
+ gcvLEVEL_WARNING, gcvZONE_OS,
+ "%s(%d): do_munmap failed",
+ __FUNCTION__, __LINE__
+ );
+ }
+ up_write(&current->mm->mmap_sem);
+#endif
+}
+
+static gceSTATUS
+_DmaMapUser(
+ gckALLOCATOR Allocator,
+ PLINUX_MDL Mdl,
+ PLINUX_MDL_MAP MdlMap,
+ gctBOOL Cacheable
+ )
+{
+ gctPOINTER userLogical = gcvNULL;
+ gceSTATUS status = gcvSTATUS_OK;
+
+ gcmkHEADER_ARG("Allocator=%p Mdl=%p Cacheable=%d", Allocator, Mdl, Cacheable);
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0)
+ userLogical = (gctPOINTER)vm_mmap(gcvNULL,
+ 0L,
+ Mdl->numPages * PAGE_SIZE,
+ PROT_READ | PROT_WRITE,
+ MAP_SHARED | MAP_NORESERVE,
+ 0);
+#else
+ down_write(&current->mm->mmap_sem);
+ userLogical = (gctPOINTER)do_mmap_pgoff(gcvNULL,
+ 0L,
+ Mdl->numPages * PAGE_SIZE,
+ PROT_READ | PROT_WRITE,
+ MAP_SHARED,
+ 0);
+ up_write(&current->mm->mmap_sem);
+#endif
+
+ gcmkTRACE_ZONE(
+ gcvLEVEL_INFO, gcvZONE_OS,
+ "%s(%d): vmaAddr->%p for phys_addr->%p",
+ __FUNCTION__, __LINE__, userLogical, Mdl
+ );
+
+ if (IS_ERR(userLogical))
+ {
+ gcmkTRACE_ZONE(
+ gcvLEVEL_INFO, gcvZONE_OS,
+ "%s(%d): do_mmap_pgoff error",
+ __FUNCTION__, __LINE__
+ );
+
+ gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
+ }
+
+ down_write(&current->mm->mmap_sem);
+ do
+ {
+ struct vm_area_struct *vma = find_vma(current->mm, (unsigned long)userLogical);
+ if (vma == gcvNULL)
+ {
+ gcmkTRACE_ZONE(
+ gcvLEVEL_INFO, gcvZONE_OS,
+ "%s(%d): find_vma error",
+ __FUNCTION__, __LINE__
+ );
+
+ gcmkERR_BREAK(gcvSTATUS_OUT_OF_RESOURCES);
+ }
+
+ gcmkERR_BREAK(_DmaMmap(Allocator, Mdl, Cacheable, 0, Mdl->numPages, vma));
+
+ MdlMap->vmaAddr = userLogical;
+ MdlMap->cacheable = gcvFALSE;
+ MdlMap->vma = vma;
+ }
+ while (gcvFALSE);
+ up_write(&current->mm->mmap_sem);
+
+OnError:
+ if (gcmIS_ERROR(status) && userLogical)
+ {
+ _DmaUnmapUser(Allocator, Mdl, userLogical, Mdl->numPages * PAGE_SIZE);
+ }
+ gcmkFOOTER();
+ return status;
+}
+
+static gceSTATUS
+_DmaMapKernel(
+ IN gckALLOCATOR Allocator,
+ IN PLINUX_MDL Mdl,
+ OUT gctPOINTER *Logical
+ )
+{
+ struct mdl_dma_priv *mdlPriv=(struct mdl_dma_priv *)Mdl->priv;
+ *Logical =mdlPriv->kvaddr;
+ return gcvSTATUS_OK;
+}
+
+static gceSTATUS
+_DmaUnmapKernel(
+ IN gckALLOCATOR Allocator,
+ IN PLINUX_MDL Mdl,
+ IN gctPOINTER Logical
+ )
+{
+ return gcvSTATUS_OK;
+}
+
+static gceSTATUS
+_DmaCache(
+ IN gckALLOCATOR Allocator,
+ IN PLINUX_MDL Mdl,
+ IN gctSIZE_T Offset,
+ IN gctPOINTER Logical,
+ IN gctUINT32 Bytes,
+ IN gceCACHEOPERATION Operation
+ )
+{
+ switch (Operation)
+ {
+ case gcvCACHE_CLEAN:
+ case gcvCACHE_FLUSH:
+ _MemoryBarrier();
+ break;
+ case gcvCACHE_INVALIDATE:
+ break;
+ default:
+ return gcvSTATUS_INVALID_ARGUMENT;
+ }
+
+ return gcvSTATUS_OK;
+}
+
+static gceSTATUS
+_DmaPhysical(
+ IN gckALLOCATOR Allocator,
+ IN PLINUX_MDL Mdl,
+ IN gctUINT32 Offset,
+ OUT gctPHYS_ADDR_T * Physical
+ )
+{
+ struct mdl_dma_priv *mdlPriv=(struct mdl_dma_priv *)Mdl->priv;
+
+ *Physical = mdlPriv->dmaHandle + Offset;
+
+ return gcvSTATUS_OK;
+}
+
+static void
+_DmaAllocatorDestructor(
+ gcsALLOCATOR *Allocator
+ )
+{
+ _DebugfsCleanup(Allocator);
+
+ if (Allocator->privateData)
+ {
+ kfree(Allocator->privateData);
+ }
+
+ kfree(Allocator);
+}
+
+/* Default allocator operations. */
+gcsALLOCATOR_OPERATIONS DmaAllocatorOperations = {
+ .Alloc = _DmaAlloc,
+ .Free = _DmaFree,
+ .Mmap = _DmaMmap,
+ .MapUser = _DmaMapUser,
+ .UnmapUser = _DmaUnmapUser,
+ .MapKernel = _DmaMapKernel,
+ .UnmapKernel = _DmaUnmapKernel,
+ .Cache = _DmaCache,
+ .Physical = _DmaPhysical,
+ .GetSGT = _DmaGetSGT,
+};
+
+/* Default allocator entry. */
+gceSTATUS
+_DmaAlloctorInit(
+ IN gckOS Os,
+ IN gcsDEBUGFS_DIR *Parent,
+ OUT gckALLOCATOR * Allocator
+ )
+{
+ gceSTATUS status;
+ gckALLOCATOR allocator = gcvNULL;
+ gcsDMA_PRIV_PTR priv = gcvNULL;
+
+ gcmkONERROR(gckALLOCATOR_Construct(Os, &DmaAllocatorOperations, &allocator));
+
+ priv = kzalloc(gcmSIZEOF(gcsDMA_PRIV), GFP_KERNEL | gcdNOWARN);
+
+ if (!priv)
+ {
+ gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
+ }
+
+ atomic_set(&priv->usage, 0);
+
+ /* Register private data. */
+ allocator->privateData = priv;
+ allocator->destructor = _DmaAllocatorDestructor;
+
+ _DebugfsInit(allocator, Parent);
+
+ /*
+ * DMA allocator is only used for NonPaged memory
+ * when NO_DMA_COHERENT is not defined.
+ */
+ allocator->capability = gcvALLOC_FLAG_CONTIGUOUS
+ | gcvALLOC_FLAG_DMABUF_EXPORTABLE
+#if defined(CONFIG_ZONE_DMA32) && LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)
+ | gcvALLOC_FLAG_4GB_ADDR
+#endif
+ ;
+
+ *Allocator = allocator;
+
+ return gcvSTATUS_OK;
+
+OnError:
+ if (allocator)
+ {
+ kfree(allocator);
+ }
+ return status;
+}
+
diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/allocator/default/gc_hal_kernel_allocator_dmabuf.c b/drivers/mxc/gpu-viv/hal/os/linux/kernel/allocator/default/gc_hal_kernel_allocator_dmabuf.c
new file mode 100644
index 000000000000..6f37daf74778
--- /dev/null
+++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/allocator/default/gc_hal_kernel_allocator_dmabuf.c
@@ -0,0 +1,546 @@
+/****************************************************************************
+*
+* The MIT License (MIT)
+*
+* Copyright (c) 2014 - 2018 Vivante 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 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 GPL License (GPL)
+*
+* Copyright (C) 2014 - 2018 Vivante 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.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+*****************************************************************************
+*
+* Note: This software is released under dual MIT and GPL licenses. A
+* recipient may use this file under the terms of either the MIT license or
+* GPL License. If you wish to use only one license not the other, you can
+* indicate your decision by deleting one of the above license notices in your
+* version of this file.
+*
+*****************************************************************************/
+
+
+#include "gc_hal_kernel_linux.h"
+#include "gc_hal_kernel_allocator.h"
+
+#include <linux/pagemap.h>
+#include <linux/seq_file.h>
+#include <linux/mman.h>
+#include <linux/slab.h>
+#include <linux/mutex.h>
+#include <asm/atomic.h>
+#include <linux/dma-mapping.h>
+
+#include <linux/dma-buf.h>
+#include <linux/platform_device.h>
+
+#define _GC_OBJ_ZONE gcvZONE_OS
+
+/* Descriptor of a dma_buf imported. */
+typedef struct _gcsDMABUF
+{
+ struct dma_buf * dmabuf;
+ struct dma_buf_attachment * attachment;
+ struct sg_table * sgt;
+ unsigned long * pagearray;
+
+ int npages;
+ int pid;
+ struct list_head list;
+}
+gcsDMABUF;
+
+struct allocator_priv
+{
+ struct mutex lock;
+ struct list_head buf_list;
+};
+
+/*
+* Debugfs support.
+*/
+static int dma_buf_info_show(struct seq_file* m, void* data)
+{
+ int ret;
+ gcsDMABUF *buf_desc;
+ struct dma_buf_attachment *attach_obj;
+ int count = 0;
+ size_t size = 0;
+ int npages = 0;
+ const char *exp_name;
+
+ gcsINFO_NODE *node = m->private;
+ gckALLOCATOR allocator = node->device;
+ struct allocator_priv *priv = allocator->privateData;
+
+ ret = mutex_lock_interruptible(&priv->lock);
+
+ if (ret)
+ return ret;
+
+ seq_puts(m, "Attached dma-buf objects:\n");
+ seq_puts(m, " pid fd pages size exporter attached-devices\n");
+
+ list_for_each_entry(buf_desc, &priv->buf_list, list) {
+ struct dma_buf *buf_obj = buf_desc->dmabuf;
+
+ ret = mutex_lock_interruptible(&buf_obj->lock);
+
+ if (ret) {
+ seq_puts(m,
+ "ERROR locking buffer object: skipping\n");
+ continue;
+ }
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0)
+ exp_name = buf_obj->exp_name;
+#else
+ exp_name = "unknown";
+#endif
+
+ seq_printf(m, "%6d %p %8d %8zu %10s",
+ buf_desc->pid,
+ buf_desc->dmabuf,
+ buf_desc->npages,
+ buf_obj->size,
+ exp_name);
+
+ list_for_each_entry(attach_obj, &buf_obj->attachments, node) {
+ seq_printf(m, " %s", dev_name(attach_obj->dev));
+ }
+ seq_puts(m, "\n");
+
+ count++;
+ size += buf_obj->size;
+ npages += buf_desc->npages;
+
+ mutex_unlock(&buf_obj->lock);
+ }
+
+ seq_printf(m, "\nTotal %d objects, %d pages, %zu bytes\n", count, npages, size);
+
+ mutex_unlock(&priv->lock);
+ return 0;
+}
+
+static gcsINFO _InfoList[] =
+{
+ {"bufinfo", dma_buf_info_show},
+};
+
+static void
+_DebugfsInit(
+ IN gckALLOCATOR Allocator,
+ IN gckDEBUGFS_DIR Root
+ )
+{
+ gcmkVERIFY_OK(
+ gckDEBUGFS_DIR_Init(&Allocator->debugfsDir, Root->root, "dma_buf"));
+
+ gcmkVERIFY_OK(gckDEBUGFS_DIR_CreateFiles(
+ &Allocator->debugfsDir,
+ _InfoList,
+ gcmCOUNTOF(_InfoList),
+ Allocator
+ ));
+}
+
+static void
+_DebugfsCleanup(
+ IN gckALLOCATOR Allocator
+ )
+{
+ gcmkVERIFY_OK(gckDEBUGFS_DIR_RemoveFiles(
+ &Allocator->debugfsDir,
+ _InfoList,
+ gcmCOUNTOF(_InfoList)
+ ));
+
+ gckDEBUGFS_DIR_Deinit(&Allocator->debugfsDir);
+}
+
+static gceSTATUS
+_DmabufAttach(
+ IN gckALLOCATOR Allocator,
+ IN gcsATTACH_DESC_PTR Desc,
+ IN PLINUX_MDL Mdl
+ )
+{
+ gceSTATUS status;
+
+ gckOS os = Allocator->os;
+
+ struct dma_buf *dmabuf = Desc->dmaBuf.dmabuf;
+ struct sg_table *sgt = NULL;
+ struct dma_buf_attachment *attachment = NULL;
+ int npages = 0;
+ unsigned long *pagearray = NULL;
+ int i, j, k = 0;
+ struct scatterlist *s;
+ struct allocator_priv *priv = Allocator->privateData;
+ gcsDMABUF *buf_desc = NULL;
+
+ gcmkHEADER();
+
+ gcmkVERIFY_OBJECT(os, gcvOBJ_OS);
+
+ if (!dmabuf)
+ {
+ gcmkONERROR(gcvSTATUS_NOT_SUPPORTED);
+ }
+
+ get_dma_buf(dmabuf);
+ attachment = dma_buf_attach(dmabuf, &os->device->platform->device->dev);
+
+ if (!attachment)
+ {
+ gcmkONERROR(gcvSTATUS_NOT_SUPPORTED);
+ }
+
+ sgt = dma_buf_map_attachment(attachment, DMA_BIDIRECTIONAL);
+
+ if (!sgt)
+ {
+ gcmkONERROR(gcvSTATUS_NOT_SUPPORTED);
+ }
+
+ /* Prepare page array. */
+ /* Get number of pages. */
+ for_each_sg(sgt->sgl, s, sgt->orig_nents, i)
+ {
+ npages += (sg_dma_len(s) + PAGE_SIZE - 1) / PAGE_SIZE;
+ }
+
+ /* Allocate page array. */
+ gcmkONERROR(gckOS_Allocate(os, npages * gcmSIZEOF(*pagearray), (gctPOINTER *)&pagearray));
+
+ /* Fill page array. */
+ for_each_sg(sgt->sgl, s, sgt->orig_nents, i)
+ {
+ for (j = 0; j < (sg_dma_len(s) + PAGE_SIZE - 1) / PAGE_SIZE; j++)
+ {
+ pagearray[k++] = sg_dma_address(s) + j * PAGE_SIZE;
+ }
+ }
+
+ /* Prepare descriptor. */
+ gcmkONERROR(gckOS_Allocate(os, sizeof(gcsDMABUF), (gctPOINTER *)&buf_desc));
+
+ buf_desc->dmabuf = dmabuf;
+ buf_desc->pagearray = pagearray;
+ buf_desc->attachment = attachment;
+ buf_desc->sgt = sgt;
+
+ /* Record in buffer list to support debugfs. */
+ buf_desc->npages = npages;
+ buf_desc->pid = _GetProcessID();
+
+ mutex_lock(&priv->lock);
+ list_add(&buf_desc->list, &priv->buf_list);
+ mutex_unlock(&priv->lock);
+
+ /* Record page number. */
+ Mdl->numPages = npages;
+
+ Mdl->priv = buf_desc;
+
+ Mdl->contiguous = (sgt->nents == 1) ? gcvTRUE : gcvFALSE;
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ if (pagearray)
+ {
+ gcmkOS_SAFE_FREE(os, pagearray);
+ }
+
+ if (sgt)
+ {
+ dma_buf_unmap_attachment(attachment, sgt, DMA_BIDIRECTIONAL);
+ }
+
+ gcmkFOOTER();
+ return status;
+}
+
+
+static void
+_DmabufFree(
+ IN gckALLOCATOR Allocator,
+ IN PLINUX_MDL Mdl
+ )
+{
+ gcsDMABUF *buf_desc = Mdl->priv;
+ gckOS os = Allocator->os;
+ struct allocator_priv *priv = Allocator->privateData;
+
+ mutex_lock(&priv->lock);
+ list_del(&buf_desc->list);
+ mutex_unlock(&priv->lock);
+
+ dma_buf_unmap_attachment(buf_desc->attachment, buf_desc->sgt, DMA_BIDIRECTIONAL);
+
+ dma_buf_detach(buf_desc->dmabuf, buf_desc->attachment);
+
+ dma_buf_put(buf_desc->dmabuf);
+
+ gckOS_Free(os, buf_desc->pagearray);
+
+ gckOS_Free(os, buf_desc);
+}
+
+static void
+_DmabufUnmapUser(
+ IN gckALLOCATOR Allocator,
+ IN PLINUX_MDL Mdl,
+ IN PLINUX_MDL_MAP MdlMap,
+ IN gctUINT32 Size
+ )
+{
+ gcsDMABUF *buf_desc = Mdl->priv;
+ gctINT8_PTR userLogical = MdlMap->vmaAddr;
+
+ if (unlikely(current->mm == gcvNULL))
+ {
+ /* Do nothing if process is exiting. */
+ return;
+ }
+
+ userLogical -= buf_desc->sgt->sgl->offset;
+ vm_munmap((unsigned long)userLogical, Mdl->numPages << PAGE_SHIFT);
+}
+
+static gceSTATUS
+_DmabufMapUser(
+ IN gckALLOCATOR Allocator,
+ IN PLINUX_MDL Mdl,
+ IN PLINUX_MDL_MAP MdlMap,
+ IN gctBOOL Cacheable
+ )
+{
+ gcsDMABUF *buf_desc = Mdl->priv;
+ gctINT8_PTR userLogical = gcvNULL;
+ gceSTATUS status = gcvSTATUS_OK;
+
+ userLogical = (gctINT8_PTR)vm_mmap(buf_desc->dmabuf->file,
+ 0L,
+ Mdl->numPages << PAGE_SHIFT,
+ PROT_READ | PROT_WRITE,
+ MAP_SHARED | MAP_NORESERVE,
+ 0);
+
+ if (IS_ERR(userLogical))
+ {
+ gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
+ }
+ userLogical += buf_desc->sgt->sgl->offset;
+
+ /* To make sure the mapping is created. */
+ if (access_ok(VERIFY_READ, userLogical, 4))
+ {
+ uint32_t mem;
+ get_user(mem, (uint32_t *)userLogical);
+
+ (void)mem;
+ }
+
+ MdlMap->vmaAddr = (gctPOINTER)userLogical;
+ MdlMap->cacheable = Cacheable;
+
+OnError:
+ if (gcmIS_ERROR(status) && userLogical)
+ {
+ _DmabufUnmapUser(Allocator, Mdl, MdlMap, Mdl->numPages << PAGE_SHIFT);
+ }
+ return status;
+}
+
+static gceSTATUS
+_DmabufMapKernel(
+ IN gckALLOCATOR Allocator,
+ IN PLINUX_MDL Mdl,
+ OUT gctPOINTER *Logical
+ )
+{
+ /* Kernel doesn't acess video memory. */
+ return gcvSTATUS_NOT_SUPPORTED;
+
+}
+
+static gceSTATUS
+_DmabufUnmapKernel(
+ IN gckALLOCATOR Allocator,
+ IN PLINUX_MDL Mdl,
+ IN gctPOINTER Logical
+ )
+{
+ /* Kernel doesn't acess video memory. */
+ return gcvSTATUS_NOT_SUPPORTED;
+}
+
+static gceSTATUS
+_DmabufCache(
+ IN gckALLOCATOR Allocator,
+ IN PLINUX_MDL Mdl,
+ IN gctSIZE_T Offset,
+ IN gctPOINTER Logical,
+ IN gctUINT32 Bytes,
+ IN gceCACHEOPERATION Operation
+ )
+{
+ gcsDMABUF *buf_desc = Mdl->priv;
+ struct sg_table *sgt = buf_desc->sgt;
+ enum dma_data_direction dir;
+
+ switch (Operation)
+ {
+ case gcvCACHE_CLEAN:
+ dir = DMA_TO_DEVICE;
+ dma_sync_sg_for_device(galcore_device, sgt->sgl, sgt->nents, dir);
+ break;
+ case gcvCACHE_FLUSH:
+ dir = DMA_TO_DEVICE;
+ dma_sync_sg_for_device(galcore_device, sgt->sgl, sgt->nents, dir);
+ dir = DMA_FROM_DEVICE;
+ dma_sync_sg_for_cpu(galcore_device, sgt->sgl, sgt->nents, dir);
+ break;
+ case gcvCACHE_INVALIDATE:
+ dir = DMA_FROM_DEVICE;
+ dma_sync_sg_for_cpu(galcore_device, sgt->sgl, sgt->nents, dir);
+ break;
+ default:
+ return gcvSTATUS_INVALID_ARGUMENT;
+ }
+
+ return gcvSTATUS_OK;
+}
+
+
+static gceSTATUS
+_DmabufPhysical(
+ IN gckALLOCATOR Allocator,
+ IN PLINUX_MDL Mdl,
+ IN gctUINT32 Offset,
+ OUT gctPHYS_ADDR_T * Physical
+ )
+{
+ gcsDMABUF *buf_desc = Mdl->priv;
+ gctUINT32 offsetInPage = Offset & ~PAGE_MASK;
+ gctUINT32 index = Offset / PAGE_SIZE;
+
+ *Physical = buf_desc->pagearray[index] + offsetInPage;
+
+
+ return gcvSTATUS_OK;
+}
+
+/* Default allocator operations. */
+static gcsALLOCATOR_OPERATIONS DmabufAllocatorOperations =
+{
+ .Attach = _DmabufAttach,
+ .Free = _DmabufFree,
+ .MapUser = _DmabufMapUser,
+ .UnmapUser = _DmabufUnmapUser,
+ .MapKernel = _DmabufMapKernel,
+ .UnmapKernel = _DmabufUnmapKernel,
+ .Cache = _DmabufCache,
+ .Physical = _DmabufPhysical,
+};
+
+static void
+_DmabufAllocatorDestructor(
+ gcsALLOCATOR *Allocator
+ )
+{
+ _DebugfsCleanup(Allocator);
+
+ if (Allocator->privateData)
+ {
+ kfree(Allocator->privateData);
+ }
+
+ kfree(Allocator);
+}
+
+/* Default allocator entry. */
+gceSTATUS
+_DmabufAlloctorInit(
+ IN gckOS Os,
+ IN gcsDEBUGFS_DIR *Parent,
+ OUT gckALLOCATOR * Allocator
+ )
+{
+ gceSTATUS status;
+ gckALLOCATOR allocator;
+ struct allocator_priv *priv = NULL;
+
+ priv = kmalloc(sizeof (struct allocator_priv), GFP_KERNEL | gcdNOWARN);
+
+ if (!priv)
+ {
+ gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
+ }
+
+ mutex_init(&priv->lock);
+ INIT_LIST_HEAD(&priv->buf_list);
+
+ gcmkONERROR(
+ gckALLOCATOR_Construct(Os, &DmabufAllocatorOperations, &allocator));
+
+ allocator->capability = gcvALLOC_FLAG_DMABUF
+ | gcvALLOC_FLAG_DMABUF_EXPORTABLE
+ ;
+
+ /* Register private data. */
+ allocator->privateData = priv;
+ allocator->destructor = _DmabufAllocatorDestructor;
+
+ _DebugfsInit(allocator, Parent);
+
+ *Allocator = allocator;
+
+ return gcvSTATUS_OK;
+
+OnError:
+ if (priv)
+ {
+ kfree(priv);
+ }
+
+ return status;
+}
+
diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/allocator/default/gc_hal_kernel_allocator_gfp.c b/drivers/mxc/gpu-viv/hal/os/linux/kernel/allocator/default/gc_hal_kernel_allocator_gfp.c
new file mode 100644
index 000000000000..d678990998a3
--- /dev/null
+++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/allocator/default/gc_hal_kernel_allocator_gfp.c
@@ -0,0 +1,1153 @@
+/****************************************************************************
+*
+* The MIT License (MIT)
+*
+* Copyright (c) 2014 - 2018 Vivante 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 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 GPL License (GPL)
+*
+* Copyright (C) 2014 - 2018 Vivante 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.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+*****************************************************************************
+*
+* Note: This software is released under dual MIT and GPL licenses. A
+* recipient may use this file under the terms of either the MIT license or
+* GPL License. If you wish to use only one license not the other, you can
+* indicate your decision by deleting one of the above license notices in your
+* version of this file.
+*
+*****************************************************************************/
+
+
+#include "gc_hal_kernel_linux.h"
+#include "gc_hal_kernel_allocator.h"
+#include <linux/pagemap.h>
+#include <linux/seq_file.h>
+#include <linux/mman.h>
+#include <asm/atomic.h>
+#include <linux/dma-mapping.h>
+#include <linux/slab.h>
+
+#include "gc_hal_kernel_platform.h"
+
+#define _GC_OBJ_ZONE gcvZONE_OS
+
+#define gcdDISCRETE_PAGES 0
+
+struct gfp_alloc
+{
+ atomic_t low;
+ atomic_t high;
+};
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION (2,6,24)
+struct sg_table
+{
+ struct scatterlist *sgl;
+ unsigned int nents;
+ unsigned int orig_nents;
+};
+#endif
+
+struct gfp_mdl_priv
+{
+ int contiguous;
+
+ union
+ {
+ /* Pointer to a array of pages. */
+ struct
+ {
+ struct page *contiguousPages;
+ dma_addr_t dma_addr;
+ int exact;
+ };
+
+ struct
+ {
+ /* Pointer to a array of pointers to page. */
+ struct page **nonContiguousPages;
+ struct sg_table sgt;
+ };
+ };
+
+ gcsPLATFORM * platform;
+};
+
+/******************************************************************************\
+************************** GFP Allocator Debugfs ***************************
+\******************************************************************************/
+
+static int gc_usage_show(struct seq_file* m, void* data)
+{
+ gcsINFO_NODE *node = m->private;
+ gckALLOCATOR Allocator = node->device;
+ struct gfp_alloc *priv = Allocator->privateData;
+ long long low = (long long)atomic_read(&priv->low);
+ long long high = (long long)atomic_read(&priv->high);
+
+ seq_printf(m, "type n pages bytes\n");
+ seq_printf(m, "normal %10llu %12llu\n", low, low * PAGE_SIZE);
+ seq_printf(m, "HighMem %10llu %12llu\n", high, high * PAGE_SIZE);
+
+ return 0;
+}
+
+static gcsINFO InfoList[] =
+{
+ {"usage", gc_usage_show},
+};
+
+static void
+_GFPAllocatorDebugfsInit(
+ IN gckALLOCATOR Allocator,
+ IN gckDEBUGFS_DIR Root
+ )
+{
+ gcmkVERIFY_OK(
+ gckDEBUGFS_DIR_Init(&Allocator->debugfsDir, Root->root, "gfp"));
+
+ gcmkVERIFY_OK(gckDEBUGFS_DIR_CreateFiles(
+ &Allocator->debugfsDir,
+ InfoList,
+ gcmCOUNTOF(InfoList),
+ Allocator
+ ));
+}
+
+static void
+_GFPAllocatorDebugfsCleanup(
+ IN gckALLOCATOR Allocator
+ )
+{
+ gcmkVERIFY_OK(gckDEBUGFS_DIR_RemoveFiles(
+ &Allocator->debugfsDir,
+ InfoList,
+ gcmCOUNTOF(InfoList)
+ ));
+
+ gckDEBUGFS_DIR_Deinit(&Allocator->debugfsDir);
+}
+
+static void
+_NonContiguousFree(
+ IN struct page ** Pages,
+ IN gctUINT32 NumPages
+ )
+{
+ gctINT i;
+
+ gcmkHEADER_ARG("Pages=%p, NumPages=%u", Pages, NumPages);
+
+ gcmkASSERT(Pages != gcvNULL);
+
+ for (i = 0; i < NumPages; i++)
+ {
+ __free_page(Pages[i]);
+ }
+
+ if (is_vmalloc_addr(Pages))
+ {
+ vfree(Pages);
+ }
+ else
+ {
+ kfree(Pages);
+ }
+
+ gcmkFOOTER_NO();
+}
+
+static struct page **
+_NonContiguousAlloc(
+ IN gctUINT32 NumPages,
+ IN gctUINT32 Gfp
+ )
+{
+ struct page ** pages;
+ struct page *p;
+ gctINT i, size;
+
+ gcmkHEADER_ARG("NumPages=%u", NumPages);
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 32)
+ if (NumPages > totalram_pages)
+#else
+ if (NumPages > num_physpages)
+#endif
+ {
+ gcmkFOOTER_NO();
+ return gcvNULL;
+ }
+
+ size = NumPages * sizeof(struct page *);
+
+ pages = kmalloc(size, GFP_KERNEL | gcdNOWARN);
+
+ if (!pages)
+ {
+ pages = vmalloc(size);
+
+ if (!pages)
+ {
+ gcmkFOOTER_NO();
+ return gcvNULL;
+ }
+ }
+
+ for (i = 0; i < NumPages; i++)
+ {
+ p = alloc_page(Gfp);
+
+ if (!p)
+ {
+ _NonContiguousFree(pages, i);
+ gcmkFOOTER_NO();
+ return gcvNULL;
+ }
+
+#if gcdDISCRETE_PAGES
+ if (i != 0)
+ {
+ if (page_to_pfn(pages[i-1]) == page_to_pfn(p)-1)
+ {
+ /* Replaced page. */
+ struct page *l = p;
+
+ /* Allocate a page which is not contiguous to previous one. */
+ p = alloc_page(Gfp);
+
+ /* Give replaced page back. */
+ __free_page(l);
+
+ if (!p)
+ {
+ _NonContiguousFree(pages, i);
+ gcmkFOOTER_NO();
+ return gcvNULL;
+ }
+ }
+ }
+#endif
+
+ pages[i] = p;
+ }
+
+ gcmkFOOTER_ARG("pages=0x%X", pages);
+ return pages;
+}
+
+/***************************************************************************\
+************************ GFP Allocator **********************************
+\***************************************************************************/
+static gceSTATUS
+_GFPAlloc(
+ IN gckALLOCATOR Allocator,
+ INOUT PLINUX_MDL Mdl,
+ IN gctSIZE_T NumPages,
+ IN gctUINT32 Flags
+ )
+{
+ gceSTATUS status;
+ gctUINT i;
+ gctBOOL contiguous = Flags & gcvALLOC_FLAG_CONTIGUOUS;
+ u32 gfp = (contiguous ? (__GFP_HIGH | __GFP_ATOMIC) : GFP_KERNEL) | __GFP_HIGHMEM | gcdNOWARN;
+
+ struct gfp_alloc *priv = (struct gfp_alloc *)Allocator->privateData;
+ struct gfp_mdl_priv *mdlPriv = gcvNULL;
+ int result;
+ int low = 0;
+ int high = 0;
+
+ gcmkHEADER_ARG("Allocator=%p Mdl=%p NumPages=%zu Flags=0x%x", Allocator, Mdl, NumPages, Flags);
+
+#ifdef gcdSYS_FREE_MEMORY_LIMIT
+ if (Flags & gcvALLOC_FLAG_MEMLIMIT)
+ {
+ struct sysinfo temsysinfo;
+ si_meminfo(&temsysinfo);
+
+ if ((temsysinfo.freeram < NumPages) || ((temsysinfo.freeram-NumPages) < gcdSYS_FREE_MEMORY_LIMIT))
+ {
+ gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
+ }
+ }
+#endif
+
+ mdlPriv = kzalloc(sizeof(struct gfp_mdl_priv), GFP_KERNEL | __GFP_NORETRY);
+
+ if (!mdlPriv)
+ {
+ gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
+ }
+
+#if defined(CONFIG_ZONE_DMA32) && LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)
+ if ((Flags & gcvALLOC_FLAG_4GB_ADDR) || (Allocator->os->device->platform->flagBits & gcvPLATFORM_FLAG_LIMIT_4G_ADDRESS))
+ {
+ /* remove __GFP_HIGHMEM bit, add __GFP_DMA32 bit */
+ gfp &= ~__GFP_HIGHMEM;
+ gfp |= __GFP_DMA32;
+ }
+#else
+ if (Flags & gcvALLOC_FLAG_4GB_ADDR || (Allocator->os->device->platform->flagBits & gcvPLATFORM_FLAG_LIMIT_4G_ADDRESS))
+ {
+ /* remove __GFP_HIGHMEM bit, add __GFP_DMA bit */
+ gfp &= ~__GFP_HIGHMEM;
+ gfp |= __GFP_DMA;
+ }
+
+#endif
+
+ if (contiguous)
+ {
+ size_t bytes = NumPages << PAGE_SHIFT;
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)
+ void *addr = NULL;
+
+ addr = alloc_pages_exact(bytes, (gfp & ~__GFP_HIGHMEM) | __GFP_NORETRY);
+
+ mdlPriv->contiguousPages = addr ? virt_to_page(addr) : gcvNULL;
+
+ if (mdlPriv->contiguousPages)
+ {
+ mdlPriv->exact = gcvTRUE;
+ }
+#endif
+
+ if (mdlPriv->contiguousPages == gcvNULL)
+ {
+ int order = get_order(bytes);
+
+ if (order >= MAX_ORDER)
+ {
+ status = gcvSTATUS_OUT_OF_MEMORY;
+ goto OnError;
+ }
+
+ mdlPriv->contiguousPages = alloc_pages(gfp, order);
+
+ }
+
+ if (mdlPriv->contiguousPages == gcvNULL)
+ {
+ gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
+ }
+
+ mdlPriv->dma_addr = dma_map_page(galcore_device,
+ mdlPriv->contiguousPages, 0, NumPages * PAGE_SIZE,
+ DMA_FROM_DEVICE);
+
+ if (!mdlPriv->dma_addr)
+ {
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)
+ if (mdlPriv->exact)
+ {
+ free_pages_exact(page_address(mdlPriv->contiguousPages), bytes);
+ }
+ else
+#endif
+ {
+ __free_pages(mdlPriv->contiguousPages, get_order(bytes));
+ }
+
+ gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
+ }
+
+#if defined(CONFIG_X86)
+ if (!PageHighMem(mdlPriv->contiguousPages))
+ {
+ if (set_memory_wc((unsigned long)page_address(mdlPriv->contiguousPages), NumPages) != 0)
+ {
+ printk("%s(%d): failed to set_memory_wc\n", __func__, __LINE__);
+ }
+ }
+#endif
+ }
+ else
+ {
+ mdlPriv->nonContiguousPages = _NonContiguousAlloc(NumPages, gfp);
+
+ if (mdlPriv->nonContiguousPages == gcvNULL)
+ {
+ gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
+ }
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION (3,6,0) \
+ && (defined(ARCH_HAS_SG_CHAIN) || defined(CONFIG_ARCH_HAS_SG_CHAIN))
+ result = sg_alloc_table_from_pages(&mdlPriv->sgt,
+ mdlPriv->nonContiguousPages, NumPages, 0,
+ NumPages << PAGE_SHIFT, GFP_KERNEL);
+
+#else
+ result = alloc_sg_list_from_pages(&mdlPriv->sgt.sgl,
+ mdlPriv->nonContiguousPages, NumPages, 0,
+ NumPages << PAGE_SHIFT, &mdlPriv->sgt.nents);
+
+ mdlPriv->sgt.orig_nents = mdlPriv->sgt.nents;
+#endif
+ if (result < 0)
+ {
+ _NonContiguousFree(mdlPriv->nonContiguousPages, NumPages);
+ gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
+ }
+
+ result = dma_map_sg(galcore_device,
+ mdlPriv->sgt.sgl, mdlPriv->sgt.nents, DMA_FROM_DEVICE);
+
+ if (result != mdlPriv->sgt.nents)
+ {
+ _NonContiguousFree(mdlPriv->nonContiguousPages, NumPages);
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION (3,6,0) \
+ && (defined (ARCH_HAS_SG_CHAIN) || defined (CONFIG_ARCH_HAS_SG_CHAIN))
+ sg_free_table(&mdlPriv->sgt);
+#else
+ kfree(mdlPriv->sgt.sgl);
+#endif
+ gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
+ }
+
+#if defined(CONFIG_X86)
+ if (set_pages_array_wc(mdlPriv->nonContiguousPages, NumPages))
+ {
+ printk("%s(%d): failed to set_pages_array_wc\n", __func__, __LINE__);
+ }
+#endif
+ }
+
+ for (i = 0; i < NumPages; i++)
+ {
+ struct page *page;
+ gctPHYS_ADDR_T phys = 0U;
+
+ if (contiguous)
+ {
+ page = nth_page(mdlPriv->contiguousPages, i);
+ }
+ else
+ {
+ page = mdlPriv->nonContiguousPages[i];
+ }
+
+ SetPageReserved(page);
+
+ phys = page_to_phys(page);
+
+ BUG_ON(!phys);
+
+ if (PageHighMem(page))
+ {
+ high++;
+ }
+ else
+ {
+ low++;
+ }
+ }
+
+ mdlPriv->platform = Allocator->os->device->platform;
+ mdlPriv->contiguous = contiguous;
+ atomic_add(low, &priv->low);
+ atomic_add(high, &priv->high);
+
+ Mdl->priv = mdlPriv;
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ if (mdlPriv)
+ {
+ kfree(mdlPriv);
+ }
+
+ gcmkFOOTER();
+ return status;
+}
+
+static gceSTATUS
+_GFPGetSGT(
+ IN gckALLOCATOR Allocator,
+ IN PLINUX_MDL Mdl,
+ IN gctSIZE_T Offset,
+ IN gctSIZE_T Bytes,
+ OUT gctPOINTER *SGT
+ )
+{
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)
+ struct page ** pages = gcvNULL;
+ struct page ** tmpPages = gcvNULL;
+ struct sg_table *sgt = NULL;
+ struct gfp_mdl_priv *mdlPriv = (struct gfp_mdl_priv*)Mdl->priv;
+
+ gceSTATUS status = gcvSTATUS_OK;
+ gctSIZE_T offset = Offset & ~PAGE_MASK; /* Offset to the first page */
+ gctINT skipPages = Offset >> PAGE_SHIFT; /* skipped pages */
+ gctINT numPages = (PAGE_ALIGN(Offset + Bytes) >> PAGE_SHIFT) - skipPages;
+ gctINT i;
+
+ gcmkASSERT(Offset + Bytes <= Mdl->numPages << PAGE_SHIFT);
+
+ if (Mdl->contiguous)
+ {
+ pages = tmpPages = kmalloc(sizeof(struct page*) * numPages, GFP_KERNEL | gcdNOWARN);
+ if (!pages)
+ {
+ gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
+ }
+
+ for (i = 0; i < numPages; ++i)
+ {
+ pages[i] = nth_page(mdlPriv->contiguousPages, i + skipPages);
+ }
+ }
+ else
+ {
+ pages = &mdlPriv->nonContiguousPages[skipPages];
+ }
+
+ sgt = kmalloc(sizeof(struct sg_table), GFP_KERNEL | gcdNOWARN);
+ if (!sgt)
+ {
+ gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
+ }
+
+ if (sg_alloc_table_from_pages(sgt, pages, numPages, offset, Bytes, GFP_KERNEL) < 0)
+ {
+ gcmkONERROR(gcvSTATUS_GENERIC_IO);
+ }
+
+ *SGT = (gctPOINTER)sgt;
+
+OnError:
+ if (tmpPages)
+ {
+ kfree(tmpPages);
+ }
+
+ if (gcmIS_ERROR(status) && sgt)
+ {
+ kfree(sgt);
+ }
+
+ return status;
+#else
+ return gcvSTATUS_NOT_SUPPORTED;
+#endif
+}
+
+static void
+_GFPFree(
+ IN gckALLOCATOR Allocator,
+ IN OUT PLINUX_MDL Mdl
+ )
+{
+ gctINT i;
+ struct page * page;
+ struct gfp_alloc *priv = (struct gfp_alloc *)Allocator->privateData;
+ struct gfp_mdl_priv *mdlPriv = Mdl->priv;
+ int low = 0;
+ int high = 0;
+
+ if (Mdl->contiguous)
+ {
+ dma_unmap_page(galcore_device, mdlPriv->dma_addr,
+ Mdl->numPages << PAGE_SHIFT, DMA_TO_DEVICE);
+ }
+ else
+ {
+ dma_unmap_sg(galcore_device, mdlPriv->sgt.sgl, mdlPriv->sgt.nents,
+ DMA_TO_DEVICE);
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION (3,6,0) \
+ && (defined (ARCH_HAS_SG_CHAIN) || defined (CONFIG_ARCH_HAS_SG_CHAIN))
+ sg_free_table(&mdlPriv->sgt);
+#else
+ kfree(mdlPriv->sgt.sgl);
+#endif
+ }
+
+ for (i = 0; i < Mdl->numPages; i++)
+ {
+ if (Mdl->contiguous)
+ {
+ page = nth_page(mdlPriv->contiguousPages, i);
+ }
+ else
+ {
+ page = mdlPriv->nonContiguousPages[i];
+ }
+
+ ClearPageReserved(page);
+
+ if (PageHighMem(page))
+ {
+ high++;
+ }
+ else
+ {
+ low++;
+ }
+ }
+
+ atomic_sub(low, &priv->low);
+ atomic_sub(high, &priv->high);
+
+ if (Mdl->contiguous)
+ {
+#if defined(CONFIG_X86)
+ if (!PageHighMem(mdlPriv->contiguousPages))
+ {
+ set_memory_wb((unsigned long)page_address(mdlPriv->contiguousPages), Mdl->numPages);
+ }
+#endif
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)
+ if (mdlPriv->exact == gcvTRUE)
+ {
+ free_pages_exact(page_address(mdlPriv->contiguousPages), Mdl->numPages * PAGE_SIZE);
+ }
+ else
+#endif
+ {
+ __free_pages(mdlPriv->contiguousPages, get_order(Mdl->numPages * PAGE_SIZE));
+ }
+ }
+ else
+ {
+#if defined(CONFIG_X86)
+ set_pages_array_wb(mdlPriv->nonContiguousPages, Mdl->numPages);
+#endif
+
+ _NonContiguousFree(mdlPriv->nonContiguousPages, Mdl->numPages);
+ }
+
+ kfree(Mdl->priv);
+}
+
+static gceSTATUS
+_GFPMmap(
+ IN gckALLOCATOR Allocator,
+ IN PLINUX_MDL Mdl,
+ IN gctBOOL Cacheable,
+ IN gctSIZE_T skipPages,
+ IN gctSIZE_T numPages,
+ IN struct vm_area_struct *vma
+ )
+{
+ struct gfp_mdl_priv *mdlPriv = (struct gfp_mdl_priv*)Mdl->priv;
+ gcsPLATFORM *platform = mdlPriv->platform;
+ gceSTATUS status = gcvSTATUS_OK;
+
+ gcmkHEADER_ARG("Allocator=%p Mdl=%p vma=%p", Allocator, Mdl, vma);
+
+ vma->vm_flags |= gcdVM_FLAGS;
+
+ if (Cacheable == gcvFALSE)
+ {
+ /* Make this mapping non-cached. */
+#if gcdENABLE_BUFFERABLE_VIDEO_MEMORY
+ vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
+#else
+ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+#endif
+ }
+
+ if (platform && platform->ops->adjustProt)
+ {
+ platform->ops->adjustProt(vma);
+ }
+
+ gcmkASSERT(skipPages + numPages <= Mdl->numPages);
+
+ /* Now map all the vmalloc pages to this user address. */
+ if (mdlPriv->contiguous)
+ {
+ /* map kernel memory to user space.. */
+ if (remap_pfn_range(vma,
+ vma->vm_start,
+ page_to_pfn(mdlPriv->contiguousPages) + skipPages,
+ numPages << PAGE_SHIFT,
+ vma->vm_page_prot) < 0)
+ {
+ gcmkTRACE_ZONE(
+ gcvLEVEL_INFO, gcvZONE_OS,
+ "%s(%d): remap_pfn_range error.",
+ __FUNCTION__, __LINE__
+ );
+
+ gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
+ }
+ }
+ else
+ {
+ gctUINT i;
+ unsigned long start = vma->vm_start;
+
+ for (i = 0; i < numPages; ++i)
+ {
+ unsigned long pfn = page_to_pfn(mdlPriv->nonContiguousPages[i + skipPages]);
+
+ if (remap_pfn_range(vma,
+ start,
+ pfn,
+ PAGE_SIZE,
+ vma->vm_page_prot) < 0)
+ {
+ gcmkTRACE(
+ gcvLEVEL_ERROR,
+ "%s(%d): remap_pfn_range error.",
+ __FUNCTION__, __LINE__
+ );
+
+ gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
+ }
+
+ start += PAGE_SIZE;
+ }
+ }
+
+OnError:
+ gcmkFOOTER();
+ return status;
+}
+
+static void
+_GFPUnmapUser(
+ IN gckALLOCATOR Allocator,
+ IN PLINUX_MDL Mdl,
+ IN PLINUX_MDL_MAP MdlMap,
+ IN gctUINT32 Size
+ )
+{
+ MdlMap->cacheable = gcvFALSE;
+
+ if (unlikely(current->mm == gcvNULL))
+ {
+ /* Do nothing if process is exiting. */
+ return;
+ }
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0)
+ if (vm_munmap((unsigned long)MdlMap->vmaAddr, Size) < 0)
+ {
+ gcmkTRACE_ZONE(
+ gcvLEVEL_WARNING, gcvZONE_OS,
+ "%s(%d): vm_munmap failed",
+ __FUNCTION__, __LINE__
+ );
+ }
+#else
+ down_write(&current->mm->mmap_sem);
+ if (do_munmap(current->mm, (unsigned long)MdlMap->vmaAddr, Size) < 0)
+ {
+ gcmkTRACE_ZONE(
+ gcvLEVEL_WARNING, gcvZONE_OS,
+ "%s(%d): do_munmap failed",
+ __FUNCTION__, __LINE__
+ );
+ }
+ up_write(&current->mm->mmap_sem);
+#endif
+
+ MdlMap->vma = NULL;
+}
+
+static gceSTATUS
+_GFPMapUser(
+ gckALLOCATOR Allocator,
+ PLINUX_MDL Mdl,
+ PLINUX_MDL_MAP MdlMap,
+ gctBOOL Cacheable
+ )
+{
+ gctPOINTER userLogical = gcvNULL;
+ gceSTATUS status = gcvSTATUS_OK;
+
+ gcmkHEADER_ARG("Allocator=%p Mdl=%p Cacheable=%d", Allocator, Mdl, Cacheable);
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0)
+ userLogical = (gctPOINTER)vm_mmap(NULL,
+ 0L,
+ Mdl->numPages * PAGE_SIZE,
+ PROT_READ | PROT_WRITE,
+ MAP_SHARED | MAP_NORESERVE,
+ 0);
+#else
+ down_write(&current->mm->mmap_sem);
+ userLogical = (gctPOINTER)do_mmap_pgoff(NULL,
+ 0L,
+ Mdl->numPages * PAGE_SIZE,
+ PROT_READ | PROT_WRITE,
+ MAP_SHARED,
+ 0);
+ up_write(&current->mm->mmap_sem);
+#endif
+
+ gcmkTRACE_ZONE(
+ gcvLEVEL_INFO, gcvZONE_OS,
+ "%s(%d): vmaAddr->%p for phys_addr->%p",
+ __FUNCTION__, __LINE__,
+ userLogical,
+ Mdl
+ );
+
+ if (IS_ERR(userLogical))
+ {
+ gcmkTRACE_ZONE(
+ gcvLEVEL_INFO, gcvZONE_OS,
+ "%s(%d): do_mmap_pgoff error",
+ __FUNCTION__, __LINE__
+ );
+
+ userLogical = gcvNULL;
+
+ gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
+ }
+
+ down_write(&current->mm->mmap_sem);
+ do
+ {
+ struct vm_area_struct *vma = find_vma(current->mm, (unsigned long)userLogical);
+
+ if (vma == gcvNULL)
+ {
+ gcmkTRACE_ZONE(
+ gcvLEVEL_INFO, gcvZONE_OS,
+ "%s(%d): find_vma error",
+ __FUNCTION__, __LINE__
+ );
+
+ gcmkERR_BREAK(gcvSTATUS_OUT_OF_RESOURCES);
+ }
+
+ gcmkERR_BREAK(_GFPMmap(Allocator, Mdl, Cacheable, 0, Mdl->numPages, vma));
+ MdlMap->vma = vma;
+ }
+ while (gcvFALSE);
+ up_write(&current->mm->mmap_sem);
+
+ if (gcmIS_SUCCESS(status))
+ {
+ MdlMap->vmaAddr = userLogical;
+ MdlMap->cacheable = Cacheable;
+ }
+
+OnError:
+ if (gcmIS_ERROR(status) && userLogical)
+ {
+ _GFPUnmapUser(Allocator, Mdl, userLogical, Mdl->numPages * PAGE_SIZE);
+ }
+ gcmkFOOTER();
+ return status;
+}
+
+static gceSTATUS
+_GFPMapKernel(
+ IN gckALLOCATOR Allocator,
+ IN PLINUX_MDL Mdl,
+ OUT gctPOINTER *Logical
+ )
+{
+ void *addr = 0;
+ gctINT numPages = Mdl->numPages;
+ struct gfp_mdl_priv *mdlPriv = Mdl->priv;
+
+ struct page ** pages;
+ gctBOOL free = gcvFALSE;
+ pgprot_t pgprot;
+ gctINT i;
+
+ if (Mdl->contiguous)
+ {
+ pages = kmalloc(sizeof(struct page *) * numPages, GFP_KERNEL | gcdNOWARN);
+
+ if (!pages)
+ {
+ return gcvSTATUS_OUT_OF_MEMORY;
+ }
+
+ for (i = 0; i < numPages; i++)
+ {
+ pages[i] = nth_page(mdlPriv->contiguousPages, i);
+ }
+
+ free = gcvTRUE;
+ }
+ else
+ {
+ pages = mdlPriv->nonContiguousPages;
+ }
+
+ /* ioremap() can't work on system memory since 2.6.38. */
+ if (Mdl->cacheable)
+ {
+ pgprot = PAGE_KERNEL;
+ }
+ else
+ {
+#if gcdENABLE_BUFFERABLE_VIDEO_MEMORY
+ pgprot = pgprot_writecombine(PAGE_KERNEL);
+#else
+ pgprot = pgprot_noncached(PAGE_KERNEL);
+#endif
+ }
+
+ addr = vmap(pages, numPages, 0, pgprot);
+
+ if (free)
+ {
+ kfree(pages);
+ }
+
+ if (addr)
+ {
+ *Logical = addr;
+ return gcvSTATUS_OK;
+ }
+ else
+ {
+ return gcvSTATUS_OUT_OF_MEMORY;
+ }
+}
+
+static gceSTATUS
+_GFPUnmapKernel(
+ IN gckALLOCATOR Allocator,
+ IN PLINUX_MDL Mdl,
+ IN gctPOINTER Logical
+ )
+{
+ vunmap(Logical);
+
+ return gcvSTATUS_OK;
+}
+
+static gceSTATUS
+_GFPCache(
+ IN gckALLOCATOR Allocator,
+ IN PLINUX_MDL Mdl,
+ IN gctSIZE_T Offset,
+ IN gctPOINTER Logical,
+ IN gctUINT32 Bytes,
+ IN gceCACHEOPERATION Operation
+ )
+{
+ struct gfp_mdl_priv *mdlPriv = Mdl->priv;
+ enum dma_data_direction dir;
+
+ switch (Operation)
+ {
+ case gcvCACHE_CLEAN:
+ dir = DMA_TO_DEVICE;
+
+ if (mdlPriv->contiguous)
+ {
+ dma_sync_single_for_device(galcore_device,
+ mdlPriv->dma_addr, Mdl->numPages << PAGE_SHIFT, dir);
+ }
+ else
+ {
+ dma_sync_sg_for_device(galcore_device,
+ mdlPriv->sgt.sgl, mdlPriv->sgt.nents, dir);
+ }
+
+ break;
+ case gcvCACHE_FLUSH:
+ dir = DMA_TO_DEVICE;
+
+ if (mdlPriv->contiguous)
+ {
+ dma_sync_single_for_device(galcore_device,
+ mdlPriv->dma_addr, Mdl->numPages << PAGE_SHIFT, dir);
+ }
+ else
+ {
+ dma_sync_sg_for_device(galcore_device,
+ mdlPriv->sgt.sgl, mdlPriv->sgt.nents, dir);
+ }
+
+ dir = DMA_FROM_DEVICE;
+
+ if (mdlPriv->contiguous)
+ {
+ dma_sync_single_for_cpu(galcore_device,
+ mdlPriv->dma_addr, Mdl->numPages << PAGE_SHIFT, dir);
+ }
+ else
+ {
+ dma_sync_sg_for_cpu(galcore_device,
+ mdlPriv->sgt.sgl, mdlPriv->sgt.nents, dir);
+ }
+
+ break;
+ case gcvCACHE_INVALIDATE:
+ dir = DMA_FROM_DEVICE;
+
+ if (mdlPriv->contiguous)
+ {
+ dma_sync_single_for_cpu(galcore_device,
+ mdlPriv->dma_addr, Mdl->numPages << PAGE_SHIFT, dir);
+ }
+ else
+ {
+ dma_sync_sg_for_cpu(galcore_device,
+ mdlPriv->sgt.sgl, mdlPriv->sgt.nents, dir);
+ }
+
+ break;
+ default:
+ return gcvSTATUS_INVALID_ARGUMENT;
+ }
+
+ return gcvSTATUS_OK;
+}
+
+static gceSTATUS
+_GFPPhysical(
+ IN gckALLOCATOR Allocator,
+ IN PLINUX_MDL Mdl,
+ IN gctUINT32 Offset,
+ OUT gctPHYS_ADDR_T * Physical
+ )
+{
+ struct gfp_mdl_priv *mdlPriv = Mdl->priv;
+ gctUINT32 offsetInPage = Offset & ~PAGE_MASK;
+ gctUINT32 index = Offset / PAGE_SIZE;
+
+ if (Mdl->contiguous)
+ {
+ *Physical = page_to_phys(nth_page(mdlPriv->contiguousPages, index));
+ }
+ else
+ {
+ *Physical = page_to_phys(mdlPriv->nonContiguousPages[index]);
+ }
+
+ *Physical += offsetInPage;
+
+ return gcvSTATUS_OK;
+}
+
+static void
+_GFPAllocatorDestructor(
+ gcsALLOCATOR *Allocator
+ )
+{
+ _GFPAllocatorDebugfsCleanup(Allocator);
+
+ if (Allocator->privateData)
+ {
+ kfree(Allocator->privateData);
+ }
+
+ kfree(Allocator);
+}
+
+/* GFP allocator operations. */
+static gcsALLOCATOR_OPERATIONS GFPAllocatorOperations = {
+ .Alloc = _GFPAlloc,
+ .Free = _GFPFree,
+ .Mmap = _GFPMmap,
+ .MapUser = _GFPMapUser,
+ .UnmapUser = _GFPUnmapUser,
+ .MapKernel = _GFPMapKernel,
+ .UnmapKernel = _GFPUnmapKernel,
+ .Cache = _GFPCache,
+ .Physical = _GFPPhysical,
+ .GetSGT = _GFPGetSGT,
+};
+
+/* GFP allocator entry. */
+gceSTATUS
+_GFPAlloctorInit(
+ IN gckOS Os,
+ IN gcsDEBUGFS_DIR *Parent,
+ OUT gckALLOCATOR * Allocator
+ )
+{
+ gceSTATUS status;
+ gckALLOCATOR allocator = gcvNULL;
+ struct gfp_alloc *priv = gcvNULL;
+
+ gcmkONERROR(
+ gckALLOCATOR_Construct(Os, &GFPAllocatorOperations, &allocator));
+
+ priv = kzalloc(sizeof(struct gfp_alloc), GFP_KERNEL | gcdNOWARN);
+
+ if (!priv)
+ {
+ gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
+ }
+
+ atomic_set(&priv->low, 0);
+ atomic_set(&priv->high, 0);
+
+ /* Register private data. */
+ allocator->privateData = priv;
+ allocator->destructor = _GFPAllocatorDestructor;
+
+ _GFPAllocatorDebugfsInit(allocator, Parent);
+
+ allocator->capability = gcvALLOC_FLAG_CONTIGUOUS
+ | gcvALLOC_FLAG_NON_CONTIGUOUS
+ | gcvALLOC_FLAG_CACHEABLE
+ | gcvALLOC_FLAG_MEMLIMIT
+ | gcvALLOC_FLAG_ALLOC_ON_FAULT
+ | gcvALLOC_FLAG_DMABUF_EXPORTABLE
+#if defined(CONFIG_ZONE_DMA32) && LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)
+ | gcvALLOC_FLAG_4GB_ADDR
+#endif
+ ;
+
+#if defined(gcdEMULATE_SECURE_ALLOCATOR)
+ allocator->capability |= gcvALLOC_FLAG_SECURITY;
+#endif
+
+ *Allocator = allocator;
+
+ return gcvSTATUS_OK;
+
+OnError:
+ if (allocator)
+ {
+ kfree(allocator);
+ }
+ return status;
+}
+
diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/allocator/default/gc_hal_kernel_allocator_reserved_mem.c b/drivers/mxc/gpu-viv/hal/os/linux/kernel/allocator/default/gc_hal_kernel_allocator_reserved_mem.c
new file mode 100644
index 000000000000..0b35e3dbac6d
--- /dev/null
+++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/allocator/default/gc_hal_kernel_allocator_reserved_mem.c
@@ -0,0 +1,511 @@
+/****************************************************************************
+*
+* The MIT License (MIT)
+*
+* Copyright (c) 2014 - 2018 Vivante 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 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 GPL License (GPL)
+*
+* Copyright (C) 2014 - 2018 Vivante 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.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+*****************************************************************************
+*
+* Note: This software is released under dual MIT and GPL licenses. A
+* recipient may use this file under the terms of either the MIT license or
+* GPL License. If you wish to use only one license not the other, you can
+* indicate your decision by deleting one of the above license notices in your
+* version of this file.
+*
+*****************************************************************************/
+
+
+#include "gc_hal_kernel_linux.h"
+#include "gc_hal_kernel_allocator.h"
+#include <linux/pagemap.h>
+#include <linux/seq_file.h>
+#include <linux/mman.h>
+#include <asm/atomic.h>
+#include <linux/dma-mapping.h>
+#include <linux/slab.h>
+#include <linux/io.h>
+#include <linux/ioport.h>
+
+#define _GC_OBJ_ZONE gcvZONE_OS
+
+/*
+ * reserved_mem is for contiguous pool, internal pool and external pool, etc.
+ */
+
+/* mdl private. */
+struct reserved_mem
+{
+ unsigned long start;
+ unsigned long size;
+ char name[32];
+ int release;
+
+ /* Link together. */
+ struct list_head link;
+};
+
+/* allocator info. */
+struct reserved_mem_alloc
+{
+ /* Record allocated reserved memory regions. */
+ struct list_head region;
+ struct mutex lock;
+};
+
+static int reserved_mem_show(struct seq_file* m, void* data)
+{
+ struct list_head *pos;
+ gcsINFO_NODE *node = m->private;
+ gckALLOCATOR Allocator = node->device;
+ struct reserved_mem_alloc *alloc = Allocator->privateData;
+
+ list_for_each(pos, &alloc->region)
+ {
+ struct reserved_mem * res= list_entry(pos, struct reserved_mem, link);
+
+ seq_printf(m, "0x%08lx-0x%08lx : %s\n",
+ res->start, res->start + res->size -1, res->name);
+ }
+
+ return 0;
+}
+
+static gcsINFO info_list[] =
+{
+ {"reserved-mem", reserved_mem_show},
+};
+
+static void
+reserved_mem_debugfs_init(
+ IN gckALLOCATOR Allocator,
+ IN gckDEBUGFS_DIR Root
+ )
+{
+ gcmkVERIFY_OK(
+ gckDEBUGFS_DIR_Init(&Allocator->debugfsDir, Root->root, "reserved-mem"));
+
+ gcmkVERIFY_OK(gckDEBUGFS_DIR_CreateFiles(
+ &Allocator->debugfsDir,
+ info_list,
+ gcmCOUNTOF(info_list),
+ Allocator
+ ));
+}
+
+static void
+reserved_mem_debugfs_cleanup(
+ IN gckALLOCATOR Allocator
+ )
+{
+ gcmkVERIFY_OK(gckDEBUGFS_DIR_RemoveFiles(
+ &Allocator->debugfsDir,
+ info_list,
+ gcmCOUNTOF(info_list)
+ ));
+
+ gckDEBUGFS_DIR_Deinit(&Allocator->debugfsDir);
+}
+
+static gceSTATUS
+reserved_mem_attach(
+ IN gckALLOCATOR Allocator,
+ IN gcsATTACH_DESC_PTR Desc,
+ IN PLINUX_MDL Mdl
+ )
+{
+ struct reserved_mem_alloc *alloc = Allocator->privateData;
+ struct reserved_mem *res;
+ struct resource *region = NULL;
+
+ res = kzalloc(sizeof(struct reserved_mem), GFP_KERNEL | gcdNOWARN);
+
+ if (!res)
+ return gcvSTATUS_OUT_OF_MEMORY;
+
+ res->start = Desc->reservedMem.start;
+ res->size = Desc->reservedMem.size;
+ strncpy(res->name, Desc->reservedMem.name, sizeof(res->name)-1);
+ res->release = 1;
+
+ if (!Desc->reservedMem.requested)
+ {
+ region = request_mem_region(res->start, res->size, res->name);
+
+ if (!region)
+ {
+ printk("request mem %s(0x%lx - 0x%lx) failed\n",
+ res->name, res->start, res->start + res->size - 1);
+
+ kfree(res);
+ return gcvSTATUS_OUT_OF_RESOURCES;
+ }
+
+ res->release = 1;
+ }
+
+ mutex_lock(&alloc->lock);
+ list_add(&res->link, &alloc->region);
+ mutex_unlock(&alloc->lock);
+
+ Mdl->priv = res;
+
+ return gcvSTATUS_OK;
+}
+
+static void
+reserved_mem_detach(
+ IN gckALLOCATOR Allocator,
+ IN OUT PLINUX_MDL Mdl
+ )
+{
+ struct reserved_mem_alloc *alloc = Allocator->privateData;
+ struct reserved_mem *res = Mdl->priv;
+
+ /* unlink from region list. */
+ mutex_lock(&alloc->lock);
+ list_del_init(&res->link);
+ mutex_unlock(&alloc->lock);
+
+ if (res->release)
+ {
+ release_mem_region(res->start, res->size);
+ }
+
+ kfree(res);
+}
+
+static gceSTATUS
+reserved_mem_mmap(
+ IN gckALLOCATOR Allocator,
+ IN PLINUX_MDL Mdl,
+ IN gctBOOL Cacheable,
+ IN gctSIZE_T skipPages,
+ IN gctSIZE_T numPages,
+ IN struct vm_area_struct *vma
+ )
+{
+ struct reserved_mem *res = (struct reserved_mem*)Mdl->priv;
+ unsigned long pfn;
+ gceSTATUS status = gcvSTATUS_OK;
+
+ gcmkHEADER_ARG("Allocator=%p Mdl=%p vma=%p", Allocator, Mdl, vma);
+
+ gcmkASSERT(skipPages + numPages <= Mdl->numPages);
+
+ pfn = (res->start >> PAGE_SHIFT) + skipPages;
+
+ /* Make this mapping non-cached. */
+ vma->vm_flags |= gcdVM_FLAGS;
+ vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
+
+ if (remap_pfn_range(vma, vma->vm_start,
+ pfn, numPages << PAGE_SHIFT, vma->vm_page_prot) < 0)
+ {
+ gcmkTRACE(
+ gcvLEVEL_ERROR,
+ "%s(%d): remap_pfn_range error.",
+ __FUNCTION__, __LINE__
+ );
+
+ status = gcvSTATUS_OUT_OF_MEMORY;
+ }
+
+ gcmkFOOTER();
+ return status;
+}
+
+static void
+reserved_mem_unmap_user(
+ IN gckALLOCATOR Allocator,
+ IN PLINUX_MDL Mdl,
+ IN PLINUX_MDL_MAP MdlMap,
+ IN gctUINT32 Size
+ )
+{
+ if (unlikely(!current->mm))
+ return;
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0)
+ if (vm_munmap((unsigned long)MdlMap->vmaAddr, (unsigned long)Size) < 0)
+ {
+ printk("%s: vm_munmap failed\n", __func__);
+ }
+#else
+ down_write(&current->mm->mmap_sem);
+ if (do_munmap(current->mm, (unsigned long)MdlMap->vmaAddr, (unsigned long)Size) < 0)
+ {
+ printk("%s: do_munmap failed\n", __func__);
+ }
+ up_write(&current->mm->mmap_sem);
+#endif
+}
+
+static gceSTATUS
+reserved_mem_map_user(
+ gckALLOCATOR Allocator,
+ PLINUX_MDL Mdl,
+ PLINUX_MDL_MAP MdlMap,
+ gctBOOL Cacheable
+ )
+{
+ struct reserved_mem *res = (struct reserved_mem*)Mdl->priv;
+ gctPOINTER userLogical = gcvNULL;
+ gceSTATUS status = gcvSTATUS_OK;
+
+ gcmkHEADER_ARG("Allocator=%p Mdl=%p Cacheable=%d", Allocator, Mdl, Cacheable);
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0)
+ userLogical = (gctPOINTER)vm_mmap(NULL, 0L, res->size,
+ PROT_READ | PROT_WRITE, MAP_SHARED | MAP_NORESERVE, 0);
+#else
+ down_write(&current->mm->mmap_sem);
+ userLogical = (gctPOINTER)do_mmap_pgoff(NULL, 0L, res->size,
+ PROT_READ | PROT_WRITE, MAP_SHARED, 0);
+ up_write(&current->mm->mmap_sem);
+#endif
+
+ gcmkTRACE_ZONE(
+ gcvLEVEL_INFO, gcvZONE_OS,
+ "%s(%d): vmaAddr->%p for phys_addr->%p",
+ __FUNCTION__, __LINE__, userLogical, Mdl
+ );
+
+ if (IS_ERR(userLogical))
+ {
+ gcmkTRACE_ZONE(
+ gcvLEVEL_INFO, gcvZONE_OS,
+ "%s(%d): do_mmap_pgoff error",
+ __FUNCTION__, __LINE__
+ );
+
+ gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
+ }
+
+ down_write(&current->mm->mmap_sem);
+ do
+ {
+ struct vm_area_struct *vma = find_vma(current->mm, (unsigned long)userLogical);
+ if (vma == gcvNULL)
+ {
+ gcmkTRACE_ZONE(
+ gcvLEVEL_INFO, gcvZONE_OS,
+ "%s(%d): find_vma error",
+ __FUNCTION__, __LINE__
+ );
+
+ gcmkERR_BREAK(gcvSTATUS_OUT_OF_RESOURCES);
+ }
+
+ gcmkERR_BREAK(reserved_mem_mmap(Allocator, Mdl, gcvFALSE, 0, Mdl->numPages, vma));
+
+ MdlMap->vmaAddr = userLogical;
+ MdlMap->cacheable = gcvFALSE;
+ MdlMap->vma = vma;
+ }
+ while (gcvFALSE);
+ up_write(&current->mm->mmap_sem);
+
+OnError:
+ if (gcmIS_ERROR(status) && userLogical)
+ {
+ reserved_mem_unmap_user(Allocator, Mdl, userLogical, res->size);
+ }
+ gcmkFOOTER();
+ return status;
+}
+
+static gceSTATUS
+reserved_mem_map_kernel(
+ IN gckALLOCATOR Allocator,
+ IN PLINUX_MDL Mdl,
+ OUT gctPOINTER *Logical
+ )
+{
+ struct reserved_mem *res = Mdl->priv;
+ void *vaddr;
+
+ /* Should never run here now. */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,6,0)
+ vaddr = memremap(res->start, res->size, MEMREMAP_WC);
+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(4,3,0)
+ vaddr = memremap(res->start, res->size, MEMREMAP_WT);
+#else
+ vaddr = ioremap_nocache(res->start, res->size);
+#endif
+
+ if (!vaddr)
+ {
+ return gcvSTATUS_OUT_OF_MEMORY;
+ }
+
+ *Logical = vaddr;
+ return gcvSTATUS_OK;;
+}
+
+static gceSTATUS
+reserved_mem_unmap_kernel(
+ IN gckALLOCATOR Allocator,
+ IN PLINUX_MDL Mdl,
+ IN gctPOINTER Logical
+ )
+{
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,3,0)
+ memunmap((void *)Logical);
+#else
+ iounmap((void *)Logical);
+#endif
+ return gcvSTATUS_OK;
+}
+
+static gceSTATUS
+reserved_mem_cache_op(
+ IN gckALLOCATOR Allocator,
+ IN PLINUX_MDL Mdl,
+ IN gctSIZE_T Offset,
+ IN gctPOINTER Logical,
+ IN gctUINT32 Bytes,
+ IN gceCACHEOPERATION Operation
+ )
+{
+ /* Always WC or UC, safe to use mb. */
+ switch (Operation)
+ {
+ case gcvCACHE_CLEAN:
+ case gcvCACHE_FLUSH:
+ _MemoryBarrier();
+ break;
+ case gcvCACHE_INVALIDATE:
+ break;
+ default:
+ return gcvSTATUS_INVALID_ARGUMENT;
+ }
+
+ return gcvSTATUS_OK;
+}
+
+static gceSTATUS
+reserved_mem_get_physical(
+ IN gckALLOCATOR Allocator,
+ IN PLINUX_MDL Mdl,
+ IN gctUINT32 Offset,
+ OUT gctPHYS_ADDR_T * Physical
+ )
+{
+ struct reserved_mem *res = Mdl->priv;
+ *Physical = res->start + Offset;
+
+ return gcvSTATUS_OK;
+}
+
+static void
+reserved_mem_dtor(
+ gcsALLOCATOR *Allocator
+ )
+{
+ reserved_mem_debugfs_cleanup(Allocator);
+
+ if (Allocator->privateData)
+ {
+ kfree(Allocator->privateData);
+ }
+
+ kfree(Allocator);
+}
+
+/* GFP allocator operations. */
+static gcsALLOCATOR_OPERATIONS reserved_mem_ops = {
+ .Alloc = NULL,
+ .Attach = reserved_mem_attach,
+ .Free = reserved_mem_detach,
+ .Mmap = reserved_mem_mmap,
+ .MapUser = reserved_mem_map_user,
+ .UnmapUser = reserved_mem_unmap_user,
+ .MapKernel = reserved_mem_map_kernel,
+ .UnmapKernel = reserved_mem_unmap_kernel,
+ .Cache = reserved_mem_cache_op,
+ .Physical = reserved_mem_get_physical,
+};
+
+/* GFP allocator entry. */
+gceSTATUS
+_ReservedMemoryAllocatorInit(
+ IN gckOS Os,
+ IN gcsDEBUGFS_DIR *Parent,
+ OUT gckALLOCATOR * Allocator
+ )
+{
+ gceSTATUS status;
+ gckALLOCATOR allocator = gcvNULL;
+ struct reserved_mem_alloc *alloc = NULL;
+
+ gcmkONERROR(
+ gckALLOCATOR_Construct(Os, &reserved_mem_ops, &allocator));
+
+ alloc = kzalloc(sizeof(*alloc), GFP_KERNEL | gcdNOWARN);
+
+ if (!alloc)
+ {
+ gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
+ }
+
+ INIT_LIST_HEAD(&alloc->region);
+ mutex_init(&alloc->lock);
+
+ /* Register private data. */
+ allocator->privateData = alloc;
+ allocator->destructor = reserved_mem_dtor;
+
+ reserved_mem_debugfs_init(allocator, Parent);
+
+ allocator->capability = gcvALLOC_FLAG_LINUX_RESERVED_MEM;
+
+ *Allocator = allocator;
+
+ return gcvSTATUS_OK;
+
+OnError:
+ if (allocator)
+ {
+ kfree(allocator);
+ }
+ return status;
+}
+
diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/allocator/default/gc_hal_kernel_allocator_user_memory.c b/drivers/mxc/gpu-viv/hal/os/linux/kernel/allocator/default/gc_hal_kernel_allocator_user_memory.c
new file mode 100644
index 000000000000..5759effdadeb
--- /dev/null
+++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/allocator/default/gc_hal_kernel_allocator_user_memory.c
@@ -0,0 +1,854 @@
+/****************************************************************************
+*
+* The MIT License (MIT)
+*
+* Copyright (c) 2014 - 2018 Vivante 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 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 GPL License (GPL)
+*
+* Copyright (C) 2014 - 2018 Vivante 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.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+*****************************************************************************
+*
+* Note: This software is released under dual MIT and GPL licenses. A
+* recipient may use this file under the terms of either the MIT license or
+* GPL License. If you wish to use only one license not the other, you can
+* indicate your decision by deleting one of the above license notices in your
+* version of this file.
+*
+*****************************************************************************/
+
+
+#include "gc_hal_kernel_linux.h"
+#include "gc_hal_kernel_allocator.h"
+#include <linux/scatterlist.h>
+
+#include <linux/slab.h>
+#include <linux/pagemap.h>
+
+#define _GC_OBJ_ZONE gcvZONE_ALLOCATOR
+
+enum um_desc_type
+{
+ UM_PHYSICAL_MAP,
+ UM_PAGE_MAP,
+ UM_PFN_MAP,
+};
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION (2,6,24)
+struct sg_table
+{
+ struct scatterlist *sgl;
+ unsigned int nents;
+ unsigned int orig_nents;
+};
+#endif
+
+/* Descriptor of a user memory imported. */
+struct um_desc
+{
+ int type;
+
+ union
+ {
+ /* UM_PHYSICAL_MAP. */
+ unsigned long physical;
+
+ /* UM_PAGE_MAP. */
+ struct
+ {
+ struct page **pages;
+ struct sg_table sgt;
+ };
+
+ /* UM_PFN_MAP. */
+ struct
+ {
+ unsigned long *pfns;
+ int *refs;
+ };
+ };
+
+ /* contiguous chunks, does not include padding pages. */
+ int chunk_count;
+
+ unsigned long vm_flags;
+ unsigned long user_vaddr;
+ size_t size;
+ unsigned long offset;
+
+ size_t pageCount;
+ size_t extraPage;
+};
+
+static int import_physical_map(struct um_desc *um, unsigned long phys)
+{
+ um->type = UM_PHYSICAL_MAP;
+ um->physical = phys & PAGE_MASK;
+ um->chunk_count = 1;
+ return 0;
+}
+
+static int import_page_map(struct um_desc *um,
+ unsigned long addr, size_t page_count, size_t size)
+{
+ int i;
+ int result;
+ struct page **pages;
+
+ pages = kzalloc(page_count * sizeof(void *), GFP_KERNEL | gcdNOWARN);
+ if (!pages)
+ return -ENOMEM;
+
+ down_read(&current->mm->mmap_sem);
+
+ result = get_user_pages(
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 6, 0)
+ current,
+ current->mm,
+#endif
+ addr & PAGE_MASK,
+ page_count,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 9, 0)
+ FOLL_WRITE,
+#else
+ 1,
+ 0,
+#endif
+ pages,
+ NULL);
+
+ up_read(&current->mm->mmap_sem);
+
+ if (result < page_count)
+ {
+ for (i = 0; i < result; i++)
+ {
+ if (pages[i])
+ {
+ put_page(pages[i]);
+ }
+ }
+
+ kfree(pages);
+ return -ENODEV;
+ }
+
+ um->chunk_count = 1;
+ for (i = 1; i < page_count; i++)
+ {
+ if (page_to_pfn(pages[i]) != page_to_pfn(pages[i - 1]) + 1)
+ {
+ ++um->chunk_count;
+ }
+ }
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION (3,6,0) \
+ && (defined(ARCH_HAS_SG_CHAIN) || defined(CONFIG_ARCH_HAS_SG_CHAIN))
+ result = sg_alloc_table_from_pages(&um->sgt, pages, page_count,
+ addr & ~PAGE_MASK, size, GFP_KERNEL | gcdNOWARN);
+
+#else
+ result = alloc_sg_list_from_pages(&um->sgt.sgl, pages, page_count,
+ addr & ~PAGE_MASK, size, &um->sgt.nents);
+
+ um->sgt.orig_nents = um->sgt.nents;
+#endif
+ if (unlikely(result < 0))
+ {
+ printk("[galcore]: %s: sg_alloc_table_from_pages failed\n", __FUNCTION__);
+ goto error;
+ }
+
+ result = dma_map_sg(galcore_device, um->sgt.sgl, um->sgt.nents, DMA_TO_DEVICE);
+ if (unlikely(result != um->sgt.nents))
+ {
+ printk("[galcore]: %s: dma_map_sg failed\n", __FUNCTION__);
+ goto error;
+ }
+
+ um->type = UM_PAGE_MAP;
+ um->pages = pages;
+
+ return 0;
+
+error:
+#if LINUX_VERSION_CODE >= KERNEL_VERSION (3,6,0) \
+ && (defined(ARCH_HAS_SG_CHAIN) || defined(CONFIG_ARCH_HAS_SG_CHAIN))
+ sg_free_table(&um->sgt);
+#else
+ kfree(um->sgt.sgl);
+#endif
+
+ if (pages)
+ {
+ kfree(pages);
+ }
+ return result;
+}
+
+
+static int import_pfn_map(struct um_desc *um,
+ unsigned long addr, size_t pfn_count)
+{
+ int i;
+ struct vm_area_struct *vma;
+ unsigned long *pfns;
+ int *refs;
+
+ if (!current->mm)
+ return -ENOTTY;
+
+ down_read(&current->mm->mmap_sem);
+ vma = find_vma(current->mm, addr);
+ up_read(&current->mm->mmap_sem);
+
+ if (!vma)
+ return -ENOTTY;
+
+ pfns = kzalloc(pfn_count * sizeof(unsigned long), GFP_KERNEL | gcdNOWARN);
+
+ if (!pfns)
+ return -ENOMEM;
+
+ refs = kzalloc(pfn_count * sizeof(int), GFP_KERNEL | gcdNOWARN);
+
+ if (!refs)
+ {
+ kfree(pfns);
+ return -ENOMEM;
+ }
+
+ for (i = 0; i < pfn_count; i++)
+ {
+ spinlock_t *ptl;
+ pgd_t *pgd;
+ pud_t *pud;
+ pmd_t *pmd;
+ pte_t *pte;
+
+ pgd = pgd_offset(current->mm, addr);
+ if (pgd_none(*pgd) || pgd_bad(*pgd))
+ goto err;
+
+ pud = pud_offset(pgd, addr);
+ if (pud_none(*pud) || pud_bad(*pud))
+ goto err;
+
+ pmd = pmd_offset(pud, addr);
+ if (pmd_none(*pmd) || pmd_bad(*pmd))
+ goto err;
+
+ pte = pte_offset_map_lock(current->mm, pmd, addr, &ptl);
+ if (!pte)
+ {
+ spin_unlock(ptl);
+ goto err;
+ }
+
+ if (!pte_present(*pte))
+ {
+ pte_unmap_unlock(pte, ptl);
+ goto err;
+ }
+
+ pfns[i] = pte_pfn(*pte);
+ pte_unmap_unlock(pte, ptl);
+
+ /* Advance to next. */
+ addr += PAGE_SIZE;
+ }
+
+ for (i = 0; i < pfn_count; i++)
+ {
+ if (pfn_valid(pfns[i]))
+ {
+ struct page *page = pfn_to_page(pfns[i]);
+ refs[i] = get_page_unless_zero(page);
+ }
+ }
+
+ um->chunk_count = 1;
+ for (i = 1; i < pfn_count; i++)
+ {
+ if (pfns[i] != pfns[i - 1] + 1)
+ {
+ ++um->chunk_count;
+ }
+ }
+
+ um->type = UM_PFN_MAP;
+ um->pfns = pfns;
+ um->refs = refs;
+ return 0;
+
+err:
+ if (pfns)
+ kfree(pfns);
+
+ if (refs)
+ kfree(refs);
+
+ return -ENOTTY;
+}
+
+static gceSTATUS
+_Import(
+ IN gckOS Os,
+ IN gctPOINTER Memory,
+ IN gctUINT32 Physical,
+ IN gctSIZE_T Size,
+ IN struct um_desc * UserMemory
+ )
+{
+ gceSTATUS status = gcvSTATUS_OK;
+ unsigned long vm_flags = 0;
+ struct vm_area_struct *vma = NULL;
+ unsigned long start, end, memory;
+ int result = 0;
+
+ gctSIZE_T extraPage;
+ gctSIZE_T pageCount, i;
+
+ gcmkHEADER_ARG("Os=0x%p Memory=%p Physical=0x%x Size=%lu", Os, Memory, Physical, Size);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
+ gcmkVERIFY_ARGUMENT(Memory != gcvNULL || Physical != ~0U);
+ gcmkVERIFY_ARGUMENT(Size > 0);
+
+ memory = (unsigned long)Memory;
+
+ /* Get the number of required pages. */
+ end = (memory + Size + PAGE_SIZE - 1) >> PAGE_SHIFT;
+ start = memory >> PAGE_SHIFT;
+ pageCount = end - start;
+
+ /* Allocate extra page to avoid cache overflow */
+#if gcdENABLE_2D
+ extraPage = 2;
+#else
+ extraPage = (((memory + gcmALIGN(Size + 64, 64) + PAGE_SIZE - 1) >> PAGE_SHIFT) > end) ? 1 : 0;
+#endif
+
+ gcmkTRACE_ZONE(
+ gcvLEVEL_INFO, _GC_OBJ_ZONE,
+ "%s(%d): pageCount: %d. extraPage: %d",
+ __FUNCTION__, __LINE__,
+ pageCount, extraPage
+ );
+
+ /* Overflow. */
+ if ((memory + Size) < memory)
+ {
+ gcmkFOOTER_ARG("status=%d", gcvSTATUS_INVALID_ARGUMENT);
+ return gcvSTATUS_INVALID_ARGUMENT;
+ }
+
+ if (memory)
+ {
+ unsigned long vaddr = memory;
+
+ for (i = 0; i < pageCount; i++)
+ {
+ u32 data;
+
+ get_user(data, (u32 *)vaddr);
+ put_user(data, (u32 *)vaddr);
+ vaddr += PAGE_SIZE;
+
+ /* Fix QM crash with test_buffers */
+ if (vaddr > memory + Size - 4)
+ {
+ vaddr = memory + Size - 4;
+ }
+ }
+
+ vma = find_vma(current->mm, memory);
+
+ if (!vma)
+ {
+ /* No such memory, or across vmas. */
+ gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
+ }
+
+#ifdef CONFIG_ARM
+ /* coherent cache in case vivt or vipt-aliasing cache. */
+ __cpuc_flush_user_range(memory, memory + Size, vma->vm_flags);
+#endif
+
+ vm_flags = vma->vm_flags;
+ vaddr = vma->vm_end;
+
+ while (vaddr < memory + Size)
+ {
+ vma = find_vma(current->mm, vaddr);
+
+ if (!vma)
+ {
+ /* No such memory. */
+ gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
+ }
+
+ if ((vma->vm_flags & VM_PFNMAP) != (vm_flags & VM_PFNMAP))
+ {
+ /* Can not support different map type: both PFN and PAGE detected. */
+ gcmkONERROR(gcvSTATUS_NOT_SUPPORTED);
+ }
+
+ vaddr = vma->vm_end;
+ }
+ }
+
+ if (Physical != gcvINVALID_PHYSICAL_ADDRESS)
+ {
+ result = import_physical_map(UserMemory, Physical);
+ }
+ else
+ {
+ if (vm_flags & VM_PFNMAP)
+ {
+ result = import_pfn_map(UserMemory, memory, pageCount);
+ }
+ else
+ {
+ result = import_page_map(UserMemory, memory, pageCount, Size);
+ }
+ }
+
+ if (result == -EINVAL)
+ {
+ gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
+ }
+ else if (result == -ENOMEM)
+ {
+ gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
+ }
+ else if (result < 0)
+ {
+ gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
+ }
+
+ if(Os->device->platform->flagBits & gcvPLATFORM_FLAG_LIMIT_4G_ADDRESS )
+ {
+ gctPHYS_ADDR_T addr;
+
+ if (Physical != gcvINVALID_PHYSICAL_ADDRESS)
+ {
+ if(Physical >0xFFFFFFFFu || Physical + Size > 0xFFFFFFFFu )
+ {
+ gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
+ }
+ }
+ else if (vm_flags & VM_PFNMAP)
+ {
+ for(i = 0; i < pageCount; i++)
+ {
+ addr = UserMemory->pfns[i] << PAGE_SHIFT;
+ if( addr > 0xFFFFFFFFu)
+ {
+ kfree(UserMemory->pfns);
+ UserMemory->pfns = gcvNULL;
+ kfree(UserMemory->refs) ;
+ UserMemory->refs = gcvNULL;
+ gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
+ }
+ }
+ }
+ else
+ {
+ for (i = 0; i< pageCount; i++)
+ {
+ addr = page_to_phys(UserMemory->pages[i]);
+ if(addr > 0xFFFFFFFFu )
+ {
+ kfree(UserMemory->pages);
+ UserMemory->pages = gcvNULL;
+ gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
+ }
+ }
+ }
+ }
+
+ UserMemory->vm_flags = vm_flags;
+ UserMemory->user_vaddr = (unsigned long)Memory;
+ UserMemory->size = Size;
+ UserMemory->offset = (Physical != gcvINVALID_PHYSICAL_ADDRESS)
+ ? (Physical & ~PAGE_MASK)
+ : (memory & ~PAGE_MASK);
+
+ UserMemory->pageCount = pageCount;
+ UserMemory->extraPage = extraPage;
+
+ if (extraPage && UserMemory->type == UM_PAGE_MAP)
+ {
+ /*Add the padding pages */
+ UserMemory->chunk_count++;
+ }
+
+ /* Success. */
+ gcmkFOOTER();
+ return gcvSTATUS_OK;
+
+OnError:
+ gcmkFOOTER();
+ return status;
+}
+
+static gceSTATUS
+_UserMemoryAttach(
+ IN gckALLOCATOR Allocator,
+ IN gcsATTACH_DESC_PTR Desc,
+ IN PLINUX_MDL Mdl
+ )
+{
+ gceSTATUS status;
+ struct um_desc * userMemory = gcvNULL;
+
+ gckOS os = Allocator->os;
+
+ gcmkHEADER();
+
+ /* Handle is meangless for this importer. */
+ gcmkVERIFY_ARGUMENT(Desc != gcvNULL);
+
+ gcmkONERROR(gckOS_Allocate(os, gcmSIZEOF(struct um_desc), (gctPOINTER *)&userMemory));
+
+ gckOS_ZeroMemory(userMemory, gcmSIZEOF(struct um_desc));
+
+ gcmkONERROR(_Import(os, Desc->userMem.memory, Desc->userMem.physical, Desc->userMem.size, userMemory));
+
+ Mdl->priv = userMemory;
+ Mdl->numPages = userMemory->pageCount + userMemory->extraPage;
+ Mdl->contiguous = (userMemory->chunk_count == 1);
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ if (userMemory != gcvNULL)
+ {
+ gckOS_Free(os,(gctPOINTER)userMemory);
+ }
+ gcmkFOOTER();
+ return status;
+}
+
+static void release_physical_map(struct um_desc *um)
+{
+}
+
+static void release_page_map(struct um_desc *um)
+{
+ int i;
+
+ dma_unmap_sg(galcore_device, um->sgt.sgl, um->sgt.nents, DMA_TO_DEVICE);
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION (3,6,0) \
+ && (defined(ARCH_HAS_SG_CHAIN) || defined(CONFIG_ARCH_HAS_SG_CHAIN))
+ sg_free_table(&um->sgt);
+#else
+ kfree(um->sgt.sgl);
+#endif
+
+ for (i = 0; i < um->pageCount; i++)
+ {
+ if (!PageReserved(um->pages[i]))
+ {
+ SetPageDirty(um->pages[i]);
+ }
+
+ put_page(um->pages[i]);
+ }
+
+ kfree(um->pages);
+}
+
+static void release_pfn_map(struct um_desc *um)
+{
+
+ int i;
+
+ for (i = 0; i < um->pageCount; i++)
+ {
+ if (pfn_valid(um->pfns[i]))
+ {
+ struct page *page = pfn_to_page(um->pfns[i]);
+ if (!PageReserved(page))
+ {
+ SetPageDirty(page);
+ }
+
+ if (um->refs[i])
+ {
+ put_page(page);
+ }
+ }
+ }
+
+ kfree(um->pfns);
+ kfree(um->refs);
+}
+
+static void
+_UserMemoryFree(
+ IN gckALLOCATOR Allocator,
+ IN PLINUX_MDL Mdl
+ )
+{
+ gckOS os = Allocator->os;
+ struct um_desc *userMemory = Mdl->priv;
+
+ gcmkHEADER();
+
+ if (userMemory)
+ {
+ switch (userMemory->type)
+ {
+ case UM_PHYSICAL_MAP:
+ release_physical_map(userMemory);
+ break;
+ case UM_PAGE_MAP:
+ release_page_map(userMemory);
+ break;
+ case UM_PFN_MAP:
+ release_pfn_map(userMemory);
+ break;
+ }
+
+ gcmkOS_SAFE_FREE(os, userMemory);
+ }
+
+ gcmkFOOTER_NO();
+}
+
+static gceSTATUS
+_UserMemoryMapUser(
+ IN gckALLOCATOR Allocator,
+ IN PLINUX_MDL Mdl,
+ IN PLINUX_MDL_MAP MdlMap,
+ IN gctBOOL Cacheable
+ )
+{
+ struct um_desc *userMemory = Mdl->priv;
+
+ MdlMap->vmaAddr = (gctPOINTER)userMemory->user_vaddr;
+ MdlMap->cacheable = gcvTRUE;
+
+ return gcvSTATUS_OK;
+}
+
+static void
+_UserMemoryUnmapUser(
+ IN gckALLOCATOR Allocator,
+ IN PLINUX_MDL Mdl,
+ IN PLINUX_MDL_MAP MdlMap,
+ IN gctUINT32 Size
+ )
+{
+ return;
+}
+
+static gceSTATUS
+_UserMemoryMapKernel(
+ IN gckALLOCATOR Allocator,
+ IN PLINUX_MDL Mdl,
+ OUT gctPOINTER *Logical
+ )
+{
+ /* Kernel doesn't acess video memory. */
+ return gcvSTATUS_NOT_SUPPORTED;
+}
+
+static gceSTATUS
+_UserMemoryUnmapKernel(
+ IN gckALLOCATOR Allocator,
+ IN PLINUX_MDL Mdl,
+ IN gctPOINTER Logical
+ )
+{
+ /* Kernel doesn't acess video memory. */
+ return gcvSTATUS_NOT_SUPPORTED;
+}
+
+static gceSTATUS
+_UserMemoryCache(
+ IN gckALLOCATOR Allocator,
+ IN PLINUX_MDL Mdl,
+ IN gctSIZE_T Offset,
+ IN gctPOINTER Logical,
+ IN gctUINT32 Bytes,
+ IN gceCACHEOPERATION Operation
+ )
+{
+ struct um_desc *um = Mdl->priv;
+ enum dma_data_direction dir;
+
+ if (um->type != UM_PAGE_MAP)
+ {
+ _MemoryBarrier();
+ return gcvSTATUS_OK;
+ }
+
+#ifdef CONFIG_ARM
+ /* coherent cache in case vivt or vipt-aliasing cache. */
+ __cpuc_flush_user_range(um->user_vaddr,
+ um->user_vaddr + um->size, um->vm_flags);
+#endif
+
+ switch (Operation)
+ {
+ case gcvCACHE_CLEAN:
+ dir = DMA_TO_DEVICE;
+ dma_sync_sg_for_device(galcore_device, um->sgt.sgl, um->sgt.nents, dir);
+ break;
+ case gcvCACHE_FLUSH:
+ dir = DMA_TO_DEVICE;
+ dma_sync_sg_for_device(galcore_device, um->sgt.sgl, um->sgt.nents, dir);
+ dir = DMA_FROM_DEVICE;
+ dma_sync_sg_for_cpu(galcore_device, um->sgt.sgl, um->sgt.nents, dir);
+ break;
+ case gcvCACHE_INVALIDATE:
+ dir = DMA_FROM_DEVICE;
+ dma_sync_sg_for_cpu(galcore_device, um->sgt.sgl, um->sgt.nents, dir);
+ break;
+ default:
+ return gcvSTATUS_INVALID_ARGUMENT;
+ }
+
+
+ return gcvSTATUS_OK;
+}
+
+static gceSTATUS
+_UserMemoryPhysical(
+ IN gckALLOCATOR Allocator,
+ IN PLINUX_MDL Mdl,
+ IN gctUINT32 Offset,
+ OUT gctPHYS_ADDR_T * Physical
+ )
+{
+ gckOS os = Allocator->os;
+ struct um_desc *userMemory = Mdl->priv;
+ unsigned long offset = Offset + userMemory->offset;
+ gctUINT32 offsetInPage = offset & ~PAGE_MASK;
+ gctUINT32 index = offset / PAGE_SIZE;
+
+ if (index >= userMemory->pageCount)
+ {
+ if (index < userMemory->pageCount + userMemory->extraPage)
+ {
+ *Physical = page_to_phys(os->paddingPage);
+ }
+ else
+ {
+ return gcvSTATUS_INVALID_ARGUMENT;
+ }
+ }
+ else
+ {
+ switch (userMemory->type)
+ {
+ case UM_PHYSICAL_MAP:
+ *Physical = userMemory->physical + index * PAGE_SIZE;
+ break;
+ case UM_PAGE_MAP:
+ *Physical = page_to_phys(userMemory->pages[index]);
+ break;
+ case UM_PFN_MAP:
+ *Physical = userMemory->pfns[index] << PAGE_SHIFT;
+ break;
+ }
+ }
+
+ *Physical += offsetInPage;
+
+ return gcvSTATUS_OK;
+}
+
+static void
+_UserMemoryAllocatorDestructor(
+ gcsALLOCATOR *Allocator
+ )
+{
+ if (Allocator->privateData)
+ {
+ kfree(Allocator->privateData);
+ }
+
+ kfree(Allocator);
+}
+
+/* User memory allocator (importer) operations. */
+static gcsALLOCATOR_OPERATIONS UserMemoryAllocatorOperations =
+{
+ .Attach = _UserMemoryAttach,
+ .Free = _UserMemoryFree,
+ .MapUser = _UserMemoryMapUser,
+ .UnmapUser = _UserMemoryUnmapUser,
+ .MapKernel = _UserMemoryMapKernel,
+ .UnmapKernel = _UserMemoryUnmapKernel,
+ .Cache = _UserMemoryCache,
+ .Physical = _UserMemoryPhysical,
+};
+
+/* Default allocator entry. */
+gceSTATUS
+_UserMemoryAlloctorInit(
+ IN gckOS Os,
+ IN gcsDEBUGFS_DIR *Parent,
+ OUT gckALLOCATOR * Allocator
+ )
+{
+ gceSTATUS status;
+ gckALLOCATOR allocator;
+
+ gcmkONERROR(
+ gckALLOCATOR_Construct(Os, &UserMemoryAllocatorOperations, &allocator));
+
+ allocator->destructor = _UserMemoryAllocatorDestructor;
+
+ allocator->capability = gcvALLOC_FLAG_USERMEMORY;
+
+ *Allocator = allocator;
+
+ return gcvSTATUS_OK;
+
+OnError:
+ return status;
+}
+
diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/allocator/freescale/gc_hal_kernel_allocator_array.h b/drivers/mxc/gpu-viv/hal/os/linux/kernel/allocator/freescale/gc_hal_kernel_allocator_array.h
new file mode 100644
index 000000000000..69d4afd23725
--- /dev/null
+++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/allocator/freescale/gc_hal_kernel_allocator_array.h
@@ -0,0 +1,131 @@
+/****************************************************************************
+*
+* The MIT License (MIT)
+*
+* Copyright (c) 2014 - 2018 Vivante 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 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 GPL License (GPL)
+*
+* Copyright (C) 2014 - 2018 Vivante 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.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+*****************************************************************************
+*
+* Note: This software is released under dual MIT and GPL licenses. A
+* recipient may use this file under the terms of either the MIT license or
+* GPL License. If you wish to use only one license not the other, you can
+* indicate your decision by deleting one of the above license notices in your
+* version of this file.
+*
+*****************************************************************************/
+
+
+#ifndef __gc_hal_kernel_allocator_array_h_
+#define __gc_hal_kernel_allocator_array_h_
+
+extern gceSTATUS
+_GFPAlloctorInit(
+ IN gckOS Os,
+ IN gcsDEBUGFS_DIR *Parent,
+ OUT gckALLOCATOR * Allocator
+ );
+
+extern gceSTATUS
+_UserMemoryAlloctorInit(
+ IN gckOS Os,
+ IN gcsDEBUGFS_DIR *Parent,
+ OUT gckALLOCATOR * Allocator
+ );
+
+extern gceSTATUS
+_ReservedMemoryAllocatorInit(
+ IN gckOS Os,
+ IN gcsDEBUGFS_DIR *Parent,
+ OUT gckALLOCATOR * Allocator
+ );
+
+#if LINUX_CMA_FSL
+extern gceSTATUS
+_CMAFSLAlloctorInit(
+ IN gckOS Os,
+ IN gcsDEBUGFS_DIR *Parent,
+ OUT gckALLOCATOR * Allocator
+ );
+#endif
+
+#ifdef CONFIG_DMA_SHARED_BUFFER
+extern gceSTATUS
+_DmabufAlloctorInit(
+ IN gckOS Os,
+ IN gcsDEBUGFS_DIR *Parent,
+ OUT gckALLOCATOR * Allocator
+ );
+#endif
+
+#ifndef NO_DMA_COHERENT
+extern gceSTATUS
+_DmaAlloctorInit(
+ IN gckOS Os,
+ IN gcsDEBUGFS_DIR *Parent,
+ OUT gckALLOCATOR * Allocator
+ );
+#endif
+
+gcsALLOCATOR_DESC allocatorArray[] =
+{
+ /* GFP allocator. */
+ gcmkDEFINE_ALLOCATOR_DESC("gfp", _GFPAlloctorInit),
+
+#if LINUX_CMA_FSL
+ gcmkDEFINE_ALLOCATOR_DESC("cmafsl", _CMAFSLAlloctorInit),
+#endif
+
+ /* User memory importer. */
+ gcmkDEFINE_ALLOCATOR_DESC("user", _UserMemoryAlloctorInit),
+
+#ifdef CONFIG_DMA_SHARED_BUFFER
+ /* Dmabuf allocator. */
+ gcmkDEFINE_ALLOCATOR_DESC("dmabuf", _DmabufAlloctorInit),
+#endif
+
+#ifndef NO_DMA_COHERENT
+ gcmkDEFINE_ALLOCATOR_DESC("dma", _DmaAlloctorInit),
+#endif
+
+ gcmkDEFINE_ALLOCATOR_DESC("reserved-mem", _ReservedMemoryAllocatorInit),
+};
+
+#endif
diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/allocator/freescale/gc_hal_kernel_allocator_cma.c b/drivers/mxc/gpu-viv/hal/os/linux/kernel/allocator/freescale/gc_hal_kernel_allocator_cma.c
new file mode 100644
index 000000000000..c6a28bbb31d9
--- /dev/null
+++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/allocator/freescale/gc_hal_kernel_allocator_cma.c
@@ -0,0 +1,603 @@
+/****************************************************************************
+*
+* The MIT License (MIT)
+*
+* Copyright (c) 2014 - 2018 Vivante 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 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 GPL License (GPL)
+*
+* Copyright (C) 2014 - 2018 Vivante 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.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+*****************************************************************************
+*
+* Note: This software is released under dual MIT and GPL licenses. A
+* recipient may use this file under the terms of either the MIT license or
+* GPL License. If you wish to use only one license not the other, you can
+* indicate your decision by deleting one of the above license notices in your
+* version of this file.
+*
+*****************************************************************************/
+
+
+#include "gc_hal_kernel_linux.h"
+#include "gc_hal_kernel_allocator.h"
+
+#include <linux/pagemap.h>
+#include <linux/seq_file.h>
+#include <linux/mman.h>
+#include <asm/atomic.h>
+#include <linux/dma-mapping.h>
+#include <linux/slab.h>
+#include <linux/platform_device.h>
+
+#define _GC_OBJ_ZONE gcvZONE_OS
+
+typedef struct _gcsCMA_PRIV * gcsCMA_PRIV_PTR;
+typedef struct _gcsCMA_PRIV {
+ atomic_t cmasize;
+ gctBOOL cmaLimitRequest;
+}
+gcsCMA_PRIV;
+
+struct mdl_cma_priv {
+ gctPOINTER kvaddr;
+ dma_addr_t physical;
+};
+
+static int gc_cma_usage_show(struct seq_file* m, void* data)
+{
+ gcsINFO_NODE *node = m->private;
+ gckALLOCATOR Allocator = node->device;
+ gcsCMA_PRIV_PTR priv = Allocator->privateData;
+ long long size = (long long)atomic_read(&priv->cmasize);
+
+ seq_printf(m, "type n pages bytes\n");
+ seq_printf(m, "cma %10llu %12llu\n", size, size * PAGE_SIZE);
+
+ return 0;
+}
+
+static gcsINFO InfoList[] =
+{
+ {"cmausage", gc_cma_usage_show},
+};
+
+static void
+_CMAAllocatorDebugfsInit(
+ IN gckALLOCATOR Allocator,
+ IN gckDEBUGFS_DIR Root
+ )
+{
+ gcmkVERIFY_OK(
+ gckDEBUGFS_DIR_Init(&Allocator->debugfsDir, Root->root, "cma"));
+
+ gcmkVERIFY_OK(gckDEBUGFS_DIR_CreateFiles(
+ &Allocator->debugfsDir,
+ InfoList,
+ gcmCOUNTOF(InfoList),
+ Allocator
+ ));
+}
+
+static void
+_CMAAllocatorDebugfsCleanup(
+ IN gckALLOCATOR Allocator
+ )
+{
+ gcmkVERIFY_OK(gckDEBUGFS_DIR_RemoveFiles(
+ &Allocator->debugfsDir,
+ InfoList,
+ gcmCOUNTOF(InfoList)
+ ));
+
+ gckDEBUGFS_DIR_Deinit(&Allocator->debugfsDir);
+}
+
+static gceSTATUS
+_CMAFSLAlloc(
+ IN gckALLOCATOR Allocator,
+ INOUT PLINUX_MDL Mdl,
+ IN gctSIZE_T NumPages,
+ IN gctUINT32 Flags
+ )
+{
+ gceSTATUS status;
+ u32 gfp = GFP_KERNEL | gcdNOWARN;
+ gcsCMA_PRIV_PTR priv = (gcsCMA_PRIV_PTR)Allocator->privateData;
+
+ struct mdl_cma_priv *mdl_priv=gcvNULL;
+ gckOS os = Allocator->os;
+
+ gcmkHEADER_ARG("Mdl=%p NumPages=0x%zx", Mdl, NumPages);
+
+ if (os->allocatorLimitMarker && !(Flags & gcvALLOC_FLAG_CMA_PREEMPT))
+ {
+ if (Flags & gcvALLOC_FLAG_CMA_LIMIT)
+ {
+ priv->cmaLimitRequest = gcvTRUE;
+ }
+ else if (priv->cmaLimitRequest == gcvTRUE)
+ {
+ gcmkONERROR(gcvSTATUS_NOT_SUPPORTED);
+ }
+ }
+
+ gcmkONERROR(gckOS_Allocate(os, sizeof(struct mdl_cma_priv), (gctPOINTER *)&mdl_priv));
+ mdl_priv->kvaddr = gcvNULL;
+
+#if defined(CONFIG_ZONE_DMA32) && LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)
+ if (Flags & gcvALLOC_FLAG_4GB_ADDR)
+ {
+ gfp |= __GFP_DMA32;
+ }
+#endif
+
+ mdl_priv->kvaddr = dma_alloc_writecombine(&os->device->platform->device->dev,
+ NumPages * PAGE_SIZE,
+ &mdl_priv->physical,
+ gfp);
+
+ if (mdl_priv->kvaddr == gcvNULL)
+ {
+ gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
+ }
+
+ Mdl->priv = mdl_priv;
+ Mdl->dmaHandle = mdl_priv->physical;
+ atomic_add(NumPages, &priv->cmasize);
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ if (mdl_priv)
+ {
+ gckOS_Free(os, mdl_priv);
+ }
+ gcmkFOOTER();
+ return status;
+}
+
+static gceSTATUS
+_CMAFSLGetSGT(
+ IN gckALLOCATOR Allocator,
+ IN PLINUX_MDL Mdl,
+ IN gctSIZE_T Offset,
+ IN gctSIZE_T Bytes,
+ OUT gctPOINTER *SGT
+ )
+{
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)
+ struct page ** pages = gcvNULL;
+ struct page * page = gcvNULL;
+ struct sg_table *sgt = NULL;
+ struct mdl_cma_priv *mdl_priv = (struct mdl_cma_priv*)Mdl->priv;
+
+ gceSTATUS status = gcvSTATUS_OK;
+ gctSIZE_T offset = Offset & ~PAGE_MASK; /* Offset to the first page */
+ gctINT skipPages = Offset >> PAGE_SHIFT; /* skipped pages */
+ gctINT numPages = (PAGE_ALIGN(Offset + Bytes) >> PAGE_SHIFT) - skipPages;
+ gctINT i;
+
+ gcmkASSERT(Offset + Bytes <= Mdl->numPages << PAGE_SHIFT);
+
+ sgt = kmalloc(sizeof(struct sg_table), GFP_KERNEL | gcdNOWARN);
+ if (!sgt)
+ {
+ gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
+ }
+
+ pages = kmalloc(sizeof(struct page*) * numPages, GFP_KERNEL | gcdNOWARN);
+ if (!pages)
+ {
+ gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
+ }
+
+#if !defined(phys_to_page)
+ page = virt_to_page(mdlPriv->kvaddr);
+#elif LINUX_VERSION_CODE < KERNEL_VERSION(3,13,0)
+ page = phys_to_page(mdlPriv->physical);
+#else
+ page = phys_to_page(dma_to_phys(&Allocator->os->device->platform->device->dev, mdl_priv->physical));
+#endif
+
+ for (i = 0; i < numPages; ++i)
+ {
+ pages[i] = nth_page(page, i + skipPages);
+ }
+
+ if (sg_alloc_table_from_pages(sgt, pages, numPages, offset, Bytes, GFP_KERNEL) < 0)
+ {
+ gcmkONERROR(gcvSTATUS_GENERIC_IO);
+ }
+
+ *SGT = (gctPOINTER)sgt;
+
+OnError:
+ if (pages)
+ {
+ kfree(pages);
+ }
+
+ if (gcmIS_ERROR(status) && sgt)
+ {
+ kfree(sgt);
+ }
+
+ return status;
+#else
+ return gcvSTATUS_NOT_SUPPORTED;
+#endif
+}
+
+static void
+_CMAFSLFree(
+ IN gckALLOCATOR Allocator,
+ IN OUT PLINUX_MDL Mdl
+ )
+{
+ gckOS os = Allocator->os;
+ struct mdl_cma_priv *mdlPriv=(struct mdl_cma_priv *)Mdl->priv;
+ gcsCMA_PRIV_PTR priv = (gcsCMA_PRIV_PTR)Allocator->privateData;
+ dma_free_writecombine(&os->device->platform->device->dev,
+ Mdl->numPages * PAGE_SIZE,
+ mdlPriv->kvaddr,
+ mdlPriv->physical);
+ gckOS_Free(os, mdlPriv);
+ atomic_sub(Mdl->numPages, &priv->cmasize);
+}
+
+static gceSTATUS
+_CMAFSLMmap(
+ IN gckALLOCATOR Allocator,
+ IN PLINUX_MDL Mdl,
+ IN gctBOOL Cacheable,
+ IN gctSIZE_T skipPages,
+ IN gctSIZE_T numPages,
+ IN struct vm_area_struct *vma
+ )
+{
+ gckOS os = Allocator->os;
+ struct mdl_cma_priv *mdlPriv = (struct mdl_cma_priv*)Mdl->priv;
+ gceSTATUS status = gcvSTATUS_OK;
+
+ gcmkHEADER_ARG("Allocator=%p Mdl=%p vma=%p", Allocator, Mdl, vma);
+
+ gcmkASSERT(skipPages + numPages <= Mdl->numPages);
+
+ /* Now map all the vmalloc pages to this user address. */
+ if (Mdl->contiguous)
+ {
+ /* map kernel memory to user space.. */
+ if (dma_mmap_writecombine(&os->device->platform->device->dev,
+ vma,
+ (gctINT8_PTR)mdlPriv->kvaddr + (skipPages << PAGE_SHIFT),
+ mdlPriv->physical + (skipPages << PAGE_SHIFT),
+ numPages << PAGE_SHIFT) < 0)
+ {
+ gcmkTRACE_ZONE(
+ gcvLEVEL_WARNING, gcvZONE_OS,
+ "%s(%d): dma_mmap_attrs error",
+ __FUNCTION__, __LINE__
+ );
+
+ gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
+ }
+ }
+ else
+ {
+ gcmkFATAL("%s(%d): unexpected noncontiguous mdl\n");
+ gcmkONERROR(gcvSTATUS_HEAP_CORRUPTED);
+ }
+
+OnError:
+ gcmkFOOTER();
+ return status;
+}
+
+static void
+_CMAFSLUnmapUser(
+ IN gckALLOCATOR Allocator,
+ IN PLINUX_MDL Mdl,
+ IN PLINUX_MDL_MAP MdlMap,
+ IN gctUINT32 Size
+ )
+{
+ if (unlikely(current->mm == gcvNULL))
+ {
+ /* Do nothing if process is exiting. */
+ return;
+ }
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0)
+ if (vm_munmap((unsigned long)MdlMap->vmaAddr, Size) < 0)
+ {
+ gcmkTRACE_ZONE(
+ gcvLEVEL_WARNING, gcvZONE_OS,
+ "%s(%d): vm_munmap failed",
+ __FUNCTION__, __LINE__
+ );
+ }
+#else
+ down_write(&current->mm->mmap_sem);
+ if (do_munmap(current->mm, (unsigned long)MdlMap->vmaAddr, Size) < 0)
+ {
+ gcmkTRACE_ZONE(
+ gcvLEVEL_WARNING, gcvZONE_OS,
+ "%s(%d): do_munmap failed",
+ __FUNCTION__, __LINE__
+ );
+ }
+ up_write(&current->mm->mmap_sem);
+#endif
+}
+
+static gceSTATUS
+_CMAFSLMapUser(
+ IN gckALLOCATOR Allocator,
+ IN PLINUX_MDL Mdl,
+ IN PLINUX_MDL_MAP MdlMap,
+ IN gctBOOL Cacheable
+ )
+{
+ gctPOINTER userLogical = gcvNULL;
+ gceSTATUS status = gcvSTATUS_OK;
+
+ gcmkHEADER_ARG("Allocator=%p Mdl=%p Cacheable=%d", Allocator, Mdl, Cacheable);
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0)
+ userLogical = (gctPOINTER)vm_mmap(gcvNULL,
+ 0L,
+ Mdl->numPages * PAGE_SIZE,
+ PROT_READ | PROT_WRITE,
+ MAP_SHARED | MAP_NORESERVE,
+ 0);
+#else
+ down_write(&current->mm->mmap_sem);
+ userLogical = (gctPOINTER)do_mmap_pgoff(gcvNULL,
+ 0L,
+ Mdl->numPages * PAGE_SIZE,
+ PROT_READ | PROT_WRITE,
+ MAP_SHARED,
+ 0);
+ up_write(&current->mm->mmap_sem);
+#endif
+
+ gcmkTRACE_ZONE(
+ gcvLEVEL_INFO, gcvZONE_OS,
+ "%s(%d): vmaAddr->%p for phys_addr->%p",
+ __FUNCTION__, __LINE__, userLogical, Mdl
+ );
+
+ if (IS_ERR(userLogical))
+ {
+ gcmkTRACE_ZONE(
+ gcvLEVEL_INFO, gcvZONE_OS,
+ "%s(%d): do_mmap_pgoff error",
+ __FUNCTION__, __LINE__
+ );
+
+ gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
+ }
+
+ down_write(&current->mm->mmap_sem);
+ do
+ {
+ struct vm_area_struct *vma = find_vma(current->mm, (unsigned long)userLogical);
+ if (vma == gcvNULL)
+ {
+ gcmkTRACE_ZONE(
+ gcvLEVEL_INFO, gcvZONE_OS,
+ "%s(%d): find_vma error",
+ __FUNCTION__, __LINE__
+ );
+
+ gcmkERR_BREAK(gcvSTATUS_OUT_OF_RESOURCES);
+ }
+
+ gcmkERR_BREAK(_CMAFSLMmap(Allocator, Mdl, Cacheable, 0, Mdl->numPages, vma));
+ MdlMap->vmaAddr = userLogical;
+ MdlMap->cacheable = Cacheable;
+ MdlMap->vma = vma;
+ }
+ while (gcvFALSE);
+ up_write(&current->mm->mmap_sem);
+
+OnError:
+ if (gcmIS_ERROR(status) && userLogical)
+ {
+ _CMAFSLUnmapUser(Allocator, Mdl, userLogical, Mdl->numPages * PAGE_SIZE);
+ }
+ gcmkFOOTER();
+ return status;
+}
+
+static gceSTATUS
+_CMAMapKernel(
+ IN gckALLOCATOR Allocator,
+ IN PLINUX_MDL Mdl,
+ OUT gctPOINTER *Logical
+ )
+{
+ struct mdl_cma_priv *mdl_priv=(struct mdl_cma_priv *)Mdl->priv;
+ *Logical =mdl_priv->kvaddr;
+ return gcvSTATUS_OK;
+}
+
+static gceSTATUS
+_CMAUnmapKernel(
+ IN gckALLOCATOR Allocator,
+ IN PLINUX_MDL Mdl,
+ IN gctPOINTER Logical
+ )
+{
+ return gcvSTATUS_OK;
+}
+
+static gceSTATUS
+_CMACache(
+ IN gckALLOCATOR Allocator,
+ IN PLINUX_MDL Mdl,
+ IN gctSIZE_T Offset,
+ IN gctPOINTER Logical,
+ IN gctUINT32 Bytes,
+ IN gceCACHEOPERATION Operation
+ )
+{
+ switch (Operation)
+ {
+ case gcvCACHE_CLEAN:
+ case gcvCACHE_FLUSH:
+ _MemoryBarrier();
+ break;
+ case gcvCACHE_INVALIDATE:
+ break;
+ default:
+ return gcvSTATUS_INVALID_ARGUMENT;
+ }
+
+ return gcvSTATUS_OK;
+}
+
+static gceSTATUS
+_CMAPhysical(
+ IN gckALLOCATOR Allocator,
+ IN PLINUX_MDL Mdl,
+ IN gctUINT32 Offset,
+ OUT gctPHYS_ADDR_T * Physical
+ )
+{
+ struct mdl_cma_priv *mdl_priv=(struct mdl_cma_priv *)Mdl->priv;
+
+ *Physical = mdl_priv->physical + Offset;
+
+ return gcvSTATUS_OK;
+}
+
+static void
+_CMAAllocatorDestructor(
+ gcsALLOCATOR *Allocator
+ )
+{
+ _CMAAllocatorDebugfsCleanup(Allocator);
+
+ if (Allocator->privateData)
+ {
+ kfree(Allocator->privateData);
+ }
+
+ kfree(Allocator);
+}
+
+/* Default allocator operations. */
+static gcsALLOCATOR_OPERATIONS CMAFSLAllocatorOperations =
+{
+ .Alloc = _CMAFSLAlloc,
+ .Free = _CMAFSLFree,
+ .Mmap = _CMAFSLMmap,
+ .MapUser = _CMAFSLMapUser,
+ .UnmapUser = _CMAFSLUnmapUser,
+ .MapKernel = _CMAMapKernel,
+ .UnmapKernel = _CMAUnmapKernel,
+ .Cache = _CMACache,
+ .Physical = _CMAPhysical,
+ .GetSGT = _CMAFSLGetSGT,
+};
+
+/* Default allocator entry. */
+gceSTATUS
+_CMAFSLAlloctorInit(
+ IN gckOS Os,
+ IN gcsDEBUGFS_DIR *Parent,
+ OUT gckALLOCATOR * Allocator
+ )
+{
+ gceSTATUS status;
+ gckALLOCATOR allocator = gcvNULL;
+ gcsCMA_PRIV_PTR priv = gcvNULL;
+
+ gcmkONERROR(
+ gckALLOCATOR_Construct(Os, &CMAFSLAllocatorOperations, &allocator));
+
+ priv = kzalloc(gcmSIZEOF(gcsCMA_PRIV), GFP_KERNEL | gcdNOWARN);
+
+ if (!priv)
+ {
+ gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
+ }
+
+ atomic_set(&priv->cmasize, 0);
+
+ /* Register private data. */
+ allocator->privateData = priv;
+ allocator->destructor = _CMAAllocatorDestructor;
+
+ _CMAAllocatorDebugfsInit(allocator, Parent);
+
+ allocator->capability = gcvALLOC_FLAG_CONTIGUOUS
+ | gcvALLOC_FLAG_DMABUF_EXPORTABLE
+#if defined(CONFIG_ZONE_DMA32) && LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)
+ | gcvALLOC_FLAG_4GB_ADDR
+#endif
+ ;
+
+#if defined(CONFIG_ARM64)
+ Os->allocatorLimitMarker = (Os->device->baseAddress + totalram_pages * PAGE_SIZE) > 0x100000000;
+#else
+ Os->allocatorLimitMarker = gcvFALSE;
+#endif
+ priv->cmaLimitRequest = gcvFALSE;
+
+ if (Os->allocatorLimitMarker)
+ {
+ allocator->capability |= gcvALLOC_FLAG_CMA_LIMIT;
+ }
+
+ allocator->capability |= gcvALLOC_FLAG_CMA_PREEMPT;
+
+ *Allocator = allocator;
+
+ return gcvSTATUS_OK;
+
+OnError:
+ if (allocator)
+ {
+ kfree(allocator);
+ }
+ return status;
+}
+
diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_allocator.c b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_allocator.c
new file mode 100644
index 000000000000..0eee49090830
--- /dev/null
+++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_allocator.c
@@ -0,0 +1,260 @@
+/****************************************************************************
+*
+* The MIT License (MIT)
+*
+* Copyright (c) 2014 - 2018 Vivante 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 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 GPL License (GPL)
+*
+* Copyright (C) 2014 - 2018 Vivante 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.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+*****************************************************************************
+*
+* Note: This software is released under dual MIT and GPL licenses. A
+* recipient may use this file under the terms of either the MIT license or
+* GPL License. If you wish to use only one license not the other, you can
+* indicate your decision by deleting one of the above license notices in your
+* version of this file.
+*
+*****************************************************************************/
+
+
+#include "gc_hal_kernel_linux.h"
+#include "gc_hal_kernel_allocator.h"
+#include <linux/pagemap.h>
+#include <linux/seq_file.h>
+#include <linux/mman.h>
+#include <asm/atomic.h>
+#include <linux/dma-mapping.h>
+#include <linux/slab.h>
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 32)
+#include <linux/anon_inodes.h>
+#endif
+#include <linux/file.h>
+
+#include "gc_hal_kernel_allocator_array.h"
+#include "gc_hal_kernel_platform.h"
+
+#define _GC_OBJ_ZONE gcvZONE_OS
+
+
+/******************************************************************************\
+******************************** Debugfs Support *******************************
+\******************************************************************************/
+
+static gceSTATUS
+_AllocatorDebugfsInit(
+ IN gckOS Os
+ )
+{
+ gceSTATUS status;
+ gckGALDEVICE device = Os->device;
+
+ gckDEBUGFS_DIR dir = &Os->allocatorDebugfsDir;
+
+ gcmkONERROR(gckDEBUGFS_DIR_Init(dir, device->debugfsDir.root, "allocators"));
+
+ return gcvSTATUS_OK;
+
+OnError:
+ return status;
+}
+
+static void
+_AllocatorDebugfsCleanup(
+ IN gckOS Os
+ )
+{
+ gckDEBUGFS_DIR dir = &Os->allocatorDebugfsDir;
+
+ gckDEBUGFS_DIR_Deinit(dir);
+}
+
+/***************************************************************************\
+************************ Allocator management *******************************
+\***************************************************************************/
+
+gceSTATUS
+gckOS_ImportAllocators(
+ gckOS Os
+ )
+{
+ gceSTATUS status;
+ gctUINT i;
+ gckALLOCATOR allocator;
+
+ _AllocatorDebugfsInit(Os);
+
+ INIT_LIST_HEAD(&Os->allocatorList);
+
+ for (i = 0; i < gcmCOUNTOF(allocatorArray); i++)
+ {
+ if (allocatorArray[i].construct)
+ {
+ /* Construct allocator. */
+ status = allocatorArray[i].construct(Os, &Os->allocatorDebugfsDir, &allocator);
+
+ if (gcmIS_ERROR(status))
+ {
+ gcmkPRINT("["DEVICE_NAME"]: Can't construct allocator(%s)",
+ allocatorArray[i].name);
+
+ continue;
+ }
+
+ allocator->name = allocatorArray[i].name;
+
+ list_add_tail(&allocator->link, &Os->allocatorList);
+ }
+ }
+
+#if gcdDEBUG
+ list_for_each_entry(allocator, &Os->allocatorList, link)
+ {
+ gcmkTRACE_ZONE(
+ gcvLEVEL_WARNING, gcvZONE_OS,
+ "%s(%d) Allocator: %s",
+ __FUNCTION__, __LINE__,
+ allocator->name
+ );
+ }
+#endif
+
+ return gcvSTATUS_OK;
+}
+
+gceSTATUS
+gckOS_FreeAllocators(
+ gckOS Os
+ )
+{
+ gckALLOCATOR allocator;
+ gckALLOCATOR temp;
+
+ list_for_each_entry_safe(allocator, temp, &Os->allocatorList, link)
+ {
+ list_del(&allocator->link);
+
+ /* Destroy allocator. */
+ allocator->destructor(allocator);
+ }
+
+ _AllocatorDebugfsCleanup(Os);
+
+ return gcvSTATUS_OK;
+}
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION (3,6,0) \
+ || (!defined (ARCH_HAS_SG_CHAIN) && !defined (CONFIG_ARCH_HAS_SG_CHAIN))
+
+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,23)
+static inline void sg_set_page(struct scatterlist *sg, struct page *page,
+ unsigned int len, unsigned int offset)
+{
+ sg->page = page;
+ sg->offset = offset;
+ sg->length = len;
+}
+
+static inline void sg_mark_end(struct scatterlist *sg)
+{
+ (void)sg;
+}
+# endif
+
+int
+alloc_sg_list_from_pages(
+ struct scatterlist **sgl,
+ struct page **pages,
+ unsigned int n_pages,
+ unsigned long offset,
+ unsigned long size,
+ unsigned int *nents
+ )
+{
+ unsigned int chunks;
+ unsigned int i;
+ unsigned int cur_page;
+ struct scatterlist *s;
+
+ chunks = 1;
+
+ for (i = 1; i < n_pages; ++i)
+ {
+ if (page_to_pfn(pages[i]) != page_to_pfn(pages[i - 1]) + 1)
+ {
+ ++chunks;
+ }
+ }
+
+ s = kzalloc(sizeof(struct scatterlist) * chunks, GFP_KERNEL);
+ if (unlikely(!s))
+ {
+ return -ENOMEM;
+ }
+
+ *sgl = s;
+ *nents = chunks;
+
+ cur_page = 0;
+
+ for (i = 0; i < chunks; i++, s++)
+ {
+ unsigned long chunk_size;
+ unsigned int j;
+
+ for (j = cur_page + 1; j < n_pages; j++)
+ {
+ if (page_to_pfn(pages[j]) != page_to_pfn(pages[j - 1]) + 1)
+ {
+ break;
+ }
+ }
+
+ chunk_size = ((j - cur_page) << PAGE_SHIFT) - offset;
+ sg_set_page(s, pages[cur_page], min(size, chunk_size), offset);
+ size -= chunk_size;
+ offset = 0;
+ cur_page = j;
+ }
+
+ sg_mark_end(s - 1);
+
+ return 0;
+}
+#endif
+
diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_allocator.h b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_allocator.h
new file mode 100644
index 000000000000..4d103f1e24cc
--- /dev/null
+++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_allocator.h
@@ -0,0 +1,572 @@
+/****************************************************************************
+*
+* The MIT License (MIT)
+*
+* Copyright (c) 2014 - 2018 Vivante 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 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 GPL License (GPL)
+*
+* Copyright (C) 2014 - 2018 Vivante 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.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+*****************************************************************************
+*
+* Note: This software is released under dual MIT and GPL licenses. A
+* recipient may use this file under the terms of either the MIT license or
+* GPL License. If you wish to use only one license not the other, you can
+* indicate your decision by deleting one of the above license notices in your
+* version of this file.
+*
+*****************************************************************************/
+
+
+#ifndef __gc_hal_kernel_allocator_h_
+#define __gc_hal_kernel_allocator_h_
+
+#include "gc_hal_kernel_linux.h"
+#include <linux/slab.h>
+#include <linux/mm_types.h>
+
+typedef struct _gcsALLOCATOR * gckALLOCATOR;
+typedef union _gcsATTACH_DESC * gcsATTACH_DESC_PTR;
+
+typedef struct _gcsALLOCATOR_OPERATIONS
+{
+ /**************************************************************************
+ **
+ ** Alloc
+ **
+ ** Allocte memory, request size is page aligned.
+ **
+ ** INPUT:
+ **
+ ** gckALLOCATOR Allocator
+ ** Pointer to an gckALLOCATOER object.
+ **
+ ** PLINUX_Mdl
+ ** Pointer to Mdl whichs stores information
+ ** about allocated memory.
+ **
+ ** gctSIZE_T NumPages
+ ** Number of pages need to allocate.
+ **
+ ** gctUINT32 Flag
+ ** Allocation option.
+ **
+ ** OUTPUT:
+ **
+ ** Nothing.
+ **
+ */
+ gceSTATUS
+ (*Alloc)(
+ IN gckALLOCATOR Allocator,
+ IN PLINUX_MDL Mdl,
+ IN gctSIZE_T NumPages,
+ IN gctUINT32 Flag
+ );
+
+ /**************************************************************************
+ **
+ ** Free
+ **
+ ** Free memory.
+ **
+ ** INPUT:
+ **
+ ** gckALLOCATOR Allocator
+ ** Pointer to an gckALLOCATOER object.
+ **
+ ** PLINUX_MDL Mdl
+ ** Mdl which stores information.
+ **
+ ** OUTPUT:
+ **
+ ** Nothing.
+ **
+ */
+ void
+ (*Free)(
+ IN gckALLOCATOR Allocator,
+ IN PLINUX_MDL Mdl
+ );
+
+ /**************************************************************************
+ **
+ ** Mmap
+ **
+ ** Map a page range of the memory to user space.
+ **
+ ** INPUT:
+ ** gckALLOCATOR Allocator
+ ** Pointer to an gckALLOCATOER object.
+ **
+ ** PLINUX_MDL Mdl
+ ** Pointer to a Mdl.
+ **
+ ** gctSIZE_T skipPages
+ ** Number of page to be skipped from beginning of this memory.
+ **
+ ** gctSIZE_T numPages
+ ** Number of pages to be mapped from skipPages.
+ **
+ ** INOUT:
+ **
+ ** struct vm_area_struct *vma
+ ** Pointer to VMM memory area.
+ **
+ */
+ gceSTATUS
+ (*Mmap)(
+ IN gckALLOCATOR Allocator,
+ IN PLINUX_MDL Mdl,
+ IN gctBOOL Cacheable,
+ IN gctSIZE_T skipPages,
+ IN gctSIZE_T numPages,
+ IN struct vm_area_struct *vma
+ );
+
+ /**************************************************************************
+ **
+ ** MapUser
+ **
+ ** Map memory to user space.
+ **
+ ** INPUT:
+ ** gckALLOCATOR Allocator
+ ** Pointer to an gckALLOCATOER object.
+ **
+ ** PLINUX_MDL Mdl
+ ** Pointer to a Mdl.
+ **
+ ** gctBOOL Cacheable
+ ** Whether this mapping is cacheable.
+ **
+ ** OUTPUT:
+ **
+ ** gctPOINTER * UserLogical
+ ** Pointer to user logical address.
+ **
+ ** Nothing.
+ **
+ */
+ gceSTATUS
+ (*MapUser)(
+ IN gckALLOCATOR Allocator,
+ IN PLINUX_MDL Mdl,
+ IN PLINUX_MDL_MAP MdlMap,
+ IN gctBOOL Cacheable
+ );
+
+ /**************************************************************************
+ **
+ ** UnmapUser
+ **
+ ** Unmap address from user address space.
+ **
+ ** INPUT:
+ ** gckALLOCATOR Allocator
+ ** Pointer to an gckALLOCATOER object.
+ **
+ ** gctPOINTER Logical
+ ** Address to be unmap
+ **
+ ** gctUINT32 Size
+ ** Size of address space
+ **
+ ** OUTPUT:
+ **
+ ** Nothing.
+ **
+ */
+ void
+ (*UnmapUser)(
+ IN gckALLOCATOR Allocator,
+ IN PLINUX_MDL Mdl,
+ IN PLINUX_MDL_MAP MdlMap,
+ IN gctUINT32 Size
+ );
+
+ /**************************************************************************
+ **
+ ** MapKernel
+ **
+ ** Map memory to kernel space.
+ **
+ ** INPUT:
+ ** gckALLOCATOR Allocator
+ ** Pointer to an gckALLOCATOER object.
+ **
+ ** PLINUX_MDL Mdl
+ ** Pointer to a Mdl object.
+ **
+ ** OUTPUT:
+ ** gctPOINTER * Logical
+ ** Mapped kernel address.
+ */
+ gceSTATUS
+ (*MapKernel)(
+ IN gckALLOCATOR Allocator,
+ IN PLINUX_MDL Mdl,
+ OUT gctPOINTER *Logical
+ );
+
+ /**************************************************************************
+ **
+ ** UnmapKernel
+ **
+ ** Unmap memory from kernel space.
+ **
+ ** INPUT:
+ ** gckALLOCATOR Allocator
+ ** Pointer to an gckALLOCATOER object.
+ **
+ ** PLINUX_MDL Mdl
+ ** Pointer to a Mdl object.
+ **
+ ** gctPOINTER Logical
+ ** Mapped kernel address.
+ **
+ ** OUTPUT:
+ **
+ ** Nothing.
+ **
+ */
+ gceSTATUS
+ (*UnmapKernel)(
+ IN gckALLOCATOR Allocator,
+ IN PLINUX_MDL Mdl,
+ IN gctPOINTER Logical
+ );
+
+ /**************************************************************************
+ **
+ ** Cache
+ **
+ ** Maintain cache coherency.
+ **
+ ** INPUT:
+ ** gckALLOCATOR Allocator
+ ** Pointer to an gckALLOCATOER object.
+ **
+ ** PLINUX_MDL Mdl
+ ** Pointer to a Mdl object.
+ **
+ ** gctSIZE_T Offset
+ ** Offset to this memory block
+ **
+ ** gctPOINTER Logical
+ ** Logical address, could be user address or kernel address
+ **
+ ** gctUINT32 Bytes
+ ** Size of memory region.
+ **
+ ** gceCACHEOPERATION Opertaion
+ ** Cache operation.
+ **
+ ** OUTPUT:
+ **
+ ** Nothing.
+ **
+ */
+ gceSTATUS (*Cache)(
+ IN gckALLOCATOR Allocator,
+ IN PLINUX_MDL Mdl,
+ IN gctSIZE_T Offset,
+ IN gctPOINTER Logical,
+ IN gctUINT32 Bytes,
+ IN gceCACHEOPERATION Operation
+ );
+
+ /**************************************************************************
+ **
+ ** Physical
+ **
+ ** Get physical address from a offset in memory region.
+ **
+ ** INPUT:
+ ** gckALLOCATOR Allocator
+ ** Pointer to an gckALLOCATOER object.
+ **
+ ** PLINUX_MDL Mdl
+ ** Pointer to a Mdl object.
+ **
+ ** gctUINT32 Offset
+ ** Offset in this memory region.
+ **
+ ** OUTPUT:
+ ** gctUINT32_PTR Physical
+ ** Physical address.
+ **
+ */
+ gceSTATUS (*Physical)(
+ IN gckALLOCATOR Allocator,
+ IN PLINUX_MDL Mdl,
+ IN gctUINT32 Offset,
+ OUT gctPHYS_ADDR_T * Physical
+ );
+
+ /**************************************************************************
+ **
+ ** Attach
+ **
+ ** Import memory allocated by an external allocator.
+ **
+ ** INPUT:
+ ** gckALLOCATOR Allocator
+ ** Pointer to an gckALLOCATOER object.
+ **
+ ** gctUINT32 Handle
+ ** Handle of the memory.
+ **
+ ** OUTPUT:
+ ** None.
+ **
+ */
+ gceSTATUS (*Attach)(
+ IN gckALLOCATOR Allocator,
+ IN gcsATTACH_DESC_PTR Desc,
+ OUT PLINUX_MDL Mdl
+ );
+
+ /**************************************************************************
+ **
+ ** GetSGT
+ **
+ ** Get scatter-gather table from a range of the memory.
+ **
+ ** INPUT:
+ ** gckALLOCATOR Allocator
+ ** Pointer to an gckALLOCATOER object.
+ **
+ ** gctUINT32 Handle
+ ** Handle of the memory.
+ **
+ ** gctSIZE_T Offset
+ ** Offset to the beginning of this mdl.
+ **
+ ** gctSIZE_T Bytes
+ ** Total bytes form Offset.
+ **
+ ** OUTPUT:
+ ** gctPOINTER *SGT
+ ** scatter-gather table
+ **
+ */
+ gceSTATUS (*GetSGT)(
+ IN gckALLOCATOR Allocator,
+ IN PLINUX_MDL Mdl,
+ IN gctSIZE_T Offset,
+ IN gctSIZE_T Bytes,
+ OUT gctPOINTER *SGT
+ );
+}
+gcsALLOCATOR_OPERATIONS;
+
+typedef struct _gcsALLOCATOR
+{
+ /* Pointer to gckOS Object. */
+ gckOS os;
+
+ /* Name. */
+ gctSTRING name;
+
+ /* Operations. */
+ gcsALLOCATOR_OPERATIONS * ops;
+
+ /* Capability of this allocator. */
+ gctUINT32 capability;
+
+ /* Debugfs entry of this allocator. */
+ gcsDEBUGFS_DIR debugfsDir;
+
+ /* Private data used by customer allocator. */
+ void * privateData;
+
+ /* Allocator destructor. */
+ void (*destructor)(struct _gcsALLOCATOR *);
+
+ struct list_head link;
+}
+gcsALLOCATOR;
+
+typedef struct _gcsALLOCATOR_DESC
+{
+ /* Name of a allocator. */
+ char * name;
+
+ /* Entry function to construct a allocator. */
+ gceSTATUS (*construct)(gckOS, gcsDEBUGFS_DIR *, gckALLOCATOR *);
+}
+gcsALLOCATOR_DESC;
+
+typedef union _gcsATTACH_DESC
+{
+ /* gcvALLOC_FLAG_DMABUF */
+ struct
+ {
+ gctPOINTER dmabuf;
+ }
+ dmaBuf;
+
+ /* gcvALLOC_FLAG_USERMEMORY */
+ struct
+ {
+ gctPOINTER memory;
+ gctPHYS_ADDR_T physical;
+ gctSIZE_T size;
+ }
+ userMem;
+
+ /* gcvALLOC_FLAG_EXTERNAL_MEMORY */
+ struct
+ {
+ gcsEXTERNAL_MEMORY_INFO info;
+ }
+ externalMem;
+
+ /* Reserved memory. */
+ struct
+ {
+ unsigned long start;
+ unsigned long size;
+ const char * name;
+ int requested;
+ }
+ reservedMem;
+}
+gcsATTACH_DESC;
+
+/*
+* Helpers
+*/
+
+/* Fill a gcsALLOCATOR_DESC structure. */
+#define gcmkDEFINE_ALLOCATOR_DESC(Name, Construct) \
+ { \
+ .name = Name, \
+ .construct = Construct, \
+ }
+
+/* Construct a allocator. */
+static inline gceSTATUS
+gckALLOCATOR_Construct(
+ IN gckOS Os,
+ IN gcsALLOCATOR_OPERATIONS * Operations,
+ OUT gckALLOCATOR * Allocator
+ )
+{
+ gceSTATUS status;
+ gckALLOCATOR allocator;
+
+ gcmkASSERT(Allocator != gcvNULL);
+ gcmkASSERT
+ ( Operations
+ && (Operations->Alloc || Operations->Attach)
+ && (Operations->Free)
+ && Operations->MapUser
+ && Operations->UnmapUser
+ && Operations->MapKernel
+ && Operations->UnmapKernel
+ && Operations->Cache
+ && Operations->Physical
+ );
+
+ allocator = kzalloc(sizeof(gcsALLOCATOR), GFP_KERNEL | gcdNOWARN);
+ if (unlikely(!allocator))
+ {
+ gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
+ }
+
+ /* Record os. */
+ allocator->os = Os;
+
+ /* Set operations. */
+ allocator->ops = Operations;
+
+ *Allocator = allocator;
+
+ return gcvSTATUS_OK;
+
+OnError:
+ return status;
+}
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION (3,6,0) \
+ || (!defined (ARCH_HAS_SG_CHAIN) && !defined (CONFIG_ARCH_HAS_SG_CHAIN))
+int
+alloc_sg_list_from_pages(
+ struct scatterlist **sgl,
+ struct page **pages,
+ unsigned int n_pages,
+ unsigned long offset,
+ unsigned long size,
+ unsigned int *nents
+ );
+#endif
+
+/*
+ How to implement customer allocator
+
+ Build in customer alloctor
+
+ It is recommanded that customer allocator is implmented in independent
+ source file(s) which is specified by CUSOMTER_ALLOCATOR_OBJS in Kbuld.
+
+ Register gcsALLOCATOR
+
+ For each customer specified allocator, a desciption entry must be added
+ to allocatorArray defined in gc_hal_kernel_allocator_array.h.
+
+ An entry in allocatorArray is a gcsALLOCATOR_DESC structure which describes
+ name and constructor of a gckALLOCATOR object.
+
+
+ Implement gcsALLOCATOR_DESC.init()
+
+ In gcsALLOCATOR_DESC.init(), gckALLOCATOR_Construct should be called
+ to create a gckALLOCATOR object, customer specified private data can
+ be put in gcsALLOCATOR.privateData.
+
+
+ Implement gcsALLOCATOR_OPERATIONS
+
+ When call gckALLOCATOR_Construct to create a gckALLOCATOR object, a
+ gcsALLOCATOR_OPERATIONS structure must be provided whose all members
+ implemented.
+
+*/
+#endif
diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_debug.h b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_debug.h
new file mode 100644
index 000000000000..ee80046bffd6
--- /dev/null
+++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_debug.h
@@ -0,0 +1,151 @@
+/****************************************************************************
+*
+* The MIT License (MIT)
+*
+* Copyright (c) 2014 - 2018 Vivante 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 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 GPL License (GPL)
+*
+* Copyright (C) 2014 - 2018 Vivante 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.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+*****************************************************************************
+*
+* Note: This software is released under dual MIT and GPL licenses. A
+* recipient may use this file under the terms of either the MIT license or
+* GPL License. If you wish to use only one license not the other, you can
+* indicate your decision by deleting one of the above license notices in your
+* version of this file.
+*
+*****************************************************************************/
+
+
+#ifndef __gc_hal_kernel_debug_h_
+#define __gc_hal_kernel_debug_h_
+
+#include <gc_hal_kernel_linux.h>
+#include <linux/spinlock.h>
+#include <linux/time.h>
+#include <stdarg.h>
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,14,0)
+#include <linux/nmi.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/******************************************************************************\
+****************************** OS-dependent Macros *****************************
+\******************************************************************************/
+
+typedef va_list gctARGUMENTS;
+
+#define gcmkARGUMENTS_START(Arguments, Pointer) \
+ va_start(Arguments, Pointer)
+
+#define gcmkARGUMENTS_END(Arguments) \
+ va_end(Arguments)
+
+#define gcmkARGUMENTS_ARG(Arguments, Type) \
+ va_arg(Arguments, Type)
+
+#define gcmkDECLARE_MUTEX(__mutex__) \
+ DEFINE_MUTEX(__mutex__); \
+
+#define gcmkMUTEX_LOCK(__mutex__) \
+ mutex_lock(&__mutex__);
+
+#define gcmkMUTEX_UNLOCK(__mutex__) \
+ mutex_unlock(&__mutex__);
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
+# define gcmkGETPROCESSID() \
+ task_tgid_vnr(current)
+#else
+# define gcmkGETPROCESSID() \
+ current->tgid
+#endif
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
+# define gcmkGETTHREADID() \
+ task_pid_vnr(current)
+#else
+# define gcmkGETTHREADID() \
+ current->pid
+#endif
+
+#define gcmkOUTPUT_STRING(String) \
+ if (gckDEBUGFS_IsEnabled()) \
+ { \
+ while (-ERESTARTSYS == gckDEBUGFS_Print(String)); \
+ } \
+ else \
+ { \
+ printk(String); \
+ }
+
+#define gcmkSPRINTF(Destination, Size, Message, Value) \
+ snprintf(Destination, Size, Message, Value)
+
+#define gcmkSPRINTF2(Destination, Size, Message, Value1, Value2) \
+ snprintf(Destination, Size, Message, Value1, Value2)
+
+#define gcmkSPRINTF3(Destination, Size, Message, Value1, Value2, Value3) \
+ snprintf(Destination, Size, Message, Value1, Value2, Value3)
+
+#define gcmkVSPRINTF(Destination, Size, Message, Arguments) \
+ vsnprintf(Destination, Size, Message, *((va_list*)Arguments))
+
+#define gcmkSTRCATSAFE(Destination, Size, String) \
+ strncat(Destination, String, (Size) - 1)
+
+#define gcmkMEMCPY(Destination, Source, Size) \
+ memcpy(Destination, Source, Size)
+
+#define gcmkSTRLEN(String) \
+ strlen(String)
+
+/* If not zero, forces data alignment in the variable argument list
+ by its individual size. */
+#define gcdALIGNBYSIZE 1
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __gc_hal_kernel_debug_h_ */
diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_debugfs.c b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_debugfs.c
new file mode 100644
index 000000000000..885eec644bb0
--- /dev/null
+++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_debugfs.c
@@ -0,0 +1,965 @@
+/****************************************************************************
+*
+* The MIT License (MIT)
+*
+* Copyright (c) 2014 - 2018 Vivante 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 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 GPL License (GPL)
+*
+* Copyright (C) 2014 - 2018 Vivante 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.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+*****************************************************************************
+*
+* Note: This software is released under dual MIT and GPL licenses. A
+* recipient may use this file under the terms of either the MIT license or
+* GPL License. If you wish to use only one license not the other, you can
+* indicate your decision by deleting one of the above license notices in your
+* version of this file.
+*
+*****************************************************************************/
+
+
+#ifdef MODULE
+#include <linux/module.h>
+#endif
+#include <linux/init.h>
+#include <linux/debugfs.h>
+#include <linux/slab.h>
+#ifdef MODVERSIONS
+#include <linux/modversions.h>
+#endif
+#include <linux/stddef.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/timer.h>
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <linux/mutex.h>
+#include <linux/vmalloc.h>
+#include <linux/types.h>
+#include <linux/fs.h>
+#include <linux/poll.h>
+#include <asm/uaccess.h>
+#include <linux/completion.h>
+#include <linux/seq_file.h>
+#include "gc_hal_kernel_linux.h"
+#include "gc_hal_kernel.h"
+#include "gc_hal_kernel_debug.h"
+
+/*
+ Prequsite:
+
+ 1) Debugfs feature must be enabled in the kernel.
+ 1.a) You can enable this, in the compilation of the uImage, all you have to do is, In the "make menuconfig" part,
+ you have to enable the debugfs in the kernel hacking part of the menu.
+
+ HOW TO USE:
+ 1) insert the driver with the following option logFileSize, Ex: insmod galcore.ko ...... logFileSize=10240
+ This gives a circular buffer of 10 MB
+
+ 2)Usually after inserting the driver, the debug file system is mounted under /sys/kernel/debug/
+
+ 2.a)If the debugfs is not mounted, you must do "mount -t debugfs none /sys/kernel/debug"
+
+ 3) To read what is being printed in the debugfs file system:
+ Ex : cat /sys/kernel/debug/gc/galcore_trace
+
+ 4)To write into the debug file system from user side :
+ Ex: echo "hello" > cat /sys/kernel/debug/gc/galcore_trace
+
+ 5)To write into debugfs from kernel side, Use the function called gckDEBUGFS_Print
+
+ How to Get Video Memory Usage:
+ 1) Select a process whose video memory usage can be dump, no need to reset it until <pid> is needed to be change.
+ echo <pid> > /sys/kernel/debug/gc/vidmem
+
+ 2) Get video memory usage.
+ cat /sys/kernel/debug/gc/vidmem
+
+ USECASE Kernel Dump:
+
+ 1) Go to /hal/inc/gc_hal_options.h, and enable the following flags:
+ - # define gcdDUMP 1
+ - # define gcdDUMP_IN_KERNEL 1
+ - # define gcdDUMP_COMMAND 1
+
+ 2) Go to /hal/kernel/gc_hal_kernel_command.c and disable the following flag
+ -#define gcdSIMPLE_COMMAND_DUMP 0
+
+ 3) Compile the driver
+ 4) insmod it with the logFileSize option
+ 5) Run an application
+ 6) You can get the dump by cat /sys/kernel/debug/gpu/galcore_trace
+
+ */
+
+/**/
+typedef va_list gctDBGARGS ;
+#define gcmkARGS_START(argument, pointer) va_start(argument, pointer)
+#define gcmkARGS_END(argument) va_end(argument)
+
+#define gcmkDEBUGFS_PRINT(ArgumentSize, Message) \
+ { \
+ gctDBGARGS __arguments__; \
+ gcmkARGS_START(__arguments__, Message); \
+ _debugfs_res = _DebugFSPrint(ArgumentSize, Message, &__arguments__);\
+ gcmkARGS_END(__arguments__); \
+ }
+
+
+static DEFINE_SPINLOCK(traceLock);
+
+/* Debug File System Node Struct. */
+struct _gcsDEBUGFS_Node
+{
+ /*wait queues for read and write operations*/
+#if defined(DECLARE_WAIT_QUEUE_HEAD)
+ wait_queue_head_t read_q , write_q ;
+#else
+ struct wait_queue *read_q , *write_q ;
+#endif
+ struct dentry *parent ; /*parent directory*/
+ struct dentry *filen ; /*filename*/
+ struct semaphore sem ; /* mutual exclusion semaphore */
+ char *data ; /* The circular buffer data */
+ int size ; /* Size of the buffer pointed to by 'data' */
+ int refcount ; /* Files that have this buffer open */
+ int read_point ; /* Offset in circ. buffer of oldest data */
+ int write_point ; /* Offset in circ. buffer of newest data */
+ int offset ; /* Byte number of read_point in the stream */
+ struct _gcsDEBUGFS_Node *next ;
+
+ caddr_t temp;
+ int tempSize;
+};
+
+/* amount of data in the queue */
+#define gcmkNODE_QLEN(node) ( (node)->write_point >= (node)->read_point ? \
+ (node)->write_point - (node)->read_point : \
+ (node)->size - (node)->read_point + (node)->write_point)
+
+/* byte number of the last byte in the queue */
+#define gcmkNODE_FIRST_EMPTY_BYTE(node) ((node)->offset + gcmkNODE_QLEN(node))
+
+/*Synchronization primitives*/
+#define gcmkNODE_READQ(node) (&((node)->read_q))
+#define gcmkNODE_WRITEQ(node) (&((node)->write_q))
+#define gcmkNODE_SEM(node) (&((node)->sem))
+
+/*Utilities*/
+#define gcmkMIN(x, y) ((x) < (y) ? (x) : y)
+
+/*Debug File System Struct*/
+typedef struct _gcsDEBUGFS_
+{
+ gcsDEBUGFS_Node* linkedlist ;
+ gcsDEBUGFS_Node* currentNode ;
+ int isInited ;
+} gcsDEBUGFS_ ;
+
+/*debug file system*/
+static gcsDEBUGFS_ gc_dbgfs ;
+
+static int gc_debugfs_open(struct inode *inode, struct file *file)
+{
+ gcsINFO_NODE *node = inode->i_private;
+
+ return single_open(file, node->info->show, node);
+}
+
+static ssize_t
+gc_debugfs_write(
+ struct file *file,
+ const char __user *buf,
+ size_t count,
+ loff_t *pos
+ )
+{
+ struct seq_file *s = file->private_data;
+ gcsINFO_NODE *node = s->private;
+ gcsINFO *info = node->info;
+
+ if (info->write)
+ {
+ info->write(buf, count, node);
+ }
+
+ return count;
+}
+
+static const struct file_operations gc_debugfs_operations = {
+ .owner = THIS_MODULE,
+ .open = gc_debugfs_open,
+ .write = gc_debugfs_write,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
+gceSTATUS
+gckDEBUGFS_DIR_Init(
+ IN gckDEBUGFS_DIR Dir,
+ IN struct dentry *root,
+ IN gctCONST_STRING Name
+ )
+{
+ Dir->root = debugfs_create_dir(Name, root);
+
+ if (!Dir->root)
+ {
+ return gcvSTATUS_NOT_SUPPORTED;
+ }
+
+ INIT_LIST_HEAD(&Dir->nodeList);
+
+ return gcvSTATUS_OK;
+}
+
+gceSTATUS
+gckDEBUGFS_DIR_CreateFiles(
+ IN gckDEBUGFS_DIR Dir,
+ IN gcsINFO * List,
+ IN int count,
+ IN gctPOINTER Data
+ )
+{
+ int i;
+ gcsINFO_NODE * node;
+ gceSTATUS status;
+
+ for (i = 0; i < count; i++)
+ {
+ umode_t mode = 0;
+
+ /* Create a node. */
+ node = (gcsINFO_NODE *)kzalloc(sizeof(gcsINFO_NODE), GFP_KERNEL);
+
+ node->info = &List[i];
+ node->device = Data;
+
+ mode |= List[i].show ? S_IRUGO : 0;
+ mode |= List[i].write ? S_IWUSR : 0;
+
+ node->entry = debugfs_create_file(
+ List[i].name, mode, Dir->root, node, &gc_debugfs_operations);
+
+ if (!node->entry)
+ {
+ gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
+ }
+
+ list_add(&(node->head), &(Dir->nodeList));
+ }
+
+ return gcvSTATUS_OK;
+
+OnError:
+ gcmkVERIFY_OK(gckDEBUGFS_DIR_RemoveFiles(Dir, List, count));
+ return status;
+}
+
+gceSTATUS
+gckDEBUGFS_DIR_RemoveFiles(
+ IN gckDEBUGFS_DIR Dir,
+ IN gcsINFO * List,
+ IN int count
+ )
+{
+ int i;
+ gcsINFO_NODE * node;
+ gcsINFO_NODE * temp;
+
+ for (i = 0; i < count; i++)
+ {
+ list_for_each_entry_safe(node, temp, &Dir->nodeList, head)
+ {
+ if (node->info == &List[i])
+ {
+ debugfs_remove(node->entry);
+ list_del(&node->head);
+ kfree(node);
+ }
+ }
+ }
+
+ return gcvSTATUS_OK;
+}
+
+void
+gckDEBUGFS_DIR_Deinit(
+ IN gckDEBUGFS_DIR Dir
+ )
+{
+ if (Dir->root != NULL)
+ {
+ debugfs_remove(Dir->root);
+ Dir->root = NULL;
+ }
+}
+
+/*******************************************************************************
+ **
+ ** READ & WRITE FUNCTIONS (START)
+ **
+ *******************************************************************************/
+
+/*******************************************************************************
+ **
+ ** _ReadFromNode
+ **
+ ** 1) reading bytes out of a circular buffer with wraparound.
+ ** 2)returns caddr_t, pointer to data read, which the caller must free.
+ ** 3) length is (a pointer to) the number of bytes to be read, which will be set by this function to
+ ** be the number of bytes actually returned
+ **
+ *******************************************************************************/
+static caddr_t
+_ReadFromNode (
+ gcsDEBUGFS_Node* Node ,
+ size_t *Length ,
+ loff_t *Offset
+ )
+{
+ caddr_t retval ;
+ int bytes_copied = 0 , n , start_point , remaining ;
+
+ /* find the smaller of the total bytes we have available and what
+ * the user is asking for */
+ *Length = gcmkMIN ( *Length , gcmkNODE_QLEN(Node) ) ;
+
+ remaining = * Length ;
+
+ /* Get start point. */
+ start_point = Node->read_point;
+
+ /* allocate memory to return */
+ if (remaining > Node->tempSize)
+ {
+ kfree(Node->temp);
+
+ if ( ( retval = kmalloc ( sizeof (char ) * remaining , GFP_ATOMIC ) ) == NULL )
+ return NULL;
+
+ Node->temp = retval;
+ Node->tempSize = remaining;
+ }
+ else
+ {
+ retval = Node->temp;
+ }
+
+ /* copy the (possibly noncontiguous) data to our buffer */
+ while ( remaining )
+ {
+ n = gcmkMIN ( remaining , Node->size - start_point ) ;
+ memcpy ( retval + bytes_copied , Node->data + start_point , n ) ;
+ bytes_copied += n ;
+ remaining -= n ;
+ start_point = ( start_point + n ) % Node->size ;
+ }
+
+ /* advance user's file pointer */
+ Node->read_point = (Node->read_point + * Length) % Node->size ;
+
+ return retval ;
+}
+
+/*******************************************************************************
+ **
+ ** _WriteToNode
+ **
+ ** 1) writes to a circular buffer with wraparound.
+ ** 2)in case of an overflow, it overwrites the oldest unread data.
+ **
+ *********************************************************************************/
+static void
+_WriteToNode (
+ gcsDEBUGFS_Node* Node ,
+ caddr_t Buf ,
+ int Length
+ )
+{
+ int bytes_copied = 0 ;
+ int overflow = 0 ;
+ int n ;
+
+ if ( Length + gcmkNODE_QLEN ( Node ) >= ( Node->size - 1 ) )
+ {
+ overflow = 1 ;
+ }
+
+ while ( Length )
+ {
+ /* how many contiguous bytes are available from the write point to
+ * the end of the circular buffer? */
+ n = gcmkMIN ( Length , Node->size - Node->write_point ) ;
+ memcpy ( Node->data + Node->write_point , Buf + bytes_copied , n ) ;
+ bytes_copied += n ;
+ Length -= n ;
+ Node->write_point = ( Node->write_point + n ) % Node->size ;
+ }
+
+ /* if there is an overflow, reset the read point to read whatever is
+ * the oldest data that we have, that has not yet been
+ * overwritten. */
+ if ( overflow )
+ {
+ Node->read_point = ( Node->write_point + 1 ) % Node->size ;
+ }
+}
+
+/*******************************************************************************
+ **
+ ** PRINTING UTILITY (START)
+ **
+ *******************************************************************************/
+
+/*******************************************************************************
+ **
+ ** _GetArgumentSize
+ **
+ **
+ *******************************************************************************/
+static gctINT
+_GetArgumentSize (
+ IN gctCONST_STRING Message
+ )
+{
+ gctINT i , count ;
+
+ for ( i = 0 , count = 0 ; Message[i] ; i += 1 )
+ {
+ if ( Message[i] == '%' )
+ {
+ count += 1 ;
+ }
+ }
+ return count * sizeof (unsigned int ) ;
+}
+
+/*******************************************************************************
+ **
+ ** _AppendString
+ **
+ **
+ *******************************************************************************/
+static ssize_t
+_AppendString (
+ IN gcsDEBUGFS_Node* Node,
+ IN gctCONST_STRING String,
+ IN int Length
+ )
+{
+ int n;
+ unsigned long flags;
+
+ /* if the message is longer than the buffer, just take the beginning
+ * of it, in hopes that the reader (if any) will have time to read
+ * before we wrap around and obliterate it */
+ n = gcmkMIN ( Length , Node->size - 1 );
+
+ spin_lock_irqsave(&traceLock, flags);
+
+ /* now copy it into the circular buffer and free our temp copy */
+ _WriteToNode ( Node , (caddr_t)String , n ) ;
+
+ spin_unlock_irqrestore(&traceLock, flags);
+
+ return n ;
+}
+
+/*******************************************************************************
+ **
+ ** _DebugFSPrint
+ **
+ **
+ *******************************************************************************/
+static ssize_t
+_DebugFSPrint (
+ IN unsigned int ArgumentSize ,
+ IN const char* Message ,
+ IN gctDBGARGS * Arguments
+
+ )
+{
+ char buffer[MAX_LINE_SIZE] ;
+ int len ;
+ ssize_t res = 0;
+
+ if ( gc_dbgfs.currentNode )
+ {
+ len = vsnprintf ( buffer , sizeof (buffer ) , Message , *( va_list * ) Arguments ) ;
+
+ buffer[len] = '\0' ;
+ /* Add end-of-line if missing. */
+ if ( buffer[len - 1] != '\n' )
+ {
+ buffer[len ++] = '\n' ;
+ buffer[len] = '\0' ;
+ }
+
+ res = _AppendString ( gc_dbgfs.currentNode , buffer , len ) ;
+ wake_up_interruptible ( gcmkNODE_READQ ( gc_dbgfs.currentNode ) ) ; /* blocked in read*/
+ }
+
+ return res;
+}
+
+/*******************************************************************************
+ **
+ ** LINUX SYSTEM FUNCTIONS (START)
+ **
+ *******************************************************************************/
+static int
+_DebugFSOpen (
+ struct inode* inode,
+ struct file* filp
+ )
+{
+ filp->private_data = inode->i_private;
+
+ return 0;
+}
+
+/*******************************************************************************
+ **
+ ** _DebugFSRead
+ **
+ *******************************************************************************/
+static ssize_t
+_DebugFSRead (
+ struct file *file,
+ char __user * buffer,
+ size_t length,
+ loff_t * offset
+ )
+{
+ int retval;
+ caddr_t data_to_return;
+ unsigned long flags;
+ gcsDEBUGFS_Node* node = file->private_data;
+
+ if (node == NULL)
+ {
+ printk ( "debugfs_read: record not found\n" );
+ return - EIO ;
+ }
+
+ spin_lock_irqsave(&traceLock, flags);
+
+ /* wait until there's data available (unless we do nonblocking reads) */
+ while (!gcmkNODE_QLEN(node))
+ {
+ spin_unlock_irqrestore(&traceLock, flags);
+
+ if (file->f_flags & O_NONBLOCK)
+ {
+ return - EAGAIN ;
+ }
+
+ if (wait_event_interruptible((*(gcmkNODE_READQ(node))) , (*offset < gcmkNODE_FIRST_EMPTY_BYTE(node))))
+ {
+ return - ERESTARTSYS ; /* signal: tell the fs layer to handle it */
+ }
+
+ spin_lock_irqsave(&traceLock, flags);
+ }
+
+ data_to_return = _ReadFromNode(node , &length , offset);
+
+ spin_unlock_irqrestore(&traceLock, flags);
+
+ if (data_to_return == NULL)
+ {
+ retval = 0;
+ goto unlock;
+ }
+
+ if (copy_to_user(buffer, data_to_return, length) > 0)
+ {
+ retval = - EFAULT;
+ }
+ else
+ {
+ retval = length;
+ }
+unlock:
+
+ wake_up_interruptible(gcmkNODE_WRITEQ(node));
+ return retval ;
+}
+
+/*******************************************************************************
+ **
+ **_DebugFSWrite
+ **
+ *******************************************************************************/
+static ssize_t
+_DebugFSWrite (
+ struct file *file ,
+ const char __user * buffer ,
+ size_t length ,
+ loff_t * offset
+ )
+{
+ caddr_t message = NULL ;
+ int n ;
+ gcsDEBUGFS_Node* node = file->private_data;
+
+ /* get the metadata about this log */
+ if (node == NULL)
+ {
+ return - EIO ;
+ }
+
+ if ( down_interruptible ( gcmkNODE_SEM ( node ) ) )
+ {
+ return - ERESTARTSYS ;
+ }
+
+ /* if the message is longer than the buffer, just take the beginning
+ * of it, in hopes that the reader (if any) will have time to read
+ * before we wrap around and obliterate it */
+ n = gcmkMIN ( length , node->size - 1 ) ;
+
+ /* make sure we have the memory for it */
+ if ( ( message = kmalloc ( n , GFP_KERNEL ) ) == NULL )
+ {
+ up ( gcmkNODE_SEM ( node ) ) ;
+ return - ENOMEM ;
+ }
+
+
+ /* copy into our temp buffer */
+ if ( copy_from_user ( message , buffer , n ) > 0 )
+ {
+ up ( gcmkNODE_SEM ( node ) ) ;
+ kfree ( message ) ;
+ return - EFAULT ;
+ }
+
+ /* now copy it into the circular buffer and free our temp copy */
+ _WriteToNode ( node , message , n ) ;
+
+ kfree ( message ) ;
+ up ( gcmkNODE_SEM ( node ) ) ;
+
+ /* wake up any readers that might be waiting for the data. we call
+ * schedule in the vague hope that a reader will run before the
+ * writer's next write, to avoid losing data. */
+ wake_up_interruptible ( gcmkNODE_READQ ( node ) ) ;
+
+ return n ;
+}
+
+/*******************************************************************************
+ **
+ ** File Operations Table
+ **
+ *******************************************************************************/
+static const struct file_operations debugfs_operations = {
+ .owner = THIS_MODULE ,
+ .open = _DebugFSOpen ,
+ .read = _DebugFSRead ,
+ .write = _DebugFSWrite ,
+} ;
+
+/*******************************************************************************
+ **
+ ** INTERFACE FUNCTIONS (START)
+ **
+ *******************************************************************************/
+
+/*******************************************************************************
+ **
+ ** gckDEBUGFS_IsEnabled
+ **
+ **
+ ** INPUT:
+ **
+ ** OUTPUT:
+ **
+ *******************************************************************************/
+
+
+gctINT
+gckDEBUGFS_IsEnabled ( void )
+{
+ return gc_dbgfs.isInited ;
+}
+/*******************************************************************************
+ **
+ ** gckDEBUGFS_Initialize
+ **
+ **
+ ** INPUT:
+ **
+ ** OUTPUT:
+ **
+ *******************************************************************************/
+
+gctINT
+gckDEBUGFS_Initialize ( void )
+{
+ if ( ! gc_dbgfs.isInited )
+ {
+ gc_dbgfs.linkedlist = gcvNULL ;
+ gc_dbgfs.currentNode = gcvNULL ;
+ gc_dbgfs.isInited = 1 ;
+ }
+ return gc_dbgfs.isInited ;
+}
+/*******************************************************************************
+ **
+ ** gckDEBUGFS_Terminate
+ **
+ **
+ ** INPUT:
+ **
+ ** OUTPUT:
+ **
+ *******************************************************************************/
+
+gctINT
+gckDEBUGFS_Terminate ( void )
+{
+ gcsDEBUGFS_Node * next = gcvNULL ;
+ gcsDEBUGFS_Node * temp = gcvNULL ;
+ if ( gc_dbgfs.isInited )
+ {
+ temp = gc_dbgfs.linkedlist ;
+ while ( temp != gcvNULL )
+ {
+ next = temp->next ;
+ gckDEBUGFS_FreeNode ( temp ) ;
+ kfree ( temp ) ;
+ temp = next ;
+ }
+ gc_dbgfs.isInited = 0 ;
+ }
+ return 0 ;
+}
+
+
+/*******************************************************************************
+ **
+ ** gckDEBUGFS_CreateNode
+ **
+ **
+ ** INPUT:
+ **
+ ** OUTPUT:
+ **
+ ** gckDEBUGFS_FreeNode * Device
+ ** Pointer to a variable receiving the gcsDEBUGFS_Node object pointer on
+ ** success.
+ *********************************************************************************/
+
+gctINT
+gckDEBUGFS_CreateNode (
+ IN gctPOINTER Device,
+ IN gctINT SizeInKB ,
+ IN struct dentry * Root ,
+ IN gctCONST_STRING NodeName ,
+ OUT gcsDEBUGFS_Node **Node
+ )
+{
+ gcsDEBUGFS_Node*node ;
+ /* allocate space for our metadata and initialize it */
+ if ( ( node = kmalloc ( sizeof (gcsDEBUGFS_Node ) , GFP_KERNEL ) ) == NULL )
+ goto struct_malloc_failed ;
+
+ /*Zero it out*/
+ memset ( node , 0 , sizeof (gcsDEBUGFS_Node ) ) ;
+
+ /*Init the sync primitives*/
+#if defined(DECLARE_WAIT_QUEUE_HEAD)
+ init_waitqueue_head ( gcmkNODE_READQ ( node ) ) ;
+#else
+ init_waitqueue ( gcmkNODE_READQ ( node ) ) ;
+#endif
+
+#if defined(DECLARE_WAIT_QUEUE_HEAD)
+ init_waitqueue_head ( gcmkNODE_WRITEQ ( node ) ) ;
+#else
+ init_waitqueue ( gcmkNODE_WRITEQ ( node ) ) ;
+#endif
+ sema_init ( gcmkNODE_SEM ( node ) , 1 ) ;
+ /*End the sync primitives*/
+
+ /*creating the debug file system*/
+ node->parent = Root;
+
+ if (SizeInKB)
+ {
+ /* figure out how much of a buffer this should be and allocate the buffer */
+ node->size = 1024 * SizeInKB ;
+ if ( ( node->data = ( char * ) vmalloc ( sizeof (char ) * node->size ) ) == NULL )
+ goto data_malloc_failed ;
+
+ node->tempSize = 0;
+ node->temp = NULL;
+
+ /*creating the file*/
+ node->filen = debugfs_create_file(NodeName, S_IRUGO|S_IWUSR, node->parent, node,
+ &debugfs_operations);
+ }
+
+ /* add it to our linked list */
+ node->next = gc_dbgfs.linkedlist ;
+ gc_dbgfs.linkedlist = node ;
+
+
+ /* pass the struct back */
+ *Node = node ;
+ return 0 ;
+
+
+data_malloc_failed:
+ kfree ( node ) ;
+struct_malloc_failed:
+ return - ENOMEM ;
+}
+
+/*******************************************************************************
+ **
+ ** gckDEBUGFS_FreeNode
+ **
+ **
+ ** INPUT:
+ **
+ ** OUTPUT:
+ **
+ *******************************************************************************/
+void
+gckDEBUGFS_FreeNode (
+ IN gcsDEBUGFS_Node * Node
+ )
+{
+
+ gcsDEBUGFS_Node **ptr ;
+
+ if ( Node == NULL )
+ {
+ printk ( "null passed to free_vinfo\n" ) ;
+ return ;
+ }
+
+ down ( gcmkNODE_SEM ( Node ) ) ;
+ /*free data*/
+ vfree ( Node->data ) ;
+
+ kfree(Node->temp);
+
+ /*Close Debug fs*/
+ if ( Node->filen )
+ {
+ debugfs_remove ( Node->filen ) ;
+ }
+
+ /* now delete the node from the linked list */
+ ptr = & ( gc_dbgfs.linkedlist ) ;
+ while ( *ptr != Node )
+ {
+ if ( ! *ptr )
+ {
+ printk ( "corrupt info list!\n" ) ;
+ break ;
+ }
+ else
+ ptr = & ( ( **ptr ).next ) ;
+ }
+ *ptr = Node->next ;
+ up ( gcmkNODE_SEM ( Node ) ) ;
+}
+
+/*******************************************************************************
+ **
+ ** gckDEBUGFS_SetCurrentNode
+ **
+ **
+ ** INPUT:
+ **
+ ** OUTPUT:
+ **
+ *******************************************************************************/
+void
+gckDEBUGFS_SetCurrentNode (
+ IN gcsDEBUGFS_Node * Node
+ )
+{
+ gc_dbgfs.currentNode = Node ;
+}
+
+/*******************************************************************************
+ **
+ ** gckDEBUGFS_GetCurrentNode
+ **
+ **
+ ** INPUT:
+ **
+ ** OUTPUT:
+ **
+ *******************************************************************************/
+void
+gckDEBUGFS_GetCurrentNode (
+ OUT gcsDEBUGFS_Node ** Node
+ )
+{
+ *Node = gc_dbgfs.currentNode ;
+}
+
+/*******************************************************************************
+ **
+ ** gckDEBUGFS_Print
+ **
+ **
+ ** INPUT:
+ **
+ ** OUTPUT:
+ **
+ *******************************************************************************/
+ssize_t
+gckDEBUGFS_Print (
+ IN gctCONST_STRING Message ,
+ ...
+ )
+{
+ ssize_t _debugfs_res = 0;
+ gcmkDEBUGFS_PRINT ( _GetArgumentSize ( Message ) , Message ) ;
+ return _debugfs_res;
+}
diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_debugfs.h b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_debugfs.h
new file mode 100644
index 000000000000..14a3324442a9
--- /dev/null
+++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_debugfs.h
@@ -0,0 +1,170 @@
+/****************************************************************************
+*
+* The MIT License (MIT)
+*
+* Copyright (c) 2014 - 2018 Vivante 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 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 GPL License (GPL)
+*
+* Copyright (C) 2014 - 2018 Vivante 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.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+*****************************************************************************
+*
+* Note: This software is released under dual MIT and GPL licenses. A
+* recipient may use this file under the terms of either the MIT license or
+* GPL License. If you wish to use only one license not the other, you can
+* indicate your decision by deleting one of the above license notices in your
+* version of this file.
+*
+*****************************************************************************/
+
+
+#include <stdarg.h>
+
+#ifndef __gc_hal_kernel_debugfs_h_
+#define __gc_hal_kernel_debugfs_h_
+
+ #define MAX_LINE_SIZE 768 /* Max bytes for a line of debug info */
+
+
+ typedef struct _gcsDEBUGFS_Node gcsDEBUGFS_Node;
+
+typedef struct _gcsDEBUGFS_DIR *gckDEBUGFS_DIR;
+typedef struct _gcsDEBUGFS_DIR
+{
+ struct dentry * root;
+ struct list_head nodeList;
+}
+gcsDEBUGFS_DIR;
+
+typedef struct _gcsINFO
+{
+ const char * name;
+ int (*show)(struct seq_file*, void*);
+ int (*write)(const char __user *buf, size_t count, void*);
+}
+gcsINFO;
+
+typedef struct _gcsINFO_NODE
+{
+ gcsINFO * info;
+ gctPOINTER device;
+ struct dentry * entry;
+ struct list_head head;
+}
+gcsINFO_NODE;
+
+gceSTATUS
+gckDEBUGFS_DIR_Init(
+ IN gckDEBUGFS_DIR Dir,
+ IN struct dentry *root,
+ IN gctCONST_STRING Name
+ );
+
+gceSTATUS
+gckDEBUGFS_DIR_CreateFiles(
+ IN gckDEBUGFS_DIR Dir,
+ IN gcsINFO * List,
+ IN int count,
+ IN gctPOINTER Data
+ );
+
+gceSTATUS
+gckDEBUGFS_DIR_RemoveFiles(
+ IN gckDEBUGFS_DIR Dir,
+ IN gcsINFO * List,
+ IN int count
+ );
+
+void
+gckDEBUGFS_DIR_Deinit(
+ IN gckDEBUGFS_DIR Dir
+ );
+
+/*******************************************************************************
+ **
+ ** System Related
+ **
+ *******************************************************************************/
+
+gctINT gckDEBUGFS_IsEnabled(void);
+
+gctINT gckDEBUGFS_Initialize(void);
+
+gctINT gckDEBUGFS_Terminate(void);
+
+
+/*******************************************************************************
+ **
+ ** Node Related
+ **
+ *******************************************************************************/
+
+gctINT
+gckDEBUGFS_CreateNode(
+ IN gctPOINTER Device,
+ IN gctINT SizeInKB,
+ IN struct dentry * Root,
+ IN gctCONST_STRING NodeName,
+ OUT gcsDEBUGFS_Node **Node
+ );
+
+void gckDEBUGFS_FreeNode(
+ IN gcsDEBUGFS_Node * Node
+ );
+
+
+
+void gckDEBUGFS_SetCurrentNode(
+ IN gcsDEBUGFS_Node * Node
+ );
+
+
+
+void gckDEBUGFS_GetCurrentNode(
+ OUT gcsDEBUGFS_Node ** Node
+ );
+
+
+ssize_t gckDEBUGFS_Print(
+ IN gctCONST_STRING Message,
+ ...
+ );
+
+#endif
+
+
diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_device.c b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_device.c
new file mode 100644
index 000000000000..773db230cf74
--- /dev/null
+++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_device.c
@@ -0,0 +1,2362 @@
+/****************************************************************************
+*
+* The MIT License (MIT)
+*
+* Copyright (c) 2014 - 2018 Vivante 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 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 GPL License (GPL)
+*
+* Copyright (C) 2014 - 2018 Vivante 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.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+*****************************************************************************
+*
+* Note: This software is released under dual MIT and GPL licenses. A
+* recipient may use this file under the terms of either the MIT license or
+* GPL License. If you wish to use only one license not the other, you can
+* indicate your decision by deleting one of the above license notices in your
+* version of this file.
+*
+*****************************************************************************/
+
+
+#include "gc_hal_kernel_linux.h"
+#include <linux/pagemap.h>
+#include <linux/seq_file.h>
+#include <linux/mman.h>
+#include <linux/slab.h>
+
+#define _GC_OBJ_ZONE gcvZONE_DEVICE
+
+#define DEBUG_FILE "galcore_trace"
+#define PARENT_FILE "gpu"
+
+#define gcdDEBUG_FS_WARN "Experimental debug entry, may be removed in future release, do NOT rely on it!\n"
+
+static gckGALDEVICE galDevice;
+
+extern gcTA globalTA[16];
+
+/******************************************************************************\
+******************************** Debugfs Support *******************************
+\******************************************************************************/
+
+/******************************************************************************\
+***************************** DEBUG SHOW FUNCTIONS *****************************
+\******************************************************************************/
+
+int gc_info_show(struct seq_file* m, void* data)
+{
+ gcsINFO_NODE *node = m->private;
+ gckGALDEVICE device = node->device;
+ int i = 0;
+ gceCHIPMODEL chipModel;
+ gctUINT32 chipRevision;
+ gctUINT32 productID = 0;
+ gctUINT32 ecoID = 0;
+
+ if (!device)
+ return -ENXIO;
+
+ for (i = 0; i < gcdMAX_GPU_COUNT; i++)
+ {
+ if (device->irqLines[i] != -1)
+ {
+#if gcdENABLE_VG
+ if (i == gcvCORE_VG)
+ {
+ chipModel = device->kernels[i]->vg->hardware->chipModel;
+ chipRevision = device->kernels[i]->vg->hardware->chipRevision;
+ }
+ else
+#endif
+ {
+ chipModel = device->kernels[i]->hardware->identity.chipModel;
+ chipRevision = device->kernels[i]->hardware->identity.chipRevision;
+ productID = device->kernels[i]->hardware->identity.productID;
+ ecoID = device->kernels[i]->hardware->identity.ecoID;
+ }
+
+ seq_printf(m, "gpu : %d\n", i);
+ seq_printf(m, "model : %4x\n", chipModel);
+ seq_printf(m, "revision : %4x\n", chipRevision);
+ seq_printf(m, "product : %4x\n", productID);
+ seq_printf(m, "eco : %4x\n", ecoID);
+ seq_printf(m, "\n");
+ }
+ }
+
+ return 0;
+}
+
+int gc_clients_show(struct seq_file* m, void* data)
+{
+ gcsINFO_NODE *node = m->private;
+ gckGALDEVICE device = node->device;
+
+ gckKERNEL kernel = _GetValidKernel(device);
+
+ gcsDATABASE_PTR database;
+ gctINT i, pid;
+ char name[24];
+
+ if (!kernel)
+ return -ENXIO;
+
+ seq_printf(m, "%-8s%s\n", "PID", "NAME");
+ seq_printf(m, "------------------------\n");
+
+ /* Acquire the database mutex. */
+ gcmkVERIFY_OK(
+ gckOS_AcquireMutex(kernel->os, kernel->db->dbMutex, gcvINFINITE));
+
+ /* Walk the databases. */
+ for (i = 0; i < gcmCOUNTOF(kernel->db->db); ++i)
+ {
+ for (database = kernel->db->db[i];
+ database != gcvNULL;
+ database = database->next)
+ {
+ pid = database->processID;
+
+ gcmkVERIFY_OK(gckOS_GetProcessNameByPid(pid, gcmSIZEOF(name), name));
+
+ seq_printf(m, "%-8d%s\n", pid, name);
+ }
+ }
+
+ /* Release the database mutex. */
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(kernel->os, kernel->db->dbMutex));
+
+ /* Success. */
+ return 0;
+}
+
+static void
+_CounterAdd(
+ gcsDATABASE_COUNTERS * Dest,
+ gcsDATABASE_COUNTERS * Src
+ )
+{
+ Dest->bytes += Src->bytes;
+ Dest->maxBytes += Src->maxBytes;
+ Dest->totalBytes += Src->totalBytes;
+}
+
+static void
+_CounterPrint(
+ gcsDATABASE_COUNTERS * Counter,
+ gctCONST_STRING Name,
+ struct seq_file* m
+ )
+{
+ seq_printf(m, " %s:\n", Name);
+ seq_printf(m, " Used : %10llu B\n", Counter->bytes);
+}
+
+int gc_meminfo_show(struct seq_file* m, void* data)
+{
+ gcsINFO_NODE *node = m->private;
+ gckGALDEVICE device = node->device;
+ gckKERNEL kernel = _GetValidKernel(device);
+ gckVIDMEM memory;
+ gceSTATUS status;
+ gcsDATABASE_PTR database;
+ gctUINT32 i;
+
+ gctUINT32 free = 0, used = 0, total = 0, minFree = 0, maxUsed = 0;
+
+ gcsDATABASE_COUNTERS contiguousCounter = {0, 0, 0};
+ gcsDATABASE_COUNTERS virtualCounter = {0, 0, 0};
+ gcsDATABASE_COUNTERS nonPagedCounter = {0, 0, 0};
+
+ if (!kernel)
+ return -ENXIO;
+
+ status = gckKERNEL_GetVideoMemoryPool(kernel, gcvPOOL_SYSTEM, &memory);
+
+ if (gcmIS_SUCCESS(status))
+ {
+ gcmkVERIFY_OK(
+ gckOS_AcquireMutex(memory->os, memory->mutex, gcvINFINITE));
+
+ free = memory->freeBytes;
+ minFree = memory->minFreeBytes;
+ used = memory->bytes - memory->freeBytes;
+ maxUsed = memory->bytes - memory->minFreeBytes;
+ total = memory->bytes;
+
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(memory->os, memory->mutex));
+ }
+
+ seq_printf(m, "VIDEO MEMORY:\n");
+ seq_printf(m, " gcvPOOL_SYSTEM:\n");
+ seq_printf(m, " Free : %10u B\n", free);
+ seq_printf(m, " Used : %10u B\n", used);
+ seq_printf(m, " MinFree : %10u B\n", minFree);
+ seq_printf(m, " MaxUsed : %10u B\n", maxUsed);
+ seq_printf(m, " Total : %10u B\n", total);
+
+ /* Acquire the database mutex. */
+ gcmkVERIFY_OK(
+ gckOS_AcquireMutex(kernel->os, kernel->db->dbMutex, gcvINFINITE));
+
+ /* Walk the databases. */
+ for (i = 0; i < gcmCOUNTOF(kernel->db->db); ++i)
+ {
+ for (database = kernel->db->db[i];
+ database != gcvNULL;
+ database = database->next)
+ {
+ gcsDATABASE_COUNTERS * counter = &database->vidMemPool[gcvPOOL_CONTIGUOUS];
+ _CounterAdd(&contiguousCounter, counter);
+
+ counter = &database->vidMemPool[gcvPOOL_VIRTUAL];
+ _CounterAdd(&virtualCounter, counter);
+
+
+ counter = &database->nonPaged;
+ _CounterAdd(&nonPagedCounter, counter);
+ }
+ }
+
+ /* Release the database mutex. */
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(kernel->os, kernel->db->dbMutex));
+
+ _CounterPrint(&contiguousCounter, "gcvPOOL_CONTIGUOUS", m);
+ _CounterPrint(&virtualCounter, "gcvPOOL_VIRTUAL", m);
+
+ seq_printf(m, "\n");
+
+ seq_printf(m, "NON PAGED MEMORY:\n");
+ seq_printf(m, " Used : %10llu B\n", nonPagedCounter.bytes);
+
+ return 0;
+}
+
+static int
+_ShowRecord(
+ IN struct seq_file *File,
+ IN gcsDATABASE_RECORD_PTR Record
+ )
+{
+ static const char * recordTypes[gcvDB_NUM_TYPES] = {
+ "Unknown",
+ "VideoMemory",
+ "CommandBuffer",
+ "NonPaged",
+ "Contiguous",
+ "Signal",
+ "VidMemLock",
+ "Context",
+ "Idel",
+ "MapMemory",
+ "MapUserMemory",
+ "ShBuf",
+ };
+
+ seq_printf(File, "%-14s %3d %16p %16zu %16zu\n",
+ recordTypes[Record->type],
+ Record->kernel->core,
+ Record->data,
+ (size_t) Record->physical,
+ Record->bytes
+ );
+
+ return 0;
+}
+
+static int
+_ShowRecords(
+ IN struct seq_file *File,
+ IN gcsDATABASE_PTR Database
+ )
+{
+ gctUINT i;
+
+ seq_printf(File, "Records:\n");
+
+ seq_printf(File, "%14s %3s %16s %16s %16s\n",
+ "Type", "GPU", "Data/Node", "Physical/Node", "Bytes");
+
+ for (i = 0; i < gcmCOUNTOF(Database->list); i++)
+ {
+ gcsDATABASE_RECORD_PTR record = Database->list[i];
+
+ while (record != NULL)
+ {
+ _ShowRecord(File, record);
+ record = record->next;
+ }
+ }
+
+ return 0;
+}
+
+static void
+_ShowCounters(
+ struct seq_file *File,
+ gcsDATABASE_PTR Database
+ )
+{
+ gctUINT i = 0;
+
+ static const char * surfaceTypes[gcvSURF_NUM_TYPES] = {
+ "Unknown",
+ "Index",
+ "Vertex",
+ "Texture",
+ "RenderTarget",
+ "Depth",
+ "Bitmap",
+ "TileStatus",
+ "Image",
+ "Mask",
+ "Scissor",
+ "HZ",
+ "ICache",
+ "TxDesc",
+ "Fence",
+ "TFBHeader",
+ };
+
+ static const char * poolTypes[gcvPOOL_NUMBER_OF_POOLS] = {
+ "Unknown",
+ "Default",
+ "Local",
+ "Internal",
+ "External",
+ "Unified",
+ "System",
+ "Virtual",
+ "User",
+ "Contiguous",
+ };
+
+ static const char * otherCounterNames[] = {
+ "AllocNonPaged",
+ "AllocContiguous",
+ "MapUserMemory",
+ "MapMemory",
+ };
+
+ gcsDATABASE_COUNTERS * otherCounters[] = {
+ &Database->nonPaged,
+ &Database->contiguous,
+ &Database->mapUserMemory,
+ &Database->mapMemory,
+ };
+
+ seq_printf(File, "%-16s %16s %16s %16s\n", "", "Current", "Maximum", "Total");
+
+ /* Print surface type counters. */
+ seq_printf(File, "%-16s %16lld %16lld %16lld\n",
+ "All-Types",
+ Database->vidMem.bytes,
+ Database->vidMem.maxBytes,
+ Database->vidMem.totalBytes);
+
+ for (i = 1; i < gcvSURF_NUM_TYPES; i++)
+ {
+ seq_printf(File, "%-16s %16lld %16lld %16lld\n",
+ surfaceTypes[i],
+ Database->vidMemType[i].bytes,
+ Database->vidMemType[i].maxBytes,
+ Database->vidMemType[i].totalBytes);
+ }
+ seq_puts(File, "\n");
+
+ /* Print surface pool counters. */
+ seq_printf(File, "%-16s %16lld %16lld %16lld\n",
+ "All-Pools",
+ Database->vidMem.bytes,
+ Database->vidMem.maxBytes,
+ Database->vidMem.totalBytes);
+
+ for (i = 1; i < gcvPOOL_NUMBER_OF_POOLS; i++)
+ {
+ seq_printf(File, "%-16s %16lld %16lld %16lld\n",
+ poolTypes[i],
+ Database->vidMemPool[i].bytes,
+ Database->vidMemPool[i].maxBytes,
+ Database->vidMemPool[i].totalBytes);
+ }
+ seq_puts(File, "\n");
+
+ /* Print other counters. */
+ for (i = 0; i < gcmCOUNTOF(otherCounterNames); i++)
+ {
+ seq_printf(File, "%-16s %16lld %16lld %16lld\n",
+ otherCounterNames[i],
+ otherCounters[i]->bytes,
+ otherCounters[i]->maxBytes,
+ otherCounters[i]->totalBytes);
+ }
+ seq_puts(File, "\n");
+}
+
+static void
+_ShowProcess(
+ IN struct seq_file *File,
+ IN gcsDATABASE_PTR Database
+ )
+{
+ gctINT pid;
+ char name[24];
+
+ /* Process ID and name */
+ pid = Database->processID;
+ gcmkVERIFY_OK(gckOS_GetProcessNameByPid(pid, gcmSIZEOF(name), name));
+
+ seq_printf(File, "--------------------------------------------------------------------------------\n");
+ seq_printf(File, "Process: %-8d %s\n", pid, name);
+
+ /* Detailed records */
+ _ShowRecords(File, Database);
+
+ seq_printf(File, "Counters:\n");
+
+ _ShowCounters(File, Database);
+}
+
+static void
+_ShowProcesses(
+ IN struct seq_file * File,
+ IN gckKERNEL Kernel
+ )
+{
+ gcsDATABASE_PTR database;
+ gctINT i;
+ static gctUINT64 idleTime = 0;
+
+ /* Acquire the database mutex. */
+ gcmkVERIFY_OK(
+ gckOS_AcquireMutex(Kernel->os, Kernel->db->dbMutex, gcvINFINITE));
+
+ if (Kernel->db->idleTime)
+ {
+ /* Record idle time if DB upated. */
+ idleTime = Kernel->db->idleTime;
+ Kernel->db->idleTime = 0;
+ }
+
+ /* Idle time since last call */
+ seq_printf(File, "GPU Idle: %llu ns\n", idleTime);
+
+ /* Walk the databases. */
+ for (i = 0; i < gcmCOUNTOF(Kernel->db->db); ++i)
+ {
+ for (database = Kernel->db->db[i];
+ database != gcvNULL;
+ database = database->next)
+ {
+ _ShowProcess(File, database);
+ }
+ }
+
+ /* Release the database mutex. */
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, Kernel->db->dbMutex));
+}
+
+static int
+gc_db_show(struct seq_file *m, void *data)
+{
+ gcsINFO_NODE *node = m->private;
+ gckGALDEVICE device = node->device;
+ gckKERNEL kernel = _GetValidKernel(device);
+
+ if (!kernel)
+ return -ENXIO;
+
+ _ShowProcesses(m, kernel);
+ return 0 ;
+}
+
+static int
+gc_version_show(struct seq_file *m, void *data)
+{
+ gcsINFO_NODE *node = m->private;
+ gckGALDEVICE device = node->device;
+ gcsPLATFORM * platform = gcvNULL;
+
+ if (!device)
+ return -ENXIO;
+
+ platform = device->platform;
+
+ if (!platform)
+ return -ENXIO;
+
+ seq_printf(m, "%s built at %s\n", gcvVERSION_STRING, HOST);
+
+ if (platform->name)
+ {
+ seq_printf(m, "Platform path: %s\n", platform->name);
+ }
+ else
+ {
+ seq_printf(m, "Code path: %s\n", __FILE__);
+ }
+
+ return 0 ;
+}
+
+/*******************************************************************************
+**
+** Show PM state timer.
+**
+** Entry is called as 'idle' for compatible reason, it shows more information
+** than idle actually.
+**
+** Start: Start time of this counting period.
+** End: End time of this counting peroid.
+** On: Time GPU stays in gcvPOWER_0N.
+** Off: Time GPU stays in gcvPOWER_0FF.
+** Idle: Time GPU stays in gcvPOWER_IDLE.
+** Suspend: Time GPU stays in gcvPOWER_SUSPEND.
+*/
+static int
+gc_idle_show(struct seq_file *m, void *data)
+{
+ gcsINFO_NODE *node = m->private;
+ gckGALDEVICE device = node->device;
+ gckKERNEL kernel = _GetValidKernel(device);
+
+ gctUINT64 start;
+ gctUINT64 end;
+ gctUINT64 on;
+ gctUINT64 off;
+ gctUINT64 idle;
+ gctUINT64 suspend;
+
+ if (!kernel)
+ return -ENXIO;
+
+ gckHARDWARE_QueryStateTimer(kernel->hardware, &start, &end, &on, &off, &idle, &suspend);
+
+ /* Idle time since last call */
+ seq_printf(m, "Start: %llu ns\n", start);
+ seq_printf(m, "End: %llu ns\n", end);
+ seq_printf(m, "On: %llu ns\n", on);
+ seq_printf(m, "Off: %llu ns\n", off);
+ seq_printf(m, "Idle: %llu ns\n", idle);
+ seq_printf(m, "Suspend: %llu ns\n", suspend);
+
+ return 0 ;
+}
+
+extern void
+_DumpState(
+ IN gckKERNEL Kernel
+ );
+
+/*******************************************************************************
+**
+** Show PM state timer.
+**
+** Entry is called as 'idle' for compatible reason, it shows more information
+** than idle actually.
+**
+** Start: Start time of this counting period.
+** End: End time of this counting peroid.
+** On: Time GPU stays in gcvPOWER_0N.
+** Off: Time GPU stays in gcvPOWER_0FF.
+** Idle: Time GPU stays in gcvPOWER_IDLE.
+** Suspend: Time GPU stays in gcvPOWER_SUSPEND.
+*/
+
+static int dumpCore = 0;
+
+static int
+gc_dump_trigger_show(struct seq_file *m, void *data)
+{
+#if gcdENABLE_3D || gcdENABLE_2D
+ gcsINFO_NODE *node = m->private;
+ gckGALDEVICE device = node->device;
+ gckKERNEL kernel = gcvNULL;
+
+ if (dumpCore >= gcvCORE_MAJOR && dumpCore < gcvCORE_COUNT)
+ {
+ kernel = device->kernels[dumpCore];
+ }
+
+ if (!kernel)
+ return -ENXIO;
+
+#endif
+
+ seq_printf(m, gcdDEBUG_FS_WARN);
+
+#if gcdENABLE_3D || gcdENABLE_2D
+ seq_printf(m, "Get dump from /proc/kmsg or /sys/kernel/debug/gc/galcore_trace\n");
+
+ if (kernel && kernel->hardware->options.powerManagement == gcvFALSE)
+ {
+ _DumpState(kernel);
+ }
+#endif
+
+ return 0;
+}
+
+static int dumpProcess = 0;
+
+
+static int gc_vidmem_show(struct seq_file *m, void *unused)
+{
+ gceSTATUS status;
+ gcsDATABASE_PTR database;
+ gcsINFO_NODE *node = m->private;
+ gckGALDEVICE device = node->device;
+ char name[64];
+ int i;
+
+ gckKERNEL kernel = _GetValidKernel(device);
+
+ if (!kernel)
+ return -ENXIO;
+
+ if (dumpProcess == 0)
+ {
+ /* Acquire the database mutex. */
+ gcmkVERIFY_OK(
+ gckOS_AcquireMutex(kernel->os, kernel->db->dbMutex, gcvINFINITE));
+
+ for (i = 0; i < gcmCOUNTOF(kernel->db->db); i++)
+ {
+ for (database = kernel->db->db[i];
+ database != gcvNULL;
+ database = database->next)
+ {
+ gckOS_GetProcessNameByPid(database->processID, gcmSIZEOF(name), name);
+ seq_printf(m, "VidMem Usage (Process %d: %s):\n", database->processID, name);
+ _ShowCounters(m, database);
+ seq_puts(m, "\n");
+ }
+ }
+
+ /* Release the database mutex. */
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(kernel->os, kernel->db->dbMutex));
+ }
+ else
+ {
+ /* Find the database. */
+ status = gckKERNEL_FindDatabase(kernel, dumpProcess, gcvFALSE, &database);
+
+ if (gcmIS_ERROR(status))
+ {
+ seq_printf(m, "ERROR: process %d not found\n", dumpProcess);
+ return 0;
+ }
+
+ gckOS_GetProcessNameByPid(dumpProcess, gcmSIZEOF(name), name);
+ seq_printf(m, "VidMem Usage (Process %d: %s):\n", dumpProcess, name);
+ _ShowCounters(m, database);
+ }
+
+ return 0;
+}
+
+static inline int strtoint_from_user(const char __user *s,
+ size_t count, int *res)
+{
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0)
+ int ret = kstrtoint_from_user(s, count, 10, res);
+
+ return ret < 0 ? ret : count;
+#else
+ /* sign, base 2 representation, newline, terminator */
+ char buf[1 + sizeof(long) * 8 + 1 + 1];
+
+ size_t len = min(count, sizeof(buf) - 1);
+
+ if (copy_from_user(buf, s, len))
+ return -EFAULT;
+ buf[len] = '\0';
+
+ *res = (int) simple_strtol(buf, NULL, 0);
+
+ return count;
+#endif
+}
+
+static int gc_vidmem_write(const char __user *buf, size_t count, void* data)
+{
+ return strtoint_from_user(buf, count, &dumpProcess);
+}
+
+static int gc_dump_trigger_write(const char __user *buf, size_t count, void* data)
+{
+ return strtoint_from_user(buf, count, &dumpCore);
+}
+
+static int gc_clk_show(struct seq_file* m, void* data)
+{
+ gcsINFO_NODE *node = m->private;
+ gckGALDEVICE device = node->device;
+ gctUINT i;
+ gceSTATUS status;
+
+ for (i = gcvCORE_MAJOR; i < gcvCORE_COUNT; i++)
+ {
+ if (device->kernels[i])
+ {
+ gckHARDWARE hardware = device->kernels[i]->hardware;
+
+#if gcdENABLE_VG
+ if (i == gcvCORE_VG)
+ {
+ continue;
+ }
+#endif
+
+ status = gckHARDWARE_QueryFrequency(hardware);
+ if (gcmIS_ERROR(status))
+ {
+ seq_printf(m, "query gpu%d clock fail.\n", i);
+ continue;
+ }
+
+ if (hardware->mcClk)
+ {
+ seq_printf(m, "gpu%d mc clock: %d HZ.\n", i, hardware->mcClk);
+ }
+
+ if (hardware->shClk)
+ {
+ seq_printf(m, "gpu%d sh clock: %d HZ.\n", i, hardware->shClk);
+ }
+ }
+ }
+
+ return 0;
+}
+
+static gcsINFO InfoList[] =
+{
+ {"info", gc_info_show},
+ {"clients", gc_clients_show},
+ {"meminfo", gc_meminfo_show},
+ {"idle", gc_idle_show},
+ {"database", gc_db_show},
+ {"version", gc_version_show},
+ {"vidmem", gc_vidmem_show, gc_vidmem_write},
+ {"dump_trigger", gc_dump_trigger_show, gc_dump_trigger_write},
+ {"clk", gc_clk_show},
+};
+
+static gceSTATUS
+_DebugfsInit(
+ IN gckGALDEVICE Device
+ )
+{
+ gceSTATUS status;
+
+ gckDEBUGFS_DIR dir = &Device->debugfsDir;
+
+ gcmkONERROR(gckDEBUGFS_DIR_Init(dir, gcvNULL, "gc"));
+
+ gcmkONERROR(gckDEBUGFS_DIR_CreateFiles(dir, InfoList, gcmCOUNTOF(InfoList), Device));
+
+ return gcvSTATUS_OK;
+
+OnError:
+ return status;
+}
+
+static void
+_DebugfsCleanup(
+ IN gckGALDEVICE Device
+ )
+{
+ gckDEBUGFS_DIR dir = &Device->debugfsDir;
+
+ if (Device->debugfsDir.root)
+ {
+ gcmkVERIFY_OK(gckDEBUGFS_DIR_RemoveFiles(dir, InfoList, gcmCOUNTOF(InfoList)));
+
+ gckDEBUGFS_DIR_Deinit(dir);
+ }
+}
+
+
+/******************************************************************************\
+*************************** Memory Allocation Wrappers *************************
+\******************************************************************************/
+
+static gceSTATUS
+_AllocateMemory(
+ IN gckGALDEVICE Device,
+ IN gctSIZE_T Bytes,
+ OUT gctPOINTER *Logical,
+ OUT gctPHYS_ADDR *Physical,
+ OUT gctUINT32 *PhysAddr
+ )
+{
+ gceSTATUS status;
+ gctPHYS_ADDR_T physAddr;
+
+ gcmkHEADER_ARG("Device=0x%x Bytes=%lu", Device, Bytes);
+
+ gcmkVERIFY_ARGUMENT(Device != NULL);
+ gcmkVERIFY_ARGUMENT(Logical != NULL);
+ gcmkVERIFY_ARGUMENT(Physical != NULL);
+ gcmkVERIFY_ARGUMENT(PhysAddr != NULL);
+
+ gcmkONERROR(gckOS_AllocateContiguous(
+ Device->os, gcvFALSE, &Bytes, Physical, Logical
+ ));
+
+ gcmkONERROR(gckOS_GetPhysicalAddress(
+ Device->os, *Logical, &physAddr
+ ));
+
+ gcmkSAFECASTPHYSADDRT(*PhysAddr, physAddr);
+
+ /* Success. */
+ gcmkFOOTER_ARG(
+ "*Logical=0x%x *Physical=0x%x *PhysAddr=0x%08x",
+ *Logical, *Physical, *PhysAddr
+ );
+
+ return gcvSTATUS_OK;
+
+OnError:
+ gcmkFOOTER();
+ return status;
+}
+
+static gceSTATUS
+_FreeMemory(
+ IN gckGALDEVICE Device,
+ IN gctPOINTER Logical,
+ IN gctPHYS_ADDR Physical)
+{
+ gceSTATUS status;
+
+ gcmkHEADER_ARG("Device=0x%x Logical=0x%x Physical=0x%x",
+ Device, Logical, Physical);
+
+ gcmkVERIFY_ARGUMENT(Device != NULL);
+
+ status = gckOS_FreeContiguous(
+ Device->os, Physical, Logical,
+ ((PLINUX_MDL) Physical)->numPages * PAGE_SIZE
+ );
+
+ gcmkFOOTER();
+ return status;
+}
+
+static gceSTATUS
+_SetupVidMem(
+ IN gckGALDEVICE Device,
+ IN gctUINT32 ContiguousBase,
+ IN gctSIZE_T ContiguousSize,
+ IN gctSIZE_T BankSize,
+ IN gcsDEVICE_CONSTRUCT_ARGS * Args
+ )
+{
+ gceSTATUS status;
+ gctUINT32 physAddr = ~0U;
+ gckGALDEVICE device = Device;
+
+ /* set up the contiguous memory */
+ device->contiguousBase = ContiguousBase;
+ device->contiguousSize = ContiguousSize;
+
+ if (ContiguousSize > 0)
+ {
+ if (ContiguousBase == 0)
+ {
+ while (device->contiguousSize > 0)
+ {
+ /* Allocate contiguous memory. */
+ status = _AllocateMemory(
+ device,
+ device->contiguousSize,
+ &device->contiguousLogical,
+ &device->contiguousPhysical,
+ &physAddr
+ );
+
+ if (gcmIS_SUCCESS(status))
+ {
+ status = gckVIDMEM_Construct(
+ device->os,
+ physAddr | device->systemMemoryBaseAddress,
+ device->contiguousSize,
+ 64,
+ BankSize,
+ &device->contiguousVidMem
+ );
+
+ if (gcmIS_SUCCESS(status))
+ {
+ device->contiguousVidMem->physical = device->contiguousPhysical;
+ device->contiguousBase = physAddr;
+ break;
+ }
+
+ gcmkONERROR(_FreeMemory(
+ device,
+ device->contiguousLogical,
+ device->contiguousPhysical
+ ));
+
+ device->contiguousLogical = gcvNULL;
+ device->contiguousPhysical = gcvNULL;
+ }
+
+ if (device->contiguousSize <= (4 << 20))
+ {
+ device->contiguousSize = 0;
+ }
+ else
+ {
+ device->contiguousSize -= (4 << 20);
+ }
+ }
+ }
+ else
+ {
+ /* Create the contiguous memory heap. */
+ status = gckVIDMEM_Construct(
+ device->os,
+ ContiguousBase | device->systemMemoryBaseAddress,
+ ContiguousSize,
+ 64, BankSize,
+ &device->contiguousVidMem
+ );
+
+ if (gcmIS_ERROR(status))
+ {
+ /* Error, disable contiguous memory pool. */
+ device->contiguousVidMem = gcvNULL;
+ device->contiguousSize = 0;
+ }
+ else
+ {
+ gcmkONERROR(gckOS_RequestReservedMemory(
+ device->os, ContiguousBase, ContiguousSize,
+ "galcore contiguous memory",
+ Args->contiguousRequested,
+ &device->contiguousPhysical
+ ));
+
+ device->contiguousVidMem->physical = device->contiguousPhysical;
+ device->requestedContiguousBase = ContiguousBase;
+ device->requestedContiguousSize = ContiguousSize;
+
+ device->contiguousPhysicalName = 0;
+ device->contiguousSize = ContiguousSize;
+ }
+ }
+ }
+
+ return gcvSTATUS_OK;
+OnError:
+ return status;
+}
+
+void
+_SetupRegisterPhysical(
+ IN gckGALDEVICE Device,
+ IN gcsDEVICE_CONSTRUCT_ARGS * Args
+ )
+{
+ gctINT *irqs = Args->irqs;
+ gctUINT *registerBases = Args->registerBases;
+ gctUINT *registerSizes = Args->registerSizes;
+
+ gctINT i = 0;
+
+ for (i = 0; i < gcvCORE_COUNT; i++)
+ {
+ if (irqs[i] != -1)
+ {
+ Device->requestedRegisterMemBases[i] = registerBases[i];
+ Device->requestedRegisterMemSizes[i] = registerSizes[i];
+
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, _GC_OBJ_ZONE,
+ "Get register base %llx of core %d",
+ registerBases[i], i);
+ }
+ }
+}
+
+/******************************************************************************\
+******************************* Interrupt Handler ******************************
+\******************************************************************************/
+static irqreturn_t isrRoutine(int irq, void *ctxt)
+{
+ gceSTATUS status;
+ gckGALDEVICE device;
+ gceCORE core = (gceCORE)gcmPTR2INT32(ctxt) - 1;
+
+ device = galDevice;
+
+ /* Call kernel interrupt notification. */
+ status = gckKERNEL_Notify(device->kernels[core], gcvNOTIFY_INTERRUPT, gcvTRUE);
+
+ if (gcmIS_SUCCESS(status))
+ {
+ up(&device->semas[core]);
+ return IRQ_HANDLED;
+ }
+
+ return IRQ_NONE;
+}
+
+static int threadRoutine(void *ctxt)
+{
+ gckGALDEVICE device = galDevice;
+ gceCORE core = (gceCORE) gcmPTR2INT32(ctxt);
+ gctUINT i;
+
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_DRIVER,
+ "Starting isr Thread with extension=%p",
+ device);
+
+ if (core != gcvCORE_VG)
+ {
+ /* Make kernel update page table of this thread to include entry related to command buffer.*/
+ for (i = 0; i < gcdCOMMAND_QUEUES; i++)
+ {
+ gctUINT32 data = *(gctUINT32_PTR)device->kernels[core]->command->queues[i].logical;
+
+ data = 0;
+ }
+ }
+
+ for (;;)
+ {
+ static int down;
+
+ down = down_interruptible(&device->semas[core]);
+ if (down); /*To make gcc 4.6 happye*/
+
+ if (device->killThread == gcvTRUE)
+ {
+ /* The daemon exits. */
+ while (!kthread_should_stop())
+ {
+ gckOS_Delay(device->os, 1);
+ }
+
+ return 0;
+ }
+
+ gckKERNEL_Notify(device->kernels[core],
+ gcvNOTIFY_INTERRUPT,
+ gcvFALSE);
+ }
+}
+
+static irqreturn_t isrRoutineVG(int irq, void *ctxt)
+{
+#if gcdENABLE_VG
+ gceSTATUS status;
+ gckGALDEVICE device;
+
+ device = (gckGALDEVICE) ctxt;
+
+ /* Serve the interrupt. */
+ status = gckVGINTERRUPT_Enque(device->kernels[gcvCORE_VG]->vg->interrupt);
+
+ /* Determine the return value. */
+ return (status == gcvSTATUS_NOT_OUR_INTERRUPT)
+ ? IRQ_RETVAL(0)
+ : IRQ_RETVAL(1);
+#else
+ return IRQ_NONE;
+#endif
+}
+
+/******************************************************************************\
+******************************* gckGALDEVICE Code ******************************
+\******************************************************************************/
+
+static gceSTATUS
+_StartThread(
+ IN int (*ThreadRoutine)(void *data),
+ IN gceCORE Core
+ )
+{
+ gceSTATUS status;
+ gckGALDEVICE device = galDevice;
+ struct task_struct * task;
+
+ if (device->kernels[Core] != gcvNULL)
+ {
+ /* Start the kernel thread. */
+ task = kthread_run(ThreadRoutine, (void *)Core, "galcore deamon thread for core[%d]", Core);
+
+ if (IS_ERR(task))
+ {
+ gcmkTRACE_ZONE(
+ gcvLEVEL_ERROR, gcvZONE_DRIVER,
+ "%s(%d): Could not start the kernel thread.\n",
+ __FUNCTION__, __LINE__
+ );
+
+ gcmkONERROR(gcvSTATUS_GENERIC_IO);
+ }
+
+ device->threadCtxts[Core] = task;
+ device->threadInitializeds[Core] = gcvTRUE;
+ }
+ else
+ {
+ device->threadInitializeds[Core] = gcvFALSE;
+ }
+
+ return gcvSTATUS_OK;
+
+OnError:
+ return status;
+}
+
+/*******************************************************************************
+**
+** gckGALDEVICE_Construct
+**
+** Constructor.
+**
+** INPUT:
+**
+** OUTPUT:
+**
+** gckGALDEVICE * Device
+** Pointer to a variable receiving the gckGALDEVICE object pointer on
+** success.
+*/
+gceSTATUS
+gckGALDEVICE_Construct(
+ IN gctINT IrqLine,
+ IN gctUINT32 RegisterMemBase,
+ IN gctSIZE_T RegisterMemSize,
+ IN gctINT IrqLine2D,
+ IN gctUINT32 RegisterMemBase2D,
+ IN gctSIZE_T RegisterMemSize2D,
+ IN gctINT IrqLineVG,
+ IN gctUINT32 RegisterMemBaseVG,
+ IN gctSIZE_T RegisterMemSizeVG,
+ IN gctUINT32 ContiguousBase,
+ IN gctSIZE_T ContiguousSize,
+ IN gctUINT32 ExternalBase,
+ IN gctSIZE_T ExternalSize,
+ IN gctSIZE_T BankSize,
+ IN gctINT FastClear,
+ IN gctINT Compression,
+ IN gctUINT32 PhysBaseAddr,
+ IN gctUINT32 PhysSize,
+ IN gctINT Signal,
+ IN gctUINT LogFileSize,
+ IN gctINT PowerManagement,
+ IN gctINT GpuProfiler,
+ IN gcsDEVICE_CONSTRUCT_ARGS * Args,
+ OUT gckGALDEVICE *Device
+ )
+{
+ gctUINT32 internalBaseAddress = 0, internalAlignment = 0;
+ gctUINT32 externalAlignment = 0;
+ gctUINT32 physical;
+ gckGALDEVICE device;
+ gceSTATUS status;
+ gctINT32 i;
+ gceHARDWARE_TYPE type;
+ gckKERNEL kernel = gcvNULL;
+
+ gcmkHEADER_ARG("IrqLine=%d RegisterMemBase=0x%08x RegisterMemSize=%u "
+ "IrqLine2D=%d RegisterMemBase2D=0x%08x RegisterMemSize2D=%u "
+ "IrqLineVG=%d RegisterMemBaseVG=0x%08x RegisterMemSizeVG=%u "
+ "ContiguousBase=0x%08x ContiguousSize=%lu BankSize=%lu "
+ "FastClear=%d Compression=%d PhysBaseAddr=0x%x PhysSize=%d Signal=%d",
+ IrqLine, RegisterMemBase, RegisterMemSize,
+ IrqLine2D, RegisterMemBase2D, RegisterMemSize2D,
+ IrqLineVG, RegisterMemBaseVG, RegisterMemSizeVG,
+ ContiguousBase, ContiguousSize, BankSize, FastClear, Compression,
+ PhysBaseAddr, PhysSize, Signal);
+
+#if !gcdENABLE_3D
+ IrqLine = -1;
+#endif
+
+#if !gcdENABLE_2D
+ IrqLine2D = -1;
+#endif
+ /* Allocate device structure. */
+ device = kmalloc(sizeof(struct _gckGALDEVICE), GFP_KERNEL | __GFP_NOWARN);
+ if (!device)
+ {
+ gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
+ }
+
+ memset(device, 0, sizeof(struct _gckGALDEVICE));
+
+ device->dbgNode = gcvNULL;
+
+ device->platform = Args->platform;
+
+ device->args = *Args;
+
+ /* set up the contiguous memory */
+ device->contiguousSize = ContiguousSize;
+
+ /* Clear irq lines. */
+ for (i = 0; i < gcdMAX_GPU_COUNT; i++)
+ {
+ device->irqLines[i] = -1;
+ }
+
+ _SetupRegisterPhysical(device, Args);
+
+ if (IrqLine != -1)
+ {
+ device->requestedRegisterMemBases[gcvCORE_MAJOR] = RegisterMemBase;
+ device->requestedRegisterMemSizes[gcvCORE_MAJOR] = RegisterMemSize;
+ }
+
+ if (IrqLine2D != -1)
+ {
+ device->requestedRegisterMemBases[gcvCORE_2D] = RegisterMemBase2D;
+ device->requestedRegisterMemSizes[gcvCORE_2D] = RegisterMemSize2D;
+ }
+
+ if (IrqLineVG != -1)
+ {
+ device->requestedRegisterMemBases[gcvCORE_VG] = RegisterMemBaseVG;
+ device->requestedRegisterMemSizes[gcvCORE_VG] = RegisterMemSizeVG;
+ }
+#if gcdDEC_ENABLE_AHB
+ {
+ device->requestedRegisterMemBases[gcvCORE_DEC] = Args->registerMemBaseDEC300;
+ device->requestedRegisterMemSizes[gcvCORE_DEC] = Args->registerMemSizeDEC300;
+ }
+#endif
+
+
+ for (i = gcvCORE_MAJOR; i < gcvCORE_COUNT; i++)
+ {
+ if (Args->irqs[i] != -1)
+ {
+ device->requestedRegisterMemBases[i] = Args->registerBases[i];
+ device->requestedRegisterMemSizes[i] = Args->registerSizes[i];
+
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_DEVICE,
+ "%s(%d): Core = %d, RegiseterBase = %x",
+ __FUNCTION__, __LINE__,
+ i, Args->registerBases[i]
+ );
+ }
+ }
+
+ /* Initialize the ISR. */
+ device->irqLines[gcvCORE_MAJOR] = IrqLine;
+ device->irqLines[gcvCORE_2D] = IrqLine2D;
+ device->irqLines[gcvCORE_VG] = IrqLineVG;
+
+ for (i = gcvCORE_MAJOR; i < gcvCORE_COUNT; i++)
+ {
+ if (Args->irqs[i] != -1)
+ {
+ device->irqLines[i] = Args->irqs[i];
+ }
+ }
+
+ device->requestedContiguousBase = 0;
+ device->requestedContiguousSize = 0;
+
+ for (i = 0; i < gcdMAX_GPU_COUNT; i++)
+ {
+ physical = device->requestedRegisterMemBases[i];
+
+ /* Set up register memory region. */
+ if (physical != 0)
+ {
+ if (Args->registerMemMapped)
+ {
+ device->registerBases[i] = Args->registerMemAddress;
+ device->requestedRegisterMemBases[i] = 0;
+
+ }
+ else
+ {
+#if USE_LINUX_PCIE
+ device->registerBases[i] = (gctPOINTER) pci_iomap(device->platform->device, 1,
+ device->requestedRegisterMemSizes[i]);
+#else
+ if (!request_mem_region(physical, device->requestedRegisterMemSizes[i], "galcore register region"))
+ {
+ gcmkTRACE_ZONE(
+ gcvLEVEL_ERROR, gcvZONE_DRIVER,
+ "%s(%d): Failed to claim %lu bytes @ 0x%zx\n",
+ __FUNCTION__, __LINE__,
+ physical, device->requestedRegisterMemSizes[i]
+ );
+
+ gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
+ }
+ device->registerBases[i] = (gctPOINTER)ioremap_nocache(
+ physical, device->requestedRegisterMemSizes[i]);
+#endif
+
+ if (device->registerBases[i] == gcvNULL)
+ {
+ gcmkTRACE_ZONE(
+ gcvLEVEL_ERROR, gcvZONE_DRIVER,
+ "%s(%d): Unable to map %ld bytes @ 0x%08X\n",
+ __FUNCTION__, __LINE__,
+ physical, device->requestedRegisterMemSizes[i]
+ );
+
+ gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
+ }
+ }
+
+ physical += device->requestedRegisterMemSizes[i];
+ }
+ }
+
+ /* Set the base address */
+ device->baseAddress = device->physBase = PhysBaseAddr;
+ device->physSize = PhysSize;
+
+ /* Construct the gckOS object. */
+ gcmkONERROR(gckOS_Construct(device, &device->os));
+
+ /* Construct the gckDEVICE object for os independent core management. */
+ gcmkONERROR(gckDEVICE_Construct(device->os, &device->device));
+
+ if (device->irqLines[gcvCORE_MAJOR] != -1)
+ {
+ gcmkONERROR(gctaOS_ConstructOS(device->os, &device->taos));
+ }
+
+ gcmkONERROR(_SetupVidMem(device, ContiguousBase, ContiguousSize, BankSize, Args));
+
+ /* Set external base and size */
+ device->externalBase = ExternalBase;
+ device->externalSize = ExternalSize;
+
+ if (device->irqLines[gcvCORE_MAJOR] != -1)
+ {
+ gcmkONERROR(gcTA_Construct(device->taos, gcvCORE_MAJOR, &globalTA[gcvCORE_MAJOR]));
+
+ gcmkONERROR(gckDEVICE_AddCore(device->device, gcvCORE_MAJOR, Args->chipIDs[gcvCORE_MAJOR], device, &device->kernels[gcvCORE_MAJOR]));
+
+ gcmkONERROR(gckHARDWARE_SetFastClear(
+ device->kernels[gcvCORE_MAJOR]->hardware, FastClear, Compression
+ ));
+
+ gcmkONERROR(gckHARDWARE_SetPowerManagement(
+ device->kernels[gcvCORE_MAJOR]->hardware, PowerManagement
+ ));
+
+#if gcdENABLE_FSCALE_VAL_ADJUST
+ gcmkONERROR(gckHARDWARE_SetMinFscaleValue(
+ device->kernels[gcvCORE_MAJOR]->hardware, Args->gpu3DMinClock
+ ));
+#endif
+
+ gcmkONERROR(gckHARDWARE_SetGpuProfiler(
+ device->kernels[gcvCORE_MAJOR]->hardware, GpuProfiler
+ ));
+ }
+ else
+ {
+ device->kernels[gcvCORE_MAJOR] = gcvNULL;
+ }
+
+ if (device->irqLines[gcvCORE_2D] != -1)
+ {
+ gcmkONERROR(gckDEVICE_AddCore(device->device, gcvCORE_2D, gcvCHIP_ID_DEFAULT, device, &device->kernels[gcvCORE_2D]));
+
+ /* Verify the hardware type */
+ gcmkONERROR(gckHARDWARE_GetType(device->kernels[gcvCORE_2D]->hardware, &type));
+
+ if (type != gcvHARDWARE_2D)
+ {
+ gcmkTRACE_ZONE(
+ gcvLEVEL_ERROR, gcvZONE_DRIVER,
+ "%s(%d): Unexpected hardware type: %d\n",
+ __FUNCTION__, __LINE__,
+ type
+ );
+
+ gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
+ }
+
+ gcmkONERROR(gckHARDWARE_SetPowerManagement(
+ device->kernels[gcvCORE_2D]->hardware, PowerManagement
+ ));
+
+#if gcdENABLE_FSCALE_VAL_ADJUST
+ gcmkONERROR(gckHARDWARE_SetMinFscaleValue(
+ device->kernels[gcvCORE_2D]->hardware, 1
+ ));
+#endif
+ }
+ else
+ {
+ device->kernels[gcvCORE_2D] = gcvNULL;
+ }
+
+ if (device->irqLines[gcvCORE_VG] != -1)
+ {
+#if gcdENABLE_VG
+ gcmkONERROR(gckDEVICE_AddCore(device->device, gcvCORE_VG, gcvCHIP_ID_DEFAULT, device, &device->kernels[gcvCORE_VG]));
+
+ gcmkONERROR(gckVGHARDWARE_SetPowerManagement(
+ device->kernels[gcvCORE_VG]->vg->hardware,
+ PowerManagement
+ ));
+#endif
+ }
+ else
+ {
+ device->kernels[gcvCORE_VG] = gcvNULL;
+ }
+
+ /* Add core for multiple core. */
+ for (i = gcvCORE_3D1; i <= gcvCORE_3D_MAX; i++)
+ {
+ if (Args->irqs[i] != -1)
+ {
+ gcmkONERROR(gcTA_Construct(device->taos, (gceCORE)i, &globalTA[i]));
+ gckDEVICE_AddCore(device->device, i, Args->chipIDs[i], device, &device->kernels[i]);
+
+ gcmkONERROR(
+ gckHARDWARE_SetFastClear(device->kernels[i]->hardware,
+ FastClear,
+ Compression));
+
+ gcmkONERROR(gckHARDWARE_SetPowerManagement(
+ device->kernels[i]->hardware, PowerManagement
+ ));
+
+ gcmkONERROR(gckHARDWARE_SetGpuProfiler(
+ device->kernels[i]->hardware, GpuProfiler
+ ));
+ }
+ }
+
+ /* Initialize the kernel thread semaphores. */
+ for (i = 0; i < gcdMAX_GPU_COUNT; i++)
+ {
+ if (device->irqLines[i] != -1) sema_init(&device->semas[i], 0);
+ }
+
+ device->signal = Signal;
+
+ for (i = 0; i < gcdMAX_GPU_COUNT; i++)
+ {
+ if (device->kernels[i] != gcvNULL) break;
+ }
+
+ if (i == gcdMAX_GPU_COUNT)
+ {
+ gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
+ }
+
+#if gcdENABLE_VG
+ if (i == gcvCORE_VG)
+ {
+ /* Query the ceiling of the system memory. */
+ gcmkONERROR(gckVGHARDWARE_QuerySystemMemory(
+ device->kernels[i]->vg->hardware,
+ &device->systemMemorySize,
+ &device->systemMemoryBaseAddress
+ ));
+ }
+ else
+#endif
+ {
+ /* Query the ceiling of the system memory. */
+ gcmkONERROR(gckHARDWARE_QuerySystemMemory(
+ device->kernels[i]->hardware,
+ &device->systemMemorySize,
+ &device->systemMemoryBaseAddress
+ ));
+ }
+
+ /* Grab the first availiable kernel */
+ for (i = 0; i < gcdMAX_GPU_COUNT; i++)
+ {
+ if (device->irqLines[i] != -1)
+ {
+ kernel = device->kernels[i];
+ break;
+ }
+ }
+
+ /* Set up the internal memory region. */
+ if (device->internalSize > 0)
+ {
+ status = gckVIDMEM_Construct(
+ device->os,
+ internalBaseAddress, device->internalSize, internalAlignment,
+ 0, &device->internalVidMem
+ );
+
+ if (gcmIS_ERROR(status))
+ {
+ /* Error, disable internal heap. */
+ device->internalSize = 0;
+ }
+ else
+ {
+ /* Map internal memory. */
+ device->internalLogical
+ = (gctPOINTER) ioremap_nocache(physical, device->internalSize);
+
+ if (device->internalLogical == gcvNULL)
+ {
+ gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
+ }
+
+ device->internalPhysical = (gctPHYS_ADDR)(gctUINTPTR_T) physical;
+ physical += device->internalSize;
+ }
+ }
+
+ if (device->externalSize > 0)
+ {
+ /* create the external memory heap */
+ status = gckVIDMEM_Construct(
+ device->os,
+ device->externalBase, device->externalSize, externalAlignment,
+ 0, &device->externalVidMem
+ );
+
+ if (gcmIS_ERROR(status))
+ {
+ /* Error, disable external heap. */
+ device->externalSize = 0;
+ }
+ else
+ {
+ /* Map external memory. */
+ gcmkONERROR(gckOS_RequestReservedMemory(
+ device->os,
+ device->externalBase, device->externalSize,
+ "galcore external memory",
+ gcvTRUE,
+ &device->externalPhysical
+ ));
+ device->externalVidMem->physical = device->externalPhysical;
+ }
+ }
+
+ if (device->internalPhysical)
+ {
+ device->internalPhysicalName = gcmPTR_TO_NAME(device->internalPhysical);
+ }
+
+ if (device->externalPhysical)
+ {
+ device->externalPhysicalName = gcmPTR_TO_NAME(device->externalPhysical);
+ }
+
+ if (device->contiguousPhysical)
+ {
+ device->contiguousPhysicalName = gcmPTR_TO_NAME(device->contiguousPhysical);
+ }
+
+ /* Return pointer to the device. */
+ *Device = galDevice = device;
+
+ gcmkONERROR(_DebugfsInit(device));
+
+ if (gckDEBUGFS_CreateNode(
+ device, LogFileSize, device->debugfsDir.root ,DEBUG_FILE, &(device->dbgNode)))
+ {
+ gcmkTRACE_ZONE(
+ gcvLEVEL_ERROR, gcvZONE_DRIVER,
+ "%s(%d): Failed to create the debug file system %s/%s \n",
+ __FUNCTION__, __LINE__,
+ PARENT_FILE, DEBUG_FILE
+ );
+ }
+ else if (LogFileSize)
+ {
+ gckDEBUGFS_SetCurrentNode(device->dbgNode);
+ }
+
+ gcmkFOOTER_ARG("*Device=0x%x", * Device);
+ return gcvSTATUS_OK;
+
+OnError:
+ /* Roll back. */
+ gcmkVERIFY_OK(gckGALDEVICE_Destroy(device));
+
+ gcmkFOOTER();
+ return status;
+}
+
+/*******************************************************************************
+**
+** gckGALDEVICE_Destroy
+**
+** Class destructor.
+**
+** INPUT:
+**
+** Nothing.
+**
+** OUTPUT:
+**
+** Nothing.
+**
+** RETURNS:
+**
+** Nothing.
+*/
+gceSTATUS
+gckGALDEVICE_Destroy(
+ gckGALDEVICE Device)
+{
+ gctINT i;
+ gckKERNEL kernel = gcvNULL;
+
+ gcmkHEADER_ARG("Device=0x%x", Device);
+
+ if (Device != gcvNULL)
+ {
+ /* Grab the first availiable kernel */
+ for (i = 0; i < gcdMAX_GPU_COUNT; i++)
+ {
+ if (Device->irqLines[i] != -1)
+ {
+ kernel = Device->kernels[i];
+ break;
+ }
+ }
+
+ if (Device->internalPhysicalName != 0)
+ {
+ gcmRELEASE_NAME(Device->internalPhysicalName);
+ Device->internalPhysicalName = 0;
+ }
+ if (Device->externalPhysicalName != 0)
+ {
+ gcmRELEASE_NAME(Device->externalPhysicalName);
+ Device->externalPhysicalName = 0;
+ }
+ if (Device->contiguousPhysicalName != 0)
+ {
+ gcmRELEASE_NAME(Device->contiguousPhysicalName);
+ Device->contiguousPhysicalName = 0;
+ }
+
+ for (i = 0; i < gcdMAX_GPU_COUNT; i++)
+ {
+ if (Device->kernels[i] != gcvNULL)
+ {
+ Device->kernels[i] = gcvNULL;
+ }
+ }
+
+ if (Device->internalLogical != gcvNULL)
+ {
+ /* Unmap the internal memory. */
+ iounmap(Device->internalLogical);
+ Device->internalLogical = gcvNULL;
+ }
+
+ if (Device->internalVidMem != gcvNULL)
+ {
+ /* Destroy the internal heap. */
+ gcmkVERIFY_OK(gckVIDMEM_Destroy(Device->internalVidMem));
+ Device->internalVidMem = gcvNULL;
+ }
+
+ if (Device->externalPhysical != gcvNULL)
+ {
+ gckOS_ReleaseReservedMemory(
+ Device->os,
+ Device->externalPhysical
+ );
+ }
+
+ if (Device->externalLogical != gcvNULL)
+ {
+ Device->externalLogical = gcvNULL;
+ }
+
+ if (Device->externalVidMem != gcvNULL)
+ {
+ /* destroy the external heap */
+ gcmkVERIFY_OK(gckVIDMEM_Destroy(Device->externalVidMem));
+ Device->externalVidMem = gcvNULL;
+ }
+
+ if (Device->contiguousPhysical != gcvNULL)
+ {
+ if (Device->requestedContiguousBase == 0)
+ {
+ gcmkVERIFY_OK(_FreeMemory(
+ Device,
+ Device->contiguousLogical,
+ Device->contiguousPhysical
+ ));
+ }
+ else
+ {
+ gckOS_ReleaseReservedMemory(
+ Device->os,
+ Device->contiguousPhysical
+ );
+
+ Device->requestedContiguousBase = 0;
+ Device->requestedContiguousSize = 0;
+ }
+
+ Device->contiguousLogical = gcvNULL;
+ Device->contiguousPhysical = gcvNULL;
+ }
+
+ if (Device->contiguousVidMem != gcvNULL)
+ {
+ /* Destroy the contiguous heap. */
+ gcmkVERIFY_OK(gckVIDMEM_Destroy(Device->contiguousVidMem));
+ Device->contiguousVidMem = gcvNULL;
+ }
+
+ for (i = 0; i < gcdMAX_GPU_COUNT; i++)
+ {
+ if (Device->registerBases[i])
+ {
+ /* Unmap register memory. */
+ if (Device->requestedRegisterMemBases[i] != 0)
+ {
+#if USE_LINUX_PCIE
+ pci_iounmap(Device->platform->device, Device->registerBases[i]);
+#else
+
+ iounmap(Device->registerBases[i]);
+ release_mem_region(Device->requestedRegisterMemBases[i],
+ Device->requestedRegisterMemSizes[i]);
+#endif
+ }
+
+ Device->registerBases[i] = gcvNULL;
+ Device->requestedRegisterMemBases[i] = 0;
+ Device->requestedRegisterMemSizes[i] = 0;
+ }
+ }
+
+ if (Device->device)
+ {
+ gcmkVERIFY_OK(gckDEVICE_Destroy(Device->os, Device->device));
+
+ for (i = 0; i < gcdMAX_GPU_COUNT; i++)
+ {
+ if (globalTA[i])
+ {
+ gcTA_Destroy(globalTA[i]);
+ globalTA[i] = gcvNULL;
+ }
+ }
+
+ Device->device = gcvNULL;
+ }
+
+ if (Device->taos)
+ {
+ gcmkVERIFY_OK(gctaOS_DestroyOS(Device->taos));
+ Device->taos = gcvNULL;
+ }
+
+ /* Destroy the gckOS object. */
+ if (Device->os != gcvNULL)
+ {
+ gcmkVERIFY_OK(gckOS_Destroy(Device->os));
+ Device->os = gcvNULL;
+ }
+
+ if (Device->dbgNode)
+ {
+ gckDEBUGFS_FreeNode(Device->dbgNode);
+
+ if(Device->dbgNode != gcvNULL)
+ {
+ kfree(Device->dbgNode);
+ Device->dbgNode = gcvNULL;
+ }
+ }
+
+ _DebugfsCleanup(Device);
+
+ /* Free the device. */
+ kfree(Device);
+ }
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+}
+
+static const char *isrNames[] =
+{
+ "galcore:0",
+ "galcore:3d-1",
+ "galcore:3d-2",
+ "galcore:3d-3",
+ "galcore:3d-4",
+ "galcore:3d-5",
+ "galcore:3d-6",
+ "galcore:3d-7",
+ "galcore:2d",
+ "galcore:vg",
+#if gcdDEC_ENABLE_AHB
+ "galcore:dec"
+#endif
+};
+
+/*******************************************************************************
+**
+** gckGALDEVICE_Setup_ISR
+**
+** Start the ISR routine.
+**
+** INPUT:
+**
+** gckGALDEVICE Device
+** Pointer to an gckGALDEVICE object.
+**
+** OUTPUT:
+**
+** Nothing.
+**
+** RETURNS:
+**
+** gcvSTATUS_OK
+** Setup successfully.
+** gcvSTATUS_GENERIC_IO
+** Setup failed.
+*/
+gceSTATUS
+gckGALDEVICE_Setup_ISR(
+ IN gceCORE Core
+ )
+{
+ gceSTATUS status;
+ gctINT ret = 0;
+ gckGALDEVICE Device = galDevice;
+
+ gcmkHEADER_ARG("Device=0x%x Core=%d", Device, Core);
+
+ gcmkVERIFY_ARGUMENT(Device != NULL);
+
+ if (Device->irqLines[Core] < 0)
+ {
+ gcmkONERROR(gcvSTATUS_GENERIC_IO);
+ }
+
+#if defined(__GNUC__) && ((__GNUC__ == 4 && __GNUC_MINOR__ >= 6) || (__GNUC__ > 4))
+ {
+ _Static_assert(gcvCORE_COUNT == gcmCOUNTOF(isrNames),
+ "Core count is lager than isrNames size");
+ }
+#endif
+
+ /* Hook up the isr based on the irq line. */
+ ret = request_irq(
+ Device->irqLines[Core], isrRoutine, gcdIRQF_FLAG,
+ isrNames[Core], (void *)(uintptr_t)(Core + 1)
+ );
+
+ if (ret != 0)
+ {
+ gcmkTRACE_ZONE(
+ gcvLEVEL_ERROR, gcvZONE_DRIVER,
+ "%s(%d): Could not register irq line %d (error=%d)\n",
+ __FUNCTION__, __LINE__,
+ Device->irqLines[Core], ret
+ );
+
+ gcmkONERROR(gcvSTATUS_GENERIC_IO);
+ }
+
+ /* Mark ISR as initialized. */
+ Device->isrInitializeds[Core] = gcvTRUE;
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ gcmkFOOTER();
+ return status;
+}
+
+gceSTATUS
+gckGALDEVICE_Setup_ISR_VG(
+ IN gckGALDEVICE Device
+ )
+{
+ gceSTATUS status;
+ gctINT ret;
+
+ gcmkHEADER_ARG("Device=0x%x", Device);
+
+ gcmkVERIFY_ARGUMENT(Device != NULL);
+
+ if (Device->irqLines[gcvCORE_VG] < 0)
+ {
+ gcmkONERROR(gcvSTATUS_GENERIC_IO);
+ }
+
+ /* Hook up the isr based on the irq line. */
+ ret = request_irq(
+ Device->irqLines[gcvCORE_VG], isrRoutineVG, gcdIRQF_FLAG,
+ isrNames[gcvCORE_VG], Device
+ );
+
+ if (ret != 0)
+ {
+ gcmkTRACE_ZONE(
+ gcvLEVEL_ERROR, gcvZONE_DRIVER,
+ "%s(%d): Could not register irq line %d (error=%d)\n",
+ __FUNCTION__, __LINE__,
+ Device->irqLines[gcvCORE_VG], ret
+ );
+
+ gcmkONERROR(gcvSTATUS_GENERIC_IO);
+ }
+
+ /* Mark ISR as initialized. */
+ Device->isrInitializeds[gcvCORE_VG] = gcvTRUE;
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ gcmkFOOTER();
+ return status;
+}
+
+/*******************************************************************************
+**
+** gckGALDEVICE_Release_ISR
+**
+** Release the irq line.
+**
+** INPUT:
+**
+** gckGALDEVICE Device
+** Pointer to an gckGALDEVICE object.
+**
+** OUTPUT:
+**
+** Nothing.
+**
+** RETURNS:
+**
+** Nothing.
+*/
+gceSTATUS
+gckGALDEVICE_Release_ISR(
+ IN gceCORE Core
+ )
+{
+ gckGALDEVICE Device = galDevice;
+ gcmkHEADER_ARG("Device=0x%x", Device);
+
+ gcmkVERIFY_ARGUMENT(Device != NULL);
+
+ /* release the irq */
+ if (Device->isrInitializeds[Core])
+ {
+ free_irq(Device->irqLines[Core], (void *)(uintptr_t)(Core + 1));
+ Device->isrInitializeds[Core] = gcvFALSE;
+ }
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+}
+
+gceSTATUS
+gckGALDEVICE_Release_ISR_VG(
+ IN gckGALDEVICE Device
+ )
+{
+ gcmkHEADER_ARG("Device=0x%x", Device);
+
+ gcmkVERIFY_ARGUMENT(Device != NULL);
+
+ /* release the irq */
+ if (Device->isrInitializeds[gcvCORE_VG])
+ {
+ free_irq(Device->irqLines[gcvCORE_VG], Device);
+ Device->isrInitializeds[gcvCORE_VG] = gcvFALSE;
+ }
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+}
+
+/*******************************************************************************
+**
+** gckGALDEVICE_Start_Threads
+**
+** Start the daemon threads.
+**
+** INPUT:
+**
+** gckGALDEVICE Device
+** Pointer to an gckGALDEVICE object.
+**
+** OUTPUT:
+**
+** Nothing.
+**
+** RETURNS:
+**
+** gcvSTATUS_OK
+** Start successfully.
+** gcvSTATUS_GENERIC_IO
+** Start failed.
+*/
+gceSTATUS
+gckGALDEVICE_Start_Threads(
+ IN gckGALDEVICE Device
+ )
+{
+ gceSTATUS status;
+ gctUINT i;
+
+ gcmkHEADER_ARG("Device=0x%x", Device);
+
+ gcmkVERIFY_ARGUMENT(Device != NULL);
+
+ gcmkONERROR(_StartThread(threadRoutine, gcvCORE_MAJOR));
+ gcmkONERROR(_StartThread(threadRoutine, gcvCORE_2D));
+
+ gcmkONERROR(_StartThread(threadRoutine, gcvCORE_VG));
+
+ for (i = gcvCORE_3D1; i <= gcvCORE_3D_MAX; i++)
+ {
+ gcmkONERROR(_StartThread(threadRoutine, i));
+ }
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ gcmkFOOTER();
+ return status;
+}
+
+/*******************************************************************************
+**
+** gckGALDEVICE_Stop_Threads
+**
+** Stop the gal device, including the following actions: stop the daemon
+** thread, release the irq.
+**
+** INPUT:
+**
+** gckGALDEVICE Device
+** Pointer to an gckGALDEVICE object.
+**
+** OUTPUT:
+**
+** Nothing.
+**
+** RETURNS:
+**
+** Nothing.
+*/
+gceSTATUS
+gckGALDEVICE_Stop_Threads(
+ gckGALDEVICE Device
+ )
+{
+ gctINT i;
+
+ gcmkHEADER_ARG("Device=0x%x", Device);
+
+ gcmkVERIFY_ARGUMENT(Device != NULL);
+
+ for (i = 0; i < gcdMAX_GPU_COUNT; i++)
+ {
+ /* Stop the kernel threads. */
+ if (Device->threadInitializeds[i])
+ {
+ Device->killThread = gcvTRUE;
+ up(&Device->semas[i]);
+
+ kthread_stop(Device->threadCtxts[i]);
+ Device->threadCtxts[i] = gcvNULL;
+ Device->threadInitializeds[i] = gcvFALSE;
+ }
+ }
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+}
+
+/*******************************************************************************
+**
+** gckGALDEVICE_Start
+**
+** Start the gal device, including the following actions: setup the isr routine
+** and start the daemoni thread.
+**
+** INPUT:
+**
+** gckGALDEVICE Device
+** Pointer to an gckGALDEVICE object.
+**
+** OUTPUT:
+**
+** Nothing.
+**
+** RETURNS:
+**
+** gcvSTATUS_OK
+** Start successfully.
+*/
+gceSTATUS
+gckGALDEVICE_Start(
+ IN gckGALDEVICE Device
+ )
+{
+ gceSTATUS status;
+ gctUINT i;
+
+ gcmkHEADER_ARG("Device=0x%x", Device);
+
+ /* Start the kernel thread. */
+ gcmkONERROR(gckGALDEVICE_Start_Threads(Device));
+
+ for (i = 0; i < gcvCORE_COUNT; i++)
+ {
+ if (i == gcvCORE_VG)
+ {
+ continue;
+ }
+
+ if (Device->kernels[i] != gcvNULL)
+ {
+ /* Setup the ISR routine. */
+ gcmkONERROR(gckGALDEVICE_Setup_ISR(i));
+
+ /* Switch to SUSPEND power state. */
+ gcmkONERROR(gckHARDWARE_SetPowerManagementState(
+ Device->kernels[i]->hardware, gcvPOWER_OFF_BROADCAST
+ ));
+ }
+ }
+
+ if (Device->kernels[gcvCORE_VG] != gcvNULL)
+ {
+ /* Setup the ISR routine. */
+ gcmkONERROR(gckGALDEVICE_Setup_ISR_VG(Device));
+
+#if gcdENABLE_VG
+ /* Switch to SUSPEND power state. */
+ gcmkONERROR(gckVGHARDWARE_SetPowerManagementState(
+ Device->kernels[gcvCORE_VG]->vg->hardware, gcvPOWER_OFF_BROADCAST
+ ));
+#endif
+ }
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ gcmkFOOTER();
+ return status;
+}
+
+/*******************************************************************************
+**
+** gckGALDEVICE_Stop
+**
+** Stop the gal device, including the following actions: stop the daemon
+** thread, release the irq.
+**
+** INPUT:
+**
+** gckGALDEVICE Device
+** Pointer to an gckGALDEVICE object.
+**
+** OUTPUT:
+**
+** Nothing.
+**
+** RETURNS:
+**
+** Nothing.
+*/
+gceSTATUS
+gckGALDEVICE_Stop(
+ gckGALDEVICE Device
+ )
+{
+ gceSTATUS status;
+ gctUINT i;
+
+ gcmkHEADER_ARG("Device=0x%x", Device);
+
+ gcmkVERIFY_ARGUMENT(Device != NULL);
+
+ for (i = 0; i < gcvCORE_COUNT; i++)
+ {
+ if (i == gcvCORE_VG)
+ {
+ continue;
+ }
+
+ if (Device->kernels[i] != gcvNULL)
+ {
+ gcmkONERROR(gckHARDWARE_SetPowerManagement(
+ Device->kernels[i]->hardware, gcvTRUE
+ ));
+
+ /* Switch to OFF power state. */
+ gcmkONERROR(gckHARDWARE_SetPowerManagementState(
+ Device->kernels[i]->hardware, gcvPOWER_OFF
+ ));
+
+ /* Remove the ISR routine. */
+ gcmkONERROR(gckGALDEVICE_Release_ISR(i));
+ }
+ }
+
+ if (Device->kernels[gcvCORE_VG] != gcvNULL)
+ {
+ /* Setup the ISR routine. */
+ gcmkONERROR(gckGALDEVICE_Release_ISR_VG(Device));
+
+#if gcdENABLE_VG
+ /* Switch to OFF power state. */
+ gcmkONERROR(gckVGHARDWARE_SetPowerManagementState(
+ Device->kernels[gcvCORE_VG]->vg->hardware, gcvPOWER_OFF
+ ));
+#endif
+ }
+
+ /* Stop the kernel thread. */
+ gcmkONERROR(gckGALDEVICE_Stop_Threads(Device));
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ gcmkFOOTER();
+ return status;
+}
+
+/*******************************************************************************
+**
+** gckGALDEVICE_AddCore
+**
+** Add a core after gckGALDevice is constructed.
+**
+** INPUT:
+**
+** OUTPUT:
+**
+*/
+gceSTATUS
+gckGALDEVICE_AddCore(
+ IN gckGALDEVICE Device,
+ IN gcsDEVICE_CONSTRUCT_ARGS * Args
+ )
+{
+ gceSTATUS status;
+ gceCORE core = gcvCORE_COUNT;
+ gctUINT i = 0;
+
+ gcmkHEADER();
+ gcmkVERIFY_ARGUMENT(Device != gcvNULL);
+
+ /* Find which core is added. */
+ for (i = 0; i < gcvCORE_COUNT; i++)
+ {
+ if (Args->irqs[i] != -1)
+ {
+ core = i;
+ break;
+ }
+ }
+
+ if (i == gcvCORE_COUNT)
+ {
+ gcmkPRINT("[galcore]: No valid core information found");
+ gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
+ }
+
+
+ gcmkPRINT("[galcore]: add core[%d]", core);
+
+ /* Record irq, registerBase, registerSize. */
+ Device->irqLines[core] = Args->irqs[core];
+ _SetupRegisterPhysical(Device, Args);
+
+ /* Map register memory.*/
+
+ /* Add a platform indepedent framework. */
+ gcmkONERROR(gckDEVICE_AddCore(
+ Device->device,
+ core,
+ Args->chipIDs[core],
+ Device,
+ &Device->kernels[core]
+ ));
+
+ /* Start thread routine. */
+ _StartThread(threadRoutine, core);
+
+ /* Register ISR. */
+ gckGALDEVICE_Setup_ISR(core);
+
+ /* Set default power management state. */
+ gcmkONERROR(gckHARDWARE_SetPowerManagementState(
+ Device->kernels[core]->hardware, gcvPOWER_OFF_BROADCAST
+ ));
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ gcmkFOOTER();
+ return gcvSTATUS_OK;
+}
+
diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_device.h b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_device.h
new file mode 100644
index 000000000000..42322007b409
--- /dev/null
+++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_device.h
@@ -0,0 +1,273 @@
+/****************************************************************************
+*
+* The MIT License (MIT)
+*
+* Copyright (c) 2014 - 2018 Vivante 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 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 GPL License (GPL)
+*
+* Copyright (C) 2014 - 2018 Vivante 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.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+*****************************************************************************
+*
+* Note: This software is released under dual MIT and GPL licenses. A
+* recipient may use this file under the terms of either the MIT license or
+* GPL License. If you wish to use only one license not the other, you can
+* indicate your decision by deleting one of the above license notices in your
+* version of this file.
+*
+*****************************************************************************/
+
+
+#ifndef __gc_hal_kernel_device_h_
+#define __gc_hal_kernel_device_h_
+
+#include "gc_hal_kernel_debugfs.h"
+#include "gc_hal_ta.h"
+
+typedef struct _gcsDEVICE_CONSTRUCT_ARGS
+{
+ gctBOOL recovery;
+ gctUINT stuckDump;
+ gctUINT gpu3DMinClock;
+
+ gctBOOL contiguousRequested;
+ gcsPLATFORM* platform;
+ gctBOOL mmu;
+ gctBOOL registerMemMapped;
+ gctPOINTER registerMemAddress;
+#if gcdDEC_ENABLE_AHB
+ gctUINT32 registerMemBaseDEC300;
+ gctSIZE_T registerMemSizeDEC300;
+#endif
+ gctINT irqs[gcvCORE_COUNT];
+ gctUINT registerBases[gcvCORE_COUNT];
+ gctUINT registerSizes[gcvCORE_COUNT];
+ gctBOOL powerManagement;
+ gctBOOL gpuProfiler;
+ gctUINT chipIDs[gcvCORE_COUNT];
+}
+gcsDEVICE_CONSTRUCT_ARGS;
+
+/******************************************************************************\
+************************** gckGALDEVICE Structure ******************************
+\******************************************************************************/
+
+typedef struct _gckGALDEVICE
+{
+ /* Objects. */
+ gckOS os;
+ gckKERNEL kernels[gcdMAX_GPU_COUNT];
+
+ gcsPLATFORM* platform;
+
+ /* Attributes. */
+ gctSIZE_T internalSize;
+ gctPHYS_ADDR internalPhysical;
+ gctUINT32 internalPhysicalName;
+ gctPOINTER internalLogical;
+ gckVIDMEM internalVidMem;
+
+ gctUINT32 externalBase;
+ gctSIZE_T externalSize;
+ gctPHYS_ADDR externalPhysical;
+ gctUINT32 externalPhysicalName;
+ gctPOINTER externalLogical;
+ gckVIDMEM externalVidMem;
+
+ gctPHYS_ADDR_T contiguousBase;
+ gctSIZE_T contiguousSize;
+
+ gckVIDMEM contiguousVidMem;
+ gctPOINTER contiguousLogical;
+ gctPHYS_ADDR contiguousPhysical;
+ gctUINT32 contiguousPhysicalName;
+
+ gctSIZE_T systemMemorySize;
+ gctUINT32 systemMemoryBaseAddress;
+ gctPOINTER registerBases[gcdMAX_GPU_COUNT];
+ gctSIZE_T registerSizes[gcdMAX_GPU_COUNT];
+
+ gctUINT32 baseAddress;
+ gctUINT32 physBase;
+ gctUINT32 physSize;
+
+ /* By request_mem_region. */
+ gctUINT32 requestedRegisterMemBases[gcdMAX_GPU_COUNT];
+ gctSIZE_T requestedRegisterMemSizes[gcdMAX_GPU_COUNT];
+
+ /* By request_mem_region. */
+ gctUINT32 requestedContiguousBase;
+ gctSIZE_T requestedContiguousSize;
+
+ /* IRQ management. */
+ gctINT irqLines[gcdMAX_GPU_COUNT];
+ gctBOOL isrInitializeds[gcdMAX_GPU_COUNT];
+
+ /* Thread management. */
+ struct task_struct *threadCtxts[gcdMAX_GPU_COUNT];
+ struct semaphore semas[gcdMAX_GPU_COUNT];
+ gctBOOL threadInitializeds[gcdMAX_GPU_COUNT];
+ gctBOOL killThread;
+
+ /* Signal management. */
+ gctINT signal;
+
+ /* States before suspend. */
+ gceCHIPPOWERSTATE statesStored[gcdMAX_GPU_COUNT];
+
+ /* Device Debug File System Entry in kernel. */
+ struct _gcsDEBUGFS_Node * dbgNode;
+
+ gcsDEBUGFS_DIR debugfsDir;
+
+ gckDEVICE device;
+
+ gcsDEVICE_CONSTRUCT_ARGS args;
+
+ /* gctsOs object for trust application. */
+ gctaOS taos;
+
+#if gcdENABLE_DRM
+ void* drm;
+#endif
+}
+* gckGALDEVICE;
+
+typedef struct _gcsHAL_PRIVATE_DATA
+{
+ gckGALDEVICE device;
+ /*
+ * 'fput' schedules actual work in '__fput' in a different thread.
+ * So the process opens the device may not be the same as the one that
+ * closes it.
+ */
+ gctUINT32 pidOpen;
+ gctBOOL isLocked;
+}
+gcsHAL_PRIVATE_DATA, * gcsHAL_PRIVATE_DATA_PTR;
+
+gceSTATUS gckGALDEVICE_Setup_ISR(
+ IN gceCORE Core
+ );
+
+gceSTATUS gckGALDEVICE_Setup_ISR_VG(
+ IN gckGALDEVICE Device
+ );
+
+gceSTATUS gckGALDEVICE_Release_ISR(
+ IN gceCORE Core
+ );
+
+gceSTATUS gckGALDEVICE_Release_ISR_VG(
+ IN gckGALDEVICE Device
+ );
+
+gceSTATUS gckGALDEVICE_Start_Threads(
+ IN gckGALDEVICE Device
+ );
+
+gceSTATUS gckGALDEVICE_Stop_Threads(
+ gckGALDEVICE Device
+ );
+
+gceSTATUS gckGALDEVICE_Start(
+ IN gckGALDEVICE Device
+ );
+
+gceSTATUS gckGALDEVICE_Stop(
+ gckGALDEVICE Device
+ );
+
+gceSTATUS gckGALDEVICE_Construct(
+ IN gctINT IrqLine,
+ IN gctUINT32 RegisterMemBase,
+ IN gctSIZE_T RegisterMemSize,
+ IN gctINT IrqLine2D,
+ IN gctUINT32 RegisterMemBase2D,
+ IN gctSIZE_T RegisterMemSize2D,
+ IN gctINT IrqLineVG,
+ IN gctUINT32 RegisterMemBaseVG,
+ IN gctSIZE_T RegisterMemSizeVG,
+ IN gctUINT32 ContiguousBase,
+ IN gctSIZE_T ContiguousSize,
+ IN gctUINT32 ExternalBase,
+ IN gctSIZE_T ExternalSize,
+ IN gctSIZE_T BankSize,
+ IN gctINT FastClear,
+ IN gctINT Compression,
+ IN gctUINT32 PhysBaseAddr,
+ IN gctUINT32 PhysSize,
+ IN gctINT Signal,
+ IN gctUINT LogFileSize,
+ IN gctINT PowerManagement,
+ IN gctINT GpuProfiler,
+ IN gcsDEVICE_CONSTRUCT_ARGS * Args,
+ OUT gckGALDEVICE *Device
+ );
+
+gceSTATUS gckGALDEVICE_Destroy(
+ IN gckGALDEVICE Device
+ );
+
+static gcmINLINE gckKERNEL
+_GetValidKernel(
+ gckGALDEVICE Device
+ )
+{
+ if (Device->kernels[gcvCORE_MAJOR])
+ {
+ return Device->kernels[gcvCORE_MAJOR];
+ }
+ else
+ if (Device->kernels[gcvCORE_2D])
+ {
+ return Device->kernels[gcvCORE_2D];
+ }
+ else
+ if (Device->kernels[gcvCORE_VG])
+ {
+ return Device->kernels[gcvCORE_VG];
+ }
+ else
+ {
+ gcmkASSERT(gcvFALSE);
+ return gcvNULL;
+ }
+}
+
+#endif /* __gc_hal_kernel_device_h_ */
diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_driver.c b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_driver.c
new file mode 100644
index 000000000000..87f26e721773
--- /dev/null
+++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_driver.c
@@ -0,0 +1,1331 @@
+/****************************************************************************
+*
+* The MIT License (MIT)
+*
+* Copyright (c) 2014 - 2018 Vivante 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 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 GPL License (GPL)
+*
+* Copyright (C) 2014 - 2018 Vivante 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.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+*****************************************************************************
+*
+* Note: This software is released under dual MIT and GPL licenses. A
+* recipient may use this file under the terms of either the MIT license or
+* GPL License. If you wish to use only one license not the other, you can
+* indicate your decision by deleting one of the above license notices in your
+* version of this file.
+*
+*****************************************************************************/
+
+
+#include <linux/device.h>
+#include <linux/slab.h>
+#include <linux/miscdevice.h>
+#include <linux/uaccess.h>
+
+#include "gc_hal_kernel_linux.h"
+#include "gc_hal_driver.h"
+
+#include <linux/platform_device.h>
+
+/* Zone used for header/footer. */
+#define _GC_OBJ_ZONE gcvZONE_DRIVER
+
+MODULE_DESCRIPTION("Vivante Graphics Driver");
+MODULE_LICENSE("Dual MIT/GPL");
+
+/* Disable MSI for internal FPGA build except PPC */
+#if gcdFPGA_BUILD && !defined(CONFIG_PPC)
+#define USE_MSI 0
+#else
+#define USE_MSI 1
+#endif
+
+static struct class* gpuClass = NULL;
+
+static gcsPLATFORM *platform = NULL;
+
+static gckGALDEVICE galDevice;
+
+static uint major = 199;
+module_param(major, uint, 0644);
+MODULE_PARM_DESC(major, "major device number for GC device");
+
+static int irqLine = -1;
+module_param(irqLine, int, 0644);
+MODULE_PARM_DESC(irqLine, "IRQ number of GC core");
+
+static ulong registerMemBase = 0x80000000;
+module_param(registerMemBase, ulong, 0644);
+MODULE_PARM_DESC(registerMemBase, "Base of bus address of GC core AHB register");
+
+static ulong registerMemSize = 2 << 10;
+module_param(registerMemSize, ulong, 0644);
+MODULE_PARM_DESC(registerMemSize, "Size of bus address range of GC core AHB register");
+
+static int irqLine2D = -1;
+module_param(irqLine2D, int, 0644);
+MODULE_PARM_DESC(irqLine2D, "IRQ number of G2D core if irqLine is used for a G3D core");
+
+static ulong registerMemBase2D = 0x00000000;
+module_param(registerMemBase2D, ulong, 0644);
+MODULE_PARM_DESC(registerMemBase2D, "Base of bus address of G2D core if registerMemBase2D is used for a G3D core");
+
+static ulong registerMemSize2D = 2 << 10;
+module_param(registerMemSize2D, ulong, 0644);
+MODULE_PARM_DESC(registerMemSize2D, "Size of bus address range of G2D core if registerMemSize is used for a G3D core");
+
+static int irqLineVG = -1;
+module_param(irqLineVG, int, 0644);
+MODULE_PARM_DESC(irqLineVG, "IRQ number of VG core");
+
+static ulong registerMemBaseVG = 0x00000000;
+module_param(registerMemBaseVG, ulong, 0644);
+MODULE_PARM_DESC(registerMemBaseVG, "Base of bus address of VG core");
+
+static ulong registerMemSizeVG = 2 << 10;
+module_param(registerMemSizeVG, ulong, 0644);
+MODULE_PARM_DESC(registerMemSizeVG, "Size of bus address range of VG core");
+
+#if gcdDEC_ENABLE_AHB
+static ulong registerMemBaseDEC300 = 0x00000000;
+module_param(registerMemBaseDEC300, ulong, 0644);
+
+static ulong registerMemSizeDEC300 = 2 << 10;
+module_param(registerMemSizeDEC300, ulong, 0644);
+#endif
+
+#ifndef gcdDEFAULT_CONTIGUOUS_SIZE
+#define gcdDEFAULT_CONTIGUOUS_SIZE (4 << 20)
+#endif
+static ulong contiguousSize = gcdDEFAULT_CONTIGUOUS_SIZE;
+module_param(contiguousSize, ulong, 0644);
+MODULE_PARM_DESC(contiguousSize, "Size of memory reserved for GC");
+
+static ulong contiguousBase = 0;
+module_param(contiguousBase, ulong, 0644);
+MODULE_PARM_DESC(contiguousBase, "Base address of memory reserved for GC, if it is 0, GC driver will try to allocate a buffer whose size defined by contiguousSize");
+
+static ulong externalSize = 0;
+module_param(externalSize, ulong, 0644);
+MODULE_PARM_DESC(externalSize, "Size of external memory, if it is 0, means there is no external pool");
+
+static ulong externalBase = 0;
+module_param(externalBase, ulong, 0644);
+MODULE_PARM_DESC(externalBase, "Base address of external memory");
+
+static int fastClear = -1;
+module_param(fastClear, int, 0644);
+MODULE_PARM_DESC(fastClear, "Disable fast clear if set it to 0, enabled by default");
+
+static int compression = -1;
+module_param(compression, int, 0644);
+MODULE_PARM_DESC(compression, "Disable compression if set it to 0, enabled by default");
+
+static int powerManagement = 1;
+module_param(powerManagement, int, 0644);
+MODULE_PARM_DESC(powerManagement, "Disable auto power saving if set it to 1, enabled by default");
+
+static int gpuProfiler = 0;
+module_param(gpuProfiler, int, 0644);
+MODULE_PARM_DESC(gpuProfiler, "Enable profiling support, disabled by default");
+
+static ulong baseAddress = 0;
+module_param(baseAddress, ulong, 0644);
+MODULE_PARM_DESC(baseAddress, "Only used for old MMU, set it to 0 if memory which can be accessed by GPU falls into 0 - 2G, otherwise set it to 0x80000000");
+
+static ulong physSize = 0;
+module_param(physSize, ulong, 0644);
+MODULE_PARM_DESC(physSize, "Obsolete");
+
+static uint logFileSize = 0;
+module_param(logFileSize,uint, 0644);
+MODULE_PARM_DESC(logFileSize, "Size of buffer to store GC driver output messsage, if it is not 0, message is read from /sys/kernel/debug/gc/galcore_trace, default value is 0");
+
+static uint recovery = 0;
+module_param(recovery, uint, 0644);
+MODULE_PARM_DESC(recovery, "Recover GPU from stuck (1: Enable, 0: Disable)");
+
+/* Middle needs about 40KB buffer, Maximal may need more than 200KB buffer. */
+static uint stuckDump = 0;
+module_param(stuckDump, uint, 0644);
+MODULE_PARM_DESC(stuckDump, "Level of stuck dump content (1: Minimal, 2: Middle, 3: Maximal)");
+
+static int showArgs = 0;
+module_param(showArgs, int, 0644);
+MODULE_PARM_DESC(showArgs, "Display parameters value when driver loaded");
+
+static int mmu = 1;
+module_param(mmu, int, 0644);
+MODULE_PARM_DESC(mmu, "Disable MMU if set it to 0, enabled by default");
+
+static int irqs[gcvCORE_COUNT] = {[0 ... gcvCORE_COUNT - 1] = -1};
+module_param_array(irqs, int, NULL, 0644);
+MODULE_PARM_DESC(irqs, "Array of IRQ numbers of multi-GPU");
+
+static uint registerBases[gcvCORE_COUNT];
+module_param_array(registerBases, uint, NULL, 0644);
+MODULE_PARM_DESC(registerBases, "Array of bases of bus address of register of multi-GPU");
+
+static uint registerSizes[gcvCORE_COUNT] = {[0 ... gcvCORE_COUNT - 1] = 2 << 10};
+module_param_array(registerSizes, uint, NULL, 0644);
+MODULE_PARM_DESC(registerSizes, "Array of sizes of bus address range of register of multi-GPU");
+
+static uint chipIDs[gcvCORE_COUNT] = {[0 ... gcvCORE_COUNT - 1] = gcvCHIP_ID_DEFAULT};
+module_param_array(chipIDs, uint, NULL, 0644);
+MODULE_PARM_DESC(chipIDs, "Array of chipIDs of multi-GPU");
+
+static uint type = 0;
+module_param(type, uint, 0664);
+MODULE_PARM_DESC(type, "0 - Char Driver (Default), 1 - Misc Driver");
+
+static int gpu3DMinClock = 1;
+
+static int contiguousRequested = 0;
+
+static gctBOOL registerMemMapped = gcvFALSE;
+static gctPOINTER registerMemAddress = gcvNULL;
+static ulong bankSize = 0;
+static int signal = 48;
+
+void
+_UpdateModuleParam(
+ gcsMODULE_PARAMETERS *Param
+ )
+{
+ irqLine = Param->irqLine ;
+ registerMemBase = Param->registerMemBase;
+ registerMemSize = Param->registerMemSize;
+ irqLine2D = Param->irqLine2D ;
+ registerMemBase2D = Param->registerMemBase2D;
+ registerMemSize2D = Param->registerMemSize2D;
+#if gcdENABLE_VG
+ irqLineVG = Param->irqLineVG;
+ registerMemBaseVG = Param->registerMemBaseVG;
+ registerMemSizeVG = Param->registerMemSizeVG;
+#endif
+ contiguousSize = Param->contiguousSize;
+ contiguousBase = Param->contiguousBase;
+ externalSize = Param->externalSize;
+ externalBase = Param->externalBase;
+ bankSize = Param->bankSize;
+ fastClear = Param->fastClear;
+ compression = (gctINT)Param->compression;
+ powerManagement = Param->powerManagement;
+ gpuProfiler = Param->gpuProfiler;
+ signal = Param->signal;
+ baseAddress = Param->baseAddress;
+ physSize = Param->physSize;
+ logFileSize = Param->logFileSize;
+ recovery = Param->recovery;
+ stuckDump = Param->stuckDump;
+ showArgs = Param->showArgs;
+ contiguousRequested = Param->contiguousRequested;
+ gpu3DMinClock = Param->gpu3DMinClock;
+ registerMemMapped = Param->registerMemMapped;
+ registerMemAddress = Param->registerMemAddress;
+
+ memcpy(irqs, Param->irqs, gcmSIZEOF(gctINT) * gcvCORE_COUNT);
+ memcpy(registerBases, Param->registerBases, gcmSIZEOF(gctUINT) * gcvCORE_COUNT);
+ memcpy(registerSizes, Param->registerSizes, gcmSIZEOF(gctUINT) * gcvCORE_COUNT);
+ memcpy(chipIDs, Param->chipIDs, gcmSIZEOF(gctUINT) * gcvCORE_COUNT);
+}
+
+void
+gckOS_DumpParam(
+ void
+ )
+{
+ gctINT i;
+
+ printk("Galcore options:\n");
+ if (irqLine != -1)
+ {
+ printk(" irqLine = %d\n", irqLine);
+ printk(" registerMemBase = 0x%08lX\n", registerMemBase);
+ printk(" registerMemSize = 0x%08lX\n", registerMemSize);
+ }
+
+ if (irqLine2D != -1)
+ {
+ printk(" irqLine2D = %d\n", irqLine2D);
+ printk(" registerMemBase2D = 0x%08lX\n", registerMemBase2D);
+ printk(" registerMemSize2D = 0x%08lX\n", registerMemSize2D);
+ }
+
+ if (irqLineVG != -1)
+ {
+ printk(" irqLineVG = %d\n", irqLineVG);
+ printk(" registerMemBaseVG = 0x%08lX\n", registerMemBaseVG);
+ printk(" registerMemSizeVG = 0x%08lX\n", registerMemSizeVG);
+ }
+
+#if gcdDEC_ENABLE_AHB
+ printk(" registerMemBaseDEC300 = 0x%08lX\n", registerMemBaseDEC300);
+ printk(" registerMemSizeDEC300 = 0x%08lX\n", registerMemSizeDEC300);
+#endif
+
+ printk(" contiguousSize = 0x%08lX\n", contiguousSize);
+ printk(" contiguousBase = 0x%08lX\n", contiguousBase);
+ printk(" externalSize = 0x%08lX\n", externalSize);
+ printk(" externalBase = 0x%08lX\n", externalBase);
+ printk(" bankSize = 0x%08lX\n", bankSize);
+ printk(" fastClear = %d\n", fastClear);
+ printk(" compression = %d\n", compression);
+ printk(" signal = %d\n", signal);
+ printk(" powerManagement = %d\n", powerManagement);
+ printk(" baseAddress = 0x%08lX\n", baseAddress);
+ printk(" physSize = 0x%08lX\n", physSize);
+ printk(" logFileSize = %d KB \n", logFileSize);
+ printk(" recovery = %d\n", recovery);
+ printk(" stuckDump = %d\n", stuckDump);
+ printk(" gpuProfiler = %d\n", gpuProfiler);
+
+ printk(" irqs = ");
+ for (i = 0; i < gcvCORE_COUNT; i++)
+ {
+ printk("%d, ", irqs[i]);
+ }
+ printk("\n");
+
+ printk(" registerBases = ");
+ for (i = 0; i < gcvCORE_COUNT; i++)
+ {
+ printk("0x%08X, ", registerBases[i]);
+ }
+ printk("\n");
+
+ printk(" registerSizes = ");
+ for (i = 0; i < gcvCORE_COUNT; i++)
+ {
+ printk("0x%08X, ", registerSizes[i]);
+ }
+ printk("\n");
+
+ printk(" chipIDs = ");
+ for (i = 0; i < gcvCORE_COUNT; i++)
+ {
+ printk("0x%08X, ", chipIDs[i]);
+ }
+ printk("\n");
+
+ printk("Build options:\n");
+ printk(" gcdGPU_TIMEOUT = %d\n", gcdGPU_TIMEOUT);
+ printk(" gcdGPU_2D_TIMEOUT = %d\n", gcdGPU_2D_TIMEOUT);
+ printk(" gcdINTERRUPT_STATISTIC = %d\n", gcdINTERRUPT_STATISTIC);
+}
+
+static int drv_open(
+ struct inode* inode,
+ struct file* filp
+ )
+{
+ gceSTATUS status;
+ gctBOOL attached = gcvFALSE;
+ gcsHAL_PRIVATE_DATA_PTR data = gcvNULL;
+ gctINT i;
+
+ gcmkHEADER_ARG("inode=0x%08X filp=0x%08X", inode, filp);
+
+ if (filp == gcvNULL)
+ {
+ gcmkTRACE_ZONE(
+ gcvLEVEL_ERROR, gcvZONE_DRIVER,
+ "%s(%d): filp is NULL\n",
+ __FUNCTION__, __LINE__
+ );
+
+ gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
+ }
+
+ data = kmalloc(sizeof(gcsHAL_PRIVATE_DATA), GFP_KERNEL | __GFP_NOWARN);
+
+ if (data == gcvNULL)
+ {
+ gcmkTRACE_ZONE(
+ gcvLEVEL_ERROR, gcvZONE_DRIVER,
+ "%s(%d): private_data is NULL\n",
+ __FUNCTION__, __LINE__
+ );
+
+ gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
+ }
+
+ data->device = galDevice;
+ data->pidOpen = _GetProcessID();
+ data->isLocked = gcvFALSE;
+
+ /* Attached the process. */
+ for (i = 0; i < gcdMAX_GPU_COUNT; i++)
+ {
+ if (galDevice->kernels[i] != gcvNULL)
+ {
+ gcmkONERROR(gckKERNEL_AttachProcess(galDevice->kernels[i], gcvTRUE));
+ }
+ }
+ attached = gcvTRUE;
+
+ filp->private_data = data;
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return 0;
+
+OnError:
+ if (data != gcvNULL)
+ {
+ kfree(data);
+ }
+
+ if (attached)
+ {
+ for (i = 0; i < gcdMAX_GPU_COUNT; i++)
+ {
+ if (galDevice->kernels[i] != gcvNULL)
+ {
+ gcmkVERIFY_OK(gckKERNEL_AttachProcess(galDevice->kernels[i], gcvFALSE));
+ }
+ }
+ }
+
+ gcmkFOOTER();
+ return -ENOTTY;
+}
+
+static int drv_release(
+ struct inode* inode,
+ struct file* filp
+ )
+{
+ gceSTATUS status;
+ gcsHAL_PRIVATE_DATA_PTR data;
+ gckGALDEVICE device;
+ gctINT i;
+
+ gcmkHEADER_ARG("inode=0x%08X filp=0x%08X", inode, filp);
+
+ if (filp == gcvNULL)
+ {
+ gcmkTRACE_ZONE(
+ gcvLEVEL_ERROR, gcvZONE_DRIVER,
+ "%s(%d): filp is NULL\n",
+ __FUNCTION__, __LINE__
+ );
+
+ gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
+ }
+
+ data = filp->private_data;
+
+ if (data == gcvNULL)
+ {
+ gcmkTRACE_ZONE(
+ gcvLEVEL_ERROR, gcvZONE_DRIVER,
+ "%s(%d): private_data is NULL\n",
+ __FUNCTION__, __LINE__
+ );
+
+ gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
+ }
+
+ device = data->device;
+
+ if (device == gcvNULL)
+ {
+ gcmkTRACE_ZONE(
+ gcvLEVEL_ERROR, gcvZONE_DRIVER,
+ "%s(%d): device is NULL\n",
+ __FUNCTION__, __LINE__
+ );
+
+ gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
+ }
+
+ if (data->isLocked)
+ {
+ /* Release the mutex. */
+ gcmkONERROR(gckOS_ReleaseMutex(gcvNULL, device->device->commitMutex));
+ data->isLocked = gcvFALSE;
+ }
+
+ /* A process gets detached. */
+ for (i = 0; i < gcdMAX_GPU_COUNT; i++)
+ {
+ if (galDevice->kernels[i] != gcvNULL)
+ {
+ gcmkONERROR(gckKERNEL_AttachProcessEx(galDevice->kernels[i], gcvFALSE, data->pidOpen));
+ }
+ }
+
+ kfree(data);
+ filp->private_data = NULL;
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return 0;
+
+OnError:
+ gcmkFOOTER();
+ return -ENOTTY;
+}
+
+static long drv_ioctl(
+ struct file* filp,
+ unsigned int ioctlCode,
+ unsigned long arg
+ )
+{
+ gceSTATUS status;
+ gcsHAL_INTERFACE iface;
+ gctUINT32 copyLen;
+ DRIVER_ARGS drvArgs;
+ gckGALDEVICE device;
+ gcsHAL_PRIVATE_DATA_PTR data;
+
+ gcmkHEADER_ARG(
+ "filp=0x%08X ioctlCode=0x%08X arg=0x%08X",
+ filp, ioctlCode, arg
+ );
+
+ if (filp == gcvNULL)
+ {
+ gcmkTRACE_ZONE(
+ gcvLEVEL_ERROR, gcvZONE_DRIVER,
+ "%s(%d): filp is NULL\n",
+ __FUNCTION__, __LINE__
+ );
+
+ gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
+ }
+
+ data = filp->private_data;
+
+ if (data == gcvNULL)
+ {
+ gcmkTRACE_ZONE(
+ gcvLEVEL_ERROR, gcvZONE_DRIVER,
+ "%s(%d): private_data is NULL\n",
+ __FUNCTION__, __LINE__
+ );
+
+ gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
+ }
+
+ device = data->device;
+
+ if (device == gcvNULL)
+ {
+ gcmkTRACE_ZONE(
+ gcvLEVEL_ERROR, gcvZONE_DRIVER,
+ "%s(%d): device is NULL\n",
+ __FUNCTION__, __LINE__
+ );
+
+ gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
+ }
+
+ if ((ioctlCode != IOCTL_GCHAL_INTERFACE)
+ && (ioctlCode != IOCTL_GCHAL_KERNEL_INTERFACE)
+ )
+ {
+ gcmkTRACE_ZONE(
+ gcvLEVEL_ERROR, gcvZONE_DRIVER,
+ "%s(%d): unknown command %d\n",
+ __FUNCTION__, __LINE__,
+ ioctlCode
+ );
+
+ gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
+ }
+
+ /* Get the drvArgs. */
+ copyLen = copy_from_user(
+ &drvArgs, (void *) arg, sizeof(DRIVER_ARGS)
+ );
+
+ if (copyLen != 0)
+ {
+ gcmkTRACE_ZONE(
+ gcvLEVEL_ERROR, gcvZONE_DRIVER,
+ "%s(%d): error copying of the input arguments.\n",
+ __FUNCTION__, __LINE__
+ );
+
+ gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
+ }
+
+ /* Now bring in the gcsHAL_INTERFACE structure. */
+ if ((drvArgs.InputBufferSize != sizeof(gcsHAL_INTERFACE))
+ || (drvArgs.OutputBufferSize != sizeof(gcsHAL_INTERFACE))
+ )
+ {
+ gcmkTRACE_ZONE(
+ gcvLEVEL_ERROR, gcvZONE_DRIVER,
+ "%s(%d): input or/and output structures are invalid.\n",
+ __FUNCTION__, __LINE__
+ );
+
+ gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
+ }
+
+ copyLen = copy_from_user(
+ &iface, gcmUINT64_TO_PTR(drvArgs.InputBuffer), sizeof(gcsHAL_INTERFACE)
+ );
+
+ if (copyLen != 0)
+ {
+ gcmkTRACE_ZONE(
+ gcvLEVEL_ERROR, gcvZONE_DRIVER,
+ "%s(%d): error copying of input HAL interface.\n",
+ __FUNCTION__, __LINE__
+ );
+
+ gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
+ }
+
+ if (iface.command == gcvHAL_DEVICE_MUTEX)
+ {
+ if (iface.u.DeviceMutex.isMutexLocked == gcvTRUE)
+ {
+ data->isLocked = gcvTRUE;
+ }
+ else
+ {
+ data->isLocked = gcvFALSE;
+ }
+ }
+
+ status = gckDEVICE_Dispatch(device->device, &iface);
+
+ /* Redo system call after pending signal is handled. */
+ if (status == gcvSTATUS_INTERRUPTED)
+ {
+ gcmkFOOTER();
+ return -ERESTARTSYS;
+ }
+
+ /* Copy data back to the user. */
+ copyLen = copy_to_user(
+ gcmUINT64_TO_PTR(drvArgs.OutputBuffer), &iface, sizeof(gcsHAL_INTERFACE)
+ );
+
+ if (copyLen != 0)
+ {
+ gcmkTRACE_ZONE(
+ gcvLEVEL_ERROR, gcvZONE_DRIVER,
+ "%s(%d): error copying of output HAL interface.\n",
+ __FUNCTION__, __LINE__
+ );
+
+ gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
+ }
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return 0;
+
+OnError:
+ gcmkFOOTER();
+ return -ENOTTY;
+}
+
+static struct file_operations driver_fops =
+{
+ .owner = THIS_MODULE,
+ .open = drv_open,
+ .release = drv_release,
+ .unlocked_ioctl = drv_ioctl,
+#ifdef HAVE_COMPAT_IOCTL
+ .compat_ioctl = drv_ioctl,
+#endif
+};
+
+static struct miscdevice gal_device = {
+ .minor = MISC_DYNAMIC_MINOR,
+ .name = DEVICE_NAME,
+ .fops = &driver_fops,
+};
+
+static int drv_init(void)
+{
+ int ret;
+ int result = -EINVAL;
+ gceSTATUS status;
+ gckGALDEVICE device = gcvNULL;
+ struct class* device_class = gcvNULL;
+
+ gcsDEVICE_CONSTRUCT_ARGS args = {
+ .recovery = recovery,
+ .stuckDump = stuckDump,
+ .gpu3DMinClock = gpu3DMinClock,
+ .contiguousRequested = contiguousRequested,
+ .platform = platform,
+ .mmu = mmu,
+ .registerMemMapped = registerMemMapped,
+ .registerMemAddress = registerMemAddress,
+#if gcdDEC_ENABLE_AHB
+ .registerMemBaseDEC300 = registerMemBaseDEC300,
+ .registerMemSizeDEC300 = registerMemSizeDEC300,
+#endif
+ };
+
+ gcmkHEADER();
+
+ memcpy(args.irqs, irqs, gcmSIZEOF(gctINT) * gcvCORE_COUNT);
+ memcpy(args.registerBases, registerBases, gcmSIZEOF(gctUINT) * gcvCORE_COUNT);
+ memcpy(args.registerSizes, registerSizes, gcmSIZEOF(gctUINT) * gcvCORE_COUNT);
+ memcpy(args.chipIDs, chipIDs, gcmSIZEOF(gctUINT) * gcvCORE_COUNT);
+
+ printk(KERN_INFO "Galcore version %d.%d.%d.%d\n",
+ gcvVERSION_MAJOR, gcvVERSION_MINOR, gcvVERSION_PATCH, gcvVERSION_BUILD);
+
+ args.powerManagement = powerManagement;
+ args.gpuProfiler = gpuProfiler;
+
+ if (showArgs)
+ {
+ gckOS_DumpParam();
+ }
+
+ if (logFileSize != 0)
+ {
+ gckDEBUGFS_Initialize();
+ }
+
+ /* Create the GAL device. */
+ status = gckGALDEVICE_Construct(
+ irqLine,
+ registerMemBase, registerMemSize,
+ irqLine2D,
+ registerMemBase2D, registerMemSize2D,
+ irqLineVG,
+ registerMemBaseVG, registerMemSizeVG,
+ contiguousBase, contiguousSize,
+ externalBase, externalSize,
+ bankSize, fastClear, compression, baseAddress, physSize, signal,
+ logFileSize,
+ powerManagement,
+ gpuProfiler,
+ &args,
+ &device
+ );
+
+ if (gcmIS_ERROR(status))
+ {
+ gcmkTRACE_ZONE(gcvLEVEL_ERROR, gcvZONE_DRIVER,
+ "%s(%d): Failed to create the GAL device: status=%d\n",
+ __FUNCTION__, __LINE__, status);
+
+ goto OnError;
+ }
+
+ /* Start the GAL device. */
+ gcmkONERROR(gckGALDEVICE_Start(device));
+
+ if ((physSize != 0)
+ && (device->kernels[gcvCORE_MAJOR] != gcvNULL)
+ && (device->kernels[gcvCORE_MAJOR]->hardware->mmuVersion != 0))
+ {
+ /* Reset the base address */
+ device->baseAddress = 0;
+ }
+
+ /* Set global galDevice pointer. */
+ galDevice = device;
+
+ if (type == 1)
+ {
+ /* Register as misc driver. */
+ ret = misc_register(&gal_device);
+
+ if (ret < 0)
+ {
+ gcmkTRACE_ZONE(
+ gcvLEVEL_ERROR, gcvZONE_DRIVER,
+ "%s(%d): misc_register fails.\n",
+ __FUNCTION__, __LINE__
+ );
+
+ gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
+ }
+ }
+ else
+ {
+ /* Register the character device. */
+ ret = register_chrdev(major, DEVICE_NAME, &driver_fops);
+
+ if (ret < 0)
+ {
+ gcmkTRACE_ZONE(
+ gcvLEVEL_ERROR, gcvZONE_DRIVER,
+ "%s(%d): Could not allocate major number for mmap.\n",
+ __FUNCTION__, __LINE__
+ );
+
+ gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
+ }
+
+ if (major == 0)
+ {
+ major = ret;
+ }
+
+ /* Create the device class. */
+ device_class = class_create(THIS_MODULE, CLASS_NAME);
+
+ if (IS_ERR(device_class))
+ {
+ gcmkTRACE_ZONE(
+ gcvLEVEL_ERROR, gcvZONE_DRIVER,
+ "%s(%d): Failed to create the class.\n",
+ __FUNCTION__, __LINE__
+ );
+
+ gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
+ }
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
+ device_create(device_class, NULL, MKDEV(major, 0), NULL, DEVICE_NAME);
+#else
+ device_create(device_class, NULL, MKDEV(major, 0), DEVICE_NAME);
+#endif
+
+ gpuClass = device_class;
+ }
+
+ gcmkTRACE_ZONE(
+ gcvLEVEL_INFO, gcvZONE_DRIVER,
+ "%s(%d): irqLine=%d, contiguousSize=%lu, memBase=0x%lX\n",
+ __FUNCTION__, __LINE__,
+ irqLine, contiguousSize, registerMemBase
+ );
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return 0;
+
+OnError:
+ /* Roll back. */
+ if (device_class != gcvNULL)
+ {
+ device_destroy(device_class, MKDEV(major, 0));
+ class_destroy(device_class);
+ }
+
+ if (device != gcvNULL)
+ {
+ gcmkVERIFY_OK(gckGALDEVICE_Stop(device));
+ gcmkVERIFY_OK(gckGALDEVICE_Destroy(device));
+ }
+
+ gcmkFOOTER();
+ return result;
+}
+
+static void drv_exit(void)
+{
+ gcmkHEADER();
+
+ if (type == 1)
+ {
+ misc_deregister(&gal_device);
+ }
+ else
+ {
+ gcmkASSERT(gpuClass != gcvNULL);
+ device_destroy(gpuClass, MKDEV(major, 0));
+ class_destroy(gpuClass);
+
+ unregister_chrdev(major, DEVICE_NAME);
+ }
+
+ gcmkVERIFY_OK(gckGALDEVICE_Stop(galDevice));
+ gcmkVERIFY_OK(gckGALDEVICE_Destroy(galDevice));
+
+ if(gckDEBUGFS_IsEnabled())
+ {
+ gckDEBUGFS_Terminate();
+ }
+
+ gcmkFOOTER_NO();
+}
+
+#if gcdENABLE_DRM
+int viv_drm_probe(struct device *dev);
+int viv_drm_remove(struct device *dev);
+#endif
+
+struct device *galcore_device = NULL;
+
+#if USE_LINUX_PCIE
+static int gpu_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+#else /* USE_LINUX_PCIE */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
+ static int gpu_probe(struct platform_device *pdev)
+#else
+ static int __devinit gpu_probe(struct platform_device *pdev)
+#endif
+#endif /* USE_LINUX_PCIE */
+{
+ int ret = -ENODEV;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24)
+ static u64 dma_mask = DMA_BIT_MASK(40);
+#else
+ static u64 dma_mask = DMA_40BIT_MASK;
+#endif
+
+ gcsMODULE_PARAMETERS moduleParam = {
+ .irqLine = irqLine,
+ .registerMemBase = registerMemBase,
+ .registerMemSize = registerMemSize,
+ .irqLine2D = irqLine2D,
+ .registerMemBase2D = registerMemBase2D,
+ .registerMemSize2D = registerMemSize2D,
+ .irqLineVG = irqLineVG,
+ .registerMemBaseVG = registerMemBaseVG,
+ .registerMemSizeVG = registerMemSizeVG,
+ .contiguousSize = contiguousSize,
+ .contiguousBase = contiguousBase,
+ .externalSize = externalSize,
+ .externalBase = externalBase,
+ .bankSize = bankSize,
+ .fastClear = fastClear,
+ .powerManagement = powerManagement,
+ .gpuProfiler = gpuProfiler,
+ .signal = signal,
+ .baseAddress = baseAddress,
+ .physSize = physSize,
+ .logFileSize = logFileSize,
+ .recovery = recovery,
+ .stuckDump = stuckDump,
+ .showArgs = showArgs,
+ .gpu3DMinClock = gpu3DMinClock,
+ .registerMemMapped = registerMemMapped,
+ };
+
+ gcmkHEADER();
+
+ memcpy(moduleParam.irqs, irqs, gcmSIZEOF(gctINT) * gcvCORE_COUNT);
+ memcpy(moduleParam.registerBases, registerBases, gcmSIZEOF(gctUINT) * gcvCORE_COUNT);
+ memcpy(moduleParam.registerSizes, registerSizes, gcmSIZEOF(gctUINT) * gcvCORE_COUNT);
+ memcpy(moduleParam.chipIDs, chipIDs, gcmSIZEOF(gctUINT) * gcvCORE_COUNT);
+ moduleParam.compression = compression;
+ platform->device = pdev;
+ galcore_device = &pdev->dev;
+
+#if USE_LINUX_PCIE
+ if (pci_enable_device(pdev)) {
+ printk(KERN_ERR "galcore: pci_enable_device() failed.\n");
+ }
+
+ if (pci_set_dma_mask(pdev, dma_mask)) {
+ printk(KERN_ERR "galcore: Failed to set DMA mask.\n");
+ }
+
+ pci_set_master(pdev);
+
+ if (pci_request_regions(pdev, "galcore")) {
+ printk(KERN_ERR "galcore: Failed to get ownership of BAR region.\n");
+ }
+
+#if USE_MSI
+ if (pci_enable_msi(pdev)) {
+ printk(KERN_ERR "galcore: Failed to enable MSI.\n");
+ }
+# endif
+#else
+ galcore_device->dma_mask = &dma_mask;
+#endif
+
+ if (platform->ops->getPower)
+ {
+ if (gcmIS_ERROR(platform->ops->getPower(platform)))
+ {
+ gcmkFOOTER_NO();
+ return ret;
+ }
+ }
+
+ if (platform->ops->adjustParam)
+ {
+ /* Override default module param. */
+ platform->ops->adjustParam(platform, &moduleParam);
+
+ /* Update module param because drv_init() uses them directly. */
+ _UpdateModuleParam(&moduleParam);
+ }
+
+ ret = drv_init();
+
+ if (!ret)
+ {
+#if USE_LINUX_PCIE
+ pci_set_drvdata(pdev, galDevice);
+#else
+ platform_set_drvdata(pdev, galDevice);
+#endif
+
+#if gcdENABLE_DRM
+ ret = viv_drm_probe(&pdev->dev);
+#endif
+ }
+
+ if (ret < 0)
+ {
+ gcmkFOOTER_ARG(KERN_INFO "Failed to register gpu driver: %d\n", ret);
+ }
+ else
+ {
+ gcmkFOOTER_NO();
+ }
+ return ret;
+}
+
+#if USE_LINUX_PCIE
+static void gpu_remove(struct pci_dev *pdev)
+#else /* USE_LINUX_PCIE */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
+ static int gpu_remove(struct platform_device *pdev)
+#else
+ static int __devexit gpu_remove(struct platform_device *pdev)
+#endif
+#endif /* USE_LINUX_PCIE */
+{
+ gcmkHEADER();
+
+#if gcdENABLE_DRM
+ viv_drm_remove(&pdev->dev);
+#endif
+
+ drv_exit();
+
+ if (platform->ops->putPower)
+ {
+ platform->ops->putPower(platform);
+ }
+
+#if USE_LINUX_PCIE
+ pci_set_drvdata(pdev, NULL);
+#if USE_MSI
+ pci_disable_msi(pdev);
+#endif
+ pci_clear_master(pdev);
+ pci_release_regions(pdev);
+ pci_disable_device(pdev);
+ gcmkFOOTER_NO();
+ return;
+#else
+ galcore_device->dma_mask = NULL;
+ galcore_device = NULL;
+ gcmkFOOTER_NO();
+ return 0;
+#endif
+}
+
+static int gpu_suspend(struct platform_device *dev, pm_message_t state)
+{
+ gceSTATUS status;
+ gckGALDEVICE device;
+ gctINT i;
+
+ device = platform_get_drvdata(dev);
+
+ if (!device)
+ {
+ return -1;
+ }
+
+ for (i = 0; i < gcdMAX_GPU_COUNT; i++)
+ {
+ if (device->kernels[i] != gcvNULL)
+ {
+ /* Store states. */
+#if gcdENABLE_VG
+ if (i == gcvCORE_VG)
+ {
+ status = gckVGHARDWARE_QueryPowerManagementState(device->kernels[i]->vg->hardware, &device->statesStored[i]);
+ }
+ else
+#endif
+ {
+ status = gckHARDWARE_QueryPowerManagementState(device->kernels[i]->hardware, &device->statesStored[i]);
+ }
+
+ if (gcmIS_ERROR(status))
+ {
+ return -1;
+ }
+
+ /* need pull up power to flush gpu command buffer before suspend */
+#if gcdENABLE_VG
+ if (i == gcvCORE_VG)
+ {
+ status = gckVGHARDWARE_SetPowerManagementState(device->kernels[i]->vg->hardware, gcvPOWER_ON);
+ }
+ else
+#endif
+ {
+ status = gckHARDWARE_SetPowerManagementState(device->kernels[i]->hardware, gcvPOWER_ON);
+ }
+
+ if (gcmIS_ERROR(status))
+ {
+ return -1;
+ }
+
+#if gcdENABLE_VG
+ if (i == gcvCORE_VG)
+ {
+ status = gckVGHARDWARE_SetPowerManagementState(device->kernels[i]->vg->hardware, gcvPOWER_OFF);
+ }
+ else
+#endif
+ {
+ status = gckHARDWARE_SetPowerManagementState(device->kernels[i]->hardware, gcvPOWER_OFF);
+ }
+
+ if (gcmIS_ERROR(status))
+ {
+ return -1;
+ }
+
+ }
+ }
+
+ return 0;
+}
+
+static int gpu_resume(struct platform_device *dev)
+{
+ gceSTATUS status;
+ gckGALDEVICE device;
+ gctINT i;
+ gceCHIPPOWERSTATE statesStored;
+
+ device = platform_get_drvdata(dev);
+
+ if (!device)
+ {
+ return -1;
+ }
+
+ for (i = 0; i < gcdMAX_GPU_COUNT; i++)
+ {
+ if (device->kernels[i] != gcvNULL)
+ {
+#if gcdENABLE_VG
+ if (i == gcvCORE_VG)
+ {
+ status = gckVGHARDWARE_SetPowerManagementState(device->kernels[i]->vg->hardware, gcvPOWER_ON);
+ }
+ else
+#endif
+ {
+ status = gckHARDWARE_SetPowerManagementState(device->kernels[i]->hardware, gcvPOWER_ON);
+ }
+
+ if (gcmIS_ERROR(status))
+ {
+ return -1;
+ }
+
+ /* Convert global state to crossponding internal state. */
+ switch(device->statesStored[i])
+ {
+ case gcvPOWER_OFF:
+ statesStored = gcvPOWER_OFF_BROADCAST;
+ break;
+ case gcvPOWER_IDLE:
+ statesStored = gcvPOWER_IDLE_BROADCAST;
+ break;
+ case gcvPOWER_SUSPEND:
+ statesStored = gcvPOWER_SUSPEND_BROADCAST;
+ break;
+ case gcvPOWER_ON:
+ statesStored = gcvPOWER_ON_AUTO;
+ break;
+ default:
+ statesStored = device->statesStored[i];
+ break;
+ }
+
+ /* Restore states. */
+#if gcdENABLE_VG
+ if (i == gcvCORE_VG)
+ {
+ status = gckVGHARDWARE_SetPowerManagementState(device->kernels[i]->vg->hardware, statesStored);
+ }
+ else
+#endif
+ {
+ gctINT j = 0;
+
+ for (; j < 100; j++)
+ {
+ status = gckHARDWARE_SetPowerManagementState(device->kernels[i]->hardware, statesStored);
+
+ if (( statesStored != gcvPOWER_OFF_BROADCAST
+ && statesStored != gcvPOWER_SUSPEND_BROADCAST)
+ || status != gcvSTATUS_CHIP_NOT_READY)
+ {
+ break;
+ }
+
+ gcmkVERIFY_OK(gckOS_Delay(device->kernels[i]->os, 10));
+ };
+ }
+
+ if (gcmIS_ERROR(status))
+ {
+ return -1;
+ }
+ }
+ }
+
+ return 0;
+}
+
+#if defined(CONFIG_PM) && LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 30)
+#ifdef CONFIG_PM_SLEEP
+static int gpu_system_suspend(struct device *dev)
+{
+ pm_message_t state={0};
+ return gpu_suspend(to_platform_device(dev), state);
+}
+
+static int gpu_system_resume(struct device *dev)
+{
+ return gpu_resume(to_platform_device(dev));
+}
+#endif
+
+static const struct dev_pm_ops gpu_pm_ops = {
+ SET_SYSTEM_SLEEP_PM_OPS(gpu_system_suspend, gpu_system_resume)
+};
+#endif
+
+#if USE_LINUX_PCIE
+static const struct pci_device_id vivpci_ids[] = {
+ {
+ .class = 0x000000,
+ .class_mask = 0x000000,
+ .vendor = 0x10ee,
+ .device = 0x7012,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .driver_data = 0
+ }, { /* End: all zeroes */ }
+};
+
+MODULE_DEVICE_TABLE(pci, vivpci_ids);
+
+static struct pci_driver gpu_driver = {
+ .name = DEVICE_NAME,
+ .id_table = vivpci_ids,
+ .probe = gpu_probe,
+ .remove = gpu_remove
+};
+
+#else /* USE_LINUX_PCIE */
+
+static struct platform_driver gpu_driver = {
+ .probe = gpu_probe,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
+ .remove = gpu_remove,
+#else
+ .remove = __devexit_p(gpu_remove),
+#endif
+
+ .suspend = gpu_suspend,
+ .resume = gpu_resume,
+
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = DEVICE_NAME,
+#if defined(CONFIG_PM) && LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 30)
+ .pm = &gpu_pm_ops,
+#endif
+ }
+};
+#endif /* USE_LINUX_PCIE */
+
+static int __init gpu_init(void)
+{
+ int ret = 0;
+
+ ret = soc_platform_init(&gpu_driver, &platform);
+
+ if (ret || !platform)
+ {
+ printk(KERN_ERR "galcore: Soc platform init failed.\n");
+ return -ENODEV;
+ }
+
+#if USE_LINUX_PCIE
+ ret = pci_register_driver(&gpu_driver);
+#else /* USE_LINUX_PCIE */
+ ret = platform_driver_register(&gpu_driver);
+#endif /* USE_LINUX_PCIE */
+
+ if (ret)
+ {
+ printk(KERN_ERR "galcore: gpu_init() failed to register driver!\n");
+ soc_platform_terminate(platform);
+ platform = NULL;
+ return ret;
+ }
+
+ platform->driver = &gpu_driver;
+
+ return 0;
+}
+
+static void __exit gpu_exit(void)
+{
+#if USE_LINUX_PCIE
+ pci_unregister_driver(&gpu_driver);
+#else
+ platform_driver_unregister(&gpu_driver);
+#endif /* USE_LINUX_PCIE */
+
+ soc_platform_terminate(platform);
+ platform = NULL;
+}
+
+module_init(gpu_init);
+module_exit(gpu_exit);
diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_drm.c b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_drm.c
new file mode 100644
index 000000000000..1fd340158dcc
--- /dev/null
+++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_drm.c
@@ -0,0 +1,856 @@
+/****************************************************************************
+*
+* The MIT License (MIT)
+*
+* Copyright (c) 2014 - 2018 Vivante 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 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 GPL License (GPL)
+*
+* Copyright (C) 2014 - 2018 Vivante 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.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+*****************************************************************************
+*
+* Note: This software is released under dual MIT and GPL licenses. A
+* recipient may use this file under the terms of either the MIT license or
+* GPL License. If you wish to use only one license not the other, you can
+* indicate your decision by deleting one of the above license notices in your
+* version of this file.
+*
+*****************************************************************************/
+
+
+#if gcdENABLE_DRM
+
+#include <drm/drmP.h>
+#include <drm/drm_gem.h>
+#include <linux/dma-buf.h>
+#include "gc_hal_kernel_linux.h"
+#include "gc_hal_drm.h"
+
+#define _GC_OBJ_ZONE gcvZONE_KERNEL
+
+/******************************************************************************\
+******************************* gckKERNEL DRM Code ******************************
+\******************************************************************************/
+
+struct viv_gem_object {
+ struct drm_gem_object base;
+
+ uint32_t node_handle;
+ gckVIDMEM_NODE node_object;
+ gctBOOL cacheable;
+};
+
+struct dma_buf *viv_gem_prime_export(struct drm_device *drm,
+ struct drm_gem_object *gem_obj,
+ int flags)
+{
+ struct viv_gem_object *viv_obj = container_of(gem_obj, struct viv_gem_object, base);
+ struct dma_buf *dmabuf = gcvNULL;
+ gckGALDEVICE gal_dev = (gckGALDEVICE)drm->dev_private;
+
+ if (gal_dev)
+ {
+ gckKERNEL kernel = gal_dev->device->map[gal_dev->device->defaultHwType].kernels[0];
+ gcmkVERIFY_OK(gckVIDMEM_NODE_Export(kernel, viv_obj->node_handle, flags,
+ (gctPOINTER*)&dmabuf, gcvNULL));
+ }
+
+ return dmabuf;
+}
+
+struct drm_gem_object *viv_gem_prime_import(struct drm_device *drm,
+ struct dma_buf *dmabuf)
+{
+ struct drm_gem_object *gem_obj = gcvNULL;
+ struct viv_gem_object *viv_obj;
+
+ gcsHAL_INTERFACE iface;
+ gckGALDEVICE gal_dev;
+ gckKERNEL kernel;
+ gctUINT32 processID;
+ gckVIDMEM_NODE nodeObject;
+ gceSTATUS status = gcvSTATUS_OK;
+
+ gal_dev = (gckGALDEVICE)drm->dev_private;
+ if (!gal_dev)
+ {
+ gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
+ }
+
+ gckOS_ZeroMemory(&iface, sizeof(iface));
+ iface.command = gcvHAL_WRAP_USER_MEMORY;
+ iface.hardwareType = gal_dev->device->defaultHwType;
+ iface.u.WrapUserMemory.desc.flag = gcvALLOC_FLAG_DMABUF;
+ iface.u.WrapUserMemory.desc.handle = -1;
+ iface.u.WrapUserMemory.desc.dmabuf = gcmPTR_TO_UINT64(dmabuf);
+ gcmkONERROR(gckDEVICE_Dispatch(gal_dev->device, &iface));
+
+ kernel = gal_dev->device->map[gal_dev->device->defaultHwType].kernels[0];
+ gcmkONERROR(gckOS_GetProcessID(&processID));
+ gcmkONERROR(gckVIDMEM_HANDLE_Lookup(kernel, processID, iface.u.WrapUserMemory.node, &nodeObject));
+
+ /* ioctl output */
+ gem_obj = kzalloc(sizeof(struct viv_gem_object), GFP_KERNEL);
+ drm_gem_private_object_init(drm, gem_obj, dmabuf->size);
+ viv_obj = container_of(gem_obj, struct viv_gem_object, base);
+ viv_obj->node_handle = iface.u.WrapUserMemory.node;
+ viv_obj->node_object = nodeObject;
+
+OnError:
+ return gem_obj;
+}
+
+void viv_gem_free_object(struct drm_gem_object *gem_obj)
+{
+ struct viv_gem_object *viv_obj = container_of(gem_obj, struct viv_gem_object, base);
+ struct drm_device *drm = gem_obj->dev;
+
+ gcsHAL_INTERFACE iface;
+ gckGALDEVICE gal_dev = (gckGALDEVICE)drm->dev_private;
+
+ gckOS_ZeroMemory(&iface, sizeof(iface));
+ iface.command = gcvHAL_RELEASE_VIDEO_MEMORY;
+ iface.hardwareType = gal_dev->device->defaultHwType;
+ iface.u.ReleaseVideoMemory.node = viv_obj->node_handle;
+ gcmkVERIFY_OK(gckDEVICE_Dispatch(gal_dev->device, &iface));
+
+ drm_gem_object_release(gem_obj);
+ kfree(gem_obj);
+}
+
+static int viv_ioctl_gem_create(struct drm_device *drm, void *data,
+ struct drm_file *file)
+{
+ int ret = 0;
+ struct drm_viv_gem_create *args = (struct drm_viv_gem_create*)data;
+ struct drm_gem_object *gem_obj = gcvNULL;
+ struct viv_gem_object *viv_obj = gcvNULL;
+
+ gcsHAL_INTERFACE iface;
+ gckGALDEVICE gal_dev;
+ gckKERNEL kernel;
+ gctUINT32 processID;
+ gckVIDMEM_NODE nodeObject;
+ gctUINT32 flags = gcvALLOC_FLAG_DMABUF_EXPORTABLE;
+ gceSTATUS status = gcvSTATUS_OK;
+ gcePOOL pool = gcvPOOL_DEFAULT;
+
+ gal_dev = (gckGALDEVICE)drm->dev_private;
+ if (!gal_dev)
+ {
+ gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
+ }
+
+ if (args->flags & DRM_VIV_GEM_CONTIGUOUS)
+ {
+ flags |= gcvALLOC_FLAG_CONTIGUOUS;
+ }
+ if (args->flags & DRM_VIV_GEM_CACHED)
+ {
+ flags |= gcvALLOC_FLAG_CACHEABLE;
+ }
+ if (args->flags & DRM_VIV_GEM_SECURE)
+ {
+ flags |= gcvALLOC_FLAG_SECURITY;
+ }
+ if (args->flags & DRM_VIV_GEM_CMA_LIMIT)
+ {
+ flags |= gcvALLOC_FLAG_CMA_LIMIT;
+ }
+ if (args->flags & DRM_VIV_GEM_VIRTUAL_POOL) {
+ flags &= ~(gcvALLOC_FLAG_CMA_LIMIT | gcvALLOC_FLAG_CONTIGUOUS);
+ pool = gcvPOOL_VIRTUAL;
+ }
+
+ gckOS_ZeroMemory(&iface, sizeof(iface));
+ iface.command = gcvHAL_ALLOCATE_LINEAR_VIDEO_MEMORY;
+ iface.hardwareType = gal_dev->device->defaultHwType;
+ iface.u.AllocateLinearVideoMemory.bytes = PAGE_ALIGN(args->size);
+ iface.u.AllocateLinearVideoMemory.alignment = 256;
+ iface.u.AllocateLinearVideoMemory.type = gcvSURF_RENDER_TARGET; /* should be general */
+ iface.u.AllocateLinearVideoMemory.flag = flags;
+ iface.u.AllocateLinearVideoMemory.pool = pool;
+ gcmkONERROR(gckDEVICE_Dispatch(gal_dev->device, &iface));
+
+ kernel = gal_dev->device->map[gal_dev->device->defaultHwType].kernels[0];
+ gcmkONERROR(gckOS_GetProcessID(&processID));
+ gcmkONERROR(gckVIDMEM_HANDLE_Lookup(kernel, processID, iface.u.AllocateLinearVideoMemory.node, &nodeObject));
+
+ /* ioctl output */
+ gem_obj = kzalloc(sizeof(struct viv_gem_object), GFP_KERNEL);
+ drm_gem_private_object_init(drm, gem_obj, iface.u.AllocateLinearVideoMemory.bytes);
+ ret = drm_gem_handle_create(file, gem_obj, &args->handle);
+
+ viv_obj = container_of(gem_obj, struct viv_gem_object, base);
+ viv_obj->node_handle = iface.u.AllocateLinearVideoMemory.node;
+ viv_obj->node_object = nodeObject;
+ viv_obj->cacheable = flags & gcvALLOC_FLAG_CACHEABLE;
+
+ /* drop reference from allocate - handle holds it now */
+ drm_gem_object_unreference_unlocked(gem_obj);
+
+OnError:
+ return gcmIS_ERROR(status) ? -ENOTTY : 0;
+}
+
+static int viv_ioctl_gem_lock(struct drm_device *drm, void *data,
+ struct drm_file *file)
+{
+ struct drm_viv_gem_lock *args = (struct drm_viv_gem_lock*)data;
+ struct drm_gem_object *gem_obj = gcvNULL;
+ struct viv_gem_object *viv_obj = gcvNULL;
+
+ gcsHAL_INTERFACE iface;
+ gceSTATUS status = gcvSTATUS_OK;
+ gckGALDEVICE gal_dev = gcvNULL;
+
+ gal_dev = (gckGALDEVICE)drm->dev_private;
+ if (!gal_dev)
+ {
+ gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
+ }
+
+ gem_obj = drm_gem_object_lookup(file, args->handle);
+ if (!gem_obj)
+ {
+ gcmkONERROR(gcvSTATUS_NOT_FOUND);
+ }
+ viv_obj = container_of(gem_obj, struct viv_gem_object, base);
+
+ gckOS_ZeroMemory(&iface, sizeof(iface));
+ iface.command = gcvHAL_LOCK_VIDEO_MEMORY;
+ iface.hardwareType = gal_dev->device->defaultHwType;
+ iface.u.LockVideoMemory.node = viv_obj->node_handle;
+ iface.u.LockVideoMemory.cacheable = args->cacheable;
+ gcmkONERROR(gckDEVICE_Dispatch(gal_dev->device, &iface));
+
+ args->logical = iface.u.LockVideoMemory.memory;
+
+OnError:
+ if (gem_obj)
+ {
+ drm_gem_object_unreference_unlocked(gem_obj);
+ }
+ return gcmIS_ERROR(status) ? -ENOTTY : 0;
+}
+
+static int viv_ioctl_gem_unlock(struct drm_device *drm, void *data,
+ struct drm_file *file)
+{
+ struct drm_viv_gem_unlock *args = (struct drm_viv_gem_unlock*)data;
+ struct drm_gem_object *gem_obj = gcvNULL;
+ struct viv_gem_object *viv_obj = gcvNULL;
+
+ gcsHAL_INTERFACE iface;
+ gceSTATUS status = gcvSTATUS_OK;
+ gckGALDEVICE gal_dev = gcvNULL;
+
+ gal_dev = (gckGALDEVICE)drm->dev_private;
+ if (!gal_dev)
+ {
+ gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
+ }
+
+ gem_obj = drm_gem_object_lookup(file, args->handle);
+ if (!gem_obj)
+ {
+ gcmkONERROR(gcvSTATUS_NOT_FOUND);
+ }
+ viv_obj = container_of(gem_obj, struct viv_gem_object, base);
+
+ memset(&iface, 0, sizeof(iface));
+ iface.command = gcvHAL_UNLOCK_VIDEO_MEMORY;
+ iface.hardwareType = gal_dev->device->defaultHwType;
+ iface.u.UnlockVideoMemory.node = (gctUINT64)viv_obj->node_handle;
+ iface.u.UnlockVideoMemory.type = gcvSURF_TYPE_UNKNOWN;
+ gcmkONERROR(gckDEVICE_Dispatch(gal_dev->device, &iface));
+
+ memset(&iface, 0, sizeof(iface));
+ iface.command = gcvHAL_BOTTOM_HALF_UNLOCK_VIDEO_MEMORY;
+ iface.hardwareType = gal_dev->device->defaultHwType;
+ iface.u.BottomHalfUnlockVideoMemory.node = (gctUINT64)viv_obj->node_handle;
+ iface.u.BottomHalfUnlockVideoMemory.type = gcvSURF_TYPE_UNKNOWN;
+ gcmkONERROR(gckDEVICE_Dispatch(gal_dev->device, &iface));
+
+OnError:
+ if (gem_obj)
+ {
+ drm_gem_object_unreference_unlocked(gem_obj);
+ }
+ return gcmIS_ERROR(status) ? -ENOTTY : 0;
+}
+
+static int viv_ioctl_gem_cache(struct drm_device *drm, void *data,
+ struct drm_file *file)
+{
+ struct drm_viv_gem_cache *args = (struct drm_viv_gem_cache*)data;
+ struct drm_gem_object *gem_obj = gcvNULL;
+ struct viv_gem_object *viv_obj = gcvNULL;
+
+ gcsHAL_INTERFACE iface;
+ gceSTATUS status = gcvSTATUS_OK;
+ gckGALDEVICE gal_dev = gcvNULL;
+ gceCACHEOPERATION cache_op = 0;
+
+ gal_dev = (gckGALDEVICE)drm->dev_private;
+ if (!gal_dev)
+ {
+ gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
+ }
+
+ gem_obj = drm_gem_object_lookup(file, args->handle);
+ if (!gem_obj)
+ {
+ gcmkONERROR(gcvSTATUS_NOT_FOUND);
+ }
+ viv_obj = container_of(gem_obj, struct viv_gem_object, base);
+
+ switch (args->op)
+ {
+ case DRM_VIV_GEM_CLEAN_CACHE:
+ cache_op = gcvCACHE_CLEAN;
+ break;
+ case DRM_VIV_GEM_INVALIDATE_CACHE:
+ cache_op = gcvCACHE_INVALIDATE;
+ break;
+ case DRM_VIV_GEM_FLUSH_CACHE:
+ cache_op = gcvCACHE_FLUSH;
+ break;
+ case DRM_VIV_GEM_MEMORY_BARRIER:
+ cache_op = gcvCACHE_MEMORY_BARRIER;
+ break;
+ default:
+ break;
+ }
+
+ gckOS_ZeroMemory(&iface, sizeof(iface));
+ iface.command = gcvHAL_CACHE;
+ iface.hardwareType = gal_dev->device->defaultHwType;
+ iface.u.Cache.node = viv_obj->node_handle;
+ iface.u.Cache.operation = cache_op;
+ iface.u.Cache.logical = args->logical;
+ iface.u.Cache.bytes = args->bytes;
+ gcmkONERROR(gckDEVICE_Dispatch(gal_dev->device, &iface));
+
+OnError:
+ if (gem_obj)
+ {
+ drm_gem_object_unreference_unlocked(gem_obj);
+ }
+ return gcmIS_ERROR(status) ? -ENOTTY : 0;
+}
+
+static int viv_ioctl_gem_query(struct drm_device *drm, void *data,
+ struct drm_file *file)
+{
+ struct drm_viv_gem_query *args = (struct drm_viv_gem_query*)data;
+ struct drm_gem_object *gem_obj = gcvNULL;
+ struct viv_gem_object *viv_obj = gcvNULL;
+
+ gceSTATUS status = gcvSTATUS_OK;
+ gckGALDEVICE gal_dev = gcvNULL;
+
+ gal_dev = (gckGALDEVICE)drm->dev_private;
+ if (!gal_dev)
+ {
+ gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
+ }
+
+ gem_obj = drm_gem_object_lookup(file, args->handle);
+ if (!gem_obj)
+ {
+ gcmkONERROR(gcvSTATUS_NOT_FOUND);
+ }
+ viv_obj = container_of(gem_obj, struct viv_gem_object, base);
+
+ switch (args->param)
+ {
+ case DRM_VIV_GEM_PARAM_POOL:
+ args->value = (__u64)viv_obj->node_object->pool;
+ break;
+ case DRM_VIV_GEM_PARAM_SIZE:
+ args->value = (__u64)gem_obj->size;
+ break;
+ default:
+ gcmkONERROR(gcvSTATUS_NOT_SUPPORTED);
+ }
+
+OnError:
+ if (gem_obj)
+ {
+ drm_gem_object_unreference_unlocked(gem_obj);
+ }
+ return gcmIS_ERROR(status) ? -ENOTTY : 0;
+}
+
+static int viv_ioctl_gem_timestamp(struct drm_device *drm, void *data,
+ struct drm_file *file)
+{
+ struct drm_viv_gem_timestamp *args = (struct drm_viv_gem_timestamp *)data;
+ struct drm_gem_object *gem_obj = gcvNULL;
+ struct viv_gem_object *viv_obj = gcvNULL;
+
+ gceSTATUS status = gcvSTATUS_OK;
+ gckGALDEVICE gal_dev = gcvNULL;
+
+ gal_dev = (gckGALDEVICE)drm->dev_private;
+ if (!gal_dev)
+ {
+ gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
+ }
+
+ gem_obj = drm_gem_object_lookup(file, args->handle);
+ if (!gem_obj)
+ {
+ gcmkONERROR(gcvSTATUS_NOT_FOUND);
+ }
+ viv_obj = container_of(gem_obj, struct viv_gem_object, base);
+
+ viv_obj->node_object->timeStamp += args->inc;
+ args->timestamp = viv_obj->node_object->timeStamp;
+
+OnError:
+ if (gem_obj)
+ {
+ drm_gem_object_unreference_unlocked(gem_obj);
+ }
+ return gcmIS_ERROR(status) ? -ENOTTY : 0;
+}
+
+static int viv_ioctl_gem_set_tiling(struct drm_device *drm, void *data,
+ struct drm_file *file)
+{
+ struct drm_viv_gem_set_tiling *args = (struct drm_viv_gem_set_tiling*)data;
+ struct drm_gem_object *gem_obj = gcvNULL;
+ struct viv_gem_object *viv_obj = gcvNULL;
+
+ gceSTATUS status = gcvSTATUS_OK;
+ gckGALDEVICE gal_dev = gcvNULL;
+
+ gal_dev = (gckGALDEVICE)drm->dev_private;
+ if (!gal_dev)
+ {
+ gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
+ }
+
+ gem_obj = drm_gem_object_lookup(file, args->handle);
+ if (!gem_obj)
+ {
+ gcmkONERROR(gcvSTATUS_NOT_FOUND);
+ }
+ viv_obj = container_of(gem_obj, struct viv_gem_object, base);
+
+ viv_obj->node_object->tilingMode = args->tiling_mode;
+ viv_obj->node_object->tsMode = args->ts_mode;
+ viv_obj->node_object->clearValue = args->clear_value;
+
+OnError:
+ if (gem_obj)
+ {
+ drm_gem_object_unreference_unlocked(gem_obj);
+ }
+ return gcmIS_ERROR(status) ? -ENOTTY : 0;
+}
+
+static int viv_ioctl_gem_get_tiling(struct drm_device *drm, void *data,
+ struct drm_file *file)
+{
+ struct drm_viv_gem_get_tiling *args = (struct drm_viv_gem_get_tiling*)data;
+ struct drm_gem_object *gem_obj = gcvNULL;
+ struct viv_gem_object *viv_obj = gcvNULL;
+
+ gceSTATUS status = gcvSTATUS_OK;
+ gckGALDEVICE gal_dev = gcvNULL;
+
+ gal_dev = (gckGALDEVICE)drm->dev_private;
+ if (!gal_dev)
+ {
+ gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
+ }
+
+ gem_obj = drm_gem_object_lookup(file, args->handle);
+ if (!gem_obj)
+ {
+ gcmkONERROR(gcvSTATUS_NOT_FOUND);
+ }
+ viv_obj = container_of(gem_obj, struct viv_gem_object, base);
+
+ args->tiling_mode = viv_obj->node_object->tilingMode;
+ args->ts_mode = viv_obj->node_object->tsMode;
+ args->clear_value = viv_obj->node_object->clearValue;
+
+OnError:
+ if (gem_obj)
+ {
+ drm_gem_object_unreference_unlocked(gem_obj);
+ }
+ return gcmIS_ERROR(status) ? -ENOTTY : 0;
+}
+
+static int viv_ioctl_gem_attach_aux(struct drm_device *drm, void *data,
+ struct drm_file *file)
+{
+ struct drm_viv_gem_attach_aux *args = (struct drm_viv_gem_attach_aux*)data;
+ struct drm_gem_object *gem_obj = gcvNULL;
+ struct viv_gem_object *viv_obj = gcvNULL;
+ struct drm_gem_object *gem_ts_obj = gcvNULL;
+
+ gceSTATUS status = gcvSTATUS_OK;
+ gckGALDEVICE gal_dev = gcvNULL;
+ gckVIDMEM_NODE nodeObj = gcvNULL;
+
+ gal_dev = (gckGALDEVICE)drm->dev_private;
+ if (!gal_dev)
+ {
+ gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
+ }
+
+ gem_obj = drm_gem_object_lookup(file, args->handle);
+ if (!gem_obj)
+ {
+ gcmkONERROR(gcvSTATUS_NOT_FOUND);
+ }
+ viv_obj = container_of(gem_obj, struct viv_gem_object, base);
+ nodeObj = viv_obj->node_object;
+
+ /* do not support re-attach */
+ if (nodeObj->tsNode)
+ {
+ gcmkONERROR(gcvSTATUS_NOT_SUPPORTED);
+ }
+
+ if (args->ts_handle)
+ {
+ struct viv_gem_object *viv_ts_obj;
+ gckKERNEL kernel = gal_dev->device->map[gal_dev->device->defaultHwType].kernels[0];
+ gcsHAL_INTERFACE iface;
+ gctBOOL is2BitPerTile = gckHARDWARE_IsFeatureAvailable(kernel->hardware , gcvFEATURE_TILE_STATUS_2BITS);
+ gctBOOL isCompressionDEC400 = gckHARDWARE_IsFeatureAvailable(kernel->hardware , gcvFEATURE_COMPRESSION_DEC400);
+ gctPOINTER entry = gcvNULL;
+ gctUINT32 tileStatusFiller = (isCompressionDEC400 || ((kernel->hardware->identity.chipModel == gcv500) && (kernel->hardware->identity.chipRevision > 2)))
+ ? 0xFFFFFFFF
+ : is2BitPerTile ? 0x55555555 : 0x11111111;
+
+ gem_ts_obj = drm_gem_object_lookup(file, args->ts_handle);
+ if (!gem_ts_obj)
+ {
+ gcmkONERROR(gcvSTATUS_NOT_FOUND);
+ }
+ viv_ts_obj = container_of(gem_ts_obj, struct viv_gem_object, base);
+
+ gcmkONERROR(gckVIDMEM_NODE_Reference(kernel, viv_ts_obj->node_object));
+ nodeObj->tsNode = viv_ts_obj->node_object;
+
+ /* Fill tile status node with tileStatusFiller value first time to avoid GPU hang. */
+ /* Lock tile status node. */
+ gckOS_ZeroMemory(&iface, sizeof(iface));
+ iface.command = gcvHAL_LOCK_VIDEO_MEMORY;
+ iface.hardwareType = gal_dev->device->defaultHwType;
+ iface.u.LockVideoMemory.node = viv_ts_obj->node_handle;
+ iface.u.LockVideoMemory.cacheable = viv_ts_obj->cacheable;
+ gcmkONERROR(gckDEVICE_Dispatch(gal_dev->device, &iface));
+
+ /* Fill tile status node with tileStatusFiller. */
+ gcmkONERROR(gckVIDMEM_NODE_LockCPU(kernel, viv_ts_obj->node_handle, &entry));
+ memset(entry , tileStatusFiller , (__u64)gem_ts_obj->size);
+ gcmkONERROR(gckVIDMEM_NODE_UnlockCPU(kernel, viv_ts_obj->node_handle, entry));
+
+ /* UnLock tile status node. */
+ memset(&iface, 0, sizeof(iface));
+ iface.command = gcvHAL_UNLOCK_VIDEO_MEMORY;
+ iface.hardwareType = gal_dev->device->defaultHwType;
+ iface.u.UnlockVideoMemory.node = (gctUINT64)viv_ts_obj->node_handle;
+ iface.u.UnlockVideoMemory.type = gcvSURF_TYPE_UNKNOWN;
+ gcmkONERROR(gckDEVICE_Dispatch(gal_dev->device, &iface));
+
+ memset(&iface, 0, sizeof(iface));
+ iface.command = gcvHAL_BOTTOM_HALF_UNLOCK_VIDEO_MEMORY;
+ iface.hardwareType = gal_dev->device->defaultHwType;
+ iface.u.BottomHalfUnlockVideoMemory.node = (gctUINT64)viv_ts_obj->node_handle;
+ iface.u.BottomHalfUnlockVideoMemory.type = gcvSURF_TYPE_UNKNOWN;
+ gcmkONERROR(gckDEVICE_Dispatch(gal_dev->device, &iface));
+ }
+
+OnError:
+ if (gem_obj)
+ {
+ drm_gem_object_unreference_unlocked(gem_obj);
+
+ if (gem_ts_obj)
+ {
+ drm_gem_object_unreference_unlocked(gem_ts_obj);
+ }
+ }
+ return gcmIS_ERROR(status) ? -ENOTTY : 0;
+}
+
+static int viv_ioctl_gem_ref_node(struct drm_device *drm, void *data,
+ struct drm_file *file)
+{
+ struct drm_viv_gem_ref_node *args = (struct drm_viv_gem_ref_node*)data;
+ struct drm_gem_object *gem_obj = gcvNULL;
+ struct viv_gem_object *viv_obj = gcvNULL;
+
+ gceSTATUS status = gcvSTATUS_OK;
+ gckGALDEVICE gal_dev = gcvNULL;
+ gckKERNEL kernel = gcvNULL;
+ gctUINT32 processID;
+ gckVIDMEM_NODE nodeObj;
+ gctUINT32 nodeHandle = 0, tsNodeHandle = 0;
+ gctBOOL refered = gcvFALSE;
+ int ret = 0;
+
+ gal_dev = (gckGALDEVICE)drm->dev_private;
+ if (!gal_dev)
+ {
+ gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
+ }
+ kernel = gal_dev->device->map[gal_dev->device->defaultHwType].kernels[0];
+
+ gem_obj = drm_gem_object_lookup(file, args->handle);
+ if (!gem_obj)
+ {
+ gcmkONERROR(gcvSTATUS_NOT_FOUND);
+ }
+ viv_obj = container_of(gem_obj, struct viv_gem_object, base);
+ nodeObj = viv_obj->node_object;
+
+ gcmkONERROR(gckOS_GetProcessID(&processID));
+ gcmkONERROR(gckVIDMEM_HANDLE_Allocate(kernel, nodeObj, &nodeHandle));
+ gcmkONERROR(
+ gckKERNEL_AddProcessDB(kernel,
+ processID, gcvDB_VIDEO_MEMORY,
+ gcmINT2PTR(nodeHandle),
+ gcvNULL,
+ 0));
+ gcmkONERROR(gckVIDMEM_NODE_Reference(kernel, nodeObj));
+ refered = gcvTRUE;
+
+ if (nodeObj->tsNode)
+ {
+ gcmkONERROR(gckVIDMEM_HANDLE_Allocate(kernel, nodeObj->tsNode, &tsNodeHandle));
+ gcmkONERROR(
+ gckKERNEL_AddProcessDB(kernel,
+ processID, gcvDB_VIDEO_MEMORY,
+ gcmINT2PTR(tsNodeHandle),
+ gcvNULL,
+ 0));
+ gcmkONERROR(gckVIDMEM_NODE_Reference(kernel, nodeObj->tsNode));
+ }
+ args->node = nodeHandle;
+ args->ts_node = tsNodeHandle;
+
+OnError:
+ if (gcmIS_ERROR(status) && kernel)
+ {
+ gctUINT32 processID;
+
+ gcmkVERIFY_OK(gckOS_GetProcessID(&processID));
+
+ if (tsNodeHandle)
+ {
+ gckVIDMEM_HANDLE_Dereference(kernel, processID, tsNodeHandle);
+ }
+
+ if (nodeHandle)
+ {
+ gckVIDMEM_HANDLE_Dereference(kernel, processID, nodeHandle);
+ }
+
+ if (refered)
+ {
+ gcmkONERROR(gckVIDMEM_NODE_Dereference(kernel, nodeObj));
+ }
+
+ args->node = 0;
+ args->ts_node = 0;
+
+ ret = -ENOTTY;
+ }
+
+ if (gem_obj)
+ {
+ drm_gem_object_unreference_unlocked(gem_obj);
+ }
+
+ return ret;
+}
+
+static const struct drm_ioctl_desc viv_ioctls[] =
+{
+ DRM_IOCTL_DEF_DRV(VIV_GEM_CREATE, viv_ioctl_gem_create, DRM_AUTH | DRM_RENDER_ALLOW),
+ DRM_IOCTL_DEF_DRV(VIV_GEM_LOCK, viv_ioctl_gem_lock, DRM_AUTH | DRM_RENDER_ALLOW),
+ DRM_IOCTL_DEF_DRV(VIV_GEM_UNLOCK, viv_ioctl_gem_unlock, DRM_AUTH | DRM_RENDER_ALLOW),
+ DRM_IOCTL_DEF_DRV(VIV_GEM_CACHE, viv_ioctl_gem_cache, DRM_AUTH | DRM_RENDER_ALLOW),
+ DRM_IOCTL_DEF_DRV(VIV_GEM_QUERY, viv_ioctl_gem_query, DRM_AUTH | DRM_RENDER_ALLOW),
+ DRM_IOCTL_DEF_DRV(VIV_GEM_TIMESTAMP, viv_ioctl_gem_timestamp, DRM_AUTH | DRM_RENDER_ALLOW),
+ DRM_IOCTL_DEF_DRV(VIV_GEM_SET_TILING, viv_ioctl_gem_set_tiling, DRM_AUTH | DRM_RENDER_ALLOW),
+ DRM_IOCTL_DEF_DRV(VIV_GEM_GET_TILING, viv_ioctl_gem_get_tiling, DRM_AUTH | DRM_RENDER_ALLOW),
+ DRM_IOCTL_DEF_DRV(VIV_GEM_ATTACH_AUX, viv_ioctl_gem_attach_aux, DRM_AUTH | DRM_RENDER_ALLOW),
+ DRM_IOCTL_DEF_DRV(VIV_GEM_REF_NODE, viv_ioctl_gem_ref_node, DRM_AUTH | DRM_RENDER_ALLOW),
+};
+
+int viv_drm_open(struct drm_device *drm, struct drm_file *file)
+{
+ gctINT i;
+ gctUINT32 pid = _GetProcessID();
+ gckGALDEVICE gal_dev = (gckGALDEVICE)drm->dev_private;
+ gceSTATUS status = gcvSTATUS_OK;
+
+ for (i = 0; i < gcdMAX_GPU_COUNT; ++i)
+ {
+ if (gal_dev->kernels[i])
+ {
+ gcmkONERROR(gckKERNEL_AttachProcessEx(gal_dev->kernels[i], gcvTRUE, pid));
+ }
+ }
+ file->driver_priv = gcmINT2PTR(pid);
+
+OnError:
+ return gcmIS_ERROR(status) ? -ENODEV : 0;
+}
+
+void viv_drm_postclose(struct drm_device *drm, struct drm_file *file)
+{
+ gctINT i;
+ gctUINT32 pid = gcmPTR2SIZE(file->driver_priv);
+ gckGALDEVICE gal_dev = (gckGALDEVICE)drm->dev_private;
+
+ for (i = 0; i < gcdMAX_GPU_COUNT; ++i)
+ {
+ if (gal_dev->kernels[i])
+ {
+ gcmkVERIFY_OK(gckKERNEL_AttachProcessEx(gal_dev->kernels[i], gcvFALSE, pid));
+ }
+ }
+}
+
+static const struct file_operations viv_drm_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,
+};
+
+static struct drm_driver viv_drm_driver = {
+ .driver_features = DRIVER_GEM | DRIVER_PRIME | DRIVER_RENDER,
+ .open = viv_drm_open,
+ .postclose = viv_drm_postclose,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0)
+ .gem_free_object_unlocked = viv_gem_free_object,
+#else
+ .gem_free_object = viv_gem_free_object,
+#endif
+ .prime_handle_to_fd = drm_gem_prime_handle_to_fd,
+ .prime_fd_to_handle = drm_gem_prime_fd_to_handle,
+ .gem_prime_export = viv_gem_prime_export,
+ .gem_prime_import = viv_gem_prime_import,
+ .ioctls = viv_ioctls,
+ .num_ioctls = DRM_VIV_NUM_IOCTLS,
+ .fops = &viv_drm_fops,
+ .name = "vivante",
+ .desc = "vivante DRM",
+ .date = "20170808",
+ .major = 1,
+ .minor = 0,
+};
+
+int viv_drm_probe(struct device *dev)
+{
+ int ret = 0;
+ gceSTATUS status = gcvSTATUS_OK;
+ gckGALDEVICE gal_dev = gcvNULL;
+ struct drm_device *drm = gcvNULL;
+
+ gal_dev = (gckGALDEVICE)dev_get_drvdata(dev);
+ if (!gal_dev)
+ {
+ ret = -ENODEV;
+ gcmkONERROR(gcvSTATUS_INVALID_OBJECT);
+ }
+
+ drm = drm_dev_alloc(&viv_drm_driver, dev);
+ if (IS_ERR(drm))
+ {
+ ret = PTR_ERR(drm);
+ gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
+ }
+ drm->dev_private = (void*)gal_dev;
+
+ ret = drm_dev_register(drm, 0);
+ if (ret)
+ {
+ gcmkONERROR(gcvSTATUS_GENERIC_IO);
+ }
+
+ gal_dev->drm = (void*)drm;
+
+OnError:
+ if (gcmIS_ERROR(status))
+ {
+ if (drm)
+ {
+ drm_dev_unref(drm);
+ }
+ printk(KERN_ERR "galcore: Failed to setup drm device.\n");
+ }
+ return ret;
+}
+
+int viv_drm_remove(struct device *dev)
+{
+ gckGALDEVICE gal_dev = (gckGALDEVICE)dev_get_drvdata(dev);
+
+ if (gal_dev)
+ {
+ struct drm_device *drm = (struct drm_device*)gal_dev->drm;
+
+ drm_dev_unregister(drm);
+ drm_dev_unref(drm);
+ }
+
+ return 0;
+}
+
+#endif
diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_iommu.c b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_iommu.c
new file mode 100644
index 000000000000..f36e11682f91
--- /dev/null
+++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_iommu.c
@@ -0,0 +1,250 @@
+/****************************************************************************
+*
+* The MIT License (MIT)
+*
+* Copyright (c) 2014 - 2018 Vivante 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 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 GPL License (GPL)
+*
+* Copyright (C) 2014 - 2018 Vivante 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.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+*****************************************************************************
+*
+* Note: This software is released under dual MIT and GPL licenses. A
+* recipient may use this file under the terms of either the MIT license or
+* GPL License. If you wish to use only one license not the other, you can
+* indicate your decision by deleting one of the above license notices in your
+* version of this file.
+*
+*****************************************************************************/
+
+
+#include "gc_hal_kernel_linux.h"
+#include "gc_hal_kernel_device.h"
+
+#include <linux/iommu.h>
+#include <linux/platform_device.h>
+
+#define _GC_OBJ_ZONE gcvZONE_OS
+
+typedef struct _gcsIOMMU
+{
+ struct iommu_domain * domain;
+ struct device * device;
+}
+gcsIOMMU;
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0)
+static int
+_IOMMU_Fault_Handler(
+ struct iommu_domain * Domain,
+ struct device * Dev,
+ unsigned long DomainAddress,
+ int flags,
+ void * args
+ )
+#else
+static int
+_IOMMU_Fault_Handler(
+ struct iommu_domain * Domain,
+ struct device * Dev,
+ unsigned long DomainAddress,
+ int flags
+ )
+#endif
+{
+ return 0;
+}
+
+static int
+_FlatMapping(
+ IN gckIOMMU Iommu
+ )
+{
+ gceSTATUS status;
+ gctUINT32 physical;
+
+ for (physical = 0; physical < 0x80000000; physical += PAGE_SIZE)
+ {
+ gcmkTRACE_ZONE(
+ gcvLEVEL_INFO, gcvZONE_OS,
+ "Map %x => %x bytes = %d",
+ physical, physical, PAGE_SIZE
+ );
+
+ gcmkONERROR(gckIOMMU_Map(Iommu, physical, physical, PAGE_SIZE));
+ }
+
+ return gcvSTATUS_OK;
+
+OnError:
+ return status;
+}
+
+void
+gckIOMMU_Destory(
+ IN gckOS Os,
+ IN gckIOMMU Iommu
+ )
+{
+ gcmkHEADER();
+
+ if (Iommu->domain && Iommu->device)
+ {
+ iommu_attach_device(Iommu->domain, Iommu->device);
+ }
+
+ if (Iommu->domain)
+ {
+ iommu_domain_free(Iommu->domain);
+ }
+
+ if (Iommu)
+ {
+ gcmkOS_SAFE_FREE(Os, Iommu);
+ }
+
+ gcmkFOOTER_NO();
+}
+
+gceSTATUS
+gckIOMMU_Construct(
+ IN gckOS Os,
+ OUT gckIOMMU * Iommu
+ )
+{
+ gceSTATUS status;
+ gckIOMMU iommu = gcvNULL;
+ struct device *dev;
+ int ret;
+
+ gcmkHEADER();
+
+ dev = &Os->device->platform->device->dev;
+
+ gcmkONERROR(gckOS_Allocate(Os, gcmSIZEOF(gcsIOMMU), (gctPOINTER *)&iommu));
+
+ gckOS_ZeroMemory(iommu, gcmSIZEOF(gcsIOMMU));
+
+ iommu->domain = iommu_domain_alloc(&platform_bus_type);
+
+ if (!iommu->domain)
+ {
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_OS, "iommu_domain_alloc() fail");
+
+ gcmkONERROR(gcvSTATUS_NOT_SUPPORTED);
+ }
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0)
+ iommu_set_fault_handler(iommu->domain, _IOMMU_Fault_Handler, dev);
+#else
+ iommu_set_fault_handler(iommu->domain, _IOMMU_Fault_Handler);
+#endif
+
+ ret = iommu_attach_device(iommu->domain, dev);
+
+ if (ret)
+ {
+ gcmkTRACE_ZONE(
+ gcvLEVEL_INFO, gcvZONE_OS, "iommu_attach_device() fail %d", ret);
+
+ gcmkONERROR(gcvSTATUS_NOT_SUPPORTED);
+ }
+
+ iommu->device = dev;
+
+ _FlatMapping(iommu);
+
+ *Iommu = iommu;
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+
+ gckIOMMU_Destory(Os, iommu);
+
+ gcmkFOOTER();
+ return status;
+}
+
+gceSTATUS
+gckIOMMU_Map(
+ IN gckIOMMU Iommu,
+ IN gctUINT32 DomainAddress,
+ IN gctUINT32 Physical,
+ IN gctUINT32 Bytes
+ )
+{
+ gceSTATUS status;
+ int ret;
+
+ gcmkHEADER_ARG("DomainAddress=%#X, Physical=%#X, Bytes=%d",
+ DomainAddress, Physical, Bytes);
+
+ ret = iommu_map(Iommu->domain, DomainAddress, Physical, Bytes, 0);
+
+ if (ret)
+ {
+ gcmkONERROR(gcvSTATUS_NOT_SUPPORTED);
+ }
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+
+ gcmkFOOTER();
+ return status;
+
+}
+
+gceSTATUS
+gckIOMMU_Unmap(
+ IN gckIOMMU Iommu,
+ IN gctUINT32 DomainAddress,
+ IN gctUINT32 Bytes
+ )
+{
+ gcmkHEADER();
+
+ iommu_unmap(Iommu->domain, DomainAddress, Bytes);
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+}
+
diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_linux.c b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_linux.c
new file mode 100644
index 000000000000..5efa3d404790
--- /dev/null
+++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_linux.c
@@ -0,0 +1,510 @@
+/****************************************************************************
+*
+* The MIT License (MIT)
+*
+* Copyright (c) 2014 - 2018 Vivante 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 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 GPL License (GPL)
+*
+* Copyright (C) 2014 - 2018 Vivante 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.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+*****************************************************************************
+*
+* Note: This software is released under dual MIT and GPL licenses. A
+* recipient may use this file under the terms of either the MIT license or
+* GPL License. If you wish to use only one license not the other, you can
+* indicate your decision by deleting one of the above license notices in your
+* version of this file.
+*
+*****************************************************************************/
+
+
+#include "gc_hal_kernel_linux.h"
+
+#define _GC_OBJ_ZONE gcvZONE_KERNEL
+
+/******************************************************************************\
+******************************* gckKERNEL API Code ******************************
+\******************************************************************************/
+
+/*******************************************************************************
+**
+** gckKERNEL_QueryVideoMemory
+**
+** Query the amount of video memory.
+**
+** INPUT:
+**
+** gckKERNEL Kernel
+** Pointer to an gckKERNEL object.
+**
+** OUTPUT:
+**
+** gcsHAL_INTERFACE * Interface
+** Pointer to an gcsHAL_INTERFACE structure that will be filled in with
+** the memory information.
+*/
+gceSTATUS
+gckKERNEL_QueryVideoMemory(
+ IN gckKERNEL Kernel,
+ OUT gcsHAL_INTERFACE * Interface
+ )
+{
+ gckGALDEVICE device;
+
+ gcmkHEADER_ARG("Kernel=%p", Kernel);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
+ gcmkVERIFY_ARGUMENT(Interface != NULL);
+
+ /* Extract the pointer to the gckGALDEVICE class. */
+ device = (gckGALDEVICE) Kernel->context;
+
+ /* Get internal memory size and physical address. */
+ Interface->u.QueryVideoMemory.internalSize = device->internalSize;
+ Interface->u.QueryVideoMemory.internalPhysical = device->internalPhysicalName;
+
+ /* Get external memory size and physical address. */
+ Interface->u.QueryVideoMemory.externalSize = device->externalSize;
+ Interface->u.QueryVideoMemory.externalPhysical = device->externalPhysicalName;
+
+ /* Get contiguous memory size and physical address. */
+ Interface->u.QueryVideoMemory.contiguousSize = device->contiguousSize;
+ Interface->u.QueryVideoMemory.contiguousPhysical = device->contiguousPhysicalName;
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+}
+
+/*******************************************************************************
+**
+** gckKERNEL_GetVideoMemoryPool
+**
+** Get the gckVIDMEM object belonging to the specified pool.
+**
+** INPUT:
+**
+** gckKERNEL Kernel
+** Pointer to an gckKERNEL object.
+**
+** gcePOOL Pool
+** Pool to query gckVIDMEM object for.
+**
+** OUTPUT:
+**
+** gckVIDMEM * VideoMemory
+** Pointer to a variable that will hold the pointer to the gckVIDMEM
+** object belonging to the requested pool.
+*/
+gceSTATUS
+gckKERNEL_GetVideoMemoryPool(
+ IN gckKERNEL Kernel,
+ IN gcePOOL Pool,
+ OUT gckVIDMEM * VideoMemory
+ )
+{
+ gckGALDEVICE device;
+ gckVIDMEM videoMemory;
+
+ gcmkHEADER_ARG("Kernel=%p Pool=%d", Kernel, Pool);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
+ gcmkVERIFY_ARGUMENT(VideoMemory != NULL);
+
+ /* Extract the pointer to the gckGALDEVICE class. */
+ device = (gckGALDEVICE) Kernel->context;
+
+ /* Dispatch on pool. */
+ switch (Pool)
+ {
+ case gcvPOOL_LOCAL_INTERNAL:
+ /* Internal memory. */
+ videoMemory = device->internalVidMem;
+ break;
+
+ case gcvPOOL_LOCAL_EXTERNAL:
+ /* External memory. */
+ videoMemory = device->externalVidMem;
+ break;
+
+ case gcvPOOL_SYSTEM:
+ /* System memory. */
+ videoMemory = device->contiguousVidMem;
+ break;
+
+ default:
+ /* Unknown pool. */
+ videoMemory = NULL;
+ }
+
+ /* Return pointer to the gckVIDMEM object. */
+ *VideoMemory = videoMemory;
+
+ /* Return status. */
+ gcmkFOOTER_ARG("*VideoMemory=%p", *VideoMemory);
+ return (videoMemory == NULL) ? gcvSTATUS_OUT_OF_MEMORY : gcvSTATUS_OK;
+}
+
+/*******************************************************************************
+**
+** gckKERNEL_MapMemory
+**
+** Map video memory into the current process space.
+**
+** INPUT:
+**
+** gckKERNEL Kernel
+** Pointer to an gckKERNEL object.
+**
+** gctPHYS_ADDR Physical
+** Physical address of video memory to map.
+**
+** gctSIZE_T Bytes
+** Number of bytes to map.
+**
+** OUTPUT:
+**
+** gctPOINTER * Logical
+** Pointer to a variable that will hold the base address of the mapped
+** memory region.
+*/
+gceSTATUS
+gckKERNEL_MapMemory(
+ IN gckKERNEL Kernel,
+ IN gctPHYS_ADDR Physical,
+ IN gctSIZE_T Bytes,
+ OUT gctPOINTER * Logical
+ )
+{
+ gckKERNEL kernel = Kernel;
+ gctPHYS_ADDR physical = gcmNAME_TO_PTR(Physical);
+
+ return gckOS_MapMemory(Kernel->os, physical, Bytes, Logical);
+}
+
+/*******************************************************************************
+**
+** gckKERNEL_UnmapMemory
+**
+** Unmap video memory from the current process space.
+**
+** INPUT:
+**
+** gckKERNEL Kernel
+** Pointer to an gckKERNEL object.
+**
+** gctPHYS_ADDR Physical
+** Physical address of video memory to map.
+**
+** gctSIZE_T Bytes
+** Number of bytes to map.
+**
+** gctPOINTER Logical
+** Base address of the mapped memory region.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckKERNEL_UnmapMemory(
+ IN gckKERNEL Kernel,
+ IN gctPHYS_ADDR Physical,
+ IN gctSIZE_T Bytes,
+ IN gctPOINTER Logical,
+ IN gctUINT32 ProcessID
+ )
+{
+ gckKERNEL kernel = Kernel;
+ gctPHYS_ADDR physical = gcmNAME_TO_PTR(Physical);
+
+ return gckOS_UnmapMemoryEx(Kernel->os, physical, Bytes, Logical, ProcessID);
+}
+
+/*******************************************************************************
+**
+** gckKERNEL_MapVideoMemory
+**
+** Get the logical address for a hardware specific memory address for the
+** current process.
+**
+** INPUT:
+**
+** gckKERNEL Kernel
+** Pointer to an gckKERNEL object.
+**
+** gctBOOL InUserSpace
+** gcvTRUE to map the memory into the user space.
+**
+** gctUINT32 Address
+** Hardware specific memory address.
+**
+** OUTPUT:
+**
+** gctPOINTER * Logical
+** Pointer to a variable that will hold the logical address of the
+** specified memory address.
+*/
+gceSTATUS
+gckKERNEL_MapVideoMemoryEx(
+ IN gckKERNEL Kernel,
+ IN gceCORE Core,
+ IN gctBOOL InUserSpace,
+ IN gctUINT32 Address,
+ IN gcePOOL Pool,
+ OUT gctPOINTER * Logical
+ )
+{
+ gckGALDEVICE device = gcvNULL;
+ gctUINT32 offset = 0;
+ gctUINT32 base = 0;
+ gctSIZE_T bytes = 0;
+ gctPHYS_ADDR physical = gcvNULL;
+ gceSTATUS status;
+ gctPOINTER logical = gcvNULL;
+#if gcdENABLE_VG
+ gcePOOL pool = gcvPOOL_UNKNOWN;
+#endif
+
+ gcmkHEADER_ARG("Kernel=%p InUserSpace=%d Address=%08x",
+ Kernel, InUserSpace, Address);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
+ gcmkVERIFY_ARGUMENT(Logical != NULL);
+
+ /* Extract the pointer to the gckGALDEVICE class. */
+ device = (gckGALDEVICE) Kernel->context;
+
+#if gcdENABLE_VG
+ if (Core == gcvCORE_VG)
+ {
+ /* Split the memory address into a pool type and offset. */
+ gcmkONERROR(
+ gckVGHARDWARE_SplitMemory(Kernel->vg->hardware, Address, &pool, &offset));
+ }
+ else
+#endif
+ {
+ offset = Address;
+ }
+
+ /* Dispatch on pool. */
+ switch (Pool)
+ {
+ case gcvPOOL_LOCAL_INTERNAL:
+ /* Internal memory. */
+ logical = device->internalLogical;
+ /* Impossible to use per device logical for all user processes. */
+ BUG_ON("Incorrect path");
+ break;
+
+ case gcvPOOL_LOCAL_EXTERNAL:
+ physical = device->externalPhysical;
+ bytes = device->externalSize;
+
+#if gcdENABLE_VG
+ if (Core == gcvCORE_VG)
+ {
+ gcmkVERIFY_OK(
+ gckVGHARDWARE_SplitMemory(Kernel->vg->hardware,
+ device->externalVidMem->baseAddress,
+ &pool,
+ &base));
+ }
+ else
+#endif
+ {
+ base = Kernel->externalBaseAddress;
+ }
+
+ break;
+
+ case gcvPOOL_SYSTEM:
+ /* System memory. */
+ physical = device->contiguousPhysical;
+ bytes = device->contiguousSize;
+
+#if gcdENABLE_VG
+ if (Core == gcvCORE_VG)
+ {
+ gcmkVERIFY_OK(
+ gckVGHARDWARE_SplitMemory(Kernel->vg->hardware,
+ device->contiguousVidMem->baseAddress,
+ &pool,
+ &base));
+ }
+ else
+#endif
+ {
+ base = Kernel->contiguousBaseAddress;
+ }
+
+ break;
+
+ default:
+ /* Invalid memory pool. */
+ gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
+ }
+
+ gcmkONERROR(gckOS_MapMemory(Kernel->os, physical, bytes, &logical));
+
+ /* GPU address offset */
+ offset -= base;
+
+ /* Build logical address of specified address. */
+ *Logical = (gctPOINTER) ((gctUINT8_PTR) logical + offset);
+
+ /* Success. */
+ gcmkFOOTER_ARG("*Logical=%p", *Logical);
+ return gcvSTATUS_OK;
+
+OnError:
+ /* Retunn the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+/*******************************************************************************
+**
+** gckKERNEL_MapVideoMemory
+**
+** Get the logical address for a hardware specific memory address for the
+** current process.
+**
+** INPUT:
+**
+** gckKERNEL Kernel
+** Pointer to an gckKERNEL object.
+**
+** gctBOOL InUserSpace
+** gcvTRUE to map the memory into the user space.
+**
+** gctUINT32 Address
+** Hardware specific memory address.
+**
+** OUTPUT:
+**
+** gctPOINTER * Logical
+** Pointer to a variable that will hold the logical address of the
+** specified memory address.
+*/
+gceSTATUS
+gckKERNEL_MapVideoMemory(
+ IN gckKERNEL Kernel,
+ IN gctBOOL InUserSpace,
+ IN gctUINT32 Address,
+ OUT gctPOINTER * Logical
+ )
+{
+ return gckKERNEL_MapVideoMemoryEx(Kernel, gcvCORE_MAJOR, InUserSpace, Address, gcvPOOL_SYSTEM, Logical);
+}
+/*******************************************************************************
+**
+** gckKERNEL_Notify
+**
+** This function iscalled by clients to notify the gckKERNRL object of an event.
+**
+** INPUT:
+**
+** gckKERNEL Kernel
+** Pointer to an gckKERNEL object.
+**
+** gceNOTIFY Notification
+** Notification event.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckKERNEL_Notify(
+ IN gckKERNEL Kernel,
+ IN gceNOTIFY Notification,
+ IN gctBOOL Data
+ )
+{
+ gceSTATUS status;
+
+ /* Dispatch on notifcation. */
+ switch (Notification)
+ {
+ case gcvNOTIFY_INTERRUPT:
+ /* Process the interrupt. */
+#if COMMAND_PROCESSOR_VERSION > 1
+ status = gckINTERRUPT_Notify(Kernel->interrupt, Data);
+#else
+ status = gckHARDWARE_Interrupt(Kernel->hardware, Data);
+#endif
+ break;
+
+ default:
+ status = gcvSTATUS_OK;
+ break;
+ }
+
+ /* Success. */
+ return status;
+}
+
+gceSTATUS
+gckKERNEL_QuerySettings(
+ IN gckKERNEL Kernel,
+ OUT gcsKERNEL_SETTINGS * Settings
+ )
+{
+ gckGALDEVICE device;
+
+ gcmkHEADER_ARG("Kernel=%p", Kernel);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
+ gcmkVERIFY_ARGUMENT(Settings != gcvNULL);
+
+ /* Extract the pointer to the gckGALDEVICE class. */
+ device = (gckGALDEVICE) Kernel->context;
+
+ /* Fill in signal. */
+ Settings->signal = device->signal;
+
+ /* Success. */
+ gcmkFOOTER_ARG("Settings->signal=%d", Settings->signal);
+ return gcvSTATUS_OK;
+}
diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_linux.h b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_linux.h
new file mode 100644
index 000000000000..c536e44d6755
--- /dev/null
+++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_linux.h
@@ -0,0 +1,411 @@
+/****************************************************************************
+*
+* The MIT License (MIT)
+*
+* Copyright (c) 2014 - 2018 Vivante 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 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 GPL License (GPL)
+*
+* Copyright (C) 2014 - 2018 Vivante 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.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+*****************************************************************************
+*
+* Note: This software is released under dual MIT and GPL licenses. A
+* recipient may use this file under the terms of either the MIT license or
+* GPL License. If you wish to use only one license not the other, you can
+* indicate your decision by deleting one of the above license notices in your
+* version of this file.
+*
+*****************************************************************************/
+
+
+#ifndef __gc_hal_kernel_linux_h_
+#define __gc_hal_kernel_linux_h_
+
+#include <linux/version.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/signal.h>
+#include <linux/interrupt.h>
+#include <linux/vmalloc.h>
+#include <linux/dma-mapping.h>
+#include <linux/kthread.h>
+
+#include <linux/idr.h>
+
+#ifdef MODVERSIONS
+# include <linux/modversions.h>
+#endif
+#include <asm/io.h>
+#include <asm/uaccess.h>
+
+#if ENABLE_GPU_CLOCK_BY_DRIVER && LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28)
+#include <linux/clk.h>
+#endif
+
+#define NTSTRSAFE_NO_CCH_FUNCTIONS
+#include "gc_hal.h"
+#include "gc_hal_driver.h"
+#include "gc_hal_kernel.h"
+#include "gc_hal_kernel_platform.h"
+#include "gc_hal_kernel_device.h"
+#include "gc_hal_kernel_os.h"
+#include "gc_hal_kernel_debugfs.h"
+#include "gc_hal_ta.h"
+
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,31)
+#define FIND_TASK_BY_PID(x) pid_task(find_vpid(x), PIDTYPE_PID)
+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
+#define FIND_TASK_BY_PID(x) find_task_by_vpid(x)
+#else
+#define FIND_TASK_BY_PID(x) find_task_by_pid(x)
+#endif
+
+#ifndef DEVICE_NAME
+# define DEVICE_NAME "galcore"
+#endif
+
+#ifndef CLASS_NAME
+# define CLASS_NAME "graphics_class"
+#endif
+
+#define GetPageCount(size, offset) ((((size) + ((offset) & ~PAGE_MASK)) + PAGE_SIZE - 1) >> PAGE_SHIFT)
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION (3,7,0)
+#define gcdVM_FLAGS (VM_IO | VM_DONTCOPY | VM_DONTEXPAND | VM_DONTDUMP)
+#else
+#define gcdVM_FLAGS (VM_IO | VM_DONTCOPY | VM_DONTEXPAND | VM_RESERVED)
+#endif
+
+/* Protection bit when mapping memroy to user sapce */
+#define gcmkPAGED_MEMROY_PROT(x) pgprot_writecombine(x)
+
+#define gcdSUPPRESS_OOM_MESSAGE 1
+
+#if gcdSUPPRESS_OOM_MESSAGE
+#define gcdNOWARN __GFP_NOWARN
+#else
+#define gcdNOWARN 0
+#endif
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION (4, 1, 0)
+#ifdef gcdIRQ_SHARED
+# define gcdIRQF_FLAG (IRQF_SHARED)
+# else
+# define gcdIRQF_FLAG (0)
+# endif
+#else
+#ifdef gcdIRQ_SHARED
+# define gcdIRQF_FLAG (IRQF_DISABLED | IRQF_SHARED)
+# else
+# define gcdIRQF_FLAG (IRQF_DISABLED)
+# endif
+#endif
+
+/* gcdLINUX_SYNC_FILE and CONFIG_SYNC_FILE. */
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,10,0)
+# define dma_fence fence
+# define dma_fence_array fence_array
+# define dma_fence_ops fence_ops
+
+# define dma_fence_default_wait fence_default_wait
+
+# define dma_fence_signal(f) fence_signal(f)
+# define dma_fence_signal_locked(f) fence_signal_locked(f)
+# define dma_fence_get(f) fence_get(f)
+# define dma_fence_put(f) fence_put(f)
+# define dma_fence_is_array(f) fence_is_array(f)
+# define dma_fence_is_signaled(f) fence_is_signaled(f)
+# define to_dma_fence_array(f) to_fence_array(f)
+# define dma_fence_wait_timeout(f, n, t) fence_wait_timeout((f), (n), (t))
+# define dma_fence_init(f, o, l, t, s) fence_init((f), (o), (l), (t), (s))
+# define dma_fence_context_alloc(s) fence_context_alloc(s)
+
+#endif
+
+extern struct device *galcore_device;
+
+/******************************************************************************\
+********************************** Structures **********************************
+\******************************************************************************/
+typedef struct _gcsIOMMU * gckIOMMU;
+
+typedef struct _gcsUSER_MAPPING * gcsUSER_MAPPING_PTR;
+typedef struct _gcsUSER_MAPPING
+{
+ /* Pointer to next mapping structure. */
+ gcsUSER_MAPPING_PTR next;
+
+ /* Physical address of this mapping. */
+ gctUINT32 physical;
+
+ /* Logical address of this mapping. */
+ gctPOINTER logical;
+
+ /* Number of bytes of this mapping. */
+ gctSIZE_T bytes;
+
+ /* Starting address of this mapping. */
+ gctINT8_PTR start;
+
+ /* Ending address of this mapping. */
+ gctINT8_PTR end;
+}
+gcsUSER_MAPPING;
+
+typedef struct _gcsINTEGER_DB * gcsINTEGER_DB_PTR;
+typedef struct _gcsINTEGER_DB
+{
+ struct idr idr;
+ spinlock_t lock;
+ gctINT curr;
+}
+gcsINTEGER_DB;
+
+struct _gckOS
+{
+ /* Object. */
+ gcsOBJECT object;
+
+ /* Pointer to device */
+ gckGALDEVICE device;
+
+ /* Memory management */
+ struct mutex mdlMutex;
+ struct list_head mdlHead;
+
+ /* Kernel process ID. */
+ gctUINT32 kernelProcessID;
+
+ /* Signal management. */
+
+ /* Lock. */
+ spinlock_t signalLock;
+
+ /* signal id database. */
+ gcsINTEGER_DB signalDB;
+
+ gcsUSER_MAPPING_PTR userMap;
+
+ /* workqueue for os timer. */
+ struct workqueue_struct * workqueue;
+
+ /* Allocate extra page to avoid cache overflow */
+ struct page* paddingPage;
+
+ /* Detect unfreed allocation. */
+ atomic_t allocateCount;
+
+ struct list_head allocatorList;
+
+ gcsDEBUGFS_DIR allocatorDebugfsDir;
+
+ gctBOOL allocatorLimitMarker;
+
+ /* Lock for register access check. */
+ spinlock_t registerAccessLock;
+
+ /* External power states. */
+ gctBOOL powerStates[gcdMAX_GPU_COUNT];
+
+ /* External clock states. */
+ gctBOOL clockStates[gcdMAX_GPU_COUNT];
+
+ /* IOMMU. */
+ gckIOMMU iommu;
+};
+
+typedef struct _gcsSIGNAL * gcsSIGNAL_PTR;
+typedef struct _gcsSIGNAL
+{
+ /* Kernel sync primitive. */
+ volatile unsigned int done;
+ spinlock_t lock;
+
+ wait_queue_head_t wait;
+
+ /* Manual reset flag. */
+ gctBOOL manualReset;
+
+ /* The reference counter. */
+ atomic_t ref;
+
+ /* The owner of the signal. */
+ gctHANDLE process;
+
+ /* ID. */
+ gctUINT32 id;
+
+#if gcdLINUX_SYNC_FILE
+#ifndef CONFIG_SYNC_FILE
+ /* Parent timeline. */
+ struct sync_timeline * timeline;
+# else
+ struct dma_fence *fence;
+# endif
+#endif
+}
+gcsSIGNAL;
+
+typedef struct _gcsOSTIMER * gcsOSTIMER_PTR;
+typedef struct _gcsOSTIMER
+{
+ struct delayed_work work;
+ gctTIMERFUNCTION function;
+ gctPOINTER data;
+} gcsOSTIMER;
+
+gceSTATUS
+gckOS_ImportAllocators(
+ gckOS Os
+ );
+
+gceSTATUS
+gckOS_FreeAllocators(
+ gckOS Os
+ );
+
+/* Reserved memory. */
+gceSTATUS
+gckOS_RequestReservedMemory(
+ gckOS Os,
+ unsigned long Start,
+ unsigned long Size,
+ const char * Name,
+ gctBOOL Requested,
+ void ** MemoryHandle
+ );
+
+void
+gckOS_ReleaseReservedMemory(
+ gckOS Os,
+ void * MemoryHandle
+ );
+
+gceSTATUS
+_ConvertLogical2Physical(
+ IN gckOS Os,
+ IN gctPOINTER Logical,
+ IN gctUINT32 ProcessID,
+ IN PLINUX_MDL Mdl,
+ OUT gctPHYS_ADDR_T * Physical
+ );
+
+gctBOOL
+_QuerySignal(
+ IN gckOS Os,
+ IN gctSIGNAL Signal
+ );
+
+static inline gctINT
+_GetProcessID(
+ void
+ )
+{
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
+ return task_tgid_vnr(current);
+#else
+ return current->tgid;
+#endif
+}
+
+static inline void
+_MemoryBarrier(
+ void
+ )
+{
+#if defined(CONFIG_ARM) && (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,34))
+ dsb();
+#else
+ mb();
+#endif
+}
+
+static inline void
+_Barrier(
+ void
+ )
+{
+ barrier();
+}
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,25)
+static inline int
+is_vmalloc_addr(
+ void *Addr
+ )
+{
+ unsigned long addr = (unsigned long)Addr;
+
+ return addr >= VMALLOC_START && addr < VMALLOC_END;
+}
+#endif
+
+#ifdef CONFIG_IOMMU_SUPPORT
+void
+gckIOMMU_Destory(
+ IN gckOS Os,
+ IN gckIOMMU Iommu
+ );
+
+gceSTATUS
+gckIOMMU_Construct(
+ IN gckOS Os,
+ OUT gckIOMMU * Iommu
+ );
+
+gceSTATUS
+gckIOMMU_Map(
+ IN gckIOMMU Iommu,
+ IN gctUINT32 DomainAddress,
+ IN gctUINT32 Physical,
+ IN gctUINT32 Bytes
+ );
+
+gceSTATUS
+gckIOMMU_Unmap(
+ IN gckIOMMU Iommu,
+ IN gctUINT32 DomainAddress,
+ IN gctUINT32 Bytes
+ );
+#endif
+
+#endif /* __gc_hal_kernel_linux_h_ */
diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_math.c b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_math.c
new file mode 100644
index 000000000000..f373f47a41e0
--- /dev/null
+++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_math.c
@@ -0,0 +1,66 @@
+/****************************************************************************
+*
+* The MIT License (MIT)
+*
+* Copyright (c) 2014 - 2018 Vivante 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 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 GPL License (GPL)
+*
+* Copyright (C) 2014 - 2018 Vivante 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.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+*****************************************************************************
+*
+* Note: This software is released under dual MIT and GPL licenses. A
+* recipient may use this file under the terms of either the MIT license or
+* GPL License. If you wish to use only one license not the other, you can
+* indicate your decision by deleting one of the above license notices in your
+* version of this file.
+*
+*****************************************************************************/
+
+
+#include "gc_hal_kernel_linux.h"
+
+gctINT
+gckMATH_ModuloInt(
+ IN gctINT X,
+ IN gctINT Y
+ )
+{
+ if(Y ==0) {return 0;}
+ else {return X % Y;}
+}
diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_mutex.h b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_mutex.h
new file mode 100644
index 000000000000..d2c94e2254ad
--- /dev/null
+++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_mutex.h
@@ -0,0 +1,89 @@
+/****************************************************************************
+*
+* The MIT License (MIT)
+*
+* Copyright (c) 2014 - 2018 Vivante 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 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 GPL License (GPL)
+*
+* Copyright (C) 2014 - 2018 Vivante 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.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+*****************************************************************************
+*
+* Note: This software is released under dual MIT and GPL licenses. A
+* recipient may use this file under the terms of either the MIT license or
+* GPL License. If you wish to use only one license not the other, you can
+* indicate your decision by deleting one of the above license notices in your
+* version of this file.
+*
+*****************************************************************************/
+
+
+#ifndef _gc_hal_kernel_mutex_h_
+#define _gc_hal_kernel_mutex_h_
+
+#include "gc_hal.h"
+#include <linux/mutex.h>
+
+/* Create a new mutex. */
+#define gckOS_CreateMutex(Os, Mutex) \
+({ \
+ gceSTATUS _status; \
+ gcmkHEADER_ARG("Os=0x%X", Os); \
+ \
+ /* Validate the arguments. */ \
+ gcmkVERIFY_OBJECT(Os, gcvOBJ_OS); \
+ gcmkVERIFY_ARGUMENT(Mutex != gcvNULL); \
+ \
+ /* Allocate the mutex structure. */ \
+ _status = gckOS_Allocate(Os, gcmSIZEOF(struct mutex), Mutex); \
+ \
+ if (gcmIS_SUCCESS(_status)) \
+ { \
+ /* Initialize the mutex. */ \
+ mutex_init(*(struct mutex **)Mutex); \
+ } \
+ \
+ /* Return status. */ \
+ gcmkFOOTER_ARG("*Mutex=0x%X", *(struct mutex **)Mutex); \
+ _status; \
+})
+
+#endif
+
+
+
diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.c b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.c
new file mode 100644
index 000000000000..0d06fc1022a9
--- /dev/null
+++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.c
@@ -0,0 +1,7822 @@
+/****************************************************************************
+*
+* The MIT License (MIT)
+*
+* Copyright (c) 2014 - 2018 Vivante 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 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 GPL License (GPL)
+*
+* Copyright (C) 2014 - 2018 Vivante 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.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+*****************************************************************************
+*
+* Note: This software is released under dual MIT and GPL licenses. A
+* recipient may use this file under the terms of either the MIT license or
+* GPL License. If you wish to use only one license not the other, you can
+* indicate your decision by deleting one of the above license notices in your
+* version of this file.
+*
+*****************************************************************************/
+
+
+#include "gc_hal_kernel_linux.h"
+
+#include <linux/pagemap.h>
+#include <linux/seq_file.h>
+#include <linux/mman.h>
+#include <asm/atomic.h>
+#include <linux/dma-mapping.h>
+#include <linux/slab.h>
+#include <linux/workqueue.h>
+#include <linux/irqflags.h>
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,23)
+#include <linux/math64.h>
+#endif
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
+#include <linux/anon_inodes.h>
+#endif
+
+#if gcdLINUX_SYNC_FILE
+# include <linux/file.h>
+# include "gc_hal_kernel_sync.h"
+#endif
+
+#if defined(CONFIG_DMA_SHARED_BUFFER)
+#include <linux/dma-buf.h>
+#endif
+
+#if defined(CONFIG_ARM) && LINUX_VERSION_CODE >= KERNEL_VERSION(4, 3, 0)
+#include <dma.h>
+#endif
+
+#define _GC_OBJ_ZONE gcvZONE_OS
+
+#include "gc_hal_kernel_allocator.h"
+
+#define gcmkBUG_ON(x) \
+ do { \
+ if (unlikely(!!(x))) \
+ { \
+ printk("[galcore]: BUG ON @ %s(%d)\n", __func__, __LINE__); \
+ dump_stack(); \
+ } \
+ } while (0)
+
+/******************************************************************************\
+******************************* Private Functions ******************************
+\******************************************************************************/
+static gctINT
+_GetThreadID(
+ void
+ )
+{
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
+ return task_pid_vnr(current);
+#else
+ return current->pid;
+#endif
+}
+
+/* Must hold Mdl->mpasMutex before call this function. */
+static inline PLINUX_MDL_MAP
+_CreateMdlMap(
+ IN PLINUX_MDL Mdl,
+ IN gctINT ProcessID
+ )
+{
+ PLINUX_MDL_MAP mdlMap;
+
+ gcmkHEADER_ARG("Mdl=0x%X ProcessID=%d", Mdl, ProcessID);
+
+ mdlMap = (PLINUX_MDL_MAP)kmalloc(sizeof(struct _LINUX_MDL_MAP), GFP_KERNEL | gcdNOWARN);
+
+ if (mdlMap == gcvNULL)
+ {
+ gcmkFOOTER_NO();
+ return gcvNULL;
+ }
+
+ mdlMap->pid = ProcessID;
+ mdlMap->vmaAddr = gcvNULL;
+ mdlMap->count = 0;
+
+ list_add(&mdlMap->link, &Mdl->mapsHead);
+
+ gcmkFOOTER_ARG("0x%X", mdlMap);
+ return mdlMap;
+}
+
+/* Must hold Mdl->mpasMutex before call this function. */
+static inline gceSTATUS
+_DestroyMdlMap(
+ IN PLINUX_MDL Mdl,
+ IN PLINUX_MDL_MAP MdlMap
+ )
+{
+ gcmkHEADER_ARG("Mdl=0x%X MdlMap=0x%X", Mdl, MdlMap);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_ARGUMENT(MdlMap != gcvNULL);
+
+ list_del(&MdlMap->link);
+ kfree(MdlMap);
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+}
+
+/* Must hold Mdl->mpasMutex before call this function. */
+extern PLINUX_MDL_MAP
+FindMdlMap(
+ IN PLINUX_MDL Mdl,
+ IN gctINT ProcessID
+ )
+{
+ PLINUX_MDL_MAP mdlMap;
+
+ gcmkHEADER_ARG("Mdl=0x%X ProcessID=%d", Mdl, ProcessID);
+
+ if (Mdl == gcvNULL)
+ {
+ gcmkFOOTER_NO();
+ return gcvNULL;
+ }
+
+ list_for_each_entry(mdlMap, &Mdl->mapsHead, link)
+ {
+ if (mdlMap->pid == ProcessID)
+ {
+ gcmkFOOTER_ARG("0x%X", mdlMap);
+ return mdlMap;
+ }
+ }
+
+ gcmkFOOTER_NO();
+ return gcvNULL;
+}
+
+
+static PLINUX_MDL
+_CreateMdl(
+ IN gckOS Os
+ )
+{
+ PLINUX_MDL mdl;
+
+ gcmkHEADER();
+
+ mdl = (PLINUX_MDL)kzalloc(sizeof(struct _LINUX_MDL), GFP_KERNEL | gcdNOWARN);
+
+ if (mdl)
+ {
+ mdl->os = Os;
+ atomic_set(&mdl->refs, 1);
+ mutex_init(&mdl->mapsMutex);
+ INIT_LIST_HEAD(&mdl->mapsHead);
+ }
+
+ gcmkFOOTER_ARG("0x%X", mdl);
+ return mdl;
+}
+
+static gceSTATUS
+_DestroyMdl(
+ IN PLINUX_MDL Mdl
+ )
+{
+ gcmkHEADER_ARG("Mdl=0x%X", Mdl);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_ARGUMENT(Mdl != gcvNULL);
+
+ if (atomic_dec_and_test(&Mdl->refs))
+ {
+ gckOS os = Mdl->os;
+ gckALLOCATOR allocator = Mdl->allocator;
+ PLINUX_MDL_MAP mdlMap, next;
+
+ /* Valid private means alloc/attach successfully */
+ if (Mdl->priv)
+ {
+ if (Mdl->addr)
+ {
+ allocator->ops->UnmapKernel(allocator, Mdl, Mdl->addr);
+ }
+ allocator->ops->Free(allocator, Mdl);
+ }
+
+ mutex_lock(&Mdl->mapsMutex);
+ list_for_each_entry_safe(mdlMap, next, &Mdl->mapsHead, link)
+ {
+ gcmkVERIFY_OK(_DestroyMdlMap(Mdl, mdlMap));
+ }
+ mutex_unlock(&Mdl->mapsMutex);
+
+ if (Mdl->link.next)
+ {
+ /* Remove the node from global list.. */
+ mutex_lock(&os->mdlMutex);
+ list_del(&Mdl->link);
+ mutex_unlock(&os->mdlMutex);
+ }
+
+ kfree(Mdl);
+ }
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+}
+
+/*******************************************************************************
+** Integer Id Management.
+*/
+gceSTATUS
+_AllocateIntegerId(
+ IN gcsINTEGER_DB_PTR Database,
+ IN gctPOINTER KernelPointer,
+ OUT gctUINT32 *Id
+ )
+{
+ int result;
+ gctINT next;
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0)
+ idr_preload(GFP_KERNEL | gcdNOWARN);
+
+ spin_lock(&Database->lock);
+
+ next = (Database->curr + 1 <= 0) ? 1 : Database->curr + 1;
+
+ result = idr_alloc(&Database->idr, KernelPointer, next, 0, GFP_ATOMIC);
+
+ /* ID allocated should not be 0. */
+ gcmkASSERT(result != 0);
+
+ if (result > 0)
+ {
+ Database->curr = *Id = result;
+ }
+
+ spin_unlock(&Database->lock);
+
+ idr_preload_end();
+
+ if (result < 0)
+ {
+ return gcvSTATUS_OUT_OF_RESOURCES;
+ }
+#else
+again:
+ if (idr_pre_get(&Database->idr, GFP_KERNEL | gcdNOWARN) == 0)
+ {
+ return gcvSTATUS_OUT_OF_MEMORY;
+ }
+
+ spin_lock(&Database->lock);
+
+ next = (Database->curr + 1 <= 0) ? 1 : Database->curr + 1;
+
+ /* Try to get a id greater than 0. */
+ result = idr_get_new_above(&Database->idr, KernelPointer, next, Id);
+
+ if (!result)
+ {
+ Database->curr = *Id;
+ }
+
+ spin_unlock(&Database->lock);
+
+ if (result == -EAGAIN)
+ {
+ goto again;
+ }
+
+ if (result != 0)
+ {
+ return gcvSTATUS_OUT_OF_RESOURCES;
+ }
+#endif
+
+ return gcvSTATUS_OK;
+}
+
+gceSTATUS
+_QueryIntegerId(
+ IN gcsINTEGER_DB_PTR Database,
+ IN gctUINT32 Id,
+ OUT gctPOINTER * KernelPointer
+ )
+{
+ gctPOINTER pointer;
+
+ spin_lock(&Database->lock);
+
+ pointer = idr_find(&Database->idr, Id);
+
+ spin_unlock(&Database->lock);
+
+ if (pointer)
+ {
+ *KernelPointer = pointer;
+ return gcvSTATUS_OK;
+ }
+ else
+ {
+ gcmkTRACE_ZONE(
+ gcvLEVEL_ERROR, gcvZONE_OS,
+ "%s(%d) Id = %d is not found",
+ __FUNCTION__, __LINE__, Id);
+
+ return gcvSTATUS_NOT_FOUND;
+ }
+}
+
+gceSTATUS
+_DestroyIntegerId(
+ IN gcsINTEGER_DB_PTR Database,
+ IN gctUINT32 Id
+ )
+{
+ spin_lock(&Database->lock);
+
+ idr_remove(&Database->idr, Id);
+
+ spin_unlock(&Database->lock);
+
+ return gcvSTATUS_OK;
+}
+
+static inline gceSTATUS
+_QueryProcessPageTable(
+ IN gctPOINTER Logical,
+ OUT gctPHYS_ADDR_T * Address
+ )
+{
+ unsigned long logical = (unsigned long)Logical;
+ unsigned long offset = logical & ~PAGE_MASK;
+
+ if (is_vmalloc_addr(Logical))
+ {
+ /* vmalloc area. */
+ *Address = page_to_phys(vmalloc_to_page(Logical)) | offset;
+ return gcvSTATUS_OK;
+ }
+ else if (virt_addr_valid(logical))
+ {
+ /* Kernel logical address. */
+ *Address = virt_to_phys(Logical);
+ return gcvSTATUS_OK;
+ }
+ else
+ {
+ /* Try user VM area. */
+ struct vm_area_struct *vma;
+ spinlock_t *ptl;
+ pgd_t *pgd;
+ pud_t *pud;
+ pmd_t *pmd;
+ pte_t *pte;
+
+ if (!current->mm)
+ return gcvSTATUS_NOT_FOUND;
+
+ down_read(&current->mm->mmap_sem);
+ vma = find_vma(current->mm, logical);
+ up_read(&current->mm->mmap_sem);
+
+ /* To check if mapped to user. */
+ if (!vma)
+ return gcvSTATUS_NOT_FOUND;
+
+ pgd = pgd_offset(current->mm, logical);
+ if (pgd_none(*pgd) || pgd_bad(*pgd))
+ return gcvSTATUS_NOT_FOUND;
+
+ pud = pud_offset(pgd, logical);
+ if (pud_none(*pud) || pud_bad(*pud))
+ return gcvSTATUS_NOT_FOUND;
+
+ pmd = pmd_offset(pud, logical);
+ if (pmd_none(*pmd) || pmd_bad(*pmd))
+ return gcvSTATUS_NOT_FOUND;
+
+ pte = pte_offset_map_lock(current->mm, pmd, logical, &ptl);
+ if (!pte)
+ {
+ spin_unlock(ptl);
+ return gcvSTATUS_NOT_FOUND;
+ }
+
+ if (!pte_present(*pte))
+ {
+ pte_unmap_unlock(pte, ptl);
+ return gcvSTATUS_NOT_FOUND;
+ }
+
+ *Address = (pte_pfn(*pte) << PAGE_SHIFT) | offset;
+ pte_unmap_unlock(pte, ptl);
+
+ return gcvSTATUS_OK;
+ }
+}
+
+
+static gceSTATUS
+_ShrinkMemory(
+ IN gckOS Os
+ )
+{
+ gcsPLATFORM * platform;
+ gceSTATUS status = gcvSTATUS_OK;
+
+ gcmkHEADER_ARG("Os=0x%X", Os);
+ gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
+
+ platform = Os->device->platform;
+
+ if (platform && platform->ops->shrinkMemory)
+ {
+ status = platform->ops->shrinkMemory(platform);
+ }
+ else
+ {
+ gcmkFOOTER_NO();
+ return gcvSTATUS_NOT_SUPPORTED;
+ }
+
+ gcmkFOOTER_NO();
+ return status;
+}
+
+/*******************************************************************************
+**
+** gckOS_Construct
+**
+** Construct a new gckOS object.
+**
+** INPUT:
+**
+** gctPOINTER Context
+** Pointer to the gckGALDEVICE class.
+**
+** OUTPUT:
+**
+** gckOS * Os
+** Pointer to a variable that will hold the pointer to the gckOS object.
+*/
+gceSTATUS
+gckOS_Construct(
+ IN gctPOINTER Context,
+ OUT gckOS * Os
+ )
+{
+ gckOS os;
+ gceSTATUS status;
+
+ gcmkHEADER_ARG("Context=0x%X", Context);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_ARGUMENT(Os != gcvNULL);
+
+ /* Allocate the gckOS object. */
+ os = (gckOS) kmalloc(gcmSIZEOF(struct _gckOS), GFP_KERNEL | gcdNOWARN);
+
+ if (os == gcvNULL)
+ {
+ /* Out of memory. */
+ gcmkFOOTER_ARG("status=%d", gcvSTATUS_OUT_OF_MEMORY);
+ return gcvSTATUS_OUT_OF_MEMORY;
+ }
+
+ /* Zero the memory. */
+ gckOS_ZeroMemory(os, gcmSIZEOF(struct _gckOS));
+
+ /* Initialize the gckOS object. */
+ os->object.type = gcvOBJ_OS;
+
+ /* Set device device. */
+ os->device = Context;
+
+ /* Set allocateCount to 0, gckOS_Allocate has not been used yet. */
+ atomic_set(&os->allocateCount, 0);
+
+ /* Initialize the memory lock. */
+ mutex_init(&os->mdlMutex);
+
+ INIT_LIST_HEAD(&os->mdlHead);
+
+ /* Get the kernel process ID. */
+ os->kernelProcessID = _GetProcessID();
+
+ /*
+ * Initialize the signal manager.
+ */
+
+ /* Initialize spinlock. */
+ spin_lock_init(&os->signalLock);
+
+ /* Initialize signal id database lock. */
+ spin_lock_init(&os->signalDB.lock);
+
+ /* Initialize signal id database. */
+ idr_init(&os->signalDB.idr);
+
+ /* Create a workqueue for os timer. */
+ os->workqueue = create_singlethread_workqueue("galcore workqueue");
+
+ if (os->workqueue == gcvNULL)
+ {
+ /* Out of memory. */
+ gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
+ }
+
+ os->paddingPage = alloc_page(GFP_KERNEL | __GFP_HIGHMEM | gcdNOWARN);
+ if (os->paddingPage == gcvNULL)
+ {
+ /* Out of memory. */
+ gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
+ }
+ else
+ {
+ SetPageReserved(os->paddingPage);
+ }
+
+ spin_lock_init(&os->registerAccessLock);
+
+ gckOS_ImportAllocators(os);
+
+#ifdef CONFIG_IOMMU_SUPPORT
+ if (((gckGALDEVICE)(os->device))->args.mmu == gcvFALSE)
+ {
+ /* Only use IOMMU when internal MMU is not enabled. */
+ status = gckIOMMU_Construct(os, &os->iommu);
+
+ if (gcmIS_ERROR(status))
+ {
+ gcmkTRACE_ZONE(
+ gcvLEVEL_INFO, gcvZONE_OS,
+ "%s(%d): Fail to setup IOMMU",
+ __FUNCTION__, __LINE__
+ );
+ }
+ }
+#endif
+
+ /* Return pointer to the gckOS object. */
+ *Os = os;
+
+ /* Success. */
+ gcmkFOOTER_ARG("*Os=0x%X", *Os);
+ return gcvSTATUS_OK;
+
+OnError:
+ if (os->workqueue != gcvNULL)
+ {
+ destroy_workqueue(os->workqueue);
+ }
+
+ kfree(os);
+
+ /* Return the error. */
+ gcmkFOOTER();
+ return status;
+}
+
+/*******************************************************************************
+**
+** gckOS_Destroy
+**
+** Destroy an gckOS object.
+**
+** INPUT:
+**
+** gckOS Os
+** Pointer to an gckOS object that needs to be destroyed.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckOS_Destroy(
+ IN gckOS Os
+ )
+{
+ gcmkHEADER_ARG("Os=0x%X", Os);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
+
+ if (Os->paddingPage != gcvNULL)
+ {
+ ClearPageReserved(Os->paddingPage);
+ __free_page(Os->paddingPage);
+ Os->paddingPage = gcvNULL;
+ }
+
+ /*
+ * Destroy the signal manager.
+ */
+
+ /* Wait for all works done. */
+ flush_workqueue(Os->workqueue);
+
+ /* Destory work queue. */
+ destroy_workqueue(Os->workqueue);
+
+ gckOS_FreeAllocators(Os);
+
+#ifdef CONFIG_IOMMU_SUPPORT
+ if (Os->iommu)
+ {
+ gckIOMMU_Destory(Os, Os->iommu);
+ }
+#endif
+
+ /* Flush the debug cache. */
+ gcmkDEBUGFLUSH(~0U);
+
+ /* Mark the gckOS object as unknown. */
+ Os->object.type = gcvOBJ_UNKNOWN;
+
+
+ /* Free the gckOS object. */
+ kfree(Os);
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+}
+
+gceSTATUS
+gckOS_CreateKernelMapping(
+ IN gckOS Os,
+ IN gctPHYS_ADDR Physical,
+ IN gctSIZE_T Offset,
+ IN gctSIZE_T Bytes,
+ OUT gctPOINTER * Logical
+ )
+{
+ gceSTATUS status = gcvSTATUS_OK;
+ PLINUX_MDL mdl = (PLINUX_MDL)Physical;
+ gckALLOCATOR allocator = mdl->allocator;
+
+ gcmkHEADER_ARG("Os=%p Physical=%p Offset=0x%zx Bytes=0x%zx",
+ Os, Physical, Offset, Bytes);
+
+ if (mdl->addr)
+ {
+ /* Already mapped whole memory. */
+ *Logical = (gctUINT8_PTR)mdl->addr + Offset;
+ }
+ else
+ {
+ gcmkONERROR(allocator->ops->MapKernel(allocator, mdl, Logical));
+ }
+
+OnError:
+ gcmkFOOTER_ARG("*Logical=%p", gcmOPT_POINTER(Logical));
+ return status;
+}
+
+gceSTATUS
+gckOS_DestroyKernelMapping(
+ IN gckOS Os,
+ IN gctPHYS_ADDR Physical,
+ IN gctPOINTER Logical
+ )
+{
+ PLINUX_MDL mdl = (PLINUX_MDL)Physical;
+ gckALLOCATOR allocator = mdl->allocator;
+
+ gcmkHEADER_ARG("Os=%p Physical=%p Logical=%p", Os, Physical, Logical);
+
+ if (mdl->addr)
+ {
+ /* Nothing to do. */
+ }
+ else
+ {
+ allocator->ops->UnmapKernel(allocator, mdl, Logical);
+ }
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+}
+
+gceSTATUS
+gckOS_CreateKernelVirtualMapping(
+ IN gckOS Os,
+ IN gctPHYS_ADDR Physical,
+ IN gctSIZE_T Bytes,
+ OUT gctPOINTER * Logical,
+ OUT gctSIZE_T * PageCount
+ )
+{
+ gceSTATUS status;
+ PLINUX_MDL mdl = (PLINUX_MDL)Physical;
+ gckALLOCATOR allocator = mdl->allocator;
+
+ gcmkHEADER();
+
+ *PageCount = mdl->numPages;
+
+ gcmkONERROR(allocator->ops->MapKernel(allocator, mdl, Logical));
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ gcmkFOOTER();
+ return status;
+}
+
+gceSTATUS
+gckOS_DestroyKernelVirtualMapping(
+ IN gckOS Os,
+ IN gctPHYS_ADDR Physical,
+ IN gctSIZE_T Bytes,
+ IN gctPOINTER Logical
+ )
+{
+ PLINUX_MDL mdl = (PLINUX_MDL)Physical;
+ gckALLOCATOR allocator = mdl->allocator;
+
+ gcmkHEADER();
+
+ allocator->ops->UnmapKernel(allocator, mdl, Logical);
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+}
+
+gceSTATUS
+gckOS_CreateUserVirtualMapping(
+ IN gckOS Os,
+ IN gctPHYS_ADDR Physical,
+ IN gctSIZE_T Bytes,
+ OUT gctPOINTER * Logical,
+ OUT gctSIZE_T * PageCount
+ )
+{
+ return gckOS_LockPages(Os, Physical, Bytes, gcvFALSE, Logical, PageCount);
+}
+
+gceSTATUS
+gckOS_DestroyUserVirtualMapping(
+ IN gckOS Os,
+ IN gctPHYS_ADDR Physical,
+ IN gctSIZE_T Bytes,
+ IN gctPOINTER Logical
+ )
+{
+ return gckOS_UnlockPages(Os, Physical, Bytes, Logical);
+}
+
+/*******************************************************************************
+**
+** gckOS_Allocate
+**
+** Allocate memory.
+**
+** INPUT:
+**
+** gckOS Os
+** Pointer to an gckOS object.
+**
+** gctSIZE_T Bytes
+** Number of bytes to allocate.
+**
+** OUTPUT:
+**
+** gctPOINTER * Memory
+** Pointer to a variable that will hold the allocated memory location.
+*/
+gceSTATUS
+gckOS_Allocate(
+ IN gckOS Os,
+ IN gctSIZE_T Bytes,
+ OUT gctPOINTER * Memory
+ )
+{
+ gceSTATUS status;
+
+ gcmkHEADER_ARG("Os=0x%X Bytes=%lu", Os, Bytes);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
+ gcmkVERIFY_ARGUMENT(Bytes > 0);
+ gcmkVERIFY_ARGUMENT(Memory != gcvNULL);
+
+ gcmkONERROR(gckOS_AllocateMemory(Os, Bytes, Memory));
+
+ /* Success. */
+ gcmkFOOTER_ARG("*Memory=0x%X", *Memory);
+ return gcvSTATUS_OK;
+
+OnError:
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+/*******************************************************************************
+**
+** gckOS_Free
+**
+** Free allocated memory.
+**
+** INPUT:
+**
+** gckOS Os
+** Pointer to an gckOS object.
+**
+** gctPOINTER Memory
+** Pointer to memory allocation to free.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckOS_Free(
+ IN gckOS Os,
+ IN gctPOINTER Memory
+ )
+{
+ gceSTATUS status;
+
+ gcmkHEADER_ARG("Os=0x%X Memory=0x%X", Os, Memory);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
+ gcmkVERIFY_ARGUMENT(Memory != gcvNULL);
+
+ gcmkONERROR(gckOS_FreeMemory(Os, Memory));
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+/*******************************************************************************
+**
+** gckOS_AllocateMemory
+**
+** Allocate memory wrapper.
+**
+** INPUT:
+**
+** gctSIZE_T Bytes
+** Number of bytes to allocate.
+**
+** OUTPUT:
+**
+** gctPOINTER * Memory
+** Pointer to a variable that will hold the allocated memory location.
+*/
+gceSTATUS
+gckOS_AllocateMemory(
+ IN gckOS Os,
+ IN gctSIZE_T Bytes,
+ OUT gctPOINTER * Memory
+ )
+{
+ gctPOINTER memory;
+ gceSTATUS status;
+
+ gcmkHEADER_ARG("Os=0x%X Bytes=%lu", Os, Bytes);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_ARGUMENT(Bytes > 0);
+ gcmkVERIFY_ARGUMENT(Memory != gcvNULL);
+
+ if (Bytes > PAGE_SIZE)
+ {
+ memory = (gctPOINTER) vmalloc(Bytes);
+ }
+ else
+ {
+ memory = (gctPOINTER) kmalloc(Bytes, GFP_KERNEL | gcdNOWARN);
+ }
+
+ if (memory == gcvNULL)
+ {
+ /* Out of memory. */
+ gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
+ }
+
+ /* Increase count. */
+ atomic_inc(&Os->allocateCount);
+
+ /* Return pointer to the memory allocation. */
+ *Memory = memory;
+
+ /* Success. */
+ gcmkFOOTER_ARG("*Memory=0x%X", *Memory);
+ return gcvSTATUS_OK;
+
+OnError:
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+/*******************************************************************************
+**
+** gckOS_FreeMemory
+**
+** Free allocated memory wrapper.
+**
+** INPUT:
+**
+** gctPOINTER Memory
+** Pointer to memory allocation to free.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckOS_FreeMemory(
+ IN gckOS Os,
+ IN gctPOINTER Memory
+ )
+{
+ gcmkHEADER_ARG("Memory=0x%X", Memory);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_ARGUMENT(Memory != gcvNULL);
+
+ /* Free the memory from the OS pool. */
+ if (is_vmalloc_addr(Memory))
+ {
+ vfree(Memory);
+ }
+ else
+ {
+ kfree(Memory);
+ }
+
+ /* Decrease count. */
+ atomic_dec(&Os->allocateCount);
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+}
+
+/*******************************************************************************
+**
+** gckOS_MapMemory
+**
+** Map physical memory into the current process.
+**
+** INPUT:
+**
+** gckOS Os
+** Pointer to an gckOS object.
+**
+** gctPHYS_ADDR Physical
+** Start of physical address memory.
+**
+** gctSIZE_T Bytes
+** Number of bytes to map.
+**
+** OUTPUT:
+**
+** gctPOINTER * Memory
+** Pointer to a variable that will hold the logical address of the
+** mapped memory.
+*/
+gceSTATUS
+gckOS_MapMemory(
+ IN gckOS Os,
+ IN gctPHYS_ADDR Physical,
+ IN gctSIZE_T Bytes,
+ OUT gctPOINTER * Logical
+ )
+{
+ gceSTATUS status;
+ PLINUX_MDL_MAP mdlMap;
+ PLINUX_MDL mdl = (PLINUX_MDL) Physical;
+ gckALLOCATOR allocator;
+ gctINT pid = _GetProcessID();
+
+ gcmkHEADER_ARG("Os=0x%X Physical=0x%X Bytes=%lu", Os, Physical, Bytes);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
+ gcmkVERIFY_ARGUMENT(Physical != 0);
+ gcmkVERIFY_ARGUMENT(Bytes > 0);
+ gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
+
+ mutex_lock(&mdl->mapsMutex);
+
+ mdlMap = FindMdlMap(mdl, pid);
+
+ if (mdlMap == gcvNULL)
+ {
+ mdlMap = _CreateMdlMap(mdl, pid);
+
+ if (mdlMap == gcvNULL)
+ {
+ gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
+ }
+ }
+
+ if (mdlMap->vmaAddr == gcvNULL)
+ {
+ allocator = mdl->allocator;
+
+ gcmkONERROR(
+ allocator->ops->MapUser(allocator,
+ mdl, mdlMap,
+ gcvFALSE));
+ }
+
+ mutex_unlock(&mdl->mapsMutex);
+
+ *Logical = mdlMap->vmaAddr;
+
+ gcmkFOOTER_ARG("*Logical=0x%X", *Logical);
+ return gcvSTATUS_OK;
+
+OnError:
+ mutex_unlock(&mdl->mapsMutex);
+
+ gcmkFOOTER();
+ return status;
+}
+
+/*******************************************************************************
+**
+** gckOS_UnmapMemory
+**
+** Unmap physical memory out of the current process.
+**
+** INPUT:
+**
+** gckOS Os
+** Pointer to an gckOS object.
+**
+** gctPHYS_ADDR Physical
+** Start of physical address memory.
+**
+** gctSIZE_T Bytes
+** Number of bytes to unmap.
+**
+** gctPOINTER Memory
+** Pointer to a previously mapped memory region.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckOS_UnmapMemory(
+ IN gckOS Os,
+ IN gctPHYS_ADDR Physical,
+ IN gctSIZE_T Bytes,
+ IN gctPOINTER Logical
+ )
+{
+ gcmkHEADER_ARG("Os=0x%X Physical=0x%X Bytes=%lu Logical=0x%X",
+ Os, Physical, Bytes, Logical);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
+ gcmkVERIFY_ARGUMENT(Physical != 0);
+ gcmkVERIFY_ARGUMENT(Bytes > 0);
+ gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
+
+ gckOS_UnmapMemoryEx(Os, Physical, Bytes, Logical, _GetProcessID());
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+}
+
+
+/*******************************************************************************
+**
+** gckOS_UnmapMemoryEx
+**
+** Unmap physical memory in the specified process.
+**
+** INPUT:
+**
+** gckOS Os
+** Pointer to an gckOS object.
+**
+** gctPHYS_ADDR Physical
+** Start of physical address memory.
+**
+** gctSIZE_T Bytes
+** Number of bytes to unmap.
+**
+** gctPOINTER Memory
+** Pointer to a previously mapped memory region.
+**
+** gctUINT32 PID
+** Pid of the process that opened the device and mapped this memory.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckOS_UnmapMemoryEx(
+ IN gckOS Os,
+ IN gctPHYS_ADDR Physical,
+ IN gctSIZE_T Bytes,
+ IN gctPOINTER Logical,
+ IN gctUINT32 PID
+ )
+{
+ PLINUX_MDL_MAP mdlMap;
+ PLINUX_MDL mdl = (PLINUX_MDL)Physical;
+
+ gcmkHEADER_ARG("Os=0x%X Physical=0x%X Bytes=%lu Logical=0x%X PID=%d",
+ Os, Physical, Bytes, Logical, PID);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
+ gcmkVERIFY_ARGUMENT(Physical != 0);
+ gcmkVERIFY_ARGUMENT(Bytes > 0);
+ gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
+ gcmkVERIFY_ARGUMENT(PID != 0);
+
+ if (Logical)
+ {
+ gckALLOCATOR allocator = mdl->allocator;
+
+ mutex_lock(&mdl->mapsMutex);
+
+ mdlMap = FindMdlMap(mdl, PID);
+
+ if (mdlMap == gcvNULL || mdlMap->vmaAddr == gcvNULL)
+ {
+ mutex_unlock(&mdl->mapsMutex);
+
+ gcmkFOOTER_ARG("status=%d", gcvSTATUS_INVALID_ARGUMENT);
+ return gcvSTATUS_INVALID_ARGUMENT;
+ }
+
+ BUG_ON(!allocator || !allocator->ops->UnmapUser);
+
+ allocator->ops->UnmapUser(allocator, mdl, mdlMap, mdl->bytes);
+
+ gcmkVERIFY_OK(_DestroyMdlMap(mdl, mdlMap));
+
+ mutex_unlock(&mdl->mapsMutex);
+ }
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+}
+
+/*******************************************************************************
+**
+** gckOS_UnmapUserLogical
+**
+** Unmap user logical memory out of physical memory.
+**
+** INPUT:
+**
+** gckOS Os
+** Pointer to an gckOS object.
+**
+** gctPHYS_ADDR Physical
+** Start of physical address memory.
+**
+** gctSIZE_T Bytes
+** Number of bytes to unmap.
+**
+** gctPOINTER Memory
+** Pointer to a previously mapped memory region.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckOS_UnmapUserLogical(
+ IN gckOS Os,
+ IN gctPHYS_ADDR Physical,
+ IN gctSIZE_T Bytes,
+ IN gctPOINTER Logical
+ )
+{
+ gcmkHEADER_ARG("Os=0x%X Physical=0x%X Bytes=%lu Logical=0x%X",
+ Os, Physical, Bytes, Logical);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
+ gcmkVERIFY_ARGUMENT(Physical != 0);
+ gcmkVERIFY_ARGUMENT(Bytes > 0);
+ gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
+
+ gckOS_UnmapMemory(Os, Physical, Bytes, Logical);
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+}
+
+/*******************************************************************************
+**
+** gckOS_AllocateNonPagedMemory
+**
+** Allocate a number of pages from non-paged memory.
+**
+** INPUT:
+**
+** gckOS Os
+** Pointer to an gckOS object.
+**
+** gctBOOL InUserSpace
+** gcvTRUE if the pages need to be mapped into user space.
+**
+** gctUINT32 Flag
+** Allocation attribute.
+**
+** gctSIZE_T * Bytes
+** Pointer to a variable that holds the number of bytes to allocate.
+**
+** OUTPUT:
+**
+** gctSIZE_T * Bytes
+** Pointer to a variable that hold the number of bytes allocated.
+**
+** gctPHYS_ADDR * Physical
+** Pointer to a variable that will hold the physical address of the
+** allocation.
+**
+** gctPOINTER * Logical
+** Pointer to a variable that will hold the logical address of the
+** allocation.
+*/
+gceSTATUS
+gckOS_AllocateNonPagedMemory(
+ IN gckOS Os,
+ IN gctBOOL InUserSpace,
+ IN gctUINT32 Flag,
+ IN OUT gctSIZE_T * Bytes,
+ OUT gctPHYS_ADDR * Physical,
+ OUT gctPOINTER * Logical
+ )
+{
+ gctSIZE_T bytes;
+ gctINT numPages;
+ PLINUX_MDL mdl = gcvNULL;
+ PLINUX_MDL_MAP mdlMap = gcvNULL;
+ gctPOINTER addr;
+ gceSTATUS status = gcvSTATUS_NOT_SUPPORTED;
+ gckALLOCATOR allocator;
+
+ gcmkHEADER_ARG("Os=0x%X InUserSpace=%d *Bytes=%lu",
+ Os, InUserSpace, gcmOPT_VALUE(Bytes));
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
+ gcmkVERIFY_ARGUMENT(Bytes != gcvNULL);
+ gcmkVERIFY_ARGUMENT(*Bytes > 0);
+ gcmkVERIFY_ARGUMENT(Physical != gcvNULL);
+ gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
+
+ /* Align number of bytes to page size. */
+ bytes = gcmALIGN(*Bytes, PAGE_SIZE);
+
+ /* Get total number of pages.. */
+ numPages = GetPageCount(bytes, 0);
+
+ /* Allocate mdl structure */
+ mdl = _CreateMdl(Os);
+ if (mdl == gcvNULL)
+ {
+ gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
+ }
+
+ gcmkASSERT(Flag & gcvALLOC_FLAG_CONTIGUOUS);
+
+ Flag |= gcvALLOC_FLAG_CMA_PREEMPT;
+
+ /* Walk all allocators. */
+ list_for_each_entry(allocator, &Os->allocatorList, link)
+ {
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_OS,
+ "%s(%d) flag = %x allocator->capability = %x",
+ __FUNCTION__, __LINE__, Flag, allocator->capability);
+
+#ifndef NO_DMA_COHERENT
+ /* Point to dma coherent allocator. */
+ if (strcmp(allocator->name, "dma"))
+ {
+ /*!VIV:
+ * For historical issue, we force allocate all non-paged memory from
+ * dma coherent pool when it is not disabled.
+ *
+ * The code below changes the scheme a little: force allocate
+ * non-paged memory whose size is larger than 1 pages, can try other
+ * allocators otherwise. This is to save memory usage of dma
+ * coherent pool.
+ */
+ if (((Flag & allocator->capability) != Flag) ||
+ (numPages > 1))
+ {
+ continue;
+ }
+ }
+#else
+ if ((Flag & allocator->capability) != Flag)
+ {
+ continue;
+ }
+#endif
+ status = allocator->ops->Alloc(allocator, mdl, numPages, Flag);
+
+ if (gcmIS_SUCCESS(status))
+ {
+ mdl->allocator = allocator;
+ break;
+ }
+ }
+
+ /* Check status. */
+ gcmkONERROR(status);
+
+ mdl->cacheable = Flag & gcvALLOC_FLAG_CACHEABLE;
+
+ mdl->bytes = bytes;
+ mdl->numPages = numPages;
+
+ mdl->contiguous = gcvTRUE;
+
+ gcmkONERROR(allocator->ops->MapKernel(allocator, mdl, &addr));
+
+ if (!strcmp(allocator->name, "gfp"))
+ {
+ /* Trigger a page fault. */
+ memset(addr, 0, numPages * PAGE_SIZE);
+ }
+
+ mdl->addr = addr;
+
+ if (InUserSpace)
+ {
+ mdlMap = _CreateMdlMap(mdl, _GetProcessID());
+
+ if (mdlMap == gcvNULL)
+ {
+ gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
+ }
+
+ gcmkONERROR(allocator->ops->MapUser(allocator, mdl, mdlMap, gcvFALSE));
+
+ *Logical = mdlMap->vmaAddr;
+ }
+ else
+ {
+ *Logical = addr;
+ }
+
+ /*
+ * Add this to a global list.
+ * Will be used by get physical address
+ * and mapuser pointer functions.
+ */
+ mutex_lock(&Os->mdlMutex);
+ list_add_tail(&mdl->link, &Os->mdlHead);
+ mutex_unlock(&Os->mdlMutex);
+
+ /* Return allocated memory. */
+ *Bytes = bytes;
+ *Physical = (gctPHYS_ADDR) mdl;
+
+ /* Success. */
+ gcmkFOOTER_ARG("*Bytes=%lu *Physical=0x%X *Logical=0x%X",
+ *Bytes, *Physical, *Logical);
+ return gcvSTATUS_OK;
+
+OnError:
+ if (mdl != gcvNULL)
+ {
+ /* Free LINUX_MDL. */
+ gcmkVERIFY_OK(_DestroyMdl(mdl));
+ }
+
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+
+/*******************************************************************************
+**
+** gckOS_FreeNonPagedMemory
+**
+** Free previously allocated and mapped pages from non-paged memory.
+**
+** INPUT:
+**
+** gckOS Os
+** Pointer to an gckOS object.
+**
+** gctSIZE_T Bytes
+** Number of bytes allocated.
+**
+** gctPHYS_ADDR Physical
+** Physical address of the allocated memory.
+**
+** gctPOINTER Logical
+** Logical address of the allocated memory.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS gckOS_FreeNonPagedMemory(
+ IN gckOS Os,
+ IN gctSIZE_T Bytes,
+ IN gctPHYS_ADDR Physical,
+ IN gctPOINTER Logical
+ )
+{
+ PLINUX_MDL mdl = (PLINUX_MDL)Physical;
+
+ gcmkHEADER_ARG("Os=0x%X Bytes=%lu Physical=0x%X Logical=0x%X",
+ Os, Bytes, Physical, Logical);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
+ gcmkVERIFY_ARGUMENT(Bytes > 0);
+ gcmkVERIFY_ARGUMENT(Physical != 0);
+ gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
+
+ gcmkVERIFY_OK(_DestroyMdl(mdl));
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+}
+
+static inline gckALLOCATOR
+_FindAllocator(
+ gckOS Os,
+ gctUINT Flag
+ )
+{
+ gckALLOCATOR allocator;
+
+ list_for_each_entry(allocator, &Os->allocatorList, link)
+ {
+ if ((allocator->capability & Flag) == Flag)
+ {
+ return allocator;
+ }
+ }
+
+ return gcvNULL;
+}
+
+gceSTATUS
+gckOS_RequestReservedMemory(
+ gckOS Os,
+ unsigned long Start,
+ unsigned long Size,
+ const char * Name,
+ gctBOOL Requested,
+ void ** MemoryHandle
+ )
+{
+ PLINUX_MDL mdl = gcvNULL;
+ gceSTATUS status;
+ gckALLOCATOR allocator;
+ gcsATTACH_DESC desc;
+
+ gcmkHEADER_ARG("start=0x%lx size=0x%lx name=%s", Start, Size, Name);
+
+ /* Round up to page size. */
+ Size = (Size + ~PAGE_MASK) & PAGE_MASK;
+
+ mdl = _CreateMdl(Os);
+ if (!mdl)
+ {
+ gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
+ }
+
+ desc.reservedMem.start = Start;
+ desc.reservedMem.size = Size;
+ desc.reservedMem.name = Name;
+ desc.reservedMem.requested = Requested;
+
+ allocator = _FindAllocator(Os, gcvALLOC_FLAG_LINUX_RESERVED_MEM);
+ if (!allocator)
+ {
+ gcmkPRINT("reserved-mem allocator not integrated!");
+ gcmkONERROR(gcvSTATUS_GENERIC_IO);
+ }
+
+ /* Call attach. */
+ gcmkONERROR(allocator->ops->Attach(allocator, &desc, mdl));
+
+ /* Assign alloator. */
+ mdl->allocator = allocator;
+ mdl->bytes = Size;
+ mdl->numPages = Size >> PAGE_SHIFT;
+ mdl->contiguous = gcvTRUE;
+ mdl->addr = gcvNULL;
+ mdl->dmaHandle = Start;
+ mdl->gid = 0;
+
+ /*
+ * Add this to a global list.
+ * Will be used by get physical address
+ * and mapuser pointer functions.
+ */
+ mutex_lock(&Os->mdlMutex);
+ list_add_tail(&mdl->link, &Os->mdlHead);
+ mutex_unlock(&Os->mdlMutex);
+
+ *MemoryHandle = (void *)mdl;
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ if (mdl)
+ {
+ gcmkVERIFY_OK(_DestroyMdl(mdl));
+ }
+
+ gcmkFOOTER();
+ return status;
+}
+
+void
+gckOS_ReleaseReservedMemory(
+ gckOS Os,
+ void * MemoryHandle
+ )
+{
+ gckALLOCATOR allocator;
+ PLINUX_MDL mdl = (PLINUX_MDL)MemoryHandle;
+
+ allocator = _FindAllocator(Os, gcvALLOC_FLAG_LINUX_RESERVED_MEM);
+
+ /* If no allocator, how comes the memory? */
+ BUG_ON(!allocator);
+
+ allocator->ops->Free(allocator, mdl);
+}
+
+/*******************************************************************************
+**
+** gckOS_ReadRegister
+**
+** Read data from a register.
+**
+** INPUT:
+**
+** gckOS Os
+** Pointer to an gckOS object.
+**
+** gctUINT32 Address
+** Address of register.
+**
+** OUTPUT:
+**
+** gctUINT32 * Data
+** Pointer to a variable that receives the data read from the register.
+*/
+gceSTATUS
+gckOS_ReadRegister(
+ IN gckOS Os,
+ IN gctUINT32 Address,
+ OUT gctUINT32 * Data
+ )
+{
+ return gckOS_ReadRegisterEx(Os, gcvCORE_MAJOR, Address, Data);
+}
+
+gceSTATUS
+gckOS_ReadRegisterEx(
+ IN gckOS Os,
+ IN gceCORE Core,
+ IN gctUINT32 Address,
+ OUT gctUINT32 * Data
+ )
+{
+ if (in_irq())
+ {
+ uint32_t data;
+
+ spin_lock(&Os->registerAccessLock);
+
+ if (unlikely(Os->clockStates[Core] == gcvFALSE))
+ {
+ spin_unlock(&Os->registerAccessLock);
+
+ /*
+ * Read register when external clock off:
+ * 1. In shared IRQ, read register may be called and that's not our irq.
+ */
+ return gcvSTATUS_GENERIC_IO;
+ }
+
+ data = readl(Os->device->registerBases[Core]);
+
+ if (unlikely((data & 0x3) == 0x3))
+ {
+ spin_unlock(&Os->registerAccessLock);
+
+ /*
+ * Read register when internal clock off:
+ * a. In shared IRQ, read register may be called and that's not our irq.
+ * b. In some condition, when ISR handled normal FE/PE, PM thread could
+ * trun off internal clock before ISR read register of async FE. And
+ * then IRQ handler will call read register with internal clock off.
+ * So here we just skip for such case.
+ */
+ return gcvSTATUS_GENERIC_IO;
+ }
+
+ *Data = readl((gctUINT8 *)Os->device->registerBases[Core] + Address);
+ spin_unlock(&Os->registerAccessLock);
+ }
+ else
+ {
+ unsigned long flags;
+
+ spin_lock_irqsave(&Os->registerAccessLock, flags);
+
+ if (unlikely(Os->clockStates[Core] == gcvFALSE))
+ {
+ spin_unlock_irqrestore(&Os->registerAccessLock, flags);
+
+ /*
+ * Read register when external clock off:
+ * 2. In non-irq context, register access should not be called,
+ * otherwise it's driver bug.
+ */
+ printk(KERN_ERR "[galcore]: %s(%d) GPU[%d] external clock off",
+ __func__, __LINE__, Core);
+ gcmkBUG_ON(1);
+ return gcvSTATUS_GENERIC_IO;
+ }
+
+ *Data = readl((gctUINT8 *)Os->device->registerBases[Core] + Address);
+ spin_unlock_irqrestore(&Os->registerAccessLock, flags);
+
+#if gcdDUMP_AHB_ACCESS
+ /* Dangerous to print in interrupt context, skip. */
+ gcmkPRINT("@[RD %d] %08x %08x", Core, Address, *Data);
+#endif
+ }
+
+ /* Success. */
+ return gcvSTATUS_OK;
+}
+
+/*******************************************************************************
+**
+** gckOS_WriteRegister
+**
+** Write data to a register.
+**
+** INPUT:
+**
+** gckOS Os
+** Pointer to an gckOS object.
+**
+** gctUINT32 Address
+** Address of register.
+**
+** gctUINT32 Data
+** Data for register.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckOS_WriteRegister(
+ IN gckOS Os,
+ IN gctUINT32 Address,
+ IN gctUINT32 Data
+ )
+{
+ return gckOS_WriteRegisterEx(Os, gcvCORE_MAJOR, Address, Data);
+}
+
+gceSTATUS
+gckOS_WriteRegisterEx(
+ IN gckOS Os,
+ IN gceCORE Core,
+ IN gctUINT32 Address,
+ IN gctUINT32 Data
+ )
+{
+ if (in_irq())
+ {
+ spin_lock(&Os->registerAccessLock);
+
+ if (unlikely(Os->clockStates[Core] == gcvFALSE))
+ {
+ spin_unlock(&Os->registerAccessLock);
+
+ printk(KERN_ERR "[galcore]: %s(%d) GPU[%d] external clock off",
+ __func__, __LINE__, Core);
+
+ /* Driver bug: register write when clock off. */
+ gcmkBUG_ON(1);
+ return gcvSTATUS_GENERIC_IO;
+ }
+
+ writel(Data, (gctUINT8 *)Os->device->registerBases[Core] + Address);
+ spin_unlock(&Os->registerAccessLock);
+ }
+ else
+ {
+ unsigned long flags;
+
+ spin_lock_irqsave(&Os->registerAccessLock, flags);
+
+ if (unlikely(Os->clockStates[Core] == gcvFALSE))
+ {
+ spin_unlock_irqrestore(&Os->registerAccessLock, flags);
+
+ printk(KERN_ERR "[galcore]: %s(%d) GPU[%d] external clock off",
+ __func__, __LINE__, Core);
+
+ /* Driver bug: register write when clock off. */
+ gcmkBUG_ON(1);
+ return gcvSTATUS_GENERIC_IO;
+ }
+
+ writel(Data, (gctUINT8 *)Os->device->registerBases[Core] + Address);
+ spin_unlock_irqrestore(&Os->registerAccessLock, flags);
+
+#if gcdDUMP_AHB_ACCESS
+ /* Dangerous to print in interrupt context, skip. */
+ gcmkPRINT("@[WR %d] %08x %08x", Core, Address, Data);
+#endif
+ }
+
+ /* Success. */
+ return gcvSTATUS_OK;
+}
+
+/*******************************************************************************
+**
+** gckOS_GetPageSize
+**
+** Get the system's page size.
+**
+** INPUT:
+**
+** gckOS Os
+** Pointer to an gckOS object.
+**
+** OUTPUT:
+**
+** gctSIZE_T * PageSize
+** Pointer to a variable that will receive the system's page size.
+*/
+gceSTATUS gckOS_GetPageSize(
+ IN gckOS Os,
+ OUT gctSIZE_T * PageSize
+ )
+{
+ gcmkHEADER_ARG("Os=0x%X", Os);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
+ gcmkVERIFY_ARGUMENT(PageSize != gcvNULL);
+
+ /* Return the page size. */
+ *PageSize = (gctSIZE_T) PAGE_SIZE;
+
+ /* Success. */
+ gcmkFOOTER_ARG("*PageSize=%d", *PageSize);
+ return gcvSTATUS_OK;
+}
+
+/*******************************************************************************
+**
+** gckOS_GetPhysicalAddressProcess
+**
+** Get the physical system address of a corresponding virtual address for a
+** given process.
+**
+** INPUT:
+**
+** gckOS Os
+** Pointer to gckOS object.
+**
+** gctPOINTER Logical
+** Logical address.
+**
+** gctUINT32 ProcessID
+** Process ID.
+**
+** OUTPUT:
+**
+** gctUINT32 * Address
+** Poinetr to a variable that receives the 32-bit physical adress.
+*/
+static gceSTATUS
+_GetPhysicalAddressProcess(
+ IN gckOS Os,
+ IN gctPOINTER Logical,
+ IN gctUINT32 ProcessID,
+ OUT gctPHYS_ADDR_T * Address
+ )
+{
+ PLINUX_MDL mdl;
+ gceSTATUS status = gcvSTATUS_INVALID_ADDRESS;
+
+ gcmkHEADER_ARG("Os=0x%X Logical=0x%X ProcessID=%d", Os, Logical, ProcessID);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
+ gcmkVERIFY_ARGUMENT(Address != gcvNULL);
+
+ mutex_lock(&Os->mdlMutex);
+
+ if (Os->device->contiguousPhysical)
+ {
+ /* Try the contiguous memory pool. */
+ mdl = (PLINUX_MDL) Os->device->contiguousPhysical;
+
+ mutex_lock(&mdl->mapsMutex);
+
+ status = _ConvertLogical2Physical(Os, Logical, ProcessID, mdl, Address);
+
+ mutex_unlock(&mdl->mapsMutex);
+ }
+
+ if (gcmIS_ERROR(status))
+ {
+ /* Walk all MDLs. */
+ list_for_each_entry(mdl, &Os->mdlHead, link)
+ {
+ mutex_lock(&mdl->mapsMutex);
+
+ status = _ConvertLogical2Physical(Os, Logical, ProcessID, mdl, Address);
+
+ mutex_unlock(&mdl->mapsMutex);
+
+ if (gcmIS_SUCCESS(status))
+ {
+ break;
+ }
+ }
+ }
+
+ mutex_unlock(&Os->mdlMutex);
+
+ gcmkONERROR(status);
+
+ /* Success. */
+ gcmkFOOTER_ARG("*Address=%p", *Address);
+ return gcvSTATUS_OK;
+
+OnError:
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+
+
+/*******************************************************************************
+**
+** gckOS_GetPhysicalAddress
+**
+** Get the physical system address of a corresponding virtual address.
+**
+** INPUT:
+**
+** gckOS Os
+** Pointer to an gckOS object.
+**
+** gctPOINTER Logical
+** Logical address.
+**
+** OUTPUT:
+**
+** gctUINT32 * Address
+** Poinetr to a variable that receives the 32-bit physical adress.
+*/
+gceSTATUS
+gckOS_GetPhysicalAddress(
+ IN gckOS Os,
+ IN gctPOINTER Logical,
+ OUT gctPHYS_ADDR_T * Address
+ )
+{
+ gceSTATUS status;
+ gctUINT32 processID;
+
+ gcmkHEADER_ARG("Os=0x%X Logical=0x%X", Os, Logical);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
+ gcmkVERIFY_ARGUMENT(Address != gcvNULL);
+
+ /* Query page table of current process first. */
+ status = _QueryProcessPageTable(Logical, Address);
+
+ if (gcmIS_ERROR(status))
+ {
+ /* Get current process ID. */
+ processID = _GetProcessID();
+
+ /* Route through other function. */
+ gcmkONERROR(
+ _GetPhysicalAddressProcess(Os, Logical, processID, Address));
+ }
+
+ /* Success. */
+ gcmkFOOTER_ARG("*Address=%p", *Address);
+ return gcvSTATUS_OK;
+
+OnError:
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+/*******************************************************************************
+**
+** gckOS_UserLogicalToPhysical
+**
+** Get the physical system address of a corresponding user virtual address.
+**
+** INPUT:
+**
+** gckOS Os
+** Pointer to an gckOS object.
+**
+** gctPOINTER Logical
+** Logical address.
+**
+** OUTPUT:
+**
+** gctUINT32 * Address
+** Pointer to a variable that receives the 32-bit physical address.
+*/
+gceSTATUS gckOS_UserLogicalToPhysical(
+ IN gckOS Os,
+ IN gctPOINTER Logical,
+ OUT gctPHYS_ADDR_T * Address
+ )
+{
+ return gckOS_GetPhysicalAddress(Os, Logical, Address);
+}
+
+#if gcdSECURE_USER
+static gceSTATUS
+gckOS_AddMapping(
+ IN gckOS Os,
+ IN gctUINT32 Physical,
+ IN gctPOINTER Logical,
+ IN gctSIZE_T Bytes
+ )
+{
+ gceSTATUS status;
+ gcsUSER_MAPPING_PTR map;
+
+ gcmkHEADER_ARG("Os=0x%X Physical=0x%X Logical=0x%X Bytes=%lu",
+ Os, Physical, Logical, Bytes);
+
+ gcmkONERROR(gckOS_Allocate(Os,
+ gcmSIZEOF(gcsUSER_MAPPING),
+ (gctPOINTER *) &map));
+
+ map->next = Os->userMap;
+ map->physical = Physical - Os->device->baseAddress;
+ map->logical = Logical;
+ map->bytes = Bytes;
+ map->start = (gctINT8_PTR) Logical;
+ map->end = map->start + Bytes;
+
+ Os->userMap = map;
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ gcmkFOOTER();
+ return status;
+}
+
+static gceSTATUS
+gckOS_RemoveMapping(
+ IN gckOS Os,
+ IN gctPOINTER Logical,
+ IN gctSIZE_T Bytes
+ )
+{
+ gceSTATUS status;
+ gcsUSER_MAPPING_PTR map, prev;
+
+ gcmkHEADER_ARG("Os=0x%X Logical=0x%X Bytes=%lu", Os, Logical, Bytes);
+
+ for (map = Os->userMap, prev = gcvNULL; map != gcvNULL; map = map->next)
+ {
+ if ((map->logical == Logical) && (map->bytes == Bytes))
+ {
+ break;
+ }
+
+ prev = map;
+ }
+
+ if (map == gcvNULL)
+ {
+ gcmkONERROR(gcvSTATUS_INVALID_ADDRESS);
+ }
+
+ if (prev == gcvNULL)
+ {
+ Os->userMap = map->next;
+ }
+ else
+ {
+ prev->next = map->next;
+ }
+
+ gcmkONERROR(gcmkOS_SAFE_FREE(Os, map));
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ gcmkFOOTER();
+ return status;
+}
+#endif
+
+gceSTATUS
+_ConvertLogical2Physical(
+ IN gckOS Os,
+ IN gctPOINTER Logical,
+ IN gctUINT32 ProcessID,
+ IN PLINUX_MDL Mdl,
+ OUT gctPHYS_ADDR_T * Physical
+ )
+{
+ gckALLOCATOR allocator = Mdl->allocator;
+ gctUINT32 offset;
+ gceSTATUS status = gcvSTATUS_NOT_FOUND;
+ gctINT8_PTR vBase;
+
+ /* TASK_SIZE is userspace - kernelspace virtual memory split. */
+ if ((gctUINTPTR_T)Logical >= TASK_SIZE)
+ {
+ /* Kernel virtual address. */
+ vBase = Mdl->addr;
+ }
+ else
+ {
+ /* User virtual address. */
+ PLINUX_MDL_MAP map;
+
+ map = FindMdlMap(Mdl, (gctINT) ProcessID);
+ vBase = (map == gcvNULL) ? gcvNULL : (gctINT8_PTR) map->vmaAddr;
+ }
+
+ /* Is the given address within that range. */
+ if ((vBase != gcvNULL)
+ && ((gctINT8_PTR) Logical >= vBase)
+ && ((gctINT8_PTR) Logical < vBase + Mdl->bytes)
+ )
+ {
+ offset = (gctINT8_PTR) Logical - vBase;
+
+ allocator->ops->Physical(allocator, Mdl, offset, Physical);
+
+ status = gcvSTATUS_OK;
+ }
+
+ return status;
+}
+
+/*******************************************************************************
+**
+** gckOS_MapPhysical
+**
+** Map a physical address into kernel space.
+**
+** INPUT:
+**
+** gckOS Os
+** Pointer to an gckOS object.
+**
+** gctUINT32 Physical
+** Physical address of the memory to map.
+**
+** gctSIZE_T Bytes
+** Number of bytes to map.
+**
+** OUTPUT:
+**
+** gctPOINTER * Logical
+** Pointer to a variable that receives the base address of the mapped
+** memory.
+*/
+gceSTATUS
+gckOS_MapPhysical(
+ IN gckOS Os,
+ IN gctUINT32 Physical,
+ IN gctSIZE_T Bytes,
+ OUT gctPOINTER * Logical
+ )
+{
+ gctPOINTER logical;
+ PLINUX_MDL mdl;
+ gctBOOL found = gcvFALSE;
+ gctUINT32 physical = Physical;
+
+ gcmkHEADER_ARG("Os=0x%X Physical=0x%X Bytes=%lu", Os, Physical, Bytes);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
+ gcmkVERIFY_ARGUMENT(Bytes > 0);
+ gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
+
+ mutex_lock(&Os->mdlMutex);
+
+ /* Go through our mapping to see if we know this physical address already. */
+ list_for_each_entry(mdl, &Os->mdlHead, link)
+ {
+ if (mdl->dmaHandle != 0)
+ {
+ if ((physical >= mdl->dmaHandle)
+ && (physical < mdl->dmaHandle + mdl->bytes)
+ && (mdl->addr != 0)
+ )
+ {
+ *Logical = mdl->addr + (physical - mdl->dmaHandle);
+ found = gcvTRUE;
+ break;
+ }
+ }
+ }
+
+ mutex_unlock(&Os->mdlMutex);
+
+ if (!found)
+ {
+ unsigned long pfn = physical >> PAGE_SHIFT;
+
+ if (pfn_valid(pfn))
+ {
+ gctUINT32 offset = physical & ~PAGE_MASK;
+ struct page ** pages;
+ struct page * page;
+ gctUINT numPages;
+ gctINT i;
+ pgprot_t pgprot;
+
+ numPages = GetPageCount(PAGE_ALIGN(offset + Bytes), 0);
+
+ pages = kmalloc(sizeof(struct page *) * numPages, GFP_KERNEL | gcdNOWARN);
+
+ if (!pages)
+ {
+ gcmkFOOTER_ARG("status=%d", gcvSTATUS_OUT_OF_MEMORY);
+ return gcvSTATUS_OUT_OF_MEMORY;
+ }
+
+ page = pfn_to_page(pfn);
+
+ for (i = 0; i < numPages; i++)
+ {
+ pages[i] = nth_page(page, i);
+ }
+
+#if gcdENABLE_BUFFERABLE_VIDEO_MEMORY
+ pgprot = pgprot_writecombine(PAGE_KERNEL);
+#else
+ pgprot = pgprot_noncached(PAGE_KERNEL);
+#endif
+
+ logical = vmap(pages, numPages, 0, pgprot);
+
+ kfree(pages);
+
+ if (logical == gcvNULL)
+ {
+ gcmkTRACE_ZONE(
+ gcvLEVEL_INFO, gcvZONE_OS,
+ "%s(%d): Failed to vmap",
+ __FUNCTION__, __LINE__
+ );
+
+ /* Out of resources. */
+ gcmkFOOTER_ARG("status=%d", gcvSTATUS_OUT_OF_RESOURCES);
+ return gcvSTATUS_OUT_OF_RESOURCES;
+ }
+
+ logical += offset;
+ }
+ else
+ {
+ /* Map memory as cached memory. */
+ request_mem_region(physical, Bytes, "MapRegion");
+ logical = (gctPOINTER) ioremap_nocache(physical, Bytes);
+
+ if (logical == gcvNULL)
+ {
+ gcmkTRACE_ZONE(
+ gcvLEVEL_INFO, gcvZONE_OS,
+ "%s(%d): Failed to ioremap",
+ __FUNCTION__, __LINE__
+ );
+
+ /* Out of resources. */
+ gcmkFOOTER_ARG("status=%d", gcvSTATUS_OUT_OF_RESOURCES);
+ return gcvSTATUS_OUT_OF_RESOURCES;
+ }
+ }
+
+ /* Return pointer to mapped memory. */
+ *Logical = logical;
+ }
+
+ /* Success. */
+ gcmkFOOTER_ARG("*Logical=0x%X", *Logical);
+ return gcvSTATUS_OK;
+}
+
+/*******************************************************************************
+**
+** gckOS_UnmapPhysical
+**
+** Unmap a previously mapped memory region from kernel memory.
+**
+** INPUT:
+**
+** gckOS Os
+** Pointer to an gckOS object.
+**
+** gctPOINTER Logical
+** Pointer to the base address of the memory to unmap.
+**
+** gctSIZE_T Bytes
+** Number of bytes to unmap.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckOS_UnmapPhysical(
+ IN gckOS Os,
+ IN gctPOINTER Logical,
+ IN gctSIZE_T Bytes
+ )
+{
+ PLINUX_MDL mdl;
+ gctBOOL found = gcvFALSE;
+
+ gcmkHEADER_ARG("Os=0x%X Logical=0x%X Bytes=%lu", Os, Logical, Bytes);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
+ gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
+ gcmkVERIFY_ARGUMENT(Bytes > 0);
+
+ mutex_lock(&Os->mdlMutex);
+
+ list_for_each_entry(mdl, &Os->mdlHead, link)
+ {
+ if (mdl->addr != gcvNULL)
+ {
+ if ((Logical >= (gctPOINTER)mdl->addr) &&
+ (Logical < (gctPOINTER)((gctSTRING)mdl->addr + mdl->bytes)))
+ {
+ found = gcvTRUE;
+ break;
+ }
+ }
+ }
+
+ mutex_unlock(&Os->mdlMutex);
+
+ if (!found)
+ {
+ /* Unmap the memory. */
+ vunmap((void *)((unsigned long)Logical & PAGE_MASK));
+ }
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+}
+
+/*******************************************************************************
+**
+** gckOS_DeleteMutex
+**
+** Delete a mutex.
+**
+** INPUT:
+**
+** gckOS Os
+** Pointer to an gckOS object.
+**
+** gctPOINTER Mutex
+** Pointer to the mute to be deleted.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckOS_DeleteMutex(
+ IN gckOS Os,
+ IN gctPOINTER Mutex
+ )
+{
+ gceSTATUS status;
+
+ gcmkHEADER_ARG("Os=0x%X Mutex=0x%X", Os, Mutex);
+
+ /* Validate the arguments. */
+ gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
+ gcmkVERIFY_ARGUMENT(Mutex != gcvNULL);
+
+ /* Destroy the mutex. */
+ mutex_destroy((struct mutex *)Mutex);
+
+ /* Free the mutex structure. */
+ gcmkONERROR(gckOS_Free(Os, Mutex));
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ /* Return status. */
+ gcmkFOOTER();
+ return status;
+}
+
+/*******************************************************************************
+**
+** gckOS_AcquireMutex
+**
+** Acquire a mutex.
+**
+** INPUT:
+**
+** gckOS Os
+** Pointer to an gckOS object.
+**
+** gctPOINTER Mutex
+** Pointer to the mutex to be acquired.
+**
+** gctUINT32 Timeout
+** Timeout value specified in milliseconds.
+** Specify the value of gcvINFINITE to keep the thread suspended
+** until the mutex has been acquired.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckOS_AcquireMutex(
+ IN gckOS Os,
+ IN gctPOINTER Mutex,
+ IN gctUINT32 Timeout
+ )
+{
+ gcmkHEADER_ARG("Os=0x%X Mutex=0x%0x Timeout=%u", Os, Mutex, Timeout);
+
+ /* Validate the arguments. */
+ gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
+ gcmkVERIFY_ARGUMENT(Mutex != gcvNULL);
+
+ if (Timeout == gcvINFINITE)
+ {
+ /* Lock the mutex. */
+ mutex_lock(Mutex);
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+ }
+
+ for (;;)
+ {
+ /* Try to acquire the mutex. */
+ if (mutex_trylock(Mutex))
+ {
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+ }
+
+ if (Timeout-- == 0)
+ {
+ break;
+ }
+
+ /* Wait for 1 millisecond. */
+ gcmkVERIFY_OK(gckOS_Delay(Os, 1));
+ }
+
+ /* Timeout. */
+ gcmkFOOTER_ARG("status=%d", gcvSTATUS_TIMEOUT);
+ return gcvSTATUS_TIMEOUT;
+}
+
+/*******************************************************************************
+**
+** gckOS_ReleaseMutex
+**
+** Release an acquired mutex.
+**
+** INPUT:
+**
+** gckOS Os
+** Pointer to an gckOS object.
+**
+** gctPOINTER Mutex
+** Pointer to the mutex to be released.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckOS_ReleaseMutex(
+ IN gckOS Os,
+ IN gctPOINTER Mutex
+ )
+{
+ gcmkHEADER_ARG("Os=0x%X Mutex=0x%0x", Os, Mutex);
+
+ /* Validate the arguments. */
+ gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
+ gcmkVERIFY_ARGUMENT(Mutex != gcvNULL);
+
+ /* Release the mutex. */
+ mutex_unlock(Mutex);
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+}
+
+/*******************************************************************************
+**
+** gckOS_AtomicExchange
+**
+** Atomically exchange a pair of 32-bit values.
+**
+** INPUT:
+**
+** gckOS Os
+** Pointer to an gckOS object.
+**
+** IN OUT gctINT32_PTR Target
+** Pointer to the 32-bit value to exchange.
+**
+** IN gctINT32 NewValue
+** Specifies a new value for the 32-bit value pointed to by Target.
+**
+** OUT gctINT32_PTR OldValue
+** The old value of the 32-bit value pointed to by Target.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckOS_AtomicExchange(
+ IN gckOS Os,
+ IN OUT gctUINT32_PTR Target,
+ IN gctUINT32 NewValue,
+ OUT gctUINT32_PTR OldValue
+ )
+{
+ /* Exchange the pair of 32-bit values. */
+ *OldValue = (gctUINT32) atomic_xchg((atomic_t *) Target, (int) NewValue);
+ return gcvSTATUS_OK;
+}
+
+/*******************************************************************************
+**
+** gckOS_AtomicExchangePtr
+**
+** Atomically exchange a pair of pointers.
+**
+** INPUT:
+**
+** gckOS Os
+** Pointer to an gckOS object.
+**
+** IN OUT gctPOINTER * Target
+** Pointer to the 32-bit value to exchange.
+**
+** IN gctPOINTER NewValue
+** Specifies a new value for the pointer pointed to by Target.
+**
+** OUT gctPOINTER * OldValue
+** The old value of the pointer pointed to by Target.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckOS_AtomicExchangePtr(
+ IN gckOS Os,
+ IN OUT gctPOINTER * Target,
+ IN gctPOINTER NewValue,
+ OUT gctPOINTER * OldValue
+ )
+{
+ /* Exchange the pair of pointers. */
+ *OldValue = (gctPOINTER)(gctUINTPTR_T) atomic_xchg((atomic_t *) Target, (int)(gctUINTPTR_T) NewValue);
+ return gcvSTATUS_OK;
+}
+
+/*******************************************************************************
+**
+** gckOS_AtomicSetMask
+**
+** Atomically set mask to Atom
+**
+** INPUT:
+** IN OUT gctPOINTER Atom
+** Pointer to the atom to set.
+**
+** IN gctUINT32 Mask
+** Mask to set.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckOS_AtomSetMask(
+ IN gctPOINTER Atom,
+ IN gctUINT32 Mask
+ )
+{
+ gctUINT32 oval, nval;
+ do
+ {
+ oval = atomic_read((atomic_t *) Atom);
+ nval = oval | Mask;
+ }
+ while (atomic_cmpxchg((atomic_t *) Atom, oval, nval) != oval);
+ return gcvSTATUS_OK;
+}
+
+/*******************************************************************************
+**
+** gckOS_AtomClearMask
+**
+** Atomically clear mask from Atom
+**
+** INPUT:
+** IN OUT gctPOINTER Atom
+** Pointer to the atom to clear.
+**
+** IN gctUINT32 Mask
+** Mask to clear.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckOS_AtomClearMask(
+ IN gctPOINTER Atom,
+ IN gctUINT32 Mask
+ )
+{
+ gctUINT32 oval, nval;
+
+ do
+ {
+ oval = atomic_read((atomic_t *) Atom);
+ nval = oval & ~Mask;
+ }
+ while (atomic_cmpxchg((atomic_t *) Atom, oval, nval) != oval);
+
+ return gcvSTATUS_OK;
+}
+
+/*******************************************************************************
+**
+** gckOS_AtomConstruct
+**
+** Create an atom.
+**
+** INPUT:
+**
+** gckOS Os
+** Pointer to a gckOS object.
+**
+** OUTPUT:
+**
+** gctPOINTER * Atom
+** Pointer to a variable receiving the constructed atom.
+*/
+gceSTATUS
+gckOS_AtomConstruct(
+ IN gckOS Os,
+ OUT gctPOINTER * Atom
+ )
+{
+ gceSTATUS status;
+
+ gcmkHEADER_ARG("Os=0x%X", Os);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
+ gcmkVERIFY_ARGUMENT(Atom != gcvNULL);
+
+ /* Allocate the atom. */
+ gcmkONERROR(gckOS_Allocate(Os, gcmSIZEOF(atomic_t), Atom));
+
+ /* Initialize the atom. */
+ atomic_set((atomic_t *) *Atom, 0);
+
+ /* Success. */
+ gcmkFOOTER_ARG("*Atom=0x%X", *Atom);
+ return gcvSTATUS_OK;
+
+OnError:
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+/*******************************************************************************
+**
+** gckOS_AtomDestroy
+**
+** Destroy an atom.
+**
+** INPUT:
+**
+** gckOS Os
+** Pointer to a gckOS object.
+**
+** gctPOINTER Atom
+** Pointer to the atom to destroy.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckOS_AtomDestroy(
+ IN gckOS Os,
+ OUT gctPOINTER Atom
+ )
+{
+ gceSTATUS status;
+
+ gcmkHEADER_ARG("Os=0x%X Atom=0x%0x", Os, Atom);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
+ gcmkVERIFY_ARGUMENT(Atom != gcvNULL);
+
+ /* Free the atom. */
+ gcmkONERROR(gcmkOS_SAFE_FREE(Os, Atom));
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+/*******************************************************************************
+**
+** gckOS_AtomGet
+**
+** Get the 32-bit value protected by an atom.
+**
+** INPUT:
+**
+** gckOS Os
+** Pointer to a gckOS object.
+**
+** gctPOINTER Atom
+** Pointer to the atom.
+**
+** OUTPUT:
+**
+** gctINT32_PTR Value
+** Pointer to a variable the receives the value of the atom.
+*/
+gceSTATUS
+gckOS_AtomGet(
+ IN gckOS Os,
+ IN gctPOINTER Atom,
+ OUT gctINT32_PTR Value
+ )
+{
+ /* Return the current value of atom. */
+ *Value = atomic_read((atomic_t *) Atom);
+ return gcvSTATUS_OK;
+}
+
+/*******************************************************************************
+**
+** gckOS_AtomSet
+**
+** Set the 32-bit value protected by an atom.
+**
+** INPUT:
+**
+** gckOS Os
+** Pointer to a gckOS object.
+**
+** gctPOINTER Atom
+** Pointer to the atom.
+**
+** gctINT32 Value
+** The value of the atom.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckOS_AtomSet(
+ IN gckOS Os,
+ IN gctPOINTER Atom,
+ IN gctINT32 Value
+ )
+{
+ /* Set the current value of atom. */
+ atomic_set((atomic_t *) Atom, Value);
+ return gcvSTATUS_OK;
+}
+
+/*******************************************************************************
+**
+** gckOS_AtomIncrement
+**
+** Atomically increment the 32-bit integer value inside an atom.
+**
+** INPUT:
+**
+** gckOS Os
+** Pointer to a gckOS object.
+**
+** gctPOINTER Atom
+** Pointer to the atom.
+**
+** OUTPUT:
+**
+** gctINT32_PTR Value
+** Pointer to a variable that receives the original value of the atom.
+*/
+gceSTATUS
+gckOS_AtomIncrement(
+ IN gckOS Os,
+ IN gctPOINTER Atom,
+ OUT gctINT32_PTR Value
+ )
+{
+ /* Increment the atom. */
+ *Value = atomic_inc_return((atomic_t *) Atom) - 1;
+ return gcvSTATUS_OK;
+}
+
+/*******************************************************************************
+**
+** gckOS_AtomDecrement
+**
+** Atomically decrement the 32-bit integer value inside an atom.
+**
+** INPUT:
+**
+** gckOS Os
+** Pointer to a gckOS object.
+**
+** gctPOINTER Atom
+** Pointer to the atom.
+**
+** OUTPUT:
+**
+** gctINT32_PTR Value
+** Pointer to a variable that receives the original value of the atom.
+*/
+gceSTATUS
+gckOS_AtomDecrement(
+ IN gckOS Os,
+ IN gctPOINTER Atom,
+ OUT gctINT32_PTR Value
+ )
+{
+ /* Decrement the atom. */
+ *Value = atomic_dec_return((atomic_t *) Atom) + 1;
+ return gcvSTATUS_OK;
+}
+
+/*******************************************************************************
+**
+** gckOS_Delay
+**
+** Delay execution of the current thread for a number of milliseconds.
+**
+** INPUT:
+**
+** gckOS Os
+** Pointer to an gckOS object.
+**
+** gctUINT32 Delay
+** Delay to sleep, specified in milliseconds.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckOS_Delay(
+ IN gckOS Os,
+ IN gctUINT32 Delay
+ )
+{
+ gcmkHEADER_ARG("Os=0x%X Delay=%u", Os, Delay);
+
+ if (Delay > 0)
+ {
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28)
+ ktime_t delay = ktime_set((Delay / MSEC_PER_SEC), (Delay % MSEC_PER_SEC) * NSEC_PER_MSEC);
+ __set_current_state(TASK_UNINTERRUPTIBLE);
+ schedule_hrtimeout(&delay, HRTIMER_MODE_REL);
+#else
+ msleep(Delay);
+#endif
+ }
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+}
+
+/*******************************************************************************
+**
+** gckOS_GetTicks
+**
+** Get the number of milliseconds since the system started.
+**
+** INPUT:
+**
+** OUTPUT:
+**
+** gctUINT32_PTR Time
+** Pointer to a variable to get time.
+**
+*/
+gceSTATUS
+gckOS_GetTicks(
+ OUT gctUINT32_PTR Time
+ )
+{
+ gcmkHEADER();
+
+ *Time = jiffies_to_msecs(jiffies);
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+}
+
+/*******************************************************************************
+**
+** gckOS_TicksAfter
+**
+** Compare time values got from gckOS_GetTicks.
+**
+** INPUT:
+** gctUINT32 Time1
+** First time value to be compared.
+**
+** gctUINT32 Time2
+** Second time value to be compared.
+**
+** OUTPUT:
+**
+** gctBOOL_PTR IsAfter
+** Pointer to a variable to result.
+**
+*/
+gceSTATUS
+gckOS_TicksAfter(
+ IN gctUINT32 Time1,
+ IN gctUINT32 Time2,
+ OUT gctBOOL_PTR IsAfter
+ )
+{
+ gcmkHEADER();
+
+ *IsAfter = time_after((unsigned long)Time1, (unsigned long)Time2);
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+}
+
+/*******************************************************************************
+**
+** gckOS_GetTime
+**
+** Get the number of microseconds since the system started.
+**
+** INPUT:
+**
+** OUTPUT:
+**
+** gctUINT64_PTR Time
+** Pointer to a variable to get time.
+**
+*/
+gceSTATUS
+gckOS_GetTime(
+ OUT gctUINT64_PTR Time
+ )
+{
+ struct timeval tv;
+ gcmkHEADER();
+
+ /* Return the time of day in microseconds. */
+ do_gettimeofday(&tv);
+ *Time = (tv.tv_sec * 1000000ULL) + tv.tv_usec;
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+}
+
+/*******************************************************************************
+**
+** gckOS_MemoryBarrier
+**
+** Make sure the CPU has executed everything up to this point and the data got
+** written to the specified pointer.
+**
+** INPUT:
+**
+** gckOS Os
+** Pointer to an gckOS object.
+**
+** gctPOINTER Address
+** Address of memory that needs to be barriered.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckOS_MemoryBarrier(
+ IN gckOS Os,
+ IN gctPOINTER Address
+ )
+{
+ _MemoryBarrier();
+
+ return gcvSTATUS_OK;
+}
+
+/*******************************************************************************
+**
+** gckOS_AllocatePagedMemory
+**
+** Allocate memory from the paged pool.
+**
+** INPUT:
+**
+** gckOS Os
+** Pointer to an gckOS object.
+**
+** gctSIZE_T Bytes
+** Number of bytes to allocate.
+**
+** OUTPUT:
+**
+** gctPHYS_ADDR * Physical
+** Pointer to a variable that receives the physical address of the
+** memory allocation.
+*/
+gceSTATUS
+gckOS_AllocatePagedMemory(
+ IN gckOS Os,
+ IN gctSIZE_T Bytes,
+ OUT gctPHYS_ADDR * Physical
+ )
+{
+ gceSTATUS status;
+
+ gcmkHEADER_ARG("Os=0x%X Bytes=%lu", Os, Bytes);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
+ gcmkVERIFY_ARGUMENT(Bytes > 0);
+ gcmkVERIFY_ARGUMENT(Physical != gcvNULL);
+
+ /* Allocate the memory. */
+ gcmkONERROR(gckOS_AllocatePagedMemoryEx(Os, gcvALLOC_FLAG_NONE, Bytes, gcvNULL, Physical));
+
+ /* Success. */
+ gcmkFOOTER_ARG("*Physical=0x%X", *Physical);
+ return gcvSTATUS_OK;
+
+OnError:
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+/*******************************************************************************
+**
+** gckOS_AllocatePagedMemoryEx
+**
+** Allocate memory from the paged pool.
+**
+** INPUT:
+**
+** gckOS Os
+** Pointer to an gckOS object.
+**
+** gctUINT32 Flag
+** Allocation attribute.
+**
+** gctSIZE_T Bytes
+** Number of bytes to allocate.
+**
+** OUTPUT:
+**
+** gctUINT32 * Gid
+** Save the global ID for the piece of allocated memory.
+**
+** gctPHYS_ADDR * Physical
+** Pointer to a variable that receives the physical address of the
+** memory allocation.
+*/
+gceSTATUS
+gckOS_AllocatePagedMemoryEx(
+ IN gckOS Os,
+ IN gctUINT32 Flag,
+ IN gctSIZE_T Bytes,
+ OUT gctUINT32 * Gid,
+ OUT gctPHYS_ADDR * Physical
+ )
+{
+ gctINT numPages;
+ PLINUX_MDL mdl = gcvNULL;
+ gctSIZE_T bytes;
+ gceSTATUS status = gcvSTATUS_NOT_SUPPORTED;
+ gckALLOCATOR allocator;
+
+ gcmkHEADER_ARG("Os=0x%X Flag=%x Bytes=%lu", Os, Flag, Bytes);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
+ gcmkVERIFY_ARGUMENT(Bytes > 0);
+ gcmkVERIFY_ARGUMENT(Physical != gcvNULL);
+
+ bytes = gcmALIGN(Bytes, PAGE_SIZE);
+
+ numPages = GetPageCount(bytes, 0);
+
+ mdl = _CreateMdl(Os);
+ if (mdl == gcvNULL)
+ {
+ gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
+ }
+
+ if (Os->allocatorLimitMarker && (Flag & gcvALLOC_FLAG_CMA_LIMIT))
+ {
+ Flag &= ~gcvALLOC_FLAG_CACHEABLE;
+ }
+ else
+ {
+ Flag &= ~gcvALLOC_FLAG_CMA_LIMIT;
+ }
+
+ /* Walk all allocators. */
+ list_for_each_entry(allocator, &Os->allocatorList, link)
+ {
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_OS,
+ "%s(%d) flag = %x allocator->capability = %x",
+ __FUNCTION__, __LINE__, Flag, allocator->capability);
+
+ if ((Flag & allocator->capability) != Flag)
+ {
+ continue;
+ }
+
+ status = allocator->ops->Alloc(allocator, mdl, numPages, Flag);
+
+ if (gcmIS_SUCCESS(status))
+ {
+ mdl->allocator = allocator;
+ break;
+ }
+ }
+
+ /* Check status. */
+ gcmkONERROR(status);
+
+ mdl->dmaHandle = 0;
+ mdl->addr = 0;
+ mdl->bytes = bytes;
+ mdl->numPages = numPages;
+ mdl->contiguous = Flag & gcvALLOC_FLAG_CONTIGUOUS;
+ mdl->cacheable = Flag & gcvALLOC_FLAG_CACHEABLE;
+
+ if (Gid != gcvNULL)
+ {
+ *Gid = mdl->gid;
+ }
+
+ /*
+ * Add this to a global list.
+ * Will be used by get physical address
+ * and mapuser pointer functions.
+ */
+ mutex_lock(&Os->mdlMutex);
+ list_add_tail(&mdl->link, &Os->mdlHead);
+ mutex_unlock(&Os->mdlMutex);
+
+ /* Return physical address. */
+ *Physical = (gctPHYS_ADDR) mdl;
+
+ /* Success. */
+ gcmkFOOTER_ARG("*Physical=0x%X", *Physical);
+ return gcvSTATUS_OK;
+
+OnError:
+ if (mdl != gcvNULL)
+ {
+ /* Free the memory. */
+ _DestroyMdl(mdl);
+ }
+
+ /* Return the status. */
+ gcmkFOOTER_ARG("Os=0x%X Flag=%x Bytes=%lu", Os, Flag, Bytes);
+ return status;
+}
+
+/*******************************************************************************
+**
+** gckOS_FreePagedMemory
+**
+** Free memory allocated from the paged pool.
+**
+** INPUT:
+**
+** gckOS Os
+** Pointer to an gckOS object.
+**
+** gctPHYS_ADDR Physical
+** Physical address of the allocation.
+**
+** gctSIZE_T Bytes
+** Number of bytes of the allocation.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckOS_FreePagedMemory(
+ IN gckOS Os,
+ IN gctPHYS_ADDR Physical,
+ IN gctSIZE_T Bytes
+ )
+{
+ PLINUX_MDL mdl = (PLINUX_MDL)Physical;
+
+ gcmkHEADER_ARG("Os=0x%X Physical=0x%X Bytes=%lu", Os, Physical, Bytes);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
+ gcmkVERIFY_ARGUMENT(Physical != gcvNULL);
+ gcmkVERIFY_ARGUMENT(Bytes > 0);
+
+ /* Free the structure... */
+ gcmkVERIFY_OK(_DestroyMdl(mdl));
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+}
+
+/*******************************************************************************
+**
+** gckOS_LockPages
+**
+** Lock memory allocated from the paged pool.
+**
+** INPUT:
+**
+** gckOS Os
+** Pointer to an gckOS object.
+**
+** gctPHYS_ADDR Physical
+** Physical address of the allocation.
+**
+** gctSIZE_T Bytes
+** Number of bytes of the allocation.
+**
+** gctBOOL Cacheable
+** Cache mode of mapping.
+**
+** OUTPUT:
+**
+** gctPOINTER * Logical
+** Pointer to a variable that receives the address of the mapped
+** memory.
+**
+** gctSIZE_T * PageCount
+** Pointer to a variable that receives the number of pages required for
+** the page table according to the GPU page size.
+*/
+gceSTATUS
+gckOS_LockPages(
+ IN gckOS Os,
+ IN gctPHYS_ADDR Physical,
+ IN gctSIZE_T Bytes,
+ IN gctBOOL Cacheable,
+ OUT gctPOINTER * Logical,
+ OUT gctSIZE_T * PageCount
+ )
+{
+ gceSTATUS status;
+ PLINUX_MDL mdl;
+ PLINUX_MDL_MAP mdlMap;
+ gckALLOCATOR allocator;
+
+ gcmkHEADER_ARG("Os=0x%X Physical=0x%X Bytes=%lu", Os, Physical, Logical);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
+ gcmkVERIFY_ARGUMENT(Physical != gcvNULL);
+ gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
+ gcmkVERIFY_ARGUMENT(PageCount != gcvNULL);
+
+ mdl = (PLINUX_MDL) Physical;
+ allocator = mdl->allocator;
+
+ mutex_lock(&mdl->mapsMutex);
+
+ mdlMap = FindMdlMap(mdl, _GetProcessID());
+
+ if (mdlMap == gcvNULL)
+ {
+ mdlMap = _CreateMdlMap(mdl, _GetProcessID());
+
+ if (mdlMap == gcvNULL)
+ {
+ mutex_unlock(&mdl->mapsMutex);
+
+ gcmkFOOTER_ARG("*status=%d", gcvSTATUS_OUT_OF_MEMORY);
+ return gcvSTATUS_OUT_OF_MEMORY;
+ }
+ }
+
+ if (mdlMap->vmaAddr == gcvNULL)
+ {
+ status = allocator->ops->MapUser(allocator, mdl, mdlMap, Cacheable);
+
+ if (gcmIS_ERROR(status))
+ {
+ mutex_unlock(&mdl->mapsMutex);
+
+ gcmkFOOTER_ARG("*status=%d", status);
+ return status;
+ }
+ }
+
+ mdlMap->count++;
+
+ /* Convert pointer to MDL. */
+ *Logical = mdlMap->vmaAddr;
+
+ /* Return the page number according to the GPU page size. */
+ gcmkASSERT((PAGE_SIZE % 4096) == 0);
+ gcmkASSERT((PAGE_SIZE / 4096) >= 1);
+
+ *PageCount = mdl->numPages * (PAGE_SIZE / 4096);
+
+ mutex_unlock(&mdl->mapsMutex);
+
+ /* Success. */
+ gcmkFOOTER_ARG("*Logical=0x%X *PageCount=%lu", *Logical, *PageCount);
+ return gcvSTATUS_OK;
+}
+
+/*******************************************************************************
+**
+** gckOS_MapPages
+**
+** Map paged memory into a page table.
+**
+** INPUT:
+**
+** gckOS Os
+** Pointer to an gckOS object.
+**
+** gctPHYS_ADDR Physical
+** Physical address of the allocation.
+**
+** gctSIZE_T PageCount
+** Number of pages required for the physical address.
+**
+** gctPOINTER PageTable
+** Pointer to the page table to fill in.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckOS_MapPages(
+ IN gckOS Os,
+ IN gctPHYS_ADDR Physical,
+ IN gctSIZE_T PageCount,
+ IN gctPOINTER PageTable
+ )
+{
+ return gcvSTATUS_NOT_SUPPORTED;
+}
+
+gceSTATUS
+gckOS_MapPagesEx(
+ IN gckOS Os,
+ IN gceCORE Core,
+ IN gctPHYS_ADDR Physical,
+ IN gctSIZE_T PageCount,
+ IN gctUINT32 Address,
+ IN gctPOINTER PageTable,
+ IN gctBOOL Writable,
+ IN gceSURF_TYPE Type
+ )
+{
+ gceSTATUS status = gcvSTATUS_OK;
+ PLINUX_MDL mdl;
+ gctUINT32* table;
+ gctUINT32 offset = 0;
+
+#if gcdPROCESS_ADDRESS_SPACE
+ gckKERNEL kernel = Os->device->kernels[Core];
+ gckMMU mmu;
+#endif
+
+ gctUINT32 bytes = PageCount * 4;
+
+ gckALLOCATOR allocator;
+
+ gctUINT32 policyID = 0;
+ gctUINT32 axiConfig = 0;
+
+ gcsPLATFORM * platform = Os->device->platform;
+
+ gcmkHEADER_ARG("Os=0x%X Core=%d Physical=0x%X PageCount=%u PageTable=0x%X",
+ Os, Core, Physical, PageCount, PageTable);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
+ gcmkVERIFY_ARGUMENT(Physical != gcvNULL);
+ gcmkVERIFY_ARGUMENT(PageCount > 0);
+ gcmkVERIFY_ARGUMENT(PageTable != gcvNULL);
+
+ /* Convert pointer to MDL. */
+ mdl = (PLINUX_MDL)Physical;
+
+ allocator = mdl->allocator;
+
+ gcmkASSERT(allocator != gcvNULL);
+
+ gcmkTRACE_ZONE(
+ gcvLEVEL_INFO, gcvZONE_OS,
+ "%s(%d): Physical->0x%X PageCount->0x%X",
+ __FUNCTION__, __LINE__,
+ (gctUINT32)(gctUINTPTR_T)Physical,
+ (gctUINT32)(gctUINTPTR_T)PageCount
+ );
+
+#if gcdPROCESS_ADDRESS_SPACE
+ gcmkONERROR(gckKERNEL_GetProcessMMU(kernel, &mmu));
+#endif
+
+ table = (gctUINT32 *)PageTable;
+
+ if (platform && platform->ops->getPolicyID)
+ {
+ platform->ops->getPolicyID(platform, Type, &policyID, &axiConfig);
+
+ gcmkBUG_ON(policyID > 0x1F);
+
+ /* ID[3:0] is used in STLB. */
+ policyID &= 0xF;
+ }
+
+ /* Get all the physical addresses and store them in the page table. */
+
+ PageCount = PageCount / (PAGE_SIZE / 4096);
+
+ /* Try to get the user pages so DMA can happen. */
+ while (PageCount-- > 0)
+ {
+ gctUINT i;
+ gctPHYS_ADDR_T phys = ~0U;
+
+ allocator->ops->Physical(allocator, mdl, offset, &phys);
+
+ gcmkVERIFY_OK(gckOS_CPUPhysicalToGPUPhysical(Os, phys, &phys));
+
+ if (policyID)
+ {
+ /* AxUSER must not used for address currently. */
+ gcmkBUG_ON((phys >> 32) & 0xF);
+
+ /* Merge policyID to AxUSER[7:4].*/
+ phys |= ((gctPHYS_ADDR_T)policyID << 36);
+ }
+
+#ifdef CONFIG_IOMMU_SUPPORT
+ if (Os->iommu)
+ {
+ /* remove LSB. */
+ phys &= PAGE_MASK;
+
+ gcmkTRACE_ZONE(
+ gcvLEVEL_INFO, gcvZONE_OS,
+ "%s(%d): Setup mapping in IOMMU %x => %x",
+ __FUNCTION__, __LINE__,
+ Address + offset, phys
+ );
+
+ /* When use IOMMU, GPU use system PAGE_SIZE. */
+ gcmkONERROR(gckIOMMU_Map(
+ Os->iommu, Address + offset, phys, PAGE_SIZE));
+ }
+ else
+#endif
+ {
+ /* remove LSB. */
+ phys &= ~(4096ull - 1);
+
+#if gcdENABLE_VG
+ if (Core == gcvCORE_VG)
+ {
+ for (i = 0; i < (PAGE_SIZE / 4096); i++)
+ {
+ gcmkONERROR(
+ gckVGMMU_SetPage(Os->device->kernels[Core]->vg->mmu,
+ phys + (i * 4096),
+ table++));
+ }
+ }
+ else
+#endif
+ {
+ for (i = 0; i < (PAGE_SIZE / 4096); i++)
+ {
+#if gcdPROCESS_ADDRESS_SPACE
+ gctUINT32_PTR pageTableEntry;
+ gckMMU_GetPageEntry(mmu, Address + offset + (i * 4096), &pageTableEntry);
+ gcmkONERROR(
+ gckMMU_SetPage(mmu,
+ phys + (i * 4096),
+ Writable,
+ pageTableEntry));
+#else
+ gcmkONERROR(
+ gckMMU_SetPage(Os->device->kernels[Core]->mmu,
+ phys + (i * 4096),
+ Writable,
+ table++));
+#endif
+ }
+ }
+ }
+
+ offset += PAGE_SIZE;
+ }
+
+#if gcdENABLE_VG
+ if (Core == gcvCORE_VG)
+ {
+ gckVGMMU mmu = Os->device->kernels[gcvCORE_VG]->vg->mmu;
+ gctPHYS_ADDR mmuMdl = mmu->pageTablePhysical;
+
+ offset = (gctUINT8_PTR)PageTable - (gctUINT8_PTR)mmu->pageTableLogical;
+
+ gcmkVERIFY_OK(gckOS_CacheClean(
+ Os,
+ _GetProcessID(),
+ mmuMdl,
+ offset,
+ PageTable,
+ bytes
+ ));
+ }
+ else
+# endif
+ {
+ gckMMU mmu = Os->device->kernels[Core]->mmu;
+ gcsADDRESS_AREA * area = &mmu->area[0];
+
+ offset = (gctUINT8_PTR)PageTable - (gctUINT8_PTR)area->pageTableLogical;
+
+ /* must be in dynamic area. */
+ gcmkASSERT(offset < area->pageTableSize);
+
+ gcmkVERIFY_OK(gckOS_CacheClean(
+ Os,
+ 0,
+ area->pageTablePhysical,
+ offset,
+ PageTable,
+ bytes
+ ));
+
+ if (mmu->mtlbPhysical)
+ {
+ /* Flush MTLB table. */
+ gcmkVERIFY_OK(gckOS_CacheClean(
+ Os,
+ 0,
+ mmu->mtlbPhysical,
+ 0,
+ mmu->mtlbLogical,
+ mmu->mtlbSize
+ ));
+ }
+ }
+
+OnError:
+
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+gceSTATUS
+gckOS_UnmapPages(
+ IN gckOS Os,
+ IN gctSIZE_T PageCount,
+ IN gctUINT32 Address
+ )
+{
+#ifdef CONFIG_IOMMU_SUPPORT
+ if (Os->iommu)
+ {
+ gcmkVERIFY_OK(gckIOMMU_Unmap(
+ Os->iommu, Address, PageCount * PAGE_SIZE));
+ }
+#endif
+
+ return gcvSTATUS_OK;
+}
+
+/*******************************************************************************
+**
+** gckOS_UnlockPages
+**
+** Unlock memory allocated from the paged pool.
+**
+** INPUT:
+**
+** gckOS Os
+** Pointer to an gckOS object.
+**
+** gctPHYS_ADDR Physical
+** Physical address of the allocation.
+**
+** gctSIZE_T Bytes
+** Number of bytes of the allocation.
+**
+** gctPOINTER Logical
+** Address of the mapped memory.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckOS_UnlockPages(
+ IN gckOS Os,
+ IN gctPHYS_ADDR Physical,
+ IN gctSIZE_T Bytes,
+ IN gctPOINTER Logical
+ )
+{
+ PLINUX_MDL_MAP mdlMap;
+ PLINUX_MDL mdl = (PLINUX_MDL)Physical;
+ gckALLOCATOR allocator = mdl->allocator;
+ gctINT pid = _GetProcessID();
+
+ gcmkHEADER_ARG("Os=0x%X Physical=0x%X Bytes=%u Logical=0x%X",
+ Os, Physical, Bytes, Logical);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
+ gcmkVERIFY_ARGUMENT(Physical != gcvNULL);
+ gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
+
+ mutex_lock(&mdl->mapsMutex);
+
+ list_for_each_entry(mdlMap, &mdl->mapsHead, link)
+ {
+ if ((mdlMap->vmaAddr != gcvNULL) && (mdlMap->pid == pid))
+ {
+ if (--mdlMap->count == 0)
+ {
+ allocator->ops->UnmapUser(
+ allocator,
+ mdl,
+ mdlMap,
+ mdl->bytes);
+
+ mdlMap->vmaAddr = gcvNULL;
+ }
+ }
+ }
+
+ mutex_unlock(&mdl->mapsMutex);
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+}
+
+
+/*******************************************************************************
+**
+** gckOS_AllocateContiguous
+**
+** Allocate memory from the contiguous pool.
+**
+** INPUT:
+**
+** gckOS Os
+** Pointer to an gckOS object.
+**
+** gctBOOL InUserSpace
+** gcvTRUE if the pages need to be mapped into user space.
+**
+** gctSIZE_T * Bytes
+** Pointer to the number of bytes to allocate.
+**
+** OUTPUT:
+**
+** gctSIZE_T * Bytes
+** Pointer to a variable that receives the number of bytes allocated.
+**
+** gctPHYS_ADDR * Physical
+** Pointer to a variable that receives the physical address of the
+** memory allocation.
+**
+** gctPOINTER * Logical
+** Pointer to a variable that receives the logical address of the
+** memory allocation.
+*/
+gceSTATUS
+gckOS_AllocateContiguous(
+ IN gckOS Os,
+ IN gctBOOL InUserSpace,
+ IN OUT gctSIZE_T * Bytes,
+ OUT gctPHYS_ADDR * Physical,
+ OUT gctPOINTER * Logical
+ )
+{
+ gceSTATUS status;
+
+ gcmkHEADER_ARG("Os=0x%X InUserSpace=%d *Bytes=%lu",
+ Os, InUserSpace, gcmOPT_VALUE(Bytes));
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
+ gcmkVERIFY_ARGUMENT(Bytes != gcvNULL);
+ gcmkVERIFY_ARGUMENT(*Bytes > 0);
+ gcmkVERIFY_ARGUMENT(Physical != gcvNULL);
+ gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
+
+ /* Same as non-paged memory for now. */
+ gcmkONERROR(gckOS_AllocateNonPagedMemory(Os,
+ InUserSpace,
+ gcvALLOC_FLAG_CONTIGUOUS,
+ Bytes,
+ Physical,
+ Logical));
+
+ /* Success. */
+ gcmkFOOTER_ARG("*Bytes=%lu *Physical=0x%X *Logical=0x%X",
+ *Bytes, *Physical, *Logical);
+ return gcvSTATUS_OK;
+
+OnError:
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+/*******************************************************************************
+**
+** gckOS_FreeContiguous
+**
+** Free memory allocated from the contiguous pool.
+**
+** INPUT:
+**
+** gckOS Os
+** Pointer to an gckOS object.
+**
+** gctPHYS_ADDR Physical
+** Physical address of the allocation.
+**
+** gctPOINTER Logical
+** Logicval address of the allocation.
+**
+** gctSIZE_T Bytes
+** Number of bytes of the allocation.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckOS_FreeContiguous(
+ IN gckOS Os,
+ IN gctPHYS_ADDR Physical,
+ IN gctPOINTER Logical,
+ IN gctSIZE_T Bytes
+ )
+{
+ gceSTATUS status;
+
+ gcmkHEADER_ARG("Os=0x%X Physical=0x%X Logical=0x%X Bytes=%lu",
+ Os, Physical, Logical, Bytes);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
+ gcmkVERIFY_ARGUMENT(Physical != gcvNULL);
+ gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
+ gcmkVERIFY_ARGUMENT(Bytes > 0);
+
+ /* Same of non-paged memory for now. */
+ gcmkONERROR(gckOS_FreeNonPagedMemory(Os, Bytes, Physical, Logical));
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+#if gcdENABLE_VG
+/******************************************************************************
+**
+** gckOS_GetKernelLogical
+**
+** Return the kernel logical pointer that corresponods to the specified
+** hardware address.
+**
+** INPUT:
+**
+** gckOS Os
+** Pointer to an gckOS object.
+**
+** gctUINT32 Address
+** Hardware physical address.
+**
+** OUTPUT:
+**
+** gctPOINTER * KernelPointer
+** Pointer to a variable receiving the pointer in kernel address space.
+*/
+gceSTATUS
+gckOS_GetKernelLogical(
+ IN gckOS Os,
+ IN gctUINT32 Address,
+ OUT gctPOINTER * KernelPointer
+ )
+{
+ return gckOS_GetKernelLogicalEx(Os, gcvCORE_MAJOR, Address, KernelPointer);
+}
+
+gceSTATUS
+gckOS_GetKernelLogicalEx(
+ IN gckOS Os,
+ IN gceCORE Core,
+ IN gctUINT32 Address,
+ OUT gctPOINTER * KernelPointer
+ )
+{
+ gceSTATUS status;
+
+ gcmkHEADER_ARG("Os=0x%X Core=%d Address=0x%08x", Os, Core, Address);
+
+ do
+ {
+ gckGALDEVICE device;
+ gckKERNEL kernel;
+ gcePOOL pool;
+ gctUINT32 offset;
+ gctPOINTER logical;
+
+ /* Extract the pointer to the gckGALDEVICE class. */
+ device = (gckGALDEVICE) Os->device;
+
+ /* Kernel shortcut. */
+ kernel = device->kernels[Core];
+#if gcdENABLE_VG
+ if (Core == gcvCORE_VG)
+ {
+ gcmkERR_BREAK(gckVGHARDWARE_SplitMemory(
+ kernel->vg->hardware, Address, &pool, &offset
+ ));
+ }
+ else
+#endif
+ {
+ /* Split the memory address into a pool type and offset. */
+ gcmkERR_BREAK(gckHARDWARE_SplitMemory(
+ kernel->hardware, Address, &pool, &offset
+ ));
+ }
+
+ /* Dispatch on pool. */
+ switch (pool)
+ {
+ case gcvPOOL_LOCAL_INTERNAL:
+ /* Internal memory. */
+ logical = device->internalLogical;
+ break;
+
+ case gcvPOOL_LOCAL_EXTERNAL:
+ /* External memory. */
+ logical = device->externalLogical;
+ break;
+
+ case gcvPOOL_SYSTEM:
+ /* System memory. */
+ logical = device->contiguousLogical;
+ break;
+
+ default:
+ /* Invalid memory pool. */
+ gcmkFOOTER();
+ return gcvSTATUS_INVALID_ARGUMENT;
+ }
+
+ /* Build logical address of specified address. */
+ * KernelPointer = ((gctUINT8_PTR) logical) + offset;
+
+ /* Success. */
+ gcmkFOOTER_ARG("*KernelPointer=0x%X", *KernelPointer);
+ return gcvSTATUS_OK;
+ }
+ while (gcvFALSE);
+
+ /* Return status. */
+ gcmkFOOTER();
+ return status;
+}
+#endif
+
+/*******************************************************************************
+**
+** gckOS_MapUserPointer
+**
+** Map a pointer from the user process into the kernel address space.
+**
+** INPUT:
+**
+** gckOS Os
+** Pointer to an gckOS object.
+**
+** gctPOINTER Pointer
+** Pointer in user process space that needs to be mapped.
+**
+** gctSIZE_T Size
+** Number of bytes that need to be mapped.
+**
+** OUTPUT:
+**
+** gctPOINTER * KernelPointer
+** Pointer to a variable receiving the mapped pointer in kernel address
+** space.
+*/
+gceSTATUS
+gckOS_MapUserPointer(
+ IN gckOS Os,
+ IN gctPOINTER Pointer,
+ IN gctSIZE_T Size,
+ OUT gctPOINTER * KernelPointer
+ )
+{
+ gcmkHEADER_ARG("Os=0x%X Pointer=0x%X Size=%lu", Os, Pointer, Size);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
+ gcmkVERIFY_ARGUMENT(Pointer != gcvNULL);
+ gcmkVERIFY_ARGUMENT(Size > 0);
+ gcmkVERIFY_ARGUMENT(KernelPointer != gcvNULL);
+
+ *KernelPointer = Pointer;
+
+ gcmkFOOTER_ARG("*KernelPointer=0x%X", *KernelPointer);
+ return gcvSTATUS_OK;
+}
+
+/*******************************************************************************
+**
+** gckOS_UnmapUserPointer
+**
+** Unmap a user process pointer from the kernel address space.
+**
+** INPUT:
+**
+** gckOS Os
+** Pointer to an gckOS object.
+**
+** gctPOINTER Pointer
+** Pointer in user process space that needs to be unmapped.
+**
+** gctSIZE_T Size
+** Number of bytes that need to be unmapped.
+**
+** gctPOINTER KernelPointer
+** Pointer in kernel address space that needs to be unmapped.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckOS_UnmapUserPointer(
+ IN gckOS Os,
+ IN gctPOINTER Pointer,
+ IN gctSIZE_T Size,
+ IN gctPOINTER KernelPointer
+ )
+{
+ gcmkHEADER_ARG("Os=0x%X Pointer=0x%X Size=%lu KernelPointer=0x%X",
+ Os, Pointer, Size, KernelPointer);
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+}
+
+/*******************************************************************************
+**
+** gckOS_QueryNeedCopy
+**
+** Query whether the memory can be accessed or mapped directly or it has to be
+** copied.
+**
+** INPUT:
+**
+** gckOS Os
+** Pointer to an gckOS object.
+**
+** gctUINT32 ProcessID
+** Process ID of the current process.
+**
+** OUTPUT:
+**
+** gctBOOL_PTR NeedCopy
+** Pointer to a boolean receiving gcvTRUE if the memory needs a copy or
+** gcvFALSE if the memory can be accessed or mapped dircetly.
+*/
+gceSTATUS
+gckOS_QueryNeedCopy(
+ IN gckOS Os,
+ IN gctUINT32 ProcessID,
+ OUT gctBOOL_PTR NeedCopy
+ )
+{
+ gcmkHEADER_ARG("Os=0x%X ProcessID=%d", Os, ProcessID);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
+ gcmkVERIFY_ARGUMENT(NeedCopy != gcvNULL);
+
+ /* We need to copy data. */
+ *NeedCopy = gcvTRUE;
+
+ /* Success. */
+ gcmkFOOTER_ARG("*NeedCopy=%d", *NeedCopy);
+ return gcvSTATUS_OK;
+}
+
+/*******************************************************************************
+**
+** gckOS_CopyFromUserData
+**
+** Copy data from user to kernel memory.
+**
+** INPUT:
+**
+** gckOS Os
+** Pointer to an gckOS object.
+**
+** gctPOINTER KernelPointer
+** Pointer to kernel memory.
+**
+** gctPOINTER Pointer
+** Pointer to user memory.
+**
+** gctSIZE_T Size
+** Number of bytes to copy.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckOS_CopyFromUserData(
+ IN gckOS Os,
+ IN gctPOINTER KernelPointer,
+ IN gctPOINTER Pointer,
+ IN gctSIZE_T Size
+ )
+{
+ gceSTATUS status;
+
+ gcmkHEADER_ARG("Os=0x%X KernelPointer=0x%X Pointer=0x%X Size=%lu",
+ Os, KernelPointer, Pointer, Size);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
+ gcmkVERIFY_ARGUMENT(KernelPointer != gcvNULL);
+ gcmkVERIFY_ARGUMENT(Pointer != gcvNULL);
+ gcmkVERIFY_ARGUMENT(Size > 0);
+
+ /* Copy data from user. */
+ if (copy_from_user(KernelPointer, Pointer, Size) != 0)
+ {
+ /* Could not copy all the bytes. */
+ gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
+ }
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+/*******************************************************************************
+**
+** gckOS_CopyToUserData
+**
+** Copy data from kernel to user memory.
+**
+** INPUT:
+**
+** gckOS Os
+** Pointer to an gckOS object.
+**
+** gctPOINTER KernelPointer
+** Pointer to kernel memory.
+**
+** gctPOINTER Pointer
+** Pointer to user memory.
+**
+** gctSIZE_T Size
+** Number of bytes to copy.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckOS_CopyToUserData(
+ IN gckOS Os,
+ IN gctPOINTER KernelPointer,
+ IN gctPOINTER Pointer,
+ IN gctSIZE_T Size
+ )
+{
+ gceSTATUS status;
+
+ gcmkHEADER_ARG("Os=0x%X KernelPointer=0x%X Pointer=0x%X Size=%lu",
+ Os, KernelPointer, Pointer, Size);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
+ gcmkVERIFY_ARGUMENT(KernelPointer != gcvNULL);
+ gcmkVERIFY_ARGUMENT(Pointer != gcvNULL);
+ gcmkVERIFY_ARGUMENT(Size > 0);
+
+ /* Copy data to user. */
+ if (copy_to_user(Pointer, KernelPointer, Size) != 0)
+ {
+ /* Could not copy all the bytes. */
+ gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
+ }
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+/*******************************************************************************
+**
+** gckOS_WriteMemory
+**
+** Write data to a memory.
+**
+** INPUT:
+**
+** gckOS Os
+** Pointer to an gckOS object.
+**
+** gctPOINTER Address
+** Address of the memory to write to.
+**
+** gctUINT32 Data
+** Data for register.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckOS_WriteMemory(
+ IN gckOS Os,
+ IN gctPOINTER Address,
+ IN gctUINT32 Data
+ )
+{
+ gceSTATUS status;
+ gcmkHEADER_ARG("Os=0x%X Address=0x%X Data=%u", Os, Address, Data);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_ARGUMENT(Address != gcvNULL);
+
+ /* Write memory. */
+ if (access_ok(VERIFY_WRITE, Address, 4))
+ {
+ /* User address. */
+ if (put_user(Data, (gctUINT32*)Address))
+ {
+ gcmkONERROR(gcvSTATUS_INVALID_ADDRESS);
+ }
+ }
+ else
+ {
+ /* Kernel address. */
+ *(gctUINT32 *)Address = Data;
+ }
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ gcmkFOOTER();
+ return status;
+}
+
+gceSTATUS
+gckOS_ReadMappedPointer(
+ IN gckOS Os,
+ IN gctPOINTER Address,
+ IN gctUINT32_PTR Data
+ )
+{
+ gceSTATUS status;
+ gcmkHEADER_ARG("Os=0x%X Address=0x%X Data=%u", Os, Address, Data);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_ARGUMENT(Address != gcvNULL);
+
+ /* Write memory. */
+ if (access_ok(VERIFY_READ, Address, 4))
+ {
+ /* User address. */
+ if (get_user(*Data, (gctUINT32*)Address))
+ {
+ gcmkONERROR(gcvSTATUS_INVALID_ADDRESS);
+ }
+ }
+ else
+ {
+ /* Kernel address. */
+ *Data = *(gctUINT32_PTR)Address;
+ }
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ gcmkFOOTER();
+ return status;
+}
+
+/*******************************************************************************
+**
+** gckOS_MapUserMemory
+**
+** Lock down a user buffer and return an DMA'able address to be used by the
+** hardware to access it.
+**
+** INPUT:
+**
+** gctPOINTER Memory
+** Pointer to memory to lock down.
+**
+** gctSIZE_T Size
+** Size in bytes of the memory to lock down.
+**
+** OUTPUT:
+**
+** gctPOINTER * Info
+** Pointer to variable receiving the information record required by
+** gckOS_UnmapUserMemory.
+**
+** gctUINT32_PTR Address
+** Pointer to a variable that will receive the address DMA'able by the
+** hardware.
+*/
+gceSTATUS
+gckOS_MapUserMemory(
+ IN gckOS Os,
+ IN gceCORE Core,
+ IN gctPOINTER Memory,
+ IN gctUINT32 Physical,
+ IN gctSIZE_T Size,
+ OUT gctPOINTER * Info,
+ OUT gctUINT32_PTR Address
+ )
+{
+ return gcvSTATUS_NOT_SUPPORTED;
+}
+
+/*******************************************************************************
+**
+** gckOS_UnmapUserMemory
+**
+** Unlock a user buffer and that was previously locked down by
+** gckOS_MapUserMemory.
+**
+** INPUT:
+**
+** gctPOINTER Memory
+** Pointer to memory to unlock.
+**
+** gctSIZE_T Size
+** Size in bytes of the memory to unlock.
+**
+** gctPOINTER Info
+** Information record returned by gckOS_MapUserMemory.
+**
+** gctUINT32_PTR Address
+** The address returned by gckOS_MapUserMemory.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckOS_UnmapUserMemory(
+ IN gckOS Os,
+ IN gceCORE Core,
+ IN gctPOINTER Memory,
+ IN gctSIZE_T Size,
+ IN gctPOINTER Info,
+ IN gctUINT32 Address
+ )
+{
+ return gcvSTATUS_NOT_SUPPORTED;
+}
+
+/*******************************************************************************
+**
+** gckOS_GetBaseAddress
+**
+** Get the base address for the physical memory.
+**
+** INPUT:
+**
+** gckOS Os
+** Pointer to the gckOS object.
+**
+** OUTPUT:
+**
+** gctUINT32_PTR BaseAddress
+** Pointer to a variable that will receive the base address.
+*/
+gceSTATUS
+gckOS_GetBaseAddress(
+ IN gckOS Os,
+ OUT gctUINT32_PTR BaseAddress
+ )
+{
+ gcmkHEADER_ARG("Os=0x%X", Os);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
+ gcmkVERIFY_ARGUMENT(BaseAddress != gcvNULL);
+
+ /* Return base address. */
+ *BaseAddress = Os->device->baseAddress;
+
+ /* Success. */
+ gcmkFOOTER_ARG("*BaseAddress=0x%08x", *BaseAddress);
+ return gcvSTATUS_OK;
+}
+
+gceSTATUS
+gckOS_SuspendInterrupt(
+ IN gckOS Os
+ )
+{
+ return gckOS_SuspendInterruptEx(Os, gcvCORE_MAJOR);
+}
+
+gceSTATUS
+gckOS_SuspendInterruptEx(
+ IN gckOS Os,
+ IN gceCORE Core
+ )
+{
+ gcmkHEADER_ARG("Os=0x%X Core=%d", Os, Core);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
+
+ disable_irq(Os->device->irqLines[Core]);
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+}
+
+gceSTATUS
+gckOS_ResumeInterrupt(
+ IN gckOS Os
+ )
+{
+ return gckOS_ResumeInterruptEx(Os, gcvCORE_MAJOR);
+}
+
+gceSTATUS
+gckOS_ResumeInterruptEx(
+ IN gckOS Os,
+ IN gceCORE Core
+ )
+{
+ gcmkHEADER_ARG("Os=0x%X Core=%d", Os, Core);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
+
+ enable_irq(Os->device->irqLines[Core]);
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+}
+
+gceSTATUS
+gckOS_MemCopy(
+ IN gctPOINTER Destination,
+ IN gctCONST_POINTER Source,
+ IN gctSIZE_T Bytes
+ )
+{
+ gcmkHEADER_ARG("Destination=0x%X Source=0x%X Bytes=%lu",
+ Destination, Source, Bytes);
+
+ gcmkVERIFY_ARGUMENT(Destination != gcvNULL);
+ gcmkVERIFY_ARGUMENT(Source != gcvNULL);
+ gcmkVERIFY_ARGUMENT(Bytes > 0);
+
+ memcpy(Destination, Source, Bytes);
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+}
+
+gceSTATUS
+gckOS_ZeroMemory(
+ IN gctPOINTER Memory,
+ IN gctSIZE_T Bytes
+ )
+{
+ gcmkHEADER_ARG("Memory=0x%X Bytes=%lu", Memory, Bytes);
+
+ gcmkVERIFY_ARGUMENT(Memory != gcvNULL);
+ gcmkVERIFY_ARGUMENT(Bytes > 0);
+
+ memset(Memory, 0, Bytes);
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+}
+
+/*******************************************************************************
+********************************* Cache Control ********************************
+*******************************************************************************/
+static gceSTATUS
+_CacheOperation(
+ IN gckOS Os,
+ IN gctUINT32 ProcessID,
+ IN gctPHYS_ADDR Handle,
+ IN gctSIZE_T Offset,
+ IN gctPOINTER Logical,
+ IN gctSIZE_T Bytes,
+ IN gceCACHEOPERATION Operation
+ )
+{
+ PLINUX_MDL mdl = (PLINUX_MDL)Handle;
+ PLINUX_MDL_MAP mdlMap = gcvNULL;
+ gckALLOCATOR allocator;
+
+ if (!mdl || !mdl->allocator)
+ {
+ gcmkPRINT("[galcore]: %s: Logical=%p no mdl", __FUNCTION__, Logical);
+ return gcvSTATUS_INVALID_ARGUMENT;
+ }
+
+ allocator = mdl->allocator;
+
+ if (allocator->ops->Cache)
+ {
+ if (ProcessID)
+ {
+ mutex_lock(&mdl->mapsMutex);
+
+ mdlMap = FindMdlMap(mdl, ProcessID);
+
+ mutex_unlock(&mdl->mapsMutex);
+ }
+
+ if (ProcessID && mdlMap == gcvNULL)
+ {
+ return gcvSTATUS_INVALID_ARGUMENT;
+ }
+
+ if ((!ProcessID && mdl->cacheable) ||
+ (mdlMap && mdlMap->cacheable))
+ {
+ allocator->ops->Cache(allocator,
+ mdl, Offset, Logical, Bytes, Operation);
+
+ return gcvSTATUS_OK;
+ }
+ }
+
+ return gcvSTATUS_OK;
+}
+
+/*******************************************************************************
+** gckOS_CacheClean
+**
+** Clean the cache for the specified addresses. The GPU is going to need the
+** data. If the system is allocating memory as non-cachable, this function can
+** be ignored.
+**
+** ARGUMENTS:
+**
+** gckOS Os
+** Pointer to gckOS object.
+**
+** gctUINT32 ProcessID
+** Process ID Logical belongs.
+**
+** gctPHYS_ADDR Handle
+** Physical address handle. If gcvNULL it is video memory.
+**
+** gctSIZE_T Offset
+** Offset to this memory block.
+**
+** gctPOINTER Logical
+** Logical address to flush.
+**
+** gctSIZE_T Bytes
+** Size of the address range in bytes to flush.
+*/
+
+/*
+
+Following patch can be applied to kernel in case cache API is not exported.
+
+diff --git a/arch/arm/mm/proc-syms.c b/arch/arm/mm/proc-syms.c
+index 054b491..e9e74ec 100644
+--- a/arch/arm/mm/proc-syms.c
++++ b/arch/arm/mm/proc-syms.c
+@@ -30,6 +30,9 @@ EXPORT_SYMBOL(__cpuc_flush_user_all);
+ EXPORT_SYMBOL(__cpuc_flush_user_range);
+ EXPORT_SYMBOL(__cpuc_coherent_kern_range);
+ EXPORT_SYMBOL(__cpuc_flush_dcache_area);
++EXPORT_SYMBOL(__glue(_CACHE,_dma_map_area));
++EXPORT_SYMBOL(__glue(_CACHE,_dma_unmap_area));
++EXPORT_SYMBOL(__glue(_CACHE,_dma_flush_range));
+ #else
+ EXPORT_SYMBOL(cpu_cache);
+ #endif
+
+*/
+gceSTATUS
+gckOS_CacheClean(
+ IN gckOS Os,
+ IN gctUINT32 ProcessID,
+ IN gctPHYS_ADDR Handle,
+ IN gctSIZE_T Offset,
+ IN gctPOINTER Logical,
+ IN gctSIZE_T Bytes
+ )
+{
+ gceSTATUS status;
+
+ gcmkHEADER_ARG("Os=0x%X ProcessID=%d Handle=0x%X Logical=%p Bytes=%lu",
+ Os, ProcessID, Handle, Logical, Bytes);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
+ gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
+ gcmkVERIFY_ARGUMENT(Bytes > 0);
+
+ gcmkONERROR(_CacheOperation(Os, ProcessID,
+ Handle, Offset, Logical, Bytes,
+ gcvCACHE_CLEAN));
+
+OnError:
+ gcmkFOOTER();
+ return status;
+
+}
+
+/*******************************************************************************
+** gckOS_CacheInvalidate
+**
+** Invalidate the cache for the specified addresses. The GPU is going to need
+** data. If the system is allocating memory as non-cachable, this function can
+** be ignored.
+**
+** ARGUMENTS:
+**
+** gckOS Os
+** Pointer to gckOS object.
+**
+** gctUINT32 ProcessID
+** Process ID Logical belongs.
+**
+** gctPHYS_ADDR Handle
+** Physical address handle. If gcvNULL it is video memory.
+**
+** gctSIZE_T Offset
+** Offset to this memory block.
+**
+** gctPOINTER Logical
+** Logical address to flush.
+**
+** gctSIZE_T Bytes
+** Size of the address range in bytes to flush.
+*/
+gceSTATUS
+gckOS_CacheInvalidate(
+ IN gckOS Os,
+ IN gctUINT32 ProcessID,
+ IN gctPHYS_ADDR Handle,
+ IN gctSIZE_T Offset,
+ IN gctPOINTER Logical,
+ IN gctSIZE_T Bytes
+ )
+{
+ gceSTATUS status;
+
+ gcmkHEADER_ARG("Os=%p ProcessID=%d Handle=%p Offset=0x%llx Logical=%p Bytes=0x%zx",
+ Os, ProcessID, Handle, Offset, Logical, Bytes);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
+ gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
+ gcmkVERIFY_ARGUMENT(Bytes > 0);
+
+ gcmkONERROR(_CacheOperation(Os, ProcessID,
+ Handle, Offset, Logical, Bytes,
+ gcvCACHE_INVALIDATE));
+
+OnError:
+ gcmkFOOTER();
+ return status;
+}
+
+/*******************************************************************************
+** gckOS_CacheFlush
+**
+** Clean the cache for the specified addresses and invalidate the lines as
+** well. The GPU is going to need and modify the data. If the system is
+** allocating memory as non-cachable, this function can be ignored.
+**
+** ARGUMENTS:
+**
+** gckOS Os
+** Pointer to gckOS object.
+**
+** gctUINT32 ProcessID
+** Process ID Logical belongs.
+**
+** gctPHYS_ADDR Handle
+** Physical address handle. If gcvNULL it is video memory.
+**
+** gctSIZE_T Offset
+** Offset to this memory block.
+**
+** gctPOINTER Logical
+** Logical address to flush.
+**
+** gctSIZE_T Bytes
+** Size of the address range in bytes to flush.
+*/
+gceSTATUS
+gckOS_CacheFlush(
+ IN gckOS Os,
+ IN gctUINT32 ProcessID,
+ IN gctPHYS_ADDR Handle,
+ IN gctSIZE_T Offset,
+ IN gctPOINTER Logical,
+ IN gctSIZE_T Bytes
+ )
+{
+ gceSTATUS status;
+
+ gcmkHEADER_ARG("Os=%p ProcessID=%d Handle=%p Offset=0x%llx Logical=%p Bytes=0x%zx",
+ Os, ProcessID, Handle, Offset, Logical, Bytes);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
+ gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
+ gcmkVERIFY_ARGUMENT(Bytes > 0);
+
+ gcmkONERROR(_CacheOperation(Os, ProcessID,
+ Handle, Offset, Logical, Bytes,
+ gcvCACHE_FLUSH));
+
+OnError:
+ gcmkFOOTER();
+ return status;
+}
+
+/*******************************************************************************
+********************************* Broadcasting *********************************
+*******************************************************************************/
+
+/*******************************************************************************
+**
+** gckOS_Broadcast
+**
+** System hook for broadcast events from the kernel driver.
+**
+** INPUT:
+**
+** gckOS Os
+** Pointer to the gckOS object.
+**
+** gckHARDWARE Hardware
+** Pointer to the gckHARDWARE object.
+**
+** gceBROADCAST Reason
+** Reason for the broadcast. Can be one of the following values:
+**
+** gcvBROADCAST_GPU_IDLE
+** Broadcasted when the kernel driver thinks the GPU might be
+** idle. This can be used to handle power management.
+**
+** gcvBROADCAST_GPU_COMMIT
+** Broadcasted when any client process commits a command
+** buffer. This can be used to handle power management.
+**
+** gcvBROADCAST_GPU_STUCK
+** Broadcasted when the kernel driver hits the timeout waiting
+** for the GPU.
+**
+** gcvBROADCAST_FIRST_PROCESS
+** First process is trying to connect to the kernel.
+**
+** gcvBROADCAST_LAST_PROCESS
+** Last process has detached from the kernel.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckOS_Broadcast(
+ IN gckOS Os,
+ IN gckHARDWARE Hardware,
+ IN gceBROADCAST Reason
+ )
+{
+ gceSTATUS status;
+#if gcdPOWER_SUSPEND_WHEN_IDLE
+ gceCHIPPOWERSTATE state = gcvPOWER_SUSPEND_BROADCAST;
+#else
+ gceCHIPPOWERSTATE state = gcvPOWER_IDLE_BROADCAST;
+#endif
+
+ gcmkHEADER_ARG("Os=0x%X Hardware=0x%X Reason=%d", Os, Hardware, Reason);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
+ gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
+
+ switch (Reason)
+ {
+ case gcvBROADCAST_FIRST_PROCESS:
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_OS, "First process has attached");
+ break;
+
+ case gcvBROADCAST_LAST_PROCESS:
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_OS, "Last process has detached");
+
+ /* Put GPU OFF. */
+ gcmkONERROR(
+ gckHARDWARE_SetPowerManagementState(Hardware,
+ gcvPOWER_OFF_BROADCAST));
+ break;
+
+ case gcvBROADCAST_GPU_IDLE:
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_OS, "GPU idle.");
+
+ /* Put GPU IDLE. */
+ gcmkONERROR(
+ gckHARDWARE_SetPowerManagementState(Hardware, state));
+
+ /* Add idle process DB. */
+ gcmkONERROR(gckKERNEL_AddProcessDB(Hardware->kernel,
+ 1,
+ gcvDB_IDLE,
+ gcvNULL, gcvNULL, 0));
+ break;
+
+ case gcvBROADCAST_GPU_COMMIT:
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_OS, "COMMIT has arrived.");
+
+ /* Add busy process DB. */
+ gcmkONERROR(gckKERNEL_AddProcessDB(Hardware->kernel,
+ 0,
+ gcvDB_IDLE,
+ gcvNULL, gcvNULL, 0));
+
+ /* Put GPU ON. */
+ gcmkONERROR(
+ gckHARDWARE_SetPowerManagementState(Hardware, gcvPOWER_ON_AUTO));
+ break;
+
+ case gcvBROADCAST_GPU_STUCK:
+ gcmkTRACE_N(gcvLEVEL_ERROR, 0, "gcvBROADCAST_GPU_STUCK\n");
+ gcmkONERROR(gckKERNEL_Recovery(Hardware->kernel));
+ break;
+
+ case gcvBROADCAST_AXI_BUS_ERROR:
+ gcmkTRACE_N(gcvLEVEL_ERROR, 0, "gcvBROADCAST_AXI_BUS_ERROR\n");
+ gcmkONERROR(gckHARDWARE_DumpGPUState(Hardware));
+ gcmkONERROR(gckKERNEL_Recovery(Hardware->kernel));
+ break;
+
+ case gcvBROADCAST_OUT_OF_MEMORY:
+ gcmkTRACE_N(gcvLEVEL_INFO, 0, "gcvBROADCAST_OUT_OF_MEMORY\n");
+
+ status = _ShrinkMemory(Os);
+
+ if (status == gcvSTATUS_NOT_SUPPORTED)
+ {
+ goto OnError;
+ }
+
+ gcmkONERROR(status);
+
+ break;
+
+ default:
+ /* Skip unimplemented broadcast. */
+ break;
+ }
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+/*******************************************************************************
+**
+** gckOS_BroadcastHurry
+**
+** The GPU is running too slow.
+**
+** INPUT:
+**
+** gckOS Os
+** Pointer to the gckOS object.
+**
+** gckHARDWARE Hardware
+** Pointer to the gckHARDWARE object.
+**
+** gctUINT Urgency
+** The higher the number, the higher the urgency to speed up the GPU.
+** The maximum value is defined by the gcdDYNAMIC_EVENT_THRESHOLD.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckOS_BroadcastHurry(
+ IN gckOS Os,
+ IN gckHARDWARE Hardware,
+ IN gctUINT Urgency
+ )
+{
+ gcmkHEADER_ARG("Os=0x%x Hardware=0x%x Urgency=%u", Os, Hardware, Urgency);
+
+ /* Do whatever you need to do to speed up the GPU now. */
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+}
+
+/*******************************************************************************
+**
+** gckOS_BroadcastCalibrateSpeed
+**
+** Calibrate the speed of the GPU.
+**
+** INPUT:
+**
+** gckOS Os
+** Pointer to the gckOS object.
+**
+** gckHARDWARE Hardware
+** Pointer to the gckHARDWARE object.
+**
+** gctUINT Idle, Time
+** Idle/Time will give the percentage the GPU is idle, so you can use
+** this to calibrate the working point of the GPU.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckOS_BroadcastCalibrateSpeed(
+ IN gckOS Os,
+ IN gckHARDWARE Hardware,
+ IN gctUINT Idle,
+ IN gctUINT Time
+ )
+{
+ gcmkHEADER_ARG("Os=0x%x Hardware=0x%x Idle=%u Time=%u",
+ Os, Hardware, Idle, Time);
+
+ /* Do whatever you need to do to callibrate the GPU speed. */
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+}
+
+/*******************************************************************************
+********************************** Semaphores **********************************
+*******************************************************************************/
+
+/*******************************************************************************
+**
+** gckOS_CreateSemaphore
+**
+** Create a semaphore.
+**
+** INPUT:
+**
+** gckOS Os
+** Pointer to the gckOS object.
+**
+** OUTPUT:
+**
+** gctPOINTER * Semaphore
+** Pointer to the variable that will receive the created semaphore.
+*/
+gceSTATUS
+gckOS_CreateSemaphore(
+ IN gckOS Os,
+ OUT gctPOINTER * Semaphore
+ )
+{
+ gceSTATUS status;
+ struct semaphore *sem = gcvNULL;
+
+ gcmkHEADER_ARG("Os=0x%X", Os);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
+ gcmkVERIFY_ARGUMENT(Semaphore != gcvNULL);
+
+ /* Allocate the semaphore structure. */
+ sem = (struct semaphore *)kmalloc(gcmSIZEOF(struct semaphore), GFP_KERNEL | gcdNOWARN);
+ if (sem == gcvNULL)
+ {
+ gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
+ }
+
+ /* Initialize the semaphore. */
+ sema_init(sem, 1);
+
+ /* Return to caller. */
+ *Semaphore = (gctPOINTER) sem;
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+/*******************************************************************************
+**
+** gckOS_AcquireSemaphore
+**
+** Acquire a semaphore.
+**
+** INPUT:
+**
+** gckOS Os
+** Pointer to the gckOS object.
+**
+** gctPOINTER Semaphore
+** Pointer to the semaphore thet needs to be acquired.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckOS_AcquireSemaphore(
+ IN gckOS Os,
+ IN gctPOINTER Semaphore
+ )
+{
+ gcmkHEADER_ARG("Os=0x%08X Semaphore=0x%08X", Os, Semaphore);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
+ gcmkVERIFY_ARGUMENT(Semaphore != gcvNULL);
+
+ /* Acquire the semaphore. */
+ down((struct semaphore *) Semaphore);
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+}
+
+/*******************************************************************************
+**
+** gckOS_TryAcquireSemaphore
+**
+** Try to acquire a semaphore.
+**
+** INPUT:
+**
+** gckOS Os
+** Pointer to the gckOS object.
+**
+** gctPOINTER Semaphore
+** Pointer to the semaphore thet needs to be acquired.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckOS_TryAcquireSemaphore(
+ IN gckOS Os,
+ IN gctPOINTER Semaphore
+ )
+{
+ gceSTATUS status;
+
+ gcmkHEADER_ARG("Os=0x%x", Os);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
+ gcmkVERIFY_ARGUMENT(Semaphore != gcvNULL);
+
+ /* Acquire the semaphore. */
+ if (down_trylock((struct semaphore *) Semaphore))
+ {
+ /* Timeout. */
+ status = gcvSTATUS_TIMEOUT;
+ gcmkFOOTER();
+ return status;
+ }
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+}
+
+/*******************************************************************************
+**
+** gckOS_ReleaseSemaphore
+**
+** Release a previously acquired semaphore.
+**
+** INPUT:
+**
+** gckOS Os
+** Pointer to the gckOS object.
+**
+** gctPOINTER Semaphore
+** Pointer to the semaphore thet needs to be released.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckOS_ReleaseSemaphore(
+ IN gckOS Os,
+ IN gctPOINTER Semaphore
+ )
+{
+ gcmkHEADER_ARG("Os=0x%X Semaphore=0x%X", Os, Semaphore);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
+ gcmkVERIFY_ARGUMENT(Semaphore != gcvNULL);
+
+ /* Release the semaphore. */
+ up((struct semaphore *) Semaphore);
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+}
+
+/*******************************************************************************
+**
+** gckOS_DestroySemaphore
+**
+** Destroy a semaphore.
+**
+** INPUT:
+**
+** gckOS Os
+** Pointer to the gckOS object.
+**
+** gctPOINTER Semaphore
+** Pointer to the semaphore thet needs to be destroyed.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckOS_DestroySemaphore(
+ IN gckOS Os,
+ IN gctPOINTER Semaphore
+ )
+{
+ gcmkHEADER_ARG("Os=0x%X Semaphore=0x%X", Os, Semaphore);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
+ gcmkVERIFY_ARGUMENT(Semaphore != gcvNULL);
+
+ /* Free the sempahore structure. */
+ kfree(Semaphore);
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+}
+
+/*******************************************************************************
+**
+** gckOS_GetProcessID
+**
+** Get current process ID.
+**
+** INPUT:
+**
+** Nothing.
+**
+** OUTPUT:
+**
+** gctUINT32_PTR ProcessID
+** Pointer to the variable that receives the process ID.
+*/
+gceSTATUS
+gckOS_GetProcessID(
+ OUT gctUINT32_PTR ProcessID
+ )
+{
+ /* Get process ID. */
+ *ProcessID = _GetProcessID();
+
+ /* Success. */
+ return gcvSTATUS_OK;
+}
+
+/*******************************************************************************
+**
+** gckOS_GetThreadID
+**
+** Get current thread ID.
+**
+** INPUT:
+**
+** Nothing.
+**
+** OUTPUT:
+**
+** gctUINT32_PTR ThreadID
+** Pointer to the variable that receives the thread ID.
+*/
+gceSTATUS
+gckOS_GetThreadID(
+ OUT gctUINT32_PTR ThreadID
+ )
+{
+ /* Get thread ID. */
+ if (ThreadID != gcvNULL)
+ {
+ *ThreadID = _GetThreadID();
+ }
+
+ /* Success. */
+ return gcvSTATUS_OK;
+}
+
+/*******************************************************************************
+**
+** gckOS_SetGPUPower
+**
+** Set the power of the GPU on or off.
+**
+** INPUT:
+**
+** gckOS Os
+** Pointer to a gckOS object.
+**
+** gceCORE Core
+** GPU whose power is set.
+**
+** gctBOOL Clock
+** gcvTRUE to turn on the clock, or gcvFALSE to turn off the clock.
+**
+** gctBOOL Power
+** gcvTRUE to turn on the power, or gcvFALSE to turn off the power.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckOS_SetGPUPower(
+ IN gckOS Os,
+ IN gceCORE Core,
+ IN gctBOOL Clock,
+ IN gctBOOL Power
+ )
+{
+ gcsPLATFORM * platform;
+
+ gctBOOL powerChange = gcvFALSE;
+ gctBOOL clockChange = gcvFALSE;
+
+ gcmkHEADER_ARG("Os=0x%X Core=%d Clock=%d Power=%d", Os, Core, Clock, Power);
+ gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
+
+ platform = Os->device->platform;
+
+ powerChange = (Power != Os->powerStates[Core]);
+
+ clockChange = (Clock != Os->clockStates[Core]);
+
+ if (powerChange && (Power == gcvTRUE))
+ {
+ if (platform && platform->ops->setPower)
+ {
+ gcmkVERIFY_OK(platform->ops->setPower(platform, Core, Power));
+ }
+
+ Os->powerStates[Core] = Power;
+ }
+
+ if (clockChange)
+ {
+ unsigned long flags;
+
+ if (!Clock)
+ {
+ spin_lock_irqsave(&Os->registerAccessLock, flags);
+
+ /* Record clock off, ahead. */
+ Os->clockStates[Core] = gcvFALSE;
+
+ spin_unlock_irqrestore(&Os->registerAccessLock, flags);
+ }
+
+ if (platform && platform->ops->setClock)
+ {
+ gcmkVERIFY_OK(platform->ops->setClock(platform, Core, Clock));
+ }
+
+ if (Clock)
+ {
+ spin_lock_irqsave(&Os->registerAccessLock, flags);
+
+ /* Record clock on, behind. */
+ Os->clockStates[Core] = gcvTRUE;
+
+ spin_unlock_irqrestore(&Os->registerAccessLock, flags);
+ }
+ }
+
+ if (powerChange && (Power == gcvFALSE))
+ {
+ if (platform && platform->ops->setPower)
+ {
+ gcmkVERIFY_OK(platform->ops->setPower(platform, Core, Power));
+ }
+
+ Os->powerStates[Core] = Power;
+ }
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+}
+
+/*******************************************************************************
+**
+** gckOS_ResetGPU
+**
+** Reset the GPU.
+**
+** INPUT:
+**
+** gckOS Os
+** Pointer to a gckOS object.
+**
+** gckCORE Core
+** GPU whose power is set.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckOS_ResetGPU(
+ IN gckOS Os,
+ IN gceCORE Core
+ )
+{
+ gceSTATUS status = gcvSTATUS_NOT_SUPPORTED;
+ gcsPLATFORM * platform;
+
+ gcmkHEADER_ARG("Os=0x%X Core=%d", Os, Core);
+ gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
+
+ platform = Os->device->platform;
+
+ if (platform && platform->ops->reset)
+ {
+ status = platform->ops->reset(platform, Core);
+ }
+
+ gcmkFOOTER_NO();
+ return status;
+}
+
+/*******************************************************************************
+**
+** gckOS_PrepareGPUFrequency
+**
+** Prepare to set GPU frequency and voltage.
+**
+** INPUT:
+**
+** gckOS Os
+** Pointer to a gckOS object.
+**
+** gckCORE Core
+** GPU whose frequency and voltage will be set.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckOS_PrepareGPUFrequency(
+ IN gckOS Os,
+ IN gceCORE Core
+ )
+{
+ return gcvSTATUS_OK;
+}
+
+/*******************************************************************************
+**
+** gckOS_FinishGPUFrequency
+**
+** Finish GPU frequency setting.
+**
+** INPUT:
+**
+** gckOS Os
+** Pointer to a gckOS object.
+**
+** gckCORE Core
+** GPU whose frequency and voltage is set.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckOS_FinishGPUFrequency(
+ IN gckOS Os,
+ IN gceCORE Core
+ )
+{
+ return gcvSTATUS_OK;
+}
+
+/*******************************************************************************
+**
+** gckOS_QueryGPUFrequency
+**
+** Query the current frequency of the GPU.
+**
+** INPUT:
+**
+** gckOS Os
+** Pointer to a gckOS object.
+**
+** gckCORE Core
+** GPU whose power is set.
+**
+** gctUINT32 * Frequency
+** Pointer to a gctUINT32 to obtain current frequency, in MHz.
+**
+** gctUINT8 * Scale
+** Pointer to a gctUINT8 to obtain current scale(1 - 64).
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckOS_QueryGPUFrequency(
+ IN gckOS Os,
+ IN gceCORE Core,
+ OUT gctUINT32 * Frequency,
+ OUT gctUINT8 * Scale
+ )
+{
+ return gcvSTATUS_OK;
+}
+
+/*******************************************************************************
+**
+** gckOS_SetGPUFrequency
+**
+** Set frequency and voltage of the GPU.
+**
+** 1. DVFS manager gives the target scale of full frequency, BSP must find
+** a real frequency according to this scale and board's configure.
+**
+** 2. BSP should find a suitable voltage for this frequency.
+**
+** 3. BSP must make sure setting take effect before this function returns.
+**
+** INPUT:
+**
+** gckOS Os
+** Pointer to a gckOS object.
+**
+** gckCORE Core
+** GPU whose power is set.
+**
+** gctUINT8 Scale
+** Target scale of full frequency, range is [1, 64]. 1 means 1/64 of
+** full frequency and 64 means 64/64 of full frequency.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckOS_SetGPUFrequency(
+ IN gckOS Os,
+ IN gceCORE Core,
+ IN gctUINT8 Scale
+ )
+{
+ return gcvSTATUS_OK;
+}
+
+/*----------------------------------------------------------------------------*/
+/*----- Profile --------------------------------------------------------------*/
+
+gceSTATUS
+gckOS_GetProfileTick(
+ OUT gctUINT64_PTR Tick
+ )
+{
+ struct timespec time;
+
+ ktime_get_ts(&time);
+
+ *Tick = time.tv_nsec + time.tv_sec * 1000000000ULL;
+
+ return gcvSTATUS_OK;
+}
+
+gceSTATUS
+gckOS_QueryProfileTickRate(
+ OUT gctUINT64_PTR TickRate
+ )
+{
+ struct timespec res;
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0)
+ res.tv_sec = 0;
+ res.tv_nsec = hrtimer_resolution;
+#else
+ hrtimer_get_res(CLOCK_MONOTONIC, &res);
+#endif
+
+ *TickRate = res.tv_nsec + res.tv_sec * 1000000000ULL;
+
+ return gcvSTATUS_OK;
+}
+
+gctUINT32
+gckOS_ProfileToMS(
+ IN gctUINT64 Ticks
+ )
+{
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,23)
+ return div_u64(Ticks, 1000000);
+#else
+ gctUINT64 rem = Ticks;
+ gctUINT64 b = 1000000;
+ gctUINT64 res, d = 1;
+ gctUINT32 high = rem >> 32;
+
+ /* Reduce the thing a bit first */
+ res = 0;
+ if (high >= 1000000)
+ {
+ high /= 1000000;
+ res = (gctUINT64) high << 32;
+ rem -= (gctUINT64) (high * 1000000) << 32;
+ }
+
+ while (((gctINT64) b > 0) && (b < rem))
+ {
+ b <<= 1;
+ d <<= 1;
+ }
+
+ do
+ {
+ if (rem >= b)
+ {
+ rem -= b;
+ res += d;
+ }
+
+ b >>= 1;
+ d >>= 1;
+ }
+ while (d);
+
+ return (gctUINT32) res;
+#endif
+}
+
+/******************************************************************************\
+******************************* Signal Management ******************************
+\******************************************************************************/
+
+#undef _GC_OBJ_ZONE
+#define _GC_OBJ_ZONE gcvZONE_SIGNAL
+
+/*******************************************************************************
+**
+** gckOS_CreateSignal
+**
+** Create a new signal.
+**
+** INPUT:
+**
+** gckOS Os
+** Pointer to an gckOS object.
+**
+** gctBOOL ManualReset
+** If set to gcvTRUE, gckOS_Signal with gcvFALSE must be called in
+** order to set the signal to nonsignaled state.
+** If set to gcvFALSE, the signal will automatically be set to
+** nonsignaled state by gckOS_WaitSignal function.
+**
+** OUTPUT:
+**
+** gctSIGNAL * Signal
+** Pointer to a variable receiving the created gctSIGNAL.
+*/
+gceSTATUS
+gckOS_CreateSignal(
+ IN gckOS Os,
+ IN gctBOOL ManualReset,
+ OUT gctSIGNAL * Signal
+ )
+{
+ gceSTATUS status;
+ gcsSIGNAL_PTR signal;
+
+ gcmkHEADER_ARG("Os=0x%X ManualReset=%d", Os, ManualReset);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
+ gcmkVERIFY_ARGUMENT(Signal != gcvNULL);
+
+ /* Create an event structure. */
+ signal = (gcsSIGNAL_PTR) kmalloc(sizeof(gcsSIGNAL), GFP_KERNEL | gcdNOWARN);
+
+ if (signal == gcvNULL)
+ {
+ gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
+ }
+
+ /* Save the process ID. */
+ signal->process = (gctHANDLE)(gctUINTPTR_T) _GetProcessID();
+
+ signal->done = 0;
+ init_waitqueue_head(&signal->wait);
+ spin_lock_init(&signal->lock);
+ signal->manualReset = ManualReset;
+
+ atomic_set(&signal->ref, 1);
+
+#if gcdLINUX_SYNC_FILE
+#ifndef CONFIG_SYNC_FILE
+ signal->timeline = gcvNULL;
+# else
+ signal->fence = gcvNULL;
+# endif
+#endif
+
+ gcmkONERROR(_AllocateIntegerId(&Os->signalDB, signal, &signal->id));
+
+ *Signal = (gctSIGNAL)(gctUINTPTR_T)signal->id;
+
+ gcmkFOOTER_ARG("*Signal=0x%X", *Signal);
+ return gcvSTATUS_OK;
+
+OnError:
+ if (signal != gcvNULL)
+ {
+ kfree(signal);
+ }
+
+ gcmkFOOTER_NO();
+ return status;
+}
+
+/*******************************************************************************
+**
+** gckOS_DestroySignal
+**
+** Destroy a signal.
+**
+** INPUT:
+**
+** gckOS Os
+** Pointer to an gckOS object.
+**
+** gctSIGNAL Signal
+** Pointer to the gctSIGNAL.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckOS_DestroySignal(
+ IN gckOS Os,
+ IN gctSIGNAL Signal
+ )
+{
+ gceSTATUS status;
+ gcsSIGNAL_PTR signal;
+ gctBOOL acquired = gcvFALSE;
+ unsigned long flags = 0;
+
+ gcmkHEADER_ARG("Os=0x%X Signal=0x%X", Os, Signal);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
+ gcmkVERIFY_ARGUMENT(Signal != gcvNULL);
+
+ if(in_irq()){
+ spin_lock(&Os->signalLock);
+ }else{
+ spin_lock_irqsave(&Os->signalLock, flags);
+ }
+ acquired = gcvTRUE;
+
+ gcmkONERROR(_QueryIntegerId(&Os->signalDB, (gctUINT32)(gctUINTPTR_T)Signal, (gctPOINTER)&signal));
+
+ gcmkASSERT(signal->id == (gctUINT32)(gctUINTPTR_T)Signal);
+
+ if (atomic_dec_and_test(&signal->ref))
+ {
+ gcmkVERIFY_OK(_DestroyIntegerId(&Os->signalDB, signal->id));
+
+ /* Free the sgianl. */
+ kfree(signal);
+ }
+
+ if(in_irq()){
+ spin_unlock(&Os->signalLock);
+ }else{
+ spin_unlock_irqrestore(&Os->signalLock, flags);
+ }
+
+ acquired = gcvFALSE;
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ if (acquired)
+ {
+ /* Release the mutex. */
+ if(in_irq()){
+ spin_unlock(&Os->signalLock);
+ }else{
+ spin_unlock_irqrestore(&Os->signalLock, flags);
+ }
+
+ }
+
+ gcmkFOOTER();
+ return status;
+}
+
+/*******************************************************************************
+**
+** gckOS_Signal
+**
+** Set a state of the specified signal.
+**
+** INPUT:
+**
+** gckOS Os
+** Pointer to an gckOS object.
+**
+** gctSIGNAL Signal
+** Pointer to the gctSIGNAL.
+**
+** gctBOOL State
+** If gcvTRUE, the signal will be set to signaled state.
+** If gcvFALSE, the signal will be set to nonsignaled state.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckOS_Signal(
+ IN gckOS Os,
+ IN gctSIGNAL Signal,
+ IN gctBOOL State
+ )
+{
+ gceSTATUS status;
+ gcsSIGNAL_PTR signal;
+#if gcdLINUX_SYNC_FILE
+#ifndef CONFIG_SYNC_FILE
+ struct sync_timeline * timeline = gcvNULL;
+# else
+ struct dma_fence * fence = gcvNULL;
+# endif
+#endif
+ unsigned long flags = 0;
+
+ gcmkHEADER_ARG("Os=0x%X Signal=0x%X State=%d", Os, Signal, State);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
+ gcmkVERIFY_ARGUMENT(Signal != gcvNULL);
+
+ spin_lock_irqsave(&Os->signalLock, flags);
+
+ status = _QueryIntegerId(&Os->signalDB,
+ (gctUINT32)(gctUINTPTR_T)Signal,
+ (gctPOINTER)&signal);
+
+ if (gcmIS_ERROR(status))
+ {
+ spin_unlock_irqrestore(&Os->signalLock, flags);
+ gcmkONERROR(status);
+ }
+
+ /*
+ * Signal saved in event is not referenced. Inc reference here to avoid
+ * concurrent issue: signaling the signal while another thread is destroying
+ * it.
+ */
+ atomic_inc(&signal->ref);
+
+ spin_unlock_irqrestore(&Os->signalLock, flags);
+
+ gcmkONERROR(status);
+
+ gcmkASSERT(signal->id == (gctUINT32)(gctUINTPTR_T)Signal);
+
+ spin_lock(&signal->lock);
+
+ if (State)
+ {
+ signal->done = 1;
+
+ wake_up(&signal->wait);
+
+#if gcdLINUX_SYNC_FILE
+#ifndef CONFIG_SYNC_FILE
+ timeline = signal->timeline;
+# else
+ fence = signal->fence;
+ signal->fence = NULL;
+# endif
+#endif
+ }
+ else
+ {
+ signal->done = 0;
+ }
+
+ spin_unlock(&signal->lock);
+
+#if gcdLINUX_SYNC_FILE
+#ifndef CONFIG_SYNC_FILE
+ /* Signal timeline. */
+ if (timeline)
+ {
+ sync_timeline_signal(timeline);
+ }
+# else
+ if (fence)
+ {
+ dma_fence_signal(fence);
+ dma_fence_put(fence);
+ }
+# endif
+#endif
+
+ spin_lock_irqsave(&Os->signalLock, flags);
+
+ if (atomic_dec_and_test(&signal->ref))
+ {
+ gcmkVERIFY_OK(_DestroyIntegerId(&Os->signalDB, signal->id));
+
+ /* Free the sgianl. */
+ kfree(signal);
+ }
+
+ spin_unlock_irqrestore(&Os->signalLock, flags);
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ gcmkFOOTER();
+ return status;
+}
+
+/*******************************************************************************
+**
+** gckOS_UserSignal
+**
+** Set the specified signal which is owned by a process to signaled state.
+**
+** INPUT:
+**
+** gckOS Os
+** Pointer to an gckOS object.
+**
+** gctSIGNAL Signal
+** Pointer to the gctSIGNAL.
+**
+** gctHANDLE Process
+** Handle of process owning the signal.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckOS_UserSignal(
+ IN gckOS Os,
+ IN gctSIGNAL Signal,
+ IN gctHANDLE Process
+ )
+{
+ gceSTATUS status;
+
+ gcmkHEADER_ARG("Os=0x%X Signal=0x%X Process=%d",
+ Os, Signal, (gctINT32)(gctUINTPTR_T)Process);
+
+ /* Signal. */
+ status = gckOS_Signal(Os, Signal, gcvTRUE);
+
+ gcmkFOOTER();
+ return status;
+}
+
+/*******************************************************************************
+**
+** gckOS_WaitSignal
+**
+** Wait for a signal to become signaled.
+**
+** INPUT:
+**
+** gckOS Os
+** Pointer to an gckOS object.
+**
+** gctSIGNAL Signal
+** Pointer to the gctSIGNAL.
+**
+** gctUINT32 Wait
+** Number of milliseconds to wait.
+** Pass the value of gcvINFINITE for an infinite wait.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckOS_WaitSignal(
+ IN gckOS Os,
+ IN gctSIGNAL Signal,
+ IN gctBOOL Interruptable,
+ IN gctUINT32 Wait
+ )
+{
+ gceSTATUS status;
+ gcsSIGNAL_PTR signal = gcvNULL;
+ int done;
+
+ gcmkHEADER_ARG("Os=0x%X Signal=0x%X Wait=0x%08X", Os, Signal, Wait);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
+ gcmkVERIFY_ARGUMENT(Signal != gcvNULL);
+
+ gcmkONERROR(_QueryIntegerId(&Os->signalDB, (gctUINT32)(gctUINTPTR_T)Signal, (gctPOINTER)&signal));
+
+ gcmkASSERT(signal->id == (gctUINT32)(gctUINTPTR_T)Signal);
+
+ spin_lock(&signal->lock);
+ done = signal->done;
+ spin_unlock(&signal->lock);
+
+ /*
+ * Do not need to lock below:
+ * 1. If signal already done, return immediately.
+ * 2. If signal not done, wait_event_xxx will handle correctly even read of
+ * signal->done is not atomic.
+ *
+ * Rest signal->done do not require lock either:
+ * No other thread can query/wait auto-reseted signal, because that is
+ * logic error.
+ */
+ if (done)
+ {
+ status = gcvSTATUS_OK;
+
+ if (!signal->manualReset)
+ {
+ signal->done = 0;
+ }
+ }
+ else if (Wait == 0)
+ {
+ status = gcvSTATUS_TIMEOUT;
+ }
+ else
+ {
+ /* Convert wait to milliseconds. */
+ long timeout = (Wait == gcvINFINITE)
+ ? MAX_SCHEDULE_TIMEOUT
+ : msecs_to_jiffies(Wait);
+
+ long ret;
+
+ if (Interruptable)
+ {
+ ret = wait_event_interruptible_timeout(signal->wait, signal->done, timeout);
+ }
+ else
+ {
+ ret = wait_event_timeout(signal->wait, signal->done, timeout);
+ }
+
+ if (likely(ret > 0))
+ {
+ status = gcvSTATUS_OK;
+
+ if (!signal->manualReset)
+ {
+ /* Auto reset. */
+ signal->done = 0;
+ }
+ }
+ else
+ {
+ status = (ret == -ERESTARTSYS) ? gcvSTATUS_INTERRUPTED
+ : gcvSTATUS_TIMEOUT;
+ }
+ }
+
+OnError:
+ /* Return status. */
+ gcmkFOOTER_ARG("Signal=0x%lX status=%d", Signal, status);
+ return status;
+}
+
+gceSTATUS
+_QuerySignal(
+ IN gckOS Os,
+ IN gctSIGNAL Signal
+ )
+{
+ /*
+ * This function is called by 'has_signaled' callback of sync_timeline.
+ * By design, 'has_signaled' could be called in interrupt context, but
+ * in current driver, it can be called only when 'gckOS_Signal' and
+ * 'gckOS_CreateNativeFence'. Thus its safe to use normal version of
+ * spinlock for 'Os->signalDB.lock' and 'signal->obj.wait.lock'.
+ */
+ gceSTATUS status;
+ gcsSIGNAL_PTR signal = gcvNULL;
+
+ status = _QueryIntegerId(&Os->signalDB,
+ (gctUINT32)(gctUINTPTR_T)Signal,
+ (gctPOINTER)&signal);
+
+ if (gcmIS_SUCCESS(status))
+ {
+ spin_lock(&signal->lock);
+ status = signal->done ? gcvSTATUS_TRUE : gcvSTATUS_FALSE;
+ spin_unlock(&signal->lock);
+ }
+
+ return status;
+}
+
+/*******************************************************************************
+**
+** gckOS_MapSignal
+**
+** Map a signal in to the current process space.
+**
+** INPUT:
+**
+** gckOS Os
+** Pointer to an gckOS object.
+**
+** gctSIGNAL Signal
+** Pointer to tha gctSIGNAL to map.
+**
+** gctHANDLE Process
+** Handle of process owning the signal.
+**
+** OUTPUT:
+**
+** gctSIGNAL * MappedSignal
+** Pointer to a variable receiving the mapped gctSIGNAL.
+*/
+gceSTATUS
+gckOS_MapSignal(
+ IN gckOS Os,
+ IN gctSIGNAL Signal,
+ IN gctHANDLE Process,
+ OUT gctSIGNAL * MappedSignal
+ )
+{
+ gceSTATUS status;
+ gcsSIGNAL_PTR signal = gcvNULL;
+ unsigned long flags = 0;
+ gcmkHEADER_ARG("Os=0x%X Signal=0x%X Process=0x%X", Os, Signal, Process);
+
+ gcmkVERIFY_ARGUMENT(Signal != gcvNULL);
+ gcmkVERIFY_ARGUMENT(MappedSignal != gcvNULL);
+
+ spin_lock_irqsave(&Os->signalLock, flags);
+
+ gcmkONERROR(_QueryIntegerId(&Os->signalDB, (gctUINT32)(gctUINTPTR_T)Signal, (gctPOINTER)&signal));
+
+ if (atomic_inc_return(&signal->ref) <= 1)
+ {
+ /* The previous value is 0, it has been deleted. */
+ gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
+ }
+
+ *MappedSignal = (gctSIGNAL) Signal;
+
+ spin_unlock_irqrestore(&Os->signalLock, flags);
+
+ /* Success. */
+ gcmkFOOTER_ARG("*MappedSignal=0x%X", *MappedSignal);
+ return gcvSTATUS_OK;
+
+OnError:
+ spin_unlock_irqrestore(&Os->signalLock, flags);
+
+ gcmkFOOTER_NO();
+ return status;
+}
+
+/*******************************************************************************
+**
+** gckOS_UnmapSignal
+**
+** Unmap a signal .
+**
+** INPUT:
+**
+** gckOS Os
+** Pointer to an gckOS object.
+**
+** gctSIGNAL Signal
+** Pointer to that gctSIGNAL mapped.
+*/
+gceSTATUS
+gckOS_UnmapSignal(
+ IN gckOS Os,
+ IN gctSIGNAL Signal
+ )
+{
+ return gckOS_DestroySignal(Os, Signal);
+}
+
+/*******************************************************************************
+**
+** gckOS_CreateUserSignal
+**
+** Create a new signal to be used in the user space.
+**
+** INPUT:
+**
+** gckOS Os
+** Pointer to an gckOS object.
+**
+** gctBOOL ManualReset
+** If set to gcvTRUE, gckOS_Signal with gcvFALSE must be called in
+** order to set the signal to nonsignaled state.
+** If set to gcvFALSE, the signal will automatically be set to
+** nonsignaled state by gckOS_WaitSignal function.
+**
+** OUTPUT:
+**
+** gctINT * SignalID
+** Pointer to a variable receiving the created signal's ID.
+*/
+gceSTATUS
+gckOS_CreateUserSignal(
+ IN gckOS Os,
+ IN gctBOOL ManualReset,
+ OUT gctINT * SignalID
+ )
+{
+ gceSTATUS status;
+ gctSIZE_T signal;
+
+ /* Create a new signal. */
+ gcmkONERROR(gckOS_CreateSignal(Os, ManualReset, (gctSIGNAL *) &signal));
+ *SignalID = (gctINT) signal;
+
+OnError:
+ return status;
+}
+
+/*******************************************************************************
+**
+** gckOS_DestroyUserSignal
+**
+** Destroy a signal to be used in the user space.
+**
+** INPUT:
+**
+** gckOS Os
+** Pointer to an gckOS object.
+**
+** gctINT SignalID
+** The signal's ID.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckOS_DestroyUserSignal(
+ IN gckOS Os,
+ IN gctINT SignalID
+ )
+{
+ return gckOS_DestroySignal(Os, (gctSIGNAL)(gctUINTPTR_T)SignalID);
+}
+
+/*******************************************************************************
+**
+** gckOS_WaitUserSignal
+**
+** Wait for a signal used in the user mode to become signaled.
+**
+** INPUT:
+**
+** gckOS Os
+** Pointer to an gckOS object.
+**
+** gctINT SignalID
+** Signal ID.
+**
+** gctUINT32 Wait
+** Number of milliseconds to wait.
+** Pass the value of gcvINFINITE for an infinite wait.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckOS_WaitUserSignal(
+ IN gckOS Os,
+ IN gctINT SignalID,
+ IN gctUINT32 Wait
+ )
+{
+ return gckOS_WaitSignal(Os, (gctSIGNAL)(gctUINTPTR_T)SignalID, gcvTRUE, Wait);
+}
+
+/*******************************************************************************
+**
+** gckOS_SignalUserSignal
+**
+** Set a state of the specified signal to be used in the user space.
+**
+** INPUT:
+**
+** gckOS Os
+** Pointer to an gckOS object.
+**
+** gctINT SignalID
+** SignalID.
+**
+** gctBOOL State
+** If gcvTRUE, the signal will be set to signaled state.
+** If gcvFALSE, the signal will be set to nonsignaled state.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckOS_SignalUserSignal(
+ IN gckOS Os,
+ IN gctINT SignalID,
+ IN gctBOOL State
+ )
+{
+ return gckOS_Signal(Os, (gctSIGNAL)(gctUINTPTR_T)SignalID, State);
+}
+
+#if gcdENABLE_VG
+gceSTATUS
+gckOS_CreateSemaphoreVG(
+ IN gckOS Os,
+ OUT gctSEMAPHORE * Semaphore
+ )
+{
+ gceSTATUS status;
+ struct semaphore * newSemaphore;
+
+ gcmkHEADER_ARG("Os=0x%X Semaphore=0x%x", Os, Semaphore);
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
+ gcmkVERIFY_ARGUMENT(Semaphore != gcvNULL);
+
+ do
+ {
+ /* Allocate the semaphore structure. */
+ newSemaphore = (struct semaphore *)kmalloc(gcmSIZEOF(struct semaphore), GFP_KERNEL | gcdNOWARN);
+ if (newSemaphore == gcvNULL)
+ {
+ gcmkERR_BREAK(gcvSTATUS_OUT_OF_MEMORY);
+ }
+
+ /* Initialize the semaphore. */
+ sema_init(newSemaphore, 0);
+
+ /* Set the handle. */
+ * Semaphore = (gctSEMAPHORE) newSemaphore;
+
+ /* Success. */
+ status = gcvSTATUS_OK;
+ }
+ while (gcvFALSE);
+
+ gcmkFOOTER();
+ /* Return the status. */
+ return status;
+}
+
+
+gceSTATUS
+gckOS_IncrementSemaphore(
+ IN gckOS Os,
+ IN gctSEMAPHORE Semaphore
+ )
+{
+ gcmkHEADER_ARG("Os=0x%X Semaphore=0x%x", Os, Semaphore);
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
+ gcmkVERIFY_ARGUMENT(Semaphore != gcvNULL);
+
+ /* Increment the semaphore's count. */
+ up((struct semaphore *) Semaphore);
+
+ gcmkFOOTER_NO();
+ /* Success. */
+ return gcvSTATUS_OK;
+}
+
+gceSTATUS
+gckOS_DecrementSemaphore(
+ IN gckOS Os,
+ IN gctSEMAPHORE Semaphore
+ )
+{
+ gceSTATUS status;
+ gctINT result;
+
+ gcmkHEADER_ARG("Os=0x%X Semaphore=0x%x", Os, Semaphore);
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
+ gcmkVERIFY_ARGUMENT(Semaphore != gcvNULL);
+
+ do
+ {
+ /* Decrement the semaphore's count. If the count is zero, wait
+ until it gets incremented. */
+ result = down_interruptible((struct semaphore *) Semaphore);
+
+ /* Signal received? */
+ if (result != 0)
+ {
+ status = gcvSTATUS_TERMINATE;
+ break;
+ }
+
+ /* Success. */
+ status = gcvSTATUS_OK;
+ }
+ while (gcvFALSE);
+
+ gcmkFOOTER();
+ /* Return the status. */
+ return status;
+}
+
+/******************************************************************************\
+******************************** Thread Object *********************************
+\******************************************************************************/
+
+gceSTATUS
+gckOS_StartThread(
+ IN gckOS Os,
+ IN gctTHREADFUNC ThreadFunction,
+ IN gctPOINTER ThreadParameter,
+ OUT gctTHREAD * Thread
+ )
+{
+ gceSTATUS status;
+ struct task_struct * thread;
+
+ gcmkHEADER_ARG("Os=0x%X ", Os);
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
+ gcmkVERIFY_ARGUMENT(ThreadFunction != gcvNULL);
+ gcmkVERIFY_ARGUMENT(Thread != gcvNULL);
+
+ do
+ {
+ /* Create the thread. */
+ thread = kthread_create(
+ ThreadFunction,
+ ThreadParameter,
+ "Vivante Kernel Thread"
+ );
+
+ /* Failed? */
+ if (IS_ERR(thread))
+ {
+ status = gcvSTATUS_GENERIC_IO;
+ break;
+ }
+
+ /* Start the thread. */
+ wake_up_process(thread);
+
+ /* Set the thread handle. */
+ * Thread = (gctTHREAD) thread;
+
+ /* Success. */
+ status = gcvSTATUS_OK;
+ }
+ while (gcvFALSE);
+
+ gcmkFOOTER();
+ /* Return the status. */
+ return status;
+}
+
+gceSTATUS
+gckOS_StopThread(
+ IN gckOS Os,
+ IN gctTHREAD Thread
+ )
+{
+ gcmkHEADER_ARG("Os=0x%X Thread=0x%x", Os, Thread);
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
+ gcmkVERIFY_ARGUMENT(Thread != gcvNULL);
+
+ /* Thread should have already been enabled to terminate. */
+ kthread_stop((struct task_struct *) Thread);
+
+ gcmkFOOTER_NO();
+ /* Success. */
+ return gcvSTATUS_OK;
+}
+
+gceSTATUS
+gckOS_VerifyThread(
+ IN gckOS Os,
+ IN gctTHREAD Thread
+ )
+{
+ gcmkHEADER_ARG("Os=0x%X Thread=0x%x", Os, Thread);
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
+ gcmkVERIFY_ARGUMENT(Thread != gcvNULL);
+
+ gcmkFOOTER_NO();
+ /* Success. */
+ return gcvSTATUS_OK;
+}
+#endif
+
+/******************************************************************************\
+******************************** Software Timer ********************************
+\******************************************************************************/
+
+void
+_TimerFunction(
+ struct work_struct * work
+ )
+{
+ gcsOSTIMER_PTR timer = (gcsOSTIMER_PTR)work;
+
+ gctTIMERFUNCTION function = timer->function;
+
+ function(timer->data);
+}
+
+/*******************************************************************************
+**
+** gckOS_CreateTimer
+**
+** Create a software timer.
+**
+** INPUT:
+**
+** gckOS Os
+** Pointer to the gckOS object.
+**
+** gctTIMERFUNCTION Function.
+** Pointer to a call back function which will be called when timer is
+** expired.
+**
+** gctPOINTER Data.
+** Private data which will be passed to call back function.
+**
+** OUTPUT:
+**
+** gctPOINTER * Timer
+** Pointer to a variable receiving the created timer.
+*/
+gceSTATUS
+gckOS_CreateTimer(
+ IN gckOS Os,
+ IN gctTIMERFUNCTION Function,
+ IN gctPOINTER Data,
+ OUT gctPOINTER * Timer
+ )
+{
+ gceSTATUS status;
+ gcsOSTIMER_PTR pointer;
+ gcmkHEADER_ARG("Os=0x%X Function=0x%X Data=0x%X", Os, Function, Data);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
+ gcmkVERIFY_ARGUMENT(Timer != gcvNULL);
+
+ gcmkONERROR(gckOS_Allocate(Os, sizeof(gcsOSTIMER), (gctPOINTER)&pointer));
+
+ pointer->function = Function;
+ pointer->data = Data;
+
+ INIT_DELAYED_WORK(&pointer->work, _TimerFunction);
+
+ *Timer = pointer;
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ gcmkFOOTER();
+ return status;
+}
+
+/*******************************************************************************
+**
+** gckOS_DestroyTimer
+**
+** Destory a software timer.
+**
+** INPUT:
+**
+** gckOS Os
+** Pointer to the gckOS object.
+**
+** gctPOINTER Timer
+** Pointer to the timer to be destoryed.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckOS_DestroyTimer(
+ IN gckOS Os,
+ IN gctPOINTER Timer
+ )
+{
+ gcsOSTIMER_PTR timer;
+ gcmkHEADER_ARG("Os=0x%X Timer=0x%X", Os, Timer);
+
+ gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
+ gcmkVERIFY_ARGUMENT(Timer != gcvNULL);
+
+ timer = (gcsOSTIMER_PTR)Timer;
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23)
+ cancel_delayed_work_sync(&timer->work);
+#else
+ cancel_delayed_work(&timer->work);
+ flush_workqueue(Os->workqueue);
+#endif
+
+ gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Os, Timer));
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+}
+
+/*******************************************************************************
+**
+** gckOS_StartTimer
+**
+** Schedule a software timer.
+**
+** INPUT:
+**
+** gckOS Os
+** Pointer to the gckOS object.
+**
+** gctPOINTER Timer
+** Pointer to the timer to be scheduled.
+**
+** gctUINT32 Delay
+** Delay in milliseconds.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckOS_StartTimer(
+ IN gckOS Os,
+ IN gctPOINTER Timer,
+ IN gctUINT32 Delay
+ )
+{
+ gcsOSTIMER_PTR timer;
+
+ gcmkHEADER_ARG("Os=0x%X Timer=0x%X Delay=%u", Os, Timer, Delay);
+
+ gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
+ gcmkVERIFY_ARGUMENT(Timer != gcvNULL);
+ gcmkVERIFY_ARGUMENT(Delay != 0);
+
+ timer = (gcsOSTIMER_PTR)Timer;
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0)
+ mod_delayed_work(Os->workqueue, &timer->work, msecs_to_jiffies(Delay));
+#else
+ if (unlikely(delayed_work_pending(&timer->work)))
+ {
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23)
+ cancel_delayed_work_sync(&timer->work);
+#else
+ cancel_delayed_work(&timer->work);
+ flush_workqueue(Os->workqueue);
+#endif
+ }
+
+ queue_delayed_work(Os->workqueue, &timer->work, msecs_to_jiffies(Delay));
+#endif
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+}
+
+/*******************************************************************************
+**
+** gckOS_StopTimer
+**
+** Cancel a unscheduled timer.
+**
+** INPUT:
+**
+** gckOS Os
+** Pointer to the gckOS object.
+**
+** gctPOINTER Timer
+** Pointer to the timer to be cancel.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckOS_StopTimer(
+ IN gckOS Os,
+ IN gctPOINTER Timer
+ )
+{
+ gcsOSTIMER_PTR timer;
+ gcmkHEADER_ARG("Os=0x%X Timer=0x%X", Os, Timer);
+
+ gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
+ gcmkVERIFY_ARGUMENT(Timer != gcvNULL);
+
+ timer = (gcsOSTIMER_PTR)Timer;
+
+ cancel_delayed_work(&timer->work);
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+}
+
+gceSTATUS
+gckOS_GetProcessNameByPid(
+ IN gctINT Pid,
+ IN gctSIZE_T Length,
+ OUT gctUINT8_PTR String
+ )
+{
+ struct task_struct *task;
+
+ /* Get the task_struct of the task with pid. */
+ rcu_read_lock();
+
+ task = FIND_TASK_BY_PID(Pid);
+
+ if (task == gcvNULL)
+ {
+ rcu_read_unlock();
+ return gcvSTATUS_NOT_FOUND;
+ }
+
+ /* Get name of process. */
+ strncpy(String, task->comm, Length);
+
+ rcu_read_unlock();
+
+ return gcvSTATUS_OK;
+}
+
+gceSTATUS
+gckOS_DumpCallStack(
+ IN gckOS Os
+ )
+{
+ gcmkHEADER_ARG("Os=0x%X", Os);
+
+ gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
+
+ dump_stack();
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+}
+
+/*******************************************************************************
+**
+** gckOS_DetectProcessByName
+**
+** task->comm maybe part of process name, so this function
+** can only be used for debugging.
+**
+** INPUT:
+**
+** gctCONST_POINTER Name
+** Pointer to a string to hold name to be check. If the length
+** of name is longer than TASK_COMM_LEN (16), use part of name
+** to detect.
+**
+** OUTPUT:
+**
+** gcvSTATUS_TRUE if name of current process matches Name.
+**
+*/
+gceSTATUS
+gckOS_DetectProcessByName(
+ IN gctCONST_POINTER Name
+ )
+{
+ char comm[sizeof(current->comm)];
+
+ memset(comm, 0, sizeof(comm));
+
+ gcmkVERIFY_OK(
+ gckOS_GetProcessNameByPid(_GetProcessID(), sizeof(current->comm), comm));
+
+ return strstr(comm, Name) ? gcvSTATUS_TRUE
+ : gcvSTATUS_FALSE;
+}
+
+#if gcdLINUX_SYNC_FILE
+#ifndef CONFIG_SYNC_FILE
+gceSTATUS
+gckOS_CreateSyncTimeline(
+ IN gckOS Os,
+ IN gceCORE Core,
+ OUT gctHANDLE * Timeline
+ )
+{
+ struct viv_sync_timeline * timeline;
+ char name[32];
+
+ snprintf(name, 32, "gccore-%u", (unsigned int) Core);
+
+ /* Create viv sync timeline. */
+ timeline = viv_sync_timeline_create(name, Os);
+
+ if (timeline == gcvNULL)
+ {
+ /* Out of memory. */
+ return gcvSTATUS_OUT_OF_MEMORY;
+ }
+
+ *Timeline = (gctHANDLE) timeline;
+ return gcvSTATUS_OK;
+}
+
+gceSTATUS
+gckOS_DestroySyncTimeline(
+ IN gckOS Os,
+ IN gctHANDLE Timeline
+ )
+{
+ struct viv_sync_timeline * timeline;
+ gcmkASSERT(Timeline != gcvNULL);
+
+ /* Destroy timeline. */
+ timeline = (struct viv_sync_timeline *) Timeline;
+ sync_timeline_destroy(&timeline->obj);
+
+ return gcvSTATUS_OK;
+}
+
+gceSTATUS
+gckOS_CreateNativeFence(
+ IN gckOS Os,
+ IN gctHANDLE Timeline,
+ IN gctSIGNAL Signal,
+ OUT gctINT * FenceFD
+ )
+{
+ int fd = -1;
+ struct viv_sync_timeline *timeline;
+ struct sync_pt * pt = gcvNULL;
+ struct sync_fence * fence;
+ char name[32];
+ gcsSIGNAL_PTR signal;
+ gceSTATUS status;
+
+ gcmkHEADER_ARG("Os=0x%X Timeline=0x%X Signal=%d",
+ Os, Timeline, (gctUINT)(gctUINTPTR_T)Signal);
+
+ gcmkONERROR(
+ _QueryIntegerId(&Os->signalDB,
+ (gctUINT32)(gctUINTPTR_T)Signal,
+ (gctPOINTER)&signal));
+
+ /* Cast timeline. */
+ timeline = (struct viv_sync_timeline *) Timeline;
+
+ fd = get_unused_fd_flags(O_CLOEXEC);
+
+ if (fd < 0)
+ {
+ /* Out of resources. */
+ gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
+ }
+
+ /* Create viv_sync_pt. */
+ pt = viv_sync_pt_create(timeline, Signal);
+
+ if (pt == gcvNULL)
+ {
+ gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
+ }
+
+ /* Reference sync_timeline. */
+ signal->timeline = &timeline->obj;
+
+ /* Build fence name. */
+ snprintf(name, 32, "%.16s-signal_%lu",
+ current->comm,
+ (unsigned long)Signal);
+
+ /* Create sync_fence. */
+ fence = sync_fence_create(name, pt);
+
+ if (fence == NULL)
+ {
+ gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
+ }
+
+ /* Install fence to fd. */
+ sync_fence_install(fence, fd);
+
+ *FenceFD = fd;
+ gcmkFOOTER_ARG("*FenceFD=%d", fd);
+ return gcvSTATUS_OK;
+
+OnError:
+ /* Error roll back. */
+ if (pt)
+ {
+ sync_pt_free(pt);
+ }
+
+ if (fd > 0)
+ {
+ put_unused_fd(fd);
+ }
+
+ gcmkFOOTER();
+ return status;
+}
+
+static void
+_NativeFenceSignaled(
+ struct sync_fence *fence,
+ struct sync_fence_waiter *waiter
+ )
+{
+ kfree(waiter);
+ sync_fence_put(fence);
+}
+
+gceSTATUS
+gckOS_WaitNativeFence(
+ IN gckOS Os,
+ IN gctHANDLE Timeline,
+ IN gctINT FenceFD,
+ IN gctUINT32 Timeout
+ )
+{
+ struct sync_timeline * timeline;
+ struct sync_fence * fence;
+ gctBOOL wait;
+ gceSTATUS status = gcvSTATUS_OK;
+
+ gcmkHEADER_ARG("Os=0x%X Timeline=0x%X FenceFD=%d Timeout=%u",
+ Os, Timeline, FenceFD, Timeout);
+
+ /* Get shortcut. */
+ timeline = (struct sync_timeline *) Timeline;
+
+ /* Get sync fence. */
+ fence = sync_fence_fdget(FenceFD);
+
+ if (!fence)
+ {
+ gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
+ }
+
+ if (sync_fence_wait(fence, 0) == 0)
+ {
+ /* Already signaled. */
+ sync_fence_put(fence);
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+ }
+
+ wait = gcvFALSE;
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0)
+ {
+ int i;
+
+ for (i = 0; i < fence->num_fences; i++)
+ {
+ struct fence *f = fence->cbs[i].sync_pt;
+ struct sync_pt *pt = container_of(f, struct sync_pt, base);
+
+ /* Do not need to wait on same timeline. */
+ if ((sync_pt_parent(pt) != timeline) && !fence_is_signaled(f))
+ {
+ wait = gcvTRUE;
+ break;
+ }
+ }
+ }
+#else
+ {
+ struct list_head *pos;
+ list_for_each(pos, &fence->pt_list_head)
+ {
+ struct sync_pt * pt =
+ container_of(pos, struct sync_pt, pt_list);
+
+ /* Do not need to wait on same timeline. */
+ if (pt->parent != timeline)
+ {
+ wait = gcvTRUE;
+ break;
+ }
+ }
+ }
+#endif
+
+ if (wait)
+ {
+ int err;
+ long timeout = (Timeout == gcvINFINITE) ? - 1 : (long) Timeout;
+ err = sync_fence_wait(fence, timeout);
+
+ /* Put the fence. */
+ sync_fence_put(fence);
+
+ switch (err)
+ {
+ case 0:
+ break;
+ case -ETIME:
+ status = gcvSTATUS_TIMEOUT;
+ break;
+ default:
+ gcmkONERROR(gcvSTATUS_GENERIC_IO);
+ break;
+ }
+ }
+ else
+ {
+ int err;
+ struct sync_fence_waiter *waiter;
+ waiter = (struct sync_fence_waiter *)kmalloc(
+ sizeof (struct sync_fence_waiter), gcdNOWARN | GFP_KERNEL);
+
+ /*
+ * schedule a callback to put the sync_fence. Otherwise after this function
+ * is returned, the caller may free it since it's signaled. Then there's
+ * be a real signal on a free'ed sync fence.
+ */
+ if (!waiter)
+ {
+ sync_fence_put(fence);
+ gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
+ }
+
+ /* Schedule a waiter callback. */
+ sync_fence_waiter_init(waiter, _NativeFenceSignaled);
+ err = sync_fence_wait_async(fence, waiter);
+
+ switch (err)
+ {
+ case 0:
+ /* Put fence in callback function. */
+ break;
+ case 1:
+ /* already signaled. */
+ sync_fence_put(fence);
+ break;
+ default:
+ sync_fence_put(fence);
+ gcmkONERROR(gcvSTATUS_GENERIC_IO);
+ break;
+ }
+ }
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ gcmkFOOTER();
+ return status;
+}
+
+# else /* !CONFIG_SYNC_FILE */
+
+gceSTATUS
+gckOS_CreateSyncTimeline(
+ IN gckOS Os,
+ IN gceCORE Core,
+ OUT gctHANDLE * Timeline
+ )
+{
+ struct viv_sync_timeline *timeline;
+
+ char name[32];
+
+ snprintf(name, 32, "gccore-%u", (unsigned int) Core);
+ timeline = viv_sync_timeline_create(name, Os);
+
+ if (timeline == gcvNULL)
+ {
+ /* Out of memory. */
+ return gcvSTATUS_OUT_OF_MEMORY;
+ }
+
+ *Timeline = (gctHANDLE) timeline;
+ return gcvSTATUS_OK;
+}
+
+gceSTATUS
+gckOS_DestroySyncTimeline(
+ IN gckOS Os,
+ IN gctHANDLE Timeline
+ )
+{
+ struct viv_sync_timeline * timeline;
+
+ /* Destroy timeline. */
+ timeline = (struct viv_sync_timeline *) Timeline;
+ viv_sync_timeline_destroy(timeline);
+
+ return gcvSTATUS_OK;
+}
+
+gceSTATUS
+gckOS_CreateNativeFence(
+ IN gckOS Os,
+ IN gctHANDLE Timeline,
+ IN gctSIGNAL Signal,
+ OUT gctINT * FenceFD
+ )
+{
+ struct dma_fence *fence = NULL;
+ struct sync_file *sync = NULL;
+ int fd = -1;
+ struct viv_sync_timeline *timeline;
+ gcsSIGNAL_PTR signal = gcvNULL;
+ gceSTATUS status = gcvSTATUS_OK;
+
+ /* Create fence. */
+ timeline = (struct viv_sync_timeline *) Timeline;
+
+ gcmkONERROR(
+ _QueryIntegerId(&Os->signalDB,
+ (gctUINT32)(gctUINTPTR_T)Signal,
+ (gctPOINTER)&signal));
+
+ fence = viv_fence_create(timeline, signal);
+
+ if (!fence)
+ {
+ gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
+ }
+
+ /* Create sync_file. */
+ sync = sync_file_create(fence);
+
+ if (!sync)
+ {
+ gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
+ }
+
+ /* Get a unused fd. */
+ fd = get_unused_fd_flags(O_CLOEXEC);
+
+ if (fd < 0)
+ {
+ gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
+ }
+
+ fd_install(fd, sync->file);
+
+ *FenceFD = fd;
+ return gcvSTATUS_OK;
+
+OnError:
+ if (sync)
+ {
+ fput(sync->file);
+ }
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,9,68)
+ if (fence)
+ {
+ dma_fence_put(fence);
+ }
+#endif
+
+ if (fd > 0)
+ {
+ put_unused_fd(fd);
+ }
+
+ *FenceFD = -1;
+ return status;
+}
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,9,0)
+/**
+ * sync_file_fdget() - get a sync_file from an fd
+ * @fd: fd referencing a fence
+ *
+ * Ensures @fd references a valid sync_file, increments the refcount of the
+ * backing file. Returns the sync_file or NULL in case of error.
+ */
+static struct sync_file *sync_file_fdget(int fd)
+{
+ struct file *file = fget(fd);
+
+ if (!file)
+ return NULL;
+
+ return file->private_data;
+}
+
+gceSTATUS
+gckOS_WaitNativeFence(
+ IN gckOS Os,
+ IN gctHANDLE Timeline,
+ IN gctINT FenceFD,
+ IN gctUINT32 Timeout
+ )
+{
+ struct viv_sync_timeline *timeline;
+ gceSTATUS status = gcvSTATUS_OK;
+ unsigned int i;
+ unsigned long timeout;
+ unsigned int numFences;
+ struct sync_file *sync_file;
+
+ timeline = (struct viv_sync_timeline *) Timeline;
+
+ sync_file = sync_file_fdget(FenceFD);
+
+ if (!sync_file)
+ {
+ gcmkONERROR(gcvSTATUS_GENERIC_IO);
+ }
+
+ numFences = sync_file->num_fences;
+
+ timeout = msecs_to_jiffies(Timeout);
+
+ for (i = 0; i < numFences; i++)
+ {
+ struct fence *f = sync_file->cbs[i].fence;
+ fence_get(f);
+
+ if (f->context != timeline->context &&
+ !fence_is_signaled(f))
+ {
+ signed long ret;
+ ret = fence_wait_timeout(f, 1, timeout);
+
+ if (ret == -ERESTARTSYS)
+ {
+ status = gcvSTATUS_INTERRUPTED;
+ fence_put(f);
+ break;
+ }
+ else if (ret <= 0)
+ {
+ status = gcvSTATUS_TIMEOUT;
+ fence_put(f);
+ break;
+ }
+ else
+ {
+ /* wait success. */
+ timeout -= ret;
+ }
+ }
+
+ fence_put(f);
+ }
+
+ return gcvSTATUS_OK;
+
+OnError:
+ return status;
+}
+
+# else
+
+gceSTATUS
+gckOS_WaitNativeFence(
+ IN gckOS Os,
+ IN gctHANDLE Timeline,
+ IN gctINT FenceFD,
+ IN gctUINT32 Timeout
+ )
+{
+ struct viv_sync_timeline *timeline;
+ gceSTATUS status = gcvSTATUS_OK;
+ unsigned int i;
+ unsigned long timeout;
+ unsigned int numFences;
+ struct dma_fence *fence;
+ struct dma_fence **fences;
+
+ timeline = (struct viv_sync_timeline *) Timeline;
+
+ fence = sync_file_get_fence(FenceFD);
+
+ if (!fence)
+ {
+ gcmkONERROR(gcvSTATUS_GENERIC_IO);
+ }
+
+ if (dma_fence_is_array(fence))
+ {
+ struct dma_fence_array *array = to_dma_fence_array(fence);
+ fences = array->fences;
+ numFences = array->num_fences;
+ }
+ else
+ {
+ fences = &fence;
+ numFences = 1;
+ }
+
+ timeout = msecs_to_jiffies(Timeout);
+
+ for (i = 0; i < numFences; i++)
+ {
+ struct dma_fence *f = fences[i];
+
+ if (f->context != timeline->context &&
+ !dma_fence_is_signaled(f))
+ {
+ signed long ret;
+ ret = dma_fence_wait_timeout(f, 1, timeout);
+
+ if (ret == -ERESTARTSYS)
+ {
+ status = gcvSTATUS_INTERRUPTED;
+ break;
+ }
+ else if (ret <= 0)
+ {
+ status = gcvSTATUS_TIMEOUT;
+ break;
+ }
+ else
+ {
+ /* wait success. */
+ timeout -= ret;
+ }
+ }
+ }
+
+ dma_fence_put(fence);
+
+ return gcvSTATUS_OK;
+
+OnError:
+ return status;
+}
+
+# endif
+# endif
+#endif
+
+#if gcdSECURITY
+gceSTATUS
+gckOS_AllocatePageArray(
+ IN gckOS Os,
+ IN gctPHYS_ADDR Physical,
+ IN gctSIZE_T PageCount,
+ OUT gctPOINTER * PageArrayLogical,
+ OUT gctPHYS_ADDR * PageArrayPhysical
+ )
+{
+ gceSTATUS status = gcvSTATUS_OK;
+ PLINUX_MDL mdl;
+ gctUINT32* table;
+ gctUINT32 offset;
+ gctSIZE_T bytes;
+ gckALLOCATOR allocator;
+
+ gcmkHEADER_ARG("Os=0x%X Physical=0x%X PageCount=%u",
+ Os, Physical, PageCount);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
+ gcmkVERIFY_ARGUMENT(Physical != gcvNULL);
+ gcmkVERIFY_ARGUMENT(PageCount > 0);
+
+ bytes = PageCount * gcmSIZEOF(gctUINT32);
+ gcmkONERROR(gckOS_AllocateNonPagedMemory(
+ Os,
+ gcvFALSE,
+ gcvALLOC_FLAG_CONTIGUOUS,
+ &bytes,
+ PageArrayPhysical,
+ PageArrayLogical
+ ));
+
+ table = *PageArrayLogical;
+
+ /* Convert pointer to MDL. */
+ mdl = (PLINUX_MDL)Physical;
+
+ allocator = mdl->allocator;
+
+ /* Get all the physical addresses and store them in the page table. */
+
+ offset = 0;
+ PageCount = PageCount / (PAGE_SIZE / 4096);
+
+ /* Try to get the user pages so DMA can happen. */
+ while (PageCount-- > 0)
+ {
+ unsigned long phys = ~0;
+
+ gctPHYS_ADDR_T phys_addr;
+
+ allocator->ops->Physical(allocator, mdl, offset * PAGE_SIZE, &phys_addr);
+
+ phys = (unsigned long)phys_addr;
+
+ table[offset] = phys & PAGE_MASK;
+
+ offset += 1;
+ }
+
+OnError:
+
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+#endif
+
+gceSTATUS
+gckOS_CPUPhysicalToGPUPhysical(
+ IN gckOS Os,
+ IN gctPHYS_ADDR_T CPUPhysical,
+ IN gctPHYS_ADDR_T * GPUPhysical
+ )
+{
+ gcsPLATFORM * platform;
+ gcmkHEADER_ARG("CPUPhysical=%p", CPUPhysical);
+
+ platform = Os->device->platform;
+
+ if (platform && platform->ops->getGPUPhysical)
+ {
+ gcmkVERIFY_OK(
+ platform->ops->getGPUPhysical(platform, CPUPhysical, GPUPhysical));
+ }
+ else
+ {
+ *GPUPhysical = CPUPhysical;
+ }
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+}
+
+gceSTATUS
+gckOS_GPUPhysicalToCPUPhysical(
+ IN gckOS Os,
+ IN gctUINT32 GPUPhysical,
+ IN gctPHYS_ADDR_T * CPUPhysical
+ )
+{
+ gcsPLATFORM * platform;
+ gcmkHEADER_ARG("GPUPhysical=0x%X", GPUPhysical);
+
+ platform = Os->device->platform;
+
+ if (platform && platform->ops->getCPUPhysical)
+ {
+ gcmkVERIFY_OK(
+ platform->ops->getCPUPhysical(platform, GPUPhysical, CPUPhysical));
+ }
+ else
+ {
+ *CPUPhysical = GPUPhysical;
+ }
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+}
+
+gceSTATUS
+gckOS_PhysicalToPhysicalAddress(
+ IN gckOS Os,
+ IN gctPOINTER Physical,
+ IN gctUINT32 Offset,
+ OUT gctPHYS_ADDR_T * PhysicalAddress
+ )
+{
+ PLINUX_MDL mdl = (PLINUX_MDL)Physical;
+ gckALLOCATOR allocator = mdl->allocator;
+
+ if (allocator)
+ {
+ return allocator->ops->Physical(allocator, mdl, Offset, PhysicalAddress);
+ }
+
+ return gcvSTATUS_NOT_SUPPORTED;
+}
+
+static int fd_release(struct inode *inode, struct file *file)
+{
+ gcsFDPRIVATE_PTR private = (gcsFDPRIVATE_PTR)file->private_data;
+
+ if (private && private->release)
+ {
+ return private->release(private);
+ }
+
+ return 0;
+}
+
+static const struct file_operations fd_fops =
+{
+ .release = fd_release,
+};
+
+gceSTATUS
+gckOS_GetFd(
+ IN gctSTRING Name,
+ IN gcsFDPRIVATE_PTR Private,
+ OUT gctINT * Fd
+ )
+{
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
+ *Fd = anon_inode_getfd(Name, &fd_fops, Private, O_RDWR);
+
+ if (*Fd < 0)
+ {
+ return gcvSTATUS_OUT_OF_RESOURCES;
+ }
+
+ return gcvSTATUS_OK;
+#else
+ return gcvSTATUS_NOT_SUPPORTED;
+#endif
+}
+
+gceSTATUS
+gckOS_QueryOption(
+ IN gckOS Os,
+ IN gctCONST_STRING Option,
+ OUT gctUINT32 * Value
+ )
+{
+ gckGALDEVICE device = Os->device;
+
+ if (!strcmp(Option, "physBase"))
+ {
+ *Value = device->physBase;
+ return gcvSTATUS_OK;
+ }
+ else if (!strcmp(Option, "physSize"))
+ {
+ *Value = device->physSize;
+ return gcvSTATUS_OK;
+ }
+ else if (!strcmp(Option, "mmu"))
+ {
+#if gcdSECURITY
+ *Value = 0;
+#else
+ *Value = device->args.mmu;
+#endif
+ return gcvSTATUS_OK;
+ }
+ else if (!strcmp(Option, "contiguousSize"))
+ {
+ *Value = device->contiguousSize;
+ return gcvSTATUS_OK;
+ }
+ else if (!strcmp(Option, "contiguousBase"))
+ {
+ *Value = (gctUINT32)device->contiguousBase;
+ return gcvSTATUS_OK;
+ }
+ else if (!strcmp(Option, "externalSize"))
+ {
+ *Value = device->externalSize;
+ return gcvSTATUS_OK;
+ }
+ else if (!strcmp(Option, "externalBase"))
+ {
+ *Value = device->externalBase;
+ return gcvSTATUS_OK;
+ }
+ else if (!strcmp(Option, "recovery"))
+ {
+ *Value = device->args.recovery;
+ return gcvSTATUS_OK;
+ }
+ else if (!strcmp(Option, "stuckDump"))
+ {
+ *Value = device->args.stuckDump;
+ return gcvSTATUS_OK;
+ }
+ else if (!strcmp(Option, "powerManagement"))
+ {
+ *Value = device->args.powerManagement;
+ return gcvSTATUS_OK;
+ }
+ else if (!strcmp(Option, "TA"))
+ {
+ *Value = 0;
+ return gcvSTATUS_OK;
+ }
+ else if (!strcmp(Option, "gpuProfiler"))
+ {
+ *Value = device->args.gpuProfiler;
+ return gcvSTATUS_OK;
+ }
+ else if (!strcmp(Option, "platformFlagBits"))
+ {
+ *Value = device->platform->flagBits;
+ return gcvSTATUS_OK;
+ }
+
+ return gcvSTATUS_NOT_SUPPORTED;
+}
+
+gceSTATUS
+gckOS_MemoryGetSGT(
+ IN gckOS Os,
+ IN gctPHYS_ADDR Physical,
+ IN gctSIZE_T Offset,
+ IN gctSIZE_T Bytes,
+ OUT gctPOINTER *SGT
+ )
+{
+ PLINUX_MDL mdl;
+ gckALLOCATOR allocator;
+ gceSTATUS status = gcvSTATUS_OK;
+
+ if (!Physical)
+ {
+ gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
+ }
+
+ mdl = (PLINUX_MDL)Physical;
+ allocator = mdl->allocator;
+
+ if (!allocator->ops->GetSGT)
+ {
+ gcmkONERROR(gcvSTATUS_NOT_SUPPORTED);
+ }
+
+ if (Bytes > 0)
+ {
+ gcmkONERROR(allocator->ops->GetSGT(allocator, mdl, Offset, Bytes, SGT));
+ }
+
+OnError:
+ return status;
+}
+
+gceSTATUS
+gckOS_MemoryMmap(
+ IN gckOS Os,
+ IN gctPHYS_ADDR Physical,
+ IN gctSIZE_T skipPages,
+ IN gctSIZE_T numPages,
+ INOUT gctPOINTER Vma
+ )
+{
+ PLINUX_MDL mdl;
+ PLINUX_MDL_MAP mdlMap;
+ gckALLOCATOR allocator;
+ gceSTATUS status = gcvSTATUS_OK;
+ gctBOOL cacheable = gcvFALSE;
+
+ if (!Physical)
+ {
+ gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
+ }
+
+ mdl = (PLINUX_MDL)Physical;
+ allocator = mdl->allocator;
+
+ if (!allocator->ops->Mmap)
+ {
+ gcmkONERROR(gcvSTATUS_NOT_SUPPORTED);
+ }
+
+ mutex_lock(&mdl->mapsMutex);
+
+ mdlMap = FindMdlMap(mdl, _GetProcessID());
+ if (mdlMap)
+ {
+ cacheable = mdlMap->cacheable;
+ }
+
+ mutex_unlock(&mdl->mapsMutex);
+
+ gcmkONERROR(allocator->ops->Mmap(allocator, mdl, cacheable, skipPages, numPages, Vma));
+
+OnError:
+ return status;
+}
+
+/*******************************************************************************
+**
+** gckOS_WrapMemory
+**
+** Import a number of pages allocated by other allocator.
+**
+** INPUT:
+**
+** gckOS Os
+** Pointer to an gckOS object.
+**
+** gctUINT32 Flag
+** Memory type.
+**
+** OUTPUT:
+**
+** gctSIZE_T * Bytes
+** Pointer to a variable that hold the number of bytes allocated.
+**
+** gctPHYS_ADDR * Physical
+** Pointer to a variable that will hold the physical address of the
+** allocation.
+*/
+gceSTATUS
+gckOS_WrapMemory(
+ IN gckOS Os,
+ IN gcsUSER_MEMORY_DESC_PTR Desc,
+ OUT gctSIZE_T *Bytes,
+ OUT gctPHYS_ADDR * Physical,
+ OUT gctBOOL *Contiguous
+ )
+{
+ PLINUX_MDL mdl = gcvNULL;
+ gceSTATUS status = gcvSTATUS_OUT_OF_MEMORY;
+ gckALLOCATOR allocator;
+ gcsATTACH_DESC desc;
+ gctSIZE_T bytes = 0;
+
+ gcmkHEADER_ARG("Os=0x%X ", Os);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
+ gcmkVERIFY_ARGUMENT(Physical != gcvNULL);
+
+ mdl = _CreateMdl(Os);
+ if (mdl == gcvNULL)
+ {
+ gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
+ }
+
+ if (Desc->flag & gcvALLOC_FLAG_DMABUF)
+ {
+ desc.dmaBuf.dmabuf = gcmUINT64_TO_PTR(Desc->dmabuf);
+
+#if defined(CONFIG_DMA_SHARED_BUFFER)
+ {
+ struct dma_buf *dmabuf = (struct dma_buf*)desc.dmaBuf.dmabuf;
+ bytes = dmabuf->size;
+ }
+#endif
+ }
+ else if (Desc->flag & gcvALLOC_FLAG_USERMEMORY)
+ {
+ desc.userMem.memory = gcmUINT64_TO_PTR(Desc->logical);
+ desc.userMem.physical = Desc->physical;
+ desc.userMem.size = Desc->size;
+ bytes = Desc->size;
+ }
+ else if (Desc->flag & gcvALLOC_FLAG_EXTERNAL_MEMORY)
+ {
+ desc.externalMem.info = Desc->externalMemoryInfo;
+ }
+ else
+ {
+ gcmkONERROR(gcvSTATUS_NOT_SUPPORTED);
+ }
+
+ /* Walk all allocators. */
+ list_for_each_entry(allocator, &Os->allocatorList, link)
+ {
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_OS,
+ "%s(%d) Flag = %x allocator->capability = %x",
+ __FUNCTION__, __LINE__, Desc->flag, allocator->capability);
+
+ if ((Desc->flag & allocator->capability) != Desc->flag)
+ {
+ status = gcvSTATUS_NOT_SUPPORTED;
+ continue;
+ }
+
+ if (Desc->flag == gcvALLOC_FLAG_EXTERNAL_MEMORY)
+ {
+ /* Use name to match suitable allocator for external memory. */
+ if (!strncmp(Desc->externalMemoryInfo.allocatorName,
+ allocator->name, gcdEXTERNAL_MEMORY_NAME_MAX))
+ {
+ status = gcvSTATUS_NOT_SUPPORTED;
+ continue;
+ }
+ }
+
+ status = allocator->ops->Attach(allocator, &desc, mdl);
+
+ if (gcmIS_SUCCESS(status))
+ {
+ mdl->allocator = allocator;
+ break;
+ }
+ }
+
+ /* Check status. */
+ gcmkONERROR(status);
+
+ mdl->dmaHandle = 0;
+ mdl->addr = 0;
+
+ mdl->bytes = bytes ? bytes : mdl->numPages * PAGE_SIZE;
+ *Bytes = mdl->bytes;
+
+ /* Return physical address. */
+ *Physical = (gctPHYS_ADDR) mdl;
+
+ *Contiguous = mdl->contiguous;
+
+ /*
+ * Add this to a global list.
+ * Will be used by get physical address
+ * and mapuser pointer functions.
+ */
+ mutex_lock(&Os->mdlMutex);
+ list_add_tail(&mdl->link, &Os->mdlHead);
+ mutex_unlock(&Os->mdlMutex);
+
+ /* Success. */
+ gcmkFOOTER_ARG("*Physical=0x%X", *Physical);
+ return gcvSTATUS_OK;
+
+OnError:
+ if (mdl != gcvNULL)
+ {
+ /* Free the memory. */
+ _DestroyMdl(mdl);
+ }
+
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+gceSTATUS
+gckOS_GetPolicyID(
+ IN gckOS Os,
+ IN gceSURF_TYPE Type,
+ OUT gctUINT32_PTR PolicyID,
+ OUT gctUINT32_PTR AXIConfig
+ )
+{
+ gcsPLATFORM * platform = Os->device->platform;
+
+ if (platform && platform->ops->getPolicyID)
+ {
+ return platform->ops->getPolicyID(platform, Type, PolicyID, AXIConfig);
+ }
+
+ return gcvSTATUS_NOT_SUPPORTED;
+}
+
diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.h b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.h
new file mode 100644
index 000000000000..6f63109903e1
--- /dev/null
+++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.h
@@ -0,0 +1,123 @@
+/****************************************************************************
+*
+* The MIT License (MIT)
+*
+* Copyright (c) 2014 - 2018 Vivante 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 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 GPL License (GPL)
+*
+* Copyright (C) 2014 - 2018 Vivante 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.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+*****************************************************************************
+*
+* Note: This software is released under dual MIT and GPL licenses. A
+* recipient may use this file under the terms of either the MIT license or
+* GPL License. If you wish to use only one license not the other, you can
+* indicate your decision by deleting one of the above license notices in your
+* version of this file.
+*
+*****************************************************************************/
+
+
+#ifndef __gc_hal_kernel_os_h_
+#define __gc_hal_kernel_os_h_
+
+typedef struct _LINUX_MDL LINUX_MDL, *PLINUX_MDL;
+typedef struct _LINUX_MDL_MAP LINUX_MDL_MAP, *PLINUX_MDL_MAP;
+
+struct _LINUX_MDL_MAP
+{
+ gctINT pid;
+
+ /* map references. */
+ gctUINT32 count;
+
+ struct vm_area_struct * vma;
+ gctPOINTER vmaAddr;
+ gctBOOL cacheable;
+
+ struct list_head link;
+};
+
+struct _LINUX_MDL
+{
+ gckOS os;
+
+ atomic_t refs;
+
+ /* Kernel address. */
+ char * addr;
+
+ /* Size and covered page count. */
+ size_t bytes;
+ gctINT numPages;
+
+ gctBOOL contiguous;
+ dma_addr_t dmaHandle;
+
+ gctBOOL cacheable;
+
+ struct mutex mapsMutex;
+ struct list_head mapsHead;
+
+ /* Pointer to allocator which allocates memory for this mdl. */
+ void * allocator;
+
+ /* Private data used by allocator. */
+ void * priv;
+
+ uint gid;
+
+ struct list_head link;
+};
+
+extern PLINUX_MDL_MAP
+FindMdlMap(
+ IN PLINUX_MDL Mdl,
+ IN gctINT PID
+ );
+
+typedef struct _DRIVER_ARGS
+{
+ gctUINT64 InputBuffer;
+ gctUINT64 InputBufferSize;
+ gctUINT64 OutputBuffer;
+ gctUINT64 OutputBufferSize;
+}
+DRIVER_ARGS;
+
+#endif /* __gc_hal_kernel_os_h_ */
diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_platform.h b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_platform.h
new file mode 100644
index 000000000000..b570195cf044
--- /dev/null
+++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_platform.h
@@ -0,0 +1,307 @@
+/****************************************************************************
+*
+* The MIT License (MIT)
+*
+* Copyright (c) 2014 - 2018 Vivante 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 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 GPL License (GPL)
+*
+* Copyright (C) 2014 - 2018 Vivante 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.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+*****************************************************************************
+*
+* Note: This software is released under dual MIT and GPL licenses. A
+* recipient may use this file under the terms of either the MIT license or
+* GPL License. If you wish to use only one license not the other, you can
+* indicate your decision by deleting one of the above license notices in your
+* version of this file.
+*
+*****************************************************************************/
+
+
+#ifndef _gc_hal_kernel_platform_h_
+#define _gc_hal_kernel_platform_h_
+#include <linux/mm.h>
+#include <linux/platform_device.h>
+#if USE_LINUX_PCIE
+#include <linux/pci.h>
+#endif
+
+typedef struct _gcsMODULE_PARAMETERS
+{
+ gctINT irqLine;
+ gctUINT registerMemBase;
+ gctUINT registerMemSize;
+ gctINT irqLine2D;
+ gctUINT registerMemBase2D;
+ gctUINT registerMemSize2D;
+ gctINT irqLineVG;
+ gctUINT registerMemBaseVG;
+ gctUINT registerMemSizeVG;
+ gctUINT contiguousSize;
+ gctUINT contiguousBase;
+ gctUINT contiguousRequested;
+ gctUINT externalSize;
+ gctUINT externalBase;
+ gctUINT bankSize;
+ gctINT fastClear;
+ gceCOMPRESSION_OPTION compression;
+ gctINT powerManagement;
+ gctINT gpuProfiler;
+ gctINT signal;
+ gctUINT baseAddress;
+ gctUINT physSize;
+ gctUINT logFileSize;
+ gctUINT recovery;
+ gctUINT stuckDump;
+ gctUINT showArgs;
+ gctUINT gpu3DMinClock;
+ gctBOOL registerMemMapped;
+ gctPOINTER registerMemAddress;
+ gctINT irqs[gcvCORE_COUNT];
+ gctUINT registerBases[gcvCORE_COUNT];
+ gctUINT registerSizes[gcvCORE_COUNT];
+ gctUINT chipIDs[gcvCORE_COUNT];
+}
+gcsMODULE_PARAMETERS;
+
+typedef struct soc_platform gcsPLATFORM;
+
+typedef struct soc_platform_ops
+{
+
+ /*******************************************************************************
+ **
+ ** adjustParam
+ **
+ ** Override content of arguments, if a argument is not changed here, it will
+ ** keep as default value or value set by insmod command line.
+ */
+ gceSTATUS
+ (*adjustParam)(
+ IN gcsPLATFORM * Platform,
+ OUT gcsMODULE_PARAMETERS *Args
+ );
+
+ /*******************************************************************************
+ **
+ ** getPower
+ **
+ ** Prepare power and clock operation.
+ */
+ gceSTATUS
+ (*getPower)(
+ IN gcsPLATFORM * Platform
+ );
+
+ /*******************************************************************************
+ **
+ ** putPower
+ **
+ ** Finish power and clock operation.
+ */
+ gceSTATUS
+ (*putPower)(
+ IN gcsPLATFORM * Platform
+ );
+
+ /*******************************************************************************
+ **
+ ** setPower
+ **
+ ** Set power state of specified GPU.
+ **
+ ** INPUT:
+ **
+ ** gceCORE GPU
+ ** GPU neeed to config.
+ **
+ ** gceBOOL Enable
+ ** Enable or disable power.
+ */
+ gceSTATUS
+ (*setPower)(
+ IN gcsPLATFORM * Platform,
+ IN gceCORE GPU,
+ IN gctBOOL Enable
+ );
+
+ /*******************************************************************************
+ **
+ ** setClock
+ **
+ ** Set clock state of specified GPU.
+ **
+ ** INPUT:
+ **
+ ** gceCORE GPU
+ ** GPU neeed to config.
+ **
+ ** gceBOOL Enable
+ ** Enable or disable clock.
+ */
+ gceSTATUS
+ (*setClock)(
+ IN gcsPLATFORM * Platform,
+ IN gceCORE GPU,
+ IN gctBOOL Enable
+ );
+
+ /*******************************************************************************
+ **
+ ** reset
+ **
+ ** Reset GPU outside.
+ **
+ ** INPUT:
+ **
+ ** gceCORE GPU
+ ** GPU neeed to reset.
+ */
+ gceSTATUS
+ (*reset)(
+ IN gcsPLATFORM * Platform,
+ IN gceCORE GPU
+ );
+
+ /*******************************************************************************
+ **
+ ** getGPUPhysical
+ **
+ ** Convert CPU physical address to GPU physical address if they are
+ ** different.
+ */
+ gceSTATUS
+ (*getGPUPhysical)(
+ IN gcsPLATFORM * Platform,
+ IN gctPHYS_ADDR_T CPUPhysical,
+ OUT gctPHYS_ADDR_T * GPUPhysical
+ );
+
+ /*******************************************************************************
+ **
+ ** getCPUPhysical
+ **
+ ** Convert GPU physical address to CPU physical address if they are
+ ** different.
+ */
+ gceSTATUS
+ (*getCPUPhysical)(
+ IN gcsPLATFORM * Platform,
+ IN gctUINT32 GPUPhysical,
+ OUT gctPHYS_ADDR_T * CPUPhysical
+ );
+
+ /*******************************************************************************
+ **
+ ** adjustProt
+ **
+ ** Override Prot flag when mapping paged memory to userspace.
+ */
+ gceSTATUS
+ (*adjustProt)(
+ IN struct vm_area_struct * vma
+ );
+
+ /*******************************************************************************
+ **
+ ** shrinkMemory
+ **
+ ** Do something to collect memory, eg, act as oom killer.
+ */
+ gceSTATUS
+ (*shrinkMemory)(
+ IN gcsPLATFORM * Platform
+ );
+
+ /*******************************************************************************
+ **
+ ** cache
+ **
+ ** Cache operation.
+ */
+ gceSTATUS
+ (*cache)(
+ IN gcsPLATFORM * Platform,
+ IN gctUINT32 ProcessID,
+ IN gctPHYS_ADDR Handle,
+ IN gctUINT32 Physical,
+ IN gctPOINTER Logical,
+ IN gctSIZE_T Bytes,
+ IN gceCACHEOPERATION Operation
+ );
+
+ /*******************************************************************************
+ **
+ ** getPolicyID
+ **
+ ** Get policyID for a specified surface type.
+ */
+ gceSTATUS
+ (*getPolicyID)(
+ IN gcsPLATFORM * Platform,
+ IN gceSURF_TYPE Type,
+ OUT gctUINT32_PTR PolicyID,
+ OUT gctUINT32_PTR AXIConfig
+ );
+}
+gcsPLATFORM_OPERATIONS;
+
+struct soc_platform
+{
+#if USE_LINUX_PCIE
+ struct pci_dev* device;
+ struct pci_driver* driver;
+#else
+ struct platform_device* device;
+ struct platform_driver* driver;
+#endif
+
+ const char *name;
+ gcsPLATFORM_OPERATIONS* ops;
+ /* PLATFORM specific flags */
+ gctUINT32 flagBits;
+};
+
+#if USE_LINUX_PCIE
+int soc_platform_init(struct pci_driver *pdrv, gcsPLATFORM **platform);
+#else
+int soc_platform_init(struct platform_driver *pdrv, gcsPLATFORM **platform);
+#endif
+int soc_platform_terminate(gcsPLATFORM *platform);
+
+#endif
diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_security_channel.c b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_security_channel.c
new file mode 100644
index 000000000000..d0969ff24661
--- /dev/null
+++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_security_channel.c
@@ -0,0 +1,426 @@
+/****************************************************************************
+*
+* The MIT License (MIT)
+*
+* Copyright (c) 2014 - 2018 Vivante 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 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 GPL License (GPL)
+*
+* Copyright (C) 2014 - 2018 Vivante 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.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+*****************************************************************************
+*
+* Note: This software is released under dual MIT and GPL licenses. A
+* recipient may use this file under the terms of either the MIT license or
+* GPL License. If you wish to use only one license not the other, you can
+* indicate your decision by deleting one of the above license notices in your
+* version of this file.
+*
+*****************************************************************************/
+
+
+#include "gc_hal_kernel_linux.h"
+#include <linux/slab.h>
+
+#include "tee_client_api.h"
+
+#define _GC_OBJ_ZONE gcvZONE_OS
+
+#define GPU3D_UUID { 0xcc9f80ea, 0xa836, 0x11e3, { 0x9b, 0x07, 0x78, 0x2b, 0xcb, 0x5c, 0xf3, 0xe3 } }
+
+static const TEEC_UUID gpu3d_uuid = GPU3D_UUID;
+TEEC_Context teecContext;
+
+typedef struct _gcsSecurityChannel
+{
+ gckOS os;
+ TEEC_Session session;
+ int * virtual;
+ TEEC_SharedMemory inputBuffer;
+ gctUINT32 bytes;
+ gctPOINTER mutex;
+}
+gcsSecurityChannel;
+
+TEEC_SharedMemory *
+gpu3d_allocate_secure_mem(
+ gckOS Os,
+ unsigned int size
+ )
+{
+ TEEC_Result result;
+ TEEC_Context *context = &teecContext;
+ TEEC_SharedMemory *shm = NULL;
+ void *handle = NULL;
+ gctPHYS_ADDR_T phyAddr;
+ gceSTATUS status;
+ gctSIZE_T bytes = size;
+
+ shm = kmalloc(sizeof(TEEC_SharedMemory), GFP_KERNEL);
+
+ if (NULL == shm)
+ {
+ return NULL;
+ }
+
+ memset(shm, 0, sizeof(TEEC_SharedMemory));
+
+ status = gckOS_AllocatePagedMemoryEx(
+ Os,
+ gcvALLOC_FLAG_SECURITY,
+ bytes,
+ gcvNULL,
+ (gctPHYS_ADDR *)&handle);
+
+ if (gcmIS_ERROR(status))
+ {
+ kfree(shm);
+ return NULL;
+ }
+
+ status = gckOS_PhysicalToPhysicalAddress(
+ Os,
+ handle,
+ 0,
+ &phyAddr);
+
+ if (gcmIS_ERROR(status))
+ {
+ kfree(shm);
+ return NULL;
+ }
+
+ /* record the handle into shm->user_data */
+ shm->userdata = handle;
+
+ /* [b] Bulk input buffer. */
+ shm->size = size;
+ shm->flags = TEEC_MEM_INPUT;
+
+ /* Use TEE Client API to register the underlying memory buffer. */
+ shm->phyAddr = (void *)(gctUINT32)phyAddr;
+
+ result = TEEC_RegisterSharedMemory(
+ context,
+ shm);
+
+ if (result != TEEC_SUCCESS)
+ {
+ gckOS_FreePagedMemory(Os, (gctPHYS_ADDR)handle, shm->size);
+ kfree(shm);
+ return NULL;
+ }
+
+ return shm;
+}
+
+void gpu3d_release_secure_mem(
+ gckOS Os,
+ void *shm_handle
+ )
+{
+ TEEC_SharedMemory *shm = shm_handle;
+ void * handle;
+
+ if (!shm)
+ {
+ return;
+ }
+
+ handle = shm->userdata;
+
+ TEEC_ReleaseSharedMemory(shm);
+ gckOS_FreePagedMemory(Os, (gctPHYS_ADDR)handle, shm->size);
+
+ kfree(shm);
+
+ return;
+}
+
+static TEEC_Result gpu3d_session_callback(
+ TEEC_Session* session,
+ uint32_t commandID,
+ TEEC_Operation* operation,
+ void* userdata
+ )
+{
+ gcsSecurityChannel *channel = userdata;
+
+ if (channel == gcvNULL)
+ {
+ return TEEC_ERROR_BAD_PARAMETERS;
+ }
+
+ switch (commandID)
+ {
+ case gcvTA_CALLBACK_ALLOC_SECURE_MEM:
+ {
+ uint32_t size = operation->params[0].value.a;
+ TEEC_SharedMemory *shm = NULL;
+
+ shm = gpu3d_allocate_secure_mem(channel->os, size);
+ if (shm == NULL)
+ {
+ return TEEC_ERROR_OUT_OF_MEMORY;
+ }
+
+ /* use the value to save the pointer in client side */
+ operation->params[0].value.a = (uint32_t)shm;
+ operation->params[0].value.b = (uint32_t)shm->phyAddr;
+
+ break;
+ }
+ case gcvTA_CALLBACK_FREE_SECURE_MEM:
+ {
+ TEEC_SharedMemory *shm = (TEEC_SharedMemory *)operation->params[0].value.a;
+
+ gpu3d_release_secure_mem(channel->os, shm);
+ break;
+ }
+ default:
+ break;
+ }
+
+ return TEEC_SUCCESS;
+}
+
+gceSTATUS
+gckOS_OpenSecurityChannel(
+ IN gckOS Os,
+ IN gceCORE GPU,
+ OUT gctUINT32 *Channel
+ )
+{
+ gceSTATUS status;
+ TEEC_Result result;
+ static bool initialized = gcvFALSE;
+ gcsSecurityChannel *channel = gcvNULL;
+
+ TEEC_Operation operation = {0};
+
+ /* Connect to TEE. */
+ if (initialized == gcvFALSE)
+ {
+ result = TEEC_InitializeContext(NULL, &teecContext);
+
+ if (result != TEEC_SUCCESS)
+ {
+ gcmkONERROR(gcvSTATUS_CHIP_NOT_READY);
+ }
+
+ initialized = gcvTRUE;
+ }
+
+ /* Construct channel. */
+ gcmkONERROR(
+ gckOS_Allocate(Os, gcmSIZEOF(*channel), (gctPOINTER *)&channel));
+
+ gckOS_ZeroMemory(channel, gcmSIZEOF(gcsSecurityChannel));
+
+ channel->os = Os;
+
+ gcmkONERROR(gckOS_CreateMutex(Os, &channel->mutex));
+
+ /* Allocate shared memory for passing gcTA_INTERFACE. */
+ channel->bytes = gcmSIZEOF(gcsTA_INTERFACE);
+ channel->virtual = kmalloc(channel->bytes, GFP_KERNEL | __GFP_NOWARN);
+
+ if (!channel->virtual)
+ {
+ gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
+ }
+
+ channel->inputBuffer.size = channel->bytes;
+ channel->inputBuffer.flags = TEEC_MEM_INPUT | TEEC_MEM_OUTPUT;
+ channel->inputBuffer.phyAddr = (void *)virt_to_phys(channel->virtual);
+
+ result = TEEC_RegisterSharedMemory(&teecContext, &channel->inputBuffer);
+
+ if (result != TEEC_SUCCESS)
+ {
+ gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
+ }
+
+ operation.paramTypes = TEEC_PARAM_TYPES(
+ TEEC_VALUE_INPUT,
+ TEEC_NONE,
+ TEEC_NONE,
+ TEEC_NONE);
+
+ operation.params[0].value.a = GPU;
+
+ /* Open session with TEE application. */
+ result = TEEC_OpenSession(
+ &teecContext,
+ &channel->session,
+ &gpu3d_uuid,
+ TEEC_LOGIN_USER,
+ NULL,
+ &operation,
+ NULL);
+
+ /* Prepare callback. */
+ TEEC_RegisterCallback(&channel->session, gpu3d_session_callback, channel);
+
+ *Channel = (gctUINT32)channel;
+
+ return gcvSTATUS_OK;
+
+OnError:
+ if (channel)
+ {
+ if (channel->virtual)
+ {
+ }
+
+ if (channel->mutex)
+ {
+ gcmkVERIFY_OK(gckOS_DeleteMutex(Os, channel->mutex));
+ }
+
+ gcmkVERIFY_OK(gckOS_Free(Os, channel));
+ }
+
+ return status;
+}
+
+gceSTATUS
+gckOS_CloseSecurityChannel(
+ IN gctUINT32 Channel
+ )
+{
+ return gcvSTATUS_OK;
+}
+
+gceSTATUS
+gckOS_CallSecurityService(
+ IN gctUINT32 Channel,
+ IN gcsTA_INTERFACE *Interface
+ )
+{
+ gceSTATUS status;
+ TEEC_Result result;
+ gcsSecurityChannel *channel = (gcsSecurityChannel *)Channel;
+ TEEC_Operation operation = {0};
+
+ gcmkHEADER();
+ gcmkVERIFY_ARGUMENT(Channel != 0);
+
+ gckOS_AcquireMutex(channel->os, channel->mutex, gcvINFINITE);
+
+ gckOS_MemCopy(channel->virtual, Interface, channel->bytes);
+
+ operation.paramTypes = TEEC_PARAM_TYPES(
+ TEEC_MEMREF_PARTIAL_INPUT,
+ TEEC_NONE,
+ TEEC_NONE,
+ TEEC_NONE);
+
+ /* Note: we use the updated size in the MemRef output by the encryption. */
+ operation.params[0].memref.parent = &channel->inputBuffer;
+ operation.params[0].memref.offset = 0;
+ operation.params[0].memref.size = sizeof(gcsTA_INTERFACE);
+ operation.started = true;
+
+ /* Start the commit command within the TEE application. */
+ result = TEEC_InvokeCommand(
+ &channel->session,
+ gcvTA_COMMAND_DISPATCH,
+ &operation,
+ NULL);
+
+ gckOS_MemCopy(Interface, channel->virtual, channel->bytes);
+
+ gckOS_ReleaseMutex(channel->os, channel->mutex);
+
+ if (result != TEEC_SUCCESS)
+ {
+ gcmkONERROR(gcvSTATUS_GENERIC_IO);
+ }
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ gcmkFOOTER();
+ return status;
+}
+
+gceSTATUS
+gckOS_InitSecurityChannel(
+ IN gctUINT32 Channel
+ )
+{
+ gceSTATUS status;
+ TEEC_Result result;
+ gcsSecurityChannel *channel = (gcsSecurityChannel *)Channel;
+ TEEC_Operation operation = {0};
+
+ gcmkHEADER();
+ gcmkVERIFY_ARGUMENT(Channel != 0);
+
+ operation.paramTypes = TEEC_PARAM_TYPES(
+ TEEC_MEMREF_PARTIAL_INPUT,
+ TEEC_NONE,
+ TEEC_NONE,
+ TEEC_NONE);
+
+ /* Note: we use the updated size in the MemRef output by the encryption. */
+ operation.params[0].memref.parent = &channel->inputBuffer;
+ operation.params[0].memref.offset = 0;
+ operation.params[0].memref.size = gcmSIZEOF(gcsTA_INTERFACE);
+ operation.started = true;
+
+ /* Start the commit command within the TEE application. */
+ result = TEEC_InvokeCommand(
+ &channel->session,
+ gcvTA_COMMAND_INIT,
+ &operation,
+ NULL);
+
+ if (result != TEEC_SUCCESS)
+ {
+ gcmkONERROR(gcvSTATUS_GENERIC_IO);
+ }
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ gcmkFOOTER();
+ return status;
+}
diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_security_channel_emulator.c b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_security_channel_emulator.c
new file mode 100644
index 000000000000..c0b17ceead52
--- /dev/null
+++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_security_channel_emulator.c
@@ -0,0 +1,116 @@
+/****************************************************************************
+*
+* The MIT License (MIT)
+*
+* Copyright (c) 2014 - 2018 Vivante 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 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 GPL License (GPL)
+*
+* Copyright (C) 2014 - 2018 Vivante 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.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+*****************************************************************************
+*
+* Note: This software is released under dual MIT and GPL licenses. A
+* recipient may use this file under the terms of either the MIT license or
+* GPL License. If you wish to use only one license not the other, you can
+* indicate your decision by deleting one of the above license notices in your
+* version of this file.
+*
+*****************************************************************************/
+
+
+#include "gc_hal_kernel_linux.h"
+
+#define _GC_OBJ_ZONE gcvZONE_OS
+
+#if gcdENABLE_TRUST_APPLICATION
+
+gceSTATUS
+gckOS_OpenSecurityChannel(
+ IN gckOS Os,
+ IN gceCORE Core,
+ OUT gctUINT32 *Channel
+ )
+{
+ *Channel = Core + 1;
+ return gcvSTATUS_OK;
+}
+
+gceSTATUS
+gckOS_InitSecurityChannel(
+ OUT gctUINT32 Channel
+ )
+{
+ return gcvSTATUS_OK;
+}
+
+gceSTATUS
+gckOS_CloseSecurityChannel(
+ IN gctUINT32 Channel
+ )
+{
+ return gcvSTATUS_OK;
+}
+
+extern gceSTATUS
+TAEmulator (
+ gceCORE,
+ void *
+ );
+
+gceSTATUS
+gckOS_CallSecurityService(
+ IN gctUINT32 Channel,
+ IN gcsTA_INTERFACE *Interface
+ )
+{
+ gceCORE core;
+ gceSTATUS status;
+ gcmkHEADER();
+ gcmkVERIFY_ARGUMENT(Channel != 0);
+
+ core = (gceCORE)(Channel - 1);
+
+ TAEmulator(core, Interface);
+
+ status = Interface->result;
+
+ gcmkFOOTER();
+ return status;
+}
+
+#endif
diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_sync.c b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_sync.c
new file mode 100644
index 000000000000..b366a2fb71fa
--- /dev/null
+++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_sync.c
@@ -0,0 +1,378 @@
+/****************************************************************************
+*
+* The MIT License (MIT)
+*
+* Copyright (c) 2014 - 2018 Vivante 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 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 GPL License (GPL)
+*
+* Copyright (C) 2014 - 2018 Vivante 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.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+*****************************************************************************
+*
+* Note: This software is released under dual MIT and GPL licenses. A
+* recipient may use this file under the terms of either the MIT license or
+* GPL License. If you wish to use only one license not the other, you can
+* indicate your decision by deleting one of the above license notices in your
+* version of this file.
+*
+*****************************************************************************/
+
+
+#include <gc_hal.h>
+#include <gc_hal_base.h>
+
+#if gcdLINUX_SYNC_FILE
+
+#include <linux/kernel.h>
+#include <linux/file.h>
+#include <linux/fs.h>
+#include <linux/miscdevice.h>
+#include <linux/module.h>
+#include <linux/syscalls.h>
+#include <linux/uaccess.h>
+#include <linux/slab.h>
+
+#include "gc_hal_kernel_sync.h"
+#include "gc_hal_kernel_linux.h"
+
+#ifndef CONFIG_SYNC_FILE
+
+static struct sync_pt * viv_sync_pt_dup(struct sync_pt *sync_pt)
+{
+ gceSTATUS status;
+ struct viv_sync_pt *pt;
+ struct viv_sync_pt *src;
+ struct viv_sync_timeline *obj;
+
+ src = (struct viv_sync_pt *)sync_pt;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0)
+ obj = (struct viv_sync_timeline *)sync_pt_parent(sync_pt);
+#else
+ obj = (struct viv_sync_timeline *)sync_pt->parent;
+#endif
+
+ /* Create the new sync_pt. */
+ pt = (struct viv_sync_pt *)
+ sync_pt_create(&obj->obj, sizeof(struct viv_sync_pt));
+
+ pt->stamp = src->stamp;
+
+ /* Reference signal. */
+ status = gckOS_MapSignal(obj->os,
+ src->signal,
+ gcvNULL /* (gctHANDLE) _GetProcessID() */,
+ &pt->signal);
+
+ if (gcmIS_ERROR(status)) {
+ sync_pt_free((struct sync_pt *)pt);
+ return NULL;
+ }
+
+ return (struct sync_pt *)pt;
+}
+
+static int viv_sync_pt_has_signaled(struct sync_pt *sync_pt)
+{
+ gceSTATUS status;
+ struct viv_sync_pt *pt;
+ struct viv_sync_timeline *obj;
+
+ pt = (struct viv_sync_pt *)sync_pt;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0)
+ obj = (struct viv_sync_timeline *)sync_pt_parent(sync_pt);
+#else
+ obj = (struct viv_sync_timeline *)sync_pt->parent;
+#endif
+
+ status = _QuerySignal(obj->os, pt->signal);
+
+ if (gcmIS_ERROR(status)) {
+ /* Error. */
+ return -1;
+ }
+
+ return (int) status;
+}
+
+static int viv_sync_pt_compare(struct sync_pt *a, struct sync_pt *b)
+{
+ int ret;
+ struct viv_sync_pt *pt1 = (struct viv_sync_pt *)a;
+ struct viv_sync_pt *pt2 = (struct viv_sync_pt *)b;
+
+ ret = (pt1->stamp < pt2->stamp) ? -1
+ : (pt1->stamp == pt2->stamp) ? 0
+ : 1;
+
+ return ret;
+}
+
+static void viv_sync_pt_free(struct sync_pt *sync_pt)
+{
+ struct viv_sync_pt *pt;
+ struct viv_sync_timeline *obj;
+
+ pt = (struct viv_sync_pt *)sync_pt;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0)
+ obj = (struct viv_sync_timeline *)sync_pt_parent(sync_pt);
+#else
+ obj = (struct viv_sync_timeline *)sync_pt->parent;
+#endif
+
+ gckOS_DestroySignal(obj->os, pt->signal);
+}
+
+static void viv_timeline_value_str(struct sync_timeline *timeline,
+ char *str, int size)
+{
+ struct viv_sync_timeline *obj;
+
+ obj = (struct viv_sync_timeline *)timeline;
+ snprintf(str, size, "stamp_%llu", obj->stamp);
+}
+
+static void viv_pt_value_str(struct sync_pt *sync_pt, char *str, int size)
+{
+ struct viv_sync_pt *pt;
+
+ pt = (struct viv_sync_pt *)sync_pt;
+ snprintf(str, size, "signal_%lu@stamp_%llu",
+ (unsigned long)pt->signal, pt->stamp);
+}
+
+static struct sync_timeline_ops viv_timeline_ops =
+{
+ .driver_name = "viv_gpu_sync",
+ .dup = viv_sync_pt_dup,
+ .has_signaled = viv_sync_pt_has_signaled,
+ .compare = viv_sync_pt_compare,
+ .free_pt = viv_sync_pt_free,
+ .timeline_value_str = viv_timeline_value_str,
+ .pt_value_str = viv_pt_value_str,
+};
+
+struct viv_sync_timeline * viv_sync_timeline_create(const char *name, gckOS os)
+{
+ struct viv_sync_timeline * obj;
+
+ obj = (struct viv_sync_timeline *)
+ sync_timeline_create(&viv_timeline_ops, sizeof(struct viv_sync_timeline), name);
+
+ obj->os = os;
+ obj->stamp = 0;
+
+ return obj;
+}
+
+struct sync_pt * viv_sync_pt_create(struct viv_sync_timeline *obj,
+ gctSIGNAL Signal)
+{
+ gceSTATUS status;
+ struct viv_sync_pt *pt;
+
+ pt = (struct viv_sync_pt *)
+ sync_pt_create(&obj->obj, sizeof(struct viv_sync_pt));
+
+ pt->stamp = obj->stamp++;
+
+ /* Dup signal. */
+ status = gckOS_MapSignal(obj->os,
+ Signal,
+ gcvNULL /* (gctHANDLE) _GetProcessID() */,
+ &pt->signal);
+
+ if (gcmIS_ERROR(status)) {
+ sync_pt_free((struct sync_pt *)pt);
+ return NULL;
+ }
+
+ return (struct sync_pt *)pt;
+}
+
+#else
+
+struct viv_sync_timeline * viv_sync_timeline_create(const char *name, gckOS Os)
+{
+ struct viv_sync_timeline *timeline;
+
+ timeline = kmalloc(sizeof(struct viv_sync_timeline),
+ gcdNOWARN | GFP_KERNEL);
+
+ if (!timeline)
+ return NULL;
+
+ strncpy(timeline->name, name, sizeof(timeline->name) - 1);
+ timeline->context = dma_fence_context_alloc(1);
+ atomic64_set(&timeline->seqno, 0);
+ timeline->os = Os;
+
+ return timeline;
+}
+
+void viv_sync_timeline_destroy(struct viv_sync_timeline *timeline)
+{
+ kfree(timeline);
+}
+
+static const char * viv_fence_get_driver_name(struct dma_fence *fence)
+{
+ return "viv_gpu_sync";
+}
+
+static const char * viv_fence_get_timeline_name(struct dma_fence *fence)
+{
+ struct viv_fence *f = (struct viv_fence *)fence;
+ return f->parent->name;
+}
+
+/* Same as fence_signaled. */
+static inline bool __viv_fence_signaled(struct dma_fence *fence)
+{
+ struct viv_fence *f = (struct viv_fence *)fence;
+ struct viv_sync_timeline *timeline = f->parent;
+ gceSTATUS status;
+
+ status = _QuerySignal(timeline->os, f->signal);
+
+ return (status == gcvSTATUS_TRUE) ? true : false;
+}
+
+static bool viv_fence_enable_signaling(struct dma_fence *fence)
+{
+ /* fence is locked already. */
+ return !__viv_fence_signaled(fence);
+}
+
+static bool viv_fence_signaled(struct dma_fence *fence)
+{
+ /* fence could be locked, could be not. */
+ return __viv_fence_signaled(fence);
+}
+
+static void viv_fence_release(struct dma_fence *fence)
+{
+ struct viv_fence *f = (struct viv_fence *)fence;
+ struct viv_sync_timeline *timeline = f->parent;
+
+ if (f->signal)
+ gckOS_DestroySignal(timeline->os, f->signal);
+
+ kfree(fence);
+}
+
+static struct dma_fence_ops viv_fence_ops =
+{
+ .get_driver_name = viv_fence_get_driver_name,
+ .get_timeline_name = viv_fence_get_timeline_name,
+ .enable_signaling = viv_fence_enable_signaling,
+ .signaled = viv_fence_signaled,
+ .wait = dma_fence_default_wait,
+ .release = viv_fence_release,
+};
+
+struct dma_fence * viv_fence_create(struct viv_sync_timeline *timeline,
+ gcsSIGNAL *signal)
+{
+ gceSTATUS status;
+ struct viv_fence *fence;
+ struct dma_fence *old_fence = NULL;
+ unsigned seqno;
+
+ fence = kzalloc(sizeof(struct viv_fence), gcdNOWARN | GFP_KERNEL);
+
+ if (!fence)
+ return NULL;
+
+ /* Reference signal in fence. */
+ status = gckOS_MapSignal(timeline->os, (gctSIGNAL)(uintptr_t)signal->id,
+ NULL, &fence->signal);
+
+ if (gcmIS_ERROR(status)) {
+ kfree(fence);
+ return NULL;
+ }
+
+ spin_lock_init(&fence->lock);
+
+ fence->parent = timeline;
+
+ seqno = (unsigned)atomic64_inc_return(&timeline->seqno);
+
+ dma_fence_init((struct dma_fence *)fence, &viv_fence_ops,
+ &fence->lock, timeline->context, seqno);
+
+ /*
+ * Reference fence in signal.
+ * Be aware of recursive reference!!
+ */
+ spin_lock(&signal->lock);
+
+ if (signal->fence) {
+ old_fence = signal->fence;
+ signal->fence = NULL;
+ }
+
+ if (!signal->done) {
+ signal->fence = (struct dma_fence*)fence;
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,9,68)
+ dma_fence_get((struct dma_fence*)fence);
+#endif
+ }
+
+ spin_unlock(&signal->lock);
+
+ if (old_fence)
+ dma_fence_put(old_fence);
+
+ if (!signal->fence) {
+ /* Fence already signaled. */
+ gckOS_DestroySignal(timeline->os, fence->signal);
+ fence->signal = NULL;
+
+ dma_fence_signal_locked((struct dma_fence*)fence);
+ dma_fence_put((struct dma_fence*)fence);
+ fence = NULL;
+ }
+
+ return (struct dma_fence*)fence;
+}
+
+#endif
+
+#endif
diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_sync.h b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_sync.h
new file mode 100644
index 000000000000..d723e469a470
--- /dev/null
+++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_sync.h
@@ -0,0 +1,151 @@
+/****************************************************************************
+*
+* The MIT License (MIT)
+*
+* Copyright (c) 2014 - 2018 Vivante 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 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 GPL License (GPL)
+*
+* Copyright (C) 2014 - 2018 Vivante 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.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+*****************************************************************************
+*
+* Note: This software is released under dual MIT and GPL licenses. A
+* recipient may use this file under the terms of either the MIT license or
+* GPL License. If you wish to use only one license not the other, you can
+* indicate your decision by deleting one of the above license notices in your
+* version of this file.
+*
+*****************************************************************************/
+
+
+#ifndef __gc_hal_kernel_sync_h_
+#define __gc_hal_kernel_sync_h_
+
+#include <linux/types.h>
+
+#ifndef CONFIG_SYNC_FILE
+
+/* sync.h is in drivers/staging/android/ for now. */
+#include <sync.h>
+
+#include <gc_hal.h>
+#include <gc_hal_base.h>
+
+struct viv_sync_timeline
+{
+ /* Parent object. */
+ struct sync_timeline obj;
+
+ /* Timestamp when sync_pt is created. */
+ gctUINT64 stamp;
+
+ /* Pointer to os struct. */
+ gckOS os;
+};
+
+
+struct viv_sync_pt
+{
+ /* Parent object. */
+ struct sync_pt pt;
+
+ /* Reference signal. */
+ gctSIGNAL signal;
+
+ /* Timestamp when sync_pt is created. */
+ gctUINT64 stamp;
+};
+
+/* Create viv_sync_timeline object. */
+struct viv_sync_timeline * viv_sync_timeline_create(const char *name, gckOS Os);
+
+/* Create viv_sync_pt object. */
+struct sync_pt * viv_sync_pt_create(struct viv_sync_timeline *obj,
+ gctSIGNAL signal);
+
+#else
+
+#include <linux/sync_file.h>
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,10,0)
+# include <linux/fence.h>
+# include <linux/fence-array.h>
+#else
+# include <linux/dma-fence.h>
+# include <linux/dma-fence-array.h>
+#endif
+
+#include <gc_hal.h>
+#include <gc_hal_base.h>
+#include "gc_hal_kernel_linux.h"
+
+struct viv_sync_timeline
+{
+ char name[64];
+
+ /* Parent object. */
+ u64 context;
+
+ /* Timestamp when sync_pt is created. */
+ atomic64_t seqno;
+
+ /* Pointer to os struct. */
+ gckOS os;
+};
+
+struct viv_fence
+{
+ /* must be the first. */
+ struct dma_fence base;
+ spinlock_t lock;
+
+ struct viv_sync_timeline *parent;
+
+ /* link with signal. */
+ gctSIGNAL signal;
+};
+
+struct viv_sync_timeline * viv_sync_timeline_create(const char *name, gckOS Os);
+
+void viv_sync_timeline_destroy(struct viv_sync_timeline *timeline);
+
+struct dma_fence * viv_fence_create(struct viv_sync_timeline *timeline,
+ gcsSIGNAL *signal);
+
+#endif
+
+#endif /* __gc_hal_kernel_sync_h_ */
diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/platform/default/gc_hal_kernel_platform_default.c b/drivers/mxc/gpu-viv/hal/os/linux/kernel/platform/default/gc_hal_kernel_platform_default.c
new file mode 100644
index 000000000000..1f522b6ced68
--- /dev/null
+++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/platform/default/gc_hal_kernel_platform_default.c
@@ -0,0 +1,146 @@
+/****************************************************************************
+*
+* The MIT License (MIT)
+*
+* Copyright (c) 2014 - 2018 Vivante 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 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 GPL License (GPL)
+*
+* Copyright (C) 2014 - 2018 Vivante 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.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+*****************************************************************************
+*
+* Note: This software is released under dual MIT and GPL licenses. A
+* recipient may use this file under the terms of either the MIT license or
+* GPL License. If you wish to use only one license not the other, you can
+* indicate your decision by deleting one of the above license notices in your
+* version of this file.
+*
+*****************************************************************************/
+
+
+#include "gc_hal_kernel_linux.h"
+#include "gc_hal_kernel_platform.h"
+
+
+gceSTATUS
+_AdjustParam(
+ IN gcsPLATFORM *Platform,
+ OUT gcsMODULE_PARAMETERS *Args
+ )
+{
+#if USE_LINUX_PCIE
+ struct pci_dev *pdev = Platform->device;
+ unsigned char irqline = pdev->irq;
+
+ if ((Args->irqLine2D != -1) && (Args->irqLine2D != irqline))
+ {
+ Args->irqLine2D = irqline;
+ }
+ if ((Args->irqLine != -1) && (Args->irqLine != irqline))
+ {
+ Args->irqLine = irqline;
+ }
+#endif
+ return gcvSTATUS_OK;
+}
+
+static struct soc_platform_ops default_ops =
+{
+ .adjustParam = _AdjustParam,
+};
+
+static struct soc_platform default_platform =
+{
+ .name = __FILE__,
+ .ops = &default_ops,
+};
+
+#if USE_LINUX_PCIE
+
+int soc_platform_init(struct pci_driver *pdrv,
+ struct soc_platform **platform)
+{
+ *platform = &default_platform;
+ return 0;
+}
+
+int soc_platform_terminate(struct soc_platform *platform)
+{
+ return 0;
+}
+
+#else
+static struct platform_device *default_dev;
+
+int soc_platform_init(struct platform_driver *pdrv,
+ struct soc_platform **platform)
+{
+ int ret;
+ default_dev = platform_device_alloc(pdrv->driver.name, -1);
+
+ if (!default_dev) {
+ printk(KERN_ERR "galcore: platform_device_alloc failed.\n");
+ return -ENOMEM;
+ }
+
+ /* Add device */
+ ret = platform_device_add(default_dev);
+ if (ret) {
+ printk(KERN_ERR "galcore: platform_device_add failed.\n");
+ goto put_dev;
+ }
+
+ *platform = &default_platform;
+ return 0;
+
+put_dev:
+ platform_device_put(default_dev);
+
+ return ret;
+}
+
+int soc_platform_terminate(struct soc_platform *platform)
+{
+ if (default_dev) {
+ platform_device_unregister(default_dev);
+ default_dev = NULL;
+ }
+
+ return 0;
+}
+#endif
diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/platform/freescale/gc_hal_kernel_platform_imx.c b/drivers/mxc/gpu-viv/hal/os/linux/kernel/platform/freescale/gc_hal_kernel_platform_imx.c
new file mode 100644
index 000000000000..8b0094103d84
--- /dev/null
+++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/platform/freescale/gc_hal_kernel_platform_imx.c
@@ -0,0 +1,1644 @@
+/****************************************************************************
+*
+* The MIT License (MIT)
+*
+* Copyright (c) 2014 - 2018 Vivante Corporation
+* Copyright 2019 NXP
+*
+* 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 GPL License (GPL)
+*
+* Copyright (C) 2014 - 2018 Vivante Corporation
+* Copyright 2019 NXP
+*
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License
+* as published by the Free Software Foundation; either version 2
+* of the License, or (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+*****************************************************************************
+*
+* Note: This software is released under dual MIT and GPL licenses. A
+* recipient may use this file under the terms of either the MIT license or
+* GPL License. If you wish to use only one license not the other, you can
+* indicate your decision by deleting one of the above license notices in your
+* version of this file.
+*
+*****************************************************************************/
+
+
+#include "gc_hal_kernel_linux.h"
+#include "gc_hal_kernel_platform.h"
+#include "gc_hal_kernel_device.h"
+#include "gc_hal_driver.h"
+#include <linux/slab.h>
+
+#if defined(CONFIG_PM_OPP)
+#include <linux/pm_opp.h>
+#endif
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
+# include <linux/of_platform.h>
+# include <linux/of_gpio.h>
+# include <linux/of_address.h>
+#endif
+
+#if USE_PLATFORM_DRIVER
+# include <linux/platform_device.h>
+#endif
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,9,0)) || defined(IMX8_SCU_CONTROL)
+# define IMX_GPU_SUBSYSTEM 1
+# include <linux/component.h>
+#endif
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)
+# include <mach/viv_gpu.h>
+#elif defined (CONFIG_PM)
+# include <linux/pm_runtime.h>
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 10, 0)
+# include <mach/busfreq.h>
+# elif LINUX_VERSION_CODE < KERNEL_VERSION(3, 14, 29)
+# include <linux/busfreq-imx6.h>
+# include <linux/reset.h>
+# else
+# include <linux/busfreq-imx.h>
+# include <linux/reset.h>
+# endif
+#endif
+
+#include <linux/clk.h>
+
+#if defined(IMX8_SCU_CONTROL)
+# include <soc/imx8/sc/sci.h>
+static sc_ipc_t gpu_ipcHandle;
+#endif
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0)
+# include <mach/hardware.h>
+#endif
+
+#include <linux/pm_runtime.h>
+#include <linux/regulator/consumer.h>
+
+#ifdef CONFIG_DEVICE_THERMAL
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
+# include <linux/device_cooling.h>
+# define REG_THERMAL_NOTIFIER(a) register_devfreq_cooling_notifier(a);
+# define UNREG_THERMAL_NOTIFIER(a) unregister_devfreq_cooling_notifier(a);
+# else
+extern int register_thermal_notifier(struct notifier_block *nb);
+extern int unregister_thermal_notifier(struct notifier_block *nb);
+# define REG_THERMAL_NOTIFIER(a) register_thermal_notifier(a);
+# define UNREG_THERMAL_NOTIFIER(a) unregister_thermal_notifier(a);
+# endif
+#endif
+
+#ifndef gcdFSL_CONTIGUOUS_SIZE
+# define gcdFSL_CONTIGUOUS_SIZE (4 << 20)
+#endif
+
+static int initgpu3DMinClock = 1;
+module_param(initgpu3DMinClock, int, 0644);
+
+struct platform_device *pdevice;
+
+#ifdef CONFIG_GPU_LOW_MEMORY_KILLER
+# include <linux/kernel.h>
+# include <linux/mm.h>
+# include <linux/oom.h>
+# include <linux/sched.h>
+# include <linux/profile.h>
+
+static unsigned long timeout;
+struct task_struct *almostfail;
+
+static int
+notif_func(struct notifier_block *self, unsigned long val, void *data)
+{
+ struct task_struct *task = data;
+
+ if (task == almostfail)
+ almostfail = NULL;
+
+ return NOTIFY_DONE;
+}
+
+static struct notifier_block task_nb = {
+ .notifier_call = notif_func,
+};
+
+static int force_shrink_mem(IN gckKERNEL Kernel)
+{
+ struct task_struct *p = NULL;
+ struct task_struct *selected = NULL;
+ int cur_size = 0;
+ int set_size = 0;
+ int oom_val = 0;
+ int mem_adj = 0;
+ int retVal = -1;
+
+ if (almostfail && time_before_eq(jiffies, timeout))
+ return 0;
+
+ rcu_read_lock();
+
+ for_each_process(p) {
+ gcuDATABASE_INFO info;
+ struct mm_struct *mm;
+ struct signal_struct *sig;
+
+ cur_size = 0;
+
+ task_lock(p);
+ sig = p->signal;
+ mm = p->mm;
+ if (!sig || !mm) {
+ task_unlock(p);
+ continue;
+ }
+ oom_val = sig->oom_score_adj;
+ if (oom_val < 0) {
+ task_unlock(p);
+ continue;
+ }
+ task_unlock(p);
+
+ rcu_read_unlock();
+ if (gckKERNEL_QueryProcessDB(Kernel, p->pid, gcvFALSE, gcvDB_VIDEO_MEMORY, &info) == gcvSTATUS_OK){
+ cur_size += info.counters.bytes / PAGE_SIZE;
+ }
+ if (gckKERNEL_QueryProcessDB(Kernel, p->pid, gcvFALSE, gcvDB_CONTIGUOUS, &info) == gcvSTATUS_OK){
+ cur_size += info.counters.bytes / PAGE_SIZE;
+ }
+ rcu_read_lock();
+
+ if (cur_size <= 0) continue;
+
+ printk("<gpu> pid %d (%s), adj %d, size %d\n", p->pid, p->comm, oom_val, cur_size);
+
+ if (selected) {
+ if ((oom_val < mem_adj) || (oom_val == mem_adj && cur_size <= set_size)) continue;
+ }
+ set_size = cur_size;
+ mem_adj = oom_val;
+ selected = p;
+ }
+
+ if (selected && mem_adj > 0) {
+ printk("<gpu> send sigkill to %d (%s), adj %d, size %d\n",
+ selected->pid, selected->comm, mem_adj, set_size);
+ almostfail = selected;
+ timeout = jiffies + HZ;
+ force_sig(SIGKILL, selected);
+ retVal = 0;
+ }
+
+ rcu_read_unlock();
+
+ return retVal;
+}
+
+extern gckKERNEL
+_GetValidKernel(
+ gckGALDEVICE Device
+ );
+
+static gceSTATUS
+_ShrinkMemory(
+ IN gcsPLATFORM * Platform
+ )
+{
+ struct platform_device *pdev;
+ gckGALDEVICE galDevice;
+ gckKERNEL kernel;
+ gceSTATUS status = gcvSTATUS_OK;
+
+ pdev = Platform->device;
+
+ galDevice = platform_get_drvdata(pdev);
+
+ kernel = _GetValidKernel(galDevice);
+
+ if (kernel != gcvNULL)
+ {
+ if (force_shrink_mem(kernel) != 0)
+ status = gcvSTATUS_OUT_OF_MEMORY;
+ }
+ else
+ {
+ printk("%s: can't find kernel!\n", __FUNCTION__);
+ }
+
+ return status;
+}
+#endif
+
+#if gcdENABLE_FSCALE_VAL_ADJUST && (defined(CONFIG_DEVICE_THERMAL) || defined(CONFIG_DEVICE_THERMAL_MODULE))
+static int thermal_hot_pm_notify(struct notifier_block *nb, unsigned long event,
+ void *dummy)
+{
+ static gctUINT orgFscale, minFscale, maxFscale;
+ static gctBOOL bAlreadyTooHot = gcvFALSE;
+ gckHARDWARE hardware;
+ gckGALDEVICE galDevice;
+
+ galDevice = platform_get_drvdata(pdevice);
+ if (!galDevice)
+ {
+ /* GPU is not ready, so it is meaningless to change GPU freq. */
+ return NOTIFY_OK;
+ }
+
+ if (!galDevice->kernels[gcvCORE_MAJOR])
+ {
+ return NOTIFY_OK;
+ }
+
+ hardware = galDevice->kernels[gcvCORE_MAJOR]->hardware;
+
+ if (!hardware)
+ {
+ return NOTIFY_OK;
+ }
+
+ if (event && !bAlreadyTooHot) {
+ gckHARDWARE_GetFscaleValue(hardware,&orgFscale,&minFscale, &maxFscale);
+ gckHARDWARE_SetFscaleValue(hardware, minFscale);
+ bAlreadyTooHot = gcvTRUE;
+ printk("System is too hot. GPU3D will work at %d/64 clock.\n", minFscale);
+ } else if (!event && bAlreadyTooHot) {
+ gckHARDWARE_SetFscaleValue(hardware, orgFscale);
+ printk("Hot alarm is canceled. GPU3D clock will return to %d/64\n", orgFscale);
+ bAlreadyTooHot = gcvFALSE;
+ }
+ return NOTIFY_OK;
+}
+
+static struct notifier_block thermal_hot_pm_notifier =
+{
+ .notifier_call = thermal_hot_pm_notify,
+};
+
+static ssize_t gpu3DMinClock_show(struct device_driver *dev, char *buf)
+{
+ gctUINT currentf = 0, minf = 0, maxf = 0;
+ gckGALDEVICE galDevice;
+
+ galDevice = platform_get_drvdata(pdevice);
+
+ minf = 0;
+ if (galDevice->kernels[gcvCORE_MAJOR])
+ {
+ gckHARDWARE_GetFscaleValue(galDevice->kernels[gcvCORE_MAJOR]->hardware,
+ &currentf, &minf, &maxf);
+ }
+
+ snprintf(buf, PAGE_SIZE, "%d\n", minf);
+ return strlen(buf);
+}
+
+static ssize_t gpu3DMinClock_store(struct device_driver *dev, const char *buf, size_t count)
+{
+
+ gctINT fields;
+ gctUINT MinFscaleValue;
+ gckGALDEVICE galDevice;
+
+ galDevice = platform_get_drvdata(pdevice);
+
+ if (galDevice->kernels[gcvCORE_MAJOR])
+ {
+ fields = sscanf(buf, "%d", &MinFscaleValue);
+
+ if (fields < 1)
+ return -EINVAL;
+
+ gckHARDWARE_SetMinFscaleValue(galDevice->kernels[gcvCORE_MAJOR]->hardware,MinFscaleValue);
+ }
+
+ return count;
+}
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,11,0)
+static DRIVER_ATTR_RW(gpu3DMinClock);
+#else
+static DRIVER_ATTR(gpu3DMinClock, S_IRUGO | S_IWUSR, gpu3DMinClock_show, gpu3DMinClock_store);
+#endif
+#endif
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0)
+static const struct of_device_id mxs_gpu_dt_ids[] = {
+#ifdef IMX_GPU_SUBSYSTEM
+ { .compatible = "fsl,imx8-gpu-ss", },
+#endif
+ { .compatible = "fsl,imx6q-gpu", }, /*Backward Compatiblity */
+ {/* sentinel */}
+};
+MODULE_DEVICE_TABLE(of, mxs_gpu_dt_ids);
+#endif
+
+struct gpu_clk
+{
+ struct clk *clk_core;
+ struct clk *clk_shader;
+ struct clk *clk_axi;
+ struct clk *clk_ahb;
+};
+
+#if defined(CONFIG_PM_OPP)
+typedef enum _GOVERN_MODE
+{
+ OVERDRIVE,
+ NOMINAL,
+ UNDERDRIVE,
+ GOVERN_COUNT
+}
+GOVERN_MODE;
+
+static const char *govern_modes[] =
+{
+ "overdrive",
+ "nominal",
+ "underdrive"
+};
+
+struct gpu_govern
+{
+ unsigned long core_clk_freq[GOVERN_COUNT];
+ unsigned long shader_clk_freq[GOVERN_COUNT];
+ struct device* dev;
+ int num_modes;
+ int current_mode;
+};
+#endif
+
+struct imx_priv
+{
+ struct gpu_clk imx_gpu_clks[gcdMAX_GPU_COUNT];
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,14,0)
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0) || LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
+ /*Power management.*/
+ struct regulator *gpu_regulator;
+# endif
+#endif
+ /*Run time pm*/
+ struct device *pmdev[gcdMAX_GPU_COUNT];
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
+ struct reset_control *rstc[gcdMAX_GPU_COUNT];
+#endif
+
+#if defined(IMX8_SCU_CONTROL)
+ sc_rsrc_t sc_gpu_pid[gcdMAX_GPU_COUNT];
+#endif
+
+ int gpu3dCount;
+
+#if defined(CONFIG_PM_OPP)
+ struct gpu_govern imx_gpu_govern;
+#endif
+};
+
+static struct imx_priv imxPriv;
+
+#if defined(CONFIG_PM_OPP)
+static ssize_t gpu_govern_show(struct device_driver *dev, char *buf)
+{
+ struct imx_priv *priv = &imxPriv;
+ int i;
+ ssize_t len;
+ int max_modes;
+
+ unsigned long core_freq;
+ unsigned long shader_freq;
+
+ if (priv->imx_gpu_govern.num_modes == GOVERN_COUNT)
+ max_modes = priv->imx_gpu_govern.num_modes - 1;
+ else
+ max_modes = priv->imx_gpu_govern.num_modes;
+
+ len = sprintf(buf, "GPU support %d modes\n", priv->imx_gpu_govern.num_modes);
+
+
+ for (i = priv->imx_gpu_govern.current_mode; i <= max_modes; i++)
+ {
+ core_freq = priv->imx_gpu_govern.core_clk_freq[i];
+ shader_freq = priv->imx_gpu_govern.shader_clk_freq[i];
+
+ len += sprintf(buf + len,
+ "%s:\tcore_clk frequency: %lu\tshader_clk frequency: %lu\n",
+ govern_modes[i], core_freq, shader_freq);
+ }
+
+ len += sprintf(buf + len, "Currently GPU runs on mode %s\n",
+ govern_modes[priv->imx_gpu_govern.current_mode]);
+
+ return len;
+}
+
+static ssize_t gpu_govern_store(struct device_driver *dev, const char *buf, size_t count)
+{
+ unsigned long core_freq = 0;
+ unsigned long shader_freq = 0;
+ struct imx_priv *priv = &imxPriv;
+ int core = gcvCORE_MAJOR;
+ int i;
+
+ for (i = 0; i < GOVERN_COUNT; i++)
+ {
+ if (strstr(buf, govern_modes[i]))
+ {
+ break;
+ }
+ }
+
+ if (i == GOVERN_COUNT)
+ {
+ return count;
+ }
+
+ core_freq = priv->imx_gpu_govern.core_clk_freq[i];
+ shader_freq = priv->imx_gpu_govern.shader_clk_freq[i];
+ priv->imx_gpu_govern.current_mode = i;
+
+ for (core = gcvCORE_MAJOR; core <= gcvCORE_3D_MAX; core++)
+ {
+ struct clk* clk_core = priv->imx_gpu_clks[core].clk_core;
+ struct clk* clk_shader = priv->imx_gpu_clks[core].clk_shader;
+
+ if (clk_core != NULL && clk_shader != NULL &&
+ core_freq != 0 && shader_freq != 0)
+ {
+ clk_set_rate(clk_core, core_freq);
+ clk_set_rate(clk_shader, shader_freq);
+ }
+ }
+
+ return count;
+}
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,11,0)
+static DRIVER_ATTR_RW(gpu_govern);
+#else
+static DRIVER_ATTR(gpu_govern, S_IRUGO | S_IWUSR, gpu_govern_show, gpu_govern_store);
+#endif
+
+int init_gpu_opp_table(struct device *dev)
+{
+ const struct property *prop;
+ const __be32 *val;
+ int nr;
+ int ret = 0;
+ int i, p;
+ int core = gcvCORE_MAJOR;
+ struct imx_priv *priv = &imxPriv;
+
+ struct clk *clk_core;
+ struct clk *clk_shader;
+
+ unsigned long core_freq, shader_freq;
+
+ priv->imx_gpu_govern.num_modes = 0;
+
+ prop = of_find_property(dev->of_node, "operating-points", NULL);
+ if (!prop) {
+ return 0;
+ }
+
+ if (!prop->value) {
+ dev_err(dev, "operating-points invalid. Frequency scaling will not work\n");
+ return -ENODATA;
+ }
+
+ /*
+ * Each OPP is a set of tuples consisting of frequency and
+ * voltage like <freq-kHz vol-uV>.
+ */
+ nr = prop->length / sizeof(u32);
+ if (nr % 2) {
+ dev_err(dev, "%s: Invalid OPP list\n", __func__);
+ return -EINVAL;
+ }
+
+ /*
+ * We handle both cases where UNDERDRIVE is represented by a single tuple
+ * or when it is represented by two. More than 4 tuples means that we have
+ * the current mode defaulting to OVERDRIVE, while less than 3 means only
+ * nominal. Lastly just two tuples means UNDERDRIVE. Note that the tuples
+ * are divisible by 2 (X Y) hence there's no need to test for odd values.
+ */
+ if (nr < 6)
+ priv->imx_gpu_govern.current_mode = UNDERDRIVE;
+ else if (nr == 6 || nr == 8)
+ priv->imx_gpu_govern.current_mode = NOMINAL;
+ else
+ priv->imx_gpu_govern.current_mode = OVERDRIVE;
+
+ val = prop->value;
+
+ for (p = 0, i = priv->imx_gpu_govern.current_mode; nr > 0 && i < GOVERN_COUNT; nr -= 4)
+ {
+ unsigned long core_freq, core_volt, shader_freq, shader_volt;
+
+ core_freq = be32_to_cpup(val++) * 1000;
+ core_volt = be32_to_cpup(val++);
+
+ if (nr == 2)
+ {
+ shader_freq = core_freq;
+ shader_volt = core_volt;
+ }
+ else
+ {
+ shader_freq = be32_to_cpup(val++) * 1000;
+ shader_volt = be32_to_cpup(val++);
+ }
+
+ /* We only register core_clk frequency */
+ if (dev_pm_opp_add(dev, core_freq, core_volt))
+ {
+ dev_warn(dev, "%s: Failed to add OPP %ld\n",
+ __func__, core_freq);
+ continue;
+ }
+
+ priv->imx_gpu_govern.core_clk_freq[i] = core_freq;
+ priv->imx_gpu_govern.shader_clk_freq[i] = shader_freq;
+
+ p++;
+ i++;
+ }
+
+ priv->imx_gpu_govern.num_modes = p;
+ priv->imx_gpu_govern.dev = dev;
+
+ if (priv->imx_gpu_govern.num_modes > 0)
+ {
+ ret = driver_create_file(dev->driver, &driver_attr_gpu_govern);
+ if (ret) {
+ dev_err(dev, "create gpu_govern attr failed (%d)\n", ret);
+ return ret;
+ }
+
+ /*
+ * This could be redundant, but it is useful for testing DTS with
+ * different OPPs that have assigned-clock rates different than the
+ * ones specified in OPP tuple array. Otherwise we will display
+ * different clock values when the driver is loaded. Further
+ * modifications of the governor will display correctly but not when
+ * the driver has been loaded.
+ */
+ core_freq = priv->imx_gpu_govern.core_clk_freq[priv->imx_gpu_govern.current_mode];
+ shader_freq = priv->imx_gpu_govern.shader_clk_freq[priv->imx_gpu_govern.current_mode];
+
+ if (core_freq && shader_freq) {
+ for (; core <= gcvCORE_3D_MAX; core++) {
+ clk_core = priv->imx_gpu_clks[core].clk_core;
+ clk_shader = priv->imx_gpu_clks[core].clk_shader;
+
+ if (clk_core != NULL && clk_shader != NULL) {
+ clk_set_rate(clk_core, core_freq);
+ clk_set_rate(clk_shader, shader_freq);
+ }
+ }
+ }
+
+ }
+
+ return ret;
+}
+
+int remove_gpu_opp_table(void)
+{
+ struct imx_priv *priv = &imxPriv;
+ struct device* dev = priv->imx_gpu_govern.dev;
+ int i = 0;
+ int max_modes;
+
+ if (priv->imx_gpu_govern.num_modes == GOVERN_COUNT)
+ max_modes = priv->imx_gpu_govern.num_modes - 1;
+ else
+ max_modes = priv->imx_gpu_govern.num_modes;
+
+ /* if we don't have any modes available we don't have OPP */
+ if (max_modes == 0)
+ return 0;
+
+ for (i = priv->imx_gpu_govern.current_mode; i <= max_modes; i++)
+ {
+ unsigned long core_freq;
+
+ core_freq = priv->imx_gpu_govern.core_clk_freq[i];
+ dev_pm_opp_remove(dev, core_freq);
+ }
+
+ if (i > 0)
+ {
+ driver_remove_file(dev->driver, &driver_attr_gpu_govern);
+ }
+
+ return 0;
+}
+#endif
+
+#ifdef IMX_GPU_SUBSYSTEM
+
+static int use_imx_gpu_subsystem;
+
+/* sub device component ops. */
+static int mxc_gpu_sub_bind(struct device *dev,
+ struct device *master, void *data)
+{
+ return 0;
+}
+
+static void mxc_gpu_sub_unbind(struct device *dev, struct device *master,
+ void *data)
+{
+}
+
+static const struct component_ops mxc_gpu_sub_ops =
+{
+ .bind = mxc_gpu_sub_bind,
+ .unbind = mxc_gpu_sub_unbind,
+};
+
+/* sub device driver. */
+static const struct of_device_id mxc_gpu_sub_match[] =
+{
+ { .compatible = "fsl,imx8-gpu"},
+ { /* sentinel */ }
+};
+
+static int mxc_gpu_sub_probe(struct platform_device *pdev)
+{
+ return component_add(&pdev->dev, &mxc_gpu_sub_ops);
+}
+
+static int mxc_gpu_sub_remove(struct platform_device *pdev)
+{
+ component_del(&pdev->dev, &mxc_gpu_sub_ops);
+ return 0;
+}
+
+struct platform_driver mxc_gpu_sub_driver =
+{
+ .driver = {
+ .name = "mxc-gpu",
+ .owner = THIS_MODULE,
+ .of_match_table = mxc_gpu_sub_match,
+ },
+
+ .probe = mxc_gpu_sub_probe,
+ .remove = mxc_gpu_sub_remove,
+};
+
+static int register_mxc_gpu_sub_driver(void)
+{
+ return use_imx_gpu_subsystem ? platform_driver_register(&mxc_gpu_sub_driver) : 0;
+}
+
+static void unregister_mxc_gpu_sub_driver(void)
+{
+ if (use_imx_gpu_subsystem) {
+ platform_driver_unregister(&mxc_gpu_sub_driver);
+ }
+}
+
+static int patch_param_imx8_subsystem(struct platform_device *pdev,
+ gcsMODULE_PARAMETERS *args)
+{
+ int i = 0;
+ struct resource* res;
+ struct device_node *node = pdev->dev.of_node;
+ struct device_node *core_node;
+ int core = gcvCORE_MAJOR;
+
+ while ((core_node = of_parse_phandle(node, "cores", i++)) != NULL) {
+ struct platform_device *pdev_gpu;
+ int irqLine = -1;
+
+ if (!of_device_is_available(core_node)) {
+ of_node_put(core_node);
+ continue;
+ }
+
+ pdev_gpu = of_find_device_by_node(core_node);
+
+ if (!pdev_gpu)
+ break;
+
+ irqLine = platform_get_irq(pdev_gpu, 0);
+
+ if (irqLine < 0)
+ break;
+
+ res = platform_get_resource(pdev_gpu, IORESOURCE_MEM, 0);
+
+ if (!res)
+ break;
+
+ args->irqs[core] = irqLine;
+ args->registerBases[core] = res->start;
+ args->registerSizes[core] = res->end - res->start + 1;
+
+ of_node_put(core_node);
+ ++core;
+ }
+
+ if (core_node)
+ of_node_put(core_node);
+
+ return 0;
+}
+
+static inline int get_power_imx8_subsystem(struct device *pdev)
+{
+ struct imx_priv *priv = &imxPriv;
+ struct clk *clk_core = NULL;
+ struct clk *clk_shader = NULL;
+ struct clk *clk_axi = NULL;
+
+ /* Initialize the clock structure */
+ int i = 0;
+ struct device_node *node = pdev->of_node;
+ struct device_node *core_node;
+ int core = gcvCORE_MAJOR;
+
+#if defined(IMX8_SCU_CONTROL)
+ sc_err_t sciErr;
+ uint32_t mu_id;
+
+ sciErr = sc_ipc_getMuID(&mu_id);
+
+ if (sciErr != SC_ERR_NONE) {
+ printk("galcore; cannot obtain mu id\n");
+ return -EINVAL;
+ }
+
+ sciErr = sc_ipc_open(&gpu_ipcHandle, mu_id);
+
+ if (sciErr != SC_ERR_NONE) {
+ printk("galcore: cannot open MU channel to SCU\n");
+ return -EINVAL;
+ }
+#endif
+
+ while ((core_node = of_parse_phandle(node, "cores", i++)) != NULL) {
+ struct platform_device *pdev_gpu = NULL;
+ clk_shader = NULL;
+ clk_core = NULL;
+ clk_axi = NULL;
+
+ if (!of_device_is_available(core_node)) {
+ of_node_put(core_node);
+ continue;
+ }
+
+ pdev_gpu = of_find_device_by_node(core_node);
+
+ if (!pdev_gpu)
+ break;
+
+ clk_core = clk_get(&pdev_gpu->dev, "core");
+
+ if (IS_ERR(clk_core)) {
+ printk("galcore: clk_get clk_core failed\n");
+ break;
+ }
+
+ clk_axi = clk_get(&pdev_gpu->dev, "bus");
+
+ if (IS_ERR(clk_axi))
+ clk_axi = NULL;
+
+ clk_shader = clk_get(&pdev_gpu->dev, "shader");
+
+ if (IS_ERR(clk_shader)) {
+ printk("galcore: clk_get clk_3d_shader failed\n");
+ continue;
+ }
+
+#if defined(CONFIG_ANDROID) && LINUX_VERSION_CODE < KERNEL_VERSION(4,9,0)
+ /* TODO: freescale BSP issue in some platform like imx8dv. */
+ clk_prepare(clk_core);
+ clk_set_rate(clk_core, 800000000);
+ clk_unprepare(clk_core);
+
+ clk_prepare(clk_shader);
+ clk_set_rate(clk_shader, 800000000);
+ clk_unprepare(clk_shader);
+#endif
+
+ priv->imx_gpu_clks[core].clk_shader = clk_shader;
+ priv->imx_gpu_clks[core].clk_core = clk_core;
+ priv->imx_gpu_clks[core].clk_axi = clk_axi;
+
+#if defined(IMX8_SCU_CONTROL)
+ if (of_property_read_u32(core_node, "fsl,sc_gpu_pid", &priv->sc_gpu_pid[core])) {
+ priv->sc_gpu_pid[core] = 0;
+ }
+#endif
+
+#ifdef CONFIG_PM
+ pm_runtime_get_noresume(&pdev_gpu->dev);
+ pm_runtime_set_active(&pdev_gpu->dev);
+ pm_runtime_enable(&pdev_gpu->dev);
+ pm_runtime_put_sync(&pdev_gpu->dev);
+ priv->pmdev[core] = &pdev_gpu->dev;
+#endif
+ of_node_put(core_node);
+ ++core;
+ }
+
+ priv->gpu3dCount = core;
+
+ if (core_node)
+ of_node_put(core_node);
+
+ return 0;
+}
+
+#endif
+
+static int patch_param_imx6(struct platform_device *pdev,
+ gcsMODULE_PARAMETERS *args)
+{
+ struct resource* res;
+
+ res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "irq_3d");
+
+ if (res)
+ args->irqLine = res->start;
+
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "iobase_3d");
+
+ if (res) {
+ args->registerMemBase = res->start;
+ args->registerMemSize = res->end - res->start + 1;
+ }
+
+ res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "irq_2d");
+
+ if (res)
+ args->irqLine2D = res->start;
+
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "iobase_2d");
+
+ if (res) {
+ args->registerMemBase2D = res->start;
+ args->registerMemSize2D = res->end - res->start + 1;
+ }
+
+ res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "irq_vg");
+
+ if (res)
+ args->irqLineVG = res->start;
+
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "iobase_vg");
+
+ if (res) {
+ args->registerMemBaseVG = res->start;
+ args->registerMemSizeVG = res->end - res->start + 1;
+ }
+
+ return 0;
+}
+
+static int patch_param(struct platform_device *pdev,
+ gcsMODULE_PARAMETERS *args)
+{
+ struct resource* res;
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0)
+ struct device_node *dn =pdev->dev.of_node;
+ const u32 *prop;
+#else
+ struct viv_gpu_platform_data *pdata;
+#endif
+
+ pdevice = pdev;
+
+#ifdef IMX_GPU_SUBSYSTEM
+ if (pdev->dev.of_node && use_imx_gpu_subsystem)
+ patch_param_imx8_subsystem(pdev, args);
+ else
+#endif
+ patch_param_imx6(pdev, args);
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0)
+ if(args->compression == -1)
+ {
+ const u32 *property;
+ args->compression = gcvCOMPRESSION_OPTION_DEFAULT;
+ property = of_get_property(pdev->dev.of_node, "depth-compression", NULL);
+ if (property && *property == 0)
+ {
+ args->compression &= ~gcvCOMPRESSION_OPTION_DEPTH;
+ }
+ }
+#endif
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "phys_baseaddr");
+
+ if (res && !args->baseAddress && !args->physSize) {
+ args->baseAddress = res->start;
+ args->physSize = res->end - res->start + 1;
+ }
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,1,0)
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "contiguous_mem");
+
+ if (res) {
+ if (args->contiguousBase == 0)
+ args->contiguousBase = res->start;
+
+ if (args->contiguousSize == ~0U)
+ args->contiguousSize = res->end - res->start + 1;
+ }
+
+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
+ args->contiguousBase = 0;
+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0)
+ prop = of_get_property(dn, "contiguousbase", NULL);
+
+ if (prop)
+ args->contiguousBase = *prop;
+
+ of_property_read_u32(dn,"contiguoussize", (u32 *)&contiguousSize);
+#else
+
+ pdata = pdev->dev.platform_data;
+
+ if (pdata) {
+ args->contiguousBase = pdata->reserved_mem_base;
+ args->contiguousSize = pdata->reserved_mem_size;
+ }
+
+#endif
+
+ if (args->contiguousSize == ~0U) {
+ printk("Warning: No contiguous memory is reserverd for gpu.!\n");
+ printk("Warning: Will use default value(%d) for the reserved memory!\n", gcdFSL_CONTIGUOUS_SIZE);
+
+ args->contiguousSize = gcdFSL_CONTIGUOUS_SIZE;
+ }
+
+ args->gpu3DMinClock = initgpu3DMinClock;
+
+ if (args->physSize == 0) {
+#if defined(IMX8_PHYS_BASE)
+ args->baseAddress = IMX8_PHYS_BASE;
+#endif
+
+#if defined(IMX8_PHYS_SIZE)
+ args->physSize = IMX8_PHYS_SIZE;
+#else
+ args->physSize = 0x80000000;
+#endif
+ }
+
+ return 0;
+}
+
+int init_priv(void)
+{
+ memset(&imxPriv, 0, sizeof(imxPriv));
+
+#ifdef CONFIG_GPU_LOW_MEMORY_KILLER
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,1,0)
+ task_free_register(&task_nb);
+# else
+ task_handoff_register(&task_nb);
+# endif
+#endif
+
+ return 0;
+}
+
+void
+free_priv(void)
+{
+#ifdef CONFIG_GPU_LOW_MEMORY_KILLER
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,1,0)
+ task_free_unregister(&task_nb);
+# else
+ task_handoff_unregister(&task_nb);
+# endif
+#endif
+}
+
+static int set_clock(int gpu, int enable);
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
+static void imx6sx_optimize_qosc_for_GPU(void)
+{
+ struct device_node *np;
+ void __iomem *src_base;
+
+ np = of_find_compatible_node(NULL, NULL, "fsl,imx6sx-qosc");
+ if (!np)
+ return;
+
+ src_base = of_iomap(np, 0);
+ WARN_ON(!src_base);
+
+ set_clock(gcvCORE_MAJOR, 1);
+
+ writel_relaxed(0, src_base); /* Disable clkgate & soft_rst */
+ writel_relaxed(0, src_base+0x60); /* Enable all masters */
+ writel_relaxed(0, src_base+0x1400); /* Disable clkgate & soft_rst for gpu */
+ writel_relaxed(0x0f000222, src_base+0x1400+0xd0); /* Set Write QoS 2 for gpu */
+ writel_relaxed(0x0f000822, src_base+0x1400+0xe0); /* Set Read QoS 8 for gpu */
+
+ set_clock(gcvCORE_MAJOR, 0);
+ return;
+}
+#endif
+
+static inline int get_power_imx6(struct device *pdev)
+{
+ struct imx_priv *priv = &imxPriv;
+ struct clk *clk_core = NULL;
+ struct clk *clk_shader = NULL;
+ struct clk *clk_axi = NULL;
+ struct clk *clk_ahb = NULL;
+
+#ifdef CONFIG_RESET_CONTROLLER
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
+ struct reset_control *rstc;
+
+ rstc = devm_reset_control_get(pdev, "gpu3d");
+ priv->rstc[gcvCORE_MAJOR] = IS_ERR(rstc) ? NULL : rstc;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,9,0)
+ rstc = devm_reset_control_get_shared(pdev, "gpu2d");
+ priv->rstc[gcvCORE_2D] = IS_ERR(rstc) ? NULL : rstc;
+ rstc = devm_reset_control_get_shared(pdev, "gpuvg");
+# else
+ rstc = devm_reset_control_get(pdev, "gpu2d");
+ priv->rstc[gcvCORE_2D] = IS_ERR(rstc) ? NULL : rstc;
+ rstc = devm_reset_control_get(pdev, "gpuvg");
+# endif
+ priv->rstc[gcvCORE_VG] = IS_ERR(rstc) ? NULL : rstc;
+# endif
+#endif
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,14,0)
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)
+ /* Get gpu regulator */
+ priv->gpu_regulator = regulator_get(pdev, "cpu_vddgpu");
+# elif LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
+ priv->gpu_regulator = devm_regulator_get(pdev, "pu");
+# endif
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0) || LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
+ if (IS_ERR(priv->gpu_regulator)) {
+ printk("%s: Failed to get gpu regulator\n", __FUNCTION__);
+ return -ENXIO;
+ }
+# endif
+#endif
+
+ clk_core = clk_get(pdev, "gpu3d_clk");
+
+ if (!IS_ERR(clk_core)) {
+ clk_axi = clk_get(pdev, "gpu3d_axi_clk");
+ clk_shader = clk_get(pdev, "gpu3d_shader_clk");
+
+ if (IS_ERR(clk_shader)) {
+ clk_put(clk_core);
+ clk_core = NULL;
+ clk_shader = NULL;
+ printk("galcore: clk_get gpu3d_shader_clk failed, disable 3d!\n");
+ }
+
+ clk_ahb = clk_get(pdev, "gpu3d_ahb_clk");
+ if (IS_ERR(clk_ahb)) {
+ clk_ahb = NULL;
+ }
+ } else {
+ clk_core = NULL;
+ printk("galcore: clk_get gpu3d_clk failed, disable 3d!\n");
+ }
+
+ priv->imx_gpu_clks[gcvCORE_MAJOR].clk_core = clk_core;
+ priv->imx_gpu_clks[gcvCORE_MAJOR].clk_shader = clk_shader;
+ priv->imx_gpu_clks[gcvCORE_MAJOR].clk_axi = clk_axi;
+ priv->imx_gpu_clks[gcvCORE_MAJOR].clk_ahb = clk_ahb;
+
+ clk_core = clk_get(pdev, "gpu2d_clk");
+
+ if (IS_ERR(clk_core)) {
+ clk_core = NULL;
+ printk("galcore: clk_get 2d core clock failed, disable 2d/vg!\n");
+ } else {
+ clk_axi = clk_get(pdev, "gpu2d_axi_clk");
+ if (IS_ERR(clk_axi)) {
+ clk_axi = NULL;
+ printk("galcore: clk_get 2d axi clock failed, disable 2d\n");
+ }
+ clk_ahb = clk_get(pdev, "gpu2d_ahb_clk");
+ if (IS_ERR(clk_ahb)) {
+ clk_ahb = NULL;
+ }
+
+ priv->imx_gpu_clks[gcvCORE_2D].clk_ahb = clk_ahb;
+ priv->imx_gpu_clks[gcvCORE_2D].clk_core = clk_core;
+ priv->imx_gpu_clks[gcvCORE_2D].clk_axi = clk_axi;
+
+ clk_axi = clk_get(pdev, "openvg_axi_clk");
+
+ if (IS_ERR(clk_axi)) {
+ clk_axi = NULL;
+ printk("galcore: clk_get vg clock failed, disable vg!\n");
+ }
+
+ priv->imx_gpu_clks[gcvCORE_VG].clk_core = clk_core;
+ priv->imx_gpu_clks[gcvCORE_VG].clk_axi = clk_axi;
+ }
+
+#ifdef CONFIG_PM
+ pm_runtime_enable(pdev);
+
+ priv->pmdev[gcvCORE_MAJOR] = pdev;
+ priv->pmdev[gcvCORE_2D] = pdev;
+ priv->pmdev[gcvCORE_VG] = pdev;
+#endif
+
+ return 0;
+}
+
+static inline int get_power(struct device *pdev)
+{
+ int ret;
+
+ /*Initialize the clock structure*/
+#ifdef IMX_GPU_SUBSYSTEM
+ if (pdev->of_node && use_imx_gpu_subsystem)
+ ret = get_power_imx8_subsystem(pdev);
+ else
+#endif
+ ret = get_power_imx6(pdev);
+
+ if (ret)
+ return ret;
+
+#if gcdENABLE_FSCALE_VAL_ADJUST && (defined(CONFIG_DEVICE_THERMAL) || defined(CONFIG_DEVICE_THERMAL_MODULE))
+ REG_THERMAL_NOTIFIER(&thermal_hot_pm_notifier);
+
+ ret = driver_create_file(pdev->driver, &driver_attr_gpu3DMinClock);
+
+ if (ret)
+ dev_err(pdev, "create gpu3DMinClock attr failed (%d)\n", ret);
+#endif
+
+#if defined(CONFIG_PM_OPP)
+ ret = init_gpu_opp_table(pdev);
+ if (ret)
+ dev_err(pdev, "OPP init failed!\n");
+#endif
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
+ imx6sx_optimize_qosc_for_GPU();
+#endif
+
+ return 0;
+}
+
+static inline void put_power(void)
+{
+ int core = 0;
+ struct gpu_clk *imx_clk = NULL;
+ struct imx_priv *priv = &imxPriv;
+ struct device *pmdev_last = NULL;/*legacy gpu device entry for imx6*/
+ struct clk *clk_core_last = NULL;/*vg has same core clk as 2d */
+
+ for (core = 0; core < gcdMAX_GPU_COUNT; core++) {
+ imx_clk = &priv->imx_gpu_clks[core];
+
+ if (imx_clk->clk_core && imx_clk->clk_core != clk_core_last) {
+ clk_put(imx_clk->clk_core);
+ clk_core_last = imx_clk->clk_core;
+ imx_clk->clk_core = NULL;
+ }
+
+ if (imx_clk->clk_shader) {
+ clk_put(imx_clk->clk_shader);
+ imx_clk->clk_shader = NULL;
+ }
+
+ if (imx_clk->clk_axi) {
+ clk_put(imx_clk->clk_axi);
+ imx_clk->clk_axi = NULL;
+ }
+
+ if (imx_clk->clk_ahb) {
+ clk_put(imx_clk->clk_ahb);
+ imx_clk->clk_ahb = NULL;
+ }
+
+#ifdef CONFIG_PM
+ if (priv->pmdev[core] && priv->pmdev[core] != pmdev_last){
+ pm_runtime_disable(priv->pmdev[core]);
+ pmdev_last = priv->pmdev[core];
+ }
+#endif
+ }
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)
+ if (priv->gpu_regulator) {
+ regulator_put(priv->gpu_regulator);
+ priv->gpu_regulator = NULL;
+ }
+#endif
+
+#if gcdENABLE_FSCALE_VAL_ADJUST && (defined(CONFIG_DEVICE_THERMAL) || defined(CONFIG_DEVICE_THERMAL_MODULE))
+ UNREG_THERMAL_NOTIFIER(&thermal_hot_pm_notifier);
+
+ driver_remove_file(pdevice->dev.driver, &driver_attr_gpu3DMinClock);
+#endif
+
+#if defined(CONFIG_PM_OPP)
+ remove_gpu_opp_table();
+#endif
+
+#if defined(IMX8_SCU_CONTROL)
+ if (gpu_ipcHandle)
+ sc_ipc_close(gpu_ipcHandle);
+#endif
+}
+
+static inline int set_power(int gpu, int enable)
+{
+#ifdef CONFIG_PM
+ struct imx_priv* priv = &imxPriv;
+#endif
+
+ if (enable) {
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,14,0)
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0) || LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
+ if (!IS_ERR(priv->gpu_regulator)) {
+ int ret = regulator_enable(priv->gpu_regulator);
+
+ if (ret)
+ printk("%s: fail to enable pu regulator %d!\n", __FUNCTION__, ret);
+ }
+# else
+ imx_gpc_power_up_pu(true);
+# endif
+#endif
+
+#ifdef CONFIG_PM
+ pm_runtime_get_sync(priv->pmdev[gpu]);
+#endif
+
+#if defined(IMX8_SCU_CONTROL)
+ if (priv->sc_gpu_pid[gpu]) {
+ sc_err_t sciErr = sc_misc_set_control(gpu_ipcHandle, priv->sc_gpu_pid[gpu], SC_C_ID, gpu);
+ if (sciErr != SC_ERR_NONE)
+ printk("galcore: failed to set gpu id for 3d_%d\n", gpu);
+
+ if (priv->gpu3dCount > 1) {
+ sciErr = sc_misc_set_control(gpu_ipcHandle, priv->sc_gpu_pid[gpu], SC_C_SINGLE_MODE, 0);
+ if (sciErr != SC_ERR_NONE)
+ printk("galcore: failed to set gpu dual mode for 3d_%d\n", gpu);
+ } else {
+ sciErr = sc_misc_set_control(gpu_ipcHandle, priv->sc_gpu_pid[gpu], SC_C_SINGLE_MODE, 1);
+ if (sciErr != SC_ERR_NONE)
+ printk("galcore: failed to set gpu single mode for 3d_%d\n", gpu);
+ }
+ }
+#endif
+ } else {
+#ifdef CONFIG_PM
+ pm_runtime_put_sync(priv->pmdev[gpu]);
+#endif
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,14,0)
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0) || LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
+ if (!IS_ERR(priv->gpu_regulator))
+ regulator_disable(priv->gpu_regulator);
+# else
+ imx_gpc_power_up_pu(false);
+# endif
+#endif
+ }
+
+ return 0;
+}
+
+int set_clock(int gpu, int enable)
+{
+ struct imx_priv* priv = &imxPriv;
+ struct clk *clk_core = priv->imx_gpu_clks[gpu].clk_core;
+ struct clk *clk_shader = priv->imx_gpu_clks[gpu].clk_shader;
+ struct clk *clk_axi = priv->imx_gpu_clks[gpu].clk_axi;
+ struct clk *clk_ahb = priv->imx_gpu_clks[gpu].clk_ahb;
+
+ if (enable) {
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0)
+ if (clk_core)
+ clk_prepare(clk_core);
+
+ if (clk_shader)
+ clk_prepare(clk_shader);
+
+ if (clk_axi)
+ clk_prepare(clk_axi);
+
+ if (clk_ahb)
+ clk_prepare(clk_ahb);
+#endif
+ if (clk_core)
+ clk_enable(clk_core);
+
+ if (clk_shader)
+ clk_enable(clk_shader);
+
+ if (clk_axi)
+ clk_enable(clk_axi);
+
+ if (clk_ahb)
+ clk_enable(clk_ahb);
+ } else {
+ if (clk_core)
+ clk_disable(clk_core);
+
+ if (clk_shader)
+ clk_disable(clk_shader);
+
+ if (clk_axi)
+ clk_disable(clk_axi);
+
+ if (clk_ahb)
+ clk_disable(clk_ahb);
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0)
+ if (clk_core)
+ clk_unprepare(clk_core);
+
+ if (clk_shader)
+ clk_unprepare(clk_shader);
+
+ if (clk_axi)
+ clk_unprepare(clk_axi);
+
+ if (clk_ahb)
+ clk_unprepare(clk_ahb);
+#endif
+ }
+
+ return gcvSTATUS_OK;
+}
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0)
+#ifdef CONFIG_PM
+static int gpu_runtime_suspend(struct device *dev)
+{
+ release_bus_freq(BUS_FREQ_HIGH);
+ return 0;
+}
+
+static int gpu_runtime_resume(struct device *dev)
+{
+ request_bus_freq(BUS_FREQ_HIGH);
+ return 0;
+}
+
+static struct dev_pm_ops gpu_pm_ops;
+#endif
+#endif
+
+
+static int adjust_platform_driver(struct platform_driver *driver)
+{
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0)
+ driver->driver.of_match_table = mxs_gpu_dt_ids;
+#endif
+
+#ifdef CONFIG_PM
+ /* Override PM callbacks to add runtime PM callbacks. */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0)
+ /* Fill local structure with original value. */
+ memcpy(&gpu_pm_ops, driver->driver.pm, sizeof(struct dev_pm_ops));
+
+ /* Add runtime PM callback. */
+#ifdef CONFIG_PM
+ gpu_pm_ops.runtime_suspend = gpu_runtime_suspend;
+ gpu_pm_ops.runtime_resume = gpu_runtime_resume;
+ gpu_pm_ops.runtime_idle = NULL;
+#endif
+
+ /* Replace callbacks. */
+ driver->driver.pm = &gpu_pm_ops;
+#endif
+#endif
+
+ return 0;
+}
+
+#define SRC_SCR_OFFSET 0
+#define BP_SRC_SCR_GPU3D_RST 1
+#define BP_SRC_SCR_GPU2D_RST 4
+
+static inline int reset_gpu(int gpu)
+{
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)
+ void __iomem *src_base = IO_ADDRESS(SRC_BASE_ADDR);
+ uint32_t bit_offset, val;
+
+ if (gpu == gcvCORE_MAJOR)
+ bit_offset = BP_SRC_SCR_GPU3D_RST;
+ else if ((gpu == gcvCORE_VG) ||(gpu == gcvCORE_2D))
+ bit_offset = BP_SRC_SCR_GPU2D_RST;
+ else
+ return -ENXIO;
+
+ val = __raw_readl(src_base + SRC_SCR_OFFSET);
+ val &= ~(1 << (bit_offset));
+ val |= (1 << (bit_offset));
+ __raw_writel(val, src_base + SRC_SCR_OFFSET);
+
+ while ((__raw_readl(src_base + SRC_SCR_OFFSET) & (1 << (bit_offset))) != 0);
+
+ return -ENODEV;
+
+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
+ struct imx_priv* priv = &imxPriv;
+ struct reset_control *rstc = priv->rstc[gpu];
+
+ if (rstc)
+ reset_control_reset(rstc);
+#else
+ imx_src_reset_gpu((int)gpu);
+#endif
+
+ return 0;
+}
+
+static gceSTATUS
+_AdjustParam(
+ gcsPLATFORM * Platform,
+ gcsMODULE_PARAMETERS *Args
+ )
+{
+ patch_param(Platform->device, Args);
+
+ if (of_find_compatible_node(NULL, NULL, "fsl,imx8mq-gpu") &&
+ ((Args->baseAddress + totalram_pages * PAGE_SIZE) > 0x100000000))
+ {
+ Platform->flagBits |= gcvPLATFORM_FLAG_LIMIT_4G_ADDRESS;
+ }
+
+ if (of_find_compatible_node(NULL, NULL, "fsl,imx8mm-gpu"))
+ {
+ Platform->flagBits |= gcvPLATFORM_FLAG_IMX_MM;
+ }
+ return gcvSTATUS_OK;
+}
+
+static gceSTATUS
+_GetPower(
+ gcsPLATFORM * Platform
+ )
+{
+ int ret = get_power(&Platform->device->dev);
+
+ if (ret)
+ return gcvSTATUS_GENERIC_IO;
+
+ return gcvSTATUS_OK;
+}
+
+static gceSTATUS
+_PutPower(
+ gcsPLATFORM * Platform
+ )
+{
+ put_power();
+ return gcvSTATUS_OK;
+}
+
+
+static gceSTATUS
+_SetPower(
+ gcsPLATFORM * Platform,
+ gceCORE GPU,
+ gctBOOL Enable
+ )
+{
+ return set_power((int)GPU, Enable) ? gcvSTATUS_GENERIC_IO
+ : gcvSTATUS_OK;
+}
+
+static gceSTATUS
+_SetClock(
+ gcsPLATFORM * Platform,
+ gceCORE GPU,
+ gctBOOL Enable
+ )
+{
+ set_clock((int)GPU, Enable);
+ return gcvSTATUS_OK;
+}
+
+static gceSTATUS
+_Reset(
+ gcsPLATFORM * Platform,
+ gceCORE GPU
+ )
+{
+ int ret;
+
+ ret = reset_gpu((int)GPU);
+
+ if (!ret)
+ return gcvSTATUS_OK;
+ else if (ret == -ENODEV)
+ return gcvSTATUS_NOT_SUPPORTED;
+ else
+ return gcvSTATUS_INVALID_CONFIG;
+}
+
+struct soc_platform_ops imx_platform_ops =
+{
+ .adjustParam = _AdjustParam,
+ .getPower = _GetPower,
+ .putPower = _PutPower,
+ .setPower = _SetPower,
+ .setClock = _SetClock,
+ .reset = _Reset,
+#ifdef CONFIG_GPU_LOW_MEMORY_KILLER
+ .shrinkMemory = _ShrinkMemory,
+#endif
+};
+
+static struct soc_platform imx_platform =
+{
+ .name = __FILE__,
+ .ops = &imx_platform_ops,
+};
+
+int soc_platform_init(struct platform_driver *pdrv,
+ struct soc_platform **platform)
+{
+#ifdef IMX_GPU_SUBSYSTEM
+ if (of_find_compatible_node(NULL, NULL, "fsl,imx8-gpu-ss")) {
+ use_imx_gpu_subsystem = 1;
+
+ if (!of_find_compatible_node(NULL, NULL, "fsl,imx8-gpu")) {
+ printk(KERN_ERR "Incorrect device-tree, please update dtb.");
+ return -EINVAL;
+ }
+ }
+#endif
+
+ adjust_platform_driver(pdrv);
+ init_priv();
+
+#ifdef IMX_GPU_SUBSYSTEM
+ register_mxc_gpu_sub_driver();
+#endif
+
+ *platform = &imx_platform;
+ return 0;
+}
+
+int soc_platform_terminate(struct soc_platform *platform)
+{
+#ifdef IMX_GPU_SUBSYSTEM
+ unregister_mxc_gpu_sub_driver();
+#endif
+
+ free_priv();
+ return 0;
+}
+
diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/platform/freescale/gc_hal_kernel_platform_imx.config b/drivers/mxc/gpu-viv/hal/os/linux/kernel/platform/freescale/gc_hal_kernel_platform_imx.config
new file mode 100644
index 000000000000..56fcc26cffcd
--- /dev/null
+++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/platform/freescale/gc_hal_kernel_platform_imx.config
@@ -0,0 +1,29 @@
+EXTRA_CFLAGS += -DgcdDEFAULT_CONTIGUOUS_SIZE=~0U
+EXTRA_CFLAGS += -DgcdFSL_CONTIGUOUS_SIZE=134217728
+
+ifneq ($(CONFIG_ANDROID),)
+# build for android
+EXTRA_CFLAGS += -DgcdANDROID
+endif
+
+EXTRA_CFLAGS += -DgcdANDROID_NATIVE_FENCE_SYNC=2
+
+ifeq ($(CONFIG_SYNC)$(CONFIG_SYNC_FILE),)
+$(warn CONFIG_SYNC or CONFIG_SYNC_FILE is not set in kernel config)
+$(warn Android native fence sync requires CONFIG_SYNC or CONFIG_SYNC_FILE)
+endif
+
+ifneq ($(CONFIG_ARCH_FSL_IMX8QM),)
+EXTRA_CFLAGS += -DIMX8_SCU_CONTROL=1 -DIMX8_PHYS_BASE=0x80000000 -DIMX8_PHYS_SIZE=0x80000000
+endif
+
+EXTRA_CFLAGS += -DLINUX_CMA_FSL=1
+ALLOCATOR_ARRAY_H_LOCATION := $(OS_KERNEL_DIR)/allocator/freescale
+CUSTOMER_ALLOCATOR_OBJS := $(ALLOCATOR_ARRAY_H_LOCATION)/gc_hal_kernel_allocator_cma.o
+
+EXTRA_CFLAGS += -DCLASS_NAME=\"gpu_class\"
+
+EXTRA_CFLAGS += -DgcdGPU_2D_TIMEOUT=20000
+EXTRA_CFLAGS += -DNO_DMA_COHERENT=1
+EXTRA_CFLAGS += -DgcdSYS_FREE_MEMORY_LIMIT=51200
+
diff --git a/drivers/mxc/gpu-viv/hal/security_v1/gc_hal_ta.c b/drivers/mxc/gpu-viv/hal/security_v1/gc_hal_ta.c
new file mode 100644
index 000000000000..7b677e43a543
--- /dev/null
+++ b/drivers/mxc/gpu-viv/hal/security_v1/gc_hal_ta.c
@@ -0,0 +1,348 @@
+/****************************************************************************
+*
+* The MIT License (MIT)
+*
+* Copyright (c) 2014 - 2018 Vivante 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 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 GPL License (GPL)
+*
+* Copyright (C) 2014 - 2018 Vivante 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.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+*****************************************************************************
+*
+* Note: This software is released under dual MIT and GPL licenses. A
+* recipient may use this file under the terms of either the MIT license or
+* GPL License. If you wish to use only one license not the other, you can
+* indicate your decision by deleting one of the above license notices in your
+* version of this file.
+*
+*****************************************************************************/
+
+
+#include "gc_hal_types.h"
+#include "gc_hal_base.h"
+#include "gc_hal_security_interface.h"
+#include "gc_hal_ta.h"
+#include "gc_hal.h"
+
+#define _GC_OBJ_ZONE gcvZONE_KERNEL
+
+/*
+* Responsibility of TA (trust application).
+* 1) Start FE.
+* When non secure driver asks for start FE. TA enable MMU and start FE.
+* TA always execute MMU enable processes because it has no idea whether
+* GPU has been power off.
+*
+* 2) Setup page table
+* When non secure driver asks for set up GPU address to physical address
+* mapping, TA check the attribute of physical address and attribute of
+* GPU address to make sure they are match. Then it change page table.
+*
+*/
+
+gcTA_MMU SharedMmu = gcvNULL;
+
+/*******************************************************************************
+**
+** gcTA_Construct
+**
+** Construct a new gcTA object.
+*/
+int
+gcTA_Construct(
+ IN gctaOS Os,
+ IN gceCORE Core,
+ OUT gcTA *TA
+ )
+{
+ gceSTATUS status;
+ gctPOINTER pointer;
+ gcTA ta = gcvNULL;
+
+ gcmkHEADER();
+ gcmkVERIFY_ARGUMENT(TA != gcvNULL);
+
+ /* Construct a gcTA object. */
+ gcmkONERROR(gctaOS_Allocate(sizeof(struct _gcTA), &pointer));
+
+ gctaOS_ZeroMemory(pointer, sizeof(struct _gcTA));
+
+ ta = (gcTA)pointer;
+
+ ta->os = Os;
+ ta->core = Core;
+
+ gcmkONERROR(gctaHARDWARE_Construct(ta, &ta->hardware));
+
+ if (gctaHARDWARE_IsFeatureAvailable(ta->hardware, gcvFEATURE_SECURITY))
+ {
+ if (SharedMmu == gcvNULL)
+ {
+ gcmkONERROR(gctaMMU_Construct(ta, &ta->mmu));
+
+ /* Record shared MMU. */
+ SharedMmu = ta->mmu;
+ ta->destoryMmu = gcvTRUE;
+ }
+ else
+ {
+ ta->mmu = SharedMmu;
+ ta->destoryMmu = gcvFALSE;
+ }
+
+ gcmkONERROR(gctaHARDWARE_PrepareFunctions(ta->hardware));
+ }
+
+ *TA = ta;
+
+ gcmkFOOTER_NO();
+ return 0;
+
+OnError:
+ if (ta)
+ {
+ if (ta->mmu && ta->destoryMmu)
+ {
+ gcmkVERIFY_OK(gctaMMU_Destory(ta->mmu));
+ }
+
+ if (ta->hardware)
+ {
+ gcmkVERIFY_OK(gctaHARDWARE_Destroy(ta->hardware));
+ }
+
+ gcmkVERIFY_OK(gctaOS_Free(ta));
+ }
+ gcmkFOOTER();
+ return status;
+}
+
+/*******************************************************************************
+**
+** gcTA_Construct
+**
+** Destroy a gcTA object.
+*/
+int
+gcTA_Destroy(
+ IN gcTA TA
+ )
+{
+ if (TA->mmu && TA->destoryMmu)
+ {
+ gcmkVERIFY_OK(gctaMMU_Destory(TA->mmu));
+ }
+
+ if (TA->hardware)
+ {
+ gcmkVERIFY_OK(gctaHARDWARE_Destroy(TA->hardware));
+ }
+
+ gcmkVERIFY_OK(gctaOS_Free(TA));
+
+ /* Destroy. */
+ return 0;
+}
+
+
+/*
+* Map a scatter gather list into gpu address space.
+*
+*/
+gceSTATUS
+gcTA_MapMemory(
+ IN gcTA TA,
+ IN gctUINT32 *PhysicalArray,
+ IN gctPHYS_ADDR_T Physical,
+ IN gctUINT32 PageCount,
+ OUT gctUINT32 *GPUAddress
+ )
+{
+ gceSTATUS status;
+ gcTA_MMU mmu;
+ gctUINT32 pageCount = PageCount;
+ gctUINT32 i;
+ gctUINT32 gpuAddress = *GPUAddress;
+ gctBOOL mtlbSecure = gcvFALSE;
+ gctBOOL physicalSecure = gcvFALSE;
+
+ mmu = TA->mmu;
+
+ /* Fill in page table. */
+ for (i = 0; i < pageCount; i++)
+ {
+ gctUINT32 physical;
+ gctUINT32_PTR entry;
+
+ if (PhysicalArray)
+ {
+ physical = PhysicalArray[i];
+ }
+ else
+ {
+ physical = (gctUINT32)Physical + 4096 * i;
+ }
+
+ gcmkONERROR(gctaMMU_GetPageEntry(mmu, gpuAddress, gcvNULL, &entry, &mtlbSecure));
+
+ status = gctaOS_IsPhysicalSecure(TA->os, physical, &physicalSecure);
+
+ if (gcmIS_SUCCESS(status) && physicalSecure != mtlbSecure)
+ {
+ gcmkONERROR(gcvSTATUS_NOT_SUPPORTED);
+ }
+
+ gctaMMU_SetPage(mmu, physical, entry);
+
+ gpuAddress += 4096;
+ }
+
+ return gcvSTATUS_OK;
+
+OnError:
+ return status;
+}
+
+gceSTATUS
+gcTA_UnmapMemory(
+ IN gcTA TA,
+ IN gctUINT32 GPUAddress,
+ IN gctUINT32 PageCount
+ )
+{
+ gceSTATUS status;
+
+ gcmkONERROR(gctaMMU_FreePages(TA->mmu, GPUAddress, PageCount));
+
+ return gcvSTATUS_OK;
+
+OnError:
+ return status;
+}
+
+gceSTATUS
+gcTA_StartCommand(
+ IN gcTA TA,
+ IN gctUINT32 Address,
+ IN gctUINT32 Bytes
+ )
+{
+ gctaHARDWARE_Execute(TA, Address, Bytes);
+ return gcvSTATUS_OK;
+}
+
+int
+gcTA_Dispatch(
+ IN gcTA TA,
+ IN gcsTA_INTERFACE * Interface
+ )
+{
+ int command = Interface->command;
+
+ gceSTATUS status = gcvSTATUS_OK;
+
+ switch (command)
+ {
+ case KERNEL_START_COMMAND:
+ /* Enable MMU every time FE starts.
+ ** Because if normal world stop GPU and power off GPU, MMU states is reset.
+ */
+ gcmkONERROR(gctaHARDWARE_SetMMU(TA->hardware, TA->mmu->mtlbLogical));
+
+ gcmkONERROR(gcTA_StartCommand(
+ TA,
+ Interface->u.StartCommand.address,
+ Interface->u.StartCommand.bytes
+ ));
+ break;
+
+ case KERNEL_MAP_MEMORY:
+ gcmkONERROR(gcTA_MapMemory(
+ TA,
+ Interface->u.MapMemory.physicals,
+ Interface->u.MapMemory.physical,
+ Interface->u.MapMemory.pageCount,
+ &Interface->u.MapMemory.gpuAddress
+ ));
+
+ break;
+
+ case KERNEL_UNMAP_MEMORY:
+ status = gcTA_UnmapMemory(
+ TA,
+ Interface->u.UnmapMemory.gpuAddress,
+ Interface->u.UnmapMemory.pageCount
+ );
+ break;
+
+ case KERNEL_DUMP_MMU_EXCEPTION:
+ status = gctaHARDWARE_DumpMMUException(TA->hardware);
+ break;
+
+ case KERNEL_HANDLE_MMU_EXCEPTION:
+ status = gctaHARDWARE_HandleMMUException(
+ TA->hardware,
+ Interface->u.HandleMMUException.mmuStatus,
+ Interface->u.HandleMMUException.physical,
+ Interface->u.HandleMMUException.gpuAddress
+ );
+ break;
+
+ case KERNEL_READ_MMU_EXCEPTION:
+ status = gctaHARDWARE_ReadMMUException(
+ TA->hardware,
+ &Interface->u.ReadMMUException.mmuStatus,
+ &Interface->u.ReadMMUException.mmuException
+ );
+ break;
+
+ default:
+ gcmkASSERT(0);
+
+ status = gcvSTATUS_INVALID_ARGUMENT;
+ break;
+ }
+
+OnError:
+ Interface->result = status;
+
+ return 0;
+}
+
+
+
diff --git a/drivers/mxc/gpu-viv/hal/security_v1/gc_hal_ta.h b/drivers/mxc/gpu-viv/hal/security_v1/gc_hal_ta.h
new file mode 100644
index 000000000000..a29513bd2877
--- /dev/null
+++ b/drivers/mxc/gpu-viv/hal/security_v1/gc_hal_ta.h
@@ -0,0 +1,373 @@
+/****************************************************************************
+*
+* The MIT License (MIT)
+*
+* Copyright (c) 2014 - 2018 Vivante 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 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 GPL License (GPL)
+*
+* Copyright (C) 2014 - 2018 Vivante 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.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+*****************************************************************************
+*
+* Note: This software is released under dual MIT and GPL licenses. A
+* recipient may use this file under the terms of either the MIT license or
+* GPL License. If you wish to use only one license not the other, you can
+* indicate your decision by deleting one of the above license notices in your
+* version of this file.
+*
+*****************************************************************************/
+
+
+#ifndef _GC_HAL_TA_H_
+#define _GC_HAL_TA_H_
+#include "gc_hal_types.h"
+#include "gc_hal_security_interface.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+typedef struct _gctaOS * gctaOS;
+typedef struct _gcTA * gcTA;
+
+typedef struct _gcTA_HARDWARE * gcTA_HARDWARE;
+typedef struct _gcTA_MMU * gcTA_MMU;
+
+/*
+ Trust Application is a object needed to be created as a context in trust zone.
+ One client for a core.
+*/
+typedef struct _gcTA {
+ /* gctaOS object */
+ gctaOS os;
+
+ gceCORE core;
+
+ gcTA_MMU mmu;
+
+ gcTA_HARDWARE hardware;
+
+ gctBOOL destoryMmu;
+} gcsTA;
+
+typedef struct _gcTA_MMU
+{
+ gctaOS os;
+
+ gctSIZE_T mtlbBytes;
+ gctPOINTER mtlbLogical;
+ gctPHYS_ADDR mtlbPhysical;
+
+ gctPOINTER stlbs;
+
+ gctPOINTER safePageLogical;
+ gctPHYS_ADDR safePagePhysical;
+
+ gctPOINTER nonSecureSafePageLogical;
+ gctPHYS_ADDR nonSecureSafePagePhysical;
+
+ gctPOINTER mutex;
+}
+gcsTA_MMU;
+
+gceSTATUS HALDECL
+TAEmulator(
+ gceCORE Core,
+ void * Interface
+ );
+
+int
+gcTA_Construct(
+ IN gctaOS Os,
+ IN gceCORE Core,
+ OUT gcTA *TA
+);
+
+int
+gcTA_Destroy(
+ IN gcTA TA
+);
+
+int
+gcTA_Dispatch(
+ IN gcTA TA,
+ IN OUT gcsTA_INTERFACE * Interface
+);
+
+/*************************************
+* Porting layer
+*/
+
+gceSTATUS
+gctaOS_ConstructOS(
+ IN gckOS Os,
+ OUT gctaOS *TAos
+ );
+
+gceSTATUS
+gctaOS_DestroyOS(
+ IN gctaOS Os
+ );
+
+gceSTATUS
+gctaOS_Allocate(
+ IN gctUINT32 Bytes,
+ OUT gctPOINTER *Pointer
+ );
+
+gceSTATUS
+gctaOS_Free(
+ IN gctPOINTER Pointer
+ );
+
+gceSTATUS
+gctaOS_AllocateSecurityMemory(
+ IN gctaOS Os,
+ IN gctSIZE_T *Bytes,
+ OUT gctPOINTER *Logical,
+ OUT gctPOINTER *Physical
+ );
+
+gceSTATUS
+gctaOS_FreeSecurityMemory(
+ IN gctaOS Os,
+ IN gctSIZE_T Bytes,
+ IN gctPOINTER Logical,
+ OUT gctPOINTER Physical
+ );
+
+gceSTATUS
+gctaOS_AllocateNonSecurityMemory(
+ IN gctaOS Os,
+ IN gctSIZE_T *Bytes,
+ OUT gctPOINTER *Logical,
+ OUT gctPOINTER *Physical
+ );
+
+gceSTATUS
+gctaOS_FreeNonSecurityMemory(
+ IN gctaOS Os,
+ IN gctSIZE_T Bytes,
+ IN gctPOINTER Logical,
+ OUT gctPOINTER Physical
+ );
+
+
+
+gceSTATUS
+gctaOS_GetPhysicalAddress(
+ IN gctaOS Os,
+ IN gctPOINTER Logical,
+ OUT gctPHYS_ADDR_T * Physical
+ );
+
+gceSTATUS gctaOS_WriteRegister(
+ IN gctaOS Os, IN gceCORE Core,
+ IN gctUINT32 Address,
+ IN gctUINT32 Data
+ );
+
+gceSTATUS gctaOS_ReadRegister(
+ IN gctaOS Os, IN gceCORE Core,
+ IN gctUINT32 Address,
+ IN gctUINT32 *Data
+ );
+
+gceSTATUS
+gctaOS_MemCopy(
+ IN gctUINT8_PTR Dest,
+ IN gctUINT8_PTR Src,
+ IN gctUINT32 Bytes
+ );
+
+gceSTATUS
+gctaOS_ZeroMemory(
+ IN gctUINT8_PTR Dest,
+ IN gctUINT32 Bytes
+ );
+
+void
+gctaOS_CacheFlush(
+ IN gctUINT8_PTR Dest,
+ IN gctUINT32 Bytes
+ );
+
+void
+gctaOS_CacheClean(
+ IN gctUINT8_PTR Dest,
+ IN gctUINT32 Bytes
+ );
+
+void
+gctaOS_CacheInvalidate(
+ IN gctUINT8_PTR Dest,
+ IN gctUINT32 Bytes
+ );
+
+gceSTATUS
+gctaOS_IsPhysicalSecure(
+ IN gctaOS Os,
+ IN gctUINT32 Physical,
+ OUT gctBOOL *Secure
+ );
+
+gceSTATUS
+gctaOS_Delay(
+ IN gctaOS Os,
+ IN gctUINT32 Delay
+ );
+
+gceSTATUS
+gctaOS_SetGPUPower(
+ IN gctaOS Os,
+ IN gctUINT32 Core,
+ IN gctBOOL Clock,
+ IN gctBOOL Power
+ );
+
+/*
+** gctaHARDWARE
+*/
+gceSTATUS
+gctaHARDWARE_Construct(
+ IN gcTA TA,
+ OUT gcTA_HARDWARE * Hardware
+ );
+
+gceSTATUS
+gctaHARDWARE_Destroy(
+ IN gcTA_HARDWARE Hardware
+ );
+
+gceSTATUS
+gctaHARDWARE_Execute(
+ IN gcTA TA,
+ IN gctUINT32 Address,
+ IN gctUINT32 Bytes
+ );
+
+gceSTATUS
+gctaHARDWARE_End(
+ IN gcTA_HARDWARE Hardware,
+ IN gctPOINTER Logical,
+ IN OUT gctUINT32 * Bytes
+ );
+
+gceSTATUS
+gctaHARDWARE_SetMMU(
+ IN gcTA_HARDWARE Hardware,
+ IN gctPOINTER Logical
+ );
+
+gceSTATUS
+gctaHARDWARE_IsFeatureAvailable(
+ IN gcTA_HARDWARE Hardware,
+ IN gceFEATURE Feature
+ );
+
+gceSTATUS
+gctaHARDWARE_PrepareFunctions(
+ IN gcTA_HARDWARE Hardware
+ );
+
+gceSTATUS
+gctaHARDWARE_DumpMMUException(
+ IN gcTA_HARDWARE Hardware
+ );
+
+gceSTATUS
+gctaHARDWARE_HandleMMUException(
+ IN gcTA_HARDWARE Hardware,
+ IN gctUINT32 MMUStatus,
+ IN gctPHYS_ADDR_T Physical,
+ IN gctUINT32 GPUAddress
+ );
+
+gceSTATUS
+gctaHARDWARE_ReadMMUException(
+ IN gcTA_HARDWARE Hardware,
+ OUT gctUINT32_PTR MMUStatus,
+ OUT gctUINT32_PTR MMUException
+ );
+
+gceSTATUS
+gctaMMU_Construct(
+ IN gcTA TA,
+ OUT gcTA_MMU *Mmu
+ );
+
+gceSTATUS
+gctaMMU_Destory(
+ IN gcTA_MMU Mmu
+ );
+
+gceSTATUS
+gctaMMU_SetPage(
+ IN gcTA_MMU Mmu,
+ IN gctUINT32 PageAddress,
+ IN gctUINT32 *PageEntry
+ );
+
+gceSTATUS
+gctaMMU_GetPageEntry(
+ IN gcTA_MMU Mmu,
+ IN gctUINT32 Address,
+ OUT gctUINT32_PTR MtlbEntry,
+ OUT gctUINT32_PTR *PageTable,
+ OUT gctBOOL * Secure
+ );
+
+void
+gctaMMU_DumpPagetableEntry(
+ IN gcTA_MMU Mmu,
+ IN gctUINT32 Address
+ );
+
+gceSTATUS
+gctaMMU_FreePages(
+ IN gcTA_MMU Mmu,
+ IN gctUINT32 Address,
+ IN gctUINT32 PageCount
+ );
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+
diff --git a/drivers/mxc/gpu-viv/hal/security_v1/gc_hal_ta_hardware.c b/drivers/mxc/gpu-viv/hal/security_v1/gc_hal_ta_hardware.c
new file mode 100644
index 000000000000..b5369bdd86aa
--- /dev/null
+++ b/drivers/mxc/gpu-viv/hal/security_v1/gc_hal_ta_hardware.c
@@ -0,0 +1,1073 @@
+/****************************************************************************
+*
+* The MIT License (MIT)
+*
+* Copyright (c) 2014 - 2018 Vivante 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 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 GPL License (GPL)
+*
+* Copyright (C) 2014 - 2018 Vivante 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.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+*****************************************************************************
+*
+* Note: This software is released under dual MIT and GPL licenses. A
+* recipient may use this file under the terms of either the MIT license or
+* GPL License. If you wish to use only one license not the other, you can
+* indicate your decision by deleting one of the above license notices in your
+* version of this file.
+*
+*****************************************************************************/
+
+
+#include "gc_hal_types.h"
+#include "gc_hal_base.h"
+#include "gc_hal_security_interface.h"
+#include "gc_hal_ta.h"
+#include "gc_hal_ta_hardware.h"
+#include "gc_hal.h"
+#include "gc_feature_database.h"
+
+
+#define _GC_OBJ_ZONE 1
+#define SRC_MAX 8
+#define RECT_ADDR_OFFSET 3
+
+#define INVALID_ADDRESS ~0U
+
+/******************************************************************************\
+********************************* Support Code *********************************
+\******************************************************************************/
+static gceSTATUS
+_IdentifyHardwareByDatabase(
+ IN gcTA_HARDWARE Hardware
+ )
+{
+ gceSTATUS status;
+ gctUINT32 chipIdentity;
+ gcsFEATURE_DATABASE *database;
+ gctaOS os = Hardware->os;
+
+ gcmkHEADER();
+
+ /***************************************************************************
+ ** Get chip ID and revision.
+ */
+
+ /* Read chip identity register. */
+ gcmkONERROR(gctaOS_ReadRegister(os, Hardware->ta->core, 0x00018, &chipIdentity));
+
+ /* Special case for older graphic cores. */
+ if (((((gctUINT32) (chipIdentity)) >> (0 ?
+ 31:24) & ((gctUINT32) ((((1 ?
+ 31:24) - (0 ?
+ 31:24) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:24) - (0 ?
+ 31:24) + 1)))))) == (0x01 & ((gctUINT32) ((((1 ?
+ 31:24) - (0 ?
+ 31:24) + 1) == 32) ? ~0U : (~(~0U << ((1 ? 31:24) - (0 ? 31:24) + 1))))))))
+ {
+ Hardware->chipModel = gcv500;
+ Hardware->chipRevision = (((((gctUINT32) (chipIdentity)) >> (0 ? 15:12)) & ((gctUINT32) ((((1 ? 15:12) - (0 ? 15:12) + 1) == 32) ? ~0U : (~(~0U << ((1 ? 15:12) - (0 ? 15:12) + 1)))))) );
+ }
+
+ else
+ {
+ /* Read chip identity register. */
+ gcmkONERROR(
+ gctaOS_ReadRegister(os, Hardware->ta->core,
+ 0x00020,
+ (gctUINT32_PTR) &Hardware->chipModel));
+
+ if (((Hardware->chipModel & 0xFF00) == 0x0400)
+ && (Hardware->chipModel != 0x0420)
+ && (Hardware->chipModel != 0x0428))
+ {
+ Hardware->chipModel = (gceCHIPMODEL) (Hardware->chipModel & 0x0400);
+ }
+
+ /* Read CHIP_REV register. */
+ gcmkONERROR(
+ gctaOS_ReadRegister(os, Hardware->ta->core,
+ 0x00024,
+ &Hardware->chipRevision));
+
+ if ((Hardware->chipModel == gcv300)
+ && (Hardware->chipRevision == 0x2201)
+ )
+ {
+ gctUINT32 chipDate;
+ gctUINT32 chipTime;
+
+ /* Read date and time registers. */
+ gcmkONERROR(
+ gctaOS_ReadRegister(os, Hardware->ta->core,
+ 0x00028,
+ &chipDate));
+
+ gcmkONERROR(
+ gctaOS_ReadRegister(os, Hardware->ta->core,
+ 0x0002C,
+ &chipTime));
+
+ if ((chipDate == 0x20080814) && (chipTime == 0x12051100))
+ {
+ /* This IP has an ECO; put the correct revision in it. */
+ Hardware->chipRevision = 0x1051;
+ }
+ }
+
+ gcmkONERROR(
+ gctaOS_ReadRegister(os, Hardware->ta->core,
+ 0x000A8,
+ &Hardware->productID));
+ }
+
+ gcmkVERIFY_OK(gctaOS_ReadRegister(
+ os, Hardware->ta->core,
+ 0x000E8
+,
+ &Hardware->ecoID
+ ));
+
+ gcmkVERIFY_OK(gctaOS_ReadRegister(
+ os, Hardware->ta->core,
+ 0x00030
+,
+ &Hardware->customerID
+ ));
+
+ /***************************************************************************
+ ** Get chip features.
+ */
+
+ database =
+ Hardware->featureDatabase =
+ gcQueryFeatureDB(
+ Hardware->chipModel,
+ Hardware->chipRevision,
+ Hardware->productID,
+ Hardware->ecoID,
+ Hardware->customerID
+ );
+
+ if (database == gcvNULL)
+ {
+ gcmkPRINT("[galcore]: Feature database is not found,"
+ "chipModel=0x%0x, chipRevision=0x%x, productID=0x%x, ecoID=0x%x, customerID=0x%x",
+ Hardware->chipModel,
+ Hardware->chipRevision,
+ Hardware->productID,
+ Hardware->ecoID,
+ Hardware->customerID);
+ gcmkONERROR(gcvSTATUS_NOT_FOUND);
+ }
+
+ /* Success. */
+ gcmkFOOTER();
+ return gcvSTATUS_OK;
+
+OnError:
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+
+gceSTATUS
+gctaHARDWARE_SetMMUStates(
+ IN gcTA_HARDWARE Hardware,
+ IN gctPOINTER MtlbAddress,
+ IN gceMMU_MODE Mode,
+ IN gctPOINTER SafeAddress,
+ IN gctPOINTER Logical,
+ IN OUT gctUINT32 * Bytes
+ )
+{
+ gceSTATUS status;
+ gctUINT32 config;
+ gctUINT32 extMtlb;
+ gctPHYS_ADDR_T physical;
+ gctUINT32_PTR buffer;
+ gctUINT32 reserveBytes = 2 * 4;
+ gcsMMU_TABLE_ARRAY_ENTRY * entry;
+
+ gcmkHEADER_ARG("Hardware=0x%x", Hardware);
+
+ entry = (gcsMMU_TABLE_ARRAY_ENTRY *) Hardware->pagetableArray.logical;
+
+ /* Convert logical address into physical address. */
+ gcmkONERROR(
+ gctaOS_GetPhysicalAddress(Hardware->os, MtlbAddress, &physical));
+
+ config = (gctUINT32)(physical & 0xFFFFFFFF);
+ extMtlb = (gctUINT32)(physical >> 32);
+ /* more than 40bit physical address */
+ if (extMtlb & 0xFFFFFF00)
+ {
+ gcmkONERROR(gcvSTATUS_NOT_SUPPORTED);
+ }
+
+ switch (Mode)
+ {
+ case gcvMMU_MODE_1K:
+ if (config & 0x3FF)
+ {
+ gcmkONERROR(gcvSTATUS_NOT_ALIGNED);
+ }
+
+ config |= ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1))))))) << (0 ?
+ 0:0))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)));
+
+ break;
+
+ case gcvMMU_MODE_4K:
+ if (config & 0xFFF)
+ {
+ gcmkONERROR(gcvSTATUS_NOT_ALIGNED);
+ }
+
+ config |= ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1))))))) << (0 ?
+ 0:0))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)));
+
+ break;
+
+ default:
+ gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
+ }
+
+ if (Logical != gcvNULL)
+ {
+ buffer = Logical;
+
+ /* Setup page table array entry. */
+ entry->low = config;
+ entry->high = extMtlb;
+
+ /* Setup command buffer to load index 0 of page table array. */
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x006B) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
+
+ *buffer++
+ = (((((gctUINT32) (~0U)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) &((((gctUINT32) (~0U)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 16:16) - (0 ?
+ 16:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 16:16) - (0 ?
+ 16:16) + 1))))))) << (0 ?
+ 16:16))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ?
+ 16:16) - (0 ?
+ 16:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 16:16) - (0 ? 16:16) + 1))))))) << (0 ? 16:16))));
+ }
+
+ if (Bytes != gcvNULL)
+ {
+ *Bytes = reserveBytes;
+ }
+
+ /* Return the status. */
+ gcmkFOOTER_NO();
+ return status;
+
+OnError:
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+gceSTATUS
+gctaHARDWARE_End(
+ IN gcTA_HARDWARE Hardware,
+ IN gctPOINTER Logical,
+ IN OUT gctUINT32 * Bytes
+ )
+{
+ gctUINT32_PTR logical = (gctUINT32_PTR) Logical;
+ gceSTATUS status;
+
+ gcmkHEADER_ARG("Hardware=0x%x Logical=0x%x *Bytes=%lu",
+ Hardware, Logical, gcmOPT_VALUE(Bytes));
+
+ /* Verify the arguments. */
+ gcmkVERIFY_ARGUMENT((Logical == gcvNULL) || (Bytes != gcvNULL));
+
+ if (Logical != gcvNULL)
+ {
+ if (*Bytes < 8)
+ {
+ /* Command queue too small. */
+ gcmkONERROR(gcvSTATUS_BUFFER_TOO_SMALL);
+ }
+
+ /* Append END. */
+ logical[0] =
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x02 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)));
+
+ /* Record the count of execution which is finised by this END. */
+ logical[1] =
+ 0;
+
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE, "0x%x: END", Logical);
+ }
+
+ if (Bytes != gcvNULL)
+ {
+ /* Return number of bytes required by the END command. */
+ *Bytes = 8;
+ }
+
+ /* Success. */
+ gcmkFOOTER_ARG("*Bytes=%lu", gcmOPT_VALUE(Bytes));
+ return gcvSTATUS_OK;
+
+OnError:
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+
+gceSTATUS
+gctaHARDWARE_Construct(
+ IN gcTA TA,
+ OUT gcTA_HARDWARE * Hardware
+ )
+{
+ gceSTATUS status;
+ gcTA_HARDWARE hardware = gcvNULL;
+
+ gctaOS os = TA->os;
+
+ gcmkONERROR(gctaOS_Allocate(
+ gcmSIZEOF(gcsTA_HARDWARE),
+ (gctPOINTER *)&hardware
+ ));
+
+ gctaOS_ZeroMemory((gctUINT8_PTR)hardware, gcmSIZEOF(gcsTA_HARDWARE));
+
+ hardware->ta = TA;
+ hardware->os = os;
+
+ hardware->pagetableArray.size = 4096;
+
+ hardware->functionBytes = 4096;
+
+ /* Power on GPU. */
+ gctaOS_SetGPUPower(os, TA->core, gcvTRUE, gcvTRUE);
+
+ /*************************************/
+ /******** Get chip information ******/
+ /*************************************/
+ gctaOS_WriteRegister(
+ hardware->ta->os, hardware->ta->core,
+ 0x00000,
+ 0x00000900
+ );
+
+ gcmkONERROR(_IdentifyHardwareByDatabase(hardware));
+
+ *Hardware = hardware;
+
+ return gcvSTATUS_OK;
+
+OnError:
+ if (hardware)
+ {
+ gctaOS_Free(hardware);
+ }
+
+ return status;
+}
+
+gceSTATUS
+gctaHARDWARE_Destroy(
+ IN gcTA_HARDWARE Hardware
+ )
+{
+ if (Hardware->pagetableArray.logical)
+ {
+ gctaOS_FreeSecurityMemory(
+ Hardware->ta->os,
+ Hardware->pagetableArray.size,
+ Hardware->pagetableArray.logical,
+ (gctUINT32_PTR)Hardware->pagetableArray.physical
+ );
+ }
+
+ if (Hardware->functionLogical)
+ {
+ gctaOS_FreeSecurityMemory(
+ Hardware->ta->os,
+ Hardware->functionBytes,
+ Hardware->functionLogical,
+ (gctUINT32_PTR)Hardware->functionPhysical
+ );
+ }
+
+ gctaOS_Free(Hardware);
+
+ return gcvSTATUS_OK;
+}
+
+gceSTATUS
+gctaHARDWARE_Execute(
+ IN gcTA TA,
+ IN gctUINT32 Address,
+ IN gctUINT32 Bytes
+ )
+{
+ gceSTATUS status;
+ gctUINT32 address = Address, control;
+
+ gcmkHEADER_ARG("Address=0x%x Bytes=%lu",
+ Address, Bytes);
+
+ /* Enable all events. */
+ gcmkONERROR(
+ gctaOS_WriteRegister(TA->os, TA->core, 0x00014, ~0U));
+
+ /* Write address register. */
+ gcmkONERROR(
+ gctaOS_WriteRegister(TA->os, TA->core, 0x00654, address));
+
+ /* Build control register. */
+ control = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 16:16) - (0 ?
+ 16:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 16:16) - (0 ?
+ 16:16) + 1))))))) << (0 ?
+ 16:16))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 16:16) - (0 ?
+ 16:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 16:16) - (0 ? 16:16) + 1))))))) << (0 ? 16:16)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) ((Bytes + 7) >> 3) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+
+ /* Write control register. */
+ gcmkONERROR(
+ gctaOS_WriteRegister(TA->os, TA->core, 0x003A4, control));
+
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
+ "Started command buffer @ 0x%08x",
+ address);
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+gceSTATUS
+gctaHARDWARE_MmuEnable(
+ IN gcTA_HARDWARE Hardware
+ )
+{
+ gctaOS_WriteRegister(
+ Hardware->ta->os, Hardware->ta->core,
+ 0x0018C,
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1))))))) << (0 ?
+ 0:0))) | (((gctUINT32) ((gctUINT32) (1 ) & ((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))));
+
+ return gcvSTATUS_OK;
+}
+
+/*
+* In trust zone, we prepare page table array table and configure base address of
+* it to hardware.
+*/
+gceSTATUS
+gctaHARDWARE_SetMMU(
+ IN gcTA_HARDWARE Hardware,
+ IN gctPOINTER Logical
+ )
+{
+ gcsMMU_TABLE_ARRAY_ENTRY *entry;
+ gcsHARDWARE_FUNCTION *function = &Hardware->functions[0];
+ gctUINT32 delay = 1;
+ gctUINT32 timer = 0;
+ gctUINT32 idle;
+ gctPHYS_ADDR_T mtlbPhysical;
+ gctPHYS_ADDR_T secureSafeAddress;
+ gctPHYS_ADDR_T nonSecureSafeAddress;
+
+ gctaOS_GetPhysicalAddress(Hardware->ta->os, Logical, &mtlbPhysical);
+
+ gctaOS_GetPhysicalAddress(Hardware->ta->os, Hardware->ta->mmu->safePageLogical, &secureSafeAddress);
+
+ gctaOS_GetPhysicalAddress(Hardware->ta->os, Hardware->ta->mmu->nonSecureSafePageLogical, &nonSecureSafeAddress);
+
+ /* not support more than 40bit physical address */
+ if ((secureSafeAddress & 0xFFFFFF0000000000ULL) ||
+ (nonSecureSafeAddress & 0xFFFFFF0000000000ULL))
+ {
+ return (gcvSTATUS_NOT_SUPPORTED);
+ }
+
+ /* Fill entry 0 of page table array. */
+ entry = (gcsMMU_TABLE_ARRAY_ENTRY *)Hardware->pagetableArray.logical;
+
+ entry->low = (gctUINT32)(mtlbPhysical & 0xFFFFFFFF);
+
+ entry->high = (gctUINT32)(mtlbPhysical >> 32)
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 8:8) - (0 ?
+ 8:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 8:8) - (0 ?
+ 8:8) + 1))))))) << (0 ?
+ 8:8))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 8:8) - (0 ?
+ 8:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 8:8) - (0 ? 8:8) + 1))))))) << (0 ? 8:8)))
+ ;
+
+ /* Set page table base. */
+ gctaOS_WriteRegister(
+ Hardware->ta->os, Hardware->ta->core,
+ 0x0038C,
+ (gctUINT32)(Hardware->pagetableArray.address & 0xFFFFFFFF)
+ );
+
+ gctaOS_WriteRegister(
+ Hardware->ta->os, Hardware->ta->core,
+ 0x00390,
+ (gctUINT32)((Hardware->pagetableArray.address >> 32) & 0xFFFFFFFF)
+ );
+
+ gctaOS_WriteRegister(
+ Hardware->ta->os, Hardware->ta->core,
+ 0x00394
+,
+ 1
+ );
+
+ gctaOS_WriteRegister(
+ Hardware->ta->os, Hardware->ta->core,
+ 0x0039C,
+ (gctUINT32)(secureSafeAddress & 0xFFFFFFFF)
+ );
+
+ gctaOS_WriteRegister(
+ Hardware->ta->os, Hardware->ta->core,
+ 0x00398,
+ (gctUINT32)(nonSecureSafeAddress & 0xFFFFFFFF)
+ );
+
+ gctaOS_WriteRegister(
+ Hardware->ta->os, Hardware->ta->core,
+ 0x003A0,
+ (((((gctUINT32) (~0U)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 23:16) - (0 ?
+ 23:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 23:16) - (0 ?
+ 23:16) + 1))))))) << (0 ?
+ 23:16))) | (((gctUINT32) ((gctUINT32) ((gctUINT32)((secureSafeAddress >> 32) & 0xFFFFFFFF)) & ((gctUINT32) ((((1 ?
+ 23:16) - (0 ?
+ 23:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 23:16) - (0 ?
+ 23:16) + 1))))))) << (0 ?
+ 23:16))) &((((gctUINT32) (~0U)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:31) - (0 ?
+ 31:31) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:31) - (0 ?
+ 31:31) + 1))))))) << (0 ?
+ 31:31))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ?
+ 31:31) - (0 ?
+ 31:31) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:31) - (0 ? 31:31) + 1))))))) << (0 ? 31:31))))
+ | (((((gctUINT32) (~0U)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1))))))) << (0 ?
+ 7:0))) | (((gctUINT32) ((gctUINT32) ((gctUINT32)((nonSecureSafeAddress >> 32) & 0xFFFFFFFF)) & ((gctUINT32) ((((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1))))))) << (0 ?
+ 7:0))) &((((gctUINT32) (~0U)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:15) - (0 ?
+ 15:15) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:15) - (0 ?
+ 15:15) + 1))))))) << (0 ?
+ 15:15))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ?
+ 15:15) - (0 ?
+ 15:15) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:15) - (0 ? 15:15) + 1))))))) << (0 ? 15:15))))
+ );
+
+ /* Execute prepared command sequence. */
+ gctaHARDWARE_Execute(
+ Hardware->ta,
+ function->address,
+ function->bytes
+ );
+
+ /* Wait until MMU configure finishes. */
+ do
+ {
+ gctaOS_Delay(Hardware->os, delay);
+
+ gctaOS_ReadRegister(
+ Hardware->ta->os, Hardware->ta->core,
+ 0x00004,
+ &idle);
+
+ timer += delay;
+ delay *= 2;
+ }
+ while (!(((((gctUINT32) (idle)) >> (0 ? 0:0)) & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1)))))) ));
+
+ /* Enable MMU. */
+ gctaOS_WriteRegister(
+ Hardware->os, Hardware->ta->core,
+ 0x00388,
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1))))))) << (0 ?
+ 0:0))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)))
+ );
+
+ return gcvSTATUS_OK;
+}
+
+gceSTATUS
+gctaHARDWARE_PrepareFunctions(
+ IN gcTA_HARDWARE Hardware
+ )
+{
+ gceSTATUS status;
+ gcsHARDWARE_FUNCTION * function;
+ gctUINT32 mmuBytes;
+ gctUINT32 endBytes = 8;
+ gctUINT8_PTR logical;
+ gctPHYS_ADDR_T physical;
+
+ gcmkHEADER();
+
+ /* Allocate page table array. */
+ gcmkONERROR(gctaOS_AllocateSecurityMemory(
+ Hardware->ta->os,
+ &Hardware->pagetableArray.size,
+ &Hardware->pagetableArray.logical,
+ &Hardware->pagetableArray.physical
+ ));
+
+ gcmkONERROR(gctaOS_GetPhysicalAddress(
+ Hardware->ta->os,
+ Hardware->pagetableArray.logical,
+ &Hardware->pagetableArray.address
+ ));
+
+ /* Allocate GPU functions. */
+ gcmkONERROR(gctaOS_AllocateSecurityMemory(
+ Hardware->ta->os,
+ &Hardware->functionBytes,
+ &Hardware->functionLogical,
+ &Hardware->functionPhysical
+ ));
+
+ gcmkONERROR(gctaOS_GetPhysicalAddress(
+ Hardware->ta->os,
+ Hardware->functionLogical,
+ &physical
+ ));
+
+ gcmkSAFECASTPHYSADDRT(Hardware->functionAddress, physical);
+
+ function = &Hardware->functions[0];
+
+ function->logical = Hardware->functionLogical;
+
+ function->address = Hardware->functionAddress;
+
+ logical = function->logical;
+
+ gcmkONERROR(gctaHARDWARE_SetMMUStates(
+ Hardware,
+ Hardware->ta->mmu->mtlbLogical,
+ gcvMMU_MODE_4K,
+ Hardware->ta->mmu->safePageLogical,
+ logical,
+ &mmuBytes
+ ));
+
+ logical += 8;
+
+ gcmkONERROR(gctaHARDWARE_End(
+ Hardware,
+ logical,
+ &endBytes
+ ));
+
+ function->bytes = mmuBytes + endBytes;
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ gcmkFOOTER();
+ return status;
+}
+
+gceSTATUS
+gctaHARDWARE_IsFeatureAvailable(
+ IN gcTA_HARDWARE Hardware,
+ IN gceFEATURE Feature
+ )
+{
+ gctBOOL available;
+ gcsFEATURE_DATABASE *database = Hardware->featureDatabase;
+
+ switch (Feature)
+ {
+ case gcvFEATURE_SECURITY:
+ available = database->SECURITY;
+ break;
+ default:
+ gcmkFATAL("Invalid feature has been requested.");
+ available = gcvFALSE;
+ }
+
+ return available;
+}
+
+gceSTATUS
+gctaHARDWARE_DumpMMUException(
+ IN gcTA_HARDWARE Hardware
+ )
+{
+ gctUINT32 mmu = 0;
+ gctUINT32 mmuStatus = 0;
+ gctUINT32 address = 0;
+ gctUINT32 i = 0;
+
+ gctUINT32 mmuStatusRegAddress;
+ gctUINT32 mmuExceptionAddress;
+
+ gcmkHEADER_ARG("Hardware=0x%x", Hardware);
+
+ mmuStatusRegAddress = 0x00384;
+ mmuExceptionAddress = 0x00380;
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
+
+ gcmkPRINT("ChipModel=0x%x ChipRevision=0x%x:\n",
+ Hardware->chipModel,
+ Hardware->chipRevision);
+
+ gcmkPRINT("**************************\n");
+ gcmkPRINT("*** MMU ERROR DUMP ***\n");
+ gcmkPRINT("**************************\n");
+
+ gcmkVERIFY_OK(gctaOS_ReadRegister(
+ Hardware->os, Hardware->ta->core,
+ mmuStatusRegAddress
+,
+ &mmuStatus
+ ));
+
+ gcmkPRINT(" MMU status = 0x%08X\n", mmuStatus);
+
+ for (i = 0; i < 4; i += 1)
+ {
+ mmu = mmuStatus & 0xF;
+ mmuStatus >>= 4;
+
+ if (mmu == 0)
+ {
+ continue;
+ }
+
+ switch (mmu)
+ {
+ case 1:
+ gcmkPRINT(" MMU%d: slave not present\n", i);
+ break;
+
+ case 2:
+ gcmkPRINT(" MMU%d: page not present\n", i);
+ break;
+
+ case 3:
+ gcmkPRINT(" MMU%d: write violation\n", i);
+ break;
+
+ case 4:
+ gcmkPRINT(" MMU%d: out of bound", i);
+ break;
+
+ case 5:
+ gcmkPRINT(" MMU%d: read security violation", i);
+ break;
+
+ case 6:
+ gcmkPRINT(" MMU%d: write security violation", i);
+ break;
+
+ default:
+ gcmkPRINT(" MMU%d: unknown state\n", i);
+ }
+
+ gcmkVERIFY_OK(gctaOS_ReadRegister(
+ Hardware->os, Hardware->ta->core,
+ mmuExceptionAddress + i * 4
+,
+ &address
+ ));
+
+ gcmkPRINT(" MMU%d: exception address = 0x%08X\n", i, address);
+
+ gctaMMU_DumpPagetableEntry(Hardware->ta->mmu, address);
+ }
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+}
+
+gceSTATUS
+gctaHARDWARE_ReadMMUException(
+ IN gcTA_HARDWARE Hardware,
+ OUT gctUINT32_PTR MMUStatus,
+ OUT gctUINT32_PTR MMUException
+ )
+{
+ gctUINT32 mmuStatusRegAddress;
+ gctUINT32 mmuExceptionAddress;
+
+ gcmkHEADER_ARG("Hardware=0x%x", Hardware);
+
+ mmuStatusRegAddress = 0x00384;
+ mmuExceptionAddress = 0x00380;
+
+ gcmkVERIFY_OK(gctaOS_ReadRegister(
+ Hardware->os, Hardware->ta->core,
+ mmuStatusRegAddress
+,
+ MMUStatus
+ ));
+
+ gcmkVERIFY_OK(gctaOS_ReadRegister(
+ Hardware->os, Hardware->ta->core,
+ mmuExceptionAddress
+,
+ MMUException
+ ));
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+}
+
+gceSTATUS
+gctaHARDWARE_HandleMMUException(
+ IN gcTA_HARDWARE Hardware,
+ IN gctUINT32 MMUStatus,
+ IN gctPHYS_ADDR_T Physical,
+ IN gctUINT32 GPUAddress
+ )
+{
+ gctUINT32 mmu = 0;
+ gctUINT32 mmuStatus = 0;
+ gctUINT32 mtlbEntry = 0;
+ gctUINT32_PTR stlbEntry;
+ gctBOOL secure;
+
+ gctUINT32 mmuStatusRegAddress;
+ gctUINT32 mmuExceptionAddress;
+
+ gcmkHEADER_ARG("Hardware=0x%x", Hardware);
+
+ mmuStatusRegAddress = 0x00384;
+ mmuExceptionAddress = 0x00380;
+
+ gcmkVERIFY_OK(gctaOS_ReadRegister(
+ Hardware->os, Hardware->ta->core,
+ mmuStatusRegAddress
+,
+ &mmuStatus
+ ));
+
+ mmu = mmuStatus & 0xF;
+
+ /* Setup page table. */
+
+ gctaMMU_GetPageEntry(
+ Hardware->ta->mmu,
+ GPUAddress,
+ &mtlbEntry,
+ &stlbEntry,
+ &secure
+ );
+
+ gctaMMU_SetPage(
+ Hardware->ta->mmu,
+ (gctUINT32)Physical,
+ stlbEntry
+ );
+
+ switch (mmu)
+ {
+ case 1:
+ gcmkASSERT(mtlbEntry != 0);
+ gctaOS_WriteRegister(
+ Hardware->os, Hardware->ta->core,
+ mmuExceptionAddress
+,
+ mtlbEntry
+ );
+
+ break;
+
+ case 2:
+ gctaOS_WriteRegister(
+ Hardware->os, Hardware->ta->core,
+ mmuExceptionAddress
+,
+ *stlbEntry
+ );
+ break;
+
+ default:
+ gcmkASSERT(0);
+ }
+
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+}
+
diff --git a/drivers/mxc/gpu-viv/hal/security_v1/gc_hal_ta_hardware.h b/drivers/mxc/gpu-viv/hal/security_v1/gc_hal_ta_hardware.h
new file mode 100644
index 000000000000..2ae926aa0f80
--- /dev/null
+++ b/drivers/mxc/gpu-viv/hal/security_v1/gc_hal_ta_hardware.h
@@ -0,0 +1,139 @@
+/****************************************************************************
+*
+* The MIT License (MIT)
+*
+* Copyright (c) 2014 - 2018 Vivante 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 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 GPL License (GPL)
+*
+* Copyright (C) 2014 - 2018 Vivante 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.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+*****************************************************************************
+*
+* Note: This software is released under dual MIT and GPL licenses. A
+* recipient may use this file under the terms of either the MIT license or
+* GPL License. If you wish to use only one license not the other, you can
+* indicate your decision by deleting one of the above license notices in your
+* version of this file.
+*
+*****************************************************************************/
+
+
+#ifndef _GC_HAL_TA_HARDWARE_H_
+#define _GC_HAL_TA_HARDWARE_H_
+#include "gc_hal_types.h"
+#include "gc_hal_security_interface.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct _gcsMMU_TABLE_ARRAY_ENTRY
+{
+ gctUINT32 low;
+ gctUINT32 high;
+}
+gcsMMU_TABLE_ARRAY_ENTRY;
+
+typedef struct _gcsHARDWARE_PAGETABLE_ARRAY
+{
+ /* Number of entries in page table array. */
+ gctUINT num;
+
+ /* Size in bytes of array. */
+ gctSIZE_T size;
+
+ /* Physical address of array. */
+ gctPHYS_ADDR_T address;
+
+ /* Memory descriptor. */
+ gctPOINTER physical;
+
+ /* Logical address of array. */
+ gctPOINTER logical;
+}
+gcsHARDWARE_PAGETABLE_ARRAY;
+
+typedef struct _gcsHARWARE_FUNCTION
+{
+ /* Entry of the function. */
+ gctUINT32 address;
+
+ /* CPU address of the function. */
+ gctUINT8_PTR logical;
+
+ /* Bytes of the function. */
+ gctUINT32 bytes;
+
+ /* Hardware address of END in this function. */
+ gctUINT32 endAddress;
+
+ /* Logical of END in this function. */
+ gctUINT8_PTR endLogical;
+}
+gcsHARDWARE_FUNCTION;
+
+typedef struct _gcTA_HARDWARE
+{
+ gctaOS os;
+ gcTA ta;
+
+ gctUINT32 chipModel;
+ gctUINT32 chipRevision;
+ gctUINT32 productID;
+ gctUINT32 ecoID;
+ gctUINT32 customerID;
+
+ gctPOINTER featureDatabase;
+
+ gcsHARDWARE_PAGETABLE_ARRAY pagetableArray;
+
+ /* Function used by gctaHARDWARE. */
+ gctPHYS_ADDR functionPhysical;
+ gctPOINTER functionLogical;
+ gctUINT32 functionAddress;
+ gctSIZE_T functionBytes;
+
+ gcsHARDWARE_FUNCTION functions[1];
+}
+gcsTA_HARDWARE;
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+
diff --git a/drivers/mxc/gpu-viv/hal/security_v1/gc_hal_ta_mmu.c b/drivers/mxc/gpu-viv/hal/security_v1/gc_hal_ta_mmu.c
new file mode 100644
index 000000000000..396712e81aed
--- /dev/null
+++ b/drivers/mxc/gpu-viv/hal/security_v1/gc_hal_ta_mmu.c
@@ -0,0 +1,586 @@
+/****************************************************************************
+*
+* The MIT License (MIT)
+*
+* Copyright (c) 2014 - 2018 Vivante 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 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 GPL License (GPL)
+*
+* Copyright (C) 2014 - 2018 Vivante 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.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+*****************************************************************************
+*
+* Note: This software is released under dual MIT and GPL licenses. A
+* recipient may use this file under the terms of either the MIT license or
+* GPL License. If you wish to use only one license not the other, you can
+* indicate your decision by deleting one of the above license notices in your
+* version of this file.
+*
+*****************************************************************************/
+
+
+#include "gc_hal_types.h"
+#include "gc_hal_base.h"
+#include "gc_hal_security_interface.h"
+#include "gc_hal_ta.h"
+#include "gc_hal.h"
+
+#define _GC_OBJ_ZONE 2
+/*******************************************************************************
+************************************ Define ************************************
+********************************************************************************/
+
+#define gcdMMU_MTLB_SHIFT 22
+#define gcdMMU_STLB_4K_SHIFT 12
+#define gcdMMU_STLB_64K_SHIFT 16
+
+#define gcdMMU_MTLB_BITS (32 - gcdMMU_MTLB_SHIFT)
+#define gcdMMU_PAGE_4K_BITS gcdMMU_STLB_4K_SHIFT
+#define gcdMMU_STLB_4K_BITS (32 - gcdMMU_MTLB_BITS - gcdMMU_PAGE_4K_BITS)
+#define gcdMMU_PAGE_64K_BITS gcdMMU_STLB_64K_SHIFT
+#define gcdMMU_STLB_64K_BITS (32 - gcdMMU_MTLB_BITS - gcdMMU_PAGE_64K_BITS)
+
+#define gcdMMU_MTLB_ENTRY_NUM (1 << gcdMMU_MTLB_BITS)
+#define gcdMMU_MTLB_SIZE (gcdMMU_MTLB_ENTRY_NUM << 2)
+#define gcdMMU_STLB_4K_ENTRY_NUM (1 << gcdMMU_STLB_4K_BITS)
+#define gcdMMU_STLB_4K_SIZE (gcdMMU_STLB_4K_ENTRY_NUM << 2)
+#define gcdMMU_PAGE_4K_SIZE (1 << gcdMMU_STLB_4K_SHIFT)
+#define gcdMMU_STLB_64K_ENTRY_NUM (1 << gcdMMU_STLB_64K_BITS)
+#define gcdMMU_STLB_64K_SIZE (gcdMMU_STLB_64K_ENTRY_NUM << 2)
+#define gcdMMU_PAGE_64K_SIZE (1 << gcdMMU_STLB_64K_SHIFT)
+
+#define gcdMMU_MTLB_MASK (~((1U << gcdMMU_MTLB_SHIFT)-1))
+#define gcdMMU_STLB_4K_MASK ((~0U << gcdMMU_STLB_4K_SHIFT) ^ gcdMMU_MTLB_MASK)
+#define gcdMMU_PAGE_4K_MASK (gcdMMU_PAGE_4K_SIZE - 1)
+#define gcdMMU_STLB_64K_MASK ((~((1U << gcdMMU_STLB_64K_SHIFT)-1)) ^ gcdMMU_MTLB_MASK)
+#define gcdMMU_PAGE_64K_MASK (gcdMMU_PAGE_64K_SIZE - 1)
+
+/* Page offset definitions. */
+#define gcdMMU_OFFSET_4K_BITS (32 - gcdMMU_MTLB_BITS - gcdMMU_STLB_4K_BITS)
+#define gcdMMU_OFFSET_4K_MASK ((1U << gcdMMU_OFFSET_4K_BITS) - 1)
+#define gcdMMU_OFFSET_16K_BITS (32 - gcdMMU_MTLB_BITS - gcdMMU_STLB_16K_BITS)
+#define gcdMMU_OFFSET_16K_MASK ((1U << gcdMMU_OFFSET_16K_BITS) - 1)
+
+#define gcdMMU_MTLB_PRESENT 0x00000001
+#define gcdMMU_MTLB_EXCEPTION 0x00000002
+#define gcdMMU_MTLB_4K_PAGE 0x00000000
+
+#define gcdMMU_STLB_PRESENT 0x00000001
+#define gcdMMU_STLB_EXCEPTION 0x00000002
+#define gcdMMU_STLB_SECURITY (1 << 4)
+#define gcdMMU_STLB_4K_PAGE 0x00000000
+
+#define gcdUSE_MMU_EXCEPTION 1
+
+#define gcdMMU_SECURE_AREA_START ((gcdMMU_MTLB_ENTRY_NUM - gcdMMU_SECURE_AREA_SIZE) << gcdMMU_MTLB_SHIFT)
+
+typedef enum _gceMMU_TYPE
+{
+ gcvMMU_USED = (0 << 4),
+ gcvMMU_SINGLE = (1 << 4),
+ gcvMMU_FREE = (2 << 4),
+}
+gceMMU_TYPE;
+
+typedef struct _gcsMMU_STLB *gcsMMU_STLB_PTR;
+typedef struct _gcsMMU_STLB
+{
+ gctPHYS_ADDR physical;
+ gctUINT32_PTR logical;
+ gctSIZE_T size;
+ gctPHYS_ADDR_T physBase;
+ gctSIZE_T pageCount;
+ gctUINT32 mtlbIndex;
+ gctUINT32 mtlbEntryNum;
+ gcsMMU_STLB_PTR next;
+} gcsMMU_STLB;
+
+
+#define gcmENTRY_TYPE(x) (x & 0xF0)
+/*
+* We need flat mapping ta command buffer.
+
+*/
+
+/*
+* Helper
+*/
+gctUINT32
+_MtlbOffset(
+ gctUINT32 Address
+ )
+{
+ return (Address & gcdMMU_MTLB_MASK) >> gcdMMU_MTLB_SHIFT;
+}
+
+gctUINT32
+_StlbOffset(
+ gctUINT32 Address
+ )
+{
+ return (Address & gcdMMU_STLB_4K_MASK) >> gcdMMU_STLB_4K_SHIFT;
+}
+
+static gctUINT32
+_SetPage(gctUINT32 PageAddress)
+{
+ return PageAddress
+ /* writable */
+ | (1 << 2)
+ /* Ignore exception */
+ | (0 << 1)
+ /* Present */
+ | (1 << 0);
+}
+
+static void
+_WritePageEntry(
+ IN gctUINT32_PTR PageEntry,
+ IN gctUINT32 EntryValue
+ )
+{
+ *PageEntry = EntryValue;
+
+ gctaOS_CacheClean((gctUINT8_PTR)PageEntry, gcmSIZEOF(gctUINT32));
+}
+
+static gceSTATUS
+_FillPageTable(
+ IN gctUINT32_PTR PageTable,
+ IN gctUINT32 PageCount,
+ IN gctUINT32 EntryValue
+)
+{
+ gctUINT i;
+
+ for (i = 0; i < PageCount; i++)
+ {
+ _WritePageEntry(PageTable + i, EntryValue);
+ }
+
+ return gcvSTATUS_OK;
+}
+
+
+static gceSTATUS
+_AllocateStlb(
+ IN gctaOS Os,
+ OUT gcsMMU_STLB_PTR *Stlb
+ )
+{
+ gceSTATUS status;
+ gcsMMU_STLB_PTR stlb;
+ gctPOINTER pointer = gcvNULL;
+
+ /* Allocate slave TLB record. */
+ gcmkONERROR(gctaOS_Allocate(gcmSIZEOF(gcsMMU_STLB), &pointer));
+ stlb = pointer;
+
+ stlb->size = gcdMMU_STLB_4K_SIZE;
+
+ /* Allocate slave TLB entries. */
+ gcmkONERROR(gctaOS_AllocateSecurityMemory(
+ Os,
+ &stlb->size,
+ (gctPOINTER *)&stlb->logical,
+ &stlb->physical
+ ));
+
+ gcmkONERROR(gctaOS_GetPhysicalAddress(Os, stlb->logical, &stlb->physBase));
+
+#if gcdUSE_MMU_EXCEPTION
+ _FillPageTable(stlb->logical, (gctUINT32)stlb->size / 4, gcdMMU_STLB_EXCEPTION);
+#else
+ gctaOS_ZeroMemory(stlb->logical, (gctUINT32)stlb->size);
+#endif
+
+ *Stlb = stlb;
+
+ return gcvSTATUS_OK;
+
+OnError:
+ if(pointer != gcvNULL)
+ gcmkVERIFY_OK(gctaOS_Free(pointer));
+ return status;
+}
+
+gceSTATUS
+gctaMMU_Construct(
+ IN gcTA TA,
+ OUT gcTA_MMU *Mmu
+ )
+{
+ gceSTATUS status;
+ gctSIZE_T bytes = 4096;
+
+ gcTA_MMU mmu = gcvNULL;
+
+ gcmkONERROR(gctaOS_Allocate(
+ gcmSIZEOF(gcsTA_MMU),
+ (gctPOINTER *)&mmu
+ ));
+
+ mmu->mtlbLogical = gcvNULL;
+ mmu->stlbs = gcvNULL;
+ mmu->safePageLogical = gcvNULL;
+ mmu->nonSecureSafePageLogical = gcvNULL;
+
+ mmu->os = TA->os;
+
+ /* MTLB bytes. */
+ mmu->mtlbBytes = gcdMMU_MTLB_SIZE;
+
+ /* Allocate MTLB. */
+ gcmkONERROR(gctaOS_AllocateSecurityMemory(
+ TA->os,
+ &mmu->mtlbBytes,
+ &mmu->mtlbLogical,
+ &mmu->mtlbPhysical
+ ));
+
+#if gcdUSE_MMU_EXCEPTION
+ _FillPageTable(mmu->mtlbLogical, (gctUINT32)mmu->mtlbBytes / 4, gcdMMU_STLB_EXCEPTION);
+#else
+ gctaOS_ZeroMemory(mmu->mtlbLogical, (gctUINT32)mmu->mtlbBytes);
+#endif
+
+ /* Allocate a array to store stlbs. */
+ gcmkONERROR(gctaOS_Allocate((gctUINT32)mmu->mtlbBytes, &mmu->stlbs));
+
+ gctaOS_ZeroMemory((gctUINT8_PTR)mmu->stlbs, (gctUINT32)mmu->mtlbBytes);
+
+ /* Allocate security safe page. */
+ gcmkONERROR(gctaOS_AllocateSecurityMemory(
+ TA->os,
+ &bytes,
+ &mmu->safePageLogical,
+ &mmu->safePagePhysical
+ ));
+
+ gctaOS_ZeroMemory((gctUINT8_PTR)mmu->safePageLogical, (gctUINT32)bytes);
+
+ /* Allocate non security safe page. */
+ gcmkONERROR(gctaOS_AllocateSecurityMemory(
+ TA->os,
+ &bytes,
+ &mmu->nonSecureSafePageLogical,
+ &mmu->nonSecureSafePagePhysical
+ ));
+
+ gctaOS_ZeroMemory((gctUINT8_PTR)mmu->nonSecureSafePageLogical, (gctUINT32)bytes);
+
+ /* gcmkONERROR(gctaOS_CreateMutex(TA->os, &mmu->mutex)); */
+
+ *Mmu = mmu;
+
+ return gcvSTATUS_OK;
+
+OnError:
+ if (mmu)
+ {
+ if (mmu->safePageLogical)
+ {
+ gcmkVERIFY_OK(gctaOS_FreeSecurityMemory(
+ TA->os,
+ 4096,
+ mmu->safePageLogical,
+ mmu->safePagePhysical
+ ));
+ }
+
+ if (mmu->nonSecureSafePageLogical)
+ {
+ gcmkVERIFY_OK(gctaOS_FreeSecurityMemory(
+ TA->os,
+ 4096,
+ mmu->nonSecureSafePageLogical,
+ mmu->nonSecureSafePagePhysical
+ ));
+ }
+
+ if (mmu->mtlbLogical)
+ {
+ gcmkVERIFY_OK(gctaOS_FreeSecurityMemory(
+ TA->os,
+ 4096,
+ mmu->mtlbLogical,
+ mmu->mtlbPhysical
+ ));
+ }
+
+ if (mmu->stlbs)
+ {
+ gcmkVERIFY_OK(gctaOS_Free((gctPOINTER)mmu->stlbs));
+ }
+
+ gcmkVERIFY_OK(gctaOS_Free((gctPOINTER)mmu));
+ }
+ return status;
+}
+
+gceSTATUS
+gctaMMU_Destory(
+ IN gcTA_MMU Mmu
+ )
+{
+ gctaOS os = Mmu->os;
+
+ if (Mmu->safePageLogical)
+ {
+ gcmkVERIFY_OK(gctaOS_FreeSecurityMemory(
+ os,
+ 4096,
+ Mmu->safePageLogical,
+ Mmu->safePagePhysical
+ ));
+ }
+
+ if (Mmu->nonSecureSafePageLogical)
+ {
+ gcmkVERIFY_OK(gctaOS_FreeSecurityMemory(
+ os,
+ 4096,
+ Mmu->nonSecureSafePageLogical,
+ Mmu->nonSecureSafePagePhysical
+ ));
+ }
+
+ if (Mmu->mtlbLogical)
+ {
+ gcmkVERIFY_OK(gctaOS_FreeSecurityMemory(
+ os,
+ 4096,
+ Mmu->mtlbLogical,
+ Mmu->mtlbPhysical
+ ));
+ }
+
+ if (Mmu->stlbs)
+ {
+ gcmkVERIFY_OK(gctaOS_Free((gctPOINTER)Mmu->stlbs));
+ }
+
+ gcmkVERIFY_OK(gctaOS_Free(Mmu));
+
+ return gcvSTATUS_OK;
+}
+
+gceSTATUS
+gctaMMU_GetPageEntry(
+ IN gcTA_MMU Mmu,
+ IN gctUINT32 Address,
+ OUT gctUINT32_PTR MtlbEntry,
+ OUT gctUINT32_PTR *PageTable,
+ OUT gctBOOL * Secure
+ )
+{
+ gceSTATUS status;
+ struct _gcsMMU_STLB *stlb;
+ struct _gcsMMU_STLB **stlbs = (struct _gcsMMU_STLB **)Mmu->stlbs;
+ gctUINT32 offset = _MtlbOffset(Address);
+ gctUINT32 mtlbEntry;
+ gctBOOL secure = Address > gcdMMU_SECURE_AREA_START;
+
+ gcmkHEADER_ARG("Mmu=0x%x", Mmu);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_ARGUMENT((Address & 0xFFF) == 0);
+
+ stlb = stlbs[offset];
+
+ if (stlb == gcvNULL)
+ {
+ gcmkONERROR(_AllocateStlb(Mmu->os, &stlb));
+
+ mtlbEntry = (gctUINT32)(stlb->physBase & 0xFFFFFFFF)
+ | gcdMMU_MTLB_4K_PAGE
+ | gcdMMU_MTLB_PRESENT
+ ;
+
+ if (secure)
+ {
+ /* Secure MTLB. */
+ mtlbEntry |= (1 << 4);
+ }
+
+ /* Insert Slave TLB address to Master TLB entry.*/
+ _WritePageEntry((gctUINT32_PTR)Mmu->mtlbLogical + offset, mtlbEntry);
+
+ /* Record stlb. */
+ stlbs[offset] = stlb;
+
+ if (MtlbEntry)
+ {
+ /* Return entry value of new mtlb entry. */
+ *MtlbEntry = mtlbEntry;
+ }
+ }
+
+ *PageTable = &stlb->logical[_StlbOffset(Address)];
+
+ if (Secure)
+ {
+ *Secure = secure;
+ }
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ gcmkFOOTER();
+ return status;
+}
+
+gceSTATUS
+gctaMMU_SetPage(
+ IN gcTA_MMU Mmu,
+ IN gctUINT32 PageAddress,
+ IN gctUINT32 *PageEntry
+ )
+{
+ /* gctBOOL secure; */
+
+ gcmkHEADER_ARG("Mmu=0x%x", Mmu);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_ARGUMENT(PageEntry != gcvNULL);
+ gcmkVERIFY_ARGUMENT(!(PageAddress & 0xFFF));
+
+ _WritePageEntry(PageEntry, _SetPage(PageAddress));
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+}
+
+gceSTATUS
+gctaMMU_FreePages(
+ IN gcTA_MMU Mmu,
+ IN gctUINT32 Address,
+ IN gctUINT32 PageCount
+ )
+{
+ gceSTATUS status;
+ gctUINT32 i;
+ gctUINT32_PTR entry;
+ gcmkHEADER_ARG("Mmu=0x%x", Mmu);
+
+ /* Fill in page table. */
+ for (i = 0; i < PageCount; i++)
+ {
+ gcmkONERROR(gctaMMU_GetPageEntry(Mmu, Address, gcvNULL, &entry, gcvNULL));
+
+#if gcdUSE_MMU_EXCEPTION
+ *entry = gcdMMU_STLB_EXCEPTION;
+#else
+ *entry = 0;
+#endif
+
+ Address += 4096;
+ }
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ gcmkFOOTER();
+ return status;
+}
+
+gceSTATUS
+gctaMMU_Enable(
+ IN gcTA_MMU Mmu,
+ IN gcTA TA
+ )
+{
+ gceSTATUS status;
+ gctPHYS_ADDR_T address;
+ gctPHYS_ADDR_T safeAddress;
+
+ gcmkONERROR(gctaOS_GetPhysicalAddress(Mmu->os, Mmu->mtlbLogical, &address));
+
+ gctaOS_GetPhysicalAddress(Mmu->os, Mmu->safePageLogical, &safeAddress);
+
+ return gcvSTATUS_OK;
+
+OnError:
+ return status;
+}
+
+void
+gctaMMU_DumpPagetableEntry(
+ IN gcTA_MMU Mmu,
+ IN gctUINT32 Address
+ )
+{
+ gctUINT32 entry;
+ gctUINT32 mtlb = _MtlbOffset(Address);
+ gctUINT32_PTR mtlbLogical = Mmu->mtlbLogical;
+ gctUINT32_PTR stlbLogical;
+ gcsMMU_STLB_PTR stlb;
+ struct _gcsMMU_STLB **stlbs = (struct _gcsMMU_STLB **)Mmu->stlbs;
+
+ gctUINT32 stlbOffset = (Address & gcdMMU_STLB_4K_MASK) >> gcdMMU_STLB_4K_SHIFT;
+ gctUINT32 offsetInPage = Address & gcdMMU_OFFSET_4K_MASK;
+
+ stlb = stlbs[mtlb];
+
+ gcmkPRINT(" MTLB entry = %d\n", mtlb);
+
+ gcmkPRINT(" STLB entry = %d\n", stlbOffset);
+
+ gcmkPRINT(" Offset = 0x%08X (%d)\n", offsetInPage, offsetInPage);
+
+
+ if (stlb == gcvNULL)
+ {
+ /* Dmp mtlb entry. */
+ entry = mtlbLogical[mtlb];
+
+ gcmkPRINT(" mtlb entry [%d] = %x", mtlb, entry);
+ }
+ else
+ {
+ stlbLogical = stlb->logical;
+
+ gcmkPRINT(" stlb entry = 0x%08X", stlbLogical[stlbOffset]);
+ }
+}
+
+
diff --git a/drivers/mxc/gpu-viv/hal/security_v1/os/emulator/gc_hal_ta_emulator.c b/drivers/mxc/gpu-viv/hal/security_v1/os/emulator/gc_hal_ta_emulator.c
new file mode 100644
index 000000000000..07f21b1ea23e
--- /dev/null
+++ b/drivers/mxc/gpu-viv/hal/security_v1/os/emulator/gc_hal_ta_emulator.c
@@ -0,0 +1,324 @@
+/****************************************************************************
+*
+* The MIT License (MIT)
+*
+* Copyright (c) 2014 - 2018 Vivante 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 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 GPL License (GPL)
+*
+* Copyright (C) 2014 - 2018 Vivante 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.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+*****************************************************************************
+*
+* Note: This software is released under dual MIT and GPL licenses. A
+* recipient may use this file under the terms of either the MIT license or
+* GPL License. If you wish to use only one license not the other, you can
+* indicate your decision by deleting one of the above license notices in your
+* version of this file.
+*
+*****************************************************************************/
+
+
+#include "gc_hal_base.h"
+#include "gc_hal.h"
+#include "gc_hal_ta.h"
+#include "gc_hal_kernel_mutex.h"
+
+#define _GC_OBJ_ZONE gcvZONE_OS
+
+gcTA globalTA[16] = { gcvNULL, gcvNULL, gcvNULL, gcvNULL,gcvNULL, gcvNULL, gcvNULL, gcvNULL };
+gctaOS globalTAos;
+
+struct _gctaOS {
+ void *os;
+
+ gctPOINTER dispatchMutex;
+};
+
+gceSTATUS HALDECL
+TAEmulator(
+ gceCORE Core,
+ void * Interface
+ )
+{
+ gckOS_AcquireMutex(globalTAos->os, globalTAos->dispatchMutex, gcvINFINITE);
+
+ gcTA_Dispatch(globalTA[Core], Interface);
+
+ gckOS_ReleaseMutex(globalTAos->os, globalTAos->dispatchMutex);
+ return gcvSTATUS_OK;
+}
+
+
+gceSTATUS
+gctaOS_ConstructOS(
+ IN gckOS Os,
+ OUT gctaOS *TAos
+ )
+{
+ gctaOS os;
+ gctPOINTER pointer = gcvNULL;
+ gceSTATUS status;
+
+ gcmkONERROR(gckOS_AllocateMemory(Os, gcmSIZEOF(struct _gctaOS), &pointer));
+
+ os = (gctaOS)pointer;
+ os->os = Os;
+
+ gcmkONERROR(gckOS_CreateMutex(Os, &os->dispatchMutex));
+
+ *TAos = globalTAos = os;
+
+ return gcvSTATUS_OK;
+
+OnError:
+ if (pointer != gcvNULL)
+ {
+ gcmkVERIFY_OK(gckOS_FreeMemory(Os, pointer));
+ }
+ return status;
+}
+
+gceSTATUS
+gctaOS_DestroyOS(
+ IN gctaOS Os
+ )
+{
+ gckOS os = Os->os;
+
+ gcmkVERIFY_OK(gckOS_DeleteMutex(os, Os->dispatchMutex));
+ gcmkVERIFY_OK(gckOS_FreeMemory(os, Os));
+
+ return gcvSTATUS_OK;
+}
+
+gceSTATUS
+gctaOS_AllocateSecurityMemory(
+ IN gctaOS Os,
+ IN gctSIZE_T *Bytes,
+ OUT gctPOINTER *Logical,
+ OUT gctPOINTER *Physical
+ )
+{
+ gceSTATUS status;
+
+ gcmkONERROR(gckOS_AllocateNonPagedMemory(Os->os, gcvFALSE, gcvALLOC_FLAG_CONTIGUOUS, Bytes, (gctPHYS_ADDR *)Physical, Logical));
+
+ return gcvSTATUS_OK;
+
+OnError:
+ return status;
+}
+
+gceSTATUS
+gctaOS_FreeSecurityMemory(
+ IN gctaOS Os,
+ IN gctSIZE_T Bytes,
+ IN gctPOINTER Logical,
+ OUT gctPOINTER Physical
+ )
+{
+ gckOS_FreeNonPagedMemory(Os->os, Bytes, (gctPHYS_ADDR)Physical, Logical);
+ return gcvSTATUS_OK;
+}
+
+gceSTATUS
+gctaOS_AllocateNonSecurityMemory(
+ IN gctaOS Os,
+ IN gctSIZE_T *Bytes,
+ OUT gctPOINTER *Logical,
+ OUT gctPOINTER *Physical
+ )
+{
+ gceSTATUS status;
+
+ gcmkONERROR(gckOS_AllocateNonPagedMemory(Os->os, gcvFALSE, gcvALLOC_FLAG_CONTIGUOUS, Bytes, (gctPHYS_ADDR *)Physical, Logical));
+
+ return gcvSTATUS_OK;
+
+OnError:
+ return status;
+}
+
+gceSTATUS
+gctaOS_FreeNonSecurityMemory(
+ IN gctaOS Os,
+ IN gctSIZE_T Bytes,
+ IN gctPOINTER Logical,
+ OUT gctPOINTER Physical
+ )
+{
+ gckOS_FreeNonPagedMemory(Os->os, Bytes, (gctPHYS_ADDR)Physical, Logical);
+ return gcvSTATUS_OK;
+}
+
+gceSTATUS
+gctaOS_Allocate(
+ IN gctUINT32 Bytes,
+ OUT gctPOINTER *Pointer
+ )
+{
+ return gckOS_AllocateMemory(globalTAos->os, Bytes, Pointer);
+}
+
+gceSTATUS
+gctaOS_Free(
+ IN gctPOINTER Pointer
+ )
+{
+ return gckOS_FreeMemory(globalTAos->os, Pointer);
+}
+
+gceSTATUS
+gctaOS_GetPhysicalAddress(
+ IN gctaOS Os,
+ IN gctPOINTER Logical,
+ OUT gctPHYS_ADDR_T * Physical
+ )
+{
+ gctPHYS_ADDR_T physical;
+ gceSTATUS status;
+
+ gcmkONERROR(gckOS_GetPhysicalAddress(Os->os, Logical, &physical));
+
+ gcmkVERIFY_OK(gckOS_CPUPhysicalToGPUPhysical(Os->os, physical, &physical));
+
+ *Physical = physical;
+
+ return gcvSTATUS_OK;
+
+OnError:
+ return status;
+}
+
+gceSTATUS gctaOS_WriteRegister(
+ IN gctaOS Os, IN gceCORE Core,
+ IN gctUINT32 Address,
+ IN gctUINT32 Data
+ )
+{
+ return gckOS_WriteRegisterEx(Os->os, Core, Address, Data);
+}
+
+gceSTATUS gctaOS_ReadRegister(
+ IN gctaOS Os, IN gceCORE Core,
+ IN gctUINT32 Address,
+ IN gctUINT32 *Data
+ )
+{
+ return gckOS_ReadRegisterEx(Os->os, Core, Address, Data);
+}
+
+gceSTATUS
+gctaOS_MemCopy(
+ IN gctUINT8_PTR Dest,
+ IN gctUINT8_PTR Src,
+ IN gctUINT32 Bytes
+ )
+{
+ gckOS_MemCopy(Dest, Src, Bytes);
+ return gcvSTATUS_OK;
+}
+
+gceSTATUS
+gctaOS_ZeroMemory(
+ IN gctUINT8_PTR Dest,
+ IN gctUINT32 Bytes
+ )
+{
+ gckOS_ZeroMemory(Dest, Bytes);
+ return gcvSTATUS_OK;
+}
+
+void
+gctaOS_CacheFlush(
+ IN gctUINT8_PTR Dest,
+ IN gctUINT32 Bytes
+ )
+{
+
+}
+
+void
+gctaOS_CacheClean(
+ IN gctUINT8_PTR Dest,
+ IN gctUINT32 Bytes
+ )
+{
+
+}
+
+void
+gctaOS_CacheInvalidate(
+ IN gctUINT8_PTR Dest,
+ IN gctUINT32 Bytes
+ )
+{
+
+}
+
+gceSTATUS
+gctaOS_IsPhysicalSecure(
+ IN gctaOS Os,
+ IN gctUINT32 Physical,
+ OUT gctBOOL *Secure
+ )
+{
+ return gcvSTATUS_NOT_SUPPORTED;
+}
+
+gceSTATUS
+gctaOS_Delay(
+ IN gctaOS Os,
+ IN gctUINT32 Delay
+ )
+{
+ return gckOS_Delay(Os->os, Delay);
+}
+
+gceSTATUS
+gctaOS_SetGPUPower(
+ IN gctaOS Os,
+ IN gctUINT32 Core,
+ IN gctBOOL Clock,
+ IN gctBOOL Power
+ )
+{
+ return gckOS_SetGPUPower(Os->os, Core, Power, Clock);
+}
+
+
diff --git a/drivers/mxc/hantro/Kconfig b/drivers/mxc/hantro/Kconfig
new file mode 100755
index 000000000000..815a01e27b69
--- /dev/null
+++ b/drivers/mxc/hantro/Kconfig
@@ -0,0 +1,14 @@
+#
+# Codec configuration
+#
+
+menu "MXC HANTRO(Video Processing Unit) support"
+ depends on ARCH_FSL_IMX8MQ
+
+config MXC_HANTRO
+ tristate "Support for MXC HANTRO(Video Processing Unit)"
+ default y
+ ---help---
+ VPU codec device.
+
+endmenu
diff --git a/drivers/mxc/hantro/Makefile b/drivers/mxc/hantro/Makefile
new file mode 100755
index 000000000000..3673ac214fa3
--- /dev/null
+++ b/drivers/mxc/hantro/Makefile
@@ -0,0 +1,8 @@
+#
+# Makefile for the VPU drivers.
+#
+
+ccflags-y += -I$(PWD)/./dwl
+
+obj-$(CONFIG_MXC_HANTRO) += hantrodec.o
+
diff --git a/drivers/mxc/hantro/dwl_defs.h b/drivers/mxc/hantro/dwl_defs.h
new file mode 100755
index 000000000000..8976dcf156b6
--- /dev/null
+++ b/drivers/mxc/hantro/dwl_defs.h
@@ -0,0 +1,94 @@
+/*****************************************************************************
+ * The GPL License (GPL)
+ *
+ * Copyright (c) 2015-2017, VeriSilicon Inc.
+ * Copyright (c) 2011-2014, Google 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.
+ *
+ * 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 may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ *****************************************************************************/
+
+#ifndef SOFTWARE_LINUX_DWL_DWL_DEFS_H_
+#define SOFTWARE_LINUX_DWL_DWL_DEFS_H_
+
+#define DWL_MPEG2_E 31 /* 1 bit */
+#define DWL_VC1_E 29 /* 2 bits */
+#define DWL_JPEG_E 28 /* 1 bit */
+#define DWL_MPEG4_E 26 /* 2 bits */
+#define DWL_H264_E 24 /* 2 bits */
+#define DWL_VP6_E 23 /* 1 bit */
+#define DWL_RV_E 26 /* 2 bits */
+#define DWL_VP8_E 23 /* 1 bit */
+#define DWL_VP7_E 24 /* 1 bit */
+#define DWL_WEBP_E 19 /* 1 bit */
+#define DWL_AVS_E 22 /* 1 bit */
+#if 0
+#define DWL_PP_E 16 /* 1 bit */
+#endif
+#define DWL_PP_E 31 /* 1 bit */
+#define DWL_HEVC_E 5 /* 2 bits */
+#define DWL_VP9_E 3 /* 2 bits */
+
+#define DWL_HEVC_ENA 0 /* 1 bits */
+#define DWL_VP9_ENA 1 /* 1 bits */
+#define DWL_RFC_E 2 /* 1 bits */
+#define DWL_DS_E 3 /* 1 bits */
+#define DWL_HEVC_VER 8 /* 4 bits */
+#define DWL_VP9_PROFILE 12 /* 3 bits */
+#define DWL_RING_E 16 /* 1 bits */
+
+#define HANTRODEC_IRQ_STAT_DEC 1
+#define HANTRODEC_IRQ_STAT_DEC_OFF (HANTRODEC_IRQ_STAT_DEC * 4)
+
+#define HANTRODECPP_SYNTH_CFG 60
+#define HANTRODECPP_SYNTH_CFG_OFF (HANTRODECPP_SYNTH_CFG * 4)
+#define HANTRODEC_SYNTH_CFG 50
+#define HANTRODEC_SYNTH_CFG_OFF (HANTRODEC_SYNTH_CFG * 4)
+#define HANTRODEC_SYNTH_CFG_2 54
+#define HANTRODEC_SYNTH_CFG_2_OFF (HANTRODEC_SYNTH_CFG_2 * 4)
+#define HANTRODEC_SYNTH_CFG_3 56
+#define HANTRODEC_SYNTH_CFG_3_OFF (HANTRODEC_SYNTH_CFG_3 * 4)
+#define HANTRODEC_CFG_STAT 23
+#define HANTRODEC_CFG_STAT_OFF (HANTRODEC_CFG_STAT * 4)
+
+
+#define HANTRODEC_DEC_E 0x01
+#define HANTRODEC_PP_E 0x01
+#define HANTRODEC_DEC_ABORT 0x20
+#define HANTRODEC_DEC_IRQ_DISABLE 0x10
+#define HANTRODEC_DEC_IRQ 0x100
+
+/* Legacy from G1 */
+#define HANTRO_IRQ_STAT_DEC 1
+#define HANTRO_IRQ_STAT_DEC_OFF (HANTRO_IRQ_STAT_DEC * 4)
+#define HANTRO_IRQ_STAT_PP 60
+#define HANTRO_IRQ_STAT_PP_OFF (HANTRO_IRQ_STAT_PP * 4)
+
+#define HANTROPP_SYNTH_CFG 100
+#define HANTROPP_SYNTH_CFG_OFF (HANTROPP_SYNTH_CFG * 4)
+#define HANTRODEC_SYNTH_CFG 50
+#define HANTRODEC_SYNTH_CFG_OFF (HANTRODEC_SYNTH_CFG * 4)
+#define HANTRODEC_SYNTH_CFG_2 54
+#define HANTRODEC_SYNTH_CFG_2_OFF (HANTRODEC_SYNTH_CFG_2 * 4)
+
+#define HANTRO_DEC_E 0x01
+#define HANTRO_PP_E 0x01
+#define HANTRO_DEC_ABORT 0x20
+#define HANTRO_DEC_IRQ_DISABLE 0x10
+#define HANTRO_PP_IRQ_DISABLE 0x10
+#define HANTRO_DEC_IRQ 0x100
+#define HANTRO_PP_IRQ 0x100
+
+#endif /* SOFTWARE_LINUX_DWL_DWL_DEFS_H_ */
diff --git a/drivers/mxc/hantro/hantrodec.c b/drivers/mxc/hantro/hantrodec.c
new file mode 100755
index 000000000000..f93a16e89d9f
--- /dev/null
+++ b/drivers/mxc/hantro/hantrodec.c
@@ -0,0 +1,1938 @@
+/*****************************************************************************
+ * The GPL License (GPL)
+ *
+ * Copyright (c) 2015-2018, VeriSilicon Inc.
+ * Copyright (c) 2011-2014, Google 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.
+ *
+ * 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 may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ *****************************************************************************/
+#include <linux/hantrodec.h>
+#include "dwl_defs.h"
+#include <linux/io.h>
+#include <linux/uaccess.h>
+#include <linux/errno.h>
+#include <linux/fs.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/pci.h>
+#include <linux/sched.h>
+#include <linux/semaphore.h>
+#include <linux/spinlock.h>
+#include <linux/slab.h>
+#include <linux/version.h>
+#include <linux/wait.h>
+#include <linux/timer.h>
+#include <linux/clk.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/clk.h>
+#include <linux/busfreq-imx.h>
+
+#ifdef CONFIG_DEVICE_THERMAL
+#include <linux/device_cooling.h>
+#define HANTRO_REG_THERMAL_NOTIFIER(a) register_devfreq_cooling_notifier(a)
+#define HANTRO_UNREG_THERMAL_NOTIFIER(a) unregister_devfreq_cooling_notifier(a)
+DEFINE_SPINLOCK(thermal_lock);
+/*1:hot, 0: not hot*/
+static int thermal_event;
+static int thermal_cur;
+static int hantro_clock_ratio = 2;
+static int hantro_dynamic_clock;
+module_param(hantro_clock_ratio, int, 0644);
+module_param(hantro_dynamic_clock, int, 0644);
+MODULE_PARM_DESC(hantro_clock_ratio, "clock ratio 1/N");
+MODULE_PARM_DESC(hantro_dynamic_clock, "enable or disable dynamic clock rate");
+#endif
+
+/*hantro G1 regs config including dec and pp*/
+#define HANTRO_DEC_ORG_REGS 60
+#define HANTRO_PP_ORG_REGS 41
+
+#define HANTRO_DEC_EXT_REGS 27
+#define HANTRO_PP_EXT_REGS 9
+
+#define HANTRO_G1_DEC_TOTAL_REGS (HANTRO_DEC_ORG_REGS + HANTRO_DEC_EXT_REGS)
+#define HANTRO_PP_TOTAL_REGS (HANTRO_PP_ORG_REGS + HANTRO_PP_EXT_REGS)
+#define HANTRO_G1_TOTAL_REGS 155 /*G1 total regs*/
+
+#define HANTRO_DEC_ORG_FIRST_REG 0
+#define HANTRO_DEC_ORG_LAST_REG 59
+#define HANTRO_DEC_EXT_FIRST_REG 119
+#define HANTRO_DEC_EXT_LAST_REG 145
+
+#define HANTRO_PP_ORG_FIRST_REG 60
+#define HANTRO_PP_ORG_LAST_REG 100
+#define HANTRO_PP_EXT_FIRST_REG 146
+#define HANTRO_PP_EXT_LAST_REG 154
+
+/*hantro G2 reg config*/
+#define HANTRO_G2_DEC_REGS 265 /*G2 total regs*/
+
+#define HANTRO_G2_DEC_FIRST_REG 0
+#define HANTRO_G2_DEC_LAST_REG (HANTRO_G2_DEC_REGS - 1)
+
+#define MAX(a, b) (((a) > (b)) ? (a) : (b))
+
+#define DEC_IO_SIZE_MAX (MAX(HANTRO_G2_DEC_REGS, HANTRO_G1_TOTAL_REGS) * 4)
+
+/********************************************************************
+ * PORTING SEGMENT
+ * NOTES: customer should modify these configuration if do porting to own platform.
+ * Please guarantee the base_addr, io_size,dec_irq belong to same core.
+ ********************************************************************/
+
+#define HXDEC_MAX_CORES 2
+
+/* Logic module base address */
+#define SOCLE_LOGIC_0_BASE 0x38300000
+#define SOCLE_LOGIC_1_BASE 0x38310000
+#define BLK_CTL_BASE 0x38320000
+
+#define VEXPRESS_LOGIC_0_BASE 0xFC010000
+#define VEXPRESS_LOGIC_1_BASE 0xFC020000
+
+#define DEC_IO_SIZE_0 ((HANTRO_G2_DEC_REGS) * 4) /* bytes */
+#define DEC_IO_SIZE_1 ((HANTRO_G2_DEC_REGS) * 4) /* bytes */
+
+#define HANTRO_G1_DEF_CLK (600000000)
+#define HANTRO_G2_DEF_CLK (600000000)
+#define HANTRO_BUS_DEF_CLK (800000000)
+#define HANTRO_CLK_VOL_THR (600000000)
+/***********************************************************************/
+
+#define IS_G1(hw_id) ((hw_id == 0x6731) ? 1:0)
+
+static const int DecHwId[] = {
+ 0x8190, /* Legacy HW */
+ 0x8170,
+ 0x9170,
+ 0x9190,
+ 0x6731, /* G1 */
+ 0x6732 /* G2 */
+};
+
+ulong multicorebase[HXDEC_MAX_CORES] = {
+ SOCLE_LOGIC_0_BASE,
+ SOCLE_LOGIC_1_BASE
+};
+
+
+static struct class *hantro_class;
+#define DEVICE_NAME "mxc_hantro"
+
+static struct device *hantro_dev;
+static struct clk *hantro_clk_g1;
+static struct clk *hantro_clk_g2;
+static struct clk *hantro_clk_bus;
+static struct regulator *hantro_regulator;
+
+static int hantro_dbg = -1;
+module_param(hantro_dbg, int, 0644);
+MODULE_PARM_DESC(hantro_dbg, "Debug level (0-1)");
+#undef PDEBUG
+#define PDEBUG(fmt, arg...) \
+ do { \
+ if (hantro_dbg > 0) { \
+ dev_info(hantro_dev, fmt, ## arg); \
+ } \
+ } while (0)
+
+
+static int hantrodec_major; /* dynamic allocation */
+
+/* here's all the must remember stuff */
+typedef struct {
+ char *buffer;
+ unsigned int iosize[HXDEC_MAX_CORES];
+ volatile u8 *hwregs[HXDEC_MAX_CORES];
+ int irq[HXDEC_MAX_CORES];
+ int hw_id[HXDEC_MAX_CORES];
+ int cores;
+ struct fasync_struct *async_queue_dec;
+ struct fasync_struct *async_queue_pp;
+} hantrodec_t;
+
+static hantrodec_t hantrodec_data; /* dynamic allocation? */
+
+static int ReserveIO(void);
+static void ReleaseIO(void);
+
+static void ResetAsic(hantrodec_t *dev);
+
+#ifdef HANTRODEC_DEBUG
+static void dump_regs(hantrodec_t *dev);
+#endif
+
+/* IRQ handler */
+static irqreturn_t hantrodec_isr(int irq, void *dev_id);
+
+static u32 dec_regs[HXDEC_MAX_CORES][DEC_IO_SIZE_MAX/4];
+struct semaphore dec_core_sem;
+struct semaphore pp_core_sem;
+
+static int dec_irq;
+static int pp_irq;
+
+atomic_t irq_rx = ATOMIC_INIT(0);
+atomic_t irq_tx = ATOMIC_INIT(0);
+
+static struct file *dec_owner[HXDEC_MAX_CORES];
+static struct file *pp_owner[HXDEC_MAX_CORES];
+
+/* spinlock_t owner_lock = SPIN_LOCK_UNLOCKED; */
+DEFINE_SPINLOCK(owner_lock);
+
+DECLARE_WAIT_QUEUE_HEAD(dec_wait_queue);
+DECLARE_WAIT_QUEUE_HEAD(pp_wait_queue);
+
+DECLARE_WAIT_QUEUE_HEAD(hw_queue);
+
+#define DWL_CLIENT_TYPE_H264_DEC 1U
+#define DWL_CLIENT_TYPE_MPEG4_DEC 2U
+#define DWL_CLIENT_TYPE_JPEG_DEC 3U
+#define DWL_CLIENT_TYPE_PP 4U
+#define DWL_CLIENT_TYPE_VC1_DEC 5U
+#define DWL_CLIENT_TYPE_MPEG2_DEC 6U
+#define DWL_CLIENT_TYPE_VP6_DEC 7U
+#define DWL_CLIENT_TYPE_AVS_DEC 8U
+#define DWL_CLIENT_TYPE_RV_DEC 9U
+#define DWL_CLIENT_TYPE_VP8_DEC 10U
+#define DWL_CLIENT_TYPE_VP9_DEC 11U
+#define DWL_CLIENT_TYPE_HEVC_DEC 12U
+
+static u32 cfg[HXDEC_MAX_CORES];
+static u32 timeout;
+
+static int hantro_update_voltage(struct device *dev)
+{
+ unsigned long new_vol, old_vol;
+ int ret;
+ unsigned long clk1, clk2;
+
+ clk1 = clk_get_rate(hantro_clk_g1);
+ clk2 = clk_get_rate(hantro_clk_g2);
+
+ if (!clk1 || !clk2)
+ return -1;
+
+ old_vol = regulator_get_voltage(hantro_regulator);
+ if ((clk1 >= HANTRO_CLK_VOL_THR) || (clk2 >= HANTRO_CLK_VOL_THR))
+ new_vol = 1000000; // 1.0v
+ else
+ new_vol = 900000; // 0.9v
+
+ if (old_vol != new_vol) {
+ ret = regulator_set_voltage_tol(hantro_regulator, new_vol, 0);
+ if (ret)
+ pr_err("failed to set hantro voltage: %ld mV\n", new_vol/1000);
+ else
+ pr_info("update hantro voltage from %ld mV to %ld mV\n", old_vol/1000, new_vol/1000);
+ }
+ return 0;
+}
+
+static int hantro_clk_enable(struct device *dev)
+{
+ clk_prepare(hantro_clk_g1);
+ clk_enable(hantro_clk_g1);
+ clk_prepare(hantro_clk_g2);
+ clk_enable(hantro_clk_g2);
+ clk_prepare(hantro_clk_bus);
+ clk_enable(hantro_clk_bus);
+ return 0;
+}
+
+static int hantro_clk_disable(struct device *dev)
+{
+ if (hantro_clk_g1) {
+ clk_disable(hantro_clk_g1);
+ clk_unprepare(hantro_clk_g1);
+ }
+ if (hantro_clk_g2) {
+ clk_disable(hantro_clk_g2);
+ clk_unprepare(hantro_clk_g2);
+ }
+ if (hantro_clk_bus) {
+ clk_disable(hantro_clk_bus);
+ clk_unprepare(hantro_clk_bus);
+ }
+ return 0;
+}
+
+static int hantro_ctrlblk_reset(struct device *dev)
+{
+ volatile u8 *iobase;
+
+ //config G1/G2
+ hantro_clk_enable(dev);
+ iobase = (volatile u8 *)ioremap_nocache(BLK_CTL_BASE, 0x10000);
+ iowrite32(0x3, iobase); //VPUMIX G1/G2 block soft reset control
+ iowrite32(0x3, iobase+4); //VPUMIX G1/G2 block clock enable control
+ iowrite32(0xFFFFFFFF, iobase + 0x8); // all G1 fuse dec enable
+ iowrite32(0xFFFFFFFF, iobase + 0xC); // all G1 fuse pp enable
+ iowrite32(0xFFFFFFFF, iobase + 0x10); // all G2 fuse dec enable
+ iounmap(iobase);
+ hantro_clk_disable(dev);
+ return 0;
+}
+
+#ifdef CONFIG_DEVICE_THERMAL
+static int hantro_thermal_check(struct device *dev)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&thermal_lock, flags);
+ if (thermal_event == thermal_cur) {
+ /*nothing to do and return directly*/
+ spin_unlock_irqrestore(&thermal_lock, flags);
+ return 0;
+ }
+ thermal_cur = thermal_event;
+ spin_unlock_irqrestore(&thermal_lock, flags);
+
+ if (thermal_cur) {
+ int ratio = hantro_clock_ratio;
+
+ pr_debug("hantro: too hot, need to decrease clock, ratio: 1/%d\n", ratio);
+ /*clock disable/enable are not required for vpu clock rate operation*/
+ clk_set_rate(hantro_clk_g1, HANTRO_G1_DEF_CLK/ratio);
+ clk_set_rate(hantro_clk_g2, HANTRO_G2_DEF_CLK/ratio);
+ clk_set_rate(hantro_clk_bus, HANTRO_BUS_DEF_CLK/ratio);
+ } else {
+ pr_debug("hantro: not hot again, will restore default clock\n");
+ clk_set_rate(hantro_clk_g1, HANTRO_G1_DEF_CLK);
+ clk_set_rate(hantro_clk_g2, HANTRO_G2_DEF_CLK);
+ clk_set_rate(hantro_clk_bus, HANTRO_BUS_DEF_CLK);
+ }
+ pr_info("hantro: event(%d), g1, g2, bus clock: %ld, %ld, %ld\n", thermal_cur,
+ clk_get_rate(hantro_clk_g1), clk_get_rate(hantro_clk_g2), clk_get_rate(hantro_clk_bus));
+ hantro_update_voltage(dev);
+ return 0;
+}
+
+static int hantro_thermal_hot_notify(struct notifier_block *nb, unsigned long event, void *dummy)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&thermal_lock, flags);
+ thermal_event = event; /*event: 1: hot, 0: cool*/
+ spin_unlock_irqrestore(&thermal_lock, flags);
+ pr_info("hantro receive hot notification event: %ld\n", event);
+
+ return NOTIFY_OK;
+}
+
+static struct notifier_block hantro_thermal_hot_notifier = {
+ .notifier_call = hantro_thermal_hot_notify,
+};
+#endif //CONFIG_DEVICE_THERMAL
+
+static void ReadCoreConfig(hantrodec_t *dev)
+{
+ int c;
+ u32 reg, tmp, mask;
+
+ memset(cfg, 0, sizeof(cfg));
+
+ for (c = 0; c < dev->cores; c++) {
+ /* Decoder configuration */
+ if (IS_G1(dev->hw_id[c])) {
+ reg = ioread32(dev->hwregs[c] + HANTRODEC_SYNTH_CFG * 4);
+
+ tmp = (reg >> DWL_H264_E) & 0x3U;
+ if (tmp)
+ pr_debug("hantrodec: Core[%d] has H264\n", c);
+ cfg[c] |= tmp ? 1 << DWL_CLIENT_TYPE_H264_DEC : 0;
+
+ tmp = (reg >> DWL_JPEG_E) & 0x01U;
+ if (tmp)
+ pr_debug("hantrodec: Core[%d] has JPEG\n", c);
+ cfg[c] |= tmp ? 1 << DWL_CLIENT_TYPE_JPEG_DEC : 0;
+
+ tmp = (reg >> DWL_MPEG4_E) & 0x3U;
+ if (tmp)
+ pr_debug("hantrodec: Core[%d] has MPEG4\n", c);
+ cfg[c] |= tmp ? 1 << DWL_CLIENT_TYPE_MPEG4_DEC : 0;
+
+ tmp = (reg >> DWL_VC1_E) & 0x3U;
+ if (tmp)
+ pr_debug("hantrodec: Core[%d] has VC1\n", c);
+ cfg[c] |= tmp ? 1 << DWL_CLIENT_TYPE_VC1_DEC : 0;
+
+ tmp = (reg >> DWL_MPEG2_E) & 0x01U;
+ if (tmp)
+ pr_debug("hantrodec: Core[%d] has MPEG2\n", c);
+ cfg[c] |= tmp ? 1 << DWL_CLIENT_TYPE_MPEG2_DEC : 0;
+
+ tmp = (reg >> DWL_VP6_E) & 0x01U;
+ if (tmp)
+ pr_debug("hantrodec: Core[%d] has VP6\n", c);
+ cfg[c] |= tmp ? 1 << DWL_CLIENT_TYPE_VP6_DEC : 0;
+
+ reg = ioread32(dev->hwregs[c] + HANTRODEC_SYNTH_CFG_2 * 4);
+
+ /* VP7 and WEBP is part of VP8 */
+ mask = (1 << DWL_VP8_E) | (1 << DWL_VP7_E) | (1 << DWL_WEBP_E);
+ tmp = (reg & mask);
+ if (tmp & (1 << DWL_VP8_E))
+ pr_debug("hantrodec: Core[%d] has VP8\n", c);
+ if (tmp & (1 << DWL_VP7_E))
+ pr_debug("hantrodec: Core[%d] has VP7\n", c);
+ if (tmp & (1 << DWL_WEBP_E))
+ pr_debug("hantrodec: Core[%d] has WebP\n", c);
+ cfg[c] |= tmp ? 1 << DWL_CLIENT_TYPE_VP8_DEC : 0;
+
+ tmp = (reg >> DWL_AVS_E) & 0x01U;
+ if (tmp)
+ pr_debug("hantrodec: Core[%d] has AVS\n", c);
+ cfg[c] |= tmp ? 1 << DWL_CLIENT_TYPE_AVS_DEC : 0;
+
+ tmp = (reg >> DWL_RV_E) & 0x03U;
+ if (tmp)
+ pr_debug("hantrodec: Core[%d] has RV\n", c);
+ cfg[c] |= tmp ? 1 << DWL_CLIENT_TYPE_RV_DEC : 0;
+
+ /* Post-processor configuration */
+ //reg = ioread32(dev->hwregs[c] + HANTROPP_SYNTH_CFG * 4);
+ } else {
+ reg = ioread32(dev->hwregs[c] + HANTRODEC_SYNTH_CFG_2 * 4);
+
+ tmp = (reg >> DWL_HEVC_E) & 0x3U;
+ if (tmp)
+ pr_debug("hantrodec: Core[%d] has HEVC\n", c);
+ cfg[c] |= tmp ? 1 << DWL_CLIENT_TYPE_HEVC_DEC : 0;
+
+ tmp = (reg >> DWL_VP9_E) & 0x03U;
+ if (tmp)
+ pr_debug("hantrodec: Core[%d] has VP9\n", c);
+ cfg[c] |= tmp ? 1 << DWL_CLIENT_TYPE_VP9_DEC : 0;
+ }
+
+ /* Post-processor configuration */
+ reg = ioread32(dev->hwregs[c] + HANTRODECPP_SYNTH_CFG * 4);
+
+ tmp = (reg >> DWL_PP_E) & 0x01U;
+ if (tmp)
+ pr_debug("hantrodec: Core[%d] has PP\n", c);
+ cfg[c] |= tmp ? 1 << DWL_CLIENT_TYPE_PP : 0;
+ }
+}
+
+static int CoreHasFormat(const u32 *cfg, int Core, u32 format)
+{
+ return (cfg[Core] & (1 << format)) ? 1 : 0;
+}
+
+int GetDecCore(long Core, hantrodec_t *dev, struct file *filp)
+{
+ int success = 0;
+ unsigned long flags;
+
+ spin_lock_irqsave(&owner_lock, flags);
+ if (dec_owner[Core] == NULL) {
+ dec_owner[Core] = filp;
+ success = 1;
+ }
+
+ spin_unlock_irqrestore(&owner_lock, flags);
+
+ return success;
+}
+
+int GetDecCoreAny(long *Core, hantrodec_t *dev, struct file *filp,
+ unsigned long format)
+{
+ int success = 0;
+ long c;
+
+ *Core = -1;
+
+ for (c = 0; c < dev->cores; c++) {
+ /* a free Core that has format */
+ if (CoreHasFormat(cfg, c, format) && GetDecCore(c, dev, filp)) {
+ success = 1;
+ *Core = c;
+ break;
+ }
+ }
+
+ return success;
+}
+int GetDecCoreID(hantrodec_t *dev, struct file *filp,
+ unsigned long format)
+{
+ long c;
+
+ int core_id = -1;
+
+ for (c = 0; c < dev->cores; c++) {
+ /* a Core that has format */
+ if (CoreHasFormat(cfg, c, format)) {
+ core_id = c;
+ break;
+ }
+ }
+ PDEBUG("GetDecCoreID=%d\n", core_id);
+ return core_id;
+}
+
+static int hantrodec_choose_core(int is_g1)
+{
+ volatile unsigned char *reg = NULL;
+ unsigned int blk_base = BLK_CTL_BASE;
+
+ PDEBUG("hantrodec_choose_core\n");
+ if (!request_mem_region(blk_base, 0x1000, "blk_ctl")) {
+ pr_err("blk_ctl: failed to reserve HW regs\n");
+ return -EBUSY;
+ }
+
+ reg = (volatile u8 *) ioremap_nocache(blk_base, 0x1000);
+
+ if (reg == NULL) {
+ pr_err("blk_ctl: failed to ioremap HW regs\n");
+ release_mem_region(blk_base, 0x1000);
+ return -EBUSY;
+ }
+
+ // G1 use, set to 1; G2 use, set to 0, choose the one you are using
+ if (is_g1)
+ iowrite32(0x1, reg + 0x14); // VPUMIX only use G1
+ else
+ iowrite32(0x0, reg + 0x14); // VPUMIX only use G2
+
+ if (reg)
+ iounmap((void *)reg);
+ release_mem_region(blk_base, 0x1000);
+ PDEBUG("hantrodec_choose_core OK!\n");
+ return 0;
+}
+
+
+long ReserveDecoder(hantrodec_t *dev, struct file *filp, unsigned long format)
+{
+ long Core = -1;
+
+ /* reserve a Core */
+ if (down_interruptible(&dec_core_sem))
+ return -ERESTARTSYS;
+
+ /* lock a Core that has specific format*/
+ if (wait_event_interruptible(hw_queue, GetDecCoreAny(&Core, dev, filp, format) != 0))
+ return -ERESTARTSYS;
+
+ if (IS_G1(dev->hw_id[Core])) {
+ if (0 == hantrodec_choose_core(1))
+ PDEBUG("G1 is reserved\n");
+ else
+ return -1;
+ } else {
+ if (0 == hantrodec_choose_core(0))
+ PDEBUG("G2 is reserved\n");
+ else
+ return -1;
+ }
+
+#ifdef CONFIG_DEVICE_THERMAL
+ if (hantro_dynamic_clock)
+ hantro_thermal_check(hantro_dev);
+#endif
+
+ return Core;
+}
+
+void ReleaseDecoder(hantrodec_t *dev, long Core)
+{
+ u32 status;
+ unsigned long flags;
+
+ status = ioread32(dev->hwregs[Core] + HANTRODEC_IRQ_STAT_DEC_OFF);
+
+ /* make sure HW is disabled */
+ if (status & HANTRODEC_DEC_E) {
+ pr_info("hantrodec: DEC[%li] still enabled -> reset\n", Core);
+
+ /* abort decoder */
+ status |= HANTRODEC_DEC_ABORT | HANTRODEC_DEC_IRQ_DISABLE;
+ iowrite32(status, dev->hwregs[Core] + HANTRODEC_IRQ_STAT_DEC_OFF);
+ }
+
+ spin_lock_irqsave(&owner_lock, flags);
+
+ dec_owner[Core] = NULL;
+
+ spin_unlock_irqrestore(&owner_lock, flags);
+
+ up(&dec_core_sem);
+
+ wake_up_interruptible_all(&hw_queue);
+
+}
+
+long ReservePostProcessor(hantrodec_t *dev, struct file *filp)
+{
+ unsigned long flags;
+
+ long Core = 0;
+
+ /* single Core PP only */
+ if (down_interruptible(&pp_core_sem))
+ return -ERESTARTSYS;
+
+ spin_lock_irqsave(&owner_lock, flags);
+
+ pp_owner[Core] = filp;
+
+ spin_unlock_irqrestore(&owner_lock, flags);
+
+ return Core;
+}
+
+void ReleasePostProcessor(hantrodec_t *dev, long Core)
+{
+ unsigned long flags;
+
+ u32 status = ioread32(dev->hwregs[Core] + HANTRO_IRQ_STAT_PP_OFF);
+
+ /* make sure HW is disabled */
+ if (status & HANTRO_PP_E) {
+ pr_info("hantrodec: PP[%li] still enabled -> reset\n", Core);
+
+ /* disable IRQ */
+ status |= HANTRO_PP_IRQ_DISABLE;
+
+ /* disable postprocessor */
+ status &= (~HANTRO_PP_E);
+ iowrite32(0x10, dev->hwregs[Core] + HANTRO_IRQ_STAT_PP_OFF);
+ }
+
+ spin_lock_irqsave(&owner_lock, flags);
+
+ pp_owner[Core] = NULL;
+
+ spin_unlock_irqrestore(&owner_lock, flags);
+
+ up(&pp_core_sem);
+}
+
+long ReserveDecPp(hantrodec_t *dev, struct file *filp, unsigned long format)
+{
+ /* reserve Core 0, DEC+PP for pipeline */
+ unsigned long flags;
+
+ long Core = 0;
+
+ /* check that Core has the requested dec format */
+ if (!CoreHasFormat(cfg, Core, format))
+ return -EFAULT;
+
+ /* check that Core has PP */
+ if (!CoreHasFormat(cfg, Core, DWL_CLIENT_TYPE_PP))
+ return -EFAULT;
+
+ /* reserve a Core */
+ if (down_interruptible(&dec_core_sem))
+ return -ERESTARTSYS;
+
+ /* wait until the Core is available */
+ if (wait_event_interruptible(hw_queue, GetDecCore(Core, dev, filp) != 0)) {
+ up(&dec_core_sem);
+ return -ERESTARTSYS;
+ }
+
+ if (down_interruptible(&pp_core_sem)) {
+ ReleaseDecoder(dev, Core);
+ return -ERESTARTSYS;
+ }
+
+ spin_lock_irqsave(&owner_lock, flags);
+ pp_owner[Core] = filp;
+ spin_unlock_irqrestore(&owner_lock, flags);
+
+ return Core;
+}
+
+long DecFlushRegs(hantrodec_t *dev, struct core_desc *Core)
+{
+ long ret = 0, i;
+
+ u32 id = Core->id;
+
+ if (IS_G1(dev->hw_id[id])) {
+ /* copy original dec regs to kernal space*/
+ ret = copy_from_user(dec_regs[id], Core->regs, HANTRO_DEC_ORG_REGS*4);
+ if (ret) {
+ pr_err("copy_from_user failed, returned %li\n", ret);
+ return -EFAULT;
+ }
+#ifdef USE_64BIT_ENV
+ /* copy extended dec regs to kernal space*/
+ ret = copy_from_user(dec_regs[id] + HANTRO_DEC_EXT_FIRST_REG,
+ Core->regs + HANTRO_DEC_EXT_FIRST_REG, HANTRO_DEC_EXT_REGS * 4);
+#endif
+ if (ret) {
+ pr_err("copy_from_user failed, returned %li\n", ret);
+ return -EFAULT;
+ }
+
+ /* write dec regs but the status reg[1] to hardware */
+ /* both original and extended regs need to be written */
+ for (i = 2; i <= HANTRO_DEC_ORG_LAST_REG; i++)
+ iowrite32(dec_regs[id][i], dev->hwregs[id] + i*4);
+#ifdef USE_64BIT_ENV
+ for (i = HANTRO_DEC_EXT_FIRST_REG; i <= HANTRO_DEC_EXT_LAST_REG; i++)
+ iowrite32(dec_regs[id][i], dev->hwregs[id] + i*4);
+#endif
+ } else {
+ ret = copy_from_user(dec_regs[id], Core->regs, HANTRO_G2_DEC_REGS*4);
+ if (ret) {
+ pr_err("copy_from_user failed, returned %li\n", ret);
+ return -EFAULT;
+ }
+
+ /* write all regs but the status reg[1] to hardware */
+ for (i = 2; i <= HANTRO_G2_DEC_LAST_REG; i++)
+ iowrite32(dec_regs[id][i], dev->hwregs[id] + i*4);
+ }
+
+ /* write the status register, which may start the decoder */
+ iowrite32(dec_regs[id][1], dev->hwregs[id] + 4);
+
+ PDEBUG("flushed registers on Core %d\n", id);
+
+ return 0;
+}
+
+long DecRefreshRegs(hantrodec_t *dev, struct core_desc *Core)
+{
+ long ret, i;
+ u32 id = Core->id;
+
+ if (IS_G1(dev->hw_id[id])) {
+ /* user has to know exactly what they are asking for */
+ //if(Core->size != (HANTRO_DEC_ORG_REGS * 4))
+ // return -EFAULT;
+
+ /* read all registers from hardware */
+ /* both original and extended regs need to be read */
+ for (i = 0; i <= HANTRO_DEC_ORG_LAST_REG; i++)
+ dec_regs[id][i] = ioread32(dev->hwregs[id] + i*4);
+#ifdef USE_64BIT_ENV
+ for (i = HANTRO_DEC_EXT_FIRST_REG; i <= HANTRO_DEC_EXT_LAST_REG; i++)
+ dec_regs[id][i] = ioread32(dev->hwregs[id] + i*4);
+#endif
+
+ if (timeout) {
+ /* Enable TIMEOUT bits in Reg[1] */
+ dec_regs[id][1] = 0x40100;
+ /* Reset HW */
+ ResetAsic(dev);
+ timeout = 0;
+ }
+
+ /* put registers to user space*/
+ /* put original registers to user space*/
+ ret = copy_to_user(Core->regs, dec_regs[id], HANTRO_DEC_ORG_REGS*4);
+#ifdef USE_64BIT_ENV
+ /*put extended registers to user space*/
+ ret = copy_to_user(Core->regs + HANTRO_DEC_EXT_FIRST_REG,
+ dec_regs[id] + HANTRO_DEC_EXT_FIRST_REG, HANTRO_DEC_EXT_REGS * 4);
+#endif
+ if (ret) {
+ pr_err("copy_to_user failed, returned %li\n", ret);
+ return -EFAULT;
+ }
+ } else {
+ /* user has to know exactly what they are asking for */
+ if (Core->size != (HANTRO_G2_DEC_REGS * 4))
+ return -EFAULT;
+
+ /* read all registers from hardware */
+ for (i = 0; i <= HANTRO_G2_DEC_LAST_REG; i++)
+ dec_regs[id][i] = ioread32(dev->hwregs[id] + i*4);
+
+ if (timeout) {
+ /* Enable TIMEOUT bits in Reg[1] */
+ dec_regs[id][1] = 0x40100;
+ /* Reset HW */
+ ResetAsic(dev);
+ timeout = 0;
+ }
+
+ /* put registers to user space*/
+ ret = copy_to_user(Core->regs, dec_regs[id], HANTRO_G2_DEC_REGS*4);
+ if (ret) {
+ pr_err("copy_to_user failed, returned %li\n", ret);
+ return -EFAULT;
+ }
+ }
+ return 0;
+}
+
+static int CheckDecIrq(hantrodec_t *dev, int id)
+{
+ unsigned long flags;
+ int rdy = 0;
+
+ const u32 irq_mask = (1 << id);
+
+ spin_lock_irqsave(&owner_lock, flags);
+
+ if (dec_irq & irq_mask) {
+ /* reset the wait condition(s) */
+ dec_irq &= ~irq_mask;
+ rdy = 1;
+ }
+
+ spin_unlock_irqrestore(&owner_lock, flags);
+
+ return rdy;
+}
+
+long WaitDecReadyAndRefreshRegs(hantrodec_t *dev, struct core_desc *Core)
+{
+ u32 id = Core->id;
+ long ret;
+
+ PDEBUG("wait_event_interruptible DEC[%d]\n", id);
+
+ //ret = wait_event_interruptible_timeout(dec_wait_queue, CheckDecIrq(dev, id), msecs_to_jiffies(200));
+ ret = wait_event_timeout(dec_wait_queue, CheckDecIrq(dev, id), msecs_to_jiffies(200));
+ if (ret == -ERESTARTSYS) {
+ pr_err("DEC[%d] failed to wait_event interrupted\n", id);
+ return -ERESTARTSYS;
+ } else if (ret == 0) {
+ pr_err("DEC[%d] wait_event timeout\n", id);
+ timeout = 1;
+ }
+
+ atomic_inc(&irq_tx);
+
+ /* refresh registers */
+ return DecRefreshRegs(dev, Core);
+}
+
+long PPFlushRegs(hantrodec_t *dev, struct core_desc *Core)
+{
+ long ret = 0;
+ u32 id = Core->id;
+ u32 i;
+
+ /* copy original dec regs to kernal space*/
+ ret = copy_from_user(dec_regs[id] + HANTRO_PP_ORG_FIRST_REG,
+ Core->regs + HANTRO_PP_ORG_FIRST_REG, HANTRO_PP_ORG_REGS*4);
+#ifdef USE_64BIT_ENV
+ /* copy extended dec regs to kernal space*/
+ ret = copy_from_user(dec_regs[id] + HANTRO_PP_EXT_FIRST_REG,
+ Core->regs + HANTRO_PP_EXT_FIRST_REG, HANTRO_PP_EXT_REGS*4);
+#endif
+ if (ret) {
+ pr_err("copy_from_user failed, returned %li\n", ret);
+ return -EFAULT;
+ }
+
+ /* write all regs but the status reg[1] to hardware */
+ /* both original and extended regs need to be written */
+ for (i = HANTRO_PP_ORG_FIRST_REG + 1; i <= HANTRO_PP_ORG_LAST_REG; i++)
+ iowrite32(dec_regs[id][i], dev->hwregs[id] + i*4);
+#ifdef USE_64BIT_ENV
+ for (i = HANTRO_PP_EXT_FIRST_REG; i <= HANTRO_PP_EXT_LAST_REG; i++)
+ iowrite32(dec_regs[id][i], dev->hwregs[id] + i*4);
+#endif
+ /* write the stat reg, which may start the PP */
+ iowrite32(dec_regs[id][HANTRO_PP_ORG_FIRST_REG],
+ dev->hwregs[id] + HANTRO_PP_ORG_FIRST_REG * 4);
+
+ return 0;
+}
+
+long PPRefreshRegs(hantrodec_t *dev, struct core_desc *Core)
+{
+ long i, ret;
+ u32 id = Core->id;
+#ifdef USE_64BIT_ENV
+ /* user has to know exactly what they are asking for */
+ if (Core->size != (HANTRO_PP_TOTAL_REGS * 4))
+ return -EFAULT;
+#else
+ /* user has to know exactly what they are asking for */
+ if (Core->size != (HANTRO_PP_ORG_REGS * 4))
+ return -EFAULT;
+#endif
+
+ /* read all registers from hardware */
+ /* both original and extended regs need to be read */
+ for (i = HANTRO_PP_ORG_FIRST_REG; i <= HANTRO_PP_ORG_LAST_REG; i++)
+ dec_regs[id][i] = ioread32(dev->hwregs[id] + i*4);
+#ifdef USE_64BIT_ENV
+ for (i = HANTRO_PP_EXT_FIRST_REG; i <= HANTRO_PP_EXT_LAST_REG; i++)
+ dec_regs[id][i] = ioread32(dev->hwregs[id] + i*4);
+#endif
+ /* put registers to user space*/
+ /* put original registers to user space*/
+ ret = copy_to_user(Core->regs + HANTRO_PP_ORG_FIRST_REG,
+ dec_regs[id] + HANTRO_PP_ORG_FIRST_REG, HANTRO_PP_ORG_REGS*4);
+#ifdef USE_64BIT_ENV
+ /* put extended registers to user space*/
+ ret = copy_to_user(Core->regs + HANTRO_PP_EXT_FIRST_REG,
+ dec_regs[id] + HANTRO_PP_EXT_FIRST_REG, HANTRO_PP_EXT_REGS * 4);
+#endif
+ if (ret) {
+ pr_err("copy_to_user failed, returned %li\n", ret);
+ return -EFAULT;
+ }
+
+ return 0;
+}
+
+static int CheckPPIrq(hantrodec_t *dev, int id)
+{
+ unsigned long flags;
+ int rdy = 0;
+
+ const u32 irq_mask = (1 << id);
+
+ spin_lock_irqsave(&owner_lock, flags);
+
+ if (pp_irq & irq_mask) {
+ /* reset the wait condition(s) */
+ pp_irq &= ~irq_mask;
+ rdy = 1;
+ }
+
+ spin_unlock_irqrestore(&owner_lock, flags);
+
+ return rdy;
+}
+
+long WaitPPReadyAndRefreshRegs(hantrodec_t *dev, struct core_desc *Core)
+{
+ u32 id = Core->id;
+
+ PDEBUG("wait_event_interruptible PP[%d]\n", id);
+
+ if (wait_event_interruptible(pp_wait_queue, CheckPPIrq(dev, id))) {
+ pr_err("PP[%d] failed to wait_event_interruptible interrupted\n", id);
+ return -ERESTARTSYS;
+ }
+
+ atomic_inc(&irq_tx);
+
+ /* refresh registers */
+ return PPRefreshRegs(dev, Core);
+}
+
+static int CheckCoreIrq(hantrodec_t *dev, const struct file *filp, int *id)
+{
+ unsigned long flags;
+ int rdy = 0, n = 0;
+
+ do {
+ u32 irq_mask = (1 << n);
+
+ spin_lock_irqsave(&owner_lock, flags);
+
+ if (dec_irq & irq_mask) {
+ if (dec_owner[n] == filp) {
+ /* we have an IRQ for our client */
+
+ /* reset the wait condition(s) */
+ dec_irq &= ~irq_mask;
+
+ /* signal ready Core no. for our client */
+ *id = n;
+
+ rdy = 1;
+
+ spin_unlock_irqrestore(&owner_lock, flags);
+ break;
+ } else if (dec_owner[n] == NULL) {
+ /* zombie IRQ */
+ pr_info("IRQ on Core[%d], but no owner!!!\n", n);
+
+ /* reset the wait condition(s) */
+ dec_irq &= ~irq_mask;
+ }
+ }
+
+ spin_unlock_irqrestore(&owner_lock, flags);
+
+ n++; /* next Core */
+ } while (n < dev->cores);
+
+ return rdy;
+}
+
+long WaitCoreReady(hantrodec_t *dev, const struct file *filp, int *id)
+{
+ PDEBUG("wait_event_interruptible CORE\n");
+
+ if (wait_event_interruptible(dec_wait_queue, CheckCoreIrq(dev, filp, id))) {
+ pr_err("CORE failed to wait_event_interruptible interrupted\n");
+ return -ERESTARTSYS;
+ }
+
+ atomic_inc(&irq_tx);
+
+ return 0;
+}
+
+/*-------------------------------------------------------------------------
+ *Function name : hantrodec_ioctl
+ *Description : communication method to/from the user space
+ *
+ *Return type : long
+ *-------------------------------------------------------------------------
+ */
+
+static long hantrodec_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
+{
+ int err = 0;
+ long tmp;
+
+ PDEBUG("ioctl cmd 0x%08x\n", cmd);
+ /*
+ * extract the type and number bitfields, and don't decode
+ * wrong cmds: return ENOTTY (inappropriate ioctl) before access_ok()
+ */
+ if (_IOC_TYPE(cmd) != HANTRODEC_IOC_MAGIC)
+ return -ENOTTY;
+ if (_IOC_NR(cmd) > HANTRODEC_IOC_MAXNR)
+ return -ENOTTY;
+
+ /*
+ * the direction is a bitmask, and VERIFY_WRITE catches R/W
+ * transfers. `Type' is user-oriented, while
+ * access_ok is kernel-oriented, so the concept of "read" and
+ * "write" is reversed
+ */
+ if (_IOC_DIR(cmd) & _IOC_READ)
+ err = !access_ok(VERIFY_WRITE, (void *) arg, _IOC_SIZE(cmd));
+ else if (_IOC_DIR(cmd) & _IOC_WRITE)
+ err = !access_ok(VERIFY_READ, (void *) arg, _IOC_SIZE(cmd));
+
+ if (err)
+ return -EFAULT;
+
+ switch (_IOC_NR(cmd)) {
+ case _IOC_NR(HANTRODEC_IOC_CLI): {
+ __u32 id;
+
+ __get_user(id, (__u32 *)arg);
+ if (id >= hantrodec_data.cores)
+ return -EFAULT;
+ disable_irq(hantrodec_data.irq[id]);
+ break;
+ }
+ case _IOC_NR(HANTRODEC_IOC_STI): {
+ __u32 id;
+
+ __get_user(id, (__u32 *)arg);
+ if (id >= hantrodec_data.cores)
+ return -EFAULT;
+ enable_irq(hantrodec_data.irq[id]);
+ break;
+ }
+ case _IOC_NR(HANTRODEC_IOCGHWOFFSET): {
+ __u32 id;
+
+ __get_user(id, (__u32 *)arg);
+ if (id >= hantrodec_data.cores)
+ return -EFAULT;
+
+ __put_user(multicorebase[id], (unsigned long *) arg);
+ break;
+ }
+ case _IOC_NR(HANTRODEC_IOCGHWIOSIZE): {
+ __u32 id;
+ __u32 io_size;
+
+ __get_user(id, (__u32 *)arg);
+ if (id >= hantrodec_data.cores)
+ return -EFAULT;
+ io_size = hantrodec_data.iosize[id];
+ __put_user(io_size, (u32 *) arg);
+
+ return 0;
+ }
+ case _IOC_NR(HANTRODEC_IOC_MC_OFFSETS): {
+ tmp = copy_to_user((u64 *) arg, multicorebase, sizeof(multicorebase));
+ if (err) {
+ pr_err("copy_to_user failed, returned %li\n", tmp);
+ return -EFAULT;
+ }
+ break;
+ }
+ case _IOC_NR(HANTRODEC_IOC_MC_CORES):
+ __put_user(hantrodec_data.cores, (unsigned int *) arg);
+ PDEBUG("hantrodec_data.cores=%d\n", hantrodec_data.cores);
+ break;
+ case _IOC_NR(HANTRODEC_IOCS_DEC_PUSH_REG): {
+ struct core_desc Core;
+
+ /* get registers from user space*/
+ tmp = copy_from_user(&Core, (void *)arg, sizeof(struct core_desc));
+ if (tmp) {
+ pr_err("copy_from_user failed, returned %li\n", tmp);
+ return -EFAULT;
+ }
+
+ if (Core.id >= hantrodec_data.cores)
+ return -EFAULT;
+
+ DecFlushRegs(&hantrodec_data, &Core);
+ break;
+ }
+ case _IOC_NR(HANTRODEC_IOCS_PP_PUSH_REG): {
+ struct core_desc Core;
+
+ /* get registers from user space*/
+ tmp = copy_from_user(&Core, (void *)arg, sizeof(struct core_desc));
+ if (tmp) {
+ pr_err("copy_from_user failed, returned %li\n", tmp);
+ return -EFAULT;
+ }
+
+ if (Core.id >= hantrodec_data.cores)
+ return -EFAULT;
+
+ PPFlushRegs(&hantrodec_data, &Core);
+ break;
+ }
+ case _IOC_NR(HANTRODEC_IOCS_DEC_PULL_REG): {
+ struct core_desc Core;
+
+ /* get registers from user space*/
+ tmp = copy_from_user(&Core, (void *)arg, sizeof(struct core_desc));
+ if (tmp) {
+ pr_err("copy_from_user failed, returned %li\n", tmp);
+ return -EFAULT;
+ }
+
+ if (Core.id >= hantrodec_data.cores)
+ return -EFAULT;
+
+ return DecRefreshRegs(&hantrodec_data, &Core);
+ }
+ case _IOC_NR(HANTRODEC_IOCS_PP_PULL_REG): {
+ struct core_desc Core;
+
+ /* get registers from user space*/
+ tmp = copy_from_user(&Core, (void *)arg, sizeof(struct core_desc));
+ if (tmp) {
+ pr_err("copy_from_user failed, returned %li\n", tmp);
+ return -EFAULT;
+ }
+
+ if (Core.id >= hantrodec_data.cores)
+ return -EFAULT;
+
+ return PPRefreshRegs(&hantrodec_data, &Core);
+ }
+ case _IOC_NR(HANTRODEC_IOCH_DEC_RESERVE): {
+ PDEBUG("Reserve DEC Core, format = %li\n", arg);
+ return ReserveDecoder(&hantrodec_data, filp, arg);
+ }
+ case _IOC_NR(HANTRODEC_IOCT_DEC_RELEASE): {
+ if (arg >= hantrodec_data.cores || dec_owner[arg] != filp) {
+ pr_err("bogus DEC release, Core = %li\n", arg);
+ return -EFAULT;
+ }
+
+ PDEBUG("Release DEC, Core = %li\n", arg);
+
+ ReleaseDecoder(&hantrodec_data, arg);
+
+ break;
+ }
+ case _IOC_NR(HANTRODEC_IOCQ_PP_RESERVE):
+ return ReservePostProcessor(&hantrodec_data, filp);
+ case _IOC_NR(HANTRODEC_IOCT_PP_RELEASE): {
+ if (arg != 0 || pp_owner[arg] != filp) {
+ pr_err("bogus PP release %li\n", arg);
+ return -EFAULT;
+ }
+
+ ReleasePostProcessor(&hantrodec_data, arg);
+
+ break;
+ }
+ case _IOC_NR(HANTRODEC_IOCX_DEC_WAIT): {
+ struct core_desc Core;
+
+ /* get registers from user space */
+ tmp = copy_from_user(&Core, (void *)arg, sizeof(struct core_desc));
+ if (tmp) {
+ pr_err("copy_from_user failed, returned %li\n", tmp);
+ return -EFAULT;
+ }
+
+ if (Core.id >= hantrodec_data.cores)
+ return -EFAULT;
+
+ return WaitDecReadyAndRefreshRegs(&hantrodec_data, &Core);
+ }
+ case _IOC_NR(HANTRODEC_IOCX_PP_WAIT): {
+ struct core_desc Core;
+
+ /* get registers from user space */
+ tmp = copy_from_user(&Core, (void *)arg, sizeof(struct core_desc));
+ if (tmp) {
+ pr_err("copy_from_user failed, returned %li\n", tmp);
+ return -EFAULT;
+ }
+
+ if (Core.id >= hantrodec_data.cores)
+ return -EFAULT;
+
+ return WaitPPReadyAndRefreshRegs(&hantrodec_data, &Core);
+ }
+ case _IOC_NR(HANTRODEC_IOCG_CORE_WAIT): {
+ int id;
+
+ tmp = WaitCoreReady(&hantrodec_data, filp, &id);
+ __put_user(id, (int *) arg);
+ return tmp;
+ }
+ case _IOC_NR(HANTRODEC_IOX_ASIC_ID): {
+ u32 id;
+
+ __get_user(id, (u32 *)arg);
+ if (id >= hantrodec_data.cores)
+ return -EFAULT;
+ id = ioread32(hantrodec_data.hwregs[id]);
+ __put_user(id, (u32 *) arg);
+ return 0;
+ }
+ case _IOC_NR(HANTRODEC_IOCG_CORE_ID): {
+ PDEBUG("Get DEC Core_id, format = %li\n", arg);
+ return GetDecCoreID(&hantrodec_data, filp, arg);
+ }
+ case _IOC_NR(HANTRODEC_DEBUG_STATUS): {
+ PDEBUG("hantrodec: dec_irq = 0x%08x\n", dec_irq);
+ PDEBUG("hantrodec: pp_irq = 0x%08x\n", pp_irq);
+
+ PDEBUG("hantrodec: IRQs received/sent2user = %d / %d\n",
+ atomic_read(&irq_rx), atomic_read(&irq_tx));
+
+ for (tmp = 0; tmp < hantrodec_data.cores; tmp++) {
+ PDEBUG("hantrodec: dec_core[%li] %s\n",
+ tmp, dec_owner[tmp] == NULL ? "FREE" : "RESERVED");
+ PDEBUG("hantrodec: pp_core[%li] %s\n",
+ tmp, pp_owner[tmp] == NULL ? "FREE" : "RESERVED");
+ }
+ }
+ default:
+ return -ENOTTY;
+ }
+
+ return 0;
+}
+
+#ifdef CONFIG_COMPAT
+struct core_desc_32 {
+ __u32 id; /* id of the Core */
+ compat_caddr_t regs; /* pointer to user registers */
+ __u32 size; /* size of register space */
+};
+
+static int get_hantro_core_desc32(struct core_desc *kp, struct core_desc_32 __user *up)
+{
+ u32 tmp;
+
+ if (!access_ok(VERIFY_READ, up, sizeof(struct core_desc_32)) ||
+ get_user(kp->id, &up->id) ||
+ get_user(kp->size, &up->size) ||
+ get_user(tmp, &up->regs)) {
+ return -EFAULT;
+ }
+ kp->regs = (__force u32 *)compat_ptr(tmp);
+ return 0;
+}
+
+static int put_hantro_core_desc32(struct core_desc *kp, struct core_desc_32 __user *up)
+{
+ u32 tmp = (u32)((unsigned long)kp->regs);
+
+ if (!access_ok(VERIFY_WRITE, up, sizeof(struct core_desc_32)) ||
+ put_user(kp->id, &up->id) ||
+ put_user(kp->size, &up->size) ||
+ put_user(tmp, &up->regs)) {
+ return -EFAULT;
+ }
+ return 0;
+}
+static long hantrodec_ioctl32(struct file *filp, unsigned int cmd, unsigned long arg)
+{
+#define HANTRO_IOCTL32(err, filp, cmd, arg) { \
+ mm_segment_t old_fs = get_fs(); \
+ set_fs(KERNEL_DS); \
+ err = hantrodec_ioctl(filp, cmd, arg); \
+ if (err) \
+ return err; \
+ set_fs(old_fs); \
+ }
+
+ union {
+ struct core_desc kcore;
+ unsigned long kux;
+ unsigned int kui;
+ } karg;
+ void __user *up = compat_ptr(arg);
+ long err = 0;
+
+ switch (_IOC_NR(cmd)) {
+ case _IOC_NR(HANTRODEC_IOCGHWOFFSET):
+ case _IOC_NR(HANTRODEC_IOC_MC_OFFSETS):
+ err = get_user(karg.kux, (s32 __user *)up);
+ if (err)
+ return err;
+ HANTRO_IOCTL32(err, filp, cmd, (unsigned long)&karg);
+ err = put_user(((s32)karg.kux), (s32 __user *)up);
+ break;
+ case _IOC_NR(HANTRODEC_IOCGHWIOSIZE):
+ case _IOC_NR(HANTRODEC_IOC_MC_CORES):
+ case _IOC_NR(HANTRODEC_IOCG_CORE_WAIT):
+ case _IOC_NR(HANTRODEC_IOX_ASIC_ID):
+ err = get_user(karg.kui, (s32 __user *)up);
+ if (err)
+ return err;
+ HANTRO_IOCTL32(err, filp, cmd, (unsigned long)&karg);
+ err = put_user(((s32)karg.kui), (s32 __user *)up);
+ break;
+ case _IOC_NR(HANTRODEC_IOCS_DEC_PUSH_REG):
+ case _IOC_NR(HANTRODEC_IOCS_PP_PUSH_REG):
+ case _IOC_NR(HANTRODEC_IOCX_DEC_WAIT):
+ case _IOC_NR(HANTRODEC_IOCX_PP_WAIT):
+ case _IOC_NR(HANTRODEC_IOCS_DEC_PULL_REG):
+ case _IOC_NR(HANTRODEC_IOCS_PP_PULL_REG):
+ err = get_hantro_core_desc32(&karg.kcore, up);
+ if (err)
+ return err;
+ HANTRO_IOCTL32(err, filp, cmd, (unsigned long)&karg);
+ err = put_hantro_core_desc32(&karg.kcore, up);
+ break;
+ default:
+ err = hantrodec_ioctl(filp, cmd, (unsigned long)up);
+ break;
+ }
+
+ return err;
+}
+
+#endif //ifdef CONFIG_COMPAT
+
+/*--------------------------------------------------------------------------
+ *Function name : hantrodec_open
+ *Description : open method
+ *
+ *Return type : int
+ *---------------------------------------------------------------------------
+ */
+static int hantrodec_open(struct inode *inode, struct file *filp)
+{
+ PDEBUG("dev opened\n");
+ hantro_clk_enable(hantro_dev);
+ pm_runtime_get_sync(hantro_dev);
+ return 0;
+}
+
+/*---------------------------------------------------------------------------
+ *Function name : hantrodec_release
+ *Description : Release driver
+ *
+ *Return type : int
+ *----------------------------------------------------------------------------
+ */
+static int hantrodec_release(struct inode *inode, struct file *filp)
+{
+ int n;
+ hantrodec_t *dev = &hantrodec_data;
+
+ PDEBUG("closing ...\n");
+
+ for (n = 0; n < dev->cores; n++) {
+ if (dec_owner[n] == filp) {
+ PDEBUG("releasing dec Core %i lock\n", n);
+ ReleaseDecoder(dev, n);
+ }
+ }
+
+ for (n = 0; n < 1; n++) {
+ if (pp_owner[n] == filp) {
+ PDEBUG("releasing pp Core %i lock\n", n);
+ ReleasePostProcessor(dev, n);
+ }
+ }
+
+ pm_runtime_put_sync(hantro_dev);
+ hantro_clk_disable(hantro_dev);
+ PDEBUG("closed\n");
+ return 0;
+}
+
+/*---------------------------------------------------------------------------
+ *Function name : hantro_mmap
+ *Description : memory map interface for hantro file operation
+ *
+ *Return type : int
+ *---------------------------------------------------------------------------
+ */
+static int hantro_mmap(struct file *fp, struct vm_area_struct *vm)
+{
+ if (vm->vm_pgoff == (multicorebase[0] >> PAGE_SHIFT) || vm->vm_pgoff == (multicorebase[1] >> PAGE_SHIFT)) {
+ vm->vm_flags |= VM_IO;
+ vm->vm_page_prot = pgprot_noncached(vm->vm_page_prot);
+ PDEBUG("hantro mmap: size=0x%lX, page off=0x%lX\n", (vm->vm_end - vm->vm_start), vm->vm_pgoff);
+ return remap_pfn_range(vm, vm->vm_start, vm->vm_pgoff, vm->vm_end - vm->vm_start,
+ vm->vm_page_prot) ? -EAGAIN : 0;
+ } else {
+ pr_err("invalid map offset :0x%lX\n", vm->vm_pgoff);
+ return -EINVAL;
+ }
+}
+
+/* VFS methods */
+static const struct file_operations hantrodec_fops = {
+ .owner = THIS_MODULE,
+ .open = hantrodec_open,
+ .release = hantrodec_release,
+ .unlocked_ioctl = hantrodec_ioctl,
+ .fasync = NULL,
+ .mmap = hantro_mmap,
+#ifdef CONFIG_COMPAT
+ .compat_ioctl = hantrodec_ioctl32,
+#endif
+};
+
+/*---------------------------------------------------------------------------
+ *Function name : hantrodec_init
+ *Description : Initialize the driver
+ *
+ *Return type : int
+ *---------------------------------------------------------------------------
+ */
+int hantrodec_init(struct platform_device *pdev)
+{
+ int result;
+ int irq_0, irq_1;
+
+ dec_irq = 0;
+ pp_irq = 0;
+ pr_debug("hantrodec: Init multi Core[0] at 0x%16lx\n"
+ " Core[1] at 0x%16lx\n", multicorebase[0], multicorebase[1]);
+
+ hantrodec_data.cores = 0;
+ hantrodec_data.iosize[0] = DEC_IO_SIZE_0;
+ hantrodec_data.iosize[1] = DEC_IO_SIZE_1;
+
+ hantrodec_data.async_queue_dec = NULL;
+ hantrodec_data.async_queue_pp = NULL;
+
+ result = register_chrdev(hantrodec_major, "hantrodec", &hantrodec_fops);
+ if (result < 0) {
+ pr_err("hantrodec: unable to get major %d\n", hantrodec_major);
+ goto err;
+ } else if (result != 0) { /* this is for dynamic major */
+ hantrodec_major = result;
+ }
+
+ result = ReserveIO();
+ if (result < 0)
+ goto err;
+
+ memset(dec_owner, 0, sizeof(dec_owner));
+ memset(pp_owner, 0, sizeof(pp_owner));
+
+ sema_init(&dec_core_sem, hantrodec_data.cores-1);
+ sema_init(&pp_core_sem, 1);
+
+ /* read configuration fo all cores */
+ ReadCoreConfig(&hantrodec_data);
+
+ /* reset hardware */
+ ResetAsic(&hantrodec_data);
+
+ /* register irq for each core*/
+ irq_0 = platform_get_irq_byname(pdev, "irq_hantro_g1");
+ if (irq_0 > 0) {
+ hantrodec_data.irq[0] = irq_0;
+ result = request_irq(irq_0, hantrodec_isr, IRQF_SHARED,
+ "hantrodec", (void *) &hantrodec_data);
+
+ if (result != 0) {
+ if (result == -EINVAL)
+ pr_err("hantrodec: Bad irq number or handler\n");
+ else if (result == -EBUSY) {
+ pr_err("hantrodec: IRQ <%d> busy, change your config\n",
+ hantrodec_data.irq[0]);
+ }
+ ReleaseIO();
+ goto err;
+ }
+ } else {
+ pr_err("hantrodec: IRQ0 not in use!\n");
+ goto err;
+ }
+
+ irq_1 = platform_get_irq_byname(pdev, "irq_hantro_g2");
+ if (irq_1 > 0) {
+ hantrodec_data.irq[1] = irq_1;
+ result = request_irq(irq_1, hantrodec_isr, IRQF_SHARED,
+ "hantrodec", (void *) &hantrodec_data);
+
+ if (result != 0) {
+ if (result == -EINVAL)
+ pr_err("hantrodec: Bad irq number or handler\n");
+ else if (result == -EBUSY) {
+ pr_err("hantrodec: IRQ <%d> busy, change your config\n",
+ hantrodec_data.irq[1]);
+ }
+
+ ReleaseIO();
+ goto err;
+ }
+ } else {
+ pr_err("hantrodec: IRQ1 not in use!\n");
+ goto err;
+ }
+ pr_info("hantrodec: module inserted. Major = %d\n", hantrodec_major);
+
+ return 0;
+
+err:
+ pr_err("hantrodec: module not inserted\n");
+ unregister_chrdev(hantrodec_major, "hantrodec");
+ return result;
+}
+
+/*---------------------------------------------------------------------------
+ *Function name : hantrodec_cleanup
+ *Description : clean up
+ *
+ *Return type : int
+ *---------------------------------------------------------------------------
+ */
+void hantrodec_cleanup(void)
+{
+ hantrodec_t *dev = &hantrodec_data;
+ int n = 0;
+ /* reset hardware */
+ ResetAsic(dev);
+
+ /* free the IRQ */
+ for (n = 0; n < dev->cores; n++) {
+ if (dev->irq[n] != -1)
+ free_irq(dev->irq[n], (void *) dev);
+ }
+
+ ReleaseIO();
+
+ unregister_chrdev(hantrodec_major, "hantrodec");
+
+ PDEBUG("hantrodec: module removed\n");
+
+}
+
+/*---------------------------------------------------------------------------
+ *Function name : CheckHwId
+ *Return type : int
+ *---------------------------------------------------------------------------
+ */
+static int CheckHwId(hantrodec_t *dev)
+{
+ long int hwid;
+ int i;
+ size_t num_hw = sizeof(DecHwId) / sizeof(*DecHwId);
+
+ int found = 0;
+
+ for (i = 0; i < dev->cores; i++) {
+ if (dev->hwregs[i] != NULL) {
+ hwid = readl(dev->hwregs[i]);
+ pr_debug("hantrodec: Core %d HW ID=0x%16lx\n", i, hwid);
+ hwid = (hwid >> 16) & 0xFFFF; /* product version only */
+
+ while (num_hw--) {
+ if (hwid == DecHwId[num_hw]) {
+ pr_debug("hantrodec: Supported HW found at 0x%16lx\n",
+ multicorebase[i]);
+ found++;
+ dev->hw_id[i] = hwid;
+ break;
+ }
+ }
+ if (!found) {
+ pr_err("hantrodec: Unknown HW found at 0x%16lx\n", multicorebase[i]);
+ return 0;
+ }
+ found = 0;
+ num_hw = sizeof(DecHwId) / sizeof(*DecHwId);
+ }
+ }
+
+ return 1;
+}
+
+/*---------------------------------------------------------------------------
+ *Function name : ReserveIO
+ *Description : IO reserve
+ *
+ *Return type : int
+ *---------------------------------------------------------------------------
+ */
+static int ReserveIO(void)
+{
+ int i;
+
+ for (i = 0; i < HXDEC_MAX_CORES; i++) {
+ if (multicorebase[i] != -1) {
+ if (!request_mem_region(multicorebase[i], hantrodec_data.iosize[i], "hantrodec0")) {
+ pr_err("hantrodec: failed to reserve HW regs\n");
+ return -EBUSY;
+ }
+
+ hantrodec_data.hwregs[i] = (volatile u8 *) ioremap_nocache(multicorebase[i],
+ hantrodec_data.iosize[i]);
+
+ if (hantrodec_data.hwregs[i] == NULL) {
+ pr_err("hantrodec: failed to ioremap HW regs\n");
+ ReleaseIO();
+ return -EBUSY;
+ }
+ hantrodec_data.cores++;
+ }
+ }
+
+ /* check for correct HW */
+ if (!CheckHwId(&hantrodec_data)) {
+ ReleaseIO();
+ return -EBUSY;
+ }
+
+ return 0;
+}
+
+/*---------------------------------------------------------------------------
+ *Function name : releaseIO
+ *Description : release
+ *
+ *Return type : void
+ *---------------------------------------------------------------------------
+ */
+static void ReleaseIO(void)
+{
+ int i;
+
+ for (i = 0; i < hantrodec_data.cores; i++) {
+ if (hantrodec_data.hwregs[i])
+ iounmap((void *) hantrodec_data.hwregs[i]);
+ release_mem_region(multicorebase[i], hantrodec_data.iosize[i]);
+ }
+}
+
+/*---------------------------------------------------------------------------
+ *Function name : hantrodec_isr
+ *Description : interrupt handler
+ *
+ *Return type : irqreturn_t
+ *---------------------------------------------------------------------------
+ */
+irqreturn_t hantrodec_isr(int irq, void *dev_id)
+{
+ unsigned long flags;
+ unsigned int handled = 0;
+ int i;
+ volatile u8 *hwregs;
+
+ hantrodec_t *dev = (hantrodec_t *) dev_id;
+ u32 irq_status_dec;
+
+ spin_lock_irqsave(&owner_lock, flags);
+
+ for (i = 0; i < dev->cores; i++) {
+ volatile u8 *hwregs = dev->hwregs[i];
+
+ /* interrupt status register read */
+ irq_status_dec = ioread32(hwregs + HANTRODEC_IRQ_STAT_DEC_OFF);
+
+ if (irq_status_dec & HANTRODEC_DEC_IRQ) {
+ /* clear dec IRQ */
+ irq_status_dec &= (~HANTRODEC_DEC_IRQ);
+ iowrite32(irq_status_dec, hwregs + HANTRODEC_IRQ_STAT_DEC_OFF);
+
+ PDEBUG("decoder IRQ received! Core %d\n", i);
+
+ atomic_inc(&irq_rx);
+
+ dec_irq |= (1 << i);
+
+ //wake_up_interruptible_all(&dec_wait_queue);
+ wake_up_all(&dec_wait_queue);
+ handled++;
+ }
+ }
+
+ spin_unlock_irqrestore(&owner_lock, flags);
+
+ if (!handled)
+ pr_info("IRQ received, but not hantrodec's!\n");
+
+ (void)hwregs;
+ return IRQ_RETVAL(handled);
+}
+
+/*---------------------------------------------------------------------------
+ *Function name : ResetAsic
+ *Description : reset asic
+ *
+ *Return type :
+ *---------------------------------------------------------------------------
+ */
+void ResetAsic(hantrodec_t *dev)
+{
+ int i, j;
+ u32 status;
+
+ for (j = 0; j < dev->cores; j++) {
+ status = ioread32(dev->hwregs[j] + HANTRODEC_IRQ_STAT_DEC_OFF);
+
+ if (status & HANTRODEC_DEC_E) {
+ /* abort with IRQ disabled */
+ status = HANTRODEC_DEC_ABORT | HANTRODEC_DEC_IRQ_DISABLE;
+ iowrite32(status, dev->hwregs[j] + HANTRODEC_IRQ_STAT_DEC_OFF);
+ }
+
+ if (IS_G1(dev->hw_id[j]))
+ /* reset PP */
+ iowrite32(0, dev->hwregs[j] + HANTRO_IRQ_STAT_PP_OFF);
+
+ for (i = 4; i < dev->iosize[j]; i += 4)
+ iowrite32(0, dev->hwregs[j] + i);
+ }
+}
+
+/*---------------------------------------------------------------------------
+ *Function name : dump_regs
+ *Description : Dump registers
+ *
+ *Return type :
+ *---------------------------------------------------------------------------
+ */
+#ifdef HANTRODEC_DEBUG
+void dump_regs(hantrodec_t *dev)
+{
+ int i, c;
+
+ PDEBUG("Reg Dump Start\n");
+ for (c = 0; c < dev->cores; c++) {
+ for (i = 0; i < dev->iosize[c]; i += 4*4) {
+ PDEBUG("\toffset %04X: %08X %08X %08X %08X\n", i,
+ ioread32(dev->hwregs[c] + i),
+ ioread32(dev->hwregs[c] + i + 4),
+ ioread32(dev->hwregs[c] + i + 8),
+ ioread32(dev->hwregs[c] + i + 12));
+ }
+ }
+ PDEBUG("Reg Dump End\n");
+}
+#endif
+
+static int hantro_dev_probe(struct platform_device *pdev)
+{
+ int err = 0;
+ struct device *temp_class;
+ struct resource *res;
+ unsigned long reg_base;
+
+ hantro_dev = &pdev->dev;
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "regs_hantro");
+ if (!res) {
+ pr_err("hantro: unable to get vpu base addr\n");
+ return -ENODEV;
+ }
+ reg_base = res->start;
+ if ((ulong)reg_base != multicorebase[0]) {
+ pr_err("hantrodec: regbase(0x%lX) not equal to expected value(0x%lX)\n", reg_base, multicorebase[0]);
+ return -ENODEV;
+ }
+
+ hantro_clk_g1 = clk_get(&pdev->dev, "clk_hantro_g1");
+ hantro_clk_g2 = clk_get(&pdev->dev, "clk_hantro_g2");
+ hantro_clk_bus = clk_get(&pdev->dev, "clk_hantro_bus");
+ if (IS_ERR(hantro_clk_g1) || IS_ERR(hantro_clk_g2) || IS_ERR(hantro_clk_bus)) {
+ pr_err("hantro: get clock failed\n");
+ return -ENODEV;
+ }
+ pr_debug("hantro: g1, g2, bus clock: 0x%lX, 0x%lX, 0x%lX\n", clk_get_rate(hantro_clk_g1),
+ clk_get_rate(hantro_clk_g2), clk_get_rate(hantro_clk_bus));
+
+ hantro_regulator = regulator_get(&pdev->dev, "regulator");
+ if (IS_ERR(hantro_regulator)) {
+ pr_err("hantro: get regulator failed\n");
+ return -ENODEV;
+ }
+ hantro_update_voltage(&pdev->dev);
+
+ hantro_clk_enable(&pdev->dev);
+ pm_runtime_enable(&pdev->dev);
+ pm_runtime_get_sync(&pdev->dev);
+ hantro_ctrlblk_reset(&pdev->dev);
+
+ err = hantrodec_init(pdev);
+ if (0 != err) {
+ pr_err("hantro: hantrodec_init failed\n");
+ goto error;
+ }
+
+ hantro_class = class_create(THIS_MODULE, "mxc_hantro");
+ if (IS_ERR(hantro_class)) {
+ err = PTR_ERR(hantro_class);
+ goto error;
+ }
+ temp_class = device_create(hantro_class, NULL, MKDEV(hantrodec_major, 0), NULL, DEVICE_NAME);
+ if (IS_ERR(temp_class)) {
+ err = PTR_ERR(temp_class);
+ goto err_out_class;
+ }
+
+#ifdef CONFIG_DEVICE_THERMAL
+ HANTRO_REG_THERMAL_NOTIFIER(&hantro_thermal_hot_notifier);
+ thermal_event = 0;
+ thermal_cur = 0;
+ hantro_dynamic_clock = 0;
+#endif
+ timeout = 0;
+ goto out;
+
+err_out_class:
+ device_destroy(hantro_class, MKDEV(hantrodec_major, 0));
+ class_destroy(hantro_class);
+error:
+ pr_err("hantro probe failed\n");
+out:
+ pm_runtime_put_sync(&pdev->dev);
+ hantro_clk_disable(&pdev->dev);
+ return err;
+}
+
+static int hantro_dev_remove(struct platform_device *pdev)
+{
+ hantro_clk_enable(&pdev->dev);
+ pm_runtime_get_sync(&pdev->dev);
+ if (hantrodec_major > 0) {
+ device_destroy(hantro_class, MKDEV(hantrodec_major, 0));
+ class_destroy(hantro_class);
+ hantrodec_cleanup();
+ hantrodec_major = 0;
+ }
+ pm_runtime_put_sync(&pdev->dev);
+ pm_runtime_disable(&pdev->dev);
+ hantro_clk_disable(&pdev->dev);
+
+#ifdef CONFIG_DEVICE_THERMAL
+ HANTRO_UNREG_THERMAL_NOTIFIER(&hantro_thermal_hot_notifier);
+#endif
+
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int hantro_suspend(struct device *dev)
+{
+ pm_runtime_put_sync_suspend(dev); //power off
+ return 0;
+}
+static int hantro_resume(struct device *dev)
+{
+ pm_runtime_get_sync(dev); //power on
+ hantro_ctrlblk_reset(dev);
+ return 0;
+}
+static int hantro_runtime_suspend(struct device *dev)
+{
+ release_bus_freq(BUS_FREQ_HIGH);
+ return 0;
+}
+
+static int hantro_runtime_resume(struct device *dev)
+{
+ request_bus_freq(BUS_FREQ_HIGH);
+ hantro_ctrlblk_reset(dev);
+ return 0;
+}
+
+static const struct dev_pm_ops hantro_pm_ops = {
+ SET_RUNTIME_PM_OPS(hantro_runtime_suspend, hantro_runtime_resume, NULL)
+ SET_SYSTEM_SLEEP_PM_OPS(hantro_suspend, hantro_resume)
+};
+#endif //CONFIG_PM
+
+static const struct of_device_id hantro_of_match[] = {
+ { .compatible = "nxp,imx8mq-hantro", },
+ {/* sentinel */}
+};
+MODULE_DEVICE_TABLE(of, hantro_of_match);
+
+
+static struct platform_driver mxchantro_driver = {
+ .driver = {
+ .name = "mxc_hantro",
+ .of_match_table = hantro_of_match,
+#ifdef CONFIG_PM
+ .pm = &hantro_pm_ops,
+#endif
+ },
+ .probe = hantro_dev_probe,
+ .remove = hantro_dev_remove,
+};
+
+static int __init hantro_init(void)
+{
+ int ret = platform_driver_register(&mxchantro_driver);
+
+ return ret;
+}
+
+static void __exit hantro_exit(void)
+{
+ if (!IS_ERR(hantro_clk_g1))
+ clk_put(hantro_clk_g1);
+ if (!IS_ERR(hantro_clk_g2))
+ clk_put(hantro_clk_g2);
+ if (!IS_ERR(hantro_clk_bus))
+ clk_put(hantro_clk_bus);
+ if (!IS_ERR(hantro_regulator))
+ regulator_put(hantro_regulator);
+ platform_driver_unregister(&mxchantro_driver);
+}
+
+module_init(hantro_init);
+module_exit(hantro_exit);
+
+/* module description */
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Google Finland Oy");
+MODULE_DESCRIPTION("Driver module for Hantro Decoder/Post-Processor");
+
diff --git a/drivers/mxc/hantro_845/Kconfig b/drivers/mxc/hantro_845/Kconfig
new file mode 100755
index 000000000000..6b59c33f91c6
--- /dev/null
+++ b/drivers/mxc/hantro_845/Kconfig
@@ -0,0 +1,14 @@
+#
+# Codec configuration
+#
+
+menu "MXC HANTRO(Video Processing Unit) 845 support"
+ depends on ARCH_FSL_IMX8MQ
+
+config MXC_HANTRO_845
+ tristate "Support for MXC HANTRO(Video Processing Unit) 845"
+ default y
+ ---help---
+ VPU codec device.
+
+endmenu
diff --git a/drivers/mxc/hantro_845/Makefile b/drivers/mxc/hantro_845/Makefile
new file mode 100755
index 000000000000..575756282a8b
--- /dev/null
+++ b/drivers/mxc/hantro_845/Makefile
@@ -0,0 +1,8 @@
+#
+# Makefile for the VPU drivers.
+#
+
+#ccflags-y += -I$(PWD)
+
+obj-$(CONFIG_MXC_HANTRO_845) += hantrodec_845s.o
+
diff --git a/drivers/mxc/hantro_845/dwl_defs.h b/drivers/mxc/hantro_845/dwl_defs.h
new file mode 100644
index 000000000000..8976dcf156b6
--- /dev/null
+++ b/drivers/mxc/hantro_845/dwl_defs.h
@@ -0,0 +1,94 @@
+/*****************************************************************************
+ * The GPL License (GPL)
+ *
+ * Copyright (c) 2015-2017, VeriSilicon Inc.
+ * Copyright (c) 2011-2014, Google 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.
+ *
+ * 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 may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ *****************************************************************************/
+
+#ifndef SOFTWARE_LINUX_DWL_DWL_DEFS_H_
+#define SOFTWARE_LINUX_DWL_DWL_DEFS_H_
+
+#define DWL_MPEG2_E 31 /* 1 bit */
+#define DWL_VC1_E 29 /* 2 bits */
+#define DWL_JPEG_E 28 /* 1 bit */
+#define DWL_MPEG4_E 26 /* 2 bits */
+#define DWL_H264_E 24 /* 2 bits */
+#define DWL_VP6_E 23 /* 1 bit */
+#define DWL_RV_E 26 /* 2 bits */
+#define DWL_VP8_E 23 /* 1 bit */
+#define DWL_VP7_E 24 /* 1 bit */
+#define DWL_WEBP_E 19 /* 1 bit */
+#define DWL_AVS_E 22 /* 1 bit */
+#if 0
+#define DWL_PP_E 16 /* 1 bit */
+#endif
+#define DWL_PP_E 31 /* 1 bit */
+#define DWL_HEVC_E 5 /* 2 bits */
+#define DWL_VP9_E 3 /* 2 bits */
+
+#define DWL_HEVC_ENA 0 /* 1 bits */
+#define DWL_VP9_ENA 1 /* 1 bits */
+#define DWL_RFC_E 2 /* 1 bits */
+#define DWL_DS_E 3 /* 1 bits */
+#define DWL_HEVC_VER 8 /* 4 bits */
+#define DWL_VP9_PROFILE 12 /* 3 bits */
+#define DWL_RING_E 16 /* 1 bits */
+
+#define HANTRODEC_IRQ_STAT_DEC 1
+#define HANTRODEC_IRQ_STAT_DEC_OFF (HANTRODEC_IRQ_STAT_DEC * 4)
+
+#define HANTRODECPP_SYNTH_CFG 60
+#define HANTRODECPP_SYNTH_CFG_OFF (HANTRODECPP_SYNTH_CFG * 4)
+#define HANTRODEC_SYNTH_CFG 50
+#define HANTRODEC_SYNTH_CFG_OFF (HANTRODEC_SYNTH_CFG * 4)
+#define HANTRODEC_SYNTH_CFG_2 54
+#define HANTRODEC_SYNTH_CFG_2_OFF (HANTRODEC_SYNTH_CFG_2 * 4)
+#define HANTRODEC_SYNTH_CFG_3 56
+#define HANTRODEC_SYNTH_CFG_3_OFF (HANTRODEC_SYNTH_CFG_3 * 4)
+#define HANTRODEC_CFG_STAT 23
+#define HANTRODEC_CFG_STAT_OFF (HANTRODEC_CFG_STAT * 4)
+
+
+#define HANTRODEC_DEC_E 0x01
+#define HANTRODEC_PP_E 0x01
+#define HANTRODEC_DEC_ABORT 0x20
+#define HANTRODEC_DEC_IRQ_DISABLE 0x10
+#define HANTRODEC_DEC_IRQ 0x100
+
+/* Legacy from G1 */
+#define HANTRO_IRQ_STAT_DEC 1
+#define HANTRO_IRQ_STAT_DEC_OFF (HANTRO_IRQ_STAT_DEC * 4)
+#define HANTRO_IRQ_STAT_PP 60
+#define HANTRO_IRQ_STAT_PP_OFF (HANTRO_IRQ_STAT_PP * 4)
+
+#define HANTROPP_SYNTH_CFG 100
+#define HANTROPP_SYNTH_CFG_OFF (HANTROPP_SYNTH_CFG * 4)
+#define HANTRODEC_SYNTH_CFG 50
+#define HANTRODEC_SYNTH_CFG_OFF (HANTRODEC_SYNTH_CFG * 4)
+#define HANTRODEC_SYNTH_CFG_2 54
+#define HANTRODEC_SYNTH_CFG_2_OFF (HANTRODEC_SYNTH_CFG_2 * 4)
+
+#define HANTRO_DEC_E 0x01
+#define HANTRO_PP_E 0x01
+#define HANTRO_DEC_ABORT 0x20
+#define HANTRO_DEC_IRQ_DISABLE 0x10
+#define HANTRO_PP_IRQ_DISABLE 0x10
+#define HANTRO_DEC_IRQ 0x100
+#define HANTRO_PP_IRQ 0x100
+
+#endif /* SOFTWARE_LINUX_DWL_DWL_DEFS_H_ */
diff --git a/drivers/mxc/hantro_845/hantrodec_845s.c b/drivers/mxc/hantro_845/hantrodec_845s.c
new file mode 100755
index 000000000000..2bd424c5fed9
--- /dev/null
+++ b/drivers/mxc/hantro_845/hantrodec_845s.c
@@ -0,0 +1,2039 @@
+/*****************************************************************************
+ * The GPL License (GPL)
+ *
+ * Copyright (c) 2015-2018, VeriSilicon Inc.
+ * Copyright (c) 2011-2014, Google 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.
+ *
+ * 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 may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ *****************************************************************************/
+#include <linux/hantrodec.h>
+#include "dwl_defs.h"
+#include <linux/io.h>
+#include <linux/uaccess.h>
+#include <linux/errno.h>
+#include <linux/fs.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/pci.h>
+#include <linux/sched.h>
+#include <linux/semaphore.h>
+#include <linux/spinlock.h>
+#include <linux/slab.h>
+#include <linux/version.h>
+#include <linux/wait.h>
+#include <linux/timer.h>
+#include <linux/clk.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/clk.h>
+#include <linux/busfreq-imx.h>
+
+#include <linux/delay.h>
+
+//#define CONFIG_DEVICE_THERMAL_HANTRO
+#ifdef CONFIG_DEVICE_THERMAL_HANTRO
+#include <linux/device_cooling.h>
+#define HANTRO_REG_THERMAL_NOTIFIER(a) register_devfreq_cooling_notifier(a)
+#define HANTRO_UNREG_THERMAL_NOTIFIER(a) unregister_devfreq_cooling_notifier(a)
+static DEFINE_SPINLOCK(thermal_lock);
+/*1:hot, 0: not hot*/
+static int thermal_event;
+static int hantro_clock_ratio = 2;
+static int hantro_dynamic_clock;
+module_param(hantro_clock_ratio, int, 0644);
+module_param(hantro_dynamic_clock, int, 0644);
+MODULE_PARM_DESC(hantro_clock_ratio, "clock ratio 1/N");
+MODULE_PARM_DESC(hantro_dynamic_clock, "enable or disable dynamic clock rate");
+#endif
+
+/*hantro G1 regs config including dec and pp*/
+#define HANTRO_DEC_ORG_REGS 60
+#define HANTRO_PP_ORG_REGS 41
+
+#define HANTRO_DEC_EXT_REGS 27
+#define HANTRO_PP_EXT_REGS 9
+
+#define HANTRO_G1_DEC_TOTAL_REGS (HANTRO_DEC_ORG_REGS + HANTRO_DEC_EXT_REGS)
+#define HANTRO_PP_TOTAL_REGS (HANTRO_PP_ORG_REGS + HANTRO_PP_EXT_REGS)
+#define HANTRO_G1_TOTAL_REGS 155 /*G1 total regs*/
+
+#define HANTRO_DEC_ORG_FIRST_REG 0
+#define HANTRO_DEC_ORG_LAST_REG 59
+#define HANTRO_DEC_EXT_FIRST_REG 119
+#define HANTRO_DEC_EXT_LAST_REG 145
+
+#define HANTRO_PP_ORG_FIRST_REG 60
+#define HANTRO_PP_ORG_LAST_REG 100
+#define HANTRO_PP_EXT_FIRST_REG 146
+#define HANTRO_PP_EXT_LAST_REG 154
+
+/*hantro G2 reg config*/
+#define HANTRO_G2_DEC_REGS 265 /*G2 total regs*/
+
+#define HANTRO_G2_DEC_FIRST_REG 0
+#define HANTRO_G2_DEC_LAST_REG (HANTRO_G2_DEC_REGS - 1)
+
+#define MAX(a, b) (((a) > (b)) ? (a) : (b))
+
+#define DEC_IO_SIZE_MAX (MAX(HANTRO_G2_DEC_REGS, HANTRO_G1_TOTAL_REGS) * 4)
+
+/********************************************************************
+ * PORTING SEGMENT
+ * NOTES: customer should modify these configuration if do porting to own platform.
+ * Please guarantee the base_addr, io_size,dec_irq belong to same core.
+ ********************************************************************/
+
+#define HXDEC_MAX_CORES 2
+
+/* Logic module base address */
+#define SOCLE_LOGIC_0_BASE 0x38300000
+#define SOCLE_LOGIC_1_BASE 0x38310000
+#define BLK_CTL_BASE 0x38330000 //0x38320000
+
+#define VEXPRESS_LOGIC_0_BASE 0xFC010000
+#define VEXPRESS_LOGIC_1_BASE 0xFC020000
+
+#define DEC_IO_SIZE_0 ((HANTRO_G2_DEC_REGS) * 4) /* bytes */
+#define DEC_IO_SIZE_1 ((HANTRO_G2_DEC_REGS) * 4) /* bytes */
+
+#define HANTRO_DEC_DEF_CLK (600000000)
+#define HANTRO_BUS_DEF_CLK (800000000)
+/***********************************************************************/
+
+#define IS_G1(hw_id) ((hw_id == 0x6731) ? 1:0)
+
+static const int DecHwId[] = {
+ 0x8190, /* Legacy HW */
+ 0x8170,
+ 0x9170,
+ 0x9190,
+ 0x6731, /* G1 */
+ 0x6732 /* G2 */
+};
+
+static ulong multicorebase[HXDEC_MAX_CORES] = {
+ SOCLE_LOGIC_0_BASE,
+ SOCLE_LOGIC_1_BASE
+};
+
+
+static struct class *hantro_class;
+#define DEVICE_NAME "mxc_hantro"
+
+//static struct device *hantro_dev[HXDEC_MAX_CORES];
+
+typedef struct {
+ struct clk *dec;
+ struct clk *bus;
+} hantrodec_clk;
+
+static int hantro_dbg = -1;
+module_param(hantro_dbg, int, 0644);
+MODULE_PARM_DESC(hantro_dbg, "Debug level (0-1)");
+#undef PDEBUG
+#define PDEBUG(fmt, arg...) \
+ do { \
+ if (hantro_dbg > 0) { \
+ dev_info(hantrodec_data[0].dev, fmt, ## arg); \
+ } \
+ } while (0)
+
+
+static int hantrodec_major;
+static int cores = 2;
+/* here's all the must remember stuff */
+typedef struct {
+ //char *buffer;
+ unsigned int iosize;
+ volatile u8 *hwregs;
+ int irq;
+ int hw_id;
+ int core_id;
+ //int cores;
+ //struct fasync_struct *async_queue_dec;
+ //struct fasync_struct *async_queue_pp;
+ hantrodec_clk clk;
+ u32 dec_regs[DEC_IO_SIZE_MAX/4];
+ struct semaphore dec_core_sem;
+ struct semaphore pp_core_sem;
+ struct file *dec_owner;
+ struct file *pp_owner;
+ u32 cfg;
+ u32 timeout;
+ atomic_t irq_rx;
+ atomic_t irq_tx;
+ struct device *dev;
+ struct mutex dev_mutex;
+ int thermal_cur;
+} hantrodec_t;
+
+static hantrodec_t hantrodec_data[HXDEC_MAX_CORES]; /* dynamic allocation? */
+
+typedef struct {
+ char inst_id;
+ char core_id; //1:g1; 2:g2; 3:unknow
+} hantrodec_instance;
+static unsigned long instance_mask;
+#define MAX_HANTRODEC_INSTANCE 32
+static hantrodec_instance hantrodec_ctx[MAX_HANTRODEC_INSTANCE];
+
+static int ReserveIO(int);
+static void ReleaseIO(int);
+
+static void ResetAsic(hantrodec_t *dev);
+
+#ifdef HANTRODEC_DEBUG
+static void dump_regs(hantrodec_t *dev);
+#endif
+
+/* IRQ handler */
+static irqreturn_t hantrodec_isr(int irq, void *dev_id);
+
+static int dec_irq;
+static int pp_irq;
+
+
+/* spinlock_t owner_lock = SPIN_LOCK_UNLOCKED; */
+static DEFINE_SPINLOCK(owner_lock);
+
+static DECLARE_WAIT_QUEUE_HEAD(dec_wait_queue);
+static DECLARE_WAIT_QUEUE_HEAD(pp_wait_queue);
+
+static DECLARE_WAIT_QUEUE_HEAD(hw_queue);
+
+#define DWL_CLIENT_TYPE_H264_DEC 1U
+#define DWL_CLIENT_TYPE_MPEG4_DEC 2U
+#define DWL_CLIENT_TYPE_JPEG_DEC 3U
+#define DWL_CLIENT_TYPE_PP 4U
+#define DWL_CLIENT_TYPE_VC1_DEC 5U
+#define DWL_CLIENT_TYPE_MPEG2_DEC 6U
+#define DWL_CLIENT_TYPE_VP6_DEC 7U
+#define DWL_CLIENT_TYPE_AVS_DEC 8U
+#define DWL_CLIENT_TYPE_RV_DEC 9U
+#define DWL_CLIENT_TYPE_VP8_DEC 10U
+#define DWL_CLIENT_TYPE_VP9_DEC 11U
+#define DWL_CLIENT_TYPE_HEVC_DEC 12U
+
+static int hantro_device_id(struct device *dev)
+{
+ int id;
+
+ if (strcmp("vpu_g1", dev->of_node->name) == 0) {
+ id = 0;
+ } else if (strcmp("vpu_g2", dev->of_node->name) == 0) {
+ id = 1;
+ } else {
+ return id = -1;
+ }
+ return id;
+}
+static int hantro_clk_enable(hantrodec_clk *clk)
+{
+ clk_prepare(clk->dec);
+ clk_enable(clk->dec);
+ clk_prepare(clk->bus);
+ clk_enable(clk->bus);
+ return 0;
+}
+
+static int hantro_clk_disable(hantrodec_clk *clk)
+{
+ clk_disable(clk->dec);
+ clk_unprepare(clk->dec);
+ clk_disable(clk->bus);
+ clk_unprepare(clk->bus);
+ return 0;
+}
+
+static int hantro_ctrlblk_reset(hantrodec_t *dev)
+{
+ volatile u8 *iobase;
+ u32 val;
+
+ //config G1/G2
+ hantro_clk_enable(&dev->clk);
+ iobase = (volatile u8 *)ioremap_nocache(BLK_CTL_BASE, 0x10000);
+ if (dev->core_id == 0) {
+ val = ioread32(iobase);
+ val &= (~0x2);
+ iowrite32(val, iobase); //assert G1 block soft reset control
+ udelay(2);
+ val = ioread32(iobase);
+ val |= 0x2;
+ iowrite32(val, iobase); //desert G1 block soft reset control
+
+ val = ioread32(iobase+4);
+ val |= 0x2;
+ iowrite32(val, iobase+4); //VPUMIX G1 block clock enable control
+ iowrite32(0xFFFFFFFF, iobase + 0x8); // all G1 fuse dec enable
+ iowrite32(0xFFFFFFFF, iobase + 0xC); // all G1 fuse pp enable
+ } else {
+ val = ioread32(iobase);
+ val &= (~0x1);
+ iowrite32(val, iobase); //assert G2 block soft reset control
+ udelay(2);
+ val = ioread32(iobase);
+ val |= 0x1;
+ iowrite32(val, iobase); //desert G2 block soft reset control
+
+ val = ioread32(iobase+4);
+ val |= 0x1;
+ iowrite32(val, iobase+4); //VPUMIX G2 block clock enable control
+ iowrite32(0xFFFFFFFF, iobase + 0x10); // all G2 fuse dec enable
+ }
+ iounmap(iobase);
+ hantro_clk_disable(&dev->clk);
+ return 0;
+}
+
+static int hantro_power_on_disirq(hantrodec_t *hantrodev)
+{
+ //spin_lock_irq(&owner_lock);
+ mutex_lock(&hantrodev->dev_mutex);
+ disable_irq(hantrodev->irq);
+ pm_runtime_get_sync(hantrodev->dev);
+ enable_irq(hantrodev->irq);
+ mutex_unlock(&hantrodev->dev_mutex);
+ //spin_unlock_irq(&owner_lock);
+ return 0;
+}
+
+static int hantro_new_instance(void)
+{
+ int idx;
+
+ spin_lock(&owner_lock);
+ if (instance_mask == ((1UL << MAX_HANTRODEC_INSTANCE) - 1)) {
+ spin_unlock(&owner_lock);
+ return -1;
+ }
+ idx = ffz(instance_mask);
+ set_bit(idx, &instance_mask);
+ spin_unlock(&owner_lock);
+ return idx;
+}
+
+static int hantro_free_instance(int idx)
+{
+ spin_lock(&owner_lock);
+ clear_bit(idx, &instance_mask);
+ spin_unlock(&owner_lock);
+
+ return 0;
+}
+
+#ifdef CONFIG_DEVICE_THERMAL_HANTRO
+static int hantro_thermal_check(struct device *dev)
+{
+ hantrodec_t *hantrodev = dev_get_drvdata(dev);
+ unsigned long flags;
+
+ spin_lock_irqsave(&thermal_lock, flags);
+ if (thermal_event == hantrodev->thermal_cur) {
+ /*nothing to do and return directly*/
+ spin_unlock_irqrestore(&thermal_lock, flags);
+ return 0;
+ }
+ hantrodev->thermal_cur = thermal_event;
+ spin_unlock_irqrestore(&thermal_lock, flags);
+
+ if (hantrodev->thermal_cur) {
+ int ratio = hantro_clock_ratio;
+
+ pr_debug("hantro[%d]: too hot, need to decrease clock, ratio: 1/%d\n", hantrodev->core_id, ratio);
+ /*clock disable/enable are not required for vpu clock rate operation*/
+ clk_set_rate(hantrodev->clk.dec, HANTRO_DEC_DEF_CLK/ratio);
+ clk_set_rate(hantrodev->clk.bus, HANTRO_BUS_DEF_CLK/ratio);
+ } else {
+ pr_debug("hantro[%d]: not hot again, will restore default clock\n", hantrodev->core_id);
+ clk_set_rate(hantrodev->clk.dec, HANTRO_DEC_DEF_CLK);
+ clk_set_rate(hantrodev->clk.bus, HANTRO_BUS_DEF_CLK);
+ }
+ pr_info("hantro[%d]: event(%d), dec, bus clock: %ld, %ld\n", hantrodev->core_id, hantrodev->thermal_cur,
+ clk_get_rate(hantrodev->clk.dec), clk_get_rate(hantrodev->clk.bus));
+ return 0;
+}
+
+static int hantro_thermal_hot_notify(struct notifier_block *nb, unsigned long event, void *dummy)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&thermal_lock, flags);
+ thermal_event = event; /*event: 1: hot, 0: cool*/
+ spin_unlock_irqrestore(&thermal_lock, flags);
+ pr_info("hantro receive hot notification event: %ld\n", event);
+
+ return NOTIFY_OK;
+}
+
+static struct notifier_block hantro_thermal_hot_notifier = {
+ .notifier_call = hantro_thermal_hot_notify,
+};
+#endif //CONFIG_DEVICE_THERMAL_HANTRO
+
+static void ReadCoreConfig(hantrodec_t *dev)
+{
+ int c = dev->core_id;
+ u32 reg, tmp, mask;
+
+ memset(&dev->cfg, 0, sizeof(dev->cfg));
+
+ //for (c = 0; c < dev->cores; c++) {
+ /* Decoder configuration */
+ if (IS_G1(dev->hw_id)) {
+ reg = ioread32(dev->hwregs + HANTRODEC_SYNTH_CFG * 4);
+
+ tmp = (reg >> DWL_H264_E) & 0x3U;
+ if (tmp)
+ pr_debug("hantrodec: Core[%d] has H264\n", c);
+ dev->cfg |= tmp ? 1 << DWL_CLIENT_TYPE_H264_DEC : 0;
+
+ tmp = (reg >> DWL_JPEG_E) & 0x01U;
+ if (tmp)
+ pr_debug("hantrodec: Core[%d] has JPEG\n", c);
+ dev->cfg |= tmp ? 1 << DWL_CLIENT_TYPE_JPEG_DEC : 0;
+
+ tmp = (reg >> DWL_MPEG4_E) & 0x3U;
+ if (tmp)
+ pr_debug("hantrodec: Core[%d] has MPEG4\n", c);
+ dev->cfg |= tmp ? 1 << DWL_CLIENT_TYPE_MPEG4_DEC : 0;
+
+ tmp = (reg >> DWL_VC1_E) & 0x3U;
+ if (tmp)
+ pr_debug("hantrodec: Core[%d] has VC1\n", c);
+ dev->cfg |= tmp ? 1 << DWL_CLIENT_TYPE_VC1_DEC : 0;
+
+ tmp = (reg >> DWL_MPEG2_E) & 0x01U;
+ if (tmp)
+ pr_debug("hantrodec: Core[%d] has MPEG2\n", c);
+ dev->cfg |= tmp ? 1 << DWL_CLIENT_TYPE_MPEG2_DEC : 0;
+
+ tmp = (reg >> DWL_VP6_E) & 0x01U;
+ if (tmp)
+ pr_debug("hantrodec: Core[%d] has VP6\n", c);
+ dev->cfg |= tmp ? 1 << DWL_CLIENT_TYPE_VP6_DEC : 0;
+
+ reg = ioread32(dev->hwregs + HANTRODEC_SYNTH_CFG_2 * 4);
+
+ /* VP7 and WEBP is part of VP8 */
+ mask = (1 << DWL_VP8_E) | (1 << DWL_VP7_E) | (1 << DWL_WEBP_E);
+ tmp = (reg & mask);
+ if (tmp & (1 << DWL_VP8_E))
+ pr_debug("hantrodec: Core[%d] has VP8\n", c);
+ if (tmp & (1 << DWL_VP7_E))
+ pr_debug("hantrodec: Core[%d] has VP7\n", c);
+ if (tmp & (1 << DWL_WEBP_E))
+ pr_debug("hantrodec: Core[%d] has WebP\n", c);
+ dev->cfg |= tmp ? 1 << DWL_CLIENT_TYPE_VP8_DEC : 0;
+
+ tmp = (reg >> DWL_AVS_E) & 0x01U;
+ if (tmp)
+ pr_debug("hantrodec: Core[%d] has AVS\n", c);
+ dev->cfg |= tmp ? 1 << DWL_CLIENT_TYPE_AVS_DEC : 0;
+
+ tmp = (reg >> DWL_RV_E) & 0x03U;
+ if (tmp)
+ pr_debug("hantrodec: Core[%d] has RV\n", c);
+ dev->cfg |= tmp ? 1 << DWL_CLIENT_TYPE_RV_DEC : 0;
+
+ /* Post-processor configuration */
+ //reg = ioread32(dev->hwregs + HANTROPP_SYNTH_CFG * 4);
+ } else {
+ reg = ioread32(dev->hwregs + HANTRODEC_SYNTH_CFG_2 * 4);
+
+ tmp = (reg >> DWL_HEVC_E) & 0x3U;
+ if (tmp)
+ pr_debug("hantrodec: Core[%d] has HEVC\n", c);
+ dev->cfg |= tmp ? 1 << DWL_CLIENT_TYPE_HEVC_DEC : 0;
+
+ tmp = (reg >> DWL_VP9_E) & 0x03U;
+ if (tmp)
+ pr_debug("hantrodec: Core[%d] has VP9\n", c);
+ dev->cfg |= tmp ? 1 << DWL_CLIENT_TYPE_VP9_DEC : 0;
+ }
+
+ /* Post-processor configuration */
+ reg = ioread32(dev->hwregs + HANTRODECPP_SYNTH_CFG * 4);
+
+ tmp = (reg >> DWL_PP_E) & 0x01U;
+ if (tmp)
+ pr_debug("hantrodec: Core[%d] has PP\n", c);
+ dev->cfg |= tmp ? 1 << DWL_CLIENT_TYPE_PP : 0;
+ //}
+}
+
+static int CoreHasFormat(const u32 cfg, u32 format)
+{
+ return (cfg & (1 << format)) ? 1 : 0;
+}
+
+static int GetDecCore(hantrodec_t *dev, struct file *filp)
+{
+ int success = 0;
+ unsigned long flags;
+
+ spin_lock_irqsave(&owner_lock, flags);
+ if (dev->dec_owner == NULL) {
+ dev->dec_owner = filp;
+ success = 1;
+ }
+
+ spin_unlock_irqrestore(&owner_lock, flags);
+
+ return success;
+}
+
+static int GetDecCoreAny(long *Core, hantrodec_t *dev, struct file *filp,
+ unsigned long format)
+{
+ int success = 0;
+ //long c;
+
+ *Core = -1;
+
+ //for (c = 0; c < dev->cores; c++) {
+ /* a free Core that has format */
+ if (CoreHasFormat(dev->cfg, format) && GetDecCore(dev, filp)) {
+ success = 1;
+ *Core = dev->core_id;
+ //break;
+ }
+ //}
+
+ return success;
+}
+
+static int GetDecCoreID(unsigned long format)
+{
+ long c;
+
+ int core_id = -1;
+
+ for (c = 0; c < cores; c++) {
+ /* a Core that has format */
+ if (CoreHasFormat(hantrodec_data[c].cfg, format)) {
+ core_id = c;
+ break;
+ }
+ }
+ PDEBUG("GetDecCoreID=%d\n", core_id);
+ return core_id;
+}
+#if 0
+static int hantrodec_choose_core(int is_g1)
+{
+ volatile unsigned char *reg = NULL;
+ unsigned int blk_base = BLK_CTL_BASE;
+
+ PDEBUG("hantrodec_choose_core\n");
+ if (!request_mem_region(blk_base, 0x1000, "blk_ctl")) {
+ pr_err("blk_ctl: failed to reserve HW regs\n");
+ return -EBUSY;
+ }
+
+ reg = (volatile u8 *) ioremap_nocache(blk_base, 0x1000);
+
+ if (reg == NULL) {
+ pr_err("blk_ctl: failed to ioremap HW regs\n");
+ if (reg)
+ iounmap((void *)reg);
+ release_mem_region(blk_base, 0x1000);
+ return -EBUSY;
+ }
+
+ // G1 use, set to 1; G2 use, set to 0, choose the one you are using
+ if (is_g1)
+ iowrite32(0x1, reg + 0x14); // VPUMIX only use G1
+ else
+ iowrite32(0x0, reg + 0x14); // VPUMIX only use G2
+
+ if (reg)
+ iounmap((void *)reg);
+ release_mem_region(blk_base, 0x1000);
+ PDEBUG("hantrodec_choose_core OK!\n");
+ return 0;
+}
+#endif
+
+static long ReserveDecoder(hantrodec_t *dev, struct file *filp, unsigned long format)
+{
+ long Core = -1;
+
+ /* reserve a Core */
+ if (down_interruptible(&dev->dec_core_sem))
+ return -ERESTARTSYS;
+
+#if 1
+ if (GetDecCoreAny(&Core, dev, filp, format) == 0) {
+ pr_err("Core %d is already been reserved !\n", dev->core_id);
+ return -1;
+ }
+#else
+ /* lock a Core that has specific format*/
+ if (wait_event_interruptible(hw_queue, GetDecCoreAny(&Core, dev, filp, format) != 0))
+ return -ERESTARTSYS;
+#endif
+#if 0
+ if (IS_G1(dev->hw_id)) {
+ if (0 == hantrodec_choose_core(1))
+ PDEBUG("G1 is reserved\n");
+ else
+ return -1;
+ } else {
+ if (0 == hantrodec_choose_core(0))
+ PDEBUG("G2 is reserved\n");
+ else
+ return -1;
+ }
+#endif
+#ifdef CONFIG_DEVICE_THERMAL_HANTRO
+ if (hantro_dynamic_clock)
+ hantro_thermal_check(dev->dev);
+#endif
+
+ return Core;
+}
+
+static void ReleaseDecoder(hantrodec_t *dev)
+{
+ u32 status;
+ unsigned long flags;
+
+ status = ioread32(dev->hwregs + HANTRODEC_IRQ_STAT_DEC_OFF);
+
+ /* make sure HW is disabled */
+ if (status & HANTRODEC_DEC_E) {
+ pr_info("hantrodec: DEC[%d] still enabled -> reset\n", dev->core_id);
+
+ /* abort decoder */
+ status |= HANTRODEC_DEC_ABORT | HANTRODEC_DEC_IRQ_DISABLE;
+ iowrite32(status, dev->hwregs + HANTRODEC_IRQ_STAT_DEC_OFF);
+ }
+
+ spin_lock_irqsave(&owner_lock, flags);
+
+ dev->dec_owner = NULL;
+
+ spin_unlock_irqrestore(&owner_lock, flags);
+
+ up(&dev->dec_core_sem);
+
+ //wake_up_interruptible_all(&hw_queue);
+
+}
+
+static long ReservePostProcessor(hantrodec_t *dev, struct file *filp)
+{
+ unsigned long flags;
+
+ long Core = 0;
+
+ /* single Core PP only */
+ if (down_interruptible(&dev->pp_core_sem))
+ return -ERESTARTSYS;
+
+ spin_lock_irqsave(&owner_lock, flags);
+
+ dev->pp_owner = filp;
+
+ spin_unlock_irqrestore(&owner_lock, flags);
+
+ return Core;
+}
+
+static void ReleasePostProcessor(hantrodec_t *dev)
+{
+ unsigned long flags;
+
+ u32 status = ioread32(dev->hwregs + HANTRO_IRQ_STAT_PP_OFF);
+
+ /* make sure HW is disabled */
+ if (status & HANTRO_PP_E) {
+ pr_info("hantrodec: PP[%d] still enabled -> reset\n", dev->core_id);
+
+ /* disable IRQ */
+ status |= HANTRO_PP_IRQ_DISABLE;
+
+ /* disable postprocessor */
+ status &= (~HANTRO_PP_E);
+ iowrite32(0x10, dev->hwregs + HANTRO_IRQ_STAT_PP_OFF);
+ }
+
+ spin_lock_irqsave(&owner_lock, flags);
+
+ dev->pp_owner = NULL;
+
+ spin_unlock_irqrestore(&owner_lock, flags);
+
+ up(&dev->pp_core_sem);
+}
+
+#if 0
+static long ReserveDecPp(hantrodec_t *dev, struct file *filp, unsigned long format)
+{
+ /* reserve Core 0, DEC+PP for pipeline */
+ unsigned long flags;
+
+ long Core = 0;
+
+ /* check that Core has the requested dec format */
+ if (!CoreHasFormat(dev->cfg, format))
+ return -EFAULT;
+
+ /* check that Core has PP */
+ if (!CoreHasFormat(dev->cfg, DWL_CLIENT_TYPE_PP))
+ return -EFAULT;
+
+ /* reserve a Core */
+ if (down_interruptible(&dev->dec_core_sem))
+ return -ERESTARTSYS;
+
+ /* wait until the Core is available */
+ if (wait_event_interruptible(hw_queue, GetDecCore(dev, filp) != 0)) {
+ up(&dev->dec_core_sem);
+ return -ERESTARTSYS;
+ }
+
+ if (down_interruptible(&dev->pp_core_sem)) {
+ ReleaseDecoder(dev);
+ return -ERESTARTSYS;
+ }
+
+ spin_lock_irqsave(&owner_lock, flags);
+ dev->pp_owner = filp;
+ spin_unlock_irqrestore(&owner_lock, flags);
+
+ return Core;
+}
+#endif
+static long DecFlushRegs(hantrodec_t *dev, struct core_desc *Core)
+{
+ long ret = 0, i;
+
+ //u32 id = Core->id;
+
+ if (IS_G1(dev->hw_id)) {
+ /* copy original dec regs to kernal space*/
+ ret = copy_from_user(dev->dec_regs, Core->regs, HANTRO_DEC_ORG_REGS*4);
+ if (ret) {
+ pr_err("copy_from_user failed, returned %li\n", ret);
+ return -EFAULT;
+ }
+#ifdef USE_64BIT_ENV
+ /* copy extended dec regs to kernal space*/
+ ret = copy_from_user(dev->dec_regs + HANTRO_DEC_EXT_FIRST_REG,
+ Core->regs + HANTRO_DEC_EXT_FIRST_REG, HANTRO_DEC_EXT_REGS * 4);
+#endif
+ if (ret) {
+ pr_err("copy_from_user failed, returned %li\n", ret);
+ return -EFAULT;
+ }
+
+ /* write dec regs but the status reg[1] to hardware */
+ /* both original and extended regs need to be written */
+ for (i = 2; i <= HANTRO_DEC_ORG_LAST_REG; i++)
+ iowrite32(dev->dec_regs[i], dev->hwregs + i*4);
+#ifdef USE_64BIT_ENV
+ for (i = HANTRO_DEC_EXT_FIRST_REG; i <= HANTRO_DEC_EXT_LAST_REG; i++)
+ iowrite32(dev->dec_regs[i], dev->hwregs + i*4);
+#endif
+ } else {
+ ret = copy_from_user(dev->dec_regs, Core->regs, HANTRO_G2_DEC_REGS*4);
+ if (ret) {
+ pr_err("copy_from_user failed, returned %li\n", ret);
+ return -EFAULT;
+ }
+
+ /* write all regs but the status reg[1] to hardware */
+ for (i = 2; i <= HANTRO_G2_DEC_LAST_REG; i++)
+ iowrite32(dev->dec_regs[i], dev->hwregs + i*4);
+ }
+
+ /* write the status register, which may start the decoder */
+ iowrite32(dev->dec_regs[1], dev->hwregs + 4);
+
+ PDEBUG("flushed registers on Core %d\n", dev->core_id);
+
+ return 0;
+}
+
+static long DecRefreshRegs(hantrodec_t *dev, struct core_desc *Core)
+{
+ long ret, i;
+ //u32 id = Core->id;
+
+ if (IS_G1(dev->hw_id)) {
+ /* user has to know exactly what they are asking for */
+ //if(Core->size != (HANTRO_DEC_ORG_REGS * 4))
+ // return -EFAULT;
+
+ /* read all registers from hardware */
+ /* both original and extended regs need to be read */
+ for (i = 0; i <= HANTRO_DEC_ORG_LAST_REG; i++)
+ dev->dec_regs[i] = ioread32(dev->hwregs + i*4);
+#ifdef USE_64BIT_ENV
+ for (i = HANTRO_DEC_EXT_FIRST_REG; i <= HANTRO_DEC_EXT_LAST_REG; i++)
+ dev->dec_regs[i] = ioread32(dev->hwregs + i*4);
+#endif
+
+ if (dev->timeout) {
+ /* Enable TIMEOUT bits in Reg[1] */
+ dev->dec_regs[1] = 0x40100;
+ /* Reset HW */
+ ResetAsic(dev);
+ dev->timeout = 0;
+ }
+
+ /* put registers to user space*/
+ /* put original registers to user space*/
+ ret = copy_to_user(Core->regs, dev->dec_regs, HANTRO_DEC_ORG_REGS*4);
+#ifdef USE_64BIT_ENV
+ /*put extended registers to user space*/
+ ret = copy_to_user(Core->regs + HANTRO_DEC_EXT_FIRST_REG,
+ dev->dec_regs + HANTRO_DEC_EXT_FIRST_REG, HANTRO_DEC_EXT_REGS * 4);
+#endif
+ if (ret) {
+ pr_err("copy_to_user failed, returned %li\n", ret);
+ return -EFAULT;
+ }
+ } else {
+ /* user has to know exactly what they are asking for */
+ if (Core->size != (HANTRO_G2_DEC_REGS * 4))
+ return -EFAULT;
+
+ /* read all registers from hardware */
+ for (i = 0; i <= HANTRO_G2_DEC_LAST_REG; i++)
+ dev->dec_regs[i] = ioread32(dev->hwregs + i*4);
+
+ if (dev->timeout) {
+ /* Enable TIMEOUT bits in Reg[1] */
+ dev->dec_regs[1] = 0x40100;
+ /* Reset HW */
+ ResetAsic(dev);
+ dev->timeout = 0;
+ }
+
+ /* put registers to user space*/
+ ret = copy_to_user(Core->regs, dev->dec_regs, HANTRO_G2_DEC_REGS*4);
+ if (ret) {
+ pr_err("copy_to_user failed, returned %li\n", ret);
+ return -EFAULT;
+ }
+ }
+ return 0;
+}
+
+static int CheckDecIrq(hantrodec_t *dev)
+{
+ unsigned long flags;
+ int rdy = 0;
+
+ const u32 irq_mask = (1 << dev->core_id);
+
+ spin_lock_irqsave(&owner_lock, flags);
+
+ if (dec_irq & irq_mask) {
+ /* reset the wait condition(s) */
+ dec_irq &= ~irq_mask;
+ rdy = 1;
+ }
+
+ spin_unlock_irqrestore(&owner_lock, flags);
+
+ return rdy;
+}
+
+static long WaitDecReadyAndRefreshRegs(hantrodec_t *dev, struct core_desc *Core)
+{
+ //u32 id = Core->id;
+ long ret;
+
+ PDEBUG("wait_event_interruptible DEC[%d]\n", dev->core_id);
+
+ //ret = wait_event_interruptible_timeout(dec_wait_queue, CheckDecIrq(dev), msecs_to_jiffies(200));
+ ret = wait_event_timeout(dec_wait_queue, CheckDecIrq(dev), msecs_to_jiffies(200));
+ if (ret == -ERESTARTSYS) {
+ pr_err("DEC[%d] failed to wait_event_interruptible interrupted\n", dev->core_id);
+ return -ERESTARTSYS;
+ } else if (ret == 0) {
+ pr_err("DEC[%d] wait_event_interruptible timeout\n", dev->core_id);
+ dev->timeout = 1;
+ }
+
+ atomic_inc(&dev->irq_tx);
+
+ /* refresh registers */
+ return DecRefreshRegs(dev, Core);
+}
+
+static long PPFlushRegs(hantrodec_t *dev, struct core_desc *Core)
+{
+ long ret = 0;
+ //u32 id = Core->id;
+ u32 i;
+
+ /* copy original dec regs to kernal space*/
+ ret = copy_from_user(dev->dec_regs + HANTRO_PP_ORG_FIRST_REG,
+ Core->regs + HANTRO_PP_ORG_FIRST_REG, HANTRO_PP_ORG_REGS*4);
+#ifdef USE_64BIT_ENV
+ /* copy extended dec regs to kernal space*/
+ ret = copy_from_user(dev->dec_regs + HANTRO_PP_EXT_FIRST_REG,
+ Core->regs + HANTRO_PP_EXT_FIRST_REG, HANTRO_PP_EXT_REGS*4);
+#endif
+ if (ret) {
+ pr_err("copy_from_user failed, returned %li\n", ret);
+ return -EFAULT;
+ }
+
+ /* write all regs but the status reg[1] to hardware */
+ /* both original and extended regs need to be written */
+ for (i = HANTRO_PP_ORG_FIRST_REG + 1; i <= HANTRO_PP_ORG_LAST_REG; i++)
+ iowrite32(dev->dec_regs[i], dev->hwregs + i*4);
+#ifdef USE_64BIT_ENV
+ for (i = HANTRO_PP_EXT_FIRST_REG; i <= HANTRO_PP_EXT_LAST_REG; i++)
+ iowrite32(dev->dec_regs[i], dev->hwregs + i*4);
+#endif
+ /* write the stat reg, which may start the PP */
+ iowrite32(dev->dec_regs[HANTRO_PP_ORG_FIRST_REG],
+ dev->hwregs + HANTRO_PP_ORG_FIRST_REG * 4);
+
+ return 0;
+}
+
+static long PPRefreshRegs(hantrodec_t *dev, struct core_desc *Core)
+{
+ long i, ret;
+ //u32 id = Core->id;
+#ifdef USE_64BIT_ENV
+ /* user has to know exactly what they are asking for */
+ if (Core->size != (HANTRO_PP_TOTAL_REGS * 4))
+ return -EFAULT;
+#else
+ /* user has to know exactly what they are asking for */
+ if (Core->size != (HANTRO_PP_ORG_REGS * 4))
+ return -EFAULT;
+#endif
+
+ /* read all registers from hardware */
+ /* both original and extended regs need to be read */
+ for (i = HANTRO_PP_ORG_FIRST_REG; i <= HANTRO_PP_ORG_LAST_REG; i++)
+ dev->dec_regs[i] = ioread32(dev->hwregs + i*4);
+#ifdef USE_64BIT_ENV
+ for (i = HANTRO_PP_EXT_FIRST_REG; i <= HANTRO_PP_EXT_LAST_REG; i++)
+ dev->dec_regs[i] = ioread32(dev->hwregs + i*4);
+#endif
+ /* put registers to user space*/
+ /* put original registers to user space*/
+ ret = copy_to_user(Core->regs + HANTRO_PP_ORG_FIRST_REG,
+ dev->dec_regs + HANTRO_PP_ORG_FIRST_REG, HANTRO_PP_ORG_REGS*4);
+#ifdef USE_64BIT_ENV
+ /* put extended registers to user space*/
+ ret = copy_to_user(Core->regs + HANTRO_PP_EXT_FIRST_REG,
+ dev->dec_regs + HANTRO_PP_EXT_FIRST_REG, HANTRO_PP_EXT_REGS * 4);
+#endif
+ if (ret) {
+ pr_err("copy_to_user failed, returned %li\n", ret);
+ return -EFAULT;
+ }
+
+ return 0;
+}
+
+static int CheckPPIrq(hantrodec_t *dev)
+{
+ unsigned long flags;
+ int rdy = 0;
+
+ const u32 irq_mask = (1 << dev->core_id);
+
+ spin_lock_irqsave(&owner_lock, flags);
+
+ if (pp_irq & irq_mask) {
+ /* reset the wait condition(s) */
+ pp_irq &= ~irq_mask;
+ rdy = 1;
+ }
+
+ spin_unlock_irqrestore(&owner_lock, flags);
+
+ return rdy;
+}
+
+static long WaitPPReadyAndRefreshRegs(hantrodec_t *dev, struct core_desc *Core)
+{
+ //u32 id = Core->id;
+
+ PDEBUG("wait_event_interruptible PP[%d]\n", dev->core_id);
+
+ if (wait_event_interruptible(pp_wait_queue, CheckPPIrq(dev))) {
+ pr_err("PP[%d] failed to wait_event_interruptible interrupted\n", dev->core_id);
+ return -ERESTARTSYS;
+ }
+
+ atomic_inc(&dev->irq_tx);
+
+ /* refresh registers */
+ return PPRefreshRegs(dev, Core);
+}
+
+static int CheckCoreIrq(const struct file *filp, int *id)
+{
+ unsigned long flags;
+ int rdy = 0, n = 0;
+ hantrodec_t *dev;
+
+ do {
+ u32 irq_mask;
+
+ dev = &hantrodec_data[n];
+ irq_mask = (1 << dev->core_id);
+
+ spin_lock_irqsave(&owner_lock, flags);
+
+ if (dec_irq & irq_mask) {
+ if (dev->dec_owner == filp) {
+ /* we have an IRQ for our client */
+
+ /* reset the wait condition(s) */
+ dec_irq &= ~irq_mask;
+
+ /* signal ready Core no. for our client */
+ *id = dev->core_id;
+
+ rdy = 1;
+
+ spin_unlock_irqrestore(&owner_lock, flags);
+ break;
+ } else if (dev->dec_owner == NULL) {
+ /* zombie IRQ */
+ pr_info("IRQ on Core[%d], but no owner!!!\n", n);
+
+ /* reset the wait condition(s) */
+ dec_irq &= ~irq_mask;
+ }
+ }
+
+ spin_unlock_irqrestore(&owner_lock, flags);
+
+ n++; /* next Core */
+ } while (n < cores);
+
+ return rdy;
+}
+
+static long WaitCoreReady(const struct file *filp, int *id)
+{
+ PDEBUG("wait_event_interruptible CORE\n");
+
+ if (wait_event_interruptible(dec_wait_queue, CheckCoreIrq(filp, id))) {
+ pr_err("CORE failed to wait_event_interruptible interrupted\n");
+ return -ERESTARTSYS;
+ }
+
+ atomic_inc(&hantrodec_data[*id].irq_tx);
+
+ return 0;
+}
+
+/*-------------------------------------------------------------------------
+ *Function name : hantrodec_ioctl
+ *Description : communication method to/from the user space
+ *
+ *Return type : long
+ *-------------------------------------------------------------------------
+ */
+
+static long hantrodec_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
+{
+ int err = 0;
+ long tmp;
+
+ PDEBUG("ioctl cmd 0x%08x\n", cmd);
+ /*
+ * extract the type and number bitfields, and don't decode
+ * wrong cmds: return ENOTTY (inappropriate ioctl) before access_ok()
+ */
+ if (_IOC_TYPE(cmd) != HANTRODEC_IOC_MAGIC)
+ return -ENOTTY;
+ if (_IOC_NR(cmd) > HANTRODEC_IOC_MAXNR)
+ return -ENOTTY;
+
+ /*
+ * the direction is a bitmask, and VERIFY_WRITE catches R/W
+ * transfers. `Type' is user-oriented, while
+ * access_ok is kernel-oriented, so the concept of "read" and
+ * "write" is reversed
+ */
+ if (_IOC_DIR(cmd) & _IOC_READ)
+ err = !access_ok(VERIFY_WRITE, (void *) arg, _IOC_SIZE(cmd));
+ else if (_IOC_DIR(cmd) & _IOC_WRITE)
+ err = !access_ok(VERIFY_READ, (void *) arg, _IOC_SIZE(cmd));
+
+ if (err)
+ return -EFAULT;
+
+ switch (_IOC_NR(cmd)) {
+ case _IOC_NR(HANTRODEC_IOC_CLI): {
+ __u32 id;
+
+ __get_user(id, (__u32 *)arg);
+ if (id >= cores)
+ return -EFAULT;
+ disable_irq(hantrodec_data[id].irq);
+ break;
+ }
+ case _IOC_NR(HANTRODEC_IOC_STI): {
+ __u32 id;
+
+ __get_user(id, (__u32 *)arg);
+ if (id >= cores)
+ return -EFAULT;
+ enable_irq(hantrodec_data[id].irq);
+ break;
+ }
+ case _IOC_NR(HANTRODEC_IOCGHWOFFSET): {
+ __u32 id;
+
+ __get_user(id, (__u32 *)arg);
+ if (id >= cores)
+ return -EFAULT;
+
+ __put_user(multicorebase[id], (unsigned long *) arg);
+ break;
+ }
+ case _IOC_NR(HANTRODEC_IOCGHWIOSIZE): {
+ __u32 id;
+ __u32 io_size;
+
+ __get_user(id, (__u32 *)arg);
+ if (id >= cores)
+ return -EFAULT;
+ io_size = hantrodec_data[id].iosize;
+ __put_user(io_size, (u32 *) arg);
+
+ return 0;
+ }
+ case _IOC_NR(HANTRODEC_IOC_MC_OFFSETS): {
+ tmp = copy_to_user((u64 *) arg, multicorebase, sizeof(multicorebase));
+ if (err) {
+ pr_err("copy_to_user failed, returned %li\n", tmp);
+ return -EFAULT;
+ }
+ break;
+ }
+ case _IOC_NR(HANTRODEC_IOC_MC_CORES):
+ __put_user(cores, (unsigned int *) arg);
+ PDEBUG("hantrodec_data.cores=%d\n", cores);
+ break;
+ case _IOC_NR(HANTRODEC_IOCS_DEC_PUSH_REG): {
+ struct core_desc Core;
+
+ /* get registers from user space*/
+ tmp = copy_from_user(&Core, (void *)arg, sizeof(struct core_desc));
+ if (tmp) {
+ pr_err("copy_from_user failed, returned %li\n", tmp);
+ return -EFAULT;
+ }
+
+ if (Core.id >= cores)
+ return -EFAULT;
+
+ DecFlushRegs(&hantrodec_data[Core.id], &Core);
+ break;
+ }
+ case _IOC_NR(HANTRODEC_IOCS_PP_PUSH_REG): {
+ struct core_desc Core;
+
+ /* get registers from user space*/
+ tmp = copy_from_user(&Core, (void *)arg, sizeof(struct core_desc));
+ if (tmp) {
+ pr_err("copy_from_user failed, returned %li\n", tmp);
+ return -EFAULT;
+ }
+
+ if (Core.id >= cores)
+ return -EFAULT;
+
+ PPFlushRegs(&hantrodec_data[Core.id], &Core);
+ break;
+ }
+ case _IOC_NR(HANTRODEC_IOCS_DEC_PULL_REG): {
+ struct core_desc Core;
+
+ /* get registers from user space*/
+ tmp = copy_from_user(&Core, (void *)arg, sizeof(struct core_desc));
+ if (tmp) {
+ pr_err("copy_from_user failed, returned %li\n", tmp);
+ return -EFAULT;
+ }
+
+ if (Core.id >= cores)
+ return -EFAULT;
+
+ return DecRefreshRegs(&hantrodec_data[Core.id], &Core);
+ }
+ case _IOC_NR(HANTRODEC_IOCS_PP_PULL_REG): {
+ struct core_desc Core;
+
+ /* get registers from user space*/
+ tmp = copy_from_user(&Core, (void *)arg, sizeof(struct core_desc));
+ if (tmp) {
+ pr_err("copy_from_user failed, returned %li\n", tmp);
+ return -EFAULT;
+ }
+
+ if (Core.id >= cores)
+ return -EFAULT;
+
+ return PPRefreshRegs(&hantrodec_data[Core.id], &Core);
+ }
+ case _IOC_NR(HANTRODEC_IOCH_DEC_RESERVE): {
+ int id;
+
+ PDEBUG("Reserve DEC Core, format = %li\n", arg);
+ id = GetDecCoreID(arg);
+ if (id < 0) {
+ pr_err("invalid format: %ld\n", arg);
+ return -EFAULT;
+ }
+ return ReserveDecoder(&hantrodec_data[id], filp, arg);
+ }
+ case _IOC_NR(HANTRODEC_IOCT_DEC_RELEASE): {
+ if (arg >= cores || hantrodec_data[arg].dec_owner != filp) {
+ pr_err("bogus DEC release, Core = %li\n", arg);
+ return -EFAULT;
+ }
+
+ PDEBUG("Release DEC, Core = %li\n", arg);
+
+ ReleaseDecoder(&hantrodec_data[arg]);
+
+ break;
+ }
+ case _IOC_NR(HANTRODEC_IOCQ_PP_RESERVE):
+ return ReservePostProcessor(&hantrodec_data[0], filp);
+ case _IOC_NR(HANTRODEC_IOCT_PP_RELEASE): {
+ if (arg != 0 || hantrodec_data[arg].pp_owner != filp) {
+ pr_err("bogus PP release %li\n", arg);
+ return -EFAULT;
+ }
+
+ ReleasePostProcessor(&hantrodec_data[arg]);
+
+ break;
+ }
+ case _IOC_NR(HANTRODEC_IOCX_DEC_WAIT): {
+ struct core_desc Core;
+
+ /* get registers from user space */
+ tmp = copy_from_user(&Core, (void *)arg, sizeof(struct core_desc));
+ if (tmp) {
+ pr_err("copy_from_user failed, returned %li\n", tmp);
+ return -EFAULT;
+ }
+
+ if (Core.id >= cores)
+ return -EFAULT;
+
+ return WaitDecReadyAndRefreshRegs(&hantrodec_data[Core.id], &Core);
+ }
+ case _IOC_NR(HANTRODEC_IOCX_PP_WAIT): {
+ struct core_desc Core;
+
+ /* get registers from user space */
+ tmp = copy_from_user(&Core, (void *)arg, sizeof(struct core_desc));
+ if (tmp) {
+ pr_err("copy_from_user failed, returned %li\n", tmp);
+ return -EFAULT;
+ }
+
+ if (Core.id >= cores)
+ return -EFAULT;
+
+ return WaitPPReadyAndRefreshRegs(&hantrodec_data[Core.id], &Core);
+ }
+ case _IOC_NR(HANTRODEC_IOCG_CORE_WAIT): {
+ int id;
+
+ tmp = WaitCoreReady(filp, &id);
+ __put_user(id, (int *) arg);
+ return tmp;
+ }
+ case _IOC_NR(HANTRODEC_IOX_ASIC_ID): {
+ u32 id;
+
+ __get_user(id, (u32 *)arg);
+ if (id >= cores)
+ return -EFAULT;
+ id = ioread32(hantrodec_data[id].hwregs);
+ __put_user(id, (u32 *) arg);
+ return 0;
+ }
+ case _IOC_NR(HANTRODEC_IOCG_CORE_ID): {
+ int id;
+ hantrodec_instance *ctx = (hantrodec_instance *)filp->private_data;
+
+ PDEBUG("Get DEC Core_id, format = %li\n", arg);
+ id = GetDecCoreID(arg);
+ if ((ctx->core_id == 3) && (id >= 0)) {
+ if (id == 0) {
+ ctx->core_id = 1; //g1
+ /*power off g2*/
+ pm_runtime_put_sync(hantrodec_data[1].dev);
+ hantro_clk_disable(&hantrodec_data[1].clk);
+ } else if (id == 1) {
+ ctx->core_id = 2; //g2
+ /*power off g1*/
+ pm_runtime_put_sync(hantrodec_data[0].dev);
+ hantro_clk_disable(&hantrodec_data[0].clk);
+ }
+ }
+ return id;
+ }
+ case _IOC_NR(HANTRODEC_DEBUG_STATUS): {
+ PDEBUG("hantrodec: dec_irq = 0x%08x\n", dec_irq);
+ PDEBUG("hantrodec: pp_irq = 0x%08x\n", pp_irq);
+
+ //PDEBUG("hantrodec: IRQs received/sent2user = %d / %d\n",
+ //atomic_read(&irq_rx), atomic_read(&irq_tx));
+
+ for (tmp = 0; tmp < cores; tmp++) {
+ PDEBUG("hantrodec: Core %ld IRQs received/sent2user = %d / %d\n", tmp,
+ atomic_read(&hantrodec_data[tmp].irq_rx), atomic_read(&hantrodec_data[tmp].irq_tx));
+
+ PDEBUG("hantrodec: dec_core[%li] %s\n",
+ tmp, hantrodec_data[tmp].dec_owner == NULL ? "FREE" : "RESERVED");
+ PDEBUG("hantrodec: pp_core[%li] %s\n",
+ tmp, hantrodec_data[tmp].pp_owner == NULL ? "FREE" : "RESERVED");
+ }
+ }
+ default:
+ return -ENOTTY;
+ }
+
+ return 0;
+}
+
+#ifdef CONFIG_COMPAT
+struct core_desc_32 {
+ __u32 id; /* id of the Core */
+ compat_caddr_t regs; /* pointer to user registers */
+ __u32 size; /* size of register space */
+};
+
+static int get_hantro_core_desc32(struct core_desc *kp, struct core_desc_32 __user *up)
+{
+ u32 tmp;
+
+ if (!access_ok(VERIFY_READ, up, sizeof(struct core_desc_32)) ||
+ get_user(kp->id, &up->id) ||
+ get_user(kp->size, &up->size) ||
+ get_user(tmp, &up->regs)) {
+ return -EFAULT;
+ }
+ kp->regs = (__force u32 *)compat_ptr(tmp);
+ return 0;
+}
+
+static int put_hantro_core_desc32(struct core_desc *kp, struct core_desc_32 __user *up)
+{
+ u32 tmp = (u32)((unsigned long)kp->regs);
+
+ if (!access_ok(VERIFY_WRITE, up, sizeof(struct core_desc_32)) ||
+ put_user(kp->id, &up->id) ||
+ put_user(kp->size, &up->size) ||
+ put_user(tmp, &up->regs)) {
+ return -EFAULT;
+ }
+ return 0;
+}
+static long hantrodec_ioctl32(struct file *filp, unsigned int cmd, unsigned long arg)
+{
+#define HANTRO_IOCTL32(err, filp, cmd, arg) { \
+ mm_segment_t old_fs = get_fs(); \
+ set_fs(KERNEL_DS); \
+ err = hantrodec_ioctl(filp, cmd, arg); \
+ if (err) \
+ return err; \
+ set_fs(old_fs); \
+ }
+
+ union {
+ struct core_desc kcore;
+ unsigned long kux;
+ unsigned int kui;
+ } karg;
+ void __user *up = compat_ptr(arg);
+ long err = 0;
+
+ switch (_IOC_NR(cmd)) {
+ case _IOC_NR(HANTRODEC_IOCGHWOFFSET):
+ case _IOC_NR(HANTRODEC_IOC_MC_OFFSETS):
+ err = get_user(karg.kux, (s32 __user *)up);
+ if (err)
+ return err;
+ HANTRO_IOCTL32(err, filp, cmd, (unsigned long)&karg);
+ err = put_user(((s32)karg.kux), (s32 __user *)up);
+ break;
+ case _IOC_NR(HANTRODEC_IOCGHWIOSIZE):
+ case _IOC_NR(HANTRODEC_IOC_MC_CORES):
+ case _IOC_NR(HANTRODEC_IOCG_CORE_WAIT):
+ case _IOC_NR(HANTRODEC_IOX_ASIC_ID):
+ err = get_user(karg.kui, (s32 __user *)up);
+ if (err)
+ return err;
+ HANTRO_IOCTL32(err, filp, cmd, (unsigned long)&karg);
+ err = put_user(((s32)karg.kui), (s32 __user *)up);
+ break;
+ case _IOC_NR(HANTRODEC_IOCS_DEC_PUSH_REG):
+ case _IOC_NR(HANTRODEC_IOCS_PP_PUSH_REG):
+ case _IOC_NR(HANTRODEC_IOCX_DEC_WAIT):
+ case _IOC_NR(HANTRODEC_IOCX_PP_WAIT):
+ case _IOC_NR(HANTRODEC_IOCS_DEC_PULL_REG):
+ case _IOC_NR(HANTRODEC_IOCS_PP_PULL_REG):
+ err = get_hantro_core_desc32(&karg.kcore, up);
+ if (err)
+ return err;
+ HANTRO_IOCTL32(err, filp, cmd, (unsigned long)&karg);
+ err = put_hantro_core_desc32(&karg.kcore, up);
+ break;
+ default:
+ err = hantrodec_ioctl(filp, cmd, (unsigned long)up);
+ break;
+ }
+
+ return err;
+}
+
+#endif //ifdef CONFIG_COMPAT
+
+/*--------------------------------------------------------------------------
+ *Function name : hantrodec_open
+ *Description : open method
+ *
+ *Return type : int
+ *---------------------------------------------------------------------------
+ */
+static int hantrodec_open(struct inode *inode, struct file *filp)
+{
+ int i;
+ int idx;
+
+ idx = hantro_new_instance();
+ if (idx < 0)
+ return -ENOMEM;
+
+ PDEBUG("dev opened: id: %d\n", idx);
+ hantrodec_ctx[idx].core_id = 3; //unknow
+ hantrodec_ctx[idx].inst_id = idx;
+ filp->private_data = (void *)(&hantrodec_ctx[idx]);
+
+ /*not yet know which core id, so power on both g1 and g2 firstly*/
+ for (i = 0; i < 2; i++) {
+ hantro_clk_enable(&hantrodec_data[i].clk);
+ hantro_power_on_disirq(&hantrodec_data[i]);
+ }
+ return 0;
+}
+
+/*---------------------------------------------------------------------------
+ *Function name : hantrodec_release
+ *Description : Release driver
+ *
+ *Return type : int
+ *----------------------------------------------------------------------------
+ */
+static int hantrodec_release(struct inode *inode, struct file *filp)
+{
+ int n;
+ //hantrodec_t *dev = &hantrodec_data;
+ hantrodec_instance *ctx = (hantrodec_instance *)filp->private_data;
+
+ PDEBUG("closing ...\n");
+ for (n = 0; n < cores; n++) {
+ if (hantrodec_data[n].dec_owner == filp) {
+ PDEBUG("releasing dec Core %i lock\n", n);
+ ReleaseDecoder(&hantrodec_data[n]);
+ }
+ }
+
+ for (n = 0; n < 1; n++) {
+ if (hantrodec_data[n].pp_owner == filp) {
+ PDEBUG("releasing pp Core %i lock\n", n);
+ ReleasePostProcessor(&hantrodec_data[n]);
+ }
+ }
+
+ if (ctx->core_id & 0x1) {
+ pm_runtime_put_sync(hantrodec_data[0].dev);
+ hantro_clk_disable(&hantrodec_data[0].clk);
+ }
+ if (ctx->core_id & 0x2) {
+ pm_runtime_put_sync(hantrodec_data[1].dev);
+ hantro_clk_disable(&hantrodec_data[1].clk);
+ }
+ hantro_free_instance(ctx->inst_id);
+
+ PDEBUG("closed: id: %d\n", n);
+ return 0;
+}
+
+/*---------------------------------------------------------------------------
+ *Function name : hantro_mmap
+ *Description : memory map interface for hantro file operation
+ *
+ *Return type : int
+ *---------------------------------------------------------------------------
+ */
+static int hantro_mmap(struct file *fp, struct vm_area_struct *vm)
+{
+ if (vm->vm_pgoff == (multicorebase[0] >> PAGE_SHIFT) || vm->vm_pgoff == (multicorebase[1] >> PAGE_SHIFT)) {
+ vm->vm_flags |= VM_IO;
+ vm->vm_page_prot = pgprot_noncached(vm->vm_page_prot);
+ PDEBUG("hantro mmap: size=0x%lX, page off=0x%lX\n", (vm->vm_end - vm->vm_start), vm->vm_pgoff);
+ return remap_pfn_range(vm, vm->vm_start, vm->vm_pgoff, vm->vm_end - vm->vm_start,
+ vm->vm_page_prot) ? -EAGAIN : 0;
+ } else {
+ pr_err("invalid map offset :0x%lX\n", vm->vm_pgoff);
+ return -EINVAL;
+ }
+}
+
+/* VFS methods */
+static const struct file_operations hantrodec_fops = {
+ .owner = THIS_MODULE,
+ .open = hantrodec_open,
+ .release = hantrodec_release,
+ .unlocked_ioctl = hantrodec_ioctl,
+ .fasync = NULL,
+ .mmap = hantro_mmap,
+#ifdef CONFIG_COMPAT
+ .compat_ioctl = hantrodec_ioctl32,
+#endif
+};
+
+/*---------------------------------------------------------------------------
+ *Function name : hantrodec_init
+ *Description : Initialize the driver
+ *
+ *Return type : int
+ *---------------------------------------------------------------------------
+ */
+static int hantrodec_init(struct platform_device *pdev, int id)
+{
+ int result;
+ int irq;
+ struct device *temp_class;
+
+ //dec_irq = 0;
+ //pp_irq = 0;
+ pr_debug("hantrodec: Init multi Core[0] at 0x%16lx\n"
+ " Core[1] at 0x%16lx\n", multicorebase[0], multicorebase[1]);
+
+ //hantrodec_data.cores = 0;
+ //hantrodec_data.iosize[0] = DEC_IO_SIZE_0;
+ //hantrodec_data.iosize[1] = DEC_IO_SIZE_1;
+
+ //hantrodec_data.async_queue_dec = NULL;
+ //hantrodec_data.async_queue_pp = NULL;
+
+ hantrodec_data[id].iosize = (id == 0) ? DEC_IO_SIZE_0 : DEC_IO_SIZE_1;
+
+ if (!hantrodec_major) {
+ dec_irq = 0;
+ pp_irq = 0;
+
+ result = register_chrdev(hantrodec_major, "hantrodec", &hantrodec_fops);
+ if (result < 0) {
+ pr_err("hantrodec: unable to get major %d\n", hantrodec_major);
+ goto err;
+ } else if (result != 0) { /* this is for dynamic major */
+ hantrodec_major = result;
+ }
+
+ hantro_class = class_create(THIS_MODULE, "mxc_hantro_845");
+ if (IS_ERR(hantro_class)) {
+ result = -1;
+ goto err;
+ }
+ temp_class = device_create(hantro_class, NULL, MKDEV(hantrodec_major, 0), NULL, DEVICE_NAME);
+ if (IS_ERR(temp_class)) {
+ result = -1;
+ goto err_out_class;
+ }
+ }
+
+ result = ReserveIO(id);
+ if (result < 0)
+ goto err;
+
+ hantrodec_data[id].dec_owner = 0;
+ hantrodec_data[id].pp_owner = 0;
+
+ sema_init(&hantrodec_data[id].dec_core_sem, 1);
+ sema_init(&hantrodec_data[id].pp_core_sem, 1);
+
+ /* read configuration fo all cores */
+ ReadCoreConfig(&hantrodec_data[id]);
+
+ /* reset hardware */
+ ResetAsic(&hantrodec_data[id]);
+
+ /* register irq for each core*/
+ irq = platform_get_irq_byname(pdev, "irq_hantro");
+ if (irq > 0) {
+ hantrodec_data[id].irq = irq;
+ result = request_irq(irq, hantrodec_isr, IRQF_SHARED,
+ "hantrodec", (void *) &hantrodec_data[id]);
+
+ if (result != 0) {
+ if (result == -EINVAL)
+ pr_err("hantrodec: Bad irq number or handler\n");
+ else if (result == -EBUSY) {
+ pr_err("hantrodec: IRQ <%d> busy, change your config\n",
+ hantrodec_data[id].irq);
+ }
+ ReleaseIO(id);
+ goto err;
+ }
+ } else {
+ pr_err("hantrodec: IRQ0 not in use!\n");
+ goto err;
+ }
+
+ hantrodec_data[id].irq_rx.counter = 0;
+ hantrodec_data[id].irq_tx.counter = 0;
+ irq_set_status_flags(irq, IRQ_DISABLE_UNLAZY);
+ pr_info("hantrodec %d : module inserted. Major = %d\n", id, hantrodec_major);
+
+ return 0;
+
+err_out_class:
+ device_destroy(hantro_class, MKDEV(hantrodec_major, 0));
+ class_destroy(hantro_class);
+err:
+ pr_err("hantrodec: module not inserted\n");
+ unregister_chrdev(hantrodec_major, "hantrodec");
+ return result;
+}
+
+/*---------------------------------------------------------------------------
+ *Function name : hantrodec_cleanup
+ *Description : clean up
+ *
+ *Return type : int
+ *---------------------------------------------------------------------------
+ */
+static void hantrodec_cleanup(int id)
+{
+ hantrodec_t *dev = &hantrodec_data[id];
+ //int n = 0;
+ /* reset hardware */
+ ResetAsic(dev);
+
+ /* free the IRQ */
+ //for (n = 0; n < dev->cores; n++) {
+ if (dev->irq != -1)
+ free_irq(dev->irq, (void *) dev);
+ //}
+
+ ReleaseIO(id);
+
+ //unregister_chrdev(hantrodec_major, "hantrodec");
+
+ PDEBUG("hantrodec: module removed\n");
+
+}
+
+/*---------------------------------------------------------------------------
+ *Function name : CheckHwId
+ *Return type : int
+ *---------------------------------------------------------------------------
+ */
+static int CheckHwId(hantrodec_t *dev)
+{
+ long int hwid;
+ //int i;
+ size_t num_hw = sizeof(DecHwId) / sizeof(*DecHwId);
+
+ int found = 0;
+
+ //for (i = 0; i < cores; i++) {
+ if (dev->hwregs != NULL) {
+ hwid = readl(dev->hwregs);
+ pr_debug("hantrodec: Core %d HW ID=0x%16lx\n", dev->core_id, hwid);
+ hwid = (hwid >> 16) & 0xFFFF; /* product version only */
+
+ while (num_hw--) {
+ if (hwid == DecHwId[num_hw]) {
+ pr_debug("hantrodec: Supported HW found at 0x%16lx\n",
+ multicorebase[dev->core_id]);
+ found++;
+ dev->hw_id = hwid;
+ break;
+ }
+ }
+ if (!found) {
+ pr_err("hantrodec: Unknown HW found at 0x%16lx\n", multicorebase[dev->core_id]);
+ return 0;
+ }
+ found = 0;
+ num_hw = sizeof(DecHwId) / sizeof(*DecHwId);
+ }
+ //}
+
+ return 1;
+}
+
+/*---------------------------------------------------------------------------
+ *Function name : ReserveIO
+ *Description : IO reserve
+ *
+ *Return type : int
+ *---------------------------------------------------------------------------
+ */
+static int ReserveIO(int i)
+{
+ //int i;
+
+ //for (i = 0; i < HXDEC_MAX_CORES; i++) {
+ if (multicorebase[i] != -1) {
+ if (!request_mem_region(multicorebase[i], hantrodec_data[i].iosize, "hantrodec0")) {
+ pr_err("hantrodec: failed to reserve HW regs, %d, base: 0x%lX, %d\n", i, multicorebase[i], hantrodec_data[i].iosize);
+ return -EBUSY;
+ }
+
+ hantrodec_data[i].hwregs = (volatile u8 *) ioremap_nocache(multicorebase[i],
+ hantrodec_data[i].iosize);
+
+ if (hantrodec_data[i].hwregs == NULL) {
+ pr_err("hantrodec: failed to ioremap HW regs\n");
+ ReleaseIO(i);
+ return -EBUSY;
+ }
+ //hantrodec_data.cores++;
+ }
+ //}
+
+ /* check for correct HW */
+ if (!CheckHwId(&hantrodec_data[i])) {
+ ReleaseIO(i);
+ return -EBUSY;
+ }
+
+ return 0;
+}
+
+/*---------------------------------------------------------------------------
+ *Function name : releaseIO
+ *Description : release
+ *
+ *Return type : void
+ *---------------------------------------------------------------------------
+ */
+static void ReleaseIO(int i)
+{
+ //int i;
+
+ //for (i = 0; i < hantrodec_data.cores; i++) {
+ if (hantrodec_data[i].hwregs)
+ iounmap((void *) hantrodec_data[i].hwregs);
+ release_mem_region(multicorebase[i], hantrodec_data[i].iosize);
+ //}
+}
+
+/*---------------------------------------------------------------------------
+ *Function name : hantrodec_isr
+ *Description : interrupt handler
+ *
+ *Return type : irqreturn_t
+ *---------------------------------------------------------------------------
+ */
+static irqreturn_t hantrodec_isr(int irq, void *dev_id)
+{
+ unsigned long flags;
+ unsigned int handled = 0;
+ //int i;
+ volatile u8 *hwregs;
+
+ hantrodec_t *dev = (hantrodec_t *) dev_id;
+ u32 irq_status_dec;
+
+ spin_lock_irqsave(&owner_lock, flags);
+
+ //for (i = 0; i < cores; i++) {
+ hwregs = dev->hwregs;
+
+ /* interrupt status register read */
+ irq_status_dec = ioread32(hwregs + HANTRODEC_IRQ_STAT_DEC_OFF);
+
+ if (irq_status_dec & HANTRODEC_DEC_IRQ) {
+ /* clear dec IRQ */
+ irq_status_dec &= (~HANTRODEC_DEC_IRQ);
+ iowrite32(irq_status_dec, hwregs + HANTRODEC_IRQ_STAT_DEC_OFF);
+
+ PDEBUG("decoder IRQ received! Core %d\n", dev->core_id);
+
+ atomic_inc(&hantrodec_data[dev->core_id].irq_rx);
+
+ dec_irq |= (1 << dev->core_id);
+
+ //wake_up_interruptible_all(&dec_wait_queue);
+ wake_up_all(&dec_wait_queue);
+ handled++;
+ }
+ //}
+
+ spin_unlock_irqrestore(&owner_lock, flags);
+
+ if (!handled)
+ pr_info("IRQ received, but not hantrodec's!\n");
+
+ (void)hwregs;
+ return IRQ_RETVAL(handled);
+}
+
+/*---------------------------------------------------------------------------
+ *Function name : ResetAsic
+ *Description : reset asic
+ *
+ *Return type :
+ *---------------------------------------------------------------------------
+ */
+static void ResetAsic(hantrodec_t *dev)
+{
+ int i;
+ u32 status;
+
+ //for (j = 0; j < dev->cores; j++) {
+ status = ioread32(dev->hwregs + HANTRODEC_IRQ_STAT_DEC_OFF);
+
+ if (status & HANTRODEC_DEC_E) {
+ /* abort with IRQ disabled */
+ status = HANTRODEC_DEC_ABORT | HANTRODEC_DEC_IRQ_DISABLE;
+ iowrite32(status, dev->hwregs + HANTRODEC_IRQ_STAT_DEC_OFF);
+ }
+
+ if (IS_G1(dev->hw_id))
+ /* reset PP */
+ iowrite32(0, dev->hwregs + HANTRO_IRQ_STAT_PP_OFF);
+
+ for (i = 4; i < dev->iosize; i += 4)
+ iowrite32(0, dev->hwregs + i);
+ //}
+}
+
+/*---------------------------------------------------------------------------
+ *Function name : dump_regs
+ *Description : Dump registers
+ *
+ *Return type :
+ *---------------------------------------------------------------------------
+ */
+#ifdef HANTRODEC_DEBUG
+static void dump_regs(hantrodec_t *dev)
+{
+ int i, c;
+
+ PDEBUG("Reg Dump Start\n");
+ for (c = 0; c < dev->cores; c++) {
+ for (i = 0; i < dev->iosize[c]; i += 4*4) {
+ PDEBUG("\toffset %04X: %08X %08X %08X %08X\n", i,
+ ioread32(dev->hwregs[c] + i),
+ ioread32(dev->hwregs[c] + i + 4),
+ ioread32(dev->hwregs[c] + i + 8),
+ ioread32(dev->hwregs[c] + i + 12));
+ }
+ }
+ PDEBUG("Reg Dump End\n");
+}
+#endif
+
+static int hantro_dev_probe(struct platform_device *pdev)
+{
+ int err = 0;
+ struct resource *res;
+ unsigned long reg_base;
+ int id;
+
+ id = hantro_device_id(&pdev->dev);
+ if (id < 0)
+ return -ENODEV;
+
+ hantrodec_data[id].dev = &pdev->dev;
+ hantrodec_data[id].core_id = id;
+ platform_set_drvdata(pdev, &hantrodec_data[id]);
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "regs_hantro");
+ if (!res) {
+ pr_err("hantro: unable to get vpu base addr\n");
+ return -ENODEV;
+ }
+ reg_base = res->start;
+ if ((ulong)reg_base != multicorebase[id]) {
+ pr_err("hantrodec %d: regbase(0x%lX) not equal to expected value(0x%lX)\n", id, reg_base, multicorebase[id]);
+ return -ENODEV;
+ }
+
+ hantrodec_data[id].clk.dec = clk_get(&pdev->dev, "clk_hantro");
+ hantrodec_data[id].clk.bus = clk_get(&pdev->dev, "clk_hantro_bus");
+ if (IS_ERR(hantrodec_data[id].clk.dec) || IS_ERR(hantrodec_data[id].clk.bus)) {
+ pr_err("hantro: get clock failed\n");
+ return -ENODEV;
+ }
+ pr_debug("hantro: dec, bus clock: 0x%lX, 0x%lX\n", clk_get_rate(hantrodec_data[id].clk.dec),
+ clk_get_rate(hantrodec_data[id].clk.bus));
+
+ hantro_clk_enable(&hantrodec_data[id].clk);
+ pm_runtime_enable(&pdev->dev);
+ pm_runtime_get_sync(&pdev->dev);
+ hantro_ctrlblk_reset(&hantrodec_data[id]);
+
+ err = hantrodec_init(pdev, id);
+ if (err != 0) {
+ pr_err("hantro: hantrodec_init failed\n");
+ goto error;
+ }
+
+#ifdef CONFIG_DEVICE_THERMAL_HANTRO
+ HANTRO_REG_THERMAL_NOTIFIER(&hantro_thermal_hot_notifier);
+ thermal_event = 0;
+ hantro_dynamic_clock = 0;
+ hantrodec_data[id].thermal_cur = 0;
+#endif
+ hantrodec_data[id].timeout = 0;
+ mutex_init(&hantrodec_data[id].dev_mutex);
+ instance_mask = 0;
+
+ goto out;
+
+error:
+ pr_err("hantro probe failed\n");
+out:
+ pm_runtime_put_sync(&pdev->dev);
+ hantro_clk_disable(&hantrodec_data[id].clk);
+ return err;
+}
+
+static int hantro_dev_remove(struct platform_device *pdev)
+{
+ hantrodec_t *dev = platform_get_drvdata(pdev);
+
+ hantro_clk_enable(&dev->clk);
+ pm_runtime_get_sync(&pdev->dev);
+
+ hantrodec_cleanup(dev->core_id);
+#if 1 // FIXME: need to identify core id
+ if (hantrodec_major > 0) {
+ device_destroy(hantro_class, MKDEV(hantrodec_major, 0));
+ class_destroy(hantro_class);
+ unregister_chrdev(hantrodec_major, "hantrodec");
+ hantrodec_major = 0;
+ }
+#endif
+ pm_runtime_put_sync(&pdev->dev);
+ pm_runtime_disable(&pdev->dev);
+ hantro_clk_disable(&dev->clk);
+
+#ifdef CONFIG_DEVICE_THERMAL_HANTRO
+ HANTRO_UNREG_THERMAL_NOTIFIER(&hantro_thermal_hot_notifier);
+#endif
+
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int hantro_suspend(struct device *dev)
+{
+ pm_runtime_put_sync_suspend(dev); //power off
+ return 0;
+}
+static int hantro_resume(struct device *dev)
+{
+ hantrodec_t *hantrodev = dev_get_drvdata(dev);
+
+ hantro_power_on_disirq(hantrodev);
+ hantro_ctrlblk_reset(hantrodev);
+ return 0;
+}
+static int hantro_runtime_suspend(struct device *dev)
+{
+ release_bus_freq(BUS_FREQ_HIGH);
+ return 0;
+}
+
+static int hantro_runtime_resume(struct device *dev)
+{
+ hantrodec_t *hantrodev = dev_get_drvdata(dev);
+
+ request_bus_freq(BUS_FREQ_HIGH);
+ hantro_ctrlblk_reset(hantrodev);
+ return 0;
+}
+
+static const struct dev_pm_ops hantro_pm_ops = {
+ SET_RUNTIME_PM_OPS(hantro_runtime_suspend, hantro_runtime_resume, NULL)
+ SET_SYSTEM_SLEEP_PM_OPS(hantro_suspend, hantro_resume)
+};
+#endif //CONFIG_PM
+
+static const struct of_device_id hantro_of_match[] = {
+ { .compatible = "nxp,imx8mm-hantro", },
+ {/* sentinel */}
+};
+MODULE_DEVICE_TABLE(of, hantro_of_match);
+
+
+static struct platform_driver mxchantro_driver = {
+ .driver = {
+ .name = "mxc_hantro_845",
+ .of_match_table = hantro_of_match,
+#ifdef CONFIG_PM
+ .pm = &hantro_pm_ops,
+#endif
+ },
+ .probe = hantro_dev_probe,
+ .remove = hantro_dev_remove,
+};
+
+static int __init hantro_init(void)
+{
+ int ret = platform_driver_register(&mxchantro_driver);
+
+ return ret;
+}
+
+static void __exit hantro_exit(void)
+{
+ //clk_put(hantro_clk);
+ platform_driver_unregister(&mxchantro_driver);
+}
+
+module_init(hantro_init);
+module_exit(hantro_exit);
+
+/* module description */
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Google Finland Oy");
+MODULE_DESCRIPTION("Driver module for Hantro Decoder/Post-Processor");
+
diff --git a/drivers/mxc/hantro_845_h1/Kconfig b/drivers/mxc/hantro_845_h1/Kconfig
new file mode 100755
index 000000000000..65b21d92770c
--- /dev/null
+++ b/drivers/mxc/hantro_845_h1/Kconfig
@@ -0,0 +1,14 @@
+#
+# Codec configuration
+#
+
+menu "MXC HANTRO(Video Processing Unit) encoder support"
+ depends on ARCH_FSL_IMX8MQ
+
+config MXC_HANTRO_845_H1
+ tristate "Support for MXC HANTRO(Video Processing Unit) encoder"
+ default y
+ ---help---
+ VPU codec device.
+
+endmenu
diff --git a/drivers/mxc/hantro_845_h1/Makefile b/drivers/mxc/hantro_845_h1/Makefile
new file mode 100755
index 000000000000..acb87202c5b0
--- /dev/null
+++ b/drivers/mxc/hantro_845_h1/Makefile
@@ -0,0 +1,8 @@
+#
+# Makefile for the VPU drivers.
+#
+
+#ccflags-y += -I$(PWD)
+
+obj-$(CONFIG_MXC_HANTRO_845_H1) += hx280enc.o
+
diff --git a/drivers/mxc/hantro_845_h1/hx280enc.c b/drivers/mxc/hantro_845_h1/hx280enc.c
new file mode 100755
index 000000000000..bdf23fd59d20
--- /dev/null
+++ b/drivers/mxc/hantro_845_h1/hx280enc.c
@@ -0,0 +1,883 @@
+/*
+ * Encoder device driver (kernel module)
+ *
+ * Copyright (c) 2013-2018, VeriSilicon Inc.
+ * Copyright (C) 2012 Google Finland Oy.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+--------------------------------------------------------------------------------
+--
+-- Abstract : 6280/7280/8270/8290/H1 Encoder device driver (kernel module)
+--
+------------------------------------------------------------------------------*/
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+/* needed for __init,__exit directives */
+#include <linux/init.h>
+/* needed for remap_page_range
+ SetPageReserved
+ ClearPageReserved
+*/
+#include <linux/mm.h>
+/* obviously, for kmalloc */
+#include <linux/slab.h>
+/* for struct file_operations, register_chrdev() */
+#include <linux/fs.h>
+/* standard error codes */
+#include <linux/errno.h>
+
+#include <linux/moduleparam.h>
+/* request_irq(), free_irq() */
+#include <linux/interrupt.h>
+#include <linux/sched.h>
+
+/* needed for virt_to_phys() */
+#include <linux/io.h>
+#include <linux/pci.h>
+#include <linux/uaccess.h>
+#include <linux/ioport.h>
+
+#include <asm/irq.h>
+#include <linux/of_irq.h>
+#include <linux/version.h>
+
+/* our own stuff */
+#include <linux/hx280enc.h>
+
+#ifndef VSI
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/clk.h>
+//static int hantro_h1_major = -1; /* dynamic allocation */
+static struct class *hantro_h1_class;
+#define DEVICE_NAME "mxc_hantro_h1"
+static struct device *hantro_h1_dev;
+static struct clk *hantro_clk_h1;
+static struct clk *hantro_clk_h1_bus;
+#define IRQF_DISABLED 0x0
+#endif
+
+#include <linux/delay.h>
+
+/* module description */
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Google Finland Oy");
+MODULE_DESCRIPTION("Hantro 6280/7280/8270/8290/H1 Encoder driver");
+
+/* this is ARM Integrator specific stuff */
+#ifndef VSI
+#define INTEGRATOR_LOGIC_MODULE0_BASE 0x38320000
+#else
+#define INTEGRATOR_LOGIC_MODULE0_BASE 0xC0000000
+#endif
+#define BLK_CTL_BASE 0x38330000 //0x38320000
+/*
+#define INTEGRATOR_LOGIC_MODULE1_BASE 0xD0000000
+#define INTEGRATOR_LOGIC_MODULE2_BASE 0xE0000000
+#define INTEGRATOR_LOGIC_MODULE3_BASE 0xF0000000
+*/
+
+#define VP_PB_INT_LT 30
+/*
+#define INT_EXPINT1 10
+#define INT_EXPINT2 11
+#define INT_EXPINT3 12
+*/
+/* these could be module params in the future */
+
+#define ENC_IO_BASE INTEGRATOR_LOGIC_MODULE0_BASE
+#define ENC_IO_SIZE (500 * 4) /* bytes */
+
+#define ENC_HW_ID1 0x62800000
+#define ENC_HW_ID2 0x72800000
+#define ENC_HW_ID3 0x82700000
+#define ENC_HW_ID4 0x82900000
+#define ENC_HW_ID5 0x48310000
+
+#define HX280ENC_BUF_SIZE 0
+
+static unsigned long base_port = INTEGRATOR_LOGIC_MODULE0_BASE;
+static int irq = VP_PB_INT_LT;
+
+/* for critical data access */
+static DEFINE_SPINLOCK(owner_lock);
+/* for irq wait */
+static DECLARE_WAIT_QUEUE_HEAD(enc_wait_queue);
+/* for reserve hw */
+static DECLARE_WAIT_QUEUE_HEAD(enc_hw_queue);
+
+/* module_param(name, type, perm) */
+module_param(base_port, ulong, 0644);
+module_param(irq, int, 0644);
+
+/* and this is our MAJOR; use 0 for dynamic allocation (recommended)*/
+static int hx280enc_major;
+
+/* here's all the must remember stuff */
+typedef struct {
+ u32 hw_id; //hw id to indicate project
+ u32 is_valid; //indicate this core is hantro's core or not
+ u32 is_reserved; //indicate this core is occupied by user or not
+ int pid; //indicate which process is occupying the core
+ u32 irq_received; //indicate this core receives irq
+ u32 irq_status;
+ int irq;
+ unsigned long iobaseaddr;
+ unsigned int iosize;
+
+ volatile u8 *hwregs;
+ struct fasync_struct *async_queue;
+ struct device *dev;
+ struct mutex dev_mutex;
+} hx280enc_t;
+
+/* dynamic allocation? */
+static hx280enc_t hx280enc_data;
+
+static int ReserveIO(void);
+static void ReleaseIO(void);
+static void ResetAsic(hx280enc_t *dev);
+
+#ifdef HX280ENC_DEBUG
+static void dump_regs(unsigned long data);
+#endif
+
+/* IRQ handler */
+static irqreturn_t hx280enc_isr(int irq, void *dev_id);
+
+#ifndef VSI
+static int hantro_h1_clk_enable(struct device *dev)
+{
+ clk_prepare(hantro_clk_h1);
+ clk_enable(hantro_clk_h1);
+ clk_prepare(hantro_clk_h1_bus);
+ clk_enable(hantro_clk_h1_bus);
+ return 0;
+}
+
+static int hantro_h1_clk_disable(struct device *dev)
+{
+ if (hantro_clk_h1) {
+ clk_disable(hantro_clk_h1);
+ clk_unprepare(hantro_clk_h1);
+ }
+ if (hantro_clk_h1_bus) {
+ clk_disable(hantro_clk_h1_bus);
+ clk_unprepare(hantro_clk_h1_bus);
+ }
+ return 0;
+}
+
+static int hantro_h1_ctrlblk_reset(struct device *dev)
+{
+ volatile u8 *iobase;
+ u32 val;
+
+ //config H1
+ hantro_h1_clk_enable(dev);
+ iobase = (volatile u8 *)ioremap_nocache(BLK_CTL_BASE, 0x10000);
+
+ val = ioread32(iobase);
+ val &= (~0x4);
+ iowrite32(val, iobase); // assert soft reset
+ udelay(2);
+
+ val = ioread32(iobase);
+ val |= 0x4;
+ iowrite32(val, iobase); // release soft reset
+
+ val = ioread32(iobase+0x4);
+ val |= 0x4;
+ iowrite32(val, iobase + 0x4); // enable clock
+
+ iowrite32(0xFFFFFFFF, iobase + 0x14); // H1 fuse encoder enable
+ iounmap(iobase);
+ hantro_h1_clk_disable(dev);
+ return 0;
+}
+
+static int hantro_h1_power_on_disirq(hx280enc_t *hx280enc)
+{
+ //spin_lock_irq(&owner_lock);
+ mutex_lock(&hx280enc->dev_mutex);
+ disable_irq(hx280enc->irq);
+ pm_runtime_get_sync(hx280enc->dev);
+ enable_irq(hx280enc->irq);
+ mutex_unlock(&hx280enc->dev_mutex);
+ //spin_unlock_irq(&owner_lock);
+ return 0;
+}
+
+#endif
+
+/* the device's mmap method. The VFS has kindly prepared the process's
+ * vm_area_struct for us, so we examine this to see what was requested.
+ */
+
+static int hx280enc_mmap(struct file *filp, struct vm_area_struct *vm)
+{
+#ifdef VSI
+ int result = -EINVAL;
+
+ result = -EINVAL;
+ vma->vm_ops = &hx280enc_vm_ops;
+ return result;
+#else
+ if (vm->vm_pgoff == (hx280enc_data.iobaseaddr >> PAGE_SHIFT)) {
+ vm->vm_flags |= VM_IO;
+ vm->vm_page_prot = pgprot_noncached(vm->vm_page_prot);
+ PDEBUG("hx280enc mmap: size=0x%lX, page off=0x%lX\n", (vm->vm_end - vm->vm_start), vm->vm_pgoff);
+ return remap_pfn_range(vm, vm->vm_start, vm->vm_pgoff, vm->vm_end - vm->vm_start,
+ vm->vm_page_prot) ? -EAGAIN : 0;
+ } else {
+ pr_err("invalid map offset :0x%lX\n", vm->vm_pgoff);
+ return -EINVAL;
+ }
+#endif
+}
+
+static int CheckEncIrq(hx280enc_t *dev)
+{
+ unsigned long flags;
+ int rdy = 0;
+
+ spin_lock_irqsave(&owner_lock, flags);
+
+ if (dev->irq_received) {
+ /* reset the wait condition(s) */
+ PDEBUG("check irq ready\n");
+ dev->irq_received = 0;
+ rdy = 1;
+ }
+
+ spin_unlock_irqrestore(&owner_lock, flags);
+ //printk("rdy=%d\n",rdy);
+
+ return rdy;
+}
+
+unsigned int WaitEncReady(hx280enc_t *dev)
+{
+ PDEBUG("WaitEncReady\n");
+
+ if (wait_event_interruptible(enc_wait_queue, CheckEncIrq(dev))) {
+ PDEBUG("ENC wait_event_interruptible interrupted\n");
+ return -ERESTARTSYS;
+ }
+
+ return 0;
+}
+
+int CheckCoreOccupation(hx280enc_t *dev)
+{
+ int ret = 0;
+ unsigned long flags;
+
+ spin_lock_irqsave(&owner_lock, flags);
+ if (!dev->is_reserved) {
+ dev->is_reserved = 1;
+ dev->pid = current->pid;
+ ret = 1;
+ PDEBUG("CheckCoreOccupation pid=%d\n", dev->pid);
+ }
+ spin_unlock_irqrestore(&owner_lock, flags);
+
+ return ret;
+}
+
+int GetWorkableCore(hx280enc_t *dev)
+{
+ int ret = 0;
+
+ PDEBUG("GetWorkableCore\n");
+
+ if (dev->is_valid && CheckCoreOccupation(dev))
+ ret = 1;
+
+ return ret;
+}
+
+long ReserveEncoder(hx280enc_t *dev)
+{
+ /* lock a core that has specified core id*/
+ if (wait_event_interruptible(enc_hw_queue, GetWorkableCore(dev) != 0))
+ return -ERESTARTSYS;
+
+ return 0;
+}
+
+void ReleaseEncoder(hx280enc_t *dev)
+{
+ unsigned long flags;
+
+ PDEBUG("ReleaseEncoder\n");
+
+ spin_lock_irqsave(&owner_lock, flags);
+ PDEBUG("relase reseve by pid=%d with current->pid=%d\n", dev->pid, current->pid);
+ if (dev->is_reserved && dev->pid == current->pid) {
+ dev->pid = -1;
+ dev->is_reserved = 0;
+ }
+
+ dev->irq_received = 0;
+ dev->irq_status = 0;
+ spin_unlock_irqrestore(&owner_lock, flags);
+
+ wake_up_interruptible_all(&enc_hw_queue);
+
+}
+
+
+static long hx280enc_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
+{
+ int err = 0;
+
+ PDEBUG("ioctl cmd 0x%X\n", cmd);
+ /*
+ * extract the type and number bitfields, and don't encode
+ * wrong cmds: return ENOTTY (inappropriate ioctl) before access_ok()
+ */
+ if (_IOC_TYPE(cmd) != HX280ENC_IOC_MAGIC)
+ return -ENOTTY;
+ if (_IOC_NR(cmd) > HX280ENC_IOC_MAXNR)
+ return -ENOTTY;
+
+ /*
+ * the direction is a bitmask, and VERIFY_WRITE catches R/W
+ * transfers. `Type' is user-oriented, while
+ * access_ok is kernel-oriented, so the concept of "read" and
+ * "write" is reversed
+ */
+ if (_IOC_DIR(cmd) & _IOC_READ)
+ err = !access_ok(VERIFY_WRITE, (void *) arg, _IOC_SIZE(cmd));
+ else if (_IOC_DIR(cmd) & _IOC_WRITE)
+ err = !access_ok(VERIFY_READ, (void *) arg, _IOC_SIZE(cmd));
+ if (err)
+ return -EFAULT;
+
+ switch (_IOC_NR(cmd)) {
+ case _IOC_NR(HX280ENC_IOCGHWOFFSET):
+ __put_user(hx280enc_data.iobaseaddr, (unsigned long *) arg);
+ break;
+ case _IOC_NR(HX280ENC_IOCGHWIOSIZE):
+ __put_user(hx280enc_data.iosize, (unsigned int *) arg);
+ break;
+ case _IOC_NR(HX280ENC_IOCH_ENC_RESERVE): {
+ int ret;
+
+ PDEBUG("Reserve ENC Cores\n");
+ ret = ReserveEncoder(&hx280enc_data);
+ return ret;
+ }
+ case _IOC_NR(HX280ENC_IOCH_ENC_RELEASE):
+ PDEBUG("Release ENC Core\n");
+ ReleaseEncoder(&hx280enc_data);
+ break;
+ case _IOC_NR(HX280ENC_IOCG_CORE_WAIT): {
+ int ret;
+
+ ret = WaitEncReady(&hx280enc_data);
+ return ret;
+ }
+ }
+ return 0;
+}
+
+static int hx280enc_open(struct inode *inode, struct file *filp)
+{
+ int result = 0;
+ hx280enc_t *dev = &hx280enc_data;
+
+ filp->private_data = (void *) dev;
+
+#ifndef VSI
+ hantro_h1_clk_enable(dev->dev);
+ hantro_h1_power_on_disirq(dev);
+#endif
+
+ PDEBUG("dev opened\n");
+ return result;
+}
+
+static int hx280enc_release(struct inode *inode, struct file *filp)
+{
+ hx280enc_t *dev = (hx280enc_t *) filp->private_data;
+ unsigned long flags;
+#ifdef HX280ENC_DEBUG
+ dump_regs((unsigned long) dev); /* dump the regs */
+#endif
+
+ PDEBUG("dev closed\n");
+ spin_lock_irqsave(&owner_lock, flags);
+ if (dev->is_reserved == 1 && dev->pid == current->pid) {
+ dev->pid = -1;
+ dev->is_reserved = 0;
+ dev->irq_received = 0;
+ dev->irq_status = 0;
+ PDEBUG("release reserved core\n");
+ }
+ spin_unlock_irqrestore(&owner_lock, flags);
+ wake_up_interruptible_all(&enc_hw_queue);
+
+#ifndef VSI
+ pm_runtime_put_sync(hantro_h1_dev);
+ hantro_h1_clk_disable(hantro_h1_dev);
+#endif
+
+ return 0;
+}
+
+static long hx280enc_ioctl32(struct file *filp, unsigned int cmd, unsigned long arg)
+{
+ long err = 0;
+#define HX280ENC_IOCTL32(err, filp, cmd, arg) { \
+ mm_segment_t old_fs = get_fs(); \
+ set_fs(KERNEL_DS); \
+ err = hx280enc_ioctl(filp, cmd, arg); \
+ if (err) \
+ return err; \
+ set_fs(old_fs); \
+}
+
+union {
+ unsigned long kux;
+ unsigned int kui;
+} karg;
+ void __user *up = compat_ptr(arg);
+
+ switch (_IOC_NR(cmd)) {
+ case _IOC_NR(HX280ENC_IOCGHWOFFSET):
+ err = get_user(karg.kux, (s32 __user *)up);
+ if (err)
+ return err;
+ HX280ENC_IOCTL32(err, filp, cmd, (unsigned long)&karg);
+ err = put_user(((s32)karg.kux), (s32 __user *)up);
+ break;
+ case _IOC_NR(HX280ENC_IOCGHWIOSIZE):
+ err = get_user(karg.kui, (s32 __user *)up);
+ if (err)
+ return err;
+ HX280ENC_IOCTL32(err, filp, cmd, (unsigned long)&karg);
+ err = put_user(((s32)karg.kui), (s32 __user *)up);
+ break;
+ case _IOC_NR(HX280ENC_IOCH_ENC_RESERVE): {
+ int ret;
+ PDEBUG("Reserve ENC Cores\n");
+ ret = ReserveEncoder(&hx280enc_data);
+ return ret;
+ }
+ case _IOC_NR(HX280ENC_IOCH_ENC_RELEASE): {
+ PDEBUG("Release ENC Core\n");
+ ReleaseEncoder(&hx280enc_data);
+ break;
+ }
+ case _IOC_NR(HX280ENC_IOCG_CORE_WAIT): {
+ int ret;
+ ret = WaitEncReady(&hx280enc_data);
+ return ret;
+ }
+ }
+ return 0;
+}
+
+/* VFS methods */
+static struct file_operations hx280enc_fops = {
+ .owner = THIS_MODULE,
+ .open = hx280enc_open,
+ .release = hx280enc_release,
+ .unlocked_ioctl = hx280enc_ioctl,
+ .fasync = NULL,
+ .mmap = hx280enc_mmap,
+#ifdef CONFIG_COMPAT
+ .compat_ioctl = hx280enc_ioctl32,
+#endif
+};
+
+#ifndef VSI
+static int hx280enc_init(void)
+#else
+static int __init hx280enc_init(void)
+#endif
+{
+ int result;
+
+ PDEBUG(KERN_INFO "hx280enc: module init - base_port=0x%08lx irq=%i\n",
+ base_port, irq);
+
+ hx280enc_data.iobaseaddr = base_port;
+ hx280enc_data.iosize = ENC_IO_SIZE;
+ hx280enc_data.irq = irq;
+ hx280enc_data.async_queue = NULL;
+ hx280enc_data.hwregs = NULL;
+
+ result = register_chrdev(hx280enc_major, "hx280enc", &hx280enc_fops);
+ if (result < 0) {
+ PDEBUG(KERN_INFO "hx280enc: unable to get major <%d>\n", hx280enc_major);
+ return result;
+ } else if (result != 0) /* this is for dynamic major */
+ hx280enc_major = result;
+
+ result = ReserveIO();
+ if (result < 0)
+ goto err;
+
+ ResetAsic(&hx280enc_data); /* reset hardware */
+
+ /* get the IRQ line */
+ if (irq != -1) {
+ result = request_irq(irq, hx280enc_isr,
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 18))
+ SA_INTERRUPT | SA_SHIRQ,
+#else
+ //IRQF_DISABLED | IRQF_SHARED,
+ IRQF_SHARED,
+#endif
+ "hx280enc", (void *) &hx280enc_data);
+ if (result == -EINVAL) {
+ PDEBUG(KERN_ERR "hx280enc: Bad irq number or handler\n");
+ ReleaseIO();
+ goto err;
+ } else if (result == -EBUSY) {
+ PDEBUG(KERN_ERR "hx280enc: IRQ <%d> busy, change your config\n",
+ hx280enc_data.irq);
+ ReleaseIO();
+ goto err;
+ }
+ } else
+ PDEBUG(KERN_INFO "hx280enc: IRQ not in use!\n");
+ irq_set_status_flags(irq, IRQ_DISABLE_UNLAZY);
+
+ pr_info("hx280enc: module inserted. Major <%d>\n", hx280enc_major);
+ return 0;
+
+err:
+ unregister_chrdev(hx280enc_major, "hx280enc");
+ PDEBUG(KERN_ERR "hx280enc: module not inserted\n");
+ return result;
+}
+
+#ifndef VSI
+static void hx280enc_cleanup(void)
+#else
+static void __exit hx280enc_cleanup(void)
+#endif
+{
+ writel(0, hx280enc_data.hwregs + 0x38); /* disable HW */
+ writel(0, hx280enc_data.hwregs + 0x04); /* clear enc IRQ */
+
+ /* free the encoder IRQ */
+ if (hx280enc_data.irq != -1)
+ free_irq(hx280enc_data.irq, (void *) &hx280enc_data);
+
+ ReleaseIO();
+ unregister_chrdev(hx280enc_major, "hx280enc");
+
+ PDEBUG(KERN_INFO "hx280enc: module removed\n");
+}
+
+#ifdef VSI
+module_init(hx280enc_init);
+module_exit(hx280enc_cleanup);
+#endif
+static int ReserveIO(void)
+{
+ long int hwid;
+
+ if (!request_mem_region(hx280enc_data.iobaseaddr, hx280enc_data.iosize, "hx280enc")) {
+ PDEBUG(KERN_INFO "hx280enc: failed to reserve HW regs\n");
+ return -EBUSY;
+ }
+ hx280enc_data.hwregs = (volatile u8 *) ioremap_nocache(hx280enc_data.iobaseaddr, hx280enc_data.iosize);
+ if (hx280enc_data.hwregs == NULL) {
+ PDEBUG(KERN_INFO "hx280enc: failed to ioremap HW regs\n");
+ ReleaseIO();
+ return -EBUSY;
+ }
+
+ hwid = readl(hx280enc_data.hwregs);
+
+ /* check for encoder HW ID */
+ if ((((hwid >> 16) & 0xFFFF) != ((ENC_HW_ID1 >> 16) & 0xFFFF)) &&
+ (((hwid >> 16) & 0xFFFF) != ((ENC_HW_ID2 >> 16) & 0xFFFF)) &&
+ (((hwid >> 16) & 0xFFFF) != ((ENC_HW_ID3 >> 16) & 0xFFFF)) &&
+ (((hwid >> 16) & 0xFFFF) != ((ENC_HW_ID4 >> 16) & 0xFFFF)) &&
+ (((hwid >> 16) & 0xFFFF) != ((ENC_HW_ID5 >> 16) & 0xFFFF))) {
+ PDEBUG(KERN_ERR "hx280enc: HW not found at 0x%08lx\n", hx280enc_data.iobaseaddr);
+#ifdef HX280ENC_DEBUG
+ dump_regs((unsigned long) &hx280enc_data);
+#endif
+ ReleaseIO();
+ return -EBUSY;
+ }
+
+ hx280enc_data.hw_id = hwid;
+ hx280enc_data.is_valid = 1;
+
+ PDEBUG(KERN_INFO "hx280enc: HW at base <0x%08lx> with ID <0x%08lx>\n", hx280enc_data.iobaseaddr, hwid);
+ return 0;
+}
+
+static void ReleaseIO(void)
+{
+ if (hx280enc_data.is_valid == 0)
+ return;
+ if (hx280enc_data.hwregs)
+ iounmap((void *) hx280enc_data.hwregs);
+ release_mem_region(hx280enc_data.iobaseaddr, hx280enc_data.iosize);
+}
+
+irqreturn_t hx280enc_isr(int irq, void *dev_id)
+{
+ hx280enc_t *dev = (hx280enc_t *) dev_id;
+ u32 irq_status;
+ unsigned long flags;
+ u32 is_write1_clr;
+
+ spin_lock_irqsave(&owner_lock, flags);
+ if (!dev->is_reserved) {
+ spin_unlock_irqrestore(&owner_lock, flags);
+ return IRQ_HANDLED;
+ }
+ spin_unlock_irqrestore(&owner_lock, flags);
+ irq_status = readl(dev->hwregs + 0x04);
+
+ /* BASE_HWFuse2 = 0x4a0; HWCFGIrqClearSupport = 0x00800000 */
+ is_write1_clr = (readl(dev->hwregs + 0x4a0) & 0x00800000);
+ if (irq_status & 0x01) {
+ /* clear enc IRQ and slice ready interrupt bit */
+ if (is_write1_clr)
+ writel(irq_status & (0x101), dev->hwregs + 0x04);
+ else
+ writel(irq_status & (~0x101), dev->hwregs + 0x04);
+
+ /* Handle slice ready interrupts. The reference implementation
+ * doesn't signal slice ready interrupts to EWL.
+ * The EWL will poll the slices ready register value. */
+ if ((irq_status & 0x1FE) == 0x100) {
+ PDEBUG("Slice ready IRQ handled!\n");
+ return IRQ_HANDLED;
+ }
+
+ spin_lock_irqsave(&owner_lock, flags);
+ dev->irq_received = 1;
+ dev->irq_status = irq_status & (~0x01);
+ spin_unlock_irqrestore(&owner_lock, flags);
+
+ wake_up_interruptible_all(&enc_wait_queue);
+
+ PDEBUG("IRQ handled!\n");
+ return IRQ_HANDLED;
+ } else {
+ PDEBUG("IRQ received, but NOT handled!\n");
+ return IRQ_NONE;
+ }
+}
+
+static void ResetAsic(hx280enc_t *dev)
+{
+ int i;
+
+ if (dev->is_valid == 0)
+ return;
+
+ writel(0, dev->hwregs + 0x38);
+
+ for (i = 4; i < dev->iosize; i += 4)
+ writel(0, dev->hwregs + i);
+}
+
+#ifdef HX280ENC_DEBUG
+static void dump_regs(unsigned long data)
+{
+ hx280enc_t *dev = (hx280enc_t *) data;
+ int i;
+
+ PDEBUG("Reg Dump Start\n");
+ for (i = 0; i < dev->iosize; i += 4)
+ PDEBUG("\toffset %02X = %08X\n", i, readl(dev->hwregs + i));
+ PDEBUG("Reg Dump End\n");
+}
+#endif
+
+
+
+#ifndef VSI
+static int hantro_h1_probe(struct platform_device *pdev)
+{
+ int err = 0;
+ struct device *temp_class;
+ struct resource *res;
+ unsigned long reg_base;
+
+ hantro_h1_dev = &pdev->dev;
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "regs_hantro_h1");
+ if (!res) {
+ pr_err("hantro h1: unable to get vpu base addr\n");
+ return -ENODEV;
+ }
+ reg_base = res->start;
+ if ((ulong)reg_base != base_port) {
+ pr_err("hantro h1: regbase(0x%lX) not equal to expected value(0x%lX)\n", reg_base, base_port);
+ return -ENODEV;
+ }
+
+ irq = platform_get_irq_byname(pdev, "irq_hantro_h1");
+ if (irq < 0) {
+ pr_err("hantro h1: not find valid irq\n");
+ return -ENODEV;
+ }
+
+ hantro_clk_h1 = clk_get(&pdev->dev, "clk_hantro_h1");
+ if (IS_ERR(hantro_clk_h1)) {
+ pr_err("hantro h1: get clock failed, %p\n", hantro_clk_h1);
+ err = -ENXIO;
+ goto error;
+ }
+ hantro_clk_h1_bus = clk_get(&pdev->dev, "clk_hantro_h1_bus");
+ if (IS_ERR(hantro_clk_h1_bus)) {
+ pr_err("hantro h1: get bus clock failed, %p\n", hantro_clk_h1_bus);
+ err = -ENXIO;
+ goto error;
+ }
+
+ PDEBUG("hantro: h1 clock: 0x%lX, 0x%lX\n", clk_get_rate(hantro_clk_h1), clk_get_rate(hantro_clk_h1_bus));
+
+ hantro_h1_clk_enable(&pdev->dev);
+ pm_runtime_enable(&pdev->dev);
+ pm_runtime_get_sync(&pdev->dev);
+ hantro_h1_ctrlblk_reset(&pdev->dev);
+
+ err = hx280enc_init();
+ if (0 != err) {
+ pr_err("hantro h1: init failed\n");
+ goto error;
+ }
+
+ hantro_h1_class = class_create(THIS_MODULE, "mxc_hantro_h1");
+ if (IS_ERR(hantro_h1_class)) {
+ err = PTR_ERR(hantro_h1_class);
+ goto error;
+ }
+ temp_class = device_create(hantro_h1_class, NULL, MKDEV(hx280enc_major, 0), NULL, DEVICE_NAME);
+ if (IS_ERR(temp_class)) {
+ err = PTR_ERR(temp_class);
+ goto err_out_class;
+ }
+ hx280enc_data.dev = &pdev->dev;
+ platform_set_drvdata(pdev, &hx280enc_data);
+ mutex_init(&hx280enc_data.dev_mutex);
+
+ goto out;
+
+err_out_class:
+ device_destroy(hantro_h1_class, MKDEV(hx280enc_major, 0));
+ class_destroy(hantro_h1_class);
+error:
+ pr_err("hantro probe failed\n");
+out:
+ pm_runtime_put_sync(&pdev->dev);
+ hantro_h1_clk_disable(&pdev->dev);
+ return err;
+}
+
+static int hantro_h1_dev_remove(struct platform_device *pdev)
+{
+ hantro_h1_clk_enable(&pdev->dev);
+ pm_runtime_get_sync(&pdev->dev);
+ if (hx280enc_major > 0) {
+ device_destroy(hantro_h1_class, MKDEV(hx280enc_major, 0));
+ class_destroy(hantro_h1_class);
+ hx280enc_cleanup();
+ hx280enc_major = 0;
+ }
+ pm_runtime_put_sync(&pdev->dev);
+ pm_runtime_disable(&pdev->dev);
+ hantro_h1_clk_disable(&pdev->dev);
+
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int hantro_h1_suspend(struct device *dev)
+{
+ pm_runtime_put_sync_suspend(dev); //power off
+ return 0;
+}
+static int hantro_h1_resume(struct device *dev)
+{
+ hx280enc_t *hx280enc = dev_get_drvdata(dev);
+
+ hantro_h1_power_on_disirq(hx280enc);
+ hantro_h1_ctrlblk_reset(dev);
+ return 0;
+}
+static int hantro_h1_runtime_suspend(struct device *dev)
+{
+ //release_bus_freq(BUS_FREQ_HIGH);
+ return 0;
+}
+
+static int hantro_h1_runtime_resume(struct device *dev)
+{
+ //request_bus_freq(BUS_FREQ_HIGH);
+ hantro_h1_ctrlblk_reset(dev);
+ return 0;
+}
+
+static const struct dev_pm_ops hantro_h1_pm_ops = {
+ SET_RUNTIME_PM_OPS(hantro_h1_runtime_suspend, hantro_h1_runtime_resume, NULL)
+ SET_SYSTEM_SLEEP_PM_OPS(hantro_h1_suspend, hantro_h1_resume)
+};
+#endif //CONFIG_PM
+
+static const struct of_device_id hantro_h1_of_match[] = {
+ { .compatible = "nxp,imx8mm-hantro-h1", },
+ {/* sentinel */}
+};
+MODULE_DEVICE_TABLE(of, hantro_h1_of_match);
+
+
+static struct platform_driver mxchantro_h1_driver = {
+ .driver = {
+ .name = "mxc_hantro_h1",
+ .of_match_table = hantro_h1_of_match,
+#ifdef CONFIG_PM
+ .pm = &hantro_h1_pm_ops,
+#endif
+ },
+ .probe = hantro_h1_probe,
+ .remove = hantro_h1_dev_remove,
+};
+
+static int __init hantro_h1_init(void)
+{
+ int ret = platform_driver_register(&mxchantro_h1_driver);
+
+ return ret;
+}
+
+static void __exit hantro_h1_exit(void)
+{
+ //clk_put(hantro_clk);
+ platform_driver_unregister(&mxchantro_h1_driver);
+}
+
+module_init(hantro_h1_init);
+module_exit(hantro_h1_exit);
+
+#endif
+
diff --git a/drivers/mxc/hantro_845_h1/hx280enc.h b/drivers/mxc/hantro_845_h1/hx280enc.h
new file mode 100755
index 000000000000..d465c25f9f66
--- /dev/null
+++ b/drivers/mxc/hantro_845_h1/hx280enc.h
@@ -0,0 +1,79 @@
+ /*****************************************************************************
+ * Encoder device driver (kernel module header)
+ *
+ * Copyright (C) 2012 Google Finland Oy.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+--------------------------------------------------------------------------------
+--
+-- Abstract : 6280/7280/8270/8290/H1 Encoder device driver (kernel module)
+--
+*****************************************************************************/
+#ifndef _UAPI_HX280ENC_H_
+#define _UAPI_HX280ENC_H_
+#include <linux/ioctl.h> /* needed for the _IOW etc stuff used later */
+
+/*
+ * Macros to help debugging
+ */
+
+#undef PDEBUG /* undef it, just in case */
+#ifdef HX280ENC_DEBUG
+# ifdef __KERNEL__
+ /* This one if debugging is on, and kernel space */
+# define PDEBUG(fmt, args...) printk(KERN_INFO "hmp4e: " fmt, ## args)
+# else
+ /* This one for user space */
+# define PDEBUG(fmt, args...) printf(__FILE__ ":%d: " fmt, __LINE__, ## args)
+# endif
+#else
+# define PDEBUG(fmt, args...) /* not debugging: nothing */
+#endif
+
+/*
+ * Ioctl definitions
+ */
+
+/* Use 'k' as magic number */
+#define HX280ENC_IOC_MAGIC 'k'
+/*
+ * S means "Set" through a ptr,
+ * T means "Tell" directly with the argument value
+ * G means "Get": reply by setting through a pointer
+ * Q means "Query": response is on the return value
+ * X means "eXchange": G and S atomically
+ * H means "sHift": T and Q atomically
+ */
+ /*
+ * #define HX280ENC_IOCGBUFBUSADDRESS _IOR(HX280ENC_IOC_MAGIC, 1, unsigned long *)
+ * #define HX280ENC_IOCGBUFSIZE _IOR(HX280ENC_IOC_MAGIC, 2, unsigned int *)
+ */
+#define HX280ENC_IOCGHWOFFSET _IOR(HX280ENC_IOC_MAGIC, 3, unsigned long *)
+#define HX280ENC_IOCGHWIOSIZE _IOR(HX280ENC_IOC_MAGIC, 4, unsigned int *)
+#define HX280ENC_IOC_CLI _IO(HX280ENC_IOC_MAGIC, 5)
+#define HX280ENC_IOC_STI _IO(HX280ENC_IOC_MAGIC, 6)
+#define HX280ENC_IOCXVIRT2BUS _IOWR(HX280ENC_IOC_MAGIC, 7, unsigned long *)
+
+#define HX280ENC_IOCHARDRESET _IO(HX280ENC_IOC_MAGIC, 8) /* debugging tool */
+#define HX280ENC_IOCGSRAMOFFSET _IOR(HX280ENC_IOC_MAGIC, 9, unsigned long *)
+#define HX280ENC_IOCGSRAMEIOSIZE _IOR(HX280ENC_IOC_MAGIC, 10, unsigned int *)
+
+#define HX280ENC_IOCH_ENC_RESERVE _IOR(HX280ENC_IOC_MAGIC, 11, unsigned int *)
+#define HX280ENC_IOCH_ENC_RELEASE _IOR(HX280ENC_IOC_MAGIC, 12, unsigned int *)
+#define HX280ENC_IOCG_CORE_WAIT _IOR(HX280ENC_IOC_MAGIC, 13, unsigned int *)
+#define HX280ENC_IOC_MAXNR 30
+
+#endif /* !_UAPI_HX280ENC_H_ */
diff --git a/drivers/mxc/hdmi-cec/Kconfig b/drivers/mxc/hdmi-cec/Kconfig
new file mode 100644
index 000000000000..c0be06854e27
--- /dev/null
+++ b/drivers/mxc/hdmi-cec/Kconfig
@@ -0,0 +1,11 @@
+
+menu "MXC HDMI CEC (Consumer Electronics Control) support"
+
+config MXC_HDMI_CEC
+ tristate "Support for MXC HDMI CEC (Consumer Electronics Control)"
+ depends on MFD_MXC_HDMI
+ depends on FB_MXC_HDMI
+ help
+ The HDMI CEC device implement low level protocol on i.MX6x platforms.
+
+endmenu
diff --git a/drivers/mxc/hdmi-cec/Makefile b/drivers/mxc/hdmi-cec/Makefile
new file mode 100644
index 000000000000..07248b25b033
--- /dev/null
+++ b/drivers/mxc/hdmi-cec/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_MXC_HDMI_CEC) += mxc_hdmi-cec.o
diff --git a/drivers/mxc/hdmi-cec/mxc_hdmi-cec.c b/drivers/mxc/hdmi-cec/mxc_hdmi-cec.c
new file mode 100644
index 000000000000..75c01972e584
--- /dev/null
+++ b/drivers/mxc/hdmi-cec/mxc_hdmi-cec.c
@@ -0,0 +1,665 @@
+/*
+ * Copyright (C) 2012-2015 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/*!
+ * @file mxc_hdmi-cec.c
+ *
+ * @brief HDMI CEC system initialization and file operation implementation
+ *
+ * @ingroup HDMI
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/fs.h>
+#include <linux/stat.h>
+#include <linux/platform_device.h>
+#include <linux/poll.h>
+#include <linux/wait.h>
+#include <linux/list.h>
+#include <linux/delay.h>
+#include <linux/fsl_devices.h>
+#include <linux/uaccess.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
+#include <linux/workqueue.h>
+#include <linux/sizes.h>
+
+#include <linux/console.h>
+#include <linux/types.h>
+#include <linux/mfd/mxc-hdmi-core.h>
+#include <linux/pinctrl/consumer.h>
+
+#include <video/mxc_hdmi.h>
+
+#include "mxc_hdmi-cec.h"
+
+
+#define MAX_MESSAGE_LEN 17
+
+#define MESSAGE_TYPE_RECEIVE_SUCCESS 1
+#define MESSAGE_TYPE_NOACK 2
+#define MESSAGE_TYPE_DISCONNECTED 3
+#define MESSAGE_TYPE_CONNECTED 4
+#define MESSAGE_TYPE_SEND_SUCCESS 5
+
+
+struct hdmi_cec_priv {
+ int receive_error;
+ int send_error;
+ u8 Logical_address;
+ bool cec_state;
+ u8 last_msg[MAX_MESSAGE_LEN];
+ u8 msg_len;
+ u8 latest_cec_stat;
+ spinlock_t irq_lock;
+ struct delayed_work hdmi_cec_work;
+ struct mutex lock;
+};
+
+struct hdmi_cec_event {
+ int event_type;
+ int msg_len;
+ u8 msg[MAX_MESSAGE_LEN];
+ struct list_head list;
+};
+
+static LIST_HEAD(head);
+
+static int hdmi_cec_major;
+static struct class *hdmi_cec_class;
+static struct hdmi_cec_priv hdmi_cec_data;
+static u8 open_count;
+
+static wait_queue_head_t hdmi_cec_queue;
+static irqreturn_t mxc_hdmi_cec_isr(int irq, void *data)
+{
+ struct hdmi_cec_priv *hdmi_cec = data;
+ u8 cec_stat = 0;
+ unsigned long flags;
+
+ spin_lock_irqsave(&hdmi_cec->irq_lock, flags);
+
+ hdmi_writeb(0x7f, HDMI_IH_MUTE_CEC_STAT0);
+
+ cec_stat = hdmi_readb(HDMI_IH_CEC_STAT0);
+ hdmi_writeb(cec_stat, HDMI_IH_CEC_STAT0);
+
+ if ((cec_stat & (HDMI_IH_CEC_STAT0_ERROR_INIT | \
+ HDMI_IH_CEC_STAT0_NACK | HDMI_IH_CEC_STAT0_EOM | \
+ HDMI_IH_CEC_STAT0_DONE)) == 0) {
+ spin_unlock_irqrestore(&hdmi_cec->irq_lock, flags);
+ return IRQ_HANDLED;
+ }
+
+ pr_debug("HDMI CEC interrupt received\n");
+ hdmi_cec->latest_cec_stat = cec_stat;
+
+ schedule_delayed_work(&(hdmi_cec->hdmi_cec_work), msecs_to_jiffies(20));
+
+ spin_unlock_irqrestore(&hdmi_cec->irq_lock, flags);
+
+ return IRQ_HANDLED;
+}
+
+void mxc_hdmi_cec_handle(u16 cec_stat)
+{
+ u8 val = 0, i = 0;
+ struct hdmi_cec_event *event = NULL;
+
+ /* The current transmission is successful (for initiator only). */
+ if (!open_count)
+ return;
+
+ if (cec_stat & HDMI_IH_CEC_STAT0_DONE) {
+
+ event = vmalloc(sizeof(struct hdmi_cec_event));
+ if (NULL == event) {
+ pr_err("%s: Not enough memory!\n", __func__);
+ return;
+ }
+
+ memset(event, 0, sizeof(struct hdmi_cec_event));
+ event->event_type = MESSAGE_TYPE_SEND_SUCCESS;
+
+ mutex_lock(&hdmi_cec_data.lock);
+ list_add_tail(&event->list, &head);
+ mutex_unlock(&hdmi_cec_data.lock);
+
+ wake_up(&hdmi_cec_queue);
+ }
+
+ /* EOM is detected so that the received data is ready
+ * in the receiver data buffer
+ */
+ if (cec_stat & HDMI_IH_CEC_STAT0_EOM) {
+
+ hdmi_writeb(0x02, HDMI_IH_CEC_STAT0);
+
+ event = vmalloc(sizeof(struct hdmi_cec_event));
+ if (NULL == event) {
+ pr_err("%s: Not enough memory!\n", __func__);
+ return;
+ }
+ memset(event, 0, sizeof(struct hdmi_cec_event));
+
+ event->msg_len = hdmi_readb(HDMI_CEC_RX_CNT);
+ if (!event->msg_len) {
+ pr_err("%s: Invalid CEC message length!\n", __func__);
+ vfree(event);
+ return;
+ }
+ event->event_type = MESSAGE_TYPE_RECEIVE_SUCCESS;
+
+ for (i = 0; i < event->msg_len; i++)
+ event->msg[i] = hdmi_readb(HDMI_CEC_RX_DATA0+i);
+ hdmi_writeb(0x0, HDMI_CEC_LOCK);
+
+ mutex_lock(&hdmi_cec_data.lock);
+ list_add_tail(&event->list, &head);
+ mutex_unlock(&hdmi_cec_data.lock);
+
+ wake_up(&hdmi_cec_queue);
+ }
+
+ /* An error is detected on cec line (for initiator only). */
+ if (cec_stat & HDMI_IH_CEC_STAT0_ERROR_INIT) {
+
+ mutex_lock(&hdmi_cec_data.lock);
+ hdmi_cec_data.send_error++;
+ if (hdmi_cec_data.send_error > 5) {
+ pr_err("%s:Re-transmission is attempted more than 5 times!\n",
+ __func__);
+ hdmi_cec_data.send_error = 0;
+ mutex_unlock(&hdmi_cec_data.lock);
+ return;
+ }
+
+ for (i = 0; i < hdmi_cec_data.msg_len; i++) {
+ hdmi_writeb(hdmi_cec_data.last_msg[i],
+ HDMI_CEC_TX_DATA0 + i);
+ }
+ hdmi_writeb(hdmi_cec_data.msg_len, HDMI_CEC_TX_CNT);
+
+ val = hdmi_readb(HDMI_CEC_CTRL);
+ val |= 0x01;
+ hdmi_writeb(val, HDMI_CEC_CTRL);
+ mutex_unlock(&hdmi_cec_data.lock);
+ }
+
+ /* A frame is not acknowledged in a directly addressed message.
+ * Or a frame is negatively acknowledged in
+ * a broadcast message (for initiator only).
+ */
+ if (cec_stat & HDMI_IH_CEC_STAT0_NACK) {
+ event = vmalloc(sizeof(struct hdmi_cec_event));
+ if (NULL == event) {
+ pr_err("%s: Not enough memory\n", __func__);
+ return;
+ }
+ memset(event, 0, sizeof(struct hdmi_cec_event));
+ event->event_type = MESSAGE_TYPE_NOACK;
+
+ mutex_lock(&hdmi_cec_data.lock);
+ list_add_tail(&event->list, &head);
+ mutex_unlock(&hdmi_cec_data.lock);
+
+ wake_up(&hdmi_cec_queue);
+ }
+
+ /* An error is notified by a follower.
+ * Abnormal logic data bit error (for follower).
+ */
+ if (cec_stat & HDMI_IH_CEC_STAT0_ERROR_FOLL) {
+ hdmi_cec_data.receive_error++;
+ }
+
+ /* HDMI cable connected */
+ if (cec_stat & 0x80) {
+ event = vmalloc(sizeof(struct hdmi_cec_event));
+ if (NULL == event) {
+ pr_err("%s: Not enough memory\n", __func__);
+ return;
+ }
+ memset(event, 0, sizeof(struct hdmi_cec_event));
+ event->event_type = MESSAGE_TYPE_CONNECTED;
+
+ mutex_lock(&hdmi_cec_data.lock);
+ list_add_tail(&event->list, &head);
+ mutex_unlock(&hdmi_cec_data.lock);
+
+ wake_up(&hdmi_cec_queue);
+ }
+
+ /* HDMI cable disconnected */
+ if (cec_stat & 0x100) {
+ event = vmalloc(sizeof(struct hdmi_cec_event));
+ if (NULL == event) {
+ pr_err("%s: Not enough memory!\n", __func__);
+ return;
+ }
+ memset(event, 0, sizeof(struct hdmi_cec_event));
+ event->event_type = MESSAGE_TYPE_DISCONNECTED;
+
+ mutex_lock(&hdmi_cec_data.lock);
+ list_add_tail(&event->list, &head);
+ mutex_unlock(&hdmi_cec_data.lock);
+
+ wake_up(&hdmi_cec_queue);
+ }
+
+ return;
+}
+EXPORT_SYMBOL(mxc_hdmi_cec_handle);
+
+static void mxc_hdmi_cec_worker(struct work_struct *work)
+{
+ u8 val;
+
+ mxc_hdmi_cec_handle(hdmi_cec_data.latest_cec_stat);
+ val = HDMI_IH_CEC_STAT0_WAKEUP | HDMI_IH_CEC_STAT0_ERROR_FOLL |
+ HDMI_IH_CEC_STAT0_ARB_LOST;
+ hdmi_writeb(val, HDMI_IH_MUTE_CEC_STAT0);
+}
+
+/*!
+ * @brief open function for vpu file operation
+ *
+ * @return 0 on success or negative error code on error
+ */
+static int hdmi_cec_open(struct inode *inode, struct file *filp)
+{
+ mutex_lock(&hdmi_cec_data.lock);
+ if (open_count) {
+ mutex_unlock(&hdmi_cec_data.lock);
+ return -EBUSY;
+ }
+
+ open_count = 1;
+ filp->private_data = (void *)(&hdmi_cec_data);
+ hdmi_cec_data.Logical_address = 15;
+ hdmi_cec_data.cec_state = false;
+ mutex_unlock(&hdmi_cec_data.lock);
+
+ return 0;
+}
+
+static ssize_t hdmi_cec_read(struct file *file, char __user *buf, size_t count,
+ loff_t *ppos)
+{
+ struct hdmi_cec_event *event = NULL;
+
+ pr_debug("function : %s\n", __func__);
+ if (!open_count)
+ return -ENODEV;
+
+ mutex_lock(&hdmi_cec_data.lock);
+ if (false == hdmi_cec_data.cec_state) {
+ mutex_unlock(&hdmi_cec_data.lock);
+ return -EACCES;
+ }
+ mutex_unlock(&hdmi_cec_data.lock);
+
+ /* delete from list */
+ mutex_lock(&hdmi_cec_data.lock);
+ if (list_empty(&head)) {
+ mutex_unlock(&hdmi_cec_data.lock);
+ return -EACCES;
+ }
+ event = list_first_entry(&head, struct hdmi_cec_event, list);
+ list_del(&event->list);
+ mutex_unlock(&hdmi_cec_data.lock);
+
+ if (copy_to_user(buf, event,
+ sizeof(struct hdmi_cec_event) - sizeof(struct list_head))) {
+ vfree(event);
+ return -EFAULT;
+ }
+ vfree(event);
+
+ return sizeof(struct hdmi_cec_event);
+}
+
+static ssize_t hdmi_cec_write(struct file *file, const char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ int ret = 0 , i = 0;
+ u8 msg[MAX_MESSAGE_LEN];
+ u8 msg_len = 0, val = 0;
+
+ pr_debug("function : %s\n", __func__);
+ if (!open_count)
+ return -ENODEV;
+
+ mutex_lock(&hdmi_cec_data.lock);
+ if (false == hdmi_cec_data.cec_state) {
+ mutex_unlock(&hdmi_cec_data.lock);
+ return -EACCES;
+ }
+ mutex_unlock(&hdmi_cec_data.lock);
+
+ if (count > MAX_MESSAGE_LEN)
+ return -EINVAL;
+
+ mutex_lock(&hdmi_cec_data.lock);
+ hdmi_cec_data.send_error = 0;
+ memset(&msg, 0, MAX_MESSAGE_LEN);
+ ret = copy_from_user(&msg, buf, count);
+ if (ret) {
+ ret = -EACCES;
+ goto end;
+ }
+
+ msg_len = count;
+ hdmi_writeb(msg_len, HDMI_CEC_TX_CNT);
+ for (i = 0; i < msg_len; i++) {
+ hdmi_writeb(msg[i], HDMI_CEC_TX_DATA0+i);
+ }
+
+ val = hdmi_readb(HDMI_CEC_CTRL);
+ val |= 0x01;
+ hdmi_writeb(val, HDMI_CEC_CTRL);
+ memcpy(hdmi_cec_data.last_msg, msg, msg_len);
+ hdmi_cec_data.msg_len = msg_len;
+
+ i = 0;
+ val = hdmi_readb(HDMI_CEC_CTRL);
+ while ((val & 0x01) == 0x1) {
+ msleep(50);
+ i++;
+ if (i > 3) {
+ ret = -EIO;
+ goto end;
+ }
+ val = hdmi_readb(HDMI_CEC_CTRL);
+ }
+
+end:
+ mutex_unlock(&hdmi_cec_data.lock);
+
+ return ret;
+}
+
+/*!
+ * @brief IO ctrl function for vpu file operation
+ * @param cmd IO ctrl command
+ * @return 0 on success or negative error code on error
+ */
+static long hdmi_cec_ioctl(struct file *filp, u_int cmd,
+ u_long arg)
+{
+ int ret = 0, status = 0;
+ u8 val = 0, msg = 0;
+ struct mxc_edid_cfg hdmi_edid_cfg;
+
+ pr_debug("function : %s\n", __func__);
+ if (!open_count)
+ return -ENODEV;
+
+ switch (cmd) {
+ case HDMICEC_IOC_SETLOGICALADDRESS:
+ mutex_lock(&hdmi_cec_data.lock);
+ if (false == hdmi_cec_data.cec_state) {
+ mutex_unlock(&hdmi_cec_data.lock);
+ return -EACCES;
+ }
+
+ hdmi_cec_data.Logical_address = (u8)arg;
+
+ if (hdmi_cec_data.Logical_address <= 7) {
+ val = 1 << hdmi_cec_data.Logical_address;
+ hdmi_writeb(val, HDMI_CEC_ADDR_L);
+ hdmi_writeb(0, HDMI_CEC_ADDR_H);
+ } else if (hdmi_cec_data.Logical_address > 7 &&
+ hdmi_cec_data.Logical_address <= 15) {
+ val = 1 << (hdmi_cec_data.Logical_address - 8);
+ hdmi_writeb(val, HDMI_CEC_ADDR_H);
+ hdmi_writeb(0, HDMI_CEC_ADDR_L);
+ } else {
+ ret = -EINVAL;
+ }
+
+ /* Send Polling message with same source
+ * and destination address
+ */
+ if (0 == ret && 15 != hdmi_cec_data.Logical_address) {
+ msg = (hdmi_cec_data.Logical_address << 4) |
+ hdmi_cec_data.Logical_address;
+ hdmi_writeb(1, HDMI_CEC_TX_CNT);
+ hdmi_writeb(msg, HDMI_CEC_TX_DATA0);
+
+ val = hdmi_readb(HDMI_CEC_CTRL);
+ val |= 0x01;
+ hdmi_writeb(val, HDMI_CEC_CTRL);
+ }
+
+ mutex_unlock(&hdmi_cec_data.lock);
+ break;
+
+ case HDMICEC_IOC_STARTDEVICE:
+ val = hdmi_readb(HDMI_MC_CLKDIS);
+ val &= ~HDMI_MC_CLKDIS_CECCLK_DISABLE;
+ hdmi_writeb(val, HDMI_MC_CLKDIS);
+
+ hdmi_writeb(0x02, HDMI_CEC_CTRL);
+
+ val = HDMI_IH_CEC_STAT0_ERROR_INIT | HDMI_IH_CEC_STAT0_NACK |
+ HDMI_IH_CEC_STAT0_EOM | HDMI_IH_CEC_STAT0_DONE;
+ hdmi_writeb(val, HDMI_CEC_POLARITY);
+
+ val = HDMI_IH_CEC_STAT0_WAKEUP | HDMI_IH_CEC_STAT0_ERROR_FOLL |
+ HDMI_IH_CEC_STAT0_ARB_LOST;
+ hdmi_writeb(val, HDMI_CEC_MASK);
+ hdmi_writeb(val, HDMI_IH_MUTE_CEC_STAT0);
+
+ mutex_lock(&hdmi_cec_data.lock);
+ hdmi_cec_data.cec_state = true;
+ mutex_unlock(&hdmi_cec_data.lock);
+ break;
+
+ case HDMICEC_IOC_STOPDEVICE:
+ hdmi_writeb(0x10, HDMI_CEC_CTRL);
+
+ val = HDMI_IH_CEC_STAT0_WAKEUP | HDMI_IH_CEC_STAT0_ERROR_FOLL |
+ HDMI_IH_CEC_STAT0_ERROR_INIT | HDMI_IH_CEC_STAT0_ARB_LOST |
+ HDMI_IH_CEC_STAT0_NACK | HDMI_IH_CEC_STAT0_EOM |
+ HDMI_IH_CEC_STAT0_DONE;
+ hdmi_writeb(val, HDMI_CEC_MASK);
+ hdmi_writeb(val, HDMI_IH_MUTE_CEC_STAT0);
+
+ hdmi_writeb(0x0, HDMI_CEC_POLARITY);
+
+ val = hdmi_readb(HDMI_MC_CLKDIS);
+ val |= HDMI_MC_CLKDIS_CECCLK_DISABLE;
+ hdmi_writeb(val, HDMI_MC_CLKDIS);
+
+ mutex_lock(&hdmi_cec_data.lock);
+ hdmi_cec_data.cec_state = false;
+ mutex_unlock(&hdmi_cec_data.lock);
+ break;
+
+ case HDMICEC_IOC_GETPHYADDRESS:
+ hdmi_get_edid_cfg(&hdmi_edid_cfg);
+ status = copy_to_user((void __user *)arg,
+ &hdmi_edid_cfg.physical_address,
+ 4*sizeof(u8));
+ if (status)
+ ret = -EFAULT;
+ break;
+
+ default:
+ ret = -EINVAL;
+ break;
+ }
+
+ return ret;
+}
+
+/*!
+* @brief Release function for vpu file operation
+* @return 0 on success or negative error code on error
+*/
+static int hdmi_cec_release(struct inode *inode, struct file *filp)
+{
+ mutex_lock(&hdmi_cec_data.lock);
+
+ if (open_count) {
+ open_count = 0;
+ hdmi_cec_data.cec_state = false;
+ hdmi_cec_data.Logical_address = 15;
+ }
+
+ mutex_unlock(&hdmi_cec_data.lock);
+
+ return 0;
+}
+
+static unsigned int hdmi_cec_poll(struct file *file, poll_table *wait)
+{
+ unsigned int mask = 0;
+
+ pr_debug("function : %s\n", __func__);
+
+ if (!open_count)
+ return -ENODEV;
+
+ if (false == hdmi_cec_data.cec_state)
+ return -EACCES;
+
+ poll_wait(file, &hdmi_cec_queue, wait);
+
+ if (!list_empty(&head))
+ mask |= (POLLIN | POLLRDNORM);
+
+ return mask;
+}
+
+const struct file_operations hdmi_cec_fops = {
+ .owner = THIS_MODULE,
+ .read = hdmi_cec_read,
+ .write = hdmi_cec_write,
+ .open = hdmi_cec_open,
+ .unlocked_ioctl = hdmi_cec_ioctl,
+ .release = hdmi_cec_release,
+ .poll = hdmi_cec_poll,
+};
+
+static int hdmi_cec_dev_probe(struct platform_device *pdev)
+{
+ int err = 0;
+ struct device *temp_class;
+ struct resource *res;
+ struct pinctrl *pinctrl;
+ int irq = platform_get_irq(pdev, 0);
+
+ hdmi_cec_major = register_chrdev(hdmi_cec_major,
+ "mxc_hdmi_cec", &hdmi_cec_fops);
+ if (hdmi_cec_major < 0) {
+ dev_err(&pdev->dev, "hdmi_cec: unable to get a major for HDMI CEC\n");
+ err = -EBUSY;
+ goto out;
+ }
+
+ res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+ if (unlikely(res == NULL)) {
+ dev_err(&pdev->dev, "hdmi_cec:No HDMI irq line provided\n");
+ goto err_out_chrdev;
+ }
+
+ spin_lock_init(&hdmi_cec_data.irq_lock);
+
+ err = devm_request_irq(&pdev->dev, irq, mxc_hdmi_cec_isr, IRQF_SHARED,
+ dev_name(&pdev->dev), &hdmi_cec_data);
+ if (err < 0) {
+ dev_err(&pdev->dev, "hdmi_cec:Unable to request irq: %d\n", err);
+ goto err_out_chrdev;
+ }
+
+ hdmi_cec_class = class_create(THIS_MODULE, "mxc_hdmi_cec");
+ if (IS_ERR(hdmi_cec_class)) {
+ err = PTR_ERR(hdmi_cec_class);
+ goto err_out_chrdev;
+ }
+
+ temp_class = device_create(hdmi_cec_class, NULL,
+ MKDEV(hdmi_cec_major, 0), NULL, "mxc_hdmi_cec");
+ if (IS_ERR(temp_class)) {
+ err = PTR_ERR(temp_class);
+ goto err_out_class;
+ }
+
+ pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
+ if (IS_ERR(pinctrl)) {
+ dev_err(&pdev->dev, "can't get/select CEC pinctrl\n");
+ goto err_out_class;
+ }
+
+ init_waitqueue_head(&hdmi_cec_queue);
+
+ INIT_LIST_HEAD(&head);
+
+ mutex_init(&hdmi_cec_data.lock);
+
+ hdmi_cec_data.Logical_address = 15;
+
+ platform_set_drvdata(pdev, &hdmi_cec_data);
+
+ INIT_DELAYED_WORK(&hdmi_cec_data.hdmi_cec_work, mxc_hdmi_cec_worker);
+
+ dev_info(&pdev->dev, "HDMI CEC initialized\n");
+ goto out;
+
+err_out_class:
+ device_destroy(hdmi_cec_class, MKDEV(hdmi_cec_major, 0));
+ class_destroy(hdmi_cec_class);
+err_out_chrdev:
+ unregister_chrdev(hdmi_cec_major, "mxc_hdmi_cec");
+out:
+ return err;
+}
+
+static int hdmi_cec_dev_remove(struct platform_device *pdev)
+{
+ if (hdmi_cec_major > 0) {
+ device_destroy(hdmi_cec_class, MKDEV(hdmi_cec_major, 0));
+ class_destroy(hdmi_cec_class);
+ unregister_chrdev(hdmi_cec_major, "mxc_hdmi_cec");
+ hdmi_cec_major = 0;
+ }
+ return 0;
+}
+
+static const struct of_device_id imx_hdmi_cec_match[] = {
+ { .compatible = "fsl,imx6q-hdmi-cec", },
+ { .compatible = "fsl,imx6dl-hdmi-cec", },
+ { /* sentinel */ }
+};
+
+static struct platform_driver mxc_hdmi_cec_driver = {
+ .probe = hdmi_cec_dev_probe,
+ .remove = hdmi_cec_dev_remove,
+ .driver = {
+ .name = "mxc_hdmi_cec",
+ .of_match_table = imx_hdmi_cec_match,
+ },
+};
+
+module_platform_driver(mxc_hdmi_cec_driver);
+
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("Linux HDMI CEC driver for Freescale i.MX/MXC");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:mxc_hdmi_cec");
+
diff --git a/drivers/mxc/hdmi-cec/mxc_hdmi-cec.h b/drivers/mxc/hdmi-cec/mxc_hdmi-cec.h
new file mode 100644
index 000000000000..5c402af4d0c3
--- /dev/null
+++ b/drivers/mxc/hdmi-cec/mxc_hdmi-cec.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2005-2015 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+#ifndef _HDMICEC_H_
+#define _HDMICEC_H_
+#include <linux/ioctl.h>
+
+/*
+ * Ioctl definitions
+ */
+
+/* Use 'k' as magic number */
+#define HDMICEC_IOC_MAGIC 'H'
+/*
+ * S means "Set" through a ptr,
+ * T means "Tell" directly with the argument value
+ * G means "Get": reply by setting through a pointer
+ * Q means "Query": response is on the return value
+ * X means "eXchange": G and S atomically
+ * H means "sHift": T and Q atomically
+ */
+#define HDMICEC_IOC_SETLOGICALADDRESS \
+ _IOW(HDMICEC_IOC_MAGIC, 1, unsigned char)
+#define HDMICEC_IOC_STARTDEVICE _IO(HDMICEC_IOC_MAGIC, 2)
+#define HDMICEC_IOC_STOPDEVICE _IO(HDMICEC_IOC_MAGIC, 3)
+#define HDMICEC_IOC_GETPHYADDRESS \
+ _IOR(HDMICEC_IOC_MAGIC, 4, unsigned char[4])
+
+#endif /* !_HDMICEC_H_ */
diff --git a/drivers/mxc/hdp-cec/Kconfig b/drivers/mxc/hdp-cec/Kconfig
new file mode 100644
index 000000000000..7acbc07525cf
--- /dev/null
+++ b/drivers/mxc/hdp-cec/Kconfig
@@ -0,0 +1,5 @@
+config IMX_HDP_CEC
+ bool "Enable IMX HDP CEC support"
+ depends on MEDIA_CEC
+ ---help---
+ When selected the imx hdmi will support the optional HDMI CEC feature.
diff --git a/drivers/mxc/hdp-cec/Makefile b/drivers/mxc/hdp-cec/Makefile
new file mode 100644
index 000000000000..a432aa700990
--- /dev/null
+++ b/drivers/mxc/hdp-cec/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_IMX_HDP_CEC) += imx-hdp-cec.o
diff --git a/drivers/mxc/hdp-cec/imx-hdp-cec.c b/drivers/mxc/hdp-cec/imx-hdp-cec.c
new file mode 100644
index 000000000000..068ae8e82541
--- /dev/null
+++ b/drivers/mxc/hdp-cec/imx-hdp-cec.c
@@ -0,0 +1,316 @@
+/*
+ * Copyright 2017 NXP
+ *
+ * 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/clk.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/mfd/syscon.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/timer.h>
+#include <linux/version.h>
+#include <linux/workqueue.h>
+#include <linux/kthread.h>
+#include <linux/freezer.h>
+#include <media/cec.h>
+#include <soc/imx8/soc.h>
+
+#include "imx-hdp-cec.h"
+
+#define CEC_NAME "hdp-cec"
+
+#define REG_ADDR_OFF 1
+
+#define MAX_LA_IDX 4
+#define MAX_LA_VAL 15
+
+/**
+ * Maximum number of Messages in the RX Buffers.
+ */
+# define CEC_MAX_RX_MSGS 2
+
+#define set_la F_MY_LOG_ADDR0
+#define get_la F_MY_LOG_ADDR0_RD
+#define set_la_valid F_LOG_ADDR_VALID0
+#define get_la_valid F_LOG_ADDR_VALID0_RD
+
+u32 cec_read(struct imx_cec_dev *cec, u32 offset)
+{
+ u32 addr = (offset << 2) + ADDR_HDP_CEC_BASE;
+ u32 value;
+
+ cec->rw->read_reg(cec->mem, addr, &value);
+ return value;
+}
+
+void cec_write(struct imx_cec_dev *cec, u32 offset, u32 value)
+{
+ u32 addr = (offset << 2) + ADDR_HDP_CEC_BASE;
+
+ cec->rw->write_reg(cec->mem, addr, value);
+}
+
+void cec_clear_rx_buffer(struct imx_cec_dev *cec)
+{
+ cec_write(cec, RX_CLEAR_BUF, 1);
+ cec_write(cec, RX_CLEAR_BUF, 0);
+}
+
+void cec_set_divider(struct imx_cec_dev *cec)
+{
+ /* Set clock divider */
+ if (cec->clk_div == 0) {
+ dev_warn(cec->dev,
+ "Warning. Clock divider is 0. Changing to 1.\n");
+ cec_write(cec, CLK_DIV_MSB, 0);
+ cec_write(cec, CLK_DIV_LSB, 1);
+ } else {
+ cec_write(cec, CLK_DIV_MSB,
+ (cec->clk_div >> 8) & 0xFF);
+ cec_write(cec, CLK_DIV_LSB, cec->clk_div & 0xFF);
+ }
+}
+
+u32 cec_read_message(struct imx_cec_dev *cec)
+{
+ struct cec_msg *msg = &cec->msg;
+ int len;
+ int i;
+
+ cec_write(cec, RX_MSG_CMD, CEC_RX_READ);
+
+ len = cec_read(cec, RX_MSG_LENGTH);
+ msg->len = len + 1;
+ dev_dbg(cec->dev, "RX MSG len =%d\n", len);
+
+ /* Read RX MSG bytes */
+ for (i = 0; i < msg->len; ++i) {
+ msg->msg[i] = (u8) cec_read(cec, RX_MSG_DATA1 + (i * REG_ADDR_OFF));
+ dev_dbg(cec->dev, "RX MSG[%d]=0x%x\n", i, msg->msg[i]);
+ }
+
+ cec_write(cec, RX_MSG_CMD, CEC_RX_STOP);
+
+ return true;
+}
+
+u32 cec_write_message(struct imx_cec_dev *cec, struct cec_msg *msg)
+{
+ u8 i;
+
+ cec_write(cec, TX_MSG_CMD, CEC_TX_STOP);
+
+ if (msg->len > CEC_MAX_MSG_SIZE) {
+ dev_err(cec->dev, "Invalid MSG size!\n");
+ return -EINVAL;
+ }
+
+ /* Write Message to register */
+ for (i = 0; i < msg->len; ++i) {
+ cec_write(cec, TX_MSG_HEADER + (i * REG_ADDR_OFF),
+ msg->msg[i]);
+ }
+ /* Write Message Length (payload + opcode) */
+ cec_write(cec, TX_MSG_LENGTH, msg->len - 1);
+
+ cec_write(cec, TX_MSG_CMD, CEC_TX_TRANSMIT);
+
+ return true;
+}
+
+void cec_abort_tx_transfer(struct imx_cec_dev *cec)
+{
+ cec_write(cec, TX_MSG_CMD, CEC_TX_ABORT);
+ cec_write(cec, TX_MSG_CMD, CEC_TX_STOP);
+}
+
+u32 imx_cec_set_logical_addr(struct imx_cec_dev *cec, u32 la)
+{
+ u8 i;
+ u8 la_reg;
+
+ if (la >= MAX_LA_VAL) {
+ dev_err(cec->dev, "Error logical Addr\n");
+ return -EINVAL;
+ }
+
+ for (i = 0; i < MAX_LA_IDX; ++i) {
+ la_reg =
+ cec_read(cec, LOGICAL_ADDRESS_LA0 + (i * REG_ADDR_OFF));
+
+ if (get_la_valid(la_reg))
+ continue;
+
+ if (get_la(la_reg) == la) {
+ dev_warn(cec->dev, "Warning. LA already in use.\n");
+ return true;
+ }
+
+ la = set_la(la) | set_la_valid(1);
+
+ cec_write(cec, LOGICAL_ADDRESS_LA0 + (i * REG_ADDR_OFF), la);
+ return true;
+ }
+
+ dev_warn(cec->dev, "All LA in use\n");
+
+ return false;
+}
+
+static int cec_poll_worker(void *_cec)
+{
+ struct imx_cec_dev *cec = (struct imx_cec_dev *)_cec;
+ int num_rx_msgs, i;
+ int sts;
+
+ set_freezable();
+
+ for (;;) {
+ if (kthread_freezable_should_stop(NULL))
+ break;
+
+ /* Check TX State */
+ sts = cec_read(cec, TX_MSG_STATUS);
+ switch (sts) {
+ case CEC_STS_SUCCESS:
+ cec_transmit_done(cec->adap, CEC_TX_STATUS_OK, 0, 0, 0,
+ 0);
+ cec_write(cec, TX_MSG_CMD, CEC_TX_STOP);
+ break;
+ case CEC_STS_ERROR:
+ cec_write(cec, TX_MSG_CMD, CEC_TX_STOP);
+ cec_transmit_done(cec->adap,
+ CEC_TX_STATUS_MAX_RETRIES |
+ CEC_TX_STATUS_ERROR, 0, 0, 0, 1);
+ break;
+ case CEC_STS_BUSY:
+ default:
+ break;
+ }
+
+ /* Check RX State */
+ sts = cec_read(cec, RX_MSG_STATUS);
+ num_rx_msgs = cec_read(cec, NUM_OF_MSG_RX_BUF);
+ switch (sts) {
+ case CEC_STS_SUCCESS:
+ if (num_rx_msgs == 0xf)
+ num_rx_msgs = CEC_MAX_RX_MSGS;
+
+ if (num_rx_msgs > CEC_MAX_RX_MSGS) {
+ dev_err(cec->dev, "Error rx msg num %d\n",
+ num_rx_msgs);
+ cec_clear_rx_buffer(cec);
+ break;
+ }
+
+ /* Rx FIFO Depth 2 RX MSG */
+ for (i = 0; i < num_rx_msgs; i++) {
+ cec_read_message(cec);
+ cec->msg.rx_status = CEC_RX_STATUS_OK;
+ cec_received_msg(cec->adap, &cec->msg);
+ }
+ break;
+ default:
+ break;
+ }
+
+ if (!kthread_should_stop())
+ schedule_timeout_idle(20);
+ }
+
+ return 0;
+}
+
+static int imx_cec_adap_enable(struct cec_adapter *adap, bool enable)
+{
+ struct imx_cec_dev *cec = adap->priv;
+
+ if (enable) {
+ cec_write(cec, DB_L_TIMER, 0x10);
+ cec_set_divider(cec);
+ } else {
+ cec_set_divider(cec);
+ }
+
+ return 0;
+}
+
+static int imx_cec_adap_log_addr(struct cec_adapter *adap, u8 addr)
+{
+ struct imx_cec_dev *cec = adap->priv;
+
+ imx_cec_set_logical_addr(cec, addr);
+ return 0;
+}
+
+static int imx_cec_adap_transmit(struct cec_adapter *adap, u8 attempts,
+ u32 signal_free_time, struct cec_msg *msg)
+{
+ struct imx_cec_dev *cec = adap->priv;
+
+ cec_write_message(cec, msg);
+
+ return 0;
+}
+
+static const struct cec_adap_ops imx_cec_adap_ops = {
+ .adap_enable = imx_cec_adap_enable,
+ .adap_log_addr = imx_cec_adap_log_addr,
+ .adap_transmit = imx_cec_adap_transmit,
+};
+
+int imx_cec_register(struct imx_cec_dev *cec)
+{
+ struct device *dev = cec->dev;
+ int ret;
+
+ cec->adap = cec_allocate_adapter(&imx_cec_adap_ops, cec,
+ CEC_NAME,
+ CEC_CAP_PHYS_ADDR | CEC_CAP_LOG_ADDRS |
+ CEC_CAP_TRANSMIT | CEC_CAP_PASSTHROUGH
+ | CEC_CAP_RC, 1);
+ ret = PTR_ERR_OR_ZERO(cec->adap);
+ if (ret)
+ return ret;
+ ret = cec_register_adapter(cec->adap, dev);
+ if (ret) {
+ cec_delete_adapter(cec->adap);
+ return ret;
+ }
+
+ cec->dev = dev;
+
+ cec->cec_worker = kthread_create(cec_poll_worker, cec, "hdp-cec");
+ if (IS_ERR(cec->cec_worker))
+ dev_err(cec->dev, "failed create hdp cec thread\n");
+
+ wake_up_process(cec->cec_worker);
+
+ dev_dbg(dev, "CEC successfuly probed\n");
+ return 0;
+}
+
+int imx_cec_unregister(struct imx_cec_dev *cec)
+{
+ if (cec->cec_worker) {
+ kthread_stop(cec->cec_worker);
+ cec->cec_worker = NULL;
+ }
+ cec_unregister_adapter(cec->adap);
+ return 0;
+}
+
+MODULE_AUTHOR("Sandor.Yu@NXP.com");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("NXP IMX HDP CEC driver");
diff --git a/drivers/mxc/hdp-cec/imx-hdp-cec.h b/drivers/mxc/hdp-cec/imx-hdp-cec.h
new file mode 100644
index 000000000000..42a06b9d728d
--- /dev/null
+++ b/drivers/mxc/hdp-cec/imx-hdp-cec.h
@@ -0,0 +1,346 @@
+/*
+ * Copyright 2018 NXP
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _IMX_HDP_CEC_H_
+#define _IMX_HDP_CEC_H_
+
+#include <linux/cec.h>
+#include "../hdp/util.h"
+#include "../hdp/address.h"
+
+/* regsiter define */
+/* register TX_MSG_HEADER */
+#define TX_MSG_HEADER 0
+#define F_TX_FOLLOWER_ADDRESS(x) (((x) & ((1 << 4) - 1)) << 0)
+#define F_TX_FOLLOWER_ADDRESS_RD(x) (((x) & (((1 << 4) - 1) << 0)) >> 0)
+#define F_TX_INITIATOR_ADDRESS(x) (((x) & ((1 << 4) - 1)) << 4)
+#define F_TX_INITIATOR_ADDRESS_RD(x) (((x) & (((1 << 4) - 1) << 4)) >> 4)
+
+/* register TX_MSG_OPCODE */
+#define TX_MSG_OPCODE 1
+#define F_TX_MSG_OPCODE(x) (((x) & ((1 << 8) - 1)) << 0)
+#define F_TX_MSG_OPCODE_RD(x) (((x) & (((1 << 8) - 1) << 0)) >> 0)
+
+/* register TX_MSG_OP1 */
+#define TX_MSG_OP1 2
+#define F_TX_MSG_OP1(x) (((x) & ((1 << 8) - 1)) << 0)
+#define F_TX_MSG_OP1_RD(x) (((x) & (((1 << 8) - 1) << 0)) >> 0)
+
+/* register TX_MSG_OP2 */
+#define TX_MSG_OP2 3
+#define F_TX_MSG_OP2(x) (((x) & ((1 << 8) - 1)) << 0)
+#define F_TX_MSG_OP2_RD(x) (((x) & (((1 << 8) - 1) << 0)) >> 0)
+
+/* register TX_MSG_OP3 */
+#define TX_MSG_OP3 4
+#define F_TX_MSG_OP3(x) (((x) & ((1 << 8) - 1)) << 0)
+#define F_TX_MSG_OP3_RD(x) (((x) & (((1 << 8) - 1) << 0)) >> 0)
+
+/* register TX_MSG_OP4 */
+#define TX_MSG_OP4 5
+#define F_TX_MSG_OP4(x) (((x) & ((1 << 8) - 1)) << 0)
+#define F_TX_MSG_OP4_RD(x) (((x) & (((1 << 8) - 1) << 0)) >> 0)
+
+/* register TX_MSG_OP5 */
+#define TX_MSG_OP5 6
+#define F_TX_MSG_OP5(x) (((x) & ((1 << 8) - 1)) << 0)
+#define F_TX_MSG_OP5_RD(x) (((x) & (((1 << 8) - 1) << 0)) >> 0)
+
+/* register TX_MSG_OP6 */
+#define TX_MSG_OP6 7
+#define F_TX_MSG_OP6(x) (((x) & ((1 << 8) - 1)) << 0)
+#define F_TX_MSG_OP6_RD(x) (((x) & (((1 << 8) - 1) << 0)) >> 0)
+
+/* register TX_MSG_OP7 */
+#define TX_MSG_OP7 8
+#define F_TX_MSG_OP7(x) (((x) & ((1 << 8) - 1)) << 0)
+#define F_TX_MSG_OP7_RD(x) (((x) & (((1 << 8) - 1) << 0)) >> 0)
+
+/* register TX_MSG_OP8 */
+#define TX_MSG_OP8 9
+#define F_TX_MSG_OP8(x) (((x) & ((1 << 8) - 1)) << 0)
+#define F_TX_MSG_OP8_RD(x) (((x) & (((1 << 8) - 1) << 0)) >> 0)
+
+/* register TX_MSG_OP9 */
+#define TX_MSG_OP9 10
+#define F_TX_MSG_OP9(x) (((x) & ((1 << 8) - 1)) << 0)
+#define F_TX_MSG_OP9_RD(x) (((x) & (((1 << 8) - 1) << 0)) >> 0)
+
+/* register TX_MSG_OP10 */
+#define TX_MSG_OP10 11
+#define F_TX_MSG_OP10(x) (((x) & ((1 << 8) - 1)) << 0)
+#define F_TX_MSG_OP10_RD(x) (((x) & (((1 << 8) - 1) << 0)) >> 0)
+
+/* register TX_MSG_OP11 */
+#define TX_MSG_OP11 12
+#define F_TX_MSG_OP11(x) (((x) & ((1 << 8) - 1)) << 0)
+#define F_TX_MSG_OP11_RD(x) (((x) & (((1 << 8) - 1) << 0)) >> 0)
+
+/* register TX_MSG_OP12 */
+#define TX_MSG_OP12 13
+#define F_TX_MSG_OP12(x) (((x) & ((1 << 8) - 1)) << 0)
+#define F_TX_MSG_OP12_RD(x) (((x) & (((1 << 8) - 1) << 0)) >> 0)
+
+/* register TX_MSG_OP13 */
+#define TX_MSG_OP13 14
+#define F_TX_MSG_OP13(x) (((x) & ((1 << 8) - 1)) << 0)
+#define F_TX_MSG_OP13_RD(x) (((x) & (((1 << 8) - 1) << 0)) >> 0)
+
+/* register TX_MSG_OP14 */
+#define TX_MSG_OP14 15
+#define F_TX_MSG_OP14(x) (((x) & ((1 << 8) - 1)) << 0)
+#define F_TX_MSG_OP14_RD(x) (((x) & (((1 << 8) - 1) << 0)) >> 0)
+
+/* register TX_MSG_LENGTH */
+#define TX_MSG_LENGTH 16
+#define F_TX_MSG_LENGTH(x) (((x) & ((1 << 4) - 1)) << 0)
+#define F_TX_MSG_LENGTH_RD(x) (((x) & (((1 << 4) - 1) << 0)) >> 0)
+
+/* register TX_MSG_CMD */
+#define TX_MSG_CMD 17
+#define F_TX_MSG_CMD(x) (((x) & ((1 << 2) - 1)) << 0)
+#define F_TX_MSG_CMD_RD(x) (((x) & (((1 << 2) - 1) << 0)) >> 0)
+
+/* register TX_WRITE_BUF */
+#define TX_WRITE_BUF 18
+#define F_TX_WRITE_BUF(x) (((x) & ((1 << 1) - 1)) << 0)
+#define F_TX_WRITE_BUF_RD(x) (((x) & (((1 << 1) - 1) << 0)) >> 0)
+
+/* register TX_CLEAR_BUF */
+#define TX_CLEAR_BUF 19
+#define F_TX_CLEAR_BUF(x) (((x) & ((1 << 1) - 1)) << 0)
+#define F_TX_CLEAR_BUF_RD(x) (((x) & (((1 << 1) - 1) << 0)) >> 0)
+
+/* register RX_MSG_CMD */
+#define RX_MSG_CMD 20
+#define F_RX_MSG_CMD(x) (((x) & ((1 << 2) - 1)) << 0)
+#define F_RX_MSG_CMD_RD(x) (((x) & (((1 << 2) - 1) << 0)) >> 0)
+
+/* register RX_CLEAR_BUF */
+#define RX_CLEAR_BUF 21
+#define F_RX_CLEAR_BUF(x) (((x) & ((1 << 1) - 1)) << 0)
+#define F_RX_CLEAR_BUF_RD(x) (((x) & (((1 << 1) - 1) << 0)) >> 0)
+
+/* register LOGICAL_ADDRESS_LA0 */
+#define LOGICAL_ADDRESS_LA0 22
+#define F_MY_LOG_ADDR0(x) (((x) & ((1 << 4) - 1)) << 0)
+#define F_MY_LOG_ADDR0_RD(x) (((x) & (((1 << 4) - 1) << 0)) >> 0)
+#define F_LOG_ADDR_VALID0(x) (((x) & ((1 << 1) - 1)) << 4)
+#define F_LOG_ADDR_VALID0_RD(x) (((x) & (((1 << 1) - 1) << 4)) >> 4)
+
+/* register LOGICAL_ADDRESS_LA1 */
+#define LOGICAL_ADDRESS_LA1 23
+#define F_MY_LOG_ADDR1(x) (((x) & ((1 << 4) - 1)) << 0)
+#define F_MY_LOG_ADDR1_RD(x) (((x) & (((1 << 4) - 1) << 0)) >> 0)
+#define F_LOG_ADDR_VALID1(x) (((x) & ((1 << 1) - 1)) << 4)
+#define F_LOG_ADDR_VALID1_RD(x) (((x) & (((1 << 1) - 1) << 4)) >> 4)
+
+/* register LOGICAL_ADDRESS_LA2 */
+#define LOGICAL_ADDRESS_LA2 24
+#define F_MY_LOG_ADDR2(x) (((x) & ((1 << 4) - 1)) << 0)
+#define F_MY_LOG_ADDR2_RD(x) (((x) & (((1 << 4) - 1) << 0)) >> 0)
+#define F_LOG_ADDR_VALID2(x) (((x) & ((1 << 1) - 1)) << 4)
+#define F_LOG_ADDR_VALID2_RD(x) (((x) & (((1 << 1) - 1) << 4)) >> 4)
+
+/* register LOGICAL_ADDRESS_LA3 */
+#define LOGICAL_ADDRESS_LA3 25
+#define F_MY_LOG_ADDR3(x) (((x) & ((1 << 4) - 1)) << 0)
+#define F_MY_LOG_ADDR3_RD(x) (((x) & (((1 << 4) - 1) << 0)) >> 0)
+#define F_LOG_ADDR_VALID3(x) (((x) & ((1 << 1) - 1)) << 4)
+#define F_LOG_ADDR_VALID3_RD(x) (((x) & (((1 << 1) - 1) << 4)) >> 4)
+
+/* register LOGICAL_ADDRESS_LA4 */
+#define LOGICAL_ADDRESS_LA4 26
+#define F_MY_LOG_ADDR4(x) (((x) & ((1 << 4) - 1)) << 0)
+#define F_MY_LOG_ADDR4_RD(x) (((x) & (((1 << 4) - 1) << 0)) >> 0)
+#define F_LOG_ADDR_VALID4(x) (((x) & ((1 << 1) - 1)) << 4)
+#define F_LOG_ADDR_VALID4_RD(x) (((x) & (((1 << 1) - 1) << 4)) >> 4)
+
+/* register CLK_DIV_MSB */
+#define CLK_DIV_MSB 27
+#define F_CLK_DIV_MSB(x) (((x) & ((1 << 8) - 1)) << 0)
+#define F_CLK_DIV_MSB_RD(x) (((x) & (((1 << 8) - 1) << 0)) >> 0)
+
+/* register CLK_DIV_LSB */
+#define CLK_DIV_LSB 28
+#define F_CLK_DIV_LSB(x) (((x) & ((1 << 8) - 1)) << 0)
+#define F_CLK_DIV_LSB_RD(x) (((x) & (((1 << 8) - 1) << 0)) >> 0)
+
+/* register CDC_MSG */
+#define CDC_MSG 31
+#define F_CDC_MSG(x) (((x) & ((1 << 1) - 1)) << 0)
+#define F_CDC_MSG_RD(x) (((x) & (((1 << 1) - 1) << 0)) >> 0)
+
+/* register RX_MSG_DATA1 */
+#define RX_MSG_DATA1 64
+#define F_RX_FOLLOWER_ADDRESS(x) (((x) & ((1 << 4) - 1)) << 0)
+#define F_RX_FOLLOWER_ADDRESS_RD(x) (((x) & (((1 << 4) - 1) << 0)) >> 0)
+#define F_RX_INITIATOR_ADDRESS(x) (((x) & ((1 << 4) - 1)) << 4)
+#define F_RX_INITIATOR_ADDRESS_RD(x) (((x) & (((1 << 4) - 1) << 4)) >> 4)
+
+/* register RX_MSG_DATA2 */
+#define RX_MSG_DATA2 65
+#define F_RX_MSG_OPCODE(x) (((x) & ((1 << 8) - 1)) << 0)
+#define F_RX_MSG_OPCODE_RD(x) (((x) & (((1 << 8) - 1) << 0)) >> 0)
+
+/* register RX_MSG_DATA3 */
+#define RX_MSG_DATA3 66
+#define F_RX_MSG_OP1(x) (((x) & ((1 << 8) - 1)) << 0)
+#define F_RX_MSG_OP1_RD(x) (((x) & (((1 << 8) - 1) << 0)) >> 0)
+
+/* register RX_MSG_DATA4 */
+#define RX_MSG_DATA4 67
+#define F_RX_MSG_OP2(x) (((x) & ((1 << 8) - 1)) << 0)
+#define F_RX_MSG_OP2_RD(x) (((x) & (((1 << 8) - 1) << 0)) >> 0)
+
+/* register RX_MSG_DATA5 */
+#define RX_MSG_DATA5 68
+#define F_RX_MSG_OP3(x) (((x) & ((1 << 8) - 1)) << 0)
+#define F_RX_MSG_OP3_RD(x) (((x) & (((1 << 8) - 1) << 0)) >> 0)
+
+/* register RX_MSG_DATA6 */
+#define RX_MSG_DATA6 69
+#define F_RX_MSG_OP4(x) (((x) & ((1 << 8) - 1)) << 0)
+#define F_RX_MSG_OP4_RD(x) (((x) & (((1 << 8) - 1) << 0)) >> 0)
+
+/* register RX_MSG_DATA7 */
+#define RX_MSG_DATA7 70
+#define F_RX_MSG_OP5(x) (((x) & ((1 << 8) - 1)) << 0)
+#define F_RX_MSG_OP5_RD(x) (((x) & (((1 << 8) - 1) << 0)) >> 0)
+
+/* register RX_MSG_DATA8 */
+#define RX_MSG_DATA8 71
+#define F_RX_MSG_OP6(x) (((x) & ((1 << 8) - 1)) << 0)
+#define F_RX_MSG_OP6_RD(x) (((x) & (((1 << 8) - 1) << 0)) >> 0)
+
+/* register RX_MSG_DATA9 */
+#define RX_MSG_DATA9 72
+#define F_RX_MSG_OP7(x) (((x) & ((1 << 8) - 1)) << 0)
+#define F_RX_MSG_OP7_RD(x) (((x) & (((1 << 8) - 1) << 0)) >> 0)
+
+/* register RX_MSG_DATA10 */
+#define RX_MSG_DATA10 73
+#define F_RX_MSG_OP8(x) (((x) & ((1 << 8) - 1)) << 0)
+#define F_RX_MSG_OP8_RD(x) (((x) & (((1 << 8) - 1) << 0)) >> 0)
+
+/* register RX_MSG_DATA11 */
+#define RX_MSG_DATA11 74
+#define F_RX_MSG_OP9(x) (((x) & ((1 << 8) - 1)) << 0)
+#define F_RX_MSG_OP9_RD(x) (((x) & (((1 << 8) - 1) << 0)) >> 0)
+
+/* register RX_MSG_DATA12 */
+#define RX_MSG_DATA12 75
+#define F_RX_MSG_OP10(x) (((x) & ((1 << 8) - 1)) << 0)
+#define F_RX_MSG_OP10_RD(x) (((x) & (((1 << 8) - 1) << 0)) >> 0)
+
+/* register RX_MSG_DATA13 */
+#define RX_MSG_DATA13 76
+#define F_RX_MSG_OP11(x) (((x) & ((1 << 8) - 1)) << 0)
+#define F_RX_MSG_OP11_RD(x) (((x) & (((1 << 8) - 1) << 0)) >> 0)
+
+/* register RX_MSG_DATA14 */
+#define RX_MSG_DATA14 77
+#define F_RX_MSG_OP12(x) (((x) & ((1 << 8) - 1)) << 0)
+#define F_RX_MSG_OP12_RD(x) (((x) & (((1 << 8) - 1) << 0)) >> 0)
+
+/* register RX_MSG_DATA15 */
+#define RX_MSG_DATA15 78
+#define F_RX_MSG_OP13(x) (((x) & ((1 << 8) - 1)) << 0)
+#define F_RX_MSG_OP13_RD(x) (((x) & (((1 << 8) - 1) << 0)) >> 0)
+
+/* register RX_MSG_DATA16 */
+#define RX_MSG_DATA16 79
+#define F_RX_MSG_OP14(x) (((x) & ((1 << 8) - 1)) << 0)
+#define F_RX_MSG_OP14_RD(x) (((x) & (((1 << 8) - 1) << 0)) >> 0)
+
+/* register RX_MSG_LENGTH */
+#define RX_MSG_LENGTH 80
+#define F_RX_MSG_LENGTH(x) (((x) & ((1 << 4) - 1)) << 0)
+#define F_RX_MSG_LENGTH_RD(x) (((x) & (((1 << 4) - 1) << 0)) >> 0)
+
+/* register RX_MSG_STATUS */
+#define RX_MSG_STATUS 81
+#define F_RX_MSG_STATUS(x) (((x) & ((1 << 2) - 1)) << 0)
+#define F_RX_MSG_STATUS_RD(x) (((x) & (((1 << 2) - 1) << 0)) >> 0)
+
+/* register NUM_OF_MSG_RX_BUF */
+#define NUM_OF_MSG_RX_BUF 82
+#define F_RX_NUM_MSG(x) (((x) & ((1 << 4) - 1)) << 0)
+#define F_RX_NUM_MSG_RD(x) (((x) & (((1 << 4) - 1) << 0)) >> 0)
+
+/* register TX_MSG_STATUS */
+#define TX_MSG_STATUS 83
+#define F_TX_MSG_STATUS(x) (((x) & ((1 << 2) - 1)) << 0)
+#define F_TX_MSG_STATUS_RD(x) (((x) & (((1 << 2) - 1) << 0)) >> 0)
+
+/* register DB_L_TIMER */
+#define DB_L_TIMER 96
+
+/* register DB_M_TIMER */
+#define DB_M_TIMER 97
+
+/* register DB_H_TIMER */
+#define DB_H_TIMER 98
+
+#define RX_OP_TIMEOUT 10000
+#define TX_OP_TIMEOUT 10000
+
+/**
+ * CEC Transceiver operation.
+ */
+enum {
+ CEC_TX_STOP,
+ CEC_TX_TRANSMIT,
+ CEC_TX_ABORT,
+ CEC_TX_ABORT_AND_TRANSMIT
+};
+
+/**
+ * CEC Transceiver status.
+ */
+enum {
+ CEC_STS_IDLE,
+ CEC_STS_BUSY,
+ CEC_STS_SUCCESS,
+ CEC_STS_ERROR
+};
+
+/**
+ * CEC Receiver operation.
+ */
+enum {
+ CEC_RX_STOP,
+ CEC_RX_READ,
+ CEC_RX_DISABLE,
+ CEC_RX_ABORT_AND_CLR_FIFO
+};
+
+struct imx_cec_dev {
+ struct cec_adapter *adap;
+ struct device *dev;
+ struct mutex lock;
+
+ struct cec_msg msg;
+ u32 clk_div;
+ struct task_struct *cec_worker;
+
+ /* inited by HDP controller driver */
+ struct hdp_mem *mem;
+ struct hdp_rw_func *rw;
+};
+
+int imx_cec_register(struct imx_cec_dev *cec);
+int imx_cec_unregister(struct imx_cec_dev *cec);
+
+#endif
diff --git a/drivers/mxc/hdp/API_AFE.c b/drivers/mxc/hdp/API_AFE.c
new file mode 100644
index 000000000000..060a6a495710
--- /dev/null
+++ b/drivers/mxc/hdp/API_AFE.c
@@ -0,0 +1,188 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2016-2017 Cadence Design Systems, Inc.
+ * All rights reserved worldwide.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 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.
+ *
+ * Copyright 2017-2018 NXP
+ *
+ ******************************************************************************
+ *
+ * API_AFE.c
+ *
+ ******************************************************************************
+ */
+
+#include "address.h"
+#include "API_AFE.h"
+#include "API_General.h"
+
+void Afe_write(state_struct *state, u32 offset, u16 val)
+{
+ CDN_API_STATUS sts;
+
+ sts =
+ CDN_API_General_Write_Register_blocking(state,
+ ADDR_AFE + (offset << 2),
+ val);
+
+ if (sts != CDN_OK) {
+ pr_err
+ ("CDN_API_General_Write_Register_blocking(0x%.8X, 0x%.8X) returned %d\n",
+ offset, val, (int)sts);
+ }
+}
+
+u16 Afe_read(state_struct *state, u32 offset)
+{
+ GENERAL_Read_Register_response resp;
+ CDN_API_STATUS sts;
+
+ sts =
+ CDN_API_General_Read_Register_blocking(state,
+ ADDR_AFE + (offset << 2),
+ &resp);
+
+ if (sts != CDN_OK) {
+ pr_err
+ ("CDN_API_General_Read_Register_blocking(0x%.8X) returned %d\n",
+ offset, (int)sts);
+ }
+ return resp.val;
+}
+
+void set_field_value(reg_field_t *reg_field, u32 value)
+{
+ u8 length;
+ u32 max_value;
+ u32 trunc_val;
+ length = (reg_field->msb - reg_field->lsb + 1);
+
+ max_value = (1 << length) - 1;
+ if (value > max_value) {
+ trunc_val = value;
+ trunc_val &= (1 << length) - 1;
+ pr_err("set_field_value() Error! Specified value (0x%0X)\
+ exceeds field capacity - it will by truncated to\
+ 0x%0X (%0d-bit field - max value: %0d dec)\n",
+ value, trunc_val, length, max_value);
+ } else
+ reg_field->value = value;
+}
+
+int set_reg_value(reg_field_t reg_field)
+{
+ return reg_field.value << reg_field.lsb;
+}
+
+int inside(u32 value, u32 left_sharp_corner, u32 right_sharp_corner)
+{
+ if (value < left_sharp_corner)
+ return 0;
+ if (value > right_sharp_corner)
+ return 0;
+ return 1;
+}
+
+int get_table_row_match_column(
+ const u32 *array,
+ u32 table_rows,
+ u32 table_cols,
+ u32 start_row,
+ u32 column_to_search,
+ u32 value_to_search_in_column)
+{
+ u32 idx_cols, idx_rows;
+ u32 value;
+
+ for (idx_rows = start_row; idx_rows < table_rows; idx_rows++) {
+ for (idx_cols = 0; idx_cols < table_cols; idx_cols++) {
+ if (idx_cols == column_to_search) {
+ value = *((array + idx_rows * table_cols) +
+ idx_cols);
+ if (value == value_to_search_in_column) {
+ return idx_rows;
+ }
+ }
+ }
+ }
+ return -1;
+}
+
+int get_table_row(
+ const u32 *array,
+ u32 table_rows,
+ u32 table_cols,
+ u32 variable_in_range,
+ u32 range_min_column,
+ u32 range_max_column,
+ u32 column_to_search,
+ u32 column_value)
+{
+ u32 i = 0;
+ while (1) {
+ i = get_table_row_match_column(array, table_rows, table_cols, i,
+ column_to_search, column_value);
+ if (i + 1) {
+ if (inside(variable_in_range,
+ *((array + i * table_cols) +
+ range_min_column),
+ *((array + i * table_cols) +
+ range_max_column))) {
+ break;
+ }
+ i++;
+ } else {
+ break;
+ }
+ }
+ return i;
+}
+
+u8 AFE_check_rate_supported(ENUM_AFE_LINK_RATE rate)
+{
+ switch (rate) {
+ case AFE_LINK_RATE_1_6:
+ case AFE_LINK_RATE_2_1:
+ case AFE_LINK_RATE_2_4:
+ case AFE_LINK_RATE_2_7:
+ case AFE_LINK_RATE_3_2:
+ case AFE_LINK_RATE_4_3:
+ case AFE_LINK_RATE_5_4:
+ return 1;
+ default:
+ return 0;
+ }
+}
+
diff --git a/drivers/mxc/hdp/API_AFE.h b/drivers/mxc/hdp/API_AFE.h
new file mode 100644
index 000000000000..37ddaa4ff568
--- /dev/null
+++ b/drivers/mxc/hdp/API_AFE.h
@@ -0,0 +1,111 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2016-2017 Cadence Design Systems, Inc.
+ * All rights reserved worldwide.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 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.
+ *
+ * Copyright 2017-2018 NXP
+ *
+ ******************************************************************************
+ *
+ * API_AFE.h
+ *
+ ******************************************************************************
+ */
+
+#ifndef API_AFE_H_
+#define API_AFE_H_
+
+#include "util.h"
+
+typedef enum {
+ AFE_LINK_RATE_1_6 = 0x6, /* 1.62 Gb/s */
+ AFE_LINK_RATE_2_1 = 0x8, /* 2.16 Gb/s */
+ AFE_LINK_RATE_2_4 = 0x9, /* 2.43 Gb/s */
+ AFE_LINK_RATE_2_7 = 0xA, /* 2.70 Gb/s */
+ AFE_LINK_RATE_3_2 = 0xC, /* 3.24 Gb/s */
+ AFE_LINK_RATE_4_3 = 0x10, /* 4.32 Gb/s */
+ AFE_LINK_RATE_5_4 = 0x14, /* 5.40 Gb/s */
+ AFE_LINK_RATE_8_1 = 0x1E, /* 8.10 Gb/s */
+} ENUM_AFE_LINK_RATE;
+
+/* Some of the PHY programming sequences
+ * depend on the reference clock frequency.
+ * Variable of this type is used to control
+ * the programming flow. */
+typedef enum {
+ REFCLK_24MHZ,
+ REFCLK_27MHZ
+} REFCLK_FREQ;
+
+typedef enum {
+ CLK_RATIO_1_1,
+ CLK_RATIO_5_4,
+ CLK_RATIO_3_2,
+ CLK_RATIO_2_1,
+ CLK_RATIO_1_2,
+ CLK_RATIO_5_8,
+ CLK_RATIO_3_4
+} clk_ratio_t;
+
+typedef struct {
+ u32 value;
+ u8 lsb;
+ u8 msb;
+ u8 *label;
+} reg_field_t;
+
+u8 AFE_check_rate_supported(ENUM_AFE_LINK_RATE rate);
+void Afe_write(state_struct *state, u32 offset, u16 val);
+u16 Afe_read(state_struct *state, u32 offset);
+void AFE_init(state_struct *state, int num_lanes,
+ ENUM_AFE_LINK_RATE link_rate);
+void afe_init_t28hpc(state_struct *state, int num_lanes,
+ ENUM_AFE_LINK_RATE link_rate);
+void AFE_power(state_struct *state, int num_lanes,
+ ENUM_AFE_LINK_RATE link_rate);
+void afe_power_t28hpc(state_struct *state, int num_lanes,
+ ENUM_AFE_LINK_RATE link_rate);
+void set_field_value(reg_field_t *reg_field, u32 value);
+int set_reg_value(reg_field_t reg_field);
+int inside(u32 value, u32 left_sharp_corner, u32 right_sharp_corner);
+int get_table_row_match_column(const u32 *array, u32 table_rows,
+ u32 table_cols, u32 start_row,
+ u32 column_to_search,
+ u32 value_to_search_in_column);
+int get_table_row(const u32 *array, u32 table_rows,
+ u32 table_cols, u32 variable_in_range,
+ u32 range_min_column, u32 range_max_column,
+ u32 column_to_search, u32 column_value);
+#endif
diff --git a/drivers/mxc/hdp/API_Audio.c b/drivers/mxc/hdp/API_Audio.c
new file mode 100644
index 000000000000..f70da60b9861
--- /dev/null
+++ b/drivers/mxc/hdp/API_Audio.c
@@ -0,0 +1,432 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2016-2017 Cadence Design Systems, Inc.
+ * All rights reserved worldwide.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 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.
+ *
+ * Copyright 2017 NXP
+ *
+ ******************************************************************************
+ *
+ * API_Audio.c
+ *
+ ******************************************************************************
+ */
+#include "address.h"
+#include "aif_pckt2smp.h"
+#include "API_Audio.h"
+#include "API_DPTX.h"
+#include "API_General.h"
+#include "clock_meters.h"
+#include "dptx_stream.h"
+#include "dptx_framer.h"
+#include "source_aif_decoder.h"
+#include "source_aif_smpl2pckt.h"
+#include "source_car.h"
+#include "util.h"
+
+CDN_API_STATUS CDN_API_AudioMute(state_struct *state, AUDIO_MUTE_MODE mode)
+{
+ return (CDN_API_General_Write_Field
+ (state, ADDR_DPTX_STREAM + (DP_VB_ID << 2), 4, 1,
+ (1 - mode) << 4));
+}
+
+CDN_API_STATUS CDN_API_AudioMute_blocking(state_struct *state,
+ AUDIO_MUTE_MODE mode)
+{
+ internal_block_function(&state->mutex, CDN_API_AudioMute(state, mode));
+}
+
+CDN_API_STATUS CDN_API_AudioMode(state_struct *state, AUDIO_MODE mode)
+{
+ return (CDN_API_General_Write_Register
+ (state, ADDR_DPTX_FRAMER + (AUDIO_PACK_CONTROL << 2),
+ F_AUDIO_PACK_EN(mode)));
+}
+
+CDN_API_STATUS CDN_API_AudioMode_blocking(state_struct *state, AUDIO_MODE mode)
+{
+ internal_block_function(&state->mutex, CDN_API_AudioMode(state, mode));
+}
+
+CDN_API_STATUS CDN_API_AudioConfigCore(state_struct *state,
+ AUDIO_TYPE audioType, int numOfChannels,
+ AUDIO_FREQ freq, int lanes,
+ AUDIO_WIDTH width)
+{
+ int i;
+ int lanesParam;
+ u32 I2S_DEC_PORT_EN_Val;
+
+ if (numOfChannels == 2) {
+ if (lanes == 1)
+ lanesParam = 1;
+ else
+ lanesParam = 3;
+ } else
+ lanesParam = 0;
+
+ if (audioType == AUDIO_TYPE_I2S) {
+ cdn_apb_write(state,
+ ADDR_SOURCE_AIF_DECODER + (AUDIO_SRC_CNFG << 2),
+ 0x20000);
+ cdn_apb_write(state,
+ ADDR_SOURCE_AIF_SMPL2PCKT + (FIFO_CNTL << 2), 2);
+ cdn_apb_write(state,
+ ADDR_SOURCE_AIF_SMPL2PCKT + (SMPL2PKT_CNFG << 2),
+ F_MAX_NUM_CH(numOfChannels - 1) |
+ F_NUM_OF_I2S_PORTS_S((numOfChannels / 2) - 1) |
+ (1 << 8) | (lanesParam << 11));
+
+ if (numOfChannels == 2)
+ I2S_DEC_PORT_EN_Val = 1;
+ else if (numOfChannels == 4)
+ I2S_DEC_PORT_EN_Val = 3;
+ else
+ I2S_DEC_PORT_EN_Val = 0xF;
+
+ /* 24 bit configuration + number of channels according to config */
+ cdn_apb_write(state,
+ ADDR_SOURCE_AIF_DECODER + (AUDIO_SRC_CNFG << 2),
+ 0x01000 | F_AUDIO_SAMPLE_WIDTH(width) |
+ F_AUDIO_CH_NUM(numOfChannels - 1) |
+ F_I2S_DEC_PORT_EN(I2S_DEC_PORT_EN_Val));
+
+ for (i = 0; i < (numOfChannels + 1) / 2; i++) {
+ cdn_apb_write(state, ADDR_SOURCE_AIF_DECODER +
+ ((STTS_BIT_CH01 + i) << 2),
+ F_WORD_LENGTH_CH0(0x2) |
+ F_WORD_LENGTH_CH1(0x2) |
+ F_CHANNEL_NUM_CH0(i * 2) |
+ F_CHANNEL_NUM_CH1((i * 2) + 1));
+ }
+
+ /*set ch status bits */
+ switch (freq) {
+
+ case AUDIO_FREQ_32:
+ cdn_apb_write(state, ADDR_SOURCE_AIF_DECODER +
+ (COM_CH_STTS_BITS << 2),
+ 4 | F_SAMPLING_FREQ(0x3) |
+ F_ORIGINAL_SAMP_FREQ(0xC));
+ break;
+ case AUDIO_FREQ_192:
+ cdn_apb_write(state, ADDR_SOURCE_AIF_DECODER +
+ (COM_CH_STTS_BITS << 2),
+ 4 | F_SAMPLING_FREQ(0xE) |
+ F_ORIGINAL_SAMP_FREQ(0x1));
+ break;
+
+ case AUDIO_FREQ_48:
+ cdn_apb_write(state, ADDR_SOURCE_AIF_DECODER +
+ (COM_CH_STTS_BITS << 2),
+ 4 | F_SAMPLING_FREQ(0x2) |
+ F_ORIGINAL_SAMP_FREQ(0xD));
+ break;
+ case AUDIO_FREQ_96:
+ cdn_apb_write(state, ADDR_SOURCE_AIF_DECODER +
+ (COM_CH_STTS_BITS << 2),
+ 4 | F_SAMPLING_FREQ(0xA) |
+ F_ORIGINAL_SAMP_FREQ(0x5));
+ break;
+ case AUDIO_FREQ_44_1:
+ cdn_apb_write(state, ADDR_SOURCE_AIF_DECODER +
+ (COM_CH_STTS_BITS << 2),
+ 4 | F_SAMPLING_FREQ(0x0) |
+ F_ORIGINAL_SAMP_FREQ(0xF));
+ break;
+ case AUDIO_FREQ_88_2:
+ cdn_apb_write(state, ADDR_SOURCE_AIF_DECODER +
+ (COM_CH_STTS_BITS << 2),
+ 4 | F_SAMPLING_FREQ(0x8) |
+ F_ORIGINAL_SAMP_FREQ(0x7));
+ break;
+ case AUDIO_FREQ_176_4:
+ cdn_apb_write(state, ADDR_SOURCE_AIF_DECODER +
+ (COM_CH_STTS_BITS << 2),
+ 4 | F_SAMPLING_FREQ(0xC) |
+ F_ORIGINAL_SAMP_FREQ(0x3));
+ break;
+ }
+
+ /* Enable I2S encoder */
+ cdn_apb_write(state,
+ ADDR_SOURCE_AIF_DECODER + (AUDIO_SRC_CNTL << 2), 2);
+ /* Enable smpl2pkt */
+ cdn_apb_write(state,
+ ADDR_SOURCE_AIF_SMPL2PCKT + (SMPL2PKT_CNTL << 2), 2);
+ } else {
+
+ /* set spidif 2c en */
+ cdn_apb_write(state,
+ ADDR_SOURCE_AIF_DECODER + (SPDIF_CTRL_ADDR << 2),
+ 0x1F0707);
+ cdn_apb_write(state,
+ ADDR_SOURCE_AIF_SMPL2PCKT + (FIFO_CNTL << 2), 2);
+ cdn_apb_write(state,
+ ADDR_SOURCE_AIF_SMPL2PCKT + (SMPL2PKT_CNFG << 2),
+ 0x101 | (lanesParam << 11));
+ cdn_apb_write(state,
+ ADDR_SOURCE_AIF_SMPL2PCKT + (SMPL2PKT_CNTL << 2), 2);
+ cdn_apb_write(state,
+ ADDR_SOURCE_AIF_DECODER + (SPDIF_CTRL_ADDR << 2),
+ 0x3F0707);
+ }
+ return CDN_OK;
+}
+
+CDN_API_STATUS CDN_API_AudioConfigCore_blocking(state_struct *state,
+ AUDIO_TYPE audioType,
+ int numOfChannels,
+ AUDIO_FREQ freq, int lanes,
+ AUDIO_WIDTH width)
+{
+ internal_block_function(&state->mutex, CDN_API_AudioConfigCore
+ (state, audioType, numOfChannels, freq, lanes,
+ width));
+}
+
+CDN_API_STATUS CDN_API_AudioAutoConfig(state_struct *state,
+ AUDIO_TYPE audioType, int numOfChannels,
+ AUDIO_FREQ freq, int lanes,
+ AUDIO_WIDTH width,
+ CDN_PROTOCOL_TYPE protocol, int ncts,
+ AUDIO_MUTE_MODE mode)
+{
+
+ CDN_API_STATUS ret = CDN_BSY;
+ u32 REF_CYC_Val;
+
+ switch (state->tmp) {
+ case 0:
+ if (protocol == CDN_DPTX) {
+ ret =
+ CDN_API_General_Write_Register(state,
+ ADDR_DPTX_FRAMER +
+ (AUDIO_PACK_STATUS <<
+ 2), 0x11 << 16);
+ } else {
+ ret = CDN_OK;
+ }
+ break;
+
+ case 1:
+ if (protocol == CDN_DPTX) {
+ REF_CYC_Val = 0x8000;
+ ret =
+ CDN_API_General_Write_Register(state,
+ ADDR_CLOCK_METERS +
+ (CM_LANE_CTRL << 2),
+ REF_CYC_Val);
+ } else {
+ /* hdmi mode */
+ ret =
+ CDN_API_General_Write_Register(state,
+ ADDR_CLOCK_METERS +
+ (CM_CTRL << 2), 8);
+
+ }
+ break;
+ case 2:
+ if ((protocol == CDN_HDMITX_TYPHOON)
+ || (protocol == CDN_HDMITX_KIRAN)) {
+ ret =
+ CDN_API_General_Write_Register(state,
+ ADDR_CLOCK_METERS +
+ (CM_I2S_CTRL << 2),
+ ncts | 0x4000000);
+ } else {
+ ret = CDN_OK;
+ }
+
+ break;
+
+ case 3:
+ if ((protocol == CDN_HDMITX_TYPHOON)
+ || (protocol == CDN_HDMITX_KIRAN)) {
+ ret = CDN_OK;
+ } else {
+ /* in dptx set audio on in dp framer */
+ ret = CDN_API_AudioMode(state, 1);
+ }
+ break;
+
+ case 4:
+ /* set car audio on _not reset */
+ if (protocol == CDN_DPTX) {
+ /* TODO DK: try to merge case 3 and 4 */
+ ret = CDN_OK;
+ } else {
+ ret = CDN_OK;
+ }
+ break;
+
+ case 5:
+ if ((protocol == CDN_DPTX) && (audioType != AUDIO_TYPE_I2S)) {
+ ret =
+ CDN_API_General_Write_Register(state,
+ ADDR_SOURCE_CAR +
+ (SOURCE_AIF_CAR <<
+ 2), 0xff);
+ } else {
+ ret = CDN_OK;
+ }
+ break;
+ case 6:
+ if (protocol == CDN_DPTX) {
+ ret =
+ CDN_API_General_Write_Register(state,
+ ADDR_CLOCK_METERS +
+ (CM_CTRL << 2), 0);
+ } else {
+ ret = CDN_OK;
+ }
+ break;
+
+ case 7:
+ ret =
+ CDN_API_AudioConfigCore(state, audioType, numOfChannels,
+ freq, lanes, width);
+ break;
+ }
+ if (!state->tmp && ret == CDN_STARTED)
+ return CDN_STARTED;
+ switch (ret) {
+ case CDN_OK:
+ state->tmp++;
+ break;
+ case CDN_STARTED:
+ return CDN_BSY;
+ break;
+ default:
+ return ret;
+ }
+ if (state->tmp == 8) {
+ state->tmp = 0;
+ return CDN_OK;
+ }
+ return CDN_BSY;
+
+}
+
+CDN_API_STATUS CDN_API_AudioAutoConfig_blocking(state_struct *state,
+ AUDIO_TYPE audioType,
+ int numOfChannels,
+ AUDIO_FREQ freq, int lanes,
+ AUDIO_WIDTH width,
+ CDN_PROTOCOL_TYPE protocol,
+ int ncts, AUDIO_MUTE_MODE mode)
+{
+ internal_block_function(&state->mutex, CDN_API_AudioAutoConfig
+ (state, audioType, numOfChannels, freq, lanes,
+ width, protocol, ncts, mode));
+}
+
+CDN_API_STATUS CDN_API_AudioOff(state_struct *state, AUDIO_TYPE audioType)
+{
+ CDN_API_STATUS ret = CDN_BSY;
+
+ switch (state->tmp) {
+ case 0:
+ cdn_apb_write(state,
+ ADDR_SOURCE_AIF_DECODER + (SPDIF_CTRL_ADDR << 2),
+ 0x1F0707);
+ cdn_apb_write(state,
+ ADDR_SOURCE_AIF_DECODER + (AUDIO_SRC_CNTL << 2),
+ 0);
+ cdn_apb_write(state,
+ ADDR_SOURCE_AIF_DECODER + (AUDIO_SRC_CNFG << 2),
+ 0);
+ cdn_apb_write(state,
+ ADDR_SOURCE_AIF_DECODER + (AUDIO_SRC_CNTL << 2),
+ 1);
+ cdn_apb_write(state,
+ ADDR_SOURCE_AIF_DECODER + (AUDIO_SRC_CNTL << 2),
+ 0);
+ cdn_apb_write(state,
+ ADDR_SOURCE_AIF_SMPL2PCKT + (SMPL2PKT_CNTL << 2),
+ 0);
+ cdn_apb_write(state,
+ ADDR_SOURCE_AIF_SMPL2PCKT + (SMPL2PKT_CNTL << 2),
+ 1);
+ cdn_apb_write(state,
+ ADDR_SOURCE_AIF_SMPL2PCKT + (SMPL2PKT_CNTL << 2),
+ 0);
+ cdn_apb_write(state,
+ ADDR_SOURCE_AIF_SMPL2PCKT + (FIFO_CNTL << 2), 1);
+ cdn_apb_write(state,
+ ADDR_SOURCE_AIF_SMPL2PCKT + (FIFO_CNTL << 2), 0);
+ ret = CDN_OK;
+
+ break;
+ case 1:
+ ret =
+ CDN_API_General_Write_Register(state, ADDR_SOURCE_CAR +
+ (SOURCE_AIF_CAR << 2), 0x5f);
+ break;
+ case 2:
+ ret =
+ CDN_API_General_Write_Register(state, ADDR_SOURCE_CAR +
+ (SOURCE_AIF_CAR << 2), 0x0f);
+ break;
+ case 3:
+ ret = CDN_OK;
+ break;
+ }
+
+ if (!state->tmp && ret == CDN_STARTED)
+ return CDN_STARTED;
+ switch (ret) {
+ case CDN_OK:
+ state->tmp++;
+ break;
+ case CDN_STARTED:
+ return CDN_BSY;
+ break;
+ default:
+ return ret;
+ }
+ if (state->tmp == 4) {
+ state->tmp = 0;
+ return CDN_OK;
+ }
+ return CDN_BSY;
+}
+
+CDN_API_STATUS CDN_API_AudioOff_blocking(state_struct *state,
+ AUDIO_TYPE audioType)
+{
+ internal_block_function(&state->mutex, CDN_API_AudioOff(state, audioType));
+}
diff --git a/drivers/mxc/hdp/API_Audio.h b/drivers/mxc/hdp/API_Audio.h
new file mode 100644
index 000000000000..4147594d4cba
--- /dev/null
+++ b/drivers/mxc/hdp/API_Audio.h
@@ -0,0 +1,159 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2016-2017 Cadence Design Systems, Inc.
+ * All rights reserved worldwide.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 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.
+ *
+ * Copyright 2017 NXP
+ *
+ ******************************************************************************
+ *
+ * API_Audio.h
+ *
+ ******************************************************************************
+ */
+
+#ifndef API_AUDIO_H_
+#define API_AUDIO_H_
+
+#include "API_General.h"
+/**
+ * \addtogroup AUDIO_API
+ * \{
+ */
+typedef enum {
+ AUDIO_TYPE_I2S,
+ AUDIO_TYPE_SPIDIF_INTERNAL,
+ AUDIO_TYPE_SPIDIF_EXTERNAL,
+} AUDIO_TYPE;
+
+typedef enum {
+ AUDIO_FREQ_32,
+ AUDIO_FREQ_48,
+ AUDIO_FREQ_96,
+ AUDIO_FREQ_192,
+ AUDIO_FREQ_44_1,
+ AUDIO_FREQ_88_2,
+ AUDIO_FREQ_176_4,
+} AUDIO_FREQ;
+
+typedef enum {
+ AUDIO_WIDTH_16,
+ AUDIO_WIDTH_24,
+ AUDIO_WIDTH_32,
+} AUDIO_WIDTH;
+
+typedef enum {
+ AUDIO_MODE_OFF,
+ AUDIO_MODE_ON
+} AUDIO_MODE;
+
+typedef enum {
+ AUDIO_MUTE_MODE_MUTE,
+ AUDIO_MUTE_MODE_UNMUTE
+} AUDIO_MUTE_MODE;
+
+/**
+ * \brief mute or unmute audio
+ */
+CDN_API_STATUS CDN_API_AudioMute(state_struct *state, AUDIO_MUTE_MODE mode);
+
+/**
+ * \brief blocking version of #CDN_API_AudioMute
+ */
+CDN_API_STATUS CDN_API_AudioMute_blocking(state_struct *state,
+ AUDIO_MUTE_MODE mode);
+
+/**
+ * \brief start playing audio with the input parameters
+ ncts and mode are relevant only in HDMI TX mode , not relevant for DPTX mode
+ */
+CDN_API_STATUS CDN_API_AudioAutoConfig(state_struct *state,
+ AUDIO_TYPE audioType, int numOfChannels,
+ AUDIO_FREQ freq, int lanes,
+ AUDIO_WIDTH width,
+ CDN_PROTOCOL_TYPE protocol, int ncts,
+ AUDIO_MUTE_MODE mode);
+
+/**
+ * \brief blocking version of #CDN_API_AudioAutoConfig
+ */
+CDN_API_STATUS CDN_API_AudioAutoConfig_blocking(state_struct *state,
+ AUDIO_TYPE audioType,
+ int numOfChannels,
+ AUDIO_FREQ freq, int lanes,
+ AUDIO_WIDTH width,
+ CDN_PROTOCOL_TYPE protocol,
+ int ncts, AUDIO_MUTE_MODE mode);
+
+/**
+ * \brief audio off (use it to stop current audio and start new one using CDN_API_AudioAutoConfig)
+ */
+CDN_API_STATUS CDN_API_AudioOff(state_struct *state, AUDIO_TYPE audioType);
+
+/**
+ * \brief blocking version of #CDN_API_AudioOff
+ */
+CDN_API_STATUS CDN_API_AudioOff_blocking(state_struct *state,
+ AUDIO_TYPE audioType);
+
+/**
+ * \brief internal function to set audio on or off inside internal registers
+ */
+CDN_API_STATUS CDN_API_AudioMode(state_struct *state, AUDIO_MODE mode);
+
+/**
+ * \brief blocking version of #CDN_API_AudioMode
+ */
+CDN_API_STATUS CDN_API_AudioMode_blocking(state_struct *state,
+ AUDIO_MODE mode);
+
+/**
+ * \brief internal function to set audio core registers
+ */
+CDN_API_STATUS CDN_API_AudioConfigCore(state_struct *state,
+ AUDIO_TYPE audioType, int numOfChannels,
+ AUDIO_FREQ freq, int lanes,
+ AUDIO_WIDTH width);
+
+/**
+ * \brief blocking version of #CDN_API_AudioConfigCore
+ */
+CDN_API_STATUS CDN_API_AudioConfigCore_blocking(state_struct *state,
+ AUDIO_TYPE audioType,
+ int numOfChannels,
+ AUDIO_FREQ freq, int lanes,
+ AUDIO_WIDTH width);
+
+#endif
diff --git a/drivers/mxc/hdp/API_DPTX.c b/drivers/mxc/hdp/API_DPTX.c
new file mode 100644
index 000000000000..7f6bb8ce3c42
--- /dev/null
+++ b/drivers/mxc/hdp/API_DPTX.c
@@ -0,0 +1,1060 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2016-2018 Cadence Design Systems, Inc.
+ * All rights reserved worldwide.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 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.
+ *
+ * Copyright 2017-2018 NXP
+ *
+ ******************************************************************************
+ *
+ * API_DPTX.c
+ *
+ ******************************************************************************
+ */
+#include "API_DPTX.h"
+#include "util.h"
+#include "opcodes.h"
+#include "address.h"
+#include "dptx_stream.h"
+#include "dptx_framer.h"
+#include "source_vif.h"
+
+CDN_API_STATUS CDN_API_DPTX_Read_DPCD(state_struct *state, int numOfBytes,
+ int addr, DPTX_Read_DPCD_response *resp,
+ CDN_BUS_TYPE bus_type)
+{
+ CDN_API_STATUS ret;
+ if (!state->running) {
+ internal_tx_mkfullmsg(state, MB_MODULE_ID_DP_TX, DPTX_READ_DPCD,
+ 2, 2, numOfBytes, 3, addr);
+ state->bus_type = bus_type;
+ state->rxEnable = 1;
+ return CDN_STARTED;
+ }
+ internal_process_messages(state);
+ ret = internal_test_rx_head(state, MB_MODULE_ID_DP_TX,
+ DPTX_DPCD_READ_RESP);
+ if (ret != CDN_OK) {
+ state->running = 0;
+ return ret;
+ }
+ /* Clean most significant bytes in members of structure used for response. */
+ resp->size = 0;
+ resp->addr = 0;
+ internal_readmsg(state, 3,
+ 2, &resp->size, 3, &resp->addr, 0, &resp->buff);
+ state->running = 0;
+ return CDN_OK;
+}
+
+CDN_API_STATUS CDN_API_DPTX_Read_DPCD_blocking(state_struct *state,
+ int numOfBytes, int addr,
+ DPTX_Read_DPCD_response *resp,
+ CDN_BUS_TYPE bus_type)
+{
+ internal_block_function(&state->mutex, CDN_API_DPTX_Read_DPCD
+ (state, numOfBytes, addr, resp, bus_type));
+}
+
+CDN_API_STATUS CDN_API_DPTX_I2C_Read(state_struct *state,
+ u32 numOfBytes, u8 addr, u8 mot, DPTX_I2C_Read_response *resp)
+{
+ CDN_API_STATUS ret;
+ if(!state->running)
+ {
+ internal_tx_mkfullmsg(state, MB_MODULE_ID_DP_TX, DPTX_I2C_READ, 3,
+ 2, numOfBytes,
+ 1, addr,
+ 1, mot);
+ state->bus_type = CDN_BUS_TYPE_APB;
+ state->rxEnable = 1;
+ return CDN_STARTED;
+ }
+ internal_process_messages(state);
+ if((ret = internal_test_rx_head(state, MB_MODULE_ID_DP_TX, DPTX_I2C_READ_RESP)) != CDN_OK)
+ {
+ state->running = 0;
+ return ret;
+ }
+ /* Clean most significant bytes in members of structure used for response. */
+ resp->size = 0;
+ resp->addr = 0;
+ internal_readmsg(state, 3,
+ 2, &resp->size,
+ 1, &resp->addr,
+ 0, &resp->buff);
+ state->running = 0;
+ return CDN_OK;
+}
+
+CDN_API_STATUS CDN_API_DPTX_I2C_Read_blocking(state_struct *state, u32 numOfBytes, u8 addr, u8 mot, DPTX_I2C_Read_response *resp)
+{
+ internal_block_function(&state->mutex, CDN_API_DPTX_I2C_Read(state, numOfBytes, addr, mot, resp));
+}
+
+CDN_API_STATUS CDN_API_DPTX_I2C_Write(state_struct *state, u32 numOfBytes, u8 addr, u8 mot, u8 *buff, DPTX_I2C_Write_response *resp)
+{
+ CDN_API_STATUS ret;
+ if(!state->running)
+ {
+ if(!internal_apb_available(state))
+ return CDN_BSY;
+ internal_tx_mkfullmsg(state,
+ MB_MODULE_ID_DP_TX, DPTX_I2C_WRITE, 4,
+ 2, numOfBytes,
+ 1, addr,
+ 1, mot,
+ -numOfBytes, buff);
+ state->rxEnable = 1;
+ state->bus_type = CDN_BUS_TYPE_APB;
+ return CDN_STARTED;
+ }
+ internal_process_messages(state);
+ if((ret = internal_test_rx_head(state, MB_MODULE_ID_DP_TX, DPTX_I2C_WRITE_RESP)) != CDN_OK)
+ return ret;
+ internal_readmsg(state, 2,
+ 2, &resp->size,
+ 1, &resp->addr);
+ return CDN_OK;
+}
+
+CDN_API_STATUS CDN_API_DPTX_I2C_Write_blocking(state_struct *state, u32 numOfBytes, u8 addr, u8 mot, u8 *buff, DPTX_I2C_Write_response *resp)
+{
+ internal_block_function(&state->mutex, CDN_API_DPTX_I2C_Write(state, numOfBytes, addr, mot, buff, resp));
+}
+
+CDN_API_STATUS CDN_API_DPTX_Read_EDID(state_struct *state, u8 segment,
+ u8 extension,
+ DPTX_Read_EDID_response *resp)
+{
+ CDN_API_STATUS ret;
+ if (!state->running) {
+ if (!internal_apb_available(state))
+ return CDN_BSY;
+ internal_tx_mkfullmsg(state, MB_MODULE_ID_DP_TX, DPTX_GET_EDID,
+ 2, 1, segment, 1, extension);
+ state->rxEnable = 1;
+ state->bus_type = CDN_BUS_TYPE_APB;
+ return CDN_STARTED;
+ }
+ internal_process_messages(state);
+ ret = internal_test_rx_head(state, MB_MODULE_ID_DP_TX,
+ DPTX_GET_EDID);
+ if (ret != CDN_OK)
+ return ret;
+ internal_readmsg(state, 3,
+ 1, &resp->size,
+ 1, &resp->blockNo,
+ 0, &resp->buff);
+ return CDN_OK;
+}
+
+CDN_API_STATUS CDN_API_DPTX_Read_EDID_blocking(state_struct *state, u8 segment,
+ u8 extension,
+ DPTX_Read_EDID_response *resp)
+{
+ internal_block_function(&state->mutex, CDN_API_DPTX_Read_EDID
+ (state, segment, extension, resp));
+}
+
+CDN_API_STATUS CDN_API_DPTX_SetHostCap(state_struct *state, u8 maxLinkRate,
+ u8 lanesCount_SSC,
+ u8 maxVoltageSwing,
+ u8 maxPreemphasis,
+ u8 testPatternsSupported,
+ u8 fastLinkTraining,
+ u8 laneMapping, u8 enchanced)
+{
+ /* fifth bit of lanesCount_SSC is used to declare eDP. */
+ state->edp = ((lanesCount_SSC >> 5) & 1);
+ if (!state->running) {
+ if (!internal_apb_available(state))
+ return CDN_BSY;
+ internal_tx_mkfullmsg(state, MB_MODULE_ID_DP_TX,
+ DPTX_SET_HOST_CAPABILITIES, 8, 1,
+ maxLinkRate, 1, lanesCount_SSC, 1,
+ maxVoltageSwing, 1, maxPreemphasis, 1,
+ testPatternsSupported, 1,
+ fastLinkTraining, 1, laneMapping, 1,
+ enchanced);
+ state->bus_type = CDN_BUS_TYPE_APB;
+ return CDN_STARTED;
+ }
+ internal_process_messages(state);
+ return CDN_OK;
+}
+
+CDN_API_STATUS CDN_API_DPTX_SetHostCap_blocking(state_struct *state,
+ u8 maxLinkRate,
+ u8 lanesCount_SSC,
+ u8 maxVoltageSwing,
+ u8 maxPreemphasis,
+ u8 testPatternsSupported,
+ u8 fastLinkTraining,
+ u8 laneMapping, u8 enchanced)
+{
+ internal_block_function(&state->mutex, CDN_API_DPTX_SetHostCap
+ (state, maxLinkRate, lanesCount_SSC,
+ maxVoltageSwing, maxPreemphasis,
+ testPatternsSupported, fastLinkTraining,
+ laneMapping, enchanced));
+}
+
+CDN_API_STATUS CDN_API_DPTX_SetPowerMode(state_struct *state,
+ CDN_API_PWR_MODE mode)
+{
+ if (!state->running) {
+ if (!internal_apb_available(state))
+ return CDN_BSY;
+ internal_tx_mkfullmsg(state, MB_MODULE_ID_DP_TX,
+ DPTX_SET_POWER_MNG, 1, 1, mode);
+ state->bus_type = CDN_BUS_TYPE_APB;
+ return CDN_STARTED;
+ }
+ internal_process_messages(state);
+ return CDN_OK;
+}
+
+CDN_API_STATUS CDN_API_DPTX_SetPowerMode_blocking(state_struct *state,
+ CDN_API_PWR_MODE mode)
+{
+ internal_block_function(&state->mutex, CDN_API_DPTX_SetPowerMode(state, mode));
+}
+
+CDN_API_STATUS CDN_API_DPTX_Control(state_struct *state, u32 mode)
+{
+ if (!state->running) {
+ if (!internal_apb_available(state))
+ return CDN_BSY;
+ internal_tx_mkfullmsg(state, MB_MODULE_ID_DP_TX,
+ DPTX_TRAINING_CONTROL, 1, 1, mode);
+ state->bus_type = CDN_BUS_TYPE_APB;
+ return CDN_STARTED;
+ }
+ internal_process_messages(state);
+ return CDN_OK;
+}
+
+CDN_API_STATUS CDN_API_DPTX_Control_blocking(state_struct *state, u32 mode)
+{
+ internal_block_function(&state->mutex, CDN_API_DPTX_Control(state, mode));
+}
+
+CDN_API_STATUS CDN_API_DPTX_EDP_Training(state_struct *state,
+ u8 mode, ENUM_AFE_LINK_RATE linkRate,
+ u8 rateId)
+{
+ if (AFE_check_rate_supported(linkRate) == 0)
+ return CDN_ERROR_NOT_SUPPORTED;
+
+ if (!state->running) {
+ if (!internal_apb_available(state))
+ return CDN_BSY;
+ internal_tx_mkfullmsg(state, MB_MODULE_ID_DP_TX, DPTX_EDP_RATE_TRAINING, 3,
+ 1, mode,
+ 1, (u8)linkRate,
+ 1, rateId);
+ state->bus_type = CDN_BUS_TYPE_APB;
+ return CDN_STARTED;
+ }
+ internal_process_messages(state);
+ return CDN_OK;
+}
+
+CDN_API_STATUS CDN_API_DPTX_EDP_Training_blocking(state_struct *state,
+ u8 mode,
+ ENUM_AFE_LINK_RATE linkRate,
+ u8 rateId)
+{
+ internal_block_function(&state->mutex, CDN_API_DPTX_EDP_Training(state, mode, linkRate, rateId));
+}
+
+CDN_API_STATUS CDN_API_DPTX_Write_DPCD(state_struct *state, u32 numOfBytes,
+ u32 addr, u8 *buff,
+ DPTX_Write_DPCD_response *resp,
+ CDN_BUS_TYPE bus_type)
+{
+ CDN_API_STATUS ret;
+ if (!state->running) {
+ if (!internal_apb_available(state))
+ return CDN_BSY;
+ internal_tx_mkfullmsg(state, MB_MODULE_ID_DP_TX,
+ DPTX_WRITE_DPCD, 3, 2, numOfBytes, 3,
+ addr, -numOfBytes, buff);
+ state->rxEnable = 1;
+ state->bus_type = bus_type;
+ return CDN_STARTED;
+ }
+ internal_process_messages(state);
+ ret = internal_test_rx_head(state, MB_MODULE_ID_DP_TX,
+ DPTX_DPCD_WRITE_RESP);
+ if (ret != CDN_OK)
+ return ret;
+ internal_readmsg(state, 2, 2, &resp->size, 3, &resp->addr);
+ return CDN_OK;
+}
+
+CDN_API_STATUS CDN_API_DPTX_Write_DPCD_blocking(state_struct *state,
+ u32 numOfBytes, u32 addr,
+ u8 *buff,
+ DPTX_Write_DPCD_response *resp,
+ CDN_BUS_TYPE bus_type)
+{
+ internal_block_function(&state->mutex, CDN_API_DPTX_Write_DPCD
+ (state, numOfBytes, addr, buff, resp,
+ bus_type));
+}
+
+CDN_API_STATUS CDN_API_DPTX_Read_Register(state_struct *state, u8 base,
+ u8 regNo,
+ DPTX_Read_Register_response *resp)
+{
+ u16 addr = (base << 8) + (regNo << 2);
+ CDN_API_STATUS ret;
+ if (!state->running) {
+ if (!internal_apb_available(state))
+ return CDN_BSY;
+ internal_tx_mkfullmsg(state, MB_MODULE_ID_DP_TX,
+ DPTX_READ_REGISTER, 1, 2, addr);
+ state->bus_type = CDN_BUS_TYPE_APB;
+ state->rxEnable = 1;
+ return CDN_STARTED;
+ }
+ internal_process_messages(state);
+ ret = internal_test_rx_head(state, MB_MODULE_ID_DP_TX,
+ DPTX_READ_REGISTER_RESP);
+ if (ret != CDN_OK)
+ return ret;
+ internal_readmsg(state, 3,
+ 1, &resp->base, 1, &resp->regNo, 4, &resp->val);
+ resp->regNo >>= 2;
+ return CDN_OK;
+}
+
+CDN_API_STATUS CDN_API_DPTX_Read_Register_blocking(state_struct *state,
+ u8 base, u8 regNo,
+ DPTX_Read_Register_response *resp)
+{
+ internal_block_function(&state->mutex, CDN_API_DPTX_Read_Register
+ (state, base, regNo, resp));
+}
+
+CDN_API_STATUS CDN_API_DPTX_Write_Register(state_struct *state, u8 base,
+ u8 regNo, u32 val)
+{
+ u16 addr = (base << 8) + (regNo << 2);
+ if (!state->running) {
+ if (!internal_apb_available(state))
+ return CDN_BSY;
+ internal_tx_mkfullmsg(state, MB_MODULE_ID_DP_TX,
+ DPTX_WRITE_REGISTER, 2, 2, addr, 4, val);
+ state->bus_type = CDN_BUS_TYPE_APB;
+ return CDN_STARTED;
+ }
+ internal_process_messages(state);
+ return CDN_OK;
+}
+
+CDN_API_STATUS CDN_API_DPTX_Write_Register_blocking(state_struct *state,
+ u8 base, u8 regNo, u32 val)
+{
+ internal_block_function(&state->mutex, CDN_API_DPTX_Write_Register
+ (state, base, regNo, val));
+}
+
+CDN_API_STATUS CDN_API_DPTX_Write_Field(state_struct *state, u8 base, u8 regNo,
+ u8 startBit, u8 bitsNo, u32 val)
+{
+ u16 addr = (base << 8) + (regNo << 2);
+ if (!state->running) {
+ if (!internal_apb_available(state))
+ return CDN_BSY;
+ internal_tx_mkfullmsg(state, MB_MODULE_ID_DP_TX,
+ DPTX_WRITE_FIELD, 4, 2, addr, 1, startBit,
+ 1, bitsNo, 4, val);
+ state->bus_type = CDN_BUS_TYPE_APB;
+ return CDN_STARTED;
+ }
+ internal_process_messages(state);
+ return CDN_OK;
+}
+
+CDN_API_STATUS CDN_API_DPTX_Write_Field_blocking(state_struct *state, u8 base,
+ u8 regNo,
+ u8 startBit,
+ u8 bitsNo, u32 val)
+{
+ internal_block_function(&state->mutex, CDN_API_DPTX_Write_Field
+ (state, base, regNo, startBit, bitsNo, val));
+}
+
+CDN_API_STATUS CDN_API_DPTX_EnableEvent(state_struct *state, bool hpd,
+ bool training)
+{
+ uint8_t events = 0;
+
+ if (!state->running) {
+ if (!internal_apb_available(state)) {
+ return CDN_BSY;
+ }
+
+ events |= (hpd ? 1 << DP_TX_EVENT_ENABLE_HPD_BIT : 0);
+ events |= (training ? 1 << DP_TX_EVENT_ENABLE_TRAINING_BIT : 0);
+
+ internal_tx_mkfullmsg(state, MB_MODULE_ID_DP_TX, DPTX_ENABLE_EVENT, 2, 1, events, 4, 0);
+
+ state->bus_type = CDN_BUS_TYPE_APB;
+
+ return CDN_STARTED;
+ }
+
+ internal_process_messages(state);
+
+ return CDN_OK;
+}
+
+CDN_API_STATUS CDN_API_DPTX_EnableEvent_blocking(state_struct *state, bool hpd,
+ bool training)
+{
+ internal_block_function(&state->mutex, CDN_API_DPTX_EnableEvent(state, hpd, training));
+}
+
+CDN_API_STATUS CDN_API_DPTX_ReadEvent(state_struct *state, u8 *LinkeventId,
+ u8 *HPDevents)
+{
+ CDN_API_STATUS ret;
+ if (!state->running) {
+ if (!internal_apb_available(state))
+ return CDN_BSY;
+ internal_tx_mkfullmsg(state, MB_MODULE_ID_DP_TX,
+ DPTX_READ_EVENT, 0);
+ state->rxEnable = 1;
+ state->bus_type = CDN_BUS_TYPE_APB;
+ return CDN_STARTED;
+ }
+ internal_process_messages(state);
+ ret = internal_test_rx_head(state, MB_MODULE_ID_DP_TX,
+ DPTX_READ_EVENT);
+ if (ret != CDN_OK)
+ return ret;
+ internal_readmsg(state, 2, 1, HPDevents, 1, LinkeventId);
+ return CDN_OK;
+}
+
+CDN_API_STATUS CDN_API_DPTX_ReadEvent_blocking(state_struct *state,
+ u8 *LinkeventId, u8 *HPDevents)
+{
+ internal_block_function(&state->mutex, CDN_API_DPTX_ReadEvent
+ (state, LinkeventId, HPDevents));
+}
+
+CDN_API_STATUS CDN_API_DPTX_Set_VIC(state_struct *state,
+ struct drm_display_mode *mode,
+ int bitsPerPixel,
+ VIC_NUM_OF_LANES NumOfLanes,
+ VIC_SYMBOL_RATE rate,
+ VIC_PXL_ENCODING_FORMAT pxlencformat,
+ STEREO_VIDEO_ATTR steroVidAttr,
+ BT_TYPE bt_type, int TU)
+{
+ int min_link_rate;
+ int bitsPerPixelCalc;
+ int TU_SIZE_reg = 34;
+ int val, val_f, val2, val2_f;
+ u32 lineThresh;
+ u32 pixelClockFreq;
+ u32 MSA_MISC_Param, tempForMisc, tempForMisc2;
+ u32 oddEvenV_Total;
+ u32 DP_FRAMER_SP_Param;
+ u32 DP_FRONT_BACK_PORCH_Param;
+ u32 DP_BYTE_COUNT_Param;
+ u32 MSA_HORIZONTAL_0_Param;
+ u32 MSA_HORIZONTAL_1_Param;
+ u32 MSA_VERTICAL_0_Param;
+ u32 MSA_VERTICAL_1_Param;
+ u32 DP_HORIZONTAL_ADDR_Param;
+ u32 DP_VERTICAL_0_ADDR_Param;
+ u32 DP_VERTICAL_1_ADDR_Param;
+ u32 DP_FRAMER_PXL_REPR_Param;
+ u32 HSYNC2VSYNC_POL_CTRL_Param = 0;
+ u32 BND_HSYNC2VSYNC_Param = 0;
+ u32 DP_FRAMER_TU_Param;
+ u32 tu_vs_diff = 0;
+ VIC_COLOR_DEPTH colorDepth;
+ CDN_API_STATUS ret = CDN_OK;
+
+ if (pxlencformat == YCBCR_4_2_2)
+ bitsPerPixelCalc = bitsPerPixel * 2;
+ else if (pxlencformat == YCBCR_4_2_0)
+ bitsPerPixelCalc = bitsPerPixel * 3 / 2;
+ else
+ bitsPerPixelCalc = bitsPerPixel * 3;
+
+ /* KHz */
+ pixelClockFreq = mode->clock;
+
+ /* KHz */
+ min_link_rate = rate * 995;
+ rate *= 1000;
+
+ val = TU_SIZE_reg * pixelClockFreq * bitsPerPixelCalc;
+ val_f = val / (NumOfLanes * rate * 8);
+ val /= NumOfLanes * rate * 8;
+
+ val2 = TU_SIZE_reg * pixelClockFreq * bitsPerPixelCalc;
+ val2_f = val2 / (NumOfLanes * min_link_rate * 8);
+ val2 /= NumOfLanes * min_link_rate * 8;
+
+ /* find optimum value for the TU_SIZE */
+
+ while (((val == 1) || (TU_SIZE_reg - val < 2) || (val != val2)
+ || (val_f % 1000 > 850) || (val2_f % 1000 > 850)
+ || (val_f % 1000 < 100) || (val2_f % 1000 < 100))
+ && (TU_SIZE_reg < 64)) {
+ TU_SIZE_reg += 2;
+
+ val = TU_SIZE_reg * pixelClockFreq * bitsPerPixelCalc;
+ val_f = val / (NumOfLanes * rate * 8);
+ val /= NumOfLanes * rate * 8;
+
+ val2 = TU_SIZE_reg * pixelClockFreq * bitsPerPixelCalc;
+ val2_f = val2 / (NumOfLanes * min_link_rate * 8);
+ val2 /= NumOfLanes * min_link_rate * 8;
+ }
+
+ /* calculate the fixed valid symbols */
+ val = TU_SIZE_reg * pixelClockFreq * bitsPerPixelCalc;
+ val /= NumOfLanes * rate * 8;
+
+ if (val > 64) {
+ return CDN_ERROR_NOT_SUPPORTED;
+ }
+ DP_FRAMER_TU_Param = (TU_SIZE_reg << 8) + val + (1 << 15);
+
+ tu_vs_diff = 0;
+ if ((TU_SIZE_reg - val) <= 3) {
+ tu_vs_diff = TU_SIZE_reg - val;
+ }
+
+ /* LINE_THRESH set according to zeev presantation */
+ lineThresh =
+ ((val + 1) * NumOfLanes - ((pixelClockFreq / rate) * (val + 1) *
+ (bitsPerPixelCalc / 8) -
+ (bitsPerPixelCalc / 8))) /
+ ((bitsPerPixelCalc * NumOfLanes) / 8);
+ lineThresh += 2;
+
+ DP_FRAMER_SP_Param =
+ ((mode->flags & DRM_MODE_FLAG_INTERLACE) ? 4 : 0) +
+ ((mode->flags & DRM_MODE_FLAG_NHSYNC) ? 2 : 0) +
+ ((mode->flags & DRM_MODE_FLAG_NVSYNC) ? 1 : 0);
+
+ DP_FRONT_BACK_PORCH_Param =
+ mode->htotal - mode->hsync_end + ((mode->hsync_start - mode->hdisplay) << 16);
+
+ DP_BYTE_COUNT_Param = mode->hdisplay * (bitsPerPixelCalc) / 8;
+
+ MSA_HORIZONTAL_0_Param =
+ mode->htotal + ((mode->htotal - mode->hsync_start) << 16);
+
+ MSA_HORIZONTAL_1_Param =
+ mode->hsync_end - mode->hsync_start +
+ ((mode->flags & DRM_MODE_FLAG_NHSYNC ? 1 : 0) << 15) + (mode->hdisplay << 16);
+
+ MSA_VERTICAL_0_Param =
+ (mode->flags & DRM_MODE_FLAG_INTERLACE ? (mode->vtotal / 2) : mode->vtotal) +
+ ((mode->vtotal - mode->vsync_start) << 16);
+
+ MSA_VERTICAL_1_Param =
+ (mode->vsync_end - mode->vsync_start +
+ ((mode->flags & DRM_MODE_FLAG_NVSYNC ? 1 : 0) << 15)) +
+ ((mode->flags & DRM_MODE_FLAG_INTERLACE ? mode->vdisplay / 2 : mode->vdisplay) << 16);
+
+ DP_HORIZONTAL_ADDR_Param = (mode->hdisplay << 16) + mode->hsync;
+
+ DP_VERTICAL_0_ADDR_Param =
+ (mode->flags & DRM_MODE_FLAG_INTERLACE ? (mode->vtotal / 2) : mode->vtotal) -
+ (mode->vtotal - mode->vdisplay) + ((mode->vtotal - mode->vsync_start) << 16);
+
+ DP_VERTICAL_1_ADDR_Param =
+ mode->flags & DRM_MODE_FLAG_INTERLACE ? (mode->vtotal / 2) : mode->vtotal;
+
+ if (mode->flags & DRM_MODE_FLAG_INTERLACE)
+ BND_HSYNC2VSYNC_Param = 0x3020;
+ else
+ BND_HSYNC2VSYNC_Param = 0x2000;
+
+ if (mode->flags & DRM_MODE_FLAG_NHSYNC)
+ HSYNC2VSYNC_POL_CTRL_Param |= F_HPOL(1);
+
+ if (mode->flags & DRM_MODE_FLAG_NVSYNC)
+ HSYNC2VSYNC_POL_CTRL_Param |= F_VPOL(1);
+
+ switch (bitsPerPixel) {
+ case 6:
+ colorDepth = BCS_6;
+ break;
+ case 8:
+ colorDepth = BCS_8;
+ break;
+ case 10:
+ colorDepth = BCS_10;
+ break;
+ case 12:
+ colorDepth = BCS_12;
+ break;
+ case 16:
+ colorDepth = BCS_16;
+ break;
+ default:
+ colorDepth = BCS_8;
+ };
+
+ DP_FRAMER_PXL_REPR_Param = (pxlencformat << 8) + colorDepth;
+
+ switch (pxlencformat) {
+ case PXL_RGB: /*0x1 */
+ tempForMisc = 0;
+ break;
+ case YCBCR_4_4_4: /*0x2 */
+ tempForMisc = 6 + 8 * (bt_type);
+ break;
+ case YCBCR_4_2_2: /*0x4 */
+ tempForMisc = 5 + 8 * (bt_type);
+ break;
+ case YCBCR_4_2_0: /*0x8 */
+ tempForMisc = 5;
+ break;
+
+ case Y_ONLY: /*0x10 */
+ tempForMisc = 0;
+ break;
+ default:
+ tempForMisc = 0;
+ };
+
+ switch (bitsPerPixel) {
+ case 6:
+ tempForMisc2 = 0;
+ break;
+
+ case 8:
+ tempForMisc2 = 1;
+ break;
+
+ case 10:
+ tempForMisc2 = 2;
+ break;
+
+ case 12:
+ tempForMisc2 = 3;
+ break;
+
+ case 16:
+ tempForMisc2 = 4;
+ break;
+ default:
+ tempForMisc2 = 1;
+
+ };
+
+ oddEvenV_Total = mode->vtotal % 2;
+ oddEvenV_Total = 1 - oddEvenV_Total;
+ oddEvenV_Total = oddEvenV_Total << 8;
+ MSA_MISC_Param =
+ ((tempForMisc * 2) + (32 * tempForMisc2) +
+ ((pxlencformat == Y_ONLY ? 1 : 0) << 14) +
+ ((oddEvenV_Total) * (mode->flags & DRM_MODE_FLAG_INTERLACE ? 1 : 0)));
+
+ /* 420 has diffrent parameters, enable VSS SDP */
+ if (pxlencformat == YCBCR_4_2_0)
+ MSA_MISC_Param = 1 << 14;
+
+ switch (state->tmp) {
+ case 0:
+ ret =
+ CDN_API_DPTX_Write_Register(state, BASE_SOURCE_VIF,
+ BND_HSYNC2VSYNC,
+ BND_HSYNC2VSYNC_Param);
+ break;
+ case 1:
+ ret =
+ CDN_API_DPTX_Write_Register(state, BASE_SOURCE_VIF,
+ HSYNC2VSYNC_POL_CTRL,
+ HSYNC2VSYNC_POL_CTRL_Param);
+ break;
+ case 2:
+ ret =
+ CDN_API_DPTX_Write_Register(state, BASE_DPTX_STREAM,
+ DP_FRAMER_TU,
+ DP_FRAMER_TU_Param);
+ break;
+ case 3:
+ ret =
+ CDN_API_DPTX_Write_Register(state, BASE_DPTX_STREAM,
+ DP_FRAMER_PXL_REPR,
+ DP_FRAMER_PXL_REPR_Param);
+ break;
+ case 4:
+ ret =
+ CDN_API_DPTX_Write_Register(state, BASE_DPTX_STREAM,
+ DP_FRAMER_SP,
+ DP_FRAMER_SP_Param);
+ break;
+ case 5:
+ ret =
+ CDN_API_DPTX_Write_Register(state, BASE_DPTX_STREAM,
+ DP_FRONT_BACK_PORCH,
+ DP_FRONT_BACK_PORCH_Param);
+ break;
+ case 6:
+ ret =
+ CDN_API_DPTX_Write_Register(state, BASE_DPTX_STREAM,
+ DP_BYTE_COUNT,
+ DP_BYTE_COUNT_Param);
+ break;
+ case 7:
+ ret =
+ CDN_API_DPTX_Write_Register(state, BASE_DPTX_STREAM,
+ MSA_HORIZONTAL_0,
+ MSA_HORIZONTAL_0_Param);
+ break;
+ case 8:
+ ret =
+ CDN_API_DPTX_Write_Register(state, BASE_DPTX_STREAM,
+ MSA_HORIZONTAL_1,
+ MSA_HORIZONTAL_1_Param);
+ break;
+ case 9:
+ ret =
+ CDN_API_DPTX_Write_Register(state, BASE_DPTX_STREAM,
+ MSA_VERTICAL_0,
+ MSA_VERTICAL_0_Param);
+ break;
+ case 10:
+ ret =
+ CDN_API_DPTX_Write_Register(state, BASE_DPTX_STREAM,
+ MSA_VERTICAL_1,
+ MSA_VERTICAL_1_Param);
+ break;
+ case 11:
+ ret =
+ CDN_API_DPTX_Write_Register(state, BASE_DPTX_STREAM,
+ MSA_MISC, MSA_MISC_Param);
+ break;
+ case 12:
+ ret =
+ CDN_API_DPTX_Write_Register(state, BASE_DPTX_STREAM,
+ STREAM_CONFIG, 1);
+ break;
+ case 13:
+ ret =
+ CDN_API_DPTX_Write_Register(state, BASE_DPTX_STREAM,
+ DP_HORIZONTAL,
+ DP_HORIZONTAL_ADDR_Param);
+ break;
+ case 14:
+ ret =
+ CDN_API_DPTX_Write_Register(state, BASE_DPTX_STREAM,
+ DP_VERTICAL_0,
+ DP_VERTICAL_0_ADDR_Param);
+ break;
+ case 15:
+ ret =
+ CDN_API_DPTX_Write_Register(state, BASE_DPTX_STREAM,
+ DP_VERTICAL_1,
+ DP_VERTICAL_1_ADDR_Param);
+ break;
+ case 16:
+ ret =
+ CDN_API_DPTX_Write_Field(state, BASE_DPTX_STREAM, DP_VB_ID,
+ 2, 1,
+ ((mode->flags & DRM_MODE_FLAG_INTERLACE ? 1 : 0) << 2));
+ break;
+ case 17:
+ ret =
+ CDN_API_DPTX_Write_Register(state, BASE_DPTX_STREAM,
+ LINE_THRESH, lineThresh);
+ break;
+ case 18:
+ ret =
+ CDN_API_DPTX_Write_Register(state, BASE_DPTX_STREAM,
+ RATE_GOVERNOR_STATUS,
+ tu_vs_diff << 8);
+ break;
+ }
+ if (!state->tmp && ret == CDN_STARTED)
+ return CDN_STARTED;
+ switch (ret) {
+ case CDN_OK:
+ state->tmp++;
+ break;
+ case CDN_STARTED:
+ return CDN_BSY;
+ break;
+ default:
+ return ret;
+ }
+ if (state->tmp == 19) {
+ state->tmp = 0;
+ return CDN_OK;
+ }
+ return CDN_BSY;
+}
+
+CDN_API_STATUS CDN_API_DPTX_Set_VIC_blocking(state_struct *state,
+ struct drm_display_mode *mode,
+ int bitsPerPixel,
+ VIC_NUM_OF_LANES NumOfLanes,
+ VIC_SYMBOL_RATE rate,
+ VIC_PXL_ENCODING_FORMAT
+ pxlencformat,
+ STEREO_VIDEO_ATTR steroVidAttr,
+ BT_TYPE bt_type, int TU)
+{
+ internal_block_function(&state->mutex, CDN_API_DPTX_Set_VIC
+ (state, mode, bitsPerPixel, NumOfLanes, rate,
+ pxlencformat, steroVidAttr, bt_type, TU));
+}
+
+CDN_API_STATUS CDN_API_DPTX_SetVideo(state_struct *state, u8 mode)
+{
+ internal_macro_command_tx(state, MB_MODULE_ID_DP_TX, DPTX_SET_VIDEO,
+ CDN_BUS_TYPE_APB, 1, 1, mode);
+ return CDN_OK;
+}
+
+CDN_API_STATUS CDN_API_DPTX_SetVideo_blocking(state_struct *state, u8 mode)
+{
+ internal_block_function(&state->mutex, CDN_API_DPTX_SetVideo(state, mode));
+}
+
+CDN_API_STATUS CDN_API_DPTX_ReadLinkStat(state_struct *state,
+ S_LINK_STAT *stat)
+{
+ internal_macro_command_txrx(state, MB_MODULE_ID_DP_TX,
+ DPTX_READ_LINK_STAT, CDN_BUS_TYPE_APB, 0);
+ internal_readmsg(state, 10, 1, &stat->rate, 1, &stat->lanes, 1,
+ &stat->swing[0], 1, &stat->preemphasis[0], 1,
+ &stat->swing[1], 1, &stat->preemphasis[1], 1,
+ &stat->swing[2], 1, &stat->preemphasis[2], 1,
+ &stat->swing[3], 1, &stat->preemphasis[3]);
+ return CDN_OK;
+}
+
+CDN_API_STATUS CDN_API_DPTX_ReadLinkStat_blocking(state_struct *state,
+ S_LINK_STAT *stat)
+{
+ internal_block_function(&state->mutex, CDN_API_DPTX_ReadLinkStat(state, stat));
+}
+
+CDN_API_STATUS CDN_API_DPTX_TrainingControl(state_struct *state, u8 val)
+{
+ internal_macro_command_tx(state, MB_MODULE_ID_DP_TX,
+ DPTX_TRAINING_CONTROL, CDN_BUS_TYPE_APB, 1, 1,
+ val);
+ return CDN_OK;
+}
+
+CDN_API_STATUS CDN_API_DPTX_TrainingControl_blocking(state_struct *state,
+ u8 val)
+{
+ internal_block_function(&state->mutex, CDN_API_DPTX_TrainingControl(state, val));
+}
+
+CDN_API_STATUS CDN_API_DPTX_GetLastAuxStatus(state_struct *state, u8 *resp)
+{
+ internal_macro_command_txrx(state, MB_MODULE_ID_DP_TX,
+ DPTX_GET_LAST_AUX_STAUS, CDN_BUS_TYPE_APB,
+ 0);
+ internal_readmsg(state, 1, 1, resp);
+ return CDN_OK;
+}
+
+CDN_API_STATUS CDN_API_DPTX_GetLastAuxStatus_blocking(state_struct *state,
+ u8 *resp)
+{
+ internal_block_function(&state->mutex, CDN_API_DPTX_GetLastAuxStatus(state, resp));
+}
+
+CDN_API_STATUS CDN_API_DPTX_GetLastI2cStatus(state_struct *state, u8 *resp)
+{
+ internal_macro_command_txrx(state, MB_MODULE_ID_DP_TX, DPTX_GET_LAST_I2C_STATUS, CDN_BUS_TYPE_APB, 0);
+ internal_readmsg(state, 1, 1, resp);
+ return CDN_OK;
+}
+
+CDN_API_STATUS CDN_API_DPTX_GetLastI2cStatus_blocking(state_struct *state, u8 *resp)
+{
+ internal_block_function(&state->mutex, CDN_API_DPTX_GetLastI2cStatus(state, resp));
+}
+
+CDN_API_STATUS CDN_API_DPTX_GetHpdStatus(state_struct *state, u8 *resp)
+{
+ internal_macro_command_txrx(state, MB_MODULE_ID_DP_TX, DPTX_HPD_STATE,
+ CDN_BUS_TYPE_APB, 0);
+ internal_readmsg(state, 1, 1, resp);
+ return CDN_OK;
+}
+
+CDN_API_STATUS CDN_API_DPTX_GetHpdStatus_blocking(state_struct *state,
+ u8 *resp)
+{
+
+ internal_block_function(&state->mutex, CDN_API_DPTX_GetHpdStatus(state, resp));
+}
+
+CDN_API_STATUS CDN_API_DPTX_ForceLanes(state_struct *state, u8 linkRate,
+ u8 numOfLanes,
+ u8 voltageSwing_l0,
+ u8 preemphasis_l0,
+ u8 voltageSwing_l1,
+ u8 preemphasis_l1,
+ u8 voltageSwing_l2,
+ u8 preemphasis_l2,
+ u8 voltageSwing_l3,
+ u8 preemphasis_l3, u8 pattern, u8 ssc)
+{
+ if (!state->running) {
+ if (!internal_apb_available(state))
+ return CDN_BSY;
+ internal_tx_mkfullmsg(state, MB_MODULE_ID_DP_TX,
+ DPTX_FORCE_LANES, 12, 1, linkRate, 1,
+ numOfLanes, 1, voltageSwing_l0, 1,
+ preemphasis_l0, 1, voltageSwing_l1, 1,
+ preemphasis_l1, 1, voltageSwing_l2, 1,
+ preemphasis_l2, 1, voltageSwing_l3, 1,
+ preemphasis_l3, 1, pattern, 1, ssc);
+ state->bus_type = CDN_BUS_TYPE_APB;
+ return CDN_STARTED;
+ }
+ internal_process_messages(state);
+ return CDN_OK;
+}
+
+CDN_API_STATUS CDN_API_DPTX_ForceLanes_blocking(state_struct *state,
+ u8 linkRate, u8 numOfLanes,
+ u8 voltageSwing_l0,
+ u8 preemphasis_l0,
+ u8 voltageSwing_l1,
+ u8 preemphasis_l1,
+ u8 voltageSwing_l2,
+ u8 preemphasis_l2,
+ u8 voltageSwing_l3,
+ u8 preemphasis_l3, u8 pattern,
+ u8 ssc)
+{
+ internal_block_function(&state->mutex, CDN_API_DPTX_ForceLanes
+ (state, linkRate, numOfLanes, voltageSwing_l0,
+ preemphasis_l0, voltageSwing_l1,
+ preemphasis_l1, voltageSwing_l2,
+ preemphasis_l2, voltageSwing_l3,
+ preemphasis_l3, pattern, ssc));
+}
+
+CDN_API_STATUS CDN_API_DPTX_SetPhyCoefficients(state_struct *state,
+ u16 mgnfsValues[4][4],
+ u16 cpostValues[4][4])
+{
+ if (!state->running) {
+ if (!internal_apb_available(state))
+ return CDN_BSY;
+ internal_tx_mkfullmsg(state, MB_MODULE_ID_DP_TX, DPTX_SET_PHY_COEFFICIENTS, 20,
+ 2, mgnfsValues[0][0],
+ 2, mgnfsValues[0][1],
+ 2, mgnfsValues[0][2],
+ 2, mgnfsValues[0][3],
+ 2, mgnfsValues[1][0],
+ 2, mgnfsValues[1][1],
+ 2, mgnfsValues[1][2],
+ 2, mgnfsValues[2][0],
+ 2, mgnfsValues[2][1],
+ 2, mgnfsValues[3][0],
+ 2, cpostValues[0][0],
+ 2, cpostValues[0][1],
+ 2, cpostValues[0][2],
+ 2, cpostValues[0][3],
+ 2, cpostValues[1][0],
+ 2, cpostValues[1][1],
+ 2, cpostValues[1][2],
+ 2, cpostValues[2][0],
+ 2, cpostValues[2][1],
+ 2, cpostValues[3][0]);
+ state->bus_type = CDN_BUS_TYPE_APB;
+ return CDN_STARTED;
+ }
+ internal_process_messages(state);
+ return CDN_OK;
+}
+
+CDN_API_STATUS CDN_API_DPTX_SetPhyCoefficients_blocking(state_struct *state,
+ u16 mgnfsValues[4][4],
+ u16 cpostValues[4][4])
+{
+ internal_block_function(&state->mutex,
+ CDN_API_DPTX_SetPhyCoefficients(state, mgnfsValues, cpostValues));
+}
+
+CDN_API_STATUS CDN_API_DPTX_SetDbg(state_struct *state, uint32_t dbg_cfg)
+{
+ uint8_t buf[sizeof(uint32_t)];
+
+ if (!state->running) {
+ if (!internal_apb_available(state))
+ return CDN_BSY;
+
+ buf[0] = (uint8_t) (dbg_cfg);
+ buf[1] = (uint8_t) (dbg_cfg >> 8);
+ buf[2] = (uint8_t) (dbg_cfg >> 16);
+ buf[3] = (uint8_t) (dbg_cfg >> 24);
+
+ internal_tx_mkfullmsg(state, MB_MODULE_ID_DP_TX, DPTX_DBG_SET,
+ 1, -sizeof(buf), buf);
+
+ state->bus_type = CDN_BUS_TYPE_APB;
+
+ return CDN_STARTED;
+ }
+
+ internal_process_messages(state);
+
+ return CDN_OK;
+}
+
+CDN_API_STATUS CDN_API_DPTX_SetDbg_blocking(state_struct *state,
+ uint32_t dbg_cfg)
+{
+ internal_block_function(&state->mutex, CDN_API_DPTX_SetDbg(state, dbg_cfg));
+}
diff --git a/drivers/mxc/hdp/API_DPTX.h b/drivers/mxc/hdp/API_DPTX.h
new file mode 100644
index 000000000000..2a896d11b499
--- /dev/null
+++ b/drivers/mxc/hdp/API_DPTX.h
@@ -0,0 +1,540 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2016-2018 Cadence Design Systems, Inc.
+ * All rights reserved worldwide.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 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.
+ *
+ * Copyright 2017-2018 NXP
+ *
+ ******************************************************************************
+ *
+ * API_DPTX.h
+ *
+ ******************************************************************************
+ */
+
+#ifndef _API_DPTX_H_
+#define _API_DPTX_H_
+
+#include "API_General.h"
+#include "API_AFE.h"
+
+#define MAX_NUM_OF_EVENTS 4
+
+/* Flags for CDN_API_DPTX_SetDbg */
+#define DPTX_DBG_SET_PWR_SKIP_SLEEP (1 << 0)
+#define DPTX_DBG_SET_ALT_CIPHER_ADDR (1 << 1)
+
+/**
+ * \addtogroup DP_TX_API
+ * \{
+ */
+typedef u8 CDN_API_PWR_MODE;
+typedef u32 CDN_EVENT;
+
+/**
+ * reply data struct for #CDN_API_DPTX_I2C_Read
+ */
+typedef struct
+{
+ /** buffer where data will be stored, will become invalid after next call to API */
+ u8 *buff;
+ int addr;
+ int size;
+} DPTX_I2C_Read_response;
+/**
+ * \brief Cadence API for DP TX to read bytes using I2C-over-AUX
+ *
+ * \param [in] numOfBytes - number of bytes to read
+ * \param [in] addr - I2C slave address to read from, placed at bits 0-6 (without direction bit).
+ * \param [in] mot - Whether (1) or not (0) to set MoT (Middle-of-Transaction) flag during the last I2C-over-AUX transaction handling this operation.
+ * \param [out] resp - pointer to store response
+ * \return status
+ *
+ */
+CDN_API_STATUS CDN_API_DPTX_I2C_Read(state_struct *state, u32 numOfBytes,
+ u8 addr, u8 mot, DPTX_I2C_Read_response *resp);
+/**
+ * blocking version of #CDN_API_DPTX_I2C_Read
+ */
+CDN_API_STATUS CDN_API_DPTX_I2C_Read_blocking(state_struct *state, u32 numOfBytes,
+ u8 addr, u8 mot, DPTX_I2C_Read_response *resp);
+
+/**
+ * reply data struct for #CDN_API_DPTX_I2C_Write
+ */
+typedef struct
+{
+ int addr;
+ int size;
+} DPTX_I2C_Write_response;
+/**
+ * \brief Cadence API for DP TX to write bytes using I2C-over-AUX
+ *
+ * \param [in] numOfBytes - number of bytes to write
+ * \param [in] addr - I2C slave address to write to, placed at bits 0-6 (without direction bit).
+ * \param [in] mot - Whether (1) or not (0) to set MoT (Middle-of-Transaction) flag during the last I2C-over-AUX transaction handling this operation.
+ * \param [in] buff - buffer with the data to write
+ * \param [out] resp - pointer to store response
+ * \return status
+ *
+ */
+CDN_API_STATUS CDN_API_DPTX_I2C_Write(state_struct *state, u32 numOfBytes,
+ u8 addr, u8 mot, u8 *buff, DPTX_I2C_Write_response *resp);
+/**
+ * blocking version of #CDN_API_DPTX_I2C_Write
+ */
+CDN_API_STATUS CDN_API_DPTX_I2C_Write_blocking(state_struct *state, u32 numOfBytes,
+ u8 addr, u8 mot, u8 *buff, DPTX_I2C_Write_response *resp);
+
+/**
+ * reply data struct for CDN_API_DPTX_READ_EDID
+ * please note, buff will point to internal api buffer, user must copy it for later use
+ */
+typedef struct {
+ u8 *buff;
+ u8 size;
+ u8 blockNo;
+} DPTX_Read_EDID_response;
+/**
+ * \brief Cadence API for DP TX to get RX EDID
+ * \param [in] segment - EDID segment to read
+ * \param [in] extension - EDID extension to read
+ * \param [out] resp - pointer to store response
+ * buffer , please note, buff will point to internal api buffer, user must copy it for later use
+ * \return status
+ *
+ */
+CDN_API_STATUS CDN_API_DPTX_Read_EDID(state_struct *state, u8 segment,
+ u8 extension,
+ DPTX_Read_EDID_response *resp);
+/**
+ * \brief blocking version of #CDN_API_DPTX_Read_EDID
+ */
+CDN_API_STATUS CDN_API_DPTX_Read_EDID_blocking(state_struct *state, u8 segment,
+ u8 extension,
+ DPTX_Read_EDID_response *resp);
+
+/**
+ * \brief Cadence API for DP TX to set power mode of sink
+ *
+ * \param [in] mode - power mode
+ * \return status
+ *
+ */
+CDN_API_STATUS CDN_API_DPTX_SetPowerMode(state_struct *state,
+ CDN_API_PWR_MODE mode);
+/**
+ * \brief blocking version of #CDN_API_DPTX_SetPowerMode
+ */
+CDN_API_STATUS CDN_API_DPTX_SetPowerMode_blocking(state_struct *state,
+ CDN_API_PWR_MODE mode);
+
+/**
+ * \brief Cadence API for DP TX to set Host capabilities
+ *
+ * \param [in] maxLinkRate Max link rate-> 0x06=1.62Gbps 0x0A=2.7Gbps 0x14=5.4Gbps 0x1E=8.1Gbps
+ * \param [in] lanesCount_SSC bit 0-3 lanes count, bit 4 SSC
+ * \param [in] maxVoltageSwing - - max supported VoltageSwing
+ * \param [in] maxPreemphasis - max supported Preemphasis
+ * \param [in] testPatternsSupported -which test patern supportrd by phy
+ * \param [in] fastLinkTraining - is it fast link training
+ * \param [in] laneMapping - line mapping for USB type C
+ * \param [in] enchanced - enchanced mode
+ * \return status
+ *
+ */
+CDN_API_STATUS CDN_API_DPTX_SetHostCap(state_struct *state, u8 maxLinkRate,
+ u8 lanesCount_SSC,
+ u8 maxVoltageSwing,
+ u8 maxPreemphasis,
+ u8 testPatternsSupported,
+ u8 fastLinkTraining,
+ u8 laneMapping, u8 enchanced);
+/**
+ * \brief blocking version of #CDN_API_DPTX_SetHostCap
+ */
+CDN_API_STATUS CDN_API_DPTX_SetHostCap_blocking(state_struct *state,
+ u8 maxLinkRate,
+ u8 lanesCount_SSC,
+ u8 maxVoltageSwing,
+ u8 maxPreemphasis,
+ u8 testPatternsSupported,
+ u8 fastLinkTraining,
+ u8 laneMapping, u8 enchanced);
+
+/**
+ * reply data struct for #CDN_API_DPTX_READ_DPCD
+ */
+typedef struct {
+ /** buffer where data will be stored, will become invalid after next call to API */
+ u8 *buff;
+ int addr;
+ int size;
+} DPTX_Read_DPCD_response;
+/**
+ * \brief Cadence API for DP TX to read DPCD
+ *
+ * \param [in] numOfBytes - num of bytes to read
+ * \param [in] addr - address to read from
+ * \param [out] resp - pointer to store response
+ * \return status
+ *
+ */
+CDN_API_STATUS CDN_API_DPTX_Read_DPCD(state_struct *state, int numOfBytes,
+ int addr, DPTX_Read_DPCD_response *resp,
+ CDN_BUS_TYPE bus_type);
+/**
+ * blocking version of #CDN_API_DPTX_READ_DPCD
+ */
+CDN_API_STATUS CDN_API_DPTX_Read_DPCD_blocking(state_struct *state,
+ int numOfBytes, int addr,
+ DPTX_Read_DPCD_response *resp,
+ CDN_BUS_TYPE bus_type);
+
+/**
+ * reply data struct for CDN_API_DPTX_WRITE_DPCD
+ */
+typedef struct {
+ int addr;
+ int size;
+} DPTX_Write_DPCD_response;
+/**
+ * \brief Cadence API for DP TX to write DPCD
+ *
+ * \param [in] numOfBytes - num of bytes to write
+ * \param [in] addr - address to write
+ * \param [in] buff - with the data to write
+ * \param [out] resp - pointer to store response
+ * \return status
+ *
+ */
+CDN_API_STATUS CDN_API_DPTX_Write_DPCD(state_struct *state, u32 numOfBytes,
+ u32 addr, u8 *buff,
+ DPTX_Write_DPCD_response *resp,
+ CDN_BUS_TYPE bus_type);
+/**
+ * blocking version of #CDN_API_DPTX_WRITE_DPCD
+ */
+CDN_API_STATUS CDN_API_DPTX_Write_DPCD_blocking(state_struct *state,
+ u32 numOfBytes, u32 addr,
+ u8 *buff,
+ DPTX_Write_DPCD_response *resp,
+ CDN_BUS_TYPE bus_type);
+
+/**
+ * DPTX_Read_Register response struct
+ */
+typedef struct {
+ u8 base;
+ u8 regNo;
+ u32 val;
+} DPTX_Read_Register_response;
+/**
+ * \brief Cadence API for DP TX to read register
+ *
+ * \param [in] base - bank numeber (MSB of bank base address)
+ * \param [in] regNo - register number
+ * \param [out] resp - pointer to store response
+ * \return status
+ *
+ * this function will return #CDN_ERR if value of base is incorrect
+ */
+CDN_API_STATUS CDN_API_DPTX_Read_Register(state_struct *state, u8 base,
+ u8 regNo,
+ DPTX_Read_Register_response *resp);
+/**
+ * blocking version of #CDN_API_DPTX_READ_REGISTER
+ */
+CDN_API_STATUS CDN_API_DPTX_Read_Register_blocking(state_struct *state,
+ u8 base, u8 regNo,
+ DPTX_Read_Register_response *
+ resp);
+
+/**
+ * \brief Cadence API for DP TX write register
+ *
+ * \param [in] base - bank numeber (MSB of bank base address)
+ * \param [in] regNo - register number
+ * \param [in] val - value to write
+ * \return status
+ *
+ * this function will return #CDN_ERR if value of base is incorrect
+ */
+CDN_API_STATUS CDN_API_DPTX_Write_Register(state_struct *state, u8 base,
+ u8 regNo, u32 val);
+/**
+ * blocking version of #CDN_API_DPTX_Write_Register
+ */
+CDN_API_STATUS CDN_API_DPTX_Write_Register_blocking(state_struct *state,
+ u8 base, u8 regNo, u32 val);
+
+/**
+ * \brief Cadence API for DP TX write register
+ *
+ * \param [in] base - bank numeber (MSB of bank base address)
+ * \param [in] regNo - register number
+ * \param [in] startBit - first bit to write
+ * \param [in] bitsNo - number of bits to write
+ * \param [in] val - value to write
+ * \return status
+ *
+ * this function will return #CDN_ERR if value of base is incorrect
+ */
+CDN_API_STATUS CDN_API_DPTX_Write_Field(state_struct *state, u8 base, u8 regNo,
+ u8 startBit, u8 bitsNo, u32 val);
+/**
+ * blocking version of #CDN_API_DPTX_Write_Field
+ */
+CDN_API_STATUS CDN_API_DPTX_Write_Field_blocking(state_struct *state, u8 base,
+ u8 regNo,
+ u8 startBit,
+ u8 bitsNo, u32 val);
+
+/* TODO doxygen of DPTX_CONTROL API */
+CDN_API_STATUS CDN_API_DPTX_Control(state_struct *state, u32 mode);
+/**
+ * blocking version of #CDN_API_DPTX_Control
+ */
+CDN_API_STATUS CDN_API_DPTX_Control_blocking(state_struct *state, u32 mode);
+
+/**
+ * \brief Performs Fast Link Training, using LINK_RATE_SET DPCD register.
+ * \param [in] mode - 0 to stop training, 1 to start it, 2 to restart it.
+ * \param [in] linkRate - Link Rate to be used for training.
+ * \param [in] rateId - index of selected Link Rate in DPCd registers.
+ *
+ * Performs Fast Link Training, selecting Link Rate using LINK_RATE_SET DPCD
+ * register, characteristic to Embedded DisplayPort (eDP) v1.4 standard.
+ * If requested link rate is not supported by DPTX, function will return error
+ * code CDN_ERROR_NOT_SUPPORTED, and will take no further action.
+ * rateId is used to select, which Link Rate supported by sink (enumerated in
+ * SUPPORTED_LINK_RATES DPCD registers) is equal to rate requested. This value
+ * will be written to first 3 bits of LINK_RATE_SET DPCD registers. Allowed
+ * range is 0-7. If it is not known beforehand, SUPPORTED_LINK_RATES DPCD
+ * registers may be read by an upper layer, and then used to determine the
+ * correct value to use.
+ */
+CDN_API_STATUS CDN_API_DPTX_EDP_Training(state_struct *state, u8 mode, ENUM_AFE_LINK_RATE linkRate, u8 rateId);
+CDN_API_STATUS CDN_API_DPTX_EDP_Training_blocking(state_struct *state, u8 mode, ENUM_AFE_LINK_RATE linkRate, u8 rateId);
+/**
+ * \brief send DPX_ENABLE_EVENT command
+ */
+CDN_API_STATUS CDN_API_DPTX_EnableEvent(state_struct *state, bool hpd,
+ bool training);
+
+/**
+ * blocking version of #CDN_API_DPTX_EnableEvent
+ */
+CDN_API_STATUS CDN_API_DPTX_EnableEvent_blocking(state_struct *state, bool hpd,
+ bool training);
+
+/**
+ * \brief send DPTX_READ_EVENT_REQUEST command
+ */
+CDN_API_STATUS CDN_API_DPTX_ReadEvent(state_struct *state, u8 *LinkeventId,
+ u8 *HPDevents);
+
+/**
+ * blocking version of #CDN_API_DPTX_ReadEvent
+ */
+CDN_API_STATUS CDN_API_DPTX_ReadEvent_blocking(state_struct *state,
+ u8 *LinkeventId,
+ u8 *HPDevents);
+
+/**
+ * \brief set vic mode according to vic table, the input are video parameters
+ */
+CDN_API_STATUS CDN_API_DPTX_Set_VIC(state_struct *state, struct drm_display_mode *mode,
+ int bitsPerPixel,
+ VIC_NUM_OF_LANES NumOfLanes,
+ VIC_SYMBOL_RATE rate,
+ VIC_PXL_ENCODING_FORMAT pxlencformat,
+ STEREO_VIDEO_ATTR steroVidAttr,
+ BT_TYPE bt_type, int TU);
+
+/**
+ * blocking version of #CDN_API_DPTX_Set_VIC
+ */
+CDN_API_STATUS CDN_API_DPTX_Set_VIC_blocking(state_struct *state,
+ struct drm_display_mode *mode,
+ int bitsPerPixel,
+ VIC_NUM_OF_LANES NumOfLanes,
+ VIC_SYMBOL_RATE rate,
+ VIC_PXL_ENCODING_FORMAT
+ pxlencformat,
+ STEREO_VIDEO_ATTR steroVidAttr,
+ BT_TYPE bt_type, int TU);
+
+/**
+ * \brief turn on or off the video
+ */
+CDN_API_STATUS CDN_API_DPTX_SetVideo(state_struct *state, u8 mode);
+
+/**
+ * \brief blocking version of CDN_API_DPTX_SetVideo
+ */
+CDN_API_STATUS CDN_API_DPTX_SetVideo_blocking(state_struct *state, u8 mode);
+/**
+ * \brief blocking version of #CDN_API_DPTX_SetAudio
+ */
+CDN_API_STATUS CDN_API_DPTX_SetAudio_blocking(state_struct *state, u8 mode);
+
+typedef struct {
+ u8 rate;
+ u8 lanes;
+ u8 swing[3];
+ u8 preemphasis[3];
+} S_LINK_STAT;
+
+/**
+ * \brief get current link status (rate, num of lanes etc), user may read it after get link finish event
+ */
+CDN_API_STATUS CDN_API_DPTX_ReadLinkStat(state_struct *state,
+ S_LINK_STAT *stat);
+
+/**
+ * \brief blocking version of #CDN_API_DPTX_ReadLinkStat
+ */
+CDN_API_STATUS CDN_API_DPTX_ReadLinkStat_blocking(state_struct *state,
+ S_LINK_STAT *stat);
+
+/**
+ * \brief start link training
+ */
+CDN_API_STATUS CDN_API_DPTX_TrainingControl(state_struct *state, u8 val);
+/**
+ * \brief blocking version of #CDN_API_DPTX_TrainingControl
+ */
+CDN_API_STATUS CDN_API_DPTX_TrainingControl_blocking(state_struct *state,
+ u8 val);
+
+/**
+ * \brief check if last auxilary transaction succedd
+ */
+CDN_API_STATUS CDN_API_DPTX_GetLastAuxStatus(state_struct *state, u8 *resp);
+/**
+ * \brief blocking version of #CDN_API_DPTX_GetLastAuxStatus
+ */
+CDN_API_STATUS CDN_API_DPTX_GetLastAuxStatus_blocking(state_struct *state,
+ u8 *resp);
+
+/**
+ * \brief Get status of latest I2C-over-AUX transaction.
+ *
+ * \param [out] resp - pointer to store response. 0 - I2C_ACK, 1 - I2C_NACK, 2 - I2C_DEFER.
+ */
+CDN_API_STATUS CDN_API_DPTX_GetLastI2cStatus(state_struct *state, u8 *resp);
+/**
+ * \brief blocking version of #CDN_API_DPTX_GetLastI2cStatus
+ */
+CDN_API_STATUS CDN_API_DPTX_GetLastI2cStatus_blocking(state_struct *state, u8 *resp);
+
+/**
+ * \brief get current hpd status
+ */
+
+CDN_API_STATUS CDN_API_DPTX_GetHpdStatus(state_struct *state, u8 *resp);
+/**
+ * \brief blocking version of #CDN_API_DPTX_GetHpdStatus
+ */
+CDN_API_STATUS CDN_API_DPTX_GetHpdStatus_blocking(state_struct *state,
+ u8 *resp);
+
+/**
+ * \brief force the lanes to specific swing or preemphasis, with SSc or without to pattern (0=PRBS7 or 1=D10.2) for CTS or debug phy purpose
+ */
+CDN_API_STATUS CDN_API_DPTX_ForceLanes(state_struct *state, u8 linkRate,
+ u8 numOfLanes,
+ u8 voltageSwing_l0,
+ u8 preemphasis_l0,
+ u8 voltageSwing_l1,
+ u8 preemphasis_l1,
+ u8 voltageSwing_l2,
+ u8 preemphasis_l2,
+ u8 voltageSwing_l3,
+ u8 preemphasis_l3, u8 pattern, u8 ssc);
+
+/**
+ * \brief blocking version of #CDN_API_DPTX_ForceLanes
+ */
+CDN_API_STATUS CDN_API_DPTX_ForceLanes_blocking(state_struct *state,
+ u8 linkRate, u8 numOfLanes,
+ u8 voltageSwing_l0,
+ u8 preemphasis_l0,
+ u8 voltageSwing_l1,
+ u8 preemphasis_l1,
+ u8 voltageSwing_l2,
+ u8 preemphasis_l2,
+ u8 voltageSwing_l3,
+ u8 preemphasis_l3, u8 pattern,
+ u8 ssc);
+/**
+ * \brief Set custom PHY coefficients (values) for voltage-swing and pre-emphasis related registers.
+ * \param [in] mgnfsValues Array of values to use for TX_TXCC_MGNFS_MULT_000 registers
+ * \param [in] cpostValues Array of values to use for TX_TXCC_CPOST_MULT_00 registers
+ *
+ * Each array shall contain set of values to be used for respective PHY register
+ * (if used PHY has such registers). First index represents voltage swing,
+ * second - pre-emphasis.
+ * For example, mgnfsValues[2][0] will be used for TX_TXCC_MGNFS_MULT_000
+ * register, for voltage swing level = 2 and pre-emphasis level = 0.
+ * Similarly, cpostValues[1][2] will be used for TX_TXCC_CPOST_MULT_00 register,
+ * for voltage swing level = 1 and pre-emphasis level = 2.
+ * Default values (one that Firmware starts with) can be acquired using
+ * API_DPTX_GetDefaultCoefficients() - if applicable for given PHY.
+ * Values, where sum of indexes (for voltage swing and pre-emphasis) are
+ * greater than 3 are ignored, as such levels are forbidden by DP standard.
+ */
+CDN_API_STATUS CDN_API_DPTX_SetPhyCoefficients(state_struct *state,
+ u16 mgnfsValues[4][4],
+ u16 cpostValues[4][4]);
+/**
+ * \brief blocking version of #CDN_API_DPTX_SetPhyCoefficients
+ */
+CDN_API_STATUS CDN_API_DPTX_SetPhyCoefficients_blocking(state_struct *state,
+ u16 mgnfsValues[4][4],
+ u16 cpostValues[4][4]);
+
+/**
+ * \brief Sets DP TX debug related features.
+ */
+CDN_API_STATUS CDN_API_DPTX_SetDbg(state_struct *state, u32 dbg_cfg);
+
+/**
+ * \brief blocking version of #CDN_API_DPTX_SetDbg
+ */
+CDN_API_STATUS CDN_API_DPTX_SetDbg_blocking(state_struct *state, u32 dbg_cfg);
+
+#endif
diff --git a/drivers/mxc/hdp/API_General.c b/drivers/mxc/hdp/API_General.c
new file mode 100644
index 000000000000..6c2c5fe0b754
--- /dev/null
+++ b/drivers/mxc/hdp/API_General.c
@@ -0,0 +1,518 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2016-2017 Cadence Design Systems, Inc.
+ * All rights reserved worldwide.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 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.
+ *
+ * Copyright 2017-2018 NXP
+ *
+ ******************************************************************************
+ *
+ * API_General.c
+ *
+ ******************************************************************************
+ */
+
+#include "API_General.h"
+#include "address.h"
+#include "apb_cfg.h"
+#include "opcodes.h"
+#include "general_handler.h"
+#include "util.h"
+
+CDN_API_STATUS CDN_API_LoadFirmware(state_struct *state, u8 *iMem,
+ int imemSize, u8 *dMem, int dmemSize)
+{
+ int i;
+ for (i = 0; i < imemSize; i += 4)
+ if (cdn_apb_write(state, ADDR_IMEM + i,
+ (u32) iMem[i] << 0 |
+ (u32) iMem[i + 1] << 8 |
+ (u32) iMem[i + 2] << 16 |
+ (u32) iMem[i + 3] << 24))
+ return CDN_ERR;
+ for (i = 0; i < dmemSize; i += 4)
+ if (cdn_apb_write(state, ADDR_DMEM + i,
+ (u32) dMem[i] << 0 |
+ (u32) dMem[i + 1] << 8 |
+ (u32) dMem[i + 2] << 16 |
+ (u32) dMem[i + 3] << 24))
+ return CDN_ERR;
+
+ return CDN_OK;
+}
+
+CDN_API_STATUS CDN_API_General_Test_Echo(state_struct *state, u32 val,
+ CDN_BUS_TYPE bus_type)
+{
+ CDN_API_STATUS ret;
+ if (!state->running) {
+ if (!internal_apb_available(state))
+ return CDN_BSY;
+ state->bus_type = bus_type;
+ state->rxEnable = 1;
+ internal_tx_mkfullmsg(state, MB_MODULE_ID_GENERAL,
+ GENERAL_TEST_ECHO, 1, 4, val);
+ return CDN_STARTED;
+ }
+ if (state->txEnable && !internal_mbox_tx_process(state).txend)
+ return CDN_BSY;
+ if (state->rxEnable && !internal_mbox_rx_process(state).rxend)
+ return CDN_BSY;
+ ret = internal_test_rx_head(state, MB_MODULE_ID_GENERAL,
+ GENERAL_TEST_ECHO);
+ if (ret != CDN_OK) {
+ state->running = 0;
+ return ret;
+ }
+ state->running = 0;
+ if (val != internal_betoi(state->rxBuffer + INTERNAL_CMD_HEAD_SIZE, 4))
+ return CDN_ERR;
+ return CDN_OK;
+}
+
+CDN_API_STATUS CDN_API_General_Test_Echo_blocking(state_struct *state, u32 val,
+ CDN_BUS_TYPE bus_type)
+{
+ internal_block_function(&state->mutex, CDN_API_General_Test_Echo
+ (state, val, bus_type));
+}
+
+CDN_API_STATUS CDN_API_General_Test_Echo_Ext(state_struct *state,
+ u8 const *msg, u8 *resp,
+ u16 num_bytes,
+ CDN_BUS_TYPE bus_type)
+{
+ CDN_API_STATUS ret;
+
+ if (!msg || !resp) {
+ return CDN_ERR;
+ }
+
+ if ((num_bytes > GENERAL_TEST_ECHO_MAX_PAYLOAD)
+ || (num_bytes < GENERAL_TEST_ECHO_MIN_PAYLOAD)) {
+ return CDN_ERR;
+ }
+
+ if (!state->running) {
+ if (!internal_apb_available(state)) {
+ return CDN_BSY;
+ }
+
+ state->bus_type = bus_type;
+ state->rxEnable = 1;
+
+ internal_tx_mkfullmsg(state, MB_MODULE_ID_GENERAL,
+ GENERAL_TEST_ECHO, 1, -num_bytes, msg);
+
+ return CDN_STARTED;
+ }
+
+ if (state->txEnable && !internal_mbox_tx_process(state).txend) {
+ return CDN_BSY;
+ }
+
+ if (state->rxEnable && !internal_mbox_rx_process(state).rxend) {
+ return CDN_BSY;
+ }
+
+ ret =
+ internal_test_rx_head(state, MB_MODULE_ID_GENERAL,
+ GENERAL_TEST_ECHO);
+
+ if (ret != CDN_OK) {
+ state->running = 0;
+ return ret;
+ }
+
+ state->running = 0;
+
+ memcpy(resp, state->rxBuffer + INTERNAL_CMD_HEAD_SIZE, num_bytes);
+
+ if (memcmp(msg, resp, num_bytes) != 0) {
+ return CDN_ERR;
+ }
+
+ return CDN_OK;
+}
+
+CDN_API_STATUS CDN_API_General_Test_Echo_Ext_blocking(state_struct *state,
+ u8 const *msg, u8 *resp,
+ u16 num_bytes,
+ CDN_BUS_TYPE bus_type)
+{
+ internal_block_function(&state->mutex, CDN_API_General_Test_Echo_Ext
+ (state, msg, resp, num_bytes, bus_type));
+}
+
+CDN_API_STATUS CDN_API_General_getCurVersion(state_struct *state, u16 *ver,
+ u16 *verlib)
+{
+ u32 vh, vl, vlh, vll;
+ if (cdn_apb_read(state, VER_L << 2, &vl))
+ return CDN_ERR;
+ if (cdn_apb_read(state, VER_H << 2, &vh))
+ return CDN_ERR;
+ if (cdn_apb_read(state, VER_LIB_L_ADDR << 2, &vll))
+ return CDN_ERR;
+ if (cdn_apb_read(state, VER_LIB_H_ADDR << 2, &vlh))
+ return CDN_ERR;
+ *ver = F_VER_MSB_RD(vh) << 8 | F_VER_LSB_RD(vl);
+ *verlib = F_SW_LIB_VER_H_RD(vlh) << 8 | F_SW_LIB_VER_L_RD(vll);
+ return CDN_OK;
+}
+
+CDN_API_STATUS CDN_API_Get_Event(state_struct *state, u32 *events)
+{
+ u32 evt[4] = { 0 };
+
+ if (!events) {
+ return CDN_ERR;
+ }
+
+ if (cdn_apb_read(state, SW_EVENTS0 << 2, &evt[0])
+ || cdn_apb_read(state, SW_EVENTS1 << 2, &evt[1])
+ || cdn_apb_read(state, SW_EVENTS2 << 2, &evt[2])
+ || cdn_apb_read(state, SW_EVENTS3 << 2, &evt[3])) {
+ printk("Failed to read events registers.\n");
+
+ return CDN_ERR;
+ }
+
+ *events = (evt[0] & 0xFF)
+ | ((evt[1] & 0xFF) << 8)
+ | ((evt[2] & 0xFF) << 16)
+ | ((evt[3] & 0xFF) << 24);
+
+ return CDN_OK;
+}
+
+CDN_API_STATUS CDN_API_Get_Debug_Reg_Val(state_struct *state, u16 *val)
+{
+ u32 dbg[2] = { 0 };
+
+ if (!val) {
+ printk("val pointer is NULL!\n");
+ return CDN_ERR;
+ }
+
+ if (cdn_apb_read(state, SW_DEBUG_L << 2, &dbg[0])
+ || cdn_apb_read(state, SW_DEBUG_H << 2, &dbg[1])) {
+ printk("Failed to read debug registers.\n");
+
+ return CDN_ERR;
+ }
+
+ *val = (u16) ((dbg[0] & 0xFF) | ((dbg[1] & 0xFF) << 8));
+
+ return CDN_OK;
+}
+
+CDN_API_STATUS CDN_API_CheckAlive(state_struct *state)
+{
+ u32 alive, newalive;
+ u8 retries_left = 10;
+
+ if (cdn_apb_read(state, KEEP_ALIVE << 2, &alive))
+ return CDN_ERR;
+
+ while (retries_left--) {
+ udelay(1);
+
+ if (cdn_apb_read(state, KEEP_ALIVE << 2, &newalive))
+ return CDN_ERR;
+ if (alive == newalive)
+ continue;
+ return CDN_OK;
+ }
+ return CDN_BSY;
+}
+
+
+CDN_API_STATUS CDN_API_CheckAlive_blocking(state_struct *state)
+{
+ internal_block_function(&state->mutex, CDN_API_CheckAlive(state));
+}
+
+CDN_API_STATUS CDN_API_MainControl(state_struct *state, u8 mode, u8 *resp)
+{
+ if (!state->running) {
+ if (!internal_apb_available(state))
+ return CDN_BSY;
+ state->bus_type = CDN_BUS_TYPE_APB;
+ state->rxEnable = 1;
+ internal_tx_mkfullmsg(state, MB_MODULE_ID_GENERAL,
+ GENERAL_MAIN_CONTROL, 1, 1, mode);
+ return CDN_STARTED;
+ }
+ internal_process_messages(state);
+ internal_opcode_ok_or_return(state, MB_MODULE_ID_GENERAL,
+ GENERAL_MAIN_CONTROL_RESP);
+ internal_readmsg(state, 1, 1, resp);
+ return CDN_OK;
+}
+
+CDN_API_STATUS CDN_API_MainControl_blocking(state_struct *state, u8 mode,
+ u8 *resp)
+{
+ internal_block_function(&state->mutex, CDN_API_MainControl(state, mode, resp));
+}
+
+CDN_API_STATUS CDN_API_ApbConf(state_struct *state, u8 dpcd_bus_sel,
+ u8 dpcd_bus_lock, u8 hdcp_bus_sel,
+ u8 hdcp_bus_lock, u8 capb_bus_sel,
+ u8 capb_bus_lock, u8 *dpcd_resp, u8 *hdcp_resp,
+ u8 *capb_resp)
+{
+ u8 resp;
+ u8 set = 0;
+
+ if (!state->running) {
+ if (!internal_apb_available(state)) {
+ return CDN_BSY;
+ }
+
+ state->bus_type = CDN_BUS_TYPE_APB;
+ state->rxEnable = 1;
+
+ set |= (dpcd_bus_sel)
+ ? (1 << GENERAL_BUS_SETTINGS_DPCD_BUS_BIT)
+ : 0;
+ set |= (dpcd_bus_lock)
+ ? (1 << GENERAL_BUS_SETTINGS_DPCD_BUS_LOCK_BIT)
+ : 0;
+ set |= (hdcp_bus_sel)
+ ? (1 << GENERAL_BUS_SETTINGS_HDCP_BUS_BIT)
+ : 0;
+ set |= (hdcp_bus_lock)
+ ? (1 << GENERAL_BUS_SETTINGS_HDCP_BUS_LOCK_BIT)
+ : 0;
+ set |= (capb_bus_sel)
+ ? (1 << GENERAL_BUS_SETTINGS_CAPB_OWNER_BIT)
+ : 0;
+ set |= (capb_bus_lock)
+ ? (1 << GENERAL_BUS_SETTINGS_CAPB_OWNER_LOCK_BIT)
+ : 0;
+
+ internal_tx_mkfullmsg(state, MB_MODULE_ID_GENERAL,
+ GENERAL_BUS_SETTINGS, 1, 1, set);
+
+ return CDN_STARTED;
+ }
+
+ internal_process_messages(state);
+ internal_opcode_ok_or_return(state, MB_MODULE_ID_GENERAL,
+ GENERAL_BUS_SETTINGS_RESP);
+
+ /* Read one one-byte response */
+ internal_readmsg(state, 1, 1, &resp);
+
+ *dpcd_resp =
+ (resp & (1 << GENERAL_BUS_SETTINGS_RESP_DPCD_BUS_BIT)) ? 1 : 0;
+ *hdcp_resp =
+ (resp & (1 << GENERAL_BUS_SETTINGS_RESP_HDCP_BUS_BIT)) ? 1 : 0;
+ *capb_resp =
+ (resp & (1 << GENERAL_BUS_SETTINGS_RESP_CAPB_OWNER_BIT)) ? 1 : 0;
+
+ return CDN_OK;
+}
+
+CDN_API_STATUS CDN_API_ApbConf_blocking(state_struct *state, u8 dpcd_bus_sel,
+ u8 dpcd_bus_lock,
+ u8 hdcp_bus_sel,
+ u8 hdcp_bus_lock,
+ u8 capb_bus_sel,
+ u8 capb_bus_lock,
+ u8 *dpcd_resp,
+ u8 *hdcp_resp, u8 *capb_resp)
+{
+ internal_block_function(&state->mutex, CDN_API_ApbConf
+ (state, dpcd_bus_sel, dpcd_bus_lock,
+ hdcp_bus_sel, hdcp_bus_lock, capb_bus_sel,
+ capb_bus_lock, dpcd_resp, hdcp_resp,
+ capb_resp));
+}
+
+CDN_API_STATUS CDN_API_SetClock(state_struct *state, u8 MHz)
+{
+ return cdn_apb_write(state, SW_CLK_H << 2, MHz);
+}
+
+CDN_API_STATUS CDN_API_GetClock(state_struct *state, u32 *MHz)
+{
+ return cdn_apb_read(state, SW_CLK_H << 2, MHz);
+}
+
+CDN_API_STATUS CDN_API_General_Read_Register(state_struct *state, u32 addr,
+ GENERAL_Read_Register_response *resp)
+{
+ CDN_API_STATUS ret;
+ if (!state->running) {
+ if (!internal_apb_available(state))
+ return CDN_BSY;
+ internal_tx_mkfullmsg(state, MB_MODULE_ID_GENERAL,
+ GENERAL_READ_REGISTER, 1, 4, addr);
+ state->bus_type = CDN_BUS_TYPE_APB;
+ state->rxEnable = 1;
+ return CDN_STARTED;
+ }
+ internal_process_messages(state);
+ ret = internal_test_rx_head(state, MB_MODULE_ID_GENERAL,
+ GENERAL_READ_REGISTER_RESP);
+ if (ret != CDN_OK)
+ return ret;
+ internal_readmsg(state, 2, 4, &resp->addr, 4, &resp->val);
+ return CDN_OK;
+}
+
+CDN_API_STATUS CDN_API_General_Read_Register_blocking(state_struct *state,
+ u32 addr, GENERAL_Read_Register_response *resp)
+{
+ internal_block_function(&state->mutex, CDN_API_General_Read_Register
+ (state, addr, resp));
+}
+
+CDN_API_STATUS CDN_API_General_Write_Register(state_struct *state, u32 addr,
+ u32 val)
+{
+ if (!state->running) {
+ if (!internal_apb_available(state))
+ return CDN_BSY;
+ internal_tx_mkfullmsg(state, MB_MODULE_ID_GENERAL,
+ GENERAL_WRITE_REGISTER, 2, 4, addr, 4,
+ val);
+ state->bus_type = CDN_BUS_TYPE_APB;
+ return CDN_STARTED;
+ }
+ internal_process_messages(state);
+ return CDN_OK;
+}
+
+CDN_API_STATUS CDN_API_General_Write_Register_blocking(state_struct *state,
+ u32 addr, u32 val)
+{
+ internal_block_function(&state->mutex, CDN_API_General_Write_Register
+ (state, addr, val));
+}
+
+CDN_API_STATUS CDN_API_General_Write_Field(state_struct *state, u32 addr,
+ u8 startBit, u8 bitsNo, u32 val)
+{
+ if (!state->running) {
+ if (!internal_apb_available(state))
+ return CDN_BSY;
+ internal_tx_mkfullmsg(state, MB_MODULE_ID_GENERAL,
+ GENERAL_WRITE_FIELD, 4, 4, addr, 1,
+ startBit, 1, bitsNo, 4, val);
+ state->bus_type = CDN_BUS_TYPE_APB;
+ return CDN_STARTED;
+ }
+ internal_process_messages(state);
+ return CDN_OK;
+}
+
+CDN_API_STATUS CDN_API_General_Write_Field_blocking(state_struct *state,
+ u32 addr, u8 startBit,
+ u8 bitsNo, u32 val)
+{
+ internal_block_function(&state->mutex, CDN_API_General_Write_Field
+ (state, addr, startBit, bitsNo, val));
+}
+
+CDN_API_STATUS CDN_API_General_Phy_Test_Access(state_struct *state, u8 *resp)
+{
+ CDN_API_STATUS ret;
+
+ *resp = 0;
+
+ if (!state->running) {
+ if (!internal_apb_available(state))
+ return CDN_BSY;
+
+ internal_tx_mkfullmsg(state, MB_MODULE_ID_GENERAL,
+ GENERAL_TEST_ACCESS, 0);
+ state->bus_type = CDN_BUS_TYPE_APB;
+ state->rxEnable = 1;
+
+ return CDN_STARTED;
+ }
+
+ internal_process_messages(state);
+
+ ret =
+ internal_test_rx_head(state, MB_MODULE_ID_GENERAL,
+ GENERAL_TEST_ACCESS);
+
+ if (ret != CDN_OK)
+ return ret;
+
+ internal_readmsg(state, 1, 1, resp);
+
+ return CDN_OK;
+}
+
+CDN_API_STATUS CDN_API_General_Phy_Test_Access_blocking(state_struct *state,
+ u8 *resp)
+{
+ internal_block_function(&state->mutex, CDN_API_General_Phy_Test_Access(state, resp));
+}
+
+CDN_API_STATUS CDN_API_General_GetHpdState(state_struct *state, u8 *hpd_state)
+{
+ CDN_API_STATUS ret;
+ *hpd_state = 0;
+
+ if (!state->running) {
+ if (!internal_apb_available(state))
+ return CDN_BSY;
+ internal_tx_mkfullmsg(state, MB_MODULE_ID_GENERAL, GENERAL_GET_HPD_STATE, 0);
+ state->bus_type = CDN_BUS_TYPE_APB;
+ state->rxEnable = 1;
+ return CDN_STARTED;
+ }
+
+ internal_process_messages(state);
+ ret = internal_test_rx_head(state, MB_MODULE_ID_GENERAL, GENERAL_GET_HPD_STATE);
+ if (ret != CDN_OK)
+ return ret;
+
+ internal_readmsg(state, 1, 1, hpd_state);
+
+ return CDN_OK;
+}
+
+CDN_API_STATUS CDN_API_General_GetHpdState_blocking(state_struct *state, u8 *hpd_state)
+{
+ internal_block_function(&state->mutex, CDN_API_General_GetHpdState(state, hpd_state));
+}
diff --git a/drivers/mxc/hdp/API_General.h b/drivers/mxc/hdp/API_General.h
new file mode 100644
index 000000000000..1a17a208288a
--- /dev/null
+++ b/drivers/mxc/hdp/API_General.h
@@ -0,0 +1,248 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2016-2017 Cadence Design Systems, Inc.
+ * All rights reserved worldwide.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 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.
+ *
+ * Copyright 2017-2018 NXP
+ *
+ ******************************************************************************
+ *
+ * API_General.h
+ *
+ ******************************************************************************
+ */
+
+#ifndef API_GENERAL_H_
+#define API_GENERAL_H_
+
+#include <linux/types.h>
+#include <linux/string.h>
+#include <linux/io.h>
+#include "util.h"
+
+#define GENERAL_TEST_ECHO_MAX_PAYLOAD 100
+#define GENERAL_TEST_ECHO_MIN_PAYLOAD 1
+
+/**
+ * GENERAL_Read_Register response struct
+ */
+typedef struct {
+ u32 addr;
+ u32 val;
+} GENERAL_Read_Register_response;
+
+/**
+ * \brief set up API, must be called before any other API call
+ */
+void CDN_API_Init(state_struct *state);
+
+/**
+ * \brief Loads firmware
+ *
+ * \param iMem - pointer to instruction memory
+ * \param imemSize - size of instruction memory buffer
+ * \param dMem - pointer to data memory
+ * \param dmemSize - size of data memory buffer
+ * \return 0 if success, 1 if apb error encountered, 2 if CPU isn't alive after loading firmware
+ *
+ * This function does not require initialisation by #CDN_API_Init
+ */
+
+CDN_API_STATUS CDN_API_LoadFirmware(state_struct *state, u8 *iMem,
+ int imemSize, u8 *dMem, int dmemSize);
+
+/**
+ * \brief debug echo command for APB
+ * \param val - value to echo
+ * \return status
+ *
+ * will return #CDN_ERROR if reply message doesn't match request
+ */
+CDN_API_STATUS CDN_API_General_Test_Echo(state_struct *state, u32 val,
+ CDN_BUS_TYPE bus_type);
+
+/**
+ * \brief blocking version of #CDN_API_General_Test_Echo
+ */
+CDN_API_STATUS CDN_API_General_Test_Echo_blocking(state_struct *state, u32 val,
+ CDN_BUS_TYPE bus_type);
+
+/**
+ * \brief Extended Echo test for mailbox.
+ *
+ * This test will send msg buffer to firmware's mailbox and receive it back to
+ * the resp buffer. Received data will be check against data sent and status will
+ * be returned as well as received data.
+ *
+ * \param msg - Pointer to a buffer to send.
+ * \param resp - Pointer to buffer for receiving msg payload back.
+ * \param num_bytes - Number of bytes to send and receive.
+ * \param bus_type Bus type.
+ * \return status
+ *
+ * will return #CDN_ERROR if reply message doesn't match request or if
+ * arguments are invalid.
+ */
+CDN_API_STATUS CDN_API_General_Test_Echo_Ext(state_struct *state,
+ u8 const *msg, u8 *resp,
+ u16 num_bytes,
+ CDN_BUS_TYPE bus_type);
+
+/**
+ * \brief blocking version of #CDN_API_General_Test_Echo_Ext
+ */
+CDN_API_STATUS CDN_API_General_Test_Echo_Ext_blocking(state_struct *state,
+ u8 const *msg, u8 *resp,
+ u16 num_bytes,
+ CDN_BUS_TYPE bus_type);
+
+/**
+ * \brief get current version
+ * \param [out] ver - fw version
+ * \param [out] libver - lib version
+ * \return status
+ *
+ * this fucntion does not require #CDN_API_Init
+ */
+CDN_API_STATUS CDN_API_General_getCurVersion(state_struct *state, u16 *ver,
+ u16 *verlib);
+
+/**
+ * \brief read event value
+ * \param [out] event - pointer to store 32-bit events value
+ * \return status
+ *
+ * this function does not require #CDN_API_Init
+ */
+CDN_API_STATUS CDN_API_Get_Event(state_struct *state, u32 *events);
+
+/**
+ * \brief read debug register value
+ * \param [out] val - pointer to store 16-bit debug reg value
+ * \return status
+ *
+ * this function does not require #CDN_API_Init
+ */
+CDN_API_STATUS CDN_API_Get_Debug_Reg_Val(state_struct *state, u16 *val);
+
+/**
+ * \brief check if KEEP_ALIVE register changed
+ * \return #CDN_BSY if KEEP_ALIVE not changed, #CDN_OK if changed and #CDN_ERR if error occured while reading
+ */
+CDN_API_STATUS CDN_API_CheckAlive(state_struct *state);
+
+/**
+ * \breif blocking version of #CDN_API_CheckAlive
+ * blocks untill KEEP_ALIVE register changes or error occurs while reading
+ */
+CDN_API_STATUS CDN_API_CheckAlive_blocking(state_struct *state);
+
+/**
+ * \brief set cpu to standby or active
+ * \param [in] state - 1 for active, 0 for standby
+ * \return status
+ */
+CDN_API_STATUS CDN_API_MainControl(state_struct *state, u8 mode, u8 *resp);
+
+/**
+ * \breif blocking version of #CDN_API_MainControl
+ */
+CDN_API_STATUS CDN_API_MainControl_blocking(state_struct *state, u8 mode,
+ u8 *resp);
+
+/**
+ * \brief settings for APB
+ *
+ * Sends GENERAL_APB_CONF Command via regular Mailbox.
+ * @param dpcd_bus_sel Set DPCD to use selected bus (0 for APB or 1 for SAPB)
+ * @param dpcd_bus_lock Lock bus type. Aftern that bus type cannot be changed
+ * by using this function.
+ * @param hdcp_bus_sel Same meaning as for DPCD but for HDCP.
+ * @param hdcp_bus_lock Same meaning as for DPCD but for HDCP.
+ * @param capb_bus_sel Same meaning as for DPCD but for Cipher APB.
+ * @param capb_bus_lock Same meaning as for DPCD but for Cipher APB.
+ * @param dpcd_resp [out] Status of the operation.
+ * If set to zero then DPCD bus type was successfuly changed.
+ * If not then error occurred, most likely due to locked DPCD bus.
+ * @param hdcp_resp [out] Same as for DPCD but for HDCP.
+ * @param capb_resp [out] Same as for DPCD but for Cipher APB.
+ *
+ * \return status
+ */
+CDN_API_STATUS CDN_API_ApbConf(state_struct *state, u8 dpcd_bus_sel,
+ u8 dpcd_bus_lock, u8 hdcp_bus_sel,
+ u8 hdcp_bus_lock, u8 capb_bus_sel,
+ u8 capb_bus_lock, u8 *dpcd_resp, u8 *hdcp_resp,
+ u8 *capb_resp);
+
+/**
+ * blocking version of #CDN_API_MainControl
+ */
+CDN_API_STATUS CDN_API_ApbConf_blocking(state_struct *state, u8 dpcd_bus_sel,
+ u8 dpcd_bus_lock,
+ u8 hdcp_bus_sel,
+ u8 hdcp_bus_lock,
+ u8 capb_bus_sel,
+ u8 capb_bus_lock,
+ u8 *dpcd_resp,
+ u8 *hdcp_resp, u8 *capb_resp);
+
+/**
+ * \brief set the xtensa clk, write this api before turn on the cpu
+ */
+CDN_API_STATUS CDN_API_SetClock(state_struct *state, u8 MHz);
+
+CDN_API_STATUS CDN_API_GetClock(state_struct *state, u32 *MHz);
+
+CDN_API_STATUS CDN_API_General_Read_Register(state_struct *state, u32 addr,
+ GENERAL_Read_Register_response *resp);
+CDN_API_STATUS CDN_API_General_Read_Register_blocking(state_struct *state,
+ u32 addr, GENERAL_Read_Register_response *resp);
+CDN_API_STATUS CDN_API_General_Write_Register(state_struct *state, u32 addr,
+ u32 val);
+CDN_API_STATUS CDN_API_General_Write_Register_blocking(state_struct *state,
+ u32 addr, u32 val);
+CDN_API_STATUS CDN_API_General_Write_Field(state_struct *state, u32 addr,
+ u8 startBit, u8 bitsNo, u32 val);
+CDN_API_STATUS CDN_API_General_Write_Field_blocking(state_struct *state,
+ u32 addr, u8 startBit,
+ u8 bitsNo, u32 val);
+CDN_API_STATUS CDN_API_General_Phy_Test_Access(state_struct *state, u8 *resp);
+CDN_API_STATUS CDN_API_General_Phy_Test_Access_blocking(state_struct *state,
+ u8 *resp);
+CDN_API_STATUS CDN_API_General_GetHpdState(state_struct *state, u8 *hpd_state);
+
+CDN_API_STATUS CDN_API_General_GetHpdState_blocking(state_struct *state, u8 *hpd_state);
+#endif
diff --git a/drivers/mxc/hdp/API_HDCP.c b/drivers/mxc/hdp/API_HDCP.c
new file mode 100644
index 000000000000..603869eb8354
--- /dev/null
+++ b/drivers/mxc/hdp/API_HDCP.c
@@ -0,0 +1,447 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2016-2017 Cadence Design Systems, Inc.
+ * All rights reserved worldwide.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 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.
+ *
+ * Copyright 2017 NXP
+ *
+ ******************************************************************************
+ *
+ * API_HDCP.c
+ *
+ ******************************************************************************
+ */
+
+#include "API_HDCP.h"
+#include "util.h"
+#include "address.h"
+#include "opcodes.h"
+#include "hdcp2.h"
+
+CDN_API_STATUS CDN_API_HDCP_TX_CONFIGURATION(state_struct *state, u8 val,
+ CDN_BUS_TYPE bus_type)
+{
+ if (!state->running) {
+ if (!internal_apb_available(state))
+ return CDN_BSY;
+ state->bus_type = bus_type;
+ internal_tx_mkfullmsg(state, MB_MODULE_ID_HDCP_TX,
+ HDCP_TX_CONFIGURATION, 1, 1, val);
+ return CDN_STARTED;
+ }
+ if (state->txEnable && !internal_mbox_tx_process(state).txend)
+ return CDN_BSY;
+ state->running = 0;
+ return CDN_OK;
+}
+
+CDN_API_STATUS CDN_API_HDCP_TX_CONFIGURATION_blocking(state_struct *state,
+ u8 val,
+ CDN_BUS_TYPE bus_type)
+{
+ internal_block_function(&state->mutex, CDN_API_HDCP_TX_CONFIGURATION
+ (state, val, bus_type));
+}
+
+CDN_API_STATUS
+CDN_API_HDCP2_TX_SET_PUBLIC_KEY_PARAMS(state_struct *state,
+ S_HDCP_TRANS_PUBLIC_KEY_PARAMS *val,
+ CDN_BUS_TYPE bus_type)
+{
+ if (!state->running) {
+ if (!internal_apb_available(state))
+ return CDN_BSY;
+ state->bus_type = bus_type;
+ internal_tx_mkfullmsg(state, MB_MODULE_ID_HDCP_TX,
+ HDCP2_TX_SET_PUBLIC_KEY_PARAMS, 2,
+ -sizeof(val->N), &val->N, -sizeof(val->E),
+ &val->E);
+ return CDN_STARTED;
+ }
+ if (state->txEnable && !internal_mbox_tx_process(state).txend)
+ return CDN_BSY;
+ state->running = 0;
+ return CDN_OK;
+}
+
+CDN_API_STATUS
+CDN_API_HDCP2_TX_SET_PUBLIC_KEY_PARAMS_blocking(state_struct *state,
+ S_HDCP_TRANS_PUBLIC_KEY_PARAMS *val,
+ CDN_BUS_TYPE bus_type)
+{
+ internal_block_function(&state->mutex, CDN_API_HDCP2_TX_SET_PUBLIC_KEY_PARAMS
+ (state, val, bus_type));
+}
+
+CDN_API_STATUS CDN_API_HDCP2_TX_SET_KM_KEY_PARAMS(state_struct *state,
+ S_HDCP_TRANS_KM_KEY_PARAMS *val,
+ CDN_BUS_TYPE bus_type)
+{
+ if (!state->running) {
+ if (!internal_apb_available(state))
+ return CDN_BSY;
+
+ state->bus_type = bus_type;
+ internal_tx_mkfullmsg(state, MB_MODULE_ID_HDCP_TX,
+ HDCP2_TX_SET_KM_KEY_PARAMS, 1,
+ -sizeof(val->KM_KEY), &val->KM_KEY);
+
+ return CDN_STARTED;
+ }
+
+ if (state->txEnable && !internal_mbox_tx_process(state).txend)
+ return CDN_BSY;
+
+ state->running = 0;
+
+ return CDN_OK;
+}
+
+CDN_API_STATUS
+CDN_API_HDCP2_TX_SET_KM_KEY_PARAMS_blocking(state_struct *state,
+ S_HDCP_TRANS_KM_KEY_PARAMS *val,
+ CDN_BUS_TYPE bus_type)
+{
+ internal_block_function(&state->mutex, CDN_API_HDCP2_TX_SET_KM_KEY_PARAMS
+ (state, val, bus_type));
+}
+
+CDN_API_STATUS
+CDN_API_HDCP2_TX_SET_DEBUG_RANDOM_NUMBERS(state_struct *state,
+ S_HDCP_TRANS_DEBUG_RANDOM_NUMBERS *val,
+ CDN_BUS_TYPE bus_type)
+{
+ if (!state->running) {
+ if (!internal_apb_available(state))
+ return CDN_BSY;
+ state->bus_type = bus_type;
+ internal_tx_mkfullmsg(state, MB_MODULE_ID_HDCP_TX,
+ HDCP2_TX_SET_DEBUG_RANDOM_NUMBERS, 5,
+ -sizeof(val->km), &val->km,
+ -sizeof(val->rn), &val->rn,
+ -sizeof(val->ks), &val->ks,
+ -sizeof(val->riv), &val->riv,
+ -sizeof(val->rtx), &val->rtx);
+ return CDN_STARTED;
+ }
+ if (state->txEnable && !internal_mbox_tx_process(state).txend)
+ return CDN_BSY;
+ state->running = 0;
+ return CDN_OK;
+}
+
+CDN_API_STATUS CDN_API_HDCP2_TX_SET_DEBUG_RANDOM_NUMBERS_blocking(
+ state_struct *state,
+ S_HDCP_TRANS_DEBUG_RANDOM_NUMBERS *val,
+ CDN_BUS_TYPE bus_type)
+{
+ internal_block_function(&state->mutex, CDN_API_HDCP2_TX_SET_DEBUG_RANDOM_NUMBERS
+ (state, val, bus_type));
+}
+
+CDN_API_STATUS CDN_API_HDCP2_TX_RESPOND_KM(state_struct *state,
+ S_HDCP_TRANS_PAIRING_DATA *val,
+ CDN_BUS_TYPE bus_type)
+{
+ if (!state->running) {
+ if (!internal_apb_available(state))
+ return CDN_BSY;
+ state->bus_type = bus_type;
+ /* pairing info found in storage */
+ if (val != NULL)
+ internal_tx_mkfullmsg(state, MB_MODULE_ID_HDCP_TX,
+ HDCP2_TX_RESPOND_KM, 4,
+ -sizeof(val->receiver_id),
+ &val->receiver_id,
+ -sizeof(val->m), &val->m,
+ -sizeof(val->km), &val->km,
+ -sizeof(val->ekh), &val->ekh);
+ else
+ /* no pairing info found in storage */
+ internal_tx_mkfullmsg(state, MB_MODULE_ID_HDCP_TX,
+ HDCP2_TX_RESPOND_KM, 0);
+ return CDN_STARTED;
+ }
+ if (state->txEnable && !internal_mbox_tx_process(state).txend)
+ return CDN_BSY;
+ state->running = 0;
+ return CDN_OK;
+}
+
+CDN_API_STATUS CDN_API_HDCP2_TX_RESPOND_KM_blocking(state_struct *state,
+ S_HDCP_TRANS_PAIRING_DATA *val,
+ CDN_BUS_TYPE bus_type)
+{
+ internal_block_function(&state->mutex, CDN_API_HDCP2_TX_RESPOND_KM
+ (state, val, bus_type));
+}
+
+CDN_API_STATUS
+CDN_API_HDCP1_TX_SEND_KEYS(state_struct *state,
+ S_HDCP_TX_MAIL_BOX_CMD_HDCP1_TX_SEND_KEYS *val,
+ CDN_BUS_TYPE bus_type)
+{
+ if (!state->running) {
+ if (!internal_apb_available(state))
+ return CDN_BSY;
+ state->bus_type = bus_type;
+ internal_tx_mkfullmsg(state, MB_MODULE_ID_HDCP_TX,
+ HDCP1_TX_SEND_KEYS, 2, -sizeof(val->AKSV),
+ &val->AKSV, -sizeof(val->KSV), &val->KSV);
+ return CDN_STARTED;
+ }
+ if (state->txEnable && !internal_mbox_tx_process(state).txend)
+ return CDN_BSY;
+ state->running = 0;
+ return CDN_OK;
+}
+
+CDN_API_STATUS
+CDN_API_HDCP1_TX_SEND_KEYS_blocking(state_struct *state,
+ S_HDCP_TX_MAIL_BOX_CMD_HDCP1_TX_SEND_KEYS *val,
+ CDN_BUS_TYPE bus_type)
+{
+ internal_block_function(&state->mutex, CDN_API_HDCP1_TX_SEND_KEYS
+ (state, val, bus_type));
+}
+
+CDN_API_STATUS CDN_API_HDCP1_TX_SEND_RANDOM_AN(state_struct *state, u8 An[8],
+ CDN_BUS_TYPE bus_type)
+{
+ if (!state->running) {
+ if (!internal_apb_available(state))
+ return CDN_BSY;
+ state->bus_type = bus_type;
+ internal_tx_mkfullmsg(state, MB_MODULE_ID_HDCP_TX,
+ HDCP1_TX_SEND_RANDOM_AN, 1, -8, An);
+ return CDN_STARTED;
+ }
+ if (state->txEnable && !internal_mbox_tx_process(state).txend)
+ return CDN_BSY;
+ state->running = 0;
+ return CDN_OK;
+}
+
+CDN_API_STATUS CDN_API_HDCP1_TX_SEND_RANDOM_AN_blocking(state_struct *state,
+ u8 An[8], CDN_BUS_TYPE bus_type)
+{
+ internal_block_function(&state->mutex, CDN_API_HDCP1_TX_SEND_RANDOM_AN
+ (state, An, bus_type));
+}
+
+CDN_API_STATUS CDN_API_HDCP_TX_STATUS_REQ(state_struct *state,
+ u8 *resp, CDN_BUS_TYPE bus_type)
+{
+ if (!state->running) {
+ if (!internal_apb_available(state))
+ return CDN_BSY;
+ state->bus_type = bus_type;
+ state->rxEnable = 1;
+ internal_tx_mkfullmsg(state, MB_MODULE_ID_HDCP_TX,
+ HDCP_TX_STATUS_CHANGE, 0);
+ return CDN_STARTED;
+ }
+ internal_process_messages(state);
+ internal_opcode_match_or_return(state);
+ internal_readmsg(state, 1, -5, resp);
+ return CDN_OK;
+}
+
+CDN_API_STATUS CDN_API_HDCP_TX_STATUS_REQ_blocking(state_struct *state,
+ u8 resp[5],
+ CDN_BUS_TYPE bus_type)
+{
+ internal_block_function(&state->mutex, CDN_API_HDCP_TX_STATUS_REQ
+ (state, resp, bus_type));
+}
+
+CDN_API_STATUS CDN_API_HDCP2_TX_IS_KM_STORED_REQ(state_struct *state,
+ u8 resp[5],
+ CDN_BUS_TYPE bus_type)
+{
+ if (!state->running) {
+ if (!internal_apb_available(state))
+ return CDN_BSY;
+ state->bus_type = bus_type;
+ state->rxEnable = 1;
+ internal_tx_mkfullmsg(state, MB_MODULE_ID_HDCP_TX,
+ HDCP2_TX_IS_KM_STORED, 0);
+ return CDN_STARTED;
+ }
+ internal_process_messages(state);
+ internal_opcode_match_or_return(state);
+ internal_readmsg(state, 1, -5, resp);
+ return CDN_OK;
+}
+
+CDN_API_STATUS CDN_API_HDCP2_TX_IS_KM_STORED_REQ_blocking(state_struct *state,
+ u8 resp[5],
+ CDN_BUS_TYPE bus_type)
+{
+ internal_block_function(&state->mutex, CDN_API_HDCP2_TX_IS_KM_STORED_REQ
+ (state, resp, bus_type));
+}
+
+CDN_API_STATUS CDN_API_HDCP2_TX_STORE_KM_REQ(state_struct *state,
+ S_HDCP_TRANS_PAIRING_DATA *resp,
+ CDN_BUS_TYPE bus_type)
+{
+ if (!state->running) {
+ if (!internal_apb_available(state))
+ return CDN_BSY;
+ state->bus_type = bus_type;
+ state->rxEnable = 1;
+ internal_tx_mkfullmsg(state, MB_MODULE_ID_HDCP_TX,
+ HDCP2_TX_STORE_KM, 0);
+ return CDN_STARTED;
+ }
+ internal_process_messages(state);
+ internal_opcode_match_or_return(state);
+ internal_readmsg(state, 4,
+ -sizeof(resp->receiver_id), &resp->receiver_id,
+ -sizeof(resp->m), &resp->m,
+ -sizeof(resp->km), &resp->km,
+ -sizeof(resp->ekh), &resp->ekh);
+ return CDN_OK;
+}
+
+CDN_API_STATUS CDN_API_HDCP2_TX_STORE_KM_REQ_blocking(state_struct *state,
+ S_HDCP_TRANS_PAIRING_DATA
+ *resp,
+ CDN_BUS_TYPE bus_type)
+{
+ internal_block_function(&state->mutex, CDN_API_HDCP2_TX_STORE_KM_REQ
+ (state, resp, bus_type));
+}
+
+CDN_API_STATUS CDN_API_HDCP_TX_IS_RECEIVER_ID_VALID_REQ(state_struct *state,
+ u8 *num, u8 *id,
+ CDN_BUS_TYPE bus_type)
+{
+ if (!state->running) {
+ if (!internal_apb_available(state))
+ return CDN_BSY;
+ state->bus_type = bus_type;
+ state->rxEnable = 1;
+ internal_tx_mkfullmsg(state, MB_MODULE_ID_HDCP_TX,
+ HDCP_TX_IS_RECEIVER_ID_VALID, 0);
+ return CDN_STARTED;
+ }
+ internal_process_messages(state);
+ internal_opcode_match_or_return(state);
+ internal_readmsg(state, 1, 1, num);
+ internal_readmsg(state, 2, 1, NULL, -5 * *num, id);
+ return CDN_OK;
+}
+
+CDN_API_STATUS CDN_API_HDCP_TX_IS_RECEIVER_ID_VALID_REQ_blocking(
+ state_struct *state,
+ u8 *num,
+ u8 *id,
+ CDN_BUS_TYPE
+ bus_type)
+{
+ internal_block_function(&state->mutex, CDN_API_HDCP_TX_IS_RECEIVER_ID_VALID_REQ
+ (state, num, id, bus_type));
+}
+
+CDN_API_STATUS CDN_API_HDCP_TX_RESPOND_RECEIVER_ID_VALID(
+ state_struct *state,
+ u8 valid,
+ CDN_BUS_TYPE bus_type)
+{
+ if (!state->running) {
+ if (!internal_apb_available(state))
+ return CDN_BSY;
+ state->bus_type = bus_type;
+ internal_tx_mkfullmsg(state, MB_MODULE_ID_HDCP_TX,
+ HDCP_TX_RESPOND_RECEIVER_ID_VALID, 1, 1,
+ valid);
+ return CDN_STARTED;
+ }
+ internal_process_messages(state);
+ return CDN_OK;
+}
+
+CDN_API_STATUS CDN_API_HDCP_TX_RESPOND_RECEIVER_ID_VALID_blocking(
+ state_struct *state,
+ u8 valid,
+ CDN_BUS_TYPE
+ bus_type)
+{
+ internal_block_function(&state->mutex, CDN_API_HDCP_TX_RESPOND_RECEIVER_ID_VALID
+ (state, valid, bus_type));
+}
+
+CDN_API_STATUS CDN_API_HDCP_GENERAL_2_SET_LC(state_struct *state, u8 *lc,
+ CDN_BUS_TYPE bus_type)
+{
+ internal_macro_command_tx(state, MB_MODULE_ID_HDCP_GENERAL,
+ HDCP_GENERAL_SET_LC_128, bus_type, 1, -16, lc);
+ return CDN_OK;
+}
+
+CDN_API_STATUS CDN_API_HDCP_GENERAL_2_SET_LC_blocking(state_struct *state,
+ u8 *lc,
+ CDN_BUS_TYPE bus_type)
+{
+ internal_block_function(&state->mutex, CDN_API_HDCP_GENERAL_2_SET_LC
+ (state, lc, bus_type));
+}
+
+CDN_API_STATUS CDN_API_TEST_KEYS(state_struct *state, u8 test_type, u8 resp[1],
+ CDN_BUS_TYPE bus_type)
+{
+ if (!state->running) {
+ if (!internal_apb_available(state))
+ return CDN_BSY;
+ state->bus_type = bus_type;
+ state->rxEnable = 1;
+ internal_tx_mkfullmsg(state, MB_MODULE_ID_HDCP_TX,
+ HDCP_TX_TEST_KEYS, 1, 1, test_type);
+ return CDN_STARTED;
+ }
+ internal_process_messages(state);
+ internal_opcode_match_or_return(state);
+ internal_readmsg(state, 1, -1, resp);
+ return CDN_OK;
+}
+
+CDN_API_STATUS CDN_API_TEST_KEYS_blocking(state_struct *state, u8 test_type,
+ u8 resp[1], CDN_BUS_TYPE bus_type)
+{
+ internal_block_function(&state->mutex, CDN_API_TEST_KEYS
+ (state, test_type, resp, bus_type));
+}
diff --git a/drivers/mxc/hdp/API_HDCP.h b/drivers/mxc/hdp/API_HDCP.h
new file mode 100644
index 000000000000..ca523225abab
--- /dev/null
+++ b/drivers/mxc/hdp/API_HDCP.h
@@ -0,0 +1,263 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2016-2017 Cadence Design Systems, Inc.
+ * All rights reserved worldwide.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 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.
+ *
+ * Copyright 2017 NXP
+ *
+ ******************************************************************************
+ *
+ * API_HDCP.h
+ *
+ ******************************************************************************
+ */
+
+#ifndef _API_HDCP_H_
+#define _API_HDCP_H_
+
+/**
+ * \addtogroup HDCP_API
+ * \{
+ */
+
+#include "API_General.h"
+#include "hdcp_tran.h"
+
+/**
+ * \brief send HDCP_TX_CONFIGURATION command
+ * \return status
+ */
+CDN_API_STATUS CDN_API_HDCP_TX_CONFIGURATION(state_struct *state, u8 val,
+ CDN_BUS_TYPE bus_type);
+
+/**
+ * \brief blocking version of #CDN_API_HDCP_TX_CONFIGURATION
+ */
+CDN_API_STATUS CDN_API_HDCP_TX_CONFIGURATION_blocking(state_struct *state,
+ u8 val,
+ CDN_BUS_TYPE bus_type);
+
+/**
+ * \brief send HDCP2_TX_SET_PUBLIC_KEY_PARAMS command
+ * \return status
+ */
+CDN_API_STATUS
+CDN_API_HDCP2_TX_SET_PUBLIC_KEY_PARAMS(state_struct *state,
+ S_HDCP_TRANS_PUBLIC_KEY_PARAMS *val,
+ CDN_BUS_TYPE bus_type);
+
+/**
+ * \brief blocking version of #CDN_API_HDCP2_TX_SET_PUBLIC_KEY_PARAMS
+ */
+CDN_API_STATUS
+CDN_API_HDCP2_TX_SET_PUBLIC_KEY_PARAMS_blocking(state_struct *state,
+ S_HDCP_TRANS_PUBLIC_KEY_PARAMS *val,
+ CDN_BUS_TYPE bus_type);
+
+/**
+ * \brief send HDCP2_TX_SET_KM_KEY_PARAMS command
+ * \return status
+ */
+CDN_API_STATUS CDN_API_HDCP2_TX_SET_KM_KEY_PARAMS(state_struct *state,
+ S_HDCP_TRANS_KM_KEY_PARAMS *val,
+ CDN_BUS_TYPE bus_type);
+
+/**
+ * \brief blocking version of #CDN_API_HDCP2_TX_SET_KM_KEY_PARAMS
+ */
+CDN_API_STATUS
+CDN_API_HDCP2_TX_SET_KM_KEY_PARAMS_blocking(state_struct *state,
+ S_HDCP_TRANS_KM_KEY_PARAMS *val,
+ CDN_BUS_TYPE bus_type);
+
+/**
+ * \brief send HDCP2_TX_SET_DEBUG_RANDOM_NUMBERS command
+ * \return status
+ */
+CDN_API_STATUS
+CDN_API_HDCP2_TX_SET_DEBUG_RANDOM_NUMBERS(state_struct *state,
+ S_HDCP_TRANS_DEBUG_RANDOM_NUMBERS *val,
+ CDN_BUS_TYPE bus_type);
+
+/**
+ * \brief blocking version of #CDN_API_HDCP2_TX_SET_DEBUG_RANDOM_NUMBERS
+ */
+CDN_API_STATUS
+ CDN_API_HDCP2_TX_SET_DEBUG_RANDOM_NUMBERS_blocking
+ (state_struct *state, S_HDCP_TRANS_DEBUG_RANDOM_NUMBERS *val,
+ CDN_BUS_TYPE bus_type);
+
+/**
+ * \brief send HDCP2_TX_RESPOND_KM command
+ * \param val - if NULL no arguments will be send
+ * \return status
+ */
+CDN_API_STATUS CDN_API_HDCP2_TX_RESPOND_KM(state_struct *state,
+ S_HDCP_TRANS_PAIRING_DATA *val,
+ CDN_BUS_TYPE bus_type);
+
+/**
+ * \brief blocking version of #CDN_API_HDCP2_TX_RESPOND_KM
+ */
+CDN_API_STATUS CDN_API_HDCP2_TX_RESPOND_KM_blocking(state_struct *state,
+ S_HDCP_TRANS_PAIRING_DATA *val,
+ CDN_BUS_TYPE bus_type);
+
+/**
+ * \brief send HDCP1_TX_SEND_KEYS command
+ * \return status
+ */
+CDN_API_STATUS
+CDN_API_HDCP1_TX_SEND_KEYS(state_struct *state,
+ S_HDCP_TX_MAIL_BOX_CMD_HDCP1_TX_SEND_KEYS *val,
+ CDN_BUS_TYPE bus_type);
+
+/**
+ * \brief blocking version of #CDN_API_HDCP1_TX_SEND_KEYS
+ */
+CDN_API_STATUS
+CDN_API_HDCP1_TX_SEND_KEYS_blocking(state_struct *state,
+ S_HDCP_TX_MAIL_BOX_CMD_HDCP1_TX_SEND_KEYS *val,
+ CDN_BUS_TYPE bus_type);
+
+/**
+ * \brief send HDCP1_TX_SEND_RANDOM_AN command
+ * \return status
+ */
+CDN_API_STATUS CDN_API_HDCP1_TX_SEND_RANDOM_AN(state_struct *state, u8 An[8],
+ CDN_BUS_TYPE bus_type);
+
+/**
+ * \brief blocking version of #CDN_API_HDCP1_TX_SEND_RANDOM_AN
+ */
+CDN_API_STATUS CDN_API_HDCP1_TX_SEND_RANDOM_AN_blocking(state_struct *state,
+ u8 An[8],
+ CDN_BUS_TYPE bus_type);
+
+/**
+ * \brief send HDCP_TX_STATUS_REQ command
+ * \return status
+ */
+CDN_API_STATUS CDN_API_HDCP_TX_STATUS_REQ(state_struct *state, u8 resp[5],
+ CDN_BUS_TYPE bus_type);
+
+/**
+ * \brief blocking version of #CDN_API_HDCP_TX_STATUS_REQ
+ */
+CDN_API_STATUS CDN_API_HDCP_TX_STATUS_REQ_blocking(state_struct *state,
+ u8 resp[5],
+ CDN_BUS_TYPE bus_type);
+
+/**
+ * \brief send HDCP2_TX_IS_KM_STORED_REQ command
+ * \return status
+ */
+CDN_API_STATUS CDN_API_HDCP2_TX_IS_KM_STORED_REQ(state_struct *state,
+ u8 resp[5],
+ CDN_BUS_TYPE bus_type);
+
+/**
+ * \brief blocking version of #CDN_API_HDCP2_TX_IS_KM_STORED_REQ
+ */
+CDN_API_STATUS CDN_API_HDCP2_TX_IS_KM_STORED_REQ_blocking(state_struct *state,
+ u8 resp[5],
+ CDN_BUS_TYPE
+ bus_type);
+
+/**
+ * \brief send HDCP2_TX_STORE_KM_REQ command
+ * \return status
+ */
+CDN_API_STATUS CDN_API_HDCP2_TX_STORE_KM_REQ(state_struct *state,
+ S_HDCP_TRANS_PAIRING_DATA *resp,
+ CDN_BUS_TYPE bus_type);
+
+/**
+ * \brief blocking version of #CDN_API_HDCP2_TX_STORE_KM_REQ
+ */
+CDN_API_STATUS CDN_API_HDCP2_TX_STORE_KM_REQ_blocking(state_struct *state,
+ S_HDCP_TRANS_PAIRING_DATA
+ *resp,
+ CDN_BUS_TYPE bus_type);
+
+/**
+ * \brief send HDCP_TX_IS_RECEIVER_ID_VALID_REQ command
+ * \return status
+ */
+CDN_API_STATUS CDN_API_HDCP_TX_IS_RECEIVER_ID_VALID_REQ(state_struct *state,
+ u8 *num, u8 *id,
+ CDN_BUS_TYPE bus_type);
+
+/**
+ * \brief blocking version of #CDN_API_HDCP_TX_IS_RECEIVER_ID_VALID_REQ
+ */
+CDN_API_STATUS CDN_API_HDCP_TX_IS_RECEIVER_ID_VALID_REQ_blocking(state_struct *state,
+ u8 *num,
+ u8 *id,
+ CDN_BUS_TYPE
+ bus_type);
+
+/**
+ * \brief send HDCP_TX_RESPOND_RECEIVER_ID_VALID command
+ * \return status
+ */
+CDN_API_STATUS CDN_API_HDCP_TX_RESPOND_RECEIVER_ID_VALID(state_struct *state,
+ u8 valid,
+ CDN_BUS_TYPE bus_type);
+
+/**
+ * \brief blocking version of #CDN_API_HDCP_TX_RESPOND_RECEIVER_ID_VALID
+ */
+CDN_API_STATUS CDN_API_HDCP_TX_RESPOND_RECEIVER_ID_VALID_blocking(state_struct *state,
+ u8 valid,
+ CDN_BUS_TYPE
+ bus_type);
+
+CDN_API_STATUS CDN_API_HDCP_GENERAL_2_SET_LC(state_struct *state, u8 *lc,
+ CDN_BUS_TYPE bus_type);
+CDN_API_STATUS CDN_API_HDCP_GENERAL_2_SET_LC_blocking(state_struct *state,
+ u8 *lc,
+ CDN_BUS_TYPE bus_type);
+/* TODO DK: Implement */
+CDN_API_STATUS CDN_API_HDCP_SET_SEED(state_struct *state, u8 *seed,
+ CDN_BUS_TYPE bus_type);
+CDN_API_STATUS CDN_API_HDCP_SET_SEED_blocking(state_struct *state, u8 *seed,
+ CDN_BUS_TYPE bus_type);
+CDN_API_STATUS CDN_API_TEST_KEYS(state_struct *state, u8 test_type, u8 resp[1],
+ CDN_BUS_TYPE bus_type);
+CDN_API_STATUS CDN_API_TEST_KEYS_blocking(state_struct *state, u8 test_type,
+ u8 resp[1], CDN_BUS_TYPE bus_type);
+
+#endif
diff --git a/drivers/mxc/hdp/API_HDMIRX.c b/drivers/mxc/hdp/API_HDMIRX.c
new file mode 100644
index 000000000000..7dcb9254fd06
--- /dev/null
+++ b/drivers/mxc/hdp/API_HDMIRX.c
@@ -0,0 +1,236 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2016-2017 Cadence Design Systems, Inc.
+ * All rights reserved worldwide.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 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.
+ *
+ * Copyright 2018 NXP
+ *
+ ******************************************************************************
+ *
+ * API_HDMIRX.c
+ *
+ ******************************************************************************
+ */
+
+#include "API_HDMIRX.h"
+#include "util.h"
+#include "opcodes.h"
+#include "address.h"
+#include "sink_vif.h"
+
+CDN_API_STATUS CDN_API_HDMIRX_ReadEvent(state_struct *state, u8 *Events_5v)
+{
+ CDN_API_STATUS ret;
+ u8 reserved1;
+ u8 reserved2;
+ u8 reserved3;
+ if (!state->running) {
+ if (!internal_apb_available(state))
+ return CDN_BSY;
+ internal_tx_mkfullmsg(state, MB_MODULE_ID_HDMI_RX, HDMI_RX_READ_EVENTS, 0);
+ state->rxEnable = 1;
+ state->bus_type = CDN_BUS_TYPE_APB;
+ return CDN_STARTED;
+ }
+ internal_process_messages(state);
+ ret = internal_test_rx_head(state, MB_MODULE_ID_HDMI_RX, HDMI_RX_READ_EVENTS);
+ if (ret != CDN_OK)
+ return ret;
+ internal_readmsg(state,
+ 4,
+ 1,
+ Events_5v,
+ 1,
+ &reserved1,
+ 1,
+ &reserved2,
+ 1,
+ &reserved3);
+ return CDN_OK;
+}
+
+CDN_API_STATUS CDN_API_HDMIRX_ReadEvent_blocking(
+ state_struct *state,
+ u8 *Events_5v)
+{
+ internal_block_function(&state->mutex, CDN_API_HDMIRX_ReadEvent(state, Events_5v));
+}
+
+CDN_API_STATUS CDN_API_HDMIRX_Init_blocking(state_struct *state)
+{
+ CDN_API_STATUS ret;
+
+ ret =
+ CDN_API_General_Write_Register_blocking(state,
+ ADDR_SINK_VIDEO_HD + (VIDEO_UNPACK_CTRL << 2),
+ F_CD_ENABLE(1));
+ ret =
+ CDN_API_General_Write_Register_blocking(state,
+ ADDR_SINK_VIDEO_HD + (VANLYZ_CTRL << 2),
+ F_VANLYZ_START(1) |
+ F_VANLYZ_FRAMES_CHECK_EN(1) |
+ F_VANLYZ_FORMAT_FINDER_EN(1));
+
+ return ret;
+}
+
+CDN_API_STATUS CDN_API_HDMIRX_Stop_blocking(state_struct *state)
+{
+ CDN_API_STATUS ret;
+
+ ret =
+ CDN_API_General_Write_Register_blocking(state,
+ ADDR_SINK_VIDEO_HD + (VIDEO_UNPACK_CTRL << 2),
+ F_CD_ENABLE(0));
+ ret =
+ CDN_API_General_Write_Register_blocking(state,
+ ADDR_SINK_VIDEO_HD + (VANLYZ_CTRL << 2), F_VANLYZ_RESET(1));
+
+ return ret;
+}
+
+CDN_API_STATUS CDN_API_HDMIRX_SET_EDID(
+ state_struct *state,
+ u8 segment,
+ u8 extension,
+ u8 *edid_buff)
+{
+ if (!state->running) {
+ if (!internal_apb_available(state))
+ return CDN_BSY;
+ internal_tx_mkfullmsg(state,
+ MB_MODULE_ID_HDMI_RX,
+ HDMI_RX_SET_EDID,
+ 3,
+ 1,
+ segment,
+ 1,
+ extension,
+ -128,
+ edid_buff);
+ state->bus_type = CDN_BUS_TYPE_APB;
+ return CDN_STARTED;
+ }
+ internal_process_messages(state);
+ return CDN_OK;
+}
+
+CDN_API_STATUS CDN_API_HDMIRX_SET_EDID_blocking(
+ state_struct *state,
+ u8 segment,
+ u8 extension,
+ u8 *edid_buff)
+{
+ internal_block_function(&state->mutex,
+ CDN_API_HDMIRX_SET_EDID(state, segment, extension, edid_buff));
+}
+
+CDN_API_STATUS CDN_API_HDMIRX_SET_SCDC_SLAVE(state_struct *state,
+ S_HDMI_SCDC_SET_MSG *scdcData)
+{
+ if (!state->running) {
+ if (!internal_apb_available(state))
+ return CDN_BSY;
+ internal_tx_mkfullmsg(state,
+ MB_MODULE_ID_HDMI_RX,
+ HDMI_RX_SCDC_SET,
+ 1,
+ -sizeof(S_HDMI_SCDC_SET_MSG),
+ scdcData);
+ state->bus_type = CDN_BUS_TYPE_APB;
+ return CDN_STARTED;
+ }
+ internal_process_messages(state);
+ return CDN_OK;
+}
+
+CDN_API_STATUS CDN_API_HDMIRX_SET_SCDC_SLAVE_blocking(
+ state_struct *state,
+ S_HDMI_SCDC_SET_MSG *scdcData)
+{
+ internal_block_function(&state->mutex,
+ CDN_API_HDMIRX_SET_SCDC_SLAVE(state, scdcData));
+}
+
+CDN_API_STATUS CDN_API_HDMIRX_GET_SCDC_SLAVE(state_struct *state,
+ S_HDMI_SCDC_GET_MSG *scdcData)
+{
+ CDN_API_STATUS ret;
+ if (!state->running) {
+ if (!internal_apb_available(state))
+ return CDN_BSY;
+ internal_tx_mkfullmsg(state, MB_MODULE_ID_HDMI_RX, HDMI_RX_SCDC_GET, 0);
+ state->bus_type = CDN_BUS_TYPE_APB;
+ state->rxEnable = 1;
+ return CDN_STARTED;
+ }
+ internal_process_messages(state);
+ ret = internal_test_rx_head(state, MB_MODULE_ID_HDMI_RX, HDMI_RX_SCDC_GET);
+ if (ret != CDN_OK)
+ return ret;
+ internal_readmsg(state,
+ 4,
+ 1, &scdcData->source_ver,
+ 1, &scdcData->TMDS_Config,
+ 1, &scdcData->config_0,
+ -sizeof(scdcData->manufacturerSpecific),
+ &scdcData->manufacturerSpecific);
+ return CDN_OK;
+}
+
+CDN_API_STATUS CDN_API_HDMIRX_GET_SCDC_SLAVE_blocking(state_struct *state,
+ S_HDMI_SCDC_GET_MSG *scdcData)
+{
+ internal_block_function(&state->mutex,
+ CDN_API_HDMIRX_GET_SCDC_SLAVE(state, scdcData));
+}
+
+CDN_API_STATUS CDN_API_HDMIRX_SetHpd(state_struct *state, u8 hpd)
+{
+ if (!state->running) {
+ if (!internal_apb_available(state))
+ return CDN_BSY;
+ internal_tx_mkfullmsg(state, MB_MODULE_ID_HDMI_RX, HDMI_RX_SET_HPD, 1, 1, hpd);
+ state->bus_type = CDN_BUS_TYPE_APB;
+ return CDN_STARTED;
+ }
+ internal_process_messages(state);
+ return CDN_OK;
+}
+
+CDN_API_STATUS CDN_API_HDMIRX_SetHpd_blocking(state_struct *state, u8 hpd)
+{
+ internal_block_function(&state->mutex, CDN_API_HDMIRX_SetHpd(state, hpd));
+}
diff --git a/drivers/mxc/hdp/API_HDMIRX.h b/drivers/mxc/hdp/API_HDMIRX.h
new file mode 100644
index 000000000000..4adbe422b7a9
--- /dev/null
+++ b/drivers/mxc/hdp/API_HDMIRX.h
@@ -0,0 +1,135 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2016-2017 Cadence Design Systems, Inc.
+ * All rights reserved worldwide.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 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.
+ *
+ * Copyright 2018 NXP
+ *
+ ******************************************************************************
+ *
+ * API_HDMIRX.h
+ *
+ ******************************************************************************
+ */
+
+#ifndef _API_HDMIRX_H_
+#define _API_HDMIRX_H_
+
+#include "API_General.h"
+#include "hdmi.h"
+
+/**
+ * \addtogroup HDMI_RX_API
+ * \{
+ */
+
+/**
+ * \brief init hdmi rx registers
+ * \returns status
+ */
+CDN_API_STATUS CDN_API_HDMIRX_Init_blocking(state_struct *state);
+CDN_API_STATUS CDN_API_HDMIRX_Stop_blocking(state_struct *state);
+
+/**
+ * \brief get hdmi rx events (currently 5v events)
+ * \returns status
+ */
+CDN_API_STATUS CDN_API_HDMIRX_ReadEvent(state_struct *state, u8 *Events_5v);
+
+/**
+ * \brief blocking version of CDN_API_HDMIRX_ReadEvent
+ * \returns status
+ */
+CDN_API_STATUS CDN_API_HDMIRX_ReadEvent_blocking(state_struct *state, u8 *Events_5v);
+
+
+/**
+ * \brief Cadence API for HDMI TX to set EDID
+ * \param [in] segment - EDID segment to read
+ * \param [in] extension - EDID extension to read
+ * \param [in] edid_buff - pointer to buffer with 128 bytes of edid block
+ * please note, edid_buff should be allocated\clear by caller
+ * \return status
+ *
+ */
+CDN_API_STATUS CDN_API_HDMIRX_SET_EDID(state_struct *state, u8 segment, u8 extension, u8 *edid_buff);
+/**
+ * \brief blocking version of #CDN_API_HDMIRX_SET_EDID
+ */
+CDN_API_STATUS CDN_API_HDMIRX_SET_EDID_blocking(state_struct *state, u8 segment, u8 extension, u8 *edid_buff);
+
+/**
+ * \brief Cadence API for HDMI Rx to set general scdc information
+ * \param [in] scdcData - general slave scdc information
+ * \return status
+ *
+ */
+CDN_API_STATUS CDN_API_HDMIRX_SET_SCDC_SLAVE(state_struct *state, S_HDMI_SCDC_SET_MSG *scdcData);
+
+/**
+ * \brief blocking version of #CDN_API_HDMIRX_SET_SCDC_SLAVE
+ */
+CDN_API_STATUS CDN_API_HDMIRX_SET_SCDC_SLAVE_blocking(state_struct *state, S_HDMI_SCDC_SET_MSG *scdcData);
+
+/**
+ * \brief Cadence API for HDMI Rx to get general scdc information
+ * \param [in] source_ver - SCDC register - Source Version
+ * \param [in] TMDS_Config - SCDC register - TMDS_Config
+ * \param [in] config_0 - SCDC register - Config_0
+ * \param [in] manufacturerSpecific - manufacturer specific data
+ * \return status
+ *
+ */
+CDN_API_STATUS CDN_API_HDMIRX_GET_SCDC_SLAVE(state_struct *state, S_HDMI_SCDC_GET_MSG *scdcData);
+
+/**
+ * \brief blocking version of #CDN_API_HDMIRX_GET_SCDC_SLAVE
+ */
+CDN_API_STATUS CDN_API_HDMIRX_GET_SCDC_SLAVE_blocking(state_struct *state, S_HDMI_SCDC_GET_MSG *scdcData);
+
+/**
+ * \brief Cadence API for HDMI Rx to set hpd
+ * \param [in] hpd - 0 or 1
+ * \return status
+ *
+ */
+CDN_API_STATUS CDN_API_HDMIRX_SetHpd(state_struct *state, u8 hpd);
+
+/**
+ * \brief blocking version of #CDN_API_HDMIRX_SetHpd
+ */
+CDN_API_STATUS CDN_API_HDMIRX_SetHpd_blocking(state_struct *state, u8 hpd);
+
+#endif
diff --git a/drivers/mxc/hdp/API_HDMITX.c b/drivers/mxc/hdp/API_HDMITX.c
new file mode 100644
index 000000000000..92e4dd6f1414
--- /dev/null
+++ b/drivers/mxc/hdp/API_HDMITX.c
@@ -0,0 +1,494 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2016-2017 Cadence Design Systems, Inc.
+ * All rights reserved worldwide.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 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.
+ *
+ * Copyright 2017-2018 NXP
+ *
+ ******************************************************************************
+ *
+ * API_HDMITX.c
+ *
+ ******************************************************************************
+ */
+
+#include "API_HDMITX.h"
+#include "util.h"
+#include "opcodes.h"
+#include "mhl_hdtx_top.h"
+#include "source_phy.h"
+#include "address.h"
+#include "source_car.h"
+#include "source_vif.h"
+#include "general_handler.h"
+#include <soc/imx8/soc.h>
+
+CDN_API_STATUS CDN_API_HDMITX_DDC_READ(state_struct *state,
+ HDMITX_TRANS_DATA *data_in,
+ HDMITX_TRANS_DATA *data_out)
+{
+ internal_macro_command_txrx(state, MB_MODULE_ID_HDMI_TX, HDMI_TX_READ,
+ CDN_BUS_TYPE_APB, 3, 1, data_in->slave, 1,
+ data_in->offset, 2, data_in->len);
+ internal_readmsg(state, 5, 1, &data_out->status, 1, &data_out->slave, 1,
+ &data_out->offset, 2, &data_out->len, 0,
+ &data_out->buff);
+ return CDN_OK;
+}
+
+CDN_API_STATUS CDN_API_HDMITX_DDC_READ_blocking(state_struct *state,
+ HDMITX_TRANS_DATA *data_in,
+ HDMITX_TRANS_DATA *data_out)
+{
+ internal_block_function(&state->mutex, CDN_API_HDMITX_DDC_READ
+ (state, data_in, data_out));
+}
+
+CDN_API_STATUS CDN_API_HDMITX_DDC_WRITE(state_struct *state,
+ HDMITX_TRANS_DATA *data_in,
+ HDMITX_TRANS_DATA *data_out)
+{
+ internal_macro_command_txrx(state, MB_MODULE_ID_HDMI_TX, HDMI_TX_WRITE,
+ CDN_BUS_TYPE_APB, 4, 1, data_in->slave, 1,
+ data_in->offset, 2, data_in->len,
+ -data_in->len, data_in->buff);
+ internal_readmsg(state, 4, 1, &data_out->status, 1, &data_out->slave, 1,
+ &data_out->offset, 2, &data_out->len);
+ return CDN_OK;
+}
+
+CDN_API_STATUS CDN_API_HDMITX_DDC_WRITE_blocking(state_struct *state,
+ HDMITX_TRANS_DATA *data_in,
+ HDMITX_TRANS_DATA *data_out)
+{
+ internal_block_function(&state->mutex, CDN_API_HDMITX_DDC_WRITE
+ (state, data_in, data_out));
+}
+
+CDN_API_STATUS CDN_API_HDMITX_DDC_UPDATE_READ(state_struct *state,
+ HDMITX_TRANS_DATA *data_out)
+{
+ internal_macro_command_txrx(state, MB_MODULE_ID_HDMI_TX,
+ HDMI_TX_UPDATE_READ, CDN_BUS_TYPE_APB, 0);
+ internal_readmsg(state, 2, 1, &data_out->status, 0, &data_out->buff);
+ return CDN_OK;
+}
+
+CDN_API_STATUS CDN_API_HDMITX_DDC_UPDATE_READ_blocking(state_struct *state,
+ HDMITX_TRANS_DATA *
+ data_out)
+{
+ internal_block_function(&state->mutex, CDN_API_HDMITX_DDC_UPDATE_READ
+ (state, data_out));
+}
+
+CDN_API_STATUS CDN_API_HDMITX_READ_EDID(state_struct *state, u8 block,
+ u8 segment,
+ HDMITX_TRANS_DATA *data_out)
+{
+ internal_macro_command_txrx(state, MB_MODULE_ID_HDMI_TX, HDMI_TX_EDID,
+ CDN_BUS_TYPE_APB, 2, 1, block, 1, segment);
+ internal_readmsg(state, 5, 1, &data_out->status, 1, &data_out->slave, 1,
+ &data_out->offset, 2, &data_out->len, 0,
+ &data_out->buff);
+ return CDN_OK;
+}
+
+CDN_API_STATUS CDN_API_HDMITX_READ_EDID_blocking(state_struct *state, u8 block,
+ u8 segment,
+ HDMITX_TRANS_DATA *data_out)
+{
+ internal_block_function(&state->mutex, CDN_API_HDMITX_READ_EDID
+ (state, block, segment, data_out));
+}
+
+CDN_API_STATUS
+CDN_API_HDMITX_Set_Mode_blocking(state_struct *state,
+ HDMI_TX_MAIL_HANDLER_PROTOCOL_TYPE protocol,
+ u32 character_rate)
+{
+ CDN_API_STATUS ret;
+ GENERAL_Read_Register_response resp;
+ u32 clk_reg_0, clk_reg_1;
+
+ ret = CDN_API_General_Read_Register_blocking(
+ state, ADDR_SOURCE_MHL_HD + (HDTX_CONTROLLER << 2), &resp);
+ if (ret != CDN_OK)
+ return ret;
+
+ /* remove data enable */
+ resp.val = resp.val & (~(F_DATA_EN(1)));
+ ret =
+ CDN_API_General_Write_Register_blocking(state, ADDR_SOURCE_MHL_HD +
+ (HDTX_CONTROLLER << 2),
+ resp.val);
+ if (ret != CDN_OK)
+ return ret;
+ clk_reg_0 = 0x7c1f;
+ clk_reg_1 = 0x7c1f;
+ if (protocol == HDMI_TX_MODE_HDMI_2_0) {
+ if (character_rate >= 340000) {
+ clk_reg_0 = 0;
+ clk_reg_1 = 0xFFFFF;
+ }
+ }
+ ret = CDN_API_General_Write_Register_blocking(
+ state, ADDR_SOURCE_MHL_HD + (HDTX_CLOCK_REG_0 << 2),
+ F_DATA_REGISTER_VAL_0(clk_reg_0));
+ if (ret != CDN_OK)
+ return ret;
+ ret = CDN_API_General_Write_Register_blocking(
+ state, ADDR_SOURCE_MHL_HD + (HDTX_CLOCK_REG_1 << 2),
+ F_DATA_REGISTER_VAL_1(clk_reg_1));
+ if (ret != CDN_OK)
+ return ret;
+
+ /* set hdmi mode and preemble mode */
+ resp.val = resp.val & (~(F_HDMI_MODE(3)));
+ resp.val = resp.val & (~(F_HDMI2_PREAMBLE_EN(1)));
+
+ resp.val =
+ (resp.val) | (F_HDMI_MODE(protocol)) | (F_HDMI2_PREAMBLE_EN(1));
+ ret =
+ CDN_API_General_Write_Register_blocking(state, ADDR_SOURCE_MHL_HD +
+ (HDTX_CONTROLLER << 2),
+ resp.val);
+ if (ret != CDN_OK)
+ return ret;
+
+ /* data enable */
+ resp.val |= F_DATA_EN(1);
+ ret =
+ CDN_API_General_Write_Register_blocking(state, ADDR_SOURCE_MHL_HD +
+ (HDTX_CONTROLLER << 2),
+ resp.val);
+ return ret;
+}
+
+CDN_API_STATUS CDN_API_HDMITX_Init_blocking(state_struct *state)
+{
+ CDN_API_STATUS ret;
+
+ ret =
+ CDN_API_General_Write_Register_blocking(state, ADDR_SOURCD_PHY +
+ (PHY_DATA_SEL << 2),
+ F_SOURCE_PHY_MHDP_SEL(1));
+ if (ret != CDN_OK)
+ return ret;
+ ret =
+ CDN_API_General_Write_Register_blocking(state, ADDR_SOURCE_MHL_HD +
+ (HDTX_HPD << 2),
+ F_HPD_VALID_WIDTH(4) |
+ F_HPD_GLITCH_WIDTH(0));
+ if (ret != CDN_OK)
+ return ret;
+ ret =
+ CDN_API_General_Write_Register_blocking(state, ADDR_SOURCE_MHL_HD +
+ (HDTX_CONTROLLER << 2),
+ F_HDMI_MODE(1) |
+ F_AUTO_MODE(0) | F_GCP_EN(1)
+ | F_DATA_EN(1) |
+ F_CLEAR_AVMUTE(1) |
+ F_HDMI2_PREAMBLE_EN(1) |
+ F_HDMI2_CTRL_IL_MODE(1) |
+ F_PIC_3D(0XF) |
+ F_BCH_EN(1));
+ if (ret != CDN_OK)
+ return ret;
+ /* open CARS */
+ ret =
+ CDN_API_General_Write_Register_blocking(state, ADDR_SOURCE_CAR +
+ (SOURCE_PHY_CAR << 2), 0xF);
+ if (ret != CDN_OK)
+ return ret;
+ ret =
+ CDN_API_General_Write_Register_blocking(state, ADDR_SOURCE_CAR +
+ (SOURCE_HDTX_CAR << 2),
+ 0xFF);
+ if (ret != CDN_OK)
+ return ret;
+ ret =
+ CDN_API_General_Write_Register_blocking(state, ADDR_SOURCE_CAR +
+ (SOURCE_PKT_CAR << 2), 0xF);
+ if (ret != CDN_OK)
+ return ret;
+ ret =
+ CDN_API_General_Write_Register_blocking(state, ADDR_SOURCE_CAR +
+ (SOURCE_AIF_CAR << 2), 0xF);
+ if (ret != CDN_OK)
+ return ret;
+ ret =
+ CDN_API_General_Write_Register_blocking(state, ADDR_SOURCE_CAR +
+ (SOURCE_CIPHER_CAR << 2),
+ 0xF);
+ if (ret != CDN_OK)
+ return ret;
+ ret =
+ CDN_API_General_Write_Register_blocking(state, ADDR_SOURCE_CAR +
+ (SOURCE_CRYPTO_CAR << 2),
+ 0xF);
+ if (ret != CDN_OK)
+ return ret;
+ ret =
+ CDN_API_General_Write_Register_blocking(state, ADDR_SOURCE_CAR +
+ (SOURCE_CEC_CAR << 2), 3);
+ if (ret != CDN_OK)
+ return ret;
+
+ /* init vif */
+ ret =
+ CDN_API_General_Write_Register_blocking(state, ADDR_SOURCE_VIF +
+ (HSYNC2VSYNC_POL_CTRL << 2),
+ F_HPOL(0) | F_VPOL(0));
+ return ret;
+}
+
+CDN_API_STATUS CDN_API_HDMITX_SetVic_blocking(state_struct *state,
+ struct drm_display_mode *mode, int bpp,
+ VIC_PXL_ENCODING_FORMAT format)
+{
+ CDN_API_STATUS ret;
+ GENERAL_Read_Register_response resp;
+ u32 vsync_lines = mode->vsync_end - mode->vsync_start;
+ u32 eof_lines = mode->vsync_start - mode->vdisplay;
+ u32 sof_lines = mode->vtotal - mode->vsync_end;
+ u32 hblank = mode->htotal - mode->hdisplay;
+ u32 hactive = mode->hdisplay;
+ u32 vblank = mode->vtotal - mode->vdisplay;
+ u32 vactive = mode->vdisplay;
+ u32 hfront = mode->hsync_start - mode->hdisplay;
+ u32 hback = mode->htotal - mode->hsync_end;
+ u32 vfront = eof_lines;
+ u32 hsync = hblank - hfront - hback;
+ u32 vsync = vsync_lines;
+ u32 vback = sof_lines;
+ u32 v_h_polarity = ((mode->flags & DRM_MODE_FLAG_NHSYNC) ? 0 : 1) +
+ ((mode->flags & DRM_MODE_FLAG_NVSYNC) ? 0 : 2);
+
+ ret = CDN_API_General_Write_Register_blocking(state, ADDR_SOURCE_MHL_HD +
+ (SCHEDULER_H_SIZE << 2),
+ (hactive << 16) + hblank);
+ if (ret != CDN_OK)
+ return ret;
+
+ ret = CDN_API_General_Write_Register_blocking(state, ADDR_SOURCE_MHL_HD +
+ (SCHEDULER_V_SIZE << 2),
+ (vactive << 16) + vblank);
+ if (ret != CDN_OK)
+ return ret;
+
+ ret = CDN_API_General_Write_Register_blocking(state, ADDR_SOURCE_MHL_HD +
+ (HDTX_SIGNAL_FRONT_WIDTH <<
+ 2),
+ (vfront << 16) + hfront);
+ if (ret != CDN_OK)
+ return ret;
+
+ ret = CDN_API_General_Write_Register_blocking(state, ADDR_SOURCE_MHL_HD +
+ (HDTX_SIGNAL_SYNC_WIDTH <<
+ 2), (vsync << 16) + hsync);
+ if (ret != CDN_OK)
+ return ret;
+
+ ret = CDN_API_General_Write_Register_blocking(state, ADDR_SOURCE_MHL_HD +
+ (HDTX_SIGNAL_BACK_WIDTH <<
+ 2), (vback << 16) + hback);
+ if (ret != CDN_OK)
+ return ret;
+
+ ret = CDN_API_General_Write_Register_blocking(state, ADDR_SOURCE_VIF +
+ (HSYNC2VSYNC_POL_CTRL << 2),
+ v_h_polarity);
+ if (ret != CDN_OK)
+ return ret;
+
+ /* Reset Data Enable */
+ ret = CDN_API_General_Read_Register_blocking(state, ADDR_SOURCE_MHL_HD +
+ (HDTX_CONTROLLER << 2), &resp);
+ if (ret != CDN_OK)
+ return ret;
+
+ /* reset data enable */
+ resp.val = resp.val & (~(F_DATA_EN(1)));
+ ret = CDN_API_General_Write_Register_blocking(state, ADDR_SOURCE_MHL_HD +
+ (HDTX_CONTROLLER << 2),
+ resp.val);
+ if (ret != CDN_OK)
+ return ret;
+
+ /* set bpp */
+ resp.val = resp.val & (~(F_VIF_DATA_WIDTH(3)));
+ switch (bpp) {
+ case 8:
+ resp.val = resp.val | (F_VIF_DATA_WIDTH(0));
+ break;
+
+ case 10:
+ resp.val = resp.val | (F_VIF_DATA_WIDTH(1));
+ break;
+
+ case 12:
+ resp.val = resp.val | (F_VIF_DATA_WIDTH(2));
+ break;
+
+ case 16:
+ resp.val = resp.val | (F_VIF_DATA_WIDTH(3));
+ break;
+ }
+
+ /* select color encoding */
+ resp.val = resp.val & (~(F_HDMI_ENCODING(3)));
+ switch (format) {
+ case PXL_RGB:
+
+ resp.val = resp.val | (F_HDMI_ENCODING(0));
+ break;
+
+ case YCBCR_4_4_4:
+ resp.val = resp.val | (F_HDMI_ENCODING(2));
+ break;
+
+ case YCBCR_4_2_2:
+ resp.val = resp.val | (F_HDMI_ENCODING(1));
+ break;
+
+ case YCBCR_4_2_0:
+ resp.val = resp.val | (F_HDMI_ENCODING(3));
+ break;
+ case Y_ONLY:
+ /* not exist in hdmi */
+ break;
+ }
+
+ ret =
+ CDN_API_General_Write_Register_blocking(state, ADDR_SOURCE_MHL_HD +
+ (HDTX_CONTROLLER << 2),
+ resp.val);
+ if (ret != CDN_OK)
+ return ret;
+
+ /* set data enable */
+ resp.val = resp.val | (F_DATA_EN(1));
+ ret =
+ CDN_API_General_Write_Register_blocking(state, ADDR_SOURCE_MHL_HD +
+ (HDTX_CONTROLLER << 2),
+ resp.val);
+ if (ret != CDN_OK)
+ return ret;
+ return ret;
+}
+
+CDN_API_STATUS CDN_API_HDMITX_Disable_GCP(state_struct *state)
+{
+ GENERAL_Read_Register_response resp;
+
+ CDN_API_General_Read_Register_blocking(state, ADDR_SOURCE_MHL_HD +(HDTX_CONTROLLER<<2), &resp);
+ resp.val = resp.val & (~F_GCP_EN(1));
+ return CDN_API_General_Write_Register_blocking(state,
+ ADDR_SOURCE_MHL_HD +(HDTX_CONTROLLER<<2), resp.val);
+}
+
+CDN_API_STATUS CDN_API_HDMITX_ForceColorDepth_blocking(state_struct *state,
+ u8 force, u8 val)
+{
+ u32 valToWrite = F_COLOR_DEPTH_VAL(val) | F_COLOR_DEPTH_FORCE(force);
+ return CDN_API_General_Write_Register_blocking(state,
+ ADDR_SOURCE_MHL_HD +
+ (GCP_FORCE_COLOR_DEPTH_CODING
+ << 2), valToWrite);
+
+}
+
+CDN_API_STATUS CDN_API_HDMITX_ReadEvents(state_struct *state,
+ uint32_t *events)
+{
+ CDN_API_STATUS ret;
+
+ if (!state->running) {
+ if (!internal_apb_available(state))
+ return CDN_BSY;
+
+ internal_tx_mkfullmsg(state, MB_MODULE_ID_HDMI_TX,
+ HDMI_TX_EVENTS, 0);
+ state->rxEnable = 1;
+ state->bus_type = CDN_BUS_TYPE_APB;
+
+ return CDN_STARTED;
+ }
+
+ internal_process_messages(state);
+
+ ret =
+ internal_test_rx_head(state, MB_MODULE_ID_HDMI_TX, HDMI_TX_EVENTS);
+
+ if (ret != CDN_OK)
+ return ret;
+
+ internal_readmsg(state, 1, 4, events);
+
+ return CDN_OK;
+}
+
+CDN_API_STATUS CDN_API_HDMITX_ReadEvents_blocking(state_struct *state,
+ uint32_t *events)
+{
+ internal_block_function(&state->mutex, CDN_API_HDMITX_ReadEvents(state, events));
+}
+
+CDN_API_STATUS CDN_API_HDMITX_GetHpdStatus(state_struct *state, u8 *hpd_sts)
+{
+ CDN_API_STATUS ret;
+ if (!state->running) {
+ if (!internal_apb_available(state))
+ return CDN_BSY;
+ internal_tx_mkfullmsg(state, MB_MODULE_ID_GENERAL, GENERAL_GET_HPD_STATE, 0);
+ state->rxEnable = 1;
+ state->bus_type = CDN_BUS_TYPE_APB;
+ return CDN_STARTED;
+ }
+ internal_process_messages(state);
+ ret =
+ internal_test_rx_head(state, MB_MODULE_ID_GENERAL, GENERAL_GET_HPD_STATE);
+ if (ret != CDN_OK)
+ return ret;
+ internal_readmsg(state, 1, 1, hpd_sts);
+ return CDN_OK;
+}
+
+CDN_API_STATUS CDN_API_HDMITX_GetHpdStatus_blocking(state_struct *state,
+ u8 *hpd_sts)
+{
+ internal_block_function(&state->mutex, CDN_API_HDMITX_GetHpdStatus(state, hpd_sts));
+}
diff --git a/drivers/mxc/hdp/API_HDMITX.h b/drivers/mxc/hdp/API_HDMITX.h
new file mode 100644
index 000000000000..0f64cc272037
--- /dev/null
+++ b/drivers/mxc/hdp/API_HDMITX.h
@@ -0,0 +1,165 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2016-2017 Cadence Design Systems, Inc.
+ * All rights reserved worldwide.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 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.
+ *
+ * Copyright 2017 NXP
+ *
+ ******************************************************************************
+ *
+ * API_HDMITX.h
+ *
+ ******************************************************************************
+ */
+
+#ifndef _API_HDMITX_H_
+#define _API_HDMITX_H_
+
+#include "API_General.h"
+#include "hdmi.h"
+
+/**
+ * \addtogroup HDMI_TX_API
+ * \{
+ */
+
+# define HDMI_TX_EVENT_CODE_HPD_HIGH 0x01
+# define HDMI_TX_EVENT_CODE_HPD_LOW 0x02
+# define HDMI_TX_EVENT_CODE_HPD_STATE_LOW 0x00
+# define HDMI_TX_EVENT_CODE_HPD_STATE_HIGH 0x08
+typedef struct {
+ /** if used to return data, this pointer is set (instead of being a destination to copy data to */
+ u8 *buff;
+ HDMI_I2C_STATUS status;
+ u16 len;
+ u8 slave;
+ u8 offset;
+} HDMITX_TRANS_DATA;
+
+typedef enum {
+ HDMI_TX_MODE_DVI,
+ HDMI_TX_MODE_HDMI_1_4,
+ HDMI_TX_MODE_HDMI_2_0,
+} HDMI_TX_MAIL_HANDLER_PROTOCOL_TYPE;
+
+/**
+ * \brief I2C read transaction
+ * \param [in] data_in - fields used: len, slave, offset
+ * \param [out] data_out - fields used: all
+ * \returns status
+ */
+CDN_API_STATUS CDN_API_HDMITX_DDC_READ(state_struct *state,
+ HDMITX_TRANS_DATA *data_in,
+ HDMITX_TRANS_DATA *data_out);
+CDN_API_STATUS CDN_API_HDMITX_DDC_READ_blocking(state_struct *state,
+ HDMITX_TRANS_DATA *data_in,
+ HDMITX_TRANS_DATA *data_out);
+
+/**
+ * \brief I2C write transaction
+ * \param [in] data_in - fields used: len, slave, offset, buff
+ * \param [out] data_out - fields used: status, len, slave, offset
+ * \returns status
+ */
+CDN_API_STATUS CDN_API_HDMITX_DDC_WRITE(state_struct *state,
+ HDMITX_TRANS_DATA *data_in,
+ HDMITX_TRANS_DATA *data_out);
+CDN_API_STATUS CDN_API_HDMITX_DDC_WRITE_blocking(state_struct *state,
+ HDMITX_TRANS_DATA *data_in,
+ HDMITX_TRANS_DATA *data_out);
+
+/**
+ * \brief I2C update read
+ * \param [out] data_out - fields used: status, buff
+ * \returns status
+ */
+CDN_API_STATUS CDN_API_HDMITX_DDC_UPDATE_READ(state_struct *state,
+ HDMITX_TRANS_DATA *data_out);
+CDN_API_STATUS CDN_API_HDMITX_DDC_UPDATE_READ_blocking(state_struct *state,
+ HDMITX_TRANS_DATA *
+ data_out);
+
+/**
+ * \brief I2C read edid
+ * \param [in] block - EDID block
+ * \pram [in] segment - EDID segment
+ * \param [out] data_out - fields used: status, buff, slave (as block), offset (as segment), len
+ * \returns status
+ */
+CDN_API_STATUS CDN_API_HDMITX_READ_EDID(state_struct *state, u8 block,
+ u8 segment,
+ HDMITX_TRANS_DATA *data_out);
+CDN_API_STATUS CDN_API_HDMITX_READ_EDID_blocking(state_struct *state, u8 block,
+ u8 segment,
+ HDMITX_TRANS_DATA *data_out);
+
+/**
+ * \brief set hdmi protocol type (DVI,1.x,2.x) (send scrambler command over scdc and set bits in controller)
+ * \param [in] protocol - type
+ * \returns status
+ */
+CDN_API_STATUS
+CDN_API_HDMITX_Set_Mode_blocking(state_struct *state,
+ HDMI_TX_MAIL_HANDLER_PROTOCOL_TYPE protocol,
+ u32 character_rate);
+
+/**
+ * \brief init hdmi registers
+ * \returns status
+ */
+CDN_API_STATUS CDN_API_HDMITX_Init_blocking(state_struct *state);
+
+/**
+ * \brief change to vid id vicMode
+ * \returns status
+ */
+CDN_API_STATUS CDN_API_HDMITX_SetVic_blocking(state_struct *state,
+ struct drm_display_mode *mode, int bpp,
+ VIC_PXL_ENCODING_FORMAT format);
+
+/**
+ * \brief option to force color depth in the gcp or not force (HW mode)
+ * \returns status
+ */
+CDN_API_STATUS CDN_API_HDMITX_ForceColorDepth_blocking(state_struct *state,
+ u8 force, u8 val);
+CDN_API_STATUS CDN_API_HDMITX_ReadEvents(state_struct *state, u32 *events);
+CDN_API_STATUS CDN_API_HDMITX_ReadEvents_blocking(state_struct *state,
+ u32 *events);
+CDN_API_STATUS CDN_API_HDMITX_GetHpdStatus(state_struct *state, u8 *hpd_sts);
+CDN_API_STATUS CDN_API_HDMITX_GetHpdStatus_blocking(state_struct *state,
+ u8 *hpd_sts);
+CDN_API_STATUS CDN_API_HDMITX_Disable_GCP(state_struct *state);
+#endif
diff --git a/drivers/mxc/hdp/API_HDMI_RX_Audio.c b/drivers/mxc/hdp/API_HDMI_RX_Audio.c
new file mode 100644
index 000000000000..1d1442c731ff
--- /dev/null
+++ b/drivers/mxc/hdp/API_HDMI_RX_Audio.c
@@ -0,0 +1,191 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2016-2017 Cadence Design Systems, Inc.
+ * All rights reserved worldwide.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 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.
+ *
+ * Copyright 2018 NXP
+ *
+ ******************************************************************************
+ *
+ * API_HDMI_RX_Audio.c
+ *
+ ******************************************************************************
+ */
+
+#include "API_HDMI_RX_Audio.h"
+#include "sink_aif_encoder.h"
+#include "aif_pckt2smp.h"
+#include "address.h"
+#include "util.h"
+#include "API_General.h"
+
+CDN_API_STATUS CDN_API_RX_AudioAutoConfig(
+ state_struct *state,
+ u8 max_ch_num,
+ u8 i2s_ports_num,
+ u8 dis_port3,
+ u8 enc_sample_width,
+ u8 i2s_sample_width)
+{
+ u32 regread;
+ u8 num_of_pairs_of_channels_per_port = max_ch_num / (i2s_ports_num * 2);
+ u8 enc_size_code;
+ u8 i2s_size_code;
+ u8 i2s_port3_dis = (dis_port3 != 0 && i2s_ports_num == 4) ? 1 : 0;
+ u8 times = 0;
+
+ /* Valid values: 1/2/4. */
+ /* 3 ports can be emulated with 'i2s_ports_num = 4' and 'dis_port3 = 1'. */
+ if (i2s_ports_num == 0 || i2s_ports_num == 3 || i2s_ports_num > 4)
+ return CDN_ERR;
+
+ /* 'dis_port3' makes sense only with 4 ports enabled */
+ if (dis_port3 != 0 && i2s_ports_num < 4)
+ return CDN_ERR;
+
+ switch (enc_sample_width) {
+ case 16:
+ enc_size_code = 0x0;
+ break;
+ case 24:
+ enc_size_code = 0x1;
+ break;
+ case 32:
+ enc_size_code = 0x2;
+ break;
+ default:
+ return CDN_ERR;
+ }
+
+ switch (i2s_sample_width) {
+ case 16:
+ i2s_size_code = 0x0;
+ break;
+ case 24:
+ i2s_size_code = 0x1;
+ break;
+ case 32:
+ i2s_size_code = 0x2;
+ break;
+ default:
+ return CDN_ERR;
+ }
+
+ /* Maximum number of channels has to be in range from 2 to 32 */
+ if (max_ch_num < 2 || max_ch_num > 32)
+ return CDN_ERR;
+ /* Maximum number of channels has to be power of 2 */
+ else if (!(max_ch_num * (max_ch_num - 1)))
+ return CDN_ERR;
+ /* Each active port shall carry the same number of sub-channels */
+ else if (max_ch_num % i2s_ports_num)
+ return CDN_ERR;
+
+ /* Disable ACR during configuration */
+ if (cdn_apb_write(state, ADDR_AIF_ENCODER + (ACR_CFG << 2), F_ACR_SW_RESET(1)))
+ return CDN_ERR;
+
+ /* Configuring audio FIFO */
+ if (cdn_apb_write(state,
+ ADDR_AIF_ENCODER + ((0x40 + FIFO_CNTL_ADDR) << 2),
+ F_CFG_FIFO_SW_RST(0) | F_CFG_INDEX_SYNC_EN(1) |
+ F_CFG_FIFO_DIR(1) | F_CFG_DIS_PORT3(i2s_port3_dis)))
+ return CDN_ERR;
+
+ /* Configuring audio parameters */
+ if (cdn_apb_write(state,
+ ADDR_AIF_ENCODER + ((0x40 + AUDIO_SINK_CNFG) << 2),
+ F_ENC_LOW_INDEX_MSB(0) | F_SINK_AUDIO_CH_NUM(max_ch_num - 1) |
+ F_ENC_SAMPLE_JUST(0x0) | F_ENC_SMPL_WIDTH(enc_size_code) |
+ F_I2S_ENC_WL_SIZE(i2s_size_code) | F_CNTL_SMPL_ONLY_EN(1) |
+ F_CNTL_TYPE_OVRD(0x0) | F_CNTL_TYPE_OVRD_EN(0) |
+ F_I2S_ENC_PORT_EN((1 << i2s_ports_num) - 1) | F_WS_POLARITY(0)))
+ return CDN_ERR;
+
+ /* Waiting for N value... */
+ do {
+ if (cdn_apb_read(state,
+ ADDR_AIF_ENCODER + (AIF_ACR_N_ST << 2), &regread))
+ return CDN_ERR;
+ times++;
+ udelay(10);
+ } while (!(regread) && times < 100);
+
+ if (times == 100)
+ return CDN_ERR;
+
+ /* Enable ACR */
+ if (cdn_apb_write(state,
+ ADDR_AIF_ENCODER + (ACR_CFG << 2), F_ACR_SW_RESET(0)))
+ return CDN_ERR;
+
+ /* Important: */
+ /* Write to AIF_ACR_N_OFST_CFG register is interpreted as new N_CTS value. */
+ /* The ACR has to be enabled (reset released) to register that event. */
+
+ if (cdn_apb_write(state,
+ ADDR_AIF_ENCODER + (AIF_ACR_N_OFST_CFG << 2),
+ F_ACR_N_OFFSET(regread * (num_of_pairs_of_channels_per_port - 1))))
+ return CDN_ERR;
+
+ /* Enable sample decoder */
+ if (cdn_apb_write(state,
+ ADDR_AIF_ENCODER + (PKT2SMPL_CNTL << 2), F_PKT2SMPL_EN(1)))
+ return CDN_ERR;
+
+ /* Enable I2S encoder */
+ if (cdn_apb_write(state,
+ ADDR_AIF_ENCODER + ((0x40 + AUDIO_SINK_CNTL) << 2), F_I2S_ENC_START(1)))
+ return CDN_ERR;
+
+ return CDN_OK;
+
+}
+
+CDN_API_STATUS CDN_API_RX_AudioAutoConfig_blocking(state_struct *state,
+ u8 max_ch_num,
+ u8 i2s_ports_num,
+ u8 dis_port3,
+ u8 enc_sample_width,
+ u8 i2s_sample_width)
+{
+ internal_block_function(&state->mutex,
+ CDN_API_RX_AudioAutoConfig(state,
+ max_ch_num,
+ i2s_ports_num,
+ dis_port3,
+ enc_sample_width,
+ i2s_sample_width));
+}
diff --git a/drivers/mxc/hdp/API_HDMI_RX_Audio.h b/drivers/mxc/hdp/API_HDMI_RX_Audio.h
new file mode 100644
index 000000000000..3dc0c2819527
--- /dev/null
+++ b/drivers/mxc/hdp/API_HDMI_RX_Audio.h
@@ -0,0 +1,80 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2016-2017 Cadence Design Systems, Inc.
+ * All rights reserved worldwide.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 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.
+ *
+ * Copyright 2018 NXP
+ *
+ ******************************************************************************
+ *
+ * API_HDMI_RX_Audio.h
+ *
+ ******************************************************************************
+ */
+
+#ifndef API_HDMI_RX_AUDIO_H_
+#define API_HDMI_RX_AUDIO_H_
+
+#include "API_General.h"
+
+/**
+ * \addtogroup AUDIO_API
+ * \{
+ */
+
+/**
+ * \brief start audio reception with the input parameters
+ */
+CDN_API_STATUS CDN_API_RX_AudioAutoConfig(
+ state_struct *state,
+ u8 max_ch_num,
+ u8 i2s_ports_num,
+ u8 dis_port3,
+ u8 enc_sample_width,
+ u8 i2s_sample_width);
+
+/**
+ * \brief blocking version of #CDN_API_RX_AudioAutoConfig
+ */
+CDN_API_STATUS CDN_API_RX_AudioAutoConfig_blocking(
+ state_struct *state,
+ u8 max_ch_num,
+ u8 i2s_ports_num,
+ u8 dis_port3,
+ u8 enc_sample_width,
+ u8 i2s_sample_width);
+
+#endif
+
diff --git a/drivers/mxc/hdp/API_Infoframe.c b/drivers/mxc/hdp/API_Infoframe.c
new file mode 100644
index 000000000000..a42010e57c9a
--- /dev/null
+++ b/drivers/mxc/hdp/API_Infoframe.c
@@ -0,0 +1,166 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2016-2017 Cadence Design Systems, Inc.
+ * All rights reserved worldwide.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 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.
+ *
+ * Copyright 2017 NXP
+ *
+ ******************************************************************************
+ *
+ * API_Infoframe.c
+ *
+ ******************************************************************************
+ */
+
+#include "API_Infoframe.h"
+#include "address.h"
+#include "source_pif.h"
+#include "util.h"
+
+#define BANK_OFFSET 0x0
+
+static CDN_API_STATUS infoframeSet(state_struct *state, u8 entry_id,
+ u8 packet_len,
+ u8 *packet, u8 packet_type, u8 active_idle)
+{
+ u32 idx;
+ u32 *packet32, len;
+ u32 activeIdleBit = (0 == active_idle) ? 0 : 0x20000;
+
+ /* invalidate entry */
+ if (cdn_apb_write
+ (state,
+ BANK_OFFSET | ADDR_SOURCE_PIF | (SOURCE_PIF_PKT_ALLOC_REG << 2),
+ activeIdleBit | F_PKT_ALLOC_ADDRESS(entry_id)))
+ return CDN_ERR;
+ if (cdn_apb_write
+ (state,
+ BANK_OFFSET | ADDR_SOURCE_PIF | (SOURCE_PIF_PKT_ALLOC_WR_EN << 2),
+ F_PKT_ALLOC_WR_EN(1)))
+ return CDN_ERR;
+
+ /* flush fifo 1 */
+ if (cdn_apb_write
+ (state,
+ BANK_OFFSET | ADDR_SOURCE_PIF | (SOURCE_PIF_FIFO1_FLUSH << 2),
+ F_FIFO1_FLUSH(1)))
+ return CDN_ERR;
+
+ /* write packet into memory */
+ packet32 = (u32 *)packet;
+ len = packet_len / 4;
+ for (idx = 0; idx < len; idx++)
+ if (cdn_apb_write
+ (state,
+ BANK_OFFSET | ADDR_SOURCE_PIF | (SOURCE_PIF_DATA_WR << 2),
+ F_DATA_WR(packet32[idx])))
+ return CDN_ERR;
+
+ /* write entry id */
+ if (cdn_apb_write
+ (state, BANK_OFFSET | ADDR_SOURCE_PIF | (SOURCE_PIF_WR_ADDR << 2),
+ F_WR_ADDR(entry_id)))
+ return CDN_ERR;
+
+ /* write request */
+ if (cdn_apb_write
+ (state, BANK_OFFSET | ADDR_SOURCE_PIF | (SOURCE_PIF_WR_REQ << 2),
+ F_HOST_WR(1)))
+ return CDN_ERR;
+
+ /* update entry */
+ if (cdn_apb_write
+ (state,
+ BANK_OFFSET | ADDR_SOURCE_PIF | (SOURCE_PIF_PKT_ALLOC_REG << 2),
+ activeIdleBit | F_TYPE_VALID(1) | F_PACKET_TYPE(packet_type) |
+ F_PKT_ALLOC_ADDRESS(entry_id)))
+ return CDN_ERR;
+ if (cdn_apb_write
+ (state,
+ BANK_OFFSET | ADDR_SOURCE_PIF | (SOURCE_PIF_PKT_ALLOC_WR_EN << 2),
+ F_PKT_ALLOC_WR_EN(1)))
+ return CDN_ERR;
+
+ return CDN_OK;
+}
+
+CDN_API_STATUS CDN_API_InfoframeSet(state_struct *state, u8 entry_id,
+ u8 packet_len, u8 *packet, u8 packet_type)
+{
+ return infoframeSet(state, entry_id, packet_len, packet, packet_type,
+ 1);
+}
+
+CDN_API_STATUS CDN_API_InfoframeSetNoActiveIdle(state_struct *state,
+ u8 entry_id, u8 packet_len,
+ u8 *packet, u8 packet_type)
+{
+ return infoframeSet(state, entry_id, packet_len, packet, packet_type,
+ 0);
+}
+
+CDN_API_STATUS CDN_API_InfoframeRemove(state_struct *state, u8 entry_id)
+{
+ /* invalidate entry */
+ if (cdn_apb_write
+ (state,
+ BANK_OFFSET | ADDR_SOURCE_PIF | (SOURCE_PIF_PKT_ALLOC_REG << 2),
+ 0x20000 | F_PKT_ALLOC_ADDRESS(entry_id)))
+ return CDN_ERR;
+ if (cdn_apb_write
+ (state,
+ BANK_OFFSET | ADDR_SOURCE_PIF | (SOURCE_PIF_PKT_ALLOC_WR_EN << 2),
+ F_PKT_ALLOC_WR_EN(1)))
+ return CDN_ERR;
+
+ return CDN_OK;
+}
+
+CDN_API_STATUS CDN_API_InfoframeRemovePacket(state_struct *state, u8 entry_id, u8 packet_type)
+{
+ /* invalidate entry */
+ if (cdn_apb_write
+ (state,
+ BANK_OFFSET | ADDR_SOURCE_PIF | (SOURCE_PIF_PKT_ALLOC_REG << 2),
+ 0x20000 | F_PKT_ALLOC_ADDRESS(entry_id) | F_PACKET_TYPE(packet_type)))
+ return CDN_ERR;
+ if (cdn_apb_write
+ (state,
+ BANK_OFFSET | ADDR_SOURCE_PIF | (SOURCE_PIF_PKT_ALLOC_WR_EN << 2),
+ F_PKT_ALLOC_WR_EN(1)))
+ return CDN_ERR;
+
+ return CDN_OK;
+}
diff --git a/drivers/mxc/hdp/API_Infoframe.h b/drivers/mxc/hdp/API_Infoframe.h
new file mode 100644
index 000000000000..15aa27387dc4
--- /dev/null
+++ b/drivers/mxc/hdp/API_Infoframe.h
@@ -0,0 +1,64 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2016-2017 Cadence Design Systems, Inc.
+ * All rights reserved worldwide.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 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.
+ *
+ * Copyright 2017 NXP
+ *
+ ******************************************************************************
+ *
+ * API_Infoframe.h
+ *
+ ******************************************************************************
+ */
+
+#ifndef API_INFOFRAME_H
+#define API_INFOFRAME_H
+
+#include "API_General.h"
+/**
+ * \addtogroup INFO_FRAME_API
+ * \{
+ */
+CDN_API_STATUS CDN_API_InfoframeSet(state_struct *state, u8 entry_id,
+ u8 packet_len, u8 *packet,
+ u8 packet_type);
+CDN_API_STATUS CDN_API_InfoframeSetNoActiveIdle(state_struct *state,
+ u8 entry_id, u8 packet_len,
+ u8 *packet, u8 packet_type);
+CDN_API_STATUS CDN_API_InfoframeRemove(state_struct *state, u8 entry_id);
+CDN_API_STATUS CDN_API_InfoframeRemovePacket(state_struct *state, u8 entry_id, u8 packet_type);
+
+#endif
diff --git a/drivers/mxc/hdp/Kconfig b/drivers/mxc/hdp/Kconfig
new file mode 100644
index 000000000000..fe98359c5c07
--- /dev/null
+++ b/drivers/mxc/hdp/Kconfig
@@ -0,0 +1,5 @@
+config MX8_HDP
+ tristate "IMX8 HDP API "
+
+config MX8_HDP_RX
+ tristate "IMX8 HDP RX API "
diff --git a/drivers/mxc/hdp/Makefile b/drivers/mxc/hdp/Makefile
new file mode 100644
index 000000000000..363cdba3fe41
--- /dev/null
+++ b/drivers/mxc/hdp/Makefile
@@ -0,0 +1,13 @@
+obj-$(CONFIG_MX8_HDP) += \
+ API_Audio.o \
+ API_AFE.o \
+ API_General.o \
+ API_HDCP.o \
+ API_HDMITX.o \
+ API_Infoframe.o \
+ API_DPTX.o \
+ util.o
+
+obj-$(CONFIG_MX8_HDP_RX) += \
+ API_HDMIRX.o \
+ API_HDMI_RX_Audio.o
diff --git a/drivers/mxc/hdp/address.h b/drivers/mxc/hdp/address.h
new file mode 100644
index 000000000000..59a68a631645
--- /dev/null
+++ b/drivers/mxc/hdp/address.h
@@ -0,0 +1,109 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2016-2017 Cadence Design Systems, Inc.
+ * All rights reserved worldwide.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 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.
+ *
+ * Copyright 2017 NXP
+ *
+ ******************************************************************************
+ *
+ * address.h
+ *
+ ******************************************************************************
+ */
+
+#ifndef ADDRESS_H_
+#define ADDRESS_H_
+
+#define ADDR_IMEM 0x10000
+#define ADDR_DMEM 0x20000
+#define ADDR_CIPHER 0x60000
+#define BASE_CIPHER 0x600
+#define ADDR_APB_CFG 0x00000
+#define BASE_APB_CFG 0x000
+#define ADDR_SOURCE_AIF_DECODER 0x30000
+#define BASE_SOURCE_AIF_DECODER 0x300
+#define ADDR_SOURCE_AIF_SMPL2PCKT 0x30080
+#define BASE_SOURCE_AIF_SMPL2PCKT 0x300
+#define ADDR_AIF_ENCODER 0x30000
+#define BASE_AIF_ENCODER 0x300
+#define ADDR_SOURCE_PIF 0x30800
+#define BASE_SOURCE_PIF 0x308
+#define ADDR_SINK_PIF 0x30800
+#define BASE_SINK_PIF 0x308
+#define ADDR_APB_CFG 0x00000
+#define BASE_APB_CFG 0x000
+#define ADDR_SOURCE_CSC 0x40000
+#define BASE_SOURCE_CSC 0x400
+#define ADDR_UCPU_CFG 0x00000
+#define BASE_UCPU_CFG 0x000
+#define ADDR_SOURCE_CAR 0x00900
+#define BASE_SOURCE_CAR 0x009
+#define ADDR_SINK_CAR 0x00900
+#define BASE_SINK_CAR 0x009
+#define ADDR_CLOCK_METERS 0x00A00
+#define BASE_CLOCK_METERS 0x00A
+#define ADDR_SOURCE_VIF 0x00b00
+#define BASE_SOURCE_VIF 0x00b
+#define ADDR_SINK_MHL_HD 0x01000
+#define ADDR_SINK_VIDEO_HD 0x01800
+#define BASE_SINK_MHL_HD 0x010
+#define ADDR_SINK_CORE 0x07800
+#define BASE_SINK_CORE 0x078
+#define ADDR_DPTX_PHY 0x02000
+#define BASE_DPTX_PHY 0x020
+#define ADDR_DPTX_HPD 0x02100
+#define BASE_DPTX_HPD 0x021
+#define ADDR_DPTX_FRAMER 0x02200
+#define BASE_DPTX_FRAMER 0x022
+#define ADDR_DPTX_STREAM 0x02200
+#define BASE_DPTX_STREAM 0x022
+#define ADDR_DPTX_GLBL 0x02300
+#define BASE_DPTX_GLBL 0x023
+#define ADDR_DPTX_HDCP 0x02400
+#define BASE_DPTX_HDCP 0x024
+#define ADDR_DP_AUX 0x02800
+#define BASE_DP_AUX 0x028
+#define ADDR_CRYPTO 0x05800
+#define BASE_CRYPTO 0x058
+#define ADDR_CIPHER 0x60000
+#define BASE_CIPHER 0x600
+#define ADDR_SOURCE_MHL_HD 0x01000
+#define ADDR_HDP_CEC_BASE 0x33800
+
+#define ADDR_AFE (0x20000 * 4)
+#define ADDR_SOURCD_PHY (0x800)
+
+#endif
diff --git a/drivers/mxc/hdp/aif_pckt2smp.h b/drivers/mxc/hdp/aif_pckt2smp.h
new file mode 100644
index 000000000000..b1b28bc3b38f
--- /dev/null
+++ b/drivers/mxc/hdp/aif_pckt2smp.h
@@ -0,0 +1,168 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2016-2017 Cadence Design Systems, Inc.
+ * All rights reserved worldwide.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 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.
+ *
+ * Copyright 2017 NXP
+ *
+ ******************************************************************************
+ *
+ * This file was auto-generated. Do not edit it manually.
+ *
+ ******************************************************************************
+ *
+ * aif_pckt2smp.h
+ *
+ ******************************************************************************
+ */
+
+#ifndef AIF_PCKT2SMP_H_
+#define AIF_PCKT2SMP_H_
+
+/* register PKT2SMPL_CNTL */
+#define PKT2SMPL_CNTL 0
+#define F_SW_RST(x) (((x) & ((1 << 1) - 1)) << 0)
+#define F_SW_RST_RD(x) (((x) & (((1 << 1) - 1) << 0)) >> 0)
+#define F_PKT2SMPL_EN(x) (((x) & ((1 << 1) - 1)) << 1)
+#define F_PKT2SMPL_EN_RD(x) (((x) & (((1 << 1) - 1) << 1)) >> 1)
+#define F_NUM_OF_I2S_PORTS(x) (((x) & ((1 << 2) - 1)) << 2)
+#define F_NUM_OF_I2S_PORTS_RD(x) (((x) & (((1 << 2) - 1) << 2)) >> 2)
+#define F_AIF_ERR_MASK(x) (((x) & ((1 << 1) - 1)) << 4)
+#define F_AIF_ERR_MASK_RD(x) (((x) & (((1 << 1) - 1) << 4)) >> 4)
+#define F_AIF_OVERFLOW_MASK(x) (((x) & ((1 << 1) - 1)) << 5)
+#define F_AIF_OVERFLOW_MASK_RD(x) (((x) & (((1 << 1) - 1) << 5)) >> 5)
+#define F_AIF_UNDERFLOW_MASK(x) (((x) & ((1 << 1) - 1)) << 6)
+#define F_AIF_UNDERFLOW_MASK_RD(x) (((x) & (((1 << 1) - 1) << 6)) >> 6)
+#define F_CFG_FORCE_SP(x) (((x) & ((1 << 1) - 1)) << 7)
+#define F_CFG_FORCE_SP_RD(x) (((x) & (((1 << 1) - 1) << 7)) >> 7)
+
+/* register ACR_CFG */
+#define ACR_CFG 1
+#define F_ACR_STOP_CLK_EN(x) (((x) & ((1 << 1) - 1)) << 0)
+#define F_ACR_STOP_CLK_EN_RD(x) (((x) & (((1 << 1) - 1) << 0)) >> 0)
+#define F_ACR_FIFO_STATUS_DIS(x) (((x) & ((1 << 1) - 1)) << 1)
+#define F_ACR_FIFO_STATUS_DIS_RD(x) (((x) & (((1 << 1) - 1) << 1)) >> 1)
+#define F_ACR_DIS_USE_NEDGE(x) (((x) & ((1 << 1) - 1)) << 2)
+#define F_ACR_DIS_USE_NEDGE_RD(x) (((x) & (((1 << 1) - 1) << 2)) >> 2)
+#define F_ACR_MASTER_CLK_FX_MODE(x) (((x) & ((1 << 2) - 1)) << 3)
+#define F_ACR_MASTER_CLK_FX_MODE_RD(x) (((x) & (((1 << 2) - 1) << 3)) >> 3)
+#define F_ACR_SW_RESET(x) (((x) & ((1 << 1) - 1)) << 5)
+#define F_ACR_SW_RESET_RD(x) (((x) & (((1 << 1) - 1) << 5)) >> 5)
+
+/* register SPDIF_CFG */
+#define SPDIF_CFG 2
+#define F_SPDIF_SELECTED(x) (((x) & ((1 << 1) - 1)) << 0)
+#define F_SPDIF_SELECTED_RD(x) (((x) & (((1 << 1) - 1) << 0)) >> 0)
+
+/* register AUDIO_FIFO_PTR_CFG0 */
+#define AUDIO_FIFO_PTR_CFG0 3
+#define F_AUDIO_FIFO_PTR_EMPTY_LOW(x) (((x) & ((1 << 9) - 1)) << 0)
+#define F_AUDIO_FIFO_PTR_EMPTY_LOW_RD(x) (((x) & (((1 << 9) - 1) << 0)) >> 0)
+#define F_AUDIO_FIFO_PTR_EMPTY_HIGH(x) (((x) & ((1 << 9) - 1)) << 9)
+#define F_AUDIO_FIFO_PTR_EMPTY_HIGH_RD(x) (((x) & (((1 << 9) - 1) << 9)) >> 9)
+#define F_AUDIO_FIFO_PTR_LOW_LOW(x) (((x) & ((1 << 9) - 1)) << 18)
+#define F_AUDIO_FIFO_PTR_LOW_LOW_RD(x) (((x) & (((1 << 9) - 1) << 18)) >> 18)
+
+/* register AUDIO_FIFO_PTR_CFG1 */
+#define AUDIO_FIFO_PTR_CFG1 4
+#define F_AUDIO_FIFO_PTR_LOW_HIGH(x) (((x) & ((1 << 9) - 1)) << 0)
+#define F_AUDIO_FIFO_PTR_LOW_HIGH_RD(x) (((x) & (((1 << 9) - 1) << 0)) >> 0)
+#define F_AUDIO_FIFO_PTR_BELOW_LOW(x) (((x) & ((1 << 9) - 1)) << 9)
+#define F_AUDIO_FIFO_PTR_BELOW_LOW_RD(x) (((x) & (((1 << 9) - 1) << 9)) >> 9)
+#define F_AUDIO_FIFO_PTR_BELOW_HIGH(x) (((x) & ((1 << 9) - 1)) << 18)
+#define F_AUDIO_FIFO_PTR_BELOW_HIGH_RD(x) (((x) & (((1 << 9) - 1) << 18)) >> 18)
+
+/* register AUDIO_FIFO_PTR_CFG2 */
+#define AUDIO_FIFO_PTR_CFG2 5
+#define F_AUDIO_FIFO_PTR_NOMINAL_LOW(x) (((x) & ((1 << 9) - 1)) << 0)
+#define F_AUDIO_FIFO_PTR_NOMINAL_LOW_RD(x) (((x) & (((1 << 9) - 1) << 0)) >> 0)
+#define F_AUDIO_FIFO_PTR_NOMINAL_HIGH(x) (((x) & ((1 << 9) - 1)) << 9)
+#define F_AUDIO_FIFO_PTR_NOMINAL_HIGH_RD(x) (((x) & (((1 << 9) - 1) << 9)) >> 9)
+#define F_AUDIO_FIFO_PTR_ABOVE_LOW(x) (((x) & ((1 << 9) - 1)) << 18)
+#define F_AUDIO_FIFO_PTR_ABOVE_LOW_RD(x) (((x) & (((1 << 9) - 1) << 18)) >> 18)
+
+/* register AUDIO_FIFO_PTR_CFG3 */
+#define AUDIO_FIFO_PTR_CFG3 6
+#define F_AUDIO_FIFO_PTR_ABOVE_HIGH(x) (((x) & ((1 << 9) - 1)) << 0)
+#define F_AUDIO_FIFO_PTR_ABOVE_HIGH_RD(x) (((x) & (((1 << 9) - 1) << 0)) >> 0)
+#define F_AUDIO_FIFO_PTR_HIGH_LOW(x) (((x) & ((1 << 9) - 1)) << 9)
+#define F_AUDIO_FIFO_PTR_HIGH_LOW_RD(x) (((x) & (((1 << 9) - 1) << 9)) >> 9)
+#define F_AUDIO_FIFO_PTR_HIGH_HIGH(x) (((x) & ((1 << 9) - 1)) << 18)
+#define F_AUDIO_FIFO_PTR_HIGH_HIGH_RD(x) (((x) & (((1 << 9) - 1) << 18)) >> 18)
+
+/* register AUDIO_FIFO_PTR_CFG4 */
+#define AUDIO_FIFO_PTR_CFG4 7
+#define F_AUDIO_FIFO_PTR_FULL_LOW(x) (((x) & ((1 << 9) - 1)) << 0)
+#define F_AUDIO_FIFO_PTR_FULL_LOW_RD(x) (((x) & (((1 << 9) - 1) << 0)) >> 0)
+#define F_AUDIO_FIFO_PTR_FULL_HIGH(x) (((x) & ((1 << 9) - 1)) << 9)
+#define F_AUDIO_FIFO_PTR_FULL_HIGH_RD(x) (((x) & (((1 << 9) - 1) << 9)) >> 9)
+
+/* register AUDIO_FIFO_PTR_CFG5 */
+#define AUDIO_FIFO_PTR_CFG5 8
+#define F_AUDIO_FIFO_PTR_IDLE_LOW(x) (((x) & ((1 << 9) - 1)) << 0)
+#define F_AUDIO_FIFO_PTR_IDLE_LOW_RD(x) (((x) & (((1 << 9) - 1) << 0)) >> 0)
+#define F_AUDIO_FIFO_PTR_IDLE_HIGH(x) (((x) & ((1 << 9) - 1)) << 9)
+#define F_AUDIO_FIFO_PTR_IDLE_HIGH_RD(x) (((x) & (((1 << 9) - 1) << 9)) >> 9)
+
+/* register AIF_INT_STTS */
+#define AIF_INT_STTS 9
+#define F_AIF_ERR_STATUS(x) (((x) & ((1 << 1) - 1)) << 0)
+#define F_AIF_ERR_STATUS_RD(x) (((x) & (((1 << 1) - 1) << 0)) >> 0)
+#define F_AIF_OVERFLOW_STATUS(x) (((x) & ((1 << 1) - 1)) << 1)
+#define F_AIF_OVERFLOW_STATUS_RD(x) (((x) & (((1 << 1) - 1) << 1)) >> 1)
+#define F_AIF_UNDERFLOW_STATUS(x) (((x) & ((1 << 1) - 1)) << 2)
+#define F_AIF_UNDERFLOW_STATUS_RD(x) (((x) & (((1 << 1) - 1) << 2)) >> 2)
+
+/* register AIF_ACR_N_ST */
+#define AIF_ACR_N_ST 10
+#define F_ACR_N(x) (((x) & ((1 << 20) - 1)) << 0)
+#define F_ACR_N_RD(x) (((x) & (((1 << 20) - 1) << 0)) >> 0)
+
+/* register AIF_ACR_CTS_ST */
+#define AIF_ACR_CTS_ST 11
+#define F_ACR_CTS(x) (((x) & ((1 << 20) - 1)) << 0)
+#define F_ACR_CTS_RD(x) (((x) & (((1 << 20) - 1) << 0)) >> 0)
+
+/* register AIF_ACR_N_OFST_CFG */
+#define AIF_ACR_N_OFST_CFG 12
+#define F_ACR_N_OFFSET(x) (((x) & ((1 << 24) - 1)) << 0)
+#define F_ACR_N_OFFSET_RD(x) (((x) & (((1 << 24) - 1) << 0)) >> 0)
+
+/* register AIF_ACR_CTS_OFST_CFG */
+#define AIF_ACR_CTS_OFST_CFG 13
+#define F_ACR_CTS_OFFSET(x) (((x) & ((1 << 24) - 1)) << 0)
+#define F_ACR_CTS_OFFSET_RD(x) (((x) & (((1 << 24) - 1) << 0)) >> 0)
+
+#endif
diff --git a/drivers/mxc/hdp/all.h b/drivers/mxc/hdp/all.h
new file mode 100644
index 000000000000..7c3e63572830
--- /dev/null
+++ b/drivers/mxc/hdp/all.h
@@ -0,0 +1,64 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2016-2017 Cadence Design Systems, Inc.
+ * All rights reserved worldwide.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 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.
+ *
+ * Copyright 2017 NXP
+ *
+ ******************************************************************************
+ *
+ * all.h
+ *
+ ******************************************************************************
+ */
+#include "address.h"
+#include "apb_cfg.h"
+#include "API_AFE.h"
+#include "API_DPTX.h"
+#include "API_General.h"
+#include "API_Infoframe.h"
+#include "API_Audio.h"
+#include "API_HDCP.h"
+#include "API_HDMITX.h"
+#include "dptx_framer.h"
+#include "source_car.h"
+#include "source_phy.h"
+#include "source_vif.h"
+#include "util.h"
+#include "sink_pif.h"
+#include "sink_mhl_hd.h"
+#include "sink_car.h"
+#include "API_HDMIRX.h"
+#include "general_handler.h"
diff --git a/drivers/mxc/hdp/apb_cfg.h b/drivers/mxc/hdp/apb_cfg.h
new file mode 100644
index 000000000000..80baa5b55315
--- /dev/null
+++ b/drivers/mxc/hdp/apb_cfg.h
@@ -0,0 +1,185 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2016-2017 Cadence Design Systems, Inc.
+ * All rights reserved worldwide.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 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.
+ *
+ * Copyright 2017 NXP
+ *
+ ******************************************************************************
+ *
+ * This file was auto-generated. Do not edit it manually.
+ *
+ ******************************************************************************
+ *
+ * apb_cfg.h
+ *
+ ******************************************************************************
+ */
+
+#ifndef APB_CFG_H_
+#define APB_CFG_H_
+
+/* register APB_CTRL */
+#define APB_CTRL 0
+#define F_APB_XT_RESET(x) (((x) & ((1 << 1) - 1)) << 0)
+#define F_APB_XT_RESET_RD(x) (((x) & (((1 << 1) - 1) << 0)) >> 0)
+#define F_APB_DRAM_PATH(x) (((x) & ((1 << 1) - 1)) << 1)
+#define F_APB_DRAM_PATH_RD(x) (((x) & (((1 << 1) - 1) << 1)) >> 1)
+#define F_APB_IRAM_PATH(x) (((x) & ((1 << 1) - 1)) << 2)
+#define F_APB_IRAM_PATH_RD(x) (((x) & (((1 << 1) - 1) << 2)) >> 2)
+
+/* register XT_INT_CTRL */
+#define XT_INT_CTRL 1
+#define F_XT_INT_POLARITY(x) (((x) & ((1 << 2) - 1)) << 0)
+#define F_XT_INT_POLARITY_RD(x) (((x) & (((1 << 2) - 1) << 0)) >> 0)
+
+/* register MAILBOX_FULL_ADDR */
+#define MAILBOX_FULL_ADDR 2
+#define F_MAILBOX_FULL(x) (((x) & ((1 << 1) - 1)) << 0)
+#define F_MAILBOX_FULL_RD(x) (((x) & (((1 << 1) - 1) << 0)) >> 0)
+
+/* register MAILBOX_EMPTY_ADDR */
+#define MAILBOX_EMPTY_ADDR 3
+#define F_MAILBOX_EMPTY(x) (((x) & ((1 << 1) - 1)) << 0)
+#define F_MAILBOX_EMPTY_RD(x) (((x) & (((1 << 1) - 1) << 0)) >> 0)
+
+/* register MAILBOX0_WR_DATA */
+#define MAILBOX0_WR_DATA 4
+#define F_MAILBOX0_WR_DATA(x) (((x) & ((1 << 8) - 1)) << 0)
+#define F_MAILBOX0_WR_DATA_RD(x) (((x) & (((1 << 8) - 1) << 0)) >> 0)
+
+/* register MAILBOX0_RD_DATA */
+#define MAILBOX0_RD_DATA 5
+#define F_MAILBOX0_RD_DATA(x) (((x) & ((1 << 8) - 1)) << 0)
+#define F_MAILBOX0_RD_DATA_RD(x) (((x) & (((1 << 8) - 1) << 0)) >> 0)
+
+/* register KEEP_ALIVE */
+#define KEEP_ALIVE 6
+#define F_KEEP_ALIVE_CNT(x) (((x) & ((1 << 8) - 1)) << 0)
+#define F_KEEP_ALIVE_CNT_RD(x) (((x) & (((1 << 8) - 1) << 0)) >> 0)
+
+/* register VER_L */
+#define VER_L 7
+#define F_VER_LSB(x) (((x) & ((1 << 8) - 1)) << 0)
+#define F_VER_LSB_RD(x) (((x) & (((1 << 8) - 1) << 0)) >> 0)
+
+/* register VER_H */
+#define VER_H 8
+#define F_VER_MSB(x) (((x) & ((1 << 8) - 1)) << 0)
+#define F_VER_MSB_RD(x) (((x) & (((1 << 8) - 1) << 0)) >> 0)
+
+/* register VER_LIB_L_ADDR */
+#define VER_LIB_L_ADDR 9
+#define F_SW_LIB_VER_L(x) (((x) & ((1 << 8) - 1)) << 0)
+#define F_SW_LIB_VER_L_RD(x) (((x) & (((1 << 8) - 1) << 0)) >> 0)
+
+/* register VER_LIB_H_ADDR */
+#define VER_LIB_H_ADDR 10
+#define F_SW_LIB_VER_H(x) (((x) & ((1 << 8) - 1)) << 0)
+#define F_SW_LIB_VER_H_RD(x) (((x) & (((1 << 8) - 1) << 0)) >> 0)
+
+/* register SW_DEBUG_L */
+#define SW_DEBUG_L 11
+#define F_SW_DEBUG_7_0(x) (((x) & ((1 << 8) - 1)) << 0)
+#define F_SW_DEBUG_7_0_RD(x) (((x) & (((1 << 8) - 1) << 0)) >> 0)
+
+/* register SW_DEBUG_H */
+#define SW_DEBUG_H 12
+#define F_SW_DEBUG_15_8(x) (((x) & ((1 << 8) - 1)) << 0)
+#define F_SW_DEBUG_15_8_RD(x) (((x) & (((1 << 8) - 1) << 0)) >> 0)
+
+/* register MAILBOX_INT_MASK */
+#define MAILBOX_INT_MASK 13
+#define F_MAILBOX_INT_MASK(x) (((x) & ((1 << 2) - 1)) << 0)
+#define F_MAILBOX_INT_MASK_RD(x) (((x) & (((1 << 2) - 1) << 0)) >> 0)
+
+/* register MAILBOX_INT_STATUS */
+#define MAILBOX_INT_STATUS 14
+#define F_MAILBOX_INT_STATUS(x) (((x) & ((1 << 2) - 1)) << 0)
+#define F_MAILBOX_INT_STATUS_RD(x) (((x) & (((1 << 2) - 1) << 0)) >> 0)
+
+/* register SW_CLK_L */
+#define SW_CLK_L 15
+#define F_SW_CLOCK_VAL_L(x) (((x) & ((1 << 8) - 1)) << 0)
+#define F_SW_CLOCK_VAL_L_RD(x) (((x) & (((1 << 8) - 1) << 0)) >> 0)
+
+/* register SW_CLK_H */
+#define SW_CLK_H 16
+#define F_SW_CLOCK_VAL_H(x) (((x) & ((1 << 8) - 1)) << 0)
+#define F_SW_CLOCK_VAL_H_RD(x) (((x) & (((1 << 8) - 1) << 0)) >> 0)
+
+/* register SW_EVENTS0 */
+#define SW_EVENTS0 17
+#define F_SW_EVENTS7_0(x) (((x) & ((1 << 8) - 1)) << 0)
+#define F_SW_EVENTS7_0_RD(x) (((x) & (((1 << 8) - 1) << 0)) >> 0)
+
+/* register SW_EVENTS1 */
+#define SW_EVENTS1 18
+#define F_SW_EVENTS15_8(x) (((x) & ((1 << 8) - 1)) << 0)
+#define F_SW_EVENTS15_8_RD(x) (((x) & (((1 << 8) - 1) << 0)) >> 0)
+
+/* register SW_EVENTS2 */
+#define SW_EVENTS2 19
+#define F_SW_EVENTS23_16(x) (((x) & ((1 << 8) - 1)) << 0)
+#define F_SW_EVENTS23_16_RD(x) (((x) & (((1 << 8) - 1) << 0)) >> 0)
+
+/* register SW_EVENTS3 */
+#define SW_EVENTS3 20
+#define F_SW_EVENTS31_24(x) (((x) & ((1 << 8) - 1)) << 0)
+#define F_SW_EVENTS31_24_RD(x) (((x) & (((1 << 8) - 1) << 0)) >> 0)
+
+/* register XT_OCD_CTRL */
+#define XT_OCD_CTRL 24
+#define F_XT_DRESET(x) (((x) & ((1 << 1) - 1)) << 0)
+#define F_XT_DRESET_RD(x) (((x) & (((1 << 1) - 1) << 0)) >> 0)
+#define F_XT_OCDHALTONRESET(x) (((x) & ((1 << 1) - 1)) << 1)
+#define F_XT_OCDHALTONRESET_RD(x) (((x) & (((1 << 1) - 1) << 1)) >> 1)
+
+/* register XT_OCD_CTRL_RO */
+#define XT_OCD_CTRL_RO 25
+#define F_XT_XOCDMODE(x) (((x) & ((1 << 1) - 1)) << 0)
+#define F_XT_XOCDMODE_RD(x) (((x) & (((1 << 1) - 1) << 0)) >> 0)
+
+/* register APB_INT_MASK */
+#define APB_INT_MASK 27
+#define F_APB_INTR_MASK(x) (((x) & ((1 << 3) - 1)) << 0)
+#define F_APB_INTR_MASK_RD(x) (((x) & (((1 << 3) - 1) << 0)) >> 0)
+
+/* register APB_STATUS_MASK */
+#define APB_STATUS_MASK 28
+#define F_APB_INTR_STATUS(x) (((x) & ((1 << 3) - 1)) << 0)
+#define F_APB_INTR_STATUS_RD(x) (((x) & (((1 << 3) - 1) << 0)) >> 0)
+
+#endif
diff --git a/drivers/mxc/hdp/clock_meters.h b/drivers/mxc/hdp/clock_meters.h
new file mode 100644
index 000000000000..f9433b40a109
--- /dev/null
+++ b/drivers/mxc/hdp/clock_meters.h
@@ -0,0 +1,157 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2016-2017 Cadence Design Systems, Inc.
+ * All rights reserved worldwide.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 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.
+ *
+ * Copyright 2017 NXP
+ *
+ ******************************************************************************
+ *
+ * This file was auto-generated. Do not edit it manually.
+ *
+ ******************************************************************************
+ *
+ * clock_meters.h
+ *
+ ******************************************************************************
+ */
+
+#ifndef CLOCK_METERS_H_
+#define CLOCK_METERS_H_
+
+/* register CM_CTRL */
+#define CM_CTRL 0
+#define F_NMVID_SEL_EXTERNAL(x) (((x) & ((1 << 1) - 1)) << 0)
+#define F_NMVID_SEL_EXTERNAL_RD(x) (((x) & (((1 << 1) - 1) << 0)) >> 0)
+#define F_SPDIF_SEL_EXTERNAL(x) (((x) & ((1 << 1) - 1)) << 1)
+#define F_SPDIF_SEL_EXTERNAL_RD(x) (((x) & (((1 << 1) - 1) << 1)) >> 1)
+#define F_I2S_SEL_EXTERNAL(x) (((x) & ((1 << 1) - 1)) << 2)
+#define F_I2S_SEL_EXTERNAL_RD(x) (((x) & (((1 << 1) - 1) << 2)) >> 2)
+#define F_SEL_AUD_LANE_REF(x) (((x) & ((1 << 1) - 1)) << 3)
+#define F_SEL_AUD_LANE_REF_RD(x) (((x) & (((1 << 1) - 1) << 3)) >> 3)
+#define F_I2S_MULT(x) (((x) & ((1 << 3) - 1)) << 4)
+#define F_I2S_MULT_RD(x) (((x) & (((1 << 3) - 1) << 4)) >> 4)
+
+/* register CM_I2S_CTRL */
+#define CM_I2S_CTRL 1
+#define F_I2S_REF_CYC(x) (((x) & ((1 << 24) - 1)) << 0)
+#define F_I2S_REF_CYC_RD(x) (((x) & (((1 << 24) - 1) << 0)) >> 0)
+#define F_I2S_MEAS_TOLERANCE(x) (((x) & ((1 << 4) - 1)) << 24)
+#define F_I2S_MEAS_TOLERANCE_RD(x) (((x) & (((1 << 4) - 1) << 24)) >> 24)
+
+/* register CM_SPDIF_CTRL */
+#define CM_SPDIF_CTRL 2
+#define F_SPDIF_REF_CYC(x) (((x) & ((1 << 24) - 1)) << 0)
+#define F_SPDIF_REF_CYC_RD(x) (((x) & (((1 << 24) - 1) << 0)) >> 0)
+#define F_SPDIF_MEAS_TOLERANCE(x) (((x) & ((1 << 4) - 1)) << 24)
+#define F_SPDIF_MEAS_TOLERANCE_RD(x) (((x) & (((1 << 4) - 1) << 24)) >> 24)
+
+/* register CM_VID_CTRL */
+#define CM_VID_CTRL 3
+#define F_NMVID_REF_CYC(x) (((x) & ((1 << 24) - 1)) << 0)
+#define F_NMVID_REF_CYC_RD(x) (((x) & (((1 << 24) - 1) << 0)) >> 0)
+#define F_NMVID_MEAS_TOLERANCE(x) (((x) & ((1 << 4) - 1)) << 24)
+#define F_NMVID_MEAS_TOLERANCE_RD(x) (((x) & (((1 << 4) - 1) << 24)) >> 24)
+
+/* register CM_LANE_CTRL */
+#define CM_LANE_CTRL 4
+#define F_LANE_REF_CYC(x) (((x) & ((1 << 24) - 1)) << 0)
+#define F_LANE_REF_CYC_RD(x) (((x) & (((1 << 24) - 1) << 0)) >> 0)
+
+/* register I2S_NM_STABLE */
+#define I2S_NM_STABLE 5
+#define F_I2S_MNAUD_STABLE(x) (((x) & ((1 << 1) - 1)) << 0)
+#define F_I2S_MNAUD_STABLE_RD(x) (((x) & (((1 << 1) - 1) << 0)) >> 0)
+
+/* register I2S_NCTS_STABLE */
+#define I2S_NCTS_STABLE 6
+#define F_I2S_NCTS_STABLE(x) (((x) & ((1 << 1) - 1)) << 0)
+#define F_I2S_NCTS_STABLE_RD(x) (((x) & (((1 << 1) - 1) << 0)) >> 0)
+
+/* register SPDIF_NM_STABLE */
+#define SPDIF_NM_STABLE 7
+#define F_SPDIF_MNAUD_STABLE(x) (((x) & ((1 << 1) - 1)) << 0)
+#define F_SPDIF_MNAUD_STABLE_RD(x) (((x) & (((1 << 1) - 1) << 0)) >> 0)
+
+/* register SPDIF_NCTS_STABLE */
+#define SPDIF_NCTS_STABLE 8
+#define F_SPDIF_NCTS_STABLE(x) (((x) & ((1 << 1) - 1)) << 0)
+#define F_SPDIF_NCTS_STABLE_RD(x) (((x) & (((1 << 1) - 1) << 0)) >> 0)
+
+/* register NMVID_MEAS_STABLE */
+#define NMVID_MEAS_STABLE 9
+#define F_ST_NMVID_MEAS_STABLE(x) (((x) & ((1 << 1) - 1)) << 0)
+#define F_ST_NMVID_MEAS_STABLE_RD(x) (((x) & (((1 << 1) - 1) << 0)) >> 0)
+
+/* register CM_VID_MEAS */
+#define CM_VID_MEAS 10
+#define F_NMVID_MEAS_CYC(x) (((x) & ((1 << 24) - 1)) << 0)
+#define F_NMVID_MEAS_CYC_RD(x) (((x) & (((1 << 24) - 1) << 0)) >> 0)
+#define F_NMVID_MEAS_VALID_INDC(x) (((x) & ((1 << 1) - 1)) << 24)
+#define F_NMVID_MEAS_VALID_INDC_RD(x) (((x) & (((1 << 1) - 1) << 24)) >> 24)
+
+/* register CM_AUD_MEAS */
+#define CM_AUD_MEAS 11
+#define F_NMAUD_MEAS_CYC(x) (((x) & ((1 << 24) - 1)) << 0)
+#define F_NMAUD_MEAS_CYC_RD(x) (((x) & (((1 << 24) - 1) << 0)) >> 0)
+#define F_NMAUD_MEAS_VALID_INDC(x) (((x) & ((1 << 1) - 1)) << 24)
+#define F_NMAUD_MEAS_VALID_INDC_RD(x) (((x) & (((1 << 1) - 1) << 24)) >> 24)
+
+/* register I2S_MEAS */
+#define I2S_MEAS 16
+#define F_I2_MEAS(x) (((x) & ((1 << 24) - 1)) << 0)
+#define F_I2_MEAS_RD(x) (((x) & (((1 << 24) - 1) << 0)) >> 0)
+
+/* register I2S_DP_MEAS */
+#define I2S_DP_MEAS 17
+#define F_I2_DP_MEAS(x) (((x) & ((1 << 24) - 1)) << 0)
+#define F_I2_DP_MEAS_RD(x) (((x) & (((1 << 24) - 1) << 0)) >> 0)
+
+/* register SPDIF_DP_MEAS */
+#define SPDIF_DP_MEAS 32
+#define F_SPDIF_DP_MEAS(x) (((x) & ((1 << 24) - 1)) << 0)
+#define F_SPDIF_DP_MEAS_RD(x) (((x) & (((1 << 24) - 1) << 0)) >> 0)
+
+/* register SPDIF_MEAS */
+#define SPDIF_MEAS 33
+#define F_SPDIF_MEAS(x) (((x) & ((1 << 24) - 1)) << 0)
+#define F_SPDIF_MEAS_RD(x) (((x) & (((1 << 24) - 1) << 0)) >> 0)
+
+/* register NMVID_MEAS */
+#define NMVID_MEAS 48
+#define F_NMVID_MEAS(x) (((x) & ((1 << 24) - 1)) << 0)
+#define F_NMVID_MEAS_RD(x) (((x) & (((1 << 24) - 1) << 0)) >> 0)
+
+#endif //CLOCK_METERS
diff --git a/drivers/mxc/hdp/dptx_framer.h b/drivers/mxc/hdp/dptx_framer.h
new file mode 100644
index 000000000000..1a7ddf8766b1
--- /dev/null
+++ b/drivers/mxc/hdp/dptx_framer.h
@@ -0,0 +1,372 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2016-2017 Cadence Design Systems, Inc.
+ * All rights reserved worldwide.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 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.
+ *
+ * Copyright 2017 NXP
+ *
+ ******************************************************************************
+ *
+ * This file was auto-generated. Do not edit it manually.
+ *
+ ******************************************************************************
+ *
+ * dptx_framer.h
+ *
+ ******************************************************************************
+ */
+
+#ifndef DPTX_FRAMER_H_
+#define DPTX_FRAMER_H_
+
+/* register DP_FRAMER_GLOBAL_CONFIG */
+#define DP_FRAMER_GLOBAL_CONFIG 0
+#define F_NUM_LANES(x) (((x) & ((1 << 2) - 1)) << 0)
+#define F_NUM_LANES_RD(x) (((x) & (((1 << 2) - 1) << 0)) >> 0)
+#define F_MST_SST(x) (((x) & ((1 << 1) - 1)) << 2)
+#define F_MST_SST_RD(x) (((x) & (((1 << 1) - 1) << 2)) >> 2)
+#define F_GLOBAL_EN(x) (((x) & ((1 << 1) - 1)) << 3)
+#define F_GLOBAL_EN_RD(x) (((x) & (((1 << 1) - 1) << 3)) >> 3)
+#define F_RG_EN(x) (((x) & ((1 << 1) - 1)) << 4)
+#define F_RG_EN_RD(x) (((x) & (((1 << 1) - 1) << 4)) >> 4)
+#define F_NO_VIDEO(x) (((x) & ((1 << 1) - 1)) << 5)
+#define F_NO_VIDEO_RD(x) (((x) & (((1 << 1) - 1) << 5)) >> 5)
+#define F_ENC_RST_DIS(x) (((x) & ((1 << 1) - 1)) << 6)
+#define F_ENC_RST_DIS_RD(x) (((x) & (((1 << 1) - 1) << 6)) >> 6)
+#define F_WR_VHSYNC_FALL(x) (((x) & ((1 << 1) - 1)) << 7)
+#define F_WR_VHSYNC_FALL_RD(x) (((x) & (((1 << 1) - 1) << 7)) >> 7)
+
+/* register DP_SW_RESET */
+#define DP_SW_RESET 1
+#define F_SW_RST(x) (((x) & ((1 << 1) - 1)) << 0)
+#define F_SW_RST_RD(x) (((x) & (((1 << 1) - 1) << 0)) >> 0)
+
+/* register DP_FRAMER_TU */
+#define DP_FRAMER_TU 2
+#define F_TU_VALID_SYMBOLS(x) (((x) & ((1 << 6) - 1)) << 0)
+#define F_TU_VALID_SYMBOLS_RD(x) (((x) & (((1 << 6) - 1) << 0)) >> 0)
+#define F_TU_SIZE(x) (((x) & ((1 << 7) - 1)) << 8)
+#define F_TU_SIZE_RD(x) (((x) & (((1 << 7) - 1) << 8)) >> 8)
+#define F_TU_CNT_RST_EN(x) (((x) & ((1 << 1) - 1)) << 15)
+#define F_TU_CNT_RST_EN_RD(x) (((x) & (((1 << 1) - 1) << 15)) >> 15)
+#define F_BS_SR_REPLACE_POSITION(x) (((x) & ((1 << 9) - 1)) << 16)
+#define F_BS_SR_REPLACE_POSITION_RD(x) (((x) & (((1 << 9) - 1) << 16)) >> 16)
+
+/* register DP_FRAMER_PXL_REPR */
+#define DP_FRAMER_PXL_REPR 3
+#define F_COLOR_DEPTH(x) (((x) & ((1 << 5) - 1)) << 0)
+#define F_COLOR_DEPTH_RD(x) (((x) & (((1 << 5) - 1) << 0)) >> 0)
+#define F_PXL_ENC_FORMAT(x) (((x) & ((1 << 5) - 1)) << 8)
+#define F_PXL_ENC_FORMAT_RD(x) (((x) & (((1 << 5) - 1) << 8)) >> 8)
+
+/* register DP_FRAMER_SP */
+#define DP_FRAMER_SP 4
+#define F_VSP(x) (((x) & ((1 << 1) - 1)) << 0)
+#define F_VSP_RD(x) (((x) & (((1 << 1) - 1) << 0)) >> 0)
+#define F_HSP(x) (((x) & ((1 << 1) - 1)) << 1)
+#define F_HSP_RD(x) (((x) & (((1 << 1) - 1) << 1)) >> 1)
+#define F_INTERLACE_EN(x) (((x) & ((1 << 1) - 1)) << 2)
+#define F_INTERLACE_EN_RD(x) (((x) & (((1 << 1) - 1) << 2)) >> 2)
+#define F_FRAMER_3D_EN(x) (((x) & ((1 << 1) - 1)) << 3)
+#define F_FRAMER_3D_EN_RD(x) (((x) & (((1 << 1) - 1) << 3)) >> 3)
+#define F_STACKED_3D_EN(x) (((x) & ((1 << 1) - 1)) << 4)
+#define F_STACKED_3D_EN_RD(x) (((x) & (((1 << 1) - 1) << 4)) >> 4)
+
+/* register AUDIO_PACK_CONTROL */
+#define AUDIO_PACK_CONTROL 5
+#define F_MST_SDP_ID(x) (((x) & ((1 << 8) - 1)) << 0)
+#define F_MST_SDP_ID_RD(x) (((x) & (((1 << 8) - 1) << 0)) >> 0)
+#define F_AUDIO_PACK_EN(x) (((x) & ((1 << 1) - 1)) << 8)
+#define F_AUDIO_PACK_EN_RD(x) (((x) & (((1 << 1) - 1) << 8)) >> 8)
+#define F_MONO(x) (((x) & ((1 << 1) - 1)) << 9)
+#define F_MONO_RD(x) (((x) & (((1 << 1) - 1) << 9)) >> 9)
+
+/* register DP_VC_TABLE_0 */
+#define DP_VC_TABLE_0 6
+#define F_VC_TABLE_0(x) (((x) & ((1 << 6) - 1)) << 0)
+#define F_VC_TABLE_0_RD(x) (((x) & (((1 << 6) - 1) << 0)) >> 0)
+#define F_VC_TABLE_1(x) (((x) & ((1 << 6) - 1)) << 8)
+#define F_VC_TABLE_1_RD(x) (((x) & (((1 << 6) - 1) << 8)) >> 8)
+#define F_VC_TABLE_2(x) (((x) & ((1 << 6) - 1)) << 16)
+#define F_VC_TABLE_2_RD(x) (((x) & (((1 << 6) - 1) << 16)) >> 16)
+#define F_VC_TABLE_3(x) (((x) & ((1 << 6) - 1)) << 24)
+#define F_VC_TABLE_3_RD(x) (((x) & (((1 << 6) - 1) << 24)) >> 24)
+
+/* register DP_VC_TABLE_1 */
+#define DP_VC_TABLE_1 7
+#define F_VC_TABLE_4(x) (((x) & ((1 << 6) - 1)) << 0)
+#define F_VC_TABLE_4_RD(x) (((x) & (((1 << 6) - 1) << 0)) >> 0)
+#define F_VC_TABLE_5(x) (((x) & ((1 << 6) - 1)) << 8)
+#define F_VC_TABLE_5_RD(x) (((x) & (((1 << 6) - 1) << 8)) >> 8)
+#define F_VC_TABLE_6(x) (((x) & ((1 << 6) - 1)) << 16)
+#define F_VC_TABLE_6_RD(x) (((x) & (((1 << 6) - 1) << 16)) >> 16)
+#define F_VC_TABLE_7(x) (((x) & ((1 << 6) - 1)) << 24)
+#define F_VC_TABLE_7_RD(x) (((x) & (((1 << 6) - 1) << 24)) >> 24)
+
+/* register DP_VC_TABLE_2 */
+#define DP_VC_TABLE_2 8
+#define F_VC_TABLE_8(x) (((x) & ((1 << 6) - 1)) << 0)
+#define F_VC_TABLE_8_RD(x) (((x) & (((1 << 6) - 1) << 0)) >> 0)
+#define F_VC_TABLE_9(x) (((x) & ((1 << 6) - 1)) << 8)
+#define F_VC_TABLE_9_RD(x) (((x) & (((1 << 6) - 1) << 8)) >> 8)
+#define F_VC_TABLE_10(x) (((x) & ((1 << 6) - 1)) << 16)
+#define F_VC_TABLE_10_RD(x) (((x) & (((1 << 6) - 1) << 16)) >> 16)
+#define F_VC_TABLE_11(x) (((x) & ((1 << 6) - 1)) << 24)
+#define F_VC_TABLE_11_RD(x) (((x) & (((1 << 6) - 1) << 24)) >> 24)
+
+/* register DP_VC_TABLE_3 */
+#define DP_VC_TABLE_3 9
+#define F_VC_TABLE_12(x) (((x) & ((1 << 6) - 1)) << 0)
+#define F_VC_TABLE_12_RD(x) (((x) & (((1 << 6) - 1) << 0)) >> 0)
+#define F_VC_TABLE_13(x) (((x) & ((1 << 6) - 1)) << 8)
+#define F_VC_TABLE_13_RD(x) (((x) & (((1 << 6) - 1) << 8)) >> 8)
+#define F_VC_TABLE_14(x) (((x) & ((1 << 6) - 1)) << 16)
+#define F_VC_TABLE_14_RD(x) (((x) & (((1 << 6) - 1) << 16)) >> 16)
+#define F_VC_TABLE_15(x) (((x) & ((1 << 6) - 1)) << 24)
+#define F_VC_TABLE_15_RD(x) (((x) & (((1 << 6) - 1) << 24)) >> 24)
+
+/* register DP_VC_TABLE_4 */
+#define DP_VC_TABLE_4 10
+#define F_VC_TABLE_16(x) (((x) & ((1 << 6) - 1)) << 0)
+#define F_VC_TABLE_16_RD(x) (((x) & (((1 << 6) - 1) << 0)) >> 0)
+#define F_VC_TABLE_17(x) (((x) & ((1 << 6) - 1)) << 8)
+#define F_VC_TABLE_17_RD(x) (((x) & (((1 << 6) - 1) << 8)) >> 8)
+#define F_VC_TABLE_18(x) (((x) & ((1 << 6) - 1)) << 16)
+#define F_VC_TABLE_18_RD(x) (((x) & (((1 << 6) - 1) << 16)) >> 16)
+#define F_VC_TABLE_19(x) (((x) & ((1 << 6) - 1)) << 24)
+#define F_VC_TABLE_19_RD(x) (((x) & (((1 << 6) - 1) << 24)) >> 24)
+
+/* register DP_VC_TABLE_5 */
+#define DP_VC_TABLE_5 11
+#define F_VC_TABLE_20(x) (((x) & ((1 << 6) - 1)) << 0)
+#define F_VC_TABLE_20_RD(x) (((x) & (((1 << 6) - 1) << 0)) >> 0)
+#define F_VC_TABLE_21(x) (((x) & ((1 << 6) - 1)) << 8)
+#define F_VC_TABLE_21_RD(x) (((x) & (((1 << 6) - 1) << 8)) >> 8)
+#define F_VC_TABLE_22(x) (((x) & ((1 << 6) - 1)) << 16)
+#define F_VC_TABLE_22_RD(x) (((x) & (((1 << 6) - 1) << 16)) >> 16)
+#define F_VC_TABLE_23(x) (((x) & ((1 << 6) - 1)) << 24)
+#define F_VC_TABLE_23_RD(x) (((x) & (((1 << 6) - 1) << 24)) >> 24)
+
+/* register DP_VC_TABLE_6 */
+#define DP_VC_TABLE_6 12
+#define F_VC_TABLE_24(x) (((x) & ((1 << 6) - 1)) << 0)
+#define F_VC_TABLE_24_RD(x) (((x) & (((1 << 6) - 1) << 0)) >> 0)
+#define F_VC_TABLE_25(x) (((x) & ((1 << 6) - 1)) << 8)
+#define F_VC_TABLE_25_RD(x) (((x) & (((1 << 6) - 1) << 8)) >> 8)
+#define F_VC_TABLE_26(x) (((x) & ((1 << 6) - 1)) << 16)
+#define F_VC_TABLE_26_RD(x) (((x) & (((1 << 6) - 1) << 16)) >> 16)
+#define F_VC_TABLE_27(x) (((x) & ((1 << 6) - 1)) << 24)
+#define F_VC_TABLE_27_RD(x) (((x) & (((1 << 6) - 1) << 24)) >> 24)
+
+/* register DP_VC_TABLE_7 */
+#define DP_VC_TABLE_7 13
+#define F_VC_TABLE_28(x) (((x) & ((1 << 6) - 1)) << 0)
+#define F_VC_TABLE_28_RD(x) (((x) & (((1 << 6) - 1) << 0)) >> 0)
+#define F_VC_TABLE_29(x) (((x) & ((1 << 6) - 1)) << 8)
+#define F_VC_TABLE_29_RD(x) (((x) & (((1 << 6) - 1) << 8)) >> 8)
+#define F_VC_TABLE_30(x) (((x) & ((1 << 6) - 1)) << 16)
+#define F_VC_TABLE_30_RD(x) (((x) & (((1 << 6) - 1) << 16)) >> 16)
+#define F_VC_TABLE_31(x) (((x) & ((1 << 6) - 1)) << 24)
+#define F_VC_TABLE_31_RD(x) (((x) & (((1 << 6) - 1) << 24)) >> 24)
+
+/* register DP_VC_TABLE_8 */
+#define DP_VC_TABLE_8 14
+#define F_VC_TABLE_32(x) (((x) & ((1 << 6) - 1)) << 0)
+#define F_VC_TABLE_32_RD(x) (((x) & (((1 << 6) - 1) << 0)) >> 0)
+#define F_VC_TABLE_33(x) (((x) & ((1 << 6) - 1)) << 8)
+#define F_VC_TABLE_33_RD(x) (((x) & (((1 << 6) - 1) << 8)) >> 8)
+#define F_VC_TABLE_34(x) (((x) & ((1 << 6) - 1)) << 16)
+#define F_VC_TABLE_34_RD(x) (((x) & (((1 << 6) - 1) << 16)) >> 16)
+#define F_VC_TABLE_35(x) (((x) & ((1 << 6) - 1)) << 24)
+#define F_VC_TABLE_35_RD(x) (((x) & (((1 << 6) - 1) << 24)) >> 24)
+
+/* register DP_VC_TABLE_9 */
+#define DP_VC_TABLE_9 15
+#define F_VC_TABLE_36(x) (((x) & ((1 << 1) - 1)) << 5)
+#define F_VC_TABLE_36_RD(x) (((x) & (((1 << 1) - 1) << 5)) >> 5)
+#define F_VC_TABLE_37(x) (((x) & ((1 << 6) - 1)) << 8)
+#define F_VC_TABLE_37_RD(x) (((x) & (((1 << 6) - 1) << 8)) >> 8)
+#define F_VC_TABLE_38(x) (((x) & ((1 << 6) - 1)) << 16)
+#define F_VC_TABLE_38_RD(x) (((x) & (((1 << 6) - 1) << 16)) >> 16)
+#define F_VC_TABLE_39(x) (((x) & ((1 << 6) - 1)) << 24)
+#define F_VC_TABLE_39_RD(x) (((x) & (((1 << 6) - 1) << 24)) >> 24)
+
+/* register DP_VC_TABLE_10 */
+#define DP_VC_TABLE_10 16
+#define F_VC_TABLE_40(x) (((x) & ((1 << 6) - 1)) << 0)
+#define F_VC_TABLE_40_RD(x) (((x) & (((1 << 6) - 1) << 0)) >> 0)
+#define F_VC_TABLE_41(x) (((x) & ((1 << 6) - 1)) << 8)
+#define F_VC_TABLE_41_RD(x) (((x) & (((1 << 6) - 1) << 8)) >> 8)
+#define F_VC_TABLE_42(x) (((x) & ((1 << 6) - 1)) << 16)
+#define F_VC_TABLE_42_RD(x) (((x) & (((1 << 6) - 1) << 16)) >> 16)
+#define F_VC_TABLE_43(x) (((x) & ((1 << 6) - 1)) << 24)
+#define F_VC_TABLE_43_RD(x) (((x) & (((1 << 6) - 1) << 24)) >> 24)
+
+/* register DP_VC_TABLE_11 */
+#define DP_VC_TABLE_11 17
+#define F_VC_TABLE_44(x) (((x) & ((1 << 6) - 1)) << 0)
+#define F_VC_TABLE_44_RD(x) (((x) & (((1 << 6) - 1) << 0)) >> 0)
+#define F_VC_TABLE_45(x) (((x) & ((1 << 6) - 1)) << 8)
+#define F_VC_TABLE_45_RD(x) (((x) & (((1 << 6) - 1) << 8)) >> 8)
+#define F_VC_TABLE_46(x) (((x) & ((1 << 6) - 1)) << 16)
+#define F_VC_TABLE_46_RD(x) (((x) & (((1 << 6) - 1) << 16)) >> 16)
+#define F_VC_TABLE_47(x) (((x) & ((1 << 6) - 1)) << 24)
+#define F_VC_TABLE_47_RD(x) (((x) & (((1 << 6) - 1) << 24)) >> 24)
+
+/* register DP_VC_TABLE_12 */
+#define DP_VC_TABLE_12 18
+#define F_VC_TABLE_48(x) (((x) & ((1 << 6) - 1)) << 0)
+#define F_VC_TABLE_48_RD(x) (((x) & (((1 << 6) - 1) << 0)) >> 0)
+#define F_VC_TABLE_49(x) (((x) & ((1 << 6) - 1)) << 8)
+#define F_VC_TABLE_49_RD(x) (((x) & (((1 << 6) - 1) << 8)) >> 8)
+#define F_VC_TABLE_50(x) (((x) & ((1 << 6) - 1)) << 16)
+#define F_VC_TABLE_50_RD(x) (((x) & (((1 << 6) - 1) << 16)) >> 16)
+#define F_VC_TABLE_51(x) (((x) & ((1 << 6) - 1)) << 24)
+#define F_VC_TABLE_51_RD(x) (((x) & (((1 << 6) - 1) << 24)) >> 24)
+
+/* register DP_VC_TABLE_13 */
+#define DP_VC_TABLE_13 19
+#define F_VC_TABLE_52(x) (((x) & ((1 << 6) - 1)) << 0)
+#define F_VC_TABLE_52_RD(x) (((x) & (((1 << 6) - 1) << 0)) >> 0)
+#define F_VC_TABLE_53(x) (((x) & ((1 << 6) - 1)) << 8)
+#define F_VC_TABLE_53_RD(x) (((x) & (((1 << 6) - 1) << 8)) >> 8)
+#define F_VC_TABLE_54(x) (((x) & ((1 << 6) - 1)) << 16)
+#define F_VC_TABLE_54_RD(x) (((x) & (((1 << 6) - 1) << 16)) >> 16)
+#define F_VC_TABLE_55(x) (((x) & ((1 << 6) - 1)) << 24)
+#define F_VC_TABLE_55_RD(x) (((x) & (((1 << 6) - 1) << 24)) >> 24)
+
+/* register DP_VC_TABLE_14 */
+#define DP_VC_TABLE_14 20
+#define F_VC_TABLE_56(x) (((x) & ((1 << 6) - 1)) << 0)
+#define F_VC_TABLE_56_RD(x) (((x) & (((1 << 6) - 1) << 0)) >> 0)
+#define F_VC_TABLE_57(x) (((x) & ((1 << 6) - 1)) << 8)
+#define F_VC_TABLE_57_RD(x) (((x) & (((1 << 6) - 1) << 8)) >> 8)
+#define F_VC_TABLE_58(x) (((x) & ((1 << 6) - 1)) << 16)
+#define F_VC_TABLE_58_RD(x) (((x) & (((1 << 6) - 1) << 16)) >> 16)
+#define F_VC_TABLE_59(x) (((x) & ((1 << 6) - 1)) << 24)
+#define F_VC_TABLE_59_RD(x) (((x) & (((1 << 6) - 1) << 24)) >> 24)
+
+/* register LINE_THRESH */
+#define LINE_THRESH 21
+#define F_CFG_ACTIVE_LINE_TRESH(x) (((x) & ((1 << 6) - 1)) << 0)
+#define F_CFG_ACTIVE_LINE_TRESH_RD(x) (((x) & (((1 << 6) - 1) << 0)) >> 0)
+#define F_VC_TABLE_61(x) (((x) & ((1 << 6) - 1)) << 8)
+#define F_VC_TABLE_61_RD(x) (((x) & (((1 << 6) - 1) << 8)) >> 8)
+#define F_VC_TABLE_62(x) (((x) & ((1 << 6) - 1)) << 16)
+#define F_VC_TABLE_62_RD(x) (((x) & (((1 << 6) - 1) << 16)) >> 16)
+#define F_VC_TABLE_63(x) (((x) & ((1 << 6) - 1)) << 24)
+#define F_VC_TABLE_63_RD(x) (((x) & (((1 << 6) - 1) << 24)) >> 24)
+
+/* register DP_VB_ID */
+#define DP_VB_ID 22
+#define F_VB_ID(x) (((x) & ((1 << 8) - 1)) << 0)
+#define F_VB_ID_RD(x) (((x) & (((1 << 8) - 1) << 0)) >> 0)
+
+/* register DP_MTPH_LVP_CONTROL */
+#define DP_MTPH_LVP_CONTROL 23
+#define F_MTPH_LVP_EN(x) (((x) & ((1 << 1) - 1)) << 0)
+#define F_MTPH_LVP_EN_RD(x) (((x) & (((1 << 1) - 1) << 0)) >> 0)
+
+/* register DP_MTPH_SYMBOL_VALUES */
+#define DP_MTPH_SYMBOL_VALUES 24
+#define F_MPTH_LVP_SYM(x) (((x) & ((1 << 8) - 1)) << 0)
+#define F_MPTH_LVP_SYM_RD(x) (((x) & (((1 << 8) - 1) << 0)) >> 0)
+#define F_MTPH_ECF_SYM(x) (((x) & ((1 << 8) - 1)) << 8)
+#define F_MTPH_ECF_SYM_RD(x) (((x) & (((1 << 8) - 1) << 8)) >> 8)
+#define F_MTPH_MTPH_SYM(x) (((x) & ((1 << 8) - 1)) << 16)
+#define F_MTPH_MTPH_SYM_RD(x) (((x) & (((1 << 8) - 1) << 16)) >> 16)
+
+/* register DP_MTPH_ECF_CONTROL */
+#define DP_MTPH_ECF_CONTROL 25
+#define F_MPTH_ECF_EN(x) (((x) & ((1 << 1) - 1)) << 0)
+#define F_MPTH_ECF_EN_RD(x) (((x) & (((1 << 1) - 1) << 0)) >> 0)
+#define F_MTPH_ACT_EN(x) (((x) & ((1 << 1) - 1)) << 1)
+#define F_MTPH_ACT_EN_RD(x) (((x) & (((1 << 1) - 1) << 1)) >> 1)
+
+/* register DP_FIELDSEQ_3D */
+#define DP_FIELDSEQ_3D 26
+#define F_FIELD_SEQ_START(x) (((x) & ((1 << 16) - 1)) << 0)
+#define F_FIELD_SEQ_START_RD(x) (((x) & (((1 << 16) - 1) << 0)) >> 0)
+#define F_FIELD_SEQ_END(x) (((x) & ((1 << 16) - 1)) << 16)
+#define F_FIELD_SEQ_END_RD(x) (((x) & (((1 << 16) - 1) << 16)) >> 16)
+
+/* register DP_MTPH_STATUS */
+#define DP_MTPH_STATUS 27
+#define F_MTP_ACT_CNT_CTRL_CURR_STATE(x) (((x) & ((1 << 8) - 1)) << 0)
+#define F_MTP_ACT_CNT_CTRL_CURR_STATE_RD(x) (((x) & (((1 << 8) - 1) << 0)) >> 0)
+#define F_MTP_ECF_CNT_CTRL_CURR_STATE(x) (((x) & ((1 << 8) - 1)) << 8)
+#define F_MTP_ECF_CNT_CTRL_CURR_STATE_RD(x) (((x) & (((1 << 8) - 1) << 8)) >> 8)
+#define F_MTPH_ACT_STATUS(x) (((x) & ((1 << 1) - 1)) << 16)
+#define F_MTPH_ACT_STATUS_RD(x) (((x) & (((1 << 1) - 1) << 16)) >> 16)
+#define F_MTPH_ECF_STATUS(x) (((x) & ((1 << 1) - 1)) << 17)
+#define F_MTPH_ECF_STATUS_RD(x) (((x) & (((1 << 1) - 1) << 17)) >> 17)
+#define F_MTPH_LVP_STATUS(x) (((x) & ((1 << 1) - 1)) << 18)
+#define F_MTPH_LVP_STATUS_RD(x) (((x) & (((1 << 1) - 1) << 18)) >> 18)
+
+/* register DP_INTERRUPT_SOURCE */
+#define DP_INTERRUPT_SOURCE 28
+#define F_PSLVERR(x) (((x) & ((1 << 1) - 1)) << 0)
+#define F_PSLVERR_RD(x) (((x) & (((1 << 1) - 1) << 0)) >> 0)
+#define F_MTPH_ACT_EN_CLEAR(x) (((x) & ((1 << 1) - 1)) << 1)
+#define F_MTPH_ACT_EN_CLEAR_RD(x) (((x) & (((1 << 1) - 1) << 1)) >> 1)
+#define F_MTPH_LVP_EN_CLEAR(x) (((x) & ((1 << 1) - 1)) << 2)
+#define F_MTPH_LVP_EN_CLEAR_RD(x) (((x) & (((1 << 1) - 1) << 2)) >> 2)
+#define F_MTPH_ECF_EN_CLEAR(x) (((x) & ((1 << 1) - 1)) << 3)
+#define F_MTPH_ECF_EN_CLEAR_RD(x) (((x) & (((1 << 1) - 1) << 3)) >> 3)
+
+/* register DP_INTERRUPT_MASK */
+#define DP_INTERRUPT_MASK 29
+#define F_PSLVERR_MASK(x) (((x) & ((1 << 1) - 1)) << 0)
+#define F_PSLVERR_MASK_RD(x) (((x) & (((1 << 1) - 1) << 0)) >> 0)
+#define F_MTPH_ACT_EN_CLEAR_MASK(x) (((x) & ((1 << 1) - 1)) << 1)
+#define F_MTPH_ACT_EN_CLEAR_MASK_RD(x) (((x) & (((1 << 1) - 1) << 1)) >> 1)
+#define F_MTPH_LVP_EN_CLEAR_MASK(x) (((x) & ((1 << 1) - 1)) << 2)
+#define F_MTPH_LVP_EN_CLEAR_MASK_RD(x) (((x) & (((1 << 1) - 1) << 2)) >> 2)
+#define F_MTPH_ECF_EN_CLEAR_MASK(x) (((x) & ((1 << 1) - 1)) << 3)
+#define F_MTPH_ECF_EN_CLEAR_MASK_RD(x) (((x) & (((1 << 1) - 1) << 3)) >> 3)
+
+/* register DP_FRONT_BACK_PORCH */
+#define DP_FRONT_BACK_PORCH 30
+#define F_BACK_PORCH(x) (((x) & ((1 << 16) - 1)) << 0)
+#define F_BACK_PORCH_RD(x) (((x) & (((1 << 16) - 1) << 0)) >> 0)
+#define F_FRONT_PORCH(x) (((x) & ((1 << 16) - 1)) << 16)
+#define F_FRONT_PORCH_RD(x) (((x) & (((1 << 16) - 1) << 16)) >> 16)
+
+/* register DP_BYTE_COUNT */
+#define DP_BYTE_COUNT 31
+#define F_BYTE_COUNT(x) (((x) & ((1 << 16) - 1)) << 0)
+#define F_BYTE_COUNT_RD(x) (((x) & (((1 << 16) - 1) << 0)) >> 0)
+
+#endif //DPTX_FRAMER
diff --git a/drivers/mxc/hdp/dptx_stream.h b/drivers/mxc/hdp/dptx_stream.h
new file mode 100644
index 000000000000..c8235a171e7c
--- /dev/null
+++ b/drivers/mxc/hdp/dptx_stream.h
@@ -0,0 +1,208 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2016-2017 Cadence Design Systems, Inc.
+ * All rights reserved worldwide.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 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.
+ *
+ * Copyright 2017 NXP
+ *
+ ******************************************************************************
+ *
+ * This file was auto-generated. Do not edit it manually.
+ *
+ ******************************************************************************
+ *
+ * dptx_stream.h
+ *
+ ******************************************************************************
+ */
+
+#ifndef DPTX_STREAM_H_
+#define DPTX_STREAM_H_
+
+/* register MSA_HORIZONTAL_0 */
+#define MSA_HORIZONTAL_0 32
+#define F_PCK_STUFF_HTOTAL(x) (((x) & ((1 << 16) - 1)) << 0)
+#define F_PCK_STUFF_HTOTAL_RD(x) (((x) & (((1 << 16) - 1) << 0)) >> 0)
+#define F_PCK_STUFF_HSTART(x) (((x) & ((1 << 16) - 1)) << 16)
+#define F_PCK_STUFF_HSTART_RD(x) (((x) & (((1 << 16) - 1) << 16)) >> 16)
+
+/* register MSA_HORIZONTAL_1 */
+#define MSA_HORIZONTAL_1 33
+#define F_PCK_STUFF_HSYNCWIDTH(x) (((x) & ((1 << 15) - 1)) << 0)
+#define F_PCK_STUFF_HSYNCWIDTH_RD(x) (((x) & (((1 << 15) - 1) << 0)) >> 0)
+#define F_PCK_STUFF_HSYNCPOLARITY(x) (((x) & ((1 << 1) - 1)) << 15)
+#define F_PCK_STUFF_HSYNCPOLARITY_RD(x) (((x) & (((1 << 1) - 1) << 15)) >> 15)
+#define F_PCK_STUFF_HWIDTH(x) (((x) & ((1 << 16) - 1)) << 16)
+#define F_PCK_STUFF_HWIDTH_RD(x) (((x) & (((1 << 16) - 1) << 16)) >> 16)
+
+/* register MSA_VERTICAL_0 */
+#define MSA_VERTICAL_0 34
+#define F_PCK_STUFF_VTOTAL(x) (((x) & ((1 << 16) - 1)) << 0)
+#define F_PCK_STUFF_VTOTAL_RD(x) (((x) & (((1 << 16) - 1) << 0)) >> 0)
+#define F_PCK_STUFF_VSTART(x) (((x) & ((1 << 16) - 1)) << 16)
+#define F_PCK_STUFF_VSTART_RD(x) (((x) & (((1 << 16) - 1) << 16)) >> 16)
+
+/* register MSA_VERTICAL_1 */
+#define MSA_VERTICAL_1 35
+#define F_PCK_STUFF_VSYNCWIDTH(x) (((x) & ((1 << 15) - 1)) << 0)
+#define F_PCK_STUFF_VSYNCWIDTH_RD(x) (((x) & (((1 << 15) - 1) << 0)) >> 0)
+#define F_PCK_STUFF_VSYNCPOLARITY(x) (((x) & ((1 << 1) - 1)) << 15)
+#define F_PCK_STUFF_VSYNCPOLARITY_RD(x) (((x) & (((1 << 1) - 1) << 15)) >> 15)
+#define F_PCK_STUFF_VHEIGHT(x) (((x) & ((1 << 16) - 1)) << 16)
+#define F_PCK_STUFF_VHEIGHT_RD(x) (((x) & (((1 << 16) - 1) << 16)) >> 16)
+
+/* register MSA_MISC */
+#define MSA_MISC 36
+#define F_MSA_MISC0(x) (((x) & ((1 << 8) - 1)) << 0)
+#define F_MSA_MISC0_RD(x) (((x) & (((1 << 8) - 1) << 0)) >> 0)
+#define F_MSA_MISC1(x) (((x) & ((1 << 8) - 1)) << 8)
+#define F_MSA_MISC1_RD(x) (((x) & (((1 << 8) - 1) << 8)) >> 8)
+#define F_MSA_MISC1_INV(x) (((x) & ((1 << 1) - 1)) << 16)
+#define F_MSA_MISC1_INV_RD(x) (((x) & (((1 << 1) - 1) << 16)) >> 16)
+#define F_MSA_IN_MID_INTERLACE_EN(x) (((x) & ((1 << 1) - 1)) << 17)
+#define F_MSA_IN_MID_INTERLACE_EN_RD(x) (((x) & (((1 << 1) - 1) << 17)) >> 17)
+
+/* register STREAM_CONFIG */
+#define STREAM_CONFIG 37
+#define F_STREAM_NUM(x) (((x) & ((1 << 6) - 1)) << 0)
+#define F_STREAM_NUM_RD(x) (((x) & (((1 << 6) - 1) << 0)) >> 0)
+
+/* register AUDIO_PACK_STATUS */
+#define AUDIO_PACK_STATUS 38
+#define F_AP_FIFO_EMPTY(x) (((x) & ((1 << 1) - 1)) << 0)
+#define F_AP_FIFO_EMPTY_RD(x) (((x) & (((1 << 1) - 1) << 0)) >> 0)
+#define F_AP_FIFO_FULL(x) (((x) & ((1 << 1) - 1)) << 1)
+#define F_AP_FIFO_FULL_RD(x) (((x) & (((1 << 1) - 1) << 1)) >> 1)
+#define F_AP_AIF_FSM_CURR_ST(x) (((x) & ((1 << 1) - 1)) << 2)
+#define F_AP_AIF_FSM_CURR_ST_RD(x) (((x) & (((1 << 1) - 1) << 2)) >> 2)
+#define F_AP_SDP_TRANSFER_FSM_CURR_ST(x) (((x) & ((1 << 3) - 1)) << 3)
+#define F_AP_SDP_TRANSFER_FSM_CURR_ST_RD(x) (((x) & (((1 << 3) - 1) << 3)) >> 3)
+#define F_AP_FIFO_RD_FSM_CURR_ST(x) (((x) & ((1 << 2) - 1)) << 6)
+#define F_AP_FIFO_RD_FSM_CURR_ST_RD(x) (((x) & (((1 << 2) - 1) << 6)) >> 6)
+#define F_AP_FIFO_WR_FSM_CURR_ST(x) (((x) & ((1 << 2) - 1)) << 8)
+#define F_AP_FIFO_WR_FSM_CURR_ST_RD(x) (((x) & (((1 << 2) - 1) << 8)) >> 8)
+#define F_AP_PARITY_FSM_CURRENT_STATE(x) (((x) & ((1 << 3) - 1)) << 10)
+#define F_AP_PARITY_FSM_CURRENT_STATE_RD(x) (((x) & (((1 << 3) - 1) << 10)) >> 10)
+#define F_AUDIO_TS_VERSION(x) (((x) & ((1 << 6) - 1)) << 16)
+#define F_AUDIO_TS_VERSION_RD(x) (((x) & (((1 << 6) - 1) << 16)) >> 16)
+
+/* register VIF_STATUS */
+#define VIF_STATUS 39
+#define F_VIF_FIFO_EMPTY(x) (((x) & ((1 << 1) - 1)) << 0)
+#define F_VIF_FIFO_EMPTY_RD(x) (((x) & (((1 << 1) - 1) << 0)) >> 0)
+#define F_VIF_FIFO_FULL(x) (((x) & ((1 << 1) - 1)) << 1)
+#define F_VIF_FIFO_FULL_RD(x) (((x) & (((1 << 1) - 1) << 1)) >> 1)
+#define F_VIF_WR_CTRL_STATE(x) (((x) & ((1 << 6) - 1)) << 2)
+#define F_VIF_WR_CTRL_STATE_RD(x) (((x) & (((1 << 6) - 1) << 2)) >> 2)
+#define F_VIF_RD_CTRL_STATE(x) (((x) & ((1 << 20) - 1)) << 8)
+#define F_VIF_RD_CTRL_STATE_RD(x) (((x) & (((1 << 20) - 1) << 8)) >> 8)
+
+/* register PCK_STUFF_STATUS_0 */
+#define PCK_STUFF_STATUS_0 40
+#define F_NO_VIDEO_GEN_STATE(x) (((x) & ((1 << 5) - 1)) << 0)
+#define F_NO_VIDEO_GEN_STATE_RD(x) (((x) & (((1 << 5) - 1) << 0)) >> 0)
+#define F_SST_VIDEO_GEN_STATE(x) (((x) & ((1 << 7) - 1)) << 8)
+#define F_SST_VIDEO_GEN_STATE_RD(x) (((x) & (((1 << 7) - 1) << 8)) >> 8)
+#define F_MST_VIDEO_GEN_STATE(x) (((x) & ((1 << 6) - 1)) << 16)
+#define F_MST_VIDEO_GEN_STATE_RD(x) (((x) & (((1 << 6) - 1) << 16)) >> 16)
+#define F_MSA_GEN_STATE(x) (((x) & ((1 << 7) - 1)) << 24)
+#define F_MSA_GEN_STATE_RD(x) (((x) & (((1 << 7) - 1) << 24)) >> 24)
+
+/* register PCK_STUFF_STATUS_1 */
+#define PCK_STUFF_STATUS_1 41
+#define F_SST_SS_GEN_STATE(x) (((x) & ((1 << 6) - 1)) << 0)
+#define F_SST_SS_GEN_STATE_RD(x) (((x) & (((1 << 6) - 1) << 0)) >> 0)
+#define F_MST_SS_GEN_STATE(x) (((x) & ((1 << 6) - 1)) << 8)
+#define F_MST_SS_GEN_STATE_RD(x) (((x) & (((1 << 6) - 1) << 8)) >> 8)
+
+/* register INFO_PACK_STATUS */
+#define INFO_PACK_STATUS 42
+#define F_INFO_PACK_FIFO_FULL(x) (((x) & ((1 << 1) - 1)) << 0)
+#define F_INFO_PACK_FIFO_FULL_RD(x) (((x) & (((1 << 1) - 1) << 0)) >> 0)
+#define F_INFO_PACK_FIFO_EMPTY(x) (((x) & ((1 << 1) - 1)) << 1)
+#define F_INFO_PACK_FIFO_EMPTY_RD(x) (((x) & (((1 << 1) - 1) << 1)) >> 1)
+#define F_IP_PARITY_FSM_CURRENT_STATE(x) (((x) & ((1 << 3) - 1)) << 2)
+#define F_IP_PARITY_FSM_CURRENT_STATE_RD(x) (((x) & (((1 << 3) - 1) << 2)) >> 2)
+#define F_IP_FIFO_WR_FSM_CURRENT_STATE(x) (((x) & ((1 << 3) - 1)) << 5)
+#define F_IP_FIFO_WR_FSM_CURRENT_STATE_RD(x) (((x) & (((1 << 3) - 1) << 5)) >> 5)
+#define F_IP_FIFO_RD_FSM_CURRENT_STATE(x) (((x) & ((1 << 4) - 1)) << 8)
+#define F_IP_FIFO_RD_FSM_CURRENT_STATE_RD(x) (((x) & (((1 << 4) - 1) << 8)) >> 8)
+#define F_IP_SEND_DATA_FSM_CURRENT_STATE(x) (((x) & ((1 << 4) - 1)) << 12)
+#define F_IP_SEND_DATA_FSM_CURRENT_STATE_RD(x) (((x) & (((1 << 4) - 1) << 12)) >> 12)
+#define F_IN_VBID(x) (((x) & ((1 << 8) - 1)) << 24)
+#define F_IN_VBID_RD(x) (((x) & (((1 << 8) - 1) << 24)) >> 24)
+
+/* register RATE_GOVERNOR_STATUS */
+#define RATE_GOVERNOR_STATUS 43
+#define F_RATE_GOVERNOR_FSM_STATE(x) (((x) & ((1 << 3) - 1)) << 0)
+#define F_RATE_GOVERNOR_FSM_STATE_RD(x) (((x) & (((1 << 3) - 1) << 0)) >> 0)
+#define F_CFG_TU_VS_DIFF(x) (((x) & ((1 << 2) - 1)) << 8)
+#define F_CFG_TU_VS_DIFF_RD(x) (((x) & (((1 << 2) - 1) << 8)) >> 8)
+#define F_CFG_HSYNC_DELAY(x) (((x) & ((1 << 8) - 1)) << 16)
+#define F_CFG_HSYNC_DELAY_RD(x) (((x) & (((1 << 8) - 1) << 16)) >> 16)
+#define F_CFG_EN_HSYNC_DELAY(x) (((x) & ((1 << 1) - 1)) << 24)
+#define F_CFG_EN_HSYNC_DELAY_RD(x) (((x) & (((1 << 1) - 1) << 24)) >> 24)
+
+/* register DP_HORIZONTAL */
+#define DP_HORIZONTAL 44
+#define F_HSYNCWIDTH(x) (((x) & ((1 << 15) - 1)) << 0)
+#define F_HSYNCWIDTH_RD(x) (((x) & (((1 << 15) - 1) << 0)) >> 0)
+#define F_HWIDTH(x) (((x) & ((1 << 16) - 1)) << 16)
+#define F_HWIDTH_RD(x) (((x) & (((1 << 16) - 1) << 16)) >> 16)
+
+/* register DP_VERTICAL_0 */
+#define DP_VERTICAL_0 45
+#define F_VHEIGHT(x) (((x) & ((1 << 16) - 1)) << 0)
+#define F_VHEIGHT_RD(x) (((x) & (((1 << 16) - 1) << 0)) >> 0)
+#define F_VSTART(x) (((x) & ((1 << 16) - 1)) << 16)
+#define F_VSTART_RD(x) (((x) & (((1 << 16) - 1) << 16)) >> 16)
+
+/* register DP_VERTICAL_1 */
+#define DP_VERTICAL_1 46
+#define F_VTOTAL(x) (((x) & ((1 << 16) - 1)) << 0)
+#define F_VTOTAL_RD(x) (((x) & (((1 << 16) - 1) << 0)) >> 0)
+#define F_VTOTAL_EVEN(x) (((x) & ((1 << 1) - 1)) << 16)
+#define F_VTOTAL_EVEN_RD(x) (((x) & (((1 << 1) - 1) << 16)) >> 16)
+
+/* register DP_BLOCK_SDP */
+#define DP_BLOCK_SDP 47
+#define F_BLOCK_SDP_BS(x) (((x) & ((1 << 8) - 1)) << 0)
+#define F_BLOCK_SDP_BS_RD(x) (((x) & (((1 << 8) - 1) << 0)) >> 0)
+#define F_BLOCK_SDP_BE(x) (((x) & ((1 << 8) - 1)) << 8)
+#define F_BLOCK_SDP_BE_RD(x) (((x) & (((1 << 8) - 1) << 8)) >> 8)
+#define F_NO_VIDEO_BLOCK_SDP(x) (((x) & ((1 << 12) - 1)) << 16)
+#define F_NO_VIDEO_BLOCK_SDP_RD(x) (((x) & (((1 << 12) - 1) << 16)) >> 16)
+
+#endif //DPTX_STREAM
diff --git a/drivers/mxc/hdp/general_handler.h b/drivers/mxc/hdp/general_handler.h
new file mode 100644
index 000000000000..a32ddce67013
--- /dev/null
+++ b/drivers/mxc/hdp/general_handler.h
@@ -0,0 +1,160 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2016-2018 Cadence Design Systems, Inc.
+ * All rights reserved worldwide.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 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.
+ *
+ * Copyright 2017-2018 NXP
+ *
+ ******************************************************************************
+ *
+ * This file was auto-generated. Do not edit it manually.
+ *
+ ******************************************************************************
+ *
+ * general_handler.h
+ *
+ ******************************************************************************
+ */
+
+#ifndef GENERAL_HANDLER_H
+#define GENERAL_HANDLER_H
+
+/**
+ * \brief opcode defines host->controller
+ */
+#define GENERAL_MAIN_CONTROL 0x01
+#define GENERAL_TEST_ECHO 0x02
+#define GENERAL_BUS_SETTINGS 0x03
+#define GENERAL_TEST_ACCESS 0x04
+
+#define GENERAL_WRITE_REGISTER 0x05
+#define GENERAL_WRITE_FIELD 0x06
+#define GENERAL_READ_REGISTER 0x07
+#define GENERAL_GET_HPD_STATE 0x11
+
+#define GENERAL_TEST_TRNG_SIMPLE 0xF0
+
+#define GENERAL_MAIN_CONTROL_SET_ACTIVE_BIT 0
+#define GENERAL_MAIN_CONTROL_SET_ALT_CIPHER_ADDR 1
+#define GENERAL_MAIN_CONTROL_SET_FAST_HDCP_DELAYS 2
+
+#define GENERAL_BUS_SETTINGS_DPCD_BUS_BIT 0
+#define GENERAL_BUS_SETTINGS_DPCD_BUS_LOCK_BIT 1
+#define GENERAL_BUS_SETTINGS_HDCP_BUS_BIT 2
+#define GENERAL_BUS_SETTINGS_HDCP_BUS_LOCK_BIT 3
+#define GENERAL_BUS_SETTINGS_CAPB_OWNER_BIT 4
+#define GENERAL_BUS_SETTINGS_CAPB_OWNER_LOCK_BIT 5
+
+/**
+ * \brief opcode defines controller->host
+ */
+
+#define GENERAL_MAIN_CONTROL_RESP 0x01
+#define GENERAL_TEST_ECHO_RESP 0x02
+#define GENERAL_BUS_SETTINGS_RESP 0x03
+
+#define GENERAL_READ_REGISTER_RESP 0x07
+
+#define GENERAL_BUS_SETTINGS_RESP_DPCD_BUS_BIT 0
+#define GENERAL_BUS_SETTINGS_RESP_HDCP_BUS_BIT 1
+#define GENERAL_BUS_SETTINGS_RESP_CAPB_OWNER_BIT 2
+
+#define GENERAL_BUS_SETTINGS_RESP_SUCCESS 0
+#define GENERAL_BUS_SETTINGS_RESP_LOCK_ERROR 1
+
+typedef struct {
+ unsigned char dpcd_locked;
+ unsigned char hdcp_locked;
+ unsigned char capb_locked;
+ unsigned char active_mode;
+} S_GENERAL_HANDLER_DATA;
+
+/**
+ * \brief event id sent to the host
+ */
+typedef enum {
+ EVENT_ID_DPTX_HPD = 0,
+ EVENT_ID_HDMI_TX_HPD = 0,
+ EVENT_ID_HDMI_RX_5V = 0,
+
+ EVENT_ID_DPTX_TRAINING = 1,
+ EVENT_ID_HDMI_RX_SCDC_CHANGE = 1,
+
+ EVENT_ID_RESERVE0 = 2,
+ EVENT_ID_RESERVE1 = 3,
+
+ EVENT_ID_HDCPTX_STATUS = 4,
+ EVENT_ID_HDCPRX_STATUS = 4,
+
+ EVENT_ID_HDCPTX_IS_KM_STORED = 5,
+ EVENT_ID_HDCPTX_STORE_KM = 6,
+ EVENT_ID_HDCPTX_IS_RECEIVER_ID_VALID = 7,
+ EVENT_ID_HDMITX_READ_REQUEST = 8,
+} EVENT_ID;
+
+/**
+ * \brief convert bank id and register number to address and write to ptr
+ */
+
+#define select_reg_old(bank, reg_no, ptr) \
+{ \
+ ptr = 0; \
+ if ((bank == 0x22) || (bank == 0x20) || (bank == 0x0b) || (bank == 0x09) || (bank == 0x0A)) \
+ ptr = (u32 *)(bank << 8 | reg_no); \
+}
+
+#define select_reg(bank, reg_no, ptr) \
+do { \
+ ptr = (u32 *)(bank << 8 | reg_no); \
+} while (0)
+
+#define select_reg4(pmsb, p2, p3, plsb, ptr) \
+do { \
+ ptr = (u32 *)((pmsb << 24) | (p2 << 16) | (p3 << 8) | (plsb << 0)); \
+} while (0)
+
+#define EVENTS_DPTX_CNT 2
+#define EVENTS_HDCPTX_CNT 4
+
+void general_handler_set_active_mode(void);
+void general_handler_set_standby_mode(void);
+
+/**
+ * \brief request sending en event to the host
+ * \param [in] eventId
+ * \param [in] eventCode
+ */
+
+#endif /* GENERAL_HANDLER_H */
diff --git a/drivers/mxc/hdp/hdcp.h b/drivers/mxc/hdp/hdcp.h
new file mode 100644
index 000000000000..d756541dc9d1
--- /dev/null
+++ b/drivers/mxc/hdp/hdcp.h
@@ -0,0 +1,52 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2016-2017 Cadence Design Systems, Inc.
+ * All rights reserved worldwide.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 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.
+ *
+ * Copyright 2017 NXP
+ *
+ ******************************************************************************
+ *
+ * hdcp.h
+ *
+ ******************************************************************************
+ */
+
+#ifndef HDCP_H
+#define HDCP_H
+# include "mailBox.h"
+
+#define RX_TX_HDCP_TRANS_MAX_BUFFER 640
+#endif //HDCP_H
diff --git a/drivers/mxc/hdp/hdcp2.h b/drivers/mxc/hdp/hdcp2.h
new file mode 100644
index 000000000000..df11446b3ba1
--- /dev/null
+++ b/drivers/mxc/hdp/hdcp2.h
@@ -0,0 +1,289 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2016-2017 Cadence Design Systems, Inc.
+ * All rights reserved worldwide.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 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.
+ *
+ * Copyright 2017 NXP
+ *
+ ******************************************************************************
+ *
+ * This file was auto-generated. Do not edit it manually.
+ *
+ ******************************************************************************
+ *
+ * hdcp2.h
+ *
+ ******************************************************************************
+ */
+
+#ifndef HDCP2_H
+#define HDCP2_H
+#include "mailBox.h"
+/* HDCP 2 registers
+ * and general use function for HDCP2 (transmitter and receiver)
+ * Author - yehonatan levin - cadence */
+/**
+ * \file
+ * \brief HDCP 2 registers
+ * and general use function for HDCP2 (trasmiter and reciever)
+ */
+
+/* HDCP2 register list */
+
+#ifdef DP_TX
+#define HDCP2_RTX 0x69000
+#define HDCP2_TX_CAPS 0x69008
+#define HDCP2_CERT_RX 0x6900B
+#define HDCP2_RRX 0x69215
+#define HDCP2_RX_CAPS 0x6921D
+#define HDCP2_EKPUB_KM 0x69220
+#define HDCP2_EKH_KM_WR 0x692A0
+#define HDCP2_M 0x692B0
+#define HDCP2_H_TAG 0x692C0
+#define HDCP2_EKH_KM_RD 0x692E0
+#define HDCP2_RN 0x692F0
+#define HDCP2_L_TAG 0x692F8
+#define HDCP2_EDKEY_KS 0x69318
+#define HDCP2_RIV 0x69328
+#define HDCP2_RX_INFO 0x69330
+#define HDCP2_SEQ_NUM_V 0x69332
+#define HDCP2_V_TAG 0x69335
+#define HDCP2_RECEIVER_ID_LIST 0x69345
+#define HDCP2_V 0x693E0
+#define HDCP2_SEQ_NUM_M 0x693F0
+#define HDCP2_K 0x693F3
+#define HDCP2_STREAM_ID_TYPE 0x693F5
+#define HDCP2_M_TAG 0x69473
+#define HDCP2_RXSTATUS 0x69493
+#define HDCP2_RSVD 0x69494
+#define HDCP2_DBG 0x69518
+
+#else /* HDMI */
+#define HDCP2_HDCP14 0x0
+#define HDCP2_RSVD1 0x44
+#define HDCP2_HDCP2_VERSION 0x50
+#define HDCP2_RSVD2 0x51
+#define HDCP2_WRITE_MESSAGE 0x60
+#define HDCP2_RSVD3 0x61
+#define HDCP2_RXSTATUS 0x70
+#define HDCP2_RSVD4 0x72
+#define HDCP2_READ_MESSAGE 0x80
+#define HDCP2_RSVD5 0x81
+#define HDCP2_DBG 0xC0
+#endif
+
+/* HDCP2 commands */
+#define HDCP2_CMD_AKE_INIT 2
+#define HDCP2_CMD_AKE_SEND_CERT 3
+#define HDCP2_CMD_AKE_NO_STORED_KM 4
+#define HDCP2_CMD_AKE_STORED_KM 5
+#define HDCP2_CMD_AKE_SEND_H_PRIME 7
+#define HDCP2_CMD_AKE_SEND_PAIRING_INFO 8
+#define HDCP2_CMD_LC_INIT 9
+#define HDCP2_CMD_LC_SEND_L_PRIME 10
+#define HDCP2_SKE_SEND_EKS 11
+#define HDCP2_REPEATER_AUTH_SEND_RECEIVER_ID_LIST 12
+#define HDCP2_REPEATER_AUTH_SEND_ACK 15
+#define HDCP2_REPEATER_AUTH_STREAM_MANAGE 16
+#define HDCP2_REPEATER_AUTH_STREAM_READY 17
+
+/* values */
+#define HDCP2_VAL_HDCP2_VERSION_SUPPORTED 2
+
+#define LC_128_LEN 16
+extern u8 pHdcpLc128[LC_128_LEN];
+
+typedef enum {
+ HDCP2_NOT_FINISHED = 0x11,
+ HDCP2_FINISHED
+} HDCP_2_REC_RES;
+
+/* command structs */
+/* AKE INIT */
+typedef struct {
+ u8 version;
+ u8 transmitter_capability_mask[2];
+} S_HDCP2_TXCAPS;
+
+typedef struct {
+ u8 rtx[8];
+ S_HDCP2_TXCAPS txcaps;
+} S_HDCP2_CMD_AKE_INIT;
+
+/* AKE_SEND_CERT */
+
+typedef struct {
+ u8 cert_rx[522];
+ u8 r_rx[8];
+ u8 rxcaps[3];
+} S_HDCP2_CMD_AKE_SEND_CERT;
+
+/* AKE_NO_STORED_KM */
+
+typedef struct {
+ u8 ekpub_km[128];
+} S_HDCP2_CMD_AKE_NO_STORED_KM;
+
+/* AKE_STORED_KM */
+
+typedef struct {
+ u8 ekh_km[16];
+ u8 m[16];
+} S_HDCP2_CMD_AKE_STORED_KM;
+
+/* AKE_SEND_H_PRIME */
+
+typedef struct {
+ u8 h[32];
+} S_HDCP2_CMD_AKE_SEND_H_PRIME;
+
+/* AKE_SEND_PAIRING_INFO */
+
+typedef struct {
+ u8 Ekh_Km[16];
+} S_HDCP2_CMD_AKE_SEND_PAIRING_INFO;
+
+/* LC_Init */
+
+typedef struct {
+ u8 rn[8];
+} S_HDCP2_CMD_LC_Init;
+
+/* LC_Send_L_Prime */
+
+typedef struct {
+ u8 l[32];
+} S_HDCP2_CMD_LC_Send_L_Prime;
+
+/* LC_Send_Eks */
+
+typedef struct {
+ u8 Edkey_Ks[16];
+ u8 Riv[8];
+} S_HDCP2_CMD_SKE_Send_Eks;
+
+/* REPEATER_AUTH_SEND_RECEIVER_ID_LIST */
+
+typedef struct {
+ u8 RxInfo[2];
+ u8 seq_num_V[3];
+ u8 V[16]; /* max device count * 5 */
+} S_HDCP2_CMD_REPEATER_AUTH_SEND_RECEIVER_ID_LIST;
+
+/* HDCP2_RxInfo bits */
+typedef struct {
+ u16 HDCP1_DEVICE_DOWNSTREAM:1;
+ u16 HDCP2_0_REPEATER_DOWNSTREAM:1;
+ u16 MAX_CASCADE_EXCEEDED:1;
+ u16 MAX_DEVS_EXCEEDED:1;
+ u16 DEVICE_COUNT:5;
+ u16 DEPTH:3;
+} S_HDCP2_RX_INFO_BITS;
+
+typedef union {
+ S_HDCP2_RX_INFO_BITS bits;
+ u16 value16Bit;
+} U_HDCP2_RX_INFO;
+
+/* REPEATER_AUTH_SEND_ACK */
+
+typedef struct {
+ u8 v[16];
+} S_HDCP2_CMD_REPEATER_AUTH_SEND_ACK;
+
+/* REPEATER_AUTH_STREAM_MANAGE */
+
+typedef struct {
+ u8 seq_num_m[3];
+ u8 k[2];
+ u8 streamId_Type[2]; /* should be k*2 by spec??? */
+} S_HDCP2_CMD_REPEATER_AUTH_STREAM_MANAGE;
+
+/* REPEATER_AUTH_STREAM_READY */
+
+typedef struct {
+ u8 m[32];
+} S_HDCP2_CMD_REPEATER_AUTH_STREAM_READY;
+
+/* HDCP2_RXSTATUS bits */
+#ifdef DP_TX
+typedef struct {
+
+ u8 READY:1;
+ u8 H_AVAILABLE:1;
+ u8 PAIRING_AVAILABLE:1;
+ u8 REAUTH_REQ:1;
+ u8 LINK_INTEGRITY_FAILURE:1;
+ u8 RSVD:3;
+} S_HDCP2_RX_STATUS_BITS;
+#else
+typedef struct {
+ u16 Message_Size:10;
+ u16 READY:1;
+ u16 REAUTH_REQ:1;
+ u16 RSVD:4;
+} S_HDCP2_RX_STATUS_BITS;
+
+#endif
+
+typedef union {
+ S_HDCP2_RX_STATUS_BITS bits;
+ u16 value16Bit;
+} U_HDCP2_RX_STATUS;
+
+/* HDCP ports mail box messages */
+typedef enum {
+ HDCP_GENERAL_SET_LC_128 = 0,
+ HDCP_SET_SEED,
+} HDCP_GENERAL_MSG;
+
+/**
+ * \brief get command length for specific command
+ *
+ * \param [in] offset offset of the command
+ * \return Return_Description
+ *
+ */
+u32 hdcp2_commandLen(u32 offset);
+/**
+ * \brief message length for specific message
+ *
+ * \param [in] msg the message
+ * \return the size of this message
+ *
+ */
+u32 hdcp2_MsgcommandLen(u8 msg);
+
+#endif
diff --git a/drivers/mxc/hdp/hdcp_tran.h b/drivers/mxc/hdp/hdcp_tran.h
new file mode 100644
index 000000000000..b80c8e05e860
--- /dev/null
+++ b/drivers/mxc/hdp/hdcp_tran.h
@@ -0,0 +1,258 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2016-2017 Cadence Design Systems, Inc.
+ * All rights reserved worldwide.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 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.
+ *
+ * Copyright 2017 NXP
+ *
+ ******************************************************************************
+ *
+ * hdcp_tran.h
+ *
+ ******************************************************************************
+ */
+
+#ifndef HDCP_TRAN_H
+#define HDCP_TRAN_H
+
+#include "hdcp.h"
+
+/**
+ * \file
+ * \brief general HDCP2 transmitter function and data structures
+ */
+
+/* supported HDCP TX ports */
+typedef enum {
+ HDCP_TX_PORT_0,
+ HDCP_TX_PORT_1,
+ HDCP_TX_PORT_2,
+ HDCP_TX_PORT_3,
+ HDCP_TX_NUM_OF_PORTS,
+} HDCP_TX_PORT;
+
+/* HDCP TX ports working mode (HDCP 2.2 or 1.4) */
+typedef enum {
+ HDCP_TX_2, /* lock only with HDCP2 */
+ HDCP_TX_1, /* lock only with HDCP1 */
+ HDCP_TX_BOTH, /* lock on HDCP2 or 1 depend on other side */
+} HDCP_TX_MODE;
+
+/* HDCP TX ports stream type (relevant if receiver is repeater) */
+typedef enum {
+ HDCP_CONTENT_TYPE_0, /* May be transmitted by The HDCP Repeater to all HDCP Devices. */
+ HDCP_CONTENT_TYPE_1, /* Must not be transmitted by the HDCP Repeater to HDCP 1.x-compliant Devices and HDCP 2.0-compliant Repeaters */
+} HDCP_TX_CONTENT_STREAM_TYPE;
+
+/* HDCP TX ports stream packet status */
+typedef enum {
+ HDCP_CONTENT_NEED_TO_SEND,
+ HDCP_CONTENT_SENT_AND_WAIT_FOR_RESPOND,
+ HDCP_CONTENT_SENT_AND_FAILED,
+ HDCP_CONTENT_SUCCESS,
+} HDCP_TX_CONTENT_STREAM_STATUS;
+
+/* HDCP TX ports working mode (HDCP 2.2 or 1.4) */
+typedef enum {
+ HDCP_TX_NOT_ACTIVE,
+ HDCP_TX_NOT_CONFIGURED,
+ HDCP_TX_START,
+ HDCP_TX_WAIT_FOR_RX_TYPE,
+ HDCP_TX_ACTION
+} HDCP_TX_STATE;
+
+typedef union {
+ struct {
+ HDCP_TX_MODE port_supported_modes:2;
+ HDCP_TX_MODE port_cur_mode:2;
+ HDCP_TX_STATE port_state:4;
+ HDCP_TX_CONTENT_STREAM_TYPE contentType:1;
+ HDCP_TX_CONTENT_STREAM_STATUS content_status:2;
+ u8 statusWasUpdated:1;
+ u8 errorWasUpdated:1;
+ u8 ENABLE_1_1_FEATURES:1;
+ u8 ENABLE_1_1_FEATURES_onCurrentConnection:1;
+ u8 hdmi_mode:1;
+ u8 irq:1;
+ } fields;
+ u32 bits;
+} U_HDCP_TRANS_PORT_DATA_STATUS;
+
+/* struct holding data needed to the HDCP transmitter */
+#define TX_PORT_STATUS_EXTRA_DATA 3
+typedef struct {
+
+ U_HDCP_TRANS_PORT_DATA_STATUS status;
+ u16 port_status;
+ u8 port_status_extraData[TX_PORT_STATUS_EXTRA_DATA];
+ u32 seq_num_M; /* for sending content stream manage */
+ u32 seq_num_V;
+ u8 rxTxBuffer[RX_TX_HDCP_TRANS_MAX_BUFFER];
+
+ u8 recieverIdListCommand[(128 * 5) + 4];
+ u32 recieverIdListSize;
+ MB_TYPE mailBoxType;
+
+} S_HDCP_TRANS_PORT_DATA;
+
+typedef struct {
+ S_HDCP_TRANS_PORT_DATA port[HDCP_TX_NUM_OF_PORTS];
+} S_HDCP_TRANS_DATA;
+
+/* HDCP TX ports working mode (HDCP 2.2 or 1.4) */
+
+/**
+ *
+ * \brief transmitter supported API (via mail box)
+ */
+typedef enum {
+ HDCP_TX_CONFIGURATION, /*!< use this command to set HDCP transmitter type and wake it up (or stop ), 1 byte with following bits : Bit (0-1)= 0 - support only HDCP 2, 1 - support only HDCP 1, 2 - support both HDCP, Bit 2 - active (to activate port set to 1), to stop port set to 0 */
+ HDCP2_TX_SET_PUBLIC_KEY_PARAMS, /*!< use it to set public key for the HDCP2.x transmitter(HDCP2.x), Modulus n - 384 bytes, E - 3 bytes */
+ HDCP2_TX_SET_DEBUG_RANDOM_NUMBERS, /*!< use this command to enforce the random parameters (for debug only!), instead of the random data generated by the embedded RNG.Use this command after HDCP_TX_SET_PUBLIC_KEY_PARAMS command. Relevant to (HDCP2.x), data is : KM 16 bytes,RN 8 bytes,KS 16 bytes,RIV 8 bytes,RTX 8 bytes */
+ HDCP2_TX_RESPOND_KM, /*!< If km is stored, return all parameters, else there is no extra data(HDCP2.x), data is : Receiver ID (5 bytes),m (16 bytes),Km (16 bytes),Ekh(Km)(16 bytes) */
+ HDCP1_TX_SEND_KEYS, /*!< send keys needed for HDCP 1, data is : AKSV (5 bytes), ksv (7*40 = 280 bytes) */
+ HDCP1_TX_SEND_RANDOM_AN, /*!< set AN, use it for debug purpose, if not use, it will be random number, data is (8 bytes) */
+ HDCP_TX_STATUS_CHANGE, /*!< Will be called in port status change event by cadence HDCP IP, Status for the port:Bit 0 - AUTHENTICATED (1 - link is authenticated), Bit 1 - receiver is REPEATER (1 for repeater, 0 not),Bit 2 - 0 for HDCP1, 1 for HDCP2, */
+ HDCP2_TX_IS_KM_STORED, /*!< controller check if KM is stored by host(HDCP2.x), data is : Receiver ID (5 bytes) */
+ HDCP2_TX_STORE_KM, /*!< controller ask host to store KM, host may store it on non-volatile memory for faster authentication(HDCP2.x), data is : Receiver ID (5 bytes),m (16 bytes),Km(16 bytes),Ekh(Km),(16 bytes) */
+ HDCP_TX_IS_RECEIVER_ID_VALID, /*!< controller check if receivers ID are not in revocation list, input is->first byte for number of receivers, then list of receivers (5 bytes each) */
+ HDCP_TX_RESPOND_RECEIVER_ID_VALID, /*!< If receivers ID are valid return 1, otherwise return 0, same for HDCP1,HDCP2 */
+ HDCP_TX_TEST_KEYS, /*!< compare HDCP keys with facsimile key */
+ HDCP2_TX_SET_KM_KEY_PARAMS, /*!< This Command is used to load customer defined Key for km-key encryption into the HDCP2.x transmitter controller. */
+} HDCP_TRNAS_MAIL_BOX_MSG;
+ /** @} *///
+
+/* HDCP_TX_CONFIGURATION */
+
+/* bits 0-1 HDCP_TX_MODE */
+#define HDCP_TX_CONFIGURATION_MODE_OFFSET 0
+#define HDCP_TX_CONFIGURATION_MODE_LEN 2
+#define HDCP_TX_CONFIGURATION_RUN 2
+#define HDCP_TX_CONFIGURATION_RPTR_CONTENT_STREAM_MNGR_OFFSET 3
+#define HDCP_TX_CONFIGURATION_RPTR 4
+#define HDCP_TX_ENABLE_1_1_FEATURES 5
+#define HDCP_TX_SECOND_LINK 6
+#define HDCP_TX_HDMI_MODE 7
+
+#define HDCP_TX_CONFIGURATION_ENABLE_KM_KEY_MASK (1 << 4)
+
+/* HDCP_TX_STATUS_CHANGE bits */
+#define HDCP_STATUS_AUTHENTICATED 0
+#define HDCP_STATUS_REPEATER 1
+#define HDCP_STATUS_HDCP2 2
+#define HDCP_STATUS_STRAM_MANAGE_SUCCESS 4
+#define HDCP_STATUS_ERROR_TYPE 5
+#define HDCP_STATUS_1_1_FEATURES 9
+
+/**
+ *
+ * \brief different error types for HDCP_TX_STATUS_CHANGE
+ */
+typedef enum {
+ HDCP_TRAN_ERR_No_error,
+ HDCP_TRAN_ERR_HPD_is_down,
+ HDCP_TRAN_ERR_SRM_failure,
+ HDCP_TRAN_ERR_signature_verification,
+ HDCP_TRAN_ERR_h_tag_diff_h,
+ HDCP_TRAN_ERR_v_tag_diff_v,
+ HDCP_TRAN_ERR_locality_check,
+ HDCP_TRAN_ERR_Ddc,
+ HDCP_TRAN_ERR_REAUTH_REQ,
+ HDCP_TRAN_ERR_topology,
+ HDCP_TRAN_ERR_HDCP_RSVD1,
+ HDCP_TRAN_ERR_HDMI_capability,
+ HDCP_TRAN_ERR_RI,
+ HDCP_TRAN_ERR_watchDog_expired,
+} HDCP_TRNAS_ERR_TYPE;
+
+/* HDCP2_TX_SET_PUBLIC_KEY_PARAMS */
+#define DLP_MODULUS_N 384
+#define DLP_E 3
+typedef struct {
+ u8 N[DLP_MODULUS_N];
+ u8 E[DLP_E];
+} S_HDCP_TRANS_PUBLIC_KEY_PARAMS;
+
+/* HDCP2_TX_SET_KM_KEY_PARAMS */
+#define DLP_KM_KEY 16
+typedef struct {
+ u8 KM_KEY[DLP_KM_KEY];
+} S_HDCP_TRANS_KM_KEY_PARAMS;
+
+/* HDCP2_TX_SET_DEBUG_RANDOM_NUMBERS */
+#define DEBUG_RANDOM_NUMBERS_KM_LEN 16
+#define DEBUG_RANDOM_NUMBERS_RN_LEN 8
+#define DEBUG_RANDOM_NUMBERS_KS_LEN 16
+#define DEBUG_RANDOM_NUMBERS_RIV_LEN 8
+#define DEBUG_RANDOM_NUMBERS_RTX_LEN 8
+
+typedef struct {
+ u8 km[DEBUG_RANDOM_NUMBERS_KM_LEN];
+ u8 rn[DEBUG_RANDOM_NUMBERS_RN_LEN];
+ u8 ks[DEBUG_RANDOM_NUMBERS_KS_LEN];
+ u8 riv[DEBUG_RANDOM_NUMBERS_RIV_LEN];
+ u8 rtx[DEBUG_RANDOM_NUMBERS_RTX_LEN];
+} S_HDCP_TRANS_DEBUG_RANDOM_NUMBERS;
+
+#define HDCP_PAIRING_M_LEN 16
+#define HDCP_PAIRING_M_EKH 16
+#define HDCP_PAIRING_R_ID 5
+
+typedef struct {
+ u8 receiver_id[HDCP_PAIRING_R_ID];
+ u8 m[HDCP_PAIRING_M_LEN];
+ u8 km[DEBUG_RANDOM_NUMBERS_KM_LEN];
+ u8 ekh[HDCP_PAIRING_M_EKH];
+} S_HDCP_TRANS_PAIRING_DATA;
+
+typedef struct {
+ u8 Receiver_ID[HDCP_PAIRING_R_ID];
+} S_HDCP_TRANS_REVOCATION_LIST;
+
+/* HDCP1_TX_SEND_KEYS */
+#define AKSV_SIZE (5)
+#define HDCPT1_KSV_SIZE (7 * 40)
+
+typedef struct {
+ u8 AKSV[AKSV_SIZE];
+ u8 KSV[HDCPT1_KSV_SIZE];
+} S_HDCP_TX_MAIL_BOX_CMD_HDCP1_TX_SEND_KEYS;
+
+#define AN_SIZE (8)
+
+/* HDCP2_TX_SESSION_KEY */
+#define HDCP_SESSION_KEY_LEN 16
+
+#endif //HDCP_TRAN_H
diff --git a/drivers/mxc/hdp/hdmi.h b/drivers/mxc/hdp/hdmi.h
new file mode 100644
index 000000000000..de69699c5d14
--- /dev/null
+++ b/drivers/mxc/hdp/hdmi.h
@@ -0,0 +1,122 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2016-2017 Cadence Design Systems, Inc.
+ * All rights reserved worldwide.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 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.
+ *
+ * Copyright 2017 NXP
+ *
+ ******************************************************************************
+ *
+ * hdmi.h
+ *
+ ******************************************************************************
+ */
+
+#ifndef _HDMI__
+#define _HDMI__
+/* ONLY ENUMS AND #DEFINES IN THIS FILE *
+ * THIS FILE WILL BE USED IN HOST'S API */
+
+#define EDID_SLAVE_ADDRESS 0x50
+#define EDID_SEGMENT_SLAVE_ADDRESS 0x30
+#define SCDC_SLAVE_ADDRESS 0x54
+
+typedef enum {
+ HDMI_TX_READ,
+ HDMI_TX_WRITE,
+ HDMI_TX_UPDATE_READ,
+ HDMI_TX_EDID,
+ HDMI_TX_EVENTS,
+ HDMI_TX_HPD_STATUS,
+ HDMI_TX_DEBUG_ECHO = 0xAA,
+ HDMI_TX_TEST = 0xBB,
+ HDMI_TX_EDID_INTERNAL = 0xF0,
+} HDMI_TX_OPCODE;
+
+typedef enum {
+ HDMI_I2C_ACK,
+ HDMI_I2C_NACK,
+ HDMI_I2C_TO,
+ HDMI_I2C_ARB_LOST,
+ HDMI_I2C_RRTO,
+ HDMI_I2C_RRT,
+ /** when i2c hardware didn't respond after some time */
+ HDMI_I2C_HW_TO,
+ HDMI_I2C_ERR //unspecified error
+} HDMI_I2C_STATUS;
+
+typedef enum {
+ HDMI_RX_SET_EDID,
+ HDMI_RX_SCDC_SET,
+ HDMI_RX_SCDC_GET,
+ HDMI_RX_READ_EVENTS,
+ HDMI_RX_SET_HPD,
+
+ HDMI_RX_DEBUG_ECHO = 0xAA,
+ HDMI_RX_TEST = 0xBB,
+} HDMI_RX_OPCODE;
+
+typedef enum {
+ HDMI_SCDC_SINK_VER,
+ HDMI_SCDC_SOURCE_VER,
+} HDMI_SCDC_FIELD;
+
+typedef struct {
+ u8 sink_ver;
+ u8 manufacturer_oui_1;
+ u8 manufacturer_oui_2;
+ u8 manufacturer_oui_3;
+ u8 devId[8];
+ u8 hardware_major_rev;
+ u8 hardware_minor_rev;
+ u8 software_major_rev;
+ u8 software_minor_rev;
+ u8 manufacturerSpecific[34];
+} S_HDMI_SCDC_SET_MSG;
+
+typedef struct {
+ u8 source_ver;
+ u8 TMDS_Config;
+ u8 config_0;
+ u8 manufacturerSpecific[34];
+} S_HDMI_SCDC_GET_MSG;
+
+/* hpd events location */
+#define HDMI_RX_EVENT_5V_HIGH 0
+#define HDMI_RX_EVENT_5V_LOW 1
+#define HDMI_TX_EVENT_reserved 2
+#define HDMI_RX_EVENT_5V_VAL 3
+
+#endif
diff --git a/drivers/mxc/hdp/mailBox.h b/drivers/mxc/hdp/mailBox.h
new file mode 100644
index 000000000000..b8e069378de0
--- /dev/null
+++ b/drivers/mxc/hdp/mailBox.h
@@ -0,0 +1,116 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2016-2017 Cadence Design Systems, Inc.
+ * All rights reserved worldwide.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 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.
+ *
+ * Copyright 2017 NXP
+ *
+ ******************************************************************************
+ *
+ * mailBox.h
+ *
+ ******************************************************************************
+ */
+
+#ifndef MAIL_BOX_H
+#define MAIL_BOX_H
+
+#define MAIL_BOX_MAX_SIZE 600
+#define MAIL_BOX_MAX_TX_SIZE 160
+
+ /**
+ * \file mailBox.h
+ * \brief Implementation mail box communication channel between IP and external host
+ */
+
+#define MB_MODULE_ID_DP_TX 0x01
+#define MB_MODULE_ID_DP_RX 0x02
+#define MB_MODULE_ID_HDMI_TX 0x03
+#define MB_MODULE_ID_HDMI_RX 0x04
+#define MB_MODULE_ID_MHL_TX 0x05
+#define MB_MODULE_ID_MHL_RX 0x06
+#define MB_MODULE_ID_HDCP_TX 0x07
+#define MB_MODULE_ID_HDCP_RX 0x08
+#define MB_MODULE_ID_HDCP_GENERAL 0x09
+#define MB_MODULE_ID_GENERAL 0x0A
+
+typedef enum {
+ MB_TYPE_REGULAR,
+ MB_TYPE_SECURE,
+ MB_TYPE_COUNT,
+} MB_TYPE;
+
+typedef enum {
+ MB_SUCCESS,
+ MB_BUSY,
+ MB_NO_MEMORY
+} MB_RET;
+
+typedef enum {
+ MB_TO_HOST,
+ MB_TO_CONTROLLER,
+} MB_IDX;
+
+typedef enum {
+ MB_STATE_EMPTY,
+ MB_STATE_WAIT_MODULE_ID,
+ MB_STATE_WAIT_SIZE_MSB,
+ MB_STATE_WAIT_SIZE_LSB,
+ MB_STATE_READ_DATA,
+ MB_STATE_MSG_READY,
+} MB_RX_STATE;
+
+#define MB_OPCODE_ID 0
+#define MB_MODULE_ID 1
+#define MB_SIZE_MSB_ID 2
+#define MB_SIZE_LSB_ID 3
+#define MB_DATA_ID 4
+
+typedef struct {
+ MB_RX_STATE rxState;
+ u32 rx_data_idx;
+ u32 rx_final_msgSize;
+ u8 rxBuff[MAIL_BOX_MAX_SIZE];
+ u8 txBuff[MAIL_BOX_MAX_TX_SIZE];
+ u32 txTotal;
+ u32 txCur;
+} S_MAIL_BOX_PORT_DATA;
+
+typedef struct {
+ S_MAIL_BOX_PORT_DATA portData;
+ u8 portsTxBusy; //bit for each port (0-7)
+} S_MAIL_BOX_DATA;
+
+#endif //MAIL_BOX_H
diff --git a/drivers/mxc/hdp/mhl_hdtx_top.h b/drivers/mxc/hdp/mhl_hdtx_top.h
new file mode 100644
index 000000000000..209b939a88e1
--- /dev/null
+++ b/drivers/mxc/hdp/mhl_hdtx_top.h
@@ -0,0 +1,220 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2016-2017 Cadence Design Systems, Inc.
+ * All rights reserved worldwide.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 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.
+ *
+ * Copyright 2017 NXP
+ *
+ ******************************************************************************
+ *
+ * This file was auto-generated. Do not edit it manually.
+ *
+ ******************************************************************************
+ *
+ * mhl_hdtx_top.h
+ *
+ ******************************************************************************
+ */
+
+#ifndef MHL_HDTX_TOP_H_
+#define MHL_HDTX_TOP_H_
+
+/* register SCHEDULER_H_SIZE */
+#define SCHEDULER_H_SIZE 0
+#define F_H_BLANK_SIZE(x) (((x) & ((1 << 16) - 1)) << 0)
+#define F_H_BLANK_SIZE_RD(x) (((x) & (((1 << 16) - 1) << 0)) >> 0)
+#define F_H_ACTIVE_SIZE(x) (((x) & ((1 << 16) - 1)) << 16)
+#define F_H_ACTIVE_SIZE_RD(x) (((x) & (((1 << 16) - 1) << 16)) >> 16)
+
+/* register SCHEDULER_V_SIZE */
+#define SCHEDULER_V_SIZE 1
+#define F_V_BLANK_SIZE(x) (((x) & ((1 << 16) - 1)) << 0)
+#define F_V_BLANK_SIZE_RD(x) (((x) & (((1 << 16) - 1) << 0)) >> 0)
+#define F_V_ACTIVE_SIZE(x) (((x) & ((1 << 16) - 1)) << 16)
+#define F_V_ACTIVE_SIZE_RD(x) (((x) & (((1 << 16) - 1) << 16)) >> 16)
+
+/* register SCHEDULER_KEEP_OUT */
+#define SCHEDULER_KEEP_OUT 2
+#define F_HKEEP_OUT(x) (((x) & ((1 << 9) - 1)) << 0)
+#define F_HKEEP_OUT_RD(x) (((x) & (((1 << 9) - 1) << 0)) >> 0)
+#define F_VKEEP_OUT_START(x) (((x) & ((1 << 11) - 1)) << 9)
+#define F_VKEEP_OUT_START_RD(x) (((x) & (((1 << 11) - 1) << 9)) >> 9)
+#define F_VKEEP_OUT_ZONE(x) (((x) & ((1 << 8) - 1)) << 20)
+#define F_VKEEP_OUT_ZONE_RD(x) (((x) & (((1 << 8) - 1) << 20)) >> 20)
+
+/* register HDTX_SIGNAL_FRONT_WIDTH */
+#define HDTX_SIGNAL_FRONT_WIDTH 3
+#define F_HFRONT(x) (((x) & ((1 << 16) - 1)) << 0)
+#define F_HFRONT_RD(x) (((x) & (((1 << 16) - 1) << 0)) >> 0)
+#define F_VFRONT(x) (((x) & ((1 << 16) - 1)) << 16)
+#define F_VFRONT_RD(x) (((x) & (((1 << 16) - 1) << 16)) >> 16)
+
+/* register HDTX_SIGNAL_SYNC_WIDTH */
+#define HDTX_SIGNAL_SYNC_WIDTH 4
+#define F_HSYNC(x) (((x) & ((1 << 16) - 1)) << 0)
+#define F_HSYNC_RD(x) (((x) & (((1 << 16) - 1) << 0)) >> 0)
+#define F_VSYNC(x) (((x) & ((1 << 16) - 1)) << 16)
+#define F_VSYNC_RD(x) (((x) & (((1 << 16) - 1) << 16)) >> 16)
+
+/* register HDTX_SIGNAL_BACK_WIDTH */
+#define HDTX_SIGNAL_BACK_WIDTH 5
+#define F_HBACK(x) (((x) & ((1 << 16) - 1)) << 0)
+#define F_HBACK_RD(x) (((x) & (((1 << 16) - 1) << 0)) >> 0)
+#define F_VBACK(x) (((x) & ((1 << 16) - 1)) << 16)
+#define F_VBACK_RD(x) (((x) & (((1 << 16) - 1) << 16)) >> 16)
+
+/* register HDTX_CONTROLLER */
+#define HDTX_CONTROLLER 6
+#define F_HDMI_MODE(x) (((x) & ((1 << 2) - 1)) << 0)
+#define F_HDMI_MODE_RD(x) (((x) & (((1 << 2) - 1) << 0)) >> 0)
+#define F_VIF_DATA_WIDTH(x) (((x) & ((1 << 2) - 1)) << 2)
+#define F_VIF_DATA_WIDTH_RD(x) (((x) & (((1 << 2) - 1) << 2)) >> 2)
+#define F_AUTO_MODE(x) (((x) & ((1 << 1) - 1)) << 4)
+#define F_AUTO_MODE_RD(x) (((x) & (((1 << 1) - 1) << 4)) >> 4)
+#define F_IL_PROG(x) (((x) & ((1 << 2) - 1)) << 5)
+#define F_IL_PROG_RD(x) (((x) & (((1 << 2) - 1) << 5)) >> 5)
+#define F_PIC_3D(x) (((x) & ((1 << 4) - 1)) << 7)
+#define F_PIC_3D_RD(x) (((x) & (((1 << 4) - 1) << 7)) >> 7)
+#define F_BCH_EN(x) (((x) & ((1 << 1) - 1)) << 11)
+#define F_BCH_EN_RD(x) (((x) & (((1 << 1) - 1) << 11)) >> 11)
+#define F_GCP_EN(x) (((x) & ((1 << 1) - 1)) << 12)
+#define F_GCP_EN_RD(x) (((x) & (((1 << 1) - 1) << 12)) >> 12)
+#define F_SET_AVMUTE(x) (((x) & ((1 << 1) - 1)) << 13)
+#define F_SET_AVMUTE_RD(x) (((x) & (((1 << 1) - 1) << 13)) >> 13)
+#define F_CLEAR_AVMUTE(x) (((x) & ((1 << 1) - 1)) << 14)
+#define F_CLEAR_AVMUTE_RD(x) (((x) & (((1 << 1) - 1) << 14)) >> 14)
+#define F_DATA_EN(x) (((x) & ((1 << 1) - 1)) << 15)
+#define F_DATA_EN_RD(x) (((x) & (((1 << 1) - 1) << 15)) >> 15)
+#define F_HDMI_ENCODING(x) (((x) & ((1 << 2) - 1)) << 16)
+#define F_HDMI_ENCODING_RD(x) (((x) & (((1 << 2) - 1) << 16)) >> 16)
+#define F_HDMI2_PREAMBLE_EN(x) (((x) & ((1 << 1) - 1)) << 18)
+#define F_HDMI2_PREAMBLE_EN_RD(x) (((x) & (((1 << 1) - 1) << 18)) >> 18)
+#define F_HDMI2_CTRL_IL_MODE(x) (((x) & ((1 << 1) - 1)) << 19)
+#define F_HDMI2_CTRL_IL_MODE_RD(x) (((x) & (((1 << 1) - 1) << 19)) >> 19)
+
+/* register HDTX_HDCP */
+#define HDTX_HDCP 7
+#define F_HDTX_HDCP_SELECT(x) (((x) & ((1 << 2) - 1)) << 0)
+#define F_HDTX_HDCP_SELECT_RD(x) (((x) & (((1 << 2) - 1) << 0)) >> 0)
+#define F_ENC_BIT(x) (((x) & ((1 << 1) - 1)) << 2)
+#define F_ENC_BIT_RD(x) (((x) & (((1 << 1) - 1) << 2)) >> 2)
+#define F_HDCP_ENABLE_1P1_FEATURES(x) (((x) & ((1 << 1) - 1)) << 3)
+#define F_HDCP_ENABLE_1P1_FEATURES_RD(x) (((x) & (((1 << 1) - 1) << 3)) >> 3)
+#define F_HDCP_DELAY_FIFO_SW_RST(x) (((x) & ((1 << 1) - 1)) << 4)
+#define F_HDCP_DELAY_FIFO_SW_RST_RD(x) (((x) & (((1 << 1) - 1) << 4)) >> 4)
+#define F_HDCP_DELAY_FIFO_SW_START(x) (((x) & ((1 << 1) - 1)) << 5)
+#define F_HDCP_DELAY_FIFO_SW_START_RD(x) (((x) & (((1 << 1) - 1) << 5)) >> 5)
+#define F_HDCP_DOUBLE_FIFO_SW_RST(x) (((x) & ((1 << 1) - 1)) << 6)
+#define F_HDCP_DOUBLE_FIFO_SW_RST_RD(x) (((x) & (((1 << 1) - 1) << 6)) >> 6)
+#define F_HDCP_SINGLE_FIFO_SW_RST(x) (((x) & ((1 << 1) - 1)) << 7)
+#define F_HDCP_SINGLE_FIFO_SW_RST_RD(x) (((x) & (((1 << 1) - 1) << 7)) >> 7)
+#define F_HDCP_DELAY_FIFO_AFULL_THR(x) (((x) & ((1 << 4) - 1)) << 8)
+#define F_HDCP_DELAY_FIFO_AFULL_THR_RD(x) (((x) & (((1 << 4) - 1) << 8)) >> 8)
+#define F_HDCP_CTRL_SW_RST(x) (((x) & ((1 << 1) - 1)) << 12)
+#define F_HDCP_CTRL_SW_RST_RD(x) (((x) & (((1 << 1) - 1) << 12)) >> 12)
+#define F_HDCP_CTRL_IL_MODE(x) (((x) & ((1 << 1) - 1)) << 13)
+#define F_HDCP_CTRL_IL_MODE_RD(x) (((x) & (((1 << 1) - 1) << 13)) >> 13)
+
+/* register HDTX_HPD */
+#define HDTX_HPD 8
+#define F_HPD_VALID_WIDTH(x) (((x) & ((1 << 12) - 1)) << 0)
+#define F_HPD_VALID_WIDTH_RD(x) (((x) & (((1 << 12) - 1) << 0)) >> 0)
+#define F_HPD_GLITCH_WIDTH(x) (((x) & ((1 << 8) - 1)) << 12)
+#define F_HPD_GLITCH_WIDTH_RD(x) (((x) & (((1 << 8) - 1) << 12)) >> 12)
+
+/* register HDTX_CLOCK_REG_0 */
+#define HDTX_CLOCK_REG_0 9
+#define F_DATA_REGISTER_VAL_0(x) (((x) & ((1 << 20) - 1)) << 0)
+#define F_DATA_REGISTER_VAL_0_RD(x) (((x) & (((1 << 20) - 1) << 0)) >> 0)
+
+/* register HDTX_CLOCK_REG_1 */
+#define HDTX_CLOCK_REG_1 10
+#define F_DATA_REGISTER_VAL_1(x) (((x) & ((1 << 20) - 1)) << 0)
+#define F_DATA_REGISTER_VAL_1_RD(x) (((x) & (((1 << 20) - 1) << 0)) >> 0)
+
+/* register HPD_PLUG_IN */
+#define HPD_PLUG_IN 11
+#define F_FILTER_HPD(x) (((x) & ((1 << 1) - 1)) << 0)
+#define F_FILTER_HPD_RD(x) (((x) & (((1 << 1) - 1) << 0)) >> 0)
+
+/* register HDCP_IN */
+#define HDCP_IN 12
+#define F_HDCP_ESS_STATE(x) (((x) & ((1 << 4) - 1)) << 0)
+#define F_HDCP_ESS_STATE_RD(x) (((x) & (((1 << 4) - 1) << 0)) >> 0)
+#define F_HDCP_DOUBLE_FIFO_WFULL(x) (((x) & ((1 << 1) - 1)) << 4)
+#define F_HDCP_DOUBLE_FIFO_WFULL_RD(x) (((x) & (((1 << 1) - 1) << 4)) >> 4)
+#define F_HDCP_DOUBLE_FIFO_REMPTY(x) (((x) & ((1 << 1) - 1)) << 5)
+#define F_HDCP_DOUBLE_FIFO_REMPTY_RD(x) (((x) & (((1 << 1) - 1) << 5)) >> 5)
+#define F_HDCP_DOUBLE_FIFO_OVERRUN(x) (((x) & ((1 << 1) - 1)) << 6)
+#define F_HDCP_DOUBLE_FIFO_OVERRUN_RD(x) (((x) & (((1 << 1) - 1) << 6)) >> 6)
+#define F_HDCP_DOUBLE_FIFO_UNDERRUN(x) (((x) & ((1 << 1) - 1)) << 7)
+#define F_HDCP_DOUBLE_FIFO_UNDERRUN_RD(x) (((x) & (((1 << 1) - 1) << 7)) >> 7)
+#define F_HDCP_DELAY_FIFO_EMPTY(x) (((x) & ((1 << 1) - 1)) << 8)
+#define F_HDCP_DELAY_FIFO_EMPTY_RD(x) (((x) & (((1 << 1) - 1) << 8)) >> 8)
+#define F_HDCP_DELAY_FIFO_FULL(x) (((x) & ((1 << 1) - 1)) << 9)
+#define F_HDCP_DELAY_FIFO_FULL_RD(x) (((x) & (((1 << 1) - 1) << 9)) >> 9)
+#define F_HDCP_SINGLE_FIFO_WFULL(x) (((x) & ((1 << 2) - 1)) << 10)
+#define F_HDCP_SINGLE_FIFO_WFULL_RD(x) (((x) & (((1 << 2) - 1) << 10)) >> 10)
+#define F_HDCP_SINGLE_FIFO_REMPTY(x) (((x) & ((1 << 2) - 1)) << 12)
+#define F_HDCP_SINGLE_FIFO_REMPTY_RD(x) (((x) & (((1 << 2) - 1) << 12)) >> 12)
+#define F_HDCP_SINGLE_FIFO_OVERRUN(x) (((x) & ((1 << 2) - 1)) << 14)
+#define F_HDCP_SINGLE_FIFO_OVERRUN_RD(x) (((x) & (((1 << 2) - 1) << 14)) >> 14)
+#define F_HDCP_SINGLE_FIFO_UNDERRUN(x) (((x) & ((1 << 2) - 1)) << 16)
+#define F_HDCP_SINGLE_FIFO_UNDERRUN_RD(x) (((x) & (((1 << 2) - 1) << 16)) >> 16)
+
+/* register GCP_FORCE_COLOR_DEPTH_CODING */
+#define GCP_FORCE_COLOR_DEPTH_CODING 13
+#define F_COLOR_DEPTH_VAL(x) (((x) & ((1 << 4) - 1)) << 0)
+#define F_COLOR_DEPTH_VAL_RD(x) (((x) & (((1 << 4) - 1) << 0)) >> 0)
+#define F_COLOR_DEPTH_FORCE(x) (((x) & ((1 << 1) - 1)) << 4)
+#define F_COLOR_DEPTH_FORCE_RD(x) (((x) & (((1 << 1) - 1) << 4)) >> 4)
+#define F_DEFAULT_PHASE_VAL(x) (((x) & ((1 << 1) - 1)) << 5)
+#define F_DEFAULT_PHASE_VAL_RD(x) (((x) & (((1 << 1) - 1) << 5)) >> 5)
+
+/* register SSCP_POSITIONING */
+#define SSCP_POSITIONING 14
+#define F_SSCP_ROW_VAL(x) (((x) & ((1 << 16) - 1)) << 0)
+#define F_SSCP_ROW_VAL_RD(x) (((x) & (((1 << 16) - 1) << 0)) >> 0)
+#define F_SSCP_COL_VAL(x) (((x) & ((1 << 16) - 1)) << 16)
+#define F_SSCP_COL_VAL_RD(x) (((x) & (((1 << 16) - 1) << 16)) >> 16)
+
+/* register HDCP_WIN_OF_OPP_POSITION */
+#define HDCP_WIN_OF_OPP_POSITION 15
+#define F_HDCP_WIN_OF_OPP_START(x) (((x) & ((1 << 10) - 1)) << 0)
+#define F_HDCP_WIN_OF_OPP_START_RD(x) (((x) & (((1 << 10) - 1) << 0)) >> 0)
+#define F_HDCP_WIN_OF_OPP_SIZE(x) (((x) & ((1 << 6) - 1)) << 10)
+#define F_HDCP_WIN_OF_OPP_SIZE_RD(x) (((x) & (((1 << 6) - 1) << 10)) >> 10)
+
+#endif //MHL_HDTX_TOP
diff --git a/drivers/mxc/hdp/opcodes.h b/drivers/mxc/hdp/opcodes.h
new file mode 100644
index 000000000000..3fa3279d27f9
--- /dev/null
+++ b/drivers/mxc/hdp/opcodes.h
@@ -0,0 +1,117 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2016-2018 Cadence Design Systems, Inc.
+ * All rights reserved worldwide.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 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.
+ *
+ * Copyright 2017-2018 NXP
+ *
+ ******************************************************************************
+ *
+ * This file was auto-generated. Do not edit it manually.
+ *
+ ******************************************************************************
+ *
+ * opcodes.h
+ *
+ ******************************************************************************
+ */
+
+#ifndef OPCODES_H_
+#define OPCODES_H_
+
+#define DP_TX_MAIL_HANDLER_H
+#define DP_TX_MAIL_HANDLER_REQUEST_BUFFER_LEN 1024
+#define DPTX_SET_POWER_MNG 0x00
+#define DPTX_SET_HOST_CAPABILITIES 0x01
+#define DPTX_GET_EDID 0x02
+#define DPTX_READ_DPCD 0x03
+#define DPTX_WRITE_DPCD 0x04
+#define DPTX_ENABLE_EVENT 0x05
+#define DPTX_WRITE_REGISTER 0x06
+#define DPTX_READ_REGISTER 0x07
+#define DPTX_WRITE_FIELD 0x08
+#define DPTX_TRAINING_CONTROL 0x09
+#define DPTX_READ_EVENT 0x0A
+#define DPTX_READ_LINK_STAT 0x0B
+#define DPTX_SET_VIDEO 0x0C
+#define DPTX_SET_AUDIO 0x0D
+#define DPTX_GET_LAST_AUX_STAUS 0x0E
+#define DPTX_SET_LINK_BREAK_POINT 0x0F
+#define DPTX_FORCE_LANES 0x10
+#define DPTX_HPD_STATE 0x11
+#define DPTX_EDP_RATE_TRAINING 0x12
+#define DPTX_SET_PHY_COEFFICIENTS 0x13
+#define DPTX_I2C_READ 0x15
+#define DPTX_I2C_WRITE 0x16
+#define DPTX_GET_LAST_I2C_STATUS 0x17
+#define DPTX_DBG_SET 0xF0
+#define DPTX_EDID_RESP 0x02
+#define DPTX_DPCD_READ_RESP 0x03
+#define DPTX_DPCD_WRITE_RESP 0x04
+#define DPTX_READ_EVENT_RESP 0x0A
+#define DPTX_READ_REGISTER_RESP 0x07
+#define DPTX_MESSAGE 0x10
+#define DPTX_I2C_READ_RESP 0x15
+#define DPTX_I2C_WRITE_RESP 0x16
+#define DP_TX_OPCODE_LOOPBACK_TEST 0xFE
+#define DP_TX_OPCODE_BIT_TEST 0xFF
+#define DP_TX_EVENT_ENABLE_HPD_BIT 0x00
+#define DP_TX_EVENT_ENABLE_TRAINING_BIT 0x01
+#define DP_TX_EVENT_CODE_HPD_HIGH 0x01
+#define DP_TX_EVENT_CODE_HPD_LOW 0x02
+#define DP_TX_EVENT_CODE_HPD_PULSE 0x04
+#define DP_TX_EVENT_CODE_HPD_STATE_HIGH 0x08
+#define DP_TX_EVENT_CODE_HPD_STATE_LOW 0x00
+#define DP_TX_EVENT_CODE_TRAINING_FULL_STARTED 0x01
+#define DP_TX_EVENT_CODE_TRAINING_FAST_STARTED 0x02
+#define DP_TX_EVENT_CODE_TRAINING_FINISHED_CR 0x04
+#define DP_TX_EVENT_CODE_TRAINING_FINISHED_EQ 0x08
+#define DP_TX_EVENT_CODE_TRAINING_FINISHED_FAST 0x10
+#define DP_TX_EVENT_CODE_TRAINING_FAILED_CR 0x20
+#define DP_TX_EVENT_CODE_TRAINING_FAILED_EQ 0x40
+#define DP_TX_EVENT_CODE_TRAINING_FAILED_FAST 0x80
+#define MB_MODULE_ID_DP_TX 0x01
+#define MB_MODULE_ID_DP_RX 0x02
+#define MB_MODULE_ID_HDMI_TX 0x03
+#define MB_MODULE_ID_HDMI_RX 0x04
+#define MB_MODULE_ID_MHL_TX 0x05
+#define MB_MODULE_ID_MHL_RX 0x06
+#define MB_MODULE_ID_HDCP_TX 0x07
+#define MB_MODULE_ID_HDCP_RX 0x08
+#define MB_MODULE_ID_HDCP_GENERAL 0x09
+#define MB_MODULE_ID_GENERAL 0x0A
+#define MB_MODULE_ID 1
+
+#endif
diff --git a/drivers/mxc/hdp/sink_aif_encoder.h b/drivers/mxc/hdp/sink_aif_encoder.h
new file mode 100644
index 000000000000..c75a1033ebd3
--- /dev/null
+++ b/drivers/mxc/hdp/sink_aif_encoder.h
@@ -0,0 +1,367 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2016-2017 Cadence Design Systems, Inc.
+ * All rights reserved worldwide.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 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.
+ *
+ * Copyright 2018 NXP
+ *
+ ******************************************************************************
+ *
+ * This file was auto-generated. Do not edit it manually.
+ *
+ ******************************************************************************
+ *
+ * sink_aif_encoder.h
+ *
+ ******************************************************************************
+ */
+
+#ifndef SINK_AIF_ENCODER_H_
+#define SINK_AIF_ENCODER_H_
+
+/* register AUDIO_SINK_CNTL */
+#define AUDIO_SINK_CNTL 0
+#define F_SINK_SW_RST(x) (((x) & ((1 << 1) - 1)) << 0)
+#define F_SINK_SW_RST_RD(x) (((x) & (((1 << 1) - 1) << 0)) >> 0)
+#define F_I2S_ENC_START(x) (((x) & ((1 << 1) - 1)) << 1)
+#define F_I2S_ENC_START_RD(x) (((x) & (((1 << 1) - 1) << 1)) >> 1)
+
+/* register AUDIO_SINK_STTS */
+#define AUDIO_SINK_STTS 1
+#define F_CH_INDX_ERR(x) (((x) & ((1 << 1) - 1)) << 0)
+#define F_CH_INDX_ERR_RD(x) (((x) & (((1 << 1) - 1) << 0)) >> 0)
+
+/* register AUDIO_SINK_CNFG */
+#define AUDIO_SINK_CNFG 2
+#define F_ENC_LOW_INDEX_MSB(x) (((x) & ((1 << 1) - 1)) << 0)
+#define F_ENC_LOW_INDEX_MSB_RD(x) (((x) & (((1 << 1) - 1) << 0)) >> 0)
+#define F_SINK_AUDIO_CH_NUM(x) (((x) & ((1 << 5) - 1)) << 1)
+#define F_SINK_AUDIO_CH_NUM_RD(x) (((x) & (((1 << 5) - 1) << 1)) >> 1)
+#define F_ENC_SAMPLE_JUST(x) (((x) & ((1 << 2) - 1)) << 6)
+#define F_ENC_SAMPLE_JUST_RD(x) (((x) & (((1 << 2) - 1) << 6)) >> 6)
+#define F_ENC_SMPL_WIDTH(x) (((x) & ((1 << 2) - 1)) << 8)
+#define F_ENC_SMPL_WIDTH_RD(x) (((x) & (((1 << 2) - 1) << 8)) >> 8)
+#define F_I2S_ENC_WL_SIZE(x) (((x) & ((1 << 2) - 1)) << 10)
+#define F_I2S_ENC_WL_SIZE_RD(x) (((x) & (((1 << 2) - 1) << 10)) >> 10)
+#define F_CNTL_SMPL_ONLY_EN(x) (((x) & ((1 << 1) - 1)) << 12)
+#define F_CNTL_SMPL_ONLY_EN_RD(x) (((x) & (((1 << 1) - 1) << 12)) >> 12)
+#define F_SINK_AIF_TYPE_SMPL(x) (((x) & ((1 << 4) - 1)) << 13)
+#define F_SINK_AIF_TYPE_SMPL_RD(x) (((x) & (((1 << 4) - 1) << 13)) >> 13)
+#define F_CNTL_TYPE_OVRD(x) (((x) & ((1 << 4) - 1)) << 17)
+#define F_CNTL_TYPE_OVRD_RD(x) (((x) & (((1 << 4) - 1) << 17)) >> 17)
+#define F_CNTL_TYPE_OVRD_EN(x) (((x) & ((1 << 1) - 1)) << 21)
+#define F_CNTL_TYPE_OVRD_EN_RD(x) (((x) & (((1 << 1) - 1) << 21)) >> 21)
+#define F_I2S_ENC_PORT_EN(x) (((x) & ((1 << 4) - 1)) << 22)
+#define F_I2S_ENC_PORT_EN_RD(x) (((x) & (((1 << 4) - 1) << 22)) >> 22)
+#define F_WS_POLARITY(x) (((x) & ((1 << 1) - 1)) << 26)
+#define F_WS_POLARITY_RD(x) (((x) & (((1 << 1) - 1) << 26)) >> 26)
+
+/* register FIFO_CNTL_ADDR */
+#define FIFO_CNTL_ADDR 3
+#define F_CFG_FIFO_SW_RST(x) (((x) & ((1 << 1) - 1)) << 0)
+#define F_CFG_FIFO_SW_RST_RD(x) (((x) & (((1 << 1) - 1) << 0)) >> 0)
+#define F_CFG_INDEX_SYNC_EN(x) (((x) & ((1 << 1) - 1)) << 1)
+#define F_CFG_INDEX_SYNC_EN_RD(x) (((x) & (((1 << 1) - 1) << 1)) >> 1)
+#define F_CFG_FIFO_DIR(x) (((x) & ((1 << 1) - 1)) << 2)
+#define F_CFG_FIFO_DIR_RD(x) (((x) & (((1 << 1) - 1) << 2)) >> 2)
+#define F_CFG_DIS_PORT3(x) (((x) & ((1 << 1) - 1)) << 3)
+#define F_CFG_DIS_PORT3_RD(x) (((x) & (((1 << 1) - 1) << 3)) >> 3)
+
+/* register FIFO_STTS_ADDR */
+#define FIFO_STTS_ADDR 4
+#define F_ST_WFULL_REG(x) (((x) & ((1 << 1) - 1)) << 0)
+#define F_ST_WFULL_REG_RD(x) (((x) & (((1 << 1) - 1) << 0)) >> 0)
+#define F_ST_REMPTY_REG(x) (((x) & ((1 << 1) - 1)) << 1)
+#define F_ST_REMPTY_REG_RD(x) (((x) & (((1 << 1) - 1) << 1)) >> 1)
+#define F_ST_OVERRUN_REG(x) (((x) & ((1 << 1) - 1)) << 2)
+#define F_ST_OVERRUN_REG_RD(x) (((x) & (((1 << 1) - 1) << 2)) >> 2)
+#define F_ST_UNDERRUN_REG(x) (((x) & ((1 << 1) - 1)) << 3)
+#define F_ST_UNDERRUN_REG_RD(x) (((x) & (((1 << 1) - 1) << 3)) >> 3)
+
+/* register SINK_COM_CH_STTS_BITS */
+#define SINK_COM_CH_STTS_BITS 5
+#define F_BYTE0(x) (((x) & ((1 << 8) - 1)) << 0)
+#define F_BYTE0_RD(x) (((x) & (((1 << 8) - 1) << 0)) >> 0)
+#define F_CATEGORY_CODE(x) (((x) & ((1 << 8) - 1)) << 8)
+#define F_CATEGORY_CODE_RD(x) (((x) & (((1 << 8) - 1) << 8)) >> 8)
+#define F_SAMPLING_FREQ(x) (((x) & ((1 << 4) - 1)) << 16)
+#define F_SAMPLING_FREQ_RD(x) (((x) & (((1 << 4) - 1) << 16)) >> 16)
+#define F_CLOCK_ACCURACY(x) (((x) & ((1 << 4) - 1)) << 20)
+#define F_CLOCK_ACCURACY_RD(x) (((x) & (((1 << 4) - 1) << 20)) >> 20)
+#define F_ORIGINAL_SAMP_FREQ(x) (((x) & ((1 << 4) - 1)) << 24)
+#define F_ORIGINAL_SAMP_FREQ_RD(x) (((x) & (((1 << 4) - 1) << 24)) >> 24)
+
+/* register SINK_STTS_BIT_CH01 */
+#define SINK_STTS_BIT_CH01 6
+#define F_SOURCE_NUM_CH0(x) (((x) & ((1 << 4) - 1)) << 0)
+#define F_SOURCE_NUM_CH0_RD(x) (((x) & (((1 << 4) - 1) << 0)) >> 0)
+#define F_CHANNEL_NUM_CH0(x) (((x) & ((1 << 4) - 1)) << 4)
+#define F_CHANNEL_NUM_CH0_RD(x) (((x) & (((1 << 4) - 1) << 4)) >> 4)
+#define F_WORD_LENGTH_CH0(x) (((x) & ((1 << 4) - 1)) << 8)
+#define F_WORD_LENGTH_CH0_RD(x) (((x) & (((1 << 4) - 1) << 8)) >> 8)
+#define F_SOURCE_NUM_CH1(x) (((x) & ((1 << 4) - 1)) << 12)
+#define F_SOURCE_NUM_CH1_RD(x) (((x) & (((1 << 4) - 1) << 12)) >> 12)
+#define F_CHANNEL_NUM_CH1(x) (((x) & ((1 << 4) - 1)) << 16)
+#define F_CHANNEL_NUM_CH1_RD(x) (((x) & (((1 << 4) - 1) << 16)) >> 16)
+#define F_WORD_LENGTH_CH1(x) (((x) & ((1 << 4) - 1)) << 20)
+#define F_WORD_LENGTH_CH1_RD(x) (((x) & (((1 << 4) - 1) << 20)) >> 20)
+
+/* register SINK_STTS_BIT_CH23 */
+#define SINK_STTS_BIT_CH23 7
+#define F_SOURCE_NUM_CH2(x) (((x) & ((1 << 4) - 1)) << 0)
+#define F_SOURCE_NUM_CH2_RD(x) (((x) & (((1 << 4) - 1) << 0)) >> 0)
+#define F_CHANNEL_NUM_CH2(x) (((x) & ((1 << 4) - 1)) << 4)
+#define F_CHANNEL_NUM_CH2_RD(x) (((x) & (((1 << 4) - 1) << 4)) >> 4)
+#define F_WORD_LENGTH_CH2(x) (((x) & ((1 << 4) - 1)) << 8)
+#define F_WORD_LENGTH_CH2_RD(x) (((x) & (((1 << 4) - 1) << 8)) >> 8)
+#define F_SOURCE_NUM_CH3(x) (((x) & ((1 << 4) - 1)) << 12)
+#define F_SOURCE_NUM_CH3_RD(x) (((x) & (((1 << 4) - 1) << 12)) >> 12)
+#define F_CHANNEL_NUM_CH3(x) (((x) & ((1 << 4) - 1)) << 16)
+#define F_CHANNEL_NUM_CH3_RD(x) (((x) & (((1 << 4) - 1) << 16)) >> 16)
+#define F_WORD_LENGTH_CH3(x) (((x) & ((1 << 4) - 1)) << 20)
+#define F_WORD_LENGTH_CH3_RD(x) (((x) & (((1 << 4) - 1) << 20)) >> 20)
+
+/* register SINK_STTS_BIT_CH45 */
+#define SINK_STTS_BIT_CH45 8
+#define F_SOURCE_NUM_CH4(x) (((x) & ((1 << 4) - 1)) << 0)
+#define F_SOURCE_NUM_CH4_RD(x) (((x) & (((1 << 4) - 1) << 0)) >> 0)
+#define F_CHANNEL_NUM_CH4(x) (((x) & ((1 << 4) - 1)) << 4)
+#define F_CHANNEL_NUM_CH4_RD(x) (((x) & (((1 << 4) - 1) << 4)) >> 4)
+#define F_WORD_LENGTH_CH4(x) (((x) & ((1 << 4) - 1)) << 8)
+#define F_WORD_LENGTH_CH4_RD(x) (((x) & (((1 << 4) - 1) << 8)) >> 8)
+#define F_SOURCE_NUM_CH5(x) (((x) & ((1 << 4) - 1)) << 12)
+#define F_SOURCE_NUM_CH5_RD(x) (((x) & (((1 << 4) - 1) << 12)) >> 12)
+#define F_CHANNEL_NUM_CH5(x) (((x) & ((1 << 4) - 1)) << 16)
+#define F_CHANNEL_NUM_CH5_RD(x) (((x) & (((1 << 4) - 1) << 16)) >> 16)
+#define F_WORD_LENGTH_CH5(x) (((x) & ((1 << 4) - 1)) << 20)
+#define F_WORD_LENGTH_CH5_RD(x) (((x) & (((1 << 4) - 1) << 20)) >> 20)
+
+/* register SINK_STTS_BIT_CH67 */
+#define SINK_STTS_BIT_CH67 9
+#define F_SOURCE_NUM_CH6(x) (((x) & ((1 << 4) - 1)) << 0)
+#define F_SOURCE_NUM_CH6_RD(x) (((x) & (((1 << 4) - 1) << 0)) >> 0)
+#define F_CHANNEL_NUM_CH6(x) (((x) & ((1 << 4) - 1)) << 4)
+#define F_CHANNEL_NUM_CH6_RD(x) (((x) & (((1 << 4) - 1) << 4)) >> 4)
+#define F_WORD_LENGTH_CH6(x) (((x) & ((1 << 4) - 1)) << 8)
+#define F_WORD_LENGTH_CH6_RD(x) (((x) & (((1 << 4) - 1) << 8)) >> 8)
+#define F_SOURCE_NUM_CH7(x) (((x) & ((1 << 4) - 1)) << 12)
+#define F_SOURCE_NUM_CH7_RD(x) (((x) & (((1 << 4) - 1) << 12)) >> 12)
+#define F_CHANNEL_NUM_CH7(x) (((x) & ((1 << 4) - 1)) << 16)
+#define F_CHANNEL_NUM_CH7_RD(x) (((x) & (((1 << 4) - 1) << 16)) >> 16)
+#define F_WORD_LENGTH_CH7(x) (((x) & ((1 << 4) - 1)) << 20)
+#define F_WORD_LENGTH_CH7_RD(x) (((x) & (((1 << 4) - 1) << 20)) >> 20)
+
+/* register SINK_STTS_BIT_CH89 */
+#define SINK_STTS_BIT_CH89 10
+#define F_SOURCE_NUM_CH8(x) (((x) & ((1 << 4) - 1)) << 0)
+#define F_SOURCE_NUM_CH8_RD(x) (((x) & (((1 << 4) - 1) << 0)) >> 0)
+#define F_CHANNEL_NUM_CH8(x) (((x) & ((1 << 4) - 1)) << 4)
+#define F_CHANNEL_NUM_CH8_RD(x) (((x) & (((1 << 4) - 1) << 4)) >> 4)
+#define F_WORD_LENGTH_CH8(x) (((x) & ((1 << 4) - 1)) << 8)
+#define F_WORD_LENGTH_CH8_RD(x) (((x) & (((1 << 4) - 1) << 8)) >> 8)
+#define F_SOURCE_NUM_CH9(x) (((x) & ((1 << 4) - 1)) << 12)
+#define F_SOURCE_NUM_CH9_RD(x) (((x) & (((1 << 4) - 1) << 12)) >> 12)
+#define F_CHANNEL_NUM_CH9(x) (((x) & ((1 << 4) - 1)) << 16)
+#define F_CHANNEL_NUM_CH9_RD(x) (((x) & (((1 << 4) - 1) << 16)) >> 16)
+#define F_WORD_LENGTH_CH9(x) (((x) & ((1 << 4) - 1)) << 20)
+#define F_WORD_LENGTH_CH9_RD(x) (((x) & (((1 << 4) - 1) << 20)) >> 20)
+
+/* register SINK_STTS_BIT_CH1011 */
+#define SINK_STTS_BIT_CH1011 11
+#define F_SOURCE_NUM_CH10(x) (((x) & ((1 << 4) - 1)) << 0)
+#define F_SOURCE_NUM_CH10_RD(x) (((x) & (((1 << 4) - 1) << 0)) >> 0)
+#define F_CHANNEL_NUM_CH10(x) (((x) & ((1 << 4) - 1)) << 4)
+#define F_CHANNEL_NUM_CH10_RD(x) (((x) & (((1 << 4) - 1) << 4)) >> 4)
+#define F_WORD_LENGTH_CH10(x) (((x) & ((1 << 4) - 1)) << 8)
+#define F_WORD_LENGTH_CH10_RD(x) (((x) & (((1 << 4) - 1) << 8)) >> 8)
+#define F_SOURCE_NUM_CH11(x) (((x) & ((1 << 4) - 1)) << 12)
+#define F_SOURCE_NUM_CH11_RD(x) (((x) & (((1 << 4) - 1) << 12)) >> 12)
+#define F_CHANNEL_NUM_CH11(x) (((x) & ((1 << 4) - 1)) << 16)
+#define F_CHANNEL_NUM_CH11_RD(x) (((x) & (((1 << 4) - 1) << 16)) >> 16)
+#define F_WORD_LENGTH_CH11(x) (((x) & ((1 << 4) - 1)) << 20)
+#define F_WORD_LENGTH_CH11_RD(x) (((x) & (((1 << 4) - 1) << 20)) >> 20)
+
+/* register SINK_STTS_BIT_CH1213 */
+#define SINK_STTS_BIT_CH1213 12
+#define F_SOURCE_NUM_CH12(x) (((x) & ((1 << 4) - 1)) << 0)
+#define F_SOURCE_NUM_CH12_RD(x) (((x) & (((1 << 4) - 1) << 0)) >> 0)
+#define F_CHANNEL_NUM_CH12(x) (((x) & ((1 << 4) - 1)) << 4)
+#define F_CHANNEL_NUM_CH12_RD(x) (((x) & (((1 << 4) - 1) << 4)) >> 4)
+#define F_WORD_LENGTH_CH12(x) (((x) & ((1 << 4) - 1)) << 8)
+#define F_WORD_LENGTH_CH12_RD(x) (((x) & (((1 << 4) - 1) << 8)) >> 8)
+#define F_SOURCE_NUM_CH13(x) (((x) & ((1 << 4) - 1)) << 12)
+#define F_SOURCE_NUM_CH13_RD(x) (((x) & (((1 << 4) - 1) << 12)) >> 12)
+#define F_CHANNEL_NUM_CH13(x) (((x) & ((1 << 4) - 1)) << 16)
+#define F_CHANNEL_NUM_CH13_RD(x) (((x) & (((1 << 4) - 1) << 16)) >> 16)
+#define F_WORD_LENGTH_CH13(x) (((x) & ((1 << 4) - 1)) << 20)
+#define F_WORD_LENGTH_CH13_RD(x) (((x) & (((1 << 4) - 1) << 20)) >> 20)
+
+/* register SINK_STTS_BIT_CH1415 */
+#define SINK_STTS_BIT_CH1415 13
+#define F_SOURCE_NUM_CH14(x) (((x) & ((1 << 4) - 1)) << 0)
+#define F_SOURCE_NUM_CH14_RD(x) (((x) & (((1 << 4) - 1) << 0)) >> 0)
+#define F_CHANNEL_NUM_CH14(x) (((x) & ((1 << 4) - 1)) << 4)
+#define F_CHANNEL_NUM_CH14_RD(x) (((x) & (((1 << 4) - 1) << 4)) >> 4)
+#define F_WORD_LENGTH_CH14(x) (((x) & ((1 << 4) - 1)) << 8)
+#define F_WORD_LENGTH_CH14_RD(x) (((x) & (((1 << 4) - 1) << 8)) >> 8)
+#define F_SOURCE_NUM_CH15(x) (((x) & ((1 << 4) - 1)) << 12)
+#define F_SOURCE_NUM_CH15_RD(x) (((x) & (((1 << 4) - 1) << 12)) >> 12)
+#define F_CHANNEL_NUM_CH15(x) (((x) & ((1 << 4) - 1)) << 16)
+#define F_CHANNEL_NUM_CH15_RD(x) (((x) & (((1 << 4) - 1) << 16)) >> 16)
+#define F_WORD_LENGTH_CH15(x) (((x) & ((1 << 4) - 1)) << 20)
+#define F_WORD_LENGTH_CH15_RD(x) (((x) & (((1 << 4) - 1) << 20)) >> 20)
+
+/* register SINK_STTS_BIT_CH1617 */
+#define SINK_STTS_BIT_CH1617 14
+#define F_SOURCE_NUM_CH16(x) (((x) & ((1 << 4) - 1)) << 0)
+#define F_SOURCE_NUM_CH16_RD(x) (((x) & (((1 << 4) - 1) << 0)) >> 0)
+#define F_CHANNEL_NUM_CH16(x) (((x) & ((1 << 4) - 1)) << 4)
+#define F_CHANNEL_NUM_CH16_RD(x) (((x) & (((1 << 4) - 1) << 4)) >> 4)
+#define F_WORD_LENGTH_CH16(x) (((x) & ((1 << 4) - 1)) << 8)
+#define F_WORD_LENGTH_CH16_RD(x) (((x) & (((1 << 4) - 1) << 8)) >> 8)
+#define F_SOURCE_NUM_CH17(x) (((x) & ((1 << 4) - 1)) << 12)
+#define F_SOURCE_NUM_CH17_RD(x) (((x) & (((1 << 4) - 1) << 12)) >> 12)
+#define F_CHANNEL_NUM_CH17(x) (((x) & ((1 << 4) - 1)) << 16)
+#define F_CHANNEL_NUM_CH17_RD(x) (((x) & (((1 << 4) - 1) << 16)) >> 16)
+#define F_WORD_LENGTH_CH17(x) (((x) & ((1 << 4) - 1)) << 20)
+#define F_WORD_LENGTH_CH17_RD(x) (((x) & (((1 << 4) - 1) << 20)) >> 20)
+
+/* register SINK_STTS_BIT_CH1819 */
+#define SINK_STTS_BIT_CH1819 15
+#define F_SOURCE_NUM_CH18(x) (((x) & ((1 << 4) - 1)) << 0)
+#define F_SOURCE_NUM_CH18_RD(x) (((x) & (((1 << 4) - 1) << 0)) >> 0)
+#define F_CHANNEL_NUM_CH18(x) (((x) & ((1 << 4) - 1)) << 4)
+#define F_CHANNEL_NUM_CH18_RD(x) (((x) & (((1 << 4) - 1) << 4)) >> 4)
+#define F_WORD_LENGTH_CH18(x) (((x) & ((1 << 4) - 1)) << 8)
+#define F_WORD_LENGTH_CH18_RD(x) (((x) & (((1 << 4) - 1) << 8)) >> 8)
+#define F_SOURCE_NUM_CH19(x) (((x) & ((1 << 4) - 1)) << 12)
+#define F_SOURCE_NUM_CH19_RD(x) (((x) & (((1 << 4) - 1) << 12)) >> 12)
+#define F_CHANNEL_NUM_CH19(x) (((x) & ((1 << 4) - 1)) << 16)
+#define F_CHANNEL_NUM_CH19_RD(x) (((x) & (((1 << 4) - 1) << 16)) >> 16)
+#define F_WORD_LENGTH_CH19(x) (((x) & ((1 << 4) - 1)) << 20)
+#define F_WORD_LENGTH_CH19_RD(x) (((x) & (((1 << 4) - 1) << 20)) >> 20)
+
+/* register SINK_STTS_BIT_CH2021 */
+#define SINK_STTS_BIT_CH2021 16
+#define F_SOURCE_NUM_CH20(x) (((x) & ((1 << 4) - 1)) << 0)
+#define F_SOURCE_NUM_CH20_RD(x) (((x) & (((1 << 4) - 1) << 0)) >> 0)
+#define F_CHANNEL_NUM_CH20(x) (((x) & ((1 << 4) - 1)) << 4)
+#define F_CHANNEL_NUM_CH20_RD(x) (((x) & (((1 << 4) - 1) << 4)) >> 4)
+#define F_WORD_LENGTH_CH20(x) (((x) & ((1 << 4) - 1)) << 8)
+#define F_WORD_LENGTH_CH20_RD(x) (((x) & (((1 << 4) - 1) << 8)) >> 8)
+#define F_SOURCE_NUM_CH21(x) (((x) & ((1 << 4) - 1)) << 12)
+#define F_SOURCE_NUM_CH21_RD(x) (((x) & (((1 << 4) - 1) << 12)) >> 12)
+#define F_CHANNEL_NUM_CH21(x) (((x) & ((1 << 4) - 1)) << 16)
+#define F_CHANNEL_NUM_CH21_RD(x) (((x) & (((1 << 4) - 1) << 16)) >> 16)
+#define F_WORD_LENGTH_CH21(x) (((x) & ((1 << 4) - 1)) << 20)
+#define F_WORD_LENGTH_CH21_RD(x) (((x) & (((1 << 4) - 1) << 20)) >> 20)
+
+/* register SINK_STTS_BIT_CH2223 */
+#define SINK_STTS_BIT_CH2223 17
+#define F_SOURCE_NUM_CH22(x) (((x) & ((1 << 4) - 1)) << 0)
+#define F_SOURCE_NUM_CH22_RD(x) (((x) & (((1 << 4) - 1) << 0)) >> 0)
+#define F_CHANNEL_NUM_CH22(x) (((x) & ((1 << 4) - 1)) << 4)
+#define F_CHANNEL_NUM_CH22_RD(x) (((x) & (((1 << 4) - 1) << 4)) >> 4)
+#define F_WORD_LENGTH_CH22(x) (((x) & ((1 << 4) - 1)) << 8)
+#define F_WORD_LENGTH_CH22_RD(x) (((x) & (((1 << 4) - 1) << 8)) >> 8)
+#define F_SOURCE_NUM_CH23(x) (((x) & ((1 << 4) - 1)) << 12)
+#define F_SOURCE_NUM_CH23_RD(x) (((x) & (((1 << 4) - 1) << 12)) >> 12)
+#define F_CHANNEL_NUM_CH23(x) (((x) & ((1 << 4) - 1)) << 16)
+#define F_CHANNEL_NUM_CH23_RD(x) (((x) & (((1 << 4) - 1) << 16)) >> 16)
+#define F_WORD_LENGTH_CH23(x) (((x) & ((1 << 4) - 1)) << 20)
+#define F_WORD_LENGTH_CH23_RD(x) (((x) & (((1 << 4) - 1) << 20)) >> 20)
+
+/* register SINK_STTS_BIT_CH2425 */
+#define SINK_STTS_BIT_CH2425 18
+#define F_SOURCE_NUM_CH24(x) (((x) & ((1 << 4) - 1)) << 0)
+#define F_SOURCE_NUM_CH24_RD(x) (((x) & (((1 << 4) - 1) << 0)) >> 0)
+#define F_CHANNEL_NUM_CH24(x) (((x) & ((1 << 4) - 1)) << 4)
+#define F_CHANNEL_NUM_CH24_RD(x) (((x) & (((1 << 4) - 1) << 4)) >> 4)
+#define F_WORD_LENGTH_CH24(x) (((x) & ((1 << 4) - 1)) << 8)
+#define F_WORD_LENGTH_CH24_RD(x) (((x) & (((1 << 4) - 1) << 8)) >> 8)
+#define F_SOURCE_NUM_CH25(x) (((x) & ((1 << 4) - 1)) << 12)
+#define F_SOURCE_NUM_CH25_RD(x) (((x) & (((1 << 4) - 1) << 12)) >> 12)
+#define F_CHANNEL_NUM_CH25(x) (((x) & ((1 << 4) - 1)) << 16)
+#define F_CHANNEL_NUM_CH25_RD(x) (((x) & (((1 << 4) - 1) << 16)) >> 16)
+#define F_WORD_LENGTH_CH25(x) (((x) & ((1 << 4) - 1)) << 20)
+#define F_WORD_LENGTH_CH25_RD(x) (((x) & (((1 << 4) - 1) << 20)) >> 20)
+
+/* register SINK_STTS_BIT_CH2627 */
+#define SINK_STTS_BIT_CH2627 19
+#define F_SOURCE_NUM_CH26(x) (((x) & ((1 << 4) - 1)) << 0)
+#define F_SOURCE_NUM_CH26_RD(x) (((x) & (((1 << 4) - 1) << 0)) >> 0)
+#define F_CHANNEL_NUM_CH26(x) (((x) & ((1 << 4) - 1)) << 4)
+#define F_CHANNEL_NUM_CH26_RD(x) (((x) & (((1 << 4) - 1) << 4)) >> 4)
+#define F_WORD_LENGTH_CH26(x) (((x) & ((1 << 4) - 1)) << 8)
+#define F_WORD_LENGTH_CH26_RD(x) (((x) & (((1 << 4) - 1) << 8)) >> 8)
+#define F_SOURCE_NUM_CH27(x) (((x) & ((1 << 4) - 1)) << 12)
+#define F_SOURCE_NUM_CH27_RD(x) (((x) & (((1 << 4) - 1) << 12)) >> 12)
+#define F_CHANNEL_NUM_CH27(x) (((x) & ((1 << 4) - 1)) << 16)
+#define F_CHANNEL_NUM_CH27_RD(x) (((x) & (((1 << 4) - 1) << 16)) >> 16)
+#define F_WORD_LENGTH_CH27(x) (((x) & ((1 << 4) - 1)) << 20)
+#define F_WORD_LENGTH_CH27_RD(x) (((x) & (((1 << 4) - 1) << 20)) >> 20)
+
+/* register SINK_STTS_BIT_CH2829 */
+#define SINK_STTS_BIT_CH2829 20
+#define F_SOURCE_NUM_CH28(x) (((x) & ((1 << 4) - 1)) << 0)
+#define F_SOURCE_NUM_CH28_RD(x) (((x) & (((1 << 4) - 1) << 0)) >> 0)
+#define F_CHANNEL_NUM_CH28(x) (((x) & ((1 << 4) - 1)) << 4)
+#define F_CHANNEL_NUM_CH28_RD(x) (((x) & (((1 << 4) - 1) << 4)) >> 4)
+#define F_WORD_LENGTH_CH28(x) (((x) & ((1 << 4) - 1)) << 8)
+#define F_WORD_LENGTH_CH28_RD(x) (((x) & (((1 << 4) - 1) << 8)) >> 8)
+#define F_SOURCE_NUM_CH29(x) (((x) & ((1 << 4) - 1)) << 12)
+#define F_SOURCE_NUM_CH29_RD(x) (((x) & (((1 << 4) - 1) << 12)) >> 12)
+#define F_CHANNEL_NUM_CH29(x) (((x) & ((1 << 4) - 1)) << 16)
+#define F_CHANNEL_NUM_CH29_RD(x) (((x) & (((1 << 4) - 1) << 16)) >> 16)
+#define F_WORD_LENGTH_CH29(x) (((x) & ((1 << 4) - 1)) << 20)
+#define F_WORD_LENGTH_CH29_RD(x) (((x) & (((1 << 4) - 1) << 20)) >> 20)
+
+/* register SINK_STTS_BIT_CH3031 */
+#define SINK_STTS_BIT_CH3031 21
+#define F_SOURCE_NUM_CH30(x) (((x) & ((1 << 4) - 1)) << 0)
+#define F_SOURCE_NUM_CH30_RD(x) (((x) & (((1 << 4) - 1) << 0)) >> 0)
+#define F_CHANNEL_NUM_CH30(x) (((x) & ((1 << 4) - 1)) << 4)
+#define F_CHANNEL_NUM_CH30_RD(x) (((x) & (((1 << 4) - 1) << 4)) >> 4)
+#define F_WORD_LENGTH_CH30(x) (((x) & ((1 << 4) - 1)) << 8)
+#define F_WORD_LENGTH_CH30_RD(x) (((x) & (((1 << 4) - 1) << 8)) >> 8)
+#define F_SOURCE_NUM_CH31(x) (((x) & ((1 << 4) - 1)) << 12)
+#define F_SOURCE_NUM_CH31_RD(x) (((x) & (((1 << 4) - 1) << 12)) >> 12)
+#define F_CHANNEL_NUM_CH31(x) (((x) & ((1 << 4) - 1)) << 16)
+#define F_CHANNEL_NUM_CH31_RD(x) (((x) & (((1 << 4) - 1) << 16)) >> 16)
+#define F_WORD_LENGTH_CH31(x) (((x) & ((1 << 4) - 1)) << 20)
+#define F_WORD_LENGTH_CH31_RD(x) (((x) & (((1 << 4) - 1) << 20)) >> 20)
+
+#endif /* SINK_AIF_ENCODER */
+
diff --git a/drivers/mxc/hdp/sink_car.h b/drivers/mxc/hdp/sink_car.h
new file mode 100644
index 000000000000..a38001c15b02
--- /dev/null
+++ b/drivers/mxc/hdp/sink_car.h
@@ -0,0 +1,168 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2016-2017 Cadence Design Systems, Inc.
+ * All rights reserved worldwide.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 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.
+ *
+ * Copyright 2018 NXP
+ *
+ ******************************************************************************
+ *
+ * This file was auto-generated. Do not edit it manually.
+ *
+ ******************************************************************************
+ *
+ * sink_car.h
+ *
+ ******************************************************************************
+ */
+
+#ifndef SINK_CAR_H_
+#define SINK_CAR_H_
+
+/* register SINK_MHL_HD_CAR */
+#define SINK_MHL_HD_CAR 0
+#define F_SINK_MHL_HD_VIF_CLK_EN(x) (((x) & ((1 << 1) - 1)) << 0)
+#define F_SINK_MHL_HD_VIF_CLK_EN_RD(x) (((x) & (((1 << 1) - 1) << 0)) >> 0)
+#define F_SINK_MHL_HD_VIF_RSTN_EN(x) (((x) & ((1 << 1) - 1)) << 1)
+#define F_SINK_MHL_HD_VIF_RSTN_EN_RD(x) (((x) & (((1 << 1) - 1) << 1)) >> 1)
+#define F_SINK_MHL_HD_SYS_CLK_EN(x) (((x) & ((1 << 1) - 1)) << 2)
+#define F_SINK_MHL_HD_SYS_CLK_EN_RD(x) (((x) & (((1 << 1) - 1) << 2)) >> 2)
+#define F_SINK_MHL_HD_SYS_CLK_RSTN_EN(x) (((x) & ((1 << 1) - 1)) << 3)
+#define F_SINK_MHL_HD_SYS_CLK_RSTN_EN_RD(x) (((x) & (((1 << 1) - 1) << 3)) >> 3)
+#define F_SINK_MHL_HD_PHY_DATA_CLK_EN(x) (((x) & ((1 << 1) - 1)) << 4)
+#define F_SINK_MHL_HD_PHY_DATA_CLK_EN_RD(x) (((x) & (((1 << 1) - 1) << 4)) >> 4)
+#define F_SINK_MHL_HD_PHY_DATA_RSTN_EN(x) (((x) & ((1 << 1) - 1)) << 5)
+#define F_SINK_MHL_HD_PHY_DATA_RSTN_EN_RD(x) (((x) & (((1 << 1) - 1) << 5)) >> 5)
+
+/* register SINK_CEC_CAR */
+#define SINK_CEC_CAR 1
+#define F_SINK_CEC_SYS_CLK_RSTN_EN(x) (((x) & ((1 << 1) - 1)) << 0)
+#define F_SINK_CEC_SYS_CLK_RSTN_EN_RD(x) (((x) & (((1 << 1) - 1) << 0)) >> 0)
+#define F_SINK_CEC_SYS_CLK_EN(x) (((x) & ((1 << 1) - 1)) << 1)
+#define F_SINK_CEC_SYS_CLK_EN_RD(x) (((x) & (((1 << 1) - 1) << 1)) >> 1)
+
+/* register SINK_SCDC_CAR */
+#define SINK_SCDC_CAR 2
+#define F_SINK_SCDC_SYS_CLK_EN(x) (((x) & ((1 << 1) - 1)) << 0)
+#define F_SINK_SCDC_SYS_CLK_EN_RD(x) (((x) & (((1 << 1) - 1) << 0)) >> 0)
+#define F_SINK_SCDC_SYS_CLK_RSTN_EN(x) (((x) & ((1 << 1) - 1)) << 1)
+#define F_SINK_SCDC_SYS_CLK_RSTN_EN_RD(x) (((x) & (((1 << 1) - 1) << 1)) >> 1)
+#define F_SINK_SCDC_RSTN_EN(x) (((x) & ((1 << 8) - 1)) << 8)
+#define F_SINK_SCDC_RSTN_EN_RD(x) (((x) & (((1 << 8) - 1) << 8)) >> 8)
+#define F_SINK_SCDC_CLK_EN(x) (((x) & ((1 << 8) - 1)) << 16)
+#define F_SINK_SCDC_CLK_EN_RD(x) (((x) & (((1 << 8) - 1) << 16)) >> 16)
+
+/* register SINK_PKT_CAR */
+#define SINK_PKT_CAR 3
+#define F_SINK_PKT_SYS_CLK_EN(x) (((x) & ((1 << 1) - 1)) << 0)
+#define F_SINK_PKT_SYS_CLK_EN_RD(x) (((x) & (((1 << 1) - 1) << 0)) >> 0)
+#define F_SINK_PKT_SYS_RSTN_EN(x) (((x) & ((1 << 1) - 1)) << 1)
+#define F_SINK_PKT_SYS_RSTN_EN_RD(x) (((x) & (((1 << 1) - 1) << 1)) >> 1)
+#define F_SINK_PKT_DATA_CLK_EN(x) (((x) & ((1 << 1) - 1)) << 2)
+#define F_SINK_PKT_DATA_CLK_EN_RD(x) (((x) & (((1 << 1) - 1) << 2)) >> 2)
+#define F_SINK_PKT_DATA_RSTN_EN(x) (((x) & ((1 << 1) - 1)) << 3)
+#define F_SINK_PKT_DATA_RSTN_EN_RD(x) (((x) & (((1 << 1) - 1) << 3)) >> 3)
+
+/* register SINK_AIF_CAR */
+#define SINK_AIF_CAR 4
+#define F_SINK_AIF_CLK_EN(x) (((x) & ((1 << 1) - 1)) << 0)
+#define F_SINK_AIF_CLK_EN_RD(x) (((x) & (((1 << 1) - 1) << 0)) >> 0)
+#define F_SINK_AIF_CLK_RSTN_EN(x) (((x) & ((1 << 1) - 1)) << 1)
+#define F_SINK_AIF_CLK_RSTN_EN_RD(x) (((x) & (((1 << 1) - 1) << 1)) >> 1)
+#define F_SINK_AIF_SYS_CLK_EN(x) (((x) & ((1 << 1) - 1)) << 2)
+#define F_SINK_AIF_SYS_CLK_EN_RD(x) (((x) & (((1 << 1) - 1) << 2)) >> 2)
+#define F_SINK_AIF_SYS_RSTN_EN(x) (((x) & ((1 << 1) - 1)) << 3)
+#define F_SINK_AIF_SYS_RSTN_EN_RD(x) (((x) & (((1 << 1) - 1) << 3)) >> 3)
+#define F_SINK_ACR_CHAR_CLK_EN(x) (((x) & ((1 << 1) - 1)) << 4)
+#define F_SINK_ACR_CHAR_CLK_EN_RD(x) (((x) & (((1 << 1) - 1) << 4)) >> 4)
+#define F_SINK_ACR_CHAR_CLK_RSTN_EN(x) (((x) & ((1 << 1) - 1)) << 5)
+#define F_SINK_ACR_CHAR_CLK_RSTN_EN_RD(x) (((x) & (((1 << 1) - 1) << 5)) >> 5)
+
+/* register SINK_CIPHER_CAR */
+#define SINK_CIPHER_CAR 5
+#define F_SINK_CIPHER_CHAR_CLK_EN(x) (((x) & ((1 << 1) - 1)) << 0)
+#define F_SINK_CIPHER_CHAR_CLK_EN_RD(x) (((x) & (((1 << 1) - 1) << 0)) >> 0)
+#define F_SINK_CIPHER_CHAR_CLK_RSTN_EN(x) (((x) & ((1 << 1) - 1)) << 1)
+#define F_SINK_CIPHER_CHAR_CLK_RSTN_EN_RD(x) (((x) & (((1 << 1) - 1) << 1)) >> 1)
+#define F_SINK_CIPHER_SYS_CLK_EN(x) (((x) & ((1 << 1) - 1)) << 2)
+#define F_SINK_CIPHER_SYS_CLK_EN_RD(x) (((x) & (((1 << 1) - 1) << 2)) >> 2)
+#define F_SINK_CIPHER_SYS_CLK_RSTN_EN(x) (((x) & ((1 << 1) - 1)) << 3)
+#define F_SINK_CIPHER_SYS_CLK_RSTN_EN_RD(x) (((x) & (((1 << 1) - 1) << 3)) >> 3)
+
+/* register SINK_CRYPTO_CAR */
+#define SINK_CRYPTO_CAR 6
+#define F_SINK_CRYPTO_SYS_CLK_EN(x) (((x) & ((1 << 1) - 1)) << 0)
+#define F_SINK_CRYPTO_SYS_CLK_EN_RD(x) (((x) & (((1 << 1) - 1) << 0)) >> 0)
+#define F_SINK_CRYPTO_SYS_CLK_RSTN_EN(x) (((x) & ((1 << 1) - 1)) << 1)
+#define F_SINK_CRYPTO_SYS_CLK_RSTN_EN_RD(x) (((x) & (((1 << 1) - 1) << 1)) >> 1)
+
+/* register SINK_VIF_CAR */
+#define SINK_VIF_CAR 7
+#define F_SINK_VIF_CLK_EN(x) (((x) & ((1 << 1) - 1)) << 0)
+#define F_SINK_VIF_CLK_EN_RD(x) (((x) & (((1 << 1) - 1) << 0)) >> 0)
+#define F_SINK_VIF_RSTN_EN(x) (((x) & ((1 << 1) - 1)) << 1)
+#define F_SINK_VIF_RSTN_EN_RD(x) (((x) & (((1 << 1) - 1) << 1)) >> 1)
+
+/* register SINK_AUDIO_CAR */
+#define SINK_AUDIO_CAR 8
+#define F_SINK_ACR_REF_CLK_EN(x) (((x) & ((1 << 1) - 1)) << 0)
+#define F_SINK_ACR_REF_CLK_EN_RD(x) (((x) & (((1 << 1) - 1) << 0)) >> 0)
+#define F_SINK_ACR_REF_CLK_RSTN_EN(x) (((x) & ((1 << 1) - 1)) << 1)
+#define F_SINK_ACR_REF_CLK_RSTN_EN_RD(x) (((x) & (((1 << 1) - 1) << 1)) >> 1)
+#define F_SINK_SPDIF_MCLK_EN(x) (((x) & ((1 << 1) - 1)) << 2)
+#define F_SINK_SPDIF_MCLK_EN_RD(x) (((x) & (((1 << 1) - 1) << 2)) >> 2)
+#define F_SINK_SPDIF_MCLK_RSTN_EN(x) (((x) & ((1 << 1) - 1)) << 3)
+#define F_SINK_SPDIF_MCLK_RSTN_EN_RD(x) (((x) & (((1 << 1) - 1) << 3)) >> 3)
+#define F_SINK_I2S_CLK_EN(x) (((x) & ((1 << 1) - 1)) << 4)
+#define F_SINK_I2S_CLK_EN_RD(x) (((x) & (((1 << 1) - 1) << 4)) >> 4)
+#define F_SINK_I2S_CLK_RSTN_EN(x) (((x) & ((1 << 1) - 1)) << 5)
+#define F_SINK_I2S_CLK_RSTN_EN_RD(x) (((x) & (((1 << 1) - 1) << 5)) >> 5)
+
+/* register SINK_PHY_CAR */
+#define SINK_PHY_CAR 9
+#define F_SINK_XT_PCLK_EN(x) (((x) & ((1 << 1) - 1)) << 0)
+#define F_SINK_XT_PCLK_EN_RD(x) (((x) & (((1 << 1) - 1) << 0)) >> 0)
+#define F_SINK_XT_PRESETN_EN(x) (((x) & ((1 << 1) - 1)) << 1)
+#define F_SINK_XT_PRESETN_EN_RD(x) (((x) & (((1 << 1) - 1) << 1)) >> 1)
+
+/* register SINK_DEBUG_CAR */
+#define SINK_DEBUG_CAR 10
+#define F_SINK_CLOCK_METER_SYS_CLK_EN(x) (((x) & ((1 << 1) - 1)) << 0)
+#define F_SINK_CLOCK_METER_SYS_CLK_EN_RD(x) (((x) & (((1 << 1) - 1) << 0)) >> 0)
+#define F_SINK_CLOCK_METER_SYS_RSTN_EN(x) (((x) & ((1 << 1) - 1)) << 1)
+#define F_SINK_CLOCK_METER_SYS_RSTN_EN_RD(x) (((x) & (((1 << 1) - 1) << 1)) >> 1)
+
+#endif /* SINK_CAR */
+
diff --git a/drivers/mxc/hdp/sink_clk_meters.h b/drivers/mxc/hdp/sink_clk_meters.h
new file mode 100644
index 000000000000..c238b9785583
--- /dev/null
+++ b/drivers/mxc/hdp/sink_clk_meters.h
@@ -0,0 +1,241 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2016-2017 Cadence Design Systems, Inc.
+ * All rights reserved worldwide.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 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.
+ *
+ * Copyright 2018 NXP
+ *
+ ******************************************************************************
+ *
+ * This file was auto-generated. Do not edit it manually.
+ *
+ ******************************************************************************
+ *
+ * sink_clk_meters.h
+ *
+ ******************************************************************************
+ */
+
+#ifndef SINK_CLK_METERS_H_
+#define SINK_CLK_METERS_H_
+
+/* register CLK_METER_REF_CFG */
+#define CLK_METER_REF_CFG 0
+#define F_REF_CYCLES_SINK_REF_CLK(x) (((x) & ((1 << 24) - 1)) << 0)
+#define F_REF_CYCLES_SINK_REF_CLK_RD(x) (((x) & (((1 << 24) - 1) << 0)) >> 0)
+#define F_MEAS_TOLERANCE_SINK_REF_CLK(x) (((x) & ((1 << 4) - 1)) << 24)
+#define F_MEAS_TOLERANCE_SINK_REF_CLK_RD(x) (((x) & (((1 << 4) - 1) << 24)) >> 24)
+
+/* register CLK_METER_PHY_CHAR_CFG */
+#define CLK_METER_PHY_CHAR_CFG 1
+#define F_REF_CYCLES_SINK_PHY_CHAR_CLK(x) (((x) & ((1 << 24) - 1)) << 0)
+#define F_REF_CYCLES_SINK_PHY_CHAR_CLK_RD(x) (((x) & (((1 << 24) - 1) << 0)) >> 0)
+#define F_MEAS_TOLERANCE_SINK_PHY_CHAR_CLK(x) (((x) & ((1 << 4) - 1)) << 24)
+#define F_MEAS_TOLERANCE_SINK_PHY_CHAR_CLK_RD(x) (((x) & (((1 << 4) - 1) << 24)) >> 24)
+
+/* register CLK_METER_PHY_DATA_CFG */
+#define CLK_METER_PHY_DATA_CFG 2
+#define F_REF_CYCLES_SINK_PHY_DATA_CLK(x) (((x) & ((1 << 24) - 1)) << 0)
+#define F_REF_CYCLES_SINK_PHY_DATA_CLK_RD(x) (((x) & (((1 << 24) - 1) << 0)) >> 0)
+#define F_MEAS_TOLERANCE_SINK_PHY_DATA_CLK(x) (((x) & ((1 << 4) - 1)) << 24)
+#define F_MEAS_TOLERANCE_SINK_PHY_DATA_CLK_RD(x) (((x) & (((1 << 4) - 1) << 24)) >> 24)
+
+/* register CLK_METER_PHY_PIXEL_CFG */
+#define CLK_METER_PHY_PIXEL_CFG 3
+#define F_REF_CYCLES_SINK_PHY_PIXEL_CLK(x) (((x) & ((1 << 24) - 1)) << 0)
+#define F_REF_CYCLES_SINK_PHY_PIXEL_CLK_RD(x) (((x) & (((1 << 24) - 1) << 0)) >> 0)
+#define F_MEAS_TOLERANCE_SINK_PHY_PIXEL_CLK(x) (((x) & ((1 << 4) - 1)) << 24)
+#define F_MEAS_TOLERANCE_SINK_PHY_PIXEL_CLK_RD(x) (((x) & (((1 << 4) - 1) << 24)) >> 24)
+
+/* register CLK_METER_SPDIF_CFG */
+#define CLK_METER_SPDIF_CFG 4
+#define F_REF_CYCLES_SINK_SPDIF_MCLK(x) (((x) & ((1 << 24) - 1)) << 0)
+#define F_REF_CYCLES_SINK_SPDIF_MCLK_RD(x) (((x) & (((1 << 24) - 1) << 0)) >> 0)
+#define F_MEAS_TOLERANCE_SINK_SPDIF_MCLK(x) (((x) & ((1 << 4) - 1)) << 24)
+#define F_MEAS_TOLERANCE_SINK_SPDIF_MCLK_RD(x) (((x) & (((1 << 4) - 1) << 24)) >> 24)
+
+/* register CLK_METER_I2S_CFG */
+#define CLK_METER_I2S_CFG 5
+#define F_REF_CYCLES_SINK_I2S_CLK(x) (((x) & ((1 << 24) - 1)) << 0)
+#define F_REF_CYCLES_SINK_I2S_CLK_RD(x) (((x) & (((1 << 24) - 1) << 0)) >> 0)
+#define F_MEAS_TOLERANCE_SINK_I2S_CLK(x) (((x) & ((1 << 4) - 1)) << 24)
+#define F_MEAS_TOLERANCE_SINK_I2S_CLK_RD(x) (((x) & (((1 << 4) - 1) << 24)) >> 24)
+
+/* register CLK_METER_PCLK_CFG */
+#define CLK_METER_PCLK_CFG 6
+#define F_REF_CYCLES_SINK_PCLK(x) (((x) & ((1 << 24) - 1)) << 0)
+#define F_REF_CYCLES_SINK_PCLK_RD(x) (((x) & (((1 << 24) - 1) << 0)) >> 0)
+#define F_MEAS_TOLERANCE_SINK_PCLK(x) (((x) & ((1 << 4) - 1)) << 24)
+#define F_MEAS_TOLERANCE_SINK_PCLK_RD(x) (((x) & (((1 << 4) - 1) << 24)) >> 24)
+
+/* register CLK_METER_SCLK_CFG */
+#define CLK_METER_SCLK_CFG 7
+#define F_REF_CYCLES_SINK_SCLK(x) (((x) & ((1 << 24) - 1)) << 0)
+#define F_REF_CYCLES_SINK_SCLK_RD(x) (((x) & (((1 << 24) - 1) << 0)) >> 0)
+#define F_MEAS_TOLERANCE_SINK_SCLK(x) (((x) & ((1 << 4) - 1)) << 24)
+#define F_MEAS_TOLERANCE_SINK_SCLK_RD(x) (((x) & (((1 << 4) - 1) << 24)) >> 24)
+
+/* register CLK_METER_CCLK_CFG */
+#define CLK_METER_CCLK_CFG 8
+#define F_REF_CYCLES_SINK_CCLK(x) (((x) & ((1 << 24) - 1)) << 0)
+#define F_REF_CYCLES_SINK_CCLK_RD(x) (((x) & (((1 << 24) - 1) << 0)) >> 0)
+#define F_MEAS_TOLERANCE_SINK_CCLK(x) (((x) & ((1 << 4) - 1)) << 24)
+#define F_MEAS_TOLERANCE_SINK_CCLK_RD(x) (((x) & (((1 << 4) - 1) << 24)) >> 24)
+
+/* register CLK_METER_TRNG_CFG */
+#define CLK_METER_TRNG_CFG 9
+#define F_REF_CYCLES_SINK_TRNG_CLK(x) (((x) & ((1 << 24) - 1)) << 0)
+#define F_REF_CYCLES_SINK_TRNG_CLK_RD(x) (((x) & (((1 << 24) - 1) << 0)) >> 0)
+#define F_MEAS_TOLERANCE_SINK_TRNG_CLK(x) (((x) & ((1 << 4) - 1)) << 24)
+#define F_MEAS_TOLERANCE_SINK_TRNG_CLK_RD(x) (((x) & (((1 << 4) - 1) << 24)) >> 24)
+
+/* register CLK_METER_REF_ST */
+#define CLK_METER_REF_ST 10
+#define F_MEAS_CYCLES_SINK_REF_CLK(x) (((x) & ((1 << 24) - 1)) << 0)
+#define F_MEAS_CYCLES_SINK_REF_CLK_RD(x) (((x) & (((1 << 24) - 1) << 0)) >> 0)
+#define F_MEAS_STABLE_SINK_REF_CLK(x) (((x) & ((1 << 1) - 1)) << 24)
+#define F_MEAS_STABLE_SINK_REF_CLK_RD(x) (((x) & (((1 << 1) - 1) << 24)) >> 24)
+
+/* register CLK_METER_PHY_CHAR_ST */
+#define CLK_METER_PHY_CHAR_ST 11
+#define F_MEAS_CYCLES_SINK_PHY_CHAR_CLK(x) (((x) & ((1 << 24) - 1)) << 0)
+#define F_MEAS_CYCLES_SINK_PHY_CHAR_CLK_RD(x) (((x) & (((1 << 24) - 1) << 0)) >> 0)
+#define F_MEAS_STABLE_SINK_PHY_CHAR_CLK(x) (((x) & ((1 << 1) - 1)) << 24)
+#define F_MEAS_STABLE_SINK_PHY_CHAR_CLK_RD(x) (((x) & (((1 << 1) - 1) << 24)) >> 24)
+
+/* register CLK_METER_PHY_DATA_ST */
+#define CLK_METER_PHY_DATA_ST 12
+#define F_MEAS_CYCLES_SINK_PHY_DATA_CLK(x) (((x) & ((1 << 24) - 1)) << 0)
+#define F_MEAS_CYCLES_SINK_PHY_DATA_CLK_RD(x) (((x) & (((1 << 24) - 1) << 0)) >> 0)
+#define F_MEAS_STABLE_SINK_PHY_DATA_CLK(x) (((x) & ((1 << 1) - 1)) << 24)
+#define F_MEAS_STABLE_SINK_PHY_DATA_CLK_RD(x) (((x) & (((1 << 1) - 1) << 24)) >> 24)
+
+/* register CLK_METER_PHY_PIXEL_ST */
+#define CLK_METER_PHY_PIXEL_ST 13
+#define F_MEAS_CYCLES_SINK_PHY_PIXEL_CLK(x) (((x) & ((1 << 24) - 1)) << 0)
+#define F_MEAS_CYCLES_SINK_PHY_PIXEL_CLK_RD(x) (((x) & (((1 << 24) - 1) << 0)) >> 0)
+#define F_MEAS_STABLE_SINK_PHY_PIXEL_CLK(x) (((x) & ((1 << 1) - 1)) << 24)
+#define F_MEAS_STABLE_SINK_PHY_PIXEL_CLK_RD(x) (((x) & (((1 << 1) - 1) << 24)) >> 24)
+
+/* register CLK_METER_SPDIF_ST */
+#define CLK_METER_SPDIF_ST 14
+#define F_MEAS_CYCLES_SINK_SPDIF_MCLK(x) (((x) & ((1 << 24) - 1)) << 0)
+#define F_MEAS_CYCLES_SINK_SPDIF_MCLK_RD(x) (((x) & (((1 << 24) - 1) << 0)) >> 0)
+#define F_MEAS_STABLE_SINK_SPDIF_MCLK(x) (((x) & ((1 << 1) - 1)) << 24)
+#define F_MEAS_STABLE_SINK_SPDIF_MCLK_RD(x) (((x) & (((1 << 1) - 1) << 24)) >> 24)
+
+/* register CLK_METER_I2S_ST */
+#define CLK_METER_I2S_ST 15
+#define F_MEAS_CYCLES_SINK_I2S_CLK(x) (((x) & ((1 << 24) - 1)) << 0)
+#define F_MEAS_CYCLES_SINK_I2S_CLK_RD(x) (((x) & (((1 << 24) - 1) << 0)) >> 0)
+#define F_MEAS_STABLE_SINK_I2S_CLK(x) (((x) & ((1 << 1) - 1)) << 24)
+#define F_MEAS_STABLE_SINK_I2S_CLK_RD(x) (((x) & (((1 << 1) - 1) << 24)) >> 24)
+
+/* register CLK_METER_PCLK_ST */
+#define CLK_METER_PCLK_ST 16
+#define F_MEAS_CYCLES_SINK_PCLK(x) (((x) & ((1 << 24) - 1)) << 0)
+#define F_MEAS_CYCLES_SINK_PCLK_RD(x) (((x) & (((1 << 24) - 1) << 0)) >> 0)
+#define F_MEAS_STABLE_SINK_PCLK(x) (((x) & ((1 << 1) - 1)) << 24)
+#define F_MEAS_STABLE_SINK_PCLK_RD(x) (((x) & (((1 << 1) - 1) << 24)) >> 24)
+
+/* register CLK_METER_SCLK_ST */
+#define CLK_METER_SCLK_ST 17
+#define F_MEAS_CYCLES_SINK_SCLK(x) (((x) & ((1 << 24) - 1)) << 0)
+#define F_MEAS_CYCLES_SINK_SCLK_RD(x) (((x) & (((1 << 24) - 1) << 0)) >> 0)
+#define F_MEAS_STABLE_SINK_SCLK(x) (((x) & ((1 << 1) - 1)) << 24)
+#define F_MEAS_STABLE_SINK_SCLK_RD(x) (((x) & (((1 << 1) - 1) << 24)) >> 24)
+
+/* register CLK_METER_CCLK_ST */
+#define CLK_METER_CCLK_ST 18
+#define F_MEAS_CYCLES_SINK_CCLK(x) (((x) & ((1 << 24) - 1)) << 0)
+#define F_MEAS_CYCLES_SINK_CCLK_RD(x) (((x) & (((1 << 24) - 1) << 0)) >> 0)
+#define F_MEAS_STABLE_SINK_CCLK(x) (((x) & ((1 << 1) - 1)) << 24)
+#define F_MEAS_STABLE_SINK_CCLK_RD(x) (((x) & (((1 << 1) - 1) << 24)) >> 24)
+
+/* register CLK_METER_TRNG_ST */
+#define CLK_METER_TRNG_ST 19
+#define F_MEAS_CYCLES_SINK_TRNG_CLK(x) (((x) & ((1 << 24) - 1)) << 0)
+#define F_MEAS_CYCLES_SINK_TRNG_CLK_RD(x) (((x) & (((1 << 24) - 1) << 0)) >> 0)
+#define F_MEAS_STABLE_SINK_TRNG_CLK(x) (((x) & ((1 << 1) - 1)) << 24)
+#define F_MEAS_STABLE_SINK_TRNG_CLK_RD(x) (((x) & (((1 << 1) - 1) << 24)) >> 24)
+
+/* register CLK_METER_INT_MASK */
+#define CLK_METER_INT_MASK 20
+#define F_MEAS_MASK_SINK_REF_CLK(x) (((x) & ((1 << 1) - 1)) << 0)
+#define F_MEAS_MASK_SINK_REF_CLK_RD(x) (((x) & (((1 << 1) - 1) << 0)) >> 0)
+#define F_MEAS_MASK_SINK_PHY_CHAR_CLK(x) (((x) & ((1 << 1) - 1)) << 1)
+#define F_MEAS_MASK_SINK_PHY_CHAR_CLK_RD(x) (((x) & (((1 << 1) - 1) << 1)) >> 1)
+#define F_MEAS_MASK_SINK_PHY_DATA_CLK(x) (((x) & ((1 << 1) - 1)) << 2)
+#define F_MEAS_MASK_SINK_PHY_DATA_CLK_RD(x) (((x) & (((1 << 1) - 1) << 2)) >> 2)
+#define F_MEAS_MASK_SINK_PHY_PIXEL_CLK(x) (((x) & ((1 << 1) - 1)) << 3)
+#define F_MEAS_MASK_SINK_PHY_PIXEL_CLK_RD(x) (((x) & (((1 << 1) - 1) << 3)) >> 3)
+#define F_MEAS_MASK_SINK_SPDIF_MCLK(x) (((x) & ((1 << 1) - 1)) << 4)
+#define F_MEAS_MASK_SINK_SPDIF_MCLK_RD(x) (((x) & (((1 << 1) - 1) << 4)) >> 4)
+#define F_MEAS_MASK_SINK_I2S_CLK(x) (((x) & ((1 << 1) - 1)) << 5)
+#define F_MEAS_MASK_SINK_I2S_CLK_RD(x) (((x) & (((1 << 1) - 1) << 5)) >> 5)
+#define F_MEAS_MASK_SINK_PCLK(x) (((x) & ((1 << 1) - 1)) << 6)
+#define F_MEAS_MASK_SINK_PCLK_RD(x) (((x) & (((1 << 1) - 1) << 6)) >> 6)
+#define F_MEAS_MASK_SINK_SCLK(x) (((x) & ((1 << 1) - 1)) << 7)
+#define F_MEAS_MASK_SINK_SCLK_RD(x) (((x) & (((1 << 1) - 1) << 7)) >> 7)
+#define F_MEAS_MASK_SINK_CCLK(x) (((x) & ((1 << 1) - 1)) << 8)
+#define F_MEAS_MASK_SINK_CCLK_RD(x) (((x) & (((1 << 1) - 1) << 8)) >> 8)
+#define F_MEAS_MASK_SINK_TRNG_CLK(x) (((x) & ((1 << 1) - 1)) << 9)
+#define F_MEAS_MASK_SINK_TRNG_CLK_RD(x) (((x) & (((1 << 1) - 1) << 9)) >> 9)
+
+/* register CLK_METER_INT_ST */
+#define CLK_METER_INT_ST 21
+#define F_MEAS_STATUS_SINK_REF_CLK(x) (((x) & ((1 << 1) - 1)) << 0)
+#define F_MEAS_STATUS_SINK_REF_CLK_RD(x) (((x) & (((1 << 1) - 1) << 0)) >> 0)
+#define F_MEAS_STATUS_SINK_PHY_CHAR_CLK(x) (((x) & ((1 << 1) - 1)) << 1)
+#define F_MEAS_STATUS_SINK_PHY_CHAR_CLK_RD(x) (((x) & (((1 << 1) - 1) << 1)) >> 1)
+#define F_MEAS_STATUS_SINK_PHY_DATA_CLK(x) (((x) & ((1 << 1) - 1)) << 2)
+#define F_MEAS_STATUS_SINK_PHY_DATA_CLK_RD(x) (((x) & (((1 << 1) - 1) << 2)) >> 2)
+#define F_MEAS_STATUS_SINK_PHY_PIXEL_CLK(x) (((x) & ((1 << 1) - 1)) << 3)
+#define F_MEAS_STATUS_SINK_PHY_PIXEL_CLK_RD(x) (((x) & (((1 << 1) - 1) << 3)) >> 3)
+#define F_MEAS_STATUS_SINK_SPDIF_MCLK(x) (((x) & ((1 << 1) - 1)) << 4)
+#define F_MEAS_STATUS_SINK_SPDIF_MCLK_RD(x) (((x) & (((1 << 1) - 1) << 4)) >> 4)
+#define F_MEAS_STATUS_SINK_I2S_CLK(x) (((x) & ((1 << 1) - 1)) << 5)
+#define F_MEAS_STATUS_SINK_I2S_CLK_RD(x) (((x) & (((1 << 1) - 1) << 5)) >> 5)
+#define F_MEAS_STATUS_SINK_PCLK(x) (((x) & ((1 << 1) - 1)) << 6)
+#define F_MEAS_STATUS_SINK_PCLK_RD(x) (((x) & (((1 << 1) - 1) << 6)) >> 6)
+#define F_MEAS_STATUS_SINK_SCLK(x) (((x) & ((1 << 1) - 1)) << 7)
+#define F_MEAS_STATUS_SINK_SCLK_RD(x) (((x) & (((1 << 1) - 1) << 7)) >> 7)
+#define F_MEAS_STATUS_SINK_CCLK(x) (((x) & ((1 << 1) - 1)) << 8)
+#define F_MEAS_STATUS_SINK_CCLK_RD(x) (((x) & (((1 << 1) - 1) << 8)) >> 8)
+#define F_MEAS_STATUS_SINK_TRNG_CLK(x) (((x) & ((1 << 1) - 1)) << 9)
+#define F_MEAS_STATUS_SINK_TRNG_CLK_RD(x) (((x) & (((1 << 1) - 1) << 9)) >> 9)
+
+#endif /* SINK_CLK_METERS */
+
diff --git a/drivers/mxc/hdp/sink_core.h b/drivers/mxc/hdp/sink_core.h
new file mode 100644
index 000000000000..ba63ca2af41a
--- /dev/null
+++ b/drivers/mxc/hdp/sink_core.h
@@ -0,0 +1,117 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2016-2017 Cadence Design Systems, Inc.
+ * All rights reserved worldwide.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 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.
+ *
+ * Copyright 2018 NXP
+ *
+ ******************************************************************************
+ *
+ * This file was auto-generated. Do not edit it manually.
+ *
+ ******************************************************************************
+ *
+ * sink_core.h
+ *
+ ******************************************************************************
+ */
+
+#ifndef SINK_CORE_H_
+#define SINK_CORE_H_
+
+/* register SCDC_INT_MSK */
+#define SCDC_INT_MSK 0
+#define F_SCDC_INT_MASK(x) (((x) & ((1 << 8) - 1)) << 0)
+#define F_SCDC_INT_MASK_RD(x) (((x) & (((1 << 8) - 1) << 0)) >> 0)
+
+/* register SCDC_INT_STS */
+#define SCDC_INT_STS 1
+#define F_SCDC_INT_STATUS(x) (((x) & ((1 << 8) - 1)) << 0)
+#define F_SCDC_INT_STATUS_RD(x) (((x) & (((1 << 8) - 1) << 0)) >> 0)
+
+/* register PHY_IF_LANE0_CFG */
+#define PHY_IF_LANE0_CFG 2
+#define F_SINK_PHY_DATA0_DATA_REVERSE(x) (((x) & ((1 << 1) - 1)) << 0)
+#define F_SINK_PHY_DATA0_DATA_REVERSE_RD(x) (((x) & (((1 << 1) - 1) << 0)) >> 0)
+#define F_SINK_PHY_DATA0_CHAR_REVERSE(x) (((x) & ((1 << 1) - 1)) << 1)
+#define F_SINK_PHY_DATA0_CHAR_REVERSE_RD(x) (((x) & (((1 << 1) - 1) << 1)) >> 1)
+#define F_SINK_PHY_CHAR0_SWAP(x) (((x) & ((1 << 1) - 1)) << 2)
+#define F_SINK_PHY_CHAR0_SWAP_RD(x) (((x) & (((1 << 1) - 1) << 2)) >> 2)
+#define F_SINK_PHY_LANE0(x) (((x) & ((1 << 2) - 1)) << 3)
+#define F_SINK_PHY_LANE0_RD(x) (((x) & (((1 << 2) - 1) << 3)) >> 3)
+
+/* register PHY_IF_LANE1_CFG */
+#define PHY_IF_LANE1_CFG 3
+#define F_SINK_PHY_DATA1_DATA_REVERSE(x) (((x) & ((1 << 1) - 1)) << 0)
+#define F_SINK_PHY_DATA1_DATA_REVERSE_RD(x) (((x) & (((1 << 1) - 1) << 0)) >> 0)
+#define F_SINK_PHY_DATA1_CHAR_REVERSE(x) (((x) & ((1 << 1) - 1)) << 1)
+#define F_SINK_PHY_DATA1_CHAR_REVERSE_RD(x) (((x) & (((1 << 1) - 1) << 1)) >> 1)
+#define F_SINK_PHY_CHAR1_SWAP(x) (((x) & ((1 << 1) - 1)) << 2)
+#define F_SINK_PHY_CHAR1_SWAP_RD(x) (((x) & (((1 << 1) - 1) << 2)) >> 2)
+#define F_SINK_PHY_LANE1(x) (((x) & ((1 << 2) - 1)) << 3)
+#define F_SINK_PHY_LANE1_RD(x) (((x) & (((1 << 2) - 1) << 3)) >> 3)
+
+/* register PHY_IF_LANE2_CFG */
+#define PHY_IF_LANE2_CFG 4
+#define F_SINK_PHY_DATA2_DATA_REVERSE(x) (((x) & ((1 << 1) - 1)) << 0)
+#define F_SINK_PHY_DATA2_DATA_REVERSE_RD(x) (((x) & (((1 << 1) - 1) << 0)) >> 0)
+#define F_SINK_PHY_DATA2_CHAR_REVERSE(x) (((x) & ((1 << 1) - 1)) << 1)
+#define F_SINK_PHY_DATA2_CHAR_REVERSE_RD(x) (((x) & (((1 << 1) - 1) << 1)) >> 1)
+#define F_SINK_PHY_CHAR2_SWAP(x) (((x) & ((1 << 1) - 1)) << 2)
+#define F_SINK_PHY_CHAR2_SWAP_RD(x) (((x) & (((1 << 1) - 1) << 2)) >> 2)
+#define F_SINK_PHY_LANE2(x) (((x) & ((1 << 2) - 1)) << 3)
+#define F_SINK_PHY_LANE2_RD(x) (((x) & (((1 << 2) - 1) << 3)) >> 3)
+
+/* register TOP_ST */
+#define TOP_ST 5
+#define F_SINK_5V(x) (((x) & ((1 << 1) - 1)) << 0)
+#define F_SINK_5V_RD(x) (((x) & (((1 << 1) - 1) << 0)) >> 0)
+
+/* register TOP_CFG */
+#define TOP_CFG 6
+#define F_SINK_HPD(x) (((x) & ((1 << 1) - 1)) << 0)
+#define F_SINK_HPD_RD(x) (((x) & (((1 << 1) - 1) << 0)) >> 0)
+
+/* register SCDC_FILTER_CFG */
+#define SCDC_FILTER_CFG 7
+#define F_SCDC_FILTER_BYPASS(x) (((x) & ((1 << 1) - 1)) << 0)
+#define F_SCDC_FILTER_BYPASS_RD(x) (((x) & (((1 << 1) - 1) << 0)) >> 0)
+#define F_SCDC_FILTER_VALID_WIDTH(x) (((x) & ((1 << 12) - 1)) << 1)
+#define F_SCDC_FILTER_VALID_WIDTH_RD(x) (((x) & (((1 << 12) - 1) << 1)) >> 1)
+#define F_SCDC_FILTER_GLITCH_WIDTH(x) (((x) & ((1 << 8) - 1)) << 13)
+#define F_SCDC_FILTER_GLITCH_WIDTH_RD(x) (((x) & (((1 << 8) - 1) << 13)) >> 13)
+
+#endif /* SINK_CORE */
+
diff --git a/drivers/mxc/hdp/sink_mhl_hd.h b/drivers/mxc/hdp/sink_mhl_hd.h
new file mode 100644
index 000000000000..be03200e9d96
--- /dev/null
+++ b/drivers/mxc/hdp/sink_mhl_hd.h
@@ -0,0 +1,418 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2016-2017 Cadence Design Systems, Inc.
+ * All rights reserved worldwide.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 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.
+ *
+ * Copyright 2018 NXP
+ *
+ ******************************************************************************
+ *
+ * This file was auto-generated. Do not edit it manually.
+ *
+ ******************************************************************************
+ *
+ * sink_mhl_hd.h
+ *
+ ******************************************************************************
+ */
+
+#ifndef SINK_MHL_HD_H_
+#define SINK_MHL_HD_H_
+
+/* register TMDS_ALIGN_CTRL */
+#define TMDS_ALIGN_CTRL 0
+#define F_CHAR_MATCH_CNT_THR(x) (((x) & ((1 << 4) - 1)) << 0)
+#define F_CHAR_MATCH_CNT_THR_RD(x) (((x) & (((1 << 4) - 1) << 0)) >> 0)
+#define F_CHAR_HAM_DIS_TOL(x) (((x) & ((1 << 4) - 1)) << 4)
+#define F_CHAR_HAM_DIS_TOL_RD(x) (((x) & (((1 << 4) - 1) << 4)) >> 4)
+#define F_LOCK_ALIGN(x) (((x) & ((1 << 1) - 1)) << 8)
+#define F_LOCK_ALIGN_RD(x) (((x) & (((1 << 1) - 1) << 8)) >> 8)
+#define F_ALIGN_WD_THR(x) (((x) & ((1 << 3) - 1)) << 9)
+#define F_ALIGN_WD_THR_RD(x) (((x) & (((1 << 3) - 1) << 9)) >> 9)
+#define F_ALIGN_ANY_CHAR(x) (((x) & ((1 << 1) - 1)) << 12)
+#define F_ALIGN_ANY_CHAR_RD(x) (((x) & (((1 << 1) - 1) << 12)) >> 12)
+
+/* register TMDS_DEC_CTRL */
+#define TMDS_DEC_CTRL 1
+#define F_DECODER_ERR_CORR_EN(x) (((x) & ((1 << 1) - 1)) << 0)
+#define F_DECODER_ERR_CORR_EN_RD(x) (((x) & (((1 << 1) - 1) << 0)) >> 0)
+#define F_TMDS_DECODER_SW_RST(x) (((x) & ((1 << 1) - 1)) << 1)
+#define F_TMDS_DECODER_SW_RST_RD(x) (((x) & (((1 << 1) - 1) << 1)) >> 1)
+#define F_TMDS_FORCE_HDMI_MODE(x) (((x) & ((1 << 1) - 1)) << 2)
+#define F_TMDS_FORCE_HDMI_MODE_RD(x) (((x) & (((1 << 1) - 1) << 2)) >> 2)
+#define F_TMDS_SW_HDMI_MODE(x) (((x) & ((1 << 1) - 1)) << 3)
+#define F_TMDS_SW_HDMI_MODE_RD(x) (((x) & (((1 << 1) - 1) << 3)) >> 3)
+
+/* register TMDS_DEC_ST */
+#define TMDS_DEC_ST 2
+#define F_DEFRAMER_HDMI_MODE(x) (((x) & ((1 << 1) - 1)) << 0)
+#define F_DEFRAMER_HDMI_MODE_RD(x) (((x) & (((1 << 1) - 1) << 0)) >> 0)
+#define F_CHAR_HAM_ERR(x) (((x) & ((1 << 3) - 1)) << 2)
+#define F_CHAR_HAM_ERR_RD(x) (((x) & (((1 << 3) - 1) << 2)) >> 2)
+#define F_CHAR_ALIGNED(x) (((x) & ((1 << 3) - 1)) << 5)
+#define F_CHAR_ALIGNED_RD(x) (((x) & (((1 << 3) - 1) << 5)) >> 5)
+#define F_CTRL_ALIGN_ERR(x) (((x) & ((1 << 1) - 1)) << 8)
+#define F_CTRL_ALIGN_ERR_RD(x) (((x) & (((1 << 1) - 1) << 8)) >> 8)
+#define F_CTRL_ALIGNED(x) (((x) & ((1 << 1) - 1)) << 9)
+#define F_CTRL_ALIGNED_RD(x) (((x) & (((1 << 1) - 1) << 9)) >> 9)
+#define F_TMDS_CHAR_CH0_WIN(x) (((x) & ((1 << 4) - 1)) << 10)
+#define F_TMDS_CHAR_CH0_WIN_RD(x) (((x) & (((1 << 4) - 1) << 10)) >> 10)
+#define F_TMDS_CHAR_CH1_WIN(x) (((x) & ((1 << 4) - 1)) << 14)
+#define F_TMDS_CHAR_CH1_WIN_RD(x) (((x) & (((1 << 4) - 1) << 14)) >> 14)
+#define F_TMDS_CHAR_CH2_WIN(x) (((x) & ((1 << 4) - 1)) << 18)
+#define F_TMDS_CHAR_CH2_WIN_RD(x) (((x) & (((1 << 4) - 1) << 18)) >> 18)
+
+/* register TMDS_CH0_ERR_CNT */
+#define TMDS_CH0_ERR_CNT 3
+#define F_DEFRAMER_CH0_ERROR_CNT(x) (((x) & ((1 << 16) - 1)) << 0)
+#define F_DEFRAMER_CH0_ERROR_CNT_RD(x) (((x) & (((1 << 16) - 1) << 0)) >> 0)
+
+/* register TMDS_CH1_ERR_CNT */
+#define TMDS_CH1_ERR_CNT 4
+#define F_DEFRAMER_CH1_ERROR_CNT(x) (((x) & ((1 << 16) - 1)) << 0)
+#define F_DEFRAMER_CH1_ERROR_CNT_RD(x) (((x) & (((1 << 16) - 1) << 0)) >> 0)
+
+/* register TMDS_CH2_ERR_CNT */
+#define TMDS_CH2_ERR_CNT 5
+#define F_DEFRAMER_CH2_ERROR_CNT(x) (((x) & ((1 << 16) - 1)) << 0)
+#define F_DEFRAMER_CH2_ERROR_CNT_RD(x) (((x) & (((1 << 16) - 1) << 0)) >> 0)
+
+/* register HDCP_FIFO_STAT */
+#define HDCP_FIFO_STAT 6
+#define F_HDCP_DOUBLE_FIFO_REMPTY(x) (((x) & ((1 << 1) - 1)) << 0)
+#define F_HDCP_DOUBLE_FIFO_REMPTY_RD(x) (((x) & (((1 << 1) - 1) << 0)) >> 0)
+#define F_HDCP_DOUBLE_FIFO_WFULL(x) (((x) & ((1 << 1) - 1)) << 1)
+#define F_HDCP_DOUBLE_FIFO_WFULL_RD(x) (((x) & (((1 << 1) - 1) << 1)) >> 1)
+#define F_HDCP_DOUBLE_FIFO_UNDERRUN(x) (((x) & ((1 << 1) - 1)) << 2)
+#define F_HDCP_DOUBLE_FIFO_UNDERRUN_RD(x) (((x) & (((1 << 1) - 1) << 2)) >> 2)
+#define F_HDCP_DOUBLE_FIFO_OVERRUN(x) (((x) & ((1 << 1) - 1)) << 3)
+#define F_HDCP_DOUBLE_FIFO_OVERRUN_RD(x) (((x) & (((1 << 1) - 1) << 3)) >> 3)
+#define F_HDCP22_DATA_FIFO_UNDERRUN(x) (((x) & ((1 << 1) - 1)) << 4)
+#define F_HDCP22_DATA_FIFO_UNDERRUN_RD(x) (((x) & (((1 << 1) - 1) << 4)) >> 4)
+#define F_HDCP22_DATA_FIFO_OVERRUN(x) (((x) & ((1 << 1) - 1)) << 5)
+#define F_HDCP22_DATA_FIFO_OVERRUN_RD(x) (((x) & (((1 << 1) - 1) << 5)) >> 5)
+#define F_HDCP22_DATA_FIFO_REMPTY(x) (((x) & ((1 << 1) - 1)) << 6)
+#define F_HDCP22_DATA_FIFO_REMPTY_RD(x) (((x) & (((1 << 1) - 1) << 6)) >> 6)
+#define F_HDCP22_DATA_FIFO_WFULL(x) (((x) & ((1 << 1) - 1)) << 7)
+#define F_HDCP22_DATA_FIFO_WFULL_RD(x) (((x) & (((1 << 1) - 1) << 7)) >> 7)
+#define F_HDCP_DELAY_FIFO_EMPTY(x) (((x) & ((1 << 1) - 1)) << 8)
+#define F_HDCP_DELAY_FIFO_EMPTY_RD(x) (((x) & (((1 << 1) - 1) << 8)) >> 8)
+#define F_HDCP_DELAY_FIFO_FULL(x) (((x) & ((1 << 1) - 1)) << 9)
+#define F_HDCP_DELAY_FIFO_FULL_RD(x) (((x) & (((1 << 1) - 1) << 9)) >> 9)
+#define F_HDCP14_DATA_FIFO_UNDERRUN(x) (((x) & ((1 << 2) - 1)) << 10)
+#define F_HDCP14_DATA_FIFO_UNDERRUN_RD(x) (((x) & (((1 << 2) - 1) << 10)) >> 10)
+#define F_HDCP14_DATA_FIFO_OVERRUN(x) (((x) & ((1 << 2) - 1)) << 12)
+#define F_HDCP14_DATA_FIFO_OVERRUN_RD(x) (((x) & (((1 << 2) - 1) << 12)) >> 12)
+#define F_HDCP14_DATA_FIFO_REMPTY(x) (((x) & ((1 << 2) - 1)) << 14)
+#define F_HDCP14_DATA_FIFO_REMPTY_RD(x) (((x) & (((1 << 2) - 1) << 14)) >> 14)
+#define F_HDCP14_DATA_FIFO_WFULL(x) (((x) & ((1 << 2) - 1)) << 16)
+#define F_HDCP14_DATA_FIFO_WFULL_RD(x) (((x) & (((1 << 2) - 1) << 16)) >> 16)
+
+/* register HDCP_DELAY_FIFO_CTRL */
+#define HDCP_DELAY_FIFO_CTRL 7
+#define F_HDCP_DELAY_FIFO_AFULL_THR(x) (((x) & ((1 << 4) - 1)) << 0)
+#define F_HDCP_DELAY_FIFO_AFULL_THR_RD(x) (((x) & (((1 << 4) - 1) << 0)) >> 0)
+#define F_HDCP_DELAY_FIFO_SW_RST(x) (((x) & ((1 << 1) - 1)) << 4)
+#define F_HDCP_DELAY_FIFO_SW_RST_RD(x) (((x) & (((1 << 1) - 1) << 4)) >> 4)
+#define F_HDCP_DOUBLE_FIFO_SW_RST(x) (((x) & ((1 << 1) - 1)) << 5)
+#define F_HDCP_DOUBLE_FIFO_SW_RST_RD(x) (((x) & (((1 << 1) - 1) << 5)) >> 5)
+#define F_HDCP14_DATA_FIFO_SW_RST(x) (((x) & ((1 << 1) - 1)) << 6)
+#define F_HDCP14_DATA_FIFO_SW_RST_RD(x) (((x) & (((1 << 1) - 1) << 6)) >> 6)
+#define F_HDCP_CTRL_SW_RST(x) (((x) & ((1 << 1) - 1)) << 7)
+#define F_HDCP_CTRL_SW_RST_RD(x) (((x) & (((1 << 1) - 1) << 7)) >> 7)
+
+/* register HDCP_CTRL */
+#define HDCP_CTRL 8
+#define F_HDCP_ENABLE_1P1_FEATURES(x) (((x) & ((1 << 1) - 1)) << 0)
+#define F_HDCP_ENABLE_1P1_FEATURES_RD(x) (((x) & (((1 << 1) - 1) << 0)) >> 0)
+#define F_HDCP_SELECT(x) (((x) & ((1 << 2) - 1)) << 1)
+#define F_HDCP_SELECT_RD(x) (((x) & (((1 << 2) - 1) << 1)) >> 1)
+#define F_FORCE_VSYNC_POLARITY(x) (((x) & ((1 << 1) - 1)) << 3)
+#define F_FORCE_VSYNC_POLARITY_RD(x) (((x) & (((1 << 1) - 1) << 3)) >> 3)
+#define F_FORCE_HSYNC_POLARITY(x) (((x) & ((1 << 1) - 1)) << 4)
+#define F_FORCE_HSYNC_POLARITY_RD(x) (((x) & (((1 << 1) - 1) << 4)) >> 4)
+#define F_SW_VSYNC_POLARITY(x) (((x) & ((1 << 1) - 1)) << 5)
+#define F_SW_VSYNC_POLARITY_RD(x) (((x) & (((1 << 1) - 1) << 5)) >> 5)
+#define F_SW_HSYNC_POLARITY(x) (((x) & ((1 << 1) - 1)) << 6)
+#define F_SW_HSYNC_POLARITY_RD(x) (((x) & (((1 << 1) - 1) << 6)) >> 6)
+
+/* register HDCP_STAT */
+#define HDCP_STAT 9
+#define F_HDCP_ESS_STATE(x) (((x) & ((1 << 4) - 1)) << 0)
+#define F_HDCP_ESS_STATE_RD(x) (((x) & (((1 << 4) - 1) << 0)) >> 0)
+#define F_SINK_HD_CIPHER_HSYNC_POLARITY(x) (((x) & ((1 << 1) - 1)) << 4)
+#define F_SINK_HD_CIPHER_HSYNC_POLARITY_RD(x) (((x) & (((1 << 1) - 1) << 4)) >> 4)
+#define F_SINK_HD_CIPHER_VSYNC_POLARITY(x) (((x) & ((1 << 1) - 1)) << 5)
+#define F_SINK_HD_CIPHER_VSYNC_POLARITY_RD(x) (((x) & (((1 << 1) - 1) << 5)) >> 5)
+
+/* register PKT_CTRL */
+#define PKT_CTRL 10
+#define F_SINK_AVMUTE_SET(x) (((x) & ((1 << 1) - 1)) << 0)
+#define F_SINK_AVMUTE_SET_RD(x) (((x) & (((1 << 1) - 1) << 0)) >> 0)
+#define F_SINK_AVMUTE_CLR(x) (((x) & ((1 << 1) - 1)) << 1)
+#define F_SINK_AVMUTE_CLR_RD(x) (((x) & (((1 << 1) - 1) << 1)) >> 1)
+#define F_ERR_CORR_EN(x) (((x) & ((1 << 1) - 1)) << 2)
+#define F_ERR_CORR_EN_RD(x) (((x) & (((1 << 1) - 1) << 2)) >> 2)
+
+/* register PKT_STAT_0 */
+#define PKT_STAT_0 11
+#define F_SINK_AVMUTE(x) (((x) & ((1 << 1) - 1)) << 0)
+#define F_SINK_AVMUTE_RD(x) (((x) & (((1 << 1) - 1) << 0)) >> 0)
+#define F_SINK_ACR_CTS(x) (((x) & ((1 << 20) - 1)) << 1)
+#define F_SINK_ACR_CTS_RD(x) (((x) & (((1 << 20) - 1) << 1)) >> 1)
+#define F_PKT_DEC_GCP_CD(x) (((x) & ((1 << 4) - 1)) << 21)
+#define F_PKT_DEC_GCP_CD_RD(x) (((x) & (((1 << 4) - 1) << 21)) >> 21)
+#define F_PKT_DEC_GCP_PP(x) (((x) & ((1 << 4) - 1)) << 25)
+#define F_PKT_DEC_GCP_PP_RD(x) (((x) & (((1 << 4) - 1) << 25)) >> 25)
+
+/* register PKT_STAT_1 */
+#define PKT_STAT_1 12
+#define F_SINK_ACR_N(x) (((x) & ((1 << 20) - 1)) << 0)
+#define F_SINK_ACR_N_RD(x) (((x) & (((1 << 20) - 1) << 0)) >> 0)
+
+/* register PKT_ERR_CNT_HEADER */
+#define PKT_ERR_CNT_HEADER 13
+#define F_PKT_HEADER_ERR_CNT(x) (((x) & ((1 << 8) - 1)) << 0)
+#define F_PKT_HEADER_ERR_CNT_RD(x) (((x) & (((1 << 8) - 1) << 0)) >> 0)
+#define F_PKT_HEADER_CORR_ERR_CNT(x) (((x) & ((1 << 8) - 1)) << 8)
+#define F_PKT_HEADER_CORR_ERR_CNT_RD(x) (((x) & (((1 << 8) - 1) << 8)) >> 8)
+
+/* register PKT_ERR_CNT_01 */
+#define PKT_ERR_CNT_01 14
+#define F_PKT_SUBPKT0_ERR_CNT(x) (((x) & ((1 << 8) - 1)) << 0)
+#define F_PKT_SUBPKT0_ERR_CNT_RD(x) (((x) & (((1 << 8) - 1) << 0)) >> 0)
+#define F_PKT_SUBPKT0_CORR_ERR_CNT(x) (((x) & ((1 << 8) - 1)) << 8)
+#define F_PKT_SUBPKT0_CORR_ERR_CNT_RD(x) (((x) & (((1 << 8) - 1) << 8)) >> 8)
+#define F_PKT_SUBPKT1_ERR_CNT(x) (((x) & ((1 << 8) - 1)) << 16)
+#define F_PKT_SUBPKT1_ERR_CNT_RD(x) (((x) & (((1 << 8) - 1) << 16)) >> 16)
+#define F_PKT_SUBPKT1_CORR_ERR_CNT(x) (((x) & ((1 << 8) - 1)) << 24)
+#define F_PKT_SUBPKT1_CORR_ERR_CNT_RD(x) (((x) & (((1 << 8) - 1) << 24)) >> 24)
+
+/* register PKT_ERR_CNT_23 */
+#define PKT_ERR_CNT_23 15
+#define F_PKT_SUBPKT2_ERR_CNT(x) (((x) & ((1 << 8) - 1)) << 0)
+#define F_PKT_SUBPKT2_ERR_CNT_RD(x) (((x) & (((1 << 8) - 1) << 0)) >> 0)
+#define F_PKT_SUBPKT2_CORR_ERR_CNT(x) (((x) & ((1 << 8) - 1)) << 8)
+#define F_PKT_SUBPKT2_CORR_ERR_CNT_RD(x) (((x) & (((1 << 8) - 1) << 8)) >> 8)
+#define F_PKT_SUBPKT3_ERR_CNT(x) (((x) & ((1 << 8) - 1)) << 16)
+#define F_PKT_SUBPKT3_ERR_CNT_RD(x) (((x) & (((1 << 8) - 1) << 16)) >> 16)
+#define F_PKT_SUBPKT3_CORR_ERR_CNT(x) (((x) & ((1 << 8) - 1)) << 24)
+#define F_PKT_SUBPKT3_CORR_ERR_CNT_RD(x) (((x) & (((1 << 8) - 1) << 24)) >> 24)
+
+/* register TMDS_SCR_CTRL */
+#define TMDS_SCR_CTRL 16
+#define F_SCRAMBLER_MODE(x) (((x) & ((1 << 1) - 1)) << 0)
+#define F_SCRAMBLER_MODE_RD(x) (((x) & (((1 << 1) - 1) << 0)) >> 0)
+#define F_SCRAMBLER_SW_EN(x) (((x) & ((1 << 1) - 1)) << 1)
+#define F_SCRAMBLER_SW_EN_RD(x) (((x) & (((1 << 1) - 1) << 1)) >> 1)
+#define F_SCRAMBLER_CTRL_SW_RST(x) (((x) & ((1 << 1) - 1)) << 2)
+#define F_SCRAMBLER_CTRL_SW_RST_RD(x) (((x) & (((1 << 1) - 1) << 2)) >> 2)
+
+/* register TMDS_SCR_CNT_INT_CTRL */
+#define TMDS_SCR_CNT_INT_CTRL 17
+#define F_SCRAMBLER_SSCP_LINE_DET_THR(x) (((x) & ((1 << 8) - 1)) << 0)
+#define F_SCRAMBLER_SSCP_LINE_DET_THR_RD(x) (((x) & (((1 << 8) - 1) << 0)) >> 0)
+#define F_SCRAMBLER_CTRL_LINE_DET_THR(x) (((x) & ((1 << 24) - 1)) << 8)
+#define F_SCRAMBLER_CTRL_LINE_DET_THR_RD(x) (((x) & (((1 << 24) - 1) << 8)) >> 8)
+
+/* register TMDS_SCR_VALID_CTRL */
+#define TMDS_SCR_VALID_CTRL 18
+#define F_SCRAMBLER_SSCP_LINE_VALID_THR(x) (((x) & ((1 << 8) - 1)) << 0)
+#define F_SCRAMBLER_SSCP_LINE_VALID_THR_RD(x) (((x) & (((1 << 8) - 1) << 0)) >> 0)
+#define F_SCRAMBLER_CTRL_LINE_VALID_THR(x) (((x) & ((1 << 24) - 1)) << 8)
+#define F_SCRAMBLER_CTRL_LINE_VALID_THR_RD(x) (((x) & (((1 << 24) - 1) << 8)) >> 8)
+
+/* register TMDS_SCR_CNT_INT_ST */
+#define TMDS_SCR_CNT_INT_ST 19
+#define F_SCRAMBLER_SSCP_LINE_CNT(x) (((x) & ((1 << 8) - 1)) << 0)
+#define F_SCRAMBLER_SSCP_LINE_CNT_RD(x) (((x) & (((1 << 8) - 1) << 0)) >> 0)
+#define F_SCRAMBLER_CTRL_LINE_CNT(x) (((x) & ((1 << 24) - 1)) << 8)
+#define F_SCRAMBLER_CTRL_LINE_CNT_RD(x) (((x) & (((1 << 24) - 1) << 8)) >> 8)
+
+/* register TMDS_MHL_HD_INT_MASK */
+#define TMDS_MHL_HD_INT_MASK 20
+#define F_TMDS_MHL_HD_MASK(x) (((x) & ((1 << 9) - 1)) << 0)
+#define F_TMDS_MHL_HD_MASK_RD(x) (((x) & (((1 << 9) - 1) << 0)) >> 0)
+
+/* register TMDS_MHL_HD_INT_STAT */
+#define TMDS_MHL_HD_INT_STAT 21
+#define F_TMDS_MHL_HD_STATUS(x) (((x) & ((1 << 9) - 1)) << 0)
+#define F_TMDS_MHL_HD_STATUS_RD(x) (((x) & (((1 << 9) - 1) << 0)) >> 0)
+
+/* register TMDS_STAT_CNT0_CTRL */
+#define TMDS_STAT_CNT0_CTRL 22
+#define F_STATUS_CNT0_INC_SEL(x) (((x) & ((1 << 4) - 1)) << 0)
+#define F_STATUS_CNT0_INC_SEL_RD(x) (((x) & (((1 << 4) - 1) << 0)) >> 0)
+#define F_STATUS_CNT0_DEC_SEL(x) (((x) & ((1 << 4) - 1)) << 4)
+#define F_STATUS_CNT0_DEC_SEL_RD(x) (((x) & (((1 << 4) - 1) << 4)) >> 4)
+#define F_STATUS_CNT0_CLR_SEL(x) (((x) & ((1 << 4) - 1)) << 8)
+#define F_STATUS_CNT0_CLR_SEL_RD(x) (((x) & (((1 << 4) - 1) << 8)) >> 8)
+#define F_STATUS_CNT0_START_SEL(x) (((x) & ((1 << 4) - 1)) << 12)
+#define F_STATUS_CNT0_START_SEL_RD(x) (((x) & (((1 << 4) - 1) << 12)) >> 12)
+#define F_STATUS_CNT0_STOP_SEL(x) (((x) & ((1 << 4) - 1)) << 16)
+#define F_STATUS_CNT0_STOP_SEL_RD(x) (((x) & (((1 << 4) - 1) << 16)) >> 16)
+
+/* register TMDS_STAT_CNT0_THR */
+#define TMDS_STAT_CNT0_THR 23
+#define F_STATUS_CNT0_THR(x) (((x) & ((1 << 32) - 1)) << 0)
+#define F_STATUS_CNT0_THR_RD(x) (((x) & (((1 << 32) - 1) << 0)) >> 0)
+
+/* register TMDS_STAT_CNT0_VAL */
+#define TMDS_STAT_CNT0_VAL 24
+#define F_STATUS_CNT0_VAL(x) (((x) & ((1 << 32) - 1)) << 0)
+#define F_STATUS_CNT0_VAL_RD(x) (((x) & (((1 << 32) - 1) << 0)) >> 0)
+
+/* register TMDS_STAT_CNT1_CTRL */
+#define TMDS_STAT_CNT1_CTRL 25
+#define F_STATUS_CNT1_INC_SEL(x) (((x) & ((1 << 4) - 1)) << 0)
+#define F_STATUS_CNT1_INC_SEL_RD(x) (((x) & (((1 << 4) - 1) << 0)) >> 0)
+#define F_STATUS_CNT1_DEC_SEL(x) (((x) & ((1 << 4) - 1)) << 4)
+#define F_STATUS_CNT1_DEC_SEL_RD(x) (((x) & (((1 << 4) - 1) << 4)) >> 4)
+#define F_STATUS_CNT1_CLR_SEL(x) (((x) & ((1 << 4) - 1)) << 8)
+#define F_STATUS_CNT1_CLR_SEL_RD(x) (((x) & (((1 << 4) - 1) << 8)) >> 8)
+#define F_STATUS_CNT1_START_SEL(x) (((x) & ((1 << 4) - 1)) << 12)
+#define F_STATUS_CNT1_START_SEL_RD(x) (((x) & (((1 << 4) - 1) << 12)) >> 12)
+#define F_STATUS_CNT1_STOP_SEL(x) (((x) & ((1 << 4) - 1)) << 16)
+#define F_STATUS_CNT1_STOP_SEL_RD(x) (((x) & (((1 << 4) - 1) << 16)) >> 16)
+
+/* register TMDS_STAT_CNT1_THR */
+#define TMDS_STAT_CNT1_THR 26
+#define F_STATUS_CNT1_THR(x) (((x) & ((1 << 32) - 1)) << 0)
+#define F_STATUS_CNT1_THR_RD(x) (((x) & (((1 << 32) - 1) << 0)) >> 0)
+
+/* register TMDS_STAT_CNT1_VAL */
+#define TMDS_STAT_CNT1_VAL 27
+#define F_STATUS_CNT1_VAL(x) (((x) & ((1 << 32) - 1)) << 0)
+#define F_STATUS_CNT1_VAL_RD(x) (((x) & (((1 << 32) - 1) << 0)) >> 0)
+
+/* register TMDS_STAT_CNT2_CTRL */
+#define TMDS_STAT_CNT2_CTRL 28
+#define F_STATUS_CNT2_INC_SEL(x) (((x) & ((1 << 4) - 1)) << 0)
+#define F_STATUS_CNT2_INC_SEL_RD(x) (((x) & (((1 << 4) - 1) << 0)) >> 0)
+#define F_STATUS_CNT2_DEC_SEL(x) (((x) & ((1 << 4) - 1)) << 4)
+#define F_STATUS_CNT2_DEC_SEL_RD(x) (((x) & (((1 << 4) - 1) << 4)) >> 4)
+#define F_STATUS_CNT2_CLR_SEL(x) (((x) & ((1 << 4) - 1)) << 8)
+#define F_STATUS_CNT2_CLR_SEL_RD(x) (((x) & (((1 << 4) - 1) << 8)) >> 8)
+#define F_STATUS_CNT2_START_SEL(x) (((x) & ((1 << 4) - 1)) << 12)
+#define F_STATUS_CNT2_START_SEL_RD(x) (((x) & (((1 << 4) - 1) << 12)) >> 12)
+#define F_STATUS_CNT2_STOP_SEL(x) (((x) & ((1 << 4) - 1)) << 16)
+#define F_STATUS_CNT2_STOP_SEL_RD(x) (((x) & (((1 << 4) - 1) << 16)) >> 16)
+
+/* register TMDS_STAT_CNT2_THR */
+#define TMDS_STAT_CNT2_THR 29
+#define F_STATUS_CNT2_THR(x) (((x) & ((1 << 32) - 1)) << 0)
+#define F_STATUS_CNT2_THR_RD(x) (((x) & (((1 << 32) - 1) << 0)) >> 0)
+
+/* register TMDS_STAT_CNT2_VAL */
+#define TMDS_STAT_CNT2_VAL 30
+#define F_STATUS_CNT2_VAL(x) (((x) & ((1 << 32) - 1)) << 0)
+#define F_STATUS_CNT2_VAL_RD(x) (((x) & (((1 << 32) - 1) << 0)) >> 0)
+
+/* register TMDS_STAT_CNT3_CTRL */
+#define TMDS_STAT_CNT3_CTRL 31
+#define F_STATUS_CNT3_INC_SEL(x) (((x) & ((1 << 4) - 1)) << 0)
+#define F_STATUS_CNT3_INC_SEL_RD(x) (((x) & (((1 << 4) - 1) << 0)) >> 0)
+#define F_STATUS_CNT3_DEC_SEL(x) (((x) & ((1 << 4) - 1)) << 4)
+#define F_STATUS_CNT3_DEC_SEL_RD(x) (((x) & (((1 << 4) - 1) << 4)) >> 4)
+#define F_STATUS_CNT3_CLR_SEL(x) (((x) & ((1 << 4) - 1)) << 8)
+#define F_STATUS_CNT3_CLR_SEL_RD(x) (((x) & (((1 << 4) - 1) << 8)) >> 8)
+#define F_STATUS_CNT3_START_SEL(x) (((x) & ((1 << 4) - 1)) << 12)
+#define F_STATUS_CNT3_START_SEL_RD(x) (((x) & (((1 << 4) - 1) << 12)) >> 12)
+#define F_STATUS_CNT3_STOP_SEL(x) (((x) & ((1 << 4) - 1)) << 16)
+#define F_STATUS_CNT3_STOP_SEL_RD(x) (((x) & (((1 << 4) - 1) << 16)) >> 16)
+
+/* register TMDS_STAT_CNT3_THR */
+#define TMDS_STAT_CNT3_THR 32
+#define F_STATUS_CNT3_THR(x) (((x) & ((1 << 32) - 1)) << 0)
+#define F_STATUS_CNT3_THR_RD(x) (((x) & (((1 << 32) - 1) << 0)) >> 0)
+
+/* register TMDS_STAT_CNT3_VAL */
+#define TMDS_STAT_CNT3_VAL 33
+#define F_STATUS_CNT3_VAL(x) (((x) & ((1 << 32) - 1)) << 0)
+#define F_STATUS_CNT3_VAL_RD(x) (((x) & (((1 << 32) - 1) << 0)) >> 0)
+
+/* register TMDS_POLARITY_STAT */
+#define TMDS_POLARITY_STAT 34
+#define F_TMDS_HSYNC_POLARITY(x) (((x) & ((1 << 1) - 1)) << 0)
+#define F_TMDS_HSYNC_POLARITY_RD(x) (((x) & (((1 << 1) - 1) << 0)) >> 0)
+#define F_TMDS_VSYNC_POLARITY(x) (((x) & ((1 << 1) - 1)) << 1)
+#define F_TMDS_VSYNC_POLARITY_RD(x) (((x) & (((1 << 1) - 1) << 1)) >> 1)
+
+/* register TMDS_MHL_HD_ERR_INT_MASK */
+#define TMDS_MHL_HD_ERR_INT_MASK 35
+#define F_TMDS_MHL_HD_ERR_MASK(x) (((x) & ((1 << 8) - 1)) << 0)
+#define F_TMDS_MHL_HD_ERR_MASK_RD(x) (((x) & (((1 << 8) - 1) << 0)) >> 0)
+
+/* register TMDS_MHL_HD_ERR_INT_STAT */
+#define TMDS_MHL_HD_ERR_INT_STAT 36
+#define F_TMDS_MHL_HD_ERR_STATUS(x) (((x) & ((1 << 8) - 1)) << 0)
+#define F_TMDS_MHL_HD_ERR_STATUS_RD(x) (((x) & (((1 << 8) - 1) << 0)) >> 0)
+
+/* register MHL_HD_INT_MASK */
+#define MHL_HD_INT_MASK 37
+#define F_MHL_HD_INT_MASK(x) (((x) & ((1 << 4) - 1)) << 0)
+#define F_MHL_HD_INT_MASK_RD(x) (((x) & (((1 << 4) - 1) << 0)) >> 0)
+
+/* register MHL_HD_INT_STAT */
+#define MHL_HD_INT_STAT 38
+#define F_MHL_HD_INT_STATUS(x) (((x) & ((1 << 4) - 1)) << 0)
+#define F_MHL_HD_INT_STATUS_RD(x) (((x) & (((1 << 4) - 1) << 0)) >> 0)
+
+/* register PKT_ACR_CTS_CTRL */
+#define PKT_ACR_CTS_CTRL 39
+#define F_SW_FORCE_ACR_CTS(x) (((x) & ((1 << 1) - 1)) << 0)
+#define F_SW_FORCE_ACR_CTS_RD(x) (((x) & (((1 << 1) - 1) << 0)) >> 0)
+#define F_PKT_DEC_ACR_CTS(x) (((x) & ((1 << 20) - 1)) << 1)
+#define F_PKT_DEC_ACR_CTS_RD(x) (((x) & (((1 << 20) - 1) << 1)) >> 1)
+
+/* register PKT_ACR_N_CTRL */
+#define PKT_ACR_N_CTRL 40
+#define F_SW_FORCE_ACR_N(x) (((x) & ((1 << 1) - 1)) << 0)
+#define F_SW_FORCE_ACR_N_RD(x) (((x) & (((1 << 1) - 1) << 0)) >> 0)
+#define F_PKT_DEC_ACR_N(x) (((x) & ((1 << 20) - 1)) << 1)
+#define F_PKT_DEC_ACR_N_RD(x) (((x) & (((1 << 20) - 1) << 1)) >> 1)
+
+/* register PKT_AVI_DATA_LOW */
+#define PKT_AVI_DATA_LOW 41
+#define F_PKT_DEC_AVI_DATA_LOW(x) (((x) & ((1 << 32) - 1)) << 0)
+#define F_PKT_DEC_AVI_DATA_LOW_RD(x) (((x) & (((1 << 32) - 1) << 0)) >> 0)
+
+/* register PKT_AVI_DATA_HIGH */
+#define PKT_AVI_DATA_HIGH 42
+#define F_PKT_DEC_AVI_DATA_HIGH(x) (((x) & ((1 << 8) - 1)) << 0)
+#define F_PKT_DEC_AVI_DATA_HIGH_RD(x) (((x) & (((1 << 8) - 1) << 0)) >> 0)
+
+#endif /* SINK_MHL_HD */
+
diff --git a/drivers/mxc/hdp/sink_pif.h b/drivers/mxc/hdp/sink_pif.h
new file mode 100644
index 000000000000..bd0944fbb27f
--- /dev/null
+++ b/drivers/mxc/hdp/sink_pif.h
@@ -0,0 +1,160 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2016-2017 Cadence Design Systems, Inc.
+ * All rights reserved worldwide.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 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.
+ *
+ * Copyright 2018 NXP
+ *
+ ******************************************************************************
+ *
+ * This file was auto-generated. Do not edit it manually.
+ *
+ ******************************************************************************
+ *
+ * sink_pif.h
+ *
+ ******************************************************************************
+ */
+
+#ifndef SINK_PIF_H_
+#define SINK_PIF_H_
+
+/* register PKT_INFO_TYPE_CFG1 */
+#define PKT_INFO_TYPE_CFG1 0
+#define F_INFO_TYPE1(x) (((x) & ((1 << 8) - 1)) << 0)
+#define F_INFO_TYPE1_RD(x) (((x) & (((1 << 8) - 1) << 0)) >> 0)
+#define F_INFO_TYPE2(x) (((x) & ((1 << 8) - 1)) << 8)
+#define F_INFO_TYPE2_RD(x) (((x) & (((1 << 8) - 1) << 8)) >> 8)
+#define F_INFO_TYPE3(x) (((x) & ((1 << 8) - 1)) << 16)
+#define F_INFO_TYPE3_RD(x) (((x) & (((1 << 8) - 1) << 16)) >> 16)
+#define F_INFO_TYPE4(x) (((x) & ((1 << 8) - 1)) << 24)
+#define F_INFO_TYPE4_RD(x) (((x) & (((1 << 8) - 1) << 24)) >> 24)
+
+/* register PKT_INFO_TYPE_CFG2 */
+#define PKT_INFO_TYPE_CFG2 1
+#define F_INFO_TYPE5(x) (((x) & ((1 << 8) - 1)) << 0)
+#define F_INFO_TYPE5_RD(x) (((x) & (((1 << 8) - 1) << 0)) >> 0)
+#define F_INFO_TYPE6(x) (((x) & ((1 << 8) - 1)) << 8)
+#define F_INFO_TYPE6_RD(x) (((x) & (((1 << 8) - 1) << 8)) >> 8)
+#define F_INFO_TYPE7(x) (((x) & ((1 << 8) - 1)) << 16)
+#define F_INFO_TYPE7_RD(x) (((x) & (((1 << 8) - 1) << 16)) >> 16)
+#define F_INFO_TYPE8(x) (((x) & ((1 << 8) - 1)) << 24)
+#define F_INFO_TYPE8_RD(x) (((x) & (((1 << 8) - 1) << 24)) >> 24)
+
+/* register PKT_INFO_TYPE_CFG3 */
+#define PKT_INFO_TYPE_CFG3 2
+#define F_INFO_TYPE9(x) (((x) & ((1 << 8) - 1)) << 0)
+#define F_INFO_TYPE9_RD(x) (((x) & (((1 << 8) - 1) << 0)) >> 0)
+#define F_INFO_TYPE10(x) (((x) & ((1 << 8) - 1)) << 8)
+#define F_INFO_TYPE10_RD(x) (((x) & (((1 << 8) - 1) << 8)) >> 8)
+#define F_INFO_TYPE11(x) (((x) & ((1 << 8) - 1)) << 16)
+#define F_INFO_TYPE11_RD(x) (((x) & (((1 << 8) - 1) << 16)) >> 16)
+#define F_INFO_TYPE12(x) (((x) & ((1 << 8) - 1)) << 24)
+#define F_INFO_TYPE12_RD(x) (((x) & (((1 << 8) - 1) << 24)) >> 24)
+
+/* register PKT_INFO_TYPE_CFG4 */
+#define PKT_INFO_TYPE_CFG4 3
+#define F_INFO_TYPE13(x) (((x) & ((1 << 8) - 1)) << 0)
+#define F_INFO_TYPE13_RD(x) (((x) & (((1 << 8) - 1) << 0)) >> 0)
+#define F_INFO_TYPE14(x) (((x) & ((1 << 8) - 1)) << 8)
+#define F_INFO_TYPE14_RD(x) (((x) & (((1 << 8) - 1) << 8)) >> 8)
+#define F_INFO_TYPE15(x) (((x) & ((1 << 8) - 1)) << 16)
+#define F_INFO_TYPE15_RD(x) (((x) & (((1 << 8) - 1) << 16)) >> 16)
+#define F_INFO_TYPE16(x) (((x) & ((1 << 8) - 1)) << 24)
+#define F_INFO_TYPE16_RD(x) (((x) & (((1 << 8) - 1) << 24)) >> 24)
+
+/* register PKT_INFO_CTRL */
+#define PKT_INFO_CTRL 4
+#define F_PACKET_RDN_WR(x) (((x) & ((1 << 1) - 1)) << 0)
+#define F_PACKET_RDN_WR_RD(x) (((x) & (((1 << 1) - 1) << 0)) >> 0)
+#define F_PACKET_NUM(x) (((x) & ((1 << 4) - 1)) << 1)
+#define F_PACKET_NUM_RD(x) (((x) & (((1 << 4) - 1) << 1)) >> 1)
+
+/* register PKT_INFO_HEADER */
+#define PKT_INFO_HEADER 7
+#define F_PKT_MEMORY_HEADER(x) (((x) & ((1 << 32) - 1)) << 0)
+#define F_PKT_MEMORY_HEADER_RD(x) (((x) & (((1 << 32) - 1) << 0)) >> 0)
+
+/* register PKT_INFO_DATA1 */
+#define PKT_INFO_DATA1 8
+#define F_PKT_MEMORY_DATA1(x) (((x) & ((1 << 32) - 1)) << 0)
+#define F_PKT_MEMORY_DATA1_RD(x) (((x) & (((1 << 32) - 1) << 0)) >> 0)
+
+/* register PKT_INFO_DATA2 */
+#define PKT_INFO_DATA2 9
+#define F_PKT_MEMORY_DATA2(x) (((x) & ((1 << 32) - 1)) << 0)
+#define F_PKT_MEMORY_DATA2_RD(x) (((x) & (((1 << 32) - 1) << 0)) >> 0)
+
+/* register PKT_INFO_DATA3 */
+#define PKT_INFO_DATA3 10
+#define F_PKT_MEMORY_DATA3(x) (((x) & ((1 << 32) - 1)) << 0)
+#define F_PKT_MEMORY_DATA3_RD(x) (((x) & (((1 << 32) - 1) << 0)) >> 0)
+
+/* register PKT_INFO_DATA4 */
+#define PKT_INFO_DATA4 11
+#define F_PKT_MEMORY_DATA4(x) (((x) & ((1 << 32) - 1)) << 0)
+#define F_PKT_MEMORY_DATA4_RD(x) (((x) & (((1 << 32) - 1) << 0)) >> 0)
+
+/* register PKT_INFO_DATA5 */
+#define PKT_INFO_DATA5 12
+#define F_PKT_MEMORY_DATA5(x) (((x) & ((1 << 32) - 1)) << 0)
+#define F_PKT_MEMORY_DATA5_RD(x) (((x) & (((1 << 32) - 1) << 0)) >> 0)
+
+/* register PKT_INFO_DATA6 */
+#define PKT_INFO_DATA6 13
+#define F_PKT_MEMORY_DATA6(x) (((x) & ((1 << 32) - 1)) << 0)
+#define F_PKT_MEMORY_DATA6_RD(x) (((x) & (((1 << 32) - 1) << 0)) >> 0)
+
+/* register PKT_INFO_DATA7 */
+#define PKT_INFO_DATA7 14
+#define F_PKT_MEMORY_DATA7(x) (((x) & ((1 << 32) - 1)) << 0)
+#define F_PKT_MEMORY_DATA7_RD(x) (((x) & (((1 << 32) - 1) << 0)) >> 0)
+
+/* register PKT_INT_STATUS */
+#define PKT_INT_STATUS 15
+#define F_PKT_RDY_STATUS(x) (((x) & ((1 << 17) - 1)) << 0)
+#define F_PKT_RDY_STATUS_RD(x) (((x) & (((1 << 17) - 1) << 0)) >> 0)
+
+/* register PKT_INT_MASK */
+#define PKT_INT_MASK 16
+#define F_PKT_RDY_MASK(x) (((x) & ((1 << 17) - 1)) << 0)
+#define F_PKT_RDY_MASK_RD(x) (((x) & (((1 << 17) - 1) << 0)) >> 0)
+
+/* register PKT_TRANS_CTRL */
+#define PKT_TRANS_CTRL 17
+#define F_PKT_TRANS_MASK_ERR(x) (((x) & ((1 << 1) - 1)) << 0)
+#define F_PKT_TRANS_MASK_ERR_RD(x) (((x) & (((1 << 1) - 1) << 0)) >> 0)
+
+#endif /* SINK_PIF */
diff --git a/drivers/mxc/hdp/sink_vif.h b/drivers/mxc/hdp/sink_vif.h
new file mode 100644
index 000000000000..cce0080a81e3
--- /dev/null
+++ b/drivers/mxc/hdp/sink_vif.h
@@ -0,0 +1,285 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2016-2017 Cadence Design Systems, Inc.
+ * All rights reserved worldwide.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 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.
+ *
+ * Copyright 2018 NXP
+ *
+ ******************************************************************************
+ *
+ * This file was auto-generated. Do not edit it manually.
+ *
+ ******************************************************************************
+ *
+ * sink_vif.h
+ *
+ ******************************************************************************
+ */
+#ifndef SINK_VIF_H_
+#define SINK_VIF_H_
+
+/* register VIDEO_UNPACK_CFG */
+#define VIDEO_UNPACK_CFG 0
+#define F_SW_CD_PHASE(x) (((x) & ((1 << 4) - 1)) << 0)
+#define F_SW_CD_PHASE_RD(x) (((x) & (((1 << 4) - 1) << 0)) >> 0)
+#define F_FORCE_SW_CD(x) (((x) & ((1 << 1) - 1)) << 4)
+#define F_FORCE_SW_CD_RD(x) (((x) & (((1 << 1) - 1) << 4)) >> 4)
+#define F_SW_CD_COLOR_DEPTH(x) (((x) & ((1 << 4) - 1)) << 5)
+#define F_SW_CD_COLOR_DEPTH_RD(x) (((x) & (((1 << 4) - 1) << 5)) >> 5)
+#define F_FORCE_SW_PHASE(x) (((x) & ((1 << 1) - 1)) << 9)
+#define F_FORCE_SW_PHASE_RD(x) (((x) & (((1 << 1) - 1) << 9)) >> 9)
+#define F_VIDEO_PIXEL_ENCODING(x) (((x) & ((1 << 2) - 1)) << 10)
+#define F_VIDEO_PIXEL_ENCODING_RD(x) (((x) & (((1 << 2) - 1) << 10)) >> 10)
+
+/* register VIDEO_UNPACK_CTRL */
+#define VIDEO_UNPACK_CTRL 1
+#define F_SW_CD_FSM_CLR(x) (((x) & ((1 << 1) - 1)) << 0)
+#define F_SW_CD_FSM_CLR_RD(x) (((x) & (((1 << 1) - 1) << 0)) >> 0)
+#define F_CD_ENABLE(x) (((x) & ((1 << 1) - 1)) << 1)
+#define F_CD_ENABLE_RD(x) (((x) & (((1 << 1) - 1) << 1)) >> 1)
+#define F_CD_FIFO_AEMPTY_TH(x) (((x) & ((1 << 5) - 1)) << 2)
+#define F_CD_FIFO_AEMPTY_TH_RD(x) (((x) & (((1 << 5) - 1) << 2)) >> 2)
+#define F_FSM_ERROR_ENABLE(x) (((x) & ((1 << 1) - 1)) << 7)
+#define F_FSM_ERROR_ENABLE_RD(x) (((x) & (((1 << 1) - 1) << 7)) >> 7)
+
+/* register VIDEO_UNPACK_STAT */
+#define VIDEO_UNPACK_STAT 2
+#define F_CD_FIFO_OVERRUN(x) (((x) & ((1 << 1) - 1)) << 0)
+#define F_CD_FIFO_OVERRUN_RD(x) (((x) & (((1 << 1) - 1) << 0)) >> 0)
+#define F_CD_FIFO_UNDERRUN(x) (((x) & ((1 << 1) - 1)) << 1)
+#define F_CD_FIFO_UNDERRUN_RD(x) (((x) & (((1 << 1) - 1) << 1)) >> 1)
+#define F_CD_PHASE(x) (((x) & ((1 << 4) - 1)) << 2)
+#define F_CD_PHASE_RD(x) (((x) & (((1 << 4) - 1) << 2)) >> 2)
+#define F_CD_COLOR_DEPTH(x) (((x) & ((1 << 4) - 1)) << 6)
+#define F_CD_COLOR_DEPTH_RD(x) (((x) & (((1 << 4) - 1) << 6)) >> 6)
+#define F_CD_LAST_PHASE(x) (((x) & ((1 << 4) - 1)) << 10)
+#define F_CD_LAST_PHASE_RD(x) (((x) & (((1 << 4) - 1) << 10)) >> 10)
+#define F_CD_FIFO_EMPTY(x) (((x) & ((1 << 1) - 1)) << 14)
+#define F_CD_FIFO_EMPTY_RD(x) (((x) & (((1 << 1) - 1) << 14)) >> 14)
+#define F_CD_FIFO_FULL(x) (((x) & ((1 << 1) - 1)) << 15)
+#define F_CD_FIFO_FULL_RD(x) (((x) & (((1 << 1) - 1) << 15)) >> 15)
+#define F_CD_STATE(x) (((x) & ((1 << 5) - 1)) << 16)
+#define F_CD_STATE_RD(x) (((x) & (((1 << 5) - 1) << 16)) >> 16)
+
+/* register VANLYZ_CTRL */
+#define VANLYZ_CTRL 4
+#define F_VANLYZ_START(x) (((x) & ((1 << 1) - 1)) << 0)
+#define F_VANLYZ_START_RD(x) (((x) & (((1 << 1) - 1) << 0)) >> 0)
+#define F_VANLYZ_RESET(x) (((x) & ((1 << 1) - 1)) << 1)
+#define F_VANLYZ_RESET_RD(x) (((x) & (((1 << 1) - 1) << 1)) >> 1)
+#define F_VANLYZ_FRAMES_CHECK_EN(x) (((x) & ((1 << 1) - 1)) << 2)
+#define F_VANLYZ_FRAMES_CHECK_EN_RD(x) (((x) & (((1 << 1) - 1) << 2)) >> 2)
+#define F_VANLYZ_FORMAT_FINDER_EN(x) (((x) & ((1 << 1) - 1)) << 3)
+#define F_VANLYZ_FORMAT_FINDER_EN_RD(x) (((x) & (((1 << 1) - 1) << 3)) >> 3)
+
+/* register VANLYZ_FRAMES_TO_CHECK */
+#define VANLYZ_FRAMES_TO_CHECK 5
+#define F_VANLYZ_FRAMES_TO_CHECK(x) (((x) & ((1 << 32) - 1)) << 0)
+#define F_VANLYZ_FRAMES_TO_CHECK_RD(x) (((x) & (((1 << 32) - 1) << 0)) >> 0)
+
+/* register VANLYZ_CFG_0 */
+#define VANLYZ_CFG_0 6
+#define F_VANLYZ_HSYNC_POLARITY(x) (((x) & ((1 << 1) - 1)) << 0)
+#define F_VANLYZ_HSYNC_POLARITY_RD(x) (((x) & (((1 << 1) - 1) << 0)) >> 0)
+#define F_VANLYZ_VSYNC_POLARITY(x) (((x) & ((1 << 1) - 1)) << 1)
+#define F_VANLYZ_VSYNC_POLARITY_RD(x) (((x) & (((1 << 1) - 1) << 1)) >> 1)
+#define F_VANLYZ_BITWIDTH(x) (((x) & ((1 << 2) - 1)) << 2)
+#define F_VANLYZ_BITWIDTH_RD(x) (((x) & (((1 << 2) - 1) << 2)) >> 2)
+
+/* register VANLYZ_CFG_1 */
+#define VANLYZ_CFG_1 7
+#define F_VANLYZ_FRONT_PORCH(x) (((x) & ((1 << 16) - 1)) << 0)
+#define F_VANLYZ_FRONT_PORCH_RD(x) (((x) & (((1 << 16) - 1) << 0)) >> 0)
+#define F_VANLYZ_BACK_PORCH(x) (((x) & ((1 << 16) - 1)) << 16)
+#define F_VANLYZ_BACK_PORCH_RD(x) (((x) & (((1 << 16) - 1) << 16)) >> 16)
+
+/* register VANLYZ_CFG_2 */
+#define VANLYZ_CFG_2 8
+#define F_VANLYZ_ACTIVE_SLOT(x) (((x) & ((1 << 16) - 1)) << 0)
+#define F_VANLYZ_ACTIVE_SLOT_RD(x) (((x) & (((1 << 16) - 1) << 0)) >> 0)
+#define F_VANLYZ_FRAME_LINES(x) (((x) & ((1 << 16) - 1)) << 16)
+#define F_VANLYZ_FRAME_LINES_RD(x) (((x) & (((1 << 16) - 1) << 16)) >> 16)
+
+/* register VANLYZ_CFG_3 */
+#define VANLYZ_CFG_3 9
+#define F_VANLYZ_LINE_WIDTH(x) (((x) & ((1 << 16) - 1)) << 0)
+#define F_VANLYZ_LINE_WIDTH_RD(x) (((x) & (((1 << 16) - 1) << 0)) >> 0)
+
+/* register VANLYZ_CFG_4 */
+#define VANLYZ_CFG_4 10
+#define F_VANLYZ_NUM_CLK_CYC(x) (((x) & ((1 << 24) - 1)) << 0)
+#define F_VANLYZ_NUM_CLK_CYC_RD(x) (((x) & (((1 << 24) - 1) << 0)) >> 0)
+#define F_VANLYZ_VSYNC_LINES(x) (((x) & ((1 << 8) - 1)) << 24)
+#define F_VANLYZ_VSYNC_LINES_RD(x) (((x) & (((1 << 8) - 1) << 24)) >> 24)
+
+/* register VANLYZ_CFG_5 */
+#define VANLYZ_CFG_5 11
+#define F_VANLYZ_3D_MODE(x) (((x) & ((1 << 3) - 1)) << 0)
+#define F_VANLYZ_3D_MODE_RD(x) (((x) & (((1 << 3) - 1) << 0)) >> 0)
+#define F_VANLYZ_EOF_LINES(x) (((x) & ((1 << 8) - 1)) << 3)
+#define F_VANLYZ_EOF_LINES_RD(x) (((x) & (((1 << 8) - 1) << 3)) >> 3)
+#define F_VANLYZ_SOF_LINES(x) (((x) & ((1 << 8) - 1)) << 11)
+#define F_VANLYZ_SOF_LINES_RD(x) (((x) & (((1 << 8) - 1) << 11)) >> 11)
+
+/* register VANLYZ_CLK_METER_REF_CYC */
+#define VANLYZ_CLK_METER_REF_CYC 12
+#define F_VANLYZ_CLK_METER_REF_CYC(x) (((x) & ((1 << 24) - 1)) << 0)
+#define F_VANLYZ_CLK_METER_REF_CYC_RD(x) (((x) & (((1 << 24) - 1) << 0)) >> 0)
+
+/* register VANLYZ_CLK_METER_MEAS_TOLRNCE */
+#define VANLYZ_CLK_METER_MEAS_TOLRNCE 13
+#define F_VANLYZ_CLK_METER_MEAS_TOLRNCE(x) (((x) & ((1 << 16) - 1)) << 0)
+#define F_VANLYZ_CLK_METER_MEAS_TOLRNCE_RD(x) (((x) & (((1 << 16) - 1) << 0)) >> 0)
+
+/* register VANLYZ_FORMAT_NUM */
+#define VANLYZ_FORMAT_NUM 14
+#define F_VANLYZ_FORMAT1_NUM(x) (((x) & ((1 << 6) - 1)) << 0)
+#define F_VANLYZ_FORMAT1_NUM_RD(x) (((x) & (((1 << 6) - 1) << 0)) >> 0)
+#define F_VANLYZ_FORMAT2_NUM(x) (((x) & ((1 << 6) - 1)) << 8)
+#define F_VANLYZ_FORMAT2_NUM_RD(x) (((x) & (((1 << 6) - 1) << 8)) >> 8)
+
+/* register VANLYZ_FAILURES */
+#define VANLYZ_FAILURES 15
+#define F_VANLYZ_FAILURES(x) (((x) & ((1 << 16) - 1)) << 0)
+#define F_VANLYZ_FAILURES_RD(x) (((x) & (((1 << 16) - 1) << 0)) >> 0)
+
+/* register VANLYZ_ST_0 */
+#define VANLYZ_ST_0 16
+#define F_VANLYZ_STATUS_HP(x) (((x) & ((1 << 1) - 1)) << 0)
+#define F_VANLYZ_STATUS_HP_RD(x) (((x) & (((1 << 1) - 1) << 0)) >> 0)
+#define F_VANLYZ_STATUS_VP(x) (((x) & ((1 << 1) - 1)) << 1)
+#define F_VANLYZ_STATUS_VP_RD(x) (((x) & (((1 << 1) - 1) << 1)) >> 1)
+
+/* register VANLYZ_ST_1 */
+#define VANLYZ_ST_1 17
+#define F_VANLYZ_STATUS_FRAME_LINES(x) (((x) & ((1 << 16) - 1)) << 0)
+#define F_VANLYZ_STATUS_FRAME_LINES_RD(x) (((x) & (((1 << 16) - 1) << 0)) >> 0)
+#define F_VANLYZ_STATUS_FP(x) (((x) & ((1 << 16) - 1)) << 16)
+#define F_VANLYZ_STATUS_FP_RD(x) (((x) & (((1 << 16) - 1) << 16)) >> 16)
+
+/* register VANLYZ_ST_2 */
+#define VANLYZ_ST_2 18
+#define F_VANLYZ_STATUS_BP(x) (((x) & ((1 << 16) - 1)) << 0)
+#define F_VANLYZ_STATUS_BP_RD(x) (((x) & (((1 << 16) - 1) << 0)) >> 0)
+#define F_VANLYZ_STATUS_AS(x) (((x) & ((1 << 16) - 1)) << 16)
+#define F_VANLYZ_STATUS_AS_RD(x) (((x) & (((1 << 16) - 1) << 16)) >> 16)
+
+/* register VANLYZ_STATUS_3 */
+#define VANLYZ_STATUS_3 19
+#define F_VANLYZ_STATUS_LINE_WIDTH(x) (((x) & ((1 << 16) - 1)) << 0)
+#define F_VANLYZ_STATUS_LINE_WIDTH_RD(x) (((x) & (((1 << 16) - 1) << 0)) >> 0)
+
+/* register VANLYZ_STATUS_4 */
+#define VANLYZ_STATUS_4 20
+#define F_VANLYZ_STATUS_VSYNC_LINES(x) (((x) & ((1 << 8) - 1)) << 0)
+#define F_VANLYZ_STATUS_VSYNC_LINES_RD(x) (((x) & (((1 << 8) - 1) << 0)) >> 0)
+#define F_VANLYZ_STATUS_EOF_LINES(x) (((x) & ((1 << 8) - 1)) << 8)
+#define F_VANLYZ_STATUS_EOF_LINES_RD(x) (((x) & (((1 << 8) - 1) << 8)) >> 8)
+#define F_VANLYZ_STATUS_SOF_LINES(x) (((x) & ((1 << 8) - 1)) << 16)
+#define F_VANLYZ_STATUS_SOF_LINES_RD(x) (((x) & (((1 << 8) - 1) << 16)) >> 16)
+
+/* register VANLYZ_STATUS_5 */
+#define VANLYZ_STATUS_5 21
+#define F_VANLYZ_FORMAT_FINDER_ADD(x) (((x) & ((1 << 6) - 1)) << 0)
+#define F_VANLYZ_FORMAT_FINDER_ADD_RD(x) (((x) & (((1 << 6) - 1) << 0)) >> 0)
+#define F_VANLYZ_FORMAT_FINDER_ACTIVE(x) (((x) & ((1 << 1) - 1)) << 6)
+#define F_VANLYZ_FORMAT_FINDER_ACTIVE_RD(x) (((x) & (((1 << 1) - 1) << 6)) >> 6)
+#define F_VANLYZ_CNT_LINES(x) (((x) & ((1 << 18) - 1)) << 7)
+#define F_VANLYZ_CNT_LINES_RD(x) (((x) & (((1 << 18) - 1) << 7)) >> 7)
+
+/* register VANLYZ_STATUS_6 */
+#define VANLYZ_STATUS_6 22
+#define F_VANLYZ_CNT_VIDEO(x) (((x) & ((1 << 18) - 1)) << 0)
+#define F_VANLYZ_CNT_VIDEO_RD(x) (((x) & (((1 << 18) - 1) << 0)) >> 0)
+
+/* register VANLYZ_STATUS_7 */
+#define VANLYZ_STATUS_7 23
+#define F_VANLYZ_VIDEO_SIZE(x) (((x) & ((1 << 18) - 1)) << 0)
+#define F_VANLYZ_VIDEO_SIZE_RD(x) (((x) & (((1 << 18) - 1) << 0)) >> 0)
+
+/* register VANLYZ_PIC_CFG_0 */
+#define VANLYZ_PIC_CFG_0 24
+#define F_VANLYZ_PIC_R(x) (((x) & ((1 << 16) - 1)) << 0)
+#define F_VANLYZ_PIC_R_RD(x) (((x) & (((1 << 16) - 1) << 0)) >> 0)
+#define F_VANLYZ_PIC_G(x) (((x) & ((1 << 16) - 1)) << 16)
+#define F_VANLYZ_PIC_G_RD(x) (((x) & (((1 << 16) - 1) << 16)) >> 16)
+
+/* register VANLYZ_PIC_CFG_1 */
+#define VANLYZ_PIC_CFG_1 25
+#define F_VANLYZ_PIC_B(x) (((x) & ((1 << 16) - 1)) << 0)
+#define F_VANLYZ_PIC_B_RD(x) (((x) & (((1 << 16) - 1) << 0)) >> 0)
+
+/* register VIF_MHL_HD_ERR_INT_MASK */
+#define VIF_MHL_HD_ERR_INT_MASK 26
+#define F_VIF_MHL_HD_ERR_MASK(x) (((x) & ((1 << 20) - 1)) << 0)
+#define F_VIF_MHL_HD_ERR_MASK_RD(x) (((x) & (((1 << 20) - 1) << 0)) >> 0)
+
+/* register VIF_MHL_HD_ERR_INT_STAT */
+#define VIF_MHL_HD_ERR_INT_STAT 27
+#define F_VIF_MHL_HD_ERR_STATUS(x) (((x) & ((1 << 20) - 1)) << 0)
+#define F_VIF_MHL_HD_ERR_STATUS_RD(x) (((x) & (((1 << 20) - 1) << 0)) >> 0)
+
+/* register VIF_IP_DETECT_CTRL */
+#define VIF_IP_DETECT_CTRL 28
+#define F_READ_DTCT_ERR(x) (((x) & ((1 << 1) - 1)) << 0)
+#define F_READ_DTCT_ERR_RD(x) (((x) & (((1 << 1) - 1) << 0)) >> 0)
+#define F_IP_DTCT_WIN(x) (((x) & ((1 << 12) - 1)) << 1)
+#define F_IP_DTCT_WIN_RD(x) (((x) & (((1 << 12) - 1) << 1)) >> 1)
+#define F_IP_DTCT_EN(x) (((x) & ((1 << 1) - 1)) << 13)
+#define F_IP_DTCT_EN_RD(x) (((x) & (((1 << 1) - 1) << 13)) >> 13)
+
+/* register VIF_IP_DETECT_ST1 */
+#define VIF_IP_DETECT_ST1 29
+#define F_IP_DTCT_HSYNC2VSYNC_F1(x) (((x) & ((1 << 16) - 1)) << 0)
+#define F_IP_DTCT_HSYNC2VSYNC_F1_RD(x) (((x) & (((1 << 16) - 1) << 0)) >> 0)
+#define F_IP_DTCT_HSYNC2VSYNC_F2(x) (((x) & ((1 << 16) - 1)) << 16)
+#define F_IP_DTCT_HSYNC2VSYNC_F2_RD(x) (((x) & (((1 << 16) - 1) << 16)) >> 16)
+
+/* register VIF_IP_DETECT_ST2 */
+#define VIF_IP_DETECT_ST2 30
+#define F_IP_STATE(x) (((x) & ((1 << 2) - 1)) << 0)
+#define F_IP_STATE_RD(x) (((x) & (((1 << 2) - 1) << 0)) >> 0)
+#define F_IP_DTCT_ERR(x) (((x) & ((1 << 1) - 1)) << 2)
+#define F_IP_DTCT_ERR_RD(x) (((x) & (((1 << 1) - 1) << 2)) >> 2)
+#define F_IP_DTCT_HJITTER(x) (((x) & ((1 << 1) - 1)) << 3)
+#define F_IP_DTCT_HJITTER_RD(x) (((x) & (((1 << 1) - 1) << 3)) >> 3)
+#define F_IP_DTCT_VJITTER(x) (((x) & ((1 << 1) - 1)) << 4)
+#define F_IP_DTCT_VJITTER_RD(x) (((x) & (((1 << 1) - 1) << 4)) >> 4)
+#define F_IP_DTCT_IP(x) (((x) & ((1 << 1) - 1)) << 5)
+#define F_IP_DTCT_IP_RD(x) (((x) & (((1 << 1) - 1) << 5)) >> 5)
+#define F_IP_DTCT_FIELD(x) (((x) & ((1 << 1) - 1)) << 6)
+#define F_IP_DTCT_FIELD_RD(x) (((x) & (((1 << 1) - 1) << 6)) >> 6)
+
+#endif /* SINK_VIF */
diff --git a/drivers/mxc/hdp/source_aif_decoder.h b/drivers/mxc/hdp/source_aif_decoder.h
new file mode 100644
index 000000000000..6b69e44865f1
--- /dev/null
+++ b/drivers/mxc/hdp/source_aif_decoder.h
@@ -0,0 +1,452 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2016-2017 Cadence Design Systems, Inc.
+ * All rights reserved worldwide.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 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.
+ *
+ * Copyright 2017 NXP
+ *
+ ******************************************************************************
+ *
+ * This file was auto-generated. Do not edit it manually.
+ *
+ ******************************************************************************
+ *
+ * source_aif_decoder.h
+ *
+ ******************************************************************************
+ */
+
+#ifndef SOURCE_AIF_DECODER_H_
+#define SOURCE_AIF_DECODER_H_
+
+/* register AUDIO_SRC_CNTL */
+#define AUDIO_SRC_CNTL 0
+#define F_SW_RST(x) (((x) & ((1 << 1) - 1)) << 0)
+#define F_SW_RST_RD(x) (((x) & (((1 << 1) - 1) << 0)) >> 0)
+#define F_I2S_DEC_START(x) (((x) & ((1 << 1) - 1)) << 1)
+#define F_I2S_DEC_START_RD(x) (((x) & (((1 << 1) - 1) << 1)) >> 1)
+#define F_I2S_BLOCK_START_FORCE(x) (((x) & ((1 << 1) - 1)) << 2)
+#define F_I2S_BLOCK_START_FORCE_RD(x) (((x) & (((1 << 1) - 1) << 2)) >> 2)
+#define F_SPDIF_TS_EN(x) (((x) & ((1 << 1) - 1)) << 3)
+#define F_SPDIF_TS_EN_RD(x) (((x) & (((1 << 1) - 1) << 3)) >> 3)
+#define F_I2S_TS_EN(x) (((x) & ((1 << 1) - 1)) << 4)
+#define F_I2S_TS_EN_RD(x) (((x) & (((1 << 1) - 1) << 4)) >> 4)
+#define F_VALID_BITS_FORCE(x) (((x) & ((1 << 1) - 1)) << 5)
+#define F_VALID_BITS_FORCE_RD(x) (((x) & (((1 << 1) - 1) << 5)) >> 5)
+#define F_VALID_ALL(x) (((x) & ((1 << 1) - 1)) << 6)
+#define F_VALID_ALL_RD(x) (((x) & (((1 << 1) - 1) << 6)) >> 6)
+
+/* register AUDIO_SRC_CNFG */
+#define AUDIO_SRC_CNFG 1
+#define F_LOW_INDEX_MSB(x) (((x) & ((1 << 1) - 1)) << 0)
+#define F_LOW_INDEX_MSB_RD(x) (((x) & (((1 << 1) - 1) << 0)) >> 0)
+#define F_WS_POLARITY(x) (((x) & ((1 << 1) - 1)) << 1)
+#define F_WS_POLARITY_RD(x) (((x) & (((1 << 1) - 1) << 1)) >> 1)
+#define F_AUDIO_CH_NUM(x) (((x) & ((1 << 5) - 1)) << 2)
+#define F_AUDIO_CH_NUM_RD(x) (((x) & (((1 << 5) - 1) << 2)) >> 2)
+#define F_AUDIO_SAMPLE_JUST(x) (((x) & ((1 << 2) - 1)) << 7)
+#define F_AUDIO_SAMPLE_JUST_RD(x) (((x) & (((1 << 2) - 1) << 7)) >> 7)
+#define F_AUDIO_SAMPLE_WIDTH(x) (((x) & ((1 << 2) - 1)) << 9)
+#define F_AUDIO_SAMPLE_WIDTH_RD(x) (((x) & (((1 << 2) - 1) << 9)) >> 9)
+#define F_TRANS_SMPL_WIDTH(x) (((x) & ((1 << 2) - 1)) << 11)
+#define F_TRANS_SMPL_WIDTH_RD(x) (((x) & (((1 << 2) - 1) << 11)) >> 11)
+#define F_AUDIO_CHANNEL_TYPE(x) (((x) & ((1 << 4) - 1)) << 13)
+#define F_AUDIO_CHANNEL_TYPE_RD(x) (((x) & (((1 << 4) - 1) << 13)) >> 13)
+#define F_I2S_DEC_PORT_EN(x) (((x) & ((1 << 4) - 1)) << 17)
+#define F_I2S_DEC_PORT_EN_RD(x) (((x) & (((1 << 4) - 1) << 17)) >> 17)
+
+/* register COM_CH_STTS_BITS */
+#define COM_CH_STTS_BITS 2
+#define F_BYTE0(x) (((x) & ((1 << 8) - 1)) << 0)
+#define F_BYTE0_RD(x) (((x) & (((1 << 8) - 1) << 0)) >> 0)
+#define F_CATEGORY_CODE(x) (((x) & ((1 << 8) - 1)) << 8)
+#define F_CATEGORY_CODE_RD(x) (((x) & (((1 << 8) - 1) << 8)) >> 8)
+#define F_SAMPLING_FREQ(x) (((x) & ((1 << 4) - 1)) << 16)
+#define F_SAMPLING_FREQ_RD(x) (((x) & (((1 << 4) - 1) << 16)) >> 16)
+#define F_CLOCK_ACCURACY(x) (((x) & ((1 << 4) - 1)) << 20)
+#define F_CLOCK_ACCURACY_RD(x) (((x) & (((1 << 4) - 1) << 20)) >> 20)
+#define F_ORIGINAL_SAMP_FREQ(x) (((x) & ((1 << 4) - 1)) << 24)
+#define F_ORIGINAL_SAMP_FREQ_RD(x) (((x) & (((1 << 4) - 1) << 24)) >> 24)
+
+/* register STTS_BIT_CH01 */
+#define STTS_BIT_CH01 3
+#define F_SOURCE_NUM_CH0(x) (((x) & ((1 << 4) - 1)) << 0)
+#define F_SOURCE_NUM_CH0_RD(x) (((x) & (((1 << 4) - 1) << 0)) >> 0)
+#define F_CHANNEL_NUM_CH0(x) (((x) & ((1 << 4) - 1)) << 4)
+#define F_CHANNEL_NUM_CH0_RD(x) (((x) & (((1 << 4) - 1) << 4)) >> 4)
+#define F_WORD_LENGTH_CH0(x) (((x) & ((1 << 4) - 1)) << 8)
+#define F_WORD_LENGTH_CH0_RD(x) (((x) & (((1 << 4) - 1) << 8)) >> 8)
+#define F_SOURCE_NUM_CH1(x) (((x) & ((1 << 4) - 1)) << 12)
+#define F_SOURCE_NUM_CH1_RD(x) (((x) & (((1 << 4) - 1) << 12)) >> 12)
+#define F_CHANNEL_NUM_CH1(x) (((x) & ((1 << 4) - 1)) << 16)
+#define F_CHANNEL_NUM_CH1_RD(x) (((x) & (((1 << 4) - 1) << 16)) >> 16)
+#define F_WORD_LENGTH_CH1(x) (((x) & ((1 << 4) - 1)) << 20)
+#define F_WORD_LENGTH_CH1_RD(x) (((x) & (((1 << 4) - 1) << 20)) >> 20)
+#define F_VALID_BITS1_0(x) (((x) & ((1 << 2) - 1)) << 24)
+#define F_VALID_BITS1_0_RD(x) (((x) & (((1 << 2) - 1) << 24)) >> 24)
+
+/* register STTS_BIT_CH23 */
+#define STTS_BIT_CH23 4
+#define F_SOURCE_NUM_CH2(x) (((x) & ((1 << 4) - 1)) << 0)
+#define F_SOURCE_NUM_CH2_RD(x) (((x) & (((1 << 4) - 1) << 0)) >> 0)
+#define F_CHANNEL_NUM_CH2(x) (((x) & ((1 << 4) - 1)) << 4)
+#define F_CHANNEL_NUM_CH2_RD(x) (((x) & (((1 << 4) - 1) << 4)) >> 4)
+#define F_WORD_LENGTH_CH2(x) (((x) & ((1 << 4) - 1)) << 8)
+#define F_WORD_LENGTH_CH2_RD(x) (((x) & (((1 << 4) - 1) << 8)) >> 8)
+#define F_SOURCE_NUM_CH3(x) (((x) & ((1 << 4) - 1)) << 12)
+#define F_SOURCE_NUM_CH3_RD(x) (((x) & (((1 << 4) - 1) << 12)) >> 12)
+#define F_CHANNEL_NUM_CH3(x) (((x) & ((1 << 4) - 1)) << 16)
+#define F_CHANNEL_NUM_CH3_RD(x) (((x) & (((1 << 4) - 1) << 16)) >> 16)
+#define F_WORD_LENGTH_CH3(x) (((x) & ((1 << 4) - 1)) << 20)
+#define F_WORD_LENGTH_CH3_RD(x) (((x) & (((1 << 4) - 1) << 20)) >> 20)
+#define F_VALID_BITS3_2(x) (((x) & ((1 << 2) - 1)) << 24)
+#define F_VALID_BITS3_2_RD(x) (((x) & (((1 << 2) - 1) << 24)) >> 24)
+
+/* register STTS_BIT_CH45 */
+#define STTS_BIT_CH45 5
+#define F_SOURCE_NUM_CH4(x) (((x) & ((1 << 4) - 1)) << 0)
+#define F_SOURCE_NUM_CH4_RD(x) (((x) & (((1 << 4) - 1) << 0)) >> 0)
+#define F_CHANNEL_NUM_CH4(x) (((x) & ((1 << 4) - 1)) << 4)
+#define F_CHANNEL_NUM_CH4_RD(x) (((x) & (((1 << 4) - 1) << 4)) >> 4)
+#define F_WORD_LENGTH_CH4(x) (((x) & ((1 << 4) - 1)) << 8)
+#define F_WORD_LENGTH_CH4_RD(x) (((x) & (((1 << 4) - 1) << 8)) >> 8)
+#define F_SOURCE_NUM_CH5(x) (((x) & ((1 << 4) - 1)) << 12)
+#define F_SOURCE_NUM_CH5_RD(x) (((x) & (((1 << 4) - 1) << 12)) >> 12)
+#define F_CHANNEL_NUM_CH5(x) (((x) & ((1 << 4) - 1)) << 16)
+#define F_CHANNEL_NUM_CH5_RD(x) (((x) & (((1 << 4) - 1) << 16)) >> 16)
+#define F_WORD_LENGTH_CH5(x) (((x) & ((1 << 4) - 1)) << 20)
+#define F_WORD_LENGTH_CH5_RD(x) (((x) & (((1 << 4) - 1) << 20)) >> 20)
+#define F_VALID_BITS5_4(x) (((x) & ((1 << 2) - 1)) << 24)
+#define F_VALID_BITS5_4_RD(x) (((x) & (((1 << 2) - 1) << 24)) >> 24)
+
+/* register STTS_BIT_CH67 */
+#define STTS_BIT_CH67 6
+#define F_SOURCE_NUM_CH6(x) (((x) & ((1 << 4) - 1)) << 0)
+#define F_SOURCE_NUM_CH6_RD(x) (((x) & (((1 << 4) - 1) << 0)) >> 0)
+#define F_CHANNEL_NUM_CH6(x) (((x) & ((1 << 4) - 1)) << 4)
+#define F_CHANNEL_NUM_CH6_RD(x) (((x) & (((1 << 4) - 1) << 4)) >> 4)
+#define F_WORD_LENGTH_CH6(x) (((x) & ((1 << 4) - 1)) << 8)
+#define F_WORD_LENGTH_CH6_RD(x) (((x) & (((1 << 4) - 1) << 8)) >> 8)
+#define F_SOURCE_NUM_CH7(x) (((x) & ((1 << 4) - 1)) << 12)
+#define F_SOURCE_NUM_CH7_RD(x) (((x) & (((1 << 4) - 1) << 12)) >> 12)
+#define F_CHANNEL_NUM_CH7(x) (((x) & ((1 << 4) - 1)) << 16)
+#define F_CHANNEL_NUM_CH7_RD(x) (((x) & (((1 << 4) - 1) << 16)) >> 16)
+#define F_WORD_LENGTH_CH7(x) (((x) & ((1 << 4) - 1)) << 20)
+#define F_WORD_LENGTH_CH7_RD(x) (((x) & (((1 << 4) - 1) << 20)) >> 20)
+#define F_VALID_BITS7_6(x) (((x) & ((1 << 2) - 1)) << 24)
+#define F_VALID_BITS7_6_RD(x) (((x) & (((1 << 2) - 1) << 24)) >> 24)
+
+/* register STTS_BIT_CH89 */
+#define STTS_BIT_CH89 7
+#define F_SOURCE_NUM_CH8(x) (((x) & ((1 << 4) - 1)) << 0)
+#define F_SOURCE_NUM_CH8_RD(x) (((x) & (((1 << 4) - 1) << 0)) >> 0)
+#define F_CHANNEL_NUM_CH8(x) (((x) & ((1 << 4) - 1)) << 4)
+#define F_CHANNEL_NUM_CH8_RD(x) (((x) & (((1 << 4) - 1) << 4)) >> 4)
+#define F_WORD_LENGTH_CH8(x) (((x) & ((1 << 4) - 1)) << 8)
+#define F_WORD_LENGTH_CH8_RD(x) (((x) & (((1 << 4) - 1) << 8)) >> 8)
+#define F_SOURCE_NUM_CH9(x) (((x) & ((1 << 4) - 1)) << 12)
+#define F_SOURCE_NUM_CH9_RD(x) (((x) & (((1 << 4) - 1) << 12)) >> 12)
+#define F_CHANNEL_NUM_CH9(x) (((x) & ((1 << 4) - 1)) << 16)
+#define F_CHANNEL_NUM_CH9_RD(x) (((x) & (((1 << 4) - 1) << 16)) >> 16)
+#define F_WORD_LENGTH_CH9(x) (((x) & ((1 << 4) - 1)) << 20)
+#define F_WORD_LENGTH_CH9_RD(x) (((x) & (((1 << 4) - 1) << 20)) >> 20)
+#define F_VALID_BITS9_8(x) (((x) & ((1 << 2) - 1)) << 24)
+#define F_VALID_BITS9_8_RD(x) (((x) & (((1 << 2) - 1) << 24)) >> 24)
+
+/* register STTS_BIT_CH1011 */
+#define STTS_BIT_CH1011 8
+#define F_SOURCE_NUM_CH10(x) (((x) & ((1 << 4) - 1)) << 0)
+#define F_SOURCE_NUM_CH10_RD(x) (((x) & (((1 << 4) - 1) << 0)) >> 0)
+#define F_CHANNEL_NUM_CH10(x) (((x) & ((1 << 4) - 1)) << 4)
+#define F_CHANNEL_NUM_CH10_RD(x) (((x) & (((1 << 4) - 1) << 4)) >> 4)
+#define F_WORD_LENGTH_CH10(x) (((x) & ((1 << 4) - 1)) << 8)
+#define F_WORD_LENGTH_CH10_RD(x) (((x) & (((1 << 4) - 1) << 8)) >> 8)
+#define F_SOURCE_NUM_CH11(x) (((x) & ((1 << 4) - 1)) << 12)
+#define F_SOURCE_NUM_CH11_RD(x) (((x) & (((1 << 4) - 1) << 12)) >> 12)
+#define F_CHANNEL_NUM_CH11(x) (((x) & ((1 << 4) - 1)) << 16)
+#define F_CHANNEL_NUM_CH11_RD(x) (((x) & (((1 << 4) - 1) << 16)) >> 16)
+#define F_WORD_LENGTH_CH11(x) (((x) & ((1 << 4) - 1)) << 20)
+#define F_WORD_LENGTH_CH11_RD(x) (((x) & (((1 << 4) - 1) << 20)) >> 20)
+#define F_VALID_BITS11_10(x) (((x) & ((1 << 2) - 1)) << 24)
+#define F_VALID_BITS11_10_RD(x) (((x) & (((1 << 2) - 1) << 24)) >> 24)
+
+/* register STTS_BIT_CH1213 */
+#define STTS_BIT_CH1213 9
+#define F_SOURCE_NUM_CH12(x) (((x) & ((1 << 4) - 1)) << 0)
+#define F_SOURCE_NUM_CH12_RD(x) (((x) & (((1 << 4) - 1) << 0)) >> 0)
+#define F_CHANNEL_NUM_CH12(x) (((x) & ((1 << 4) - 1)) << 4)
+#define F_CHANNEL_NUM_CH12_RD(x) (((x) & (((1 << 4) - 1) << 4)) >> 4)
+#define F_WORD_LENGTH_CH12(x) (((x) & ((1 << 4) - 1)) << 8)
+#define F_WORD_LENGTH_CH12_RD(x) (((x) & (((1 << 4) - 1) << 8)) >> 8)
+#define F_SOURCE_NUM_CH13(x) (((x) & ((1 << 4) - 1)) << 12)
+#define F_SOURCE_NUM_CH13_RD(x) (((x) & (((1 << 4) - 1) << 12)) >> 12)
+#define F_CHANNEL_NUM_CH13(x) (((x) & ((1 << 4) - 1)) << 16)
+#define F_CHANNEL_NUM_CH13_RD(x) (((x) & (((1 << 4) - 1) << 16)) >> 16)
+#define F_WORD_LENGTH_CH13(x) (((x) & ((1 << 4) - 1)) << 20)
+#define F_WORD_LENGTH_CH13_RD(x) (((x) & (((1 << 4) - 1) << 20)) >> 20)
+#define F_VALID_BITS13_12(x) (((x) & ((1 << 2) - 1)) << 24)
+#define F_VALID_BITS13_12_RD(x) (((x) & (((1 << 2) - 1) << 24)) >> 24)
+
+/* register STTS_BIT_CH1415 */
+#define STTS_BIT_CH1415 10
+#define F_SOURCE_NUM_CH14(x) (((x) & ((1 << 4) - 1)) << 0)
+#define F_SOURCE_NUM_CH14_RD(x) (((x) & (((1 << 4) - 1) << 0)) >> 0)
+#define F_CHANNEL_NUM_CH14(x) (((x) & ((1 << 4) - 1)) << 4)
+#define F_CHANNEL_NUM_CH14_RD(x) (((x) & (((1 << 4) - 1) << 4)) >> 4)
+#define F_WORD_LENGTH_CH14(x) (((x) & ((1 << 4) - 1)) << 8)
+#define F_WORD_LENGTH_CH14_RD(x) (((x) & (((1 << 4) - 1) << 8)) >> 8)
+#define F_SOURCE_NUM_CH15(x) (((x) & ((1 << 4) - 1)) << 12)
+#define F_SOURCE_NUM_CH15_RD(x) (((x) & (((1 << 4) - 1) << 12)) >> 12)
+#define F_CHANNEL_NUM_CH15(x) (((x) & ((1 << 4) - 1)) << 16)
+#define F_CHANNEL_NUM_CH15_RD(x) (((x) & (((1 << 4) - 1) << 16)) >> 16)
+#define F_WORD_LENGTH_CH15(x) (((x) & ((1 << 4) - 1)) << 20)
+#define F_WORD_LENGTH_CH15_RD(x) (((x) & (((1 << 4) - 1) << 20)) >> 20)
+#define F_VALID_BITS15_14(x) (((x) & ((1 << 2) - 1)) << 24)
+#define F_VALID_BITS15_14_RD(x) (((x) & (((1 << 2) - 1) << 24)) >> 24)
+
+/* register STTS_BIT_CH1617 */
+#define STTS_BIT_CH1617 11
+#define F_SOURCE_NUM_CH16(x) (((x) & ((1 << 4) - 1)) << 0)
+#define F_SOURCE_NUM_CH16_RD(x) (((x) & (((1 << 4) - 1) << 0)) >> 0)
+#define F_CHANNEL_NUM_CH16(x) (((x) & ((1 << 4) - 1)) << 4)
+#define F_CHANNEL_NUM_CH16_RD(x) (((x) & (((1 << 4) - 1) << 4)) >> 4)
+#define F_WORD_LENGTH_CH16(x) (((x) & ((1 << 4) - 1)) << 8)
+#define F_WORD_LENGTH_CH16_RD(x) (((x) & (((1 << 4) - 1) << 8)) >> 8)
+#define F_SOURCE_NUM_CH17(x) (((x) & ((1 << 4) - 1)) << 12)
+#define F_SOURCE_NUM_CH17_RD(x) (((x) & (((1 << 4) - 1) << 12)) >> 12)
+#define F_CHANNEL_NUM_CH17(x) (((x) & ((1 << 4) - 1)) << 16)
+#define F_CHANNEL_NUM_CH17_RD(x) (((x) & (((1 << 4) - 1) << 16)) >> 16)
+#define F_WORD_LENGTH_CH17(x) (((x) & ((1 << 4) - 1)) << 20)
+#define F_WORD_LENGTH_CH17_RD(x) (((x) & (((1 << 4) - 1) << 20)) >> 20)
+#define F_VALID_BITS17_16(x) (((x) & ((1 << 2) - 1)) << 24)
+#define F_VALID_BITS17_16_RD(x) (((x) & (((1 << 2) - 1) << 24)) >> 24)
+
+/* register STTS_BIT_CH1819 */
+#define STTS_BIT_CH1819 12
+#define F_SOURCE_NUM_CH18(x) (((x) & ((1 << 4) - 1)) << 0)
+#define F_SOURCE_NUM_CH18_RD(x) (((x) & (((1 << 4) - 1) << 0)) >> 0)
+#define F_CHANNEL_NUM_CH18(x) (((x) & ((1 << 4) - 1)) << 4)
+#define F_CHANNEL_NUM_CH18_RD(x) (((x) & (((1 << 4) - 1) << 4)) >> 4)
+#define F_WORD_LENGTH_CH18(x) (((x) & ((1 << 4) - 1)) << 8)
+#define F_WORD_LENGTH_CH18_RD(x) (((x) & (((1 << 4) - 1) << 8)) >> 8)
+#define F_SOURCE_NUM_CH19(x) (((x) & ((1 << 4) - 1)) << 12)
+#define F_SOURCE_NUM_CH19_RD(x) (((x) & (((1 << 4) - 1) << 12)) >> 12)
+#define F_CHANNEL_NUM_CH19(x) (((x) & ((1 << 4) - 1)) << 16)
+#define F_CHANNEL_NUM_CH19_RD(x) (((x) & (((1 << 4) - 1) << 16)) >> 16)
+#define F_WORD_LENGTH_CH19(x) (((x) & ((1 << 4) - 1)) << 20)
+#define F_WORD_LENGTH_CH19_RD(x) (((x) & (((1 << 4) - 1) << 20)) >> 20)
+#define F_VALID_BITS19_18(x) (((x) & ((1 << 2) - 1)) << 24)
+#define F_VALID_BITS19_18_RD(x) (((x) & (((1 << 2) - 1) << 24)) >> 24)
+
+/* register STTS_BIT_CH2021 */
+#define STTS_BIT_CH2021 13
+#define F_SOURCE_NUM_CH20(x) (((x) & ((1 << 4) - 1)) << 0)
+#define F_SOURCE_NUM_CH20_RD(x) (((x) & (((1 << 4) - 1) << 0)) >> 0)
+#define F_CHANNEL_NUM_CH20(x) (((x) & ((1 << 4) - 1)) << 4)
+#define F_CHANNEL_NUM_CH20_RD(x) (((x) & (((1 << 4) - 1) << 4)) >> 4)
+#define F_WORD_LENGTH_CH20(x) (((x) & ((1 << 4) - 1)) << 8)
+#define F_WORD_LENGTH_CH20_RD(x) (((x) & (((1 << 4) - 1) << 8)) >> 8)
+#define F_SOURCE_NUM_CH21(x) (((x) & ((1 << 4) - 1)) << 12)
+#define F_SOURCE_NUM_CH21_RD(x) (((x) & (((1 << 4) - 1) << 12)) >> 12)
+#define F_CHANNEL_NUM_CH21(x) (((x) & ((1 << 4) - 1)) << 16)
+#define F_CHANNEL_NUM_CH21_RD(x) (((x) & (((1 << 4) - 1) << 16)) >> 16)
+#define F_WORD_LENGTH_CH21(x) (((x) & ((1 << 4) - 1)) << 20)
+#define F_WORD_LENGTH_CH21_RD(x) (((x) & (((1 << 4) - 1) << 20)) >> 20)
+#define F_VALID_BITS21_20(x) (((x) & ((1 << 2) - 1)) << 24)
+#define F_VALID_BITS21_20_RD(x) (((x) & (((1 << 2) - 1) << 24)) >> 24)
+
+/* register STTS_BIT_CH2223 */
+#define STTS_BIT_CH2223 14
+#define F_SOURCE_NUM_CH22(x) (((x) & ((1 << 4) - 1)) << 0)
+#define F_SOURCE_NUM_CH22_RD(x) (((x) & (((1 << 4) - 1) << 0)) >> 0)
+#define F_CHANNEL_NUM_CH22(x) (((x) & ((1 << 4) - 1)) << 4)
+#define F_CHANNEL_NUM_CH22_RD(x) (((x) & (((1 << 4) - 1) << 4)) >> 4)
+#define F_WORD_LENGTH_CH22(x) (((x) & ((1 << 4) - 1)) << 8)
+#define F_WORD_LENGTH_CH22_RD(x) (((x) & (((1 << 4) - 1) << 8)) >> 8)
+#define F_SOURCE_NUM_CH23(x) (((x) & ((1 << 4) - 1)) << 12)
+#define F_SOURCE_NUM_CH23_RD(x) (((x) & (((1 << 4) - 1) << 12)) >> 12)
+#define F_CHANNEL_NUM_CH23(x) (((x) & ((1 << 4) - 1)) << 16)
+#define F_CHANNEL_NUM_CH23_RD(x) (((x) & (((1 << 4) - 1) << 16)) >> 16)
+#define F_WORD_LENGTH_CH23(x) (((x) & ((1 << 4) - 1)) << 20)
+#define F_WORD_LENGTH_CH23_RD(x) (((x) & (((1 << 4) - 1) << 20)) >> 20)
+#define F_VALID_BITS23_22(x) (((x) & ((1 << 2) - 1)) << 24)
+#define F_VALID_BITS23_22_RD(x) (((x) & (((1 << 2) - 1) << 24)) >> 24)
+
+/* register STTS_BIT_CH2425 */
+#define STTS_BIT_CH2425 15
+#define F_SOURCE_NUM_CH24(x) (((x) & ((1 << 4) - 1)) << 0)
+#define F_SOURCE_NUM_CH24_RD(x) (((x) & (((1 << 4) - 1) << 0)) >> 0)
+#define F_CHANNEL_NUM_CH24(x) (((x) & ((1 << 4) - 1)) << 4)
+#define F_CHANNEL_NUM_CH24_RD(x) (((x) & (((1 << 4) - 1) << 4)) >> 4)
+#define F_WORD_LENGTH_CH24(x) (((x) & ((1 << 4) - 1)) << 8)
+#define F_WORD_LENGTH_CH24_RD(x) (((x) & (((1 << 4) - 1) << 8)) >> 8)
+#define F_SOURCE_NUM_CH25(x) (((x) & ((1 << 4) - 1)) << 12)
+#define F_SOURCE_NUM_CH25_RD(x) (((x) & (((1 << 4) - 1) << 12)) >> 12)
+#define F_CHANNEL_NUM_CH25(x) (((x) & ((1 << 4) - 1)) << 16)
+#define F_CHANNEL_NUM_CH25_RD(x) (((x) & (((1 << 4) - 1) << 16)) >> 16)
+#define F_WORD_LENGTH_CH25(x) (((x) & ((1 << 4) - 1)) << 20)
+#define F_WORD_LENGTH_CH25_RD(x) (((x) & (((1 << 4) - 1) << 20)) >> 20)
+#define F_VALID_BITS25_24(x) (((x) & ((1 << 2) - 1)) << 24)
+#define F_VALID_BITS25_24_RD(x) (((x) & (((1 << 2) - 1) << 24)) >> 24)
+
+/* register STTS_BIT_CH2627 */
+#define STTS_BIT_CH2627 16
+#define F_SOURCE_NUM_CH26(x) (((x) & ((1 << 4) - 1)) << 0)
+#define F_SOURCE_NUM_CH26_RD(x) (((x) & (((1 << 4) - 1) << 0)) >> 0)
+#define F_CHANNEL_NUM_CH26(x) (((x) & ((1 << 4) - 1)) << 4)
+#define F_CHANNEL_NUM_CH26_RD(x) (((x) & (((1 << 4) - 1) << 4)) >> 4)
+#define F_WORD_LENGTH_CH26(x) (((x) & ((1 << 4) - 1)) << 8)
+#define F_WORD_LENGTH_CH26_RD(x) (((x) & (((1 << 4) - 1) << 8)) >> 8)
+#define F_SOURCE_NUM_CH27(x) (((x) & ((1 << 4) - 1)) << 12)
+#define F_SOURCE_NUM_CH27_RD(x) (((x) & (((1 << 4) - 1) << 12)) >> 12)
+#define F_CHANNEL_NUM_CH27(x) (((x) & ((1 << 4) - 1)) << 16)
+#define F_CHANNEL_NUM_CH27_RD(x) (((x) & (((1 << 4) - 1) << 16)) >> 16)
+#define F_WORD_LENGTH_CH27(x) (((x) & ((1 << 4) - 1)) << 20)
+#define F_WORD_LENGTH_CH27_RD(x) (((x) & (((1 << 4) - 1) << 20)) >> 20)
+#define F_VALID_BITS27_26(x) (((x) & ((1 << 2) - 1)) << 24)
+#define F_VALID_BITS27_26_RD(x) (((x) & (((1 << 2) - 1) << 24)) >> 24)
+
+/* register STTS_BIT_CH2829 */
+#define STTS_BIT_CH2829 17
+#define F_SOURCE_NUM_CH28(x) (((x) & ((1 << 4) - 1)) << 0)
+#define F_SOURCE_NUM_CH28_RD(x) (((x) & (((1 << 4) - 1) << 0)) >> 0)
+#define F_CHANNEL_NUM_CH28(x) (((x) & ((1 << 4) - 1)) << 4)
+#define F_CHANNEL_NUM_CH28_RD(x) (((x) & (((1 << 4) - 1) << 4)) >> 4)
+#define F_WORD_LENGTH_CH28(x) (((x) & ((1 << 4) - 1)) << 8)
+#define F_WORD_LENGTH_CH28_RD(x) (((x) & (((1 << 4) - 1) << 8)) >> 8)
+#define F_SOURCE_NUM_CH29(x) (((x) & ((1 << 4) - 1)) << 12)
+#define F_SOURCE_NUM_CH29_RD(x) (((x) & (((1 << 4) - 1) << 12)) >> 12)
+#define F_CHANNEL_NUM_CH29(x) (((x) & ((1 << 4) - 1)) << 16)
+#define F_CHANNEL_NUM_CH29_RD(x) (((x) & (((1 << 4) - 1) << 16)) >> 16)
+#define F_WORD_LENGTH_CH29(x) (((x) & ((1 << 4) - 1)) << 20)
+#define F_WORD_LENGTH_CH29_RD(x) (((x) & (((1 << 4) - 1) << 20)) >> 20)
+#define F_VALID_BITS29_28(x) (((x) & ((1 << 2) - 1)) << 24)
+#define F_VALID_BITS29_28_RD(x) (((x) & (((1 << 2) - 1) << 24)) >> 24)
+
+/* register STTS_BIT_CH3031 */
+#define STTS_BIT_CH3031 18
+#define F_SOURCE_NUM_CH30(x) (((x) & ((1 << 4) - 1)) << 0)
+#define F_SOURCE_NUM_CH30_RD(x) (((x) & (((1 << 4) - 1) << 0)) >> 0)
+#define F_CHANNEL_NUM_CH30(x) (((x) & ((1 << 4) - 1)) << 4)
+#define F_CHANNEL_NUM_CH30_RD(x) (((x) & (((1 << 4) - 1) << 4)) >> 4)
+#define F_WORD_LENGTH_CH30(x) (((x) & ((1 << 4) - 1)) << 8)
+#define F_WORD_LENGTH_CH30_RD(x) (((x) & (((1 << 4) - 1) << 8)) >> 8)
+#define F_SOURCE_NUM_CH31(x) (((x) & ((1 << 4) - 1)) << 12)
+#define F_SOURCE_NUM_CH31_RD(x) (((x) & (((1 << 4) - 1) << 12)) >> 12)
+#define F_CHANNEL_NUM_CH31(x) (((x) & ((1 << 4) - 1)) << 16)
+#define F_CHANNEL_NUM_CH31_RD(x) (((x) & (((1 << 4) - 1) << 16)) >> 16)
+#define F_WORD_LENGTH_CH31(x) (((x) & ((1 << 4) - 1)) << 20)
+#define F_WORD_LENGTH_CH31_RD(x) (((x) & (((1 << 4) - 1) << 20)) >> 20)
+#define F_VALID_BITS31_30(x) (((x) & ((1 << 2) - 1)) << 24)
+#define F_VALID_BITS31_30_RD(x) (((x) & (((1 << 2) - 1) << 24)) >> 24)
+
+/* register SPDIF_CTRL_ADDR */
+#define SPDIF_CTRL_ADDR 19
+#define F_SPDIF_JITTER_AVG_WIN(x) (((x) & ((1 << 3) - 1)) << 0)
+#define F_SPDIF_JITTER_AVG_WIN_RD(x) (((x) & (((1 << 3) - 1) << 0)) >> 0)
+#define F_SPDIF_JITTER_THRSH(x) (((x) & ((1 << 8) - 1)) << 3)
+#define F_SPDIF_JITTER_THRSH_RD(x) (((x) & (((1 << 8) - 1) << 3)) >> 3)
+#define F_SPDIF_FIFO_MID_RANGE(x) (((x) & ((1 << 8) - 1)) << 11)
+#define F_SPDIF_FIFO_MID_RANGE_RD(x) (((x) & (((1 << 8) - 1) << 11)) >> 11)
+#define F_SPDIF_JITTER_BYPASS(x) (((x) & ((1 << 1) - 1)) << 19)
+#define F_SPDIF_JITTER_BYPASS_RD(x) (((x) & (((1 << 1) - 1) << 19)) >> 19)
+#define F_SPDIF_AVG_SEL(x) (((x) & ((1 << 1) - 1)) << 20)
+#define F_SPDIF_AVG_SEL_RD(x) (((x) & (((1 << 1) - 1) << 20)) >> 20)
+#define F_SPDIF_ENABLE(x) (((x) & ((1 << 1) - 1)) << 21)
+#define F_SPDIF_ENABLE_RD(x) (((x) & (((1 << 1) - 1) << 21)) >> 21)
+#define F_SPDIF_JITTER_STATUS(x) (((x) & ((1 << 4) - 1)) << 22)
+#define F_SPDIF_JITTER_STATUS_RD(x) (((x) & (((1 << 4) - 1) << 22)) >> 22)
+
+/* register SPDIF_CH1_CS_3100_ADDR */
+#define SPDIF_CH1_CS_3100_ADDR 20
+#define F_SPDIF_CH1_ST_STTS_BITS3100(x) (((x) & ((1 << 32) - 1)) << 0)
+#define F_SPDIF_CH1_ST_STTS_BITS3100_RD(x) (((x) & (((1 << 32) - 1) << 0)) >> 0)
+
+/* register SPDIF_CH1_CS_6332_ADDR */
+#define SPDIF_CH1_CS_6332_ADDR 21
+#define F_SPDIF_CH1_ST_STTS_BITS6332(x) (((x) & ((1 << 32) - 1)) << 0)
+#define F_SPDIF_CH1_ST_STTS_BITS6332_RD(x) (((x) & (((1 << 32) - 1) << 0)) >> 0)
+
+/* register SPDIF_CH1_CS_9564_ADDR */
+#define SPDIF_CH1_CS_9564_ADDR 22
+#define F_SPDIF_CH1_ST_STTS_BITS9564(x) (((x) & ((1 << 32) - 1)) << 0)
+#define F_SPDIF_CH1_ST_STTS_BITS9564_RD(x) (((x) & (((1 << 32) - 1) << 0)) >> 0)
+
+/* register SPDIF_CH1_CS_12796_ADDR */
+#define SPDIF_CH1_CS_12796_ADDR 23
+#define F_SPDIF_CH1_ST_STTS_BITS12796(x) (((x) & ((1 << 32) - 1)) << 0)
+#define F_SPDIF_CH1_ST_STTS_BITS12796_RD(x) (((x) & (((1 << 32) - 1) << 0)) >> 0)
+
+/* register SPDIF_CH1_CS_159128_ADDR */
+#define SPDIF_CH1_CS_159128_ADDR 24
+#define F_SPDIF_CH1_ST_STTS_BITS159128(x) (((x) & ((1 << 32) - 1)) << 0)
+#define F_SPDIF_CH1_ST_STTS_BITS159128_RD(x) (((x) & (((1 << 32) - 1) << 0)) >> 0)
+
+/* register SPDIF_CH1_CS_191160_ADDR */
+#define SPDIF_CH1_CS_191160_ADDR 25
+#define F_SPDIF_CH1_ST_STTS_BITS191160(x) (((x) & ((1 << 32) - 1)) << 0)
+#define F_SPDIF_CH1_ST_STTS_BITS191160_RD(x) (((x) & (((1 << 32) - 1) << 0)) >> 0)
+
+/* register SPDIF_CH2_CS_3100_ADDR */
+#define SPDIF_CH2_CS_3100_ADDR 26
+#define F_SPDIF_CH2_ST_STTS_BITS3100(x) (((x) & ((1 << 32) - 1)) << 0)
+#define F_SPDIF_CH2_ST_STTS_BITS3100_RD(x) (((x) & (((1 << 32) - 1) << 0)) >> 0)
+
+/* register SPDIF_CH2_CS_6332_ADDR */
+#define SPDIF_CH2_CS_6332_ADDR 27
+#define F_SPDIF_CH2_ST_STTS_BITS6332(x) (((x) & ((1 << 32) - 1)) << 0)
+#define F_SPDIF_CH2_ST_STTS_BITS6332_RD(x) (((x) & (((1 << 32) - 1) << 0)) >> 0)
+
+/* register SPDIF_CH2_CS_9564_ADDR */
+#define SPDIF_CH2_CS_9564_ADDR 28
+#define F_SPDIF_CH2_ST_STTS_BITS9564(x) (((x) & ((1 << 32) - 1)) << 0)
+#define F_SPDIF_CH2_ST_STTS_BITS9564_RD(x) (((x) & (((1 << 32) - 1) << 0)) >> 0)
+
+/* register SPDIF_CH2_CS_12796_ADDR */
+#define SPDIF_CH2_CS_12796_ADDR 29
+#define F_SPDIF_CH2_ST_STTS_BITS12796(x) (((x) & ((1 << 32) - 1)) << 0)
+#define F_SPDIF_CH2_ST_STTS_BITS12796_RD(x) (((x) & (((1 << 32) - 1) << 0)) >> 0)
+
+/* register SPDIF_CH2_CS_159128_ADDR */
+#define SPDIF_CH2_CS_159128_ADDR 30
+#define F_SPDIF_CH2_ST_STTS_BITS159128(x) (((x) & ((1 << 32) - 1)) << 0)
+#define F_SPDIF_CH2_ST_STTS_BITS159128_RD(x) (((x) & (((1 << 32) - 1) << 0)) >> 0)
+
+/* register SPDIF_CH2_CS_191160_ADDR */
+#define SPDIF_CH2_CS_191160_ADDR 31
+#define F_SPDIF_CH2_ST_STTS_BITS191160(x) (((x) & ((1 << 32) - 1)) << 0)
+#define F_SPDIF_CH2_ST_STTS_BITS191160_RD(x) (((x) & (((1 << 32) - 1) << 0)) >> 0)
+
+#endif //SOURCE_AIF_DECODER
diff --git a/drivers/mxc/hdp/source_aif_smpl2pckt.h b/drivers/mxc/hdp/source_aif_smpl2pckt.h
new file mode 100644
index 000000000000..8721cf432528
--- /dev/null
+++ b/drivers/mxc/hdp/source_aif_smpl2pckt.h
@@ -0,0 +1,113 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2016-2017 Cadence Design Systems, Inc.
+ * All rights reserved worldwide.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 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.
+ *
+ * Copyright 2017 NXP
+ *
+ ******************************************************************************
+ *
+ * This file was auto-generated. Do not edit it manually.
+ *
+ ******************************************************************************
+ *
+ * source_aif_smpl2pckt.h
+ *
+ ******************************************************************************
+ */
+
+#ifndef SOURCE_AIF_SMPL2PCKT_H_
+#define SOURCE_AIF_SMPL2PCKT_H_
+
+/* register SMPL2PKT_CNTL */
+#define SMPL2PKT_CNTL 0
+#define F_SW_RST(x) (((x) & ((1 << 1) - 1)) << 0)
+#define F_SW_RST_RD(x) (((x) & (((1 << 1) - 1) << 0)) >> 0)
+#define F_SMPL2PKT_EN(x) (((x) & ((1 << 1) - 1)) << 1)
+#define F_SMPL2PKT_EN_RD(x) (((x) & (((1 << 1) - 1) << 1)) >> 1)
+
+/* register SMPL2PKT_CNFG */
+#define SMPL2PKT_CNFG 1
+#define F_MAX_NUM_CH(x) (((x) & ((1 << 5) - 1)) << 0)
+#define F_MAX_NUM_CH_RD(x) (((x) & (((1 << 5) - 1) << 0)) >> 0)
+#define F_NUM_OF_I2S_PORTS_S(x) (((x) & ((1 << 2) - 1)) << 5)
+#define F_NUM_OF_I2S_PORTS_RD_S(x) (((x) & (((1 << 2) - 1) << 5)) >> 5)
+#define F_AUDIO_TYPE(x) (((x) & ((1 << 4) - 1)) << 7)
+#define F_AUDIO_TYPE_RD(x) (((x) & (((1 << 4) - 1) << 7)) >> 7)
+#define F_CFG_SUB_PCKT_NUM(x) (((x) & ((1 << 3) - 1)) << 11)
+#define F_CFG_SUB_PCKT_NUM_RD(x) (((x) & (((1 << 3) - 1) << 11)) >> 11)
+#define F_CFG_BLOCK_LPCM_FIRST_PKT(x) (((x) & ((1 << 1) - 1)) << 14)
+#define F_CFG_BLOCK_LPCM_FIRST_PKT_RD(x) (((x) & (((1 << 1) - 1) << 14)) >> 14)
+#define F_CFG_EN_AUTO_SUB_PCKT_NUM(x) (((x) & ((1 << 1) - 1)) << 15)
+#define F_CFG_EN_AUTO_SUB_PCKT_NUM_RD(x) (((x) & (((1 << 1) - 1) << 15)) >> 15)
+#define F_CFG_SAMPLE_PRESENT(x) (((x) & ((1 << 4) - 1)) << 16)
+#define F_CFG_SAMPLE_PRESENT_RD(x) (((x) & (((1 << 4) - 1) << 16)) >> 16)
+#define F_CFG_SAMPLE_PRESENT_FORCE(x) (((x) & ((1 << 1) - 1)) << 20)
+#define F_CFG_SAMPLE_PRESENT_FORCE_RD(x) (((x) & (((1 << 1) - 1) << 20)) >> 20)
+
+/* register FIFO_CNTL */
+#define FIFO_CNTL 2
+#define F_FIFO_SW_RST(x) (((x) & ((1 << 1) - 1)) << 0)
+#define F_FIFO_SW_RST_RD(x) (((x) & (((1 << 1) - 1) << 0)) >> 0)
+#define F_SYNC_WR_TO_CH_ZERO(x) (((x) & ((1 << 1) - 1)) << 1)
+#define F_SYNC_WR_TO_CH_ZERO_RD(x) (((x) & (((1 << 1) - 1) << 1)) >> 1)
+#define F_FIFO_DIR(x) (((x) & ((1 << 1) - 1)) << 2)
+#define F_FIFO_DIR_RD(x) (((x) & (((1 << 1) - 1) << 2)) >> 2)
+#define F_FIFO_EMPTY_CALC(x) (((x) & ((1 << 1) - 1)) << 3)
+#define F_FIFO_EMPTY_CALC_RD(x) (((x) & (((1 << 1) - 1) << 3)) >> 3)
+#define F_CFG_DIS_PORT3(x) (((x) & ((1 << 1) - 1)) << 4)
+#define F_CFG_DIS_PORT3_RD(x) (((x) & (((1 << 1) - 1) << 4)) >> 4)
+
+/* register FIFO_STTS */
+#define FIFO_STTS 3
+#define F_WFULL(x) (((x) & ((1 << 1) - 1)) << 0)
+#define F_WFULL_RD(x) (((x) & (((1 << 1) - 1) << 0)) >> 0)
+#define F_REMPTY(x) (((x) & ((1 << 1) - 1)) << 1)
+#define F_REMPTY_RD(x) (((x) & (((1 << 1) - 1) << 1)) >> 1)
+#define F_OVERRUN(x) (((x) & ((1 << 1) - 1)) << 2)
+#define F_OVERRUN_RD(x) (((x) & (((1 << 1) - 1) << 2)) >> 2)
+#define F_UNDERRUN(x) (((x) & ((1 << 1) - 1)) << 3)
+#define F_UNDERRUN_RD(x) (((x) & (((1 << 1) - 1) << 3)) >> 3)
+
+/* register SUB_PCKT_THRSH */
+#define SUB_PCKT_THRSH 4
+#define F_CFG_MEM_FIFO_THRSH1(x) (((x) & ((1 << 8) - 1)) << 0)
+#define F_CFG_MEM_FIFO_THRSH1_RD(x) (((x) & (((1 << 8) - 1) << 0)) >> 0)
+#define F_CFG_MEM_FIFO_THRSH2(x) (((x) & ((1 << 8) - 1)) << 8)
+#define F_CFG_MEM_FIFO_THRSH2_RD(x) (((x) & (((1 << 8) - 1) << 8)) >> 8)
+#define F_CFG_MEM_FIFO_THRSH3(x) (((x) & ((1 << 8) - 1)) << 16)
+#define F_CFG_MEM_FIFO_THRSH3_RD(x) (((x) & (((1 << 8) - 1) << 16)) >> 16)
+
+#endif //SOURCE_AIF_SMPL2PCKT
diff --git a/drivers/mxc/hdp/source_car.h b/drivers/mxc/hdp/source_car.h
new file mode 100644
index 000000000000..a53f99a08c5f
--- /dev/null
+++ b/drivers/mxc/hdp/source_car.h
@@ -0,0 +1,173 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2016-2017 Cadence Design Systems, Inc.
+ * All rights reserved worldwide.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 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.
+ *
+ * Copyright 2017 NXP
+ *
+ ******************************************************************************
+ *
+ * This file was auto-generated. Do not edit it manually.
+ *
+ ******************************************************************************
+ *
+ * source_car.h
+ *
+ ******************************************************************************
+ */
+
+#ifndef SOURCE_CAR_H_
+#define SOURCE_CAR_H_
+
+/* register SOURCE_HDTX_CAR */
+#define SOURCE_HDTX_CAR 0
+#define F_SOURCE_HDTX_PIXEL_CLK_EN(x) (((x) & ((1 << 1) - 1)) << 0)
+#define F_SOURCE_HDTX_PIXEL_CLK_EN_RD(x) (((x) & (((1 << 1) - 1) << 0)) >> 0)
+#define F_SOURCE_HDTX_PIXEL_RSTN_EN(x) (((x) & ((1 << 1) - 1)) << 1)
+#define F_SOURCE_HDTX_PIXEL_RSTN_EN_RD(x) (((x) & (((1 << 1) - 1) << 1)) >> 1)
+#define F_SOURCE_HDTX_SYS_CLK_EN(x) (((x) & ((1 << 1) - 1)) << 2)
+#define F_SOURCE_HDTX_SYS_CLK_EN_RD(x) (((x) & (((1 << 1) - 1) << 2)) >> 2)
+#define F_SOURCE_HDTX_SYS_CLK_RSTN_EN(x) (((x) & ((1 << 1) - 1)) << 3)
+#define F_SOURCE_HDTX_SYS_CLK_RSTN_EN_RD(x) (((x) & (((1 << 1) - 1) << 3)) >> 3)
+#define F_SOURCE_HDTX_PHY_DATA_CLK_EN(x) (((x) & ((1 << 1) - 1)) << 4)
+#define F_SOURCE_HDTX_PHY_DATA_CLK_EN_RD(x) (((x) & (((1 << 1) - 1) << 4)) >> 4)
+#define F_SOURCE_HDTX_PHY_DATA_RSTN_EN(x) (((x) & ((1 << 1) - 1)) << 5)
+#define F_SOURCE_HDTX_PHY_DATA_RSTN_EN_RD(x) (((x) & (((1 << 1) - 1) << 5)) >> 5)
+#define F_SOURCE_HDTX_PHY_CHAR_CLK_EN(x) (((x) & ((1 << 1) - 1)) << 6)
+#define F_SOURCE_HDTX_PHY_CHAR_CLK_EN_RD(x) (((x) & (((1 << 1) - 1) << 6)) >> 6)
+#define F_SOURCE_HDTX_PHY_CHAR_CLK_RSTN_EN(x) (((x) & ((1 << 1) - 1)) << 7)
+#define F_SOURCE_HDTX_PHY_CHAR_CLK_RSTN_EN_RD(x) (((x) & (((1 << 1) - 1) << 7)) >> 7)
+
+/* register SOURCE_DPTX_CAR */
+#define SOURCE_DPTX_CAR 1
+#define F_SOURCE_CFG_DPTX_VIF_CLK_EN(x) (((x) & ((1 << 1) - 1)) << 0)
+#define F_SOURCE_CFG_DPTX_VIF_CLK_EN_RD(x) (((x) & (((1 << 1) - 1) << 0)) >> 0)
+#define F_SOURCE_CFG_DPTX_VIF_CLK_RSTN_EN(x) (((x) & ((1 << 1) - 1)) << 1)
+#define F_SOURCE_CFG_DPTX_VIF_CLK_RSTN_EN_RD(x) (((x) & (((1 << 1) - 1) << 1)) >> 1)
+#define F_SOURCE_DPTX_SYS_CLK_EN(x) (((x) & ((1 << 1) - 1)) << 2)
+#define F_SOURCE_DPTX_SYS_CLK_EN_RD(x) (((x) & (((1 << 1) - 1) << 2)) >> 2)
+#define F_SOURCE_DPTX_SYS_CLK_RSTN_EN(x) (((x) & ((1 << 1) - 1)) << 3)
+#define F_SOURCE_DPTX_SYS_CLK_RSTN_EN_RD(x) (((x) & (((1 << 1) - 1) << 3)) >> 3)
+#define F_SOURCE_AUX_SYS_CLK_EN(x) (((x) & ((1 << 1) - 1)) << 4)
+#define F_SOURCE_AUX_SYS_CLK_EN_RD(x) (((x) & (((1 << 1) - 1) << 4)) >> 4)
+#define F_SOURCE_AUX_SYS_CLK_RSTN_EN(x) (((x) & ((1 << 1) - 1)) << 5)
+#define F_SOURCE_AUX_SYS_CLK_RSTN_EN_RD(x) (((x) & (((1 << 1) - 1) << 5)) >> 5)
+#define F_SOUrcE_DPTX_PHY_CHAR_CLK_EN(x) (((x) & ((1 << 1) - 1)) << 6)
+#define F_SOUrcE_DPTX_PHY_CHAR_CLK_EN_RD(x) (((x) & (((1 << 1) - 1) << 6)) >> 6)
+#define F_SOUrcE_DPTX_PHY_CHAR_RSTN_EN(x) (((x) & ((1 << 1) - 1)) << 7)
+#define F_SOUrcE_DPTX_PHY_CHAR_RSTN_EN_RD(x) (((x) & (((1 << 1) - 1) << 7)) >> 7)
+#define F_SOUrcE_DPTX_PHY_DATA_CLK_EN(x) (((x) & ((1 << 1) - 1)) << 8)
+#define F_SOUrcE_DPTX_PHY_DATA_CLK_EN_RD(x) (((x) & (((1 << 1) - 1) << 8)) >> 8)
+#define F_SOUrcE_DPTX_PHY_DATA_RSTN_EN(x) (((x) & ((1 << 1) - 1)) << 9)
+#define F_SOUrcE_DPTX_PHY_DATA_RSTN_EN_RD(x) (((x) & (((1 << 1) - 1) << 9)) >> 9)
+#define F_SOUrcE_DPTX_FRMR_DATA_CLK_EN(x) (((x) & ((1 << 1) - 1)) << 10)
+#define F_SOUrcE_DPTX_FRMR_DATA_CLK_EN_RD(x) (((x) & (((1 << 1) - 1) << 10)) >> 10)
+#define F_SOUrcE_DPTX_FRMR_DATA_CLK_RSTN_EN(x) (((x) & ((1 << 1) - 1)) << 11)
+#define F_SOUrcE_DPTX_FRMR_DATA_CLK_RSTN_EN_RD(x) (((x) & (((1 << 1) - 1) << 11)) >> 11)
+
+/* register SOURCE_PHY_CAR */
+#define SOURCE_PHY_CAR 2
+#define F_SOURCE_PHY_DATA_OUT_CLK_EN(x) (((x) & ((1 << 1) - 1)) << 0)
+#define F_SOURCE_PHY_DATA_OUT_CLK_EN_RD(x) (((x) & (((1 << 1) - 1) << 0)) >> 0)
+#define F_SOURCE_PHY_DATA_OUT_CLK_RSTN_EN(x) (((x) & ((1 << 1) - 1)) << 1)
+#define F_SOURCE_PHY_DATA_OUT_CLK_RSTN_EN_RD(x) (((x) & (((1 << 1) - 1) << 1)) >> 1)
+#define F_SOURCE_PHY_CHAR_OUT_CLK_EN(x) (((x) & ((1 << 1) - 1)) << 2)
+#define F_SOURCE_PHY_CHAR_OUT_CLK_EN_RD(x) (((x) & (((1 << 1) - 1) << 2)) >> 2)
+#define F_SOURCE_PHY_CHAR_OUT_CLK_RSTN_EN(x) (((x) & ((1 << 1) - 1)) << 3)
+#define F_SOURCE_PHY_CHAR_OUT_CLK_RSTN_EN_RD(x) (((x) & (((1 << 1) - 1) << 3)) >> 3)
+
+/* register SOURCE_CEC_CAR */
+#define SOURCE_CEC_CAR 3
+#define F_SOURCE_CEC_SYS_CLK_EN(x) (((x) & ((1 << 1) - 1)) << 0)
+#define F_SOURCE_CEC_SYS_CLK_EN_RD(x) (((x) & (((1 << 1) - 1) << 0)) >> 0)
+#define F_SOURCE_CEC_SYS_CLK_RSTN_EN(x) (((x) & ((1 << 1) - 1)) << 1)
+#define F_SOURCE_CEC_SYS_CLK_RSTN_EN_RD(x) (((x) & (((1 << 1) - 1) << 1)) >> 1)
+
+/* register SOURCE_CBUS_CAR */
+#define SOURCE_CBUS_CAR 4
+#define F_SOURCE_CBUS_SYS_CLK_EN(x) (((x) & ((1 << 1) - 1)) << 0)
+#define F_SOURCE_CBUS_SYS_CLK_EN_RD(x) (((x) & (((1 << 1) - 1) << 0)) >> 0)
+#define F_SOURCE_CBUS_SYS_CLK_RSTN_EN(x) (((x) & ((1 << 1) - 1)) << 1)
+#define F_SOURCE_CBUS_SYS_CLK_RSTN_EN_RD(x) (((x) & (((1 << 1) - 1) << 1)) >> 1)
+
+/* register SOURCE_PKT_CAR */
+#define SOURCE_PKT_CAR 6
+#define F_SOURCE_PKT_DATA_CLK_EN(x) (((x) & ((1 << 1) - 1)) << 0)
+#define F_SOURCE_PKT_DATA_CLK_EN_RD(x) (((x) & (((1 << 1) - 1) << 0)) >> 0)
+#define F_SOURCE_PKT_DATA_RSTN_EN(x) (((x) & ((1 << 1) - 1)) << 1)
+#define F_SOURCE_PKT_DATA_RSTN_EN_RD(x) (((x) & (((1 << 1) - 1) << 1)) >> 1)
+#define F_SOURCE_PKT_SYS_CLK_EN(x) (((x) & ((1 << 1) - 1)) << 2)
+#define F_SOURCE_PKT_SYS_CLK_EN_RD(x) (((x) & (((1 << 1) - 1) << 2)) >> 2)
+#define F_SOURCE_PKT_SYS_RSTN_EN(x) (((x) & ((1 << 1) - 1)) << 3)
+#define F_SOURCE_PKT_SYS_RSTN_EN_RD(x) (((x) & (((1 << 1) - 1) << 3)) >> 3)
+
+/* register SOURCE_AIF_CAR */
+#define SOURCE_AIF_CAR 7
+#define F_SOURCE_AIF_PKT_CLK_EN(x) (((x) & ((1 << 1) - 1)) << 0)
+#define F_SOURCE_AIF_PKT_CLK_EN_RD(x) (((x) & (((1 << 1) - 1) << 0)) >> 0)
+#define F_SOURCE_AIF_PKT_CLK_RSTN_EN(x) (((x) & ((1 << 1) - 1)) << 1)
+#define F_SOURCE_AIF_PKT_CLK_RSTN_EN_RD(x) (((x) & (((1 << 1) - 1) << 1)) >> 1)
+#define F_SOURCE_AIF_SYS_CLK_EN(x) (((x) & ((1 << 1) - 1)) << 2)
+#define F_SOURCE_AIF_SYS_CLK_EN_RD(x) (((x) & (((1 << 1) - 1) << 2)) >> 2)
+#define F_SOURCE_AIF_SYS_RSTN_EN(x) (((x) & ((1 << 1) - 1)) << 3)
+#define F_SOURCE_AIF_SYS_RSTN_EN_RD(x) (((x) & (((1 << 1) - 1) << 3)) >> 3)
+#define F_SOURCE_SPDIF_CDR_CLK_EN(x) (((x) & ((1 << 1) - 1)) << 4)
+#define F_SOURCE_SPDIF_CDR_CLK_EN_RD(x) (((x) & (((1 << 1) - 1) << 4)) >> 4)
+#define F_SOURCE_SPDIF_CDR_CLK_RSTN_EN(x) (((x) & ((1 << 1) - 1)) << 5)
+#define F_SOURCE_SPDIF_CDR_CLK_RSTN_EN_RD(x) (((x) & (((1 << 1) - 1) << 5)) >> 5)
+#define F_SOURCE_SPDIF_MCLK_EN(x) (((x) & ((1 << 1) - 1)) << 6)
+#define F_SOURCE_SPDIF_MCLK_EN_RD(x) (((x) & (((1 << 1) - 1) << 6)) >> 6)
+#define F_SOURCE_SPDIF_MCLK_RSTN_EN(x) (((x) & ((1 << 1) - 1)) << 7)
+#define F_SOURCE_SPDIF_MCLK_RSTN_EN_RD(x) (((x) & (((1 << 1) - 1) << 7)) >> 7)
+
+/* register SOURCE_CIPHER_CAR */
+#define SOURCE_CIPHER_CAR 8
+#define F_SOURCE_CIPHER_CHAR_CLK_EN(x) (((x) & ((1 << 1) - 1)) << 0)
+#define F_SOURCE_CIPHER_CHAR_CLK_EN_RD(x) (((x) & (((1 << 1) - 1) << 0)) >> 0)
+#define F_SOURCE_CIPHER_CHAR_CLK_RSTN_EN(x) (((x) & ((1 << 1) - 1)) << 1)
+#define F_SOURCE_CIPHER_CHAR_CLK_RSTN_EN_RD(x) (((x) & (((1 << 1) - 1) << 1)) >> 1)
+#define F_SOURCE_CIPHER_SYS_CLK_EN(x) (((x) & ((1 << 1) - 1)) << 2)
+#define F_SOURCE_CIPHER_SYS_CLK_EN_RD(x) (((x) & (((1 << 1) - 1) << 2)) >> 2)
+#define F_SOURCE_CIPHER_SYSTEM_CLK_RSTN_EN(x) (((x) & ((1 << 1) - 1)) << 3)
+#define F_SOURCE_CIPHER_SYSTEM_CLK_RSTN_EN_RD(x) (((x) & (((1 << 1) - 1) << 3)) >> 3)
+
+/* register SOURCE_CRYPTO_CAR */
+#define SOURCE_CRYPTO_CAR 9
+#define F_SOURCE_CRYPTO_SYS_CLK_EN(x) (((x) & ((1 << 1) - 1)) << 0)
+#define F_SOURCE_CRYPTO_SYS_CLK_EN_RD(x) (((x) & (((1 << 1) - 1) << 0)) >> 0)
+#define F_SOURCE_CRYPTO_SYS_CLK_RSTN_EN(x) (((x) & ((1 << 1) - 1)) << 1)
+#define F_SOURCE_CRYPTO_SYS_CLK_RSTN_EN_RD(x) (((x) & (((1 << 1) - 1) << 1)) >> 1)
+
+#endif /* SOURCE_CAR */
diff --git a/drivers/mxc/hdp/source_phy.h b/drivers/mxc/hdp/source_phy.h
new file mode 100644
index 000000000000..40fd427db71f
--- /dev/null
+++ b/drivers/mxc/hdp/source_phy.h
@@ -0,0 +1,180 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2016-2017 Cadence Design Systems, Inc.
+ * All rights reserved worldwide.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 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.
+ *
+ * Copyright 2017 NXP
+ *
+ ******************************************************************************
+ *
+ * This file was auto-generated. Do not edit it manually.
+ *
+ ******************************************************************************
+ *
+ * source_phy.h
+ *
+ ******************************************************************************
+ */
+
+#ifndef SOURCE_PHY_H_
+#define SOURCE_PHY_H_
+
+/* register SHIFT_PATTERN_IN_3_0 */
+#define SHIFT_PATTERN_IN_3_0 0
+#define F_SOURCE_PHY_SHIFT_PATTERN0(x) (((x) & ((1 << 8) - 1)) << 0)
+#define F_SOURCE_PHY_SHIFT_PATTERN0_RD(x) (((x) & (((1 << 8) - 1) << 0)) >> 0)
+#define F_SOURCE_PHY_SHIFT_PATTERN1(x) (((x) & ((1 << 8) - 1)) << 8)
+#define F_SOURCE_PHY_SHIFT_PATTERN1_RD(x) (((x) & (((1 << 8) - 1) << 8)) >> 8)
+#define F_SOURCE_PHY_SHIFT_PATTERN2(x) (((x) & ((1 << 8) - 1)) << 16)
+#define F_SOURCE_PHY_SHIFT_PATTERN2_RD(x) (((x) & (((1 << 8) - 1) << 16)) >> 16)
+#define F_SOURCE_PHY_SHIFT_PATTERN3(x) (((x) & ((1 << 8) - 1)) << 24)
+#define F_SOURCE_PHY_SHIFT_PATTERN3_RD(x) (((x) & (((1 << 8) - 1) << 24)) >> 24)
+
+/* register SHIFT_PATTERN_IN_4_7 */
+#define SHIFT_PATTERN_IN_4_7 1
+#define F_SOURCE_PHY_SHIFT_PATTERN4(x) (((x) & ((1 << 8) - 1)) << 0)
+#define F_SOURCE_PHY_SHIFT_PATTERN4_RD(x) (((x) & (((1 << 8) - 1) << 0)) >> 0)
+#define F_SOURCE_PHY_SHIFT_PATTERN5(x) (((x) & ((1 << 8) - 1)) << 8)
+#define F_SOURCE_PHY_SHIFT_PATTERN5_RD(x) (((x) & (((1 << 8) - 1) << 8)) >> 8)
+#define F_SOURCE_PHY_SHIFT_PATTERN6(x) (((x) & ((1 << 8) - 1)) << 16)
+#define F_SOURCE_PHY_SHIFT_PATTERN6_RD(x) (((x) & (((1 << 8) - 1) << 16)) >> 16)
+#define F_SOURCE_PHY_SHIFT_PATTERN7(x) (((x) & ((1 << 8) - 1)) << 24)
+#define F_SOURCE_PHY_SHIFT_PATTERN7_RD(x) (((x) & (((1 << 8) - 1) << 24)) >> 24)
+
+/* register SHIFT_PATTERN_IN9_8 */
+#define SHIFT_PATTERN_IN9_8 2
+#define F_SOURCE_PHY_SHIFT_PATTERN8(x) (((x) & ((1 << 8) - 1)) << 0)
+#define F_SOURCE_PHY_SHIFT_PATTERN8_RD(x) (((x) & (((1 << 8) - 1) << 0)) >> 0)
+#define F_SOURCE_PHY_SHIFT_PATTERN9(x) (((x) & ((1 << 8) - 1)) << 8)
+#define F_SOURCE_PHY_SHIFT_PATTERN9_RD(x) (((x) & (((1 << 8) - 1) << 8)) >> 8)
+#define F_SOURCE_PHY_SHIFT_LOAD(x) (((x) & ((1 << 1) - 1)) << 16)
+#define F_SOURCE_PHY_SHIFT_LOAD_RD(x) (((x) & (((1 << 1) - 1) << 16)) >> 16)
+#define F_SOURCE_PHY_SHIFT_EN(x) (((x) & ((1 << 1) - 1)) << 17)
+#define F_SOURCE_PHY_SHIFT_EN_RD(x) (((x) & (((1 << 1) - 1) << 17)) >> 17)
+#define F_SOURCE_PHY_SHIFT_REPETITION(x) (((x) & ((1 << 3) - 1)) << 18)
+#define F_SOURCE_PHY_SHIFT_REPETITION_RD(x) (((x) & (((1 << 3) - 1) << 18)) >> 18)
+
+/* register PRBS_CNTRL */
+#define PRBS_CNTRL 3
+#define F_SOURCE_PHY_PRBS0_MODE(x) (((x) & ((1 << 2) - 1)) << 0)
+#define F_SOURCE_PHY_PRBS0_MODE_RD(x) (((x) & (((1 << 2) - 1) << 0)) >> 0)
+#define F_SOURCE_PHY_PRBS0_OUT_MODE(x) (((x) & ((1 << 2) - 1)) << 2)
+#define F_SOURCE_PHY_PRBS0_OUT_MODE_RD(x) (((x) & (((1 << 2) - 1) << 2)) >> 2)
+#define F_SOURCE_PHY_PRBS1_MODE(x) (((x) & ((1 << 2) - 1)) << 4)
+#define F_SOURCE_PHY_PRBS1_MODE_RD(x) (((x) & (((1 << 2) - 1) << 4)) >> 4)
+#define F_SOURCE_PHY_PRBS1_OUT_MODE(x) (((x) & ((1 << 2) - 1)) << 6)
+#define F_SOURCE_PHY_PRBS1_OUT_MODE_RD(x) (((x) & (((1 << 2) - 1) << 6)) >> 6)
+#define F_SOURCE_PHY_PRBS2_MODE(x) (((x) & ((1 << 2) - 1)) << 8)
+#define F_SOURCE_PHY_PRBS2_MODE_RD(x) (((x) & (((1 << 2) - 1) << 8)) >> 8)
+#define F_SOURCE_PHY_PRBS2_OUT_MODE(x) (((x) & ((1 << 2) - 1)) << 10)
+#define F_SOURCE_PHY_PRBS2_OUT_MODE_RD(x) (((x) & (((1 << 2) - 1) << 10)) >> 10)
+#define F_SOURCE_PHY_PRBS3_MODE(x) (((x) & ((1 << 2) - 1)) << 12)
+#define F_SOURCE_PHY_PRBS3_MODE_RD(x) (((x) & (((1 << 2) - 1) << 12)) >> 12)
+#define F_SOURCE_PHY_PRBS3_OUT_MODE(x) (((x) & ((1 << 2) - 1)) << 14)
+#define F_SOURCE_PHY_PRBS3_OUT_MODE_RD(x) (((x) & (((1 << 2) - 1) << 14)) >> 14)
+
+/* register PRBS_ERR_INSERTION */
+#define PRBS_ERR_INSERTION 4
+#define F_ADD_ERROR0(x) (((x) & ((1 << 1) - 1)) << 0)
+#define F_ADD_ERROR0_RD(x) (((x) & (((1 << 1) - 1) << 0)) >> 0)
+#define F_NUMBER_OF_ERRORS0(x) (((x) & ((1 << 5) - 1)) << 1)
+#define F_NUMBER_OF_ERRORS0_RD(x) (((x) & (((1 << 5) - 1) << 1)) >> 1)
+#define F_ADD_ERROR1(x) (((x) & ((1 << 1) - 1)) << 6)
+#define F_ADD_ERROR1_RD(x) (((x) & (((1 << 1) - 1) << 6)) >> 6)
+#define F_NUMBER_OF_ERRORS1(x) (((x) & ((1 << 5) - 1)) << 7)
+#define F_NUMBER_OF_ERRORS1_RD(x) (((x) & (((1 << 5) - 1) << 7)) >> 7)
+#define F_ADD_ERROR2(x) (((x) & ((1 << 1) - 1)) << 12)
+#define F_ADD_ERROR2_RD(x) (((x) & (((1 << 1) - 1) << 12)) >> 12)
+#define F_NUMBER_OF_ERRORS2(x) (((x) & ((1 << 5) - 1)) << 13)
+#define F_NUMBER_OF_ERRORS2_RD(x) (((x) & (((1 << 5) - 1) << 13)) >> 13)
+#define F_ADD_ERROR3(x) (((x) & ((1 << 1) - 1)) << 18)
+#define F_ADD_ERROR3_RD(x) (((x) & (((1 << 1) - 1) << 18)) >> 18)
+#define F_NUMBER_OF_ERRORS3(x) (((x) & ((1 << 5) - 1)) << 19)
+#define F_NUMBER_OF_ERRORS3_RD(x) (((x) & (((1 << 5) - 1) << 19)) >> 19)
+
+/* register LANES_CONFIG */
+#define LANES_CONFIG 5
+#define F_SOURCE_PHY_LANE0_SWAP(x) (((x) & ((1 << 2) - 1)) << 0)
+#define F_SOURCE_PHY_LANE0_SWAP_RD(x) (((x) & (((1 << 2) - 1) << 0)) >> 0)
+#define F_SOURCE_PHY_LANE1_SWAP(x) (((x) & ((1 << 2) - 1)) << 2)
+#define F_SOURCE_PHY_LANE1_SWAP_RD(x) (((x) & (((1 << 2) - 1) << 2)) >> 2)
+#define F_SOURCE_PHY_LANE2_SWAP(x) (((x) & ((1 << 2) - 1)) << 4)
+#define F_SOURCE_PHY_LANE2_SWAP_RD(x) (((x) & (((1 << 2) - 1) << 4)) >> 4)
+#define F_SOURCE_PHY_LANE3_SWAP(x) (((x) & ((1 << 2) - 1)) << 6)
+#define F_SOURCE_PHY_LANE3_SWAP_RD(x) (((x) & (((1 << 2) - 1) << 6)) >> 6)
+#define F_SOURCE_PHY_LANE0_LSB_MSB(x) (((x) & ((1 << 1) - 1)) << 8)
+#define F_SOURCE_PHY_LANE0_LSB_MSB_RD(x) (((x) & (((1 << 1) - 1) << 8)) >> 8)
+#define F_SOURCE_PHY_LANE1_LSB_MSB(x) (((x) & ((1 << 1) - 1)) << 9)
+#define F_SOURCE_PHY_LANE1_LSB_MSB_RD(x) (((x) & (((1 << 1) - 1) << 9)) >> 9)
+#define F_SOURCE_PHY_LANE2_LSB_MSB(x) (((x) & ((1 << 1) - 1)) << 10)
+#define F_SOURCE_PHY_LANE2_LSB_MSB_RD(x) (((x) & (((1 << 1) - 1) << 10)) >> 10)
+#define F_SOURCE_PHY_LANE3_LSB_MSB(x) (((x) & ((1 << 1) - 1)) << 11)
+#define F_SOURCE_PHY_LANE3_LSB_MSB_RD(x) (((x) & (((1 << 1) - 1) << 11)) >> 11)
+#define F_SOURCE_PHY_AUX_SPARE(x) (((x) & ((1 << 4) - 1)) << 12)
+#define F_SOURCE_PHY_AUX_SPARE_RD(x) (((x) & (((1 << 4) - 1) << 12)) >> 12)
+#define F_SOURCE_PHY_LANE0_POLARITY(x) (((x) & ((1 << 1) - 1)) << 16)
+#define F_SOURCE_PHY_LANE0_POLARITY_RD(x) (((x) & (((1 << 1) - 1) << 16)) >> 16)
+#define F_SOURCE_PHY_LANE1_POLARITY(x) (((x) & ((1 << 1) - 1)) << 17)
+#define F_SOURCE_PHY_LANE1_POLARITY_RD(x) (((x) & (((1 << 1) - 1) << 17)) >> 17)
+#define F_SOURCE_PHY_LANE2_POLARITY(x) (((x) & ((1 << 1) - 1)) << 18)
+#define F_SOURCE_PHY_LANE2_POLARITY_RD(x) (((x) & (((1 << 1) - 1) << 18)) >> 18)
+#define F_SOURCE_PHY_LANE3_POLARITY(x) (((x) & ((1 << 1) - 1)) << 19)
+#define F_SOURCE_PHY_LANE3_POLARITY_RD(x) (((x) & (((1 << 1) - 1) << 19)) >> 19)
+#define F_SOURCE_PHY_DATA_DEL_EN(x) (((x) & ((1 << 1) - 1)) << 20)
+#define F_SOURCE_PHY_DATA_DEL_EN_RD(x) (((x) & (((1 << 1) - 1) << 20)) >> 20)
+#define F_SOURCE_PHY_COMB_BYPASS(x) (((x) & ((1 << 1) - 1)) << 21)
+#define F_SOURCE_PHY_COMB_BYPASS_RD(x) (((x) & (((1 << 1) - 1) << 21)) >> 21)
+#define F_SOURCE_PHY_20_10(x) (((x) & ((1 << 1) - 1)) << 22)
+#define F_SOURCE_PHY_20_10_RD(x) (((x) & (((1 << 1) - 1) << 22)) >> 22)
+
+/* register PHY_DATA_SEL */
+#define PHY_DATA_SEL 6
+#define F_SOURCE_PHY_DATA_SEL(x) (((x) & ((1 << 3) - 1)) << 0)
+#define F_SOURCE_PHY_DATA_SEL_RD(x) (((x) & (((1 << 3) - 1) << 0)) >> 0)
+#define F_SOURCE_PHY_MHDP_SEL(x) (((x) & ((1 << 2) - 1)) << 3)
+#define F_SOURCE_PHY_MHDP_SEL_RD(x) (((x) & (((1 << 2) - 1) << 3)) >> 3)
+
+/* register LANES_DEL_VAL */
+#define LANES_DEL_VAL 7
+#define F_SOURCE_PHY_LANE0_DEL_VAL(x) (((x) & ((1 << 4) - 1)) << 0)
+#define F_SOURCE_PHY_LANE0_DEL_VAL_RD(x) (((x) & (((1 << 4) - 1) << 0)) >> 0)
+#define F_SOURCE_PHY_LANE1_DEL_VAL(x) (((x) & ((1 << 4) - 1)) << 4)
+#define F_SOURCE_PHY_LANE1_DEL_VAL_RD(x) (((x) & (((1 << 4) - 1) << 4)) >> 4)
+#define F_SOURCE_PHY_LANE2_DEL_VAL(x) (((x) & ((1 << 4) - 1)) << 8)
+#define F_SOURCE_PHY_LANE2_DEL_VAL_RD(x) (((x) & (((1 << 4) - 1) << 8)) >> 8)
+#define F_SOURCE_PHY_LANE3_DEL_VAL(x) (((x) & ((1 << 4) - 1)) << 12)
+#define F_SOURCE_PHY_LANE3_DEL_VAL_RD(x) (((x) & (((1 << 4) - 1) << 12)) >> 12)
+
+#endif //SOURCE_PHY
diff --git a/drivers/mxc/hdp/source_pif.h b/drivers/mxc/hdp/source_pif.h
new file mode 100644
index 000000000000..ed6c66aa611e
--- /dev/null
+++ b/drivers/mxc/hdp/source_pif.h
@@ -0,0 +1,170 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2016-2017 Cadence Design Systems, Inc.
+ * All rights reserved worldwide.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 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.
+ *
+ * Copyright 2017 NXP
+ *
+ ******************************************************************************
+ *
+ * This file was auto-generated. Do not edit it manually.
+ *
+ ******************************************************************************
+ *
+ * source_pif.h
+ *
+ ******************************************************************************
+ */
+
+#ifndef SOURCE_PIF_H_
+#define SOURCE_PIF_H_
+
+/* register SOURCE_PIF_WR_ADDR */
+#define SOURCE_PIF_WR_ADDR 0
+#define F_WR_ADDR(x) (((x) & ((1 << 4) - 1)) << 0)
+#define F_WR_ADDR_RD(x) (((x) & (((1 << 4) - 1) << 0)) >> 0)
+
+/* register SOURCE_PIF_WR_REQ */
+#define SOURCE_PIF_WR_REQ 1
+#define F_HOST_WR(x) (((x) & ((1 << 1) - 1)) << 0)
+#define F_HOST_WR_RD(x) (((x) & (((1 << 1) - 1) << 0)) >> 0)
+
+/* register SOURCE_PIF_RD_ADDR */
+#define SOURCE_PIF_RD_ADDR 2
+#define F_RD_ADDR(x) (((x) & ((1 << 4) - 1)) << 0)
+#define F_RD_ADDR_RD(x) (((x) & (((1 << 4) - 1) << 0)) >> 0)
+
+/* register SOURCE_PIF_RD_REQ */
+#define SOURCE_PIF_RD_REQ 3
+#define F_HOST_RD(x) (((x) & ((1 << 1) - 1)) << 0)
+#define F_HOST_RD_RD(x) (((x) & (((1 << 1) - 1) << 0)) >> 0)
+
+/* register SOURCE_PIF_DATA_WR */
+#define SOURCE_PIF_DATA_WR 4
+#define F_DATA_WR(x) (x)
+#define F_DATA_WR_RD(x) (x)
+
+/* register SOURCE_PIF_DATA_RD */
+#define SOURCE_PIF_DATA_RD 5
+#define F_FIFO2_DATA_OUT(x) (x)
+#define F_FIFO2_DATA_OUT_RD(x) (x)
+
+/* register SOURCE_PIF_FIFO1_FLUSH */
+#define SOURCE_PIF_FIFO1_FLUSH 6
+#define F_FIFO1_FLUSH(x) (((x) & ((1 << 1) - 1)) << 0)
+#define F_FIFO1_FLUSH_RD(x) (((x) & (((1 << 1) - 1) << 0)) >> 0)
+
+/* register SOURCE_PIF_FIFO2_FLUSH */
+#define SOURCE_PIF_FIFO2_FLUSH 7
+#define F_FIFO2_FLUSH(x) (((x) & ((1 << 1) - 1)) << 0)
+#define F_FIFO2_FLUSH_RD(x) (((x) & (((1 << 1) - 1) << 0)) >> 0)
+
+/* register SOURCE_PIF_STATUS */
+#define SOURCE_PIF_STATUS 8
+#define F_SOURCE_PKT_MEM_CTRL_FSM_STATE(x) (((x) & ((1 << 2) - 1)) << 0)
+#define F_SOURCE_PKT_MEM_CTRL_FSM_STATE_RD(x) (((x) & (((1 << 2) - 1) << 0)) >> 0)
+#define F_FIFO1_FULL(x) (((x) & ((1 << 1) - 1)) << 2)
+#define F_FIFO1_FULL_RD(x) (((x) & (((1 << 1) - 1) << 2)) >> 2)
+#define F_FIFO2_EMPTY(x) (((x) & ((1 << 1) - 1)) << 3)
+#define F_FIFO2_EMPTY_RD(x) (((x) & (((1 << 1) - 1) << 3)) >> 3)
+
+/* register SOURCE_PIF_INTERRUPT_SOURCE */
+#define SOURCE_PIF_INTERRUPT_SOURCE 9
+#define F_HOST_WR_DONE_INT(x) (((x) & ((1 << 1) - 1)) << 0)
+#define F_HOST_WR_DONE_INT_RD(x) (((x) & (((1 << 1) - 1) << 0)) >> 0)
+#define F_HOST_RD_DONE_INT(x) (((x) & ((1 << 1) - 1)) << 1)
+#define F_HOST_RD_DONE_INT_RD(x) (((x) & (((1 << 1) - 1) << 1)) >> 1)
+#define F_NONVALID_TYPE_REQUESTED_INT(x) (((x) & ((1 << 1) - 1)) << 2)
+#define F_NONVALID_TYPE_REQUESTED_INT_RD(x) (((x) & (((1 << 1) - 1) << 2)) >> 2)
+#define F_PSLVERR(x) (((x) & ((1 << 1) - 1)) << 3)
+#define F_PSLVERR_RD(x) (((x) & (((1 << 1) - 1) << 3)) >> 3)
+#define F_ALLOC_WR_DONE(x) (((x) & ((1 << 1) - 1)) << 4)
+#define F_ALLOC_WR_DONE_RD(x) (((x) & (((1 << 1) - 1) << 4)) >> 4)
+#define F_ALLOC_WR_ERROR(x) (((x) & ((1 << 1) - 1)) << 5)
+#define F_ALLOC_WR_ERROR_RD(x) (((x) & (((1 << 1) - 1) << 5)) >> 5)
+#define F_FIFO1_OVERFLOW(x) (((x) & ((1 << 1) - 1)) << 6)
+#define F_FIFO1_OVERFLOW_RD(x) (((x) & (((1 << 1) - 1) << 6)) >> 6)
+#define F_FIFO1_UNDERFLOW(x) (((x) & ((1 << 1) - 1)) << 7)
+#define F_FIFO1_UNDERFLOW_RD(x) (((x) & (((1 << 1) - 1) << 7)) >> 7)
+#define F_FIFO2_OVERFLOW(x) (((x) & ((1 << 1) - 1)) << 8)
+#define F_FIFO2_OVERFLOW_RD(x) (((x) & (((1 << 1) - 1) << 8)) >> 8)
+#define F_FIFO2_UNDERFLOW(x) (((x) & ((1 << 1) - 1)) << 9)
+#define F_FIFO2_UNDERFLOW_RD(x) (((x) & (((1 << 1) - 1) << 9)) >> 9)
+
+/* register SOURCE_PIF_INTERRUPT_MASK */
+#define SOURCE_PIF_INTERRUPT_MASK 10
+#define F_HOST_WR_DONE_INT_MASK(x) (((x) & ((1 << 1) - 1)) << 0)
+#define F_HOST_WR_DONE_INT_MASK_RD(x) (((x) & (((1 << 1) - 1) << 0)) >> 0)
+#define F_HOST_RD_DONE_INT_MASK(x) (((x) & ((1 << 1) - 1)) << 1)
+#define F_HOST_RD_DONE_INT_MASK_RD(x) (((x) & (((1 << 1) - 1) << 1)) >> 1)
+#define F_NONVALID_TYPE_REQUESTED_INT_MASK(x) (((x) & ((1 << 1) - 1)) << 2)
+#define F_NONVALID_TYPE_REQUESTED_INT_MASK_RD(x) (((x) & (((1 << 1) - 1) << 2)) >> 2)
+#define F_PSLVERR_MASK(x) (((x) & ((1 << 1) - 1)) << 3)
+#define F_PSLVERR_MASK_RD(x) (((x) & (((1 << 1) - 1) << 3)) >> 3)
+#define F_ALLOC_WR_DONE_MASK(x) (((x) & ((1 << 1) - 1)) << 4)
+#define F_ALLOC_WR_DONE_MASK_RD(x) (((x) & (((1 << 1) - 1) << 4)) >> 4)
+#define F_ALLOC_WR_ERROR_MASK(x) (((x) & ((1 << 1) - 1)) << 5)
+#define F_ALLOC_WR_ERROR_MASK_RD(x) (((x) & (((1 << 1) - 1) << 5)) >> 5)
+#define F_FIFO1_OVERFLOW_MASK(x) (((x) & ((1 << 1) - 1)) << 6)
+#define F_FIFO1_OVERFLOW_MASK_RD(x) (((x) & (((1 << 1) - 1) << 6)) >> 6)
+#define F_FIFO1_UNDERFLOW_MASK(x) (((x) & ((1 << 1) - 1)) << 7)
+#define F_FIFO1_UNDERFLOW_MASK_RD(x) (((x) & (((1 << 1) - 1) << 7)) >> 7)
+#define F_FIFO2_OVERFLOW_MASK(x) (((x) & ((1 << 1) - 1)) << 8)
+#define F_FIFO2_OVERFLOW_MASK_RD(x) (((x) & (((1 << 1) - 1) << 8)) >> 8)
+#define F_FIFO2_UNDERFLOW_MASK(x) (((x) & ((1 << 1) - 1)) << 9)
+#define F_FIFO2_UNDERFLOW_MASK_RD(x) (((x) & (((1 << 1) - 1) << 9)) >> 9)
+
+/* register SOURCE_PIF_PKT_ALLOC_REG */
+#define SOURCE_PIF_PKT_ALLOC_REG 11
+#define F_PKT_ALLOC_ADDRESS(x) (((x) & ((1 << 4) - 1)) << 0)
+#define F_PKT_ALLOC_ADDRESS_RD(x) (((x) & (((1 << 4) - 1) << 0)) >> 0)
+#define F_PACKET_TYPE(x) (((x) & ((1 << 8) - 1)) << 8)
+#define F_PACKET_TYPE_RD(x) (((x) & (((1 << 8) - 1) << 8)) >> 8)
+#define F_TYPE_VALID(x) (((x) & ((1 << 1) - 1)) << 16)
+#define F_TYPE_VALID_RD(x) (((x) & (((1 << 1) - 1) << 16)) >> 16)
+#define F_ACTIVE_IDLE_TYPE(x) (((x) & ((1 << 1) - 1)) << 17)
+#define F_ACTIVE_IDLE_TYPE_RD(x) (((x) & (((1 << 1) - 1) << 17)) >> 17)
+
+/* register SOURCE_PIF_PKT_ALLOC_WR_EN */
+#define SOURCE_PIF_PKT_ALLOC_WR_EN 12
+#define F_PKT_ALLOC_WR_EN(x) (((x) & ((1 << 1) - 1)) << 0)
+#define F_PKT_ALLOC_WR_EN_RD(x) (((x) & (((1 << 1) - 1) << 0)) >> 0)
+
+/* register SOURCE_PIF_SW_RESET */
+#define SOURCE_PIF_SW_RESET 13
+#define F_SW_RST(x) (((x) & ((1 << 1) - 1)) << 0)
+#define F_SW_RST_RD(x) (((x) & (((1 << 1) - 1) << 0)) >> 0)
+
+#endif //SOURCE_PIF
diff --git a/drivers/mxc/hdp/source_vif.h b/drivers/mxc/hdp/source_vif.h
new file mode 100644
index 000000000000..8281f9bcb282
--- /dev/null
+++ b/drivers/mxc/hdp/source_vif.h
@@ -0,0 +1,93 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2016-2017 Cadence Design Systems, Inc.
+ * All rights reserved worldwide.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 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.
+ *
+ * Copyright 2017 NXP
+ *
+ ******************************************************************************
+ *
+ * This file was auto-generated. Do not edit it manually.
+ *
+ ******************************************************************************
+ *
+ * source_vif.h
+ *
+ ******************************************************************************
+ */
+
+#ifndef SOURCE_VIF_H_
+#define SOURCE_VIF_H_
+
+/* register BND_HSYNC2VSYNC */
+#define BND_HSYNC2VSYNC 0
+#define F_IP_DTCT_WIN(x) (((x) & ((1 << 12) - 1)) << 0)
+#define F_IP_DTCT_WIN_RD(x) (((x) & (((1 << 12) - 1) << 0)) >> 0)
+#define F_IP_DET_EN(x) (((x) & ((1 << 1) - 1)) << 12)
+#define F_IP_DET_EN_RD(x) (((x) & (((1 << 1) - 1) << 12)) >> 12)
+#define F_IP_VIF_BYPASS(x) (((x) & ((1 << 1) - 1)) << 13)
+#define F_IP_VIF_BYPASS_RD(x) (((x) & (((1 << 1) - 1) << 13)) >> 13)
+
+/* register HSYNC2VSYNC_F1_L1 */
+#define HSYNC2VSYNC_F1_L1 1
+#define F_IP_DTCT_HSYNC2VSYNC_F1(x) (((x) & ((1 << 16) - 1)) << 0)
+#define F_IP_DTCT_HSYNC2VSYNC_F1_RD(x) (((x) & (((1 << 16) - 1) << 0)) >> 0)
+
+/* register HSYNC2VSYNC_F2_L1 */
+#define HSYNC2VSYNC_F2_L1 2
+#define F_IP_DTCT_HSYNC2VSYNC_F2(x) (((x) & ((1 << 16) - 1)) << 0)
+#define F_IP_DTCT_HSYNC2VSYNC_F2_RD(x) (((x) & (((1 << 16) - 1) << 0)) >> 0)
+
+/* register HSYNC2VSYNC_STATUS */
+#define HSYNC2VSYNC_STATUS 3
+#define F_IP_DTCT_ERR(x) (((x) & ((1 << 1) - 1)) << 0)
+#define F_IP_DTCT_ERR_RD(x) (((x) & (((1 << 1) - 1) << 0)) >> 0)
+#define F_IP_DCT_IP(x) (((x) & ((1 << 1) - 1)) << 1)
+#define F_IP_DCT_IP_RD(x) (((x) & (((1 << 1) - 1) << 1)) >> 1)
+#define F_IP_DTCT_VJITTER(x) (((x) & ((1 << 1) - 1)) << 2)
+#define F_IP_DTCT_VJITTER_RD(x) (((x) & (((1 << 1) - 1) << 2)) >> 2)
+#define F_IP_DTCT_HJITTER(x) (((x) & ((1 << 1) - 1)) << 3)
+#define F_IP_DTCT_HJITTER_RD(x) (((x) & (((1 << 1) - 1) << 3)) >> 3)
+
+/* register HSYNC2VSYNC_POL_CTRL */
+#define HSYNC2VSYNC_POL_CTRL 4
+#define F_VPOL(x) (((x) & ((1 << 1) - 1)) << 2)
+#define F_VPOL_RD(x) (((x) & (((1 << 1) - 1) << 2)) >> 2)
+#define F_HPOL(x) (((x) & ((1 << 1) - 1)) << 1)
+#define F_HPOL_RD(x) (((x) & (((1 << 1) - 1) << 1)) >> 1)
+#define F_VIF_AUTO_MODE(x) (((x) & ((1 << 1) - 1)) << 0)
+#define F_VIF_AUTO_MODE_RD(x) (((x) & (((1 << 1) - 1) << 0)) >> 0)
+
+#endif //SOURCE_VIF
diff --git a/drivers/mxc/hdp/util.c b/drivers/mxc/hdp/util.c
new file mode 100644
index 000000000000..e59b5f059239
--- /dev/null
+++ b/drivers/mxc/hdp/util.c
@@ -0,0 +1,360 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2016-2017 Cadence Design Systems, Inc.
+ * All rights reserved worldwide.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 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.
+ *
+ * Copyright 2017-2018 NXP
+ *
+ ******************************************************************************
+ *
+ * util.c
+ *
+ ******************************************************************************
+ */
+#include "util.h"
+#include "API_General.h"
+#include "apb_cfg.h"
+#include "opcodes.h"
+
+int cdn_apb_read(state_struct *state, u32 addr, u32 *value)
+{
+ struct hdp_mem *mem = state->mem;
+ state->rw->read_reg(mem, addr, value);
+ return 0;
+}
+
+int cdn_apb_write(state_struct *state, u32 addr, u32 value)
+{
+ struct hdp_mem *mem = state->mem;
+ state->rw->write_reg(mem, addr, value);
+ return 0;
+}
+
+int cdn_sapb_read(state_struct *state, u32 addr, u32 *value)
+{
+ struct hdp_mem *mem = state->mem;
+ state->rw->sread_reg(mem, addr, value);
+ return 0;
+}
+
+int cdn_sapb_write(state_struct *state, u32 addr, u32 value)
+{
+ struct hdp_mem *mem = state->mem;
+ state->rw->swrite_reg(mem, addr, value);
+ return 0;
+}
+
+void cdn_sleep(u32 ms)
+{
+ mdelay(ms);
+}
+
+void cdn_usleep(u32 us)
+{
+ udelay(us);
+}
+
+int cdn_bus_read(state_struct *state, u32 addr, u32 *value)
+{
+ return state->bus_type ?
+ cdn_sapb_read(state, addr, value) : cdn_apb_read(state, addr,
+ value);
+}
+
+int cdn_bus_write(state_struct *state, u32 addr, u32 value)
+{
+ return state->bus_type ?
+ cdn_sapb_write(state, addr, value) : cdn_apb_write(state, addr,
+ value);
+}
+
+void internal_itobe(int val, volatile u8 *dest, int bytes)
+{
+ int i;
+ for (i = bytes - 1; i >= 0; --i) {
+ dest[i] = (u8) val;
+ val >>= 8;
+ }
+}
+
+u32 internal_betoi(volatile u8 const *src, u8 bytes)
+{
+ u32 ret = 0;
+ int i;
+
+ if (bytes > sizeof(ret)) {
+ printk
+ ("Warning. Read request for payload larger then supported.\n");
+ bytes = sizeof(ret);
+
+ }
+
+ for (i = 0; i < bytes; ++i) {
+ ret <<= 8;
+ ret |= (u32) src[i];
+ }
+
+ return ret;
+}
+
+u32 internal_mkmsg(volatile u8 *dest, int valNo, ...)
+{
+ va_list vl;
+ u32 len = 0;
+ va_start(vl, valNo);
+ len = internal_vmkmsg(dest, valNo, vl);
+ va_end(vl);
+ return len;
+}
+
+u32 internal_vmkmsg(volatile u8 *dest, int valNo, va_list vl)
+{
+ u32 len = 0;
+ int i;
+ for (i = 0; i < valNo; ++i) {
+ int size = va_arg(vl, int);
+ if (size > 0) {
+ internal_itobe(va_arg(vl, int), dest, size);
+ dest += size;
+ len += size;;
+ } else {
+ memcpy((void *)dest, va_arg(vl, void *), -size);
+ dest -= size;
+ len -= size;
+ }
+ }
+ return len;
+}
+
+void internal_tx_mkfullmsg(state_struct *state, u8 module, u8 opcode,
+ int valNo, ...)
+{
+ va_list vl;
+ va_start(vl, valNo);
+ internal_vtx_mkfullmsg(state, module, opcode, valNo, vl);
+ va_end(vl);
+}
+
+void internal_vtx_mkfullmsg(state_struct *state, u8 module, u8 opcode,
+ int valNo, va_list vl)
+{
+ u32 len =
+ internal_vmkmsg(state->txBuffer + INTERNAL_CMD_HEAD_SIZE, valNo,
+ vl);
+ internal_mbox_tx_enable(state, module, opcode, len);
+ state->txEnable = 1;
+ state->running = 1;
+}
+
+void internal_readmsg(state_struct *state, int valNo, ...)
+{
+ va_list vl;
+ va_start(vl, valNo);
+ internal_vreadmsg(state, valNo, vl);
+ va_end(vl);
+}
+
+void internal_vreadmsg(state_struct *state, int valNo, va_list vl)
+{
+ u8 *src = state->rxBuffer + INTERNAL_CMD_HEAD_SIZE;
+ size_t i;
+
+ for (i = 0; i < (size_t) valNo; ++i) {
+ int size = va_arg(vl, int);
+ void *ptr = va_arg(vl, void *);
+
+ if (!ptr) {
+ src += size;
+ } else if (!size) {
+ *((u8 **) ptr) = src;
+ } else if (size > 0) {
+ switch ((size_t) size) {
+ case sizeof(u8):
+ *((u8 *) ptr) = internal_betoi(src, size);
+ break;
+ case sizeof(u16):
+ *((u16 *) ptr) = internal_betoi(src, size);
+ break;
+ case 3: // 3-byte value (e.g. DPCD address) can be safely converted from BE
+ case sizeof(u32):
+ *((u32 *) ptr) = internal_betoi(src, size);
+ break;
+ default:
+ pr_warn("Warning. Unsupported variable size.\n");
+ memcpy(ptr, src, size);
+ };
+
+ src += size;
+ } else {
+ memcpy(ptr, src, -size);
+ src -= size;
+ }
+ }
+}
+
+INTERNAL_MBOX_STATUS mailbox_write(state_struct *state, u8 val)
+{
+ INTERNAL_MBOX_STATUS ret = { 0, 0, 0, 0 };
+ u32 full;
+ if (cdn_bus_read(state, MAILBOX_FULL_ADDR << 2, &full)) {
+ ret.tx_status = CDN_TX_APB_ERROR;
+ return ret;
+ }
+ if (full) {
+ ret.tx_status = CDN_TX_FULL;
+ return ret;
+ }
+ if (cdn_bus_write(state, MAILBOX0_WR_DATA << 2, val)) {
+ ret.tx_status = CDN_TX_APB_ERROR;
+ return ret;
+ }
+ ret.tx_status = CDN_TX_WRITE;
+ return ret;
+}
+
+INTERNAL_MBOX_STATUS mailbox_read(state_struct *state, volatile u8 *val)
+{
+ INTERNAL_MBOX_STATUS ret = { 0, 0, 0, 0 };
+ u32 empty;
+ u32 rd;
+ if (cdn_bus_read(state, MAILBOX_EMPTY_ADDR << 2, &empty)) {
+ ret.rx_status = CDN_RX_APB_ERROR;
+ return ret;
+ }
+ if (empty) {
+ ret.rx_status = CDN_RX_EMPTY;
+ return ret;
+ }
+ if (cdn_bus_read(state, MAILBOX0_RD_DATA << 2, &rd)) {
+ ret.rx_status = CDN_RX_APB_ERROR;
+ return ret;
+ }
+ *val = (u8) rd;
+ ret.rx_status = CDN_RX_READ;
+ return ret;
+}
+
+INTERNAL_MBOX_STATUS internal_mbox_tx_process(state_struct *state)
+{
+ u32 txCount = 0;
+ u32 length = (u32) state->txBuffer[2] << 8 | (u32) state->txBuffer[3];
+ INTERNAL_MBOX_STATUS ret = {.txend = 0 };
+ INTERNAL_MBOX_STATUS tx_ret;
+
+ ret.tx_status = CDN_TX_NOTHING;
+ if (!state->txEnable)
+ return ret;
+ while ((tx_ret.tx_status =
+ mailbox_write(state, state->txBuffer[state->txi]).tx_status) ==
+ CDN_TX_WRITE) {
+ txCount++;
+ if (++state->txi >= length + 4) {
+ state->txEnable = 0;
+ state->txi = 0;
+ ret.txend = 1;
+ break;
+ }
+ }
+ if (txCount && tx_ret.tx_status == CDN_TX_FULL)
+ ret.tx_status = CDN_TX_WRITE;
+ else
+ ret.tx_status = tx_ret.tx_status;
+ return ret;
+}
+
+INTERNAL_MBOX_STATUS internal_mbox_rx_process(state_struct *state)
+{
+ u32 rxCount = 0;
+ INTERNAL_MBOX_STATUS ret = { 0, 0, 0, 0 };
+ INTERNAL_MBOX_STATUS rx_ret;
+ while ((rx_ret.rx_status =
+ mailbox_read(state, state->rxBuffer + state->rxi).rx_status) ==
+ CDN_RX_READ) {
+ rxCount++;
+ if (++state->rxi >=
+ 4 +
+ ((u32) state->rxBuffer[2] << 8 | (u32) state->
+ rxBuffer[3])) {
+ state->rxi = 0;
+ ret.rxend = 1;
+ state->rxEnable = 0;
+ break;
+ }
+ }
+ ret.rx_status = rxCount ? CDN_RX_READ : CDN_RX_EMPTY;
+ return ret;
+}
+
+u32 internal_apb_available(state_struct *state)
+{
+ return !(state->rxEnable || state->txEnable);
+}
+
+void internal_mbox_tx_enable(state_struct *state, u8 module, u8 opcode,
+ u16 length)
+{
+ state->txBuffer[0] = opcode;
+ state->txBuffer[1] = module;
+ state->txBuffer[2] = (u8) (length >> 8);
+ state->txBuffer[3] = (u8) length;
+ state->txEnable = 1;
+}
+
+CDN_API_STATUS internal_test_rx_head(state_struct *state, u8 module, u8 opcode)
+{
+ if (opcode != state->rxBuffer[0])
+ return CDN_BAD_OPCODE;
+ if (module != state->rxBuffer[1])
+ return CDN_BAD_MODULE;
+ return CDN_OK;
+}
+
+CDN_API_STATUS internal_test_rx_head_match(state_struct *state)
+{
+ return internal_test_rx_head(state, state->txBuffer[1],
+ state->txBuffer[0]);
+}
+
+void print_fw_ver(state_struct *state)
+{
+ u16 ver, verlib;
+ CDN_API_General_getCurVersion(state, &ver, &verlib);
+ printk("FIRMWARE VERSION: %d, LIB VERSION: %d\n", ver, verlib);
+}
+
+u16 internal_get_msg_len(state_struct *state)
+{
+ return ((u16) state->rxBuffer[2] << 8) | (u16) state->rxBuffer[3];
+}
diff --git a/drivers/mxc/hdp/util.h b/drivers/mxc/hdp/util.h
new file mode 100644
index 000000000000..f92900c2a584
--- /dev/null
+++ b/drivers/mxc/hdp/util.h
@@ -0,0 +1,396 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2016-2017 Cadence Design Systems, Inc.
+ * All rights reserved worldwide.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 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.
+ *
+ * Copyright 2017-2018 NXP
+ *
+ ******************************************************************************
+ *
+ * util.h
+ *
+ ******************************************************************************
+ */
+
+#ifndef UTIL_H_
+#define UTIL_H_
+
+#include <linux/delay.h>
+#include <linux/mutex.h>
+#include <drm/drm_modes.h>
+#include <drm/drm_edid.h>
+
+/**
+ * \addtogroup GENERAL_API
+ * \{
+ */
+/** status code returned by API calls */
+typedef enum {
+ /** operation succedded */
+ CDN_OK = 0,
+ /** CEC operation succedded */
+ CDN_CEC_ERR_NONE = 0,
+ /** mailbox is currently sending or receiving data */
+ CDN_BSY,
+ /** message set up and ready to be sent, no data sent yet */
+ CDN_STARTED,
+ /** error encountered while reading/writing APB */
+ CDN_ERR,
+ /** reply returned with bad opcode */
+ CDN_BAD_OPCODE,
+ /** reply returned with bad module */
+ CDN_BAD_MODULE,
+ /** reply not supported mode */
+ CDN_ERROR_NOT_SUPPORTED,
+ /** Invalid argument passed to CEC API function */
+ CDN_CEC_ERR_INVALID_ARG,
+ /**
+ * TX Buffer for CEC Messages is full. This is applicable only
+ * when TX Buffers for CEC Messages are implemented in the HW.
+ */
+ CDN_CEC_ERR_TX_BUFF_FULL,
+ /** No Messages in the RX Buffers are present. */
+ CDN_CEC_ERR_RX_BUFF_EMPTY,
+ /** Timeout during TX operation */
+ CDN_CEC_ERR_TX_TIMEOUT,
+ /** Timeout during RX operation */
+ CDN_CEC_ERR_RX_TIMEOUT,
+ /** Data transmision fail. */
+ CDN_CEC_ERR_TX_FAILED,
+ /** Data reception fail. */
+ CDN_CEC_ERR_RX_FAILED,
+ /** Operation aborted. */
+ CDN_CEC_ERR_ABORT,
+ /** All Logical Addresses are in use. */
+ CDN_CEC_ERR_ALL_LA_IN_USE,
+} CDN_API_STATUS;
+
+typedef enum {
+ CDN_DPTX,
+ CDN_HDMITX_TYPHOON,
+ CDN_HDMITX_KIRAN,
+} CDN_PROTOCOL_TYPE;
+
+typedef enum {
+ CDN_BUS_TYPE_APB = 0,
+ CDN_BUS_TYPE_SAPB = 1
+} CDN_BUS_TYPE;
+
+typedef enum {
+ NUM_OF_LANES_1 = 1,
+ NUM_OF_LANES_2 = 2,
+ NUM_OF_LANES_4 = 4,
+} VIC_NUM_OF_LANES;
+
+typedef enum {
+ RATE_1_6 = 162,
+ RATE_2_1 = 216,
+ RATE_2_4 = 243,
+ RATE_2_7 = 270,
+ RATE_3_2 = 324,
+ RATE_4_3 = 432,
+ RATE_5_4 = 540,
+ RATE_8_1 = 810,
+} VIC_SYMBOL_RATE;
+
+typedef enum {
+ PXL_RGB = 0x1,
+ YCBCR_4_4_4 = 0x2,
+ YCBCR_4_2_2 = 0x4,
+ YCBCR_4_2_0 = 0x8,
+ Y_ONLY = 0x10,
+} VIC_PXL_ENCODING_FORMAT;
+
+typedef enum {
+ BCS_6 = 0x1,
+ BCS_8 = 0x2,
+ BCS_10 = 0x4,
+ BCS_12 = 0x8,
+ BCS_16 = 0x10,
+} VIC_COLOR_DEPTH;
+
+typedef enum {
+ STEREO_VIDEO_LEFT = 0x0,
+ STEREO_VIDEO_RIGHT = 0x1,
+} STEREO_VIDEO_ATTR;
+
+typedef enum {
+ BT_601 = 0x0,
+ BT_709 = 0x1,
+} BT_TYPE;
+
+typedef struct {
+ /** apb write status */
+ enum tx_status_enum {
+ /** one or more bytes written */
+ CDN_TX_WRITE = 0,
+ /** nothing to write */
+ CDN_TX_NOTHING = 1,
+ /** mailbox full, 0 bytes written */
+ CDN_TX_FULL = 2,
+ /** APB error while writing */
+ CDN_TX_APB_ERROR = 3
+ } tx_status:3;
+ /** apb read status */
+ enum rx_status_enum {
+ /** 1 or more bytes read */
+ CDN_RX_READ = 0,
+ /** mailbox empty, 0 bytes read */
+ CDN_RX_EMPTY = 1,
+ /** apb error while reading */
+ CDN_RX_APB_ERROR = 2
+ } rx_status:2;
+ /** indicates end of currenly recived message */
+ u8 rxend:1;
+ /** end of tx message reached */
+ u8 txend:1;
+} INTERNAL_MBOX_STATUS;
+
+struct hdp_mem {
+ void __iomem *regs_base; /* Controller regs base */
+ void __iomem *ss_base; /* HDP Subsystem regs base */
+ void __iomem *rst_base; /* HDP Subsystem reset base */
+ struct mutex mutex;
+};
+
+struct hdp_rw_func {
+ int (*read_reg) (struct hdp_mem *mem, u32 addr, u32 *value);
+ int (*write_reg) (struct hdp_mem *mem, u32 addr, u32 value);
+ int (*sread_reg) (struct hdp_mem *mem, u32 addr, u32 *value);
+ int (*swrite_reg) (struct hdp_mem *mem, u32 addr, u32 value);
+};
+
+typedef struct {
+ u8 txBuffer[1024];
+ u8 rxBuffer[1024];
+ u32 txi; //iterators
+ u32 rxi;
+ u8 txEnable; //data readt to send
+ u8 rxEnable;
+ u8 running;
+ CDN_BUS_TYPE bus_type;
+ u32 tmp;
+ u32 edp; /* use eDP */
+ u8 phy_init;
+
+ struct mutex mutex; //mutex may replace running
+ struct hdp_mem *mem;
+ struct hdp_rw_func *rw;
+} state_struct;
+/**
+ * \addtogroup UTILS
+ * \{
+ */
+#define INTERNAL_CMD_HEAD_SIZE 4
+
+/**
+ * \brief expands to blocking function body
+ * \param x - function call
+ */
+#define MAILBOX_FILL_TIMEOUT 1500
+#define internal_block_function(y, x) \
+do { \
+ unsigned long end_jiffies = jiffies + \
+ msecs_to_jiffies(MAILBOX_FILL_TIMEOUT); \
+ CDN_API_STATUS ret; \
+ mutex_lock(y); \
+ do { \
+ ret = x; \
+ cpu_relax(); \
+ } while (time_after(end_jiffies, jiffies) && \
+ (ret == CDN_BSY || ret == CDN_STARTED)); \
+ mutex_unlock(y); \
+ return ret; \
+} while (0)
+
+/**
+ * \brief write message and write response (if any), non-blocking way. Also sets state.running = 0
+ */
+#define internal_process_messages(state) \
+do { \
+ if (state->txEnable && !internal_mbox_tx_process(state).txend) \
+ return CDN_BSY; \
+ if (state->rxEnable && !internal_mbox_rx_process(state).rxend) \
+ return CDN_BSY; \
+ state->running = 0; \
+} while (0)
+
+#define internal_opcode_ok_or_return(state, module, opcode) do { \
+ CDN_API_STATUS ret; \
+ ret = internal_test_rx_head(state, module, opcode); \
+ if (ret != CDN_OK) \
+ return ret; \
+} while (0)
+
+#define internal_opcode_match_or_return(state) do { \
+ CDN_API_STATUS ret; \
+ ret = internal_test_rx_head_match(state); \
+ if (ret != CDN_OK) \
+ return ret; \
+} while (0)
+
+/* macro for simple tx only command, command format as in mkfullmsg (with count) */
+#define internal_macro_command_tx(state, module, opcode, bustype, command...) \
+do { \
+ if (!state->running) { \
+ internal_tx_mkfullmsg(state, module, opcode, command); \
+ state->bus_type = bustype; \
+ return CDN_STARTED; \
+ } \
+ internal_process_messages(state); \
+} while (0)
+
+/* macro for command with response with matching opcode, command format as in mkfullmsg (with count) */
+#define internal_macro_command_txrx(state, module, opcode, bustype, command...) \
+do { \
+ if (!state->running) { \
+ internal_tx_mkfullmsg(state, module, opcode, command); \
+ state->bus_type = bustype; \
+ state->rxEnable = 1; \
+ return CDN_STARTED; \
+ } \
+ internal_process_messages(state); \
+ internal_opcode_match_or_return(state); \
+} while (0)
+
+/**
+ * \brief put val into dest in big endian format
+ * \param val - value to put
+ * \param dest - place to put value
+ * \param bytes - true size of val in bytes. for example if bytes = 2 val is treated as short int
+ */
+void internal_itobe(int val, volatile u8 *dest, int bytes);
+
+/**
+ * \brief read big endian value from src and return it
+ * \param src - source to read from
+ * \param bytes - size of read value
+ * \return result
+ */
+u32 internal_betoi(volatile u8 const *src, u8 bytes);
+
+/**
+ * \brief create message from size and value pairs; also sets state.runnging and state.txEnable
+ * \param dest - pointer to write message to
+ * \param valNo - number of values to write
+ * \param ... - pairs of size and value, each value is written after another. if size is positive value, value is written with #internal_itobe, if size is negative, value is treated as src pointer for memcpy
+ *
+ * example:
+ *
+ * u16 x = 0xAABB;
+ *
+ * internal_mkmsg(dest, 3, 1, 1, 2, 3, -2, &x);
+ *
+ * will write 01 00 03 AA BB to dest
+ */
+u32 internal_mkmsg(volatile u8 *dest, int valNo, ...);
+u32 internal_vmkmsg(volatile u8 *dest, int valNo, va_list vl);
+
+/**
+ * \brief setup message header in txBuffer, set txEnable = 1
+ */
+void internal_mbox_tx_enable(state_struct *state, u8 module, u8 opcode,
+ u16 length);
+
+/**
+ * \brief write from txBuffer to mailbox untill full or end of message.
+ *
+ * when txEnable == 0 writes nothing
+ * when write reaches end of message set txEnable = 0
+ */
+
+/**
+ * \brief combination of #internal_mkmsg and #internal_mbox_tx_enable
+ *
+ * #internal_mkmsg dest and #internal_mbox_tx_enable length are determined automaticly
+ * this function also sets state.txEnable = 1 and state.running
+ */
+void internal_tx_mkfullmsg(state_struct *state, u8 module, u8 opcode,
+ int valNo, ...);
+void internal_vtx_mkfullmsg(state_struct *state, u8 module, u8 opcode,
+ int valNo, va_list vl);
+
+/**
+ * \brief read from state.txBuffer and store results in specified pointers
+ * \param valNo - numbero of values to read
+ * \param ... - pairs of size and ptr
+ *
+ * this function is similar to #internal_mkmsg -
+ *
+ * when size is positive read value using #internal_betoi
+ * when size is negative mempcy from txBuffer to ptr -size bytes
+ * when size is 0 write to ptr addres of current position in rxbuffer
+ * when ptr is NULL ignore size bytes (if size is negative this will rewind buffer)
+ */
+void internal_readmsg(state_struct *state, int valNo, ...);
+void internal_vreadmsg(state_struct *state, int valNo, va_list vl);
+
+INTERNAL_MBOX_STATUS internal_mbox_tx_process(state_struct *state);
+/**
+ * \brief read to rxBuffer from mailbox untill empty or end of message
+ *
+ * when rxEnable == 0 reads nothing
+ * when end of message reached sets rxEnable = 0
+ */
+INTERNAL_MBOX_STATUS internal_mbox_rx_process(state_struct *state);
+
+/**
+ * \brief check if apb is available
+ * \return !(rxEnable && txEable)
+ */
+u32 internal_apb_available(state_struct *state);
+
+/**
+ * \brief test if parameters match module and opcode in rxBuffer
+ * \return CDN_OK or CDN_BAD_OPCODE or CDN_BAD_MODULE
+ */
+CDN_API_STATUS internal_test_rx_head(state_struct *state, u8 module,
+ u8 opcode);
+
+CDN_API_STATUS internal_test_rx_head_match(state_struct *state);
+
+/**
+ * \brief print current fw and lib version
+ */
+void print_fw_ver(state_struct *state);
+
+int cdn_apb_read(state_struct *state, u32 addr, u32 *value);
+int cdn_sapb_read(state_struct *state, u32 addr, u32 *value);
+int cdn_apb_write(state_struct *state, u32 addr, u32 value);
+int cdn_sapb_write(state_struct *state, u32 addr, u32 value);
+void cdn_sleep(u32 ms);
+void cdn_usleep(u32 us);
+u16 internal_get_msg_len(state_struct *state);
+#endif
diff --git a/drivers/mxc/ipu3/Kconfig b/drivers/mxc/ipu3/Kconfig
new file mode 100644
index 000000000000..c702efed2b55
--- /dev/null
+++ b/drivers/mxc/ipu3/Kconfig
@@ -0,0 +1,21 @@
+config MXC_IPU_V3
+ bool
+
+config MXC_IPU_V3_PRG
+ tristate "i.MX IPUv3 prefetch gasket engine"
+ depends on MXC_IPU_V3 && MXC_IPU_V3_PRE
+ help
+ This enables support for the IPUv3 prefetch gasket engine to
+ support double buffer handshake control bewteen IPUv3 and
+ prefetch engine(PRE), snoop the AXI interface for display
+ refresh requests to memory and modify the request address to
+ fetch the double buffered row of blocks in OCRAM.
+
+config MXC_IPU_V3_PRE
+ tristate "i.MX IPUv3 prefetch engine"
+ depends on MXC_IPU_V3
+ select MXC_IPU_V3_PRG
+ help
+ This enables support for the IPUv3 prefetch engine to improve
+ the system memory performance. The engine has the capability
+ to resolve framebuffers in tile pixel format to linear.
diff --git a/drivers/mxc/ipu3/Makefile b/drivers/mxc/ipu3/Makefile
new file mode 100644
index 000000000000..d48f11244073
--- /dev/null
+++ b/drivers/mxc/ipu3/Makefile
@@ -0,0 +1,7 @@
+obj-$(CONFIG_MXC_IPU_V3) = mxc_ipu.o
+
+obj-$(CONFIG_MXC_IPU_V3_PRG) += prg.o
+obj-$(CONFIG_MXC_IPU_V3_PRE) += pre.o
+
+mxc_ipu-objs := ipu_common.o ipu_ic.o ipu_disp.o ipu_capture.o ipu_device.o \
+ ipu_calc_stripes_sizes.o vdoa.o ipu_pixel_clk.o
diff --git a/drivers/mxc/ipu3/ipu_calc_stripes_sizes.c b/drivers/mxc/ipu3/ipu_calc_stripes_sizes.c
new file mode 100644
index 000000000000..512404d4101c
--- /dev/null
+++ b/drivers/mxc/ipu3/ipu_calc_stripes_sizes.c
@@ -0,0 +1,495 @@
+/*
+ * Copyright 2009-2015 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/*
+ * @file ipu_calc_stripes_sizes.c
+ *
+ * @brief IPU IC functions
+ *
+ * @ingroup IPU
+ */
+
+#include <linux/ipu-v3.h>
+#include <linux/module.h>
+#include <linux/math64.h>
+
+#define BPP_32 0
+#define BPP_16 3
+#define BPP_8 5
+#define BPP_24 1
+#define BPP_12 4
+#define BPP_18 2
+
+static u32 truncate(u32 up, /* 0: down; else: up */
+ u64 a, /* must be non-negative */
+ u32 b)
+{
+ u32 d;
+ u64 div;
+ div = div_u64(a, b);
+ d = b * (div >> 32);
+ if (up && (a > (((u64)d) << 32)))
+ return d+b;
+ else
+ return d;
+}
+
+static unsigned int f_calc(unsigned int pfs, unsigned int bpp, unsigned int *write)
+{/* return input_f */
+ unsigned int f_calculated = 0;
+ switch (pfs) {
+ case IPU_PIX_FMT_YVU422P:
+ case IPU_PIX_FMT_YUV422P:
+ case IPU_PIX_FMT_YUV420P2:
+ case IPU_PIX_FMT_YUV420P:
+ case IPU_PIX_FMT_YVU420P:
+ case IPU_PIX_FMT_YUV444P:
+ f_calculated = 16;
+ break;
+
+ case IPU_PIX_FMT_RGB565:
+ case IPU_PIX_FMT_YUYV:
+ case IPU_PIX_FMT_UYVY:
+ f_calculated = 8;
+ break;
+
+ case IPU_PIX_FMT_NV12:
+ f_calculated = 8;
+ break;
+
+ default:
+ f_calculated = 0;
+ break;
+
+ }
+ if (!f_calculated) {
+ switch (bpp) {
+ case BPP_32:
+ f_calculated = 2;
+ break;
+
+ case BPP_16:
+ f_calculated = 4;
+ break;
+
+ case BPP_8:
+ case BPP_24:
+ f_calculated = 8;
+ break;
+
+ case BPP_12:
+ f_calculated = 16;
+ break;
+
+ case BPP_18:
+ f_calculated = 32;
+ break;
+
+ default:
+ f_calculated = 0;
+ break;
+ }
+ }
+ return f_calculated;
+}
+
+
+static unsigned int m_calc(unsigned int pfs)
+{
+ unsigned int m_calculated = 0;
+ switch (pfs) {
+ case IPU_PIX_FMT_YUV420P2:
+ case IPU_PIX_FMT_YUV420P:
+ case IPU_PIX_FMT_YVU422P:
+ case IPU_PIX_FMT_YUV422P:
+ case IPU_PIX_FMT_YVU420P:
+ case IPU_PIX_FMT_YUV444P:
+ m_calculated = 16;
+ break;
+
+ case IPU_PIX_FMT_NV12:
+ case IPU_PIX_FMT_YUYV:
+ case IPU_PIX_FMT_UYVY:
+ m_calculated = 8;
+ break;
+
+ default:
+ m_calculated = 8;
+ break;
+
+ }
+ return m_calculated;
+}
+
+static int calc_split_resize_coeffs(unsigned int inSize, unsigned int outSize,
+ unsigned int *resizeCoeff,
+ unsigned int *downsizeCoeff)
+{
+ uint32_t tempSize;
+ uint32_t tempDownsize;
+
+ if (inSize > 4096) {
+ pr_debug("IC input size(%d) cannot exceed 4096\n",
+ inSize);
+ return -EINVAL;
+ }
+
+ if (outSize > 1024) {
+ pr_debug("IC output size(%d) cannot exceed 1024\n",
+ outSize);
+ return -EINVAL;
+ }
+
+ if ((outSize << 3) < inSize) {
+ pr_debug("IC cannot downsize more than 8:1\n");
+ return -EINVAL;
+ }
+
+ /* Compute downsizing coefficient */
+ /* Output of downsizing unit cannot be more than 1024 */
+ tempDownsize = 0;
+ tempSize = inSize;
+ while (((tempSize > 1024) || (tempSize >= outSize * 2)) &&
+ (tempDownsize < 2)) {
+ tempSize >>= 1;
+ tempDownsize++;
+ }
+ *downsizeCoeff = tempDownsize;
+
+ /* compute resizing coefficient using the following equation:
+ resizeCoeff = M*(SI -1)/(SO - 1)
+ where M = 2^13, SI - input size, SO - output size */
+ *resizeCoeff = (8192L * (tempSize - 1)) / (outSize - 1);
+ if (*resizeCoeff >= 16384L) {
+ pr_debug("Overflow on IC resize coefficient.\n");
+ return -EINVAL;
+ }
+
+ pr_debug("resizing from %u -> %u pixels, "
+ "downsize=%u, resize=%u.%lu (reg=%u)\n", inSize, outSize,
+ *downsizeCoeff, (*resizeCoeff >= 8192L) ? 1 : 0,
+ ((*resizeCoeff & 0x1FFF) * 10000L) / 8192L, *resizeCoeff);
+
+ return 0;
+}
+
+/* Stripe parameters calculator */
+/**************************************************************************
+Notes:
+MSW = the maximal width allowed for a stripe
+ i.MX31: 720, i.MX35: 800, i.MX37/51/53: 1024
+cirr = the maximal inverse resizing ratio for which overlap in the input
+ is requested; typically cirr~2
+flags
+ bit 0 - equal_stripes
+ 0 each stripe is allowed to have independent parameters
+ for maximal image quality
+ 1 the stripes are requested to have identical parameters
+ (except the base address), for maximal performance
+ bit 1 - vertical/horizontal
+ 0 horizontal
+ 1 vertical
+
+If performance is the top priority (above image quality)
+ Avoid overlap, by setting CIRR = 0
+ This will also force effectively identical_stripes = 1
+ Choose IF & OF that corresponds to the same IOX/SX for both stripes
+ Choose IFW & OFW such that
+ IFW/IM, IFW/IF, OFW/OM, OFW/OF are even integers
+ The function returns an error status:
+ 0: no error
+ 1: invalid input parameters -> aborted without result
+ Valid parameters should satisfy the following conditions
+ IFW <= OFW, otherwise downsizing is required
+ - which is not supported yet
+ 4 <= IFW,OFW, so some interpolation may be needed even without overlap
+ IM, OM, IF, OF should not vanish
+ 2*IF <= IFW
+ so the frame can be split to two equal stripes, even without overlap
+ 2*(OF+IF/irr_opt) <= OFW
+ so a valid positive INW exists even for equal stripes
+ OF <= MSW, otherwise, the left stripe cannot be sufficiently large
+ MSW < OFW, so splitting to stripes is required
+ OFW <= 2*MSW, so two stripes are sufficient
+ (this also implies that 2<=MSW)
+ 2: OF is not a multiple of OM - not fully-supported yet
+ Output is produced but OW is not guaranited to be a multiple of OM
+ 4: OFW reduced to be a multiple of OM
+ 8: CIRR > 1: truncated to 1
+ Overlap is not supported (and not needed) y for upsizing)
+**************************************************************************/
+int ipu_calc_stripes_sizes(const unsigned int input_frame_width,
+ /* input frame width;>1 */
+ unsigned int output_frame_width, /* output frame width; >1 */
+ const unsigned int maximal_stripe_width,
+ /* the maximal width allowed for a stripe */
+ const unsigned long long cirr, /* see above */
+ const unsigned int flags, /* see above */
+ u32 input_pixelformat,/* pixel format after of read channel*/
+ u32 output_pixelformat,/* pixel format after of write channel*/
+ struct stripe_param *left,
+ struct stripe_param *right)
+{
+ const unsigned int irr_frac_bits = 13;
+ const unsigned long irr_steps = 1 << irr_frac_bits;
+ const u64 dirr = ((u64)1) << (32 - 2);
+ /* The maximum relative difference allowed between the irrs */
+ const u64 cr = ((u64)4) << 32;
+ /* The importance ratio between the two terms in the cost function below */
+
+ unsigned int status;
+ unsigned int temp;
+ unsigned int onw_min;
+ unsigned int inw = 0, onw = 0, inw_best = 0;
+ /* number of pixels in the left stripe NOT hidden by the right stripe */
+ u64 irr_opt; /* the optimal inverse resizing ratio */
+ u64 rr_opt; /* the optimal resizing ratio = 1/irr_opt*/
+ u64 dinw; /* the misalignment between the stripes */
+ /* (measured in units of input columns) */
+ u64 difwl, difwr = 0;
+ /* The number of input columns not reflected in the output */
+ /* the resizing ratio used for the right stripe is */
+ /* left->irr and right->irr respectively */
+ u64 cost, cost_min;
+ u64 div; /* result of division */
+ bool equal_stripes = (flags & 0x1) != 0;
+ bool vertical = (flags & 0x2) != 0;
+
+ unsigned int input_m, input_f, output_m, output_f; /* parameters for upsizing by stripes */
+ unsigned int resize_coeff;
+ unsigned int downsize_coeff;
+
+ status = 0;
+
+ if (vertical) {
+ input_f = 2;
+ input_m = 8;
+ output_f = 8;
+ output_m = 2;
+ } else {
+ input_f = f_calc(input_pixelformat, 0, NULL);
+ input_m = m_calc(input_pixelformat);
+ output_f = input_m;
+ output_m = m_calc(output_pixelformat);
+ }
+ if ((input_frame_width < 4) || (output_frame_width < 4))
+ return 1;
+
+ irr_opt = div_u64((((u64)(input_frame_width - 1)) << 32),
+ (output_frame_width - 1));
+ rr_opt = div_u64((((u64)(output_frame_width - 1)) << 32),
+ (input_frame_width - 1));
+
+ if ((input_m == 0) || (output_m == 0) || (input_f == 0) || (output_f == 0)
+ || (input_frame_width < (2 * input_f))
+ || ((((u64)output_frame_width) << 32) <
+ (2 * ((((u64)output_f) << 32) + (input_f * rr_opt))))
+ || (maximal_stripe_width < output_f)
+ || ((output_frame_width <= maximal_stripe_width)
+ && (equal_stripes == 0))
+ || ((2 * maximal_stripe_width) < output_frame_width))
+ return 1;
+
+ if (output_f % output_m)
+ status += 2;
+
+ temp = truncate(0, (((u64)output_frame_width) << 32), output_m);
+ if (temp < output_frame_width) {
+ output_frame_width = temp;
+ status += 4;
+ }
+
+ pr_debug("---------------->\n"
+ "if = %d\n"
+ "im = %d\n"
+ "of = %d\n"
+ "om = %d\n"
+ "irr_opt = %llu\n"
+ "rr_opt = %llu\n"
+ "cirr = %llu\n"
+ "pixel in = %08x\n"
+ "pixel out = %08x\n"
+ "ifw = %d\n"
+ "ofwidth = %d\n",
+ input_f,
+ input_m,
+ output_f,
+ output_m,
+ irr_opt,
+ rr_opt,
+ cirr,
+ input_pixelformat,
+ output_pixelformat,
+ input_frame_width,
+ output_frame_width
+ );
+
+ if (equal_stripes) {
+ if ((irr_opt > cirr) /* overlap in the input is not requested */
+ && ((input_frame_width % (input_m << 1)) == 0)
+ && ((input_frame_width % (input_f << 1)) == 0)
+ && ((output_frame_width % (output_m << 1)) == 0)
+ && ((output_frame_width % (output_f << 1)) == 0)) {
+ /* without overlap */
+ left->input_width = right->input_width = right->input_column =
+ input_frame_width >> 1;
+ left->output_width = right->output_width = right->output_column =
+ output_frame_width >> 1;
+ left->input_column = 0;
+ left->output_column = 0;
+ div = div_u64(((((u64)irr_steps) << 32) *
+ (right->input_width - 1)), (right->output_width - 1));
+ left->irr = right->irr = truncate(0, div, 1);
+ } else { /* with overlap */
+ onw = truncate(0, (((u64)output_frame_width - 1) << 32) >> 1,
+ output_f);
+ inw = truncate(0, onw * irr_opt, input_f);
+ /* this is the maximal inw which allows the same resizing ratio */
+ /* in both stripes */
+ onw = truncate(1, (inw * rr_opt), output_f);
+ div = div_u64((((u64)(irr_steps * inw)) <<
+ 32), onw);
+ left->irr = right->irr = truncate(0, div, 1);
+ left->output_width = right->output_width =
+ output_frame_width - onw;
+ /* These are valid assignments for output_width, */
+ /* assuming output_f is a multiple of output_m */
+ div = (((u64)(left->output_width-1) * (left->irr)) << 32);
+ div = (((u64)1) << 32) + div_u64(div, irr_steps);
+
+ left->input_width = right->input_width = truncate(1, div, input_m);
+
+ div = div_u64((((u64)((right->output_width - 1) * right->irr)) <<
+ 32), irr_steps);
+ difwr = (((u64)(input_frame_width - 1 - inw)) << 32) - div;
+ div = div_u64((difwr + (((u64)input_f) << 32)), 2);
+ left->input_column = truncate(0, div, input_f);
+
+
+ /* This splits the truncated input columns evenly */
+ /* between the left and right margins */
+ right->input_column = left->input_column + inw;
+ left->output_column = 0;
+ right->output_column = onw;
+ }
+ if (left->input_width > left->output_width) {
+ if (calc_split_resize_coeffs(left->input_width,
+ left->output_width,
+ &resize_coeff,
+ &downsize_coeff) < 0)
+ return -EINVAL;
+
+ if (downsize_coeff > 0) {
+ left->irr = right->irr =
+ (downsize_coeff << 14) | resize_coeff;
+ }
+ }
+ pr_debug("inw %d, onw %d, ilw %d, ilc %d, olw %d,"
+ " irw %d, irc %d, orw %d, orc %d, "
+ "difwr %llu, lirr %u\n",
+ inw, onw, left->input_width,
+ left->input_column, left->output_width,
+ right->input_width, right->input_column,
+ right->output_width,
+ right->output_column, difwr, left->irr);
+ } else { /* independent stripes */
+ onw_min = output_frame_width - maximal_stripe_width;
+ /* onw is a multiple of output_f, in the range */
+ /* [max(output_f,output_frame_width-maximal_stripe_width),*/
+ /*min(output_frame_width-2,maximal_stripe_width)] */
+ /* definitely beyond the cost of any valid setting */
+ cost_min = (((u64)input_frame_width) << 32) + cr;
+ onw = truncate(0, ((u64)maximal_stripe_width), output_f);
+ if (output_frame_width - onw == 1)
+ onw -= output_f; /* => onw and output_frame_width-1-onw are positive */
+ inw = truncate(0, onw * irr_opt, input_f);
+ /* this is the maximal inw which allows the same resizing ratio */
+ /* in both stripes */
+ onw = truncate(1, inw * rr_opt, output_f);
+ do {
+ div = div_u64((((u64)(irr_steps * inw)) << 32), onw);
+ left->irr = truncate(0, div, 1);
+ div = div_u64((((u64)(onw * left->irr)) << 32),
+ irr_steps);
+ dinw = (((u64)inw) << 32) - div;
+
+ div = div_u64((((u64)((output_frame_width - 1 - onw) * left->irr)) <<
+ 32), irr_steps);
+
+ difwl = (((u64)(input_frame_width - 1 - inw)) << 32) - div;
+
+ cost = difwl + (((u64)(cr * dinw)) >> 32);
+
+ if (cost < cost_min) {
+ inw_best = inw;
+ cost_min = cost;
+ }
+
+ inw -= input_f;
+ onw = truncate(1, inw * rr_opt, output_f);
+ /* This is the minimal onw which allows the same resizing ratio */
+ /* in both stripes */
+ } while (onw >= onw_min);
+
+ inw = inw_best;
+ onw = truncate(1, inw * rr_opt, output_f);
+ div = div_u64((((u64)(irr_steps * inw)) << 32), onw);
+ left->irr = truncate(0, div, 1);
+
+ left->output_width = onw;
+ right->output_width = output_frame_width - onw;
+ /* These are valid assignments for output_width, */
+ /* assuming output_f is a multiple of output_m */
+ left->input_width = truncate(1, ((u64)(inw + 1)) << 32, input_m);
+ right->input_width = truncate(1, ((u64)(input_frame_width - inw)) <<
+ 32, input_m);
+
+ div = div_u64((((u64)(irr_steps * (input_frame_width - 1 - inw))) <<
+ 32), (right->output_width - 1));
+ right->irr = truncate(0, div, 1);
+ temp = truncate(0, ((u64)left->irr) * ((((u64)1) << 32) + dirr), 1);
+ if (temp < right->irr)
+ right->irr = temp;
+ div = div_u64(((u64)((right->output_width - 1) * right->irr) <<
+ 32), irr_steps);
+ difwr = (u64)(input_frame_width - 1 - inw) - div;
+
+
+ div = div_u64((difwr + (((u64)input_f) << 32)), 2);
+ left->input_column = truncate(0, div, input_f);
+
+ /* This splits the truncated input columns evenly */
+ /* between the left and right margins */
+ right->input_column = left->input_column + inw;
+ left->output_column = 0;
+ right->output_column = onw;
+ if (left->input_width > left->output_width) {
+ if (calc_split_resize_coeffs(left->input_width,
+ left->output_width,
+ &resize_coeff,
+ &downsize_coeff) < 0)
+ return -EINVAL;
+ left->irr = (downsize_coeff << 14) | resize_coeff;
+ }
+ if (right->input_width > right->output_width) {
+ if (calc_split_resize_coeffs(right->input_width,
+ right->output_width,
+ &resize_coeff,
+ &downsize_coeff) < 0)
+ return -EINVAL;
+ right->irr = (downsize_coeff << 14) | resize_coeff;
+ }
+ }
+ return status;
+}
+EXPORT_SYMBOL(ipu_calc_stripes_sizes);
diff --git a/drivers/mxc/ipu3/ipu_capture.c b/drivers/mxc/ipu3/ipu_capture.c
new file mode 100644
index 000000000000..f304c8140be4
--- /dev/null
+++ b/drivers/mxc/ipu3/ipu_capture.c
@@ -0,0 +1,816 @@
+/*
+ * Copyright 2008-2015 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/*!
+ * @file ipu_capture.c
+ *
+ * @brief IPU capture dase functions
+ *
+ * @ingroup IPU
+ */
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/ipu-v3.h>
+#include <linux/module.h>
+#include <linux/spinlock.h>
+#include <linux/types.h>
+
+#include "ipu_prv.h"
+#include "ipu_regs.h"
+
+/*!
+ * _ipu_csi_mclk_set
+ *
+ * @param ipu ipu handler
+ * @param pixel_clk desired pixel clock frequency in Hz
+ * @param csi csi 0 or csi 1
+ *
+ * @return Returns 0 on success or negative error code on fail
+ */
+int _ipu_csi_mclk_set(struct ipu_soc *ipu, uint32_t pixel_clk, uint32_t csi)
+{
+ uint32_t temp;
+ int32_t div_ratio;
+
+ div_ratio = (clk_get_rate(ipu->ipu_clk) / pixel_clk) - 1;
+
+ if (div_ratio > 0xFF || div_ratio < 0) {
+ dev_dbg(ipu->dev, "value of pixel_clk extends normal range\n");
+ return -EINVAL;
+ }
+
+ temp = ipu_csi_read(ipu, csi, CSI_SENS_CONF);
+ temp &= ~CSI_SENS_CONF_DIVRATIO_MASK;
+ ipu_csi_write(ipu, csi, temp |
+ (div_ratio << CSI_SENS_CONF_DIVRATIO_SHIFT),
+ CSI_SENS_CONF);
+
+ return 0;
+}
+
+/*!
+ * ipu_csi_init_interface
+ * Sets initial values for the CSI registers.
+ * The width and height of the sensor and the actual frame size will be
+ * set to the same values.
+ * @param ipu ipu handler
+ * @param width Sensor width
+ * @param height Sensor height
+ * @param pixel_fmt pixel format
+ * @param cfg_param ipu_csi_signal_cfg_t structure
+ * @param csi csi 0 or csi 1
+ *
+ * @return 0 for success, -EINVAL for error
+ */
+int32_t
+ipu_csi_init_interface(struct ipu_soc *ipu, uint16_t width, uint16_t height,
+ uint32_t pixel_fmt, ipu_csi_signal_cfg_t cfg_param)
+{
+ uint32_t data = 0;
+ uint32_t csi = cfg_param.csi;
+
+ /* Set SENS_DATA_FORMAT bits (8, 9 and 10)
+ RGB or YUV444 is 0 which is current value in data so not set
+ explicitly
+ This is also the default value if attempts are made to set it to
+ something invalid. */
+ switch (pixel_fmt) {
+ case IPU_PIX_FMT_YUYV:
+ cfg_param.data_fmt = CSI_SENS_CONF_DATA_FMT_YUV422_YUYV;
+ break;
+ case IPU_PIX_FMT_UYVY:
+ cfg_param.data_fmt = CSI_SENS_CONF_DATA_FMT_YUV422_UYVY;
+ break;
+ case IPU_PIX_FMT_RGB24:
+ case IPU_PIX_FMT_BGR24:
+ cfg_param.data_fmt = CSI_SENS_CONF_DATA_FMT_RGB_YUV444;
+ break;
+ case IPU_PIX_FMT_GENERIC:
+ case IPU_PIX_FMT_GENERIC_16:
+ cfg_param.data_fmt = CSI_SENS_CONF_DATA_FMT_BAYER;
+ break;
+ case IPU_PIX_FMT_RGB565:
+ cfg_param.data_fmt = CSI_SENS_CONF_DATA_FMT_RGB565;
+ break;
+ case IPU_PIX_FMT_RGB555:
+ cfg_param.data_fmt = CSI_SENS_CONF_DATA_FMT_RGB555;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ /* Set the CSI_SENS_CONF register remaining fields */
+ data |= cfg_param.data_width << CSI_SENS_CONF_DATA_WIDTH_SHIFT |
+ cfg_param.data_fmt << CSI_SENS_CONF_DATA_FMT_SHIFT |
+ cfg_param.data_pol << CSI_SENS_CONF_DATA_POL_SHIFT |
+ cfg_param.Vsync_pol << CSI_SENS_CONF_VSYNC_POL_SHIFT |
+ cfg_param.Hsync_pol << CSI_SENS_CONF_HSYNC_POL_SHIFT |
+ cfg_param.pixclk_pol << CSI_SENS_CONF_PIX_CLK_POL_SHIFT |
+ cfg_param.ext_vsync << CSI_SENS_CONF_EXT_VSYNC_SHIFT |
+ cfg_param.clk_mode << CSI_SENS_CONF_SENS_PRTCL_SHIFT |
+ cfg_param.pack_tight << CSI_SENS_CONF_PACK_TIGHT_SHIFT |
+ cfg_param.force_eof << CSI_SENS_CONF_FORCE_EOF_SHIFT |
+ cfg_param.data_en_pol << CSI_SENS_CONF_DATA_EN_POL_SHIFT;
+
+ _ipu_get(ipu);
+
+ mutex_lock(&ipu->mutex_lock);
+
+ ipu_csi_write(ipu, csi, data, CSI_SENS_CONF);
+
+ /* Setup sensor frame size */
+ ipu_csi_write(ipu, csi, (width - 1) | (height - 1) << 16, CSI_SENS_FRM_SIZE);
+
+ /* Set CCIR registers */
+ if (cfg_param.clk_mode == IPU_CSI_CLK_MODE_CCIR656_PROGRESSIVE) {
+ ipu_csi_write(ipu, csi, 0x40030, CSI_CCIR_CODE_1);
+ ipu_csi_write(ipu, csi, 0xFF0000, CSI_CCIR_CODE_3);
+ } else if (cfg_param.clk_mode == IPU_CSI_CLK_MODE_CCIR656_INTERLACED) {
+ if (width == 720 && height == 625) {
+ /* PAL case */
+ /*
+ * Field0BlankEnd = 0x6, Field0BlankStart = 0x2,
+ * Field0ActiveEnd = 0x4, Field0ActiveStart = 0
+ */
+ ipu_csi_write(ipu, csi, 0x40596, CSI_CCIR_CODE_1);
+ /*
+ * Field1BlankEnd = 0x7, Field1BlankStart = 0x3,
+ * Field1ActiveEnd = 0x5, Field1ActiveStart = 0x1
+ */
+ ipu_csi_write(ipu, csi, 0xD07DF, CSI_CCIR_CODE_2);
+
+ ipu_csi_write(ipu, csi, 0xFF0000, CSI_CCIR_CODE_3);
+
+ } else if (width == 720 && height == 525) {
+ /* NTSC case */
+ /*
+ * Field0BlankEnd = 0x7, Field0BlankStart = 0x3,
+ * Field0ActiveEnd = 0x5, Field0ActiveStart = 0x1
+ */
+ ipu_csi_write(ipu, csi, 0xD07DF, CSI_CCIR_CODE_1);
+ /*
+ * Field1BlankEnd = 0x6, Field1BlankStart = 0x2,
+ * Field1ActiveEnd = 0x4, Field1ActiveStart = 0
+ */
+ ipu_csi_write(ipu, csi, 0x40596, CSI_CCIR_CODE_2);
+ ipu_csi_write(ipu, csi, 0xFF0000, CSI_CCIR_CODE_3);
+ } else {
+ dev_err(ipu->dev, "Unsupported CCIR656 interlaced "
+ "video mode\n");
+ mutex_unlock(&ipu->mutex_lock);
+ _ipu_put(ipu);
+ return -EINVAL;
+ }
+ _ipu_csi_ccir_err_detection_enable(ipu, csi);
+ } else if ((cfg_param.clk_mode ==
+ IPU_CSI_CLK_MODE_CCIR1120_PROGRESSIVE_DDR) ||
+ (cfg_param.clk_mode ==
+ IPU_CSI_CLK_MODE_CCIR1120_PROGRESSIVE_SDR) ||
+ (cfg_param.clk_mode ==
+ IPU_CSI_CLK_MODE_CCIR1120_INTERLACED_DDR) ||
+ (cfg_param.clk_mode ==
+ IPU_CSI_CLK_MODE_CCIR1120_INTERLACED_SDR)) {
+ ipu_csi_write(ipu, csi, 0x40030, CSI_CCIR_CODE_1);
+ ipu_csi_write(ipu, csi, 0xFF0000, CSI_CCIR_CODE_3);
+ _ipu_csi_ccir_err_detection_enable(ipu, csi);
+ } else if ((cfg_param.clk_mode == IPU_CSI_CLK_MODE_GATED_CLK) ||
+ (cfg_param.clk_mode == IPU_CSI_CLK_MODE_NONGATED_CLK)) {
+ _ipu_csi_ccir_err_detection_disable(ipu, csi);
+ }
+
+ dev_dbg(ipu->dev, "CSI_SENS_CONF = 0x%08X\n",
+ ipu_csi_read(ipu, csi, CSI_SENS_CONF));
+ dev_dbg(ipu->dev, "CSI_ACT_FRM_SIZE = 0x%08X\n",
+ ipu_csi_read(ipu, csi, CSI_ACT_FRM_SIZE));
+
+ mutex_unlock(&ipu->mutex_lock);
+
+ _ipu_put(ipu);
+
+ return 0;
+}
+EXPORT_SYMBOL(ipu_csi_init_interface);
+
+/*!
+ * ipu_csi_get_sensor_protocol
+ *
+ * @param ipu ipu handler
+ * @param csi csi 0 or csi 1
+ *
+ * @return Returns sensor protocol
+ */
+int32_t ipu_csi_get_sensor_protocol(struct ipu_soc *ipu, uint32_t csi)
+{
+ int ret;
+ _ipu_get(ipu);
+ ret = (ipu_csi_read(ipu, csi, CSI_SENS_CONF) &
+ CSI_SENS_CONF_SENS_PRTCL_MASK) >>
+ CSI_SENS_CONF_SENS_PRTCL_SHIFT;
+ _ipu_put(ipu);
+ return ret;
+}
+EXPORT_SYMBOL(ipu_csi_get_sensor_protocol);
+
+/*!
+ * ipu_csi_enable_mclk
+ *
+ * @param ipu ipu handler
+ * @param csi csi 0 or csi 1
+ * @param flag true to enable mclk, false to disable mclk
+ * @param wait true to wait 100ms make clock stable, false not wait
+ *
+ * @return Returns 0 on success
+ */
+int ipu_csi_enable_mclk(struct ipu_soc *ipu, int csi, bool flag, bool wait)
+{
+ /* Return immediately if there is no csi_clk to manage */
+ if (ipu->csi_clk[csi] == NULL)
+ return 0;
+
+ if (flag) {
+ clk_enable(ipu->csi_clk[csi]);
+ if (wait == true)
+ msleep(10);
+ } else {
+ clk_disable(ipu->csi_clk[csi]);
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL(ipu_csi_enable_mclk);
+
+/*!
+ * ipu_csi_get_window_size
+ *
+ * @param ipu ipu handler
+ * @param width pointer to window width
+ * @param height pointer to window height
+ * @param csi csi 0 or csi 1
+ */
+void ipu_csi_get_window_size(struct ipu_soc *ipu, uint32_t *width, uint32_t *height, uint32_t csi)
+{
+ uint32_t reg;
+
+ _ipu_get(ipu);
+
+ mutex_lock(&ipu->mutex_lock);
+
+ reg = ipu_csi_read(ipu, csi, CSI_ACT_FRM_SIZE);
+ *width = (reg & 0xFFFF) + 1;
+ *height = (reg >> 16 & 0xFFFF) + 1;
+
+ mutex_unlock(&ipu->mutex_lock);
+
+ _ipu_put(ipu);
+}
+EXPORT_SYMBOL(ipu_csi_get_window_size);
+
+/*!
+ * ipu_csi_set_window_size
+ *
+ * @param ipu ipu handler
+ * @param width window width
+ * @param height window height
+ * @param csi csi 0 or csi 1
+ */
+void ipu_csi_set_window_size(struct ipu_soc *ipu, uint32_t width, uint32_t height, uint32_t csi)
+{
+ _ipu_get(ipu);
+
+ mutex_lock(&ipu->mutex_lock);
+
+ ipu_csi_write(ipu, csi, (width - 1) | (height - 1) << 16, CSI_ACT_FRM_SIZE);
+
+ mutex_unlock(&ipu->mutex_lock);
+
+ _ipu_put(ipu);
+}
+EXPORT_SYMBOL(ipu_csi_set_window_size);
+
+/*!
+ * ipu_csi_set_window_pos
+ *
+ * @param ipu ipu handler
+ * @param left uint32 window x start
+ * @param top uint32 window y start
+ * @param csi csi 0 or csi 1
+ */
+void ipu_csi_set_window_pos(struct ipu_soc *ipu, uint32_t left, uint32_t top, uint32_t csi)
+{
+ uint32_t temp;
+
+ _ipu_get(ipu);
+
+ mutex_lock(&ipu->mutex_lock);
+
+ temp = ipu_csi_read(ipu, csi, CSI_OUT_FRM_CTRL);
+ temp &= ~(CSI_HSC_MASK | CSI_VSC_MASK);
+ temp |= ((top << CSI_VSC_SHIFT) | (left << CSI_HSC_SHIFT));
+ ipu_csi_write(ipu, csi, temp, CSI_OUT_FRM_CTRL);
+
+ mutex_unlock(&ipu->mutex_lock);
+
+ _ipu_put(ipu);
+}
+EXPORT_SYMBOL(ipu_csi_set_window_pos);
+
+/*!
+ * _ipu_csi_horizontal_downsize_enable
+ * Enable horizontal downsizing(decimation) by 2.
+ *
+ * @param ipu ipu handler
+ * @param csi csi 0 or csi 1
+ */
+void _ipu_csi_horizontal_downsize_enable(struct ipu_soc *ipu, uint32_t csi)
+{
+ uint32_t temp;
+
+ temp = ipu_csi_read(ipu, csi, CSI_OUT_FRM_CTRL);
+ temp |= CSI_HORI_DOWNSIZE_EN;
+ ipu_csi_write(ipu, csi, temp, CSI_OUT_FRM_CTRL);
+}
+
+/*!
+ * _ipu_csi_horizontal_downsize_disable
+ * Disable horizontal downsizing(decimation) by 2.
+ *
+ * @param ipu ipu handler
+ * @param csi csi 0 or csi 1
+ */
+void _ipu_csi_horizontal_downsize_disable(struct ipu_soc *ipu, uint32_t csi)
+{
+ uint32_t temp;
+
+ temp = ipu_csi_read(ipu, csi, CSI_OUT_FRM_CTRL);
+ temp &= ~CSI_HORI_DOWNSIZE_EN;
+ ipu_csi_write(ipu, csi, temp, CSI_OUT_FRM_CTRL);
+}
+
+/*!
+ * _ipu_csi_vertical_downsize_enable
+ * Enable vertical downsizing(decimation) by 2.
+ *
+ * @param ipu ipu handler
+ * @param csi csi 0 or csi 1
+ */
+void _ipu_csi_vertical_downsize_enable(struct ipu_soc *ipu, uint32_t csi)
+{
+ uint32_t temp;
+
+ temp = ipu_csi_read(ipu, csi, CSI_OUT_FRM_CTRL);
+ temp |= CSI_VERT_DOWNSIZE_EN;
+ ipu_csi_write(ipu, csi, temp, CSI_OUT_FRM_CTRL);
+}
+
+/*!
+ * _ipu_csi_vertical_downsize_disable
+ * Disable vertical downsizing(decimation) by 2.
+ *
+ * @param ipu ipu handler
+ * @param csi csi 0 or csi 1
+ */
+void _ipu_csi_vertical_downsize_disable(struct ipu_soc *ipu, uint32_t csi)
+{
+ uint32_t temp;
+
+ temp = ipu_csi_read(ipu, csi, CSI_OUT_FRM_CTRL);
+ temp &= ~CSI_VERT_DOWNSIZE_EN;
+ ipu_csi_write(ipu, csi, temp, CSI_OUT_FRM_CTRL);
+}
+
+/*!
+ * _ipu_csi_set_test_generator
+ *
+ * @param ipu ipu handler
+ * @param active 1 for active and 0 for inactive
+ * @param r_value red value for the generated pattern of even pixel
+ * @param g_value green value for the generated pattern of even
+ * pixel
+ * @param b_value blue value for the generated pattern of even pixel
+ * @param pixel_clk desired pixel clock frequency in Hz
+ * @param csi csi 0 or csi 1
+ */
+void _ipu_csi_set_test_generator(struct ipu_soc *ipu, bool active, uint32_t r_value,
+ uint32_t g_value, uint32_t b_value, uint32_t pix_clk, uint32_t csi)
+{
+ uint32_t temp;
+
+ temp = ipu_csi_read(ipu, csi, CSI_TST_CTRL);
+
+ if (active == false) {
+ temp &= ~CSI_TEST_GEN_MODE_EN;
+ ipu_csi_write(ipu, csi, temp, CSI_TST_CTRL);
+ } else {
+ /* Set sensb_mclk div_ratio*/
+ _ipu_csi_mclk_set(ipu, pix_clk, csi);
+
+ temp &= ~(CSI_TEST_GEN_R_MASK | CSI_TEST_GEN_G_MASK |
+ CSI_TEST_GEN_B_MASK);
+ temp |= CSI_TEST_GEN_MODE_EN;
+ temp |= (r_value << CSI_TEST_GEN_R_SHIFT) |
+ (g_value << CSI_TEST_GEN_G_SHIFT) |
+ (b_value << CSI_TEST_GEN_B_SHIFT);
+ ipu_csi_write(ipu, csi, temp, CSI_TST_CTRL);
+ }
+}
+
+/*!
+ * _ipu_csi_ccir_err_detection_en
+ * Enable error detection and correction for
+ * CCIR interlaced mode with protection bit.
+ *
+ * @param ipu ipu handler
+ * @param csi csi 0 or csi 1
+ */
+void _ipu_csi_ccir_err_detection_enable(struct ipu_soc *ipu, uint32_t csi)
+{
+ uint32_t temp;
+
+ temp = ipu_csi_read(ipu, csi, CSI_CCIR_CODE_1);
+ temp |= CSI_CCIR_ERR_DET_EN;
+ ipu_csi_write(ipu, csi, temp, CSI_CCIR_CODE_1);
+
+}
+
+/*!
+ * _ipu_csi_ccir_err_detection_disable
+ * Disable error detection and correction for
+ * CCIR interlaced mode with protection bit.
+ *
+ * @param ipu ipu handler
+ * @param csi csi 0 or csi 1
+ */
+void _ipu_csi_ccir_err_detection_disable(struct ipu_soc *ipu, uint32_t csi)
+{
+ uint32_t temp;
+
+ temp = ipu_csi_read(ipu, csi, CSI_CCIR_CODE_1);
+ temp &= ~CSI_CCIR_ERR_DET_EN;
+ ipu_csi_write(ipu, csi, temp, CSI_CCIR_CODE_1);
+
+}
+
+/*!
+ * _ipu_csi_set_mipi_di
+ *
+ * @param ipu ipu handler
+ * @param num MIPI data identifier 0-3 handled by CSI
+ * @param di_val data identifier value
+ * @param csi csi 0 or csi 1
+ *
+ * @return Returns 0 on success or negative error code on fail
+ */
+int _ipu_csi_set_mipi_di(struct ipu_soc *ipu, uint32_t num, uint32_t di_val, uint32_t csi)
+{
+ uint32_t temp;
+ int retval = 0;
+
+ if (di_val > 0xFFL) {
+ retval = -EINVAL;
+ goto err;
+ }
+
+ temp = ipu_csi_read(ipu, csi, CSI_MIPI_DI);
+
+ switch (num) {
+ case IPU_CSI_MIPI_DI0:
+ temp &= ~CSI_MIPI_DI0_MASK;
+ temp |= (di_val << CSI_MIPI_DI0_SHIFT);
+ ipu_csi_write(ipu, csi, temp, CSI_MIPI_DI);
+ break;
+ case IPU_CSI_MIPI_DI1:
+ temp &= ~CSI_MIPI_DI1_MASK;
+ temp |= (di_val << CSI_MIPI_DI1_SHIFT);
+ ipu_csi_write(ipu, csi, temp, CSI_MIPI_DI);
+ break;
+ case IPU_CSI_MIPI_DI2:
+ temp &= ~CSI_MIPI_DI2_MASK;
+ temp |= (di_val << CSI_MIPI_DI2_SHIFT);
+ ipu_csi_write(ipu, csi, temp, CSI_MIPI_DI);
+ break;
+ case IPU_CSI_MIPI_DI3:
+ temp &= ~CSI_MIPI_DI3_MASK;
+ temp |= (di_val << CSI_MIPI_DI3_SHIFT);
+ ipu_csi_write(ipu, csi, temp, CSI_MIPI_DI);
+ break;
+ default:
+ retval = -EINVAL;
+ }
+
+err:
+ return retval;
+}
+
+/*!
+ * _ipu_csi_set_skip_isp
+ *
+ * @param ipu ipu handler
+ * @param skip select frames to be skipped and set the
+ * correspond bits to 1
+ * @param max_ratio number of frames in a skipping set and the
+ * maximum value of max_ratio is 5
+ * @param csi csi 0 or csi 1
+ *
+ * @return Returns 0 on success or negative error code on fail
+ */
+int _ipu_csi_set_skip_isp(struct ipu_soc *ipu, uint32_t skip, uint32_t max_ratio, uint32_t csi)
+{
+ uint32_t temp;
+ int retval = 0;
+
+ if (max_ratio > 5) {
+ retval = -EINVAL;
+ goto err;
+ }
+
+ temp = ipu_csi_read(ipu, csi, CSI_SKIP);
+ temp &= ~(CSI_MAX_RATIO_SKIP_ISP_MASK | CSI_SKIP_ISP_MASK);
+ temp |= (max_ratio << CSI_MAX_RATIO_SKIP_ISP_SHIFT) |
+ (skip << CSI_SKIP_ISP_SHIFT);
+ ipu_csi_write(ipu, csi, temp, CSI_SKIP);
+
+err:
+ return retval;
+}
+
+/*!
+ * _ipu_csi_set_skip_smfc
+ *
+ * @param ipu ipu handler
+ * @param skip select frames to be skipped and set the
+ * correspond bits to 1
+ * @param max_ratio number of frames in a skipping set and the
+ * maximum value of max_ratio is 5
+ * @param id csi to smfc skipping id
+ * @param csi csi 0 or csi 1
+ *
+ * @return Returns 0 on success or negative error code on fail
+ */
+int _ipu_csi_set_skip_smfc(struct ipu_soc *ipu, uint32_t skip,
+ uint32_t max_ratio, uint32_t id, uint32_t csi)
+{
+ uint32_t temp;
+ int retval = 0;
+
+ if (max_ratio > 5 || id > 3) {
+ retval = -EINVAL;
+ goto err;
+ }
+
+ temp = ipu_csi_read(ipu, csi, CSI_SKIP);
+ temp &= ~(CSI_MAX_RATIO_SKIP_SMFC_MASK | CSI_ID_2_SKIP_MASK |
+ CSI_SKIP_SMFC_MASK);
+ temp |= (max_ratio << CSI_MAX_RATIO_SKIP_SMFC_SHIFT) |
+ (id << CSI_ID_2_SKIP_SHIFT) |
+ (skip << CSI_SKIP_SMFC_SHIFT);
+ ipu_csi_write(ipu, csi, temp, CSI_SKIP);
+
+err:
+ return retval;
+}
+
+/*!
+ * _ipu_smfc_init
+ * Map CSI frames to IDMAC channels.
+ *
+ * @param ipu ipu handler
+ * @param channel IDMAC channel 0-3
+ * @param mipi_id mipi id number 0-3
+ * @param csi csi0 or csi1
+ */
+void _ipu_smfc_init(struct ipu_soc *ipu, ipu_channel_t channel, uint32_t mipi_id, uint32_t csi)
+{
+ uint32_t temp;
+
+ temp = ipu_smfc_read(ipu, SMFC_MAP);
+
+ switch (channel) {
+ case CSI_MEM0:
+ temp &= ~SMFC_MAP_CH0_MASK;
+ temp |= ((csi << 2) | mipi_id) << SMFC_MAP_CH0_SHIFT;
+ break;
+ case CSI_MEM1:
+ temp &= ~SMFC_MAP_CH1_MASK;
+ temp |= ((csi << 2) | mipi_id) << SMFC_MAP_CH1_SHIFT;
+ break;
+ case CSI_MEM2:
+ temp &= ~SMFC_MAP_CH2_MASK;
+ temp |= ((csi << 2) | mipi_id) << SMFC_MAP_CH2_SHIFT;
+ break;
+ case CSI_MEM3:
+ temp &= ~SMFC_MAP_CH3_MASK;
+ temp |= ((csi << 2) | mipi_id) << SMFC_MAP_CH3_SHIFT;
+ break;
+ default:
+ return;
+ }
+
+ ipu_smfc_write(ipu, temp, SMFC_MAP);
+}
+
+/*!
+ * _ipu_smfc_set_wmc
+ * Caution: The number of required channels, the enabled channels
+ * and the FIFO size per channel are configured restrictedly.
+ *
+ * @param ipu ipu handler
+ * @param channel IDMAC channel 0-3
+ * @param set set 1 or clear 0
+ * @param level water mark level when FIFO is on the
+ * relative size
+ */
+void _ipu_smfc_set_wmc(struct ipu_soc *ipu, ipu_channel_t channel, bool set, uint32_t level)
+{
+ uint32_t temp;
+
+ temp = ipu_smfc_read(ipu, SMFC_WMC);
+
+ switch (channel) {
+ case CSI_MEM0:
+ if (set == true) {
+ temp &= ~SMFC_WM0_SET_MASK;
+ temp |= level << SMFC_WM0_SET_SHIFT;
+ } else {
+ temp &= ~SMFC_WM0_CLR_MASK;
+ temp |= level << SMFC_WM0_CLR_SHIFT;
+ }
+ break;
+ case CSI_MEM1:
+ if (set == true) {
+ temp &= ~SMFC_WM1_SET_MASK;
+ temp |= level << SMFC_WM1_SET_SHIFT;
+ } else {
+ temp &= ~SMFC_WM1_CLR_MASK;
+ temp |= level << SMFC_WM1_CLR_SHIFT;
+ }
+ break;
+ case CSI_MEM2:
+ if (set == true) {
+ temp &= ~SMFC_WM2_SET_MASK;
+ temp |= level << SMFC_WM2_SET_SHIFT;
+ } else {
+ temp &= ~SMFC_WM2_CLR_MASK;
+ temp |= level << SMFC_WM2_CLR_SHIFT;
+ }
+ break;
+ case CSI_MEM3:
+ if (set == true) {
+ temp &= ~SMFC_WM3_SET_MASK;
+ temp |= level << SMFC_WM3_SET_SHIFT;
+ } else {
+ temp &= ~SMFC_WM3_CLR_MASK;
+ temp |= level << SMFC_WM3_CLR_SHIFT;
+ }
+ break;
+ default:
+ return;
+ }
+
+ ipu_smfc_write(ipu, temp, SMFC_WMC);
+}
+
+/*!
+ * _ipu_smfc_set_burst_size
+ *
+ * @param ipu ipu handler
+ * @param channel IDMAC channel 0-3
+ * @param bs burst size of IDMAC channel,
+ * the value programmed here shoud be BURST_SIZE-1
+ */
+void _ipu_smfc_set_burst_size(struct ipu_soc *ipu, ipu_channel_t channel, uint32_t bs)
+{
+ uint32_t temp;
+
+ temp = ipu_smfc_read(ipu, SMFC_BS);
+
+ switch (channel) {
+ case CSI_MEM0:
+ temp &= ~SMFC_BS0_MASK;
+ temp |= bs << SMFC_BS0_SHIFT;
+ break;
+ case CSI_MEM1:
+ temp &= ~SMFC_BS1_MASK;
+ temp |= bs << SMFC_BS1_SHIFT;
+ break;
+ case CSI_MEM2:
+ temp &= ~SMFC_BS2_MASK;
+ temp |= bs << SMFC_BS2_SHIFT;
+ break;
+ case CSI_MEM3:
+ temp &= ~SMFC_BS3_MASK;
+ temp |= bs << SMFC_BS3_SHIFT;
+ break;
+ default:
+ return;
+ }
+
+ ipu_smfc_write(ipu, temp, SMFC_BS);
+}
+
+/*!
+ * _ipu_csi_init
+ *
+ * @param ipu ipu handler
+ * @param channel IDMAC channel
+ * @param csi csi 0 or csi 1
+ *
+ * @return Returns 0 on success or negative error code on fail
+ */
+int _ipu_csi_init(struct ipu_soc *ipu, ipu_channel_t channel, uint32_t csi)
+{
+ uint32_t csi_sens_conf, csi_dest;
+ int retval = 0;
+
+ switch (channel) {
+ case CSI_MEM0:
+ case CSI_MEM1:
+ case CSI_MEM2:
+ case CSI_MEM3:
+ csi_dest = CSI_DATA_DEST_IDMAC;
+ break;
+ case CSI_PRP_ENC_MEM:
+ case CSI_PRP_VF_MEM:
+ csi_dest = CSI_DATA_DEST_IC;
+ break;
+ default:
+ retval = -EINVAL;
+ goto err;
+ }
+
+ csi_sens_conf = ipu_csi_read(ipu, csi, CSI_SENS_CONF);
+ csi_sens_conf &= ~CSI_SENS_CONF_DATA_DEST_MASK;
+ ipu_csi_write(ipu, csi, csi_sens_conf | (csi_dest <<
+ CSI_SENS_CONF_DATA_DEST_SHIFT), CSI_SENS_CONF);
+err:
+ return retval;
+}
+
+/*!
+ * csi_irq_handler
+ *
+ * @param irq interrupt id
+ * @param dev_id pointer to ipu handler
+ *
+ * @return Returns if irq is handled
+ */
+static irqreturn_t csi_irq_handler(int irq, void *dev_id)
+{
+ struct ipu_soc *ipu = dev_id;
+ struct completion *comp = &ipu->csi_comp;
+
+ complete(comp);
+ return IRQ_HANDLED;
+}
+
+/*!
+ * _ipu_csi_wait4eof
+ *
+ * @param ipu ipu handler
+ * @param channel IDMAC channel
+ *
+ */
+void _ipu_csi_wait4eof(struct ipu_soc *ipu, ipu_channel_t channel)
+{
+ int ret;
+ int irq = 0;
+
+ if (channel == CSI_MEM0)
+ irq = IPU_IRQ_CSI0_OUT_EOF;
+ else if (channel == CSI_MEM1)
+ irq = IPU_IRQ_CSI1_OUT_EOF;
+ else if (channel == CSI_MEM2)
+ irq = IPU_IRQ_CSI2_OUT_EOF;
+ else if (channel == CSI_MEM3)
+ irq = IPU_IRQ_CSI3_OUT_EOF;
+ else if (channel == CSI_PRP_ENC_MEM)
+ irq = IPU_IRQ_PRP_ENC_OUT_EOF;
+ else if (channel == CSI_PRP_VF_MEM)
+ irq = IPU_IRQ_PRP_VF_OUT_EOF;
+ else{
+ dev_err(ipu->dev, "Not a CSI channel\n");
+ return;
+ }
+
+ init_completion(&ipu->csi_comp);
+ ret = ipu_request_irq(ipu, irq, csi_irq_handler, 0, NULL, ipu);
+ if (ret < 0) {
+ dev_err(ipu->dev, "CSI irq %d in use\n", irq);
+ return;
+ }
+ ret = wait_for_completion_timeout(&ipu->csi_comp, msecs_to_jiffies(500));
+ ipu_free_irq(ipu, irq, ipu);
+ dev_dbg(ipu->dev, "CSI stop timeout - %d * 10ms\n", 5 - ret);
+}
diff --git a/drivers/mxc/ipu3/ipu_common.c b/drivers/mxc/ipu3/ipu_common.c
new file mode 100644
index 000000000000..c5b82f78421f
--- /dev/null
+++ b/drivers/mxc/ipu3/ipu_common.c
@@ -0,0 +1,3494 @@
+/*
+ * Copyright 2005-2016 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+/*
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/*!
+ * @file ipu_common.c
+ *
+ * @brief This file contains the IPU driver common API functions.
+ *
+ * @ingroup IPU
+ */
+#include <linux/busfreq-imx.h>
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/ipu-v3.h>
+#include <linux/irq.h>
+#include <linux/irqdesc.h>
+#include <linux/module.h>
+#include <linux/mod_devicetable.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/reset.h>
+#include <linux/spinlock.h>
+#include <linux/types.h>
+
+#include <asm/cacheflush.h>
+
+#include "ipu_param_mem.h"
+#include "ipu_regs.h"
+
+static struct ipu_soc ipu_array[MXC_IPU_MAX_NUM];
+
+/* Static functions */
+static irqreturn_t ipu_sync_irq_handler(int irq, void *desc);
+static irqreturn_t ipu_err_irq_handler(int irq, void *desc);
+
+static inline uint32_t channel_2_dma(ipu_channel_t ch, ipu_buffer_t type)
+{
+ return ((uint32_t) ch >> (6 * type)) & 0x3F;
+};
+
+static inline int _ipu_is_ic_chan(uint32_t dma_chan)
+{
+ return (((dma_chan >= 11) && (dma_chan <= 22) && (dma_chan != 17) &&
+ (dma_chan != 18)));
+}
+
+static inline int _ipu_is_vdi_out_chan(uint32_t dma_chan)
+{
+ return (dma_chan == 5);
+}
+
+static inline int _ipu_is_ic_graphic_chan(uint32_t dma_chan)
+{
+ return (dma_chan == 14 || dma_chan == 15);
+}
+
+/* Either DP BG or DP FG can be graphic window */
+static inline int _ipu_is_dp_graphic_chan(uint32_t dma_chan)
+{
+ return (dma_chan == 23 || dma_chan == 27);
+}
+
+static inline int _ipu_is_irt_chan(uint32_t dma_chan)
+{
+ return ((dma_chan >= 45) && (dma_chan <= 50));
+}
+
+static inline int _ipu_is_dmfc_chan(uint32_t dma_chan)
+{
+ return ((dma_chan >= 23) && (dma_chan <= 29));
+}
+
+static inline int _ipu_is_trb_chan(struct ipu_soc *ipu, uint32_t dma_chan)
+{
+ return (((dma_chan == 8) || (dma_chan == 9) ||
+ (dma_chan == 10) || (dma_chan == 13) ||
+ (dma_chan == 21) || (dma_chan == 23) ||
+ (dma_chan == 27) || (dma_chan == 28)) &&
+ (ipu->devtype >= IPUv3EX));
+}
+
+/*
+ * We usually use IDMAC 23 as full plane and IDMAC 27 as partial
+ * plane.
+ * IDMAC 23/24/28/41 can drive a display respectively - primary
+ * IDMAC 27 depends on IDMAC 23 - nonprimary
+ */
+static inline int _ipu_is_primary_disp_chan(uint32_t dma_chan)
+{
+ return ((dma_chan == 23) || (dma_chan == 24) ||
+ (dma_chan == 28) || (dma_chan == 41));
+}
+
+static inline int _ipu_is_sync_irq(uint32_t irq)
+{
+ /* sync interrupt register number */
+ int reg_num = irq / 32 + 1;
+
+ return ((reg_num == 1) || (reg_num == 2) || (reg_num == 3) ||
+ (reg_num == 4) || (reg_num == 7) || (reg_num == 8) ||
+ (reg_num == 11) || (reg_num == 12) || (reg_num == 13) ||
+ (reg_num == 14) || (reg_num == 15));
+}
+
+static inline uint32_t tri_cur_buf_mask(uint32_t dma_chan)
+{
+ uint32_t mask = 1UL << ((dma_chan * 2) & 0x1F);
+
+ return mask * 3;
+}
+
+static inline uint32_t tri_cur_buf_shift(uint32_t dma_chan)
+{
+ uint32_t mask = 1UL << ((dma_chan * 2) & 0x1F);
+
+ return ffs(mask) - 1;
+}
+
+#define idma_is_valid(ch) ((ch) != NO_DMA)
+#define idma_mask(ch) (idma_is_valid(ch) ? (1UL << ((ch) & 0x1F)) : 0)
+
+static inline bool idma_is_set(struct ipu_soc *ipu, uint32_t reg, uint32_t dma)
+{
+ return !!(ipu_idmac_read(ipu, reg) & idma_mask(dma));
+}
+
+static int ipu_clk_setup_enable(struct ipu_soc *ipu)
+{
+ char pixel_clk[11];
+ char pixel_clk_sel[15];
+ char pixel_clk_div[15];
+ char pixel_clk_parent0[5];
+ char pixel_clk_parent1[9];
+ char *pixel_clk_parents[2];
+ char di_clk[4];
+ char di_clk_sel[8];
+ struct clk *clk;
+ unsigned int di;
+ unsigned int ipu_id; /* for clk naming */
+ int ret;
+
+ dev_dbg(ipu->dev, "ipu_clk = %lu\n", clk_get_rate(ipu->ipu_clk));
+
+ ipu_id = ipu->id + 1;
+
+ pixel_clk_parents[0] = pixel_clk_parent0;
+ pixel_clk_parents[1] = pixel_clk_parent1;
+
+ for (di = 0; di < 2; di++) {
+ snprintf(pixel_clk_sel, sizeof(pixel_clk_sel),
+ "ipu%u_pclk%u_sel", ipu_id, di);
+ snprintf(pixel_clk_parent0, sizeof(pixel_clk_parent0),
+ "ipu%u", ipu_id);
+ snprintf(pixel_clk_parent1, sizeof(pixel_clk_parent1),
+ "ipu%u_di%u", ipu_id, di);
+ clk = clk_register_mux_pix_clk(ipu->dev, pixel_clk_sel,
+ (const char **)pixel_clk_parents,
+ ARRAY_SIZE(pixel_clk_parents),
+ 0, ipu->id, di, 0);
+ if (IS_ERR(clk)) {
+ dev_err(ipu->dev, "di%u mux clk register failed\n", di);
+ return PTR_ERR(clk);
+ }
+ ipu->pixel_clk_sel[di] = clk;
+
+ snprintf(pixel_clk_div, sizeof(pixel_clk_div),
+ "ipu%u_pclk%u_div", ipu_id, di);
+ clk = clk_register_div_pix_clk(ipu->dev, pixel_clk_div,
+ pixel_clk_sel, 0, ipu->id, di, 0);
+ if (IS_ERR(clk)) {
+ dev_err(ipu->dev, "di%u div clk register failed\n", di);
+ return PTR_ERR(clk);
+ }
+
+ snprintf(pixel_clk, sizeof(pixel_clk),
+ "ipu%u_pclk%u", ipu_id, di);
+ ipu->pixel_clk[di] = clk_register_gate_pix_clk(ipu->dev,
+ pixel_clk, pixel_clk_div,
+ CLK_SET_RATE_PARENT, ipu->id, di, 0);
+ if (IS_ERR(ipu->pixel_clk[di])) {
+ dev_err(ipu->dev,
+ "di%u gate clk register failed\n", di);
+ return PTR_ERR(ipu->pixel_clk[di]);
+ }
+
+ ret = clk_set_parent(ipu->pixel_clk_sel[di], ipu->ipu_clk);
+ if (ret) {
+ dev_err(ipu->dev, "pixel clk set parent failed\n");
+ return ret;
+ }
+
+ snprintf(di_clk, sizeof(di_clk), "di%u", di);
+ ipu->di_clk[di] = devm_clk_get(ipu->dev, di_clk);
+ if (IS_ERR(ipu->di_clk[di])) {
+ dev_err(ipu->dev, "di%u clk get failed\n", di);
+ return PTR_ERR(ipu->di_clk[di]);
+ }
+
+ snprintf(di_clk_sel, sizeof(di_clk_sel), "di%u_sel", di);
+ ipu->di_clk_sel[di] = devm_clk_get(ipu->dev, di_clk_sel);
+ if (IS_ERR(ipu->di_clk_sel[di])) {
+ dev_err(ipu->dev, "di%u sel clk get failed\n", di);
+ return PTR_ERR(ipu->di_clk_sel[di]);
+ }
+ }
+
+ return 0;
+}
+
+static int ipu_mem_reset(struct ipu_soc *ipu)
+{
+ int timeout = 1000;
+
+ ipu_cm_write(ipu, 0x807FFFFF, IPU_MEM_RST);
+
+ while (ipu_cm_read(ipu, IPU_MEM_RST) & 0x80000000) {
+ if (!timeout--)
+ return -ETIME;
+ msleep(1);
+ }
+
+ return 0;
+}
+
+struct ipu_soc *ipu_get_soc(int id)
+{
+ if (id >= MXC_IPU_MAX_NUM)
+ return ERR_PTR(-ENODEV);
+ else if (!ipu_array[id].online)
+ return ERR_PTR(-ENODEV);
+ else
+ return &(ipu_array[id]);
+}
+EXPORT_SYMBOL_GPL(ipu_get_soc);
+
+void _ipu_get(struct ipu_soc *ipu)
+{
+ int ret;
+
+ ret = clk_enable(ipu->ipu_clk);
+ if (ret < 0)
+ BUG();
+}
+
+void _ipu_put(struct ipu_soc *ipu)
+{
+ clk_disable(ipu->ipu_clk);
+}
+
+void ipu_disable_hsp_clk(struct ipu_soc *ipu)
+{
+ _ipu_put(ipu);
+}
+EXPORT_SYMBOL(ipu_disable_hsp_clk);
+
+struct ipu_devtype {
+ const char *name;
+ unsigned long cm_ofs;
+ unsigned long idmac_ofs;
+ unsigned long ic_ofs;
+ unsigned long csi0_ofs;
+ unsigned long csi1_ofs;
+ unsigned long di0_ofs;
+ unsigned long di1_ofs;
+ unsigned long smfc_ofs;
+ unsigned long dc_ofs;
+ unsigned long dmfc_ofs;
+ unsigned long vdi_ofs;
+ unsigned long cpmem_ofs;
+ unsigned long srm_ofs;
+ unsigned long tpm_ofs;
+ unsigned long dc_tmpl_ofs;
+ enum ipuv3_type type;
+ bool idmac_used_bufs_present;
+};
+
+struct ipu_platform_type {
+ struct ipu_devtype devtype;
+ unsigned int ch0123_axi;
+ unsigned int ch23_axi;
+ unsigned int ch27_axi;
+ unsigned int ch28_axi;
+ unsigned int normal_axi;
+ bool smfc_idmac_12bit_3planar_bs_fixup; /* workaround little stripes */
+ bool idmac_used_bufs_en_r;
+ bool idmac_used_bufs_en_w;
+ unsigned int idmac_used_bufs_max_r;
+ unsigned int idmac_used_bufs_max_w;
+};
+
+static struct ipu_platform_type ipu_type_imx51 = {
+ .devtype = {
+ .name = "IPUv3EX",
+ .cm_ofs = 0x1E000000,
+ .idmac_ofs = 0x1E008000,
+ .ic_ofs = 0x1E020000,
+ .csi0_ofs = 0x1E030000,
+ .csi1_ofs = 0x1E038000,
+ .di0_ofs = 0x1E040000,
+ .di1_ofs = 0x1E048000,
+ .smfc_ofs = 0x1E050000,
+ .dc_ofs = 0x1E058000,
+ .dmfc_ofs = 0x1E060000,
+ .vdi_ofs = 0x1E068000,
+ .cpmem_ofs = 0x1F000000,
+ .srm_ofs = 0x1F040000,
+ .tpm_ofs = 0x1F060000,
+ .dc_tmpl_ofs = 0x1F080000,
+ .type = IPUv3EX,
+ .idmac_used_bufs_present = false,
+ },
+ .ch0123_axi = 1,
+ .ch23_axi = 1,
+ .ch23_axi = 1,
+ .ch27_axi = 1,
+ .ch28_axi = 1,
+ .normal_axi = 0,
+ .smfc_idmac_12bit_3planar_bs_fixup = false,
+};
+
+static struct ipu_platform_type ipu_type_imx53 = {
+ .devtype = {
+ .name = "IPUv3M",
+ .cm_ofs = 0x06000000,
+ .idmac_ofs = 0x06008000,
+ .ic_ofs = 0x06020000,
+ .csi0_ofs = 0x06030000,
+ .csi1_ofs = 0x06038000,
+ .di0_ofs = 0x06040000,
+ .di1_ofs = 0x06048000,
+ .smfc_ofs = 0x06050000,
+ .dc_ofs = 0x06058000,
+ .dmfc_ofs = 0x06060000,
+ .vdi_ofs = 0x06068000,
+ .cpmem_ofs = 0x07000000,
+ .srm_ofs = 0x07040000,
+ .tpm_ofs = 0x07060000,
+ .dc_tmpl_ofs = 0x07080000,
+ .type = IPUv3M,
+ .idmac_used_bufs_present = true,
+ },
+ .ch0123_axi = 1,
+ .ch23_axi = 1,
+ .ch27_axi = 1,
+ .ch28_axi = 1,
+ .normal_axi = 0,
+ .idmac_used_bufs_en_r = false,
+ .idmac_used_bufs_en_w = false,
+ .smfc_idmac_12bit_3planar_bs_fixup = false,
+};
+
+static struct ipu_platform_type ipu_type_imx6q = {
+ .devtype = {
+ .name = "IPUv3H",
+ .cm_ofs = 0x00200000,
+ .idmac_ofs = 0x00208000,
+ .ic_ofs = 0x00220000,
+ .csi0_ofs = 0x00230000,
+ .csi1_ofs = 0x00238000,
+ .di0_ofs = 0x00240000,
+ .di1_ofs = 0x00248000,
+ .smfc_ofs = 0x00250000,
+ .dc_ofs = 0x00258000,
+ .dmfc_ofs = 0x00260000,
+ .vdi_ofs = 0x00268000,
+ .cpmem_ofs = 0x00300000,
+ .srm_ofs = 0x00340000,
+ .tpm_ofs = 0x00360000,
+ .dc_tmpl_ofs = 0x00380000,
+ .type = IPUv3H,
+ .idmac_used_bufs_present = true,
+ },
+ .ch0123_axi = 0,
+ .ch23_axi = 0,
+ .ch27_axi = 0,
+ .ch28_axi = 0,
+ .normal_axi = 1,
+ .idmac_used_bufs_en_r = false,
+ .idmac_used_bufs_en_w = false,
+ .smfc_idmac_12bit_3planar_bs_fixup = false,
+};
+
+static struct ipu_platform_type ipu_type_imx6qp = {
+ .devtype = {
+ .name = "IPUv3H",
+ .cm_ofs = 0x00200000,
+ .idmac_ofs = 0x00208000,
+ .ic_ofs = 0x00220000,
+ .csi0_ofs = 0x00230000,
+ .csi1_ofs = 0x00238000,
+ .di0_ofs = 0x00240000,
+ .di1_ofs = 0x00248000,
+ .smfc_ofs = 0x00250000,
+ .dc_ofs = 0x00258000,
+ .dmfc_ofs = 0x00260000,
+ .vdi_ofs = 0x00268000,
+ .cpmem_ofs = 0x00300000,
+ .srm_ofs = 0x00340000,
+ .tpm_ofs = 0x00360000,
+ .dc_tmpl_ofs = 0x00380000,
+ .type = IPUv3H,
+ .idmac_used_bufs_present = true,
+ },
+ .ch0123_axi = 0,
+ .ch23_axi = 0,
+ .ch27_axi = 2,
+ .ch28_axi = 3,
+ .normal_axi = 1,
+ .idmac_used_bufs_en_r = true,
+ .idmac_used_bufs_en_w = true,
+ .idmac_used_bufs_max_r = 0x3,
+ .idmac_used_bufs_max_w = 0x3,
+ .smfc_idmac_12bit_3planar_bs_fixup = true,
+ };
+
+static const struct of_device_id imx_ipuv3_dt_ids[] = {
+ { .compatible = "fsl,imx51-ipu", .data = &ipu_type_imx51, },
+ { .compatible = "fsl,imx53-ipu", .data = &ipu_type_imx53, },
+ { .compatible = "fsl,imx6q-ipu", .data = &ipu_type_imx6q, },
+ { .compatible = "fsl,imx6qp-ipu", .data = &ipu_type_imx6qp, },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, imx_ipuv3_dt_ids);
+
+/*!
+ * This function is called by the driver framework to initialize the IPU
+ * hardware.
+ *
+ * @param dev The device structure for the IPU passed in by the
+ * driver framework.
+ *
+ * @return Returns 0 on success or negative error code on error
+ */
+static int ipu_probe(struct platform_device *pdev)
+{
+ struct ipu_soc *ipu;
+ struct resource *res;
+ unsigned long ipu_base;
+ const struct of_device_id *of_id =
+ of_match_device(imx_ipuv3_dt_ids, &pdev->dev);
+ const struct ipu_platform_type *iputype = of_id->data;
+ const struct ipu_devtype *devtype = &iputype->devtype;
+ int ret = 0, id;
+ u32 bypass_reset, reg;
+
+ dev_dbg(&pdev->dev, "<%s>\n", __func__);
+
+ ret = of_property_read_u32(pdev->dev.of_node,
+ "bypass_reset", &bypass_reset);
+ if (ret < 0) {
+ dev_dbg(&pdev->dev, "can not get bypass_reset\n");
+ return ret;
+ }
+
+ id = of_alias_get_id(pdev->dev.of_node, "ipu");
+ if (id < 0) {
+ dev_dbg(&pdev->dev, "can not get alias id\n");
+ return id;
+ }
+
+ ipu = &ipu_array[id];
+ memset(ipu, 0, sizeof(struct ipu_soc));
+ ipu->bypass_reset = (bool)bypass_reset;
+ ipu->dev = &pdev->dev;
+ ipu->id = id;
+ ipu->devtype = devtype->type;
+ ipu->ch0123_axi = iputype->ch0123_axi;
+ ipu->ch23_axi = iputype->ch23_axi;
+ ipu->ch27_axi = iputype->ch27_axi;
+ ipu->ch28_axi = iputype->ch28_axi;
+ ipu->normal_axi = iputype->normal_axi;
+ ipu->smfc_idmac_12bit_3planar_bs_fixup =
+ iputype->smfc_idmac_12bit_3planar_bs_fixup;
+ spin_lock_init(&ipu->int_reg_spin_lock);
+ spin_lock_init(&ipu->rdy_reg_spin_lock);
+ mutex_init(&ipu->mutex_lock);
+
+ dev_dbg(&pdev->dev, "revision is %s\n", devtype->name);
+
+ ipu->irq_sync = platform_get_irq(pdev, 0);
+ ipu->irq_err = platform_get_irq(pdev, 1);
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+
+ if (!res || ipu->irq_sync < 0 || ipu->irq_err < 0) {
+ dev_err(&pdev->dev, "can't get device resources\n");
+ return -ENODEV;
+ }
+
+ if (!devm_request_mem_region(&pdev->dev, res->start,
+ resource_size(res), pdev->name))
+ return -EBUSY;
+
+ ret = devm_request_irq(&pdev->dev, ipu->irq_sync,
+ ipu_sync_irq_handler, 0, pdev->name, ipu);
+ if (ret) {
+ dev_err(ipu->dev, "request SYNC interrupt failed\n");
+ return ret;
+ }
+ ret = devm_request_irq(&pdev->dev, ipu->irq_err,
+ ipu_err_irq_handler, 0, pdev->name, ipu);
+ if (ret) {
+ dev_err(ipu->dev, "request ERR interrupt failed\n");
+ return ret;
+ }
+
+ ipu_base = res->start;
+
+ ipu->cm_reg = devm_ioremap(&pdev->dev,
+ ipu_base + devtype->cm_ofs, PAGE_SIZE);
+ ipu->ic_reg = devm_ioremap(&pdev->dev,
+ ipu_base + devtype->ic_ofs, PAGE_SIZE);
+ ipu->idmac_reg = devm_ioremap(&pdev->dev,
+ ipu_base + devtype->idmac_ofs, PAGE_SIZE);
+ /* DP Registers are accessed thru the SRM */
+ ipu->dp_reg = devm_ioremap(&pdev->dev,
+ ipu_base + devtype->srm_ofs, PAGE_SIZE);
+ ipu->dc_reg = devm_ioremap(&pdev->dev,
+ ipu_base + devtype->dc_ofs, PAGE_SIZE);
+ ipu->dmfc_reg = devm_ioremap(&pdev->dev,
+ ipu_base + devtype->dmfc_ofs, PAGE_SIZE);
+ ipu->di_reg[0] = devm_ioremap(&pdev->dev,
+ ipu_base + devtype->di0_ofs, PAGE_SIZE);
+ ipu->di_reg[1] = devm_ioremap(&pdev->dev,
+ ipu_base + devtype->di1_ofs, PAGE_SIZE);
+ ipu->smfc_reg = devm_ioremap(&pdev->dev,
+ ipu_base + devtype->smfc_ofs, PAGE_SIZE);
+ ipu->csi_reg[0] = devm_ioremap(&pdev->dev,
+ ipu_base + devtype->csi0_ofs, PAGE_SIZE);
+ ipu->csi_reg[1] = devm_ioremap(&pdev->dev,
+ ipu_base + devtype->csi1_ofs, PAGE_SIZE);
+ ipu->cpmem_base = devm_ioremap(&pdev->dev,
+ ipu_base + devtype->cpmem_ofs, SZ_128K);
+ ipu->tpmem_base = devm_ioremap(&pdev->dev,
+ ipu_base + devtype->tpm_ofs, SZ_64K);
+ ipu->dc_tmpl_reg = devm_ioremap(&pdev->dev,
+ ipu_base + devtype->dc_tmpl_ofs, SZ_128K);
+ ipu->vdi_reg = devm_ioremap(&pdev->dev,
+ ipu_base + devtype->vdi_ofs, PAGE_SIZE);
+ if (!ipu->cm_reg || !ipu->ic_reg || !ipu->idmac_reg ||
+ !ipu->dp_reg || !ipu->dc_reg || !ipu->dmfc_reg ||
+ !ipu->di_reg[0] || !ipu->di_reg[1] || !ipu->smfc_reg ||
+ !ipu->csi_reg[0] || !ipu->csi_reg[1] || !ipu->cpmem_base ||
+ !ipu->tpmem_base || !ipu->dc_tmpl_reg || !ipu->vdi_reg)
+ return -ENOMEM;
+
+ dev_dbg(ipu->dev, "IPU CM Regs = %p\n", ipu->cm_reg);
+ dev_dbg(ipu->dev, "IPU IC Regs = %p\n", ipu->ic_reg);
+ dev_dbg(ipu->dev, "IPU IDMAC Regs = %p\n", ipu->idmac_reg);
+ dev_dbg(ipu->dev, "IPU DP Regs = %p\n", ipu->dp_reg);
+ dev_dbg(ipu->dev, "IPU DC Regs = %p\n", ipu->dc_reg);
+ dev_dbg(ipu->dev, "IPU DMFC Regs = %p\n", ipu->dmfc_reg);
+ dev_dbg(ipu->dev, "IPU DI0 Regs = %p\n", ipu->di_reg[0]);
+ dev_dbg(ipu->dev, "IPU DI1 Regs = %p\n", ipu->di_reg[1]);
+ dev_dbg(ipu->dev, "IPU SMFC Regs = %p\n", ipu->smfc_reg);
+ dev_dbg(ipu->dev, "IPU CSI0 Regs = %p\n", ipu->csi_reg[0]);
+ dev_dbg(ipu->dev, "IPU CSI1 Regs = %p\n", ipu->csi_reg[1]);
+ dev_dbg(ipu->dev, "IPU CPMem = %p\n", ipu->cpmem_base);
+ dev_dbg(ipu->dev, "IPU TPMem = %p\n", ipu->tpmem_base);
+ dev_dbg(ipu->dev, "IPU DC Template Mem = %p\n", ipu->dc_tmpl_reg);
+ dev_dbg(ipu->dev, "IPU VDI Regs = %p\n", ipu->vdi_reg);
+
+ ipu->ipu_clk = devm_clk_get(ipu->dev, "bus");
+ if (IS_ERR(ipu->ipu_clk)) {
+ dev_err(ipu->dev, "clk_get ipu failed");
+ return PTR_ERR(ipu->ipu_clk);
+ }
+
+ /* ipu_clk is always prepared */
+ ret = clk_prepare_enable(ipu->ipu_clk);
+ if (ret < 0) {
+ dev_err(ipu->dev, "ipu clk enable failed\n");
+ return ret;
+ }
+
+ ipu->prg_clk = devm_clk_get(ipu->dev, "prg");
+ if (IS_ERR(ipu->prg_clk))
+ ipu->prg_clk = NULL;
+
+ ipu->online = true;
+
+ platform_set_drvdata(pdev, ipu);
+
+ if (!bypass_reset) {
+ ret = device_reset(&pdev->dev);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to reset: %d\n", ret);
+ return ret;
+ }
+
+ ipu_mem_reset(ipu);
+
+ ipu_disp_init(ipu);
+
+ /* Set MCU_T to divide MCU access window into 2 */
+ ipu_cm_write(ipu, 0x00400000L | (IPU_MCU_T_DEFAULT << 18),
+ IPU_DISP_GEN);
+ }
+
+ /* setup ipu clk tree after ipu reset */
+ ret = ipu_clk_setup_enable(ipu);
+ if (ret < 0) {
+ dev_err(ipu->dev, "ipu clk setup failed\n");
+ ipu->online = false;
+ return ret;
+ }
+
+ if (devtype->idmac_used_bufs_present) {
+ reg = ipu_idmac_read(ipu, IDMAC_CONF);
+ if (iputype->idmac_used_bufs_en_r)
+ reg |= IDMAC_CONF_USED_BUFS_EN_R;
+ else
+ reg &= ~IDMAC_CONF_USED_BUFS_EN_R;
+ if (iputype->idmac_used_bufs_en_w)
+ reg |= IDMAC_CONF_USED_BUFS_EN_W;
+ else
+ reg &= ~IDMAC_CONF_USED_BUFS_EN_W;
+
+ reg &= ~IDMAC_CONF_USED_BUFS_MAX_R_MASK;
+ reg |= (iputype->idmac_used_bufs_max_r <<
+ IDMAC_CONF_USED_BUFS_MAX_R_OFFSET);
+ reg &= ~IDMAC_CONF_USED_BUFS_MAX_W_MASK;
+ reg |= (iputype->idmac_used_bufs_max_w <<
+ IDMAC_CONF_USED_BUFS_MAX_W_OFFSET);
+ ipu_idmac_write(ipu, reg, IDMAC_CONF);
+ }
+
+ /* Set sync refresh channels and CSI->mem channel as high priority */
+ ipu_idmac_write(ipu, 0x18800003L, IDMAC_CHA_PRI(0));
+
+ /* Enable error interrupts by default */
+ ipu_cm_write(ipu, 0xFFFFFFFF, IPU_INT_CTRL(5));
+ ipu_cm_write(ipu, 0xFFFFFFFF, IPU_INT_CTRL(6));
+ ipu_cm_write(ipu, 0xFFFFFFFF, IPU_INT_CTRL(9));
+ ipu_cm_write(ipu, 0xFFFFFFFF, IPU_INT_CTRL(10));
+
+ if (!bypass_reset)
+ clk_disable(ipu->ipu_clk);
+
+ register_ipu_device(ipu, id);
+
+ pm_runtime_enable(&pdev->dev);
+
+ return ret;
+}
+
+int ipu_remove(struct platform_device *pdev)
+{
+ struct ipu_soc *ipu = platform_get_drvdata(pdev);
+
+ unregister_ipu_device(ipu, ipu->id);
+
+ clk_put(ipu->ipu_clk);
+
+ return 0;
+}
+
+void ipu_dump_registers(struct ipu_soc *ipu)
+{
+ dev_dbg(ipu->dev, "IPU_CONF = \t0x%08X\n", ipu_cm_read(ipu, IPU_CONF));
+ dev_dbg(ipu->dev, "IDMAC_CONF = \t0x%08X\n", ipu_idmac_read(ipu, IDMAC_CONF));
+ dev_dbg(ipu->dev, "IDMAC_CHA_EN1 = \t0x%08X\n",
+ ipu_idmac_read(ipu, IDMAC_CHA_EN(0)));
+ dev_dbg(ipu->dev, "IDMAC_CHA_EN2 = \t0x%08X\n",
+ ipu_idmac_read(ipu, IDMAC_CHA_EN(32)));
+ dev_dbg(ipu->dev, "IDMAC_CHA_PRI1 = \t0x%08X\n",
+ ipu_idmac_read(ipu, IDMAC_CHA_PRI(0)));
+ dev_dbg(ipu->dev, "IDMAC_CHA_PRI2 = \t0x%08X\n",
+ ipu_idmac_read(ipu, IDMAC_CHA_PRI(32)));
+ dev_dbg(ipu->dev, "IDMAC_BAND_EN1 = \t0x%08X\n",
+ ipu_idmac_read(ipu, IDMAC_BAND_EN(ipu->devtype, 0)));
+ dev_dbg(ipu->dev, "IDMAC_BAND_EN2 = \t0x%08X\n",
+ ipu_idmac_read(ipu, IDMAC_BAND_EN(ipu->devtype, 32)));
+ dev_dbg(ipu->dev, "IPU_CHA_DB_MODE_SEL0 = \t0x%08X\n",
+ ipu_cm_read(ipu, IPU_CHA_DB_MODE_SEL(0)));
+ dev_dbg(ipu->dev, "IPU_CHA_DB_MODE_SEL1 = \t0x%08X\n",
+ ipu_cm_read(ipu, IPU_CHA_DB_MODE_SEL(32)));
+ if (ipu->devtype >= IPUv3EX) {
+ dev_dbg(ipu->dev, "IPU_CHA_TRB_MODE_SEL0 = \t0x%08X\n",
+ ipu_cm_read(ipu, IPU_CHA_TRB_MODE_SEL(ipu->devtype, 0)));
+ dev_dbg(ipu->dev, "IPU_CHA_TRB_MODE_SEL1 = \t0x%08X\n",
+ ipu_cm_read(ipu,
+ IPU_CHA_TRB_MODE_SEL(ipu->devtype, 32)));
+ }
+ dev_dbg(ipu->dev, "DMFC_WR_CHAN = \t0x%08X\n",
+ ipu_dmfc_read(ipu, DMFC_WR_CHAN));
+ dev_dbg(ipu->dev, "DMFC_WR_CHAN_DEF = \t0x%08X\n",
+ ipu_dmfc_read(ipu, DMFC_WR_CHAN_DEF));
+ dev_dbg(ipu->dev, "DMFC_DP_CHAN = \t0x%08X\n",
+ ipu_dmfc_read(ipu, DMFC_DP_CHAN));
+ dev_dbg(ipu->dev, "DMFC_DP_CHAN_DEF = \t0x%08X\n",
+ ipu_dmfc_read(ipu, DMFC_DP_CHAN_DEF));
+ dev_dbg(ipu->dev, "DMFC_IC_CTRL = \t0x%08X\n",
+ ipu_dmfc_read(ipu, DMFC_IC_CTRL));
+ dev_dbg(ipu->dev, "IPU_FS_PROC_FLOW1 = \t0x%08X\n",
+ ipu_cm_read(ipu, IPU_FS_PROC_FLOW1));
+ dev_dbg(ipu->dev, "IPU_FS_PROC_FLOW2 = \t0x%08X\n",
+ ipu_cm_read(ipu, IPU_FS_PROC_FLOW2));
+ dev_dbg(ipu->dev, "IPU_FS_PROC_FLOW3 = \t0x%08X\n",
+ ipu_cm_read(ipu, IPU_FS_PROC_FLOW3));
+ dev_dbg(ipu->dev, "IPU_FS_DISP_FLOW1 = \t0x%08X\n",
+ ipu_cm_read(ipu, IPU_FS_DISP_FLOW1));
+ dev_dbg(ipu->dev, "IPU_VDIC_VDI_FSIZE = \t0x%08X\n",
+ ipu_vdi_read(ipu, VDI_FSIZE));
+ dev_dbg(ipu->dev, "IPU_VDIC_VDI_C = \t0x%08X\n",
+ ipu_vdi_read(ipu, VDI_C));
+ dev_dbg(ipu->dev, "IPU_IC_CONF = \t0x%08X\n",
+ ipu_ic_read(ipu, IC_CONF));
+}
+
+/*!
+ * This function is called to initialize a logical IPU channel.
+ *
+ * @param ipu ipu handler
+ * @param channel Input parameter for the logical channel ID to init.
+ *
+ * @param params Input parameter containing union of channel
+ * initialization parameters.
+ *
+ * @return Returns 0 on success or negative error code on fail
+ */
+int32_t ipu_init_channel(struct ipu_soc *ipu, ipu_channel_t channel, ipu_channel_params_t *params)
+{
+ int ret = 0;
+ bool bad_pixfmt;
+ uint32_t ipu_conf, reg, in_g_pixel_fmt, sec_dma;
+
+ dev_dbg(ipu->dev, "init channel = %d\n", IPU_CHAN_ID(channel));
+
+ ret = pm_runtime_get_sync(ipu->dev);
+ if (ret < 0) {
+ dev_err(ipu->dev, "ch = %d, pm_runtime_get failed:%d!\n",
+ IPU_CHAN_ID(channel), ret);
+ dump_stack();
+ return ret;
+ }
+ /*
+ * Here, ret could be 1 if the device's runtime PM status was
+ * already 'active', so clear it to be 0.
+ */
+ ret = 0;
+
+ _ipu_get(ipu);
+
+ mutex_lock(&ipu->mutex_lock);
+
+ /* Re-enable error interrupts every time a channel is initialized */
+ ipu_cm_write(ipu, 0xFFFFFFFF, IPU_INT_CTRL(5));
+ ipu_cm_write(ipu, 0xFFFFFFFF, IPU_INT_CTRL(6));
+ ipu_cm_write(ipu, 0xFFFFFFFF, IPU_INT_CTRL(9));
+ ipu_cm_write(ipu, 0xFFFFFFFF, IPU_INT_CTRL(10));
+
+ if (ipu->channel_init_mask & (1L << IPU_CHAN_ID(channel))) {
+ dev_warn(ipu->dev, "Warning: channel already initialized %d\n",
+ IPU_CHAN_ID(channel));
+ }
+
+ ipu_conf = ipu_cm_read(ipu, IPU_CONF);
+
+ switch (channel) {
+ case CSI_MEM0:
+ case CSI_MEM1:
+ case CSI_MEM2:
+ case CSI_MEM3:
+ if (params->csi_mem.csi > 1) {
+ ret = -EINVAL;
+ goto err;
+ }
+
+ if (params->csi_mem.interlaced)
+ ipu->chan_is_interlaced[channel_2_dma(channel,
+ IPU_OUTPUT_BUFFER)] = true;
+ else
+ ipu->chan_is_interlaced[channel_2_dma(channel,
+ IPU_OUTPUT_BUFFER)] = false;
+
+ ipu->smfc_use_count++;
+ ipu->csi_channel[params->csi_mem.csi] = channel;
+
+ /*SMFC setting*/
+ if (params->csi_mem.mipi_en) {
+ ipu_conf |= (1 << (IPU_CONF_CSI0_DATA_SOURCE_OFFSET +
+ params->csi_mem.csi));
+ _ipu_smfc_init(ipu, channel, params->csi_mem.mipi_vc,
+ params->csi_mem.csi);
+ _ipu_csi_set_mipi_di(ipu, params->csi_mem.mipi_vc,
+ params->csi_mem.mipi_id, params->csi_mem.csi);
+ } else {
+ ipu_conf &= ~(1 << (IPU_CONF_CSI0_DATA_SOURCE_OFFSET +
+ params->csi_mem.csi));
+ _ipu_smfc_init(ipu, channel, 0, params->csi_mem.csi);
+ }
+
+ /*CSI data (include compander) dest*/
+ _ipu_csi_init(ipu, channel, params->csi_mem.csi);
+ break;
+ case CSI_PRP_ENC_MEM:
+ if (params->csi_prp_enc_mem.csi > 1) {
+ ret = -EINVAL;
+ goto err;
+ }
+ if ((ipu->using_ic_dirct_ch == MEM_VDI_PRP_VF_MEM) ||
+ (ipu->using_ic_dirct_ch == MEM_VDI_MEM)) {
+ ret = -EINVAL;
+ goto err;
+ }
+ ipu->using_ic_dirct_ch = CSI_PRP_ENC_MEM;
+
+ ipu->ic_use_count++;
+ ipu->csi_channel[params->csi_prp_enc_mem.csi] = channel;
+
+ if (params->csi_prp_enc_mem.mipi_en) {
+ ipu_conf |= (1 << (IPU_CONF_CSI0_DATA_SOURCE_OFFSET +
+ params->csi_prp_enc_mem.csi));
+ _ipu_csi_set_mipi_di(ipu,
+ params->csi_prp_enc_mem.mipi_vc,
+ params->csi_prp_enc_mem.mipi_id,
+ params->csi_prp_enc_mem.csi);
+ } else
+ ipu_conf &= ~(1 << (IPU_CONF_CSI0_DATA_SOURCE_OFFSET +
+ params->csi_prp_enc_mem.csi));
+
+ /*CSI0/1 feed into IC*/
+ ipu_conf &= ~IPU_CONF_IC_INPUT;
+ if (params->csi_prp_enc_mem.csi)
+ ipu_conf |= IPU_CONF_CSI_SEL;
+ else
+ ipu_conf &= ~IPU_CONF_CSI_SEL;
+
+ /*PRP skip buffer in memory, only valid when RWS_EN is true*/
+ reg = ipu_cm_read(ipu, IPU_FS_PROC_FLOW1);
+ ipu_cm_write(ipu, reg & ~FS_ENC_IN_VALID, IPU_FS_PROC_FLOW1);
+
+ /*CSI data (include compander) dest*/
+ _ipu_csi_init(ipu, channel, params->csi_prp_enc_mem.csi);
+ _ipu_ic_init_prpenc(ipu, params, true);
+ break;
+ case CSI_PRP_VF_MEM:
+ if (params->csi_prp_vf_mem.csi > 1) {
+ ret = -EINVAL;
+ goto err;
+ }
+ if ((ipu->using_ic_dirct_ch == MEM_VDI_PRP_VF_MEM) ||
+ (ipu->using_ic_dirct_ch == MEM_VDI_MEM)) {
+ ret = -EINVAL;
+ goto err;
+ }
+ ipu->using_ic_dirct_ch = CSI_PRP_VF_MEM;
+
+ ipu->ic_use_count++;
+ ipu->csi_channel[params->csi_prp_vf_mem.csi] = channel;
+
+ if (params->csi_prp_vf_mem.mipi_en) {
+ ipu_conf |= (1 << (IPU_CONF_CSI0_DATA_SOURCE_OFFSET +
+ params->csi_prp_vf_mem.csi));
+ _ipu_csi_set_mipi_di(ipu,
+ params->csi_prp_vf_mem.mipi_vc,
+ params->csi_prp_vf_mem.mipi_id,
+ params->csi_prp_vf_mem.csi);
+ } else
+ ipu_conf &= ~(1 << (IPU_CONF_CSI0_DATA_SOURCE_OFFSET +
+ params->csi_prp_vf_mem.csi));
+
+ /*CSI0/1 feed into IC*/
+ ipu_conf &= ~IPU_CONF_IC_INPUT;
+ if (params->csi_prp_vf_mem.csi)
+ ipu_conf |= IPU_CONF_CSI_SEL;
+ else
+ ipu_conf &= ~IPU_CONF_CSI_SEL;
+
+ /*PRP skip buffer in memory, only valid when RWS_EN is true*/
+ reg = ipu_cm_read(ipu, IPU_FS_PROC_FLOW1);
+ ipu_cm_write(ipu, reg & ~FS_VF_IN_VALID, IPU_FS_PROC_FLOW1);
+
+ /*CSI data (include compander) dest*/
+ _ipu_csi_init(ipu, channel, params->csi_prp_vf_mem.csi);
+ _ipu_ic_init_prpvf(ipu, params, true);
+ break;
+ case MEM_PRP_VF_MEM:
+ if (params->mem_prp_vf_mem.graphics_combine_en) {
+ sec_dma = channel_2_dma(channel, IPU_GRAPH_IN_BUFFER);
+ in_g_pixel_fmt = params->mem_prp_vf_mem.in_g_pixel_fmt;
+ bad_pixfmt =
+ _ipu_ch_param_bad_alpha_pos(in_g_pixel_fmt);
+
+ if (params->mem_prp_vf_mem.alpha_chan_en) {
+ if (bad_pixfmt) {
+ dev_err(ipu->dev, "bad pixel format "
+ "for graphics plane from "
+ "ch%d\n", sec_dma);
+ ret = -EINVAL;
+ goto err;
+ }
+ ipu->thrd_chan_en[IPU_CHAN_ID(channel)] = true;
+ }
+ ipu->sec_chan_en[IPU_CHAN_ID(channel)] = true;
+ }
+
+ reg = ipu_cm_read(ipu, IPU_FS_PROC_FLOW1);
+ ipu_cm_write(ipu, reg | FS_VF_IN_VALID, IPU_FS_PROC_FLOW1);
+
+ _ipu_ic_init_prpvf(ipu, params, false);
+ ipu->ic_use_count++;
+ break;
+ case MEM_VDI_PRP_VF_MEM:
+ if ((ipu->using_ic_dirct_ch == CSI_PRP_VF_MEM) ||
+ (ipu->using_ic_dirct_ch == MEM_VDI_MEM) ||
+ (ipu->using_ic_dirct_ch == CSI_PRP_ENC_MEM)) {
+ ret = -EINVAL;
+ goto err;
+ }
+ ipu->using_ic_dirct_ch = MEM_VDI_PRP_VF_MEM;
+ ipu->ic_use_count++;
+ ipu->vdi_use_count++;
+ reg = ipu_cm_read(ipu, IPU_FS_PROC_FLOW1);
+ reg &= ~FS_VDI_SRC_SEL_MASK;
+ ipu_cm_write(ipu, reg , IPU_FS_PROC_FLOW1);
+
+ if (params->mem_prp_vf_mem.graphics_combine_en)
+ ipu->sec_chan_en[IPU_CHAN_ID(channel)] = true;
+ _ipu_ic_init_prpvf(ipu, params, false);
+ _ipu_vdi_init(ipu, channel, params);
+ break;
+ case MEM_VDI_PRP_VF_MEM_P:
+ case MEM_VDI_PRP_VF_MEM_N:
+ case MEM_VDI_MEM_P:
+ case MEM_VDI_MEM_N:
+ _ipu_vdi_init(ipu, channel, params);
+ break;
+ case MEM_VDI_MEM:
+ if ((ipu->using_ic_dirct_ch == CSI_PRP_VF_MEM) ||
+ (ipu->using_ic_dirct_ch == MEM_VDI_PRP_VF_MEM) ||
+ (ipu->using_ic_dirct_ch == CSI_PRP_ENC_MEM)) {
+ ret = -EINVAL;
+ goto err;
+ }
+ ipu->using_ic_dirct_ch = MEM_VDI_MEM;
+ ipu->ic_use_count++;
+ ipu->vdi_use_count++;
+ _ipu_vdi_init(ipu, channel, params);
+ break;
+ case MEM_ROT_VF_MEM:
+ ipu->ic_use_count++;
+ ipu->rot_use_count++;
+ _ipu_ic_init_rotate_vf(ipu, params);
+ break;
+ case MEM_PRP_ENC_MEM:
+ ipu->ic_use_count++;
+ reg = ipu_cm_read(ipu, IPU_FS_PROC_FLOW1);
+ ipu_cm_write(ipu, reg | FS_ENC_IN_VALID, IPU_FS_PROC_FLOW1);
+ _ipu_ic_init_prpenc(ipu, params, false);
+ break;
+ case MEM_ROT_ENC_MEM:
+ ipu->ic_use_count++;
+ ipu->rot_use_count++;
+ _ipu_ic_init_rotate_enc(ipu, params);
+ break;
+ case MEM_PP_MEM:
+ if (params->mem_pp_mem.graphics_combine_en) {
+ sec_dma = channel_2_dma(channel, IPU_GRAPH_IN_BUFFER);
+ in_g_pixel_fmt = params->mem_pp_mem.in_g_pixel_fmt;
+ bad_pixfmt =
+ _ipu_ch_param_bad_alpha_pos(in_g_pixel_fmt);
+
+ if (params->mem_pp_mem.alpha_chan_en) {
+ if (bad_pixfmt) {
+ dev_err(ipu->dev, "bad pixel format "
+ "for graphics plane from "
+ "ch%d\n", sec_dma);
+ ret = -EINVAL;
+ goto err;
+ }
+ ipu->thrd_chan_en[IPU_CHAN_ID(channel)] = true;
+ }
+
+ ipu->sec_chan_en[IPU_CHAN_ID(channel)] = true;
+ }
+
+ _ipu_ic_init_pp(ipu, params);
+ ipu->ic_use_count++;
+ break;
+ case MEM_ROT_PP_MEM:
+ _ipu_ic_init_rotate_pp(ipu, params);
+ ipu->ic_use_count++;
+ ipu->rot_use_count++;
+ break;
+ case MEM_DC_SYNC:
+ if (params->mem_dc_sync.di > 1) {
+ ret = -EINVAL;
+ goto err;
+ }
+
+ ipu->dc_di_assignment[1] = params->mem_dc_sync.di;
+ _ipu_dc_init(ipu, 1, params->mem_dc_sync.di,
+ params->mem_dc_sync.interlaced,
+ params->mem_dc_sync.out_pixel_fmt);
+ ipu->di_use_count[params->mem_dc_sync.di]++;
+ ipu->dc_use_count++;
+ ipu->dmfc_use_count++;
+ break;
+ case MEM_BG_SYNC:
+ if (params->mem_dp_bg_sync.di > 1) {
+ ret = -EINVAL;
+ goto err;
+ }
+
+ if (params->mem_dp_bg_sync.alpha_chan_en)
+ ipu->thrd_chan_en[IPU_CHAN_ID(channel)] = true;
+
+ ipu->dc_di_assignment[5] = params->mem_dp_bg_sync.di;
+ _ipu_dp_init(ipu, channel, params->mem_dp_bg_sync.in_pixel_fmt,
+ params->mem_dp_bg_sync.out_pixel_fmt);
+ _ipu_dc_init(ipu, 5, params->mem_dp_bg_sync.di,
+ params->mem_dp_bg_sync.interlaced,
+ params->mem_dp_bg_sync.out_pixel_fmt);
+ ipu->di_use_count[params->mem_dp_bg_sync.di]++;
+ ipu->dc_use_count++;
+ ipu->dp_use_count++;
+ ipu->dmfc_use_count++;
+ break;
+ case MEM_FG_SYNC:
+ _ipu_dp_init(ipu, channel, params->mem_dp_fg_sync.in_pixel_fmt,
+ params->mem_dp_fg_sync.out_pixel_fmt);
+
+ if (params->mem_dp_fg_sync.alpha_chan_en)
+ ipu->thrd_chan_en[IPU_CHAN_ID(channel)] = true;
+
+ ipu->dc_use_count++;
+ ipu->dp_use_count++;
+ ipu->dmfc_use_count++;
+ break;
+ case DIRECT_ASYNC0:
+ if (params->direct_async.di > 1) {
+ ret = -EINVAL;
+ goto err;
+ }
+
+ ipu->dc_di_assignment[8] = params->direct_async.di;
+ _ipu_dc_init(ipu, 8, params->direct_async.di, false, IPU_PIX_FMT_GENERIC);
+ ipu->di_use_count[params->direct_async.di]++;
+ ipu->dc_use_count++;
+ break;
+ case DIRECT_ASYNC1:
+ if (params->direct_async.di > 1) {
+ ret = -EINVAL;
+ goto err;
+ }
+
+ ipu->dc_di_assignment[9] = params->direct_async.di;
+ _ipu_dc_init(ipu, 9, params->direct_async.di, false, IPU_PIX_FMT_GENERIC);
+ ipu->di_use_count[params->direct_async.di]++;
+ ipu->dc_use_count++;
+ break;
+ default:
+ dev_err(ipu->dev, "Missing channel initialization\n");
+ break;
+ }
+
+ ipu->channel_init_mask |= 1L << IPU_CHAN_ID(channel);
+
+ ipu_cm_write(ipu, ipu_conf, IPU_CONF);
+
+err:
+ mutex_unlock(&ipu->mutex_lock);
+ return ret;
+}
+EXPORT_SYMBOL(ipu_init_channel);
+
+/*!
+ * This function is called to uninitialize a logical IPU channel.
+ *
+ * @param ipu ipu handler
+ * @param channel Input parameter for the logical channel ID to uninit.
+ */
+void ipu_uninit_channel(struct ipu_soc *ipu, ipu_channel_t channel)
+{
+ uint32_t reg;
+ uint32_t in_dma, out_dma = 0;
+ uint32_t ipu_conf;
+ uint32_t dc_chan = 0;
+ int ret;
+
+ mutex_lock(&ipu->mutex_lock);
+
+ if ((ipu->channel_init_mask & (1L << IPU_CHAN_ID(channel))) == 0) {
+ dev_dbg(ipu->dev, "Channel already uninitialized %d\n",
+ IPU_CHAN_ID(channel));
+ mutex_unlock(&ipu->mutex_lock);
+ return;
+ }
+
+ /* Make sure channel is disabled */
+ /* Get input and output dma channels */
+ in_dma = channel_2_dma(channel, IPU_VIDEO_IN_BUFFER);
+ out_dma = channel_2_dma(channel, IPU_OUTPUT_BUFFER);
+
+ if (idma_is_set(ipu, IDMAC_CHA_EN(in_dma), in_dma) ||
+ idma_is_set(ipu, IDMAC_CHA_EN(out_dma), out_dma)) {
+ dev_err(ipu->dev,
+ "Channel %d is not disabled, disable first\n",
+ IPU_CHAN_ID(channel));
+ mutex_unlock(&ipu->mutex_lock);
+ return;
+ }
+
+ ipu_conf = ipu_cm_read(ipu, IPU_CONF);
+
+ /* Reset the double buffer */
+ reg = ipu_cm_read(ipu, IPU_CHA_DB_MODE_SEL(in_dma));
+ ipu_cm_write(ipu, reg & ~idma_mask(in_dma), IPU_CHA_DB_MODE_SEL(in_dma));
+ reg = ipu_cm_read(ipu, IPU_CHA_DB_MODE_SEL(out_dma));
+ ipu_cm_write(ipu, reg & ~idma_mask(out_dma), IPU_CHA_DB_MODE_SEL(out_dma));
+
+ /* Reset the triple buffer */
+ reg = ipu_cm_read(ipu, IPU_CHA_TRB_MODE_SEL(ipu->devtype, in_dma));
+ ipu_cm_write(ipu, reg & ~idma_mask(in_dma),
+ IPU_CHA_TRB_MODE_SEL(ipu->devtype, in_dma));
+ reg = ipu_cm_read(ipu, IPU_CHA_TRB_MODE_SEL(ipu->devtype, out_dma));
+ ipu_cm_write(ipu, reg & ~idma_mask(out_dma),
+ IPU_CHA_TRB_MODE_SEL(ipu->devtype, out_dma));
+
+ if (_ipu_is_ic_chan(in_dma) || _ipu_is_dp_graphic_chan(in_dma)) {
+ ipu->sec_chan_en[IPU_CHAN_ID(channel)] = false;
+ ipu->thrd_chan_en[IPU_CHAN_ID(channel)] = false;
+ }
+
+ switch (channel) {
+ case CSI_MEM0:
+ case CSI_MEM1:
+ case CSI_MEM2:
+ case CSI_MEM3:
+ ipu->smfc_use_count--;
+ if (ipu->csi_channel[0] == channel) {
+ ipu->csi_channel[0] = CHAN_NONE;
+ } else if (ipu->csi_channel[1] == channel) {
+ ipu->csi_channel[1] = CHAN_NONE;
+ }
+ break;
+ case CSI_PRP_ENC_MEM:
+ ipu->ic_use_count--;
+ if (ipu->using_ic_dirct_ch == CSI_PRP_ENC_MEM)
+ ipu->using_ic_dirct_ch = 0;
+ _ipu_ic_uninit_prpenc(ipu);
+ if (ipu->csi_channel[0] == channel) {
+ ipu->csi_channel[0] = CHAN_NONE;
+ } else if (ipu->csi_channel[1] == channel) {
+ ipu->csi_channel[1] = CHAN_NONE;
+ }
+ break;
+ case CSI_PRP_VF_MEM:
+ ipu->ic_use_count--;
+ if (ipu->using_ic_dirct_ch == CSI_PRP_VF_MEM)
+ ipu->using_ic_dirct_ch = 0;
+ _ipu_ic_uninit_prpvf(ipu);
+ if (ipu->csi_channel[0] == channel) {
+ ipu->csi_channel[0] = CHAN_NONE;
+ } else if (ipu->csi_channel[1] == channel) {
+ ipu->csi_channel[1] = CHAN_NONE;
+ }
+ break;
+ case MEM_PRP_VF_MEM:
+ ipu->ic_use_count--;
+ _ipu_ic_uninit_prpvf(ipu);
+ reg = ipu_cm_read(ipu, IPU_FS_PROC_FLOW1);
+ ipu_cm_write(ipu, reg & ~FS_VF_IN_VALID, IPU_FS_PROC_FLOW1);
+ break;
+ case MEM_VDI_PRP_VF_MEM:
+ ipu->ic_use_count--;
+ ipu->vdi_use_count--;
+ if (ipu->using_ic_dirct_ch == MEM_VDI_PRP_VF_MEM)
+ ipu->using_ic_dirct_ch = 0;
+ _ipu_ic_uninit_prpvf(ipu);
+ _ipu_vdi_uninit(ipu);
+ reg = ipu_cm_read(ipu, IPU_FS_PROC_FLOW1);
+ ipu_cm_write(ipu, reg & ~FS_VF_IN_VALID, IPU_FS_PROC_FLOW1);
+ break;
+ case MEM_VDI_MEM:
+ ipu->ic_use_count--;
+ ipu->vdi_use_count--;
+ if (ipu->using_ic_dirct_ch == MEM_VDI_MEM)
+ ipu->using_ic_dirct_ch = 0;
+ _ipu_vdi_uninit(ipu);
+ break;
+ case MEM_VDI_PRP_VF_MEM_P:
+ case MEM_VDI_PRP_VF_MEM_N:
+ case MEM_VDI_MEM_P:
+ case MEM_VDI_MEM_N:
+ break;
+ case MEM_ROT_VF_MEM:
+ ipu->rot_use_count--;
+ ipu->ic_use_count--;
+ _ipu_ic_uninit_rotate_vf(ipu);
+ break;
+ case MEM_PRP_ENC_MEM:
+ ipu->ic_use_count--;
+ _ipu_ic_uninit_prpenc(ipu);
+ reg = ipu_cm_read(ipu, IPU_FS_PROC_FLOW1);
+ ipu_cm_write(ipu, reg & ~FS_ENC_IN_VALID, IPU_FS_PROC_FLOW1);
+ break;
+ case MEM_ROT_ENC_MEM:
+ ipu->rot_use_count--;
+ ipu->ic_use_count--;
+ _ipu_ic_uninit_rotate_enc(ipu);
+ break;
+ case MEM_PP_MEM:
+ ipu->ic_use_count--;
+ _ipu_ic_uninit_pp(ipu);
+ break;
+ case MEM_ROT_PP_MEM:
+ ipu->rot_use_count--;
+ ipu->ic_use_count--;
+ _ipu_ic_uninit_rotate_pp(ipu);
+ break;
+ case MEM_DC_SYNC:
+ dc_chan = 1;
+ _ipu_dc_uninit(ipu, 1);
+ ipu->di_use_count[ipu->dc_di_assignment[1]]--;
+ ipu->dc_use_count--;
+ ipu->dmfc_use_count--;
+ break;
+ case MEM_BG_SYNC:
+ dc_chan = 5;
+ _ipu_dp_uninit(ipu, channel);
+ _ipu_dc_uninit(ipu, 5);
+ ipu->di_use_count[ipu->dc_di_assignment[5]]--;
+ ipu->dc_use_count--;
+ ipu->dp_use_count--;
+ ipu->dmfc_use_count--;
+ break;
+ case MEM_FG_SYNC:
+ _ipu_dp_uninit(ipu, channel);
+ ipu->dc_use_count--;
+ ipu->dp_use_count--;
+ ipu->dmfc_use_count--;
+ break;
+ case DIRECT_ASYNC0:
+ dc_chan = 8;
+ _ipu_dc_uninit(ipu, 8);
+ ipu->di_use_count[ipu->dc_di_assignment[8]]--;
+ ipu->dc_use_count--;
+ break;
+ case DIRECT_ASYNC1:
+ dc_chan = 9;
+ _ipu_dc_uninit(ipu, 9);
+ ipu->di_use_count[ipu->dc_di_assignment[9]]--;
+ ipu->dc_use_count--;
+ break;
+ default:
+ break;
+ }
+
+ if (ipu->ic_use_count == 0)
+ ipu_conf &= ~IPU_CONF_IC_EN;
+ if (ipu->vdi_use_count == 0) {
+ ipu_conf &= ~IPU_CONF_ISP_EN;
+ ipu_conf &= ~IPU_CONF_VDI_EN;
+ ipu_conf &= ~IPU_CONF_IC_INPUT;
+ }
+ if (ipu->rot_use_count == 0)
+ ipu_conf &= ~IPU_CONF_ROT_EN;
+ if (ipu->dc_use_count == 0)
+ ipu_conf &= ~IPU_CONF_DC_EN;
+ if (ipu->dp_use_count == 0)
+ ipu_conf &= ~IPU_CONF_DP_EN;
+ if (ipu->dmfc_use_count == 0)
+ ipu_conf &= ~IPU_CONF_DMFC_EN;
+ if (ipu->di_use_count[0] == 0) {
+ ipu_conf &= ~IPU_CONF_DI0_EN;
+ }
+ if (ipu->di_use_count[1] == 0) {
+ ipu_conf &= ~IPU_CONF_DI1_EN;
+ }
+ if (ipu->smfc_use_count == 0)
+ ipu_conf &= ~IPU_CONF_SMFC_EN;
+
+ ipu_cm_write(ipu, ipu_conf, IPU_CONF);
+
+ ipu->channel_init_mask &= ~(1L << IPU_CHAN_ID(channel));
+
+ /*
+ * Disable pixel clk and its parent clock(if the parent clock
+ * usecount is 1) after clearing DC/DP/DI bits in IPU_CONF
+ * register to prevent LVDS display channel starvation.
+ */
+ if (_ipu_is_primary_disp_chan(in_dma) &&
+ ipu->pixel_clk_en[ipu->dc_di_assignment[dc_chan]]) {
+ clk_disable_unprepare(ipu->pixel_clk[ipu->dc_di_assignment[dc_chan]]);
+ ipu->pixel_clk_en[ipu->dc_di_assignment[dc_chan]] = false;
+ }
+
+ mutex_unlock(&ipu->mutex_lock);
+
+ _ipu_put(ipu);
+
+ ret = pm_runtime_put_sync_suspend(ipu->dev);
+ if (ret < 0) {
+ dev_err(ipu->dev, "ch = %d, pm_runtime_put failed:%d!\n",
+ IPU_CHAN_ID(channel), ret);
+ dump_stack();
+ }
+
+ WARN_ON(ipu->ic_use_count < 0);
+ WARN_ON(ipu->vdi_use_count < 0);
+ WARN_ON(ipu->rot_use_count < 0);
+ WARN_ON(ipu->dc_use_count < 0);
+ WARN_ON(ipu->dp_use_count < 0);
+ WARN_ON(ipu->dmfc_use_count < 0);
+ WARN_ON(ipu->smfc_use_count < 0);
+}
+EXPORT_SYMBOL(ipu_uninit_channel);
+
+/*!
+ * This function is called to initialize buffer(s) for logical IPU channel.
+ *
+ * @param ipu ipu handler
+ *
+ * @param channel Input parameter for the logical channel ID.
+ *
+ * @param type Input parameter which buffer to initialize.
+ *
+ * @param pixel_fmt Input parameter for pixel format of buffer.
+ * Pixel format is a FOURCC ASCII code.
+ *
+ * @param width Input parameter for width of buffer in pixels.
+ *
+ * @param height Input parameter for height of buffer in pixels.
+ *
+ * @param stride Input parameter for stride length of buffer
+ * in pixels.
+ *
+ * @param rot_mode Input parameter for rotation setting of buffer.
+ * A rotation setting other than
+ * IPU_ROTATE_VERT_FLIP
+ * should only be used for input buffers of
+ * rotation channels.
+ *
+ * @param phyaddr_0 Input parameter buffer 0 physical address.
+ *
+ * @param phyaddr_1 Input parameter buffer 1 physical address.
+ * Setting this to a value other than NULL enables
+ * double buffering mode.
+ *
+ * @param phyaddr_2 Input parameter buffer 2 physical address.
+ * Setting this to a value other than NULL enables
+ * triple buffering mode, phyaddr_1 should not be
+ * NULL then.
+ *
+ * @param u private u offset for additional cropping,
+ * zero if not used.
+ *
+ * @param v private v offset for additional cropping,
+ * zero if not used.
+ *
+ * @return Returns 0 on success or negative error code on fail
+ */
+int32_t ipu_init_channel_buffer(struct ipu_soc *ipu, ipu_channel_t channel,
+ ipu_buffer_t type,
+ uint32_t pixel_fmt,
+ uint16_t width, uint16_t height,
+ uint32_t stride,
+ ipu_rotate_mode_t rot_mode,
+ dma_addr_t phyaddr_0, dma_addr_t phyaddr_1,
+ dma_addr_t phyaddr_2,
+ uint32_t u, uint32_t v)
+{
+ uint32_t reg;
+ uint32_t dma_chan;
+ uint32_t burst_size;
+
+ dma_chan = channel_2_dma(channel, type);
+ if (!idma_is_valid(dma_chan))
+ return -EINVAL;
+
+ if (stride < width * bytes_per_pixel(pixel_fmt))
+ stride = width * bytes_per_pixel(pixel_fmt);
+
+ if (stride % 4) {
+ dev_err(ipu->dev,
+ "Stride not 32-bit aligned, stride = %d\n", stride);
+ return -EINVAL;
+ }
+ /* IC & IRT channels' width must be multiple of 8 pixels */
+ if ((_ipu_is_ic_chan(dma_chan) || _ipu_is_irt_chan(dma_chan))
+ && (width % 8)) {
+ dev_err(ipu->dev, "Width must be 8 pixel multiple\n");
+ return -EINVAL;
+ }
+
+ if (_ipu_is_vdi_out_chan(dma_chan) &&
+ ((width < 16) || (height < 16) || (width % 2) || (height % 4))) {
+ dev_err(ipu->dev, "vdi width/height limited err\n");
+ return -EINVAL;
+ }
+
+ /* IPUv3EX and IPUv3M support triple buffer */
+ if ((!_ipu_is_trb_chan(ipu, dma_chan)) && phyaddr_2) {
+ dev_err(ipu->dev, "Chan%d doesn't support triple buffer "
+ "mode\n", dma_chan);
+ return -EINVAL;
+ }
+ if (!phyaddr_1 && phyaddr_2) {
+ dev_err(ipu->dev, "Chan%d's buf1 physical addr is NULL for "
+ "triple buffer mode\n", dma_chan);
+ return -EINVAL;
+ }
+
+ mutex_lock(&ipu->mutex_lock);
+
+ /* Build parameter memory data for DMA channel */
+ _ipu_ch_param_init(ipu, dma_chan, pixel_fmt, width, height, stride, u, v, 0,
+ phyaddr_0, phyaddr_1, phyaddr_2);
+
+ /* Set correlative channel parameter of local alpha channel */
+ if ((_ipu_is_ic_graphic_chan(dma_chan) ||
+ _ipu_is_dp_graphic_chan(dma_chan)) &&
+ (ipu->thrd_chan_en[IPU_CHAN_ID(channel)] == true)) {
+ _ipu_ch_param_set_alpha_use_separate_channel(ipu, dma_chan, true);
+ _ipu_ch_param_set_alpha_buffer_memory(ipu, dma_chan);
+ _ipu_ch_param_set_alpha_condition_read(ipu, dma_chan);
+ /* fix alpha width as 8 and burst size as 16*/
+ _ipu_ch_params_set_alpha_width(ipu, dma_chan, 8);
+ _ipu_ch_param_set_burst_size(ipu, dma_chan, 16);
+ } else if (_ipu_is_ic_graphic_chan(dma_chan) &&
+ ipu_pixel_format_has_alpha(pixel_fmt))
+ _ipu_ch_param_set_alpha_use_separate_channel(ipu, dma_chan, false);
+
+ if (rot_mode)
+ _ipu_ch_param_set_rotation(ipu, dma_chan, rot_mode);
+
+ /* IC and ROT channels have restriction of 8 or 16 pix burst length */
+ if (_ipu_is_ic_chan(dma_chan) || _ipu_is_vdi_out_chan(dma_chan)) {
+ if ((width % 16) == 0)
+ _ipu_ch_param_set_burst_size(ipu, dma_chan, 16);
+ else
+ _ipu_ch_param_set_burst_size(ipu, dma_chan, 8);
+ } else if (_ipu_is_irt_chan(dma_chan)) {
+ _ipu_ch_param_set_burst_size(ipu, dma_chan, 8);
+ _ipu_ch_param_set_block_mode(ipu, dma_chan);
+ } else if (_ipu_is_dmfc_chan(dma_chan)) {
+ burst_size = _ipu_ch_param_get_burst_size(ipu, dma_chan);
+ _ipu_dmfc_set_wait4eot(ipu, dma_chan, width);
+ _ipu_dmfc_set_burst_size(ipu, dma_chan, burst_size);
+ }
+
+ if (_ipu_disp_chan_is_interlaced(ipu, channel) ||
+ ipu->chan_is_interlaced[dma_chan])
+ _ipu_ch_param_set_interlaced_scan(ipu, dma_chan);
+
+ if (_ipu_is_ic_chan(dma_chan) || _ipu_is_irt_chan(dma_chan) ||
+ _ipu_is_vdi_out_chan(dma_chan)) {
+ burst_size = _ipu_ch_param_get_burst_size(ipu, dma_chan);
+ _ipu_ic_idma_init(ipu, dma_chan, width, height, burst_size,
+ rot_mode);
+ } else if (_ipu_is_smfc_chan(dma_chan)) {
+ burst_size = _ipu_ch_param_get_burst_size(ipu, dma_chan);
+ /*
+ * This is different from IPUv3 spec, but it is confirmed
+ * in IPUforum that SMFC burst size should be NPB[6:3]
+ * when IDMAC works in 16-bit generic data mode.
+ */
+ if (pixel_fmt == IPU_PIX_FMT_GENERIC)
+ /* 8 bits per pixel */
+ burst_size = burst_size >> 4;
+ else if (pixel_fmt == IPU_PIX_FMT_GENERIC_16)
+ /* 16 bits per pixel */
+ burst_size = burst_size >> 3;
+ else
+ burst_size = burst_size >> 2;
+ _ipu_smfc_set_burst_size(ipu, channel, burst_size-1);
+ }
+
+ switch (dma_chan) {
+ case 0:
+ case 1:
+ case 2:
+ case 3:
+ _ipu_ch_param_set_axi_id(ipu, dma_chan, ipu->ch0123_axi);
+ break;
+ case 23:
+ _ipu_ch_param_set_axi_id(ipu, dma_chan, ipu->ch23_axi);
+ break;
+ case 27:
+ _ipu_ch_param_set_axi_id(ipu, dma_chan, ipu->ch27_axi);
+ break;
+ case 28:
+ _ipu_ch_param_set_axi_id(ipu, dma_chan, ipu->ch28_axi);
+ break;
+ default:
+ _ipu_ch_param_set_axi_id(ipu, dma_chan, ipu->normal_axi);
+ break;
+ }
+
+ if (idma_is_set(ipu, IDMAC_CHA_PRI(dma_chan), dma_chan) &&
+ ipu->devtype == IPUv3H) {
+ uint32_t reg = IDMAC_CH_LOCK_EN_1(ipu->devtype);
+ uint32_t value = 0;
+
+ switch (dma_chan) {
+ case 5:
+ value = 0x3;
+ break;
+ case 11:
+ value = 0x3 << 2;
+ break;
+ case 12:
+ value = 0x3 << 4;
+ break;
+ case 14:
+ value = 0x3 << 6;
+ break;
+ case 15:
+ value = 0x3 << 8;
+ break;
+ case 20:
+ value = 0x3 << 10;
+ break;
+ case 21:
+ value = 0x3 << 12;
+ break;
+ case 22:
+ value = 0x3 << 14;
+ break;
+ case 23:
+ value = 0x3 << 16;
+ break;
+ case 27:
+ value = 0x3 << 18;
+ break;
+ case 28:
+ value = 0x3 << 20;
+ break;
+ case 45:
+ reg = IDMAC_CH_LOCK_EN_2(ipu->devtype);
+ value = 0x3 << 0;
+ break;
+ case 46:
+ reg = IDMAC_CH_LOCK_EN_2(ipu->devtype);
+ value = 0x3 << 2;
+ break;
+ case 47:
+ reg = IDMAC_CH_LOCK_EN_2(ipu->devtype);
+ value = 0x3 << 4;
+ break;
+ case 48:
+ reg = IDMAC_CH_LOCK_EN_2(ipu->devtype);
+ value = 0x3 << 6;
+ break;
+ case 49:
+ reg = IDMAC_CH_LOCK_EN_2(ipu->devtype);
+ value = 0x3 << 8;
+ break;
+ case 50:
+ reg = IDMAC_CH_LOCK_EN_2(ipu->devtype);
+ value = 0x3 << 10;
+ break;
+ default:
+ break;
+ }
+ value |= ipu_idmac_read(ipu, reg);
+ ipu_idmac_write(ipu, value, reg);
+ }
+
+ _ipu_ch_param_dump(ipu, dma_chan);
+
+ if (phyaddr_2 && ipu->devtype >= IPUv3EX) {
+ reg = ipu_cm_read(ipu, IPU_CHA_DB_MODE_SEL(dma_chan));
+ reg &= ~idma_mask(dma_chan);
+ ipu_cm_write(ipu, reg, IPU_CHA_DB_MODE_SEL(dma_chan));
+
+ reg = ipu_cm_read(ipu,
+ IPU_CHA_TRB_MODE_SEL(ipu->devtype, dma_chan));
+ reg |= idma_mask(dma_chan);
+ ipu_cm_write(ipu, reg,
+ IPU_CHA_TRB_MODE_SEL(ipu->devtype, dma_chan));
+
+ /* Set IDMAC third buffer's cpmem number */
+ /* See __ipu_ch_get_third_buf_cpmem_num() for mapping */
+ ipu_idmac_write(ipu, 0x00444047L,
+ IDMAC_SUB_ADDR_4(ipu->devtype));
+ ipu_idmac_write(ipu, 0x46004241L,
+ IDMAC_SUB_ADDR_3(ipu->devtype));
+ ipu_idmac_write(ipu, 0x00000045L,
+ IDMAC_SUB_ADDR_1(ipu->devtype));
+
+ /* Reset to buffer 0 */
+ ipu_cm_write(ipu, tri_cur_buf_mask(dma_chan),
+ IPU_CHA_TRIPLE_CUR_BUF(ipu->devtype, dma_chan));
+ } else {
+ reg = ipu_cm_read(ipu,
+ IPU_CHA_TRB_MODE_SEL(ipu->devtype, dma_chan));
+ reg &= ~idma_mask(dma_chan);
+ ipu_cm_write(ipu, reg,
+ IPU_CHA_TRB_MODE_SEL(ipu->devtype, dma_chan));
+
+ reg = ipu_cm_read(ipu, IPU_CHA_DB_MODE_SEL(dma_chan));
+ if (phyaddr_1)
+ reg |= idma_mask(dma_chan);
+ else
+ reg &= ~idma_mask(dma_chan);
+ ipu_cm_write(ipu, reg, IPU_CHA_DB_MODE_SEL(dma_chan));
+
+ /* Reset to buffer 0 */
+ ipu_cm_write(ipu, idma_mask(dma_chan),
+ IPU_CHA_CUR_BUF(ipu->devtype, dma_chan));
+
+ }
+
+ mutex_unlock(&ipu->mutex_lock);
+
+ return 0;
+}
+EXPORT_SYMBOL(ipu_init_channel_buffer);
+
+/*!
+ * This function is called to update the physical address of a buffer for
+ * a logical IPU channel.
+ *
+ * @param ipu ipu handler
+ * @param channel Input parameter for the logical channel ID.
+ *
+ * @param type Input parameter which buffer to initialize.
+ *
+ * @param bufNum Input parameter for buffer number to update.
+ * 0 or 1 are the only valid values.
+ *
+ * @param phyaddr Input parameter buffer physical address.
+ *
+ * @return This function returns 0 on success or negative error code on
+ * fail. This function will fail if the buffer is set to ready.
+ */
+int32_t ipu_update_channel_buffer(struct ipu_soc *ipu, ipu_channel_t channel,
+ ipu_buffer_t type, uint32_t bufNum, dma_addr_t phyaddr)
+{
+ uint32_t reg;
+ int ret = 0;
+ uint32_t dma_chan = channel_2_dma(channel, type);
+ unsigned long lock_flags;
+
+ if (dma_chan == IDMA_CHAN_INVALID)
+ return -EINVAL;
+
+ spin_lock_irqsave(&ipu->rdy_reg_spin_lock, lock_flags);
+ if (bufNum == 0)
+ reg = ipu_cm_read(ipu,
+ IPU_CHA_BUF0_RDY(ipu->devtype, dma_chan));
+ else if (bufNum == 1)
+ reg = ipu_cm_read(ipu,
+ IPU_CHA_BUF1_RDY(ipu->devtype, dma_chan));
+ else
+ reg = ipu_cm_read(ipu,
+ IPU_CHA_BUF2_RDY(ipu->devtype, dma_chan));
+
+ if ((reg & idma_mask(dma_chan)) == 0)
+ _ipu_ch_param_set_buffer(ipu, dma_chan, bufNum, phyaddr);
+ else
+ ret = -EACCES;
+ spin_unlock_irqrestore(&ipu->rdy_reg_spin_lock, lock_flags);
+
+ return ret;
+}
+EXPORT_SYMBOL(ipu_update_channel_buffer);
+
+/*!
+ * This function is called to update the band mode setting for
+ * a logical IPU channel.
+ *
+ * @param ipu ipu handler
+ *
+ * @param channel Input parameter for the logical channel ID.
+ *
+ * @param type Input parameter which buffer to initialize.
+ *
+ * @param band_height Input parameter for band lines:
+ * shoule be log2(4/8/16/32/64/128/256).
+ *
+ * @return This function returns 0 on success or negative error code on
+ * fail.
+ */
+int32_t ipu_set_channel_bandmode(struct ipu_soc *ipu, ipu_channel_t channel,
+ ipu_buffer_t type, uint32_t band_height)
+{
+ uint32_t reg;
+ int ret = 0;
+ uint32_t dma_chan = channel_2_dma(channel, type);
+
+ if ((2 > band_height) || (8 < band_height))
+ return -EINVAL;
+
+ mutex_lock(&ipu->mutex_lock);
+
+ reg = ipu_idmac_read(ipu, IDMAC_BAND_EN(ipu->devtype, dma_chan));
+ reg |= 1 << (dma_chan % 32);
+ ipu_idmac_write(ipu, reg, IDMAC_BAND_EN(ipu->devtype, dma_chan));
+
+ _ipu_ch_param_set_bandmode(ipu, dma_chan, band_height);
+ dev_dbg(ipu->dev, "dma_chan:%d, band_height:%d.\n\n",
+ dma_chan, 1 << band_height);
+ mutex_unlock(&ipu->mutex_lock);
+
+ return ret;
+}
+EXPORT_SYMBOL(ipu_set_channel_bandmode);
+
+/*!
+ * This function is called to initialize a buffer for logical IPU channel.
+ *
+ * @param ipu ipu handler
+ * @param channel Input parameter for the logical channel ID.
+ *
+ * @param type Input parameter which buffer to initialize.
+ *
+ * @param pixel_fmt Input parameter for pixel format of buffer.
+ * Pixel format is a FOURCC ASCII code.
+ *
+ * @param width Input parameter for width of buffer in pixels.
+ *
+ * @param height Input parameter for height of buffer in pixels.
+ *
+ * @param stride Input parameter for stride length of buffer
+ * in pixels.
+ *
+ * @param u predefined private u offset for additional cropping,
+ * zero if not used.
+ *
+ * @param v predefined private v offset for additional cropping,
+ * zero if not used.
+ *
+ * @param vertical_offset vertical offset for Y coordinate
+ * in the existed frame
+ *
+ *
+ * @param horizontal_offset horizontal offset for X coordinate
+ * in the existed frame
+ *
+ *
+ * @return Returns 0 on success or negative error code on fail
+ * This function will fail if any buffer is set to ready.
+ */
+
+int32_t ipu_update_channel_offset(struct ipu_soc *ipu,
+ ipu_channel_t channel, ipu_buffer_t type,
+ uint32_t pixel_fmt,
+ uint16_t width, uint16_t height,
+ uint32_t stride,
+ uint32_t u, uint32_t v,
+ uint32_t vertical_offset, uint32_t horizontal_offset)
+{
+ int ret = 0;
+ uint32_t dma_chan = channel_2_dma(channel, type);
+ unsigned long lock_flags;
+
+ if (dma_chan == IDMA_CHAN_INVALID)
+ return -EINVAL;
+
+ spin_lock_irqsave(&ipu->rdy_reg_spin_lock, lock_flags);
+ if ((ipu_cm_read(ipu, IPU_CHA_BUF0_RDY(ipu->devtype, dma_chan)) &
+ idma_mask(dma_chan)) ||
+ (ipu_cm_read(ipu, IPU_CHA_BUF1_RDY(ipu->devtype, dma_chan)) &
+ idma_mask(dma_chan)) ||
+ ((ipu_cm_read(ipu, IPU_CHA_BUF2_RDY(ipu->devtype, dma_chan)) &
+ idma_mask(dma_chan)) &&
+ (ipu_cm_read(ipu, IPU_CHA_TRB_MODE_SEL(ipu->devtype, dma_chan)) &
+ idma_mask(dma_chan)) && _ipu_is_trb_chan(ipu, dma_chan)))
+ ret = -EACCES;
+ else
+ _ipu_ch_offset_update(ipu, dma_chan, pixel_fmt, width, height, stride,
+ u, v, 0, vertical_offset, horizontal_offset);
+ spin_unlock_irqrestore(&ipu->rdy_reg_spin_lock, lock_flags);
+
+ return ret;
+}
+EXPORT_SYMBOL(ipu_update_channel_offset);
+
+int32_t ipu_get_channel_offset(uint32_t pixel_fmt,
+ uint16_t width, uint16_t height,
+ uint32_t stride,
+ uint32_t u, uint32_t v,
+ uint32_t vertical_offset, uint32_t horizontal_offset,
+ uint32_t *u_offset, uint32_t *v_offset)
+{
+ return __ipu_ch_offset_calc(pixel_fmt, width, height, stride,
+ u, v, 0,
+ vertical_offset, horizontal_offset,
+ u_offset, v_offset);
+}
+EXPORT_SYMBOL(ipu_get_channel_offset);
+
+/*!
+ * This function is called to set a channel's buffer as ready.
+ *
+ * @param ipu ipu handler
+ * @param channel Input parameter for the logical channel ID.
+ *
+ * @param type Input parameter which buffer to initialize.
+ *
+ * @param bufNum Input parameter for which buffer number set to
+ * ready state.
+ *
+ * @return Returns 0 on success or negative error code on fail
+ */
+int32_t ipu_select_buffer(struct ipu_soc *ipu, ipu_channel_t channel,
+ ipu_buffer_t type, uint32_t bufNum)
+{
+ uint32_t dma_chan = channel_2_dma(channel, type);
+ unsigned long lock_flags;
+
+ if (dma_chan == IDMA_CHAN_INVALID)
+ return -EINVAL;
+
+ spin_lock_irqsave(&ipu->rdy_reg_spin_lock, lock_flags);
+ /* Mark buffer to be ready. */
+ if (bufNum == 0)
+ ipu_cm_write(ipu, idma_mask(dma_chan),
+ IPU_CHA_BUF0_RDY(ipu->devtype, dma_chan));
+ else if (bufNum == 1)
+ ipu_cm_write(ipu, idma_mask(dma_chan),
+ IPU_CHA_BUF1_RDY(ipu->devtype, dma_chan));
+ else
+ ipu_cm_write(ipu, idma_mask(dma_chan),
+ IPU_CHA_BUF2_RDY(ipu->devtype, dma_chan));
+ spin_unlock_irqrestore(&ipu->rdy_reg_spin_lock, lock_flags);
+
+ return 0;
+}
+EXPORT_SYMBOL(ipu_select_buffer);
+
+/*!
+ * This function is called to set a channel's buffer as ready.
+ *
+ * @param ipu ipu handler
+ * @param bufNum Input parameter for which buffer number set to
+ * ready state.
+ *
+ * @return Returns 0 on success or negative error code on fail
+ */
+int32_t ipu_select_multi_vdi_buffer(struct ipu_soc *ipu, uint32_t bufNum)
+{
+
+ uint32_t dma_chan = channel_2_dma(MEM_VDI_PRP_VF_MEM, IPU_INPUT_BUFFER);
+ uint32_t mask_bit =
+ idma_mask(channel_2_dma(MEM_VDI_PRP_VF_MEM_P, IPU_INPUT_BUFFER))|
+ idma_mask(dma_chan)|
+ idma_mask(channel_2_dma(MEM_VDI_PRP_VF_MEM_N, IPU_INPUT_BUFFER));
+ unsigned long lock_flags;
+
+ spin_lock_irqsave(&ipu->rdy_reg_spin_lock, lock_flags);
+ /* Mark buffers to be ready. */
+ if (bufNum == 0)
+ ipu_cm_write(ipu, mask_bit,
+ IPU_CHA_BUF0_RDY(ipu->devtype, dma_chan));
+ else
+ ipu_cm_write(ipu, mask_bit,
+ IPU_CHA_BUF1_RDY(ipu->devtype, dma_chan));
+ spin_unlock_irqrestore(&ipu->rdy_reg_spin_lock, lock_flags);
+
+ return 0;
+}
+EXPORT_SYMBOL(ipu_select_multi_vdi_buffer);
+
+#define NA -1
+static int proc_dest_sel[] = {
+ 0, 1, 1, 3, 5, 5, 4, 7, 8, 9, 10, 11, 12, 14, 15, 16,
+ 0, 1, 1, 5, 5, 5, 5, 5, 7, 8, 9, 10, 11, 12, 14, 31 };
+static int proc_src_sel[] = { 0, 6, 7, 6, 7, 8, 5, NA, NA, NA,
+ NA, NA, NA, NA, NA, 1, 2, 3, 4, 7, 8, NA, 8, NA };
+static int disp_src_sel[] = { 0, 6, 7, 8, 3, 4, 5, NA, NA, NA,
+ NA, NA, NA, NA, NA, 1, NA, 2, NA, 3, 4, 4, 4, 4 };
+
+
+/*!
+ * This function links 2 channels together for automatic frame
+ * synchronization. The output of the source channel is linked to the input of
+ * the destination channel.
+ *
+ * @param ipu ipu handler
+ * @param src_ch Input parameter for the logical channel ID of
+ * the source channel.
+ *
+ * @param dest_ch Input parameter for the logical channel ID of
+ * the destination channel.
+ *
+ * @return This function returns 0 on success or negative error code on
+ * fail.
+ */
+int32_t ipu_link_channels(struct ipu_soc *ipu, ipu_channel_t src_ch, ipu_channel_t dest_ch)
+{
+ int retval = 0;
+ uint32_t fs_proc_flow1;
+ uint32_t fs_proc_flow2;
+ uint32_t fs_proc_flow3;
+ uint32_t fs_disp_flow1;
+
+ mutex_lock(&ipu->mutex_lock);
+
+ fs_proc_flow1 = ipu_cm_read(ipu, IPU_FS_PROC_FLOW1);
+ fs_proc_flow2 = ipu_cm_read(ipu, IPU_FS_PROC_FLOW2);
+ fs_proc_flow3 = ipu_cm_read(ipu, IPU_FS_PROC_FLOW3);
+ fs_disp_flow1 = ipu_cm_read(ipu, IPU_FS_DISP_FLOW1);
+
+ switch (src_ch) {
+ case CSI_MEM0:
+ fs_proc_flow3 &= ~FS_SMFC0_DEST_SEL_MASK;
+ fs_proc_flow3 |=
+ proc_dest_sel[IPU_CHAN_ID(dest_ch)] <<
+ FS_SMFC0_DEST_SEL_OFFSET;
+ break;
+ case CSI_MEM1:
+ fs_proc_flow3 &= ~FS_SMFC1_DEST_SEL_MASK;
+ fs_proc_flow3 |=
+ proc_dest_sel[IPU_CHAN_ID(dest_ch)] <<
+ FS_SMFC1_DEST_SEL_OFFSET;
+ break;
+ case CSI_MEM2:
+ fs_proc_flow3 &= ~FS_SMFC2_DEST_SEL_MASK;
+ fs_proc_flow3 |=
+ proc_dest_sel[IPU_CHAN_ID(dest_ch)] <<
+ FS_SMFC2_DEST_SEL_OFFSET;
+ break;
+ case CSI_MEM3:
+ fs_proc_flow3 &= ~FS_SMFC3_DEST_SEL_MASK;
+ fs_proc_flow3 |=
+ proc_dest_sel[IPU_CHAN_ID(dest_ch)] <<
+ FS_SMFC3_DEST_SEL_OFFSET;
+ break;
+ case CSI_PRP_ENC_MEM:
+ fs_proc_flow2 &= ~FS_PRPENC_DEST_SEL_MASK;
+ fs_proc_flow2 |=
+ proc_dest_sel[IPU_CHAN_ID(dest_ch)] <<
+ FS_PRPENC_DEST_SEL_OFFSET;
+ break;
+ case CSI_PRP_VF_MEM:
+ fs_proc_flow2 &= ~FS_PRPVF_DEST_SEL_MASK;
+ fs_proc_flow2 |=
+ proc_dest_sel[IPU_CHAN_ID(dest_ch)] <<
+ FS_PRPVF_DEST_SEL_OFFSET;
+ break;
+ case MEM_PP_MEM:
+ fs_proc_flow2 &= ~FS_PP_DEST_SEL_MASK;
+ fs_proc_flow2 |=
+ proc_dest_sel[IPU_CHAN_ID(dest_ch)] <<
+ FS_PP_DEST_SEL_OFFSET;
+ break;
+ case MEM_ROT_PP_MEM:
+ fs_proc_flow2 &= ~FS_PP_ROT_DEST_SEL_MASK;
+ fs_proc_flow2 |=
+ proc_dest_sel[IPU_CHAN_ID(dest_ch)] <<
+ FS_PP_ROT_DEST_SEL_OFFSET;
+ break;
+ case MEM_PRP_ENC_MEM:
+ fs_proc_flow2 &= ~FS_PRPENC_DEST_SEL_MASK;
+ fs_proc_flow2 |=
+ proc_dest_sel[IPU_CHAN_ID(dest_ch)] <<
+ FS_PRPENC_DEST_SEL_OFFSET;
+ break;
+ case MEM_ROT_ENC_MEM:
+ fs_proc_flow2 &= ~FS_PRPENC_ROT_DEST_SEL_MASK;
+ fs_proc_flow2 |=
+ proc_dest_sel[IPU_CHAN_ID(dest_ch)] <<
+ FS_PRPENC_ROT_DEST_SEL_OFFSET;
+ break;
+ case MEM_PRP_VF_MEM:
+ fs_proc_flow2 &= ~FS_PRPVF_DEST_SEL_MASK;
+ fs_proc_flow2 |=
+ proc_dest_sel[IPU_CHAN_ID(dest_ch)] <<
+ FS_PRPVF_DEST_SEL_OFFSET;
+ break;
+ case MEM_VDI_PRP_VF_MEM:
+ fs_proc_flow2 &= ~FS_PRPVF_DEST_SEL_MASK;
+ fs_proc_flow2 |=
+ proc_dest_sel[IPU_CHAN_ID(dest_ch)] <<
+ FS_PRPVF_DEST_SEL_OFFSET;
+ break;
+ case MEM_ROT_VF_MEM:
+ fs_proc_flow2 &= ~FS_PRPVF_ROT_DEST_SEL_MASK;
+ fs_proc_flow2 |=
+ proc_dest_sel[IPU_CHAN_ID(dest_ch)] <<
+ FS_PRPVF_ROT_DEST_SEL_OFFSET;
+ break;
+ case MEM_VDOA_MEM:
+ fs_proc_flow3 &= ~FS_VDOA_DEST_SEL_MASK;
+ if (MEM_VDI_MEM == dest_ch)
+ fs_proc_flow3 |= FS_VDOA_DEST_SEL_VDI;
+ else if (MEM_PP_MEM == dest_ch)
+ fs_proc_flow3 |= FS_VDOA_DEST_SEL_IC;
+ else {
+ retval = -EINVAL;
+ goto err;
+ }
+ break;
+ default:
+ retval = -EINVAL;
+ goto err;
+ }
+
+ switch (dest_ch) {
+ case MEM_PP_MEM:
+ fs_proc_flow1 &= ~FS_PP_SRC_SEL_MASK;
+ if (MEM_VDOA_MEM == src_ch)
+ fs_proc_flow1 |= FS_PP_SRC_SEL_VDOA;
+ else
+ fs_proc_flow1 |= proc_src_sel[IPU_CHAN_ID(src_ch)] <<
+ FS_PP_SRC_SEL_OFFSET;
+ break;
+ case MEM_ROT_PP_MEM:
+ fs_proc_flow1 &= ~FS_PP_ROT_SRC_SEL_MASK;
+ fs_proc_flow1 |=
+ proc_src_sel[IPU_CHAN_ID(src_ch)] <<
+ FS_PP_ROT_SRC_SEL_OFFSET;
+ break;
+ case MEM_PRP_ENC_MEM:
+ fs_proc_flow1 &= ~FS_PRP_SRC_SEL_MASK;
+ fs_proc_flow1 |=
+ proc_src_sel[IPU_CHAN_ID(src_ch)] << FS_PRP_SRC_SEL_OFFSET;
+ break;
+ case MEM_ROT_ENC_MEM:
+ fs_proc_flow1 &= ~FS_PRPENC_ROT_SRC_SEL_MASK;
+ fs_proc_flow1 |=
+ proc_src_sel[IPU_CHAN_ID(src_ch)] <<
+ FS_PRPENC_ROT_SRC_SEL_OFFSET;
+ break;
+ case MEM_PRP_VF_MEM:
+ fs_proc_flow1 &= ~FS_PRP_SRC_SEL_MASK;
+ fs_proc_flow1 |=
+ proc_src_sel[IPU_CHAN_ID(src_ch)] << FS_PRP_SRC_SEL_OFFSET;
+ break;
+ case MEM_VDI_PRP_VF_MEM:
+ fs_proc_flow1 &= ~FS_PRP_SRC_SEL_MASK;
+ fs_proc_flow1 |=
+ proc_src_sel[IPU_CHAN_ID(src_ch)] << FS_PRP_SRC_SEL_OFFSET;
+ break;
+ case MEM_ROT_VF_MEM:
+ fs_proc_flow1 &= ~FS_PRPVF_ROT_SRC_SEL_MASK;
+ fs_proc_flow1 |=
+ proc_src_sel[IPU_CHAN_ID(src_ch)] <<
+ FS_PRPVF_ROT_SRC_SEL_OFFSET;
+ break;
+ case MEM_DC_SYNC:
+ fs_disp_flow1 &= ~FS_DC1_SRC_SEL_MASK;
+ fs_disp_flow1 |=
+ disp_src_sel[IPU_CHAN_ID(src_ch)] << FS_DC1_SRC_SEL_OFFSET;
+ break;
+ case MEM_BG_SYNC:
+ fs_disp_flow1 &= ~FS_DP_SYNC0_SRC_SEL_MASK;
+ fs_disp_flow1 |=
+ disp_src_sel[IPU_CHAN_ID(src_ch)] <<
+ FS_DP_SYNC0_SRC_SEL_OFFSET;
+ break;
+ case MEM_FG_SYNC:
+ fs_disp_flow1 &= ~FS_DP_SYNC1_SRC_SEL_MASK;
+ fs_disp_flow1 |=
+ disp_src_sel[IPU_CHAN_ID(src_ch)] <<
+ FS_DP_SYNC1_SRC_SEL_OFFSET;
+ break;
+ case MEM_DC_ASYNC:
+ fs_disp_flow1 &= ~FS_DC2_SRC_SEL_MASK;
+ fs_disp_flow1 |=
+ disp_src_sel[IPU_CHAN_ID(src_ch)] << FS_DC2_SRC_SEL_OFFSET;
+ break;
+ case MEM_BG_ASYNC0:
+ fs_disp_flow1 &= ~FS_DP_ASYNC0_SRC_SEL_MASK;
+ fs_disp_flow1 |=
+ disp_src_sel[IPU_CHAN_ID(src_ch)] <<
+ FS_DP_ASYNC0_SRC_SEL_OFFSET;
+ break;
+ case MEM_FG_ASYNC0:
+ fs_disp_flow1 &= ~FS_DP_ASYNC1_SRC_SEL_MASK;
+ fs_disp_flow1 |=
+ disp_src_sel[IPU_CHAN_ID(src_ch)] <<
+ FS_DP_ASYNC1_SRC_SEL_OFFSET;
+ break;
+ case MEM_VDI_MEM:
+ fs_proc_flow1 &= ~FS_VDI_SRC_SEL_MASK;
+ if (MEM_VDOA_MEM == src_ch)
+ fs_proc_flow1 |= FS_VDI_SRC_SEL_VDOA;
+ else {
+ retval = -EINVAL;
+ goto err;
+ }
+ break;
+ default:
+ retval = -EINVAL;
+ goto err;
+ }
+
+ ipu_cm_write(ipu, fs_proc_flow1, IPU_FS_PROC_FLOW1);
+ ipu_cm_write(ipu, fs_proc_flow2, IPU_FS_PROC_FLOW2);
+ ipu_cm_write(ipu, fs_proc_flow3, IPU_FS_PROC_FLOW3);
+ ipu_cm_write(ipu, fs_disp_flow1, IPU_FS_DISP_FLOW1);
+
+err:
+ mutex_unlock(&ipu->mutex_lock);
+ return retval;
+}
+EXPORT_SYMBOL(ipu_link_channels);
+
+/*!
+ * This function unlinks 2 channels and disables automatic frame
+ * synchronization.
+ *
+ * @param ipu ipu handler
+ * @param src_ch Input parameter for the logical channel ID of
+ * the source channel.
+ *
+ * @param dest_ch Input parameter for the logical channel ID of
+ * the destination channel.
+ *
+ * @return This function returns 0 on success or negative error code on
+ * fail.
+ */
+int32_t ipu_unlink_channels(struct ipu_soc *ipu, ipu_channel_t src_ch, ipu_channel_t dest_ch)
+{
+ int retval = 0;
+ uint32_t fs_proc_flow1;
+ uint32_t fs_proc_flow2;
+ uint32_t fs_proc_flow3;
+ uint32_t fs_disp_flow1;
+
+ mutex_lock(&ipu->mutex_lock);
+
+ fs_proc_flow1 = ipu_cm_read(ipu, IPU_FS_PROC_FLOW1);
+ fs_proc_flow2 = ipu_cm_read(ipu, IPU_FS_PROC_FLOW2);
+ fs_proc_flow3 = ipu_cm_read(ipu, IPU_FS_PROC_FLOW3);
+ fs_disp_flow1 = ipu_cm_read(ipu, IPU_FS_DISP_FLOW1);
+
+ switch (src_ch) {
+ case CSI_MEM0:
+ fs_proc_flow3 &= ~FS_SMFC0_DEST_SEL_MASK;
+ break;
+ case CSI_MEM1:
+ fs_proc_flow3 &= ~FS_SMFC1_DEST_SEL_MASK;
+ break;
+ case CSI_MEM2:
+ fs_proc_flow3 &= ~FS_SMFC2_DEST_SEL_MASK;
+ break;
+ case CSI_MEM3:
+ fs_proc_flow3 &= ~FS_SMFC3_DEST_SEL_MASK;
+ break;
+ case CSI_PRP_ENC_MEM:
+ fs_proc_flow2 &= ~FS_PRPENC_DEST_SEL_MASK;
+ break;
+ case CSI_PRP_VF_MEM:
+ fs_proc_flow2 &= ~FS_PRPVF_DEST_SEL_MASK;
+ break;
+ case MEM_PP_MEM:
+ fs_proc_flow2 &= ~FS_PP_DEST_SEL_MASK;
+ break;
+ case MEM_ROT_PP_MEM:
+ fs_proc_flow2 &= ~FS_PP_ROT_DEST_SEL_MASK;
+ break;
+ case MEM_PRP_ENC_MEM:
+ fs_proc_flow2 &= ~FS_PRPENC_DEST_SEL_MASK;
+ break;
+ case MEM_ROT_ENC_MEM:
+ fs_proc_flow2 &= ~FS_PRPENC_ROT_DEST_SEL_MASK;
+ break;
+ case MEM_PRP_VF_MEM:
+ fs_proc_flow2 &= ~FS_PRPVF_DEST_SEL_MASK;
+ break;
+ case MEM_VDI_PRP_VF_MEM:
+ fs_proc_flow2 &= ~FS_PRPVF_DEST_SEL_MASK;
+ break;
+ case MEM_ROT_VF_MEM:
+ fs_proc_flow2 &= ~FS_PRPVF_ROT_DEST_SEL_MASK;
+ break;
+ case MEM_VDOA_MEM:
+ fs_proc_flow3 &= ~FS_VDOA_DEST_SEL_MASK;
+ break;
+ default:
+ retval = -EINVAL;
+ goto err;
+ }
+
+ switch (dest_ch) {
+ case MEM_PP_MEM:
+ fs_proc_flow1 &= ~FS_PP_SRC_SEL_MASK;
+ break;
+ case MEM_ROT_PP_MEM:
+ fs_proc_flow1 &= ~FS_PP_ROT_SRC_SEL_MASK;
+ break;
+ case MEM_PRP_ENC_MEM:
+ fs_proc_flow1 &= ~FS_PRP_SRC_SEL_MASK;
+ break;
+ case MEM_ROT_ENC_MEM:
+ fs_proc_flow1 &= ~FS_PRPENC_ROT_SRC_SEL_MASK;
+ break;
+ case MEM_PRP_VF_MEM:
+ fs_proc_flow1 &= ~FS_PRP_SRC_SEL_MASK;
+ break;
+ case MEM_VDI_PRP_VF_MEM:
+ fs_proc_flow1 &= ~FS_PRP_SRC_SEL_MASK;
+ break;
+ case MEM_ROT_VF_MEM:
+ fs_proc_flow1 &= ~FS_PRPVF_ROT_SRC_SEL_MASK;
+ break;
+ case MEM_DC_SYNC:
+ fs_disp_flow1 &= ~FS_DC1_SRC_SEL_MASK;
+ break;
+ case MEM_BG_SYNC:
+ fs_disp_flow1 &= ~FS_DP_SYNC0_SRC_SEL_MASK;
+ break;
+ case MEM_FG_SYNC:
+ fs_disp_flow1 &= ~FS_DP_SYNC1_SRC_SEL_MASK;
+ break;
+ case MEM_DC_ASYNC:
+ fs_disp_flow1 &= ~FS_DC2_SRC_SEL_MASK;
+ break;
+ case MEM_BG_ASYNC0:
+ fs_disp_flow1 &= ~FS_DP_ASYNC0_SRC_SEL_MASK;
+ break;
+ case MEM_FG_ASYNC0:
+ fs_disp_flow1 &= ~FS_DP_ASYNC1_SRC_SEL_MASK;
+ break;
+ case MEM_VDI_MEM:
+ fs_proc_flow1 &= ~FS_VDI_SRC_SEL_MASK;
+ break;
+ default:
+ retval = -EINVAL;
+ goto err;
+ }
+
+ ipu_cm_write(ipu, fs_proc_flow1, IPU_FS_PROC_FLOW1);
+ ipu_cm_write(ipu, fs_proc_flow2, IPU_FS_PROC_FLOW2);
+ ipu_cm_write(ipu, fs_proc_flow3, IPU_FS_PROC_FLOW3);
+ ipu_cm_write(ipu, fs_disp_flow1, IPU_FS_DISP_FLOW1);
+
+err:
+ mutex_unlock(&ipu->mutex_lock);
+ return retval;
+}
+EXPORT_SYMBOL(ipu_unlink_channels);
+
+/*!
+ * This function check whether a logical channel was enabled.
+ *
+ * @param ipu ipu handler
+ * @param channel Input parameter for the logical channel ID.
+ *
+ * @return This function returns 1 while request channel is enabled or
+ * 0 for not enabled.
+ */
+int32_t ipu_is_channel_busy(struct ipu_soc *ipu, ipu_channel_t channel)
+{
+ uint32_t reg;
+ uint32_t in_dma;
+ uint32_t out_dma;
+
+ out_dma = channel_2_dma(channel, IPU_OUTPUT_BUFFER);
+ in_dma = channel_2_dma(channel, IPU_VIDEO_IN_BUFFER);
+
+ reg = ipu_idmac_read(ipu, IDMAC_CHA_EN(in_dma));
+ if (reg & idma_mask(in_dma))
+ return 1;
+ reg = ipu_idmac_read(ipu, IDMAC_CHA_EN(out_dma));
+ if (reg & idma_mask(out_dma))
+ return 1;
+ return 0;
+}
+EXPORT_SYMBOL(ipu_is_channel_busy);
+
+/*!
+ * This function enables a logical channel.
+ *
+ * @param ipu ipu handler
+ * @param channel Input parameter for the logical channel ID.
+ *
+ * @return This function returns 0 on success or negative error code on
+ * fail.
+ */
+int32_t ipu_enable_channel(struct ipu_soc *ipu, ipu_channel_t channel)
+{
+ uint32_t reg;
+ uint32_t ipu_conf;
+ uint32_t in_dma;
+ uint32_t out_dma;
+ uint32_t sec_dma;
+ uint32_t thrd_dma;
+ uint32_t di = 0;
+
+ mutex_lock(&ipu->mutex_lock);
+
+ if (ipu->channel_enable_mask & (1L << IPU_CHAN_ID(channel))) {
+ dev_err(ipu->dev, "Warning: channel already enabled %d\n",
+ IPU_CHAN_ID(channel));
+ mutex_unlock(&ipu->mutex_lock);
+ return -EACCES;
+ }
+
+ /* Get input and output dma channels */
+ out_dma = channel_2_dma(channel, IPU_OUTPUT_BUFFER);
+ in_dma = channel_2_dma(channel, IPU_VIDEO_IN_BUFFER);
+
+ ipu_conf = ipu_cm_read(ipu, IPU_CONF);
+ switch (channel) {
+ case MEM_BG_SYNC:
+ di = ipu->dc_di_assignment[5];
+ if (ipu->di_use_count[di] > 0)
+ ipu_conf |= di ? IPU_CONF_DI1_EN : IPU_CONF_DI0_EN;
+ if (ipu->dp_use_count > 0)
+ ipu_conf |= IPU_CONF_DP_EN;
+ if (ipu->dc_use_count > 0)
+ ipu_conf |= IPU_CONF_DC_EN;
+ if (ipu->dmfc_use_count > 0)
+ ipu_conf |= IPU_CONF_DMFC_EN;
+ break;
+ case MEM_DC_SYNC:
+ di = ipu->dc_di_assignment[1];
+ if (ipu->di_use_count[di] > 0)
+ ipu_conf |= di ? IPU_CONF_DI1_EN : IPU_CONF_DI0_EN;
+ if (ipu->dc_use_count > 0)
+ ipu_conf |= IPU_CONF_DC_EN;
+ if (ipu->dmfc_use_count > 0)
+ ipu_conf |= IPU_CONF_DMFC_EN;
+ break;
+ case MEM_FG_SYNC:
+ if (ipu->dp_use_count > 0)
+ ipu_conf |= IPU_CONF_DP_EN;
+ if (ipu->dc_use_count > 0)
+ ipu_conf |= IPU_CONF_DC_EN;
+ if (ipu->dmfc_use_count > 0)
+ ipu_conf |= IPU_CONF_DMFC_EN;
+ break;
+ case DIRECT_ASYNC0:
+ di = ipu->dc_di_assignment[8];
+ /* fall through */
+ case DIRECT_ASYNC1:
+ di = ipu->dc_di_assignment[9];
+ if (ipu->di_use_count[di] > 0)
+ ipu_conf |= di ? IPU_CONF_DI1_EN : IPU_CONF_DI0_EN;
+ if (ipu->dc_use_count > 0)
+ ipu_conf |= IPU_CONF_DC_EN;
+ break;
+ case MEM_ROT_PP_MEM:
+ case MEM_ROT_ENC_MEM:
+ case MEM_ROT_VF_MEM:
+ if (ipu->rot_use_count > 0)
+ ipu_conf |= IPU_CONF_ROT_EN;
+ /* fall through */
+ case MEM_PP_MEM:
+ case MEM_PRP_ENC_MEM:
+ case MEM_PRP_VF_MEM:
+ case CSI_PRP_ENC_MEM:
+ case CSI_PRP_VF_MEM:
+ if (ipu->ic_use_count > 0)
+ ipu_conf |= IPU_CONF_IC_EN;
+ break;
+ case CSI_MEM0:
+ case CSI_MEM1:
+ case CSI_MEM2:
+ case CSI_MEM3:
+ if (ipu->smfc_use_count > 0)
+ ipu_conf |= IPU_CONF_SMFC_EN;
+ break;
+ case MEM_VDI_PRP_VF_MEM:
+ case MEM_VDI_MEM:
+ if (ipu->vdi_use_count > 0) {
+ ipu_conf |= IPU_CONF_ISP_EN;
+ ipu_conf |= IPU_CONF_VDI_EN;
+ ipu_conf |= IPU_CONF_IC_INPUT;
+ }
+ if (ipu->ic_use_count > 0)
+ ipu_conf |= IPU_CONF_IC_EN;
+ break;
+ default:
+ break;
+ }
+ ipu_cm_write(ipu, ipu_conf, IPU_CONF);
+
+ if (idma_is_valid(in_dma)) {
+ reg = ipu_idmac_read(ipu, IDMAC_CHA_EN(in_dma));
+ ipu_idmac_write(ipu, reg | idma_mask(in_dma), IDMAC_CHA_EN(in_dma));
+ }
+ if (idma_is_valid(out_dma)) {
+ reg = ipu_idmac_read(ipu, IDMAC_CHA_EN(out_dma));
+ ipu_idmac_write(ipu, reg | idma_mask(out_dma), IDMAC_CHA_EN(out_dma));
+ }
+
+ if ((ipu->sec_chan_en[IPU_CHAN_ID(channel)]) &&
+ ((channel == MEM_PP_MEM) || (channel == MEM_PRP_VF_MEM) ||
+ (channel == MEM_VDI_PRP_VF_MEM))) {
+ sec_dma = channel_2_dma(channel, IPU_GRAPH_IN_BUFFER);
+ reg = ipu_idmac_read(ipu, IDMAC_CHA_EN(sec_dma));
+ ipu_idmac_write(ipu, reg | idma_mask(sec_dma), IDMAC_CHA_EN(sec_dma));
+ }
+ if ((ipu->thrd_chan_en[IPU_CHAN_ID(channel)]) &&
+ ((channel == MEM_PP_MEM) || (channel == MEM_PRP_VF_MEM))) {
+ thrd_dma = channel_2_dma(channel, IPU_ALPHA_IN_BUFFER);
+ reg = ipu_idmac_read(ipu, IDMAC_CHA_EN(thrd_dma));
+ ipu_idmac_write(ipu, reg | idma_mask(thrd_dma), IDMAC_CHA_EN(thrd_dma));
+
+ sec_dma = channel_2_dma(channel, IPU_GRAPH_IN_BUFFER);
+ reg = ipu_idmac_read(ipu, IDMAC_SEP_ALPHA);
+ ipu_idmac_write(ipu, reg | idma_mask(sec_dma), IDMAC_SEP_ALPHA);
+ } else if ((ipu->thrd_chan_en[IPU_CHAN_ID(channel)]) &&
+ ((channel == MEM_BG_SYNC) || (channel == MEM_FG_SYNC))) {
+ thrd_dma = channel_2_dma(channel, IPU_ALPHA_IN_BUFFER);
+ reg = ipu_idmac_read(ipu, IDMAC_CHA_EN(thrd_dma));
+ ipu_idmac_write(ipu, reg | idma_mask(thrd_dma), IDMAC_CHA_EN(thrd_dma));
+ reg = ipu_idmac_read(ipu, IDMAC_SEP_ALPHA);
+ ipu_idmac_write(ipu, reg | idma_mask(in_dma), IDMAC_SEP_ALPHA);
+ }
+
+ if ((channel == MEM_DC_SYNC) || (channel == MEM_BG_SYNC) ||
+ (channel == MEM_FG_SYNC)) {
+ reg = ipu_idmac_read(ipu, IDMAC_WM_EN(in_dma));
+ ipu_idmac_write(ipu, reg | idma_mask(in_dma), IDMAC_WM_EN(in_dma));
+
+ _ipu_dp_dc_enable(ipu, channel);
+ }
+
+ if (_ipu_is_ic_chan(in_dma) || _ipu_is_ic_chan(out_dma) ||
+ _ipu_is_irt_chan(in_dma) || _ipu_is_irt_chan(out_dma) ||
+ _ipu_is_vdi_out_chan(out_dma))
+ _ipu_ic_enable_task(ipu, channel);
+
+ ipu->channel_enable_mask |= 1L << IPU_CHAN_ID(channel);
+
+ if (ipu->prg_clk)
+ clk_prepare_enable(ipu->prg_clk);
+
+ mutex_unlock(&ipu->mutex_lock);
+
+ return 0;
+}
+EXPORT_SYMBOL(ipu_enable_channel);
+
+/*!
+ * This function check buffer ready for a logical channel.
+ *
+ * @param ipu ipu handler
+ * @param channel Input parameter for the logical channel ID.
+ *
+ * @param type Input parameter which buffer to clear.
+ *
+ * @param bufNum Input parameter for which buffer number clear
+ * ready state.
+ *
+ */
+int32_t ipu_check_buffer_ready(struct ipu_soc *ipu, ipu_channel_t channel, ipu_buffer_t type,
+ uint32_t bufNum)
+{
+ uint32_t dma_chan = channel_2_dma(channel, type);
+ uint32_t reg;
+ unsigned long lock_flags;
+
+ if (dma_chan == IDMA_CHAN_INVALID)
+ return -EINVAL;
+
+ spin_lock_irqsave(&ipu->rdy_reg_spin_lock, lock_flags);
+ if (bufNum == 0)
+ reg = ipu_cm_read(ipu,
+ IPU_CHA_BUF0_RDY(ipu->devtype, dma_chan));
+ else if (bufNum == 1)
+ reg = ipu_cm_read(ipu,
+ IPU_CHA_BUF1_RDY(ipu->devtype, dma_chan));
+ else
+ reg = ipu_cm_read(ipu,
+ IPU_CHA_BUF2_RDY(ipu->devtype, dma_chan));
+ spin_unlock_irqrestore(&ipu->rdy_reg_spin_lock, lock_flags);
+
+ if (reg & idma_mask(dma_chan))
+ return 1;
+ else
+ return 0;
+}
+EXPORT_SYMBOL(ipu_check_buffer_ready);
+
+/*!
+ * This function clear buffer ready for a logical channel.
+ *
+ * @param ipu ipu handler
+ * @param channel Input parameter for the logical channel ID.
+ *
+ * @param type Input parameter which buffer to clear.
+ *
+ * @param bufNum Input parameter for which buffer number clear
+ * ready state.
+ *
+ */
+void _ipu_clear_buffer_ready(struct ipu_soc *ipu, ipu_channel_t channel, ipu_buffer_t type,
+ uint32_t bufNum)
+{
+ uint32_t dma_ch = channel_2_dma(channel, type);
+
+ if (!idma_is_valid(dma_ch))
+ return;
+
+ ipu_cm_write(ipu, 0xF0300000, IPU_GPR); /* write one to clear */
+ if (bufNum == 0)
+ ipu_cm_write(ipu, idma_mask(dma_ch),
+ IPU_CHA_BUF0_RDY(ipu->devtype, dma_ch));
+ else if (bufNum == 1)
+ ipu_cm_write(ipu, idma_mask(dma_ch),
+ IPU_CHA_BUF1_RDY(ipu->devtype, dma_ch));
+ else
+ ipu_cm_write(ipu, idma_mask(dma_ch),
+ IPU_CHA_BUF2_RDY(ipu->devtype, dma_ch));
+ ipu_cm_write(ipu, 0x0, IPU_GPR); /* write one to set */
+}
+
+void ipu_clear_buffer_ready(struct ipu_soc *ipu, ipu_channel_t channel, ipu_buffer_t type,
+ uint32_t bufNum)
+{
+ unsigned long lock_flags;
+
+ spin_lock_irqsave(&ipu->rdy_reg_spin_lock, lock_flags);
+ _ipu_clear_buffer_ready(ipu, channel, type, bufNum);
+ spin_unlock_irqrestore(&ipu->rdy_reg_spin_lock, lock_flags);
+}
+EXPORT_SYMBOL(ipu_clear_buffer_ready);
+
+/*!
+ * This function disables a logical channel.
+ *
+ * @param ipu ipu handler
+ * @param channel Input parameter for the logical channel ID.
+ *
+ * @param wait_for_stop Flag to set whether to wait for channel end
+ * of frame or return immediately.
+ *
+ * @return This function returns 0 on success or negative error code on
+ * fail.
+ */
+int32_t ipu_disable_channel(struct ipu_soc *ipu, ipu_channel_t channel, bool wait_for_stop)
+{
+ uint32_t reg;
+ uint32_t in_dma;
+ uint32_t out_dma;
+ uint32_t sec_dma = NO_DMA;
+ uint32_t thrd_dma = NO_DMA;
+ uint16_t fg_pos_x, fg_pos_y;
+ unsigned long lock_flags;
+
+ mutex_lock(&ipu->mutex_lock);
+
+ if ((ipu->channel_enable_mask & (1L << IPU_CHAN_ID(channel))) == 0) {
+ dev_dbg(ipu->dev, "Channel already disabled %d\n",
+ IPU_CHAN_ID(channel));
+ mutex_unlock(&ipu->mutex_lock);
+ return -EACCES;
+ }
+
+ /* Get input and output dma channels */
+ out_dma = channel_2_dma(channel, IPU_OUTPUT_BUFFER);
+ in_dma = channel_2_dma(channel, IPU_VIDEO_IN_BUFFER);
+
+ if ((idma_is_valid(in_dma) &&
+ !idma_is_set(ipu, IDMAC_CHA_EN(in_dma), in_dma))
+ && (idma_is_valid(out_dma) &&
+ !idma_is_set(ipu, IDMAC_CHA_EN(out_dma), out_dma))) {
+ mutex_unlock(&ipu->mutex_lock);
+ return -EINVAL;
+ }
+
+ if (ipu->sec_chan_en[IPU_CHAN_ID(channel)])
+ sec_dma = channel_2_dma(channel, IPU_GRAPH_IN_BUFFER);
+ if (ipu->thrd_chan_en[IPU_CHAN_ID(channel)]) {
+ sec_dma = channel_2_dma(channel, IPU_GRAPH_IN_BUFFER);
+ thrd_dma = channel_2_dma(channel, IPU_ALPHA_IN_BUFFER);
+ }
+
+ if ((channel == MEM_BG_SYNC) || (channel == MEM_FG_SYNC) ||
+ (channel == MEM_DC_SYNC)) {
+ if (channel == MEM_FG_SYNC) {
+ _ipu_disp_get_window_pos(ipu, channel, &fg_pos_x, &fg_pos_y);
+ _ipu_disp_set_window_pos(ipu, channel, 0, 0);
+ }
+
+ _ipu_dp_dc_disable(ipu, channel, false);
+
+ /*
+ * wait for BG channel EOF then disable FG-IDMAC,
+ * it avoid FG NFB4EOF error.
+ */
+ if ((channel == MEM_FG_SYNC) && (ipu_is_channel_busy(ipu, MEM_BG_SYNC))) {
+ int timeout = 50;
+
+ ipu_cm_write(ipu, IPUIRQ_2_MASK(IPU_IRQ_BG_SYNC_EOF),
+ IPUIRQ_2_STATREG(ipu->devtype,
+ IPU_IRQ_BG_SYNC_EOF));
+ while ((ipu_cm_read(ipu,
+ IPUIRQ_2_STATREG(ipu->devtype,
+ IPU_IRQ_BG_SYNC_EOF)) &
+ IPUIRQ_2_MASK(IPU_IRQ_BG_SYNC_EOF)) == 0) {
+ msleep(10);
+ timeout -= 10;
+ if (timeout <= 0) {
+ dev_err(ipu->dev, "warning: wait for bg sync eof timeout\n");
+ break;
+ }
+ }
+ }
+ } else if (wait_for_stop && !_ipu_is_smfc_chan(out_dma) &&
+ channel != CSI_PRP_VF_MEM && channel != CSI_PRP_ENC_MEM) {
+ while (idma_is_set(ipu, IDMAC_CHA_BUSY(ipu->devtype, in_dma),
+ in_dma) ||
+ idma_is_set(ipu, IDMAC_CHA_BUSY(ipu->devtype, out_dma),
+ out_dma) ||
+ (ipu->sec_chan_en[IPU_CHAN_ID(channel)] &&
+ idma_is_set(ipu, IDMAC_CHA_BUSY(ipu->devtype, sec_dma),
+ sec_dma)) ||
+ (ipu->thrd_chan_en[IPU_CHAN_ID(channel)] &&
+ idma_is_set(ipu, IDMAC_CHA_BUSY(ipu->devtype, thrd_dma),
+ thrd_dma))) {
+ uint32_t irq = 0xffffffff;
+ int timeout = 50000;
+
+ if (idma_is_set(ipu, IDMAC_CHA_BUSY(ipu->devtype,
+ out_dma), out_dma))
+ irq = out_dma;
+ if (ipu->sec_chan_en[IPU_CHAN_ID(channel)] &&
+ idma_is_set(ipu, IDMAC_CHA_BUSY(ipu->devtype,
+ sec_dma), sec_dma))
+ irq = sec_dma;
+ if (ipu->thrd_chan_en[IPU_CHAN_ID(channel)] &&
+ idma_is_set(ipu, IDMAC_CHA_BUSY(ipu->devtype,
+ thrd_dma), thrd_dma))
+ irq = thrd_dma;
+ if (idma_is_set(ipu, IDMAC_CHA_BUSY(ipu->devtype,
+ in_dma), in_dma))
+ irq = in_dma;
+
+ if (irq == 0xffffffff) {
+ dev_dbg(ipu->dev, "warning: no channel busy, break\n");
+ break;
+ }
+
+ ipu_cm_write(ipu, IPUIRQ_2_MASK(irq),
+ IPUIRQ_2_STATREG(ipu->devtype, irq));
+
+ dev_dbg(ipu->dev, "warning: channel %d busy, need wait\n", irq);
+
+ while (((ipu_cm_read(ipu,
+ IPUIRQ_2_STATREG(ipu->devtype, irq))
+ & IPUIRQ_2_MASK(irq)) == 0) &&
+ (idma_is_set(ipu, IDMAC_CHA_BUSY(ipu->devtype,
+ irq), irq))) {
+ udelay(10);
+ timeout -= 10;
+ if (timeout <= 0) {
+ ipu_dump_registers(ipu);
+ dev_err(ipu->dev, "warning: disable ipu dma channel %d during its busy state\n", irq);
+ break;
+ }
+ }
+ dev_dbg(ipu->dev, "wait_time:%d\n", 50000 - timeout);
+
+ }
+ }
+
+ if ((channel == MEM_BG_SYNC) || (channel == MEM_FG_SYNC) ||
+ (channel == MEM_DC_SYNC)) {
+ reg = ipu_idmac_read(ipu, IDMAC_WM_EN(in_dma));
+ ipu_idmac_write(ipu, reg & ~idma_mask(in_dma), IDMAC_WM_EN(in_dma));
+ }
+
+ /* Disable IC task */
+ if (_ipu_is_ic_chan(in_dma) || _ipu_is_ic_chan(out_dma) ||
+ _ipu_is_irt_chan(in_dma) || _ipu_is_irt_chan(out_dma) ||
+ _ipu_is_vdi_out_chan(out_dma))
+ _ipu_ic_disable_task(ipu, channel);
+
+ /* Disable DMA channel(s) */
+ if (idma_is_valid(in_dma)) {
+ reg = ipu_idmac_read(ipu, IDMAC_CHA_EN(in_dma));
+ ipu_idmac_write(ipu, reg & ~idma_mask(in_dma), IDMAC_CHA_EN(in_dma));
+ ipu_cm_write(ipu, idma_mask(in_dma),
+ IPU_CHA_CUR_BUF(ipu->devtype, in_dma));
+ ipu_cm_write(ipu, tri_cur_buf_mask(in_dma),
+ IPU_CHA_TRIPLE_CUR_BUF(ipu->devtype, in_dma));
+ }
+ if (idma_is_valid(out_dma)) {
+ reg = ipu_idmac_read(ipu, IDMAC_CHA_EN(out_dma));
+ ipu_idmac_write(ipu, reg & ~idma_mask(out_dma), IDMAC_CHA_EN(out_dma));
+ ipu_cm_write(ipu, idma_mask(out_dma),
+ IPU_CHA_CUR_BUF(ipu->devtype, out_dma));
+ ipu_cm_write(ipu, tri_cur_buf_mask(out_dma),
+ IPU_CHA_TRIPLE_CUR_BUF(ipu->devtype, out_dma));
+ }
+ if (ipu->sec_chan_en[IPU_CHAN_ID(channel)] && idma_is_valid(sec_dma)) {
+ reg = ipu_idmac_read(ipu, IDMAC_CHA_EN(sec_dma));
+ ipu_idmac_write(ipu, reg & ~idma_mask(sec_dma), IDMAC_CHA_EN(sec_dma));
+ ipu_cm_write(ipu, idma_mask(sec_dma),
+ IPU_CHA_CUR_BUF(ipu->devtype, sec_dma));
+ }
+ if (ipu->thrd_chan_en[IPU_CHAN_ID(channel)] && idma_is_valid(thrd_dma)) {
+ reg = ipu_idmac_read(ipu, IDMAC_CHA_EN(thrd_dma));
+ ipu_idmac_write(ipu, reg & ~idma_mask(thrd_dma), IDMAC_CHA_EN(thrd_dma));
+ if (channel == MEM_BG_SYNC || channel == MEM_FG_SYNC) {
+ reg = ipu_idmac_read(ipu, IDMAC_SEP_ALPHA);
+ ipu_idmac_write(ipu, reg & ~idma_mask(in_dma), IDMAC_SEP_ALPHA);
+ } else {
+ reg = ipu_idmac_read(ipu, IDMAC_SEP_ALPHA);
+ ipu_idmac_write(ipu, reg & ~idma_mask(sec_dma), IDMAC_SEP_ALPHA);
+ }
+ ipu_cm_write(ipu, idma_mask(thrd_dma),
+ IPU_CHA_CUR_BUF(ipu->devtype, thrd_dma));
+ }
+
+ if (channel == MEM_FG_SYNC)
+ _ipu_disp_set_window_pos(ipu, channel, fg_pos_x, fg_pos_y);
+
+ spin_lock_irqsave(&ipu->rdy_reg_spin_lock, lock_flags);
+ /* Set channel buffers NOT to be ready */
+ if (idma_is_valid(in_dma)) {
+ _ipu_clear_buffer_ready(ipu, channel, IPU_VIDEO_IN_BUFFER, 0);
+ _ipu_clear_buffer_ready(ipu, channel, IPU_VIDEO_IN_BUFFER, 1);
+ _ipu_clear_buffer_ready(ipu, channel, IPU_VIDEO_IN_BUFFER, 2);
+ }
+ if (idma_is_valid(out_dma)) {
+ _ipu_clear_buffer_ready(ipu, channel, IPU_OUTPUT_BUFFER, 0);
+ _ipu_clear_buffer_ready(ipu, channel, IPU_OUTPUT_BUFFER, 1);
+ }
+ if (ipu->sec_chan_en[IPU_CHAN_ID(channel)] && idma_is_valid(sec_dma)) {
+ _ipu_clear_buffer_ready(ipu, channel, IPU_GRAPH_IN_BUFFER, 0);
+ _ipu_clear_buffer_ready(ipu, channel, IPU_GRAPH_IN_BUFFER, 1);
+ }
+ if (ipu->thrd_chan_en[IPU_CHAN_ID(channel)] && idma_is_valid(thrd_dma)) {
+ _ipu_clear_buffer_ready(ipu, channel, IPU_ALPHA_IN_BUFFER, 0);
+ _ipu_clear_buffer_ready(ipu, channel, IPU_ALPHA_IN_BUFFER, 1);
+ }
+ spin_unlock_irqrestore(&ipu->rdy_reg_spin_lock, lock_flags);
+
+ ipu->channel_enable_mask &= ~(1L << IPU_CHAN_ID(channel));
+
+ if (ipu->prg_clk)
+ clk_disable_unprepare(ipu->prg_clk);
+
+ mutex_unlock(&ipu->mutex_lock);
+
+ return 0;
+}
+EXPORT_SYMBOL(ipu_disable_channel);
+
+/*!
+ * This function enables CSI.
+ *
+ * @param ipu ipu handler
+ * @param csi csi num 0 or 1
+ *
+ * @return This function returns 0 on success or negative error code on
+ * fail.
+ */
+int32_t ipu_enable_csi(struct ipu_soc *ipu, uint32_t csi)
+{
+ uint32_t reg;
+
+ if (csi > 1) {
+ dev_err(ipu->dev, "Wrong csi num_%d\n", csi);
+ return -EINVAL;
+ }
+
+ _ipu_get(ipu);
+ mutex_lock(&ipu->mutex_lock);
+ ipu->csi_use_count[csi]++;
+
+ if (ipu->csi_use_count[csi] == 1) {
+ reg = ipu_cm_read(ipu, IPU_CONF);
+ if (csi == 0)
+ ipu_cm_write(ipu, reg | IPU_CONF_CSI0_EN, IPU_CONF);
+ else
+ ipu_cm_write(ipu, reg | IPU_CONF_CSI1_EN, IPU_CONF);
+ }
+ mutex_unlock(&ipu->mutex_lock);
+ _ipu_put(ipu);
+ return 0;
+}
+EXPORT_SYMBOL(ipu_enable_csi);
+
+/*!
+ * This function disables CSI.
+ *
+ * @param ipu ipu handler
+ * @param csi csi num 0 or 1
+ *
+ * @return This function returns 0 on success or negative error code on
+ * fail.
+ */
+int32_t ipu_disable_csi(struct ipu_soc *ipu, uint32_t csi)
+{
+ uint32_t reg;
+
+ if (csi > 1) {
+ dev_err(ipu->dev, "Wrong csi num_%d\n", csi);
+ return -EINVAL;
+ }
+ _ipu_get(ipu);
+ mutex_lock(&ipu->mutex_lock);
+ ipu->csi_use_count[csi]--;
+ if (ipu->csi_use_count[csi] == 0) {
+ _ipu_csi_wait4eof(ipu, ipu->csi_channel[csi]);
+ reg = ipu_cm_read(ipu, IPU_CONF);
+ if (csi == 0)
+ ipu_cm_write(ipu, reg & ~IPU_CONF_CSI0_EN, IPU_CONF);
+ else
+ ipu_cm_write(ipu, reg & ~IPU_CONF_CSI1_EN, IPU_CONF);
+ }
+ mutex_unlock(&ipu->mutex_lock);
+ _ipu_put(ipu);
+ return 0;
+}
+EXPORT_SYMBOL(ipu_disable_csi);
+
+static irqreturn_t ipu_sync_irq_handler(int irq, void *desc)
+{
+ struct ipu_soc *ipu = desc;
+ int i;
+ uint32_t line, bit, int_stat, int_ctrl;
+ irqreturn_t result = IRQ_NONE;
+ const int int_reg[] = { 1, 2, 3, 4, 11, 12, 13, 14, 15, 0 };
+
+ spin_lock(&ipu->int_reg_spin_lock);
+
+ for (i = 0; int_reg[i] != 0; i++) {
+ int_stat = ipu_cm_read(ipu,
+ IPU_INT_STAT(ipu->devtype, int_reg[i]));
+ int_ctrl = ipu_cm_read(ipu, IPU_INT_CTRL(int_reg[i]));
+ int_stat &= int_ctrl;
+ ipu_cm_write(ipu, int_stat,
+ IPU_INT_STAT(ipu->devtype, int_reg[i]));
+ while ((line = ffs(int_stat)) != 0) {
+ bit = --line;
+ int_stat &= ~(1UL << line);
+ line += (int_reg[i] - 1) * 32;
+ result |=
+ ipu->irq_list[line].handler(line,
+ ipu->irq_list[line].
+ dev_id);
+ if (ipu->irq_list[line].flags & IPU_IRQF_ONESHOT) {
+ int_ctrl &= ~(1UL << bit);
+ ipu_cm_write(ipu, int_ctrl,
+ IPU_INT_CTRL(int_reg[i]));
+ }
+ }
+ }
+
+ spin_unlock(&ipu->int_reg_spin_lock);
+
+ return result;
+}
+
+static irqreturn_t ipu_err_irq_handler(int irq, void *desc)
+{
+ struct ipu_soc *ipu = desc;
+ int i;
+ uint32_t int_stat;
+ const int err_reg[] = { 5, 6, 9, 10, 0 };
+
+ spin_lock(&ipu->int_reg_spin_lock);
+
+ for (i = 0; err_reg[i] != 0; i++) {
+ int_stat = ipu_cm_read(ipu,
+ IPU_INT_STAT(ipu->devtype, err_reg[i]));
+ int_stat &= ipu_cm_read(ipu, IPU_INT_CTRL(err_reg[i]));
+ if (int_stat) {
+ ipu_cm_write(ipu, int_stat,
+ IPU_INT_STAT(ipu->devtype, err_reg[i]));
+ dev_warn(ipu->dev,
+ "IPU Warning - IPU_INT_STAT_%d = 0x%08X\n",
+ err_reg[i], int_stat);
+ /* Disable interrupts so we only get error once */
+ int_stat = ipu_cm_read(ipu, IPU_INT_CTRL(err_reg[i])) &
+ ~int_stat;
+ ipu_cm_write(ipu, int_stat, IPU_INT_CTRL(err_reg[i]));
+ }
+ }
+
+ spin_unlock(&ipu->int_reg_spin_lock);
+
+ return IRQ_HANDLED;
+}
+
+/*!
+ * This function enables the interrupt for the specified interrupt line.
+ * The interrupt lines are defined in \b ipu_irq_line enum.
+ *
+ * @param ipu ipu handler
+ * @param irq Interrupt line to enable interrupt for.
+ *
+ * @return This function returns 0 on success or negative error code on
+ * fail.
+ */
+int ipu_enable_irq(struct ipu_soc *ipu, uint32_t irq)
+{
+ uint32_t reg;
+ unsigned long lock_flags;
+ int ret = 0;
+
+ _ipu_get(ipu);
+
+ spin_lock_irqsave(&ipu->int_reg_spin_lock, lock_flags);
+
+ /*
+ * Check sync interrupt handler only, since we do nothing for
+ * error interrupts but than print out register values in the
+ * error interrupt source handler.
+ */
+ if (_ipu_is_sync_irq(irq) && (ipu->irq_list[irq].handler == NULL)) {
+ dev_err(ipu->dev, "handler hasn't been registered on sync "
+ "irq %d\n", irq);
+ ret = -EACCES;
+ goto out;
+ }
+
+ reg = ipu_cm_read(ipu, IPUIRQ_2_CTRLREG(irq));
+ reg |= IPUIRQ_2_MASK(irq);
+ ipu_cm_write(ipu, reg, IPUIRQ_2_CTRLREG(irq));
+out:
+ spin_unlock_irqrestore(&ipu->int_reg_spin_lock, lock_flags);
+
+ _ipu_put(ipu);
+
+ return ret;
+}
+EXPORT_SYMBOL(ipu_enable_irq);
+
+/*!
+ * This function disables the interrupt for the specified interrupt line.
+ * The interrupt lines are defined in \b ipu_irq_line enum.
+ *
+ * @param ipu ipu handler
+ * @param irq Interrupt line to disable interrupt for.
+ *
+ */
+void ipu_disable_irq(struct ipu_soc *ipu, uint32_t irq)
+{
+ uint32_t reg;
+ unsigned long lock_flags;
+
+ _ipu_get(ipu);
+
+ spin_lock_irqsave(&ipu->int_reg_spin_lock, lock_flags);
+
+ reg = ipu_cm_read(ipu, IPUIRQ_2_CTRLREG(irq));
+ reg &= ~IPUIRQ_2_MASK(irq);
+ ipu_cm_write(ipu, reg, IPUIRQ_2_CTRLREG(irq));
+
+ spin_unlock_irqrestore(&ipu->int_reg_spin_lock, lock_flags);
+
+ _ipu_put(ipu);
+}
+EXPORT_SYMBOL(ipu_disable_irq);
+
+/*!
+ * This function clears the interrupt for the specified interrupt line.
+ * The interrupt lines are defined in \b ipu_irq_line enum.
+ *
+ * @param ipu ipu handler
+ * @param irq Interrupt line to clear interrupt for.
+ *
+ */
+void ipu_clear_irq(struct ipu_soc *ipu, uint32_t irq)
+{
+ unsigned long lock_flags;
+
+ _ipu_get(ipu);
+
+ spin_lock_irqsave(&ipu->int_reg_spin_lock, lock_flags);
+
+ ipu_cm_write(ipu, IPUIRQ_2_MASK(irq),
+ IPUIRQ_2_STATREG(ipu->devtype, irq));
+
+ spin_unlock_irqrestore(&ipu->int_reg_spin_lock, lock_flags);
+
+ _ipu_put(ipu);
+}
+EXPORT_SYMBOL(ipu_clear_irq);
+
+/*!
+ * This function returns the current interrupt status for the specified
+ * interrupt line. The interrupt lines are defined in \b ipu_irq_line enum.
+ *
+ * @param ipu ipu handler
+ * @param irq Interrupt line to get status for.
+ *
+ * @return Returns true if the interrupt is pending/asserted or false if
+ * the interrupt is not pending.
+ */
+bool ipu_get_irq_status(struct ipu_soc *ipu, uint32_t irq)
+{
+ uint32_t reg;
+ unsigned long lock_flags;
+
+ _ipu_get(ipu);
+
+ spin_lock_irqsave(&ipu->int_reg_spin_lock, lock_flags);
+ reg = ipu_cm_read(ipu, IPUIRQ_2_STATREG(ipu->devtype, irq));
+ spin_unlock_irqrestore(&ipu->int_reg_spin_lock, lock_flags);
+
+ _ipu_put(ipu);
+
+ if (reg & IPUIRQ_2_MASK(irq))
+ return true;
+ else
+ return false;
+}
+EXPORT_SYMBOL(ipu_get_irq_status);
+
+/*!
+ * This function registers an interrupt handler function for the specified
+ * interrupt line. The interrupt lines are defined in \b ipu_irq_line enum.
+ *
+ * @param ipu ipu handler
+ * @param irq Interrupt line to get status for.
+ *
+ * @param handler Input parameter for address of the handler
+ * function.
+ *
+ * @param irq_flags Flags for interrupt mode. Currently not used.
+ *
+ * @param devname Input parameter for string name of driver
+ * registering the handler.
+ *
+ * @param dev_id Input parameter for pointer of data to be
+ * passed to the handler.
+ *
+ * @return This function returns 0 on success or negative error code on
+ * fail.
+ */
+int ipu_request_irq(struct ipu_soc *ipu, uint32_t irq,
+ irqreturn_t(*handler) (int, void *),
+ uint32_t irq_flags, const char *devname, void *dev_id)
+{
+ uint32_t reg;
+ unsigned long lock_flags;
+ int ret = 0;
+
+ BUG_ON(irq >= IPU_IRQ_COUNT);
+
+ _ipu_get(ipu);
+
+ spin_lock_irqsave(&ipu->int_reg_spin_lock, lock_flags);
+
+ if (ipu->irq_list[irq].handler != NULL) {
+ dev_err(ipu->dev,
+ "handler already installed on irq %d\n", irq);
+ ret = -EINVAL;
+ goto out;
+ }
+
+ /*
+ * Check sync interrupt handler only, since we do nothing for
+ * error interrupts but than print out register values in the
+ * error interrupt source handler.
+ */
+ if (_ipu_is_sync_irq(irq) && (handler == NULL)) {
+ dev_err(ipu->dev, "handler is NULL for sync irq %d\n", irq);
+ ret = -EINVAL;
+ goto out;
+ }
+
+ ipu->irq_list[irq].handler = handler;
+ ipu->irq_list[irq].flags = irq_flags;
+ ipu->irq_list[irq].dev_id = dev_id;
+ ipu->irq_list[irq].name = devname;
+
+ /* clear irq stat for previous use */
+ ipu_cm_write(ipu, IPUIRQ_2_MASK(irq),
+ IPUIRQ_2_STATREG(ipu->devtype, irq));
+ /* enable the interrupt */
+ reg = ipu_cm_read(ipu, IPUIRQ_2_CTRLREG(irq));
+ reg |= IPUIRQ_2_MASK(irq);
+ ipu_cm_write(ipu, reg, IPUIRQ_2_CTRLREG(irq));
+out:
+ spin_unlock_irqrestore(&ipu->int_reg_spin_lock, lock_flags);
+
+ _ipu_put(ipu);
+
+ return ret;
+}
+EXPORT_SYMBOL(ipu_request_irq);
+
+/*!
+ * This function unregisters an interrupt handler for the specified interrupt
+ * line. The interrupt lines are defined in \b ipu_irq_line enum.
+ *
+ * @param ipu ipu handler
+ * @param irq Interrupt line to get status for.
+ *
+ * @param dev_id Input parameter for pointer of data to be passed
+ * to the handler. This must match value passed to
+ * ipu_request_irq().
+ *
+ */
+void ipu_free_irq(struct ipu_soc *ipu, uint32_t irq, void *dev_id)
+{
+ uint32_t reg;
+ unsigned long lock_flags;
+
+ _ipu_get(ipu);
+
+ spin_lock_irqsave(&ipu->int_reg_spin_lock, lock_flags);
+
+ /* disable the interrupt */
+ reg = ipu_cm_read(ipu, IPUIRQ_2_CTRLREG(irq));
+ reg &= ~IPUIRQ_2_MASK(irq);
+ ipu_cm_write(ipu, reg, IPUIRQ_2_CTRLREG(irq));
+ if (ipu->irq_list[irq].dev_id == dev_id)
+ memset(&ipu->irq_list[irq], 0, sizeof(ipu->irq_list[irq]));
+
+ spin_unlock_irqrestore(&ipu->int_reg_spin_lock, lock_flags);
+
+ _ipu_put(ipu);
+}
+EXPORT_SYMBOL(ipu_free_irq);
+
+uint32_t ipu_get_cur_buffer_idx(struct ipu_soc *ipu, ipu_channel_t channel, ipu_buffer_t type)
+{
+ uint32_t reg, dma_chan;
+
+ dma_chan = channel_2_dma(channel, type);
+ if (!idma_is_valid(dma_chan))
+ return -EINVAL;
+
+ reg = ipu_cm_read(ipu, IPU_CHA_TRB_MODE_SEL(ipu->devtype, dma_chan));
+ if ((reg & idma_mask(dma_chan)) && _ipu_is_trb_chan(ipu, dma_chan)) {
+ reg = ipu_cm_read(ipu,
+ IPU_CHA_TRIPLE_CUR_BUF(ipu->devtype, dma_chan));
+ return (reg & tri_cur_buf_mask(dma_chan)) >>
+ tri_cur_buf_shift(dma_chan);
+ } else {
+ reg = ipu_cm_read(ipu, IPU_CHA_CUR_BUF(ipu->devtype, dma_chan));
+ if (reg & idma_mask(dma_chan))
+ return 1;
+ else
+ return 0;
+ }
+}
+EXPORT_SYMBOL(ipu_get_cur_buffer_idx);
+
+uint32_t _ipu_channel_status(struct ipu_soc *ipu, ipu_channel_t channel)
+{
+ uint32_t stat = 0;
+ uint32_t task_stat_reg = ipu_cm_read(ipu,
+ IPU_PROC_TASK_STAT(ipu->devtype));
+
+ switch (channel) {
+ case MEM_PRP_VF_MEM:
+ stat = (task_stat_reg & TSTAT_VF_MASK) >> TSTAT_VF_OFFSET;
+ break;
+ case MEM_VDI_PRP_VF_MEM:
+ stat = (task_stat_reg & TSTAT_VF_MASK) >> TSTAT_VF_OFFSET;
+ break;
+ case MEM_ROT_VF_MEM:
+ stat =
+ (task_stat_reg & TSTAT_VF_ROT_MASK) >> TSTAT_VF_ROT_OFFSET;
+ break;
+ case MEM_PRP_ENC_MEM:
+ stat = (task_stat_reg & TSTAT_ENC_MASK) >> TSTAT_ENC_OFFSET;
+ break;
+ case MEM_ROT_ENC_MEM:
+ stat =
+ (task_stat_reg & TSTAT_ENC_ROT_MASK) >>
+ TSTAT_ENC_ROT_OFFSET;
+ break;
+ case MEM_PP_MEM:
+ stat = (task_stat_reg & TSTAT_PP_MASK) >> TSTAT_PP_OFFSET;
+ break;
+ case MEM_ROT_PP_MEM:
+ stat =
+ (task_stat_reg & TSTAT_PP_ROT_MASK) >> TSTAT_PP_ROT_OFFSET;
+ break;
+
+ default:
+ stat = TASK_STAT_IDLE;
+ break;
+ }
+ return stat;
+}
+
+/*!
+ * This function check for a logical channel status
+ *
+ * @param ipu ipu handler
+ * @param channel Input parameter for the logical channel ID.
+ *
+ * @return This function returns 0 on idle and 1 on busy.
+ *
+ */
+uint32_t ipu_channel_status(struct ipu_soc *ipu, ipu_channel_t channel)
+{
+ uint32_t dma_status;
+
+ _ipu_get(ipu);
+ mutex_lock(&ipu->mutex_lock);
+ dma_status = ipu_is_channel_busy(ipu, channel);
+ mutex_unlock(&ipu->mutex_lock);
+ _ipu_put(ipu);
+
+ dev_dbg(ipu->dev, "%s, dma_status:%d.\n", __func__, dma_status);
+
+ return dma_status;
+}
+EXPORT_SYMBOL(ipu_channel_status);
+
+int32_t ipu_swap_channel(struct ipu_soc *ipu, ipu_channel_t from_ch, ipu_channel_t to_ch)
+{
+ uint32_t reg;
+ unsigned long lock_flags;
+ int from_dma = channel_2_dma(from_ch, IPU_INPUT_BUFFER);
+ int to_dma = channel_2_dma(to_ch, IPU_INPUT_BUFFER);
+
+ mutex_lock(&ipu->mutex_lock);
+
+ /* enable target channel */
+ reg = ipu_idmac_read(ipu, IDMAC_CHA_EN(to_dma));
+ ipu_idmac_write(ipu, reg | idma_mask(to_dma), IDMAC_CHA_EN(to_dma));
+
+ ipu->channel_enable_mask |= 1L << IPU_CHAN_ID(to_ch);
+
+ /* switch dp dc */
+ _ipu_dp_dc_disable(ipu, from_ch, true);
+
+ /* disable source channel */
+ reg = ipu_idmac_read(ipu, IDMAC_CHA_EN(from_dma));
+ ipu_idmac_write(ipu, reg & ~idma_mask(from_dma), IDMAC_CHA_EN(from_dma));
+ ipu_cm_write(ipu, idma_mask(from_dma),
+ IPU_CHA_CUR_BUF(ipu->devtype, from_dma));
+ ipu_cm_write(ipu, tri_cur_buf_mask(from_dma),
+ IPU_CHA_TRIPLE_CUR_BUF(ipu->devtype, from_dma));
+
+ ipu->channel_enable_mask &= ~(1L << IPU_CHAN_ID(from_ch));
+
+ spin_lock_irqsave(&ipu->rdy_reg_spin_lock, lock_flags);
+ _ipu_clear_buffer_ready(ipu, from_ch, IPU_VIDEO_IN_BUFFER, 0);
+ _ipu_clear_buffer_ready(ipu, from_ch, IPU_VIDEO_IN_BUFFER, 1);
+ _ipu_clear_buffer_ready(ipu, from_ch, IPU_VIDEO_IN_BUFFER, 2);
+ spin_unlock_irqrestore(&ipu->rdy_reg_spin_lock, lock_flags);
+
+ mutex_unlock(&ipu->mutex_lock);
+
+ return 0;
+}
+EXPORT_SYMBOL(ipu_swap_channel);
+
+uint32_t bytes_per_pixel(uint32_t fmt)
+{
+ switch (fmt) {
+ case IPU_PIX_FMT_GENERIC: /*generic data */
+ case IPU_PIX_FMT_RGB332:
+ case IPU_PIX_FMT_YUV420P:
+ case IPU_PIX_FMT_YVU420P:
+ case IPU_PIX_FMT_YUV422P:
+ case IPU_PIX_FMT_YUV444P:
+ case IPU_PIX_FMT_NV12:
+ case PRE_PIX_FMT_NV21:
+ case IPU_PIX_FMT_NV16:
+ case PRE_PIX_FMT_NV61:
+ return 1;
+ break;
+ case IPU_PIX_FMT_GENERIC_16: /* generic data */
+ case IPU_PIX_FMT_RGB565:
+ case IPU_PIX_FMT_BGRA4444:
+ case IPU_PIX_FMT_BGRA5551:
+ case IPU_PIX_FMT_YUYV:
+ case IPU_PIX_FMT_UYVY:
+ case IPU_PIX_FMT_GPU16_SB_ST:
+ case IPU_PIX_FMT_GPU16_SB_SRT:
+ case IPU_PIX_FMT_GPU16_ST:
+ case IPU_PIX_FMT_GPU16_SRT:
+ return 2;
+ break;
+ case IPU_PIX_FMT_BGR24:
+ case IPU_PIX_FMT_RGB24:
+ case IPU_PIX_FMT_YUV444:
+ return 3;
+ break;
+ case IPU_PIX_FMT_GENERIC_32: /*generic data */
+ case IPU_PIX_FMT_BGR32:
+ case IPU_PIX_FMT_BGRA32:
+ case IPU_PIX_FMT_RGB32:
+ case IPU_PIX_FMT_RGBA32:
+ case IPU_PIX_FMT_ABGR32:
+ case IPU_PIX_FMT_GPU32_SB_ST:
+ case IPU_PIX_FMT_GPU32_SB_SRT:
+ case IPU_PIX_FMT_GPU32_ST:
+ case IPU_PIX_FMT_GPU32_SRT:
+ case IPU_PIX_FMT_AYUV:
+ return 4;
+ break;
+ default:
+ return 1;
+ break;
+ }
+ return 0;
+}
+EXPORT_SYMBOL(bytes_per_pixel);
+
+ipu_color_space_t format_to_colorspace(uint32_t fmt)
+{
+ switch (fmt) {
+ case IPU_PIX_FMT_RGB666:
+ case IPU_PIX_FMT_RGB565:
+ case IPU_PIX_FMT_BGRA4444:
+ case IPU_PIX_FMT_BGRA5551:
+ case IPU_PIX_FMT_BGR24:
+ case IPU_PIX_FMT_RGB24:
+ case IPU_PIX_FMT_GBR24:
+ case IPU_PIX_FMT_BGR32:
+ case IPU_PIX_FMT_BGRA32:
+ case IPU_PIX_FMT_RGB32:
+ case IPU_PIX_FMT_RGBA32:
+ case IPU_PIX_FMT_ABGR32:
+ case IPU_PIX_FMT_LVDS666:
+ case IPU_PIX_FMT_LVDS888:
+ case IPU_PIX_FMT_GPU32_SB_ST:
+ case IPU_PIX_FMT_GPU32_SB_SRT:
+ case IPU_PIX_FMT_GPU32_ST:
+ case IPU_PIX_FMT_GPU32_SRT:
+ case IPU_PIX_FMT_GPU16_SB_ST:
+ case IPU_PIX_FMT_GPU16_SB_SRT:
+ case IPU_PIX_FMT_GPU16_ST:
+ case IPU_PIX_FMT_GPU16_SRT:
+ return RGB;
+ break;
+
+ default:
+ return YCbCr;
+ break;
+ }
+ return RGB;
+}
+EXPORT_SYMBOL(format_to_colorspace);
+
+bool ipu_pixel_format_has_alpha(uint32_t fmt)
+{
+ switch (fmt) {
+ case IPU_PIX_FMT_RGBA32:
+ case IPU_PIX_FMT_BGRA32:
+ case IPU_PIX_FMT_ABGR32:
+ return true;
+ break;
+ default:
+ return false;
+ break;
+ }
+ return false;
+}
+
+bool ipu_ch_param_bad_alpha_pos(uint32_t pixel_fmt)
+{
+ return _ipu_ch_param_bad_alpha_pos(pixel_fmt);
+}
+EXPORT_SYMBOL(ipu_ch_param_bad_alpha_pos);
+
+bool ipu_pixel_format_is_gpu_tile(uint32_t fmt)
+{
+ switch (fmt) {
+ case IPU_PIX_FMT_GPU32_SB_ST:
+ case IPU_PIX_FMT_GPU32_SB_SRT:
+ case IPU_PIX_FMT_GPU32_ST:
+ case IPU_PIX_FMT_GPU32_SRT:
+ case IPU_PIX_FMT_GPU16_SB_ST:
+ case IPU_PIX_FMT_GPU16_SB_SRT:
+ case IPU_PIX_FMT_GPU16_ST:
+ case IPU_PIX_FMT_GPU16_SRT:
+ return true;
+ default:
+ return false;
+ }
+}
+EXPORT_SYMBOL(ipu_pixel_format_is_gpu_tile);
+
+bool ipu_pixel_format_is_split_gpu_tile(uint32_t fmt)
+{
+ switch (fmt) {
+ case IPU_PIX_FMT_GPU32_SB_ST:
+ case IPU_PIX_FMT_GPU32_SB_SRT:
+ case IPU_PIX_FMT_GPU16_SB_ST:
+ case IPU_PIX_FMT_GPU16_SB_SRT:
+ return true;
+ default:
+ return false;
+ }
+}
+EXPORT_SYMBOL(ipu_pixel_format_is_split_gpu_tile);
+
+bool ipu_pixel_format_is_pre_yuv(uint32_t fmt)
+{
+ switch (fmt) {
+ case PRE_PIX_FMT_NV21:
+ case PRE_PIX_FMT_NV61:
+ return true;
+ default:
+ return false;
+ }
+}
+EXPORT_SYMBOL(ipu_pixel_format_is_pre_yuv);
+
+bool ipu_pixel_format_is_multiplanar_yuv(uint32_t fmt)
+{
+ switch (fmt) {
+ case IPU_PIX_FMT_YVU410P:
+ case IPU_PIX_FMT_YUV420P:
+ case IPU_PIX_FMT_YUV420P2:
+ case IPU_PIX_FMT_YVU420P:
+ case IPU_PIX_FMT_YUV422P:
+ case IPU_PIX_FMT_YVU422P:
+ case IPU_PIX_FMT_YUV444P:
+ case IPU_PIX_FMT_NV12:
+ case PRE_PIX_FMT_NV21:
+ case IPU_PIX_FMT_NV16:
+ case PRE_PIX_FMT_NV61:
+ return true;
+ default:
+ return false;
+ }
+}
+EXPORT_SYMBOL(ipu_pixel_format_is_multiplanar_yuv);
+
+int ipu_ch_param_get_axi_id(struct ipu_soc *ipu, ipu_channel_t channel, ipu_buffer_t type)
+{
+ uint32_t dma_chan = channel_2_dma(channel, type);
+ int axi_id;
+
+ if (!idma_is_valid(dma_chan))
+ return -EINVAL;
+
+ _ipu_get(ipu);
+ mutex_lock(&ipu->mutex_lock);
+ axi_id = _ipu_ch_param_get_axi_id(ipu, dma_chan);
+ mutex_unlock(&ipu->mutex_lock);
+ _ipu_put(ipu);
+
+ return axi_id;
+}
+EXPORT_SYMBOL(ipu_ch_param_get_axi_id);
+
+#ifdef CONFIG_PM
+int ipu_runtime_suspend(struct device *dev)
+{
+ release_bus_freq(BUS_FREQ_HIGH);
+ dev_dbg(dev, "ipu busfreq high release.\n");
+
+ return 0;
+}
+
+int ipu_runtime_resume(struct device *dev)
+{
+ request_bus_freq(BUS_FREQ_HIGH);
+ dev_dbg(dev, "ipu busfreq high requst.\n");
+
+ return 0;
+}
+
+static const struct dev_pm_ops ipu_pm_ops = {
+ SET_RUNTIME_PM_OPS(ipu_runtime_suspend, ipu_runtime_resume, NULL)
+};
+#endif
+
+/*!
+ * This structure contains pointers to the power management callback functions.
+ */
+static struct platform_driver mxcipu_driver = {
+ .driver = {
+ .name = "imx-ipuv3",
+ .of_match_table = imx_ipuv3_dt_ids,
+ #ifdef CONFIG_PM
+ .pm = &ipu_pm_ops,
+ #endif
+ },
+ .probe = ipu_probe,
+ .remove = ipu_remove,
+};
+
+int32_t __init ipu_gen_init(void)
+{
+ int32_t ret;
+
+ ret = platform_driver_register(&mxcipu_driver);
+ return 0;
+}
+
+subsys_initcall(ipu_gen_init);
+
+static void __exit ipu_gen_uninit(void)
+{
+ platform_driver_unregister(&mxcipu_driver);
+}
+
+module_exit(ipu_gen_uninit);
diff --git a/drivers/mxc/ipu3/ipu_device.c b/drivers/mxc/ipu3/ipu_device.c
new file mode 100644
index 000000000000..20d3140b7024
--- /dev/null
+++ b/drivers/mxc/ipu3/ipu_device.c
@@ -0,0 +1,3755 @@
+/*
+ * Copyright 2005-2015 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2019 NXP
+ */
+
+/*
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/*!
+ * @file ipu_device.c
+ *
+ * @brief This file contains the IPUv3 driver device interface and fops functions.
+ *
+ * @ingroup IPU
+ */
+#include <linux/clk.h>
+#include <linux/cpumask.h>
+#include <linux/delay.h>
+#include <linux/dma-mapping.h>
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/ipu-v3.h>
+#include <linux/kernel.h>
+#include <linux/kthread.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/poll.h>
+#include <linux/sched.h>
+#include <linux/sched/types.h>
+#include <linux/sched/rt.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/time.h>
+#include <linux/types.h>
+#include <linux/vmalloc.h>
+#include <linux/wait.h>
+
+#include <asm/cacheflush.h>
+#include <asm/outercache.h>
+
+#include "ipu_param_mem.h"
+#include "ipu_regs.h"
+#include "vdoa.h"
+
+#define CHECK_RETCODE(cont, str, err, label, ret) \
+do { \
+ if (cont) { \
+ dev_err(t->dev, "ERR:[0x%p]-no:0x%x "#str" ret:%d," \
+ "line:%d\n", t, t->task_no, ret, __LINE__);\
+ if (ret != -EACCES) { \
+ t->state = err; \
+ goto label; \
+ } \
+ } \
+} while (0)
+
+#define CHECK_RETCODE_CONT(cont, str, err, ret) \
+do { \
+ if (cont) { \
+ dev_err(t->dev, "ERR:[0x%p]-no:0x%x"#str" ret:%d," \
+ "line:%d\n", t, t->task_no, ret, __LINE__);\
+ if (ret != -EACCES) { \
+ if (t->state == STATE_OK) \
+ t->state = err; \
+ } \
+ } \
+} while (0)
+
+#undef DBG_IPU_PERF
+#ifdef DBG_IPU_PERF
+#define CHECK_PERF(ts) \
+do { \
+ getnstimeofday(ts); \
+} while (0)
+
+#define DECLARE_PERF_VAR \
+ struct timespec ts_queue; \
+ struct timespec ts_dotask; \
+ struct timespec ts_waitirq; \
+ struct timespec ts_sche; \
+ struct timespec ts_rel; \
+ struct timespec ts_frame
+
+#define PRINT_TASK_STATISTICS \
+do { \
+ ts_queue = timespec_sub(tsk->ts_dotask, tsk->ts_queue); \
+ ts_dotask = timespec_sub(tsk->ts_waitirq, tsk->ts_dotask); \
+ ts_waitirq = timespec_sub(tsk->ts_inirq, tsk->ts_waitirq); \
+ ts_sche = timespec_sub(tsk->ts_wakeup, tsk->ts_inirq); \
+ ts_rel = timespec_sub(tsk->ts_rel, tsk->ts_wakeup); \
+ ts_frame = timespec_sub(tsk->ts_rel, tsk->ts_queue); \
+ dev_dbg(tsk->dev, "[0x%p] no-0x%x, ts_q:%ldus, ts_do:%ldus," \
+ "ts_waitirq:%ldus,ts_sche:%ldus, ts_rel:%ldus," \
+ "ts_frame: %ldus\n", tsk, tsk->task_no, \
+ ts_queue.tv_nsec / NSEC_PER_USEC + ts_queue.tv_sec * USEC_PER_SEC,\
+ ts_dotask.tv_nsec / NSEC_PER_USEC + ts_dotask.tv_sec * USEC_PER_SEC,\
+ ts_waitirq.tv_nsec / NSEC_PER_USEC + ts_waitirq.tv_sec * USEC_PER_SEC,\
+ ts_sche.tv_nsec / NSEC_PER_USEC + ts_sche.tv_sec * USEC_PER_SEC,\
+ ts_rel.tv_nsec / NSEC_PER_USEC + ts_rel.tv_sec * USEC_PER_SEC,\
+ ts_frame.tv_nsec / NSEC_PER_USEC + ts_frame.tv_sec * USEC_PER_SEC); \
+ if ((ts_frame.tv_nsec/NSEC_PER_USEC + ts_frame.tv_sec*USEC_PER_SEC) > \
+ 80000) \
+ dev_dbg(tsk->dev, "ts_frame larger than 80ms [0x%p] no-0x%x.\n"\
+ , tsk, tsk->task_no); \
+} while (0)
+#else
+#define CHECK_PERF(ts)
+#define DECLARE_PERF_VAR
+#define PRINT_TASK_STATISTICS
+#endif
+
+#define IPU_PP_CH_VF (IPU_TASK_ID_VF - 1)
+#define IPU_PP_CH_PP (IPU_TASK_ID_PP - 1)
+#define MAX_PP_CH (IPU_TASK_ID_MAX - 1)
+#define VDOA_DEF_TIMEOUT_MS (HZ/2)
+
+/* Strucutures and variables for exporting MXC IPU as device*/
+typedef enum {
+ STATE_OK = 0,
+ STATE_QUEUE,
+ STATE_IN_PROGRESS,
+ STATE_ERR,
+ STATE_TIMEOUT,
+ STATE_RES_TIMEOUT,
+ STATE_NO_IPU,
+ STATE_NO_IRQ,
+ STATE_IPU_BUSY,
+ STATE_IRQ_FAIL,
+ STATE_IRQ_TIMEOUT,
+ STATE_ENABLE_CHAN_FAIL,
+ STATE_DISABLE_CHAN_FAIL,
+ STATE_SEL_BUF_FAIL,
+ STATE_INIT_CHAN_FAIL,
+ STATE_LINK_CHAN_FAIL,
+ STATE_UNLINK_CHAN_FAIL,
+ STATE_INIT_CHAN_BUF_FAIL,
+ STATE_INIT_CHAN_BAND_FAIL,
+ STATE_SYS_NO_MEM,
+ STATE_VDOA_IRQ_TIMEOUT,
+ STATE_VDOA_IRQ_FAIL,
+ STATE_VDOA_TASK_FAIL,
+} ipu_state_t;
+
+enum {
+ INPUT_CHAN_VDI_P = 1,
+ INPUT_CHAN,
+ INPUT_CHAN_VDI_N,
+};
+
+struct ipu_state_msg {
+ int state;
+ char *msg;
+} state_msg[] = {
+ {STATE_OK, "ok"},
+ {STATE_QUEUE, "split queue"},
+ {STATE_IN_PROGRESS, "split in progress"},
+ {STATE_ERR, "error"},
+ {STATE_TIMEOUT, "split task timeout"},
+ {STATE_RES_TIMEOUT, "wait resource timeout"},
+ {STATE_NO_IPU, "no ipu found"},
+ {STATE_NO_IRQ, "no irq found for task"},
+ {STATE_IPU_BUSY, "ipu busy"},
+ {STATE_IRQ_FAIL, "request irq failed"},
+ {STATE_IRQ_TIMEOUT, "wait for irq timeout"},
+ {STATE_ENABLE_CHAN_FAIL, "ipu enable channel fail"},
+ {STATE_DISABLE_CHAN_FAIL, "ipu disable channel fail"},
+ {STATE_SEL_BUF_FAIL, "ipu select buf fail"},
+ {STATE_INIT_CHAN_FAIL, "ipu init channel fail"},
+ {STATE_LINK_CHAN_FAIL, "ipu link channel fail"},
+ {STATE_UNLINK_CHAN_FAIL, "ipu unlink channel fail"},
+ {STATE_INIT_CHAN_BUF_FAIL, "ipu init channel buffer fail"},
+ {STATE_INIT_CHAN_BAND_FAIL, "ipu init channel band mode fail"},
+ {STATE_SYS_NO_MEM, "sys no mem: -ENOMEM"},
+ {STATE_VDOA_IRQ_TIMEOUT, "wait for vdoa irq timeout"},
+ {STATE_VDOA_IRQ_FAIL, "vdoa irq fail"},
+ {STATE_VDOA_TASK_FAIL, "vdoa task fail"},
+};
+
+struct stripe_setting {
+ u32 iw;
+ u32 ih;
+ u32 ow;
+ u32 oh;
+ u32 outh_resize_ratio;
+ u32 outv_resize_ratio;
+ u32 i_left_pos;
+ u32 i_right_pos;
+ u32 i_top_pos;
+ u32 i_bottom_pos;
+ u32 o_left_pos;
+ u32 o_right_pos;
+ u32 o_top_pos;
+ u32 o_bottom_pos;
+ u32 rl_split_line;
+ u32 ud_split_line;
+};
+
+struct task_set {
+#define NULL_MODE 0x0
+#define IC_MODE 0x1
+#define ROT_MODE 0x2
+#define VDI_MODE 0x4
+#define IPU_PREPROCESS_MODE_MASK (IC_MODE | ROT_MODE | VDI_MODE)
+/* VDOA_MODE means this task use vdoa, and VDOA has two modes:
+ * BAND MODE and non-BAND MODE. Non-band mode will do transfer data
+ * to memory. BAND mode needs hareware sync with IPU, it is used default
+ * if connected to VDIC.
+ */
+#define VDOA_MODE 0x8
+#define VDOA_BAND_MODE 0x10
+ u8 mode;
+#define IC_VF 0x1
+#define IC_PP 0x2
+#define ROT_VF 0x4
+#define ROT_PP 0x8
+#define VDI_VF 0x10
+#define VDOA_ONLY 0x20
+ u8 task;
+#define NO_SPLIT 0x0
+#define RL_SPLIT 0x1
+#define UD_SPLIT 0x2
+#define LEFT_STRIPE 0x1
+#define RIGHT_STRIPE 0x2
+#define UP_STRIPE 0x4
+#define DOWN_STRIPE 0x8
+#define SPLIT_MASK 0xF
+ u8 split_mode;
+ u8 band_lines;
+ ipu_channel_t ic_chan;
+ ipu_channel_t rot_chan;
+ ipu_channel_t vdi_ic_p_chan;
+ ipu_channel_t vdi_ic_n_chan;
+
+ u32 i_off;
+ u32 i_uoff;
+ u32 i_voff;
+ u32 istride;
+
+ u32 ov_off;
+ u32 ov_uoff;
+ u32 ov_voff;
+ u32 ovstride;
+
+ u32 ov_alpha_off;
+ u32 ov_alpha_stride;
+
+ u32 o_off;
+ u32 o_uoff;
+ u32 o_voff;
+ u32 ostride;
+
+ u32 r_fmt;
+ u32 r_width;
+ u32 r_height;
+ u32 r_stride;
+ dma_addr_t r_paddr;
+
+ struct stripe_setting sp_setting;
+};
+
+struct ipu_split_task {
+ struct ipu_task task;
+ struct ipu_task_entry *parent_task;
+ struct ipu_task_entry *child_task;
+ u32 task_no;
+};
+
+struct ipu_task_entry {
+ struct ipu_input input;
+ struct ipu_output output;
+
+ bool overlay_en;
+ struct ipu_overlay overlay;
+#define DEF_TIMEOUT_MS 1000
+#define DEF_DELAY_MS 20
+ int timeout;
+ int irq;
+
+ u8 task_id;
+ u8 ipu_id;
+ u8 task_in_list;
+ u8 split_done;
+ struct mutex split_lock;
+ struct mutex vdic_lock;
+ wait_queue_head_t split_waitq;
+
+ struct list_head node;
+ struct list_head split_list;
+ struct ipu_soc *ipu;
+ struct device *dev;
+ struct task_set set;
+ wait_queue_head_t task_waitq;
+ struct completion irq_comp;
+ struct kref refcount;
+ ipu_state_t state;
+ u32 task_no;
+ atomic_t done;
+ atomic_t res_free;
+ atomic_t res_get;
+
+ struct ipu_task_entry *parent;
+ char *vditmpbuf[2];
+ u32 old_save_lines;
+ u32 old_size;
+ bool buf1filled;
+ bool buf0filled;
+
+ vdoa_handle_t vdoa_handle;
+ struct vdoa_output_mem {
+ void *vaddr;
+ dma_addr_t paddr;
+ int size;
+ } vdoa_dma;
+
+#ifdef DBG_IPU_PERF
+ struct timespec ts_queue;
+ struct timespec ts_dotask;
+ struct timespec ts_waitirq;
+ struct timespec ts_inirq;
+ struct timespec ts_wakeup;
+ struct timespec ts_rel;
+#endif
+};
+
+struct ipu_channel_tabel {
+ struct mutex lock;
+ u8 used[MXC_IPU_MAX_NUM][MAX_PP_CH];
+ u8 vdoa_used;
+};
+
+struct ipu_thread_data {
+ struct ipu_soc *ipu;
+ u32 id;
+ u32 is_vdoa;
+};
+
+struct ipu_alloc_list {
+ struct list_head list;
+ dma_addr_t phy_addr;
+ void *cpu_addr;
+ u32 size;
+ void *file_index;
+};
+
+static LIST_HEAD(ipu_alloc_list);
+static DEFINE_MUTEX(ipu_alloc_lock);
+static struct ipu_channel_tabel ipu_ch_tbl;
+static LIST_HEAD(ipu_task_list);
+static DEFINE_SPINLOCK(ipu_task_list_lock);
+static DECLARE_WAIT_QUEUE_HEAD(thread_waitq);
+static DECLARE_WAIT_QUEUE_HEAD(res_waitq);
+static atomic_t req_cnt;
+static atomic_t file_index = ATOMIC_INIT(1);
+static int major;
+static int max_ipu_no;
+static int thread_id;
+static atomic_t frame_no;
+static struct class *ipu_class;
+static struct device *ipu_dev;
+static int debug;
+module_param(debug, int, 0600);
+#ifdef DBG_IPU_PERF
+static struct timespec ts_frame_max;
+static u32 ts_frame_avg;
+static atomic_t frame_cnt;
+#endif
+
+static bool deinterlace_3_field(struct ipu_task_entry *t)
+{
+ return ((t->set.mode & VDI_MODE) &&
+ (t->input.deinterlace.motion != HIGH_MOTION));
+}
+
+static u32 tiled_filed_size(struct ipu_task_entry *t)
+{
+ u32 field_size;
+
+ /* note: page_align is required by VPU hw ouput buffer */
+ field_size = TILED_NV12_FRAME_SIZE(t->input.width, t->input.height/2);
+ return field_size;
+}
+
+static bool only_ic(u8 mode)
+{
+ mode = mode & IPU_PREPROCESS_MODE_MASK;
+ return ((mode == IC_MODE) || (mode == VDI_MODE));
+}
+
+static bool only_rot(u8 mode)
+{
+ mode = mode & IPU_PREPROCESS_MODE_MASK;
+ return (mode == ROT_MODE);
+}
+
+static bool ic_and_rot(u8 mode)
+{
+ mode = mode & IPU_PREPROCESS_MODE_MASK;
+ return ((mode == (IC_MODE | ROT_MODE)) ||
+ (mode == (VDI_MODE | ROT_MODE)));
+}
+
+static bool need_split(struct ipu_task_entry *t)
+{
+ return ((t->set.split_mode != NO_SPLIT) || (t->task_no & SPLIT_MASK));
+}
+
+unsigned int fmt_to_bpp(unsigned int pixelformat)
+{
+ u32 bpp;
+
+ switch (pixelformat) {
+ case IPU_PIX_FMT_RGB565:
+ /*interleaved 422*/
+ case IPU_PIX_FMT_YUYV:
+ case IPU_PIX_FMT_UYVY:
+ /*non-interleaved 422*/
+ case IPU_PIX_FMT_YUV422P:
+ case IPU_PIX_FMT_YVU422P:
+ bpp = 16;
+ break;
+ case IPU_PIX_FMT_BGR24:
+ case IPU_PIX_FMT_RGB24:
+ case IPU_PIX_FMT_YUV444:
+ case IPU_PIX_FMT_YUV444P:
+ bpp = 24;
+ break;
+ case IPU_PIX_FMT_BGR32:
+ case IPU_PIX_FMT_BGRA32:
+ case IPU_PIX_FMT_RGB32:
+ case IPU_PIX_FMT_RGBA32:
+ case IPU_PIX_FMT_ABGR32:
+ bpp = 32;
+ break;
+ /*non-interleaved 420*/
+ case IPU_PIX_FMT_YUV420P:
+ case IPU_PIX_FMT_YVU420P:
+ case IPU_PIX_FMT_YUV420P2:
+ case IPU_PIX_FMT_NV12:
+ bpp = 12;
+ break;
+ default:
+ bpp = 8;
+ break;
+ }
+ return bpp;
+}
+EXPORT_SYMBOL_GPL(fmt_to_bpp);
+
+cs_t colorspaceofpixel(int fmt)
+{
+ switch (fmt) {
+ case IPU_PIX_FMT_RGB565:
+ case IPU_PIX_FMT_RGB666:
+ case IPU_PIX_FMT_BGR24:
+ case IPU_PIX_FMT_RGB24:
+ case IPU_PIX_FMT_BGRA32:
+ case IPU_PIX_FMT_BGR32:
+ case IPU_PIX_FMT_RGBA32:
+ case IPU_PIX_FMT_RGB32:
+ case IPU_PIX_FMT_ABGR32:
+ return RGB_CS;
+ break;
+ case IPU_PIX_FMT_UYVY:
+ case IPU_PIX_FMT_YUYV:
+ case IPU_PIX_FMT_YUV420P2:
+ case IPU_PIX_FMT_YUV420P:
+ case IPU_PIX_FMT_YVU420P:
+ case IPU_PIX_FMT_YVU422P:
+ case IPU_PIX_FMT_YUV422P:
+ case IPU_PIX_FMT_YUV444:
+ case IPU_PIX_FMT_YUV444P:
+ case IPU_PIX_FMT_NV12:
+ case IPU_PIX_FMT_TILED_NV12:
+ case IPU_PIX_FMT_TILED_NV12F:
+ return YUV_CS;
+ break;
+ default:
+ return NULL_CS;
+ }
+}
+EXPORT_SYMBOL_GPL(colorspaceofpixel);
+
+int need_csc(int ifmt, int ofmt)
+{
+ cs_t ics, ocs;
+
+ ics = colorspaceofpixel(ifmt);
+ ocs = colorspaceofpixel(ofmt);
+
+ if ((ics == NULL_CS) || (ocs == NULL_CS))
+ return -1;
+ else if (ics != ocs)
+ return 1;
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(need_csc);
+
+static int soc_max_in_width(u32 is_vdoa)
+{
+ return is_vdoa ? 8192 : 4096;
+}
+
+static int soc_max_vdi_in_width(struct ipu_soc *ipu)
+{
+ int i;
+
+ if (!ipu) {
+ for (i = 0; i < max_ipu_no; i++) {
+ ipu = ipu_get_soc(i);
+ if (!IS_ERR_OR_NULL(ipu))
+ break;
+ }
+
+ if (i == max_ipu_no)
+ return 720;
+ }
+ return IPU_MAX_VDI_IN_WIDTH(ipu->devtype);
+}
+static int soc_max_in_height(void)
+{
+ return 4096;
+}
+
+static int soc_max_out_width(void)
+{
+ /* mx51/mx53/mx6q is 1024*/
+ return 1024;
+}
+
+static int soc_max_out_height(void)
+{
+ /* mx51/mx53/mx6q is 1024*/
+ return 1024;
+}
+
+static void dump_task_info(struct ipu_task_entry *t)
+{
+ if (!debug)
+ return;
+ dev_dbg(t->dev, "[0x%p]input:\n", (void *)t);
+ dev_dbg(t->dev, "[0x%p]\tformat = 0x%x\n", (void *)t, t->input.format);
+ dev_dbg(t->dev, "[0x%p]\twidth = %d\n", (void *)t, t->input.width);
+ dev_dbg(t->dev, "[0x%p]\theight = %d\n", (void *)t, t->input.height);
+ dev_dbg(t->dev, "[0x%p]\tcrop.w = %d\n", (void *)t, t->input.crop.w);
+ dev_dbg(t->dev, "[0x%p]\tcrop.h = %d\n", (void *)t, t->input.crop.h);
+ dev_dbg(t->dev, "[0x%p]\tcrop.pos.x = %d\n",
+ (void *)t, t->input.crop.pos.x);
+ dev_dbg(t->dev, "[0x%p]\tcrop.pos.y = %d\n",
+ (void *)t, t->input.crop.pos.y);
+ dev_dbg(t->dev, "[0x%p]input buffer:\n", (void *)t);
+ dev_dbg(t->dev, "[0x%p]\tpaddr = 0x%x\n", (void *)t, t->input.paddr);
+ dev_dbg(t->dev, "[0x%p]\ti_off = 0x%x\n", (void *)t, t->set.i_off);
+ dev_dbg(t->dev, "[0x%p]\ti_uoff = 0x%x\n", (void *)t, t->set.i_uoff);
+ dev_dbg(t->dev, "[0x%p]\ti_voff = 0x%x\n", (void *)t, t->set.i_voff);
+ dev_dbg(t->dev, "[0x%p]\tistride = %d\n", (void *)t, t->set.istride);
+ if (t->input.deinterlace.enable) {
+ dev_dbg(t->dev, "[0x%p]deinterlace enabled with:\n", (void *)t);
+ if (t->input.deinterlace.motion != HIGH_MOTION) {
+ dev_dbg(t->dev, "[0x%p]\tlow/medium motion\n", (void *)t);
+ dev_dbg(t->dev, "[0x%p]\tpaddr_n = 0x%x\n",
+ (void *)t, t->input.paddr_n);
+ } else
+ dev_dbg(t->dev, "[0x%p]\thigh motion\n", (void *)t);
+ }
+
+ dev_dbg(t->dev, "[0x%p]output:\n", (void *)t);
+ dev_dbg(t->dev, "[0x%p]\tformat = 0x%x\n", (void *)t, t->output.format);
+ dev_dbg(t->dev, "[0x%p]\twidth = %d\n", (void *)t, t->output.width);
+ dev_dbg(t->dev, "[0x%p]\theight = %d\n", (void *)t, t->output.height);
+ dev_dbg(t->dev, "[0x%p]\tcrop.w = %d\n", (void *)t, t->output.crop.w);
+ dev_dbg(t->dev, "[0x%p]\tcrop.h = %d\n", (void *)t, t->output.crop.h);
+ dev_dbg(t->dev, "[0x%p]\tcrop.pos.x = %d\n",
+ (void *)t, t->output.crop.pos.x);
+ dev_dbg(t->dev, "[0x%p]\tcrop.pos.y = %d\n",
+ (void *)t, t->output.crop.pos.y);
+ dev_dbg(t->dev, "[0x%p]\trotate = %d\n", (void *)t, t->output.rotate);
+ dev_dbg(t->dev, "[0x%p]output buffer:\n", (void *)t);
+ dev_dbg(t->dev, "[0x%p]\tpaddr = 0x%x\n", (void *)t, t->output.paddr);
+ dev_dbg(t->dev, "[0x%p]\to_off = 0x%x\n", (void *)t, t->set.o_off);
+ dev_dbg(t->dev, "[0x%p]\to_uoff = 0x%x\n", (void *)t, t->set.o_uoff);
+ dev_dbg(t->dev, "[0x%p]\to_voff = 0x%x\n", (void *)t, t->set.o_voff);
+ dev_dbg(t->dev, "[0x%p]\tostride = %d\n", (void *)t, t->set.ostride);
+
+ if (t->overlay_en) {
+ dev_dbg(t->dev, "[0x%p]overlay:\n", (void *)t);
+ dev_dbg(t->dev, "[0x%p]\tformat = 0x%x\n",
+ (void *)t, t->overlay.format);
+ dev_dbg(t->dev, "[0x%p]\twidth = %d\n",
+ (void *)t, t->overlay.width);
+ dev_dbg(t->dev, "[0x%p]\theight = %d\n",
+ (void *)t, t->overlay.height);
+ dev_dbg(t->dev, "[0x%p]\tcrop.w = %d\n",
+ (void *)t, t->overlay.crop.w);
+ dev_dbg(t->dev, "[0x%p]\tcrop.h = %d\n",
+ (void *)t, t->overlay.crop.h);
+ dev_dbg(t->dev, "[0x%p]\tcrop.pos.x = %d\n",
+ (void *)t, t->overlay.crop.pos.x);
+ dev_dbg(t->dev, "[0x%p]\tcrop.pos.y = %d\n",
+ (void *)t, t->overlay.crop.pos.y);
+ dev_dbg(t->dev, "[0x%p]overlay buffer:\n", (void *)t);
+ dev_dbg(t->dev, "[0x%p]\tpaddr = 0x%x\n",
+ (void *)t, t->overlay.paddr);
+ dev_dbg(t->dev, "[0x%p]\tov_off = 0x%x\n",
+ (void *)t, t->set.ov_off);
+ dev_dbg(t->dev, "[0x%p]\tov_uoff = 0x%x\n",
+ (void *)t, t->set.ov_uoff);
+ dev_dbg(t->dev, "[0x%p]\tov_voff = 0x%x\n",
+ (void *)t, t->set.ov_voff);
+ dev_dbg(t->dev, "[0x%p]\tovstride = %d\n",
+ (void *)t, t->set.ovstride);
+ if (t->overlay.alpha.mode == IPU_ALPHA_MODE_LOCAL) {
+ dev_dbg(t->dev, "[0x%p]local alpha enabled with:\n",
+ (void *)t);
+ dev_dbg(t->dev, "[0x%p]\tpaddr = 0x%x\n",
+ (void *)t, t->overlay.alpha.loc_alp_paddr);
+ dev_dbg(t->dev, "[0x%p]\tov_alpha_off = 0x%x\n",
+ (void *)t, t->set.ov_alpha_off);
+ dev_dbg(t->dev, "[0x%p]\tov_alpha_stride = %d\n",
+ (void *)t, t->set.ov_alpha_stride);
+ } else
+ dev_dbg(t->dev, "[0x%p]globle alpha enabled with value 0x%x\n",
+ (void *)t, t->overlay.alpha.gvalue);
+ if (t->overlay.colorkey.enable)
+ dev_dbg(t->dev, "[0x%p]colorkey enabled with value 0x%x\n",
+ (void *)t, t->overlay.colorkey.value);
+ }
+
+ dev_dbg(t->dev, "[0x%p]want task_id = %d\n", (void *)t, t->task_id);
+ dev_dbg(t->dev, "[0x%p]want task mode is 0x%x\n",
+ (void *)t, t->set.mode);
+ dev_dbg(t->dev, "[0x%p]\tIC_MODE = 0x%x\n", (void *)t, IC_MODE);
+ dev_dbg(t->dev, "[0x%p]\tROT_MODE = 0x%x\n", (void *)t, ROT_MODE);
+ dev_dbg(t->dev, "[0x%p]\tVDI_MODE = 0x%x\n", (void *)t, VDI_MODE);
+ dev_dbg(t->dev, "[0x%p]\tTask_no = 0x%x\n\n\n", (void *)t, t->task_no);
+}
+
+static void dump_check_err(struct device *dev, int err)
+{
+ switch (err) {
+ case IPU_CHECK_ERR_INPUT_CROP:
+ dev_err(dev, "input crop setting error\n");
+ break;
+ case IPU_CHECK_ERR_OUTPUT_CROP:
+ dev_err(dev, "output crop setting error\n");
+ break;
+ case IPU_CHECK_ERR_OVERLAY_CROP:
+ dev_err(dev, "overlay crop setting error\n");
+ break;
+ case IPU_CHECK_ERR_INPUT_OVER_LIMIT:
+ dev_err(dev, "input over limitation\n");
+ break;
+ case IPU_CHECK_ERR_OVERLAY_WITH_VDI:
+ dev_err(dev, "do not support overlay with deinterlace\n");
+ break;
+ case IPU_CHECK_ERR_OV_OUT_NO_FIT:
+ dev_err(dev,
+ "width/height of overlay and ic output should be same\n");
+ break;
+ case IPU_CHECK_ERR_PROC_NO_NEED:
+ dev_err(dev, "no ipu processing need\n");
+ break;
+ case IPU_CHECK_ERR_SPLIT_INPUTW_OVER:
+ dev_err(dev, "split mode input width overflow\n");
+ break;
+ case IPU_CHECK_ERR_SPLIT_INPUTH_OVER:
+ dev_err(dev, "split mode input height overflow\n");
+ break;
+ case IPU_CHECK_ERR_SPLIT_OUTPUTW_OVER:
+ dev_err(dev, "split mode output width overflow\n");
+ break;
+ case IPU_CHECK_ERR_SPLIT_OUTPUTH_OVER:
+ dev_err(dev, "split mode output height overflow\n");
+ break;
+ case IPU_CHECK_ERR_SPLIT_WITH_ROT:
+ dev_err(dev, "not support split mode with rotation\n");
+ break;
+ case IPU_CHECK_ERR_W_DOWNSIZE_OVER:
+ dev_err(dev, "horizontal downsizing ratio overflow\n");
+ break;
+ case IPU_CHECK_ERR_H_DOWNSIZE_OVER:
+ dev_err(dev, "vertical downsizing ratio overflow\n");
+ break;
+ default:
+ break;
+ }
+}
+
+static void dump_check_warn(struct device *dev, int warn)
+{
+ if (warn & IPU_CHECK_WARN_INPUT_OFFS_NOT8ALIGN)
+ dev_warn(dev, "input u/v offset not 8 align\n");
+ if (warn & IPU_CHECK_WARN_OUTPUT_OFFS_NOT8ALIGN)
+ dev_warn(dev, "output u/v offset not 8 align\n");
+ if (warn & IPU_CHECK_WARN_OVERLAY_OFFS_NOT8ALIGN)
+ dev_warn(dev, "overlay u/v offset not 8 align\n");
+}
+
+static int set_crop(struct ipu_crop *crop, int width, int height, int fmt)
+{
+ if ((width == 0) || (height == 0)) {
+ pr_err("Invalid param: width=%d, height=%d\n", width, height);
+ return -EINVAL;
+ }
+
+ if ((IPU_PIX_FMT_TILED_NV12 == fmt) ||
+ (IPU_PIX_FMT_TILED_NV12F == fmt)) {
+ if (crop->w || crop->h) {
+ if (((crop->w + crop->pos.x) > width)
+ || ((crop->h + crop->pos.y) > height)
+ || (0 != (crop->w % IPU_PIX_FMT_TILED_NV12_MBALIGN))
+ || (0 != (crop->h % IPU_PIX_FMT_TILED_NV12_MBALIGN))
+ || (0 != (crop->pos.x % IPU_PIX_FMT_TILED_NV12_MBALIGN))
+ || (0 != (crop->pos.y % IPU_PIX_FMT_TILED_NV12_MBALIGN))
+ ) {
+ pr_err("set_crop error MB align.\n");
+ return -EINVAL;
+ }
+ } else {
+ crop->pos.x = 0;
+ crop->pos.y = 0;
+ crop->w = width;
+ crop->h = height;
+ if ((0 != (crop->w % IPU_PIX_FMT_TILED_NV12_MBALIGN))
+ || (0 != (crop->h % IPU_PIX_FMT_TILED_NV12_MBALIGN))) {
+ pr_err("set_crop error w/h MB align.\n");
+ return -EINVAL;
+ }
+ }
+ } else {
+ if (crop->w || crop->h) {
+ if (((crop->w + crop->pos.x) > (width + 16))
+ || ((crop->h + crop->pos.y) > height + 16)) {
+ pr_err("set_crop error exceeds width/height.\n");
+ return -EINVAL;
+ }
+ } else {
+ crop->pos.x = 0;
+ crop->pos.y = 0;
+ crop->w = width;
+ crop->h = height;
+ }
+ crop->w -= crop->w%8;
+ crop->h -= crop->h%8;
+ }
+
+ if ((crop->w == 0) || (crop->h == 0)) {
+ pr_err("Invalid crop param: crop.w=%d, crop.h=%d\n",
+ crop->w, crop->h);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static void update_offset(unsigned int fmt,
+ unsigned int width, unsigned int height,
+ unsigned int pos_x, unsigned int pos_y,
+ int *off, int *uoff, int *voff, int *stride)
+{
+ /* NOTE: u v offset should based on start point of off*/
+ switch (fmt) {
+ case IPU_PIX_FMT_YUV420P2:
+ case IPU_PIX_FMT_YUV420P:
+ *off = pos_y * width + pos_x;
+ *uoff = (width * (height - pos_y) - pos_x)
+ + (width/2) * (pos_y/2) + pos_x/2;
+ /* In case height is odd, round up to even */
+ *voff = *uoff + (width/2) * ((height+1)/2);
+ break;
+ case IPU_PIX_FMT_YVU420P:
+ *off = pos_y * width + pos_x;
+ *voff = (width * (height - pos_y) - pos_x)
+ + (width/2) * (pos_y/2) + pos_x/2;
+ /* In case height is odd, round up to even */
+ *uoff = *voff + (width/2) * ((height+1)/2);
+ break;
+ case IPU_PIX_FMT_YVU422P:
+ *off = pos_y * width + pos_x;
+ *voff = (width * (height - pos_y) - pos_x)
+ + (width/2) * pos_y + pos_x/2;
+ *uoff = *voff + (width/2) * height;
+ break;
+ case IPU_PIX_FMT_YUV422P:
+ *off = pos_y * width + pos_x;
+ *uoff = (width * (height - pos_y) - pos_x)
+ + (width/2) * pos_y + pos_x/2;
+ *voff = *uoff + (width/2) * height;
+ break;
+ case IPU_PIX_FMT_YUV444P:
+ *off = pos_y * width + pos_x;
+ *uoff = width * height;
+ *voff = width * height * 2;
+ break;
+ case IPU_PIX_FMT_NV12:
+ *off = pos_y * width + pos_x;
+ *uoff = (width * (height - pos_y) - pos_x)
+ + width * (pos_y/2) + pos_x;
+ break;
+ case IPU_PIX_FMT_TILED_NV12:
+ /*
+ * tiled format, progressive:
+ * assuming that line is aligned with MB height (aligned to 16)
+ * offset = line * stride + (pixel / MB_width) * pixels_in_MB
+ * = line * stride + (pixel / 16) * 256
+ * = line * stride + pixel * 16
+ */
+ *off = pos_y * width + (pos_x << 4);
+ *uoff = ALIGN(width * height, SZ_4K) + (*off >> 1) - *off;
+ break;
+ case IPU_PIX_FMT_TILED_NV12F:
+ /*
+ * tiled format, interlaced:
+ * same as above, only number of pixels in MB is 128,
+ * instead of 256
+ */
+ *off = (pos_y >> 1) * width + (pos_x << 3);
+ *uoff = ALIGN(width * height/2, SZ_4K) + (*off >> 1) - *off;
+ break;
+ default:
+ *off = (pos_y * width + pos_x) * fmt_to_bpp(fmt)/8;
+ break;
+ }
+ *stride = width * bytes_per_pixel(fmt);
+}
+
+static int update_split_setting(struct ipu_task_entry *t, bool vdi_split)
+{
+ struct stripe_param left_stripe;
+ struct stripe_param right_stripe;
+ struct stripe_param up_stripe;
+ struct stripe_param down_stripe;
+ u32 iw, ih, ow, oh;
+ u32 max_width;
+ int ret;
+
+ if (t->output.rotate >= IPU_ROTATE_90_RIGHT)
+ return IPU_CHECK_ERR_SPLIT_WITH_ROT;
+
+ iw = t->input.crop.w;
+ ih = t->input.crop.h;
+
+ ow = t->output.crop.w;
+ oh = t->output.crop.h;
+
+ memset(&left_stripe, 0, sizeof(left_stripe));
+ memset(&right_stripe, 0, sizeof(right_stripe));
+ memset(&up_stripe, 0, sizeof(up_stripe));
+ memset(&down_stripe, 0, sizeof(down_stripe));
+
+ if (t->set.split_mode & RL_SPLIT) {
+ /*
+ * We do want equal strips: initialize stripes in case
+ * calc_stripes returns before actually doing the calculation
+ */
+ left_stripe.input_width = iw / 2;
+ left_stripe.output_width = ow / 2;
+ right_stripe.input_column = iw / 2;
+ right_stripe.output_column = ow / 2;
+
+ if (vdi_split)
+ max_width = soc_max_vdi_in_width(t->ipu);
+ else
+ max_width = soc_max_out_width();
+ ret = ipu_calc_stripes_sizes(iw,
+ ow,
+ max_width,
+ (((unsigned long long)1) << 32), /* 32bit for fractional*/
+ 1, /* equal stripes */
+ t->input.format,
+ t->output.format,
+ &left_stripe,
+ &right_stripe);
+ if (ret < 0)
+ return IPU_CHECK_ERR_W_DOWNSIZE_OVER;
+ else if (ret)
+ dev_dbg(t->dev, "Warn: no:0x%x,calc_stripes ret:%d\n",
+ t->task_no, ret);
+ t->set.sp_setting.iw = left_stripe.input_width;
+ t->set.sp_setting.ow = left_stripe.output_width;
+ t->set.sp_setting.outh_resize_ratio = left_stripe.irr;
+ t->set.sp_setting.i_left_pos = left_stripe.input_column;
+ t->set.sp_setting.o_left_pos = left_stripe.output_column;
+ t->set.sp_setting.i_right_pos = right_stripe.input_column;
+ t->set.sp_setting.o_right_pos = right_stripe.output_column;
+ } else {
+ t->set.sp_setting.iw = iw;
+ t->set.sp_setting.ow = ow;
+ t->set.sp_setting.outh_resize_ratio = 0;
+ t->set.sp_setting.i_left_pos = 0;
+ t->set.sp_setting.o_left_pos = 0;
+ t->set.sp_setting.i_right_pos = 0;
+ t->set.sp_setting.o_right_pos = 0;
+ }
+ if ((t->set.sp_setting.iw + t->set.sp_setting.i_right_pos) > (iw+16))
+ return IPU_CHECK_ERR_SPLIT_INPUTW_OVER;
+ if (((t->set.sp_setting.ow + t->set.sp_setting.o_right_pos) > ow)
+ || (t->set.sp_setting.ow > soc_max_out_width()))
+ return IPU_CHECK_ERR_SPLIT_OUTPUTW_OVER;
+ if (rounddown(t->set.sp_setting.ow, 8) * 8 <=
+ rounddown(t->set.sp_setting.iw, 8))
+ return IPU_CHECK_ERR_W_DOWNSIZE_OVER;
+
+ if (t->set.split_mode & UD_SPLIT) {
+ /*
+ * We do want equal strips: initialize stripes in case
+ * calc_stripes returns before actually doing the calculation
+ */
+ up_stripe.input_width = ih / 2;
+ up_stripe.output_width = oh / 2;
+ down_stripe.input_column = ih / 2;
+ down_stripe.output_column = oh / 2;
+ ret = ipu_calc_stripes_sizes(ih,
+ oh,
+ soc_max_out_height(),
+ (((unsigned long long)1) << 32), /* 32bit for fractional*/
+ 0x1 | 0x2, /* equal stripes and vertical */
+ t->input.format,
+ t->output.format,
+ &up_stripe,
+ &down_stripe);
+ if (ret < 0)
+ return IPU_CHECK_ERR_H_DOWNSIZE_OVER;
+ else if (ret)
+ dev_err(t->dev, "Warn: no:0x%x,calc_stripes ret:%d\n",
+ t->task_no, ret);
+ t->set.sp_setting.ih = up_stripe.input_width;
+ t->set.sp_setting.oh = up_stripe.output_width;
+ t->set.sp_setting.outv_resize_ratio = up_stripe.irr;
+ t->set.sp_setting.i_top_pos = up_stripe.input_column;
+ t->set.sp_setting.o_top_pos = up_stripe.output_column;
+ t->set.sp_setting.i_bottom_pos = down_stripe.input_column;
+ t->set.sp_setting.o_bottom_pos = down_stripe.output_column;
+ } else {
+ t->set.sp_setting.ih = ih;
+ t->set.sp_setting.oh = oh;
+ t->set.sp_setting.outv_resize_ratio = 0;
+ t->set.sp_setting.i_top_pos = 0;
+ t->set.sp_setting.o_top_pos = 0;
+ t->set.sp_setting.i_bottom_pos = 0;
+ t->set.sp_setting.o_bottom_pos = 0;
+ }
+
+ /* downscale case: enforce limits */
+ if (((t->set.sp_setting.ih + t->set.sp_setting.i_bottom_pos) > (ih))
+ && (t->set.sp_setting.ih >= t->set.sp_setting.oh))
+ return IPU_CHECK_ERR_SPLIT_INPUTH_OVER;
+ /* upscale case: relax limits because ipu_calc_stripes_sizes() may
+ create input stripe that falls just outside of the input window */
+ else if ((t->set.sp_setting.ih + t->set.sp_setting.i_bottom_pos)
+ > (ih+16))
+ return IPU_CHECK_ERR_SPLIT_INPUTH_OVER;
+ if (((t->set.sp_setting.oh + t->set.sp_setting.o_bottom_pos) > oh)
+ || (t->set.sp_setting.oh > soc_max_out_height()))
+ return IPU_CHECK_ERR_SPLIT_OUTPUTH_OVER;
+ if (rounddown(t->set.sp_setting.oh, 8) * 8 <=
+ rounddown(t->set.sp_setting.ih, 8))
+ return IPU_CHECK_ERR_H_DOWNSIZE_OVER;
+
+ return IPU_CHECK_OK;
+}
+
+static int check_task(struct ipu_task_entry *t)
+{
+ int tmp;
+ int ret = IPU_CHECK_OK;
+ int timeout;
+ bool vdi_split = false;
+ int ocw, och;
+
+ if ((IPU_PIX_FMT_TILED_NV12 == t->overlay.format) ||
+ (IPU_PIX_FMT_TILED_NV12F == t->overlay.format) ||
+ (IPU_PIX_FMT_TILED_NV12 == t->output.format) ||
+ (IPU_PIX_FMT_TILED_NV12F == t->output.format) ||
+ ((IPU_PIX_FMT_TILED_NV12F == t->input.format) &&
+ !t->input.deinterlace.enable)) {
+ ret = IPU_CHECK_ERR_NOT_SUPPORT;
+ goto done;
+ }
+
+ /* check input */
+ ret = set_crop(&t->input.crop, t->input.width, t->input.height,
+ t->input.format);
+ if (ret < 0) {
+ ret = IPU_CHECK_ERR_INPUT_CROP;
+ goto done;
+ } else
+ update_offset(t->input.format, t->input.width, t->input.height,
+ t->input.crop.pos.x, t->input.crop.pos.y,
+ &t->set.i_off, &t->set.i_uoff,
+ &t->set.i_voff, &t->set.istride);
+
+ /* check output */
+ ret = set_crop(&t->output.crop, t->output.width, t->output.height,
+ t->output.format);
+ if (ret < 0) {
+ ret = IPU_CHECK_ERR_OUTPUT_CROP;
+ goto done;
+ } else
+ update_offset(t->output.format,
+ t->output.width, t->output.height,
+ t->output.crop.pos.x, t->output.crop.pos.y,
+ &t->set.o_off, &t->set.o_uoff,
+ &t->set.o_voff, &t->set.ostride);
+
+ if (t->output.rotate >= IPU_ROTATE_90_RIGHT) {
+ /*
+ * Cache output width and height and
+ * swap them so that we may check
+ * downsize overflow correctly.
+ */
+ ocw = t->output.crop.h;
+ och = t->output.crop.w;
+ } else {
+ ocw = t->output.crop.w;
+ och = t->output.crop.h;
+ }
+
+ if (ocw * 8 <= t->input.crop.w) {
+ ret = IPU_CHECK_ERR_W_DOWNSIZE_OVER;
+ goto done;
+ }
+
+ if (och * 8 <= t->input.crop.h) {
+ ret = IPU_CHECK_ERR_H_DOWNSIZE_OVER;
+ goto done;
+ }
+
+ if ((IPU_PIX_FMT_TILED_NV12 == t->input.format) ||
+ (IPU_PIX_FMT_TILED_NV12F == t->input.format)) {
+ if ((t->input.crop.w > soc_max_in_width(1)) ||
+ (t->input.crop.h > soc_max_in_height())) {
+ ret = IPU_CHECK_ERR_INPUT_OVER_LIMIT;
+ goto done;
+ }
+ /* output fmt: NV12 and YUYV, now don't support resize */
+ if (((IPU_PIX_FMT_NV12 != t->output.format) &&
+ (IPU_PIX_FMT_YUYV != t->output.format)) ||
+ (t->input.crop.w != t->output.crop.w) ||
+ (t->input.crop.h != t->output.crop.h)) {
+ ret = IPU_CHECK_ERR_NOT_SUPPORT;
+ goto done;
+ }
+ }
+
+ /* check overlay if there is */
+ if (t->overlay_en) {
+ if (t->input.deinterlace.enable) {
+ ret = IPU_CHECK_ERR_OVERLAY_WITH_VDI;
+ goto done;
+ }
+
+ ret = set_crop(&t->overlay.crop, t->overlay.width,
+ t->overlay.height, t->overlay.format);
+ if (ret < 0) {
+ ret = IPU_CHECK_ERR_OVERLAY_CROP;
+ goto done;
+ } else {
+ ocw = t->output.crop.w;
+ och = t->output.crop.h;
+
+ if (t->output.rotate >= IPU_ROTATE_90_RIGHT) {
+ ocw = t->output.crop.h;
+ och = t->output.crop.w;
+ }
+ if ((t->overlay.crop.w != ocw) ||
+ (t->overlay.crop.h != och)) {
+ ret = IPU_CHECK_ERR_OV_OUT_NO_FIT;
+ goto done;
+ }
+
+ update_offset(t->overlay.format,
+ t->overlay.width, t->overlay.height,
+ t->overlay.crop.pos.x, t->overlay.crop.pos.y,
+ &t->set.ov_off, &t->set.ov_uoff,
+ &t->set.ov_voff, &t->set.ovstride);
+ if (t->overlay.alpha.mode == IPU_ALPHA_MODE_LOCAL) {
+ t->set.ov_alpha_stride = t->overlay.width;
+ t->set.ov_alpha_off = t->overlay.crop.pos.y *
+ t->overlay.width + t->overlay.crop.pos.x;
+ }
+ }
+ }
+
+ /* input overflow? */
+ if (!((IPU_PIX_FMT_TILED_NV12 == t->input.format) ||
+ (IPU_PIX_FMT_TILED_NV12F == t->input.format))) {
+ if ((t->input.crop.w > soc_max_in_width(0)) ||
+ (t->input.crop.h > soc_max_in_height())) {
+ ret = IPU_CHECK_ERR_INPUT_OVER_LIMIT;
+ goto done;
+ }
+ }
+
+ /* check task mode */
+ t->set.mode = NULL_MODE;
+ t->set.split_mode = NO_SPLIT;
+
+ if (t->output.rotate >= IPU_ROTATE_90_RIGHT) {
+ /*output swap*/
+ tmp = t->output.crop.w;
+ t->output.crop.w = t->output.crop.h;
+ t->output.crop.h = tmp;
+ }
+
+ if (t->output.rotate >= IPU_ROTATE_90_RIGHT)
+ t->set.mode |= ROT_MODE;
+
+ /*need resize or CSC?*/
+ if ((t->input.crop.w != t->output.crop.w) ||
+ (t->input.crop.h != t->output.crop.h) ||
+ need_csc(t->input.format, t->output.format))
+ t->set.mode |= IC_MODE;
+
+ /*need cropping?*/
+ if ((t->input.crop.w != t->input.width) ||
+ (t->input.crop.h != t->input.height) ||
+ (t->output.crop.w != t->output.width) ||
+ (t->output.crop.h != t->output.height))
+ t->set.mode |= IC_MODE;
+
+ /*need flip?*/
+ if ((t->set.mode == NULL_MODE) && (t->output.rotate > IPU_ROTATE_NONE))
+ t->set.mode |= IC_MODE;
+
+ /*need IDMAC do format(same color space)?*/
+ if ((t->set.mode == NULL_MODE) && (t->input.format != t->output.format))
+ t->set.mode |= IC_MODE;
+
+ /*overlay support*/
+ if (t->overlay_en)
+ t->set.mode |= IC_MODE;
+
+ /*deinterlace*/
+ if (t->input.deinterlace.enable) {
+ t->set.mode &= ~IC_MODE;
+ t->set.mode |= VDI_MODE;
+ }
+ if ((IPU_PIX_FMT_TILED_NV12 == t->input.format) ||
+ (IPU_PIX_FMT_TILED_NV12F == t->input.format)) {
+ if (t->set.mode & ROT_MODE) {
+ ret = IPU_CHECK_ERR_NOT_SUPPORT;
+ goto done;
+ }
+ t->set.mode |= VDOA_MODE;
+ if (IPU_PIX_FMT_TILED_NV12F == t->input.format)
+ t->set.mode |= VDOA_BAND_MODE;
+ t->set.mode &= ~IC_MODE;
+ }
+
+ if ((t->set.mode & (IC_MODE | VDI_MODE)) &&
+ (IPU_PIX_FMT_TILED_NV12F != t->input.format)) {
+ if (t->output.crop.w > soc_max_out_width())
+ t->set.split_mode |= RL_SPLIT;
+ if (t->output.crop.h > soc_max_out_height())
+ t->set.split_mode |= UD_SPLIT;
+ if (!t->set.split_mode && (t->set.mode & VDI_MODE) &&
+ (t->input.crop.w >
+ soc_max_vdi_in_width(t->ipu))) {
+ t->set.split_mode |= RL_SPLIT;
+ vdi_split = true;
+ }
+ if (t->set.split_mode) {
+ if ((t->set.split_mode == RL_SPLIT) ||
+ (t->set.split_mode == UD_SPLIT))
+ timeout = DEF_TIMEOUT_MS * 2 + DEF_DELAY_MS;
+ else
+ timeout = DEF_TIMEOUT_MS * 4 + DEF_DELAY_MS;
+ if (t->timeout < timeout)
+ t->timeout = timeout;
+
+ ret = update_split_setting(t, vdi_split);
+ if (ret > IPU_CHECK_ERR_MIN)
+ goto done;
+ }
+ }
+
+ if (t->output.rotate >= IPU_ROTATE_90_RIGHT) {
+ /*output swap*/
+ tmp = t->output.crop.w;
+ t->output.crop.w = t->output.crop.h;
+ t->output.crop.h = tmp;
+ }
+
+ if (t->set.mode == NULL_MODE) {
+ ret = IPU_CHECK_ERR_PROC_NO_NEED;
+ goto done;
+ }
+
+ if ((t->set.i_uoff % 8) || (t->set.i_voff % 8))
+ ret |= IPU_CHECK_WARN_INPUT_OFFS_NOT8ALIGN;
+ if ((t->set.o_uoff % 8) || (t->set.o_voff % 8))
+ ret |= IPU_CHECK_WARN_OUTPUT_OFFS_NOT8ALIGN;
+ if (t->overlay_en && ((t->set.ov_uoff % 8) || (t->set.ov_voff % 8)))
+ ret |= IPU_CHECK_WARN_OVERLAY_OFFS_NOT8ALIGN;
+
+done:
+ /* dump msg */
+ if (debug) {
+ if (ret > IPU_CHECK_ERR_MIN)
+ dump_check_err(t->dev, ret);
+ else if (ret != IPU_CHECK_OK)
+ dump_check_warn(t->dev, ret);
+ }
+
+ return ret;
+}
+
+static int prepare_task(struct ipu_task_entry *t)
+{
+ int ret = 0;
+
+ ret = check_task(t);
+ if (ret > IPU_CHECK_ERR_MIN)
+ return -EINVAL;
+
+ if (t->set.mode & VDI_MODE) {
+ t->task_id = IPU_TASK_ID_VF;
+ t->set.task = VDI_VF;
+ if (t->set.mode & ROT_MODE)
+ t->set.task |= ROT_VF;
+ }
+
+ if (VDOA_MODE == t->set.mode) {
+ if (t->set.task != 0) {
+ dev_err(t->dev, "ERR: vdoa only task:0x%x, [0x%p].\n",
+ t->set.task, t);
+ return -EINVAL;
+ }
+ t->set.task |= VDOA_ONLY;
+ }
+
+ if (VDOA_BAND_MODE & t->set.mode) {
+ /* to save band size: 1<<3 = 8 lines */
+ t->set.band_lines = 3;
+ }
+
+ dump_task_info(t);
+
+ return ret;
+}
+
+static uint32_t ic_vf_pp_is_busy(struct ipu_soc *ipu, bool is_vf)
+{
+ uint32_t status;
+ uint32_t status_vf;
+ uint32_t status_rot;
+
+ if (is_vf) {
+ status = ipu_channel_status(ipu, MEM_VDI_PRP_VF_MEM);
+ status_vf = ipu_channel_status(ipu, MEM_PRP_VF_MEM);
+ status_rot = ipu_channel_status(ipu, MEM_ROT_VF_MEM);
+ return status || status_vf || status_rot;
+ } else {
+ status = ipu_channel_status(ipu, MEM_PP_MEM);
+ status_rot = ipu_channel_status(ipu, MEM_ROT_PP_MEM);
+ return status || status_rot;
+ }
+}
+
+static int _get_vdoa_ipu_res(struct ipu_task_entry *t)
+{
+ int i;
+ struct ipu_soc *ipu;
+ u8 *used;
+ uint32_t found_ipu = 0;
+ uint32_t found_vdoa = 0;
+ struct ipu_channel_tabel *tbl = &ipu_ch_tbl;
+
+ mutex_lock(&tbl->lock);
+ if (t->set.mode & VDOA_MODE) {
+ if (NULL != t->vdoa_handle)
+ found_vdoa = 1;
+ else {
+ found_vdoa = tbl->vdoa_used ? 0 : 1;
+ if (found_vdoa) {
+ tbl->vdoa_used = 1;
+ vdoa_get_handle(&t->vdoa_handle);
+ } else
+ /* first get vdoa->ipu resource sequence */
+ goto out;
+ if (t->set.task & VDOA_ONLY)
+ goto out;
+ }
+ }
+
+ for (i = 0; i < max_ipu_no; i++) {
+ ipu = ipu_get_soc(i);
+ if (IS_ERR(ipu))
+ dev_err(t->dev, "no:0x%x,found_vdoa:%d, ipu:%d\n",
+ t->task_no, found_vdoa, i);
+
+ used = &tbl->used[i][IPU_PP_CH_VF];
+ if (t->set.mode & VDI_MODE) {
+ if (0 == *used) {
+ *used = 1;
+ found_ipu = 1;
+ break;
+ }
+ } else if ((t->set.mode & IC_MODE) || only_rot(t->set.mode)) {
+ if (0 == *used) {
+ t->task_id = IPU_TASK_ID_VF;
+ if (t->set.mode & IC_MODE)
+ t->set.task |= IC_VF;
+ if (t->set.mode & ROT_MODE)
+ t->set.task |= ROT_VF;
+ *used = 1;
+ found_ipu = 1;
+ break;
+ }
+ } else
+ dev_err(t->dev, "no:0x%x,found_vdoa:%d, mode:0x%x\n",
+ t->task_no, found_vdoa, t->set.mode);
+ }
+ if (found_ipu)
+ goto next;
+
+ for (i = 0; i < max_ipu_no; i++) {
+ ipu = ipu_get_soc(i);
+ if (IS_ERR(ipu))
+ dev_err(t->dev, "no:0x%x,found_vdoa:%d, ipu:%d\n",
+ t->task_no, found_vdoa, i);
+
+ if ((t->set.mode & IC_MODE) || only_rot(t->set.mode)) {
+ used = &tbl->used[i][IPU_PP_CH_PP];
+ if (0 == *used) {
+ t->task_id = IPU_TASK_ID_PP;
+ if (t->set.mode & IC_MODE)
+ t->set.task |= IC_PP;
+ if (t->set.mode & ROT_MODE)
+ t->set.task |= ROT_PP;
+ *used = 1;
+ found_ipu = 1;
+ break;
+ }
+ }
+ }
+
+next:
+ if (found_ipu) {
+ t->ipu = ipu;
+ t->ipu_id = i;
+ t->dev = ipu->dev;
+ if (atomic_inc_return(&t->res_get) == 2)
+ dev_err(t->dev,
+ "ERR no:0x%x,found_vdoa:%d,get ipu twice\n",
+ t->task_no, found_vdoa);
+ }
+out:
+ dev_dbg(t->dev,
+ "%s:no:0x%x,found_vdoa:%d, found_ipu:%d\n",
+ __func__, t->task_no, found_vdoa, found_ipu);
+ mutex_unlock(&tbl->lock);
+ if (t->set.task & VDOA_ONLY)
+ return found_vdoa;
+ else if (t->set.mode & VDOA_MODE)
+ return found_vdoa && found_ipu;
+ else
+ return found_ipu;
+}
+
+static void put_vdoa_ipu_res(struct ipu_task_entry *tsk, int vdoa_only)
+{
+ int ret;
+ int rel_vdoa = 0, rel_ipu = 0;
+ struct ipu_channel_tabel *tbl = &ipu_ch_tbl;
+
+ mutex_lock(&tbl->lock);
+ if (tsk->set.mode & VDOA_MODE) {
+ if (!tbl->vdoa_used && tsk->vdoa_handle)
+ dev_err(tsk->dev,
+ "ERR no:0x%x,vdoa not used,mode:0x%x\n",
+ tsk->task_no, tsk->set.mode);
+ if (tbl->vdoa_used && tsk->vdoa_handle) {
+ tbl->vdoa_used = 0;
+ vdoa_put_handle(&tsk->vdoa_handle);
+ if (tsk->ipu)
+ tsk->ipu->vdoa_en = 0;
+ rel_vdoa = 1;
+ if (vdoa_only || (tsk->set.task & VDOA_ONLY))
+ goto out;
+ }
+ }
+
+ if (tsk->ipu_id != 0 && tsk->ipu_id != 1) {
+ dev_err(tsk->dev,
+ "%s:invalid ipu id, no:0x%x, rel_vdoa:%d, rel_ipu:%d\n",
+ __func__, tsk->task_no, rel_vdoa, rel_ipu);
+ goto out;
+ }
+
+ tbl->used[tsk->ipu_id][tsk->task_id - 1] = 0;
+ rel_ipu = 1;
+ ret = atomic_inc_return(&tsk->res_free);
+ if (ret == 2)
+ dev_err(tsk->dev,
+ "ERR no:0x%x,rel_vdoa:%d,put ipu twice\n",
+ tsk->task_no, rel_vdoa);
+out:
+ dev_dbg(tsk->dev,
+ "%s:no:0x%x,rel_vdoa:%d, rel_ipu:%d\n",
+ __func__, tsk->task_no, rel_vdoa, rel_ipu);
+ mutex_unlock(&tbl->lock);
+}
+
+static int get_vdoa_ipu_res(struct ipu_task_entry *t)
+{
+ int ret;
+ uint32_t found = 0;
+
+ found = _get_vdoa_ipu_res(t);
+ if (!found) {
+ t->ipu_id = -1;
+ t->ipu = NULL;
+ /* blocking to get resource */
+ ret = atomic_inc_return(&req_cnt);
+ dev_dbg(t->dev,
+ "wait_res:no:0x%x,req_cnt:%d\n", t->task_no, ret);
+ ret = wait_event_timeout(res_waitq, _get_vdoa_ipu_res(t),
+ msecs_to_jiffies(t->timeout - DEF_DELAY_MS));
+ if (ret == 0) {
+ dev_err(t->dev, "ERR[0x%p,no-0x%x] wait_res timeout:%dms!\n",
+ t, t->task_no, t->timeout - DEF_DELAY_MS);
+ ret = -ETIMEDOUT;
+ t->state = STATE_RES_TIMEOUT;
+ goto out;
+ } else {
+ if (!(t->set.task & VDOA_ONLY) && (!t->ipu))
+ dev_err(t->dev,
+ "ERR[no-0x%x] can not get ipu!\n",
+ t->task_no);
+ ret = atomic_read(&req_cnt);
+ if (ret > 0)
+ ret = atomic_dec_return(&req_cnt);
+ else
+ dev_err(t->dev,
+ "ERR[no-0x%x] req_cnt:%d mismatch!\n",
+ t->task_no, ret);
+ dev_dbg(t->dev, "no-0x%x,[0x%p],req_cnt:%d, got_res!\n",
+ t->task_no, t, ret);
+ found = 1;
+ }
+ }
+
+out:
+ return found;
+}
+
+static struct ipu_task_entry *create_task_entry(struct ipu_task *task)
+{
+ struct ipu_task_entry *tsk;
+
+ tsk = kzalloc(sizeof(struct ipu_task_entry), GFP_KERNEL);
+ if (!tsk)
+ return ERR_PTR(-ENOMEM);
+ kref_init(&tsk->refcount);
+ tsk->state = -EINVAL;
+ tsk->ipu_id = -1;
+ tsk->dev = ipu_dev;
+ tsk->input = task->input;
+ tsk->output = task->output;
+ tsk->overlay_en = task->overlay_en;
+ if (tsk->overlay_en)
+ tsk->overlay = task->overlay;
+ if (task->timeout > DEF_TIMEOUT_MS)
+ tsk->timeout = task->timeout;
+ else
+ tsk->timeout = DEF_TIMEOUT_MS;
+
+ return tsk;
+}
+
+static void task_mem_free(struct kref *ref)
+{
+ struct ipu_task_entry *tsk =
+ container_of(ref, struct ipu_task_entry, refcount);
+ kfree(tsk);
+}
+
+int create_split_child_task(struct ipu_split_task *sp_task)
+{
+ int ret = 0;
+ struct ipu_task_entry *tsk;
+
+ tsk = create_task_entry(&sp_task->task);
+ if (IS_ERR(tsk))
+ return PTR_ERR(tsk);
+
+ sp_task->child_task = tsk;
+ tsk->task_no = sp_task->task_no;
+
+ ret = prepare_task(tsk);
+ if (ret < 0)
+ goto err;
+
+ tsk->parent = sp_task->parent_task;
+ tsk->set.sp_setting = sp_task->parent_task->set.sp_setting;
+
+ list_add(&tsk->node, &tsk->parent->split_list);
+ dev_dbg(tsk->dev, "[0x%p] sp_tsk Q list,no-0x%x\n", tsk, tsk->task_no);
+ tsk->state = STATE_QUEUE;
+ CHECK_PERF(&tsk->ts_queue);
+err:
+ return ret;
+}
+
+static inline int sp_task_check_done(struct ipu_split_task *sp_task,
+ struct ipu_task_entry *parent, int num, int *idx)
+{
+ int i;
+ int ret = 0;
+ struct ipu_task_entry *tsk;
+ struct mutex *lock = &parent->split_lock;
+
+ *idx = -EINVAL;
+ mutex_lock(lock);
+ for (i = 0; i < num; i++) {
+ tsk = sp_task[i].child_task;
+ if (tsk && tsk->split_done) {
+ *idx = i;
+ ret = 1;
+ goto out;
+ }
+ }
+
+out:
+ mutex_unlock(lock);
+ return ret;
+}
+
+static int create_split_task(
+ int stripe,
+ struct ipu_split_task *sp_task)
+{
+ struct ipu_task *task = &(sp_task->task);
+ struct ipu_task_entry *t = sp_task->parent_task;
+ int ret;
+
+ sp_task->task_no |= stripe;
+
+ task->input = t->input;
+ task->output = t->output;
+ task->overlay_en = t->overlay_en;
+ if (task->overlay_en)
+ task->overlay = t->overlay;
+ task->task_id = t->task_id;
+ if ((t->set.split_mode == RL_SPLIT) ||
+ (t->set.split_mode == UD_SPLIT))
+ task->timeout = t->timeout / 2;
+ else
+ task->timeout = t->timeout / 4;
+
+ task->input.crop.w = t->set.sp_setting.iw;
+ task->input.crop.h = t->set.sp_setting.ih;
+ if (task->overlay_en) {
+ task->overlay.crop.w = t->set.sp_setting.ow;
+ task->overlay.crop.h = t->set.sp_setting.oh;
+ }
+ if (t->output.rotate >= IPU_ROTATE_90_RIGHT) {
+ task->output.crop.w = t->set.sp_setting.oh;
+ task->output.crop.h = t->set.sp_setting.ow;
+ t->set.sp_setting.rl_split_line = t->set.sp_setting.o_bottom_pos;
+ t->set.sp_setting.ud_split_line = t->set.sp_setting.o_right_pos;
+
+ } else {
+ task->output.crop.w = t->set.sp_setting.ow;
+ task->output.crop.h = t->set.sp_setting.oh;
+ t->set.sp_setting.rl_split_line = t->set.sp_setting.o_right_pos;
+ t->set.sp_setting.ud_split_line = t->set.sp_setting.o_bottom_pos;
+ }
+
+ if (stripe & LEFT_STRIPE)
+ task->input.crop.pos.x += t->set.sp_setting.i_left_pos;
+ else if (stripe & RIGHT_STRIPE)
+ task->input.crop.pos.x += t->set.sp_setting.i_right_pos;
+ if (stripe & UP_STRIPE)
+ task->input.crop.pos.y += t->set.sp_setting.i_top_pos;
+ else if (stripe & DOWN_STRIPE)
+ task->input.crop.pos.y += t->set.sp_setting.i_bottom_pos;
+
+ if (task->overlay_en) {
+ if (stripe & LEFT_STRIPE)
+ task->overlay.crop.pos.x += t->set.sp_setting.o_left_pos;
+ else if (stripe & RIGHT_STRIPE)
+ task->overlay.crop.pos.x += t->set.sp_setting.o_right_pos;
+ if (stripe & UP_STRIPE)
+ task->overlay.crop.pos.y += t->set.sp_setting.o_top_pos;
+ else if (stripe & DOWN_STRIPE)
+ task->overlay.crop.pos.y += t->set.sp_setting.o_bottom_pos;
+ }
+
+ switch (t->output.rotate) {
+ case IPU_ROTATE_NONE:
+ if (stripe & LEFT_STRIPE)
+ task->output.crop.pos.x += t->set.sp_setting.o_left_pos;
+ else if (stripe & RIGHT_STRIPE)
+ task->output.crop.pos.x += t->set.sp_setting.o_right_pos;
+ if (stripe & UP_STRIPE)
+ task->output.crop.pos.y += t->set.sp_setting.o_top_pos;
+ else if (stripe & DOWN_STRIPE)
+ task->output.crop.pos.y += t->set.sp_setting.o_bottom_pos;
+ break;
+ case IPU_ROTATE_VERT_FLIP:
+ if (stripe & LEFT_STRIPE)
+ task->output.crop.pos.x += t->set.sp_setting.o_left_pos;
+ else if (stripe & RIGHT_STRIPE)
+ task->output.crop.pos.x += t->set.sp_setting.o_right_pos;
+ if (stripe & UP_STRIPE)
+ task->output.crop.pos.y =
+ t->output.crop.pos.y + t->output.crop.h
+ - t->set.sp_setting.o_top_pos - t->set.sp_setting.oh;
+ else if (stripe & DOWN_STRIPE)
+ task->output.crop.pos.y =
+ t->output.crop.pos.y + t->output.crop.h
+ - t->set.sp_setting.o_bottom_pos - t->set.sp_setting.oh;
+ break;
+ case IPU_ROTATE_HORIZ_FLIP:
+ if (stripe & LEFT_STRIPE)
+ task->output.crop.pos.x =
+ t->output.crop.pos.x + t->output.crop.w
+ - t->set.sp_setting.o_left_pos - t->set.sp_setting.ow;
+ else if (stripe & RIGHT_STRIPE)
+ task->output.crop.pos.x =
+ t->output.crop.pos.x + t->output.crop.w
+ - t->set.sp_setting.o_right_pos - t->set.sp_setting.ow;
+ if (stripe & UP_STRIPE)
+ task->output.crop.pos.y += t->set.sp_setting.o_top_pos;
+ else if (stripe & DOWN_STRIPE)
+ task->output.crop.pos.y += t->set.sp_setting.o_bottom_pos;
+ break;
+ case IPU_ROTATE_180:
+ if (stripe & LEFT_STRIPE)
+ task->output.crop.pos.x =
+ t->output.crop.pos.x + t->output.crop.w
+ - t->set.sp_setting.o_left_pos - t->set.sp_setting.ow;
+ else if (stripe & RIGHT_STRIPE)
+ task->output.crop.pos.x =
+ t->output.crop.pos.x + t->output.crop.w
+ - t->set.sp_setting.o_right_pos - t->set.sp_setting.ow;
+ if (stripe & UP_STRIPE)
+ task->output.crop.pos.y =
+ t->output.crop.pos.y + t->output.crop.h
+ - t->set.sp_setting.o_top_pos - t->set.sp_setting.oh;
+ else if (stripe & DOWN_STRIPE)
+ task->output.crop.pos.y =
+ t->output.crop.pos.y + t->output.crop.h
+ - t->set.sp_setting.o_bottom_pos - t->set.sp_setting.oh;
+ break;
+ case IPU_ROTATE_90_RIGHT:
+ if (stripe & UP_STRIPE)
+ task->output.crop.pos.x =
+ t->output.crop.pos.x + t->output.crop.w
+ - t->set.sp_setting.o_top_pos - t->set.sp_setting.oh;
+ else if (stripe & DOWN_STRIPE)
+ task->output.crop.pos.x =
+ t->output.crop.pos.x + t->output.crop.w
+ - t->set.sp_setting.o_bottom_pos - t->set.sp_setting.oh;
+ if (stripe & LEFT_STRIPE)
+ task->output.crop.pos.y += t->set.sp_setting.o_left_pos;
+ else if (stripe & RIGHT_STRIPE)
+ task->output.crop.pos.y += t->set.sp_setting.o_right_pos;
+ break;
+ case IPU_ROTATE_90_RIGHT_HFLIP:
+ if (stripe & UP_STRIPE)
+ task->output.crop.pos.x += t->set.sp_setting.o_top_pos;
+ else if (stripe & DOWN_STRIPE)
+ task->output.crop.pos.x += t->set.sp_setting.o_bottom_pos;
+ if (stripe & LEFT_STRIPE)
+ task->output.crop.pos.y += t->set.sp_setting.o_left_pos;
+ else if (stripe & RIGHT_STRIPE)
+ task->output.crop.pos.y += t->set.sp_setting.o_right_pos;
+ break;
+ case IPU_ROTATE_90_RIGHT_VFLIP:
+ if (stripe & UP_STRIPE)
+ task->output.crop.pos.x =
+ t->output.crop.pos.x + t->output.crop.w
+ - t->set.sp_setting.o_top_pos - t->set.sp_setting.oh;
+ else if (stripe & DOWN_STRIPE)
+ task->output.crop.pos.x =
+ t->output.crop.pos.x + t->output.crop.w
+ - t->set.sp_setting.o_bottom_pos - t->set.sp_setting.oh;
+ if (stripe & LEFT_STRIPE)
+ task->output.crop.pos.y =
+ t->output.crop.pos.y + t->output.crop.h
+ - t->set.sp_setting.o_left_pos - t->set.sp_setting.ow;
+ else if (stripe & RIGHT_STRIPE)
+ task->output.crop.pos.y =
+ t->output.crop.pos.y + t->output.crop.h
+ - t->set.sp_setting.o_right_pos - t->set.sp_setting.ow;
+ break;
+ case IPU_ROTATE_90_LEFT:
+ if (stripe & UP_STRIPE)
+ task->output.crop.pos.x += t->set.sp_setting.o_top_pos;
+ else if (stripe & DOWN_STRIPE)
+ task->output.crop.pos.x += t->set.sp_setting.o_bottom_pos;
+ if (stripe & LEFT_STRIPE)
+ task->output.crop.pos.y =
+ t->output.crop.pos.y + t->output.crop.h
+ - t->set.sp_setting.o_left_pos - t->set.sp_setting.ow;
+ else if (stripe & RIGHT_STRIPE)
+ task->output.crop.pos.y =
+ t->output.crop.pos.y + t->output.crop.h
+ - t->set.sp_setting.o_right_pos - t->set.sp_setting.ow;
+ break;
+ default:
+ dev_err(t->dev, "ERR:should not be here\n");
+ break;
+ }
+
+ ret = create_split_child_task(sp_task);
+ if (ret < 0)
+ dev_err(t->dev, "ERR:create_split_child_task() ret:%d\n", ret);
+ return ret;
+}
+
+static int queue_split_task(struct ipu_task_entry *t,
+ struct ipu_split_task *sp_task, uint32_t size)
+{
+ int err[4];
+ int ret = 0;
+ int i, j;
+ struct ipu_task_entry *tsk = NULL;
+ struct mutex *lock = &t->split_lock;
+ struct mutex *vdic_lock = &t->vdic_lock;
+
+ dev_dbg(t->dev, "Split task 0x%p, no-0x%x, size:%d\n",
+ t, t->task_no, size);
+ mutex_init(lock);
+ mutex_init(vdic_lock);
+ init_waitqueue_head(&t->split_waitq);
+ INIT_LIST_HEAD(&t->split_list);
+ for (j = 0; j < size; j++) {
+ memset(&sp_task[j], 0, sizeof(*sp_task));
+ sp_task[j].parent_task = t;
+ sp_task[j].task_no = t->task_no;
+ }
+
+ if (t->set.split_mode == RL_SPLIT) {
+ i = 0;
+ err[i] = create_split_task(RIGHT_STRIPE, &sp_task[i]);
+ if (err[i] < 0)
+ goto err_start;
+ i = 1;
+ err[i] = create_split_task(LEFT_STRIPE, &sp_task[i]);
+ } else if (t->set.split_mode == UD_SPLIT) {
+ i = 0;
+ err[i] = create_split_task(DOWN_STRIPE, &sp_task[i]);
+ if (err[i] < 0)
+ goto err_start;
+ i = 1;
+ err[i] = create_split_task(UP_STRIPE, &sp_task[i]);
+ } else {
+ i = 0;
+ err[i] = create_split_task(RIGHT_STRIPE | DOWN_STRIPE, &sp_task[i]);
+ if (err[i] < 0)
+ goto err_start;
+ i = 1;
+ err[i] = create_split_task(LEFT_STRIPE | DOWN_STRIPE, &sp_task[i]);
+ if (err[i] < 0)
+ goto err_start;
+ i = 2;
+ err[i] = create_split_task(RIGHT_STRIPE | UP_STRIPE, &sp_task[i]);
+ if (err[i] < 0)
+ goto err_start;
+ i = 3;
+ err[i] = create_split_task(LEFT_STRIPE | UP_STRIPE, &sp_task[i]);
+ }
+
+err_start:
+ for (j = 0; j < (i + 1); j++) {
+ if (err[j] < 0) {
+ if (sp_task[j].child_task)
+ dev_err(t->dev,
+ "sp_task[%d],no-0x%x fail state:%d, queue err:%d.\n",
+ j, sp_task[j].child_task->task_no,
+ sp_task[j].child_task->state, err[j]);
+ goto err_exit;
+ }
+ dev_dbg(t->dev, "[0x%p] sp_task[%d], no-0x%x state:%s, queue ret:%d.\n",
+ sp_task[j].child_task, j, sp_task[j].child_task->task_no,
+ state_msg[sp_task[j].child_task->state].msg, err[j]);
+ }
+
+ return ret;
+
+err_exit:
+ for (j = 0; j < (i + 1); j++) {
+ if (err[j] < 0 && !ret)
+ ret = err[j];
+ tsk = sp_task[j].child_task;
+ if (!tsk)
+ continue;
+ kfree(tsk);
+ }
+ t->state = STATE_ERR;
+ return ret;
+
+}
+
+static int init_tiled_buf(struct ipu_soc *ipu, struct ipu_task_entry *t,
+ ipu_channel_t channel, uint32_t ch_type)
+{
+ int ret = 0;
+ int i;
+ uint32_t ipu_fmt;
+ dma_addr_t inbuf_base = 0;
+ u32 field_size;
+ struct vdoa_params param;
+ struct vdoa_ipu_buf buf;
+ struct ipu_soc *ipu_idx;
+ u32 ipu_stride, obuf_size;
+ u32 height, width;
+ ipu_buffer_t type;
+
+ if ((IPU_PIX_FMT_YUYV != t->output.format) &&
+ (IPU_PIX_FMT_NV12 != t->output.format)) {
+ dev_err(t->dev, "ERR:[0x%d] output format\n", t->task_no);
+ return -EINVAL;
+ }
+
+ memset(&param, 0, sizeof(param));
+ /* init channel tiled bufs */
+ if (deinterlace_3_field(t) &&
+ (IPU_PIX_FMT_TILED_NV12F == t->input.format)) {
+ field_size = tiled_filed_size(t);
+ if (INPUT_CHAN_VDI_P == ch_type) {
+ inbuf_base = t->input.paddr + field_size;
+ param.vfield_buf.prev_veba = inbuf_base + t->set.i_off;
+ } else if (INPUT_CHAN == ch_type) {
+ inbuf_base = t->input.paddr_n;
+ param.vfield_buf.cur_veba = inbuf_base + t->set.i_off;
+ } else if (INPUT_CHAN_VDI_N == ch_type) {
+ inbuf_base = t->input.paddr_n + field_size;
+ param.vfield_buf.next_veba = inbuf_base + t->set.i_off;
+ } else
+ return -EINVAL;
+ height = t->input.crop.h >> 1; /* field format for vdoa */
+ width = t->input.crop.w;
+ param.vfield_buf.vubo = t->set.i_uoff;
+ param.interlaced = 1;
+ param.scan_order = 1;
+ type = IPU_INPUT_BUFFER;
+ } else if ((IPU_PIX_FMT_TILED_NV12 == t->input.format) &&
+ (INPUT_CHAN == ch_type)) {
+ height = t->input.crop.h;
+ width = t->input.crop.w;
+ param.vframe_buf.veba = t->input.paddr + t->set.i_off;
+ param.vframe_buf.vubo = t->set.i_uoff;
+ type = IPU_INPUT_BUFFER;
+ } else
+ return -EINVAL;
+
+ param.band_mode = (t->set.mode & VDOA_BAND_MODE) ? 1 : 0;
+ if (param.band_mode && (t->set.band_lines != 3) &&
+ (t->set.band_lines != 4) && (t->set.band_lines != 5))
+ return -EINVAL;
+ else if (param.band_mode)
+ param.band_lines = (1 << t->set.band_lines);
+ for (i = 0; i < max_ipu_no; i++) {
+ ipu_idx = ipu_get_soc(i);
+ if (!IS_ERR(ipu_idx) && ipu_idx == ipu)
+ break;
+ }
+ if (t->set.task & VDOA_ONLY)
+ /* dummy, didn't need ipu res */
+ i = 0;
+ if (max_ipu_no == i) {
+ dev_err(t->dev, "ERR:[0x%p] get ipu num\n", t);
+ return -EINVAL;
+ }
+
+ param.ipu_num = i;
+ param.vpu_stride = t->input.width;
+ param.height = height;
+ param.width = width;
+ if (IPU_PIX_FMT_NV12 == t->output.format)
+ param.pfs = VDOA_PFS_NV12;
+ else
+ param.pfs = VDOA_PFS_YUYV;
+ ipu_fmt = (param.pfs == VDOA_PFS_YUYV) ? IPU_PIX_FMT_YUYV :
+ IPU_PIX_FMT_NV12;
+ ipu_stride = param.width * bytes_per_pixel(ipu_fmt);
+ obuf_size = PAGE_ALIGN(param.width * param.height *
+ fmt_to_bpp(ipu_fmt)/8);
+ dev_dbg(t->dev, "band_mode:%d, band_lines:%d\n",
+ param.band_mode, param.band_lines);
+ if (!param.band_mode) {
+ /* note: if only for tiled -> raster convert and
+ no other post-processing, we don't need alloc buf
+ and use output buffer directly.
+ */
+ if (t->set.task & VDOA_ONLY)
+ param.ieba0 = t->output.paddr;
+ else {
+ dev_err(t->dev, "ERR:[0x%d] vdoa task\n", t->task_no);
+ return -EINVAL;
+ }
+ } else {
+ if (IPU_PIX_FMT_TILED_NV12F != t->input.format) {
+ dev_err(t->dev, "ERR [0x%d] vdoa task\n", t->task_no);
+ return -EINVAL;
+ }
+ }
+ ret = vdoa_setup(t->vdoa_handle, &param);
+ if (ret)
+ goto done;
+ vdoa_get_output_buf(t->vdoa_handle, &buf);
+ if (t->set.task & VDOA_ONLY)
+ goto done;
+
+ ret = ipu_init_channel_buffer(ipu,
+ channel,
+ type,
+ ipu_fmt,
+ width,
+ height,
+ ipu_stride,
+ IPU_ROTATE_NONE,
+ buf.ieba0,
+ buf.ieba1,
+ 0,
+ buf.iubo,
+ 0);
+ if (ret < 0) {
+ t->state = STATE_INIT_CHAN_BUF_FAIL;
+ goto done;
+ }
+
+ if (param.band_mode) {
+ ret = ipu_set_channel_bandmode(ipu, channel,
+ type, t->set.band_lines);
+ if (ret < 0) {
+ t->state = STATE_INIT_CHAN_BAND_FAIL;
+ goto done;
+ }
+ }
+done:
+ return ret;
+}
+
+static int init_tiled_ch_bufs(struct ipu_soc *ipu, struct ipu_task_entry *t)
+{
+ int ret = 0;
+
+ if (IPU_PIX_FMT_TILED_NV12 == t->input.format) {
+ ret = init_tiled_buf(ipu, t, t->set.ic_chan, INPUT_CHAN);
+ CHECK_RETCODE(ret < 0, "init tiled_ch", t->state, done, ret);
+ } else if (IPU_PIX_FMT_TILED_NV12F == t->input.format) {
+ ret = init_tiled_buf(ipu, t, t->set.ic_chan, INPUT_CHAN);
+ CHECK_RETCODE(ret < 0, "init tiled_ch-c", t->state, done, ret);
+ ret = init_tiled_buf(ipu, t, t->set.vdi_ic_p_chan,
+ INPUT_CHAN_VDI_P);
+ CHECK_RETCODE(ret < 0, "init tiled_ch-p", t->state, done, ret);
+ ret = init_tiled_buf(ipu, t, t->set.vdi_ic_n_chan,
+ INPUT_CHAN_VDI_N);
+ CHECK_RETCODE(ret < 0, "init tiled_ch-n", t->state, done, ret);
+ } else {
+ ret = -EINVAL;
+ dev_err(t->dev, "ERR[no-0x%x] invalid fmt:0x%x!\n",
+ t->task_no, t->input.format);
+ }
+
+done:
+ return ret;
+}
+
+static int init_ic(struct ipu_soc *ipu, struct ipu_task_entry *t)
+{
+ int ret = 0;
+ ipu_channel_params_t params;
+ dma_addr_t inbuf = 0, ovbuf = 0, ov_alp_buf = 0;
+ dma_addr_t inbuf_p = 0, inbuf_n = 0;
+ dma_addr_t outbuf = 0;
+ int out_uoff = 0, out_voff = 0, out_rot;
+ int out_w = 0, out_h = 0, out_stride;
+ int out_fmt;
+ u32 vdi_frame_idx = 0;
+
+ memset(&params, 0, sizeof(params));
+
+ /* is it need link a rot channel */
+ if (ic_and_rot(t->set.mode)) {
+ outbuf = t->set.r_paddr;
+ out_w = t->set.r_width;
+ out_h = t->set.r_height;
+ out_stride = t->set.r_stride;
+ out_fmt = t->set.r_fmt;
+ out_uoff = 0;
+ out_voff = 0;
+ out_rot = IPU_ROTATE_NONE;
+ } else {
+ outbuf = t->output.paddr + t->set.o_off;
+ out_w = t->output.crop.w;
+ out_h = t->output.crop.h;
+ out_stride = t->set.ostride;
+ out_fmt = t->output.format;
+ out_uoff = t->set.o_uoff;
+ out_voff = t->set.o_voff;
+ out_rot = t->output.rotate;
+ }
+
+ /* settings */
+ params.mem_prp_vf_mem.in_width = t->input.crop.w;
+ params.mem_prp_vf_mem.out_width = out_w;
+ params.mem_prp_vf_mem.in_height = t->input.crop.h;
+ params.mem_prp_vf_mem.out_height = out_h;
+ params.mem_prp_vf_mem.in_pixel_fmt = t->input.format;
+ params.mem_prp_vf_mem.out_pixel_fmt = out_fmt;
+ params.mem_prp_vf_mem.motion_sel = t->input.deinterlace.motion;
+
+ params.mem_prp_vf_mem.outh_resize_ratio =
+ t->set.sp_setting.outh_resize_ratio;
+ params.mem_prp_vf_mem.outv_resize_ratio =
+ t->set.sp_setting.outv_resize_ratio;
+
+ if (t->overlay_en) {
+ params.mem_prp_vf_mem.in_g_pixel_fmt = t->overlay.format;
+ params.mem_prp_vf_mem.graphics_combine_en = 1;
+ if (t->overlay.alpha.mode == IPU_ALPHA_MODE_GLOBAL)
+ params.mem_prp_vf_mem.global_alpha_en = 1;
+ else if (t->overlay.alpha.loc_alp_paddr)
+ params.mem_prp_vf_mem.alpha_chan_en = 1;
+ /* otherwise, alpha bending per pixel is used. */
+ params.mem_prp_vf_mem.alpha = t->overlay.alpha.gvalue;
+ if (t->overlay.colorkey.enable) {
+ params.mem_prp_vf_mem.key_color_en = 1;
+ params.mem_prp_vf_mem.key_color = t->overlay.colorkey.value;
+ }
+ }
+
+ if (t->input.deinterlace.enable) {
+ if (t->input.deinterlace.field_fmt & IPU_DEINTERLACE_FIELD_MASK)
+ params.mem_prp_vf_mem.field_fmt =
+ IPU_DEINTERLACE_FIELD_BOTTOM;
+ else
+ params.mem_prp_vf_mem.field_fmt =
+ IPU_DEINTERLACE_FIELD_TOP;
+
+ if (t->input.deinterlace.field_fmt & IPU_DEINTERLACE_RATE_EN)
+ vdi_frame_idx = t->input.deinterlace.field_fmt &
+ IPU_DEINTERLACE_RATE_FRAME1;
+ }
+
+ if (t->set.mode & VDOA_MODE)
+ ipu->vdoa_en = 1;
+
+ /* init channels */
+ if (!(t->set.task & VDOA_ONLY)) {
+ ret = ipu_init_channel(ipu, t->set.ic_chan, &params);
+ if (ret < 0) {
+ t->state = STATE_INIT_CHAN_FAIL;
+ goto done;
+ }
+ }
+
+ if (deinterlace_3_field(t)) {
+ ret = ipu_init_channel(ipu, t->set.vdi_ic_p_chan, &params);
+ if (ret < 0) {
+ t->state = STATE_INIT_CHAN_FAIL;
+ goto done;
+ }
+ ret = ipu_init_channel(ipu, t->set.vdi_ic_n_chan, &params);
+ if (ret < 0) {
+ t->state = STATE_INIT_CHAN_FAIL;
+ goto done;
+ }
+ }
+
+ /* init channel bufs */
+ if ((IPU_PIX_FMT_TILED_NV12 == t->input.format) ||
+ (IPU_PIX_FMT_TILED_NV12F == t->input.format)) {
+ ret = init_tiled_ch_bufs(ipu, t);
+ if (ret < 0)
+ goto done;
+ } else {
+ if ((deinterlace_3_field(t)) &&
+ (IPU_PIX_FMT_TILED_NV12F != t->input.format)) {
+ if (params.mem_prp_vf_mem.field_fmt ==
+ IPU_DEINTERLACE_FIELD_TOP) {
+ if (vdi_frame_idx) {
+ inbuf_p = t->input.paddr + t->set.istride +
+ t->set.i_off;
+ inbuf = t->input.paddr_n + t->set.i_off;
+ inbuf_n = t->input.paddr_n + t->set.istride +
+ t->set.i_off;
+ params.mem_prp_vf_mem.field_fmt =
+ IPU_DEINTERLACE_FIELD_BOTTOM;
+ } else {
+ inbuf_p = t->input.paddr + t->set.i_off;
+ inbuf = t->input.paddr + t->set.istride + t->set.i_off;
+ inbuf_n = t->input.paddr_n + t->set.i_off;
+ }
+ } else {
+ if (vdi_frame_idx) {
+ inbuf_p = t->input.paddr + t->set.i_off;
+ inbuf = t->input.paddr_n + t->set.istride + t->set.i_off;
+ inbuf_n = t->input.paddr_n + t->set.i_off;
+ params.mem_prp_vf_mem.field_fmt =
+ IPU_DEINTERLACE_FIELD_TOP;
+ } else {
+ inbuf_p = t->input.paddr + t->set.istride +
+ t->set.i_off;
+ inbuf = t->input.paddr + t->set.i_off;
+ inbuf_n = t->input.paddr_n + t->set.istride +
+ t->set.i_off;
+ }
+ }
+ } else {
+ if (t->input.deinterlace.enable) {
+ if (params.mem_prp_vf_mem.field_fmt ==
+ IPU_DEINTERLACE_FIELD_TOP) {
+ if (vdi_frame_idx) {
+ inbuf = t->input.paddr + t->set.istride + t->set.i_off;
+ params.mem_prp_vf_mem.field_fmt =
+ IPU_DEINTERLACE_FIELD_BOTTOM;
+ } else
+ inbuf = t->input.paddr + t->set.i_off;
+ } else {
+ if (vdi_frame_idx) {
+ inbuf = t->input.paddr + t->set.i_off;
+ params.mem_prp_vf_mem.field_fmt =
+ IPU_DEINTERLACE_FIELD_TOP;
+ } else
+ inbuf = t->input.paddr + t->set.istride + t->set.i_off;
+ }
+ } else
+ inbuf = t->input.paddr + t->set.i_off;
+ }
+
+ if (t->overlay_en)
+ ovbuf = t->overlay.paddr + t->set.ov_off;
+ }
+ if (t->overlay_en && (t->overlay.alpha.mode == IPU_ALPHA_MODE_LOCAL))
+ ov_alp_buf = t->overlay.alpha.loc_alp_paddr
+ + t->set.ov_alpha_off;
+
+ if ((IPU_PIX_FMT_TILED_NV12 != t->input.format) &&
+ (IPU_PIX_FMT_TILED_NV12F != t->input.format)) {
+ ret = ipu_init_channel_buffer(ipu,
+ t->set.ic_chan,
+ IPU_INPUT_BUFFER,
+ t->input.format,
+ t->input.crop.w,
+ t->input.crop.h,
+ t->set.istride,
+ IPU_ROTATE_NONE,
+ inbuf,
+ 0,
+ 0,
+ t->set.i_uoff,
+ t->set.i_voff);
+ if (ret < 0) {
+ t->state = STATE_INIT_CHAN_BUF_FAIL;
+ goto done;
+ }
+ }
+ if (deinterlace_3_field(t) &&
+ (IPU_PIX_FMT_TILED_NV12F != t->input.format)) {
+ ret = ipu_init_channel_buffer(ipu,
+ t->set.vdi_ic_p_chan,
+ IPU_INPUT_BUFFER,
+ t->input.format,
+ t->input.crop.w,
+ t->input.crop.h,
+ t->set.istride,
+ IPU_ROTATE_NONE,
+ inbuf_p,
+ 0,
+ 0,
+ t->set.i_uoff,
+ t->set.i_voff);
+ if (ret < 0) {
+ t->state = STATE_INIT_CHAN_BUF_FAIL;
+ goto done;
+ }
+
+ ret = ipu_init_channel_buffer(ipu,
+ t->set.vdi_ic_n_chan,
+ IPU_INPUT_BUFFER,
+ t->input.format,
+ t->input.crop.w,
+ t->input.crop.h,
+ t->set.istride,
+ IPU_ROTATE_NONE,
+ inbuf_n,
+ 0,
+ 0,
+ t->set.i_uoff,
+ t->set.i_voff);
+ if (ret < 0) {
+ t->state = STATE_INIT_CHAN_BUF_FAIL;
+ goto done;
+ }
+ }
+
+ if (t->overlay_en) {
+ ret = ipu_init_channel_buffer(ipu,
+ t->set.ic_chan,
+ IPU_GRAPH_IN_BUFFER,
+ t->overlay.format,
+ t->overlay.crop.w,
+ t->overlay.crop.h,
+ t->set.ovstride,
+ IPU_ROTATE_NONE,
+ ovbuf,
+ 0,
+ 0,
+ t->set.ov_uoff,
+ t->set.ov_voff);
+ if (ret < 0) {
+ t->state = STATE_INIT_CHAN_BUF_FAIL;
+ goto done;
+ }
+ }
+
+ if (t->overlay.alpha.mode == IPU_ALPHA_MODE_LOCAL) {
+ ret = ipu_init_channel_buffer(ipu,
+ t->set.ic_chan,
+ IPU_ALPHA_IN_BUFFER,
+ IPU_PIX_FMT_GENERIC,
+ t->overlay.crop.w,
+ t->overlay.crop.h,
+ t->set.ov_alpha_stride,
+ IPU_ROTATE_NONE,
+ ov_alp_buf,
+ 0,
+ 0,
+ 0, 0);
+ if (ret < 0) {
+ t->state = STATE_INIT_CHAN_BUF_FAIL;
+ goto done;
+ }
+ }
+
+ if (!(t->set.task & VDOA_ONLY)) {
+ ret = ipu_init_channel_buffer(ipu,
+ t->set.ic_chan,
+ IPU_OUTPUT_BUFFER,
+ out_fmt,
+ out_w,
+ out_h,
+ out_stride,
+ out_rot,
+ outbuf,
+ 0,
+ 0,
+ out_uoff,
+ out_voff);
+ if (ret < 0) {
+ t->state = STATE_INIT_CHAN_BUF_FAIL;
+ goto done;
+ }
+ }
+
+ if ((t->set.mode & VDOA_BAND_MODE) && (t->set.task & VDI_VF)) {
+ ret = ipu_link_channels(ipu, MEM_VDOA_MEM, t->set.ic_chan);
+ CHECK_RETCODE(ret < 0, "ipu_link_ch vdoa_ic",
+ STATE_LINK_CHAN_FAIL, done, ret);
+ }
+
+done:
+ return ret;
+}
+
+static void uninit_ic(struct ipu_soc *ipu, struct ipu_task_entry *t)
+{
+ int ret;
+
+ if ((t->set.mode & VDOA_BAND_MODE) && (t->set.task & VDI_VF)) {
+ ret = ipu_unlink_channels(ipu, MEM_VDOA_MEM, t->set.ic_chan);
+ CHECK_RETCODE_CONT(ret < 0, "ipu_unlink_ch vdoa_ic",
+ STATE_UNLINK_CHAN_FAIL, ret);
+ }
+ ipu_uninit_channel(ipu, t->set.ic_chan);
+ if (deinterlace_3_field(t)) {
+ ipu_uninit_channel(ipu, t->set.vdi_ic_p_chan);
+ ipu_uninit_channel(ipu, t->set.vdi_ic_n_chan);
+ }
+}
+
+static int init_rot(struct ipu_soc *ipu, struct ipu_task_entry *t)
+{
+ int ret = 0;
+ dma_addr_t inbuf = 0, outbuf = 0;
+ int in_uoff = 0, in_voff = 0;
+ int in_fmt, in_width, in_height, in_stride;
+
+ /* init channel */
+ ret = ipu_init_channel(ipu, t->set.rot_chan, NULL);
+ if (ret < 0) {
+ t->state = STATE_INIT_CHAN_FAIL;
+ goto done;
+ }
+
+ /* init channel buf */
+ /* is it need link to a ic channel */
+ if (ic_and_rot(t->set.mode)) {
+ in_fmt = t->set.r_fmt;
+ in_width = t->set.r_width;
+ in_height = t->set.r_height;
+ in_stride = t->set.r_stride;
+ inbuf = t->set.r_paddr;
+ in_uoff = 0;
+ in_voff = 0;
+ } else {
+ in_fmt = t->input.format;
+ in_width = t->input.crop.w;
+ in_height = t->input.crop.h;
+ in_stride = t->set.istride;
+ inbuf = t->input.paddr + t->set.i_off;
+ in_uoff = t->set.i_uoff;
+ in_voff = t->set.i_voff;
+ }
+ outbuf = t->output.paddr + t->set.o_off;
+
+ ret = ipu_init_channel_buffer(ipu,
+ t->set.rot_chan,
+ IPU_INPUT_BUFFER,
+ in_fmt,
+ in_width,
+ in_height,
+ in_stride,
+ t->output.rotate,
+ inbuf,
+ 0,
+ 0,
+ in_uoff,
+ in_voff);
+ if (ret < 0) {
+ t->state = STATE_INIT_CHAN_BUF_FAIL;
+ goto done;
+ }
+
+ ret = ipu_init_channel_buffer(ipu,
+ t->set.rot_chan,
+ IPU_OUTPUT_BUFFER,
+ t->output.format,
+ t->output.crop.w,
+ t->output.crop.h,
+ t->set.ostride,
+ IPU_ROTATE_NONE,
+ outbuf,
+ 0,
+ 0,
+ t->set.o_uoff,
+ t->set.o_voff);
+ if (ret < 0) {
+ t->state = STATE_INIT_CHAN_BUF_FAIL;
+ goto done;
+ }
+
+done:
+ return ret;
+}
+
+static void uninit_rot(struct ipu_soc *ipu, struct ipu_task_entry *t)
+{
+ ipu_uninit_channel(ipu, t->set.rot_chan);
+}
+
+static int get_irq(struct ipu_task_entry *t)
+{
+ int irq;
+ ipu_channel_t chan;
+
+ if (only_ic(t->set.mode))
+ chan = t->set.ic_chan;
+ else
+ chan = t->set.rot_chan;
+
+ switch (chan) {
+ case MEM_ROT_VF_MEM:
+ irq = IPU_IRQ_PRP_VF_ROT_OUT_EOF;
+ break;
+ case MEM_ROT_PP_MEM:
+ irq = IPU_IRQ_PP_ROT_OUT_EOF;
+ break;
+ case MEM_VDI_PRP_VF_MEM:
+ case MEM_PRP_VF_MEM:
+ irq = IPU_IRQ_PRP_VF_OUT_EOF;
+ break;
+ case MEM_PP_MEM:
+ irq = IPU_IRQ_PP_OUT_EOF;
+ break;
+ case MEM_VDI_MEM:
+ irq = IPU_IRQ_VDIC_OUT_EOF;
+ break;
+ default:
+ irq = -EINVAL;
+ }
+
+ return irq;
+}
+
+static irqreturn_t task_irq_handler(int irq, void *dev_id)
+{
+ struct ipu_task_entry *prev_tsk = dev_id;
+
+ CHECK_PERF(&prev_tsk->ts_inirq);
+ complete(&prev_tsk->irq_comp);
+ dev_dbg(prev_tsk->dev, "[0x%p] no-0x%x in-irq!",
+ prev_tsk, prev_tsk->task_no);
+
+ return IRQ_HANDLED;
+}
+
+/* Fix deinterlace up&down split mode medium line */
+static void vdi_split_process(struct ipu_soc *ipu, struct ipu_task_entry *t)
+{
+ u32 vdi_size;
+ u32 vdi_save_lines;
+ u32 stripe_mode;
+ u32 task_no;
+ u32 i, offset_addr;
+ u32 line_size;
+ unsigned char *base_off;
+ struct ipu_task_entry *parent = t->parent;
+ struct mutex *lock = &parent->vdic_lock;
+
+ if (!parent) {
+ dev_err(t->dev, "ERR[0x%x]invalid parent\n", t->task_no);
+ return;
+ }
+ mutex_lock(lock);
+ stripe_mode = t->task_no & 0xf;
+ task_no = t->task_no >> 4;
+
+ /* Save both luma and chroma part for interleaved YUV(e.g. YUYV).
+ * Save luma part for non-interleaved and partial-interleaved
+ * YUV format (e.g NV12 and YV12). */
+ if (t->output.format == IPU_PIX_FMT_YUYV ||
+ t->output.format == IPU_PIX_FMT_UYVY)
+ line_size = t->output.crop.w * fmt_to_bpp(t->output.format)/8;
+ else
+ line_size = t->output.crop.w;
+
+ vdi_save_lines = (t->output.crop.h - t->set.sp_setting.ud_split_line)/2;
+ vdi_size = vdi_save_lines * line_size;
+ if (vdi_save_lines <= 0) {
+ dev_err(t->dev, "[0x%p] vdi_save_line error\n", (void *)t);
+ mutex_unlock(lock);
+ return;
+ }
+
+ /*check vditmpbuf buffer have alloced or buffer size is changed */
+ if ((vdi_save_lines != parent->old_save_lines) ||
+ (vdi_size != parent->old_size)) {
+ if (parent->vditmpbuf[0] != NULL)
+ kfree(parent->vditmpbuf[0]);
+ if (parent->vditmpbuf[1] != NULL)
+ kfree(parent->vditmpbuf[1]);
+
+ parent->vditmpbuf[0] = kmalloc(vdi_size, GFP_KERNEL);
+ if (parent->vditmpbuf[0] == NULL) {
+ dev_err(t->dev,
+ "[0x%p]Falied Alloc vditmpbuf[0]\n", (void *)t);
+ mutex_unlock(lock);
+ return;
+ }
+ memset(parent->vditmpbuf[0], 0, vdi_size);
+
+ parent->vditmpbuf[1] = kmalloc(vdi_size, GFP_KERNEL);
+ if (parent->vditmpbuf[1] == NULL) {
+ dev_err(t->dev,
+ "[0x%p]Falied Alloc vditmpbuf[1]\n", (void *)t);
+ mutex_unlock(lock);
+ return;
+ }
+ memset(parent->vditmpbuf[1], 0, vdi_size);
+
+ parent->old_save_lines = vdi_save_lines;
+ parent->old_size = vdi_size;
+ }
+
+ if (pfn_valid(t->output.paddr >> PAGE_SHIFT)) {
+ base_off = page_address(pfn_to_page(t->output.paddr >> PAGE_SHIFT));
+ base_off += t->output.paddr & ((1 << PAGE_SHIFT) - 1);
+ } else {
+ base_off = (char *)ioremap_nocache(t->output.paddr,
+ t->output.width * t->output.height *
+ fmt_to_bpp(t->output.format)/8);
+ }
+ if (base_off == NULL) {
+ dev_err(t->dev, "ERR[0x%p]Failed get virtual address\n", t);
+ mutex_unlock(lock);
+ return;
+ }
+
+ /* UP stripe or UP&LEFT stripe */
+ if ((stripe_mode == UP_STRIPE) ||
+ (stripe_mode == (UP_STRIPE | LEFT_STRIPE))) {
+ if (!parent->buf0filled) {
+ offset_addr = t->set.o_off +
+ t->set.sp_setting.ud_split_line*t->set.ostride;
+ dmac_flush_range(base_off + offset_addr,
+ base_off + offset_addr + vdi_size);
+ outer_flush_range(t->output.paddr + offset_addr,
+ t->output.paddr + offset_addr + vdi_size);
+
+ for (i = 0; i < vdi_save_lines; i++)
+ memcpy(parent->vditmpbuf[0] + i*line_size,
+ base_off + offset_addr +
+ i*t->set.ostride, line_size);
+ parent->buf0filled = true;
+ } else {
+ offset_addr = t->set.o_off + (t->output.crop.h -
+ vdi_save_lines) * t->set.ostride;
+ for (i = 0; i < vdi_save_lines; i++)
+ memcpy(base_off + offset_addr + i*t->set.ostride,
+ parent->vditmpbuf[0] + i*line_size, line_size);
+
+ dmac_flush_range(base_off + offset_addr,
+ base_off + offset_addr + i*t->set.ostride);
+ outer_flush_range(t->output.paddr + offset_addr,
+ t->output.paddr + offset_addr + i*t->set.ostride);
+ parent->buf0filled = false;
+ }
+ }
+ /*Down stripe or Down&Left stripe*/
+ else if ((stripe_mode == DOWN_STRIPE) ||
+ (stripe_mode == (DOWN_STRIPE | LEFT_STRIPE))) {
+ if (!parent->buf0filled) {
+ offset_addr = t->set.o_off + vdi_save_lines*t->set.ostride;
+ dmac_flush_range(base_off + offset_addr,
+ base_off + offset_addr + vdi_size);
+ outer_flush_range(t->output.paddr + offset_addr,
+ t->output.paddr + offset_addr + vdi_size);
+
+ for (i = 0; i < vdi_save_lines; i++)
+ memcpy(parent->vditmpbuf[0] + i*line_size,
+ base_off + offset_addr + i*t->set.ostride,
+ line_size);
+ parent->buf0filled = true;
+ } else {
+ offset_addr = t->set.o_off;
+ for (i = 0; i < vdi_save_lines; i++)
+ memcpy(base_off + offset_addr + i*t->set.ostride,
+ parent->vditmpbuf[0] + i*line_size,
+ line_size);
+
+ dmac_flush_range(base_off + offset_addr,
+ base_off + offset_addr + i*t->set.ostride);
+ outer_flush_range(t->output.paddr + offset_addr,
+ t->output.paddr + offset_addr + i*t->set.ostride);
+ parent->buf0filled = false;
+ }
+ }
+ /*Up&Right stripe*/
+ else if (stripe_mode == (UP_STRIPE | RIGHT_STRIPE)) {
+ if (!parent->buf1filled) {
+ offset_addr = t->set.o_off +
+ t->set.sp_setting.ud_split_line*t->set.ostride;
+ dmac_flush_range(base_off + offset_addr,
+ base_off + offset_addr + vdi_size);
+ outer_flush_range(t->output.paddr + offset_addr,
+ t->output.paddr + offset_addr + vdi_size);
+
+ for (i = 0; i < vdi_save_lines; i++)
+ memcpy(parent->vditmpbuf[1] + i*line_size,
+ base_off + offset_addr + i*t->set.ostride,
+ line_size);
+ parent->buf1filled = true;
+ } else {
+ offset_addr = t->set.o_off +
+ (t->output.crop.h - vdi_save_lines)*t->set.ostride;
+ for (i = 0; i < vdi_save_lines; i++)
+ memcpy(base_off + offset_addr + i*t->set.ostride,
+ parent->vditmpbuf[1] + i*line_size,
+ line_size);
+
+ dmac_flush_range(base_off + offset_addr,
+ base_off + offset_addr + i*t->set.ostride);
+ outer_flush_range(t->output.paddr + offset_addr,
+ t->output.paddr + offset_addr + i*t->set.ostride);
+ parent->buf1filled = false;
+ }
+ }
+ /*Down stripe or Down&Right stript*/
+ else if (stripe_mode == (DOWN_STRIPE | RIGHT_STRIPE)) {
+ if (!parent->buf1filled) {
+ offset_addr = t->set.o_off + vdi_save_lines*t->set.ostride;
+ dmac_flush_range(base_off + offset_addr,
+ base_off + offset_addr + vdi_save_lines*t->set.ostride);
+ outer_flush_range(t->output.paddr + offset_addr,
+ t->output.paddr + offset_addr + vdi_save_lines*t->set.ostride);
+
+ for (i = 0; i < vdi_save_lines; i++)
+ memcpy(parent->vditmpbuf[1] + i*line_size,
+ base_off + offset_addr + i*t->set.ostride,
+ line_size);
+ parent->buf1filled = true;
+ } else {
+ offset_addr = t->set.o_off;
+ for (i = 0; i < vdi_save_lines; i++)
+ memcpy(base_off + offset_addr + i*t->set.ostride,
+ parent->vditmpbuf[1] + i*line_size,
+ line_size);
+
+ dmac_flush_range(base_off + offset_addr,
+ base_off + offset_addr + vdi_save_lines*t->set.ostride);
+ outer_flush_range(t->output.paddr + offset_addr,
+ t->output.paddr + offset_addr + vdi_save_lines*t->set.ostride);
+ parent->buf1filled = false;
+ }
+ }
+ if (!pfn_valid(t->output.paddr >> PAGE_SHIFT))
+ iounmap(base_off);
+ mutex_unlock(lock);
+}
+
+static void do_task_release(struct ipu_task_entry *t, int fail)
+{
+ int ret;
+ struct ipu_soc *ipu = t->ipu;
+
+ if (t->input.deinterlace.enable && !fail &&
+ (t->task_no & (UP_STRIPE | DOWN_STRIPE)))
+ vdi_split_process(ipu, t);
+
+ ipu_free_irq(ipu, t->irq, t);
+
+ if (t->vdoa_dma.vaddr)
+ dma_free_coherent(t->dev,
+ t->vdoa_dma.size,
+ t->vdoa_dma.vaddr,
+ t->vdoa_dma.paddr);
+
+ if (only_ic(t->set.mode)) {
+ ret = ipu_disable_channel(ipu, t->set.ic_chan, true);
+ CHECK_RETCODE_CONT(ret < 0, "ipu_disable_ch only_ic",
+ STATE_DISABLE_CHAN_FAIL, ret);
+ if (deinterlace_3_field(t)) {
+ ret = ipu_disable_channel(ipu, t->set.vdi_ic_p_chan,
+ true);
+ CHECK_RETCODE_CONT(ret < 0, "ipu_disable_ch only_ic_p",
+ STATE_DISABLE_CHAN_FAIL, ret);
+ ret = ipu_disable_channel(ipu, t->set.vdi_ic_n_chan,
+ true);
+ CHECK_RETCODE_CONT(ret < 0, "ipu_disable_ch only_ic_n",
+ STATE_DISABLE_CHAN_FAIL, ret);
+ }
+ } else if (only_rot(t->set.mode)) {
+ ret = ipu_disable_channel(ipu, t->set.rot_chan, true);
+ CHECK_RETCODE_CONT(ret < 0, "ipu_disable_ch only_rot",
+ STATE_DISABLE_CHAN_FAIL, ret);
+ } else if (ic_and_rot(t->set.mode)) {
+ ret = ipu_unlink_channels(ipu, t->set.ic_chan, t->set.rot_chan);
+ CHECK_RETCODE_CONT(ret < 0, "ipu_unlink_ch",
+ STATE_UNLINK_CHAN_FAIL, ret);
+ ret = ipu_disable_channel(ipu, t->set.rot_chan, true);
+ CHECK_RETCODE_CONT(ret < 0, "ipu_disable_ch ic_and_rot-rot",
+ STATE_DISABLE_CHAN_FAIL, ret);
+ ret = ipu_disable_channel(ipu, t->set.ic_chan, true);
+ CHECK_RETCODE_CONT(ret < 0, "ipu_disable_ch ic_and_rot-ic",
+ STATE_DISABLE_CHAN_FAIL, ret);
+ if (deinterlace_3_field(t)) {
+ ret = ipu_disable_channel(ipu, t->set.vdi_ic_p_chan,
+ true);
+ CHECK_RETCODE_CONT(ret < 0, "ipu_disable_ch icrot-ic-p",
+ STATE_DISABLE_CHAN_FAIL, ret);
+ ret = ipu_disable_channel(ipu, t->set.vdi_ic_n_chan,
+ true);
+ CHECK_RETCODE_CONT(ret < 0, "ipu_disable_ch icrot-ic-n",
+ STATE_DISABLE_CHAN_FAIL, ret);
+ }
+ }
+
+ if (only_ic(t->set.mode))
+ uninit_ic(ipu, t);
+ else if (only_rot(t->set.mode))
+ uninit_rot(ipu, t);
+ else if (ic_and_rot(t->set.mode)) {
+ uninit_ic(ipu, t);
+ uninit_rot(ipu, t);
+ }
+
+ t->state = STATE_OK;
+ CHECK_PERF(&t->ts_rel);
+ return;
+}
+
+static void do_task_vdoa_only(struct ipu_task_entry *t)
+{
+ int ret;
+
+ ret = init_tiled_ch_bufs(NULL, t);
+ CHECK_RETCODE(ret < 0, "do_vdoa_only", STATE_ERR, out, ret);
+ ret = vdoa_start(t->vdoa_handle, VDOA_DEF_TIMEOUT_MS);
+ vdoa_stop(t->vdoa_handle);
+ CHECK_RETCODE(ret < 0, "vdoa_wait4complete, do_vdoa_only",
+ STATE_VDOA_IRQ_TIMEOUT, out, ret);
+
+ t->state = STATE_OK;
+out:
+ return;
+}
+
+static void do_task(struct ipu_task_entry *t)
+{
+ int r_size;
+ int irq;
+ int ret;
+ uint32_t busy;
+ struct ipu_soc *ipu = t->ipu;
+
+ CHECK_PERF(&t->ts_dotask);
+
+ if (!ipu) {
+ t->state = STATE_NO_IPU;
+ return;
+ }
+
+ init_completion(&t->irq_comp);
+ dev_dbg(ipu->dev, "[0x%p]Do task no:0x%x: id %d\n", (void *)t,
+ t->task_no, t->task_id);
+ dump_task_info(t);
+
+ if (t->set.task & IC_PP) {
+ t->set.ic_chan = MEM_PP_MEM;
+ dev_dbg(ipu->dev, "[0x%p]ic channel MEM_PP_MEM\n", (void *)t);
+ } else if (t->set.task & IC_VF) {
+ t->set.ic_chan = MEM_PRP_VF_MEM;
+ dev_dbg(ipu->dev, "[0x%p]ic channel MEM_PRP_VF_MEM\n", (void *)t);
+ } else if (t->set.task & VDI_VF) {
+ if (t->set.mode & VDOA_BAND_MODE) {
+ t->set.ic_chan = MEM_VDI_MEM;
+ if (deinterlace_3_field(t)) {
+ t->set.vdi_ic_p_chan = MEM_VDI_MEM_P;
+ t->set.vdi_ic_n_chan = MEM_VDI_MEM_N;
+ }
+ dev_dbg(ipu->dev, "[0x%p]ic ch MEM_VDI_MEM\n",
+ (void *)t);
+ } else {
+ t->set.ic_chan = MEM_VDI_PRP_VF_MEM;
+ if (deinterlace_3_field(t)) {
+ t->set.vdi_ic_p_chan = MEM_VDI_PRP_VF_MEM_P;
+ t->set.vdi_ic_n_chan = MEM_VDI_PRP_VF_MEM_N;
+ }
+ dev_dbg(ipu->dev,
+ "[0x%p]ic ch MEM_VDI_PRP_VF_MEM\n", t);
+ }
+ }
+
+ if (t->set.task & ROT_PP) {
+ t->set.rot_chan = MEM_ROT_PP_MEM;
+ dev_dbg(ipu->dev, "[0x%p]rot channel MEM_ROT_PP_MEM\n", (void *)t);
+ } else if (t->set.task & ROT_VF) {
+ t->set.rot_chan = MEM_ROT_VF_MEM;
+ dev_dbg(ipu->dev, "[0x%p]rot channel MEM_ROT_VF_MEM\n", (void *)t);
+ }
+
+ if (t->task_id == IPU_TASK_ID_VF)
+ busy = ic_vf_pp_is_busy(ipu, true);
+ else if (t->task_id == IPU_TASK_ID_PP)
+ busy = ic_vf_pp_is_busy(ipu, false);
+ else {
+ dev_err(ipu->dev, "ERR[no:0x%x]ipu task_id:%d invalid!\n",
+ t->task_no, t->task_id);
+ return;
+ }
+ if (busy) {
+ dev_err(ipu->dev, "ERR[0x%p-no:0x%x]ipu task_id:%d busy!\n",
+ (void *)t, t->task_no, t->task_id);
+ t->state = STATE_IPU_BUSY;
+ return;
+ }
+
+ irq = get_irq(t);
+ if (irq < 0) {
+ t->state = STATE_NO_IRQ;
+ return;
+ }
+ t->irq = irq;
+
+ /* channel setup */
+ if (only_ic(t->set.mode)) {
+ dev_dbg(t->dev, "[0x%p]only ic mode\n", (void *)t);
+ ret = init_ic(ipu, t);
+ CHECK_RETCODE(ret < 0, "init_ic only_ic",
+ t->state, chan_setup, ret);
+ } else if (only_rot(t->set.mode)) {
+ dev_dbg(t->dev, "[0x%p]only rot mode\n", (void *)t);
+ ret = init_rot(ipu, t);
+ CHECK_RETCODE(ret < 0, "init_rot only_rot",
+ t->state, chan_setup, ret);
+ } else if (ic_and_rot(t->set.mode)) {
+ int rot_idx = (t->task_id == IPU_TASK_ID_VF) ? 0 : 1;
+
+ dev_dbg(t->dev, "[0x%p]ic + rot mode\n", (void *)t);
+ t->set.r_fmt = t->output.format;
+ if (t->output.rotate >= IPU_ROTATE_90_RIGHT) {
+ t->set.r_width = t->output.crop.h;
+ t->set.r_height = t->output.crop.w;
+ } else {
+ t->set.r_width = t->output.crop.w;
+ t->set.r_height = t->output.crop.h;
+ }
+ t->set.r_stride = t->set.r_width *
+ bytes_per_pixel(t->set.r_fmt);
+ r_size = PAGE_ALIGN(t->set.r_width * t->set.r_height
+ * fmt_to_bpp(t->set.r_fmt)/8);
+
+ if (r_size > ipu->rot_dma[rot_idx].size) {
+ dev_dbg(t->dev, "[0x%p]realloc rot buffer\n", (void *)t);
+
+ if (ipu->rot_dma[rot_idx].vaddr)
+ dma_free_coherent(t->dev,
+ ipu->rot_dma[rot_idx].size,
+ ipu->rot_dma[rot_idx].vaddr,
+ ipu->rot_dma[rot_idx].paddr);
+
+ ipu->rot_dma[rot_idx].size = r_size;
+ ipu->rot_dma[rot_idx].vaddr = dma_alloc_coherent(t->dev,
+ r_size,
+ &ipu->rot_dma[rot_idx].paddr,
+ GFP_DMA | GFP_KERNEL);
+ CHECK_RETCODE(ipu->rot_dma[rot_idx].vaddr == NULL,
+ "ic_and_rot", STATE_SYS_NO_MEM,
+ chan_setup, -ENOMEM);
+ }
+ t->set.r_paddr = ipu->rot_dma[rot_idx].paddr;
+
+ dev_dbg(t->dev, "[0x%p]rotation:\n", (void *)t);
+ dev_dbg(t->dev, "[0x%p]\tformat = 0x%x\n", (void *)t, t->set.r_fmt);
+ dev_dbg(t->dev, "[0x%p]\twidth = %d\n", (void *)t, t->set.r_width);
+ dev_dbg(t->dev, "[0x%p]\theight = %d\n", (void *)t, t->set.r_height);
+ dev_dbg(t->dev, "[0x%p]\tpaddr = 0x%x\n", (void *)t, t->set.r_paddr);
+ dev_dbg(t->dev, "[0x%p]\trstride = %d\n", (void *)t, t->set.r_stride);
+
+ ret = init_ic(ipu, t);
+ CHECK_RETCODE(ret < 0, "init_ic ic_and_rot",
+ t->state, chan_setup, ret);
+ ret = init_rot(ipu, t);
+ CHECK_RETCODE(ret < 0, "init_rot ic_and_rot",
+ t->state, chan_setup, ret);
+ ret = ipu_link_channels(ipu, t->set.ic_chan,
+ t->set.rot_chan);
+ CHECK_RETCODE(ret < 0, "ipu_link_ch ic_and_rot",
+ STATE_LINK_CHAN_FAIL, chan_setup, ret);
+ } else {
+ dev_err(t->dev, "ERR [0x%p]do task: should not be here\n", t);
+ t->state = STATE_ERR;
+ return;
+ }
+
+ ret = ipu_request_irq(ipu, irq, task_irq_handler, 0, NULL, t);
+ CHECK_RETCODE(ret < 0, "ipu_req_irq",
+ STATE_IRQ_FAIL, chan_setup, ret);
+
+ /* enable/start channel */
+ if (only_ic(t->set.mode)) {
+ ret = ipu_enable_channel(ipu, t->set.ic_chan);
+ CHECK_RETCODE(ret < 0, "ipu_enable_ch only_ic",
+ STATE_ENABLE_CHAN_FAIL, chan_en, ret);
+ if (deinterlace_3_field(t)) {
+ ret = ipu_enable_channel(ipu, t->set.vdi_ic_p_chan);
+ CHECK_RETCODE(ret < 0, "ipu_enable_ch only_ic_p",
+ STATE_ENABLE_CHAN_FAIL, chan_en, ret);
+ ret = ipu_enable_channel(ipu, t->set.vdi_ic_n_chan);
+ CHECK_RETCODE(ret < 0, "ipu_enable_ch only_ic_n",
+ STATE_ENABLE_CHAN_FAIL, chan_en, ret);
+ }
+
+ ret = ipu_select_buffer(ipu, t->set.ic_chan, IPU_OUTPUT_BUFFER,
+ 0);
+ CHECK_RETCODE(ret < 0, "ipu_sel_buf only_ic",
+ STATE_SEL_BUF_FAIL, chan_buf, ret);
+ if (t->overlay_en) {
+ ret = ipu_select_buffer(ipu, t->set.ic_chan,
+ IPU_GRAPH_IN_BUFFER, 0);
+ CHECK_RETCODE(ret < 0, "ipu_sel_buf only_ic_g",
+ STATE_SEL_BUF_FAIL, chan_buf, ret);
+ if (t->overlay.alpha.mode == IPU_ALPHA_MODE_LOCAL) {
+ ret = ipu_select_buffer(ipu, t->set.ic_chan,
+ IPU_ALPHA_IN_BUFFER, 0);
+ CHECK_RETCODE(ret < 0, "ipu_sel_buf only_ic_a",
+ STATE_SEL_BUF_FAIL, chan_buf,
+ ret);
+ }
+ }
+ if (!(t->set.mode & VDOA_BAND_MODE)) {
+ if (deinterlace_3_field(t))
+ ipu_select_multi_vdi_buffer(ipu, 0);
+ else {
+ ret = ipu_select_buffer(ipu, t->set.ic_chan,
+ IPU_INPUT_BUFFER, 0);
+ CHECK_RETCODE(ret < 0, "ipu_sel_buf only_ic_i",
+ STATE_SEL_BUF_FAIL, chan_buf, ret);
+ }
+ }
+ } else if (only_rot(t->set.mode)) {
+ ret = ipu_enable_channel(ipu, t->set.rot_chan);
+ CHECK_RETCODE(ret < 0, "ipu_enable_ch only_rot",
+ STATE_ENABLE_CHAN_FAIL, chan_en, ret);
+ ret = ipu_select_buffer(ipu, t->set.rot_chan,
+ IPU_OUTPUT_BUFFER, 0);
+ CHECK_RETCODE(ret < 0, "ipu_sel_buf only_rot_o",
+ STATE_SEL_BUF_FAIL, chan_buf, ret);
+ ret = ipu_select_buffer(ipu, t->set.rot_chan,
+ IPU_INPUT_BUFFER, 0);
+ CHECK_RETCODE(ret < 0, "ipu_sel_buf only_rot_i",
+ STATE_SEL_BUF_FAIL, chan_buf, ret);
+ } else if (ic_and_rot(t->set.mode)) {
+ ret = ipu_enable_channel(ipu, t->set.rot_chan);
+ CHECK_RETCODE(ret < 0, "ipu_enable_ch ic_and_rot-rot",
+ STATE_ENABLE_CHAN_FAIL, chan_en, ret);
+ ret = ipu_enable_channel(ipu, t->set.ic_chan);
+ CHECK_RETCODE(ret < 0, "ipu_enable_ch ic_and_rot-ic",
+ STATE_ENABLE_CHAN_FAIL, chan_en, ret);
+ if (deinterlace_3_field(t)) {
+ ret = ipu_enable_channel(ipu, t->set.vdi_ic_p_chan);
+ CHECK_RETCODE(ret < 0, "ipu_enable_ch ic_and_rot-p",
+ STATE_ENABLE_CHAN_FAIL, chan_en, ret);
+ ret = ipu_enable_channel(ipu, t->set.vdi_ic_n_chan);
+ CHECK_RETCODE(ret < 0, "ipu_enable_ch ic_and_rot-n",
+ STATE_ENABLE_CHAN_FAIL, chan_en, ret);
+ }
+
+ ret = ipu_select_buffer(ipu, t->set.rot_chan,
+ IPU_OUTPUT_BUFFER, 0);
+ CHECK_RETCODE(ret < 0, "ipu_sel_buf ic_and_rot-rot-o",
+ STATE_SEL_BUF_FAIL, chan_buf, ret);
+ if (t->overlay_en) {
+ ret = ipu_select_buffer(ipu, t->set.ic_chan,
+ IPU_GRAPH_IN_BUFFER, 0);
+ CHECK_RETCODE(ret < 0, "ipu_sel_buf ic_and_rot-ic-g",
+ STATE_SEL_BUF_FAIL, chan_buf, ret);
+ if (t->overlay.alpha.mode == IPU_ALPHA_MODE_LOCAL) {
+ ret = ipu_select_buffer(ipu, t->set.ic_chan,
+ IPU_ALPHA_IN_BUFFER, 0);
+ CHECK_RETCODE(ret < 0, "ipu_sel_buf icrot-ic-a",
+ STATE_SEL_BUF_FAIL,
+ chan_buf, ret);
+ }
+ }
+ ret = ipu_select_buffer(ipu, t->set.ic_chan,
+ IPU_OUTPUT_BUFFER, 0);
+ CHECK_RETCODE(ret < 0, "ipu_sel_buf ic_and_rot-ic-o",
+ STATE_SEL_BUF_FAIL, chan_buf, ret);
+ if (deinterlace_3_field(t))
+ ipu_select_multi_vdi_buffer(ipu, 0);
+ else {
+ ret = ipu_select_buffer(ipu, t->set.ic_chan,
+ IPU_INPUT_BUFFER, 0);
+ CHECK_RETCODE(ret < 0, "ipu_sel_buf ic_and_rot-ic-i",
+ STATE_SEL_BUF_FAIL, chan_buf, ret);
+ }
+ }
+
+ if (need_split(t))
+ t->state = STATE_IN_PROGRESS;
+
+ if (t->set.mode & VDOA_BAND_MODE) {
+ ret = vdoa_start(t->vdoa_handle, VDOA_DEF_TIMEOUT_MS);
+ CHECK_RETCODE(ret < 0, "vdoa_wait4complete, do_vdoa_band",
+ STATE_VDOA_IRQ_TIMEOUT, chan_rel, ret);
+ }
+
+ CHECK_PERF(&t->ts_waitirq);
+ ret = wait_for_completion_timeout(&t->irq_comp,
+ msecs_to_jiffies(t->timeout - DEF_DELAY_MS));
+ CHECK_PERF(&t->ts_wakeup);
+ CHECK_RETCODE(ret == 0, "wait_for_comp_timeout",
+ STATE_IRQ_TIMEOUT, chan_rel, ret);
+ dev_dbg(t->dev, "[0x%p] no-0x%x ipu irq done!", t, t->task_no);
+
+chan_rel:
+chan_buf:
+chan_en:
+chan_setup:
+ if (t->set.mode & VDOA_BAND_MODE)
+ vdoa_stop(t->vdoa_handle);
+ do_task_release(t, t->state >= STATE_ERR);
+ return;
+}
+
+static void do_task_vdoa_vdi(struct ipu_task_entry *t)
+{
+ int i;
+ int ret;
+ u32 stripe_width;
+
+ /* FIXME: crop mode not support now */
+ stripe_width = t->input.width >> 1;
+ t->input.crop.pos.x = 0;
+ t->input.crop.pos.y = 0;
+ t->input.crop.w = stripe_width;
+ t->input.crop.h = t->input.height;
+ t->output.crop.w = stripe_width;
+ t->output.crop.h = t->input.height;
+
+ for (i = 0; i < 2; i++) {
+ t->input.crop.pos.x = t->input.crop.pos.x + i * stripe_width;
+ t->output.crop.pos.x = t->output.crop.pos.x + i * stripe_width;
+ /* check input */
+ ret = set_crop(&t->input.crop, t->input.width, t->input.height,
+ t->input.format);
+ if (ret < 0) {
+ ret = STATE_ERR;
+ goto done;
+ } else
+ update_offset(t->input.format,
+ t->input.width, t->input.height,
+ t->input.crop.pos.x,
+ t->input.crop.pos.y,
+ &t->set.i_off, &t->set.i_uoff,
+ &t->set.i_voff, &t->set.istride);
+ dev_dbg(t->dev, "i_off:0x%x, i_uoff:0x%x, istride:%d.\n",
+ t->set.i_off, t->set.i_uoff, t->set.istride);
+ /* check output */
+ ret = set_crop(&t->output.crop, t->input.width,
+ t->output.height, t->output.format);
+ if (ret < 0) {
+ ret = STATE_ERR;
+ goto done;
+ } else
+ update_offset(t->output.format,
+ t->output.width, t->output.height,
+ t->output.crop.pos.x,
+ t->output.crop.pos.y,
+ &t->set.o_off, &t->set.o_uoff,
+ &t->set.o_voff, &t->set.ostride);
+
+ dev_dbg(t->dev, "o_off:0x%x, o_uoff:0x%x, ostride:%d.\n",
+ t->set.o_off, t->set.o_uoff, t->set.ostride);
+
+ do_task(t);
+ }
+
+ return;
+done:
+ dev_err(t->dev, "ERR %s set_crop.\n", __func__);
+ t->state = ret;
+ return;
+}
+
+static void get_res_do_task(struct ipu_task_entry *t)
+{
+ uint32_t found;
+ uint32_t split_child;
+ struct mutex *lock;
+
+ found = get_vdoa_ipu_res(t);
+ if (!found) {
+ dev_err(t->dev, "ERR:[0x%p] no-0x%x can not get res\n",
+ t, t->task_no);
+ return;
+ } else {
+ if (t->set.task & VDOA_ONLY)
+ do_task_vdoa_only(t);
+ else if ((IPU_PIX_FMT_TILED_NV12F == t->input.format) &&
+ (t->set.mode & VDOA_BAND_MODE) &&
+ (t->input.crop.w >
+ soc_max_vdi_in_width(t->ipu)))
+ do_task_vdoa_vdi(t);
+ else
+ do_task(t);
+ put_vdoa_ipu_res(t, 0);
+ }
+ if (t->state != STATE_OK) {
+ dev_err(t->dev, "ERR:[0x%p] no-0x%x state: %s\n",
+ t, t->task_no, state_msg[t->state].msg);
+ }
+
+ split_child = need_split(t) && t->parent;
+ if (split_child) {
+ lock = &t->parent->split_lock;
+ mutex_lock(lock);
+ t->split_done = 1;
+ mutex_unlock(lock);
+ wake_up(&t->parent->split_waitq);
+ }
+
+ return;
+}
+
+static void wait_split_task_complete(struct ipu_task_entry *parent,
+ struct ipu_split_task *sp_task, uint32_t size)
+{
+ struct ipu_task_entry *tsk = NULL;
+ int ret = 0, rc;
+ int j, idx = -1;
+ unsigned long flags;
+ struct mutex *lock = &parent->split_lock;
+ int k, busy_vf, busy_pp;
+ struct ipu_soc *ipu;
+ DECLARE_PERF_VAR;
+
+ for (j = 0; j < size; j++) {
+ rc = wait_event_timeout(
+ parent->split_waitq,
+ sp_task_check_done(sp_task, parent, size, &idx),
+ msecs_to_jiffies(parent->timeout - DEF_DELAY_MS));
+ if (!rc) {
+ dev_err(parent->dev,
+ "ERR:[0x%p] no-0x%x, split_task timeout,j:%d,"
+ "size:%d.\n",
+ parent, parent->task_no, j, size);
+ ret = -ETIMEDOUT;
+ goto out;
+ } else {
+ if (idx < 0) {
+ dev_err(parent->dev,
+ "ERR:[0x%p] no-0x%x, invalid task idx:%d\n",
+ parent, parent->task_no, idx);
+ continue;
+ }
+ tsk = sp_task[idx].child_task;
+ mutex_lock(lock);
+ if (!tsk->split_done || !tsk->ipu)
+ dev_err(tsk->dev,
+ "ERR:no-0x%x,split not done:%d/null ipu:0x%p\n",
+ tsk->task_no, tsk->split_done, tsk->ipu);
+ tsk->split_done = 0;
+ mutex_unlock(lock);
+
+ dev_dbg(tsk->dev,
+ "[0x%p] no-0x%x sp_tsk[%d] done,state:%d.\n",
+ tsk, tsk->task_no, idx, tsk->state);
+ #ifdef DBG_IPU_PERF
+ CHECK_PERF(&tsk->ts_rel);
+ PRINT_TASK_STATISTICS;
+ #endif
+ }
+ }
+
+out:
+ if (ret == -ETIMEDOUT) {
+ /* debug */
+ for (k = 0; k < max_ipu_no; k++) {
+ ipu = ipu_get_soc(k);
+ if (IS_ERR(ipu)) {
+ dev_err(parent->dev, "no:0x%x, null ipu:%d\n",
+ parent->task_no, k);
+ } else {
+ busy_vf = ic_vf_pp_is_busy(ipu, true);
+ busy_pp = ic_vf_pp_is_busy(ipu, false);
+ dev_err(parent->dev,
+ "ERR:ipu[%d] busy_vf:%d, busy_pp:%d.\n",
+ k, busy_vf, busy_pp);
+ }
+ }
+ for (k = 0; k < size; k++) {
+ tsk = sp_task[k].child_task;
+ if (!tsk)
+ continue;
+ dev_err(parent->dev,
+ "ERR: sp_task[%d][0x%p] no-0x%x done:%d,"
+ "state:%s,on_list:%d, ipu:0x%p,timeout!\n",
+ k, tsk, tsk->task_no, tsk->split_done,
+ state_msg[tsk->state].msg, tsk->task_in_list,
+ tsk->ipu);
+ }
+ }
+
+ for (j = 0; j < size; j++) {
+ tsk = sp_task[j].child_task;
+ if (!tsk)
+ continue;
+ spin_lock_irqsave(&ipu_task_list_lock, flags);
+ if (tsk->task_in_list) {
+ list_del(&tsk->node);
+ tsk->task_in_list = 0;
+ dev_dbg(tsk->dev,
+ "[0x%p] no-0x%x,id:%d sp_tsk timeout list_del.\n",
+ tsk, tsk->task_no, tsk->task_id);
+ }
+ spin_unlock_irqrestore(&ipu_task_list_lock, flags);
+ if (!tsk->ipu)
+ continue;
+ if (tsk->state != STATE_OK) {
+ dev_err(tsk->dev,
+ "ERR:[0x%p] no-0x%x,id:%d, sp_tsk state: %s\n",
+ tsk, tsk->task_no, tsk->task_id,
+ state_msg[tsk->state].msg);
+ }
+ kref_put(&tsk->refcount, task_mem_free);
+ }
+
+ kfree(parent->vditmpbuf[0]);
+ kfree(parent->vditmpbuf[1]);
+
+ if (ret < 0)
+ parent->state = STATE_TIMEOUT;
+ else
+ parent->state = STATE_OK;
+ return;
+}
+
+static inline int find_task(struct ipu_task_entry **t, int thread_id)
+{
+ int found;
+ unsigned long flags;
+ struct ipu_task_entry *tsk;
+ struct list_head *task_list = &ipu_task_list;
+
+ *t = NULL;
+ spin_lock_irqsave(&ipu_task_list_lock, flags);
+ found = !list_empty(task_list);
+ if (found) {
+ tsk = list_first_entry(task_list, struct ipu_task_entry, node);
+ if (tsk->task_in_list) {
+ list_del(&tsk->node);
+ tsk->task_in_list = 0;
+ *t = tsk;
+ kref_get(&tsk->refcount);
+ dev_dbg(tsk->dev,
+ "thread_id:%d,[0x%p] task_no:0x%x,mode:0x%x list_del\n",
+ thread_id, tsk, tsk->task_no, tsk->set.mode);
+ } else
+ dev_err(tsk->dev,
+ "thread_id:%d,task_no:0x%x,mode:0x%x not on list_del\n",
+ thread_id, tsk->task_no, tsk->set.mode);
+ }
+ spin_unlock_irqrestore(&ipu_task_list_lock, flags);
+
+ return found;
+}
+
+static int ipu_task_thread(void *argv)
+{
+ struct ipu_task_entry *tsk;
+ struct ipu_task_entry *sp_tsk0;
+ struct ipu_split_task sp_task[4];
+ /* priority lower than irq_thread */
+ const struct sched_param param = {
+ .sched_priority = MAX_USER_RT_PRIO/2 - 1,
+ };
+ int ret;
+ int curr_thread_id;
+ uint32_t size;
+ unsigned long flags;
+ unsigned int cpu;
+ struct cpumask cpu_mask;
+ struct ipu_thread_data *data = (struct ipu_thread_data *)argv;
+
+ thread_id++;
+ curr_thread_id = thread_id;
+ sched_setscheduler(current, SCHED_FIFO, &param);
+
+ if (!data->is_vdoa) {
+ cpu = cpumask_first(cpu_online_mask);
+ cpumask_set_cpu(cpu, &cpu_mask);
+ ret = sched_setaffinity(data->ipu->thread[data->id]->pid,
+ &cpu_mask);
+ if (ret < 0) {
+ pr_err("%s: sched_setaffinity fail:%d.\n", __func__, ret);
+ }
+ pr_debug("%s: sched_setaffinity cpu:%d.\n", __func__, cpu);
+ }
+
+ while (!kthread_should_stop()) {
+ int split_fail = 0;
+ int split_parent;
+ int split_child;
+
+ wait_event_interruptible(thread_waitq, find_task(&tsk, curr_thread_id));
+
+ if (!tsk) {
+ pr_err("thread:%d can not find task.\n",
+ curr_thread_id);
+ continue;
+ }
+
+ /* note: other threads run split child task */
+ split_parent = need_split(tsk) && !tsk->parent;
+ split_child = need_split(tsk) && tsk->parent;
+ if (split_parent) {
+ if ((tsk->set.split_mode == RL_SPLIT) ||
+ (tsk->set.split_mode == UD_SPLIT))
+ size = 2;
+ else
+ size = 4;
+ ret = queue_split_task(tsk, sp_task, size);
+ if (ret < 0) {
+ split_fail = 1;
+ } else {
+ struct list_head *pos;
+
+ spin_lock_irqsave(&ipu_task_list_lock, flags);
+
+ sp_tsk0 = list_first_entry(&tsk->split_list,
+ struct ipu_task_entry, node);
+ list_del(&sp_tsk0->node);
+
+ list_for_each(pos, &tsk->split_list) {
+ struct ipu_task_entry *tmp;
+
+ tmp = list_entry(pos,
+ struct ipu_task_entry, node);
+ tmp->task_in_list = 1;
+ dev_dbg(tmp->dev,
+ "[0x%p] no-0x%x,id:%d sp_tsk "
+ "add_to_list.\n", tmp,
+ tmp->task_no, tmp->task_id);
+ }
+ /* add to global list */
+ list_splice(&tsk->split_list, &ipu_task_list);
+
+ spin_unlock_irqrestore(&ipu_task_list_lock,
+ flags);
+ /* let the parent thread do the first sp_task */
+ /* FIXME: ensure the correct sequence for split
+ 4size: 5/6->9/a*/
+ wake_up_interruptible(&thread_waitq);
+ get_res_do_task(sp_tsk0);
+ dev_dbg(sp_tsk0->dev,
+ "thread:%d complete tsk no:0x%x.\n",
+ curr_thread_id, sp_tsk0->task_no);
+ ret = atomic_read(&req_cnt);
+ if (ret > 0) {
+ wake_up(&res_waitq);
+ dev_dbg(sp_tsk0->dev,
+ "sp_tsk0 sche thread:%d no:0x%x,"
+ "req_cnt:%d\n", curr_thread_id,
+ sp_tsk0->task_no, ret);
+ /* For other threads to get_res */
+ schedule();
+ }
+ }
+ } else
+ get_res_do_task(tsk);
+
+ /* wait for all 4 sp_task finished here or timeout
+ and then release all resources */
+ if (split_parent && !split_fail)
+ wait_split_task_complete(tsk, sp_task, size);
+
+ if (!split_child) {
+ atomic_inc(&tsk->done);
+ wake_up(&tsk->task_waitq);
+ }
+
+ dev_dbg(tsk->dev, "thread:%d complete tsk no:0x%x-[0x%p].\n",
+ curr_thread_id, tsk->task_no, tsk);
+ ret = atomic_read(&req_cnt);
+ if (ret > 0) {
+ wake_up(&res_waitq);
+ dev_dbg(tsk->dev, "sche thread:%d no:0x%x,req_cnt:%d\n",
+ curr_thread_id, tsk->task_no, ret);
+ /* note: give cpu to other threads to get_res */
+ schedule();
+ }
+
+ kref_put(&tsk->refcount, task_mem_free);
+ }
+
+ pr_info("ERR %s exit.\n", __func__);
+ return 0;
+}
+
+int ipu_check_task(struct ipu_task *task)
+{
+ struct ipu_task_entry *tsk;
+ int ret = 0;
+
+ tsk = create_task_entry(task);
+ if (IS_ERR(tsk))
+ return PTR_ERR(tsk);
+
+ ret = check_task(tsk);
+
+ task->input = tsk->input;
+ task->output = tsk->output;
+ task->overlay = tsk->overlay;
+ dump_task_info(tsk);
+
+ kref_put(&tsk->refcount, task_mem_free);
+ if (ret != 0)
+ pr_debug("%s ret:%d.\n", __func__, ret);
+ return ret;
+}
+EXPORT_SYMBOL_GPL(ipu_check_task);
+
+int ipu_queue_task(struct ipu_task *task)
+{
+ struct ipu_task_entry *tsk;
+ unsigned long flags;
+ int ret;
+ u32 tmp_task_no;
+ DECLARE_PERF_VAR;
+
+ tsk = create_task_entry(task);
+ if (IS_ERR(tsk))
+ return PTR_ERR(tsk);
+
+ CHECK_PERF(&tsk->ts_queue);
+ ret = prepare_task(tsk);
+ if (ret < 0)
+ goto done;
+
+ if (need_split(tsk)) {
+ CHECK_PERF(&tsk->ts_dotask);
+ CHECK_PERF(&tsk->ts_waitirq);
+ CHECK_PERF(&tsk->ts_inirq);
+ CHECK_PERF(&tsk->ts_wakeup);
+ }
+
+ /* task_no last four bits for split task type*/
+ tmp_task_no = atomic_inc_return(&frame_no);
+ tsk->task_no = tmp_task_no << 4;
+ init_waitqueue_head(&tsk->task_waitq);
+
+ spin_lock_irqsave(&ipu_task_list_lock, flags);
+ list_add_tail(&tsk->node, &ipu_task_list);
+ tsk->task_in_list = 1;
+ dev_dbg(tsk->dev, "[0x%p,no-0x%x] list_add_tail\n", tsk, tsk->task_no);
+ spin_unlock_irqrestore(&ipu_task_list_lock, flags);
+ wake_up_interruptible(&thread_waitq);
+
+ ret = wait_event_timeout(tsk->task_waitq, atomic_read(&tsk->done),
+ msecs_to_jiffies(tsk->timeout));
+ if (0 == ret) {
+ /* note: the timeout should larger than the internal timeout!*/
+ ret = -ETIMEDOUT;
+ dev_err(tsk->dev, "ERR: [0x%p] no-0x%x, timeout:%dms!\n",
+ tsk, tsk->task_no, tsk->timeout);
+ } else {
+ if (STATE_OK != tsk->state) {
+ dev_err(tsk->dev, "ERR: [0x%p] no-0x%x,state %d: %s\n",
+ tsk, tsk->task_no, tsk->state,
+ state_msg[tsk->state].msg);
+ ret = -ECANCELED;
+ } else
+ ret = 0;
+ }
+
+ spin_lock_irqsave(&ipu_task_list_lock, flags);
+ if (tsk->task_in_list) {
+ list_del(&tsk->node);
+ tsk->task_in_list = 0;
+ dev_dbg(tsk->dev, "[0x%p] no:0x%x list_del\n",
+ tsk, tsk->task_no);
+ }
+ spin_unlock_irqrestore(&ipu_task_list_lock, flags);
+
+#ifdef DBG_IPU_PERF
+ CHECK_PERF(&tsk->ts_rel);
+ PRINT_TASK_STATISTICS;
+ if (ts_frame_avg == 0)
+ ts_frame_avg = ts_frame.tv_nsec / NSEC_PER_USEC +
+ ts_frame.tv_sec * USEC_PER_SEC;
+ else
+ ts_frame_avg = (ts_frame_avg + ts_frame.tv_nsec / NSEC_PER_USEC
+ + ts_frame.tv_sec * USEC_PER_SEC)/2;
+ if (timespec_compare(&ts_frame, &ts_frame_max) > 0)
+ ts_frame_max = ts_frame;
+
+ atomic_inc(&frame_cnt);
+
+ if ((atomic_read(&frame_cnt) % 1000) == 0)
+ pr_debug("ipu_dev: max frame time:%ldus, avg frame time:%dus,"
+ "frame_cnt:%d\n", ts_frame_max.tv_nsec / NSEC_PER_USEC
+ + ts_frame_max.tv_sec * USEC_PER_SEC,
+ ts_frame_avg, atomic_read(&frame_cnt));
+#endif
+done:
+ if (ret < 0)
+ dev_err(tsk->dev, "ERR: no-0x%x,ipu_queue_task err:%d\n",
+ tsk->task_no, ret);
+
+ kref_put(&tsk->refcount, task_mem_free);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(ipu_queue_task);
+
+static int mxc_ipu_open(struct inode *inode, struct file *file)
+{
+ file->private_data = (void *)atomic_inc_return(&file_index);
+ return 0;
+}
+
+static long mxc_ipu_ioctl(struct file *file,
+ unsigned int cmd, unsigned long arg)
+{
+ int __user *argp = (void __user *)arg;
+ int ret = 0;
+
+ switch (cmd) {
+ case IPU_CHECK_TASK:
+ {
+ struct ipu_task task;
+
+ if (copy_from_user
+ (&task, (struct ipu_task *) arg,
+ sizeof(struct ipu_task)))
+ return -EFAULT;
+ ret = ipu_check_task(&task);
+ if (copy_to_user((struct ipu_task *) arg,
+ &task, sizeof(struct ipu_task)))
+ return -EFAULT;
+ break;
+ }
+ case IPU_QUEUE_TASK:
+ {
+ struct ipu_task task;
+
+ if (copy_from_user
+ (&task, (struct ipu_task *) arg,
+ sizeof(struct ipu_task)))
+ return -EFAULT;
+ ret = ipu_queue_task(&task);
+ break;
+ }
+ case IPU_ALLOC:
+ {
+ int size;
+ struct ipu_alloc_list *mem;
+
+ mem = kzalloc(sizeof(*mem), GFP_KERNEL);
+ if (mem == NULL)
+ return -ENOMEM;
+
+ if (get_user(size, argp)) {
+ kfree(mem);
+ return -EFAULT;
+ }
+
+ mem->size = PAGE_ALIGN(size);
+
+ mem->cpu_addr = dma_alloc_coherent(ipu_dev, size,
+ &mem->phy_addr,
+ GFP_DMA | GFP_KERNEL);
+ if (mem->cpu_addr == NULL) {
+ kfree(mem);
+ return -ENOMEM;
+ }
+ mem->file_index = file->private_data;
+ mutex_lock(&ipu_alloc_lock);
+ list_add(&mem->list, &ipu_alloc_list);
+ mutex_unlock(&ipu_alloc_lock);
+
+ if (put_user(mem->phy_addr, argp)) {
+ mutex_lock(&ipu_alloc_lock);
+ list_del(&mem->list);
+ mutex_unlock(&ipu_alloc_lock);
+ dma_free_coherent(ipu_dev,
+ mem->size,
+ mem->cpu_addr,
+ mem->phy_addr);
+ kfree(mem);
+ return -EFAULT;
+ }
+
+ dev_dbg(ipu_dev, "allocated %d bytes @ 0x%08X\n",
+ mem->size, mem->phy_addr);
+
+ break;
+ }
+ case IPU_FREE:
+ {
+ unsigned long offset;
+ struct ipu_alloc_list *mem;
+
+ if (get_user(offset, argp))
+ return -EFAULT;
+
+ ret = -EINVAL;
+ mutex_lock(&ipu_alloc_lock);
+ list_for_each_entry(mem, &ipu_alloc_list, list) {
+ if (mem->phy_addr == offset) {
+ list_del(&mem->list);
+ dma_free_coherent(ipu_dev,
+ mem->size,
+ mem->cpu_addr,
+ mem->phy_addr);
+ kfree(mem);
+ ret = 0;
+ break;
+ }
+ }
+ mutex_unlock(&ipu_alloc_lock);
+ if (0 == ret)
+ dev_dbg(ipu_dev, "free %d bytes @ 0x%08X\n",
+ mem->size, mem->phy_addr);
+
+ break;
+ }
+ default:
+ break;
+ }
+ return ret;
+}
+
+static int mxc_ipu_mmap(struct file *file, struct vm_area_struct *vma)
+{
+ bool found = false;
+ u32 len;
+ unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
+ struct ipu_alloc_list *mem;
+
+ mutex_lock(&ipu_alloc_lock);
+ list_for_each_entry(mem, &ipu_alloc_list, list) {
+ if (offset == mem->phy_addr) {
+ found = true;
+ len = mem->size;
+ break;
+ }
+ }
+ mutex_unlock(&ipu_alloc_lock);
+ if (!found)
+ return -EINVAL;
+
+ if (vma->vm_end - vma->vm_start > len)
+ return -EINVAL;
+
+ vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
+
+ if (remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
+ vma->vm_end - vma->vm_start,
+ vma->vm_page_prot)) {
+ printk(KERN_ERR
+ "mmap failed!\n");
+ return -ENOBUFS;
+ }
+ return 0;
+}
+
+static int mxc_ipu_release(struct inode *inode, struct file *file)
+{
+ struct ipu_alloc_list *mem;
+ struct ipu_alloc_list *n;
+
+ mutex_lock(&ipu_alloc_lock);
+ list_for_each_entry_safe(mem, n, &ipu_alloc_list, list) {
+ if ((mem->cpu_addr != 0) &&
+ (file->private_data == mem->file_index)) {
+ list_del(&mem->list);
+ dma_free_coherent(ipu_dev,
+ mem->size,
+ mem->cpu_addr,
+ mem->phy_addr);
+ dev_dbg(ipu_dev, "rel-free %d bytes @ 0x%08X\n",
+ mem->size, mem->phy_addr);
+ kfree(mem);
+ }
+ }
+ mutex_unlock(&ipu_alloc_lock);
+ atomic_dec(&file_index);
+
+ return 0;
+}
+
+static struct file_operations mxc_ipu_fops = {
+ .owner = THIS_MODULE,
+ .open = mxc_ipu_open,
+ .mmap = mxc_ipu_mmap,
+ .release = mxc_ipu_release,
+ .unlocked_ioctl = mxc_ipu_ioctl,
+};
+
+int register_ipu_device(struct ipu_soc *ipu, int id)
+{
+ int ret = 0;
+ static int idx;
+ static struct ipu_thread_data thread_data[5];
+
+ if (!major) {
+ major = register_chrdev(0, "mxc_ipu", &mxc_ipu_fops);
+ if (major < 0) {
+ printk(KERN_ERR "Unable to register mxc_ipu as a char device\n");
+ ret = major;
+ goto register_cdev_fail;
+ }
+
+ ipu_class = class_create(THIS_MODULE, "mxc_ipu");
+ if (IS_ERR(ipu_class)) {
+ ret = PTR_ERR(ipu_class);
+ goto ipu_class_fail;
+ }
+
+ ipu_dev = device_create(ipu_class, NULL, MKDEV(major, 0),
+ NULL, "mxc_ipu");
+ if (IS_ERR(ipu_dev)) {
+ ret = PTR_ERR(ipu_dev);
+ goto dev_create_fail;
+ }
+ ipu_dev->dma_mask = kmalloc(sizeof(*ipu_dev->dma_mask), GFP_KERNEL);
+ *ipu_dev->dma_mask = DMA_BIT_MASK(32);
+ ipu_dev->coherent_dma_mask = DMA_BIT_MASK(32);
+
+ mutex_init(&ipu_ch_tbl.lock);
+ }
+ max_ipu_no = ++id;
+ ipu->rot_dma[0].size = 0;
+ ipu->rot_dma[1].size = 0;
+
+ thread_data[idx].ipu = ipu;
+ thread_data[idx].id = 0;
+ thread_data[idx].is_vdoa = 0;
+ ipu->thread[0] = kthread_run(ipu_task_thread, &thread_data[idx++],
+ "ipu%d_task", id);
+ if (IS_ERR(ipu->thread[0])) {
+ ret = PTR_ERR(ipu->thread[0]);
+ goto kthread0_fail;
+ }
+
+ thread_data[idx].ipu = ipu;
+ thread_data[idx].id = 1;
+ thread_data[idx].is_vdoa = 0;
+ ipu->thread[1] = kthread_run(ipu_task_thread, &thread_data[idx++],
+ "ipu%d_task", id);
+ if (IS_ERR(ipu->thread[1])) {
+ ret = PTR_ERR(ipu->thread[1]);
+ goto kthread1_fail;
+ }
+
+
+ return ret;
+
+kthread1_fail:
+ kthread_stop(ipu->thread[0]);
+kthread0_fail:
+ if (id == 0)
+ device_destroy(ipu_class, MKDEV(major, 0));
+dev_create_fail:
+ if (id == 0) {
+ class_destroy(ipu_class);
+ }
+ipu_class_fail:
+ if (id == 0)
+ unregister_chrdev(major, "mxc_ipu");
+register_cdev_fail:
+ return ret;
+}
+
+void unregister_ipu_device(struct ipu_soc *ipu, int id)
+{
+ int i;
+
+ kthread_stop(ipu->thread[0]);
+ kthread_stop(ipu->thread[1]);
+ for (i = 0; i < 2; i++) {
+ if (ipu->rot_dma[i].vaddr)
+ dma_free_coherent(ipu_dev,
+ ipu->rot_dma[i].size,
+ ipu->rot_dma[i].vaddr,
+ ipu->rot_dma[i].paddr);
+ }
+
+ if (major) {
+ device_destroy(ipu_class, MKDEV(major, 0));
+ class_destroy(ipu_class);
+ unregister_chrdev(major, "mxc_ipu");
+ major = 0;
+ }
+}
diff --git a/drivers/mxc/ipu3/ipu_disp.c b/drivers/mxc/ipu3/ipu_disp.c
new file mode 100644
index 000000000000..33ff22ca860f
--- /dev/null
+++ b/drivers/mxc/ipu3/ipu_disp.c
@@ -0,0 +1,1993 @@
+/*
+ * Copyright 2005-2015 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2019 NXP
+ */
+
+/*
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/*!
+ * @file ipu_disp.c
+ *
+ * @brief IPU display submodule API functions
+ *
+ * @ingroup IPU
+ */
+
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/errno.h>
+#include <linux/io.h>
+#include <linux/ipu-v3.h>
+#include <linux/module.h>
+#include <linux/spinlock.h>
+#include <linux/types.h>
+
+#include <asm/atomic.h>
+
+#include "ipu_param_mem.h"
+#include "ipu_regs.h"
+
+struct dp_csc_param_t {
+ int mode;
+ void *coeff;
+};
+
+#define SYNC_WAVE 0
+#define NULL_WAVE (-1)
+#define ASYNC_SER_WAVE 6
+
+/* DC display ID assignments */
+#define DC_DISP_ID_SYNC(di) (di)
+#define DC_DISP_ID_SERIAL 2
+#define DC_DISP_ID_ASYNC 3
+
+int dmfc_type_setup;
+
+void _ipu_dmfc_init(struct ipu_soc *ipu, int dmfc_type, int first)
+{
+ u32 dmfc_wr_chan, dmfc_dp_chan;
+
+ if (first) {
+ if (dmfc_type_setup > dmfc_type)
+ dmfc_type = dmfc_type_setup;
+ else
+ dmfc_type_setup = dmfc_type;
+
+ /* disable DMFC-IC channel*/
+ ipu_dmfc_write(ipu, 0x2, DMFC_IC_CTRL);
+ } else if (dmfc_type_setup >= DMFC_HIGH_RESOLUTION_DC) {
+ dev_dbg(ipu->dev, "DMFC high resolution has set, will not change\n");
+ return;
+ } else
+ dmfc_type_setup = dmfc_type;
+
+ if (dmfc_type == DMFC_HIGH_RESOLUTION_DC) {
+ /* 1 - segment 0~3;
+ * 5B - segement 4, 5;
+ * 5F - segement 6, 7;
+ * 1C, 2C and 6B, 6F unused;
+ */
+ dev_info(ipu->dev, "IPU DMFC DC HIGH RESOLUTION: 1(0~3), 5B(4,5), 5F(6,7)\n");
+ dmfc_wr_chan = 0x00000088;
+ dmfc_dp_chan = 0x00009694;
+ ipu->dmfc_size_28 = 256*4;
+ ipu->dmfc_size_29 = 0;
+ ipu->dmfc_size_24 = 0;
+ ipu->dmfc_size_27 = 128*4;
+ ipu->dmfc_size_23 = 128*4;
+ } else if (dmfc_type == DMFC_HIGH_RESOLUTION_DP) {
+ /* 1 - segment 0, 1;
+ * 5B - segement 2~5;
+ * 5F - segement 6,7;
+ * 1C, 2C and 6B, 6F unused;
+ */
+ dev_info(ipu->dev, "IPU DMFC DP HIGH RESOLUTION: 1(0,1), 5B(2~5), 5F(6,7)\n");
+ dmfc_wr_chan = 0x00000090;
+ dmfc_dp_chan = 0x0000968a;
+ ipu->dmfc_size_28 = 128*4;
+ ipu->dmfc_size_29 = 0;
+ ipu->dmfc_size_24 = 0;
+ ipu->dmfc_size_27 = 128*4;
+ ipu->dmfc_size_23 = 256*4;
+ } else if (dmfc_type == DMFC_HIGH_RESOLUTION_ONLY_DP) {
+ /* 5B - segement 0~3;
+ * 5F - segement 4~7;
+ * 1, 1C, 2C and 6B, 6F unused;
+ */
+ dev_info(ipu->dev, "IPU DMFC ONLY-DP HIGH RESOLUTION: 5B(0~3), 5F(4~7)\n");
+ dmfc_wr_chan = 0x00000000;
+ dmfc_dp_chan = 0x00008c88;
+ ipu->dmfc_size_28 = 0;
+ ipu->dmfc_size_29 = 0;
+ ipu->dmfc_size_24 = 0;
+ ipu->dmfc_size_27 = 256*4;
+ ipu->dmfc_size_23 = 256*4;
+ } else {
+ /* 1 - segment 0, 1;
+ * 5B - segement 4, 5;
+ * 5F - segement 6, 7;
+ * 1C, 2C and 6B, 6F unused;
+ */
+ dev_info(ipu->dev, "IPU DMFC NORMAL mode: 1(0~1), 5B(4,5), 5F(6,7)\n");
+ dmfc_wr_chan = 0x00000090;
+ dmfc_dp_chan = 0x00009694;
+ ipu->dmfc_size_28 = 128*4;
+ ipu->dmfc_size_29 = 0;
+ ipu->dmfc_size_24 = 0;
+ ipu->dmfc_size_27 = 128*4;
+ ipu->dmfc_size_23 = 128*4;
+ }
+ ipu_dmfc_write(ipu, dmfc_wr_chan, DMFC_WR_CHAN);
+ ipu_dmfc_write(ipu, 0x202020F6, DMFC_WR_CHAN_DEF);
+ ipu_dmfc_write(ipu, dmfc_dp_chan, DMFC_DP_CHAN);
+ /* Enable chan 5 watermark set at 5 bursts and clear at 7 bursts */
+ ipu_dmfc_write(ipu, 0x2020F6F6, DMFC_DP_CHAN_DEF);
+}
+
+static int __init dmfc_setup(char *options)
+{
+ get_option(&options, &dmfc_type_setup);
+ if (dmfc_type_setup > DMFC_HIGH_RESOLUTION_ONLY_DP)
+ dmfc_type_setup = DMFC_HIGH_RESOLUTION_ONLY_DP;
+ return 1;
+}
+__setup("dmfc=", dmfc_setup);
+
+void _ipu_dmfc_set_wait4eot(struct ipu_soc *ipu, int dma_chan, int width)
+{
+ u32 dmfc_gen1 = ipu_dmfc_read(ipu, DMFC_GENERAL1);
+
+ if (width >= HIGH_RESOLUTION_WIDTH) {
+ if (dma_chan == 23)
+ _ipu_dmfc_init(ipu, DMFC_HIGH_RESOLUTION_DP, 0);
+ else if (dma_chan == 28)
+ _ipu_dmfc_init(ipu, DMFC_HIGH_RESOLUTION_DC, 0);
+ }
+
+ if (dma_chan == 23) { /*5B*/
+ if (ipu->dmfc_size_23/width > 3)
+ dmfc_gen1 |= 1UL << 20;
+ else
+ dmfc_gen1 &= ~(1UL << 20);
+ } else if (dma_chan == 24) { /*6B*/
+ if (ipu->dmfc_size_24/width > 1)
+ dmfc_gen1 |= 1UL << 22;
+ else
+ dmfc_gen1 &= ~(1UL << 22);
+ } else if (dma_chan == 27) { /*5F*/
+ if (ipu->dmfc_size_27/width > 2)
+ dmfc_gen1 |= 1UL << 21;
+ else
+ dmfc_gen1 &= ~(1UL << 21);
+ } else if (dma_chan == 28) { /*1*/
+ if (ipu->dmfc_size_28/width > 2)
+ dmfc_gen1 |= 1UL << 16;
+ else
+ dmfc_gen1 &= ~(1UL << 16);
+ } else if (dma_chan == 29) { /*6F*/
+ if (ipu->dmfc_size_29/width > 1)
+ dmfc_gen1 |= 1UL << 23;
+ else
+ dmfc_gen1 &= ~(1UL << 23);
+ }
+
+ ipu_dmfc_write(ipu, dmfc_gen1, DMFC_GENERAL1);
+}
+
+void _ipu_dmfc_set_burst_size(struct ipu_soc *ipu, int dma_chan, int burst_size)
+{
+ u32 dmfc_wr_chan = ipu_dmfc_read(ipu, DMFC_WR_CHAN);
+ u32 dmfc_dp_chan = ipu_dmfc_read(ipu, DMFC_DP_CHAN);
+ int dmfc_bs = 0;
+
+ switch (burst_size) {
+ case 64:
+ dmfc_bs = 0x40;
+ break;
+ case 32:
+ case 20:
+ dmfc_bs = 0x80;
+ break;
+ case 16:
+ dmfc_bs = 0xc0;
+ break;
+ default:
+ dev_err(ipu->dev, "Unsupported burst size %d\n",
+ burst_size);
+ return;
+ }
+
+ if (dma_chan == 23) { /*5B*/
+ dmfc_dp_chan &= ~(0xc0);
+ dmfc_dp_chan |= dmfc_bs;
+ } else if (dma_chan == 27) { /*5F*/
+ dmfc_dp_chan &= ~(0xc000);
+ dmfc_dp_chan |= (dmfc_bs << 8);
+ } else if (dma_chan == 28) { /*1*/
+ dmfc_wr_chan &= ~(0xc0);
+ dmfc_wr_chan |= dmfc_bs;
+ }
+
+ ipu_dmfc_write(ipu, dmfc_wr_chan, DMFC_WR_CHAN);
+ ipu_dmfc_write(ipu, dmfc_dp_chan, DMFC_DP_CHAN);
+}
+
+static void _ipu_di_data_wave_config(struct ipu_soc *ipu,
+ int di, int wave_gen,
+ int access_size, int component_size)
+{
+ u32 reg;
+ reg = (access_size << DI_DW_GEN_ACCESS_SIZE_OFFSET) |
+ (component_size << DI_DW_GEN_COMPONENT_SIZE_OFFSET);
+ ipu_di_write(ipu, di, reg, DI_DW_GEN(wave_gen));
+}
+
+static void _ipu_di_data_pin_config(struct ipu_soc *ipu,
+ int di, int wave_gen, int di_pin, int set,
+ int up, int down)
+{
+ u32 reg;
+
+ reg = ipu_di_read(ipu, di, DI_DW_GEN(wave_gen));
+ reg &= ~(0x3 << (di_pin * 2));
+ reg |= set << (di_pin * 2);
+ ipu_di_write(ipu, di, reg, DI_DW_GEN(wave_gen));
+
+ ipu_di_write(ipu, di, (down << 16) | up, DI_DW_SET(wave_gen, set));
+}
+
+static void _ipu_di_sync_config(struct ipu_soc *ipu,
+ int di, int wave_gen,
+ int run_count, int run_src,
+ int offset_count, int offset_src,
+ int repeat_count, int cnt_clr_src,
+ int cnt_polarity_gen_en,
+ int cnt_polarity_clr_src,
+ int cnt_polarity_trigger_src,
+ int cnt_up, int cnt_down)
+{
+ u32 reg;
+
+ if ((run_count >= 0x1000) || (offset_count >= 0x1000) || (repeat_count >= 0x1000) ||
+ (cnt_up >= 0x400) || (cnt_down >= 0x400)) {
+ dev_err(ipu->dev, "DI%d counters out of range.\n", di);
+ return;
+ }
+
+ reg = (run_count << 19) | (++run_src << 16) |
+ (offset_count << 3) | ++offset_src;
+ ipu_di_write(ipu, di, reg, DI_SW_GEN0(wave_gen));
+ reg = (cnt_polarity_gen_en << 29) | (++cnt_clr_src << 25) |
+ (++cnt_polarity_trigger_src << 12) | (++cnt_polarity_clr_src << 9);
+ reg |= (cnt_down << 16) | cnt_up;
+ if (repeat_count == 0) {
+ /* Enable auto reload */
+ reg |= 0x10000000;
+ }
+ ipu_di_write(ipu, di, reg, DI_SW_GEN1(wave_gen));
+ reg = ipu_di_read(ipu, di, DI_STP_REP(wave_gen));
+ reg &= ~(0xFFFF << (16 * ((wave_gen - 1) & 0x1)));
+ reg |= repeat_count << (16 * ((wave_gen - 1) & 0x1));
+ ipu_di_write(ipu, di, reg, DI_STP_REP(wave_gen));
+}
+
+static void _ipu_dc_map_link(struct ipu_soc *ipu,
+ int current_map,
+ int base_map_0, int buf_num_0,
+ int base_map_1, int buf_num_1,
+ int base_map_2, int buf_num_2)
+{
+ int ptr_0 = base_map_0 * 3 + buf_num_0;
+ int ptr_1 = base_map_1 * 3 + buf_num_1;
+ int ptr_2 = base_map_2 * 3 + buf_num_2;
+ int ptr;
+ u32 reg;
+ ptr = (ptr_2 << 10) + (ptr_1 << 5) + ptr_0;
+
+ reg = ipu_dc_read(ipu, DC_MAP_CONF_PTR(current_map));
+ reg &= ~(0x1F << ((16 * (current_map & 0x1))));
+ reg |= ptr << ((16 * (current_map & 0x1)));
+ ipu_dc_write(ipu, reg, DC_MAP_CONF_PTR(current_map));
+}
+
+static void _ipu_dc_map_config(struct ipu_soc *ipu,
+ int map, int byte_num, int offset, int mask)
+{
+ int ptr = map * 3 + byte_num;
+ u32 reg;
+
+ reg = ipu_dc_read(ipu, DC_MAP_CONF_VAL(ptr));
+ reg &= ~(0xFFFF << (16 * (ptr & 0x1)));
+ reg |= ((offset << 8) | mask) << (16 * (ptr & 0x1));
+ ipu_dc_write(ipu, reg, DC_MAP_CONF_VAL(ptr));
+
+ reg = ipu_dc_read(ipu, DC_MAP_CONF_PTR(map));
+ reg &= ~(0x1F << ((16 * (map & 0x1)) + (5 * byte_num)));
+ reg |= ptr << ((16 * (map & 0x1)) + (5 * byte_num));
+ ipu_dc_write(ipu, reg, DC_MAP_CONF_PTR(map));
+}
+
+static void _ipu_dc_map_clear(struct ipu_soc *ipu, int map)
+{
+ u32 reg = ipu_dc_read(ipu, DC_MAP_CONF_PTR(map));
+ ipu_dc_write(ipu, reg & ~(0xFFFF << (16 * (map & 0x1))),
+ DC_MAP_CONF_PTR(map));
+}
+
+static void _ipu_dc_write_tmpl(struct ipu_soc *ipu,
+ int word, u32 opcode, u32 operand, int map,
+ int wave, int glue, int sync, int stop)
+{
+ u32 reg;
+
+ if (opcode == WRG) {
+ reg = sync;
+ reg |= (glue << 4);
+ reg |= (++wave << 11);
+ reg |= ((operand & 0x1FFFF) << 15);
+ ipu_dc_tmpl_write(ipu, reg, word * 8);
+
+ reg = (operand >> 17);
+ reg |= opcode << 7;
+ reg |= (stop << 9);
+ ipu_dc_tmpl_write(ipu, reg, word * 8 + 4);
+ } else {
+ reg = sync;
+ reg |= (glue << 4);
+ reg |= (++wave << 11);
+ reg |= (++map << 15);
+ reg |= (operand << 20) & 0xFFF00000;
+ ipu_dc_tmpl_write(ipu, reg, word * 8);
+
+ reg = (operand >> 12);
+ reg |= opcode << 4;
+ reg |= (stop << 9);
+ ipu_dc_tmpl_write(ipu, reg, word * 8 + 4);
+ }
+}
+
+static void _ipu_dc_link_event(struct ipu_soc *ipu,
+ int chan, int event, int addr, int priority)
+{
+ u32 reg;
+ u32 address_shift;
+ if (event < DC_EVEN_UGDE0) {
+ reg = ipu_dc_read(ipu, DC_RL_CH(chan, event));
+ reg &= ~(0xFFFF << (16 * (event & 0x1)));
+ reg |= ((addr << 8) | priority) << (16 * (event & 0x1));
+ ipu_dc_write(ipu, reg, DC_RL_CH(chan, event));
+ } else {
+ reg = ipu_dc_read(ipu, DC_UGDE_0((event - DC_EVEN_UGDE0) / 2));
+ if ((event - DC_EVEN_UGDE0) & 0x1) {
+ reg &= ~(0x2FF << 16);
+ reg |= (addr << 16);
+ reg |= priority ? (2 << 24) : 0x0;
+ } else {
+ reg &= ~0xFC00FFFF;
+ if (priority)
+ chan = (chan >> 1) +
+ ((((chan & 0x1) + ((chan & 0x2) >> 1))) | (chan >> 3));
+ else
+ chan = 0x7;
+ address_shift = ((event - DC_EVEN_UGDE0) >> 1) ? 7 : 8;
+ reg |= (addr << address_shift) | (priority << 3) | chan;
+ }
+ ipu_dc_write(ipu, reg, DC_UGDE_0((event - DC_EVEN_UGDE0) / 2));
+ }
+}
+
+/* Y = R * 1.200 + G * 2.343 + B * .453 + 0.250;
+ U = R * -.672 + G * -1.328 + B * 2.000 + 512.250.;
+ V = R * 2.000 + G * -1.672 + B * -.328 + 512.250.;*/
+static const int rgb2ycbcr_coeff[5][3] = {
+ {0x4D, 0x96, 0x1D},
+ {-0x2B, -0x55, 0x80},
+ {0x80, -0x6B, -0x15},
+ {0x0000, 0x0200, 0x0200}, /* B0, B1, B2 */
+ {0x2, 0x2, 0x2}, /* S0, S1, S2 */
+};
+
+/* R = (1.164 * (Y - 16)) + (1.596 * (Cr - 128));
+ G = (1.164 * (Y - 16)) - (0.392 * (Cb - 128)) - (0.813 * (Cr - 128));
+ B = (1.164 * (Y - 16)) + (2.017 * (Cb - 128); */
+static const int ycbcr2rgb_coeff[5][3] = {
+ {0x095, 0x000, 0x0CC},
+ {0x095, 0x3CE, 0x398},
+ {0x095, 0x0FF, 0x000},
+ {0x3E42, 0x010A, 0x3DD6}, /*B0,B1,B2 */
+ {0x1, 0x1, 0x1}, /*S0,S1,S2 */
+};
+
+#define mask_a(a) ((u32)(a) & 0x3FF)
+#define mask_b(b) ((u32)(b) & 0x3FFF)
+
+/* Pls keep S0, S1 and S2 as 0x2 by using this convertion */
+static int _rgb_to_yuv(int n, int red, int green, int blue)
+{
+ int c;
+ c = red * rgb2ycbcr_coeff[n][0];
+ c += green * rgb2ycbcr_coeff[n][1];
+ c += blue * rgb2ycbcr_coeff[n][2];
+ c /= 16;
+ c += rgb2ycbcr_coeff[3][n] * 4;
+ c += 8;
+ c /= 16;
+ if (c < 0)
+ c = 0;
+ if (c > 255)
+ c = 255;
+ return c;
+}
+
+/*
+ * Row is for BG: RGB2YUV YUV2RGB RGB2RGB YUV2YUV CSC_NONE
+ * Column is for FG: RGB2YUV YUV2RGB RGB2RGB YUV2YUV CSC_NONE
+ */
+static struct dp_csc_param_t dp_csc_array[CSC_NUM][CSC_NUM] = {
+{
+ {DP_COM_CONF_CSC_DEF_BOTH, (void *)&rgb2ycbcr_coeff},
+ {0, 0}, {0, 0},
+ {DP_COM_CONF_CSC_DEF_BG, (void *)&rgb2ycbcr_coeff},
+ {DP_COM_CONF_CSC_DEF_BG, (void *)&rgb2ycbcr_coeff}
+},
+{
+ {0, 0},
+ {DP_COM_CONF_CSC_DEF_BOTH, (void *)&ycbcr2rgb_coeff},
+ {DP_COM_CONF_CSC_DEF_BG, (void *)&ycbcr2rgb_coeff},
+ {0, 0},
+ {DP_COM_CONF_CSC_DEF_BG, (void *)&ycbcr2rgb_coeff}
+},
+{
+ {0, 0},
+ {DP_COM_CONF_CSC_DEF_FG, (void *)&ycbcr2rgb_coeff},
+ {0, 0}, {0, 0}, {0, 0}
+},
+{
+ {DP_COM_CONF_CSC_DEF_FG, (void *)&rgb2ycbcr_coeff},
+ {0, 0}, {0, 0}, {0, 0}, {0, 0}
+},
+{
+ {DP_COM_CONF_CSC_DEF_FG, (void *)&rgb2ycbcr_coeff},
+ {DP_COM_CONF_CSC_DEF_FG, (void *)&ycbcr2rgb_coeff},
+ {0, 0}, {0, 0}, {0, 0}
+}
+};
+
+void __ipu_dp_csc_setup(struct ipu_soc *ipu,
+ int dp, struct dp_csc_param_t dp_csc_param,
+ bool srm_mode_update)
+{
+ u32 reg;
+ const int (*coeff)[5][3];
+
+ if (dp_csc_param.mode >= 0) {
+ reg = ipu_dp_read(ipu, DP_COM_CONF(dp));
+ reg &= ~DP_COM_CONF_CSC_DEF_MASK;
+ reg |= dp_csc_param.mode;
+ ipu_dp_write(ipu, reg, DP_COM_CONF(dp));
+ }
+
+ coeff = dp_csc_param.coeff;
+
+ if (coeff) {
+ ipu_dp_write(ipu, mask_a((*coeff)[0][0]) |
+ (mask_a((*coeff)[0][1]) << 16), DP_CSC_A_0(dp));
+ ipu_dp_write(ipu, mask_a((*coeff)[0][2]) |
+ (mask_a((*coeff)[1][0]) << 16), DP_CSC_A_1(dp));
+ ipu_dp_write(ipu, mask_a((*coeff)[1][1]) |
+ (mask_a((*coeff)[1][2]) << 16), DP_CSC_A_2(dp));
+ ipu_dp_write(ipu, mask_a((*coeff)[2][0]) |
+ (mask_a((*coeff)[2][1]) << 16), DP_CSC_A_3(dp));
+ ipu_dp_write(ipu, mask_a((*coeff)[2][2]) |
+ (mask_b((*coeff)[3][0]) << 16) |
+ ((*coeff)[4][0] << 30), DP_CSC_0(dp));
+ ipu_dp_write(ipu, mask_b((*coeff)[3][1]) | ((*coeff)[4][1] << 14) |
+ (mask_b((*coeff)[3][2]) << 16) |
+ ((*coeff)[4][2] << 30), DP_CSC_1(dp));
+ }
+
+ if (srm_mode_update) {
+ reg = ipu_cm_read(ipu, IPU_SRM_PRI2) | 0x8;
+ ipu_cm_write(ipu, reg, IPU_SRM_PRI2);
+ }
+}
+
+int _ipu_dp_init(struct ipu_soc *ipu,
+ ipu_channel_t channel, uint32_t in_pixel_fmt,
+ uint32_t out_pixel_fmt)
+{
+ int in_fmt, out_fmt;
+ int dp;
+ int partial = false;
+ uint32_t reg;
+
+ if (channel == MEM_FG_SYNC) {
+ dp = DP_SYNC;
+ partial = true;
+ } else if (channel == MEM_BG_SYNC) {
+ dp = DP_SYNC;
+ partial = false;
+ } else if (channel == MEM_BG_ASYNC0) {
+ dp = DP_ASYNC0;
+ partial = false;
+ } else {
+ return -EINVAL;
+ }
+
+ in_fmt = format_to_colorspace(in_pixel_fmt);
+ out_fmt = format_to_colorspace(out_pixel_fmt);
+
+ if (partial) {
+ if (in_fmt == RGB) {
+ if (out_fmt == RGB)
+ ipu->fg_csc_type = RGB2RGB;
+ else
+ ipu->fg_csc_type = RGB2YUV;
+ } else {
+ if (out_fmt == RGB)
+ ipu->fg_csc_type = YUV2RGB;
+ else
+ ipu->fg_csc_type = YUV2YUV;
+ }
+ } else {
+ if (in_fmt == RGB) {
+ if (out_fmt == RGB)
+ ipu->bg_csc_type = RGB2RGB;
+ else
+ ipu->bg_csc_type = RGB2YUV;
+ } else {
+ if (out_fmt == RGB)
+ ipu->bg_csc_type = YUV2RGB;
+ else
+ ipu->bg_csc_type = YUV2YUV;
+ }
+ }
+
+ /* Transform color key from rgb to yuv if CSC is enabled */
+ reg = ipu_dp_read(ipu, DP_COM_CONF(dp));
+ if (ipu->color_key_4rgb && (reg & DP_COM_CONF_GWCKE) &&
+ (((ipu->fg_csc_type == RGB2YUV) && (ipu->bg_csc_type == YUV2YUV)) ||
+ ((ipu->fg_csc_type == YUV2YUV) && (ipu->bg_csc_type == RGB2YUV)) ||
+ ((ipu->fg_csc_type == YUV2YUV) && (ipu->bg_csc_type == YUV2YUV)) ||
+ ((ipu->fg_csc_type == YUV2RGB) && (ipu->bg_csc_type == YUV2RGB)))) {
+ int red, green, blue;
+ int y, u, v;
+ uint32_t color_key = ipu_dp_read(ipu, DP_GRAPH_WIND_CTRL(dp)) & 0xFFFFFFL;
+
+ dev_dbg(ipu->dev, "_ipu_dp_init color key 0x%x need change to yuv fmt!\n", color_key);
+
+ red = (color_key >> 16) & 0xFF;
+ green = (color_key >> 8) & 0xFF;
+ blue = color_key & 0xFF;
+
+ y = _rgb_to_yuv(0, red, green, blue);
+ u = _rgb_to_yuv(1, red, green, blue);
+ v = _rgb_to_yuv(2, red, green, blue);
+ color_key = (y << 16) | (u << 8) | v;
+
+ reg = ipu_dp_read(ipu, DP_GRAPH_WIND_CTRL(dp)) & 0xFF000000L;
+ ipu_dp_write(ipu, reg | color_key, DP_GRAPH_WIND_CTRL(dp));
+ ipu->color_key_4rgb = false;
+
+ dev_dbg(ipu->dev, "_ipu_dp_init color key change to yuv fmt 0x%x!\n", color_key);
+ }
+
+ __ipu_dp_csc_setup(ipu, dp,
+ dp_csc_array[ipu->bg_csc_type][ipu->fg_csc_type],
+ false);
+
+ return 0;
+}
+
+void _ipu_dp_uninit(struct ipu_soc *ipu, ipu_channel_t channel)
+{
+ int dp;
+ int partial = false;
+
+ if (channel == MEM_FG_SYNC) {
+ dp = DP_SYNC;
+ partial = true;
+ } else if (channel == MEM_BG_SYNC) {
+ dp = DP_SYNC;
+ partial = false;
+ } else if (channel == MEM_BG_ASYNC0) {
+ dp = DP_ASYNC0;
+ partial = false;
+ } else {
+ return;
+ }
+
+ if (partial)
+ ipu->fg_csc_type = CSC_NONE;
+ else
+ ipu->bg_csc_type = CSC_NONE;
+
+ __ipu_dp_csc_setup(ipu, dp, dp_csc_array[ipu->bg_csc_type][ipu->fg_csc_type], false);
+}
+
+void _ipu_dc_init(struct ipu_soc *ipu, int dc_chan, int di, bool interlaced, uint32_t pixel_fmt)
+{
+ u32 reg = 0;
+
+ if ((dc_chan == 1) || (dc_chan == 5)) {
+ if (interlaced) {
+ _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NL, 0, 3);
+ _ipu_dc_link_event(ipu, dc_chan, DC_EVT_EOL, 0, 2);
+ _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NEW_DATA, 0, 1);
+ } else {
+ if (di) {
+ _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NL, 2, 3);
+ _ipu_dc_link_event(ipu, dc_chan, DC_EVT_EOL, 3, 2);
+ _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NEW_DATA, 1, 1);
+ if ((pixel_fmt == IPU_PIX_FMT_YUYV) ||
+ (pixel_fmt == IPU_PIX_FMT_UYVY) ||
+ (pixel_fmt == IPU_PIX_FMT_YVYU) ||
+ (pixel_fmt == IPU_PIX_FMT_VYUY)) {
+ _ipu_dc_link_event(ipu, dc_chan, DC_ODD_UGDE1, 9, 5);
+ _ipu_dc_link_event(ipu, dc_chan, DC_EVEN_UGDE1, 8, 5);
+ }
+ } else {
+ _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NL, 5, 3);
+ _ipu_dc_link_event(ipu, dc_chan, DC_EVT_EOL, 6, 2);
+ _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NEW_DATA, 12, 1);
+ if ((pixel_fmt == IPU_PIX_FMT_YUYV) ||
+ (pixel_fmt == IPU_PIX_FMT_UYVY) ||
+ (pixel_fmt == IPU_PIX_FMT_YVYU) ||
+ (pixel_fmt == IPU_PIX_FMT_VYUY)) {
+ _ipu_dc_link_event(ipu, dc_chan, DC_ODD_UGDE0, 10, 5);
+ _ipu_dc_link_event(ipu, dc_chan, DC_EVEN_UGDE0, 11, 5);
+ }
+ }
+ }
+ _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NF, 0, 0);
+ _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NFIELD, 0, 0);
+ _ipu_dc_link_event(ipu, dc_chan, DC_EVT_EOF, 0, 0);
+ _ipu_dc_link_event(ipu, dc_chan, DC_EVT_EOFIELD, 0, 0);
+ _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NEW_CHAN, 0, 0);
+ _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NEW_ADDR, 0, 0);
+
+ reg = 0x2;
+ reg |= DC_DISP_ID_SYNC(di) << DC_WR_CH_CONF_PROG_DISP_ID_OFFSET;
+ reg |= di << 2;
+ if (interlaced)
+ reg |= DC_WR_CH_CONF_FIELD_MODE;
+ } else if ((dc_chan == 8) || (dc_chan == 9)) {
+ /* async channels */
+ _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NEW_DATA_W_0, 0x64, 1);
+ _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NEW_DATA_W_1, 0x64, 1);
+
+ reg = 0x3;
+ reg |= DC_DISP_ID_SERIAL << DC_WR_CH_CONF_PROG_DISP_ID_OFFSET;
+ }
+ ipu_dc_write(ipu, reg, DC_WR_CH_CONF(dc_chan));
+
+ ipu_dc_write(ipu, 0x00000000, DC_WR_CH_ADDR(dc_chan));
+
+ ipu_dc_write(ipu, 0x00000084, DC_GEN);
+}
+
+void _ipu_dc_uninit(struct ipu_soc *ipu, int dc_chan)
+{
+ if ((dc_chan == 1) || (dc_chan == 5)) {
+ _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NL, 0, 0);
+ _ipu_dc_link_event(ipu, dc_chan, DC_EVT_EOL, 0, 0);
+ _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NEW_DATA, 0, 0);
+ _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NF, 0, 0);
+ _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NFIELD, 0, 0);
+ _ipu_dc_link_event(ipu, dc_chan, DC_EVT_EOF, 0, 0);
+ _ipu_dc_link_event(ipu, dc_chan, DC_EVT_EOFIELD, 0, 0);
+ _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NEW_CHAN, 0, 0);
+ _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NEW_ADDR, 0, 0);
+ _ipu_dc_link_event(ipu, dc_chan, DC_ODD_UGDE0, 0, 0);
+ _ipu_dc_link_event(ipu, dc_chan, DC_EVEN_UGDE0, 0, 0);
+ _ipu_dc_link_event(ipu, dc_chan, DC_ODD_UGDE1, 0, 0);
+ _ipu_dc_link_event(ipu, dc_chan, DC_EVEN_UGDE1, 0, 0);
+ } else if ((dc_chan == 8) || (dc_chan == 9)) {
+ _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NEW_ADDR_W_0, 0, 0);
+ _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NEW_ADDR_W_1, 0, 0);
+ _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NEW_CHAN_W_0, 0, 0);
+ _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NEW_CHAN_W_1, 0, 0);
+ _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NEW_DATA_W_0, 0, 0);
+ _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NEW_DATA_W_1, 0, 0);
+ _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NEW_ADDR_R_0, 0, 0);
+ _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NEW_ADDR_R_1, 0, 0);
+ _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NEW_CHAN_R_0, 0, 0);
+ _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NEW_CHAN_R_1, 0, 0);
+ _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NEW_DATA_R_0, 0, 0);
+ _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NEW_DATA_R_1, 0, 0);
+ }
+}
+
+int _ipu_disp_chan_is_interlaced(struct ipu_soc *ipu, ipu_channel_t channel)
+{
+ if (channel == MEM_DC_SYNC)
+ return !!(ipu_dc_read(ipu, DC_WR_CH_CONF_1) &
+ DC_WR_CH_CONF_FIELD_MODE);
+ else if ((channel == MEM_BG_SYNC) || (channel == MEM_FG_SYNC))
+ return !!(ipu_dc_read(ipu, DC_WR_CH_CONF_5) &
+ DC_WR_CH_CONF_FIELD_MODE);
+ return 0;
+}
+
+void _ipu_dp_dc_enable(struct ipu_soc *ipu, ipu_channel_t channel)
+{
+ int di;
+ uint32_t reg;
+ uint32_t dc_chan;
+ int irq = 0;
+
+ if (channel == MEM_FG_SYNC)
+ irq = IPU_IRQ_DP_SF_END;
+ else if (channel == MEM_DC_SYNC)
+ dc_chan = 1;
+ else if (channel == MEM_BG_SYNC)
+ dc_chan = 5;
+ else
+ return;
+
+ if (channel == MEM_FG_SYNC) {
+ /* Enable FG channel */
+ reg = ipu_dp_read(ipu, DP_COM_CONF(DP_SYNC));
+ ipu_dp_write(ipu, reg | DP_COM_CONF_FG_EN, DP_COM_CONF(DP_SYNC));
+
+ reg = ipu_cm_read(ipu, IPU_SRM_PRI2) | 0x8;
+ ipu_cm_write(ipu, reg, IPU_SRM_PRI2);
+ return;
+ } else if (channel == MEM_BG_SYNC) {
+ reg = ipu_cm_read(ipu, IPU_SRM_PRI2) | 0x8;
+ ipu_cm_write(ipu, reg, IPU_SRM_PRI2);
+ }
+
+ di = ipu->dc_di_assignment[dc_chan];
+
+ /* Make sure other DC sync channel is not assigned same DI */
+ reg = ipu_dc_read(ipu, DC_WR_CH_CONF(6 - dc_chan));
+ if ((di << 2) == (reg & DC_WR_CH_CONF_PROG_DI_ID)) {
+ reg &= ~DC_WR_CH_CONF_PROG_DI_ID;
+ reg |= di ? 0 : DC_WR_CH_CONF_PROG_DI_ID;
+ ipu_dc_write(ipu, reg, DC_WR_CH_CONF(6 - dc_chan));
+ }
+
+ reg = ipu_dc_read(ipu, DC_WR_CH_CONF(dc_chan));
+ reg |= 4 << DC_WR_CH_CONF_PROG_TYPE_OFFSET;
+ ipu_dc_write(ipu, reg, DC_WR_CH_CONF(dc_chan));
+
+ clk_prepare_enable(ipu->pixel_clk[di]);
+ ipu->pixel_clk_en[ipu->dc_di_assignment[dc_chan]] = true;
+}
+
+static irqreturn_t dc_irq_handler(int irq, void *dev_id)
+{
+ struct ipu_soc *ipu = dev_id;
+ struct completion *comp = &ipu->dc_comp;
+ uint32_t reg;
+ uint32_t dc_chan;
+
+ if (irq == IPU_IRQ_DC_FC_1)
+ dc_chan = 1;
+ else
+ dc_chan = 5;
+
+ if (!ipu->dc_swap) {
+ reg = ipu_dc_read(ipu, DC_WR_CH_CONF(dc_chan));
+ reg &= ~DC_WR_CH_CONF_PROG_TYPE_MASK;
+ ipu_dc_write(ipu, reg, DC_WR_CH_CONF(dc_chan));
+
+ reg = ipu_cm_read(ipu, IPU_DISP_GEN);
+ if (ipu->dc_di_assignment[dc_chan])
+ reg &= ~DI1_COUNTER_RELEASE;
+ else
+ reg &= ~DI0_COUNTER_RELEASE;
+ ipu_cm_write(ipu, reg, IPU_DISP_GEN);
+ }
+
+ complete(comp);
+ return IRQ_HANDLED;
+}
+
+void _ipu_dp_dc_disable(struct ipu_soc *ipu, ipu_channel_t channel, bool swap)
+{
+ int ret;
+ uint32_t reg;
+ uint32_t csc;
+ uint32_t dc_chan;
+ int irq = 0;
+ int timeout = 50;
+
+ ipu->dc_swap = swap;
+
+ if (channel == MEM_DC_SYNC) {
+ dc_chan = 1;
+ irq = IPU_IRQ_DC_FC_1;
+ } else if (channel == MEM_BG_SYNC) {
+ dc_chan = 5;
+ irq = IPU_IRQ_DP_SF_END;
+ } else if (channel == MEM_FG_SYNC) {
+ /* Disable FG channel */
+ dc_chan = 5;
+
+ reg = ipu_dp_read(ipu, DP_COM_CONF(DP_SYNC));
+ csc = reg & DP_COM_CONF_CSC_DEF_MASK;
+ if (csc == DP_COM_CONF_CSC_DEF_FG)
+ reg &= ~DP_COM_CONF_CSC_DEF_MASK;
+
+ reg &= ~DP_COM_CONF_FG_EN;
+ ipu_dp_write(ipu, reg, DP_COM_CONF(DP_SYNC));
+
+ reg = ipu_cm_read(ipu, IPU_SRM_PRI2) | 0x8;
+ ipu_cm_write(ipu, reg, IPU_SRM_PRI2);
+
+ if (ipu_is_channel_busy(ipu, MEM_BG_SYNC)) {
+ ipu_cm_write(ipu, IPUIRQ_2_MASK(IPU_IRQ_DP_SF_END),
+ IPUIRQ_2_STATREG(ipu->devtype,
+ IPU_IRQ_DP_SF_END));
+ while ((ipu_cm_read(ipu,
+ IPUIRQ_2_STATREG(ipu->devtype,
+ IPU_IRQ_DP_SF_END)) &
+ IPUIRQ_2_MASK(IPU_IRQ_DP_SF_END)) == 0) {
+ msleep(2);
+ timeout -= 2;
+ if (timeout <= 0)
+ break;
+ }
+ }
+ return;
+ } else {
+ return;
+ }
+
+ init_completion(&ipu->dc_comp);
+ ret = ipu_request_irq(ipu, irq, dc_irq_handler, 0, NULL, ipu);
+ if (ret < 0) {
+ dev_err(ipu->dev, "DC irq %d in use\n", irq);
+ return;
+ }
+ ret = wait_for_completion_timeout(&ipu->dc_comp, msecs_to_jiffies(50));
+ ipu_free_irq(ipu, irq, ipu);
+ dev_dbg(ipu->dev, "DC stop timeout - %d * 10ms\n", 5 - ret);
+
+ if (ipu->dc_swap) {
+ /* Swap DC channel 1 and 5 settings, and disable old dc chan */
+ reg = ipu_dc_read(ipu, DC_WR_CH_CONF(dc_chan));
+ ipu_dc_write(ipu, reg, DC_WR_CH_CONF(6 - dc_chan));
+ reg &= ~DC_WR_CH_CONF_PROG_TYPE_MASK;
+ reg ^= DC_WR_CH_CONF_PROG_DI_ID;
+ ipu_dc_write(ipu, reg, DC_WR_CH_CONF(dc_chan));
+ }
+}
+
+void _ipu_init_dc_mappings(struct ipu_soc *ipu)
+{
+ /* IPU_PIX_FMT_RGB24 */
+ _ipu_dc_map_clear(ipu, 0);
+ _ipu_dc_map_config(ipu, 0, 0, 7, 0xFF);
+ _ipu_dc_map_config(ipu, 0, 1, 15, 0xFF);
+ _ipu_dc_map_config(ipu, 0, 2, 23, 0xFF);
+
+ /* IPU_PIX_FMT_RGB666 */
+ _ipu_dc_map_clear(ipu, 1);
+ _ipu_dc_map_config(ipu, 1, 0, 5, 0xFC);
+ _ipu_dc_map_config(ipu, 1, 1, 11, 0xFC);
+ _ipu_dc_map_config(ipu, 1, 2, 17, 0xFC);
+
+ /* IPU_PIX_FMT_YUV444 */
+ _ipu_dc_map_clear(ipu, 2);
+ _ipu_dc_map_config(ipu, 2, 0, 15, 0xFF);
+ _ipu_dc_map_config(ipu, 2, 1, 23, 0xFF);
+ _ipu_dc_map_config(ipu, 2, 2, 7, 0xFF);
+
+ /* IPU_PIX_FMT_RGB565 */
+ _ipu_dc_map_clear(ipu, 3);
+ _ipu_dc_map_config(ipu, 3, 0, 4, 0xF8);
+ _ipu_dc_map_config(ipu, 3, 1, 10, 0xFC);
+ _ipu_dc_map_config(ipu, 3, 2, 15, 0xF8);
+
+ /* IPU_PIX_FMT_LVDS666 */
+ _ipu_dc_map_clear(ipu, 4);
+ _ipu_dc_map_config(ipu, 4, 0, 5, 0xFC);
+ _ipu_dc_map_config(ipu, 4, 1, 13, 0xFC);
+ _ipu_dc_map_config(ipu, 4, 2, 21, 0xFC);
+
+ /* IPU_PIX_FMT_VYUY 16bit width */
+ _ipu_dc_map_clear(ipu, 5);
+ _ipu_dc_map_config(ipu, 5, 0, 7, 0xFF);
+ _ipu_dc_map_config(ipu, 5, 1, 0, 0x0);
+ _ipu_dc_map_config(ipu, 5, 2, 15, 0xFF);
+ _ipu_dc_map_clear(ipu, 6);
+ _ipu_dc_map_config(ipu, 6, 0, 0, 0x0);
+ _ipu_dc_map_config(ipu, 6, 1, 7, 0xFF);
+ _ipu_dc_map_config(ipu, 6, 2, 15, 0xFF);
+
+ /* IPU_PIX_FMT_UYUV 16bit width */
+ _ipu_dc_map_clear(ipu, 7);
+ _ipu_dc_map_link(ipu, 7, 6, 0, 6, 1, 6, 2);
+ _ipu_dc_map_clear(ipu, 8);
+ _ipu_dc_map_link(ipu, 8, 5, 0, 5, 1, 5, 2);
+
+ /* IPU_PIX_FMT_YUYV 16bit width */
+ _ipu_dc_map_clear(ipu, 9);
+ _ipu_dc_map_link(ipu, 9, 5, 2, 5, 1, 5, 0);
+ _ipu_dc_map_clear(ipu, 10);
+ _ipu_dc_map_link(ipu, 10, 5, 1, 5, 2, 5, 0);
+
+ /* IPU_PIX_FMT_YVYU 16bit width */
+ _ipu_dc_map_clear(ipu, 11);
+ _ipu_dc_map_link(ipu, 11, 5, 1, 5, 2, 5, 0);
+ _ipu_dc_map_clear(ipu, 12);
+ _ipu_dc_map_link(ipu, 12, 5, 2, 5, 1, 5, 0);
+
+ /* IPU_PIX_FMT_GBR24 */
+ /* IPU_PIX_FMT_VYU444 */
+ _ipu_dc_map_clear(ipu, 13);
+ _ipu_dc_map_link(ipu, 13, 0, 2, 0, 0, 0, 1);
+
+ /* IPU_PIX_FMT_BGR24 */
+ _ipu_dc_map_clear(ipu, 14);
+ _ipu_dc_map_link(ipu, 14, 0, 2, 0, 1, 0, 0);
+}
+
+int _ipu_pixfmt_to_map(uint32_t fmt)
+{
+ switch (fmt) {
+ case IPU_PIX_FMT_GENERIC:
+ case IPU_PIX_FMT_RGB24:
+ return 0;
+ case IPU_PIX_FMT_RGB666:
+ return 1;
+ case IPU_PIX_FMT_YUV444:
+ return 2;
+ case IPU_PIX_FMT_RGB565:
+ return 3;
+ case IPU_PIX_FMT_LVDS666:
+ return 4;
+ case IPU_PIX_FMT_VYUY:
+ return 6;
+ case IPU_PIX_FMT_UYVY:
+ return 8;
+ case IPU_PIX_FMT_YUYV:
+ return 10;
+ case IPU_PIX_FMT_YVYU:
+ return 12;
+ case IPU_PIX_FMT_GBR24:
+ case IPU_PIX_FMT_VYU444:
+ return 13;
+ case IPU_PIX_FMT_BGR24:
+ return 14;
+ }
+
+ return -1;
+}
+
+/*!
+ * This function sets the colorspace for of dp.
+ * modes.
+ *
+ * @param ipu ipu handler
+ * @param channel Input parameter for the logical channel ID.
+ *
+ * @param param If it's not NULL, update the csc table
+ * with this parameter.
+ *
+ * @return N/A
+ */
+void _ipu_dp_set_csc_coefficients(struct ipu_soc *ipu, ipu_channel_t channel, int32_t param[][3])
+{
+ int dp;
+ struct dp_csc_param_t dp_csc_param;
+
+ if (channel == MEM_FG_SYNC)
+ dp = DP_SYNC;
+ else if (channel == MEM_BG_SYNC)
+ dp = DP_SYNC;
+ else if (channel == MEM_BG_ASYNC0)
+ dp = DP_ASYNC0;
+ else
+ return;
+
+ dp_csc_param.mode = -1;
+ dp_csc_param.coeff = param;
+ __ipu_dp_csc_setup(ipu, dp, dp_csc_param, true);
+}
+
+void ipu_set_csc_coefficients(struct ipu_soc *ipu, ipu_channel_t channel, int32_t param[][3])
+{
+ _ipu_dp_set_csc_coefficients(ipu, channel, param);
+}
+EXPORT_SYMBOL(ipu_set_csc_coefficients);
+
+/*!
+ * This function is called to adapt synchronous LCD panel to IPU restriction.
+ *
+ */
+void adapt_panel_to_ipu_restricitions(struct ipu_soc *ipu, uint16_t *v_start_width,
+ uint16_t *v_sync_width,
+ uint16_t *v_end_width)
+{
+ if (*v_end_width < 2) {
+ uint16_t diff = 2 - *v_end_width;
+ if (*v_start_width >= diff) {
+ *v_end_width = 2;
+ *v_start_width = *v_start_width - diff;
+ } else if (*v_sync_width > diff) {
+ *v_end_width = 2;
+ *v_sync_width = *v_sync_width - diff;
+ } else
+ dev_err(ipu->dev, "WARNING: try to adapt timming, but failed\n");
+ dev_err(ipu->dev, "WARNING: adapt panel end blank lines\n");
+ }
+}
+
+/*!
+ * This function is called to initialize a synchronous LCD panel.
+ *
+ * @param ipu ipu handler
+ * @param disp The DI the panel is attached to.
+ *
+ * @param pixel_clk Desired pixel clock frequency in Hz.
+ *
+ * @param pixel_fmt Input parameter for pixel format of buffer.
+ * Pixel format is a FOURCC ASCII code.
+ *
+ * @param width The width of panel in pixels.
+ *
+ * @param height The height of panel in pixels.
+ *
+ * @param hStartWidth The number of pixel clocks between the HSYNC
+ * signal pulse and the start of valid data.
+ *
+ * @param hSyncWidth The width of the HSYNC signal in units of pixel
+ * clocks.
+ *
+ * @param hEndWidth The number of pixel clocks between the end of
+ * valid data and the HSYNC signal for next line.
+ *
+ * @param vStartWidth The number of lines between the VSYNC
+ * signal pulse and the start of valid data.
+ *
+ * @param vSyncWidth The width of the VSYNC signal in units of lines
+ *
+ * @param vEndWidth The number of lines between the end of valid
+ * data and the VSYNC signal for next frame.
+ *
+ * @param sig Bitfield of signal polarities for LCD interface.
+ *
+ * @return This function returns 0 on success or negative error code on
+ * fail.
+ */
+int32_t ipu_init_sync_panel(struct ipu_soc *ipu, int disp, uint32_t pixel_clk,
+ uint16_t width, uint16_t height,
+ uint32_t pixel_fmt,
+ uint16_t h_start_width, uint16_t h_sync_width,
+ uint16_t h_end_width, uint16_t v_start_width,
+ uint16_t v_sync_width, uint16_t v_end_width,
+ uint32_t v_to_h_sync, ipu_di_signal_cfg_t sig)
+{
+ uint32_t field0_offset = 0;
+ uint32_t field1_offset;
+ uint32_t reg;
+ uint32_t di_gen, vsync_cnt;
+ uint32_t div, rounded_pixel_clk;
+ uint32_t h_total, v_total;
+ int map;
+ int ret;
+ struct clk *ldb_di0_clk, *ldb_di1_clk;
+ struct clk *di_parent;
+
+ dev_dbg(ipu->dev, "panel size = %d x %d\n", width, height);
+
+ if ((v_sync_width == 0) || (h_sync_width == 0))
+ return -EINVAL;
+
+ adapt_panel_to_ipu_restricitions(ipu, &v_start_width, &v_sync_width, &v_end_width);
+ h_total = width + h_sync_width + h_start_width + h_end_width;
+ v_total = height + v_sync_width + v_start_width + v_end_width;
+
+ /* Init clocking */
+ dev_dbg(ipu->dev, "pixel clk = %d\n", pixel_clk);
+
+ di_parent = clk_get_parent(ipu->di_clk_sel[disp]);
+ if (!di_parent) {
+ dev_err(ipu->dev, "get di clk parent fail\n");
+ return -EINVAL;
+ }
+ ldb_di0_clk = clk_get(ipu->dev, "ldb_di0");
+ if (IS_ERR(ldb_di0_clk)) {
+ dev_err(ipu->dev, "clk_get di0 failed");
+ return PTR_ERR(ldb_di0_clk);
+ }
+ ldb_di1_clk = clk_get(ipu->dev, "ldb_di1");
+ if (IS_ERR(ldb_di1_clk)) {
+ dev_err(ipu->dev, "clk_get di1 failed");
+ return PTR_ERR(ldb_di1_clk);
+ }
+ if (!strcmp(__clk_get_name(di_parent), __clk_get_name(ldb_di0_clk)) ||
+ !strcmp(__clk_get_name(di_parent), __clk_get_name(ldb_di1_clk))) {
+ /* if di clk parent is tve/ldb, then keep it;*/
+ dev_dbg(ipu->dev, "use special clk parent\n");
+ ret = clk_set_parent(ipu->pixel_clk_sel[disp], ipu->di_clk[disp]);
+ if (ret) {
+ dev_err(ipu->dev, "set pixel clk error:%d\n", ret);
+ return ret;
+ }
+ clk_put(ldb_di0_clk);
+ clk_put(ldb_di1_clk);
+ } else {
+ /* try ipu clk first*/
+ dev_dbg(ipu->dev, "try ipu internal clk\n");
+ ret = clk_set_parent(ipu->pixel_clk_sel[disp], ipu->ipu_clk);
+ if (ret) {
+ dev_err(ipu->dev, "set pixel clk error:%d\n", ret);
+ return ret;
+ }
+ rounded_pixel_clk = clk_round_rate(ipu->pixel_clk[disp], pixel_clk);
+ dev_dbg(ipu->dev, "rounded pix clk:%d\n", rounded_pixel_clk);
+ /*
+ * we will only use 1/2 fraction for ipu clk,
+ * so if the clk rate is not fit, try ext clk.
+ */
+ if (!sig.int_clk &&
+ ((rounded_pixel_clk >= pixel_clk + pixel_clk/200) ||
+ (rounded_pixel_clk <= pixel_clk - pixel_clk/200))) {
+ dev_dbg(ipu->dev, "try ipu ext di clk\n");
+
+ rounded_pixel_clk =
+ clk_round_rate(ipu->di_clk[disp], pixel_clk);
+ ret = clk_set_rate(ipu->di_clk[disp],
+ rounded_pixel_clk);
+ if (ret) {
+ dev_err(ipu->dev,
+ "set di clk rate error:%d\n", ret);
+ return ret;
+ }
+ dev_dbg(ipu->dev, "di clk:%d\n", rounded_pixel_clk);
+ ret = clk_set_parent(ipu->pixel_clk_sel[disp],
+ ipu->di_clk[disp]);
+ if (ret) {
+ dev_err(ipu->dev,
+ "set pixel clk parent error:%d\n", ret);
+ return ret;
+ }
+ }
+ }
+ rounded_pixel_clk = clk_round_rate(ipu->pixel_clk[disp], pixel_clk);
+ if (rounded_pixel_clk == 0) {
+ dev_err(ipu->dev, "rounded pixel clock should not be zero\n");
+ return -EINVAL;
+ }
+ dev_dbg(ipu->dev, "round pixel clk:%d\n", rounded_pixel_clk);
+ ret = clk_set_rate(ipu->pixel_clk[disp], rounded_pixel_clk);
+ if (ret) {
+ dev_err(ipu->dev, "set pixel clk rate error:%d\n", ret);
+ return ret;
+ }
+ msleep(5);
+ /* Get integer portion of divider */
+ div = clk_get_rate(clk_get_parent(ipu->pixel_clk_sel[disp])) / rounded_pixel_clk;
+ dev_dbg(ipu->dev, "div:%d\n", div);
+ if (!div) {
+ dev_err(ipu->dev, "invalid pixel clk div = 0\n");
+ return -EINVAL;
+ }
+
+
+ mutex_lock(&ipu->mutex_lock);
+
+ _ipu_di_data_wave_config(ipu, disp, SYNC_WAVE, div - 1, div - 1);
+ _ipu_di_data_pin_config(ipu, disp, SYNC_WAVE, DI_PIN15, 3, 0, div * 2);
+
+ map = _ipu_pixfmt_to_map(pixel_fmt);
+ if (map < 0) {
+ dev_dbg(ipu->dev, "IPU_DISP: No MAP\n");
+ mutex_unlock(&ipu->mutex_lock);
+ return -EINVAL;
+ }
+
+ /*clear DI*/
+ di_gen = ipu_di_read(ipu, disp, DI_GENERAL);
+ di_gen &= (0x3 << 20);
+ ipu_di_write(ipu, disp, di_gen, DI_GENERAL);
+
+ if (sig.interlaced) {
+ if (ipu->devtype >= IPUv3EX) {
+ /* Setup internal HSYNC waveform */
+ _ipu_di_sync_config(ipu,
+ disp, /* display */
+ 1, /* counter */
+ h_total/2 - 1, /* run count */
+ DI_SYNC_CLK, /* run_resolution */
+ 0, /* offset */
+ DI_SYNC_NONE, /* offset resolution */
+ 0, /* repeat count */
+ DI_SYNC_NONE, /* CNT_CLR_SEL */
+ 0, /* CNT_POLARITY_GEN_EN */
+ DI_SYNC_NONE, /* CNT_POLARITY_CLR_SEL */
+ DI_SYNC_NONE, /* CNT_POLARITY_TRIGGER_SEL */
+ 0, /* COUNT UP */
+ 0 /* COUNT DOWN */
+ );
+
+ /* Field 1 VSYNC waveform */
+ _ipu_di_sync_config(ipu,
+ disp, /* display */
+ 2, /* counter */
+ h_total - 1, /* run count */
+ DI_SYNC_CLK, /* run_resolution */
+ 0, /* offset */
+ DI_SYNC_NONE, /* offset resolution */
+ 0, /* repeat count */
+ DI_SYNC_NONE, /* CNT_CLR_SEL */
+ 0, /* CNT_POLARITY_GEN_EN */
+ DI_SYNC_NONE, /* CNT_POLARITY_CLR_SEL */
+ DI_SYNC_NONE, /* CNT_POLARITY_TRIGGER_SEL */
+ 0, /* COUNT UP */
+ 2*div /* COUNT DOWN */
+ );
+
+ /* Setup internal HSYNC waveform */
+ _ipu_di_sync_config(ipu,
+ disp, /* display */
+ 3, /* counter */
+ v_total*2 - 1, /* run count */
+ DI_SYNC_INT_HSYNC, /* run_resolution */
+ 1, /* offset */
+ DI_SYNC_INT_HSYNC, /* offset resolution */
+ 0, /* repeat count */
+ DI_SYNC_NONE, /* CNT_CLR_SEL */
+ 0, /* CNT_POLARITY_GEN_EN */
+ DI_SYNC_NONE, /* CNT_POLARITY_CLR_SEL */
+ DI_SYNC_NONE, /* CNT_POLARITY_TRIGGER_SEL */
+ 0, /* COUNT UP */
+ 2*div /* COUNT DOWN */
+ );
+
+ /* Active Field ? */
+ _ipu_di_sync_config(ipu,
+ disp, /* display */
+ 4, /* counter */
+ v_total/2 - 1, /* run count */
+ DI_SYNC_HSYNC, /* run_resolution */
+ v_start_width, /* offset */
+ DI_SYNC_HSYNC, /* offset resolution */
+ 2, /* repeat count */
+ DI_SYNC_VSYNC, /* CNT_CLR_SEL */
+ 0, /* CNT_POLARITY_GEN_EN */
+ DI_SYNC_NONE, /* CNT_POLARITY_CLR_SEL */
+ DI_SYNC_NONE, /* CNT_POLARITY_TRIGGER_SEL */
+ 0, /* COUNT UP */
+ 0 /* COUNT DOWN */
+ );
+
+ /* Active Line */
+ _ipu_di_sync_config(ipu,
+ disp, /* display */
+ 5, /* counter */
+ 0, /* run count */
+ DI_SYNC_HSYNC, /* run_resolution */
+ 0, /* offset */
+ DI_SYNC_NONE, /* offset resolution */
+ height/2, /* repeat count */
+ 4, /* CNT_CLR_SEL */
+ 0, /* CNT_POLARITY_GEN_EN */
+ DI_SYNC_NONE, /* CNT_POLARITY_CLR_SEL */
+ DI_SYNC_NONE, /* CNT_POLARITY_TRIGGER_SEL */
+ 0, /* COUNT UP */
+ 0 /* COUNT DOWN */
+ );
+
+ /* Field 0 VSYNC waveform */
+ _ipu_di_sync_config(ipu,
+ disp, /* display */
+ 6, /* counter */
+ v_total - 1, /* run count */
+ DI_SYNC_HSYNC, /* run_resolution */
+ 0, /* offset */
+ DI_SYNC_NONE, /* offset resolution */
+ 0, /* repeat count */
+ DI_SYNC_NONE, /* CNT_CLR_SEL */
+ 0, /* CNT_POLARITY_GEN_EN */
+ DI_SYNC_NONE, /* CNT_POLARITY_CLR_SEL */
+ DI_SYNC_NONE, /* CNT_POLARITY_TRIGGER_SEL */
+ 0, /* COUNT UP */
+ 0 /* COUNT DOWN */
+ );
+
+ /* DC VSYNC waveform */
+ vsync_cnt = 7;
+ _ipu_di_sync_config(ipu,
+ disp, /* display */
+ 7, /* counter */
+ v_total/2 - 1, /* run count */
+ DI_SYNC_HSYNC, /* run_resolution */
+ 9, /* offset */
+ DI_SYNC_HSYNC, /* offset resolution */
+ 2, /* repeat count */
+ DI_SYNC_VSYNC, /* CNT_CLR_SEL */
+ 0, /* CNT_POLARITY_GEN_EN */
+ DI_SYNC_NONE, /* CNT_POLARITY_CLR_SEL */
+ DI_SYNC_NONE, /* CNT_POLARITY_TRIGGER_SEL */
+ 0, /* COUNT UP */
+ 0 /* COUNT DOWN */
+ );
+
+ /* active pixel waveform */
+ _ipu_di_sync_config(ipu,
+ disp, /* display */
+ 8, /* counter */
+ 0, /* run count */
+ DI_SYNC_CLK, /* run_resolution */
+ h_start_width, /* offset */
+ DI_SYNC_CLK, /* offset resolution */
+ width, /* repeat count */
+ 5, /* CNT_CLR_SEL */
+ 0, /* CNT_POLARITY_GEN_EN */
+ DI_SYNC_NONE, /* CNT_POLARITY_CLR_SEL */
+ DI_SYNC_NONE, /* CNT_POLARITY_TRIGGER_SEL */
+ 0, /* COUNT UP */
+ 0 /* COUNT DOWN */
+ );
+
+ /* Second VSYNC */
+ _ipu_di_sync_config(ipu,
+ disp, /* display */
+ 9, /* counter */
+ v_total - 1, /* run count */
+ DI_SYNC_INT_HSYNC, /* run_resolution */
+ v_total/2, /* offset */
+ DI_SYNC_INT_HSYNC, /* offset resolution */
+ 0, /* repeat count */
+ DI_SYNC_HSYNC, /* CNT_CLR_SEL */
+ 0, /* CNT_POLARITY_GEN_EN */
+ DI_SYNC_NONE, /* CNT_POLARITY_CLR_SEL */
+ DI_SYNC_NONE, /* CNT_POLARITY_TRIGGER_SEL */
+ 0, /* COUNT UP */
+ 2*div /* COUNT DOWN */
+ );
+
+ /* set gentime select and tag sel */
+ reg = ipu_di_read(ipu, disp, DI_SW_GEN1(9));
+ reg &= 0x1FFFFFFF;
+ reg |= (3-1)<<29 | 0x00008000;
+ ipu_di_write(ipu, disp, reg, DI_SW_GEN1(9));
+
+ ipu_di_write(ipu, disp, v_total / 2 - 1, DI_SCR_CONF);
+
+ /* set y_sel = 1 */
+ di_gen |= 0x10000000;
+ di_gen |= DI_GEN_POLARITY_5;
+ di_gen |= DI_GEN_POLARITY_8;
+ } else {
+ /* Setup internal HSYNC waveform */
+ _ipu_di_sync_config(ipu, disp, 1, h_total - 1, DI_SYNC_CLK,
+ 0, DI_SYNC_NONE, 0, DI_SYNC_NONE, 0, DI_SYNC_NONE,
+ DI_SYNC_NONE, 0, 0);
+
+ field1_offset = v_sync_width + v_start_width + height / 2 +
+ v_end_width;
+ if (sig.odd_field_first) {
+ field0_offset = field1_offset - 1;
+ field1_offset = 0;
+ }
+ v_total += v_start_width + v_end_width;
+
+ /* Field 1 VSYNC waveform */
+ _ipu_di_sync_config(ipu, disp, 2, v_total - 1, 1,
+ field0_offset,
+ field0_offset ? 1 : DI_SYNC_NONE,
+ 0, DI_SYNC_NONE, 0,
+ DI_SYNC_NONE, DI_SYNC_NONE, 0, 4);
+
+ /* Setup internal HSYNC waveform */
+ _ipu_di_sync_config(ipu, disp, 3, h_total - 1, DI_SYNC_CLK,
+ 0, DI_SYNC_NONE, 0, DI_SYNC_NONE, 0,
+ DI_SYNC_NONE, DI_SYNC_NONE, 0, 4);
+
+ /* Active Field ? */
+ _ipu_di_sync_config(ipu, disp, 4,
+ field0_offset ?
+ field0_offset : field1_offset - 2,
+ 1, v_start_width + v_sync_width, 1, 2, 2,
+ 0, DI_SYNC_NONE, DI_SYNC_NONE, 0, 0);
+
+ /* Active Line */
+ _ipu_di_sync_config(ipu, disp, 5, 0, 1,
+ 0, DI_SYNC_NONE,
+ height / 2, 4, 0, DI_SYNC_NONE,
+ DI_SYNC_NONE, 0, 0);
+
+ /* Field 0 VSYNC waveform */
+ _ipu_di_sync_config(ipu, disp, 6, v_total - 1, 1,
+ 0, DI_SYNC_NONE,
+ 0, DI_SYNC_NONE, 0, DI_SYNC_NONE,
+ DI_SYNC_NONE, 0, 0);
+
+ /* DC VSYNC waveform */
+ vsync_cnt = 7;
+ _ipu_di_sync_config(ipu, disp, 7, 0, 1,
+ field1_offset,
+ field1_offset ? 1 : DI_SYNC_NONE,
+ 1, 2, 0, DI_SYNC_NONE, DI_SYNC_NONE, 0, 0);
+
+ /* active pixel waveform */
+ _ipu_di_sync_config(ipu, disp, 8, 0, DI_SYNC_CLK,
+ h_sync_width + h_start_width, DI_SYNC_CLK,
+ width, 5, 0, DI_SYNC_NONE, DI_SYNC_NONE,
+ 0, 0);
+
+ /* ??? */
+ _ipu_di_sync_config(ipu, disp, 9, v_total - 1, 2,
+ 0, DI_SYNC_NONE,
+ 0, DI_SYNC_NONE, 6, DI_SYNC_NONE,
+ DI_SYNC_NONE, 0, 0);
+
+ reg = ipu_di_read(ipu, disp, DI_SW_GEN1(9));
+ reg |= 0x8000;
+ ipu_di_write(ipu, disp, reg, DI_SW_GEN1(9));
+
+ ipu_di_write(ipu, disp, v_sync_width + v_start_width +
+ v_end_width + height / 2 - 1, DI_SCR_CONF);
+ }
+
+ /* Init template microcode */
+ _ipu_dc_write_tmpl(ipu, 0, WROD(0), 0, map, SYNC_WAVE, 0, 8, 1);
+
+ if (sig.Hsync_pol)
+ di_gen |= DI_GEN_POLARITY_3;
+ if (sig.Vsync_pol)
+ di_gen |= DI_GEN_POLARITY_2;
+ } else {
+ /* Setup internal HSYNC waveform */
+ _ipu_di_sync_config(ipu, disp, 1, h_total - 1, DI_SYNC_CLK,
+ 0, DI_SYNC_NONE, 0, DI_SYNC_NONE, 0, DI_SYNC_NONE,
+ DI_SYNC_NONE, 0, 0);
+
+ /* Setup external (delayed) HSYNC waveform */
+ _ipu_di_sync_config(ipu, disp, DI_SYNC_HSYNC, h_total - 1,
+ DI_SYNC_CLK, div * v_to_h_sync, DI_SYNC_CLK,
+ 0, DI_SYNC_NONE, 1, DI_SYNC_NONE,
+ DI_SYNC_CLK, 0, h_sync_width * 2);
+ /* Setup VSYNC waveform */
+ vsync_cnt = DI_SYNC_VSYNC;
+ _ipu_di_sync_config(ipu, disp, DI_SYNC_VSYNC, v_total - 1,
+ DI_SYNC_INT_HSYNC, 0, DI_SYNC_NONE, 0,
+ DI_SYNC_NONE, 1, DI_SYNC_NONE,
+ DI_SYNC_INT_HSYNC, 0, v_sync_width * 2);
+ ipu_di_write(ipu, disp, v_total - 1, DI_SCR_CONF);
+
+ /* Setup active data waveform to sync with DC */
+ _ipu_di_sync_config(ipu, disp, 4, 0, DI_SYNC_HSYNC,
+ v_sync_width + v_start_width, DI_SYNC_HSYNC, height,
+ DI_SYNC_VSYNC, 0, DI_SYNC_NONE,
+ DI_SYNC_NONE, 0, 0);
+ _ipu_di_sync_config(ipu, disp, 5, 0, DI_SYNC_CLK,
+ h_sync_width + h_start_width, DI_SYNC_CLK,
+ width, 4, 0, DI_SYNC_NONE, DI_SYNC_NONE, 0,
+ 0);
+
+ /* set VGA delayed hsync/vsync no matter VGA enabled */
+ if (disp) {
+ /* couter 7 for VGA delay HSYNC */
+ _ipu_di_sync_config(ipu, disp, 7,
+ h_total - 1, DI_SYNC_CLK,
+ 18, DI_SYNC_CLK,
+ 0, DI_SYNC_NONE,
+ 1, DI_SYNC_NONE, DI_SYNC_CLK,
+ 0, h_sync_width * 2);
+
+ /* couter 8 for VGA delay VSYNC */
+ _ipu_di_sync_config(ipu, disp, 8,
+ v_total - 1, DI_SYNC_INT_HSYNC,
+ 1, DI_SYNC_INT_HSYNC,
+ 0, DI_SYNC_NONE,
+ 1, DI_SYNC_NONE, DI_SYNC_INT_HSYNC,
+ 0, v_sync_width * 2);
+ }
+
+ /* reset all unused counters */
+ ipu_di_write(ipu, disp, 0, DI_SW_GEN0(6));
+ ipu_di_write(ipu, disp, 0, DI_SW_GEN1(6));
+ if (!disp) {
+ ipu_di_write(ipu, disp, 0, DI_SW_GEN0(7));
+ ipu_di_write(ipu, disp, 0, DI_SW_GEN1(7));
+ ipu_di_write(ipu, disp, 0, DI_STP_REP(7));
+ ipu_di_write(ipu, disp, 0, DI_SW_GEN0(8));
+ ipu_di_write(ipu, disp, 0, DI_SW_GEN1(8));
+ ipu_di_write(ipu, disp, 0, DI_STP_REP(8));
+ }
+ ipu_di_write(ipu, disp, 0, DI_SW_GEN0(9));
+ ipu_di_write(ipu, disp, 0, DI_SW_GEN1(9));
+ ipu_di_write(ipu, disp, 0, DI_STP_REP(9));
+
+ reg = ipu_di_read(ipu, disp, DI_STP_REP(6));
+ reg &= 0x0000FFFF;
+ ipu_di_write(ipu, disp, reg, DI_STP_REP(6));
+
+ /* Init template microcode */
+ if (disp) {
+ if ((pixel_fmt == IPU_PIX_FMT_YUYV) ||
+ (pixel_fmt == IPU_PIX_FMT_UYVY) ||
+ (pixel_fmt == IPU_PIX_FMT_YVYU) ||
+ (pixel_fmt == IPU_PIX_FMT_VYUY)) {
+ _ipu_dc_write_tmpl(ipu, 8, WROD(0), 0, (map - 1), SYNC_WAVE, 0, 5, 1);
+ _ipu_dc_write_tmpl(ipu, 9, WROD(0), 0, map, SYNC_WAVE, 0, 5, 1);
+ /* configure user events according to DISP NUM */
+ ipu_dc_write(ipu, (width - 1), DC_UGDE_3(disp));
+ }
+ _ipu_dc_write_tmpl(ipu, 2, WROD(0), 0, map, SYNC_WAVE, 8, 5, 1);
+ _ipu_dc_write_tmpl(ipu, 3, WROD(0), 0, map, SYNC_WAVE, 4, 5, 0);
+ _ipu_dc_write_tmpl(ipu, 4, WRG, 0, map, NULL_WAVE, 0, 0, 1);
+ _ipu_dc_write_tmpl(ipu, 1, WROD(0), 0, map, SYNC_WAVE, 0, 5, 1);
+
+ } else {
+ if ((pixel_fmt == IPU_PIX_FMT_YUYV) ||
+ (pixel_fmt == IPU_PIX_FMT_UYVY) ||
+ (pixel_fmt == IPU_PIX_FMT_YVYU) ||
+ (pixel_fmt == IPU_PIX_FMT_VYUY)) {
+ _ipu_dc_write_tmpl(ipu, 10, WROD(0), 0, (map - 1), SYNC_WAVE, 0, 5, 1);
+ _ipu_dc_write_tmpl(ipu, 11, WROD(0), 0, map, SYNC_WAVE, 0, 5, 1);
+ /* configure user events according to DISP NUM */
+ ipu_dc_write(ipu, width - 1, DC_UGDE_3(disp));
+ }
+ _ipu_dc_write_tmpl(ipu, 5, WROD(0), 0, map, SYNC_WAVE, 8, 5, 1);
+ _ipu_dc_write_tmpl(ipu, 6, WROD(0), 0, map, SYNC_WAVE, 4, 5, 0);
+ _ipu_dc_write_tmpl(ipu, 7, WRG, 0, map, NULL_WAVE, 0, 0, 1);
+ _ipu_dc_write_tmpl(ipu, 12, WROD(0), 0, map, SYNC_WAVE, 0, 5, 1);
+ }
+
+ if (sig.Hsync_pol) {
+ di_gen |= DI_GEN_POLARITY_2;
+ if (disp)
+ di_gen |= DI_GEN_POLARITY_7;
+ }
+ if (sig.Vsync_pol) {
+ di_gen |= DI_GEN_POLARITY_3;
+ if (disp)
+ di_gen |= DI_GEN_POLARITY_8;
+ }
+ }
+ /* changinc DISP_CLK polarity: it can be wrong for some applications */
+ if ((pixel_fmt == IPU_PIX_FMT_YUYV) ||
+ (pixel_fmt == IPU_PIX_FMT_UYVY) ||
+ (pixel_fmt == IPU_PIX_FMT_YVYU) ||
+ (pixel_fmt == IPU_PIX_FMT_VYUY))
+ di_gen |= 0x00020000;
+
+ if (!sig.clk_pol)
+ di_gen |= DI_GEN_POLARITY_DISP_CLK;
+ else
+ di_gen &= ~DI_GEN_POLARITY_DISP_CLK;
+
+ ipu_di_write(ipu, disp, di_gen, DI_GENERAL);
+
+ ipu_di_write(ipu, disp, (--vsync_cnt << DI_VSYNC_SEL_OFFSET) |
+ 0x00000002, DI_SYNC_AS_GEN);
+ reg = ipu_di_read(ipu, disp, DI_POL);
+ reg &= ~(DI_POL_DRDY_DATA_POLARITY | DI_POL_DRDY_POLARITY_15);
+ if (sig.enable_pol)
+ reg |= DI_POL_DRDY_POLARITY_15;
+ if (sig.data_pol)
+ reg |= DI_POL_DRDY_DATA_POLARITY;
+ ipu_di_write(ipu, disp, reg, DI_POL);
+
+ ipu_dc_write(ipu, width, DC_DISP_CONF2(DC_DISP_ID_SYNC(disp)));
+
+ mutex_unlock(&ipu->mutex_lock);
+
+ return 0;
+}
+EXPORT_SYMBOL(ipu_init_sync_panel);
+
+void ipu_uninit_sync_panel(struct ipu_soc *ipu, int disp)
+{
+ uint32_t reg;
+ uint32_t di_gen;
+
+ if (disp != 0 && disp != 1)
+ return;
+
+ mutex_lock(&ipu->mutex_lock);
+
+ di_gen = ipu_di_read(ipu, disp, DI_GENERAL);
+ di_gen |= 0x3ff | DI_GEN_POLARITY_DISP_CLK;
+ ipu_di_write(ipu, disp, di_gen, DI_GENERAL);
+
+ reg = ipu_di_read(ipu, disp, DI_POL);
+ reg |= 0x3ffffff;
+ ipu_di_write(ipu, disp, reg, DI_POL);
+
+ mutex_unlock(&ipu->mutex_lock);
+}
+EXPORT_SYMBOL(ipu_uninit_sync_panel);
+
+int ipu_init_async_panel(struct ipu_soc *ipu, int disp, int type, uint32_t cycle_time,
+ uint32_t pixel_fmt, ipu_adc_sig_cfg_t sig)
+{
+ int map;
+ u32 ser_conf = 0;
+ u32 div;
+ u32 di_clk = clk_get_rate(ipu->ipu_clk);
+
+ if (di_clk == 0) {
+ dev_err(ipu->dev, "di clock rate should not be zero\n");
+ return -EINVAL;
+ }
+
+ /* round up cycle_time, then calcalate the divider using scaled math */
+ cycle_time += (1000000000UL / di_clk) - 1;
+ div = (cycle_time * (di_clk / 256UL)) / (1000000000UL / 256UL);
+
+ map = _ipu_pixfmt_to_map(pixel_fmt);
+ if (map < 0)
+ return -EINVAL;
+
+ mutex_lock(&ipu->mutex_lock);
+
+ if (type == IPU_PANEL_SERIAL) {
+ ipu_di_write(ipu, disp, (div << 24) | ((sig.ifc_width - 1) << 4),
+ DI_DW_GEN(ASYNC_SER_WAVE));
+
+ _ipu_di_data_pin_config(ipu, disp, ASYNC_SER_WAVE, DI_PIN_CS,
+ 0, 0, (div * 2) + 1);
+ _ipu_di_data_pin_config(ipu, disp, ASYNC_SER_WAVE, DI_PIN_SER_CLK,
+ 1, div, div * 2);
+ _ipu_di_data_pin_config(ipu, disp, ASYNC_SER_WAVE, DI_PIN_SER_RS,
+ 2, 0, 0);
+
+ _ipu_dc_write_tmpl(ipu, 0x64, WROD(0), 0, map, ASYNC_SER_WAVE, 0, 0, 1);
+
+ /* Configure DC for serial panel */
+ ipu_dc_write(ipu, 0x14, DC_DISP_CONF1(DC_DISP_ID_SERIAL));
+
+ if (sig.clk_pol)
+ ser_conf |= DI_SER_CONF_SERIAL_CLK_POL;
+ if (sig.data_pol)
+ ser_conf |= DI_SER_CONF_SERIAL_DATA_POL;
+ if (sig.rs_pol)
+ ser_conf |= DI_SER_CONF_SERIAL_RS_POL;
+ if (sig.cs_pol)
+ ser_conf |= DI_SER_CONF_SERIAL_CS_POL;
+ ipu_di_write(ipu, disp, ser_conf, DI_SER_CONF);
+ }
+
+ mutex_unlock(&ipu->mutex_lock);
+ return 0;
+}
+EXPORT_SYMBOL(ipu_init_async_panel);
+
+/*!
+ * This function sets the foreground and background plane global alpha blending
+ * modes. This function also sets the DP graphic plane according to the
+ * parameter of IPUv3 DP channel.
+ *
+ * @param ipu ipu handler
+ * @param channel IPUv3 DP channel
+ *
+ * @param enable Boolean to enable or disable global alpha
+ * blending. If disabled, local blending is used.
+ *
+ * @param alpha Global alpha value.
+ *
+ * @return Returns 0 on success or negative error code on fail
+ */
+int32_t ipu_disp_set_global_alpha(struct ipu_soc *ipu, ipu_channel_t channel,
+ bool enable, uint8_t alpha)
+{
+ uint32_t reg;
+ uint32_t flow;
+ bool bg_chan;
+
+ if (channel == MEM_BG_SYNC || channel == MEM_FG_SYNC)
+ flow = DP_SYNC;
+ else if (channel == MEM_BG_ASYNC0 || channel == MEM_FG_ASYNC0)
+ flow = DP_ASYNC0;
+ else if (channel == MEM_BG_ASYNC1 || channel == MEM_FG_ASYNC1)
+ flow = DP_ASYNC1;
+ else
+ return -EINVAL;
+
+ if (channel == MEM_BG_SYNC || channel == MEM_BG_ASYNC0 ||
+ channel == MEM_BG_ASYNC1)
+ bg_chan = true;
+ else
+ bg_chan = false;
+
+ _ipu_get(ipu);
+
+ mutex_lock(&ipu->mutex_lock);
+
+ if (bg_chan) {
+ reg = ipu_dp_read(ipu, DP_COM_CONF(flow));
+ ipu_dp_write(ipu, reg & ~DP_COM_CONF_GWSEL, DP_COM_CONF(flow));
+ } else {
+ reg = ipu_dp_read(ipu, DP_COM_CONF(flow));
+ ipu_dp_write(ipu, reg | DP_COM_CONF_GWSEL, DP_COM_CONF(flow));
+ }
+
+ if (enable) {
+ reg = ipu_dp_read(ipu, DP_GRAPH_WIND_CTRL(flow)) & 0x00FFFFFFL;
+ ipu_dp_write(ipu, reg | ((uint32_t) alpha << 24),
+ DP_GRAPH_WIND_CTRL(flow));
+
+ reg = ipu_dp_read(ipu, DP_COM_CONF(flow));
+ ipu_dp_write(ipu, reg | DP_COM_CONF_GWAM, DP_COM_CONF(flow));
+ } else {
+ reg = ipu_dp_read(ipu, DP_COM_CONF(flow));
+ ipu_dp_write(ipu, reg & ~DP_COM_CONF_GWAM, DP_COM_CONF(flow));
+ }
+
+ reg = ipu_cm_read(ipu, IPU_SRM_PRI2) | 0x8;
+ ipu_cm_write(ipu, reg, IPU_SRM_PRI2);
+
+ mutex_unlock(&ipu->mutex_lock);
+
+ _ipu_put(ipu);
+
+ return 0;
+}
+EXPORT_SYMBOL(ipu_disp_set_global_alpha);
+
+/*!
+ * This function sets the transparent color key for SDC graphic plane.
+ *
+ * @param ipu ipu handler
+ * @param channel Input parameter for the logical channel ID.
+ *
+ * @param enable Boolean to enable or disable color key
+ *
+ * @param colorKey 24-bit RGB color for transparent color key.
+ *
+ * @return Returns 0 on success or negative error code on fail
+ */
+int32_t ipu_disp_set_color_key(struct ipu_soc *ipu, ipu_channel_t channel,
+ bool enable, uint32_t color_key)
+{
+ uint32_t reg, flow;
+ int y, u, v;
+ int red, green, blue;
+
+ if (channel == MEM_BG_SYNC || channel == MEM_FG_SYNC)
+ flow = DP_SYNC;
+ else if (channel == MEM_BG_ASYNC0 || channel == MEM_FG_ASYNC0)
+ flow = DP_ASYNC0;
+ else if (channel == MEM_BG_ASYNC1 || channel == MEM_FG_ASYNC1)
+ flow = DP_ASYNC1;
+ else
+ return -EINVAL;
+
+ _ipu_get(ipu);
+
+ mutex_lock(&ipu->mutex_lock);
+
+ ipu->color_key_4rgb = true;
+ /* Transform color key from rgb to yuv if CSC is enabled */
+ if (((ipu->fg_csc_type == RGB2YUV) && (ipu->bg_csc_type == YUV2YUV)) ||
+ ((ipu->fg_csc_type == YUV2YUV) && (ipu->bg_csc_type == RGB2YUV)) ||
+ ((ipu->fg_csc_type == YUV2YUV) && (ipu->bg_csc_type == YUV2YUV)) ||
+ ((ipu->fg_csc_type == YUV2RGB) && (ipu->bg_csc_type == YUV2RGB))) {
+
+ dev_dbg(ipu->dev, "color key 0x%x need change to yuv fmt\n", color_key);
+
+ red = (color_key >> 16) & 0xFF;
+ green = (color_key >> 8) & 0xFF;
+ blue = color_key & 0xFF;
+
+ y = _rgb_to_yuv(0, red, green, blue);
+ u = _rgb_to_yuv(1, red, green, blue);
+ v = _rgb_to_yuv(2, red, green, blue);
+ color_key = (y << 16) | (u << 8) | v;
+
+ ipu->color_key_4rgb = false;
+
+ dev_dbg(ipu->dev, "color key change to yuv fmt 0x%x\n", color_key);
+ }
+
+ if (enable) {
+ reg = ipu_dp_read(ipu, DP_GRAPH_WIND_CTRL(flow)) & 0xFF000000L;
+ ipu_dp_write(ipu, reg | color_key, DP_GRAPH_WIND_CTRL(flow));
+
+ reg = ipu_dp_read(ipu, DP_COM_CONF(flow));
+ ipu_dp_write(ipu, reg | DP_COM_CONF_GWCKE, DP_COM_CONF(flow));
+ } else {
+ reg = ipu_dp_read(ipu, DP_COM_CONF(flow));
+ ipu_dp_write(ipu, reg & ~DP_COM_CONF_GWCKE, DP_COM_CONF(flow));
+ }
+
+ reg = ipu_cm_read(ipu, IPU_SRM_PRI2) | 0x8;
+ ipu_cm_write(ipu, reg, IPU_SRM_PRI2);
+
+ mutex_unlock(&ipu->mutex_lock);
+
+ _ipu_put(ipu);
+
+ return 0;
+}
+EXPORT_SYMBOL(ipu_disp_set_color_key);
+
+/*!
+ * This function sets the gamma correction for DP output.
+ *
+ * @param ipu ipu handler
+ * @param channel Input parameter for the logical channel ID.
+ *
+ * @param enable Boolean to enable or disable gamma correction.
+ *
+ * @param constk Gamma piecewise linear approximation constk coeff.
+ *
+ * @param slopek Gamma piecewise linear approximation slopek coeff.
+ *
+ * @return Returns 0 on success or negative error code on fail
+ */
+int32_t ipu_disp_set_gamma_correction(struct ipu_soc *ipu, ipu_channel_t channel, bool enable, int constk[], int slopek[])
+{
+ uint32_t reg, flow, i;
+
+ if (channel == MEM_BG_SYNC || channel == MEM_FG_SYNC)
+ flow = DP_SYNC;
+ else if (channel == MEM_BG_ASYNC0 || channel == MEM_FG_ASYNC0)
+ flow = DP_ASYNC0;
+ else if (channel == MEM_BG_ASYNC1 || channel == MEM_FG_ASYNC1)
+ flow = DP_ASYNC1;
+ else
+ return -EINVAL;
+
+ _ipu_get(ipu);
+
+ mutex_lock(&ipu->mutex_lock);
+
+ for (i = 0; i < 8; i++)
+ ipu_dp_write(ipu, (constk[2*i] & 0x1ff) | ((constk[2*i+1] & 0x1ff) << 16), DP_GAMMA_C(flow, i));
+ for (i = 0; i < 4; i++)
+ ipu_dp_write(ipu, (slopek[4*i] & 0xff) | ((slopek[4*i+1] & 0xff) << 8) |
+ ((slopek[4*i+2] & 0xff) << 16) | ((slopek[4*i+3] & 0xff) << 24), DP_GAMMA_S(flow, i));
+
+ reg = ipu_dp_read(ipu, DP_COM_CONF(flow));
+ if (enable) {
+ if ((ipu->bg_csc_type == RGB2YUV) || (ipu->bg_csc_type == YUV2YUV))
+ reg |= DP_COM_CONF_GAMMA_YUV_EN;
+ else
+ reg &= ~DP_COM_CONF_GAMMA_YUV_EN;
+ ipu_dp_write(ipu, reg | DP_COM_CONF_GAMMA_EN, DP_COM_CONF(flow));
+ } else
+ ipu_dp_write(ipu, reg & ~DP_COM_CONF_GAMMA_EN, DP_COM_CONF(flow));
+
+ reg = ipu_cm_read(ipu, IPU_SRM_PRI2) | 0x8;
+ ipu_cm_write(ipu, reg, IPU_SRM_PRI2);
+
+ mutex_unlock(&ipu->mutex_lock);
+
+ _ipu_put(ipu);
+
+ return 0;
+}
+EXPORT_SYMBOL(ipu_disp_set_gamma_correction);
+
+/*!
+ * This function sets the window position of the foreground or background plane.
+ * modes.
+ *
+ * @param ipu ipu handler
+ * @param channel Input parameter for the logical channel ID.
+ *
+ * @param x_pos The X coordinate position to place window at.
+ * The position is relative to the top left corner.
+ *
+ * @param y_pos The Y coordinate position to place window at.
+ * The position is relative to the top left corner.
+ *
+ * @return Returns 0 on success or negative error code on fail
+ */
+int32_t _ipu_disp_set_window_pos(struct ipu_soc *ipu, ipu_channel_t channel,
+ int16_t x_pos, int16_t y_pos)
+{
+ u32 reg;
+ uint32_t flow = 0;
+ uint32_t dp_srm_shift;
+
+ if ((channel == MEM_FG_SYNC) || (channel == MEM_BG_SYNC)) {
+ flow = DP_SYNC;
+ dp_srm_shift = 3;
+ } else if (channel == MEM_FG_ASYNC0) {
+ flow = DP_ASYNC0;
+ dp_srm_shift = 5;
+ } else if (channel == MEM_FG_ASYNC1) {
+ flow = DP_ASYNC1;
+ dp_srm_shift = 7;
+ } else
+ return -EINVAL;
+
+ ipu_dp_write(ipu, (x_pos << 16) | y_pos, DP_FG_POS(flow));
+
+ if (ipu_is_channel_busy(ipu, channel)) {
+ /* controled by FSU if channel enabled */
+ reg = ipu_cm_read(ipu, IPU_SRM_PRI2) & (~(0x3 << dp_srm_shift));
+ reg |= (0x1 << dp_srm_shift);
+ ipu_cm_write(ipu, reg, IPU_SRM_PRI2);
+ } else {
+ /* disable auto swap, controled by MCU if channel disabled */
+ reg = ipu_cm_read(ipu, IPU_SRM_PRI2) & (~(0x3 << dp_srm_shift));
+ ipu_cm_write(ipu, reg, IPU_SRM_PRI2);
+ }
+
+ return 0;
+}
+
+int32_t ipu_disp_set_window_pos(struct ipu_soc *ipu, ipu_channel_t channel,
+ int16_t x_pos, int16_t y_pos)
+{
+ int ret;
+
+ _ipu_get(ipu);
+ mutex_lock(&ipu->mutex_lock);
+ ret = _ipu_disp_set_window_pos(ipu, channel, x_pos, y_pos);
+ mutex_unlock(&ipu->mutex_lock);
+ _ipu_put(ipu);
+ return ret;
+}
+EXPORT_SYMBOL(ipu_disp_set_window_pos);
+
+int32_t _ipu_disp_get_window_pos(struct ipu_soc *ipu, ipu_channel_t channel,
+ int16_t *x_pos, int16_t *y_pos)
+{
+ u32 reg;
+ uint32_t flow = 0;
+
+ if (channel == MEM_FG_SYNC)
+ flow = DP_SYNC;
+ else if (channel == MEM_FG_ASYNC0)
+ flow = DP_ASYNC0;
+ else if (channel == MEM_FG_ASYNC1)
+ flow = DP_ASYNC1;
+ else
+ return -EINVAL;
+
+ reg = ipu_dp_read(ipu, DP_FG_POS(flow));
+
+ *x_pos = (reg >> 16) & 0x7FF;
+ *y_pos = reg & 0x7FF;
+
+ return 0;
+}
+int32_t ipu_disp_get_window_pos(struct ipu_soc *ipu, ipu_channel_t channel,
+ int16_t *x_pos, int16_t *y_pos)
+{
+ int ret;
+
+ _ipu_get(ipu);
+ mutex_lock(&ipu->mutex_lock);
+ ret = _ipu_disp_get_window_pos(ipu, channel, x_pos, y_pos);
+ mutex_unlock(&ipu->mutex_lock);
+ _ipu_put(ipu);
+ return ret;
+}
+EXPORT_SYMBOL(ipu_disp_get_window_pos);
+
+void ipu_reset_disp_panel(struct ipu_soc *ipu)
+{
+ uint32_t tmp;
+
+ tmp = ipu_di_read(ipu, 1, DI_GENERAL);
+ ipu_di_write(ipu, 1, tmp | 0x08, DI_GENERAL);
+ msleep(10); /* tRES >= 100us */
+ tmp = ipu_di_read(ipu, 1, DI_GENERAL);
+ ipu_di_write(ipu, 1, tmp & ~0x08, DI_GENERAL);
+ msleep(60);
+
+ return;
+}
+EXPORT_SYMBOL(ipu_reset_disp_panel);
+
+void ipu_disp_init(struct ipu_soc *ipu)
+{
+ ipu->fg_csc_type = ipu->bg_csc_type = CSC_NONE;
+ ipu->color_key_4rgb = true;
+ _ipu_init_dc_mappings(ipu);
+ _ipu_dmfc_init(ipu, DMFC_NORMAL, 1);
+}
diff --git a/drivers/mxc/ipu3/ipu_ic.c b/drivers/mxc/ipu3/ipu_ic.c
new file mode 100644
index 000000000000..29519bd00d12
--- /dev/null
+++ b/drivers/mxc/ipu3/ipu_ic.c
@@ -0,0 +1,924 @@
+/*
+ * Copyright 2005-2015 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/*
+ * @file ipu_ic.c
+ *
+ * @brief IPU IC functions
+ *
+ * @ingroup IPU
+ */
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/ipu-v3.h>
+#include <linux/spinlock.h>
+#include <linux/types.h>
+#include <linux/videodev2.h>
+
+#include "ipu_param_mem.h"
+#include "ipu_regs.h"
+
+enum {
+ IC_TASK_VIEWFINDER,
+ IC_TASK_ENCODER,
+ IC_TASK_POST_PROCESSOR
+};
+
+static void _init_csc(struct ipu_soc *ipu, uint8_t ic_task, ipu_color_space_t in_format,
+ ipu_color_space_t out_format, int csc_index);
+
+static int _calc_resize_coeffs(struct ipu_soc *ipu,
+ uint32_t inSize, uint32_t outSize,
+ uint32_t *resizeCoeff,
+ uint32_t *downsizeCoeff);
+
+void _ipu_vdi_set_top_field_man(struct ipu_soc *ipu, bool top_field_0)
+{
+ uint32_t reg;
+
+ reg = ipu_vdi_read(ipu, VDI_C);
+ if (top_field_0)
+ reg &= ~VDI_C_TOP_FIELD_MAN_1;
+ else
+ reg |= VDI_C_TOP_FIELD_MAN_1;
+ ipu_vdi_write(ipu, reg, VDI_C);
+}
+
+void _ipu_vdi_set_motion(struct ipu_soc *ipu, ipu_motion_sel motion_sel)
+{
+ uint32_t reg;
+
+ reg = ipu_vdi_read(ipu, VDI_C);
+ reg &= ~(VDI_C_MOT_SEL_FULL | VDI_C_MOT_SEL_MED | VDI_C_MOT_SEL_LOW);
+ if (motion_sel == HIGH_MOTION)
+ reg |= VDI_C_MOT_SEL_FULL;
+ else if (motion_sel == MED_MOTION)
+ reg |= VDI_C_MOT_SEL_MED;
+ else
+ reg |= VDI_C_MOT_SEL_LOW;
+
+ ipu_vdi_write(ipu, reg, VDI_C);
+ dev_dbg(ipu->dev, "VDI_C = \t0x%08X\n", reg);
+}
+
+void ic_dump_register(struct ipu_soc *ipu)
+{
+ printk(KERN_DEBUG "IC_CONF = \t0x%08X\n", ipu_ic_read(ipu, IC_CONF));
+ printk(KERN_DEBUG "IC_PRP_ENC_RSC = \t0x%08X\n",
+ ipu_ic_read(ipu, IC_PRP_ENC_RSC));
+ printk(KERN_DEBUG "IC_PRP_VF_RSC = \t0x%08X\n",
+ ipu_ic_read(ipu, IC_PRP_VF_RSC));
+ printk(KERN_DEBUG "IC_PP_RSC = \t0x%08X\n", ipu_ic_read(ipu, IC_PP_RSC));
+ printk(KERN_DEBUG "IC_IDMAC_1 = \t0x%08X\n", ipu_ic_read(ipu, IC_IDMAC_1));
+ printk(KERN_DEBUG "IC_IDMAC_2 = \t0x%08X\n", ipu_ic_read(ipu, IC_IDMAC_2));
+ printk(KERN_DEBUG "IC_IDMAC_3 = \t0x%08X\n", ipu_ic_read(ipu, IC_IDMAC_3));
+}
+
+void _ipu_ic_enable_task(struct ipu_soc *ipu, ipu_channel_t channel)
+{
+ uint32_t ic_conf;
+
+ ic_conf = ipu_ic_read(ipu, IC_CONF);
+ switch (channel) {
+ case CSI_PRP_VF_MEM:
+ case MEM_PRP_VF_MEM:
+ ic_conf |= IC_CONF_PRPVF_EN;
+ break;
+ case MEM_VDI_PRP_VF_MEM:
+ ic_conf |= IC_CONF_PRPVF_EN;
+ break;
+ case MEM_VDI_MEM:
+ ic_conf |= IC_CONF_PRPVF_EN | IC_CONF_RWS_EN ;
+ break;
+ case MEM_ROT_VF_MEM:
+ ic_conf |= IC_CONF_PRPVF_ROT_EN;
+ break;
+ case CSI_PRP_ENC_MEM:
+ case MEM_PRP_ENC_MEM:
+ ic_conf |= IC_CONF_PRPENC_EN;
+ break;
+ case MEM_ROT_ENC_MEM:
+ ic_conf |= IC_CONF_PRPENC_ROT_EN;
+ break;
+ case MEM_PP_MEM:
+ ic_conf |= IC_CONF_PP_EN;
+ break;
+ case MEM_ROT_PP_MEM:
+ ic_conf |= IC_CONF_PP_ROT_EN;
+ break;
+ default:
+ break;
+ }
+ ipu_ic_write(ipu, ic_conf, IC_CONF);
+}
+
+void _ipu_ic_disable_task(struct ipu_soc *ipu, ipu_channel_t channel)
+{
+ uint32_t ic_conf;
+
+ ic_conf = ipu_ic_read(ipu, IC_CONF);
+ switch (channel) {
+ case CSI_PRP_VF_MEM:
+ case MEM_PRP_VF_MEM:
+ ic_conf &= ~IC_CONF_PRPVF_EN;
+ break;
+ case MEM_VDI_PRP_VF_MEM:
+ ic_conf &= ~IC_CONF_PRPVF_EN;
+ break;
+ case MEM_VDI_MEM:
+ ic_conf &= ~(IC_CONF_PRPVF_EN | IC_CONF_RWS_EN);
+ break;
+ case MEM_ROT_VF_MEM:
+ ic_conf &= ~IC_CONF_PRPVF_ROT_EN;
+ break;
+ case CSI_PRP_ENC_MEM:
+ case MEM_PRP_ENC_MEM:
+ ic_conf &= ~IC_CONF_PRPENC_EN;
+ break;
+ case MEM_ROT_ENC_MEM:
+ ic_conf &= ~IC_CONF_PRPENC_ROT_EN;
+ break;
+ case MEM_PP_MEM:
+ ic_conf &= ~IC_CONF_PP_EN;
+ break;
+ case MEM_ROT_PP_MEM:
+ ic_conf &= ~IC_CONF_PP_ROT_EN;
+ break;
+ default:
+ break;
+ }
+ ipu_ic_write(ipu, ic_conf, IC_CONF);
+}
+
+void _ipu_vdi_init(struct ipu_soc *ipu, ipu_channel_t channel, ipu_channel_params_t *params)
+{
+ uint32_t reg;
+ uint32_t pixel_fmt;
+ uint32_t pix_per_burst;
+
+ reg = ((params->mem_prp_vf_mem.in_height-1) << 16) |
+ (params->mem_prp_vf_mem.in_width-1);
+ ipu_vdi_write(ipu, reg, VDI_FSIZE);
+
+ /* Full motion, only vertical filter is used
+ Burst size is 4 accesses */
+ if (params->mem_prp_vf_mem.in_pixel_fmt ==
+ IPU_PIX_FMT_UYVY ||
+ params->mem_prp_vf_mem.in_pixel_fmt ==
+ IPU_PIX_FMT_YUYV) {
+ pixel_fmt = VDI_C_CH_422;
+ pix_per_burst = 32;
+ } else {
+ pixel_fmt = VDI_C_CH_420;
+ pix_per_burst = 64;
+ }
+
+ reg = ipu_vdi_read(ipu, VDI_C);
+ reg |= pixel_fmt;
+ switch (channel) {
+ case MEM_VDI_PRP_VF_MEM:
+ reg |= VDI_C_BURST_SIZE2_4;
+ break;
+ case MEM_VDI_PRP_VF_MEM_P:
+ reg |= VDI_C_BURST_SIZE1_4 | VDI_C_VWM1_SET_1 | VDI_C_VWM1_CLR_2;
+ break;
+ case MEM_VDI_PRP_VF_MEM_N:
+ reg |= VDI_C_BURST_SIZE3_4 | VDI_C_VWM3_SET_1 | VDI_C_VWM3_CLR_2;
+ break;
+
+ case MEM_VDI_MEM:
+ reg |= (((pix_per_burst >> 2) - 1) & VDI_C_BURST_SIZE_MASK)
+ << VDI_C_BURST_SIZE2_OFFSET;
+ break;
+ case MEM_VDI_MEM_P:
+ reg |= (((pix_per_burst >> 2) - 1) & VDI_C_BURST_SIZE_MASK)
+ << VDI_C_BURST_SIZE1_OFFSET;
+ reg |= VDI_C_VWM1_SET_2 | VDI_C_VWM1_CLR_2;
+ break;
+ case MEM_VDI_MEM_N:
+ reg |= (((pix_per_burst >> 2) - 1) & VDI_C_BURST_SIZE_MASK)
+ << VDI_C_BURST_SIZE3_OFFSET;
+ reg |= VDI_C_VWM3_SET_2 | VDI_C_VWM3_CLR_2;
+ break;
+ default:
+ break;
+ }
+ ipu_vdi_write(ipu, reg, VDI_C);
+
+ if (params->mem_prp_vf_mem.field_fmt == IPU_DEINTERLACE_FIELD_TOP)
+ _ipu_vdi_set_top_field_man(ipu, true);
+ else if (params->mem_prp_vf_mem.field_fmt == IPU_DEINTERLACE_FIELD_BOTTOM)
+ _ipu_vdi_set_top_field_man(ipu, false);
+
+ _ipu_vdi_set_motion(ipu, params->mem_prp_vf_mem.motion_sel);
+
+ reg = ipu_ic_read(ipu, IC_CONF);
+ reg &= ~IC_CONF_RWS_EN;
+ ipu_ic_write(ipu, reg, IC_CONF);
+}
+
+void _ipu_vdi_uninit(struct ipu_soc *ipu)
+{
+ ipu_vdi_write(ipu, 0, VDI_FSIZE);
+ ipu_vdi_write(ipu, 0, VDI_C);
+}
+
+int _ipu_ic_init_prpvf(struct ipu_soc *ipu, ipu_channel_params_t *params,
+ bool src_is_csi)
+{
+ uint32_t reg, ic_conf;
+ uint32_t downsizeCoeff, resizeCoeff;
+ ipu_color_space_t in_fmt, out_fmt;
+ int ret = 0;
+
+ /* Setup vertical resizing */
+ if (!params->mem_prp_vf_mem.outv_resize_ratio) {
+ ret = _calc_resize_coeffs(ipu, params->mem_prp_vf_mem.in_height,
+ params->mem_prp_vf_mem.out_height,
+ &resizeCoeff, &downsizeCoeff);
+ if (ret < 0) {
+ dev_err(ipu->dev, "failed to calculate prpvf height "
+ "scaling coefficients\n");
+ return ret;
+ }
+
+ reg = (downsizeCoeff << 30) | (resizeCoeff << 16);
+ } else
+ reg = (params->mem_prp_vf_mem.outv_resize_ratio) << 16;
+
+ /* Setup horizontal resizing */
+ if (!params->mem_prp_vf_mem.outh_resize_ratio) {
+ ret = _calc_resize_coeffs(ipu, params->mem_prp_vf_mem.in_width,
+ params->mem_prp_vf_mem.out_width,
+ &resizeCoeff, &downsizeCoeff);
+ if (ret < 0) {
+ dev_err(ipu->dev, "failed to calculate prpvf width "
+ "scaling coefficients\n");
+ return ret;
+ }
+
+ reg |= (downsizeCoeff << 14) | resizeCoeff;
+ } else
+ reg |= params->mem_prp_vf_mem.outh_resize_ratio;
+
+ ipu_ic_write(ipu, reg, IC_PRP_VF_RSC);
+
+ ic_conf = ipu_ic_read(ipu, IC_CONF);
+
+ /* Setup color space conversion */
+ in_fmt = format_to_colorspace(params->mem_prp_vf_mem.in_pixel_fmt);
+ out_fmt = format_to_colorspace(params->mem_prp_vf_mem.out_pixel_fmt);
+ if (in_fmt == RGB) {
+ if ((out_fmt == YCbCr) || (out_fmt == YUV)) {
+ /* Enable RGB->YCBCR CSC1 */
+ _init_csc(ipu, IC_TASK_VIEWFINDER, RGB, out_fmt, 1);
+ ic_conf |= IC_CONF_PRPVF_CSC1;
+ }
+ }
+ if ((in_fmt == YCbCr) || (in_fmt == YUV)) {
+ if (out_fmt == RGB) {
+ /* Enable YCBCR->RGB CSC1 */
+ _init_csc(ipu, IC_TASK_VIEWFINDER, YCbCr, RGB, 1);
+ ic_conf |= IC_CONF_PRPVF_CSC1;
+ } else {
+ /* TODO: Support YUV<->YCbCr conversion? */
+ }
+ }
+
+ if (params->mem_prp_vf_mem.graphics_combine_en) {
+ ic_conf |= IC_CONF_PRPVF_CMB;
+
+ if (!(ic_conf & IC_CONF_PRPVF_CSC1)) {
+ /* need transparent CSC1 conversion */
+ _init_csc(ipu, IC_TASK_VIEWFINDER, RGB, RGB, 1);
+ ic_conf |= IC_CONF_PRPVF_CSC1; /* Enable RGB->RGB CSC */
+ }
+ in_fmt = format_to_colorspace(params->mem_prp_vf_mem.in_g_pixel_fmt);
+ out_fmt = format_to_colorspace(params->mem_prp_vf_mem.out_pixel_fmt);
+ if (in_fmt == RGB) {
+ if ((out_fmt == YCbCr) || (out_fmt == YUV)) {
+ /* Enable RGB->YCBCR CSC2 */
+ _init_csc(ipu, IC_TASK_VIEWFINDER, RGB, out_fmt, 2);
+ ic_conf |= IC_CONF_PRPVF_CSC2;
+ }
+ }
+ if ((in_fmt == YCbCr) || (in_fmt == YUV)) {
+ if (out_fmt == RGB) {
+ /* Enable YCBCR->RGB CSC2 */
+ _init_csc(ipu, IC_TASK_VIEWFINDER, YCbCr, RGB, 2);
+ ic_conf |= IC_CONF_PRPVF_CSC2;
+ } else {
+ /* TODO: Support YUV<->YCbCr conversion? */
+ }
+ }
+
+ if (params->mem_prp_vf_mem.global_alpha_en) {
+ ic_conf |= IC_CONF_IC_GLB_LOC_A;
+ reg = ipu_ic_read(ipu, IC_CMBP_1);
+ reg &= ~(0xff);
+ reg |= params->mem_prp_vf_mem.alpha;
+ ipu_ic_write(ipu, reg, IC_CMBP_1);
+ } else
+ ic_conf &= ~IC_CONF_IC_GLB_LOC_A;
+
+ if (params->mem_prp_vf_mem.key_color_en) {
+ ic_conf |= IC_CONF_KEY_COLOR_EN;
+ ipu_ic_write(ipu, params->mem_prp_vf_mem.key_color,
+ IC_CMBP_2);
+ } else
+ ic_conf &= ~IC_CONF_KEY_COLOR_EN;
+ } else {
+ ic_conf &= ~IC_CONF_PRPVF_CMB;
+ }
+
+ if (src_is_csi)
+ ic_conf &= ~IC_CONF_RWS_EN;
+ else
+ ic_conf |= IC_CONF_RWS_EN;
+
+ ipu_ic_write(ipu, ic_conf, IC_CONF);
+
+ return ret;
+}
+
+void _ipu_ic_uninit_prpvf(struct ipu_soc *ipu)
+{
+ uint32_t reg;
+
+ reg = ipu_ic_read(ipu, IC_CONF);
+ reg &= ~(IC_CONF_PRPVF_EN | IC_CONF_PRPVF_CMB |
+ IC_CONF_PRPVF_CSC2 | IC_CONF_PRPVF_CSC1);
+ ipu_ic_write(ipu, reg, IC_CONF);
+}
+
+void _ipu_ic_init_rotate_vf(struct ipu_soc *ipu, ipu_channel_params_t *params)
+{
+}
+
+void _ipu_ic_uninit_rotate_vf(struct ipu_soc *ipu)
+{
+ uint32_t reg;
+ reg = ipu_ic_read(ipu, IC_CONF);
+ reg &= ~IC_CONF_PRPVF_ROT_EN;
+ ipu_ic_write(ipu, reg, IC_CONF);
+}
+
+int _ipu_ic_init_prpenc(struct ipu_soc *ipu, ipu_channel_params_t *params,
+ bool src_is_csi)
+{
+ uint32_t reg, ic_conf;
+ uint32_t downsizeCoeff, resizeCoeff;
+ ipu_color_space_t in_fmt, out_fmt;
+ int ret = 0;
+
+ /* Setup vertical resizing */
+ if (!params->mem_prp_enc_mem.outv_resize_ratio) {
+ ret = _calc_resize_coeffs(ipu,
+ params->mem_prp_enc_mem.in_height,
+ params->mem_prp_enc_mem.out_height,
+ &resizeCoeff, &downsizeCoeff);
+ if (ret < 0) {
+ dev_err(ipu->dev, "failed to calculate prpenc height "
+ "scaling coefficients\n");
+ return ret;
+ }
+
+ reg = (downsizeCoeff << 30) | (resizeCoeff << 16);
+ } else
+ reg = (params->mem_prp_enc_mem.outv_resize_ratio) << 16;
+
+ /* Setup horizontal resizing */
+ if (!params->mem_prp_enc_mem.outh_resize_ratio) {
+ ret = _calc_resize_coeffs(ipu, params->mem_prp_enc_mem.in_width,
+ params->mem_prp_enc_mem.out_width,
+ &resizeCoeff, &downsizeCoeff);
+ if (ret < 0) {
+ dev_err(ipu->dev, "failed to calculate prpenc width "
+ "scaling coefficients\n");
+ return ret;
+ }
+
+ reg |= (downsizeCoeff << 14) | resizeCoeff;
+ } else
+ reg |= params->mem_prp_enc_mem.outh_resize_ratio;
+
+ ipu_ic_write(ipu, reg, IC_PRP_ENC_RSC);
+
+ ic_conf = ipu_ic_read(ipu, IC_CONF);
+
+ /* Setup color space conversion */
+ in_fmt = format_to_colorspace(params->mem_prp_enc_mem.in_pixel_fmt);
+ out_fmt = format_to_colorspace(params->mem_prp_enc_mem.out_pixel_fmt);
+ if (in_fmt == RGB) {
+ if ((out_fmt == YCbCr) || (out_fmt == YUV)) {
+ /* Enable RGB->YCBCR CSC1 */
+ _init_csc(ipu, IC_TASK_ENCODER, RGB, out_fmt, 1);
+ ic_conf |= IC_CONF_PRPENC_CSC1;
+ }
+ }
+ if ((in_fmt == YCbCr) || (in_fmt == YUV)) {
+ if (out_fmt == RGB) {
+ /* Enable YCBCR->RGB CSC1 */
+ _init_csc(ipu, IC_TASK_ENCODER, YCbCr, RGB, 1);
+ ic_conf |= IC_CONF_PRPENC_CSC1;
+ } else {
+ /* TODO: Support YUV<->YCbCr conversion? */
+ }
+ }
+
+ if (src_is_csi)
+ ic_conf &= ~IC_CONF_RWS_EN;
+ else
+ ic_conf |= IC_CONF_RWS_EN;
+
+ ipu_ic_write(ipu, ic_conf, IC_CONF);
+
+ return ret;
+}
+
+void _ipu_ic_uninit_prpenc(struct ipu_soc *ipu)
+{
+ uint32_t reg;
+
+ reg = ipu_ic_read(ipu, IC_CONF);
+ reg &= ~(IC_CONF_PRPENC_EN | IC_CONF_PRPENC_CSC1);
+ ipu_ic_write(ipu, reg, IC_CONF);
+}
+
+void _ipu_ic_init_rotate_enc(struct ipu_soc *ipu, ipu_channel_params_t *params)
+{
+}
+
+void _ipu_ic_uninit_rotate_enc(struct ipu_soc *ipu)
+{
+ uint32_t reg;
+
+ reg = ipu_ic_read(ipu, IC_CONF);
+ reg &= ~(IC_CONF_PRPENC_ROT_EN);
+ ipu_ic_write(ipu, reg, IC_CONF);
+}
+
+int _ipu_ic_init_pp(struct ipu_soc *ipu, ipu_channel_params_t *params)
+{
+ uint32_t reg, ic_conf;
+ uint32_t downsizeCoeff, resizeCoeff;
+ ipu_color_space_t in_fmt, out_fmt;
+ int ret = 0;
+
+ /* Setup vertical resizing */
+ if (!params->mem_pp_mem.outv_resize_ratio) {
+ ret = _calc_resize_coeffs(ipu, params->mem_pp_mem.in_height,
+ params->mem_pp_mem.out_height,
+ &resizeCoeff, &downsizeCoeff);
+ if (ret < 0) {
+ dev_err(ipu->dev, "failed to calculate pp height "
+ "scaling coefficients\n");
+ return ret;
+ }
+
+ reg = (downsizeCoeff << 30) | (resizeCoeff << 16);
+ } else {
+ reg = (params->mem_pp_mem.outv_resize_ratio) << 16;
+ }
+
+ /* Setup horizontal resizing */
+ if (!params->mem_pp_mem.outh_resize_ratio) {
+ ret = _calc_resize_coeffs(ipu, params->mem_pp_mem.in_width,
+ params->mem_pp_mem.out_width,
+ &resizeCoeff, &downsizeCoeff);
+ if (ret < 0) {
+ dev_err(ipu->dev, "failed to calculate pp width "
+ "scaling coefficients\n");
+ return ret;
+ }
+
+ reg |= (downsizeCoeff << 14) | resizeCoeff;
+ } else {
+ reg |= params->mem_pp_mem.outh_resize_ratio;
+ }
+
+ ipu_ic_write(ipu, reg, IC_PP_RSC);
+
+ ic_conf = ipu_ic_read(ipu, IC_CONF);
+
+ /* Setup color space conversion */
+ in_fmt = format_to_colorspace(params->mem_pp_mem.in_pixel_fmt);
+ out_fmt = format_to_colorspace(params->mem_pp_mem.out_pixel_fmt);
+ if (in_fmt == RGB) {
+ if ((out_fmt == YCbCr) || (out_fmt == YUV)) {
+ /* Enable RGB->YCBCR CSC1 */
+ _init_csc(ipu, IC_TASK_POST_PROCESSOR, RGB, out_fmt, 1);
+ ic_conf |= IC_CONF_PP_CSC1;
+ }
+ }
+ if ((in_fmt == YCbCr) || (in_fmt == YUV)) {
+ if (out_fmt == RGB) {
+ /* Enable YCBCR->RGB CSC1 */
+ _init_csc(ipu, IC_TASK_POST_PROCESSOR, YCbCr, RGB, 1);
+ ic_conf |= IC_CONF_PP_CSC1;
+ } else {
+ /* TODO: Support YUV<->YCbCr conversion? */
+ }
+ }
+
+ if (params->mem_pp_mem.graphics_combine_en) {
+ ic_conf |= IC_CONF_PP_CMB;
+
+ if (!(ic_conf & IC_CONF_PP_CSC1)) {
+ /* need transparent CSC1 conversion */
+ _init_csc(ipu, IC_TASK_POST_PROCESSOR, RGB, RGB, 1);
+ ic_conf |= IC_CONF_PP_CSC1; /* Enable RGB->RGB CSC */
+ }
+
+ in_fmt = format_to_colorspace(params->mem_pp_mem.in_g_pixel_fmt);
+ out_fmt = format_to_colorspace(params->mem_pp_mem.out_pixel_fmt);
+ if (in_fmt == RGB) {
+ if ((out_fmt == YCbCr) || (out_fmt == YUV)) {
+ /* Enable RGB->YCBCR CSC2 */
+ _init_csc(ipu, IC_TASK_POST_PROCESSOR, RGB, out_fmt, 2);
+ ic_conf |= IC_CONF_PP_CSC2;
+ }
+ }
+ if ((in_fmt == YCbCr) || (in_fmt == YUV)) {
+ if (out_fmt == RGB) {
+ /* Enable YCBCR->RGB CSC2 */
+ _init_csc(ipu, IC_TASK_POST_PROCESSOR, YCbCr, RGB, 2);
+ ic_conf |= IC_CONF_PP_CSC2;
+ } else {
+ /* TODO: Support YUV<->YCbCr conversion? */
+ }
+ }
+
+ if (params->mem_pp_mem.global_alpha_en) {
+ ic_conf |= IC_CONF_IC_GLB_LOC_A;
+ reg = ipu_ic_read(ipu, IC_CMBP_1);
+ reg &= ~(0xff00);
+ reg |= (params->mem_pp_mem.alpha << 8);
+ ipu_ic_write(ipu, reg, IC_CMBP_1);
+ } else
+ ic_conf &= ~IC_CONF_IC_GLB_LOC_A;
+
+ if (params->mem_pp_mem.key_color_en) {
+ ic_conf |= IC_CONF_KEY_COLOR_EN;
+ ipu_ic_write(ipu, params->mem_pp_mem.key_color,
+ IC_CMBP_2);
+ } else
+ ic_conf &= ~IC_CONF_KEY_COLOR_EN;
+ } else {
+ ic_conf &= ~IC_CONF_PP_CMB;
+ }
+
+ ipu_ic_write(ipu, ic_conf, IC_CONF);
+
+ return ret;
+}
+
+void _ipu_ic_uninit_pp(struct ipu_soc *ipu)
+{
+ uint32_t reg;
+
+ reg = ipu_ic_read(ipu, IC_CONF);
+ reg &= ~(IC_CONF_PP_EN | IC_CONF_PP_CSC1 | IC_CONF_PP_CSC2 |
+ IC_CONF_PP_CMB);
+ ipu_ic_write(ipu, reg, IC_CONF);
+}
+
+void _ipu_ic_init_rotate_pp(struct ipu_soc *ipu, ipu_channel_params_t *params)
+{
+}
+
+void _ipu_ic_uninit_rotate_pp(struct ipu_soc *ipu)
+{
+ uint32_t reg;
+ reg = ipu_ic_read(ipu, IC_CONF);
+ reg &= ~IC_CONF_PP_ROT_EN;
+ ipu_ic_write(ipu, reg, IC_CONF);
+}
+
+int _ipu_ic_idma_init(struct ipu_soc *ipu, int dma_chan,
+ uint16_t width, uint16_t height,
+ int burst_size, ipu_rotate_mode_t rot)
+{
+ u32 ic_idmac_1, ic_idmac_2, ic_idmac_3;
+ u32 temp_rot = bitrev8(rot) >> 5;
+ bool need_hor_flip = false;
+
+ if ((burst_size != 8) && (burst_size != 16)) {
+ dev_dbg(ipu->dev, "Illegal burst length for IC\n");
+ return -EINVAL;
+ }
+
+ width--;
+ height--;
+
+ if (temp_rot & 0x2) /* Need horizontal flip */
+ need_hor_flip = true;
+
+ ic_idmac_1 = ipu_ic_read(ipu, IC_IDMAC_1);
+ ic_idmac_2 = ipu_ic_read(ipu, IC_IDMAC_2);
+ ic_idmac_3 = ipu_ic_read(ipu, IC_IDMAC_3);
+ if (dma_chan == 22) { /* PP output - CB2 */
+ if (burst_size == 16)
+ ic_idmac_1 |= IC_IDMAC_1_CB2_BURST_16;
+ else
+ ic_idmac_1 &= ~IC_IDMAC_1_CB2_BURST_16;
+
+ if (need_hor_flip)
+ ic_idmac_1 |= IC_IDMAC_1_PP_FLIP_RS;
+ else
+ ic_idmac_1 &= ~IC_IDMAC_1_PP_FLIP_RS;
+
+ ic_idmac_2 &= ~IC_IDMAC_2_PP_HEIGHT_MASK;
+ ic_idmac_2 |= height << IC_IDMAC_2_PP_HEIGHT_OFFSET;
+
+ ic_idmac_3 &= ~IC_IDMAC_3_PP_WIDTH_MASK;
+ ic_idmac_3 |= width << IC_IDMAC_3_PP_WIDTH_OFFSET;
+ } else if (dma_chan == 11) { /* PP Input - CB5 */
+ if (burst_size == 16)
+ ic_idmac_1 |= IC_IDMAC_1_CB5_BURST_16;
+ else
+ ic_idmac_1 &= ~IC_IDMAC_1_CB5_BURST_16;
+ } else if (dma_chan == 47) { /* PP Rot input */
+ ic_idmac_1 &= ~IC_IDMAC_1_PP_ROT_MASK;
+ ic_idmac_1 |= temp_rot << IC_IDMAC_1_PP_ROT_OFFSET;
+ }
+
+ if (dma_chan == 12) { /* PRP Input - CB6 */
+ if (burst_size == 16)
+ ic_idmac_1 |= IC_IDMAC_1_CB6_BURST_16;
+ else
+ ic_idmac_1 &= ~IC_IDMAC_1_CB6_BURST_16;
+ }
+
+ if (dma_chan == 20) { /* PRP ENC output - CB0 */
+ if (burst_size == 16)
+ ic_idmac_1 |= IC_IDMAC_1_CB0_BURST_16;
+ else
+ ic_idmac_1 &= ~IC_IDMAC_1_CB0_BURST_16;
+
+ if (need_hor_flip)
+ ic_idmac_1 |= IC_IDMAC_1_PRPENC_FLIP_RS;
+ else
+ ic_idmac_1 &= ~IC_IDMAC_1_PRPENC_FLIP_RS;
+
+ ic_idmac_2 &= ~IC_IDMAC_2_PRPENC_HEIGHT_MASK;
+ ic_idmac_2 |= height << IC_IDMAC_2_PRPENC_HEIGHT_OFFSET;
+
+ ic_idmac_3 &= ~IC_IDMAC_3_PRPENC_WIDTH_MASK;
+ ic_idmac_3 |= width << IC_IDMAC_3_PRPENC_WIDTH_OFFSET;
+
+ } else if (dma_chan == 45) { /* PRP ENC Rot input */
+ ic_idmac_1 &= ~IC_IDMAC_1_PRPENC_ROT_MASK;
+ ic_idmac_1 |= temp_rot << IC_IDMAC_1_PRPENC_ROT_OFFSET;
+ }
+
+ if (dma_chan == 21) { /* PRP VF output - CB1 */
+ if (burst_size == 16)
+ ic_idmac_1 |= IC_IDMAC_1_CB1_BURST_16;
+ else
+ ic_idmac_1 &= ~IC_IDMAC_1_CB1_BURST_16;
+
+ if (need_hor_flip)
+ ic_idmac_1 |= IC_IDMAC_1_PRPVF_FLIP_RS;
+ else
+ ic_idmac_1 &= ~IC_IDMAC_1_PRPVF_FLIP_RS;
+
+ ic_idmac_2 &= ~IC_IDMAC_2_PRPVF_HEIGHT_MASK;
+ ic_idmac_2 |= height << IC_IDMAC_2_PRPVF_HEIGHT_OFFSET;
+
+ ic_idmac_3 &= ~IC_IDMAC_3_PRPVF_WIDTH_MASK;
+ ic_idmac_3 |= width << IC_IDMAC_3_PRPVF_WIDTH_OFFSET;
+
+ } else if (dma_chan == 46) { /* PRP VF Rot input */
+ ic_idmac_1 &= ~IC_IDMAC_1_PRPVF_ROT_MASK;
+ ic_idmac_1 |= temp_rot << IC_IDMAC_1_PRPVF_ROT_OFFSET;
+ }
+
+ if (dma_chan == 14) { /* PRP VF graphics combining input - CB3 */
+ if (burst_size == 16)
+ ic_idmac_1 |= IC_IDMAC_1_CB3_BURST_16;
+ else
+ ic_idmac_1 &= ~IC_IDMAC_1_CB3_BURST_16;
+ } else if (dma_chan == 15) { /* PP graphics combining input - CB4 */
+ if (burst_size == 16)
+ ic_idmac_1 |= IC_IDMAC_1_CB4_BURST_16;
+ else
+ ic_idmac_1 &= ~IC_IDMAC_1_CB4_BURST_16;
+ } else if (dma_chan == 5) { /* VDIC OUTPUT - CB7 */
+ if (burst_size == 16)
+ ic_idmac_1 |= IC_IDMAC_1_CB7_BURST_16;
+ else
+ ic_idmac_1 &= ~IC_IDMAC_1_CB7_BURST_16;
+ }
+
+ ipu_ic_write(ipu, ic_idmac_1, IC_IDMAC_1);
+ ipu_ic_write(ipu, ic_idmac_2, IC_IDMAC_2);
+ ipu_ic_write(ipu, ic_idmac_3, IC_IDMAC_3);
+ return 0;
+}
+
+static void _init_csc(struct ipu_soc *ipu, uint8_t ic_task, ipu_color_space_t in_format,
+ ipu_color_space_t out_format, int csc_index)
+{
+ /*
+ * Y = 0.257 * R + 0.504 * G + 0.098 * B + 16;
+ * U = -0.148 * R - 0.291 * G + 0.439 * B + 128;
+ * V = 0.439 * R - 0.368 * G - 0.071 * B + 128;
+ */
+ static const uint32_t rgb2ycbcr_coeff[4][3] = {
+ {0x0042, 0x0081, 0x0019},
+ {0x01DA, 0x01B6, 0x0070},
+ {0x0070, 0x01A2, 0x01EE},
+ {0x0040, 0x0200, 0x0200}, /* A0, A1, A2 */
+ };
+
+ /* transparent RGB->RGB matrix for combining
+ */
+ static const uint32_t rgb2rgb_coeff[4][3] = {
+ {0x0080, 0x0000, 0x0000},
+ {0x0000, 0x0080, 0x0000},
+ {0x0000, 0x0000, 0x0080},
+ {0x0000, 0x0000, 0x0000}, /* A0, A1, A2 */
+ };
+
+/* R = (1.164 * (Y - 16)) + (1.596 * (Cr - 128));
+ G = (1.164 * (Y - 16)) - (0.392 * (Cb - 128)) - (0.813 * (Cr - 128));
+ B = (1.164 * (Y - 16)) + (2.017 * (Cb - 128); */
+ static const uint32_t ycbcr2rgb_coeff[4][3] = {
+ {149, 0, 204},
+ {149, 462, 408},
+ {149, 255, 0},
+ {8192 - 446, 266, 8192 - 554}, /* A0, A1, A2 */
+ };
+
+ uint32_t param;
+ uint32_t *base = NULL;
+
+ if (ic_task == IC_TASK_ENCODER) {
+ base = (uint32_t *)ipu->tpmem_base + 0x2008 / 4;
+ } else if (ic_task == IC_TASK_VIEWFINDER) {
+ if (csc_index == 1)
+ base = (uint32_t *)ipu->tpmem_base + 0x4028 / 4;
+ else
+ base = (uint32_t *)ipu->tpmem_base + 0x4040 / 4;
+ } else if (ic_task == IC_TASK_POST_PROCESSOR) {
+ if (csc_index == 1)
+ base = (uint32_t *)ipu->tpmem_base + 0x6060 / 4;
+ else
+ base = (uint32_t *)ipu->tpmem_base + 0x6078 / 4;
+ } else {
+ BUG();
+ }
+
+ if ((in_format == YCbCr) && (out_format == RGB)) {
+ /* Init CSC (YCbCr->RGB) */
+ param = (ycbcr2rgb_coeff[3][0] << 27) |
+ (ycbcr2rgb_coeff[0][0] << 18) |
+ (ycbcr2rgb_coeff[1][1] << 9) | ycbcr2rgb_coeff[2][2];
+ writel(param, base++);
+ /* scale = 2, sat = 0 */
+ param = (ycbcr2rgb_coeff[3][0] >> 5) | (2L << (40 - 32));
+ writel(param, base++);
+
+ param = (ycbcr2rgb_coeff[3][1] << 27) |
+ (ycbcr2rgb_coeff[0][1] << 18) |
+ (ycbcr2rgb_coeff[1][0] << 9) | ycbcr2rgb_coeff[2][0];
+ writel(param, base++);
+ param = (ycbcr2rgb_coeff[3][1] >> 5);
+ writel(param, base++);
+
+ param = (ycbcr2rgb_coeff[3][2] << 27) |
+ (ycbcr2rgb_coeff[0][2] << 18) |
+ (ycbcr2rgb_coeff[1][2] << 9) | ycbcr2rgb_coeff[2][1];
+ writel(param, base++);
+ param = (ycbcr2rgb_coeff[3][2] >> 5);
+ writel(param, base++);
+ } else if ((in_format == RGB) && (out_format == YCbCr)) {
+ /* Init CSC (RGB->YCbCr) */
+ param = (rgb2ycbcr_coeff[3][0] << 27) |
+ (rgb2ycbcr_coeff[0][0] << 18) |
+ (rgb2ycbcr_coeff[1][1] << 9) | rgb2ycbcr_coeff[2][2];
+ writel(param, base++);
+ /* scale = 1, sat = 0 */
+ param = (rgb2ycbcr_coeff[3][0] >> 5) | (1UL << 8);
+ writel(param, base++);
+
+ param = (rgb2ycbcr_coeff[3][1] << 27) |
+ (rgb2ycbcr_coeff[0][1] << 18) |
+ (rgb2ycbcr_coeff[1][0] << 9) | rgb2ycbcr_coeff[2][0];
+ writel(param, base++);
+ param = (rgb2ycbcr_coeff[3][1] >> 5);
+ writel(param, base++);
+
+ param = (rgb2ycbcr_coeff[3][2] << 27) |
+ (rgb2ycbcr_coeff[0][2] << 18) |
+ (rgb2ycbcr_coeff[1][2] << 9) | rgb2ycbcr_coeff[2][1];
+ writel(param, base++);
+ param = (rgb2ycbcr_coeff[3][2] >> 5);
+ writel(param, base++);
+ } else if ((in_format == RGB) && (out_format == RGB)) {
+ /* Init CSC */
+ param =
+ (rgb2rgb_coeff[3][0] << 27) | (rgb2rgb_coeff[0][0] << 18) |
+ (rgb2rgb_coeff[1][1] << 9) | rgb2rgb_coeff[2][2];
+ writel(param, base++);
+ /* scale = 2, sat = 0 */
+ param = (rgb2rgb_coeff[3][0] >> 5) | (2UL << 8);
+ writel(param, base++);
+
+ param =
+ (rgb2rgb_coeff[3][1] << 27) | (rgb2rgb_coeff[0][1] << 18) |
+ (rgb2rgb_coeff[1][0] << 9) | rgb2rgb_coeff[2][0];
+ writel(param, base++);
+ param = (rgb2rgb_coeff[3][1] >> 5);
+ writel(param, base++);
+
+ param =
+ (rgb2rgb_coeff[3][2] << 27) | (rgb2rgb_coeff[0][2] << 18) |
+ (rgb2rgb_coeff[1][2] << 9) | rgb2rgb_coeff[2][1];
+ writel(param, base++);
+ param = (rgb2rgb_coeff[3][2] >> 5);
+ writel(param, base++);
+ } else {
+ dev_err(ipu->dev, "Unsupported color space conversion\n");
+ }
+}
+
+static int _calc_resize_coeffs(struct ipu_soc *ipu,
+ uint32_t inSize, uint32_t outSize,
+ uint32_t *resizeCoeff,
+ uint32_t *downsizeCoeff)
+{
+ uint32_t tempSize;
+ uint32_t tempDownsize;
+
+ if (inSize > 4096) {
+ dev_err(ipu->dev, "IC input size(%d) cannot exceed 4096\n",
+ inSize);
+ return -EINVAL;
+ }
+
+ if (outSize > 1024) {
+ dev_err(ipu->dev, "IC output size(%d) cannot exceed 1024\n",
+ outSize);
+ return -EINVAL;
+ }
+
+ if ((outSize << 3) < inSize) {
+ dev_err(ipu->dev, "IC cannot downsize more than 8:1\n");
+ return -EINVAL;
+ }
+
+ /* Compute downsizing coefficient */
+ /* Output of downsizing unit cannot be more than 1024 */
+ tempDownsize = 0;
+ tempSize = inSize;
+ while (((tempSize > 1024) || (tempSize >= outSize * 2)) &&
+ (tempDownsize < 2)) {
+ tempSize >>= 1;
+ tempDownsize++;
+ }
+ *downsizeCoeff = tempDownsize;
+
+ /* compute resizing coefficient using the following equation:
+ resizeCoeff = M*(SI -1)/(SO - 1)
+ where M = 2^13, SI - input size, SO - output size */
+ *resizeCoeff = (8192L * (tempSize - 1)) / (outSize - 1);
+ if (*resizeCoeff >= 16384L) {
+ dev_err(ipu->dev, "Overflow on IC resize coefficient.\n");
+ return -EINVAL;
+ }
+
+ dev_dbg(ipu->dev, "resizing from %u -> %u pixels, "
+ "downsize=%u, resize=%u.%lu (reg=%u)\n", inSize, outSize,
+ *downsizeCoeff, (*resizeCoeff >= 8192L) ? 1 : 0,
+ ((*resizeCoeff & 0x1FFF) * 10000L) / 8192L, *resizeCoeff);
+
+ return 0;
+}
+
+void _ipu_vdi_toggle_top_field_man(struct ipu_soc *ipu)
+{
+ uint32_t reg;
+ uint32_t mask_reg;
+
+ reg = ipu_vdi_read(ipu, VDI_C);
+ mask_reg = reg & VDI_C_TOP_FIELD_MAN_1;
+ if (mask_reg == VDI_C_TOP_FIELD_MAN_1)
+ reg &= ~VDI_C_TOP_FIELD_MAN_1;
+ else
+ reg |= VDI_C_TOP_FIELD_MAN_1;
+
+ ipu_vdi_write(ipu, reg, VDI_C);
+}
diff --git a/drivers/mxc/ipu3/ipu_param_mem.h b/drivers/mxc/ipu3/ipu_param_mem.h
new file mode 100644
index 000000000000..a22839a98ac8
--- /dev/null
+++ b/drivers/mxc/ipu3/ipu_param_mem.h
@@ -0,0 +1,998 @@
+/*
+ * Copyright 2005-2015 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+#ifndef __INCLUDE_IPU_PARAM_MEM_H__
+#define __INCLUDE_IPU_PARAM_MEM_H__
+
+#include <linux/bitrev.h>
+#include <linux/types.h>
+
+#include "ipu_prv.h"
+
+extern u32 *ipu_cpmem_base;
+
+struct ipu_ch_param_word {
+ uint32_t data[5];
+ uint32_t res[3];
+};
+
+struct ipu_ch_param {
+ struct ipu_ch_param_word word[2];
+};
+
+#define ipu_ch_param_addr(ipu, ch) \
+ (((struct ipu_ch_param *)(ipu)->cpmem_base) + (ch))
+
+#define _param_word(base, w) \
+ (((struct ipu_ch_param *)(base))->word[(w)].data)
+
+#define ipu_ch_param_set_field(base, w, bit, size, v) { \
+ int i = (bit) / 32; \
+ int off = (bit) % 32; \
+ _param_word((base), (w))[i] |= (v) << off; \
+ if (((bit)+(size)-1)/32 > i) { \
+ _param_word((base), (w))[i + 1] |= \
+ (v) >> (off ? (32 - off) : 0); \
+ } \
+}
+
+#define ipu_ch_param_set_field_io(base, w, bit, size, v) { \
+ int i = (bit) / 32; \
+ int off = (bit) % 32; \
+ unsigned reg_offset; \
+ u32 temp; \
+ reg_offset = sizeof(struct ipu_ch_param_word) * (w) / 4; \
+ reg_offset += i; \
+ temp = readl((u32 *)(base) + reg_offset); \
+ temp |= (v) << off; \
+ writel(temp, (u32 *)(base) + reg_offset); \
+ if (((bit)+(size)-1)/32 > i) { \
+ reg_offset++; \
+ temp = readl((u32 *)(base) + reg_offset); \
+ temp |= (v) >> (off ? (32 - off) : 0); \
+ writel(temp, (u32 *)(base) + reg_offset); \
+ } \
+}
+
+#define ipu_ch_param_mod_field(base, w, bit, size, v) { \
+ int i = (bit) / 32; \
+ int off = (bit) % 32; \
+ u32 mask = (1UL << (size)) - 1; \
+ u32 temp = _param_word((base), (w))[i]; \
+ temp &= ~(mask << off); \
+ _param_word((base), (w))[i] = temp | (v) << off; \
+ if (((bit)+(size)-1)/32 > i) { \
+ temp = _param_word((base), (w))[i + 1]; \
+ temp &= ~(mask >> (32 - off)); \
+ _param_word((base), (w))[i + 1] = \
+ temp | ((v) >> (off ? (32 - off) : 0)); \
+ } \
+}
+
+#define ipu_ch_param_mod_field_io(base, w, bit, size, v) { \
+ int i = (bit) / 32; \
+ int off = (bit) % 32; \
+ u32 mask = (1UL << (size)) - 1; \
+ unsigned reg_offset; \
+ u32 temp; \
+ reg_offset = sizeof(struct ipu_ch_param_word) * (w) / 4; \
+ reg_offset += i; \
+ temp = readl((u32 *)(base) + reg_offset); \
+ temp &= ~(mask << off); \
+ temp |= (v) << off; \
+ writel(temp, (u32 *)(base) + reg_offset); \
+ if (((bit)+(size)-1)/32 > i) { \
+ reg_offset++; \
+ temp = readl((u32 *)(base) + reg_offset); \
+ temp &= ~(mask >> (32 - off)); \
+ temp |= ((v) >> (off ? (32 - off) : 0)); \
+ writel(temp, (u32 *)(base) + reg_offset); \
+ } \
+}
+
+#define ipu_ch_param_read_field(base, w, bit, size) ({ \
+ u32 temp2; \
+ int i = (bit) / 32; \
+ int off = (bit) % 32; \
+ u32 mask = (1UL << (size)) - 1; \
+ u32 temp1 = _param_word((base), (w))[i]; \
+ temp1 = mask & (temp1 >> off); \
+ if (((bit)+(size)-1)/32 > i) { \
+ temp2 = _param_word((base), (w))[i + 1]; \
+ temp2 &= mask >> (off ? (32 - off) : 0); \
+ temp1 |= temp2 << (off ? (32 - off) : 0); \
+ } \
+ temp1; \
+})
+
+#define ipu_ch_param_read_field_io(base, w, bit, size) ({ \
+ u32 temp1, temp2; \
+ int i = (bit) / 32; \
+ int off = (bit) % 32; \
+ u32 mask = (1UL << (size)) - 1; \
+ unsigned reg_offset; \
+ reg_offset = sizeof(struct ipu_ch_param_word) * (w) / 4; \
+ reg_offset += i; \
+ temp1 = readl((u32 *)(base) + reg_offset); \
+ temp1 = mask & (temp1 >> off); \
+ if (((bit)+(size)-1)/32 > i) { \
+ reg_offset++; \
+ temp2 = readl((u32 *)(base) + reg_offset); \
+ temp2 &= mask >> (off ? (32 - off) : 0); \
+ temp1 |= temp2 << (off ? (32 - off) : 0); \
+ } \
+ temp1; \
+})
+
+static inline int __ipu_ch_get_third_buf_cpmem_num(int ch)
+{
+ switch (ch) {
+ case 8:
+ return 64;
+ case 9:
+ return 65;
+ case 10:
+ return 66;
+ case 13:
+ return 67;
+ case 21:
+ return 68;
+ case 23:
+ return 69;
+ case 27:
+ return 70;
+ case 28:
+ return 71;
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static inline void _ipu_ch_params_set_packing(struct ipu_ch_param *p,
+ int red_width, int red_offset,
+ int green_width, int green_offset,
+ int blue_width, int blue_offset,
+ int alpha_width, int alpha_offset)
+{
+ /* Setup red width and offset */
+ ipu_ch_param_set_field(p, 1, 116, 3, red_width - 1);
+ ipu_ch_param_set_field(p, 1, 128, 5, red_offset);
+ /* Setup green width and offset */
+ ipu_ch_param_set_field(p, 1, 119, 3, green_width - 1);
+ ipu_ch_param_set_field(p, 1, 133, 5, green_offset);
+ /* Setup blue width and offset */
+ ipu_ch_param_set_field(p, 1, 122, 3, blue_width - 1);
+ ipu_ch_param_set_field(p, 1, 138, 5, blue_offset);
+ /* Setup alpha width and offset */
+ ipu_ch_param_set_field(p, 1, 125, 3, alpha_width - 1);
+ ipu_ch_param_set_field(p, 1, 143, 5, alpha_offset);
+}
+
+static inline void _ipu_ch_param_dump(struct ipu_soc *ipu, int ch)
+{
+ struct ipu_ch_param *p = ipu_ch_param_addr(ipu, ch);
+ dev_dbg(ipu->dev, "ch %d word 0 - %08X %08X %08X %08X %08X\n", ch,
+ p->word[0].data[0], p->word[0].data[1], p->word[0].data[2],
+ p->word[0].data[3], p->word[0].data[4]);
+ dev_dbg(ipu->dev, "ch %d word 1 - %08X %08X %08X %08X %08X\n", ch,
+ p->word[1].data[0], p->word[1].data[1], p->word[1].data[2],
+ p->word[1].data[3], p->word[1].data[4]);
+ dev_dbg(ipu->dev, "PFS 0x%x, ",
+ ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, ch), 1, 85, 4));
+ dev_dbg(ipu->dev, "BPP 0x%x, ",
+ ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, ch), 0, 107, 3));
+ dev_dbg(ipu->dev, "NPB 0x%x\n",
+ ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, ch), 1, 78, 7));
+
+ dev_dbg(ipu->dev, "FW %d, ",
+ ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, ch), 0, 125, 13));
+ dev_dbg(ipu->dev, "FH %d, ",
+ ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, ch), 0, 138, 12));
+ dev_dbg(ipu->dev, "EBA0 0x%x\n",
+ ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, ch), 1, 0, 29) << 3);
+ dev_dbg(ipu->dev, "EBA1 0x%x\n",
+ ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, ch), 1, 29, 29) << 3);
+ dev_dbg(ipu->dev, "Stride %d\n",
+ ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, ch), 1, 102, 14));
+ dev_dbg(ipu->dev, "scan_order %d\n",
+ ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, ch), 0, 113, 1));
+ dev_dbg(ipu->dev, "uv_stride %d\n",
+ ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, ch), 1, 128, 14));
+ dev_dbg(ipu->dev, "u_offset 0x%x\n",
+ ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, ch), 0, 46, 22) << 3);
+ dev_dbg(ipu->dev, "v_offset 0x%x\n",
+ ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, ch), 0, 68, 22) << 3);
+
+ dev_dbg(ipu->dev, "Width0 %d+1, ",
+ ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, ch), 1, 116, 3));
+ dev_dbg(ipu->dev, "Width1 %d+1, ",
+ ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, ch), 1, 119, 3));
+ dev_dbg(ipu->dev, "Width2 %d+1, ",
+ ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, ch), 1, 122, 3));
+ dev_dbg(ipu->dev, "Width3 %d+1, ",
+ ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, ch), 1, 125, 3));
+ dev_dbg(ipu->dev, "Offset0 %d, ",
+ ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, ch), 1, 128, 5));
+ dev_dbg(ipu->dev, "Offset1 %d, ",
+ ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, ch), 1, 133, 5));
+ dev_dbg(ipu->dev, "Offset2 %d, ",
+ ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, ch), 1, 138, 5));
+ dev_dbg(ipu->dev, "Offset3 %d\n",
+ ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, ch), 1, 143, 5));
+}
+
+static inline void fill_cpmem(struct ipu_soc *ipu, int ch, struct ipu_ch_param *params)
+{
+ int i, w;
+ void *addr = ipu_ch_param_addr(ipu, ch);
+
+ /* 2 words, 5 valid data */
+ for (w = 0; w < 2; w++) {
+ for (i = 0; i < 5; i++) {
+ writel(params->word[w].data[i], addr);
+ addr += 4;
+ }
+ addr += 12;
+ }
+}
+
+static inline void _ipu_ch_param_init(struct ipu_soc *ipu, int ch,
+ uint32_t pixel_fmt, uint32_t width,
+ uint32_t height, uint32_t stride,
+ uint32_t u, uint32_t v,
+ uint32_t uv_stride, dma_addr_t addr0,
+ dma_addr_t addr1, dma_addr_t addr2)
+{
+ uint32_t u_offset = 0;
+ uint32_t v_offset = 0;
+ uint32_t bs = 0;
+ int32_t sub_ch = 0;
+ struct ipu_ch_param params;
+
+ memset(&params, 0, sizeof(params));
+
+ ipu_ch_param_set_field(&params, 0, 125, 13, width - 1);
+
+ if (((ch == 8) || (ch == 9) || (ch == 10)) && !ipu->vdoa_en) {
+ ipu_ch_param_set_field(&params, 0, 138, 12, (height / 2) - 1);
+ ipu_ch_param_set_field(&params, 1, 102, 14, (stride * 2) - 1);
+ } else {
+ /* note: for vdoa+vdi- ch8/9/10, always use band mode */
+ ipu_ch_param_set_field(&params, 0, 138, 12, height - 1);
+ ipu_ch_param_set_field(&params, 1, 102, 14, stride - 1);
+ }
+
+ /* EBA is 8-byte aligned */
+ ipu_ch_param_set_field(&params, 1, 0, 29, addr0 >> 3);
+ ipu_ch_param_set_field(&params, 1, 29, 29, addr1 >> 3);
+ if (addr0%8)
+ dev_warn(ipu->dev,
+ "IDMAC%d's EBA0 is not 8-byte aligned\n", ch);
+ if (addr1%8)
+ dev_warn(ipu->dev,
+ "IDMAC%d's EBA1 is not 8-byte aligned\n", ch);
+
+ switch (pixel_fmt) {
+ case IPU_PIX_FMT_GENERIC:
+ /*Represents 8-bit Generic data */
+ ipu_ch_param_set_field(&params, 0, 107, 3, 5); /* bits/pixel */
+ ipu_ch_param_set_field(&params, 1, 85, 4, 6); /* pix format */
+ ipu_ch_param_set_field(&params, 1, 78, 7, 63); /* burst size */
+
+ break;
+ case IPU_PIX_FMT_GENERIC_16:
+ /* Represents 16-bit generic data */
+ ipu_ch_param_set_field(&params, 0, 107, 3, 3); /* bits/pixel */
+ ipu_ch_param_set_field(&params, 1, 85, 4, 6); /* pix format */
+ ipu_ch_param_set_field(&params, 1, 78, 7, 31); /* burst size */
+
+ break;
+ case IPU_PIX_FMT_GENERIC_32:
+ /*Represents 32-bit Generic data */
+ break;
+ case IPU_PIX_FMT_RGB565:
+ ipu_ch_param_set_field(&params, 0, 107, 3, 3); /* bits/pixel */
+ ipu_ch_param_set_field(&params, 1, 85, 4, 7); /* pix format */
+ ipu_ch_param_set_field(&params, 1, 78, 7, 31); /* burst size */
+
+ _ipu_ch_params_set_packing(&params, 5, 0, 6, 5, 5, 11, 8, 16);
+ break;
+ case IPU_PIX_FMT_BGRA4444:
+ ipu_ch_param_set_field(&params, 0, 107, 3, 3); /* bits/pixel */
+ ipu_ch_param_set_field(&params, 1, 85, 4, 7); /* pix format */
+ ipu_ch_param_set_field(&params, 1, 78, 7, 31); /* burst size */
+
+ _ipu_ch_params_set_packing(&params, 4, 4, 4, 8, 4, 12, 4, 0);
+ break;
+ case IPU_PIX_FMT_BGRA5551:
+ ipu_ch_param_set_field(&params, 0, 107, 3, 3); /* bits/pixel */
+ ipu_ch_param_set_field(&params, 1, 85, 4, 7); /* pix format */
+ ipu_ch_param_set_field(&params, 1, 78, 7, 31); /* burst size */
+
+ _ipu_ch_params_set_packing(&params, 5, 1, 5, 6, 5, 11, 1, 0);
+ break;
+ case IPU_PIX_FMT_BGR24:
+ ipu_ch_param_set_field(&params, 0, 107, 3, 1); /* bits/pixel */
+ ipu_ch_param_set_field(&params, 1, 85, 4, 7); /* pix format */
+ ipu_ch_param_set_field(&params, 1, 78, 7, 19); /* burst size */
+
+ _ipu_ch_params_set_packing(&params, 8, 0, 8, 8, 8, 16, 8, 24);
+ break;
+ case IPU_PIX_FMT_RGB24:
+ case IPU_PIX_FMT_YUV444:
+ ipu_ch_param_set_field(&params, 0, 107, 3, 1); /* bits/pixel */
+ ipu_ch_param_set_field(&params, 1, 85, 4, 7); /* pix format */
+ ipu_ch_param_set_field(&params, 1, 78, 7, 19); /* burst size */
+
+ _ipu_ch_params_set_packing(&params, 8, 16, 8, 8, 8, 0, 8, 24);
+ break;
+ case IPU_PIX_FMT_VYU444:
+ ipu_ch_param_set_field(&params, 0, 107, 3, 1); /* bits/pixel */
+ ipu_ch_param_set_field(&params, 1, 85, 4, 7); /* pix format */
+ ipu_ch_param_set_field(&params, 1, 78, 7, 19); /* burst size */
+
+ _ipu_ch_params_set_packing(&params, 8, 8, 8, 0, 8, 16, 8, 24);
+ break;
+ case IPU_PIX_FMT_AYUV:
+ ipu_ch_param_set_field(&params, 0, 107, 3, 0); /* bits/pixel */
+ ipu_ch_param_set_field(&params, 1, 85, 4, 7); /* pix format */
+ ipu_ch_param_set_field(&params, 1, 78, 7, 15); /* burst size */
+
+ _ipu_ch_params_set_packing(&params, 8, 8, 8, 16, 8, 24, 8, 0);
+ break;
+ case IPU_PIX_FMT_BGRA32:
+ case IPU_PIX_FMT_BGR32:
+ ipu_ch_param_set_field(&params, 0, 107, 3, 0); /* bits/pixel */
+ ipu_ch_param_set_field(&params, 1, 85, 4, 7); /* pix format */
+ ipu_ch_param_set_field(&params, 1, 78, 7, 15); /* burst size */
+
+ _ipu_ch_params_set_packing(&params, 8, 8, 8, 16, 8, 24, 8, 0);
+ break;
+ case IPU_PIX_FMT_RGBA32:
+ case IPU_PIX_FMT_RGB32:
+ ipu_ch_param_set_field(&params, 0, 107, 3, 0); /* bits/pixel */
+ ipu_ch_param_set_field(&params, 1, 85, 4, 7); /* pix format */
+ ipu_ch_param_set_field(&params, 1, 78, 7, 15); /* burst size */
+
+ _ipu_ch_params_set_packing(&params, 8, 24, 8, 16, 8, 8, 8, 0);
+ break;
+ case IPU_PIX_FMT_ABGR32:
+ ipu_ch_param_set_field(&params, 0, 107, 3, 0); /* bits/pixel */
+ ipu_ch_param_set_field(&params, 1, 85, 4, 7); /* pix format */
+ ipu_ch_param_set_field(&params, 1, 78, 7, 15); /* burst size */
+
+ _ipu_ch_params_set_packing(&params, 8, 0, 8, 8, 8, 16, 8, 24);
+ break;
+ case IPU_PIX_FMT_UYVY:
+ ipu_ch_param_set_field(&params, 0, 107, 3, 3); /* bits/pixel */
+ ipu_ch_param_set_field(&params, 1, 85, 4, 0xA); /* pix format */
+ if ((ch == 8) || (ch == 9) || (ch == 10)) {
+ ipu_ch_param_set_field(&params, 1, 78, 7, 15); /* burst size */
+ } else {
+ ipu_ch_param_set_field(&params, 1, 78, 7, 31); /* burst size */
+ }
+ break;
+ case IPU_PIX_FMT_YUYV:
+ ipu_ch_param_set_field(&params, 0, 107, 3, 3); /* bits/pixel */
+ ipu_ch_param_set_field(&params, 1, 85, 4, 0x8); /* pix format */
+ if ((ch == 8) || (ch == 9) || (ch == 10)) {
+ if (ipu->vdoa_en) {
+ ipu_ch_param_set_field(&params, 1, 78, 7, 31);
+ } else {
+ ipu_ch_param_set_field(&params, 1, 78, 7, 15);
+ }
+ } else {
+ ipu_ch_param_set_field(&params, 1, 78, 7, 31); /* burst size */
+ }
+ break;
+ case IPU_PIX_FMT_YUV420P2:
+ case IPU_PIX_FMT_YUV420P:
+ ipu_ch_param_set_field(&params, 1, 85, 4, 2); /* pix format */
+
+ if (uv_stride < stride / 2)
+ uv_stride = stride / 2;
+
+ u_offset = stride * height;
+ v_offset = u_offset + (uv_stride * height / 2);
+ if ((ch == 8) || (ch == 9) || (ch == 10)) {
+ ipu_ch_param_set_field(&params, 1, 78, 7, 15); /* burst size */
+ uv_stride = uv_stride*2;
+ } else {
+ if (_ipu_is_smfc_chan(ch) &&
+ ipu->smfc_idmac_12bit_3planar_bs_fixup)
+ bs = 15;
+ else
+ bs = 31;
+ ipu_ch_param_set_field(&params, 1, 78, 7, bs); /* burst size */
+ }
+ break;
+ case IPU_PIX_FMT_YVU420P:
+ ipu_ch_param_set_field(&params, 1, 85, 4, 2); /* pix format */
+
+ if (uv_stride < stride / 2)
+ uv_stride = stride / 2;
+
+ v_offset = stride * height;
+ u_offset = v_offset + (uv_stride * height / 2);
+ if ((ch == 8) || (ch == 9) || (ch == 10)) {
+ ipu_ch_param_set_field(&params, 1, 78, 7, 15); /* burst size */
+ uv_stride = uv_stride*2;
+ } else {
+ if (_ipu_is_smfc_chan(ch) &&
+ ipu->smfc_idmac_12bit_3planar_bs_fixup)
+ bs = 15;
+ else
+ bs = 31;
+ ipu_ch_param_set_field(&params, 1, 78, 7, bs); /* burst size */
+ }
+ break;
+ case IPU_PIX_FMT_YVU422P:
+ /* BPP & pixel format */
+ ipu_ch_param_set_field(&params, 1, 85, 4, 1); /* pix format */
+ ipu_ch_param_set_field(&params, 1, 78, 7, 31); /* burst size */
+
+ if (uv_stride < stride / 2)
+ uv_stride = stride / 2;
+
+ v_offset = (v == 0) ? stride * height : v;
+ u_offset = (u == 0) ? v_offset + v_offset / 2 : u;
+ break;
+ case IPU_PIX_FMT_YUV422P:
+ /* BPP & pixel format */
+ ipu_ch_param_set_field(&params, 1, 85, 4, 1); /* pix format */
+ ipu_ch_param_set_field(&params, 1, 78, 7, 31); /* burst size */
+
+ if (uv_stride < stride / 2)
+ uv_stride = stride / 2;
+
+ u_offset = (u == 0) ? stride * height : u;
+ v_offset = (v == 0) ? u_offset + u_offset / 2 : v;
+ break;
+ case IPU_PIX_FMT_YUV444P:
+ /* BPP & pixel format */
+ ipu_ch_param_set_field(&params, 1, 85, 4, 0); /* pix format */
+ ipu_ch_param_set_field(&params, 1, 78, 7, 31); /* burst size */
+ uv_stride = stride;
+ u_offset = (u == 0) ? stride * height : u;
+ v_offset = (v == 0) ? u_offset * 2 : v;
+ break;
+ case IPU_PIX_FMT_NV16:
+ ipu_ch_param_set_field(&params, 1, 85, 4, 1); /* pix format */
+ ipu_ch_param_set_field(&params, 1, 78, 7, 31); /* burst size */
+ uv_stride = stride;
+ u_offset = (u == 0) ? stride * height : u;
+ break;
+ case IPU_PIX_FMT_NV12:
+ /* BPP & pixel format */
+ ipu_ch_param_set_field(&params, 1, 85, 4, 4); /* pix format */
+ uv_stride = stride;
+ u_offset = (u == 0) ? stride * height : u;
+ if ((ch == 8) || (ch == 9) || (ch == 10)) {
+ if (ipu->vdoa_en) {
+ /* one field buffer, memory width 64bits */
+ ipu_ch_param_set_field(&params, 1, 78, 7, 63);
+ } else {
+ ipu_ch_param_set_field(&params, 1, 78, 7, 15);
+ /* top/bottom field in one buffer*/
+ uv_stride = uv_stride*2;
+ }
+ } else {
+ ipu_ch_param_set_field(&params, 1, 78, 7, 31); /* burst size */
+ }
+ break;
+ default:
+ dev_err(ipu->dev, "mxc ipu: unimplemented pixel format\n");
+ break;
+ }
+ /*set burst size to 16*/
+
+
+ if (uv_stride)
+ ipu_ch_param_set_field(&params, 1, 128, 14, uv_stride - 1);
+
+ /* Get the uv offset from user when need cropping */
+ if (u || v) {
+ u_offset = u;
+ v_offset = v;
+ }
+
+ /* UBO and VBO are 22-bit and 8-byte aligned */
+ if (u_offset/8 > 0x3fffff)
+ dev_warn(ipu->dev,
+ "IDMAC%d's U offset exceeds IPU limitation\n", ch);
+ if (v_offset/8 > 0x3fffff)
+ dev_warn(ipu->dev,
+ "IDMAC%d's V offset exceeds IPU limitation\n", ch);
+ if (u_offset%8)
+ dev_warn(ipu->dev,
+ "IDMAC%d's U offset is not 8-byte aligned\n", ch);
+ if (v_offset%8)
+ dev_warn(ipu->dev,
+ "IDMAC%d's V offset is not 8-byte aligned\n", ch);
+
+ ipu_ch_param_set_field(&params, 0, 46, 22, u_offset / 8);
+ ipu_ch_param_set_field(&params, 0, 68, 22, v_offset / 8);
+
+ dev_dbg(ipu->dev, "initializing idma ch %d @ %p\n", ch, ipu_ch_param_addr(ipu, ch));
+ fill_cpmem(ipu, ch, &params);
+ if (addr2) {
+ sub_ch = __ipu_ch_get_third_buf_cpmem_num(ch);
+ if (sub_ch <= 0)
+ return;
+
+ ipu_ch_param_set_field(&params, 1, 0, 29, addr2 >> 3);
+ ipu_ch_param_set_field(&params, 1, 29, 29, 0);
+ if (addr2%8)
+ dev_warn(ipu->dev,
+ "IDMAC%d's sub-CPMEM entry%d EBA0 is not "
+ "8-byte aligned\n", ch, sub_ch);
+
+ dev_dbg(ipu->dev, "initializing idma ch %d @ %p sub cpmem\n", ch,
+ ipu_ch_param_addr(ipu, sub_ch));
+ fill_cpmem(ipu, sub_ch, &params);
+ }
+};
+
+static inline void _ipu_ch_param_set_burst_size(struct ipu_soc *ipu,
+ uint32_t ch,
+ uint16_t burst_pixels)
+{
+ int32_t sub_ch = 0;
+
+ ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, ch), 1, 78, 7,
+ burst_pixels - 1);
+
+ sub_ch = __ipu_ch_get_third_buf_cpmem_num(ch);
+ if (sub_ch <= 0)
+ return;
+ ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, sub_ch), 1, 78, 7,
+ burst_pixels - 1);
+};
+
+static inline int _ipu_ch_param_get_burst_size(struct ipu_soc *ipu, uint32_t ch)
+{
+ return ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, ch), 1, 78, 7) + 1;
+};
+
+static inline int _ipu_ch_param_get_bpp(struct ipu_soc *ipu, uint32_t ch)
+{
+ return ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, ch), 0, 107, 3);
+};
+
+static inline void _ipu_ch_param_set_buffer(struct ipu_soc *ipu, uint32_t ch,
+ int bufNum, dma_addr_t phyaddr)
+{
+ if (bufNum == 2) {
+ ch = __ipu_ch_get_third_buf_cpmem_num(ch);
+ if (ch <= 0)
+ return;
+ bufNum = 0;
+ }
+
+ ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, ch), 1, 29 * bufNum, 29,
+ phyaddr / 8);
+};
+
+static inline void _ipu_ch_param_set_rotation(struct ipu_soc *ipu, uint32_t ch,
+ ipu_rotate_mode_t rot)
+{
+ u32 temp_rot = bitrev8(rot) >> 5;
+ int32_t sub_ch = 0;
+
+ ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, ch), 0, 119, 3, temp_rot);
+
+ sub_ch = __ipu_ch_get_third_buf_cpmem_num(ch);
+ if (sub_ch <= 0)
+ return;
+ ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, sub_ch), 0, 119, 3, temp_rot);
+};
+
+static inline void _ipu_ch_param_set_block_mode(struct ipu_soc *ipu, uint32_t ch)
+{
+ int32_t sub_ch = 0;
+
+ ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, ch), 0, 117, 2, 1);
+
+ sub_ch = __ipu_ch_get_third_buf_cpmem_num(ch);
+ if (sub_ch <= 0)
+ return;
+ ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, sub_ch), 0, 117, 2, 1);
+};
+
+static inline void _ipu_ch_param_set_alpha_use_separate_channel(struct ipu_soc *ipu,
+ uint32_t ch,
+ bool option)
+{
+ int32_t sub_ch = 0;
+
+ if (option) {
+ ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, ch), 1, 89, 1, 1);
+ } else {
+ ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, ch), 1, 89, 1, 0);
+ }
+
+ sub_ch = __ipu_ch_get_third_buf_cpmem_num(ch);
+ if (sub_ch <= 0)
+ return;
+
+ if (option) {
+ ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, sub_ch), 1, 89, 1, 1);
+ } else {
+ ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, sub_ch), 1, 89, 1, 0);
+ }
+};
+
+static inline void _ipu_ch_param_set_alpha_condition_read(struct ipu_soc *ipu, uint32_t ch)
+{
+ int32_t sub_ch = 0;
+
+ ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, ch), 1, 149, 1, 1);
+
+ sub_ch = __ipu_ch_get_third_buf_cpmem_num(ch);
+ if (sub_ch <= 0)
+ return;
+ ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, sub_ch), 1, 149, 1, 1);
+};
+
+static inline void _ipu_ch_param_set_alpha_buffer_memory(struct ipu_soc *ipu, uint32_t ch)
+{
+ int alp_mem_idx;
+ int32_t sub_ch = 0;
+
+ switch (ch) {
+ case 14: /* PRP graphic */
+ alp_mem_idx = 0;
+ break;
+ case 15: /* PP graphic */
+ alp_mem_idx = 1;
+ break;
+ case 23: /* DP BG SYNC graphic */
+ alp_mem_idx = 4;
+ break;
+ case 27: /* DP FG SYNC graphic */
+ alp_mem_idx = 2;
+ break;
+ default:
+ dev_err(ipu->dev, "unsupported correlative channel of local "
+ "alpha channel\n");
+ return;
+ }
+
+ ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, ch), 1, 90, 3, alp_mem_idx);
+
+ sub_ch = __ipu_ch_get_third_buf_cpmem_num(ch);
+ if (sub_ch <= 0)
+ return;
+ ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, sub_ch), 1, 90, 3, alp_mem_idx);
+};
+
+static inline void _ipu_ch_param_set_interlaced_scan(struct ipu_soc *ipu, uint32_t ch)
+{
+ u32 stride;
+ int32_t sub_ch = 0;
+
+ sub_ch = __ipu_ch_get_third_buf_cpmem_num(ch);
+
+ ipu_ch_param_set_field_io(ipu_ch_param_addr(ipu, ch), 0, 113, 1, 1);
+ if (sub_ch > 0)
+ ipu_ch_param_set_field_io(ipu_ch_param_addr(ipu, sub_ch), 0, 113, 1, 1);
+ stride = ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, ch), 1, 102, 14) + 1;
+ /* ILO is 20-bit and 8-byte aligned */
+ if (stride/8 > 0xfffff)
+ dev_warn(ipu->dev,
+ "IDMAC%d's ILO exceeds IPU limitation\n", ch);
+ if (stride%8)
+ dev_warn(ipu->dev,
+ "IDMAC%d's ILO is not 8-byte aligned\n", ch);
+ ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, ch), 1, 58, 20, stride / 8);
+ if (sub_ch > 0)
+ ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, sub_ch), 1, 58, 20,
+ stride / 8);
+ stride *= 2;
+ ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, ch), 1, 102, 14, stride - 1);
+ if (sub_ch > 0)
+ ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, sub_ch), 1, 102, 14,
+ stride - 1);
+};
+
+static inline void _ipu_ch_param_set_axi_id(struct ipu_soc *ipu, uint32_t ch, uint32_t id)
+{
+ int32_t sub_ch = 0;
+
+ id %= 4;
+
+ ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, ch), 1, 93, 2, id);
+
+ sub_ch = __ipu_ch_get_third_buf_cpmem_num(ch);
+ if (sub_ch <= 0)
+ return;
+ ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, sub_ch), 1, 93, 2, id);
+};
+
+static inline int _ipu_ch_param_get_axi_id(struct ipu_soc *ipu, uint32_t ch)
+{
+ return ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, ch), 1, 93, 2);
+}
+
+static inline int __ipu_ch_offset_calc(uint32_t pixel_fmt,
+ uint32_t width,
+ uint32_t height,
+ uint32_t stride,
+ uint32_t u,
+ uint32_t v,
+ uint32_t uv_stride,
+ uint32_t vertical_offset,
+ uint32_t horizontal_offset,
+ uint32_t *u_offset,
+ uint32_t *v_offset)
+{
+ uint32_t u_fix = 0;
+ uint32_t v_fix = 0;
+
+ switch (pixel_fmt) {
+ case IPU_PIX_FMT_GENERIC:
+ case IPU_PIX_FMT_GENERIC_16:
+ case IPU_PIX_FMT_GENERIC_32:
+ case IPU_PIX_FMT_RGB565:
+ case IPU_PIX_FMT_BGR24:
+ case IPU_PIX_FMT_RGB24:
+ case IPU_PIX_FMT_YUV444:
+ case IPU_PIX_FMT_BGRA32:
+ case IPU_PIX_FMT_BGR32:
+ case IPU_PIX_FMT_RGBA32:
+ case IPU_PIX_FMT_RGB32:
+ case IPU_PIX_FMT_ABGR32:
+ case IPU_PIX_FMT_UYVY:
+ case IPU_PIX_FMT_YUYV:
+ case IPU_PIX_FMT_GPU32_SB_ST:
+ case IPU_PIX_FMT_GPU32_SB_SRT:
+ case IPU_PIX_FMT_GPU32_ST:
+ case IPU_PIX_FMT_GPU32_SRT:
+ case IPU_PIX_FMT_GPU16_SB_ST:
+ case IPU_PIX_FMT_GPU16_SB_SRT:
+ case IPU_PIX_FMT_GPU16_ST:
+ case IPU_PIX_FMT_GPU16_SRT:
+ *u_offset = 0;
+ *v_offset = 0;
+ break;
+ case IPU_PIX_FMT_YUV420P2:
+ case IPU_PIX_FMT_YUV420P:
+ if (uv_stride < stride / 2)
+ uv_stride = stride / 2;
+
+ *u_offset = stride * (height - vertical_offset - 1) +
+ (stride - horizontal_offset) +
+ (uv_stride * vertical_offset / 2) +
+ horizontal_offset / 2;
+ *v_offset = *u_offset + (uv_stride * height / 2);
+ u_fix = u ? (u + (uv_stride * vertical_offset / 2) +
+ (horizontal_offset / 2) -
+ (stride * vertical_offset) - (horizontal_offset)) :
+ *u_offset;
+ v_fix = v ? (v + (uv_stride * vertical_offset / 2) +
+ (horizontal_offset / 2) -
+ (stride * vertical_offset) - (horizontal_offset)) :
+ *v_offset;
+ break;
+ case IPU_PIX_FMT_YVU420P:
+ if (uv_stride < stride / 2)
+ uv_stride = stride / 2;
+
+ *v_offset = stride * (height - vertical_offset - 1) +
+ (stride - horizontal_offset) +
+ (uv_stride * vertical_offset / 2) +
+ horizontal_offset / 2;
+ *u_offset = *v_offset + (uv_stride * height / 2);
+ u_fix = u ? (u + (uv_stride * vertical_offset / 2) +
+ (horizontal_offset / 2) -
+ (stride * vertical_offset) - (horizontal_offset)) :
+ *u_offset;
+ v_fix = v ? (v + (uv_stride * vertical_offset / 2) +
+ (horizontal_offset / 2) -
+ (stride * vertical_offset) - (horizontal_offset)) :
+ *v_offset;
+ break;
+ case IPU_PIX_FMT_YVU422P:
+ if (uv_stride < stride / 2)
+ uv_stride = stride / 2;
+
+ *v_offset = stride * (height - vertical_offset - 1) +
+ (stride - horizontal_offset) +
+ (uv_stride * vertical_offset) +
+ horizontal_offset / 2;
+ *u_offset = *v_offset + uv_stride * height;
+ u_fix = u ? (u + (uv_stride * vertical_offset) +
+ horizontal_offset / 2 -
+ (stride * vertical_offset) - (horizontal_offset)) :
+ *u_offset;
+ v_fix = v ? (v + (uv_stride * vertical_offset) +
+ horizontal_offset / 2 -
+ (stride * vertical_offset) - (horizontal_offset)) :
+ *v_offset;
+ break;
+ case IPU_PIX_FMT_YUV422P:
+ if (uv_stride < stride / 2)
+ uv_stride = stride / 2;
+
+ *u_offset = stride * (height - vertical_offset - 1) +
+ (stride - horizontal_offset) +
+ (uv_stride * vertical_offset) +
+ horizontal_offset / 2;
+ *v_offset = *u_offset + uv_stride * height;
+ u_fix = u ? (u + (uv_stride * vertical_offset) +
+ horizontal_offset / 2 -
+ (stride * vertical_offset) - (horizontal_offset)) :
+ *u_offset;
+ v_fix = v ? (v + (uv_stride * vertical_offset) +
+ horizontal_offset / 2 -
+ (stride * vertical_offset) - (horizontal_offset)) :
+ *v_offset;
+ break;
+ case IPU_PIX_FMT_YUV444P:
+ uv_stride = stride;
+ *u_offset = stride * (height - vertical_offset - 1) +
+ (stride - horizontal_offset) +
+ (uv_stride * vertical_offset) +
+ horizontal_offset;
+ *v_offset = *u_offset + uv_stride * height;
+ u_fix = u ? (u + (uv_stride * vertical_offset) +
+ horizontal_offset -
+ (stride * vertical_offset) -
+ (horizontal_offset)) :
+ *u_offset;
+ v_fix = v ? (v + (uv_stride * vertical_offset) +
+ horizontal_offset -
+ (stride * vertical_offset) -
+ (horizontal_offset)) :
+ *v_offset;
+ break;
+ case IPU_PIX_FMT_NV12:
+ case IPU_PIX_FMT_NV16:
+ case PRE_PIX_FMT_NV21:
+ case PRE_PIX_FMT_NV61:
+ uv_stride = stride;
+ *u_offset = stride * (height - vertical_offset - 1) +
+ (stride - horizontal_offset) +
+ (uv_stride * vertical_offset / 2) +
+ horizontal_offset;
+ *v_offset = 0;
+ u_fix = u ? (u + (uv_stride * vertical_offset / 2) +
+ horizontal_offset -
+ (stride * vertical_offset) - (horizontal_offset)) :
+ *u_offset;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ if (u_fix > *u_offset)
+ *u_offset = u_fix;
+
+ if (v_fix > *v_offset)
+ *v_offset = v_fix;
+
+ return 0;
+}
+
+/* IDMAC U/V offset changing support */
+/* U and V input is not affected, */
+/* the update is done by new calculation according to */
+/* vertical_offset and horizontal_offset */
+static inline void _ipu_ch_offset_update(struct ipu_soc *ipu,
+ int ch,
+ uint32_t pixel_fmt,
+ uint32_t width,
+ uint32_t height,
+ uint32_t stride,
+ uint32_t u,
+ uint32_t v,
+ uint32_t uv_stride,
+ uint32_t vertical_offset,
+ uint32_t horizontal_offset)
+{
+ uint32_t u_offset = 0;
+ uint32_t v_offset = 0;
+ uint32_t old_offset = 0;
+ int32_t sub_ch = 0;
+ int ret;
+
+ ret = __ipu_ch_offset_calc(pixel_fmt, width, height, stride,
+ u, v, uv_stride,
+ vertical_offset, horizontal_offset,
+ &u_offset, &v_offset);
+ if (ret) {
+ dev_err(ipu->dev, "mxc ipu: unimplemented pixel format\n");
+ return;
+ }
+
+ /* UBO and VBO are 22-bit and 8-byte aligned */
+ if (u_offset/8 > 0x3fffff)
+ dev_warn(ipu->dev,
+ "IDMAC%d's U offset exceeds IPU limitation\n", ch);
+ if (v_offset/8 > 0x3fffff)
+ dev_warn(ipu->dev,
+ "IDMAC%d's V offset exceeds IPU limitation\n", ch);
+ if (u_offset%8)
+ dev_warn(ipu->dev,
+ "IDMAC%d's U offset is not 8-byte aligned\n", ch);
+ if (v_offset%8)
+ dev_warn(ipu->dev,
+ "IDMAC%d's V offset is not 8-byte aligned\n", ch);
+
+ old_offset = ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, ch), 0, 46, 22);
+ if (old_offset != u_offset / 8)
+ ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, ch), 0, 46, 22, u_offset / 8);
+ old_offset = ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, ch), 0, 68, 22);
+ if (old_offset != v_offset / 8)
+ ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, ch), 0, 68, 22, v_offset / 8);
+
+ sub_ch = __ipu_ch_get_third_buf_cpmem_num(ch);
+ if (sub_ch <= 0)
+ return;
+ old_offset = ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, sub_ch), 0, 46, 22);
+ if (old_offset != u_offset / 8)
+ ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, sub_ch), 0, 46, 22, u_offset / 8);
+ old_offset = ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, sub_ch), 0, 68, 22);
+ if (old_offset != v_offset / 8)
+ ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, sub_ch), 0, 68, 22, v_offset / 8);
+};
+
+static inline void _ipu_ch_params_set_alpha_width(struct ipu_soc *ipu, uint32_t ch, int alpha_width)
+{
+ int32_t sub_ch = 0;
+
+ ipu_ch_param_set_field_io(ipu_ch_param_addr(ipu, ch), 1, 125, 3, alpha_width - 1);
+
+ sub_ch = __ipu_ch_get_third_buf_cpmem_num(ch);
+ if (sub_ch <= 0)
+ return;
+ ipu_ch_param_set_field_io(ipu_ch_param_addr(ipu, sub_ch), 1, 125, 3, alpha_width - 1);
+};
+
+static inline void _ipu_ch_param_set_bandmode(struct ipu_soc *ipu,
+ uint32_t ch, uint32_t band_height)
+{
+ int32_t sub_ch = 0;
+
+ ipu_ch_param_set_field_io(ipu_ch_param_addr(ipu, ch),
+ 0, 114, 3, band_height - 1);
+ sub_ch = __ipu_ch_get_third_buf_cpmem_num(ch);
+ if (sub_ch <= 0)
+ return;
+ ipu_ch_param_set_field_io(ipu_ch_param_addr(ipu, sub_ch),
+ 0, 114, 3, band_height - 1);
+
+ dev_dbg(ipu->dev, "BNDM 0x%x, ",
+ ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, ch), 0, 114, 3));
+}
+
+/*
+ * The IPUv3 IDMAC has a bug to read 32bpp pixels from a graphics plane
+ * whose alpha component is at the most significant 8 bits. The bug only
+ * impacts on cases in which the relevant separate alpha channel is enabled.
+ *
+ * Return true on bad alpha component position, otherwise, return false.
+ */
+static inline bool _ipu_ch_param_bad_alpha_pos(uint32_t pixel_fmt)
+{
+ switch (pixel_fmt) {
+ case IPU_PIX_FMT_BGRA32:
+ case IPU_PIX_FMT_BGR32:
+ case IPU_PIX_FMT_RGBA32:
+ case IPU_PIX_FMT_RGB32:
+ return true;
+ }
+
+ return false;
+}
+#endif
diff --git a/drivers/mxc/ipu3/ipu_pixel_clk.c b/drivers/mxc/ipu3/ipu_pixel_clk.c
new file mode 100644
index 000000000000..66e73dd6284f
--- /dev/null
+++ b/drivers/mxc/ipu3/ipu_pixel_clk.c
@@ -0,0 +1,317 @@
+/*
+ * Copyright (C) 2013-2015 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/*!
+ * @file ipu_pixel_clk.c
+ *
+ * @brief IPU pixel clock implementation
+ *
+ * @ingroup IPU
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/ipu-v3.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+
+#include "ipu_prv.h"
+#include "ipu_regs.h"
+
+ /*
+ * muxd clock implementation
+ */
+struct clk_di_mux {
+ struct clk_hw hw;
+ u8 ipu_id;
+ u8 di_id;
+ u8 flags;
+ u8 index;
+};
+#define to_clk_di_mux(_hw) container_of(_hw, struct clk_di_mux, hw)
+
+static int _ipu_pixel_clk_set_parent(struct clk_hw *hw, u8 index)
+{
+ struct clk_di_mux *mux = to_clk_di_mux(hw);
+ struct ipu_soc *ipu = ipu_get_soc(mux->ipu_id);
+ u32 di_gen;
+
+ di_gen = ipu_di_read(ipu, mux->di_id, DI_GENERAL);
+ if (index == 0)
+ /* ipu1_clk or ipu2_clk internal clk */
+ di_gen &= ~DI_GEN_DI_CLK_EXT;
+ else
+ di_gen |= DI_GEN_DI_CLK_EXT;
+
+ ipu_di_write(ipu, mux->di_id, di_gen, DI_GENERAL);
+ mux->index = index;
+ pr_debug("ipu_pixel_clk: di_clk_ext:0x%x, di_gen reg:0x%x.\n",
+ !(di_gen & DI_GEN_DI_CLK_EXT), di_gen);
+ return 0;
+}
+
+static u8 _ipu_pixel_clk_get_parent(struct clk_hw *hw)
+{
+ struct clk_di_mux *mux = to_clk_di_mux(hw);
+
+ return mux->index;
+}
+
+const struct clk_ops clk_mux_di_ops = {
+ .get_parent = _ipu_pixel_clk_get_parent,
+ .set_parent = _ipu_pixel_clk_set_parent,
+};
+
+struct clk *clk_register_mux_pix_clk(struct device *dev, const char *name,
+ const char **parent_names, u8 num_parents, unsigned long flags,
+ u8 ipu_id, u8 di_id, u8 clk_mux_flags)
+{
+ struct clk_di_mux *mux;
+ struct clk *clk;
+ struct clk_init_data init;
+
+ mux = kzalloc(sizeof(struct clk_di_mux), GFP_KERNEL);
+ if (!mux)
+ return ERR_PTR(-ENOMEM);
+
+ init.name = name;
+ init.ops = &clk_mux_di_ops;
+ init.flags = flags;
+ init.parent_names = parent_names;
+ init.num_parents = num_parents;
+
+ mux->ipu_id = ipu_id;
+ mux->di_id = di_id;
+ mux->flags = clk_mux_flags | CLK_SET_RATE_PARENT;
+ mux->hw.init = &init;
+
+ clk = clk_register(dev, &mux->hw);
+ if (IS_ERR(clk))
+ kfree(mux);
+
+ return clk;
+}
+
+/*
+ * Gated clock implementation
+ */
+struct clk_di_div {
+ struct clk_hw hw;
+ u8 ipu_id;
+ u8 di_id;
+ u8 flags;
+};
+#define to_clk_di_div(_hw) container_of(_hw, struct clk_di_div, hw)
+
+static unsigned long _ipu_pixel_clk_div_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ struct clk_di_div *di_div = to_clk_di_div(hw);
+ struct ipu_soc *ipu = ipu_get_soc(di_div->ipu_id);
+ u32 div;
+ u64 final_rate = (unsigned long long)parent_rate * 16;
+
+ _ipu_get(ipu);
+ div = ipu_di_read(ipu, di_div->di_id, DI_BS_CLKGEN0);
+ _ipu_put(ipu);
+ pr_debug("ipu_di%d read BS_CLKGEN0 div:%d, final_rate:%lld, prate:%ld\n",
+ di_div->di_id, div, final_rate, parent_rate);
+
+ if (div == 0)
+ return 0;
+ do_div(final_rate, div);
+
+ return (unsigned long)final_rate;
+}
+
+static long _ipu_pixel_clk_div_round_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long *parent_clk_rate)
+{
+ u64 div, final_rate;
+ u32 remainder;
+ u64 parent_rate = (unsigned long long)(*parent_clk_rate) * 16;
+
+ /*
+ * Calculate divider
+ * Fractional part is 4 bits,
+ * so simply multiply by 2^4 to get fractional part.
+ */
+ div = parent_rate;
+ remainder = do_div(div, rate);
+ /* Round the divider value */
+ if (remainder > (rate/2))
+ div++;
+ if (div < 0x10) /* Min DI disp clock divider is 1 */
+ div = 0x10;
+ if (div & ~0xFEF)
+ div &= 0xFF8;
+ else {
+ /* Round up divider if it gets us closer to desired pix clk */
+ if ((div & 0xC) == 0xC) {
+ div += 0x10;
+ div &= ~0xF;
+ }
+ }
+ final_rate = parent_rate;
+ do_div(final_rate, div);
+
+ return final_rate;
+}
+
+static int _ipu_pixel_clk_div_set_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long parent_clk_rate)
+{
+ struct clk_di_div *di_div = to_clk_di_div(hw);
+ struct ipu_soc *ipu = ipu_get_soc(di_div->ipu_id);
+ u64 div, parent_rate;
+ u32 remainder;
+
+ parent_rate = (unsigned long long)parent_clk_rate * 16;
+ div = parent_rate;
+ remainder = do_div(div, rate);
+ /* Round the divider value */
+ if (remainder > (rate/2))
+ div++;
+
+ /* Round up divider if it gets us closer to desired pix clk */
+ if ((div & 0xC) == 0xC) {
+ div += 0x10;
+ div &= ~0xF;
+ }
+ if (div > 0x1000)
+ pr_err("Overflow, di:%d, DI_BS_CLKGEN0 div:0x%x\n",
+ di_div->di_id, (u32)div);
+ _ipu_get(ipu);
+ ipu_di_write(ipu, di_div->di_id, (u32)div, DI_BS_CLKGEN0);
+
+ /* Setup pixel clock timing */
+ /* FIXME: needs to be more flexible */
+ /* Down time is half of period */
+ ipu_di_write(ipu, di_div->di_id, ((u32)div / 16) << 16, DI_BS_CLKGEN1);
+ _ipu_put(ipu);
+
+ return 0;
+}
+
+static struct clk_ops clk_div_ops = {
+ .recalc_rate = _ipu_pixel_clk_div_recalc_rate,
+ .round_rate = _ipu_pixel_clk_div_round_rate,
+ .set_rate = _ipu_pixel_clk_div_set_rate,
+};
+
+struct clk *clk_register_div_pix_clk(struct device *dev, const char *name,
+ const char *parent_name, unsigned long flags,
+ u8 ipu_id, u8 di_id, u8 clk_div_flags)
+{
+ struct clk_di_div *di_div;
+ struct clk *clk;
+ struct clk_init_data init;
+
+ di_div = kzalloc(sizeof(struct clk_di_div), GFP_KERNEL);
+ if (!di_div)
+ return ERR_PTR(-ENOMEM);
+
+ /* struct clk_di_div assignments */
+ di_div->ipu_id = ipu_id;
+ di_div->di_id = di_id;
+ di_div->flags = clk_div_flags;
+
+ init.name = name;
+ init.ops = &clk_div_ops;
+ init.flags = flags | CLK_SET_RATE_PARENT;
+ init.parent_names = parent_name ? &parent_name : NULL;
+ init.num_parents = parent_name ? 1 : 0;
+
+ di_div->hw.init = &init;
+
+ clk = clk_register(dev, &di_div->hw);
+ if (IS_ERR(clk))
+ kfree(di_div);
+
+ return clk;
+}
+
+/*
+ * Gated clock implementation
+ */
+struct clk_di_gate {
+ struct clk_hw hw;
+ u8 ipu_id;
+ u8 di_id;
+ u8 flags;
+};
+#define to_clk_di_gate(_hw) container_of(_hw, struct clk_di_gate, hw)
+
+static int _ipu_pixel_clk_enable(struct clk_hw *hw)
+{
+ struct clk_di_gate *gate = to_clk_di_gate(hw);
+ struct ipu_soc *ipu = ipu_get_soc(gate->ipu_id);
+ u32 disp_gen;
+
+ disp_gen = ipu_cm_read(ipu, IPU_DISP_GEN);
+ disp_gen |= gate->di_id ? DI1_COUNTER_RELEASE : DI0_COUNTER_RELEASE;
+ ipu_cm_write(ipu, disp_gen, IPU_DISP_GEN);
+
+ return 0;
+}
+
+static void _ipu_pixel_clk_disable(struct clk_hw *hw)
+{
+ struct clk_di_gate *gate = to_clk_di_gate(hw);
+ struct ipu_soc *ipu = ipu_get_soc(gate->ipu_id);
+ u32 disp_gen;
+
+ disp_gen = ipu_cm_read(ipu, IPU_DISP_GEN);
+ disp_gen &= gate->di_id ? ~DI1_COUNTER_RELEASE : ~DI0_COUNTER_RELEASE;
+ ipu_cm_write(ipu, disp_gen, IPU_DISP_GEN);
+
+}
+
+
+static struct clk_ops clk_gate_di_ops = {
+ .enable = _ipu_pixel_clk_enable,
+ .disable = _ipu_pixel_clk_disable,
+};
+
+struct clk *clk_register_gate_pix_clk(struct device *dev, const char *name,
+ const char *parent_name, unsigned long flags,
+ u8 ipu_id, u8 di_id, u8 clk_gate_flags)
+{
+ struct clk_di_gate *gate;
+ struct clk *clk;
+ struct clk_init_data init;
+
+ gate = kzalloc(sizeof(struct clk_di_gate), GFP_KERNEL);
+ if (!gate)
+ return ERR_PTR(-ENOMEM);
+
+ gate->ipu_id = ipu_id;
+ gate->di_id = di_id;
+ gate->flags = clk_gate_flags;
+
+ init.name = name;
+ init.ops = &clk_gate_di_ops;
+ init.flags = flags | CLK_SET_RATE_PARENT;
+ init.parent_names = parent_name ? &parent_name : NULL;
+ init.num_parents = parent_name ? 1 : 0;
+
+ gate->hw.init = &init;
+
+ clk = clk_register(dev, &gate->hw);
+ if (IS_ERR(clk))
+ kfree(gate);
+
+ return clk;
+}
diff --git a/drivers/mxc/ipu3/ipu_prv.h b/drivers/mxc/ipu3/ipu_prv.h
new file mode 100644
index 000000000000..0a21d922c127
--- /dev/null
+++ b/drivers/mxc/ipu3/ipu_prv.h
@@ -0,0 +1,369 @@
+/*
+ * Copyright 2005-2016 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+#ifndef __INCLUDE_IPU_PRV_H__
+#define __INCLUDE_IPU_PRV_H__
+
+#include <linux/clkdev.h>
+#include <linux/device.h>
+#include <linux/fsl_devices.h>
+#include <linux/interrupt.h>
+#include <linux/ipu-v3.h>
+#include <linux/types.h>
+
+#define MXC_IPU_MAX_NUM 2
+#define MXC_DI_NUM_PER_IPU 2
+
+/* Globals */
+extern int dmfc_type_setup;
+
+#define IDMA_CHAN_INVALID 0xFF
+#define HIGH_RESOLUTION_WIDTH 1024
+
+enum ipuv3_type {
+ IPUv3D, /* i.MX37 */
+ IPUv3EX, /* i.MX51 */
+ IPUv3M, /* i.MX53 */
+ IPUv3H, /* i.MX6Q/SDL */
+};
+
+#define IPU_MAX_VDI_IN_WIDTH(type) ({ (type) >= IPUv3M ? 968 : 720; })
+
+struct ipu_irq_node {
+ irqreturn_t(*handler) (int, void *); /*!< the ISR */
+ const char *name; /*!< device associated with the interrupt */
+ void *dev_id; /*!< some unique information for the ISR */
+ __u32 flags; /*!< not used */
+};
+
+enum csc_type_t {
+ RGB2YUV = 0,
+ YUV2RGB,
+ RGB2RGB,
+ YUV2YUV,
+ CSC_NONE,
+ CSC_NUM
+};
+
+struct ipu_soc {
+ unsigned int id;
+ unsigned int devtype;
+ bool online;
+
+ /*clk*/
+ struct clk *ipu_clk;
+ struct clk *di_clk[2];
+ struct clk *di_clk_sel[2];
+ struct clk *pixel_clk[2];
+ bool pixel_clk_en[2];
+ struct clk *pixel_clk_sel[2];
+ struct clk *csi_clk[2];
+ struct clk *prg_clk;
+
+ /*irq*/
+ int irq_sync;
+ int irq_err;
+ struct ipu_irq_node irq_list[IPU_IRQ_COUNT];
+
+ /*reg*/
+ void __iomem *cm_reg;
+ void __iomem *idmac_reg;
+ void __iomem *dp_reg;
+ void __iomem *ic_reg;
+ void __iomem *dc_reg;
+ void __iomem *dc_tmpl_reg;
+ void __iomem *dmfc_reg;
+ void __iomem *di_reg[2];
+ void __iomem *smfc_reg;
+ void __iomem *csi_reg[2];
+ void __iomem *cpmem_base;
+ void __iomem *tpmem_base;
+ void __iomem *vdi_reg;
+
+ struct device *dev;
+
+ ipu_channel_t csi_channel[2];
+ ipu_channel_t using_ic_dirct_ch;
+ unsigned char dc_di_assignment[10];
+ bool sec_chan_en[IPU_MAX_CH];
+ bool thrd_chan_en[IPU_MAX_CH];
+ bool chan_is_interlaced[52];
+ uint32_t channel_init_mask;
+ uint32_t channel_enable_mask;
+
+ /*use count*/
+ int dc_use_count;
+ int dp_use_count;
+ int dmfc_use_count;
+ int smfc_use_count;
+ int ic_use_count;
+ int rot_use_count;
+ int vdi_use_count;
+ int di_use_count[2];
+ int csi_use_count[2];
+
+ struct mutex mutex_lock;
+ spinlock_t int_reg_spin_lock;
+ spinlock_t rdy_reg_spin_lock;
+
+ int dmfc_size_28;
+ int dmfc_size_29;
+ int dmfc_size_24;
+ int dmfc_size_27;
+ int dmfc_size_23;
+
+ enum csc_type_t fg_csc_type;
+ enum csc_type_t bg_csc_type;
+ bool color_key_4rgb;
+ bool dc_swap;
+ struct completion dc_comp;
+ struct completion csi_comp;
+
+ struct rot_mem {
+ void *vaddr;
+ dma_addr_t paddr;
+ int size;
+ } rot_dma[2];
+
+ int vdoa_en;
+ struct task_struct *thread[2];
+
+ /*
+ * Bypass reset to avoid display channel being
+ * stopped by probe since it may starts to work
+ * in bootloader.
+ */
+ bool bypass_reset;
+
+ unsigned int ch0123_axi;
+ unsigned int ch23_axi;
+ unsigned int ch27_axi;
+ unsigned int ch28_axi;
+ unsigned int normal_axi;
+
+ bool smfc_idmac_12bit_3planar_bs_fixup; /* workaround little stripes */
+};
+
+struct ipu_channel {
+ u8 video_in_dma;
+ u8 alpha_in_dma;
+ u8 graph_in_dma;
+ u8 out_dma;
+};
+
+enum ipu_dmfc_type {
+ DMFC_NORMAL = 0,
+ DMFC_HIGH_RESOLUTION_DC,
+ DMFC_HIGH_RESOLUTION_DP,
+ DMFC_HIGH_RESOLUTION_ONLY_DP,
+};
+
+static inline int _ipu_is_smfc_chan(uint32_t dma_chan)
+{
+ return dma_chan <= 3;
+}
+
+static inline u32 ipu_cm_read(struct ipu_soc *ipu, unsigned offset)
+{
+ return readl(ipu->cm_reg + offset);
+}
+
+static inline void ipu_cm_write(struct ipu_soc *ipu,
+ u32 value, unsigned offset)
+{
+ writel(value, ipu->cm_reg + offset);
+}
+
+static inline u32 ipu_idmac_read(struct ipu_soc *ipu, unsigned offset)
+{
+ return readl(ipu->idmac_reg + offset);
+}
+
+static inline void ipu_idmac_write(struct ipu_soc *ipu,
+ u32 value, unsigned offset)
+{
+ writel(value, ipu->idmac_reg + offset);
+}
+
+static inline u32 ipu_dc_read(struct ipu_soc *ipu, unsigned offset)
+{
+ return readl(ipu->dc_reg + offset);
+}
+
+static inline void ipu_dc_write(struct ipu_soc *ipu,
+ u32 value, unsigned offset)
+{
+ writel(value, ipu->dc_reg + offset);
+}
+
+static inline u32 ipu_dc_tmpl_read(struct ipu_soc *ipu, unsigned offset)
+{
+ return readl(ipu->dc_tmpl_reg + offset);
+}
+
+static inline void ipu_dc_tmpl_write(struct ipu_soc *ipu,
+ u32 value, unsigned offset)
+{
+ writel(value, ipu->dc_tmpl_reg + offset);
+}
+
+static inline u32 ipu_dmfc_read(struct ipu_soc *ipu, unsigned offset)
+{
+ return readl(ipu->dmfc_reg + offset);
+}
+
+static inline void ipu_dmfc_write(struct ipu_soc *ipu,
+ u32 value, unsigned offset)
+{
+ writel(value, ipu->dmfc_reg + offset);
+}
+
+static inline u32 ipu_dp_read(struct ipu_soc *ipu, unsigned offset)
+{
+ return readl(ipu->dp_reg + offset);
+}
+
+static inline void ipu_dp_write(struct ipu_soc *ipu,
+ u32 value, unsigned offset)
+{
+ writel(value, ipu->dp_reg + offset);
+}
+
+static inline u32 ipu_di_read(struct ipu_soc *ipu, int di, unsigned offset)
+{
+ return readl(ipu->di_reg[di] + offset);
+}
+
+static inline void ipu_di_write(struct ipu_soc *ipu, int di,
+ u32 value, unsigned offset)
+{
+ writel(value, ipu->di_reg[di] + offset);
+}
+
+static inline u32 ipu_csi_read(struct ipu_soc *ipu, int csi, unsigned offset)
+{
+ return readl(ipu->csi_reg[csi] + offset);
+}
+
+static inline void ipu_csi_write(struct ipu_soc *ipu, int csi,
+ u32 value, unsigned offset)
+{
+ writel(value, ipu->csi_reg[csi] + offset);
+}
+
+static inline u32 ipu_smfc_read(struct ipu_soc *ipu, unsigned offset)
+{
+ return readl(ipu->smfc_reg + offset);
+}
+
+static inline void ipu_smfc_write(struct ipu_soc *ipu,
+ u32 value, unsigned offset)
+{
+ writel(value, ipu->smfc_reg + offset);
+}
+
+static inline u32 ipu_vdi_read(struct ipu_soc *ipu, unsigned offset)
+{
+ return readl(ipu->vdi_reg + offset);
+}
+
+static inline void ipu_vdi_write(struct ipu_soc *ipu,
+ u32 value, unsigned offset)
+{
+ writel(value, ipu->vdi_reg + offset);
+}
+
+static inline u32 ipu_ic_read(struct ipu_soc *ipu, unsigned offset)
+{
+ return readl(ipu->ic_reg + offset);
+}
+
+static inline void ipu_ic_write(struct ipu_soc *ipu,
+ u32 value, unsigned offset)
+{
+ writel(value, ipu->ic_reg + offset);
+}
+
+int register_ipu_device(struct ipu_soc *ipu, int id);
+void unregister_ipu_device(struct ipu_soc *ipu, int id);
+ipu_color_space_t format_to_colorspace(uint32_t fmt);
+bool ipu_pixel_format_has_alpha(uint32_t fmt);
+
+void ipu_dump_registers(struct ipu_soc *ipu);
+
+uint32_t _ipu_channel_status(struct ipu_soc *ipu, ipu_channel_t channel);
+
+void ipu_disp_init(struct ipu_soc *ipu);
+void _ipu_init_dc_mappings(struct ipu_soc *ipu);
+int _ipu_dp_init(struct ipu_soc *ipu, ipu_channel_t channel, uint32_t in_pixel_fmt,
+ uint32_t out_pixel_fmt);
+void _ipu_dp_uninit(struct ipu_soc *ipu, ipu_channel_t channel);
+void _ipu_dc_init(struct ipu_soc *ipu, int dc_chan, int di, bool interlaced, uint32_t pixel_fmt);
+void _ipu_dc_uninit(struct ipu_soc *ipu, int dc_chan);
+void _ipu_dp_dc_enable(struct ipu_soc *ipu, ipu_channel_t channel);
+void _ipu_dp_dc_disable(struct ipu_soc *ipu, ipu_channel_t channel, bool swap);
+void _ipu_dmfc_init(struct ipu_soc *ipu, int dmfc_type, int first);
+void _ipu_dmfc_set_wait4eot(struct ipu_soc *ipu, int dma_chan, int width);
+void _ipu_dmfc_set_burst_size(struct ipu_soc *ipu, int dma_chan, int burst_size);
+int _ipu_disp_chan_is_interlaced(struct ipu_soc *ipu, ipu_channel_t channel);
+
+void _ipu_ic_enable_task(struct ipu_soc *ipu, ipu_channel_t channel);
+void _ipu_ic_disable_task(struct ipu_soc *ipu, ipu_channel_t channel);
+int _ipu_ic_init_prpvf(struct ipu_soc *ipu, ipu_channel_params_t *params,
+ bool src_is_csi);
+void _ipu_vdi_init(struct ipu_soc *ipu, ipu_channel_t channel, ipu_channel_params_t *params);
+void _ipu_vdi_uninit(struct ipu_soc *ipu);
+void _ipu_ic_uninit_prpvf(struct ipu_soc *ipu);
+void _ipu_ic_init_rotate_vf(struct ipu_soc *ipu, ipu_channel_params_t *params);
+void _ipu_ic_uninit_rotate_vf(struct ipu_soc *ipu);
+void _ipu_ic_init_csi(struct ipu_soc *ipu, ipu_channel_params_t *params);
+void _ipu_ic_uninit_csi(struct ipu_soc *ipu);
+int _ipu_ic_init_prpenc(struct ipu_soc *ipu, ipu_channel_params_t *params,
+ bool src_is_csi);
+void _ipu_ic_uninit_prpenc(struct ipu_soc *ipu);
+void _ipu_ic_init_rotate_enc(struct ipu_soc *ipu, ipu_channel_params_t *params);
+void _ipu_ic_uninit_rotate_enc(struct ipu_soc *ipu);
+int _ipu_ic_init_pp(struct ipu_soc *ipu, ipu_channel_params_t *params);
+void _ipu_ic_uninit_pp(struct ipu_soc *ipu);
+void _ipu_ic_init_rotate_pp(struct ipu_soc *ipu, ipu_channel_params_t *params);
+void _ipu_ic_uninit_rotate_pp(struct ipu_soc *ipu);
+int _ipu_ic_idma_init(struct ipu_soc *ipu, int dma_chan, uint16_t width, uint16_t height,
+ int burst_size, ipu_rotate_mode_t rot);
+void _ipu_vdi_toggle_top_field_man(struct ipu_soc *ipu);
+int _ipu_csi_init(struct ipu_soc *ipu, ipu_channel_t channel, uint32_t csi);
+int _ipu_csi_set_mipi_di(struct ipu_soc *ipu, uint32_t num, uint32_t di_val, uint32_t csi);
+void ipu_csi_set_test_generator(struct ipu_soc *ipu, bool active, uint32_t r_value,
+ uint32_t g_value, uint32_t b_value,
+ uint32_t pix_clk, uint32_t csi);
+void _ipu_csi_ccir_err_detection_enable(struct ipu_soc *ipu, uint32_t csi);
+void _ipu_csi_ccir_err_detection_disable(struct ipu_soc *ipu, uint32_t csi);
+void _ipu_csi_wait4eof(struct ipu_soc *ipu, ipu_channel_t channel);
+void _ipu_smfc_init(struct ipu_soc *ipu, ipu_channel_t channel, uint32_t mipi_id, uint32_t csi);
+void _ipu_smfc_set_burst_size(struct ipu_soc *ipu, ipu_channel_t channel, uint32_t bs);
+void _ipu_dp_set_csc_coefficients(struct ipu_soc *ipu, ipu_channel_t channel, int32_t param[][3]);
+int32_t _ipu_disp_set_window_pos(struct ipu_soc *ipu, ipu_channel_t channel,
+ int16_t x_pos, int16_t y_pos);
+int32_t _ipu_disp_get_window_pos(struct ipu_soc *ipu, ipu_channel_t channel,
+ int16_t *x_pos, int16_t *y_pos);
+void _ipu_get(struct ipu_soc *ipu);
+void _ipu_put(struct ipu_soc *ipu);
+
+struct clk *clk_register_mux_pix_clk(struct device *dev, const char *name,
+ const char **parent_names, u8 num_parents, unsigned long flags,
+ u8 ipu_id, u8 di_id, u8 clk_mux_flags);
+struct clk *clk_register_div_pix_clk(struct device *dev, const char *name,
+ const char *parent_name, unsigned long flags,
+ u8 ipu_id, u8 di_id, u8 clk_div_flags);
+struct clk *clk_register_gate_pix_clk(struct device *dev, const char *name,
+ const char *parent_name, unsigned long flags,
+ u8 ipu_id, u8 di_id, u8 clk_gate_flags);
+#endif /* __INCLUDE_IPU_PRV_H__ */
diff --git a/drivers/mxc/ipu3/ipu_regs.h b/drivers/mxc/ipu3/ipu_regs.h
new file mode 100644
index 000000000000..099346da3e1b
--- /dev/null
+++ b/drivers/mxc/ipu3/ipu_regs.h
@@ -0,0 +1,702 @@
+/*
+ * Copyright (C) 2005-2015 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/*
+ * @file ipu_regs.h
+ *
+ * @brief IPU Register definitions
+ *
+ * @ingroup IPU
+ */
+#ifndef __IPU_REGS_INCLUDED__
+#define __IPU_REGS_INCLUDED__
+
+#include "ipu_prv.h"
+
+#define IPU_MCU_T_DEFAULT 8
+
+/* Register addresses */
+/* IPU Common registers */
+#define IPU_CM_REG(offset) (offset)
+
+#define IPU_CONF IPU_CM_REG(0)
+#define IPU_SRM_PRI1 IPU_CM_REG(0x00A0)
+#define IPU_SRM_PRI2 IPU_CM_REG(0x00A4)
+#define IPU_FS_PROC_FLOW1 IPU_CM_REG(0x00A8)
+#define IPU_FS_PROC_FLOW2 IPU_CM_REG(0x00AC)
+#define IPU_FS_PROC_FLOW3 IPU_CM_REG(0x00B0)
+#define IPU_FS_DISP_FLOW1 IPU_CM_REG(0x00B4)
+#define IPU_FS_DISP_FLOW2 IPU_CM_REG(0x00B8)
+#define IPU_SKIP IPU_CM_REG(0x00BC)
+#define IPU_DISP_ALT_CONF IPU_CM_REG(0x00C0)
+#define IPU_DISP_GEN IPU_CM_REG(0x00C4)
+#define IPU_DISP_ALT1 IPU_CM_REG(0x00C8)
+#define IPU_DISP_ALT2 IPU_CM_REG(0x00CC)
+#define IPU_DISP_ALT3 IPU_CM_REG(0x00D0)
+#define IPU_DISP_ALT4 IPU_CM_REG(0x00D4)
+#define IPU_SNOOP IPU_CM_REG(0x00D8)
+#define IPU_MEM_RST IPU_CM_REG(0x00DC)
+#define IPU_PM IPU_CM_REG(0x00E0)
+#define IPU_GPR IPU_CM_REG(0x00E4)
+#define IPU_CHA_DB_MODE_SEL(ch) IPU_CM_REG(0x0150 + 4 * ((ch) / 32))
+#define IPU_ALT_CHA_DB_MODE_SEL(ch) IPU_CM_REG(0x0168 + 4 * ((ch) / 32))
+/*
+ * IPUv3D doesn't support triple buffer, so point
+ * IPU_CHA_TRB_MODE_SEL, IPU_CHA_TRIPLE_CUR_BUF and
+ * IPU_CHA_BUF2_RDY to readonly
+ * IPU_ALT_CUR_BUF0 for IPUv3D.
+ */
+#define IPU_CHA_TRB_MODE_SEL(type, ch) IPU_CM_REG({(type) >= IPUv3EX ? \
+ (0x0178 + 4 * ((ch) / 32)) : \
+ (0x012C); })
+#define IPU_CHA_TRIPLE_CUR_BUF(type, ch) IPU_CM_REG({(type) >= IPUv3EX ? \
+ (0x0258 + \
+ 4 * (((ch) * 2) / 32)) : \
+ (0x012C); })
+#define IPU_CHA_BUF2_RDY(type, ch) IPU_CM_REG({(type) >= IPUv3EX ? \
+ (0x0288 + 4 * ((ch) / 32)) : \
+ (0x012C); })
+#define IPU_CHA_CUR_BUF(type, ch) IPU_CM_REG({(type) >= IPUv3EX ? \
+ (0x023C + 4 * ((ch) / 32)) : \
+ (0x0124 + 4 * ((ch) / 32)); })
+#define IPU_ALT_CUR_BUF0(type) IPU_CM_REG({(type) >= IPUv3EX ? \
+ (0x0244) : \
+ (0x012C); })
+#define IPU_ALT_CUR_BUF1(type) IPU_CM_REG({(type) >= IPUv3EX ? \
+ (0x0248) : \
+ (0x0130); })
+#define IPU_SRM_STAT(type) IPU_CM_REG({(type) >= IPUv3EX ? \
+ (0x024C) : \
+ (0x0134); })
+#define IPU_PROC_TASK_STAT(type) IPU_CM_REG({(type) >= IPUv3EX ? \
+ (0x0250) : \
+ (0x0138); })
+#define IPU_DISP_TASK_STAT(type) IPU_CM_REG({(type) >= IPUv3EX ? \
+ (0x0254) : \
+ (0x013C); })
+#define IPU_CHA_BUF0_RDY(type, ch) IPU_CM_REG({(type) >= IPUv3EX ? \
+ (0x0268 + 4 * ((ch) / 32)) : \
+ (0x0140 + 4 * ((ch) / 32)); })
+#define IPU_CHA_BUF1_RDY(type, ch) IPU_CM_REG({(type) >= IPUv3EX ? \
+ (0x0270 + 4 * ((ch) / 32)) : \
+ (0x0148 + 4 * ((ch) / 32)); })
+#define IPU_ALT_CHA_BUF0_RDY(type, ch) IPU_CM_REG({(type) >= IPUv3EX ? \
+ (0x0278 + 4 * ((ch) / 32)) : \
+ (0x0158 + 4 * ((ch) / 32)); })
+#define IPU_ALT_CHA_BUF1_RDY(type, ch) IPU_CM_REG({(type) >= IPUv3EX ? \
+ (0x0280 + 4 * ((ch) / 32)) : \
+ (0x0160 + 4 * ((ch) / 32)); })
+
+#define IPU_INT_CTRL(n) IPU_CM_REG(0x003C + 4 * ((n) - 1))
+#define IPU_INT_STAT(type, n) IPU_CM_REG({(type) >= IPUv3EX ? \
+ (0x0200 + 4 * ((n) - 1)) : \
+ (0x00E8 + 4 * ((n) - 1)); })
+
+#define IPUIRQ_2_STATREG(type, irq) IPU_CM_REG(IPU_INT_STAT((type), 1) + 4 \
+ * ((irq) / 32))
+#define IPUIRQ_2_CTRLREG(irq) IPU_CM_REG(IPU_INT_CTRL(1) + 4 * ((irq) / 32))
+#define IPUIRQ_2_MASK(irq) (1UL << ((irq) & 0x1F))
+
+/* IPU VDI registers */
+#define IPU_VDI_REG(offset) (offset)
+
+#define VDI_FSIZE IPU_VDI_REG(0)
+#define VDI_C IPU_VDI_REG(0x0004)
+
+/* IPU CSI Registers */
+#define IPU_CSI_REG(offset) (offset)
+
+#define CSI_SENS_CONF IPU_CSI_REG(0)
+#define CSI_SENS_FRM_SIZE IPU_CSI_REG(0x0004)
+#define CSI_ACT_FRM_SIZE IPU_CSI_REG(0x0008)
+#define CSI_OUT_FRM_CTRL IPU_CSI_REG(0x000C)
+#define CSI_TST_CTRL IPU_CSI_REG(0x0010)
+#define CSI_CCIR_CODE_1 IPU_CSI_REG(0x0014)
+#define CSI_CCIR_CODE_2 IPU_CSI_REG(0x0018)
+#define CSI_CCIR_CODE_3 IPU_CSI_REG(0x001C)
+#define CSI_MIPI_DI IPU_CSI_REG(0x0020)
+#define CSI_SKIP IPU_CSI_REG(0x0024)
+#define CSI_CPD_CTRL IPU_CSI_REG(0x0028)
+#define CSI_CPD_RC(n) IPU_CSI_REG(0x002C + 4 * (n))
+#define CSI_CPD_RS(n) IPU_CSI_REG(0x004C + 4 * (n))
+#define CSI_CPD_GRC(n) IPU_CSI_REG(0x005C + 4 * (n))
+#define CSI_CPD_GRS(n) IPU_CSI_REG(0x007C + 4 * (n))
+#define CSI_CPD_GBC(n) IPU_CSI_REG(0x008C + 4 * (n))
+#define CSI_CPD_GBS(n) IPU_CSI_REG(0x00AC + 4 * (n))
+#define CSI_CPD_BC(n) IPU_CSI_REG(0x00BC + 4 * (n))
+#define CSI_CPD_BS(n) IPU_CSI_REG(0x00DC + 4 * (n))
+#define CSI_CPD_OFFSET1 IPU_CSI_REG(0x00EC)
+#define CSI_CPD_OFFSET2 IPU_CSI_REG(0x00F0)
+
+/* IPU SMFC Registers */
+#define IPU_SMFC_REG(offset) (offset)
+
+#define SMFC_MAP IPU_SMFC_REG(0)
+#define SMFC_WMC IPU_SMFC_REG(0x0004)
+#define SMFC_BS IPU_SMFC_REG(0x0008)
+
+/* IPU IC Registers */
+#define IPU_IC_REG(offset) (offset)
+
+#define IC_CONF IPU_IC_REG(0)
+#define IC_PRP_ENC_RSC IPU_IC_REG(0x0004)
+#define IC_PRP_VF_RSC IPU_IC_REG(0x0008)
+#define IC_PP_RSC IPU_IC_REG(0x000C)
+#define IC_CMBP_1 IPU_IC_REG(0x0010)
+#define IC_CMBP_2 IPU_IC_REG(0x0014)
+#define IC_IDMAC_1 IPU_IC_REG(0x0018)
+#define IC_IDMAC_2 IPU_IC_REG(0x001C)
+#define IC_IDMAC_3 IPU_IC_REG(0x0020)
+#define IC_IDMAC_4 IPU_IC_REG(0x0024)
+
+/* IPU IDMAC Registers */
+#define IPU_IDMAC_REG(offset) (offset)
+
+#define IDMAC_CONF IPU_IDMAC_REG(0x0000)
+#define IDMAC_CHA_EN(ch) IPU_IDMAC_REG(0x0004 + 4 * ((ch) / 32))
+#define IDMAC_SEP_ALPHA IPU_IDMAC_REG(0x000C)
+#define IDMAC_ALT_SEP_ALPHA IPU_IDMAC_REG(0x0010)
+#define IDMAC_CHA_PRI(ch) IPU_IDMAC_REG(0x0014 + 4 * ((ch) / 32))
+#define IDMAC_WM_EN(ch) IPU_IDMAC_REG(0x001C + 4 * ((ch) / 32))
+#define IDMAC_CH_LOCK_EN_1(type) IPU_IDMAC_REG({(type) >= IPUv3EX ? \
+ (0x0024) : 0; })
+#define IDMAC_CH_LOCK_EN_2(type) IPU_IDMAC_REG({(type) >= IPUv3EX ? \
+ (0x0028) : \
+ (0x0024); })
+#define IDMAC_SUB_ADDR_0(type) IPU_IDMAC_REG({(type) >= IPUv3EX ? \
+ (0x002C) : \
+ (0x0028); })
+#define IDMAC_SUB_ADDR_1(type) IPU_IDMAC_REG({(type) >= IPUv3EX ? \
+ (0x0030) : \
+ (0x002C); })
+#define IDMAC_SUB_ADDR_2(type) IPU_IDMAC_REG({(type) >= IPUv3EX ? \
+ (0x0034) : \
+ (0x0030); })
+/*
+ * IPUv3D doesn't support IDMAC_SUB_ADDR_3 and IDMAC_SUB_ADDR_4,
+ * so point them to readonly IDMAC_CHA_BUSY1 for IPUv3D.
+ */
+#define IDMAC_SUB_ADDR_3(type) IPU_IDMAC_REG({(type) >= IPUv3EX ? \
+ (0x0038) : \
+ (0x0040); })
+#define IDMAC_SUB_ADDR_4(type) IPU_IDMAC_REG({(type) >= IPUv3EX ? \
+ (0x003C) : \
+ (0x0040); })
+#define IDMAC_BAND_EN(type, ch) IPU_IDMAC_REG({(type) >= IPUv3EX ? \
+ (0x0040 + 4 * ((ch) / 32)) : \
+ (0x0034 + 4 * ((ch) / 32)); })
+#define IDMAC_CHA_BUSY(type, ch) IPU_IDMAC_REG({(type) >= IPUv3EX ? \
+ (0x0100 + 4 * ((ch) / 32)) : \
+ (0x0040 + 4 * ((ch) / 32)); })
+
+/* IPU DI Registers */
+#define IPU_DI_REG(offset) (offset)
+
+#define DI_GENERAL IPU_DI_REG(0)
+#define DI_BS_CLKGEN0 IPU_DI_REG(0x0004)
+#define DI_BS_CLKGEN1 IPU_DI_REG(0x0008)
+#define DI_SW_GEN0(gen) IPU_DI_REG(0x000C + 4 * ((gen) - 1))
+#define DI_SW_GEN1(gen) IPU_DI_REG(0x0030 + 4 * ((gen) - 1))
+#define DI_STP_REP(gen) IPU_DI_REG(0x0148 + 4 * (((gen) - 1) / 2))
+#define DI_SYNC_AS_GEN IPU_DI_REG(0x0054)
+#define DI_DW_GEN(gen) IPU_DI_REG(0x0058 + 4 * (gen))
+#define DI_DW_SET(gen, set) IPU_DI_REG(0x0088 + 4 * ((gen) + 0xC * (set)))
+#define DI_SER_CONF IPU_DI_REG(0x015C)
+#define DI_SSC IPU_DI_REG(0x0160)
+#define DI_POL IPU_DI_REG(0x0164)
+#define DI_AW0 IPU_DI_REG(0x0168)
+#define DI_AW1 IPU_DI_REG(0x016C)
+#define DI_SCR_CONF IPU_DI_REG(0x0170)
+#define DI_STAT IPU_DI_REG(0x0174)
+
+/* IPU DMFC Registers */
+#define IPU_DMFC_REG(offset) (offset)
+
+#define DMFC_RD_CHAN IPU_DMFC_REG(0)
+#define DMFC_WR_CHAN IPU_DMFC_REG(0x0004)
+#define DMFC_WR_CHAN_DEF IPU_DMFC_REG(0x0008)
+#define DMFC_DP_CHAN IPU_DMFC_REG(0x000C)
+#define DMFC_DP_CHAN_DEF IPU_DMFC_REG(0x0010)
+#define DMFC_GENERAL1 IPU_DMFC_REG(0x0014)
+#define DMFC_GENERAL2 IPU_DMFC_REG(0x0018)
+#define DMFC_IC_CTRL IPU_DMFC_REG(0x001C)
+#define DMFC_STAT IPU_DMFC_REG(0x0020)
+
+/* IPU DC Registers */
+#define IPU_DC_REG(offset) (offset)
+
+#define DC_MAP_CONF_PTR(n) IPU_DC_REG(0x0108 + ((n) & ~0x1) * 2)
+#define DC_MAP_CONF_VAL(n) IPU_DC_REG(0x0144 + ((n) & ~0x1) * 2)
+
+#define _RL_CH_2_OFFSET(ch) (((ch) == 0) ? 8 : ( \
+ ((ch) == 1) ? 0x24 : ( \
+ ((ch) == 2) ? 0x40 : ( \
+ ((ch) == 5) ? 0x64 : ( \
+ ((ch) == 6) ? 0x80 : ( \
+ ((ch) == 8) ? 0x9C : ( \
+ ((ch) == 9) ? 0xBC : (-1))))))))
+#define DC_RL_CH(ch, evt) IPU_DC_REG(_RL_CH_2_OFFSET(ch) + \
+ ((evt) & ~0x1) * 2)
+
+#define DC_EVT_NF 0
+#define DC_EVT_NL 1
+#define DC_EVT_EOF 2
+#define DC_EVT_NFIELD 3
+#define DC_EVT_EOL 4
+#define DC_EVT_EOFIELD 5
+#define DC_EVT_NEW_ADDR 6
+#define DC_EVT_NEW_CHAN 7
+#define DC_EVT_NEW_DATA 8
+
+#define DC_EVT_NEW_ADDR_W_0 0
+#define DC_EVT_NEW_ADDR_W_1 1
+#define DC_EVT_NEW_CHAN_W_0 2
+#define DC_EVT_NEW_CHAN_W_1 3
+#define DC_EVT_NEW_DATA_W_0 4
+#define DC_EVT_NEW_DATA_W_1 5
+#define DC_EVT_NEW_ADDR_R_0 6
+#define DC_EVT_NEW_ADDR_R_1 7
+#define DC_EVT_NEW_CHAN_R_0 8
+#define DC_EVT_NEW_CHAN_R_1 9
+#define DC_EVT_NEW_DATA_R_0 10
+#define DC_EVT_NEW_DATA_R_1 11
+#define DC_EVEN_UGDE0 12
+#define DC_ODD_UGDE0 13
+#define DC_EVEN_UGDE1 14
+#define DC_ODD_UGDE1 15
+#define DC_EVEN_UGDE2 16
+#define DC_ODD_UGDE2 17
+#define DC_EVEN_UGDE3 18
+#define DC_ODD_UGDE3 19
+
+#define dc_ch_offset(ch) \
+({ \
+ const u8 _offset[] = { \
+ 0, 0x1C, 0x38, 0x54, 0x58, 0x5C, 0x78, 0, 0x94, 0xB4}; \
+ _offset[ch]; \
+})
+#define DC_WR_CH_CONF(ch) IPU_DC_REG(dc_ch_offset(ch))
+#define DC_WR_CH_ADDR(ch) IPU_DC_REG(dc_ch_offset(ch) + 4)
+
+#define DC_WR_CH_CONF_1 IPU_DC_REG(0x001C)
+#define DC_WR_CH_ADDR_1 IPU_DC_REG(0x0020)
+#define DC_WR_CH_CONF_5 IPU_DC_REG(0x005C)
+#define DC_WR_CH_ADDR_5 IPU_DC_REG(0x0060)
+#define DC_GEN IPU_DC_REG(0x00D4)
+#define DC_DISP_CONF1(disp) IPU_DC_REG(0x00D8 + 4 * (disp))
+#define DC_DISP_CONF2(disp) IPU_DC_REG(0x00E8 + 4 * (disp))
+#define DC_STAT IPU_DC_REG(0x01C8)
+#define DC_UGDE_0(evt) IPU_DC_REG(0x0174 + 16 * (evt))
+#define DC_UGDE_1(evt) IPU_DC_REG(0x0178 + 16 * (evt))
+#define DC_UGDE_2(evt) IPU_DC_REG(0x017C + 16 * (evt))
+#define DC_UGDE_3(evt) IPU_DC_REG(0x0180 + 16 * (evt))
+
+/* IPU DP Registers */
+#define IPU_DP_REG(offset) (offset)
+
+#define DP_SYNC 0
+#define DP_ASYNC0 0x60
+#define DP_ASYNC1 0xBC
+#define DP_COM_CONF(flow) IPU_DP_REG(flow)
+#define DP_GRAPH_WIND_CTRL(flow) IPU_DP_REG(0x0004 + (flow))
+#define DP_FG_POS(flow) IPU_DP_REG(0x0008 + (flow))
+#define DP_GAMMA_C(flow, i) IPU_DP_REG(0x0014 + (flow) + 4 * (i))
+#define DP_GAMMA_S(flow, i) IPU_DP_REG(0x0034 + (flow) + 4 * (i))
+#define DP_CSC_A_0(flow) IPU_DP_REG(0x0044 + (flow))
+#define DP_CSC_A_1(flow) IPU_DP_REG(0x0048 + (flow))
+#define DP_CSC_A_2(flow) IPU_DP_REG(0x004C + (flow))
+#define DP_CSC_A_3(flow) IPU_DP_REG(0x0050 + (flow))
+#define DP_CSC_0(flow) IPU_DP_REG(0x0054 + (flow))
+#define DP_CSC_1(flow) IPU_DP_REG(0x0058 + (flow))
+
+enum {
+ IPU_CONF_CSI0_EN = 0x00000001,
+ IPU_CONF_CSI1_EN = 0x00000002,
+ IPU_CONF_IC_EN = 0x00000004,
+ IPU_CONF_ROT_EN = 0x00000008,
+ IPU_CONF_ISP_EN = 0x00000010,
+ IPU_CONF_DP_EN = 0x00000020,
+ IPU_CONF_DI0_EN = 0x00000040,
+ IPU_CONF_DI1_EN = 0x00000080,
+ IPU_CONF_DMFC_EN = 0x00000400,
+ IPU_CONF_SMFC_EN = 0x00000100,
+ IPU_CONF_DC_EN = 0x00000200,
+ IPU_CONF_VDI_EN = 0x00001000,
+ IPU_CONF_IDMAC_DIS = 0x00400000,
+ IPU_CONF_IC_DMFC_SEL = 0x02000000,
+ IPU_CONF_IC_DMFC_SYNC = 0x04000000,
+ IPU_CONF_VDI_DMFC_SYNC = 0x08000000,
+ IPU_CONF_CSI0_DATA_SOURCE = 0x10000000,
+ IPU_CONF_CSI0_DATA_SOURCE_OFFSET = 28,
+ IPU_CONF_CSI1_DATA_SOURCE = 0x20000000,
+ IPU_CONF_IC_INPUT = 0x40000000,
+ IPU_CONF_CSI_SEL = 0x80000000,
+
+ DI0_COUNTER_RELEASE = 0x01000000,
+ DI1_COUNTER_RELEASE = 0x02000000,
+
+ FS_PRPVF_ROT_SRC_SEL_MASK = 0x00000F00,
+ FS_PRPVF_ROT_SRC_SEL_OFFSET = 8,
+ FS_PRPENC_ROT_SRC_SEL_MASK = 0x0000000F,
+ FS_PRPENC_ROT_SRC_SEL_OFFSET = 0,
+ FS_PP_ROT_SRC_SEL_MASK = 0x000F0000,
+ FS_PP_ROT_SRC_SEL_OFFSET = 16,
+ FS_PP_SRC_SEL_MASK = 0x0000F000,
+ FS_PP_SRC_SEL_VDOA = 0x00008000,
+ FS_PP_SRC_SEL_OFFSET = 12,
+ FS_PRP_SRC_SEL_MASK = 0x0F000000,
+ FS_PRP_SRC_SEL_OFFSET = 24,
+ FS_VF_IN_VALID = 0x80000000,
+ FS_ENC_IN_VALID = 0x40000000,
+ FS_VDI_SRC_SEL_MASK = 0x30000000,
+ FS_VDI_SRC_SEL_VDOA = 0x20000000,
+ FS_VDOA_DEST_SEL_MASK = 0x00030000,
+ FS_VDOA_DEST_SEL_VDI = 0x00020000,
+ FS_VDOA_DEST_SEL_IC = 0x00010000,
+ FS_VDI_SRC_SEL_OFFSET = 28,
+
+
+ FS_PRPENC_DEST_SEL_MASK = 0x0000000F,
+ FS_PRPENC_DEST_SEL_OFFSET = 0,
+ FS_PRPVF_DEST_SEL_MASK = 0x000000F0,
+ FS_PRPVF_DEST_SEL_OFFSET = 4,
+ FS_PRPVF_ROT_DEST_SEL_MASK = 0x00000F00,
+ FS_PRPVF_ROT_DEST_SEL_OFFSET = 8,
+ FS_PP_DEST_SEL_MASK = 0x0000F000,
+ FS_PP_DEST_SEL_OFFSET = 12,
+ FS_PP_ROT_DEST_SEL_MASK = 0x000F0000,
+ FS_PP_ROT_DEST_SEL_OFFSET = 16,
+ FS_PRPENC_ROT_DEST_SEL_MASK = 0x00F00000,
+ FS_PRPENC_ROT_DEST_SEL_OFFSET = 20,
+
+ FS_SMFC0_DEST_SEL_MASK = 0x0000000F,
+ FS_SMFC0_DEST_SEL_OFFSET = 0,
+ FS_SMFC1_DEST_SEL_MASK = 0x00000070,
+ FS_SMFC1_DEST_SEL_OFFSET = 4,
+ FS_SMFC2_DEST_SEL_MASK = 0x00000780,
+ FS_SMFC2_DEST_SEL_OFFSET = 7,
+ FS_SMFC3_DEST_SEL_MASK = 0x00003800,
+ FS_SMFC3_DEST_SEL_OFFSET = 11,
+
+ FS_DC1_SRC_SEL_MASK = 0x00F00000,
+ FS_DC1_SRC_SEL_OFFSET = 20,
+ FS_DC2_SRC_SEL_MASK = 0x000F0000,
+ FS_DC2_SRC_SEL_OFFSET = 16,
+ FS_DP_SYNC0_SRC_SEL_MASK = 0x0000000F,
+ FS_DP_SYNC0_SRC_SEL_OFFSET = 0,
+ FS_DP_SYNC1_SRC_SEL_MASK = 0x000000F0,
+ FS_DP_SYNC1_SRC_SEL_OFFSET = 4,
+ FS_DP_ASYNC0_SRC_SEL_MASK = 0x00000F00,
+ FS_DP_ASYNC0_SRC_SEL_OFFSET = 8,
+ FS_DP_ASYNC1_SRC_SEL_MASK = 0x0000F000,
+ FS_DP_ASYNC1_SRC_SEL_OFFSET = 12,
+
+ FS_AUTO_REF_PER_MASK = 0,
+ FS_AUTO_REF_PER_OFFSET = 16,
+
+ TSTAT_VF_MASK = 0x0000000C,
+ TSTAT_VF_OFFSET = 2,
+ TSTAT_VF_ROT_MASK = 0x00000300,
+ TSTAT_VF_ROT_OFFSET = 8,
+ TSTAT_ENC_MASK = 0x00000003,
+ TSTAT_ENC_OFFSET = 0,
+ TSTAT_ENC_ROT_MASK = 0x000000C0,
+ TSTAT_ENC_ROT_OFFSET = 6,
+ TSTAT_PP_MASK = 0x00000030,
+ TSTAT_PP_OFFSET = 4,
+ TSTAT_PP_ROT_MASK = 0x00000C00,
+ TSTAT_PP_ROT_OFFSET = 10,
+
+ TASK_STAT_IDLE = 0,
+ TASK_STAT_ACTIVE = 1,
+ TASK_STAT_WAIT4READY = 2,
+
+ /* IDMAC register bits */
+ IDMAC_CONF_USED_BUFS_EN_R = 0x02000000,
+ IDMAC_CONF_USED_BUFS_MAX_R_MASK = 0x01E00000,
+ IDMAC_CONF_USED_BUFS_MAX_R_OFFSET = 21,
+ IDMAC_CONF_USED_BUFS_EN_W = 0x00100000,
+ IDMAC_CONF_USED_BUFS_MAX_W_MASK = 0x000E0000,
+ IDMAC_CONF_USED_BUFS_MAX_W_OFFSET = 17,
+
+ /* Image Converter Register bits */
+ IC_CONF_PRPENC_EN = 0x00000001,
+ IC_CONF_PRPENC_CSC1 = 0x00000002,
+ IC_CONF_PRPENC_ROT_EN = 0x00000004,
+ IC_CONF_PRPVF_EN = 0x00000100,
+ IC_CONF_PRPVF_CSC1 = 0x00000200,
+ IC_CONF_PRPVF_CSC2 = 0x00000400,
+ IC_CONF_PRPVF_CMB = 0x00000800,
+ IC_CONF_PRPVF_ROT_EN = 0x00001000,
+ IC_CONF_PP_EN = 0x00010000,
+ IC_CONF_PP_CSC1 = 0x00020000,
+ IC_CONF_PP_CSC2 = 0x00040000,
+ IC_CONF_PP_CMB = 0x00080000,
+ IC_CONF_PP_ROT_EN = 0x00100000,
+ IC_CONF_IC_GLB_LOC_A = 0x10000000,
+ IC_CONF_KEY_COLOR_EN = 0x20000000,
+ IC_CONF_RWS_EN = 0x40000000,
+ IC_CONF_CSI_MEM_WR_EN = 0x80000000,
+
+ IC_RSZ_MAX_RESIZE_RATIO = 0x00004000,
+
+ IC_IDMAC_1_CB0_BURST_16 = 0x00000001,
+ IC_IDMAC_1_CB1_BURST_16 = 0x00000002,
+ IC_IDMAC_1_CB2_BURST_16 = 0x00000004,
+ IC_IDMAC_1_CB3_BURST_16 = 0x00000008,
+ IC_IDMAC_1_CB4_BURST_16 = 0x00000010,
+ IC_IDMAC_1_CB5_BURST_16 = 0x00000020,
+ IC_IDMAC_1_CB6_BURST_16 = 0x00000040,
+ IC_IDMAC_1_CB7_BURST_16 = 0x00000080,
+ IC_IDMAC_1_PRPENC_ROT_MASK = 0x00003800,
+ IC_IDMAC_1_PRPENC_ROT_OFFSET = 11,
+ IC_IDMAC_1_PRPVF_ROT_MASK = 0x0001C000,
+ IC_IDMAC_1_PRPVF_ROT_OFFSET = 14,
+ IC_IDMAC_1_PP_ROT_MASK = 0x000E0000,
+ IC_IDMAC_1_PP_ROT_OFFSET = 17,
+ IC_IDMAC_1_PP_FLIP_RS = 0x00400000,
+ IC_IDMAC_1_PRPVF_FLIP_RS = 0x00200000,
+ IC_IDMAC_1_PRPENC_FLIP_RS = 0x00100000,
+
+ IC_IDMAC_2_PRPENC_HEIGHT_MASK = 0x000003FF,
+ IC_IDMAC_2_PRPENC_HEIGHT_OFFSET = 0,
+ IC_IDMAC_2_PRPVF_HEIGHT_MASK = 0x000FFC00,
+ IC_IDMAC_2_PRPVF_HEIGHT_OFFSET = 10,
+ IC_IDMAC_2_PP_HEIGHT_MASK = 0x3FF00000,
+ IC_IDMAC_2_PP_HEIGHT_OFFSET = 20,
+
+ IC_IDMAC_3_PRPENC_WIDTH_MASK = 0x000003FF,
+ IC_IDMAC_3_PRPENC_WIDTH_OFFSET = 0,
+ IC_IDMAC_3_PRPVF_WIDTH_MASK = 0x000FFC00,
+ IC_IDMAC_3_PRPVF_WIDTH_OFFSET = 10,
+ IC_IDMAC_3_PP_WIDTH_MASK = 0x3FF00000,
+ IC_IDMAC_3_PP_WIDTH_OFFSET = 20,
+
+ CSI_SENS_CONF_DATA_FMT_SHIFT = 8,
+ CSI_SENS_CONF_DATA_FMT_MASK = 0x00000700,
+ CSI_SENS_CONF_DATA_FMT_RGB_YUV444 = 0L,
+ CSI_SENS_CONF_DATA_FMT_YUV422_YUYV = 1L,
+ CSI_SENS_CONF_DATA_FMT_YUV422_UYVY = 2L,
+ CSI_SENS_CONF_DATA_FMT_BAYER = 3L,
+ CSI_SENS_CONF_DATA_FMT_RGB565 = 4L,
+ CSI_SENS_CONF_DATA_FMT_RGB555 = 5L,
+ CSI_SENS_CONF_DATA_FMT_RGB444 = 6L,
+ CSI_SENS_CONF_DATA_FMT_JPEG = 7L,
+
+ CSI_SENS_CONF_VSYNC_POL_SHIFT = 0,
+ CSI_SENS_CONF_HSYNC_POL_SHIFT = 1,
+ CSI_SENS_CONF_DATA_POL_SHIFT = 2,
+ CSI_SENS_CONF_PIX_CLK_POL_SHIFT = 3,
+ CSI_SENS_CONF_SENS_PRTCL_MASK = 0x00000070L,
+ CSI_SENS_CONF_SENS_PRTCL_SHIFT = 4,
+ CSI_SENS_CONF_PACK_TIGHT_SHIFT = 7,
+ CSI_SENS_CONF_DATA_WIDTH_SHIFT = 11,
+ CSI_SENS_CONF_EXT_VSYNC_SHIFT = 15,
+ CSI_SENS_CONF_DIVRATIO_SHIFT = 16,
+
+ CSI_SENS_CONF_DIVRATIO_MASK = 0x00FF0000L,
+ CSI_SENS_CONF_DATA_DEST_SHIFT = 24,
+ CSI_SENS_CONF_DATA_DEST_MASK = 0x07000000L,
+ CSI_SENS_CONF_JPEG8_EN_SHIFT = 27,
+ CSI_SENS_CONF_JPEG_EN_SHIFT = 28,
+ CSI_SENS_CONF_FORCE_EOF_SHIFT = 29,
+ CSI_SENS_CONF_DATA_EN_POL_SHIFT = 31,
+
+ CSI_DATA_DEST_ISP = 1L,
+ CSI_DATA_DEST_IC = 2L,
+ CSI_DATA_DEST_IDMAC = 4L,
+
+ CSI_CCIR_ERR_DET_EN = 0x01000000L,
+ CSI_HORI_DOWNSIZE_EN = 0x80000000L,
+ CSI_VERT_DOWNSIZE_EN = 0x40000000L,
+ CSI_TEST_GEN_MODE_EN = 0x01000000L,
+
+ CSI_HSC_MASK = 0x1FFF0000,
+ CSI_HSC_SHIFT = 16,
+ CSI_VSC_MASK = 0x00000FFF,
+ CSI_VSC_SHIFT = 0,
+
+ CSI_TEST_GEN_R_MASK = 0x000000FFL,
+ CSI_TEST_GEN_R_SHIFT = 0,
+ CSI_TEST_GEN_G_MASK = 0x0000FF00L,
+ CSI_TEST_GEN_G_SHIFT = 8,
+ CSI_TEST_GEN_B_MASK = 0x00FF0000L,
+ CSI_TEST_GEN_B_SHIFT = 16,
+
+ CSI_MIPI_DI0_MASK = 0x000000FFL,
+ CSI_MIPI_DI0_SHIFT = 0,
+ CSI_MIPI_DI1_MASK = 0x0000FF00L,
+ CSI_MIPI_DI1_SHIFT = 8,
+ CSI_MIPI_DI2_MASK = 0x00FF0000L,
+ CSI_MIPI_DI2_SHIFT = 16,
+ CSI_MIPI_DI3_MASK = 0xFF000000L,
+ CSI_MIPI_DI3_SHIFT = 24,
+
+ CSI_MAX_RATIO_SKIP_ISP_MASK = 0x00070000L,
+ CSI_MAX_RATIO_SKIP_ISP_SHIFT = 16,
+ CSI_SKIP_ISP_MASK = 0x00F80000L,
+ CSI_SKIP_ISP_SHIFT = 19,
+ CSI_MAX_RATIO_SKIP_SMFC_MASK = 0x00000007L,
+ CSI_MAX_RATIO_SKIP_SMFC_SHIFT = 0,
+ CSI_SKIP_SMFC_MASK = 0x000000F8L,
+ CSI_SKIP_SMFC_SHIFT = 3,
+ CSI_ID_2_SKIP_MASK = 0x00000300L,
+ CSI_ID_2_SKIP_SHIFT = 8,
+
+ CSI_COLOR_FIRST_ROW_MASK = 0x00000002L,
+ CSI_COLOR_FIRST_COMP_MASK = 0x00000001L,
+
+ SMFC_MAP_CH0_MASK = 0x00000007L,
+ SMFC_MAP_CH0_SHIFT = 0,
+ SMFC_MAP_CH1_MASK = 0x00000038L,
+ SMFC_MAP_CH1_SHIFT = 3,
+ SMFC_MAP_CH2_MASK = 0x000001C0L,
+ SMFC_MAP_CH2_SHIFT = 6,
+ SMFC_MAP_CH3_MASK = 0x00000E00L,
+ SMFC_MAP_CH3_SHIFT = 9,
+
+ SMFC_WM0_SET_MASK = 0x00000007L,
+ SMFC_WM0_SET_SHIFT = 0,
+ SMFC_WM1_SET_MASK = 0x000001C0L,
+ SMFC_WM1_SET_SHIFT = 6,
+ SMFC_WM2_SET_MASK = 0x00070000L,
+ SMFC_WM2_SET_SHIFT = 16,
+ SMFC_WM3_SET_MASK = 0x01C00000L,
+ SMFC_WM3_SET_SHIFT = 22,
+
+ SMFC_WM0_CLR_MASK = 0x00000038L,
+ SMFC_WM0_CLR_SHIFT = 3,
+ SMFC_WM1_CLR_MASK = 0x00000E00L,
+ SMFC_WM1_CLR_SHIFT = 9,
+ SMFC_WM2_CLR_MASK = 0x00380000L,
+ SMFC_WM2_CLR_SHIFT = 19,
+ SMFC_WM3_CLR_MASK = 0x0E000000L,
+ SMFC_WM3_CLR_SHIFT = 25,
+
+ SMFC_BS0_MASK = 0x0000000FL,
+ SMFC_BS0_SHIFT = 0,
+ SMFC_BS1_MASK = 0x000000F0L,
+ SMFC_BS1_SHIFT = 4,
+ SMFC_BS2_MASK = 0x00000F00L,
+ SMFC_BS2_SHIFT = 8,
+ SMFC_BS3_MASK = 0x0000F000L,
+ SMFC_BS3_SHIFT = 12,
+
+ PF_CONF_TYPE_MASK = 0x00000007,
+ PF_CONF_TYPE_SHIFT = 0,
+ PF_CONF_PAUSE_EN = 0x00000010,
+ PF_CONF_RESET = 0x00008000,
+ PF_CONF_PAUSE_ROW_MASK = 0x00FF0000,
+ PF_CONF_PAUSE_ROW_SHIFT = 16,
+
+ DI_DW_GEN_ACCESS_SIZE_OFFSET = 24,
+ DI_DW_GEN_COMPONENT_SIZE_OFFSET = 16,
+
+ DI_GEN_DI_CLK_EXT = 0x100000,
+ DI_GEN_POLARITY_DISP_CLK = 0x00020000,
+ DI_GEN_POLARITY_1 = 0x00000001,
+ DI_GEN_POLARITY_2 = 0x00000002,
+ DI_GEN_POLARITY_3 = 0x00000004,
+ DI_GEN_POLARITY_4 = 0x00000008,
+ DI_GEN_POLARITY_5 = 0x00000010,
+ DI_GEN_POLARITY_6 = 0x00000020,
+ DI_GEN_POLARITY_7 = 0x00000040,
+ DI_GEN_POLARITY_8 = 0x00000080,
+
+ DI_POL_DRDY_DATA_POLARITY = 0x00000080,
+ DI_POL_DRDY_POLARITY_15 = 0x00000010,
+
+ DI_VSYNC_SEL_OFFSET = 13,
+
+ DC_WR_CH_CONF_FIELD_MODE = 0x00000200,
+ DC_WR_CH_CONF_PROG_TYPE_OFFSET = 5,
+ DC_WR_CH_CONF_PROG_TYPE_MASK = 0x000000E0,
+ DC_WR_CH_CONF_PROG_DI_ID = 0x00000004,
+ DC_WR_CH_CONF_PROG_DISP_ID_OFFSET = 3,
+ DC_WR_CH_CONF_PROG_DISP_ID_MASK = 0x00000018,
+
+ DC_UGDE_0_ODD_EN = 0x02000000,
+ DC_UGDE_0_ID_CODED_MASK = 0x00000007,
+ DC_UGDE_0_ID_CODED_OFFSET = 0,
+ DC_UGDE_0_EV_PRIORITY_MASK = 0x00000078,
+ DC_UGDE_0_EV_PRIORITY_OFFSET = 3,
+
+ DP_COM_CONF_FG_EN = 0x00000001,
+ DP_COM_CONF_GWSEL = 0x00000002,
+ DP_COM_CONF_GWAM = 0x00000004,
+ DP_COM_CONF_GWCKE = 0x00000008,
+ DP_COM_CONF_CSC_DEF_MASK = 0x00000300,
+ DP_COM_CONF_CSC_DEF_OFFSET = 8,
+ DP_COM_CONF_CSC_DEF_FG = 0x00000300,
+ DP_COM_CONF_CSC_DEF_BG = 0x00000200,
+ DP_COM_CONF_CSC_DEF_BOTH = 0x00000100,
+ DP_COM_CONF_GAMMA_EN = 0x00001000,
+ DP_COM_CONF_GAMMA_YUV_EN = 0x00002000,
+
+ DI_SER_CONF_LLA_SER_ACCESS = 0x00000020,
+ DI_SER_CONF_SERIAL_CLK_POL = 0x00000010,
+ DI_SER_CONF_SERIAL_DATA_POL = 0x00000008,
+ DI_SER_CONF_SERIAL_RS_POL = 0x00000004,
+ DI_SER_CONF_SERIAL_CS_POL = 0x00000002,
+ DI_SER_CONF_WAIT4SERIAL = 0x00000001,
+
+ VDI_C_CH_420 = 0x00000000,
+ VDI_C_CH_422 = 0x00000002,
+ VDI_C_MOT_SEL_FULL = 0x00000008,
+ VDI_C_MOT_SEL_LOW = 0x00000004,
+ VDI_C_MOT_SEL_MED = 0x00000000,
+ VDI_C_BURST_SIZE1_4 = 0x00000030,
+ VDI_C_BURST_SIZE2_4 = 0x00000300,
+ VDI_C_BURST_SIZE3_4 = 0x00003000,
+ VDI_C_BURST_SIZE_MASK = 0xF,
+ VDI_C_BURST_SIZE1_OFFSET = 4,
+ VDI_C_BURST_SIZE2_OFFSET = 8,
+ VDI_C_BURST_SIZE3_OFFSET = 12,
+ VDI_C_VWM1_SET_1 = 0x00000000,
+ VDI_C_VWM1_SET_2 = 0x00010000,
+ VDI_C_VWM1_CLR_2 = 0x00080000,
+ VDI_C_VWM3_SET_1 = 0x00000000,
+ VDI_C_VWM3_SET_2 = 0x00400000,
+ VDI_C_VWM3_CLR_2 = 0x02000000,
+ VDI_C_TOP_FIELD_MAN_1 = 0x40000000,
+ VDI_C_TOP_FIELD_AUTO_1 = 0x80000000,
+};
+
+enum di_pins {
+ DI_PIN11 = 0,
+ DI_PIN12 = 1,
+ DI_PIN13 = 2,
+ DI_PIN14 = 3,
+ DI_PIN15 = 4,
+ DI_PIN16 = 5,
+ DI_PIN17 = 6,
+ DI_PIN_CS = 7,
+
+ DI_PIN_SER_CLK = 0,
+ DI_PIN_SER_RS = 1,
+};
+
+enum di_sync_wave {
+ DI_SYNC_NONE = -1,
+ DI_SYNC_CLK = 0,
+ DI_SYNC_INT_HSYNC = 1,
+ DI_SYNC_HSYNC = 2,
+ DI_SYNC_VSYNC = 3,
+ DI_SYNC_DE = 5,
+};
+
+/* DC template opcodes */
+#define WROD(lf) (0x18 | ((lf) << 1))
+#define WRG (0x01)
+
+#endif
diff --git a/drivers/mxc/ipu3/pre-regs.h b/drivers/mxc/ipu3/pre-regs.h
new file mode 100644
index 000000000000..06a9b029ce3e
--- /dev/null
+++ b/drivers/mxc/ipu3/pre-regs.h
@@ -0,0 +1,480 @@
+/*
+ * Freescale PRE Register Definitions
+ *
+ * Copyright 2014-2015 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#ifndef __ARCH_ARM___PRE_H
+#define __ARCH_ARM___PRE_H
+
+
+#define HW_PRE_CTRL (0x00000000)
+#define HW_PRE_CTRL_SET (0x00000004)
+#define HW_PRE_CTRL_CLR (0x00000008)
+#define HW_PRE_CTRL_TOG (0x0000000c)
+
+#define BM_PRE_CTRL_SFTRST 0x80000000
+#define BF_PRE_CTRL_SFTRST(v) \
+ (((v) << 31) & BM_PRE_CTRL_SFTRST)
+#define BM_PRE_CTRL_CLKGATE 0x40000000
+#define BF_PRE_CTRL_CLKGATE(v) \
+ (((v) << 30) & BM_PRE_CTRL_CLKGATE)
+#define BM_PRE_CTRL_TPR_RESET_SEL 0x20000000
+#define BF_PRE_CTRL_TPR_RESET_SEL(v) \
+ (((v) << 29) & BM_PRE_CTRL_TPR_RESET_SEL)
+#define BM_PRE_CTRL_EN_REPEAT 0x10000000
+#define BF_PRE_CTRL_EN_REPEAT(v) \
+ (((v) << 28) & BM_PRE_CTRL_EN_REPEAT)
+#define BP_PRE_CTRL_RSVD2 16
+#define BM_PRE_CTRL_RSVD2 0x0FFF0000
+#define BF_PRE_CTRL_RSVD2(v) \
+ (((v) << 16) & BM_PRE_CTRL_RSVD2)
+#define BP_PRE_CTRL_RSVD1 12
+#define BM_PRE_CTRL_RSVD1 0x0000F000
+#define BF_PRE_CTRL_RSVD1(v) \
+ (((v) << 12) & BM_PRE_CTRL_RSVD1)
+#define BM_PRE_CTRL_HANDSHAKE_ABORT_SKIP_EN 0x00000800
+#define BF_PRE_CTRL_HANDSHAKE_ABORT_SKIP_EN(v) \
+ (((v) << 11) & BM_PRE_CTRL_HANDSHAKE_ABORT_SKIP_EN)
+#define BV_PRE_CTRL_HANDSHAKE_ABORT_SKIP_EN__0 0x0
+#define BV_PRE_CTRL_HANDSHAKE_ABORT_SKIP_EN__1 0x1
+#define BP_PRE_CTRL_HANDSHAKE_LINE_NUM 9
+#define BM_PRE_CTRL_HANDSHAKE_LINE_NUM 0x00000600
+#define BF_PRE_CTRL_HANDSHAKE_LINE_NUM(v) \
+ (((v) << 9) & BM_PRE_CTRL_HANDSHAKE_LINE_NUM)
+#define BV_PRE_CTRL_HANDSHAKE_LINE_NUM__0 0x0
+#define BV_PRE_CTRL_HANDSHAKE_LINE_NUM__1 0x1
+#define BV_PRE_CTRL_HANDSHAKE_LINE_NUM__2 0x2
+#define BM_PRE_CTRL_HANDSHAKE_EN 0x00000100
+#define BF_PRE_CTRL_HANDSHAKE_EN(v) \
+ (((v) << 8) & BM_PRE_CTRL_HANDSHAKE_EN)
+#define BV_PRE_CTRL_HANDSHAKE_EN__0 0x0
+#define BV_PRE_CTRL_HANDSHAKE_EN__1 0x1
+#define BM_PRE_CTRL_INTERLACED_FIELD 0x00000080
+#define BF_PRE_CTRL_INTERLACED_FIELD(v) \
+ (((v) << 7) & BM_PRE_CTRL_INTERLACED_FIELD)
+#define BM_PRE_CTRL_SO 0x00000040
+#define BF_PRE_CTRL_SO(v) \
+ (((v) << 6) & BM_PRE_CTRL_SO)
+#define BM_PRE_CTRL_VFLIP 0x00000020
+#define BF_PRE_CTRL_VFLIP(v) \
+ (((v) << 5) & BM_PRE_CTRL_VFLIP)
+#define BM_PRE_CTRL_SDW_UPDATE 0x00000010
+#define BF_PRE_CTRL_SDW_UPDATE(v) \
+ (((v) << 4) & BM_PRE_CTRL_SDW_UPDATE)
+#define BM_PRE_CTRL_RSVD0 0x00000008
+#define BF_PRE_CTRL_RSVD0(v) \
+ (((v) << 3) & BM_PRE_CTRL_RSVD0)
+#define BM_PRE_CTRL_BLOCK_16 0x00000004
+#define BF_PRE_CTRL_BLOCK_16(v) \
+ (((v) << 2) & BM_PRE_CTRL_BLOCK_16)
+#define BV_PRE_CTRL_BLOCK_16__32x4 0x0
+#define BV_PRE_CTRL_BLOCK_16__16x4 0x1
+#define BM_PRE_CTRL_BLOCK_EN 0x00000002
+#define BF_PRE_CTRL_BLOCK_EN(v) \
+ (((v) << 1) & BM_PRE_CTRL_BLOCK_EN)
+#define BV_PRE_CTRL_BLOCK_EN__0 0x0
+#define BV_PRE_CTRL_BLOCK_EN__1 0x1
+#define BM_PRE_CTRL_ENABLE 0x00000001
+#define BF_PRE_CTRL_ENABLE(v) \
+ (((v) << 0) & BM_PRE_CTRL_ENABLE)
+
+#define HW_PRE_IRQ_MASK (0x00000010)
+#define HW_PRE_IRQ_MASK_SET (0x00000014)
+#define HW_PRE_IRQ_MASK_CLR (0x00000018)
+#define HW_PRE_IRQ_MASK_TOG (0x0000001c)
+
+#define BP_PRE_IRQ_MASK_RSVD1 4
+#define BM_PRE_IRQ_MASK_RSVD1 0xFFFFFFF0
+#define BF_PRE_IRQ_MASK_RSVD1(v) \
+ (((v) << 4) & BM_PRE_IRQ_MASK_RSVD1)
+#define BM_PRE_IRQ_MASK_TPR_RD_NUM_BYTES_OVFL_IRQ_EN 0x00000008
+#define BF_PRE_IRQ_MASK_TPR_RD_NUM_BYTES_OVFL_IRQ_EN(v) \
+ (((v) << 3) & BM_PRE_IRQ_MASK_TPR_RD_NUM_BYTES_OVFL_IRQ_EN)
+#define BM_PRE_IRQ_MASK_HANDSHAKE_ABORT_IRQ_EN 0x00000004
+#define BF_PRE_IRQ_MASK_HANDSHAKE_ABORT_IRQ_EN(v) \
+ (((v) << 2) & BM_PRE_IRQ_MASK_HANDSHAKE_ABORT_IRQ_EN)
+#define BM_PRE_IRQ_MASK_STORE_IRQ_EN 0x00000002
+#define BF_PRE_IRQ_MASK_STORE_IRQ_EN(v) \
+ (((v) << 1) & BM_PRE_IRQ_MASK_STORE_IRQ_EN)
+#define BM_PRE_IRQ_MASK_PREFETCH_IRQ_EN 0x00000001
+#define BF_PRE_IRQ_MASK_PREFETCH_IRQ_EN(v) \
+ (((v) << 0) & BM_PRE_IRQ_MASK_PREFETCH_IRQ_EN)
+
+#define HW_PRE_IRQ (0x00000020)
+#define HW_PRE_IRQ_SET (0x00000024)
+#define HW_PRE_IRQ_CLR (0x00000028)
+#define HW_PRE_IRQ_TOG (0x0000002c)
+
+#define BP_PRE_IRQ_RSVD1 14
+#define BM_PRE_IRQ_RSVD1 0xFFFFC000
+#define BF_PRE_IRQ_RSVD1(v) \
+ (((v) << 14) & BM_PRE_IRQ_RSVD1)
+#define BP_PRE_IRQ_AXI_ERROR_ID 10
+#define BM_PRE_IRQ_AXI_ERROR_ID 0x00003C00
+#define BF_PRE_IRQ_AXI_ERROR_ID(v) \
+ (((v) << 10) & BM_PRE_IRQ_AXI_ERROR_ID)
+#define BM_PRE_IRQ_AXI_READ_ERROR 0x00000200
+#define BF_PRE_IRQ_AXI_READ_ERROR(v) \
+ (((v) << 9) & BM_PRE_IRQ_AXI_READ_ERROR)
+#define BM_PRE_IRQ_AXI_WRITE_ERROR 0x00000100
+#define BF_PRE_IRQ_AXI_WRITE_ERROR(v) \
+ (((v) << 8) & BM_PRE_IRQ_AXI_WRITE_ERROR)
+#define BP_PRE_IRQ_RSVD0 5
+#define BM_PRE_IRQ_RSVD0 0x000000E0
+#define BF_PRE_IRQ_RSVD0(v) \
+ (((v) << 5) & BM_PRE_IRQ_RSVD0)
+#define BM_PRE_IRQ_HANDSHAKE_ERROR_IRQ 0x00000010
+#define BF_PRE_IRQ_HANDSHAKE_ERROR_IRQ(v) \
+ (((v) << 4) & BM_PRE_IRQ_HANDSHAKE_ERROR_IRQ)
+#define BM_PRE_IRQ_TPR_RD_NUM_BYTES_OVFL_IRQ 0x00000008
+#define BF_PRE_IRQ_TPR_RD_NUM_BYTES_OVFL_IRQ(v) \
+ (((v) << 3) & BM_PRE_IRQ_TPR_RD_NUM_BYTES_OVFL_IRQ)
+#define BM_PRE_IRQ_HANDSHAKE_ABORT_IRQ 0x00000004
+#define BF_PRE_IRQ_HANDSHAKE_ABORT_IRQ(v) \
+ (((v) << 2) & BM_PRE_IRQ_HANDSHAKE_ABORT_IRQ)
+#define BM_PRE_IRQ_STORE_IRQ 0x00000002
+#define BF_PRE_IRQ_STORE_IRQ(v) \
+ (((v) << 1) & BM_PRE_IRQ_STORE_IRQ)
+#define BM_PRE_IRQ_PREFETCH_IRQ 0x00000001
+#define BF_PRE_IRQ_PREFETCH_IRQ(v) \
+ (((v) << 0) & BM_PRE_IRQ_PREFETCH_IRQ)
+
+#define HW_PRE_CUR_BUF (0x00000030)
+
+#define BP_PRE_CUR_BUF_ADDR 0
+#define BM_PRE_CUR_BUF_ADDR 0xFFFFFFFF
+#define BF_PRE_CUR_BUF_ADDR(v) (v)
+
+#define HW_PRE_NEXT_BUF (0x00000040)
+
+#define BP_PRE_NEXT_BUF_ADDR 0
+#define BM_PRE_NEXT_BUF_ADDR 0xFFFFFFFF
+#define BF_PRE_NEXT_BUF_ADDR(v) (v)
+
+#define HW_PRE_U_BUF_OFFSET (0x00000050)
+
+#define BP_PRE_U_BUF_OFFSET_RSVD0 25
+#define BM_PRE_U_BUF_OFFSET_RSVD0 0xFE000000
+#define BF_PRE_U_BUF_OFFSET_RSVD0(v) \
+ (((v) << 25) & BM_PRE_U_BUF_OFFSET_RSVD0)
+#define BP_PRE_U_BUF_OFFSET_UBO 0
+#define BM_PRE_U_BUF_OFFSET_UBO 0x01FFFFFF
+#define BF_PRE_U_BUF_OFFSET_UBO(v) \
+ (((v) << 0) & BM_PRE_U_BUF_OFFSET_UBO)
+
+#define HW_PRE_V_BUF_OFFSET (0x00000060)
+
+#define BP_PRE_V_BUF_OFFSET_RSVD0 25
+#define BM_PRE_V_BUF_OFFSET_RSVD0 0xFE000000
+#define BF_PRE_V_BUF_OFFSET_RSVD0(v) \
+ (((v) << 25) & BM_PRE_V_BUF_OFFSET_RSVD0)
+#define BP_PRE_V_BUF_OFFSET_VBO 0
+#define BM_PRE_V_BUF_OFFSET_VBO 0x01FFFFFF
+#define BF_PRE_V_BUF_OFFSET_VBO(v) \
+ (((v) << 0) & BM_PRE_V_BUF_OFFSET_VBO)
+
+#define HW_PRE_TPR_CTRL (0x00000070)
+#define HW_PRE_TPR_CTRL_SET (0x00000074)
+#define HW_PRE_TPR_CTRL_CLR (0x00000078)
+#define HW_PRE_TPR_CTRL_TOG (0x0000007c)
+
+#define BP_PRE_TPR_CTRL_RSVD 8
+#define BM_PRE_TPR_CTRL_RSVD 0xFFFFFF00
+#define BF_PRE_TPR_CTRL_RSVD(v) \
+ (((v) << 8) & BM_PRE_TPR_CTRL_RSVD)
+#define BP_PRE_TPR_CTRL_TILE_FORMAT 0
+#define BM_PRE_TPR_CTRL_TILE_FORMAT 0x000000FF
+#define BF_PRE_TPR_CTRL_TILE_FORMAT(v) \
+ (((v) << 0) & BM_PRE_TPR_CTRL_TILE_FORMAT)
+#define BV_PRE_TPR_CTRL_TILE_FORMAT__BYPASS 0x00
+#define BV_PRE_TPR_CTRL_TILE_FORMAT__GPU32_SB_ST 0x10
+#define BV_PRE_TPR_CTRL_TILE_FORMAT__GPU32_SB_SRT 0x50
+#define BV_PRE_TPR_CTRL_TILE_FORMAT__GPU32_ST 0x20
+#define BV_PRE_TPR_CTRL_TILE_FORMAT__GPU32_SRT 0x60
+#define BV_PRE_TPR_CTRL_TILE_FORMAT__GPU32_MST 0xA0
+#define BV_PRE_TPR_CTRL_TILE_FORMAT__GPU32_MSRT 0xE0
+#define BV_PRE_TPR_CTRL_TILE_FORMAT__GPU16_SB_ST 0x11
+#define BV_PRE_TPR_CTRL_TILE_FORMAT__GPU16_SB_SRT 0x51
+#define BV_PRE_TPR_CTRL_TILE_FORMAT__GPU16_ST 0x21
+#define BV_PRE_TPR_CTRL_TILE_FORMAT__GPU16_SRT 0x61
+#define BV_PRE_TPR_CTRL_TILE_FORMAT__GPU16_MST 0xA1
+#define BV_PRE_TPR_CTRL_TILE_FORMAT__GPU16_MSRT 0xE1
+#define BV_PRE_TPR_CTRL_TILE_FORMAT__VPU8_PRO 0x22
+#define BV_PRE_TPR_CTRL_TILE_FORMAT__VPU8_SB_INT 0x13
+
+#define HW_PRE_PREFETCH_ENGINE_CTRL (0x00000080)
+#define HW_PRE_PREFETCH_ENGINE_CTRL_SET (0x00000084)
+#define HW_PRE_PREFETCH_ENGINE_CTRL_CLR (0x00000088)
+#define HW_PRE_PREFETCH_ENGINE_CTRL_TOG (0x0000008c)
+
+#define BP_PRE_PREFETCH_ENGINE_CTRL_RSVD1 16
+#define BM_PRE_PREFETCH_ENGINE_CTRL_RSVD1 0xFFFF0000
+#define BF_PRE_PREFETCH_ENGINE_CTRL_RSVD1(v) \
+ (((v) << 16) & BM_PRE_PREFETCH_ENGINE_CTRL_RSVD1)
+#define BM_PRE_PREFETCH_ENGINE_CTRL_TPR_COOR_OFFSET_EN 0x00008000
+#define BF_PRE_PREFETCH_ENGINE_CTRL_TPR_COOR_OFFSET_EN(v) \
+ (((v) << 15) & BM_PRE_PREFETCH_ENGINE_CTRL_TPR_COOR_OFFSET_EN)
+#define BM_PRE_PREFETCH_ENGINE_CTRL_PARTIAL_UV_SWAP 0x00004000
+#define BF_PRE_PREFETCH_ENGINE_CTRL_PARTIAL_UV_SWAP(v) \
+ (((v) << 14) & BM_PRE_PREFETCH_ENGINE_CTRL_PARTIAL_UV_SWAP)
+#define BM_PRE_PREFETCH_ENGINE_CTRL_CROP_EN 0x00002000
+#define BF_PRE_PREFETCH_ENGINE_CTRL_CROP_EN(v) \
+ (((v) << 13) & BM_PRE_PREFETCH_ENGINE_CTRL_CROP_EN)
+#define BV_PRE_PREFETCH_ENGINE_CTRL_CROP_EN__0 0x0
+#define BV_PRE_PREFETCH_ENGINE_CTRL_CROP_EN__1 0x1
+#define BM_PRE_PREFETCH_ENGINE_CTRL_FIELD_INVERSE 0x00001000
+#define BF_PRE_PREFETCH_ENGINE_CTRL_FIELD_INVERSE(v) \
+ (((v) << 12) & BM_PRE_PREFETCH_ENGINE_CTRL_FIELD_INVERSE)
+#define BV_PRE_PREFETCH_ENGINE_CTRL_FIELD_INVERSE__0 0x0
+#define BV_PRE_PREFETCH_ENGINE_CTRL_FIELD_INVERSE__1 0x1
+#define BM_PRE_PREFETCH_ENGINE_CTRL_SHIFT_BYPASS 0x00000800
+#define BF_PRE_PREFETCH_ENGINE_CTRL_SHIFT_BYPASS(v) \
+ (((v) << 11) & BM_PRE_PREFETCH_ENGINE_CTRL_SHIFT_BYPASS)
+#define BV_PRE_PREFETCH_ENGINE_CTRL_SHIFT_BYPASS__0 0x0
+#define BV_PRE_PREFETCH_ENGINE_CTRL_SHIFT_BYPASS__1 0x1
+#define BP_PRE_PREFETCH_ENGINE_CTRL_INPUT_PIXEL_FORMAT 8
+#define BM_PRE_PREFETCH_ENGINE_CTRL_INPUT_PIXEL_FORMAT 0x00000700
+#define BF_PRE_PREFETCH_ENGINE_CTRL_INPUT_PIXEL_FORMAT(v) \
+ (((v) << 8) & BM_PRE_PREFETCH_ENGINE_CTRL_INPUT_PIXEL_FORMAT)
+#define BV_PRE_PREFETCH_ENGINE_CTRL_INPUT_PIXEL_FORMAT__0 0x0
+#define BV_PRE_PREFETCH_ENGINE_CTRL_INPUT_PIXEL_FORMAT__1 0x1
+#define BV_PRE_PREFETCH_ENGINE_CTRL_INPUT_PIXEL_FORMAT__2 0x2
+#define BV_PRE_PREFETCH_ENGINE_CTRL_INPUT_PIXEL_FORMAT__3 0x3
+#define BV_PRE_PREFETCH_ENGINE_CTRL_INPUT_PIXEL_FORMAT__4 0x4
+#define BV_PRE_PREFETCH_ENGINE_CTRL_INPUT_PIXEL_FORMAT__5 0x5
+#define BP_PRE_PREFETCH_ENGINE_CTRL_RSVD0 6
+#define BM_PRE_PREFETCH_ENGINE_CTRL_RSVD0 0x000000C0
+#define BF_PRE_PREFETCH_ENGINE_CTRL_RSVD0(v) \
+ (((v) << 6) & BM_PRE_PREFETCH_ENGINE_CTRL_RSVD0)
+#define BP_PRE_PREFETCH_ENGINE_CTRL_INPUT_ACTIVE_BPP 4
+#define BM_PRE_PREFETCH_ENGINE_CTRL_INPUT_ACTIVE_BPP 0x00000030
+#define BF_PRE_PREFETCH_ENGINE_CTRL_INPUT_ACTIVE_BPP(v) \
+ (((v) << 4) & BM_PRE_PREFETCH_ENGINE_CTRL_INPUT_ACTIVE_BPP)
+#define BV_PRE_PREFETCH_ENGINE_CTRL_INPUT_ACTIVE_BPP__0 0x0
+#define BV_PRE_PREFETCH_ENGINE_CTRL_INPUT_ACTIVE_BPP__1 0x1
+#define BV_PRE_PREFETCH_ENGINE_CTRL_INPUT_ACTIVE_BPP__2 0x2
+#define BV_PRE_PREFETCH_ENGINE_CTRL_INPUT_ACTIVE_BPP__3 0x3
+#define BP_PRE_PREFETCH_ENGINE_CTRL_RD_NUM_BYTES 1
+#define BM_PRE_PREFETCH_ENGINE_CTRL_RD_NUM_BYTES 0x0000000E
+#define BF_PRE_PREFETCH_ENGINE_CTRL_RD_NUM_BYTES(v) \
+ (((v) << 1) & BM_PRE_PREFETCH_ENGINE_CTRL_RD_NUM_BYTES)
+#define BV_PRE_PREFETCH_ENGINE_CTRL_RD_NUM_BYTES__8_bytes 0x0
+#define BV_PRE_PREFETCH_ENGINE_CTRL_RD_NUM_BYTES__16_bytes 0x1
+#define BV_PRE_PREFETCH_ENGINE_CTRL_RD_NUM_BYTES__32_bytes 0x2
+#define BV_PRE_PREFETCH_ENGINE_CTRL_RD_NUM_BYTES__64_bytes 0x3
+#define BV_PRE_PREFETCH_ENGINE_CTRL_RD_NUM_BYTES__128_bytes 0x4
+#define BM_PRE_PREFETCH_ENGINE_CTRL_PREFETCH_EN 0x00000001
+#define BF_PRE_PREFETCH_ENGINE_CTRL_PREFETCH_EN(v) \
+ (((v) << 0) & BM_PRE_PREFETCH_ENGINE_CTRL_PREFETCH_EN)
+#define BV_PRE_PREFETCH_ENGINE_CTRL_PREFETCH_EN__0 0x0
+#define BV_PRE_PREFETCH_ENGINE_CTRL_PREFETCH_EN__1 0x1
+
+#define HW_PRE_PREFETCH_ENGINE_STATUS (0x00000090)
+
+#define BP_PRE_PREFETCH_ENGINE_STATUS_PREFETCH_BLOCK_Y 16
+#define BM_PRE_PREFETCH_ENGINE_STATUS_PREFETCH_BLOCK_Y 0x3FFF0000
+#define BF_PRE_PREFETCH_ENGINE_STATUS_PREFETCH_BLOCK_Y(v) \
+ (((v) << 16) & BM_PRE_PREFETCH_ENGINE_STATUS_PREFETCH_BLOCK_Y)
+#define BP_PRE_PREFETCH_ENGINE_STATUS_PREFETCH_BLOCK_X 0
+#define BM_PRE_PREFETCH_ENGINE_STATUS_PREFETCH_BLOCK_X 0x0000FFFF
+#define BF_PRE_PREFETCH_ENGINE_STATUS_PREFETCH_BLOCK_X(v) \
+ (((v) << 0) & BM_PRE_PREFETCH_ENGINE_STATUS_PREFETCH_BLOCK_X)
+
+#define HW_PRE_PREFETCH_ENGINE_INPUT_SIZE (0x000000a0)
+
+#define BP_PRE_PREFETCH_ENGINE_INPUT_SIZE_INPUT_HEIGHT 16
+#define BM_PRE_PREFETCH_ENGINE_INPUT_SIZE_INPUT_HEIGHT 0xFFFF0000
+#define BF_PRE_PREFETCH_ENGINE_INPUT_SIZE_INPUT_HEIGHT(v) \
+ (((v) << 16) & BM_PRE_PREFETCH_ENGINE_INPUT_SIZE_INPUT_HEIGHT)
+#define BP_PRE_PREFETCH_ENGINE_INPUT_SIZE_INPUT_WIDTH 0
+#define BM_PRE_PREFETCH_ENGINE_INPUT_SIZE_INPUT_WIDTH 0x0000FFFF
+#define BF_PRE_PREFETCH_ENGINE_INPUT_SIZE_INPUT_WIDTH(v) \
+ (((v) << 0) & BM_PRE_PREFETCH_ENGINE_INPUT_SIZE_INPUT_WIDTH)
+
+#define HW_PRE_PREFETCH_ENGINE_OUTPUT_SIZE_ULC (0x000000b0)
+
+#define BP_PRE_PREFETCH_ENGINE_OUTPUT_SIZE_ULC_OUTPUT_SIZE_ULC_Y 16
+#define BM_PRE_PREFETCH_ENGINE_OUTPUT_SIZE_ULC_OUTPUT_SIZE_ULC_Y 0xFFFF0000
+#define BF_PRE_PREFETCH_ENGINE_OUTPUT_SIZE_ULC_OUTPUT_SIZE_ULC_Y(v) \
+ (((v) << 16) & BM_PRE_PREFETCH_ENGINE_OUTPUT_SIZE_ULC_OUTPUT_SIZE_ULC_Y)
+#define BP_PRE_PREFETCH_ENGINE_OUTPUT_SIZE_ULC_OUTPUT_SIZE_ULC_X 0
+#define BM_PRE_PREFETCH_ENGINE_OUTPUT_SIZE_ULC_OUTPUT_SIZE_ULC_X 0x0000FFFF
+#define BF_PRE_PREFETCH_ENGINE_OUTPUT_SIZE_ULC_OUTPUT_SIZE_ULC_X(v) \
+ (((v) << 0) & BM_PRE_PREFETCH_ENGINE_OUTPUT_SIZE_ULC_OUTPUT_SIZE_ULC_X)
+
+#define HW_PRE_PREFETCH_ENGINE_OUTPUT_SIZE_LRC (0x000000c0)
+
+#define BP_PRE_PREFETCH_ENGINE_OUTPUT_SIZE_LRC_OUTPUT_SIZE_LRC_Y 16
+#define BM_PRE_PREFETCH_ENGINE_OUTPUT_SIZE_LRC_OUTPUT_SIZE_LRC_Y 0xFFFF0000
+#define BF_PRE_PREFETCH_ENGINE_OUTPUT_SIZE_LRC_OUTPUT_SIZE_LRC_Y(v) \
+ (((v) << 16) & BM_PRE_PREFETCH_ENGINE_OUTPUT_SIZE_LRC_OUTPUT_SIZE_LRC_Y)
+#define BP_PRE_PREFETCH_ENGINE_OUTPUT_SIZE_LRC_OUTPUT_SIZE_LRC_X 0
+#define BM_PRE_PREFETCH_ENGINE_OUTPUT_SIZE_LRC_OUTPUT_SIZE_LRC_X 0x0000FFFF
+#define BF_PRE_PREFETCH_ENGINE_OUTPUT_SIZE_LRC_OUTPUT_SIZE_LRC_X(v) \
+ (((v) << 0) & BM_PRE_PREFETCH_ENGINE_OUTPUT_SIZE_LRC_OUTPUT_SIZE_LRC_X)
+
+#define HW_PRE_PREFETCH_ENGINE_PITCH (0x000000d0)
+
+#define BP_PRE_PREFETCH_ENGINE_PITCH_INPUT_UV_PITCH 16
+#define BM_PRE_PREFETCH_ENGINE_PITCH_INPUT_UV_PITCH 0xFFFF0000
+#define BF_PRE_PREFETCH_ENGINE_PITCH_INPUT_UV_PITCH(v) \
+ (((v) << 16) & BM_PRE_PREFETCH_ENGINE_PITCH_INPUT_UV_PITCH)
+#define BP_PRE_PREFETCH_ENGINE_PITCH_INPUT_Y_PITCH 0
+#define BM_PRE_PREFETCH_ENGINE_PITCH_INPUT_Y_PITCH 0x0000FFFF
+#define BF_PRE_PREFETCH_ENGINE_PITCH_INPUT_Y_PITCH(v) \
+ (((v) << 0) & BM_PRE_PREFETCH_ENGINE_PITCH_INPUT_Y_PITCH)
+
+#define HW_PRE_PREFETCH_ENGINE_SHIFT_OFFSET (0x000000e0)
+#define HW_PRE_PREFETCH_ENGINE_SHIFT_OFFSET_SET (0x000000e4)
+#define HW_PRE_PREFETCH_ENGINE_SHIFT_OFFSET_CLR (0x000000e8)
+#define HW_PRE_PREFETCH_ENGINE_SHIFT_OFFSET_TOG (0x000000ec)
+
+#define BP_PRE_PREFETCH_ENGINE_SHIFT_OFFSET_RSVD0 29
+#define BM_PRE_PREFETCH_ENGINE_SHIFT_OFFSET_RSVD0 0xE0000000
+#define BF_PRE_PREFETCH_ENGINE_SHIFT_OFFSET_RSVD0(v) \
+ (((v) << 29) & BM_PRE_PREFETCH_ENGINE_SHIFT_OFFSET_RSVD0)
+#define BP_PRE_PREFETCH_ENGINE_SHIFT_OFFSET_OFFSET3 24
+#define BM_PRE_PREFETCH_ENGINE_SHIFT_OFFSET_OFFSET3 0x1F000000
+#define BF_PRE_PREFETCH_ENGINE_SHIFT_OFFSET_OFFSET3(v) \
+ (((v) << 24) & BM_PRE_PREFETCH_ENGINE_SHIFT_OFFSET_OFFSET3)
+#define BP_PRE_PREFETCH_ENGINE_SHIFT_OFFSET_RSVD1 21
+#define BM_PRE_PREFETCH_ENGINE_SHIFT_OFFSET_RSVD1 0x00E00000
+#define BF_PRE_PREFETCH_ENGINE_SHIFT_OFFSET_RSVD1(v) \
+ (((v) << 21) & BM_PRE_PREFETCH_ENGINE_SHIFT_OFFSET_RSVD1)
+#define BP_PRE_PREFETCH_ENGINE_SHIFT_OFFSET_OFFSET2 16
+#define BM_PRE_PREFETCH_ENGINE_SHIFT_OFFSET_OFFSET2 0x001F0000
+#define BF_PRE_PREFETCH_ENGINE_SHIFT_OFFSET_OFFSET2(v) \
+ (((v) << 16) & BM_PRE_PREFETCH_ENGINE_SHIFT_OFFSET_OFFSET2)
+#define BP_PRE_PREFETCH_ENGINE_SHIFT_OFFSET_RSVD2 13
+#define BM_PRE_PREFETCH_ENGINE_SHIFT_OFFSET_RSVD2 0x0000E000
+#define BF_PRE_PREFETCH_ENGINE_SHIFT_OFFSET_RSVD2(v) \
+ (((v) << 13) & BM_PRE_PREFETCH_ENGINE_SHIFT_OFFSET_RSVD2)
+#define BP_PRE_PREFETCH_ENGINE_SHIFT_OFFSET_OFFSET1 8
+#define BM_PRE_PREFETCH_ENGINE_SHIFT_OFFSET_OFFSET1 0x00001F00
+#define BF_PRE_PREFETCH_ENGINE_SHIFT_OFFSET_OFFSET1(v) \
+ (((v) << 8) & BM_PRE_PREFETCH_ENGINE_SHIFT_OFFSET_OFFSET1)
+#define BP_PRE_PREFETCH_ENGINE_SHIFT_OFFSET_RSVD3 5
+#define BM_PRE_PREFETCH_ENGINE_SHIFT_OFFSET_RSVD3 0x000000E0
+#define BF_PRE_PREFETCH_ENGINE_SHIFT_OFFSET_RSVD3(v) \
+ (((v) << 5) & BM_PRE_PREFETCH_ENGINE_SHIFT_OFFSET_RSVD3)
+#define BP_PRE_PREFETCH_ENGINE_SHIFT_OFFSET_OFFSET0 0
+#define BM_PRE_PREFETCH_ENGINE_SHIFT_OFFSET_OFFSET0 0x0000001F
+#define BF_PRE_PREFETCH_ENGINE_SHIFT_OFFSET_OFFSET0(v) \
+ (((v) << 0) & BM_PRE_PREFETCH_ENGINE_SHIFT_OFFSET_OFFSET0)
+
+#define HW_PRE_PREFETCH_ENGINE_SHIFT_WIDTH (0x000000f0)
+#define HW_PRE_PREFETCH_ENGINE_SHIFT_WIDTH_SET (0x000000f4)
+#define HW_PRE_PREFETCH_ENGINE_SHIFT_WIDTH_CLR (0x000000f8)
+#define HW_PRE_PREFETCH_ENGINE_SHIFT_WIDTH_TOG (0x000000fc)
+
+#define BP_PRE_PREFETCH_ENGINE_SHIFT_WIDTH_RSVD0 16
+#define BM_PRE_PREFETCH_ENGINE_SHIFT_WIDTH_RSVD0 0xFFFF0000
+#define BF_PRE_PREFETCH_ENGINE_SHIFT_WIDTH_RSVD0(v) \
+ (((v) << 16) & BM_PRE_PREFETCH_ENGINE_SHIFT_WIDTH_RSVD0)
+#define BP_PRE_PREFETCH_ENGINE_SHIFT_WIDTH_WIDTH3 12
+#define BM_PRE_PREFETCH_ENGINE_SHIFT_WIDTH_WIDTH3 0x0000F000
+#define BF_PRE_PREFETCH_ENGINE_SHIFT_WIDTH_WIDTH3(v) \
+ (((v) << 12) & BM_PRE_PREFETCH_ENGINE_SHIFT_WIDTH_WIDTH3)
+#define BP_PRE_PREFETCH_ENGINE_SHIFT_WIDTH_WIDTH2 8
+#define BM_PRE_PREFETCH_ENGINE_SHIFT_WIDTH_WIDTH2 0x00000F00
+#define BF_PRE_PREFETCH_ENGINE_SHIFT_WIDTH_WIDTH2(v) \
+ (((v) << 8) & BM_PRE_PREFETCH_ENGINE_SHIFT_WIDTH_WIDTH2)
+#define BP_PRE_PREFETCH_ENGINE_SHIFT_WIDTH_WIDTH1 4
+#define BM_PRE_PREFETCH_ENGINE_SHIFT_WIDTH_WIDTH1 0x000000F0
+#define BF_PRE_PREFETCH_ENGINE_SHIFT_WIDTH_WIDTH1(v) \
+ (((v) << 4) & BM_PRE_PREFETCH_ENGINE_SHIFT_WIDTH_WIDTH1)
+#define BP_PRE_PREFETCH_ENGINE_SHIFT_WIDTH_WIDTH0 0
+#define BM_PRE_PREFETCH_ENGINE_SHIFT_WIDTH_WIDTH0 0x0000000F
+#define BF_PRE_PREFETCH_ENGINE_SHIFT_WIDTH_WIDTH0(v) \
+ (((v) << 0) & BM_PRE_PREFETCH_ENGINE_SHIFT_WIDTH_WIDTH0)
+
+#define HW_PRE_PREFETCH_ENGINE_INTERLACE_OFFSET (0x00000100)
+
+#define BP_PRE_PREFETCH_ENGINE_INTERLACE_OFFSET_RSVD0 23
+#define BM_PRE_PREFETCH_ENGINE_INTERLACE_OFFSET_RSVD0 0xFF800000
+#define BF_PRE_PREFETCH_ENGINE_INTERLACE_OFFSET_RSVD0(v) \
+ (((v) << 23) & BM_PRE_PREFETCH_ENGINE_INTERLACE_OFFSET_RSVD0)
+#define BP_PRE_PREFETCH_ENGINE_INTERLACE_OFFSET_INTERLACE_OFFSET 0
+#define BM_PRE_PREFETCH_ENGINE_INTERLACE_OFFSET_INTERLACE_OFFSET 0xFFFFFFFF
+#define BF_PRE_PREFETCH_ENGINE_INTERLACE_OFFSET_INTERLACE_OFFSET(v) \
+ (((v) << 0) & BM_PRE_PREFETCH_ENGINE_INTERLACE_OFFSET_INTERLACE_OFFSET)
+
+#define HW_PRE_STORE_ENGINE_CTRL (0x00000110)
+#define HW_PRE_STORE_ENGINE_CTRL_SET (0x00000114)
+#define HW_PRE_STORE_ENGINE_CTRL_CLR (0x00000118)
+#define HW_PRE_STORE_ENGINE_CTRL_TOG (0x0000011c)
+
+#define BP_PRE_STORE_ENGINE_CTRL_RSVD0 6
+#define BM_PRE_STORE_ENGINE_CTRL_RSVD0 0xFFFFFFC0
+#define BF_PRE_STORE_ENGINE_CTRL_RSVD0(v) \
+ (((v) << 6) & BM_PRE_STORE_ENGINE_CTRL_RSVD0)
+#define BP_PRE_STORE_ENGINE_CTRL_OUTPUT_ACTIVE_BPP 4
+#define BM_PRE_STORE_ENGINE_CTRL_OUTPUT_ACTIVE_BPP 0x00000030
+#define BF_PRE_STORE_ENGINE_CTRL_OUTPUT_ACTIVE_BPP(v) \
+ (((v) << 4) & BM_PRE_STORE_ENGINE_CTRL_OUTPUT_ACTIVE_BPP)
+#define BV_PRE_STORE_ENGINE_CTRL_OUTPUT_ACTIVE_BPP__8_bits 0x0
+#define BV_PRE_STORE_ENGINE_CTRL_OUTPUT_ACTIVE_BPP__16_bits 0x1
+#define BV_PRE_STORE_ENGINE_CTRL_OUTPUT_ACTIVE_BPP__32_bits 0x2
+#define BV_PRE_STORE_ENGINE_CTRL_OUTPUT_ACTIVE_BPP__64_bits 0x3
+#define BP_PRE_STORE_ENGINE_CTRL_WR_NUM_BYTES 1
+#define BM_PRE_STORE_ENGINE_CTRL_WR_NUM_BYTES 0x0000000E
+#define BF_PRE_STORE_ENGINE_CTRL_WR_NUM_BYTES(v) \
+ (((v) << 1) & BM_PRE_STORE_ENGINE_CTRL_WR_NUM_BYTES)
+#define BV_PRE_STORE_ENGINE_CTRL_WR_NUM_BYTES__8_bytes 0x0
+#define BV_PRE_STORE_ENGINE_CTRL_WR_NUM_BYTES__16_bytes 0x1
+#define BV_PRE_STORE_ENGINE_CTRL_WR_NUM_BYTES__32_bytes 0x2
+#define BV_PRE_STORE_ENGINE_CTRL_WR_NUM_BYTES__64_bytes 0x3
+#define BV_PRE_STORE_ENGINE_CTRL_WR_NUM_BYTES__128_bytes 0x4
+#define BM_PRE_STORE_ENGINE_CTRL_STORE_EN 0x00000001
+#define BF_PRE_STORE_ENGINE_CTRL_STORE_EN(v) \
+ (((v) << 0) & BM_PRE_STORE_ENGINE_CTRL_STORE_EN)
+#define BV_PRE_STORE_ENGINE_CTRL_STORE_EN__0 0x0
+#define BV_PRE_STORE_ENGINE_CTRL_STORE_EN__1 0x1
+
+#define HW_PRE_STORE_ENGINE_STATUS (0x00000120)
+
+#define BP_PRE_STORE_ENGINE_STATUS_STORE_BLOCK_Y 16
+#define BM_PRE_STORE_ENGINE_STATUS_STORE_BLOCK_Y 0x3FFF0000
+#define BF_PRE_STORE_ENGINE_STATUS_STORE_BLOCK_Y(v) \
+ (((v) << 16) & BM_PRE_STORE_ENGINE_STATUS_STORE_BLOCK_Y)
+#define BP_PRE_STORE_ENGINE_STATUS_STORE_BLOCK_X 0
+#define BM_PRE_STORE_ENGINE_STATUS_STORE_BLOCK_X 0x0000FFFF
+#define BF_PRE_STORE_ENGINE_STATUS_STORE_BLOCK_X(v) \
+ (((v) << 0) & BM_PRE_STORE_ENGINE_STATUS_STORE_BLOCK_X)
+
+#define HW_PRE_STORE_ENGINE_SIZE (0x00000130)
+
+#define BP_PRE_STORE_ENGINE_SIZE_INPUT_TOTAL_HEIGHT 16
+#define BM_PRE_STORE_ENGINE_SIZE_INPUT_TOTAL_HEIGHT 0xFFFF0000
+#define BF_PRE_STORE_ENGINE_SIZE_INPUT_TOTAL_HEIGHT(v) \
+ (((v) << 16) & BM_PRE_STORE_ENGINE_SIZE_INPUT_TOTAL_HEIGHT)
+#define BP_PRE_STORE_ENGINE_SIZE_INPUT_TOTAL_WIDTH 0
+#define BM_PRE_STORE_ENGINE_SIZE_INPUT_TOTAL_WIDTH 0x0000FFFF
+#define BF_PRE_STORE_ENGINE_SIZE_INPUT_TOTAL_WIDTH(v) \
+ (((v) << 0) & BM_PRE_STORE_ENGINE_SIZE_INPUT_TOTAL_WIDTH)
+
+#define HW_PRE_STORE_ENGINE_PITCH (0x00000140)
+
+#define BP_PRE_STORE_ENGINE_PITCH_RSVD0 16
+#define BM_PRE_STORE_ENGINE_PITCH_RSVD0 0xFFFF0000
+#define BF_PRE_STORE_ENGINE_PITCH_RSVD0(v) \
+ (((v) << 16) & BM_PRE_STORE_ENGINE_PITCH_RSVD0)
+#define BP_PRE_STORE_ENGINE_PITCH_OUT_PITCH 0
+#define BM_PRE_STORE_ENGINE_PITCH_OUT_PITCH 0x0000FFFF
+#define BF_PRE_STORE_ENGINE_PITCH_OUT_PITCH(v) \
+ (((v) << 0) & BM_PRE_STORE_ENGINE_PITCH_OUT_PITCH)
+
+#define HW_PRE_STORE_ENGINE_ADDR (0x00000150)
+
+#define BP_PRE_STORE_ENGINE_ADDR_OUT_BASE_ADDR 0
+#define BM_PRE_STORE_ENGINE_ADDR_OUT_BASE_ADDR 0xFFFFFFFF
+#define BF_PRE_STORE_ENGINE_ADDR_OUT_BASE_ADDR(v) (v)
+#endif /* __ARCH_ARM___PRE_H */
diff --git a/drivers/mxc/ipu3/pre.c b/drivers/mxc/ipu3/pre.c
new file mode 100644
index 000000000000..f1ce02b3fe90
--- /dev/null
+++ b/drivers/mxc/ipu3/pre.c
@@ -0,0 +1,999 @@
+/*
+ * Copyright (C) 2014-2016 Freescale Semiconductor, Inc.
+ *
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+#include <linux/clk.h>
+#include <linux/genalloc.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/ipu-v3.h>
+#include <linux/ipu-v3-pre.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+
+#include "pre-regs.h"
+
+struct ipu_pre_data {
+ unsigned int id;
+ struct device *dev;
+ void __iomem *base;
+ struct clk *clk;
+
+ struct mutex mutex; /* for in_use */
+ spinlock_t lock; /* for register access */
+
+ struct list_head list;
+
+ struct gen_pool *iram_pool;
+ unsigned long double_buffer_size;
+ unsigned long double_buffer_base;
+ unsigned long double_buffer_paddr;
+
+ bool in_use;
+ bool enabled;
+};
+
+static LIST_HEAD(pre_list);
+static DEFINE_SPINLOCK(pre_list_lock);
+
+static inline void pre_write(struct ipu_pre_data *pre,
+ u32 value, unsigned int offset)
+{
+ writel(value, pre->base + offset);
+}
+
+static inline u32 pre_read(struct ipu_pre_data *pre, unsigned offset)
+{
+ return readl(pre->base + offset);
+}
+
+static struct ipu_pre_data *get_pre(unsigned int id)
+{
+ struct ipu_pre_data *pre;
+ unsigned long lock_flags;
+
+ spin_lock_irqsave(&pre_list_lock, lock_flags);
+ list_for_each_entry(pre, &pre_list, list) {
+ if (pre->id == id) {
+ spin_unlock_irqrestore(&pre_list_lock, lock_flags);
+ return pre;
+ }
+ }
+ spin_unlock_irqrestore(&pre_list_lock, lock_flags);
+
+ return NULL;
+}
+
+int ipu_pre_alloc(int ipu_id, ipu_channel_t channel)
+{
+ struct ipu_pre_data *pre;
+ int i, fixed;
+
+ if (channel == MEM_BG_SYNC) {
+ fixed = ipu_id ? 3 : 0;
+ pre = get_pre(fixed);
+ if (pre) {
+ mutex_lock(&pre->mutex);
+ if (!pre->in_use) {
+ pre->in_use = true;
+ mutex_unlock(&pre->mutex);
+ return pre->id;
+ }
+ mutex_unlock(&pre->mutex);
+ }
+ return pre ? -EBUSY : -ENOENT;
+ }
+
+ for (i = 1; i < 3; i++) {
+ pre = get_pre(i);
+ if (!pre)
+ continue;
+ mutex_lock(&pre->mutex);
+ if (!pre->in_use) {
+ pre->in_use = true;
+ mutex_unlock(&pre->mutex);
+ return pre->id;
+ }
+ mutex_unlock(&pre->mutex);
+ }
+
+ return pre ? -EBUSY : -ENOENT;
+}
+EXPORT_SYMBOL(ipu_pre_alloc);
+
+void ipu_pre_free(unsigned int *id)
+{
+ struct ipu_pre_data *pre;
+
+ pre = get_pre(*id);
+ if (!pre)
+ return;
+
+ mutex_lock(&pre->mutex);
+ pre->in_use = false;
+ mutex_unlock(&pre->mutex);
+
+ *id = -1;
+}
+EXPORT_SYMBOL(ipu_pre_free);
+
+unsigned long ipu_pre_alloc_double_buffer(unsigned int id, unsigned int size)
+{
+ struct ipu_pre_data *pre = get_pre(id);
+
+ if (!pre)
+ return -ENOENT;
+
+ if (!size)
+ return -EINVAL;
+
+ pre->double_buffer_base = gen_pool_alloc(pre->iram_pool, size);
+ if (!pre->double_buffer_base) {
+ dev_err(pre->dev, "double buffer allocate failed\n");
+ return -ENOMEM;
+ }
+ pre->double_buffer_size = size;
+
+ pre->double_buffer_paddr = gen_pool_virt_to_phys(pre->iram_pool,
+ pre->double_buffer_base);
+
+ return pre->double_buffer_paddr;
+}
+EXPORT_SYMBOL(ipu_pre_alloc_double_buffer);
+
+void ipu_pre_free_double_buffer(unsigned int id)
+{
+ struct ipu_pre_data *pre = get_pre(id);
+
+ if (!pre)
+ return;
+
+ if (pre->double_buffer_base) {
+ gen_pool_free(pre->iram_pool,
+ pre->double_buffer_base,
+ pre->double_buffer_size);
+ pre->double_buffer_base = 0;
+ pre->double_buffer_size = 0;
+ pre->double_buffer_paddr = 0;
+ }
+}
+EXPORT_SYMBOL(ipu_pre_free_double_buffer);
+
+/* PRE register configurations */
+int ipu_pre_set_ctrl(unsigned int id, struct ipu_pre_context *config)
+{
+ struct ipu_pre_data *pre = get_pre(id);
+ unsigned long lock_flags;
+ int ret = 0;
+
+ if (!pre)
+ return -EINVAL;
+
+ if (!pre->enabled)
+ clk_prepare_enable(pre->clk);
+
+ spin_lock_irqsave(&pre->lock, lock_flags);
+ pre_write(pre, BF_PRE_CTRL_TPR_RESET_SEL(1), HW_PRE_CTRL_SET);
+
+ if (config->repeat)
+ pre_write(pre, BF_PRE_CTRL_EN_REPEAT(1), HW_PRE_CTRL_SET);
+ else
+ pre_write(pre, BM_PRE_CTRL_EN_REPEAT, HW_PRE_CTRL_CLR);
+
+ if (config->vflip)
+ pre_write(pre, BF_PRE_CTRL_VFLIP(1), HW_PRE_CTRL_SET);
+ else
+ pre_write(pre, BM_PRE_CTRL_VFLIP, HW_PRE_CTRL_CLR);
+
+ if (config->handshake_en) {
+ pre_write(pre, BF_PRE_CTRL_HANDSHAKE_EN(1), HW_PRE_CTRL_SET);
+ if (config->hsk_abort_en)
+ pre_write(pre, BF_PRE_CTRL_HANDSHAKE_ABORT_SKIP_EN(1),
+ HW_PRE_CTRL_SET);
+ else
+ pre_write(pre, BM_PRE_CTRL_HANDSHAKE_ABORT_SKIP_EN,
+ HW_PRE_CTRL_CLR);
+
+ switch (config->hsk_line_num) {
+ case 0 /* 4 lines */:
+ pre_write(pre, BM_PRE_CTRL_HANDSHAKE_LINE_NUM,
+ HW_PRE_CTRL_CLR);
+ break;
+ case 1 /* 8 lines */:
+ pre_write(pre, BM_PRE_CTRL_HANDSHAKE_LINE_NUM,
+ HW_PRE_CTRL_CLR);
+ pre_write(pre, BF_PRE_CTRL_HANDSHAKE_LINE_NUM(1),
+ HW_PRE_CTRL_SET);
+ break;
+ case 2 /* 16 lines */:
+ pre_write(pre, BM_PRE_CTRL_HANDSHAKE_LINE_NUM,
+ HW_PRE_CTRL_CLR);
+ pre_write(pre, BF_PRE_CTRL_HANDSHAKE_LINE_NUM(2),
+ HW_PRE_CTRL_SET);
+ break;
+ default:
+ dev_err(pre->dev, "invalid hanshake line number\n");
+ ret = -EINVAL;
+ goto err;
+ }
+ } else
+ pre_write(pre, BM_PRE_CTRL_HANDSHAKE_EN, HW_PRE_CTRL_CLR);
+
+
+ switch (config->prefetch_mode) {
+ case 0:
+ pre_write(pre, BM_PRE_CTRL_BLOCK_EN, HW_PRE_CTRL_CLR);
+ break;
+ case 1:
+ pre_write(pre, BF_PRE_CTRL_BLOCK_EN(1), HW_PRE_CTRL_SET);
+ switch (config->block_size) {
+ case 0:
+ pre_write(pre, BM_PRE_CTRL_BLOCK_16, HW_PRE_CTRL_CLR);
+ break;
+ case 1:
+ pre_write(pre, BF_PRE_CTRL_BLOCK_16(1), HW_PRE_CTRL_SET);
+ break;
+ default:
+ dev_err(pre->dev, "invalid block size for pre\n");
+ ret = -EINVAL;
+ goto err;
+ }
+ break;
+ default:
+ dev_err(pre->dev, "invalid prefech mode for pre\n");
+ ret = -EINVAL;
+ goto err;
+ }
+
+ switch (config->interlaced) {
+ case 0: /* progressive mode */
+ pre_write(pre, BM_PRE_CTRL_SO, HW_PRE_CTRL_CLR);
+ break;
+ case 2: /* interlaced mode: Pal */
+ pre_write(pre, BF_PRE_CTRL_SO(1), HW_PRE_CTRL_SET);
+ pre_write(pre, BM_PRE_CTRL_INTERLACED_FIELD, HW_PRE_CTRL_CLR);
+ break;
+ case 3: /* interlaced mode: NTSC */
+ pre_write(pre, BF_PRE_CTRL_SO(1), HW_PRE_CTRL_SET);
+ pre_write(pre, BF_PRE_CTRL_INTERLACED_FIELD(1), HW_PRE_CTRL_SET);
+ break;
+ default:
+ dev_err(pre->dev, "invalid interlaced or progressive mode\n");
+ ret = -EINVAL;
+ goto err;
+ }
+
+ if (config->sdw_update)
+ pre_write(pre, BF_PRE_CTRL_SDW_UPDATE(1), HW_PRE_CTRL_SET);
+ else
+ pre_write(pre, BM_PRE_CTRL_SDW_UPDATE, HW_PRE_CTRL_CLR);
+
+err:
+ spin_unlock_irqrestore(&pre->lock, lock_flags);
+
+ if (!pre->enabled)
+ clk_disable_unprepare(pre->clk);
+
+ return ret;
+}
+EXPORT_SYMBOL(ipu_pre_set_ctrl);
+
+static void ipu_pre_irq_mask(struct ipu_pre_data *pre,
+ unsigned long mask, bool clear)
+{
+ if (clear) {
+ pre_write(pre, mask & 0x1f, HW_PRE_IRQ_MASK_CLR);
+ return;
+ }
+ pre_write(pre, mask & 0x1f, HW_PRE_IRQ_MASK_SET);
+}
+
+static int ipu_pre_buf_set(unsigned int id, unsigned long cur_buf,
+ unsigned long next_buf)
+{
+ struct ipu_pre_data *pre = get_pre(id);
+ unsigned long lock_flags;
+
+ if (!pre)
+ return -EINVAL;
+
+ spin_lock_irqsave(&pre->lock, lock_flags);
+ pre_write(pre, cur_buf, HW_PRE_CUR_BUF);
+ pre_write(pre, next_buf, HW_PRE_NEXT_BUF);
+ spin_unlock_irqrestore(&pre->lock, lock_flags);
+
+ return 0;
+}
+
+static int ipu_pre_plane_buf_off_set(unsigned int id,
+ unsigned long sec_buf_off,
+ unsigned long trd_buf_off)
+{
+ struct ipu_pre_data *pre = get_pre(id);
+ unsigned long lock_flags;
+
+ if (!pre || sec_buf_off & BM_PRE_U_BUF_OFFSET_RSVD0 ||
+ trd_buf_off & BM_PRE_V_BUF_OFFSET_RSVD0)
+ return -EINVAL;
+
+ spin_lock_irqsave(&pre->lock, lock_flags);
+ pre_write(pre, sec_buf_off, HW_PRE_U_BUF_OFFSET);
+ pre_write(pre, trd_buf_off, HW_PRE_V_BUF_OFFSET);
+ spin_unlock_irqrestore(&pre->lock, lock_flags);
+
+ return 0;
+}
+
+static int ipu_pre_tpr_set(unsigned int id, unsigned int tile_fmt)
+{
+ struct ipu_pre_data *pre = get_pre(id);
+ unsigned long lock_flags;
+ unsigned int tpr_ctrl, fmt;
+
+ if (!pre)
+ return -EINVAL;
+
+ switch (tile_fmt) {
+ case 0x0: /* Bypass */
+ fmt = BF_PRE_TPR_CTRL_TILE_FORMAT(0x0);
+ break;
+ case IPU_PIX_FMT_GPU32_SB_ST:
+ fmt = BF_PRE_TPR_CTRL_TILE_FORMAT(0x10);
+ break;
+ case IPU_PIX_FMT_GPU16_SB_ST:
+ fmt = BF_PRE_TPR_CTRL_TILE_FORMAT(0x11);
+ break;
+ case IPU_PIX_FMT_GPU32_ST:
+ fmt = BF_PRE_TPR_CTRL_TILE_FORMAT(0x20);
+ break;
+ case IPU_PIX_FMT_GPU16_ST:
+ fmt = BF_PRE_TPR_CTRL_TILE_FORMAT(0x21);
+ break;
+ case IPU_PIX_FMT_GPU32_SB_SRT:
+ fmt = BF_PRE_TPR_CTRL_TILE_FORMAT(0x50);
+ break;
+ case IPU_PIX_FMT_GPU16_SB_SRT:
+ fmt = BF_PRE_TPR_CTRL_TILE_FORMAT(0x51);
+ break;
+ case IPU_PIX_FMT_GPU32_SRT:
+ fmt = BF_PRE_TPR_CTRL_TILE_FORMAT(0x60);
+ break;
+ case IPU_PIX_FMT_GPU16_SRT:
+ fmt = BF_PRE_TPR_CTRL_TILE_FORMAT(0x61);
+ break;
+ default:
+ dev_err(pre->dev, "invalid tile fmt for pre\n");
+ return -EINVAL;
+ }
+
+ spin_lock_irqsave(&pre->lock, lock_flags);
+ tpr_ctrl = pre_read(pre, HW_PRE_TPR_CTRL);
+ tpr_ctrl &= ~BM_PRE_TPR_CTRL_TILE_FORMAT;
+ tpr_ctrl |= fmt;
+ pre_write(pre, tpr_ctrl, HW_PRE_TPR_CTRL);
+ spin_unlock_irqrestore(&pre->lock, lock_flags);
+
+ return 0;
+}
+
+static int ipu_pre_set_shift(int id, unsigned int offset, unsigned int width)
+{
+ struct ipu_pre_data *pre = get_pre(id);
+ unsigned long lock_flags;
+
+ if (!pre)
+ return -EINVAL;
+
+ spin_lock_irqsave(&pre->lock, lock_flags);
+ pre_write(pre, offset, HW_PRE_PREFETCH_ENGINE_SHIFT_OFFSET);
+ pre_write(pre, width, HW_PRE_PREFETCH_ENGINE_SHIFT_WIDTH);
+ spin_unlock_irqrestore(&pre->lock, lock_flags);
+
+ return 0;
+}
+
+static int ipu_pre_prefetch(unsigned int id,
+ unsigned int read_burst,
+ unsigned int input_bpp,
+ unsigned int input_pixel_fmt,
+ bool shift_bypass,
+ bool field_inverse,
+ bool tpr_coor_offset_en,
+ struct ipu_rect output_size,
+ unsigned int input_width,
+ unsigned int input_height,
+ unsigned int input_active_width,
+ unsigned int interlaced,
+ int interlace_offset)
+{
+ unsigned int prefetch_ctrl = 0;
+ unsigned int input_y_pitch = 0, input_uv_pitch = 0;
+ struct ipu_pre_data *pre = get_pre(id);
+ unsigned long lock_flags;
+
+ if (!pre)
+ return -EINVAL;
+
+ spin_lock_irqsave(&pre->lock, lock_flags);
+ prefetch_ctrl |= BF_PRE_PREFETCH_ENGINE_CTRL_PREFETCH_EN(1);
+ switch (read_burst) {
+ case 0x0:
+ prefetch_ctrl |= BF_PRE_PREFETCH_ENGINE_CTRL_RD_NUM_BYTES(0x0);
+ break;
+ case 0x1:
+ prefetch_ctrl |= BF_PRE_PREFETCH_ENGINE_CTRL_RD_NUM_BYTES(0x1);
+ break;
+ case 0x2:
+ prefetch_ctrl |= BF_PRE_PREFETCH_ENGINE_CTRL_RD_NUM_BYTES(0x2);
+ break;
+ case 0x3:
+ prefetch_ctrl |= BF_PRE_PREFETCH_ENGINE_CTRL_RD_NUM_BYTES(0x3);
+ break;
+ case 0x4:
+ prefetch_ctrl |= BF_PRE_PREFETCH_ENGINE_CTRL_RD_NUM_BYTES(0x4);
+ break;
+ default:
+ spin_unlock_irqrestore(&pre->lock, lock_flags);
+ dev_err(pre->dev, "invalid read burst for prefetch engine\n");
+ return -EINVAL;
+ }
+
+ switch (input_bpp) {
+ case 8:
+ prefetch_ctrl |= BF_PRE_PREFETCH_ENGINE_CTRL_INPUT_ACTIVE_BPP(0x0);
+ break;
+ case 16:
+ prefetch_ctrl |= BF_PRE_PREFETCH_ENGINE_CTRL_INPUT_ACTIVE_BPP(0x1);
+ break;
+ case 32:
+ prefetch_ctrl |= BF_PRE_PREFETCH_ENGINE_CTRL_INPUT_ACTIVE_BPP(0x2);
+ break;
+ case 64:
+ prefetch_ctrl |= BF_PRE_PREFETCH_ENGINE_CTRL_INPUT_ACTIVE_BPP(0x3);
+ break;
+ default:
+ spin_unlock_irqrestore(&pre->lock, lock_flags);
+ dev_err(pre->dev, "invalid input bpp for prefetch engine\n");
+ return -EINVAL;
+ }
+
+ switch (input_pixel_fmt) {
+ case 0x1: /* tile */
+ case 0x0: /* generic data */
+ case IPU_PIX_FMT_RGB666:
+ case IPU_PIX_FMT_RGB565:
+ case IPU_PIX_FMT_BGRA4444:
+ case IPU_PIX_FMT_BGRA5551:
+ case IPU_PIX_FMT_BGR24:
+ case IPU_PIX_FMT_RGB24:
+ case IPU_PIX_FMT_GBR24:
+ case IPU_PIX_FMT_BGR32:
+ case IPU_PIX_FMT_BGRA32:
+ case IPU_PIX_FMT_RGB32:
+ case IPU_PIX_FMT_RGBA32:
+ case IPU_PIX_FMT_ABGR32:
+ case IPU_PIX_FMT_YUYV:
+ case IPU_PIX_FMT_UYVY:
+ case IPU_PIX_FMT_YUV444:
+ case IPU_PIX_FMT_AYUV:
+ prefetch_ctrl |= BF_PRE_PREFETCH_ENGINE_CTRL_INPUT_PIXEL_FORMAT(0x0);
+ input_y_pitch = input_width * (input_bpp >> 3);
+ if (interlaced && input_pixel_fmt != 0x1)
+ input_y_pitch *= 2;
+ break;
+ case IPU_PIX_FMT_YUV444P:
+ prefetch_ctrl |= BF_PRE_PREFETCH_ENGINE_CTRL_INPUT_PIXEL_FORMAT(0x1);
+ input_y_pitch = input_width;
+ input_uv_pitch = input_width;
+ break;
+ case IPU_PIX_FMT_YUV422P:
+ case IPU_PIX_FMT_YVU422P:
+ prefetch_ctrl |= BF_PRE_PREFETCH_ENGINE_CTRL_INPUT_PIXEL_FORMAT(0x2);
+ input_y_pitch = input_width;
+ input_uv_pitch = input_width >> 1;
+ break;
+ case IPU_PIX_FMT_YUV420P2:
+ case IPU_PIX_FMT_YUV420P:
+ prefetch_ctrl |= BF_PRE_PREFETCH_ENGINE_CTRL_INPUT_PIXEL_FORMAT(0x3);
+ input_y_pitch = input_width;
+ input_uv_pitch = input_width >> 1;
+ break;
+ case PRE_PIX_FMT_NV61:
+ prefetch_ctrl |= BM_PRE_PREFETCH_ENGINE_CTRL_PARTIAL_UV_SWAP;
+ case IPU_PIX_FMT_NV16:
+ prefetch_ctrl |= BF_PRE_PREFETCH_ENGINE_CTRL_INPUT_PIXEL_FORMAT(0x4);
+ input_y_pitch = input_width;
+ input_uv_pitch = input_width;
+ break;
+ case PRE_PIX_FMT_NV21:
+ prefetch_ctrl |= BM_PRE_PREFETCH_ENGINE_CTRL_PARTIAL_UV_SWAP;
+ case IPU_PIX_FMT_NV12:
+ prefetch_ctrl |= BF_PRE_PREFETCH_ENGINE_CTRL_INPUT_PIXEL_FORMAT(0x5);
+ input_y_pitch = input_width;
+ input_uv_pitch = input_width;
+ break;
+ default:
+ spin_unlock_irqrestore(&pre->lock, lock_flags);
+ dev_err(pre->dev, "invalid input pixel format for prefetch engine\n");
+ return -EINVAL;
+ }
+
+ prefetch_ctrl |= BF_PRE_PREFETCH_ENGINE_CTRL_SHIFT_BYPASS(shift_bypass ? 1 : 0);
+ prefetch_ctrl |= BF_PRE_PREFETCH_ENGINE_CTRL_FIELD_INVERSE(field_inverse ? 1 : 0);
+ prefetch_ctrl |= BF_PRE_PREFETCH_ENGINE_CTRL_TPR_COOR_OFFSET_EN(tpr_coor_offset_en ? 1 : 0);
+
+ pre_write(pre, BF_PRE_PREFETCH_ENGINE_INPUT_SIZE_INPUT_WIDTH(input_active_width) |
+ BF_PRE_PREFETCH_ENGINE_INPUT_SIZE_INPUT_HEIGHT(input_height),
+ HW_PRE_PREFETCH_ENGINE_INPUT_SIZE);
+
+ if (tpr_coor_offset_en)
+ pre_write(pre, BF_PRE_PREFETCH_ENGINE_OUTPUT_SIZE_ULC_OUTPUT_SIZE_ULC_X(output_size.left) |
+ BF_PRE_PREFETCH_ENGINE_OUTPUT_SIZE_ULC_OUTPUT_SIZE_ULC_Y(output_size.top),
+ HW_PRE_PREFETCH_ENGINE_OUTPUT_SIZE_ULC);
+
+ pre_write(pre, BF_PRE_PREFETCH_ENGINE_PITCH_INPUT_Y_PITCH(input_y_pitch) |
+ BF_PRE_PREFETCH_ENGINE_PITCH_INPUT_UV_PITCH(input_uv_pitch),
+ HW_PRE_PREFETCH_ENGINE_PITCH);
+
+ pre_write(pre, BF_PRE_PREFETCH_ENGINE_INTERLACE_OFFSET_INTERLACE_OFFSET(interlace_offset), HW_PRE_PREFETCH_ENGINE_INTERLACE_OFFSET);
+
+ pre_write(pre, prefetch_ctrl, HW_PRE_PREFETCH_ENGINE_CTRL);
+ spin_unlock_irqrestore(&pre->lock, lock_flags);
+
+ return 0;
+}
+
+static int ipu_pre_store(unsigned int id,
+ bool store_en,
+ unsigned int write_burst,
+ unsigned int output_bpp,
+ /* this means the output
+ * width by prefetch
+ */
+ unsigned int input_width,
+ unsigned int input_height,
+ unsigned int out_pitch,
+ unsigned int output_addr)
+{
+ struct ipu_pre_data *pre = get_pre(id);
+ unsigned int store_ctrl = 0;
+ unsigned long lock_flags;
+
+ if (!pre)
+ return -EINVAL;
+
+ spin_lock_irqsave(&pre->lock, lock_flags);
+ store_ctrl |= BF_PRE_STORE_ENGINE_CTRL_STORE_EN(store_en ? 1 : 0);
+
+ if (store_en) {
+ switch (write_burst) {
+ case 0x0:
+ store_ctrl |= BF_PRE_STORE_ENGINE_CTRL_WR_NUM_BYTES(0x0);
+ break;
+ case 0x1:
+ store_ctrl |= BF_PRE_STORE_ENGINE_CTRL_WR_NUM_BYTES(0x1);
+ break;
+ case 0x2:
+ store_ctrl |= BF_PRE_STORE_ENGINE_CTRL_WR_NUM_BYTES(0x2);
+ break;
+ case 0x3:
+ store_ctrl |= BF_PRE_STORE_ENGINE_CTRL_WR_NUM_BYTES(0x3);
+ break;
+ case 0x4:
+ store_ctrl |= BF_PRE_STORE_ENGINE_CTRL_WR_NUM_BYTES(0x4);
+ break;
+ default:
+ spin_unlock_irqrestore(&pre->lock, lock_flags);
+ dev_err(pre->dev, "invalid write burst value for store engine\n");
+ return -EINVAL;
+ }
+
+ switch (output_bpp) {
+ case 8:
+ store_ctrl |= BF_PRE_STORE_ENGINE_CTRL_OUTPUT_ACTIVE_BPP(0x0);
+ break;
+ case 16:
+ store_ctrl |= BF_PRE_STORE_ENGINE_CTRL_OUTPUT_ACTIVE_BPP(0x1);
+ break;
+ case 32:
+ store_ctrl |= BF_PRE_STORE_ENGINE_CTRL_OUTPUT_ACTIVE_BPP(0x2);
+ break;
+ case 64:
+ store_ctrl |= BF_PRE_STORE_ENGINE_CTRL_OUTPUT_ACTIVE_BPP(0x3);
+ break;
+ default:
+ spin_unlock_irqrestore(&pre->lock, lock_flags);
+ dev_err(pre->dev, "invalid ouput bpp for store engine\n");
+ return -EINVAL;
+ }
+
+ pre_write(pre, BF_PRE_STORE_ENGINE_SIZE_INPUT_TOTAL_WIDTH(input_width) |
+ BF_PRE_STORE_ENGINE_SIZE_INPUT_TOTAL_HEIGHT(input_height),
+ HW_PRE_STORE_ENGINE_SIZE);
+
+ pre_write(pre, BF_PRE_STORE_ENGINE_PITCH_OUT_PITCH(out_pitch),
+ HW_PRE_STORE_ENGINE_PITCH);
+
+ pre_write(pre, BF_PRE_STORE_ENGINE_ADDR_OUT_BASE_ADDR(output_addr),
+ HW_PRE_STORE_ENGINE_ADDR);
+ }
+
+ pre_write(pre, store_ctrl, HW_PRE_STORE_ENGINE_CTRL);
+ spin_unlock_irqrestore(&pre->lock, lock_flags);
+
+ return 0;
+}
+/* End */
+
+static irqreturn_t ipu_pre_irq_handle(int irq, void *dev_id)
+{
+ struct ipu_pre_data *pre = dev_id;
+ unsigned int irq_stat, axi_id = 0;
+
+ spin_lock(&pre->lock);
+ irq_stat = pre_read(pre, HW_PRE_IRQ);
+
+ if (irq_stat & BM_PRE_IRQ_HANDSHAKE_ABORT_IRQ) {
+ dev_warn(pre->dev, "handshake abort\n");
+ pre_write(pre, BM_PRE_IRQ_HANDSHAKE_ABORT_IRQ, HW_PRE_IRQ_CLR);
+ }
+
+ if (irq_stat & BM_PRE_IRQ_TPR_RD_NUM_BYTES_OVFL_IRQ) {
+ dev_warn(pre->dev, "tpr read num bytes overflow\n");
+ pre_write(pre, BM_PRE_IRQ_TPR_RD_NUM_BYTES_OVFL_IRQ,
+ HW_PRE_IRQ_CLR);
+ }
+
+ if (irq_stat & BM_PRE_IRQ_HANDSHAKE_ERROR_IRQ) {
+ dev_warn(pre->dev, "handshake error\n");
+ pre_write(pre, BM_PRE_IRQ_HANDSHAKE_ERROR_IRQ, HW_PRE_IRQ_CLR);
+ }
+
+ axi_id = (irq_stat & BM_PRE_IRQ_AXI_ERROR_ID) >>
+ BP_PRE_IRQ_AXI_ERROR_ID;
+ if (irq_stat & BM_PRE_IRQ_AXI_WRITE_ERROR) {
+ dev_warn(pre->dev, "AXI%d write error\n", axi_id);
+ pre_write(pre, BM_PRE_IRQ_AXI_WRITE_ERROR, HW_PRE_IRQ_CLR);
+ }
+
+ if (irq_stat & BM_PRE_IRQ_AXI_READ_ERROR) {
+ dev_warn(pre->dev, "AXI%d read error\n", axi_id);
+ pre_write(pre, BM_PRE_IRQ_AXI_READ_ERROR, HW_PRE_IRQ_CLR);
+ }
+ spin_unlock(&pre->lock);
+
+ return IRQ_HANDLED;
+}
+
+static void ipu_pre_out_of_reset(unsigned int id)
+{
+ struct ipu_pre_data *pre = get_pre(id);
+ unsigned long lock_flags;
+
+ if (!pre)
+ return;
+
+ spin_lock_irqsave(&pre->lock, lock_flags);
+ pre_write(pre, BF_PRE_CTRL_SFTRST(1) | BF_PRE_CTRL_CLKGATE(1),
+ HW_PRE_CTRL_CLR);
+ spin_unlock_irqrestore(&pre->lock, lock_flags);
+}
+
+int ipu_pre_config(int id, struct ipu_pre_context *config)
+{
+ int ret = 0;
+ struct ipu_pre_data *pre = get_pre(id);
+
+ if (!config || !pre)
+ return -EINVAL;
+
+ config->store_addr = pre->double_buffer_paddr;
+
+ if (!pre->enabled)
+ clk_prepare_enable(pre->clk);
+
+ ipu_pre_out_of_reset(id);
+
+ ret = ipu_pre_plane_buf_off_set(id, config->sec_buf_off,
+ config->trd_buf_off);
+ if (ret < 0)
+ goto out;
+
+ ret = ipu_pre_tpr_set(id, config->tile_fmt);
+ if (ret < 0)
+ goto out;
+
+ ret = ipu_pre_buf_set(id, config->cur_buf, config->next_buf);
+ if (ret < 0)
+ goto out;
+
+ ret = ipu_pre_set_shift(id, config->prefetch_shift_offset,
+ config->prefetch_shift_width);
+ if (ret < 0)
+ goto out;
+
+ ret = ipu_pre_prefetch(id, config->read_burst, config->prefetch_input_bpp,
+ config->prefetch_input_pixel_fmt, config->shift_bypass,
+ config->field_inverse, config->tpr_coor_offset_en,
+ config->prefetch_output_size, config->prefetch_input_width,
+ config->prefetch_input_height,
+ config->prefetch_input_active_width,
+ config->interlaced,
+ config->interlace_offset);
+ if (ret < 0)
+ goto out;
+
+ ret = ipu_pre_store(id, config->store_en,
+ config->write_burst, config->store_output_bpp,
+ config->prefetch_output_size.width, config->prefetch_output_size.height,
+ config->store_pitch,
+ config->store_addr);
+ if (ret < 0)
+ goto out;
+
+ ipu_pre_irq_mask(pre, BM_PRE_IRQ_HANDSHAKE_ABORT_IRQ |
+ BM_PRE_IRQ_TPR_RD_NUM_BYTES_OVFL_IRQ |
+ BM_PRE_IRQ_HANDSHAKE_ERROR_IRQ, false);
+out:
+ if (!pre->enabled)
+ clk_disable_unprepare(pre->clk);
+
+ return ret;
+}
+EXPORT_SYMBOL(ipu_pre_config);
+
+int ipu_pre_enable(int id)
+{
+ int ret = 0;
+ struct ipu_pre_data *pre = get_pre(id);
+ unsigned long lock_flags;
+
+ if (!pre)
+ return -EINVAL;
+
+ if (pre->enabled)
+ return 0;
+
+ clk_prepare_enable(pre->clk);
+
+ /* start the pre engine */
+ spin_lock_irqsave(&pre->lock, lock_flags);
+ pre_write(pre, BF_PRE_CTRL_ENABLE(1), HW_PRE_CTRL_SET);
+ spin_unlock_irqrestore(&pre->lock, lock_flags);
+
+ pre->enabled = true;
+
+ return ret;
+}
+EXPORT_SYMBOL(ipu_pre_enable);
+
+int ipu_pre_sdw_update(int id)
+{
+ int ret = 0;
+ struct ipu_pre_data *pre = get_pre(id);
+ unsigned long lock_flags;
+
+ if (!pre)
+ return -EINVAL;
+
+ if (!pre->enabled)
+ clk_prepare_enable(pre->clk);
+
+ /* start the pre engine */
+ spin_lock_irqsave(&pre->lock, lock_flags);
+ pre_write(pre, BF_PRE_CTRL_SDW_UPDATE(1), HW_PRE_CTRL_SET);
+ spin_unlock_irqrestore(&pre->lock, lock_flags);
+
+ if (!pre->enabled)
+ clk_disable_unprepare(pre->clk);
+
+ return ret;
+}
+EXPORT_SYMBOL(ipu_pre_sdw_update);
+
+void ipu_pre_disable(int id)
+{
+ struct ipu_pre_data *pre = get_pre(id);
+ unsigned long lock_flags;
+
+ if (!pre)
+ return;
+
+ if (!pre->enabled)
+ return;
+
+ /* stop the pre engine */
+ spin_lock_irqsave(&pre->lock, lock_flags);
+ pre_write(pre, BF_PRE_CTRL_ENABLE(1), HW_PRE_CTRL_CLR);
+ pre_write(pre, BF_PRE_CTRL_SDW_UPDATE(1), HW_PRE_CTRL_SET);
+ pre_write(pre, BF_PRE_CTRL_SFTRST(1), HW_PRE_CTRL_SET);
+ spin_unlock_irqrestore(&pre->lock, lock_flags);
+
+ clk_disable_unprepare(pre->clk);
+
+ pre->enabled = false;
+}
+EXPORT_SYMBOL(ipu_pre_disable);
+
+int ipu_pre_set_fb_buffer(int id, bool resolve,
+ unsigned long fb_paddr,
+ unsigned int y_res,
+ unsigned int x_crop,
+ unsigned int y_crop,
+ unsigned int sec_buf_off,
+ unsigned int trd_buf_off)
+{
+ struct ipu_pre_data *pre = get_pre(id);
+ unsigned int store_stat, store_block_y;
+ unsigned long lock_flags;
+ bool update = true;
+
+ if (!pre)
+ return -EINVAL;
+
+ spin_lock_irqsave(&pre->lock, lock_flags);
+ pre_write(pre, fb_paddr, HW_PRE_NEXT_BUF);
+ pre_write(pre, sec_buf_off, HW_PRE_U_BUF_OFFSET);
+ pre_write(pre, trd_buf_off, HW_PRE_V_BUF_OFFSET);
+ pre_write(pre, BF_PRE_PREFETCH_ENGINE_OUTPUT_SIZE_ULC_OUTPUT_SIZE_ULC_X(x_crop) |
+ BF_PRE_PREFETCH_ENGINE_OUTPUT_SIZE_ULC_OUTPUT_SIZE_ULC_Y(y_crop),
+ HW_PRE_PREFETCH_ENGINE_OUTPUT_SIZE_ULC);
+
+ /*
+ * Update shadow only when store engine runs out of the problematic
+ * window to workaround the SoC design bug recorded by errata ERR009624.
+ */
+ if (y_res > IPU_PRE_SMALL_LINE) {
+ unsigned long timeout = jiffies + msecs_to_jiffies(20);
+
+ do {
+ if (time_after(jiffies, timeout)) {
+ update = false;
+ dev_warn(pre->dev, "timeout waiting for PRE "
+ "to run out of problematic window for "
+ "shadow update\n");
+ break;
+ }
+
+ store_stat = pre_read(pre, HW_PRE_STORE_ENGINE_STATUS);
+ store_block_y = (store_stat &
+ BM_PRE_STORE_ENGINE_STATUS_STORE_BLOCK_Y) >>
+ BP_PRE_STORE_ENGINE_STATUS_STORE_BLOCK_Y;
+ } while (store_block_y >=
+ (resolve ? DIV_ROUND_UP(y_res, 4) - 1 : y_res - 2) ||
+ store_block_y == 0);
+ }
+
+ if (update)
+ pre_write(pre, BF_PRE_CTRL_SDW_UPDATE(1), HW_PRE_CTRL_SET);
+ spin_unlock_irqrestore(&pre->lock, lock_flags);
+
+ return 0;
+}
+EXPORT_SYMBOL(ipu_pre_set_fb_buffer);
+
+static int ipu_pre_probe(struct platform_device *pdev)
+{
+ struct device_node *np = pdev->dev.of_node;
+ struct ipu_pre_data *pre;
+ struct resource *res;
+ unsigned long lock_flags;
+ int id, irq, err;
+
+ pre = devm_kzalloc(&pdev->dev, sizeof(*pre), GFP_KERNEL);
+ if (!pre)
+ return -ENOMEM;
+ pre->dev = &pdev->dev;
+
+ id = of_alias_get_id(np, "pre");
+ if (id < 0) {
+ dev_err(&pdev->dev, "failed to get PRE id\n");
+ return id;
+ }
+ pre->id = id;
+
+ mutex_init(&pre->mutex);
+ spin_lock_init(&pre->lock);
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ pre->base = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(pre->base))
+ return PTR_ERR(pre->base);
+
+ pre->clk = devm_clk_get(&pdev->dev, NULL);
+ if (IS_ERR(pre->clk)) {
+ dev_err(&pdev->dev, "failed to get the pre clk\n");
+ return PTR_ERR(pre->clk);
+ }
+
+ irq = platform_get_irq(pdev, 0);
+ err = devm_request_irq(&pdev->dev, irq, ipu_pre_irq_handle,
+ IRQF_TRIGGER_RISING, pdev->name, pre);
+ if (err) {
+ dev_err(&pdev->dev, "failed to request pre irq\n");
+ return err;
+ }
+
+ pre->iram_pool = of_gen_pool_get(pdev->dev.of_node, "ocram", 0);
+ if (!pre->iram_pool) {
+ dev_err(&pdev->dev, "no iram exist for pre\n");
+ return -ENOMEM;
+ }
+
+ spin_lock_irqsave(&pre_list_lock, lock_flags);
+ list_add_tail(&pre->list, &pre_list);
+ spin_unlock_irqrestore(&pre_list_lock, lock_flags);
+
+ ipu_pre_alloc_double_buffer(pre->id, IPU_PRE_MAX_WIDTH * 8 * IPU_PRE_MAX_BPP);
+
+ /* PRE GATE ON */
+ clk_prepare_enable(pre->clk);
+ pre_write(pre, BF_PRE_CTRL_SFTRST(1) | BF_PRE_CTRL_CLKGATE(1),
+ HW_PRE_CTRL_CLR);
+ pre_write(pre, 0xf, HW_PRE_IRQ_MASK);
+ clk_disable_unprepare(pre->clk);
+
+ platform_set_drvdata(pdev, pre);
+
+ dev_info(&pdev->dev, "driver probed\n");
+
+ return 0;
+}
+
+static int ipu_pre_remove(struct platform_device *pdev)
+{
+ struct ipu_pre_data *pre = platform_get_drvdata(pdev);
+ unsigned long lock_flags;
+
+ if (pre->iram_pool && pre->double_buffer_base) {
+ gen_pool_free(pre->iram_pool,
+ pre->double_buffer_base,
+ pre->double_buffer_size);
+ }
+
+ spin_lock_irqsave(&pre_list_lock, lock_flags);
+ list_del(&pre->list);
+ spin_unlock_irqrestore(&pre_list_lock, lock_flags);
+
+ return 0;
+}
+
+static const struct of_device_id imx_ipu_pre_dt_ids[] = {
+ { .compatible = "fsl,imx6q-pre", },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, imx_ipu_pre_dt_ids);
+
+static struct platform_driver ipu_pre_driver = {
+ .driver = {
+ .name = "imx-pre",
+ .of_match_table = of_match_ptr(imx_ipu_pre_dt_ids),
+ },
+ .probe = ipu_pre_probe,
+ .remove = ipu_pre_remove,
+};
+
+static int __init ipu_pre_init(void)
+{
+ return platform_driver_register(&ipu_pre_driver);
+}
+subsys_initcall(ipu_pre_init);
+
+static void __exit ipu_pre_exit(void)
+{
+ platform_driver_unregister(&ipu_pre_driver);
+}
+module_exit(ipu_pre_exit);
+
+MODULE_DESCRIPTION("i.MX PRE driver");
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_LICENSE("GPL");
diff --git a/drivers/mxc/ipu3/prg-regs.h b/drivers/mxc/ipu3/prg-regs.h
new file mode 100644
index 000000000000..bca0e560a6f9
--- /dev/null
+++ b/drivers/mxc/ipu3/prg-regs.h
@@ -0,0 +1,70 @@
+/*
+ * Freescale IPU PRG Register Definitions
+ *
+ * Copyright 2014-2015 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+#include <linux/bitops.h>
+
+#ifndef __IPU_PRG_H__
+#define __IPU_PRG_H__
+
+#define IPU_PR_CTRL 0x00
+#define IPU_PR_STATUS 0x04
+#define IPU_PR_QOS 0x08
+#define IPU_PR_REG_UPDATE 0x0c
+#define IPU_PR_STRIDE(ch) (0x10 + (ch) * 4)
+#define IPU_PR_CROP_LINE 0x1c
+#define IPU_PR_ADDR_THD 0x20
+#define IPU_PR_CH_BADDR(ch) (0x24 + (ch) * 4)
+#define IPU_PR_CH_OFFSET(ch) (0x30 + (ch) * 4)
+#define IPU_PR_CH_ILO(ch) (0x3c + (ch) * 4)
+#define IPU_PR_CH_HEIGHT(ch) (0x48 + (ch) * 4)
+
+#define IPU_PR_CTRL_CH_BYPASS(ch) (0x1 << (ch))
+#define IPU_PR_CTRL_SOFT_CH_ARID(ch, n) ((n) << ((ch) * 2 + 8))
+#define IPU_PR_CTRL_SOFT_CH_ARID_MASK(ch) (0x3 << ((ch) * 2 + 8))
+#define IPU_PR_CTRL_CH_SO(ch, interlace) ((interlace) << ((ch) + 16))
+#define IPU_PR_CTRL_CH_SO_MASK(ch) (0x1 << ((ch) + 16))
+#define IPU_PR_CTRL_CH_VFLIP(ch, vflip) ((vflip) << ((ch) + 19))
+#define IPU_PR_CTRL_CH_VFLIP_MASK(ch) (0x1 << ((ch) + 19))
+#define IPU_PR_CTRL_CH_BLOCK_MODE(ch, mode) ((mode) << ((ch) + 22))
+#define IPU_PR_CTRL_CH_BLOCK_MODE_MASK(ch) (0x1 << ((ch) + 22))
+#define IPU_PR_CTRL_CH_CNT_LOAD_EN(ch) (0x1 << ((ch) + 25))
+#define IPU_PR_CTRL_CH_CNT_LOAD_EN_MASK (0x7 << 25)
+#define IPU_PR_CTRL_SOFTRST BIT(30)
+#define IPU_PR_CTRL_SHADOW_EN BIT(31)
+
+#define IPU_PR_STATUS_BUF_RDY(ch, buf) (1 << ((ch) * 2 + (buf)))
+
+#define IPU_PR_QOS_PRI(id, qos) ((qos) << ((id) * 4))
+#define IPU_PR_QOS_MASK(id) (0xf << ((id) * 4))
+
+#define IPU_PR_REG_UPDATE_EN BIT(0)
+
+#define IPU_PR_STRIDE_MASK 0x3fff
+
+#define IPU_PR_CROP_LINE_NUM(ch, n) ((n) << ((ch) * 4))
+#define IPU_PR_CROP_LINE_MASK(ch) (0xf << ((ch) * 4))
+
+#define IPU_PR_ADDR_THD_MASK 0xffffffff
+
+#define IPU_PR_CH_BADDR_MASK 0xffffffff
+
+#define IPU_PR_CH_OFFSET_MASK 0xffffffff
+
+#define IPU_PR_CH_ILO_MASK 0x007fffff
+#define IPU_PR_CH_ILO_NUM(ilo) ((ilo) & IPU_PR_CH_ILO_MASK)
+
+#define IPU_PR_CH_HEIGHT_MASK 0x00000fff
+#define IPU_PR_CH_HEIGHT_NUM(fh) (((fh) - 1) & IPU_PR_CH_HEIGHT_MASK)
+#define IPU_PR_CH_IPU_HEIGHT_MASK 0x0fff0000
+#define IPU_PR_CH_IPU_HEIGHT_NUM(fh) ((((fh) - 1) << 16) & IPU_PR_CH_IPU_HEIGHT_MASK)
+
+#endif /* __IPU_PRG_H__ */
diff --git a/drivers/mxc/ipu3/prg.c b/drivers/mxc/ipu3/prg.c
new file mode 100644
index 000000000000..45363a843392
--- /dev/null
+++ b/drivers/mxc/ipu3/prg.c
@@ -0,0 +1,506 @@
+/*
+ * Copyright (C) 2014-2015 Freescale Semiconductor, Inc.
+ *
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/ipu-v3-prg.h>
+#include <linux/kernel.h>
+#include <linux/mfd/syscon.h>
+#include <linux/mfd/syscon/imx6q-iomuxc-gpr.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+#include "prg-regs.h"
+
+#define PRG_CHAN_NUM 3
+
+struct prg_chan {
+ unsigned int pre_num;
+ struct mutex mutex; /* for in_use */
+ bool in_use;
+};
+
+struct ipu_prg_data {
+ unsigned int id;
+ void __iomem *base;
+ unsigned long memory;
+ struct clk *axi_clk;
+ struct clk *apb_clk;
+ struct list_head list;
+ struct device *dev;
+ struct prg_chan chan[PRG_CHAN_NUM];
+ struct regmap *regmap;
+ struct regmap_field *pre_prg_sel[2];
+ spinlock_t lock;
+};
+
+static LIST_HEAD(prg_list);
+static DEFINE_MUTEX(prg_lock);
+
+static inline void prg_write(struct ipu_prg_data *prg,
+ u32 value, unsigned int offset)
+{
+ writel(value, prg->base + offset);
+}
+
+static inline u32 prg_read(struct ipu_prg_data *prg, unsigned offset)
+{
+ return readl(prg->base + offset);
+}
+
+static struct ipu_prg_data *get_prg(unsigned int ipu_id)
+{
+ struct ipu_prg_data *prg;
+
+ mutex_lock(&prg_lock);
+ list_for_each_entry(prg, &prg_list, list) {
+ if (prg->id == ipu_id) {
+ mutex_unlock(&prg_lock);
+ return prg;
+ }
+ }
+ mutex_unlock(&prg_lock);
+
+ return NULL;
+}
+
+static int assign_prg_chan(struct ipu_prg_data *prg, unsigned int pre_num,
+ ipu_channel_t ipu_ch)
+{
+ int prg_ch;
+
+ if (!prg)
+ return -EINVAL;
+
+ switch (ipu_ch) {
+ case MEM_BG_SYNC:
+ prg_ch = 0;
+ break;
+ case MEM_FG_SYNC:
+ prg_ch = 1;
+ break;
+ case MEM_DC_SYNC:
+ prg_ch = 2;
+ break;
+ default:
+ dev_err(prg->dev, "wrong ipu channel type\n");
+ return -EINVAL;
+ }
+
+ mutex_lock(&prg->chan[prg_ch].mutex);
+ if (!prg->chan[prg_ch].in_use) {
+ prg->chan[prg_ch].in_use = true;
+ prg->chan[prg_ch].pre_num = pre_num;
+
+ if (prg_ch != 0) {
+ unsigned int pmux, psel; /* primary */
+ unsigned int smux, ssel; /* secondary */
+ struct regmap_field *pfield, *sfield;
+
+ psel = pre_num - 1;
+ ssel = psel ? 0 : 1;
+
+ pfield = prg->pre_prg_sel[psel];
+ sfield = prg->pre_prg_sel[ssel];
+ pmux = (prg_ch - 1) + (prg->id << 1);
+
+ mutex_lock(&prg_lock);
+ regmap_field_write(pfield, pmux);
+
+ /*
+ * PRE1 and PRE2 cannot bind with a same channel of
+ * one PRG even if one of the two PREs is disabled.
+ */
+ regmap_field_read(sfield, &smux);
+ if (smux == pmux) {
+ smux = pmux ^ 0x1;
+ regmap_field_write(sfield, smux);
+ }
+ mutex_unlock(&prg_lock);
+ }
+ mutex_unlock(&prg->chan[prg_ch].mutex);
+ dev_dbg(prg->dev, "bind prg%u ch%d with pre%u\n",
+ prg->id, prg_ch, pre_num);
+ return prg_ch;
+ }
+ mutex_unlock(&prg->chan[prg_ch].mutex);
+ return -EBUSY;
+}
+
+static inline int get_prg_chan(struct ipu_prg_data *prg, unsigned int pre_num)
+{
+ int i;
+
+ if (!prg)
+ return -EINVAL;
+
+ for (i = 0; i < PRG_CHAN_NUM; i++) {
+ mutex_lock(&prg->chan[i].mutex);
+ if (prg->chan[i].in_use &&
+ prg->chan[i].pre_num == pre_num) {
+ mutex_unlock(&prg->chan[i].mutex);
+ return i;
+ }
+ mutex_unlock(&prg->chan[i].mutex);
+ }
+ return -ENOENT;
+}
+
+int ipu_prg_config(struct ipu_prg_config *config)
+{
+ struct ipu_prg_data *prg = get_prg(config->id);
+ struct ipu_soc *ipu = ipu_get_soc(config->id);
+ int prg_ch, axi_id;
+ u32 reg;
+
+ if (!prg || config->crop_line > 3 || !ipu)
+ return -EINVAL;
+
+ if (config->height & ~IPU_PR_CH_HEIGHT_MASK)
+ return -EINVAL;
+
+ prg_ch = assign_prg_chan(prg, config->pre_num, config->ipu_ch);
+ if (prg_ch < 0)
+ return prg_ch;
+
+ axi_id = ipu_ch_param_get_axi_id(ipu, config->ipu_ch, IPU_INPUT_BUFFER);
+
+ clk_prepare_enable(prg->axi_clk);
+ clk_prepare_enable(prg->apb_clk);
+
+ spin_lock(&prg->lock);
+ /* clear all load enable to impact other channels */
+ reg = prg_read(prg, IPU_PR_CTRL);
+ reg &= ~IPU_PR_CTRL_CH_CNT_LOAD_EN_MASK;
+ prg_write(prg, reg, IPU_PR_CTRL);
+
+ /* counter load enable */
+ reg = prg_read(prg, IPU_PR_CTRL);
+ reg |= IPU_PR_CTRL_CH_CNT_LOAD_EN(prg_ch);
+ prg_write(prg, reg, IPU_PR_CTRL);
+
+ /* AXI ID */
+ reg = prg_read(prg, IPU_PR_CTRL);
+ reg &= ~IPU_PR_CTRL_SOFT_CH_ARID_MASK(prg_ch);
+ reg |= IPU_PR_CTRL_SOFT_CH_ARID(prg_ch, axi_id);
+ prg_write(prg, reg, IPU_PR_CTRL);
+
+ /* so */
+ reg = prg_read(prg, IPU_PR_CTRL);
+ reg &= ~IPU_PR_CTRL_CH_SO_MASK(prg_ch);
+ reg |= IPU_PR_CTRL_CH_SO(prg_ch, config->so);
+ prg_write(prg, reg, IPU_PR_CTRL);
+
+ /* vflip */
+ reg = prg_read(prg, IPU_PR_CTRL);
+ reg &= ~IPU_PR_CTRL_CH_VFLIP_MASK(prg_ch);
+ reg |= IPU_PR_CTRL_CH_VFLIP(prg_ch, config->vflip);
+ prg_write(prg, reg, IPU_PR_CTRL);
+
+ /* block mode */
+ reg = prg_read(prg, IPU_PR_CTRL);
+ reg &= ~IPU_PR_CTRL_CH_BLOCK_MODE_MASK(prg_ch);
+ reg |= IPU_PR_CTRL_CH_BLOCK_MODE(prg_ch, config->block_mode);
+ prg_write(prg, reg, IPU_PR_CTRL);
+
+ /* disable bypass */
+ reg = prg_read(prg, IPU_PR_CTRL);
+ reg &= ~IPU_PR_CTRL_CH_BYPASS(prg_ch);
+ prg_write(prg, reg, IPU_PR_CTRL);
+
+ /* stride */
+ reg = prg_read(prg, IPU_PR_STRIDE(prg_ch));
+ reg &= ~IPU_PR_STRIDE_MASK;
+ reg |= config->stride - 1;
+ prg_write(prg, reg, IPU_PR_STRIDE(prg_ch));
+
+ /* ilo */
+ reg = prg_read(prg, IPU_PR_CH_ILO(prg_ch));
+ reg &= ~IPU_PR_CH_ILO_MASK;
+ reg |= IPU_PR_CH_ILO_NUM(config->ilo);
+ prg_write(prg, reg, IPU_PR_CH_ILO(prg_ch));
+
+ /* height */
+ reg = prg_read(prg, IPU_PR_CH_HEIGHT(prg_ch));
+ reg &= ~IPU_PR_CH_HEIGHT_MASK;
+ reg |= IPU_PR_CH_HEIGHT_NUM(config->height);
+ prg_write(prg, reg, IPU_PR_CH_HEIGHT(prg_ch));
+
+ /* ipu height */
+ reg = prg_read(prg, IPU_PR_CH_HEIGHT(prg_ch));
+ reg &= ~IPU_PR_CH_IPU_HEIGHT_MASK;
+ reg |= IPU_PR_CH_IPU_HEIGHT_NUM(config->ipu_height);
+ prg_write(prg, reg, IPU_PR_CH_HEIGHT(prg_ch));
+
+ /* crop */
+ reg = prg_read(prg, IPU_PR_CROP_LINE);
+ reg &= ~IPU_PR_CROP_LINE_MASK(prg_ch);
+ reg |= IPU_PR_CROP_LINE_NUM(prg_ch, config->crop_line);
+ prg_write(prg, reg, IPU_PR_CROP_LINE);
+
+ /* buffer address */
+ reg = prg_read(prg, IPU_PR_CH_BADDR(prg_ch));
+ reg &= ~IPU_PR_CH_BADDR_MASK;
+ reg |= config->baddr;
+ prg_write(prg, reg, IPU_PR_CH_BADDR(prg_ch));
+
+ /* offset */
+ reg = prg_read(prg, IPU_PR_CH_OFFSET(prg_ch));
+ reg &= ~IPU_PR_CH_OFFSET_MASK;
+ reg |= config->offset;
+ prg_write(prg, reg, IPU_PR_CH_OFFSET(prg_ch));
+
+ /* threshold */
+ reg = prg_read(prg, IPU_PR_ADDR_THD);
+ reg &= ~IPU_PR_ADDR_THD_MASK;
+ reg |= prg->memory;
+ prg_write(prg, reg, IPU_PR_ADDR_THD);
+
+ /* shadow enable */
+ reg = prg_read(prg, IPU_PR_CTRL);
+ reg |= IPU_PR_CTRL_SHADOW_EN;
+ prg_write(prg, reg, IPU_PR_CTRL);
+
+ /* register update */
+ reg = prg_read(prg, IPU_PR_REG_UPDATE);
+ reg |= IPU_PR_REG_UPDATE_EN;
+ prg_write(prg, reg, IPU_PR_REG_UPDATE);
+ spin_unlock(&prg->lock);
+
+ clk_disable_unprepare(prg->apb_clk);
+
+ return 0;
+}
+EXPORT_SYMBOL(ipu_prg_config);
+
+int ipu_prg_disable(unsigned int ipu_id, unsigned int pre_num)
+{
+ struct ipu_prg_data *prg = get_prg(ipu_id);
+ int prg_ch;
+ u32 reg;
+
+ if (!prg)
+ return -EINVAL;
+
+ prg_ch = get_prg_chan(prg, pre_num);
+ if (prg_ch < 0)
+ return prg_ch;
+
+ clk_prepare_enable(prg->apb_clk);
+
+ spin_lock(&prg->lock);
+ /* clear all load enable to impact other channels */
+ reg = prg_read(prg, IPU_PR_CTRL);
+ reg &= ~IPU_PR_CTRL_CH_CNT_LOAD_EN_MASK;
+ prg_write(prg, reg, IPU_PR_CTRL);
+
+ /* counter load enable */
+ reg = prg_read(prg, IPU_PR_CTRL);
+ reg |= IPU_PR_CTRL_CH_CNT_LOAD_EN(prg_ch);
+ prg_write(prg, reg, IPU_PR_CTRL);
+
+ /* enable bypass */
+ reg = prg_read(prg, IPU_PR_CTRL);
+ reg |= IPU_PR_CTRL_CH_BYPASS(prg_ch);
+ prg_write(prg, reg, IPU_PR_CTRL);
+
+ /* shadow enable */
+ reg = prg_read(prg, IPU_PR_CTRL);
+ reg |= IPU_PR_CTRL_SHADOW_EN;
+ prg_write(prg, reg, IPU_PR_CTRL);
+
+ /* register update */
+ reg = prg_read(prg, IPU_PR_REG_UPDATE);
+ reg |= IPU_PR_REG_UPDATE_EN;
+ prg_write(prg, reg, IPU_PR_REG_UPDATE);
+ spin_unlock(&prg->lock);
+
+ clk_disable_unprepare(prg->apb_clk);
+ clk_disable_unprepare(prg->axi_clk);
+
+ mutex_lock(&prg->chan[prg_ch].mutex);
+ prg->chan[prg_ch].in_use = false;
+ mutex_unlock(&prg->chan[prg_ch].mutex);
+
+ return 0;
+}
+EXPORT_SYMBOL(ipu_prg_disable);
+
+int ipu_prg_wait_buf_ready(unsigned int ipu_id, unsigned int pre_num,
+ unsigned int hsk_line_num,
+ int pre_store_out_height)
+{
+ struct ipu_prg_data *prg = get_prg(ipu_id);
+ int prg_ch, timeout = 1000;
+ u32 reg;
+
+ if (!prg)
+ return -EINVAL;
+
+ prg_ch = get_prg_chan(prg, pre_num);
+ if (prg_ch < 0)
+ return prg_ch;
+
+ clk_prepare_enable(prg->apb_clk);
+
+ spin_lock(&prg->lock);
+ if (pre_store_out_height <= (4 << hsk_line_num)) {
+ do {
+ reg = prg_read(prg, IPU_PR_STATUS);
+ udelay(1000);
+ timeout--;
+ } while (!(reg & IPU_PR_STATUS_BUF_RDY(prg_ch, 0)) && timeout);
+ } else {
+ do {
+ reg = prg_read(prg, IPU_PR_STATUS);
+ udelay(1000);
+ timeout--;
+ } while ((!(reg & IPU_PR_STATUS_BUF_RDY(prg_ch, 0)) ||
+ !(reg & IPU_PR_STATUS_BUF_RDY(prg_ch, 1))) && timeout);
+ }
+ spin_unlock(&prg->lock);
+
+ clk_disable_unprepare(prg->apb_clk);
+
+ if (!timeout)
+ dev_err(prg->dev, "wait for buffer ready timeout\n");
+
+ return 0;
+}
+EXPORT_SYMBOL(ipu_prg_wait_buf_ready);
+
+static int ipu_prg_probe(struct platform_device *pdev)
+{
+ struct device_node *np = pdev->dev.of_node, *memory;
+ struct ipu_prg_data *prg;
+ struct resource *res;
+ struct reg_field reg_field0 = REG_FIELD(IOMUXC_GPR5,
+ IMX6Q_GPR5_PRE_PRG_SEL0_LSB,
+ IMX6Q_GPR5_PRE_PRG_SEL0_MSB);
+ struct reg_field reg_field1 = REG_FIELD(IOMUXC_GPR5,
+ IMX6Q_GPR5_PRE_PRG_SEL1_LSB,
+ IMX6Q_GPR5_PRE_PRG_SEL1_MSB);
+ int id, i;
+
+ prg = devm_kzalloc(&pdev->dev, sizeof(*prg), GFP_KERNEL);
+ if (!prg)
+ return -ENOMEM;
+ prg->dev = &pdev->dev;
+
+ for (i = 0; i < PRG_CHAN_NUM; i++)
+ mutex_init(&prg->chan[i].mutex);
+
+ spin_lock_init(&prg->lock);
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ prg->base = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(prg->base))
+ return PTR_ERR(prg->base);
+
+ prg->axi_clk = devm_clk_get(&pdev->dev, "axi");
+ if (IS_ERR(prg->axi_clk)) {
+ dev_err(&pdev->dev, "failed to get the axi clk\n");
+ return PTR_ERR(prg->axi_clk);
+ }
+
+ prg->apb_clk = devm_clk_get(&pdev->dev, "apb");
+ if (IS_ERR(prg->apb_clk)) {
+ dev_err(&pdev->dev, "failed to get the apb clk\n");
+ return PTR_ERR(prg->apb_clk);
+ }
+
+ prg->regmap = syscon_regmap_lookup_by_phandle(np, "gpr");
+ if (IS_ERR(prg->regmap)) {
+ dev_err(&pdev->dev, "failed to get regmap\n");
+ return PTR_ERR(prg->regmap);
+ }
+
+ prg->pre_prg_sel[0] = devm_regmap_field_alloc(&pdev->dev, prg->regmap,
+ reg_field0);
+ if (IS_ERR(prg->pre_prg_sel[0]))
+ return PTR_ERR(prg->pre_prg_sel[0]);
+
+ prg->pre_prg_sel[1] = devm_regmap_field_alloc(&pdev->dev, prg->regmap,
+ reg_field1);
+ if (IS_ERR(prg->pre_prg_sel[1]))
+ return PTR_ERR(prg->pre_prg_sel[1]);
+
+ memory = of_parse_phandle(np, "memory-region", 0);
+ if (!memory)
+ return -ENODEV;
+
+ prg->memory = of_translate_address(memory,
+ of_get_address(memory, 0, NULL, NULL));
+
+ id = of_alias_get_id(np, "prg");
+ if (id < 0) {
+ dev_err(&pdev->dev, "failed to get PRG id\n");
+ return id;
+ }
+ prg->id = id;
+
+ mutex_lock(&prg_lock);
+ list_add_tail(&prg->list, &prg_list);
+ mutex_unlock(&prg_lock);
+
+ platform_set_drvdata(pdev, prg);
+
+ dev_info(&pdev->dev, "driver probed\n");
+
+ return 0;
+}
+
+static int ipu_prg_remove(struct platform_device *pdev)
+{
+ struct ipu_prg_data *prg = platform_get_drvdata(pdev);
+
+ mutex_lock(&prg_lock);
+ list_del(&prg->list);
+ mutex_unlock(&prg_lock);
+
+ return 0;
+}
+
+static const struct of_device_id imx_ipu_prg_dt_ids[] = {
+ { .compatible = "fsl,imx6q-prg", },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, imx_ipu_prg_dt_ids);
+
+static struct platform_driver ipu_prg_driver = {
+ .driver = {
+ .name = "imx-prg",
+ .of_match_table = of_match_ptr(imx_ipu_prg_dt_ids),
+ },
+ .probe = ipu_prg_probe,
+ .remove = ipu_prg_remove,
+};
+
+static int __init ipu_prg_init(void)
+{
+ return platform_driver_register(&ipu_prg_driver);
+}
+subsys_initcall(ipu_prg_init);
+
+static void __exit ipu_prg_exit(void)
+{
+ platform_driver_unregister(&ipu_prg_driver);
+}
+module_exit(ipu_prg_exit);
+
+MODULE_DESCRIPTION("i.MX PRG driver");
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_LICENSE("GPL");
diff --git a/drivers/mxc/ipu3/vdoa.c b/drivers/mxc/ipu3/vdoa.c
new file mode 100644
index 000000000000..e0128d3b7816
--- /dev/null
+++ b/drivers/mxc/ipu3/vdoa.c
@@ -0,0 +1,537 @@
+/*
+ * Copyright (C) 2012-2015 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2018 NXP
+ *
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/ipu.h>
+#include <linux/genalloc.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+
+#include "vdoa.h"
+/* 6band(3field* double buffer) * (width*2) * bandline(8)
+ = 6x1024x2x8 = 96k or 72k(1.5byte) */
+#define MAX_VDOA_IRAM_SIZE (1024*96)
+#define VDOA_IRAM_SIZE (1024*72)
+
+#define VDOAC_BAND_HEIGHT_32LINES (32)
+#define VDOAC_BAND_HEIGHT_16LINES (16)
+#define VDOAC_BAND_HEIGHT_8LINES (8)
+#define VDOAC_THREE_FRAMES (0x1 << 2)
+#define VDOAC_SYNC_BAND_MODE (0x1 << 3)
+#define VDOAC_SCAN_ORDER_INTERLACED (0x1 << 4)
+#define VDOAC_PFS_YUYV (0x1 << 5)
+#define VDOAC_IPU_SEL_1 (0x1 << 6)
+#define VDOAFP_FH_MASK (0x1FFF)
+#define VDOAFP_FH_SHIFT (16)
+#define VDOAFP_FW_MASK (0x3FFF)
+#define VDOAFP_FW_SHIFT (0)
+#define VDOASL_VSLY_MASK (0x3FFF)
+#define VDOASL_VSLY_SHIFT (16)
+#define VDOASL_ISLY_MASK (0x7FFF)
+#define VDOASL_ISLY_SHIFT (0)
+#define VDOASRR_START_XFER (0x2)
+#define VDOASRR_SWRST (0x1)
+#define VDOAIEIST_TRANSFER_ERR (0x2)
+#define VDOAIEIST_TRANSFER_END (0x1)
+
+#define VDOAC (0x0) /* Control Register */
+#define VDOASRR (0x4) /* Start and Reset Register */
+#define VDOAIE (0x8) /* Interrupt Enable Register */
+#define VDOAIST (0xc) /* Interrupt Status Register */
+#define VDOAFP (0x10) /* Frame Parameters Register */
+#define VDOAIEBA00 (0x14) /* External Buffer n Frame m Address Register */
+#define VDOAIEBA01 (0x18) /* External Buffer n Frame m Address Register */
+#define VDOAIEBA02 (0x1c) /* External Buffer n Frame m Address Register */
+#define VDOAIEBA10 (0x20) /* External Buffer n Frame m Address Register */
+#define VDOAIEBA11 (0x24) /* External Buffer n Frame m Address Register */
+#define VDOAIEBA12 (0x28) /* External Buffer n Frame m Address Register */
+#define VDOASL (0x2c) /* IPU Stride Line Register */
+#define VDOAIUBO (0x30) /* IPU Chroma Buffer Offset Register */
+#define VDOAVEBA0 (0x34) /* External Buffer m Address Register */
+#define VDOAVEBA1 (0x38) /* External Buffer m Address Register */
+#define VDOAVEBA2 (0x3c) /* External Buffer m Address Register */
+#define VDOAVUBO (0x40) /* VPU Chroma Buffer Offset */
+#define VDOASR (0x44) /* Status Register */
+#define VDOATD (0x48) /* Test Debug Register */
+
+
+enum {
+ VDOA_INIT = 0x1,
+ VDOA_GET = 0x2,
+ VDOA_SETUP = 0x4,
+ VDOA_GET_OBUF = 0x8,
+ VDOA_START = 0x10,
+ VDOA_INIRQ = 0x20,
+ VDOA_STOP = 0x40,
+ VDOA_PUT = VDOA_INIT,
+};
+
+enum {
+ VDOA_NULL = 0,
+ VDOA_FRAME = 1,
+ VDOA_PREV_FIELD = 2,
+ VDOA_CURR_FIELD = 3,
+ VDOA_NEXT_FIELD = 4,
+};
+
+#define CHECK_STATE(expect, retcode) \
+do { \
+ if (!((expect) & vdoa->state)) { \
+ dev_err(vdoa->dev, "ERR: %s state:0x%x, expect:0x%x.\n",\
+ __func__, vdoa->state, (expect)); \
+ retcode; \
+ } \
+} while (0)
+
+#define CHECK_NULL_PTR(ptr) \
+do { \
+ pr_debug("vdoa_ptr:0x%p in %s state:0x%x.\n", \
+ vdoa, __func__, vdoa->state); \
+ if (NULL == (ptr)) { \
+ pr_err("ERR vdoa: %s state:0x%x null ptr.\n", \
+ __func__, vdoa->state); \
+ } \
+} while (0)
+
+struct vdoa_info {
+ int state;
+ struct device *dev;
+ struct clk *vdoa_clk;
+ void __iomem *reg_base;
+ struct gen_pool *iram_pool;
+ unsigned long iram_base;
+ unsigned long iram_paddr;
+ int irq;
+ int field;
+ struct completion comp;
+};
+
+static struct vdoa_info *g_vdoa;
+static unsigned long iram_size;
+static DEFINE_MUTEX(vdoa_lock);
+
+static inline void vdoa_read_register(struct vdoa_info *vdoa,
+ u32 reg, u32 *val)
+{
+ *val = ioread32(vdoa->reg_base + reg);
+ dev_dbg(vdoa->dev, "read_reg:0x%02x, val:0x%08x.\n", reg, *val);
+}
+
+static inline void vdoa_write_register(struct vdoa_info *vdoa,
+ u32 reg, u32 val)
+{
+ iowrite32(val, vdoa->reg_base + reg);
+ dev_dbg(vdoa->dev, "\t\twrite_reg:0x%02x, val:0x%08x.\n", reg, val);
+}
+
+static void dump_registers(struct vdoa_info *vdoa)
+{
+ int i;
+ u32 data;
+
+ for (i = VDOAC; i < VDOATD; i += 4)
+ vdoa_read_register(vdoa, i, &data);
+}
+
+int vdoa_setup(vdoa_handle_t handle, struct vdoa_params *params)
+{
+ int band_size;
+ int total_band_size = 0;
+ int ipu_stride;
+ u32 data;
+ struct vdoa_info *vdoa = (struct vdoa_info *)handle;
+
+ CHECK_NULL_PTR(vdoa);
+ CHECK_STATE(VDOA_GET | VDOA_GET_OBUF | VDOA_STOP, return -EINVAL);
+ if (VDOA_GET == vdoa->state) {
+ dev_dbg(vdoa->dev, "w:%d, h:%d.\n",
+ params->width, params->height);
+ data = (params->band_lines == VDOAC_BAND_HEIGHT_32LINES) ? 2 :
+ ((params->band_lines == VDOAC_BAND_HEIGHT_16LINES) ?
+ 1 : 0);
+ data |= params->scan_order ? VDOAC_SCAN_ORDER_INTERLACED : 0;
+ data |= params->band_mode ? VDOAC_SYNC_BAND_MODE : 0;
+ data |= params->pfs ? VDOAC_PFS_YUYV : 0;
+ data |= params->ipu_num ? VDOAC_IPU_SEL_1 : 0;
+ vdoa_write_register(vdoa, VDOAC, data);
+
+ data = ((params->width & VDOAFP_FW_MASK) << VDOAFP_FW_SHIFT) |
+ ((params->height & VDOAFP_FH_MASK) << VDOAFP_FH_SHIFT);
+ vdoa_write_register(vdoa, VDOAFP, data);
+
+ ipu_stride = params->pfs ? params->width << 1 : params->width;
+ data = ((params->vpu_stride & VDOASL_VSLY_MASK) <<
+ VDOASL_VSLY_SHIFT) |
+ ((ipu_stride & VDOASL_ISLY_MASK) << VDOASL_ISLY_SHIFT);
+ vdoa_write_register(vdoa, VDOASL, data);
+
+ dev_dbg(vdoa->dev, "band_mode:%d, band_line:%d, base:0x%lx.\n",
+ params->band_mode, params->band_lines, vdoa->iram_paddr);
+ }
+ /*
+ * band size = (luma_per_line + chroma_per_line) * bandLines
+ * = width * (3/2 or 2) * bandLines
+ * double buffer mode used.
+ */
+ if (params->pfs)
+ band_size = (params->width << 1) * params->band_lines;
+ else
+ band_size = ((params->width * 3) >> 1) *
+ params->band_lines;
+ if (params->interlaced) {
+ total_band_size = 6 * band_size; /* 3 frames*double buffer */
+ if (iram_size < total_band_size) {
+ dev_err(vdoa->dev, "iram_size:0x%lx is smaller than "
+ "request:0x%x!\n", iram_size, total_band_size);
+ return -EINVAL;
+ }
+ if (params->vfield_buf.prev_veba) {
+ if (params->band_mode) {
+ vdoa_write_register(vdoa, VDOAIEBA00,
+ vdoa->iram_paddr);
+ vdoa_write_register(vdoa, VDOAIEBA10,
+ vdoa->iram_paddr + band_size);
+ } else
+ vdoa_write_register(vdoa, VDOAIEBA00,
+ params->ieba0);
+ vdoa_write_register(vdoa, VDOAVEBA0,
+ params->vfield_buf.prev_veba);
+ vdoa->field = VDOA_PREV_FIELD;
+ }
+ if (params->vfield_buf.cur_veba) {
+ if (params->band_mode) {
+ vdoa_write_register(vdoa, VDOAIEBA01,
+ vdoa->iram_paddr + band_size * 2);
+ vdoa_write_register(vdoa, VDOAIEBA11,
+ vdoa->iram_paddr + band_size * 3);
+ } else
+ vdoa_write_register(vdoa, VDOAIEBA01,
+ params->ieba1);
+ vdoa_write_register(vdoa, VDOAVEBA1,
+ params->vfield_buf.cur_veba);
+ vdoa->field = VDOA_CURR_FIELD;
+ }
+ if (params->vfield_buf.next_veba) {
+ if (params->band_mode) {
+ vdoa_write_register(vdoa, VDOAIEBA02,
+ vdoa->iram_paddr + band_size * 4);
+ vdoa_write_register(vdoa, VDOAIEBA12,
+ vdoa->iram_paddr + band_size * 5);
+ } else
+ vdoa_write_register(vdoa, VDOAIEBA02,
+ params->ieba2);
+ vdoa_write_register(vdoa, VDOAVEBA2,
+ params->vfield_buf.next_veba);
+ vdoa->field = VDOA_NEXT_FIELD;
+ vdoa_read_register(vdoa, VDOAC, &data);
+ data |= VDOAC_THREE_FRAMES;
+ vdoa_write_register(vdoa, VDOAC, data);
+ }
+
+ if (!params->pfs)
+ vdoa_write_register(vdoa, VDOAIUBO,
+ params->width * params->band_lines);
+ vdoa_write_register(vdoa, VDOAVUBO,
+ params->vfield_buf.vubo);
+ dev_dbg(vdoa->dev, "total band_size:0x%x.\n", band_size*6);
+ } else if (params->band_mode) {
+ /* used for progressive frame resize on PrP channel */
+ BUG(); /* currently not support */
+ /* progressvie frame: band mode */
+ vdoa_write_register(vdoa, VDOAIEBA00, vdoa->iram_paddr);
+ vdoa_write_register(vdoa, VDOAIEBA10,
+ vdoa->iram_paddr + band_size);
+ if (!params->pfs)
+ vdoa_write_register(vdoa, VDOAIUBO,
+ params->width * params->band_lines);
+ dev_dbg(vdoa->dev, "total band_size:0x%x\n", band_size*2);
+ } else {
+ /* progressive frame: mem->mem, non-band mode */
+ vdoa->field = VDOA_FRAME;
+ vdoa_write_register(vdoa, VDOAVEBA0, params->vframe_buf.veba);
+ vdoa_write_register(vdoa, VDOAVUBO, params->vframe_buf.vubo);
+ vdoa_write_register(vdoa, VDOAIEBA00, params->ieba0);
+ if (!params->pfs)
+ /* note: iubo is relative value, based on ieba0 */
+ vdoa_write_register(vdoa, VDOAIUBO,
+ params->width * params->height);
+ }
+ vdoa->state = VDOA_SETUP;
+ return 0;
+}
+
+void vdoa_get_output_buf(vdoa_handle_t handle, struct vdoa_ipu_buf *buf)
+{
+ u32 data;
+ struct vdoa_info *vdoa = (struct vdoa_info *)handle;
+
+ CHECK_NULL_PTR(vdoa);
+ CHECK_STATE(VDOA_SETUP, return);
+ vdoa->state = VDOA_GET_OBUF;
+ memset(buf, 0, sizeof(*buf));
+
+ vdoa_read_register(vdoa, VDOAC, &data);
+ switch (vdoa->field) {
+ case VDOA_FRAME:
+ case VDOA_PREV_FIELD:
+ vdoa_read_register(vdoa, VDOAIEBA00, &buf->ieba0);
+ if (data & VDOAC_SYNC_BAND_MODE)
+ vdoa_read_register(vdoa, VDOAIEBA10, &buf->ieba1);
+ break;
+ case VDOA_CURR_FIELD:
+ vdoa_read_register(vdoa, VDOAIEBA01, &buf->ieba0);
+ vdoa_read_register(vdoa, VDOAIEBA11, &buf->ieba1);
+ break;
+ case VDOA_NEXT_FIELD:
+ vdoa_read_register(vdoa, VDOAIEBA02, &buf->ieba0);
+ vdoa_read_register(vdoa, VDOAIEBA12, &buf->ieba1);
+ break;
+ default:
+ BUG();
+ break;
+ }
+ if (!(data & VDOAC_PFS_YUYV))
+ vdoa_read_register(vdoa, VDOAIUBO, &buf->iubo);
+}
+
+int vdoa_start(vdoa_handle_t handle, int timeout_ms)
+{
+ int ret;
+ struct vdoa_info *vdoa = (struct vdoa_info *)handle;
+
+ CHECK_NULL_PTR(vdoa);
+ CHECK_STATE(VDOA_GET_OBUF, return -EINVAL);
+ vdoa->state = VDOA_START;
+ init_completion(&vdoa->comp);
+ vdoa_write_register(vdoa, VDOAIST,
+ VDOAIEIST_TRANSFER_ERR | VDOAIEIST_TRANSFER_END);
+ vdoa_write_register(vdoa, VDOAIE,
+ VDOAIEIST_TRANSFER_ERR | VDOAIEIST_TRANSFER_END);
+
+ enable_irq(vdoa->irq);
+ vdoa_write_register(vdoa, VDOASRR, VDOASRR_START_XFER);
+ dump_registers(vdoa);
+
+ ret = wait_for_completion_timeout(&vdoa->comp,
+ msecs_to_jiffies(timeout_ms));
+
+ return ret > 0 ? 0 : -ETIMEDOUT;
+}
+
+void vdoa_stop(vdoa_handle_t handle)
+{
+ struct vdoa_info *vdoa = (struct vdoa_info *)handle;
+
+ CHECK_NULL_PTR(vdoa);
+ CHECK_STATE(VDOA_GET | VDOA_START | VDOA_INIRQ, return);
+ vdoa->state = VDOA_STOP;
+
+ disable_irq(vdoa->irq);
+
+ vdoa_write_register(vdoa, VDOASRR, VDOASRR_SWRST);
+}
+
+void vdoa_get_handle(vdoa_handle_t *handle)
+{
+ struct vdoa_info *vdoa = g_vdoa;
+
+ CHECK_NULL_PTR(handle);
+ *handle = (vdoa_handle_t *)NULL;
+ CHECK_STATE(VDOA_INIT, return);
+ mutex_lock(&vdoa_lock);
+ clk_prepare_enable(vdoa->vdoa_clk);
+ vdoa->state = VDOA_GET;
+ vdoa->field = VDOA_NULL;
+ vdoa_write_register(vdoa, VDOASRR, VDOASRR_SWRST);
+
+ *handle = (vdoa_handle_t *)vdoa;
+}
+
+void vdoa_put_handle(vdoa_handle_t *handle)
+{
+ struct vdoa_info *vdoa = (struct vdoa_info *)(*handle);
+
+ CHECK_NULL_PTR(vdoa);
+ CHECK_STATE(VDOA_STOP, return);
+ if (vdoa != g_vdoa)
+ BUG();
+
+ clk_disable_unprepare(vdoa->vdoa_clk);
+ vdoa->state = VDOA_PUT;
+ *handle = (vdoa_handle_t *)NULL;
+ mutex_unlock(&vdoa_lock);
+}
+
+static irqreturn_t vdoa_irq_handler(int irq, void *data)
+{
+ u32 status, mask, val;
+ struct vdoa_info *vdoa = data;
+
+ CHECK_NULL_PTR(vdoa);
+ CHECK_STATE(VDOA_START, return IRQ_HANDLED);
+ vdoa->state = VDOA_INIRQ;
+ vdoa_read_register(vdoa, VDOAIST, &status);
+ vdoa_read_register(vdoa, VDOAIE, &mask);
+ val = status & mask;
+ vdoa_write_register(vdoa, VDOAIST, val);
+ if (VDOAIEIST_TRANSFER_ERR & val)
+ dev_err(vdoa->dev, "vdoa Transfer err irq!\n");
+ if (VDOAIEIST_TRANSFER_END & val)
+ dev_dbg(vdoa->dev, "vdoa Transfer end irq!\n");
+ if (0 == val) {
+ dev_err(vdoa->dev, "vdoa unknown irq!\n");
+ BUG();
+ }
+
+ complete(&vdoa->comp);
+ return IRQ_HANDLED;
+}
+
+/* IRAM Size in Kbytes, example:vdoa_iram_size=64, 64KBytes */
+static int __init vdoa_iram_size_setup(char *options)
+{
+ int ret;
+
+ ret = kstrtoul(options, 0, &iram_size);
+ if (ret)
+ iram_size = 0;
+ else
+ iram_size *= SZ_1K;
+
+ return 1;
+}
+__setup("vdoa_iram_size=", vdoa_iram_size_setup);
+
+static const struct of_device_id imx_vdoa_dt_ids[] = {
+ { .compatible = "fsl,imx6q-vdoa", },
+ { /* sentinel */ }
+};
+
+static int vdoa_probe(struct platform_device *pdev)
+{
+ int ret;
+ struct vdoa_info *vdoa;
+ struct resource *res;
+ struct resource *res_irq;
+ struct device *dev = &pdev->dev;
+ struct device_node *np = pdev->dev.of_node;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ dev_err(dev, "can't get device resources\n");
+ return -ENOENT;
+ }
+
+ res_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+ if (!res_irq) {
+ dev_err(dev, "failed to get irq resource\n");
+ return -ENOENT;
+ }
+
+ vdoa = devm_kzalloc(dev, sizeof(struct vdoa_info), GFP_KERNEL);
+ if (!vdoa)
+ return -ENOMEM;
+ vdoa->dev = dev;
+
+ vdoa->reg_base = devm_ioremap_resource(&pdev->dev, res);
+ if (!vdoa->reg_base)
+ return -EBUSY;
+
+ vdoa->irq = res_irq->start;
+ ret = devm_request_irq(dev, vdoa->irq, vdoa_irq_handler, 0,
+ "vdoa", vdoa);
+ if (ret) {
+ dev_err(dev, "can't claim irq %d\n", vdoa->irq);
+ return ret;
+ }
+ disable_irq(vdoa->irq);
+
+ vdoa->vdoa_clk = devm_clk_get(dev, NULL);
+ if (IS_ERR(vdoa->vdoa_clk)) {
+ dev_err(dev, "failed to get vdoa_clk\n");
+ return PTR_ERR(vdoa->vdoa_clk);
+ }
+
+ vdoa->iram_pool = of_gen_pool_get(np, "iram", 0);
+ if (!vdoa->iram_pool) {
+ dev_err(&pdev->dev, "iram pool not available\n");
+ return -ENOMEM;
+ }
+
+ if ((iram_size == 0) || (iram_size > MAX_VDOA_IRAM_SIZE))
+ iram_size = VDOA_IRAM_SIZE;
+
+ vdoa->iram_base = gen_pool_alloc(vdoa->iram_pool, iram_size);
+ if (!vdoa->iram_base) {
+ dev_err(&pdev->dev, "unable to alloc iram\n");
+ return -ENOMEM;
+ }
+
+ vdoa->iram_paddr = gen_pool_virt_to_phys(vdoa->iram_pool,
+ vdoa->iram_base);
+
+ dev_dbg(dev, "iram_base:0x%lx,iram_paddr:0x%lx,size:0x%lx\n",
+ vdoa->iram_base, vdoa->iram_paddr, iram_size);
+
+ vdoa->state = VDOA_INIT;
+ dev_set_drvdata(dev, vdoa);
+ g_vdoa = vdoa;
+ dev_info(dev, "i.MX Video Data Order Adapter(VDOA) driver probed\n");
+ return 0;
+}
+
+static int vdoa_remove(struct platform_device *pdev)
+{
+ struct vdoa_info *vdoa = dev_get_drvdata(&pdev->dev);
+
+ gen_pool_free(vdoa->iram_pool, vdoa->iram_base, iram_size);
+ kfree(vdoa);
+ dev_set_drvdata(&pdev->dev, NULL);
+
+ return 0;
+}
+
+static struct platform_driver vdoa_driver = {
+ .driver = {
+ .name = "mxc_vdoa",
+ .of_match_table = imx_vdoa_dt_ids,
+ },
+ .probe = vdoa_probe,
+ .remove = vdoa_remove,
+};
+
+static int __init vdoa_init(void)
+{
+ int err;
+
+ err = platform_driver_register(&vdoa_driver);
+ if (err) {
+ pr_err("vdoa_driver register failed\n");
+ return -ENODEV;
+ }
+ return 0;
+}
+
+static void __exit vdoa_cleanup(void)
+{
+ platform_driver_unregister(&vdoa_driver);
+}
+
+subsys_initcall(vdoa_init);
+module_exit(vdoa_cleanup);
+
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("i.MX Video Data Order Adapter(VDOA) driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/mxc/ipu3/vdoa.h b/drivers/mxc/ipu3/vdoa.h
new file mode 100644
index 000000000000..3e4c7356cb26
--- /dev/null
+++ b/drivers/mxc/ipu3/vdoa.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2012-2015 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#ifndef __VDOA_H__
+#define __VDOA_H__
+
+#define VDOA_PFS_YUYV (1)
+#define VDOA_PFS_NV12 (0)
+
+
+struct vfield_buf {
+ u32 prev_veba;
+ u32 cur_veba;
+ u32 next_veba;
+ u32 vubo;
+};
+
+struct vframe_buf {
+ u32 veba;
+ u32 vubo;
+};
+
+struct vdoa_params {
+ u32 width;
+ u32 height;
+ int vpu_stride;
+ int interlaced;
+ int scan_order;
+ int ipu_num;
+ int band_lines;
+ int band_mode;
+ int pfs;
+ u32 ieba0;
+ u32 ieba1;
+ u32 ieba2;
+ struct vframe_buf vframe_buf;
+ struct vfield_buf vfield_buf;
+};
+struct vdoa_ipu_buf {
+ u32 ieba0;
+ u32 ieba1;
+ u32 iubo;
+};
+
+struct vdoa_info;
+typedef void *vdoa_handle_t;
+
+int vdoa_setup(vdoa_handle_t handle, struct vdoa_params *params);
+void vdoa_get_output_buf(vdoa_handle_t handle, struct vdoa_ipu_buf *buf);
+int vdoa_start(vdoa_handle_t handle, int timeout_ms);
+void vdoa_stop(vdoa_handle_t handle);
+void vdoa_get_handle(vdoa_handle_t *handle);
+void vdoa_put_handle(vdoa_handle_t *handle);
+#endif
diff --git a/drivers/mxc/mipi/Kconfig b/drivers/mxc/mipi/Kconfig
new file mode 100644
index 000000000000..4c85da374ed2
--- /dev/null
+++ b/drivers/mxc/mipi/Kconfig
@@ -0,0 +1,14 @@
+#
+# MIPI configuration
+#
+
+menu "MXC MIPI Support"
+
+config MXC_MIPI_CSI2
+ tristate "MIPI CSI2 support"
+ depends on (SOC_IMX6 || SOC_IMX7)
+ default n
+ ---help---
+ Say Y to get the MIPI CSI2 support.
+
+endmenu
diff --git a/drivers/mxc/mipi/Makefile b/drivers/mxc/mipi/Makefile
new file mode 100644
index 000000000000..98cda773bd28
--- /dev/null
+++ b/drivers/mxc/mipi/Makefile
@@ -0,0 +1,4 @@
+#
+# Makefile for the mipi interface driver
+#
+obj-$(CONFIG_MXC_MIPI_CSI2) += mxc_mipi_csi2.o
diff --git a/drivers/mxc/mipi/mxc_mipi_csi2.c b/drivers/mxc/mipi/mxc_mipi_csi2.c
new file mode 100644
index 000000000000..df45c364f144
--- /dev/null
+++ b/drivers/mxc/mipi/mxc_mipi_csi2.c
@@ -0,0 +1,540 @@
+/*
+ * Copyright (C) 2011-2014 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/irqdesc.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/console.h>
+#include <linux/io.h>
+#include <linux/bitops.h>
+#include <linux/delay.h>
+#include <linux/fsl_devices.h>
+#include <linux/slab.h>
+#include <linux/of.h>
+
+#include <linux/mipi_csi2.h>
+
+#include "mxc_mipi_csi2.h"
+
+static struct mipi_csi2_info *gmipi_csi2;
+
+void _mipi_csi2_lock(struct mipi_csi2_info *info)
+{
+ if (!in_irq() && !in_softirq())
+ mutex_lock(&info->mutex_lock);
+}
+
+void _mipi_csi2_unlock(struct mipi_csi2_info *info)
+{
+ if (!in_irq() && !in_softirq())
+ mutex_unlock(&info->mutex_lock);
+}
+
+static inline void mipi_csi2_write(struct mipi_csi2_info *info,
+ unsigned value, unsigned offset)
+{
+ writel(value, info->mipi_csi2_base + offset);
+}
+
+static inline unsigned int mipi_csi2_read(struct mipi_csi2_info *info,
+ unsigned offset)
+{
+ return readl(info->mipi_csi2_base + offset);
+}
+
+/*!
+ * This function is called to enable the mipi csi2 interface.
+ *
+ * @param info mipi csi2 hander
+ * @return Returns setted value
+ */
+bool mipi_csi2_enable(struct mipi_csi2_info *info)
+{
+ bool status;
+
+ _mipi_csi2_lock(info);
+
+ if (!info->mipi_en) {
+ info->mipi_en = true;
+ clk_prepare_enable(info->cfg_clk);
+ clk_prepare_enable(info->dphy_clk);
+ } else
+ mipi_dbg("mipi csi2 already enabled!\n");
+
+ status = info->mipi_en;
+
+ _mipi_csi2_unlock(info);
+
+ return status;
+}
+EXPORT_SYMBOL(mipi_csi2_enable);
+
+/*!
+ * This function is called to disable the mipi csi2 interface.
+ *
+ * @param info mipi csi2 hander
+ * @return Returns setted value
+ */
+bool mipi_csi2_disable(struct mipi_csi2_info *info)
+{
+ bool status;
+
+ _mipi_csi2_lock(info);
+
+ if (info->mipi_en) {
+ info->mipi_en = false;
+ clk_disable_unprepare(info->dphy_clk);
+ clk_disable_unprepare(info->cfg_clk);
+ } else
+ mipi_dbg("mipi csi2 already disabled!\n");
+
+ status = info->mipi_en;
+
+ _mipi_csi2_unlock(info);
+
+ return status;
+}
+EXPORT_SYMBOL(mipi_csi2_disable);
+
+/*!
+ * This function is called to get mipi csi2 disable/enable status.
+ *
+ * @param info mipi csi2 hander
+ * @return Returns mipi csi2 status
+ */
+bool mipi_csi2_get_status(struct mipi_csi2_info *info)
+{
+ bool status;
+
+ _mipi_csi2_lock(info);
+ status = info->mipi_en;
+ _mipi_csi2_unlock(info);
+
+ return status;
+}
+EXPORT_SYMBOL(mipi_csi2_get_status);
+
+/*!
+ * This function is called to set mipi lanes.
+ *
+ * @param info mipi csi2 hander
+ * @return Returns setted value
+ */
+unsigned int mipi_csi2_set_lanes(struct mipi_csi2_info *info)
+{
+ unsigned int lanes;
+
+ _mipi_csi2_lock(info);
+ mipi_csi2_write(info, info->lanes - 1, MIPI_CSI2_N_LANES);
+ lanes = mipi_csi2_read(info, MIPI_CSI2_N_LANES);
+ _mipi_csi2_unlock(info);
+
+ return lanes;
+}
+EXPORT_SYMBOL(mipi_csi2_set_lanes);
+
+/*!
+ * This function is called to set mipi data type.
+ *
+ * @param info mipi csi2 hander
+ * @return Returns setted value
+ */
+unsigned int mipi_csi2_set_datatype(struct mipi_csi2_info *info,
+ unsigned int datatype)
+{
+ unsigned int dtype;
+
+ _mipi_csi2_lock(info);
+ info->datatype = datatype;
+ dtype = info->datatype;
+ _mipi_csi2_unlock(info);
+
+ return dtype;
+}
+EXPORT_SYMBOL(mipi_csi2_set_datatype);
+
+/*!
+ * This function is called to get mipi data type.
+ *
+ * @param info mipi csi2 hander
+ * @return Returns mipi data type
+ */
+unsigned int mipi_csi2_get_datatype(struct mipi_csi2_info *info)
+{
+ unsigned int dtype;
+
+ _mipi_csi2_lock(info);
+ dtype = info->datatype;
+ _mipi_csi2_unlock(info);
+
+ return dtype;
+}
+EXPORT_SYMBOL(mipi_csi2_get_datatype);
+
+/*!
+ * This function is called to get mipi csi2 dphy status.
+ *
+ * @param info mipi csi2 hander
+ * @return Returns dphy status
+ */
+unsigned int mipi_csi2_dphy_status(struct mipi_csi2_info *info)
+{
+ unsigned int status;
+
+ _mipi_csi2_lock(info);
+ status = mipi_csi2_read(info, MIPI_CSI2_PHY_STATE);
+ _mipi_csi2_unlock(info);
+
+ return status;
+}
+EXPORT_SYMBOL(mipi_csi2_dphy_status);
+
+/*!
+ * This function is called to get mipi csi2 error1 status.
+ *
+ * @param info mipi csi2 hander
+ * @return Returns error1 value
+ */
+unsigned int mipi_csi2_get_error1(struct mipi_csi2_info *info)
+{
+ unsigned int err1;
+
+ _mipi_csi2_lock(info);
+ err1 = mipi_csi2_read(info, MIPI_CSI2_ERR1);
+ _mipi_csi2_unlock(info);
+
+ return err1;
+}
+EXPORT_SYMBOL(mipi_csi2_get_error1);
+
+/*!
+ * This function is called to get mipi csi2 error1 status.
+ *
+ * @param info mipi csi2 hander
+ * @return Returns error1 value
+ */
+unsigned int mipi_csi2_get_error2(struct mipi_csi2_info *info)
+{
+ unsigned int err2;
+
+ _mipi_csi2_lock(info);
+ err2 = mipi_csi2_read(info, MIPI_CSI2_ERR2);
+ _mipi_csi2_unlock(info);
+
+ return err2;
+}
+EXPORT_SYMBOL(mipi_csi2_get_error2);
+
+/*!
+ * This function is called to enable mipi to ipu pixel clock.
+ *
+ * @param info mipi csi2 hander
+ * @return Returns 0 on success or negative error code on fail
+ */
+int mipi_csi2_pixelclk_enable(struct mipi_csi2_info *info)
+{
+ return clk_prepare_enable(info->pixel_clk);
+}
+EXPORT_SYMBOL(mipi_csi2_pixelclk_enable);
+
+/*!
+ * This function is called to disable mipi to ipu pixel clock.
+ *
+ * @param info mipi csi2 hander
+ * @return Returns 0 on success or negative error code on fail
+ */
+void mipi_csi2_pixelclk_disable(struct mipi_csi2_info *info)
+{
+ clk_disable_unprepare(info->pixel_clk);
+}
+EXPORT_SYMBOL(mipi_csi2_pixelclk_disable);
+
+/*!
+ * This function is called to power on mipi csi2.
+ *
+ * @param info mipi csi2 hander
+ * @return Returns 0 on success or negative error code on fail
+ */
+int mipi_csi2_reset(struct mipi_csi2_info *info)
+{
+ _mipi_csi2_lock(info);
+
+ mipi_csi2_write(info, 0x0, MIPI_CSI2_PHY_SHUTDOWNZ);
+ mipi_csi2_write(info, 0x0, MIPI_CSI2_DPHY_RSTZ);
+ mipi_csi2_write(info, 0x0, MIPI_CSI2_CSI2_RESETN);
+
+ mipi_csi2_write(info, 0x00000001, MIPI_CSI2_PHY_TST_CTRL0);
+ mipi_csi2_write(info, 0x00000000, MIPI_CSI2_PHY_TST_CTRL1);
+ mipi_csi2_write(info, 0x00000000, MIPI_CSI2_PHY_TST_CTRL0);
+ mipi_csi2_write(info, 0x00000002, MIPI_CSI2_PHY_TST_CTRL0);
+ mipi_csi2_write(info, 0x00010044, MIPI_CSI2_PHY_TST_CTRL1);
+ mipi_csi2_write(info, 0x00000000, MIPI_CSI2_PHY_TST_CTRL0);
+ mipi_csi2_write(info, 0x00000014, MIPI_CSI2_PHY_TST_CTRL1);
+ mipi_csi2_write(info, 0x00000002, MIPI_CSI2_PHY_TST_CTRL0);
+ mipi_csi2_write(info, 0x00000000, MIPI_CSI2_PHY_TST_CTRL0);
+
+ mipi_csi2_write(info, 0xffffffff, MIPI_CSI2_PHY_SHUTDOWNZ);
+ mipi_csi2_write(info, 0xffffffff, MIPI_CSI2_DPHY_RSTZ);
+ mipi_csi2_write(info, 0xffffffff, MIPI_CSI2_CSI2_RESETN);
+
+ _mipi_csi2_unlock(info);
+
+ return 0;
+}
+EXPORT_SYMBOL(mipi_csi2_reset);
+
+/*!
+ * This function is called to get mipi csi2 info.
+ *
+ * @return Returns mipi csi2 info struct pointor
+ */
+struct mipi_csi2_info *mipi_csi2_get_info(void)
+{
+ return gmipi_csi2;
+}
+EXPORT_SYMBOL(mipi_csi2_get_info);
+
+/*!
+ * This function is called to get mipi csi2 bind ipu num.
+ *
+ * @return Returns mipi csi2 bind ipu num
+ */
+int mipi_csi2_get_bind_ipu(struct mipi_csi2_info *info)
+{
+ int ipu_id;
+
+ _mipi_csi2_lock(info);
+ ipu_id = info->ipu_id;
+ _mipi_csi2_unlock(info);
+
+ return ipu_id;
+}
+EXPORT_SYMBOL(mipi_csi2_get_bind_ipu);
+
+/*!
+ * This function is called to get mipi csi2 bind csi num.
+ *
+ * @return Returns mipi csi2 bind csi num
+ */
+unsigned int mipi_csi2_get_bind_csi(struct mipi_csi2_info *info)
+{
+ unsigned int csi_id;
+
+ _mipi_csi2_lock(info);
+ csi_id = info->csi_id;
+ _mipi_csi2_unlock(info);
+
+ return csi_id;
+}
+EXPORT_SYMBOL(mipi_csi2_get_bind_csi);
+
+/*!
+ * This function is called to get mipi csi2 virtual channel.
+ *
+ * @return Returns mipi csi2 virtual channel num
+ */
+unsigned int mipi_csi2_get_virtual_channel(struct mipi_csi2_info *info)
+{
+ unsigned int v_channel;
+
+ _mipi_csi2_lock(info);
+ v_channel = info->v_channel;
+ _mipi_csi2_unlock(info);
+
+ return v_channel;
+}
+EXPORT_SYMBOL(mipi_csi2_get_virtual_channel);
+
+/**
+ * This function is called by the driver framework to initialize the MIPI CSI2
+ * device.
+ *
+ * @param pdev The device structure for the MIPI CSI2 passed in by the
+ * driver framework.
+ *
+ * @return Returns 0 on success or negative error code on error
+ */
+static int mipi_csi2_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct device_node *np = pdev->dev.of_node;
+ struct resource *res;
+ u32 mipi_csi2_dphy_ver;
+ int ret;
+
+ gmipi_csi2 = kmalloc(sizeof(struct mipi_csi2_info), GFP_KERNEL);
+ if (!gmipi_csi2) {
+ ret = -ENOMEM;
+ goto alloc_failed;
+ }
+
+ ret = of_property_read_u32(np, "ipu_id", &(gmipi_csi2->ipu_id));
+ if (ret) {
+ dev_err(&pdev->dev, "ipu_id missing or invalid\n");
+ goto err;
+ }
+
+ ret = of_property_read_u32(np, "csi_id", &(gmipi_csi2->csi_id));
+ if (ret) {
+ dev_err(&pdev->dev, "csi_id missing or invalid\n");
+ goto err;
+ }
+
+ ret = of_property_read_u32(np, "v_channel", &(gmipi_csi2->v_channel));
+ if (ret) {
+ dev_err(&pdev->dev, "v_channel missing or invalid\n");
+ goto err;
+ }
+
+ ret = of_property_read_u32(np, "lanes", &(gmipi_csi2->lanes));
+ if (ret) {
+ dev_err(&pdev->dev, "lanes missing or invalid\n");
+ goto err;
+ }
+
+ if ((gmipi_csi2->ipu_id < 0) || (gmipi_csi2->ipu_id > 1) ||
+ (gmipi_csi2->csi_id > 1) || (gmipi_csi2->v_channel > 3) ||
+ (gmipi_csi2->lanes > 4)) {
+ dev_err(&pdev->dev, "invalid param for mipi csi2!\n");
+ ret = -EINVAL;
+ goto err;
+ }
+
+ /* initialize mutex */
+ mutex_init(&gmipi_csi2->mutex_lock);
+
+ /* get mipi csi2 informaiton */
+ gmipi_csi2->pdev = pdev;
+ gmipi_csi2->mipi_en = false;
+
+ gmipi_csi2->cfg_clk = devm_clk_get(dev, "cfg_clk");
+ if (IS_ERR(gmipi_csi2->cfg_clk)) {
+ dev_err(&pdev->dev, "failed to get cfg_clk\n");
+ ret = PTR_ERR(gmipi_csi2->cfg_clk);
+ goto err;
+ }
+
+ /* get mipi dphy clk */
+ gmipi_csi2->dphy_clk = devm_clk_get(dev, "dphy_clk");
+ if (IS_ERR(gmipi_csi2->dphy_clk)) {
+ dev_err(&pdev->dev, "failed to get dphy pll_ref_clk\n");
+ ret = PTR_ERR(gmipi_csi2->dphy_clk);
+ goto err;
+ }
+
+ /* get mipi to ipu pixel clk */
+ gmipi_csi2->pixel_clk = devm_clk_get(dev, "pixel_clk");
+ if (IS_ERR(gmipi_csi2->pixel_clk)) {
+ dev_err(&pdev->dev, "failed to get mipi pixel clk\n");
+ ret = PTR_ERR(gmipi_csi2->pixel_clk);
+ goto err;
+ }
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ ret = -ENODEV;
+ goto err;
+ }
+
+ /* mipi register mapping */
+ gmipi_csi2->mipi_csi2_base = ioremap(res->start, PAGE_SIZE);
+ if (!gmipi_csi2->mipi_csi2_base) {
+ ret = -ENOMEM;
+ goto err;
+ }
+
+ /* mipi dphy clk enable for register access */
+ clk_prepare_enable(gmipi_csi2->dphy_clk);
+ /* get mipi csi2 dphy version */
+ mipi_csi2_dphy_ver = mipi_csi2_read(gmipi_csi2, MIPI_CSI2_VERSION);
+
+ clk_disable_unprepare(gmipi_csi2->dphy_clk);
+
+ platform_set_drvdata(pdev, gmipi_csi2);
+
+ dev_info(&pdev->dev, "i.MX MIPI CSI2 driver probed\n");
+ dev_info(&pdev->dev, "i.MX MIPI CSI2 dphy version is 0x%x\n",
+ mipi_csi2_dphy_ver);
+
+ return 0;
+
+err:
+ kfree(gmipi_csi2);
+alloc_failed:
+ dev_err(&pdev->dev, "i.MX MIPI CSI2 driver probed - error\n");
+ return ret;
+}
+
+static int mipi_csi2_remove(struct platform_device *pdev)
+{
+ /* unmapping mipi register */
+ iounmap(gmipi_csi2->mipi_csi2_base);
+
+ kfree(gmipi_csi2);
+
+ dev_set_drvdata(&pdev->dev, NULL);
+
+ return 0;
+}
+
+static const struct of_device_id imx_mipi_csi2_dt_ids[] = {
+ { .compatible = "fsl,imx6q-mipi-csi2", },
+ { /* sentinel */ }
+};
+
+static struct platform_driver mipi_csi2_driver = {
+ .driver = {
+ .name = "mxc_mipi_csi2",
+ .of_match_table = imx_mipi_csi2_dt_ids,
+ },
+ .probe = mipi_csi2_probe,
+ .remove = mipi_csi2_remove,
+};
+
+static int __init mipi_csi2_init(void)
+{
+ int err;
+
+ err = platform_driver_register(&mipi_csi2_driver);
+ if (err) {
+ pr_err("mipi_csi2_driver register failed\n");
+ return -ENODEV;
+ }
+
+ pr_info("MIPI CSI2 driver module loaded\n");
+
+ return 0;
+}
+
+static void __exit mipi_csi2_cleanup(void)
+{
+ platform_driver_unregister(&mipi_csi2_driver);
+}
+
+subsys_initcall(mipi_csi2_init);
+module_exit(mipi_csi2_cleanup);
+
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("i.MX MIPI CSI2 driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/mxc/mipi/mxc_mipi_csi2.h b/drivers/mxc/mipi/mxc_mipi_csi2.h
new file mode 100644
index 000000000000..291d7e891e09
--- /dev/null
+++ b/drivers/mxc/mipi/mxc_mipi_csi2.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2011-2014 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __MXC_MIPI_CSI2_H__
+#define __MXC_MIPI_CSI2_H__
+
+#ifdef DEBUG
+#define mipi_dbg(fmt, ...) \
+ printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__)
+#else
+#define mipi_dbg(fmt, ...)
+#endif
+
+/* driver private data */
+struct mipi_csi2_info {
+ bool mipi_en;
+ int ipu_id;
+ unsigned int csi_id;
+ unsigned int v_channel;
+ unsigned int lanes;
+ unsigned int datatype;
+ struct clk *cfg_clk;
+ struct clk *dphy_clk;
+ struct clk *pixel_clk;
+ void __iomem *mipi_csi2_base;
+ struct platform_device *pdev;
+
+ struct mutex mutex_lock;
+};
+
+#endif
diff --git a/drivers/mxc/mlb/Kconfig b/drivers/mxc/mlb/Kconfig
new file mode 100644
index 000000000000..343f884b9221
--- /dev/null
+++ b/drivers/mxc/mlb/Kconfig
@@ -0,0 +1,17 @@
+#
+# MLB150 configuration
+#
+
+menu "MXC Media Local Bus Driver"
+
+config MXC_MLB
+ boolean
+
+config MXC_MLB150
+ tristate "MLB150 support"
+ depends on (SOC_IMX6Q || SOC_IMX6SX || ARCH_FSL_IMX8QM || ARCH_FSL_IMX8QXP)
+ select MXC_MLB
+ ---help---
+ Say Y to get the MLB150 support.
+
+endmenu
diff --git a/drivers/mxc/mlb/Makefile b/drivers/mxc/mlb/Makefile
new file mode 100644
index 000000000000..e71005a3788f
--- /dev/null
+++ b/drivers/mxc/mlb/Makefile
@@ -0,0 +1,5 @@
+#
+# Makefile for the i.MX6Q/DL MLB150 driver
+#
+
+obj-$(CONFIG_MXC_MLB150) += mxc_mlb.o
diff --git a/drivers/mxc/mlb/mxc_mlb.c b/drivers/mxc/mlb/mxc_mlb.c
new file mode 100755
index 000000000000..cab46b9eed8f
--- /dev/null
+++ b/drivers/mxc/mlb/mxc_mlb.c
@@ -0,0 +1,2813 @@
+/*
+ * Copyright (C) 2011-2014 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <linux/cdev.h>
+#include <linux/circ_buf.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/dma-mapping.h>
+#include <linux/errno.h>
+#include <linux/fs.h>
+#include <linux/genalloc.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/mxc_mlb.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/poll.h>
+#include <linux/regulator/consumer.h>
+#include <linux/sched/signal.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/uaccess.h>
+
+#define DRIVER_NAME "mxc_mlb150"
+
+/*
+ * MLB module memory map registers define
+ */
+#define REG_MLBC0 0x0
+#define MLBC0_MLBEN (0x1)
+#define MLBC0_MLBCLK_MASK (0x7 << 2)
+#define MLBC0_MLBCLK_SHIFT (2)
+#define MLBC0_MLBPEN (0x1 << 5)
+#define MLBC0_MLBLK (0x1 << 7)
+#define MLBC0_ASYRETRY (0x1 << 12)
+#define MLBC0_CTLRETRY (0x1 << 12)
+#define MLBC0_FCNT_MASK (0x7 << 15)
+#define MLBC0_FCNT_SHIFT (15)
+
+#define REG_MLBPC0 0x8
+#define MLBPC0_MCLKHYS (0x1 << 11)
+
+#define REG_MS0 0xC
+#define REG_MS1 0x14
+
+#define REG_MSS 0x20
+#define MSS_RSTSYSCMD (0x1)
+#define MSS_LKSYSCMD (0x1 << 1)
+#define MSS_ULKSYSCMD (0x1 << 2)
+#define MSS_CSSYSCMD (0x1 << 3)
+#define MSS_SWSYSCMD (0x1 << 4)
+#define MSS_SERVREQ (0x1 << 5)
+
+#define REG_MSD 0x24
+
+#define REG_MIEN 0x2C
+#define MIEN_ISOC_PE (0x1)
+#define MIEN_ISOC_BUFO (0x1 << 1)
+#define MIEN_SYNC_PE (0x1 << 16)
+#define MIEN_ARX_DONE (0x1 << 17)
+#define MIEN_ARX_PE (0x1 << 18)
+#define MIEN_ARX_BREAK (0x1 << 19)
+#define MIEN_ATX_DONE (0x1 << 20)
+#define MIEN_ATX_PE (0x1 << 21)
+#define MIEN_ATX_BREAK (0x1 << 22)
+#define MIEN_CRX_DONE (0x1 << 24)
+#define MIEN_CRX_PE (0x1 << 25)
+#define MIEN_CRX_BREAK (0x1 << 26)
+#define MIEN_CTX_DONE (0x1 << 27)
+#define MIEN_CTX_PE (0x1 << 28)
+#define MIEN_CTX_BREAK (0x1 << 29)
+
+#define REG_MLBPC2 0x34
+#define REG_MLBPC1 0x38
+#define MLBPC1_VAL (0x00000888)
+
+#define REG_MLBC1 0x3C
+#define MLBC1_LOCK (0x1 << 6)
+#define MLBC1_CLKM (0x1 << 7)
+#define MLBC1_NDA_MASK (0xFF << 8)
+#define MLBC1_NDA_SHIFT (8)
+
+#define REG_HCTL 0x80
+#define HCTL_RST0 (0x1)
+#define HCTL_RST1 (0x1 << 1)
+#define HCTL_EN (0x1 << 15)
+
+#define REG_HCMR0 0x88
+#define REG_HCMR1 0x8C
+#define REG_HCER0 0x90
+#define REG_HCER1 0x94
+#define REG_HCBR0 0x98
+#define REG_HCBR1 0x9C
+
+#define REG_MDAT0 0xC0
+#define REG_MDAT1 0xC4
+#define REG_MDAT2 0xC8
+#define REG_MDAT3 0xCC
+
+#define REG_MDWE0 0xD0
+#define REG_MDWE1 0xD4
+#define REG_MDWE2 0xD8
+#define REG_MDWE3 0xDC
+
+#define REG_MCTL 0xE0
+#define MCTL_XCMP (0x1)
+
+#define REG_MADR 0xE4
+#define MADR_WNR (0x1 << 31)
+#define MADR_TB (0x1 << 30)
+#define MADR_ADDR_MASK (0x7f << 8)
+#define MADR_ADDR_SHIFT (0)
+
+#define REG_ACTL 0x3C0
+#define ACTL_MPB (0x1 << 4)
+#define ACTL_DMAMODE (0x1 << 2)
+#define ACTL_SMX (0x1 << 1)
+#define ACTL_SCE (0x1)
+
+#define REG_ACSR0 0x3D0
+#define REG_ACSR1 0x3D4
+#define REG_ACMR0 0x3D8
+#define REG_ACMR1 0x3DC
+
+#define REG_CAT_MDATn(ch) (REG_MDAT0 + ((ch % 8) >> 1) * 4)
+#define REG_CAT_MDWEn(ch) (REG_MDWE0 + ((ch % 8) >> 1) * 4)
+
+#define INT_AHB0_CH_START (0)
+#define INT_AHB1_CH_START (32)
+
+#define LOGIC_CH_NUM (64)
+#define BUF_CDT_OFFSET (0x0)
+#define BUF_ADT_OFFSET (0x40)
+#define BUF_CAT_MLB_OFFSET (0x80)
+#define BUF_CAT_HBI_OFFSET (0x88)
+#define BUF_CTR_END_OFFSET (0x8F)
+
+#define CAT_MODE_RX (0x1 << 0)
+#define CAT_MODE_TX (0x1 << 1)
+#define CAT_MODE_INBOUND_DMA (0x1 << 8)
+#define CAT_MODE_OUTBOUND_DMA (0x1 << 9)
+
+#define CH_SYNC_DEFAULT_QUAD (1)
+#define CH_SYNC_MAX_QUAD (15)
+#define CH_SYNC_CDT_BUF_DEP (CH_SYNC_DEFAULT_QUAD * 4 * 4)
+#define CH_SYNC_ADT_BUF_MULTI (4)
+#define CH_SYNC_ADT_BUF_DEP (CH_SYNC_CDT_BUF_DEP * CH_SYNC_ADT_BUF_MULTI)
+#define CH_SYNC_BUF_SZ (CH_SYNC_MAX_QUAD * 4 * 4 * \
+ CH_SYNC_ADT_BUF_MULTI)
+#define CH_CTRL_CDT_BUF_DEP (64)
+#define CH_CTRL_ADT_BUF_DEP (CH_CTRL_CDT_BUF_DEP)
+#define CH_CTRL_BUF_SZ (CH_CTRL_ADT_BUF_DEP)
+#define CH_ASYNC_MDP_PACKET_LEN (1024)
+#define CH_ASYNC_MEP_PACKET_LEN (1536)
+#define CH_ASYNC_CDT_BUF_DEP (CH_ASYNC_MEP_PACKET_LEN)
+#define CH_ASYNC_ADT_BUF_DEP (CH_ASYNC_CDT_BUF_DEP)
+#define CH_ASYNC_BUF_SZ (CH_ASYNC_ADT_BUF_DEP)
+#define CH_ISOC_BLK_SIZE_188 (188)
+#define CH_ISOC_BLK_SIZE_196 (196)
+#define CH_ISOC_BLK_SIZE (CH_ISOC_BLK_SIZE_188)
+#define CH_ISOC_BLK_NUM (1)
+#define CH_ISOC_CDT_BUF_DEP (CH_ISOC_BLK_SIZE * CH_ISOC_BLK_NUM)
+#define CH_ISOC_ADT_BUF_DEP (CH_ISOC_CDT_BUF_DEP)
+#define CH_ISOC_BUF_SZ (1024)
+
+#define CH_SYNC_DBR_BUF_OFFSET (0x0)
+#define CH_CTRL_DBR_BUF_OFFSET (CH_SYNC_DBR_BUF_OFFSET + \
+ 2 * (CH_SYNC_MAX_QUAD * 4 * 4))
+#define CH_ASYNC_DBR_BUF_OFFSET (CH_CTRL_DBR_BUF_OFFSET + \
+ 2 * CH_CTRL_CDT_BUF_DEP)
+#define CH_ISOC_DBR_BUF_OFFSET (CH_ASYNC_DBR_BUF_OFFSET + \
+ 2 * CH_ASYNC_CDT_BUF_DEP)
+
+#define DBR_BUF_START 0x00000
+
+#define CDT_LEN (16)
+#define ADT_LEN (16)
+#define CAT_LEN (2)
+
+#define CDT_SZ (CDT_LEN * LOGIC_CH_NUM)
+#define ADT_SZ (ADT_LEN * LOGIC_CH_NUM)
+#define CAT_SZ (CAT_LEN * LOGIC_CH_NUM * 2)
+
+#define CDT_BASE(base) (base + BUF_CDT_OFFSET)
+#define ADT_BASE(base) (base + BUF_ADT_OFFSET)
+#define CAT_MLB_BASE(base) (base + BUF_CAT_MLB_OFFSET)
+#define CAT_HBI_BASE(base) (base + BUF_CAT_HBI_OFFSET)
+
+#define CDTn_ADDR(base, n) (base + BUF_CDT_OFFSET + n * CDT_LEN)
+#define ADTn_ADDR(base, n) (base + BUF_ADT_OFFSET + n * ADT_LEN)
+#define CATn_MLB_ADDR(base, n) (base + BUF_CAT_MLB_OFFSET + n * CAT_LEN)
+#define CATn_HBI_ADDR(base, n) (base + BUF_CAT_HBI_OFFSET + n * CAT_LEN)
+
+#define CAT_CL_SHIFT (0x0)
+#define CAT_CT_SHIFT (8)
+#define CAT_CE (0x1 << 11)
+#define CAT_RNW (0x1 << 12)
+#define CAT_MT (0x1 << 13)
+#define CAT_FCE (0x1 << 14)
+#define CAT_MFE (0x1 << 14)
+
+#define CDT_WSBC_SHIFT (14)
+#define CDT_WPC_SHIFT (11)
+#define CDT_RSBC_SHIFT (30)
+#define CDT_RPC_SHIFT (27)
+#define CDT_WPC_1_SHIFT (12)
+#define CDT_RPC_1_SHIFT (28)
+#define CDT_WPTR_SHIFT (0)
+#define CDT_SYNC_WSTS_MASK (0x0000f000)
+#define CDT_SYNC_WSTS_SHIFT (12)
+#define CDT_CTRL_ASYNC_WSTS_MASK (0x0000f000)
+#define CDT_CTRL_ASYNC_WSTS_SHIFT (12)
+#define CDT_ISOC_WSTS_MASK (0x0000e000)
+#define CDT_ISOC_WSTS_SHIFT (13)
+#define CDT_RPTR_SHIFT (16)
+#define CDT_SYNC_RSTS_MASK (0xf0000000)
+#define CDT_SYNC_RSTS_SHIFT (28)
+#define CDT_CTRL_ASYNC_RSTS_MASK (0xf0000000)
+#define CDT_CTRL_ASYNC_RSTS_SHIFT (28)
+#define CDT_ISOC_RSTS_MASK (0xe0000000)
+#define CDT_ISOC_RSTS_SHIFT (29)
+#define CDT_CTRL_ASYNC_WSTS_1 (0x1 << 14)
+#define CDT_CTRL_ASYNC_RSTS_1 (0x1 << 15)
+#define CDT_BD_SHIFT (0)
+#define CDT_BA_SHIFT (16)
+#define CDT_BS_SHIFT (0)
+#define CDT_BF_SHIFT (31)
+
+#define ADT_PG (0x1 << 13)
+#define ADT_LE (0x1 << 14)
+#define ADT_CE (0x1 << 15)
+#define ADT_BD1_SHIFT (0)
+#define ADT_ERR1 (0x1 << 13)
+#define ADT_DNE1 (0x1 << 14)
+#define ADT_RDY1 (0x1 << 15)
+#define ADT_BD2_SHIFT (16)
+#define ADT_ERR2 (0x1 << 29)
+#define ADT_DNE2 (0x1 << 30)
+#define ADT_RDY2 (0x1 << 31)
+#define ADT_BA1_SHIFT (0x0)
+#define ADT_BA2_SHIFT (0x0)
+#define ADT_PS1 (0x1 << 12)
+#define ADT_PS2 (0x1 << 28)
+#define ADT_MEP1 (0x1 << 11)
+#define ADT_MEP2 (0x1 << 27)
+
+#define MLB_MINOR_DEVICES 4
+#define MLB_CONTROL_DEV_NAME "ctrl"
+#define MLB_ASYNC_DEV_NAME "async"
+#define MLB_SYNC_DEV_NAME "sync"
+#define MLB_ISOC_DEV_NAME "isoc"
+
+#define TX_CHANNEL 0
+#define RX_CHANNEL 1
+
+#define TRANS_RING_NODES (1 << 3)
+#define MLB_QUIRK_MLB150 (1 << 0)
+
+enum MLB_CTYPE {
+ MLB_CTYPE_SYNC,
+ MLB_CTYPE_CTRL,
+ MLB_CTYPE_ASYNC,
+ MLB_CTYPE_ISOC,
+};
+
+enum CLK_SPEED {
+ CLK_256FS,
+ CLK_512FS,
+ CLK_1024FS,
+ CLK_2048FS,
+ CLK_3072FS,
+ CLK_4096FS,
+ CLK_6144FS,
+ CLK_8192FS,
+};
+
+enum MLB_INDEX {
+ IMX6Q_MLB = 0,
+ IMX6SX_MLB,
+};
+
+struct mlb_ringbuf {
+ s8 *virt_bufs[TRANS_RING_NODES];
+ u32 phy_addrs[TRANS_RING_NODES];
+ s32 head;
+ s32 tail;
+ s32 unit_size;
+ s32 total_size;
+ rwlock_t rb_lock ____cacheline_aligned; /* ring index lock */
+};
+
+struct mlb_channel_info {
+ /* Input MLB channel address */
+ u32 address;
+ /* Internal AHB channel label */
+ u32 cl;
+ /* DBR buf head */
+ u32 dbr_buf_head;
+};
+
+struct mlb_dev_info {
+ /* device node name */
+ const char dev_name[20];
+ /* channel type */
+ const unsigned int channel_type;
+ /* ch fps */
+ enum CLK_SPEED fps;
+ /* channel info for tx/rx */
+ struct mlb_channel_info channels[2];
+ /* ring buffer */
+ u8 *rbuf_base_virt;
+ u32 rbuf_base_phy;
+ struct mlb_ringbuf rx_rbuf;
+ struct mlb_ringbuf tx_rbuf;
+ /* exception event */
+ unsigned long ex_event;
+ /* tx busy indicator */
+ unsigned long tx_busy;
+ /* channel started up or not */
+ atomic_t on;
+ /* device open count */
+ atomic_t opencnt;
+ /* wait queue head for channel */
+ wait_queue_head_t rx_wq;
+ wait_queue_head_t tx_wq;
+ /* TX OK */
+ s32 tx_ok;
+ /* spinlock for event access */
+ spinlock_t event_lock;
+ /*
+ * Block size for isoc mode
+ * This variable can be configured in ioctl
+ */
+ u32 isoc_blksz;
+ /*
+ * Quads number for sync mode
+ * This variable can be confifured in ioctl
+ */
+ u32 sync_quad;
+ /* Buffer depth in cdt */
+ u32 cdt_buf_dep;
+ /* Buffer depth in adt */
+ u32 adt_buf_dep;
+ /* Buffer size to hold data */
+ u32 buf_size;
+};
+
+struct mlb_data {
+ struct device *dev;
+ struct mlb_dev_info *devinfo;
+#ifdef CONFIG_ARCH_MXC_ARM64
+ struct clk *ipg;
+ struct clk *hclk;
+#endif
+ struct clk *mlb;
+ struct cdev cdev;
+ struct class *class; /* device class */
+ dev_t firstdev;
+#ifdef CONFIG_REGULATOR
+ struct regulator *nvcc;
+#endif
+ void __iomem *membase; /* mlb module base address */
+ struct gen_pool *iram_pool;
+ u32 iram_size;
+ int irq_ahb0;
+ int irq_ahb1;
+ int irq_mlb;
+ u32 quirk_flag;
+ bool use_iram;
+};
+
+/*
+ * For optimization, we use fixed channel label for
+ * input channels of each mode
+ * SYNC: CL = 0 for RX, CL = 64 for TX
+ * CTRL: CL = 1 for RX, CL = 65 for TX
+ * ASYNC: CL = 2 for RX, CL = 66 for TX
+ * ISOC: CL = 3 for RX, CL = 67 for TX
+ */
+#define SYNC_RX_CL_AHB0 0
+#define CTRL_RX_CL_AHB0 1
+#define ASYNC_RX_CL_AHB0 2
+#define ISOC_RX_CL_AHB0 3
+#define SYNC_TX_CL_AHB0 4
+#define CTRL_TX_CL_AHB0 5
+#define ASYNC_TX_CL_AHB0 6
+#define ISOC_TX_CL_AHB0 7
+
+#define SYNC_RX_CL_AHB1 32
+#define CTRL_RX_CL_AHB1 33
+#define ASYNC_RX_CL_AHB1 34
+#define ISOC_RX_CL_AHB1 35
+#define SYNC_TX_CL_AHB1 36
+#define CTRL_TX_CL_AHB1 37
+#define ASYNC_TX_CL_AHB1 38
+#define ISOC_TX_CL_AHB1 39
+
+#define SYNC_RX_CL SYNC_RX_CL_AHB0
+#define CTRL_RX_CL CTRL_RX_CL_AHB0
+#define ASYNC_RX_CL ASYNC_RX_CL_AHB0
+#define ISOC_RX_CL ISOC_RX_CL_AHB0
+
+#define SYNC_TX_CL SYNC_TX_CL_AHB0
+#define CTRL_TX_CL CTRL_TX_CL_AHB0
+#define ASYNC_TX_CL ASYNC_TX_CL_AHB0
+#define ISOC_TX_CL ISOC_TX_CL_AHB0
+
+static struct mlb_dev_info mlb_devinfo[MLB_MINOR_DEVICES] = {
+ {
+ .dev_name = MLB_SYNC_DEV_NAME,
+ .channel_type = MLB_CTYPE_SYNC,
+ .channels = {
+ [0] = {
+ .cl = SYNC_TX_CL,
+ .dbr_buf_head = CH_SYNC_DBR_BUF_OFFSET,
+ },
+ [1] = {
+ .cl = SYNC_RX_CL,
+ .dbr_buf_head = CH_SYNC_DBR_BUF_OFFSET
+ + CH_SYNC_BUF_SZ,
+ },
+ },
+ .rx_rbuf = {
+ .unit_size = CH_SYNC_BUF_SZ,
+ .rb_lock =
+ __RW_LOCK_UNLOCKED(mlb_devinfo[0].rx_rbuf.rb_lock),
+ },
+ .tx_rbuf = {
+ .unit_size = CH_SYNC_BUF_SZ,
+ .rb_lock =
+ __RW_LOCK_UNLOCKED(mlb_devinfo[0].tx_rbuf.rb_lock),
+ },
+ .cdt_buf_dep = CH_SYNC_CDT_BUF_DEP,
+ .adt_buf_dep = CH_SYNC_ADT_BUF_DEP,
+ .buf_size = CH_SYNC_BUF_SZ,
+ .on = ATOMIC_INIT(0),
+ .opencnt = ATOMIC_INIT(0),
+ .event_lock = __SPIN_LOCK_UNLOCKED(mlb_devinfo[0].event_lock),
+ },
+ {
+ .dev_name = MLB_CONTROL_DEV_NAME,
+ .channel_type = MLB_CTYPE_CTRL,
+ .channels = {
+ [0] = {
+ .cl = CTRL_TX_CL,
+ .dbr_buf_head = CH_CTRL_DBR_BUF_OFFSET,
+ },
+ [1] = {
+ .cl = CTRL_RX_CL,
+ .dbr_buf_head = CH_CTRL_DBR_BUF_OFFSET
+ + CH_CTRL_BUF_SZ,
+ },
+ },
+ .rx_rbuf = {
+ .unit_size = CH_CTRL_BUF_SZ,
+ .rb_lock =
+ __RW_LOCK_UNLOCKED(mlb_devinfo[1].rx_rbuf.rb_lock),
+ },
+ .tx_rbuf = {
+ .unit_size = CH_CTRL_BUF_SZ,
+ .rb_lock =
+ __RW_LOCK_UNLOCKED(mlb_devinfo[1].tx_rbuf.rb_lock),
+ },
+ .cdt_buf_dep = CH_CTRL_CDT_BUF_DEP,
+ .adt_buf_dep = CH_CTRL_ADT_BUF_DEP,
+ .buf_size = CH_CTRL_BUF_SZ,
+ .on = ATOMIC_INIT(0),
+ .opencnt = ATOMIC_INIT(0),
+ .event_lock = __SPIN_LOCK_UNLOCKED(mlb_devinfo[1].event_lock),
+ },
+ {
+ .dev_name = MLB_ASYNC_DEV_NAME,
+ .channel_type = MLB_CTYPE_ASYNC,
+ .channels = {
+ [0] = {
+ .cl = ASYNC_TX_CL,
+ .dbr_buf_head = CH_ASYNC_DBR_BUF_OFFSET,
+ },
+ [1] = {
+ .cl = ASYNC_RX_CL,
+ .dbr_buf_head = CH_ASYNC_DBR_BUF_OFFSET
+ + CH_ASYNC_BUF_SZ,
+ },
+ },
+ .rx_rbuf = {
+ .unit_size = CH_ASYNC_BUF_SZ,
+ .rb_lock =
+ __RW_LOCK_UNLOCKED(mlb_devinfo[2].rx_rbuf.rb_lock),
+ },
+ .tx_rbuf = {
+ .unit_size = CH_ASYNC_BUF_SZ,
+ .rb_lock =
+ __RW_LOCK_UNLOCKED(mlb_devinfo[2].tx_rbuf.rb_lock),
+ },
+ .cdt_buf_dep = CH_ASYNC_CDT_BUF_DEP,
+ .adt_buf_dep = CH_ASYNC_ADT_BUF_DEP,
+ .buf_size = CH_ASYNC_BUF_SZ,
+ .on = ATOMIC_INIT(0),
+ .opencnt = ATOMIC_INIT(0),
+ .event_lock = __SPIN_LOCK_UNLOCKED(mlb_devinfo[2].event_lock),
+ },
+ {
+ .dev_name = MLB_ISOC_DEV_NAME,
+ .channel_type = MLB_CTYPE_ISOC,
+ .channels = {
+ [0] = {
+ .cl = ISOC_TX_CL,
+ .dbr_buf_head = CH_ISOC_DBR_BUF_OFFSET,
+ },
+ [1] = {
+ .cl = ISOC_RX_CL,
+ .dbr_buf_head = CH_ISOC_DBR_BUF_OFFSET
+ + CH_ISOC_BUF_SZ,
+ },
+ },
+ .rx_rbuf = {
+ .unit_size = CH_ISOC_BUF_SZ,
+ .rb_lock =
+ __RW_LOCK_UNLOCKED(mlb_devinfo[3].rx_rbuf.rb_lock),
+ },
+ .tx_rbuf = {
+ .unit_size = CH_ISOC_BUF_SZ,
+ .rb_lock =
+ __RW_LOCK_UNLOCKED(mlb_devinfo[3].tx_rbuf.rb_lock),
+ },
+ .cdt_buf_dep = CH_ISOC_CDT_BUF_DEP,
+ .adt_buf_dep = CH_ISOC_ADT_BUF_DEP,
+ .buf_size = CH_ISOC_BUF_SZ,
+ .on = ATOMIC_INIT(0),
+ .opencnt = ATOMIC_INIT(0),
+ .event_lock = __SPIN_LOCK_UNLOCKED(mlb_devinfo[3].event_lock),
+ .isoc_blksz = CH_ISOC_BLK_SIZE_188,
+ },
+};
+
+static void __iomem *mlb_base;
+
+DEFINE_SPINLOCK(ctr_lock);
+
+#ifdef DEBUG
+#define DUMP_REG(reg) pr_debug(#reg": 0x%08x\n", __raw_readl(mlb_base + reg))
+
+static void mlb150_dev_dump_reg(void)
+{
+ pr_debug("mxc_mlb150: Dump registers:\n");
+ DUMP_REG(REG_MLBC0);
+ DUMP_REG(REG_MLBPC0);
+ DUMP_REG(REG_MS0);
+ DUMP_REG(REG_MS1);
+ DUMP_REG(REG_MSS);
+ DUMP_REG(REG_MSD);
+ DUMP_REG(REG_MIEN);
+ DUMP_REG(REG_MLBPC2);
+ DUMP_REG(REG_MLBPC1);
+ DUMP_REG(REG_MLBC1);
+ DUMP_REG(REG_HCTL);
+ DUMP_REG(REG_HCMR0);
+ DUMP_REG(REG_HCMR1);
+ DUMP_REG(REG_HCER0);
+ DUMP_REG(REG_HCER1);
+ DUMP_REG(REG_HCBR0);
+ DUMP_REG(REG_HCBR1);
+ DUMP_REG(REG_MDAT0);
+ DUMP_REG(REG_MDAT1);
+ DUMP_REG(REG_MDAT2);
+ DUMP_REG(REG_MDAT3);
+ DUMP_REG(REG_MDWE0);
+ DUMP_REG(REG_MDWE1);
+ DUMP_REG(REG_MDWE2);
+ DUMP_REG(REG_MDWE3);
+ DUMP_REG(REG_MCTL);
+ DUMP_REG(REG_MADR);
+ DUMP_REG(REG_ACTL);
+ DUMP_REG(REG_ACSR0);
+ DUMP_REG(REG_ACSR1);
+ DUMP_REG(REG_ACMR0);
+ DUMP_REG(REG_ACMR1);
+}
+
+static void mlb150_dev_dump_hex(const u8 *buf, u32 len)
+{
+ print_hex_dump(KERN_DEBUG, "CTR DUMP:",
+ DUMP_PREFIX_OFFSET, 8, 1, buf, len, 0);
+}
+#endif
+
+static inline void mlb150_dev_enable_ctr_write(u32 mdat0_bits_en,
+ u32 mdat1_bits_en, u32 mdat2_bits_en, u32 mdat3_bits_en)
+{
+ __raw_writel(mdat0_bits_en, mlb_base + REG_MDWE0);
+ __raw_writel(mdat1_bits_en, mlb_base + REG_MDWE1);
+ __raw_writel(mdat2_bits_en, mlb_base + REG_MDWE2);
+ __raw_writel(mdat3_bits_en, mlb_base + REG_MDWE3);
+}
+
+#ifdef DEBUG
+static inline u8 mlb150_dev_dbr_read(u32 dbr_addr)
+{
+ s32 timeout = 1000;
+ u8 dbr_val = 0;
+ unsigned long flags;
+
+ spin_lock_irqsave(&ctr_lock, flags);
+ __raw_writel(MADR_TB | dbr_addr,
+ mlb_base + REG_MADR);
+
+ while ((!(__raw_readl(mlb_base + REG_MCTL)
+ & MCTL_XCMP)) &&
+ timeout--)
+ ;
+
+ if (0 == timeout) {
+ spin_unlock_irqrestore(&ctr_lock, flags);
+ return -ETIME;
+ }
+
+ dbr_val = __raw_readl(mlb_base + REG_MDAT0) & 0x000000ff;
+
+ __raw_writel(0, mlb_base + REG_MCTL);
+ spin_unlock_irqrestore(&ctr_lock, flags);
+
+ return dbr_val;
+}
+
+static inline s32 mlb150_dev_dbr_write(u32 dbr_addr, u8 dbr_val)
+{
+ s32 timeout = 1000;
+ u32 mdat0 = dbr_val & 0x000000ff;
+ unsigned long flags;
+
+ spin_lock_irqsave(&ctr_lock, flags);
+ __raw_writel(mdat0, mlb_base + REG_MDAT0);
+
+ __raw_writel(MADR_WNR | MADR_TB | dbr_addr,
+ mlb_base + REG_MADR);
+
+ while ((!(__raw_readl(mlb_base + REG_MCTL)
+ & MCTL_XCMP)) &&
+ timeout--)
+ ;
+
+ if (timeout <= 0) {
+ spin_unlock_irqrestore(&ctr_lock, flags);
+ return -ETIME;
+ }
+
+ __raw_writel(0, mlb_base + REG_MCTL);
+ spin_unlock_irqrestore(&ctr_lock, flags);
+
+ return 0;
+}
+
+static inline s32 mlb150_dev_dbr_dump(u32 addr, u32 size)
+{
+ u8 *dump_buf = NULL;
+ u8 *buf_ptr = NULL;
+ s32 i;
+
+ dump_buf = kzalloc(size, GFP_KERNEL);
+ if (!dump_buf) {
+ pr_err("can't allocate enough memory\n");
+ return -ENOMEM;
+ }
+
+ for (i = 0, buf_ptr = dump_buf;
+ i < size; ++i, ++buf_ptr)
+ *buf_ptr = mlb150_dev_dbr_read(addr + i);
+
+ mlb150_dev_dump_hex(dump_buf, size);
+
+ kfree(dump_buf);
+
+ return 0;
+}
+#endif
+
+static s32 mlb150_dev_ctr_read(u32 ctr_offset, u32 *ctr_val)
+{
+ s32 timeout = 1000;
+ unsigned long flags;
+
+ spin_lock_irqsave(&ctr_lock, flags);
+ __raw_writel(ctr_offset, mlb_base + REG_MADR);
+
+ while ((!(__raw_readl(mlb_base + REG_MCTL)
+ & MCTL_XCMP)) &&
+ timeout--)
+ ;
+
+ if (timeout <= 0) {
+ spin_unlock_irqrestore(&ctr_lock, flags);
+ pr_debug("mxc_mlb150: Read CTR timeout\n");
+ return -ETIME;
+ }
+
+ ctr_val[0] = __raw_readl(mlb_base + REG_MDAT0);
+ ctr_val[1] = __raw_readl(mlb_base + REG_MDAT1);
+ ctr_val[2] = __raw_readl(mlb_base + REG_MDAT2);
+ ctr_val[3] = __raw_readl(mlb_base + REG_MDAT3);
+
+ __raw_writel(0, mlb_base + REG_MCTL);
+
+ spin_unlock_irqrestore(&ctr_lock, flags);
+
+ return 0;
+}
+
+static s32 mlb150_dev_ctr_write(u32 ctr_offset, const u32 *ctr_val)
+{
+ s32 timeout = 1000;
+ unsigned long flags;
+
+ spin_lock_irqsave(&ctr_lock, flags);
+
+ __raw_writel(ctr_val[0], mlb_base + REG_MDAT0);
+ __raw_writel(ctr_val[1], mlb_base + REG_MDAT1);
+ __raw_writel(ctr_val[2], mlb_base + REG_MDAT2);
+ __raw_writel(ctr_val[3], mlb_base + REG_MDAT3);
+
+ __raw_writel(MADR_WNR | ctr_offset,
+ mlb_base + REG_MADR);
+
+ while ((!(__raw_readl(mlb_base + REG_MCTL)
+ & MCTL_XCMP)) &&
+ timeout--)
+ ;
+
+ if (timeout <= 0) {
+ spin_unlock_irqrestore(&ctr_lock, flags);
+ pr_debug("mxc_mlb150: Write CTR timeout\n");
+ return -ETIME;
+ }
+
+ __raw_writel(0, mlb_base + REG_MCTL);
+
+ spin_unlock_irqrestore(&ctr_lock, flags);
+
+#ifdef DEBUG_CTR
+ {
+ u32 ctr_rd[4] = { 0 };
+
+ if (!mlb150_dev_ctr_read(ctr_offset, ctr_rd)) {
+ if (ctr_val[0] == ctr_rd[0] &&
+ ctr_val[1] == ctr_rd[1] &&
+ ctr_val[2] == ctr_rd[2] &&
+ ctr_val[3] == ctr_rd[3])
+ return 0;
+ else {
+ pr_debug("mxc_mlb150: ctr write failed\n");
+ pr_debug("offset: 0x%x\n", ctr_offset);
+ pr_debug("Write: 0x%x 0x%x 0x%x 0x%x\n",
+ ctr_val[3], ctr_val[2],
+ ctr_val[1], ctr_val[0]);
+ pr_debug("Read: 0x%x 0x%x 0x%x 0x%x\n",
+ ctr_rd[3], ctr_rd[2],
+ ctr_rd[1], ctr_rd[0]);
+ return -EBADE;
+ }
+ } else {
+ pr_debug("mxc_mlb150: ctr read failed\n");
+ return -EBADE;
+ }
+ }
+#endif
+
+ return 0;
+}
+
+#ifdef DEBUG
+static s32 mlb150_dev_cat_read(u32 ctr_offset, u32 ch, u16 *cat_val)
+{
+ u16 ctr_val[8] = { 0 };
+
+ if (mlb150_dev_ctr_read(ctr_offset, (u32 *)ctr_val))
+ return -ETIME;
+
+ /*
+ * Use u16 array to get u32 array value,
+ * need to convert
+ */
+ cat_val = ctr_val[ch % 8];
+
+ return 0;
+}
+#endif
+
+static s32 mlb150_dev_cat_write(u32 ctr_offset, u32 ch, const u16 cat_val)
+{
+ u16 ctr_val[8] = { 0 };
+
+ if (mlb150_dev_ctr_read(ctr_offset, (u32 *)ctr_val))
+ return -ETIME;
+
+ ctr_val[ch % 8] = cat_val;
+ if (mlb150_dev_ctr_write(ctr_offset, (u32 *)ctr_val))
+ return -ETIME;
+
+ return 0;
+}
+
+#define mlb150_dev_cat_mlb_read(ch, cat_val) \
+ mlb150_dev_cat_read(BUF_CAT_MLB_OFFSET + (ch >> 3), ch, cat_val)
+#define mlb150_dev_cat_mlb_write(ch, cat_val) \
+ mlb150_dev_cat_write(BUF_CAT_MLB_OFFSET + (ch >> 3), ch, cat_val)
+#define mlb150_dev_cat_hbi_read(ch, cat_val) \
+ mlb150_dev_cat_read(BUF_CAT_HBI_OFFSET + (ch >> 3), ch, cat_val)
+#define mlb150_dev_cat_hbi_write(ch, cat_val) \
+ mlb150_dev_cat_write(BUF_CAT_HBI_OFFSET + (ch >> 3), ch, cat_val)
+
+#define mlb150_dev_cdt_read(ch, cdt_val) \
+ mlb150_dev_ctr_read(BUF_CDT_OFFSET + ch, cdt_val)
+#define mlb150_dev_cdt_write(ch, cdt_val) \
+ mlb150_dev_ctr_write(BUF_CDT_OFFSET + ch, cdt_val)
+#define mlb150_dev_adt_read(ch, adt_val) \
+ mlb150_dev_ctr_read(BUF_ADT_OFFSET + ch, adt_val)
+#define mlb150_dev_adt_write(ch, adt_val) \
+ mlb150_dev_ctr_write(BUF_ADT_OFFSET + ch, adt_val)
+
+static s32 mlb150_dev_get_adt_sts(u32 ch)
+{
+ s32 timeout = 1000;
+ unsigned long flags;
+ u32 reg;
+
+ spin_lock_irqsave(&ctr_lock, flags);
+ __raw_writel(BUF_ADT_OFFSET + ch,
+ mlb_base + REG_MADR);
+
+ while ((!(__raw_readl(mlb_base + REG_MCTL)
+ & MCTL_XCMP)) &&
+ timeout--)
+ ;
+
+ if (timeout <= 0) {
+ spin_unlock_irqrestore(&ctr_lock, flags);
+ pr_debug("mxc_mlb150: Read CTR timeout\n");
+ return -ETIME;
+ }
+
+ reg = __raw_readl(mlb_base + REG_MDAT1);
+
+ __raw_writel(0, mlb_base + REG_MCTL);
+ spin_unlock_irqrestore(&ctr_lock, flags);
+
+#ifdef DEBUG_ADT
+ pr_debug("mxc_mlb150: Get ch %d adt sts: 0x%08x\n", ch, reg);
+#endif
+
+ return reg;
+}
+
+#ifdef DEBUG
+static void mlb150_dev_dump_ctr_tbl(u32 ch_start, u32 ch_end)
+{
+ u32 i = 0;
+ u32 ctr_val[4] = { 0 };
+
+ pr_debug("mxc_mlb150: CDT Table");
+ for (i = BUF_CDT_OFFSET + ch_start;
+ i < BUF_CDT_OFFSET + ch_end;
+ ++i) {
+ mlb150_dev_ctr_read(i, ctr_val);
+ pr_debug("CTR 0x%02x: 0x%08x, 0x%08x, 0x%08x, 0x%08x\n",
+ i, ctr_val[3], ctr_val[2], ctr_val[1], ctr_val[0]);
+ }
+
+ pr_debug("mxc_mlb150: ADT Table");
+ for (i = BUF_ADT_OFFSET + ch_start;
+ i < BUF_ADT_OFFSET + ch_end;
+ ++i) {
+ mlb150_dev_ctr_read(i, ctr_val);
+ pr_debug("CTR 0x%02x: 0x%08x, 0x%08x, 0x%08x, 0x%08x\n",
+ i, ctr_val[3], ctr_val[2], ctr_val[1], ctr_val[0]);
+ }
+
+ pr_debug("mxc_mlb150: CAT MLB Table");
+ for (i = BUF_CAT_MLB_OFFSET + (ch_start >> 3);
+ i <= BUF_CAT_MLB_OFFSET + ((ch_end + 8) >> 3);
+ ++i) {
+ mlb150_dev_ctr_read(i, ctr_val);
+ pr_debug("CTR 0x%02x: 0x%08x, 0x%08x, 0x%08x, 0x%08x\n",
+ i, ctr_val[3], ctr_val[2], ctr_val[1], ctr_val[0]);
+ }
+
+ pr_debug("mxc_mlb150: CAT HBI Table");
+ for (i = BUF_CAT_HBI_OFFSET + (ch_start >> 3);
+ i <= BUF_CAT_HBI_OFFSET + ((ch_end + 8) >> 3);
+ ++i) {
+ mlb150_dev_ctr_read(i, ctr_val);
+ pr_debug("CTR 0x%02x: 0x%08x, 0x%08x, 0x%08x, 0x%08x\n",
+ i, ctr_val[3], ctr_val[2], ctr_val[1], ctr_val[0]);
+ }
+}
+#endif
+
+/*
+ * Initial the MLB module device
+ */
+static inline void mlb150_dev_enable_dma_irq(u32 enable)
+{
+ u32 ch_rx_mask = (1 << SYNC_RX_CL_AHB0) | (1 << CTRL_RX_CL_AHB0)
+ | (1 << ASYNC_RX_CL_AHB0) | (1 << ISOC_RX_CL_AHB0)
+ | (1 << SYNC_TX_CL_AHB0) | (1 << CTRL_TX_CL_AHB0)
+ | (1 << ASYNC_TX_CL_AHB0) | (1 << ISOC_TX_CL_AHB0);
+ u32 ch_tx_mask = (1 << (SYNC_RX_CL_AHB1 - INT_AHB1_CH_START)) |
+ (1 << (CTRL_RX_CL_AHB1 - INT_AHB1_CH_START)) |
+ (1 << (ASYNC_RX_CL_AHB1 - INT_AHB1_CH_START)) |
+ (1 << (ISOC_RX_CL_AHB1 - INT_AHB1_CH_START)) |
+ (1 << (SYNC_TX_CL_AHB1 - INT_AHB1_CH_START)) |
+ (1 << (CTRL_TX_CL_AHB1 - INT_AHB1_CH_START)) |
+ (1 << (ASYNC_TX_CL_AHB1 - INT_AHB1_CH_START)) |
+ (1 << (ISOC_TX_CL_AHB1 - INT_AHB1_CH_START));
+
+ if (enable) {
+ __raw_writel(ch_rx_mask, mlb_base + REG_ACMR0);
+ __raw_writel(ch_tx_mask, mlb_base + REG_ACMR1);
+ } else {
+ __raw_writel(0x0, mlb_base + REG_ACMR0);
+ __raw_writel(0x0, mlb_base + REG_ACMR1);
+ }
+}
+
+
+static void mlb150_dev_init_ir_amba_ahb(void)
+{
+ u32 reg = 0;
+
+ /*
+ * Step 1. Program the ACMRn registers to enable interrupts from all
+ * active DMA channels
+ */
+ mlb150_dev_enable_dma_irq(1);
+
+ /*
+ * Step 2. Select the status clear method:
+ * ACTL.SCE = 0, hardware clears on read
+ * ACTL.SCE = 1, software writes a '1' to clear
+ * We only support DMA MODE 1
+ */
+ reg = __raw_readl(mlb_base + REG_ACTL);
+ reg |= ACTL_DMAMODE;
+#ifdef MULTIPLE_PACKAGE_MODE
+ reg |= REG_ACTL_MPB;
+#endif
+
+ /*
+ * Step 3. Select 1 or 2 interrupt signals:
+ * ACTL.SMX = 0: one interrupt for channels 0 - 31 on ahb_init[0]
+ * and another interrupt for channels 32 - 63 on ahb_init[1]
+ * ACTL.SMX = 1: singel interrupt all channels on ahb_init[0]
+ */
+ reg &= ~ACTL_SMX;
+
+ __raw_writel(reg, mlb_base + REG_ACTL);
+}
+
+static inline void mlb150_dev_enable_ir_mlb(u32 enable)
+{
+ /*
+ * Step 1, Select the MSn to be cleared by software,
+ * writing a '0' to the appropriate bits
+ */
+ __raw_writel(0, mlb_base + REG_MS0);
+ __raw_writel(0, mlb_base + REG_MS1);
+
+ /*
+ * Step 1, Program MIEN to enable protocol error
+ * interrupts for all active MLB channels
+ */
+ if (enable)
+ __raw_writel(MIEN_CTX_PE |
+ MIEN_CRX_PE | MIEN_ATX_PE |
+ MIEN_ARX_PE | MIEN_SYNC_PE |
+ MIEN_ISOC_PE,
+ mlb_base + REG_MIEN);
+ else
+ __raw_writel(0, mlb_base + REG_MIEN);
+}
+
+static inline void mlb150_enable_pll(struct mlb_data *drvdata)
+{
+ u32 c0_val;
+
+ __raw_writel(MLBPC1_VAL,
+ drvdata->membase + REG_MLBPC1);
+
+ c0_val = __raw_readl(drvdata->membase + REG_MLBC0);
+ if (c0_val & MLBC0_MLBPEN) {
+ c0_val &= ~MLBC0_MLBPEN;
+ __raw_writel(c0_val,
+ drvdata->membase + REG_MLBC0);
+ }
+
+ c0_val |= (MLBC0_MLBPEN);
+ __raw_writel(c0_val, drvdata->membase + REG_MLBC0);
+}
+
+static inline void mlb150_disable_pll(struct mlb_data *drvdata)
+{
+ u32 c0_val;
+
+ c0_val = __raw_readl(drvdata->membase + REG_MLBC0);
+
+ __raw_writel(0x0, drvdata->membase + REG_MLBPC1);
+
+ c0_val &= ~MLBC0_MLBPEN;
+ __raw_writel(c0_val, drvdata->membase + REG_MLBC0);
+}
+
+static void mlb150_dev_reset_cdt(void)
+{
+ int i = 0;
+ u32 ctr_val[4] = { 0 };
+
+ mlb150_dev_enable_ctr_write(0xffffffff, 0xffffffff,
+ 0xffffffff, 0xffffffff);
+
+ for (i = 0; i < (LOGIC_CH_NUM); ++i)
+ mlb150_dev_ctr_write(BUF_CDT_OFFSET + i, ctr_val);
+}
+
+static s32 mlb150_dev_init_ch_cdt(struct mlb_dev_info *pdevinfo, u32 ch,
+ enum MLB_CTYPE ctype, u32 ch_func)
+{
+ u32 cdt_val[4] = { 0 };
+
+ /* a. Set the 14-bit base address (BA) */
+ pr_debug("mxc_mlb150: ctype: %d, ch: %d, dbr_buf_head: 0x%08x",
+ ctype, ch, pdevinfo->channels[ch_func].dbr_buf_head);
+ cdt_val[3] = (pdevinfo->channels[ch_func].dbr_buf_head)
+ << CDT_BA_SHIFT;
+ /*
+ * b. Set the 12-bit or 13-bit buffer depth (BD)
+ * BD = buffer depth in bytes - 1
+ * For synchronous channels: (BD + 1) = 4 * m * bpf
+ * For control channels: (BD + 1) >= max packet length (64)
+ * For asynchronous channels: (BD + 1) >= max packet length
+ * 1024 for a MOST Data packet (MDP);
+ * 1536 for a MOST Ethernet Packet (MEP)
+ * For isochronous channels: (BD + 1) mod (BS + 1) = 0
+ * BS
+ */
+ if (MLB_CTYPE_ISOC == ctype)
+ cdt_val[1] |= (pdevinfo->isoc_blksz - 1);
+ /* BD */
+ cdt_val[3] |= (pdevinfo->cdt_buf_dep - 1) << CDT_BD_SHIFT;
+
+ pr_debug("mxc_mlb150: Set CDT val of channel %d, type: %d: "
+ "0x%08x 0x%08x 0x%08x 0x%08x\n",
+ ch, ctype, cdt_val[3], cdt_val[2], cdt_val[1], cdt_val[0]);
+
+ if (mlb150_dev_cdt_write(ch, cdt_val))
+ return -ETIME;
+
+#ifdef DEBUG_CTR
+ {
+ u32 cdt_rd[4] = { 0 };
+ if (!mlb150_dev_cdt_read(ch, cdt_rd)) {
+ pr_debug("mxc_mlb150: CDT val of channel %d: "
+ "0x%08x 0x%08x 0x%08x 0x%08x\n",
+ ch, cdt_rd[3], cdt_rd[2], cdt_rd[1], cdt_rd[0]);
+ if (cdt_rd[3] == cdt_val[3] &&
+ cdt_rd[2] == cdt_val[2] &&
+ cdt_rd[1] == cdt_val[1] &&
+ cdt_rd[0] == cdt_val[0]) {
+ pr_debug("mxc_mlb150: set cdt succeed!\n");
+ return 0;
+ } else {
+ pr_debug("mxc_mlb150: set cdt failed!\n");
+ return -EBADE;
+ }
+ } else {
+ pr_debug("mxc_mlb150: Read CDT val of channel %d failed\n",
+ ch);
+ return -EBADE;
+ }
+ }
+#endif
+
+ return 0;
+}
+
+static s32 mlb150_dev_init_ch_cat(u32 ch, u32 cl,
+ u32 cat_mode, enum MLB_CTYPE ctype)
+{
+ u16 cat_val = 0;
+#ifdef DEBUG_CTR
+ u16 cat_rd = 0;
+#endif
+
+ cat_val = CAT_CE | (ctype << CAT_CT_SHIFT) | cl;
+
+ if (cat_mode & CAT_MODE_OUTBOUND_DMA)
+ cat_val |= CAT_RNW;
+
+ if (MLB_CTYPE_SYNC == ctype)
+ cat_val |= CAT_MT;
+
+ switch (cat_mode) {
+ case CAT_MODE_RX | CAT_MODE_INBOUND_DMA:
+ case CAT_MODE_TX | CAT_MODE_OUTBOUND_DMA:
+ pr_debug("mxc_mlb150: set CAT val of channel %d, type: %d: 0x%04x\n",
+ ch, ctype, cat_val);
+
+ if (mlb150_dev_cat_mlb_write(ch, cat_val))
+ return -ETIME;
+#ifdef DEBUG_CTR
+ if (!mlb150_dev_cat_mlb_read(ch, &cat_rd))
+ pr_debug("mxc_mlb150: CAT val of mlb channel %d: 0x%04x",
+ ch, cat_rd);
+ else {
+ pr_debug("mxc_mlb150: Read CAT of mlb channel %d failed\n",
+ ch);
+ return -EBADE;
+ }
+#endif
+ break;
+ case CAT_MODE_TX | CAT_MODE_INBOUND_DMA:
+ case CAT_MODE_RX | CAT_MODE_OUTBOUND_DMA:
+ pr_debug("mxc_mlb150: set CAT val of channel %d, type: %d: 0x%04x\n",
+ cl, ctype, cat_val);
+
+ if (mlb150_dev_cat_hbi_write(cl, cat_val))
+ return -ETIME;
+#ifdef DEBUG_CTR
+ if (!mlb150_dev_cat_hbi_read(cl, &cat_rd))
+ pr_debug("mxc_mlb150: CAT val of hbi channel %d: 0x%04x",
+ cl, cat_rd);
+ else {
+ pr_debug("mxc_mlb150: Read CAT of hbi channel %d failed\n",
+ cl);
+ return -EBADE;
+ }
+#endif
+ break;
+ default:
+ return EBADRQC;
+ }
+
+#ifdef DEBUG_CTR
+ {
+ if (cat_val == cat_rd) {
+ pr_debug("mxc_mlb150: set cat succeed!\n");
+ return 0;
+ } else {
+ pr_debug("mxc_mlb150: set cat failed!\n");
+ return -EBADE;
+ }
+ }
+#endif
+ return 0;
+}
+
+static void mlb150_dev_reset_cat(void)
+{
+ int i = 0;
+ u32 ctr_val[4] = { 0 };
+
+ mlb150_dev_enable_ctr_write(0xffffffff, 0xffffffff,
+ 0xffffffff, 0xffffffff);
+
+ for (i = 0; i < (LOGIC_CH_NUM >> 3); ++i) {
+ mlb150_dev_ctr_write(BUF_CAT_MLB_OFFSET + i, ctr_val);
+ mlb150_dev_ctr_write(BUF_CAT_HBI_OFFSET + i, ctr_val);
+ }
+}
+
+static void mlb150_dev_init_rfb(struct mlb_dev_info *pdevinfo, u32 rx_ch,
+ u32 tx_ch, enum MLB_CTYPE ctype)
+{
+ u32 rx_cl = pdevinfo->channels[RX_CHANNEL].cl;
+ u32 tx_cl = pdevinfo->channels[TX_CHANNEL].cl;
+ /* Step 1, Initialize all bits of CAT to '0' */
+ mlb150_dev_reset_cat();
+ mlb150_dev_reset_cdt();
+ /*
+ * Step 2, Initialize logical channel
+ * Step 3, Program the CDT for channel N
+ */
+ mlb150_dev_init_ch_cdt(pdevinfo, rx_cl, ctype, RX_CHANNEL);
+ mlb150_dev_init_ch_cdt(pdevinfo, tx_cl, ctype, TX_CHANNEL);
+
+ /* Step 4&5, Program the CAT for the inbound and outbound DMA */
+ mlb150_dev_init_ch_cat(rx_ch, rx_cl,
+ CAT_MODE_RX | CAT_MODE_INBOUND_DMA,
+ ctype);
+ mlb150_dev_init_ch_cat(rx_ch, rx_cl,
+ CAT_MODE_RX | CAT_MODE_OUTBOUND_DMA,
+ ctype);
+ mlb150_dev_init_ch_cat(tx_ch, tx_cl,
+ CAT_MODE_TX | CAT_MODE_INBOUND_DMA,
+ ctype);
+ mlb150_dev_init_ch_cat(tx_ch, tx_cl,
+ CAT_MODE_TX | CAT_MODE_OUTBOUND_DMA,
+ ctype);
+}
+
+static void mlb150_dev_reset_adt(void)
+{
+ int i = 0;
+ u32 ctr_val[4] = { 0 };
+
+ mlb150_dev_enable_ctr_write(0xffffffff, 0xffffffff,
+ 0xffffffff, 0xffffffff);
+
+ for (i = 0; i < (LOGIC_CH_NUM); ++i)
+ mlb150_dev_ctr_write(BUF_ADT_OFFSET + i, ctr_val);
+}
+
+static void mlb150_dev_reset_whole_ctr(void)
+{
+ mlb150_dev_enable_ctr_write(0xffffffff, 0xffffffff,
+ 0xffffffff, 0xffffffff);
+ mlb150_dev_reset_cdt();
+ mlb150_dev_reset_adt();
+ mlb150_dev_reset_cat();
+}
+
+#define CLR_REG(reg) __raw_writel(0x0, mlb_base + reg)
+
+static void mlb150_dev_reset_all_regs(void)
+{
+ CLR_REG(REG_MLBC0);
+ CLR_REG(REG_MLBPC0);
+ CLR_REG(REG_MS0);
+ CLR_REG(REG_MS1);
+ CLR_REG(REG_MSS);
+ CLR_REG(REG_MSD);
+ CLR_REG(REG_MIEN);
+ CLR_REG(REG_MLBPC2);
+ CLR_REG(REG_MLBPC1);
+ CLR_REG(REG_MLBC1);
+ CLR_REG(REG_HCTL);
+ CLR_REG(REG_HCMR0);
+ CLR_REG(REG_HCMR1);
+ CLR_REG(REG_HCER0);
+ CLR_REG(REG_HCER1);
+ CLR_REG(REG_HCBR0);
+ CLR_REG(REG_HCBR1);
+ CLR_REG(REG_MDAT0);
+ CLR_REG(REG_MDAT1);
+ CLR_REG(REG_MDAT2);
+ CLR_REG(REG_MDAT3);
+ CLR_REG(REG_MDWE0);
+ CLR_REG(REG_MDWE1);
+ CLR_REG(REG_MDWE2);
+ CLR_REG(REG_MDWE3);
+ CLR_REG(REG_MCTL);
+ CLR_REG(REG_MADR);
+ CLR_REG(REG_ACTL);
+ CLR_REG(REG_ACSR0);
+ CLR_REG(REG_ACSR1);
+ CLR_REG(REG_ACMR0);
+ CLR_REG(REG_ACMR1);
+}
+
+static inline s32 mlb150_dev_pipo_start(struct mlb_ringbuf *rbuf,
+ u32 ahb_ch, u32 buf_addr)
+{
+ u32 ctr_val[4] = { 0 };
+
+ ctr_val[1] |= ADT_RDY1;
+ ctr_val[2] = buf_addr;
+
+ if (mlb150_dev_adt_write(ahb_ch, ctr_val))
+ return -ETIME;
+
+ return 0;
+}
+
+static inline s32 mlb150_dev_pipo_next(u32 ahb_ch, enum MLB_CTYPE ctype,
+ u32 dne_sts, u32 buf_addr)
+{
+ u32 ctr_val[4] = { 0 };
+
+ if (MLB_CTYPE_ASYNC == ctype ||
+ MLB_CTYPE_CTRL == ctype) {
+ ctr_val[1] |= ADT_PS1;
+ ctr_val[1] |= ADT_PS2;
+ }
+
+ /*
+ * Clear DNE1 and ERR1
+ * Set the page ready bit (RDY1)
+ */
+ if (dne_sts & ADT_DNE1) {
+ ctr_val[1] |= ADT_RDY2;
+ ctr_val[3] = buf_addr;
+ } else {
+ ctr_val[1] |= ADT_RDY1;
+ ctr_val[2] = buf_addr;
+ }
+
+ if (mlb150_dev_adt_write(ahb_ch, ctr_val))
+ return -ETIME;
+
+ return 0;
+}
+
+static inline s32 mlb150_dev_pipo_stop(struct mlb_ringbuf *rbuf, u32 ahb_ch)
+{
+ u32 ctr_val[4] = { 0 };
+ unsigned long flags;
+
+ write_lock_irqsave(&rbuf->rb_lock, flags);
+ rbuf->head = rbuf->tail = 0;
+ write_unlock_irqrestore(&rbuf->rb_lock, flags);
+
+ if (mlb150_dev_adt_write(ahb_ch, ctr_val))
+ return -ETIME;
+
+ return 0;
+}
+
+static s32 mlb150_dev_init_ch_amba_ahb(struct mlb_dev_info *pdevinfo,
+ struct mlb_channel_info *chinfo,
+ enum MLB_CTYPE ctype)
+{
+ u32 ctr_val[4] = { 0 };
+
+ /* a. Set the 32-bit base address (BA1) */
+ ctr_val[3] = 0;
+ ctr_val[2] = 0;
+ ctr_val[1] = (pdevinfo->adt_buf_dep - 1) << ADT_BD1_SHIFT;
+ ctr_val[1] |= (pdevinfo->adt_buf_dep - 1) << ADT_BD2_SHIFT;
+ if (MLB_CTYPE_ASYNC == ctype ||
+ MLB_CTYPE_CTRL == ctype) {
+ ctr_val[1] |= ADT_PS1;
+ ctr_val[1] |= ADT_PS2;
+ }
+
+ ctr_val[0] |= (ADT_LE | ADT_CE);
+
+ pr_debug("mxc_mlb150: Set ADT val of channel %d, ctype: %d: "
+ "0x%08x 0x%08x 0x%08x 0x%08x\n",
+ chinfo->cl, ctype, ctr_val[3], ctr_val[2],
+ ctr_val[1], ctr_val[0]);
+
+ if (mlb150_dev_adt_write(chinfo->cl, ctr_val))
+ return -ETIME;
+
+#ifdef DEBUG_CTR
+ {
+ u32 ctr_rd[4] = { 0 };
+ if (!mlb150_dev_adt_read(chinfo->cl, ctr_rd)) {
+ pr_debug("mxc_mlb150: ADT val of channel %d: "
+ "0x%08x 0x%08x 0x%08x 0x%08x\n",
+ chinfo->cl, ctr_rd[3], ctr_rd[2],
+ ctr_rd[1], ctr_rd[0]);
+ if (ctr_rd[3] == ctr_val[3] &&
+ ctr_rd[2] == ctr_val[2] &&
+ ctr_rd[1] == ctr_val[1] &&
+ ctr_rd[0] == ctr_val[0]) {
+ pr_debug("mxc_mlb150: set adt succeed!\n");
+ return 0;
+ } else {
+ pr_debug("mxc_mlb150: set adt failed!\n");
+ return -EBADE;
+ }
+ } else {
+ pr_debug("mxc_mlb150: Read ADT val of channel %d failed\n",
+ chinfo->cl);
+ return -EBADE;
+ }
+ }
+#endif
+
+ return 0;
+}
+
+static void mlb150_dev_init_amba_ahb(struct mlb_dev_info *pdevinfo,
+ enum MLB_CTYPE ctype)
+{
+ struct mlb_channel_info *tx_chinfo = &pdevinfo->channels[TX_CHANNEL];
+ struct mlb_channel_info *rx_chinfo = &pdevinfo->channels[RX_CHANNEL];
+
+ /* Step 1, Initialize all bits of the ADT to '0' */
+ mlb150_dev_reset_adt();
+
+ /*
+ * Step 2, Select a logic channel
+ * Step 3, Program the AMBA AHB block ping page for channel N
+ * Step 4, Program the AMBA AHB block pong page for channel N
+ */
+ mlb150_dev_init_ch_amba_ahb(pdevinfo, rx_chinfo, ctype);
+ mlb150_dev_init_ch_amba_ahb(pdevinfo, tx_chinfo, ctype);
+}
+
+static void mlb150_dev_exit(void)
+{
+ u32 c0_val, hctl_val;
+
+ /* Disable EN bits */
+ c0_val = __raw_readl(mlb_base + REG_MLBC0);
+ c0_val &= ~(MLBC0_MLBEN | MLBC0_MLBPEN);
+ __raw_writel(c0_val, mlb_base + REG_MLBC0);
+
+ hctl_val = __raw_readl(mlb_base + REG_HCTL);
+ hctl_val &= ~HCTL_EN;
+ __raw_writel(hctl_val, mlb_base + REG_HCTL);
+
+ __raw_writel(0x0, mlb_base + REG_HCMR0);
+ __raw_writel(0x0, mlb_base + REG_HCMR1);
+
+ mlb150_dev_enable_dma_irq(0);
+ mlb150_dev_enable_ir_mlb(0);
+}
+
+static void mlb150_dev_init(void)
+{
+ u32 c0_val;
+ u32 ch_rx_mask = (1 << SYNC_RX_CL_AHB0) | (1 << CTRL_RX_CL_AHB0)
+ | (1 << ASYNC_RX_CL_AHB0) | (1 << ISOC_RX_CL_AHB0)
+ | (1 << SYNC_TX_CL_AHB0) | (1 << CTRL_TX_CL_AHB0)
+ | (1 << ASYNC_TX_CL_AHB0) | (1 << ISOC_TX_CL_AHB0);
+ u32 ch_tx_mask = (1 << (SYNC_RX_CL_AHB1 - INT_AHB1_CH_START)) |
+ (1 << (CTRL_RX_CL_AHB1 - INT_AHB1_CH_START)) |
+ (1 << (ASYNC_RX_CL_AHB1 - INT_AHB1_CH_START)) |
+ (1 << (ISOC_RX_CL_AHB1 - INT_AHB1_CH_START)) |
+ (1 << (SYNC_TX_CL_AHB1 - INT_AHB1_CH_START)) |
+ (1 << (CTRL_TX_CL_AHB1 - INT_AHB1_CH_START)) |
+ (1 << (ASYNC_TX_CL_AHB1 - INT_AHB1_CH_START)) |
+ (1 << (ISOC_TX_CL_AHB1 - INT_AHB1_CH_START));
+
+ /* Disable EN bits */
+ mlb150_dev_exit();
+
+ /*
+ * Step 1. Initialize CTR and registers
+ * a. Set all bit of the CTR (CAT, CDT, and ADT) to 0.
+ */
+ mlb150_dev_reset_whole_ctr();
+
+ /* a. Set all bit of the CTR (CAT, CDT, and ADT) to 0. */
+ mlb150_dev_reset_all_regs();
+
+ /*
+ * Step 2, Configure the MediaLB interface
+ * Select pin mode and clock, 3-pin and 256fs
+ */
+ c0_val = __raw_readl(mlb_base + REG_MLBC0);
+ c0_val &= ~(MLBC0_MLBPEN | MLBC0_MLBCLK_MASK);
+ __raw_writel(c0_val, mlb_base + REG_MLBC0);
+
+ c0_val |= MLBC0_MLBEN;
+ __raw_writel(c0_val, mlb_base + REG_MLBC0);
+
+ /* Step 3, Configure the HBI interface */
+ __raw_writel(ch_rx_mask, mlb_base + REG_HCMR0);
+ __raw_writel(ch_tx_mask, mlb_base + REG_HCMR1);
+ __raw_writel(HCTL_EN, mlb_base + REG_HCTL);
+
+ mlb150_dev_init_ir_amba_ahb();
+
+ mlb150_dev_enable_ir_mlb(1);
+}
+
+static s32 mlb150_dev_unmute_syn_ch(u32 rx_ch, u32 rx_cl, u32 tx_ch, u32 tx_cl)
+{
+ u32 timeout = 10000;
+
+ /*
+ * Check that MediaLB clock is running (MLBC1.CLKM = 0)
+ * If MLBC1.CLKM = 1, clear the register bit, wait one
+ * APB or I/O clock cycle and repeat the check
+ */
+ while ((__raw_readl(mlb_base + REG_MLBC1) & MLBC1_CLKM)
+ && --timeout)
+ __raw_writel(~MLBC1_CLKM, mlb_base + REG_MLBC1);
+
+ if (0 == timeout)
+ return -ETIME;
+
+ timeout = 10000;
+ /* Poll for MLB lock (MLBC0.MLBLK = 1) */
+ while (!(__raw_readl(mlb_base + REG_MLBC0) & MLBC0_MLBLK)
+ && --timeout)
+ ;
+
+ if (0 == timeout)
+ return -ETIME;
+
+ /* Unmute synchronous channel(s) */
+ mlb150_dev_cat_mlb_write(rx_ch, CAT_CE | rx_cl);
+ mlb150_dev_cat_mlb_write(tx_ch,
+ CAT_CE | tx_cl | CAT_RNW);
+ mlb150_dev_cat_hbi_write(rx_cl,
+ CAT_CE | rx_cl | CAT_RNW);
+ mlb150_dev_cat_hbi_write(tx_cl, CAT_CE | tx_cl);
+
+ return 0;
+}
+
+/* In case the user calls channel shutdown, but rx or tx is not completed yet */
+static s32 mlb150_trans_complete_check(struct mlb_dev_info *pdevinfo)
+{
+ struct mlb_ringbuf *rx_rbuf = &pdevinfo->rx_rbuf;
+ struct mlb_ringbuf *tx_rbuf = &pdevinfo->tx_rbuf;
+ s32 timeout = 1024;
+
+ while (timeout--) {
+ read_lock(&tx_rbuf->rb_lock);
+ if (!CIRC_CNT(tx_rbuf->head, tx_rbuf->tail, TRANS_RING_NODES)) {
+ read_unlock(&tx_rbuf->rb_lock);
+ break;
+ } else
+ read_unlock(&tx_rbuf->rb_lock);
+ }
+
+ if (timeout <= 0) {
+ pr_debug("TX complete check timeout!\n");
+ return -ETIME;
+ }
+
+ timeout = 1024;
+ while (timeout--) {
+ read_lock(&rx_rbuf->rb_lock);
+ if (!CIRC_CNT(rx_rbuf->head, rx_rbuf->tail, TRANS_RING_NODES)) {
+ read_unlock(&rx_rbuf->rb_lock);
+ break;
+ } else
+ read_unlock(&rx_rbuf->rb_lock);
+ }
+
+ if (timeout <= 0) {
+ pr_debug("RX complete check timeout!\n");
+ return -ETIME;
+ }
+
+ /*
+ * Interrupt from TX can only inform that the data is sent
+ * to AHB bus, not mean that it is sent to MITB. Thus we add
+ * a delay here for data to be completed sent.
+ */
+ udelay(1000);
+
+ return 0;
+}
+
+/*
+ * Enable/Disable the MLB IRQ
+ */
+static void mxc_mlb150_irq_enable(struct mlb_data *drvdata, u8 enable)
+{
+ if (enable) {
+ enable_irq(drvdata->irq_ahb0);
+ enable_irq(drvdata->irq_mlb);
+ if (drvdata->irq_ahb1 > 0)
+ enable_irq(drvdata->irq_ahb1);
+ } else {
+ disable_irq(drvdata->irq_ahb0);
+ disable_irq(drvdata->irq_mlb);
+ if (drvdata->irq_ahb1 > 0)
+ disable_irq(drvdata->irq_ahb1);
+ }
+}
+
+/*
+ * Enable the MLB channel
+ */
+static s32 mlb_channel_enable(struct mlb_data *drvdata,
+ int chan_dev_id, int on)
+{
+ struct mlb_dev_info *pdevinfo = drvdata->devinfo;
+ struct mlb_channel_info *tx_chinfo = &pdevinfo->channels[TX_CHANNEL];
+ struct mlb_channel_info *rx_chinfo = &pdevinfo->channels[RX_CHANNEL];
+ u32 tx_ch = tx_chinfo->address;
+ u32 rx_ch = rx_chinfo->address;
+ u32 tx_cl = tx_chinfo->cl;
+ u32 rx_cl = rx_chinfo->cl;
+ s32 ret = 0;
+
+ /*
+ * setup the direction, enable, channel type,
+ * mode select, channel address and mask buf start
+ */
+ if (on) {
+ u32 ctype = pdevinfo->channel_type;
+
+ mlb150_dev_enable_ctr_write(0xffffffff, 0xffffffff,
+ 0xffffffff, 0xffffffff);
+ mlb150_dev_init_rfb(pdevinfo, rx_ch, tx_ch, ctype);
+
+ mlb150_dev_init_amba_ahb(pdevinfo, ctype);
+
+#ifdef DEBUG
+ mlb150_dev_dump_ctr_tbl(0, tx_chinfo->cl + 1);
+#endif
+ /* Synchronize and unmute synchrouous channel */
+ if (MLB_CTYPE_SYNC == ctype) {
+ ret = mlb150_dev_unmute_syn_ch(rx_ch, rx_cl,
+ tx_ch, tx_cl);
+ if (ret)
+ return ret;
+ }
+
+ mlb150_dev_enable_ctr_write(0x0, ADT_RDY1 | ADT_DNE1 |
+ ADT_ERR1 | ADT_PS1 |
+ ADT_RDY2 | ADT_DNE2 | ADT_ERR2 | ADT_PS2,
+ 0xffffffff, 0xffffffff);
+
+ if (pdevinfo->fps >= CLK_2048FS)
+ mlb150_enable_pll(drvdata);
+
+ atomic_set(&pdevinfo->on, 1);
+
+#ifdef DEBUG
+ mlb150_dev_dump_reg();
+ mlb150_dev_dump_ctr_tbl(0, tx_chinfo->cl + 1);
+#endif
+ /* Init RX ADT */
+ mlb150_dev_pipo_start(&pdevinfo->rx_rbuf, rx_cl,
+ pdevinfo->rx_rbuf.phy_addrs[0]);
+ } else {
+ mlb150_dev_pipo_stop(&pdevinfo->rx_rbuf, rx_cl);
+
+ mlb150_dev_enable_dma_irq(0);
+ mlb150_dev_enable_ir_mlb(0);
+
+ mlb150_dev_reset_cat();
+
+ atomic_set(&pdevinfo->on, 0);
+
+ if (pdevinfo->fps >= CLK_2048FS)
+ mlb150_disable_pll(drvdata);
+ }
+
+ return 0;
+}
+
+/*
+ * MLB interrupt handler
+ */
+static void mlb_rx_isr(s32 ctype, u32 ahb_ch, struct mlb_dev_info *pdevinfo)
+{
+ struct mlb_ringbuf *rx_rbuf = &pdevinfo->rx_rbuf;
+ s32 head, tail, adt_sts;
+ u32 rx_buf_ptr;
+
+#ifdef DEBUG_RX
+ pr_debug("mxc_mlb150: mlb_rx_isr\n");
+#endif
+
+ read_lock(&rx_rbuf->rb_lock);
+
+ head = (rx_rbuf->head + 1) & (TRANS_RING_NODES - 1);
+ tail = ACCESS_ONCE(rx_rbuf->tail);
+ read_unlock(&rx_rbuf->rb_lock);
+
+ if (CIRC_SPACE(head, tail, TRANS_RING_NODES) >= 1) {
+ rx_buf_ptr = rx_rbuf->phy_addrs[head];
+
+ /* commit the item before incrementing the head */
+ smp_wmb();
+
+ write_lock(&rx_rbuf->rb_lock);
+ rx_rbuf->head = head;
+ write_unlock(&rx_rbuf->rb_lock);
+
+ /* wake up the reader */
+ wake_up_interruptible(&pdevinfo->rx_wq);
+ } else {
+ rx_buf_ptr = rx_rbuf->phy_addrs[head];
+ pr_debug("drop RX package, due to no space, (%d,%d)\n",
+ head, tail);
+ }
+
+ adt_sts = mlb150_dev_get_adt_sts(ahb_ch);
+ /* Set ADT for RX */
+ mlb150_dev_pipo_next(ahb_ch, ctype, adt_sts, rx_buf_ptr);
+}
+
+static void mlb_tx_isr(s32 ctype, u32 ahb_ch, struct mlb_dev_info *pdevinfo)
+{
+ struct mlb_ringbuf *tx_rbuf = &pdevinfo->tx_rbuf;
+ s32 head, tail, adt_sts;
+ u32 tx_buf_ptr;
+
+ read_lock(&tx_rbuf->rb_lock);
+
+ head = ACCESS_ONCE(tx_rbuf->head);
+ tail = (tx_rbuf->tail + 1) & (TRANS_RING_NODES - 1);
+ read_unlock(&tx_rbuf->rb_lock);
+
+ smp_mb();
+ write_lock(&tx_rbuf->rb_lock);
+ tx_rbuf->tail = tail;
+ write_unlock(&tx_rbuf->rb_lock);
+
+ /* check the current tx buffer is available or not */
+ if (CIRC_CNT(head, tail, TRANS_RING_NODES) >= 1) {
+ /* read index before reading contents at that index */
+ smp_read_barrier_depends();
+
+ tx_buf_ptr = tx_rbuf->phy_addrs[tail];
+
+ wake_up_interruptible(&pdevinfo->tx_wq);
+
+ adt_sts = mlb150_dev_get_adt_sts(ahb_ch);
+ /* Set ADT for TX */
+ mlb150_dev_pipo_next(ahb_ch, ctype, adt_sts, tx_buf_ptr);
+ }
+}
+
+static irqreturn_t mlb_ahb_isr(int irq, void *dev_id)
+{
+ u32 acsr0, hcer0;
+ u32 ch_mask = (1 << SYNC_RX_CL) | (1 << CTRL_RX_CL)
+ | (1 << ASYNC_RX_CL) | (1 << ISOC_RX_CL)
+ | (1 << SYNC_TX_CL) | (1 << CTRL_TX_CL)
+ | (1 << ASYNC_TX_CL) | (1 << ISOC_TX_CL);
+
+ /*
+ * Step 5, Read the ACSRn registers to determine which channel or
+ * channels are causing the interrupt
+ */
+ acsr0 = __raw_readl(mlb_base + REG_ACSR0);
+
+ hcer0 = __raw_readl(mlb_base + REG_HCER0);
+
+ /*
+ * Step 6, If ACTL.SCE = 1, write the result of step 5 back to ACSR0
+ * and ACSR1 to clear the interrupt
+ * We'll not set ACTL_SCE
+ */
+
+ if (ch_mask & hcer0)
+ pr_err("CH encounters an AHB error: 0x%x\n", hcer0);
+
+ if ((1 << SYNC_RX_CL) & acsr0)
+ mlb_rx_isr(MLB_CTYPE_SYNC, SYNC_RX_CL,
+ &mlb_devinfo[MLB_CTYPE_SYNC]);
+
+ if ((1 << CTRL_RX_CL) & acsr0)
+ mlb_rx_isr(MLB_CTYPE_CTRL, CTRL_RX_CL,
+ &mlb_devinfo[MLB_CTYPE_CTRL]);
+
+ if ((1 << ASYNC_RX_CL) & acsr0)
+ mlb_rx_isr(MLB_CTYPE_ASYNC, ASYNC_RX_CL,
+ &mlb_devinfo[MLB_CTYPE_ASYNC]);
+
+ if ((1 << ISOC_RX_CL) & acsr0)
+ mlb_rx_isr(MLB_CTYPE_ISOC, ISOC_RX_CL,
+ &mlb_devinfo[MLB_CTYPE_ISOC]);
+
+ if ((1 << SYNC_TX_CL) & acsr0)
+ mlb_tx_isr(MLB_CTYPE_SYNC, SYNC_TX_CL,
+ &mlb_devinfo[MLB_CTYPE_SYNC]);
+
+ if ((1 << CTRL_TX_CL) & acsr0)
+ mlb_tx_isr(MLB_CTYPE_CTRL, CTRL_TX_CL,
+ &mlb_devinfo[MLB_CTYPE_CTRL]);
+
+ if ((1 << ASYNC_TX_CL) & acsr0)
+ mlb_tx_isr(MLB_CTYPE_ASYNC, ASYNC_TX_CL,
+ &mlb_devinfo[MLB_CTYPE_ASYNC]);
+
+ if ((1 << ISOC_TX_CL) & acsr0)
+ mlb_tx_isr(MLB_CTYPE_ASYNC, ISOC_TX_CL,
+ &mlb_devinfo[MLB_CTYPE_ISOC]);
+
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t mlb_isr(int irq, void *dev_id)
+{
+ u32 rx_int_sts, tx_int_sts, ms0,
+ ms1, tx_cis, rx_cis, ctype;
+ int minor;
+ u32 cdt_val[4] = { 0 };
+
+ /*
+ * Step 4, Read the MSn register to determine which channel(s)
+ * are causing the interrupt
+ */
+ ms0 = __raw_readl(mlb_base + REG_MS0);
+ ms1 = __raw_readl(mlb_base + REG_MS1);
+
+ /*
+ * The MLB150_MS0, MLB150_MS1 registers need to be cleared. In
+ * the spec description, the registers should be cleared when
+ * enabling interrupt. In fact, we also should clear it in ISR.
+ */
+ __raw_writel(0, mlb_base + REG_MS0);
+ __raw_writel(0, mlb_base + REG_MS1);
+
+ pr_debug("mxc_mlb150: mlb interrupt:0x%08x 0x%08x\n",
+ (u32)ms0, (u32)ms1);
+
+ for (minor = 0; minor < MLB_MINOR_DEVICES; minor++) {
+ struct mlb_dev_info *pdevinfo = &mlb_devinfo[minor];
+ u32 rx_mlb_ch = pdevinfo->channels[RX_CHANNEL].address;
+ u32 tx_mlb_ch = pdevinfo->channels[TX_CHANNEL].address;
+ u32 rx_mlb_cl = pdevinfo->channels[RX_CHANNEL].cl;
+ u32 tx_mlb_cl = pdevinfo->channels[TX_CHANNEL].cl;
+
+ tx_cis = rx_cis = 0;
+
+ ctype = pdevinfo->channel_type;
+ rx_int_sts = (rx_mlb_ch < 31) ? ms0 : ms1;
+ tx_int_sts = (tx_mlb_ch < 31) ? ms0 : ms1;
+
+ pr_debug("mxc_mlb150: channel interrupt: "
+ "tx %d: 0x%08x, rx %d: 0x%08x\n",
+ tx_mlb_ch, (u32)tx_int_sts, rx_mlb_ch, (u32)rx_int_sts);
+
+ /* Get tx channel interrupt status */
+ if (tx_int_sts & (1 << (tx_mlb_ch % 32))) {
+ mlb150_dev_cdt_read(tx_mlb_cl, cdt_val);
+ pr_debug("mxc_mlb150: TX_CH: %d, cdt_val[3]: 0x%08x, "
+ "cdt_val[2]: 0x%08x, "
+ "cdt_val[1]: 0x%08x, "
+ "cdt_val[0]: 0x%08x\n",
+ tx_mlb_ch, cdt_val[3], cdt_val[2],
+ cdt_val[1], cdt_val[0]);
+ switch (ctype) {
+ case MLB_CTYPE_SYNC:
+ tx_cis = (cdt_val[2] & CDT_SYNC_WSTS_MASK)
+ >> CDT_SYNC_WSTS_SHIFT;
+ /*
+ * Clear RSTS/WSTS errors to resume
+ * channel operation
+ * a. For synchronous channels: WSTS[3] = 0
+ */
+ cdt_val[2] &= ~(0x8 << CDT_SYNC_WSTS_SHIFT);
+ break;
+ case MLB_CTYPE_CTRL:
+ case MLB_CTYPE_ASYNC:
+ tx_cis = (cdt_val[2] &
+ CDT_CTRL_ASYNC_WSTS_MASK)
+ >> CDT_CTRL_ASYNC_WSTS_SHIFT;
+ tx_cis = (cdt_val[3] & CDT_CTRL_ASYNC_WSTS_1) ?
+ (tx_cis | (0x1 << 4)) : tx_cis;
+ /*
+ * b. For async and ctrl channels:
+ * RSTS[4]/WSTS[4] = 0
+ * and RSTS[2]/WSTS[2] = 0
+ */
+ cdt_val[3] &= ~CDT_CTRL_ASYNC_WSTS_1;
+ cdt_val[2] &=
+ ~(0x4 << CDT_CTRL_ASYNC_WSTS_SHIFT);
+ break;
+ case MLB_CTYPE_ISOC:
+ tx_cis = (cdt_val[2] & CDT_ISOC_WSTS_MASK)
+ >> CDT_ISOC_WSTS_SHIFT;
+ /* c. For isoc channels: WSTS[2:1] = 0x00 */
+ cdt_val[2] &= ~(0x6 << CDT_ISOC_WSTS_SHIFT);
+ break;
+ default:
+ break;
+ }
+ mlb150_dev_cdt_write(tx_mlb_ch, cdt_val);
+ }
+
+ /* Get rx channel interrupt status */
+ if (rx_int_sts & (1 << (rx_mlb_ch % 32))) {
+ mlb150_dev_cdt_read(rx_mlb_cl, cdt_val);
+ pr_debug("mxc_mlb150: RX_CH: %d, cdt_val[3]: 0x%08x, "
+ "cdt_val[2]: 0x%08x, "
+ "cdt_val[1]: 0x%08x, "
+ "cdt_val[0]: 0x%08x\n",
+ rx_mlb_ch, cdt_val[3], cdt_val[2],
+ cdt_val[1], cdt_val[0]);
+ switch (ctype) {
+ case MLB_CTYPE_SYNC:
+ rx_cis = (cdt_val[2] & CDT_SYNC_RSTS_MASK)
+ >> CDT_SYNC_RSTS_SHIFT;
+ cdt_val[2] &= ~(0x8 << CDT_SYNC_WSTS_SHIFT);
+ break;
+ case MLB_CTYPE_CTRL:
+ case MLB_CTYPE_ASYNC:
+ rx_cis =
+ (cdt_val[2] & CDT_CTRL_ASYNC_RSTS_MASK)
+ >> CDT_CTRL_ASYNC_RSTS_SHIFT;
+ rx_cis = (cdt_val[3] & CDT_CTRL_ASYNC_RSTS_1) ?
+ (rx_cis | (0x1 << 4)) : rx_cis;
+ cdt_val[3] &= ~CDT_CTRL_ASYNC_RSTS_1;
+ cdt_val[2] &=
+ ~(0x4 << CDT_CTRL_ASYNC_RSTS_SHIFT);
+ break;
+ case MLB_CTYPE_ISOC:
+ rx_cis = (cdt_val[2] & CDT_ISOC_RSTS_MASK)
+ >> CDT_ISOC_RSTS_SHIFT;
+ cdt_val[2] &= ~(0x6 << CDT_ISOC_WSTS_SHIFT);
+ break;
+ default:
+ break;
+ }
+ mlb150_dev_cdt_write(rx_mlb_ch, cdt_val);
+ }
+
+ if (!tx_cis && !rx_cis)
+ continue;
+
+ /* fill exception event */
+ spin_lock(&pdevinfo->event_lock);
+ pdevinfo->ex_event |= (rx_cis << 16) | tx_cis;
+ spin_unlock(&pdevinfo->event_lock);
+ }
+
+ return IRQ_HANDLED;
+}
+
+static int mxc_mlb150_open(struct inode *inode, struct file *filp)
+{
+ int minor, ring_buf_size, buf_size, j, ret;
+ void *buf_addr;
+ dma_addr_t phy_addr;
+ struct mlb_dev_info *pdevinfo = NULL;
+ struct mlb_channel_info *pchinfo = NULL;
+ struct mlb_data *drvdata;
+
+ minor = MINOR(inode->i_rdev);
+ drvdata = container_of(inode->i_cdev, struct mlb_data, cdev);
+ drvdata->use_iram = true;
+
+ if (minor < 0 || minor >= MLB_MINOR_DEVICES) {
+ pr_err("no device\n");
+ return -ENODEV;
+ }
+
+ /* open for each channel device */
+ if (atomic_cmpxchg(&mlb_devinfo[minor].opencnt, 0, 1) != 0) {
+ pr_err("busy\n");
+ return -EBUSY;
+ }
+
+#ifdef CONFIG_ARCH_MXC_ARM64
+ clk_prepare_enable(drvdata->ipg);
+ clk_prepare_enable(drvdata->hclk);
+#endif
+ clk_prepare_enable(drvdata->mlb);
+
+ /* initial MLB module */
+ mlb150_dev_init();
+
+ pdevinfo = &mlb_devinfo[minor];
+ pchinfo = &pdevinfo->channels[TX_CHANNEL];
+
+ ring_buf_size = pdevinfo->buf_size;
+ buf_size = ring_buf_size * (TRANS_RING_NODES * 2);
+
+ buf_addr = gen_pool_dma_alloc(drvdata->iram_pool, buf_size, &phy_addr);
+ if (!buf_addr) {
+ drvdata->use_iram = false;
+ buf_addr = dma_alloc_coherent(drvdata->dev, buf_size, &phy_addr, GFP_KERNEL);
+ if (!buf_addr) {
+ ret = -ENOMEM;
+ pr_err("can not alloc rx/tx buffers: %d\n", buf_size);
+ return ret;
+ }
+ }
+
+ pr_debug("IRAM Range: Virt 0x%p - 0x%p, Phys 0x%x - 0x%x, size: 0x%x\n",
+ buf_addr, (buf_addr + buf_size - 1), (u32)phy_addr,
+ (u32)(phy_addr + buf_size - 1), buf_size);
+ pdevinfo->rbuf_base_virt = buf_addr;
+ pdevinfo->rbuf_base_phy = phy_addr;
+ drvdata->iram_size = drvdata->use_iram ? buf_size : 0;
+
+ memset(buf_addr, 0, buf_size);
+
+ for (j = 0; j < (TRANS_RING_NODES);
+ ++j, buf_addr += ring_buf_size, phy_addr += ring_buf_size) {
+ pdevinfo->rx_rbuf.virt_bufs[j] = buf_addr;
+ pdevinfo->rx_rbuf.phy_addrs[j] = phy_addr;
+ pr_debug("RX Ringbuf[%d]: 0x%p 0x%x\n",
+ j, buf_addr, (u32)phy_addr);
+ }
+ pdevinfo->rx_rbuf.unit_size = ring_buf_size;
+ pdevinfo->rx_rbuf.total_size = buf_size;
+ for (j = 0; j < (TRANS_RING_NODES);
+ ++j, buf_addr += ring_buf_size, phy_addr += ring_buf_size) {
+ pdevinfo->tx_rbuf.virt_bufs[j] = buf_addr;
+ pdevinfo->tx_rbuf.phy_addrs[j] = phy_addr;
+ pr_debug("TX Ringbuf[%d]: 0x%p 0x%x\n",
+ j, buf_addr, (u32)phy_addr);
+ }
+
+ pdevinfo->tx_rbuf.unit_size = ring_buf_size;
+ pdevinfo->tx_rbuf.total_size = buf_size;
+
+ /* reset the buffer read/write ptr */
+ pdevinfo->rx_rbuf.head = pdevinfo->rx_rbuf.tail = 0;
+ pdevinfo->tx_rbuf.head = pdevinfo->tx_rbuf.tail = 0;
+ pdevinfo->ex_event = 0;
+ pdevinfo->tx_ok = 0;
+
+ init_waitqueue_head(&pdevinfo->rx_wq);
+ init_waitqueue_head(&pdevinfo->tx_wq);
+
+ drvdata = container_of(inode->i_cdev, struct mlb_data, cdev);
+ drvdata->devinfo = pdevinfo;
+ mxc_mlb150_irq_enable(drvdata, 1);
+ filp->private_data = drvdata;
+
+ return 0;
+}
+
+static int mxc_mlb150_release(struct inode *inode, struct file *filp)
+{
+ int minor;
+ struct mlb_data *drvdata = filp->private_data;
+ struct mlb_dev_info *pdevinfo = drvdata->devinfo;
+
+ minor = MINOR(inode->i_rdev);
+ mxc_mlb150_irq_enable(drvdata, 0);
+
+#ifdef DEBUG
+ mlb150_dev_dump_reg();
+ mlb150_dev_dump_ctr_tbl(0, pdevinfo->channels[TX_CHANNEL].cl + 1);
+#endif
+
+ if (drvdata->use_iram)
+ gen_pool_free(drvdata->iram_pool,
+ (ulong)pdevinfo->rbuf_base_virt, drvdata->iram_size);
+
+ mlb150_dev_exit();
+
+ atomic_set(&pdevinfo->on, 0);
+
+ clk_disable_unprepare(drvdata->mlb);
+#ifdef CONFIG_ARCH_MXC_ARM64
+ clk_disable_unprepare(drvdata->hclk);
+ clk_disable_unprepare(drvdata->ipg);
+#endif
+ /* decrease the open count */
+ atomic_set(&pdevinfo->opencnt, 0);
+
+ drvdata->devinfo = NULL;
+
+ return 0;
+}
+
+static long mxc_mlb150_ioctl(struct file *filp,
+ unsigned int cmd, unsigned long arg)
+{
+ //struct inode *inode = filp->f_dentry->d_inode;
+ struct inode *inode = file_inode(filp);
+ struct mlb_data *drvdata = filp->private_data;
+ struct mlb_dev_info *pdevinfo = drvdata->devinfo;
+ void __user *argp = (void __user *)arg;
+ unsigned long flags, event;
+ int minor;
+
+ minor = MINOR(inode->i_rdev);
+
+ switch (cmd) {
+ case MLB_CHAN_SETADDR:
+ {
+ unsigned int caddr;
+ /* get channel address from user space */
+ if (copy_from_user(&caddr, argp, sizeof(caddr))) {
+ pr_err("mxc_mlb150: copy from user failed\n");
+ return -EFAULT;
+ }
+ pdevinfo->channels[TX_CHANNEL].address =
+ (caddr >> 16) & 0xFFFF;
+ pdevinfo->channels[RX_CHANNEL].address = caddr & 0xFFFF;
+ pr_debug("mxc_mlb150: set ch addr, tx: %d, rx: %d\n",
+ pdevinfo->channels[TX_CHANNEL].address,
+ pdevinfo->channels[RX_CHANNEL].address);
+ break;
+ }
+
+ case MLB_CHAN_STARTUP:
+ if (atomic_read(&pdevinfo->on)) {
+ pr_debug("mxc_mlb150: channel alreadly startup\n");
+ break;
+ }
+ if (mlb_channel_enable(drvdata, minor, 1))
+ return -EFAULT;
+ break;
+ case MLB_CHAN_SHUTDOWN:
+ if (atomic_read(&pdevinfo->on) == 0) {
+ pr_debug("mxc_mlb150: channel areadly shutdown\n");
+ break;
+ }
+ mlb150_trans_complete_check(pdevinfo);
+ mlb_channel_enable(drvdata, minor, 0);
+ break;
+ case MLB_CHAN_GETEVENT:
+ /* get and clear the ex_event */
+ spin_lock_irqsave(&pdevinfo->event_lock, flags);
+ event = pdevinfo->ex_event;
+ pdevinfo->ex_event = 0;
+ spin_unlock_irqrestore(&pdevinfo->event_lock, flags);
+
+ if (event) {
+ if (copy_to_user(argp, &event, sizeof(event))) {
+ pr_err("mxc_mlb150: copy to user failed\n");
+ return -EFAULT;
+ }
+ } else
+ return -EAGAIN;
+ break;
+ case MLB_SET_ISOC_BLKSIZE_188:
+ pdevinfo->isoc_blksz = 188;
+ pdevinfo->cdt_buf_dep = pdevinfo->adt_buf_dep =
+ pdevinfo->isoc_blksz * CH_ISOC_BLK_NUM;
+ break;
+ case MLB_SET_ISOC_BLKSIZE_196:
+ pdevinfo->isoc_blksz = 196;
+ pdevinfo->cdt_buf_dep = pdevinfo->adt_buf_dep =
+ pdevinfo->isoc_blksz * CH_ISOC_BLK_NUM;
+ break;
+ case MLB_SET_SYNC_QUAD:
+ {
+ u32 quad;
+
+ if (copy_from_user(&quad, argp, sizeof(quad))) {
+ pr_err("mxc_mlb150: get quad number "
+ "from user failed\n");
+ return -EFAULT;
+ }
+ if (quad <= 0 || quad > 3) {
+ pr_err("mxc_mlb150: Invalid Quadlets!"
+ "Quadlets in Sync mode can "
+ "only be 1, 2, 3\n");
+ return -EINVAL;
+ }
+ pdevinfo->sync_quad = quad;
+ /* Each quadlets is 4 bytes */
+ pdevinfo->cdt_buf_dep = quad * 4 * 4;
+ pdevinfo->adt_buf_dep =
+ pdevinfo->cdt_buf_dep * CH_SYNC_ADT_BUF_MULTI;
+ }
+ break;
+ case MLB_SET_FPS:
+ {
+ u32 fps, c0_val;
+
+ /* get fps from user space */
+ if (copy_from_user(&fps, argp, sizeof(fps))) {
+ pr_err("mxc_mlb150: copy from user failed\n");
+ return -EFAULT;
+ }
+
+ if ((fps > 1024) &&
+ !(drvdata->quirk_flag & MLB_QUIRK_MLB150)) {
+ pr_err("mxc_mlb150: not support fps %d\n", fps);
+ return -EINVAL;
+ }
+
+ c0_val = __raw_readl(mlb_base + REG_MLBC0);
+ c0_val &= ~MLBC0_MLBCLK_MASK;
+
+ /* check fps value */
+ switch (fps) {
+ case 256:
+ case 512:
+ case 1024:
+ pdevinfo->fps = fps >> 9;
+ c0_val &= ~MLBC0_MLBPEN;
+ c0_val |= (fps >> 9)
+ << MLBC0_MLBCLK_SHIFT;
+
+ if (1024 == fps) {
+ /*
+ * Invert output clock phase
+ * in 1024 fps
+ */
+ __raw_writel(0x1,
+ mlb_base + REG_MLBPC2);
+ }
+ break;
+ case 2048:
+ case 3072:
+ case 4096:
+ pdevinfo->fps = (fps >> 10) + 1;
+ c0_val |= ((fps >> 10) + 1)
+ << MLBC0_MLBCLK_SHIFT;
+ break;
+ case 6144:
+ pdevinfo->fps = fps >> 10;
+ c0_val |= ((fps >> 10) + 1)
+ << MLBC0_MLBCLK_SHIFT;
+ break;
+ case 8192:
+ pdevinfo->fps = (fps >> 10) - 1;
+ c0_val |= ((fps >> 10) - 1)
+ << MLBC0_MLBCLK_SHIFT;
+ break;
+ default:
+ pr_debug("mxc_mlb150: invalid fps argument: %d\n",
+ fps);
+ return -EINVAL;
+ }
+
+ __raw_writel(c0_val, mlb_base + REG_MLBC0);
+
+ pr_debug("mxc_mlb150: set fps to %d, MLBC0: 0x%08x\n",
+ fps,
+ (u32)__raw_readl(mlb_base + REG_MLBC0));
+
+ break;
+ }
+
+ case MLB_GET_VER:
+ {
+ u32 version;
+
+ /* get MLB device module version */
+ version = 0x03030003;
+
+ pr_debug("mxc_mlb150: get version: 0x%08x\n",
+ version);
+
+ if (copy_to_user(argp, &version, sizeof(version))) {
+ pr_err("mxc_mlb150: copy to user failed\n");
+ return -EFAULT;
+ }
+ break;
+ }
+
+ case MLB_SET_DEVADDR:
+ {
+ u32 c1_val;
+ u8 devaddr;
+
+ /* get MLB device address from user space */
+ if (copy_from_user
+ (&devaddr, argp, sizeof(unsigned char))) {
+ pr_err("mxc_mlb150: copy from user failed\n");
+ return -EFAULT;
+ }
+
+ c1_val = __raw_readl(mlb_base + REG_MLBC1);
+ c1_val &= ~MLBC1_NDA_MASK;
+ c1_val |= devaddr << MLBC1_NDA_SHIFT;
+ __raw_writel(c1_val, mlb_base + REG_MLBC1);
+ pr_debug("mxc_mlb150: set dev addr, dev addr: %d, "
+ "MLBC1: 0x%08x\n", devaddr,
+ (u32)__raw_readl(mlb_base + REG_MLBC1));
+
+ break;
+ }
+
+ case MLB_IRQ_DISABLE:
+ {
+ disable_irq(drvdata->irq_mlb);
+ break;
+ }
+
+ case MLB_IRQ_ENABLE:
+ {
+ enable_irq(drvdata->irq_mlb);
+ break;
+ }
+ default:
+ pr_info("mxc_mlb150: Invalid ioctl command\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+/*
+ * MLB read routine
+ * Read the current received data from queued buffer,
+ * and free this buffer for hw to fill ingress data.
+ */
+static ssize_t mxc_mlb150_read(struct file *filp, char __user *buf,
+ size_t count, loff_t *f_pos)
+{
+ int size;
+ struct mlb_data *drvdata = filp->private_data;
+ struct mlb_dev_info *pdevinfo = drvdata->devinfo;
+ struct mlb_ringbuf *rx_rbuf = &pdevinfo->rx_rbuf;
+ int head, tail;
+ unsigned long flags;
+
+ read_lock_irqsave(&rx_rbuf->rb_lock, flags);
+
+ head = ACCESS_ONCE(rx_rbuf->head);
+ tail = rx_rbuf->tail;
+
+ read_unlock_irqrestore(&rx_rbuf->rb_lock, flags);
+
+ /* check the current rx buffer is available or not */
+ if (0 == CIRC_CNT(head, tail, TRANS_RING_NODES)) {
+
+ if (filp->f_flags & O_NONBLOCK)
+ return -EAGAIN;
+
+ do {
+ DEFINE_WAIT(__wait);
+
+ for (;;) {
+ prepare_to_wait(&pdevinfo->rx_wq,
+ &__wait, TASK_INTERRUPTIBLE);
+
+ read_lock_irqsave(&rx_rbuf->rb_lock, flags);
+ if (CIRC_CNT(rx_rbuf->head, rx_rbuf->tail,
+ TRANS_RING_NODES) > 0) {
+ read_unlock_irqrestore(&rx_rbuf->rb_lock,
+ flags);
+ break;
+ }
+ read_unlock_irqrestore(&rx_rbuf->rb_lock,
+ flags);
+
+ if (!signal_pending(current)) {
+ schedule();
+ continue;
+ }
+ return -ERESTARTSYS;
+ }
+ finish_wait(&pdevinfo->rx_wq, &__wait);
+ } while (0);
+ }
+
+ /* read index before reading contents at that index */
+ smp_read_barrier_depends();
+
+ size = pdevinfo->adt_buf_dep;
+ if (size > count) {
+ /* the user buffer is too small */
+ pr_warn("mxc_mlb150: received data size is biggerthan size:"
+ "%d, count: %d\n", size, (int)count);
+ return -EINVAL;
+ }
+
+ /* extract one item from the buffer */
+ if (copy_to_user(buf, rx_rbuf->virt_bufs[tail], size)) {
+ pr_err("mxc_mlb150: copy from user failed\n");
+ return -EFAULT;
+ }
+
+ /* finish reading descriptor before incrementing tail */
+ smp_mb();
+
+ write_lock_irqsave(&rx_rbuf->rb_lock, flags);
+ rx_rbuf->tail = (tail + 1) & (TRANS_RING_NODES - 1);
+ write_unlock_irqrestore(&rx_rbuf->rb_lock, flags);
+
+ *f_pos = 0;
+
+ return size;
+}
+
+/*
+ * MLB write routine
+ * Copy the user data to tx channel buffer,
+ * and prepare the channel current/next buffer ptr.
+ */
+static ssize_t mxc_mlb150_write(struct file *filp, const char __user *buf,
+ size_t count, loff_t *f_pos)
+{
+ s32 ret = 0;
+ struct mlb_channel_info *pchinfo = NULL;
+ struct mlb_data *drvdata = filp->private_data;
+ struct mlb_dev_info *pdevinfo = drvdata->devinfo;
+ struct mlb_ringbuf *tx_rbuf = &pdevinfo->tx_rbuf;
+ int head, tail;
+ unsigned long flags;
+
+ /*
+ * minor = MINOR(filp->f_dentry->d_inode->i_rdev);
+ */
+ pchinfo = &pdevinfo->channels[TX_CHANNEL];
+
+ if (count > pdevinfo->buf_size) {
+ /* too many data to write */
+ pr_warning("mxc_mlb150: overflow write data\n");
+ return -EFBIG;
+ }
+
+ *f_pos = 0;
+
+ read_lock_irqsave(&tx_rbuf->rb_lock, flags);
+
+ head = tx_rbuf->head;
+ tail = ACCESS_ONCE(tx_rbuf->tail);
+ read_unlock_irqrestore(&tx_rbuf->rb_lock, flags);
+
+ if (0 == CIRC_SPACE(head, tail, TRANS_RING_NODES)) {
+ if (filp->f_flags & O_NONBLOCK)
+ return -EAGAIN;
+ do {
+ DEFINE_WAIT(__wait);
+
+ for (;;) {
+ prepare_to_wait(&pdevinfo->tx_wq,
+ &__wait, TASK_INTERRUPTIBLE);
+
+ read_lock_irqsave(&tx_rbuf->rb_lock, flags);
+ if (CIRC_SPACE(tx_rbuf->head, tx_rbuf->tail,
+ TRANS_RING_NODES) > 0) {
+ read_unlock_irqrestore(&tx_rbuf->rb_lock,
+ flags);
+ break;
+ }
+ read_unlock_irqrestore(&tx_rbuf->rb_lock,
+ flags);
+
+ if (!signal_pending(current)) {
+ schedule();
+ continue;
+ }
+ return -ERESTARTSYS;
+ }
+ finish_wait(&pdevinfo->tx_wq, &__wait);
+ } while (0);
+ }
+
+ if (copy_from_user((void *)tx_rbuf->virt_bufs[head], buf, count)) {
+ read_unlock_irqrestore(&tx_rbuf->rb_lock, flags);
+ pr_err("mxc_mlb: copy from user failed\n");
+ ret = -EFAULT;
+ goto out;
+ }
+
+ write_lock_irqsave(&tx_rbuf->rb_lock, flags);
+ smp_wmb();
+ tx_rbuf->head = (head + 1) & (TRANS_RING_NODES - 1);
+ write_unlock_irqrestore(&tx_rbuf->rb_lock, flags);
+
+ if (0 == CIRC_CNT(head, tail, TRANS_RING_NODES)) {
+ u32 tx_buf_ptr, ahb_ch;
+ s32 adt_sts;
+ u32 ctype = pdevinfo->channel_type;
+
+ /* read index before reading contents at that index */
+ smp_read_barrier_depends();
+
+ tx_buf_ptr = tx_rbuf->phy_addrs[tail];
+
+ ahb_ch = pdevinfo->channels[TX_CHANNEL].cl;
+ adt_sts = mlb150_dev_get_adt_sts(ahb_ch);
+
+ /* Set ADT for TX */
+ mlb150_dev_pipo_next(ahb_ch, ctype, adt_sts, tx_buf_ptr);
+ }
+
+ ret = count;
+out:
+ return ret;
+}
+
+static unsigned int mxc_mlb150_poll(struct file *filp,
+ struct poll_table_struct *wait)
+{
+ int minor;
+ unsigned int ret = 0;
+ struct mlb_data *drvdata = filp->private_data;
+ struct mlb_dev_info *pdevinfo = drvdata->devinfo;
+ struct mlb_ringbuf *tx_rbuf = &pdevinfo->tx_rbuf;
+ struct mlb_ringbuf *rx_rbuf = &pdevinfo->rx_rbuf;
+ int head, tail;
+ unsigned long flags;
+
+
+ minor = MINOR(file_inode(filp)->i_rdev);
+
+ poll_wait(filp, &pdevinfo->rx_wq, wait);
+ poll_wait(filp, &pdevinfo->tx_wq, wait);
+
+ read_lock_irqsave(&tx_rbuf->rb_lock, flags);
+ head = tx_rbuf->head;
+ tail = tx_rbuf->tail;
+ read_unlock_irqrestore(&tx_rbuf->rb_lock, flags);
+
+ /* check the tx buffer is avaiable or not */
+ if (CIRC_SPACE(head, tail, TRANS_RING_NODES) >= 1)
+ ret |= POLLOUT | POLLWRNORM;
+
+ read_lock_irqsave(&rx_rbuf->rb_lock, flags);
+ head = rx_rbuf->head;
+ tail = rx_rbuf->tail;
+ read_unlock_irqrestore(&rx_rbuf->rb_lock, flags);
+
+ /* check the rx buffer filled or not */
+ if (CIRC_CNT(head, tail, TRANS_RING_NODES) >= 1)
+ ret |= POLLIN | POLLRDNORM;
+
+
+ /* check the exception event */
+ if (pdevinfo->ex_event)
+ ret |= POLLIN | POLLRDNORM;
+
+ return ret;
+}
+
+/*
+ * char dev file operations structure
+ */
+static const struct file_operations mxc_mlb150_fops = {
+
+ .owner = THIS_MODULE,
+ .open = mxc_mlb150_open,
+ .release = mxc_mlb150_release,
+ .unlocked_ioctl = mxc_mlb150_ioctl,
+ .poll = mxc_mlb150_poll,
+ .read = mxc_mlb150_read,
+ .write = mxc_mlb150_write,
+};
+
+static struct platform_device_id imx_mlb150_devtype[] = {
+ {
+ .name = "imx6q-mlb150",
+ .driver_data = MLB_QUIRK_MLB150,
+ }, {
+ .name = "imx6sx-mlb50",
+ .driver_data = 0,
+ }, {
+ /* sentinel */
+ }
+};
+MODULE_DEVICE_TABLE(platform, imx_mlb150_devtype);
+
+static const struct of_device_id mlb150_imx_dt_ids[] = {
+ { .compatible = "fsl,imx6q-mlb150",
+ .data = &imx_mlb150_devtype[IMX6Q_MLB], },
+ { .compatible = "fsl,imx6sx-mlb50",
+ .data = &imx_mlb150_devtype[IMX6SX_MLB], },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, mlb150_imx_dt_ids);
+
+/*
+ * This function is called whenever the MLB device is detected.
+ */
+static int mxc_mlb150_probe(struct platform_device *pdev)
+{
+ int ret, mlb_major, i;
+ struct mlb_data *drvdata;
+ struct resource *res;
+ struct device_node *np = pdev->dev.of_node;
+ const struct of_device_id *of_id;
+
+ drvdata = devm_kzalloc(&pdev->dev, sizeof(struct mlb_data),
+ GFP_KERNEL);
+ if (!drvdata) {
+ dev_err(&pdev->dev, "can't allocate enough memory\n");
+ return -ENOMEM;
+ }
+
+ drvdata->dev = &pdev->dev;
+ of_id = of_match_device(mlb150_imx_dt_ids, &pdev->dev);
+ if (of_id)
+ pdev->id_entry = of_id->data;
+ else
+ return -EINVAL;
+ /*
+ * Register MLB lld as four character devices
+ */
+ ret = alloc_chrdev_region(&drvdata->firstdev, 0,
+ MLB_MINOR_DEVICES, "mxc_mlb150");
+ if (ret < 0) {
+ dev_err(&pdev->dev, "alloc region error\n");
+ goto err_reg;
+ }
+ mlb_major = MAJOR(drvdata->firstdev);
+ dev_dbg(&pdev->dev, "MLB device major: %d\n", mlb_major);
+
+ cdev_init(&drvdata->cdev, &mxc_mlb150_fops);
+ drvdata->cdev.owner = THIS_MODULE;
+
+ ret = cdev_add(&drvdata->cdev, drvdata->firstdev, MLB_MINOR_DEVICES);
+ if (ret) {
+ dev_err(&pdev->dev, "can't add cdev\n");
+ goto err_reg;
+ }
+
+ /* create class and device for udev information */
+ drvdata->class = class_create(THIS_MODULE, "mlb150");
+ if (IS_ERR(drvdata->class)) {
+ dev_err(&pdev->dev, "failed to create device class\n");
+ ret = -ENOMEM;
+ goto err_class;
+ }
+
+ for (i = 0; i < MLB_MINOR_DEVICES; i++) {
+ struct device *class_dev;
+
+ class_dev = device_create(drvdata->class, NULL,
+ MKDEV(mlb_major, i),
+ NULL, mlb_devinfo[i].dev_name);
+ if (IS_ERR(class_dev)) {
+ dev_err(&pdev->dev, "failed to create mlb150 %s"
+ " class device\n", mlb_devinfo[i].dev_name);
+ ret = -ENOMEM;
+ goto err_dev;
+ }
+ }
+
+ drvdata->quirk_flag = pdev->id_entry->driver_data;
+
+ /* ahb0 irq */
+ drvdata->irq_ahb0 = platform_get_irq(pdev, 1);
+ if (drvdata->irq_ahb0 < 0) {
+ dev_err(&pdev->dev, "No ahb0 irq line provided\n");
+ goto err_dev;
+ }
+ dev_dbg(&pdev->dev, "ahb0_irq: %d\n", drvdata->irq_ahb0);
+ if (devm_request_irq(&pdev->dev, drvdata->irq_ahb0, mlb_ahb_isr,
+ 0, "mlb_ahb0", NULL)) {
+ dev_err(&pdev->dev, "can't claim irq %d\n", drvdata->irq_ahb0);
+ goto err_dev;
+ }
+
+ /* ahb1 irq */
+ drvdata->irq_ahb1 = platform_get_irq(pdev, 2);
+ dev_dbg(&pdev->dev, "ahb1_irq: %d\n", drvdata->irq_ahb1);
+ if (drvdata->irq_ahb1 > 0) {
+ if (devm_request_irq(&pdev->dev, drvdata->irq_ahb1, mlb_ahb_isr,
+ 0, "mlb_ahb1", NULL)) {
+ dev_err(&pdev->dev, "can't claim irq %d\n", drvdata->irq_ahb1);
+ goto err_dev;
+ }
+ }
+
+ /* mlb irq */
+ drvdata->irq_mlb = platform_get_irq(pdev, 0);
+ if (drvdata->irq_mlb < 0) {
+ dev_err(&pdev->dev, "No mlb irq line provided\n");
+ goto err_dev;
+ }
+ dev_dbg(&pdev->dev, "mlb_irq: %d\n", drvdata->irq_mlb);
+ if (devm_request_irq(&pdev->dev, drvdata->irq_mlb, mlb_isr,
+ 0, "mlb", NULL)) {
+ dev_err(&pdev->dev, "can't claim irq %d\n", drvdata->irq_mlb);
+ goto err_dev;
+ }
+
+ /* ioremap from phy mlb to kernel space */
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ dev_err(&pdev->dev, "can't get device resources\n");
+ ret = -ENOENT;
+ goto err_dev;
+ }
+ mlb_base = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(mlb_base)) {
+ dev_err(&pdev->dev,
+ "failed to get ioremap base\n");
+ ret = PTR_ERR(mlb_base);
+ goto err_dev;
+ }
+ drvdata->membase = mlb_base;
+
+#ifdef CONFIG_REGULATOR
+ drvdata->nvcc = devm_regulator_get(&pdev->dev, "reg_nvcc");
+ if (!IS_ERR(drvdata->nvcc)) {
+ regulator_set_voltage(drvdata->nvcc, 2500000, 2500000);
+ dev_err(&pdev->dev, "enalbe regulator\n");
+ ret = regulator_enable(drvdata->nvcc);
+ if (ret) {
+ dev_err(&pdev->dev, "vdd set voltage error\n");
+ goto err_dev;
+ }
+ }
+#endif
+
+#ifdef CONFIG_ARCH_MXC_ARM64
+ drvdata->ipg = devm_clk_get(&pdev->dev, "ipg");
+ if (IS_ERR(drvdata->ipg)) {
+ dev_err(&pdev->dev, "unable to get mlb ipg clock\n");
+ ret = PTR_ERR(drvdata->ipg);
+ goto err_dev;
+ };
+
+ drvdata->hclk = devm_clk_get(&pdev->dev, "hclk");
+ if (IS_ERR(drvdata->hclk)) {
+ dev_err(&pdev->dev, "unable to get mlb hclk clock\n");
+ ret = PTR_ERR(drvdata->hclk);
+ goto err_dev;
+ };
+#endif
+
+ drvdata->mlb = devm_clk_get(&pdev->dev, "mlb");
+ if (IS_ERR(drvdata->mlb)) {
+ dev_err(&pdev->dev, "unable to get mlb clock\n");
+ ret = PTR_ERR(drvdata->mlb);
+ goto err_dev;
+ }
+
+ drvdata->iram_pool = of_gen_pool_get(np, "iram", 0);
+ if (!drvdata->iram_pool)
+ dev_warn(&pdev->dev, "no iram assigned, using external mem\n");
+
+ drvdata->devinfo = NULL;
+ mxc_mlb150_irq_enable(drvdata, 0);
+ platform_set_drvdata(pdev, drvdata);
+ return 0;
+
+err_dev:
+ for (--i; i >= 0; i--)
+ device_destroy(drvdata->class, MKDEV(mlb_major, i));
+
+ class_destroy(drvdata->class);
+err_class:
+ cdev_del(&drvdata->cdev);
+err_reg:
+ unregister_chrdev_region(drvdata->firstdev, MLB_MINOR_DEVICES);
+
+ return ret;
+}
+
+static int mxc_mlb150_remove(struct platform_device *pdev)
+{
+ int i;
+ struct mlb_data *drvdata = platform_get_drvdata(pdev);
+ struct mlb_dev_info *pdevinfo = drvdata->devinfo;
+
+ if (pdevinfo && atomic_read(&pdevinfo->opencnt))
+ clk_disable_unprepare(drvdata->mlb);
+
+ /* disable mlb power */
+#ifdef CONFIG_REGULATOR
+ if (!IS_ERR(drvdata->nvcc))
+ regulator_disable(drvdata->nvcc);
+#endif
+
+ /* destroy mlb device class */
+ for (i = MLB_MINOR_DEVICES - 1; i >= 0; i--)
+ device_destroy(drvdata->class,
+ MKDEV(MAJOR(drvdata->firstdev), i));
+ class_destroy(drvdata->class);
+
+ cdev_del(&drvdata->cdev);
+
+ /* Unregister the two MLB devices */
+ unregister_chrdev_region(drvdata->firstdev, MLB_MINOR_DEVICES);
+
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int mxc_mlb150_suspend(struct platform_device *pdev, pm_message_t state)
+{
+ struct mlb_data *drvdata = platform_get_drvdata(pdev);
+ struct mlb_dev_info *pdevinfo = drvdata->devinfo;
+
+ if (pdevinfo && atomic_read(&pdevinfo->opencnt)) {
+ mlb150_dev_exit();
+ clk_disable_unprepare(drvdata->mlb);
+ }
+
+ return 0;
+}
+
+static int mxc_mlb150_resume(struct platform_device *pdev)
+{
+ struct mlb_data *drvdata = platform_get_drvdata(pdev);
+ struct mlb_dev_info *pdevinfo = drvdata->devinfo;
+
+ if (pdevinfo && atomic_read(&pdevinfo->opencnt)) {
+ clk_prepare_enable(drvdata->mlb);
+ mlb150_dev_init();
+ }
+
+ return 0;
+}
+#else
+#define mxc_mlb150_suspend NULL
+#define mxc_mlb150_resume NULL
+#endif
+
+/*
+ * platform driver structure for MLB
+ */
+static struct platform_driver mxc_mlb150_driver = {
+ .driver = {
+ .name = DRIVER_NAME,
+ .owner = THIS_MODULE,
+ .of_match_table = mlb150_imx_dt_ids,
+ },
+ .probe = mxc_mlb150_probe,
+ .remove = mxc_mlb150_remove,
+ .suspend = mxc_mlb150_suspend,
+ .resume = mxc_mlb150_resume,
+ .id_table = imx_mlb150_devtype,
+};
+
+static int __init mxc_mlb150_init(void)
+{
+ return platform_driver_register(&mxc_mlb150_driver);
+}
+
+static void __exit mxc_mlb150_exit(void)
+{
+ platform_driver_unregister(&mxc_mlb150_driver);
+}
+
+module_init(mxc_mlb150_init);
+module_exit(mxc_mlb150_exit);
+
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("MLB150 low level driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/mxc/sim/Kconfig b/drivers/mxc/sim/Kconfig
new file mode 100644
index 000000000000..d5b9e3e1e929
--- /dev/null
+++ b/drivers/mxc/sim/Kconfig
@@ -0,0 +1,27 @@
+#
+# SIM configuration
+#
+
+menu "MXC SIM Support"
+
+config MXC_SIMv2
+ tristate "MXC SIMv2 support"
+ depends on ARCH_MXC && MXC_SIM
+ default n
+ ---help---
+ Say Y if you want to use the SIMv2 on NXP i.MX6/7 processors.
+
+ This driver can also be built as a module. If so, the module
+ will be called imx_sim.
+
+config MXC_EMVSIM
+ tristate "IMX EMVSIM support"
+ depends on ARCH_MXC_ARM64 && MXC_SIM
+ default n
+ ---help---
+ Say Y here if you want to use the EMVSIM on NXP i.MX8 processors.
+
+ This driver can also be built as a module. If so, the module
+ will be called imx_emvsim.
+
+endmenu
diff --git a/drivers/mxc/sim/Makefile b/drivers/mxc/sim/Makefile
new file mode 100644
index 000000000000..7b1ca96b6b28
--- /dev/null
+++ b/drivers/mxc/sim/Makefile
@@ -0,0 +1,6 @@
+#
+# Makefile for the i.MX SIM driver
+#
+
+obj-$(CONFIG_MXC_SIMv2) += imx_sim.o
+obj-$(CONFIG_MXC_EMVSIM) += imx_emvsim.o
diff --git a/drivers/mxc/sim/imx_emvsim.c b/drivers/mxc/sim/imx_emvsim.c
new file mode 100644
index 000000000000..59f54dcd533e
--- /dev/null
+++ b/drivers/mxc/sim/imx_emvsim.c
@@ -0,0 +1,1638 @@
+/*
+ * Copyright 2017 NXP
+ *
+ * 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/clk.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/ioport.h>
+#include <linux/kernel.h>
+#include <linux/miscdevice.h>
+#include <linux/module.h>
+#include <linux/mxc_sim_interface.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/poll.h>
+#include <linux/sched.h>
+#include <linux/spinlock.h>
+#include <linux/time.h>
+#include <linux/types.h>
+
+#define DRIVER_NAME "mxc_emvsim"
+
+/* Definitions of the offset of the SIM hardware registers */
+#define EMV_SIM_VER_ID 0X00
+#define EMV_SIM_PARAM 0X04
+#define EMV_SIM_CLKCFG 0X08
+#define EMV_SIM_DIVISOR 0X0C
+#define EMV_SIM_CTRL 0X10
+#define EMV_SIM_INT_MASK 0X14
+#define EMV_SIM_RX_THD 0X18
+#define EMV_SIM_TX_THD 0X1C
+#define EMV_SIM_RX_STATUS 0X20
+#define EMV_SIM_TX_STATUS 0X24
+#define EMV_SIM_PCSR 0X28
+#define EMV_SIM_RX_BUF 0X2C
+#define EMV_SIM_TX_BUF 0X30
+#define EMV_SIM_TX_GETU 0X34
+#define EMV_SIM_CWT_VAL 0X38
+#define EMV_SIM_BWT_VAL 0X3C
+#define EMV_SIM_BGT_VAL 0X40
+#define EMV_SIM_GPCNT0_VAL 0X44
+#define EMV_SIM_GPCNT1_VAL 0X48
+
+#define SIM_XMT_BUFFER_SIZE 300
+#define SIM_RCV_BUFFER_SIZE 400
+
+#define SIM_TX_FIFO_DEPTH 16
+#define SIM_RX_FIFO_DEPTH 16
+#define TX_FIFO_THRESHOLD 4
+
+#define SIM_STATE_REMOVED 0
+#define SIM_STATE_DETECTED 1
+#define SIM_STATE_ATR_RECEIVING 2
+#define SIM_STATE_ATR_RECEIVED 3
+#define SIM_STATE_XMTING 4
+#define SIM_STATE_XMT_DONE 5
+#define SIM_STATE_XMT_ERROR 6
+#define SIM_STATE_RECEIVING 7
+#define SIM_STATE_RECEIVE_DONE 8
+#define SIM_STATE_RECEIVE_ERROR 9
+#define SIM_STATE_RESET_SEQUENCY 10
+
+#define SIM_CNTL_GPCNT_RESET 0
+#define SIM_CNTL_GPCNT_CARD_CLK 1
+#define SIM_CNTL_GPCNT_RCV_CLK 2
+#define SIM_CNTL_GPCNT_ETU_CLK 3
+#define SIM_EMV_NACK_THRESHOLD 5
+#define EMV_T0_BGT 16
+#define EMV_T1_BGT 22
+#define ATR_THRESHOLD_MAX 100
+#define ATR_MAX_CWT 10080
+#define ATR_MAX_DURATION 20160
+#define FCLK_FREQ 4000000
+
+#define ATR_TIMEOUT 5
+#define TX_TIMEOUT 10
+#define RX_TIMEOUT 100
+#define RESET_RETRY_TIMES 5
+#define EMV_RESET_LOW_CYCLES 40000
+#define ATR_MAX_DELAY_CLK 46400
+#define DIVISOR_VALUE 372
+
+#define SIM_CNTL_GPCNT0_CLK_SEL_MASK (3 << 10)
+#define SIM_CNTL_GPCNT0_CLK_SEL(x) ((x & 3) << 10)
+#define SIM_CNTL_GPCNT1_CLK_SEL_MASK (3 << 8)
+#define SIM_CNTL_GPCNT1_CLK_SEL(x) ((x & 3) << 8)
+
+/* EMV_SIM_CTRL */
+#define IC (1 << 0)
+#define ICM (1 << 1)
+#define ANACK (1 << 2)
+#define ONACK (1 << 3)
+#define FLSH_RX (1 << 8)
+#define FLSH_TX (1 << 9)
+#define SW_RST (1 << 10)
+#define KILL_CLOCKS (1 << 11)
+#define RCV_EN (1 << 16)
+#define XMT_EN (1 << 17)
+#define RCVR_11 (1 << 18)
+#define CWT_EN (1 << 27)
+#define BWT_EN (1 << 31)
+
+/* EMV_SIM_INT_MASK */
+#define RDT_IM (1 << 0)
+#define TC_IM (1 << 1)
+#define ETC_IM (1 << 3)
+#define TNACK_IM (1 << 5)
+#define TDT_IM (1 << 7)
+#define GPCNT0_IM (1 << 8)
+#define CWT_ERR_IM (1 << 9)
+#define RNACK_IM (1 << 10)
+#define BWT_ERR_IM (1 << 11)
+#define GPCNT1_IM (1 << 13)
+#define RX_DATA_IM (1 << 14)
+
+/* EMV_SIM_RX_THD */
+#define SIM_RCV_THRESHOLD_RDT_MASK (0x0f << 0)
+#define SIM_RCV_THRESHOLD_RDT(x) ((x & 0x0f) << 0)
+#define SIM_RCV_THRESHOLD_RTH_MASK (0x0f << 8)
+#define SIM_RCV_THRESHOLD_RTH(x) ((x & 0x0f) << 8)
+
+/* EMV_SIM_TX_THD */
+#define SIM_XMT_THRESHOLD_TDT_MASK (0x0f << 0)
+#define SIM_XMT_THRESHOLD_TDT(x) ((x & 0x0f) << 0)
+#define SIM_XMT_THRESHOLD_XTH_MASK (0x0f << 8)
+#define SIM_XMT_THRESHOLD_XTH(x) ((x & 0x0f) << 8)
+
+/* EMV_SIM_RX_STATUS */
+#define RX_DATA (1 << 4)
+#define RDTF (1 << 5)
+#define CWT_ERR (1 << 8)
+#define RTE (1 << 9)
+#define BWT_ERR (1 << 10)
+#define BGT_ERR (1 << 11)
+#define PEF (1 << 12)
+#define FEF (1 << 13)
+
+/* EMV_SIM_TX_STATUS */
+#define TNTE (1 << 0)
+#define ETCF (1 << 4)
+#define TCF (1 << 5)
+#define TDTF (1 << 7)
+#define GPCNT0_TO (1 << 8)
+#define GPCNT1_TO (1 << 9)
+
+/* EMV_SIM_PCSR */
+#define SAPD (1 << 0)
+#define SVCC_EN (1 << 1)
+#define VCCENP (1 << 2)
+#define SRST (1 << 3)
+#define SCEN (1 << 4)
+#define SPD (1 << 7)
+#define SPDIM (1 << 24)
+#define SPDIF (1 << 25)
+#define SPDP (1 << 26)
+#define SPDES (1 << 27)
+
+struct emvsim_t {
+ s32 present;
+ u8 open_cnt;
+ int state;
+ struct clk *clk;
+ struct clk *ipg;
+ struct resource *res;
+ void __iomem *ioaddr;
+ int irq;
+
+ int errval;
+ int protocol_type;
+ sim_timing_t timing_data;
+ sim_baud_t baud_rate;
+ int timeout;
+ u8 nack_threshold;
+ u8 nack_enable;
+ u32 expected_rcv_cnt;
+ u8 is_fixed_len_rec;
+ u32 xmt_remaining;
+ u32 xmt_pos;
+ u32 rcv_count;
+ u8 rcv_buffer[SIM_RCV_BUFFER_SIZE];
+ u8 xmt_buffer[SIM_XMT_BUFFER_SIZE];
+ struct completion xfer_done;
+ u16 rcv_head;
+ spinlock_t lock;
+ u32 clk_rate;
+ u8 checking_ts_timing;
+};
+
+static struct miscdevice emvsim_dev;
+
+static void emvsim_data_reset(struct emvsim_t *emvsim)
+{
+ emvsim->errval = SIM_OK;
+ emvsim->protocol_type = 0;
+ emvsim->timeout = 0;
+ emvsim->nack_threshold = SIM_EMV_NACK_THRESHOLD;
+ emvsim->nack_enable = 0;
+ memset(&emvsim->timing_data, 0, sizeof(emvsim->timing_data));
+ memset(&emvsim->baud_rate, 0, sizeof(emvsim->baud_rate));
+
+ emvsim->xmt_remaining = 0;
+ emvsim->xmt_pos = 0;
+ emvsim->rcv_count = 0;
+ emvsim->rcv_head = 0;
+ memset(emvsim->rcv_buffer, 0, SIM_RCV_BUFFER_SIZE);
+ memset(emvsim->xmt_buffer, 0, SIM_XMT_BUFFER_SIZE);
+
+ reinit_completion(&emvsim->xfer_done);
+};
+
+static void emvsim_set_nack(struct emvsim_t *emvsim, u8 enable)
+{
+ u32 reg_val;
+
+ reg_val = __raw_readl(emvsim->ioaddr + EMV_SIM_CTRL);
+ /*Disable overrun NACK setting for now*/
+ reg_val &= ~ONACK;
+
+ if (enable) {
+ reg_val |= ANACK;
+ __raw_writel(reg_val, emvsim->ioaddr + EMV_SIM_CTRL);
+
+ reg_val = __raw_readl(emvsim->ioaddr + EMV_SIM_TX_THD);
+ reg_val &= ~(SIM_XMT_THRESHOLD_XTH_MASK);
+ reg_val |= SIM_XMT_THRESHOLD_XTH(emvsim->nack_threshold);
+ __raw_writel(reg_val, emvsim->ioaddr + EMV_SIM_TX_THD);
+ } else {
+ reg_val &= ~ANACK;
+ __raw_writel(reg_val, emvsim->ioaddr + EMV_SIM_CTRL);
+ }
+
+ emvsim->nack_enable = enable;
+}
+
+static void emvsim_set_tx(struct emvsim_t *emvsim, u8 enable)
+{
+ u32 reg_data;
+
+ reg_data = __raw_readl(emvsim->ioaddr + EMV_SIM_CTRL);
+ if (enable) {
+ reg_data |= XMT_EN;
+ reg_data &= ~RCV_EN;
+ } else {
+ reg_data &= ~XMT_EN;
+ }
+
+ __raw_writel(reg_data, emvsim->ioaddr + EMV_SIM_CTRL);
+}
+
+static void emvsim_set_rx(struct emvsim_t *emvsim, u8 enable)
+{
+ u32 reg_data;
+
+ reg_data = __raw_readl(emvsim->ioaddr + EMV_SIM_CTRL);
+ if (enable) {
+ reg_data |= RCV_EN;
+ reg_data &= ~XMT_EN;
+ } else {
+ reg_data &= ~RCV_EN;
+ }
+
+ __raw_writel(reg_data, emvsim->ioaddr + EMV_SIM_CTRL);
+}
+
+static void emvsim_mask_timer0_int(struct emvsim_t *emvsim)
+{
+ u32 reg_data;
+
+ reg_data = __raw_readl(emvsim->ioaddr + EMV_SIM_INT_MASK);
+ reg_data |= GPCNT0_IM;
+ __raw_writel(reg_data, emvsim->ioaddr + EMV_SIM_INT_MASK);
+
+ reg_data = __raw_readl(emvsim->ioaddr + EMV_SIM_TX_STATUS);
+ reg_data |= GPCNT0_TO;
+ __raw_writel(reg_data, emvsim->ioaddr + EMV_SIM_TX_STATUS);
+}
+
+static void emvsim_mask_timer1_int(struct emvsim_t *emvsim)
+{
+ u32 reg_data;
+
+ reg_data = __raw_readl(emvsim->ioaddr + EMV_SIM_INT_MASK);
+ reg_data |= GPCNT1_IM;
+ __raw_writel(reg_data, emvsim->ioaddr + EMV_SIM_INT_MASK);
+
+ reg_data = __raw_readl(emvsim->ioaddr + EMV_SIM_TX_STATUS);
+ reg_data |= GPCNT1_TO;
+ __raw_writel(reg_data, emvsim->ioaddr + EMV_SIM_TX_STATUS);
+}
+
+static void emvsim_set_gpctimer0_clk(struct emvsim_t *emvsim, u8 clk_source)
+{
+ u32 reg_data;
+
+ reg_data = __raw_readl(emvsim->ioaddr + EMV_SIM_CLKCFG);
+ reg_data &= ~SIM_CNTL_GPCNT0_CLK_SEL_MASK;
+ reg_data |= SIM_CNTL_GPCNT0_CLK_SEL(clk_source);
+ writel(reg_data, emvsim->ioaddr + EMV_SIM_CLKCFG);
+}
+
+static void emvsim_set_gpctimer1_clk(struct emvsim_t *emvsim, u8 clk_source)
+{
+ u32 reg_data;
+
+ reg_data = __raw_readl(emvsim->ioaddr + EMV_SIM_CLKCFG);
+ reg_data &= ~SIM_CNTL_GPCNT1_CLK_SEL_MASK;
+ reg_data |= SIM_CNTL_GPCNT1_CLK_SEL(clk_source);
+ writel(reg_data, emvsim->ioaddr + EMV_SIM_CLKCFG);
+}
+
+static void emvsim_reset_gpctimer(struct emvsim_t *emvsim)
+{
+ emvsim_set_gpctimer0_clk(emvsim, SIM_CNTL_GPCNT_RESET);
+ emvsim_set_gpctimer1_clk(emvsim, SIM_CNTL_GPCNT_RESET);
+
+ /* need a tx_en posedge to update gpctimer0 clk */
+ emvsim_set_tx(emvsim, 0);
+ emvsim_set_tx(emvsim, 1);
+ emvsim_set_tx(emvsim, 0);
+}
+
+static int emvsim_reset_low_timing(struct emvsim_t *emvsim, u32 clock_cycle)
+{
+ int errval = 0;
+ int timeout = 0;
+ u32 fclk_in_khz, delay_in_us, reg_data;
+
+ fclk_in_khz = emvsim->clk_rate / MSEC_PER_SEC;
+ delay_in_us = EMV_RESET_LOW_CYCLES * USEC_PER_MSEC / fclk_in_khz;
+
+ emvsim_mask_timer0_int(emvsim);
+ __raw_writel(clock_cycle, emvsim->ioaddr + EMV_SIM_GPCNT0_VAL);
+ emvsim_set_gpctimer0_clk(emvsim, SIM_CNTL_GPCNT_CARD_CLK);
+ emvsim_set_tx(emvsim, 1);
+
+ reg_data = __raw_readl(emvsim->ioaddr + EMV_SIM_INT_MASK);
+ reg_data &= ~GPCNT0_IM;
+ __raw_writel(reg_data, emvsim->ioaddr + EMV_SIM_INT_MASK);
+
+ timeout = wait_for_completion_timeout(
+ &emvsim->xfer_done,
+ msecs_to_jiffies(delay_in_us / 1000 * 2));
+ if (timeout == 0) {
+ dev_err(emvsim_dev.parent, "Reset low GPC timout\n");
+ errval = -SIM_E_TIMEOUT;
+ }
+
+ return errval;
+}
+
+static void emvsim_set_cwt(struct emvsim_t *emvsim, u8 enable)
+{
+ u32 reg_val;
+
+ reg_val = __raw_readl(emvsim->ioaddr + EMV_SIM_CTRL);
+ if (enable && emvsim->timing_data.cwt)
+ reg_val |= CWT_EN;
+ else
+ reg_val &= ~CWT_EN;
+ __raw_writel(reg_val, emvsim->ioaddr + EMV_SIM_CTRL);
+}
+
+static void emvsim_set_bwt(struct emvsim_t *emvsim, u8 enable)
+{
+ u32 reg_val;
+
+ reg_val = __raw_readl(emvsim->ioaddr + EMV_SIM_CTRL);
+ if (enable && (emvsim->timing_data.bwt || emvsim->timing_data.bgt))
+ reg_val |= BWT_EN;
+ else
+ reg_val &= ~BWT_EN;
+ __raw_writel(reg_val, emvsim->ioaddr + EMV_SIM_CTRL);
+}
+
+static int emvsim_reset_module(struct emvsim_t *emvsim)
+{
+ u32 reg_val;
+
+ reg_val = __raw_readl(emvsim->ioaddr + EMV_SIM_CTRL);
+ reg_val |= SW_RST;
+ __raw_writel(reg_val, emvsim->ioaddr + EMV_SIM_CTRL);
+
+ /* Software should allow a minimum of 4 Protocol clock cycles(4MHz)*/
+ usleep_range(1, 3);
+
+ return 0;
+}
+
+static void emvsim_receive_atr_set(struct emvsim_t *emvsim)
+{
+ u32 reg_data;
+
+ __raw_writel(0x0, emvsim->ioaddr + EMV_SIM_GPCNT1_VAL);
+ emvsim_set_gpctimer1_clk(emvsim, SIM_CNTL_GPCNT_ETU_CLK);
+ emvsim_set_rx(emvsim, 1);
+
+ /*Set the cwt timer.Refer the setting of ATR on EMV4.3 book*/
+ __raw_writel(ATR_MAX_CWT, emvsim->ioaddr + EMV_SIM_CWT_VAL);
+
+ reg_data = __raw_readl(emvsim->ioaddr + EMV_SIM_CTRL);
+ reg_data |= CWT_EN;
+ __raw_writel(reg_data, emvsim->ioaddr + EMV_SIM_CTRL);
+
+ emvsim_set_nack(emvsim, 0);
+ emvsim->errval = 0;
+ emvsim->rcv_count = 0;
+ emvsim->checking_ts_timing = 1;
+ emvsim->state = SIM_STATE_ATR_RECEIVING;
+
+ reg_data = __raw_readl(emvsim->ioaddr + EMV_SIM_INT_MASK);
+ reg_data |= CWT_ERR_IM;
+ reg_data &= ~(RX_DATA_IM | GPCNT0_IM);
+ __raw_writel(reg_data, emvsim->ioaddr + EMV_SIM_INT_MASK);
+}
+
+static int32_t emvsim_check_rec_data(u32 *reg_data)
+{
+ s32 err = 0;
+
+ if (*reg_data & CWT_ERR)
+ err |= SIM_ERROR_CWT;
+
+ if (*reg_data & FEF)
+ err |= SIM_ERROR_FRAME;
+
+ if (*reg_data & PEF)
+ err |= SIM_ERROR_PARITY;
+
+ return err;
+}
+
+static void emvsim_xmt_fill_fifo(struct emvsim_t *emvsim)
+{
+ u32 reg_data;
+ u32 bytesleft, i;
+
+ reg_data = __raw_readl(emvsim->ioaddr + EMV_SIM_TX_STATUS);
+ bytesleft = SIM_TX_FIFO_DEPTH - ((reg_data >> 24) & 0x1F);
+
+ if (bytesleft > emvsim->xmt_remaining)
+ bytesleft = emvsim->xmt_remaining;
+
+ for (i = 0; i < bytesleft; i++) {
+ __raw_writel(emvsim->xmt_buffer[emvsim->xmt_pos],
+ emvsim->ioaddr + EMV_SIM_TX_BUF);
+ emvsim->xmt_pos++;
+ };
+ emvsim->xmt_remaining -= bytesleft;
+};
+
+static void emvsim_rcv_read_fifo(struct emvsim_t *emvsim)
+{
+ u16 i, count;
+ u32 reg_data;
+ u8 data;
+
+ count = __raw_readl(emvsim->ioaddr + EMV_SIM_RX_STATUS) >> 24;
+
+ spin_lock(&emvsim->lock);
+ for (i = 0; i < count; i++) {
+ reg_data = __raw_readl(emvsim->ioaddr + EMV_SIM_RX_STATUS);
+ emvsim->errval |= emvsim_check_rec_data(&reg_data);
+
+ /* T1 mode and t0 mode no parity error, T1 mode SIM module
+ * will not produce NACK be NACK is disabled. T0 mode to
+ * ensure there is no parity error for the current byte
+ */
+ if (!(emvsim->nack_enable && (reg_data & PEF))) {
+ data = __raw_readb(emvsim->ioaddr + EMV_SIM_RX_BUF);
+ emvsim->rcv_buffer[emvsim->rcv_head + emvsim->rcv_count] = data;
+ emvsim->rcv_count++;
+ }
+
+ if (emvsim->rcv_head + emvsim->rcv_count >=
+ SIM_RCV_BUFFER_SIZE) {
+ dev_err(emvsim_dev.parent,
+ "The software fifo is full,head %d, cnt%d\n",
+ emvsim->rcv_head, emvsim->rcv_count);
+ break;
+ }
+ }
+ spin_unlock(&emvsim->lock);
+}
+
+static void emvsim_tx_irq_enable(struct emvsim_t *emvsim)
+{
+ u32 reg_val;
+
+ /*Clear the TX&RX status, W1C */
+ reg_val = __raw_readl(emvsim->ioaddr + EMV_SIM_TX_STATUS);
+ __raw_writel(reg_val, emvsim->ioaddr + EMV_SIM_TX_STATUS);
+ reg_val = __raw_readl(emvsim->ioaddr + EMV_SIM_RX_STATUS);
+ __raw_writel(reg_val, emvsim->ioaddr + EMV_SIM_RX_STATUS);
+
+ reg_val = __raw_readl(emvsim->ioaddr + EMV_SIM_INT_MASK);
+ reg_val |= CWT_ERR_IM | BWT_ERR_IM | RX_DATA_IM | RX_DATA_IM;
+
+ if (emvsim->xmt_remaining != 0) {
+ reg_val &= ~TDT_IM;
+ } else {
+ reg_val &= ~TC_IM;
+ reg_val &= ~ETC_IM;
+ }
+
+ /* NACK interrupt is enabled only when T0 mode*/
+ if (emvsim->protocol_type == SIM_PROTOCOL_T0 ||
+ emvsim->nack_enable != 0)
+ reg_val &= ~TNACK_IM;
+ else
+ reg_val |= TNACK_IM;
+
+ __raw_writel(reg_val, emvsim->ioaddr + EMV_SIM_INT_MASK);
+}
+
+static void emvsim_tx_irq_disable(struct emvsim_t *emvsim)
+{
+ u32 reg_val;
+
+ reg_val = __raw_readl(emvsim->ioaddr + EMV_SIM_INT_MASK);
+ reg_val |= (TDT_IM | TC_IM | TNACK_IM | ETC_IM);
+ __raw_writel(reg_val, emvsim->ioaddr + EMV_SIM_INT_MASK);
+}
+
+static void emvsim_rx_irq_enable(struct emvsim_t *emvsim)
+{
+ u32 reg_data;
+
+ /* Ensure the CWT timer is enabled */
+ emvsim_set_cwt(emvsim, 1);
+
+ reg_data = __raw_readl(emvsim->ioaddr + EMV_SIM_INT_MASK);
+ reg_data |= (TC_IM | TDT_IM | TNACK_IM);
+ reg_data &= ~(RX_DATA_IM | CWT_ERR_IM | BWT_ERR_IM);
+
+ if (emvsim->protocol_type == SIM_PROTOCOL_T0 ||
+ emvsim->nack_enable != 0)
+ reg_data &= ~RNACK_IM;
+ else
+ reg_data |= RNACK_IM;
+
+ __raw_writel(reg_data, emvsim->ioaddr + EMV_SIM_INT_MASK);
+}
+
+static void emvsim_rx_irq_disable(struct emvsim_t *emvsim)
+{
+ u32 reg_val;
+
+ reg_val = __raw_readl(emvsim->ioaddr + EMV_SIM_INT_MASK);
+ reg_val |= (RX_DATA_IM | CWT_ERR_IM | BWT_ERR_IM | RNACK_IM);
+ __raw_writel(reg_val, emvsim->ioaddr + EMV_SIM_INT_MASK);
+}
+
+static irqreturn_t emvsim_irq_handler(int irq, void *dev_id)
+{
+ u32 reg_data, tx_status, rx_status;
+ struct emvsim_t *emvsim = (struct emvsim_t *)dev_id;
+
+ /* clear TX/RX interrupt status, W1C*/
+ tx_status = __raw_readl(emvsim->ioaddr + EMV_SIM_TX_STATUS);
+ rx_status = __raw_readl(emvsim->ioaddr + EMV_SIM_RX_STATUS);
+ __raw_writel(tx_status, emvsim->ioaddr + EMV_SIM_TX_STATUS);
+ __raw_writel(rx_status, emvsim->ioaddr + EMV_SIM_RX_STATUS);
+
+ if (emvsim->state == SIM_STATE_ATR_RECEIVING &&
+ emvsim->checking_ts_timing == 1) {
+ if ((tx_status & GPCNT0_TO) && !(rx_status & RX_DATA)) {
+ reg_data = __raw_readl(emvsim->ioaddr + EMV_SIM_CTRL);
+ reg_data &= ~CWT_EN;
+ __raw_writel(reg_data, emvsim->ioaddr + EMV_SIM_CTRL);
+
+ reg_data = __raw_readl(emvsim->ioaddr + EMV_SIM_INT_MASK);
+ reg_data |= (GPCNT0_IM | CWT_ERR_IM | RX_DATA_IM);
+ __raw_writel(reg_data, emvsim->ioaddr + EMV_SIM_INT_MASK);
+
+ emvsim->errval = SIM_ERROR_ATR_DELAY;
+ complete(&emvsim->xfer_done);
+ emvsim->checking_ts_timing = 0;
+ } else if (rx_status & RX_DATA) {
+ u8 rdt = 1;
+
+ emvsim_mask_timer0_int(emvsim);
+
+ /* ATR each received byte will cost 12 ETU */
+ reg_data = ATR_MAX_DURATION - emvsim->rcv_count * 12;
+ __raw_writel(reg_data, emvsim->ioaddr + EMV_SIM_GPCNT1_VAL);
+
+ reg_data = __raw_readl(emvsim->ioaddr + EMV_SIM_INT_MASK);
+ reg_data &= ~(GPCNT1_IM | CWT_ERR_IM | RX_DATA_IM);
+ __raw_writel(reg_data, emvsim->ioaddr + EMV_SIM_INT_MASK);
+ emvsim_rcv_read_fifo(emvsim);
+
+ reg_data = __raw_readl(emvsim->ioaddr + EMV_SIM_TX_STATUS);
+ reg_data |= GPCNT1_TO;
+ __raw_writel(reg_data, emvsim->ioaddr + EMV_SIM_TX_STATUS);
+
+ reg_data = SIM_RCV_THRESHOLD_RTH(0) | SIM_RCV_THRESHOLD_RDT(rdt);
+ __raw_writel(reg_data, emvsim->ioaddr + EMV_SIM_RX_THD);
+
+ /* ATR has arrived as EMV demands */
+ emvsim->checking_ts_timing = 0;
+ } else {
+ dev_err(emvsim_dev.parent,
+ "Unexpected irq when delay checking\n");
+ }
+ }
+
+ else if (emvsim->state == SIM_STATE_ATR_RECEIVING) {
+ /*CWT ERROR OR ATR_MAX_DURATION TIMEOUT */
+ if ((rx_status & CWT_ERR) ||
+ ((tx_status & GPCNT1_TO) && (emvsim->rcv_count != 0))) {
+ reg_data = __raw_readl(emvsim->ioaddr + EMV_SIM_CTRL);
+ reg_data &= ~CWT_EN;
+ __raw_writel(reg_data, emvsim->ioaddr + EMV_SIM_CTRL);
+
+ reg_data = __raw_readl(emvsim->ioaddr +
+ EMV_SIM_INT_MASK);
+ reg_data |= (GPCNT1_IM | CWT_ERR_IM | RX_DATA_IM | GPCNT0_IM);
+ __raw_writel(reg_data, emvsim->ioaddr +
+ EMV_SIM_INT_MASK);
+
+ if (tx_status & GPCNT1_TO)
+ emvsim->errval |= SIM_ERROR_ATR_TIMEROUT;
+
+ if (rx_status & CWT_ERR)
+ emvsim->errval |= SIM_ERROR_CWT;
+
+ emvsim_rcv_read_fifo(emvsim);
+ emvsim->state = SIM_STATE_ATR_RECEIVED;
+
+ complete(&emvsim->xfer_done);
+ } else if (rx_status & RX_DATA) {
+ emvsim_rcv_read_fifo(emvsim);
+ }
+ }
+
+ else if (emvsim->state == SIM_STATE_XMTING) {
+ /* need to enable CWT timer */
+ if (tx_status & ETCF)
+ emvsim_set_cwt(emvsim, 1);
+
+ if (tx_status & TNTE) {
+ emvsim_set_tx(emvsim, 0);
+
+ /*Disalbe the timers*/
+ emvsim_set_cwt(emvsim, 0);
+ emvsim_set_bwt(emvsim, 0);
+
+ /*Disable the NACK interruptand TX related interrupt*/
+ emvsim_tx_irq_disable(emvsim);
+
+ /*Update the state and status*/
+ emvsim->errval |= SIM_ERROR_NACK_THRESHOLD;
+ emvsim->state = SIM_STATE_XMT_ERROR;
+
+ complete(&emvsim->xfer_done);
+ } else if (tx_status & TDTF && emvsim->xmt_remaining != 0) {
+ emvsim_xmt_fill_fifo(emvsim);
+ if (emvsim->xmt_remaining == 0) {
+ reg_data = __raw_readl(emvsim->ioaddr +
+ EMV_SIM_INT_MASK);
+ reg_data |= TDT_IM;
+ reg_data &= ~(TC_IM | ETC_IM);
+ __raw_writel(reg_data, emvsim->ioaddr +
+ EMV_SIM_INT_MASK);
+ }
+ } else if ((tx_status & TCF) && !emvsim->xmt_remaining) {
+ emvsim_tx_irq_disable(emvsim);
+ emvsim_set_rx(emvsim, 1);
+ emvsim->state = SIM_STATE_XMT_DONE;
+ complete(&emvsim->xfer_done);
+ }
+ }
+
+ /*
+ * It takes some time to change from SIM_STATE_XMT_DONE to
+ * SIM_STATE_RECEIVING RX would only be enabled after state
+ * becomes SIM_STATE_RECEIVING
+ */
+ else if (emvsim->state == SIM_STATE_RECEIVING) {
+ if (rx_status & RTE) {
+ emvsim_set_rx(emvsim, 0);
+
+ /* Disable the BWT timer and CWT timer right now */
+ emvsim_set_cwt(emvsim, 0);
+ emvsim_set_bwt(emvsim, 0);
+
+ /* Disable the interrupt right now */
+ emvsim_rx_irq_disable(emvsim);
+
+ /* Should we read the fifo or just flush the fifo? */
+ emvsim_rcv_read_fifo(emvsim);
+ emvsim->errval = SIM_ERROR_NACK_THRESHOLD;
+ emvsim->state = SIM_STATE_RECEIVE_ERROR;
+ complete(&emvsim->xfer_done);
+ }
+
+ if (rx_status & RX_DATA) {
+ emvsim_rcv_read_fifo(emvsim);
+ if (emvsim->is_fixed_len_rec &&
+ emvsim->rcv_count >= emvsim->expected_rcv_cnt) {
+ emvsim_rx_irq_disable(emvsim);
+
+ if (emvsim->state == SIM_STATE_RECEIVING) {
+ emvsim->state = SIM_STATE_RECEIVE_DONE;
+ complete(&emvsim->xfer_done);
+ }
+ }
+ }
+
+ if (rx_status & (CWT_ERR | BWT_ERR | BGT_ERR)) {
+ emvsim_set_cwt(emvsim, 0);
+ emvsim_set_bwt(emvsim, 0);
+ emvsim_rx_irq_disable(emvsim);
+
+ if (rx_status & BWT_ERR)
+ emvsim->errval |= SIM_ERROR_BWT;
+ if (rx_status & CWT_ERR)
+ emvsim->errval |= SIM_ERROR_CWT;
+ if (rx_status & BGT_ERR)
+ emvsim->errval |= SIM_ERROR_BGT;
+
+ emvsim_rcv_read_fifo(emvsim);
+
+ if (emvsim->state == SIM_STATE_RECEIVING) {
+ emvsim->state = SIM_STATE_RECEIVE_DONE;
+ complete(&emvsim->xfer_done);
+ }
+ }
+ }
+
+ else if ((emvsim->state == SIM_STATE_RESET_SEQUENCY) &&
+ (tx_status & GPCNT0_TO)) {
+ complete(&emvsim->xfer_done);
+ emvsim_mask_timer0_int(emvsim);
+ } else if (rx_status & RX_DATA) {
+ dev_err(emvsim_dev.parent,
+ "unexpected status %d\n", emvsim->state);
+ emvsim_rcv_read_fifo(emvsim);
+ }
+
+ return IRQ_HANDLED;
+};
+
+static void emvsim_start(struct emvsim_t *emvsim)
+{
+ u32 reg_data, clk_rate, clk_div = 0;
+
+ clk_rate = clk_get_rate(emvsim->clk);
+ clk_div = (clk_rate + emvsim->clk_rate - 1) / emvsim->clk_rate;
+ __raw_writel(clk_div, emvsim->ioaddr + EMV_SIM_CLKCFG);
+
+ usleep_range(90, 100);
+ /* SPDP=0: SIM Presence Detect pin is low, default PRESENT status */
+ if (__raw_readl(emvsim->ioaddr + EMV_SIM_PCSR) & SPDP) {
+ emvsim->present = SIM_PRESENT_REMOVED;
+ emvsim->state = SIM_STATE_REMOVED;
+ } else {
+ emvsim->present = SIM_PRESENT_DETECTED;
+ emvsim->state = SIM_STATE_DETECTED;
+ };
+
+ /* disabled card interrupt. clear interrupt status*/
+ reg_data = __raw_readl(emvsim->ioaddr + EMV_SIM_PCSR);
+ reg_data |= SPDIM | SPDIF;
+ __raw_writel(reg_data, emvsim->ioaddr + EMV_SIM_PCSR);
+};
+
+static void emvsim_cold_reset_sequency(struct emvsim_t *emvsim)
+{
+ u32 reg_data;
+
+ emvsim->state = SIM_STATE_RESET_SEQUENCY;
+
+ reg_data = __raw_readl(emvsim->ioaddr + EMV_SIM_PCSR);
+ reg_data &= ~VCCENP;
+ reg_data |= SVCC_EN;
+ __raw_writel(reg_data, emvsim->ioaddr + EMV_SIM_PCSR);
+
+ msleep(20);
+
+ reg_data = __raw_readl(emvsim->ioaddr + EMV_SIM_PCSR);
+ reg_data |= SCEN;
+ __raw_writel(reg_data, emvsim->ioaddr + EMV_SIM_PCSR);
+
+ emvsim_reset_low_timing(emvsim, EMV_RESET_LOW_CYCLES);
+
+ reg_data = __raw_readl(emvsim->ioaddr + EMV_SIM_PCSR);
+ reg_data |= SRST;
+ __raw_writel(reg_data, emvsim->ioaddr + EMV_SIM_PCSR);
+
+ emvsim_mask_timer0_int(emvsim);
+ __raw_writel(ATR_MAX_DELAY_CLK, emvsim->ioaddr +
+ EMV_SIM_GPCNT0_VAL);
+};
+
+static void emvsim_deactivate(struct emvsim_t *emvsim)
+{
+ u32 reg_data;
+
+ /* Auto powdown to implement the deactivate sequence */
+ if (emvsim->present != SIM_PRESENT_REMOVED) {
+ reg_data = __raw_readl(emvsim->ioaddr + EMV_SIM_PCSR);
+ reg_data |= SAPD | SPD;
+ writel(reg_data, emvsim->ioaddr + EMV_SIM_PCSR);
+ } else {
+ dev_err(emvsim_dev.parent, ">>>No card%s\n", __func__);
+ }
+};
+
+static void emvsim_cold_reset(struct emvsim_t *emvsim)
+{
+ if (emvsim->present != SIM_PRESENT_REMOVED) {
+ emvsim->state = SIM_STATE_DETECTED;
+ emvsim->present = SIM_PRESENT_DETECTED;
+ emvsim_cold_reset_sequency(emvsim);
+ emvsim_receive_atr_set(emvsim);
+ } else {
+ dev_err(emvsim_dev.parent, "No card%s\n", __func__);
+ }
+};
+
+static void emvsim_warm_reset_sequency(struct emvsim_t *emvsim)
+{
+ u32 reg_data;
+
+ /*enable power/clk, deassert rst*/
+ emvsim->state = SIM_STATE_RESET_SEQUENCY;
+ reg_data = __raw_readl(emvsim->ioaddr + EMV_SIM_PCSR);
+ reg_data |= (SRST | SCEN);
+ reg_data &= ~VCCENP;
+ reg_data |= SVCC_EN;
+ __raw_writel(reg_data, emvsim->ioaddr + EMV_SIM_PCSR);
+
+ usleep_range(20, 25);
+
+ /* assert rst */
+ reg_data = __raw_readl(emvsim->ioaddr + EMV_SIM_PCSR);
+ reg_data &= ~SRST;
+ __raw_writel(reg_data, emvsim->ioaddr + EMV_SIM_PCSR);
+
+ /* rst keep low */
+ emvsim_reset_low_timing(emvsim, EMV_RESET_LOW_CYCLES);
+
+ /* deassert rst */
+ reg_data = __raw_readl(emvsim->ioaddr + EMV_SIM_PCSR);
+ reg_data |= SRST;
+ __raw_writel(reg_data, emvsim->ioaddr + EMV_SIM_PCSR);
+
+ emvsim_mask_timer0_int(emvsim);
+ __raw_writel(ATR_MAX_DELAY_CLK, emvsim->ioaddr + EMV_SIM_GPCNT0_VAL);
+}
+
+static void emvsim_warm_reset(struct emvsim_t *emvsim)
+{
+ if (emvsim->present != SIM_PRESENT_REMOVED) {
+ emvsim_data_reset(emvsim);
+ emvsim_reset_gpctimer(emvsim);
+ emvsim_warm_reset_sequency(emvsim);
+ emvsim_receive_atr_set(emvsim);
+ } else {
+ dev_err(emvsim_dev.parent, "No card%s\n", __func__);
+ }
+};
+
+static int emvsim_card_lock(struct emvsim_t *emvsim)
+{
+ int errval;
+
+ /* place holder for true physcial locking */
+ if (emvsim->present != SIM_PRESENT_REMOVED)
+ errval = SIM_OK;
+ else
+ errval = -SIM_E_NOCARD;
+
+ return errval;
+};
+
+static int emvsim_card_eject(struct emvsim_t *emvsim)
+{
+ int errval;
+
+ /* place holder for true physcial locking */
+ if (emvsim->present != SIM_PRESENT_REMOVED)
+ errval = SIM_OK;
+ else
+ errval = -SIM_E_NOCARD;
+
+ return errval;
+};
+
+static int emvsim_check_baud_rate(sim_baud_t *baud_rate)
+{
+ /* The valid value is decribed in the 8.3.3.1 in EMV 4.3 */
+ if (baud_rate->fi == 1 && (baud_rate->di == 1 ||
+ baud_rate->di == 2 || baud_rate->di == 3))
+ return 0;
+
+ return -EINVAL;
+}
+
+static int emvsim_set_baud_rate(struct emvsim_t *emvsim)
+{
+ u32 reg_data;
+
+ switch (emvsim->baud_rate.di) {
+ case 1:
+ reg_data = 372;
+ break;
+ case 2:
+ reg_data = 372 >> 1;
+ break;
+ case 3:
+ reg_data = 372 >> 2;
+ break;
+ default:
+ dev_err(emvsim_dev.parent,
+ "Invalid baud Di, Using default 372 / 1\n");
+ reg_data = 372;
+ break;
+ }
+
+ __raw_writel(reg_data, emvsim->ioaddr + EMV_SIM_DIVISOR);
+
+ return 0;
+}
+
+static int emvsim_check_timing_data(sim_timing_t *timing_data)
+{
+ if (timing_data->wwt > 0xFFFF || timing_data->cwt > 0xFFFF ||
+ timing_data->bgt > 0xFFFF || timing_data->cgt > 0xFF) {
+ dev_err(emvsim_dev.parent,
+ "The timing value is out of scope of IP\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static void emvsim_set_timer_counter(struct emvsim_t *emvsim)
+{
+ u32 reg;
+
+ if (emvsim->timing_data.wwt != 0 &&
+ emvsim->protocol_type == SIM_PROTOCOL_T0) {
+ emvsim->timing_data.cwt = emvsim->timing_data.wwt;
+ emvsim->timing_data.bwt = emvsim->timing_data.wwt;
+ }
+
+ if (emvsim->timing_data.bgt != 0)
+ __raw_writel(emvsim->timing_data.bgt,
+ emvsim->ioaddr + EMV_SIM_BGT_VAL);
+
+ if (emvsim->timing_data.cwt != 0)
+ __raw_writel(emvsim->timing_data.cwt,
+ emvsim->ioaddr + EMV_SIM_CWT_VAL);
+
+ if (emvsim->timing_data.bwt != 0)
+ __raw_writel(emvsim->timing_data.bwt,
+ emvsim->ioaddr + EMV_SIM_BWT_VAL);
+
+ /* 11 etu and 12 etu, T0: 12ETU; T1: 11ETU */
+ if (emvsim->protocol_type == SIM_PROTOCOL_T0) {
+ /*
+ * From EMV4.3 , T0 mode means 12 ETU. TotalETU=12+CGT.
+ * If cgt equals 0xFF, TotalETU = 12
+ */
+ reg = __raw_readl(emvsim->ioaddr + EMV_SIM_CTRL);
+ reg &= ~RCVR_11;
+ __raw_writel(reg, emvsim->ioaddr + EMV_SIM_CTRL);
+
+ /* set Transmitter Guard Time Value in ETU */
+ if (emvsim->timing_data.cgt == 0xFF)
+ __raw_writel(0, emvsim->ioaddr + EMV_SIM_TX_GETU);
+ else
+ __raw_writel(emvsim->timing_data.cgt,
+ emvsim->ioaddr + EMV_SIM_TX_GETU);
+ } else if (emvsim->protocol_type == SIM_PROTOCOL_T1) {
+ /* From EMV4.3 , T1 mode means 11 ETU. TotalETU=11+CGT */
+ reg = __raw_readl(emvsim->ioaddr + EMV_SIM_CTRL);
+ reg |= RCVR_11;
+ __raw_writel(reg, emvsim->ioaddr + EMV_SIM_CTRL);
+ __raw_writel(emvsim->timing_data.cgt,
+ emvsim->ioaddr + EMV_SIM_TX_GETU);
+ }
+}
+
+static int emvsim_xmt_start(struct emvsim_t *emvsim)
+{
+ u32 reg_val;
+
+ emvsim_set_baud_rate(emvsim);
+ if (emvsim->protocol_type == SIM_PROTOCOL_T0) {
+ emvsim_set_nack(emvsim, 1);
+ } else if (emvsim->protocol_type == SIM_PROTOCOL_T1) {
+ emvsim_set_nack(emvsim, 0);
+ } else {
+ dev_err(emvsim_dev.parent, "Invalid protocol not T0 or T1\n");
+ return -EINVAL;
+ }
+
+ emvsim_set_timer_counter(emvsim);
+
+ if (emvsim->xmt_remaining != 0) {
+ reg_val = __raw_readl(emvsim->ioaddr + EMV_SIM_TX_THD);
+ reg_val &= ~SIM_XMT_THRESHOLD_TDT_MASK;
+ reg_val |= SIM_XMT_THRESHOLD_TDT(TX_FIFO_THRESHOLD);
+ __raw_writel(reg_val, emvsim->ioaddr + EMV_SIM_TX_THD);
+ }
+
+ emvsim_set_bwt(emvsim, 1);
+ emvsim_set_cwt(emvsim, 0);
+
+ emvsim_set_tx(emvsim, 1);
+ emvsim_xmt_fill_fifo(emvsim);
+ emvsim_tx_irq_enable(emvsim);
+ emvsim->state = SIM_STATE_XMTING;
+
+ return 0;
+}
+
+static void emvsim_flush_fifo(struct emvsim_t *emvsim, u8 flush_tx, u8 flush_rx)
+{
+ u32 reg_val;
+
+ reg_val = __raw_readl(emvsim->ioaddr + EMV_SIM_CTRL);
+
+ if (flush_tx)
+ reg_val |= FLSH_TX;
+ if (flush_rx)
+ reg_val |= FLSH_RX;
+ __raw_writel(reg_val, emvsim->ioaddr + EMV_SIM_CTRL);
+}
+
+static void emvsim_start_rcv(struct emvsim_t *emvsim)
+{
+ int rdt = 1;
+
+ emvsim->state = SIM_STATE_RECEIVING;
+
+ emvsim_set_rx(emvsim, 1);
+ emvsim_set_baud_rate(emvsim);
+ emvsim_set_timer_counter(emvsim);
+ emvsim_set_cwt(emvsim, 1);
+ emvsim_set_bwt(emvsim, 1);
+
+ if (emvsim->protocol_type == SIM_PROTOCOL_T0)
+ emvsim_set_nack(emvsim, 1);
+ else if (emvsim->protocol_type == SIM_PROTOCOL_T1)
+ emvsim_set_nack(emvsim, 0);
+
+ /*Set RX threshold*/
+ if (emvsim->protocol_type == SIM_PROTOCOL_T0)
+ __raw_writel(SIM_RCV_THRESHOLD_RTH(emvsim->nack_threshold) |
+ SIM_RCV_THRESHOLD_RDT(rdt),
+ emvsim->ioaddr + EMV_SIM_RX_THD);
+ else
+ __raw_writel(SIM_RCV_THRESHOLD_RDT(rdt),
+ emvsim->ioaddr + EMV_SIM_RX_THD);
+
+ /*Clear status and enable interrupt*/
+ emvsim_rx_irq_enable(emvsim);
+}
+
+static void emvsim_polling_delay(struct emvsim_t *emvsim, u32 delay)
+{
+ u32 reg_data;
+ unsigned long orig_jiffies = jiffies;
+
+ emvsim_mask_timer1_int(emvsim);
+
+ __raw_writel(delay, emvsim->ioaddr + EMV_SIM_GPCNT0_VAL);
+ reg_data = __raw_readl(emvsim->ioaddr + EMV_SIM_INT_MASK);
+ reg_data &= ~GPCNT1_IM;
+ __raw_writel(reg_data, emvsim->ioaddr + EMV_SIM_INT_MASK);
+
+ /* Loop for timeout, add timeout mechanism to avoid dead loop */
+ while (!(__raw_readl(emvsim->ioaddr + EMV_SIM_TX_STATUS) & GPCNT0_TO)) {
+ if (time_after(jiffies, orig_jiffies + msecs_to_jiffies(500))) {
+ dev_err(emvsim_dev.parent, "polling delay timeout\n");
+ break;
+ }
+
+ usleep_range(10, 20);
+ }
+
+ emvsim_mask_timer1_int(emvsim);
+}
+
+void emvsim_clear_rx_buf(struct emvsim_t *emvsim)
+{
+ unsigned int i;
+
+ for (i = 0; i < SIM_RCV_BUFFER_SIZE; i++)
+ emvsim->rcv_buffer[i] = 0;
+ emvsim->rcv_count = 0;
+ emvsim->rcv_head = 0;
+}
+
+static long emvsim_ioctl(struct file *file,
+ unsigned int cmd, unsigned long arg)
+{
+ int ret, errval = SIM_OK;
+ unsigned long timeout;
+ u32 reg_data;
+ u32 delay;
+ u32 copy_cnt, val;
+ unsigned long flags;
+ unsigned char __user *atr_buffer;
+ unsigned char __user *xmt_buffer;
+ unsigned char __user *rcv_buffer;
+
+ struct emvsim_t *emvsim = (struct emvsim_t *)file->private_data;
+
+ switch (cmd) {
+ case SIM_IOCTL_GET_ATR:
+ if (emvsim->present != SIM_PRESENT_DETECTED) {
+ dev_err(emvsim_dev.parent, "NO card ...\n");
+ errval = -SIM_E_NOCARD;
+ break;
+ }
+
+ emvsim->timeout = ATR_TIMEOUT * HZ;
+ val = 0;
+ ret = copy_to_user(&(((sim_atr_t *)arg)->size), &val,
+ sizeof((((sim_atr_t *)arg)->size)));
+
+ timeout = wait_for_completion_interruptible_timeout(
+ &emvsim->xfer_done, emvsim->timeout);
+
+ reg_data = __raw_readl(emvsim->ioaddr + EMV_SIM_CTRL);
+ reg_data &= ~CWT_EN;
+ __raw_writel(reg_data, emvsim->ioaddr + EMV_SIM_CTRL);
+
+ reg_data = __raw_readl(emvsim->ioaddr + EMV_SIM_INT_MASK);
+ reg_data |= (GPCNT0_IM | CWT_ERR_IM);
+ __raw_writel(reg_data, emvsim->ioaddr + EMV_SIM_INT_MASK);
+
+ if (timeout == 0) {
+ dev_err(emvsim_dev.parent, "ATR timeout\n");
+ errval = -SIM_E_TIMEOUT;
+ break;
+ }
+
+ ret = copy_to_user(&(((sim_atr_t *)arg)->size),
+ &emvsim->rcv_count,
+ sizeof(emvsim->rcv_count));
+ if (ret) {
+ dev_err(emvsim_dev.parent,
+ "ATR ACCESS rcv_count Error, %d\n", ret);
+ errval = -SIM_E_ACCESS;
+ break;
+ }
+
+ __get_user(atr_buffer, &((sim_atr_t __user *)arg)->atr_buffer);
+ ret = copy_to_user(atr_buffer,
+ emvsim->rcv_buffer, emvsim->rcv_count);
+ if (ret) {
+ dev_err(emvsim_dev.parent,
+ "ATR ACCESS buffer Error %d %d\n",
+ emvsim->rcv_count, ret);
+ errval = -SIM_E_ACCESS;
+ break;
+ }
+
+ ret = copy_to_user(&(((sim_atr_t *)arg)->errval),
+ &emvsim->errval, sizeof(emvsim->errval));
+ if (ret) {
+ dev_err(emvsim_dev.parent, "ATR ACCESS Error\n");
+ errval = -SIM_E_ACCESS;
+ break;
+ }
+ emvsim->rcv_count = 0;
+ emvsim->rcv_head = 0;
+ emvsim->errval = 0;
+
+ break;
+
+ case SIM_IOCTL_DEACTIVATE:
+ emvsim_deactivate(emvsim);
+ break;
+
+ case SIM_IOCTL_COLD_RESET:
+ emvsim->present = SIM_PRESENT_REMOVED;
+ emvsim->state = SIM_STATE_REMOVED;
+ emvsim_reset_module(emvsim);
+ emvsim_data_reset(emvsim);
+ emvsim_start(emvsim);
+ emvsim_cold_reset(emvsim);
+ break;
+
+ case SIM_IOCTL_WARM_RESET:
+ emvsim_warm_reset(emvsim);
+ break;
+
+ case SIM_IOCTL_XMT:
+ ret = copy_from_user(&emvsim->xmt_remaining,
+ &(((sim_xmt_t *)arg)->xmt_length),
+ sizeof(uint32_t));
+ if (ret || emvsim->xmt_remaining > SIM_XMT_BUFFER_SIZE) {
+ dev_err(emvsim_dev.parent,
+ "copy error or to big buffer\n");
+ errval = -EINVAL;
+ break;
+ }
+
+ __get_user(xmt_buffer, &((sim_xmt_t *)arg)->xmt_buffer);
+ ret = copy_from_user(emvsim->xmt_buffer, xmt_buffer,
+ emvsim->xmt_remaining);
+ if (ret) {
+ dev_err(emvsim_dev.parent, "Copy Error\n");
+ errval = ret;
+ break;
+ }
+
+ emvsim_clear_rx_buf(emvsim);
+ emvsim_set_cwt(emvsim, 0);
+ emvsim_set_bwt(emvsim, 0);
+ /*Flush the tx rx fifo*/
+ emvsim_flush_fifo(emvsim, 1, 1);
+ emvsim->xmt_pos = 0;
+ emvsim->errval = 0;
+
+ errval = emvsim_xmt_start(emvsim);
+ if (errval)
+ break;
+
+ emvsim->timeout = TX_TIMEOUT * HZ;
+ timeout = wait_for_completion_interruptible_timeout(
+ &emvsim->xfer_done, emvsim->timeout);
+ if (timeout == 0) {
+ /*Disable the NACK interruptand TX related interrupt*/
+ emvsim_tx_irq_disable(emvsim);
+ dev_err(emvsim_dev.parent, "tx timeout\n");
+ }
+
+ if (timeout == 0 || emvsim->state == SIM_STATE_XMT_ERROR) {
+ dev_err(emvsim_dev.parent, "TX error\n");
+ /*Disable timers*/
+ emvsim_set_cwt(emvsim, 0);
+ emvsim_set_bwt(emvsim, 0);
+ /*Disable TX*/
+ emvsim_set_tx(emvsim, 0);
+ /*Flush the tx fifos*/
+ emvsim_flush_fifo(emvsim, 1, 0);
+ if (timeout == 0)
+ errval = -SIM_E_TIMEOUT;
+ else
+ errval = -SIM_E_NACK;
+
+ ret = copy_to_user(&(((sim_atr_t *)arg)->errval),
+ &emvsim->errval,
+ sizeof(emvsim->errval));
+ emvsim->errval = 0;
+ break;
+ }
+
+ /*Copy the error status to user space*/
+ ret = copy_to_user(&(((sim_atr_t *)arg)->errval),
+ &emvsim->errval, sizeof(emvsim->errval));
+ emvsim->errval = 0;
+
+ emvsim_start_rcv(emvsim);
+
+ break;
+
+ case SIM_IOCTL_RCV:
+ if (emvsim->present != SIM_PRESENT_DETECTED) {
+ errval = -SIM_E_NOCARD;
+ break;
+ }
+
+ val = 0;
+ emvsim->is_fixed_len_rec = 0;
+ ret = copy_from_user(&emvsim->expected_rcv_cnt,
+ &(((sim_rcv_t *)arg)->rcv_length),
+ sizeof(emvsim->expected_rcv_cnt));
+
+ /*Set the length to be 0 at first*/
+ ret = copy_to_user(&(((sim_rcv_t *)arg)->rcv_length), &val,
+ sizeof(val));
+
+ /*Set error value to be 0 at first*/
+ ret = copy_to_user(&(((sim_rcv_t *)arg)->errval), &val,
+ sizeof(val));
+
+ if (emvsim->expected_rcv_cnt != 0)
+ emvsim->is_fixed_len_rec = 1;
+
+ if (emvsim->is_fixed_len_rec &&
+ emvsim->rcv_count >= emvsim->expected_rcv_cnt)
+ goto copy_data;
+
+ if (emvsim->state != SIM_STATE_RECEIVING)
+ emvsim_start_rcv(emvsim);
+
+ spin_lock_irqsave(&emvsim->lock, flags);
+ spin_unlock_irqrestore(&emvsim->lock, flags);
+ emvsim->timeout = RX_TIMEOUT * HZ;
+ timeout = wait_for_completion_interruptible_timeout(
+ &emvsim->xfer_done, emvsim->timeout);
+ if (timeout == 0) {
+ dev_err(emvsim_dev.parent, "Receiving timeout\n");
+ emvsim_set_cwt(emvsim, 0);
+ emvsim_set_bwt(emvsim, 0);
+ emvsim_rx_irq_disable(emvsim);
+ errval = -SIM_E_TIMEOUT;
+ break;
+ }
+copy_data:
+ if (emvsim->is_fixed_len_rec)
+ copy_cnt = emvsim->rcv_count > emvsim->expected_rcv_cnt
+ ? emvsim->expected_rcv_cnt
+ : emvsim->rcv_count;
+ else
+ copy_cnt = emvsim->rcv_count;
+
+ ret = copy_to_user(&(((sim_rcv_t *)arg)->rcv_length),
+ &copy_cnt, sizeof(copy_cnt));
+ if (ret) {
+ dev_err(emvsim_dev.parent, "ATR ACCESS Error\n");
+ errval = -SIM_E_ACCESS;
+ break;
+ }
+
+ __get_user(rcv_buffer, &((sim_rcv_t *)arg)->rcv_buffer);
+ ret = copy_to_user(rcv_buffer,
+ &emvsim->rcv_buffer[emvsim->rcv_head],
+ copy_cnt);
+ if (ret) {
+ dev_err(emvsim_dev.parent, "ATR ACCESS Error\n");
+ errval = -SIM_E_ACCESS;
+ break;
+ }
+
+ ret = copy_to_user(&(((sim_rcv_t *)arg)->errval),
+ &emvsim->errval, sizeof(emvsim->errval));
+ if (ret) {
+ dev_err(emvsim_dev.parent, "ATR ACCESS Error\n");
+ errval = -SIM_E_ACCESS;
+ break;
+ }
+ /*Reset the receiving count and errval*/
+ spin_lock_irqsave(&emvsim->lock, flags);
+ emvsim->rcv_head += copy_cnt;
+ emvsim->rcv_count -= copy_cnt;
+ emvsim->errval = 0;
+ spin_unlock_irqrestore(&emvsim->lock, flags);
+
+ break;
+
+ case SIM_IOCTL_SET_PROTOCOL:
+ ret = copy_from_user(&emvsim->protocol_type, (int *)arg,
+ sizeof(int));
+ if (ret)
+ errval = -SIM_E_ACCESS;
+ break;
+
+ case SIM_IOCTL_SET_TIMING:
+ ret = copy_from_user(&emvsim->timing_data, (sim_timing_t *)arg,
+ sizeof(sim_timing_t));
+ if (ret) {
+ dev_err(emvsim_dev.parent, "Copy Error\n");
+ errval = ret;
+ break;
+ }
+
+ ret = emvsim_check_timing_data(&emvsim->timing_data);
+ if (ret)
+ errval = ret;
+
+ break;
+
+ case SIM_IOCTL_SET_BAUD:
+ ret = copy_from_user(&emvsim->baud_rate, (sim_baud_t *)arg,
+ sizeof(sim_baud_t));
+ if (ret) {
+ dev_err(emvsim_dev.parent, "Copy Error\n");
+ errval = ret;
+ break;
+ }
+
+ emvsim_check_baud_rate(&emvsim->baud_rate);
+
+ break;
+ case SIM_IOCTL_WAIT:
+ ret = copy_from_user(&delay, (unsigned int *)arg,
+ sizeof(unsigned int));
+ if (ret) {
+ dev_err(emvsim_dev.parent, "\nWait Copy Error\n");
+ errval = ret;
+ break;
+ }
+
+ emvsim_polling_delay(emvsim, delay);
+ break;
+
+ case SIM_IOCTL_GET_PRESENSE:
+ if (put_user(emvsim->present, (int *)arg))
+ errval = -SIM_E_ACCESS;
+ break;
+
+ case SIM_IOCTL_CARD_LOCK:
+ errval = emvsim_card_lock(emvsim);
+ break;
+
+ case SIM_IOCTL_CARD_EJECT:
+ errval = emvsim_card_eject(emvsim);
+ break;
+ };
+
+ return errval;
+};
+
+static int emvsim_open(struct inode *inode, struct file *file)
+{
+ int errval = SIM_OK;
+ struct emvsim_t *emvsim = dev_get_drvdata(emvsim_dev.parent);
+
+ file->private_data = emvsim;
+ spin_lock_init(&emvsim->lock);
+
+ if (!emvsim->ioaddr) {
+ errval = -ENOMEM;
+ return errval;
+ }
+
+ if (!emvsim->open_cnt) {
+ clk_prepare_enable(emvsim->ipg);
+ clk_prepare_enable(emvsim->clk);
+ }
+
+ emvsim->open_cnt = 1;
+ init_completion(&emvsim->xfer_done);
+ errval = emvsim_reset_module(emvsim);
+ emvsim_data_reset(emvsim);
+
+ return errval;
+};
+
+static int emvsim_release(struct inode *inode, struct file *file)
+{
+ u32 reg_data;
+ struct emvsim_t *emvsim = (struct emvsim_t *)file->private_data;
+
+ /* disable presense detection interrupt */
+ reg_data = __raw_readl(emvsim->ioaddr + EMV_SIM_PCSR);
+ __raw_writel(reg_data | SPDIM, emvsim->ioaddr + EMV_SIM_PCSR);
+
+ if (emvsim->present != SIM_PRESENT_REMOVED)
+ emvsim_deactivate(emvsim);
+
+ if (emvsim->open_cnt) {
+ clk_disable_unprepare(emvsim->clk);
+ clk_disable_unprepare(emvsim->ipg);
+ }
+
+ emvsim->open_cnt = 0;
+
+ return 0;
+};
+
+static const struct file_operations emvsim_fops = {
+ .owner = THIS_MODULE,
+ .open = emvsim_open,
+ .release = emvsim_release,
+ .unlocked_ioctl = emvsim_ioctl,
+};
+
+static struct miscdevice emvsim_dev = {
+ MISC_DYNAMIC_MINOR,
+ "mxc_sim",
+ &emvsim_fops
+};
+
+static const struct of_device_id emvsim_imx_dt_ids[] = {
+ { .compatible = "fsl,imx8-emvsim" },
+ { /* sentinel */ }
+};
+
+MODULE_DEVICE_TABLE(of, emvsim_imx_dt_ids);
+
+static int emvsim_probe(struct platform_device *pdev)
+{
+ int ret = 0;
+ const struct of_device_id *of_id;
+ struct emvsim_t *emvsim = NULL;
+
+ emvsim = devm_kzalloc(&pdev->dev, sizeof(struct emvsim_t),
+ GFP_KERNEL);
+ if (!emvsim)
+ return -ENOMEM;
+
+ of_id = of_match_device(emvsim_imx_dt_ids, &pdev->dev);
+ if (of_id)
+ pdev->id_entry = of_id->data;
+ else
+ return -EINVAL;
+
+ emvsim->clk_rate = FCLK_FREQ;
+ emvsim->open_cnt = 0;
+
+ emvsim->res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!emvsim->res) {
+ dev_err(emvsim_dev.parent, "Can't get the MEMORY\n");
+ return -ENOMEM;
+ }
+ emvsim->ioaddr = devm_ioremap_resource(&pdev->dev, emvsim->res);
+ if (IS_ERR(emvsim->ioaddr)) {
+ dev_err(&pdev->dev,
+ "failed to get ioremap base\n");
+ ret = PTR_ERR(emvsim->ioaddr);
+ return ret;
+ }
+
+ /* request the emvsim per clk and ipg clk */
+ emvsim->clk = devm_clk_get(&pdev->dev, "sim");
+ if (IS_ERR(emvsim->clk)) {
+ ret = PTR_ERR(emvsim->clk);
+ dev_err(emvsim_dev.parent, "Get PER CLK ERROR !\n");
+ return ret;
+ }
+
+ emvsim->ipg = devm_clk_get(&pdev->dev, "ipg");
+ if (IS_ERR(emvsim->ipg)) {
+ ret = PTR_ERR(emvsim->ipg);
+ dev_err(emvsim_dev.parent, "Get IPG CLK ERROR !\n");
+ return ret;
+ }
+
+ emvsim->irq = platform_get_irq(pdev, 0);
+ if (emvsim->irq < 0) {
+ dev_err(&pdev->dev, "No irq line provided\n");
+ return -ENOENT;
+ }
+
+ if (devm_request_irq(&pdev->dev, emvsim->irq, emvsim_irq_handler,
+ 0, "mxc_emvsim_irq", emvsim)) {
+ dev_err(&pdev->dev, "can't claim irq %d\n", emvsim->irq);
+ return -ENOENT;
+ }
+
+ platform_set_drvdata(pdev, emvsim);
+ emvsim_dev.parent = &pdev->dev;
+
+ ret = misc_register(&emvsim_dev);
+ dev_info(&pdev->dev, "emvsim register %s\n", ret ? "fail" : "success");
+
+ return ret;
+}
+
+static int emvsim_remove(struct platform_device *pdev)
+{
+ struct emvsim_t *emvsim = platform_get_drvdata(pdev);
+
+ if (emvsim->open_cnt) {
+ clk_disable_unprepare(emvsim->clk);
+ clk_disable_unprepare(emvsim->ipg);
+ }
+
+ misc_deregister(&emvsim_dev);
+
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int emvsim_suspend(struct platform_device *pdev, pm_message_t state)
+{
+ struct emvsim_t *emvsim = platform_get_drvdata(pdev);
+
+ if (emvsim->open_cnt) {
+ clk_disable_unprepare(emvsim->clk);
+ clk_disable_unprepare(emvsim->ipg);
+ }
+
+ pinctrl_pm_select_sleep_state(&pdev->dev);
+
+ return 0;
+}
+
+static int emvsim_resume(struct platform_device *pdev)
+{
+ struct emvsim_t *emvsim = platform_get_drvdata(pdev);
+
+ if (!emvsim->open_cnt) {
+ clk_prepare_enable(emvsim->ipg);
+ clk_prepare_enable(emvsim->clk);
+ }
+
+ pinctrl_pm_select_default_state(&pdev->dev);
+
+ return 0;
+}
+
+#else
+#define emvsim_suspend NULL
+#define emvsim_resume NULL
+#endif
+
+static struct platform_driver emvsim_driver = {
+ .driver = {
+ .name = DRIVER_NAME,
+ .owner = THIS_MODULE,
+ .of_match_table = emvsim_imx_dt_ids,
+ },
+ .probe = emvsim_probe,
+ .remove = emvsim_remove,
+ .suspend = emvsim_suspend,
+ .resume = emvsim_resume,
+};
+
+static int __init emvsim_drv_init(void)
+{
+ return platform_driver_register(&emvsim_driver);
+}
+
+static void __exit emvsim_drv_exit(void)
+{
+ platform_driver_unregister(&emvsim_driver);
+}
+
+module_init(emvsim_drv_init);
+module_exit(emvsim_drv_exit);
+
+MODULE_AUTHOR("Gao Pan <pandy.gao@nxp.com>");
+MODULE_DESCRIPTION("NXP EMVSIM Driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/mxc/sim/imx_sim.c b/drivers/mxc/sim/imx_sim.c
new file mode 100755
index 000000000000..e907bd3a8ec8
--- /dev/null
+++ b/drivers/mxc/sim/imx_sim.c
@@ -0,0 +1,1865 @@
+/*
+ * Copyright (C) 2015 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <linux/module.h>
+#include <linux/ioport.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/sched.h>
+#include <linux/io.h>
+#include <linux/interrupt.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/poll.h>
+#include <linux/miscdevice.h>
+#include <linux/clk.h>
+#include <linux/types.h>
+#include <linux/platform_device.h>
+#include <linux/mxc_sim_interface.h>
+#include <linux/spinlock.h>
+#include <linux/time.h>
+
+#include <linux/io.h>
+
+#define DRIVER_NAME "mxc_sim"
+#define SIM_INTERNAL_CLK (0)
+#define SIM_RFU (-1)
+
+/* Transmit and receive buffer sizes */
+#define SIM_XMT_BUFFER_SIZE (300)
+#define SIM_RCV_BUFFER_SIZE (400)
+
+#define SIM_TX_FIFO_DEPTH (16)
+#define SIM_RX_FIFO_DEPTH (285)
+
+#define TX_FIFO_THRESHOLD (0x04)
+#define RX_FIFO_THRESHOLD (250)
+
+/* Interface character references */
+#define SIM_IFC_TXI(letter, number) (letter + number * 4)
+#define SIM_IFC_TA1 SIM_IFC_TXI(0, 0)
+#define SIM_IFC_TB1 SIM_IFC_TXI(0, 1)
+#define SIM_IFC_TC1 SIM_IFC_TXI(0, 2)
+#define SIM_IFC_TD1 SIM_IFC_TXI(0, 3)
+#define SIM_IFC_TA2 SIM_IFC_TXI(1, 0)
+#define SIM_IFC_TB2 SIM_IFC_TXI(1, 1)
+#define SIM_IFC_TC2 SIM_IFC_TXI(1, 2)
+#define SIM_IFC_TD2 SIM_IFC_TXI(1, 3)
+#define SIM_IFC_TA3 SIM_IFC_TXI(2, 0)
+#define SIM_IFC_TB3 SIM_IFC_TXI(2, 1)
+#define SIM_IFC_TC3 SIM_IFC_TXI(2, 2)
+#define SIM_IFC_TD3 SIM_IFC_TXI(2, 3)
+#define SIM_IFC_TA4 SIM_IFC_TXI(3, 0)
+#define SIM_IFC_TB4 SIM_IFC_TXI(3, 1)
+#define SIM_IFC_TC4 SIM_IFC_TXI(3, 2)
+#define SIM_IFC_TD4 SIM_IFC_TXI(3, 3)
+
+/* ATR and OPS states */
+#define SIM_STATE_REMOVED (0)
+#define SIM_STATE_DETECTED (1)
+#define SIM_STATE_ATR_RECEIVING (2)
+#define SIM_STATE_ATR_RECEIVED (3)
+#define SIM_STATE_XMTING (4)
+#define SIM_STATE_XMT_DONE (5)
+#define SIM_STATE_XMT_ERROR (6)
+#define SIM_STATE_RECEIVING (7)
+#define SIM_STATE_RECEIVE_DONE (8)
+#define SIM_STATE_RECEIVE_ERROR (9)
+#define SIM_STATE_RESET_SEQUENCY (10)
+
+/* Definitions of the offset of the SIM hardware registers */
+#define PORT1_CNTL (0x00)
+#define SETUP (0x04)
+#define PORT1_DETECT (0x08)
+#define PORT1_XMT_BUF (0x0C)
+#define PORT1_RCV_BUF (0x10)
+#define PORT0_CNTL (0x14)
+#define CNTL (0x18)
+#define CLK_PRESCALER (0x1C)
+#define RCV_THRESHOLD (0x20)
+#define ENABLE (0x24)
+#define XMT_STATUS (0x28)
+#define RCV_STATUS (0x2C)
+#define INT_MASK (0x30)
+#define PORTO_XMT_BUF (0x34)
+#define PORT0_RCV_BUF (0x38)
+#define PORT0_DETECT (0x3C)
+#define DATA_FORMAT (0x40)
+#define XMT_THRESHOLD (0x44)
+#define GUARD_CNTL (0x48)
+#define OD_CONFIG (0x4C)
+#define RESET_CNTL (0x50)
+#define CHAR_WAIT (0x54)
+#define GPCNT (0x58)
+#define DIVISOR (0x5C)
+#define BWT (0x60)
+#define BGT (0x64)
+#define BWT_H (0x68)
+#define XMT_FIFO_STAT (0x6C)
+#define RCV_FIFO_CNT (0x70)
+#define RCV_FIFO_WPTR (0x74)
+#define RCV_FIFO_RPTR (0x78)
+
+/* SIM SETUP register bits */
+#define SIM_SETUP_SPS_PORT0 (0 << 1)
+#define SIM_SETUP_SPS_PORT1 (1 << 1)
+
+/* SIM port[0|1]_cntl register bits */
+#define SIM_PORT_CNTL_SFPD (1 << 7)
+#define SIM_PORT_CNTL_3VOLT (1 << 6)
+#define SIM_PORT_CNTL_SCSP (1 << 5)
+#define SIM_PORT_CNTL_SCEN (1 << 4)
+#define SIM_PORT_CNTL_SRST (1 << 3)
+#define SIM_PORT_CNTL_STEN (1 << 2)
+#define SIM_PORT_CNTL_SVEN (1 << 1)
+#define SIM_PORT_CNTL_SAPD (1 << 0)
+
+/* SIM od_config register bits */
+#define SIM_OD_CONFIG_OD_P1 (1 << 1)
+#define SIM_OD_CONFIG_OD_P0 (1 << 0)
+
+/* SIM enable register bits */
+#define SIM_ENABLE_XMTEN (1 << 1)
+#define SIM_ENABLE_RCVEN (1 << 0)
+#define SIM_ESTOP_EN (1 << 5)
+#define SIM_ESTOP_EXE (1 << 6)
+
+/* SIM int_mask register bits */
+#define SIM_INT_MASK_RFEM (1 << 13)
+#define SIM_INT_MASK_BGTM (1 << 12)
+#define SIM_INT_MASK_BWTM (1 << 11)
+#define SIM_INT_MASK_RTM (1 << 10)
+#define SIM_INT_MASK_CWTM (1 << 9)
+#define SIM_INT_MASK_GPCM (1 << 8)
+#define SIM_INT_MASK_TDTFM (1 << 7)
+#define SIM_INT_MASK_TFOM (1 << 6)
+#define SIM_INT_MASK_XTM (1 << 5)
+#define SIM_INT_MASK_TFEIM (1 << 4)
+#define SIM_INT_MASK_ETCIM (1 << 3)
+#define SIM_INT_MASK_OIM (1 << 2)
+#define SIM_INT_MASK_TCIM (1 << 1)
+#define SIM_INT_MASK_RIM (1 << 0)
+
+/* SIM xmt_status register bits */
+#define SIM_XMT_STATUS_GPCNT (1 << 8)
+#define SIM_XMT_STATUS_TDTF (1 << 7)
+#define SIM_XMT_STATUS_TFO (1 << 6)
+#define SIM_XMT_STATUS_TC (1 << 5)
+#define SIM_XMT_STATUS_ETC (1 << 4)
+#define SIM_XMT_STATUS_TFE (1 << 3)
+#define SIM_XMT_STATUS_XTE (1 << 0)
+
+/* SIM rcv_status register bits */
+#define SIM_RCV_STATUS_BGT (1 << 11)
+#define SIM_RCV_STATUS_BWT (1 << 10)
+#define SIM_RCV_STATUS_RTE (1 << 9)
+#define SIM_RCV_STATUS_CWT (1 << 8)
+#define SIM_RCV_STATUS_CRCOK (1 << 7)
+#define SIM_RCV_STATUS_LRCOK (1 << 6)
+#define SIM_RCV_STATUS_RDRF (1 << 5)
+#define SIM_RCV_STATUS_RFD (1 << 4)
+#define SIM_RCV_STATUS_RFE (1 << 1)
+#define SIM_RCV_STATUS_OEF (1 << 0)
+
+/* SIM cntl register bits */
+#define SIM_CNTL_BWTEN (1 << 15)
+#define SIM_CNTL_XMT_CRC_LRC (1 << 14)
+#define SIM_CNTL_CRCEN (1 << 13)
+#define SIM_CNTL_LRCEN (1 << 12)
+#define SIM_CNTL_CWTEN (1 << 11)
+#define SIM_CNTL_SAMPLE12 (1 << 4)
+#define SIM_CNTL_ONACK (1 << 3)
+#define SIM_CNTL_ANACK (1 << 2)
+#define SIM_CNTL_ICM (1 << 1)
+#define SIM_CNTL_GPCNT_CLK_SEL(x) ((x&0x03) << 9)
+#define SIM_CNTL_GPCNT_CLK_SEL_MASK (0x03 << 9)
+#define SIM_CNTL_BAUD_SEL(x) ((x&0x07) << 6)
+#define SIM_CNTL_BAUD_SEL_MASK (0x07 << 6)
+#define SIM_CNTL_GPCNT_CARD_CLK 1
+#define SIM_CNTL_GPCNT_RCV_CLK 2
+#define SIM_CNTL_GPCNT_ETU_CLK 3
+
+/* SIM rcv_threshold register bits */
+#define SIM_RCV_THRESHOLD_RTH(x) ((x&0x0f) << 9)
+#define SIM_RCV_THRESHOLD_RTH_MASK (0x0f << 9)
+#define SIM_RCV_THRESHOLD_RDT(x) ((x&0x1ff) << 0)
+#define SIM_RCV_THRESHOLD_RDT_MASK (0x1ff << 0)
+
+/* SIM xmt_threshold register bits */
+#define SIM_XMT_THRESHOLD_XTH(x) ((x&0x0f) << 4)
+#define SIM_XMT_THRESHOLD_XTH_MASK (0x0f << 4)
+#define SIM_XMT_THRESHOLD_TDT(x) ((x&0x0f) << 0)
+#define SIM_XMT_THRESHOLD_TDT_MASK (0x0f << 0)
+
+/* SIM guard_cntl register bits */
+#define SIM_GUARD_CNTL_RCVR11 (1 << 8)
+#define SIM_GIARD_CNTL_GETU(x) (x&0xff)
+#define SIM_GIARD_CNTL_GETU_MASK (0xff)
+
+/* SIM port[0|]_detect register bits */
+#define SIM_PORT_DETECT_SPDS (1 << 3)
+#define SIM_PORT_DETECT_SPDP (1 << 2)
+#define SIM_PORT_DETECT_SDI (1 << 1)
+#define SIM_PORT_DETECT_SDIM (1 << 0)
+
+/* SIM RESET_CNTL register bits*/
+#define SIM_RESET_CNTL_FLUSH_RCV (1 << 0)
+#define SIM_RESET_CNTL_FLUSH_XMT (1 << 1)
+#define SIM_RESET_CNTL_SOFT_RESET (1 << 2)
+#define SIM_RESET_CNTL_KILL_CLOCK (1 << 3)
+#define SIM_RESET_CNTL_DOZE (1 << 4)
+#define SIM_RESET_CNTL_STOP (1 << 5)
+#define SIM_RESET_CNTL_DEBUG (1 << 6)
+
+
+/*SIM receive buffer register error status*/
+#define SIM_REC_CWT_ERROR (1 << 10)
+#define SIM_REC_FRAME_ERROR (1 << 9)
+#define SIM_REC_PARITY_ERROR (1 << 8)
+
+#define SIM_EMV_NACK_THRESHOLD (5)
+#define EMV_T0_BGT (16)
+#define EMV_T1_BGT (22)
+#define ATR_THRESHOLD_MAX (100)
+#define ATR_MAX_CWT (10080)
+#define ATR_MAX_DURATION (20160)
+#define FCLK_FREQ (4000000)
+
+#define ATR_TIMEOUT (5)
+#define TX_TIMEOUT (10)
+#define RX_TIMEOUT (100)
+#define RESET_RETRY_TIMES (5)
+#define SIM_QUIRK_TKT259347 (1 << 0)
+#define EMV_RESET_LOW_CYCLES 40000
+#define ATR_MAX_DELAY_CLK 46400
+
+/* Main SIM driver structure */
+struct sim_t{
+ s32 present;
+ u8 open_cnt;
+ int state;
+ struct clk *clk;
+ struct resource *res;
+ void __iomem *ioaddr;
+ int ipb_irq;
+ int dat_irq;
+
+ /* error code occured during transfer */
+ int errval;
+ int protocol_type;
+ sim_timing_t timing_data;
+ sim_baud_t baud_rate;
+ int timeout;
+ u8 nack_threshold;
+ u8 nack_enable;
+ u32 expected_rcv_cnt;
+ u8 is_fixed_len_rec;
+
+ /* remaining bytes to transmit for the current transfer */
+ u32 xmt_remaining;
+ /* transmit position */
+ u32 xmt_pos;
+ /* receive position / number of bytes received */
+ u32 rcv_count;
+ u8 rcv_buffer[SIM_RCV_BUFFER_SIZE];
+ u8 xmt_buffer[SIM_XMT_BUFFER_SIZE];
+ /* transfer completion notifier */
+ struct completion xfer_done;
+ /* async notifier for card and ATR detection */
+ struct fasync_struct *fasync;
+ /* Platform specific data */
+ struct mxc_sim_platform_data *plat_data;
+ bool last_is_tx;
+ u16 rcv_head;
+ spinlock_t lock;
+ bool sven_low_active;
+ u32 port_index;
+ u32 port_detect_reg;
+ u32 port_ctrl_reg;
+ u32 clk_rate;
+ u32 quirks;
+ u8 checking_ts_timing;
+};
+
+static struct miscdevice sim_dev;
+
+static void sim_data_reset(struct sim_t *sim)
+{
+ sim->errval = SIM_OK;
+ sim->protocol_type = 0;
+ sim->timeout = 0;
+ sim->nack_threshold = SIM_EMV_NACK_THRESHOLD;
+ sim->nack_enable = 0;
+ memset(&sim->timing_data, 0, sizeof(sim->timing_data));
+ memset(&sim->baud_rate, 0, sizeof(sim->baud_rate));
+
+ sim->xmt_remaining = 0;
+ sim->xmt_pos = 0;
+ sim->rcv_count = 0;
+ sim->rcv_head = 0;
+ sim->last_is_tx = false;
+ memset(sim->rcv_buffer, 0, SIM_RCV_BUFFER_SIZE);
+ memset(sim->xmt_buffer, 0, SIM_XMT_BUFFER_SIZE);
+
+ init_completion(&sim->xfer_done);
+};
+
+static void sim_set_nack(struct sim_t *sim, u8 enable)
+{
+ u32 reg_val;
+
+ reg_val = __raw_readl(sim->ioaddr + CNTL);
+ /*Disable overrun NACK setting for now*/
+ reg_val &= ~(SIM_CNTL_ONACK);
+
+ if (enable) {
+ reg_val |= SIM_CNTL_ANACK;
+ __raw_writel(reg_val, sim->ioaddr + CNTL);
+ reg_val = __raw_readl(sim->ioaddr + XMT_THRESHOLD);
+ reg_val &= ~(SIM_XMT_THRESHOLD_XTH_MASK);
+ reg_val |= SIM_XMT_THRESHOLD_XTH(sim->nack_threshold);
+ __raw_writel(reg_val, sim->ioaddr + XMT_THRESHOLD);
+ } else {
+ reg_val &= ~SIM_CNTL_ANACK;
+ __raw_writel(reg_val, sim->ioaddr + CNTL);
+ }
+
+ sim->nack_enable = enable;
+}
+
+static void sim_set_tx(struct sim_t *sim, u8 enable)
+{
+ u32 reg_data;
+
+ reg_data = __raw_readl(sim->ioaddr + ENABLE);
+ if (enable) {
+ reg_data |= SIM_ENABLE_XMTEN | SIM_ENABLE_RCVEN;
+ if (sim->quirks & SIM_QUIRK_TKT259347)
+ reg_data &= ~(SIM_ESTOP_EN | SIM_ESTOP_EXE);
+ } else
+ reg_data &= ~SIM_ENABLE_XMTEN;
+
+ __raw_writel(reg_data, sim->ioaddr + ENABLE);
+}
+
+static void sim_set_rx(struct sim_t *sim, u8 enable)
+{
+ u32 reg_data;
+ reg_data = __raw_readl(sim->ioaddr + ENABLE);
+ if (enable) {
+ reg_data |= SIM_ENABLE_RCVEN;
+ reg_data &= ~SIM_ENABLE_XMTEN;
+ if (sim->quirks & SIM_QUIRK_TKT259347)
+ reg_data |= (SIM_ESTOP_EN | SIM_ESTOP_EXE);
+ } else {
+ reg_data &= ~SIM_ENABLE_RCVEN;
+ if (sim->quirks & SIM_QUIRK_TKT259347)
+ reg_data &= ~(SIM_ESTOP_EN | SIM_ESTOP_EXE);
+ }
+
+ __raw_writel(reg_data, sim->ioaddr + ENABLE);
+}
+
+static void sim_reset_timer(struct sim_t *sim)
+{
+ u32 reg_data;
+
+ reg_data = __raw_readl(sim->ioaddr + CNTL);
+ reg_data &= ~SIM_CNTL_GPCNT_CLK_SEL_MASK;
+ __raw_writel(reg_data, sim->ioaddr + CNTL);
+}
+
+static void sim_start_timer(struct sim_t *sim, u8 clk_source)
+{
+ u32 reg_data;
+
+ reg_data = __raw_readl(sim->ioaddr + CNTL);
+ reg_data &= ~SIM_CNTL_GPCNT_CLK_SEL_MASK;
+ reg_data |= SIM_CNTL_GPCNT_CLK_SEL(clk_source);
+ writel(reg_data, sim->ioaddr + CNTL);
+}
+
+static void sim_set_gpc_timer(struct sim_t *sim, u32 val)
+{
+ uint32_t reg_data;
+
+ /*Clear the interrupt status*/
+ reg_data = __raw_readl(sim->ioaddr + XMT_STATUS);
+ reg_data |= SIM_XMT_STATUS_GPCNT;
+ __raw_writel(reg_data, sim->ioaddr + XMT_STATUS);
+
+ /*Set the timer counter*/
+ __raw_writel(val, sim->ioaddr + GPCNT);
+
+ /*First reset the counter*/
+ sim_reset_timer(sim);
+
+ /*Enable GPC timer interrupt*/
+ reg_data = __raw_readl(sim->ioaddr + INT_MASK);
+ reg_data &= ~SIM_INT_MASK_GPCM;
+ __raw_writel(reg_data, sim->ioaddr + INT_MASK);
+
+ /*Set the GPCNT clock source to be Fclk*/
+ sim_start_timer(sim, SIM_CNTL_GPCNT_CARD_CLK);
+}
+
+static int sim_reset_low_timing(struct sim_t *sim, u32 clock_cycle)
+{
+ int errval = 0;
+ int timeout = 0;
+ u32 fclk_in_khz, delay_in_us, reg_data;
+
+ fclk_in_khz = sim->clk_rate / MSEC_PER_SEC;
+ delay_in_us = EMV_RESET_LOW_CYCLES * USEC_PER_MSEC / fclk_in_khz;
+
+ sim_set_gpc_timer(sim, clock_cycle);
+
+ timeout = wait_for_completion_timeout(&sim->xfer_done,
+ msecs_to_jiffies(delay_in_us / 1000 * 2));
+ if (timeout == 0) {
+ pr_err("Reset low GPC timout\n");
+ errval = -SIM_E_TIMEOUT;
+ }
+
+ sim_reset_timer(sim);
+ /*Disable GPC timer interrupt*/
+ reg_data = __raw_readl(sim->ioaddr + INT_MASK);
+ reg_data |= SIM_INT_MASK_GPCM;
+ __raw_writel(reg_data, sim->ioaddr + INT_MASK);
+
+ return errval;
+}
+
+static void sim_set_cwt(struct sim_t *sim, u8 enable)
+{
+ u32 reg_val;
+ reg_val = __raw_readl(sim->ioaddr + CNTL);
+ if (enable && sim->timing_data.cwt)
+ reg_val |= SIM_CNTL_CWTEN;
+ else
+ reg_val &= ~SIM_CNTL_CWTEN;
+ __raw_writel(reg_val, sim->ioaddr + CNTL);
+}
+
+static void sim_set_bwt(struct sim_t *sim, u8 enable)
+{
+ u32 reg_val;
+ reg_val = __raw_readl(sim->ioaddr + CNTL);
+ if (enable && (sim->timing_data.bwt || sim->timing_data.bgt))
+ reg_val |= SIM_CNTL_BWTEN;
+ else
+ reg_val &= ~SIM_CNTL_BWTEN;
+ __raw_writel(reg_val, sim->ioaddr + CNTL);
+}
+
+static int sim_reset_module(struct sim_t *sim)
+{
+ u32 reg_val;
+ s8 timeout = RESET_RETRY_TIMES;
+
+ reg_val = __raw_readl(sim->ioaddr + RESET_CNTL);
+ reg_val |= (SIM_RESET_CNTL_SOFT_RESET);
+ __raw_writel(reg_val, sim->ioaddr + RESET_CNTL);
+
+ while (__raw_readl(sim->ioaddr + RESET_CNTL) & SIM_RESET_CNTL_SOFT_RESET) {
+ usleep_range(1, 3);
+ if (timeout-- <= 0) {
+ pr_err("SIM module reset timeout\n");
+ return -EINVAL;
+ }
+ }
+ return 0;
+}
+
+static void sim_receive_atr_set(struct sim_t *sim)
+{
+ u32 reg_data;
+
+ /*Enable RX*/
+ sim_set_rx(sim, 1);
+
+ /*Receive fifo threshold = 1*/
+ reg_data = SIM_RCV_THRESHOLD_RTH(0) | SIM_RCV_THRESHOLD_RDT(1);
+ __raw_writel(reg_data, sim->ioaddr + RCV_THRESHOLD);
+
+ /* Clear the interrupt status*/
+ reg_data = __raw_readl(sim->ioaddr + RCV_STATUS);
+ reg_data |= (SIM_RCV_STATUS_CWT | SIM_RCV_STATUS_RDRF);
+ __raw_writel(reg_data, sim->ioaddr + RCV_STATUS);
+
+ /*Set the cwt timer.Refer the setting of ATR on EMV4.3 book*/
+ __raw_writel(ATR_MAX_CWT, sim->ioaddr + CHAR_WAIT);
+
+ /*Set the baud rate to be 1/372. Refer the setting of ATR on EMV4.3 book
+ *Enable the CWT timer during receiving ATR process.
+ */
+ reg_data = __raw_readl(sim->ioaddr + CNTL);
+ reg_data &= ~SIM_CNTL_BAUD_SEL_MASK;
+ reg_data |= SIM_CNTL_BAUD_SEL(0) | SIM_CNTL_CWTEN;
+
+ /*Enable ICM mode*/
+ reg_data |= SIM_CNTL_ICM;
+
+ /*Enable Sample12*/
+ reg_data |= SIM_CNTL_SAMPLE12;
+ __raw_writel(reg_data, sim->ioaddr + CNTL);
+
+ /*Disable NACK*/
+ sim_set_nack(sim, 0);
+
+ /*Set 12 ETUS*/
+ __raw_writel(0, sim->ioaddr + GUARD_CNTL);
+
+ sim->errval = 0;
+ sim->rcv_count = 0;
+ sim->checking_ts_timing = 1;
+ sim->state = SIM_STATE_ATR_RECEIVING;
+
+ /*Enable the RIM and GPC interrupt, disalbe the CWT interrupt*/
+ reg_data = __raw_readl(sim->ioaddr + INT_MASK);
+ reg_data |= SIM_INT_MASK_CWTM;
+ reg_data &= ~(SIM_INT_MASK_RIM | SIM_INT_MASK_GPCM);
+ __raw_writel(reg_data, sim->ioaddr + INT_MASK);
+}
+
+static int32_t sim_check_rec_data(u32 *reg_data)
+{
+ s32 err = 0;
+
+ if (*reg_data & SIM_REC_CWT_ERROR)
+ err |= SIM_ERROR_CWT;
+
+ if (*reg_data & SIM_REC_FRAME_ERROR)
+ err |= SIM_ERROR_FRAME;
+
+ if (*reg_data & SIM_REC_PARITY_ERROR)
+ err |= SIM_ERROR_PARITY;
+
+ return err;
+}
+
+static void sim_xmt_fill_fifo(struct sim_t *sim)
+{
+ u32 reg_data;
+ u32 bytesleft, i;
+
+ reg_data = __raw_readl(sim->ioaddr + XMT_FIFO_STAT);
+ bytesleft = SIM_TX_FIFO_DEPTH - ((reg_data >> 8) & 0x0F);
+
+ if (bytesleft > sim->xmt_remaining)
+ bytesleft = sim->xmt_remaining;
+
+ for (i = 0; i < bytesleft; i++) {
+ __raw_writel(sim->xmt_buffer[sim->xmt_pos],
+ sim->ioaddr + PORT1_XMT_BUF);
+ sim->xmt_pos++;
+ };
+ sim->xmt_remaining -= bytesleft;
+};
+
+static void sim_rcv_read_fifo(struct sim_t *sim)
+{
+ u16 i, count;
+ u32 reg_data;
+
+ count = __raw_readl(sim->ioaddr + RCV_FIFO_CNT);
+
+ spin_lock(&sim->lock);
+ for (i = 0; i < count; i++) {
+ reg_data = __raw_readl(sim->ioaddr + PORT1_RCV_BUF);
+ sim->errval |= sim_check_rec_data(&reg_data);
+
+ /* T1 mode and t0 mode no parity error, T1 mode SIM module will not produce NACK be
+ * NACK is disabled. T0 mode to ensure there is no parity error for the current byte
+ */
+ if (!(sim->nack_enable && (reg_data & SIM_REC_PARITY_ERROR))) {
+ sim->rcv_buffer[sim->rcv_head + sim->rcv_count] = (u8)reg_data;
+ sim->rcv_count++;
+ }
+ if (sim->rcv_head + sim->rcv_count >= SIM_RCV_BUFFER_SIZE) {
+ pr_err("The software fifo is full,head %d, cnt%d\n", sim->rcv_head, sim->rcv_count);
+ break;
+ }
+ }
+ spin_unlock(&sim->lock);
+}
+
+static void sim_tx_irq_enable(struct sim_t *sim)
+{
+ u32 reg_val;
+ /*Clear the status and enable the related interrupt*/
+ reg_val = __raw_readl(sim->ioaddr + XMT_STATUS);
+ __raw_writel(reg_val, sim->ioaddr + XMT_STATUS);
+ reg_val = __raw_readl(sim->ioaddr + RCV_STATUS);
+ __raw_writel(reg_val, sim->ioaddr + RCV_STATUS);
+
+ reg_val = __raw_readl(sim->ioaddr + INT_MASK);
+ /*
+ *Disable CWT , BWT interrupt when transmitting, it would
+ *be enabled when rx is enabled just after tx completes
+ *The timer will be enabled.
+ */
+ reg_val |= SIM_INT_MASK_CWTM | SIM_INT_MASK_BWTM;
+ reg_val |= SIM_INT_MASK_RIM | SIM_INT_MASK_RTM;
+
+ if (sim->xmt_remaining != 0)
+ reg_val &= ~SIM_INT_MASK_TDTFM;
+ else{
+ reg_val &= ~SIM_INT_MASK_TCIM;
+ /*Enable transmit early complete interrupt.*/
+ reg_val &= ~SIM_INT_MASK_ETCIM;
+ }
+
+ /*NACK interrupt is enabled only when T0 mode*/
+ if (sim->protocol_type == SIM_PROTOCOL_T0 || sim->nack_enable != 0)
+ reg_val &= ~SIM_INT_MASK_XTM;
+ else
+ reg_val |= SIM_INT_MASK_XTM;
+ __raw_writel(reg_val, sim->ioaddr + INT_MASK);
+}
+
+static void sim_tx_irq_disable(struct sim_t *sim)
+{
+ u32 reg_val;
+ /*Disable the NACK interruptand TX related interrupt*/
+ reg_val = __raw_readl(sim->ioaddr + INT_MASK);
+ reg_val |= (SIM_INT_MASK_TDTFM | SIM_INT_MASK_TCIM | SIM_INT_MASK_XTM | SIM_INT_MASK_ETCIM);
+ __raw_writel(reg_val, sim->ioaddr + INT_MASK);
+}
+
+static void sim_rx_irq_enable(struct sim_t *sim)
+{
+ u32 reg_data;
+ /*
+ * Ensure the CWT timer is enabled.
+ */
+ sim_set_cwt(sim, 1);
+ reg_data = __raw_readl(sim->ioaddr + INT_MASK);
+ reg_data |= (SIM_INT_MASK_TCIM | SIM_INT_MASK_TDTFM | SIM_INT_MASK_XTM);
+ reg_data &= ~(SIM_INT_MASK_RIM | SIM_INT_MASK_CWTM | SIM_INT_MASK_BWTM);
+
+ if (sim->protocol_type == SIM_PROTOCOL_T0 || sim->nack_enable != 0)
+ reg_data &= ~SIM_INT_MASK_RTM;
+ else
+ reg_data |= SIM_INT_MASK_RTM;
+
+ __raw_writel(reg_data, sim->ioaddr + INT_MASK);
+}
+
+static void sim_rx_irq_disable(struct sim_t *sim)
+{
+ u32 reg_val;
+ reg_val = __raw_readl(sim->ioaddr + INT_MASK);
+ reg_val |= (SIM_INT_MASK_RIM | SIM_INT_MASK_CWTM | SIM_INT_MASK_BWTM | SIM_INT_MASK_RTM);
+ __raw_writel(reg_val, sim->ioaddr + INT_MASK);
+}
+
+static irqreturn_t sim_irq_handler(int irq, void *dev_id)
+{
+ u32 reg_data, tx_status, rx_status;
+
+ struct sim_t *sim = (struct sim_t *) dev_id;
+
+ tx_status = __raw_readl(sim->ioaddr + XMT_STATUS);
+ rx_status = __raw_readl(sim->ioaddr + RCV_STATUS);
+ __raw_writel(tx_status, sim->ioaddr + XMT_STATUS);
+ __raw_writel(rx_status, sim->ioaddr + RCV_STATUS);
+
+ if (sim->state == SIM_STATE_ATR_RECEIVING &&
+ sim->checking_ts_timing == 1) {
+
+ if ((tx_status & SIM_XMT_STATUS_GPCNT) &&
+ !(rx_status & SIM_RCV_STATUS_RDRF)) {
+ /*Disable the GPCNT timer and CWT timer right now*/
+ reg_data = __raw_readl(sim->ioaddr + CNTL);
+ reg_data &= ~(SIM_CNTL_GPCNT_CLK_SEL_MASK |
+ SIM_CNTL_CWTEN);
+ __raw_writel(reg_data, sim->ioaddr + CNTL);
+
+ reg_data = __raw_readl(sim->ioaddr + INT_MASK);
+ reg_data |= (SIM_INT_MASK_GPCM |
+ SIM_INT_MASK_CWTM | SIM_INT_MASK_RIM);
+ __raw_writel(reg_data, sim->ioaddr + INT_MASK);
+ sim->errval = SIM_ERROR_ATR_DELAY;
+ complete(&sim->xfer_done);
+ sim->checking_ts_timing = 0;
+ } else if (rx_status & SIM_RCV_STATUS_RDRF) {
+ /*
+ * Reset/stop the GPCNT timer first.
+ */
+ sim_reset_timer(sim);
+
+ /*Enable GPC, CWT interrupt and
+ *disable the rx full interrupt
+ */
+ reg_data = __raw_readl(sim->ioaddr + INT_MASK);
+ reg_data &= ~(SIM_INT_MASK_GPCM | SIM_INT_MASK_CWTM);
+ reg_data |= SIM_INT_MASK_RIM;
+ __raw_writel(reg_data, sim->ioaddr + INT_MASK);
+ sim_rcv_read_fifo(sim);
+
+ /*Clear the GPCNT expiring status*/
+ __raw_writel(SIM_XMT_STATUS_GPCNT,
+ sim->ioaddr + XMT_STATUS);
+
+ /*ATR each recieved byte will cost 12 ETU, so get the remaining etus*/
+ reg_data = ATR_MAX_DURATION - sim->rcv_count * 12;
+ __raw_writel(reg_data, sim->ioaddr + GPCNT);
+
+ sim_start_timer(sim, SIM_CNTL_GPCNT_ETU_CLK);
+
+ /*Receive fifo threshold set to max value*/
+ reg_data = SIM_RCV_THRESHOLD_RTH(0) | SIM_RCV_THRESHOLD_RDT(ATR_THRESHOLD_MAX);
+ __raw_writel(reg_data, sim->ioaddr + RCV_THRESHOLD);
+ sim->checking_ts_timing = 0;
+ } else {
+ pr_err("Unexpected irq when delay checking\n");
+ }
+ }
+
+ else if (sim->state == SIM_STATE_ATR_RECEIVING) {
+ if ((rx_status & SIM_RCV_STATUS_CWT) ||
+ ((tx_status & SIM_XMT_STATUS_GPCNT) &&
+ (sim->rcv_count != 0))) {
+
+ /*Disable the GPCNT timer and CWT timer right now*/
+ reg_data = __raw_readl(sim->ioaddr + CNTL);
+ reg_data &= ~(SIM_CNTL_GPCNT_CLK_SEL_MASK | SIM_CNTL_CWTEN);
+ __raw_writel(reg_data, sim->ioaddr + CNTL);
+
+ reg_data = __raw_readl(sim->ioaddr + INT_MASK);
+ reg_data |= (SIM_INT_MASK_GPCM | SIM_INT_MASK_CWTM);
+ __raw_writel(reg_data, sim->ioaddr + INT_MASK);
+
+ if (tx_status & SIM_XMT_STATUS_GPCNT)
+ sim->errval |= SIM_ERROR_ATR_TIMEROUT;
+
+ if (rx_status & SIM_RCV_STATUS_CWT)
+ sim->errval |= SIM_ERROR_CWT;
+
+ sim_rcv_read_fifo(sim);
+ sim->state = SIM_STATE_ATR_RECEIVED;
+
+ complete(&sim->xfer_done);
+ }
+ }
+
+ else if (sim->state == SIM_STATE_XMTING) {
+ /*The CWT BWT expire should not happen when in the transmitting state*/
+ if (tx_status & SIM_XMT_STATUS_ETC) {
+ /*Once the transmit frame is completed, need to enable CWT timer*/
+ sim_set_cwt(sim, 1);
+ }
+ if (tx_status & SIM_XMT_STATUS_XTE) {
+ /*Disable TX*/
+ sim_set_tx(sim, 0);
+ /*Disalbe the timers*/
+ sim_set_cwt(sim, 0);
+ sim_set_bwt(sim, 0);
+ /*Disable the NACK interruptand TX related interrupt*/
+ sim_tx_irq_disable(sim);
+
+ /*Update the state and status*/
+ sim->errval |= SIM_ERROR_NACK_THRESHOLD;
+ sim->state = SIM_STATE_XMT_ERROR;
+
+ complete(&sim->xfer_done);
+ } else if (tx_status & SIM_XMT_STATUS_TDTF && sim->xmt_remaining != 0) {
+ sim_xmt_fill_fifo(sim);
+ if (sim->xmt_remaining == 0) {
+ /*Disable TX threshold interrupt and enable tx complete interrupt*/
+ reg_data = __raw_readl(sim->ioaddr + INT_MASK);
+ reg_data |= SIM_INT_MASK_TDTFM;
+ /*Enable transmit complete and early transmit complete interrupt*/
+ reg_data &= ~(SIM_INT_MASK_TCIM | SIM_INT_MASK_ETCIM);
+ __raw_writel(reg_data, sim->ioaddr + INT_MASK);
+ }
+ } else if (tx_status & SIM_XMT_STATUS_TC && sim->xmt_remaining == 0) {
+ /*Disable the NACK interruptand TX related interrupt*/
+ sim_tx_irq_disable(sim);
+ sim_set_rx(sim, 1);
+ /*Update the state and status*/
+ sim->state = SIM_STATE_XMT_DONE;
+ complete(&sim->xfer_done);
+ }
+ }
+
+ /*
+ * It takes some time to change from SIM_STATE_XMT_DONE to SIM_STATE_RECEIVING
+ * RX would only be enabled after state becomes SIM_STATE_RECEIVING
+ */
+ else if (sim->state == SIM_STATE_RECEIVING) {
+ if (rx_status & SIM_RCV_STATUS_RTE) {
+ /*Disable RX*/
+ sim_set_rx(sim, 0);
+ /*Disable the BWT timer and CWT timer right now*/
+ sim_set_cwt(sim, 0);
+ sim_set_bwt(sim, 0);
+ /*Disable the interrupt right now*/
+ sim_rx_irq_disable(sim);
+ /*Should we read the fifo or just flush the fifo?*/
+ sim_rcv_read_fifo(sim);
+ sim->errval = SIM_ERROR_NACK_THRESHOLD;
+ sim->state = SIM_STATE_RECEIVE_ERROR;
+ complete(&sim->xfer_done);
+ }
+
+ if (rx_status & SIM_RCV_STATUS_RDRF) {
+ sim_rcv_read_fifo(sim);
+ if (sim->is_fixed_len_rec &&
+ sim->rcv_count >= sim->expected_rcv_cnt) {
+
+ /*Disable the BWT timer and CWT timer right now*/
+ sim_rx_irq_disable(sim);
+ /*Add the state judgement to ensure the maybe complete has been impletment in the above "if" case*/
+ if (sim->state == SIM_STATE_RECEIVING) {
+ sim->state = SIM_STATE_RECEIVE_DONE;
+ complete(&sim->xfer_done);
+ }
+ }
+ }
+
+ if ((rx_status & SIM_RCV_STATUS_CWT) ||
+ (rx_status & SIM_RCV_STATUS_BWT) ||
+ (rx_status & SIM_RCV_STATUS_BGT)) {
+
+ /*Disable the BWT timer and CWT timer right now*/
+ sim_set_cwt(sim, 0);
+ sim_set_bwt(sim, 0);
+ sim_rx_irq_disable(sim);
+
+ if (rx_status & SIM_RCV_STATUS_BWT) {
+ sim->errval |= SIM_ERROR_BWT;
+ }
+ if (rx_status & SIM_RCV_STATUS_CWT)
+ sim->errval |= SIM_ERROR_CWT;
+ if (rx_status & SIM_RCV_STATUS_BGT)
+ sim->errval |= SIM_ERROR_BGT;
+
+ sim_rcv_read_fifo(sim);
+ /*Add the state judgement to ensure the maybe complete has been impletment in the above "if" case*/
+ if (sim->state == SIM_STATE_RECEIVING) {
+ sim->state = SIM_STATE_RECEIVE_DONE;
+ complete(&sim->xfer_done);
+ }
+ }
+ }
+
+ else if ((sim->state == SIM_STATE_RESET_SEQUENCY) &&
+ (tx_status & SIM_XMT_STATUS_GPCNT))
+ complete(&sim->xfer_done);
+ else if (rx_status & SIM_RCV_STATUS_RDRF) {
+ pr_err("unexpected status %d\n", sim->state);
+ sim_rcv_read_fifo(sim);
+ }
+
+ return IRQ_HANDLED;
+};
+
+static void sim_start(struct sim_t *sim)
+{
+ u32 reg_data, clk_rate, clk_div = 0;
+ pr_debug("%s entering.\n", __func__);
+
+ if (sim->port_index == 1)
+ __raw_writel(SIM_SETUP_SPS_PORT1, sim->ioaddr + SETUP);
+ else
+ __raw_writel(SIM_SETUP_SPS_PORT0, sim->ioaddr + SETUP);
+
+ /*1 ~ 5 MHz */
+ clk_rate = clk_get_rate(sim->clk);
+ clk_div = (clk_rate + sim->clk_rate - 1) / sim->clk_rate;
+ __raw_writel(clk_div, sim->ioaddr + CLK_PRESCALER);
+
+ /*Set the port pin to be open drained*/
+ reg_data = __raw_readl(sim->ioaddr + OD_CONFIG);
+ if (sim->port_index == 1)
+ reg_data |= SIM_OD_CONFIG_OD_P1;
+ else
+ reg_data |= SIM_OD_CONFIG_OD_P0;
+
+ __raw_writel(reg_data, sim->ioaddr + OD_CONFIG);
+
+ reg_data = __raw_readl(sim->ioaddr + sim->port_ctrl_reg);
+
+ /*One pin mode*/
+ reg_data |= SIM_PORT_CNTL_3VOLT | SIM_PORT_CNTL_STEN;
+ __raw_writel(reg_data, sim->ioaddr + sim->port_ctrl_reg);
+
+ /* presense detect */
+ pr_debug("%s p0_det is 0x%x \n", __func__,
+ __raw_readl(sim->ioaddr + sim->port_detect_reg));
+ if (__raw_readl(sim->ioaddr + sim->port_detect_reg)
+ & SIM_PORT_DETECT_SPDP) {
+ reg_data = __raw_readl(sim->ioaddr + sim->port_detect_reg);
+ reg_data &= ~SIM_PORT_DETECT_SPDS;
+ __raw_writel(reg_data, sim->ioaddr + sim->port_detect_reg);
+ sim->present = SIM_PRESENT_REMOVED;
+ sim->state = SIM_STATE_REMOVED;
+ } else {
+ reg_data = __raw_readl(sim->ioaddr + sim->port_detect_reg);
+ reg_data |= SIM_PORT_DETECT_SPDS;
+ __raw_writel(reg_data, sim->ioaddr + sim->port_detect_reg);
+ sim->present = SIM_PRESENT_DETECTED;
+ sim->state = SIM_STATE_DETECTED;
+ };
+
+ /*enable card interrupt. clear interrupt status*/
+ reg_data = __raw_readl(sim->ioaddr + sim->port_detect_reg);
+ reg_data |= SIM_PORT_DETECT_SDI;
+ reg_data |= SIM_PORT_DETECT_SDIM;
+ __raw_writel(reg_data, sim->ioaddr + sim->port_detect_reg);
+};
+
+static void sim_cold_reset_sequency(struct sim_t *sim)
+{
+ u32 reg_data;
+
+ sim->state = SIM_STATE_RESET_SEQUENCY;
+
+ /*set VCC*/
+ reg_data = __raw_readl(sim->ioaddr + sim->port_ctrl_reg);
+ if (sim->sven_low_active)
+ reg_data &= ~SIM_PORT_CNTL_SVEN;
+ else
+ reg_data |= SIM_PORT_CNTL_SVEN;
+ __raw_writel(reg_data, sim->ioaddr + sim->port_ctrl_reg);
+
+ msleep(9);
+
+ /*enable CLK*/
+ reg_data = __raw_readl(sim->ioaddr + sim->port_ctrl_reg);
+ reg_data |= SIM_PORT_CNTL_SCEN;
+ __raw_writel(reg_data, sim->ioaddr + sim->port_ctrl_reg);
+
+ /*RST low time*/
+ sim_reset_low_timing(sim, EMV_RESET_LOW_CYCLES);
+
+ /*RST high*/
+ reg_data = __raw_readl(sim->ioaddr + sim->port_ctrl_reg);
+ reg_data |= SIM_PORT_CNTL_SRST;
+ __raw_writel(reg_data, sim->ioaddr + sim->port_ctrl_reg);
+
+ /*wait for ATR*/
+ sim_set_gpc_timer(sim, ATR_MAX_DELAY_CLK);
+};
+
+static void sim_deactivate(struct sim_t *sim)
+{
+ u32 reg_data;
+
+ pr_debug("%s entering.\n", __func__);
+ /* Auto powdown to implement the deactivate sequence */
+ if (sim->present != SIM_PRESENT_REMOVED) {
+ if (sim->sven_low_active) {
+ /*Set the RESET to be low*/
+ reg_data = __raw_readl(sim->ioaddr + sim->port_ctrl_reg);
+ reg_data &= ~SIM_PORT_CNTL_SRST;
+ writel(reg_data, sim->ioaddr + sim->port_ctrl_reg);
+ usleep_range(2, 5);
+
+ /*Set the clock to be low*/
+ reg_data &= ~SIM_PORT_CNTL_SCEN;
+ writel(reg_data, sim->ioaddr + sim->port_ctrl_reg);
+ usleep_range(2, 5);
+
+ /*Set the sven to be high*/
+ reg_data |= SIM_PORT_CNTL_SVEN;
+ writel(reg_data, sim->ioaddr + sim->port_ctrl_reg);
+
+ } else {
+ reg_data = __raw_readl(sim->ioaddr + sim->port_ctrl_reg);
+ reg_data |= SIM_PORT_CNTL_SAPD;
+ __raw_writel(reg_data,
+ sim->ioaddr + sim->port_ctrl_reg);
+ reg_data |= SIM_PORT_CNTL_SFPD;
+ __raw_writel(reg_data,
+ sim->ioaddr + sim->port_ctrl_reg);
+ }
+ } else
+ pr_err(">>>No card%s\n", __func__);
+};
+
+static void sim_cold_reset(struct sim_t *sim)
+{
+ if (sim->present != SIM_PRESENT_REMOVED) {
+ sim->state = SIM_STATE_DETECTED;
+ sim->present = SIM_PRESENT_DETECTED;
+ sim_cold_reset_sequency(sim);
+ sim_receive_atr_set(sim);
+ } else {
+ pr_err("No card%s\n", __func__);
+ }
+};
+
+static void sim_warm_reset_sequency(struct sim_t *sim)
+{
+ u32 reg_data;
+
+ sim->state = SIM_STATE_RESET_SEQUENCY;
+ reg_data = __raw_readl(sim->ioaddr + sim->port_ctrl_reg);
+ reg_data |= (SIM_PORT_CNTL_SRST | SIM_PORT_CNTL_SCEN);
+ if (sim->sven_low_active)
+ reg_data &= ~SIM_PORT_CNTL_SVEN;
+ else
+ reg_data |= SIM_PORT_CNTL_SVEN;
+ __raw_writel(reg_data, sim->ioaddr + sim->port_ctrl_reg);
+
+ usleep_range(20, 25);
+
+ reg_data = __raw_readl(sim->ioaddr + sim->port_ctrl_reg);
+ reg_data &= ~SIM_PORT_CNTL_SRST;
+ __raw_writel(reg_data, sim->ioaddr + sim->port_ctrl_reg);
+
+ sim_reset_low_timing(sim, EMV_RESET_LOW_CYCLES);
+
+ reg_data = __raw_readl(sim->ioaddr + sim->port_ctrl_reg);
+ reg_data |= SIM_PORT_CNTL_SRST;
+ __raw_writel(reg_data, sim->ioaddr + sim->port_ctrl_reg);
+ sim_set_gpc_timer(sim, ATR_MAX_DELAY_CLK);
+}
+
+static void sim_warm_reset(struct sim_t *sim)
+{
+ if (sim->present != SIM_PRESENT_REMOVED) {
+ sim_data_reset(sim);
+ sim_warm_reset_sequency(sim);
+ sim_receive_atr_set(sim);
+ } else {
+ pr_err("No card%s\n", __func__);
+ }
+};
+
+
+static int sim_card_lock(struct sim_t *sim)
+{
+ int errval;
+
+ /* place holder for true physcial locking */
+ if (sim->present != SIM_PRESENT_REMOVED)
+ errval = SIM_OK;
+ else
+ errval = -SIM_E_NOCARD;
+ return errval;
+};
+
+static int sim_card_eject(struct sim_t *sim)
+{
+ int errval;
+
+ pr_debug("%s entering.\n", __func__);
+ /* place holder for true physcial locking */
+ if (sim->present != SIM_PRESENT_REMOVED)
+ errval = SIM_OK;
+ else
+ errval = -SIM_E_NOCARD;
+ return errval;
+};
+
+static int sim_check_baud_rate(sim_baud_t *baud_rate)
+{
+ /*
+ * The valid value is decribed in the 8.3.3.1 in EMV 4.3
+ */
+ if (baud_rate->fi == 1 && (baud_rate->di == 1 ||
+ baud_rate->di == 2 || baud_rate->di == 3))
+ return 0;
+
+ return -EINVAL;
+}
+
+static int sim_set_baud_rate(struct sim_t *sim)
+{
+ u32 reg_data;
+ reg_data = __raw_readl(sim->ioaddr + CNTL);
+ reg_data &= ~(SIM_CNTL_BAUD_SEL_MASK);
+
+ switch (sim->baud_rate.di) {
+ case 1:
+ reg_data |= SIM_CNTL_BAUD_SEL(0);
+ break;
+ case 2:
+ reg_data |= SIM_CNTL_BAUD_SEL(1);
+ break;
+ case 3:
+ reg_data |= SIM_CNTL_BAUD_SEL(2);
+ break;
+ default:
+ pr_err("Invalid baud Di, Using default 372 / 1\n");
+ reg_data |= SIM_CNTL_BAUD_SEL(0);
+ break;
+ }
+
+ __raw_writel(reg_data, sim->ioaddr + CNTL);
+
+ return 0;
+}
+
+static int sim_check_timing_data(sim_timing_t *timing_data)
+{
+ if (timing_data->wwt > 0xFFFF ||
+ timing_data->cwt > 0xFFFF ||
+ timing_data->bgt > 0xFFFF ||
+ timing_data->cgt > 0xFF) {
+ /*Check whether the counter is out of the scope of SIM IP*/
+ pr_err("The timing value is out of scope of IP\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static void sim_set_timer_counter(struct sim_t *sim)
+{
+ if (sim->timing_data.wwt != 0 &&
+ sim->protocol_type == SIM_PROTOCOL_T0) {
+ sim->timing_data.cwt = sim->timing_data.wwt;
+ sim->timing_data.bwt = sim->timing_data.wwt;
+ }
+
+
+ if (sim->timing_data.bgt != 0) {
+ __raw_writel(sim->timing_data.bgt, sim->ioaddr + BGT);
+ }
+
+ if (sim->timing_data.cwt != 0)
+ __raw_writel(sim->timing_data.cwt, sim->ioaddr + CHAR_WAIT);
+
+ if (sim->timing_data.bwt != 0) {
+
+ __raw_writel(sim->timing_data.bwt & 0x0000FFFF, sim->ioaddr + BWT);
+ __raw_writel((sim->timing_data.bwt >> 16) & 0x0000FFFF,
+ sim->ioaddr + BWT_H);
+ }
+
+ if (sim->timing_data.cgt == 0xFF && sim->protocol_type == SIM_PROTOCOL_T0)
+ /* From EMV4.3 , CGT =0xFF in T0 mode means 12 ETU.
+ * Set register to be 12 ETU for transmitting and receiving.
+ */
+ __raw_writel(0 , sim->ioaddr + GUARD_CNTL);
+ else if (sim->timing_data.cgt == 0xFF && sim->protocol_type == SIM_PROTOCOL_T1)
+ /* From EMV4.3 , CGT =0xFF in T1 mode means 11 ETU.
+ * Set register to be 12 ETU for transmitting and receiving.
+ */
+ __raw_writel(0x1FF , sim->ioaddr + GUARD_CNTL);
+
+ /*For the T1 mode, use 11ETU to receive.*/
+ else if (sim->protocol_type == SIM_PROTOCOL_T1)
+ __raw_writel((sim->timing_data.cgt | SIM_GUARD_CNTL_RCVR11), sim->ioaddr + GUARD_CNTL);
+
+ else
+ /*sim->protocol_type == SIM_PROTOCOL_T0*/
+ __raw_writel(sim->timing_data.cgt, sim->ioaddr + GUARD_CNTL);
+}
+
+static void sim_xmt_start(struct sim_t *sim)
+{
+ u32 reg_val;
+
+ /*Set TX threshold if there are remaing data*/
+ if (sim->xmt_remaining != 0) {
+ reg_val = __raw_readl(sim->ioaddr + XMT_THRESHOLD);
+ reg_val &= ~SIM_XMT_THRESHOLD_TDT_MASK;
+ reg_val |= SIM_XMT_THRESHOLD_TDT(TX_FIFO_THRESHOLD);
+ __raw_writel(reg_val, sim->ioaddr + XMT_THRESHOLD);
+ }
+ sim_tx_irq_enable(sim);
+
+ /*Enable BWT and disalbe CWT timers when tx*/
+ sim_set_bwt(sim, 1);
+ sim_set_cwt(sim, 0);
+
+ /*Disalbe RX*/
+ sim_set_rx(sim, 0);
+
+ /*Enable TX*/
+ sim_set_tx(sim, 1);
+}
+
+static void sim_flush_fifo(struct sim_t *sim, u8 flush_tx, u8 flush_rx)
+{
+ u32 reg_val;
+
+ reg_val = __raw_readl(sim->ioaddr + RESET_CNTL);
+
+ if (flush_tx)
+ reg_val |= SIM_RESET_CNTL_FLUSH_XMT;
+ if (flush_rx)
+ reg_val |= SIM_RESET_CNTL_FLUSH_RCV;
+ __raw_writel(reg_val, sim->ioaddr + RESET_CNTL);
+
+ usleep_range(2, 3);
+
+ if (flush_tx)
+ reg_val &= ~(SIM_RESET_CNTL_FLUSH_XMT);
+ if (flush_rx)
+ reg_val &= ~(SIM_RESET_CNTL_FLUSH_RCV);
+ __raw_writel(reg_val, sim->ioaddr + RESET_CNTL);
+}
+
+static void sim_change_rcv_threshold(struct sim_t *sim)
+{
+ u32 rx_threshold = 0;
+ u32 reg_val = 0;
+
+ if (sim->is_fixed_len_rec) {
+ rx_threshold = sim->expected_rcv_cnt - sim->rcv_count;
+ reg_val = __raw_readl(sim->ioaddr + RCV_THRESHOLD);
+ reg_val &= ~(SIM_RCV_THRESHOLD_RDT_MASK);
+ reg_val |= SIM_RCV_THRESHOLD_RDT(rx_threshold);
+ __raw_writel(reg_val, sim->ioaddr + RCV_THRESHOLD);
+ }
+}
+
+static void sim_start_rcv(struct sim_t *sim)
+{
+ sim_set_baud_rate(sim);
+ if (sim->protocol_type == SIM_PROTOCOL_T0)
+ sim_set_nack(sim, 1);
+ else if (sim->protocol_type == SIM_PROTOCOL_T1)
+ sim_set_nack(sim, 0);
+
+ /*Set RX threshold*/
+ if (sim->protocol_type == SIM_PROTOCOL_T0)
+ __raw_writel(SIM_RCV_THRESHOLD_RTH(sim->nack_threshold) |
+ SIM_RCV_THRESHOLD_RDT(RX_FIFO_THRESHOLD), sim->ioaddr + RCV_THRESHOLD);
+ else
+ __raw_writel(SIM_RCV_THRESHOLD_RDT(RX_FIFO_THRESHOLD), sim->ioaddr + RCV_THRESHOLD);
+
+ /*Clear status and enable interrupt*/
+ sim_rx_irq_enable(sim);
+
+ /*Disalbe TX and Enable Rx*/
+ sim_set_rx(sim, 1);
+ sim_set_tx(sim, 0);
+}
+
+static void sim_polling_delay(struct sim_t *sim, u32 delay)
+{
+ u32 reg_data;
+
+ /*Reset the timer*/
+ reg_data = __raw_readl(sim->ioaddr + CNTL);
+ reg_data &= ~SIM_CNTL_GPCNT_CLK_SEL_MASK;
+ reg_data |= SIM_CNTL_GPCNT_CLK_SEL(0);
+ __raw_writel(reg_data, sim->ioaddr + CNTL);
+
+ /*Clear the interrupt status*/
+ __raw_writel(SIM_XMT_STATUS_GPCNT, sim->ioaddr + XMT_STATUS);
+
+ /*Disable timer interrupt*/
+ reg_data = __raw_readl(sim->ioaddr + INT_MASK);
+ reg_data |= SIM_INT_MASK_GPCM;
+ __raw_writel(reg_data, sim->ioaddr + INT_MASK);
+
+ __raw_writel(delay, sim->ioaddr + GPCNT);
+
+ /*Set the ETU as clock source and start timer*/
+ reg_data = __raw_readl(sim->ioaddr + CNTL);
+ reg_data &= ~SIM_CNTL_GPCNT_CLK_SEL_MASK;
+ reg_data |= SIM_CNTL_GPCNT_CLK_SEL(3);
+ __raw_writel(reg_data, sim->ioaddr + CNTL);
+
+ /*Loop for timeout*/
+ while (!(__raw_readl(sim->ioaddr + XMT_STATUS) & SIM_XMT_STATUS_GPCNT))
+ usleep_range(10, 20);
+ __raw_writel(SIM_XMT_STATUS_GPCNT, sim->ioaddr + XMT_STATUS);
+}
+
+void sim_clear_rx_buf(struct sim_t *sim)
+{
+ unsigned int i;
+ for (i = 0; i < SIM_RCV_BUFFER_SIZE; i++)
+ sim->rcv_buffer[i] = 0;
+ sim->rcv_count = 0;
+ sim->rcv_head = 0;
+}
+
+static long sim_ioctl(struct file *file,
+ unsigned int cmd, unsigned long arg)
+{
+ int ret, errval = SIM_OK;
+ unsigned long timeout;
+ u32 reg_data;
+ u32 delay;
+ u32 copy_cnt, val;
+ unsigned long flags;
+ unsigned char __user *atr_buffer;
+ unsigned char __user *xmt_buffer;
+ unsigned char __user *rcv_buffer;
+
+ struct sim_t *sim = (struct sim_t *) file->private_data;
+
+ pr_debug("%s entering.\n", __func__);
+ switch (cmd) {
+
+ case SIM_IOCTL_GET_ATR:
+ if (sim->present != SIM_PRESENT_DETECTED) {
+ pr_err("NO card ...\n");
+ errval = -SIM_E_NOCARD;
+ break;
+ };
+ sim->timeout = ATR_TIMEOUT * HZ;
+ val = 0;
+ ret = copy_to_user(&(((sim_atr_t *)arg)->size), &val,
+ sizeof((((sim_atr_t *)arg)->size)));
+
+ timeout = wait_for_completion_interruptible_timeout(&sim->xfer_done,
+ sim->timeout);
+ /*Disalbe the GPCNT timer and CWT timer right now*/
+ reg_data = __raw_readl(sim->ioaddr + CNTL);
+ reg_data &= ~(SIM_CNTL_GPCNT_CLK_SEL_MASK | SIM_CNTL_CWTEN);
+ __raw_writel(reg_data, sim->ioaddr + CNTL);
+
+ reg_data = __raw_readl(sim->ioaddr + INT_MASK);
+ reg_data |= (SIM_INT_MASK_GPCM | SIM_INT_MASK_CWTM);
+ __raw_writel(reg_data, sim->ioaddr + INT_MASK);
+
+ if (timeout == 0) {
+ pr_err("ATR timeout\n");
+ errval = -SIM_E_TIMEOUT;
+ break;
+ }
+
+ ret = copy_to_user(&(((sim_atr_t *)arg)->size), &sim->rcv_count,
+ sizeof(sim->rcv_count));
+ if (ret) {
+ pr_err("ATR ACCESS rcv_count Error, %d\n", ret);
+ errval = -SIM_E_ACCESS;
+ break;
+ }
+
+ __get_user(atr_buffer, &((sim_atr_t __user *)arg)->atr_buffer);
+ ret = copy_to_user(atr_buffer, sim->rcv_buffer, sim->rcv_count);
+ if (ret) {
+ pr_err("ATR ACCESS buffer Error %d %d\n", sim->rcv_count, ret);
+ errval = -SIM_E_ACCESS;
+ break;
+ }
+
+ ret = copy_to_user(&(((sim_atr_t *)arg)->errval), &sim->errval,
+ sizeof(sim->errval));
+ if (ret) {
+ pr_err("ATR ACCESS Error\n");
+ errval = -SIM_E_ACCESS;
+ break;
+ }
+ sim->rcv_count = 0;
+ sim->rcv_head = 0;
+ sim->errval = 0;
+
+ break;
+
+ case SIM_IOCTL_DEACTIVATE:
+
+ sim_deactivate(sim);
+ break;
+
+ case SIM_IOCTL_COLD_RESET:
+ sim->present = SIM_PRESENT_REMOVED;
+ sim->state = SIM_STATE_REMOVED;
+ sim_reset_module(sim);
+ sim_data_reset(sim);
+ sim_start(sim);
+ sim_cold_reset(sim);
+
+ break;
+
+ case SIM_IOCTL_WARM_RESET:
+ sim_warm_reset(sim);
+ break;
+
+ case SIM_IOCTL_XMT:
+ ret = copy_from_user(&sim->xmt_remaining, &(((sim_xmt_t *)arg)->xmt_length),
+ sizeof(uint32_t));
+ if (ret || sim->xmt_remaining > SIM_XMT_BUFFER_SIZE) {
+ pr_err("copy error or to big buffer\n");
+ errval = -EINVAL;
+ break;
+ }
+
+ __get_user(xmt_buffer, &((sim_xmt_t *)arg)->xmt_buffer);
+ ret = copy_from_user(sim->xmt_buffer, xmt_buffer, sim->xmt_remaining);
+
+ if (ret) {
+ pr_err("Copy Error\n");
+ errval = ret;
+ break;
+ }
+
+ sim_clear_rx_buf(sim);
+ sim_set_cwt(sim, 0);
+ sim_set_bwt(sim, 0);
+ /*Flush the tx rx fifo*/
+ sim_flush_fifo(sim, 1, 1);
+ sim->xmt_pos = 0;
+ sim->errval = 0;
+
+ sim_xmt_fill_fifo(sim);
+ sim_set_baud_rate(sim);
+ if (sim->protocol_type == SIM_PROTOCOL_T0)
+ sim_set_nack(sim, 1);
+ else if (sim->protocol_type == SIM_PROTOCOL_T1)
+ sim_set_nack(sim, 0);
+ else {
+ pr_err("Invalid protocol not T0 or T1\n");
+ errval = -EINVAL;
+ break;
+ }
+
+ sim_set_timer_counter(sim);
+ sim_xmt_start(sim);
+ sim->state = SIM_STATE_XMTING;
+
+ sim->timeout = TX_TIMEOUT * HZ;
+ timeout = wait_for_completion_interruptible_timeout(&sim->xfer_done,
+ sim->timeout);
+ if (timeout == 0) {
+ /*Disable the NACK interruptand TX related interrupt*/
+ sim_tx_irq_disable(sim);
+ pr_err("tx timeout\n");
+ }
+
+ if (timeout == 0 || sim->state == SIM_STATE_XMT_ERROR) {
+ pr_err("TX error\n");
+ /*Disable timers*/
+ sim_set_cwt(sim, 0);
+ sim_set_bwt(sim, 0);
+ /*Disable TX*/
+ sim_set_tx(sim, 0);
+ /*Flush the tx fifos*/
+ sim_flush_fifo(sim, 1, 0);
+ if (timeout == 0)
+ errval = -SIM_E_TIMEOUT;
+ else
+ errval = -SIM_E_NACK;
+
+ ret = copy_to_user(&(((sim_atr_t *)arg)->errval), &sim->errval,
+ sizeof(sim->errval));
+ sim->errval = 0;
+ break;
+ }
+
+ /*Copy the error status to user space*/
+ ret = copy_to_user(&(((sim_atr_t *)arg)->errval), &sim->errval,
+ sizeof(sim->errval));
+ sim->last_is_tx = true;
+ /*Start RX*/
+ sim->errval = 0;
+ sim->state = SIM_STATE_RECEIVING;
+ sim_start_rcv(sim);
+
+ break;
+
+ case SIM_IOCTL_RCV:
+ if (sim->present != SIM_PRESENT_DETECTED) {
+ errval = -SIM_E_NOCARD;
+ break;
+ }
+ sim->is_fixed_len_rec = 0;
+ val = 0;
+ ret = copy_from_user(&sim->expected_rcv_cnt, &(((sim_rcv_t *)arg)->rcv_length),
+ sizeof(sim->expected_rcv_cnt));
+
+ /*Set the length to be 0 at first*/
+ ret = copy_to_user(&(((sim_rcv_t *)arg)->rcv_length), &val,
+ sizeof(val));
+
+ /*Set error value to be 0 at first*/
+ ret = copy_to_user(&(((sim_rcv_t *)arg)->errval), &val,
+ sizeof(val));
+
+ if (sim->expected_rcv_cnt != 0)
+ sim->is_fixed_len_rec = 1;
+
+ if (sim->is_fixed_len_rec && sim->rcv_count >= sim->expected_rcv_cnt)
+ goto copy_data;
+
+ if (sim->state != SIM_STATE_RECEIVING) {
+ sim_set_timer_counter(sim);
+ /*Enable CWT BWT*/
+ sim_set_cwt(sim, 1);
+ sim_set_bwt(sim, 1);
+ sim->state = SIM_STATE_RECEIVING;
+ sim_start_rcv(sim);
+ }
+
+ spin_lock_irqsave(&sim->lock, flags);
+ if (sim->is_fixed_len_rec && sim->rcv_count < sim->expected_rcv_cnt)
+ sim_change_rcv_threshold(sim);
+ spin_unlock_irqrestore(&sim->lock, flags);
+ sim->timeout = RX_TIMEOUT * HZ;
+ timeout = wait_for_completion_interruptible_timeout(&sim->xfer_done,
+ sim->timeout);
+
+ if (timeout == 0) {
+ pr_err("Receiving timeout\n");
+ sim_set_cwt(sim, 0);
+ sim_set_bwt(sim, 0);
+ sim_rx_irq_disable(sim);
+ errval = -SIM_E_TIMEOUT;
+ break;
+ }
+
+copy_data:
+ if (sim->is_fixed_len_rec)
+ copy_cnt = sim->rcv_count >= sim->expected_rcv_cnt ? sim->expected_rcv_cnt : sim->rcv_count;
+ else
+ copy_cnt = sim->rcv_count;
+
+ ret = copy_to_user(&(((sim_rcv_t *)arg)->rcv_length), &copy_cnt,
+ sizeof(copy_cnt));
+ if (ret) {
+ pr_err("ATR ACCESS Error\n");
+ errval = -SIM_E_ACCESS;
+ break;
+ }
+
+ __get_user(rcv_buffer, &((sim_rcv_t *)arg)->rcv_buffer);
+ ret = copy_to_user(rcv_buffer, &sim->rcv_buffer[sim->rcv_head], copy_cnt);
+ if (ret) {
+ pr_err("ATR ACCESS Error\n");
+ errval = -SIM_E_ACCESS;
+ break;
+ }
+
+ ret = copy_to_user(&(((sim_rcv_t *)arg)->errval), &sim->errval,
+ sizeof(sim->errval));
+ if (ret) {
+ pr_err("ATR ACCESS Error\n");
+ errval = -SIM_E_ACCESS;
+ break;
+ }
+ /*Reset the receiving count and errval*/
+ spin_lock_irqsave(&sim->lock, flags);
+ sim->rcv_head += copy_cnt;
+ sim->rcv_count -= copy_cnt;
+ sim->errval = 0;
+ spin_unlock_irqrestore(&sim->lock, flags);
+
+ sim->last_is_tx = false;
+
+ break;
+
+ case SIM_IOCTL_SET_PROTOCOL:
+ ret = copy_from_user(&sim->protocol_type, (int *)arg,
+ sizeof(int));
+ if (ret)
+ errval = -SIM_E_ACCESS;
+ break;
+
+ case SIM_IOCTL_SET_TIMING:
+ ret = copy_from_user(&sim->timing_data, (sim_timing_t *)arg,
+ sizeof(sim_timing_t));
+ if (ret) {
+ pr_err("Copy Error\n");
+ errval = ret;
+ break;
+ }
+
+ ret = sim_check_timing_data(&sim->timing_data);
+
+ if (ret)
+ errval = ret;
+
+ break;
+
+ case SIM_IOCTL_SET_BAUD:
+ ret = copy_from_user(&sim->baud_rate, (sim_baud_t *)arg,
+ sizeof(sim_baud_t));
+
+ if (ret) {
+ pr_err("Copy Error\n");
+ errval = ret;
+ break;
+ }
+
+ sim_check_baud_rate(&sim->baud_rate);
+
+ break;
+ case SIM_IOCTL_WAIT:
+ ret = copy_from_user(&delay, (unsigned int *)arg,
+ sizeof(unsigned int));
+
+ if (ret) {
+ pr_err("\nWait Copy Error\n");
+ errval = ret;
+ break;
+ }
+
+ sim_polling_delay(sim, delay);
+ break;
+
+ case SIM_IOCTL_GET_PRESENSE:
+ if (put_user(sim->present, (int *)arg))
+ errval = -SIM_E_ACCESS;
+ break;
+
+ case SIM_IOCTL_CARD_LOCK:
+ errval = sim_card_lock(sim);
+ break;
+
+ case SIM_IOCTL_CARD_EJECT:
+ errval = sim_card_eject(sim);
+ break;
+
+ };
+
+ return errval;
+};
+
+static int sim_open(struct inode *inode, struct file *file)
+{
+ int errval = SIM_OK;
+ struct sim_t *sim = dev_get_drvdata(sim_dev.parent);
+
+ file->private_data = sim;
+ spin_lock_init(&sim->lock);
+
+ pr_debug("%s entering.\n", __func__);
+ if (!sim->ioaddr) {
+ errval = -ENOMEM;
+ return errval;
+ }
+
+ if (!sim->open_cnt)
+ clk_prepare_enable(sim->clk);
+
+ sim->open_cnt = 1;
+
+ errval = sim_reset_module(sim);
+ sim_data_reset(sim);
+
+ return errval;
+};
+
+static int sim_release(struct inode *inode, struct file *file)
+{
+ u32 reg_data;
+ struct sim_t *sim = (struct sim_t *) file->private_data;
+
+ /* disable presense detection */
+ reg_data = __raw_readl(sim->ioaddr + sim->port_detect_reg);
+ __raw_writel(reg_data | SIM_PORT_DETECT_SDIM,
+ sim->ioaddr + sim->port_detect_reg);
+
+ if (sim->present != SIM_PRESENT_REMOVED)
+ sim_deactivate(sim);
+
+
+ if (sim->open_cnt)
+ clk_disable_unprepare(sim->clk);
+
+ sim->open_cnt = 0;
+
+ return 0;
+};
+
+static const struct file_operations sim_fops = {
+ .owner = THIS_MODULE,
+ .open = sim_open,
+ .release = sim_release,
+ .unlocked_ioctl = sim_ioctl,
+};
+
+static struct miscdevice sim_dev = {
+ MISC_DYNAMIC_MINOR,
+ "mxc_sim",
+ &sim_fops
+};
+
+static struct platform_device_id imx_sim_devtype[] = {
+ {
+ .name = "imx7d-sim",
+ .driver_data = 0,
+ }, {
+ .name = "imx6ul-sim",
+ .driver_data = SIM_QUIRK_TKT259347,
+ }, {
+ /* sentinel */
+ }
+};
+
+enum imx_sim_type {
+ IMX7D_SIM = 0,
+ IMX6UL_SIM,
+};
+
+static const struct of_device_id sim_imx_dt_ids[] = {
+ { .compatible = "fsl,imx7d-sim",
+ .data = &imx_sim_devtype[IMX7D_SIM], },
+ { .compatible = "fsl,imx6ul-sim",
+ .data = &imx_sim_devtype[IMX6UL_SIM], },
+ { /* sentinel */ }
+};
+
+MODULE_DEVICE_TABLE(of, sim_imx_dt_ids);
+
+static int sim_probe(struct platform_device *pdev)
+{
+ int ret = 0;
+ const struct of_device_id *of_id;
+ struct sim_t *sim = NULL;
+ struct device_node *of_node = pdev->dev.of_node;
+
+ sim = devm_kzalloc(&pdev->dev, sizeof(struct sim_t),
+ GFP_KERNEL);
+ if (!sim) {
+ dev_err(&pdev->dev, "can't allocate enough memory\n");
+ return -ENOMEM;
+ }
+
+
+ of_id = of_match_device(sim_imx_dt_ids, &pdev->dev);
+ if (of_id)
+ pdev->id_entry = of_id->data;
+ else
+ return -EINVAL;
+
+ sim->clk_rate = FCLK_FREQ;
+ sim->open_cnt = 0;
+
+ sim->res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!sim->res) {
+ pr_err("Can't get the MEMORY\n");
+ return -ENOMEM;
+ }
+ sim->ioaddr = devm_ioremap_resource(&pdev->dev, sim->res);
+ dev_dbg(&pdev->dev, "mapped base address: 0x%08x\n", (u32)sim->ioaddr);
+ if (IS_ERR(sim->ioaddr)) {
+ dev_err(&pdev->dev,
+ "failed to get ioremap base\n");
+ ret = PTR_ERR(sim->ioaddr);
+ return ret;
+ }
+
+ /* request the sim clk and sim_serial_clk */
+ sim->clk = devm_clk_get(&pdev->dev, "sim");
+ if (IS_ERR(sim->clk)) {
+ ret = PTR_ERR(sim->clk);
+ pr_err("Get CLK ERROR !\n");
+ return ret;
+ }
+ pr_debug("sim clock:%lu\n", clk_get_rate(sim->clk));
+
+ sim->ipb_irq = platform_get_irq(pdev, 0);
+ if (sim->ipb_irq < 0) {
+ dev_err(&pdev->dev, "No ipb irq line provided\n");
+ return -ENOENT;
+ }
+ if (devm_request_irq(&pdev->dev, sim->ipb_irq, sim_irq_handler,
+ 0, "mxc_sim_ipb", sim)) {
+ dev_err(&pdev->dev, "can't claim irq %d\n", sim->ipb_irq);
+ return -ENOENT;
+ }
+
+ sim->sven_low_active = of_property_read_bool(of_node,
+ "sven_low_active");
+
+ ret = of_property_read_u32(of_node, "port", &sim->port_index);
+ if (ret)
+ sim->port_index = 0;
+ sim->port_ctrl_reg = (sim->port_index == 0) ?
+ PORT0_CNTL : PORT1_CNTL;
+ sim->port_detect_reg = (sim->port_index == 0) ?
+ PORT0_DETECT : PORT1_DETECT;
+ sim->quirks = pdev->id_entry->driver_data;
+
+ platform_set_drvdata(pdev, sim);
+
+ /*
+ *@todo: Need to figure a better way if possible.
+ */
+ sim_dev.parent = &(pdev->dev);
+
+ misc_register(&sim_dev);
+
+ return 0;
+}
+
+static int sim_remove(struct platform_device *pdev)
+{
+ struct sim_t *sim = platform_get_drvdata(pdev);
+
+ if (sim->open_cnt)
+ clk_disable_unprepare(sim->clk);
+
+ misc_deregister(&sim_dev);
+
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int sim_suspend(struct platform_device *pdev, pm_message_t state)
+{
+ struct sim_t *sim = platform_get_drvdata(pdev);
+
+ if (sim->open_cnt)
+ clk_disable_unprepare(sim->clk);
+
+ pinctrl_pm_select_sleep_state(&pdev->dev);
+
+ return 0;
+}
+
+static int sim_resume(struct platform_device *pdev)
+{
+ struct sim_t *sim = platform_get_drvdata(pdev);
+
+ if (sim->open_cnt)
+ clk_prepare_enable(sim->clk);
+
+ pinctrl_pm_select_default_state(&pdev->dev);
+
+ return 0;
+}
+#else
+#define sim_suspend NULL
+#define sim_resume NULL
+#endif
+
+static struct platform_driver sim_driver = {
+ .driver = {
+ .name = DRIVER_NAME,
+ .owner = THIS_MODULE,
+ .of_match_table = sim_imx_dt_ids,
+ },
+ .probe = sim_probe,
+ .remove = sim_remove,
+ .suspend = sim_suspend,
+ .resume = sim_resume,
+ .id_table = imx_sim_devtype,
+};
+
+static int __init sim_drv_init(void)
+{
+ return platform_driver_register(&sim_driver);
+}
+
+static void __exit sim_drv_exit(void)
+{
+ platform_driver_unregister(&sim_driver);
+}
+
+module_init(sim_drv_init);
+module_exit(sim_drv_exit);
+
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("MXC SIM Driver");
+MODULE_LICENSE("GPL");
+
diff --git a/drivers/mxc/vpu/Kconfig b/drivers/mxc/vpu/Kconfig
new file mode 100644
index 000000000000..520209601dbe
--- /dev/null
+++ b/drivers/mxc/vpu/Kconfig
@@ -0,0 +1,31 @@
+#
+# Codec configuration
+#
+
+menu "MXC VPU(Video Processing Unit) support"
+
+config MXC_VPU
+ tristate "Support for MXC VPU(Video Processing Unit)"
+ depends on (SOC_IMX27 || SOC_IMX5 || SOC_IMX6Q)
+ default y
+ ---help---
+ The VPU codec device provides codec function for H.264/MPEG4/H.263,
+ as well as MPEG2/VC-1/DivX on some platforms.
+
+config MXC_VPU_DEBUG
+ bool "MXC VPU debugging"
+ depends on MXC_VPU != n
+ help
+ This is an option for the developers; most people should
+ say N here. This enables MXC VPU driver debugging.
+
+config MX6_VPU_352M
+ bool "MX6 VPU 352M"
+ depends on MXC_VPU
+ default n
+ help
+ Increase VPU frequncy to 352M, the config will disable bus frequency
+ adjust dynamic, and CPU lowest setpoint will be 352Mhz.
+ This config is used for special VPU use case.
+
+endmenu
diff --git a/drivers/mxc/vpu/Makefile b/drivers/mxc/vpu/Makefile
new file mode 100644
index 000000000000..1a821f4921cb
--- /dev/null
+++ b/drivers/mxc/vpu/Makefile
@@ -0,0 +1,9 @@
+#
+# Makefile for the VPU drivers.
+#
+
+obj-$(CONFIG_MXC_VPU) += mxc_vpu.o
+
+ifeq ($(CONFIG_MXC_VPU_DEBUG),y)
+EXTRA_CFLAGS += -DDEBUG
+endif
diff --git a/drivers/mxc/vpu/mxc_vpu.c b/drivers/mxc/vpu/mxc_vpu.c
new file mode 100644
index 000000000000..089daf7f9978
--- /dev/null
+++ b/drivers/mxc/vpu/mxc_vpu.c
@@ -0,0 +1,1349 @@
+/*
+ * Copyright 2006-2015 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/*!
+ * @file mxc_vpu.c
+ *
+ * @brief VPU system initialization and file operation implementation
+ *
+ * @ingroup VPU
+ */
+
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/stat.h>
+#include <linux/platform_device.h>
+#include <linux/kdev_t.h>
+#include <linux/dma-mapping.h>
+#include <linux/wait.h>
+#include <linux/list.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/fsl_devices.h>
+#include <linux/uaccess.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <linux/workqueue.h>
+#include <linux/sched/signal.h>
+#include <linux/sched.h>
+#include <linux/vmalloc.h>
+#include <linux/regulator/consumer.h>
+#include <linux/page-flags.h>
+#include <linux/mm_types.h>
+#include <linux/types.h>
+#include <linux/memblock.h>
+#include <linux/memory.h>
+#include <linux/version.h>
+#include <asm/page.h>
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)
+#include <linux/module.h>
+#include <linux/pm_runtime.h>
+#include <linux/sizes.h>
+#endif
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 10, 0)
+#include <linux/iram_alloc.h>
+#include <mach/clock.h>
+#include <mach/hardware.h>
+#include <mach/mxc_vpu.h>
+#endif
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0)
+#include <linux/busfreq-imx.h>
+#include <linux/clk.h>
+#include <linux/genalloc.h>
+#include <linux/mxc_vpu.h>
+#include <linux/of.h>
+#include <linux/reset.h>
+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)
+#include <mach/busfreq.h>
+#include <mach/common.h>
+#else
+#include <asm/sizes.h>
+#endif
+
+/* Define one new pgprot which combined uncached and XN(never executable) */
+#define pgprot_noncachedxn(prot) \
+ __pgprot_modify(prot, L_PTE_MT_MASK, L_PTE_MT_UNCACHED | L_PTE_XN)
+
+struct vpu_priv {
+ struct fasync_struct *async_queue;
+ struct work_struct work;
+ struct workqueue_struct *workqueue;
+ struct mutex lock;
+};
+
+/* To track the allocated memory buffer */
+struct memalloc_record {
+ struct list_head list;
+ struct vpu_mem_desc mem;
+};
+
+struct iram_setting {
+ u32 start;
+ u32 end;
+};
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0)
+static struct gen_pool *iram_pool;
+static u32 iram_base;
+#endif
+
+static LIST_HEAD(head);
+
+static int vpu_major;
+static int vpu_clk_usercount;
+static struct class *vpu_class;
+static struct vpu_priv vpu_data;
+static u8 open_count;
+static struct clk *vpu_clk;
+static struct vpu_mem_desc bitwork_mem = { 0 };
+static struct vpu_mem_desc pic_para_mem = { 0 };
+static struct vpu_mem_desc user_data_mem = { 0 };
+static struct vpu_mem_desc share_mem = { 0 };
+static struct vpu_mem_desc vshare_mem = { 0 };
+
+static void __iomem *vpu_base;
+static int vpu_ipi_irq;
+static u32 phy_vpu_base_addr;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 5, 0)
+static phys_addr_t top_address_DRAM;
+static struct mxc_vpu_platform_data *vpu_plat;
+#endif
+
+static struct device *vpu_dev;
+
+/* IRAM setting */
+static struct iram_setting iram;
+
+/* implement the blocking ioctl */
+static int irq_status;
+static int codec_done;
+static wait_queue_head_t vpu_queue;
+
+#ifdef CONFIG_SOC_IMX6Q
+#define MXC_VPU_HAS_JPU
+#endif
+
+#ifdef MXC_VPU_HAS_JPU
+static int vpu_jpu_irq;
+#endif
+
+#ifdef CONFIG_PM
+static unsigned int regBk[64];
+static unsigned int pc_before_suspend;
+#endif
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 14, 0)
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 5, 0) || LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0)
+static struct regulator *vpu_regulator;
+#endif
+#endif
+static atomic_t clk_cnt_from_ioc = ATOMIC_INIT(0);
+
+#define READ_REG(x) readl_relaxed(vpu_base + x)
+#define WRITE_REG(val, x) writel_relaxed(val, vpu_base + x)
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)
+/* redirect to static functions */
+static int cpu_is_mx6dl(void)
+{
+ int ret;
+ ret = of_machine_is_compatible("fsl,imx6dl");
+ return ret;
+}
+
+static int cpu_is_mx6q(void)
+{
+ int ret;
+ ret = of_machine_is_compatible("fsl,imx6q");
+ return ret;
+}
+#endif
+
+static void vpu_reset(void)
+{
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0)
+ int ret;
+
+ ret = device_reset(vpu_dev);
+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)
+ imx_src_reset_vpu();
+#else
+ if (vpu_plat->reset)
+ vpu_plat->reset();
+#endif
+}
+
+static long vpu_power_get(bool on)
+{
+ long ret = 0;
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 14, 0)
+ if (on) {
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 5, 0)
+ vpu_regulator = regulator_get(NULL, "cpu_vddvpu");
+ ret = IS_ERR(vpu_regulator);
+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0)
+ vpu_regulator = devm_regulator_get(vpu_dev, "pu");
+ ret = IS_ERR(vpu_regulator);
+#endif
+ } else {
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 5, 0)
+ if (!IS_ERR(vpu_regulator))
+ regulator_put(vpu_regulator);
+#endif
+ }
+#endif
+ return ret;
+}
+
+static void vpu_power_up(bool on)
+{
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)
+ if (on)
+ pm_runtime_get_sync(vpu_dev);
+#endif
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 14, 0)
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 5, 0) || LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0)
+ if (on) {
+ if (!IS_ERR(vpu_regulator)) {
+ if (regulator_enable(vpu_regulator))
+ dev_err(vpu_dev, "failed to power up vpu\n");
+ }
+ } else {
+ if (!IS_ERR(vpu_regulator)) {
+ if (regulator_disable(vpu_regulator))
+ dev_err(vpu_dev, "failed to power down vpu\n");
+ }
+ }
+#else
+ imx_gpc_power_up_pu(on);
+#endif
+#endif
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)
+ if (!on)
+ pm_runtime_put_sync_suspend(vpu_dev);
+#endif
+}
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0)
+static int cpu_is_mx53(void)
+{
+ return 0;
+}
+
+static int cpu_is_mx51(void)
+{
+ return 0;
+}
+
+#define VM_RESERVED 0
+#endif
+
+/*!
+ * Private function to alloc dma buffer
+ * @return status 0 success.
+ */
+static int vpu_alloc_dma_buffer(struct vpu_mem_desc *mem)
+{
+ mem->cpu_addr = (unsigned long)
+ dma_alloc_coherent(NULL, PAGE_ALIGN(mem->size),
+ (dma_addr_t *) (&mem->phy_addr),
+ GFP_DMA | GFP_KERNEL);
+ dev_dbg(vpu_dev, "[ALLOC] mem alloc cpu_addr = 0x%x\n", mem->cpu_addr);
+ if ((void *)(mem->cpu_addr) == NULL) {
+ dev_err(vpu_dev, "Physical memory allocation error!\n");
+ return -1;
+ }
+ return 0;
+}
+
+/*!
+ * Private function to free dma buffer
+ */
+static void vpu_free_dma_buffer(struct vpu_mem_desc *mem)
+{
+ if (mem->cpu_addr != 0) {
+ dma_free_coherent(0, PAGE_ALIGN(mem->size),
+ (void *)mem->cpu_addr, mem->phy_addr);
+ }
+}
+
+/*!
+ * Private function to free buffers
+ * @return status 0 success.
+ */
+static int vpu_free_buffers(void)
+{
+ struct memalloc_record *rec, *n;
+ struct vpu_mem_desc mem;
+
+ list_for_each_entry_safe(rec, n, &head, list) {
+ mem = rec->mem;
+ if (mem.cpu_addr != 0) {
+ vpu_free_dma_buffer(&mem);
+ dev_dbg(vpu_dev, "[FREE] freed paddr=0x%08X\n", mem.phy_addr);
+ /* delete from list */
+ list_del(&rec->list);
+ kfree(rec);
+ }
+ }
+
+ return 0;
+}
+
+static inline void vpu_worker_callback(struct work_struct *w)
+{
+ struct vpu_priv *dev = container_of(w, struct vpu_priv,
+ work);
+
+ if (dev->async_queue)
+ kill_fasync(&dev->async_queue, SIGIO, POLL_IN);
+
+ irq_status = 1;
+ /*
+ * Clock is gated on when dec/enc started, gate it off when
+ * codec is done.
+ */
+ if (codec_done)
+ codec_done = 0;
+
+ wake_up_interruptible(&vpu_queue);
+}
+
+/*!
+ * @brief vpu interrupt handler
+ */
+static irqreturn_t vpu_ipi_irq_handler(int irq, void *dev_id)
+{
+ struct vpu_priv *dev = dev_id;
+ unsigned long reg;
+
+ reg = READ_REG(BIT_INT_REASON);
+ if (reg & 0x8)
+ codec_done = 1;
+ WRITE_REG(0x1, BIT_INT_CLEAR);
+
+ queue_work(dev->workqueue, &dev->work);
+
+ return IRQ_HANDLED;
+}
+
+/*!
+ * @brief vpu jpu interrupt handler
+ */
+#ifdef MXC_VPU_HAS_JPU
+static irqreturn_t vpu_jpu_irq_handler(int irq, void *dev_id)
+{
+ struct vpu_priv *dev = dev_id;
+ unsigned long reg;
+
+ reg = READ_REG(MJPEG_PIC_STATUS_REG);
+ if (reg & 0x3)
+ codec_done = 1;
+
+ queue_work(dev->workqueue, &dev->work);
+
+ return IRQ_HANDLED;
+}
+#endif
+
+/*!
+ * @brief check phy memory prepare to pass to vpu is valid or not, we
+ * already address some issue that if pass a wrong address to vpu
+ * (like virtual address), system will hang.
+ *
+ * @return true return is a valid phy memory address, false return not.
+ */
+bool vpu_is_valid_phy_memory(u32 paddr)
+{
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 5, 0)
+ if (paddr > top_address_DRAM)
+ return false;
+#endif
+
+ return true;
+}
+
+/*!
+ * @brief open function for vpu file operation
+ *
+ * @return 0 on success or negative error code on error
+ */
+static int vpu_open(struct inode *inode, struct file *filp)
+{
+
+ mutex_lock(&vpu_data.lock);
+
+ if (open_count++ == 0) {
+ vpu_power_up(true);
+
+#ifdef CONFIG_SOC_IMX6Q
+ clk_prepare(vpu_clk);
+ clk_enable(vpu_clk);
+ if (READ_REG(BIT_CUR_PC))
+ dev_dbg(vpu_dev, "Not power off before vpu open!\n");
+ clk_disable(vpu_clk);
+ clk_unprepare(vpu_clk);
+#endif
+ }
+
+ filp->private_data = (void *)(&vpu_data);
+ mutex_unlock(&vpu_data.lock);
+ return 0;
+}
+
+/*!
+ * @brief IO ctrl function for vpu file operation
+ * @param cmd IO ctrl command
+ * @return 0 on success or negative error code on error
+ */
+static long vpu_ioctl(struct file *filp, u_int cmd,
+ u_long arg)
+{
+ int ret = 0;
+
+ switch (cmd) {
+ case VPU_IOC_PHYMEM_ALLOC:
+ {
+ struct memalloc_record *rec;
+
+ rec = kzalloc(sizeof(*rec), GFP_KERNEL);
+ if (!rec)
+ return -ENOMEM;
+
+ ret = copy_from_user(&(rec->mem),
+ (struct vpu_mem_desc *)arg,
+ sizeof(struct vpu_mem_desc));
+ if (ret) {
+ kfree(rec);
+ return -EFAULT;
+ }
+
+ dev_dbg(vpu_dev, "[ALLOC] mem alloc size = 0x%x\n",
+ rec->mem.size);
+
+ ret = vpu_alloc_dma_buffer(&(rec->mem));
+ if (ret == -1) {
+ kfree(rec);
+ dev_err(vpu_dev,
+ "Physical memory allocation error!\n");
+ break;
+ }
+ ret = copy_to_user((void __user *)arg, &(rec->mem),
+ sizeof(struct vpu_mem_desc));
+ if (ret) {
+ kfree(rec);
+ ret = -EFAULT;
+ break;
+ }
+
+ mutex_lock(&vpu_data.lock);
+ list_add(&rec->list, &head);
+ mutex_unlock(&vpu_data.lock);
+
+ break;
+ }
+ case VPU_IOC_PHYMEM_FREE:
+ {
+ struct memalloc_record *rec, *n;
+ struct vpu_mem_desc vpu_mem;
+
+ ret = copy_from_user(&vpu_mem,
+ (struct vpu_mem_desc *)arg,
+ sizeof(struct vpu_mem_desc));
+ if (ret)
+ return -EACCES;
+
+ dev_dbg(vpu_dev, "[FREE] mem freed cpu_addr = 0x%x\n",
+ vpu_mem.cpu_addr);
+ if ((void *)vpu_mem.cpu_addr != NULL)
+ vpu_free_dma_buffer(&vpu_mem);
+
+ mutex_lock(&vpu_data.lock);
+ list_for_each_entry_safe(rec, n, &head, list) {
+ if (rec->mem.cpu_addr == vpu_mem.cpu_addr) {
+ /* delete from list */
+ list_del(&rec->list);
+ kfree(rec);
+ break;
+ }
+ }
+ mutex_unlock(&vpu_data.lock);
+
+ break;
+ }
+ case VPU_IOC_WAIT4INT:
+ {
+ u_long timeout = (u_long) arg;
+ if (!wait_event_interruptible_timeout
+ (vpu_queue, irq_status != 0,
+ msecs_to_jiffies(timeout))) {
+ dev_warn(vpu_dev, "VPU blocking: timeout.\n");
+ ret = -ETIME;
+ } else if (signal_pending(current)) {
+ dev_warn(vpu_dev, "VPU interrupt received.\n");
+ ret = -ERESTARTSYS;
+ } else
+ irq_status = 0;
+ break;
+ }
+ case VPU_IOC_IRAM_SETTING:
+ {
+ ret = copy_to_user((void __user *)arg, &iram,
+ sizeof(struct iram_setting));
+ if (ret)
+ ret = -EFAULT;
+
+ break;
+ }
+ case VPU_IOC_CLKGATE_SETTING:
+ {
+ u32 clkgate_en;
+
+ if (get_user(clkgate_en, (u32 __user *) arg))
+ return -EFAULT;
+
+ if (clkgate_en) {
+ clk_prepare(vpu_clk);
+ clk_enable(vpu_clk);
+ atomic_inc(&clk_cnt_from_ioc);
+ } else {
+ clk_disable(vpu_clk);
+ clk_unprepare(vpu_clk);
+ atomic_dec(&clk_cnt_from_ioc);
+ }
+
+ break;
+ }
+ case VPU_IOC_GET_SHARE_MEM:
+ {
+ mutex_lock(&vpu_data.lock);
+ if (share_mem.cpu_addr != 0) {
+ ret = copy_to_user((void __user *)arg,
+ &share_mem,
+ sizeof(struct vpu_mem_desc));
+ mutex_unlock(&vpu_data.lock);
+ break;
+ } else {
+ if (copy_from_user(&share_mem,
+ (struct vpu_mem_desc *)arg,
+ sizeof(struct vpu_mem_desc))) {
+ mutex_unlock(&vpu_data.lock);
+ return -EFAULT;
+ }
+ if (vpu_alloc_dma_buffer(&share_mem) == -1)
+ ret = -EFAULT;
+ else {
+ if (copy_to_user((void __user *)arg,
+ &share_mem,
+ sizeof(struct
+ vpu_mem_desc)))
+ ret = -EFAULT;
+ }
+ }
+ mutex_unlock(&vpu_data.lock);
+ break;
+ }
+ case VPU_IOC_REQ_VSHARE_MEM:
+ {
+ mutex_lock(&vpu_data.lock);
+ if (vshare_mem.cpu_addr != 0) {
+ ret = copy_to_user((void __user *)arg,
+ &vshare_mem,
+ sizeof(struct vpu_mem_desc));
+ mutex_unlock(&vpu_data.lock);
+ break;
+ } else {
+ if (copy_from_user(&vshare_mem,
+ (struct vpu_mem_desc *)arg,
+ sizeof(struct
+ vpu_mem_desc))) {
+ mutex_unlock(&vpu_data.lock);
+ return -EFAULT;
+ }
+ /* vmalloc shared memory if not allocated */
+ if (!vshare_mem.cpu_addr)
+ vshare_mem.cpu_addr =
+ (unsigned long)
+ vmalloc_user(vshare_mem.size);
+ if (copy_to_user
+ ((void __user *)arg, &vshare_mem,
+ sizeof(struct vpu_mem_desc)))
+ ret = -EFAULT;
+ }
+ mutex_unlock(&vpu_data.lock);
+ break;
+ }
+ case VPU_IOC_GET_WORK_ADDR:
+ {
+ if (bitwork_mem.cpu_addr != 0) {
+ ret =
+ copy_to_user((void __user *)arg,
+ &bitwork_mem,
+ sizeof(struct vpu_mem_desc));
+ break;
+ } else {
+ if (copy_from_user(&bitwork_mem,
+ (struct vpu_mem_desc *)arg,
+ sizeof(struct vpu_mem_desc)))
+ return -EFAULT;
+
+ if (vpu_alloc_dma_buffer(&bitwork_mem) == -1)
+ ret = -EFAULT;
+ else if (copy_to_user((void __user *)arg,
+ &bitwork_mem,
+ sizeof(struct
+ vpu_mem_desc)))
+ ret = -EFAULT;
+ }
+ break;
+ }
+ /*
+ * The following two ioctl is used when user allocates working buffer
+ * and register it to vpu driver.
+ */
+ case VPU_IOC_QUERY_BITWORK_MEM:
+ {
+ if (copy_to_user((void __user *)arg,
+ &bitwork_mem,
+ sizeof(struct vpu_mem_desc)))
+ ret = -EFAULT;
+ break;
+ }
+ case VPU_IOC_SET_BITWORK_MEM:
+ {
+ if (copy_from_user(&bitwork_mem,
+ (struct vpu_mem_desc *)arg,
+ sizeof(struct vpu_mem_desc)))
+ ret = -EFAULT;
+ break;
+ }
+ case VPU_IOC_SYS_SW_RESET:
+ {
+ vpu_reset();
+ break;
+ }
+ case VPU_IOC_REG_DUMP:
+ break;
+ case VPU_IOC_PHYMEM_DUMP:
+ break;
+ case VPU_IOC_PHYMEM_CHECK:
+ {
+ struct vpu_mem_desc check_memory;
+ ret = copy_from_user(&check_memory,
+ (void __user *)arg,
+ sizeof(struct vpu_mem_desc));
+ if (ret != 0) {
+ dev_err(vpu_dev, "copy from user failure:%d\n", ret);
+ ret = -EFAULT;
+ break;
+ }
+ ret = vpu_is_valid_phy_memory((u32)check_memory.phy_addr);
+
+ dev_dbg(vpu_dev, "vpu: memory phy:0x%x %s phy memory\n",
+ check_memory.phy_addr, (ret ? "is" : "isn't"));
+ /* borrow .size to pass back the result. */
+ check_memory.size = ret;
+ ret = copy_to_user((void __user *)arg, &check_memory,
+ sizeof(struct vpu_mem_desc));
+ if (ret) {
+ ret = -EFAULT;
+ break;
+ }
+ break;
+ }
+ case VPU_IOC_LOCK_DEV:
+ {
+ u32 lock_en;
+
+ if (get_user(lock_en, (u32 __user *) arg))
+ return -EFAULT;
+
+ if (lock_en)
+ mutex_lock(&vpu_data.lock);
+ else
+ mutex_unlock(&vpu_data.lock);
+
+ break;
+ }
+ default:
+ {
+ dev_err(vpu_dev, "No such IOCTL, cmd is %d\n", cmd);
+ ret = -EINVAL;
+ break;
+ }
+ }
+ return ret;
+}
+
+/*!
+ * @brief Release function for vpu file operation
+ * @return 0 on success or negative error code on error
+ */
+static int vpu_release(struct inode *inode, struct file *filp)
+{
+ int i;
+ unsigned long timeout;
+
+ mutex_lock(&vpu_data.lock);
+
+ if (open_count > 0 && !(--open_count)) {
+
+ /* Wait for vpu go to idle state */
+ clk_prepare(vpu_clk);
+ clk_enable(vpu_clk);
+ if (READ_REG(BIT_CUR_PC)) {
+
+ timeout = jiffies + HZ;
+ while (READ_REG(BIT_BUSY_FLAG)) {
+ msleep(1);
+ if (time_after(jiffies, timeout)) {
+ dev_warn(vpu_dev, "VPU timeout during release\n");
+ break;
+ }
+ }
+ clk_disable(vpu_clk);
+ clk_unprepare(vpu_clk);
+
+ /* Clean up interrupt */
+ cancel_work_sync(&vpu_data.work);
+ flush_workqueue(vpu_data.workqueue);
+ irq_status = 0;
+
+ clk_prepare(vpu_clk);
+ clk_enable(vpu_clk);
+ if (READ_REG(BIT_BUSY_FLAG)) {
+
+ if (cpu_is_mx51() || cpu_is_mx53()) {
+ dev_err(vpu_dev,
+ "fatal error: can't gate/power off when VPU is busy\n");
+ clk_disable(vpu_clk);
+ clk_unprepare(vpu_clk);
+ mutex_unlock(&vpu_data.lock);
+ return -EFAULT;
+ }
+
+#ifdef CONFIG_SOC_IMX6Q
+ if (cpu_is_mx6dl() || cpu_is_mx6q()) {
+ WRITE_REG(0x11, 0x10F0);
+ timeout = jiffies + HZ;
+ while (READ_REG(0x10F4) != 0x77) {
+ msleep(1);
+ if (time_after(jiffies, timeout))
+ break;
+ }
+
+ if (READ_REG(0x10F4) != 0x77) {
+ dev_err(vpu_dev,
+ "fatal error: can't gate/power off when VPU is busy\n");
+ WRITE_REG(0x0, 0x10F0);
+ clk_disable(vpu_clk);
+ clk_unprepare(vpu_clk);
+ mutex_unlock(&vpu_data.lock);
+ return -EFAULT;
+ } else
+ vpu_reset();
+ }
+#endif
+ }
+ }
+ clk_disable(vpu_clk);
+ clk_unprepare(vpu_clk);
+
+ vpu_free_buffers();
+
+ /* Free shared memory when vpu device is idle */
+ vpu_free_dma_buffer(&share_mem);
+ share_mem.cpu_addr = 0;
+ vfree((void *)vshare_mem.cpu_addr);
+ vshare_mem.cpu_addr = 0;
+
+ vpu_clk_usercount = atomic_read(&clk_cnt_from_ioc);
+ for (i = 0; i < vpu_clk_usercount; i++) {
+ clk_disable(vpu_clk);
+ clk_unprepare(vpu_clk);
+ atomic_dec(&clk_cnt_from_ioc);
+ }
+
+ vpu_power_up(false);
+ }
+ mutex_unlock(&vpu_data.lock);
+
+ return 0;
+}
+
+/*!
+ * @brief fasync function for vpu file operation
+ * @return 0 on success or negative error code on error
+ */
+static int vpu_fasync(int fd, struct file *filp, int mode)
+{
+ struct vpu_priv *dev = (struct vpu_priv *)filp->private_data;
+ return fasync_helper(fd, filp, mode, &dev->async_queue);
+}
+
+/*!
+ * @brief memory map function of harware registers for vpu file operation
+ * @return 0 on success or negative error code on error
+ */
+static int vpu_map_hwregs(struct file *fp, struct vm_area_struct *vm)
+{
+ unsigned long pfn;
+
+ vm->vm_flags |= VM_IO | VM_RESERVED;
+ /*
+ * Since vpu registers have been mapped with ioremap() at probe
+ * which L_PTE_XN is 1, and the same physical address must be
+ * mapped multiple times with same type, so set L_PTE_XN to 1 here.
+ * Otherwise, there may be unexpected result in video codec.
+ */
+ vm->vm_page_prot = pgprot_noncachedxn(vm->vm_page_prot);
+ pfn = phy_vpu_base_addr >> PAGE_SHIFT;
+ dev_dbg(vpu_dev, "size=0x%x, page no.=0x%x\n",
+ (int)(vm->vm_end - vm->vm_start), (int)pfn);
+ return remap_pfn_range(vm, vm->vm_start, pfn, vm->vm_end - vm->vm_start,
+ vm->vm_page_prot) ? -EAGAIN : 0;
+}
+
+/*!
+ * @brief memory map function of memory for vpu file operation
+ * @return 0 on success or negative error code on error
+ */
+static int vpu_map_dma_mem(struct file *fp, struct vm_area_struct *vm)
+{
+ int request_size;
+ request_size = vm->vm_end - vm->vm_start;
+
+ dev_dbg(vpu_dev, "start=0x%x, pgoff=0x%x, size=0x%x\n",
+ (unsigned int)(vm->vm_start), (unsigned int)(vm->vm_pgoff),
+ request_size);
+
+ vm->vm_flags |= VM_IO | VM_RESERVED;
+ vm->vm_page_prot = pgprot_writecombine(vm->vm_page_prot);
+
+ return remap_pfn_range(vm, vm->vm_start, vm->vm_pgoff,
+ request_size, vm->vm_page_prot) ? -EAGAIN : 0;
+
+}
+
+/* !
+ * @brief memory map function of vmalloced share memory
+ * @return 0 on success or negative error code on error
+ */
+static int vpu_map_vshare_mem(struct file *fp, struct vm_area_struct *vm)
+{
+ int ret = -EINVAL;
+
+ ret = remap_vmalloc_range(vm, (void *)(vm->vm_pgoff << PAGE_SHIFT), 0);
+ vm->vm_flags |= VM_IO;
+
+ return ret;
+}
+/*!
+ * @brief memory map interface for vpu file operation
+ * @return 0 on success or negative error code on error
+ */
+static int vpu_mmap(struct file *fp, struct vm_area_struct *vm)
+{
+ unsigned long offset;
+
+ offset = vshare_mem.cpu_addr >> PAGE_SHIFT;
+
+ if (vm->vm_pgoff && (vm->vm_pgoff == offset))
+ return vpu_map_vshare_mem(fp, vm);
+ else if (vm->vm_pgoff)
+ return vpu_map_dma_mem(fp, vm);
+ else
+ return vpu_map_hwregs(fp, vm);
+}
+
+const struct file_operations vpu_fops = {
+ .owner = THIS_MODULE,
+ .open = vpu_open,
+ .unlocked_ioctl = vpu_ioctl,
+ .release = vpu_release,
+ .fasync = vpu_fasync,
+ .mmap = vpu_mmap,
+};
+
+/*!
+ * This function is called by the driver framework to initialize the vpu device.
+ * @param dev The device structure for the vpu passed in by the framework.
+ * @return 0 on success or negative error code on error
+ */
+static int vpu_dev_probe(struct platform_device *pdev)
+{
+ int err = 0;
+ struct device *temp_class;
+ struct resource *res;
+ unsigned long addr = 0;
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)
+ struct device_node *np = pdev->dev.of_node;
+ u32 iramsize;
+
+ err = of_property_read_u32(np, "iramsize", (u32 *)&iramsize);
+ if (!err && iramsize)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0)
+ {
+ iram_pool = of_gen_pool_get(np, "iram", 0);
+ if (!iram_pool) {
+ dev_err(&pdev->dev, "iram pool not available\n");
+ return -ENOMEM;
+ }
+
+ iram_base = gen_pool_alloc(iram_pool, iramsize);
+ if (!iram_base) {
+ dev_err(&pdev->dev, "unable to alloc iram\n");
+ return -ENOMEM;
+ }
+
+ addr = gen_pool_virt_to_phys(iram_pool, iram_base);
+ }
+#else
+ iram_alloc(iramsize, &addr);
+#endif
+ if (addr == 0)
+ iram.start = iram.end = 0;
+ else {
+ iram.start = addr;
+ iram.end = addr + iramsize - 1;
+ }
+#else
+
+ vpu_plat = pdev->dev.platform_data;
+
+ if (vpu_plat && vpu_plat->iram_enable && vpu_plat->iram_size)
+ iram_alloc(vpu_plat->iram_size, &addr);
+ if (addr == 0)
+ iram.start = iram.end = 0;
+ else {
+ iram.start = addr;
+ iram.end = addr + vpu_plat->iram_size - 1;
+ }
+#endif
+
+ vpu_dev = &pdev->dev;
+
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "vpu_regs");
+ if (!res) {
+ dev_err(vpu_dev, "vpu: unable to get vpu base addr\n");
+ return -ENODEV;
+ }
+ phy_vpu_base_addr = res->start;
+ vpu_base = ioremap(res->start, res->end - res->start);
+
+ vpu_major = register_chrdev(vpu_major, "mxc_vpu", &vpu_fops);
+ if (vpu_major < 0) {
+ dev_err(vpu_dev, "vpu: unable to get a major for VPU\n");
+ err = -EBUSY;
+ goto error;
+ }
+
+ vpu_class = class_create(THIS_MODULE, "mxc_vpu");
+ if (IS_ERR(vpu_class)) {
+ err = PTR_ERR(vpu_class);
+ goto err_out_chrdev;
+ }
+
+ temp_class = device_create(vpu_class, NULL, MKDEV(vpu_major, 0),
+ NULL, "mxc_vpu");
+ if (IS_ERR(temp_class)) {
+ err = PTR_ERR(temp_class);
+ goto err_out_class;
+ }
+
+ vpu_clk = clk_get(&pdev->dev, "vpu_clk");
+ if (IS_ERR(vpu_clk)) {
+ err = -ENOENT;
+ goto err_out_class;
+ }
+
+ vpu_ipi_irq = platform_get_irq_byname(pdev, "vpu_ipi_irq");
+ if (vpu_ipi_irq < 0) {
+ dev_err(vpu_dev, "vpu: unable to get vpu interrupt\n");
+ err = -ENXIO;
+ goto err_out_class;
+ }
+ err = request_irq(vpu_ipi_irq, vpu_ipi_irq_handler, 0, "VPU_CODEC_IRQ",
+ (void *)(&vpu_data));
+ if (err)
+ goto err_out_class;
+ if (vpu_power_get(true)) {
+ if (!(cpu_is_mx51() || cpu_is_mx53())) {
+ dev_err(vpu_dev, "failed to get vpu power\n");
+ goto err_out_class;
+ } else {
+ /* regulator_get will return error on MX5x,
+ * just igore it everywhere*/
+ dev_warn(vpu_dev, "failed to get vpu power\n");
+ }
+ }
+
+#ifdef MXC_VPU_HAS_JPU
+ vpu_jpu_irq = platform_get_irq_byname(pdev, "vpu_jpu_irq");
+ if (vpu_jpu_irq < 0) {
+ dev_err(vpu_dev, "vpu: unable to get vpu jpu interrupt\n");
+ err = -ENXIO;
+ free_irq(vpu_ipi_irq, &vpu_data);
+ goto err_out_class;
+ }
+ err = request_irq(vpu_jpu_irq, vpu_jpu_irq_handler, IRQF_TRIGGER_RISING,
+ "VPU_JPG_IRQ", (void *)(&vpu_data));
+ if (err) {
+ free_irq(vpu_ipi_irq, &vpu_data);
+ goto err_out_class;
+ }
+#endif
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)
+ pm_runtime_enable(&pdev->dev);
+#endif
+
+ vpu_data.workqueue = create_workqueue("vpu_wq");
+ INIT_WORK(&vpu_data.work, vpu_worker_callback);
+ mutex_init(&vpu_data.lock);
+ dev_info(vpu_dev, "VPU initialized\n");
+ goto out;
+
+err_out_class:
+ device_destroy(vpu_class, MKDEV(vpu_major, 0));
+ class_destroy(vpu_class);
+err_out_chrdev:
+ unregister_chrdev(vpu_major, "mxc_vpu");
+error:
+ iounmap(vpu_base);
+out:
+ return err;
+}
+
+static int vpu_dev_remove(struct platform_device *pdev)
+{
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)
+ pm_runtime_disable(&pdev->dev);
+#endif
+ free_irq(vpu_ipi_irq, &vpu_data);
+#ifdef MXC_VPU_HAS_JPU
+ free_irq(vpu_jpu_irq, &vpu_data);
+#endif
+ cancel_work_sync(&vpu_data.work);
+ flush_workqueue(vpu_data.workqueue);
+ destroy_workqueue(vpu_data.workqueue);
+
+ iounmap(vpu_base);
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)
+ if (iram.start)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0)
+ gen_pool_free(iram_pool, iram_base, iram.end-iram.start+1);
+#else
+ iram_free(iram.start, iram.end-iram.start+1);
+#endif
+#else
+ if (vpu_plat && vpu_plat->iram_enable && vpu_plat->iram_size)
+ iram_free(iram.start, vpu_plat->iram_size);
+#endif
+
+ vpu_power_get(false);
+ return 0;
+}
+
+#ifdef CONFIG_PM
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)
+static int vpu_suspend(struct device *dev)
+#else
+static int vpu_suspend(struct platform_device *pdev, pm_message_t state)
+#endif
+{
+ int i;
+ unsigned long timeout;
+
+ mutex_lock(&vpu_data.lock);
+ if (open_count == 0) {
+ /* VPU is released (all instances are freed),
+ * clock is already off, context is no longer needed,
+ * power is already off on MX6,
+ * gate power on MX51 */
+ if (cpu_is_mx51()) {
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 5, 0)
+ if (vpu_plat->pg)
+ vpu_plat->pg(1);
+#endif
+ }
+ } else {
+ /* Wait for vpu go to idle state, suspect vpu cannot be changed
+ to idle state after about 1 sec */
+ timeout = jiffies + HZ;
+ clk_prepare(vpu_clk);
+ clk_enable(vpu_clk);
+ while (READ_REG(BIT_BUSY_FLAG)) {
+ msleep(1);
+ if (time_after(jiffies, timeout)) {
+ clk_disable(vpu_clk);
+ clk_unprepare(vpu_clk);
+ mutex_unlock(&vpu_data.lock);
+ return -EAGAIN;
+ }
+ }
+ clk_disable(vpu_clk);
+ clk_unprepare(vpu_clk);
+
+ /* Make sure clock is disabled before suspend */
+ vpu_clk_usercount = atomic_read(&clk_cnt_from_ioc);
+ for (i = 0; i < vpu_clk_usercount; i++) {
+ clk_disable(vpu_clk);
+ clk_unprepare(vpu_clk);
+ }
+
+ if (cpu_is_mx53()) {
+ mutex_unlock(&vpu_data.lock);
+ return 0;
+ }
+
+ if (bitwork_mem.cpu_addr != 0) {
+ clk_prepare(vpu_clk);
+ clk_enable(vpu_clk);
+ /* Save 64 registers from BIT_CODE_BUF_ADDR */
+ for (i = 0; i < 64; i++)
+ regBk[i] = READ_REG(BIT_CODE_BUF_ADDR + (i * 4));
+ pc_before_suspend = READ_REG(BIT_CUR_PC);
+ clk_disable(vpu_clk);
+ clk_unprepare(vpu_clk);
+ }
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 5, 0)
+ if (vpu_plat->pg)
+ vpu_plat->pg(1);
+#endif
+
+ /* If VPU is working before suspend, disable
+ * regulator to make usecount right. */
+ vpu_power_up(false);
+ }
+
+ mutex_unlock(&vpu_data.lock);
+ return 0;
+}
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)
+static int vpu_resume(struct device *dev)
+#else
+static int vpu_resume(struct platform_device *pdev)
+#endif
+{
+ int i;
+
+ mutex_lock(&vpu_data.lock);
+ if (open_count == 0) {
+ /* VPU is released (all instances are freed),
+ * clock should be kept off, context is no longer needed,
+ * power should be kept off on MX6,
+ * disable power gating on MX51 */
+ if (cpu_is_mx51()) {
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 5, 0)
+ if (vpu_plat->pg)
+ vpu_plat->pg(0);
+#endif
+ }
+ } else {
+ if (cpu_is_mx53())
+ goto recover_clk;
+
+ /* If VPU is working before suspend, enable
+ * regulator to make usecount right. */
+ vpu_power_up(true);
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 5, 0)
+ if (vpu_plat->pg)
+ vpu_plat->pg(0);
+#endif
+
+ if (bitwork_mem.cpu_addr != 0) {
+ u32 *p = (u32 *) bitwork_mem.cpu_addr;
+ u32 data, pc;
+ u16 data_hi;
+ u16 data_lo;
+
+ clk_prepare(vpu_clk);
+ clk_enable(vpu_clk);
+
+ pc = READ_REG(BIT_CUR_PC);
+ if (pc) {
+ dev_warn(vpu_dev, "Not power off after suspend (PC=0x%x)\n", pc);
+ clk_disable(vpu_clk);
+ clk_unprepare(vpu_clk);
+ goto recover_clk;
+ }
+
+ /* Restore registers */
+ for (i = 0; i < 64; i++)
+ WRITE_REG(regBk[i], BIT_CODE_BUF_ADDR + (i * 4));
+
+ WRITE_REG(0x0, BIT_RESET_CTRL);
+ WRITE_REG(0x0, BIT_CODE_RUN);
+ /* MX6 RTL has a bug not to init MBC_SET_SUBBLK_EN on reset */
+#ifdef CONFIG_SOC_IMX6Q
+ WRITE_REG(0x0, MBC_SET_SUBBLK_EN);
+#endif
+
+ /*
+ * Re-load boot code, from the codebuffer in external RAM.
+ * Thankfully, we only need 4096 bytes, same for all platforms.
+ */
+ for (i = 0; i < 2048; i += 4) {
+ data = p[(i / 2) + 1];
+ data_hi = (data >> 16) & 0xFFFF;
+ data_lo = data & 0xFFFF;
+ WRITE_REG((i << 16) | data_hi, BIT_CODE_DOWN);
+ WRITE_REG(((i + 1) << 16) | data_lo,
+ BIT_CODE_DOWN);
+
+ data = p[i / 2];
+ data_hi = (data >> 16) & 0xFFFF;
+ data_lo = data & 0xFFFF;
+ WRITE_REG(((i + 2) << 16) | data_hi,
+ BIT_CODE_DOWN);
+ WRITE_REG(((i + 3) << 16) | data_lo,
+ BIT_CODE_DOWN);
+ }
+
+ if (pc_before_suspend) {
+ WRITE_REG(0x1, BIT_BUSY_FLAG);
+ WRITE_REG(0x1, BIT_CODE_RUN);
+ while (READ_REG(BIT_BUSY_FLAG))
+ ;
+ } else {
+ dev_warn(vpu_dev, "PC=0 before suspend\n");
+ }
+ clk_disable(vpu_clk);
+ clk_unprepare(vpu_clk);
+ }
+
+recover_clk:
+ /* Recover vpu clock */
+ for (i = 0; i < vpu_clk_usercount; i++) {
+ clk_prepare(vpu_clk);
+ clk_enable(vpu_clk);
+ }
+ }
+
+ mutex_unlock(&vpu_data.lock);
+ return 0;
+}
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)
+static int vpu_runtime_suspend(struct device *dev)
+{
+ release_bus_freq(BUS_FREQ_HIGH);
+ return 0;
+}
+
+static int vpu_runtime_resume(struct device *dev)
+{
+ request_bus_freq(BUS_FREQ_HIGH);
+ return 0;
+}
+
+static const struct dev_pm_ops vpu_pm_ops = {
+ SET_RUNTIME_PM_OPS(vpu_runtime_suspend, vpu_runtime_resume, NULL)
+ SET_SYSTEM_SLEEP_PM_OPS(vpu_suspend, vpu_resume)
+};
+#endif
+
+#else
+#define vpu_suspend NULL
+#define vpu_resume NULL
+#endif /* !CONFIG_PM */
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)
+static const struct of_device_id vpu_of_match[] = {
+ { .compatible = "fsl,imx6-vpu", },
+ {/* sentinel */}
+};
+MODULE_DEVICE_TABLE(of, vpu_of_match);
+#endif
+
+/*! Driver definition
+ *
+ */
+static struct platform_driver mxcvpu_driver = {
+ .driver = {
+ .name = "mxc_vpu",
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)
+ .of_match_table = vpu_of_match,
+#ifdef CONFIG_PM
+ .pm = &vpu_pm_ops,
+#endif
+#endif
+ },
+ .probe = vpu_dev_probe,
+ .remove = vpu_dev_remove,
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 5, 0)
+ .suspend = vpu_suspend,
+ .resume = vpu_resume,
+#endif
+};
+
+static int __init vpu_init(void)
+{
+ int ret = platform_driver_register(&mxcvpu_driver);
+
+ init_waitqueue_head(&vpu_queue);
+
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 5, 0)
+ memblock_analyze();
+ top_address_DRAM = memblock_end_of_DRAM_with_reserved();
+#endif
+
+ return ret;
+}
+
+static void __exit vpu_exit(void)
+{
+ if (vpu_major > 0) {
+ device_destroy(vpu_class, MKDEV(vpu_major, 0));
+ class_destroy(vpu_class);
+ unregister_chrdev(vpu_major, "mxc_vpu");
+ vpu_major = 0;
+ }
+
+ vpu_free_dma_buffer(&bitwork_mem);
+ vpu_free_dma_buffer(&pic_para_mem);
+ vpu_free_dma_buffer(&user_data_mem);
+
+ /* reset VPU state */
+ vpu_power_up(true);
+ clk_prepare(vpu_clk);
+ clk_enable(vpu_clk);
+ vpu_reset();
+ clk_disable(vpu_clk);
+ clk_unprepare(vpu_clk);
+ vpu_power_up(false);
+
+ clk_put(vpu_clk);
+
+ platform_driver_unregister(&mxcvpu_driver);
+ return;
+}
+
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("Linux VPU driver for Freescale i.MX/MXC");
+MODULE_LICENSE("GPL");
+
+module_init(vpu_init);
+module_exit(vpu_exit);
diff --git a/drivers/mxc/vpu_legacy/Kconfig b/drivers/mxc/vpu_legacy/Kconfig
new file mode 100644
index 000000000000..c0115d1eb630
--- /dev/null
+++ b/drivers/mxc/vpu_legacy/Kconfig
@@ -0,0 +1,20 @@
+#
+# Codec configuration
+#
+
+menu "MXC VPU(Video Processing Unit) LEGACY DECODER support"
+
+config MXC_VPU_LEGACY
+ tristate "Support for MXC VPU(Video Processing Unit) LEGACY A0 DECODER"
+ default n
+ ---help---
+ The VPU codec device provides codec function for H.265/H.264/MPEG4/H.263 etc.
+
+config MXC_VPU_LEGACY_DEBUG
+ bool "MXC VPU LEGACY debugging"
+ depends on MXC_VPU_LEGACY != n
+ help
+ This is an option for the developers; most people should
+ say N here. This enables MXC VPU driver debugging.
+
+endmenu
diff --git a/drivers/mxc/vpu_legacy/Makefile b/drivers/mxc/vpu_legacy/Makefile
new file mode 100644
index 000000000000..844ca9b18763
--- /dev/null
+++ b/drivers/mxc/vpu_legacy/Makefile
@@ -0,0 +1,197 @@
+#
+# Makefile for VPU driver.
+#
+
+LEGACY_ROOT = $(srctree)/drivers/mxc/vpu_legacy/Malone_Firmware
+
+#---------------------------------------------------------------------------
+# Header Include Paths
+
+LEGACY_KERN_HEADER = \
+ -I$(LEGACY_ROOT)/DecKLib/KernelIF \
+ -I$(LEGACY_ROOT)/DecKLib/Control \
+ -I$(LEGACY_ROOT)/DecKLib/Incl
+
+SYS_HEADER = -I$(LEGACY_ROOT)/Incl \
+ -I$(LEGACY_ROOT)/PAL/Incl \
+ -I$(srctree)/drivers/mxc/vpu_legacy
+
+LEGACY_KERN_HEADER += $(SYS_HEADER)
+
+
+#---------------------------------------------------------------------------
+# Actual Source and Library control
+
+MAL_KERN_OBJECTS = \
+ Malone_Firmware/DecKLib/KernelIF/DecKernelLib.o \
+ Malone_Firmware/DecKLib/KernelIF/DecKernelLibPrivate.o \
+ Malone_Firmware/DecKLib/Control/DecKernelLibHWControl.o \
+ Malone_Firmware/DecKLib/Control/DecKernelLibHWIsr.o
+
+MAL_KERN_OBJECTS += Malone_Firmware/PAL/pal.o
+
+#---------------------------------------------------------------------------
+# Build flags
+
+DEFINES = -DDTV_GATHER_PERF_METRICS \
+ -DMVD_DTV_USERDATA \
+ -DMVD_WAIT_BOB_INACTIVE \
+ -DDECLIB_FORCE_HW_STOP \
+ -DMVD_NO_BSDMA_SAFETY_MARGIN \
+ -DMVD_CQ_ENABLE_REFILL \
+ -DMVD_SPP_HW_GOULOMB \
+ -DSVC_SFA_ADD_ERROR_CHECKING \
+ -DMVC_SFA_ADD_ERROR_CHECKING \
+ -DSVC_SPP_SAVE_CTX_PER_VCL_NAL \
+ -DMVD_CQ_CQSR \
+ -DAVC_SUPPORT_THRU_MVC \
+ -DMVC_ERROR_CONTROL_INSERT_SKIP_START_CONTROLS \
+ -DDECLIB_CTX_FLUSH_AFTER_SAVE \
+ -DDECLIB_SERVICE_EOS \
+ -DMVD_PERF_MEASURE \
+ -DVC1_ENABLED \
+ -DHEVC_ENABLED \
+ -DHEVC_CM_WORKAROUND \
+ -DHEVC_NEW_OUTPUT_TRIGGER \
+ -DHEVC_ALL_PICS_REF \
+ -DHEVC_SCAL_LIST_USE_YCRCB_XREF \
+ -DHEVC_SFA_ADD_ERROR_CHECKING \
+ -DMVD_DFE_DBG \
+ -DHEVC_JVT_MODEL=100 \
+ -DPAL_CLOCK_API \
+ -DSVC_ADDITIONAL_DEBUG \
+ -DDIAG_SUPPORT_ENABLED \
+ -DENABLE_PERF_TIMER \
+ -DFW_API_VERSION=19 \
+ -DGLOBAL_USE_RUN_TIME_CFG \
+ -DENABLE_TRACE_IN_RELEASE=0 \
+ -DYES=1 \
+ -DNO=0 \
+ -DNONE=0 \
+ -DNUP=1 \
+ -DUCOS=2 \
+ -DUCOS3=3 \
+ -DRTOS=0 \
+ -DUSE_DECODER \
+ -DARM=0 \
+ -DMIPS=1 \
+ -DX86=2 \
+ -DOR1K=3 \
+ -DCPU=0 \
+ -DNO_AL=0 \
+ -DCNXT_KAL=1 \
+ -DNXP_OSAL=2 \
+ -DOSAL=0 \
+ -DARM926=0 \
+ -DARMR5=1 \
+ -DARMA53=2 \
+ -DARM_CPU_TYPE=2 \
+ -DADS=0 \
+ -DRVDS=1 \
+ -DGNU_MIPS=2 \
+ -DGNU_MIPS_LNX=3 \
+ -DGNU_ARM=4 \
+ -DGNU_ARM_SOURCERY=5 \
+ -DGNU_X86=6 \
+ -DWIN_X86=7 \
+ -DDS5=8 \
+ -DGNU_OR32=9 \
+ -DGNU_ARM_LINARO=10 \
+ -DGNU_OR1K=11 \
+ -DTOOLSET=10 \
+ -DNO_DEBUG=0 \
+ -DBUILD_DEBUG=1 \
+ -DARRAY_DEBUG=2 \
+ -DFULL_DEBUG=3 \
+ -DDEBUG_CAPS=0 \
+ -DGENTB_PLATFORM=0 \
+ -DWIN_LIB=1 \
+ -DGEN_TB_ENC=2 \
+ -DTARGET_PLATFORM=0 \
+ -DVIDEO_TRANS=0 \
+ -DGTB_TRANS=1 \
+ -DGTB_DEC=2 \
+ -DWINDSOR_LIB=3 \
+ -DGTB_ENC=4 \
+ -DMEDIA_DEC=5 \
+ -DMEDIA_LIB=6 \
+ -DVPU_TEST_APP=7 \
+ -DTARGET_APP=7 \
+ -DPAL_CLOCK_API \
+ -DSVC_ADDITIONAL_DEBUG \
+ -DDIAG_SUPPORT_ENABLED \
+ -DENABLE_PERF_TIMER \
+ -DFW_API_VERSION=19 \
+ -DGLOBAL_USE_RUN_TIME_CFG \
+ -DDISABLE_TRACE \
+ -DENABLE_TRACE_IN_RELEASE=0 \
+ -DYES=1 \
+ -DNO=0 \
+ -DNONE=0 \
+ -DNUP=1 \
+ -DUCOS=2 \
+ -DUCOS3=3 \
+ -DRTOS=0 \
+ -DUSE_DECODER \
+ -DCHIP=0 \
+ -DEMULATION=1 \
+ -DHAPS=2 \
+ -DSIMULATION=3 \
+ -DCMODEL=4 \
+ -DTARGET_LEVEL=0 \
+ -DSVC_DISABLED=0 \
+ -DSVC_ENABLED=1 \
+ -DSVC_SUPPORT=0 \
+ -DMVC_DISABLED=0 \
+ -DMVC_ENABLED=1 \
+ -DMVC_SUPPORT=1 \
+ -DSFA_DISABLED=0 \
+ -DSFA_ENABLED=1 \
+ -DSFA_SUPPORT=1 \
+ -DCNXT_HW=0 \
+ -DNXP_HW=1 \
+ -DHWLIB=1 \
+ -DDTV=0 \
+ -DSTB=1 \
+ -DPLAYMODE=0 \
+ -DSTANDARD=0 \
+ -DREBOOT=1 \
+ -DBOOT_ARCH=0 \
+ -DTBPLAYER_FLOW_CHANGE_ON_REF_FRMS \
+ -DPULSAR_MERGE \
+ -DFSLCACHE_ENABLED \
+ -DDECLIB_ENABLE_DFE -DDECLIB_ENABLE_DBE \
+ -DDECLIB_ENABLE_DCP -DMVD_DCP_DYNAMIC_CONFIG \
+ -DDECLIB_4K_SUPPORTED -DHEVC_LEVEL_5PT0_SUPPORT \
+ -DPLAYER_LOCAL_THREAD \
+ -DDECLIB_ISR_IN_THREAD_CTX \
+ -DJPG_ENABLED \
+ -DJPGD_AUTO_DOWN_SCALE \
+ -DSPARK_ENABLED \
+ -DRV_ENABLED \
+ -DVP6_ENABLED \
+ -DVP8_ENABLED \
+ -DJPG_DPV_ENABLED \
+ -DMALONE_64BIT_ADDR \
+ -DDISABLE_TRACE
+
+LEGACY_KERN_DEFINEFLAGS = $(DEFINES)
+LEGACY_KERN_DEFINEFLAGS += -DVPU_KERNEL_BUILD
+
+EXTRA_CFLAGS += $(LEGACY_KERN_DEFINEFLAGS)
+EXTRA_CFLAGS += $(LEGACY_KERN_HEADER)
+
+ifeq ($(CONFIG_MXC_VPU_LEGACY_DEBUG),y)
+EXTRA_CFLAGS += -DDEBUG
+endif
+
+obj-$(CONFIG_MXC_VPU_LEGACY) = decoder.o
+
+decoder-objs = mxc_vpu-malone.o \
+ $(MAL_KERN_OBJECTS)
+
+cmd_files := $(foreach f,$(decoder-objs),$(dir $(f)).$(notdir $(f)).cmd)
+clean:
+ rm -rf $(decoder-objs) $(cmd_files) *.o .*.cmd modules.builtin modules.order
+
+
diff --git a/drivers/mxc/vpu_legacy/Malone_Firmware/DecKLib/Control/DecKernelLibHWControl.c b/drivers/mxc/vpu_legacy/Malone_Firmware/DecKLib/Control/DecKernelLibHWControl.c
new file mode 100755
index 000000000000..7861d545e577
--- /dev/null
+++ b/drivers/mxc/vpu_legacy/Malone_Firmware/DecKLib/Control/DecKernelLibHWControl.c
@@ -0,0 +1,326 @@
+/***************************************************
+ Copyright (c) 2015 Amphion Semiconductor Ltd
+ All rights reserved.
+ ***************************************************
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ ****************************************************
+
+ Author : Media IP FW team ( Belfast and Shanghai )
+ File name : DecLibHWControl.c
+ Notes : Processes commands from decoder lib scheduler
+ Establishes context for and makes calls to
+ the base decoders
+ This file provides the hardware facing aspect to
+ the interface. It is part of a group with
+ DecLibStreamControl.c which provides the
+ HW funtionality
+
+ ******************************************************/
+
+/////////////////////////////////////////////////////////////////////////////////
+// Header Files
+/////////////////////////////////////////////////////////////////////////////////
+
+#include "basetype.h"
+#include "mediaip_fw_types.h"
+#include "pal.h"
+
+#include "mvd_types.h"
+#include "mvd_reg_map.h"
+#include "mvd_sif_control.h"
+
+#include "DecKernelLibPrivate.h"
+#include "DecKernelLibHWControl.h"
+
+/////////////////////////////////////////////////////////////////////////////////
+// Extern Function Prototypes
+/////////////////////////////////////////////////////////////////////////////////
+
+extern MEDIAIP_IRQ_RETCODE mvd_kernel_hw_primary_isr ( u_int32 irq_val );
+extern MEDIAIP_IRQ_RETCODE mvd_kernel_hw_secondary_isr ( u_int32 irq_val );
+
+/////////////////////////////////////////////////////////////////////////////////
+// Private Function Prototypes
+/////////////////////////////////////////////////////////////////////////////////
+
+
+/////////////////////////////////////////////////////////////////////////////////
+// Global Variables
+/////////////////////////////////////////////////////////////////////////////////;
+
+extern DEC_KERNEL_LIB gDecKernelLib;
+ MALONE_KERNEL_HW_SESSION gMvdKernelHw[(DECODERLIB_MAX_MALONES + 1)];
+ pMALONE_KERNEL_HW_SESSION pgMVDKernelHw;
+
+u_int32 gMaloneList[(DECODERLIB_MAX_MALONES + 1)] = { MALONE_HW_1,
+#if DECODERLIB_MAX_MALONES > 1
+ MALONE_HW_2,
+#endif
+ MALONE_SW };
+
+static u_int32 uSWMaloneRegSpace[2048]; /* Until we are sure we have eliminated register access */
+ /* for functions using the 'SW Malone', point them here */
+
+extern u_int32 uDecLibIrqPin[DECODERLIB_MAX_MALONES][0x2];
+
+/////////////////////////////////////////////////////////////////////////////////
+// Code
+/////////////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////////////////
+// FUNCTION: mvd_kernel_hw_control_init //
+// //
+// DESCRIPTION: Perform all HW initialisation and shared structure setup //
+// //
+// INPUTS: uMaloneID - The ID of the Malone for which the info is to //
+// be restored //
+// pCtxArea - Pointer to area of memory from which data is to be //
+// read //
+// //
+// OUTPUTS: None. //
+// //
+// RETURNS: None. //
+// //
+// NOTES: None. //
+// //
+// CONTEXT: This function must be called from non-interrupt context //
+// //
+////////////////////////////////////////////////////////////////////////////////////
+
+void mvd_kernel_hw_control_init ( DECODERLIB_KERNEL_CFG * pCfg )
+{
+ /* Init the handles */
+ /* This sets up the reg pointers so do it first */
+ mvd_kernel_hw_init_handles ( pCfg,
+ TRUE );
+
+ /* Default global pointers to a 1st Malone focus */
+ mvd_kernel_hw_set_focus ( MALONE_HW_1, &pgMVDKernelHw );
+
+}
+
+
+////////////////////////////////////////////////////////////////////////////////////
+// FUNCTION: mvd_kernel_hw_set_malone_instance //
+// //
+// DESCRIPTION: Look for the most appropriate Malone instance to service //
+// the command for a specified stream //
+// //
+// INPUTS: uStrId - The Stream ID //
+// bSWCmd - is the command to be carried out for this stream //
+// capable of being handled without using the HW engine? //
+// uHWIndex - HW Index suggested by scheduler //
+// bUseSch - Set to guarantee scheduler suggested unit is used //
+// //
+// OUTPUTS: None. //
+// //
+// RETURNS: The most suitable Malone ID to be used //
+// //
+// NOTES: This function must return a value. //
+// //
+// CONTEXT: This function must be called from non-interrupt context //
+// //
+////////////////////////////////////////////////////////////////////////////////////
+
+u_int32 mvd_kernel_hw_set_malone_instance ( u_int32 uStrId,
+ bool bSWCmd,
+ u_int32 uHWIndex,
+ bool bUseSch
+ )
+{
+ u_int32 uIdx = 0;
+
+ if ( bUseSch )
+ {
+ return uHWIndex;
+ }
+
+ for ( uIdx = 0; uIdx < gDecKernelLib.uNumMalones; uIdx++ )
+ {
+ /* Even if there is no command active, this is a valid check as */
+ /* it avoids need for a context change if it matches */
+ if ( gMvdKernelHw[uIdx].uStrID == uStrId )
+ {
+ return uIdx;
+ }
+ }
+
+ if ( bSWCmd ) return MALONE_SW;
+
+ /* Look for free Malone - this function should not be called */
+ /* unless this is a SW command or there is a free Malone */
+
+ for ( uIdx = 0; uIdx < gDecKernelLib.uNumMalones; uIdx++ )
+ {
+ /* Even if there is no command active, this is a valid check as */
+ /* it avoids need for a context change if it matches */
+ if ( gMvdKernelHw[uIdx].eState == MALONE_INACTIVE )
+ {
+ break;
+ }
+ }
+
+ /* Do not assign this stream and do NOT make it active yet */
+ /* Only make this malone active when the command is issued */
+ /* This is necessary so we we can trigger context switches */
+
+ /* We should set the global pointer though so calls to sif */
+ /* etc can get correct functions!! */
+
+ mvd_kernel_hw_set_focus ( uIdx, &pgMVDKernelHw );
+
+ return uIdx;
+
+}
+
+////////////////////////////////////////////////////////////////////////////////////
+// FUNCTION: mvd_kernel_hw_set_focus //
+// //
+// DESCRIPTION: Changes focus to the selected Malone HW unit //
+// //
+// INPUTS: uMaloneID - The ID of the Malone //
+// //
+// OUTPUTS: ppMVDHw - Pointer to a HW session structure for the specified //
+// Malone //
+// //
+// RETURNS: None. //
+// //
+// NOTES: Only makes sense in multi-malone configs //
+// //
+// CONTEXT: This function may be called from any context //
+// //
+////////////////////////////////////////////////////////////////////////////////////
+
+void mvd_kernel_hw_set_focus ( u_int32 uMaloneID, pMALONE_KERNEL_HW_SESSION * ppMVDHw )
+{
+ *ppMVDHw = ( MALONE_KERNEL_HW_SESSION * )&gMvdKernelHw[uMaloneID];
+}
+
+
+
+////////////////////////////////////////////////////////////////////////////////////
+// FUNCTION: mvd_kernel_hw_init_handles //
+// //
+// DESCRIPTION: Initialise the HW session handles //
+// //
+// INPUTS: pCfg - A pointer to the DecLib Config structure //
+// bSoftInit - If set, the FW pointers get established - leave //
+// FALSE when restarting from a snapshot //
+// //
+// OUTPUTS: None. //
+// //
+// RETURNS: None. //
+// //
+// NOTES: None. //
+// //
+// CONTEXT: This function must be called from non-interrupt context //
+// //
+////////////////////////////////////////////////////////////////////////////////////
+
+void mvd_kernel_hw_init_handles ( DECODERLIB_KERNEL_CFG * pCfg,
+ bool bSoftInit
+ )
+{
+ u_int32 uIdx;
+ pMALONE_KERNEL_HW_SESSION pMVDHw;
+ MvdHwRegMap *pMvdReg;
+
+ for ( uIdx = 0; uIdx < (gDecKernelLib.uNumMalones + 1); uIdx++ )
+ {
+ /* If we have set up all the HW handles then move to the SW */
+ /* handle and set it up */
+ if ( uIdx == gDecKernelLib.uNumMalones ) uIdx = DECODERLIB_MAX_MALONES;
+
+ pMVDHw = &gMvdKernelHw[uIdx];
+
+ if ( bSoftInit )
+ {
+ pMVDHw->eState = MALONE_INACTIVE;
+ pMVDHw->uStrID = 0;
+ pMVDHw->uForceFIQ = 0;
+ pMVDHw->uForceDFEFIQ = 0;
+
+ /* Malone ID that the instance uses, normally fixed... */
+ pMVDHw->uMaloneID = gMaloneList[uIdx];
+ }
+
+ if ( pMVDHw->uMaloneID == DECODERLIB_MAX_MALONES )
+ {
+ pMvdReg = ( MvdHwRegMap * )uSWMaloneRegSpace;
+ }
+ else if ( pMVDHw->uMaloneID == MALONE_HW_2 )
+ {
+ pMvdReg = ( MvdHwRegMap * ) ( pCfg->uMaloneBaseAddr[0x1] + pCfg->uMaloneHifOffset[0x1] );
+ }
+ else
+ {
+ pMvdReg = ( MvdHwRegMap * ) ( pCfg->uMaloneBaseAddr[0x0] + pCfg->uMaloneHifOffset[0x0] );
+ }
+
+ if ( pMVDHw->uMaloneID == MALONE_SW )
+ {
+ pMVDHw->msd_regp = ( MvdHwRegMap * )pMvdReg;
+ pMVDHw->hif_regp = ( MvdHwRegHifMap * )pMvdReg;
+ pMVDHw->sif_regp = ( MvdHwRegSifMap * )pMvdReg;
+ pMVDHw->ctx_regp = ( MvdHwRegCtxMap * )pMvdReg;
+ pMVDHw->rsb_regp = ( MvdHwReg * )pMvdReg;
+ pMVDHw->rpr_regp = ( MvdHwRegRprMap * )pMvdReg;
+ pMVDHw->spp_regp = ( MvdHwRegSppMap * )pMvdReg;
+ pMVDHw->avc_regp = ( MvdHwRegH264Map * )pMvdReg;
+ pMVDHw->mp2d_regp = ( MvdHwRegMp2dMap * )pMvdReg;
+ pMVDHw->avsd_regp = ( MvdHwRegAvsdMap * )pMvdReg;
+ pMVDHw->aspd_regp = ( MvdHwRegAspdMap * )pMvdReg;
+ pMVDHw->vc1d_regp = ( MvdHwRegVc1dMap * )pMvdReg;
+ pMVDHw->jpgd_regp = ( MvdHwRegAspdMap * )pMvdReg;
+ pMVDHw->rvid_regp = ( MvdHwRegRvidMap * )pMvdReg;
+ pMVDHw->hevc_regp = ( MvdHwRegHevcMap * )pMvdReg;
+ pMVDHw->on2d_regp = ( MvdHwRegOn2dMap * )pMvdReg;
+ pMVDHw->cq_regp = ( MvdHwRegCqMap * )pMvdReg;
+ pMVDHw->rc4_regp = ( MvdHwRegRC4Map * )pMvdReg;
+ pMVDHw->dfe_regp = ( MvdHwRegDfeMap * )pMvdReg;
+ pMVDHw->dbe_regp[0x0] = ( MvdHwRegDbeMap * )pMvdReg;
+ pMVDHw->dbe_regp[0x1] = ( MvdHwRegDbeMap * )pMvdReg;
+
+ }
+ else
+ {
+ pMVDHw->msd_regp = pMvdReg;
+ pMVDHw->hif_regp = &( pMvdReg->HifMap.hif_map );
+ pMVDHw->sif_regp = &( pMvdReg->SifMap.sif_map );
+ pMVDHw->ctx_regp = &( pMvdReg->CtxMap.ctx_map );
+ pMVDHw->rpr_regp = &( pMvdReg->RprMap.rpr_map );
+ pMVDHw->spp_regp = &( pMvdReg->SppMap.spp_map );
+ pMVDHw->avc_regp = &( pMvdReg->DecMap.h264_map );
+ pMVDHw->mp2d_regp = &( pMvdReg->DecMap.mp2d_map );
+ pMVDHw->aspd_regp = &( pMvdReg->DecMap.aspd_map );
+ pMVDHw->avsd_regp = &( pMvdReg->DecMap.avsd_map );
+ pMVDHw->vc1d_regp = &( pMvdReg->DecMap.vc1d_map );
+ pMVDHw->jpgd_regp = &( pMvdReg->DecMap.aspd_map );
+ pMVDHw->on2d_regp = &( pMvdReg->DecMap.on2d_map );
+ pMVDHw->rvid_regp = &( pMvdReg->DecMap.rvid_map );
+ pMVDHw->hevc_regp = &( pMvdReg->DecMap.hevc_map );
+ pMVDHw->bbd_regp = &( pMvdReg->BbdMap.bbd_map );
+ pMVDHw->cq_regp = &( pMvdReg->CqMap.cq_map );
+ pMVDHw->rc4_regp = &( pMvdReg->RC4Map.RC4_map );
+ pMVDHw->dfe_regp = &( pMvdReg->DcpMap.dfe_map );
+ pMVDHw->dbe_regp[0x0] = &( pMvdReg->DcpMap.dbe_map[0x0] );
+ pMVDHw->dbe_regp[0x1] = &( pMvdReg->DcpMap.dbe_map[0x1] );
+
+ if ( pMVDHw->uMaloneID == MALONE_HW_2 )
+ {
+ pMVDHw->rsb_regp = ( MvdHwReg * ) pCfg->uMaloneBaseAddr[0x1] ;
+ }
+ else
+ {
+ pMVDHw->rsb_regp = ( MvdHwReg * ) pCfg->uMaloneBaseAddr[0x0] ;
+ }
+ }
+ }
+}
+
+/* End of File */
diff --git a/drivers/mxc/vpu_legacy/Malone_Firmware/DecKLib/Control/DecKernelLibHWControl.h b/drivers/mxc/vpu_legacy/Malone_Firmware/DecKLib/Control/DecKernelLibHWControl.h
new file mode 100755
index 000000000000..4ef9b0f0b08e
--- /dev/null
+++ b/drivers/mxc/vpu_legacy/Malone_Firmware/DecKLib/Control/DecKernelLibHWControl.h
@@ -0,0 +1,175 @@
+/***************************************************
+ Copyright (c) 2015 Amphion Semiconductor Ltd
+ All rights reserved.
+ ***************************************************
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ ****************************************************
+
+ Filename: DecLibHWControl.h
+ Description:
+
+ **************************************************/
+
+/////////////////////////////////////////////////////////////////////////////////
+// Header files
+/////////////////////////////////////////////////////////////////////////////////
+
+#ifndef _DECODER_LIB_HW_CONTROL_H_
+#define _DECODER_LIB_HW_CONTROL_H_
+
+#include "mvd_types.h"
+#include "mvd_reg_map.h"
+#include "DecKernelLib.h"
+
+/////////////////////////////////////////////////////////////////////////////////
+// Global Macros
+/////////////////////////////////////////////////////////////////////////////////
+
+#define MALONE_HW_1 0 /* Identifiers for the Malone units */
+#define MALONE_HW_2 1
+#define MALONE_SW DECODERLIB_MAX_MALONES /* Sw Malone does not exist! Simply a */
+ /* control structure for carrying out */
+ /* commands which do not need a HW unit */
+#define MALONE_SW_IRQ 0xdeaf
+
+#define DECODERLIB_ISR_QU_SIZE ( DECODERLIB_MAX_MALONES * 4 )
+#define DECODERLIB_SECONDARY_ISR_EVENT 0x80000000
+#define DECODERLIB_EVENT_MASK 0x7FFFFFFF
+
+#define DECODERLIB_FORCEIRQ_BIT_SET( uVal ) (( uVal & 0x1 ) << 30 )
+#define DECODERLIB_FORCEIRQ_BIT_GET( uVal ) (( uVal >> 30 ) & 0x1 )
+#define DECODERLIB_FORCEDFEIRQ_BIT_SET( uVal ) (( uVal & 0x1 ) << 29 )
+#define DECODERLIB_FORCEDFEIRQ_BIT_GET( uVal ) (( uVal >> 29 ) & 0x1 )
+
+/////////////////////////////////////////////////////////////////////////////////
+// Global Types
+/////////////////////////////////////////////////////////////////////////////////
+
+//////////////////////////////////////////////////////////////
+// Decoder Library HW State
+
+typedef enum
+{
+ MALONE_INACTIVE = 0,
+ MALONE_ACTIVE,
+ MALONE_BE_ACTIVE
+
+} MALONE_STATE;
+
+//////////////////////////////////////////////////////////////
+// Decoder Library HW Control Context Info
+
+typedef struct
+{
+
+ MALONE_STATE eState;
+ u_int32 uStrID;
+
+ u_int32 uForceFIQ;
+ u_int32 uForceDFEFIQ;
+ u_int32 uChipVer; /* Hold "malone" version to be filled in from Malone HW register */
+ u_int32 uChipMnrVer; /* Hold "malone" minor version to be filled in from Malone HW register */
+ u_int32 uChipSubVer; /* Hold metal version to be filled in by higher level control */
+ u_int32 uHWFeatures;
+ u_int32 uForceCacheFlush; /* Cache reset issue workaround purpose for Kronos and Fusion RevA */
+ u_int32 bPreparser; /* Set TRUE to indicate a preparser is in place */
+ u_int32 bCQ; /* Set TRUE to indicate a command queue is in place */
+ u_int32 bDCP; /* Set TRUE to indicate unit can operate in decoupled mode */
+ u_int32 uNumDBEs; /* Indicates the number of decoupled back ends available */
+ u_int32 bFBC; /* Set TRUE to indicate Frame buffer Compression support */
+ u_int32 uRSBSize;
+ u_int32 uMaloneID;
+ u_int32 bPixIf;
+ u_int32 bXBUS;
+
+ u_int32 uCQProcType[DECODERLIB_MAX_CQ_PER_MALONE]; /* Specifies what type of processing each of the CQ units is doing */
+
+ MALONE_STATE eDFEState; /* If the front end of the HW is active in isolation - specifies state */
+ u_int8 usDFEStrID; /* If the front end of the HW is active in isolation - specifies */
+ /* which stream is assigned */
+
+ u_int32 uDmaMemSize;
+ void * pDmaMemArea;
+
+ MvdHwRegMap * msd_regp;
+ MvdHwRegHifMap * hif_regp;
+ MvdHwRegSifMap * sif_regp;
+ MvdHwRegCtxMap * ctx_regp;
+ MvdHwReg * rsb_regp;
+ MvdHwRegRprMap * rpr_regp;
+ MvdHwRegSppMap * spp_regp;
+ MvdHwRegH264Map * avc_regp;
+ MvdHwRegMp2dMap * mp2d_regp;
+ MvdHwRegAvsdMap * avsd_regp;
+ MvdHwRegAspdMap * aspd_regp;
+ MvdHwRegVc1dMap * vc1d_regp;
+ MvdHwRegAspdMap * jpgd_regp;
+ MvdHwRegOn2dMap * on2d_regp;
+ MvdHwRegRvidMap * rvid_regp;
+ MvdHwRegHevcMap * hevc_regp;
+ MvdHwRegBbdMap * bbd_regp;
+ MvdHwRegDbgMap * dbg_regp;
+ MvdHwRegCqMap * cq_regp;
+ MvdHwRegRC4Map * rc4_regp;
+ MvdHwRegDfeMap * dfe_regp;
+ MvdHwRegDbeMap * dbe_regp[DECODERLIB_MAX_DBE_UNITS];
+
+} MALONE_KERNEL_HW_SESSION, *pMALONE_KERNEL_HW_SESSION;
+
+/////////////////////////////////////////////////////////////////////////////////
+// Global Function definitions
+/////////////////////////////////////////////////////////////////////////////////
+
+
+void mvd_kernel_hw_control_init ( DECODERLIB_KERNEL_CFG * pCfg );
+
+////////////////////////////////////////////////////////////////////////////////////
+// FUNCTION: mvd_kernel_hw_set_focus //
+// //
+// DESCRIPTION: Changes focus to the selected Malone HW unit //
+// //
+// INPUTS: uMaloneID - The ID of the Malone //
+// //
+// OUTPUTS: ppMVDHw - Pointer to a HW session structure for the specified //
+// Malone //
+// //
+// RETURNS: None. //
+// //
+// NOTES: Only makes sense in multi-malone configs //
+// //
+// CONTEXT: This function may be called from any context //
+// //
+////////////////////////////////////////////////////////////////////////////////////
+
+void mvd_kernel_hw_set_focus ( u_int32 uMaloneID, pMALONE_KERNEL_HW_SESSION * ppMVDHw );
+
+////////////////////////////////////////////////////////////////////////////////////
+// FUNCTION: mvd_kernel_hw_init_handles //
+// //
+// DESCRIPTION: Initialise the HW session handles //
+// //
+// INPUTS: pCfg - A pointer to the DecLib Config structure //
+// bSoftInit - If set, the FW pointers get established - leave //
+// FALSE when restarting from a snapshot //
+// //
+// OUTPUTS: None. //
+// //
+// RETURNS: None. //
+// //
+// NOTES: None. //
+// //
+// CONTEXT: This function must be called from non-interrupt context //
+// //
+////////////////////////////////////////////////////////////////////////////////////
+
+void mvd_kernel_hw_init_handles ( DECODERLIB_KERNEL_CFG * pCfg,
+ bool bSoftInit );
+
+#endif /* _DECODER_LIB_HW_CONTROL_H_ */
+
+/* End of file */
diff --git a/drivers/mxc/vpu_legacy/Malone_Firmware/DecKLib/Control/DecKernelLibHWIsr.c b/drivers/mxc/vpu_legacy/Malone_Firmware/DecKLib/Control/DecKernelLibHWIsr.c
new file mode 100755
index 000000000000..68b33384c769
--- /dev/null
+++ b/drivers/mxc/vpu_legacy/Malone_Firmware/DecKLib/Control/DecKernelLibHWIsr.c
@@ -0,0 +1,514 @@
+/***************************************************
+ Copyright (c) 2015 Amphion Semiconductor Ltd
+ All rights reserved.
+ ***************************************************
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ ****************************************************
+
+ File name : DecLibHWIsr.c
+ Notes : Provides the HW Interrupt Service Routines
+
+ *******************************************************/
+
+/////////////////////////////////////////////////////////////////////////////////
+// Header Files
+/////////////////////////////////////////////////////////////////////////////////
+
+#include "basetype.h"
+#include "mediaip_fw_types.h"
+#include "pal.h"
+
+#include "mvd.h"
+#include "mvd_types.h"
+#include "mvd_reg_map.h"
+#include "mvd_sif_control.h"
+
+#include "DecKernelLibHWControl.h"
+#include "DecKernelLibPrivate.h"
+
+/////////////////////////////////////////////////////////////////////////////////
+// Global Variables
+/////////////////////////////////////////////////////////////////////////////////
+
+extern pMALONE_KERNEL_HW_SESSION pgMVDKernelHw;
+extern u_int32 uMvdKernelIrqPin[DECODERLIB_MAX_MALONES][0x2];
+extern DEC_KERNEL_LIB gDecKernelLib;
+
+/////////////////////////////////////////////////////////////////////////////////
+// Global Macros
+/////////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////////
+// Private Prototypes
+/////////////////////////////////////////////////////////////////////////////////
+
+void mvd_kernel_hw_isr_event ( u_int32 uMaloneIdx,
+ u_int32 * puIrqStatus );
+
+/////////////////////////////////////////////////////////////////////////////////
+// Extern Prototypes
+/////////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////////
+// Code
+/////////////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////////////////
+// FUNCTION: mvd_hw_sesh_isr //
+// //
+// DESCRIPTION: Malone HW ISR //
+// //
+// INPUTS: irq_val - Identification Parameter from which source of call //
+// may be ascertained //
+// //
+// OUTPUTS: None. //
+// //
+// RETURNS: MEDIAIP_IRQ_RETCODE //
+// //
+// NOTES: None. //
+// //
+// CONTEXT: This function may be called from any context //
+// Since it is an isr, that may be strange but it can be called to //
+// handle SW commands in thread context only //
+// //
+////////////////////////////////////////////////////////////////////////////////////
+
+#define CTX_DBG(x)
+
+MEDIAIP_IRQ_RETCODE mvd_kernel_hw_primary_isr ( u_int32 irq_val )
+{
+ u_int32 sif_irq_status[0x3] = { 0x0 };
+ u_int32 uActMaloneID;
+#if ( TARGET_APP == GTB_DEC ) || ( TARGET_APP == MEDIA_DEC ) || ( TARGET_APP == VIDEO_TRANS ) || ( TARGET_APP == GTB_TRANS )
+ u_int32 uIrqTarget0, uIrqTarget1;
+#endif
+ u_int32 uForceFIQ = 0, uForceDFEFIQ = 0;
+ u_int32 uHEVCActive;
+
+ /* Future Proof... */
+ /* If we have two levels of interrupt or we process interrupts in thread context */
+ /* we need to save and restore HW focus */
+ pMALONE_KERNEL_HW_SESSION pLocMVDHw = pgMVDKernelHw;
+
+ /* Work out which Malone instance caused this isr and set HW focus accordingly */
+
+#if ( TARGET_APP == GTB_DEC ) || ( TARGET_APP == MEDIA_DEC ) || ( TARGET_APP == VIDEO_TRANS ) || ( TARGET_APP == GTB_TRANS )
+
+ pal_int_get_irq_line ( uMvdKernelIrqPin[0x0][0x0],
+ &uIrqTarget0
+ );
+ pal_int_get_irq_line ( uMvdKernelIrqPin[0x0][0x1],
+ &uIrqTarget1
+ );
+
+ uActMaloneID = ( irq_val == MALONE_SW_IRQ ) ? MALONE_SW :
+ (( irq_val == uIrqTarget0 ) | ( irq_val == uIrqTarget1 )) ? MALONE_HW_1 :
+ MALONE_HW_2;
+
+#else
+
+ uActMaloneID = ( irq_val == MALONE_SW_IRQ ) ? MALONE_SW :
+ (( irq_val == uMvdKernelIrqPin[0x0][0x0] ) | ( irq_val == uMvdKernelIrqPin[0x0][0x1] )) ? MALONE_HW_1 :
+ MALONE_HW_2;
+
+#endif
+
+ mvd_kernel_hw_set_focus ( uActMaloneID, &pgMVDKernelHw );
+
+ /* work out if HEVC active, as if not we don't care about irq_status3 DBE*/
+ MVD_REG_READ( pgMVDKernelHw, DECLIB_DBG_REG_CTX, pgMVDKernelHw->ctx_regp->ctx_status, uHEVCActive );
+
+ if(uHEVCActive&0x400)
+ uHEVCActive = 1;
+ else
+ uHEVCActive = 0;
+
+
+
+#if 1
+ MVD_REG_READ( pgMVDKernelHw, DECLIB_DBG_REG_SIF, pgMVDKernelHw->sif_regp->msd_data0_reg, uForceFIQ );
+ MVD_REG_READ( pgMVDKernelHw, DECLIB_DBG_REG_SIF, pgMVDKernelHw->sif_regp->msd_data1_reg, uForceDFEFIQ );
+
+ if ( uForceFIQ )
+ {
+ MVD_REG_WRITE( pgMVDKernelHw, DECLIB_DBG_REG_SIF, pgMVDKernelHw->sif_regp->msd_data0_reg, 0 );
+ }
+
+ if ( uForceDFEFIQ )
+ {
+ MVD_REG_WRITE( pgMVDKernelHw, DECLIB_DBG_REG_SIF, pgMVDKernelHw->sif_regp->msd_data1_reg, 0 );
+ }
+#else
+ MVD_REG_READ( pgMVDKernelHw, DECLIB_DBG_REG_SIF, pgMVDKernelHw->sif_regp->msd_data0_reg, uData );
+
+ MVD_REG_WRITE( pgMVDKernelHw, DECLIB_DBG_REG_SIF, pgMVDKernelHw->sif_regp->msd_data0_reg, 0 );
+
+ uForceFIQ = ( uData & 0x1 ) ? 1 : 0;
+ uForceDFEFIQ = ( uData & 0x2 ) ? 1 : 0;
+#endif
+
+ if ( uActMaloneID != MALONE_SW )
+ {
+ u_int32 uClearVal;
+
+ /* Break down sif IRQ sources */
+ MVD_REG_READ( pgMVDKernelHw, DECLIB_DBG_REG_SIF, pgMVDKernelHw->sif_regp->intr_status, sif_irq_status[0x0] );
+ MVD_REG_READ( pgMVDKernelHw, DECLIB_DBG_REG_SIF, pgMVDKernelHw->sif_regp->intr2_status, sif_irq_status[0x1] );
+ MVD_REG_READ( pgMVDKernelHw, DECLIB_DBG_REG_SIF, pgMVDKernelHw->sif_regp->intr3_status, sif_irq_status[0x2] );
+
+ pal_trace( DECODER_TL_INFO, "mvd_kernel_hw_primary_isr(%d): opening sif_irq_status = 0x%x\n", irq_val, sif_irq_status[0x0]);
+ pal_trace( DECODER_TL_INFO, "mvd_kernel_hw_primary_isr(%d): opening sif_irq_status[0x1] = 0x%x\n", irq_val, sif_irq_status[0x1]);
+ pal_trace( DECODER_TL_INFO, "mvd_kernel_hw_primary_isr(%d): opening sif_irq_status[0x2] = 0x%x\n", irq_val, sif_irq_status[0x2]);
+
+ /* Clear the interrupt bits we're going to handle here */
+
+#ifdef FW_PES_PARSE_AS_FIQ
+
+ uClearVal = sif_irq_status[0x0] & ( MSD_SIF_INTR_BSDMA_BIT |
+ MSD_SIF_INTR_FORCE_EXIT_BIT |
+ MSD_SIF_INTR_DISPQ_PULL_BIT |
+ MSD_SIF_INTR_SEMAPHORE_BIT |
+ MSD_SIF_INTR_IMAGE_DONE_BIT |
+ MSD_SIF_INTR_SLICE_DONE_BIT |
+ MSD_SIF_INTR_FORCE_ENTRY_BIT
+ );
+
+ MVD_REG_WRITE( pgMVDKernelHw, DECLIB_DBG_REG_SIF, pgMVDKernelHw->sif_regp->intr_status, uClearVal );
+
+#else
+
+ uClearVal = sif_irq_status[0x0] & ( MSD_SIF_INTR_BSDMA_BIT |
+ MSD_SIF_INTR_PES_BIT |
+ MSD_SIF_INTR_SCODE_FOUND_BIT |
+ MSD_SIF_INTR_DISPQ_PULL_BIT |
+ MSD_SIF_INTR_SEMAPHORE_BIT |
+ MSD_SIF_INTR_IMAGE_DONE_BIT |
+ MSD_SIF_INTR_SLICE_DONE_BIT |
+ MSD_SIF_INTR_FORCE_ENTRY_BIT
+ );
+
+ MVD_REG_WRITE( pgMVDKernelHw, DECLIB_DBG_REG_SIF, pgMVDKernelHw->sif_regp->intr_status, uClearVal );
+
+#endif /* FW_PES_PARSE_AS_FIQ */
+
+ /* Read it back to ensure write has made it to Malone */
+ MVD_REG_READ( pgMVDKernelHw, DECLIB_DBG_REG_SIF, pgMVDKernelHw->sif_regp->intr_status, uClearVal );
+
+ /* Also re-clear the INTC bit which brought us in here since */
+ /* it will have been reset. */
+ pal_int_clear ( irq_val,
+ TRUE
+ );
+
+#ifdef FW_PARSE_PES
+#ifdef FW_PES_PARSE_AS_FIQ
+
+ /* Pes FW handling done at higher level */
+ /* Re-maps the force-exit ISR as the startcode */
+
+ /* TODO-KMC */
+ /* Does this mean a normal engine startcode is mapped as a force-exit? I guess it does */
+ /* So if we were parsing PES as an FIQ we would not actually be in this function if it */
+ /* were a PES startcode and so the below event must be a normal startcode? */
+
+ if ( sif_irq_status[0x0] & MSD_SIF_INTR_FORCE_EXIT_BIT )
+ {
+ sif_irq_status[0x0] |= MSD_SIF_INTR_SCODE_FOUND_BIT;
+ }
+#else
+ /* PES isr */
+ if ( sif_irq_status[0x0] & MSD_SIF_INTR_SCODE_FOUND_BIT )
+ {
+ u_int32 scode_status;
+
+ MVD_REG_READ( pgMVDKernelHw, DECLIB_DBG_REG_SIF, pgMVDKernelHw->sif_regp->bs2rbsp_status, scode_status );
+
+ if ( scode_status & MSD_SIF_BS2RBSP_GOT_PESSCODE )
+ {
+ sesh_pes_isr ( irq_val );
+ }
+
+ /* If it was just a PES startcode, then don't tell the engine */
+ /* that there was a startcode, as will get handled later */
+ if (( scode_status & MSD_SIF_BS2RBSP_GOT_SCODE ) == 0 )
+ {
+ sif_irq_status[0x0] &= ~(MSD_SIF_INTR_SCODE_FOUND_BIT);
+ }
+ }
+#endif
+#endif
+
+ if ( sif_irq_status[0x1] & ( MSD_SIF_INTR2_CSC_BIT ) )
+ {
+ MVD_REG_WRITE( pgMVDKernelHw, 0x0 /*DECLIB_DBG_REG_SIF*/, pgMVDKernelHw->sif_regp->intr2_status, sif_irq_status[0x1] & ( MSD_SIF_INTR2_CSC_BIT ) );
+ }
+
+ if ( sif_irq_status[0x1] & ( MSD_SIF_INTR2_CQ_BIT ) )
+ {
+ MVD_REG_WRITE( pgMVDKernelHw, 0x0 /*DECLIB_DBG_REG_SIF*/, pgMVDKernelHw->sif_regp->intr2_status, sif_irq_status[0x1] & ( MSD_SIF_INTR2_CQ_BIT ) );
+ }
+
+ if ( sif_irq_status[0x1] & ( MSD_SIF_INTR2_DFE_DONE_BIT ) )
+ {
+ MVD_REG_WRITE( pgMVDKernelHw, 0x0 /*DECLIB_DBG_REG_SIF*/, pgMVDKernelHw->sif_regp->intr2_status, sif_irq_status[0x1] & ( MSD_SIF_INTR2_DFE_DONE_BIT ) );
+ MVD_REG_WRITE( pgMVDKernelHw, 0x0 /*DECLIB_DBG_REG_SIF*/, pgMVDKernelHw->sif_regp->intr2_status, sif_irq_status[0x1] & ( MSD_SIF_INTR2_DFE_SLC_DONE_BIT ) );
+ }
+
+ if ( sif_irq_status[0x1] & MSD_SIF_INTR2_DFE_SLC_DONE_BIT )
+ {
+ MVD_REG_WRITE( pgMVDKernelHw, 0x0 /*DECLIB_DBG_REG_SIF*/, pgMVDKernelHw->sif_regp->intr2_status, sif_irq_status[0x1] & ( MSD_SIF_INTR2_DFE_SLC_DONE_BIT ) );
+ }
+
+ if ( sif_irq_status[0x2] & MSD_SIF_INTR3_DBE0_CQ_BIT )
+ {
+ MVD_REG_WRITE( pgMVDKernelHw, 0x0 /*DECLIB_DBG_REG_SIF*/, pgMVDKernelHw->sif_regp->intr3_status, sif_irq_status[0x2] & ( MSD_SIF_INTR3_DBE0_CQ_BIT ) );
+ }
+
+ if ( sif_irq_status[0x2] & MSD_SIF_INTR3_DBE1_CQ_BIT )
+ {
+ MVD_REG_WRITE( pgMVDKernelHw, 0x0 /*DECLIB_DBG_REG_SIF*/, pgMVDKernelHw->sif_regp->intr3_status, sif_irq_status[0x2] & ( MSD_SIF_INTR3_DBE1_CQ_BIT ) );
+ }
+
+ if ( sif_irq_status[0x2] &
+ ( MSD_SIF_INTR3_DBE0_DONE_BIT | MSD_SIF_INTR3_DBE1_DONE_BIT )
+ )
+ {
+ u_int32 uMask = ( MSD_SIF_INTR3_DBE0_DONE_BIT |
+ MSD_SIF_INTR3_DBE1_DONE_BIT );
+
+ if (( sif_irq_status[0x0] & MSD_SIF_INTR_IMAGE_DONE_BIT )||(uHEVCActive==0))
+ {
+ MVD_REG_WRITE( pgMVDKernelHw, 0x0 /*DECLIB_DBG_REG_SIF*/, pgMVDKernelHw->sif_regp->intr3_status, sif_irq_status[0x2] & uMask );
+ }
+ else
+ {
+ sif_irq_status[0x2] &= ~uMask;
+ }
+ }
+
+ if ( sif_irq_status[0x2] &
+ ( MSD_SIF_INTR3_DBE0_SLC_DONE_BIT | MSD_SIF_INTR3_DBE1_SLC_DONE_BIT )
+ )
+ {
+ u_int32 uMask = ( MSD_SIF_INTR3_DBE0_SLC_DONE_BIT |
+ MSD_SIF_INTR3_DBE1_SLC_DONE_BIT );
+
+ if (( sif_irq_status[0x0] & MSD_SIF_INTR_SLICE_DONE_BIT )|| (uHEVCActive==0))
+ {
+ MVD_REG_WRITE( pgMVDKernelHw, 0x0 /*DECLIB_DBG_REG_SIF*/, pgMVDKernelHw->sif_regp->intr3_status, sif_irq_status[0x2] & uMask );
+ }
+ else
+ {
+ sif_irq_status[0x2] &= ~uMask;
+ }
+ }
+ }
+ else /* We wish to process a command without accessing HW */
+ {
+ sif_irq_status[0x0] = 0;
+ }
+
+ pal_trace( DECODER_TL_DEBUG, "-> mvd_kernel_hw_primary_isr( ) : uForceFIQ = 0x%x\n", uForceFIQ );
+
+ /* Decode engine IRQs */
+ if (( uActMaloneID == MALONE_SW ) ||
+ ( uForceFIQ ) ||
+ ( uForceDFEFIQ ) ||
+ ( sif_irq_status[0x0] & ( MSD_SIF_INTR_IMAGE_DONE_BIT | MSD_SIF_INTR_SLICE_DONE_BIT | MSD_SIF_INTR_SCODE_FOUND_BIT | MSD_SIF_INTR_FORCE_ENTRY_BIT | MSD_SIF_INTR_BSDMA_BIT )) ||
+ ( sif_irq_status[0x1] & ( MSD_SIF_INTR2_CSC_BIT | MSD_SIF_INTR2_DFE_DONE_BIT | MSD_SIF_INTR2_DFE_SLC_DONE_BIT | MSD_SIF_INTR2_CQ_BIT )) ||
+ ( sif_irq_status[0x2] & ( MSD_SIF_INTR3_DBE0_DONE_BIT | MSD_SIF_INTR3_DBE1_DONE_BIT | MSD_SIF_INTR3_DBE0_SLC_DONE_BIT | MSD_SIF_INTR3_DBE1_SLC_DONE_BIT | MSD_SIF_INTR3_DBE0_CQ_BIT | MSD_SIF_INTR3_DBE1_CQ_BIT ))
+ )
+ {
+ pal_trace ( DECODER_TL_DEBUG,
+ "-> mvd_kernel_hw_primary_isr( ) : sif_irq_status[0x0] = 0x%x : sif_irq_status[0x1] = 0x%x : sif_irq_status[0x2] = 0x%x : uForceFIQ = 0x%x\n",
+ sif_irq_status[0x0],
+ sif_irq_status[0x1],
+ sif_irq_status[0x2],
+ uForceFIQ
+ );
+
+ /* Only pass events not serviced inline in this isr */
+
+ sif_irq_status[0x0] &= ( MSD_SIF_INTR_IMAGE_DONE_BIT | MSD_SIF_INTR_SLICE_DONE_BIT | MSD_SIF_INTR_SCODE_FOUND_BIT | MSD_SIF_INTR_FORCE_ENTRY_BIT | MSD_SIF_INTR_BSDMA_BIT );
+ sif_irq_status[0x1] &= ( MSD_SIF_INTR2_CSC_BIT | MSD_SIF_INTR2_DFE_DONE_BIT | MSD_SIF_INTR2_DFE_SLC_DONE_BIT | MSD_SIF_INTR2_CQ_BIT);
+ sif_irq_status[0x2] &= ( MSD_SIF_INTR3_DBE0_DONE_BIT | MSD_SIF_INTR3_DBE1_DONE_BIT | MSD_SIF_INTR3_DBE0_SLC_DONE_BIT | MSD_SIF_INTR3_DBE1_SLC_DONE_BIT | MSD_SIF_INTR3_DBE0_CQ_BIT | MSD_SIF_INTR3_DBE1_CQ_BIT );
+
+ /* When passing to thread - explicitly set that a force irq has been set */
+ /* so that the thread function knows after which interrupt it can reset */
+ /* pMVDHw->uForceFIQ */
+
+ sif_irq_status[0x0] |= DECODERLIB_FORCEIRQ_BIT_SET( uForceFIQ );
+ sif_irq_status[0x0] |= DECODERLIB_FORCEDFEIRQ_BIT_SET( uForceDFEFIQ );
+
+ if (( sif_irq_status[0x0] ) ||
+ ( sif_irq_status[0x1] ) ||
+ ( sif_irq_status[0x2] )
+ )
+ {
+ mvd_kernel_hw_isr_event ( uActMaloneID,
+ sif_irq_status );
+ }
+ }
+
+ /* Future Proof - Restore pgMVDKernelHw */
+ pgMVDKernelHw = pLocMVDHw;
+
+ return MEDIAIP_FW_STATUS_OK;
+
+}
+
+////////////////////////////////////////////////////////////////////////////////////
+// FUNCTION: mvd_kernel_hw_secondary_isr //
+// //
+// DESCRIPTION: Malone HW ISR 2 //
+// //
+// INPUTS: irq_val - Identification Parameter from which source of call //
+// may be ascertained //
+// //
+// OUTPUTS: None. //
+// //
+// RETURNS: MEDIAIP_IRQ_RETCODE //
+// //
+// NOTES: None. //
+// //
+// CONTEXT: This function may be called from any context //
+// Since it is an isr, that may be strange but it can be called to //
+// handle SW commands in thread context only //
+// //
+////////////////////////////////////////////////////////////////////////////////////
+
+MEDIAIP_IRQ_RETCODE mvd_kernel_hw_secondary_isr ( u_int32 irq_val )
+{
+ u_int32 uActMaloneID;
+ u_int32 uTemp;
+ u_int32 sif_irq_status[0x3] = { 0x0 };
+#if ( TARGET_APP == GTB_DEC ) || ( TARGET_APP == MEDIA_DEC ) || ( TARGET_APP == VIDEO_TRANS ) || ( TARGET_APP == GTB_TRANS )
+ u_int32 uIrqTarget0, uIrqTarget1;
+#endif
+
+ /* Future Proof... */
+ /* If we have two levels of interrupt we need to save and restore HW focus */
+ pMALONE_KERNEL_HW_SESSION pLocMVDHw = pgMVDKernelHw;
+
+ /* Work out which Malone instance cause this isr and set HW focus accordingly */
+
+#if ( TARGET_APP == GTB_DEC ) || ( TARGET_APP == MEDIA_DEC ) || ( TARGET_APP == VIDEO_TRANS ) || ( TARGET_APP == GTB_TRANS )
+
+ pal_int_get_irq_line ( uMvdKernelIrqPin[0x0][0x0],
+ &uIrqTarget0
+ );
+ pal_int_get_irq_line ( uMvdKernelIrqPin[0x0][0x1],
+ &uIrqTarget1
+ );
+
+ uActMaloneID = ( irq_val == MALONE_SW_IRQ ) ? MALONE_SW :
+ (( irq_val == uIrqTarget0 ) | ( irq_val == uIrqTarget1 )) ? MALONE_HW_1 :
+ MALONE_HW_2;
+
+#else
+
+ uActMaloneID = ( irq_val == MALONE_SW_IRQ ) ? MALONE_SW :
+ (( irq_val == uMvdKernelIrqPin[0x0][0x0] ) | ( irq_val == uMvdKernelIrqPin[0x0][0x1] )) ? MALONE_HW_1 :
+ MALONE_HW_2;
+
+#endif
+
+ mvd_kernel_hw_set_focus ( uActMaloneID, &pgMVDKernelHw );
+
+ if ( uActMaloneID != MALONE_SW )
+ {
+ /* Break down sif IRQ sources */
+ APB_REG_READ( pgMVDKernelHw->sif_regp->intr_status, sif_irq_status[0x0] );
+
+ /* Clear those we will handle here */
+ MVD_REG_WRITE( pgMVDKernelHw, 0x0 /*DECLIB_DBG_REG_SIF*/, pgMVDKernelHw->sif_regp->intr_status, sif_irq_status[0x0] & MSD_SIF_INTR2_EXTENSION_BIT_2 );
+
+ /* Read it back to ensure write has made it to Malone */
+ /* Using uActMaloneID as read dsetination as it is no longer */
+ /* required */
+ APB_REG_READ( pgMVDKernelHw->sif_regp->intr_status, uTemp );
+
+ /* Also re-clear the INTC bit which brought us in here since */
+ /* it will have been reset. */
+ pal_int_clear ( irq_val,
+ TRUE );
+
+ if ( sif_irq_status[0x0] & MSD_SIF_INTR2_EXTENSION_BIT_2 )
+ {
+ /* Break down extension IRQ sources */
+ APB_REG_READ( pgMVDKernelHw->sif_regp->intr2_status, sif_irq_status[0x1]);
+
+ /* Clear those we will handle here */
+ MVD_REG_WRITE( pgMVDKernelHw, DECLIB_DBG_REG_SIF, pgMVDKernelHw->sif_regp->intr2_status, sif_irq_status[0x1] & ( MSD_SIF_CTRL2_SPP_SCODE_INTR_ENAB_BIT |
+ MSD_SIF_CTRL2_SPP_PESSC_INTR_ENAB_BIT |
+ MSD_SIF_CTRL2_SPP_BSDMA_INTR_ENAB_BIT ));
+
+ /* Bugzilla 237 - PES Interupt enable inadvertantly set through a RMW of sif_regp->control */
+ if ( sif_irq_status[0x1] & MSD_SIF_CTRL2_SPP_PESSC_INTR_ENAB_BIT )
+ {
+ u_int32 pes_status;
+
+ APB_REG_READ ( pgMVDKernelHw->spp_regp->pes_status, pes_status );
+
+ if ( MSD_SIF_PES_STATUS_GET_STATE( pes_status ) == pes_WaitClear )
+ {
+ /* Pending DTS/PTS looks like it is locked out reception of another startcode */
+ MVD_REG_WRITE( pgMVDKernelHw, 0x0 /*DECLIB_DBG_REG_SPP*/, pgMVDKernelHw->spp_regp->pes_ctrl, 0x0 );
+ }
+ }
+
+ sif_irq_status[0x0] |= DECODERLIB_SECONDARY_ISR_EVENT;
+
+ mvd_kernel_hw_isr_event ( uActMaloneID,
+ sif_irq_status );
+
+ }
+
+ /* What other interrupts might we wish to handle in a seperate context? */
+ /* Only PES is known so far */
+
+ }
+
+ /* Future Proof - Restore pgMVDKernelHw */
+ pgMVDKernelHw = pLocMVDHw;
+
+ return MEDIAIP_FW_STATUS_OK;
+
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// FUNCTION: internal_decoder_kernel_lib_isr_event //
+// //
+// DESCRIPTION: Callback function for base decoder to schedule the //
+// processing of the isr in thread context //
+// //
+// INPUTS: None //
+// //
+// OUTPUTS: None //
+// //
+// RETURNS: None //
+// //
+// NOTES: Will be called in ISR or thread context by base decoders //
+// //
+////////////////////////////////////////////////////////////////////////////////
+
+void mvd_kernel_hw_isr_event ( u_int32 uMaloneIdx,
+ u_int32 * puIrqStatus )
+{
+ DECODER_KERNEL_LIB_ISR_EVENT_DATA sData;
+
+ sData.uMalIdx = uMaloneIdx;
+ sData.uIrqStatus[0x0] = puIrqStatus[0x0];
+ sData.uIrqStatus[0x1] = puIrqStatus[0x1];
+ sData.uIrqStatus[0x2] = puIrqStatus[0x2];
+
+ gDecKernelLib.pfCallback[uMaloneIdx] ( &sData );
+
+}
+
+/* End of file */
diff --git a/drivers/mxc/vpu_legacy/Malone_Firmware/DecKLib/Incl/DecKernelLib.h b/drivers/mxc/vpu_legacy/Malone_Firmware/DecKLib/Incl/DecKernelLib.h
new file mode 100755
index 000000000000..b924aa44f50f
--- /dev/null
+++ b/drivers/mxc/vpu_legacy/Malone_Firmware/DecKLib/Incl/DecKernelLib.h
@@ -0,0 +1,121 @@
+/////////////////////////////////////////////////////////////////////////////////
+/// @author Copyright (c) 2015 Amphion Semiconductor Ltd
+/////////////////////////////////////////////////////////////////////////////////
+// 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:
+//
+// http://www.opensource.org/licenses/gpl-license.html
+// http://www.gnu.org/copyleft/gpl.html
+////////////////////////////////////////////////////////////////////////////////
+//
+/// @file DecLib.h
+/// @brief Main DecLib public header file
+/// @ingroup DecLib
+/// @defgroup DecLib DecLib API
+/// @{
+/// Decoder Library API level - Exported header file
+/// called by the Player level and passing data back
+/// via registered callbacks
+/// @}
+//
+/////////////////////////////////////////////////////////////////////////////////
+// $Id:
+/////////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////////
+// Header files
+/////////////////////////////////////////////////////////////////////////////////
+
+#include "basetype.h"
+#include "mediaip_fw_types.h"
+#include "pal.h"
+#include "DecKernelLibCfg.h"
+
+#ifndef _DECODER_KLIB_H_
+#define _DECODER_KLIB_H_
+
+/////////////////////////////////////////////////////////////////////////////////
+// Global Macros
+/////////////////////////////////////////////////////////////////////////////////
+
+#define DECLIB_FSID_INVALID 0xbad
+
+#define DECLIB_DBG_SESSION_STATE 0x1
+#define DECLIB_DBG_DECODER_STATE 0x2
+#define DECLIB_DBG_SYNTAX_ELEMENT 0x4
+#define DECLIB_DBG_REG_ACCESS 0x8
+#define DECLIB_DBG_CQ_FIFO 0x10
+
+#define DECLIB_DBG_REG_HIF 0x1
+#define DECLIB_DBG_REG_SIF 0x2
+#define DECLIB_DBG_REG_CTX 0x4
+#define DECLIB_DBG_REG_RPR 0x8
+#define DECLIB_DBG_REG_SPP 0x10
+#define DECLIB_DBG_REG_DEC 0x20
+#define DECLIB_DBG_REG_CQ 0x40
+#define DECLIB_DBG_REG_RSB 0x80
+#define DECLIB_DBG_REG_DFE 0x80
+
+#ifdef MVD_DIAG_LOG_REG_ACCESS
+#define DECLIB_DBG_MASK 0x1F
+#define DECLIB_DBG_REG_MASK 0x1FF
+#else
+#define DECLIB_DBG_MASK 0x7
+#define DECLIB_DBG_REG_MASK 0x0
+#endif
+
+/////////////////////////////////////////////////////////////////////////////////
+// Global Types
+/////////////////////////////////////////////////////////////////////////////////
+
+typedef struct
+{
+ u_int32 uMalIdx;
+ u_int32 uIrqStatus[0x3];
+
+} DECODER_KERNEL_LIB_ISR_EVENT_DATA;
+
+/////////////////////////////////////////////////////////////////////////////////
+// Global Function definitions
+/////////////////////////////////////////////////////////////////////////////////
+
+//////////////////////////////////////////////////////////////
+/// Decoder Event info callback
+
+typedef void ( * DecKernelLib_Isr_Callback_t )( DECODER_KERNEL_LIB_ISR_EVENT_DATA *ptEventData );
+
+/////////////////////////////////////////////////////////////////////////////////
+// Global Configuration Type
+/////////////////////////////////////////////////////////////////////////////////
+
+//////////////////////////////////////////////////////////////
+/// DecoderLib Configuration structure
+
+typedef struct
+{
+ /* Malone hardware details */
+ u_int32 uNumMalones;
+ u_int32 uMaloneHifOffset[DECODERLIB_MAX_MALONES];
+ uint_addr uMaloneBaseAddr[DECODERLIB_MAX_MALONES];
+ u_int32 uMaloneIrqPin[DECODERLIB_MAX_MALONES][0x2];
+ u_int32 uNumDPVUnits; /* 0 or 1 - could infer this from base address but for clarity */
+ uint_addr uDPVBaseAddr;
+ u_int32 uDPVIrqPin;
+} DECODERLIB_KERNEL_CFG, * pDECODERLIB_KERNEL_CFG;
+
+/////////////////////////////////////////////////////////////////////////////////
+// Global Function Prototypes
+/////////////////////////////////////////////////////////////////////////////////
+
+MEDIAIP_FW_STATUS decoder_kernel_lib_init ( DECODERLIB_KERNEL_CFG * pCfg );
+
+MEDIAIP_FW_STATUS decoder_kernel_lib_term ( void );
+
+MEDIAIP_FW_STATUS decoder_kernel_lib_register_isr_callback ( u_int32 uMalIdx,
+ DecKernelLib_Isr_Callback_t pfCallback );
+
+
+#endif /* _DECODER_KLIB_H_ */
+
+/* End of File */
diff --git a/drivers/mxc/vpu_legacy/Malone_Firmware/DecKLib/Incl/mvd.h b/drivers/mxc/vpu_legacy/Malone_Firmware/DecKLib/Incl/mvd.h
new file mode 100755
index 000000000000..956f69e93f70
--- /dev/null
+++ b/drivers/mxc/vpu_legacy/Malone_Firmware/DecKLib/Incl/mvd.h
@@ -0,0 +1,157 @@
+/***************************************************
+ Copyright (c) 2015 Amphion Semiconductor Ltd
+ All rights reserved.
+ ***************************************************
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ ****************************************************
+
+ Author : Media IP FW team
+ File name : mvd.h
+ Notes : Replaces misnamed "global.h"
+
+ ***********************************************/
+
+#ifndef _MVD_H_
+#define _MVD_H_
+
+/////////////////////////////////////////////////////////////////////////////////
+// Header files
+/////////////////////////////////////////////////////////////////////////////////
+
+#include "basetype.h"
+#include "DecKernelLibCfg.h"
+
+/////////////////////////////////////////////////////////////////////////////////
+// Global Variables
+/////////////////////////////////////////////////////////////////////////////////
+extern u_int32 uMvdKernelIrqPin[DECODERLIB_MAX_MALONES][0x2];
+
+/////////////////////////////////////////////////////////////////////////////////
+// Macros
+/////////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////////
+// Register access model
+//
+
+///////////////////////////////////////////////////
+// This is the option used for most builds
+
+#ifndef MVD_DEBUG_REG_ACCESS
+#if TARGET_LEVEL == CMODEL
+ extern u_int32 dec_model_malone_reg_write ( u_int32 * puRegAddr, u_int32 uWrtData );
+ extern u_int32 dec_model_malone_reg_read ( u_int32 * puRegAddr, u_int32 uReadData );
+
+ #define APB_REGISTER_WRITE(a,b) dec_model_malone_reg_write ( ( u_int32 * )a, ( u_int32 )b )
+ #define APB_REGISTER_READ(a,b) b = *a; dec_model_malone_reg_read ( ( u_int32 * )a, ( u_int32 )b )
+ #define APB_REG_WRITE(a,b) dec_model_malone_reg_write ( ( u_int32 * )&a, ( u_int32 )b )
+ #define APB_REG_READ(a,b) b = a; dec_model_malone_reg_read ( ( u_int32 * )&a, ( u_int32 )b )
+#else
+
+
+
+#if 0
+#include "VPU_debug.h"
+//static u_int32 c;
+
+#define APB_REGISTER_WRITE(a,b) c = b; *a = c; printk("write reg 0x%p, val 0x%x, in %s\n", a, c, __FUNCTION__)
+#define APB_REGISTER_READ(a,b) c = *a; b = c; printk("read reg 0x%p, val 0x%x, in %s\n", a, c, __FUNCTION__)
+#define APB_REG_WRITE(a,b) c = b; a = c; printk("write reg 0x%p, val 0x%x, in %s\n", &a, c, __FUNCTION__)
+#define APB_REG_READ(a,b) c = a; b = c; printk("read reg 0x%p, val 0x%x, in %s\n", &a, c, __FUNCTION__)
+#else
+
+ #define APB_REGISTER_WRITE(a,b) *a = b
+ #define APB_REGISTER_READ(a,b) b = *a
+ #define APB_REG_WRITE(a,b) a = b
+ #define APB_REG_READ(a,b) b = a
+#endif
+
+#endif
+#else
+ // Store reg acesses in simple debug array for dumping from debugger
+ extern void decoderlib_debug_reg( volatile u_int32 * puRegAddr, u_int32 uVal);
+ #define APB_REGISTER_WRITE(a,b) *a = b
+ #define APB_REGISTER_READ(a,b) b = *a
+ #define APB_REG_WRITE(a,b) decoderlib_debug_reg(( u_int32 * )&a,b)
+ #define APB_REG_READ(a,b) b = a
+#endif
+
+
+#ifdef MVD_DIAG_LOG_REG_ACCESS
+
+#define DIAG_CQ_ID DECLIB_DBG_REG_CQ
+
+extern void decoderlib_dbg_core_log_write ( volatile u_int32 * puRegAddr, u_int32 uVal, void * pMVDHw, u_int32 uAuxData, bool bActive );
+extern void decoderlib_dbg_core_log_read ( volatile u_int32 * puRegAddr, u_int32 *puVal, void * pMVDHw, u_int32 uAuxData, bool bActive );
+extern u_int32 decoderlib_dbg_get_reg_mask ( u_int32 uStrIdx );
+
+#define MVD_REG_WRITE(pMvdHw,aux,addr,val) decoderlib_dbg_core_log_write ( ( u_int32 * )&addr, val, ( void * )pMvdHw, aux, gbLogRegAccessActive )
+#define MVD_REG_READ(pMvdHw,aux,addr,val) decoderlib_dbg_core_log_read ( ( u_int32 * )&addr, &val, ( void * )pMvdHw, 0x0, gbLogRegAccessActive )
+#define MVD_ADDRESS_WRITE(pMvdHw,aux,addr,val) decoderlib_dbg_core_log_write ( ( u_int32 * )addr, val, ( void * )pMvdHw, aux, gbLogRegAccessActive )
+#define MVD_ADDRESS_READ(pMvdHw,aux,addr,val) decoderlib_dbg_core_log_read ( ( u_int32 * )addr, &val, ( void * )pMvdHw, 0x0, gbLogRegAccessActive )
+
+#else
+
+#define MVD_REG_WRITE(pMvdHw,aux,addr,val) APB_REG_WRITE(addr,val)
+#define MVD_REG_READ(pMvdHw,aux,addr,val) APB_REG_READ(addr,val)
+#define MVD_ADDRESS_WRITE(pMvdHw,aux,addr,val) APB_REGISTER_WRITE(addr,val)
+#define MVD_ADDRESS_READ(pMvdHw,aux,addr,val) APB_REGISTER_READ(addr,val)
+
+#endif /* MVD_DIAG_LOG_REG_WRITES */
+
+#define APB_REGISTER_POLL(s,p,v,m)
+#define APB_SEEK_EVENT(e)
+#define APB_REG_SET(a,m,b) ((a)) = ((((a)) & ~(m)) | ((b) & (m)))
+
+///////////////////////////
+// System functions
+//
+
+///////////////////////////
+// MULT_U(a,b)
+//
+// a * b
+
+#define MULT_U(a,b) (a)*(b)
+
+///////////////////////////
+// LDIV_MOD_U(a,b)
+//
+// a / b, mod = a % b
+
+#define LDIV_MOD_U(a,b,mod) (a)/(b), mod = (a)%(b)
+
+///////////////////////////
+// MEMORY_BLOCK_COPY(a,b,c,d)
+//
+// a : int - 1 for load, 0: store
+// b : int - size of transfer in bytes
+// c : void * - source address
+// d : void * - destination address
+
+#define MEMORY_BLOCK_COPY(a,b,c,d) pal_memcpy(d,c,b)
+
+//////////////////////////////////////////////////
+// Implementation running defines
+//
+
+#define FORCE_DECODE_HANDLE_IRQ { \
+ pgCtrlMVDHw->uForceFIQ = 1; \
+ if ( pgCtrlMVDHw->uMaloneID == 0 ) \
+ { \
+ pal_int_set ( uDecLibIrqPin[0x0][0x0] ); \
+ } \
+ else \
+ { \
+ pal_int_set ( uDecLibIrqPin[0x1][0x0] ); \
+ } \
+ }
+
+#endif /* _MVD_H_ */
+
+/* End of file */
diff --git a/drivers/mxc/vpu_legacy/Malone_Firmware/DecKLib/Incl/mvd_reg_map.h b/drivers/mxc/vpu_legacy/Malone_Firmware/DecKLib/Incl/mvd_reg_map.h
new file mode 100755
index 000000000000..5464cd240458
--- /dev/null
+++ b/drivers/mxc/vpu_legacy/Malone_Firmware/DecKLib/Incl/mvd_reg_map.h
@@ -0,0 +1,1676 @@
+/***************************************************
+ Copyright (c) 2015 Amphion Semiconductor Ltd
+ All rights reserved.
+ ***************************************************
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ ****************************************************
+
+ Author : VCodec FW team
+ File name : mvd_reg_map.h
+ Function : Register map file
+
+ ************************************************/
+
+#ifndef _MVD_REG_MAP_H_
+#define _MVD_REG_MAP_H_
+
+/////////////////////////////////////////////////////////////////
+// HIF address index
+//
+
+typedef struct MvdHwRegHifMapTag
+{
+ // 0x00 --> 0x0f
+ MvdHwReg control;
+ MvdHwReg status;
+ MvdHwReg config;
+ MvdHwReg config2;
+ MvdHwReg test;
+ MvdHwReg host_interrupt_enable;
+ MvdHwReg interrupt_status;
+ MvdHwReg fast_interrupt_enable;
+ MvdHwReg dq_unused[4];
+ MvdHwReg security;
+ MvdHwReg format_disable;
+ MvdHwReg system_data;
+ MvdHwReg spp_security;
+ // 0x10 --> 0x1f
+ MvdHwReg dfe_security;
+ MvdHwReg hif_unused[15];
+
+ // the rest are not used
+ // MvdHwReg unused_0x60[96];
+
+} MvdHwRegHifMap;
+
+
+/////////////////////////////////////////////////////////////////
+// SIF address index
+//
+
+typedef struct MvdHwRegSifMapTag
+{
+ // 0x00 --> 0x0f
+ MvdHwReg semaphore_read; // R
+ MvdHwReg intr_mask_read; // R
+ MvdHwReg semaphore_set; // W
+ MvdHwReg semaphore_clr; // W
+ MvdHwReg intr_mask_set; // W
+ MvdHwReg intr_mask_clr; // W
+ MvdHwReg host_data0_reg; // R
+ MvdHwReg msd_data0_reg; // R/W
+ MvdHwReg host_data1_reg; // R
+ MvdHwReg msd_data1_reg; // R/W
+ MvdHwReg frame_active_count;
+ MvdHwReg slice_active_count;
+ MvdHwReg rbsp_bytes_count;
+ MvdHwReg sib_wait_count;
+ MvdHwReg dpb_read_count;
+ MvdHwReg mpr_wait_count;
+ // 0x10 --> 0x1f
+ MvdHwReg intr3_control; // W/R
+ MvdHwReg dpb_fs_size; // R/W
+ MvdHwReg dpb_frm_size; // R/W
+ MvdHwReg dpb_fs_size_ext; // R/W
+ MvdHwReg rsb_mprr_mprc_base; // R/W
+ MvdHwReg rsb_bsd_dbfc_base; // R/W
+ MvdHwReg rsb_pwt_pxd_base; // R/W
+ MvdHwReg frm_dangling; // W
+ MvdHwReg rsb_dfe_base; // R/W
+ MvdHwReg dpb_lut_load; // W
+ MvdHwReg bbb_crc; // R
+ MvdHwReg load_dpb_numb; // W
+ MvdHwReg dpb_frm_size_ext; // R/W
+ MvdHwReg dec_status; // R
+ MvdHwReg mbq_full_count;
+ MvdHwReg mbq_empty_count;
+ // 0x20 --> 0x2f
+ MvdHwReg dispq_push[16];
+ // 0x30 --> 0x3f
+ MvdHwReg intr3_status;
+ MvdHwReg intr3_force;
+ MvdHwReg bs2rbsp_status; // R
+ MvdHwReg bs2rbsp_feed_control;// W/R
+ MvdHwReg bs2rbsp_scode; // R
+ MvdHwReg bs2rbsp_scdctrl; // W/R
+ MvdHwReg rpr_wr_uv_offset;
+ MvdHwReg dispd_cnt_tag; // R
+ MvdHwReg frame_request; // R
+ MvdHwReg intr2_control; // W/R
+ MvdHwReg intr2_status; // R/W
+ MvdHwReg intr2_force;
+ MvdHwReg control; // W/R
+ MvdHwReg intr_status; // R/W
+ MvdHwReg intr_force;
+ MvdHwReg soft_reset; // W
+ // 0x40 --> 0x4f
+ MvdHwReg pes_setup; // W/R
+ MvdHwReg pes_status; // W/R
+ MvdHwReg pes_ctrl; // W
+ MvdHwReg pes_set_state; // W
+ MvdHwReg pes_peek_data; // R
+ MvdHwReg pes_read_data; // R
+ MvdHwReg pes_pts; // R
+ MvdHwReg pes_dts; // R
+ MvdHwReg bs_read; // R
+ MvdHwReg dpbmc_setup; // W
+ MvdHwReg dpbmc_crc_data; // R
+ MvdHwReg rsb_ctrl_stat;
+ MvdHwReg ext_rsb_base;
+ MvdHwReg ext_xfr_param;
+ MvdHwReg vmif_rsb_arb_ctrl;
+ MvdHwReg vmif_stride;
+
+ // 0x50 --> 0x5f
+ MvdHwReg vmif_uv_offset;
+ MvdHwReg vmif_options;
+ MvdHwReg vmif_base_offset;
+ MvdHwReg vmif_mbi_cache;
+ MvdHwReg lmem_config;
+ MvdHwReg qp_acc;
+ MvdHwReg vmif_mbi_xmem;
+ MvdHwReg vmif_4kcache_stride;
+ MvdHwReg dpbmc_setup2;
+ MvdHwReg rpr_rd_uv_offset;
+ MvdHwReg slow_feed_wt_val;
+ MvdHwReg unused_0x5b;
+ MvdHwReg unused_0x5c;
+ MvdHwReg dpbmc_crc2_data; // R
+ MvdHwReg errgen_config; // W
+ MvdHwReg errgen_seeds; // W
+ // 0x60 --> 0x6f
+ MvdHwReg bsdma_command;
+ MvdHwReg bsdma_options;
+ MvdHwReg bsdma_status;
+ MvdHwReg bsdma_des;
+ MvdHwReg bsdma_bwp;
+ MvdHwReg bsdma_brp;
+ MvdHwReg bsdma_bsa;
+ MvdHwReg bsdma_bea;
+ MvdHwReg bsdma_blw;
+ MvdHwReg bsdma_bup;
+ MvdHwReg bsdma_peek;
+ MvdHwReg bsdma_bhw;
+ MvdHwReg bsdma_trc;
+ MvdHwReg bsdma_ext_options;
+ MvdHwReg bsdma_lvl;
+ MvdHwReg unused_0x6f;
+ // 0x70 --> 0x7f
+ // MvdHwReg unused_16[16];
+} MvdHwRegSifMap;
+
+/////////////////////////////////////////////////////////////////
+// Context Reg Map
+//
+
+#define MVD_CTX_POC_RESTORE_WORDS 62
+
+typedef struct MvdHwRegCtxMapTag
+{
+ // 0x00 --> 0x0f
+ MvdHwReg ctx_command;
+ MvdHwReg ctx_next_sf;
+ MvdHwReg ctx_spp_command;
+ MvdHwReg align_7[4];
+ MvdHwReg ctx_status;
+ MvdHwReg align_8[8];
+
+ // 0x10 --> 0x1f
+ MvdHwReg ctx_addr_spp[16]; /* PreParser (if it is configured in) */
+// MvdHwReg align_9[4];
+
+ // 0x20 --> 0x2f
+ MvdHwReg ctx_addr_bbb[2]; /* Active BBB */
+ MvdHwReg align_10[14];
+
+ // 0x30 --> 0x3f
+ MvdHwReg ctx_addr_bsi[13]; /* SCD/PES/FIFO */
+ MvdHwReg align_11[3];
+
+ // 0x40 --> 0x7f
+ MvdHwReg h264_poc_restore[MVD_CTX_POC_RESTORE_WORDS];
+ MvdHwReg unused_poc[64-MVD_CTX_POC_RESTORE_WORDS];
+
+} MvdHwRegCtxMap;
+
+
+/////////////////////////////////////////////////////////////////
+// Resampler Reg Map
+//
+
+typedef struct MvdHwRegRprMapTag
+{
+ // 0x0 --> 0xf
+ MvdHwReg rpr_status_addr; // R
+ MvdHwReg rpr_ctl_start;
+ MvdHwReg rpr_in_size;
+ MvdHwReg rpr_out_size;
+ MvdHwReg rpr_fill_value;
+ MvdHwReg rpr_ax_ini_y;
+ MvdHwReg rpr_ax_ini_uv;
+ MvdHwReg rpr_ax_inc;
+ MvdHwReg rpr_iuyl_num_y;
+ MvdHwReg rpr_iuyl_num_uv;
+ MvdHwReg rpr_iuyl_inc;
+ MvdHwReg rpr_options_addr;
+ MvdHwReg csc_status;
+ MvdHwReg csc_ctrl_start;
+ MvdHwReg csc_fs_size;
+ MvdHwReg csc_fs_idc;
+ MvdHwReg csc_fs_stride;
+ MvdHwReg rpr_rd_fs_stride;
+ MvdHwReg rpr_wr_fs_stride;
+ MvdHwReg dpv_status;
+ MvdHwReg dpv_ctrl_start;
+ MvdHwReg dpv_fs_size;
+ MvdHwReg dpv_init_val;
+ MvdHwReg dpv_crc_val;
+
+ // approx 1KB space not used (1KB - rpr register)
+ // MsdHwReg unused_0x90[240];
+
+} MvdHwRegRprMap;
+
+/////////////////////////////////////////////////////////////////
+// RC4 Decryption Reg Map
+//
+
+typedef struct MvdHwRegRC4MapTag
+{
+
+ MvdHwReg Key0Word0;
+ MvdHwReg Key0Word1;
+ MvdHwReg Key0Word2;
+ MvdHwReg Key0Word3;
+ MvdHwReg Key1Word0;
+ MvdHwReg Key1Word1;
+ MvdHwReg Key1Word2;
+ MvdHwReg Key1Word3;
+ MvdHwReg RC4Enable;
+ MvdHwReg unused_rc4_0[12-9];
+ MvdHwReg RC4Ctx0;
+ MvdHwReg RC4Ctx1;
+ MvdHwReg RC4Ctx2;
+ MvdHwReg unused_rc4_1;
+
+} MvdHwRegRC4Map;
+
+
+/////////////////////////////////////////////////////////////////
+// Black Bar Detector Reg Map
+//
+/*-- BBD registers (common to all formats) */
+
+typedef struct MvdHwRegBbdMapTag
+{
+ MvdHwReg bbd_cfg_ctrl;
+ MvdHwReg bbd_logo_width;
+ MvdHwReg bbd_pix_thr;
+ MvdHwReg bbd_s_thr_row;
+ MvdHwReg bbd_p_thr_row;
+ MvdHwReg bbd_s_thr_logo_row;
+ MvdHwReg bbd_p_thr_logo_row;
+ MvdHwReg bbd_s_thr_col;
+ MvdHwReg bbd_p_thr_col;
+ MvdHwReg bbd_chr_thr;
+ MvdHwReg bbd_excl_win_mb;
+ MvdHwReg unused;
+ MvdHwReg bbd_hor_active;
+ MvdHwReg bbd_ver_active;
+ MvdHwReg bbd_logo_active;
+ MvdHwReg bbd_botprev_active;
+ MvdHwReg bbd_min_col_proj;
+ MvdHwReg bbd_min_row_proj;
+
+
+} MvdHwRegBbdMap;
+
+/////////////////////////////////////////////////////////////////
+// Debug Reg Map
+//
+
+typedef struct MvdHwRegDbgMapTag
+{
+ // 0x0 --> 0x1f
+ union
+ {
+ MvdHwReg msk0_lo;
+ MvdHwReg fifo0;
+ MvdHwReg status0;
+ } fifo0_up;
+ union
+ {
+ MvdHwReg msk0_hi;
+ MvdHwReg fifo1;
+ MvdHwReg status1;
+ } fifo1_up;
+ union
+ {
+ MvdHwReg msk1_lo;
+ MvdHwReg fifo2;
+ MvdHwReg status2;
+ } fifo2_up;
+ union
+ {
+ MvdHwReg msk1_hi;
+ MvdHwReg fifo3;
+ MvdHwReg status3;
+ } fifo3_up;
+ union
+ {
+ MvdHwReg msk2_lo;
+ MvdHwReg fifo4;
+ MvdHwReg status4;
+ } fifo4_up;
+ union
+ {
+ MvdHwReg msk2_hi;
+ MvdHwReg fifo5;
+ MvdHwReg status5;
+ } fifo5_up;
+ union
+ {
+ MvdHwReg mode;
+ MvdHwReg fifo6;
+ MvdHwReg status6;
+ } fifo6_up;
+ union
+ {
+ MvdHwReg unused2;
+ MvdHwReg fifo7;
+ MvdHwReg status7;
+ } fifo7_up;
+ union
+ {
+ MvdHwReg crc0;
+ MvdHwReg fifo8;
+ MvdHwReg status8;
+ } crc0_up;
+ union
+ {
+ MvdHwReg crc1;
+ MvdHwReg fifo9;
+ MvdHwReg status9;
+ } crc1_up;
+ union
+ {
+ MvdHwReg crc2;
+ MvdHwReg fifo10;
+ MvdHwReg status10;
+ } crc2_up;
+ union
+ {
+ MvdHwReg crc3;
+ MvdHwReg fifo11;
+ MvdHwReg status11;
+ } crc3_up;
+ union
+ {
+ MvdHwReg crc4;
+ MvdHwReg fifo12;
+ MvdHwReg status12;
+ } crc4_up;
+ union
+ {
+ MvdHwReg crc5;
+ MvdHwReg fifo13;
+ MvdHwReg status13;
+ } crc5_up;
+ union
+ {
+ MvdHwReg crc6;
+ MvdHwReg fifo14;
+ MvdHwReg status14;
+ } crc6_up;
+ union
+ {
+ MvdHwReg crc7;
+ MvdHwReg clr_crc;
+ MvdHwReg fifo15;
+ MvdHwReg status15;
+ } crc7_up;
+ union
+ {
+ MvdHwReg crc8;
+ MvdHwReg fifo16;
+ MvdHwReg status16;
+ } crc8_up;
+ union
+ {
+ MvdHwReg crc9;
+ MvdHwReg fifo17;
+ MvdHwReg status17;
+ } crc9_up;
+ union
+ {
+ MvdHwReg crc10;
+ } crc10_up;
+ union
+ {
+ MvdHwReg crc11;
+ } crc11_up;
+
+ MvdHwReg crc12;
+ MvdHwReg crc13;
+ MvdHwReg crc14;
+ MvdHwReg dbg_unused_31to23[9];
+
+} MvdHwRegDbgMap;
+
+/////////////////////////////////////////////////////////////////
+//Command Queues Reg Map
+//
+
+typedef struct MvdHwRegCqMapTag
+{
+
+ MvdHwReg cq_status;
+ MvdHwReg cq_grp;
+ MvdHwReg cq_clr;
+ MvdHwReg cq_data;
+ MvdHwReg cq_data_last;
+ MvdHwReg cq_data_mask;
+ MvdHwReg cq_data_test;
+ MvdHwReg cq_opts;
+ MvdHwReg cq_push;
+ MvdHwReg cq_dummy;
+ MvdHwReg cq_cmdq_base;
+ MvdHwReg cq_cmdq_amax;
+ MvdHwReg cq_cmdq_wptr;
+ MvdHwReg cq_cmdq_rptr;
+ MvdHwReg cq_cmdq_level;
+ MvdHwReg cq_rdq_base;
+ MvdHwReg cq_rdq_amax;
+ MvdHwReg cq_rdq_wptr;
+ MvdHwReg cq_rdq_rptr;
+ MvdHwReg cq_rdq_level;
+ MvdHwReg cq_poll_param;
+ MvdHwReg cq_grp_level;
+ MvdHwReg cq_exec;
+ MvdHwReg cq_lwm;
+ MvdHwReg cq_dataq_base;
+ MvdHwReg cq_dataq_amax;
+ MvdHwReg cq_dataq_rptr;
+ MvdHwReg cq_special_en;
+ MvdHwReg cq_wdata_opt;
+ MvdHwReg cq_sgrp_base_addr;
+ MvdHwReg cq_sgrp_num_cmds;
+ MvdHwReg cq_status2;
+
+} MvdHwRegCqMap;
+
+
+/////////////////////////////////////////////////////////////////
+// Stream Preparser Reg Map
+//
+
+typedef struct MvdHwRegSppMapTag
+{
+ // 0x0 --> 0x07
+ MvdHwReg bbb_showbits; // R
+ MvdHwReg bbb_status; // R
+ MvdHwReg config; // W/R
+ MvdHwReg bs2rbsp_status; // R
+ MvdHwReg bs2rbsp_feed_control;// W/R
+ MvdHwReg bs2rbsp_scode; // R
+ MvdHwReg bs2rbsp_scdctrl; // W/R
+ MvdHwReg bbb_crc; // R
+
+ // 0x08 --> 0x0f
+ MvdHwReg pes_setup; // W/R
+ MvdHwReg pes_status; // W/R
+ MvdHwReg pes_ctrl; // W
+ MvdHwReg pes_set_state; // W
+ MvdHwReg pes_peek_data; // R
+ MvdHwReg pes_read_data; // R
+ MvdHwReg pes_pts; // R
+ MvdHwReg pes_dts; // R
+
+ // 0x10 --> 0x1f
+ MvdHwReg bsdma_command;
+ MvdHwReg bsdma_options;
+ MvdHwReg bsdma_status;
+ MvdHwReg bsdma_des;
+ MvdHwReg bsdma_bwp;
+ MvdHwReg bsdma_brp;
+ MvdHwReg bsdma_bsa;
+ MvdHwReg bsdma_bea;
+ MvdHwReg bsdma_blw;
+ MvdHwReg bsdma_bup;
+ MvdHwReg bsdma_peek;
+ MvdHwReg bsdma_bhw;
+ MvdHwReg bsdma_trc;
+ MvdHwReg bsdma_ext_options;
+ MvdHwReg bsdma_lvl;
+ MvdHwReg unused_0x1f;
+
+ // 0x20 --> 0x3f
+ union
+ {
+ MvdHwReg bsd_byte_align;
+ MvdHwReg bsd_getbits[32];
+ } get_bits;
+
+ // 0x40 --> 0x4f
+ MvdHwReg egd_ue;
+ MvdHwReg egd_se;
+ MvdHwReg egd_me_intra;
+ MvdHwReg egd_me_inter;
+ MvdHwReg data_reg; /* R/W */
+ MvdHwReg num_bits_pulled; /* R */
+ MvdHwReg bit_puller;
+ MvdHwReg unused_spp1[16-7];
+
+ // 0x50 --> 0x5f
+ MvdHwReg Key0Word0;
+ MvdHwReg Key0Word1;
+ MvdHwReg Key0Word2;
+ MvdHwReg Key0Word3;
+ MvdHwReg Key1Word0;
+ MvdHwReg Key1Word1;
+ MvdHwReg Key1Word2;
+ MvdHwReg Key1Word3;
+ MvdHwReg RC4Enable;
+ MvdHwReg unused_rc4_0[12-9];
+ MvdHwReg RC4Ctx0;
+ MvdHwReg RC4Ctx1;
+ MvdHwReg RC4Ctx2;
+ MvdHwReg unused_rc4_1;
+
+} MvdHwRegSppMap;
+
+/////////////////////////////////////////////////////////////////
+// Stream Frame Buffer Compression Reg Map
+//
+
+typedef struct MvdHwRegFbcMapTag
+{
+ // 0x0 --> 0x0f
+ MvdHwReg fbc_start;
+ MvdHwReg fbc_config;
+ MvdHwReg fbc_param1;
+ MvdHwReg fbc_param2;
+ MvdHwReg fbc_ctb_tile_px4;
+ MvdHwReg fbc_ctb_tile_py4;
+ MvdHwReg fbc_ctb_tile_px8;
+ MvdHwReg fbc_ctb_tile_py8;
+ MvdHwReg fbc_ctb_tile_px9_y10;
+ MvdHwReg fbc_ot_offset;
+ MvdHwReg fbc_field_offset;
+ MvdHwReg fbc_uv_offset;
+ MvdHwReg fbc_field_list;
+ MvdHwReg fbc_luma_pad_list;
+ MvdHwReg fbc_chroma_pad_list;
+ MvdHwReg fbc_write_count;
+ MvdHwReg fbc_read_count_0;
+ MvdHwReg fbc_read_count_1;
+ MvdHwReg fbc_write_chksum;
+ MvdHwReg fbc_read_chksum_0;
+ MvdHwReg fbc_read_chksum_1;
+ MvdHwReg fbc_param3;
+ MvdHwReg fbc_fs_height;
+ MvdHwReg fbc_read_dbg_gen;
+ MvdHwReg fbc_read_dbg_blk;
+ MvdHwReg fbd_ot_offset;
+ MvdHwReg fbd_fld_offset;
+ MvdHwReg fbd_uv_offset;
+ MvdHwReg fbc_unused[62-28];
+ MvdHwReg unused_fbc_0[2];
+} MvdHwRegFbcMap;
+
+
+/////////////////////////////////////////////////////////////////
+// Decoupled Front End Register Map
+// ( 1K incl debug registers )
+
+typedef struct MvdHwRegDfeMapTag
+{
+ // 0x0 --> 0x07
+ MvdHwReg bbb_showbits; // R
+ MvdHwReg bbb_status; // R
+ MvdHwReg config; // W/R
+ MvdHwReg bs2rbsp_status; // R
+ MvdHwReg bs2rbsp_feed_control;// W/R
+ MvdHwReg bs2rbsp_scode; // R
+ MvdHwReg bs2rbsp_scdctrl; // W/R
+ MvdHwReg bbb_crc; // R
+
+ // 0x08 --> 0x0f
+ MvdHwReg pes_setup; // W/R
+ MvdHwReg pes_status; // W/R
+ MvdHwReg pes_ctrl; // W
+ MvdHwReg pes_set_state; // W
+ MvdHwReg pes_peek_data; // R
+ MvdHwReg pes_read_data; // R
+ MvdHwReg pes_pts; // R
+ MvdHwReg pes_dts; // R
+
+ // 0x10 --> 0x1f
+ MvdHwReg bsdma_command;
+ MvdHwReg bsdma_options;
+ MvdHwReg bsdma_status;
+ MvdHwReg bsdma_des;
+ MvdHwReg bsdma_bwp;
+ MvdHwReg bsdma_brp;
+ MvdHwReg bsdma_bsa;
+ MvdHwReg bsdma_bea;
+ MvdHwReg bsdma_blw;
+ MvdHwReg bsdma_bup;
+ MvdHwReg bsdma_peek;
+ MvdHwReg bsdma_bhw;
+ MvdHwReg bsdma_trc;
+ MvdHwReg bsdma_ext_options;
+ MvdHwReg bsdma_lvl;
+ MvdHwReg unused_0x1f;
+
+ /* BSD address, 0x20 --> 0x5f */
+ MvdHwReg bsd_options;
+ MvdHwReg bsd_dec_status;
+ MvdHwReg bsd_ctb_coord;
+ MvdHwReg bsd_slice_start;
+ MvdHwReg bsd_dec_param1;
+ MvdHwReg bsd_dec_param2;
+ MvdHwReg bsd_dec_ctb_cnt;
+ MvdHwReg bsd_dec_err_ctb_cnt;
+ MvdHwReg bsd_dec_ctb_qp_sum;
+
+ MvdHwReg Unused_9;
+ MvdHwReg Unused_A;
+
+ MvdHwReg bsd_ue;
+ MvdHwReg bsd_se;
+ MvdHwReg Unused_D;
+ MvdHwReg Unused_E;
+ MvdHwReg bsd_data;
+
+ MvdHwReg Unused_10;
+ MvdHwReg bsd_ctb_tile_px4;
+ MvdHwReg bsd_ctb_tile_py4;
+ MvdHwReg bsd_ctb_tile_px8;
+ MvdHwReg bsd_ctb_tile_py8;
+ MvdHwReg bsd_ctb_tile_px9_y10;
+ MvdHwReg bsd_sc_list_usage;
+ MvdHwReg bsd_sc_list_base;
+ MvdHwReg bsd_sc_list_idx[4];
+ MvdHwReg bsd_ei_flags_mask;
+ MvdHwReg bsd_bit_puller;
+ MvdHwReg bsd_is_trailing;
+ MvdHwReg bsd_bbb_status;
+
+ union
+ {
+ MvdHwReg bsd_byte_align;
+ MvdHwReg bsd_getbits[32];
+ } get_bits;
+
+ /* 0x60 --> 0x6f */
+ MvdHwReg Key0Word0;
+ MvdHwReg Key0Word1;
+ MvdHwReg Key0Word2;
+ MvdHwReg Key0Word3;
+ MvdHwReg Key1Word0;
+ MvdHwReg Key1Word1;
+ MvdHwReg Key1Word2;
+ MvdHwReg Key1Word3;
+ MvdHwReg RC4Enable;
+ MvdHwReg unused_rc4_0[12-9];
+ MvdHwReg RC4Ctx0;
+ MvdHwReg RC4Ctx1;
+ MvdHwReg RC4Ctx2;
+ MvdHwReg unused_rc4_1;
+
+ /* 0x70-0x7f */
+ MvdHwReg dfe_ctx_cmd;
+ MvdHwReg unused_dfe_ctx_1;
+ MvdHwReg dfe_ctx_addr_bbb[2]; /* Active BBB */
+ MvdHwReg unused_dfe_ctx_2[12];
+
+ /* 0x80 --> 0x8f */
+ MvdHwReg dfe_ctx_addr_bsi[13]; /* SCD/PES/FIFO */
+ MvdHwReg unused_dfe_ctx_3[3];
+
+ /* 0x90 --> 0x9F */
+ MvdHwReg dfe_img_cfg;
+ MvdHwReg dfe_slice_cfg;
+ MvdHwReg dfe_frm_size;
+ MvdHwReg dfe_status;
+ MvdHwReg dfe_frm_act_count;
+ MvdHwReg dfe_slice_act_count;
+ MvdHwReg dfe_rbsp_bytes_count;
+ MvdHwReg dfe_sib_wait_count;
+ MvdHwReg dfe_bsd_wait_count;
+ MvdHwReg unused_dfe[16-9];
+
+ /* 0xA0 -> 0xBF */
+ MvdHwRegCqMap DFECQ;
+
+ /* 0xC0 -> 0xDF */
+ MvdHwReg unused_0xc0_0xdf[32];
+
+ /* 0xE0 -> 0xFF */
+ MvdHwReg dfe_dbg[32];
+
+} MvdHwRegDfeMap;
+
+/////////////////////////////////////////////////////////////////
+// Decoupled Back End Register Map
+// ( 4K incl debug registers )
+
+typedef struct MvdHwRegDbeMapTag
+{
+
+ /* TOP address, 0x00 --> 0x3f */
+ MvdHwReg image_config; // R/W
+ MvdHwReg slice_config; // R/W
+ MvdHwReg top_ctb_tile_info; // R/W
+ MvdHwReg mbi_wr_base; // R/W
+ MvdHwReg mbi_rd_base; // R/W
+
+ MvdHwReg dec_cfg; // R/W Addr in CQ : 0x605
+ MvdHwReg dbg_cfg; // R/W
+ MvdHwReg dbf1_cfg; // R/W
+ MvdHwReg dbf2_cfg; // R/W
+ MvdHwReg dbe_frm_size; // R/W
+ MvdHwReg prb_pack_base; // R/W
+ MvdHwReg prb_bin_cfg; // R/W
+ MvdHwReg dcp_bin_cfg; // R/W
+
+ MvdHwReg unused_top[64-13];
+
+ /* DBE address, 0x40 --> 0x7F */
+ MvdHwReg dbe_status; // R
+ MvdHwReg dbe_frm_act_count; // R
+ MvdHwReg dbe_slice_act_count; // R
+ MvdHwReg dbe_wait_count; // R
+ MvdHwReg dbe_fetch_crc; // R
+ MvdHwReg dbe_mpr_prx_wait; // R
+ MvdHwReg dbe_pxd_prx_wait; // R
+ MvdHwReg dbe_fch_plq_wait; // R
+ MvdHwReg dbe_pxd_plq_wait; // R
+ MvdHwReg dbe_mpr_wait_count; // R
+ MvdHwReg dbe_fch_words_count; // R
+ MvdHwReg unused_dbe[64-11];
+
+ /* MPR address, 0x80 --> 0xBF */
+ MvdHwReg mpr_config;
+ MvdHwReg mpr_slice_param;
+
+ MvdHwReg Unused_82_9F[30];
+
+ MvdHwReg mpr_list[32];
+
+ MvdHwReg Unused_0xC0_FF[64];
+
+ /* CQ address, 0x100 --> 0x11F */
+ MvdHwRegCqMap DBECQ;
+ MvdHwReg Unused_0x120_13F[32];
+
+ MvdHwReg Unused_0x140_17F[64];
+
+ MvdHwReg mpr_dbg;
+ MvdHwReg pxd_dbg;
+ MvdHwReg dbf_dbg;
+
+ /* Not quite sure what debug is in here */
+ MvdHwReg Unused_DbeDbg[61];
+
+ MvdHwReg Unused_0x1C0_1FF[64];
+
+} MvdHwRegDbeMap;
+
+
+/////////////////////////////////////////////////////////////////
+// H.264 Reg Map
+//
+
+typedef struct MvdHwRegH264MapTag
+{
+ //------- TOP address, 0x00 --> 0x3f
+ MvdHwReg options; // R/W
+ MvdHwReg mbi_wr_base; // R/W
+ MvdHwReg mbi_rd_base; // R/W
+ MvdHwReg bli_wr_base; // R/W
+ MvdHwReg bli_wr_stride; // R/W
+ MvdHwReg unused_top[64-5];
+ //------- BSD address, 0x40 --> 0x7f
+ // 0x40 --> 0x4f
+ MvdHwReg bsd_dec_options; // W/R
+ MvdHwReg bsd_dec_status; // R
+ MvdHwReg bsd_curr_coord;
+ MvdHwReg bsd_slice_start;
+ MvdHwReg bsd_slice_param1;
+ MvdHwReg bsd_slice_param2;
+ MvdHwReg qm_dec_start;
+ MvdHwReg qm_dec_status;
+ MvdHwReg qm_load_start;
+ MvdHwReg qm_load_value;
+ MvdHwReg bsd_pwt_dec; // W
+ MvdHwReg bsd_egd_ue;
+ MvdHwReg bsd_egd_se;
+ MvdHwReg bsd_egd_me_intra;
+ MvdHwReg bsd_egd_me_inter;
+ MvdHwReg bsd_data_reg; // R/W
+ // 0x50 --> 0x5f
+ MvdHwReg ibb_buf_mode;
+ MvdHwReg ibb_buf_ctrl;
+ MvdHwReg ibb_buf_status;
+ MvdHwReg bsd_image_init;
+ MvdHwReg unused_bsd_0[4];
+ MvdHwReg bsd_pause;
+ MvdHwReg unused_bsd[16-9-4];
+ MvdHwReg bsd_err_mask;
+ MvdHwReg bsd_bit_puller;
+ MvdHwReg bsd_is_trailing;
+ MvdHwReg bsd_bbb_status; // R
+ // 0x60 --> 0x7f
+ union
+ {
+ MvdHwReg bsd_byte_align;
+ MvdHwReg bsd_getbits[32];
+ } get_bits;
+ //------- MPR/PXD address
+ // 0x80 --> 0x9f
+ MvdHwReg mpr_top_poc;
+ MvdHwReg mpr_bot_poc;
+ MvdHwReg unused_mpr[32-2];
+ // 0xa0 --> 0xbf
+ MvdHwReg mpr_list[32];
+ //------- DBF address
+ // 0xc0 --> 0xff
+ MvdHwReg unused_dbf[64];
+ // 0x100 --> 0x1bf not used
+ MvdHwReg unsued_spare_128[128];
+ MvdHwReg bsd_debug;
+ MvdHwReg pxd_debug;
+ MvdHwReg arb_wr_debug;
+ MvdHwReg arb_rd_debug;
+ MvdHwReg arb_mbi_debug;
+ MvdHwReg unsued_spare[59];
+
+} MvdHwRegH264Map;
+
+/////////////////////////////////////////////////////////////////
+// VC-1 Reg Map
+//
+
+typedef struct MvdHwRegVc1dMapTag
+{
+ //------- TOP address, 0x00 --> 0x3f
+ MvdHwReg unused_gen64[64];
+ //-- BSP address, 0x40 --> 0x7f
+ // 0x40 --> 0x5f
+ union
+ {
+ MvdHwReg bsp_byte_align;
+ MvdHwReg bsp_getbits[32];
+ } get_bits;
+ // 0x60 --> 0x6f
+ MvdHwReg bsp_status;
+ MvdHwReg bsp_control;
+ MvdHwReg bsp_showbits;
+ MvdHwReg bsp_showbitsflipped;
+ MvdHwReg bsp_ignorebbblevel;
+ MvdHwReg unused_bsp11[11];
+ // 0x70 --> 0x7f
+ MvdHwReg bsp_hdrvlc_ptype;
+ MvdHwReg bsp_hdrvlc_pptype;
+ MvdHwReg bsp_hdrvlc_mvrange;
+ MvdHwReg bsp_hdrvlc_mvmode;
+ MvdHwReg bsp_hdrvlc_mvmode2;
+ MvdHwReg bsp_hdrvlc_dmvrange;
+ MvdHwReg bsp_hdrvlc_bppmode;
+ MvdHwReg bsp_hdrvlc_bppvlc2;
+ MvdHwReg bsp_hdrvlc_bppvlc6;
+ MvdHwReg bsp_hdrvlc_bfract;
+ MvdHwReg bsp_hdrvlc_refdist;
+ MvdHwReg unused_bsp5[5];
+ // 0x80 --> 0x8f
+ MvdHwReg spr_general;
+ MvdHwReg spr_stream_format1;
+ MvdHwReg spr_coded_size;
+ MvdHwReg spr_stream_format2;
+ MvdHwReg spr_entrypoint1;
+ MvdHwReg spr_range_map;
+ MvdHwReg spr_frame_type;
+ MvdHwReg spr_recon_control;
+ MvdHwReg spr_mv_control;
+ MvdHwReg spr_int_comp_fwd_topnorm;
+ MvdHwReg spr_ref_bfraction;
+ MvdHwReg spr_blk_control;
+ MvdHwReg spr_trans_data;
+ MvdHwReg spr_vop_dquant;
+ MvdHwReg spr_curref_frm_id;
+ MvdHwReg spr_curdisp_frm_id;
+ // 0x90 --> 0x9f
+ MvdHwReg spr_fwdref_frm_id;
+ MvdHwReg spr_bwdref_frm_id;
+ MvdHwReg spr_fieldref_ctrl_id;
+ MvdHwReg spr_auxfrmctrl;
+ MvdHwReg spr_imgstruct;
+ MvdHwReg spr_alt_frame_type;
+ MvdHwReg spr_int_comp_fwd_bot;
+ MvdHwReg spr_int_comp_bwd_top;
+ MvdHwReg spr_int_comp_bwd_bot;
+ MvdHwReg unused_spr7[7];
+ // 0xa0 --> 0xbf
+ MvdHwReg unused_spr32[32];
+ // 0xc0 --> 0xcf
+ MvdHwReg mbd_status;
+ MvdHwReg mbd_frm_start;
+ MvdHwReg mbd_fwdebug;
+ MvdHwReg mbd_mbqdebug;
+ MvdHwReg mbd_mprdebug;
+ MvdHwReg mbd_masdebug;
+ MvdHwReg mbd_bppdebug;
+ MvdHwReg mbd_dpbmcdebug;
+ MvdHwReg mbd_gendebug;
+ MvdHwReg mbd_fw_rw;
+ MvdHwReg unused_6[6];
+ // 0xd0 --> 0xdf
+ MvdHwReg mbd_error_control;
+ MvdHwReg unused_mbd15[15];
+ // 0xe0 --> 0xff;
+ MvdHwReg unused_mbd32[32];
+ //------- BPP address
+ // 0x100 --> 0x10f
+ MvdHwReg bpp_control_status;
+ MvdHwReg bpp_datain_status;
+ MvdHwReg bpp_datain_value;
+ MvdHwReg bpp_datain_possize;
+ MvdHwReg bpp_bcachetag0;
+ MvdHwReg bpp_bcachetag1;
+ MvdHwReg bpp_bcachetag2;
+ MvdHwReg unused_0x107[9];
+ // 0x110 --> 0x1bf not used
+ MvdHwReg unsued_spare[176];
+
+} MvdHwRegVc1dMap;
+
+/////////////////////////////////////////////////////////////////
+// MPEG-2 Reg Map
+//
+
+typedef struct MvdHwRegMp2dMapTag
+{
+ //------- TOP address, 0x00 --> 0x3f
+ // 0x00 --> 0x3f
+ MvdHwReg top_seq_param;
+ MvdHwReg top_frame_ptr;
+ MvdHwReg top_pic_start;
+ MvdHwReg unused_top[64-3];
+ //------- BSD address, 0x40 --> 0x7f
+ // 0x40 --> 0x5f
+ MvdHwReg bsd_show_bits;
+ MvdHwReg bsd_dec_status;
+ MvdHwReg bsd_bbb_status;
+ MvdHwReg bsd_qm_status;
+ MvdHwReg bsd_qm_load;
+ MvdHwReg bsd_pic_param;
+ MvdHwReg bsd_slice_start;
+ MvdHwReg bsd_curr_mbcoord;
+ MvdHwReg unused_bsd[32-8];
+ // 0x60 --> 0x7f
+ union
+ {
+ MvdHwReg bsd_byte_align;
+ MvdHwReg bsd_getbits[32];
+ } get_bits;
+ // 0x80 --> 0xff
+ MvdHwReg unused_128[128];
+ //------- DBF address
+ // 0x100 --> 0x17f
+ MvdHwReg unused_dbf16[16];
+ MvdHwReg dbf_ctrl0;
+ MvdHwReg dbf_ctrl1;
+ MvdHwReg dbf_ctrl2;
+ MvdHwReg dbf_ctrl3;
+ MvdHwReg unused_dbf[128-20];
+ //------ DEBUG address
+ // 0x180 --> 0x1bf
+ MvdHwReg debug_bsd;
+ MvdHwReg debug_pxd_idct;
+ MvdHwReg debug_wr_arbiter;
+ MvdHwReg debug_rd_arbiter;
+ MvdHwReg unused_debug[64-4];
+
+} MvdHwRegMp2dMap;
+
+/////////////////////////////////////////////////////////////////
+// AVS Reg Map
+//
+
+// `define AVSD_APB_ADDR_TOP_PREFIX 3'h1 // 0x40
+// `define AVSD_APB_ADDR_BSD_PREFIX 3'h0 // 0x00
+// `define AVSD_APB_ADDR_MPR_PREFIX 3'h2 // 0x80
+#define MVD_AVSD_TOP_MIN_ADDR 0x00
+#define MVD_AVSD_BSD_MIN_ADDR 0x40
+#define MVD_AVSD_MPR_MIN_ADDR 0x80
+
+//-- Top level Register address
+#define MVD_AVSD_TOP_SEQ_PARAM_ADDR 0x00 // W/R, Chroma422
+#define MVD_AVSD_TOP_FRAME_PTR_ADDR 0x01 // W/R, cur_dec_ptr, bwd_ref_ptr, fwd_ref_ptr
+#define MVD_AVSD_TOP_PICT_START_ADDR 0x02 // W/R, is_2nd_fld, top_fild_1st, coding_type, pict_struct
+#define MVD_AVSD_TOP_PICT_PARAM_ADDR 0x03 // W/R
+
+//-- BSD Register address
+#define MVD_AVSD_BSD_SHOW_BITS_ADDR 0x40 // R, show available bits (up to 31), lsb aligned
+#define MVD_AVSD_BSD_DEC_STATUS_ADDR 0x41 // R, returns {1'b0, vld_mb_y, 1'b0, vld_mb_x, VldState, vld_error, img_in_prog, slice_in_prog}
+#define MVD_AVSD_BSD_BBB_STATUS_ADDR 0x42 // R, returns {6'd0, bits_ei_flag, bbb_underflow, 6'd0, bbb_is_stuffing, bits_ended, 10'd0, num_bits_in_bbb}
+#define MVD_AVSD_BSD_SCEPB_CTRL_ADDR 0x43 // W/R, {scepb_disab, scepb_delay}
+#define MVD_AVSD_BSD_EGDUE_START_ADDR 0x44 // R, start UE decode, [0]: ready in 3 ticks, [1]: out of range(dec not performed)
+#define MVD_AVSD_BSD_EGDSE_START_ADDR 0x45 // R, start SE decode, [0]: ready in 3 ticks, [1]: out of range(dec not performed)
+#define MVD_AVSD_BSD_SLC_START_ADDR 0x46 // W/R, {24'd0, vld_recover, vld_new_mbrow}
+#define MVD_AVSD_BSD_CURR_MBCOORD_ADDR 0x47 // R/W
+#define MVD_AVSD_BSD_EGD_VALUE_ADDR 0x48 // R, exp-golumn decode value
+#define MVD_AVSD_BSD_ERRCHK_MASK_ADDR 0x49 // R/W
+#define MVD_AVSD_BSD_ERROR_STAT_ADDR 0x4a // R, cleard at start of a slice
+
+#define MVD_AVSD_BSD_BYTE_ALIGN_ADDR 0x60
+#define MVD_AVSD_BSD_GETBITS_MIN_ADDR 0x60 // MVD_AVSD_BSD_ALIGN_BYTE_ADDR
+#define MVD_AVSD_BSD_GETBITS_MAX_ADDR 0x7f // 31 bits
+
+//-- MPR register address
+#define MVD_AVSD_MPR_WT_PARAM0_ADDR 0x80 // R/W
+#define MVD_AVSD_MPR_WT_PARAM1_ADDR 0x81 // R/W
+#define MVD_AVSD_MPR_WT_PARAM2_ADDR 0x82 // R/W
+#define MVD_AVSD_MPR_WT_PARAM3_ADDR 0x83 // R/W
+#define MVD_AVSD_MPR_BWD_DIST_ADDR 0x84 // when P picture, use bwd0,1 as fwd0,1
+#define MVD_AVSD_MPR_FWD_DIST_ADDR 0x85 // when P picture, use fwd0,1 as fwd2,3
+#define MVD_AVSD_MPR_REF01_DIST_ADDR 0x86
+#define MVD_AVSD_MPR_REF23_DIST_ADDR 0x87
+#define MVD_AVSD_MPR_BWD_DISTIDX_ADDR 0x88 // when P picture, use bwd0,1 as fwd0,1
+#define MVD_AVSD_MPR_FWD_DISTIDX_ADDR 0x89 // when P picture, use fwd0,1 as fwd2,3
+#define MVD_AVSD_MPR_REF01_DISTIDX_ADDR 0x8a
+#define MVD_AVSD_MPR_REF23_DISTIDX_ADDR 0x8b
+#define MVD_AVSD_MPR_CONFIG_OPTS_ADDR 0x8c
+
+typedef struct MvdHwRegAvsdMapTag {
+ //------- TOP address, 0x00 --> 0x3f
+ // 0x00 --> 0x3f
+ MvdHwReg top_seq_param;
+ MvdHwReg top_frame_ptr;
+ MvdHwReg top_pict_start;
+ MvdHwReg top_pict_param;
+ MvdHwReg unused_top[64-4];
+ //------- BSD address, 0x40 --> 0x7f
+ // 0x40 --> 0x5f
+ MvdHwReg bsd_show_bits;
+ MvdHwReg bsd_dec_status;
+ MvdHwReg bsd_bbb_status;
+ MvdHwReg bsd_scepb_ctrl;
+ MvdHwReg bsd_egdue_start;
+ MvdHwReg bsd_egdse_start;
+ MvdHwReg bsd_slc_start;
+ MvdHwReg bsd_curr_mbcoord;
+ MvdHwReg bsd_egd_value;
+ MvdHwReg bsd_errchk_mask;
+ MvdHwReg bsd_error_stat;
+ MvdHwReg bsd_qp_delta_uv;
+ MvdHwReg bsd_wqm1_low;
+ MvdHwReg bsd_wqm1_high;
+ MvdHwReg bsd_wqm2_low;
+ MvdHwReg bsd_wqm2_high;
+ MvdHwReg bsd_qp_ctr;
+ MvdHwReg unused_bsd[32-17];
+ //MvdHwReg unused_bsd[32-11];
+ // 0x60 --> 0x7f
+ union
+ {
+ MvdHwReg bsd_byte_align;
+ MvdHwReg bsd_getbits[32];
+ } get_bits;
+ //------- MPR address
+ // 0x80 --> 0xbf
+ MvdHwReg mpr_wt_param[4];
+ MvdHwReg mpr_bwd_dist;
+ MvdHwReg mpr_fwd_dist;
+ MvdHwReg mpr_ref01_dist;
+ MvdHwReg mpr_ref23_dist;
+ MvdHwReg mpr_bwd_distidx;
+ MvdHwReg mpr_fwd_distidx;
+ MvdHwReg mpr_ref01_distidx;
+ MvdHwReg mpr_ref23_distidx;
+ MvdHwReg mpr_config_opts;
+ MvdHwReg unused_mpr[64-13];
+ // 0xc0 --> 0x1bf not used
+ MvdHwReg unsued_spare[256];
+
+} MvdHwRegAvsdMap;
+
+/////////////////////////////////////////////////////////////////
+// ASPD/DIVX/JPEG Reg Map
+//
+
+//`define ASPD_APB_ADDR_TOP_PREFIX 3'h0 // 0x00
+//`define ASPD_APB_ADDR_BSD_PREFIX 3'h1 // 0x40
+//`define ASPD_APB_ADDR_MPR_PREFIX 3'h2 // 0x80
+//`define ASPD_APB_ADDR_PXD_PREFIX 3'h3 // 0xc0
+//`define ASPD_APB_ADDR_DBF_PREFIX 3'h4 // 0x100
+#define MVD_ASPD_TOP_MIN_ADDR 0x00
+#define MVD_ASPD_BSD_MIN_ADDR 0x40
+#define MVD_ASPD_MPR_MIN_ADDR 0x80
+#define MVD_ASPD_DBF_MIN_ADDR 0x100
+
+//-- Top level Register address
+#define MVD_ASPD_TOP_IMG_START_ADDR 0x00
+#define MVD_ASPD_TOP_VO_PARAM_ADDR 0x01
+#define MVD_ASPD_TOP_FRAME_PTR_ADDR 0x02 // W/R, cur_dec_ptr, bwd_ref_ptr, fwd_ref_ptr
+#define MVD_ASPD_TOP_VPARAM1_ADDR 0x03
+#define MVD_ASPD_TOP_VPARAM2_ADDR 0x04
+#define MVD_ASPD_TOP_VPARAM3_ADDR 0x05
+#define MVD_ASPD_TOP_VO_PARAM_EXT_ADDR 0x06
+
+//-- BSD Register address
+#define MVD_ASPD_BSD_SHOW_BITS_ADDR 0x40 // R, show available bits (up to 31), lsb aligned
+#define MVD_ASPD_BSD_DEC_STATUS_ADDR 0x41 // R, returns {1'b0, vld_mb_y, 1'b0, vld_mb_x, VldState, vld_error, img_in_prog, slice_in_prog}
+#define MVD_ASPD_BSD_BBB_STATUS_ADDR 0x42 // R, returns {6'd0, bits_ei_flag, bbb_underflow, 6'd0, bbb_is_stuffing, bits_ended, 10'd0, num_bits_in_bbb}
+#define MVD_ASPD_BSD_SLC_START_ADDR 0x46 // W/R, {24'd0, vld_recover, vld_new_mbrow}
+#define MVD_ASPD_BSD_CURR_MBCOORD_ADDR 0x47 // R/W
+#define MVD_ASPD_BSD_OPTIONS_ADDR 0x49 // R/W
+
+// JPEG DC Predictor registers
+#define MVD_ASPB_BSD_JPEG_CTX0_ADDR 0x4a // R/W, must be backup when doing multiple JPEG images
+#define MVD_ASPB_BSD_JPEG_CTX1_ADDR 0x4b // R/W, must be backup when doing multiple JPEG images
+
+#define MVD_ASPD_BSD_BYTE_ALIGN_ADDR 0x60
+#define MVD_ASPD_BSD_GETBITS_MIN_ADDR 0x60 // MVD_ASPD_BSD_ALIGN_BYTE_ADDR
+#define MVD_ASPD_BSD_GETBITS_MAX_ADDR 0x7f // 31 bits
+
+//-- MPR GMC register address
+#define MVD_ASPD_GMC_ATLUM_X0_ADDR 0x90 // R/W, atlum->X0, 18 bits, signed
+#define MVD_ASPD_GMC_ATLUM_Y0_ADDR 0x91 // R/W, atlum->Y0, 18 bits, signed
+#define MVD_ASPD_GMC_ATLUM_YXXX_ADDR 0x92 // R/W, {atlum->YX, atlum->XX}, 16 bits each, signed
+#define MVD_ASPD_GMC_ATLUM_XYYY_ADDR 0x93 // R/W, {atlum->XY, atlum->YY}, 16 bits each, signed
+#define MVD_ASPD_GMC_ATCHR_X0_ADDR 0x94 // R/W, atchr->X0, 28 bits, signed
+#define MVD_ASPD_GMC_ATCHR_Y0_ADDR 0x95 // R/W, atchr->Y0, 28 bits, signed
+#define MVD_ASPD_GMC_ATCHR_YXXX_ADDR 0x96 // R/W, {atchr->YX, atchr->XX}, 16 bits each, signed
+#define MVD_ASPD_GMC_ATCHR_XYYY_ADDR 0x97 // R/W, {atchr->XY, atchr->YY}, 16 bits each, signed
+#define MVD_ASPD_GMC_PARAM_ADDR 0x98 // R/W, {5'd0, fcode_gmc, 6'd0, warp_accuracy, 3'd0, atchr_shift, 3'd0, atlum_shift}
+
+#define MVD_ASPD_MPR_OPTS_ADDR 0x99 // R/W {26'b0,mpr_opts}
+
+#define ASPD_PXD_STATUS_ADDR 0xc0
+#define ASPD_PXD_QM_CTRL_ADDR 0xc1
+#define ASPD_PXD_WR_QMDATA_ADDR 0xc2
+
+//-- DBF registers -- these are the same as those for MP2D
+#define MVD_ASPD_DBF_CTRL0_ADDR 0x110 // Kevin Lim's POSTP_DEBLK_CTRL0
+#define MVD_ASPD_DBF_CTRL1_ADDR 0x111 // Kevin Lim's POSTP_DEBLK_CTRL1
+#define MVD_ASPD_DBF_CTRL2_ADDR 0x112 // Kevin Lim's POSTP_DEBLK_CTRL2
+#define MVD_ASPD_DBF_CTRL3_ADDR 0x113 // Kevin Lim's POSTP_DEBLK_CTRL3
+
+typedef struct MvdHwRegAspdMapTag
+{
+ //------- TOP address, 0x00 --> 0x3f
+ // 0x00 --> 0x3f
+ MvdHwReg top_img_start;
+ MvdHwReg top_vo_param;
+ MvdHwReg top_frame_ptr;
+ MvdHwReg top_vparam1;
+ MvdHwReg top_vparam2;
+ MvdHwReg top_vparam3;
+ MvdHwReg top_vo_param_ext;
+ MvdHwReg top_vparam4;
+ MvdHwReg top_vparam5;
+ MvdHwReg unused_top[64-9];
+ //------- BSD address, 0x40 --> 0x7f
+ // 0x40 --> 0x5f
+ MvdHwReg bsd_show_bits;
+ MvdHwReg bsd_dec_status;
+ MvdHwReg bsd_bbb_status;
+ MvdHwReg bsd_scepb_ctrl;
+ MvdHwReg unused_0x04;
+ MvdHwReg unused_0x05;
+ MvdHwReg bsd_slc_start;
+ MvdHwReg bsd_curr_mbcoord;
+ MvdHwReg unused_0x08;
+ MvdHwReg bsd_options;
+ MvdHwReg bsd_jpeg_ctx0;
+ MvdHwReg bsd_jpeg_ctx1;
+ MvdHwReg unused_bsd[32-12];
+ // 0x60 --> 0x7f
+ union
+ {
+ MvdHwReg bsd_byte_align;
+ MvdHwReg bsd_getbits[32];
+ } get_bits;
+ //------- MPR/PXD/GMC address
+ // 0x80 --> 0xbf
+ MvdHwReg unused_mpr16[16];
+ MvdHwReg gmc_atlum_x0;
+ MvdHwReg gmc_atlum_y0;
+ MvdHwReg gmc_atlum_yxxx;
+ MvdHwReg gmc_atlum_xyyy;
+ MvdHwReg gmc_atchr_x0;
+ MvdHwReg gmc_atchr_y0;
+ MvdHwReg gmc_atchr_yxxx;
+ MvdHwReg gmc_atchr_xyyy;
+ MvdHwReg gmc_param;
+ MvdHwReg mpr_opts;
+ MvdHwReg unused_mpr38[64-16-10];
+ // 0xc0 --> 0xff
+ MvdHwReg pxd_qm_status;
+ MvdHwReg pxd_qm_ctrl;
+ MvdHwReg pxd_qm_data;
+ MvdHwReg unused_pxd61[61];
+ //------- DBF address
+ // 0x100 --> 0x17f
+ MvdHwReg unused_dbf16[16];
+ MvdHwReg dbf_ctrl0;
+ MvdHwReg dbf_ctrl1;
+ MvdHwReg dbf_ctrl2;
+ MvdHwReg dbf_ctrl3;
+ MvdHwReg unused_dbf108[108];
+ // 0x180 --> 0x1bf not used
+ MvdHwReg dbg_a;
+ MvdHwReg dbg_b;
+ MvdHwReg dbg_arb_wr;
+ MvdHwReg dbg_arb_rd;
+ MvdHwReg dbg_arb_mbi;
+ MvdHwReg unsued_spare[59];
+
+} MvdHwRegAspdMap;
+
+/////////////////////////////////////////////////////////////////
+// On2 Reg Map
+//
+
+typedef struct MvdHwRegOn2dMapTag {
+ //------- TOP address, 0x00 --> 0x3f
+ // 0x00 --> 0x3f
+ MvdHwReg top_img_start;
+ MvdHwReg top_param1;
+ MvdHwReg top_frame_ptr;
+ MvdHwReg top_param2;
+ MvdHwReg top_param3;
+ MvdHwReg top_param4;
+ MvdHwReg top_param5;
+ MvdHwReg top_param6;
+ MvdHwReg top_param7;
+ MvdHwReg top_param8;
+ MvdHwReg top_param9;
+ MvdHwReg top_param10;
+ MvdHwReg top_param11;
+ MvdHwReg top_param12;
+ MvdHwReg top_param13;
+ MvdHwReg top_param14;
+ MvdHwReg top_param15;
+ MvdHwReg top_param16;
+ MvdHwReg top_param17;
+ MvdHwReg top_param18;
+ MvdHwReg top_param19;
+ MvdHwReg top_param20;
+ MvdHwReg top_param21;
+ MvdHwReg top_param22;
+ MvdHwReg top_param23;
+ MvdHwReg top_param24;
+ MvdHwReg top_param25;
+ MvdHwReg top_param26;
+ MvdHwReg unused_top[64-28];
+
+ //------- BSD address, 0x40 --> 0x7f
+ // 0x40 --> 0x5f
+ MvdHwReg bsd_show_bits;
+ MvdHwReg bsd_dec_status;
+ MvdHwReg bsd_bbb_status;
+ MvdHwReg unused_0x03;
+ MvdHwReg bsd_mbd_status;
+ MvdHwReg unused_0x05;
+ MvdHwReg bsd_slc_start;
+ MvdHwReg bsd_curr_mbcoord;
+ MvdHwReg unused_0x08;
+ MvdHwReg bsd_options;
+ MvdHwReg bsd_arith_config;
+ MvdHwReg unused_0x0B;
+ MvdHwReg bsd_scan_start;
+ MvdHwReg bsd_scan_data;
+ MvdHwReg bsd_prob_start;
+ MvdHwReg bsd_prob_data;
+ MvdHwReg bsd_prob_status;
+ MvdHwReg unused_0x11;
+ MvdHwReg unused_0x12;
+ MvdHwReg unused_0x13;
+ MvdHwReg unused_0x14;
+ MvdHwReg unused_0x15;
+ MvdHwReg unused_0x16;
+ MvdHwReg unused_0x17;
+ MvdHwReg debug_status;
+ MvdHwReg debug_data0;
+ MvdHwReg debug_data1;
+ MvdHwReg unused_bsd[32-27];
+ // 0x60 --> 0x7f
+ union
+ {
+ MvdHwReg bsd_byte_align;
+ MvdHwReg bsd_getbits[32];
+ } get_bits;
+ // the rest are not used
+} MvdHwRegOn2dMap;
+
+/////////////////////////////////////////////////////////////////
+// RVid Reg Map
+//
+
+typedef struct MvdHwRegRvidMapTag
+{
+ //------- TOP address, 0x00 --> 0x3f
+ // 0x00 --> 0x3f
+ MvdHwReg top_img_start;
+ MvdHwReg top_param1;
+ MvdHwReg top_frame_ptr;
+ MvdHwReg top_param2;
+ MvdHwReg top_param3;
+ MvdHwReg top_param4;
+ MvdHwReg unused_top[64-6];
+
+ //------- BSD address, 0x40 --> 0x7f
+ // 0x40 --> 0x5f
+ MvdHwReg bsd_show_bits;
+ MvdHwReg bsd_dec_status;
+ MvdHwReg bsd_bbb_status;
+ MvdHwReg unused_0x03;
+ MvdHwReg bsd_mbd_status;
+ MvdHwReg unused_0x05;
+ MvdHwReg bsd_slc_start;
+ MvdHwReg bsd_curr_mbcoord;
+ MvdHwReg unused_0x08;
+ MvdHwReg bsd_options;
+ MvdHwReg bsd_rsb_missing;
+ MvdHwReg bsd_mb_qp;
+ MvdHwReg unused_bsd[32-12];
+ // 0x60 --> 0x7f
+ union
+ {
+ MvdHwReg bsd_byte_align;
+ MvdHwReg bsd_getbits[32];
+ } get_bits;
+ // the rest are not used
+} MvdHwRegRvidMap;
+
+/////////////////////////////////////////////////////////////////
+// HEVC Reg Map
+//
+
+typedef struct MvdHwRegHevcMapTag
+{
+
+ /* TOP address, 0x00 --> 0x3f */
+ MvdHwReg image_config; // R/W
+ MvdHwReg slice_config; // R/W
+ MvdHwReg top_ctb_tile_info; // R/W
+ MvdHwReg mbi_wr_base; // R/W
+ MvdHwReg mbi_rd_base; // R/W
+
+ MvdHwReg dec_cfg; // R/W
+ MvdHwReg dbg_cfg; // R/W
+ MvdHwReg dbf1_cfg; // R/W
+ MvdHwReg dbf2_cfg; // R/W
+ MvdHwReg dbe_frm_size; // R/W
+ MvdHwReg prb_pack_base; // R/W
+ MvdHwReg prb_bin_cfg; // R/W
+ MvdHwReg dcp_bin_cfg; // R/W
+
+ MvdHwReg unused_top[64-13];
+
+ /* BSD address, 0x40 --> 0x7f */
+ MvdHwReg bsd_options;
+ MvdHwReg bsd_dec_status;
+ MvdHwReg bsd_ctb_coord;
+ MvdHwReg bsd_slice_start;
+ MvdHwReg bsd_dec_param1;
+ MvdHwReg bsd_dec_param2;
+ MvdHwReg bsd_dec_ctb_cnt;
+ MvdHwReg bsd_dec_err_ctb_cnt;
+ MvdHwReg bsd_dec_ctb_qp_sum;
+
+ MvdHwReg bsd_plq_levels;
+ MvdHwReg Unused_A;
+
+ MvdHwReg bsd_ue;
+ MvdHwReg bsd_se;
+ MvdHwReg Unused_D;
+ MvdHwReg Unused_E;
+ MvdHwReg bsd_data;
+
+ MvdHwReg Unused_10;
+ MvdHwReg bsd_ctb_tile_px4;
+ MvdHwReg bsd_ctb_tile_py4;
+ MvdHwReg bsd_ctb_tile_px8;
+ MvdHwReg bsd_ctb_tile_py8;
+ MvdHwReg bsd_ctb_tile_px9_y10;
+ MvdHwReg bsd_sc_list_usage;
+ MvdHwReg bsd_sc_list_base;
+ MvdHwReg bsd_sc_list_idx[4];
+ MvdHwReg bsd_ei_flags_mask;
+ MvdHwReg bsd_bit_puller;
+ MvdHwReg bsd_is_trailing;
+ MvdHwReg bsd_bbb_status;
+
+ union
+ {
+ MvdHwReg bsd_byte_align;
+ MvdHwReg bsd_getbits[32];
+ } get_bits;
+
+ /* MPR address, 0x80 --> 0xBF */
+ MvdHwReg mpr_config;
+ MvdHwReg mpr_slice_param;
+
+ MvdHwReg Unused_82_9F[30];
+
+ MvdHwReg mpr_list[32];
+
+ MvdHwReg Unused_0xC0_FF[64];
+
+ /* dfe address, 0x100 --> 0x103 */
+ MvdHwReg dfe_status;
+ MvdHwReg dfe_num_pr_bits;
+ MvdHwReg dfe_row_crc;
+ MvdHwReg dfe_num_bins_used;
+ MvdHwReg Unused_DFE[60];
+
+ MvdHwReg Unused_0x140_17F[64];
+
+ MvdHwReg mpr_dbg;
+ MvdHwReg pxd_dbg;
+ MvdHwReg dbf_dbg;
+ MvdHwReg wr_arb_dbg;
+ MvdHwReg rd_arb_dbg;
+ MvdHwReg mbi_rd_arb_dbg;
+ MvdHwReg mbi_wr_arb_dbg;
+ MvdHwReg Unused_DBG[64-7];
+
+} MvdHwRegHevcMap;
+
+///////////////////////////////////////////////////////////////////////////////////////
+// Top address mapping struct
+//
+// The base decoder address to be passed should be that of the HIF registers
+// not the RSB registers
+//
+// Minor non-backwards compatible address map change between Kronos
+// and Krome...
+
+/* *********************************************************** */
+/* Kronos */
+/* */
+/* MvdHwReg hif[1024]; */
+/* MvdHwReg sif[128]; */
+/* MvdHwReg ctx[128]; */
+/* MvdHwReg rpr[32]; */
+/* MvdHwReg unused[32]; */
+/* MvdHwReg bbd[32]; -- BL only -- */
+/* MvdHwReg dbg[32]; -- EL only -- */
+/* MvdHwReg spp[128]; */
+/* MvdHwReg dec[512-64]; */
+/* */
+/* *********************************************************** */
+
+/* *********************************************************** */
+/* Krome */
+/* */
+/* Base Malone: Enhancement Malone */
+/* */
+/* MvdHwReg hif[1024]; MvdHwReg hif[1024]; */
+/* MvdHwReg sif[128]; MvdHwReg sif[128]; */
+/* MvdHwReg ctx[128]; MvdHwReg ctx[128]; */
+/* MvdHwReg rpr[32]; MvdHwReg rpr[32]; */
+/* MvdHwReg unused[32]; MvdHwReg unused[32]; */
+/* MvdHwReg bbd[32]; MvdHwReg dbg[32]; */
+/* MvdHwReg cq[32]; MvdHwReg cq[32]; */
+/* MvdHwReg spp[128]; MvdHwReg spp[128]; */
+/* MvdHwReg dec[512-64]; MvdHwReg dec[512-64]; */
+/* */
+/* *********************************************************** */
+
+typedef struct MvdHwRegMapTag
+{
+ //------------- 8KB MSD address -------------
+ /* 4KB HIF address space */
+ union
+ {
+ MvdHwReg hif[1024];
+ MvdHwRegHifMap hif_map;
+ } HifMap;
+
+ /* 0.5KB SIF address space */
+ union
+ {
+ MvdHwReg sif[128];
+ MvdHwRegSifMap sif_map;
+ } SifMap;
+
+ /* 0.5KB CTX address space */
+ union
+ {
+ MvdHwReg ctx[128];
+ MvdHwRegCtxMap ctx_map;
+ } CtxMap;
+
+ /* 128 B RPR address space */
+ union
+ {
+ MvdHwReg rpr[32];
+ MvdHwRegRprMap rpr_map;
+ } RprMap;
+
+ /* 128 B RC4 address space */
+ union
+ {
+ MvdHwReg RC4[32];
+ MvdHwRegRC4Map RC4_map;
+ } RC4Map;
+
+ /* 128 B DBG address space */
+ union
+ {
+ MvdHwReg dbg[32];
+ MvdHwRegDbgMap dbg_map;
+ } DbgMap;
+
+ /* 128 B CQ address space */
+ union
+ {
+ MvdHwReg cq[32];
+ MvdHwRegCqMap cq_map;
+ MvdHwRegDbgMap dbg_map;
+ } CqMap;
+
+ /* 0.5KB SPP address space */
+ union
+ {
+ MvdHwReg spp[128];
+ MvdHwRegSppMap spp_map;
+ } SppMap;
+
+ /* 1.75KB decoder address space */
+ union
+ {
+ MvdHwReg dec[512-64];
+ MvdHwRegH264Map h264_map;
+ MvdHwRegVc1dMap vc1d_map;
+ MvdHwRegMp2dMap mp2d_map;
+ MvdHwRegAvsdMap avsd_map;
+ MvdHwRegAspdMap aspd_map;
+ MvdHwRegRvidMap rvid_map;
+ MvdHwRegOn2dMap on2d_map;
+ MvdHwRegHevcMap hevc_map;
+ } DecMap;
+
+ /* 0.25kB BBD address space */
+ union
+ {
+ MvdHwReg bbd[64];
+ MvdHwRegBbdMap bbd_map;
+ MvdHwRegDbgMap dbg_map;
+ } BbdMap;
+
+ /* 4KB Decoupled unit space */
+ union
+ {
+ MvdHwReg dcp[1024];
+ MvdHwRegDfeMap dfe_map;
+ MvdHwRegDbeMap dbe_map[2];
+ } DcpMap;
+
+ /* 0.25 KB FBC address space */
+ union
+ {
+ MvdHwReg fbc[64];
+ MvdHwRegFbcMap fbc_map;
+ } FbcMap;
+
+ /* 3.75 KB Special address */
+ MvdHwReg spc[1024 - 64];
+
+} MvdHwRegMap;
+
+///////////////////////////////////////////////////////////////////////////////////////
+// DPV address map
+//
+
+typedef struct
+{
+ MvdHwReg YFrameCRC;
+ MvdHwReg YTopFieldCRC;
+ MvdHwReg YBotFieldCRC;
+ MvdHwReg UVFrameCRC;
+ MvdHwReg UVTopFieldCRC;
+ MvdHwReg UVBotFieldCRC;
+
+} MvdHwRegA3CRCRegMap;
+
+
+typedef struct
+{
+ MvdHwReg YWordLower;
+ MvdHwReg UWordLower;
+ MvdHwReg VWordLower;
+ MvdHwReg YWordUpper;
+ MvdHwReg UWordUpper;
+ MvdHwReg VWordUpper;
+
+} MvdHwRegMD5RegMap;
+
+typedef struct
+{
+ MvdHwReg YFrameCRC;
+ MvdHwReg UFrameCRC;
+ MvdHwReg VFrameCRC;
+
+} MvdHwRegHashCRCRegMap;
+
+typedef struct
+{
+ MvdHwReg YCheckSum;
+ MvdHwReg UCheckSum;
+ MvdHwReg VCheckSum;
+
+} MvdHwRegHashChkSumRegMap;
+
+typedef struct
+{ //DCSN_CFG_BASE_MMIO | 0x1FC000 => 0xE07FC000
+ MvdHwReg Control;
+ MvdHwReg Status;
+ MvdHwReg DTLReadCalib;
+ MvdHwReg CropTopLeft;
+ MvdHwReg CropBotRight;
+ MvdHwReg LumaBase;
+ MvdHwReg ChromaBase;
+
+ union
+ {
+ MvdHwReg Digest[0x6];
+ MvdHwRegA3CRCRegMap A3CRC;
+ MvdHwRegMD5RegMap MD5;
+ MvdHwRegHashCRCRegMap HashCRC;
+ MvdHwRegHashChkSumRegMap HashCheckSum;
+
+ } DigestMap0;
+
+ MvdHwReg Stride;
+
+ /* For code readability - this is added as a union */
+ /* but in fact the registers are valid only in MD5 mode */
+ union
+ {
+ MvdHwReg Digest[0x6];
+ MvdHwRegA3CRCRegMap A3CRC;
+ MvdHwRegMD5RegMap MD5;
+ MvdHwRegHashCRCRegMap HashCRC;
+ MvdHwRegHashChkSumRegMap HashCheckSum;
+
+ } DigestMap1;
+
+ MvdHwReg Scratch[0x4];
+
+} MvdHwDPVRegMap;
+
+#endif /* _MVD_REG_MAP_H_ */
+
+/* End of file */
diff --git a/drivers/mxc/vpu_legacy/Malone_Firmware/DecKLib/Incl/mvd_sif_control.h b/drivers/mxc/vpu_legacy/Malone_Firmware/DecKLib/Incl/mvd_sif_control.h
new file mode 100755
index 000000000000..80dc48d6f40d
--- /dev/null
+++ b/drivers/mxc/vpu_legacy/Malone_Firmware/DecKLib/Incl/mvd_sif_control.h
@@ -0,0 +1,975 @@
+/***************************************************
+ Copyright (c) 2015 Amphion Semiconductor Ltd
+ All rights reserved.
+ ***************************************************
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ ****************************************************
+
+ Filename: mvd_sif_control.h
+ Description: Malone system interface
+ Notes:
+
+ ****************************************************/
+
+#ifndef _MVD_SIF_CONTROL_H_
+#define _MVD_SIF_CONTROL_H_
+
+/////////////////////////////////////////////////////////////////////////////////
+// Header files
+/////////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////////
+// Global Macros
+/////////////////////////////////////////////////////////////////////////////////
+
+// SIF data range definitions
+#define MSD_SIF_FS_KBYTES_BITS(r) (((r)&0xFFFF0000)>>16)
+#define MSD_SIF_FRAME_SIZE_MB_BITS(r) ((r)&0xFFFF)
+#define MSD_PUT_SIF_FRAME_SIZE_MB_BITS(w) ((w)&0xFFFF)
+#define MSD_PUT_SIF_FS_KBYTES_BITS(w) (((w)&0xFFFF)<<16)
+
+#define MSD_PUT_FRAME_WIDTH_MB_BITS(w) ((w)&0xFF)
+#define MSD_PUT_FRAME_HEIGHT_MB_BITS(w) (((w)&0xFF)<<8)
+#define MSD_PUT_FRAME_SIZE_MB_BITS(w) (((w)&0xFFFF)<<16)
+
+#define MSD_DPB_IN_KBYTES_BITS(r) ((r)&0xFFFF)
+
+#define MPD_SIF_DISP_Q_CNT_BITS(r) ((r)&0xFF)
+#define MPD_SIF_DISP_Q_FULL_BITS(r) ((r>>8)&0x1)
+#define MPD_SIF_DISP_Q_REQ_BIT(r) ((r>>16)&0x1)
+
+#define MPD_SIF_DISP_Q_PUSH_FS_IDC_BITS(w) ((w)&0x1F)
+#define MPD_SIF_DISP_Q_PUSH_SPS_IDC_BITS(w) (((w)&0x7)<<16)
+#define MPD_SIF_DISP_Q_PUSH_DANG_FIELD_BIT(w) (((w)&0x1)<<19)
+#define MPD_SIF_DISP_Q_PUSH_FIELD_MODE_BIT(w) (((w)&0x2)<<19)
+#define MPD_SIF_DISP_Q_PUSH_BOT_FIRST_BIT(w) (((w)&0x1)<<21)
+#define MPD_SIF_DISP_Q_PUSH_SKIP_PIC_BITS(w) (((w)&0x3)<<22)
+#define MPD_SIF_DISP_Q_SYS_DATA_BITS(w) (((w)&0xFF)<<24)
+
+#define MPD_SIF_DISP_Q_PUSH_CRC_MODE_BIT(w) (((w)&0x1)<<20)
+
+#define MPD_SIF_FS_PACK_UNIT_BITS(r) ((r)&0x7)
+#define MPD_SIF_FS_BASE_UNIT_BITS(r) ((r>>12)&0x7)
+#define MPD_SIF_SYS_DATA_EDGE_BIT(r) ((r>>16)&0x1)
+#define MPD_SIF_BS_SYNC_USED_BIT(r) ((r>>17)&0x1)
+
+#define MPD_SIF_SYS_DATA_BITS(r) ((r)&0xFF)
+
+#define MPD_SIF_FRAME_DEC_IRQ_POS 1
+#define MPD_SIF_SLICE_DEC_IRQ_POS 2
+#define MPD_SIF_START_CODE_IRQ_POS 3
+#define MPD_SIF_SEMAPHORE_IRQ_BIT(r) ((r)&0x1)
+#define MPD_SIF_FRAME_DEC_IRQ_BIT(r) (((r)&0x2)>>1)
+#define MPD_SIF_SLICE_DEC_IRQ_BIT(r) (((r)&0x4)>>2)
+#define MPD_SIF_START_CODE_IRQ_BIT(r) (((r)&0x8)>>3)
+
+
+#define MSD_SIF_QPULL_IRQ_BIT(r) (((r)&0x10)>>4)
+#define MSD_SIF_QPULL_SHIFT 4
+#define MSD_SIF_QPULL_MASK 0x10
+#define MPD_SIF_BSDMA_IRQ_BIT(r) (((r)&0x80)>>7)
+#define PUT_MSD_STREAM_ID(w) ((w)&0xF)
+#define PUT_MSD_FORMAT(w) (((w)&0x3)<<4)
+
+// Sempahore reg bits
+#define FRAME_DISPLAYED_BITS(r) ((r)&0x1)
+
+// MSD_SIF_DPB_FS_SIZE_ADDR
+#define MSD_SIF_DPB_FS_WIDTH_IN_MB_POS 0
+#define MSD_SIF_DPB_FS_WIDTH_IN_MB_SIZE 8
+#define MSD_SIF_DPB_FS_WIDTH_IN_MB_MASK 0xff
+#define MSD_SIF_DPB_FS_HEIGHT_IN_MB_POS 8
+#define MSD_SIF_DPB_FS_HEIGHT_IN_MB_SIZE 8
+#define MSD_SIF_DPB_FS_HEIGHT_IN_MB_MASK 0xff
+#define MSD_SIF_DPB_FS_SIZE_KBYTES_POS 16
+#define MSD_SIF_DPB_FS_SIZE_KBYTES_SIZE 14
+#define MSD_SIF_DPB_FS_SIZE_KBYTES_MASK 0x3fff
+#define MSD_SIF_DPB_FS_SIZE_WIDTH_INMBS_GET(val) ((val>>MSD_SIF_DPB_FS_WIDTH_IN_MB_POS)&MSD_SIF_DPB_FS_WIDTH_IN_MB_MASK)
+#define MSD_SIF_DPB_FS_SIZE_HEIGHT_INMBS_GET(val) ((val>>MSD_SIF_DPB_FS_HEIGHT_IN_MB_POS)&MSD_SIF_DPB_FS_HEIGHT_IN_MB_MASK)
+#define MSD_SIF_DPB_FS_SIZE_KBYTES(val) ((val>>MSD_SIF_DPB_FS_SIZE_KBYTES_POS)&MSD_SIF_DPB_FS_SIZE_KBYTES_MASK)
+
+// MSD_SIF_DPB_FS_SIZE_EXT_ADDR
+#define MSD_SIF_DPB_FS_WIDTH_IN_MB_EXT_POS 0
+#define MSD_SIF_DPB_FS_WIDTH_IN_MB_EXT_SIZE 2
+#define MSD_SIF_DPB_FS_WIDTH_IN_MB_EXT_MASK 0x3
+#define MSD_SIF_DPB_FS_HEIGHT_IN_MB_EXT_POS 2
+#define MSD_SIF_DPB_FS_HEIGHT_IN_MB_EXT_SIZE 2
+#define MSD_SIF_DPB_FS_HEIGHT_IN_MB_EXT_MASK 0x3
+#define MSD_SIF_DPB_FS_SIZE_KBYTES_EXT_POS 4
+#define MSD_SIF_DPB_FS_SIZE_KBYTES_EXT_SIZE 3
+#define MSD_SIF_DPB_FS_SIZE_KBYTES_EXT_MASK 0x7
+#define MSD_SIF_DPB_FS_SIZE_WIDTH_INMBS_EXT_GET(val) ((val>>MSD_SIF_DPB_FS_WIDTH_IN_MB_POS)&MSD_SIF_DPB_FS_WIDTH_IN_MB_EXT_MASK)
+#define MSD_SIF_DPB_FS_SIZE_HEIGHT_INMBS_EXT_GET(val) ((val>>MSD_SIF_DPB_FS_HEIGHT_IN_MB_POS)&MSD_SIF_DPB_FS_HEIGHT_IN_MB_EXT_MASK)
+#define MSD_SIF_DPB_FS_SIZE_KBYTES_EXT(val) ((val>>MSD_SIF_DPB_FS_SIZE_KBYTES_POS)&MSD_SIF_DPB_FS_SIZE_KBYTES_MASK)
+
+//MSD_SIF_DPB_FRM_SIZE_ADDR
+#define MSD_SIF_DPB_FRM_WIDTH_IN_MB_POS 0
+#define MSD_SIF_DPB_FRM_WIDTH_IN_MB_SIZE 8
+#define MSD_SIF_DPB_FRM_WIDTH_IN_MB_MASK 0xff
+#define MSD_SIF_DPB_FRM_HEIGHT_IN_MB_POS 8
+#define MSD_SIF_DPB_FRM_HEIGHT_IN_MB_SIZE 8
+#define MSD_SIF_DPB_FRM_HEIGHT_IN_MB_MASK 0xff
+#define MSD_SIF_DPB_FRM_SIZE_MBS_POS 16
+#define MSD_SIF_DPB_FRM_SIZE_MBS_SIZE 16
+#define MSD_SIF_DPB_FRM_SIZE_MBS_MASK 0xffff
+#define MSD_SIF_DPB_FRM_SIZE_INMBS(val) ((val>>MSD_SIF_DPB_FRM_SIZE_MBS_POS)&MSD_SIF_DPB_FRM_SIZE_MBS_MASK)
+#define MSD_SIF_DPB_FRM_WIDTH_INMBS_GET(val) ((val>>MSD_SIF_DPB_FRM_WIDTH_IN_MB_POS)&MSD_SIF_DPB_FRM_WIDTH_IN_MB_MASK)
+#define MSD_SIF_DPB_FRM_HEIGHT_INMBS_GET(val) ((val>>MSD_SIF_DPB_FRM_HEIGHT_IN_MB_POS)&MSD_SIF_DPB_FRM_HEIGHT_IN_MB_MASK)
+
+//MSD_SIF_DPB_FRM_SIZE_EXT_ADDR
+#define MSD_SIF_DPB_FRM_WIDTH_IN_MB_EXT_POS 0
+#define MSD_SIF_DPB_FRM_WIDTH_IN_MB_EXT_SIZE 1
+#define MSD_SIF_DPB_FRM_WIDTH_IN_MB_EXT_MASK 0x1
+#define MSD_SIF_DPB_FRM_HEIGHT_IN_MB_EXT_POS 1
+#define MSD_SIF_DPB_FRM_HEIGHT_IN_MB_EXT_SIZE 1
+#define MSD_SIF_DPB_FRM_HEIGHT_IN_MB_EXT_MASK 0x1
+#define MSD_SIF_DPB_FRM_SIZE_MBS_EXT_POS 2
+#define MSD_SIF_DPB_FRM_SIZE_MBS_EXT_SIZE 3
+#define MSD_SIF_DPB_FRM_SIZE_MBS_EXT_MASK 0x7
+#define MSD_SIF_DPB_FRM_SIZE_INMBS_EXT(val) ((val>>MSD_SIF_DPB_FRM_SIZE_MBS_POS)&MSD_SIF_DPB_FRM_WIDTH_IN_MB_EXT_MASK)
+#define MSD_SIF_DPB_FRM_WIDTH_INMBS_EXT_GET(val) ((val>>MSD_SIF_DPB_FRM_WIDTH_IN_MB_POS)&MSD_SIF_DPB_FRM_HEIGHT_IN_MB_EXT_MASK)
+#define MSD_SIF_DPB_FRM_HEIGHT_INMBS_EXT_GET(val) ((val>>MSD_SIF_DPB_FRM_HEIGHT_IN_MB_POS)&MSD_SIF_DPB_FRM_SIZE_MBS_EXT_MASK)
+#define MSD_PUT_FRAME_WIDTH_MB_EXT_BITS(val) (((val>>8)&MSD_SIF_DPB_FRM_WIDTH_IN_MB_EXT_MASK)<<MSD_SIF_DPB_FRM_WIDTH_IN_MB_EXT_POS)
+#define MSD_PUT_FRAME_HEIGHT_MB_EXT_BITS(val) (((val>>8)&MSD_SIF_DPB_FRM_HEIGHT_IN_MB_EXT_MASK)<<MSD_SIF_DPB_FRM_HEIGHT_IN_MB_EXT_POS)
+#define MSD_PUT_FRAME_SIZE_MB_EXT_BITS(val) (((val>>16)&MSD_SIF_DPB_FRM_SIZE_MBS_EXT_MASK)<<MSD_SIF_DPB_FRM_SIZE_MBS_EXT_POS)
+
+
+//MSD_SIF_DPB_FS_SETTING_ADDR
+#define MSD_SIF_FS_PACK_UNIT_POS 0
+#define MSD_SIF_FS_PACK_UNIT_SIZE 3
+#define MSD_SIF_FS_PACK_UNIT(val) ((val>>MSD_SIF_FS_PACK_UNIT_POS)&0x7)
+#define MSD_SIF_FS_PACK_WIDTH_POS 4
+#define MSD_SIF_FS_PACK_WIDTH_SIZE 3
+#define MSD_SIF_FS_PACK_ID (1<<8)
+#define MSD_SIF_FRM_SYNC_EDGE (1<<16)
+#define MSD_SIF_BS_SYNC_USED (1<<17)
+#define MSD_SIF_FS_BASE_UNIT_POS 12
+#define MSD_SIF_FS_BASE_UNIT(val) ((val>>MSD_SIF_FS_BASE_UNIT_POS)&0x7)
+
+// Standard pack unit sizes
+#define SIF_SPB_BASE_UNITS_1KBYTES 0x4
+#define SIF_SPB_BASE_UNITS_2KBYTES 0x5
+#define SIF_SPB_BASE_UNITS_4KBYTES 0x6
+#define SIF_SPB_BASE_UNITS_8KBYTES 0x7
+
+//MSD_SIF_DPB_OFFSET_ADDR
+//MSD_SIF_FRM_SYNC_DATA_ADDR
+//MSD_SIF_FRM_DANGLING_ADDR
+
+//MSD_SIF_DPB_CONFIG_ADDR
+#define MSD_SIF_DPB_LUT_ENAB (1<<0)
+#define MSD_SIF_DPB_LUT_ADDR_MSB (1<<1)
+#define MSD_SIF_DPB_USE_FS_IDC (1<<2)
+#define MSD_SIF_DPB_RSHIFT_CA_POS 3
+#define MSD_SIF_DPB_RSHIFT_CA_SIZE 3
+
+//MSD_SIF_DPB_LUT_LOAD_ADDR
+#define MSD_SIF_DPB_LUT_VALUE_POS 0
+#define MSD_SIF_DPB_LUT_VALUE_SIZE 20
+#define MSD_SIF_DPB_LUT_ADDR_POS 24
+#define MSD_SIF_DPB_LUT_ADDR_SIZE 6
+
+//MSD_SIF_LOAD_DPB_NUMB_ADDR
+#define MSD_SIF_LOAD_DPB_NUMB_NUMB_POS 0
+#define MSD_SIF_LOAD_DPB_NUMB_NUMB_SIZE 5
+#define MSD_SIF_LOAD_DPB_NUMB_NUMB(val) ((val>>MSD_SIF_LOAD_DPB_NUMB_NUMB_POS)&0x1f)
+#define MSD_SIF_LOAD_DPB_NUMB_SID_POS 12
+#define MSD_SIF_LOAD_DPB_NUMB_SID_SIZE 4
+
+//MSD_SIF_DEC_STATUS_ADDR
+#define MSD_SIF_DEC_STATUS_SLC_PROG_POS 0
+#define MSD_SIF_DEC_STATUS_SLC_PROG_SIZE 1
+#define MSD_SIF_DEC_STATUS_SLC_PROG(val) ((val>>MSD_SIF_DEC_STATUS_SLC_PROG_POS)&0x1)
+
+#define MSD_SIF_DEC_STATUS_IMG_PROG_POS 1
+#define MSD_SIF_DEC_STATUS_IMG_PROG_SIZE 1
+#define MSD_SIF_DEC_STATUS_IMG_PROG(val) ((val>>MSD_SIF_DEC_STATUS_IMG_PROG_POS)&0x1)
+
+#define MSD_SIF_DEC_STATUS_FRM_PROG_POS 2
+#define MSD_SIF_DEC_STATUS_FRM_PROG_SIZE 1
+#define MSD_SIF_DEC_STATUS_FRM_PROG(val) ((val>>MSD_SIF_DEC_STATUS_FRM_PROG_POS)&0x1)
+
+#define MSD_SIF_DEC_STATUS_VPMD_BUSY_POS 3
+#define MSD_SIF_DEC_STATUS_VPMD_BUSY_SIZE 1
+#define MSD_SIF_DEC_STATUS_VPMD_BUSY(val) ((val>>MSD_SIF_DEC_STATUS_VPMD_BUSY_POS)&0x1)
+
+#define MSD_SIF_DEC_STATUS_VDBF_BUSY_POS 4
+#define MSD_SIF_DEC_STATUS_VDBF_BUSY_SIZE 1
+#define MSD_SIF_DEC_STATUS_VDBF_BUSY(val) ((val>>MSD_SIF_DEC_STATUS_VDBF_BUSY_POS)&0x1)
+
+#define MSD_SIF_DEC_STATUS_XOB_IDLE_POS 5
+#define MSD_SIF_DEC_STATUS_XOB_IDLE_SIZE 1
+#define MSD_SIF_DEC_STATUS_XOB_IDLE(val) ((val>>MSD_SIF_DEC_STATUS_XOB_IDLE_POS)&0x1)
+
+#define MSD_SIF_DEC_STATUS_DPBMC_IDLE_POS 6
+#define MSD_SIF_DEC_STATUS_DPBMC_IDLE_SIZE 1
+#define MSD_SIF_DEC_STATUS_DPBMC_IDLE(val) ((val>>MSD_SIF_DEC_STATUS_DPBMC_IDLE_POS)&0x1)
+
+#define MSD_SIF_DEC_STATUS_BS_EMPTY_POS 7
+#define MSD_SIF_DEC_STATUS_BS_EMPTY_SIZE 1
+#define MSD_SIF_DEC_STATUS_BS_EMPTY(val) ((val>>MSD_SIF_DEC_STATUS_BS_EMPTY_POS)&0x1)
+
+/* From Kronos Rev.B */
+#define MSD_SIF_DEC_STATUS_MBQ_STAT_POS 8
+#define MSD_SIF_DEC_STATUS_MBQ_STAT_SIZE 2
+#define MSD_SIF_DEC_STATUS_MBQ_STAT(val) ((val>>MSD_SIF_DEC_STATUS_MBQ_STAT_POS)&0x3)
+
+#define MSD_SIF_DEC_STATUS_MPR_FIFO_POS 10
+#define MSD_SIF_DEC_STATUS_MPR_FIFO_SIZE 6
+
+#define MSD_SIF_DEC_STATUS_MPR_FIFOS_NEMPTY_POS 16
+#define MSD_SIF_DEC_STATUS_MPR_FIFOS_NEMPTY_SIZE 1
+
+#define MSD_SIF_DEC_STATUS_VMIF_CLSET_IDLE_POS 17
+#define MSD_SIF_DEC_STATUS_VMIF_CLSET_IDLE_SIZE 2
+
+#define MSD_SIF_DEC_STATUS_PIXIF_IDLE_POS 19
+#define MSD_SIF_DEC_STATUS_PIXIF_IDLE_SIZE 1
+
+#define MSD_SIF_DEC_STATUS_MBIWR_TAGFIFO_EMPTY_POS 22
+#define MSD_SIF_DEC_STATUS_MBIWR_TAGFIFO_EMPTY_SIZE 1
+#define MSD_SIF_DEC_STATUS_MBIWR_TAGFIFO_EMPTY(val) ((val>>MSD_SIF_DEC_STATUS_MBIWR_TAGFIFO_EMPTY_POS)&0x1)
+
+
+//MSD_SIF_BS2RBSP_STATUS_ADDR 6'h32 // R, bs2rbsp status -- [bs_sync frm_sync_data] got_start_code, nal_unit_done, buf_level
+// BSD data range definitions
+#define MSD_SIF_BS2RBSP_GOT_START_CODE_BITS(r) ((r)&0x1)
+#define MSD_SIF_BS2RBSP_NAL_UNIT_DONE_BIT(r) (((r)&0x2)>>1)
+#define MSD_SIF_BS2RBSP_CBUF_LEVEL_BITS(r) (((r)&0x1FC)>>2)
+#define MSD_SIF_BS2RBSP_GOT_START_CODE_MASK 0x1
+#define MSD_SIF_BS2RBSP_GOT_SCODE (1<<0)
+#define MSD_SIF_BS2RBSP_NALU_FINISH (1<<1)
+#define MSD_SIF_BS2RBSP_EMPTY (1<<2)
+#define MSD_SIF_BS2RBSP_BUF_LEVEL_POS 3
+#define MSD_SIF_BS2RBSP_BUF_LEVEL_SIZE 4
+#define MSD_SIF_BS2RBSP_BUF_LEVEL(val) ((val>>MSD_SIF_BS2RBSP_BUF_LEVEL_POS)&0xf)
+#define MSD_SIF_BS2RBSP_GOT_PESSCODE 1<<8
+#define MSD_SIF_BS2RBSP_SCD_LEVEL_POS 10
+#define MSD_SIF_BS2RBSP_SCD_LEVEL_MASK 0x3
+#define MSD_SIF_BS2RBSP_3RD_BTYE_POS 12
+#define MSD_SIF_BS2RBSP_3RD_BTYE_MASK 0xFF
+#define MSD_SIF_BS2RBSP_SCD_DIS_POS 20
+#define MSD_SIF_BS2RBSP_SCD_DIS_MASK 0x1
+#define MSD_SIF_BS2RBSP_LONG_SCODE_POS 21
+#define MSD_SIF_BS2RBSP_LONG_SCODE_MASK 0x1
+#define MSD_SIF_BS2RBSP_SHORT_SYNC_POS 22
+#define MSD_SIF_BS2RBSP_SHORT_SYNC_MASK 0x1
+
+#define MSD_SIF_BS2RBSP_SCD_LEVEL(val) ((val >> MSD_SIF_BS2RBSP_SCD_LEVEL_POS ) & MSD_SIF_BS2RBSP_SCD_LEVEL_MASK )
+#define MSD_SIF_BS2RBSP_SCD_3RD_BTYE(val) ((val >> MSD_SIF_BS2RBSP_3RD_BTYE_POS ) & MSD_SIF_BS2RBSP_3RD_BTYE_MASK )
+#define MSD_SIF_BS2RBSP_SCD_DIS(val) ((val >> MSD_SIF_BS2RBSP_SCD_DIS_POS ) & MSD_SIF_BS2RBSP_SCD_DIS_MASK )
+#define MSD_SIF_BS2RBSP_LONG_SCODE(val) ((val >> MSD_SIF_BS2RBSP_LONG_SCODE_POS ) & MSD_SIF_BS2RBSP_LONG_SCODE_MASK )
+#define MSD_SIF_BS2RBSP_SHORT_SYNC(val) ((val >> MSD_SIF_BS2RBSP_SHORT_SYNC_POS ) & MSD_SIF_BS2RBSP_SHORT_SYNC_MASK )
+
+//MSD_SIF_BS2RBSP_FEED_ADDR
+#define MSD_SIF_BS2RBSP_FEED_CTRL (1<<0) // W: RBSP feed start & stop control,
+#define MSD_SIF_BS2RBSP_NAL_EI_FLAG (1<<1) // R only, on nalu bases, cleared by HW at start of nalu,
+#define MSD_SIF_BS2RBSP_FEED_STOP ((~MSD_SIF_BS2RBSP_FEED_CTRL)&1)
+
+//MSD_SIF_BS2RBSP_SCODE_ADDR
+#define MSD_SIF_BS2RBSP_START_CODE_POS 0
+#define MSD_SIF_BS2RBSP_START_CODE_SIZE 8
+#define MSD_SIF_BS2RBSP_START_CODE(val) ((val>>MSD_SIF_BS2RBSP_START_CODE_POS)&0xff)
+#define MSD_SIF_RS2RBSP_SHORT_SC_POS 8
+#define MSD_SIF_RS2RBSP_SHORT_SC_SIZE 1
+#define MSD_SIF_RS2RBSP_SHORT_SC_FLAG(val) ((val>>MSD_SIF_RS2RBSP_SHORT_SC_POS)&0x1)
+#define MSD_SIF_BS2RBSP_SYNC_DATA_POS 16
+#define MSD_SIF_BS2RBSP_SYNC_DATA(val) ((val & 0xff0000) >> MSD_SIF_BS2RBSP_SYNC_DATA_POS)
+#define MSD_SIF_BS2RBSP_SYNC_DATA_SET(val) ((val<<MSD_SIF_BS2RBSP_SYNC_DATA_POS) & 0xff0000)
+
+#define MSD_SIF_BS2RBSP_SYNC_DATA_SIZE 8
+#define MSD_SIF_BS2RBSP_SYNC_DATA_PTSDTSFLAGS_POS 0
+#define MSD_SIF_BS2RBSP_SYNC_DATA_DTS_POS 2
+#define MSD_SIF_BS2RBSP_SYNC_DATA_PTS_POS 3
+#define MSD_SIF_BS2RBSP_SYNC_DATA_ERR_POS 7
+#define MSD_SIF_BS2RBSP_SYNC_DATA_ERR (1<<MSD_SIF_BS2RBSP_SYNC_DATA_ERR_POS)
+#define MSD_SIF_BS2RBSP_SYNC_FLAG (1<<24) // 0 if bs_sync_used is set to '0'
+
+//MSD_SIF_BS2RBSP_SCDCTRL_ADDR
+#define MSD_SIF_BS2RBSP_SCDCTRL_EXPLICIT_CTRL_POS 0
+#define MSD_SIF_BS2RBSP_SCDCTRL_ERR_SLCMRG_POS 3
+#define MSD_SIF_BS2RBSP_SCDCTRL_DETECT_JPEG_MARKERS_POS 5
+#define MSD_SIF_BS2RBSP_SCDCTRL_STOP_SLICE_ON_SYNC_POS 6
+#define MSD_SIF_BS2RBSP_SCDCTRL_USE_OLD_EMUL_PREVENT_POS 7
+#define MSD_SIF_BS2RBSP_SCDCTRL_SCODE_DETECT_DISABLE_PERIOD_POS 8
+#define MSD_SIF_BS2RBSP_SCDCTRL_EXPLICIT_CTRL (1<<MSD_SIF_BS2RBSP_SCDCTRL_EXPLICIT_CTRL_POS)
+#define MSD_SIF_BS2RBSP_SCDCTRL_ERR_SLCMRG (1<<MSD_SIF_BS2RBSP_SCDCTRL_ERR_SLCMRG_POS)
+#define MSD_SIF_BS2RBSP_SCDCTRL_DETECT_JPEG_MARKERS (1<<MSD_SIF_BS2RBSP_SCDCTRL_DETECT_JPEG_MARKERS_POS)
+#define MSD_SIF_BS2RBSP_SCDCTRL_STOP_SLICE_ON_SYNC (1<<MSD_SIF_BS2RBSP_SCDCTRL_STOP_SLICE_ON_SYNC_POS)
+
+//MSD_SIF_CTRL_STATUS_ADDR
+#define MSD_SIF_CTRL_SEMAPHORE_INTR_BIT (1<<0) // Read Only, '1'
+#define MSD_SIF_CTRL_IMAGE_INTR_ENAB_BIT (1<<1)
+#define MSD_SIF_CTRL_SLICE_INTR_ENAB_BIT (1<<2)
+#define MSD_SIF_CTRL_SCODE_INTR_ENAB_BIT (1<<3)
+#define MSD_SIF_CTRL_QPULL_INTR_ENAB_BIT (1<<4)
+#define MSD_SIF_CTRL_DTLERR_INTR_ENAB_BIT (1<<5) // Took over FORCE_ENTRY bit as not needed in status
+#define MSD_SIF_CTRL_PESSC_INTR_ENAB_BIT (1<<6) // Took over FORCE_ENTRY bit as not needed in status
+#define MSD_SIF_CTRL_BSDMA_INTR_ENAB_BIT (1<<7)
+#define MSD_SIF_CTRL_MP2D_SLC_MERGE_BIT (1<<8)
+#define MSD_SIF_CTRL_BS2RBSP_ENAB_BIT (1<<9)
+#define MSD_SIF_CTRL_SCODE_IN_FEED_BIT (1<<10)
+#define MSD_SIF_CTRL_SLC_RESYNC_DISAB_BIT (1<<11)
+#define MSD_SIF_CTRL_ALT_IRQ_CLR_BIT (1<<12)
+#define MSD_SIF_CTRL_ASPD_SSC_ENAB_BIT (1<<13) // SPD short start code enable
+#define MSD_SIF_CTRL_BBB_RSCMD_DISAB_BIT (1<<14) // BBB read-sensitive command disable - if set, BBB get_bits and exp-golumb commands require write first
+#define MSD_SIF_CTRL_RSBXFR_INTR_ENAB_BIT (1<<15)
+#define MSD_SIF_CTRL_IRQ_SELECT_BITS_SHIFT (16)
+
+//MSD_SIF_INTR_STATUS_ADDR
+#define MSD_SIF_INTR_SEMAPHORE_BIT (1<<0) // Controlled by semaphore interrupt mask, cannot be disabled or forced
+#define MSD_SIF_INTR_IMAGE_DONE_BIT (1<<1)
+#define MSD_SIF_INTR_SLICE_DONE_BIT (1<<2)
+#define MSD_SIF_INTR_SCODE_FOUND_BIT (1<<3)
+#define MSD_SIF_INTR_DISPQ_PULL_BIT (1<<4)
+#define MSD_SIF_INTR_FORCE_ENTRY_BIT (1<<5) // Always enabled
+#define MSD_SIF_INTR_PES_BIT (1<<6)
+#define MSD_SIF_INTR_BSDMA_BIT (1<<7)
+#define MSD_SIF_INTR_FORCE_EXIT_BIT (1<<8) // Always enabled
+#define MSD_SIF_INTR_DTL_ERR_BIT (1<<9)
+#define MSD_SIF_INTR2_EXTENSION_BITS (3<<10) // Always Enabled
+#define MSD_SIF_INTR2_EXTENSION_BIT_1 (1<<10) // Always Enabled
+#define MSD_SIF_INTR2_EXTENSION_BIT_2 (1<<11) // Always Enabled
+#define MSD_SIF_INTR3_EXTENSION_BITS (3<<12) // Always Enabled
+#define MSD_SIF_INTR3_EXTENSION_BIT_1 (1<<12) // Always Enabled
+#define MSD_SIF_INTR3_EXTENSION_BIT_2 (1<<13) // Always Enabled
+#define MSD_SIF_INTR_RSBXFR_DONE_BIT (1<<15)
+
+//MSD_SIF_CTRL2_STATUS_ADDR
+#define MSD_SIF_CTRL2_IRQ_MASK 0x80000000
+#define MSD_SIF_CTRL2_RPR_DONE_INTR_ENAB_BIT ((1<<4)|MSD_SIF_CTRL2_IRQ_MASK)
+#define MSD_SIF_CTRL2_BSD_DONE_BIT ((1<<5)|MSD_SIF_CTRL2_IRQ_MASK)
+#define MSD_SIF_CTRL2_SPP_SCODE_INTR_ENAB_BIT ((1<<6)|MSD_SIF_CTRL2_IRQ_MASK)
+#define MSD_SIF_CTRL2_SPP_PESSC_INTR_ENAB_BIT ((1<<7)|MSD_SIF_CTRL2_IRQ_MASK)
+#define MSD_SIF_CTRL2_SPP_BSDMA_INTR_ENAB_BIT ((1<<8)|MSD_SIF_CTRL2_IRQ_MASK)
+#define MSD_SIF_CTRL2_CSC_DONE_ENAB_BIT ((1<<9) |MSD_SIF_CTRL2_IRQ_MASK)
+#define MSD_SIF_CTRL2_CQ_ENAB_BIT ((1<<10)|MSD_SIF_CTRL2_IRQ_MASK)
+#define MSD_SIF_CTRL2_DFE_DONE_ENAB_BIT ((1<<13)|MSD_SIF_CTRL2_IRQ_MASK)
+#define MSD_SIF_CTRL2_DFE_SLC_DONE_ENAB_BIT ((1<<14)|MSD_SIF_CTRL2_IRQ_MASK)
+
+//MSD_SIF_INTR2_STATUS_ADDR
+#define MSD_SIF_INTR2_RPR_BIT (1<<4)
+#define MSD_SIF_INTR2_SPP_SCODE_FOUND_BIT (1<<6)
+#define MSD_SIF_INTR2_SPP_PESSC_FOUND_BIT (1<<7)
+#define MSD_SIF_INTR2_SPP_BSDMA_BIT (1<<8)
+#define MSD_SIF_INTR2_CSC_BIT (1<<9)
+#define MSD_SIF_INTR2_CQ_BIT (1<<10)
+#define MSD_SIF_INTR2_DFE_DONE_BIT (1<<13)
+#define MSD_SIF_INTR2_DFE_SLC_DONE_BIT (1<<14)
+
+//MSD_SIF_CTRL3_STATUS_ADDR
+#define MSD_SIF_CTRL3_IRQ_MASK 0x40000000
+#define MSD_SIF_CTRL3_DBE0_CQ_ENAB_BIT ((1<<0)|MSD_SIF_CTRL3_IRQ_MASK)
+#define MSD_SIF_CTRL3_DBE1_CQ_ENAB_BIT ((1<<1)|MSD_SIF_CTRL3_IRQ_MASK)
+#define MSD_SIF_CTRL3_DBE0_DONE_ENAB_BIT ((1<<4)|MSD_SIF_CTRL3_IRQ_MASK)
+#define MSD_SIF_CTRL3_DBE1_DONE_ENAB_BIT ((1<<5)|MSD_SIF_CTRL3_IRQ_MASK)
+#define MSD_SIF_CTRL3_DBE0_SLC_DONE_ENAB_BIT ((1<<8)|MSD_SIF_CTRL3_IRQ_MASK)
+#define MSD_SIF_CTRL3_DBE1_SLC_DONE_ENAB_BIT ((1<<9)|MSD_SIF_CTRL3_IRQ_MASK)
+
+//MSD_SIF_INTR3_STATUS_ADDR
+#define MSD_SIF_INTR3_DBE0_CQ_BIT (1<<0)
+#define MSD_SIF_INTR3_DBE1_CQ_BIT (1<<1)
+#define MSD_SIF_INTR3_DBE0_DONE_BIT (1<<4)
+#define MSD_SIF_INTR3_DBE1_DONE_BIT (1<<5)
+#define MSD_SIF_INTR3_DBE0_SLC_DONE_BIT (1<<8)
+#define MSD_SIF_INTR3_DBE1_SLC_DONE_BIT (1<<9)
+
+//MSD_SIF_RESET_COMMAND_ADDR
+#define MSD_SIF_RESET_DEC_ENGINE_BIT (1<<0)
+#define MSD_SIF_RESET_BS_INBUF_BIT (1<<1)
+#define MSD_SIF_RESET_DISP_QUEUE_BIT (1<<2)
+#define MSD_SIF_RESET_DTL_CACHE_BIT (1<<3)
+#define MSD_SIF_RESET_SLICE_BIT (1<<4)
+#define MSD_SIF_RESET_SPP_BIT (1<<5)
+#define MSD_SIF_RESET_DTL_4K_CACHE_BIT (1<<6) /* TODO - useme */
+#define MSD_SIF_RESET_DBE_BIT (1<<7)
+#define MSD_SIF_RESET_DFE_BIT (1<<8)
+
+//MSD_CTX_NEXT_SF_ADDR
+#define MSD_CTX_NEXT_BS_IDC_POS 0
+#define MSD_CTX_NEXT_BS_IDC_MASK 0xF
+#define MSD_CTX_NEXT_FORMAT_POS 4
+#define MSD_CTX_NEXT_FORMAT_MASK 0x1F
+
+// PES control
+//volatile u_int32 pes_setup;
+#define MSD_SIF_PES_SETUP_STRMID_POS 0
+#define MSD_SIF_PES_SETUP_SET_STRMID(id) ((id&0xff)<<MSD_SIF_PES_SETUP_STRMID_POS)
+#define MSD_SIF_PES_SETUP_STRMIDMASK_POS 8
+#define MSD_SIF_PES_SETUP_SET_STRMIDMASK(mask) ((mask&0xff)<<MSD_SIF_PES_SETUP_STRMIDMASK_POS)
+#define MSD_SIF_PES_SETUP_PESIRQEN_POS 16
+#define MSD_SIF_PES_SETUP_PESIRQEN (1<<MSD_SIF_PES_SETUP_PESIRQEN_POS)
+#define MSD_SIF_PES_SETUP_WAITPESHDR_POS 17
+#define MSD_SIF_PES_SETUP_WAITPESHDR (1<<MSD_SIF_PES_SETUP_WAITPESHDR_POS)
+#define MSD_SIF_PES_SETUP_ERRORMODE_POS 18
+#define MSD_SIF_PES_SETUP_SET_ERRORMODE(type) ((type&0x3)<<MSD_SIF_PES_SETUP_ERRORMODE_POS)
+#define MSD_SIF_PES_SETUP_ERRORMODE_NONE 0x0
+#define MSD_SIF_PES_SETUP_ERRORMODE_EIFLAG 0x2
+#define MSD_SIF_PES_SETUP_ERRORMODE_DISCONMARK 0x1
+#define MSD_SIF_PES_SETUP_PESEN_POS 20
+#define MSD_SIF_PES_SETUP_PESEN (1<<MSD_SIF_PES_SETUP_PESEN_POS)
+#define MSD_SIF_PES_SETUP_CHKPKTLEN_POS 21
+#define MSD_SIF_PES_SETUP_CHKPKTLEN (1<<MSD_SIF_PES_SETUP_CHKPKTLEN_POS)
+#define MSD_SIF_PES_SETUP_SYNC_ALWAYS_POS 22
+#define MSD_SIF_PES_SETUP_SYNC_ALWAYS (1<<MSD_SIF_PES_SETUP_SYNC_ALWAYS_POS)
+#define MSD_SIF_PES_SETUP_HOLD_DODGY_PTS_POS 23
+#define MSD_SIF_PES_SETUP_HOLD_DODGY_PTS (1<<MSD_SIF_PES_SETUP_HOLD_DODGY_PTS_POS)
+// Optionally disallow match inside PKT, to support artificial streams that do not have emulation prevention bytes
+#define MSD_SIF_PES_SETUP_ENFORCE_PKTLEN_POS 24
+#define MSD_SIF_PES_SETUP_ENFORCE_PKTLEN (1<<MSD_SIF_PES_SETUP_ENFORCE_PKTLEN_POS)
+
+//volatile u_int32 pes_status;
+#define MSD_SIF_PES_STATUS_STATE_POS 0
+#define MSD_SIF_PES_STATUS_GET_STATE(status) ((status>>MSD_SIF_PES_STATUS_STATE_POS)&0x3f)
+#define MSD_SIF_PES_STATUS_EVENT_POS 6
+#define MSD_SIF_PES_STATUS_GET_EVENT(status) ((status>>MSD_SIF_PES_STATUS_EVENT_POS)&0x3)
+#define MSD_SIF_PES_STATUS_PTS_PRESENT 0x2
+#define MSD_SIF_PES_STATUS_PTSDTS_PRESENT 0x3
+#define MSD_SIF_PES_STATUS_ERROR_PRESENT 0x1
+#define MSD_SIF_PES_STATUS_TOPDTS_POS 8
+#define MSD_SIF_PES_STATUS_GET_TOPDTS(status) ((status>>MSD_SIF_PES_STATUS_TOPDTS_POS)&0x1)
+#define MSD_SIF_PES_STATUS_SET_TOPDTS(status) ((status & 1) << MSD_SIF_PES_STATUS_TOPDTS_POS)
+#define MSD_SIF_PES_STATUS_TOPPTS_POS 9
+#define MSD_SIF_PES_STATUS_GET_TOPPTS(status) ((status>>MSD_SIF_PES_STATUS_TOPPTS_POS)&0x1)
+#define MSD_SIF_PES_STATUS_SET_TOPPTS(status) ((status & 1) << MSD_SIF_PES_STATUS_TOPPTS_POS)
+#define MSD_SIF_PES_STATUS_STALLED_POS 10
+#define MSD_SIF_PES_STATUS_GET_STALLED(status) ((status>>MSD_SIF_PES_STATUS_STALLED_POS)&0x1)
+#define MSD_SIF_PES_STATUS_STREAM_ID_MASK 0xFF
+#define MSD_SIF_PES_STATUS_STREAM_ID_POS 12
+#define MSD_SIF_PES_STATUS_GET_STREAMID(status) ((status>>MSD_SIF_PES_STATUS_STREAM_ID_POS)&MSD_SIF_PES_STATUS_STREAM_ID_MASK)
+#define MSD_SIF_PES_STATUS_TIMEBASE_ID_MASK 0x7
+#define MSD_SIF_PES_STATUS_TIMEBASE_ID_POS 12
+#define MSD_SIF_PES_STATUS_GET_TIMEBASE(status) ((status>>MSD_SIF_PES_STATUS_TIMEBASE_ID_POS)&MSD_SIF_PES_STATUS_TIMEBASE_ID_MASK)
+#define MSD_SIF_PES_STATUS_PARITY_MASK 0x1
+#define MSD_SIF_PES_STATUS_PARITY_POS 15
+#define MSD_SIF_PES_STATUS_GET_PARITY(status) ((status>>MSD_SIF_PES_STATUS_PARITY_POS)&MSD_SIF_PES_STATUS_PARITY_MASK)
+
+typedef enum
+{
+ pes_Seek = 4, // 6'b0001_00, // Wait for initial start pes start code
+ pes_DumpPrefix = 8, // 6'b0010_00, // Dumping the 0x00_00_01. Move on when get the 0x01
+ pes_DumpStrmID = 12, // 6'b0011_00, // Dumping the 0x00_00_01. Move on when get the 0x01
+ pes_WaitClear = 16, // 6'b0100_00, // Stalled waiting for firmware to clear the previous PTS
+ pes_PackLenH = 20, // 6'b0101_00, //
+ pes_PackLenL = 24, // 6'b0110_00, //
+ pes_Discon_0 = 28, // 6'b0111_00, // Output 0x00 from internally generates discontinuity
+ pes_Discon_1 = 32, // 6'b1000_00, // Output 0x00
+ pes_Discon_2 = 36, // 6'b1001_00, // Output 0x01
+ pes_Discon_3 = 40, // 6'b1010_00, // Output 0xB4
+ pes_ParseFW = 60, // 6'b1111_00, // Just let firmware read the data one at a time
+ pes_Flags1 = 1, // 6'b0000_01,
+ pes_Flags2 = 5, // 6'b0001_01,
+ pes_HdrLen = 9, // 6'b0010_01,
+ pes_PTS1 = 3, // 6'b0000_11,
+ pes_PTS2 = 7, // 6'b0001_11,
+ pes_PTS3 = 11, // 6'b0010_11,
+ pes_PTS4 = 15, // 6'b0011_11,
+ pes_PTS5 = 19, // 6'b0100_11,
+ pes_DTS1 = 23, // 6'b0101_11,
+ pes_DTS2 = 27, // 6'b0110_11,
+ pes_DTS3 = 31, // 6'b0111_11,
+ pes_DTS4 = 35, // 6'b1000_11,
+ pes_DTS5 = 39, // 6'b1001_11,
+ pes_DumpHdr = 43, // 6'b1010_11, // Skipping over remainder of headre
+ pes_PayloadSync = 45, // 6'b1011_01, // Outputting first payload byte to SCD
+ pes_Payload = 49 // 6'b1100_01 // Outputting payload to SCD
+
+} PES_STATE;
+
+// BSDMA Control
+//volatile u_int32 bsdma_command;
+#define MSD_SIF_BSDMA_CMND_START 0x1
+#define MSD_SIF_BSDMA_CMND_FETCHSTRDESC 0x2
+#define MSD_SIF_BSDMA_CMND_STOP 0x4
+#define MSD_SIF_BSDMA_CMND_CLEAR 0x8
+#define MSD_SIF_BSDMA_CMND_FORCE_DESC_UPDATE 0x10
+#define MSD_SIF_BSDMA_CMND_FORCE_CALC_LEVEL 0x20
+
+//volatile u_int32 bsdma_options;
+#define MSD_SIF_BSDMA_OPT_ENABLE 0x1
+#define MSD_SIF_BSDMA_OPT_PERIEN 0x2
+#define MSD_SIF_BSDMA_OPT_OFLIRQEN 0x4
+#define MSD_SIF_BSDMA_OPT_DISCONEN 0x8
+#define MSD_SIF_BSDMA_OPT_DESCUPPER_POS 4
+#define MSD_SIF_BSDMA_OPT_LOCBUFSIZE_POS 8
+#define MSD_SIF_BSDMA_OPT_LOCBUFOFFSET_POS 16
+#define MSD_SIF_BSDMA_OPT_DEBUG_FEED (1<<24)
+#define MSD_SIF_BSDMA_OPT_BURST (1<<25)
+
+#define MSD_SIF_BSDMA_OPT_SAFEREADMARGIN_POS 26
+#define MSD_SIF_BSDMA_OPT_TRACEBACK_POS 28
+#define MSD_BSDMA_STRIDE_END_IRQ_P0S 30 // Interrupt when all data read
+#define MSD_BSDMA_STRIDE_END_IRQ (1<<MSD_BSDMA_STRIDE_END_IRQ_P0S)
+#define MSD_BSDMA_STRIDE_DONE_IRQ_POS 31 // Interrupt when all data used
+#define MSD_BSDMA_STRIDE_DONE_IRQ ((u_int32)(1<<MSD_BSDMA_STRIDE_DONE_IRQ_POS))
+
+
+#define MSD_SIF_BSDMA_OPT_0B_SAFEMARGIN (0<<MSD_SIF_BSDMA_OPT_SAFEREADMARGIN_POS)
+#define MSD_SIF_BSDMA_OPT_128B_SAFEMARGIN (1<<MSD_SIF_BSDMA_OPT_SAFEREADMARGIN_POS)
+#define MSD_SIF_BSDMA_OPT_2KB_SAFEMARGIN (2<<MSD_SIF_BSDMA_OPT_SAFEREADMARGIN_POS)
+#define MSD_SIF_BSDMA_OPT_32KB_SAFEMARGIN (3<<MSD_SIF_BSDMA_OPT_SAFEREADMARGIN_POS)
+
+#define MSD_SIF_BSDMA_OPT_TRACEBACK_0 (0<<MSD_SIF_BSDMA_OPT_TRACEBACK_POS)
+#define MSD_SIF_BSDMA_OPT_TRACEBACK_16K (1<<MSD_SIF_BSDMA_OPT_TRACEBACK_POS)
+#define MSD_SIF_BSDMA_OPT_TRACEBACK_256K (2<<MSD_SIF_BSDMA_OPT_TRACEBACK_POS)
+#define MSD_SIF_BSDMA_OPT_TRACEBACK_4M (3<<MSD_SIF_BSDMA_OPT_TRACEBACK_POS)
+
+/* Constant defines on the 160/128 64-bit words of IBB memory */
+/* Split between the BSDMA stream buffer and the H.264 IBB usage */
+#define IBBBUF_SIZE 128
+#define IBBBUF_SIZE_LARGE 160
+#define BSDMA_IBBBUF_USAGE 16
+
+//volatile u_int32 bsdma_status;
+#define MSD_SIF_BSDMA_STATUS_CB_LEVEL (0xFF)
+#define MSD_SIF_BSDMA_STATUS_NMEMWORDS (0x1f<<8)
+#define MSD_SIF_BSDMA_STATUS_BELOW_LWM (0x1<<13) // Currently below Low Water Mark
+#define MSD_SIF_BSDMA_STATUS_BELOW_LWMH (0x1<<14) // Below Low Water Mark since last cleared
+#define MSD_SIF_BSDMA_STATUS_BUFOFLOW (0x1<<15)
+#define MSD_SIF_BSDMA_STATUS_DMA_STATE (0x1F<<16)
+#define MSD_SIF_BSDMA_STATUS_MCX_STATE (0x3F<<21)
+#define MSD_SIF_BSDMA_STATUS_RQ_STATE (0x1<<27)
+#define MSD_SIF_BSDMA_STATUS_ABOVE_HWM (0x1<<28) // Currently above High Water Mark
+#define MSD_SIF_BSDMA_STATUS_ABOVE_HWMH (0x1<<29) // Above High Water Mark since last cleared
+#define MSD_SIF_BSDMA_STATUS_STRIDE_END (0x1<<30) // all data fed
+#define MSD_SIF_BSDMA_STATUS_STRIDE_DONE ((u_int32)(0x1<<31)) // all data used
+
+#define MSD_SIF_BSDMA_EXTOPT_LOOPBIT_POS 0x0
+#define MSD_SIF_BSDMA_EXTOPT_CB_MIN_POS 3
+#define MSD_SIF_BSDMA_EXTOPT_REQ_8 (1<<10)
+#define MSD_SIF_BSDMA_EXTOPT_SINGLE_STRIDE (1<<11)
+#define MSD_SIF_BSDMA_EXTOPT_INIT_IRQ (1<<12)
+#define MSD_SIF_BSDMA_EXTOPT_MIN_UPDATES (1<<13)
+#define MSD_SIF_BSDMA_EXTOPT_CHECK_WPTR (1<<14)
+
+//volatile u_int32 bsdma_ext_options;
+#define MSD_SIF_BSDMA_EXTOPT_LOOPBIT_SET(w) ((w&0x7)<<MSD_SIF_BSDMA_EXTOPT_LOOPBIT_POS)
+#define MSD_SIF_BSDMA_EXTOPT_LOOPBIT_GET(r) ((r>>MSD_SIF_BSDMA_EXTOPT_LOOPBIT_POS)&0x7)
+#define MSD_SIF_BSDMA_EXTOPT_SINGLESHOTEXITMODE MSD_SIF_BSDMA_EXTOPT_SINGLE_STRIDE
+
+// This define is used only when FW controls how close the RP can get to the WP
+// For pecos we are assuming at least two full burst of distance
+//#define BSDMA_WP_AHEAD_OF_RP_MARGIN (2*16*8)
+#define BSDMA_WP_AHEAD_OF_RP_MARGIN (8*16*8)
+#define BSDMA_DESC_REAL_ADDR(x) (x&0xfffffff)
+#define BSDMA_DESC_WRAP_ADDR(x) (x&0xf0000000)
+#define BSDMA_DESC_NOPARITY_MASK 0xfffffffe
+
+
+#define MSD_FORMAT_H264 (0x1 <<MSD_CTX_NEXT_FORMAT_POS)
+#define MSD_FORMAT_VC1 (0x2 <<MSD_CTX_NEXT_FORMAT_POS)
+#define MSD_FORMAT_MP2 (0x3 <<MSD_CTX_NEXT_FORMAT_POS)
+#define MSD_FORMAT_AVS (0x4 <<MSD_CTX_NEXT_FORMAT_POS)
+#define MSD_FORMAT_ASP (0x5 <<MSD_CTX_NEXT_FORMAT_POS)
+#define MSD_FORMAT_JPG (0xD <<MSD_CTX_NEXT_FORMAT_POS) // Uses aspd HW and ext. format flag
+#define MSD_FORMAT_RV8 (0x6 <<MSD_CTX_NEXT_FORMAT_POS)
+#define MSD_FORMAT_RV9 (0xE <<MSD_CTX_NEXT_FORMAT_POS)
+#define MSD_FORMAT_VP6 (0x7 <<MSD_CTX_NEXT_FORMAT_POS)
+#define MSD_FORMAT_VP8 (0xF <<MSD_CTX_NEXT_FORMAT_POS)
+#define MSD_FORMAT_VP3 (0x7 <<MSD_CTX_NEXT_FORMAT_POS)
+#define MSD_FORMAT_HEVC (0x10 <<MSD_CTX_NEXT_FORMAT_POS)
+#define MSD_FORMAT_NULL (0x0 <<MSD_CTX_NEXT_FORMAT_POS)
+
+//MSD_SIF_DPBMC_SETUP_ADDR
+#define MSD_SIF_DPBMC_SET_CRC_TYPE(datasrc,datatype) (((0x3&datatype)<<2)|(datasrc&0x3))
+
+#define MSD_SIF_DPBMC_CLEAR_CRC2_TYPE_MASK 0xFF0FFFFF
+#define MSD_SIF_DPBMC_SET_CRC2_TYPE(datasrc,datatype) (((0x3&datatype)<<22)|((datasrc&0x3)<<20))
+// Alternate method of setup
+
+#define MSD_SIF_DPBMC_CLEAR_CRC2_MAJOR_MINOR_TYPE_MASK 0x87CFFFFF
+#define MSD_SIF_DPBMC_SET_CRC2_TYPE_MAJOR(datatype) (( 0x3 & datatype ) << 20 )
+#define MSD_SIF_DPBMC_SET_CRC2_TYPE_MINOR(datasrc) (( 0xf & datasrc ) << 27 )
+#define MSD_SIF_DPBMC_GET_CRC2_TYPE_MAJOR(datatype) (( datatype >> 20 ) & 0x3 )
+#define MSD_SIF_DPBMC_GET_CRC2_TYPE_MINOR(datasrc) (( datasrc >> 27) & 0xf )
+#define MSD_SIF_DPBMC_SET_CRC_ALT_TYPE_MAJOR(datatype) (( 0x3 & datatype ) << 2 )
+#define MSD_SIF_DPBMC_SET_CRC_ALT_TYPE_MINOR(datasrc) (( 0xf & datasrc ) << 23 )
+#define MSD_SIF_DPBMC_SET_CRC_USE_ALT_TYPE(use) (( use & 0x1 ) << 22 )
+
+#define MSD_SIF_DPBMC_CRC_RDDATA_TYPE 0x0
+#define MSD_SIF_DPBMC_CRC_WRDATA_TYPE 0x1
+#define MSD_SIF_DPBMC_CRC_RDADDR_TYPE 0x2
+#define MSD_SIF_DPBMC_CRC_WRADDR_TYPE 0x3
+#define MSD_SIF_DPBMC_CRC_BPP_SRCTYPE 0x3
+#define MSD_SIF_DPBMC_CRC_MBI_SRCTYPE 0x2
+#define MSD_SIF_DPBMC_CRC_PIXEL_SRCTYPE 0x0
+
+#define MSD_SIF_DPBMC_CRC_ALT_DBE1_SRCTYPE 0xf
+#define MSD_SIF_DPBMC_CRC_ALT_TES_SRCTYPE 0xe
+#define MSD_SIF_DPBMC_CRC_ALT_DFE_SRCTYPE 0xd
+#define MSD_SIF_DPBMC_CRC_ALT_MPSDBF_UV_SRCTYPE 0xc
+#define MSD_SIF_DPBMC_CRC_ALT_SVC_RSMP_SRCTYPE 0xb
+#define MSD_SIF_DPBMC_CRC_ALT_SVC_META_SRCTYPE 0xa
+#define MSD_SIF_DPBMC_CRC_ALT_MBQ_SRCTYPE 0x9
+#define MSD_SIF_DPBMC_CRC_ALT_CSC_SRCTYPE 0x8
+#define MSD_SIF_DPBMC_CRC_ALT_RPR_SRCTYPE 0x7
+#define MSD_SIF_DPBMC_CRC_ALT_MPSDBF_SRCTYPE 0x6
+#define MSD_SIF_DPBMC_CRC_ALT_MBI_SRCTYPE 0x5
+#define MSD_SIF_DPBMC_CRC_ALT_MX12_SRCTYPE 0x4
+#define MSD_SIF_DPBMC_CRC_ALT_MX34_SRCTYPE 0x3
+#define MSD_SIF_DPBMC_CRC_ALT_RSB_SRCTYPE 0x2
+#define MSD_SIF_DPBMC_CRC_ALT_MCX_SRCTYPE 0x1
+#define MSD_SIF_DPBMC_CRC_ALT_BSD_SRCTYPE 0x0
+
+#define MSD_SIF_DPBMC_OUTSTAND_REQ_POS 4
+#define MSD_SIF_DPBMC_OUTSTAND_REQ_MASK 0x7
+#define MSD_SIF_DPBMC_SET_OUTSTAND_REQ(num_req) ((num_req&MSD_SIF_DPBMC_OUTSTAND_REQ_MASK)<<MSD_SIF_DPBMC_OUTSTAND_REQ_POS)
+#define MSD_SIF_DPBMC_OUTSTAND_WR_REQ_POS 7
+#define MSD_SIF_DPBMC_OUTSTAND_WR_REQ_MASK 0x3
+#define MSD_SIF_DPBMC_SET_OUTSTAND_WR_REQ(num_req) ((num_req&MSD_SIF_DPBMC_OUTSTAND_WR_REQ_MASK)<<MSD_SIF_DPBMC_OUTSTAND_WR_REQ_POS)
+#define MSD_SIF_DPBMC_DBFAL_MODE_POS 9
+#define MSD_SIF_DPBMC_DBFAL_MODE_MASK 0x3
+#define MSD_SIF_DPBMC_SET_DBFAL_MODE(num_req) ((num_req&MSD_SIF_DPBMC_DBFAL_MODE_MASK)<<MSD_SIF_DPBMC_DBFAL_MODE_POS)
+#define MSD_SIF_DPBMC_SET_USE_CHROMA_DPATH_POS 0x0
+#define MSD_SIF_DPBMC_SET_USE_CHROMA_DPATH_MASK 0x1
+#define MSD_SIF_DPBMC_SET_USE_CHROMA_DPATH(a) ((a&MSD_SIF_DPBMC_SET_USE_CHROMA_DPATH_MASK)<<MSD_SIF_DPBMC_SET_USE_CHROMA_DPATH_POS)
+#define MSD_SIF_DPBMC_SET_CLR_CHROMA_DPATH (~(MSD_SIF_DPBMC_SET_USE_CHROMA_DPATH_MASK << MSD_SIF_DPBMC_SET_USE_CHROMA_DPATH_POS))
+
+
+// VMIF MBI CACHE
+#define MSD_VMIF_MBI_CACHE_RDCLR_POS 0
+#define MSD_VMIF_MBI_CACHE_RDCLR_MASK 0x7
+#define MSD_VMIF_MBI_CACHE_RDDIS_POS 3
+#define MSD_VMIF_MBI_CACHE_RDDIS_MASK 0x7
+#define MSD_VMIF_MBI_CACHE_RDSCLR_DIS_POS 6
+#define MSD_VMIF_MBI_CACHE_RDSCLR_DIS_MASK 0x7
+#define MSD_VMIF_MBI_CACHE_WRCLR_POS 9
+#define MSD_VMIF_MBI_CACHE_WRCLR_MASK 0x7
+#define MSD_VMIF_MBI_CACHE_WRDIS_POS 12
+#define MSD_VMIF_MBI_CACHE_WRDIS_MASK 0x7
+#define MSD_VMIF_MBI_CACHE_WRFLSH_POS 15
+#define MSD_VMIF_MBI_CACHE_WRFLSH_MASK 0x7
+
+#define MSD_VMIF_MBI_CACHE_SET_RDCLR(w) ((w&MSD_VMIF_MBI_CACHE_RDCLR_MASK)<<MSD_VMIF_MBI_CACHE_RDCLR_POS)
+#define MSD_VMIF_MBI_CACHE_SET_RDDIS(w) ((w&MSD_VMIF_MBI_CACHE_RDDIS_MASK)<<MSD_VMIF_MBI_CACHE_RDDIS_POS)
+#define MSD_VMIF_MBI_CACHE_SET_RDSCLR_DIS(w) ((w&MSD_VMIF_MBI_CACHE_RDSCLR_DIS_MASK)<<MSD_VMIF_MBI_CACHE_RDSCLR_DIS_POS)
+#define MSD_VMIF_MBI_CACHE_SET_WRCLR(w) ((w&MSD_VMIF_MBI_CACHE_WRCLR_MASK)<<MSD_VMIF_MBI_CACHE_WRCLR_POS)
+#define MSD_VMIF_MBI_CACHE_SET_WRDIS(w) ((w&MSD_VMIF_MBI_CACHE_WRDIS_MASK)<<MSD_VMIF_MBI_CACHE_WRDIS_POS)
+#define MSD_VMIF_MBI_CACHE_SET_WRFLSH(w) ((w&MSD_SIF_DPBMC_OUTSTAND_WR_REQ_MASK)<<MSD_VMIF_MBI_CACHE_WRFLSH_POS)
+
+
+// DPBMC SETUP 2
+#define MSD_SIF_DPBMC_SET_OUTSTAND_MBIRD_MASK 0x3
+#define MSD_SIF_DPBMC_SET_OUTSTAND_MBIRD_POS 14
+#define MSD_VMIF_MPSAL_MODE_DISOB_BIT 13
+#define MSD_VMIF_MPSAL_MODE_REQ16_BIT 10
+#define MSD_VMIF_MPSAL_MODE_16PIX_POS 9
+// MSD_SIF_COUNT_STRB_SEL_BITS 8:1
+#define MSD_SIF_COUNT_RD_CMD_STRB_SEL 7
+#define MSD_SIF_COUNT_WR_CMD_STRB_SEL 6
+#define MSD_SIF_COUNT_WR_STRB_SEL 5
+#define MSD_SIF_COUNT_RD_STRB_SEL 4
+#define MSD_SIF_COUNT_UV_RD_STRB_SEL 3
+#define MSD_SIF_COUNT_RSMP_RD_STRB_SEL 2
+#define MSD_SIF_COUNT_RSMP_MBMETA_STRB_SEL 1
+#define MSD_SIF_COUNT_MBI_RD_STRB_SEL 0
+
+#define MSD_SIF_COUNT_STRB_SEL_MASK 0x1
+#define MSD_SIF_COUNT_STRB_SET_USE_RD_CMD_STRB(a) (((a&MSD_SIF_COUNT_STRB_SEL_MASK) <<MSD_SIF_COUNT_RD_CMD_STRB_SEL )<<1)
+#define MSD_SIF_COUNT_STRB_SET_USE_WR_CMD_STRB(a) (((a&MSD_SIF_COUNT_STRB_SEL_MASK) <<MSD_SIF_COUNT_WR_CMD_STRB_SEL )<<1)
+#define MSD_SIF_COUNT_STRB_SET_USE_WR_STRB(a) (((a&MSD_SIF_COUNT_STRB_SEL_MASK) <<MSD_SIF_COUNT_WR_STRB_SEL )<<1)
+#define MSD_SIF_COUNT_STRB_SET_USE_RD_STRB(a) (((a&MSD_SIF_COUNT_STRB_SEL_MASK) <<MSD_SIF_COUNT_RD_STRB_SEL )<<1)
+#define MSD_SIF_COUNT_STRB_SET_USE_UV_RD_STRB(a) (((a&MSD_SIF_COUNT_STRB_SEL_MASK) <<MSD_SIF_COUNT_UV_RD_STRB_SEL )<<1)
+#define MSD_SIF_COUNT_STRB_SET_USE_RSMP_RD_STRB(a) (((a&MSD_SIF_COUNT_STRB_SEL_MASK) <<MSD_SIF_COUNT_RSMP_RD_STRB_SEL )<<1)
+#define MSD_SIF_COUNT_STRB_SET_USE_RSMP_MBMETA_STRB(a) (((a&MSD_SIF_COUNT_STRB_SEL_MASK) <<MSD_SIF_COUNT_RSMP_MBMETA_STRB_SEL )<<1)
+#define MSD_SIF_COUNT_STRB_SET_USE_MBI_RD_STRB(a) (((a&MSD_SIF_COUNT_STRB_SEL_MASK) <<MSD_SIF_COUNT_MBI_RD_STRB_SEL )<<1)
+#define MSD_SIF_DPBMC_SET_OUTSTAND_MBIRD(a) ((a&MSD_SIF_DPBMC_SET_OUTSTAND_MBIRD_MASK)<<MSD_SIF_DPBMC_SET_OUTSTAND_MBIRD_POS)
+
+
+#define MSD_DPBMC_DPBCOH_POS 9
+#define MSD_DPBMC_DPBCOH_MASK 0x1
+#define MSD_DPBMC_DPBCOH_SET(a) ((a&MSD_DPBMC_DPBCOH_MASK)<<MSD_DPBMC_DPBCOH_POS)
+#define MSD_DPBMC_MBICOH_POS 10
+#define MSD_DPBMC_MBICOH_MASK 0x1
+#define MSD_DPBMC_MBICOH_SET(a) ((a&MSD_DPBMC_MBICOH_MASK)<<MSD_DPBMC_MBICOH_POS)
+#define MSD_DPBMC_RSBCOH_POS 11
+#define MSD_DPBMC_RSBCOH_MASK 0x1
+#define MSD_DPBMC_RSBCOH_SET(a) ((a&MSD_DPBMC_RSBCOH_MASK)<<MSD_DPBMC_RSBCOH_POS)
+#define MSD_SIF_DPBMC_BASE_UNIT_POS 12
+#define MSD_SIF_DPBMC_BASE_UNIT_MASK 0x7
+#define MSD_SIF_DPBMC_SET_BASE_UNIT(base) ((base&MSD_SIF_DPBMC_BASE_UNIT_MASK)<<MSD_SIF_DPBMC_BASE_UNIT_POS)
+#define MSD_DPBMC_INT_WAIT_IDLE_POS 15
+#define MSD_DPBMC_INT_WAIT_IDLE_MASK 0x1
+#define MSD_DPBMC_INT_WAIT_IDLE_SET(a) ((a&MSD_DPBMC_INT_WAIT_IDLE_MASK)<<MSD_DPBMC_INT_WAIT_IDLE_POS)
+#define MSD_DPBMC_SC_INT_WAIT_IDLE_SET_POS 31
+#define MSD_DPBMC_SC_INT_WAIT_IDLE_SET_MASK 0x1
+#define MSD_DPBMC_SC_INT_WAIT_IDLE_SET(a) ((a&MSD_DPBMC_SC_INT_WAIT_IDLE_SET_MASK)<<MSD_DPBMC_SC_INT_WAIT_IDLE_SET_POS)
+#define MSD_DPBMC_ARB_MCX_POS 16
+#define MSD_DPBMC_ARB_MCX_MASK 0x1
+#define MSD_DPBMC_ARB_MCX_SET(a) ((a&MSD_DPBMC_ARB_MCX_MASK)<<MSD_DPBMC_ARB_MCX_POS)
+#define MSD_DPBMC_ARB_MCX_CLR(a) (~((a&MSD_DPBMC_ARB_MCX_MASK)<<MSD_DPBMC_ARB_MCX_POS))
+#define MSD_DPBMC_ARB_BSDMA_POS 17
+#define MSD_DPBMC_ARB_BSDMA_MASK 0x1
+#define MSD_DPBMC_ARB_BSDMA_SET(a) ((a&MSD_DPBMC_ARB_BSDMA_MASK)<<MSD_DPBMC_ARB_BSDMA_POS)
+#define MSD_DPBMC_ARB_BSDMA_CLR(a) (~((a&MSD_DPBMC_ARB_BSDMA_MASK)<<MSD_DPBMC_ARB_BSDMA_POS))
+#define MSD_DPBMC_DIS_CRC_AUTO_RESET_POS 19
+#define MSD_DPBMC_DIS_CRC_AUTO_RESET_MASK 0x1
+#define MSD_DPBMC_DIS_CRC_AUTO_RESET_SET(a) ((a&MSD_DPBMC_DIS_CRC_AUTO_RESET_MASK)<<MSD_DPBMC_DIS_CRC_AUTO_RESET_POS)
+#define MSD_DPBMC_DIS_CRC_AUTO_RESET_CLR(a) (~((a&MSD_DPBMC_DIS_CRC_AUTO_RESET_MASK)<<MSD_DPBMC_DIS_CRC_AUTO_RESET_POS))
+
+// Local memory configuration (power down)
+#define MSD_SIF_LMEM_CONFIG_PD_MASK 0x1
+#define MSD_SIF_LMEM_CONFIG_PD_CCHE0_POS 0
+#define MSD_SIF_LMEM_CONFIG_PD_RSB_POS 1
+#define MSD_SIF_LMEM_CONFIG_PD_AVSD_POS 2
+#define MSD_SIF_LMEM_CONFIG_PD_MPGD_POS 3
+#define MSD_SIF_LMEM_CONFIG_PD_VC1D_POS 4
+#define MSD_SIF_LMEM_CONFIG_PD_AVCD_POS 5
+#define MSD_SIF_LMEM_CONFIG_PD_COMM_POS 6
+#define MSD_SIF_LMEM_CONFIG_PD_RPR_POS 7
+#define MSD_SIF_LMEM_CONFIG_PD_CCHE1_POS 14
+#define MSD_SIF_LMEM_CONFIG_PD_HEVD_POS 15
+#define MSD_SIF_LMEM_CONFIG_PD_VMIF_POS 17
+
+#define MSD_SIF_LMEM_CONFIG_SET_PD_CCHE0(a) ((a&MSD_SIF_LMEM_CONFIG_PD_MASK) <<MSD_SIF_LMEM_CONFIG_PD_CCHE0_POS )
+#define MSD_SIF_LMEM_CONFIG_SET_PD_RSB(a) ((a&MSD_SIF_LMEM_CONFIG_PD_MASK) <<MSD_SIF_LMEM_CONFIG_PD_RSB_POS )
+#define MSD_SIF_LMEM_CONFIG_SET_PD_AVSD(a) ((a&MSD_SIF_LMEM_CONFIG_PD_MASK) <<MSD_SIF_LMEM_CONFIG_PD_AVSD_POS )
+#define MSD_SIF_LMEM_CONFIG_SET_PD_MPGD(a) ((a&MSD_SIF_LMEM_CONFIG_PD_MASK) <<MSD_SIF_LMEM_CONFIG_PD_MPGD_POS )
+#define MSD_SIF_LMEM_CONFIG_SET_PD_VC1D(a) ((a&MSD_SIF_LMEM_CONFIG_PD_MASK) <<MSD_SIF_LMEM_CONFIG_PD_VC1D_POS )
+#define MSD_SIF_LMEM_CONFIG_SET_PD_AVCD(a) ((a&MSD_SIF_LMEM_CONFIG_PD_MASK) <<MSD_SIF_LMEM_CONFIG_PD_AVCD_POS )
+#define MSD_SIF_LMEM_CONFIG_SET_PD_COMM(a) ((a&MSD_SIF_LMEM_CONFIG_PD_MASK) <<MSD_SIF_LMEM_CONFIG_PD_COMM_POS )
+#define MSD_SIF_LMEM_CONFIG_SET_PD_RPR(a) ((a&MSD_SIF_LMEM_CONFIG_PD_MASK) <<MSD_SIF_LMEM_CONFIG_PD_RPR_POS )
+#define MSD_SIF_LMEM_CONFIG_SET_PD_CCHE1(a) ((a&MSD_SIF_LMEM_CONFIG_PD_MASK) <<MSD_SIF_LMEM_CONFIG_PD_CCHE1_POS )
+#define MSD_SIF_LMEM_CONFIG_SET_PD_HEVD(a) ((a&MSD_SIF_LMEM_CONFIG_PD_MASK) <<MSD_SIF_LMEM_CONFIG_PD_HEVD_POS )
+#define MSD_SIF_LMEM_CONFIG_SET_PD_VMIF(a) ((a&MSD_SIF_LMEM_CONFIG_PD_MASK) <<MSD_SIF_LMEM_CONFIG_PD_VMIF_POS )
+
+#define MSD_SIF_LMEM_CONFIG_RESET_PD_CCHE0(a) (a & (~(MSD_SIF_LMEM_CONFIG_PD_MASK << MSD_SIF_LMEM_CONFIG_PD_CCHE0_POS )))
+#define MSD_SIF_LMEM_CONFIG_RESET_PD_RSB(a) (a & (~(MSD_SIF_LMEM_CONFIG_PD_MASK << MSD_SIF_LMEM_CONFIG_PD_RSB_POS )))
+#define MSD_SIF_LMEM_CONFIG_RESET_PD_AVSD(a) (a & (~(MSD_SIF_LMEM_CONFIG_PD_MASK << MSD_SIF_LMEM_CONFIG_PD_AVSD_POS )))
+#define MSD_SIF_LMEM_CONFIG_RESET_PD_MPGD(a) (a & (~(MSD_SIF_LMEM_CONFIG_PD_MASK << MSD_SIF_LMEM_CONFIG_PD_MPGD_POS )))
+#define MSD_SIF_LMEM_CONFIG_RESET_PD_VC1D(a) (a & (~(MSD_SIF_LMEM_CONFIG_PD_MASK << MSD_SIF_LMEM_CONFIG_PD_VC1D_POS )))
+#define MSD_SIF_LMEM_CONFIG_RESET_PD_AVCD(a) (a & (~(MSD_SIF_LMEM_CONFIG_PD_MASK << MSD_SIF_LMEM_CONFIG_PD_AVCD_POS )))
+#define MSD_SIF_LMEM_CONFIG_RESET_PD_COMM(a) (a & (~(MSD_SIF_LMEM_CONFIG_PD_MASK << MSD_SIF_LMEM_CONFIG_PD_COMM_POS )))
+#define MSD_SIF_LMEM_CONFIG_RESET_PD_RPR(a) (a & (~(MSD_SIF_LMEM_CONFIG_PD_MASK << MSD_SIF_LMEM_CONFIG_PD_RPR_POS )))
+#define MSD_SIF_LMEM_CONFIG_RESET_PD_CCHE1(a) (a & (~(MSD_SIF_LMEM_CONFIG_PD_MASK << MSD_SIF_LMEM_CONFIG_PD_CCHE1_POS )))
+#define MSD_SIF_LMEM_CONFIG_RESET_PD_HEVD(a) (a & (~(MSD_SIF_LMEM_CONFIG_PD_MASK << MSD_SIF_LMEM_CONFIG_PD_HEVD_POS )))
+#define MSD_SIF_LMEM_CONFIG_RESET_PD_VMIF(a) (a & (~(MSD_SIF_LMEM_CONFIG_PD_MASK << MSD_SIF_LMEM_CONFIG_PD_VMIF_POS )))
+
+
+
+// Row-store buffer control
+//--------------------------
+// MSD_SIF_RSB_CTRL_STAT_ADDR (0x6e) //0x1b8
+#define MSD_SIF_RSB_SWITCH_REGION_ACCESS_POS 0x0
+#define MSD_SIF_RSB_SWITCH_REGION_ACCESS_MASK 0x1
+#define MSD_SIF_RSB_SWITCH_REGION_ACCESS_GET(r) (( r >> MSD_SIF_RSB_SWITCH_REGION_ACCESS_POS ) & MSD_SIF_RSB_SWITCH_REGION_ACCESS_MASK )
+#define MSD_SIF_RSB_SWITCH_REGION_ACCESS_SET(w) (( w & MSD_SIF_RSB_SWITCH_REGION_ACCESS_MASK ) << MSD_SIF_RSB_SWITCH_REGION_ACCESS_POS )
+#define MSD_SIF_RSB_INT_BASE_ADDR_SET(a) ((0x1fff & a)<<0) // 12:0
+#define MSD_SIF_RSB_XFR_XNUM_MASK ((0xff )<<13)
+#define MSD_SIF_RSB_XFR_XNUM_SET(a) ((0xff & a )<<13) //20:13
+#define MSD_SIF_RSB_XFR_YNUM_MASK ((0x7 )<<21) // 23:21
+#define MSD_SIF_RSB_XFR_YNUM_SET(a) ((0x7 & a)<<21) // 23:21
+#define MSD_SIF_RSB_SPLIT_FACTOR_MASK ((0x3 )<<24) //25:24
+#define MSD_SIF_RSB_SPLIT_FACTOR_SET(a) ((0x3 & a)<<24) //25:24
+#define MSD_SIF_RSB_XFR_MODE_MASK ((0x3 )<<26) //27:26
+#define MSD_SIF_RSB_XFR_MODE_SET(a) ((0x3 & a)<<26) //27:26
+#define MSD_SIF_RSB_XFR_START_MASK ((0x1 )<<28) //28
+#define MSD_SIF_RSB_XFR_START_SET(a) ((0x1 & a)<<28) //28
+#define MSD_SIF_RSB_APB_ACC_EN_MASK ((0x1 )<<31) //31
+#define MSD_SIF_RSB_APB_ACC_EN_SET(a) ((0x1 & a)<<31) //31
+
+#define MSD_SIF_RSB_XFR_PROG_GET(a) (( a >>29) & 0x1) //29
+#define MSD_SIF_RSB_XFR_DONE_GET(a) (( a >>30) & 0x1) //30
+#define MSD_SIF_RSB_XFR_MODE_GET(a) (( a >>26) & 0x3) //27:26
+
+
+// Ancillary RSB transfer defines
+//-------------------------------
+#define MSD_SIF_RSB_INT_BASE_ADDR_MASK 0x1FFFF
+
+//MSD_SIF_EXT_RSB_BASE_ADDR (0X6f) //0x1bc
+#define MSD_SIF_EXT_RSB_BASE_ADDR_SET(a) (a & 0xffffff) // 31:3
+//MSD_SIF_EXT_XFR_PARAMS_ADDR (0x70) 0x1c0
+#define MSD_SIF_EXT_XFR_PARAM_TF_TYPE_MASK ((0x3) <<30 ) //31:30 0:2DLU; 1:2DCR 2:MINF 3:1DTF ;
+#define MSD_SIF_EXT_XFR_PARAM_TF_TYPE(a) ((a & 0x3) <<30 ) //31:30 0:2DLU; 1:2DCR 2:MINF 3:1DTF ;
+#define MSD_SIF_EXT_XFR_PARAM_TYPE_GET(a) (( a >>30) & 0x3) //31:30
+// 2D transferred
+#define MSD_SIF_EXT_XFR_PARAM_FIELD_FRAME_MASK ((0x01)<<29) //29 : field 1 ; 0 frame
+#define MSD_SIF_EXT_XFR_PARAM_TOP_ROW_POS_MASK ((0x7ff)<<18) // row position in frame of top row of data in the transfer
+#define MSD_SIF_EXT_XFR_PARAM_COL_LFT_POS_MASK ((0xff )<<10) // collumn position in frame of left-most word in the transfer
+#define MSD_SIF_EXT_XFR_PARAM_NUM_ROW_MASK ((0x1f )<<5) // number of rows in a tile to be transferred
+#define MSD_SIF_EXT_XFR_PARAM_NUM_PER_ROW_MASK ((0x3) <<0) // number of words per row in a tile to be transferred
+
+#define MSD_SIF_EXT_XFR_PARAM_FIELD_FRAME(a) ((a & 0x01)<<29) //29 : field 1 ; 0 frame
+#define MSD_SIF_EXT_XFR_PARAM_TOP_ROW_POS(a) ((a & 0x7ff)<<18) // row position in frame of top row of data in the transfer
+#define MSD_SIF_EXT_XFR_PARAM_COL_LFT_POS(a) ((a & 0xff )<<10) // collumn position in frame of left-most word in the transfer
+#define MSD_SIF_EXT_XFR_PARAM_NUM_ROW(a) ((a & 0x1f )<<5) // number of rows in a tile to be transferred
+#define MSD_SIF_EXT_XFR_PARAM_NUM_PER_ROW(a) ((a & 0x3) <<0) // number of words per row in a tile to be transferred
+// 1D transferred
+#define MSD_SIF_EXT_XFR_PARAM_NUM_WORDS_MASK ((0x1fff)<<0) // number of words to be transferred under 1D
+#define MSD_SIF_EXT_XFR_PARAM_NUM_WORDS(a) ((a & 0x1fff)<<0) // number of words to be transferred under 1D
+#define MSD_SIF_EXT_XFR_BASE_ADDR_SET(a) ( a & 0xffffff) // 31:3
+
+#define MSD_SIF_PWT_BASE_ADDR_POS 0x0
+#define MSD_SIF_PWT_BASE_ADDR_MASK 0x3FFF
+#define MSD_SIF_PXD_BASE_ADDR_POS 0x10
+#define MSD_SIF_PXD_BASE_ADDR_MASK 0x3FFF
+
+#define MSD_SIF_PUT_PWT_BASE(w) (( w & MSD_SIF_PWT_BASE_ADDR_MASK ) << MSD_SIF_PWT_BASE_ADDR_POS )
+#define MSD_SIF_PUT_PXD_BASE(w) (( w & MSD_SIF_PXD_BASE_ADDR_MASK ) << MSD_SIF_PXD_BASE_ADDR_POS )
+
+#define MSD_SIF_BSD_BASE_ADDR_POS 0x0
+#define MSD_SIF_BSD_BASE_ADDR_MASK 0x3FFF
+#define MSD_SIF_DBFC_BASE_ADDR_POS 0x10
+#define MSD_SIF_DBFC_BASE_ADDR_MASK 0x3FFF
+#define MSD_SIF_RSB_USE_APB_OFF_POS 0x1F
+#define MSD_SIF_RSB_USE_APB_OFF_MASK 0x1
+
+#define MSD_SIF_PUT_BSD_BASE(w) (( w & MSD_SIF_BSD_BASE_ADDR_MASK ) << MSD_SIF_BSD_BASE_ADDR_POS )
+#define MSD_SIF_PUT_DBFC_BASE(w) (( w & MSD_SIF_DBFC_BASE_ADDR_MASK ) << MSD_SIF_DBFC_BASE_ADDR_POS )
+#define MSD_SIF_PUT_RSB_USE_APB(w) (( w & MSD_SIF_RSB_USE_APB_OFF_MASK ) << MSD_SIF_RSB_USE_APB_OFF_POS )
+
+#define MSD_SIF_MPRR_BASE_ADDR_POS 0x0
+#define MSD_SIF_MPRR_BASE_ADDR_MASK 0x3FFF
+#define MSD_SIF_MPRC_BASE_ADDR_POS 0x10
+#define MSD_SIF_MPRC_BASE_ADDR_MASK 0x3FFF
+
+#define MSD_SIF_PUT_MPRR_BASE(w) (( w & MSD_SIF_MPRR_BASE_ADDR_MASK ) << MSD_SIF_MPRR_BASE_ADDR_POS )
+#define MSD_SIF_PUT_MPRC_BASE(w) (( w & MSD_SIF_MPRC_BASE_ADDR_MASK ) << MSD_SIF_MPRC_BASE_ADDR_POS )
+
+
+/* MVD VMIF Options */
+#define MSD_VMIF_TAG_ACK_ON_FLUSH_POS 0
+#define MSD_VMIF_MAX_RD_REQ_SIZE_POS 1
+#define MSD_VMIF_CACHE_ENAB_POS 3
+#define MSD_VMIF_CACHE_RST_STAT_POS 4
+#define MSD_VMIF_SPLIT_READS_POS 5
+#define MSD_VMIF_SPLIT_WRITES_POS 6
+#define MSD_VMIF_FS_OFFSET_8PIX_POS 7
+#define MSD_VMIF_FS_OFFSET_CHROMA_8PIX_POS 8
+#define MSD_VMIF_CACHE_16WAY_MODE_POS 9
+#define MSD_VMIF_SCALE_MODE_POS 10
+#define MSD_VMIF_RSB_EXT_CACHE_ENAB 11
+#define MSD_VMIF_MAX_RD_SIZE_CONFIG_POS 12
+#define MSD_VMIF_MBI_RD_BUS_ENAB_POS 13
+#define MSD_VMIF_CACHE_DIS_AUTO_RST_POS 15
+#define MSD_VMIF_MBI_WR_BUS_ENAB_POS 16
+
+#define MSD_VMIF_DISABLE_BIT_POS 18
+#define MSD_VMIF_USE_RPR_STRIDES_POS 19
+#define MSD_VMIF_DBG_SEL_POS 20
+#define MSD_VMIF_USE_4K_CACHE_CTRL_POS 23
+#define MSD_VMIF_4K_CACHE_ENAB_POS 24
+#define MSD_VMIF_4K_CACHE_RST_STAT_POS 25
+#define MSD_VMIF_4K_CACHE_DIS_AUTO_RST_POS 26
+#define MSD_VMIF_PACK_FORMAT_POS 27
+#define MSD_VMIF_CACHE_MODE_POS 28
+#define MSD_VMIF_MPSAL_POS 30
+#define MSD_VMIF_CLR_FSBA_POS 31
+
+/* Extension : MVD VMIF Options */
+/* With the introduction of Pixif some of thee bits have been re-used */
+#define MSD_VMIF_USE_FBC_RPR_MASK 0x08000000 /* Bit 27 */
+#define MSD_VMIF_USE_FBC_RPR_POS 27
+
+#define MSD_VMIF_USE_MBI_RD_RPR_POS 13
+#define MSD_VMIF_USE_MBI_RD_CSC_POS 14
+#define MSD_VMIF_USE_MBI_RD_MASK 0x0006000 /* Bits 14: 13 */
+
+#define MSD_VMIF_USE_MBI_WR_RPR_POS 23
+#define MSD_VMIF_USE_MBI_WR_CSC_POS 24
+#define MSD_VMIF_USE_MBI_WR_JPG_DBF_POS 25
+#define MSD_VMIF_USE_MBI_WR_MP2_VC1_POS 26
+#define MSD_VMIF_USE_MBI_WR_MASK 0x7800000 /* Bits 26: 23 */
+
+#define MSD_VMIF_MAX_RD_128 0
+#define MSD_VMIF_MAX_RD_256 1
+#define MSD_VMIF_MAX_RD_512 2
+
+/* MVD VMIF RSB ERT ARBITER CONTROL */
+
+#define MSD_VMIF_RSB_CLIENT_DBF 0x0
+#define MSD_VMIF_RSB_CLIENT_MPR 0x1
+#define MSD_VMIF_RSB_CLIENT_PXD 0x2
+#define MSD_VMIF_RSB_CLIENT_BSD 0x3
+#define MSD_VMIF_RSB_CLIENT_PWT 0x4
+#define MSD_VMIF_RSB_CLIENT_HUF 0x5
+#define MSD_VMIF_RSB_CLIENT_MTL 0x6
+#define MSD_VMIF_RSB_CLIENT_APB 0x7
+#define MSD_VMIF_RSB_CLIENT_XFR 0x8
+#define MSD_VMIF_RSB_CLIENT_BBD 0x9
+#define MSD_VMIF_RSB_CLIENT_CQ 0xa
+#define MSD_VMIF_RSB_CLIENT_BOB 0xb
+#define MSD_VMIF_RSB_CLIENT_DFE 0xb /* Yes this is deliberately the same - they replace the other in certain core configs */
+#define MSD_VMIF_RSB_CLIENT_CQBE 0xc
+
+#define MVD_RSB_ARB_CLIENT_MASK 0xFFFF
+#define MVD_RSB_ARB_READ_CLIENT_SHIFT 0x10
+
+/* RSB Defines */
+
+#define MSD_RSB_XFR_TYPE_LUMA 0x0
+#define MSD_RSB_XFR_TYPE_CHROMA 0x1
+#define MSD_RSB_XFR_TYPE_MBINFO 0x2
+#define MSD_RSB_XFR_TYPE_DATA 0x3
+
+#define MSD_RSB_MODE_ONCHIP_TOEXT 0x0 // direct is chip to ext ; is chip transaction with ext ;
+#define MSD_RSB_MODE_OFFCHIP_TOEXT 0x1 // direct is OFF chip to ext ; is off RSB transaction with ext ; off RSB is usable ; on chip not used
+#define MSD_RSB_MODE_ONCHIP_FREXT 0x2 // direct is ext to chip ; is chip transaction with ext ;
+#define MSD_RSB_MODE_OFFCHIP_FREXT 0x3 // direct is ext to off RSB ; is off RSB transaction with ext ;off RSB is usable ; on chip not used
+#define MSD_RSB_APB_ACC_EN_BIT 0x80000000
+
+
+/* MSD RPR Defines */
+#define MSD_RPR_SIZE_WIDTH_POS 0
+#define MSD_RPR_SIZE_HEIGHT_POS 16
+#define MSD_RPR_SIZE_WIDTH_MASK 0x3fff //14 bits
+
+#define MSD_RPR_FILL_VALUE_Y_POS 0
+#define MSD_RPR_FILL_VALUE_U_POS 8
+#define MSD_RPR_FILL_VALUE_V_POS 16
+#define MSD_RPR_FILL_VALUE_MASK 0xff // 8bits
+
+#define MSD_RPR_CTRL_START_POS 0
+#define MSD_RPR_CTL_FILL_MODE_POS 1
+#define MSD_RPR_CTL_ROUNDING_POS 2
+#define MSD_RPR_CTL_H_PRIME_M_POS 8
+#define MSD_RPR_CTL_V_PRIME_N_POS 12
+#define MSD_RPR_CTL_PRIME_MASK 0xf
+#define MSD_RPR_CTL_IN_FS_IDC_POS 16
+#define MSD_RPR_CTL_OUT_FS_IDC_POS 24
+#define MSD_RPR_CTL_FS_IDC_MASK 0x1f
+
+#define MSD_RPR_CTRL_START_BIT 1
+
+#define MSD_RPR_STATUS_IN_PROG_POS 29
+
+
+/* Decoupled data packing */
+/* Pack Base Set */
+#define MSD_SIF_PLQ_PACK_ADDR_MASK 0xFFFFFFFF
+#define MSD_SIF_PLQ_PACK_ADDR_SHIFT 0x0
+
+#define MSD_SIF_SET_PLQ_PACK_ADDR( w ) (( w & MSD_SIF_PLQ_WRPACK_ADDR_MASK ) << MSD_SIF_PLQ_WRPACK_ADDR_SHIFT )
+
+/* PRB Bin configuration */
+#define MSD_SIF_PLQ_BIN_SIZE_MASK 0x3FFFFF
+#define MSD_SIF_PLQ_BIN_SIZE_SHIFT 0x0
+#define MSD_SIF_PLQ_NUM_BINS_MASK 0x3FF
+#define MSD_SIF_PLQ_NUM_BINS_SHIFT 0x16
+
+#define MSD_SIF_SET_PLQ_BIN_SIZE( w ) (( w & MSD_SIF_PLQ_BIN_SIZE_MASK ) << MSD_SIF_PLQ_BIN_SIZE_SHIFT )
+#define MSD_SIF_SET_PLQ_NUM_BINS( w ) (( w & MSD_SIF_PLQ_NUM_BINS_MASK ) << MSD_SIF_PLQ_NUM_BINS_SHIFT )
+
+/* DCP Bin configuration */
+#define MSD_SIF_DCP_START_BINDEX_MASK 0x3FF
+#define MSD_SIF_DCP_START_BINDEX_SHIFT 0x0
+#define MSD_SIF_DCP_NUM_BINS_MASK 0x3FF
+#define MSD_SIF_DCP_NUM_BINS_SHIFT 0xA
+
+#define MSD_SIF_SET_DCP_START_BINDEX( w )(( w & MSD_SIF_DCP_START_BINDEX_MASK ) << MSD_SIF_DCP_START_BINDEX_SHIFT )
+#define MSD_SIF_SET_DCP_NUM_BINS( w ) (( w & MSD_SIF_DCP_NUM_BINS_MASK ) << MSD_SIF_DCP_NUM_BINS_SHIFT )
+
+
+/////////////////////////////////////////////////////////////////////////////////
+// Function Prototypes
+/////////////////////////////////////////////////////////////////////////////////
+
+#endif /* _MVD_SIF_CONTROL_H_ */
+
+/* End of file */
diff --git a/drivers/mxc/vpu_legacy/Malone_Firmware/DecKLib/Incl/mvd_types.h b/drivers/mxc/vpu_legacy/Malone_Firmware/DecKLib/Incl/mvd_types.h
new file mode 100755
index 000000000000..ccd93d3e1d0f
--- /dev/null
+++ b/drivers/mxc/vpu_legacy/Malone_Firmware/DecKLib/Incl/mvd_types.h
@@ -0,0 +1,132 @@
+/***************************************************
+ Copyright (c) 2015 Amphion Semiconductor Ltd
+ All rights reserved.
+ ***************************************************
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ ****************************************************
+
+ Author : MediaIP FW Team
+ File name : mvd_types.h
+ Function : Used as a home for generic MVD base decoder
+ types
+
+ ***************************************************/
+
+#ifndef _MVD_TYPES_H_
+#define _MVD_TYPES_H_
+
+#include "basetype.h"
+
+///////////////////////////////////////////////////////
+// tAuxCRCData
+
+typedef struct
+{
+ u_int32 uDpbCRC2;
+ u_int32 uBSCRC;
+ u_int32 uCRC0;
+ u_int32 uCRC1;
+ u_int32 uCRC2;
+ u_int32 uCRC3;
+ u_int32 uCRC4;
+ u_int32 uCRC5;
+ u_int32 uCRC6;
+ u_int32 uCRC7;
+
+} tAuxCRCData, *ptAuxCRCData;
+
+///////////////////////////////////////////////////////
+// tAuxCRC2Data
+
+typedef struct
+{
+ u_int32 uCRC8;
+ u_int32 uCRC9;
+ u_int32 uCRC10;
+ u_int32 uCRC11;
+ u_int32 uCRC12;
+ u_int32 uCRC13;
+ u_int32 uCRC14;
+
+} tAuxCRC2Data, *ptAuxCRC2Data;
+
+#define MVD_TRUE 0x1UL
+#define MVD_FALSE 0x0UL
+
+typedef float MvdFloat; // fVariableName, *pfPointerName
+typedef double MvdDouble; // dVariableName, *pdPointerName
+
+typedef volatile u_int32 MvdHwReg; // rVariableName, *prPointerName
+typedef volatile u_int32 *MvdHwAddr;
+
+/* ************** */
+/* Debug arrays */
+/* ************** */
+typedef struct
+{
+ int32 index;
+ int32 array[512];
+} DBG_ARRAY_512;
+
+typedef struct
+{
+ int32 index;
+ int32 array[1024];
+} DBG_ARRAY_1024;
+
+typedef struct
+{
+ int32 index;
+ int32 array[2048];
+} DBG_ARRAY_2048;
+
+typedef struct
+{
+ int32 index;
+ int32 array[4096];
+} DBG_ARRAY_4096;
+
+///////////////////////////////////////////////////////
+// Metadata structs
+
+///////////////////////////////////////////////////////
+// TimeStamp Metadata
+
+typedef struct
+{
+ u_int32 uPTS;
+ u_int32 uDTS;
+ u_int32 uPESFlags;
+ bool bValid;
+
+} tMVD_METADATA_TS, *ptMVD_METADATA_TS;
+
+///////////////////////////////////////////////////////
+// Pic Struct Metadata
+
+typedef struct
+{
+ u_int32 uDummy;
+ bool bValid;
+
+} tMVD_METADATA_PIC_STRUCT, *ptMVD_METADATA_PIC_STRUCT;
+
+///////////////////////////////////////////////////////
+// UData Metadata
+
+typedef struct
+{
+ bool bValid;
+ void * pUDataMemChunk;
+ u_int32 uWrPtr;
+
+} tMVD_METADATA_UDATA, *ptMVD_METADATA_UDATA;
+
+#endif /* _MVD_TYPES_H_ */
+
+/* End of file */
diff --git a/drivers/mxc/vpu_legacy/Malone_Firmware/DecKLib/KernelIF/DecKernelLib.c b/drivers/mxc/vpu_legacy/Malone_Firmware/DecKLib/KernelIF/DecKernelLib.c
new file mode 100755
index 000000000000..ca7d70b55814
--- /dev/null
+++ b/drivers/mxc/vpu_legacy/Malone_Firmware/DecKLib/KernelIF/DecKernelLib.c
@@ -0,0 +1,152 @@
+/***************************************************
+ Copyright (c) 2015 Amphion Semiconductor Ltd
+ All rights reserved.
+ ***************************************************
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ ****************************************************
+
+ Filename: DecoderLib.c
+ Description: Decoder Library API level
+ Author: Media IP FW team (Belfast & Shanghai)
+
+ ****************************************************/
+
+/////////////////////////////////////////////////////////////////////////////////
+// Header files
+/////////////////////////////////////////////////////////////////////////////////
+
+#include "basetype.h"
+#include "mediaip_fw_types.h"
+#include "pal.h"
+#include "DecKernelLib.h"
+#include "DecKernelLibPrivate.h"
+#include "DecKernelLibCfg.h"
+
+/////////////////////////////////////////////////////////////////////////////////
+// Global Variables
+/////////////////////////////////////////////////////////////////////////////////
+
+DEC_KERNEL_LIB gDecKernelLib = { 0x0 };
+
+/////////////////////////////////////////////////////////////////////////////////
+// Code
+/////////////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////////////////
+// FUNCTION: decoder_kernel_lib_init //
+// //
+// DESCRIPTION: This function initialises the decoder library //
+// to be called from kernel space //
+// It's only purpose is to post interrupts via callback to a queue //
+// for processing in userspace //
+// //
+// INPUTS: pCfg - Pointer to a static configuration structure for the //
+// library //
+// //
+// OUTPUTS: None. //
+// //
+// RETURNS: MEDIAIP_FW_STATUS_ //
+// OK - Success. //
+// ALREADY_INIT - This function has already been called and no //
+// subsequent call to decoderlib_term made //
+// //
+// NOTES: None. //
+// //
+// CONTEXT: This function must be called from non-interrupt context //
+// //
+////////////////////////////////////////////////////////////////////////////////////
+
+MEDIAIP_FW_STATUS decoder_kernel_lib_init ( DECODERLIB_KERNEL_CFG * pCfg )
+{
+ MEDIAIP_FW_STATUS eRetCode = MEDIAIP_FW_STATUS_OK;
+
+ if ( gDecKernelLib.bInit == FALSE )
+ {
+ gDecKernelLib.bInit = TRUE;
+
+ /* Make all necessary init calls */
+ internal_decoder_kernel_lib_init ( pCfg );
+ }
+ else
+ {
+ eRetCode = MEDIAIP_FW_STATUS_ALREADY_INIT;
+ }
+
+ return eRetCode;
+
+}
+
+////////////////////////////////////////////////////////////////////////////////////
+// FUNCTION: decoderlib_register_event_callback //
+// //
+// DESCRIPTION: This function registers a handler for reporting decoder events //
+// //
+// INPUTS: hHandle - handle for the stream with which to register the //
+// callbacks //
+// pfCallback - Function ponter to be executed when a decoder //
+// event is raised //
+// //
+// OUTPUTS: None. //
+// //
+// RETURNS: MEDIAIP_FW_STATUS_ //
+// OK - Success. //
+// BAD_HANDLE - hHandle is not a valid decoder library //
+// handle //
+// //
+// NOTES: None. //
+// //
+// CONTEXT: Unknown if there are any constraints here as yet //
+// //
+////////////////////////////////////////////////////////////////////////////////////
+
+MEDIAIP_FW_STATUS decoder_kernel_lib_register_isr_callback ( u_int32 uMalIdx,
+ DecKernelLib_Isr_Callback_t pfCallback )
+{
+
+ if ( gDecKernelLib.bInit == FALSE )
+ {
+ pal_trace( DECODER_TL_WARNING, "DECODER_LIB: decoder_kernel_lib_register_isr_callback : Invalid Malone\n", uMalIdx );
+
+ return MEDIAIP_FW_STATUS_BAD_HANDLE;
+ }
+
+ internal_decoder_kernel_lib_register_isr_callback ( uMalIdx,
+ pfCallback );
+
+ return MEDIAIP_FW_STATUS_OK;
+
+}
+
+////////////////////////////////////////////////////////////////////////////////////
+// FUNCTION: decoderlib_term //
+// //
+// DESCRIPTION: Deinitialises decode library //
+// //
+// INPUTS: None //
+// //
+// OUTPUTS: None. //
+// //
+// RETURNS: MEDIAIP_FW_STATUS_ //
+// OK - Success. //
+// //
+// NOTES: None. //
+// //
+// CONTEXT: This function must be called from non-interrupt context //
+// //
+////////////////////////////////////////////////////////////////////////////////////
+
+MEDIAIP_FW_STATUS decoder_kernel_lib_term ( )
+{
+ MEDIAIP_FW_STATUS eRetCode = MEDIAIP_FW_STATUS_OK;
+
+ gDecKernelLib.bInit = FALSE;
+
+ return eRetCode;
+
+}
+
diff --git a/drivers/mxc/vpu_legacy/Malone_Firmware/DecKLib/KernelIF/DecKernelLibCfg.h b/drivers/mxc/vpu_legacy/Malone_Firmware/DecKLib/KernelIF/DecKernelLibCfg.h
new file mode 100755
index 000000000000..8cee711dc10c
--- /dev/null
+++ b/drivers/mxc/vpu_legacy/Malone_Firmware/DecKLib/KernelIF/DecKernelLibCfg.h
@@ -0,0 +1,95 @@
+/***************************************************
+ Copyright (c) 2015 Amphion Semiconductor Ltd
+ All rights reserved.
+ ***************************************************
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ ****************************************************
+
+ Filename: DecLibCfg.h
+ Description: Decoder Library Configuration
+ Author: Media IP FW team (Belfast & Shanghai)
+
+ *******************************************************/
+
+#ifndef _DECODER_LIB_CFG_H_
+#define _DECODER_LIB_CFG_H_
+
+/////////////////////////////////////////////////////////////////////////////////
+// Header files
+/////////////////////////////////////////////////////////////////////////////////
+
+#ifndef VPU_KERNEL_BUILD
+#include "video_subsystem.h"
+#endif
+#include "mediaip_fw_types.h"
+
+/////////////////////////////////////////////////////////////////////////////////
+// Global Macros
+/////////////////////////////////////////////////////////////////////////////////
+
+/* Local defines cast to those in global cfg file */
+#define DECODERLIB_MAX_MALONES MEDIAIP_MAX_NUM_MALONES
+#define DECODERLIB_MAX_DBE_UNITS 0x2
+
+/* These don't really need to be passed in the cfg methinks... */
+#define DECODERLIB_NUM_STREAMS NUM_DECODER_STREAMS
+#define DECODERLIB_MAX_NUM_FRAMES MAX_NUM_FRAMES_PER_STREAM
+#if HEVC_JVT_MODEL < 92
+#define DECODERLIB_MAX_MBI_FRAMES 0x12
+#else
+#define DECODERLIB_MAX_MBI_FRAMES 0x11
+#endif
+#define DECODERLIB_MAX_DFE_AREAS 0x1
+#define DECODERLIB_MAX_NUM_OVLP_FRMS 1
+#define DECODERLIB_METADATA_AREA_NULL 0xFF
+#define DECODERLIB_NUM_EVENTS_PER_STREAM 4
+#define DECODERLIB_NUM_CMDS_PER_STREAM 4
+
+#define DECODERLIB_MAX_MVC_DPID 1
+#define DECODERLIB_MAX_MVC_TARGET_VIEWS 2
+#define DECODERLIB_MAX_MVC_VIEWS 4
+
+#define DECODERLIB_MAX_DPVS 0x1
+#define DECODERLIB_PIXIF_MAX_UPIX_TARGETS 0x2
+#define DECODERLIB_PIXIF_MAX_FBC_TARGETS 0x2
+#define DECODERLIB_MAX_STREAM_LEVELS DECODERLIB_MAX_MVC_VIEWS
+
+
+#define DECODERLIB_MAX_STR_BUFFERS DECODERLIB_MAX_STREAM_LEVELS
+#define DECODERLIB_RC4_CONTEXT_VALS 66
+
+#if ( TARGET_LEVEL == HAPS ) || ( TARGET_LEVEL == SIMULATION )
+#define DECODERLIB_NUM_DBG_FIFOS 26
+#else
+#define DECODERLIB_NUM_DBG_FIFOS 1
+#endif
+
+#ifdef DECLIB_ENABLE_DCP
+#define DECODERLIB_MAX_CQ_PER_MALONE 0x3
+#else
+#define DECODERLIB_MAX_CQ_PER_MALONE 0x1
+#endif
+
+// Enable processing of PAFF streams
+// If defined Field frame storage choice is made at a picture level
+// otherwise it is made as a sequence level
+//#define PIXIF_STORE_AS_PAFF
+
+//-------------------------------------------------
+// Some options for testing different HW Configs
+//-------------------------------------------------
+//#define FSLCACHE0_BYPASS
+#define ALLOW_CHROMA_DP
+#define ALLOW_MPS_ALIGN
+#define ALLOW_OFFSET_FS
+//#define FORCE_UNCACHED_8x8
+//-------------------------------------------------
+
+#endif /* _DECODER_LIB_CFG_H_ */
+
+/* End of File */
diff --git a/drivers/mxc/vpu_legacy/Malone_Firmware/DecKLib/KernelIF/DecKernelLibPrivate.c b/drivers/mxc/vpu_legacy/Malone_Firmware/DecKLib/KernelIF/DecKernelLibPrivate.c
new file mode 100755
index 000000000000..1aee23588cc0
--- /dev/null
+++ b/drivers/mxc/vpu_legacy/Malone_Firmware/DecKLib/KernelIF/DecKernelLibPrivate.c
@@ -0,0 +1,171 @@
+/***************************************************
+ Copyright (c) 2015 Amphion Semiconductor Ltd
+ All rights reserved.
+ ***************************************************
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ ****************************************************
+
+ Filename: DecoderLibPrivate.c
+ Description: Decoder Library API level
+ Author: Kyle McAdoo - Media IP FW Team ( Belfast & Shanghai )
+
+ ***************************************************/
+
+/////////////////////////////////////////////////////////////////////////////////
+// Header files
+/////////////////////////////////////////////////////////////////////////////////
+
+#include "basetype.h"
+#include "mediaip_fw_types.h"
+#include "pal.h"
+#include "DecKernelLibPrivate.h"
+#include "DecKernelLibHWControl.h"
+
+/////////////////////////////////////////////////////////////////////////////////
+// Global Variables
+/////////////////////////////////////////////////////////////////////////////////
+
+u_int32 uMvdKernelIrqPin[DECODERLIB_MAX_MALONES][0x2];
+
+/////////////////////////////////////////////////////////////////////////////////
+// Extern function prototypes
+/////////////////////////////////////////////////////////////////////////////////
+
+extern DEC_KERNEL_LIB gDecKernelLib;
+extern MALONE_KERNEL_HW_SESSION gMvdKernelHw[(DECODERLIB_MAX_MALONES + 1)];
+
+extern MEDIAIP_IRQ_RETCODE mvd_kernel_hw_primary_isr ( u_int32 irq_val );
+extern MEDIAIP_IRQ_RETCODE mvd_kernel_hw_secondary_isr ( u_int32 irq_val );
+
+/////////////////////////////////////////////////////////////////////////////////
+// Code
+/////////////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////////////////
+// FUNCTION: internal_decoder_kernel_lib_init //
+// //
+// DESCRIPTION: This function initialises the decoder library //
+// more notes to follow when it works... //
+// //
+// INPUTS: None //
+// //
+// OUTPUTS: None. //
+// //
+// RETURNS: MEDIAIP_FW_STATUS_ //
+// OK - Success. //
+// BAD_PARAMETER - Configuration structure not initialised //
+// ALREADY_INIT - //
+// //
+// NOTES: None. //
+// //
+// CONTEXT: This function must be called from non-interrupt context //
+// //
+////////////////////////////////////////////////////////////////////////////////////
+
+MEDIAIP_FW_STATUS internal_decoder_kernel_lib_init ( DECODERLIB_KERNEL_CFG * pCfg )
+{
+ MEDIAIP_FW_STATUS RetCode = MEDIAIP_FW_STATUS_OK;
+
+ /* Parse interrupt config */
+ internal_decoder_kernel_lib_parse_cfg ( pCfg,
+ FALSE );
+
+ /* Setup hardware view of Malone */
+ mvd_kernel_hw_control_init ( pCfg );
+
+ return RetCode;
+}
+
+////////////////////////////////////////////////////////////////////////////////////
+// FUNCTION: internal_decoder_kernel_lib_register_isr_callback //
+// //
+// DESCRIPTION: This function registers handlers for event processing //
+// more notes to follow when it works... //
+// //
+// INPUTS: hHandle - handle for the stream with which to register the //
+// callbacks //
+// pfCallback - Function ponter to be executed when a decoder //
+// event is raised //
+// //
+// OUTPUTS: None. //
+// //
+// RETURNS: None. //
+// //
+// NOTES: None. //
+// //
+// CONTEXT: Unknown if there are any constraints here as yet //
+// //
+////////////////////////////////////////////////////////////////////////////////////
+
+void internal_decoder_kernel_lib_register_isr_callback ( u_int32 uMalIdx,
+ DecKernelLib_Isr_Callback_t pfCallback
+ )
+{
+ gDecKernelLib.pfCallback[uMalIdx] = pfCallback;
+}
+
+///////////////////////////////////////////////////////////////////////////////////
+// FUNCTION: internal_decoder_kernel_lib_parse_cfg //
+// //
+// DESCRIPTION: Update DecoderLib structs with info from the configuration //
+// //
+// INPUTS: pCfg - The DecLib configuration //
+// bCheck - A control variable which allows prints on changes in //
+// //
+// OUTPUTS: None. //
+// //
+// RETURNS: None. //
+// //
+// NOTES: Set bCheck in snapshot restarts to see what may be different //
+// in the configuration of the generation and restart platforms //
+// //
+// CONTEXT: Call from thread context //
+// //
+////////////////////////////////////////////////////////////////////////////////////
+
+void internal_decoder_kernel_lib_parse_cfg ( DECODERLIB_KERNEL_CFG * pCfg,
+ bool bCheck
+ )
+{
+ PAL_PFNISR pFnDecodeIsr;
+ u_int32 uMalIdx;
+
+ gDecKernelLib.uNumMalones = pCfg->uNumMalones;
+
+ for ( uMalIdx = 0x0; uMalIdx < gDecKernelLib.uNumMalones; uMalIdx++ )
+ {
+ uMvdKernelIrqPin[uMalIdx][0x0] = pCfg->uMaloneIrqPin[uMalIdx][0x0];
+ uMvdKernelIrqPin[uMalIdx][0x1] = pCfg->uMaloneIrqPin[uMalIdx][0x1];
+ }
+
+ /* Finally claim the interrupts */
+ pFnDecodeIsr = ( PAL_PFNISR )mvd_kernel_hw_primary_isr;
+ pal_int_register ( uMvdKernelIrqPin[0x0][0x0], pFnDecodeIsr, FALSE );
+ pFnDecodeIsr = ( PAL_PFNISR )mvd_kernel_hw_secondary_isr;
+
+ /* This is a safety check in case a lazy player does not setup the second irq */
+ if ( uMvdKernelIrqPin[0x0][0x0] != uMvdKernelIrqPin[0x0][0x1] )
+ {
+ pal_int_register ( uMvdKernelIrqPin[0x0][0x1], pFnDecodeIsr, FALSE );
+ }
+
+ if ( gDecKernelLib.uNumMalones > 0x1 )
+ {
+ pFnDecodeIsr = ( PAL_PFNISR )mvd_kernel_hw_primary_isr;
+ pal_int_register ( uMvdKernelIrqPin[0x1][0x0], pFnDecodeIsr, FALSE );
+ pFnDecodeIsr = ( PAL_PFNISR )mvd_kernel_hw_secondary_isr;
+
+ if ( uMvdKernelIrqPin[0x1][0x0] != uMvdKernelIrqPin[0x1][0x1] )
+ {
+ pal_int_register ( uMvdKernelIrqPin[0x1][0x1], pFnDecodeIsr, FALSE );
+ }
+ }
+}
+
+
+/* End of file */
diff --git a/drivers/mxc/vpu_legacy/Malone_Firmware/DecKLib/KernelIF/DecKernelLibPrivate.h b/drivers/mxc/vpu_legacy/Malone_Firmware/DecKLib/KernelIF/DecKernelLibPrivate.h
new file mode 100755
index 000000000000..a3dd00f62272
--- /dev/null
+++ b/drivers/mxc/vpu_legacy/Malone_Firmware/DecKLib/KernelIF/DecKernelLibPrivate.h
@@ -0,0 +1,69 @@
+/***************************************************
+ Copyright (c) 2015 Amphion Semiconductor Ltd
+ All rights reserved.
+ ***************************************************
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ ****************************************************
+
+ Filename: DecKernelPrivate.h
+ Description: Decoder Library Private header file - not
+ for inclusion by code outside of decoder lib.
+ Author: Media IP FW team (Belfast & Shanghai)
+
+ *******************************************************/
+
+/////////////////////////////////////////////////////////////////////////////////
+// Header files
+/////////////////////////////////////////////////////////////////////////////////
+
+#include "DecKernelLib.h"
+
+/* Include NO other files here */
+
+#ifndef _DECODER_KERN_LIB_PRIV_H_
+#define _DECODER_KERN_LIB_PRIV_H_
+
+
+/////////////////////////////////////////////////////////////////////////////////
+// Global Macros
+/////////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////////
+// Global Structures
+/////////////////////////////////////////////////////////////////////////////////
+
+//////////////////////////////////////////////////////////////
+// DecoderLib Context structure
+
+typedef struct decoderlib_inst
+{
+ bool bInit;
+ u_int32 uNumMalones;
+ /* One per Malone, kernel lib only has concept of Malone hardware, not */
+ /* the individual streams running on it! */
+ DecKernelLib_Isr_Callback_t pfCallback[DECODERLIB_MAX_MALONES];
+
+} DEC_KERNEL_LIB;
+
+/////////////////////////////////////////////////////////////////////////////////
+// Function Prototypes
+/////////////////////////////////////////////////////////////////////////////////
+
+MEDIAIP_FW_STATUS internal_decoder_kernel_lib_init ( DECODERLIB_KERNEL_CFG * pCfg );
+
+void internal_decoder_kernel_lib_register_isr_callback ( u_int32 uMalIdx,
+ DecKernelLib_Isr_Callback_t pfCallback
+ );
+
+ void internal_decoder_kernel_lib_parse_cfg ( DECODERLIB_KERNEL_CFG * pCfg,
+ bool bCheck
+ );
+
+#endif /* _DECODER_KERN_LIB_PRIV_H_ */
+
+/* End of File */
diff --git a/drivers/mxc/vpu_legacy/Malone_Firmware/Incl/basetype.h b/drivers/mxc/vpu_legacy/Malone_Firmware/Incl/basetype.h
new file mode 100755
index 000000000000..a90567ce278c
--- /dev/null
+++ b/drivers/mxc/vpu_legacy/Malone_Firmware/Incl/basetype.h
@@ -0,0 +1,343 @@
+/***************************************************
+ Copyright (c) 2015 Amphion Semiconductor Ltd
+ All rights reserved.
+ ***************************************************
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ ****************************************************
+ Filename: basetype.h
+ Description: Public header file for use in all FW
+ Author: Media IP FW team (Belfast)
+
+ ************************************************/
+
+#ifndef _BASETYPE_H_
+#define _BASETYPE_H_
+#ifndef VPU_KERNEL_BUILD
+#include <stdint.h>
+#include <stdio.h>
+#else
+#include <linux/types.h>
+#include <linux/kernel.h>
+#endif
+
+#ifdef WIN32
+#if _MSC_VER
+typedef unsigned __int64 u_int64;
+#else
+typedef unsigned long long u_int64;
+#endif
+#else
+typedef unsigned long long u_int64;
+#endif
+
+#ifdef MALONE_64BIT_ADDR
+typedef uint64_t uint_addr;
+#else
+typedef uint32_t uint_addr;
+#endif
+
+typedef uint32_t u_int32;
+typedef uint16_t u_int16;
+typedef uint8_t u_int8;
+
+//Alignment Macro
+#define ALIGN_SIZE(x) (((x)+sizeof(u_int32) - 1)/(sizeof(u_int32)))
+
+#ifdef WIN32
+#if _MSC_VER
+typedef signed __int64 int64;
+#else
+typedef signed long long int64;
+#endif
+#else
+typedef signed long long int64;
+#endif
+
+typedef int32_t int32;
+typedef int16_t int16;
+typedef int8_t int8;
+typedef unsigned char BYTE;
+
+// XXX:TAS No idea what all this ifdefing is about
+// should just need the C++ ifdef
+#ifndef HOST_BUILD
+#ifndef COREPLAY_API
+#ifndef _MSC_VER
+#ifndef VPU_KERNEL_BUILD
+typedef unsigned int bool;
+#endif
+#endif
+#else
+#ifndef _MSC_VER
+typedef unsigned int bool;
+#endif
+#endif
+#else
+ #ifndef __cplusplus
+ // bool is defined in cpp
+ typedef unsigned int bool;
+ #endif /* __cplusplus */
+#endif
+
+typedef unsigned char BOOLEAN;
+
+#define VOID_PARAMS void
+
+#define INT32 int32
+
+#define UINT8 u_int8
+#define UINT16 u_int16
+#define UINT32 u_int32
+#define UINT64 u_int64
+#ifdef _MSC_VER
+#define BOOL int
+#else
+#define BOOL bool
+#endif
+#define SINT8 int8
+#define SINT16 int16
+#define SINT32 int32
+#ifdef WIN32
+#define SINT64 int64
+#define SINT64_MIN (-9223372036854775807i64 - 1i64)
+#else
+#define SINT64 int64
+#define SINT64_MIN (-9223372036854775807LL - 1LL)
+#endif
+
+#ifndef VPU_KERNEL_BUILD
+#define SUCCESS 0
+#define FAILURE -1
+#endif
+
+#ifdef __cplusplus
+#ifndef FALSE
+ #define FALSE 0
+#endif
+#ifndef TRUE
+ #define TRUE 1
+#endif
+#else // 'C'
+#ifndef false
+ #define false 0
+#endif
+#ifndef true
+ #define true 1
+#endif
+
+#ifndef FALSE
+ #define FALSE 0
+#endif
+#ifndef TRUE
+ #define TRUE 1
+#endif
+#endif
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+#ifndef OKAY
+#define OKAY 0
+#endif
+
+#ifndef ZERO
+#define ZERO 0
+#endif
+
+// Define more error types as used - 1st is generic
+#define MEDIAIP_ERROR_FLAG 1
+#define MEDIAIP_END_ES 2
+#define MEDIAIP_DECODER_EXIT 3
+#define MEDIAIP_ENCODER_EXIT 4
+#define MEDIAIP_VC1D_NOFREEFRAMES 5
+#define MEDIAIP_DECODER_SKIP 6
+
+/* Alignment macros - align address to a specific byte alignment */
+#define MEDIAIP_ALIGN_16(addr) addr = (addr + (( 0x1 << 0x4 ) - 0x1 ) ) & ~((( 0x1 << 0x4 ) - 0x1 ))
+#define MEDIAIP_ALIGN_32(addr) addr = (addr + (( 0x1 << 0x5 ) - 0x1 ) ) & ~((( 0x1 << 0x5 ) - 0x1 ))
+#define MEDIAIP_ALIGN_64(addr) addr = (addr + (( 0x1 << 0x6 ) - 0x1 ) ) & ~((( 0x1 << 0x6 ) - 0x1 ))
+#define MEDIAIP_ALIGN_128(addr) addr = (addr + (( 0x1 << 0x7 ) - 0x1 ) ) & ~((( 0x1 << 0x7 ) - 0x1 ))
+#define MEDIAIP_ALIGN_256(addr) addr = (addr + (( 0x1 << 0x8 ) - 0x1 ) ) & ~((( 0x1 << 0x8 ) - 0x1 ))
+#define MEDIAIP_ALIGN_512(addr) addr = (addr + (( 0x1 << 0x9 ) - 0x1 ) ) & ~((( 0x1 << 0x9 ) - 0x1 ))
+
+/* used when declaring single bitfields
+*/
+#define FLAG 1
+
+#ifndef WIN32
+ #if CPU == MIPS
+ #define DOUBLE_ALIGN __attribute__((aligned(8)))
+ #define SECTION(sec) __attribute__ ((section (#sec)))
+ #define ALIGNED(ali) __attribute__ ((aligned (ali)))
+ #else
+ #define DOUBLE_ALIGN
+ #endif
+#endif // win32
+/* We need to stop defining ARM and use only CPU == ARM !!! */
+/* Lose all #ifdef ARM from code */
+
+/* - Only for RCVCT */
+#ifdef __CC_ARM
+ #define ALIGN_8_u_int8 __align(8) u_int8
+ #define ALIGN_8_u_int16 __align(8) u_int16
+ #define ALIGN_8_u_int32 __align(8) u_int32
+ #define ALIGN_256_u_int16 __align(256) u_int16
+ #define ALIGN_256_u_int32 __align(256) u_int32
+ #define ALIGN_1024_u_int32 __align(1024) u_int32
+ #define ALIGN_1024_u_int64 __align(1024) u_int64
+ #define ALIGN_1024 __align(1024)
+#else
+/* All others? */
+ #define ALIGN_8_u_int8 u_int8 __attribute__((aligned(8)))
+ #define ALIGN_8_u_int16 u_int16 __attribute__((aligned(8)))
+ #define ALIGN_8_u_int32 u_int32 __attribute__((aligned(8)))
+ #define ALIGN_256_u_int16 u_int16 __attribute__((aligned(256)))
+ #define ALIGN_256_u_int32 u_int32 __attribute__((aligned(256)))
+ #define ALIGN_1024_u_int32 u_int32 __attribute__((aligned(1024)))
+ #define ALIGN_1024_u_int64 u_int64 __attribute__((aligned(1024)))
+ #define ALIGN_1024 __attribute__((aligned(1024)))
+#endif
+
+#ifndef COREPLAY_API
+#if RTOS == UCOS
+
+/* Additions for uCOS */
+
+typedef unsigned char INT8U; /* Unsigned 8 bit quantity */
+typedef signed char INT8S; /* Signed 8 bit quantity */
+typedef unsigned int INT16U; /* Unsigned 16 bit quantity */
+typedef signed int INT16S; /* Signed 16 bit quantity */
+typedef unsigned long INT32U; /* Unsigned 32 bit quantity */
+typedef signed long INT32S; /* Signed 32 bit quantity */
+typedef float FP32; /* Single precision floating point */
+typedef double FP64; /* Double precision floating point */
+
+typedef unsigned int OS_STK; /* Each stack entry is 16-bit wide */
+typedef unsigned int OS_CPU_SR; /* Define size of CPU status register (PSR = 32 bits) */
+
+#define UBYTE INT8U /* ... to uC/OS V1.xx. Not actually needed for ... */
+#define WORD INT16S /* ... uC/OS-II. */
+#define UWORD INT16U
+#define LONG INT32S
+#define ULONG INT32U
+
+#endif
+
+typedef signed short int SHORT; /* Signed 16 bit quantity */
+typedef unsigned short USHORT;
+
+#endif /* COREPLAY_API */
+
+/****************************************************************************/
+/* */
+/* Hardware register access macros */
+/* */
+/****************************************************************************/
+
+#define RMO(y) \
+ ( ((y) & 0x00000001) ? 0 : \
+ ( ((y) & 0x00000002) ? 1 : \
+ ( ((y) & 0x00000004) ? 2 : \
+ ( ((y) & 0x00000008) ? 3 : \
+ ( ((y) & 0x00000010) ? 4 : \
+ ( ((y) & 0x00000020) ? 5 : \
+ ( ((y) & 0x00000040) ? 6 : \
+ ( ((y) & 0x00000080) ? 7 : \
+ ( ((y) & 0x00000100) ? 8 : \
+ ( ((y) & 0x00000200) ? 9 : \
+ ( ((y) & 0x00000400) ? 10 : \
+ ( ((y) & 0x00000800) ? 11 : \
+ ( ((y) & 0x00001000) ? 12 : \
+ ( ((y) & 0x00002000) ? 13 : \
+ ( ((y) & 0x00004000) ? 14 : \
+ ( ((y) & 0x00008000) ? 15 : \
+ ( ((y) & 0x00010000) ? 16 : \
+ ( ((y) & 0x00020000) ? 17 : \
+ ( ((y) & 0x00040000) ? 18 : \
+ ( ((y) & 0x00080000) ? 19 : \
+ ( ((y) & 0x00100000) ? 20 : \
+ ( ((y) & 0x00200000) ? 21 : \
+ ( ((y) & 0x00400000) ? 22 : \
+ ( ((y) & 0x00800000) ? 23 : \
+ ( ((y) & 0x01000000) ? 24 : \
+ ( ((y) & 0x02000000) ? 25 : \
+ ( ((y) & 0x04000000) ? 26 : \
+ ( ((y) & 0x08000000) ? 27 : \
+ ( ((y) & 0x10000000) ? 28 : \
+ ( ((y) & 0x20000000) ? 29 : \
+ ( ((y) & 0x40000000) ? 30 : \
+ ( ((y) & 0x80000000) ? 31 : 0 ))))))))))))))))))))))))))))))))
+
+/*
+ * Access macros used to get, set/clear bits within a hardware register.
+ * These macros *do not* perform any automatic shifting of bits and are
+ * meant to be used with bit definitions which include their encoded bit
+ * position within the register definition (e.g. an enable bit).
+ */
+
+#ifdef VSIM_ENV
+ UINT32 MEDIAIP_GET(UINT32,UINT32);
+ void MEDIAIP_SET(UINT32,UINT32,UINT32);
+ #define MEDIAIP_PUT(reg,mask,val) { \
+ VSimAPI_WriteRegister((UINT32) reg, val); \
+ }
+ UINT32 MEDIAIP_SM_GET(volatile UINT32 *);
+ void MEDIAIP_SM_SET(volatile UINT32 *, UINT32, UINT32 );
+ void MEDIAIP_SM_PUT(volatile UINT32 *, UINT32 );
+
+#else
+
+ #define MEDIAIP_GET(reg,mask) (*(LPREG)(reg) & (mask))
+ #define MEDIAIP_SET(reg,mask,val) (*(LPREG)(reg)) = ((*(LPREG)(reg) & ~(mask)) | ((val) & (mask)))
+ #define MEDIAIP_PUT(reg,val) (*(LPREG)(reg)) = (val)
+ #define MEDIAIP_SM_GET(x) (*(x))
+ #define MEDIAIP_SM_SET(a,b,c) (*(a)) = (((*(a)) & ~(b)) | ((c) & (b)))
+ #define MEDIAIP_SM_PUT(a,b) (*(a)) = (b)
+
+// IDJ: Consider using this?
+// No- there are only a few instances where this would make a difference.
+//efine MEDIAIP_SET(reg,mask,val) (*(LPREG)(reg)) = ((~(mask) ? 0 : (*(LPREG)(reg) & ~(mask))) | ((val) & (mask)))
+
+#endif
+
+/*
+ * Access macros used to get & set a numerical value within a hardware
+ * register. These macros perform automatic shifting (based on the mask)
+ * of the numerical value used. These macros are useful for setting a
+ * numerical value into a multi-bit contiguous field within a register.
+ */
+#define MEDIAIP_GET_VAL(reg,mask) ((*(LPREG)(reg) & (mask)) >> RMO(mask))
+#define MEDIAIP_SET_VAL(reg,mask,val) (*(LPREG)(reg)) = \
+ ((*(LPREG)(reg) & ~(mask)) | (((unsigned long)(val) << RMO(mask)) & (mask)))
+
+#define MEDIAIP_REGWRITE(reg,val) *((LPREG)(reg)) = (val)
+#define MEDIAIP_REGREAD(reg) *((LPREG)(reg))
+
+
+#define MEDIAIP_SET_REG(reg,mask,val) reg = ((reg & ~(mask)) | ((val) & (mask)))
+#define MEDIAIP_GET_REG(reg,mask) reg & mask
+
+typedef unsigned long HW_DWORD; /* was u_int32; */
+typedef unsigned short HW_WORD; /* was u_int16; */
+typedef unsigned char HW_BYTE; /* was u_int8; */
+typedef unsigned int HW_BOOL; /* was bool; */
+typedef void HW_VOID;
+
+typedef volatile u_int32 *LPREG;
+
+#ifdef __CC_ARM
+#define FUNC_INLINE __inline
+#else
+#define FUNC_INLINE inline
+#endif
+
+#endif /* _BASETYPE_H_ */
+
+/* End of File */
+
diff --git a/drivers/mxc/vpu_legacy/Malone_Firmware/Incl/mediaip_fw_defines.h b/drivers/mxc/vpu_legacy/Malone_Firmware/Incl/mediaip_fw_defines.h
new file mode 100755
index 000000000000..ed825ce6e7f8
--- /dev/null
+++ b/drivers/mxc/vpu_legacy/Malone_Firmware/Incl/mediaip_fw_defines.h
@@ -0,0 +1,249 @@
+/***************************************************
+ Copyright (c) 2015 Amphion Semiconductor Ltd
+ All rights reserved.
+ ***************************************************
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ ****************************************************
+
+ Filename: mediaip_fw_defines.h
+ Description: Contains general definitions for
+ module based architecture
+ Author: Media IP FW team - Belfast
+
+ TODO-KMC - Should remove this file!!
+ **************************************************/
+
+#ifndef _MEDIAIP_FW_DEFINES_H_
+#define _MEDIAIP_FW_DEFINES_H_
+
+/* In use MACROS for use by types shared across modules */
+/* When adding new modules, endeavour to maintain the same 'position' as that suggested by the */
+/* module's position in the MEDIAIP_FW_HANDLE_TYPE enumeration - see Modules/Public/handle.h */
+
+#define IN_USE_DECODER ( 1 << 0x0 )
+#define IN_USE_ENCODER ( 1 << 0x1 )
+#define IN_USE_IMG_PORT ( 1 << 0x2 )
+#define IN_USE_DISPLAY ( 1 << 0x3 )
+#define IN_USE_VAMUX ( 1 << 0x4 )
+#define IN_USE_VIPP ( 1 << 0x5 )
+#define IN_USE_SYS_API ( 1 << 0x10 )
+
+/////////////////////////////////////////////////
+// Frame Store Display Data make-up
+
+// Read
+#define FRAME_STORE_DISP_DATA_FSID(r) ((r>>0)&0x3f)
+#define FRAME_STORE_DISP_DATA_RPT_FIRST_FLD(r) ((r>>15)&0x1) // IDJ: Pass RFF (borrow a bit from unused base addr field)
+#define FRAME_STORE_DISP_DATA_SPS_IDC_BITS(r) ((r>>16)&0x7)
+#define FRAME_STORE_DISP_DATA_DANG_FIELD_BIT(r) ((r>>19)&0x1)
+#define FRAME_STORE_DISP_DATA_FIELD_MODE_BIT(r) ((r>>20)&0x1)
+#define FRAME_STORE_DISP_DATA_BOT_FIRST_BIT(r) ((r>>21)&0x1)
+#define FRAME_STORE_DISP_DATA_SKIP_PIC_BITS(r) ((r>>22)&0x3)
+#define FRAME_STORE_DISP_DATA_SYS_DATA_BITS(r) ((r>>24)&0xFF)
+#define FRAME_STORE_DISP_DATA_FRAME_BADDR(r) ((r>>0)&0x7FFF)
+#define FRAME_STORE_DATAFIELDS(a) (a&0xffff8000) // IDJ - bit 15 used above
+
+// Write
+#define FRAME_STORE_DISP_DATA_PUT_FSID(a) ((a&0x3f) << 0)
+#define FRAME_STORE_DISP_DATA_PUT_FRAME_BADDR(a) ((a&0x7fff) << 0)
+#define FRAME_STORE_DISP_DATA_PUT_DUPLC_FRAME_SENT(a) ((a&0x1) << 14) // RayC/JKD: but used to control when duplicate frames are sent
+#define FRAME_STORE_DISP_DATA_PUT_DUPLC_FRAME_SENT_GET(a) ((a>>14)&0x1)
+#define FRAME_STORE_DISP_DATA_PUT_RPT_FIRST_FIELD(a) ((a&0x1) << 15) // IDJ Borrow a bit from BADDR field (not used)
+#define FRAME_STORE_DISP_DATA_PUT_DISP_PARAM_ID(a) ((a&0x7) << 16)
+#define FRAME_STORE_DISP_DATA_PUT_DANGLING_FIELD(a) ((a&0x1) << 19)
+#define FRAME_STORE_DISP_DATA_PUT_FIELD_MODE(a) ((a&0x1) << 20)
+#define FRAME_STORE_DISP_DATA_PUT_BOT_FIELD_FIRST(a) ((a&0x1) << 21)
+#define FRAME_STORE_DISP_DATA_PUT_TOP_SKIPPED(a) ((a&0x1) << 22)
+#define FRAME_STORE_DISP_DATA_PUT_BOT_SKIPPED(a) ((a&0x1) << 23)
+#define FRAME_STORE_DISP_DATA_PUT_SYS_DATA(a) ((a&0xff) << 24)
+
+#define NUM_DISP_PUSHES_MASK 0xFF00
+#define NUM_DISP_PUSHES_POS 8
+#define NUM_DISP_PUSHES_SET(x) (x<<NUM_DISP_PUSHES_POS)
+#define NUM_DISP_PUSHES_GET(x) ( (x&NUM_DISP_PUSHES_MASK) >> NUM_DISP_PUSHES_POS)
+
+/////////////////////////////////////////////////
+// Display Params
+
+#define DISP_INFO_USER_DATA_ATTACHED_MASK 0x1
+#define DISP_INFO_USER_DATA_ATTACHED_POS 0
+#define DISP_INFO_GET_USER_DATA_ATTACHED(x) ((x&DISP_INFO_USER_DATA_ATTACHED_MASK)>>DISP_INFO_USER_DATA_ATTACHED_POS)
+#define DISP_INFO_USER_DATA_MASK 0xFFFF
+#define DISP_INFO_USER_DATA_POS 16
+#define DISP_INFO_GET_USER_DATA(x) ((x>>DISP_INFO_USER_DATA_POS)&DISP_INFO_USER_DATA_MASK)
+
+// uScanFormat defines
+
+#define DISP_SCAN_FORMAT_INTERLACED 0x0
+#define DISP_SCAN_FORMAT_PROGRESSIVE 0x1
+#define DISP_SCAN_FORMAT_VALID_GET(r) (r&0x1)
+#define DISP_SCAN_FORMAT_GET(r) ((r&0x2)>>1)
+#define DISP_SCAN_FORMAT_VALID_SET(r) ((r&0x1)<<0)
+#define DISP_SCAN_FORMAT_SET(r) ((r&0x1)<<1)
+
+/////////////////////////////////////////////////
+// General defines - base on Stream descriptor for Pecos
+
+#define STOP_IMMEDIATE 0x0
+#define STOP_COMPLETE_DISPLAY 0x1
+
+#define FORMAT_VC1 0x2
+#define FORMAT_MPEG2 0x1
+#define FORMAT_MPEG4 0x0
+#define FORMAT_MPEG2_DBEN 0x1
+#define FORMAT_MPEG2_DBDRNGEN 0x2
+
+#define STREAM_MODE_ES 0x1
+#define STREAM_MODE_PES 0x0
+
+#define DELIVERY_MODE_TSP_DIRECT 0x0
+#define DELIVERY_MODE_BSP 0x1
+#define DELIVERY_MODE_BSDMA 0x2
+
+// Buffer Indices
+#define SD_BUFIND_ESBUF_MASK 0xFF
+#define SD_BUFIND_ESBUF_SHIFT 0
+#define SD_BUFIND_STC_MASK 0x30000
+#define SD_BUFIND_STC_SHIFT 16
+#define SD_BUFIND_ESBUF_GET(x) ((x&SD_BUFIND_ESBUF_MASK)>>SD_BUFIND_ESBUF_SHIFT)
+#define SD_BUFIND_STC_GET(x) ((x&SD_BUFIND_STC_MASK)>>SD_BUFIND_STC_SHIFT)
+
+#define UD_ORDER_DECODE 0x1
+#define UD_ORDER_DISPLAY 0x2
+#define UD_ORDER_DECODEANDDISPLAY 0x3
+
+#define PRINT_UART4(a,b,c,d)
+#define PRINT_UART5(a,b,c,d,e)
+
+#define DISPLAY_ASPECT_RATIO_4_3 0x2
+#define DISPLAY_ASPECT_RATIO_16_9 0x3
+
+
+/////////////////////////////////////////////////
+// PTS capture descriptor flags
+#define PTS_DESCRIPTOR_PTS_LO 0x00000000
+#define PTS_DESCRIPTOR_DTS_LO 0x00000004
+#define PTS_DESCRIPTOR_FLAGS 0x00000008
+#define PTS_DESCRIPTOR_WRAP_COUNT 0x00000009
+#define PTS_DESCRIPTOR_TIMEBASE_ID 0x0000000A
+#define PTS_DESCRIPTOR_MATURITY_ADDRESS 0x0000000C
+
+#define PTS_DESCRIPTOR_FLAG_PTS_HI_MASK 0x00000001
+#define PTS_DESCRIPTOR_FLAG_PTS_HI_BIT 0
+#define PTS_DESCRIPTOR_FLAG_DTS_HI_MASK 0x00000002
+#define PTS_DESCRIPTOR_FLAG_DTS_HI_BIT 1
+#define PTS_DESCRIPTOR_FLAG_STC_PARITY_MASK 0x00000004
+#define PTS_DESCRIPTOR_FLAG_STC_PARITY_BIT 2
+#define PTS_DESCRIPTOR_FLAG_PENDING_MASK 0x00000008
+#define PTS_DESCRIPTOR_FLAG_PENDING_BIT 3
+#define PTS_DESCRIPTOR_FLAG_PESERROR_MASK 0x00000010
+#define PTS_DESCRIPTOR_FLAG_PESERROR_BIT 4
+
+#define PTS_DESCRIPTOR_FLAG_ADDRESS_WRAP_COUNT_BIT 8
+#define PTS_DESCRIPTOR_FLAG_ADDRESS_WRAP_COUNT_MASK 0x0000FF00
+#define PTS_DESCRIPTOR_FLAG_TIMEBASE_ID_BIT 16
+#define PTS_DESCRIPTOR_FLAG_TIMEBASE_ID_MASK 0x000F0000
+#define PTS_DESCRIPTOR_FLAG_AVC_TAG_BIT 24
+#define PTS_DESCRIPTOR_FLAG_AVC_TAG_MASK 0xFF000000
+
+// PTS debug descriptor extensions
+#define PTS_DESCRIPTOR_DEBUG 0x00000010
+#define PTS_DESCRIPTOR_DEBUG_PTS_DTS 0x00000010
+#define PTS_DESCRIPTOR_DEBUG_STC_SNAPSHOT 0x00000014
+#define PTS_DESCRIPTOR_DEBUG_DIFFERENCE 0x00000018
+#define PTS_DESCRIPTOR_DEBUG_FLAGS 0x0000001C
+
+#define PTS_DESCRIPTOR_DEBUG_FLAG_NO_PTS 0x00000001
+#define PTS_DESCRIPTOR_DEBUG_FLAG_NO_STC 0x00000002
+#define PTS_DESCRIPTOR_DEBUG_FLAG_IS_DTS 0x00000004
+#define PTS_DESCRIPTOR_DEBUG_FLAG_RUNNING 0x00000008
+#define PTS_DESCRIPTOR_DEBUG_FLAG_INSANE 0x00000010
+#define PTS_DESCRIPTOR_DEBUG_FLAG_STC_B 0x00000020
+#define PTS_DESCRIPTOR_DEBUG_FLAG_STC_CURRENT 0x00000040
+#define PTS_DESCRIPTOR_DEBUG_FLAG_TIMEBASE_MISMATCH 0x00000080
+#define PTS_DESCRIPTOR_DEBUG_FLAG_LATE 0x00000100
+#define PTS_DESCRIPTOR_DEBUG_FLAG_EARLY 0x00000200
+#define PTS_DESCRIPTOR_DEBUG_FLAG_VERY_LATE 0x00000100
+
+/////////////////////////////////////////////////
+// Tag descriptor defines
+// Flag definitions
+#define TAGLIST_SEI_PIC_STRUCT_FLAG_MASK 0x1
+#define TAGLIST_SEI_PIC_STRUCT_FLAG_SHIFT 0
+#define TAGLIST_SEI_FRAME_FREEZE_FLAG_MASK 0x2
+#define TAGLIST_SEI_FRAME_FREEZE_FLAG_SHIFT 1
+#define TAGLIST_SEI_FRAME_RELEASE_FLAG_MASK 0x4
+#define TAGLIST_SEI_FRAME_RELEASE_FLAG_SHIFT 2
+#define TAGLIST_SEI_SKIP_FLAG_MASK 0x8
+#define TAGLIST_SEI_SKIP_FLAG_SHIFT 3
+
+//////////////////////////////////////////////////////////////
+// Frame status ~ TEMP
+#define FRAME_INUSE_BYIPP 0x1
+#define FRAME_FREE 0x0
+
+//////////////////////////////////////////////////////////////
+// Scan format ~ TEMP
+#define SCAN_FORMAT_INTERLACED 0x0
+#define SCAN_FORMAT_PROGRESSIVE 0x1
+#define SCAN_FORMAT_VALID_GET(r) (r&0x1)
+#define SCAN_FORMAT_GET(r) ((r&0x2)>>1)
+#define SCAN_FORMAT_VALID_SET(r) ((r&0x1)<<0)
+#define SCAN_FORMAT_SET(r) ((r&0x1)<<1)
+
+//////////////////////////////////////////////////////////////
+// Internal System Control Defines
+
+#define NO_INTERNAL_CONTROL 0xFF
+#define SFD_INTERNAL_CONTROL 0x1
+#define AUTORECOVER_INTERNAL_CONTROL 0x2
+
+//////////////////////////////////////////////////////////////
+// SVC specific defines
+#define MEDIAIP_MAX_SVC_DID 0x3
+#define MEDIAIP_MAX_SVC_STR_BUFFERS 0x3
+
+//////////////////////////////////////////////////////////////
+// Malone specific defines
+#define MEDIAIP_MAX_NUM_MALONES 0x2
+#define MEDIAIP_MAX_NUM_MALONE_IRQ_PINS 0x2
+
+#define MEDIAIP_MAX_NUM_FSLCACHES 0x4
+
+//////////////////////////////////////////////////////////////
+// Windsor specific defines
+#define MEDIAIP_MAX_NUM_WINDSORS 0x1
+#define MEDIAIP_MAX_NUM_WINDSOR_IRQ_PINS 0x2
+
+//////////////////////////////////////////////////////////////
+// Subsystem specific defines
+#define MEDIAIP_MAX_NUM_IRQ_PINS 0x10
+#define MEDIAIP_MAX_NUM_CMD_IRQ_PINS 0x2
+#define MEDIAIP_MAX_NUM_MSG_IRQ_PINS 0x1
+#define MEDIAIP_MAX_NUM_TIMER_IRQ_PINS 0x4
+#define MEDIAIP_MAX_NUM_TIMER_IRQ_SLOTS 0x4
+
+#define SUBSYSTEM_CFG_MAGIC_COOKIE 0xB0B1B2B3
+
+//////////////////////////////////////////////////////////////
+// Max supported picture resolution, except H.264 and JPEG
+
+#define MEDIAIP_MAX_PIC_WIDTH 2048
+#define MEDIAIP_MAX_PIC_HEIGHT 2048
+
+//////////////////////////////////////////////////////////////
+// Encoder user data programming vals
+
+#define MEDIAIP_ENC_USER_DATA_WORDS 16
+#define MEDIAIP_ENC_USER_DATA_BYTES ( MEDIAIP_ENC_USER_DATA_WORDS << 2 )
+
+
+
+#endif /* _MEDIAIP_FW_DEFINES_H_ */
+
+/* End of File */
diff --git a/drivers/mxc/vpu_legacy/Malone_Firmware/Incl/mediaip_fw_types.h b/drivers/mxc/vpu_legacy/Malone_Firmware/Incl/mediaip_fw_types.h
new file mode 100755
index 000000000000..98ff57773a27
--- /dev/null
+++ b/drivers/mxc/vpu_legacy/Malone_Firmware/Incl/mediaip_fw_types.h
@@ -0,0 +1,1991 @@
+/***************************************************
+ Copyright (c) 2015 Amphion Semiconductor Ltd
+ All rights reserved.
+ ***************************************************
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ ****************************************************
+
+ Filename: mediaip_fw_types.h
+ Description: Contains structure definitions common
+ to multiple modules / layers
+ Author: Media IP FW team - Belfast / Shanghai
+
+ ****************************************************/
+
+#ifndef _MEDIAIP_FW_TYPES_H_
+#define _MEDIAIP_FW_TYPES_H_
+
+#include "basetype.h"
+#include "mediaip_fw_defines.h"
+
+//////////////////////////////////////////////////////////////
+// Generic Stream format
+
+typedef enum
+{
+ MEDIA_IP_FMT_NULL = 0x0,
+ MEDIA_IP_FMT_AVC = 0x1,
+ MEDIA_IP_FMT_VC1 = 0x2,
+ MEDIA_IP_FMT_MP2 = 0x3,
+ MEDIA_IP_FMT_AVS = 0x4,
+ MEDIA_IP_FMT_ASP = 0x5,
+ MEDIA_IP_FMT_JPG = 0x6,
+ MEDIA_IP_FMT_RV = 0x7,
+ MEDIA_IP_FMT_VP6 = 0x8,
+ MEDIA_IP_FMT_SPK = 0x9,
+ MEDIA_IP_FMT_VP8 = 0xA,
+ MEDIA_IP_FMT_MVC = 0xB,
+ MEDIA_IP_FMT_VP3 = 0xC,
+ MEDIA_IP_FMT_HEVC = 0xD,
+ MEDIA_IP_FMT_AUTO_DETECT = 0xAD00,
+ MEDIA_IP_FMT_ALL = (int)0xAAAAAAAA,
+ MEDIA_IP_FMT_UNSUPPORTED = (int)0xFFFFFFFF,
+ MEDIA_IP_FMT_LAST = MEDIA_IP_FMT_UNSUPPORTED
+
+} MEDIA_IP_FORMAT;
+
+//////////////////////////////////////////////////////////////
+// Generic picture Structure
+
+typedef enum
+{
+ MEDIAIP_TOP_FIELD,
+ MEDIAIP_BOT_FIELD,
+ MEDIAIP_TWO_FIELDS,
+ MEDIAIP_FRAME_PICTURE
+
+} MEDIAIP_PIC_STRUCT;
+
+//////////////////////////////////////////////////////////////
+// Generic picture type
+
+typedef enum
+{
+ MEDIAIP_I_PICTYPE = 1,
+ MEDIAIP_P_PICTYPE,
+ MEDIAIP_B_PICTYPE,
+ MEDIAIP_UNDEF_PICTYPE
+
+} MEDIAIP_PIC_TYPE;
+
+//////////////////////////////////////////////////////////////
+// Stream Layer
+
+typedef enum
+{
+ MEDIAIP_BASE_LAYER = 0,
+ MEDIAIP_ENHANCEMENT_LAYER
+
+} MEDIAIP_LAYER;
+
+//////////////////////////////////////////////////////////////
+// Display module - sync state
+
+typedef enum
+{
+ DISP_SYNC_UNINITIALISED = 0,
+ DISP_SYNC_ACQUIRING,
+ DISP_SYNC_ACQUIRED,
+ DISP_SYNC_LOST,
+ DISP_SYNC_LOST_INVALID,
+ DISP_SYNC_LOST_INSANE
+
+} MEDIAIP_DISP_SYNC_STATE;
+
+//////////////////////////////////////////////////////////////
+// PES HW state
+
+typedef enum
+{
+ PES_STATE_NORMAL = 0,
+ PES_STATE_PTS_BACKTOBACK,
+ PES_STATE_PTS_WITH_SLICE,
+ PES_STATE_PTS_WITH_PIC
+
+} MEDIAIP_PES_STATE;
+
+//////////////////////////////////////////////////////////////
+// Playback mode
+
+typedef enum
+{
+ MEDIAIP_PLAYMODE_CONNECTIVITY = 0,
+ MEDIAIP_PLAYMODE_BROADCAST,
+ MEDIAIP_PLAYMODE_BROADCAST_DSS,
+ MEDIAIP_PLAYMODE_LAST = MEDIAIP_PLAYMODE_BROADCAST_DSS
+
+} MEDIA_IP_PLAYMODE;
+
+//////////////////////////////////////////////////////////////
+// System mode
+
+typedef enum
+{
+ MEDIAIP_SYSMODE_DTV = 0,
+ MEDIAIP_SYSMODE_STB,
+ MEDIAIP_SYSMODE_LAST = MEDIAIP_SYSMODE_STB
+
+} MEDIA_IP_SYSMODE;
+
+//////////////////////////////////////////////////////////////
+// Encoder Output Info
+typedef struct
+{
+ u_int32 uStrIndex;
+ BOOL bLastFrame;
+ BOOL bEndOfGOP;
+ u_int32 uEsStruct;
+ u_int32 uMsbPTS;
+ u_int32 uPTS;
+ u_int32 uVesSize;
+ u_int32 uCbFrmStartAddr;
+
+} MEDIAIP_ENCODER_OUTPUT_INFO;
+
+//////////////////////////////////////////////////////////////
+// YUV Output Info
+
+#ifndef HOST_BUILD
+#ifndef _MSC_VER
+typedef enum
+{
+ YUV420 = 0x0,
+ YUV422,
+ YUV400
+
+} MEDIAIP_FW_FRAME_FMT;
+#endif // _MSC_VER
+#endif
+
+//////////////////////////////////////////////////////////////
+// Frame Display info
+
+typedef struct
+{
+ u_int32 top_field_first;
+ u_int32 repeat_first_field;
+ u_int32 disp_vert_res;
+ u_int32 disp_horiz_res;
+ u_int32 centre_vert_offset;
+ u_int32 centre_horiz_offset;
+
+} MEDIAIP_PIC_DISP_INFO;
+
+//////////////////////////////////////////////////////////////
+// Frame info
+
+typedef struct
+{
+ MEDIAIP_PIC_TYPE pic_type;
+ u_int32 pic_struct;
+ u_int32 pic_st_addr;
+ u_int32 last_pic_npf;
+ u_int32 user_data_avail;
+ u_int32 frame_store_id;
+ u_int32 uPercentInErr;
+ u_int32 view_id; /* H264 MVC */
+ u_int32 uVOIdx; /* H264 MVC */
+#if MVC_SUPPORT == MVC_ENABLED
+ u_int32 uViewId;
+#endif
+ u_int32 uSkipInProg;
+
+} MEDIAIP_PIC_INFO;
+
+//////////////////////////////////////////////////////////////
+// Memory request type enum
+
+typedef enum
+{
+ MEDIAIP_FRAME_REQ = 0,
+ MEDIAIP_MBI_REQ,
+ MEDIAIP_DCP_REQ,
+ MEDIAIP_REQ_LAST = MEDIAIP_DCP_REQ
+
+} MEDIAIP_MEM_REQ;
+
+//////////////////////////////////////////////////////////////
+// Memory request ctrl
+
+typedef struct
+{
+ u_int32 uLayerIdx;
+ MEDIAIP_MEM_REQ eType;
+
+} MEDIAIP_MEM_REQ_CTRL, *pMEDIAIP_MEM_REQ_CTRL;
+
+//////////////////////////////////////////////////////////////
+// Memory release ctrl
+
+typedef struct
+{
+ u_int32 uLayerIdx;
+ u_int32 uFSIdx;
+ MEDIAIP_MEM_REQ eType;
+
+} MEDIAIP_MEM_REL_CTRL, *pMEDIAIP_MEM_REL_CTRL;
+
+////////////////////////////////////////////////////////
+// Media IP mem alloc struct
+
+typedef struct
+{
+ MEDIAIP_MEM_REQ eType;
+ u_int32 uLayerIdx;
+
+ u_int32 uFSHandle;
+ u_int32 uBaseAddr;
+ u_int32 uStride;
+ u_int32 uChromaOffset;
+
+} MEDIAIP_MEM_ALLOC_CTRL, *pMEDIAIP_MEM_ALLOC_CTRL;
+
+//////////////////////////////////////////////////////////////
+// Decoder metrics info
+
+typedef struct
+{
+ u_int32 uDpbmcCrc;
+ u_int32 uFrameActiveCount;
+ u_int32 uSliceActiveCount;
+ u_int32 uRbspBytesCount;
+ u_int32 uSibWaitCount;
+ u_int32 uDpbReadCount;
+ u_int32 uMprWaitCount;
+ u_int32 uBBBCrc;
+ u_int32 uAccQP;
+ u_int32 uCacheStat;
+ u_int32 uCRCSkip;
+ u_int32 uCRCDrop;
+ BOOL bCRCValid;
+
+ u_int32 uBaseDpbMcCrc;
+ u_int32 uByteStreamCrc;
+
+ u_int32 uCRC0;
+ u_int32 uCRC1;
+ u_int32 uCRC2;
+ u_int32 uCRC3;
+ u_int32 uCRC4;
+ u_int32 uCRC5;
+ u_int32 uCRC6;
+ u_int32 uCRC7;
+ u_int32 uCRC8;
+ u_int32 uCRC9;
+ u_int32 uCRC10;
+ u_int32 uCRC11;
+ u_int32 uCRC12;
+ u_int32 uCRC13;
+ u_int32 uCRC14;
+
+ u_int32 mbq_full;
+ u_int32 mbq_empty;
+ u_int32 slice_cnt;
+ u_int32 mb_count;
+
+ u_int32 uTotalTime_us;
+ u_int32 uTotalFwTime_us;
+
+ u_int32 uSTCAtFrameDone;
+
+ u_int32 uProcIaccTotRdCnt;
+ u_int32 uProcDaccTotRdCnt;
+ u_int32 uProcDaccTotWrCnt;
+ u_int32 uProcDaccRegRdCnt;
+ u_int32 uProcDaccRegWrCnt;
+ u_int32 uProcDaccRngRdCnt;
+ u_int32 uProcDaccRngWrCnt;
+
+} MEDIAIP_DEC_METRICS_INFO, *pMEDIAIP_DEC_METRICS_INFO;
+
+//////////////////////////////////////////////////////////////
+// GOP info
+
+typedef struct
+{
+ u_int32 closed_gop;
+ u_int32 broken_link;
+
+} MEDIAIP_GOP_INFO;
+
+//////////////////////////////////////////////////////////////
+// Stream frequency
+
+typedef enum
+{
+ MEDIAIP_FR_UNKNOWN = 0,
+ MEDIAIP_FR_23_97_HZ = 1,
+ MEDIAIP_FR_24_HZ = 2,
+ MEDIAIP_FR_25_HZ = 3,
+ MEDIAIP_FR_29_97_HZ = 4,
+ MEDIAIP_FR_30_HZ = 5,
+ MEDIAIP_FR_50_HZ = 6,
+ MEDIAIP_FR_59_94_HZ = 7,
+ MEDIAIP_FR_60_HZ = 8,
+ MEDIAIP_FR_7P992_HZ = 9,
+ MEDIAIP_FR_8_HZ = 10,
+ MEDIAIP_FR_8P33_HZ = 11,
+ MEDIAIP_FR_9P99_HZ = 12,
+ MEDIAIP_FR_10_HZ = 13,
+ MEDIAIP_FR_11P988_HZ= 14,
+ MEDIAIP_FR_12_HZ = 15,
+ MEDIAIP_FR_12P5_HZ = 16,
+ MEDIAIP_FR_14P985_HZ= 17,
+ MEDIAIP_FR_15_HZ = 18
+
+} MEDIAIP_OUTPUT_FREQ;
+
+//////////////////////////////////////////////////////////////
+// Scan info
+
+typedef enum
+{
+ MEDIAIP_PROGRESSIVE,
+ MEDIAIP_INTERLACE
+
+} MEDIAIP_SCAN_INFO;
+
+//////////////////////////////////////////////////////////////
+// Pipeline type enumeration
+
+typedef enum
+{
+ MEDIAIP_VIDEO_DECODE_PIPELINE = 0x0,
+ MEDIAIP_VIDEO_ENCODE_PIPELINE,
+ MEDIAIP_VIDEO_TRANSCODE_PIPELINE,
+ MEDIAIP_VIDEO_TRANSDISP_PIPELINE,
+ MEDIAIP_VIDEO_NULL_PIPELINE
+
+} MEDIAIP_VIDEO_PIPELINE_TYPE;
+
+//////////////////////////////////////////////////////////////
+// Decode info
+
+/* TODO-KMC */
+/* Why do these structures break the protocol in case used for naming ? */
+
+typedef enum
+{
+ MediaIPFW_DEC_CodingTypeI = 1,
+ MediaIPFW_DEC_CodingTypeP,
+ MediaIPFW_DEC_CodingTypeAny,
+ MediaIPFW_DEC_CodingTypeIP,
+ MediaIPFW_DEC_CodingTypeSkip,
+ MediaIPFW_DEC_CodingTypeLast
+
+} MediaIPFW_DEC_CodingType;
+
+//////////////////////////////////////////////////////////////
+// Decode Command Mode
+
+typedef enum
+{
+ MediaIPFW_DEC_ModeSplit = 0,
+ MediaIPFW_DEC_ModeNoSplit
+
+} MediaIPFW_DEC_Mode;
+
+//////////////////////////////////////////////////////////////
+// Tag structures
+
+typedef enum
+{
+ TAG_FREE = 0,
+ TAG_IN_USE
+
+} TAG_STATUS;
+
+typedef struct
+{
+
+ u_int32 pts; // TSP aspect of the structure
+ u_int32 dts;
+ u_int32 pts_flags;
+#ifdef PES_INPUT_ENABLE
+#else
+ u_int32 maturity_address;
+#endif
+ u_int32 scode_loc; // Possibly this variable could be combined with maturity_address
+ // They are the same thing, but come from very different places
+ BOOL bValid;
+
+} DEMUX_INFO, *pDEMUX_INFO;
+
+// This struct is AVC specific - needs to be generic or at least cast as generic
+typedef struct
+{
+
+ u_int32 sei_flags; // Display aspect
+ u_int32 sei_pic_struct;
+
+} DISP_INFO, *pDISP_INFO;
+
+typedef struct
+{
+ u_int32 fs_idc;
+ u_int32 uUseFrameCRC;
+ u_int32 uBotFirst;
+ u_int32 uTopData[2];
+ u_int32 uBotData[2];
+ u_int32 uReported;
+
+ u_int32 uDpbmcCRC; // Internal MC interface CRC
+ u_int32 uBsCRC; // Byte Stream CRC
+
+ u_int32 uDPBLevel; // DPB Level at frame start
+
+ u_int16 fs_is_used;
+ u_int16 Monochrome;
+
+ u_int32 control;
+
+} CRC_INFO, *pCRC_INFO;
+
+typedef struct
+{
+ u_int32 frame_size_inmbs; // {Size[15:0],Height[7:0],Width[7:0]}
+ u_int32 bs_ib_empty;
+ u_int32 frm_dec_active;
+ u_int32 slc_dec_active;
+ u_int32 stc_at_decode;
+ u_int32 stc_at_display;
+ u_int32 num_slc_overlapped;
+ u_int32 num_mb_overlapped;
+ u_int32 luma_address;
+ u_int32 cpb_min_level;
+ u_int32 rbsp_byte_count;
+ u_int32 dpb_read_count;
+ u_int32 mpr_wait_count;
+ u_int32 slice_count;
+ u_int16 drm_pull_count;
+ u_int16 drm_pap_pts_cnt;
+ u_int16 drm_pap_skip_cnt;
+ u_int16 drm_pap_dang_cnt;
+
+} PERF_INFO, *pPERF_INFO;
+
+typedef struct
+{
+ u_int32 uNumSlices;
+ u_int32 uSumQP;
+
+}QMETER_INFO, *pQMETER_INFO;
+
+typedef struct
+{
+
+ DEMUX_INFO TspInfo;
+ DISP_INFO DispInfo;
+ CRC_INFO CRCInfo;
+ TAG_STATUS Status; // General info on the structure - free or taken...
+ QMETER_INFO QMeterInfo;
+ u_int32 uPercentMBInErr;
+#ifdef PERF_DEBUG
+ PERF_INFO PerfInfo;
+#endif
+
+} TAG, *pTAG;
+
+typedef struct
+{
+
+ u_int32 uLastTSP;
+ u_int32 uLastNonTSP;
+ u_int32 uInUse;
+
+} TAG_CTRL, *pTAG_CTRL;
+
+
+// Film Grain technology support
+typedef struct
+{
+ BOOL bFGS_Flag;
+ u_int32 log2_scale_factor;
+ u_int32 pic_order_count;
+ u_int32 pic_order_offset;
+ u_int16 fgs_lut[3][256];
+
+}USERDATA_FILMGRAIN_CONTROL;
+
+#define DIAG_ARRAY_SIZE 26
+
+typedef struct
+{
+
+ int32 nAvcDiagState;
+ int32 nTSPDiagState;
+ u_int32 uFailurePt;
+ u_int32 uFailData[4];
+ int32 nLastCall;
+ int32 nDecodeBegan;
+ int32 nEngStart;
+ u_int32 uLastStart;
+ int32 DPBCount;
+ int32 DPBAnomaly;
+ int32 DPBAnomalyCnt;
+ int32 nEntryIndex;
+ int32 nEntryArray[DIAG_ARRAY_SIZE];
+ int32 nExitIndex;
+ int32 nExitArray[DIAG_ARRAY_SIZE];
+
+} DiagInfo, *pDiagInfo;
+
+
+////////////////////////////////////////////////////////
+// Frame store structure -
+// Common to multiple modules will hold all information
+// which needs to be transferred between any two modules
+// in relation to a picture buffer
+
+typedef struct mediaip_fw_frame_store
+{
+ struct mediaip_fw_frame_store * pNext; // Not entirely sure I need this - we will see as the architecture evolves...
+
+ /* Frame store description */
+ u_int32 uBaseAddr; // Base Address - Luma base for a image store, address for MBI or BLI
+ u_int32 uChromaOffset;
+ u_int32 uPitch;
+ u_int32 uDimsMBs;
+
+ // Module usage
+ u_int32 uModUsage; // 1 bit set for each module that considers this frame store to be in use by it
+ // For a real time display / transcode situation this could be more than 2
+
+ // Last Frame flag
+ BOOL bLastFrame; // Flag to indicate whether this is the last frame store decoded by the decoder.
+ // Important when stopping a transcode pipeline or reaching the last frame of a bitstream
+ // so that we can tell the encoder not to expect any more frames and hence empty it's
+ // pipeline.
+
+ // Display params
+ u_int32 uDispData; // Bottom field first etc - normally to be filled in by decode module
+
+ // Frame store
+ u_int32 uFSID; // An ID used to cross reference with a local structure - filled in by the capture unit, decoder or
+ // image capture unit, etc
+
+ pTAG pFSTag; // A pointer to a tag for the frame store - normally allocated by the decoder so that unit should
+ // set the pointer
+
+ USERDATA_FILMGRAIN_CONTROL ud_filmgrain; // Filmgrain support structure
+
+ // Want to give anything that may be managed by the resource layer a generic resource tag!
+ // Until I can be bothered working out how to do this I will go with the 3 below...
+
+ u_int8 uDynBuffType; // What is the buffer type of the currently allocayted frame store
+ // Could be worked out from uFSInternBufNum - Remember if we have to
+ // hold a frames over a channel change not all uDynBuffType members
+ // will be the same in each stream's group of frame stores
+
+ u_int8 uFSInternBufStart;
+ u_int8 uFSInternBufNum;
+
+} MEDIAIP_FW_FRAME_STORE;
+
+typedef MEDIAIP_FW_FRAME_STORE MEDIAIP_FW_ENCODER_REF_FRAME_STORE;
+typedef MEDIAIP_FW_FRAME_STORE MEDIAIP_FW_ENCODER_FRAME_ACT_STORE;
+
+
+////////////////////////////////////////////////////////
+// MetaData store structure -
+// Defines an area which may be passed to a base module for its own internal use
+
+typedef struct
+{
+ u_int32 uMetadataBase;
+ u_int32 uMetadataSize;
+
+} MEDIAIP_FW_METADATA_STORE, *pMEDIAIP_FW_METADATA_STORE;
+
+////////////////////////////////////////////////////////
+// Stream Frequency enumeration -
+
+
+typedef enum {
+
+ STREAM_FR_UNKNOWN = 0,
+ STREAM_FR_23_97_HZ = 1,
+ STREAM_FR_24_HZ = 2,
+ STREAM_FR_25_HZ = 3,
+ STREAM_FR_29_97_HZ = 4,
+ STREAM_FR_30_HZ = 5,
+ STREAM_FR_50_HZ = 6,
+ STREAM_FR_59_94_HZ = 7,
+ STREAM_FR_60_HZ = 8
+
+ } STREAM_SCAN_FREQ;
+
+////////////////////////////////////////////////////////
+// Digital Encode Mode ( at the tv encoder)
+
+typedef enum {
+ MODE_240p = 0x0,
+ MODE_240i = 0x1,
+ MODE_480p = 0x2,
+ MODE_NTSC = 0x3,
+ MODE_PALp = 0x4,
+ MODE_PAL = 0x5,
+ MODE_720p = 0x6,
+ MODE_720p_50Hz = 0x7,
+ MODE_720i = 0x8,
+ MODE_720i_25Hz = 0x9,
+ MODE_720i_50Hz = 0xa,
+ MODE_720i_60Hz = 0xb,
+ MODE_1080p = 0xc,
+ MODE_1080p_25Hz = 0xd,
+ MODE_1080i = 0xe,
+ MODE_1080i_25Hz = 0xf,
+ MODE_2Kp = 0x10,
+ MODE_1080p_24Hz = 0x11,
+ MODE_UNKNOWN = 0xff
+
+ } TV_ENC_MODE;
+
+////////////////////////////////////////////////////////
+// Stream Display parameters
+
+typedef struct
+{
+ u_int32 uTargetLevel;
+ u_int32 uHorDecodeRes;
+ u_int32 uVerDecodeRes;
+ u_int32 uHorDispRes;
+ u_int32 uVerDispRes;
+ u_int32 uDispWidthMBs;
+ u_int32 uDispHeightMBs;
+ u_int32 uBufWidthMBs;
+ u_int32 uBufHeightMBs;
+ u_int32 uAspectRatio;
+ u_int32 uSizeMBs;
+ u_int32 uYUVFmt;
+ u_int32 uScanFormat;
+ STREAM_SCAN_FREQ sFreq;
+ u_int32 uNumRefFrms;
+ u_int32 uNumDPBFrms;
+ u_int32 uNumDFEAreas;
+ u_int32 uProfLevelIDC;
+ MEDIAIP_OUTPUT_FREQ eOutputFreq;
+ MEDIAIP_SCAN_INFO eScanInfo;
+ u_int32 uAR;
+ u_int32 uColorDesc;
+ u_int32 uBitDepthLuma;
+ u_int32 uBitDepthChroma;
+ u_int32 uNumViews;
+ u_int32 uViewList;
+
+} MEDIAIP_FW_STREAM_DISPLAY_PARAMS;
+
+
+////////////////////////////////////////////////////////
+// Frame decoded parameters
+
+typedef struct
+{
+ BOOL bTopFieldFirst;
+ BOOL bRepeatFirstField;
+ MEDIAIP_PIC_TYPE ePicType;
+ MEDIAIP_PIC_STRUCT ePicStruct;
+
+ u_int32 uFSHandle;
+
+ u_int32 uPicStartAddr;
+ u_int32 uPercentMBsInErr;
+
+ u_int32 uPTSLo;
+ u_int32 uPTSHi;
+ BOOL bPTSValid;
+
+ BOOL bQMeterValid;
+ u_int32 uQMeter;
+ BOOL bGopBitRateAvail;
+ u_int32 uGopBitRate;
+
+ u_int32 bTemporalRef;
+
+ u_int32 uBbdHorActive;
+ u_int32 uBbdVerActive;
+ u_int32 uBbdLogoActive;
+ u_int32 uBbdBotPrev;
+ u_int32 uBbdMinColPrj;
+ u_int32 uBbdMinRowPrj;
+
+ u_int32 uFSBaseAddr;
+ BOOL bDangling;
+ BOOL bTopFieldPresent;
+
+ /* Only for RealVideo RPR */
+ u_int32 uRprPicWidth;
+ u_int32 uRprPicHeight;
+
+ /* Only for DivX3 */
+ u_int32 uFrameRate;
+
+ /* For decode time yuv gathering */
+ u_int32 ulTopLumBaseAddr;
+ u_int32 ulTopChrBaseAddr;
+ u_int32 ulBotLumBaseAddr;
+ u_int32 ulBotChrBaseAddr;
+
+ u_int32 ulStride;
+
+ void * pAltView;
+ u_int32 uMVCTargetViewIdx;
+} MEDIAIP_FW_FRAME_DEC_PARAMS , *pMEDIAIP_FW_FRAME_DEC_PARAMS;
+
+////////////////////////////////////////////////////////
+// SVC Seq parameters
+
+typedef struct
+{
+ u_int32 uNumValidLayers;
+ MEDIAIP_FW_STREAM_DISPLAY_PARAMS tLayerParams[MEDIAIP_MAX_SVC_DID];
+
+} MEDIAIP_FW_SVC_STREAM_PARAMS;
+
+//////////////////////////////////////////////////////////////
+// IRQ Event data
+
+typedef struct
+{
+ void * pMVDHw;
+ u_int32 uIrqStatus[0x3];
+
+} MEDIAIP_FW_IRQ_DATA, *pMEDIAIP_FW_IRQ_DATA;
+
+
+//////////////////////////////////////////////////////////////
+// CMD Event data
+
+typedef struct
+{
+ u_int32 uCmdData;
+
+}MEDIAIP_FW_CMD_DATA, *pMEDIAIP_FW_CMD_DATA;
+
+//////////////////////////////////////////////////////////////
+// Callback Request Data
+
+typedef struct
+{
+ u_int32 uReason;
+
+}MEDIAIP_FW_CBACK_DATA, *pMEDIAIP_FW_CBACK_DATA;
+
+////////////////////////////////////////////////////////
+// Interface descriptor
+// Generic descriptor type as initially defined by Tempest
+// module
+
+typedef struct
+{
+
+ volatile u_int32 address;
+ volatile u_int32 parameters;
+
+} INTERFACE_DESCRIPTOR_TYPE, *pINTERFACE_DESCRIPTOR_TYPE;
+
+////////////////////////////////////////////////////////
+// Buffer descriptor
+// Generic buffer descriptor as initially defined by Tempest
+// module
+
+typedef struct
+{
+ u_int32 descriptor_number;
+ u_int32 descriptor_size;
+ u_int32 descriptor_ptr;
+
+} BUFFER_TBL_DESCRIPTOR, *BUFFER_TBL_DESCRIPTOR_PTR;
+
+////////////////////////////////////////////////////////
+// Buffer descriptor
+// Generic buffer descriptor as initially defined by Tempest
+// module
+
+typedef struct
+{
+ u_int32 wptr;
+ u_int32 rptr;
+ u_int32 start;
+ u_int32 end;
+
+} BUFFER_DESCRIPTOR_TYPE, *pBUFFER_DESCRIPTOR_TYPE;
+
+////////////////////////////////////////////////////////
+// Stream Buffer descriptor
+// Specific buffer descriptor for stream data
+
+typedef struct
+{
+ volatile u_int32 wptr;
+ volatile u_int32 rptr;
+ volatile u_int32 start;
+ volatile u_int32 end;
+ volatile u_int32 LWM;
+
+} STREAM_BUFFER_DESCRIPTOR_TYPE, *pSTREAM_BUFFER_DESCRIPTOR_TYPE;
+
+#ifdef TCODE_API_TEST
+// Defined specific for PCI ,for its access unit is 64 bits
+typedef struct
+{
+ volatile u_int32 wptr;
+ volatile u_int32 wptr_res;
+ volatile u_int32 rptr;
+ volatile u_int32 rptr_res;
+ volatile u_int32 start;
+ volatile u_int32 end;
+
+} BUF_DES_PCI_SHARE_TYPE, BUF_DES_PCI_SHARE_TYPE_PTR;
+
+#endif
+////////////////////////////////////////////////////////
+// Stream Buffer descriptor
+// Buffer descriptor as used by the encoder
+// module
+
+typedef struct
+{
+
+ u_int32 stream_index;
+ u_int32 stream_buffer_size;
+ u_int32 stream_buffer_base;
+
+} STREAM_BUFFER_DESCRIPTOR, *STREAM_BUFFER_DESCRIPTOR_PTR;
+
+typedef STREAM_BUFFER_DESCRIPTOR MEDIAIP_FW_ENCODER_STREAM_BUFFER_DESC;
+
+////////////////////////////////////////////////////////
+// PTS debug descriptor
+// This descriptor is as initially defined by Tempest
+// module
+
+typedef struct
+{
+ volatile u_int32 pts_lo;
+ volatile u_int32 stc_lo;
+ volatile int32 error;
+ volatile u_int32 flags;
+
+} PTS_DEBUG_DESCRIPTOR_TYPE, *pPTS_DEBUG_DESCRIPTOR_TYPE;
+
+////////////////////////////////////////////////////////
+// PTS descriptor
+// This descriptor is as initially defined by Tempest
+// module
+
+typedef struct
+{
+ volatile u_int32 pts_lo;
+ volatile u_int32 dts_lo;
+ volatile int32 flags;
+ volatile u_int32 maturity_addr;
+
+} PTS_DESCRIPTOR_TYPE, *pPTS_DESCRIPTOR_TYPE;
+
+//////////////////////////////////////////////////////////////
+// Video Stream Status structure
+//
+// Note : I am putting this in the communal include file because we may wish to let
+// module base FW update such a structure directly as opposed to sending messages
+// back to the public FW level...
+// We may also wish to lump all module's status into this one structure
+
+// Why are these volatiles? Should consider removing their volatility!!...
+typedef struct
+{
+ //////////////////////
+ // Pipeline variables
+ volatile u_int32 run;
+ volatile u_int32 pause;
+
+ //////////////////////
+ // Decoder variables
+ volatile u_int32 mpeg_format;
+ volatile u_int32 DSS;
+ volatile u_int32 native_sd;
+ volatile u_int32 stop;
+ volatile u_int32 stop_pending;
+ volatile u_int32 stream_terminate_type;
+ volatile u_int32 ES;
+ volatile u_int32 PAL;
+ volatile u_int32 CRC;
+ volatile u_int32 update_offset;
+ volatile u_int32 pcr_sent;
+ volatile u_int32 PVRMode;
+ volatile u_int32 malone_mp2_dbdrng_en;
+ volatile u_int32 uWaitFlush;
+
+ volatile u_int32 pvr_type; /* These are new - need to be fixed */
+ volatile u_int32 valid_frame_mask;
+
+ //////////////////////
+ // Display variables
+ volatile u_int32 force_interlace;
+ volatile u_int32 sync_stc;
+ volatile int32 nTrinityDisc;
+ volatile u_int32 uTrinityDiscPCRLo;
+ volatile u_int32 display_mode_status;
+ volatile u_int32 sync;
+
+} MEDIAIP_FW_STREAM_STATUS, *MEDIAIP_FW_STREAM_STATUS_PTR;
+
+//////////////////////////////////////////////////////////////
+// Stream Descriptor Structure
+//
+// Currently this is basically the stream descriptor structure
+// from the decoder FW interface with the host SW
+// This needs to evolve to suit our needs better
+#if ( TARGET_PLATFORM == GENTB_PLATFORM )
+
+typedef struct
+{
+ volatile u_int32 Control;
+ volatile u_int32 Buffer_Indices;
+ volatile u_int32 Message_Filter;
+ volatile u_int32 Extended_Message_Filter;
+ volatile u_int32 Tempest_Command_Filter;
+ volatile u_int32 Status;
+ volatile u_int32 Bitstream_Error;
+ volatile u_int32 Skip_Count;
+ volatile u_int32 Repeat_Count;
+ volatile u_int32 Frame_Count;
+ volatile u_int32 Bitstream_Timeout;
+ volatile u_int32 Max_Frame_Dpb_Size; // For dynamic frame allocation this actually means the start of the allocated memory
+ volatile u_int32 Decode_Buffer_Count; // For dynamic frame allocation this actually means the size of allocated memory
+ volatile u_int32 Buffer_Pitch; // For dynamic frame allocation this actually means the memory controller tile width
+ volatile INTERFACE_DESCRIPTOR_TYPE DPB_Base_Address_dec; // For dynamic frame allocation this actually means the MB info address
+ volatile u_int32 PTS_DTS_Offset;
+ volatile u_int32 Internal_PTS_Delay;
+ volatile u_int32 Sync_Window_Start;
+ volatile u_int32 Sync_Window_End;
+ volatile u_int32 Sync_Sanity_Limit;
+ volatile u_int32 trick_speed;
+ INTERFACE_DESCRIPTOR_TYPE user_data_desc;
+
+ INTERFACE_DESCRIPTOR_TYPE FrameStoreDesc;
+ INTERFACE_DESCRIPTOR_TYPE frame_buffer_control_desc;
+
+ INTERFACE_DESCRIPTOR_TYPE pvr_command_list_desc;
+ volatile u_int32 Pad[2];
+
+ pPTS_DESCRIPTOR_TYPE pts_table_desc;
+ pPTS_DEBUG_DESCRIPTOR_TYPE pts_debug_table_desc;
+
+ volatile u_int32 PVR_Control;
+ volatile u_int32 RAI;
+
+ // For PecosB onwards this is the security control word
+ volatile u_int32 security_control;
+ // Status variables for a stream
+ volatile u_int32 sd_changed_control;
+ volatile u_int32 ud_type_mask;
+ MEDIAIP_FW_STREAM_STATUS stream_status;
+
+#if TARGET_APP == VIDEO_TRANS
+ volatile u_int32 FrameStoreCount;
+ // Second set of image buffers ( only required in a dual MC situation )
+ volatile u_int32 FrameStoreCount2;
+ volatile INTERFACE_DESCRIPTOR_TYPE FrameStoreDesc2;
+
+ // Encoder Reference buffers
+ volatile u_int32 EncRefCount;
+ volatile INTERFACE_DESCRIPTOR_TYPE EncRefDesc;
+
+ // Encoder Image Activity buffers
+ volatile u_int32 EncActCount;
+ volatile INTERFACE_DESCRIPTOR_TYPE EncActDesc;
+
+ // Stream buffer descriptor index - for encoder and decoder
+ volatile u_int32 uDecStrmBufIdx; // Current decode FW expects that the buffer used will match the SDIndex
+ volatile u_int32 uEncOutBufIdx;
+
+ // Only enc, vamux interDesc used at present to pass params
+ volatile INTERFACE_DESCRIPTOR_TYPE uDecParamSet;
+ volatile INTERFACE_DESCRIPTOR_TYPE uEncParamSet;
+ volatile INTERFACE_DESCRIPTOR_TYPE uVamuxParamSet;
+
+ // Hardware Interface to system layer
+ INTERFACE_DESCRIPTOR_TYPE system_config_desc;
+
+#ifdef TCODE_API_TEST
+ volatile INTERFACE_DESCRIPTOR_TYPE uBitRateDispSet;
+#endif
+
+ volatile u_int32 streamdes_id;
+
+#else
+
+#if PLAYMODE == STB
+ volatile u_int32 streamdes_id;
+#endif
+#endif
+
+} STREAM_DESCRIPTOR, *STREAM_DESCRIPTOR_PTR;
+
+#else
+
+typedef struct
+{
+ volatile u_int32 Control; // 0
+ volatile u_int32 Buffer_Indices;
+ volatile u_int32 Message_Filter;
+ volatile u_int32 Extended_Message_Filter;
+ volatile u_int32 Tempest_Command_Filter;
+ volatile u_int32 Status;
+ volatile u_int32 Bitstream_Error;
+ volatile u_int32 Skip_Count;
+ volatile u_int32 Repeat_Count;
+ volatile u_int32 Frame_Count;
+ volatile u_int32 Bitstream_Timeout;
+ volatile u_int32 Max_Frame_Dpb_Size;
+ volatile u_int32 Buffer_Pitch;
+ volatile u_int32 Decode_Buffer_Count;
+ volatile u_int32 PTS_DTS_Offset;
+ volatile u_int32 Internal_PTS_Delay;
+ volatile u_int32 Sync_Window_Start;
+ volatile u_int32 Sync_Window_End;
+ volatile u_int32 Sync_Sanity_Limit;
+ volatile u_int32 trick_speed; // 20
+
+ // Image buffers
+ volatile u_int32 FrameStoreCount;
+ volatile INTERFACE_DESCRIPTOR_TYPE FrameStoreDesc;
+
+ // Second set of image buffers ( only required in a dual MC situation )
+ volatile u_int32 FrameStoreCount2;
+ volatile INTERFACE_DESCRIPTOR_TYPE FrameStoreDesc2;
+
+ // Encoder Reference buffers
+ volatile u_int32 EncRefCount;
+ volatile INTERFACE_DESCRIPTOR_TYPE EncRefDesc;
+
+ // Encoder Image Activity buffers
+ volatile u_int32 EncActCount; // 30
+ volatile INTERFACE_DESCRIPTOR_TYPE EncActDesc;
+
+ // Stream buffer descriptor index - for encoder and decoder
+ volatile u_int32 uDecStrmBufIdx; // Current decode FW expects that the buffer used will match the SDIndex
+ volatile u_int32 uEncOutBufIdx;
+
+ // Only enc, vamux interDesc used at present to pass params
+ volatile INTERFACE_DESCRIPTOR_TYPE uDecParamSet;
+ volatile INTERFACE_DESCRIPTOR_TYPE uEncParamSet;
+ volatile INTERFACE_DESCRIPTOR_TYPE uVamuxParamSet;
+
+ INTERFACE_DESCRIPTOR_TYPE user_data_desc;
+ INTERFACE_DESCRIPTOR_TYPE frame_buffer_attribute_desc; // Address of the attribute table used by the display process
+ // Who fills this in?? Do I give a shite in module architecture?
+ INTERFACE_DESCRIPTOR_TYPE frame_buffer_control_desc;
+ BUFFER_DESCRIPTOR_TYPE pvr_command_list_desc;
+ pPTS_DESCRIPTOR_TYPE pts_table_desc;
+ pPTS_DEBUG_DESCRIPTOR_TYPE pts_debug_table_desc;
+
+ // Hardware Interface to system layer
+ INTERFACE_DESCRIPTOR_TYPE system_config_desc;
+
+ // Status variables for a stream
+ volatile u_int32 sd_changed_control;
+ MEDIAIP_FW_STREAM_STATUS stream_status;
+
+ volatile u_int32 RAI;
+
+
+#ifdef DRM_AV_SYNC_DEBUG
+ volatile u_int32 DRMPath_Take_Snapshot; // Only used when DRM_AV_SYNC_DEBUG defined but included
+ volatile u_int32 DRMPath_Snapshot_Addr; // in all builds to enable more transparent api
+ volatile u_int32 DRMPath_Snapshot_Index; // operations
+#endif
+
+#ifdef TCODE_API_TEST
+ volatile INTERFACE_DESCRIPTOR_TYPE uBitRateDispSet;
+#endif
+
+ volatile u_int32 streamdes_id;
+
+ /* Following have been removed from official descriptor area
+ INTERFACE_DESCRIPTOR_TYPE sps_td;
+ INTERFACE_DESCRIPTOR_TYPE pps_td;
+ INTERFACE_DESCRIPTOR_TYPE spds_td;
+ */
+
+} STREAM_DESCRIPTOR, *STREAM_DESCRIPTOR_PTR;
+
+#endif
+
+#define CRC_DEBUG_NUM 1024
+#define PERF_DEBUG_NUM 2048 // 68secs
+#define CRC_FRAME 0
+#define CRC_FIELD_TOP 1
+#define CRC_FIELD_BOT 3
+
+typedef struct
+{
+
+ u_int32 abort_type;
+ u_int32 mode;
+ u_int32 link_reg;
+ u_int32 stack_pointer;
+
+}ExceptionDesc, pExceptionDesc;
+
+#ifndef VIDEO_SOFTWARE
+/* Structure below needs to be in shared memory header file for SW apps */
+typedef enum
+{
+ MVDDecoderOK = 0x0,
+ MVDDecoderServiceIrq,
+ MVDDecoderCmdPending,
+ MVDDecoderFWLoop,
+ MVDDecoderHWActive,
+ MVDDecoderHWActiveStreamStall,
+ MVDDecoderHWActiveMemStall,
+ MVDDecoderFWHWDeadlock,
+ MVDDecoderFWHWAutoRec,
+ MVDDecoderHWBSDMAIssue,
+ MVDDecoderUnknown,
+ MVDDecoderLast = MVDDecoderUnknown
+
+} MEDIAIP_FW_DECODER_STATUS;
+
+#endif
+
+typedef struct
+
+{
+
+ u_int32 size; // Size of this structure
+ u_int32 index; // Current index into array
+ u_int32 loops; // Number of times we looped
+ u_int32 num_frames; // Number of frames in a loop
+ u_int32 frame_size_inmbs; // {Size[15:0],Height[7:0],Width[7:0]}
+
+ u_int32 not_first_time;
+ u_int32 prev_vsync_count;
+ u_int32 worst_frame;
+ u_int32 loop_key; // Value used to decide when stream has looped
+ u_int32 skip_start;
+
+
+ u_int32 luma_mismatches; //
+ u_int32 chroma_mismatches; //
+ u_int32 dpbmc_mismatches; //
+ u_int32 bs_mismatches; //
+ u_int32 skip_count; //
+ u_int32 repeat_count; //
+ u_int32 loop_lu_crc; // Merge of CRCs
+ u_int32 loop_ch_crc; // Merge of CRCs
+
+ // Most recent captured Info
+ u_int32 crc_type[PERF_DEBUG_NUM];
+ u_int32 idr_pic[PERF_DEBUG_NUM];
+ u_int32 poc[PERF_DEBUG_NUM];
+ u_int32 luma_crc[PERF_DEBUG_NUM];
+ u_int32 chroma_crc[PERF_DEBUG_NUM];
+ u_int32 dpbmc_crc[PERF_DEBUG_NUM]; // Only valid for BBV & above
+ u_int32 bs_crc[PERF_DEBUG_NUM]; // Only valid for BBV & above
+
+ // Mismatches & skips
+ u_int32 luma_mismatch[PERF_DEBUG_NUM];
+ u_int32 chroma_mismatch[PERF_DEBUG_NUM];
+ u_int32 dpbmc_mismatch[PERF_DEBUG_NUM]; // Only valid for BBV & above
+ u_int32 bs_mismatch[PERF_DEBUG_NUM]; // Only valid for BBV & above
+
+ u_int32 mismatch_fs_idc[32];
+ u_int32 skip[PERF_DEBUG_NUM];
+ u_int32 repeat[PERF_DEBUG_NUM];
+
+
+ // Performance metrics & the associated CRCs for first loop
+ u_int32 crc_type_l0[PERF_DEBUG_NUM];
+ u_int32 idr_pic_l0[PERF_DEBUG_NUM];
+ u_int32 poc_l0[PERF_DEBUG_NUM];
+ u_int32 luma_crc_l0[PERF_DEBUG_NUM];
+ u_int32 chroma_crc_l0[PERF_DEBUG_NUM];
+ u_int32 dpbmc_crc_l0[PERF_DEBUG_NUM]; // Only valid for BBV & above
+ u_int32 bs_crc_l0[PERF_DEBUG_NUM]; // Only valid for BBV & above
+
+ // Max of metrics
+ u_int32 max_slc_dec_active;
+ u_int32 max_dpb_read_count;
+ u_int32 max_mpr_wait_count;
+ u_int32 max_rbsp_byte_count;
+ u_int32 max_bs_ib_empty;
+ u_int32 max_slice_count;
+ u_int32 max_mb_overlapped;
+ u_int32 min_stc_diff;
+ u_int32 max_frm_dec_active;
+ u_int32 max_frm_dec_active_2;
+ u_int32 max_frm_dec_active_4;
+ u_int32 max_frm_dec_active_8;
+
+ // Max of metrics assiciated with worst frame
+ u_int32 mfda_bs_ib_empty;
+ u_int32 mfda_mpr_wait_count;
+ u_int32 mfda_dpb_read_count;
+ u_int32 mfda_rbsp_byte_count;
+ u_int32 mfda_slice_count;
+ u_int32 mfda_slc_dec_active;
+ u_int32 mfda_mb_overlapped;
+
+ // Will effectively be averages
+ u_int32 Av_frm_dec_active;
+ u_int32 Av_slc_dec_active;
+ u_int32 Av_mpr_wait_count;
+ u_int32 Av_dpb_read_count;
+ u_int32 Av_rbsp_byte_count;
+ u_int32 Av_bs_ib_empty;
+ u_int32 Av_slice_count;
+ u_int32 Av_mb_overlapped;
+
+ u_int32 stc_diff[PERF_DEBUG_NUM];
+ u_int32 frm_dec_active[PERF_DEBUG_NUM];
+ u_int32 bs_ib_empty[PERF_DEBUG_NUM];
+ u_int32 slc_dec_active[PERF_DEBUG_NUM];
+ u_int32 num_slc_overlapped[PERF_DEBUG_NUM]; // Only valid for BBV & above
+ u_int32 num_mb_overlapped[PERF_DEBUG_NUM]; // Only valid for BBV & above
+ u_int32 cpb_min_level[PERF_DEBUG_NUM];
+ u_int32 rbsp_byte_count[PERF_DEBUG_NUM];
+ u_int32 dpb_read_count[PERF_DEBUG_NUM];
+ u_int32 mpr_wait_count[PERF_DEBUG_NUM];
+ u_int16 drm_pull_count[PERF_DEBUG_NUM];
+ u_int16 drm_pap_pts_cnt[PERF_DEBUG_NUM];
+ u_int16 drm_pap_skip_cnt[PERF_DEBUG_NUM];
+ u_int16 drm_pap_dang_cnt[PERF_DEBUG_NUM];
+
+ u_int32 initial_dpb_level[PERF_DEBUG_NUM]; // DPB level at frame start
+
+} PerfDebug;
+
+typedef struct
+
+{
+
+ u_int32 loops; // Number of times we looped
+ u_int32 loop_frames; // Number of frames in a loop
+ u_int32 num_frames; // Position in current loop
+ u_int32 loop_dpbmc_crc; // Merge of CRCs
+ u_int32 loop_stream_crc; // Merge of CRCs
+ u_int32 LoopCyCntD1024; // Sum of frm_dec_active/1024
+ u_int32 MaxDecActive; // Max frm_dec_active
+ u_int32 not_first_time;
+ u_int32 first_crc;
+ u_int32 WorstFrame;
+
+} DecDebug;
+
+
+///////////////////////////////////////////
+// System Configuration structure
+
+typedef struct
+{
+ u_int32 uCfgCookie;
+
+ u_int32 uNumMalones;
+ u_int32 uMaloneBaseAddress[MEDIAIP_MAX_NUM_MALONES];
+ u_int32 uHifOffset[MEDIAIP_MAX_NUM_MALONES];
+ u_int32 uMaloneIrqPin[MEDIAIP_MAX_NUM_MALONES][MEDIAIP_MAX_NUM_MALONE_IRQ_PINS];
+ u_int32 uMaloneIrqTarget[MEDIAIP_MAX_NUM_MALONES][MEDIAIP_MAX_NUM_MALONE_IRQ_PINS];
+
+ u_int32 uNumWindsors;
+ u_int32 uWindsorBaseAddress[MEDIAIP_MAX_NUM_WINDSORS];
+ u_int32 uWindsorIrqPin[MEDIAIP_MAX_NUM_WINDSORS][MEDIAIP_MAX_NUM_WINDSOR_IRQ_PINS];
+ u_int32 uWindsorIrqTarget[MEDIAIP_MAX_NUM_WINDSORS][MEDIAIP_MAX_NUM_WINDSOR_IRQ_PINS];
+
+ u_int32 uCmdIrqPin[MEDIAIP_MAX_NUM_CMD_IRQ_PINS];
+ u_int32 uCmdIrqTarget[MEDIAIP_MAX_NUM_CMD_IRQ_PINS];
+
+ u_int32 uMsgIrqPin[MEDIAIP_MAX_NUM_MSG_IRQ_PINS];
+ u_int32 uMsgIrqTarget[MEDIAIP_MAX_NUM_MSG_IRQ_PINS];
+
+ u_int32 uSysClkFreq;
+ u_int32 uNumTimers;
+ u_int32 uTimerBaseAddr;
+ u_int32 uTimerIrqPin[MEDIAIP_MAX_NUM_TIMER_IRQ_PINS];
+ u_int32 uTimerIrqTarget[MEDIAIP_MAX_NUM_TIMER_IRQ_PINS];
+ u_int32 uTimerSlots[MEDIAIP_MAX_NUM_TIMER_IRQ_SLOTS];
+
+ u_int32 uGICBaseAddr;
+ u_int32 uUartBaseAddr;
+
+ u_int32 uDPVBaseAddr;
+ u_int32 uDPVIrqPin;
+ u_int32 uDPVIrqTarget;
+
+ u_int32 uPixIfBaseAddr;
+
+ u_int32 pal_trace_level;
+ u_int32 pal_trace_destination;
+
+ u_int32 pal_trace_level1;
+ u_int32 pal_trace_destination1;
+
+ u_int32 uHeapBase;
+ u_int32 uHeapSize;
+
+ u_int32 uFSLCacheBaseAddr;
+
+} MEDIAIP_FW_SYSTEM_CONFIG, *pMEDIAIP_FW_SYSTEM_CONFIG;
+
+
+///////////////////////////////////////////
+// Encoder types to be globally used across
+// all encode / transcode apps and components
+
+///////////////////////////////////////////
+// MEDIAIP_ENC_FMT
+
+typedef enum
+{
+ MEDIAIP_ENC_FMT_H264 = 0,
+ MEDIAIP_ENC_FMT_VC1,
+ MEDIAIP_ENC_FMT_MPEG2,
+ MEDIAIP_ENC_FMT_MPEG4SP,
+ MEDIAIP_ENC_FMT_H263,
+ MEDIAIP_ENC_FMT_MPEG1,
+ MEDIAIP_ENC_FMT_SHORT_HEADER,
+ MEDIAIP_ENC_FMT_NULL
+
+} MEDIAIP_ENC_FMT;
+
+///////////////////////////////////////////
+// MEDIAIP_ENC_PROFILE
+
+typedef enum
+{
+ MEDIAIP_ENC_PROF_MPEG2_SP = 0,
+ MEDIAIP_ENC_PROF_MPEG2_MP,
+ MEDIAIP_ENC_PROF_MPEG2_HP,
+ MEDIAIP_ENC_PROF_H264_BP,
+ MEDIAIP_ENC_PROF_H264_MP,
+ MEDIAIP_ENC_PROF_H264_HP,
+ MEDIAIP_ENC_PROF_MPEG4_SP,
+ MEDIAIP_ENC_PROF_MPEG4_ASP,
+ MEDIAIP_ENC_PROF_VC1_SP,
+ MEDIAIP_ENC_PROF_VC1_MP,
+ MEDIAIP_ENC_PROF_VC1_AP
+
+} MEDIAIP_ENC_PROFILE;
+
+///////////////////////////////////////////
+// MEDIAIP_ENC_CONFIG_CODEC_PARAMETER
+
+typedef struct
+{
+ MEDIAIP_ENC_FMT eCodecMode;
+ MEDIAIP_ENC_PROFILE eProfile;
+ u_int32 uReserved[2];
+
+} MEDIAIP_ENC_CONFIG_CODEC_PARAMETER, *pMEDIAIP_ENC_CONFIG_CODEC_PARAMETER; //8 words
+
+///////////////////////////////////////////
+// MEDIAIP_ENC_PIXEL_FORMAT
+
+typedef enum
+{
+ MEDIAIP_ENC_PLANAR = 0,
+ MEDIAIP_ENC_SEMIPLANAR
+
+} MEDIAIP_ENC_PIXEL_FORMAT;
+
+///////////////////////////////////////////
+// MEDIAIP_ENC_CHROMA_FMT
+
+typedef enum
+{
+ MODE_420=0,
+ MODE_422,
+ MODE_444
+
+} MEDIAIP_ENC_CHROMA_FMT;
+
+///////////////////////////////////////////
+// MEDIAIP_ENC_FRAME_STRUCT
+
+typedef struct
+{
+ u_int32 uSrcFieldModeForDsa;
+ u_int32 uDstFieldModeForEnc;
+ u_int32 uReserved[2];
+
+} MEDIAIP_ENC_FRAME_STRUCT, *pMEDIAIP_ENC_FRAME_STRUCT;
+
+///////////////////////////////////////////
+// MEDIAIP_ENC_FRAME_DIMENSIONS
+
+typedef struct
+{
+ /* Input picture features */
+ u_int32 uSrcWidth;
+ u_int32 uSrcHeight;
+ u_int32 uYStride;
+ u_int32 uUVStride;
+
+ /* Clipping information */
+ u_int32 uClipFlag; /*Note: 0: don't clip, 1: clip. encode only a part of input frame */
+ u_int32 uOffset_x;
+ u_int32 uOffset_y;
+ u_int32 uClipPicWidth;
+ u_int32 uClipPicHeight;
+
+ /* Output picture features */
+ u_int32 uDstWidth;
+ u_int32 uDstHeight;
+ u_int32 uTileMode; /* 0: scan raster mode 1: tile mode. */
+ u_int32 uTileWidth; /* Note: In tile mode, uYStride should be calculated depend on uTileWidth */
+ u_int32 uTileHeight;
+
+} MEDIAIP_ENC_FRAME_DIMENSIONS, *pMEDIAIP_ENC_FRAME_DIMENSIONS;
+
+///////////////////////////////////////////
+// MEDIAIP_ENC_BITRATE_MODE
+
+typedef enum
+{
+ MEDIAIP_ENC_BITRATECONTROLMODE_VBR = 0x00000001,
+ MEDIAIP_ENC_BITRATECONTROLMODE_CBR = 0x00000002,
+ MEDIAIP_ENC_BITRATECONTROLMODE_CONSTANT_QP = 0x00000004 /* Only in debug mode */
+
+} MEDIAIP_ENC_BITRATE_MODE, *pMEDIAIP_ENC_BITRATE_MODE;
+
+///////////////////////////////////////////
+// MEDIAIP_ENC_BITRATE_CONTROL
+
+typedef struct
+{
+ MEDIAIP_ENC_BITRATE_MODE eBitRateMode;
+ u_int32 uTargetBitrate;
+ u_int32 uMaxBitRate;
+ u_int32 uMinBitRate; /* Requested by Windsor, for soft encoder, it is useless */
+ u_int32 uSliceQP;
+
+} MEDIAIP_ENC_BITRATE_CONTROL, *pMEDIAIP_ENC_BITRATE_CONTROL;
+
+///////////////////////////////////////////
+// MEDIAIP_ENC_GOP_STRUCTURE
+
+typedef struct
+{
+ u_int32 uFrameRateNum;
+ u_int32 uFrameRateDen;
+ u_int32 uIFrameInterval;
+ u_int32 uGopBLength; /* How many B frames between I or P frames, max is 4 for Windsor */
+ u_int32 uLowLatencyMode; /* Switch off scene change mode, no B frame, only in VBR Mode */
+ /* TODO-KMC */
+ /* Remove the crap below */
+ u_int32 reserved[3];
+
+} MEDIAIP_ENC_GOP_STRUCTURE, *pMEDIAIP_ENC_GOP_STRUCTURE;
+
+///////////////////////////////////////////
+// MEDIAIP_ENC_STREAM_PARAMETER
+
+typedef struct
+{
+ MEDIAIP_ENC_CHROMA_FMT eVideoFormat;
+ MEDIAIP_ENC_PIXEL_FORMAT ePixelFormat;
+
+ MEDIAIP_ENC_GOP_STRUCTURE mGOPStructure;
+ MEDIAIP_ENC_FRAME_STRUCT mFrameStructure;
+ MEDIAIP_ENC_FRAME_DIMENSIONS mFrameSize;
+ MEDIAIP_ENC_BITRATE_CONTROL mBitRateControl;
+ u_int32 uExpertModeEnable; /* Enable expert mode */
+ u_int32 uMemChunkAddr; /* Start address of memory chunk */
+ u_int32 uMemChunkSize; /* Size of memory chunk */
+ u_int32 uStreamFinish;
+ /* TODO-KMC */
+ /* Remove the crap below */
+ u_int32 reserved[64 - 40];
+
+} MEDIAIP_ENC_STREAM_PARAMETER, *pMEDIAIP_ENC_STREAM_PARAMETER;
+
+
+///////////////////////////////////////////
+// MEDIAIP_ENC_YUV_BUFFER_DESC
+
+typedef struct
+{
+ u_int32 uFrameID;
+ u_int32 uLumaBase;
+ u_int32 uChromaBase;
+ u_int32 uParamIdx;
+
+} MEDIAIP_ENC_YUV_BUFFER_DESC, *pMEDIAIP_ENC_YUV_BUFFER_DESC;
+
+///////////////////////////////////////////
+// eMEDIAIP_ENC_PIC_TYPE
+
+typedef enum
+{
+ MEDIAIP_ENC_PIC_TYPE_B_FRAME = 0,
+ MEDIAIP_ENC_PIC_TYPE_P_FRAME,
+ MEDIAIP_ENC_PIC_TYPE_I_FRAME,
+ MEDIAIP_ENC_PIC_TYPE_IDR_FRAME,
+ MEDIAIP_ENC_PIC_TYPE_BI_FRAME
+
+} MEDIAIP_ENC_PIC_TYPE, *pMEDIAIP_ENC_PIC_TYPE;
+
+///////////////////////////////////////////
+// MEDIAIP_ENC_PIC_TYPE
+
+typedef struct
+{
+ u_int32 uFrameID;
+ u_int32 uPicEncodDone;
+ MEDIAIP_ENC_PIC_TYPE ePicType;
+ u_int32 uSkippedFrame;
+ u_int32 uErrorFlag;
+ u_int32 uPSNR;
+ u_int32 uFlushDone;
+ u_int32 uMBy;
+ u_int32 uMBx;
+ u_int32 uFrameSize;
+ u_int32 uFrameEncTtlFrmCycles;
+ u_int32 uFrameEncTtlSlcCycles;
+ u_int32 uFrameEncTtlEncCycles;
+ u_int32 uFrameEncTtlHmeCycles;
+ u_int32 uFrameEncTtlDsaCycles;
+ u_int32 uFrameEncFwCycles;
+ u_int32 uFrameCrc;
+ u_int32 uNumInterrupts_1;
+ u_int32 uNumInterrupts_2;
+ u_int32 uH264POC;
+ u_int32 uRefInfo;
+ u_int32 uPicNum;
+ u_int32 uPicActivity;
+ u_int32 uSceneChange;
+ u_int32 uMBStats;
+ u_int32 uEncCacheCount0;
+ u_int32 uEncCacheCount1;
+ u_int32 uMtlWrStrbCnt;
+ u_int32 uMtlRdStrbCnt;
+ u_int32 uStrBuffWrPtr;
+ u_int32 uDiagnosticEvents;
+ u_int32 uProcIaccTotRdCnt;
+ u_int32 uProcDaccTotRdCnt;
+ u_int32 uProcDaccTotWrCnt;
+ u_int32 uProcDaccRegRdCnt;
+ u_int32 uProcDaccRegWrCnt;
+ u_int32 uProcDaccRngRdCnt;
+ u_int32 uProcDaccRngWrCnt;
+
+} MEDIAIP_ENC_PIC_INFO, *pMEDIAIP_ENC_PIC_INFO;
+
+///////////////////////////////////////////
+// MEDIAIP_ENC_DSA_INFO
+
+typedef struct
+{
+ u_int32 uHeight;
+ u_int32 uWidth;
+ u_int32 uCropWidth;
+ u_int32 uCropHeight;
+ u_int32 uCropPixelXOffset;
+ u_int8 * pImgBuffer;
+ u_int32 uStride;
+ u_int32 uOffset2Chroma;
+ u_int32 uOffset2Decimate;
+
+} MEDIAIP_ENC_DSA_INFO, *pMEDIAIP_ENC_DSA_INFO;
+
+///////////////////////////////////////////
+// MEDIAIP_ENC_PIC_PARAM_UPD
+
+typedef struct
+{
+ /* Each bit indicate corresponding parameter should be updated */
+ u_int32 uMaskflag;
+
+ /* ENC_GOP_STRUCTURE variables */
+ u_int32 uFrameRateNum;
+ u_int32 uFrameRateDen;
+
+ /* MEDIAIP_ENC_FRAME_STRUCT variables */
+ u_int32 uSrcFieldModeForDsa;
+ u_int32 uDstFieldModeForEnc;
+
+ /* MEDIAIP_ENC_FRAME_DIMENSIONS variables */
+ u_int32 uSrcWidth;
+ u_int32 uSrcHeight;
+ u_int32 uYStride;
+ u_int32 uUVStride;
+ u_int32 uOffset_x;
+ u_int32 uOffset_y;
+ u_int32 uClipPicWidth;
+ u_int32 uClipPicHeight;
+ u_int32 uDstWidth;
+ u_int32 uDstHeight;
+ u_int32 uIFrameInterval;
+ u_int32 uGopBLength;
+ u_int32 uLowLatencyMode;
+
+ /* MEDIAIP_ENC_BITRATE_CONTROL variables */
+ MEDIAIP_ENC_BITRATE_MODE eBitRateMode;
+ u_int32 uTargetBitrate;
+ u_int32 uMaxBitRate;
+ u_int32 uMinBitRate;
+ u_int32 uSliceQP;
+ u_int32 uReserved[32-23];
+
+} MEDIAIP_ENC_PIC_PARAM_UPD, *pMEDIAIP_ENC_PIC_PARAM_UPD;
+
+
+///////////////////////////////////////////
+// MEDIAIP_ENC_CALIB_PARAMS
+//
+// Encoder Hardware calibration parameters
+
+typedef struct
+{
+ u_int32 use_ame;
+
+ u_int32 cme_mvx_max;
+ u_int32 cme_mvy_max;
+ u_int32 ame_prefresh_y0;
+ u_int32 ame_prefresh_y1;
+ u_int32 fme_min_sad;
+ u_int32 cme_min_sad;
+
+ u_int32 fme_pred_int_weight;
+ u_int32 fme_pred_hp_weight;
+ u_int32 fme_pred_qp_weight;
+ u_int32 fme_cost_weight;
+ u_int32 fme_act_thold;
+ u_int32 fme_sad_thold;
+ u_int32 fme_zero_sad_thold;
+
+ u_int32 fme_lrg_mvx_lmt;
+ u_int32 fme_lrg_mvy_lmt;
+ u_int32 fme_force_mode;
+ u_int32 fme_force4mvcost;
+ u_int32 fme_force2mvcost;
+
+ u_int32 h264_inter_thrd;
+
+ u_int32 i16x16_mode_cost;
+ u_int32 i4x4_mode_lambda;
+ u_int32 i8x8_mode_lambda;
+
+ u_int32 inter_mod_mult;
+ u_int32 inter_sel_mult;
+ u_int32 inter_bid_cost;
+ u_int32 inter_bwd_cost;
+ u_int32 inter_4mv_cost;
+ int32 one_mv_i16_cost;
+ int32 one_mv_i4x4_cost;
+ int32 one_mv_i8x8_cost;
+ int32 two_mv_i16_cost;
+ int32 two_mv_i4x4_cost;
+ int32 two_mv_i8x8_cost;
+ int32 four_mv_i16_cost;
+ int32 four_mv_i4x4_cost;
+ int32 four_mv_i8x8_cost;
+
+ u_int32 intra_pred_enab;
+ u_int32 intra_chr_pred;
+ u_int32 intra16_pred;
+ u_int32 intra4x4_pred;
+ u_int32 intra8x8_pred;
+
+ u_int32 cb_base;
+ u_int32 cb_size;
+ u_int32 cb_head_room;
+
+ u_int32 mem_page_width;
+ u_int32 mem_page_height;
+ u_int32 mem_total_size;
+ u_int32 mem_chunk_addr;
+ u_int32 mem_chunk_size;
+ u_int32 mem_y_stride;
+ u_int32 mem_uv_stride;
+
+ u_int32 split_wr_enab;
+ u_int32 split_wr_req_size;
+ u_int32 split_rd_enab;
+ u_int32 split_rd_req_size;
+
+} MEDIAIP_ENC_CALIB_PARAMS, *pMEDIAIP_ENC_CALIB_PARAMS;
+
+///////////////////////////////////////////
+// MEDIAIP_ENC_CONFIG_PARAMS
+//
+// Stream-specific configuration parameters
+
+typedef struct
+{
+ u_int32 ParamChange;
+
+ u_int32 start_frame; // These variables are for debugging purposes only
+ u_int32 end_frame;
+
+ u_int32 userdata_enable;
+ u_int32 userdata_id[4];
+ u_int32 userdata_message[MEDIAIP_ENC_USER_DATA_WORDS];
+ u_int32 userdata_length;
+
+ u_int32 h264_profile_idc;
+ u_int32 h264_level_idc;
+ u_int32 h264_au_delimiter; // Enable the use of Access Unit Delimiters
+ u_int32 h264_seq_end_code; // Enable the use of Sequence End Codes
+ u_int32 h264_recovery_points; // Enable the use of Recovery Points (must be with a fixed GOP structure)
+ u_int32 h264_vui_parameters; // Enable the use of VUI parameters (for rate control purposes)
+ u_int32 h264_aspect_ratio_present;
+ u_int32 h264_aspect_ratio_sar_width;
+ u_int32 h264_aspect_ratio_sar_height;
+ u_int32 h264_overscan_present;
+ u_int32 h264_video_type_present;
+ u_int32 h264_video_format;
+ u_int32 h264_video_full_range;
+ u_int32 h264_video_colour_descriptor;
+ u_int32 h264_video_colour_primaries;
+ u_int32 h264_video_transfer_char;
+ u_int32 h264_video_matrix_coeff;
+ u_int32 h264_chroma_loc_info_present;
+ u_int32 h264_chroma_loc_type_top;
+ u_int32 h264_chroma_loc_type_bot;
+ u_int32 h264_timing_info_present;
+ u_int32 h264_buffering_period_present;
+ u_int32 h264_low_delay_hrd_flag;
+
+ u_int32 aspect_ratio;
+ u_int32 test_mode; // Automated firmware test mode
+ u_int32 dsa_test_mode; // Automated test mode for the DSA.
+ u_int32 fme_test_mode; // Automated test mode for the fme
+
+ u_int32 cbr_row_mode; //0: FW mode; 1: HW mode
+ u_int32 windsor_mode; //0: normal mode; 1: intra only mode; 2: intra+0MV mode
+ u_int32 encode_mode; // H264, VC1, MPEG2, DIVX
+ u_int32 frame_width; // display width
+ u_int32 frame_height; // display height
+ u_int32 enc_frame_width; // encoding width, should be 16-pix align
+ u_int32 enc_frame_height; // encoding height, should be 16-pix aligned for progressive and 32-pix aligned for interlace
+ u_int32 frame_rate_num;
+ u_int32 frame_rate_den;
+
+ u_int32 vi_field_source; // vi input source is frame or field
+ u_int32 vi_frame_width;
+ u_int32 vi_frame_height;
+ u_int32 crop_frame_width;
+ u_int32 crop_frame_height;
+ u_int32 crop_x_start_posn;
+ u_int32 crop_y_start_posn;
+ u_int32 mode422;
+ u_int32 mode_yuy2;
+ u_int32 dsa_luma_en;
+ u_int32 dsa_chroma_en;
+ u_int32 dsa_ext_hfilt_en;
+ u_int32 dsa_di_en;
+ u_int32 dsa_di_top_ref;
+ u_int32 dsa_vertf_disable; // disable the vertical filter.
+ u_int32 dsa_disable_pwb;
+ u_int32 dsa_hor_phase;
+ u_int32 dsa_ver_phase;
+
+ u_int32 dsa_iac_enable; // IAC / DSA cannot operate independently in FW so this variable controls
+ u_int32 iac_sc_threshold;
+ u_int32 iac_vm_threshold;
+ u_int32 iac_skip_mode;
+ u_int32 iac_grp_width;
+ u_int32 iac_grp_height;
+
+ u_int32 rate_control_mode;
+ u_int32 rate_control_resolution;
+ u_int32 buffer_size;
+ u_int32 buffer_level_init;
+ u_int32 buffer_I_bit_budget;
+
+ u_int32 top_field_first;
+
+ u_int32 intra_lum_qoffset;
+ u_int32 intra_chr_qoffset;
+ u_int32 inter_lum_qoffset;
+ u_int32 inter_chr_qoffset;
+ u_int32 use_def_scaling_mtx;
+
+ u_int32 inter_8x8_enab;
+ u_int32 inter_4x4_enab;
+
+ u_int32 fme_enable_qpel;
+ u_int32 fme_enable_hpel;
+ u_int32 fme_nozeromv; // can force the FME not to do the (0,0) search.
+ u_int32 fme_predmv_en;
+ u_int32 fme_pred_2mv4mv;
+ u_int32 fme_smallsadthresh;
+
+ u_int32 ame_en_lmvc;
+ u_int32 ame_x_mult;
+ u_int32 cme_enable_4mv; // Enable the use of 4MV partitioning
+ u_int32 cme_enable_1mv;
+ u_int32 hme_enable_16x8mv;
+ u_int32 hme_enable_8x16mv;
+ u_int32 cme_mv_weight; // CME motion vector decisions are made by combining these
+ u_int32 cme_mv_cost; // cost and weight variables
+ u_int32 ame_mult_mv;
+ u_int32 ame_shift_mv;
+
+ u_int32 hme_forceto1mv_en;
+ u_int32 hme_2mv_cost; // the cost of choosing a 2MV mode over 1MV.
+ u_int32 hme_pred_mode;
+ u_int32 hme_sc_rnge;
+ u_int32 hme_sw_rnge;
+
+ // for windsor pes , add by fulin
+ u_int32 output_format; // 0: output ES; 1: output PES
+ u_int32 timestamp_enab; // 0: have timestamps in all frame; 1: have timestamps in I and P frame; 2: have timestamps only in I frame
+ u_int32 initial_PTS_enab; // if enabled , use following value,else compute by fw
+ u_int32 initial_PTS; // the initial value of PTS in the first frame (ms)
+
+} MEDIAIP_ENC_CONFIG_PARAMS, *pMEDIAIP_ENC_CONFIG_PARAMS;
+
+
+///////////////////////////////////////////
+// MEDIAIP_ENC_STATIC_PARAMS
+//
+// Static parameters ( may change at the GOP level )
+
+typedef struct
+{
+ u_int32 ParamChange;
+
+ u_int32 gop_length;
+
+ u_int32 rate_control_bitrate;
+ u_int32 rate_control_bitrate_min;
+ u_int32 rate_control_bitrate_max;
+ u_int32 rate_control_content_models;
+ u_int32 rate_control_iframe_maxsize; // Maximum size of I frame generated by BPM in comparison to ideal (/4)
+ u_int32 rate_control_qp_init;
+ u_int32 rate_control_islice_qp;
+ u_int32 rate_control_pslice_qp;
+ u_int32 rate_control_bslice_qp;
+
+ u_int32 adaptive_quantization; // Enable the use of activity measures from VIPP in QP assignment
+ u_int32 aq_variance;
+ u_int32 cost_optimization; // Enable picture/frame level adjustments of the cost parameters by FW.
+ u_int32 fdlp_mode; // Frequency-domain low-pass filter control, 0: off, 1-4: specific, 5: adaptive
+ u_int32 enable_isegbframes; // Enable the use of B frames in the first segment of a GOP
+ u_int32 enable_adaptive_keyratio; // Enable the use of an adaptive I to P/B ratio (aims to reduce distortion)
+ u_int32 keyratio_imin; // Clamps applied to picture size ratios
+ u_int32 keyratio_imax;
+ u_int32 keyratio_pmin;
+ u_int32 keyratio_pmax;
+ u_int32 keyratio_bmin;
+ u_int32 keyratio_bmax;
+ int32 keyratio_istep;
+ int32 keyratio_pstep;
+ int32 keyratio_bstep;
+
+ u_int32 enable_paff; // Enable Picture Adaptive Frame/Field
+ u_int32 enable_b_frame_ref; // Enable B frame as references
+ u_int32 enable_adaptive_gop; // Enable an adaptive GOP structure
+ u_int32 enable_closed_gop; // Enable a closed GOP structure
+ // i.e. if enabled, the first consecutive B frames following
+ // an I frame in each GOP will be intra or backwards only coded
+ // and do not rely on previous reference pictures.
+ u_int32 open_gop_refresh_freq; // Controls the insertion of closed GOP's (or IDR GOP's in H.264)
+ u_int32 enable_adaptive_sc; // Enable adaptive scene change GOP structure (0:off, 1:adaptive, 2:IDR)
+ u_int32 enable_fade_detection; // Enable fade detection and associated motion estimation restrictions
+ int32 fade_detection_threshold; // Threshold at which the activity slope indicates a possible fading event
+ u_int32 enable_repeat_b; // Enalbe the repeated B frame mode at CBR
+
+} MEDIAIP_ENC_STATIC_PARAMS, *pMEDIAIP_ENC_STATIC_PARAMS;
+
+///////////////////////////////////////////
+// MEDIAIP_ENC_DYN_PARAMS
+//
+// Dynamic parameters (may change at the frame level)
+
+typedef struct
+{
+ u_int32 ParamChange;
+
+ u_int32 rows_per_slice;
+
+ u_int32 mbaff_enable; // Macroblock adaptive frame/field enable
+ u_int32 dbf_enable; // Enable the deblocking filter
+
+ u_int32 field_source; // progressive/interlaced control
+ u_int32 gop_b_length; // Number of B frames between anchor frames
+ // (only to be changed at a GOP segment boundary)
+ u_int32 mb_group_size; // Number of macroblocks normally assigned to a group
+ // (implications for performance, interrupts and rate control)
+
+ u_int32 cbr_rows_per_group;
+
+ u_int32 skip_enable; // Enable the use of skipped macroblocks
+
+ u_int32 pts_bits_0_to_31; // TO BE REMOVED...
+ u_int32 pts_bit_32;
+
+ u_int32 rm_expsv_cff;
+ u_int32 const_ipred;
+ int32 chr_qp_offset;
+ u_int32 intra_mb_qp_offset;
+
+ u_int32 h264_cabac_init_method;
+ u_int32 h264_cabac_init_idc;
+ u_int32 h264_cabac_enable; // Main and stream
+
+ int32 alpha_c0_offset_div2;
+ int32 beta_offset_div2;
+
+ u_int32 intra_prefresh_y0; // for setting intra limits for prog refresh.
+ u_int32 intra_prefresh_y1;
+
+ u_int32 dbg_dump_rec_src;
+
+} MEDIAIP_ENC_DYN_PARAMS, *pMEDIAIP_ENC_DYN_PARAMS;
+
+///////////////////////////////////////////
+// MEDIAIP_ENC_EXPERT_MODE_PARAM
+
+typedef struct
+{
+ MEDIAIP_ENC_CALIB_PARAMS Calib;
+ MEDIAIP_ENC_CONFIG_PARAMS Config;
+ MEDIAIP_ENC_STATIC_PARAMS Static;
+ MEDIAIP_ENC_DYN_PARAMS Dynamic;
+} MEDIAIP_ENC_EXPERT_MODE_PARAM, *pMEDIAIP_ENC_EXPERT_MODE_PARAM;
+
+///////////////////////////////////////////
+// MEDIAIP_ENC_PARAM
+
+typedef struct
+{
+ MEDIAIP_ENC_FMT eCodecMode;
+ MEDIAIP_ENC_PROFILE eProfile;
+
+ u_int32 uMemChunkAddr;
+ u_int32 uMemChunkSize;
+
+ u_int32 uFrameRate;
+ u_int32 uSrcStride;
+ u_int32 uSrcWidth;
+ u_int32 uSrcHeight;
+ u_int32 uSrcOffset_x;
+ u_int32 uSrcOffset_y;
+ u_int32 uSrcCropWidth;
+ u_int32 uSrcCropHeight;
+ u_int32 uOutWidth;
+ u_int32 uOutHeight;
+ u_int32 uIFrameInterval;
+ u_int32 uGopBLength;
+ u_int32 uLowLatencyMode;
+
+ MEDIAIP_ENC_BITRATE_MODE eBitRateMode;
+ u_int32 uTargetBitrate;
+ u_int32 uMaxBitRate;
+ u_int32 uMinBitRate;
+ u_int32 uInitSliceQP;
+
+} MEDIAIP_ENC_PARAM, *pMEDIAIP_ENC_PARAM;
+
+#endif /* _MEDIAIP_FW_TYPES_H_ */
+
+/* End of File */
diff --git a/drivers/mxc/vpu_legacy/Malone_Firmware/Incl/pal.h b/drivers/mxc/vpu_legacy/Malone_Firmware/Incl/pal.h
new file mode 100755
index 000000000000..66c21417a891
--- /dev/null
+++ b/drivers/mxc/vpu_legacy/Malone_Firmware/Incl/pal.h
@@ -0,0 +1,337 @@
+/***************************************************
+ Copyright (c) 2015 Amphion Semiconductor Ltd
+ All rights reserved.
+ ***************************************************
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ ****************************************************
+ Filename : pal.h
+ Description : Public header file for the
+ Platform Abstraction Layer
+ Author: Media IP FW team (Belfast)
+
+ ***************************************************/
+
+#ifndef _PAL_H_
+#define _PAL_H_
+
+/////////////////////////////////////////////////////////////////////////////////
+// Header Files
+/////////////////////////////////////////////////////////////////////////////////
+
+#ifndef VPU_KERNEL_BUILD
+#include "stdio.h"
+#include "video_subsystem.h"
+#include "pal_os_al.h"
+/* For va_list */
+#include <stdarg.h>
+#endif
+#include "basetype.h"
+#include "pal_types.h"
+
+#if ( TARGET_APP == VPU_TEST_APP )
+/* thread, semaphore and queue funcitons */
+#include "pal_linux_map.h"
+#endif
+
+/* For buffer descriptor */
+#include "mediaip_fw_types.h"
+
+/* For va_list */
+#include <stdarg.h>
+
+/////////////////////////////////////////////////////////////////////////////////
+// Function prototypes
+/////////////////////////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////////////
+// Initialisation Functions
+//
+
+#if RTOS == NONE
+
+MEDIAIP_FW_STATUS pal_initialise ( psPALConfig pconfig );
+
+#else
+
+void pal_early_initialise ( void );
+
+MEDIAIP_FW_STATUS pal_initialise ( void );
+
+#endif
+
+//////////////////////////////////////////////////
+// Assert function
+//
+void pal_assert_impl(u_int32 uAssertPC, u_int32 uAssertInfo);
+
+///////////////////////////////////////////////////
+// Critical section functions
+//
+
+MEDIAIP_FW_STATUS pal_critical_section_begin ( PAL_CRIT_STATE *pState );
+
+MEDIAIP_FW_STATUS pal_critical_section_end ( PAL_CRIT_STATE PreviousState );
+
+///////////////////////////////////////////////////
+// Interrupt Functions
+//
+
+MEDIAIP_FW_STATUS pal_int_register ( u_int32 dwIntID,
+ PAL_PFNISR pfnHandler,
+ BOOL bFIQ );
+
+MEDIAIP_FW_STATUS pal_int_enable ( u_int32 dwIntID );
+
+void pal_int_set ( u_int32 dwIntID );
+
+#if ( TARGET_PLATFORM == GENTB_PLATFORM ) || ( TARGET_PLATFORM == GEN_TB_ENC ) || ( TARGET_PLATFORM == WIN_LIB )
+
+void pal_int_clear ( u_int32 dwIntID,
+ BOOL bDirect );
+
+MEDIAIP_FW_STATUS pal_int_get_irq_line ( u_int32 uFWIrq,
+ u_int32 *puIrqLine );
+
+#else
+
+void pal_int_clear ( u_int32 dwIntID );
+
+#endif
+
+void pal_int_clear_host ( u_int32 dwIntID );
+
+
+///////////////////////////////////////////////////
+// Processor Cache Control Functions
+//
+
+MEDIAIP_FW_STATUS pal_clean_d_cache ( void );
+
+MEDIAIP_FW_STATUS pal_disable_d_cache ( void );
+
+void pal_wait_for_interrupt ( void );
+
+///////////////////////////////////////////////////
+// Malone Cache Control Functions
+//
+void pal_set_malone_cache ( u_int32 uMalID );
+
+///////////////////////////////////////////////////
+// C Runtime Wrappers
+//
+
+MEDIAIP_FW_STATUS pal_memcpy ( void *pDest,
+ const void *pSrc,
+ u_int32 uSize );
+
+void pal_memset ( void *pDest, int32 nChar, u_int32 uCount );
+
+BOOL pal_memcompare ( void *pArea1, void *pArea2, u_int32 uSizeInWords );
+
+///////////////////////////////////////////////////
+// Hardware Timer Service APIs
+//
+
+MEDIAIP_FW_STATUS pal_timer_create ( PAL_PFNTIMER pfnCallback,
+ void * pUserData,
+ PAL_TIMER_ID * pTimer );
+
+MEDIAIP_FW_STATUS pal_timer_destroy( PAL_TIMER_ID Timer );
+
+///////////////////////////////////////////////////
+// Perf Counter APIs
+//
+
+MEDIAIP_FW_STATUS pal_perf_counter_create ( const char * pszName,
+ PAL_PERF_ID * pPCId );
+
+MEDIAIP_FW_STATUS pal_perf_counter_destroy ( PAL_PERF_ID PCId );
+
+MEDIAIP_FW_STATUS pal_perf_counter_start ( PAL_PERF_ID PCId );
+
+MEDIAIP_FW_STATUS pal_perf_counter_stop ( PAL_PERF_ID PCId );
+
+MEDIAIP_FW_STATUS pal_perf_counter_pause_control ( PAL_PERF_ID PCId , bool bStartPause);
+
+MEDIAIP_FW_STATUS pal_perf_counter_read ( PAL_PERF_ID PerfId,
+ u_int32 * puCountVal );
+
+///////////////////////////////////////////////////
+// Trace / Error / Message log functions
+//
+
+/* Error logging */
+#if !(DEBUG_CAPS == FULL_DEBUG ) && (ENABLE_TRACE_IN_RELEASE == NO)
+
+/* Non-debug case */
+MEDIAIP_FW_STATUS pal_error_log ( u_int32 uError );
+
+#else
+
+/* Debug case - wrap in macros so that we can add file and line number automatically */
+#ifdef _MSC_VER
+int pal_debug_error_log (
+#else
+MEDIAIP_FW_STATUS pal_debug_error_log (
+#endif
+ u_int32 uError,
+ char *pszFile,
+ int32 nLineNum );
+#ifndef _MSC_VER
+#define pal_error_log(x) pal_debug_error_log((x), __FILE__, __LINE__)
+#endif // _MSC_VER
+#endif
+
+/* Size of trace print buffer */
+#define FW_PRT_BUFF_SIZE 512
+
+#ifdef DISABLE_TRACE
+/* Declare pal_trace as an empty statement and cast to void to avoid a "no-effect" warning. */
+/* This soaks up the trailing semi-colon and avoids leaving them dangling. */
+#define pal_trace(...) (void)(0)
+#else
+#if ( TARGET_APP == VPU_TEST_APP )
+#ifdef NXP_MX_REAL_TARGET
+#define pal_trace(flags, fmt, arg...) dprintf(LVL_FUNC, fmt, ## arg)
+#else
+void pal_trace ( u_int32 uFlags, const char *psz_format, ...);
+#endif
+#else
+void pal_trace ( u_int32 uFlags, const char *psz_format, ...);
+#endif
+#endif
+
+int pal_vsnprintf ( char *str, int size, const char *format, va_list args );
+
+int pal_sprintf ( char *str, int size, const char *psz_format, ...);
+
+#ifdef PAL_DEBUG_LOG
+void pal_debug_log ( u_int32 uCode );
+#else
+#define pal_debug_log(...) (void)(0)
+#endif
+
+MEDIAIP_FW_STATUS pal_trace_set_level ( u_int32 uLevel,
+ BOOL bTimestamp,
+ MEDIAIP_TRACE_FLAGS * pFlags );
+
+MEDIAIP_FW_STATUS pal_trace_set_module_flag ( u_int32 uModuleID,
+ BOOL bEnable,
+ MEDIAIP_TRACE_FLAGS * pFlags );
+
+MEDIAIP_FW_STATUS pal_trace_is_module_enabled ( u_int32 uModuleID,
+ BOOL * pbEnabled );
+
+void pal_checkpoint_str(char *pMsg );
+void pal_checkpoint_hex(unsigned uData);
+#define CHECKPOINT_STR pal_checkpoint_str
+#define CHECKPOINT_HEX pal_checkpoint_hex
+
+
+///////////////////////////////////////////////////
+// Clock functions - often very platform specific
+//
+
+#ifdef PAL_CLOCK_API
+
+MEDIAIP_FW_STATUS pal_malone_clock_reg_init ( void );
+
+MEDIAIP_FW_STATUS pal_malone_clock_enable_common ( bool bEnable );
+
+MEDIAIP_FW_STATUS pal_malone_clock_enable_avc ( bool bEnable );
+
+MEDIAIP_FW_STATUS pal_malone_clock_enable_vc1 ( bool bEnable );
+
+MEDIAIP_FW_STATUS pal_malone_clock_enable_mpg ( bool bEnable );
+
+MEDIAIP_FW_STATUS pal_malone_clock_enable_avs ( bool bEnable );
+
+#endif /* PAL_CLOCK_API */
+
+///////////////////////////////////////////////////
+// Miscellaneous functions
+//
+
+void pal_fatal_exit_internal ( u_int32 uCosmicConstant,
+ char * pszFilename,
+ int iLineNum );
+
+//#define pal_fatal_exit(x) pal_fatal_exit_internal((x), __FILE__, __LINE__)
+#ifdef VPU_KERNEL_BUILD
+#define pal_fatal_exit(x) while (1) {printk("pal_fatal_exit in %s file %s line %d\n", __FUNCTION__, __FILE__, __LINE__);}
+#else
+#define pal_fatal_exit(x) while (1) {printf("pal_fatal_exit in %s file %s line %d\n", __FUNCTION__, __FILE__, __LINE__);}
+#endif
+
+
+
+u_int32 pal_find_highest_bit ( u_int32 uValue );
+
+extern u_int32 _return_pc ( void );
+
+#define pal_return_pc _return_pc
+
+u_int32 pal_get_fw_base ( void );
+
+u_int32 pal_get_target_version ( void );
+
+///////////////////////////////////////////////////
+// Memory management abstraction functions
+//
+#if ( TARGET_APP == VPU_TEST_APP )
+/* sPALMemDesc Added by NXP for their PAL implementation */
+typedef struct {
+ u_int32 size;
+ u_int32 phy_addr;
+ uint_addr virt_addr;
+#ifdef USE_ION
+ int32 ion_buf_fd;
+#endif
+} sPALMemDesc, *psPALMemDesc;
+
+MEDIAIP_FW_STATUS pal_get_phy_buf(psPALMemDesc pbuf);
+MEDIAIP_FW_STATUS pal_free_phy_buf(psPALMemDesc pbuf);
+#endif
+
+u_int32 pal_va2pa ( u_int32 * pAddr );
+
+u_int32 * pal_return_uncached_addr ( u_int32 * puAddress );
+
+u_int32 * pal_return_cacheable_addr ( u_int32 * puAddress );
+
+u_int32 * pal_return_mmu_bypass_addr ( u_int32 * puAddress );
+
+u_int32 pal_read_uncached ( u_int32 * puAddress );
+
+#if RTOS != NONE
+/* Need to add in the prototypes for the PAL ftns which invoke an OS */
+/* Abstraction layer call */
+
+#include "pal_os_al.h"
+
+#endif
+
+///////////////////////////////////////////////////
+// Miscellaneous macros
+//
+
+#ifdef PERF_MEASURE_ENABLE_ENC
+u_int32 GetCountVal();
+u_int32 SetCountVal(u_int32 CountVal);
+#endif
+
+#if ( TARGET_APP == VPU_TEST_APP )
+#define INT_ID_MALONE_LOW 0
+#define INT_ID_MALONE_HI 1
+#define INT_ID_MAX 2
+extern PAL_PFNISR int_handlers[INT_ID_MAX];
+#endif
+
+#endif /* _PAL_H_ */
+
+/* End of File */
diff --git a/drivers/mxc/vpu_legacy/Malone_Firmware/Incl/status_codes.h b/drivers/mxc/vpu_legacy/Malone_Firmware/Incl/status_codes.h
new file mode 100755
index 000000000000..cc53a566948c
--- /dev/null
+++ b/drivers/mxc/vpu_legacy/Malone_Firmware/Incl/status_codes.h
@@ -0,0 +1,99 @@
+/***************************************************
+ Copyright (c) 2015 Amphion Semiconductor Ltd
+ All rights reserved.
+ ***************************************************
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ ****************************************************
+ Filename : status_codes.h
+ Description : Public header file for FW & SW status codes
+ including those used by relevant abstraction layers
+ Author : Kyle McAdoo
+
+ *****************************************************/
+
+#ifndef _STATUS_CODES_H_
+#define _STATUS_CODES_H_
+
+typedef enum
+{
+ /* 0 0x00 */ MEDIAIP_FW_STATUS_OK = 0,
+ /* 1 0x01 */ MEDIAIP_FW_STATUS_ALREADY_INIT,
+ /* 2 0x02 */ MEDIAIP_FW_STATUS_NOT_INIT,
+ /* 3 0x03 */ MEDIAIP_FW_STATUS_INTERNAL_ERROR,
+ /* 4 0x04 */ MEDIAIP_FW_STATUS_BAD_HANDLE,
+ /* 5 0x05 */ MEDIAIP_FW_STATUS_BAD_PARAMETER,
+ /* 6 0x06 */ MEDIAIP_FW_STATUS_BAD_LENGTH,
+ /* 7 0x07 */ MEDIAIP_FW_STATUS_BAD_UNIT,
+ /* 8 0x08 */ MEDIAIP_FW_STATUS_RESOURCE_ERROR,
+ /* 9 0x09 */ MEDIAIP_FW_STATUS_CLOSED_HANDLE,
+ /* 10 0x0A */ MEDIAIP_FW_STATUS_TIMEOUT,
+ /* 11 0x0B */ MEDIAIP_FW_STATUS_NOT_ATTACHED,
+ /* 12 0x0C */ MEDIAIP_FW_STATUS_NOT_SUPPORTED,
+ /* 13 0x0D */ MEDIAIP_FW_STATUS_REOPENED_HANDLE,
+ /* 14 0x0E */ MEDIAIP_FW_STATUS_INVALID,
+ /* 15 0x0F */ MEDIAIP_FW_STATUS_DESTROYED,
+ /* 16 0x10 */ MEDIAIP_FW_STATUS_DISCONNECTED,
+ /* 17 0x11 */ MEDIAIP_FW_STATUS_BUSY,
+ /* 18 0x12 */ MEDIAIP_FW_STATUS_IN_USE,
+ /* 19 0x13 */ MEDIAIP_FW_STATUS_CANCELLED,
+ /* 20 0x14 */ MEDIAIP_FW_STATUS_UNDEFINED,
+ /* 21 0x15 */ MEDIAIP_FW_STATUS_UNKNOWN,
+ /* 22 0x16 */ MEDIAIP_FW_STATUS_NOT_FOUND,
+ /* 23 0x17 */ MEDIAIP_FW_STATUS_NOT_AVAILABLE,
+ /* 24 0x18 */ MEDIAIP_FW_STATUS_NOT_COMPATIBLE,
+ /* 25 0x19 */ MEDIAIP_FW_STATUS_NOT_IMPLEMENTED,
+ /* 26 0x1A */ MEDIAIP_FW_STATUS_EMPTY,
+ /* 27 0x1B */ MEDIAIP_FW_STATUS_FULL,
+ /* 28 0x1C */ MEDIAIP_FW_STATUS_FAILURE,
+ /* 29 0x1D */ MEDIAIP_FW_STATUS_ALREADY_ATTACHED,
+ /* 30 0x1E */ MEDIAIP_FW_STATUS_ALREADY_DONE,
+ /* 31 0x1F */ MEDIAIP_FW_STATUS_ASLEEP,
+ /* 32 0x20 */ MEDIAIP_FW_STATUS_BAD_ATTACHMENT,
+ /* 33 0x21 */ MEDIAIP_FW_STATUS_BAD_COMMAND,
+ /* 34 0x22 */ MEDIAIP_FW_STATUS_INT_HANDLED,
+ /* 35 0x23 */ MEDIAIP_FW_STATUS_INT_NOT_HANDLED,
+ /* 36 0x24 */ MEDIAIP_FW_STATUS_NOT_SET,
+ /* 37 0x25 */ MEDIAIP_FW_STATUS_NOT_HOOKED,
+ /* 38 0x26 */ MEDIAIP_FW_STATUS_COMPLETE,
+ /* 39 0x27 */ MEDIAIP_FW_STATUS_INVALID_NODE,
+ /* 40 0x28 */ MEDIAIP_FW_STATUS_DUPLICATE_NODE,
+ /* 41 0x29 */ MEDIAIP_FW_STATUS_HARDWARE_NOT_FOUND,
+ /* 42 0x2A */ MEDIAIP_FW_STATUS_ILLEGAL_OPERATION,
+ /* 43 0x2B */ MEDIAIP_FW_STATUS_INCOMPATIBLE_FORMATS,
+ /* 44 0x2C */ MEDIAIP_FW_STATUS_INVALID_DEVICE,
+ /* 45 0x2D */ MEDIAIP_FW_STATUS_INVALID_EDGE,
+ /* 46 0x2E */ MEDIAIP_FW_STATUS_INVALID_NUMBER,
+ /* 47 0x2F */ MEDIAIP_FW_STATUS_INVALID_STATE,
+ /* 48 0x30 */ MEDIAIP_FW_STATUS_INVALID_TYPE,
+ /* 49 0x31 */ MEDIAIP_FW_STATUS_STOPPED,
+ /* 50 0x32 */ MEDIAIP_FW_STATUS_SUSPENDED,
+ /* 51 0x33 */ MEDIAIP_FW_STATUS_TERMINATED,
+ /* 52 0x34 */ MEDIAIP_FW_STATUS_FRAMESTORE_NOT_HANDLED,
+ /* Last Entry */ MEDIAIP_FW_STATUS_CODE_LAST = MEDIAIP_FW_STATUS_FRAMESTORE_NOT_HANDLED
+} MEDIAIP_FW_STATUS;
+
+#if RTOS != NONE
+
+#if OSAL == CNXT_KAL
+#include "cnxt_kal_status_codes.h"
+typedef MEDIAIP_OSAL_STATUS CNXT_IRQ_RETCODE;
+typedef MEDIAIP_FW_STATUS MEDIAIP_IRQ_RETCODE;
+#endif
+
+#if OSAL == NXP_OSAL
+#include "nxp_osal_status_codes.h"
+typedef MEDIAIP_OSAL_STATUS MEDIAIP_IRQ_RETCODE;
+#endif
+
+#else
+typedef MEDIAIP_FW_STATUS MEDIAIP_IRQ_RETCODE;
+#endif
+
+#endif /* _STATUS_CODES_H_ */
+
+/* End of File */
diff --git a/drivers/mxc/vpu_legacy/Malone_Firmware/Incl/trace_types.h b/drivers/mxc/vpu_legacy/Malone_Firmware/Incl/trace_types.h
new file mode 100755
index 000000000000..18a3cb381c53
--- /dev/null
+++ b/drivers/mxc/vpu_legacy/Malone_Firmware/Incl/trace_types.h
@@ -0,0 +1,261 @@
+/***************************************************
+ Copyright (c) 2015 Amphion Semiconductor Ltd
+ All rights reserved.
+ ***************************************************
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ ****************************************************
+ Filename : trace_types.h
+ Description : Public header file containing type definitions and labels
+ related to debug trace functions
+ Author : Dave Wilson
+ Modified for Transcode FW by K McAdoo (from version 1.41)
+ This is no longer only for RTOS builds
+ ************************************************/
+
+#ifndef _TRACE_TYPES_H_
+#define _TRACE_TYPES_H_
+
+#include "basetype.h"
+
+/* Flag indicating a fatal error - top bit of error_num */
+#define MEDIAIP_ERROR_FATAL 0x80000000
+#define MEDIAIP_ERROR_WARNING 0x00000000
+
+/* Flags for trace levels */
+#define MEDIAIP_TRACE_MASK_MODULE 0x0FFFFFFF
+#define MEDIAIP_TRACE_MASK_LEVEL 0x70000000
+#define MEDIAIP_TRACE_MASK_TIMESTAMP 0x80000000
+
+#define MEDIAIP_TRACE_SHIFT_LEVEL 28
+#define MEDIAIP_TRACE_SHIFT_TIMESTAMP 31
+
+#define MEDIAIP_TRACE_LEVEL_NEVER 0x00000000
+#define MEDIAIP_TRACE_LEVEL_1 0x10000000
+#define MEDIAIP_TRACE_LEVEL_2 0x20000000
+#define MEDIAIP_TRACE_LEVEL_3 0x30000000
+#define MEDIAIP_TRACE_LEVEL_4 0x40000000
+#define MEDIAIP_TRACE_LEVEL_5 0x50000000
+#define MEDIAIP_TRACE_LEVEL_6 0x60000000
+#define MEDIAIP_TRACE_LEVEL_ALWAYS 0x70000000
+
+/* Disable the timestamp */
+#define MEDIAIP_TRACE_NO_TIMESTAMP 0x80000000
+
+/* Module identifiers */
+#define MEDIAIP_TRACE_DECODER 0x00000001
+#define MEDIAIP_TRACE_DISPLAY 0x00000002
+#define MEDIAIP_TRACE_ENCODER 0x00000003
+#define MEDIAIP_TRACE_HANDLE 0x00000004
+#define MEDIAIP_TRACE_IMGPORT 0x00000005
+#define MEDIAIP_TRACE_PAL 0x00000006
+#define MEDIAIP_TRACE_KAL 0x00000006
+#define MEDIAIP_TRACE_MEMMOVE 0x00000007
+#define MEDIAIP_TRACE_QUEUE 0x00000008
+#define MEDIAIP_TRACE_VAMUX 0x00000009
+
+/* Control Layer identifiers */
+#define MEDIAIP_TRACE_VIDEO_LAYER 0x00000050
+#define MEDIAIP_TRACE_SYSTEM_LAYER 0x00000051
+#define MEDIAIP_TRACE_PROC_LAYER 0x00000052
+#define MEDIAIP_TRACE_API_LAYER 0x00000053
+
+/* Additional IDs for application use */
+#define MEDIAIP_TRACE_APPLICATION 0x00000060
+#define MEDIAIP_TRACE_TEST 0x00000061
+
+/* The upper supported value of a trace module identifier. Make sure that
+ there are no trace IDs defined above this value since it is used to
+ determine the amount of storage required for trace flags! */
+#define MEDIAIP_TRACE_MAX 0x0000009F
+
+/* ID indicating that message should be displayed regardless of the
+ modules which are currently enabled. */
+#define MEDIAIP_TRACE_ANY 0x00000000
+
+/* Trace message color codes */
+
+#define MEDIAIP_TRACE_FG_LIGHT_BLUE "\033[1;34m"
+#define MEDIAIP_TRACE_FG_LIGHT_GREEN "\033[1;32m"
+#define MEDIAIP_TRACE_FG_LIGHT_CYAN "\033[1;36m"
+#define MEDIAIP_TRACE_FG_LIGHT_RED "\033[1;31m"
+#define MEDIAIP_TRACE_FG_WHITE "\033[1;37m"
+#define MEDIAIP_TRACE_FG_NORMAL MEDIAIP_TRACE_FG_WHITE
+#define MEDIAIP_TRACE_BG_GRAY "\033[0;47m"
+#define MEDIAIP_TRACE_BG_BLACK "\033[0;40m"
+
+/* The number of 32bit words needed to store our trace flags */
+#define MEDIAIP_TRACE_FLAGS_WORDS ((MEDIAIP_TRACE_MAX+31)/32)
+
+/* Data structure used to store trace flags */
+typedef struct
+{
+
+ u_int32 Flags[MEDIAIP_TRACE_FLAGS_WORDS];
+
+} MEDIAIP_TRACE_FLAGS;
+
+
+/////////////////////////////////////////////////////////////////////////////////
+// Module / Application and System Trace level definitions
+
+#define DECODER_TL_CATASTROPHE (MEDIAIP_TRACE_LEVEL_ALWAYS | MEDIAIP_TRACE_ANY)
+#define DECODER_TL_SEVERE (MEDIAIP_TRACE_LEVEL_ALWAYS | MEDIAIP_TRACE_DECODER)
+#define DECODER_TL_ERROR (MEDIAIP_TRACE_LEVEL_6 | MEDIAIP_TRACE_DECODER)
+#define DECODER_TL_WARNING (MEDIAIP_TRACE_LEVEL_5 | MEDIAIP_TRACE_DECODER)
+#define DECODER_TL_FUNC (MEDIAIP_TRACE_LEVEL_4 | MEDIAIP_TRACE_DECODER)
+#define DECODER_TL_INFO (MEDIAIP_TRACE_LEVEL_3 | MEDIAIP_TRACE_DECODER)
+#define DECODER_TL_VERBOSE (MEDIAIP_TRACE_LEVEL_2 | MEDIAIP_TRACE_DECODER)
+#define DECODER_TL_DEBUG (MEDIAIP_TRACE_LEVEL_1 | MEDIAIP_TRACE_DECODER)
+
+#define DISPLAY_TL_CATASTROPHE (MEDIAIP_TRACE_LEVEL_ALWAYS | MEDIAIP_TRACE_ANY)
+#define DISPLAY_TL_SEVERE (MEDIAIP_TRACE_LEVEL_ALWAYS | MEDIAIP_TRACE_DISPLAY)
+#define DISPLAY_TL_ERROR (MEDIAIP_TRACE_LEVEL_6 | MEDIAIP_TRACE_DISPLAY)
+#define DISPLAY_TL_WARNING (MEDIAIP_TRACE_LEVEL_5 | MEDIAIP_TRACE_DISPLAY)
+#define DISPLAY_TL_FUNC (MEDIAIP_TRACE_LEVEL_4 | MEDIAIP_TRACE_DISPLAY)
+#define DISPLAY_TL_INFO (MEDIAIP_TRACE_LEVEL_3 | MEDIAIP_TRACE_DISPLAY)
+#define DISPLAY_TL_VERBOSE (MEDIAIP_TRACE_LEVEL_2 | MEDIAIP_TRACE_DISPLAY)
+#define DISPLAY_TL_DEBUG (MEDIAIP_TRACE_LEVEL_1 | MEDIAIP_TRACE_DISPLAY)
+
+#define ENCODER_TL_CATASTROPHE (MEDIAIP_TRACE_LEVEL_ALWAYS | MEDIAIP_TRACE_ANY)
+#define ENCODER_TL_SEVERE (MEDIAIP_TRACE_LEVEL_ALWAYS | MEDIAIP_TRACE_ENCODER)
+#define ENCODER_TL_ERROR (MEDIAIP_TRACE_LEVEL_6 | MEDIAIP_TRACE_ENCODER)
+#define ENCODER_TL_WARNING (MEDIAIP_TRACE_LEVEL_5 | MEDIAIP_TRACE_ENCODER)
+#define ENCODER_TL_FUNC (MEDIAIP_TRACE_LEVEL_4 | MEDIAIP_TRACE_ENCODER)
+#define ENCODER_TL_INFO (MEDIAIP_TRACE_LEVEL_3 | MEDIAIP_TRACE_ENCODER)
+#define ENCODER_TL_VERBOSE (MEDIAIP_TRACE_LEVEL_2 | MEDIAIP_TRACE_ENCODER)
+#define ENCODER_TL_DEBUG (MEDIAIP_TRACE_LEVEL_1 | MEDIAIP_TRACE_ENCODER)
+
+#define HANDLE_TL_CATASTROPHE (MEDIAIP_TRACE_LEVEL_ALWAYS | MEDIAIP_TRACE_ANY)
+#define HANDLE_TL_SEVERE (MEDIAIP_TRACE_LEVEL_ALWAYS | MEDIAIP_TRACE_HANDLE)
+#define HANDLE_TL_ERROR (MEDIAIP_TRACE_LEVEL_6 | MEDIAIP_TRACE_HANDLE)
+#define HANDLE_TL_WARNING (MEDIAIP_TRACE_LEVEL_5 | MEDIAIP_TRACE_HANDLE)
+#define HANDLE_TL_FUNC (MEDIAIP_TRACE_LEVEL_4 | MEDIAIP_TRACE_HANDLE)
+#define HANDLE_TL_INFO (MEDIAIP_TRACE_LEVEL_3 | MEDIAIP_TRACE_HANDLE)
+#define HANDLE_TL_VERBOSE (MEDIAIP_TRACE_LEVEL_2 | MEDIAIP_TRACE_HANDLE)
+#define HANDLE_TL_DEBUG (MEDIAIP_TRACE_LEVEL_1 | MEDIAIP_TRACE_HANDLE)
+
+#define IMGPORT_TL_CATASTROPHE (MEDIAIP_TRACE_LEVEL_ALWAYS | MEDIAIP_TRACE_ANY)
+#define IMGPORT_TL_SEVERE (MEDIAIP_TRACE_LEVEL_ALWAYS | MEDIAIP_TRACE_IMGPORT)
+#define IMGPORT_TL_ERROR (MEDIAIP_TRACE_LEVEL_6 | MEDIAIP_TRACE_IMGPORT)
+#define IMGPORT_TL_WARNING (MEDIAIP_TRACE_LEVEL_5 | MEDIAIP_TRACE_IMGPORT)
+#define IMGPORT_TL_FUNC (MEDIAIP_TRACE_LEVEL_4 | MEDIAIP_TRACE_IMGPORT)
+#define IMGPORT_TL_INFO (MEDIAIP_TRACE_LEVEL_3 | MEDIAIP_TRACE_IMGPORT)
+#define IMGPORT_TL_VERBOSE (MEDIAIP_TRACE_LEVEL_2 | MEDIAIP_TRACE_IMGPORT)
+#define IMGPORT_TL_DEBUG (MEDIAIP_TRACE_LEVEL_1 | MEDIAIP_TRACE_IMGPORT)
+
+#define KAL_TL_CATASTROPHE (MEDIAIP_TRACE_LEVEL_ALWAYS | MEDIAIP_TRACE_ANY)
+#define KAL_TL_SEVERE (MEDIAIP_TRACE_LEVEL_ALWAYS | MEDIAIP_TRACE_KAL)
+#define KAL_TL_ERROR (MEDIAIP_TRACE_LEVEL_6 | MEDIAIP_TRACE_KAL)
+#define KAL_TL_WARNING (MEDIAIP_TRACE_LEVEL_5 | MEDIAIP_TRACE_KAL)
+#define KAL_TL_FUNC (MEDIAIP_TRACE_LEVEL_4 | MEDIAIP_TRACE_KAL)
+#define KAL_TL_INFO (MEDIAIP_TRACE_LEVEL_3 | MEDIAIP_TRACE_KAL)
+#define KAL_TL_VERBOSE (MEDIAIP_TRACE_LEVEL_2 | MEDIAIP_TRACE_KAL)
+#define KAL_TL_DEBUG (MEDIAIP_TRACE_LEVEL_1 | MEDIAIP_TRACE_KAL)
+
+#define PAL_TL_CATASTROPHE (MEDIAIP_TRACE_LEVEL_ALWAYS | MEDIAIP_TRACE_ANY)
+#define PAL_TL_SEVERE (MEDIAIP_TRACE_LEVEL_ALWAYS | MEDIAIP_TRACE_PAL)
+#define PAL_TL_ERROR (MEDIAIP_TRACE_LEVEL_6 | MEDIAIP_TRACE_PAL)
+#define PAL_TL_WARNING (MEDIAIP_TRACE_LEVEL_5 | MEDIAIP_TRACE_PAL)
+#define PAL_TL_FUNC (MEDIAIP_TRACE_LEVEL_4 | MEDIAIP_TRACE_PAL)
+#define PAL_TL_INFO (MEDIAIP_TRACE_LEVEL_3 | MEDIAIP_TRACE_PAL)
+#define PAL_TL_VERBOSE (MEDIAIP_TRACE_LEVEL_2 | MEDIAIP_TRACE_PAL)
+#define PAL_TL_DEBUG (MEDIAIP_TRACE_LEVEL_1 | MEDIAIP_TRACE_PAL)
+
+#define MEMMOVE_TL_CATASTROPHE (MEDIAIP_TRACE_LEVEL_ALWAYS | MEDIAIP_TRACE_ANY)
+#define MEMMOVE_TL_SEVERE (MEDIAIP_TRACE_LEVEL_ALWAYS | MEDIAIP_TRACE_MEMMOVE)
+#define MEMMOVE_TL_ERROR (MEDIAIP_TRACE_LEVEL_6 | MEDIAIP_TRACE_MEMMOVE)
+#define MEMMOVE_TL_WARNING (MEDIAIP_TRACE_LEVEL_5 | MEDIAIP_TRACE_MEMMOVE)
+#define MEMMOVE_TL_FUNC (MEDIAIP_TRACE_LEVEL_4 | MEDIAIP_TRACE_MEMMOVE)
+#define MEMMOVE_TL_INFO (MEDIAIP_TRACE_LEVEL_3 | MEDIAIP_TRACE_MEMMOVE)
+#define MEMMOVE_TL_VERBOSE (MEDIAIP_TRACE_LEVEL_2 | MEDIAIP_TRACE_MEMMOVE)
+#define MEMMOVE_TL_DEBUG (MEDIAIP_TRACE_LEVEL_1 | MEDIAIP_TRACE_MEMMOVE)
+
+#define QUEUE_TL_CATASTROPHE (MEDIAIP_TRACE_LEVEL_ALWAYS | MEDIAIP_TRACE_ANY)
+#define QUEUE_TL_SEVERE (MEDIAIP_TRACE_LEVEL_ALWAYS | MEDIAIP_TRACE_QUEUE)
+#define QUEUE_TL_ERROR (MEDIAIP_TRACE_LEVEL_6 | MEDIAIP_TRACE_QUEUE)
+#define QUEUE_TL_WARNING (MEDIAIP_TRACE_LEVEL_5 | MEDIAIP_TRACE_QUEUE)
+#define QUEUE_TL_FUNC (MEDIAIP_TRACE_LEVEL_4 | MEDIAIP_TRACE_QUEUE)
+#define QUEUE_TL_INFO (MEDIAIP_TRACE_LEVEL_3 | MEDIAIP_TRACE_QUEUE)
+#define QUEUE_TL_VERBOSE (MEDIAIP_TRACE_LEVEL_2 | MEDIAIP_TRACE_QUEUE)
+#define QUEUE_TL_DEBUG (MEDIAIP_TRACE_LEVEL_1 | MEDIAIP_TRACE_QUEUE)
+
+#define VAMUX_TL_CATASTROPHE (MEDIAIP_TRACE_LEVEL_ALWAYS | MEDIAIP_TRACE_ANY)
+#define VAMUX_TL_SEVERE (MEDIAIP_TRACE_LEVEL_ALWAYS | MEDIAIP_TRACE_VAMUX)
+#define VAMUX_TL_ERROR (MEDIAIP_TRACE_LEVEL_6 | MEDIAIP_TRACE_VAMUX)
+#define VAMUX_TL_WARNING (MEDIAIP_TRACE_LEVEL_5 | MEDIAIP_TRACE_VAMUX)
+#define VAMUX_TL_FUNC (MEDIAIP_TRACE_LEVEL_4 | MEDIAIP_TRACE_VAMUX)
+#define VAMUX_TL_INFO (MEDIAIP_TRACE_LEVEL_3 | MEDIAIP_TRACE_VAMUX)
+#define VAMUX_TL_VERBOSE (MEDIAIP_TRACE_LEVEL_2 | MEDIAIP_TRACE_VAMUX)
+#define VAMUX_TL_DEBUG (MEDIAIP_TRACE_LEVEL_1 | MEDIAIP_TRACE_VAMUX)
+
+#define VIDEO_TL_CATASTROPHE (MEDIAIP_TRACE_LEVEL_ALWAYS | MEDIAIP_TRACE_ANY)
+#define VIDEO_TL_SEVERE (MEDIAIP_TRACE_LEVEL_ALWAYS | MEDIAIP_TRACE_VIDEO_LAYER)
+#define VIDEO_TL_ERROR (MEDIAIP_TRACE_LEVEL_6 | MEDIAIP_TRACE_VIDEO_LAYER)
+#define VIDEO_TL_WARNING (MEDIAIP_TRACE_LEVEL_5 | MEDIAIP_TRACE_VIDEO_LAYER)
+#define VIDEO_TL_FUNC (MEDIAIP_TRACE_LEVEL_4 | MEDIAIP_TRACE_VIDEO_LAYER)
+#define VIDEO_TL_INFO (MEDIAIP_TRACE_LEVEL_3 | MEDIAIP_TRACE_VIDEO_LAYER)
+#define VIDEO_TL_VERBOSE (MEDIAIP_TRACE_LEVEL_2 | MEDIAIP_TRACE_VIDEO_LAYER)
+#define VIDEO_TL_DEBUG (MEDIAIP_TRACE_LEVEL_1 | MEDIAIP_TRACE_VIDEO_LAYER)
+
+#define SYSTEM_TL_CATASTROPHE (MEDIAIP_TRACE_LEVEL_ALWAYS | MEDIAIP_TRACE_ANY)
+#define SYSTEM_TL_SEVERE (MEDIAIP_TRACE_LEVEL_ALWAYS | MEDIAIP_TRACE_SYSTEM_LAYER)
+#define SYSTEM_TL_ERROR (MEDIAIP_TRACE_LEVEL_6 | MEDIAIP_TRACE_SYSTEM_LAYER)
+#define SYSTEM_TL_WARNING (MEDIAIP_TRACE_LEVEL_5 | MEDIAIP_TRACE_SYSTEM_LAYER)
+#define SYSTEM_TL_FUNC (MEDIAIP_TRACE_LEVEL_4 | MEDIAIP_TRACE_SYSTEM_LAYER)
+#define SYSTEM_TL_INFO (MEDIAIP_TRACE_LEVEL_3 | MEDIAIP_TRACE_SYSTEM_LAYER)
+#define SYSTEM_TL_VERBOSE (MEDIAIP_TRACE_LEVEL_2 | MEDIAIP_TRACE_SYSTEM_LAYER)
+#define SYSTEM_TL_DEBUG (MEDIAIP_TRACE_LEVEL_1 | MEDIAIP_TRACE_SYSTEM_LAYER)
+
+#define PROC_TL_CATASTROPHE (MEDIAIP_TRACE_LEVEL_ALWAYS | MEDIAIP_TRACE_ANY)
+#define PROC_TL_SEVERE (MEDIAIP_TRACE_LEVEL_ALWAYS | MEDIAIP_TRACE_PROC_LAYER)
+#define PROC_TL_ERROR (MEDIAIP_TRACE_LEVEL_6 | MEDIAIP_TRACE_PROC_LAYER)
+#define PROC_TL_WARNING (MEDIAIP_TRACE_LEVEL_5 | MEDIAIP_TRACE_PROC_LAYER)
+#define PROC_TL_FUNC (MEDIAIP_TRACE_LEVEL_4 | MEDIAIP_TRACE_PROC_LAYER)
+#define PROC_TL_INFO (MEDIAIP_TRACE_LEVEL_3 | MEDIAIP_TRACE_PROC_LAYER)
+#define PROC_TL_VERBOSE (MEDIAIP_TRACE_LEVEL_2 | MEDIAIP_TRACE_PROC_LAYER)
+#define PROC_TL_DEBUG (MEDIAIP_TRACE_LEVEL_1 | MEDIAIP_TRACE_PROC_LAYER)
+
+#define API_TL_CATASTROPHE (MEDIAIP_TRACE_LEVEL_ALWAYS | MEDIAIP_TRACE_ANY)
+#define API_TL_SEVERE (MEDIAIP_TRACE_LEVEL_ALWAYS | MEDIAIP_TRACE_API_LAYER)
+#define API_TL_ERROR (MEDIAIP_TRACE_LEVEL_6 | MEDIAIP_TRACE_API_LAYER)
+#define API_TL_WARNING (MEDIAIP_TRACE_LEVEL_5 | MEDIAIP_TRACE_API_LAYER)
+#define API_TL_FUNC (MEDIAIP_TRACE_LEVEL_4 | MEDIAIP_TRACE_API_LAYER)
+#define API_TL_INFO (MEDIAIP_TRACE_LEVEL_3 | MEDIAIP_TRACE_API_LAYER)
+#define API_TL_VERBOSE (MEDIAIP_TRACE_LEVEL_2 | MEDIAIP_TRACE_API_LAYER)
+#define API_TL_DEBUG (MEDIAIP_TRACE_LEVEL_1 | MEDIAIP_TRACE_API_LAYER)
+
+#define APP_TL_CATASTROPHE (MEDIAIP_TRACE_LEVEL_ALWAYS | MEDIAIP_TRACE_ANY)
+#define APP_TL_SEVERE (MEDIAIP_TRACE_LEVEL_ALWAYS | MEDIAIP_TRACE_APPLICATION)
+#define APP_TL_ERROR (MEDIAIP_TRACE_LEVEL_6 | MEDIAIP_TRACE_APPLICATION)
+#define APP_TL_WARNING (MEDIAIP_TRACE_LEVEL_5 | MEDIAIP_TRACE_APPLICATION)
+#define APP_TL_FUNC (MEDIAIP_TRACE_LEVEL_4 | MEDIAIP_TRACE_APPLICATION)
+#define APP_TL_INFO (MEDIAIP_TRACE_LEVEL_3 | MEDIAIP_TRACE_APPLICATION)
+#define APP_TL_VERBOSE (MEDIAIP_TRACE_LEVEL_2 | MEDIAIP_TRACE_APPLICATION)
+#define APP_TL_DEBUG (MEDIAIP_TRACE_LEVEL_1 | MEDIAIP_TRACE_APPLICATION)
+
+#define TEST_TL_CATASTROPHE (MEDIAIP_TRACE_LEVEL_ALWAYS | MEDIAIP_TRACE_ANY)
+#define TEST_TL_SEVERE (MEDIAIP_TRACE_LEVEL_ALWAYS | MEDIAIP_TRACE_TEST)
+#define TEST_TL_ERROR (MEDIAIP_TRACE_LEVEL_6 | MEDIAIP_TRACE_TEST)
+#define TEST_TL_WARNING (MEDIAIP_TRACE_LEVEL_5 | MEDIAIP_TRACE_TEST)
+#define TEST_TL_FUNC (MEDIAIP_TRACE_LEVEL_4 | MEDIAIP_TRACE_TEST)
+#define TEST_TL_INFO (MEDIAIP_TRACE_LEVEL_3 | MEDIAIP_TRACE_TEST)
+#define TEST_TL_VERBOSE (MEDIAIP_TRACE_LEVEL_2 | MEDIAIP_TRACE_TEST)
+#define TEST_TL_DEBUG (MEDIAIP_TRACE_LEVEL_1 | MEDIAIP_TRACE_TEST)
+
+#if RTOS != NONE
+#if OSAL == CNXT_KAL
+
+typedef MEDIAIP_TRACE_FLAGS CNXT_TRACE_FLAGS;
+
+#endif /* OSAL == CNXT_KAL */
+#endif /* RTOS != NOOS */
+
+#endif /* _TRACE_TYPES_H_ */
+
+
+/* End of file */
diff --git a/drivers/mxc/vpu_legacy/Malone_Firmware/PAL/Incl/pal_linux_map.h b/drivers/mxc/vpu_legacy/Malone_Firmware/PAL/Incl/pal_linux_map.h
new file mode 100755
index 000000000000..8e6563091809
--- /dev/null
+++ b/drivers/mxc/vpu_legacy/Malone_Firmware/PAL/Incl/pal_linux_map.h
@@ -0,0 +1,149 @@
+/***********************************************
+ * Copyright (c) 2015 Amphion Semiconductor Ltd *
+ ***********************************************
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ ****************************************************
+ *
+ * Filename: pal_linux_map.h
+ * Description: Maps the abstraction layer type from the
+ * PAL to Linux defines, though a variation of CNXT KAL
+ * for implementing NXP PAL implementaiton layer
+ * Author: Media IP FW team (Belfast)
+ *
+ ******************************************************************************
+ * $Id:
+ ******************************************************************************/
+
+/* Note : At the moment I have done no real comparison and merge of the
+ different abstarction layers supported in the PAL layer so this
+ file is simply a direct map - currently its only ftn is to
+ remove compiler warnings and to get the code structure correct for
+ the future
+*/
+
+#ifndef _PAL_LINUX_MAP_H_
+#define _PAL_LINUX_MAP_H_
+
+#include "status_codes.h"
+
+/*******************/
+/* Resource Limits */
+/*******************/
+
+#if 0
+/* Maximum length of an OS object name string */
+#define PAL_MAX_OBJ_NAME_LENGTH CNXT_KAL_MAX_OBJ_NAME_LENGTH
+#endif
+
+#define PAL_NO_WAIT 0
+#define PAL_WAIT_FOREVER ((u_int32)-1)
+
+#if 0
+/* Macro to assign task priority based on RTOS */
+#define PAL_THREAD_PRIO(Prio, UCOS_Prio) CNXT_KAL_THREAD_PRIO(Prio, UCOS_Prio)
+
+/* Task Priority Limits. */
+#define PAL_DEFAULT_PRIORITY CNXT_KAL_DEFAULT_PRIORITY
+#define PAL_MAX_THREAD_PRIORITY CNXT_KAL_MAX_THREAD_PRIORITY
+#define PAL_MIN_THREAD_PRIORITY CNXT_KAL_MIN_THREAD_PRIORITY
+#endif
+
+/* Object identifiers, KAL originated */
+typedef u_int32 CNXT_QUEUE_ID;
+typedef u_int32 CNXT_THREAD_ID;
+typedef u_int32 CNXT_SEM_ID;
+typedef u_int32 CNXT_MUTEX_ID;
+typedef u_int32 CNXT_POOL_ID;
+typedef u_int16 CNXT_EVENTS;
+typedef u_int32 CNXT_TICK_ID;
+typedef u_int32 CNXT_TIMER_ID;
+typedef bool CNXT_CRIT_STATE;
+
+#define PAL_QUEUE_ID CNXT_QUEUE_ID
+#define PAL_THREAD_ID CNXT_THREAD_ID
+#define PAL_SEM_ID CNXT_SEM_ID
+#define PAL_POOL_ID CNXT_POOL_ID
+#define PAL_EVENTS CNXT_EVENTS
+#define PAL_TICK_ID CNXT_TICK_ID
+#define PAL_TIMER_ID CNXT_TIMER_ID
+#define PAL_CRIT_STATE CNXT_CRIT_STATE
+
+
+typedef enum
+{
+ PAL_CB_LOW_PRIORITY,
+ PAL_CB_LOW_PRIORITY_NO_BLOCK,
+ PAL_CB_HIGH_PRIORITY,
+ PAL_CB_HIGH_PRIORITY_NO_BLOCK,
+ PAL_CB_PRIORITY_LAST = PAL_CB_HIGH_PRIORITY_NO_BLOCK
+} PAL_CB_PRIORITY;
+
+#define PAL_PFNTHREAD PFNTHREAD
+#define PAL_PFNISR PFNISR
+#define PAL_PFNTHREADCALLBACK PFNTHREADCALLBACK
+typedef void (*PFNTHREAD)(int, void **);
+typedef MEDIAIP_FW_STATUS (*PFNISR)(u_int32);
+typedef void (*PFNTHREADCALLBACK)(u_int32, u_int32, void *);
+
+
+
+
+
+/*****************************************************************/
+/** PAL functions exporting OS abstraction layer functionality **/
+/*****************************************************************/
+
+MEDIAIP_FW_STATUS pal_thread_create ( PAL_PFNTHREAD pfnEntryPoint,
+ int nArgC,
+ void **ppArgV,
+ u_int32 uStackSize,
+ u_int8 uPrio,
+ const char *pszName,
+ PAL_THREAD_ID *pId );
+
+MEDIAIP_FW_STATUS pal_thread_terminate ( PAL_THREAD_ID *pId );
+
+MEDIAIP_FW_STATUS pal_make_async_thread_callback (
+ PAL_PFNTHREADCALLBACK pfnCallback,
+ PAL_CB_PRIORITY Priority,
+ u_int32 uParam1,
+ u_int32 uParam2,
+ void *pData );
+
+
+
+
+////////////////////////////////////////////////////////////////////////////////
+// Semaphore functions
+////////////////////////////////////////////////////////////////////////////////
+
+MEDIAIP_FW_STATUS pal_sem_create ( u_int32 uInitialValue,
+ const char *pszName,
+ PAL_SEM_ID *pSem);
+
+////////////////////////////////////////////////////////////////////////////////
+// Queue functions
+////////////////////////////////////////////////////////////////////////////////
+
+MEDIAIP_FW_STATUS pal_qu_create ( unsigned int nMaxElements,
+ const char *pszName,
+ PAL_QUEUE_ID *pQuId );
+
+MEDIAIP_FW_STATUS pal_qu_destroy ( PAL_QUEUE_ID QuId );
+
+MEDIAIP_FW_STATUS pal_qu_send ( PAL_QUEUE_ID QuId,
+ void *pMessage );
+
+MEDIAIP_FW_STATUS pal_qu_receive ( PAL_QUEUE_ID QuId,
+ u_int32 uTimeoutMs,
+ void *pMessage );
+
+
+#endif /* _PAL_CNXT_KAL_MAP_H_ */
+
+/* End of File */
diff --git a/drivers/mxc/vpu_legacy/Malone_Firmware/PAL/Incl/pal_types.h b/drivers/mxc/vpu_legacy/Malone_Firmware/PAL/Incl/pal_types.h
new file mode 100755
index 000000000000..0177427fa590
--- /dev/null
+++ b/drivers/mxc/vpu_legacy/Malone_Firmware/PAL/Incl/pal_types.h
@@ -0,0 +1,170 @@
+/***************************************************
+ Copyright (c) 2015 Amphion Semiconductor Ltd
+ All rights reserved.
+ ***************************************************
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ ****************************************************
+
+ Filename: pal_types.h
+ Description: Public header file for PAL type definitions
+ Common between all platforms
+ Author: Media IP FW team (Belfast)
+
+ ****************************************************/
+
+#ifndef _PAL_TYPES_H_
+#define _PAL_TYPES_H_
+
+/////////////////////////////////////////////////////////////////////////////////
+// Header Files
+/////////////////////////////////////////////////////////////////////////////////
+
+#include "basetype.h"
+#include "status_codes.h"
+#include "trace_types.h"
+
+/////////////////////////////////////////////////////////////////////////////////
+// Macros
+/////////////////////////////////////////////////////////////////////////////////
+
+// Define the magic cookie
+#define PAL_CONFIG_MAGIC 0x434C4150 // "PALC", little endian
+
+// Values for pal_trace_destination
+#define PAL_TRACE_TO_DEVNULL 0
+#define PAL_TRACE_TO_UART 1
+#define PAL_TRACE_TO_MESSAGE 2
+#define PAL_TRACE_TO_CIRCULARBUF 3
+
+#if ( TARGET_PLATFORM == GENTB_PLATFORM ) || ( TARGET_PLATFORM == WIN_LIB ) || ( TARGET_PLATFORM == GEN_TB_ENC )
+
+#define PAL_CONFIG_MAX_IRQS 0x12
+#define PAL_CONFIG_MAX_MALONES 0x2
+#define PAL_CONFIG_MAX_WINDSORS 0x1
+#define PAL_CONFIG_MAX_TIMER_IRQS 0x4
+#define PAL_CONFIG_MAX_TIMER_SLOTS 0x4
+
+/* Define the entry locations in the irq vector */
+#define PAL_IRQ_MALONE0_LOW 0x0
+#define PAL_IRQ_MALONE0_HI 0x1
+#define PAL_IRQ_MALONE1_LOW 0x2
+#define PAL_IRQ_MALONE1_HI 0x3
+#define PAL_IRQ_WINDSOR_LOW 0x4
+#define PAL_IRQ_WINDSOR_HI 0x5
+#define PAL_IRQ_HOST_CMD_LO 0x6
+#define PAL_IRQ_HOST_CMD_HI 0x7
+#define PAL_IRQ_HOST_MSG 0x9
+#define PAL_IRQ_DPV 0xA
+#define PAL_IRQ_TIMER_0 0xE
+#define PAL_IRQ_TIMER_1 0xF
+#define PAL_IRQ_TIMER_2 0x10
+#define PAL_IRQ_TIMER_3 0x11
+
+#else
+
+#define PAL_CONFIG_MAX_INITS 4 // Number of init slots
+#define PAL_CONFIG_MAX_IRQS 2 // Number of incoming irq lines supported
+
+#endif /* TARGET_PLATFORM == TB_PLATFORM */
+
+/////////////////////////////////////////////////////////////////////////////////
+// Structure definitions
+/////////////////////////////////////////////////////////////////////////////////
+
+#if OSAL == NO_AL
+/* Function pointer types */
+typedef u_int32 PAL_TIMER_ID;
+typedef u_int32 PAL_CRIT_STATE;
+
+typedef MEDIAIP_IRQ_RETCODE (*PAL_PFNISR)(u_int32);
+typedef void (*PAL_PFNTIMER)(PAL_TIMER_ID, void *);
+
+#endif
+
+typedef u_int32 PAL_PERF_ID;
+
+/////////////////////////////////////////////////////////////////////////////////
+// PAL Configuration structure
+
+#if ( TARGET_PLATFORM == GENTB_PLATFORM ) || ( TARGET_PLATFORM == WIN_LIB ) || ( TARGET_PLATFORM == GEN_TB_ENC )
+
+typedef struct _PALConfig
+{
+ u_int32 uPalConfigMagicCookie;
+
+ u_int32 uGICBaseAddr;
+ u_int32 uIrqLines[PAL_CONFIG_MAX_IRQS];
+ u_int32 uIrqTarget[PAL_CONFIG_MAX_IRQS];
+
+ u_int32 uUartBaseAddr;
+
+ u_int32 uSysClkFreq;
+ u_int32 uNumTimers;
+ u_int32 uTimerBaseAddr;
+ u_int32 uTimerSlots[PAL_CONFIG_MAX_TIMER_SLOTS];
+
+ /* Do we need this in the PAL config? Only for checking mmu setup */
+ /* perhaps - otherwise its more naturtal home is in the DECLIB_CFG */
+ /* structure */
+ u_int32 uNumMalones;
+ u_int32 uMaloneBaseAddr[PAL_CONFIG_MAX_MALONES];
+ u_int32 uHifOffset[PAL_CONFIG_MAX_MALONES];
+
+ u_int32 uNumWindsors;
+ u_int32 uWindsorBaseAddr[PAL_CONFIG_MAX_WINDSORS];
+
+ u_int32 uDPVBaseAddr;
+ u_int32 uPixIfAddr;
+
+ u_int32 pal_trace_level;
+// u_int32 pal_trace_destination;
+// u_int32 pal_trace_CBDescAddr[3]; // 3 separate circular buffers for PAL_TRACE_TO_CIRCULARBUF
+ // 0: normal 1: irq 2: fiq
+ u_int32 uHeapBase;
+ u_int32 uHeapSize;
+
+ u_int32 uFSLCacheBaseAddr;
+
+} sPALConfig, *psPALConfig;
+
+#else
+
+typedef struct _PALConfig
+{
+ u_int32 pal_config_magic_cookie;
+ u_int32 cmd_irq_line[PAL_CONFIG_MAX_IRQS];
+ u_int32 cmd_irq_clear_addr[PAL_CONFIG_MAX_INITS];
+ u_int32 cmd_irq_clear_mask[PAL_CONFIG_MAX_INITS];
+ u_int32 cmd_irq_clear_val[PAL_CONFIG_MAX_INITS];
+ u_int32 msg_irq_init_addr[PAL_CONFIG_MAX_INITS];
+ u_int32 msg_irq_init_mask[PAL_CONFIG_MAX_INITS];
+ u_int32 msg_irq_init_val[PAL_CONFIG_MAX_INITS];
+ u_int32 msg_irq_raise_addr;
+ u_int32 msg_irq_raise_mask;
+ u_int32 msg_irq_raise_val;
+ u_int32 uart_init_addr[PAL_CONFIG_MAX_INITS];
+ u_int32 uart_init_mask[PAL_CONFIG_MAX_INITS];
+ u_int32 uart_init_val[PAL_CONFIG_MAX_INITS];
+ u_int32 uart_check_addr;
+ u_int32 uart_check_mask;
+ u_int32 uart_check_val;
+ u_int32 uart_put_addr;
+ u_int32 pal_trace_level;
+ u_int32 pal_trace_destination;
+ MEDIAIP_TRACE_FLAGS pal_trace_flags; // Currently 5 words
+ u_int32 pal_trace_CBDescAddr[3]; // 3 separate circular buffers for PAL_TRACE_TO_CIRCULARBUF
+ // 0: normal 1: irq 2: fiq
+} sPALConfig, *psPALConfig;
+
+#endif /* TARGET_PLATFORM == TB_PLATFORM */
+
+
+#endif /* _PAL_TYPES_H_ */
+
+
+/* End of File */
diff --git a/drivers/mxc/vpu_legacy/Malone_Firmware/PAL/pal.c b/drivers/mxc/vpu_legacy/Malone_Firmware/PAL/pal.c
new file mode 100755
index 000000000000..d75db10b5606
--- /dev/null
+++ b/drivers/mxc/vpu_legacy/Malone_Firmware/PAL/pal.c
@@ -0,0 +1,780 @@
+/***************************************************
+ * Copyright (c) 2015 Amphion Semiconductor Ltd
+ * All rights reserved.
+ ****************************************************
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ ****************************************************
+ *
+ * Filename : pal.c
+ * Description : Code implementing Platform Abstraction Layer
+ *
+ * Author : Media IP FW team (Belfast)
+ *
+ ****************************************************/
+
+/////////////////////////////////////////////////////////////////////////////////
+//// Header Files
+///////////////////////////////////////////////////////////////////////////////////
+
+#ifndef VPU_KERNEL_BUILD
+#include <string.h>
+#include <stdlib.h>
+#include <pthread.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/errno.h>
+#include "VPU_io.h"
+#else
+#undef ARM
+#undef SUCCESS
+#include <linux/io.h>
+#include <linux/kfifo.h>
+#include <linux/kthread.h>
+
+#endif
+#include "pal.h"
+#include "VPU_regdef.h"
+#include "VPU_debug.h"
+#include "mvd.h"
+
+
+///////////////////////////////////////////////////////////////////////////////////
+//// External Function Prototypes
+///////////////////////////////////////////////////////////////////////////////////
+
+// The function declared in pal.h is set to be empty
+// and need to be defined later
+
+//volatile u_int32 guPlayerFlag[MEDIA_PLAYER_NUM_STREAMS];
+
+#ifdef VPU_KERNEL_BUILD
+extern void __iomem *vpu_base;
+#define VPU_REG_WR(reg, val) writel(val, vpu_base + reg)
+#define VPU_REG_RD(reg) readl(vpu_base + reg)
+#else
+#define VPU_REG_WR(reg, val) VpuWriteReg(reg, val)
+#define VPU_REG_RD(reg) VpuReadReg(reg)
+#endif
+
+PAL_PFNISR int_handlers[INT_ID_MAX];
+
+#ifdef ENABLE_CRIT_SECTIONS
+static int ulCriticalNesting = 0;
+#endif
+
+/////////////////////////////////////////////////////////////////////////////////////
+// Assert function, implementation to be defined but we want to use this to trap logical errors
+//
+bool gbAssertExit = FALSE;
+void pal_assert_impl(u_int32 uAssertPC, u_int32 uAssertInfo)
+{
+ /* AssertInfo could be the offset address of the calling function or something else? */
+ while(gbAssertExit==FALSE)
+ {
+ /* wait to allow debug */
+ }
+}
+
+
+MEDIAIP_FW_STATUS pal_critical_section_begin ( PAL_CRIT_STATE *pState )
+{
+#ifdef ENABLE_CRIT_SECTIONS
+ //ENTER_FUNC();
+ if(ulCriticalNesting>0)
+ dprintf(LVL_FUNC, "Nested %d\n", ulCriticalNesting);
+ // FIXME: might need MFD_HIF_MSD_REG_HOST_INTERRUPT_ENABLE 0x1000
+ *pState = VPU_REG_RD((DEC_MFD_XREG_SLV_BASE + MFD_HIF + MFD_HIF_MSD_REG_FAST_INTERRUPT_ENABLE));
+ VPU_REG_WR((DEC_MFD_XREG_SLV_BASE + MFD_HIF + MFD_HIF_MSD_REG_FAST_INTERRUPT_ENABLE), *pState & ~0x20);
+ //dprintf(LVL_FUNC, "save to State 0x%lx, expect 0x20 outside irq or 0 inside irq\n", *pState);
+ ulCriticalNesting++;
+#endif
+
+ return MEDIAIP_FW_STATUS_OK;
+}
+
+MEDIAIP_FW_STATUS pal_critical_section_end ( PAL_CRIT_STATE PreviousState )
+{
+#ifdef ENABLE_CRIT_SECTIONS
+ ulCriticalNesting--;
+ //ENTER_FUNC();
+ //dprintf(LVL_FUNC, "Nest %d\n", ulCriticalNesting);
+ //dprintf(LVL_FUNC, "restore from State 0x%lx, expect 0x20 outside irq or 0 inside irq\n", PreviousState);
+ VPU_REG_WR((DEC_MFD_XREG_SLV_BASE + MFD_HIF + MFD_HIF_MSD_REG_FAST_INTERRUPT_ENABLE), PreviousState);
+#endif
+ return MEDIAIP_FW_STATUS_OK;
+}
+
+MEDIAIP_FW_STATUS pal_int_register ( u_int32 dwIntID,
+ PAL_PFNISR pfnHandler,
+ BOOL bFIQ )
+{
+ ENTER_FUNC();
+ if (pfnHandler == NULL)
+ return MEDIAIP_FW_STATUS_BAD_PARAMETER;
+
+ if (dwIntID == PAL_IRQ_MALONE0_LOW) {
+ int_handlers[INT_ID_MALONE_LOW] = pfnHandler;
+ } else if (dwIntID == PAL_IRQ_MALONE0_HI) {
+ int_handlers[INT_ID_MALONE_HI] = pfnHandler;
+ } else {
+ err_msg("wrong dwIntID 0x%x\n", dwIntID);
+ return MEDIAIP_FW_STATUS_INT_NOT_HANDLED;
+ }
+ dprintf(LVL_FUNC, "pal pfnHandler 0x%p\n", pfnHandler);
+
+ return MEDIAIP_FW_STATUS_OK;
+}
+
+
+MEDIAIP_FW_STATUS pal_int_enable ( u_int32 dwIntID )
+{
+ ENTER_FUNC();
+ return MEDIAIP_FW_STATUS_OK;
+}
+
+void pal_int_set ( u_int32 dwIntID )
+{
+ ENTER_FUNC();
+ dprintf(LVL_FUNC, "dwIntID %d\n", dwIntID);
+
+ if (dwIntID != PAL_IRQ_MALONE0_LOW) {
+ err_msg("ERROR: not PAL_IRQ_MALONE0_LOW!!!\n");
+ EXIT_FUNC();
+ return;
+ }
+
+ VPU_REG_WR((DEC_MFD_XREG_SLV_BASE + MFD_SIF + MFD_SIF_INTR_FORCE), 0x100);
+
+ EXIT_FUNC();
+}
+
+void pal_int_clear ( u_int32 dwIntID,
+ BOOL bDirect )
+{
+ ENTER_FUNC();
+}
+
+MEDIAIP_FW_STATUS pal_int_get_irq_line ( u_int32 uFWIrq,
+ u_int32 *puIrqLine )
+{
+ ENTER_FUNC();
+ return MEDIAIP_FW_STATUS_OK;
+}
+
+MEDIAIP_FW_STATUS pal_memcpy ( void *pDest,
+ const void *pSrc,
+ u_int32 uSize )
+{
+ ENTER_FUNC();
+ if (pDest == NULL || pSrc == NULL)
+ return MEDIAIP_FW_STATUS_BAD_PARAMETER;
+
+ memcpy(pDest, pSrc, uSize);
+ return MEDIAIP_FW_STATUS_OK;
+}
+
+void pal_memset ( void *pDest, int32 nChar, u_int32 uCount )
+{
+ ENTER_FUNC();
+ dprintf(LVL_FUNC, "pDest 0x%p, nChar %d, uCount %d\n", pDest, nChar, uCount);
+ if (pDest == NULL)
+ return;
+
+ memset(pDest, nChar, uCount);
+}
+
+BOOL pal_memcompare ( void *pArea1, void *pArea2, u_int32 uSizeInWords )
+{
+ u_int32 i;
+ u_int32 *ptr0, *ptr1;
+ u_int32 uChange;
+
+ ENTER_FUNC();
+ if (pArea1 == NULL || pArea2 == NULL)
+ return FALSE;
+
+ ptr0 = ( u_int32 * ) pArea1;
+ ptr1 = ( u_int32 * ) pArea2;
+
+ for ( i = 0, uChange = 0; ( i < uSizeInWords ) && ( uChange == 0 ); i++ )
+ {
+ if ( ptr0[i] != ptr1[i] )
+ {
+ uChange = 1;
+ }
+ }
+
+ return ( uChange ) ? TRUE : FALSE;
+}
+
+MEDIAIP_FW_STATUS pal_timer_create ( PAL_PFNTIMER pfnCallback,
+ void * pUserData,
+ PAL_TIMER_ID * pTimer )
+{
+ return MEDIAIP_FW_STATUS_OK;
+}
+
+MEDIAIP_FW_STATUS pal_timer_destroy( PAL_TIMER_ID Timer )
+{
+ return MEDIAIP_FW_STATUS_OK;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// FUNCTION: pal_memalloc //
+// //
+// DESCRIPTION: //
+// allocates size bytes and returns a pointer to the allocated memory. //
+// The memory is not cleared. //
+// //
+// INPUT PARAMETERS: //
+// uSize - Size of memory in bytes to alloc //
+// //
+// OUTPUT PARAMETERS: //
+// //
+// RETURN VALUES: //
+// //
+// NOTES: //
+// //
+// CONTEXT: //
+// This function may be called from any context //
+// //
+////////////////////////////////////////////////////////////////////////////////
+#ifndef VPU_KERNEL_BUILD
+
+void * pal_memalloc ( size_t uSize )
+{
+ void * pPtr = malloc ( uSize );
+
+ return pPtr;
+}
+#endif
+////////////////////////////////////////////////////////////////////////////////
+// FUNCTION: pal_memfree //
+// //
+// DESCRIPTION: //
+// frees the memory space pointed to by ptr, which must have been //
+// returned by a previous call to malloc(), calloc() or realloc(). //
+// Otherwise, or if free(ptr) has already been called before, undefined //
+// behaviour occurs. If ptr is NULL, no operation is performed. //
+// //
+// //
+// INPUT PARAMETERS: //
+// pPtr - Pointer to memory to free //
+// //
+// OUTPUT PARAMETERS: //
+// //
+// RETURN VALUES: //
+// //
+// NOTES: //
+// //
+// CONTEXT: //
+// This function may be called from any context //
+// //
+////////////////////////////////////////////////////////////////////////////////
+#ifndef VPU_KERNEL_BUILD
+
+void pal_memfree ( void * pPtr )
+{
+ free ( pPtr );
+}
+#endif
+u_int32 pal_find_highest_bit ( u_int32 uValue )
+{
+ u_int32 mask = 0x80000000;
+ u_int32 ret = 31;
+
+ ENTER_FUNC();
+
+ while (mask && ((uValue & mask) == 0)) {
+ mask >>= 1;
+ ret--;
+ }
+
+ return ret;
+}
+
+MEDIAIP_FW_STATUS pal_perf_counter_create ( const char * pszName,
+ PAL_PERF_ID * pPCId )
+{
+ return MEDIAIP_FW_STATUS_OK;
+}
+
+MEDIAIP_FW_STATUS pal_perf_counter_destroy ( PAL_PERF_ID PCId )
+{
+ return MEDIAIP_FW_STATUS_OK;
+}
+
+MEDIAIP_FW_STATUS pal_perf_counter_start ( PAL_PERF_ID PCId )
+{
+ return MEDIAIP_FW_STATUS_OK;
+}
+
+
+MEDIAIP_FW_STATUS pal_perf_counter_pause_control ( PAL_PERF_ID PCId , bool bStartPause)
+{
+ return MEDIAIP_FW_STATUS_OK;
+}
+
+MEDIAIP_FW_STATUS pal_perf_counter_read ( PAL_PERF_ID PerfId,
+ u_int32 * puCountVal )
+{
+ return MEDIAIP_FW_STATUS_OK;
+}
+
+MEDIAIP_FW_STATUS pal_malone_clock_reg_init ( void )
+{
+ return MEDIAIP_FW_STATUS_OK;
+}
+
+static void mfd_clock_enable(unsigned int mask, bool bEnable)
+{
+ if (bEnable)
+ VPU_REG_WR((DEC_MFD_XREG_SLV_BASE + MFD_BLK_CTRL + MFD_BLK_CTRL_MFD_SYS_CLOCK_ENABLE_SET), mask);
+ else
+ VPU_REG_WR((DEC_MFD_XREG_SLV_BASE + MFD_BLK_CTRL + MFD_BLK_CTRL_MFD_SYS_CLOCK_ENABLE_CLR), mask);
+}
+
+MEDIAIP_FW_STATUS pal_malone_clock_enable_common ( bool bEnable )
+{
+ ENTER_FUNC();
+ mfd_clock_enable(0x10, bEnable);
+ return MEDIAIP_FW_STATUS_OK;
+}
+
+MEDIAIP_FW_STATUS pal_malone_clock_enable_avc ( bool bEnable )
+{
+ ENTER_FUNC();
+ mfd_clock_enable(0x1, bEnable);
+ return MEDIAIP_FW_STATUS_OK;
+}
+
+MEDIAIP_FW_STATUS pal_malone_clock_enable_vc1 ( bool bEnable )
+{
+ ENTER_FUNC();
+ mfd_clock_enable(0x2, bEnable);
+ return MEDIAIP_FW_STATUS_OK;
+}
+
+MEDIAIP_FW_STATUS pal_malone_clock_enable_mpg ( bool bEnable )
+{
+ ENTER_FUNC();
+ mfd_clock_enable(0x4, bEnable);
+ return MEDIAIP_FW_STATUS_OK;
+}
+
+MEDIAIP_FW_STATUS pal_malone_clock_enable_avs ( bool bEnable )
+{
+ ENTER_FUNC();
+ mfd_clock_enable(0x8, bEnable);
+ return MEDIAIP_FW_STATUS_OK;
+}
+
+u_int32 pal_get_target_version ( void )
+{
+ return 0;
+}
+
+#ifndef VPU_KERNEL_BUILD
+MEDIAIP_FW_STATUS pal_get_phy_buf(psPALMemDesc pbuf)
+{
+ vpu_mem_desc mem_desc = {0};
+ int ret;
+
+ ENTER_FUNC();
+
+ mem_desc.size = pbuf->size;
+ ret = IOGetPhyMem(&mem_desc);
+ if (ret) {
+ err_msg("Unable to obtain physical mem\n");
+ return MEDIAIP_FW_STATUS_RESOURCE_ERROR;
+ }
+
+ if (IOGetVirtMem(&mem_desc) == -1) {
+ err_msg("Unable to obtain virtual mem\n");
+ IOFreePhyMem(&mem_desc);
+ return MEDIAIP_FW_STATUS_RESOURCE_ERROR;
+ }
+
+ pbuf->phy_addr = mem_desc.phy_addr;
+ pbuf->virt_addr = mem_desc.virt_uaddr;
+#ifdef USE_ION
+ pbuf->ion_buf_fd = mem_desc.ion_buf_fd;
+#endif
+
+ return MEDIAIP_FW_STATUS_OK;
+}
+
+MEDIAIP_FW_STATUS pal_free_phy_buf(psPALMemDesc pbuf)
+{
+ vpu_mem_desc mem_desc = {0};
+
+ ENTER_FUNC();
+
+ mem_desc.size = pbuf->size;
+ mem_desc.phy_addr = pbuf->phy_addr;
+ mem_desc.virt_uaddr = pbuf->virt_addr;
+#ifdef USE_ION
+ mem_desc.ion_buf_fd = pbuf->ion_buf_fd;
+#endif
+
+ IOFreeVirtMem(&mem_desc);
+ IOFreePhyMem(&mem_desc);
+
+ return MEDIAIP_FW_STATUS_OK;
+}
+#endif
+
+u_int32 pal_va2pa ( u_int32 * pAddr )
+{
+ /* CAUTION: pAddr shall be physical address already*/
+ dprintf(LVL_FUNC, "pAddr 0x%p shall be physical!!!\n", pAddr);
+ return (u_int32)(uint_addr)pAddr;
+}
+
+u_int32 * pal_return_uncached_addr ( u_int32 * puAddress )
+{
+ dprintf(LVL_FUNC, "puAddress 0x%p\n", puAddress);
+ return puAddress;
+}
+
+u_int32 * pal_return_cacheable_addr ( u_int32 * puAddress )
+{
+ dprintf(LVL_FUNC, "puAddress 0x%p\n", puAddress);
+ return puAddress;
+}
+
+u_int32 pal_read_uncached ( u_int32 * puAddress )
+{
+ dprintf(LVL_FUNC, "puAddress 0x%p\n", puAddress);
+
+ if (puAddress == NULL)
+ return MEDIAIP_FW_STATUS_BAD_PARAMETER;
+
+ return (*puAddress);
+}
+
+int pal_vsnprintf ( char *str, int size, const char *format, va_list args )
+{
+ ENTER_FUNC();
+ return 0;
+}
+
+int pal_sprintf ( char *str, int size, const char *psz_format, ...)
+{
+ ENTER_FUNC();
+ return 0;
+}
+
+static void mfd_cache_clock_enable(unsigned int enable)
+{
+ ENTER_FUNC();
+ VPU_REG_WR((SCB_XREG_SLV_BASE + SCB_SCB_BLK_CTRL + SCB_BLK_CTRL_SCB_CLK_ENABLE_SET),enable);
+}
+
+void pal_set_malone_cache ( u_int32 uMalID )
+{
+ ENTER_FUNC();
+ mfd_cache_clock_enable(0xE);
+}
+
+#define MAX_QUEUE_NUM 10
+static PAL_QUEUE_ID gQuId = 0;
+
+MEDIAIP_FW_STATUS pal_sem_create ( u_int32 uInitialValue,
+ const char *pszName,
+ PAL_SEM_ID *pSem)
+{
+ /* CAUTION: if in use */
+ ENTER_FUNC();
+ return MEDIAIP_FW_STATUS_OK;
+}
+
+#ifdef VPU_KERNEL_BUILD
+
+static struct kfifo irq_fifo[MAX_QUEUE_NUM];
+static spinlock_t irq_lock[MAX_QUEUE_NUM];
+static struct task_struct *msg_thread;
+static wait_queue_head_t irq_wq[MAX_QUEUE_NUM];
+
+MEDIAIP_FW_STATUS pal_thread_create ( PAL_PFNTHREAD pfnEntryPoint,
+ int nArgC,
+ void **ppArgV,
+ u_int32 uStackSize,
+ u_int8 uPrio,
+ const char *pszName,
+ PAL_THREAD_ID *pId )
+{
+ typedef int (*INTFUNC)(void *);
+
+ /* CAUTION: shall not enter twice due to global msg_thread */
+ ENTER_FUNC();
+ //struct task_struct *msg_thread;
+ msg_thread = kthread_run((INTFUNC)pfnEntryPoint , NULL, pszName);
+ if(IS_ERR( msg_thread ))
+ return MEDIAIP_FW_STATUS_FAILURE;
+
+ return MEDIAIP_FW_STATUS_OK;
+}
+
+MEDIAIP_FW_STATUS pal_thread_terminate ( PAL_THREAD_ID *pId )
+{
+ ENTER_FUNC();
+
+ kthread_stop(msg_thread);
+
+ return MEDIAIP_FW_STATUS_OK;
+}
+
+MEDIAIP_FW_STATUS pal_qu_create ( unsigned int nMaxElements,
+ const char *pszName,
+ PAL_QUEUE_ID *pQuId )
+{
+ /* CAUTION: message length shall be 4 * sizeof(uint_addr) */
+ ENTER_FUNC();
+ *pQuId = gQuId;
+ spin_lock_init(&irq_lock[*pQuId]);
+ init_waitqueue_head(&irq_wq[*pQuId]);
+ if(kfifo_alloc(&irq_fifo[*pQuId],
+ nMaxElements * 4 * sizeof(uint_addr),
+ GFP_KERNEL))
+ {
+ err_msg("fail to alloc fifo in pal\n");
+ return MEDIAIP_FW_STATUS_FAILURE;
+ }
+
+ gQuId++;
+ if( MAX_QUEUE_NUM == gQuId)
+ gQuId=0;
+ dprintf(LVL_FUNC, "create QuId:%d\n",
+ *pQuId
+ );
+ return MEDIAIP_FW_STATUS_OK;
+}
+
+MEDIAIP_FW_STATUS pal_qu_destroy ( PAL_QUEUE_ID QuId )
+{
+ ENTER_FUNC();
+ dprintf(LVL_FUNC, "destory QuId:%d\n",
+ QuId
+ );
+ kfifo_free(&irq_fifo[QuId]);
+
+ return MEDIAIP_FW_STATUS_OK;
+}
+
+MEDIAIP_FW_STATUS pal_qu_send ( PAL_QUEUE_ID QuId,
+ void *pMessage)
+{
+ u_int32 retval;
+ ENTER_FUNC();
+ dprintf(LVL_FUNC, "QuId %d\n", QuId);
+
+ /* CAUTION: if message is not 4 * sizeof(uint_addr) */
+ retval = kfifo_in_locked(&irq_fifo[QuId], pMessage, 4 * sizeof(uint_addr),&irq_lock[QuId]);
+ dprintf(LVL_FUNC, "message send: 0x%llx, 0x%llx, 0x%llx, 0x%llx\n", *(uint_addr *)pMessage, *((uint_addr *)pMessage+1), *((uint_addr *)pMessage+2), *((uint_addr *)pMessage+3));
+ if(retval != 4*sizeof(uint_addr))
+ return MEDIAIP_FW_STATUS_FAILURE;
+ wake_up(&irq_wq[QuId]);
+
+ return MEDIAIP_FW_STATUS_OK;
+}
+
+MEDIAIP_FW_STATUS pal_qu_receive ( PAL_QUEUE_ID QuId,
+ u_int32 uTimeoutMs,
+ void *pMessage )
+{
+ u_int32 retval;
+ long ret;
+
+ ENTER_FUNC();
+ dprintf(LVL_FUNC, "QuId %d\n", QuId);
+/* while (kfifo_len(&irq_fifo) < sizeof(*pMessage)) {
+ set_current_state(TASK_INTERRUPTIBLE);
+ schedule();
+ }*/
+ ret = wait_event_interruptible_timeout(irq_wq[QuId],
+ kfifo_len(&irq_fifo[QuId])>=4*sizeof(uint_addr)
+ /* || kthread_should_stop() */,
+ //uTimeoutMs
+ msecs_to_jiffies(uTimeoutMs)
+ );
+
+ if (ret == 0) {
+ dprintf(LVL_FUNC, "timeout %d ms\n", uTimeoutMs);
+ return MEDIAIP_FW_STATUS_TIMEOUT;
+ } else if (ret == -ERESTARTSYS) {
+ dprintf(LVL_FUNC, "ERROR interrupted by a signal!!\n");
+ return MEDIAIP_FW_STATUS_FAILURE;
+ } else {
+ dprintf(LVL_FUNC, "%ld returned from wait event\n", ret);
+ }
+
+ //if(kthread_should_stop())
+ // return MEDIAIP_FW_STATUS_STOPPED;
+
+ if (kfifo_len(&irq_fifo[QuId])>=4*sizeof(uint_addr))
+ {
+ retval = kfifo_out_locked(&irq_fifo[QuId], pMessage, 4*sizeof(uint_addr),&irq_lock[QuId]);
+ dprintf(LVL_FUNC, "message receive: 0x%llx, 0x%llx, 0x%llx, 0x%llx\n", *(uint_addr *)pMessage, *((uint_addr *)pMessage+1), *((uint_addr *)pMessage+2), *((uint_addr *)pMessage+3));
+ }
+ else
+ {
+ dprintf(LVL_FUNC, "ERROR interrupted by a signal!!\n");
+ }
+
+ return MEDIAIP_FW_STATUS_OK;
+}
+
+#else
+
+#define FN_MSG_FIFO "/dev/shm/vpu_msg_fifo"
+static char fn_fifo[MAX_QUEUE_NUM][64] = {0};
+static int fd_send[MAX_QUEUE_NUM] = {0};
+static int fd_receive[MAX_QUEUE_NUM] = {0};
+
+MEDIAIP_FW_STATUS pal_thread_create ( PAL_PFNTHREAD pfnEntryPoint,
+ int nArgC,
+ void **ppArgV,
+ u_int32 uStackSize,
+ u_int8 uPrio,
+ const char *pszName,
+ PAL_THREAD_ID *pId )
+{
+ int err;
+ pthread_t msg_tid;
+
+ ENTER_FUNC();
+ err = pthread_create(&msg_tid, NULL, (void *)pfnEntryPoint, NULL);
+ if (err)
+ return MEDIAIP_FW_STATUS_FAILURE;
+
+ *pId = msg_tid;
+ return MEDIAIP_FW_STATUS_OK;
+}
+
+MEDIAIP_FW_STATUS pal_thread_terminate ( PAL_THREAD_ID *pId )
+{
+ pthread_t msg_tid = *pId;
+
+ ENTER_FUNC();
+
+ if (msg_tid == 0)
+ return MEDIAIP_FW_STATUS_BAD_PARAMETER;
+
+ pthread_cancel(msg_tid);
+ pthread_join(msg_tid, NULL);
+
+ return MEDIAIP_FW_STATUS_OK;
+}
+
+MEDIAIP_FW_STATUS pal_qu_create ( unsigned int nMaxElements,
+ const char *pszName,
+ PAL_QUEUE_ID *pQuId )
+{
+ /* CAUTION: message length shall be 4 * sizeof(uint_addr) */
+ ENTER_FUNC();
+ *pQuId = gQuId;
+ sprintf(fn_fifo[gQuId], "%s%d", FN_MSG_FIFO, gQuId);
+ if(access(fn_fifo[gQuId], F_OK) == -1)
+ {
+ if(mkfifo(fn_fifo[gQuId], 0777))
+ {
+ err_msg("failed to alloc fifo %s in pal\n", fn_fifo[gQuId]);
+ return MEDIAIP_FW_STATUS_FAILURE;
+ }
+ dprintf(LVL_FUNC, "created fifo %s\n", fn_fifo[gQuId]);
+ } else {
+ dprintf(LVL_FUNC, "exist fifo %s\n", fn_fifo[gQuId]);
+ }
+
+ gQuId++;
+ if( MAX_QUEUE_NUM == gQuId)
+ gQuId=0;
+ dprintf(LVL_FUNC, "create QuId:%d\n",
+ *pQuId
+ );
+ return MEDIAIP_FW_STATUS_OK;
+}
+
+MEDIAIP_FW_STATUS pal_qu_destroy ( PAL_QUEUE_ID QuId )
+{
+ ENTER_FUNC();
+ dprintf(LVL_FUNC, "destory QuId:%d\n",
+ QuId
+ );
+ if (fd_send[QuId]) {
+ close(fd_send[QuId]);
+ fd_send[QuId] = 0;
+ }
+ if (fd_receive[QuId]) {
+ close(fd_receive[QuId]);
+ fd_receive[QuId] = 0;
+ }
+
+ return MEDIAIP_FW_STATUS_OK;
+}
+
+MEDIAIP_FW_STATUS pal_qu_send ( PAL_QUEUE_ID QuId,
+ void *pMessage)
+{
+ u_int32 retval;
+ ENTER_FUNC();
+ dprintf(LVL_FUNC, "QuId %d\n", QuId);
+
+ /* CAUTION: if message is not 4 * sizeof(uint_addr) */
+ if (fd_send[QuId] == 0) {
+ fd_send[QuId] = open(fn_fifo[QuId], O_WRONLY);
+ if (fd_send[QuId] == -1) {
+ err_msg("failed to open fifo %s to send\n", fn_fifo[QuId]);
+ return MEDIAIP_FW_STATUS_FAILURE;
+ } else {
+ dprintf(LVL_FUNC, "opened fifo %s to send\n", fn_fifo[QuId]);
+ }
+ }
+ retval = write(fd_send[QuId], pMessage, 4 * sizeof(uint_addr));
+ if(retval != 4*sizeof(uint_addr))
+ {
+ err_msg("%s\n", strerror(errno));
+ return MEDIAIP_FW_STATUS_FAILURE;
+ }
+ dprintf(LVL_FUNC, "message send: 0x%lx, 0x%lx, 0x%lx, 0x%lx\n", *(uint_addr *)pMessage, *((uint_addr *)pMessage+1), *((uint_addr *)pMessage+2), *((uint_addr *)pMessage+3));
+
+ return MEDIAIP_FW_STATUS_OK;
+}
+
+MEDIAIP_FW_STATUS pal_qu_receive ( PAL_QUEUE_ID QuId,
+ u_int32 uTimeoutMs,
+ void *pMessage )
+{
+ u_int32 retval;
+
+ ENTER_FUNC();
+ dprintf(LVL_FUNC, "QuId %d\n", QuId);
+ // TODO: time out case
+ if (fd_receive[QuId] == 0) {
+ fd_receive[QuId] = open(fn_fifo[QuId], O_RDONLY);
+ if (fd_receive[QuId] == -1) {
+ err_msg("failed to open fifo %s to receive\n", fn_fifo[QuId]);
+ return MEDIAIP_FW_STATUS_FAILURE;
+ } else {
+ dprintf(LVL_FUNC, "opened fifo %s to receive\n", fn_fifo[QuId]);
+ }
+ }
+ retval = read(fd_receive[QuId], pMessage, 4*sizeof(uint_addr));
+ if(retval != 4*sizeof(uint_addr))
+ {
+ err_msg("%s\n", strerror(errno));
+ return MEDIAIP_FW_STATUS_FAILURE;
+ }
+ dprintf(LVL_FUNC, "message receive: 0x%lx, 0x%lx, 0x%lx, 0x%lx\n", *(uint_addr *)pMessage, *((uint_addr *)pMessage+1), *((uint_addr *)pMessage+2), *((uint_addr *)pMessage+3));
+
+ return MEDIAIP_FW_STATUS_OK;
+}
+#endif
+
diff --git a/drivers/mxc/vpu_legacy/VPU_debug.h b/drivers/mxc/vpu_legacy/VPU_debug.h
new file mode 100644
index 000000000000..1b2fd26c9572
--- /dev/null
+++ b/drivers/mxc/vpu_legacy/VPU_debug.h
@@ -0,0 +1,95 @@
+/*
+ * Copyright 2017 NXP
+ */
+
+/*
+ * The code contained herein is licensed under the GNU Lesser General
+ * Public License. You may obtain a copy of the GNU Lesser General
+ * Public License Version 2.1 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/lgpl-license.html
+ * http://www.gnu.org/copyleft/lgpl.html
+ */
+
+/*!
+ * @file vpu_debug.h
+ *
+ * @brief VPU debug definition
+ *
+ * @ingroup VPU
+ */
+
+#ifndef __VPU_DEBUG_H
+#define __VPU_DEBUG_H
+
+
+
+#define LVL_NOPRINT 0
+#define LVL_ISR 2
+#define LVL_CRI 3
+#define LVL_FUNC 5
+#define LVL_PRINTALL 10
+
+
+
+#ifdef VPU_KERNEL_BUILD
+
+#include <linux/io.h>
+
+//#define vpu_lib_dbg_level LVL_PRINTALL
+
+#define vpu_lib_dbg_level LVL_NOPRINT
+
+#define err_msg(fmt, arg...) do { if (vpu_lib_dbg_level > LVL_NOPRINT) \
+ printk("[ERR]\t%s:%d " fmt, __FILE__, __LINE__, ## arg); else \
+ printk("[ERR]\t" fmt, ## arg); \
+ } while (0)
+#define info_msg(fmt, arg...) do { if (vpu_lib_dbg_level > LVL_NOPRINT) \
+ printk("[INFO]\t%s:%d " fmt, __FILE__, __LINE__, ## arg); else \
+ printk("[INFO]\t" fmt, ## arg); \
+ } while (0)
+#define warn_msg(fmt, arg...) do { if (vpu_lib_dbg_level > LVL_NOPRINT) \
+ printk("[WARN]\t%s:%d " fmt, __FILE__, __LINE__, ## arg); else \
+ printk("[WARN]\t" fmt, ## arg); \
+ } while (0)
+
+#define dprintf(level, fmt, arg...) do {if (level <= vpu_lib_dbg_level) printk("[DEBUG]\t%s " fmt, __FUNCTION__, ## arg);} while(0)
+
+
+
+#define ENTER_FUNC() dprintf(LVL_FUNC, "enter %s()\n", __func__)
+#define EXIT_FUNC() dprintf(LVL_FUNC, "exit %s()\n", __func__)
+
+#else
+
+#include <stdio.h>
+
+#include "VPU_lib.h"
+
+
+//#define vpu_lib_dbg_level LVL_PRINTALL
+
+#define vpu_lib_dbg_level LVL_CRI
+
+#define err_msg(fmt, arg...) do { if (vpu_lib_dbg_level > LVL_NOPRINT) \
+ printf("[ERR]\t%s:%d " fmt, __FILE__, __LINE__, ## arg); else \
+ printf("[ERR]\t" fmt, ## arg); \
+ } while (0)
+#define info_msg(fmt, arg...) do { if (vpu_lib_dbg_level > LVL_NOPRINT) \
+ printf("[INFO]\t%s:%d " fmt, __FILE__, __LINE__, ## arg); else \
+ printf("[INFO]\t" fmt, ## arg); \
+ } while (0)
+#define warn_msg(fmt, arg...) do { if (vpu_lib_dbg_level > LVL_NOPRINT) \
+ printf("[WARN]\t%s:%d " fmt, __FILE__, __LINE__, ## arg); else \
+ printf("[WARN]\t" fmt, ## arg); \
+ } while (0)
+
+//#define dprintf(level, fmt, arg...) do {if (level <= vpu_lib_dbg_level) printf("[DEBUG]\t%s " fmt, __FUNCTION__, ## arg);} while(0)
+#define dprintf(level, fmt, arg...) do { if (vpu_lib_dbg_level >= level) printf("[DEBUG]\t%s:%d " fmt, __FILE__, __LINE__, ## arg); } while (0)
+
+#define ENTER_FUNC() dprintf(LVL_FUNC, "enter %s()\n", __func__)
+#define EXIT_FUNC() dprintf(LVL_FUNC, "exit %s()\n", __func__)
+
+#endif
+
+#endif
diff --git a/drivers/mxc/vpu_legacy/VPU_regdef.h b/drivers/mxc/vpu_legacy/VPU_regdef.h
new file mode 100644
index 000000000000..597cc1385db6
--- /dev/null
+++ b/drivers/mxc/vpu_legacy/VPU_regdef.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2017 NXP
+ */
+
+/*
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// vpu_regdef.h
+//
+// Description:
+//
+// Register definition
+//
+// Authors:
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef __VPU_REGDEF_H__
+#define __VPU_REGDEF_H__
+
+#define SCB_XREG_SLV_BASE 0x00000000
+#define SCB_SCB_BLK_CTRL 0x00070000
+#define SCB_BLK_CTRL_XMEM_RESET_SET 0x00000090
+#define SCB_BLK_CTRL_CACHE_RESET_SET 0x000000A0
+#define SCB_BLK_CTRL_CACHE_RESET_CLR 0x000000A4
+#define SCB_BLK_CTRL_SCB_CLK_ENABLE_SET 0x00000100
+
+#define XMEM_CONTROL 0x00041000
+
+#define DEC_MFD_XREG_SLV_BASE 0x00180000
+
+#define MFD_HIF 0x0001C000
+#define MFD_HIF_MSD_REG_HOST_INTERRUPT_ENABLE 0x00000014
+#define MFD_HIF_MSD_REG_INTERRUPT_STATUS 0x00000018
+#define MFD_HIF_MSD_REG_FAST_INTERRUPT_ENABLE 0x0000001C
+#define MFD_SIF 0x0001D000
+#define MFD_SIF_CTRL_STATUS 0x000000F0
+#define MFD_SIF_INTR_STATUS 0x000000F4
+#define MFD_SIF_INTR_FORCE 0x000000F8
+#define MFD_MCX 0x00020800
+
+#define MFD_BLK_CTRL 0x00030000
+#define MFD_BLK_CTRL_MFD_SYS_RESET_SET 0x00000000
+#define MFD_BLK_CTRL_MFD_SYS_RESET_CLR 0x00000004
+#define MFD_BLK_CTRL_MFD_SYS_CLOCK_ENABLE_SET 0x00000100
+#define MFD_BLK_CTRL_MFD_SYS_CLOCK_ENABLE_CLR 0x00000104
+
+#endif //__VPU_REGDEF_H__
diff --git a/drivers/mxc/vpu_legacy/mxc_vpu-malone.c b/drivers/mxc/vpu_legacy/mxc_vpu-malone.c
new file mode 100644
index 000000000000..8ce2787e6050
--- /dev/null
+++ b/drivers/mxc/vpu_legacy/mxc_vpu-malone.c
@@ -0,0 +1,1344 @@
+/*
+ * Copyright 2017 NXP
+ */
+
+/*
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/*!
+ * @file mxc_vpu-malone.c
+ *
+ * @brief VPU system initialization and file operation implementation
+ *
+ * @ingroup VPU
+ */
+
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/stat.h>
+#include <linux/platform_device.h>
+#include <linux/kdev_t.h>
+#include <linux/dma-mapping.h>
+#include <linux/wait.h>
+#include <linux/list.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/fsl_devices.h>
+#include <linux/uaccess.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <linux/workqueue.h>
+#include <linux/sched.h>
+#include <linux/vmalloc.h>
+#include <linux/regulator/consumer.h>
+#include <linux/page-flags.h>
+#include <linux/mm_types.h>
+#include <linux/types.h>
+#include <linux/memblock.h>
+#include <linux/memory.h>
+#include <linux/version.h>
+#include <asm/page.h>
+
+#include <linux/module.h>
+#include <linux/pm_runtime.h>
+#include <linux/sizes.h>
+
+#include <linux/busfreq-imx.h>
+#include <linux/clk.h>
+#include <linux/genalloc.h>
+#include <linux/mxc_vpu-malone.h>
+#include <linux/of.h>
+#include <linux/reset.h>
+
+#include <soc/imx8/sc/svc/pm/api.h>
+#include <soc/imx8/sc/ipc.h>
+
+#include "VPU_regdef.h"
+#include "pal.h"
+#include "mvd.h"
+#include "DecKernelLib.h"
+
+struct vpu_priv {
+ struct fasync_struct *async_queue;
+ struct work_struct work;
+ struct workqueue_struct *workqueue;
+ struct mutex lock;
+};
+
+/* To track the allocated memory buffer */
+struct memalloc_record {
+ struct list_head list;
+ struct vpu_mem_desc mem;
+};
+
+static LIST_HEAD(head);
+
+static int vpu_major;
+static struct class *vpu_class;
+static struct vpu_priv vpu_data;
+static u8 open_count;
+static struct clk *vpu_clk;
+static struct vpu_mem_desc share_mem = { 0 };
+static struct vpu_mem_desc vshare_mem = { 0 };
+
+void __iomem *vpu_base;
+static u32 phy_vpu_base_addr;
+static int vpu_dec_irq;
+static int vpu_dec_fiq;
+
+static struct device *vpu_dev;
+
+/* implement the blocking ioctl */
+static int irq_status;
+static wait_queue_head_t vpu_queue;
+
+static int vpu_clk_usercount;
+static atomic_t clk_cnt_from_ioc = ATOMIC_INIT(0);
+
+static sc_ipc_t ipcHndl;
+
+#define ISR_EVENT_QU_SIZE 64
+
+static PAL_QUEUE_ID gIsrEventQu;
+static DECODER_KERNEL_LIB_ISR_EVENT_DATA gIsrEventData[ISR_EVENT_QU_SIZE];
+static u32 uIsrEventQuWrIdx = 0;
+static DECODERLIB_KERNEL_CFG gtKernelCfg;
+
+#define READ_REG(x) readl_relaxed(vpu_base + x)
+#define WRITE_REG(val, x) writel_relaxed(val, vpu_base + x)
+
+static void vpu_reset(void)
+{
+#if 0
+ int ret;
+
+ ret = device_reset(vpu_dev);
+#endif
+}
+
+/*!
+ * Private function to change the power mode of VPU to pm
+ * @return status 0 success.
+ */
+static int setVPUPwr(sc_ipc_t ipcHndl,
+ sc_pm_power_mode_t pm
+ )
+{
+ int rv = -1;
+ sc_err_t sciErr;
+
+ dev_dbg(vpu_dev, "enter %s()\n", __FUNCTION__);
+ if (!ipcHndl)
+ {
+ dev_err(vpu_dev, "--- setVPUPwr no IPC handle\n");
+ goto setVPUPwrExit;
+ }
+
+ /* Power on or off PID0, DEC, ENC */
+ sciErr = sc_pm_set_resource_power_mode(ipcHndl, SC_R_VPU, pm);
+ if (sciErr != SC_ERR_NONE)
+ {
+ dev_err(vpu_dev, "--- sc_pm_set_resource_power_mode(SC_R_VPU,%d) SCI error! (%d)\n", pm, sciErr);
+ goto setVPUPwrExit;
+ }
+#if 0
+ /* FIXME: no need of PID1-7? */
+ sciErr = sc_pm_set_resource_power_mode(ipcHndl, SC_R_VPU_PID1, pm);
+ if (sciErr != SC_ERR_NONE)
+ {
+ dev_err(vpu_dev, "--- sc_pm_set_resource_power_mode(SC_R_VPU_PID1,%d) SCI error! (%d)\n", pm, sciErr);
+ goto setVPUPwrExit;
+ }
+ sciErr = sc_pm_set_resource_power_mode(ipcHndl,SC_R_VPU_PID2, pm);
+ if (sciErr != SC_ERR_NONE)
+ {
+ dev_err(vpu_dev, "--- sc_pm_set_resource_power_mode(SC_R_VPU_PID2,%d) SCI error! (%d)\n", pm, sciErr);
+ goto setVPUPwrExit;
+ }
+ sciErr = sc_pm_set_resource_power_mode(ipcHndl, SC_R_VPU_PID3, pm);
+ if (sciErr != SC_ERR_NONE)
+ {
+ dev_err(vpu_dev, "--- sc_pm_set_resource_power_mode(SC_R_VPU_PID3,%d) SCI error! (%d)\n", pm, sciErr);
+ goto setVPUPwrExit;
+ }
+ sciErr = sc_pm_set_resource_power_mode(ipcHndl, SC_R_VPU_PID4, pm);
+ if (sciErr != SC_ERR_NONE)
+ {
+ dev_err(vpu_dev, "--- sc_pm_set_resource_power_mode(SC_R_VPU_PID4,%d) SCI error! (%d)\n", pm, sciErr);
+ goto setVPUPwrExit;
+ }
+ sciErr = sc_pm_set_resource_power_mode(ipcHndl, SC_R_VPU_PID5, pm);
+ if (sciErr != SC_ERR_NONE)
+ {
+ dev_err(vpu_dev, "--- sc_pm_set_resource_power_mode(SC_R_VPU_PID5,%d) SCI error! (%d)\n", pm, sciErr);
+ goto setVPUPwrExit;
+ }
+ sciErr = sc_pm_set_resource_power_mode(ipcHndl, SC_R_VPU_PID6, pm);
+ if (sciErr != SC_ERR_NONE)
+ {
+ dev_err(vpu_dev, "--- sc_pm_set_resource_power_mode(SC_R_VPU_PID6,%d) SCI error! (%d)\n", pm, sciErr);
+ goto setVPUPwrExit;
+ }
+ sciErr = sc_pm_set_resource_power_mode(ipcHndl, SC_R_VPU_PID7, pm);
+ if (sciErr != SC_ERR_NONE)
+ {
+ dev_err(vpu_dev, "--- sc_pm_set_resource_power_mode(SC_R_VPU_PID7,%d) SCI error! (%d)\n", pm, sciErr);
+ goto setVPUPwrExit;
+ }
+#endif
+ sciErr = sc_pm_set_resource_power_mode(ipcHndl, SC_R_VPU_DEC_0, pm);
+ if (sciErr != SC_ERR_NONE)
+ {
+ dev_err(vpu_dev, "--- sc_pm_set_resource_power_mode(SC_R_VPU_DEC_0,%d) SCI error! (%d)\n", pm, sciErr);
+ goto setVPUPwrExit;
+ }
+ sciErr = sc_pm_set_resource_power_mode(ipcHndl, SC_R_VPU_ENC_0, pm);
+ if (sciErr != SC_ERR_NONE)
+ {
+ dev_err(vpu_dev, "--- sc_pm_set_resource_power_mode(SC_R_VPU_ENC_0,%d) SCI error! (%d)\n", pm, sciErr);
+ goto setVPUPwrExit;
+ }
+
+ rv = 0;
+
+setVPUPwrExit:
+ return (rv);
+}
+
+#if 0
+/*!
+ * Private function to return the power mode of VPU
+ * @return <0 if there were errors.
+ */
+static sc_pm_power_mode_t getVPUPwr(sc_ipc_t ipcHndl)
+{
+ sc_pm_power_mode_t rv = -1;
+ sc_err_t sciErr;
+
+ if (!ipcHndl)
+ {
+ dev_err(vpu_dev, "--- getVPUPwr no IPC handle\n");
+ return (rv);
+ }
+
+ sciErr = sc_pm_get_resource_power_mode(ipcHndl, SC_R_VPU, &rv);
+ if (sciErr != SC_ERR_NONE)
+ {
+ dev_err(vpu_dev, "--- sc_pm_get_resource_power_mode(SC_R_VPU) SCI error! (%d)\n", sciErr);
+ rv = -1;
+ }
+
+ return (rv);
+}
+#endif
+
+static long vpu_power_get(bool on)
+{
+ return 0;
+}
+
+static void vpu_power_up(bool on)
+{
+ int err;
+
+ if (on) {
+ err = setVPUPwr(ipcHndl, SC_PM_PW_MODE_ON);
+ if (err)
+ dev_err(vpu_dev, "failed to power on\n");
+ pm_runtime_get_sync(vpu_dev);
+ /* TODO: before or after clk enable? */
+ clk_set_rate(vpu_clk, 600000000);
+ } else {
+ pm_runtime_put_sync_suspend(vpu_dev);
+ err = setVPUPwr(ipcHndl, SC_PM_PW_MODE_OFF);
+ if (err)
+ dev_err(vpu_dev, "failed to power off\n");
+ }
+}
+
+#define VM_RESERVED 0
+
+/*!
+ * Private function to alloc dma buffer
+ * @return status 0 success.
+ */
+static int vpu_alloc_dma_buffer(struct vpu_mem_desc *mem)
+{
+ mem->cpu_addr = dma_alloc_coherent(vpu_dev, PAGE_ALIGN(mem->size),
+ &mem->phy_addr,
+ GFP_DMA | GFP_KERNEL);
+ dev_dbg(vpu_dev, "[ALLOC] mem alloc cpu_addr = 0x%p\n", mem->cpu_addr);
+ if (mem->cpu_addr == NULL) {
+ dev_err(vpu_dev, "Physical memory allocation error!\n");
+ return -1;
+ }
+ return 0;
+}
+
+/*!
+ * Private function to free dma buffer
+ */
+static void vpu_free_dma_buffer(struct vpu_mem_desc *mem)
+{
+ if (mem->cpu_addr != NULL) {
+ dma_free_coherent(vpu_dev, PAGE_ALIGN(mem->size),
+ mem->cpu_addr, mem->phy_addr);
+ }
+}
+
+/*!
+ * Private function to free buffers
+ * @return status 0 success.
+ */
+static int vpu_free_buffers(void)
+{
+ struct memalloc_record *rec, *n;
+ struct vpu_mem_desc mem;
+
+ list_for_each_entry_safe(rec, n, &head, list) {
+ mem = rec->mem;
+ if (mem.cpu_addr != NULL) {
+ vpu_free_dma_buffer(&mem);
+ dev_dbg(vpu_dev, "[FREE] freed paddr=0x%08llX\n", mem.phy_addr);
+ /* delete from list */
+ list_del(&rec->list);
+ kfree(rec);
+ }
+ }
+
+ return 0;
+}
+
+static inline void vpu_worker_callback(struct work_struct *w)
+{
+ struct vpu_priv *dev = container_of(w, struct vpu_priv,
+ work);
+
+ if (dev->async_queue)
+ kill_fasync(&dev->async_queue, SIGIO, POLL_IN);
+
+ irq_status = 1;
+
+ wake_up_interruptible(&vpu_queue);
+}
+
+#if 0
+/*!
+ * @brief vpu interrupt handler
+ */
+static irqreturn_t vpu_ipi_irq_handler(int irq, void *dev_id)
+{
+ struct vpu_priv *dev = dev_id;
+
+ queue_work(dev->workqueue, &dev->work);
+
+ return IRQ_HANDLED;
+}
+#endif
+
+/*!
+ * @brief vpu fiq handler
+ */
+static irqreturn_t vpu_dec_fiq_handler(int irq, void *dev_id)
+{
+ dev_dbg(vpu_dev, "enter %s\n", __FUNCTION__);
+
+ /* NXP using this bit in pal_int_enable() which is FORCE_EXIT, not hanlded within the ISR routing itself */
+ WRITE_REG(0x100, DEC_MFD_XREG_SLV_BASE + MFD_SIF + MFD_SIF_INTR_STATUS);
+
+ int_handlers[INT_ID_MALONE_LOW](uMvdKernelIrqPin[0][0]);
+
+ return IRQ_HANDLED;
+}
+
+/*!
+ * @brief vpu irq handler
+ */
+static irqreturn_t vpu_dec_irq_handler(int irq, void *dev_id)
+{
+ dev_dbg(vpu_dev, "enter %s\n", __FUNCTION__);
+
+ int_handlers[INT_ID_MALONE_HI](uMvdKernelIrqPin[0][1]);
+
+ return IRQ_HANDLED;
+}
+
+static int vpu_isr_event_qu_init(void)
+{
+ int ret;
+
+ dev_dbg(vpu_dev, "enter %s\n", __FUNCTION__);
+
+ ret = pal_qu_create(ISR_EVENT_QU_SIZE,
+ NULL,
+ &gIsrEventQu);
+
+ return ret;
+}
+
+static int vpu_isr_event_qu_send(DECODER_KERNEL_LIB_ISR_EVENT_DATA *pIsrEventData)
+{
+ int ret;
+ uint_addr ulMsg[4];
+
+ dev_dbg(vpu_dev, "enter %s\n", __FUNCTION__);
+
+ mutex_lock(&vpu_data.lock);
+
+ /* Need to take care of copying over the data */
+ gIsrEventData[uIsrEventQuWrIdx] = *pIsrEventData;
+
+ /* Fill message */
+ ulMsg[0] = (uint_addr)&gIsrEventData[uIsrEventQuWrIdx];
+ ulMsg[1] = 0;
+ ulMsg[2] = 0;
+ ulMsg[3] = 0;
+
+ uIsrEventQuWrIdx++;
+ if (uIsrEventQuWrIdx == ISR_EVENT_QU_SIZE) uIsrEventQuWrIdx = 0;
+
+ ret = pal_qu_send (gIsrEventQu,
+ ulMsg);
+
+ mutex_unlock(&vpu_data.lock);
+
+ dev_dbg(vpu_dev, "leave %s\n", __FUNCTION__);
+ return ret;
+}
+
+static int vpu_isr_event_qu_receive(DECODER_KERNEL_LIB_ISR_EVENT_DATA *pIsrEventData)
+{
+ int ret;
+ uint_addr uMsg[4];
+
+ dev_dbg(vpu_dev, "enter %s\n", __FUNCTION__);
+
+ ret = pal_qu_receive(gIsrEventQu,
+ 1000,
+ uMsg);
+
+ if (ret == MEDIAIP_FW_STATUS_OK)
+ *pIsrEventData = *(DECODER_KERNEL_LIB_ISR_EVENT_DATA *)uMsg[0];
+
+ dev_dbg(vpu_dev, "leave %s\n", __FUNCTION__);
+ return ret;
+}
+
+static int vpu_isr_event_qu_uninit(void)
+{
+ int ret;
+
+ dev_dbg(vpu_dev, "enter %s\n", __FUNCTION__);
+
+ ret = pal_qu_destroy(gIsrEventQu);
+
+ return ret;
+}
+
+static void vpu_isr_event_callback(DECODER_KERNEL_LIB_ISR_EVENT_DATA *ptEventData)
+{
+ int err;
+
+ dev_dbg(vpu_dev, "enter %s\n", __FUNCTION__);
+
+ err = vpu_isr_event_qu_send(ptEventData);
+ if (err)
+ dev_err(vpu_dev, "failed to send isr event\n");
+
+ dev_dbg(vpu_dev, "leave %s\n", __FUNCTION__);
+}
+
+static void vpu_set_kernel_cfg(pDECODERLIB_KERNEL_CFG ptKernelCfg)
+{
+ ptKernelCfg->uNumMalones = 1;
+
+ ptKernelCfg->uMaloneBaseAddr[0] = (uint_addr)(vpu_base + 0x180000);
+ ptKernelCfg->uMaloneHifOffset[0] = 0x1C000;
+
+ /* Pass Decoder a PAL index, not an actual GIC position */
+ /* The PAL will take care of the rest */
+ ptKernelCfg->uMaloneIrqPin[0][0x0] = PAL_IRQ_MALONE0_LOW;
+ ptKernelCfg->uMaloneIrqPin[0][0x1] = PAL_IRQ_MALONE0_HI;
+
+ ptKernelCfg->uDPVBaseAddr = 0;
+ ptKernelCfg->uDPVIrqPin = 0;
+}
+
+static void vpu_prepare(void)
+{
+ dev_dbg(vpu_dev, "enter %s\n", __FUNCTION__);
+
+ WRITE_REG(0x1, SCB_XREG_SLV_BASE + SCB_SCB_BLK_CTRL + SCB_BLK_CTRL_SCB_CLK_ENABLE_SET);
+ WRITE_REG(0xffffffff, SCB_XREG_SLV_BASE + SCB_SCB_BLK_CTRL + SCB_BLK_CTRL_XMEM_RESET_SET);
+
+ WRITE_REG(0xE, SCB_XREG_SLV_BASE + SCB_SCB_BLK_CTRL + SCB_BLK_CTRL_SCB_CLK_ENABLE_SET);
+ WRITE_REG(0x7, SCB_XREG_SLV_BASE + SCB_SCB_BLK_CTRL + SCB_BLK_CTRL_CACHE_RESET_SET);
+
+ WRITE_REG(0x1f, DEC_MFD_XREG_SLV_BASE + MFD_BLK_CTRL + MFD_BLK_CTRL_MFD_SYS_CLOCK_ENABLE_SET);
+ WRITE_REG(0xffffffff, DEC_MFD_XREG_SLV_BASE + MFD_BLK_CTRL + MFD_BLK_CTRL_MFD_SYS_RESET_SET);
+
+ WRITE_REG(0x102, XMEM_CONTROL);
+}
+
+static void vpu_unprepare(void)
+{
+ dev_dbg(vpu_dev, "enter %s\n", __FUNCTION__);
+
+ WRITE_REG(0x7, SCB_XREG_SLV_BASE + SCB_SCB_BLK_CTRL + SCB_BLK_CTRL_CACHE_RESET_CLR);
+ WRITE_REG(0xffffffff, DEC_MFD_XREG_SLV_BASE + MFD_BLK_CTRL + MFD_BLK_CTRL_MFD_SYS_RESET_CLR);
+}
+
+/*!
+ * @brief open function for vpu file operation
+ *
+ * @return 0 on success or negative error code on error
+ */
+static int vpu_open(struct inode *inode, struct file *filp)
+{
+ u32 mu_id;
+ int err;
+
+ mutex_lock(&vpu_data.lock);
+
+ if (open_count++ == 0) {
+ err = sc_ipc_getMuID(&mu_id);;
+ if(err != SC_ERR_NONE)
+ {
+ dev_err(vpu_dev, "--- sc_ipc_getMuID() cannot obtain mu id SCI error! (%d)\n", err);
+ return -EFAULT;
+ }
+
+ err = sc_ipc_open(&ipcHndl, mu_id);
+ if(err != SC_ERR_NONE)
+ {
+ dev_err(vpu_dev, "--- sc_ipc_getMuID() cannot open MU channel to SCU error! (%d)\n", err);
+ return -EFAULT;
+ }
+ vpu_power_up(true);
+ clk_prepare_enable(vpu_clk);
+ vpu_prepare();
+ err = vpu_isr_event_qu_init();
+ if(err)
+ {
+ dev_err(vpu_dev, "failed to init isr event qu\n");
+ return -EFAULT;
+ }
+ vpu_set_kernel_cfg(&gtKernelCfg);
+ decoder_kernel_lib_init(&gtKernelCfg);
+ decoder_kernel_lib_register_isr_callback(0, &vpu_isr_event_callback);
+
+#if 0
+ WRITE_REG(0x1000, DEC_MFD_XREG_SLV_BASE + MFD_HIF + 0x014);
+ WRITE_REG(0x20, DEC_MFD_XREG_SLV_BASE + MFD_HIF + 0x01C);
+ WRITE_REG(0x1000, DEC_MFD_XREG_SLV_BASE + MFD_SIF + MFD_SIF_CTRL_STATUS);
+ pal_int_set(PAL_IRQ_MALONE0_LOW);
+#endif
+ } else {
+ dev_err(vpu_dev, "open more than once is forbidden now\n");
+ }
+
+ filp->private_data = (void *)(&vpu_data);
+
+ mutex_unlock(&vpu_data.lock);
+
+ return 0;
+}
+
+/*!
+ * @brief IO ctrl function for vpu file operation
+ * @param cmd IO ctrl command
+ * @return 0 on success or negative error code on error
+ */
+
+#ifdef VPU_KERNEL_DBG_ISR
+int guDbgIsrArray[1024][3] ;
+int guDbgIsrArrayWrtIdx = 0 ;
+#endif
+
+static long vpu_ioctl(struct file *filp, u_int cmd,
+ u_long arg)
+{
+ int ret = 0;
+
+ switch (cmd) {
+ case VPU_IOC_PHYMEM_ALLOC:
+ {
+ struct memalloc_record *rec;
+
+ rec = kzalloc(sizeof(*rec), GFP_KERNEL);
+ if (!rec)
+ return -ENOMEM;
+
+ ret = copy_from_user(&(rec->mem),
+ (struct vpu_mem_desc *)arg,
+ sizeof(struct vpu_mem_desc));
+ if (ret) {
+ kfree(rec);
+ return -EFAULT;
+ }
+
+ dev_dbg(vpu_dev, "[ALLOC] mem alloc size = 0x%x\n",
+ rec->mem.size);
+
+ ret = vpu_alloc_dma_buffer(&(rec->mem));
+ if (ret == -1) {
+ kfree(rec);
+ dev_err(vpu_dev,
+ "Physical memory allocation error!\n");
+ break;
+ }
+ ret = copy_to_user((void __user *)arg, &(rec->mem),
+ sizeof(struct vpu_mem_desc));
+ if (ret) {
+ kfree(rec);
+ ret = -EFAULT;
+ break;
+ }
+
+ mutex_lock(&vpu_data.lock);
+ list_add(&rec->list, &head);
+ mutex_unlock(&vpu_data.lock);
+
+ break;
+ }
+ case VPU_IOC_PHYMEM_FREE:
+ {
+ struct memalloc_record *rec, *n;
+ struct vpu_mem_desc vpu_mem;
+
+ ret = copy_from_user(&vpu_mem,
+ (struct vpu_mem_desc *)arg,
+ sizeof(struct vpu_mem_desc));
+ if (ret)
+ return -EACCES;
+
+ dev_dbg(vpu_dev, "[FREE] mem freed cpu_addr = 0x%p\n",
+ vpu_mem.cpu_addr);
+ if (vpu_mem.cpu_addr != NULL)
+ vpu_free_dma_buffer(&vpu_mem);
+
+ mutex_lock(&vpu_data.lock);
+ list_for_each_entry_safe(rec, n, &head, list) {
+ if (rec->mem.cpu_addr == vpu_mem.cpu_addr) {
+ /* delete from list */
+ list_del(&rec->list);
+ kfree(rec);
+ break;
+ }
+ }
+ mutex_unlock(&vpu_data.lock);
+
+ break;
+ }
+ case VPU_IOC_WAIT4INT:
+ {
+ DECODER_KERNEL_LIB_ISR_EVENT_DATA IsrEventData;
+
+ ret = vpu_isr_event_qu_receive(&IsrEventData);
+ if (ret)
+ {
+ dev_info(vpu_dev, "no isr event\n");
+ ret = -EFAULT;
+ break;
+ }
+#ifdef VPU_KERNEL_DBG_ISR
+ else
+ {
+ dev_dbg(vpu_dev, "isr events= %x %x %x\n", IsrEventData.uIrqStatus[0],IsrEventData.uIrqStatus[1], IsrEventData.uIrqStatus[2]);
+ }
+
+ guDbgIsrArray[guDbgIsrArrayWrtIdx][0] = IsrEventData.uIrqStatus[0];
+ guDbgIsrArray[guDbgIsrArrayWrtIdx][1] = IsrEventData.uIrqStatus[1];
+ guDbgIsrArray[guDbgIsrArrayWrtIdx][2] = IsrEventData.uIrqStatus[2];
+ guDbgIsrArrayWrtIdx++;
+ guDbgIsrArrayWrtIdx = (guDbgIsrArrayWrtIdx==1024) ? 0 : guDbgIsrArrayWrtIdx;
+#endif
+
+ ret = copy_to_user((void __user *)arg, &IsrEventData, sizeof(DECODER_KERNEL_LIB_ISR_EVENT_DATA));
+
+ if (ret)
+ ret = -EFAULT;
+#if 0
+ u_long timeout = (u_long) arg;
+ if (!wait_event_interruptible_timeout
+ (vpu_queue, irq_status != 0,
+ msecs_to_jiffies(timeout))) {
+ dev_warn(vpu_dev, "VPU blocking: timeout.\n");
+ ret = -ETIME;
+ } else if (signal_pending(current)) {
+ dev_warn(vpu_dev, "Other interrupt received.\n");
+ ret = -ERESTARTSYS;
+ } else
+ irq_status = 0;
+#endif
+ break;
+ }
+ case VPU_IOC_CLKGATE_SETTING:
+ {
+ u32 clkgate_en;
+
+ if (get_user(clkgate_en, (u32 __user *) arg))
+ return -EFAULT;
+
+ if (clkgate_en) {
+ clk_prepare_enable(vpu_clk);
+ atomic_inc(&clk_cnt_from_ioc);
+ } else {
+ clk_disable_unprepare(vpu_clk);
+ atomic_dec(&clk_cnt_from_ioc);
+ }
+
+ break;
+ }
+ case VPU_IOC_GET_SHARE_MEM:
+ {
+ mutex_lock(&vpu_data.lock);
+ if (share_mem.cpu_addr != NULL) {
+ ret = copy_to_user((void __user *)arg,
+ &share_mem,
+ sizeof(struct vpu_mem_desc));
+ mutex_unlock(&vpu_data.lock);
+ break;
+ } else {
+ if (copy_from_user(&share_mem,
+ (struct vpu_mem_desc *)arg,
+ sizeof(struct vpu_mem_desc))) {
+ mutex_unlock(&vpu_data.lock);
+ return -EFAULT;
+ }
+ if (vpu_alloc_dma_buffer(&share_mem) == -1)
+ ret = -EFAULT;
+ else {
+ if (copy_to_user((void __user *)arg,
+ &share_mem,
+ sizeof(struct
+ vpu_mem_desc)))
+ ret = -EFAULT;
+ }
+ }
+ mutex_unlock(&vpu_data.lock);
+ break;
+ }
+ case VPU_IOC_REQ_VSHARE_MEM:
+ {
+ mutex_lock(&vpu_data.lock);
+ if (vshare_mem.cpu_addr != NULL) {
+ ret = copy_to_user((void __user *)arg,
+ &vshare_mem,
+ sizeof(struct vpu_mem_desc));
+ mutex_unlock(&vpu_data.lock);
+ break;
+ } else {
+ if (copy_from_user(&vshare_mem,
+ (struct vpu_mem_desc *)arg,
+ sizeof(struct
+ vpu_mem_desc))) {
+ mutex_unlock(&vpu_data.lock);
+ return -EFAULT;
+ }
+ /* vmalloc shared memory if not allocated */
+ if (!vshare_mem.cpu_addr)
+ vshare_mem.cpu_addr =
+ vmalloc_user(vshare_mem.size);
+ if (copy_to_user
+ ((void __user *)arg, &vshare_mem,
+ sizeof(struct vpu_mem_desc)))
+ ret = -EFAULT;
+ }
+ mutex_unlock(&vpu_data.lock);
+ break;
+ }
+ case VPU_IOC_SYS_SW_RESET:
+ {
+ vpu_reset();
+ break;
+ }
+ case VPU_IOC_LOCK_DEV:
+ {
+ u32 lock_en;
+
+ if (get_user(lock_en, (u32 __user *) arg))
+ return -EFAULT;
+
+ if (lock_en)
+ mutex_lock(&vpu_data.lock);
+ else
+ mutex_unlock(&vpu_data.lock);
+
+ break;
+ }
+ default:
+ {
+ dev_err(vpu_dev, "No such IOCTL, cmd is %d\n", cmd);
+ ret = -EINVAL;
+ break;
+ }
+ }
+ return ret;
+}
+
+/*!
+ * @brief Release function for vpu file operation
+ * @return 0 on success or negative error code on error
+ */
+static int vpu_release(struct inode *inode, struct file *filp)
+{
+ int i;
+ unsigned long timeout;
+ int err;
+
+ mutex_lock(&vpu_data.lock);
+
+ if (open_count > 0 && !(--open_count)) {
+
+ /* Wait for vpu go to idle state */
+ clk_prepare_enable(vpu_clk);
+ timeout = jiffies + HZ;
+ /* checking busy */
+ while (0) {
+ msleep(1);
+ if (time_after(jiffies, timeout)) {
+ dev_warn(vpu_dev, "VPU timeout during release\n");
+ break;
+ }
+ }
+
+ /* Clean up interrupt */
+#if 0
+ cancel_work_sync(&vpu_data.work);
+ flush_workqueue(vpu_data.workqueue);
+ irq_status = 0;
+#endif
+
+ /* reset if busy */
+ if (0) {
+ vpu_reset();
+ }
+ clk_disable_unprepare(vpu_clk);
+
+ vpu_free_buffers();
+
+ /* Free shared memory when vpu device is idle */
+ vpu_free_dma_buffer(&share_mem);
+ share_mem.cpu_addr = NULL;
+ vfree(vshare_mem.cpu_addr);
+ vshare_mem.cpu_addr = NULL;
+
+ vpu_clk_usercount = atomic_read(&clk_cnt_from_ioc);
+ for (i = 0; i < vpu_clk_usercount; i++) {
+ clk_disable_unprepare(vpu_clk);
+ atomic_dec(&clk_cnt_from_ioc);
+ }
+
+ err = vpu_isr_event_qu_uninit();
+ if (err)
+ dev_err(vpu_dev, "failed to uninit isr event qu\n");
+ vpu_unprepare();
+ clk_disable_unprepare(vpu_clk);
+ vpu_power_up(false);
+ sc_ipc_close(ipcHndl);
+ }
+ mutex_unlock(&vpu_data.lock);
+
+ return 0;
+}
+
+/*!
+ * @brief fasync function for vpu file operation
+ * @return 0 on success or negative error code on error
+ */
+static int vpu_fasync(int fd, struct file *filp, int mode)
+{
+ struct vpu_priv *dev = (struct vpu_priv *)filp->private_data;
+ return fasync_helper(fd, filp, mode, &dev->async_queue);
+}
+
+/*!
+ * @brief memory map function of harware registers for vpu file operation
+ * @return 0 on success or negative error code on error
+ */
+static int vpu_map_hwregs(struct file *fp, struct vm_area_struct *vm)
+{
+ unsigned long pfn;
+
+ vm->vm_flags |= VM_IO | VM_RESERVED;
+ /*
+ * Since vpu registers have been mapped with ioremap() at probe
+ * which L_PTE_XN is 1, and the same physical address must be
+ * mapped multiple times with same type, so set L_PTE_XN to 1 here.
+ * Otherwise, there may be unexpected result in video codec.
+ */
+ vm->vm_page_prot = pgprot_noncached(vm->vm_page_prot);
+ pfn = phy_vpu_base_addr >> PAGE_SHIFT;
+ dev_dbg(vpu_dev, "size=0x%x, page no.=0x%x\n",
+ (int)(vm->vm_end - vm->vm_start), (int)pfn);
+ return remap_pfn_range(vm, vm->vm_start, pfn, vm->vm_end - vm->vm_start,
+ vm->vm_page_prot) ? -EAGAIN : 0;
+}
+
+/*!
+ * @brief memory map function of memory for vpu file operation
+ * @return 0 on success or negative error code on error
+ */
+static int vpu_map_dma_mem(struct file *fp, struct vm_area_struct *vm)
+{
+ int request_size;
+ request_size = vm->vm_end - vm->vm_start;
+
+ dev_dbg(vpu_dev, "start=0x%x, pgoff=0x%x, size=0x%x\n",
+ (unsigned int)(vm->vm_start), (unsigned int)(vm->vm_pgoff),
+ request_size);
+
+ vm->vm_flags |= VM_IO | VM_RESERVED;
+ vm->vm_page_prot = pgprot_writecombine(vm->vm_page_prot);
+
+ return remap_pfn_range(vm, vm->vm_start, vm->vm_pgoff,
+ request_size, vm->vm_page_prot) ? -EAGAIN : 0;
+
+}
+
+/* !
+ * @brief memory map function of vmalloced share memory
+ * @return 0 on success or negative error code on error
+ */
+static int vpu_map_vshare_mem(struct file *fp, struct vm_area_struct *vm)
+{
+ int ret = -EINVAL;
+
+ ret = remap_vmalloc_range(vm, (void *)(vm->vm_pgoff << PAGE_SHIFT), 0);
+ vm->vm_flags |= VM_IO;
+
+ return ret;
+}
+/*!
+ * @brief memory map interface for vpu file operation
+ * @return 0 on success or negative error code on error
+ */
+static int vpu_mmap(struct file *fp, struct vm_area_struct *vm)
+{
+ u64 offset;
+
+ offset = (u64)((s64)vshare_mem.cpu_addr >> PAGE_SHIFT);
+ if (vm->vm_pgoff && (vm->vm_pgoff == offset || vm->vm_pgoff == (offset & 0xFFFFFFFF))){
+ if(vm->vm_pgoff == (offset & 0xFFFFFFFF))
+ vm->vm_pgoff = offset;
+ return vpu_map_vshare_mem(fp, vm);
+ }else if (vm->vm_pgoff)
+ return vpu_map_dma_mem(fp, vm);
+ else
+ return vpu_map_hwregs(fp, vm);
+}
+
+#ifdef CONFIG_COMPAT
+struct vpu_mem_desc_32 {
+ u32 size;
+ u32 phy_addr;
+ u32 cpu_addr; /* cpu address to free the dma mem */
+ u32 virt_uaddr; /* virtual user space address */
+};
+static int get_vpu_mem_desc_32(struct vpu_mem_desc *kp, struct vpu_mem_desc_32 __user *up)
+{
+ u32 tmp_phy;
+ u32 tmp_cpu;
+ u32 tmp_virt;
+
+ if (!access_ok(VERIFY_READ, up, sizeof(struct vpu_mem_desc_32)) ||
+ get_user(kp->size, &up->size) ||
+ get_user(tmp_phy, &up->phy_addr) ||
+ get_user(tmp_cpu, &up->cpu_addr) ||
+ get_user(tmp_virt, &up->virt_uaddr)) {
+ return -EFAULT;
+ }
+ kp->phy_addr = (__force dma_addr_t)compat_ptr(tmp_phy);
+ kp->cpu_addr = (__force void *)compat_ptr(tmp_cpu);
+ kp->virt_uaddr = (__force u64)compat_ptr(tmp_virt);
+
+ return 0;
+}
+
+static int put_vpu_mem_desc_32(struct vpu_mem_desc *kp, struct vpu_mem_desc_32 __user *up)
+{
+ u32 tmp_phy = (u32)((unsigned long)kp->phy_addr);
+ u32 tmp_cpu = (u32)((unsigned long)kp->cpu_addr);
+ u32 tmp_virt = (u32)((unsigned long)kp->virt_uaddr);
+
+ if (!access_ok(VERIFY_WRITE, up, sizeof(struct vpu_mem_desc_32)) ||
+ put_user(kp->size, &up->size) ||
+ put_user(tmp_phy, &up->phy_addr) ||
+ put_user(tmp_cpu, &up->cpu_addr) ||
+ put_user(tmp_virt, &up->virt_uaddr)) {
+ return -EFAULT;
+ }
+ return 0;
+}
+struct ISR_EVENT_DATA
+{
+ u_int32 uMalIdx;
+ u_int32 uIrqStatus[0x3];
+};
+struct ISR_EVENT_DATA_32
+{
+ u_int32 uMalIdx;
+ u_int32 uIrqStatus[0x3];
+};
+
+static int get_isr_event_32(struct ISR_EVENT_DATA *kp, struct ISR_EVENT_DATA_32 __user *up)
+{
+ if (!access_ok(VERIFY_READ, up, sizeof(struct ISR_EVENT_DATA_32)) ||
+ get_user(kp->uMalIdx, &up->uMalIdx) ||
+ get_user(kp->uIrqStatus[0], &up->uIrqStatus[0]) ||
+ get_user(kp->uIrqStatus[1], &up->uIrqStatus[1]) ||
+ get_user(kp->uIrqStatus[2], &up->uIrqStatus[2])) {
+ return -EFAULT;
+ }
+
+ return 0;
+}
+
+static int put_isr_event_32(struct ISR_EVENT_DATA *kp, struct ISR_EVENT_DATA_32 __user *up)
+{
+ if (!access_ok(VERIFY_WRITE, up, sizeof(struct ISR_EVENT_DATA_32)) ||
+ put_user(kp->uMalIdx, &up->uMalIdx) ||
+ put_user(kp->uIrqStatus[0], &up->uIrqStatus[0]) ||
+ put_user(kp->uIrqStatus[1], &up->uIrqStatus[1]) ||
+ put_user(kp->uIrqStatus[2], &up->uIrqStatus[2])) {
+ return -EFAULT;
+ }
+ return 0;
+}
+static long vpu_ioctl32(struct file *filp, unsigned int cmd, unsigned long arg)
+{
+#define VPU_IOCTL32(err, filp, cmd, arg) { \
+ mm_segment_t old_fs = get_fs(); \
+ set_fs(KERNEL_DS); \
+ err = vpu_ioctl(filp, cmd, arg); \
+ if (err) \
+ return err; \
+ set_fs(old_fs); \
+ }
+
+ union {
+ struct vpu_mem_desc kcore;
+ struct ISR_EVENT_DATA kevent;
+ unsigned long kux;
+ unsigned int kui;
+ } karg;
+ void __user *up = compat_ptr(arg);
+ long err = 0;
+
+ switch (_IOC_NR(cmd)) {
+ case _IOC_NR(VPU_IOC_CLKGATE_SETTING):
+ case _IOC_NR(VPU_IOC_LOCK_DEV):
+ err = get_user(karg.kui, (s32 __user *)up);
+ if (err)
+ return err;
+ VPU_IOCTL32(err, filp, cmd, (unsigned long)&karg);
+ err = put_user(((s32)karg.kui), (s32 __user *)up);
+ break;
+ case _IOC_NR(VPU_IOC_PHYMEM_ALLOC):
+ case _IOC_NR(VPU_IOC_PHYMEM_FREE):
+ case _IOC_NR(VPU_IOC_GET_SHARE_MEM):
+ case _IOC_NR(VPU_IOC_REQ_VSHARE_MEM):
+ err = get_vpu_mem_desc_32(&karg.kcore, up);
+ if (err)
+ return err;
+ VPU_IOCTL32(err, filp, cmd, (unsigned long)&karg);
+ err = put_vpu_mem_desc_32(&karg.kcore, up);
+ break;
+ case _IOC_NR(VPU_IOC_WAIT4INT):
+ err = get_isr_event_32(&karg.kevent, up);
+ if (err)
+ return err;
+ VPU_IOCTL32(err, filp, cmd, (unsigned long)&karg);
+ err = put_isr_event_32(&karg.kevent, up);
+ break;
+ default:
+ err = vpu_ioctl(filp, cmd, (unsigned long)up);
+ break;
+ }
+
+ return err;
+}
+
+#endif //ifdef CONFIG_COMPAT
+
+const struct file_operations vpu_fops = {
+ .owner = THIS_MODULE,
+ .open = vpu_open,
+ .unlocked_ioctl = vpu_ioctl,
+ .release = vpu_release,
+ .fasync = vpu_fasync,
+ .mmap = vpu_mmap,
+#ifdef CONFIG_COMPAT
+ .compat_ioctl = vpu_ioctl32,
+#endif
+};
+
+/*!
+ * This function is called by the driver framework to initialize the vpu device.
+ * @param dev The device structure for the vpu passed in by the framework.
+ * @return 0 on success or negative error code on error
+ */
+static int vpu_dev_probe(struct platform_device *pdev)
+{
+ int err = 0;
+ struct device *temp_class;
+ struct resource *res;
+
+ vpu_dev = &pdev->dev;
+
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "vpu_regs");
+ if (!res) {
+ dev_err(vpu_dev, "vpu: unable to get vpu base addr\n");
+ return -ENODEV;
+ }
+ phy_vpu_base_addr = res->start;
+ vpu_base = devm_ioremap_resource(vpu_dev, res);
+
+ vpu_major = register_chrdev(vpu_major, "mxc_vpu_malone", &vpu_fops);
+ if (vpu_major < 0) {
+ dev_err(vpu_dev, "vpu: unable to get a major for VPU\n");
+ err = -EBUSY;
+ goto error;
+ }
+
+ vpu_class = class_create(THIS_MODULE, "mxc_vpu_malone");
+ if (IS_ERR(vpu_class)) {
+ err = PTR_ERR(vpu_class);
+ goto err_out_chrdev;
+ }
+
+ temp_class = device_create(vpu_class, NULL, MKDEV(vpu_major, 0),
+ NULL, "mxc_vpu_malone");
+ if (IS_ERR(temp_class)) {
+ err = PTR_ERR(temp_class);
+ goto err_out_class;
+ }
+
+ vpu_clk = clk_get(&pdev->dev, "vpu_clk");
+ if (IS_ERR(vpu_clk)) {
+ err = -ENOENT;
+ goto err_out_class;
+ }
+
+ vpu_dec_irq = platform_get_irq_byname(pdev, "dec_irq");
+ if (vpu_dec_irq < 0) {
+ dev_err(vpu_dev, "dec_irq is not found\n");
+ err = -ENXIO;
+ goto err_out_class;
+ }
+ err = devm_request_threaded_irq(vpu_dev, vpu_dec_irq, vpu_dec_irq_handler,
+ NULL, 0, "VPU DEC IRQ", (void*)(&vpu_data));
+ if (err < 0) {
+ dev_err(vpu_dev, "failed to request irq for dec_irq\n");
+ goto err_out_class;
+ }
+
+ vpu_dec_fiq = platform_get_irq_byname(pdev, "dec_fiq");
+ if (vpu_dec_fiq < 0) {
+ dev_err(vpu_dev, "dec_fiq is not found\n");
+ err = -ENXIO;
+ goto err_out_class;
+ }
+ err = devm_request_threaded_irq(vpu_dev, vpu_dec_fiq, vpu_dec_fiq_handler,
+ NULL, 0, "VPU DEC FIQ", (void*)(&vpu_data));
+ if (err < 0)
+ dev_err(vpu_dev, "failed to request irq for dec_fiq\n");
+
+ if (vpu_power_get(true)) {
+ dev_err(vpu_dev, "failed to get vpu power\n");
+ goto err_out_class;
+ }
+
+ pm_runtime_enable(&pdev->dev);
+
+ vpu_data.workqueue = create_workqueue("vpu_wq");
+ INIT_WORK(&vpu_data.work, vpu_worker_callback);
+ mutex_init(&vpu_data.lock);
+ dev_info(vpu_dev, "VPU initialized\n");
+
+ goto out;
+
+err_out_class:
+ device_destroy(vpu_class, MKDEV(vpu_major, 0));
+ class_destroy(vpu_class);
+err_out_chrdev:
+ unregister_chrdev(vpu_major, "mxc_vpu_malone");
+error:
+ devm_iounmap(vpu_dev, vpu_base);
+out:
+ return err;
+}
+
+static int vpu_dev_remove(struct platform_device *pdev)
+{
+ pm_runtime_disable(&pdev->dev);
+ devm_free_irq(&pdev->dev, vpu_dec_irq, &vpu_data);
+ devm_free_irq(&pdev->dev, vpu_dec_fiq, &vpu_data);
+ cancel_work_sync(&vpu_data.work);
+ flush_workqueue(vpu_data.workqueue);
+ destroy_workqueue(vpu_data.workqueue);
+
+ devm_iounmap(&pdev->dev, vpu_base);
+
+ vpu_power_get(false);
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int vpu_suspend(struct device *dev)
+{
+ int i;
+ unsigned long timeout;
+
+ mutex_lock(&vpu_data.lock);
+ if (open_count != 0) {
+ /* Wait for vpu go to idle state, suspect vpu cannot be changed
+ to idle state after about 1 sec */
+ timeout = jiffies + HZ;
+ clk_prepare_enable(vpu_clk);
+ /* checking busy */
+ while (0) {
+ msleep(1);
+ if (time_after(jiffies, timeout)) {
+ clk_disable_unprepare(vpu_clk);
+ mutex_unlock(&vpu_data.lock);
+ return -EAGAIN;
+ }
+ }
+ clk_disable_unprepare(vpu_clk);
+
+ /* Make sure clock is disabled before suspend */
+ vpu_clk_usercount = atomic_read(&clk_cnt_from_ioc);
+ for (i = 0; i < vpu_clk_usercount; i++) {
+ clk_disable_unprepare(vpu_clk);
+ }
+
+ clk_prepare_enable(vpu_clk);
+ /* Save registers */
+ clk_disable_unprepare(vpu_clk);
+
+ /* If VPU is working before suspend, disable
+ * regulator to make usecount right. */
+ vpu_power_up(false);
+ }
+
+ mutex_unlock(&vpu_data.lock);
+ return 0;
+}
+
+static int vpu_resume(struct device *dev)
+{
+ int i;
+
+ mutex_lock(&vpu_data.lock);
+ if (open_count != 0) {
+ /* If VPU is working before suspend, enable
+ * regulator to make usecount right. */
+ vpu_power_up(true);
+
+ clk_prepare_enable(vpu_clk);
+
+ /* Restore registers */
+
+ clk_disable_unprepare(vpu_clk);
+
+ /* Recover vpu clock */
+ for (i = 0; i < vpu_clk_usercount; i++) {
+ clk_prepare_enable(vpu_clk);
+ }
+ }
+
+ mutex_unlock(&vpu_data.lock);
+ return 0;
+}
+
+static int vpu_runtime_suspend(struct device *dev)
+{
+ release_bus_freq(BUS_FREQ_HIGH);
+ return 0;
+}
+
+static int vpu_runtime_resume(struct device *dev)
+{
+ request_bus_freq(BUS_FREQ_HIGH);
+ return 0;
+}
+
+static const struct dev_pm_ops vpu_pm_ops = {
+ SET_RUNTIME_PM_OPS(vpu_runtime_suspend, vpu_runtime_resume, NULL)
+ SET_SYSTEM_SLEEP_PM_OPS(vpu_suspend, vpu_resume)
+};
+
+#else
+#define vpu_suspend NULL
+#define vpu_resume NULL
+#endif /* !CONFIG_PM */
+
+static const struct of_device_id vpu_of_match[] = {
+ { .compatible = "nxp,imx8qm-vpu", },
+ { .compatible = "nxp,imx8qxp-vpu", },
+ {/* sentinel */}
+};
+MODULE_DEVICE_TABLE(of, vpu_of_match);
+
+/*! Driver definition
+ *
+ */
+static struct platform_driver mxcvpu_driver = {
+ .driver = {
+ .name = "mxc_vpu_malone",
+ .of_match_table = vpu_of_match,
+#ifdef CONFIG_PM
+ .pm = &vpu_pm_ops,
+#endif
+ },
+ .probe = vpu_dev_probe,
+ .remove = vpu_dev_remove,
+};
+
+static int __init vpu_init(void)
+{
+ int ret = platform_driver_register(&mxcvpu_driver);
+
+ init_waitqueue_head(&vpu_queue);
+
+ return ret;
+}
+
+static void __exit vpu_exit(void)
+{
+ if (vpu_major > 0) {
+ device_destroy(vpu_class, MKDEV(vpu_major, 0));
+ class_destroy(vpu_class);
+ unregister_chrdev(vpu_major, "mxc_vpu_malone");
+ vpu_major = 0;
+ }
+
+ /* reset VPU state */
+ vpu_power_up(true);
+ clk_prepare_enable(vpu_clk);
+ vpu_reset();
+ clk_disable_unprepare(vpu_clk);
+ vpu_power_up(false);
+
+ clk_put(vpu_clk);
+
+ platform_driver_unregister(&mxcvpu_driver);
+ return;
+}
+
+MODULE_AUTHOR("NXP");
+MODULE_DESCRIPTION("Linux VPU driver for NXP i.MX/MXC");
+MODULE_LICENSE("GPL");
+
+module_init(vpu_init);
+module_exit(vpu_exit);
diff --git a/drivers/mxc/vpu_malone/Kconfig b/drivers/mxc/vpu_malone/Kconfig
new file mode 100644
index 000000000000..39bca920f7a4
--- /dev/null
+++ b/drivers/mxc/vpu_malone/Kconfig
@@ -0,0 +1,20 @@
+#
+# Codec configuration
+#
+
+menu "MXC VPU(Video Processing Unit) MALONE DECODER support"
+
+config MXC_VPU_MALONE
+ tristate "Support for MXC VPU(Video Processing Unit) MALONE B0 DECODER"
+ default y
+ ---help---
+ The VPU codec device provides codec function for H.265 H.264 MPEG2 MPEG4 etc.
+
+config MXC_VPU_MALONE_DEBUG
+ bool "MXC VPU MALONE debugging"
+ depends on MXC_VPU_MALONE != n
+ help
+ This is an option for the developers; most people should
+ say N here. This enables MXC VPU driver debugging.
+
+endmenu
diff --git a/drivers/mxc/vpu_malone/Makefile b/drivers/mxc/vpu_malone/Makefile
new file mode 100644
index 000000000000..6256d7b2d026
--- /dev/null
+++ b/drivers/mxc/vpu_malone/Makefile
@@ -0,0 +1,16 @@
+##
+## Makefile for the VPU and M0 driver
+##
+DEFINES += -D REBOOT=1 \
+ -D BOOT_ARCH=1
+
+EXTRA_CFLAGS += $(DEFINES)
+
+obj-$(CONFIG_MXC_VPU_MALONE) = vpu-malone.o
+vpu-malone-objs = vpu_b0.o \
+ vpu_rpc.o \
+ insert_startcode.o \
+ vpu_debug_log.o
+
+clean:
+ rm -rf $(vpu-malone-objs)
diff --git a/drivers/mxc/vpu_malone/insert_startcode.c b/drivers/mxc/vpu_malone/insert_startcode.c
new file mode 100644
index 000000000000..dbd8a893ad6c
--- /dev/null
+++ b/drivers/mxc/vpu_malone/insert_startcode.c
@@ -0,0 +1,546 @@
+/*
+ * Copyright 2018 NXP
+ */
+
+/*
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/*!
+ * @file insert_startcode.c
+ *
+ * copyright here may be changed later
+ *
+ *
+ */
+#include "insert_startcode.h"
+// Global VC1 ID and version
+u_int32 uVC1CodecID = 0x10; // Simple = 0x10, Main = 0x11
+u_int32 uVC1VersionID = 1;
+
+static int insert_RCV_seqhdr(unsigned char *pHeader, u_int32 *pHeaderLen, unsigned char *src,
+ u_int32 nFrameSize, u_int32 nWidth, u_int32 nHeight, int *pNoError)
+{
+ int nHeaderLen;
+
+ unsigned int nValue;
+ unsigned int HdrExtDataLen;
+ int i = 0;
+ int profile;
+
+ nHeaderLen = RCV_HEADER_LEN;
+
+ //Number of Frames, Header Extension Bit, Codec Version
+ nValue = RCV_NUM_FRAMES | RCV_SET_HDR_EXT | RCV_CODEC_VERSION;
+ pHeader[i++] = (unsigned char)nValue;
+ pHeader[i++] = (unsigned char)(nValue >> 8);
+ pHeader[i++] = (unsigned char)(nValue >> 16);
+#if 0 //1 ???
+ pHeader[i++] = 0xC5;
+#else
+ pHeader[i++] = (unsigned char)(nValue >> 24);
+#endif
+
+ //Header Extension Size
+ //ASF Parser gives 5 bytes whereas the VPU expects only 4 bytes, so limiting it
+ HdrExtDataLen = 4;
+ pHeader[i++] = (unsigned char)HdrExtDataLen;
+ pHeader[i++] = (unsigned char)(HdrExtDataLen >> 8);
+ pHeader[i++] = (unsigned char)(HdrExtDataLen >> 16);
+ pHeader[i++] = (unsigned char)(HdrExtDataLen >> 24);
+
+ profile = (*src)>>4;
+ if ((profile != 0) && (profile != 4) && (profile != 12)) {
+ //it is reasonable to return error immediately since only one sequence header inserted in whole rcv clip
+ *pNoError = 0;
+ }
+ memcpy(pHeader+i, src, HdrExtDataLen);
+ i += HdrExtDataLen;
+
+ //Height
+ pHeader[i++] = (unsigned char)nHeight;
+ pHeader[i++] = (unsigned char)(((nHeight >> 8) & 0xff));
+ pHeader[i++] = (unsigned char)(((nHeight >> 16) & 0xff));
+ pHeader[i++] = (unsigned char)(((nHeight >> 24) & 0xff));
+ //Width
+ pHeader[i++] = (unsigned char)nWidth;
+ pHeader[i++] = (unsigned char)(((nWidth >> 8) & 0xff));
+ pHeader[i++] = (unsigned char)(((nWidth >> 16) & 0xff));
+ pHeader[i++] = (unsigned char)(((nWidth >> 24) & 0xff));
+
+ //Frame Size
+ pHeader[i++] = (unsigned char)nFrameSize;
+ pHeader[i++] = (unsigned char)(nFrameSize >> 8);
+ pHeader[i++] = (unsigned char)(nFrameSize >> 16);
+#if 0 //1 ???
+ pHeader[i++] = (unsigned char)((nFrameSize >> 24));
+#else
+ pHeader[i++] = (unsigned char)((nFrameSize >> 24) | 0x80);
+#endif
+
+ *pHeaderLen = nHeaderLen;
+
+ return 1;
+}
+
+static int insert_RCV_pichdr(unsigned char *pHeader, int *pHeaderLen, unsigned int nInSize)
+{
+ pHeader[0] = (unsigned char)nInSize;
+ pHeader[1] = (unsigned char)(nInSize >> 8);
+ pHeader[2] = (unsigned char)(nInSize >> 16);
+ pHeader[3] = (unsigned char)(nInSize >> 24);
+ *pHeaderLen = 4;
+
+ return 1;
+}
+
+/*
+ * Byte 0-3: Startcode
+ * Byte 4: Payload length bits[23:16]
+ * Byte 5: Payload length bits[15:8]
+ * Byte 6: 0x4e
+ * Byte 7: Payload length bits[7:0]
+ * Byte 8: Codec ID Non-zero
+ * Byte 9: Codec Version ID Non-zero
+ * Byte 10: Picture Width bits[15:8]
+ * Byte 11: Picture Width bits[7:0]
+ * Byte 12: 0x58
+ * Byte 13: Picture Height bits[15:8]
+ * Byte 14: Picture Height bits[7:0]
+ * Byte 15: 0x50
+ */
+
+static void insert_payload_header_vc1(u_int8 *dst, u_int32 uScodeType, u_int32 uPayloadSize, u_int32 uWidth, u_int32 uHeight)
+{
+ // Startcode
+ dst[0] = 0x00;
+ dst[1] = 0x00;
+ dst[2] = 0x01;
+ dst[3] = uScodeType;
+
+ // Length
+ dst[4] = ((uPayloadSize>>16)&0xff);
+ dst[5] = ((uPayloadSize>>8)&0xff);
+ dst[6] = 0x4e;
+ dst[7] = ((uPayloadSize>>0)&0xff);
+
+ // Codec ID and Version
+ dst[8] = uVC1CodecID;
+ dst[9] = uVC1VersionID;
+
+ // Width
+ dst[10] = ((uWidth>>8)&0xff);
+ dst[11] = ((uWidth>>0)&0xff);
+ dst[12] = 0x58;
+
+ // Height
+ dst[13] = ((uHeight>>8)&0xff);
+ dst[14] = ((uHeight>>0)&0xff);
+ dst[15] = 0x50;
+}
+
+static int VC1CreateNALSeqHeader(unsigned char *pHeader, int *pHeaderLen,
+ unsigned char *pCodecPri, int nCodecSize, unsigned int *pData, int nMaxHeader)
+{
+ int nHeaderLen;
+ unsigned char temp[4] = {0x00, 0x00, 0x01, 0x0D};
+
+ nHeaderLen = nCodecSize - 1;
+ if ((4+nHeaderLen) > nMaxHeader) {
+ nHeaderLen = nMaxHeader - 4;
+ vpu_dbg(LVL_ERR, "error: header length %d overrun !!! \r\n", nCodecSize);
+ }
+ memcpy(pHeader, pCodecPri+1, nHeaderLen);
+
+ if (VC1_IS_NOT_NAL(pData[0])) {
+ //insert 0x0000010D at the end of header
+ memcpy(pHeader+nHeaderLen, temp, 4);
+ nHeaderLen += 4;
+ }
+
+ *pHeaderLen = nHeaderLen;
+
+ return 1;
+}
+
+static int VC1CreateNalFrameHeader(unsigned char *pHeader, int *pHeaderLen, unsigned int *pInData)
+{
+ unsigned int VC1Id;
+
+ VC1Id = *pInData;
+ if (VC1_IS_NOT_NAL(VC1Id)) {
+ //need insert header : special ID
+ pHeader[0] = 0x0;
+ pHeader[1] = 0x0;
+ pHeader[2] = 0x01;
+ pHeader[3] = 0x0D;
+ *pHeaderLen = 4;
+ } else {
+ //need not insert header
+ //do nothing
+ *pHeaderLen = 0;
+ }
+
+ return 1;
+}
+
+void vp6_scd_sequence_header(unsigned char *buffer, int pic_width, int pic_height)
+{
+ int Length = 0;
+
+ buffer[0] = 0x00;
+ buffer[1] = 0x00;
+ buffer[2] = 0x01;
+ buffer[3] = 0x31;
+ buffer[4] = (Length+12)>>16;
+ buffer[5] = (Length+12)>>8;
+ buffer[6] = 0x4e;
+ buffer[7] = (Length+12);
+ buffer[8] = 0x36;
+ buffer[9] = 0x1;
+ buffer[10] = pic_width>>8;
+ buffer[11] = pic_width;
+ buffer[12] = 0x58;
+ buffer[13] = pic_height>>8;
+ buffer[14] = pic_height;
+ buffer[15] = 0x50;
+}
+
+void vp6_scd_frame_header(unsigned char *buffer, int pic_width, int pic_height, int Length)
+{
+ buffer[0] = 0x00;
+ buffer[1] = 0x00;
+ buffer[2] = 0x01;
+ buffer[3] = 0x32;
+ buffer[4] = (Length+12)>>16;
+ buffer[5] = (Length+12)>>8;
+ buffer[6] = 0x4e;
+ buffer[7] = (Length+12);
+ buffer[8] = 0x36;
+ buffer[9] = 0x1;
+ buffer[10] = pic_width>>8;
+ buffer[11] = pic_width;
+ buffer[12] = 0x58;
+ buffer[13] = pic_height>>8;
+ buffer[14] = pic_height;
+ buffer[15] = 0x50;
+}
+
+void vp8_ivf_sequence_header(unsigned char *buffer, int pic_width, int pic_height)
+{
+ int Length = 32;
+
+ buffer[0] = 0x44;
+ buffer[1] = 0x4b;
+ buffer[2] = 0x49;
+ buffer[3] = 0x46; //0-3byte signature "DKIF"
+ buffer[4] = 0x00;
+ buffer[5] = 0x00; //4-5byte version 0
+ buffer[6] = Length;
+ buffer[7] = Length >> 8; //length of Header
+ buffer[8] = 0x56;
+ buffer[9] = 0x50;
+ buffer[10] = 0x38;
+ buffer[11] = 0x30; //VP8 fourcc
+ buffer[12] = pic_width;
+ buffer[13] = pic_width >> 8;
+ buffer[14] = pic_height;
+ buffer[15] = pic_height >> 8;
+ buffer[16] = 0xe8;
+ buffer[17] = 0x03;
+ buffer[18] = 0x00;
+ buffer[19] = 0x00; //16-19 frame rate
+ buffer[20] = 0x01;
+ buffer[21] = 0x00;
+ buffer[22] = 0x00;
+ buffer[23] = 0x00; //20-23 time scale
+ buffer[24] = 0xdf;
+ buffer[25] = 0xf9;
+ buffer[26] = 0x09;
+ buffer[27] = 0x00; //24-27 number frames
+ //28-31 unused
+}
+
+void vp8_ivf_frame_header(unsigned char *buffer, u_int32 FrameSize)
+{
+ buffer[0] = FrameSize;
+ buffer[1] = FrameSize >> 8;
+ buffer[2] = FrameSize >> 16;
+ buffer[3] = FrameSize >> 24;
+ //4-11 timestamp
+}
+
+void vp8_scd_sequence_header(unsigned char *buffer, int pic_width, int pic_height)
+{
+ int Length = 32;
+
+ buffer[0] = 0x00;
+ buffer[1] = 0x00;
+ buffer[2] = 0x01;
+ buffer[3] = 0x31;
+ buffer[4] = (Length+12)>>16;
+ buffer[5] = (Length+12)>>8;
+ buffer[6] = 0x4e;
+ buffer[7] = (Length+12);
+ buffer[8] = 0x36;
+ buffer[9] = 0x1;
+ buffer[10] = pic_width>>8;
+ buffer[11] = pic_width;
+ buffer[12] = 0x58;
+ buffer[13] = pic_height>>8;
+ buffer[14] = pic_height;
+ buffer[15] = 0x50;
+}
+void vp8_scd_frame_header(unsigned char *buffer, int pic_width, int pic_height, int Length)
+{
+ buffer[0] = 0x00;
+ buffer[1] = 0x00;
+ buffer[2] = 0x01;
+ buffer[3] = 0x32;
+ buffer[4] = (Length+12)>>16;
+ buffer[5] = (Length+12)>>8;
+ buffer[6] = 0x4e;
+ buffer[7] = (Length+12);
+ buffer[8] = 0x36;
+ buffer[9] = 0x1;
+ buffer[10] = pic_width>>8;
+ buffer[11] = pic_width;
+ buffer[12] = 0x58;
+ buffer[13] = pic_height>>8;
+ buffer[14] = pic_height;
+ buffer[15] = 0x50;
+}
+
+static void insert_payload_header_divx(u_int8 *dst, u_int32 uPayloadSize, u_int32 uWidth, u_int32 uHeight)
+{
+ // Startcode
+ dst[0] = 0x00;
+ dst[1] = 0x00;
+ dst[2] = 0x01;
+ dst[3] = 0x32;
+
+ // Length
+ dst[4] = ((uPayloadSize>>16)&0xff);
+ dst[5] = ((uPayloadSize>>8)&0xff);
+ dst[6] = 0x4e;
+ dst[7] = ((uPayloadSize>>0)&0xff);
+
+ // Codec ID and Version
+ dst[8] = 0x38;
+ dst[9] = 0x01;
+
+ // Width
+ dst[10] = ((uWidth>>8)&0xff);
+ dst[11] = ((uWidth>>0)&0xff);
+ dst[12] = 0x58;
+
+ // Height
+ dst[13] = ((uHeight>>8)&0xff);
+ dst[14] = ((uHeight>>0)&0xff);
+ dst[15] = 0x50;
+}
+
+static void insert_seq_header_spk(u_int8 *dst, u_int32 uPayloadSize, u_int32 uWidth, u_int32 uHeight)
+{
+ // Startcode
+ dst[0] = 0x00;
+ dst[1] = 0x00;
+ dst[2] = 0x01;
+ dst[3] = 0x31;
+
+ // Length
+ dst[4] = ((uPayloadSize>>16)&0xff);
+ dst[5] = ((uPayloadSize>>8)&0xff);
+ dst[6] = 0x4e;
+ dst[7] = ((uPayloadSize>>0)&0xff);
+
+ // Codec ID and Version
+ dst[8] = 0x39;
+ dst[9] = 0x01;
+
+ // Width
+ dst[10] = ((uWidth>>8)&0xff);
+ dst[11] = ((uWidth>>0)&0xff);
+ dst[12] = 0x58;
+
+ // Height
+ dst[13] = ((uHeight>>8)&0xff);
+ dst[14] = ((uHeight>>0)&0xff);
+ dst[15] = 0x50;
+}
+
+static void insert_frame_header_spk(u_int8 *dst, u_int32 uPayloadSize, u_int32 uWidth, u_int32 uHeight)
+{
+ uPayloadSize = 0;
+ // Startcode
+ dst[0] = 0x00;
+ dst[1] = 0x00;
+ dst[2] = 0x01;
+ dst[3] = 0x32;
+
+ // Length
+ dst[4] = ((uPayloadSize>>16)&0xff);
+ dst[5] = ((uPayloadSize>>8)&0xff);
+ dst[6] = 0x4e;
+ dst[7] = ((uPayloadSize>>0)&0xff);
+
+ // Codec ID and Version
+ dst[8] = 0x39;
+ dst[9] = 0x01;
+
+ // Width
+ dst[10] = ((uWidth>>8)&0xff);
+ dst[11] = ((uWidth>>0)&0xff);
+ dst[12] = 0x58;
+
+ // Height
+ dst[13] = ((uHeight>>8)&0xff);
+ dst[14] = ((uHeight>>0)&0xff);
+ dst[15] = 0x50;
+}
+
+u_int32 insert_scode_4_seq(struct vpu_ctx *ctx, u_int8 *src, u_int8 *dst, u_int32 vdec_std, u_int32 uPayloadSize)
+{
+ struct queue_data *q_data = &ctx->q_data[V4L2_SRC];
+ u_int32 length = 0;
+
+ switch (vdec_std) {
+ case VPU_VIDEO_VC1: {
+ if (q_data->fourcc == V4L2_PIX_FMT_VC1_ANNEX_G) {
+ u_int8 Header[VC1_MAX_SEQ_HEADER_SIZE];
+ u_int32 uWidth = q_data->width;
+ u_int32 uHeight = q_data->height; //Width & Height in the generic payload header are ignored
+ u_int32 FrameSize = 0x60;
+ u_int32 HeaderLen, NoError = 1;
+ //insert startcode for vc1
+ insert_payload_header_vc1(dst, VC1_SCODE_NEW_SEQUENCE, 20, uWidth, uHeight);
+ length = 16;
+ //insert RCV sequence header for vc1 v1, length=20
+ insert_RCV_seqhdr(Header, &HeaderLen, src, FrameSize, uWidth, uHeight, &NoError);
+ HeaderLen = RCV_HEADER_LEN - 4;
+ memcpy(dst + 16, Header, HeaderLen);
+ length += HeaderLen;
+ } else {
+ u_int8 Header[VC1_MAX_SEQ_HEADER_SIZE];
+ u_int32 HeaderLen;
+
+ VC1CreateNALSeqHeader(Header, &HeaderLen, src, uPayloadSize,
+ (unsigned int *)src, VC1_MAX_SEQ_HEADER_SIZE);
+ if (VC1_IS_NOT_NAL(((unsigned int *)src)[0]))
+ HeaderLen -= 4;
+ memcpy(dst, Header, HeaderLen);
+ length += HeaderLen;
+ }
+ }
+
+ break;
+ case VPU_VIDEO_VP6: {
+ vp6_scd_sequence_header(dst, q_data->width, q_data->height);
+ length = 16;
+ }
+ break;
+ case VPU_VIDEO_VP8: {
+ u_int8 seq_header[32] = {0};
+ u_int8 frame_header[8] = {0};
+
+ vp8_scd_sequence_header(dst, q_data->width, q_data->height);
+ length = 16;
+ vp8_ivf_sequence_header(seq_header, q_data->width, q_data->height);
+ memcpy(dst+length, seq_header, 32);
+ length += 32;
+ vp8_scd_frame_header(dst + length, q_data->width, q_data->height, uPayloadSize + 8);
+ length += 16;
+ vp8_ivf_frame_header(frame_header, uPayloadSize);
+ memcpy(dst+length, frame_header, 8);
+ length += 8;
+ memcpy(dst+length, src, uPayloadSize);
+ length += uPayloadSize;
+ }
+ break;
+ case VPU_VIDEO_ASP: {
+ if (q_data->fourcc == VPU_PIX_FMT_DIVX) {
+ insert_payload_header_divx(dst, uPayloadSize, q_data->width, q_data->height);
+ length = 16;
+ memcpy(dst+length, src, uPayloadSize);
+ length += uPayloadSize;
+ }
+ }
+ break;
+ case VPU_VIDEO_SPK: {
+ insert_seq_header_spk(dst, uPayloadSize, q_data->width, q_data->height);
+ length = 16;
+ }
+ break;
+ default:
+ break;
+ }
+ return length;
+}
+
+u_int32 insert_scode_4_pic(struct vpu_ctx *ctx, u_int8 *dst, u_int8 *src, u_int32 vdec_std, u_int32 uPayloadSize)
+{
+ struct queue_data *q_data = &ctx->q_data[V4L2_SRC];
+ u_int32 length = 0;
+
+ switch (vdec_std) {
+ case VPU_VIDEO_VC1: {
+ if (q_data->fourcc == V4L2_PIX_FMT_VC1_ANNEX_G) {
+ u_int8 Header[VC1_MAX_FRM_HEADER_SIZE];
+ u_int32 HeaderLen;
+ u_int32 uWidth = q_data->width;
+ u_int32 uHeight = q_data->height; //Width & Height in the generic payload header are ignored
+
+ insert_payload_header_vc1(dst, VC1_SCODE_NEW_PICTURE, uPayloadSize + 4, uWidth, uHeight);
+ insert_RCV_pichdr(Header, &HeaderLen, uPayloadSize);
+ memcpy(dst+16, Header, 4);
+ length = 16 + 4;
+ } else {
+ u_int8 Header[VC1_MAX_FRM_HEADER_SIZE];
+ u_int32 HeaderLen;
+
+ VC1CreateNalFrameHeader(Header, (int *)(&HeaderLen), (unsigned int *)(src));
+ memcpy(dst, Header, HeaderLen);
+ length = HeaderLen;
+ }
+ }
+ break;
+ case VPU_VIDEO_VP6: {
+ vp6_scd_frame_header(dst, q_data->width, q_data->height, uPayloadSize);
+ length = 16;
+ }
+ break;
+ case VPU_VIDEO_VP8: {
+ u_int8 frame_header[8];
+
+ vp8_scd_frame_header(dst, q_data->width, q_data->height, uPayloadSize + 8);
+ length = 16;
+ vp8_ivf_frame_header(frame_header, uPayloadSize);
+ memcpy(dst+length, frame_header, 8);
+ length += 8;
+ }
+ break;
+ case VPU_VIDEO_ASP: {
+ if (q_data->fourcc == VPU_PIX_FMT_DIVX) {
+ insert_payload_header_divx(dst, uPayloadSize, q_data->width, q_data->height);
+ length = 16;
+ }
+ }
+ break;
+ case VPU_VIDEO_SPK: {
+ insert_frame_header_spk(dst, uPayloadSize, q_data->width, q_data->height);
+ length = 16;
+ }
+ break;
+ default:
+ break;
+ }
+ return length;
+}
+
+
+
diff --git a/drivers/mxc/vpu_malone/insert_startcode.h b/drivers/mxc/vpu_malone/insert_startcode.h
new file mode 100644
index 000000000000..56d023f9e66c
--- /dev/null
+++ b/drivers/mxc/vpu_malone/insert_startcode.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2018 NXP
+ */
+
+/*
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/*!
+ * @file insert_startcode.h
+ *
+ */
+#ifndef __INSERT_STARTCODE_H__
+#define __INSERT_STARTCODE_H__
+
+#include "vpu_b0.h"
+#include "mediasys_types.h"
+// Startcode insertion types for VC1
+#define VC1_SCODE_NEW_SEQUENCE 0x31
+#define VC1_SCODE_NEW_PICTURE 0x32
+#define VC1_SCODE_NEW_SLICE 0x33
+#define RCV_V2_FRAMESIZE_FLAGS (0xFF000000)
+#define RCV_HEADER_LEN 24
+#define RCV_CODEC_VERSION (0x5 << 24) //FOURCC_WMV3_WMV
+#define RCV_NUM_FRAMES 0xFF
+#define RCV_SET_HDR_EXT 0x80000000
+#define VC1_IS_NOT_NAL(id) ((id & 0x00FFFFFF) != 0x00010000)
+#define VC1_MAX_FRM_HEADER_SIZE 32
+#define VC1_MAX_SEQ_HEADER_SIZE 256
+
+u_int32 insert_scode_4_pic(struct vpu_ctx *ctx, u_int8 *dst, u_int8 *src, u_int32 vdec_std, u_int32 uPayloadSize);
+u_int32 insert_scode_4_seq(struct vpu_ctx *ctx, u_int8 *src, u_int8 *dst, u_int32 vdec_std, u_int32 uPayloadSize);
+
+#endif
diff --git a/drivers/mxc/vpu_malone/mediasys_types.h b/drivers/mxc/vpu_malone/mediasys_types.h
new file mode 100644
index 000000000000..c511d35fbbaf
--- /dev/null
+++ b/drivers/mxc/vpu_malone/mediasys_types.h
@@ -0,0 +1,793 @@
+/*
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2018 NXP. All rights reserved.
+ *
+ * This program 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.
+ *
+ * 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.
+ * The full GNU General Public License is included in this distribution
+ * in the file called LICENSE.GPL.
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2018 NXP. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _MEDIASYS_TYPES_H_
+#define _MEDIASYS_TYPES_H_
+
+typedef unsigned int u_int32;
+typedef unsigned char u_int8;
+typedef unsigned long u_int64;
+typedef unsigned int BOOL;
+#define FALSE 0
+#define TRUE 1
+#define VPU_MAX_NUM_STREAMS 8
+#define VID_API_NUM_STREAMS 8
+#define VID_API_MAX_BUF_PER_STR 3
+#define VID_API_MAX_NUM_MVC_VIEWS 4
+#define MEDIAIP_MAX_NUM_MALONES 2
+#define MEDIAIP_MAX_NUM_MALONE_IRQ_PINS 2
+#define MEDIAIP_MAX_NUM_WINDSORS 1
+#define MEDIAIP_MAX_NUM_WINDSOR_IRQ_PINS 2
+#define MEDIAIP_MAX_NUM_CMD_IRQ_PINS 2
+#define MEDIAIP_MAX_NUM_MSG_IRQ_PINS 1
+#define MEDIAIP_MAX_NUM_TIMER_IRQ_PINS 4
+#define MEDIAIP_MAX_NUM_TIMER_IRQ_SLOTS 4
+#define VID_API_COMMAND_LIMIT 64
+#define VID_API_MESSAGE_LIMIT 256
+#define MSG_WORD_LENGTH 3
+#define MEDIA_PLAYER_SKIPPED_FRAME_ID 0x555
+
+#define API_CMD_AVAILABLE 0x0
+#define API_CMD_INCOMPLETE 0x1
+#define API_CMD_BUFFER_ERROR 0x2
+#define API_CMD_UNAVAILABLE 0x3
+#define API_MSG_AVAILABLE 0x0
+#define API_MSG_INCOMPLETE 0x1
+#define API_MSG_BUFFER_ERROR 0x2
+#define API_MSG_UNAVAILABLE 0x3
+
+typedef enum {
+ FRAME_ALLOC = 0,
+ FRAME_FREE,
+ FRAME_DECODED,
+ FRAME_READY,
+ FRAME_RELEASE,
+} FRAME_BUFFER_STAT;
+
+typedef enum {
+ VPU_APP,
+ VPU_DRIVER,
+ VPU_DECODER,
+} FRAME_BUFFER_OWNER;
+
+typedef enum {
+ INVALID_MODE = 0,
+ FRAME_LVL,
+ NON_FRAME_LVL,
+} STREAM_INPUT_MODE;
+
+typedef enum {
+ MEDIAIP_FRAME_REQ = 0,
+ MEDIAIP_MBI_REQ,
+ MEDIAIP_DCP_REQ,
+ MEDIAIP_REQ_LAST = MEDIAIP_DCP_REQ
+
+} MEDIAIP_MEM_REQ;
+
+typedef struct {
+ u_int32 uNum;
+ MEDIAIP_MEM_REQ eType;
+} MEDIA_PLAYER_FSREQ;
+
+typedef struct {
+ u_int32 uFSIdx;
+ MEDIAIP_MEM_REQ eType;
+ BOOL bNotDisplayed;
+} MEDIA_PLAYER_FSREL;
+
+typedef enum {
+ /* Non-Stream Specific messages */
+ MEDIA_PLAYER_API_MODE_INVALID = 0x00,
+ MEDIA_PLAYER_API_MODE_PARSE_STEP = 0x01,
+ MEDIA_PLAYER_API_MODE_DECODE_STEP = 0x02,
+ MEDIA_PLAYER_API_MODE_CONTINUOUS = 0x03
+} MEDIA_PLAYER_API_MODE;
+
+typedef enum {
+ /* Non-Stream Specific messages */
+ MEDIA_PLAYER_FS_CTRL_MODE_INTERNAL = 0x00,
+ MEDIA_PLAYER_FS_CTRL_MODE_EXTERNAL = 0x01
+} MEDIA_PLAYER_FS_CTRL_MODE;
+
+typedef enum {
+ /* Non-Stream Specific messages */
+ VID_API_CMD_NULL = 0x00,
+ VID_API_CMD_PARSE_NEXT_SEQ = 0x01,
+ VID_API_CMD_PARSE_NEXT_I = 0x02,
+ VID_API_CMD_PARSE_NEXT_IP = 0x03,
+ VID_API_CMD_PARSE_NEXT_ANY = 0x04,
+ VID_API_CMD_DEC_PIC = 0x05,
+ VID_API_CMD_UPDATE_ES_WR_PTR = 0x06,
+ VID_API_CMD_UPDATE_ES_RD_PTR = 0x07,
+ VID_API_CMD_UPDATE_UDATA = 0x08,
+ VID_API_CMD_GET_FSINFO = 0x09,
+ VID_API_CMD_SKIP_PIC = 0x0a,
+ VID_API_CMD_DEC_CHUNK = 0x0b,
+ VID_API_CMD_START = 0x10,
+ VID_API_CMD_STOP = 0x11,
+ VID_API_CMD_ABORT = 0x12,
+ VID_API_CMD_RST_BUF = 0x13,
+ VID_API_CMD_FS_RELEASE = 0x15,
+ VID_API_CMD_MEM_REGION_ATTACH = 0x16,
+ VID_API_CMD_MEM_REGION_DETACH = 0x17,
+ VID_API_CMD_MVC_VIEW_SELECT = 0x18,
+ VID_API_CMD_FS_ALLOC = 0x19,
+ VID_API_CMD_DBG_GET_STATUS = 0x1C,
+ VID_API_CMD_DBG_START_LOG = 0x1D,
+ VID_API_CMD_DBG_STOP_LOG = 0x1E,
+ VID_API_CMD_DBG_DUMP_LOG = 0x1F,
+ /* Begin Encode CMDs */
+ VID_API_CMD_YUV_READY = 0x20,
+
+ VID_API_CMD_FIRM_RESET = 0x40,
+
+#if BOOT_ARCH == REBOOT
+ VID_API_CMD_SNAPSHOT = 0xAA,
+ VID_API_CMD_ROLL_SNAPSHOT = 0xAB,
+ VID_API_CMD_LOCK_SCHEDULER = 0xAC,
+ VID_API_CMD_UNLOCK_SCHEDULER = 0xAD,
+#endif
+ VID_API_CMD_CQ_FIFO_DUMP = 0xAE,
+ VID_API_CMD_DBG_FIFO_DUMP = 0xAF,
+ VID_API_CMD_SVC_ILP = 0xBB,
+ VID_API_CMD_INVALID = 0xFF
+
+} TB_API_DEC_CMD;
+
+typedef enum {
+ /* Non-Stream Specific messages */
+ VID_API_EVENT_NULL = 0x00,
+ VID_API_EVENT_RESET_DONE = 0x01,
+ VID_API_EVENT_SEQ_HDR_FOUND = 0x02,
+ VID_API_EVENT_PIC_HDR_FOUND = 0x03,
+ VID_API_EVENT_PIC_DECODED = 0x04,
+ VID_API_EVENT_FIFO_LOW = 0x05,
+ VID_API_EVENT_FIFO_HIGH = 0x06,
+ VID_API_EVENT_FIFO_EMPTY = 0x07,
+ VID_API_EVENT_FIFO_FULL = 0x08,
+ VID_API_EVENT_BS_ERROR = 0x09,
+ VID_API_EVENT_UDATA_FIFO_UPTD = 0x0A,
+ VID_API_EVENT_RES_CHANGE = 0x0B,
+ VID_API_EVENT_FIFO_OVF = 0x0C,
+ VID_API_EVENT_CHUNK_DECODED = 0x0D,
+ VID_API_EVENT_REQ_FRAME_BUFF = 0x10,
+ VID_API_EVENT_FRAME_BUFF_RDY = 0x11,
+ VID_API_EVENT_REL_FRAME_BUFF = 0x12,
+ VID_API_EVENT_STR_BUF_RST = 0x13,
+ VID_API_EVENT_RET_PING = 0x14, /* Temp here - rationalise debug events at bottom */
+ VID_API_EVENT_QMETER = 0x15,
+ VID_API_EVENT_STR_FMT_CHANGE = 0x16,
+ VID_API_EVENT_FIRMWARE_XCPT = 0x17,
+ VID_API_EVENT_START_DONE = 0x18,
+ VID_API_EVENT_STOPPED = 0x19,
+ VID_API_EVENT_ABORT_DONE = 0x1A,
+ VID_API_EVENT_FINISHED = 0x1B,
+ VID_API_EVENT_DBG_STAT_UPDATE = 0x1C,
+ VID_API_EVENT_DBG_LOG_STARTED = 0x1D,
+ VID_API_EVENT_DBG_LOG_STOPPED = 0x1E,
+ VID_API_EVENT_DBG_LOG_UPDATED = 0x1F,
+ VID_API_EVENT_DBG_MSG_DEC = 0x20,
+ VID_API_EVENT_DEC_SC_ERR = 0x21,
+ VID_API_EVENT_CQ_FIFO_DUMP = 0x22,
+ VID_API_EVENT_DBG_FIFO_DUMP = 0x23,
+ VID_API_EVENT_DEC_CHECK_RES = 0x24,
+ VID_API_EVENT_DEC_CFG_INFO = 0x25,
+ VID_API_EVENT_SNAPSHOT_DONE = 0x40,
+ VID_API_EVENT_INVALID = 0xFF
+
+} TB_API_DEC_EVENT;
+
+typedef enum {
+ MEDIAIP_PLAYMODE_CONNECTIVITY = 0,
+ MEDIAIP_PLAYMODE_BROADCAST,
+ MEDIAIP_PLAYMODE_BROADCAST_DSS,
+ MEDIAIP_PLAYMODE_LAST = MEDIAIP_PLAYMODE_BROADCAST_DSS
+
+} MEDIA_IP_PLAYMODE;
+
+typedef enum {
+ MEDIA_IP_FMT_NULL = 0x0,
+ MEDIA_IP_FMT_AVC = 0x1,
+ MEDIA_IP_FMT_VC1 = 0x2,
+ MEDIA_IP_FMT_MP2 = 0x3,
+ MEDIA_IP_FMT_AVS = 0x4,
+ MEDIA_IP_FMT_ASP = 0x5,
+ MEDIA_IP_FMT_JPG = 0x6,
+ MEDIA_IP_FMT_RV = 0x7,
+ MEDIA_IP_FMT_VP6 = 0x8,
+ MEDIA_IP_FMT_SPK = 0x9,
+ MEDIA_IP_FMT_VP8 = 0xA,
+ MEDIA_IP_FMT_MVC = 0xB,
+ MEDIA_IP_FMT_VP3 = 0xC,
+ MEDIA_IP_FMT_HEVC = 0xD,
+ MEDIA_IP_FMT_AUTO_DETECT = 0xAD00,
+ MEDIA_IP_FMT_ALL = (int)0xAAAAAAAA,
+ MEDIA_IP_FMT_UNSUPPORTED = (int)0xFFFFFFFF,
+ MEDIA_IP_FMT_LAST = MEDIA_IP_FMT_UNSUPPORTED
+
+} MEDIA_IP_FORMAT;
+
+typedef enum {
+ VSys_FrmtNull = 0x0,
+ VSys_AvcFrmt = 0x1,
+ VSys_Mp2Frmt = 0x2,
+ VSys_Vc1Frmt = 0x3,
+ VSys_AvsFrmt = 0x4,
+ VSys_AspFrmt = 0x5,
+ VSys_JpgFrmt = 0x6,
+ VSys_RvFrmt = 0x7,
+ VSys_Vp6Frmt = 0x8,
+ VSys_SpkFrmt = 0x9,
+ VSys_Vp8Frmt = 0xA,
+ VSys_HevcFrmt = 0xB,
+ VSys_LastFrmt = VSys_HevcFrmt
+} TB_API_DEC_FMT;
+
+typedef struct {
+ u_int32 bTopFldFirst;
+ u_int32 bRptFstField;
+ u_int32 uDispVerRes;
+ u_int32 uDispHorRes;
+ u_int32 uCentreVerOffset;
+ u_int32 uCentreHorOffset;
+ u_int32 uCropLeftRightOffset;
+ u_int32 uCropTopBotOffset;
+
+} MediaIPFW_Video_PicDispInfo;
+
+typedef struct MediaIPFW_PicPerfInfo {
+ u_int32 uMemCRC;
+ u_int32 uBSCRC;
+ u_int32 uSlcActiveCnt;
+ u_int32 uIBEmptyCnt;
+ u_int32 uBaseMemCRC;
+
+ u_int32 uBaseCRCSkip;
+ u_int32 uBaseCRCDrop;
+ BOOL bBaseCRCValid;
+
+ u_int32 uCRC0;
+ u_int32 uCRC1;
+ u_int32 uCRC2;
+ u_int32 uCRC3;
+ u_int32 uCRC4;
+ u_int32 uCRC5;
+
+ u_int32 uFrameActCount;
+ u_int32 uRbspBytesCount;
+ u_int32 uDpbReadCount;
+ u_int32 uMprWaitCount;
+ u_int32 uAccQP;
+ u_int32 uCacheStat;
+ u_int32 mbq_full;
+ u_int32 mbq_empty;
+ u_int32 slice_cnt;
+ u_int32 mb_count;
+
+ u_int32 uTotalTime_us;
+ u_int32 uTotalFwTime_us;
+
+ u_int32 uProcIaccTotRdCnt;
+ u_int32 uProcDaccTotRdCnt;
+ u_int32 uProcDaccTotWrCnt;
+ u_int32 uProcDaccRegRdCnt;
+ u_int32 uProcDaccRegWrCnt;
+ u_int32 uProcDaccRngRdCnt;
+ u_int32 uProcDaccRngWrCnt;
+
+} MediaIPFW_Video_PicPerfInfo;
+
+typedef struct {
+ u_int32 mb_count;
+ u_int32 slice_cnt;
+
+ /* Front End Metrics */
+ u_int32 uDFEBinsUsed;
+ u_int32 uDFECycleCount;
+ u_int32 uDFESliceCycleCount;
+ u_int32 uDFEIBWaitCount;
+ u_int32 uDFENumBytes;
+
+ u_int32 uProcIaccTotRdCnt;
+ u_int32 uProcDaccTotRdCnt;
+ u_int32 uProcDaccTotWrCnt;
+ u_int32 uProcDaccRegRdCnt;
+ u_int32 uProcDaccRegWrCnt;
+ u_int32 uProcDaccRngRdCnt;
+ u_int32 uProcDaccRngWrCnt;
+
+ /* Back End metrics */
+ u_int32 uNumBEUsed;
+ u_int32 uTotalTime_us;
+ u_int32 uTotalFwTime_us;
+ u_int32 uDBECycleCount[0x2];
+ u_int32 uDBESliceCycleCount[0x2];
+ u_int32 uDBEMprWaitCount[0x2];
+ u_int32 uDBEWaitCount[0x2];
+ u_int32 uDBECRC[0x2];
+ u_int32 uDBETotalTime_us[0x2];
+
+ u_int32 uDBEMPRPRXWaitCount[0x2];
+ u_int32 uDBEPXDPRXWaitCount[0x2];
+ u_int32 uDBEFCHPLQWaitCount[0x2];
+ u_int32 uDBEPXDPLQWaitCount[0x2];
+
+ u_int32 uDBEFchWordsCount[0x2];
+ u_int32 uDBEDpbCRC[0x2];
+ u_int32 uDBEDpbReadCount[0x2];
+ u_int32 uDBECacheStats[0x2];
+
+} MediaIPFW_Video_PicPerfDcpInfo, *pMediaIPFW_Video_PicPerfDcpInfo;
+
+typedef struct {
+ u_int32 uPicType;
+ u_int32 uPicStruct;
+ u_int32 bLastPicNPF;
+ u_int32 uPicStAddr;
+ u_int32 uFrameStoreID;
+ MediaIPFW_Video_PicDispInfo DispInfo;
+ MediaIPFW_Video_PicPerfInfo PerfInfo;
+ MediaIPFW_Video_PicPerfDcpInfo PerfDcpInfo;
+ u_int32 bUserDataAvail;
+ u_int32 uPercentInErr;
+
+ u_int32 uBbdHorActive;
+ u_int32 uBbdVerActive;
+ u_int32 uBbdLogoActive;
+ u_int32 uBbdBotPrev;
+ u_int32 uBbdMinColPrj;
+ u_int32 uBbdMinRowPrj;
+ u_int32 uFSBaseAddr;
+
+ /* Only for RealVideo RPR */
+ u_int32 uRprPicWidth;
+ u_int32 uRprPicHeight;
+
+ /*only for divx3*/
+ u_int32 uFrameRate;
+
+} MediaIPFW_Video_PicInfo;
+
+
+typedef struct {
+ u_int32 bClosedGop;
+ u_int32 bBrokenLink;
+} MediaIPFW_Video_GopInfo;
+
+typedef struct {
+ u_int32 uIQuant;
+ u_int32 uIQuantAvail;
+ u_int32 uGopBitRate;
+ u_int32 uGopBitRateAvail;
+
+} MediaIPFW_Video_QMeterInfo;
+
+typedef struct {
+ u_int32 pPicInfoArrayBase;
+ u_int32 uNumSizeDescriptors;
+} MediaIPFW_Video_PicInfoBuffTabDesc;
+
+typedef struct {
+ u_int32 pGopInfoArrayBase;
+ u_int32 uNumSizeDescriptors;
+} MediaIPFW_Video_GopInfoBuffTabDesc;
+
+typedef struct {
+ u_int32 pQMeterInfoArrayBase;
+ u_int32 uNumSizeDescriptors;
+} MediaIPFW_Video_QMeterInfoTabDesc;
+
+typedef struct {
+ u_int32 uMemChunkBase;
+ u_int32 uMemChunkSize;
+
+} MediaIPFW_Video_FrameBuffer;
+
+typedef struct {
+ u_int32 uUDataBase;
+ u_int32 uUDataTotalSize;
+ u_int32 uUDataSlotSize;
+
+} MediaIPFW_Video_UData;
+
+typedef struct {
+ u_int32 uDecStatusLogBase;
+ u_int32 uDecStatusLogSize;
+ u_int32 uDecStatusLogLevel;
+ u_int32 uReserved;
+
+} MediaIPFW_Video_DbgLogDesc;
+
+typedef struct {
+ u_int32 uDTVLogBase[VID_API_NUM_STREAMS];
+ u_int32 uDTVLogSize[VID_API_NUM_STREAMS];
+
+} MediaIPFW_Video_EngAccessLogDesc;
+
+typedef struct MediaIPFW_FrameStore {
+ u_int32 uFrameStoreLumaBase;
+ u_int32 uFrameStoreChromaBase;
+
+} MediaIPFW_Video_FrameStore;
+
+typedef struct {
+ u_int32 uAddrFirstDescriptor;
+ u_int32 uNumSizeDescriptors;
+
+} MediaIPFW_Video_StreamBuffTabDesc;
+
+typedef struct {
+ u_int32 uAddrFirstDescriptor;
+ u_int32 uNumSizeDescriptors;
+} MediaIPFW_Video_UserDataBuffTabDesc;
+
+typedef struct {
+ u_int32 uNumRefFrms;
+ u_int32 uNumDPBFrms;
+ u_int32 uNumDFEAreas;
+ u_int32 uColorDesc;
+ u_int32 uTransferChars;
+ u_int32 uMatrixCoeffs;
+ u_int32 uVideoFullRangeFlag;
+ u_int32 uVUIPresent;
+ u_int32 uProgressive;
+ u_int32 uVerRes;
+ u_int32 uHorRes;
+ u_int32 uParWidth;
+ u_int32 uParHeight;
+ u_int32 FrameRate;
+ u_int32 UDispAspRatio;
+ u_int32 uLevelIDC;
+ u_int32 uVerDecodeRes;
+ u_int32 uHorDecodeRes;
+ u_int32 uOverScan;
+ u_int32 uChromaFmt;
+ u_int32 uPAFF;
+ u_int32 uMBAFF;
+ u_int32 uBitDepthLuma;
+ u_int32 uBitDepthChroma;
+ u_int32 uMVCNumViews;
+ u_int32 uMVCViewList[VID_API_MAX_NUM_MVC_VIEWS];
+ u_int32 uActiveSeqTag;
+ u_int32 uFrameCropValid;
+ u_int32 uFrameCropLeftOffset;
+ u_int32 uFrameCropRightOffset;
+ u_int32 uFrameCropTopOffset;
+ u_int32 uFrameCropBottomOffset;
+
+} MediaIPFW_Video_SeqInfo;
+
+typedef struct {
+ u_int32 pSeqInfoArrayBase;
+ u_int32 uNumSizeDescriptors;
+} MediaIPFW_Video_SeqInfoBuffTabDesc;
+
+typedef struct {
+ u_int32 wptr;
+ u_int32 rptr;
+ u_int32 start;
+ u_int32 end;
+
+} BUFFER_DESCRIPTOR_TYPE, *pBUFFER_DESCRIPTOR_TYPE;
+
+typedef struct {
+ u_int32 stream_input_mode;
+ u_int32 stream_pic_input_count;
+ u_int32 stream_pic_parsed_count;
+ u_int32 stream_buffer_threshold;
+ u_int32 stream_pic_end_flag;
+} BUFFER_INFO_TYPE, *pBUFFER_INFO_TYPE;
+
+typedef struct {
+ volatile u_int32 wptr;
+ volatile u_int32 rptr;
+ volatile u_int32 start;
+ volatile u_int32 end;
+ volatile u_int32 LWM;
+
+} STREAM_BUFFER_DESCRIPTOR_TYPE, *pSTREAM_BUFFER_DESCRIPTOR_TYPE;
+
+typedef struct {
+ u_int32 uRotationAngle;
+ u_int32 uHorizScaleFactor;
+ u_int32 uVertScaleFactor;
+ u_int32 uRotationMode;
+ u_int32 uRGBMode;
+ u_int32 uChunkMode; /* 0 ~ 1 */
+ u_int32 uLastChunk; /* 0 ~ 1 */
+ u_int32 uChunkRows; /* 0 ~ 255 */
+ u_int32 uNumBytes;
+ u_int32 uJpgCropXStart;
+ u_int32 uJpgCropYStart;
+ u_int32 uJpgCropWidth;
+ u_int32 uJpgCropHeight;
+ u_int32 uJpgMjpegMode;
+ u_int32 uJpgMjpegInterlaced;
+
+} MediaIPFW_Video_JpegParams;
+
+typedef struct {
+ u_int32 pJpegParamArrayBase;
+ u_int32 uNumSizeDescriptors;
+
+} MediaIPFW_Video_JpegParamTabDesc;
+
+typedef struct {
+ u_int32 uDispImm;
+ u_int32 uFourCC;
+ u_int32 uCodecVersion;
+ u_int32 uFrameRate;
+ u_int32 uEnableDbgLog;
+ u_int32 bbd_lum_thr;
+ u_int32 bbd_coring;
+ u_int32 bbd_s_thr_row;
+ u_int32 bbd_p_thr_row;
+ u_int32 bbd_s_thr_logo_row;
+ u_int32 bbd_p_thr_logo_row;
+ u_int32 bbd_s_thr_col;
+ u_int32 bbd_p_thr_col;
+ u_int32 bbd_chr_thr_row;
+ u_int32 bbd_chr_thr_col;
+ u_int32 bbd_uv_mid_level;
+ u_int32 bbd_excl_win_mb_left;
+ u_int32 bbd_excl_win_mb_right;
+
+} MediaIPFW_Video_CodecParams;
+
+typedef struct {
+ u_int32 uFramePitch;
+
+} MediaIPFW_Video_PitchInfo;
+
+typedef struct {
+ u_int32 uWrPtr;
+ u_int32 uRdPtr;
+ u_int32 uStart;
+ u_int32 uEnd;
+ u_int32 uLo;
+ u_int32 uHi;
+
+} MediaIPFW_Video_BufDesc;
+
+typedef struct {
+ u_int32 pCodecParamArrayBase;
+ u_int32 uNumSizeDescriptors;
+
+} MediaIPFW_Video_CodecParamTabDesc;
+
+typedef struct {
+ u_int32 uRC4Key[0x8];
+ u_int32 uMemObfuscVal;
+
+} MediaIPFW_Video_Encrypt_Info, *pMediaIPFW_Video_Encrypt_Info;
+
+typedef struct {
+ u_int32 uCfgCookie;
+
+ u_int32 uNumMalones;
+ u_int32 uMaloneBaseAddress[MEDIAIP_MAX_NUM_MALONES];
+ u_int32 uHifOffset[MEDIAIP_MAX_NUM_MALONES];
+ u_int32 uMaloneIrqPin[MEDIAIP_MAX_NUM_MALONES][MEDIAIP_MAX_NUM_MALONE_IRQ_PINS];
+ u_int32 uMaloneIrqTarget[MEDIAIP_MAX_NUM_MALONES][MEDIAIP_MAX_NUM_MALONE_IRQ_PINS];
+
+ u_int32 uNumWindsors;
+ u_int32 uWindsorBaseAddress[MEDIAIP_MAX_NUM_WINDSORS];
+ u_int32 uWindsorIrqPin[MEDIAIP_MAX_NUM_WINDSORS][MEDIAIP_MAX_NUM_WINDSOR_IRQ_PINS];
+ u_int32 uWindsorIrqTarget[MEDIAIP_MAX_NUM_WINDSORS][MEDIAIP_MAX_NUM_WINDSOR_IRQ_PINS];
+
+ u_int32 uCmdIrqPin[MEDIAIP_MAX_NUM_CMD_IRQ_PINS];
+ u_int32 uCmdIrqTarget[MEDIAIP_MAX_NUM_CMD_IRQ_PINS];
+
+ u_int32 uMsgIrqPin[MEDIAIP_MAX_NUM_MSG_IRQ_PINS];
+ u_int32 uMsgIrqTarget[MEDIAIP_MAX_NUM_MSG_IRQ_PINS];
+
+ u_int32 uSysClkFreq;
+ u_int32 uNumTimers;
+ u_int32 uTimerBaseAddr;
+ u_int32 uTimerIrqPin[MEDIAIP_MAX_NUM_TIMER_IRQ_PINS];
+ u_int32 uTimerIrqTarget[MEDIAIP_MAX_NUM_TIMER_IRQ_PINS];
+ u_int32 uTimerSlots[MEDIAIP_MAX_NUM_TIMER_IRQ_SLOTS];
+
+ u_int32 uGICBaseAddr;
+ u_int32 uUartBaseAddr;
+
+ u_int32 uDPVBaseAddr;
+ u_int32 uDPVIrqPin;
+ u_int32 uDPVIrqTarget;
+
+ u_int32 uPixIfBaseAddr;
+
+ u_int32 pal_trace_level;
+ u_int32 pal_trace_destination;
+
+ u_int32 pal_trace_level1;
+ u_int32 pal_trace_destination1;
+
+ u_int32 uHeapBase;
+ u_int32 uHeapSize;
+
+ u_int32 uFSLCacheBaseAddr[2];
+
+} MEDIAIP_FW_SYSTEM_CONFIG, *pMEDIAIP_FW_SYSTEM_CONFIG;
+
+typedef struct {
+ u_int32 FwExecBaseAddr;
+ u_int32 FwExecAreaSize;
+ MediaIPFW_Video_BufDesc StreamCmdBufferDesc;
+ MediaIPFW_Video_BufDesc StreamMsgBufferDesc;
+ u_int32 StreamCmdIntEnable[VID_API_NUM_STREAMS];
+ MediaIPFW_Video_PitchInfo StreamPitchInfo[VID_API_NUM_STREAMS];
+ u_int32 StreamConfig[VID_API_NUM_STREAMS];
+ MediaIPFW_Video_CodecParamTabDesc CodecParamTabDesc; /* TODO-KMC should we just go ahead and remove the concept of tabdesc? It is basicaly a bad coding style used for pinkys anyway */
+ MediaIPFW_Video_JpegParamTabDesc JpegParamTabDesc;
+ u_int32 pStreamBuffDesc[VID_API_NUM_STREAMS][VID_API_MAX_BUF_PER_STR];
+ MediaIPFW_Video_SeqInfoBuffTabDesc SeqInfoTabDesc;
+ MediaIPFW_Video_PicInfoBuffTabDesc PicInfoTabDesc;
+ MediaIPFW_Video_GopInfoBuffTabDesc GopInfoTabDesc;
+ MediaIPFW_Video_QMeterInfoTabDesc QMeterInfoTabDesc;
+ u_int32 StreamError[VID_API_NUM_STREAMS];
+ u_int32 FWVersion;
+ u_int32 uMVDMipsOffset;
+ u_int32 uMaxDecoderStreams;
+ MediaIPFW_Video_DbgLogDesc DbgLogDesc;
+ MediaIPFW_Video_FrameBuffer StreamFrameBuffer[VID_API_NUM_STREAMS];
+ MediaIPFW_Video_FrameBuffer StreamDCPBuffer[VID_API_NUM_STREAMS];
+ MediaIPFW_Video_UData UDataBuffer[VID_API_NUM_STREAMS];
+ MediaIPFW_Video_BufDesc DebugBufferDesc;
+ MediaIPFW_Video_BufDesc EngAccessBufferDesc[VID_API_NUM_STREAMS];
+ u_int32 ptEncryptInfo[VID_API_NUM_STREAMS];
+ MEDIAIP_FW_SYSTEM_CONFIG sSystemCfg;
+ u_int32 uApiVersion;
+ BUFFER_INFO_TYPE StreamBuffInfo[VID_API_NUM_STREAMS];
+} DEC_RPC_HOST_IFACE, *pDEC_RPC_HOST_IFACE;
+
+//x means source data , y means destination data
+#define VID_STREAM_CONFIG_FORMAT_MASK 0x0000000F
+#define VID_STREAM_CONFIG_FORMAT_POS 0
+#define VID_STREAM_CONFIG_FORMAT_SET(x, y) (*y = (*y | ((x << VID_STREAM_CONFIG_FORMAT_POS)&VID_STREAM_CONFIG_FORMAT_MASK)))
+
+#define VID_STREAM_CONFIG_STRBUFIDX_MASK 0x00000300
+#define VID_STREAM_CONFIG_STRBUFIDX_POS 8
+#define VID_STREAM_CONFIG_STRBUFIDX_SET(x, y) (*y = (*y | ((x << VID_STREAM_CONFIG_STRBUFIDX_POS)&VID_STREAM_CONFIG_STRBUFIDX_MASK)))
+
+#define VID_STREAM_CONFIG_NOSEQ_MASK 0x00000400
+#define VID_STREAM_CONFIG_NOSEQ_POS 10
+#define VID_STREAM_CONFIG_NOSEQ_SET(x, y) (*y = (*y | ((x << VID_STREAM_CONFIG_NOSEQ_POS)&VID_STREAM_CONFIG_NOSEQ_MASK)))
+
+#define VID_STREAM_CONFIG_DEBLOCK_MASK 0x00000800
+#define VID_STREAM_CONFIG_DEBLOCK_POS 11
+#define VID_STREAM_CONFIG_DEBLOCK_SET(x, y) (*y = (*y | ((x << VID_STREAM_CONFIG_DEBLOCK_POS)&VID_STREAM_CONFIG_DEBLOCK_MASK)))
+
+#define VID_STREAM_CONFIG_DERING_MASK 0x00001000
+#define VID_STREAM_CONFIG_DERING_POS 12
+#define VID_STREAM_CONFIG_DERING_SET(x, y) (*y = (*y | ((x << VID_STREAM_CONFIG_DERING_POS)&VID_STREAM_CONFIG_DERING_MASK)))
+
+#define VID_STREAM_CONFIG_IBWAIT_MASK 0x00002000
+#define VID_STREAM_CONFIG_IBWAIT_POS 13
+#define VID_STREAM_CONFIG_IBWAIT_SET(x, y) (*y = (*y | ((x << VID_STREAM_CONFIG_IBWAIT_POS)&VID_STREAM_CONFIG_IBWAIT_MASK)))
+
+#define VID_STREAM_CONFIG_FBC_MASK 0x00004000
+#define VID_STREAM_CONFIG_FBC_POS 14
+#define VID_STREAM_CONFIG_FBC_SET(x, y) (*y = (*y | ((x << VID_STREAM_CONFIG_FBC_POS)&VID_STREAM_CONFIG_FBC_MASK)))
+
+#define VID_STREAM_CONFIG_PLAY_MODE_MASK 0x00030000
+#define VID_STREAM_CONFIG_PLAY_MODE_POS 16
+#define VID_STREAM_CONFIG_PLAY_MODE_SET(x, y) (*y = (*y | ((x << VID_STREAM_CONFIG_PLAY_MODE_POS)&VID_STREAM_CONFIG_PLAY_MODE_MASK)))
+
+#define VID_STREAM_CONFIG_ENABLE_DCP_MASK 0x00100000
+#define VID_STREAM_CONFIG_ENABLE_DCP_POS 20
+#define VID_STREAM_CONFIG_ENABLE_DCP_SET(x, y) (*y = (*y | ((x << VID_STREAM_CONFIG_ENABLE_DCP_POS)&VID_STREAM_CONFIG_ENABLE_DCP_MASK)))
+
+#define VID_STREAM_CONFIG_NUM_STR_BUF_MASK 0x00600000
+#define VID_STREAM_CONFIG_NUM_STR_BUF_POS 21
+#define VID_STREAM_CONFIG_NUM_STR_BUF_SET(x, y) (*y = (*y | ((x << VID_STREAM_CONFIG_NUM_STR_BUF_POS)&VID_STREAM_CONFIG_NUM_STR_BUF_MASK)))
+
+#define VID_STREAM_CONFIG_MALONE_USAGE_MASK 0x01800000
+#define VID_STREAM_CONFIG_MALONE_USAGE_POS 23
+#define VID_STREAM_CONFIG_MALONE_USAGE_SET(x, y) (*y = (*y | ((x << VID_STREAM_CONFIG_MALONE_USAGE_POS)&VID_STREAM_CONFIG_MALONE_USAGE_MASK)))
+
+#define VID_STREAM_CONFIG_MULTI_VID_MASK 0x02000000
+#define VID_STREAM_CONFIG_MULTI_VID_POS 25
+#define VID_STREAM_CONFIG_MULTI_VID_SET(x, y) (*y = (*y | ((x << VID_STREAM_CONFIG_MULTI_VID_POS)&VID_STREAM_CONFIG_MULTI_VID_MASK)))
+
+#define VID_STREAM_CONFIG_OBFUSC_EN_MASK 0x04000000
+#define VID_STREAM_CONFIG_OBFUSC_EN_POS 26
+#define VID_STREAM_CONFIG_OBFUSC_EN_SET(x, y) (*y = (*y | ((x << VID_STREAM_CONFIG_OBFUSC_EN_POS)&VID_STREAM_CONFIG_OBFUSC_EN_MASK)))
+
+#define VID_STREAM_CONFIG_RC4_EN_MASK 0x08000000
+#define VID_STREAM_CONFIG_RC4_EN_POS 27
+#define VID_STREAM_CONFIG_RC4_EN_SET(x, y) (*y = (*y | ((x << VID_STREAM_CONFIG_RC4_EN_POS)&VID_STREAM_CONFIG_RC4_EN_MASK)))
+
+#define VID_STREAM_CONFIG_MCX_MASK 0x10000000
+#define VID_STREAM_CONFIG_MCX_POS 28
+#define VID_STREAM_CONFIG_MCX_SET(x, y) (*y = (*y | ((x << VID_STREAM_CONFIG_MCX_POS)&VID_STREAM_CONFIG_MCX_MASK)))
+
+#define VID_STREAM_CONFIG_PES_MASK 0x20000000
+#define VID_STREAM_CONFIG_PES_POS 29
+#define VID_STREAM_CONFIG_PES_SET(x, y) ((*y = (*y | ((x << VID_STREAM_CONFIG_PES_POS)&VID_STREAM_CONFIG_PES_MASK))))
+
+#define VID_STREAM_CONFIG_NUM_DBE_MASK 0x40000000
+#define VID_STREAM_CONFIG_NUM_DBE_POS 30
+#define VID_STREAM_CONFIG_NUM_DBE_SET(x, y) (*y = (*y | ((x << VID_STREAM_CONFIG_NUM_DBE_POS)&VID_STREAM_CONFIG_NUM_DBE_MASK)))
+
+#define VID_STREAM_CONFIG_FS_CTRL_MODE_MASK 0x80000000
+#define VID_STREAM_CONFIG_FS_CTRL_MODE_POS 31
+#define VID_STREAM_CONFIG_FS_CTRL_MODE_SET(x, y) (*y = (*y | ((x << VID_STREAM_CONFIG_FS_CTRL_MODE_POS)&VID_STREAM_CONFIG_FS_CTRL_MODE_MASK)))
+
+#define SCB_XREG_SLV_BASE 0x00000000
+#define SCB_SCB_BLK_CTRL 0x00070000
+#define SCB_BLK_CTRL_XMEM_RESET_SET 0x00000090
+#define SCB_BLK_CTRL_CACHE_RESET_SET 0x000000A0
+#define SCB_BLK_CTRL_CACHE_RESET_CLR 0x000000A4
+#define SCB_BLK_CTRL_SCB_CLK_ENABLE_SET 0x00000100
+
+#define XMEM_CONTROL 0x00041000
+
+#define DEC_MFD_XREG_SLV_BASE 0x00180000
+
+#define MFD_HIF 0x0001C000
+#define MFD_HIF_MSD_REG_INTERRUPT_STATUS 0x00000018
+#define MFD_SIF 0x0001D000
+#define MFD_SIF_CTRL_STATUS 0x000000F0
+#define MFD_SIF_INTR_STATUS 0x000000F4
+#define MFD_MCX 0x00020800
+#define MFD_MCX_OFF 0x00000020
+
+#define MFD_BLK_CTRL 0x00030000
+#define MFD_BLK_CTRL_MFD_SYS_RESET_SET 0x00000000
+#define MFD_BLK_CTRL_MFD_SYS_RESET_CLR 0x00000004
+#define MFD_BLK_CTRL_MFD_SYS_CLOCK_ENABLE_SET 0x00000100
+#define MFD_BLK_CTRL_MFD_SYS_CLOCK_ENABLE_CLR 0x00000104
+
+#endif
diff --git a/drivers/mxc/vpu_malone/vpu_b0.c b/drivers/mxc/vpu_malone/vpu_b0.c
new file mode 100644
index 000000000000..b8862eb8c7d3
--- /dev/null
+++ b/drivers/mxc/vpu_malone/vpu_b0.c
@@ -0,0 +1,4321 @@
+/*
+ * Copyright 2018 NXP
+ */
+
+/*
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/*!
+ * @file vpu-b0.c
+ *
+ * copyright here may be changed later
+ *
+ *
+ */
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/dma-mapping.h>
+#include <linux/module.h>
+#include <linux/videodev2.h>
+#include <linux/firmware.h>
+#include <linux/interrupt.h>
+#include <linux/file.h>
+#include <linux/of_platform.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/slab.h>
+#include <linux/platform_data/dma-imx.h>
+#include <linux/miscdevice.h>
+#include <linux/fs.h>
+#include <linux/pm_runtime.h>
+#include <linux/mx8_mu.h>
+#include <linux/uaccess.h>
+#include <linux/debugfs.h>
+
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-event.h>
+#include <media/v4l2-ioctl.h>
+#include <media/v4l2-mem2mem.h>
+#include <media/videobuf2-v4l2.h>
+#include <media/videobuf2-dma-contig.h>
+#include <media/videobuf2-dma-sg.h>
+
+#include "vpu_b0.h"
+#include "insert_startcode.h"
+#include "vpu_debug_log.h"
+
+unsigned int vpu_dbg_level_decoder = 1;
+static int vpu_frm_depth = INVALID_FRAME_DEPTH;
+static int vpu_log_depth = DEFAULT_LOG_DEPTH;
+static int vpu_max_bufsize = MAX_BUFFER_SIZE;
+static int vpu_frmdbg_ena = DEFAULT_FRMDBG_ENABLE;
+static int vpu_frmdbg_level = DEFAULT_FRMDBG_LEVEL;
+static int vpu_dbe_num = 1;
+static int vpu_frmcrcdump_ena;
+static int stream_buffer_threshold;
+
+/* Generic End of content startcodes to differentiate from those naturally in the stream/file */
+#define EOS_GENERIC_HEVC 0x7c010000
+#define EOS_GENERIC_JPEG 0xefff0000
+#define EOS_GENERIC_MPEG 0xCC010000
+#define V4L2_CID_USER_RAW_BASE (V4L2_CID_USER_BASE + 0x1100)
+static void vpu_api_event_handler(struct vpu_ctx *ctx, u_int32 uStrIdx, u_int32 uEvent, u_int32 *event_data);
+static void v4l2_vpu_send_cmd(struct vpu_ctx *ctx, uint32_t idx, uint32_t cmdid, uint32_t cmdnum, uint32_t *local_cmddata);
+static int add_scode(struct vpu_ctx *ctx, u_int32 uStrBufIdx, VPU_PADDING_SCODE_TYPE eScodeType, bool bUpdateWr);
+static void v4l2_update_stream_addr(struct vpu_ctx *ctx, uint32_t uStrBufIdx);
+static int swreset_vpu_firmware(struct vpu_dev *dev, u_int32 idx);
+static int find_first_available_instance(struct vpu_dev *dev);
+static int remove_instance_file(struct vpu_ctx *ctx);
+static void fill_stream_buffer_info(struct vpu_ctx *ctx);
+static void set_pic_end_flag(struct vpu_ctx *ctx);
+static void clear_pic_end_flag(struct vpu_ctx *ctx);
+static void send_skip_event(struct vpu_ctx* ctx);
+#define CHECK_BIT(var, pos) (((var) >> (pos)) & 1)
+
+static char *cmd2str[] = {
+ "VID_API_CMD_NULL", /*0x0*/
+ "VID_API_CMD_PARSE_NEXT_SEQ", /*0x1*/
+ "VID_API_CMD_PARSE_NEXT_I",
+ "VID_API_CMD_PARSE_NEXT_IP",
+ "VID_API_CMD_PARSE_NEXT_ANY",
+ "VID_API_CMD_DEC_PIC",
+ "VID_API_CMD_UPDATE_ES_WR_PTR",
+ "VID_API_CMD_UPDATE_ES_RD_PTR",
+ "VID_API_CMD_UPDATE_UDATA",
+ "VID_API_CMD_GET_FSINFO",
+ "VID_API_CMD_SKIP_PIC",
+ "VID_API_CMD_DEC_CHUNK", /*0x0b*/
+ "VID_API_CMD_UNDEFINED",
+ "VID_API_CMD_UNDEFINED",
+ "VID_API_CMD_UNDEFINED",
+ "VID_API_CMD_UNDEFINED",
+ "VID_API_CMD_START", /*0x10*/
+ "VID_API_CMD_STOP",
+ "VID_API_CMD_ABORT",
+ "VID_API_CMD_RST_BUF",
+ "VID_API_CMD_UNDEFINED",
+ "VID_API_CMD_FS_RELEASE",
+ "VID_API_CMD_MEM_REGION_ATTACH",
+ "VID_API_CMD_MEM_REGION_DETACH",
+ "VID_API_CMD_MVC_VIEW_SELECT",
+ "VID_API_CMD_FS_ALLOC", /*0x19*/
+ "VID_API_CMD_UNDEFINED",
+ "VID_API_CMD_UNDEFINED",
+ "VID_API_CMD_DBG_GET_STATUS", /*0x1C*/
+ "VID_API_CMD_DBG_START_LOG",
+ "VID_API_CMD_DBG_STOP_LOG",
+ "VID_API_CMD_DBG_DUMP_LOG",
+ "VID_API_CMD_YUV_READY", /*0x20*/
+};
+
+static char *event2str[] = {
+ "VID_API_EVENT_NULL", /*0x0*/
+ "VID_API_EVENT_RESET_DONE", /*0x1*/
+ "VID_API_EVENT_SEQ_HDR_FOUND",
+ "VID_API_EVENT_PIC_HDR_FOUND",
+ "VID_API_EVENT_PIC_DECODED",
+ "VID_API_EVENT_FIFO_LOW",
+ "VID_API_EVENT_FIFO_HIGH",
+ "VID_API_EVENT_FIFO_EMPTY",
+ "VID_API_EVENT_FIFO_FULL",
+ "VID_API_EVENT_BS_ERROR",
+ "VID_API_EVENT_UDATA_FIFO_UPTD",
+ "VID_API_EVENT_RES_CHANGE",
+ "VID_API_EVENT_FIFO_OVF",
+ "VID_API_EVENT_CHUNK_DECODED", /*0x0D*/
+ "VID_API_EVENT_UNDEFINED",
+ "VID_API_EVENT_UNDEFINED",
+ "VID_API_EVENT_REQ_FRAME_BUFF", /*0x10*/
+ "VID_API_EVENT_FRAME_BUFF_RDY",
+ "VID_API_EVENT_REL_FRAME_BUFF",
+ "VID_API_EVENT_STR_BUF_RST",
+ "VID_API_EVENT_RET_PING",
+ "VID_API_EVENT_QMETER",
+ "VID_API_EVENT_STR_FMT_CHANGED",
+ "VID_API_EVENT_FIRMWARE_XCPT",
+ "VID_API_EVENT_START_DONE",
+ "VID_API_EVENT_STOPPED",
+ "VID_API_EVENT_ABORT_DONE",
+ "VID_API_EVENT_FINISHED",
+ "VID_API_EVENT_DBG_STAT_UPDATE",
+ "VID_API_EVENT_DBG_LOG_STARTED",
+ "VID_API_EVENT_DBG_LOG_STOPPED",
+ "VID_API_EVENT_DBG_LOG_UPFATED",
+ "VID_API_EVENT_DBG_MSG_DEC", /*0x20*/
+ "VID_API_EVENT_DEC_SC_ERR",
+ "VID_API_EVENT_CQ_FIFO_DUMP",
+ "VID_API_EVENT_DBG_FIFO_DUMP",
+ "VID_API_EVENT_DEC_CHECK_RES",
+ "VID_API_EVENT_DEC_CFG_INFO", /*0x25*/
+};
+
+static char *bufstat[] = {
+ "FRAME_ALLOC",
+ "FRAME_FREE",
+ "FRAME_DECODED",
+ "FRAME_READY",
+ "FRAME_RELEASE",
+};
+
+static int alloc_vpu_buffer(struct vpu_ctx *ctx);
+
+static char *get_event_str(u32 event)
+{
+ if (event == VID_API_EVENT_SNAPSHOT_DONE)
+ return "VID_API_EVENT_SNAPSHOT_DONE";
+ else if (event >= ARRAY_SIZE(event2str))
+ return "UNKNOWN EVENT";
+ return event2str[event];
+}
+
+static char *get_cmd_str(u32 cmdid)
+{
+ if (cmdid == VID_API_CMD_FIRM_RESET)
+ return "VID_API_CMD_FIRM_RESET";
+ else if (cmdid == VID_API_CMD_SNAPSHOT)
+ return "VID_API_CMD_SNAPSHOT";
+ else if (cmdid >= ARRAY_SIZE(cmd2str))
+ return "UNKNOWN CMD";
+ return cmd2str[cmdid];
+}
+
+static void vpu_log_event(u_int32 uEvent, u_int32 ctxid)
+{
+ if (uEvent > ARRAY_SIZE(event2str)-1)
+ vpu_dbg(LVL_EVENT, "reveive event: 0x%X, ctx id:%d\n",
+ uEvent, ctxid);
+ else
+ vpu_dbg(LVL_EVENT, "recevie event: %s, ctx id:%d\n",
+ event2str[uEvent], ctxid);
+}
+
+static void vpu_log_cmd(u_int32 cmdid, u_int32 ctxid)
+{
+ if (cmdid > ARRAY_SIZE(cmd2str)-1)
+ vpu_dbg(LVL_EVENT, "send cmd: 0x%X, ctx id:%d\n",
+ cmdid, ctxid);
+ else
+ vpu_dbg(LVL_EVENT, "send cmd: %s ctx id:%d\n",
+ cmd2str[cmdid], ctxid);
+}
+
+static void vpu_log_buffer_state(struct vpu_ctx *ctx)
+{
+ struct vb2_data_req *p_data_req;
+ struct queue_data *This;
+ int i;
+
+ if (!ctx)
+ return;
+
+ This = &ctx->q_data[V4L2_DST];
+ down(&This->drv_q_lock);
+ for (i = 0; i < VPU_MAX_BUFFER; i++) {
+ p_data_req = &This->vb2_reqs[i];
+ if (p_data_req->vb2_buf != NULL)
+ vpu_dbg(LVL_INFO, "ctx: %d, buffer[%d] status: %s\n",
+ ctx->str_index, i, bufstat[p_data_req->status]);
+ }
+ up(&This->drv_q_lock);
+}
+
+static void count_event(struct vpu_statistic *statistic, u32 event)
+{
+ if (!statistic)
+ return;
+
+ if (event < ARRAY_SIZE(event2str))
+ statistic->event[event]++;
+ else
+ statistic->event[VID_API_EVENT_DEC_CFG_INFO + 1]++;
+
+ statistic->current_event = event;
+ getrawmonotonic(&statistic->ts_event);
+}
+
+static void count_cmd(struct vpu_statistic *statistic, u32 cmdid)
+{
+ if (!statistic)
+ return;
+
+ if (cmdid < ARRAY_SIZE(cmd2str))
+ statistic->cmd[cmdid]++;
+ else
+ statistic->cmd[VID_API_CMD_YUV_READY + 1]++;
+ statistic->current_cmd = cmdid;
+ getrawmonotonic(&statistic->ts_cmd);
+}
+static int find_buffer_id(struct vpu_ctx *ctx, u_int32 addr)
+{
+ struct queue_data *This;
+ struct vb2_data_req *p_data_req;
+ u_int32 LumaAddr;
+ u_int32 *pphy_address;
+ u_int32 i;
+
+ if (!ctx)
+ return -1;
+
+ This = &ctx->q_data[V4L2_DST];
+ down(&This->drv_q_lock);
+ for (i = 0; i < VPU_MAX_BUFFER; i++) {
+ p_data_req = &This->vb2_reqs[i];
+ if (p_data_req->vb2_buf != NULL) {
+ pphy_address = (u_int32 *)vb2_plane_cookie(p_data_req->vb2_buf, 0);
+ if (pphy_address != NULL) {
+ LumaAddr = *pphy_address + p_data_req->data_offset[0];
+ if (LumaAddr == addr) {
+ up(&This->drv_q_lock);
+ return i;
+ }
+ } else {
+ vpu_dbg(LVL_INFO, "error: %s() ctx[%d] buffer (%d) is NULL\n",
+ __func__, ctx->str_index, i);
+ }
+ }
+ }
+ up(&This->drv_q_lock);
+ vpu_dbg(LVL_ERR, "error: %s() ctx[%d] can't find suitable id based on address(0x%x)\n",
+ __func__, ctx->str_index, addr);
+ return -1;
+}
+
+static void MU_sendMesgToFW(void __iomem *base, MSG_Type type, uint32_t value)
+{
+ MU_SendMessage(base, 1, value);
+ MU_SendMessage(base, 0, type);
+}
+#ifdef DEBUG
+static void vpu_log_shared_mem(struct vpu_ctx *ctx)
+{
+ struct vpu_dev *dev = ctx->dev;
+ struct shared_addr *This = &dev->shared_mem;
+ pDEC_RPC_HOST_IFACE pSharedInterface = (pDEC_RPC_HOST_IFACE)This->shared_mem_vir;
+ MediaIPFW_Video_BufDesc *pMsgDesc = &pSharedInterface->StreamMsgBufferDesc;
+ MediaIPFW_Video_BufDesc *pCmdDesc = &pSharedInterface->StreamCmdBufferDesc;
+ pSTREAM_BUFFER_DESCRIPTOR_TYPE pStrBufDesc;
+ u_int32 index = ctx->str_index;
+
+ vpu_dbg(LVL_INFO, "msg: wr: 0x%x, rd: 0x%x, cmd: wr : 0x%x, rd: 0x%x\n",
+ pMsgDesc->uWrPtr, pMsgDesc->uRdPtr, pCmdDesc->uWrPtr, pCmdDesc->uRdPtr);
+
+ pStrBufDesc = dev->regs_base + DEC_MFD_XREG_SLV_BASE + MFD_MCX + MFD_MCX_OFF * index;
+ vpu_dbg(LVL_INFO, "data: wptr(0x%x) rptr(0x%x) start(0x%x) end(0x%x) uStrIdx(%d)\n",
+ pStrBufDesc->wptr, pStrBufDesc->rptr, pStrBufDesc->start, pStrBufDesc->end, index);
+}
+#endif
+/*
+ * v4l2 ioctl() operation
+ *
+ */
+static struct vpu_v4l2_fmt formats_compressed_dec[] = {
+ {
+ .name = "H264 Encoded Stream",
+ .fourcc = V4L2_PIX_FMT_H264,
+ .num_planes = 1,
+ .vdec_std = VPU_VIDEO_AVC,
+ .disable = 0,
+ },
+ {
+ .name = "VC1 Encoded Stream",
+ .fourcc = V4L2_PIX_FMT_VC1_ANNEX_G,
+ .num_planes = 1,
+ .vdec_std = VPU_VIDEO_VC1,
+ .disable = 0,
+ },
+ {
+ .name = "VC1 RCV Encoded Stream",
+ .fourcc = V4L2_PIX_FMT_VC1_ANNEX_L,
+ .num_planes = 1,
+ .vdec_std = VPU_VIDEO_VC1,
+ .disable = 0,
+ },
+ {
+ .name = "MPEG2 Encoded Stream",
+ .fourcc = V4L2_PIX_FMT_MPEG2,
+ .num_planes = 1,
+ .vdec_std = VPU_VIDEO_MPEG2,
+ .disable = 0,
+ },
+
+ {
+ .name = "AVS Encoded Stream",
+ .fourcc = VPU_PIX_FMT_AVS,
+ .num_planes = 1,
+ .vdec_std = VPU_VIDEO_AVS,
+ .disable = 0,
+ },
+ {
+ .name = "MPEG4 ASP Encoded Stream",
+ .fourcc = V4L2_PIX_FMT_MPEG4,
+ .num_planes = 1,
+ .vdec_std = VPU_VIDEO_ASP,
+ .disable = 0,
+ },
+ {
+ .name = "DIVX Encoded Stream",
+ .fourcc = VPU_PIX_FMT_DIVX,
+ .num_planes = 1,
+ .vdec_std = VPU_VIDEO_ASP,
+ .disable = 0,
+ },
+ {
+ .name = "JPEG stills",
+ .fourcc = V4L2_PIX_FMT_JPEG,
+ .num_planes = 1,
+ .vdec_std = VPU_VIDEO_JPEG,
+ .disable = 0,
+ },
+ {
+ .name = "RV Encoded Stream",
+ .fourcc = VPU_PIX_FMT_RV,
+ .num_planes = 1,
+ .vdec_std = VPU_VIDEO_RV,
+ .disable = 0,
+ },
+ {
+ .name = "VP6 Encoded Stream",
+ .fourcc = VPU_PIX_FMT_VP6,
+ .num_planes = 1,
+ .vdec_std = VPU_VIDEO_VP6,
+ .disable = 0,
+ },
+ {
+ .name = "SPK Encoded Stream",
+ .fourcc = VPU_PIX_FMT_SPK,
+ .num_planes = 1,
+ .vdec_std = VPU_VIDEO_SPK,
+ .disable = 0,
+ },
+ {
+ .name = "H263 Encoded Stream",
+ .fourcc = V4L2_PIX_FMT_H263,
+ .num_planes = 1,
+ .vdec_std = VPU_VIDEO_ASP,
+ .disable = 0,
+ },
+ {
+ .name = "VP8 Encoded Stream",
+ .fourcc = V4L2_PIX_FMT_VP8,
+ .num_planes = 1,
+ .vdec_std = VPU_VIDEO_VP8,
+ .disable = 0,
+ },
+ {
+ .name = "H264/MVC Encoded Stream",
+ .fourcc = V4L2_PIX_FMT_H264_MVC,
+ .num_planes = 1,
+ .vdec_std = VPU_VIDEO_AVC_MVC,
+ .disable = 0,
+ },
+ {
+ .name = "H265 HEVC Encoded Stream",
+ .fourcc = VPU_PIX_FMT_HEVC,
+ .num_planes = 1,
+ .vdec_std = VPU_VIDEO_HEVC,
+ .disable = 0,
+ },
+ {
+ .name = "Logo",
+ .fourcc = VPU_PIX_FMT_LOGO,
+ .num_planes = 1,
+ .vdec_std = VPU_VIDEO_UNDEFINED,
+ .disable = 0,
+ },
+};
+
+static struct vpu_v4l2_fmt formats_yuv_dec[] = {
+ {
+ .name = "4:2:0 2 Planes Y/CbCr",
+ .fourcc = V4L2_PIX_FMT_NV12,
+ .num_planes = 2,
+ .vdec_std = VPU_PF_YUV420_SEMIPLANAR,
+ .disable = 0,
+ },
+ {
+ .name = "4:2:0 2 Planes Y/CbCr",
+ .fourcc = V4L2_PIX_FMT_NV12_10BIT,
+ .num_planes = 2,
+ .vdec_std = VPU_PF_YUV420_SEMIPLANAR,
+ .disable = 0,
+ },
+};
+
+static int v4l2_ioctl_querycap(struct file *file,
+ void *fh,
+ struct v4l2_capability *cap
+ )
+{
+ vpu_dbg(LVL_INFO, "%s()\n", __func__);
+ strlcpy(cap->driver, "vpu B0", sizeof(cap->driver));
+ strlcpy(cap->card, "vpu B0", sizeof(cap->card));
+ strlcpy(cap->bus_info, "platform:", sizeof(cap->bus_info));
+ cap->version = KERNEL_VERSION(0, 0, 1);
+ cap->device_caps = V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_STREAMING;
+ cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
+ return 0;
+}
+
+static int v4l2_ioctl_enum_fmt_vid_cap_mplane(struct file *file,
+ void *fh,
+ struct v4l2_fmtdesc *f
+ )
+{
+ struct vpu_v4l2_fmt *fmt;
+
+ vpu_dbg(LVL_INFO, "%s()\n", __func__);
+ if (f->index >= ARRAY_SIZE(formats_yuv_dec))
+ return -EINVAL;
+
+ fmt = &formats_yuv_dec[f->index];
+ strlcpy(f->description, fmt->name, sizeof(f->description));
+ f->pixelformat = fmt->fourcc;
+ return 0;
+}
+static int v4l2_ioctl_enum_fmt_vid_out_mplane(struct file *file,
+ void *fh,
+ struct v4l2_fmtdesc *f
+ )
+{
+ struct vpu_v4l2_fmt *fmt;
+ u_int32 index = 0, i;
+
+ vpu_dbg(LVL_INFO, "%s()\n", __func__);
+
+ if (f->index >= ARRAY_SIZE(formats_compressed_dec))
+ return -EINVAL;
+
+ for (i = 0; i < ARRAY_SIZE(formats_compressed_dec); i++) {
+ fmt = &formats_compressed_dec[i];
+ if (fmt->disable == 1)
+ continue;
+ if (f->index == index)
+ break;
+ index++;
+ }
+
+ if (i == ARRAY_SIZE(formats_compressed_dec))
+ return -EINVAL;
+
+ strlcpy(f->description, fmt->name, sizeof(f->description));
+ f->pixelformat = fmt->fourcc;
+ f->flags |= V4L2_FMT_FLAG_COMPRESSED;
+ return 0;
+}
+
+static void caculate_frame_size(struct vpu_ctx *ctx)
+{
+ u_int32 width = ctx->pSeqinfo->uHorDecodeRes;
+ u_int32 height = ctx->pSeqinfo->uVerDecodeRes;
+ u_int32 luma_size;
+ u_int32 chroma_size;
+ u_int32 chroma_height;
+ u_int32 uVertAlign = 512-1;
+ bool b10BitFormat = (ctx->pSeqinfo->uBitDepthLuma > 8) ||
+ (ctx->pSeqinfo->uBitDepthChroma > 8);
+
+ struct queue_data *q_data;
+
+ q_data = &ctx->q_data[V4L2_DST];
+
+ width = b10BitFormat?(width + ((width + 3) >> 2)):width;
+ width = ((width + uVertAlign) & ~uVertAlign);
+ q_data->stride = width;
+
+ height = ((height + uVertAlign) & ~uVertAlign);
+ if (ctx->pSeqinfo->uProgressive)
+ chroma_height = height >> 1;
+ else
+ chroma_height = height;
+ luma_size = width * height;
+ chroma_size = width * chroma_height;
+ ctx->q_data[V4L2_DST].sizeimage[0] = luma_size;
+ ctx->q_data[V4L2_DST].sizeimage[1] = chroma_size;
+}
+
+static int v4l2_ioctl_g_fmt(struct file *file,
+ void *fh,
+ struct v4l2_format *f
+ )
+{
+ struct vpu_ctx *ctx = v4l2_fh_to_ctx(fh);
+ struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp;
+ unsigned int i;
+ struct queue_data *q_data;
+
+ vpu_dbg(LVL_INFO, "%s()\n", __func__);
+
+ if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
+ q_data = &ctx->q_data[V4L2_DST];
+ if ((ctx->pSeqinfo->uBitDepthLuma > 8) || (ctx->pSeqinfo->uBitDepthChroma > 8))
+ pix_mp->pixelformat = V4L2_PIX_FMT_NV12_10BIT;
+ else
+ pix_mp->pixelformat = V4L2_PIX_FMT_NV12;
+ pix_mp->width = ctx->pSeqinfo->uHorRes > 0?ctx->pSeqinfo->uHorRes:q_data->width;
+ pix_mp->height = ctx->pSeqinfo->uVerRes > 0?ctx->pSeqinfo->uVerRes:q_data->height;
+ if (ctx->pSeqinfo->uProgressive == 1)
+ pix_mp->field = V4L2_FIELD_NONE;
+ else
+ pix_mp->field = V4L2_FIELD_INTERLACED;
+ pix_mp->num_planes = 2;
+ pix_mp->colorspace = V4L2_COLORSPACE_REC709;
+
+ for (i = 0; i < pix_mp->num_planes; i++) {
+ pix_mp->plane_fmt[i].bytesperline = q_data->stride;
+ pix_mp->plane_fmt[i].sizeimage = q_data->sizeimage[i];
+ }
+ } else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
+ q_data = &ctx->q_data[V4L2_SRC];
+ pix_mp->width = q_data->width;
+ pix_mp->height = q_data->height;
+ pix_mp->field = V4L2_FIELD_NONE;
+ pix_mp->num_planes = q_data->num_planes;
+ for (i = 0; i < pix_mp->num_planes; i++) {
+ pix_mp->plane_fmt[i].bytesperline = q_data->stride;
+ pix_mp->plane_fmt[i].sizeimage = q_data->sizeimage[i];
+
+ }
+ pix_mp->pixelformat = q_data->fourcc;
+ } else
+ return -EINVAL;
+ return 0;
+}
+
+static bool set_video_standard(struct queue_data *q_data,
+ struct v4l2_format *f,
+ struct vpu_v4l2_fmt *pformat_table,
+ uint32_t table_size)
+{
+ unsigned int i;
+
+ for (i = 0; i < table_size; i++) {
+ if (pformat_table[i].fourcc == f->fmt.pix_mp.pixelformat) {
+ if (pformat_table[i].disable == 1)
+ return false;
+ q_data->vdec_std = pformat_table[i].vdec_std;
+ }
+ }
+ return true;
+}
+
+#define VPU_DISABLE_BITS (0x7)
+void check_fuse_value(struct vpu_dev *dev,
+ struct vpu_v4l2_fmt *pformat_table,
+ uint32_t table_size)
+{
+ u_int32 fuse;
+ u_int32 val;
+ u_int32 i;
+
+ if (!dev)
+ return;
+ sc_misc_otp_fuse_read(dev->mu_ipcHandle, VPU_DISABLE_BITS, &fuse);
+ val = (fuse >> 2) & 0x3UL;
+ if (val == 0x1UL) {
+ for (i = 0; i < table_size; i++)
+ if (pformat_table[i].fourcc == VPU_PIX_FMT_HEVC)
+ pformat_table[i].disable = 1;
+ vpu_dbg(LVL_WARN, "H265 is disabled\n");
+ } else if (val == 0x2UL) {
+ for (i = 0; i < table_size; i++)
+ if (pformat_table[i].fourcc == V4L2_PIX_FMT_H264)
+ pformat_table[i].disable = 1;
+ vpu_dbg(LVL_WARN, "H264 is disabled\n");
+ } else if (val == 0x3UL) {
+ for (i = 0; i < table_size; i++)
+ pformat_table[i].disable = 1;
+ vpu_dbg(LVL_WARN, "All decoder disabled\n");
+ }
+
+}
+
+static int v4l2_ioctl_s_fmt(struct file *file,
+ void *fh,
+ struct v4l2_format *f
+ )
+{
+ struct vpu_ctx *ctx = v4l2_fh_to_ctx(fh);
+ struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp;
+ struct queue_data *q_data;
+ u_int32 i;
+
+ vpu_dbg(LVL_INFO, "%s()\n", __func__);
+
+ if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
+ q_data = &ctx->q_data[V4L2_DST];
+ if (!set_video_standard(q_data, f, formats_yuv_dec, ARRAY_SIZE(formats_yuv_dec)))
+ return -EINVAL;
+ pix_mp->num_planes = 2;
+ pix_mp->colorspace = V4L2_COLORSPACE_REC709;
+ for (i = 0; i < pix_mp->num_planes; i++) {
+ if (ctx->q_data[V4L2_DST].stride > 0)
+ pix_mp->plane_fmt[i].bytesperline = ctx->q_data[V4L2_DST].stride;
+ if (ctx->q_data[V4L2_DST].sizeimage[i] > 0)
+ pix_mp->plane_fmt[i].sizeimage = ctx->q_data[V4L2_DST].sizeimage[i];
+ }
+ } else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
+ q_data = &ctx->q_data[V4L2_SRC];
+ if (!set_video_standard(q_data, f, formats_compressed_dec, ARRAY_SIZE(formats_compressed_dec)))
+ return -EINVAL;
+ } else
+ return -EINVAL;
+
+ q_data->num_planes = pix_mp->num_planes;
+ for (i = 0; i < q_data->num_planes; i++) {
+ q_data->stride = pix_mp->plane_fmt[i].bytesperline;
+ q_data->sizeimage[i] = pix_mp->plane_fmt[i].sizeimage;
+ }
+ q_data->fourcc = pix_mp->pixelformat;
+ q_data->width = pix_mp->width;
+ q_data->height = pix_mp->height;
+ q_data->rect.left = 0;
+ q_data->rect.top = 0;
+ q_data->rect.width = pix_mp->width;
+ q_data->rect.height = pix_mp->height;
+
+ return 0;
+}
+
+static int vpu_dec_queue_expbuf(struct queue_data *queue,
+ struct v4l2_exportbuffer *buf)
+{
+ int ret = -EINVAL;
+
+ down(&queue->drv_q_lock);
+ if (queue->vb2_q_inited)
+ ret = vb2_expbuf(&queue->vb2_q, buf);
+ up(&queue->drv_q_lock);
+
+ return ret;
+}
+
+static int vpu_dec_queue_reqbufs(struct queue_data *queue,
+ struct v4l2_requestbuffers *reqbuf)
+{
+ int ret = -EINVAL;
+
+ down(&queue->drv_q_lock);
+ if (queue->vb2_q_inited)
+ ret = vb2_reqbufs(&queue->vb2_q, reqbuf);
+ up(&queue->drv_q_lock);
+
+ return ret;
+}
+
+static int vpu_dec_queue_querybuf(struct queue_data *queue,
+ struct v4l2_buffer *buf)
+{
+ int ret = -EINVAL;
+
+ down(&queue->drv_q_lock);
+ if (queue->vb2_q_inited)
+ ret = vb2_querybuf(&queue->vb2_q, buf);
+ up(&queue->drv_q_lock);
+
+ return ret;
+}
+
+static int vpu_dec_queue_qbuf(struct queue_data *queue,
+ struct v4l2_buffer *buf)
+{
+ int ret = -EINVAL;
+
+ down(&queue->drv_q_lock);
+ if (queue->vb2_q_inited)
+ ret = vb2_qbuf(&queue->vb2_q, buf);
+ up(&queue->drv_q_lock);
+
+ return ret;
+}
+
+static int vpu_dec_queue_dqbuf(struct queue_data *queue,
+ struct v4l2_buffer *buf, bool nonblocking)
+{
+ int ret = -EINVAL;
+
+ down(&queue->drv_q_lock);
+ if (queue->vb2_q_inited)
+ ret = vb2_dqbuf(&queue->vb2_q, buf, nonblocking);
+ up(&queue->drv_q_lock);
+
+ return ret;
+}
+
+static int vpu_dec_queue_enable(struct queue_data *queue,
+ enum v4l2_buf_type type)
+{
+ int ret = -EINVAL;
+
+ down(&queue->drv_q_lock);
+ if (queue->vb2_q_inited)
+ ret = vb2_streamon(&queue->vb2_q, type);
+ up(&queue->drv_q_lock);
+
+ return ret;
+}
+
+static void clear_queue(struct queue_data *queue)
+{
+ struct vb2_data_req *p_data_req = NULL;
+ struct vb2_data_req *p_temp;
+ struct vb2_buffer *vb;
+
+ vpu_dbg(LVL_INFO, "%s() is called\n", __func__);
+ list_for_each_entry_safe(p_data_req, p_temp, &queue->drv_q, list) {
+ list_del(&p_data_req->list);
+ p_data_req->queued = false;
+ }
+
+ list_for_each_entry(vb, &queue->vb2_q.queued_list, queued_entry) {
+ if (vb->state == VB2_BUF_STATE_ACTIVE)
+ vb2_buffer_done(vb, VB2_BUF_STATE_ERROR);
+ }
+ INIT_LIST_HEAD(&queue->drv_q);
+}
+
+static int vpu_dec_queue_disable(struct queue_data *queue,
+ enum v4l2_buf_type type)
+{
+ int ret = -EINVAL;
+
+ down(&queue->drv_q_lock);
+ if (queue->vb2_q_inited)
+ ret = vb2_streamoff(&queue->vb2_q, type);
+ up(&queue->drv_q_lock);
+
+ return ret;
+}
+
+static int vpu_dec_queue_release(struct queue_data *queue)
+{
+ int ret = -EINVAL;
+
+ down(&queue->drv_q_lock);
+ if (queue->vb2_q_inited) {
+ clear_queue(queue);
+ vb2_queue_release(&queue->vb2_q);
+ }
+ up(&queue->drv_q_lock);
+
+ return ret;
+}
+
+static int vpu_dec_queue_mmap(struct queue_data *queue,
+ struct vm_area_struct *vma)
+{
+ int ret = -EINVAL;
+
+ down(&queue->drv_q_lock);
+ if (queue->vb2_q_inited)
+ ret = vb2_mmap(&queue->vb2_q, vma);
+ up(&queue->drv_q_lock);
+
+ return ret;
+}
+
+static int v4l2_ioctl_expbuf(struct file *file,
+ void *fh,
+ struct v4l2_exportbuffer *buf
+ )
+{
+ struct vpu_ctx *ctx = v4l2_fh_to_ctx(fh);
+ struct queue_data *q_data;
+
+ vpu_dbg(LVL_INFO, "%s()\n", __func__);
+
+ if (buf->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
+ q_data = &ctx->q_data[V4L2_SRC];
+ else if (buf->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
+ q_data = &ctx->q_data[V4L2_DST];
+ else
+ return -EINVAL;
+
+ return vpu_dec_queue_expbuf(q_data, buf);
+}
+
+static int v4l2_ioctl_subscribe_event(struct v4l2_fh *fh,
+ const struct v4l2_event_subscription *sub
+ )
+{
+ vpu_dbg(LVL_INFO, "%s()\n", __func__);
+
+ switch (sub->type) {
+ case V4L2_EVENT_EOS:
+ return v4l2_event_subscribe(fh, sub, 0, NULL);
+ case V4L2_EVENT_SKIP:
+ return v4l2_event_subscribe(fh, sub, 0, NULL);
+ case V4L2_EVENT_SOURCE_CHANGE:
+ return v4l2_src_change_event_subscribe(fh, sub);
+ default:
+ return -EINVAL;
+ }
+}
+
+static void init_dma_buffer(struct dma_buffer *buffer)
+{
+ if (!buffer)
+ return;
+
+ buffer->dma_phy = 0;
+ buffer->dma_virt = NULL;
+ buffer->dma_size = 0;
+}
+
+static int alloc_dma_buffer(struct vpu_ctx *ctx, struct dma_buffer *buffer)
+{
+ if (!ctx || !ctx->dev || !buffer)
+ return -EINVAL;
+
+ buffer->dma_virt = dma_alloc_coherent(&ctx->dev->plat_dev->dev,
+ buffer->dma_size,
+ (dma_addr_t *)&buffer->dma_phy,
+ GFP_KERNEL | GFP_DMA32);
+
+ if (!buffer->dma_virt) {
+ vpu_dbg(LVL_ERR, "error: %s() dma buffer alloc size(%x) fail!\n",
+ __func__, buffer->dma_size);
+ return -ENOMEM;
+ }
+
+ memset_io(buffer->dma_virt, 0, buffer->dma_size);
+ atomic64_add(buffer->dma_size, &ctx->statistic.total_dma_size);
+ return 0;
+}
+
+static int free_dma_buffer(struct vpu_ctx *ctx, struct dma_buffer *buffer)
+{
+ if (!ctx || !ctx->dev || !buffer)
+ return -EINVAL;
+
+ if (!buffer->dma_virt)
+ return -1;
+
+ dma_free_coherent(&ctx->dev->plat_dev->dev,
+ buffer->dma_size,
+ buffer->dma_virt,
+ buffer->dma_phy);
+
+ atomic64_sub(buffer->dma_size, &ctx->statistic.total_dma_size);
+ init_dma_buffer(buffer);
+ return 0;
+}
+
+static u_int32 get_mbi_size(struct queue_data *queue)
+{
+ u_int32 uAlign = 0x800;
+ u_int32 mbi_size;
+
+ mbi_size = (queue->sizeimage[0] + queue->sizeimage[1])/4;
+ return ALIGN(mbi_size, uAlign);
+}
+
+static int alloc_mbi_buffer(struct vpu_ctx *ctx)
+{
+ u_int32 ret = 0;
+ u_int32 i;
+
+ for (i = 0; i < ctx->mbi_num; i++) {
+ ctx->mbi_buffer[i].dma_size = ctx->mbi_size;
+ ret = alloc_dma_buffer(ctx, &ctx->mbi_buffer[i]);
+ if (ret) {
+ vpu_dbg(LVL_ERR, "error: %s() ctx[%d] alloc mbi buffer fail\n",
+ __func__, ctx->str_index);
+ return ret;
+ } else {
+ vpu_dbg(LVL_EVENT, "%s() ctx[%d] mbi[%d]: virt: %p, phy: %lld\n",
+ __func__, ctx->str_index, i, ctx->mbi_buffer[i].dma_virt, ctx->mbi_buffer[i].dma_phy);
+ }
+ }
+
+ return ret;
+}
+
+static int alloc_dcp_buffer(struct vpu_ctx *ctx, uint32_t index)
+{
+ struct dma_buffer *dcp_buffer = NULL;
+ int ret = 0;
+
+ if (index >= ARRAY_SIZE(ctx->dcp_buffer))
+ return -EINVAL;
+
+ dcp_buffer = &ctx->dcp_buffer[index];
+ if (dcp_buffer->dma_virt && dcp_buffer->dma_size >= DCP_SIZE)
+ return 0;
+
+ free_dma_buffer(ctx, dcp_buffer);
+ dcp_buffer->dma_size = DCP_SIZE;
+ ret = alloc_dma_buffer(ctx, dcp_buffer);
+ if (ret) {
+ vpu_dbg(LVL_ERR, "error: alloc dcp buffer fail\n");
+ return ret;
+ }
+
+ return 0;
+}
+
+static int free_mbi_buffers(struct vpu_ctx *ctx)
+{
+ u_int32 i;
+
+ for (i = 0; i < ARRAY_SIZE(ctx->mbi_buffer); i++)
+ free_dma_buffer(ctx, &ctx->mbi_buffer[i]);
+
+ return 0;
+}
+
+static int free_decoder_buffer(struct vpu_ctx *ctx)
+{
+ struct queue_data *queue;
+ u_int32 i;
+
+ queue = &ctx->q_data[V4L2_DST];
+ down(&queue->drv_q_lock);
+ for (i = 0; i < ARRAY_SIZE(ctx->mbi_buffer); i++)
+ free_dma_buffer(ctx, &ctx->mbi_buffer[i]);
+ up(&queue->drv_q_lock);
+
+ for (i = 0; i < ARRAY_SIZE(ctx->dcp_buffer); i++)
+ free_dma_buffer(ctx, &ctx->dcp_buffer[i]);
+
+ queue = &ctx->q_data[V4L2_SRC];
+ down(&queue->drv_q_lock);
+ free_dma_buffer(ctx, &ctx->stream_buffer);
+ free_dma_buffer(ctx, &ctx->udata_buffer);
+ up(&queue->drv_q_lock);
+
+ return 0;
+}
+
+void clear_vb2_buf(struct queue_data *q_data)
+{
+ struct vb2_data_req *p_data_req;
+ u_int32 i;
+
+ if (!q_data)
+ return;
+
+ down(&q_data->drv_q_lock);
+ for (i = 0; i < VPU_MAX_BUFFER; i++) {
+ p_data_req = &q_data->vb2_reqs[i];
+ p_data_req->vb2_buf = NULL;
+ }
+ up(&q_data->drv_q_lock);
+}
+
+static int v4l2_ioctl_reqbufs(struct file *file,
+ void *fh,
+ struct v4l2_requestbuffers *reqbuf
+ )
+{
+ struct vpu_ctx *ctx = v4l2_fh_to_ctx(fh);
+ struct queue_data *q_data;
+ int ret;
+
+ vpu_dbg(LVL_INFO, "%s()\n", __func__);
+
+ if (reqbuf->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
+ q_data = &ctx->q_data[V4L2_SRC];
+ else if (reqbuf->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
+ q_data = &ctx->q_data[V4L2_DST];
+ else
+ return -EINVAL;
+
+ clear_vb2_buf(q_data);
+ if (reqbuf->count == 0)
+ ctx->buffer_null = true;
+ else
+ ctx->buffer_null = false;
+
+ ret = vpu_dec_queue_reqbufs(q_data, reqbuf);
+ if (ret) {
+ vpu_dbg(LVL_ERR, "error: %s() can't request (%d) buffer : %d\n",
+ __func__, reqbuf->count, ret);
+ return ret;
+ }
+ if (V4L2_TYPE_IS_OUTPUT(reqbuf->type))
+ return ret;
+
+ down(&q_data->drv_q_lock);
+ free_mbi_buffers(ctx);
+ ctx->mbi_count = 0;
+ ctx->mbi_num = min_t(u32, reqbuf->count, MAX_MBI_NUM);
+ if (ctx->mbi_num > 0) {
+ ctx->mbi_size = get_mbi_size(q_data);
+ alloc_mbi_buffer(ctx);
+ }
+ up(&q_data->drv_q_lock);
+ if (reqbuf->count > 0)
+ complete(&ctx->alloc_cmp);
+
+ return ret;
+}
+
+static int v4l2_ioctl_querybuf(struct file *file,
+ void *fh,
+ struct v4l2_buffer *buf
+ )
+{
+ struct vpu_ctx *ctx = v4l2_fh_to_ctx(fh);
+ struct queue_data *q_data;
+ unsigned int i;
+ int ret;
+
+ vpu_dbg(LVL_INFO, "%s()\n", __func__);
+
+ if (buf->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
+ q_data = &ctx->q_data[V4L2_SRC];
+ else if (buf->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
+ q_data = &ctx->q_data[V4L2_DST];
+ else
+ return -EINVAL;
+
+ ret = vpu_dec_queue_querybuf(q_data, buf);
+ if (!ret) {
+ if (buf->memory == V4L2_MEMORY_MMAP) {
+ if (V4L2_TYPE_IS_MULTIPLANAR(buf->type)) {
+ for (i = 0; i < buf->length; i++)
+ buf->m.planes[i].m.mem_offset |= (q_data->type << MMAP_BUF_TYPE_SHIFT);
+ } else
+ buf->m.offset |= (q_data->type << MMAP_BUF_TYPE_SHIFT);
+ }
+ } else
+ vpu_dbg(LVL_ERR, "error: %s() return ret=%d\n", __func__, ret);
+
+ return ret;
+}
+
+static int v4l2_ioctl_qbuf(struct file *file,
+ void *fh,
+ struct v4l2_buffer *buf
+ )
+{
+ struct vpu_ctx *ctx = v4l2_fh_to_ctx(fh);
+ struct queue_data *q_data;
+ struct vb2_data_req *p_data_req;
+ int ret;
+
+ vpu_dbg(LVL_INFO, "%s()\n", __func__);
+
+ if (buf->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
+ vpu_dbg(LVL_INFO, "%s: input %d bytes \n", __func__, buf->m.planes[0].bytesused);
+ q_data = &ctx->q_data[V4L2_SRC];
+ v4l2_update_stream_addr(ctx, 0);
+ } else if (buf->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
+ q_data = &ctx->q_data[V4L2_DST];
+ down(&q_data->drv_q_lock);
+ p_data_req = &q_data->vb2_reqs[buf->index];
+ p_data_req->data_offset[0] = buf->m.planes[0].data_offset;
+ p_data_req->data_offset[1] = buf->m.planes[1].data_offset;
+ up(&q_data->drv_q_lock);
+ }
+ else
+ return -EINVAL;
+
+ ret = vpu_dec_queue_qbuf(q_data, buf);
+ if (ret) {
+ vpu_dbg(LVL_ERR, "error: %s() return ret=%d\n", __func__, ret);
+ return ret;
+ }
+ if (!V4L2_TYPE_IS_OUTPUT(buf->type))
+ wake_up_interruptible(&ctx->buffer_wq);
+ v4l2_update_stream_addr(ctx, 0);
+
+ return ret;
+}
+
+static int v4l2_ioctl_dqbuf(struct file *file,
+ void *fh,
+ struct v4l2_buffer *buf
+ )
+{
+ struct vpu_ctx *ctx = v4l2_fh_to_ctx(fh);
+ struct queue_data *q_data;
+ int ret;
+
+ vpu_dbg(LVL_INFO, "%s()\n", __func__);
+
+ if (buf->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
+ q_data = &ctx->q_data[V4L2_SRC];
+ else if (buf->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
+ q_data = &ctx->q_data[V4L2_DST];
+ else
+ return -EINVAL;
+
+ ret = vpu_dec_queue_dqbuf(q_data, buf, file->f_flags & O_NONBLOCK);
+
+ if (!ret) {
+ if (q_data->vb2_reqs[buf->index].bfield)
+ buf->field = V4L2_FIELD_INTERLACED;
+ else
+ buf->field = V4L2_FIELD_NONE;
+ v4l2_update_stream_addr(ctx, 0);
+ if (buf->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
+ if ((ctx->pSeqinfo->uBitDepthLuma > 8) || (ctx->pSeqinfo->uBitDepthChroma > 8))
+ buf->reserved = 1;
+ } else
+ vpu_dbg(LVL_ERR, "error: %s() return ret=%d\n", __func__, ret);
+
+ return ret;
+}
+
+static bool format_is_support(struct vpu_v4l2_fmt *format_table,
+ unsigned int table_size,
+ struct v4l2_format *f)
+{
+ unsigned int i;
+
+ for (i = 0; i < table_size; i++) {
+ if (format_table[i].fourcc == f->fmt.pix_mp.pixelformat)
+ return true;
+ }
+ return false;
+}
+
+static int v4l2_ioctl_try_fmt(struct file *file,
+ void *fh,
+ struct v4l2_format *f
+ )
+{
+ unsigned int table_size;
+
+ if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
+ table_size = ARRAY_SIZE(formats_compressed_dec);
+ if (!format_is_support(formats_compressed_dec, table_size, f))
+ return -EINVAL;
+ } else if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
+ table_size = ARRAY_SIZE(formats_yuv_dec);
+ if (!format_is_support(formats_yuv_dec, table_size, f))
+ return -EINVAL;
+ } else
+ return -EINVAL;
+
+ return 0;
+}
+
+static int v4l2_ioctl_g_crop(struct file *file,
+ void *fh,
+ struct v4l2_crop *cr
+ )
+{
+ struct vpu_ctx *ctx = v4l2_fh_to_ctx(fh);
+
+ vpu_dbg(LVL_INFO, "%s()\n", __func__);
+ cr->c.left = ctx->pSeqinfo->uFrameCropLeftOffset;
+ cr->c.top = ctx->pSeqinfo->uFrameCropTopOffset;
+ cr->c.width = ctx->pSeqinfo->uHorRes;
+ cr->c.height = ctx->pSeqinfo->uVerRes;
+
+ return 0;
+}
+
+static int v4l2_ioctl_decoder_cmd(struct file *file,
+ void *fh,
+ struct v4l2_decoder_cmd *cmd
+ )
+{
+ struct vpu_ctx *ctx = v4l2_fh_to_ctx(fh);
+
+ vpu_dbg(LVL_INFO, "%s()\n", __func__);
+
+ switch (cmd->cmd) {
+ case V4L2_DEC_CMD_START:
+ break;
+ case V4L2_DEC_CMD_STOP: {
+ vpu_dbg(LVL_EVENT, "ctx[%d]: receive V4L2_DEC_CMD_STOP\n", ctx->str_index);
+ ctx->eos_stop_received = true;
+ v4l2_update_stream_addr(ctx, 0);
+ }
+ break;
+ case V4L2_DEC_CMD_PAUSE:
+ break;
+ case V4L2_DEC_CMD_RESUME:
+ break;
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static int v4l2_ioctl_streamon(struct file *file,
+ void *fh,
+ enum v4l2_buf_type i
+ )
+{
+ struct vpu_ctx *ctx = v4l2_fh_to_ctx(fh);
+ struct queue_data *q_data;
+ int ret;
+
+ vpu_dbg(LVL_INFO, "%s()\n", __func__);
+
+ if (i == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
+ q_data = &ctx->q_data[V4L2_SRC];
+ else if (i == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
+ q_data = &ctx->q_data[V4L2_DST];
+ else
+ return -EINVAL;
+
+ ctx->firmware_finished = false;
+
+ ret = vpu_dec_queue_enable(q_data, i);
+ if (!ret) {
+ if (i == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
+ wake_up_interruptible(&ctx->buffer_wq);
+
+ v4l2_update_stream_addr(ctx, 0);
+ } else
+ vpu_dbg(LVL_ERR, "error: %s() return ret=%d\n", __func__, ret);
+
+ if (ctx->hang_status) {
+ vpu_dbg(LVL_ERR, "%s(): not succeed and some instance are blocked\n", __func__);
+ return -EINVAL;
+ } else
+ return ret;
+}
+
+static int v4l2_ioctl_streamoff(struct file *file,
+ void *fh,
+ enum v4l2_buf_type i
+ )
+{
+ struct vpu_ctx *ctx = v4l2_fh_to_ctx(fh);
+ struct queue_data *q_data;
+ int ret;
+
+ vpu_dbg(LVL_EVENT, "%s(): ctx[%d] buf_type: %d\n",
+ __func__, ctx->str_index, i);
+
+ if (i == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
+ q_data = &ctx->q_data[V4L2_SRC];
+ else if (i == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
+ q_data = &ctx->q_data[V4L2_DST];
+ else
+ return -EINVAL;
+
+ if (i == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
+ if (ctx->firmware_stopped) {
+ vpu_dbg(LVL_ERR, "%s() - IGNORE - stopped(%d), finished(%d), eos_added(%d)\n",
+ __func__, ctx->firmware_stopped, ctx->firmware_finished, ctx->eos_stop_added);
+ } else {
+ int size;
+ ctx->wait_rst_done = true;
+ vpu_dbg(LVL_INFO, "%s(): send VID_API_CMD_ABORT\n", __func__);
+
+ size = add_scode(ctx, 0, BUFABORT_PADDING_TYPE, false);
+ record_log_info(ctx, LOG_PADDING, 0, 0);
+ if (size < 0)
+ vpu_dbg(LVL_ERR, "%s(): failed to fill abort padding data\n", __func__);
+ v4l2_vpu_send_cmd(ctx, ctx->str_index, VID_API_CMD_ABORT, 1, &size);
+
+ wake_up_interruptible(&ctx->buffer_wq);
+ if (!wait_for_completion_timeout(&ctx->completion, msecs_to_jiffies(1000))) {
+ ctx->hang_status = true;
+ vpu_dbg(LVL_ERR, "the path id:%d firmware timeout after send VID_API_CMD_ABORT, stopped(%d), finished(%d), eos_added(%d)\n",
+ ctx->str_index, ctx->firmware_stopped,
+ ctx->firmware_finished, ctx->eos_stop_added);
+ }
+ vpu_dbg(LVL_INFO, "receive abort done\n");
+ }
+ }
+
+ ret = vpu_dec_queue_disable(q_data, i);
+
+ if (ctx->hang_status) {
+ vpu_dbg(LVL_ERR, "%s(): not succeed and some instance are blocked\n", __func__);
+ return -EINVAL;
+ } else
+ return ret;
+}
+
+static const struct v4l2_ioctl_ops v4l2_decoder_ioctl_ops = {
+ .vidioc_querycap = v4l2_ioctl_querycap,
+ .vidioc_enum_fmt_vid_cap_mplane = v4l2_ioctl_enum_fmt_vid_cap_mplane,
+ .vidioc_enum_fmt_vid_out_mplane = v4l2_ioctl_enum_fmt_vid_out_mplane,
+ .vidioc_g_fmt_vid_cap_mplane = v4l2_ioctl_g_fmt,
+ .vidioc_g_fmt_vid_out_mplane = v4l2_ioctl_g_fmt,
+ .vidioc_try_fmt_vid_cap_mplane = v4l2_ioctl_try_fmt,
+ .vidioc_try_fmt_vid_out_mplane = v4l2_ioctl_try_fmt,
+ .vidioc_s_fmt_vid_cap_mplane = v4l2_ioctl_s_fmt,
+ .vidioc_s_fmt_vid_out_mplane = v4l2_ioctl_s_fmt,
+ .vidioc_expbuf = v4l2_ioctl_expbuf,
+ .vidioc_g_crop = v4l2_ioctl_g_crop,
+ .vidioc_decoder_cmd = v4l2_ioctl_decoder_cmd,
+ .vidioc_subscribe_event = v4l2_ioctl_subscribe_event,
+ .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
+ .vidioc_reqbufs = v4l2_ioctl_reqbufs,
+ .vidioc_querybuf = v4l2_ioctl_querybuf,
+ .vidioc_qbuf = v4l2_ioctl_qbuf,
+ .vidioc_dqbuf = v4l2_ioctl_dqbuf,
+ .vidioc_streamon = v4l2_ioctl_streamon,
+ .vidioc_streamoff = v4l2_ioctl_streamoff,
+};
+
+// Set/Get controls - v4l2 control framework
+
+static struct vpu_v4l2_control vpu_controls_dec[] = {
+ {
+ .id = V4L2_CID_MIN_BUFFERS_FOR_CAPTURE,
+ .minimum = 1,
+ .maximum = 32,
+ .step = 1,
+ .default_value = 4,
+ .is_volatile = true,
+ },
+};
+
+#define NUM_CTRLS_DEC ARRAY_SIZE(vpu_controls_dec)
+
+static int v4l2_custom_s_ctrl(struct v4l2_ctrl *ctrl)
+{
+ struct vpu_ctx *ctx = v4l2_ctrl_to_ctx(ctrl);
+
+ vpu_dbg(LVL_INFO, "%s() control(%d)\n",
+ __func__, ctrl->id);
+
+ switch (ctrl->id) {
+ case V4L2_CID_USER_RAW_BASE:
+ ctx->start_code_bypass = ctrl->val;
+ break;
+ default:
+ vpu_dbg(LVL_INFO, "%s() Invalid costomer control(%d)\n",
+ __func__, ctrl->id);
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static int v4l2_dec_g_v_ctrl(struct v4l2_ctrl *ctrl)
+{
+ struct vpu_ctx *ctx = v4l2_ctrl_to_ctx(ctrl);
+
+ vpu_dbg(LVL_INFO, "%s() control(%d)\n",
+ __func__, ctrl->id);
+
+ switch (ctrl->id) {
+ case V4L2_CID_MIN_BUFFERS_FOR_CAPTURE:
+ ctrl->val = ctx->pSeqinfo->uNumDPBFrms + ctx->pSeqinfo->uNumRefFrms;
+ break;
+ default:
+ vpu_dbg(LVL_INFO, "%s() Invalid control(%d)\n",
+ __func__, ctrl->id);
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static int add_dec_ctrl(struct vpu_ctx *This)
+{
+ static const struct v4l2_ctrl_ops vpu_dec_ctrl_ops = {
+ .g_volatile_ctrl = v4l2_dec_g_v_ctrl,
+ };
+ u_int32 i;
+
+ for (i = 0; i < NUM_CTRLS_DEC; i++) {
+ This->ctrls[i] = v4l2_ctrl_new_std(&This->ctrl_handler,
+ &vpu_dec_ctrl_ops,
+ vpu_controls_dec[i].id,
+ vpu_controls_dec[i].minimum,
+ vpu_controls_dec[i].maximum,
+ vpu_controls_dec[i].step,
+ vpu_controls_dec[i].default_value
+ );
+ if (This->ctrl_handler.error ||
+ !This->ctrls[i]) {
+ vpu_dbg(LVL_ERR, "%s() v4l2_ctrl_new_std failed(%d) This->ctrls[%d](%p)\n",
+ __func__, This->ctrl_handler.error, i, This->ctrls[i]);
+ return This->ctrl_handler.error;
+ }
+
+ if (vpu_controls_dec[i].is_volatile &&
+ This->ctrls[i])
+ This->ctrls[i]->flags |= V4L2_CTRL_FLAG_VOLATILE;
+ }
+
+ return 0;
+}
+
+static int add_custom_ctrl(struct vpu_ctx *This)
+{
+ static const struct v4l2_ctrl_ops vpu_custom_ctrl_ops = {
+ .s_ctrl = v4l2_custom_s_ctrl,
+ };
+ struct v4l2_ctrl_config cfg;
+ struct v4l2_ctrl *ctrl;
+
+ memset(&cfg, 0, sizeof(struct v4l2_ctrl_config));
+ cfg.ops = &vpu_custom_ctrl_ops;
+ cfg.id = V4L2_CID_USER_RAW_BASE;
+ cfg.name = "Raw Ctrl";
+ cfg.min = 0;
+ cfg.max = 1;
+ cfg.step = 1;
+ cfg.def = 0;
+ cfg.type = V4L2_CTRL_TYPE_INTEGER;
+
+ ctrl = v4l2_ctrl_new_custom(&This->ctrl_handler,
+ &cfg, NULL);
+ if (!ctrl) {
+ vpu_dbg(LVL_ERR, "Add custom ctrl fail\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int ctrls_setup_decoder(struct vpu_ctx *This)
+{
+ if (!This)
+ return -EINVAL;
+
+ v4l2_ctrl_handler_init(&This->ctrl_handler,
+ NUM_CTRLS_DEC + 1
+ );
+ if (This->ctrl_handler.error) {
+ vpu_dbg(LVL_ERR, "%s() v4l2_ctrl_handler_init failed(%d)\n",
+ __func__, This->ctrl_handler.error);
+
+ return This->ctrl_handler.error;
+ } else {
+ vpu_dbg(LVL_INFO, "%s() v4l2_ctrl_handler_init ctrls(%ld)\n",
+ __func__, NUM_CTRLS_DEC);
+ This->ctrl_inited = true;
+ }
+
+ add_dec_ctrl(This);
+ add_custom_ctrl(This);
+
+ v4l2_ctrl_handler_setup(&This->ctrl_handler);
+
+ return 0;
+}
+
+static void ctrls_delete_decoder(struct vpu_ctx *This)
+{
+ int i;
+
+ if (This->ctrl_inited) {
+ v4l2_ctrl_handler_free(&This->ctrl_handler);
+ This->ctrl_inited = false;
+ }
+ for (i = 0; i < NUM_CTRLS_DEC; i++)
+ This->ctrls[i] = NULL;
+}
+
+/* Insert either the codec specific EOS type or a special scode to mark that this frame should be flushed/pushed directly for decode */
+static int add_scode_vpu(struct vpu_ctx *ctx, u_int32 uStrBufIdx, VPU_PADDING_SCODE_TYPE eScodeType, bool bUpdateWr)
+{
+ struct vpu_dev *dev = ctx->dev;
+ pSTREAM_BUFFER_DESCRIPTOR_TYPE pStrBufDesc;
+ struct queue_data *q_data = &ctx->q_data[V4L2_SRC];
+ uint32_t start;
+ uint32_t end;
+ uint32_t wptr;
+ uint32_t rptr;
+ uint8_t *pbbuffer;
+ uint32_t *plbuffer;
+ uint32_t last;
+ uint32_t last2 = 0x0;
+ uint32_t pad_bytes = 0;
+ uint8_t *buffer;
+
+ vpu_dbg(LVL_INFO, "enter %s\n", __func__);
+ pStrBufDesc = ctx->dev->regs_base + DEC_MFD_XREG_SLV_BASE + MFD_MCX + MFD_MCX_OFF * ctx->str_index;
+ start = pStrBufDesc->start;
+ end = pStrBufDesc->end;
+ wptr = pStrBufDesc->wptr;
+ rptr = pStrBufDesc->rptr;
+
+ if (start != ctx->stream_buffer.dma_phy ||
+ end != ctx->stream_buffer.dma_phy + ctx->stream_buffer.dma_size) {
+ vpu_dbg(LVL_ERR, "error: %s(), start or end pointer cross-border\n", __func__);
+ return 0;
+ }
+ if (wptr < start || wptr > end) {
+ vpu_dbg(LVL_ERR, "error: %s(), wptr pointer cross-border\n", __func__);
+ return 0;
+ }
+ if (rptr < start || rptr > end) {
+ vpu_dbg(LVL_ERR, "error: %s(), rptr pointer cross-border\n", __func__);
+ return 0;
+ }
+
+ buffer = kzalloc(SCODE_SIZE, GFP_KERNEL); //for eos data
+ if (!buffer) {
+ vpu_dbg(LVL_ERR, "error: eos buffer alloc fail\n");
+ return -1;
+ }
+ atomic64_add(SCODE_SIZE, &ctx->statistic.total_alloc_size);
+ plbuffer = (uint32_t *)buffer;
+ if (wptr - start < ctx->stream_buffer.dma_size)
+ pbbuffer = (uint8_t *)(ctx->stream_buffer.dma_virt + wptr - start);
+ else {
+ vpu_dbg(LVL_ERR, "error: return wptr(0x%x), start(0x%x) is not valid\n", wptr, start);
+ return -1;
+ }
+
+ // Word align
+ if (((u_int64)pbbuffer)%4 != 0) {
+ int i;
+ if (end%4 != 0) {
+ vpu_dbg(LVL_ERR, "end address of stream not aligned by 4 bytes !\n");
+ return -1;
+ }
+ pad_bytes = 4 - (((u_int64)pbbuffer)%4);
+ for (i = 0; i < pad_bytes; i++)
+ pbbuffer[i] = 0;
+ pbbuffer += pad_bytes;
+ wptr += pad_bytes;
+ if (wptr == end) {
+ wptr = start;
+ pbbuffer = (uint8_t *)ctx->stream_buffer.dma_virt;
+ }
+ }
+
+ if (eScodeType == BUFABORT_PADDING_TYPE) {
+ switch (q_data->vdec_std) {
+ case VPU_VIDEO_AVC:
+ last = 0x0B010000;
+ break;
+ case VPU_VIDEO_VC1:
+ last = 0x0a010000;
+ break;
+ case VPU_VIDEO_MPEG2:
+ last = 0xb7010000;
+ break;
+ case VPU_VIDEO_ASP:
+ last = 0xb1010000;
+ break;
+ case VPU_VIDEO_SPK:
+ case VPU_VIDEO_VP6:
+ case VPU_VIDEO_VP8:
+ case VPU_VIDEO_RV:
+ last = 0x34010000;
+ break;
+ case VPU_VIDEO_HEVC:
+ last = 0x4A010000;
+ last2 = 0x20;
+ break;
+ case VPU_VIDEO_JPEG:
+ default:
+ last = 0x0;
+ break;
+ }
+ } else if (eScodeType == EOS_PADDING_TYPE) {
+ switch (q_data->vdec_std) {
+ case VPU_VIDEO_AVC:
+ last = 0x0B010000;
+ break;
+ case VPU_VIDEO_VC1:
+ last = 0x0a010000;
+ break;
+ case VPU_VIDEO_MPEG2:
+ last = EOS_GENERIC_MPEG;
+ break;
+ case VPU_VIDEO_ASP:
+ last = 0xb1010000;
+ break;
+ case VPU_VIDEO_SPK:
+ case VPU_VIDEO_VP6:
+ case VPU_VIDEO_VP8:
+ case VPU_VIDEO_RV:
+ last = 0x34010000;
+ break;
+ case VPU_VIDEO_JPEG:
+ last = EOS_GENERIC_JPEG;
+ break;
+ case VPU_VIDEO_HEVC:
+ last = 0x4A010000;
+ last2 = 0x20;
+ break;
+ default:
+ last = 0x0;
+ break;
+ }
+ } else {
+ if (q_data->vdec_std == VPU_VIDEO_AVC) {
+ last = 0x15010000;
+ last2 = 0x0;
+ } else {
+ /* all other standards do not support the frame flush mechanism so just return */
+ vpu_dbg(LVL_WARN, "warning: format(%d) not support frame flush mechanism !\n", q_data->vdec_std);
+ return 0;
+ }
+ }
+ plbuffer[0] = last;
+ plbuffer[1] = last2;
+
+ if ((wptr == rptr) || (wptr > rptr)) {
+ if (end - wptr >= SCODE_SIZE) {
+ memcpy(pbbuffer, buffer, SCODE_SIZE);
+ wptr += SCODE_SIZE;
+ if (wptr == end)
+ wptr = start;
+ } else {
+ memcpy(pbbuffer, buffer, end-wptr);
+ memcpy(ctx->stream_buffer.dma_virt, buffer + (end - wptr), SCODE_SIZE - (end - wptr));
+ wptr = start + SCODE_SIZE - (end - wptr);
+ }
+ pad_bytes += SCODE_SIZE;
+ } else {
+ if (rptr - wptr >= SCODE_SIZE) {
+ memcpy(pbbuffer, buffer, SCODE_SIZE);
+ wptr += SCODE_SIZE;
+ pad_bytes += SCODE_SIZE;
+ } else {
+ //shouldn't enter here: suppose space is enough since add_eos() only be called in FIFO LOW
+ vpu_dbg(LVL_ERR, "No enough space to insert EOS, size=%d !\n", rptr - wptr);
+ memcpy(pbbuffer, buffer, rptr - wptr);
+ wptr += (rptr - wptr);
+ pad_bytes += (rptr - wptr);
+ }
+ }
+ mb();
+
+ if (bUpdateWr)
+ pStrBufDesc->wptr = wptr;
+ dev->shared_mem.pSharedInterface->pStreamBuffDesc[ctx->str_index][uStrBufIdx] =
+ (VPU_REG_BASE + DEC_MFD_XREG_SLV_BASE + MFD_MCX + MFD_MCX_OFF * ctx->str_index);
+ kfree(buffer);
+ atomic64_sub(SCODE_SIZE, &ctx->statistic.total_alloc_size);
+ vpu_dbg(LVL_INFO, "%s() done type (%d) MCX address virt=%p, phy=0x%x, index=%d\n",
+ __func__, eScodeType, pStrBufDesc, dev->shared_mem.pSharedInterface->pStreamBuffDesc[ctx->str_index][uStrBufIdx], ctx->str_index);
+ return pad_bytes;
+}
+
+static int add_scode(struct vpu_ctx *ctx, u_int32 uStrBufIdx, VPU_PADDING_SCODE_TYPE eScodeType, bool bUpdateWr)
+{
+ int size = 0;
+
+ if (!ctx)
+ return 0;
+
+ mutex_lock(&ctx->instance_mutex);
+ size = add_scode_vpu(ctx, uStrBufIdx, eScodeType, bUpdateWr);
+ if (size > 0)
+ set_pic_end_flag(ctx);
+ mutex_unlock(&ctx->instance_mutex);
+ return size;
+}
+
+TB_API_DEC_FMT vpu_format_remap(uint32_t vdec_std)
+{
+ TB_API_DEC_FMT malone_format = VSys_FrmtNull;
+
+ switch (vdec_std) {
+ case VPU_VIDEO_AVC:
+ malone_format = VSys_AvcFrmt;
+ vpu_dbg(LVL_INFO, "format translated to AVC");
+ break;
+ case VPU_VIDEO_VC1:
+ malone_format = VSys_Vc1Frmt;
+ vpu_dbg(LVL_INFO, "format translated to VC1");
+ break;
+ case VPU_VIDEO_MPEG2:
+ malone_format = VSys_Mp2Frmt;
+ vpu_dbg(LVL_INFO, "format translated to MP2");
+ break;
+ case VPU_VIDEO_AVS:
+ malone_format = VSys_AvsFrmt;
+ vpu_dbg(LVL_INFO, "format translated to AVS");
+ break;
+ case VPU_VIDEO_ASP:
+ malone_format = VSys_AspFrmt;
+ vpu_dbg(LVL_INFO, "format translated to ASP");
+ break;
+ case VPU_VIDEO_JPEG:
+ malone_format = VSys_JpgFrmt;
+ vpu_dbg(LVL_INFO, "format translated to JPG");
+ break;
+ case VPU_VIDEO_VP6:
+ malone_format = VSys_Vp6Frmt;
+ vpu_dbg(LVL_INFO, "format translated to VP6");
+ break;
+ case VPU_VIDEO_SPK:
+ malone_format = VSys_SpkFrmt;
+ vpu_dbg(LVL_INFO, "format translated to SPK");
+ break;
+ case VPU_VIDEO_VP8:
+ malone_format = VSys_Vp8Frmt;
+ vpu_dbg(LVL_INFO, "format translated to VP8");
+ break;
+ case VPU_VIDEO_HEVC:
+ malone_format = VSys_HevcFrmt;
+ vpu_dbg(LVL_INFO, "format translated to HEVC");
+ break;
+ case VPU_VIDEO_RV:
+ malone_format = VSys_RvFrmt;
+ vpu_dbg(LVL_INFO, "format translated to RV");
+ break;
+ case VPU_VIDEO_AVC_MVC:
+ malone_format = VSys_AvcFrmt;
+ vpu_dbg(LVL_INFO, "format translated to AVC");
+ break;
+ default:
+ malone_format = VSys_FrmtNull;
+ vpu_dbg(LVL_INFO, "unspport format");
+ break;
+ }
+ vpu_dbg(LVL_INFO, "\n");
+
+ return malone_format;
+}
+
+static void v4l2_vpu_send_cmd(struct vpu_ctx *ctx, uint32_t idx, uint32_t cmdid, uint32_t cmdnum, uint32_t *local_cmddata)
+{
+ vpu_log_cmd(cmdid, idx);
+ count_cmd(&ctx->statistic, cmdid);
+ record_log_info(ctx, LOG_COMMAND, cmdid, 0);
+ mutex_lock(&ctx->dev->cmd_mutex);
+ rpc_send_cmd_buf(&ctx->dev->shared_mem, idx, cmdid, cmdnum, local_cmddata);
+ mutex_unlock(&ctx->dev->cmd_mutex);
+ mb();
+ MU_SendMessage(ctx->dev->mu_base_virtaddr, 0, COMMAND);
+}
+
+static void transfer_buffer_to_firmware(struct vpu_ctx *ctx, void *input_buffer, uint32_t buffer_size, uint32_t vdec_std)
+{
+ pSTREAM_BUFFER_DESCRIPTOR_TYPE pStrBufDesc;
+ u_int32 uStrBufIdx = 0; //set to be default 0, FIX_ME later
+ MediaIPFW_Video_UData *pUdataBuf =
+ &ctx->dev->shared_mem.pSharedInterface->UDataBuffer[ctx->str_index];
+ pDEC_RPC_HOST_IFACE pSharedInterface = ctx->dev->shared_mem.pSharedInterface;
+ unsigned int *CurrStrfg = &pSharedInterface->StreamConfig[ctx->str_index];
+ u_int32 length;
+ MediaIPFW_Video_CodecParams *pCodecPara;
+
+ vpu_dbg(LVL_INFO, "enter %s, start_flag %d, index=%d, firmware_started=%d\n",
+ __func__, ctx->start_flag, ctx->str_index, ctx->dev->firmware_started);
+
+ vpu_dbg(LVL_WARN, "firmware version is %d.%d.%d\n",
+ (pSharedInterface->FWVersion & 0x00ff0000) >> 16,
+ (pSharedInterface->FWVersion & 0x0000ff00) >> 8,
+ pSharedInterface->FWVersion & 0x000000ff);
+
+
+ if (ctx->stream_buffer.dma_size < buffer_size + MIN_SPACE) {
+ vpu_dbg(LVL_ERR, "circular buffer size is set too small\n");
+ return;
+ }
+ if (!ctx->start_code_bypass)
+ length = insert_scode_4_seq(ctx, input_buffer, ctx->stream_buffer.dma_virt, vdec_std, buffer_size);
+ else
+ length = 0;
+ if (length == 0) {
+ memcpy(ctx->stream_buffer.dma_virt, input_buffer, buffer_size);
+ length = buffer_size;
+ }
+ vpu_dbg(LVL_INFO, "transfer data from virt 0x%p: size:%d\n",
+ ctx->stream_buffer.dma_virt, buffer_size);
+ mb();
+ pStrBufDesc = ctx->dev->regs_base + DEC_MFD_XREG_SLV_BASE + MFD_MCX + MFD_MCX_OFF * ctx->str_index;
+ pStrBufDesc->wptr = ctx->stream_buffer.dma_phy + length;
+ pStrBufDesc->rptr = ctx->stream_buffer.dma_phy;
+ pStrBufDesc->start = ctx->stream_buffer.dma_phy;
+ pStrBufDesc->end = ctx->stream_buffer.dma_phy + ctx->stream_buffer.dma_size;
+ pStrBufDesc->LWM = 0x01;
+
+ ctx->dev->shared_mem.pSharedInterface->pStreamBuffDesc[ctx->str_index][uStrBufIdx] =
+ (VPU_REG_BASE + DEC_MFD_XREG_SLV_BASE + MFD_MCX + MFD_MCX_OFF * ctx->str_index);
+
+ vpu_dbg(LVL_INFO, "transfer MCX address virt=%p, phy=0x%x, index=%d\n",
+ pStrBufDesc, ctx->dev->shared_mem.pSharedInterface->pStreamBuffDesc[ctx->str_index][uStrBufIdx], ctx->str_index);
+ pUdataBuf->uUDataBase = ctx->udata_buffer.dma_phy;
+ pUdataBuf->uUDataSlotSize = ctx->udata_buffer.dma_size;
+ VID_STREAM_CONFIG_FORMAT_SET(vpu_format_remap(vdec_std), CurrStrfg);
+ if (vdec_std == VPU_VIDEO_JPEG) {
+ MediaIPFW_Video_JpegParams *pJpgPara;
+
+ pJpgPara = (MediaIPFW_Video_JpegParams *)ctx->dev->shared_mem.jpeg_mem_vir;
+ pJpgPara[ctx->str_index].uJpgMjpegMode = 1; //1:JPGD_MJPEG_MODE_A; 2:JPGD_MJPEG_MODE_B
+ pJpgPara[ctx->str_index].uJpgMjpegInterlaced = 0; //0: JPGD_MJPEG_PROGRESSIVE
+ }
+
+ pCodecPara = (MediaIPFW_Video_CodecParams *)ctx->dev->shared_mem.codec_mem_vir;
+ if (ctx->b_dis_reorder) {
+ /* set the shared memory space control with this */
+ add_scode(ctx, 0, BUFFLUSH_PADDING_TYPE, true);
+ record_log_info(ctx, LOG_PADDING, 0, 0);
+ pCodecPara[ctx->str_index].uDispImm = 1;
+ } else {
+ pCodecPara[ctx->str_index].uDispImm = 0;
+ }
+
+ pCodecPara[ctx->str_index].uEnableDbgLog = CHECK_BIT(vpu_frmdbg_ena, ctx->str_index) ? 1 : 0;
+ ctx->dev->shared_mem.pSharedInterface->DbgLogDesc.uDecStatusLogLevel = vpu_frmdbg_level;
+
+ /*initialize frame count*/
+ ctx->frm_dis_delay = 1;
+ ctx->frm_dec_delay = 1;
+ ctx->frm_total_num = 1;
+ fill_stream_buffer_info(ctx);
+}
+
+static void v4l2_transfer_buffer_to_firmware(struct queue_data *This, struct vb2_buffer *vb)
+{
+ struct vpu_ctx *ctx = container_of(This, struct vpu_ctx, q_data[V4L2_SRC]);
+ struct vb2_data_req *p_data_req;
+ void *data_mapped;
+ uint32_t buffer_size = vb->planes[0].bytesused;
+ int ret;
+
+ data_mapped = (void *)vb2_plane_vaddr(vb, 0);
+
+ if (ctx->start_flag == true) {
+ ret = alloc_vpu_buffer(ctx);
+ if (ret) {
+ vpu_dbg(LVL_ERR, "alloc vpu buffer fail\n");
+ return;
+ }
+ transfer_buffer_to_firmware(ctx, data_mapped, buffer_size, This->vdec_std);
+#ifdef HANDLE_EOS
+ if (vb->planes[0].bytesused < vb->planes[0].length)
+ vpu_dbg(LVL_INFO, "v4l2_transfer_buffer_to_firmware - set stream_feed_complete - DEBUG 1\n");
+#endif
+ v4l2_vpu_send_cmd(ctx, ctx->str_index, VID_API_CMD_START, 0, NULL);
+ p_data_req = list_first_entry(&This->drv_q,
+ typeof(*p_data_req), list);
+ list_del(&p_data_req->list);
+ p_data_req->queued = false;
+ if (p_data_req->vb2_buf)
+ vb2_buffer_done(p_data_req->vb2_buf,
+ VB2_BUF_STATE_DONE);
+ ctx->start_flag = false;
+ }
+}
+
+static u_int32 got_free_space(u_int32 wptr, u_int32 rptr, u_int32 start, u_int32 end)
+{
+ u_int32 freespace = 0;
+
+ if (wptr == rptr)
+ freespace = end - start;
+ if (wptr < rptr)
+ freespace = rptr - wptr;
+ if (wptr > rptr)
+ freespace = (end - wptr) + (rptr - start);
+ return freespace;
+}
+
+static int update_stream_addr(struct vpu_ctx *ctx, void *input_buffer, uint32_t buffer_size, uint32_t uStrBufIdx)
+{
+ struct vpu_dev *dev = ctx->dev;
+ uint32_t index = ctx->str_index;
+ pSTREAM_BUFFER_DESCRIPTOR_TYPE pStrBufDesc;
+ struct queue_data *q_data = &ctx->q_data[V4L2_SRC];
+ u_int8 payload_header[256] = {0};
+ uint32_t nfreespace = 0;
+ uint32_t wptr;
+ uint32_t rptr;
+ uint32_t start;
+ uint32_t end;
+ void *wptr_virt;
+ uint32_t ret = 1;
+ u_int32 length = 0;
+
+ vpu_dbg(LVL_INFO, "enter %s\n", __func__);
+
+ // changed to virtual address and back
+ pStrBufDesc = dev->regs_base + DEC_MFD_XREG_SLV_BASE + MFD_MCX + MFD_MCX_OFF * index;
+ vpu_dbg(LVL_INFO, "%s wptr(%x) rptr(%x) start(%x) end(%x) uStrBufIdx(%d)\n",
+ __func__,
+ pStrBufDesc->wptr,
+ pStrBufDesc->rptr,
+ pStrBufDesc->start,
+ pStrBufDesc->end,
+ uStrBufIdx
+ );
+ wptr = pStrBufDesc->wptr;
+ rptr = pStrBufDesc->rptr;
+
+ start = pStrBufDesc->start;
+ end = pStrBufDesc->end;
+
+ if (start != ctx->stream_buffer.dma_phy ||
+ end != ctx->stream_buffer.dma_phy + ctx->stream_buffer.dma_size) {
+ vpu_dbg(LVL_ERR, "error: %s(), start or end pointer cross-border\n", __func__);
+ return 0;
+ }
+ if (wptr < start || wptr > end) {
+ vpu_dbg(LVL_ERR, "error: %s(), wptr pointer cross-border\n", __func__);
+ return 0;
+ }
+ if (rptr < start || rptr > end) {
+ vpu_dbg(LVL_ERR, "error: %s(), rptr pointer cross-border\n", __func__);
+ return 0;
+ }
+ wptr_virt = (void *)ctx->stream_buffer.dma_virt + wptr - start;
+
+ vpu_dbg(LVL_INFO, "update_stream_addr down\n");
+
+ nfreespace = got_free_space(wptr, rptr, start, end);
+
+ if (!ctx->start_code_bypass)
+ length = insert_scode_4_pic(ctx, payload_header, input_buffer, q_data->vdec_std, buffer_size);
+ else
+ length = 0;
+
+ if (nfreespace - buffer_size - length < MIN_SPACE)
+ return 0;
+
+ if (nfreespace >= buffer_size + length) {
+ if ((wptr == rptr) || (wptr > rptr)) {
+ if (end - wptr >= length) {
+ memcpy(wptr_virt, payload_header, length);
+ wptr += length;
+ wptr_virt += length;
+ if (wptr == end) {
+ wptr = start;
+ wptr_virt = (void *)ctx->stream_buffer.dma_virt;
+ }
+ } else {
+ memcpy(wptr_virt, payload_header, end-wptr);
+ memcpy(ctx->stream_buffer.dma_virt, payload_header + (end-wptr), length - (end-wptr));
+ wptr = start + length - (end-wptr);
+ wptr_virt = (void *)ctx->stream_buffer.dma_virt + length - (end-wptr);
+ }
+ if (end - wptr >= buffer_size) {
+ memcpy(wptr_virt, input_buffer, buffer_size);
+ wptr += buffer_size;
+ if (wptr == end)
+ wptr = start;
+ } else {
+ memcpy(wptr_virt, input_buffer, end-wptr);
+ memcpy(ctx->stream_buffer.dma_virt, input_buffer + (end-wptr), buffer_size - (end-wptr));
+ wptr = start + buffer_size - (end-wptr);
+ }
+ } else {
+ memcpy(wptr_virt, payload_header, length);
+ wptr += length;
+ wptr_virt += length;
+ memcpy(wptr_virt, input_buffer, buffer_size);
+ wptr += buffer_size;
+ }
+ } else {
+ vpu_dbg(LVL_INFO, "buffer_full: the circular buffer freespace < buffer_size, treat as full");
+ return 0; //do not consider this situation now
+ }
+
+ mb();
+ pStrBufDesc->wptr = wptr;
+ vpu_dbg(LVL_INFO, "update_stream_addr up, wptr 0x%x\n", wptr);
+
+ dev->shared_mem.pSharedInterface->pStreamBuffDesc[index][uStrBufIdx] =
+ (VPU_REG_BASE + DEC_MFD_XREG_SLV_BASE + MFD_MCX + MFD_MCX_OFF * index);
+
+ vpu_dbg(LVL_INFO, "update address virt=%p, phy=0x%x, index=%d\n",
+ pStrBufDesc, dev->shared_mem.pSharedInterface->pStreamBuffDesc[ctx->str_index][uStrBufIdx], ctx->str_index);
+ return ret;
+}
+static int update_stream_addr_vpu(struct vpu_ctx *ctx, void *input_buffer, uint32_t buffer_size, uint32_t uStrBufIdx)
+{
+ int size = 0;
+
+ mutex_lock(&ctx->instance_mutex);
+ size = update_stream_addr(ctx, input_buffer, buffer_size, uStrBufIdx);
+ mutex_unlock(&ctx->instance_mutex);
+
+ return size;
+}
+
+static void fill_stream_buffer_info(struct vpu_ctx *ctx)
+{
+ pDEC_RPC_HOST_IFACE pSharedInterface = ctx->dev->shared_mem.pSharedInterface;
+ pBUFFER_INFO_TYPE buffer_info = &pSharedInterface->StreamBuffInfo[ctx->str_index];
+
+ if (!ctx)
+ return;
+
+ if (ctx->start_code_bypass)
+ buffer_info->stream_input_mode = NON_FRAME_LVL;
+ else
+ buffer_info->stream_input_mode = FRAME_LVL;
+
+ buffer_info->stream_pic_input_count = ctx->frm_total_num;
+}
+
+static void set_pic_end_flag(struct vpu_ctx *ctx)
+{
+ pDEC_RPC_HOST_IFACE pSharedInterface;
+ pBUFFER_INFO_TYPE buffer_info;
+
+ if (!ctx)
+ return;
+
+ pSharedInterface = ctx->dev->shared_mem.pSharedInterface;
+ buffer_info = &pSharedInterface->StreamBuffInfo[ctx->str_index];
+
+ if (buffer_info->stream_input_mode == FRAME_LVL)
+ buffer_info->stream_pic_end_flag = 0x1;
+}
+
+static void clear_pic_end_flag(struct vpu_ctx *ctx)
+{
+ pDEC_RPC_HOST_IFACE pSharedInterface;
+ pBUFFER_INFO_TYPE buffer_info;
+
+ if (!ctx)
+ return;
+
+ pSharedInterface = ctx->dev->shared_mem.pSharedInterface;
+ buffer_info = &pSharedInterface->StreamBuffInfo[ctx->str_index];
+
+ if (buffer_info->stream_input_mode == FRAME_LVL)
+ buffer_info->stream_pic_end_flag = 0x0;
+}
+
+//warn uStrIdx need to refine how to handle it
+static void v4l2_update_stream_addr(struct vpu_ctx *ctx, uint32_t uStrBufIdx)
+{
+ struct vb2_data_req *p_data_req;
+ struct queue_data *This = &ctx->q_data[V4L2_SRC];
+ void *input_buffer;
+ uint32_t buffer_size;
+
+ down(&This->drv_q_lock);
+ while (!list_empty(&This->drv_q)) {
+ if (vpu_frm_depth != INVALID_FRAME_DEPTH) //frame depth need to be set by user and then the condition works
+ if (ctx->frm_dec_delay >= vpu_frm_depth)
+ break;
+ p_data_req = list_first_entry(&This->drv_q,
+ typeof(*p_data_req), list);
+
+ if (!p_data_req->vb2_buf)
+ break;
+
+ buffer_size = p_data_req->vb2_buf->planes[0].bytesused;
+ input_buffer = (void *)vb2_plane_vaddr(p_data_req->vb2_buf, 0);
+ if (!update_stream_addr_vpu(ctx, input_buffer, buffer_size, uStrBufIdx)) {
+ up(&This->drv_q_lock);
+ vpu_dbg(LVL_INFO, " %s no space to write\n", __func__);
+ return;
+ } else {
+ if (ctx->b_dis_reorder) {
+ /* frame successfully written into the stream buffer if in special low latency mode
+ mark that this frame should be flushed for decode immediately */
+ add_scode(ctx, 0, BUFFLUSH_PADDING_TYPE, true);
+ record_log_info(ctx, LOG_PADDING, 0, 0);
+ }
+ ctx->frm_dec_delay++;
+ ctx->frm_dis_delay++;
+ ctx->frm_total_num++;
+ record_log_info(ctx, LOG_UPDATE_STREAM, 0, buffer_size);
+ fill_stream_buffer_info(ctx);
+ }
+#ifdef HANDLE_EOS
+ if (buffer_size < p_data_req->vb2_buf->planes[0].length)
+ vpu_dbg(LVL_INFO, "v4l2_transfer_buffer_to_firmware - set stream_feed_complete - DEBUG 2\n");
+#endif
+ list_del(&p_data_req->list);
+ p_data_req->queued = false;
+ if (p_data_req->vb2_buf)
+ vb2_buffer_done(p_data_req->vb2_buf,
+ VB2_BUF_STATE_DONE);
+ }
+ if (list_empty(&This->drv_q) && ctx->eos_stop_received) {
+ if (!ctx->firmware_stopped) {
+ vpu_dbg(LVL_EVENT, "ctx[%d]: insert eos directly\n", ctx->str_index);
+ if (add_scode(ctx, 0, EOS_PADDING_TYPE, true) >= 0) {
+ record_log_info(ctx, LOG_EOS, 0, 0);
+ ctx->eos_stop_received = false;
+ ctx->eos_stop_added = true;
+ }
+ } else {
+ vpu_dbg(LVL_ERR, "Firmware already stopped !\n");
+ }
+ }
+ up(&This->drv_q_lock);
+}
+
+static void report_buffer_done(struct vpu_ctx *ctx, void *frame_info)
+{
+ struct vb2_data_req *p_data_req;
+ struct queue_data *This = &ctx->q_data[V4L2_DST];
+ u_int32 *FrameInfo = (u_int32 *)frame_info;
+ u_int32 fs_id = FrameInfo[0x0];
+ uint32_t stride = FrameInfo[3];
+ bool b10BitFormat = (ctx->pSeqinfo->uBitDepthLuma > 8) || (ctx->pSeqinfo->uBitDepthChroma > 8);
+ int buffer_id;
+
+ vpu_dbg(LVL_INFO, "%s() fs_id=%d, ulFsLumaBase[0]=%x, stride=%d, b10BitFormat=%d, ctx->pSeqinfo->uBitDepthLuma=%d\n",
+ __func__, fs_id, FrameInfo[1], stride, b10BitFormat, ctx->pSeqinfo->uBitDepthLuma);
+ v4l2_update_stream_addr(ctx, 0);
+
+ buffer_id = find_buffer_id(ctx, FrameInfo[1]);
+ if (buffer_id == -1) {
+ vpu_dbg(LVL_ERR, "%s() ctx[%d] not find buffer id: %d, addr: 0x%x\n",
+ __func__, ctx->str_index, fs_id, FrameInfo[1]);
+ return;
+ }
+
+ if (buffer_id != fs_id) {
+ if (fs_id == MEDIA_PLAYER_SKIPPED_FRAME_ID) {
+ send_skip_event(ctx);
+ ctx->frm_dis_delay--;
+ return;
+ }
+ vpu_dbg(LVL_ERR, "error: find buffer_id(%d) and firmware return id(%d) doesn't match\n",
+ buffer_id, fs_id);
+ }
+ if (ctx->q_data[V4L2_DST].vb2_reqs[buffer_id].status != FRAME_DECODED)
+ vpu_dbg(LVL_ERR, "error: buffer(%d) need to set FRAME_READY, but previous state %s is not FRAME_DECODED\n",
+ buffer_id, bufstat[ctx->q_data[V4L2_DST].vb2_reqs[buffer_id].status]);
+
+ ctx->q_data[V4L2_DST].vb2_reqs[buffer_id].status = FRAME_READY;
+ ctx->frm_dis_delay--;
+ vpu_dbg(LVL_INFO, "frame total: %d; depth: %d; delay: [dec, dis] = [%d, %d]\n", ctx->frm_total_num,
+ vpu_frm_depth, ctx->frm_dec_delay, ctx->frm_dis_delay);
+
+ down(&This->drv_q_lock);
+ p_data_req = &This->vb2_reqs[buffer_id];
+ if (p_data_req->vb2_buf) {
+ p_data_req->vb2_buf->planes[0].bytesused = This->sizeimage[0];
+ p_data_req->vb2_buf->planes[1].bytesused = This->sizeimage[1];
+ if (p_data_req->vb2_buf->state == VB2_BUF_STATE_ACTIVE)
+ vb2_buffer_done(p_data_req->vb2_buf,
+ VB2_BUF_STATE_DONE
+ );
+ else
+ vpu_dbg(LVL_ERR, "warning: wait_rst_done(%d) check buffer(%d) state(%d)\n",
+ ctx->wait_rst_done, buffer_id, p_data_req->vb2_buf->state);
+ }
+ up(&This->drv_q_lock);
+ vpu_dbg(LVL_INFO, "leave %s\n", __func__);
+}
+
+/*
+ * this is used for waiting the right status buffer in the queue list
+ * true means find right buffer, false means not
+ */
+static bool wait_right_buffer(struct queue_data *This)
+{
+ struct vb2_data_req *p_data_req, *p_temp;
+
+ down(&This->drv_q_lock);
+ if (!list_empty(&This->drv_q)) {
+ list_for_each_entry_safe(p_data_req, p_temp, &This->drv_q, list)
+ if (p_data_req->status == FRAME_ALLOC
+ || p_data_req->status == FRAME_RELEASE) {
+ up(&This->drv_q_lock);
+ return true;
+ }
+ }
+ up(&This->drv_q_lock);
+
+ return false;
+}
+
+static void send_skip_event(struct vpu_ctx* ctx)
+{
+ const struct v4l2_event ev = {
+ .type = V4L2_EVENT_SKIP
+ };
+
+ if (!ctx)
+ return;
+ v4l2_event_queue_fh(&ctx->fh, &ev);
+}
+
+static void vpu_api_event_handler(struct vpu_ctx *ctx, u_int32 uStrIdx, u_int32 uEvent, u_int32 *event_data)
+{
+ struct vpu_dev *dev;
+ pDEC_RPC_HOST_IFACE pSharedInterface;
+ pSTREAM_BUFFER_DESCRIPTOR_TYPE pStrBufDesc;
+
+ vpu_log_event(uEvent, uStrIdx);
+ count_event(&ctx->statistic, uEvent);
+
+ pStrBufDesc = ctx->dev->regs_base + DEC_MFD_XREG_SLV_BASE + MFD_MCX + MFD_MCX_OFF * ctx->str_index;
+ record_log_info(ctx, LOG_EVENT, uEvent, pStrBufDesc->rptr);
+
+ if (ctx == NULL) {
+ vpu_dbg(LVL_ERR, "receive event: 0x%X after instance released, ignore it\n", uEvent);
+ return;
+ }
+
+ if (ctx->firmware_stopped && uEvent != VID_API_EVENT_START_DONE) {
+ vpu_dbg(LVL_ERR, "receive event: 0x%X after stopped, ignore it\n", uEvent);
+ return;
+ }
+ dev = ctx->dev;
+ pSharedInterface = (pDEC_RPC_HOST_IFACE)dev->shared_mem.shared_mem_vir;
+
+ switch (uEvent) {
+ case VID_API_EVENT_START_DONE:
+ ctx->firmware_stopped = false;
+ ctx->firmware_finished = false;
+ break;
+ case VID_API_EVENT_STOPPED: {
+ vpu_dbg(LVL_INFO, "receive VID_API_EVENT_STOPPED\n");
+ ctx->firmware_stopped = true;
+ ctx->start_flag = true;
+ complete(&ctx->completion);//reduce possibility of abort hang if decoder enter stop automatically
+ complete(&ctx->stop_cmp);
+ }
+ break;
+ case VID_API_EVENT_RESET_DONE:
+ break;
+ case VID_API_EVENT_PIC_DECODED: {
+ MediaIPFW_Video_QMeterInfo *pQMeterInfo = (MediaIPFW_Video_QMeterInfo *)dev->shared_mem.qmeter_mem_vir;
+ MediaIPFW_Video_PicInfo *pPicInfo = (MediaIPFW_Video_PicInfo *)dev->shared_mem.pic_mem_vir;
+ MediaIPFW_Video_PicDispInfo *pDispInfo = &pPicInfo[uStrIdx].DispInfo;
+ MediaIPFW_Video_PicPerfInfo *pPerfInfo = &pPicInfo[uStrIdx].PerfInfo;
+ MediaIPFW_Video_PicPerfDcpInfo *pPerfDcpInfo = &pPicInfo[uStrIdx].PerfDcpInfo;
+ int buffer_id;
+ u_int32 uDecFrmId = event_data[7];
+ u_int32 uPicStartAddr = event_data[10];
+ struct queue_data *This = &ctx->q_data[V4L2_DST];
+ u_int32 uDpbmcCrc;
+ size_t wr_size;
+
+ if (ctx->buffer_null == true) {
+ vpu_dbg(LVL_INFO, "frame already released\n");
+ break;
+ }
+
+ if (This->vdec_std == VPU_VIDEO_HEVC)
+ uDpbmcCrc = pPerfDcpInfo->uDBEDpbCRC[0];
+ else
+ uDpbmcCrc = pPerfInfo->uMemCRC;
+ if (vpu_frmcrcdump_ena) {
+ wr_size = kernel_write(ctx->crc_fp, &uDpbmcCrc, sizeof(uDpbmcCrc), &ctx->pos);
+ ctx->pos += wr_size;
+ }
+
+ vpu_dbg(LVL_INFO, "PICINFO GET: uPicType:%d uPicStruct:%d uPicStAddr:0x%x uFrameStoreID:%d uPercentInErr:%d, uRbspBytesCount=%d, ulLumBaseAddr[0]=%x, pQMeterInfo:%p, pPicInfo:%p, pDispInfo:%p, pPerfInfo:%p, pPerfDcpInfo:%p, uPicStartAddr=0x%x, uDpbmcCrc:%x\n",
+ pPicInfo[uStrIdx].uPicType, pPicInfo[uStrIdx].uPicStruct,
+ pPicInfo[uStrIdx].uPicStAddr, pPicInfo[uStrIdx].uFrameStoreID,
+ pPicInfo[uStrIdx].uPercentInErr, pPerfInfo->uRbspBytesCount, event_data[0],
+ pQMeterInfo, pPicInfo, pDispInfo, pPerfInfo, pPerfDcpInfo, uPicStartAddr, uDpbmcCrc);
+
+ buffer_id = find_buffer_id(ctx, event_data[0]);
+ if (buffer_id == -1) {
+ vpu_dbg(LVL_ERR, "error: %s() ctx[%d] not find buffer id: %d, addr: 0x%x\n",
+ __func__, ctx->str_index, uDecFrmId, event_data[0]);
+ break;
+ }
+
+ if (buffer_id != uDecFrmId) {
+ if (uDecFrmId == MEDIA_PLAYER_SKIPPED_FRAME_ID) {
+ send_skip_event(ctx);
+ ctx->frm_dec_delay--;
+ break;
+ }
+ vpu_dbg(LVL_ERR, "error: VID_API_EVENT_PIC_DECODED address and id doesn't match\n");
+ }
+ if (ctx->q_data[V4L2_DST].vb2_reqs[buffer_id].status != FRAME_FREE)
+ vpu_dbg(LVL_ERR, "error: buffer(%d) need to set FRAME_DECODED, but previous state %s is not FRAME_FREE\n",
+ buffer_id, bufstat[ctx->q_data[V4L2_DST].vb2_reqs[buffer_id].status]);
+ ctx->q_data[V4L2_DST].vb2_reqs[buffer_id].status = FRAME_DECODED;
+ if (ctx->pSeqinfo->uProgressive == 1)
+ ctx->q_data[V4L2_DST].vb2_reqs[buffer_id].bfield = false;
+ else
+ ctx->q_data[V4L2_DST].vb2_reqs[buffer_id].bfield = true;
+ }
+ ctx->frm_dec_delay--;
+ break;
+ case VID_API_EVENT_SEQ_HDR_FOUND: {
+ MediaIPFW_Video_SeqInfo *pSeqInfo = (MediaIPFW_Video_SeqInfo *)dev->shared_mem.seq_mem_vir;
+// MediaIPFW_Video_FrameBuffer *pStreamFrameBuffer = &pSharedInterface->StreamFrameBuffer[uStrIdx];
+// MediaIPFW_Video_FrameBuffer *pStreamDCPBuffer = &pSharedInterface->StreamDCPBuffer[uStrIdx];
+ MediaIPFW_Video_PitchInfo *pStreamPitchInfo = &pSharedInterface->StreamPitchInfo[uStrIdx];
+ unsigned int num = pSharedInterface->SeqInfoTabDesc.uNumSizeDescriptors;
+
+ if (ctx->pSeqinfo == NULL) {
+ ctx->pSeqinfo = kzalloc(sizeof(MediaIPFW_Video_SeqInfo), GFP_KERNEL);
+ atomic64_add(sizeof(MediaIPFW_Video_SeqInfo), &ctx->statistic.total_alloc_size);
+ }
+ else
+ vpu_dbg(LVL_INFO, "pSeqinfo is not NULL, need not to realloc\n");
+ memcpy(ctx->pSeqinfo, &pSeqInfo[ctx->str_index], sizeof(MediaIPFW_Video_SeqInfo));
+
+ caculate_frame_size(ctx);
+ vpu_dbg(LVL_INFO, "SEQINFO GET: uHorRes:%d uVerRes:%d uHorDecodeRes:%d uVerDecodeRes:%d uNumDPBFrms:%d, num:%d, uNumRefFrms:%d, uNumDFEAreas:%d\n",
+ ctx->pSeqinfo->uHorRes, ctx->pSeqinfo->uVerRes,
+ ctx->pSeqinfo->uHorDecodeRes, ctx->pSeqinfo->uVerDecodeRes,
+ ctx->pSeqinfo->uNumDPBFrms, num, ctx->pSeqinfo->uNumRefFrms, ctx->pSeqinfo->uNumDFEAreas);
+ if (ctx->b_firstseq) {
+ const struct v4l2_event ev = {
+ .type = V4L2_EVENT_SOURCE_CHANGE,
+ .u.src_change.changes = V4L2_EVENT_SRC_CH_RESOLUTION
+ };
+ v4l2_event_queue_fh(&ctx->fh, &ev);
+
+ pStreamPitchInfo->uFramePitch = 0x4000;
+ ctx->b_firstseq = false;
+ }
+ }
+ break;
+ case VID_API_EVENT_PIC_HDR_FOUND:
+ break;
+ case VID_API_EVENT_REQ_FRAME_BUFF: {
+ MEDIA_PLAYER_FSREQ *pFSREQ = (MEDIA_PLAYER_FSREQ *)event_data;
+ u_int32 local_cmddata[10];
+ struct vb2_data_req *p_data_req, *p_temp;
+ struct queue_data *This = &ctx->q_data[V4L2_DST];
+ u_int32 LumaAddr = 0;
+ u_int32 ChromaAddr = 0;
+ u_int32 *pphy_address;
+ struct vb2_data_req;
+ bool buffer_flag = false;
+
+ vpu_dbg(LVL_INFO, "VID_API_EVENT_REQ_FRAME_BUFF, type=%d, size=%ld\n", pFSREQ->eType, sizeof(MEDIA_PLAYER_FSREQ));
+ if (pFSREQ->eType == MEDIAIP_DCP_REQ) {
+ if (ctx->dcp_count >= MAX_DCP_NUM) {
+ vpu_dbg(LVL_ERR, "error: request dcp buffers number is over MAX_DCP_NUM\n");
+ break;
+ }
+ if (alloc_dcp_buffer(ctx, ctx->dcp_count))
+ break;
+
+ local_cmddata[0] = ctx->dcp_count | (ctx->pSeqinfo->uActiveSeqTag<<24);
+ local_cmddata[1] = ctx->dcp_buffer[ctx->dcp_count].dma_phy;
+ local_cmddata[2] = DCP_SIZE;
+ local_cmddata[3] = 0;
+ local_cmddata[4] = 0;
+ local_cmddata[5] = 0;
+ local_cmddata[6] = pFSREQ->eType;
+ v4l2_vpu_send_cmd(ctx, uStrIdx, VID_API_CMD_FS_ALLOC, 7, local_cmddata);
+ vpu_dbg(LVL_INFO, "VID_API_CMD_FS_ALLOC, ctx[%d] eType=%d, index=%d\n",
+ ctx->str_index, pFSREQ->eType, ctx->dcp_count);
+ ctx->dcp_count++;
+ } else if (pFSREQ->eType == MEDIAIP_MBI_REQ) {
+ if (ctx->mbi_count >= ctx->mbi_num) {
+ vpu_dbg(LVL_ERR, "error: request mbi buffers number(%d) is over allocted buffer number(%d)\n",
+ ctx->mbi_count, ctx->mbi_num);
+ break;
+ }
+ local_cmddata[0] = ctx->mbi_count | (ctx->pSeqinfo->uActiveSeqTag<<24);
+ local_cmddata[1] = ctx->mbi_buffer[ctx->mbi_count].dma_phy;
+ local_cmddata[2] = ctx->mbi_buffer[ctx->mbi_count].dma_size;
+ local_cmddata[3] = 0;
+ local_cmddata[4] = 0;
+ local_cmddata[5] = 0;
+ local_cmddata[6] = pFSREQ->eType;
+ v4l2_vpu_send_cmd(ctx, uStrIdx, VID_API_CMD_FS_ALLOC, 7, local_cmddata);
+ vpu_dbg(LVL_INFO, "VID_API_CMD_FS_ALLOC, ctx[%d] eType=%d, index=%d\n",
+ ctx->str_index, pFSREQ->eType, ctx->mbi_count);
+ ctx->mbi_count++;
+ } else {
+#if 1
+ while (1) {
+ if (!wait_event_interruptible_timeout(ctx->buffer_wq,
+ ((ctx->wait_rst_done == true) || (wait_right_buffer(This) == true)),
+ msecs_to_jiffies(5000))) {
+ vpu_dbg(LVL_ERR, " warn: wait_event_interruptible_timeout wait 5s timeout\n");
+ vpu_log_buffer_state(ctx);
+ } else
+ break;
+ }
+#endif
+
+ if (ctx->buffer_null == true) {
+ vpu_dbg(LVL_INFO, "frame already released\n");
+ break;
+ }
+
+ if (!list_empty(&This->drv_q) && !ctx->wait_rst_done) {
+ down(&This->drv_q_lock);
+ list_for_each_entry_safe(p_data_req, p_temp, &This->drv_q, list) {
+ if (p_data_req->status == FRAME_ALLOC
+ || p_data_req->status == FRAME_RELEASE){
+ if (!p_data_req->vb2_buf)
+ break;
+ pphy_address = (u_int32 *)vb2_plane_cookie(p_data_req->vb2_buf, 0);
+ if (pphy_address != NULL)
+ LumaAddr = *pphy_address + p_data_req->data_offset[0];
+ pphy_address = (u_int32 *)vb2_plane_cookie(p_data_req->vb2_buf, 1);
+ if (pphy_address != NULL)
+ ChromaAddr = *pphy_address + p_data_req->data_offset[1];
+ vpu_dbg(LVL_INFO, "%s :LumaAddr(%x) ChromaAddr(%x) buf_id (%d)\n",
+ __func__,
+ LumaAddr,
+ ChromaAddr,
+ p_data_req->id
+ );
+ if (!LumaAddr || !ChromaAddr) {
+ LumaAddr = p_data_req->phy_addr[0] + p_data_req->data_offset[0];
+ ChromaAddr = p_data_req->phy_addr[1] + p_data_req->data_offset[1];
+ }
+
+ local_cmddata[0] = p_data_req->id | (ctx->pSeqinfo->uActiveSeqTag<<24);
+ local_cmddata[1] = LumaAddr;
+ local_cmddata[2] = local_cmddata[1] + This->sizeimage[0]/2;
+ local_cmddata[3] = ChromaAddr;
+ local_cmddata[4] = local_cmddata[3] + This->sizeimage[1]/2;
+ local_cmddata[5] = ctx->q_data[V4L2_DST].stride;
+ local_cmddata[6] = pFSREQ->eType;
+ //WARN :need to check the call back VID_API_EVENT_REL_FRAME_BUFF later, when it is received, the corepond id can be released, now just do a temporary workaround
+ if (p_data_req->status == FRAME_RELEASE)
+ v4l2_vpu_send_cmd(ctx, uStrIdx, VID_API_CMD_FS_RELEASE, 1, local_cmddata);
+ v4l2_vpu_send_cmd(ctx, uStrIdx, VID_API_CMD_FS_ALLOC, 7, local_cmddata);
+ p_data_req->status = FRAME_FREE;
+ vpu_dbg(LVL_INFO, "VID_API_CMD_FS_ALLOC, ctx[%d] data_req->vb2_buf=%p, data_req->id=%d\n",
+ ctx->str_index, p_data_req->vb2_buf, p_data_req->id);
+ list_del(&p_data_req->list);
+ p_data_req->queued = false;
+ buffer_flag = true;
+ break;
+ } else {
+ vpu_dbg(LVL_INFO, "buffer %d status=0x%x is not right, find next\n", p_data_req->id, p_data_req->status);
+ continue;
+ }
+ }
+ up(&This->drv_q_lock);
+ if (buffer_flag == false && !ctx->firmware_finished)
+ vpu_dbg(LVL_ERR, "error: don't find the right buffer for VID_API_CMD_FS_ALLOC\n");
+ } else if (ctx->wait_rst_done) {
+ u_int32 i;
+
+ if (ctx->firmware_finished)
+ break;
+ down(&This->drv_q_lock);
+ for (i = 0; i < VPU_MAX_BUFFER; i++) {
+ p_data_req = &This->vb2_reqs[i];
+ if (p_data_req->status == FRAME_RELEASE)
+ break;
+ }
+ if (i == VPU_MAX_BUFFER || !p_data_req->vb2_buf) {
+ vpu_dbg(LVL_ERR, "error: don't find buffer when wait_rst_done is true, ctx->firmware_stopped=%dfin=%d\n", ctx->firmware_stopped, ctx->firmware_finished); //wait_rst_done is true when streamoff or v4l2_release is called
+ up(&This->drv_q_lock);
+ break;
+ }
+
+ pphy_address = (u_int32 *)vb2_plane_cookie(p_data_req->vb2_buf, 0);
+ if (pphy_address != NULL)
+ LumaAddr = *pphy_address + p_data_req->data_offset[0];
+ pphy_address = (u_int32 *)vb2_plane_cookie(p_data_req->vb2_buf, 1);
+ if (pphy_address != NULL)
+ ChromaAddr = *pphy_address + p_data_req->data_offset[1];
+ vpu_dbg(LVL_INFO, "%s :LumaAddr(%x) ChromaAddr(%x) buf_id (%d)\n",
+ __func__,
+ LumaAddr,
+ ChromaAddr,
+ p_data_req->id
+ );
+ if (!LumaAddr || !ChromaAddr) {
+ LumaAddr = p_data_req->phy_addr[0] + p_data_req->data_offset[0];
+ ChromaAddr = p_data_req->phy_addr[1] + p_data_req->data_offset[1];
+ }
+ local_cmddata[0] = p_data_req->id | (ctx->pSeqinfo->uActiveSeqTag<<24);
+ local_cmddata[1] = LumaAddr;
+ local_cmddata[2] = local_cmddata[1] + This->sizeimage[0]/2;
+ local_cmddata[3] = ChromaAddr;
+ local_cmddata[4] = local_cmddata[3] + This->sizeimage[1]/2;
+ local_cmddata[5] = ctx->q_data[V4L2_DST].stride;
+ local_cmddata[6] = pFSREQ->eType;
+ //WARN :need to check the call back VID_API_EVENT_REL_FRAME_BUFF later, when it is received, the corepond id can be released, now just do a temporary workaround
+ if (p_data_req->status == FRAME_RELEASE)
+ v4l2_vpu_send_cmd(ctx, uStrIdx, VID_API_CMD_FS_RELEASE, 1, local_cmddata);
+ v4l2_vpu_send_cmd(ctx, uStrIdx, VID_API_CMD_FS_ALLOC, 7, local_cmddata);
+ p_data_req->status = FRAME_FREE;
+ up(&This->drv_q_lock);
+ vpu_dbg(LVL_INFO, "VID_API_CMD_FS_ALLOC, ctx[%d] data_req->vb2_buf=%p, data_req->id=%d\n",
+ ctx->str_index, p_data_req->vb2_buf, p_data_req->id);
+ } else
+ vpu_dbg(LVL_ERR, "error: the list is still empty");
+ }
+ }
+ break;
+ case VID_API_EVENT_REL_FRAME_BUFF: {
+ MEDIA_PLAYER_FSREL *fsrel = (MEDIA_PLAYER_FSREL *)event_data;
+ struct queue_data *This = &ctx->q_data[V4L2_DST];
+ struct vb2_data_req *p_data_req;
+
+ if (ctx->buffer_null == true) {
+ vpu_dbg(LVL_INFO, "frame already released !!!!!!!!!!!!!!!!!\n");
+ break;
+ }
+
+ down(&This->drv_q_lock);
+ if (fsrel->eType == MEDIAIP_FRAME_REQ) {
+ p_data_req = &This->vb2_reqs[fsrel->uFSIdx];
+
+ if (ctx->wait_rst_done != true && p_data_req->status != FRAME_READY) {
+ const struct v4l2_event ev = {
+ .type = V4L2_EVENT_SKIP
+ };
+ vpu_dbg(LVL_WARN, "warning: normal release and previous status %s, frame not for display, queue the buffer to list again\n",
+ bufstat[p_data_req->status]);
+
+ if (p_data_req->status == FRAME_DECODED && p_data_req->queued == false) {
+ v4l2_event_queue_fh(&ctx->fh, &ev);
+ list_add_tail(&p_data_req->list, &This->drv_q);
+ p_data_req->queued = true;
+ }
+ }
+ p_data_req->status = FRAME_RELEASE;
+ } else if (fsrel->eType == MEDIAIP_MBI_REQ) {
+ vpu_dbg(LVL_INFO, "ctx[%d] relase MEDIAIP_MBI_REQ frame[%d]\n",
+ ctx->str_index, fsrel->uFSIdx);
+ } else if (fsrel->eType == MEDIAIP_DCP_REQ) {
+ vpu_dbg(LVL_INFO, "ctx[%d] relase MEDIAIP_DCP_REQ frame[%d]\n",
+ ctx->str_index, fsrel->uFSIdx);
+ } else {
+ vpu_dbg(LVL_WARN, "warning: ctx[%d] release unknown type frame!\n",
+ ctx->str_index);
+ }
+ up(&This->drv_q_lock);
+ vpu_dbg(LVL_INFO, "VID_API_EVENT_REL_FRAME_BUFF uFSIdx=%d, eType=%d, size=%ld\n",
+ fsrel->uFSIdx, fsrel->eType, sizeof(MEDIA_PLAYER_FSREL));
+ } break;
+ case VID_API_EVENT_FRAME_BUFF_RDY: {
+ u_int32 *FrameInfo = (u_int32 *)event_data;
+
+ //when the buffer is not NULL, do report_buffer_done
+ if (ctx->buffer_null == false)
+ report_buffer_done(ctx, FrameInfo);
+ }
+ break;
+ case VID_API_EVENT_CHUNK_DECODED:
+ break;
+ case VID_API_EVENT_FIFO_LOW: {
+ u_int32 uStrBufIdx = 0; //use buffer 0 for the stream
+
+ if (ctx->buffer_null == true) {
+ vpu_dbg(LVL_INFO, "frame already released !!!!!!!!!!!!!!!!!\n");
+ break;
+ }
+ v4l2_update_stream_addr(ctx, uStrBufIdx);
+ } break;
+ case VID_API_EVENT_FIFO_HIGH:
+ break;
+ case VID_API_EVENT_FIFO_EMPTY:
+ break;
+ case VID_API_EVENT_FIFO_FULL:
+ break;
+ case VID_API_EVENT_FIFO_OVF:
+ break;
+ case VID_API_EVENT_BS_ERROR:
+ break;
+ case VID_API_EVENT_UDATA_FIFO_UPTD:
+ break;
+ case VID_API_EVENT_DBG_STAT_UPDATE:
+ break;
+ case VID_API_EVENT_DBG_LOG_STARTED:
+ break;
+ case VID_API_EVENT_DBG_LOG_STOPPED:
+ break;
+ case VID_API_EVENT_ABORT_DONE: {
+ pSTREAM_BUFFER_DESCRIPTOR_TYPE pStrBufDesc;
+
+ pStrBufDesc = dev->regs_base + DEC_MFD_XREG_SLV_BASE + MFD_MCX + MFD_MCX_OFF * ctx->str_index;
+ vpu_dbg(LVL_INFO, "%s AbrtDone StrBuf Curr, wptr(%x) rptr(%x) start(%x) end(%x)\n",
+ __func__,
+ pStrBufDesc->wptr,
+ pStrBufDesc->rptr,
+ pStrBufDesc->start,
+ pStrBufDesc->end
+ );
+
+ pStrBufDesc->wptr = pStrBufDesc->rptr;
+ clear_pic_end_flag(ctx);
+ ctx->frm_dis_delay = 0;
+ ctx->frm_dec_delay = 0;
+ ctx->frm_total_num = 0;
+ v4l2_vpu_send_cmd(ctx, uStrIdx, VID_API_CMD_RST_BUF, 0, NULL);
+ }
+ break;
+ case VID_API_EVENT_RES_CHANGE: {
+ const struct v4l2_event ev = {
+ .type = V4L2_EVENT_SOURCE_CHANGE,
+ .u.src_change.changes = V4L2_EVENT_SRC_CH_RESOLUTION
+ };
+ vpu_dbg(LVL_WARN, "warning: ctx[%d] VID_API_EVENT_RES_CHANGE, seq id: %d\n",
+ ctx->str_index, ctx->pSeqinfo->uActiveSeqTag);
+ vpu_log_buffer_state(ctx);
+ v4l2_event_queue_fh(&ctx->fh, &ev);
+ reinit_completion(&ctx->alloc_cmp);
+ while (1) {
+ if (!wait_for_completion_timeout(&ctx->alloc_cmp, msecs_to_jiffies(1000))) {
+ vpu_dbg(LVL_WARN, "ctx[%d] warning: wait application alloc frame timeout\n",
+ ctx->str_index);
+ } else {
+ vpu_dbg(LVL_WARN, "ctx[%d] application alloc frame done\n",
+ ctx->str_index);
+ break;
+ }
+ }
+ }
+ break;
+ case VID_API_EVENT_STR_BUF_RST: {
+ pSTREAM_BUFFER_DESCRIPTOR_TYPE pStrBufDesc;
+ struct vb2_data_req *p_data_req;
+ struct queue_data *This;
+ u_int32 i;
+
+ pStrBufDesc = dev->regs_base + DEC_MFD_XREG_SLV_BASE + MFD_MCX + MFD_MCX_OFF * ctx->str_index;
+ vpu_dbg(LVL_INFO, "%s wptr(%x) rptr(%x) start(%x) end(%x)\n",
+ __func__,
+ pStrBufDesc->wptr,
+ pStrBufDesc->rptr,
+ pStrBufDesc->start,
+ pStrBufDesc->end
+ );
+ ctx->wait_rst_done = false;
+ This = &ctx->q_data[V4L2_DST];
+ down(&This->drv_q_lock);
+ for (i = 0; i < VPU_MAX_BUFFER; i++) {
+ p_data_req = &This->vb2_reqs[i];
+ if (p_data_req->vb2_buf != NULL)
+ if (p_data_req->status != FRAME_RELEASE)
+ vpu_dbg(LVL_INFO, "buffer(%d) status is %s when receive VID_API_EVENT_STR_BUF_RST\n",
+ i, bufstat[p_data_req->status]);
+ }
+ up(&This->drv_q_lock);
+ if (ctx->b_firstseq)
+ v4l2_vpu_send_cmd(ctx, ctx->str_index,
+ VID_API_CMD_STOP, 0, NULL);
+ else
+ complete(&ctx->completion);
+ }
+ break;
+ case VID_API_EVENT_RET_PING:
+ break;
+ case VID_API_EVENT_STR_FMT_CHANGE:
+ break;
+ case VID_API_EVENT_FINISHED: {
+ const struct v4l2_event ev = {
+ .type = V4L2_EVENT_EOS
+ };
+
+ if (ctx->eos_stop_added == false)
+ vpu_dbg(LVL_ERR, "warning: receive VID_API_EVENT_FINISHED before eos_stop_added set\n");
+ ctx->eos_stop_added = false;
+ if (ctx->firmware_finished == true)
+ vpu_dbg(LVL_ERR, "warning: receive VID_API_EVENT_FINISHED when firmware_finished == true\n");
+ ctx->firmware_finished = true;
+ vpu_dbg(LVL_INFO, "receive VID_API_EVENT_FINISHED and notfiy app eos\n");
+ clear_pic_end_flag(ctx);
+ vpu_log_buffer_state(ctx);
+ v4l2_event_queue_fh(&ctx->fh, &ev); //notfiy app stream eos reached
+
+ } break;
+ case VID_API_EVENT_FIRMWARE_XCPT: {
+ char *xcpt_info = (char*)event_data;
+ const struct v4l2_event ev = {
+ .type = V4L2_EVENT_EOS
+ };
+ vpu_dbg(LVL_ERR, "warning: VID_API_EVENT_FIRMWARE_XCPT,exception info: %s\n", xcpt_info);
+ ctx->hang_status = true;
+ v4l2_event_queue_fh(&ctx->fh, &ev);
+ }
+ break;
+ case VID_API_EVENT_DEC_CFG_INFO:
+ break;
+ default:
+ vpu_dbg(LVL_ERR, "warning: uEvent %d is not handled\n", uEvent);
+ break;
+ }
+ vpu_dbg(LVL_INFO, "leave %s, uEvent %d\n", __func__, uEvent);
+}
+
+
+
+//This code is added for MU
+
+static irqreturn_t fsl_vpu_mu_isr(int irq, void *This)
+{
+ struct vpu_dev *dev = This;
+ u32 msg;
+
+ MU_ReceiveMsg(dev->mu_base_virtaddr, 0, &msg);
+ if (msg == 0xaa) {
+ rpc_init_shared_memory(&dev->shared_mem, dev->m0_rpc_phy - dev->m0_p_fw_space_phy, dev->m0_rpc_virt, dev->m0_rpc_size);
+ rpc_set_system_cfg_value(dev->shared_mem.pSharedInterface, VPU_REG_BASE);
+
+ MU_sendMesgToFW(dev->mu_base_virtaddr, RPC_BUF_OFFSET, dev->m0_rpc_phy - dev->m0_p_fw_space_phy); //CM0 use relative address
+ MU_sendMesgToFW(dev->mu_base_virtaddr, BOOT_ADDRESS, dev->m0_p_fw_space_phy);
+ MU_sendMesgToFW(dev->mu_base_virtaddr, INIT_DONE, 2);
+
+ } else if (msg == 0x55) {
+ dev->firmware_started = true;
+ complete(&dev->start_cmp);
+ } else if (msg == 0xA5) {
+ /*receive snapshot done msg and wakeup complete to suspend*/
+ complete(&dev->snap_done_cmp);
+ } else
+ schedule_work(&dev->msg_work);
+
+ return IRQ_HANDLED;
+}
+
+/* Initialization of the MU code. */
+static int vpu_mu_init(struct vpu_dev *dev)
+{
+ struct device_node *np;
+ unsigned int vpu_mu_id;
+ u32 irq;
+ int ret = 0;
+
+ /*
+ * Get the address of MU to be used for communication with the M0 core
+ */
+ np = of_find_compatible_node(NULL, NULL, "fsl,imx8-mu0-vpu-m0");
+ if (!np) {
+ vpu_dbg(LVL_ERR, "error: Cannot find MU entry in device tree\n");
+ return -EINVAL;
+ }
+ dev->mu_base_virtaddr = of_iomap(np, 0);
+ WARN_ON(!dev->mu_base_virtaddr);
+
+ ret = of_property_read_u32_index(np,
+ "fsl,vpu_ap_mu_id", 0, &vpu_mu_id);
+ if (ret) {
+ vpu_dbg(LVL_ERR, "error: Cannot get mu_id %d\n", ret);
+ return -EINVAL;
+ }
+
+ dev->vpu_mu_id = vpu_mu_id;
+
+ irq = of_irq_get(np, 0);
+
+ ret = devm_request_irq(&dev->plat_dev->dev, irq, fsl_vpu_mu_isr,
+ IRQF_EARLY_RESUME, "vpu_mu_isr", (void *)dev);
+ if (ret) {
+ vpu_dbg(LVL_ERR, "error: request_irq failed %d, error = %d\n", irq, ret);
+ return -EINVAL;
+ }
+
+ if (!dev->vpu_mu_init) {
+ MU_Init(dev->mu_base_virtaddr);
+ MU_EnableRxFullInt(dev->mu_base_virtaddr, 0);
+ dev->vpu_mu_init = 1;
+ }
+
+ return ret;
+}
+
+static int release_hang_instance(struct vpu_dev *dev)
+{
+ u_int32 i;
+
+ if (!dev)
+ return -EINVAL;
+
+ for (i = 0; i < VPU_MAX_NUM_STREAMS; i++)
+ if (dev->ctx[i]) {
+ remove_instance_file(dev->ctx[i]);
+ destroy_log_info_queue(dev->ctx[i]);
+ if (atomic64_read(&dev->ctx[i]->statistic.total_alloc_size) != 0)
+ vpu_dbg(LVL_ERR, "error: memory leak for vpu kalloc buffer\n");
+ kfree(dev->ctx[i]);
+ dev->ctx[i] = NULL;
+ }
+
+ return 0;
+}
+
+static int get_reset_index(struct vpu_dev *dev)
+{
+ int idx;
+
+ for (idx = 0; idx < VPU_MAX_NUM_STREAMS; idx++)
+ if (CHECK_BIT(dev->instance_mask, idx))
+ break;
+
+ return idx;
+}
+
+/*
+ * Add judge to find if it has available path to decode, if all
+ * path hang, reset vpu and then get one index
+ */
+static int vpu_next_free_instance(struct vpu_dev *dev)
+{
+ int idx;
+
+ if (dev->hang_mask == dev->instance_mask
+ && dev->instance_mask != 0) {
+ idx = get_reset_index(dev);
+ if (idx < 0 || idx >= VPU_MAX_NUM_STREAMS)
+ return -EBUSY;
+ else {
+ if (swreset_vpu_firmware(dev, idx))
+ return -EINVAL;
+ release_hang_instance(dev);
+ }
+ dev->hang_mask = 0;
+ dev->instance_mask = 0;
+ }
+
+ idx = ffz(dev->instance_mask);
+ if (idx < 0 || idx >= VPU_MAX_NUM_STREAMS)
+ return -EBUSY;
+
+ kfree(dev->ctx[idx]);
+ dev->ctx[idx] = NULL;
+
+ return idx;
+}
+
+static void send_msg_queue(struct vpu_ctx *ctx, struct event_msg *msg)
+{
+ u_int32 ret;
+
+ ret = kfifo_in(&ctx->msg_fifo, msg, sizeof(u_int32) * (MSG_WORD_LENGTH + msg->msgnum));
+ if (ret != sizeof(u_int32) * (MSG_WORD_LENGTH + msg->msgnum))
+ vpu_dbg(LVL_ERR, "There is no memory for msg fifo, ret=%d\n", ret);
+}
+
+static bool receive_msg_queue(struct vpu_ctx *ctx, struct event_msg *msg)
+{
+ u_int32 ret;
+
+ if (kfifo_len(&ctx->msg_fifo) >= sizeof(u_int32) * MSG_WORD_LENGTH) {
+ ret = kfifo_out(&ctx->msg_fifo, msg, sizeof(u_int32) * MSG_WORD_LENGTH);
+ if (ret != sizeof(u_int32) * MSG_WORD_LENGTH) {
+ vpu_dbg(LVL_ERR, "kfifo_out msg word has error, ret=%d\n", ret);
+ return false;
+ } else {
+ if (msg->msgnum > 0) {
+ if (kfifo_len(&ctx->msg_fifo) >= sizeof(u_int32) * msg->msgnum) {
+ ret = kfifo_out(&ctx->msg_fifo, msg->msgdata, sizeof(u_int32) * msg->msgnum);
+ if (ret != sizeof(u_int32) * msg->msgnum) {
+ vpu_dbg(LVL_ERR, "kfifo_out msg data has error, ret=%d\n", ret);
+ return false;
+ } else
+ return true;
+ } else
+ return false;
+ } else
+ return true;
+ }
+ } else
+ return false;
+}
+
+extern u_int32 rpc_MediaIPFW_Video_message_check(struct shared_addr *This);
+static void vpu_msg_run_work(struct work_struct *work)
+{
+ struct vpu_dev *dev = container_of(work, struct vpu_dev, msg_work);
+ struct vpu_ctx *ctx;
+ struct event_msg msg;
+ struct shared_addr *This = &dev->shared_mem;
+
+ if (!dev || !This)
+ return;
+
+ memset(&msg, 0, sizeof(struct event_msg));
+
+ while (rpc_MediaIPFW_Video_message_check(This) == API_MSG_AVAILABLE) {
+ rpc_receive_msg_buf(This, &msg);
+ mutex_lock(&dev->dev_mutex);
+ ctx = dev->ctx[msg.idx];
+ if (ctx != NULL) {
+ mutex_lock(&ctx->instance_mutex);
+ if (!ctx->ctx_released) {
+ send_msg_queue(ctx, &msg);
+ queue_work(ctx->instance_wq, &ctx->instance_work);
+ }
+ mutex_unlock(&ctx->instance_mutex);
+ }
+ mutex_unlock(&dev->dev_mutex);
+ }
+ if (rpc_MediaIPFW_Video_message_check(This) == API_MSG_BUFFER_ERROR)
+ vpu_dbg(LVL_ERR, "error: message size is too big to handle\n");
+}
+static void vpu_msg_instance_work(struct work_struct *work)
+{
+ struct vpu_ctx *ctx = container_of(work, struct vpu_ctx, instance_work);
+ struct event_msg msg;
+
+ if (!ctx)
+ return;
+
+ memset(&msg, 0, sizeof(struct event_msg));
+
+ while (receive_msg_queue(ctx, &msg))
+ vpu_api_event_handler(ctx, msg.idx, msg.msgid, msg.msgdata);
+}
+
+static int vpu_queue_setup(struct vb2_queue *vq,
+ unsigned int *buf_count,
+ unsigned int *plane_count,
+ unsigned int psize[],
+ struct device *allocators[])
+{
+ struct queue_data *This = (struct queue_data *)vq->drv_priv;
+
+ vpu_dbg(LVL_INFO, "%s() is called\n", __func__);
+
+ if ((vq->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) ||
+ (vq->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ ) {
+ if (vq->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
+ *plane_count = 2;
+ psize[0] = This->sizeimage[0];//check alignment
+ psize[1] = This->sizeimage[1];//check colocated_size
+ } else {
+ psize[0] = This->sizeimage[0] + This->sizeimage[1];
+ *plane_count = 1;
+ }
+ } else {
+ *plane_count = 1;
+ psize[0] = This->sizeimage[0];
+ }
+ return 0;
+}
+
+static int vpu_buf_prepare(struct vb2_buffer *vb)
+{
+ vpu_dbg(LVL_INFO, "%s() is called\n", __func__);
+
+ return 0;
+}
+
+
+static int vpu_start_streaming(struct vb2_queue *q,
+ unsigned int count
+ )
+{
+ int ret = 0;
+
+ vpu_dbg(LVL_INFO, "%s() is called\n", __func__);
+ return ret;
+}
+
+
+static void vpu_stop_streaming(struct vb2_queue *q)
+{
+ struct queue_data *queue = (struct queue_data *)q->drv_priv;
+
+ vpu_dbg(LVL_INFO, "%s() is called\n", __func__);
+ clear_queue(queue);
+}
+
+static void vpu_buf_queue(struct vb2_buffer *vb)
+{
+ struct vb2_queue *vq = vb->vb2_queue;
+ struct queue_data *This = (struct queue_data *)vq->drv_priv;
+ struct vb2_data_req *data_req;
+ u_int32 *pphy_address;
+
+ vpu_dbg(LVL_INFO, "%s() is called\n", __func__);
+
+ vpu_dbg(LVL_INFO, "%s(), vq->type=%d, vb->index=%d\n",
+ __func__, vq->type, vb->index);
+
+ data_req = &This->vb2_reqs[vb->index];
+ data_req->vb2_buf = vb;
+ data_req->id = vb->index;
+ if (vq->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
+ pphy_address = (u_int32 *)vb2_plane_cookie(vb, 0);
+ data_req->phy_addr[0] = *pphy_address;
+ pphy_address = (u_int32 *)vb2_plane_cookie(vb, 1);
+ data_req->phy_addr[1] = *pphy_address;
+ }
+ if (data_req->status != FRAME_FREE && data_req->status != FRAME_DECODED) {
+ list_add_tail(&data_req->list, &This->drv_q);
+ data_req->queued = true;
+ }
+ if (V4L2_TYPE_IS_OUTPUT(vq->type))
+ v4l2_transfer_buffer_to_firmware(This, vb);
+}
+
+static void vpu_prepare(struct vb2_queue *q)
+{
+ vpu_dbg(LVL_INFO, "%s() is called\n", __func__);
+}
+
+static void vpu_finish(struct vb2_queue *q)
+{
+ vpu_dbg(LVL_INFO, "%s() is called\n", __func__);
+}
+
+struct vb2_ops v4l2_qops = {
+ .queue_setup = vpu_queue_setup,
+ .wait_prepare = vpu_prepare,
+ .wait_finish = vpu_finish,
+ .buf_prepare = vpu_buf_prepare,
+ .start_streaming = vpu_start_streaming,
+ .stop_streaming = vpu_stop_streaming,
+ .buf_queue = vpu_buf_queue,
+};
+
+static void init_vb2_queue(struct queue_data *This, unsigned int type, struct vpu_ctx *ctx)
+{
+ struct vb2_queue *vb2_q = &This->vb2_q;
+ int ret;
+ u_int32 i;
+
+ vpu_dbg(LVL_INFO, "%s()\n", __func__);
+
+ for (i = 0; i < VPU_MAX_BUFFER; i++)
+ This->vb2_reqs[i].status = 0;
+ // initialze driver queue
+ INIT_LIST_HEAD(&This->drv_q);
+ // initialize vb2 queue
+ vb2_q->type = type;
+ vb2_q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF;
+ vb2_q->gfp_flags = GFP_DMA32;
+ vb2_q->ops = &v4l2_qops;
+ vb2_q->drv_priv = This;
+ vb2_q->mem_ops = (struct vb2_mem_ops *)&vb2_dma_contig_memops;
+ vb2_q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
+ vb2_q->dev = &ctx->dev->plat_dev->dev;
+ ret = vb2_queue_init(vb2_q);
+ if (ret)
+ vpu_dbg(LVL_ERR, "error: %s vb2_queue_init() failed (%d)!\n",
+ __func__, ret);
+ else
+ This->vb2_q_inited = true;
+}
+
+static void init_queue_data(struct vpu_ctx *ctx)
+{
+ init_vb2_queue(&ctx->q_data[V4L2_SRC], V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, ctx);
+ ctx->q_data[V4L2_SRC].type = V4L2_SRC;
+ sema_init(&ctx->q_data[V4L2_SRC].drv_q_lock, 1);
+ init_vb2_queue(&ctx->q_data[V4L2_DST], V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, ctx);
+ ctx->q_data[V4L2_DST].type = V4L2_DST;
+ sema_init(&ctx->q_data[V4L2_DST].drv_q_lock, 1);
+}
+
+static void release_queue_data(struct vpu_ctx *ctx)
+{
+ vpu_dec_queue_release(&ctx->q_data[V4L2_SRC]);
+ vpu_dec_queue_release(&ctx->q_data[V4L2_DST]);
+}
+
+static void enable_csr_reg(struct vpu_dev *This)
+{
+ writel(This->m0_p_fw_space_phy, This->csr_base);
+ writel(0x0, This->csr_base + 4);
+}
+
+static int vpu_firmware_download(struct vpu_dev *This)
+{
+ unsigned char *image;
+ unsigned int FW_Size = 0;
+ int ret = 0;
+ char *p = This->m0_p_fw_space_vir;
+
+ ret = request_firmware((const struct firmware **)&This->m0_pfw,
+ M0FW_FILENAME,
+ This->generic_dev
+ );
+
+ if (ret) {
+ vpu_dbg(LVL_ERR, "error: %s() request fw %s failed(%d)\n",
+ __func__, M0FW_FILENAME, ret);
+
+ if (This->m0_pfw) {
+ release_firmware(This->m0_pfw);
+ This->m0_pfw = NULL;
+ }
+ return ret;
+ } else {
+ vpu_dbg(LVL_INFO, "%s() request fw %s got size(%d)\n",
+ __func__, M0FW_FILENAME, (int)This->m0_pfw->size);
+ image = (uint8_t *)This->m0_pfw->data;
+ FW_Size = This->m0_pfw->size;
+ }
+ memcpy(This->m0_p_fw_space_vir,
+ image,
+ FW_Size
+ );
+
+ p[16] = This->plat_type;
+ p[18] = 1;
+ enable_csr_reg(This);
+
+ return ret;
+}
+
+static int dbglog_show(struct seq_file *s, void *data)
+{
+#define DBG_UNIT_SIZE (7)
+
+ struct vpu_ctx *ctx = (struct vpu_ctx *)s->private;
+ u_int32 *pbuf;
+ u_int32 i, line;
+#if 0
+ seq_printf(s, "dbg log buffer:\n");
+#endif
+ pbuf = (u_int32 *)ctx->dev->shared_mem.dbglog_mem_vir;
+ line = (DBGLOG_SIZE) / (DBG_UNIT_SIZE * 4);
+ for (i = 0; i < line; i++) {
+#if 0
+ seq_printf(s, "[%03d]:%08X %08X %08X %08X-%08X %08X %08X\n",
+ i, pbuf[0], pbuf[1], pbuf[2], pbuf[3], pbuf[4], pbuf[5], pbuf[6]);
+#else
+ seq_printf(s, "%08x %08x %08x %08x %08x %08x %08x\n",
+ pbuf[0], pbuf[1], pbuf[2], pbuf[3], pbuf[4], pbuf[5], pbuf[6]);
+#endif
+ pbuf += 7;
+ }
+ return 0;
+}
+
+static int dbglog_open(struct inode *inode, struct file *filp)
+{
+ return single_open(filp, dbglog_show, inode->i_private);
+}
+
+static struct file_operations dbglog_fops = {
+ .owner = THIS_MODULE,
+ .open = dbglog_open,
+ .read = seq_read,
+};
+
+static int create_instance_dbglog_file(struct vpu_ctx *ctx)
+{
+ if (ctx->dev->debugfs_root == NULL)
+ ctx->dev->debugfs_root = debugfs_create_dir("vpu", NULL);
+
+ scnprintf(ctx->dbglog_name, sizeof(ctx->dbglog_name) - 1,
+ "instance%d",
+ ctx->str_index);
+
+ ctx->dbglog_dir = debugfs_create_dir(ctx->dbglog_name, ctx->dev->debugfs_root);
+ if (!ctx->dbglog_dir) {
+ vpu_dbg(LVL_ERR, "error: %s() ctx->dbglog_dir == NULL\n", __func__);
+ return -EINVAL;
+ }
+ debugfs_create_file("dbglog", VERIFY_OCTAL_PERMISSIONS(0444),
+ ctx->dbglog_dir, ctx, &dbglog_fops);
+
+ return 0;
+}
+
+
+static ssize_t show_instance_command_info(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct vpu_ctx *ctx;
+ struct vpu_statistic *statistic;
+ int i, size, num = 0;
+
+ ctx = container_of(attr, struct vpu_ctx, dev_attr_instance_command);
+ statistic = &ctx->statistic;
+
+ num += scnprintf(buf + num, PAGE_SIZE - num, "command number:\n");
+ for (i = VID_API_CMD_NULL; i < VID_API_CMD_YUV_READY + 1; i++) {
+ size = scnprintf(buf + num, PAGE_SIZE - num,
+ "\t%40s(%2d):%16ld\n",
+ cmd2str[i], i, statistic->cmd[i]);
+ num += size;
+ }
+
+ num += scnprintf(buf + num, PAGE_SIZE - num, "\t%40s :%16ld\n",
+ "UNKNOWN COMMAND", statistic->cmd[VID_API_CMD_YUV_READY + 1]);
+
+ num += scnprintf(buf + num, PAGE_SIZE - num, "current command:\n");
+ num += scnprintf(buf + num, PAGE_SIZE - num,
+ "%10s:%40s;%10ld.%06ld\n", "command",
+ get_cmd_str(statistic->current_cmd),
+ statistic->ts_cmd.tv_sec,
+ statistic->ts_cmd.tv_nsec / 1000);
+
+ return num;
+}
+
+static ssize_t show_instance_event_info(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct vpu_ctx *ctx;
+ struct vpu_statistic *statistic;
+ int i, size, num = 0;
+
+ ctx = container_of(attr, struct vpu_ctx, dev_attr_instance_event);
+ statistic = &ctx->statistic;
+
+ num += scnprintf(buf + num, PAGE_SIZE - num, "event number:\n");
+ for (i = VID_API_EVENT_NULL; i < VID_API_EVENT_DEC_CFG_INFO + 1; i++) {
+ size = scnprintf(buf + num, PAGE_SIZE - num,
+ "\t%40s(%2d):%16ld\n",
+ event2str[i], i, statistic->event[i]);
+ num += size;
+ }
+
+ num += scnprintf(buf + num, PAGE_SIZE - num, "\t%40s :%16ld\n",
+ "UNKNOWN EVENT",
+ statistic->event[VID_API_EVENT_DEC_CFG_INFO + 1]);
+
+ num += scnprintf(buf + num, PAGE_SIZE - num, "current event:\n");
+ num += scnprintf(buf + num, PAGE_SIZE - num,
+ "%10s:%40s;%10ld.%06ld\n", "event",
+ get_event_str(statistic->current_event),
+ statistic->ts_event.tv_sec,
+ statistic->ts_event.tv_nsec / 1000);
+
+ return num;
+}
+
+static ssize_t show_instance_buffer_info(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct vpu_ctx *ctx;
+ struct vpu_statistic *statistic;
+ struct vb2_data_req *p_data_req;
+ struct queue_data *This;
+ pSTREAM_BUFFER_DESCRIPTOR_TYPE pStrBufDesc;
+ u_int32 stream_length = 0;
+ int i, size, num = 0;
+
+ ctx = container_of(attr, struct vpu_ctx, dev_attr_instance_buffer);
+ statistic = &ctx->statistic;
+
+ num += scnprintf(buf + num, PAGE_SIZE - num, "frame buffer status:\n");
+
+ This = &ctx->q_data[V4L2_DST];
+ down(&This->drv_q_lock);
+ for (i = 0; i < VPU_MAX_BUFFER; i++) {
+ p_data_req = &This->vb2_reqs[i];
+ if (p_data_req->vb2_buf != NULL) {
+ size = scnprintf(buf + num, PAGE_SIZE - num,
+ "\t%40s(%2d):%16s\n",
+ "buffer", i, bufstat[p_data_req->status]);
+ num += size;
+ }
+ }
+ up(&This->drv_q_lock);
+
+ num += scnprintf(buf + num, PAGE_SIZE - num, "stream buffer status:\n");
+
+ pStrBufDesc = ctx->dev->regs_base + DEC_MFD_XREG_SLV_BASE + MFD_MCX
+ + MFD_MCX_OFF * ctx->str_index;
+
+ num += scnprintf(buf + num, PAGE_SIZE - num,
+ "\t%40s:%16x\n", "wptr", pStrBufDesc->wptr);
+ num += scnprintf(buf + num, PAGE_SIZE - num,
+ "\t%40s:%16x\n", "rptr", pStrBufDesc->rptr);
+ num += scnprintf(buf + num, PAGE_SIZE - num,
+ "\t%40s:%16x\n", "start", pStrBufDesc->start);
+ num += scnprintf(buf + num, PAGE_SIZE - num,
+ "\t%40s:%16x\n", "end", pStrBufDesc->end);
+ stream_length = ctx->stream_buffer.dma_size -
+ got_free_space(pStrBufDesc->wptr, pStrBufDesc->rptr, pStrBufDesc->start, pStrBufDesc->end);
+
+ num += scnprintf(buf + num, PAGE_SIZE - num,
+ "\t%40s:%16x\n", "stream length", stream_length);
+ num += scnprintf(buf + num, PAGE_SIZE - num,
+ "\t%40s:%16x\n", "decode dealy frame", ctx->frm_dec_delay);
+ num += scnprintf(buf + num, PAGE_SIZE - num,
+ "\t%40s:%16x\n", "display delay frame", ctx->frm_dis_delay);
+
+ return num;
+}
+
+static ssize_t show_instance_log_info(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct vpu_ctx *ctx;
+ struct vpu_statistic *statistic;
+ struct vpu_log_info *vpu_info;
+ struct vpu_log_info *tem_info;
+ int num = 0;
+
+ ctx = container_of(attr, struct vpu_ctx, dev_attr_instance_flow);
+ statistic = &ctx->statistic;
+
+ num += scnprintf(buf + num, PAGE_SIZE - num, "log info under depth: %d\n",
+ vpu_log_depth);
+
+ mutex_lock(&ctx->instance_mutex);
+ if (list_empty(&ctx->log_q))
+ goto exit;
+
+ list_for_each_entry_safe(vpu_info, tem_info, &ctx->log_q, list) {
+ switch (vpu_info->type) {
+ case LOG_EVENT:
+ num += scnprintf(buf + num, PAGE_SIZE - num,
+ "\t%20s:%40s %20s:%20x\n", "event", get_event_str(vpu_info->log_info[vpu_info->type]),
+ "rptr", vpu_info->data);
+ break;
+ case LOG_COMMAND:
+ num += scnprintf(buf + num, PAGE_SIZE - num,
+ "\t%20s:%40s\n", "command", get_cmd_str(vpu_info->log_info[vpu_info->type]));
+ break;
+ case LOG_EOS:
+ num += scnprintf(buf + num, PAGE_SIZE - num,
+ "\t%20s:%40s\n", "add eos", "done");
+ break;
+ case LOG_PADDING:
+ num += scnprintf(buf + num, PAGE_SIZE - num,
+ "\t%20s:%40s\n", "add padding", "done");
+ break;
+ case LOG_UPDATE_STREAM:
+ num += scnprintf(buf + num, PAGE_SIZE - num,
+ "\t%20s:%40s %16d\n", "update stream data", "stream size", vpu_info->data);
+ break;
+ default:
+ break;
+ }
+ }
+
+exit:
+ mutex_unlock(&ctx->instance_mutex);
+ return num;
+}
+
+
+static int create_instance_command_file(struct vpu_ctx *ctx)
+{
+ scnprintf(ctx->command_name, sizeof(ctx->command_name) - 1,
+ "instance%d_command",
+ ctx->str_index);
+ sysfs_attr_init(&ctx->dev_attr_instance_command.attr);
+ ctx->dev_attr_instance_command.attr.name = ctx->command_name;
+ ctx->dev_attr_instance_command.attr.mode = VERIFY_OCTAL_PERMISSIONS(0444);
+ ctx->dev_attr_instance_command.show = show_instance_command_info;
+
+ device_create_file(ctx->dev->generic_dev, &ctx->dev_attr_instance_command);
+
+ return 0;
+}
+
+static int create_instance_event_file(struct vpu_ctx *ctx)
+{
+ scnprintf(ctx->event_name, sizeof(ctx->event_name) - 1,
+ "instance%d_event",
+ ctx->str_index);
+ sysfs_attr_init(&ctx->dev_attr_instance_event.attr);
+ ctx->dev_attr_instance_event.attr.name = ctx->event_name;
+ ctx->dev_attr_instance_event.attr.mode = VERIFY_OCTAL_PERMISSIONS(0444);
+ ctx->dev_attr_instance_event.show = show_instance_event_info;
+
+ device_create_file(ctx->dev->generic_dev, &ctx->dev_attr_instance_event);
+
+ return 0;
+}
+
+static int create_instance_buffer_file(struct vpu_ctx *ctx)
+{
+ scnprintf(ctx->buffer_name, sizeof(ctx->buffer_name) - 1,
+ "instance%d_buffer",
+ ctx->str_index);
+ sysfs_attr_init(&ctx->dev_attr_instance_buffer.attr);
+ ctx->dev_attr_instance_buffer.attr.name = ctx->buffer_name;
+ ctx->dev_attr_instance_buffer.attr.mode = VERIFY_OCTAL_PERMISSIONS(0444);
+ ctx->dev_attr_instance_buffer.show = show_instance_buffer_info;
+
+ device_create_file(ctx->dev->generic_dev, &ctx->dev_attr_instance_buffer);
+
+ return 0;
+}
+
+static int create_instance_flow_file(struct vpu_ctx *ctx)
+{
+ scnprintf(ctx->flow_name, sizeof(ctx->flow_name) - 1,
+ "instance%d_flow",
+ ctx->str_index);
+ sysfs_attr_init(&ctx->dev_attr_instance_flow.attr);
+ ctx->dev_attr_instance_flow.attr.name = ctx->flow_name;
+ ctx->dev_attr_instance_flow.attr.mode = VERIFY_OCTAL_PERMISSIONS(0444);
+ ctx->dev_attr_instance_flow.show = show_instance_log_info;
+
+ device_create_file(ctx->dev->generic_dev, &ctx->dev_attr_instance_flow);
+
+ return 0;
+}
+static int create_instance_file(struct vpu_ctx *ctx)
+{
+ if (!ctx || !ctx->dev || !ctx->dev->generic_dev)
+ return -EINVAL;
+
+ create_instance_command_file(ctx);
+ create_instance_event_file(ctx);
+ create_instance_buffer_file(ctx);
+ create_instance_dbglog_file(ctx);
+ create_instance_flow_file(ctx);
+ atomic64_set(&ctx->statistic.total_dma_size, 0);
+ atomic64_set(&ctx->statistic.total_alloc_size, 0);
+
+ return 0;
+}
+
+static int remove_instance_file(struct vpu_ctx *ctx)
+{
+ if (!ctx || !ctx->dev || !ctx->dev->generic_dev)
+ return -EINVAL;
+
+ device_remove_file(ctx->dev->generic_dev, &ctx->dev_attr_instance_command);
+ device_remove_file(ctx->dev->generic_dev, &ctx->dev_attr_instance_event);
+ device_remove_file(ctx->dev->generic_dev, &ctx->dev_attr_instance_buffer);
+ if (ctx->dbglog_dir != NULL) {
+ debugfs_remove_recursive(ctx->dbglog_dir);
+ ctx->dbglog_dir = NULL;
+ }
+ device_remove_file(ctx->dev->generic_dev, &ctx->dev_attr_instance_flow);
+
+ return 0;
+}
+
+static int init_vpu_buffer(struct vpu_ctx *ctx)
+{
+ u_int32 i;
+
+ if (!ctx)
+ return -EINVAL;
+
+ for (i = 0; i < MAX_DCP_NUM; i++)
+ init_dma_buffer(&ctx->dcp_buffer[i]);
+ ctx->dcp_count = 0;
+ for (i = 0; i < MAX_MBI_NUM; i++)
+ init_dma_buffer(&ctx->mbi_buffer[i]);
+ ctx->mbi_count = 0;
+ ctx->mbi_num = 0;
+ ctx->mbi_size = 0;
+ init_dma_buffer(&ctx->stream_buffer);
+ init_dma_buffer(&ctx->udata_buffer);
+
+ return 0;
+}
+
+static int alloc_vpu_buffer(struct vpu_ctx *ctx)
+{
+ u_int32 ret = 0;
+
+ if (!ctx)
+ return -EINVAL;
+
+ if (!ctx->stream_buffer.dma_phy) {
+ ctx->stream_buffer.dma_size = vpu_max_bufsize;
+ ret = alloc_dma_buffer(ctx, &ctx->stream_buffer);
+ if (ret) {
+ vpu_dbg(LVL_ERR, "error: alloc stream buffer fail!\n");
+ return ret;
+ }
+ }
+
+ if (!ctx->udata_buffer.dma_phy) {
+ ctx->udata_buffer.dma_size = UDATA_BUFFER_SIZE;
+ ret = alloc_dma_buffer(ctx, &ctx->udata_buffer);
+ if (ret) {
+ vpu_dbg(LVL_ERR, "error: alloc udata buffer fail!\n");
+ free_dma_buffer(ctx, &ctx->stream_buffer);
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+static int open_crc_file(struct vpu_ctx *ctx)
+{
+ char crc_file[64];
+ int ret = 0;
+
+ if (!ctx)
+ return -EINVAL;
+
+ scnprintf(crc_file, sizeof(crc_file) - 1,
+ "/home/instance%d_crc.txt",
+ ctx->str_index);
+ ctx->crc_fp = filp_open(crc_file, O_RDWR | O_CREAT, 0664);
+ if (IS_ERR(ctx->crc_fp)) {
+ vpu_dbg(LVL_ERR, "error: open crc file fail\n");
+ ret = -1;
+ }
+ ctx->pos = 0;
+
+ return ret;
+}
+
+static int close_crc_file(struct vpu_ctx *ctx)
+{
+ int ret = 0;
+
+ if (!ctx)
+ return -EINVAL;
+
+ if (!IS_ERR(ctx->crc_fp))
+ ret = filp_close(ctx->crc_fp, NULL);
+ ctx->pos = 0;
+
+ return ret;
+}
+
+static int v4l2_open(struct file *filp)
+{
+ struct video_device *vdev = video_devdata(filp);
+ struct vpu_dev *dev = video_get_drvdata(vdev);
+ struct vpu_ctx *ctx = NULL;
+ int idx;
+ int ret = 0;
+
+ pm_runtime_get_sync(dev->generic_dev);
+ ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
+ if (!ctx)
+ return -ENOMEM;
+ mutex_lock(&dev->dev_mutex);
+ idx = vpu_next_free_instance(dev);
+ if (idx < 0) {
+ ret = idx;
+ mutex_unlock(&dev->dev_mutex);
+ goto err_find_index;
+ }
+ set_bit(idx, &dev->instance_mask);
+ mutex_unlock(&dev->dev_mutex);
+ init_completion(&ctx->completion);
+ init_completion(&ctx->stop_cmp);
+ init_completion(&ctx->eos_cmp);
+ init_completion(&ctx->alloc_cmp);
+
+ v4l2_fh_init(&ctx->fh, video_devdata(filp));
+ filp->private_data = &ctx->fh;
+ v4l2_fh_add(&ctx->fh);
+
+ ctx->ctrl_inited = false;
+ ctrls_setup_decoder(ctx);
+ ctx->fh.ctrl_handler = &ctx->ctrl_handler;
+
+ ctx->instance_wq = alloc_workqueue("vpu_instance", WQ_UNBOUND | WQ_MEM_RECLAIM, 1);
+ if (!ctx->instance_wq) {
+ vpu_dbg(LVL_ERR, "error: %s unable to alloc workqueue for ctx\n", __func__);
+ ret = -ENOMEM;
+ goto err_alloc_wq;
+ }
+ INIT_WORK(&ctx->instance_work, vpu_msg_instance_work);
+
+ mutex_init(&ctx->instance_mutex);
+ if (kfifo_alloc(&ctx->msg_fifo,
+ sizeof(struct event_msg) * VID_API_MESSAGE_LIMIT,
+ GFP_KERNEL)) {
+ vpu_dbg(LVL_ERR, "fail to alloc fifo when open\n");
+ ret = -ENOMEM;
+ goto err_alloc_fifo;
+ }
+ ctx->dev = dev;
+ ctx->str_index = idx;
+ dev->ctx[idx] = ctx;
+ ctx->b_firstseq = true;
+ ctx->start_flag = true;
+ ctx->wait_rst_done = false;
+ ctx->firmware_stopped = false;
+ ctx->firmware_finished = false;
+ ctx->eos_stop_received = false;
+ ctx->eos_stop_added = false;
+ ctx->buffer_null = true; //this flag is to judge whether the buffer is null is not, it is used for the workaround that when send stop command still can receive buffer ready event, and true means buffer is null, false not
+ ctx->ctx_released = false;
+ ctx->b_dis_reorder = false;
+ ctx->start_code_bypass = false;
+ ctx->hang_status = false;
+ create_instance_file(ctx);
+ if (vpu_frmcrcdump_ena) {
+ ret = open_crc_file(ctx);
+ if (ret)
+ goto err_open_crc;
+ }
+ ctx->pSeqinfo = kzalloc(sizeof(MediaIPFW_Video_SeqInfo), GFP_KERNEL);
+ if (!ctx->pSeqinfo) {
+ vpu_dbg(LVL_ERR, "error: pSeqinfo alloc fail\n");
+ ret = -ENOMEM;
+ goto err_alloc_seq;
+ }
+ atomic64_add(sizeof(MediaIPFW_Video_SeqInfo), &ctx->statistic.total_alloc_size);
+ ctx->pSeqinfo->uProgressive = 1;
+ init_queue_data(ctx);
+ init_log_info_queue(ctx);
+ create_log_info_queue(ctx, vpu_log_depth);
+ init_waitqueue_head(&ctx->buffer_wq);
+ mutex_lock(&dev->dev_mutex);
+ if (!dev->fw_is_ready) {
+ ret = vpu_firmware_download(dev);
+ if (ret) {
+ vpu_dbg(LVL_ERR, "error: vpu_firmware_download fail\n");
+ mutex_unlock(&dev->dev_mutex);
+ goto err_firmware_load;
+ }
+ vpu_dbg(LVL_INFO, "done: vpu_firmware_download\n");
+ if (!ctx->dev->firmware_started)
+ if (!wait_for_completion_timeout(&ctx->dev->start_cmp, msecs_to_jiffies(10000))) {
+ vpu_dbg(LVL_ERR, "error: don't get start interrupt\n");
+ ret = -1;
+ goto err_firmware_load;
+ }
+ dev->fw_is_ready = true;
+ }
+ mutex_unlock(&dev->dev_mutex);
+ rpc_set_stream_cfg_value(dev->shared_mem.pSharedInterface, ctx->str_index, vpu_dbe_num);
+ init_vpu_buffer(ctx);
+
+ return 0;
+
+err_firmware_load:
+ destroy_log_info_queue(ctx);
+ kfree(ctx->pSeqinfo);
+ ctx->pSeqinfo = NULL;
+ atomic64_sub(sizeof(MediaIPFW_Video_SeqInfo), &ctx->statistic.total_alloc_size);
+ release_queue_data(ctx);
+err_alloc_seq:
+ if (vpu_frmcrcdump_ena)
+ close_crc_file(ctx);
+err_open_crc:
+ remove_instance_file(ctx);
+ kfifo_free(&ctx->msg_fifo);
+err_alloc_fifo:
+ destroy_workqueue(ctx->instance_wq);
+err_alloc_wq:
+ ctrls_delete_decoder(ctx);
+ v4l2_fh_del(&ctx->fh);
+ v4l2_fh_exit(&ctx->fh);
+ clear_bit(ctx->str_index, &dev->instance_mask);
+err_find_index:
+ if (atomic64_read(&ctx->statistic.total_alloc_size) != 0)
+ vpu_dbg(LVL_ERR, "error: memory leak for vpu kalloc buffer\n");
+ kfree(ctx);
+ pm_runtime_put_sync(dev->generic_dev);
+
+ return ret;
+}
+
+static int v4l2_release(struct file *filp)
+{
+ struct video_device *vdev = video_devdata(filp);
+ struct vpu_dev *dev = video_get_drvdata(vdev);
+ struct vpu_ctx *ctx = v4l2_fh_to_ctx(filp->private_data);
+
+ vpu_dbg(LVL_EVENT, "ctx[%d]: v4l2_release() - stopped(%d), finished(%d), eos_added(%d), total frame: %d\n",
+ ctx->str_index, ctx->firmware_stopped, ctx->firmware_finished, ctx->eos_stop_added, ctx->frm_total_num);
+
+ if (!ctx->firmware_stopped && ctx->start_flag == false) {
+ ctx->wait_rst_done = true;
+ wake_up_interruptible(&ctx->buffer_wq); //workaround: to wakeup event handler who still may receive request frame after reset done
+ vpu_dbg(LVL_INFO, "v4l2_release() - send VID_API_CMD_STOP\n");
+ v4l2_vpu_send_cmd(ctx, ctx->str_index, VID_API_CMD_STOP, 0, NULL);
+ if (!wait_for_completion_timeout(&ctx->stop_cmp, msecs_to_jiffies(1000))) {
+ ctx->hang_status = true;
+ vpu_dbg(LVL_ERR, "the path id:%d firmware hang after send VID_API_CMD_STOP\n", ctx->str_index);
+ }
+ } else
+ vpu_dbg(LVL_INFO, "v4l2_release() - stopped(%d): skip VID_API_CMD_STOP\n", ctx->firmware_stopped);
+
+ mutex_lock(&ctx->instance_mutex);
+ ctx->ctx_released = true;
+ kfifo_free(&ctx->msg_fifo);
+ destroy_workqueue(ctx->instance_wq);
+ mutex_unlock(&ctx->instance_mutex);
+
+ if (vpu_frmcrcdump_ena)
+ close_crc_file(ctx);
+ release_queue_data(ctx);
+ ctrls_delete_decoder(ctx);
+ v4l2_fh_del(&ctx->fh);
+ v4l2_fh_exit(&ctx->fh);
+ free_decoder_buffer(ctx);
+ if (atomic64_read(&ctx->statistic.total_dma_size) != 0)
+ vpu_dbg(LVL_ERR, "error: memory leak for vpu dma alloc buffer\n");
+ if (ctx->pSeqinfo) {
+ kfree(ctx->pSeqinfo);
+ ctx->pSeqinfo = NULL;
+ atomic64_sub(sizeof(MediaIPFW_Video_SeqInfo), &ctx->statistic.total_alloc_size);
+ }
+
+ pm_runtime_put_sync(ctx->dev->generic_dev);
+
+ if (!ctx->hang_status) { // judge the path is hang or not, if hang, don't clear
+ remove_instance_file(ctx);
+ destroy_log_info_queue(ctx);
+ if (atomic64_read(&ctx->statistic.total_alloc_size) != 0)
+ vpu_dbg(LVL_ERR, "error: memory leak for vpu kalloc buffer\n");
+ mutex_lock(&dev->dev_mutex);
+ clear_bit(ctx->str_index, &dev->instance_mask);
+ if (ctx->firmware_finished) {
+ dev->ctx[ctx->str_index] = NULL;
+ kfree(ctx);
+ }
+
+ mutex_unlock(&dev->dev_mutex);
+ } else {
+ mutex_lock(&dev->dev_mutex);
+ set_bit(ctx->str_index, &dev->hang_mask);
+ mutex_unlock(&dev->dev_mutex);
+ }
+ return 0;
+}
+
+static unsigned int v4l2_poll(struct file *filp, poll_table *wait)
+{
+ struct vpu_ctx *ctx = v4l2_fh_to_ctx(filp->private_data);
+ struct vb2_queue *src_q, *dst_q;
+ unsigned int rc = 0;
+
+ vpu_dbg(LVL_INFO, "%s()\n", __func__);
+
+ if (ctx) {
+ poll_wait(filp, &ctx->fh.wait, wait);
+
+ if (v4l2_event_pending(&ctx->fh)) {
+ vpu_dbg(LVL_INFO, "%s() v4l2_event_pending\n", __func__);
+ rc |= POLLPRI;
+ }
+
+ src_q = &ctx->q_data[V4L2_SRC].vb2_q;
+ dst_q = &ctx->q_data[V4L2_DST].vb2_q;
+
+ if (ctx->firmware_finished && !list_empty(&dst_q->done_list))
+ rc = 0;
+
+ if ((!src_q->streaming || list_empty(&src_q->queued_list))
+ && (!dst_q->streaming || list_empty(&dst_q->queued_list))) {
+ rc |= POLLERR;
+ return rc;
+ }
+
+ poll_wait(filp, &src_q->done_wq, wait);
+ if (!list_empty(&src_q->done_list))
+ rc |= POLLOUT | POLLWRNORM;
+ poll_wait(filp, &dst_q->done_wq, wait);
+ if (!list_empty(&dst_q->done_list))
+ rc |= POLLIN | POLLRDNORM;
+ } else
+ rc = POLLERR;
+
+ return rc;
+}
+
+static int v4l2_mmap(struct file *filp, struct vm_area_struct *vma)
+{
+ long ret = -EPERM;
+ unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
+ struct queue_data *q_data;
+ enum QUEUE_TYPE type;
+
+ struct vpu_ctx *ctx = v4l2_fh_to_ctx(filp->private_data);
+
+ vpu_dbg(LVL_INFO, "%s()\n", __func__);
+
+ if (ctx) {
+ type = offset >> MMAP_BUF_TYPE_SHIFT;
+ q_data = &ctx->q_data[type];
+
+ offset &= ~MMAP_BUF_TYPE_MASK;
+ offset = offset >> PAGE_SHIFT;
+ vma->vm_pgoff = offset;
+ ret = vpu_dec_queue_mmap(q_data, vma);
+ }
+
+ return ret;
+}
+
+static const struct v4l2_file_operations v4l2_decoder_fops = {
+ .owner = THIS_MODULE,
+ .open = v4l2_open,
+ .unlocked_ioctl = video_ioctl2,
+ .release = v4l2_release,
+ .poll = v4l2_poll,
+ .mmap = v4l2_mmap,
+};
+
+static struct video_device v4l2_videodevice_decoder = {
+ .name = "vpu decoder",
+ .fops = &v4l2_decoder_fops,
+ .ioctl_ops = &v4l2_decoder_ioctl_ops,
+ .vfl_dir = VFL_DIR_M2M,
+};
+
+static void vpu_setup(struct vpu_dev *This)
+{
+ uint32_t read_data = 0;
+
+ vpu_dbg(LVL_INFO, "enter %s\n", __func__);
+ writel(0x1, This->regs_base + SCB_XREG_SLV_BASE + SCB_SCB_BLK_CTRL + SCB_BLK_CTRL_SCB_CLK_ENABLE_SET);
+ writel(0xffffffff, This->regs_base + 0x70190);
+ writel(0xffffffff, This->regs_base + SCB_XREG_SLV_BASE + SCB_SCB_BLK_CTRL + SCB_BLK_CTRL_XMEM_RESET_SET);
+
+ writel(0xE, This->regs_base + SCB_XREG_SLV_BASE + SCB_SCB_BLK_CTRL + SCB_BLK_CTRL_SCB_CLK_ENABLE_SET);
+ writel(0x7, This->regs_base + SCB_XREG_SLV_BASE + SCB_SCB_BLK_CTRL + SCB_BLK_CTRL_CACHE_RESET_SET);
+
+ writel(0x1f, This->regs_base + DEC_MFD_XREG_SLV_BASE + MFD_BLK_CTRL + MFD_BLK_CTRL_MFD_SYS_CLOCK_ENABLE_SET);
+ writel(0xffffffff, This->regs_base + DEC_MFD_XREG_SLV_BASE + MFD_BLK_CTRL + MFD_BLK_CTRL_MFD_SYS_RESET_SET);
+
+ writel(0x102, This->regs_base + XMEM_CONTROL);
+
+ read_data = readl(This->regs_base+0x70108);
+ vpu_dbg(LVL_INFO, "%s read_data=%x\n", __func__, read_data);
+}
+
+static void vpu_reset(struct vpu_dev *This)
+{
+ vpu_dbg(LVL_INFO, "enter %s\n", __func__);
+ writel(0x7, This->regs_base + SCB_XREG_SLV_BASE + SCB_SCB_BLK_CTRL + SCB_BLK_CTRL_CACHE_RESET_CLR);
+ writel(0xffffffff, This->regs_base + DEC_MFD_XREG_SLV_BASE + MFD_BLK_CTRL + MFD_BLK_CTRL_MFD_SYS_RESET_CLR);
+}
+
+static int vpu_enable_hw(struct vpu_dev *This)
+{
+ vpu_dbg(LVL_INFO, "%s()\n", __func__);
+ vpu_setup(This);
+ return 0;
+}
+static void vpu_disable_hw(struct vpu_dev *This)
+{
+ vpu_reset(This);
+}
+
+static int swreset_vpu_firmware(struct vpu_dev *dev, u_int32 idx)
+{
+ int ret = 0;
+
+ vpu_dbg(LVL_WARN, "SWRESET: swreset_vpu_firmware\n");
+ dev->firmware_started = false;
+
+ v4l2_vpu_send_cmd(dev->ctx[idx], 0, VID_API_CMD_FIRM_RESET, 0, NULL);
+
+ if (!wait_for_completion_timeout(&dev->start_cmp, msecs_to_jiffies(10000))) {
+ vpu_dbg(LVL_ERR, "error: %s() fail\n", __func__);
+ return -1;
+ }
+ dev->firmware_started = true;
+
+ return ret;
+}
+
+static int parse_dt_info(struct vpu_dev *dev, struct device_node *np)
+{
+ u_int32 core_type;
+ struct resource reserved_res;
+ struct device_node *reserved_node;
+ u_int32 csr_base;
+ int ret;
+
+ if (!dev || !np)
+ return -EINVAL;
+
+ ret = of_property_read_u32(np, "core_type", &core_type);
+ if (ret) {
+ vpu_dbg(LVL_ERR, "error: Cannot get core num %d\n", ret);
+ return -EINVAL;
+ }
+ if (core_type == 2)
+ dev->plat_type = IMX8QM;
+ else
+ dev->plat_type = IMX8QXP;
+ reserved_node = of_parse_phandle(np, "boot-region", 0);
+ if (!reserved_node) {
+ vpu_dbg(LVL_ERR, "error: boot-region of_parse_phandle error\n");
+ return -ENODEV;
+ }
+
+ if (of_address_to_resource(reserved_node, 0, &reserved_res)) {
+ vpu_dbg(LVL_ERR, "error: boot-region of_address_to_resource error\n");
+ return -EINVAL;
+ }
+ dev->m0_p_fw_space_phy = reserved_res.start;
+ dev->m0_boot_size = reserved_res.end - reserved_res.start;
+ reserved_node = of_parse_phandle(np, "rpc-region", 0);
+ if (!reserved_node) {
+ vpu_dbg(LVL_ERR, "error: rpc-region of_parse_phandle error\n");
+ return -ENODEV;
+ }
+
+ if (of_address_to_resource(reserved_node, 0, &reserved_res)) {
+ vpu_dbg(LVL_ERR, "error: rpc-region of_address_to_resource error\n");
+ return -EINVAL;
+ }
+ dev->m0_rpc_phy = reserved_res.start;
+ dev->m0_rpc_size = reserved_res.end - reserved_res.start;
+
+ ret = of_property_read_u32(np, "reg-csr", &csr_base);
+ if (ret) {
+ vpu_dbg(LVL_ERR, "error: Cannot get csr offset %d\n", ret);
+ return -EINVAL;
+ }
+ dev->csr_base = ioremap(csr_base, 8); //for csr0 offset and cpuwait
+
+ return 0;
+}
+
+static int create_vpu_video_device(struct vpu_dev *dev)
+{
+ int ret;
+
+ if (!dev)
+ return -EINVAL;
+
+ dev->pvpu_decoder_dev = video_device_alloc();
+ if (!dev->pvpu_decoder_dev) {
+ vpu_dbg(LVL_ERR, "video device alloc for decoder fail\n");
+ return -ENOMEM;
+ }
+ strlcpy(dev->pvpu_decoder_dev->name,
+ v4l2_videodevice_decoder.name,
+ sizeof(dev->pvpu_decoder_dev->name));
+ dev->pvpu_decoder_dev->fops = v4l2_videodevice_decoder.fops;
+ dev->pvpu_decoder_dev->ioctl_ops = v4l2_videodevice_decoder.ioctl_ops;
+ dev->pvpu_decoder_dev->release = video_device_release;
+ dev->pvpu_decoder_dev->vfl_dir = v4l2_videodevice_decoder.vfl_dir;
+ dev->pvpu_decoder_dev->v4l2_dev = &dev->v4l2_dev;
+
+ video_set_drvdata(dev->pvpu_decoder_dev, dev);
+
+ ret = video_register_device(dev->pvpu_decoder_dev,
+ VFL_TYPE_GRABBER,
+ DECODER_NODE_NUMBER);
+ if (ret) {
+ vpu_dbg(LVL_ERR, "error: %s unable to register video decoder device\n",
+ __func__
+ );
+ video_device_release(dev->pvpu_decoder_dev);
+ dev->pvpu_decoder_dev = NULL;
+ return ret;
+ }
+
+ return 0;
+}
+
+static int init_vpudev_parameters(struct vpu_dev *dev)
+{
+ int ret;
+
+ if (!dev)
+ return -EINVAL;
+
+ mutex_init(&dev->dev_mutex);
+ mutex_init(&dev->cmd_mutex);
+ init_completion(&dev->start_cmp);
+ init_completion(&dev->snap_done_cmp);
+ dev->firmware_started = false;
+ dev->hang_mask = 0;
+ dev->instance_mask = 0;
+
+ dev->fw_is_ready = false;
+
+ ret = vpu_mu_init(dev);
+ if (ret) {
+ vpu_dbg(LVL_ERR, "error: %s vpu mu init failed\n", __func__);
+ return ret;
+ }
+
+ //firmware space for M0
+ dev->m0_p_fw_space_vir = ioremap_wc(dev->m0_p_fw_space_phy,
+ dev->m0_boot_size
+ );
+ if (!dev->m0_p_fw_space_vir) {
+ vpu_dbg(LVL_ERR, "error: failed to remap space for M0 firmware\n");
+ return -ENOMEM;
+ }
+
+ memset_io(dev->m0_p_fw_space_vir, 0, dev->m0_boot_size);
+
+ dev->m0_rpc_virt = ioremap_wc(dev->m0_rpc_phy,
+ dev->m0_rpc_size
+ );
+ if (!dev->m0_rpc_virt) {
+ vpu_dbg(LVL_ERR, "error: failed to remap space for rpc shared memory\n");
+ return -ENOMEM;
+ }
+
+ memset_io(dev->m0_rpc_virt, 0, dev->m0_rpc_size);
+
+ return 0;
+}
+
+static int vpu_probe(struct platform_device *pdev)
+{
+ struct vpu_dev *dev;
+ struct resource *res;
+ struct device_node *np = pdev->dev.of_node;
+ unsigned int mu_id;
+ int ret;
+
+ dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL);
+ if (!dev)
+ return -ENOMEM;
+
+ dev->plat_dev = pdev;
+ dev->generic_dev = get_device(&pdev->dev);
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ dev->regs_base = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(dev->regs_base)) {
+ vpu_dbg(LVL_ERR, "error: %s could not map regs_base\n", __func__);
+ ret = PTR_ERR(dev->regs_base);
+ goto err_put_dev;
+ }
+
+ ret = parse_dt_info(dev, np);
+ if (ret) {
+ vpu_dbg(LVL_ERR, "error: %s parse device tree fail\n", __func__);
+ goto err_dev_iounmap;
+ }
+
+ ret = v4l2_device_register(&pdev->dev, &dev->v4l2_dev);
+ if (ret) {
+ vpu_dbg(LVL_ERR, "error: %s unable to register v4l2 dev\n", __func__);
+ goto err_dev_iounmap;
+ }
+
+ platform_set_drvdata(pdev, dev);
+
+ ret = create_vpu_video_device(dev);
+ if (ret) {
+ vpu_dbg(LVL_ERR, "error: %s create vpu video device fail\n", __func__);
+ goto err_unreg_v4l2;
+ }
+
+ if (!dev->mu_ipcHandle) {
+ ret = sc_ipc_getMuID(&mu_id);
+ if (ret) {
+ vpu_dbg(LVL_ERR, "error: --- sc_ipc_getMuID() cannot obtain mu id SCI error! (%d)\n", ret);
+ goto err_rm_vdev;
+ }
+
+ ret = sc_ipc_open(&dev->mu_ipcHandle, mu_id);
+ if (ret) {
+ vpu_dbg(LVL_ERR, "error: --- sc_ipc_getMuID() cannot open MU channel to SCU error! (%d)\n", ret);
+ goto err_rm_vdev;
+ }
+ }
+
+ dev->workqueue = alloc_workqueue("vpu", WQ_UNBOUND | WQ_MEM_RECLAIM, 1);
+ if (!dev->workqueue) {
+ vpu_dbg(LVL_ERR, "error: %s unable to alloc workqueue\n", __func__);
+ ret = -ENOMEM;
+ goto err_rm_vdev;
+ }
+
+ INIT_WORK(&dev->msg_work, vpu_msg_run_work);
+
+ check_fuse_value(dev, formats_compressed_dec, ARRAY_SIZE(formats_compressed_dec));
+ vpu_enable_hw(dev);
+ pm_runtime_enable(&pdev->dev);
+ pm_runtime_get_sync(&pdev->dev);
+
+ ret = init_vpudev_parameters(dev);
+ if (ret) {
+ vpu_dbg(LVL_ERR, "error: failed to init parameters for vpudev\n");
+ goto err_poweroff;
+ }
+
+ pm_runtime_put_sync(&pdev->dev);
+
+ return 0;
+
+err_poweroff:
+ destroy_workqueue(dev->workqueue);
+ vpu_disable_hw(dev);
+ pm_runtime_put_sync(&pdev->dev);
+ pm_runtime_disable(&pdev->dev);
+err_rm_vdev:
+ if (dev->pvpu_decoder_dev) {
+ video_unregister_device(dev->pvpu_decoder_dev);
+ dev->pvpu_decoder_dev = NULL;
+ }
+err_unreg_v4l2:
+ v4l2_device_unregister(&dev->v4l2_dev);
+err_dev_iounmap:
+ if (dev->regs_base)
+ iounmap(dev->regs_base);
+err_put_dev:
+ if (dev->generic_dev) {
+ put_device(dev->generic_dev);
+ dev->generic_dev = NULL;
+ }
+
+ return ret;
+}
+
+static int vpu_remove(struct platform_device *pdev)
+{
+ struct vpu_dev *dev = platform_get_drvdata(pdev);
+
+ destroy_workqueue(dev->workqueue);
+ if (dev->m0_p_fw_space_vir)
+ iounmap(dev->m0_p_fw_space_vir);
+ if (dev->m0_pfw) {
+ release_firmware(dev->m0_pfw);
+ dev->m0_pfw = NULL;
+ }
+ dev->m0_p_fw_space_vir = NULL;
+ dev->m0_p_fw_space_phy = 0;
+ dev->m0_rpc_virt = NULL;
+ dev->m0_rpc_phy = 0;
+ if (dev->shared_mem.shared_mem_vir)
+ iounmap(dev->shared_mem.shared_mem_vir);
+ dev->shared_mem.shared_mem_vir = NULL;
+ dev->shared_mem.shared_mem_phy = 0;
+
+ vpu_disable_hw(dev);
+ pm_runtime_disable(&pdev->dev);
+
+ if (video_get_drvdata(dev->pvpu_decoder_dev))
+ video_unregister_device(dev->pvpu_decoder_dev);
+
+ v4l2_device_unregister(&dev->v4l2_dev);
+ return 0;
+}
+
+static int vpu_runtime_suspend(struct device *dev)
+{
+ return 0;
+}
+
+static int vpu_runtime_resume(struct device *dev)
+{
+ return 0;
+}
+
+static int find_first_available_instance(struct vpu_dev *dev)
+{
+ int strIdx, i;
+
+ if (!dev)
+ return -EINVAL;
+
+ strIdx = (~dev->hang_mask) & (dev->instance_mask);
+
+ for (i = 0; i < VPU_MAX_NUM_STREAMS; i++) {
+ if (CHECK_BIT(strIdx, i)) {
+ strIdx = i;
+ break;
+ }
+ }
+
+ return strIdx;
+}
+
+static void v4l2_vpu_send_snapshot(struct vpu_dev *dev)
+{
+ int strIdx;
+
+ strIdx = find_first_available_instance(dev);
+ if (strIdx >= 0 && strIdx < VPU_MAX_NUM_STREAMS)
+ v4l2_vpu_send_cmd(dev->ctx[strIdx], strIdx, VID_API_CMD_SNAPSHOT, 0, NULL);
+ else
+ vpu_dbg(LVL_WARN, "warning: all path hang, need to reset\n");
+}
+
+static int vpu_suspend(struct device *dev)
+{
+ struct vpu_dev *vpudev = (struct vpu_dev *)dev_get_drvdata(dev);
+
+ if (vpudev->hang_mask != vpudev->instance_mask) {
+
+ /*if there is an available device, send snapshot command to firmware*/
+ v4l2_vpu_send_snapshot(vpudev);
+
+ if (!wait_for_completion_timeout(&vpudev->snap_done_cmp, msecs_to_jiffies(1000))) {
+ vpu_dbg(LVL_ERR, "error: wait for vpu decoder snapdone event timeout!\n");
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+static bool is_vpu_poweroff(struct vpu_dev *vpudev)
+{
+ void *mu_cr_addr;
+ u_int32 mu_cr;
+
+ if (!vpudev)
+ return false;
+
+ mu_cr_addr = vpudev->mu_base_virtaddr + 0x10000 + 0x24;
+ mu_cr = readl_relaxed(mu_cr_addr);
+
+ if (mu_cr == 0)// it mean M0+ is already power off/on
+ return true;
+ else
+ return false;
+
+}
+
+static int resume_vpu_register(struct vpu_dev *vpudev)
+{
+ if (!vpudev)
+ return -EINVAL;
+
+ vpu_enable_hw(vpudev);
+ MU_Init(vpudev->mu_base_virtaddr);
+ MU_EnableRxFullInt(vpudev->mu_base_virtaddr, 0);
+
+ return 0;
+}
+
+static int resume_from_vpu_poweroff(struct vpu_dev *vpudev)
+{
+ int ret = 0;
+
+ enable_csr_reg(vpudev);
+ /*wait for firmware resotre done*/
+ if (!wait_for_completion_timeout(&vpudev->start_cmp, msecs_to_jiffies(1000))) {
+ vpu_dbg(LVL_ERR, "error: wait for vpu decoder resume done timeout!\n");
+ ret = -1;
+ }
+
+ return ret;
+}
+
+static int vpu_resume(struct device *dev)
+{
+ struct vpu_dev *vpudev = (struct vpu_dev *)dev_get_drvdata(dev);
+ int ret = 0;
+ u_int32 idx;
+
+ pm_runtime_get_sync(vpudev->generic_dev);
+
+ resume_vpu_register(vpudev);
+
+ if (vpudev->fw_is_ready == false)
+ return 0;
+
+ if (is_vpu_poweroff(vpudev))
+ ret = resume_from_vpu_poweroff(vpudev);
+ else if (vpudev->hang_mask != vpudev->instance_mask) {
+ idx = get_reset_index(vpudev);
+ if (idx < VPU_MAX_NUM_STREAMS)
+ swreset_vpu_firmware(vpudev, idx);
+ else
+ return -EINVAL;
+ }
+
+ pm_runtime_put_sync(vpudev->generic_dev);
+
+ return ret;
+}
+
+static const struct dev_pm_ops vpu_pm_ops = {
+ SET_RUNTIME_PM_OPS(vpu_runtime_suspend, vpu_runtime_resume, NULL)
+ SET_SYSTEM_SLEEP_PM_OPS(vpu_suspend, vpu_resume)
+};
+
+static const struct of_device_id vpu_of_match[] = {
+ { .compatible = "nxp,imx8qm-b0-vpudec", },
+ { .compatible = "nxp,imx8qxp-b0-vpudec", },
+ {}
+}
+MODULE_DEVICE_TABLE(of, vpu_of_match);
+
+static struct platform_driver vpu_driver = {
+ .probe = vpu_probe,
+ .remove = vpu_remove,
+ .driver = {
+ .name = "vpu-b0",
+ .of_match_table = vpu_of_match,
+ .pm = &vpu_pm_ops,
+ },
+};
+module_platform_driver(vpu_driver);
+
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("Linux VPU driver for Freescale i.MX/MXC");
+MODULE_LICENSE("GPL");
+
+module_param(vpu_dbg_level_decoder, int, 0644);
+MODULE_PARM_DESC(vpu_dbg_level_decoder, "Debug level (0-3)");
+module_param(vpu_frm_depth, int, 0644);
+MODULE_PARM_DESC(vpu_frm_depth, "maximum frame number in data pool");
+module_param(vpu_log_depth, int, 0644);
+MODULE_PARM_DESC(vpu_log_depth, "maximum log number in queue(0-60)");
+module_param(vpu_frmdbg_ena, int, 0644);
+MODULE_PARM_DESC(vpu_frmdbg_ena, "enable firmware mask instance dbg log (bit N to mask instance N)");
+module_param(vpu_frmdbg_level, int, 0644);
+MODULE_PARM_DESC(vpu_frmdbg_level, "firmware debug level (0-2)");
+module_param(vpu_max_bufsize, int, 0644);
+MODULE_PARM_DESC(vpu_max_bufsize, "maximun stream buffer size");
+module_param(vpu_dbe_num, int, 0644);
+MODULE_PARM_DESC(vpu_dbe_num, "vpu dbe number(1-2)");
+module_param(vpu_frmcrcdump_ena, int, 0644);
+MODULE_PARM_DESC(vpu_frmcrcdump_ena, "enable frame crc dump(0-1)");
+module_param(stream_buffer_threshold, int, 0644);
+MODULE_PARM_DESC(stream_buffer_threshold, "stream buffer threshold");
diff --git a/drivers/mxc/vpu_malone/vpu_b0.h b/drivers/mxc/vpu_malone/vpu_b0.h
new file mode 100644
index 000000000000..1c147bae0ba4
--- /dev/null
+++ b/drivers/mxc/vpu_malone/vpu_b0.h
@@ -0,0 +1,324 @@
+/*
+ * Copyright 2018 NXP
+ */
+
+/*
+ * The code contained herein is licensed under the GNU Lesser General
+ * Public License. You may obtain a copy of the GNU Lesser General
+ * Public License Version 2.1 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/lgpl-license.html
+ * http://www.gnu.org/copyleft/lgpl.html
+ */
+
+/*!
+ * @file vpu_b0.h
+ *
+ * @brief VPU B0 definition
+ *
+ */
+#ifndef __VPU_B0_H
+#define __VPU_B0_H
+
+#include <linux/irqreturn.h>
+#include <linux/mutex.h>
+#include <linux/videodev2.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-fh.h>
+#include <media/videobuf2-v4l2.h>
+#include <soc/imx8/sc/svc/irq/api.h>
+#include <soc/imx8/sc/ipc.h>
+#include <soc/imx8/sc/sci.h>
+#include <linux/mx8_mu.h>
+#include <media/v4l2-event.h>
+#include <linux/kfifo.h>
+#include "vpu_rpc.h"
+
+extern unsigned int vpu_dbg_level_decoder;
+
+#define v4l2_fh_to_ctx(__fh) \
+ container_of(__fh, struct vpu_ctx, fh)
+#define v4l2_ctrl_to_ctx(__ctrl) \
+ container_of((__ctrl)->handler, struct vpu_ctx, ctrl_handler)
+
+#define MIN_SPACE (SCODE_SIZE + 64)
+#define SCODE_SIZE (4096)
+
+#define VPU_MAX_BUFFER 32
+#define M0FW_FILENAME "vpu/vpu_fw_imx8_dec.bin"
+#define MMAP_BUF_TYPE_SHIFT 28
+#define MMAP_BUF_TYPE_MASK 0xF0000000
+#define DCP_SIZE 0x3000000
+#define MAX_BUFFER_SIZE 0xc00000
+#define UDATA_BUFFER_SIZE 0x1000
+#define MAX_DCP_NUM 2
+#define MAX_MBI_NUM 18 // same with MEDIA_PLAYER_MAX_MBI_UNIT defined in firmware
+#define MAX_TIMEOUT_COUNT 10
+#define VPU_REG_BASE 0x40000000
+
+#define V4L2_MAX_CTRLS 12
+#define V4L2_PIX_FMT_NV12_10BIT v4l2_fourcc('N', 'T', '1', '2') /* Y/CbCr 4:2:0 for 10bit */
+#define INVALID_FRAME_DEPTH -1
+#define DECODER_NODE_NUMBER 12 // use /dev/video12 as vpu decoder
+#define DEFAULT_LOG_DEPTH 20
+#define V4L2_EVENT_SKIP 8
+#define DEFAULT_FRMDBG_ENABLE 0
+#define DEFAULT_FRMDBG_LEVEL 0
+
+struct vpu_v4l2_control {
+ uint32_t id;
+ enum v4l2_ctrl_type type;
+ uint32_t minimum;
+ uint32_t maximum;
+ uint32_t step;
+ uint32_t default_value;
+ uint32_t menu_skip_mask;
+ bool is_volatile;
+};
+
+typedef enum{
+ INIT_DONE = 1,
+ RPC_BUF_OFFSET,
+ BOOT_ADDRESS,
+ COMMAND,
+ EVENT
+} MSG_Type;
+
+enum PLAT_TYPE {
+ IMX8QXP = 0,
+ IMX8QM = 1,
+};
+
+enum QUEUE_TYPE {
+ V4L2_SRC = 0,
+ V4L2_DST = 1,
+};
+
+enum vpu_video_standard {
+ VPU_VIDEO_UNDEFINED = 0,
+ VPU_VIDEO_AVC = 1,
+ VPU_VIDEO_VC1 = 2,
+ VPU_VIDEO_MPEG2 = 3,
+ VPU_VIDEO_AVS = 4,
+ VPU_VIDEO_ASP = 5,
+ VPU_VIDEO_JPEG = 6,
+ VPU_VIDEO_RV = 7,
+ VPU_VIDEO_VP6 = 8,
+ VPU_VIDEO_SPK = 9,
+ VPU_VIDEO_VP8 = 10,
+ VPU_VIDEO_AVC_MVC = 11,
+ VPU_VIDEO_HEVC = 12,
+};
+
+typedef enum{
+ EOS_PADDING_TYPE = 1,
+ BUFFLUSH_PADDING_TYPE = 2,
+ BUFABORT_PADDING_TYPE = 3,
+} VPU_PADDING_SCODE_TYPE;
+
+#define VPU_PIX_FMT_AVS v4l2_fourcc('A', 'V', 'S', '0')
+#define VPU_PIX_FMT_ASP v4l2_fourcc('A', 'S', 'P', '0')
+#define VPU_PIX_FMT_RV v4l2_fourcc('R', 'V', '0', '0')
+#define VPU_PIX_FMT_VP6 v4l2_fourcc('V', 'P', '6', '0')
+#define VPU_PIX_FMT_SPK v4l2_fourcc('S', 'P', 'K', '0')
+#define VPU_PIX_FMT_DIVX v4l2_fourcc('D', 'I', 'V', 'X')
+#define VPU_PIX_FMT_HEVC v4l2_fourcc('H', 'E', 'V', 'C')
+#define VPU_PIX_FMT_LOGO v4l2_fourcc('L', 'O', 'G', 'O')
+
+#define VPU_PIX_FMT_TILED_8 v4l2_fourcc('Z', 'T', '0', '8')
+#define VPU_PIX_FMT_TILED_10 v4l2_fourcc('Z', 'T', '1', '0')
+
+#define V4L2_CID_USER_RAW_BASE (V4L2_CID_USER_BASE + 0x1100)
+
+enum vpu_pixel_format {
+ VPU_HAS_COLOCATED = 0x00000001,
+ VPU_HAS_SPLIT_FLD = 0x00000002,
+ VPU_PF_MASK = ~(VPU_HAS_COLOCATED | VPU_HAS_SPLIT_FLD),
+
+ VPU_IS_TILED = 0x000000100,
+ VPU_HAS_10BPP = 0x00000200,
+
+ VPU_IS_PLANAR = 0x00001000,
+ VPU_IS_SEMIPLANAR = 0x00002000,
+ VPU_IS_PACKED = 0x00004000,
+
+ // Merged definitions using above flags:
+ VPU_PF_UNDEFINED = 0,
+ VPU_PF_YUV420_SEMIPLANAR = 0x00010000 | VPU_IS_SEMIPLANAR,
+ VPU_PF_YUV420_PLANAR = 0x00020000 | VPU_IS_PLANAR,
+ VPU_PF_UYVY = 0x00040000 | VPU_IS_PACKED,
+ VPU_PF_TILED_8BPP = 0x00080000 | VPU_IS_TILED | VPU_IS_SEMIPLANAR,
+ VPU_PF_TILED_10BPP = 0x00100000 | VPU_IS_TILED | VPU_IS_SEMIPLANAR | VPU_HAS_10BPP,
+};
+
+struct vpu_v4l2_fmt {
+ char *name;
+ unsigned int fourcc;
+ unsigned int num_planes;
+ unsigned int vdec_std;
+ unsigned int disable;
+};
+
+struct vb2_data_req {
+ struct list_head list;
+ struct vb2_buffer *vb2_buf;
+ int id;
+ u_int32 status;
+ bool bfield;
+ bool queued;
+ u_int32 phy_addr[2]; //0 for luma, 1 for chroma
+ u_int32 data_offset[2]; //0 for luma, 1 for chroma
+};
+
+struct queue_data {
+ unsigned int width;
+ unsigned int height;
+ unsigned int stride;
+ unsigned int bytesperline;
+ unsigned int num_planes;
+ unsigned int sizeimage[2];
+ unsigned int fourcc;
+ unsigned int vdec_std;
+ struct v4l2_rect rect;
+ int buf_type; // v4l2_buf_type
+ bool vb2_q_inited;
+ struct vb2_queue vb2_q; // vb2 queue
+ struct list_head drv_q; // driver queue
+ struct semaphore drv_q_lock;
+ struct vb2_data_req vb2_reqs[VPU_MAX_BUFFER];
+ enum QUEUE_TYPE type;
+};
+struct vpu_ctx;
+struct vpu_dev {
+ struct device *generic_dev;
+ struct v4l2_device v4l2_dev;
+ struct video_device *pvpu_decoder_dev;
+ struct platform_device *plat_dev;
+ struct firmware *m0_pfw;
+ void *m0_p_fw_space_vir;
+ u_int32 m0_p_fw_space_phy;
+ u_int32 m0_boot_size;
+ void *m0_rpc_virt;
+ u_int32 m0_rpc_phy;
+ u_int32 m0_rpc_size;
+ struct mutex dev_mutex;
+ struct mutex cmd_mutex;
+ bool fw_is_ready;
+ bool firmware_started;
+ struct completion start_cmp;
+ struct completion snap_done_cmp;
+ struct workqueue_struct *workqueue;
+ struct work_struct msg_work;
+ unsigned long instance_mask;
+ unsigned long hang_mask; //this is used to deal with hang issue to reset firmware
+ sc_ipc_t mu_ipcHandle;
+ struct clk *vpu_clk;
+ void __iomem *mu_base_virtaddr;
+ unsigned int vpu_mu_id;
+ int vpu_mu_init;
+ u_int32 plat_type;
+
+ struct clk *clk_m0;
+ void __iomem *regs_base;
+ void __iomem *csr_base;
+ u_int32 cm_offset;
+
+ struct shared_addr shared_mem;
+ struct vpu_ctx *ctx[VPU_MAX_NUM_STREAMS];
+ struct dentry *debugfs_root;
+};
+
+struct vpu_statistic {
+ unsigned long cmd[VID_API_CMD_YUV_READY + 2];
+ unsigned long event[VID_API_EVENT_DEC_CFG_INFO + 2];
+ unsigned long current_cmd;
+ unsigned long current_event;
+ struct timespec ts_cmd;
+ struct timespec ts_event;
+ atomic64_t total_dma_size;
+ atomic64_t total_alloc_size;
+};
+
+struct dma_buffer {
+ dma_addr_t dma_phy;
+ void *dma_virt;
+ u_int32 dma_size;
+};
+
+struct vpu_ctx {
+ struct vpu_dev *dev;
+ struct v4l2_fh fh;
+
+ struct vpu_statistic statistic;
+ atomic64_t total_alloc_size;
+ struct device_attribute dev_attr_instance_command;
+ char command_name[64];
+ struct device_attribute dev_attr_instance_event;
+ char event_name[64];
+ struct device_attribute dev_attr_instance_buffer;
+ char buffer_name[64];
+ struct device_attribute dev_attr_instance_flow;
+ char flow_name[64];
+ struct dentry *dbglog_dir;
+ char dbglog_name[64];
+ struct v4l2_ctrl *ctrls[V4L2_MAX_CTRLS];
+ struct v4l2_ctrl_handler ctrl_handler;
+ bool ctrl_inited;
+ struct list_head log_q;
+
+ int str_index;
+ struct queue_data q_data[2];
+ struct kfifo msg_fifo;
+ struct mutex instance_mutex;
+ struct work_struct instance_work;
+ struct workqueue_struct *instance_wq;
+ struct completion completion;
+ struct completion stop_cmp;
+ struct completion eos_cmp;
+ struct completion alloc_cmp;
+ MediaIPFW_Video_SeqInfo *pSeqinfo;
+ bool b_dis_reorder;
+ bool b_firstseq;
+ bool start_flag;
+ bool wait_abort_done;
+ bool wait_rst_done;
+ bool buffer_null;
+ bool firmware_stopped;
+ bool firmware_finished;
+ bool eos_stop_received;
+ bool eos_stop_added;
+ bool ctx_released;
+ bool start_code_bypass;
+ bool hang_status;
+ wait_queue_head_t buffer_wq;
+ u_int32 mbi_count;
+ u_int32 mbi_num;
+ u_int32 mbi_size;
+ u_int32 dcp_count;
+ struct dma_buffer dpb_buffer;
+ struct dma_buffer dcp_buffer[MAX_DCP_NUM];
+ struct dma_buffer mbi_buffer[MAX_MBI_NUM];
+ struct dma_buffer stream_buffer;
+ struct dma_buffer udata_buffer;
+
+ struct file *crc_fp;
+ loff_t pos;
+
+ int frm_dis_delay;
+ int frm_dec_delay;
+ int frm_total_num;
+};
+
+#define LVL_INFO 3
+#define LVL_EVENT 2
+#define LVL_WARN 1
+#define LVL_ERR 0
+
+#define vpu_dbg(level, fmt, arg...) \
+ do { \
+ if (vpu_dbg_level_decoder >= (level)) \
+ printk("[VPU Decoder]\t " fmt, ## arg); \
+ } while (0)
+
+#endif
diff --git a/drivers/mxc/vpu_malone/vpu_debug_log.c b/drivers/mxc/vpu_malone/vpu_debug_log.c
new file mode 100644
index 000000000000..766b824ee655
--- /dev/null
+++ b/drivers/mxc/vpu_malone/vpu_debug_log.c
@@ -0,0 +1,137 @@
+/*
+ * Copyright 2018 NXP
+ */
+
+/*
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/*!
+ * @file vpu-debug_log.c
+ *
+ * copyright here may be changed later
+ *
+ *
+ */
+#include "vpu_debug_log.h"
+
+int init_log_info_queue(struct vpu_ctx *ctx)
+{
+ if (!ctx)
+ return -EINVAL;
+
+ mutex_lock(&ctx->instance_mutex);
+ INIT_LIST_HEAD(&ctx->log_q);
+ mutex_unlock(&ctx->instance_mutex);
+ return 0;
+}
+
+int create_log_info_queue(struct vpu_ctx *ctx, u_int32 vpu_log_depth)
+{
+ struct vpu_log_info *vpu_info = NULL;
+ u_int32 i;
+
+ if (!ctx)
+ return -EINVAL;
+
+ for (i = 0; i < vpu_log_depth; i++) {
+ vpu_info = kzalloc(sizeof(*vpu_info), GFP_KERNEL);
+ if (!vpu_info)
+ continue;
+
+ atomic64_add(sizeof(*vpu_info), &ctx->statistic.total_alloc_size);
+ list_add_tail(&vpu_info->list, &ctx->log_q);
+ }
+
+ return 0;
+}
+
+int destroy_log_info_queue(struct vpu_ctx *ctx)
+{
+ struct vpu_log_info *vpu_info, *temp_info;
+ u_int32 ret = 0;
+
+ if (!ctx)
+ return -EINVAL;
+
+ mutex_lock(&ctx->instance_mutex);
+ if (list_empty(&ctx->log_q)) {
+ ret = -EINVAL;
+ goto exit;
+ }
+ list_for_each_entry_safe(vpu_info, temp_info, &ctx->log_q, list)
+ if (vpu_info) {
+ list_del_init(&vpu_info->list);
+ kfree(vpu_info);
+ atomic64_sub(sizeof(*vpu_info), &ctx->statistic.total_alloc_size);
+ }
+
+exit:
+ mutex_unlock(&ctx->instance_mutex);
+
+ return ret;
+}
+
+int put_log_info(struct vpu_ctx *ctx, struct vpu_log_info *vpu_info)
+{
+ if (!ctx || !vpu_info)
+ return -EINVAL;
+
+ mutex_lock(&ctx->instance_mutex);
+ list_add_tail(&vpu_info->list, &ctx->log_q);
+ mutex_unlock(&ctx->instance_mutex);
+
+ return 0;
+}
+
+struct vpu_log_info *pop_log_info(struct vpu_ctx *ctx)
+{
+ struct vpu_log_info *vpu_info = NULL;
+
+ if (!ctx)
+ return NULL;
+
+ mutex_lock(&ctx->instance_mutex);
+ if (list_empty(&ctx->log_q))
+ vpu_info = NULL;
+ vpu_info = list_first_entry(&ctx->log_q, struct vpu_log_info, list);
+ if (vpu_info)
+ list_del_init(&vpu_info->list);
+ mutex_unlock(&ctx->instance_mutex);
+ return vpu_info;
+}
+
+int set_log_info(struct vpu_log_info *vpu_info, enum ACTION_TYPE type, u_int32 info, u_int32 info_data)
+{
+ if (!vpu_info)
+ return -EINVAL;
+ if (type >= LOG_RESERVED)
+ return -EINVAL;
+
+ vpu_info->type = type;
+ vpu_info->log_info[type] = info;
+ vpu_info->data = info_data;
+ return 0;
+}
+
+int record_log_info(struct vpu_ctx *ctx, enum ACTION_TYPE type, u_int32 info, u_int32 info_data)
+{
+ struct vpu_log_info *vpu_info = NULL;
+
+ if (!ctx)
+ return -EINVAL;
+
+ vpu_info = pop_log_info(ctx);
+ if (!vpu_info)
+ return -EINVAL;
+ set_log_info(vpu_info, type, info, info_data);
+ put_log_info(ctx, vpu_info);
+
+ return 0;
+}
+
diff --git a/drivers/mxc/vpu_malone/vpu_debug_log.h b/drivers/mxc/vpu_malone/vpu_debug_log.h
new file mode 100644
index 000000000000..a42e9ea9a044
--- /dev/null
+++ b/drivers/mxc/vpu_malone/vpu_debug_log.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2018 NXP
+ */
+
+/*
+ * The code contained herein is licensed under the GNU Lesser General
+ * Public License. You may obtain a copy of the GNU Lesser General
+ * Public License Version 2.1 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/lgpl-license.html
+ * http://www.gnu.org/copyleft/lgpl.html
+ */
+
+/*!
+ * @file vpu_debug_log.h
+ *
+ * @brief VPU debug definition
+ *
+ */
+#ifndef _VPU_DEBUG_LOG_H_
+#define _VPU_DEBUG_LOG_H_
+#include "vpu_b0.h"
+enum ACTION_TYPE {
+ LOG_NULL = 0,
+ LOG_EVENT,
+ LOG_COMMAND,
+ LOG_PADDING,
+ LOG_EOS,
+ LOG_UPDATE_STREAM,
+ LOG_RESERVED,
+};
+
+struct vpu_log_info {
+ struct list_head list;
+ enum ACTION_TYPE type;
+ u_int32 log_info[LOG_RESERVED];
+ u_int32 data;
+};
+int init_log_info_queue(struct vpu_ctx *ctx);
+int create_log_info_queue(struct vpu_ctx *ctx, u_int32 vpu_log_depth);
+int destroy_log_info_queue(struct vpu_ctx *ctx);
+int put_log_info(struct vpu_ctx *ctx, struct vpu_log_info *vpu_info);
+struct vpu_log_info *pop_log_info(struct vpu_ctx *ctx);
+int set_log_info(struct vpu_log_info *vpu_info, enum ACTION_TYPE type, u_int32 info, u_int32 info_data);
+int record_log_info(struct vpu_ctx *ctx, enum ACTION_TYPE type, u_int32 info, u_int32 info_data);
+
+#endif
+
diff --git a/drivers/mxc/vpu_malone/vpu_rpc.c b/drivers/mxc/vpu_malone/vpu_rpc.c
new file mode 100644
index 000000000000..adf3c6d61e64
--- /dev/null
+++ b/drivers/mxc/vpu_malone/vpu_rpc.c
@@ -0,0 +1,364 @@
+/*
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2018 NXP. All rights reserved.
+ *
+ * This program 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.
+ *
+ * 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.
+ * The full GNU General Public License is included in this distribution
+ * in the file called LICENSE.GPL.
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2018 NXP. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <linux/uaccess.h>
+#include <linux/fs.h>
+#include "vpu_rpc.h"
+
+void rpc_init_shared_memory(struct shared_addr *This,
+ unsigned long long base_phy_addr,
+ void *base_virt_addr,
+ u_int32 total_size)
+{
+ pDEC_RPC_HOST_IFACE pSharedInterface;
+ unsigned int phy_addr;
+ unsigned int i;
+ MediaIPFW_Video_BufDesc *pSharedCmdBufDescPtr;
+ MediaIPFW_Video_BufDesc *pSharedMsgBufDescPtr;
+ MediaIPFW_Video_BufDesc *pDebugBufferDesc;
+ MediaIPFW_Video_BufDesc *pEngAccessBufferDesc;
+
+ This->shared_mem_phy = base_phy_addr;
+ This->shared_mem_vir = base_virt_addr;
+
+ pSharedInterface = (pDEC_RPC_HOST_IFACE)This->shared_mem_vir;
+ This->pSharedInterface = pSharedInterface;
+
+ pSharedInterface->FwExecBaseAddr = base_phy_addr;
+ pSharedInterface->FwExecAreaSize = total_size;
+
+ pSharedCmdBufDescPtr = (MediaIPFW_Video_BufDesc *)&pSharedInterface->StreamCmdBufferDesc;
+ pSharedMsgBufDescPtr = (MediaIPFW_Video_BufDesc *)&pSharedInterface->StreamMsgBufferDesc;
+
+ phy_addr = base_phy_addr + sizeof(DEC_RPC_HOST_IFACE);
+ This->cmd_mem_phy = phy_addr;
+ This->cmd_mem_vir = This->shared_mem_vir + sizeof(DEC_RPC_HOST_IFACE);
+
+ pSharedCmdBufDescPtr->uWrPtr = phy_addr;
+ pSharedCmdBufDescPtr->uRdPtr = pSharedCmdBufDescPtr->uWrPtr;
+ pSharedCmdBufDescPtr->uStart = pSharedCmdBufDescPtr->uWrPtr;
+ pSharedCmdBufDescPtr->uEnd = pSharedCmdBufDescPtr->uStart + CMD_SIZE;
+
+ phy_addr += CMD_SIZE;
+ This->msg_mem_phy = phy_addr;
+ This->msg_mem_vir = This->cmd_mem_vir + CMD_SIZE;
+
+ pSharedMsgBufDescPtr->uWrPtr = phy_addr;
+ pSharedMsgBufDescPtr->uRdPtr = pSharedMsgBufDescPtr->uWrPtr;
+ pSharedMsgBufDescPtr->uStart = pSharedMsgBufDescPtr->uWrPtr;
+ pSharedMsgBufDescPtr->uEnd = pSharedMsgBufDescPtr->uStart + MSG_SIZE;
+
+ phy_addr += MSG_SIZE;
+ This->codec_mem_phy = phy_addr;
+ This->codec_mem_vir = This->msg_mem_vir + MSG_SIZE;
+ pSharedInterface->CodecParamTabDesc.pCodecParamArrayBase = This->codec_mem_phy;
+
+ phy_addr += CODEC_SIZE;
+ This->jpeg_mem_phy = phy_addr;
+ This->jpeg_mem_vir = This->codec_mem_vir + CODEC_SIZE;
+ pSharedInterface->JpegParamTabDesc.pJpegParamArrayBase = This->jpeg_mem_phy;
+
+ phy_addr += JPEG_SIZE;
+ This->seq_mem_phy = phy_addr;
+ This->seq_mem_vir = This->jpeg_mem_vir + JPEG_SIZE;
+
+ pSharedInterface->SeqInfoTabDesc.pSeqInfoArrayBase = This->seq_mem_phy;
+
+ phy_addr += SEQ_SIZE;
+ This->pic_mem_phy = phy_addr;
+ This->pic_mem_vir = This->seq_mem_vir + SEQ_SIZE;
+
+ pSharedInterface->PicInfoTabDesc.pPicInfoArrayBase = This->pic_mem_phy;
+
+ phy_addr += PIC_SIZE;
+ This->gop_mem_phy = phy_addr;
+ This->gop_mem_vir = This->pic_mem_vir + PIC_SIZE;
+
+ pSharedInterface->GopInfoTabDesc.pGopInfoArrayBase = This->gop_mem_phy;
+
+ phy_addr += GOP_SIZE;
+ This->qmeter_mem_phy = phy_addr;
+ This->qmeter_mem_vir = This->gop_mem_vir + GOP_SIZE;
+
+ pSharedInterface->QMeterInfoTabDesc.pQMeterInfoArrayBase = This->qmeter_mem_phy;
+
+ phy_addr += QMETER_SIZE;
+ pDebugBufferDesc = &pSharedInterface->DebugBufferDesc;
+ pDebugBufferDesc->uWrPtr = base_phy_addr + M0_PRINT_OFFSET;
+ pDebugBufferDesc->uRdPtr = pDebugBufferDesc->uWrPtr;
+ pDebugBufferDesc->uStart = pDebugBufferDesc->uWrPtr;
+ pDebugBufferDesc->uEnd = pDebugBufferDesc->uStart + DEBUG_SIZE;
+
+ This->dbglog_mem_phy = phy_addr;
+ This->dbglog_mem_vir = This->qmeter_mem_vir + QMETER_SIZE;
+
+ pSharedInterface->DbgLogDesc.uDecStatusLogBase = This->dbglog_mem_phy;
+ pSharedInterface->DbgLogDesc.uDecStatusLogSize = DBGLOG_SIZE;
+ phy_addr += DBGLOG_SIZE;
+
+// phy_addr += sizeof(MediaIPFW_Video_BufDesc);
+ for (i = 0; i < VPU_MAX_NUM_STREAMS; i++) {
+ pEngAccessBufferDesc = &pSharedInterface->EngAccessBufferDesc[i];
+ pEngAccessBufferDesc->uWrPtr = phy_addr;
+ pEngAccessBufferDesc->uRdPtr = pEngAccessBufferDesc->uWrPtr;
+ pEngAccessBufferDesc->uStart = pEngAccessBufferDesc->uWrPtr;
+ pEngAccessBufferDesc->uEnd = pEngAccessBufferDesc->uStart + ENG_SIZE;
+ phy_addr += ENG_SIZE;
+ }
+
+ for (i = 0; i < VPU_MAX_NUM_STREAMS; i++) {
+ pSharedInterface->ptEncryptInfo[i] = phy_addr;
+ phy_addr += sizeof(MediaIPFW_Video_Encrypt_Info);
+ }
+}
+
+void rpc_set_stream_cfg_value(void *Interface, u_int32 str_idx, u_int32 vpu_dbe_num)
+{
+ pDEC_RPC_HOST_IFACE pSharedInterface;
+ u_int32 *CurrStrfg;
+
+ pSharedInterface = (pDEC_RPC_HOST_IFACE)Interface;
+ CurrStrfg = &pSharedInterface->StreamConfig[str_idx];
+ *CurrStrfg = 0;
+ //the value should be passed from application
+ VID_STREAM_CONFIG_STRBUFIDX_SET(0, CurrStrfg);
+ VID_STREAM_CONFIG_NOSEQ_SET(FALSE, CurrStrfg);
+ VID_STREAM_CONFIG_DEBLOCK_SET(FALSE, CurrStrfg);
+ VID_STREAM_CONFIG_DERING_SET(FALSE, CurrStrfg);
+ VID_STREAM_CONFIG_PLAY_MODE_SET(MEDIA_PLAYER_API_MODE_CONTINUOUS, CurrStrfg);
+ VID_STREAM_CONFIG_FS_CTRL_MODE_SET(MEDIA_PLAYER_FS_CTRL_MODE_EXTERNAL, CurrStrfg);
+ VID_STREAM_CONFIG_ENABLE_DCP_SET(TRUE, CurrStrfg);
+ VID_STREAM_CONFIG_NUM_STR_BUF_SET(1, CurrStrfg);
+ VID_STREAM_CONFIG_MALONE_USAGE_SET(1, CurrStrfg);
+ VID_STREAM_CONFIG_MULTI_VID_SET(FALSE, CurrStrfg);
+ VID_STREAM_CONFIG_OBFUSC_EN_SET(FALSE, CurrStrfg);
+ VID_STREAM_CONFIG_RC4_EN_SET(FALSE, CurrStrfg);
+ VID_STREAM_CONFIG_MCX_SET(TRUE, CurrStrfg);
+ VID_STREAM_CONFIG_PES_SET(FALSE, CurrStrfg);
+ VID_STREAM_CONFIG_NUM_DBE_SET(vpu_dbe_num, CurrStrfg);
+}
+
+void rpc_set_system_cfg_value(void *Interface, u_int32 regs_base)
+{
+ pDEC_RPC_HOST_IFACE pSharedInterface;
+ MEDIAIP_FW_SYSTEM_CONFIG *pSystemCfg;
+
+ pSharedInterface = (pDEC_RPC_HOST_IFACE)Interface;
+ pSystemCfg = &pSharedInterface->sSystemCfg;
+ pSystemCfg->uNumMalones = 1;
+ pSystemCfg->uMaloneBaseAddress[0] = (unsigned int)(regs_base + 0x180000);
+
+ pSystemCfg->uMaloneBaseAddress[0x1] = 0x0;
+ pSystemCfg->uHifOffset[0x0] = 0x1C000;
+ pSystemCfg->uHifOffset[0x1] = 0x0;
+
+ pSystemCfg->uDPVBaseAddr = 0x0;
+ pSystemCfg->uDPVIrqPin = 0x0;
+ pSystemCfg->uPixIfBaseAddr = (unsigned int)(regs_base + 0x180000 + 0x20000);
+ pSystemCfg->uFSLCacheBaseAddr[0] = (unsigned int)(regs_base + 0x60000);
+ pSystemCfg->uFSLCacheBaseAddr[1] = (unsigned int)(regs_base + 0x68000);
+}
+
+u_int32 rpc_MediaIPFW_Video_buffer_space_check(MediaIPFW_Video_BufDesc *pBufDesc,
+ BOOL bFull,
+ u_int32 uSize,
+ u_int32 *puUpdateAddress)
+{
+ u_int32 uPtr1;
+ u_int32 uPtr2;
+ u_int32 uStart;
+ u_int32 uEnd;
+ u_int32 uTemp;
+
+ /* bFull is FALSE when send message, write data */
+ /* bFull is TRUE when process commands, read data */
+ uPtr1 = (bFull) ? pBufDesc->uRdPtr : pBufDesc->uWrPtr;
+ uPtr2 = (bFull) ? pBufDesc->uWrPtr : pBufDesc->uRdPtr;
+
+ if (uPtr1 == uPtr2) {
+ if (bFull)
+ /* No data at all to read */
+ return 0;
+ else {
+ /* wrt pointer equal to read pointer thus the */
+ /* buffer is completely empty for further writes */
+ uStart = pBufDesc->uStart;
+ uEnd = pBufDesc->uEnd;
+ /* The address to be returned in this case is for */
+ /* the updated write pointer. */
+ uTemp = uPtr1 + uSize;
+ if (uTemp >= uEnd)
+ uTemp += (uStart - uEnd);
+ *puUpdateAddress = uTemp;
+ return (uEnd - uStart);
+ }
+ } else if (uPtr1 < uPtr2) {
+ /* return updated rd pointer address */
+ /* In this case if size was too big - we expect the */
+ /* external ftn to compare the size against the */
+ /* space returned.
+ */
+ *puUpdateAddress = uPtr1 + uSize;
+ return (uPtr2 - uPtr1);
+ }
+ /* We know the system has looped!! */
+ uStart = pBufDesc->uStart;
+ uEnd = pBufDesc->uEnd;
+ uTemp = uPtr1 + uSize;
+ if (uTemp >= uEnd)
+ uTemp += (uStart - uEnd);
+ *puUpdateAddress = uTemp;
+ return ((uEnd - uPtr1) + (uPtr2 - uStart));
+}
+
+static void rpc_update_cmd_buffer_ptr(MediaIPFW_Video_BufDesc *pCmdDesc)
+{
+ u_int32 uWritePtr;
+
+ mb();
+ uWritePtr = pCmdDesc->uWrPtr + 4;
+ if (uWritePtr >= pCmdDesc->uEnd)
+ uWritePtr = pCmdDesc->uStart;
+ pCmdDesc->uWrPtr = uWritePtr;
+}
+
+void rpc_send_cmd_buf(struct shared_addr *This,
+ u_int32 idx,
+ u_int32 cmdid,
+ u_int32 cmdnum,
+ u_int32 *local_cmddata)
+{
+ pDEC_RPC_HOST_IFACE pSharedInterface = (pDEC_RPC_HOST_IFACE)This->shared_mem_vir;
+ MediaIPFW_Video_BufDesc *pCmdDesc = &pSharedInterface->StreamCmdBufferDesc;
+ u_int32 *cmddata;
+ u_int32 i;
+ u_int32 *cmdword = (u_int32 *)(This->cmd_mem_vir+pCmdDesc->uWrPtr - pCmdDesc->uStart);
+
+ *cmdword = 0;
+ *cmdword |= ((idx & 0x000000ff) << 24);
+ *cmdword |= ((cmdnum & 0x000000ff) << 16);
+ *cmdword |= ((cmdid & 0x00003fff) << 0);
+ rpc_update_cmd_buffer_ptr(pCmdDesc);
+
+ for (i = 0; i < cmdnum; i++) {
+ cmddata = (u_int32 *)(This->cmd_mem_vir+pCmdDesc->uWrPtr - pCmdDesc->uStart);
+ *cmddata = local_cmddata[i];
+ rpc_update_cmd_buffer_ptr(pCmdDesc);
+ }
+}
+
+u_int32 rpc_MediaIPFW_Video_message_check(struct shared_addr *This)
+{
+ u_int32 uSpace;
+ u_int32 uIgnore;
+ pDEC_RPC_HOST_IFACE pSharedInterface = (pDEC_RPC_HOST_IFACE)This->shared_mem_vir;
+ MediaIPFW_Video_BufDesc *pMsgDesc = &pSharedInterface->StreamMsgBufferDesc;
+ u_int32 msgword;
+ u_int32 msgnum;
+
+ uSpace = rpc_MediaIPFW_Video_buffer_space_check(pMsgDesc, TRUE, 0, &uIgnore);
+ uSpace = (uSpace >> 2);
+ if (uSpace) {
+ /* get current msgword word */
+ msgword = *((u_int32 *)(This->msg_mem_vir+pMsgDesc->uRdPtr - pMsgDesc->uStart));
+ /* Find the number of additional words */
+ msgnum = ((msgword & 0x00ff0000) >> 16);
+
+ /*
+ * * Check the number of message words against
+ * * 1) a limit - some sort of maximum or at least
+ * * the size of the SW buffer the message is read into
+ * * 2) The space reported (where space is write ptr - read ptr in 32bit words)
+ * * It must be less than space (as opposed to <=) because
+ * * the message itself is not included in msgword
+ */
+ if (msgnum < VID_API_MESSAGE_LIMIT) {
+ if (msgnum < uSpace)
+ return API_MSG_AVAILABLE;
+ else
+ return API_MSG_INCOMPLETE;
+ } else
+ return API_MSG_BUFFER_ERROR;
+ }
+ return API_MSG_UNAVAILABLE;
+}
+
+static void rpc_update_msg_buffer_ptr(MediaIPFW_Video_BufDesc *pMsgDesc)
+{
+ u_int32 uReadPtr;
+
+ mb();
+ uReadPtr = pMsgDesc->uRdPtr + 4;
+ if (uReadPtr >= pMsgDesc->uEnd)
+ uReadPtr = pMsgDesc->uStart;
+ pMsgDesc->uRdPtr = uReadPtr;
+}
+
+void rpc_receive_msg_buf(struct shared_addr *This, struct event_msg *msg)
+{
+ unsigned int i;
+ pDEC_RPC_HOST_IFACE pSharedInterface = (pDEC_RPC_HOST_IFACE)This->shared_mem_vir;
+ MediaIPFW_Video_BufDesc *pMsgDesc = &pSharedInterface->StreamMsgBufferDesc;
+ u_int32 msgword = *((u_int32 *)(This->msg_mem_vir+pMsgDesc->uRdPtr - pMsgDesc->uStart));
+
+ msg->idx = ((msgword & 0xff000000) >> 24);
+ msg->msgnum = ((msgword & 0x00ff0000) >> 16);
+ msg->msgid = ((msgword & 0x00003fff) >> 0);
+ rpc_update_msg_buffer_ptr(pMsgDesc);
+
+ for (i = 0; i < msg->msgnum; i++) {
+ msg->msgdata[i] = *((u_int32 *)(This->msg_mem_vir+pMsgDesc->uRdPtr - pMsgDesc->uStart));
+ rpc_update_msg_buffer_ptr(pMsgDesc);
+ }
+}
diff --git a/drivers/mxc/vpu_malone/vpu_rpc.h b/drivers/mxc/vpu_malone/vpu_rpc.h
new file mode 100644
index 000000000000..36fbae8f8f63
--- /dev/null
+++ b/drivers/mxc/vpu_malone/vpu_rpc.h
@@ -0,0 +1,118 @@
+/*
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2018 NXP. All rights reserved.
+ *
+ * This program 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.
+ *
+ * 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.
+ * The full GNU General Public License is included in this distribution
+ * in the file called LICENSE.GPL.
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2018 NXP. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __VPU_IPC_H
+#define __VPU_IPC_H
+
+#include "mediasys_types.h"
+
+#define CMD_SIZE 25600
+#define MSG_SIZE 25600
+#define CODEC_SIZE 0x1000
+#define JPEG_SIZE 0x1000
+#define SEQ_SIZE 0x1000
+#define GOP_SIZE 0x1000
+#define PIC_SIZE 0x1000
+#define QMETER_SIZE 0x1000
+#define DBGLOG_SIZE 0x10000
+#define DEBUG_SIZE 0x80000
+#define ENG_SIZE 0x1000
+#define LOCAL_MSG_NUM VID_API_MESSAGE_LIMIT
+#define M0_PRINT_OFFSET 0x180000
+
+struct shared_addr {
+ pDEC_RPC_HOST_IFACE pSharedInterface;
+ unsigned long long shared_mem_phy;
+ void *shared_mem_vir;
+ unsigned long long cmd_mem_phy;
+ void *cmd_mem_vir;
+ unsigned long long msg_mem_phy;
+ void *msg_mem_vir;
+ unsigned long long codec_mem_phy;
+ void *codec_mem_vir;
+ unsigned long long jpeg_mem_phy;
+ void *jpeg_mem_vir;
+ unsigned long long seq_mem_phy;
+ void *seq_mem_vir;
+ unsigned long long pic_mem_phy;
+ void *pic_mem_vir;
+ unsigned long long gop_mem_phy;
+ void *gop_mem_vir;
+ unsigned long long qmeter_mem_phy;
+ void *qmeter_mem_vir;
+ unsigned long long dbglog_mem_phy;
+ void *dbglog_mem_vir;
+};
+
+struct event_msg {
+ u_int32 idx;
+ u_int32 msgnum;
+ u_int32 msgid;
+ u_int32 msgdata[LOCAL_MSG_NUM];
+};
+
+void rpc_init_shared_memory(struct shared_addr *This,
+ unsigned long long base_phy_addr,
+ void *base_virt_addr,
+ u_int32 total_size);
+void rpc_set_system_cfg_value(void *Interface, u_int32 regs_base);
+void rpc_set_stream_cfg_value(void *Interface, u_int32 str_idx, u_int32 vpu_dbe_num);
+void rpc_send_cmd_buf(struct shared_addr *This,
+ u_int32 idx,
+ u_int32 cmdid,
+ u_int32 cmdnum,
+ u_int32 *local_cmddata);
+void rpc_receive_msg_buf(struct shared_addr *This, struct event_msg *msg);
+
+#endif
diff --git a/drivers/mxc/vpu_windsor/Kconfig b/drivers/mxc/vpu_windsor/Kconfig
new file mode 100644
index 000000000000..11562a6475c6
--- /dev/null
+++ b/drivers/mxc/vpu_windsor/Kconfig
@@ -0,0 +1,25 @@
+#
+# Codec configuration
+#
+
+menu "MXC VPU(Video Processing Unit) WINDSOR ENCODER support"
+
+config MXC_VPU_WINDSOR
+ tristate "Support for MXC VPU(Video Processing Unit) WINDSOR ENCODER"
+ depends on MEDIA_SUPPORT
+ depends on VIDEO_DEV
+ depends on VIDEO_V4L2
+ select VIDEOBUF2_DMA_CONTIG
+ select VIDEOBUF2_VMALLOC
+ default y
+ ---help---
+ The VPU codec device provides codec function for H.264 etc.
+
+config MXC_VPU_WINDSOR_DEBUG
+ bool "MXC VPU WINDSOR ENCODER debugging"
+ depends on MXC_VPU_WINDSOR != n
+ help
+ This is an option for the developers; most people should
+ say N here. This enables MXC VPU WINDSOR Encoder driver debugging.
+
+endmenu
diff --git a/drivers/mxc/vpu_windsor/Makefile b/drivers/mxc/vpu_windsor/Makefile
new file mode 100644
index 000000000000..14bbfe66cb55
--- /dev/null
+++ b/drivers/mxc/vpu_windsor/Makefile
@@ -0,0 +1,15 @@
+##
+## Makefile for the VPU and M0 driver
+##
+
+EXTRA_CFLAGS += $(DEFINES)
+
+obj-$(CONFIG_MXC_VPU_WINDSOR) = vpu-windsor.o
+vpu-windsor-objs = vpu_encoder_b0.o \
+ vpu_encoder_ctrl.o \
+ vpu_event_msg.o \
+ vpu_encoder_mem.o \
+ vpu_encoder_rpc.o
+
+clean:
+ rm -rf $(vpu-windsor-objs)
diff --git a/drivers/mxc/vpu_windsor/mediasys_types.h b/drivers/mxc/vpu_windsor/mediasys_types.h
new file mode 100644
index 000000000000..62a187ae1dd7
--- /dev/null
+++ b/drivers/mxc/vpu_windsor/mediasys_types.h
@@ -0,0 +1,705 @@
+/*
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2018 NXP. All rights reserved.
+ *
+ * This program 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.
+ *
+ * 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.
+ * The full GNU General Public License is included in this distribution
+ * in the file called LICENSE.GPL.
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2018 NXP. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _MEDIASYS_TYPES_H_
+#define _MEDIASYS_TYPES_H_
+
+typedef unsigned int u_int32;
+typedef unsigned char u_int8;
+typedef unsigned long u_int64;
+typedef unsigned int BOOL;
+typedef int int32;
+#define FALSE 0
+#define TRUE 1
+#define VID_API_NUM_STREAMS 8
+#define VID_API_MAX_BUF_PER_STR 3
+#define VID_API_MAX_NUM_MVC_VIEWS 4
+#define MEDIAIP_MAX_NUM_MALONES 2
+#define MEDIAIP_MAX_NUM_MALONE_IRQ_PINS 2
+#define MEDIAIP_MAX_NUM_WINDSORS 1
+#define MEDIAIP_MAX_NUM_WINDSOR_IRQ_PINS 2
+#define MEDIAIP_MAX_NUM_CMD_IRQ_PINS 2
+#define MEDIAIP_MAX_NUM_MSG_IRQ_PINS 1
+#define MEDIAIP_MAX_NUM_TIMER_IRQ_PINS 4
+#define MEDIAIP_MAX_NUM_TIMER_IRQ_SLOTS 4
+#define VID_API_COMMAND_LIMIT 64
+#define VID_API_MESSAGE_LIMIT 256
+
+#define API_CMD_AVAILABLE 0x0
+#define API_CMD_INCOMPLETE 0x1
+#define API_CMD_BUFFER_ERROR 0x2
+#define API_CMD_UNAVAILABLE 0x3
+#define API_MSG_AVAILABLE 0x0
+#define API_MSG_INCOMPLETE 0x1
+#define API_MSG_BUFFER_ERROR 0x2
+#define API_MSG_UNAVAILABLE 0x3
+#define MEDIAIP_ENC_USER_DATA_WORDS 16
+#define MEDIAIP_MAX_NUM_WINDSOR_SRC_FRAMES 0x6
+#define MEDIAIP_MAX_NUM_WINDSOR_REF_FRAMES 0x3
+
+typedef enum {
+ GTB_ENC_CMD_NOOP = 0x0,
+ GTB_ENC_CMD_STREAM_START,
+ GTB_ENC_CMD_FRAME_ENCODE,
+ GTB_ENC_CMD_FRAME_SKIP,
+ GTB_ENC_CMD_STREAM_STOP,
+ GTB_ENC_CMD_PARAMETER_UPD,
+ GTB_ENC_CMD_TERMINATE,
+ GTB_ENC_CMD_SNAPSHOT,
+ GTB_ENC_CMD_ROLL_SNAPSHOT,
+ GTB_ENC_CMD_LOCK_SCHEDULER,
+ GTB_ENC_CMD_UNLOCK_SCHEDULER,
+ GTB_ENC_CMD_CONFIGURE_CODEC,
+ GTB_ENC_CMD_DEAD_MARK,
+ GTB_ENC_CMD_FIRM_RESET,
+ GTB_ENC_CMD_RESERVED
+} GTB_ENC_CMD;
+
+typedef enum {
+ VID_API_EVENT_UNDEFINED = 0x0,
+ VID_API_ENC_EVENT_RESET_DONE = 0x1,
+ VID_API_ENC_EVENT_START_DONE,
+ VID_API_ENC_EVENT_STOP_DONE,
+ VID_API_ENC_EVENT_TERMINATE_DONE,
+ VID_API_ENC_EVENT_FRAME_INPUT_DONE,
+ VID_API_ENC_EVENT_FRAME_DONE,
+ VID_API_ENC_EVENT_FRAME_RELEASE,
+ VID_API_ENC_EVENT_PARA_UPD_DONE,
+ VID_API_ENC_EVENT_MEM_REQUEST,
+ VID_API_ENC_EVENT_FIRMWARE_XCPT,
+ VID_API_ENC_EVENT_RESERVED
+} ENC_TB_API_ENC_EVENT;
+
+typedef enum {
+ MEDIAIP_ENC_PIC_TYPE_B_FRAME = 0,
+ MEDIAIP_ENC_PIC_TYPE_P_FRAME,
+ MEDIAIP_ENC_PIC_TYPE_I_FRAME,
+ MEDIAIP_ENC_PIC_TYPE_IDR_FRAME,
+ MEDIAIP_ENC_PIC_TYPE_BI_FRAME
+
+} MEDIAIP_ENC_PIC_TYPE, *pMEDIAIP_ENC_PIC_TYPE;
+
+typedef struct {
+ u_int32 uMemPhysAddr;
+ u_int32 uMemVirtAddr;
+ u_int32 uMemSize;
+} MEDIAIP_ENC_MEM_RESOURCE, *pMEDIAIP_ENC_MEM_RESOURCE;
+
+typedef struct {
+ u_int32 uEncFrmSize;
+ u_int32 uEncFrmNum;
+ u_int32 uRefFrmSize;
+ u_int32 uRefFrmNum;
+ u_int32 uActBufSize;
+} MEDIAIP_ENC_MEM_REQ_DATA, *pMEDIAIP_ENC_MEM_REQ_DATA;
+
+typedef struct {
+ MEDIAIP_ENC_MEM_RESOURCE tEncFrameBuffers[MEDIAIP_MAX_NUM_WINDSOR_SRC_FRAMES];
+ MEDIAIP_ENC_MEM_RESOURCE tRefFrameBuffers[MEDIAIP_MAX_NUM_WINDSOR_REF_FRAMES];
+ MEDIAIP_ENC_MEM_RESOURCE tActFrameBufferArea;
+} MEDIAIP_ENC_MEM_POOL, *pMEDIAIP_ENC_MEM_POOL;
+
+///////////////////////////////////////////
+// MEDIAIP_ENC_PIC_TYPE
+
+typedef struct {
+ u_int32 uFrameID;
+ u_int32 uPicEncodDone;
+ MEDIAIP_ENC_PIC_TYPE ePicType;
+ u_int32 uSkippedFrame;
+ u_int32 uErrorFlag;
+ u_int32 uPSNR;
+ u_int32 uFlushDone;
+ u_int32 uMBy;
+ u_int32 uMBx;
+ u_int32 uFrameSize;
+ u_int32 uFrameEncTtlCycles;
+ u_int32 uFrameEncTtlFrmCycles;
+ u_int32 uFrameEncTtlSlcCycles;
+ u_int32 uFrameEncTtlEncCycles;
+ u_int32 uFrameEncTtlHmeCycles;
+ u_int32 uFrameEncTtlDsaCycles;
+ u_int32 uFrameEncFwCycles;
+ u_int32 uFrameCrc;
+ u_int32 uNumInterrupts_1;
+ u_int32 uNumInterrupts_2;
+ u_int32 uH264POC;
+ u_int32 uRefInfo;
+ u_int32 uPicNum;
+ u_int32 uPicActivity;
+ u_int32 uSceneChange;
+ u_int32 uMBStats;
+ u_int32 uEncCacheCount0;
+ u_int32 uEncCacheCount1;
+ u_int32 uMtlWrStrbCnt;
+ u_int32 uMtlRdStrbCnt;
+ u_int32 uStrBuffWrPtr;
+ u_int32 uDiagnosticEvents;
+
+ u_int32 uProcIaccTotRdCnt;
+ u_int32 uProcDaccTotRdCnt;
+ u_int32 uProcDaccTotWrCnt;
+ u_int32 uProcDaccRegRdCnt;
+ u_int32 uProcDaccRegWrCnt;
+ u_int32 uProcDaccRngRdCnt;
+ u_int32 uProcDaccRngWrCnt;
+
+} MEDIAIP_ENC_PIC_INFO, *pMEDIAIP_ENC_PIC_INFO;
+
+typedef enum {
+ MEDIAIP_PLAYMODE_CONNECTIVITY = 0,
+ MEDIAIP_PLAYMODE_BROADCAST,
+ MEDIAIP_PLAYMODE_BROADCAST_DSS,
+ MEDIAIP_PLAYMODE_LAST = MEDIAIP_PLAYMODE_BROADCAST_DSS
+
+} MEDIA_IP_PLAYMODE;
+
+typedef struct {
+ u_int32 wptr;
+ u_int32 rptr;
+ u_int32 start;
+ u_int32 end;
+
+} BUFFER_DESCRIPTOR_TYPE, *pBUFFER_DESCRIPTOR_TYPE;
+
+typedef struct {
+ u_int32 uWrPtr;
+ u_int32 uRdPtr;
+ u_int32 uStart;
+ u_int32 uEnd;
+ u_int32 uLo;
+ u_int32 uHi;
+
+} MediaIPFW_Video_BufDesc;
+
+typedef struct {
+ u_int32 uCfgCookie;
+
+ u_int32 uNumMalones;
+ u_int32 uMaloneBaseAddress[MEDIAIP_MAX_NUM_MALONES];
+ u_int32 uHifOffset[MEDIAIP_MAX_NUM_MALONES];
+ u_int32 uMaloneIrqPin[MEDIAIP_MAX_NUM_MALONES][MEDIAIP_MAX_NUM_MALONE_IRQ_PINS];
+ u_int32 uMaloneIrqTarget[MEDIAIP_MAX_NUM_MALONES][MEDIAIP_MAX_NUM_MALONE_IRQ_PINS];
+
+ u_int32 uNumWindsors;
+ u_int32 uWindsorBaseAddress[MEDIAIP_MAX_NUM_WINDSORS];
+ u_int32 uWindsorIrqPin[MEDIAIP_MAX_NUM_WINDSORS][MEDIAIP_MAX_NUM_WINDSOR_IRQ_PINS];
+ u_int32 uWindsorIrqTarget[MEDIAIP_MAX_NUM_WINDSORS][MEDIAIP_MAX_NUM_WINDSOR_IRQ_PINS];
+
+ u_int32 uCmdIrqPin[MEDIAIP_MAX_NUM_CMD_IRQ_PINS];
+ u_int32 uCmdIrqTarget[MEDIAIP_MAX_NUM_CMD_IRQ_PINS];
+
+ u_int32 uMsgIrqPin[MEDIAIP_MAX_NUM_MSG_IRQ_PINS];
+ u_int32 uMsgIrqTarget[MEDIAIP_MAX_NUM_MSG_IRQ_PINS];
+
+ u_int32 uSysClkFreq;
+ u_int32 uNumTimers;
+ u_int32 uTimerBaseAddr;
+ u_int32 uTimerIrqPin[MEDIAIP_MAX_NUM_TIMER_IRQ_PINS];
+ u_int32 uTimerIrqTarget[MEDIAIP_MAX_NUM_TIMER_IRQ_PINS];
+ u_int32 uTimerSlots[MEDIAIP_MAX_NUM_TIMER_IRQ_SLOTS];
+
+ u_int32 uGICBaseAddr;
+ u_int32 uUartBaseAddr;
+
+ u_int32 uDPVBaseAddr;
+ u_int32 uDPVIrqPin;
+ u_int32 uDPVIrqTarget;
+
+ u_int32 uPixIfBaseAddr;
+
+ u_int32 pal_trace_level;
+ u_int32 pal_trace_destination;
+
+ u_int32 pal_trace_level1;
+ u_int32 pal_trace_destination1;
+
+ u_int32 uHeapBase;
+ u_int32 uHeapSize;
+
+ u_int32 uFSLCacheBaseAddr[2];
+
+} MEDIAIP_FW_SYSTEM_CONFIG, *pMEDIAIP_FW_SYSTEM_CONFIG;
+
+typedef struct {
+ u_int32 uFrameID;
+ u_int32 uLumaBase;
+ u_int32 uChromaBase;
+ u_int32 uParamIdx;
+ u_int32 uKeyFrame;
+} MEDIAIP_ENC_YUV_BUFFER_DESC, *pMEDIAIP_ENC_YUV_BUFFER_DESC;
+
+typedef struct {
+ u_int32 use_ame;
+
+ u_int32 cme_mvx_max;
+ u_int32 cme_mvy_max;
+ u_int32 ame_prefresh_y0;
+ u_int32 ame_prefresh_y1;
+ u_int32 fme_min_sad;
+ u_int32 cme_min_sad;
+
+ u_int32 fme_pred_int_weight;
+ u_int32 fme_pred_hp_weight;
+ u_int32 fme_pred_qp_weight;
+ u_int32 fme_cost_weight;
+ u_int32 fme_act_thold;
+ u_int32 fme_sad_thold;
+ u_int32 fme_zero_sad_thold;
+
+ u_int32 fme_lrg_mvx_lmt;
+ u_int32 fme_lrg_mvy_lmt;
+ u_int32 fme_force_mode;
+ u_int32 fme_force4mvcost;
+ u_int32 fme_force2mvcost;
+
+ u_int32 h264_inter_thrd;
+
+ u_int32 i16x16_mode_cost;
+ u_int32 i4x4_mode_lambda;
+ u_int32 i8x8_mode_lambda;
+
+ u_int32 inter_mod_mult;
+ u_int32 inter_sel_mult;
+ u_int32 inter_bid_cost;
+ u_int32 inter_bwd_cost;
+ u_int32 inter_4mv_cost;
+ int32 one_mv_i16_cost;
+ int32 one_mv_i4x4_cost;
+ int32 one_mv_i8x8_cost;
+ int32 two_mv_i16_cost;
+ int32 two_mv_i4x4_cost;
+ int32 two_mv_i8x8_cost;
+ int32 four_mv_i16_cost;
+ int32 four_mv_i4x4_cost;
+ int32 four_mv_i8x8_cost;
+
+ u_int32 intra_pred_enab;
+ u_int32 intra_chr_pred;
+ u_int32 intra16_pred;
+ u_int32 intra4x4_pred;
+ u_int32 intra8x8_pred;
+
+ u_int32 cb_base;
+ u_int32 cb_size;
+ u_int32 cb_head_room;
+
+ u_int32 mem_page_width;
+ u_int32 mem_page_height;
+ u_int32 mem_total_size;
+ u_int32 mem_chunk_phys_addr;
+ u_int32 mem_chunk_virt_addr;
+ u_int32 mem_chunk_size;
+ u_int32 mem_y_stride;
+ u_int32 mem_uv_stride;
+
+ u_int32 split_wr_enab;
+ u_int32 split_wr_req_size;
+ u_int32 split_rd_enab;
+ u_int32 split_rd_req_size;
+
+} MEDIAIP_ENC_CALIB_PARAMS, *pMEDIAIP_ENC_CALIB_PARAMS;
+
+typedef struct {
+ u_int32 ParamChange;
+
+ u_int32 start_frame; // These variables are for debugging purposes only
+ u_int32 end_frame;
+
+ u_int32 userdata_enable;
+ u_int32 userdata_id[4];
+ u_int32 userdata_message[MEDIAIP_ENC_USER_DATA_WORDS];
+ u_int32 userdata_length;
+
+ u_int32 h264_profile_idc;
+ u_int32 h264_level_idc;
+ u_int32 h264_au_delimiter; // Enable the use of Access Unit Delimiters
+ u_int32 h264_seq_end_code; // Enable the use of Sequence End Codes
+ u_int32 h264_recovery_points; // Enable the use of Recovery Points (must be with a fixed GOP structure)
+ u_int32 h264_vui_parameters; // Enable the use of VUI parameters (for rate control purposes)
+ u_int32 h264_aspect_ratio_present;
+ u_int32 h264_aspect_ratio_sar_width;
+ u_int32 h264_aspect_ratio_sar_height;
+ u_int32 h264_overscan_present;
+ u_int32 h264_video_type_present;
+ u_int32 h264_video_format;
+ u_int32 h264_video_full_range;
+ u_int32 h264_video_colour_descriptor;
+ u_int32 h264_video_colour_primaries;
+ u_int32 h264_video_transfer_char;
+ u_int32 h264_video_matrix_coeff;
+ u_int32 h264_chroma_loc_info_present;
+ u_int32 h264_chroma_loc_type_top;
+ u_int32 h264_chroma_loc_type_bot;
+ u_int32 h264_timing_info_present;
+ u_int32 h264_buffering_period_present;
+ u_int32 h264_low_delay_hrd_flag;
+
+ u_int32 aspect_ratio;
+ u_int32 test_mode; // Automated firmware test mode
+ u_int32 dsa_test_mode; // Automated test mode for the DSA.
+ u_int32 fme_test_mode; // Automated test mode for the fme
+
+ u_int32 cbr_row_mode; //0: FW mode; 1: HW mode
+ u_int32 windsor_mode; //0: normal mode; 1: intra only mode; 2: intra+0MV mode
+ u_int32 encode_mode; // H264, VC1, MPEG2, DIVX
+ u_int32 frame_width; // display width
+ u_int32 frame_height; // display height
+ u_int32 enc_frame_width; // encoding width, should be 16-pix align
+ u_int32 enc_frame_height; // encoding height, should be 16-pix aligned for progressive and 32-pix aligned for interlace
+ u_int32 frame_rate_num;
+ u_int32 frame_rate_den;
+
+ u_int32 vi_field_source; // vi input source is frame or field
+ u_int32 vi_frame_width;
+ u_int32 vi_frame_height;
+ u_int32 crop_frame_width;
+ u_int32 crop_frame_height;
+ u_int32 crop_x_start_posn;
+ u_int32 crop_y_start_posn;
+ u_int32 mode422;
+ u_int32 mode_yuy2;
+ u_int32 dsa_luma_en;
+ u_int32 dsa_chroma_en;
+ u_int32 dsa_ext_hfilt_en;
+ u_int32 dsa_di_en;
+ u_int32 dsa_di_top_ref;
+ u_int32 dsa_vertf_disable; // disable the vertical filter.
+ u_int32 dsa_disable_pwb;
+ u_int32 dsa_hor_phase;
+ u_int32 dsa_ver_phase;
+
+ u_int32 dsa_iac_enable; // IAC / DSA cannot operate independently in FW so this variable controls
+ u_int32 iac_sc_threshold;
+ u_int32 iac_vm_threshold;
+ u_int32 iac_skip_mode;
+ u_int32 iac_grp_width;
+ u_int32 iac_grp_height;
+
+ u_int32 rate_control_mode;
+ u_int32 rate_control_resolution;
+ u_int32 buffer_size;
+ u_int32 buffer_level_init;
+ u_int32 buffer_I_bit_budget;
+
+ u_int32 top_field_first;
+
+ u_int32 intra_lum_qoffset;
+ u_int32 intra_chr_qoffset;
+ u_int32 inter_lum_qoffset;
+ u_int32 inter_chr_qoffset;
+ u_int32 use_def_scaling_mtx;
+
+ u_int32 inter_8x8_enab;
+ u_int32 inter_4x4_enab;
+
+ u_int32 fme_enable_qpel;
+ u_int32 fme_enable_hpel;
+ u_int32 fme_nozeromv; // can force the FME not to do the (0,0) search.
+ u_int32 fme_predmv_en;
+ u_int32 fme_pred_2mv4mv;
+ u_int32 fme_smallsadthresh;
+
+ u_int32 ame_en_lmvc;
+ u_int32 ame_x_mult;
+ u_int32 cme_enable_4mv; // Enable the use of 4MV partitioning
+ u_int32 cme_enable_1mv;
+ u_int32 hme_enable_16x8mv;
+ u_int32 hme_enable_8x16mv;
+ u_int32 cme_mv_weight; // CME motion vector decisions are made by combining these
+ u_int32 cme_mv_cost; // cost and weight variables
+ u_int32 ame_mult_mv;
+ u_int32 ame_shift_mv;
+
+ u_int32 hme_forceto1mv_en;
+ u_int32 hme_2mv_cost; // the cost of choosing a 2MV mode over 1MV.
+ u_int32 hme_pred_mode;
+ u_int32 hme_sc_rnge;
+ u_int32 hme_sw_rnge;
+
+ // for windsor pes , add by fulin
+ u_int32 output_format; // 0: output ES; 1: output PES
+ u_int32 timestamp_enab; // 0: have timestamps in all frame; 1: have timestamps in I and P frame; 2: have timestamps only in I frame
+ u_int32 initial_PTS_enab; // if enabled , use following value,else compute by fw
+ u_int32 initial_PTS; // the initial value of PTS in the first frame (ms)
+
+} MEDIAIP_ENC_CONFIG_PARAMS, *pMEDIAIP_ENC_CONFIG_PARAMS;
+
+typedef struct {
+ u_int32 ParamChange;
+
+ u_int32 gop_length;
+
+ u_int32 rate_control_bitrate;
+ u_int32 rate_control_bitrate_min;
+ u_int32 rate_control_bitrate_max;
+ u_int32 rate_control_content_models;
+ u_int32 rate_control_iframe_maxsize; // Maximum size of I frame generated by BPM in comparison to ideal (/4)
+ u_int32 rate_control_qp_init;
+ u_int32 rate_control_islice_qp;
+ u_int32 rate_control_pslice_qp;
+ u_int32 rate_control_bslice_qp;
+
+ u_int32 adaptive_quantization; // Enable the use of activity measures from VIPP in QP assignment
+ u_int32 aq_variance;
+ u_int32 cost_optimization; // Enable picture/frame level adjustments of the cost parameters by FW.
+ u_int32 fdlp_mode; // Frequency-domain low-pass filter control, 0: off, 1-4: specific, 5: adaptive
+ u_int32 enable_isegbframes; // Enable the use of B frames in the first segment of a GOP
+ u_int32 enable_adaptive_keyratio; // Enable the use of an adaptive I to P/B ratio (aims to reduce distortion)
+ u_int32 keyratio_imin; // Clamps applied to picture size ratios
+ u_int32 keyratio_imax;
+ u_int32 keyratio_pmin;
+ u_int32 keyratio_pmax;
+ u_int32 keyratio_bmin;
+ u_int32 keyratio_bmax;
+ int32 keyratio_istep;
+ int32 keyratio_pstep;
+ int32 keyratio_bstep;
+
+ u_int32 enable_paff; // Enable Picture Adaptive Frame/Field
+ u_int32 enable_b_frame_ref; // Enable B frame as references
+ u_int32 enable_adaptive_gop; // Enable an adaptive GOP structure
+ u_int32 enable_closed_gop; // Enable a closed GOP structure
+ // i.e. if enabled, the first consecutive B frames following
+ // an I frame in each GOP will be intra or backwards only coded
+ // and do not rely on previous reference pictures.
+ u_int32 open_gop_refresh_freq; // Controls the insertion of closed GOP's (or IDR GOP's in H.264)
+ u_int32 enable_adaptive_sc; // Enable adaptive scene change GOP structure (0:off, 1:adaptive, 2:IDR)
+ u_int32 enable_fade_detection; // Enable fade detection and associated motion estimation restrictions
+ int32 fade_detection_threshold; // Threshold at which the activity slope indicates a possible fading event
+ u_int32 enable_repeat_b; // Enalbe the repeated B frame mode at CBR
+ u_int32 enable_low_delay_b; // Use low delay-b frames with an IPPPP style GOP
+
+} MEDIAIP_ENC_STATIC_PARAMS, *pMEDIAIP_ENC_STATIC_PARAMS;
+
+typedef struct {
+ u_int32 ParamChange;
+
+ u_int32 rows_per_slice;
+
+ u_int32 mbaff_enable; // Macroblock adaptive frame/field enable
+ u_int32 dbf_enable; // Enable the deblocking filter
+
+ u_int32 field_source; // progressive/interlaced control
+ u_int32 gop_b_length; // Number of B frames between anchor frames
+ // (only to be changed at a GOP segment boundary)
+ u_int32 mb_group_size; // Number of macroblocks normally assigned to a group
+ // (implications for performance, interrupts and rate control)
+
+ u_int32 cbr_rows_per_group;
+
+ u_int32 skip_enable; // Enable the use of skipped macroblocks
+
+ u_int32 pts_bits_0_to_31; // TO BE REMOVED...
+ u_int32 pts_bit_32;
+
+ u_int32 rm_expsv_cff;
+ u_int32 const_ipred;
+ int32 chr_qp_offset;
+ u_int32 intra_mb_qp_offset;
+
+ u_int32 h264_cabac_init_method;
+ u_int32 h264_cabac_init_idc;
+ u_int32 h264_cabac_enable; // Main and stream
+
+ int32 alpha_c0_offset_div2;
+ int32 beta_offset_div2;
+
+ u_int32 intra_prefresh_y0; // for setting intra limits for prog refresh.
+ u_int32 intra_prefresh_y1;
+
+ u_int32 dbg_dump_rec_src;
+
+} MEDIAIP_ENC_DYN_PARAMS, *pMEDIAIP_ENC_DYN_PARAMS;
+
+typedef struct {
+ MEDIAIP_ENC_CALIB_PARAMS Calib;
+ MEDIAIP_ENC_CONFIG_PARAMS Config;
+ MEDIAIP_ENC_STATIC_PARAMS Static;
+ MEDIAIP_ENC_DYN_PARAMS Dynamic;
+} MEDIAIP_ENC_EXPERT_MODE_PARAM, *pMEDIAIP_ENC_EXPERT_MODE_PARAM;
+
+typedef enum {
+ MEDIAIP_ENC_FMT_H264 = 0,
+ MEDIAIP_ENC_FMT_VC1,
+ MEDIAIP_ENC_FMT_MPEG2,
+ MEDIAIP_ENC_FMT_MPEG4SP,
+ MEDIAIP_ENC_FMT_H263,
+ MEDIAIP_ENC_FMT_MPEG1,
+ MEDIAIP_ENC_FMT_SHORT_HEADER,
+ MEDIAIP_ENC_FMT_NULL
+
+} MEDIAIP_ENC_FMT;
+
+typedef enum {
+ MEDIAIP_ENC_PROF_MPEG2_SP = 0,
+ MEDIAIP_ENC_PROF_MPEG2_MP,
+ MEDIAIP_ENC_PROF_MPEG2_HP,
+ MEDIAIP_ENC_PROF_H264_BP,
+ MEDIAIP_ENC_PROF_H264_MP,
+ MEDIAIP_ENC_PROF_H264_HP,
+ MEDIAIP_ENC_PROF_MPEG4_SP,
+ MEDIAIP_ENC_PROF_MPEG4_ASP,
+ MEDIAIP_ENC_PROF_VC1_SP,
+ MEDIAIP_ENC_PROF_VC1_MP,
+ MEDIAIP_ENC_PROF_VC1_AP
+
+} MEDIAIP_ENC_PROFILE;
+
+typedef enum {
+ MEDIAIP_ENC_BITRATECONTROLMODE_VBR = 0x00000001,
+ MEDIAIP_ENC_BITRATECONTROLMODE_CBR = 0x00000002,
+ MEDIAIP_ENC_BITRATECONTROLMODE_CONSTANT_QP = 0x00000004 /* Only in debug mode */
+
+} MEDIAIP_ENC_BITRATE_MODE, *pMEDIAIP_ENC_BITRATE_MODE;
+
+typedef struct {
+ MEDIAIP_ENC_FMT eCodecMode;
+ MEDIAIP_ENC_PROFILE eProfile;
+ u_int32 uLevel;
+
+ MEDIAIP_ENC_MEM_RESOURCE tEncMemDesc;
+
+ u_int32 uFrameRate;
+ u_int32 uSrcStride;
+ u_int32 uSrcWidth;
+ u_int32 uSrcHeight;
+ u_int32 uSrcOffset_x;
+ u_int32 uSrcOffset_y;
+ u_int32 uSrcCropWidth;
+ u_int32 uSrcCropHeight;
+ u_int32 uOutWidth;
+ u_int32 uOutHeight;
+ u_int32 uIFrameInterval;
+ u_int32 uGopBLength;
+ u_int32 uLowLatencyMode;
+
+ MEDIAIP_ENC_BITRATE_MODE eBitRateMode;
+ u_int32 uTargetBitrate;
+ u_int32 uMaxBitRate;
+ u_int32 uMinBitRate;
+ u_int32 uInitSliceQP;
+
+} MEDIAIP_ENC_PARAM, *pMEDIAIP_ENC_PARAM;
+
+typedef struct {
+ u_int32 uFrameID;
+ u_int32 uErrorFlag; //Error type
+ u_int32 uMBy;
+ u_int32 uMBx;
+ u_int32 uReserved[12];
+
+} ENC_ENCODING_STATUS, *pENC_ENCODING_STATUS;
+
+typedef struct {
+ u_int32 uFrameID;
+ u_int32 uDsaCyle;
+ u_int32 uMBy;
+ u_int32 uMBx;
+ u_int32 uReserved[4];
+
+} ENC_DSA_STATUS_t, *pENC_DSA_STATUS_t;
+
+typedef struct {
+ u_int32 pEncYUVBufferDesc;
+ u_int32 pEncStreamBufferDesc;
+ u_int32 pEncExpertModeParam;
+ u_int32 pEncParam;
+ u_int32 pEncMemPool;
+ /* Status information for master to read */
+ u_int32 pEncEncodingStatus;
+ u_int32 pEncDSAStatus;
+} MEDIA_ENC_API_CONTROL_INTERFACE, *pMEDIA_ENC_API_CONTROL_INTERFACE;
+
+typedef struct {
+ u_int32 FwExecBaseAddr;
+ u_int32 FwExecAreaSize;
+ BUFFER_DESCRIPTOR_TYPE StreamCmdBufferDesc;
+ BUFFER_DESCRIPTOR_TYPE StreamMsgBufferDesc;
+ u_int32 StreamCmdIntEnable[VID_API_NUM_STREAMS];
+ u_int32 FWVersion;
+ u_int32 uMVDFWOffset;
+ u_int32 uMaxEncoderStreams;
+ u_int32 pEncCtrlInterface[VID_API_NUM_STREAMS];
+ MEDIAIP_FW_SYSTEM_CONFIG sSystemCfg;
+ u_int32 uApiVersion;
+ BUFFER_DESCRIPTOR_TYPE DebugBufferDesc;
+} ENC_RPC_HOST_IFACE, *pENC_RPC_HOST_IFACE;
+
+#define SCB_XREG_SLV_BASE 0x00000000
+#define SCB_SCB_BLK_CTRL 0x00070000
+#define SCB_BLK_CTRL_XMEM_RESET_SET 0x00000090
+#define SCB_BLK_CTRL_CACHE_RESET_SET 0x000000A0
+#define SCB_BLK_CTRL_CACHE_RESET_CLR 0x000000A4
+#define SCB_BLK_CTRL_SCB_CLK_ENABLE_SET 0x00000100
+
+#define XMEM_CONTROL 0x00041000
+
+#define DEC_MFD_XREG_SLV_BASE 0x00180000
+
+#define MFD_HIF 0x0001C000
+#define MFD_HIF_MSD_REG_INTERRUPT_STATUS 0x00000018
+#define MFD_SIF 0x0001D000
+#define MFD_SIF_CTRL_STATUS 0x000000F0
+#define MFD_SIF_INTR_STATUS 0x000000F4
+#define MFD_MCX 0x00020800
+#define MFD_MCX_OFF 0x00000020
+
+#define MFD_BLK_CTRL 0x00030000
+#define MFD_BLK_CTRL_MFD_SYS_RESET_SET 0x00000000
+#define MFD_BLK_CTRL_MFD_SYS_RESET_CLR 0x00000004
+#define MFD_BLK_CTRL_MFD_SYS_CLOCK_ENABLE_SET 0x00000100
+#define MFD_BLK_CTRL_MFD_SYS_CLOCK_ENABLE_CLR 0x00000104
+
+#endif
diff --git a/drivers/mxc/vpu_windsor/vpu_encoder_b0.c b/drivers/mxc/vpu_windsor/vpu_encoder_b0.c
new file mode 100644
index 000000000000..e9e43247b828
--- /dev/null
+++ b/drivers/mxc/vpu_windsor/vpu_encoder_b0.c
@@ -0,0 +1,5811 @@
+/*
+ * Copyright 2018 NXP
+ */
+
+/*
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/*!
+ * @file vpu_encoder_b0.c
+ *
+ * copyright here may be changed later
+ *
+ *
+ */
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/dma-mapping.h>
+#include <linux/module.h>
+#include <linux/videodev2.h>
+#include <linux/firmware.h>
+#include <linux/interrupt.h>
+#include <linux/file.h>
+#include <linux/of_platform.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/of_device.h>
+#include <linux/slab.h>
+#include <linux/platform_data/dma-imx.h>
+#include <linux/miscdevice.h>
+#include <linux/fs.h>
+#include <linux/pm_runtime.h>
+#include <linux/mx8_mu.h>
+#include <linux/uaccess.h>
+
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-event.h>
+#include <media/v4l2-ioctl.h>
+#include <media/v4l2-mem2mem.h>
+#include <media/videobuf2-v4l2.h>
+#include <media/videobuf2-dma-contig.h>
+#include <media/videobuf2-vmalloc.h>
+
+#include <soc/imx8/sc/ipc.h>
+#include "vpu_encoder_b0.h"
+#include "vpu_encoder_ctrl.h"
+#include "vpu_encoder_config.h"
+#include "vpu_event_msg.h"
+#include "vpu_encoder_mem.h"
+
+#define VPU_ENC_DRIVER_VERSION "1.0.1"
+
+struct vpu_frame_info {
+ struct list_head list;
+ MEDIAIP_ENC_PIC_INFO info;
+ u32 bytesleft;
+ u32 wptr;
+ u32 rptr;
+ u32 start;
+ u32 end;
+ bool eos;
+ bool is_start;
+ unsigned long index;
+ struct queue_data *queue;
+ s64 timestamp;
+};
+
+unsigned int vpu_dbg_level_encoder = LVL_ERR | LVL_WARN | LVL_ALL;
+static unsigned int reset_on_hang;
+static unsigned int show_detail_index = VPU_DETAIL_INDEX_DFT;
+static unsigned long debug_firmware_bitmap;
+
+#define ITEM_NAME(name) \
+ [name] = #name
+
+static char *cmd2str[] = {
+ ITEM_NAME(GTB_ENC_CMD_NOOP),
+ ITEM_NAME(GTB_ENC_CMD_STREAM_START),
+ ITEM_NAME(GTB_ENC_CMD_FRAME_ENCODE),
+ ITEM_NAME(GTB_ENC_CMD_FRAME_SKIP),
+ ITEM_NAME(GTB_ENC_CMD_STREAM_STOP),
+ ITEM_NAME(GTB_ENC_CMD_PARAMETER_UPD),
+ ITEM_NAME(GTB_ENC_CMD_TERMINATE),
+ ITEM_NAME(GTB_ENC_CMD_SNAPSHOT),
+ ITEM_NAME(GTB_ENC_CMD_ROLL_SNAPSHOT),
+ ITEM_NAME(GTB_ENC_CMD_LOCK_SCHEDULER),
+ ITEM_NAME(GTB_ENC_CMD_UNLOCK_SCHEDULER),
+ ITEM_NAME(GTB_ENC_CMD_CONFIGURE_CODEC),
+ ITEM_NAME(GTB_ENC_CMD_DEAD_MARK),
+ ITEM_NAME(GTB_ENC_CMD_FIRM_RESET),
+ ITEM_NAME(GTB_ENC_CMD_RESERVED)
+};
+
+static char *event2str[] = {
+ ITEM_NAME(VID_API_EVENT_UNDEFINED),
+ ITEM_NAME(VID_API_ENC_EVENT_RESET_DONE),
+ ITEM_NAME(VID_API_ENC_EVENT_START_DONE),
+ ITEM_NAME(VID_API_ENC_EVENT_STOP_DONE),
+ ITEM_NAME(VID_API_ENC_EVENT_TERMINATE_DONE),
+ ITEM_NAME(VID_API_ENC_EVENT_FRAME_INPUT_DONE),
+ ITEM_NAME(VID_API_ENC_EVENT_FRAME_DONE),
+ ITEM_NAME(VID_API_ENC_EVENT_FRAME_RELEASE),
+ ITEM_NAME(VID_API_ENC_EVENT_PARA_UPD_DONE),
+ ITEM_NAME(VID_API_ENC_EVENT_MEM_REQUEST),
+ ITEM_NAME(VID_API_ENC_EVENT_FIRMWARE_XCPT),
+ ITEM_NAME(VID_API_ENC_EVENT_RESERVED)
+};
+
+static int wait_for_start_done(struct core_device *core, int resume);
+static void wait_for_stop_done(struct vpu_ctx *ctx);
+static int sw_reset_firmware(struct core_device *core, int resume);
+static int enable_fps_sts(struct vpu_attr *attr);
+static int disable_fps_sts(struct vpu_attr *attr);
+static int configure_codec(struct vpu_ctx *ctx);
+static struct vpu_frame_info *get_idle_frame(struct queue_data *queue);
+static void put_frame_idle(struct vpu_frame_info *frame);
+static int inc_frame(struct queue_data *queue);
+static void dec_frame(struct vpu_frame_info *frame);
+static int submit_input_and_encode(struct vpu_ctx *ctx);
+static int process_stream_output(struct vpu_ctx *ctx);
+
+static char *get_event_str(u32 event)
+{
+ if (event >= VID_API_ENC_EVENT_RESERVED)
+ return "UNKNOWN EVENT";
+ return event2str[event];
+}
+
+static char *get_cmd_str(u32 cmdid)
+{
+ if (cmdid >= GTB_ENC_CMD_RESERVED)
+ return "UNKNOWN CMD";
+ return cmd2str[cmdid];
+}
+
+static void vpu_log_event(u_int32 uEvent, u_int32 ctxid)
+{
+ if (uEvent >= VID_API_ENC_EVENT_RESERVED)
+ vpu_err("reveive event: 0x%X, ctx id:%d\n",
+ uEvent, ctxid);
+ else
+ vpu_dbg(LVL_EVT, "recevie event: %s, ctx id:%d\n",
+ event2str[uEvent], ctxid);
+}
+
+static void vpu_log_cmd(u_int32 cmdid, u_int32 ctxid)
+{
+ if (cmdid >= GTB_ENC_CMD_RESERVED)
+ vpu_err("send cmd: 0x%X, ctx id:%d\n",
+ cmdid, ctxid);
+ else
+ vpu_dbg(LVL_CMD, "send cmd: %s ctx id:%d\n",
+ cmd2str[cmdid], ctxid);
+}
+
+static void count_event(struct vpu_ctx *ctx, u32 event)
+{
+ struct vpu_attr *attr;
+
+ WARN_ON(!ctx);
+
+ attr = get_vpu_ctx_attr(ctx);
+ if (!attr)
+ return;
+
+ if (event < VID_API_ENC_EVENT_RESERVED)
+ attr->statistic.event[event]++;
+ else
+ attr->statistic.event[VID_API_ENC_EVENT_RESERVED]++;
+
+ attr->statistic.current_event = event;
+ getrawmonotonic(&attr->statistic.ts_event);
+}
+
+static void count_cmd(struct vpu_attr *attr, u32 cmdid)
+{
+ WARN_ON(!attr);
+
+ if (cmdid < GTB_ENC_CMD_RESERVED)
+ attr->statistic.cmd[cmdid]++;
+ else
+ attr->statistic.cmd[GTB_ENC_CMD_RESERVED]++;
+ attr->statistic.current_cmd = cmdid;
+ getrawmonotonic(&attr->statistic.ts_cmd);
+}
+
+static void count_yuv_input(struct vpu_ctx *ctx)
+{
+ struct vpu_attr *attr = NULL;
+
+ WARN_ON(!ctx);
+
+ attr = get_vpu_ctx_attr(ctx);
+ if (!attr)
+ return;
+
+ attr->statistic.yuv_count++;
+}
+
+static void count_h264_output(struct vpu_ctx *ctx)
+{
+ struct vpu_attr *attr = NULL;
+
+ WARN_ON(!ctx);
+
+ attr = get_vpu_ctx_attr(ctx);
+ if (!attr)
+ return;
+
+ attr->statistic.h264_count++;
+}
+
+static void count_encoded_frame(struct vpu_ctx *ctx)
+{
+ struct vpu_attr *attr = NULL;
+
+ WARN_ON(!ctx);
+
+ attr = get_vpu_ctx_attr(ctx);
+ if (!attr)
+ return;
+
+ attr->statistic.encoded_count++;
+}
+
+static void count_timestamp_overwrite(struct vpu_ctx *ctx)
+{
+ struct vpu_attr *attr = NULL;
+
+ WARN_ON(!ctx);
+
+ attr = get_vpu_ctx_attr(ctx);
+ if (!attr)
+ return;
+
+ attr->statistic.timestamp_overwrite++;
+}
+
+static void write_vpu_reg(struct vpu_dev *dev, u32 val, off_t reg)
+{
+ writel(val, dev->regs_base + reg);
+}
+
+static u32 read_vpu_reg(struct vpu_dev *dev, off_t reg)
+{
+ return readl(dev->regs_base + reg);
+}
+
+/*
+ * v4l2 ioctl() operation
+ *
+ */
+static struct vpu_v4l2_fmt formats_compressed_enc[] = {
+ {
+ .name = "H264 Encoded Stream",
+ .fourcc = V4L2_PIX_FMT_H264,
+ .num_planes = 1,
+ .venc_std = VPU_VIDEO_AVC,
+ .is_yuv = 0,
+ },
+};
+
+static struct vpu_v4l2_fmt formats_yuv_enc[] = {
+ {
+ .name = "4:2:0 2 Planes Y/CbCr",
+ .fourcc = V4L2_PIX_FMT_NV12,
+ .num_planes = 2,
+ .venc_std = VPU_PF_YUV420_SEMIPLANAR,
+ .is_yuv = 1,
+ },
+};
+
+static void vpu_ctx_send_cmd(struct vpu_ctx *ctx, uint32_t cmdid,
+ uint32_t cmdnum, uint32_t *local_cmddata);
+
+static void MU_sendMesgToFW(void __iomem *base, MSG_Type type, uint32_t value)
+{
+ MU_SendMessage(base, 1, value);
+ MU_SendMessage(base, 0, type);
+}
+
+#define GET_CTX_RPC(ctx, func) \
+ func(&ctx->core_dev->shared_mem, ctx->str_index)
+
+pMEDIAIP_ENC_YUV_BUFFER_DESC get_rpc_yuv_buffer_desc(struct vpu_ctx *ctx)
+{
+ return GET_CTX_RPC(ctx, rpc_get_yuv_buffer_desc);
+}
+
+pBUFFER_DESCRIPTOR_TYPE get_rpc_stream_buffer_desc(struct vpu_ctx *ctx)
+{
+ return GET_CTX_RPC(ctx, rpc_get_stream_buffer_desc);
+}
+
+pMEDIAIP_ENC_EXPERT_MODE_PARAM get_rpc_expert_mode_param(struct vpu_ctx *ctx)
+{
+ return GET_CTX_RPC(ctx, rpc_get_expert_mode_param);
+}
+
+pMEDIAIP_ENC_PARAM get_rpc_enc_param(struct vpu_ctx *ctx)
+{
+ return GET_CTX_RPC(ctx, rpc_get_enc_param);
+}
+
+pMEDIAIP_ENC_MEM_POOL get_rpc_mem_pool(struct vpu_ctx *ctx)
+{
+ return GET_CTX_RPC(ctx, rpc_get_mem_pool);
+}
+
+pENC_ENCODING_STATUS get_rpc_encoding_status(struct vpu_ctx *ctx)
+{
+ if (!ctx || !ctx->core_dev)
+ return NULL;
+ return GET_CTX_RPC(ctx, rpc_get_encoding_status);
+}
+
+pENC_DSA_STATUS_t get_rpc_dsa_status(struct vpu_ctx *ctx)
+{
+ if (!ctx || !ctx->core_dev)
+ return NULL;
+ return GET_CTX_RPC(ctx, rpc_get_dsa_status);
+}
+
+static int vpu_enc_v4l2_ioctl_querycap(struct file *file,
+ void *fh,
+ struct v4l2_capability *cap)
+{
+ vpu_log_func();
+ strlcpy(cap->driver, "vpu encoder", sizeof(cap->driver));
+ strlcpy(cap->card, "vpu encoder", sizeof(cap->card));
+ strlcpy(cap->bus_info, "platform:", sizeof(cap->bus_info));
+ cap->version = KERNEL_VERSION(0, 0, 1);
+ cap->device_caps = V4L2_CAP_VIDEO_M2M_MPLANE |
+ V4L2_CAP_STREAMING |
+ V4L2_CAP_VIDEO_CAPTURE_MPLANE |
+ V4L2_CAP_VIDEO_OUTPUT_MPLANE;
+ cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
+ return 0;
+}
+
+static int vpu_enc_v4l2_ioctl_enum_fmt_vid_cap_mplane(struct file *file,
+ void *fh,
+ struct v4l2_fmtdesc *f)
+{
+ struct vpu_v4l2_fmt *fmt;
+
+ vpu_log_func();
+ if (f->index >= ARRAY_SIZE(formats_compressed_enc))
+ return -EINVAL;
+
+ fmt = &formats_compressed_enc[f->index];
+ strlcpy(f->description, fmt->name, sizeof(f->description));
+ f->pixelformat = fmt->fourcc;
+ f->flags |= V4L2_FMT_FLAG_COMPRESSED;
+ return 0;
+}
+static int vpu_enc_v4l2_ioctl_enum_fmt_vid_out_mplane(struct file *file,
+ void *fh,
+ struct v4l2_fmtdesc *f)
+{
+ struct vpu_v4l2_fmt *fmt;
+
+ vpu_log_func();
+ if (f->index >= ARRAY_SIZE(formats_yuv_enc))
+ return -EINVAL;
+
+ fmt = &formats_yuv_enc[f->index];
+ strlcpy(f->description, fmt->name, sizeof(f->description));
+ f->pixelformat = fmt->fourcc;
+ return 0;
+}
+
+static int vpu_enc_v4l2_ioctl_enum_framesizes(struct file *file, void *fh,
+ struct v4l2_frmsizeenum *fsize)
+{
+ struct vpu_ctx *ctx = v4l2_fh_to_ctx(fh);
+ struct vpu_dev *vdev = ctx->dev;
+
+ if (!fsize)
+ return -EINVAL;
+
+ if (fsize->index)
+ return -EINVAL;
+
+ if (!vdev)
+ return -EINVAL;
+
+ vpu_log_func();
+ fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE;
+ fsize->stepwise.max_width = vdev->supported_size.max_width;
+ fsize->stepwise.max_height = vdev->supported_size.max_height;
+ fsize->stepwise.min_width = vdev->supported_size.min_width;
+ fsize->stepwise.min_height = vdev->supported_size.min_height;
+ fsize->stepwise.step_width = vdev->supported_size.step_width;
+ fsize->stepwise.step_height = vdev->supported_size.step_height;
+
+ return 0;
+}
+
+static int vpu_enc_v4l2_ioctl_enum_frameintervals(struct file *file, void *fh,
+ struct v4l2_frmivalenum *fival)
+{
+ u32 framerate;
+ struct vpu_ctx *ctx = v4l2_fh_to_ctx(fh);
+ struct vpu_dev *vdev = ctx->dev;
+
+
+ if (!fival)
+ return -EINVAL;
+ if (!vdev)
+ return -EINVAL;
+
+ vpu_log_func();
+ framerate = vdev->supported_fps.min +
+ fival->index * vdev->supported_fps.step;
+ if (framerate > vdev->supported_fps.max)
+ return -EINVAL;
+
+ fival->type = V4L2_FRMIVAL_TYPE_DISCRETE;
+ fival->discrete.numerator = 1;
+ fival->discrete.denominator = framerate;
+
+ return 0;
+}
+
+static struct queue_data *get_queue_by_v4l2_type(struct vpu_ctx *ctx, u32 type)
+{
+ struct queue_data *queue = NULL;
+
+ if (!ctx)
+ return NULL;
+
+ switch (type) {
+ case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
+ queue = &ctx->q_data[V4L2_SRC];
+ break;
+ case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
+ queue = &ctx->q_data[V4L2_DST];
+ break;
+ default:
+ vpu_err("unsupport v4l2 buf type : %d\n", type);
+ break;
+ }
+
+ return queue;
+}
+
+static int vpu_enc_v4l2_ioctl_g_fmt(struct file *file,
+ void *fh,
+ struct v4l2_format *f)
+{
+ struct vpu_ctx *ctx = v4l2_fh_to_ctx(fh);
+ struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp;
+ struct queue_data *q_data;
+ unsigned int i;
+
+ q_data = get_queue_by_v4l2_type(ctx, f->type);
+ if (!q_data)
+ return -EINVAL;
+ vpu_dbg(LVL_FUNC, "%s(), %s\n", __func__, q_data->desc);
+
+ if (!q_data->current_fmt) {
+ vpu_err("%s's current fmt is NULL\n", q_data->desc);
+ return -EINVAL;
+ }
+
+ pix_mp->pixelformat = q_data->current_fmt->fourcc;
+ pix_mp->num_planes = q_data->current_fmt->num_planes;
+ pix_mp->width = q_data->width;
+ pix_mp->height = q_data->height;
+ pix_mp->field = V4L2_FIELD_ANY;
+ for (i = 0; i < pix_mp->num_planes; i++)
+ pix_mp->plane_fmt[i].sizeimage = q_data->sizeimage[i];
+
+ if (V4L2_TYPE_IS_OUTPUT(f->type))
+ pix_mp->colorspace = V4L2_COLORSPACE_REC709;
+ else
+ pix_mp->plane_fmt[0].bytesperline = q_data->width;
+
+ return 0;
+}
+
+u32 cpu_phy_to_mu(struct core_device *dev, u32 addr)
+{
+ return addr - dev->m0_p_fw_space_phy;
+}
+
+static int initialize_enc_param(struct vpu_ctx *ctx)
+{
+ struct vpu_attr *attr = get_vpu_ctx_attr(ctx);
+ pMEDIAIP_ENC_PARAM param = &attr->param;
+
+ mutex_lock(&ctx->instance_mutex);
+
+ param->eCodecMode = MEDIAIP_ENC_FMT_H264;
+ param->tEncMemDesc.uMemPhysAddr = 0;
+ param->tEncMemDesc.uMemVirtAddr = 0;
+ param->tEncMemDesc.uMemSize = 0;
+ param->uSrcStride = VPU_ENC_WIDTH_DEFAULT;
+ param->uSrcWidth = VPU_ENC_WIDTH_DEFAULT;
+ param->uSrcHeight = VPU_ENC_HEIGHT_DEFAULT;
+ param->uSrcOffset_x = 0;
+ param->uSrcOffset_y = 0;
+ param->uSrcCropWidth = VPU_ENC_WIDTH_DEFAULT;
+ param->uSrcCropHeight = VPU_ENC_HEIGHT_DEFAULT;
+ param->uOutWidth = VPU_ENC_WIDTH_DEFAULT;
+ param->uOutHeight = VPU_ENC_HEIGHT_DEFAULT;
+ param->uFrameRate = VPU_ENC_FRAMERATE_DEFAULT;
+ param->uMinBitRate = BITRATE_LOW_THRESHOLD;
+
+ mutex_unlock(&ctx->instance_mutex);
+
+ return 0;
+}
+
+static int check_stepwise(u32 val, u32 min, u32 max, u32 step)
+{
+ if (val < min)
+ return -EINVAL;
+ if (val > max)
+ return -EINVAL;
+ if ((val - min) % step)
+ return -EINVAL;
+
+ return 0;
+}
+
+static int check_size(struct vpu_dev *vdev, u32 width, u32 height)
+{
+ int ret;
+
+ if (!vdev)
+ return -EINVAL;
+
+ ret = check_stepwise(width,
+ vdev->supported_size.min_width,
+ vdev->supported_size.max_width,
+ vdev->supported_size.step_width);
+ if (ret) {
+ vpu_err("Unsupported frame size : %dx%d\n", width, height);
+ return -EINVAL;
+ }
+ ret = check_stepwise(height,
+ vdev->supported_size.min_height,
+ vdev->supported_size.max_height,
+ vdev->supported_size.step_height);
+ if (ret) {
+ vpu_err("Unsupported frame size : %dx%d\n", width, height);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int valid_crop_info(struct queue_data *queue, struct v4l2_rect *rect)
+{
+ struct vpu_ctx *ctx;
+ u32 MIN_WIDTH;
+ u32 MIN_HEIGHT;
+
+ if (!queue || !rect || !queue->ctx)
+ return -EINVAL;
+
+ ctx = queue->ctx;
+ MIN_WIDTH = ctx->dev->supported_size.min_width;
+ MIN_HEIGHT = ctx->dev->supported_size.min_height;
+
+ if (rect->left > queue->width - MIN_WIDTH ||
+ rect->top > queue->height - MIN_HEIGHT) {
+ rect->left = 0;
+ rect->top = 0;
+ rect->width = queue->width;
+ rect->height = queue->height;
+ return 0;
+ }
+
+ rect->width = min(rect->width, queue->width - rect->left);
+ if (rect->width)
+ rect->width = max_t(u32, rect->width, MIN_WIDTH);
+ else
+ rect->width = queue->width;
+ rect->height = min(rect->height, queue->height - rect->top);
+ if (rect->height)
+ rect->height = max_t(u32, rect->height, MIN_HEIGHT);
+ else
+ rect->height = queue->height;
+
+ return 0;
+}
+
+static int check_v4l2_fmt(struct vpu_dev *dev, struct v4l2_format *f)
+{
+ int ret = -EINVAL;
+
+ switch (f->type) {
+ case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+ case V4L2_BUF_TYPE_VIDEO_OUTPUT:
+ ret = check_size(dev, f->fmt.pix.width, f->fmt.pix.height);
+ break;
+ case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
+ case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
+ ret = check_size(dev, f->fmt.pix_mp.width,
+ f->fmt.pix_mp.height);
+ break;
+ default:
+ break;
+ }
+
+ return ret;
+}
+
+static struct vpu_v4l2_fmt *find_fmt_by_fourcc(struct vpu_v4l2_fmt *fmts,
+ unsigned int size,
+ u32 fourcc)
+{
+ unsigned int i;
+
+ if (!fmts || !size)
+ return NULL;
+
+ for (i = 0; i < size; i++) {
+ if (fmts[i].fourcc == fourcc)
+ return &fmts[i];
+ }
+
+ return NULL;
+}
+
+static char *cvrt_fourcc_to_str(u32 pixelformat)
+{
+ static char str[5];
+
+ str[0] = pixelformat & 0xff;
+ str[1] = (pixelformat >> 8) & 0xff;
+ str[2] = (pixelformat >> 16) & 0xff;
+ str[3] = (pixelformat >> 24) & 0xff;
+ str[4] = '\0';
+
+ return str;
+}
+
+static int set_yuv_queue_fmt(struct queue_data *q_data, struct v4l2_format *f)
+{
+ struct vpu_v4l2_fmt *fmt = NULL;
+ struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp;
+ int i;
+
+ if (!q_data || !f)
+ return -EINVAL;
+
+ fmt = find_fmt_by_fourcc(q_data->supported_fmts, q_data->fmt_count,
+ pix_mp->pixelformat);
+ if (!fmt) {
+ vpu_err("unsupport yuv fmt : %s\n",
+ cvrt_fourcc_to_str(pix_mp->pixelformat));
+ return -EINVAL;
+ }
+
+ q_data->width = pix_mp->width;
+ q_data->height = pix_mp->height;
+ q_data->rect.left = 0;
+ q_data->rect.top = 0;
+ q_data->rect.width = pix_mp->width;
+ q_data->rect.height = pix_mp->height;
+ q_data->sizeimage[0] = pix_mp->width * pix_mp->height;
+ q_data->sizeimage[1] = pix_mp->width * pix_mp->height / 2;
+ pix_mp->num_planes = fmt->num_planes;
+ for (i = 0; i < pix_mp->num_planes; i++)
+ pix_mp->plane_fmt[i].sizeimage = q_data->sizeimage[i];
+
+ q_data->current_fmt = fmt;
+
+ return 0;
+}
+
+static u32 get_enc_minimum_sizeimage(u32 width, u32 height)
+{
+ const u32 THRESHOLD = 256 * 1024;
+ u32 sizeimage;
+
+ sizeimage = width * height / 2;
+ if (sizeimage < THRESHOLD)
+ sizeimage = THRESHOLD;
+
+ return sizeimage;
+}
+
+static int set_enc_queue_fmt(struct queue_data *q_data, struct v4l2_format *f)
+{
+ struct vpu_v4l2_fmt *fmt = NULL;
+ struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp;
+ u32 sizeimage;
+
+ if (!q_data || !f)
+ return -EINVAL;
+
+ fmt = find_fmt_by_fourcc(q_data->supported_fmts, q_data->fmt_count,
+ pix_mp->pixelformat);
+ if (!fmt) {
+ vpu_err("unsupport encode fmt : %s\n",
+ cvrt_fourcc_to_str(pix_mp->pixelformat));
+ return -EINVAL;
+ }
+
+ q_data->width = pix_mp->width;
+ q_data->height = pix_mp->height;
+ sizeimage = get_enc_minimum_sizeimage(pix_mp->width, pix_mp->height);
+ q_data->sizeimage[0] = max(sizeimage, pix_mp->plane_fmt[0].sizeimage);
+ pix_mp->plane_fmt[0].sizeimage = q_data->sizeimage[0];
+
+ q_data->current_fmt = fmt;
+
+ return 0;
+}
+
+static int vpu_enc_v4l2_ioctl_s_fmt(struct file *file,
+ void *fh,
+ struct v4l2_format *f)
+{
+ struct vpu_ctx *ctx = v4l2_fh_to_ctx(fh);
+ int ret = 0;
+ struct queue_data *q_data;
+ pMEDIAIP_ENC_PARAM pEncParam;
+ struct vpu_attr *attr;
+
+ attr = get_vpu_ctx_attr(ctx);
+ pEncParam = &attr->param;
+ q_data = get_queue_by_v4l2_type(ctx, f->type);
+ if (!q_data)
+ return -EINVAL;
+ vpu_dbg(LVL_FUNC, "%s(), %s, (%d, %d)\n", __func__, q_data->desc,
+ ctx->core_dev->id, ctx->str_index);
+
+ ret = check_v4l2_fmt(ctx->dev, f);
+ if (ret)
+ return ret;
+
+ mutex_lock(&ctx->instance_mutex);
+ if (V4L2_TYPE_IS_OUTPUT(f->type))
+ ret = set_yuv_queue_fmt(q_data, f);
+ else
+ ret = set_enc_queue_fmt(q_data, f);
+ mutex_unlock(&ctx->instance_mutex);
+
+ return ret;
+}
+
+static int vpu_enc_v4l2_ioctl_g_parm(struct file *file, void *fh,
+ struct v4l2_streamparm *parm)
+{
+ struct vpu_ctx *ctx = v4l2_fh_to_ctx(fh);
+ struct vpu_attr *attr = NULL;
+ pMEDIAIP_ENC_PARAM param = NULL;
+
+ if (!parm || !ctx)
+ return -EINVAL;
+
+ attr = get_vpu_ctx_attr(ctx);
+ param = &attr->param;
+
+ vpu_log_func();
+ parm->parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
+ parm->parm.capture.capturemode = V4L2_CAP_TIMEPERFRAME;
+ parm->parm.capture.timeperframe.numerator = 1;
+ parm->parm.capture.timeperframe.denominator = param->uFrameRate;
+ parm->parm.capture.readbuffers = 0;
+
+ return 0;
+}
+
+static int find_proper_framerate(struct vpu_dev *dev, struct v4l2_fract *fival)
+{
+ u32 min_delta = INT_MAX;
+ struct v4l2_fract target_fival = {0, 0};
+ u32 framerate;
+
+ if (!fival || !dev)
+ return -EINVAL;
+
+ framerate = dev->supported_fps.min;
+
+ while (framerate <= dev->supported_fps.max) {
+ u32 delta;
+
+ delta = abs(fival->numerator * framerate -
+ fival->denominator);
+ if (!delta)
+ return 0;
+ if (delta < min_delta) {
+ target_fival.numerator = 1;
+ target_fival.denominator = framerate;
+ min_delta = delta;
+ }
+
+ framerate += dev->supported_fps.step;
+ }
+ if (!target_fival.numerator || !target_fival.denominator)
+ return -EINVAL;
+
+ fival->numerator = target_fival.numerator;
+ fival->denominator = target_fival.denominator;
+
+ return 0;
+}
+
+static int vpu_enc_v4l2_ioctl_s_parm(struct file *file, void *fh,
+ struct v4l2_streamparm *parm)
+{
+ struct vpu_ctx *ctx = v4l2_fh_to_ctx(fh);
+ struct vpu_attr *attr = NULL;
+ struct v4l2_fract fival;
+ int ret;
+
+ if (!parm || !ctx)
+ return -EINVAL;
+
+ vpu_log_func();
+ attr = get_vpu_ctx_attr(ctx);
+
+ fival.numerator = parm->parm.capture.timeperframe.numerator;
+ fival.denominator = parm->parm.capture.timeperframe.denominator;
+ if (!fival.numerator || !fival.denominator)
+ return -EINVAL;
+
+ ret = find_proper_framerate(ctx->dev, &fival);
+ if (ret) {
+ vpu_err("Unsupported FPS : %d / %d\n",
+ fival.numerator, fival.denominator);
+ return ret;
+ }
+
+ mutex_lock(&ctx->instance_mutex);
+ attr->param.uFrameRate = fival.denominator / fival.numerator;
+ mutex_unlock(&ctx->instance_mutex);
+
+ parm->parm.capture.timeperframe.numerator = fival.numerator;
+ parm->parm.capture.timeperframe.denominator = fival.denominator;
+
+ return 0;
+}
+
+static int vpu_enc_queue_expbuf(struct queue_data *queue,
+ struct v4l2_exportbuffer *buf)
+{
+ int ret = -EINVAL;
+
+ down(&queue->drv_q_lock);
+ if (queue->vb2_q_inited)
+ ret = vb2_expbuf(&queue->vb2_q, buf);
+ up(&queue->drv_q_lock);
+
+ return ret;
+}
+
+static int vpu_enc_queue_reqbufs(struct queue_data *queue,
+ struct v4l2_requestbuffers *reqbuf)
+{
+ int ret = -EINVAL;
+
+ down(&queue->drv_q_lock);
+ if (queue->vb2_q_inited)
+ ret = vb2_reqbufs(&queue->vb2_q, reqbuf);
+ up(&queue->drv_q_lock);
+
+ return ret;
+}
+
+static int vpu_enc_queue_querybuf(struct queue_data *queue,
+ struct v4l2_buffer *buf)
+{
+ int ret = -EINVAL;
+
+ down(&queue->drv_q_lock);
+ if (queue->vb2_q_inited)
+ ret = vb2_querybuf(&queue->vb2_q, buf);
+ up(&queue->drv_q_lock);
+
+ return ret;
+}
+
+static int vpu_enc_queue_qbuf(struct queue_data *queue,
+ struct v4l2_buffer *buf)
+{
+ int ret = -EINVAL;
+
+ down(&queue->drv_q_lock);
+ if (queue->vb2_q_inited)
+ ret = vb2_qbuf(&queue->vb2_q, buf);
+ up(&queue->drv_q_lock);
+
+ return ret;
+}
+
+static int vpu_enc_queue_dqbuf(struct queue_data *queue,
+ struct v4l2_buffer *buf, bool nonblocking)
+{
+ int ret = -EINVAL;
+
+ down(&queue->drv_q_lock);
+ if (queue->vb2_q_inited)
+ ret = vb2_dqbuf(&queue->vb2_q, buf, nonblocking);
+ up(&queue->drv_q_lock);
+
+ return ret;
+}
+
+static int vpu_enc_queue_enable(struct queue_data *queue,
+ enum v4l2_buf_type type)
+{
+ int ret = -EINVAL;
+
+ down(&queue->drv_q_lock);
+ if (queue->vb2_q_inited)
+ ret = vb2_streamon(&queue->vb2_q, type);
+ up(&queue->drv_q_lock);
+
+ return ret;
+}
+
+static void clear_queue(struct queue_data *queue)
+{
+ struct vpu_frame_info *frame;
+ struct vpu_frame_info *tmp;
+ struct vb2_data_req *p_data_req;
+ struct vb2_data_req *p_temp;
+ struct vb2_buffer *vb;
+
+ if (!queue)
+ return;
+
+ list_for_each_entry_safe(frame, tmp, &queue->frame_q, list) {
+ vpu_dbg(LVL_INFO, "drop frame\n");
+ put_frame_idle(frame);
+ }
+
+ list_for_each_entry_safe(frame, tmp, &queue->frame_idle, list)
+ dec_frame(frame);
+
+ list_for_each_entry_safe(p_data_req, p_temp, &queue->drv_q, list) {
+ vpu_dbg(LVL_DEBUG, "%s(%d) - list_del(%p)\n", __func__,
+ p_data_req->sequence, p_data_req);
+ list_del(&p_data_req->list);
+ }
+ list_for_each_entry(vb, &queue->vb2_q.queued_list, queued_entry) {
+ if (vb->state == VB2_BUF_STATE_ACTIVE)
+ vb2_buffer_done(vb, VB2_BUF_STATE_ERROR);
+ }
+
+ INIT_LIST_HEAD(&queue->drv_q);
+ INIT_LIST_HEAD(&queue->frame_q);
+ INIT_LIST_HEAD(&queue->frame_idle);
+}
+
+static int vpu_enc_queue_disable(struct queue_data *queue,
+ enum v4l2_buf_type type)
+{
+ int ret = -EINVAL;
+
+ down(&queue->drv_q_lock);
+ if (queue->vb2_q_inited)
+ ret = vb2_streamoff(&queue->vb2_q, type);
+ up(&queue->drv_q_lock);
+
+ return ret;
+}
+
+static int vpu_enc_queue_release(struct queue_data *queue)
+{
+ int ret = -EINVAL;
+
+ down(&queue->drv_q_lock);
+ if (queue->vb2_q_inited) {
+ clear_queue(queue);
+ vb2_queue_release(&queue->vb2_q);
+ }
+ up(&queue->drv_q_lock);
+
+ return ret;
+}
+
+static int vpu_enc_queue_mmap(struct queue_data *queue,
+ struct vm_area_struct *vma)
+{
+ int ret = -EINVAL;
+
+ down(&queue->drv_q_lock);
+ if (queue->vb2_q_inited)
+ ret = vb2_mmap(&queue->vb2_q, vma);
+ up(&queue->drv_q_lock);
+
+ return ret;
+}
+
+static int vpu_enc_v4l2_ioctl_expbuf(struct file *file,
+ void *fh,
+ struct v4l2_exportbuffer *buf)
+{
+ struct vpu_ctx *ctx = v4l2_fh_to_ctx(fh);
+ struct queue_data *q_data;
+
+ q_data = get_queue_by_v4l2_type(ctx, buf->type);
+ if (!q_data)
+ return -EINVAL;
+ vpu_dbg(LVL_FUNC, "%s(), %s\n", __func__, q_data->desc);
+
+ return vpu_enc_queue_expbuf(q_data, buf);
+}
+
+static int vpu_enc_v4l2_ioctl_subscribe_event(struct v4l2_fh *fh,
+ const struct v4l2_event_subscription *sub
+ )
+{
+ vpu_log_func();
+
+ switch (sub->type) {
+ case V4L2_EVENT_EOS:
+ return v4l2_event_subscribe(fh, sub, 0, NULL);
+ case V4L2_EVENT_SOURCE_CHANGE:
+ return v4l2_src_change_event_subscribe(fh, sub);
+ default:
+ return -EINVAL;
+ }
+}
+
+static int vpu_enc_v4l2_ioctl_reqbufs(struct file *file,
+ void *fh,
+ struct v4l2_requestbuffers *reqbuf)
+{
+ struct vpu_ctx *ctx = v4l2_fh_to_ctx(fh);
+ struct queue_data *q_data;
+ int ret;
+
+ q_data = get_queue_by_v4l2_type(ctx, reqbuf->type);
+ if (!q_data)
+ return -EINVAL;
+ vpu_dbg(LVL_FUNC, "%s(), %s, (%d, %d)\n", __func__, q_data->desc,
+ ctx->core_dev->id, ctx->str_index);
+
+ ret = vpu_enc_queue_reqbufs(q_data, reqbuf);
+
+ return ret;
+}
+
+static int vpu_enc_v4l2_ioctl_querybuf(struct file *file,
+ void *fh,
+ struct v4l2_buffer *buf)
+{
+ struct vpu_ctx *ctx = v4l2_fh_to_ctx(fh);
+ struct queue_data *q_data;
+ unsigned int i;
+ int ret;
+
+ q_data = get_queue_by_v4l2_type(ctx, buf->type);
+ if (!q_data)
+ return -EINVAL;
+ vpu_dbg(LVL_FUNC, "%s(), %s, (%d, %d)\n", __func__, q_data->desc,
+ ctx->core_dev->id, ctx->str_index);
+
+ ret = vpu_enc_queue_querybuf(q_data, buf);
+ if (ret)
+ return ret;
+
+ if (buf->memory == V4L2_MEMORY_MMAP) {
+ if (V4L2_TYPE_IS_MULTIPLANAR(buf->type)) {
+ for (i = 0; i < buf->length; i++)
+ buf->m.planes[i].m.mem_offset |= (q_data->type << MMAP_BUF_TYPE_SHIFT);
+ } else
+ buf->m.offset |= (q_data->type << MMAP_BUF_TYPE_SHIFT);
+ }
+
+ return ret;
+}
+
+static struct vb2_buffer *cvrt_v4l2_to_vb2_buffer(struct vb2_queue *vq,
+ struct v4l2_buffer *buf)
+{
+ if (!vq || !buf)
+ return NULL;
+
+ if (buf->index >= vq->num_buffers)
+ return NULL;
+
+ return vq->bufs[buf->index];
+}
+
+static u32 get_v4l2_plane_payload(struct v4l2_plane *plane)
+{
+ return plane->bytesused - plane->data_offset;
+}
+
+static void set_v4l2_plane_payload(struct v4l2_plane *plane, u32 size)
+{
+ plane->bytesused = plane->data_offset + size;
+}
+
+static int is_valid_output_mplane_buf(struct queue_data *q_data,
+ struct vpu_v4l2_fmt *fmt,
+ struct v4l2_buffer *buf)
+{
+ int i;
+
+ for (i = 0; i < fmt->num_planes; i++) {
+ u32 bytesused = get_v4l2_plane_payload(&buf->m.planes[i]);
+
+ if (!bytesused) {
+ set_v4l2_plane_payload(&buf->m.planes[i],
+ q_data->sizeimage[i]);
+ continue;
+ }
+ if (fmt->is_yuv && bytesused != q_data->sizeimage[i])
+ return 0;
+ }
+
+ return 1;
+}
+
+static int is_valid_output_buf(struct queue_data *q_data,
+ struct vpu_v4l2_fmt *fmt,
+ struct v4l2_buffer *buf)
+{
+ if (!buf->bytesused) {
+ buf->bytesused = q_data->sizeimage[0];
+ return 1;
+ }
+ if (fmt->is_yuv && buf->bytesused != q_data->sizeimage[0])
+ return 0;
+
+ return 1;
+}
+
+static int precheck_qbuf(struct queue_data *q_data, struct v4l2_buffer *buf)
+{
+ struct vb2_buffer *vb = NULL;
+ struct vpu_v4l2_fmt *fmt;
+ int ret;
+
+ if (!q_data || !buf)
+ return -EINVAL;
+
+ if (!q_data->current_fmt)
+ return -EINVAL;
+
+ vb = cvrt_v4l2_to_vb2_buffer(&q_data->vb2_q, buf);
+ if (!vb) {
+ vpu_err("invalid v4l2 buffer index:%d\n", buf->index);
+ return -EINVAL;
+ }
+ if (vb->state != VB2_BUF_STATE_DEQUEUED) {
+ vpu_err("invalid buffer state:%d\n", vb->state);
+ return -EINVAL;
+ }
+
+ if (!V4L2_TYPE_IS_OUTPUT(buf->type))
+ return 0;
+
+ fmt = q_data->current_fmt;
+ if (V4L2_TYPE_IS_MULTIPLANAR(buf->type))
+ ret = is_valid_output_mplane_buf(q_data, fmt, buf);
+ else
+ ret = is_valid_output_buf(q_data, fmt, buf);
+ if (!ret)
+ return -EINVAL;
+
+ return 0;
+}
+
+static int vpu_enc_v4l2_ioctl_qbuf(struct file *file,
+ void *fh,
+ struct v4l2_buffer *buf)
+{
+ struct vpu_ctx *ctx = v4l2_fh_to_ctx(fh);
+ struct queue_data *q_data;
+ int ret;
+
+ q_data = get_queue_by_v4l2_type(ctx, buf->type);
+ if (!q_data)
+ return -EINVAL;
+ vpu_dbg(LVL_FUNC, "%s(), %s, (%d, %d)\n", __func__, q_data->desc,
+ ctx->core_dev->id, ctx->str_index);
+
+ ret = precheck_qbuf(q_data, buf);
+ if (ret < 0)
+ return ret;
+
+ ret = vpu_enc_queue_qbuf(q_data, buf);
+ if (ret)
+ return ret;
+
+ if (V4L2_TYPE_IS_OUTPUT(buf->type)) {
+ mutex_lock(&ctx->dev->dev_mutex);
+ mutex_lock(&ctx->instance_mutex);
+ if (!test_bit(VPU_ENC_STATUS_CONFIGURED, &ctx->status))
+ set_bit(VPU_ENC_STATUS_DATA_READY, &ctx->status);
+ configure_codec(ctx);
+ mutex_unlock(&ctx->instance_mutex);
+ mutex_unlock(&ctx->dev->dev_mutex);
+
+ submit_input_and_encode(ctx);
+ count_yuv_input(ctx);
+ } else {
+ process_stream_output(ctx);
+ }
+
+ return ret;
+}
+
+static void notify_eos(struct vpu_ctx *ctx)
+{
+ const struct v4l2_event ev = {
+ .type = V4L2_EVENT_EOS
+ };
+
+ mutex_lock(&ctx->instance_mutex);
+ if (!test_bit(VPU_ENC_STATUS_CLOSED, &ctx->status) &&
+ !test_and_set_bit(VPU_ENC_STATUS_EOS_SEND, &ctx->status))
+ v4l2_event_queue_fh(&ctx->fh, &ev);
+ mutex_unlock(&ctx->instance_mutex);
+}
+
+static int send_eos(struct vpu_ctx *ctx)
+{
+ if (!ctx)
+ return -EINVAL;
+
+ if (!test_bit(VPU_ENC_STATUS_START_SEND, &ctx->status)) {
+ notify_eos(ctx);
+ return 0;
+ }
+
+ if (!test_and_set_bit(VPU_ENC_STATUS_STOP_SEND, &ctx->status)) {
+ vpu_dbg(LVL_INFO, "stop stream\n");
+ vpu_ctx_send_cmd(ctx, GTB_ENC_CMD_STREAM_STOP, 0, NULL);
+ }
+
+ return 0;
+}
+
+static int vpu_enc_v4l2_ioctl_dqbuf(struct file *file,
+ void *fh,
+ struct v4l2_buffer *buf)
+{
+ struct vpu_ctx *ctx = v4l2_fh_to_ctx(fh);
+ struct queue_data *q_data;
+ int ret;
+
+ q_data = get_queue_by_v4l2_type(ctx, buf->type);
+ if (!q_data)
+ return -EINVAL;
+ vpu_dbg(LVL_FUNC, "%s(), %s, (%d, %d)\n", __func__, q_data->desc,
+ ctx->core_dev->id, ctx->str_index);
+
+ ret = vpu_enc_queue_dqbuf(q_data, buf, file->f_flags & O_NONBLOCK);
+
+ if (buf->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
+ if (!ret)
+ count_h264_output(ctx);
+ buf->flags = q_data->vb2_reqs[buf->index].buffer_flags;
+ }
+
+ return ret;
+}
+
+static bool format_is_support(struct vpu_v4l2_fmt *format_table,
+ unsigned int table_size,
+ struct v4l2_format *f)
+{
+ unsigned int i;
+
+ for (i = 0; i < table_size; i++) {
+ if (format_table[i].fourcc == f->fmt.pix_mp.pixelformat)
+ return true;
+ }
+ return false;
+}
+
+static int vpu_enc_v4l2_ioctl_try_fmt(struct file *file,
+ void *fh,
+ struct v4l2_format *f)
+{
+ struct vpu_ctx *ctx = v4l2_fh_to_ctx(fh);
+ struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp;
+ struct queue_data *q_data;
+
+ q_data = get_queue_by_v4l2_type(ctx, f->type);
+ if (!q_data)
+ return -EINVAL;
+ vpu_dbg(LVL_FUNC, "%s(), %s\n", __func__, q_data->desc);
+
+ if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
+ pix_mp->field = V4L2_FIELD_ANY;
+ pix_mp->colorspace = V4L2_COLORSPACE_REC709;
+ }
+ if (!format_is_support(q_data->supported_fmts, q_data->fmt_count, f))
+ return -EINVAL;
+
+ return 0;
+}
+
+static int vpu_enc_v4l2_ioctl_g_crop(struct file *file, void *fh,
+ struct v4l2_crop *cr)
+{
+ struct vpu_ctx *ctx = v4l2_fh_to_ctx(fh);
+ struct queue_data *src = &ctx->q_data[V4L2_SRC];
+
+ if (!cr)
+ return -EINVAL;
+
+ if (get_queue_by_v4l2_type(ctx, cr->type) != src)
+ return -EINVAL;
+
+ vpu_log_func();
+ cr->c.left = src->rect.left;
+ cr->c.top = src->rect.top;
+ cr->c.width = src->rect.width;
+ cr->c.height = src->rect.height;
+
+ return 0;
+}
+
+static int vpu_enc_v4l2_ioctl_s_crop(struct file *file, void *fh,
+ const struct v4l2_crop *cr)
+{
+ struct vpu_ctx *ctx = v4l2_fh_to_ctx(fh);
+ struct queue_data *src = &ctx->q_data[V4L2_SRC];
+ struct vpu_dev *dev = ctx->dev;
+
+ if (!cr)
+ return -EINVAL;
+ if (!dev)
+ return -EINVAL;
+
+ if (get_queue_by_v4l2_type(ctx, cr->type) != src)
+ return -EINVAL;
+
+ vpu_log_func();
+ src->rect.left = ALIGN(cr->c.left, dev->supported_size.step_width);
+ src->rect.top = ALIGN(cr->c.top, dev->supported_size.step_height);
+ src->rect.width = ALIGN(cr->c.width, dev->supported_size.step_width);
+ src->rect.height = ALIGN(cr->c.height, dev->supported_size.step_height);
+ valid_crop_info(src, &src->rect);
+
+ return 0;
+}
+
+static int response_stop_stream(struct vpu_ctx *ctx)
+{
+ struct queue_data *queue;
+
+ if (!ctx)
+ return -EINVAL;
+
+ queue = &ctx->q_data[V4L2_SRC];
+
+ down(&queue->drv_q_lock);
+ if (!list_empty(&queue->drv_q))
+ goto exit;
+
+ if (!test_bit(VPU_ENC_FLAG_WRITEABLE, &queue->rw_flag))
+ goto exit;
+ if (test_and_clear_bit(VPU_ENC_STATUS_STOP_REQ, &ctx->status))
+ send_eos(ctx);
+exit:
+ up(&queue->drv_q_lock);
+
+ return 0;
+}
+
+static int request_eos(struct vpu_ctx *ctx)
+{
+ WARN_ON(!ctx);
+
+ set_bit(VPU_ENC_STATUS_STOP_REQ, &ctx->status);
+ response_stop_stream(ctx);
+
+ return 0;
+}
+
+static int set_core_force_release(struct core_device *core)
+{
+ int i;
+
+ if (!core)
+ return -EINVAL;
+
+ for (i = 0; i < core->supported_instance_count; i++) {
+ if (!core->ctx[i])
+ continue;
+ set_bit(VPU_ENC_STATUS_FORCE_RELEASE, &core->ctx[i]->status);
+ }
+
+ return 0;
+}
+
+static void clear_start_status(struct vpu_ctx *ctx)
+{
+ if (!ctx)
+ return;
+
+ clear_bit(VPU_ENC_STATUS_CONFIGURED, &ctx->status);
+ clear_bit(VPU_ENC_STATUS_START_SEND, &ctx->status);
+ clear_bit(VPU_ENC_STATUS_START_DONE, &ctx->status);
+}
+
+static void clear_stop_status(struct vpu_ctx *ctx)
+{
+ if (!ctx)
+ return;
+
+ clear_bit(VPU_ENC_STATUS_STOP_REQ, &ctx->status);
+ clear_bit(VPU_ENC_STATUS_STOP_SEND, &ctx->status);
+ clear_bit(VPU_ENC_STATUS_STOP_DONE, &ctx->status);
+ clear_bit(VPU_ENC_STATUS_EOS_SEND, &ctx->status);
+}
+
+static void reset_core_on_hang(struct core_device *core)
+{
+ int ret;
+ int i;
+
+ for (i = 0; i < core->supported_instance_count; i++)
+ clear_start_status(core->ctx[i]);
+
+ ret = sw_reset_firmware(core, 1);
+ if (ret)
+ vpu_err("reset core[%d] on hang fail\n", core->id);
+}
+
+static int set_core_hang(struct core_device *core)
+{
+ core->hang = true;
+
+ if (reset_on_hang)
+ reset_core_on_hang(core);
+
+ return 0;
+}
+
+static void clear_core_hang(struct core_device *core)
+{
+ if (!core)
+ return;
+
+ core->hang = false;
+}
+
+static void wait_for_stop_done(struct vpu_ctx *ctx)
+{
+ int ret;
+
+ WARN_ON(!ctx);
+
+ if (!test_bit(VPU_ENC_STATUS_START_SEND, &ctx->status))
+ return;
+ if (test_bit(VPU_ENC_STATUS_STOP_DONE, &ctx->status))
+ return;
+
+ ret = wait_for_completion_timeout(&ctx->stop_cmp,
+ msecs_to_jiffies(500));
+ if (!ret)
+ vpu_err("wait for stop done timeout\n");
+}
+
+static int vpu_enc_v4l2_ioctl_encoder_cmd(struct file *file,
+ void *fh,
+ struct v4l2_encoder_cmd *cmd
+ )
+{
+ struct vpu_ctx *ctx = v4l2_fh_to_ctx(fh);
+
+ vpu_dbg(LVL_FUNC, "%s(), cmd = %d, (%d, %d)\n", __func__, cmd->cmd,
+ ctx->core_dev->id, ctx->str_index);
+ switch (cmd->cmd) {
+ case V4L2_ENC_CMD_START:
+ break;
+ case V4L2_ENC_CMD_STOP:
+ request_eos(ctx);
+ break;
+ case V4L2_ENC_CMD_PAUSE:
+ break;
+ case V4L2_ENC_CMD_RESUME:
+ break;
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static int vpu_enc_v4l2_ioctl_streamon(struct file *file,
+ void *fh,
+ enum v4l2_buf_type i
+ )
+{
+ struct vpu_ctx *ctx = v4l2_fh_to_ctx(fh);
+ struct vpu_attr *attr;
+ struct queue_data *q_data;
+ int ret;
+
+ q_data = get_queue_by_v4l2_type(ctx, i);
+ if (!q_data)
+ return -EINVAL;
+ vpu_dbg(LVL_FUNC, "%s(), %s, (%d, %d)\n", __func__, q_data->desc,
+ ctx->core_dev->id, ctx->str_index);
+
+ attr = get_vpu_ctx_attr(ctx);
+ if (attr) {
+ attr->ts_start[V4L2_SRC] = 0;
+ attr->ts_start[V4L2_DST] = 0;
+ }
+
+ ret = vpu_enc_queue_enable(q_data, i);
+ if (ret)
+ return ret;
+
+ if (V4L2_TYPE_IS_OUTPUT(i)) {
+ mutex_lock(&ctx->dev->dev_mutex);
+ mutex_lock(&ctx->instance_mutex);
+ set_bit(VPU_ENC_STATUS_OUTPUT_READY, &ctx->status);
+ configure_codec(ctx);
+ mutex_unlock(&ctx->instance_mutex);
+ mutex_unlock(&ctx->dev->dev_mutex);
+ }
+
+ return 0;
+}
+
+static int vpu_enc_v4l2_ioctl_streamoff(struct file *file,
+ void *fh,
+ enum v4l2_buf_type i)
+{
+ struct vpu_ctx *ctx = v4l2_fh_to_ctx(fh);
+ struct queue_data *q_data;
+ int ret;
+
+ q_data = get_queue_by_v4l2_type(ctx, i);
+ if (!q_data)
+ return -EINVAL;
+
+ vpu_dbg(LVL_FUNC, "%s(), %s, (%d, %d)\n", __func__, q_data->desc,
+ ctx->core_dev->id, ctx->str_index);
+
+ request_eos(ctx);
+ wait_for_stop_done(ctx);
+
+ ret = vpu_enc_queue_disable(q_data, i);
+
+ return ret;
+}
+
+static const struct v4l2_ioctl_ops vpu_enc_v4l2_ioctl_ops = {
+ .vidioc_querycap = vpu_enc_v4l2_ioctl_querycap,
+ .vidioc_enum_fmt_vid_cap_mplane = vpu_enc_v4l2_ioctl_enum_fmt_vid_cap_mplane,
+ .vidioc_enum_fmt_vid_out_mplane = vpu_enc_v4l2_ioctl_enum_fmt_vid_out_mplane,
+ .vidioc_enum_framesizes = vpu_enc_v4l2_ioctl_enum_framesizes,
+ .vidioc_enum_frameintervals = vpu_enc_v4l2_ioctl_enum_frameintervals,
+ .vidioc_g_fmt_vid_cap_mplane = vpu_enc_v4l2_ioctl_g_fmt,
+ .vidioc_g_fmt_vid_out_mplane = vpu_enc_v4l2_ioctl_g_fmt,
+ .vidioc_try_fmt_vid_cap_mplane = vpu_enc_v4l2_ioctl_try_fmt,
+ .vidioc_try_fmt_vid_out_mplane = vpu_enc_v4l2_ioctl_try_fmt,
+ .vidioc_s_fmt_vid_cap_mplane = vpu_enc_v4l2_ioctl_s_fmt,
+ .vidioc_s_fmt_vid_out_mplane = vpu_enc_v4l2_ioctl_s_fmt,
+ .vidioc_g_parm = vpu_enc_v4l2_ioctl_g_parm,
+ .vidioc_s_parm = vpu_enc_v4l2_ioctl_s_parm,
+ .vidioc_expbuf = vpu_enc_v4l2_ioctl_expbuf,
+ .vidioc_g_crop = vpu_enc_v4l2_ioctl_g_crop,
+ .vidioc_s_crop = vpu_enc_v4l2_ioctl_s_crop,
+ .vidioc_encoder_cmd = vpu_enc_v4l2_ioctl_encoder_cmd,
+ .vidioc_subscribe_event = vpu_enc_v4l2_ioctl_subscribe_event,
+ .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
+ .vidioc_reqbufs = vpu_enc_v4l2_ioctl_reqbufs,
+ .vidioc_querybuf = vpu_enc_v4l2_ioctl_querybuf,
+ .vidioc_qbuf = vpu_enc_v4l2_ioctl_qbuf,
+ .vidioc_dqbuf = vpu_enc_v4l2_ioctl_dqbuf,
+ .vidioc_streamon = vpu_enc_v4l2_ioctl_streamon,
+ .vidioc_streamoff = vpu_enc_v4l2_ioctl_streamoff,
+};
+
+static void vpu_core_send_cmd(struct core_device *core, u32 idx,
+ u32 cmdid, u32 cmdnum, u32 *local_cmddata)
+{
+ WARN_ON(!core || idx >= VID_API_NUM_STREAMS);
+
+ vpu_log_cmd(cmdid, idx);
+ count_cmd(&core->attr[idx], cmdid);
+
+ mutex_lock(&core->cmd_mutex);
+ rpc_send_cmd_buf_encoder(&core->shared_mem, idx,
+ cmdid, cmdnum, local_cmddata);
+ mb();
+ MU_SendMessage(core->mu_base_virtaddr, 0, COMMAND);
+ mutex_unlock(&core->cmd_mutex);
+}
+
+static void vpu_ctx_send_cmd(struct vpu_ctx *ctx, uint32_t cmdid,
+ uint32_t cmdnum, uint32_t *local_cmddata)
+{
+ vpu_core_send_cmd(ctx->core_dev, ctx->str_index,
+ cmdid, cmdnum, local_cmddata);
+}
+
+static void set_core_fw_status(struct core_device *core, bool status)
+{
+ core->fw_is_ready = status;
+}
+
+static int reset_vpu_core_dev(struct core_device *core_dev)
+{
+ if (!core_dev)
+ return -EINVAL;
+
+ set_core_fw_status(core_dev, false);
+ core_dev->firmware_started = false;
+
+ return 0;
+}
+
+static int sw_reset_firmware(struct core_device *core, int resume)
+{
+ int ret = 0;
+
+ WARN_ON(!core);
+
+ vpu_dbg(LVL_INFO, "core[%d] sw reset firmware\n", core->id);
+
+ init_completion(&core->start_cmp);
+ vpu_core_send_cmd(core, 0, GTB_ENC_CMD_FIRM_RESET, 0, NULL);
+ ret = wait_for_start_done(core, resume);
+ if (ret) {
+ set_core_hang(core);
+ return -EINVAL;
+ }
+ core->reset_times++;
+
+ return 0;
+}
+
+static int process_core_hang(struct core_device *core)
+{
+ int ret;
+ int i;
+ int instance_count = 0;
+
+ if (!core->hang)
+ return 0;
+
+ for (i = 0; i < core->supported_instance_count; i++) {
+ if (core->ctx[i])
+ instance_count++;
+ }
+
+ if (instance_count)
+ return -EBUSY;
+
+ ret = sw_reset_firmware(core, 0);
+ if (ret)
+ return ret;
+
+ clear_core_hang(core);
+ return 0;
+}
+
+static void show_codec_configure(pMEDIAIP_ENC_PARAM param)
+{
+ if (!param)
+ return;
+
+ vpu_dbg(LVL_INFO, "Encoder Parameter:\n");
+ vpu_dbg(LVL_INFO, "\t%20s:%16d\n",
+ "Codec Mode", param->eCodecMode);
+ vpu_dbg(LVL_INFO, "\t%20s:%16d\n",
+ "Profile", param->eProfile);
+ vpu_dbg(LVL_INFO, "\t%20s:%16d\n",
+ "Level", param->uLevel);
+ vpu_dbg(LVL_INFO, "\t%20s:%16d\n",
+ "Mem Phys Addr", param->tEncMemDesc.uMemPhysAddr);
+ vpu_dbg(LVL_INFO, "\t%20s:%16d\n",
+ "Mem Virt Addr", param->tEncMemDesc.uMemVirtAddr);
+ vpu_dbg(LVL_INFO, "\t%20s:%16d\n",
+ "Mem Size", param->tEncMemDesc.uMemSize);
+ vpu_dbg(LVL_INFO, "\t%20s:%16d\n",
+ "Frame Rate", param->uFrameRate);
+ vpu_dbg(LVL_INFO, "\t%20s:%16d\n",
+ "Source Stride", param->uSrcStride);
+ vpu_dbg(LVL_INFO, "\t%20s:%16d\n",
+ "Source Width", param->uSrcWidth);
+ vpu_dbg(LVL_INFO, "\t%20s:%16d\n",
+ "Source Height", param->uSrcHeight);
+ vpu_dbg(LVL_INFO, "\t%20s:%16d\n",
+ "Source Offset x", param->uSrcOffset_x);
+ vpu_dbg(LVL_INFO, "\t%20s:%16d\n",
+ "Source Offset y", param->uSrcOffset_y);
+ vpu_dbg(LVL_INFO, "\t%20s:%16d\n",
+ "Source Crop Width", param->uSrcCropWidth);
+ vpu_dbg(LVL_INFO, "\t%20s:%16d\n",
+ "Source Crop Height", param->uSrcCropHeight);
+ vpu_dbg(LVL_INFO, "\t%20s:%16d\n",
+ "Out Width", param->uOutWidth);
+ vpu_dbg(LVL_INFO, "\t%20s:%16d\n",
+ "Out Height", param->uOutHeight);
+ vpu_dbg(LVL_INFO, "\t%20s:%16d\n",
+ "I Frame Interval", param->uIFrameInterval);
+ vpu_dbg(LVL_INFO, "\t%20s:%16d\n",
+ "GOP Length", param->uGopBLength);
+ vpu_dbg(LVL_INFO, "\t%20s:%16d\n",
+ "Low Latency Mode", param->uLowLatencyMode);
+ vpu_dbg(LVL_INFO, "\t%20s:%16d\n",
+ "Bitrate Mode", param->eBitRateMode);
+ vpu_dbg(LVL_INFO, "\t%20s:%16d\n",
+ "Target Bitrate", param->uTargetBitrate);
+ vpu_dbg(LVL_INFO, "\t%20s:%16d\n",
+ "Min Bitrate", param->uMinBitRate);
+ vpu_dbg(LVL_INFO, "\t%20s:%16d\n",
+ "Max Bitrate", param->uMaxBitRate);
+ vpu_dbg(LVL_INFO, "\t%20s:%16d\n",
+ "QP", param->uInitSliceQP);
+}
+
+static void show_firmware_version(struct core_device *core_dev,
+ unsigned int level)
+{
+ pENC_RPC_HOST_IFACE pSharedInterface;
+
+ if (!core_dev)
+ return;
+
+ pSharedInterface = core_dev->shared_mem.pSharedInterface;
+
+ vpu_dbg(level, "vpu encoder core[%d] firmware version is %d.%d.%d\n",
+ core_dev->id,
+ (pSharedInterface->FWVersion & 0x00ff0000) >> 16,
+ (pSharedInterface->FWVersion & 0x0000ff00) >> 8,
+ pSharedInterface->FWVersion & 0x000000ff);
+}
+
+static void update_encode_size(struct vpu_ctx *ctx)
+{
+ struct queue_data *src = NULL;
+ struct queue_data *dst = NULL;
+ struct vpu_attr *attr;
+ pMEDIAIP_ENC_PARAM pEncParam;
+
+ if (!ctx)
+ return;
+
+ attr = get_vpu_ctx_attr(ctx);
+ if (!attr)
+ return;
+
+ src = &ctx->q_data[V4L2_SRC];
+ dst = &ctx->q_data[V4L2_DST];
+ pEncParam = &attr->param;
+
+ pEncParam->uSrcStride = src->width;
+ pEncParam->uSrcWidth = src->width;
+ pEncParam->uSrcHeight = src->height;
+ pEncParam->uSrcOffset_x = src->rect.left;
+ pEncParam->uSrcOffset_y = src->rect.top;
+ pEncParam->uSrcCropWidth = src->rect.width;
+ pEncParam->uSrcCropHeight = src->rect.height;
+ pEncParam->uOutWidth = min(dst->width, src->rect.width);
+ pEncParam->uOutHeight = min(dst->height, src->rect.height);
+}
+
+static void init_ctx_seq_info(struct vpu_ctx *ctx)
+{
+ int i;
+
+ if (!ctx)
+ return;
+
+ ctx->sequence = 0;
+ for (i = 0; i < ARRAY_SIZE(ctx->timestams); i++)
+ ctx->timestams[i] = VPU_ENC_INVALID_TIMESTAMP;
+}
+
+static void fill_ctx_seq(struct vpu_ctx *ctx, struct vb2_data_req *p_data_req)
+{
+ u_int32 idx;
+
+ WARN_ON(!ctx || !p_data_req);
+
+ p_data_req->sequence = ctx->sequence++;
+ idx = p_data_req->sequence % VPU_ENC_SEQ_CAPACITY;
+ if (ctx->timestams[idx] != VPU_ENC_INVALID_TIMESTAMP) {
+ count_timestamp_overwrite(ctx);
+ vpu_dbg(LVL_FRAME, "[%d.%d][%d] overwrite timestamp\n",
+ ctx->core_dev->id, ctx->str_index,
+ p_data_req->sequence);
+ }
+ ctx->timestams[idx] = p_data_req->vb2_buf->timestamp;
+}
+
+static s64 get_ctx_seq_timestamp(struct vpu_ctx *ctx, u32 sequence)
+{
+ s64 timestamp;
+ u_int32 idx;
+
+ WARN_ON(!ctx);
+
+ idx = sequence % VPU_ENC_SEQ_CAPACITY;
+ timestamp = ctx->timestams[idx];
+ ctx->timestams[idx] = VPU_ENC_INVALID_TIMESTAMP;
+
+ return timestamp;
+}
+
+static void fill_vb_sequence(struct vb2_buffer *vb, u32 sequence)
+{
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+
+ vbuf->sequence = sequence;
+}
+
+static struct vb2_data_req *find_vb2_data_by_sequence(struct queue_data *queue,
+ u32 sequence)
+{
+ int i;
+
+ for (i = 0; i < queue->vb2_q.num_buffers; i++) {
+ if (!queue->vb2_reqs[i].vb2_buf)
+ continue;
+ if (queue->vb2_reqs[i].sequence == sequence)
+ return &queue->vb2_reqs[i];
+ }
+
+ return NULL;
+}
+
+static int do_configure_codec(struct vpu_ctx *ctx)
+{
+ pBUFFER_DESCRIPTOR_TYPE pEncStrBuffDesc = NULL;
+ pMEDIAIP_ENC_EXPERT_MODE_PARAM pEncExpertModeParam = NULL;
+ pMEDIAIP_ENC_PARAM enc_param;
+ struct vpu_attr *attr;
+
+ if (!ctx || !ctx->core_dev)
+ return -EINVAL;
+
+ attr = get_vpu_ctx_attr(ctx);
+ if (!attr)
+ return -EINVAL;
+
+ if (vpu_enc_alloc_stream(ctx))
+ return -ENOMEM;
+
+ update_encode_size(ctx);
+
+ enc_param = get_rpc_enc_param(ctx);
+ pEncStrBuffDesc = get_rpc_stream_buffer_desc(ctx);
+
+ pEncStrBuffDesc->start = ctx->encoder_stream.phy_addr;
+ pEncStrBuffDesc->wptr = pEncStrBuffDesc->start;
+ pEncStrBuffDesc->rptr = pEncStrBuffDesc->start;
+ pEncStrBuffDesc->end = ctx->encoder_stream.phy_addr +
+ ctx->encoder_stream.size;
+
+ vpu_dbg(LVL_DEBUG,
+ "pEncStrBuffDesc:start=%x, wptr=0x%x, rptr=%x, end=%x\n",
+ pEncStrBuffDesc->start,
+ pEncStrBuffDesc->wptr,
+ pEncStrBuffDesc->rptr,
+ pEncStrBuffDesc->end);
+
+ pEncExpertModeParam = get_rpc_expert_mode_param(ctx);
+ pEncExpertModeParam->Calib.mem_chunk_phys_addr = 0;
+ pEncExpertModeParam->Calib.mem_chunk_virt_addr = 0;
+ pEncExpertModeParam->Calib.mem_chunk_size = 0;
+ pEncExpertModeParam->Calib.cb_base = ctx->encoder_stream.phy_addr;
+ pEncExpertModeParam->Calib.cb_size = ctx->encoder_stream.size;
+
+ show_firmware_version(ctx->core_dev, LVL_INFO);
+ clear_stop_status(ctx);
+ memcpy(enc_param, &attr->param, sizeof(attr->param));
+ vpu_ctx_send_cmd(ctx, GTB_ENC_CMD_CONFIGURE_CODEC, 0, NULL);
+
+ show_codec_configure(enc_param);
+
+ return 0;
+}
+
+static int check_vpu_ctx_is_ready(struct vpu_ctx *ctx)
+{
+ if (!ctx)
+ return false;
+
+ if (!test_bit(VPU_ENC_STATUS_OUTPUT_READY, &ctx->status))
+ return false;
+ if (!test_bit(VPU_ENC_STATUS_DATA_READY, &ctx->status))
+ return false;
+
+ return true;
+}
+
+static int configure_codec(struct vpu_ctx *ctx)
+{
+ if (!ctx)
+ return -EINVAL;
+
+ if (!check_vpu_ctx_is_ready(ctx))
+ return 0;
+
+ if (ctx->core_dev->snapshot)
+ return 0;
+
+ if (test_bit(VPU_ENC_STATUS_SNAPSHOT, &ctx->status))
+ return 0;
+
+ if (!test_and_set_bit(VPU_ENC_STATUS_CONFIGURED, &ctx->status)) {
+ do_configure_codec(ctx);
+ clear_bit(VPU_ENC_STATUS_OUTPUT_READY, &ctx->status);
+ clear_bit(VPU_ENC_STATUS_DATA_READY, &ctx->status);
+ }
+
+ return 0;
+}
+
+static void dump_vb2_data(struct vb2_buffer *vb)
+{
+#ifdef DUMP_DATA
+ const int DATA_NUM = 10;
+ char *read_data;
+ u_int32 read_idx;
+ char data_str[1024];
+ int num = 0;
+
+ if (!vb)
+ return;
+
+ read_data = vb2_plane_vaddr(vb, 0);
+ num = scnprintf(data_str, sizeof(data_str),
+ "transfer data from virt 0x%p: ", read_data);
+ for (read_idx = 0; read_idx < DATA_NUM; read_idx++)
+ num += scnprintf(data_str + num, sizeof(data_str) - num,
+ " 0x%x", read_data[read_idx]);
+
+ vpu_dbg(LVL_DEBUG, "%s\n", data_str);
+#endif
+}
+
+static u32 get_vb2_plane_phy_addr(struct vb2_buffer *vb, unsigned int plane_no)
+{
+ dma_addr_t *dma_addr;
+
+ dma_addr = vb2_plane_cookie(vb, plane_no);
+ return *dma_addr + vb->planes[plane_no].data_offset;
+}
+
+static void record_start_time(struct vpu_ctx *ctx, enum QUEUE_TYPE type)
+{
+ struct vpu_attr *attr = get_vpu_ctx_attr(ctx);
+ struct timespec ts;
+
+ if (!attr)
+ return;
+
+ if (attr->ts_start[type])
+ return;
+
+ getrawmonotonic(&ts);
+ attr->ts_start[type] = ts.tv_sec * MSEC_PER_SEC +
+ ts.tv_nsec / NSEC_PER_MSEC;
+}
+
+static bool update_yuv_addr(struct vpu_ctx *ctx)
+{
+ bool bGotAFrame = FALSE;
+
+ struct vb2_data_req *p_data_req;
+ struct queue_data *This = &ctx->q_data[V4L2_SRC];
+
+ pMEDIAIP_ENC_YUV_BUFFER_DESC desc;
+
+ desc = get_rpc_yuv_buffer_desc(ctx);
+
+ if (list_empty(&This->drv_q))
+ return bGotAFrame;
+
+ p_data_req = list_first_entry(&This->drv_q, typeof(*p_data_req), list);
+
+ dump_vb2_data(p_data_req->vb2_buf);
+
+ desc->uLumaBase = get_vb2_plane_phy_addr(p_data_req->vb2_buf, 0);
+ desc->uChromaBase = get_vb2_plane_phy_addr(p_data_req->vb2_buf, 1);
+
+ if (desc->uLumaBase != 0)
+ bGotAFrame = TRUE;
+
+ /*
+ * keeps increasing,
+ * so just a frame input count rather than a Frame buffer ID
+ */
+ desc->uFrameID = p_data_req->sequence;
+ if (test_and_clear_bit(VPU_ENC_STATUS_KEY_FRAME, &ctx->status))
+ desc->uKeyFrame = 1;
+ else
+ desc->uKeyFrame = 0;
+ list_del(&p_data_req->list);
+
+ return bGotAFrame;
+}
+
+static void get_kmp_next(const u8 *p, int *next, int size)
+{
+ int k = -1;
+ int j = 0;
+
+ next[0] = -1;
+ while (j < size - 1) {
+ if (k == -1 || p[j] == p[k]) {
+ ++k;
+ ++j;
+ next[j] = k;
+ } else {
+ k = next[k];
+ }
+ }
+}
+
+static int kmp_serach(u8 *s, int s_len, const u8 *p, int p_len, int *next)
+{
+ int i = 0;
+ int j = 0;
+
+ while (i < s_len && j < p_len) {
+ if (j == -1 || s[i] == p[j]) {
+ i++;
+ j++;
+ } else {
+ j = next[j];
+ }
+ }
+ if (j == p_len)
+ return i - j;
+ else
+ return -1;
+}
+
+static int get_stuff_data_size(u8 *data, int size)
+{
+ const u8 pattern[] = VPU_STRM_END_PATTERN;
+ int next[] = VPU_STRM_END_PATTERN;
+ int index;
+
+ if (size < ARRAY_SIZE(pattern))
+ return 0;
+
+ get_kmp_next(pattern, next, ARRAY_SIZE(pattern));
+ index = kmp_serach(data, size, pattern, ARRAY_SIZE(pattern), next);
+ if (index < 0)
+ return 0;
+ vpu_dbg(LVL_DEBUG, "find end_of_stream nal\n");
+ return size - index;
+}
+
+static void count_strip_info(struct vpu_strip_info *info, u32 bytes)
+{
+ if (!info)
+ return;
+
+ info->count++;
+ info->total += bytes;
+ if (info->max < bytes)
+ info->max = bytes;
+}
+
+static void strip_stuff_data_on_tail(struct vpu_ctx *ctx, struct vb2_buffer *vb)
+{
+ u8 *ptr = vb2_plane_vaddr(vb, 0);
+ unsigned long bytesused = vb2_get_plane_payload(vb, 0);
+ int count = VPU_TAIL_SERACH_SIZE;
+ int stuff_size;
+
+ if (count > bytesused)
+ count = bytesused;
+
+ if (!count)
+ return;
+
+ stuff_size = get_stuff_data_size(ptr + bytesused - count, count);
+ if (stuff_size) {
+ struct vpu_attr *attr = get_vpu_ctx_attr(ctx);
+
+ if (attr)
+ count_strip_info(&attr->statistic.strip_sts.eos,
+ stuff_size);
+
+ vpu_dbg(LVL_DEBUG, "strip %d bytes stuff data\n", stuff_size);
+ vb2_set_plane_payload(vb, 0, bytesused - stuff_size);
+ }
+}
+
+static int check_enc_rw_flag(int flag)
+{
+ int ret = -EINVAL;
+
+ switch (flag) {
+ case VPU_ENC_FLAG_WRITEABLE:
+ case VPU_ENC_FLAG_READABLE:
+ ret = 0;
+ break;
+ default:
+ break;
+ }
+
+ return ret;
+}
+
+static void set_queue_rw_flag(struct queue_data *queue, int flag)
+{
+ if (!queue)
+ return;
+
+ if (check_enc_rw_flag(flag))
+ return;
+
+ set_bit(flag, &queue->rw_flag);
+}
+
+static void clear_queue_rw_flag(struct queue_data *queue, int flag)
+{
+ if (!queue)
+ return;
+
+ if (check_enc_rw_flag(flag))
+ return;
+
+ clear_bit(flag, &queue->rw_flag);
+}
+
+static int submit_input_and_encode(struct vpu_ctx *ctx)
+{
+ struct queue_data *queue;
+
+ if (!ctx)
+ return -EINVAL;
+
+ queue = &ctx->q_data[V4L2_SRC];
+
+ down(&queue->drv_q_lock);
+
+ if (!test_bit(VPU_ENC_FLAG_WRITEABLE, &queue->rw_flag))
+ goto exit;
+
+ if (list_empty(&queue->drv_q))
+ goto exit;
+
+ if (test_bit(VPU_ENC_STATUS_STOP_SEND, &ctx->status))
+ goto exit;
+ if (!test_bit(VPU_ENC_STATUS_START_DONE, &ctx->status))
+ goto exit;
+
+ if (update_yuv_addr(ctx)) {
+ vpu_ctx_send_cmd(ctx, GTB_ENC_CMD_FRAME_ENCODE, 0, NULL);
+ clear_queue_rw_flag(queue, VPU_ENC_FLAG_WRITEABLE);
+ record_start_time(ctx, V4L2_SRC);
+ }
+exit:
+ up(&queue->drv_q_lock);
+
+ return 0;
+}
+
+static void add_rptr(struct vpu_frame_info *frame, u32 length)
+{
+ WARN_ON(!frame);
+
+ frame->rptr += length;
+ if (frame->rptr >= frame->end)
+ frame->rptr -= (frame->end - frame->start);
+}
+
+static void report_frame_type(struct vb2_data_req *p_data_req,
+ struct vpu_frame_info *frame)
+{
+ WARN_ON(!p_data_req || !frame);
+
+ switch (frame->info.ePicType) {
+ case MEDIAIP_ENC_PIC_TYPE_IDR_FRAME:
+ case MEDIAIP_ENC_PIC_TYPE_I_FRAME:
+ p_data_req->buffer_flags = V4L2_BUF_FLAG_KEYFRAME;
+ break;
+ case MEDIAIP_ENC_PIC_TYPE_P_FRAME:
+ p_data_req->buffer_flags = V4L2_BUF_FLAG_PFRAME;
+ break;
+ case MEDIAIP_ENC_PIC_TYPE_B_FRAME:
+ p_data_req->buffer_flags = V4L2_BUF_FLAG_BFRAME;
+ break;
+ default:
+ break;
+ }
+}
+
+static u32 calc_frame_length(struct vpu_frame_info *frame)
+{
+ u32 length;
+ u32 buffer_size;
+
+ WARN_ON(!frame);
+
+ if (frame->eos)
+ return 0;
+
+ buffer_size = frame->end - frame->start;
+ if (!buffer_size)
+ return 0;
+
+ length = (buffer_size + frame->wptr - frame->rptr) % buffer_size;
+
+ return length;
+}
+
+static u32 get_ptr(u32 ptr)
+{
+ return (ptr | 0x80000000);
+}
+
+static void *get_rptr_virt(struct vpu_ctx *ctx, struct vpu_frame_info *frame)
+{
+ WARN_ON(!ctx || !frame);
+
+ return ctx->encoder_stream.virt_addr + frame->rptr - frame->start;
+}
+
+static int find_nal_begin(u8 *data, u32 size)
+{
+ const u8 pattern[] = VPU_STRM_BEGIN_PATTERN;
+ int next[] = VPU_STRM_BEGIN_PATTERN;
+ u32 len;
+ int index;
+
+ len = ARRAY_SIZE(pattern);
+ get_kmp_next(pattern, next, len);
+ index = kmp_serach(data, size, pattern, len, next);
+ if (index > 0 && data[index - 1] == 0)
+ index--;
+
+ return index;
+}
+
+static int find_frame_start_and_skip(struct vpu_ctx *ctx,
+ struct vpu_frame_info *frame, int skip)
+{
+ u32 length;
+ u32 bytesskiped = 0;
+ u8 *data = get_rptr_virt(ctx, frame);
+ int index;
+
+ length = frame->bytesleft;
+ if (frame->rptr + length <= frame->end) {
+ index = find_nal_begin(data, length);
+ if (index >= 0)
+ bytesskiped += index;
+ else
+ bytesskiped += length;
+ } else {
+ u32 size = frame->end - frame->rptr;
+
+ index = find_nal_begin(data, size);
+ if (index >= 0) {
+ bytesskiped += index;
+ } else {
+ bytesskiped += size;
+
+ data = ctx->encoder_stream.virt_addr;
+ size = length - size;
+ index = find_nal_begin(data, size);
+ if (index >= 0)
+ bytesskiped += index;
+ else
+ bytesskiped += size;
+ }
+ }
+
+ if (skip && bytesskiped) {
+ add_rptr(frame, bytesskiped);
+ frame->bytesleft -= bytesskiped;
+ }
+
+ return bytesskiped;
+}
+
+static int transfer_stream_output(struct vpu_ctx *ctx,
+ struct vpu_frame_info *frame,
+ struct vb2_data_req *p_data_req)
+{
+ struct vb2_buffer *vb = NULL;
+ u32 length;
+ void *pdst;
+
+ WARN_ON(!ctx || !frame || !p_data_req);
+
+ length = frame->bytesleft;
+
+ vb = p_data_req->vb2_buf;
+ if (length > vb->planes[0].length)
+ length = vb->planes[0].length;
+ vb2_set_plane_payload(vb, 0, length);
+
+ pdst = vb2_plane_vaddr(vb, 0);
+ if (frame->rptr + length <= frame->end) {
+ memcpy(pdst, get_rptr_virt(ctx, frame), length);
+ frame->bytesleft -= length;
+ add_rptr(frame, length);
+ } else {
+ u32 offset = frame->end - frame->rptr;
+
+ memcpy(pdst, get_rptr_virt(ctx, frame), offset);
+ frame->bytesleft -= offset;
+ add_rptr(frame, offset);
+ length -= offset;
+ memcpy(pdst + offset, get_rptr_virt(ctx, frame), length);
+ frame->bytesleft -= length;
+ add_rptr(frame, length);
+ }
+ report_frame_type(p_data_req, frame);
+ if (frame->bytesleft)
+ return 0;
+
+ strip_stuff_data_on_tail(ctx, p_data_req->vb2_buf);
+
+ return 0;
+}
+
+static int append_empty_end_frame(struct vb2_data_req *p_data_req)
+{
+ struct vb2_buffer *vb = NULL;
+ const u8 pattern[] = VPU_STRM_END_PATTERN;
+ void *pdst;
+
+ WARN_ON(!p_data_req);
+
+ vb = p_data_req->vb2_buf;
+ pdst = vb2_plane_vaddr(vb, 0);
+ memcpy(pdst, pattern, ARRAY_SIZE(pattern));
+
+ vb2_set_plane_payload(vb, 0, ARRAY_SIZE(pattern));
+ p_data_req->buffer_flags = V4L2_BUF_FLAG_LAST;
+
+ vpu_dbg(LVL_INFO, "append the last frame\n");
+
+ return 0;
+}
+
+static bool is_valid_frame_read_pos(u32 ptr, struct vpu_frame_info *frame)
+{
+ if (ptr < frame->start || ptr >= frame->end)
+ return false;
+ if (ptr >= frame->rptr && ptr < frame->wptr)
+ return true;
+ if (frame->rptr > frame->wptr) {
+ if (ptr >= frame->rptr || ptr < frame->wptr)
+ return true;
+ }
+
+ return false;
+}
+static int precheck_frame(struct vpu_ctx *ctx, struct vpu_frame_info *frame)
+{
+ struct vpu_attr *attr = get_vpu_ctx_attr(ctx);
+ u32 length;
+ int bytesskiped;
+ u32 rptr;
+
+ if (frame->eos)
+ return 0;
+ if (!frame->is_start)
+ return 0;
+
+ add_rptr(frame, 0);
+ frame->is_start = false;
+ rptr = get_ptr(frame->info.uStrBuffWrPtr);
+ if (rptr == frame->end)
+ rptr = frame->start;
+
+ if (is_valid_frame_read_pos(rptr, frame)) {
+ if (rptr != frame->rptr) {
+ vpu_dbg(LVL_DEBUG, "frame skip %d bytes\n",
+ rptr - frame->rptr);
+ count_strip_info(&attr->statistic.strip_sts.fw,
+ rptr - frame->rptr);
+ }
+ frame->rptr = rptr;
+ } else {
+ vpu_err("[%ld]wrong uStrBuffWrPtr:0x%x\n", frame->index, rptr);
+ }
+
+ length = calc_frame_length(frame);
+ if (!length || length < frame->bytesleft) {
+ vpu_err("[%d][%d]'s frame[%ld] invalid, want %d but %d, drop\n",
+ ctx->core_dev->id, ctx->str_index,
+ frame->index, frame->bytesleft, length);
+ vpu_err("uStrBuffWrPtr = 0x%x, uFrameSize = 0x%x\n",
+ frame->info.uStrBuffWrPtr, frame->info.uFrameSize);
+ add_rptr(frame, length);
+ return -EINVAL;
+ }
+
+ bytesskiped = find_frame_start_and_skip(ctx, frame, 0);
+ if (!bytesskiped)
+ return 0;
+
+ if (attr)
+ count_strip_info(&attr->statistic.strip_sts.begin, bytesskiped);
+
+ return 0;
+}
+
+static int inc_frame(struct queue_data *queue)
+{
+ struct vpu_frame_info *frame = NULL;
+
+ if (!queue)
+ return -EINVAL;
+
+ frame = vzalloc(sizeof(*frame));
+ if (!frame)
+ return -EINVAL;
+
+ frame->queue = queue;
+ list_add_tail(&frame->list, &queue->frame_idle);
+ atomic64_inc(&queue->frame_count);
+
+ vpu_dbg(LVL_DEBUG, "++ frame : %ld\n",
+ atomic64_read(&queue->frame_count));
+
+ return 0;
+}
+
+static void dec_frame(struct vpu_frame_info *frame)
+{
+ if (!frame)
+ return;
+ list_del_init(&frame->list);
+ if (frame->queue) {
+ atomic64_dec(&frame->queue->frame_count);
+
+ vpu_dbg(LVL_DEBUG, "-- frame : %ld\n",
+ atomic64_read(&frame->queue->frame_count));
+ }
+ VPU_SAFE_RELEASE(frame, vfree);
+}
+
+static struct vpu_frame_info *get_idle_frame(struct queue_data *queue)
+{
+ struct vpu_frame_info *frame = NULL;
+
+ if (!queue)
+ return NULL;
+
+ if (list_empty(&queue->frame_idle))
+ inc_frame(queue);
+ frame = list_first_entry(&queue->frame_idle,
+ struct vpu_frame_info, list);
+ if (frame)
+ list_del_init(&frame->list);
+
+ return frame;
+}
+
+static void put_frame_idle(struct vpu_frame_info *frame)
+{
+ struct queue_data *queue;
+
+ if (!frame)
+ return;
+
+ list_del_init(&frame->list);
+ memset(&frame->info, 0, sizeof(frame->info));
+ frame->bytesleft = 0;
+ frame->wptr = 0;
+ frame->rptr = 0;
+ frame->start = 0;
+ frame->end = 0;
+ frame->eos = false;
+ frame->is_start = false;
+ frame->index = 0;
+ frame->timestamp = VPU_ENC_INVALID_TIMESTAMP;
+ queue = frame->queue;
+ if (queue && atomic64_read(&queue->frame_count) <= FRAME_COUNT_THD)
+ list_add_tail(&frame->list, &queue->frame_idle);
+ else
+ dec_frame(frame);
+}
+
+static bool process_frame_done(struct queue_data *queue)
+{
+ struct vpu_ctx *ctx;
+ struct vb2_data_req *p_data_req = NULL;
+ struct vpu_frame_info *frame = NULL;
+ pBUFFER_DESCRIPTOR_TYPE stream_buffer_desc;
+
+ WARN_ON(!queue || !queue->ctx);
+
+ ctx = queue->ctx;
+
+ stream_buffer_desc = get_rpc_stream_buffer_desc(ctx);
+
+ if (list_empty(&queue->frame_q))
+ return false;
+
+ frame = list_first_entry(&queue->frame_q, typeof(*frame), list);
+ if (!frame)
+ return false;
+
+ frame->rptr = get_ptr(stream_buffer_desc->rptr);
+
+ if (precheck_frame(ctx, frame)) {
+ stream_buffer_desc->rptr = frame->rptr;
+ put_frame_idle(frame);
+ frame = NULL;
+ return true;
+ }
+
+ if (list_empty(&queue->drv_q))
+ return false;
+
+ p_data_req = list_first_entry(&queue->drv_q, typeof(*p_data_req), list);
+
+ if (frame->eos)
+ append_empty_end_frame(p_data_req);
+ else
+ transfer_stream_output(ctx, frame, p_data_req);
+
+ stream_buffer_desc->rptr = frame->rptr;
+ if (!frame->eos) {
+ fill_vb_sequence(p_data_req->vb2_buf, frame->info.uFrameID);
+ p_data_req->vb2_buf->timestamp = frame->timestamp;
+ }
+ if (!frame->bytesleft) {
+ put_frame_idle(frame);
+ frame = NULL;
+ }
+ list_del(&p_data_req->list);
+
+ if (p_data_req->vb2_buf->state == VB2_BUF_STATE_ACTIVE)
+ vb2_buffer_done(p_data_req->vb2_buf, VB2_BUF_STATE_DONE);
+ else
+ vpu_err("vb2_buf's state is invalid(%d\n)",
+ p_data_req->vb2_buf->state);
+
+ return true;
+}
+
+static int process_stream_output(struct vpu_ctx *ctx)
+{
+ struct queue_data *queue = NULL;
+
+ if (!ctx)
+ return -EINVAL;
+
+ queue = &ctx->q_data[V4L2_DST];
+
+ down(&queue->drv_q_lock);
+ while (1) {
+ if (!process_frame_done(queue))
+ break;
+ }
+ up(&queue->drv_q_lock);
+
+ return 0;
+}
+
+static void show_enc_pic_info(MEDIAIP_ENC_PIC_INFO *pEncPicInfo)
+{
+#ifdef TB_REC_DBG
+ vpu_dbg(LVL_DEBUG, " - Frame ID : 0x%x\n",
+ pEncPicInfo->uFrameID);
+
+ switch (pEncPicInfo->ePicType) {
+ case MEDIAIP_ENC_PIC_TYPE_IDR_FRAME:
+ vpu_dbg(LVL_DEBUG, " - Picture Type : IDR picture\n");
+ break;
+ case MEDIAIP_ENC_PIC_TYPE_I_FRAME:
+ vpu_dbg(LVL_DEBUG, " - Picture Type : I picture\n");
+ break;
+ case MEDIAIP_ENC_PIC_TYPE_P_FRAME:
+ vpu_dbg(LVL_DEBUG, " - Picture Type : P picture\n");
+ break;
+ case MEDIAIP_ENC_PIC_TYPE_B_FRAME:
+ vpu_dbg(LVL_DEBUG, " - Picture Type : B picture\n");
+ break;
+ default:
+ vpu_dbg(LVL_DEBUG, " - Picture Type : BI picture\n");
+ break;
+ }
+ vpu_dbg(LVL_DEBUG, " - Skipped frame : 0x%x\n",
+ pEncPicInfo->uSkippedFrame);
+ vpu_dbg(LVL_DEBUG, " - Frame size : 0x%x\n",
+ pEncPicInfo->uFrameSize);
+ vpu_dbg(LVL_DEBUG, " - Frame CRC : 0x%x\n",
+ pEncPicInfo->uFrameCrc);
+#endif
+}
+
+static int handle_event_start_done(struct vpu_ctx *ctx)
+{
+ if (!ctx)
+ return -EINVAL;
+
+ set_bit(VPU_ENC_STATUS_START_DONE, &ctx->status);
+ set_queue_rw_flag(&ctx->q_data[V4L2_SRC], VPU_ENC_FLAG_WRITEABLE);
+ submit_input_and_encode(ctx);
+
+ enable_fps_sts(get_vpu_ctx_attr(ctx));
+
+ return 0;
+}
+
+static int handle_event_mem_request(struct vpu_ctx *ctx,
+ MEDIAIP_ENC_MEM_REQ_DATA *req_data)
+{
+ int ret;
+
+ if (!ctx || !req_data)
+ return -EINVAL;
+
+ ret = vpu_enc_alloc_mem(ctx, req_data, get_rpc_mem_pool(ctx));
+ if (ret) {
+ vpu_err("fail to alloc encoder memory\n");
+ return ret;
+ }
+ vpu_ctx_send_cmd(ctx, GTB_ENC_CMD_STREAM_START, 0, NULL);
+ set_bit(VPU_ENC_STATUS_START_SEND, &ctx->status);
+
+ return 0;
+}
+
+static int handle_event_frame_done(struct vpu_ctx *ctx,
+ MEDIAIP_ENC_PIC_INFO *pEncPicInfo)
+{
+ struct queue_data *queue;
+ struct vpu_frame_info *frame;
+ pBUFFER_DESCRIPTOR_TYPE stream_buffer_desc;
+ s64 timestamp;
+
+ if (!ctx || !pEncPicInfo)
+ return -EINVAL;
+
+ vpu_dbg(LVL_DEBUG, "Frame done(%d) - uFrameID = %d\n",
+ pEncPicInfo->uPicEncodDone, pEncPicInfo->uFrameID);
+
+ queue = &ctx->q_data[V4L2_DST];
+ if (!pEncPicInfo->uPicEncodDone) {
+ vpu_err("Pic Encoder Not Done\n");
+ return -EINVAL;
+ }
+
+ stream_buffer_desc = get_rpc_stream_buffer_desc(ctx);
+ if (stream_buffer_desc->rptr < stream_buffer_desc->start ||
+ stream_buffer_desc->rptr > stream_buffer_desc->end ||
+ stream_buffer_desc->wptr < stream_buffer_desc->start ||
+ stream_buffer_desc->wptr > stream_buffer_desc->end ||
+ stream_buffer_desc->end - stream_buffer_desc->start !=
+ ctx->encoder_stream.size) {
+ vpu_err("stream buffer desc is invalid, s:%x,e:%x,r:%x,w:%x\n",
+ stream_buffer_desc->start,
+ stream_buffer_desc->end,
+ stream_buffer_desc->rptr,
+ stream_buffer_desc->wptr);
+ return -EINVAL;
+ }
+
+ show_enc_pic_info(pEncPicInfo);
+ record_start_time(ctx, V4L2_DST);
+
+ timestamp = get_ctx_seq_timestamp(ctx, pEncPicInfo->uFrameID);
+
+ down(&queue->drv_q_lock);
+ frame = get_idle_frame(queue);
+ if (frame) {
+ struct vpu_attr *attr = get_vpu_ctx_attr(ctx);
+
+ memcpy(&frame->info, pEncPicInfo, sizeof(frame->info));
+ frame->bytesleft = frame->info.uFrameSize;
+ frame->wptr = get_ptr(stream_buffer_desc->wptr);
+ frame->rptr = get_ptr(stream_buffer_desc->rptr);
+ frame->start = get_ptr(stream_buffer_desc->start);
+ frame->end = get_ptr(stream_buffer_desc->end);
+ frame->eos = false;
+ frame->is_start = true;
+ frame->timestamp = timestamp;
+ if (attr)
+ frame->index = attr->statistic.encoded_count;
+
+ list_add_tail(&frame->list, &queue->frame_q);
+ } else {
+ vpu_err("fail to alloc memory for frame info\n");
+ }
+ up(&queue->drv_q_lock);
+ count_encoded_frame(ctx);
+
+ /* Sync the write pointer to the local view of it */
+ process_stream_output(ctx);
+
+ return 0;
+}
+
+static int handle_event_frame_release(struct vpu_ctx *ctx, u_int32 *uFrameID)
+{
+ struct queue_data *This = &ctx->q_data[V4L2_SRC];
+ struct vb2_data_req *p_data_req = NULL;
+
+ if (!ctx || !uFrameID)
+ return -EINVAL;
+
+ This = &ctx->q_data[V4L2_SRC];
+ vpu_dbg(LVL_DEBUG, "Frame release - uFrameID = %d\n", *uFrameID);
+ p_data_req = find_vb2_data_by_sequence(This, *uFrameID);
+ if (!p_data_req) {
+ vpu_err("uFrameID[%d] is invalid\n", *uFrameID);
+ return -EINVAL;
+ }
+ if (p_data_req->vb2_buf->state == VB2_BUF_STATE_ACTIVE)
+ vb2_buffer_done(p_data_req->vb2_buf, VB2_BUF_STATE_DONE);
+
+ return 0;
+}
+
+static int handle_event_stop_done(struct vpu_ctx *ctx)
+{
+ struct queue_data *queue;
+ struct vpu_frame_info *frame;
+
+ WARN_ON(!ctx);
+ queue = &ctx->q_data[V4L2_DST];
+
+ disable_fps_sts(get_vpu_ctx_attr(ctx));
+
+ set_bit(VPU_ENC_STATUS_STOP_DONE, &ctx->status);
+ notify_eos(ctx);
+
+ down(&queue->drv_q_lock);
+ frame = get_idle_frame(queue);
+ if (frame) {
+ frame->eos = true;
+ list_add_tail(&frame->list, &queue->frame_q);
+ } else {
+ vpu_err("fail to alloc memory for last frame\n");
+ }
+ up(&queue->drv_q_lock);
+
+ process_stream_output(ctx);
+
+ clear_start_status(ctx);
+ init_ctx_seq_info(ctx);
+ complete(&ctx->stop_cmp);
+
+ return 0;
+}
+
+static void vpu_enc_event_handler(struct vpu_ctx *ctx,
+ u_int32 uEvent, u_int32 *event_data)
+{
+ vpu_log_event(uEvent, ctx->str_index);
+ count_event(ctx, uEvent);
+ vpu_enc_check_mem_overstep(ctx);
+
+ switch (uEvent) {
+ case VID_API_ENC_EVENT_START_DONE:
+ handle_event_start_done(ctx);
+ break;
+ case VID_API_ENC_EVENT_MEM_REQUEST:
+ handle_event_mem_request(ctx,
+ (MEDIAIP_ENC_MEM_REQ_DATA *)event_data);
+ break;
+ case VID_API_ENC_EVENT_PARA_UPD_DONE:
+ break;
+ case VID_API_ENC_EVENT_FRAME_DONE:
+ handle_event_frame_done(ctx,
+ (MEDIAIP_ENC_PIC_INFO *)event_data);
+ break;
+ case VID_API_ENC_EVENT_FRAME_RELEASE:
+ handle_event_frame_release(ctx, (u_int32 *)event_data);
+ break;
+ case VID_API_ENC_EVENT_STOP_DONE:
+ handle_event_stop_done(ctx);
+ break;
+ case VID_API_ENC_EVENT_FRAME_INPUT_DONE:
+ set_queue_rw_flag(&ctx->q_data[V4L2_SRC],
+ VPU_ENC_FLAG_WRITEABLE);
+ response_stop_stream(ctx);
+ submit_input_and_encode(ctx);
+ break;
+ case VID_API_ENC_EVENT_TERMINATE_DONE:
+ break;
+ case VID_API_ENC_EVENT_RESET_DONE:
+ break;
+ case VID_API_ENC_EVENT_FIRMWARE_XCPT:
+ vpu_err("firmware exception:%s\n", (char *)event_data);
+ break;
+ default:
+ vpu_err("........unknown event : 0x%x\n", uEvent);
+ break;
+ }
+}
+
+static void enable_mu(struct core_device *dev)
+{
+ u32 mu_addr;
+
+ vpu_dbg(LVL_ALL, "enable mu for core[%d]\n", dev->id);
+
+ rpc_init_shared_memory_encoder(&dev->shared_mem,
+ cpu_phy_to_mu(dev, dev->m0_rpc_phy),
+ dev->m0_rpc_virt, dev->rpc_buf_size,
+ &dev->rpc_actual_size);
+ rpc_set_system_cfg_value_encoder(dev->shared_mem.pSharedInterface,
+ dev->vdev->reg_rpc_system, dev->id);
+
+ if (dev->rpc_actual_size > dev->rpc_buf_size)
+ vpu_err("rpc actual size(0x%x) > (0x%x), may occur overlay\n",
+ dev->rpc_actual_size, dev->rpc_buf_size);
+
+ mu_addr = cpu_phy_to_mu(dev, dev->m0_rpc_phy + dev->rpc_buf_size);
+ rpc_set_print_buffer(&dev->shared_mem, mu_addr, dev->print_buf_size);
+ dev->print_buf = dev->m0_rpc_virt + dev->rpc_buf_size;
+
+ mu_addr = cpu_phy_to_mu(dev, dev->m0_rpc_phy);
+ MU_sendMesgToFW(dev->mu_base_virtaddr, RPC_BUF_OFFSET, mu_addr);
+
+ MU_sendMesgToFW(dev->mu_base_virtaddr, BOOT_ADDRESS,
+ dev->m0_p_fw_space_phy);
+ MU_sendMesgToFW(dev->mu_base_virtaddr, INIT_DONE, 2);
+}
+
+static void get_core_supported_instance_count(struct core_device *core)
+{
+ pENC_RPC_HOST_IFACE iface;
+
+ iface = core->shared_mem.pSharedInterface;
+ core->supported_instance_count =
+ min_t(u32, iface->uMaxEncoderStreams, VID_API_NUM_STREAMS);
+}
+
+static int re_configure_codecs(struct core_device *core)
+{
+ int i;
+
+ for (i = 0; i < core->supported_instance_count; i++) {
+ struct vpu_ctx *ctx = core->ctx[i];
+ struct queue_data *queue;
+
+ if (!ctx || !test_bit(VPU_ENC_STATUS_INITIALIZED, &ctx->status))
+ continue;
+
+ mutex_lock(&ctx->instance_mutex);
+ queue = &ctx->q_data[V4L2_SRC];
+ if (!list_empty(&queue->drv_q)) {
+ vpu_dbg(LVL_INFO,
+ "re configure codec for core[%d]\n", core->id);
+ configure_codec(ctx);
+ submit_input_and_encode(ctx);
+ }
+ mutex_unlock(&ctx->instance_mutex);
+ }
+
+ return 0;
+}
+
+static int wait_for_start_done(struct core_device *core, int resume)
+{
+ int ret;
+
+ if (!core)
+ return -EINVAL;
+
+ ret = wait_for_completion_timeout(&core->start_cmp,
+ msecs_to_jiffies(1000));
+ if (!ret) {
+ vpu_err("error: wait for core[%d] %s done timeout!\n",
+ core->id, resume ? "resume" : "start");
+ return -EINVAL;
+ }
+
+ if (resume)
+ re_configure_codecs(core);
+
+ return 0;
+}
+
+static void vpu_core_start_done(struct core_device *core)
+{
+ if (!core)
+ return;
+
+ get_core_supported_instance_count(core);
+ core->firmware_started = true;
+ complete(&core->start_cmp);
+
+ show_firmware_version(core, LVL_ALL);
+}
+
+//This code is added for MU
+static irqreturn_t fsl_vpu_enc_mu_isr(int irq, void *This)
+{
+ struct core_device *dev = This;
+ u32 msg;
+
+ MU_ReceiveMsg(dev->mu_base_virtaddr, 0, &msg);
+ if (msg == 0xaa) {
+ enable_mu(dev);
+ } else if (msg == 0x55) {
+ vpu_core_start_done(dev);
+ } else if (msg == 0xA5) {
+ /*receive snapshot done msg and wakeup complete to suspend*/
+ complete(&dev->snap_done_cmp);
+ } else
+ queue_work(dev->workqueue, &dev->msg_work);
+
+ return IRQ_HANDLED;
+}
+
+/* Initialization of the MU code. */
+static int vpu_enc_mu_init(struct core_device *core_dev)
+{
+ int ret = 0;
+
+ core_dev->mu_base_virtaddr =
+ core_dev->vdev->regs_base + core_dev->reg_base;
+ WARN_ON(!core_dev->mu_base_virtaddr);
+
+ vpu_dbg(LVL_INFO, "core[%d] irq : %d\n", core_dev->id, core_dev->irq);
+
+ ret = devm_request_irq(core_dev->generic_dev, core_dev->irq,
+ fsl_vpu_enc_mu_isr,
+ IRQF_EARLY_RESUME,
+ "vpu_mu_isr",
+ (void *)core_dev);
+ if (ret) {
+ vpu_err("request_irq failed %d, error = %d\n",
+ core_dev->irq, ret);
+ return -EINVAL;
+ }
+
+ if (!core_dev->vpu_mu_init) {
+ MU_Init(core_dev->mu_base_virtaddr);
+ MU_EnableRxFullInt(core_dev->mu_base_virtaddr, 0);
+ core_dev->vpu_mu_init = 1;
+ }
+
+ return ret;
+}
+
+static struct vpu_ctx *get_ctx_by_index(struct core_device *core, int index)
+{
+ struct vpu_ctx *ctx = NULL;
+
+ if (!core)
+ return NULL;
+
+ if (index < 0 || index >= core->supported_instance_count)
+ return NULL;
+
+ ctx = core->ctx[index];
+ if (!ctx)
+ return NULL;
+
+ if (!test_bit(VPU_ENC_STATUS_INITIALIZED, &ctx->status)) {
+ vpu_err("core[%d]'s ctx[%d] is not initialized\n",
+ core->id, index);
+ return NULL;
+ }
+
+ if (test_bit(VPU_ENC_STATUS_CLOSED, &ctx->status)) {
+ vpu_err("core[%d]'s ctx[%d] is closed\n",
+ core->id, index);
+ return NULL;
+ }
+
+ return ctx;
+}
+
+static int process_ctx_msg(struct vpu_ctx *ctx, struct msg_header *header)
+{
+ int ret = 0;
+ struct vpu_event_msg *msg = NULL;
+ u32 *pdata = NULL;
+
+ if (!ctx || !header)
+ return -EINVAL;
+
+ if (ctx->ctx_released)
+ return -EINVAL;
+
+ msg = get_idle_msg(ctx);
+ if (!msg) {
+ vpu_err("get idle msg fail\n");
+ return -ENOMEM;
+ }
+
+ msg->idx = header->idx;
+ msg->msgid = header->msgid;
+ msg->number = header->msgnum;
+ pdata = msg->data;
+ ret = 0;
+ if (msg->number > ARRAY_SIZE(msg->data)) {
+ ret = alloc_msg_ext_buffer(msg, header->msgnum);
+ pdata = msg->ext_data;
+ }
+ rpc_read_msg_array(&ctx->core_dev->shared_mem, pdata, msg->number);
+ if (ret) {
+ put_idle_msg(ctx, msg);
+ return ret;
+ }
+
+ push_back_event_msg(ctx, msg);
+
+ return ret;
+}
+
+static int process_msg(struct core_device *core)
+{
+ struct msg_header header;
+ struct vpu_ctx *ctx = NULL;
+ int ret;
+
+ ret = rpc_get_msg_header(&core->shared_mem, &header);
+ if (ret)
+ return ret;
+
+ if (header.idx >= ARRAY_SIZE(core->ctx)) {
+ vpu_err("msg idx(%d) is out of range\n", header.idx);
+ return -EINVAL;
+ }
+
+ mutex_lock(&core->vdev->dev_mutex);
+ ctx = get_ctx_by_index(core, header.idx);
+ if (ctx != NULL) {
+ process_ctx_msg(ctx, &header);
+ queue_work(ctx->instance_wq, &ctx->instance_work);
+ } else {
+ vpu_err("msg[%d] of ctx[%d] is missed\n",
+ header.msgid, header.idx);
+ rpc_read_msg_array(&core->shared_mem, NULL, header.msgnum);
+ }
+ mutex_unlock(&core->vdev->dev_mutex);
+
+ return 0;
+}
+
+extern u_int32 rpc_MediaIPFW_Video_message_check_encoder(struct shared_addr *This);
+static void vpu_enc_msg_run_work(struct work_struct *work)
+{
+ struct core_device *dev = container_of(work, struct core_device, msg_work);
+ /*struct vpu_ctx *ctx;*/
+ /*struct event_msg msg;*/
+ struct shared_addr *This = &dev->shared_mem;
+
+ while (rpc_MediaIPFW_Video_message_check_encoder(This) == API_MSG_AVAILABLE) {
+ process_msg(dev);
+ }
+ if (rpc_MediaIPFW_Video_message_check_encoder(This) == API_MSG_BUFFER_ERROR)
+ vpu_err("MSG num is too big to handle");
+}
+
+static void vpu_enc_msg_instance_work(struct work_struct *work)
+{
+ struct vpu_ctx *ctx = container_of(work, struct vpu_ctx, instance_work);
+ struct vpu_event_msg *msg;
+
+ while (1) {
+ msg = pop_event_msg(ctx);
+ if (!msg)
+ break;
+ if (msg->ext_data)
+ vpu_enc_event_handler(ctx, msg->msgid, msg->ext_data);
+ else
+ vpu_enc_event_handler(ctx, msg->msgid, msg->data);
+
+ put_idle_msg(ctx, msg);
+ }
+}
+
+static int vpu_queue_setup(struct vb2_queue *vq,
+ unsigned int *buf_count,
+ unsigned int *plane_count,
+ unsigned int psize[],
+ struct device *allocators[])
+{
+ struct queue_data *This = (struct queue_data *)vq->drv_priv;
+
+ vpu_dbg(LVL_BUF, "%s(), %s, (%d, %d)\n", __func__, This->desc,
+ This->ctx->core_dev->id, This->ctx->str_index);
+
+ if (V4L2_TYPE_IS_OUTPUT(vq->type)) {
+ if (vq->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
+ *plane_count = 2;
+ psize[0] = This->sizeimage[0];//check alignment
+ psize[1] = This->sizeimage[1];//check colocated_size
+ } else {
+ psize[0] = This->sizeimage[0] + This->sizeimage[1];
+ *plane_count = 1;
+ }
+ if (*buf_count < MIN_BUFFER_COUNT)
+ *buf_count = MIN_BUFFER_COUNT;
+ } else {
+ *plane_count = 1;
+ psize[0] = This->sizeimage[0];//check alignment
+ }
+
+ if (*buf_count > VPU_MAX_BUFFER)
+ *buf_count = VPU_MAX_BUFFER;
+ if (*buf_count < 1)
+ *buf_count = 1;
+
+ return 0;
+}
+
+static int vpu_buf_prepare(struct vb2_buffer *vb)
+{
+ struct vb2_queue *vq = vb->vb2_queue;
+ struct queue_data *q_data = (struct queue_data *)vq->drv_priv;
+
+ vpu_dbg(LVL_BUF, "%s(), %s, (%d, %d)\n", __func__, q_data->desc,
+ q_data->ctx->core_dev->id, q_data->ctx->str_index);
+
+ return 0;
+}
+
+
+static int vpu_start_streaming(struct vb2_queue *q, unsigned int count)
+{
+ struct queue_data *q_data = (struct queue_data *)q->drv_priv;
+
+ vpu_dbg(LVL_BUF, "%s(), %s, (%d, %d)\n", __func__, q_data->desc,
+ q_data->ctx->core_dev->id, q_data->ctx->str_index);
+
+ return 0;
+}
+
+static void vpu_stop_streaming(struct vb2_queue *q)
+{
+ struct queue_data *q_data = (struct queue_data *)q->drv_priv;
+
+ vpu_dbg(LVL_BUF, "%s(), %s, (%d, %d)\n", __func__, q_data->desc,
+ q_data->ctx->core_dev->id, q_data->ctx->str_index);
+ clear_queue(q_data);
+}
+
+static void vpu_buf_queue(struct vb2_buffer *vb)
+{
+ struct vb2_queue *vq = vb->vb2_queue;
+ struct queue_data *This = (struct queue_data *)vq->drv_priv;
+ struct vb2_data_req *data_req;
+ struct vpu_ctx *ctx = This->ctx;
+
+ vpu_dbg(LVL_BUF, "%s(), %s, (%d, %d)\n", __func__, This->desc,
+ This->ctx->core_dev->id, This->ctx->str_index);
+
+ data_req = &This->vb2_reqs[vb->index];
+ data_req->vb2_buf = vb;
+ if (V4L2_TYPE_IS_OUTPUT(vq->type)) {
+ fill_ctx_seq(ctx, data_req);
+ fill_vb_sequence(vb, data_req->sequence);
+ }
+ list_add_tail(&data_req->list, &This->drv_q);
+}
+
+static bool is_enc_dma_buf(struct vb2_buffer *vb)
+{
+ struct vb2_queue *vq = vb->vb2_queue;
+
+ if (vb->memory != V4L2_MEMORY_MMAP)
+ return false;
+
+ if (vq->mem_ops != &vb2_dma_contig_memops)
+ return false;
+
+ return true;
+}
+
+static int vpu_enc_buf_init(struct vb2_buffer *vb)
+{
+ struct vb2_queue *vq = vb->vb2_queue;
+ struct queue_data *queue = vq->drv_priv;
+ struct vpu_ctx *ctx = queue->ctx;
+ int i;
+
+ vpu_dbg(LVL_BUF, "%s(), %s, (%d, %d)\n", __func__, queue->desc,
+ ctx->core_dev->id, ctx->str_index);
+ if (!is_enc_dma_buf(vb))
+ return 0;
+
+ for (i = 0; i < vb->num_planes; i++)
+ vpu_enc_add_dma_size(get_vpu_ctx_attr(ctx),
+ vb->planes[i].length);
+
+ return 0;
+}
+
+static void vpu_enc_buf_cleanup(struct vb2_buffer *vb)
+{
+ struct vb2_queue *vq = vb->vb2_queue;
+ struct queue_data *queue = vq->drv_priv;
+ struct vpu_ctx *ctx = queue->ctx;
+ int i;
+
+ vpu_dbg(LVL_BUF, "%s(), %s, (%d, %d)\n", __func__, queue->desc,
+ ctx->core_dev->id, ctx->str_index);
+
+ if (!is_enc_dma_buf(vb))
+ return;
+
+ for (i = 0; i < vb->num_planes; i++)
+ vpu_enc_sub_dma_size(get_vpu_ctx_attr(ctx),
+ vb->planes[i].length);
+}
+
+static void vpu_prepare(struct vb2_queue *q)
+{
+ struct queue_data *q_data = (struct queue_data *)q->drv_priv;
+
+ vpu_dbg(LVL_BUF, "%s(), %s, (%d, %d)\n", __func__, q_data->desc,
+ q_data->ctx->core_dev->id, q_data->ctx->str_index);
+}
+
+static void vpu_finish(struct vb2_queue *q)
+{
+ struct queue_data *q_data = (struct queue_data *)q->drv_priv;
+
+ vpu_dbg(LVL_BUF, "%s(), %s, (%d, %d)\n", __func__, q_data->desc,
+ q_data->ctx->core_dev->id, q_data->ctx->str_index);
+}
+
+static struct vb2_ops vpu_enc_v4l2_qops = {
+ .queue_setup = vpu_queue_setup,
+ .buf_init = vpu_enc_buf_init,
+ .buf_cleanup = vpu_enc_buf_cleanup,
+ .wait_prepare = vpu_prepare,
+ .wait_finish = vpu_finish,
+ .buf_prepare = vpu_buf_prepare,
+ .start_streaming = vpu_start_streaming,
+ .stop_streaming = vpu_stop_streaming,
+ .buf_queue = vpu_buf_queue,
+};
+
+static void init_vb2_queue(struct queue_data *This, unsigned int type,
+ struct vpu_ctx *ctx,
+ const struct vb2_mem_ops *mem_ops,
+ gfp_t gfp_flags)
+{
+ struct vb2_queue *vb2_q = &This->vb2_q;
+ int ret;
+
+ vpu_log_func();
+
+ // initialze driver queue
+ INIT_LIST_HEAD(&This->drv_q);
+ INIT_LIST_HEAD(&This->frame_q);
+ INIT_LIST_HEAD(&This->frame_idle);
+ atomic64_set(&This->frame_count, 0);
+ // initialize vb2 queue
+ vb2_q->type = type;
+ vb2_q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF;
+ vb2_q->gfp_flags = gfp_flags;
+ vb2_q->ops = &vpu_enc_v4l2_qops;
+ vb2_q->drv_priv = This;
+ if (mem_ops)
+ vb2_q->mem_ops = mem_ops;
+ else
+ vb2_q->mem_ops = &vb2_dma_contig_memops;
+ vb2_q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
+ vb2_q->dev = &ctx->dev->plat_dev->dev;
+ ret = vb2_queue_init(vb2_q);
+ if (ret)
+ vpu_err("%s vb2_queue_init() failed (%d)!\n",
+ __func__,
+ ret
+ );
+ else
+ This->vb2_q_inited = true;
+}
+
+static void vpu_enc_init_output_queue(struct vpu_ctx *ctx,
+ struct queue_data *q)
+{
+ WARN_ON(!ctx);
+ WARN_ON(!q);
+
+ vpu_log_func();
+
+ init_vb2_queue(q,
+ V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
+ ctx,
+ &vb2_dma_contig_memops,
+ GFP_DMA32);
+ q->type = V4L2_SRC;
+ sema_init(&q->drv_q_lock, 1);
+ q->ctx = ctx;
+
+ q->supported_fmts = formats_yuv_enc;
+ q->fmt_count = ARRAY_SIZE(formats_yuv_enc);
+ q->current_fmt = &formats_yuv_enc[0];
+
+ q->width = VPU_ENC_WIDTH_DEFAULT;
+ q->height = VPU_ENC_HEIGHT_DEFAULT;
+ q->rect.left = 0;
+ q->rect.top = 0;
+ q->rect.width = VPU_ENC_WIDTH_DEFAULT;
+ q->rect.height = VPU_ENC_HEIGHT_DEFAULT;
+ scnprintf(q->desc, sizeof(q->desc), "OUTPUT");
+}
+
+static void vpu_enc_init_capture_queue(struct vpu_ctx *ctx,
+ struct queue_data *q)
+{
+ WARN_ON(!ctx);
+ WARN_ON(!q);
+
+ vpu_log_func();
+
+ init_vb2_queue(q,
+ V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE,
+ ctx,
+ &vb2_vmalloc_memops, 0);
+ q->type = V4L2_DST;
+ sema_init(&q->drv_q_lock, 1);
+ q->ctx = ctx;
+
+ q->supported_fmts = formats_compressed_enc;
+ q->fmt_count = ARRAY_SIZE(formats_compressed_enc);
+ q->current_fmt = &formats_compressed_enc[0];
+
+ q->width = VPU_ENC_WIDTH_DEFAULT;
+ q->height = VPU_ENC_HEIGHT_DEFAULT;
+ scnprintf(q->desc, sizeof(q->desc), "CAPTURE");
+}
+
+static void vpu_enc_init_queue_data(struct vpu_ctx *ctx)
+{
+ vpu_enc_init_output_queue(ctx, &ctx->q_data[V4L2_SRC]);
+ vpu_enc_init_capture_queue(ctx, &ctx->q_data[V4L2_DST]);
+}
+
+static void vpu_enc_release_queue_data(struct vpu_ctx *ctx)
+{
+ vpu_enc_queue_release(&ctx->q_data[V4L2_SRC]);
+ vpu_enc_queue_release(&ctx->q_data[V4L2_DST]);
+}
+
+static void vpu_ctx_power_on(struct vpu_ctx *ctx)
+{
+ if (!ctx || !ctx->core_dev)
+ return;
+
+ if (ctx->power_status)
+ return;
+ pm_runtime_get_sync(ctx->core_dev->generic_dev);
+ ctx->power_status = true;
+}
+
+static void vpu_ctx_power_off(struct vpu_ctx *ctx)
+{
+ if (!ctx || !ctx->core_dev)
+ return;
+
+ if (!ctx->power_status)
+ return;
+ pm_runtime_put_sync(ctx->core_dev->generic_dev);
+ ctx->power_status = false;
+}
+
+static int set_vpu_fw_addr(struct vpu_dev *dev, struct core_device *core_dev)
+{
+ off_t reg_fw_base;
+
+ if (!dev || !core_dev)
+ return -EINVAL;
+
+ MU_Init(core_dev->mu_base_virtaddr);
+ MU_EnableRxFullInt(core_dev->mu_base_virtaddr, 0);
+
+ reg_fw_base = core_dev->reg_csr_base;
+ write_vpu_reg(dev, core_dev->m0_p_fw_space_phy, reg_fw_base);
+ write_vpu_reg(dev, 0x0, reg_fw_base + 4);
+
+ return 0;
+}
+
+static void cleanup_firmware_memory(struct core_device *core_dev)
+{
+ memset_io(core_dev->m0_p_fw_space_vir, 0, core_dev->fw_buf_size);
+}
+
+static int vpu_firmware_download(struct vpu_dev *This, u_int32 core_id)
+{
+ const struct firmware *m0_pfw = NULL;
+ const u8 *image;
+ unsigned int FW_Size = 0;
+ int ret = 0;
+ struct core_device *core_dev = &This->core_dev[core_id];
+ char *p = This->core_dev[core_id].m0_p_fw_space_vir;
+
+ vpu_log_func();
+
+ ret = request_firmware(&m0_pfw, M0FW_FILENAME, This->generic_dev);
+ if (ret) {
+ vpu_err("%s() request fw %s failed(%d)\n",
+ __func__, M0FW_FILENAME, ret);
+
+ return ret;
+ }
+ vpu_dbg(LVL_DEBUG, "%s() request fw %s got size(%ld)\n",
+ __func__, M0FW_FILENAME, m0_pfw->size);
+
+ image = m0_pfw->data;
+ FW_Size = min_t(u32, m0_pfw->size, This->core_dev[core_id].fw_buf_size);
+ This->core_dev[core_id].fw_actual_size = FW_Size;
+
+ cleanup_firmware_memory(core_dev);
+ memcpy(core_dev->m0_p_fw_space_vir, image, FW_Size);
+ p[16] = This->plat_type;
+ p[17] = core_id + 1;
+ p[18] = 1;
+ set_vpu_fw_addr(This, &This->core_dev[core_id]);
+
+ release_firmware(m0_pfw);
+ m0_pfw = NULL;
+
+ return ret;
+}
+
+static int download_vpu_firmware(struct vpu_dev *dev,
+ struct core_device *core_dev)
+{
+ int ret = 0;
+
+ if (!dev || !core_dev)
+ return -EINVAL;
+
+ if (core_dev->fw_is_ready)
+ return 0;
+
+ vpu_dbg(LVL_INFO, "download firmware for core[%d]\n", core_dev->id);
+ init_completion(&core_dev->start_cmp);
+ ret = vpu_firmware_download(dev, core_dev->id);
+ if (ret) {
+ vpu_err("error: vpu_firmware_download fail\n");
+ goto exit;
+ }
+ wait_for_start_done(core_dev, 0);
+ if (!core_dev->firmware_started) {
+ vpu_err("core[%d] start firmware failed\n", core_dev->id);
+ ret = -EINVAL;
+ goto exit;
+ }
+
+ set_core_fw_status(core_dev, true);
+ clear_core_hang(core_dev);
+exit:
+ return ret;
+}
+
+static bool is_valid_ctx(struct vpu_ctx *ctx)
+{
+ if (!ctx)
+ return false;
+ if (!ctx->dev || !ctx->core_dev)
+ return false;
+ if (ctx->str_index >= ARRAY_SIZE(ctx->core_dev->ctx))
+ return false;
+
+ return true;
+}
+
+static void free_instance(struct vpu_ctx *ctx)
+{
+ if (!ctx)
+ return;
+
+ if (is_valid_ctx(ctx))
+ ctx->core_dev->ctx[ctx->str_index] = NULL;
+ VPU_SAFE_RELEASE(ctx, kfree);
+}
+
+static u32 count_free_core_slot(struct core_device *core)
+{
+ u32 count = 0;
+ int i;
+
+ for (i = 0; i < core->supported_instance_count; i++) {
+ if (!core->ctx[i])
+ count++;
+ }
+
+ return count;
+}
+
+static struct core_device *find_proper_core(struct vpu_dev *dev)
+{
+ struct core_device *core = NULL;
+ u32 maximum = 0;
+ u32 count;
+ int i;
+ int ret;
+
+ for (i = 0; i < dev->core_num; i++) {
+ struct core_device *core_dev = &dev->core_dev[i];
+
+ ret = process_core_hang(core_dev);
+ if (ret)
+ continue;
+
+ ret = download_vpu_firmware(dev, core_dev);
+ if (ret)
+ continue;
+
+ if (core_dev->supported_instance_count == 0)
+ continue;
+
+ count = count_free_core_slot(core_dev);
+ if (count == core_dev->supported_instance_count)
+ return core_dev;
+
+ if (maximum < count) {
+ core = core_dev;
+ maximum = count;
+ }
+ }
+
+ return core;
+}
+
+static int request_instance(struct core_device *core, struct vpu_ctx *ctx)
+{
+ int found = 0;
+ int idx;
+
+ if (!core || !ctx)
+ return -EINVAL;
+
+ for (idx = 0; idx < core->supported_instance_count; idx++) {
+ if (!core->ctx[idx]) {
+ found = 1;
+ ctx->core_dev = core;
+ ctx->str_index = idx;
+ ctx->dev = core->vdev;
+ break;
+ }
+ }
+
+ if (!found) {
+ vpu_err("cann't request any instance\n");
+ return -EBUSY;
+ }
+
+ return 0;
+}
+
+static int construct_vpu_ctx(struct vpu_ctx *ctx)
+{
+ if (!ctx)
+ return -EINVAL;
+
+ ctx->ctrl_inited = false;
+ mutex_init(&ctx->instance_mutex);
+ ctx->ctx_released = false;
+
+ return 0;
+}
+
+static struct vpu_ctx *create_and_request_instance(struct vpu_dev *dev)
+{
+ struct core_device *core = NULL;
+ struct vpu_ctx *ctx = NULL;
+ int ret;
+
+ if (!dev)
+ return NULL;
+
+ core = find_proper_core(dev);
+ if (!core)
+ return NULL;
+
+ ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
+ if (!ctx)
+ return NULL;
+
+ ret = request_instance(core, ctx);
+ if (ret < 0) {
+ VPU_SAFE_RELEASE(ctx, kfree);
+ return NULL;
+ }
+
+ construct_vpu_ctx(ctx);
+ vpu_ctx_power_on(ctx);
+ vpu_dbg(LVL_INFO, "request encoder instance : %d.%d\n",
+ ctx->core_dev->id, ctx->str_index);
+
+ return ctx;
+}
+
+static int init_vpu_ctx_fh(struct vpu_ctx *ctx, struct vpu_dev *dev)
+{
+ if (!ctx || !dev)
+ return -EINVAL;
+
+ mutex_lock(&ctx->instance_mutex);
+
+ v4l2_fh_init(&ctx->fh, dev->pvpu_encoder_dev);
+ v4l2_fh_add(&ctx->fh);
+ ctx->fh.ctrl_handler = &ctx->ctrl_handler;
+ clear_bit(VPU_ENC_STATUS_CLOSED, &ctx->status);
+
+ mutex_unlock(&ctx->instance_mutex);
+
+ return 0;
+}
+
+static void uninit_vpu_ctx_fh(struct vpu_ctx *ctx)
+{
+ if (!ctx)
+ return;
+
+ mutex_lock(&ctx->instance_mutex);
+
+ set_bit(VPU_ENC_STATUS_CLOSED, &ctx->status);
+ v4l2_fh_del(&ctx->fh);
+ v4l2_fh_exit(&ctx->fh);
+
+ mutex_unlock(&ctx->instance_mutex);
+}
+
+static void cancel_vpu_ctx(struct vpu_ctx *ctx)
+{
+ cancel_work_sync(&ctx->instance_work);
+ cleanup_ctx_msg_queue(ctx);
+}
+
+static void uninit_vpu_ctx(struct vpu_ctx *ctx)
+{
+ if (!ctx)
+ return;
+
+ clear_bit(VPU_ENC_STATUS_INITIALIZED, &ctx->status);
+ cancel_vpu_ctx(ctx);
+ if (ctx->instance_wq) {
+ destroy_workqueue(ctx->instance_wq);
+ ctx->instance_wq = NULL;
+ }
+ mutex_lock(&ctx->instance_mutex);
+ vpu_enc_free_stream(ctx);
+
+ ctx->ctx_released = true;
+ mutex_unlock(&ctx->instance_mutex);
+}
+
+static int init_vpu_ctx(struct vpu_ctx *ctx)
+{
+ INIT_WORK(&ctx->instance_work, vpu_enc_msg_instance_work);
+ ctx->instance_wq = alloc_workqueue("vpu_instance",
+ WQ_UNBOUND | WQ_MEM_RECLAIM, 1);
+ if (!ctx->instance_wq) {
+ vpu_err("error: unable to alloc workqueue for ctx\n");
+ return -ENOMEM;
+ }
+
+ init_ctx_msg_queue(ctx);
+
+ vpu_enc_init_queue_data(ctx);
+ init_completion(&ctx->stop_cmp);
+
+ set_bit(VPU_ENC_STATUS_INITIALIZED, &ctx->status);
+ ctx->core_dev->ctx[ctx->str_index] = ctx;
+
+ return 0;
+}
+
+static int show_encoder_param(struct vpu_attr *attr,
+ pMEDIAIP_ENC_PARAM param, char *buf, u32 size)
+{
+ int num = 0;
+
+ num += scnprintf(buf + num, size - num,
+ "encoder param:[setting/take effect]\n");
+ num += scnprintf(buf + num, size - num,
+ "\t%-18s:%10d;%10d\n", "Codec Mode",
+ attr->param.eCodecMode, param->eCodecMode);
+ num += scnprintf(buf + num, size - num,
+ "\t%-18s:%10d;%10d\n", "Profile",
+ attr->param.eProfile, param->eProfile);
+ num += scnprintf(buf + num, size - num,
+ "\t%-18s:%10d;%10d\n", "Level",
+ attr->param.uLevel, param->uLevel);
+ num += scnprintf(buf + num, size - num,
+ "\t%-18s:%10d;%10d\n", "Frame Rate",
+ attr->param.uFrameRate, param->uFrameRate);
+ num += scnprintf(buf + num, size - num,
+ "\t%-18s:%10d;%10d\n", "Source Stride",
+ attr->param.uSrcStride, param->uSrcStride);
+ num += scnprintf(buf + num, size - num,
+ "\t%-18s:%10d;%10d\n", "Source Width",
+ attr->param.uSrcWidth, param->uSrcWidth);
+ num += scnprintf(buf + num, size - num,
+ "\t%-18s:%10d;%10d\n", "Source Height",
+ attr->param.uSrcHeight, param->uSrcHeight);
+ num += scnprintf(buf + num, size - num,
+ "\t%-18s:%10d;%10d\n", "Source Offset x",
+ attr->param.uSrcOffset_x, param->uSrcOffset_x);
+ num += scnprintf(buf + num, size - num,
+ "\t%-18s:%10d;%10d\n", "Source Offset y",
+ attr->param.uSrcOffset_y, param->uSrcOffset_y);
+ num += scnprintf(buf + num, size - num,
+ "\t%-18s:%10d;%10d\n", "Source Crop Width",
+ attr->param.uSrcCropWidth, param->uSrcCropWidth);
+ num += scnprintf(buf + num, size - num,
+ "\t%-18s:%10d;%10d\n", "Source Crop Height",
+ attr->param.uSrcCropHeight,
+ param->uSrcCropHeight);
+ num += scnprintf(buf + num, size - num,
+ "\t%-18s:%10d;%10d\n", "Out Width",
+ attr->param.uOutWidth, param->uOutWidth);
+ num += scnprintf(buf + num, size - num,
+ "\t%-18s:%10d;%10d\n", "Out Height",
+ attr->param.uOutHeight, param->uOutHeight);
+ num += scnprintf(buf + num, size - num,
+ "\t%-18s:%10d;%10d\n", "I Frame Interval",
+ attr->param.uIFrameInterval,
+ param->uIFrameInterval);
+ num += scnprintf(buf + num, size - num,
+ "\t%-18s:%10d;%10d\n", "Bframes",
+ attr->param.uGopBLength, param->uGopBLength);
+ num += scnprintf(buf + num, size - num,
+ "\t%-18s:%10d;%10d\n", "Low Latency Mode",
+ attr->param.uLowLatencyMode,
+ param->uLowLatencyMode);
+ num += scnprintf(buf + num, size - num,
+ "\t%-18s:%10d;%10d\n", "Bitrate Mode",
+ attr->param.eBitRateMode, param->eBitRateMode);
+ num += scnprintf(buf + num, size - num,
+ "\t%-18s:%10d;%10d\n", "Target Bitrate",
+ attr->param.uTargetBitrate,
+ param->uTargetBitrate);
+ num += scnprintf(buf + num, size - num,
+ "\t%-18s:%10d;%10d\n", "Min Bitrate",
+ attr->param.uMinBitRate, param->uMinBitRate);
+ num += scnprintf(buf + num, size - num,
+ "\t%-18s:%10d;%10d\n", "Max Bitrate",
+ attr->param.uMaxBitRate, param->uMaxBitRate);
+ num += scnprintf(buf + num, size - num,
+ "\t%-18s:%10d;%10d\n", "QP",
+ attr->param.uInitSliceQP,
+ param->uInitSliceQP);
+
+ return num;
+}
+
+static int show_queue_buffer_info(struct queue_data *queue, char *buf, u32 size)
+{
+ int i;
+ int num = 0;
+
+ for (i = 0; i < queue->vb2_q.num_buffers; i++) {
+ struct vb2_buffer *vb = queue->vb2_q.bufs[i];
+
+ num += scnprintf(buf + num, size - num, " %d", vb->state);
+ }
+
+ return num;
+}
+
+static int show_cmd_event(struct vpu_statistic *statistic, int i,
+ char *buf, u32 size)
+{
+ int num = 0;
+
+ num += scnprintf(buf + num, PAGE_SIZE - num, "\t(%2d) ", i);
+
+ if (i <= GTB_ENC_CMD_RESERVED)
+ num += scnprintf(buf + num, PAGE_SIZE - num, "%-28s:%12ld;",
+ get_cmd_str(i), statistic->cmd[i]);
+ else
+ num += scnprintf(buf + num, PAGE_SIZE - num, "%-28s:%12s;",
+ "", "");
+
+ num += scnprintf(buf + num, PAGE_SIZE - num, " ");
+ if (i <= VID_API_ENC_EVENT_RESERVED)
+ num += scnprintf(buf + num, PAGE_SIZE - num, "%-34s:%12ld;",
+ get_event_str(i), statistic->event[i]);
+
+ num += scnprintf(buf + num, PAGE_SIZE - num, "\n");
+
+ return num;
+}
+
+static int show_cmd_event_infos(struct vpu_statistic *statistic,
+ char *buf, u32 size)
+{
+ int num = 0;
+ int i;
+ int count;
+
+ num += scnprintf(buf + num, size - num, "command/event:\n");
+
+ count = max(GTB_ENC_CMD_RESERVED, VID_API_ENC_EVENT_RESERVED);
+ for (i = 0; i <= count; i++)
+ num += show_cmd_event(statistic, i, buf + num, size - num);
+
+ num += scnprintf(buf + num, size - num, "current status:\n");
+ num += scnprintf(buf + num, size - num,
+ "\t%-10s:%36s;%10ld.%06ld\n", "commond",
+ get_cmd_str(statistic->current_cmd),
+ statistic->ts_cmd.tv_sec,
+ statistic->ts_cmd.tv_nsec / 1000);
+ num += scnprintf(buf + num, size - num,
+ "\t%-10s:%36s;%10ld.%06ld\n", "event",
+ get_event_str(statistic->current_event),
+ statistic->ts_event.tv_sec,
+ statistic->ts_event.tv_nsec / 1000);
+
+ return num;
+}
+
+static int show_single_fps_info(struct vpu_fps_sts *fps, char *buf, u32 size)
+{
+ const u32 COEF = VPU_FPS_COEF;
+ int num = 0;
+
+ num += scnprintf(buf + num, size - num, "%3ld.", fps->fps / COEF);
+ num += scnprintf(buf + num, size - num, "%02ld", fps->fps % COEF);
+ if (fps->thd)
+ num += scnprintf(buf + num, size - num, "(%ds)", fps->thd);
+ else
+ num += scnprintf(buf + num, size - num, "(avg)");
+
+ return num;
+}
+
+static int show_fps_info(struct vpu_fps_sts *fps, int count,
+ char *buf, u32 size)
+{
+ int i;
+ int num = 0;
+
+ for (i = 0; i < count; i++) {
+ if (i > 0)
+ num += scnprintf(buf + num, size - num, " ");
+ num += show_single_fps_info(&fps[i], buf + num, size - num);
+ }
+
+ return num;
+}
+
+static int show_frame_sts(struct vpu_statistic *statistic, char *buf, u32 size)
+{
+ int num = 0;
+
+ num += scnprintf(buf + num, size - num,
+ "frame count:\n");
+ num += scnprintf(buf + num, size - num, "\t%-24s:%ld\n",
+ "dbuf input yuv count", statistic->yuv_count);
+ num += scnprintf(buf + num, size - num, "\t%-24s:%ld\n",
+ "encode frame count", statistic->encoded_count);
+ num += scnprintf(buf + num, size - num, "\t%-24s:%ld\n",
+ "dqbuf output h264 count", statistic->h264_count);
+
+ num += scnprintf(buf + num, size - num, "\t%-24s:", "actual fps:");
+ num += show_fps_info(statistic->fps, ARRAY_SIZE(statistic->fps),
+ buf + num, PAGE_SIZE - num);
+ num += scnprintf(buf + num, size - num, "\n");
+ num += scnprintf(buf + num, size - num, "\t%-24s:%ld\n",
+ "timestamp overwrite", statistic->timestamp_overwrite);
+
+ return num;
+}
+
+static int show_strip_info(struct vpu_statistic *statistic, char *buf, u32 size)
+{
+ int num = 0;
+
+ num += scnprintf(buf + num, size - num,
+ "strip data frame count:\n");
+ num += scnprintf(buf + num, size - num,
+ "\t fw :%16ld (max : %ld; total : %ld)\n",
+ statistic->strip_sts.fw.count,
+ statistic->strip_sts.fw.max,
+ statistic->strip_sts.fw.total);
+ num += scnprintf(buf + num, size - num,
+ "\t begin :%16ld (max : %ld; total : %ld)\n",
+ statistic->strip_sts.begin.count,
+ statistic->strip_sts.begin.max,
+ statistic->strip_sts.begin.total);
+ num += scnprintf(buf + num, size - num,
+ "\t eos :%16ld (max : %ld; total : %ld)\n",
+ statistic->strip_sts.eos.count,
+ statistic->strip_sts.eos.max,
+ statistic->strip_sts.eos.total);
+
+ return num;
+}
+
+static int show_v4l2_buf_status(struct vpu_ctx *ctx, char *buf, u32 size)
+{
+ int num = 0;
+
+ num += scnprintf(buf + num, size - num, "V4L2 Buffer Status: ");
+ num += scnprintf(buf + num, PAGE_SIZE - num, "(");
+ num += scnprintf(buf + num, PAGE_SIZE - num,
+ " %d:dequeued,", VB2_BUF_STATE_DEQUEUED);
+ num += scnprintf(buf + num, PAGE_SIZE - num,
+ " %d:preparing,", VB2_BUF_STATE_PREPARING);
+ num += scnprintf(buf + num, PAGE_SIZE - num,
+ " %d:prepared,", VB2_BUF_STATE_PREPARED);
+ num += scnprintf(buf + num, PAGE_SIZE - num,
+ " %d:queued,", VB2_BUF_STATE_QUEUED);
+ num += scnprintf(buf + num, PAGE_SIZE - num,
+ " %d:requeueing,", VB2_BUF_STATE_REQUEUEING);
+ num += scnprintf(buf + num, PAGE_SIZE - num,
+ " %d:active,", VB2_BUF_STATE_ACTIVE);
+ num += scnprintf(buf + num, PAGE_SIZE - num,
+ " %d:done,", VB2_BUF_STATE_DONE);
+ num += scnprintf(buf + num, PAGE_SIZE - num,
+ " %d:error", VB2_BUF_STATE_ERROR);
+ num += scnprintf(buf + num, PAGE_SIZE - num, ")\n");
+ num += scnprintf(buf + num, size - num, "\tOUTPUT:");
+ num += show_queue_buffer_info(&ctx->q_data[V4L2_SRC],
+ buf + num,
+ size - num);
+ num += scnprintf(buf + num, size - num, " CAPTURE:");
+ num += show_queue_buffer_info(&ctx->q_data[V4L2_DST],
+ buf + num,
+ size - num);
+ num += scnprintf(buf + num, size - num, "\n");
+
+ return num;
+}
+
+static int show_instance_status(struct vpu_ctx *ctx, char *buf, u32 size)
+{
+ int num = 0;
+
+ num += scnprintf(buf + num, size - num, "instance status:\n");
+ num += scnprintf(buf + num, size - num,
+ "\t%-13s:0x%lx\n", "status", ctx->status);
+ num += scnprintf(buf + num, size - num,
+ "\t%-13s:%d\n", "frozen count", ctx->frozen_count);
+
+ return num;
+}
+
+static int show_instance_others(struct vpu_attr *attr, char *buf, u32 size)
+{
+ int num = 0;
+ struct vpu_ctx *ctx = NULL;
+ struct vpu_dev *vpudev = attr->core->vdev;
+
+ num += scnprintf(buf + num, size - num, "others:\n");
+ if (attr->ts_start[V4L2_SRC] && attr->ts_start[V4L2_DST]) {
+ unsigned long latency;
+
+ latency = attr->ts_start[V4L2_DST] - attr->ts_start[V4L2_SRC];
+ num += scnprintf(buf + num, size - num,
+ "\tlatency(ms) :%ld\n", latency);
+ }
+
+ num += scnprintf(buf + num, size - num,
+ "\ttotal dma size :%ld\n",
+ atomic64_read(&attr->total_dma_size));
+ num += scnprintf(buf + num, size - num,
+ "\ttotal event msg obj count :%ld\n",
+ attr->msg_count);
+ num += scnprintf(buf + num, size - num,
+ "\ttotal msg ext data count :%lld\n",
+ get_total_ext_data_number());
+
+ mutex_lock(&vpudev->dev_mutex);
+ ctx = get_vpu_attr_ctx(attr);
+ if (ctx) {
+ num += scnprintf(buf + num, size - num,
+ "\ttotal frame obj count :%ld\n",
+ atomic64_read(&ctx->q_data[V4L2_DST].frame_count));
+
+ if (test_bit(VPU_ENC_STATUS_HANG, &ctx->status))
+ num += scnprintf(buf + num, size - num, "<hang>\n");
+ } else {
+ num += scnprintf(buf + num, size - num,
+ "<instance has been released>\n");
+ }
+ mutex_unlock(&vpudev->dev_mutex);
+
+ return num;
+}
+
+static ssize_t show_instance_info(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct vpu_attr *vpu_attr;
+ struct vpu_dev *vpudev;
+ struct vpu_statistic *statistic;
+ struct vpu_ctx *ctx;
+ pMEDIAIP_ENC_PARAM param;
+ int num = 0;
+
+ vpu_attr = container_of(attr, struct vpu_attr, dev_attr);
+ vpudev = vpu_attr->core->vdev;
+
+ num += scnprintf(buf + num, PAGE_SIZE,
+ "pid: %d; tgid: %d\n", vpu_attr->pid, vpu_attr->tgid);
+
+ param = rpc_get_enc_param(&vpu_attr->core->shared_mem, vpu_attr->index);
+ num += show_encoder_param(vpu_attr, param, buf + num, PAGE_SIZE - num);
+
+ statistic = &vpu_attr->statistic;
+ num += show_cmd_event_infos(statistic, buf + num, PAGE_SIZE - num);
+ num += show_frame_sts(statistic, buf + num, PAGE_SIZE - num);
+ num += show_strip_info(statistic, buf + num, PAGE_SIZE - num);
+
+ mutex_lock(&vpudev->dev_mutex);
+ ctx = get_vpu_attr_ctx(vpu_attr);
+ if (ctx) {
+ num += show_v4l2_buf_status(ctx, buf + num, PAGE_SIZE - num);
+ num += show_instance_status(ctx, buf + num, PAGE_SIZE - num);
+ }
+ mutex_unlock(&vpudev->dev_mutex);
+
+ num += show_instance_others(vpu_attr, buf + num, PAGE_SIZE - num);
+
+ return num;
+}
+
+static ssize_t show_core_info(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct core_device *core = NULL;
+ char *fw = NULL;
+ int num = 0;
+
+ core = container_of(attr, struct core_device, core_attr);
+ fw = core->m0_p_fw_space_vir;
+
+ num += scnprintf(buf + num, PAGE_SIZE - num,
+ "core[%d] info:\n", core->id);
+ num += scnprintf(buf + num, PAGE_SIZE - num,
+ "vpu mu id : %d\n", core->vpu_mu_id);
+ num += scnprintf(buf + num, PAGE_SIZE - num,
+ "irq : %d\n", core->irq);
+ num += scnprintf(buf + num, PAGE_SIZE - num,
+ "reg mu mcu : 0x%08x 0x%08x\n",
+ core->reg_base, core->reg_size);
+ num += scnprintf(buf + num, PAGE_SIZE - num,
+ "reg csr : 0x%08x 0x%08x\n",
+ core->reg_csr_base, core->reg_csr_size);
+ num += scnprintf(buf + num, PAGE_SIZE - num,
+ "fw space phy : 0x%08x\n", core->m0_p_fw_space_phy);
+ num += scnprintf(buf + num, PAGE_SIZE - num,
+ "fw space size : 0x%08x\n", core->fw_buf_size);
+ num += scnprintf(buf + num, PAGE_SIZE - num,
+ "fw actual size : 0x%08x\n", core->fw_actual_size);
+ num += scnprintf(buf + num, PAGE_SIZE - num,
+ "rpc phy : 0x%08x\n", core->m0_rpc_phy);
+ num += scnprintf(buf + num, PAGE_SIZE - num,
+ "rpc buf size : 0x%08x\n", core->rpc_buf_size);
+ num += scnprintf(buf + num, PAGE_SIZE - num,
+ "rpc actual size : 0x%08x\n", core->rpc_actual_size);
+ num += scnprintf(buf + num, PAGE_SIZE - num,
+ "print buf phy : 0x%08x\n",
+ core->m0_rpc_phy + core->rpc_buf_size);
+ num += scnprintf(buf + num, PAGE_SIZE - num,
+ "print buf size : 0x%08x\n", core->print_buf_size);
+ num += scnprintf(buf + num, PAGE_SIZE - num,
+ "max instance num: %d\n",
+ core->supported_instance_count);
+ num += scnprintf(buf + num, PAGE_SIZE - num,
+ "fw_is_ready : %d\n", core->fw_is_ready);
+ num += scnprintf(buf + num, PAGE_SIZE - num,
+ "firmware_started: %d\n", core->firmware_started);
+ num += scnprintf(buf + num, PAGE_SIZE - num,
+ "hang : %d\n", core->hang);
+ num += scnprintf(buf + num, PAGE_SIZE - num,
+ "reset times : %ld\n", core->reset_times);
+ num += scnprintf(buf + num, PAGE_SIZE - num,
+ "heartbeat : %02x\n", core->vdev->heartbeat);
+ if (core->fw_is_ready) {
+ pENC_RPC_HOST_IFACE iface = core->shared_mem.pSharedInterface;
+
+ num += scnprintf(buf + num, PAGE_SIZE - num,
+ "firmware version: %d.%d.%d\n",
+ (iface->FWVersion & 0x00ff0000) >> 16,
+ (iface->FWVersion & 0x0000ff00) >> 8,
+ iface->FWVersion & 0x000000ff);
+ num += scnprintf(buf + num, PAGE_SIZE - num,
+ "fw info : 0x%02x 0x%02x\n", fw[16], fw[17]);
+ }
+ num += scnprintf(buf + num, PAGE_SIZE - num,
+ "driver version : %s\n", VPU_ENC_DRIVER_VERSION);
+
+ return num;
+}
+
+static int show_vb2_memory(struct vb2_buffer *vb, char *buf, u32 size)
+{
+ int num = 0;
+ int i;
+
+ for (i = 0; i < vb->num_planes; i++) {
+ num += scnprintf(buf + num, size - num, "0x%8x 0x%x",
+ get_vb2_plane_phy_addr(vb, i),
+ vb->planes[i].length);
+ if (i == vb->num_planes - 1)
+ num += scnprintf(buf + num, size - num, "\n");
+ else
+ num += scnprintf(buf + num, size - num, "; ");
+ }
+
+ return num;
+}
+
+static int show_queue_memory(struct queue_data *queue, char *buf, u32 size,
+ char *prefix)
+{
+ int num = 0;
+ int i;
+
+ num += scnprintf(buf + num, size - num, "%s%4s v4l2buf :\n", prefix,
+ queue->type == V4L2_SRC ? "YUV" : "H264");
+
+ for (i = 0; i < queue->vb2_q.num_buffers; i++) {
+ struct vb2_buffer *vb = queue->vb2_q.bufs[i];
+
+ num += scnprintf(buf + num, size - num, "%s%18s", prefix, "");
+ num += show_vb2_memory(vb, buf + num, size - num);
+ }
+
+ return num;
+}
+
+static int show_ctx_memory_details(struct vpu_ctx *ctx, char *buf, u32 size,
+ char *prefix)
+{
+ int num = 0;
+ int i;
+
+ if (!ctx)
+ return 0;
+
+ num += scnprintf(buf + num, size - num, "%smemory details:\n", prefix);
+ num += scnprintf(buf + num, size - num, "%sencFrames :\n", prefix);
+ for (i = 0; i < MEDIAIP_MAX_NUM_WINDSOR_SRC_FRAMES; i++) {
+ num += scnprintf(buf + num, size - num, "%s%14s", prefix, "");
+ num += scnprintf(buf + num, size - num, "[%d] 0x%8llx 0x%x\n",
+ i,
+ ctx->encFrame[i].phy_addr,
+ ctx->encFrame[i].size);
+ }
+
+ num += scnprintf(buf + num, size - num, "%srefFrames :\n", prefix);
+ for (i = 0; i < MEDIAIP_MAX_NUM_WINDSOR_REF_FRAMES; i++) {
+ num += scnprintf(buf + num, size - num, "%s%14s", prefix, "");
+ num += scnprintf(buf + num, size - num, "[%d] 0x%8llx 0x%x\n",
+ i,
+ ctx->refFrame[i].phy_addr,
+ ctx->refFrame[i].size);
+ }
+
+ num += scnprintf(buf + num, size - num, "%sactFrames :\n", prefix);
+ num += scnprintf(buf + num, size - num, "%s%18s", prefix, "");
+ num += scnprintf(buf + num, size - num, "0x%8llx 0x%x\n",
+ ctx->actFrame.phy_addr, ctx->actFrame.size);
+
+ num += scnprintf(buf + num, size - num, "%sencoderStream:\n", prefix);
+ num += scnprintf(buf + num, size - num, "%s%18s", prefix, "");
+ num += scnprintf(buf + num, size - num, "0x%8llx 0x%x\n",
+ ctx->encoder_stream.phy_addr, ctx->encoder_stream.size);
+
+ for (i = 0; i < ARRAY_SIZE(ctx->q_data); i++) {
+ struct queue_data *queue = &ctx->q_data[i];
+
+ if (queue->vb2_q.memory != V4L2_MEMORY_MMAP)
+ continue;
+ if (queue->vb2_q.mem_ops != &vb2_dma_contig_memops)
+ continue;
+
+ num += show_queue_memory(queue, buf + num, size - num, prefix);
+ }
+
+ return num;
+}
+
+static ssize_t show_memory_info(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct vpu_dev *vdev = dev_get_drvdata(dev);
+ unsigned long total_dma_size = 0;
+ int num = 0;
+ int i;
+ int j;
+ int core_id = (show_detail_index >> 8) & 0xff;
+ int ctx_id = show_detail_index & 0xff;
+
+ num += scnprintf(buf + num, PAGE_SIZE - num, "dma memory usage:\n");
+ for (i = 0; i < vdev->core_num; i++) {
+ struct core_device *core = &vdev->core_dev[i];
+
+ num += scnprintf(buf + num, PAGE_SIZE - num, "core[%d]\n", i);
+
+ for (j = 0; j < ARRAY_SIZE(core->attr); j++) {
+ struct vpu_attr *attr = &core->attr[j];
+ unsigned long size;
+
+ size = atomic64_read(&attr->total_dma_size);
+ total_dma_size += size;
+ num += scnprintf(buf + num, PAGE_SIZE - num,
+ "\t[%d] : %ld\n", j, size);
+ if (core_id != i || ctx_id != j)
+ continue;
+ mutex_lock(&vdev->dev_mutex);
+ num += show_ctx_memory_details(core->ctx[j],
+ buf + num,
+ PAGE_SIZE - num,
+ "\t\t");
+ mutex_unlock(&vdev->dev_mutex);
+ }
+ }
+
+ num += scnprintf(buf + num, PAGE_SIZE - num,
+ "total dma : %ld\n", total_dma_size);
+ num += scnprintf(buf + num, PAGE_SIZE - num,
+ "total reserved memory : %ld\n",
+ vdev->reserved_mem.bytesused);
+ show_detail_index = VPU_DETAIL_INDEX_DFT;
+
+ return num;
+}
+
+static ssize_t store_memory_info_index(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ long val = VPU_DETAIL_INDEX_DFT;
+
+ if (!kstrtol(buf, 0, &val))
+ show_detail_index = val;
+
+ return count;
+}
+DEVICE_ATTR(meminfo, 0664, show_memory_info, store_memory_info_index);
+
+static ssize_t show_buffer_info(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct vpu_dev *vdev = dev_get_drvdata(dev);
+ int num = 0;
+ int i;
+ int j;
+
+ mutex_lock(&vdev->dev_mutex);
+ num += scnprintf(buf + num, PAGE_SIZE - num, "vpu encoder buffers:\t");
+ num += scnprintf(buf + num, PAGE_SIZE - num, "(");
+ num += scnprintf(buf + num, PAGE_SIZE - num,
+ " %d:dequeued,", VB2_BUF_STATE_DEQUEUED);
+ num += scnprintf(buf + num, PAGE_SIZE - num,
+ " %d:preparing,", VB2_BUF_STATE_PREPARING);
+ num += scnprintf(buf + num, PAGE_SIZE - num,
+ " %d:prepared,", VB2_BUF_STATE_PREPARED);
+ num += scnprintf(buf + num, PAGE_SIZE - num,
+ " %d:queued,", VB2_BUF_STATE_QUEUED);
+ num += scnprintf(buf + num, PAGE_SIZE - num,
+ " %d:requeueing,", VB2_BUF_STATE_REQUEUEING);
+ num += scnprintf(buf + num, PAGE_SIZE - num,
+ " %d:active,", VB2_BUF_STATE_ACTIVE);
+ num += scnprintf(buf + num, PAGE_SIZE - num,
+ " %d:done,", VB2_BUF_STATE_DONE);
+ num += scnprintf(buf + num, PAGE_SIZE - num,
+ " %d:error", VB2_BUF_STATE_ERROR);
+ num += scnprintf(buf + num, PAGE_SIZE - num, ")\n");
+
+ for (i = 0; i < vdev->core_num; i++) {
+ struct core_device *core = &vdev->core_dev[i];
+
+ if (!core->supported_instance_count)
+ continue;
+
+ num += scnprintf(buf + num, PAGE_SIZE - num, "core[%d]\n", i);
+ for (j = 0; j < core->supported_instance_count; j++) {
+ struct vpu_ctx *ctx = core->ctx[j];
+
+ if (!ctx)
+ continue;
+ num += scnprintf(buf + num, PAGE_SIZE - num,
+ "\t[%d]: ", j);
+ num += scnprintf(buf + num,
+ PAGE_SIZE - num, "OUTPUT:");
+ num += show_queue_buffer_info(&ctx->q_data[V4L2_SRC],
+ buf + num,
+ PAGE_SIZE - num);
+ num += scnprintf(buf + num,
+ PAGE_SIZE - num, " CAPTURE:");
+ num += show_queue_buffer_info(&ctx->q_data[V4L2_DST],
+ buf + num,
+ PAGE_SIZE - num);
+ num += scnprintf(buf + num, PAGE_SIZE - num, "\n");
+ }
+ }
+ mutex_unlock(&vdev->dev_mutex);
+
+ return num;
+}
+DEVICE_ATTR(buffer, 0444, show_buffer_info, NULL);
+
+static ssize_t show_fpsinfo(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct vpu_dev *vdev = dev_get_drvdata(dev);
+ int num = 0;
+ int i;
+ int j;
+
+ for (i = 0; i < vdev->core_num; i++) {
+ struct core_device *core = &vdev->core_dev[i];
+
+ if (!core->supported_instance_count)
+ continue;
+
+ num += scnprintf(buf + num, PAGE_SIZE - num, "core[%d]\n", i);
+ for (j = 0; j < core->supported_instance_count; j++) {
+ struct vpu_attr *attr = &core->attr[j];
+
+ if (!attr->created)
+ continue;
+ num += scnprintf(buf + num, PAGE_SIZE - num,
+ "\t[%d]", j);
+ num += scnprintf(buf + num, PAGE_SIZE - num,
+ " %3d(setting) ",
+ attr->param.uFrameRate);
+ num += show_fps_info(attr->statistic.fps,
+ ARRAY_SIZE(attr->statistic.fps),
+ buf + num, PAGE_SIZE - num);
+ num += scnprintf(buf + num, PAGE_SIZE - num, "\n");
+ }
+ }
+
+ return num;
+}
+DEVICE_ATTR(fpsinfo, 0444, show_fpsinfo, NULL);
+
+static ssize_t show_vpuinfo(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct vpu_dev *vdev = dev_get_drvdata(dev);
+ int num = 0;
+
+ num += scnprintf(buf + num, PAGE_SIZE - num,
+ "core number : %d\n", vdev->core_num);
+ num += scnprintf(buf + num, PAGE_SIZE - num,
+ "platform type : %d\n", vdev->plat_type);
+ num += scnprintf(buf + num, PAGE_SIZE - num,
+ "reg-vpu : 0x%8x 0x%08x\n",
+ vdev->reg_vpu_base, vdev->reg_vpu_size);
+ num += scnprintf(buf + num, PAGE_SIZE - num,
+ "reg-rpc-system : 0x%08x\n",
+ vdev->reg_rpc_system);
+ num += scnprintf(buf + num, PAGE_SIZE - num,
+ "reserved-memory : 0x%08lx 0x%08lx\n",
+ vdev->reserved_mem.phy_addr, vdev->reserved_mem.size);
+ num += scnprintf(buf + num, PAGE_SIZE - num, "supported resolution :");
+ num += scnprintf(buf + num, PAGE_SIZE - num, " %dx%d(min);",
+ vdev->supported_size.min_width,
+ vdev->supported_size.min_height);
+ num += scnprintf(buf + num, PAGE_SIZE - num, " %dx%d(step);",
+ vdev->supported_size.step_width,
+ vdev->supported_size.step_height);
+ num += scnprintf(buf + num, PAGE_SIZE - num, " %dx%d(max)\n",
+ vdev->supported_size.max_width,
+ vdev->supported_size.max_height);
+ num += scnprintf(buf + num, PAGE_SIZE - num,
+ "supported frame rate : %d(min); %d(step); %d(max)\n",
+ vdev->supported_fps.min,
+ vdev->supported_fps.step,
+ vdev->supported_fps.max);
+
+ return num;
+}
+DEVICE_ATTR(vpuinfo, 0444, show_vpuinfo, NULL);
+
+static void reset_statistic(struct vpu_attr *attr)
+{
+ if (!attr)
+ return;
+
+ memset(&attr->statistic, 0, sizeof(attr->statistic));
+ attr->statistic.current_cmd = GTB_ENC_CMD_NOOP;
+ attr->statistic.current_event = VID_API_EVENT_UNDEFINED;
+}
+
+static int init_vpu_attr_fps_sts(struct vpu_attr *attr)
+{
+ const unsigned int THDS[] = VPU_FPS_STS_THDS;
+ int i;
+
+ for (i = 0; i < VPU_FPS_STS_CNT; i++) {
+ if (i < ARRAY_SIZE(THDS))
+ attr->statistic.fps[i].thd = THDS[i];
+ else
+ attr->statistic.fps[i].thd = 0;
+ }
+
+ return 0;
+}
+
+static int enable_fps_sts(struct vpu_attr *attr)
+{
+ int i;
+ struct vpu_statistic *sts = &attr->statistic;
+
+ sts->fps_sts_enable = true;
+
+ for (i = 0; i < VPU_FPS_STS_CNT; i++) {
+ getrawmonotonic(&sts->fps[i].ts);
+ sts->fps[i].frame_number = sts->encoded_count;
+ }
+
+ return 0;
+}
+
+static int disable_fps_sts(struct vpu_attr *attr)
+{
+ attr->statistic.fps_sts_enable = false;
+
+ return 0;
+}
+
+static int init_vpu_attr(struct vpu_attr *attr)
+{
+ if (!attr || !attr->core)
+ return -EINVAL;
+
+ reset_statistic(attr);
+ memset(&attr->param, 0, sizeof(attr->param));
+ attr->pid = current->pid;
+ attr->tgid = current->tgid;
+ if (!attr->created) {
+ device_create_file(attr->core->generic_dev, &attr->dev_attr);
+ attr->created = true;
+ }
+
+ init_vpu_attr_fps_sts(attr);
+
+ return 0;
+}
+
+static int release_instance(struct vpu_ctx *ctx)
+{
+ struct vpu_dev *dev;
+
+ if (!ctx || !ctx->dev)
+ return -EINVAL;
+
+ if (!test_bit(VPU_ENC_STATUS_CLOSED, &ctx->status))
+ return 0;
+ if (!test_bit(VPU_ENC_STATUS_FORCE_RELEASE, &ctx->status)) {
+ if (test_bit(VPU_ENC_STATUS_START_SEND, &ctx->status) &&
+ !test_bit(VPU_ENC_STATUS_STOP_DONE, &ctx->status))
+ return -EINVAL;
+ }
+
+ dev = ctx->dev;
+
+ uninit_vpu_ctx(ctx);
+ vpu_enc_free_ctrls(ctx);
+ vpu_enc_release_queue_data(ctx);
+ vpu_enc_free_mem(ctx, get_rpc_mem_pool(ctx));
+
+ vpu_ctx_power_off(ctx);
+ free_instance(ctx);
+
+ return 0;
+}
+
+static int try_to_release_idle_instance(struct vpu_dev *dev)
+{
+ int i;
+ int j;
+
+ if (!dev)
+ return -EINVAL;
+
+ for (i = 0; i < dev->core_num; i++) {
+ if (dev->core_dev[i].hang)
+ set_core_force_release(&dev->core_dev[i]);
+ for (j = 0; j < dev->core_dev[i].supported_instance_count; j++)
+ release_instance(dev->core_dev[i].ctx[j]);
+ }
+
+ return 0;
+}
+
+struct vpu_attr *get_vpu_ctx_attr(struct vpu_ctx *ctx)
+{
+ WARN_ON(!ctx || !ctx->core_dev);
+
+ if (ctx->str_index >= ctx->core_dev->supported_instance_count)
+ return NULL;
+
+ return &ctx->core_dev->attr[ctx->str_index];
+}
+
+struct vpu_ctx *get_vpu_attr_ctx(struct vpu_attr *attr)
+{
+ WARN_ON(!attr || !attr->core);
+
+ if (attr->index >= attr->core->supported_instance_count)
+ return NULL;
+
+ return attr->core->ctx[attr->index];
+}
+
+static int vpu_enc_v4l2_open(struct file *filp)
+{
+ struct video_device *vdev = video_devdata(filp);
+ struct vpu_dev *dev = video_get_drvdata(vdev);
+ struct vpu_ctx *ctx = NULL;
+ int ret;
+
+ vpu_log_func();
+
+ mutex_lock(&dev->dev_mutex);
+ try_to_release_idle_instance(dev);
+
+ pm_runtime_get_sync(dev->generic_dev);
+ ctx = create_and_request_instance(dev);
+ pm_runtime_put_sync(dev->generic_dev);
+ if (!ctx) {
+ mutex_unlock(&dev->dev_mutex);
+ vpu_err("failed to create encoder ctx\n");
+ return -ENOMEM;
+ }
+
+ init_vpu_attr(get_vpu_ctx_attr(ctx));
+ ret = init_vpu_ctx(ctx);
+ if (ret) {
+ mutex_unlock(&dev->dev_mutex);
+ vpu_err("init vpu ctx fail\n");
+ goto error;
+ }
+
+ initialize_enc_param(ctx);
+ vpu_enc_setup_ctrls(ctx);
+
+ init_vpu_ctx_fh(ctx, dev);
+ init_ctx_seq_info(ctx);
+ filp->private_data = &ctx->fh;
+ mutex_unlock(&dev->dev_mutex);
+
+ return 0;
+error:
+ mutex_lock(&dev->dev_mutex);
+ set_bit(VPU_ENC_STATUS_FORCE_RELEASE, &ctx->status);
+ VPU_SAFE_RELEASE(ctx, release_instance);
+ mutex_unlock(&dev->dev_mutex);
+ return ret;
+}
+
+static int vpu_enc_v4l2_release(struct file *filp)
+{
+ struct vpu_ctx *ctx = v4l2_fh_to_ctx(filp->private_data);
+ struct vpu_dev *dev = ctx->dev;
+
+ vpu_log_func();
+
+ request_eos(ctx);
+ wait_for_stop_done(ctx);
+
+ mutex_lock(&dev->dev_mutex);
+
+ uninit_vpu_ctx_fh(ctx);
+ filp->private_data = NULL;
+
+ VPU_SAFE_RELEASE(ctx, release_instance);
+ mutex_unlock(&dev->dev_mutex);
+
+ return 0;
+}
+
+static unsigned int vpu_enc_v4l2_poll(struct file *filp, poll_table *wait)
+{
+ struct vpu_ctx *ctx = v4l2_fh_to_ctx(filp->private_data);
+ struct vb2_queue *src_q, *dst_q;
+ unsigned int rc = 0;
+
+ vpu_dbg(LVL_FUNC, "%s(), event: 0x%lx\n", __func__,
+ poll_requested_events(wait));
+
+ poll_wait(filp, &ctx->fh.wait, wait);
+
+ if (v4l2_event_pending(&ctx->fh)) {
+ vpu_dbg(LVL_DEBUG, "%s() v4l2_event_pending\n", __func__);
+ rc |= POLLPRI;
+ }
+
+ src_q = &ctx->q_data[V4L2_SRC].vb2_q;
+ dst_q = &ctx->q_data[V4L2_DST].vb2_q;
+
+ if ((!src_q->streaming || list_empty(&src_q->queued_list))
+ && (!dst_q->streaming || list_empty(&dst_q->queued_list))) {
+ rc |= POLLERR;
+ return rc;
+ }
+
+ poll_wait(filp, &src_q->done_wq, wait);
+ if (!list_empty(&src_q->done_list))
+ rc |= POLLOUT | POLLWRNORM;
+ poll_wait(filp, &dst_q->done_wq, wait);
+ if (!list_empty(&dst_q->done_list))
+ rc |= POLLIN | POLLRDNORM;
+
+ return rc;
+}
+
+static int vpu_enc_v4l2_mmap(struct file *filp, struct vm_area_struct *vma)
+{
+ long ret = -EPERM;
+ unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
+ struct queue_data *q_data;
+ enum QUEUE_TYPE type;
+
+ struct vpu_ctx *ctx = v4l2_fh_to_ctx(filp->private_data);
+
+ vpu_log_func();
+
+ if (ctx) {
+ type = offset >> MMAP_BUF_TYPE_SHIFT;
+ q_data = &ctx->q_data[type];
+
+ offset &= ~MMAP_BUF_TYPE_MASK;
+ offset = offset >> PAGE_SHIFT;
+ vma->vm_pgoff = offset;
+ ret = vpu_enc_queue_mmap(q_data, vma);
+ }
+
+ return ret;
+}
+
+static const struct v4l2_file_operations vpu_enc_v4l2_fops = {
+ .owner = THIS_MODULE,
+ .open = vpu_enc_v4l2_open,
+ .unlocked_ioctl = video_ioctl2,
+ .release = vpu_enc_v4l2_release,
+ .poll = vpu_enc_v4l2_poll,
+ .mmap = vpu_enc_v4l2_mmap,
+};
+
+static struct video_device vpu_enc_v4l2_videodevice = {
+ .name = "vpu encoder",
+ .fops = &vpu_enc_v4l2_fops,
+ .ioctl_ops = &vpu_enc_v4l2_ioctl_ops,
+ .vfl_dir = VFL_DIR_M2M,
+};
+
+static void vpu_enc_setup(struct vpu_dev *This)
+{
+ const off_t offset = SCB_XREG_SLV_BASE + SCB_SCB_BLK_CTRL;
+ uint32_t read_data = 0;
+
+ vpu_log_func();
+
+ write_vpu_reg(This, 0x1, offset + SCB_BLK_CTRL_SCB_CLK_ENABLE_SET);
+ write_vpu_reg(This, 0xffffffff, 0x70190);
+ write_vpu_reg(This, 0xffffffff, offset + SCB_BLK_CTRL_XMEM_RESET_SET);
+ write_vpu_reg(This, 0xE, offset + SCB_BLK_CTRL_SCB_CLK_ENABLE_SET);
+ write_vpu_reg(This, 0x7, offset + SCB_BLK_CTRL_CACHE_RESET_SET);
+ write_vpu_reg(This, 0x102, XMEM_CONTROL);
+
+ read_data = read_vpu_reg(This, 0x70108);
+ vpu_dbg(LVL_IRQ, "%s read_data=%x\n", __func__, read_data);
+}
+
+static void vpu_enc_reset(struct vpu_dev *This)
+{
+ const off_t offset = SCB_XREG_SLV_BASE + SCB_SCB_BLK_CTRL;
+
+ vpu_log_func();
+ write_vpu_reg(This, 0x7, offset + SCB_BLK_CTRL_CACHE_RESET_CLR);
+}
+
+static int vpu_enc_enable_hw(struct vpu_dev *This)
+{
+ vpu_log_func();
+ vpu_enc_setup(This);
+
+ This->hw_enable = true;
+
+ return 0;
+}
+
+static void vpu_enc_disable_hw(struct vpu_dev *This)
+{
+ This->hw_enable = false;
+ vpu_enc_reset(This);
+ if (This->regs_base) {
+ iounmap(This->regs_base);
+ This->regs_base = NULL;
+ }
+}
+
+static int parse_core_info(struct core_device *core, struct device_node *np)
+{
+ int ret;
+ u32 val;
+
+ WARN_ON(!core || !np);
+
+ ret = of_property_read_u32_index(np, "reg", 0, &val);
+ if (ret) {
+ vpu_err("find reg for core[%d] fail\n", core->id);
+ return ret;
+ }
+ core->reg_base = val;
+
+ ret = of_property_read_u32_index(np, "reg", 1, &val);
+ if (ret) {
+ vpu_err("find reg for core[%d] fail\n", core->id);
+ return ret;
+ }
+ core->reg_size = val;
+
+ ret = of_property_read_u32_index(np, "reg-csr", 0, &val);
+ if (ret) {
+ vpu_err("find reg-csr for core[%d] fail\n", core->id);
+ return ret;
+ }
+ core->reg_csr_base = val;
+
+ ret = of_property_read_u32_index(np, "reg-csr", 1, &val);
+ if (ret) {
+ vpu_err("find reg-csr for core[%d] fail\n", core->id);
+ return ret;
+ }
+ core->reg_csr_size = val;
+
+ ret = of_irq_get(np, 0);
+ if (ret < 0) {
+ vpu_err("get irq for core[%d] fail\n", core->id);
+ return -EINVAL;
+ }
+ core->irq = ret;
+
+ ret = of_property_read_u32(np, "fsl,vpu_ap_mu_id", &val);
+ if (!ret)
+ core->vpu_mu_id = val;
+
+ ret = of_property_read_u32(np, "fw-buf-size", &val);
+ if (ret) {
+ vpu_err("find fw-buf-size for core[%d] fail\n", core->id);
+ core->fw_buf_size = M0_BOOT_SIZE_DEFAULT;
+ } else {
+ core->fw_buf_size = val;
+ }
+ core->fw_buf_size = max_t(u32, core->fw_buf_size, M0_BOOT_SIZE_MIN);
+
+ ret = of_property_read_u32(np, "rpc-buf-size", &val);
+ if (ret) {
+ vpu_err("find rpc-buf-size for core[%d] fail\n", core->id);
+ core->rpc_buf_size = RPC_SIZE_DEFAULT;
+ } else {
+ core->rpc_buf_size = val;
+ }
+ core->rpc_buf_size = max_t(u32, core->rpc_buf_size, RPC_SIZE_MIN);
+
+ ret = of_property_read_u32(np, "print-buf-size", &val);
+ if (ret) {
+ vpu_err("find print-buf-size for core[%d] fail\n", core->id);
+ core->print_buf_size = PRINT_SIZE_DEFAULT;
+ } else {
+ core->print_buf_size = val;
+ }
+ core->print_buf_size = max_t(u32, core->print_buf_size, PRINT_SIZE_MIN);
+
+ return 0;
+}
+
+static int parse_dt_cores(struct vpu_dev *dev, struct device_node *np)
+{
+ char core_name[64];
+ struct device_node *node = NULL;
+ struct core_device *core = NULL;
+ int i;
+ int ret;
+
+ dev->core_num = 0;
+ for (i = 0; i < VPU_ENC_MAX_CORE_NUM; i++) {
+ scnprintf(core_name, sizeof(core_name), "core%d", i);
+ node = of_find_node_by_name(np, core_name);
+ if (!node) {
+ vpu_dbg(LVL_INFO, "can't find %s\n", core_name);
+ break;
+ }
+
+ core = &dev->core_dev[i];
+ core->id = i;
+ ret = parse_core_info(core, node);
+ of_node_put(node);
+ node = NULL;
+ if (ret) {
+ vpu_err("parse core[%d] fail\n", i);
+ break;
+ }
+ }
+ if (i == 0)
+ return -EINVAL;
+
+ dev->core_num = i;
+
+ return 0;
+}
+
+static int parse_dt_info(struct vpu_dev *dev, struct device_node *np)
+{
+ int ret;
+ struct device_node *reserved_node = NULL;
+ struct resource reserved_fw;
+ struct resource reserved_rpc;
+ struct resource reserved_mem;
+ u32 fw_total_size = 0;
+ u32 rpc_total_size = 0;
+ u32 val;
+ u32 i;
+
+ if (!dev || !np)
+ return -EINVAL;
+
+ ret = of_property_read_u32_index(np, "reg-rpc-system", 0, &val);
+ if (ret) {
+ vpu_err("get reg-rpc-system fail\n");
+ return -EINVAL;
+ }
+ dev->reg_rpc_system = val;
+
+ reserved_node = of_parse_phandle(np, "boot-region", 0);
+ if (!reserved_node) {
+ vpu_err("error: boot-region of_parse_phandle error\n");
+ return -ENODEV;
+ }
+ if (of_address_to_resource(reserved_node, 0, &reserved_fw)) {
+ vpu_err("error: boot-region of_address_to_resource error\n");
+ return -EINVAL;
+ }
+
+ reserved_node = of_parse_phandle(np, "rpc-region", 0);
+ if (!reserved_node) {
+ vpu_err("error: rpc-region of_parse_phandle error\n");
+ return -ENODEV;
+ }
+ if (of_address_to_resource(reserved_node, 0, &reserved_rpc)) {
+ vpu_err("error: rpc-region of_address_to_resource error\n");
+ return -EINVAL;
+ }
+
+ reserved_node = of_parse_phandle(np, "reserved-region", 0);
+ if (!reserved_node) {
+ vpu_err("error: rpc-region of_parse_phandle error\n");
+ return -ENODEV;
+ }
+ if (of_address_to_resource(reserved_node, 0, &reserved_mem)) {
+ vpu_err("error: rpc-region of_address_to_resource error\n");
+ return -EINVAL;
+ }
+ dev->reserved_mem.phy_addr = reserved_mem.start;
+ dev->reserved_mem.size = resource_size(&reserved_mem);
+
+ ret = parse_dt_cores(dev, np);
+ if (ret) {
+ vpu_err("parse cores from dt fail\n");
+ return ret;
+ }
+
+ fw_total_size = 0;
+ rpc_total_size = 0;
+ for (i = 0; i < dev->core_num; i++) {
+ struct core_device *core = &dev->core_dev[i];
+
+ core->m0_p_fw_space_phy = reserved_fw.start + fw_total_size;
+ core->m0_rpc_phy = reserved_rpc.start + rpc_total_size;
+ fw_total_size += core->fw_buf_size;
+ rpc_total_size += core->rpc_buf_size;
+ rpc_total_size += core->print_buf_size;
+ }
+
+ if (fw_total_size > resource_size(&reserved_fw)) {
+ vpu_err("boot-region's size(0x%llx) is less than wanted:0x%x\n",
+ resource_size(&reserved_fw), fw_total_size);
+ return -EINVAL;
+ }
+ if (rpc_total_size > resource_size(&reserved_rpc)) {
+ vpu_err("rpc-region's size(0x%llx) is less than wanted:0x%x\n",
+ resource_size(&reserved_rpc), rpc_total_size);
+ return -EINVAL;
+ }
+
+ dev->supported_size.min_width = VPU_ENC_WIDTH_MIN;
+ dev->supported_size.max_width = VPU_ENC_WIDTH_MAX;
+ dev->supported_size.step_width = VPU_ENC_WIDTH_STEP;
+ dev->supported_size.min_height = VPU_ENC_HEIGHT_MIN;
+ dev->supported_size.max_height = VPU_ENC_HEIGHT_MAX;
+ dev->supported_size.step_height = VPU_ENC_HEIGHT_STEP;
+
+ dev->supported_fps.min = VPU_ENC_FRAMERATE_MIN;
+ dev->supported_fps.max = VPU_ENC_FRAMERATE_MAX;
+ dev->supported_fps.step = VPU_ENC_FRAMERATE_STEP;
+
+ ret = of_property_read_u32_index(np, "resolution-max", 0, &val);
+ if (!ret)
+ dev->supported_size.max_width = val;
+
+ ret = of_property_read_u32_index(np, "resolution-max", 1, &val);
+ if (!ret)
+ dev->supported_size.max_height = val;
+
+ ret = of_property_read_u32_index(np, "fps-max", 0, &val);
+ if (!ret)
+ dev->supported_fps.max = val;
+
+ return 0;
+}
+
+static int create_vpu_video_device(struct vpu_dev *dev)
+{
+ int ret;
+
+ dev->pvpu_encoder_dev = video_device_alloc();
+ if (!dev->pvpu_encoder_dev) {
+ vpu_err("alloc vpu encoder video device fail\n");
+ return -ENOMEM;
+ }
+
+ strlcpy(dev->pvpu_encoder_dev->name,
+ vpu_enc_v4l2_videodevice.name,
+ sizeof(dev->pvpu_encoder_dev->name));
+ dev->pvpu_encoder_dev->fops = vpu_enc_v4l2_videodevice.fops;
+ dev->pvpu_encoder_dev->ioctl_ops = vpu_enc_v4l2_videodevice.ioctl_ops;
+ dev->pvpu_encoder_dev->release = video_device_release;
+ dev->pvpu_encoder_dev->vfl_dir = vpu_enc_v4l2_videodevice.vfl_dir;
+ dev->pvpu_encoder_dev->v4l2_dev = &dev->v4l2_dev;
+ video_set_drvdata(dev->pvpu_encoder_dev, dev);
+
+ ret = video_register_device(dev->pvpu_encoder_dev,
+ VFL_TYPE_GRABBER,
+ ENCODER_NODE_NUMBER);
+ if (ret) {
+ vpu_err("unable to register video encoder device\n");
+ video_device_release(dev->pvpu_encoder_dev);
+ dev->pvpu_encoder_dev = NULL;
+ return ret;
+ }
+
+ return 0;
+}
+
+static int init_vpu_attrs(struct core_device *core)
+{
+ int i;
+
+ WARN_ON(!core);
+
+ for (i = 0; i < ARRAY_SIZE(core->attr); i++) {
+ struct vpu_attr *attr = &core->attr[i];
+
+ attr->core = core;
+ attr->index = i;
+ scnprintf(attr->name, sizeof(attr->name) - 1, "instance.%d.%d",
+ core->id, attr->index);
+ sysfs_attr_init(&attr->dev_attr.attr);
+ attr->dev_attr.attr.name = attr->name;
+ attr->dev_attr.attr.mode = VERIFY_OCTAL_PERMISSIONS(0444);
+ attr->dev_attr.show = show_instance_info;
+
+ atomic64_set(&attr->total_dma_size, 0);
+
+ attr->created = false;
+ }
+
+ return 0;
+}
+
+static int release_vpu_attrs(struct core_device *core)
+{
+ int i;
+
+ WARN_ON(!core);
+
+ for (i = 0; i < ARRAY_SIZE(core->attr); i++) {
+ struct vpu_attr *attr = &core->attr[i];
+
+ if (!attr->created)
+ continue;
+ device_remove_file(attr->core->generic_dev, &attr->dev_attr);
+ }
+
+ return 0;
+}
+
+static int is_ctx_frozen(struct vpu_ctx *ctx)
+{
+ int is_frozen = 1;
+ int i;
+ struct vpu_attr *attr = get_vpu_ctx_attr(ctx);
+
+ for (i = 0; i < GTB_ENC_CMD_RESERVED; i++) {
+ if (attr->statistic.cmd[i] != ctx->sts.cmd[i])
+ is_frozen = 0;
+ ctx->sts.cmd[i] = attr->statistic.cmd[i];
+ }
+
+ for (i = 0; i < VID_API_ENC_EVENT_RESERVED; i++) {
+ if (attr->statistic.event[i] != ctx->sts.event[i])
+ is_frozen = 0;
+ ctx->sts.event[i] = attr->statistic.event[i];
+ }
+
+ if (ctx->sts.cmd[GTB_ENC_CMD_FRAME_ENCODE] ==
+ ctx->sts.event[VID_API_ENC_EVENT_FRAME_DONE])
+ is_frozen = 0;
+
+ if (ctx->sts.cmd[GTB_ENC_CMD_CONFIGURE_CODEC] >
+ ctx->sts.event[VID_API_ENC_EVENT_MEM_REQUEST])
+ is_frozen = 1;
+ if (ctx->sts.cmd[GTB_ENC_CMD_STREAM_START] >
+ ctx->sts.event[VID_API_ENC_EVENT_START_DONE])
+ is_frozen = 1;
+ if (ctx->sts.cmd[GTB_ENC_CMD_STREAM_STOP] >
+ ctx->sts.event[VID_API_ENC_EVENT_STOP_DONE])
+ is_frozen = 1;
+
+ return is_frozen;
+}
+
+static bool check_vpu_ctx_is_hang(struct vpu_ctx *ctx)
+{
+ if (is_ctx_frozen(ctx))
+ ctx->frozen_count++;
+ else
+ ctx->frozen_count = 0;
+
+ if (ctx->frozen_count > VPU_ENC_HANG_THD) {
+ set_bit(VPU_ENC_STATUS_HANG, &ctx->status);
+ ctx->frozen_count = VPU_ENC_HANG_THD;
+ } else if (ctx->frozen_count == 0) {
+ clear_bit(VPU_ENC_STATUS_HANG, &ctx->status);
+ }
+
+ if (test_bit(VPU_ENC_STATUS_HANG, &ctx->status))
+ return true;
+
+ return false;
+}
+
+static void check_vpu_core_is_hang(struct core_device *core)
+{
+ int i;
+ unsigned int instance_count = 0;
+ unsigned int hang_count = 0;
+
+ for (i = 0; i < core->supported_instance_count; i++) {
+ if (!core->ctx[i])
+ continue;
+
+ if (check_vpu_ctx_is_hang(core->ctx[i]))
+ hang_count++;
+ instance_count++;
+ }
+
+ if (!instance_count)
+ return;
+ if (hang_count == instance_count)
+ set_core_hang(core);
+ else
+ clear_core_hang(core);
+}
+
+static void handle_vpu_core_watchdog(struct core_device *core)
+{
+ if (!core->fw_is_ready)
+ return;
+ if (core->suspend)
+ return;
+ if (core->snapshot)
+ return;
+
+ check_vpu_core_is_hang(core);
+}
+
+static unsigned long get_timestamp_ns(struct timespec *ts)
+{
+ if (!ts)
+ return 0;
+
+ return ts->tv_sec * NSEC_PER_SEC + ts->tv_nsec;
+}
+
+static void calc_rt_fps(struct vpu_fps_sts *fps,
+ unsigned long number, struct timespec *ts)
+{
+ unsigned long delta_num;
+ unsigned long delta_ts;
+
+ if (!fps || !ts)
+ return;
+
+ fps->times++;
+ if (fps->times < fps->thd)
+ return;
+
+ if (number >= fps->frame_number) {
+ delta_num = number - fps->frame_number;
+ delta_ts = get_timestamp_ns(ts) - get_timestamp_ns(&fps->ts);
+ if (!delta_ts)
+ return;
+ fps->fps = delta_num * NSEC_PER_SEC * VPU_FPS_COEF / delta_ts;
+ }
+ fps->times = 0;
+ if (fps->thd) {
+ fps->frame_number = number;
+ memcpy(&fps->ts, ts, sizeof(fps->ts));
+ }
+}
+
+static void statistic_fps_info(struct vpu_statistic *sts)
+{
+ unsigned long encoded_count = sts->encoded_count;
+ struct timespec ts;
+ int i;
+
+ if (!sts->fps_sts_enable)
+ return;
+ getrawmonotonic(&ts);
+ for (i = 0; i < VPU_FPS_STS_CNT; i++)
+ calc_rt_fps(&sts->fps[i], encoded_count, &ts);
+}
+
+static void print_firmware_debug(char *ptr, u32 size)
+{
+ u32 total = 0;
+ u32 len;
+
+ while (total < size) {
+ len = min_t(u32, size - total, 256);
+
+ pr_info("%.*s", len, ptr + total);
+ total += len;
+ }
+}
+
+static void handle_core_firmware_debug(struct core_device *core)
+{
+ char *ptr;
+ u32 rptr;
+ u32 wptr;
+
+ if (!core || !core->print_buf)
+ return;
+
+ if (!test_bit(core->id, &debug_firmware_bitmap))
+ return;
+
+ rptr = core->print_buf->read;
+ wptr = core->print_buf->write;
+ if (rptr == wptr)
+ return;
+
+ ptr = core->print_buf->buffer;
+ pr_info("----mem_printf for VPU Encoder core %d----\n", core->id);
+ if (rptr > wptr) {
+ print_firmware_debug(ptr + rptr, core->print_buf->bytes - rptr);
+ rptr = 0;
+ }
+ if (rptr < wptr) {
+ print_firmware_debug(ptr + rptr, wptr - rptr);
+ rptr = wptr;
+ }
+ if (rptr >= core->print_buf->bytes)
+ rptr = 0;
+ core->print_buf->read = rptr;
+}
+
+static void handle_core_minors(struct core_device *core)
+{
+ int i;
+
+ for (i = 0; i < core->supported_instance_count; i++)
+ statistic_fps_info(&core->attr[i].statistic);
+
+ handle_core_firmware_debug(core);
+}
+
+static void vpu_enc_watchdog_handler(struct work_struct *work)
+{
+ struct delayed_work *dwork;
+ struct vpu_dev *vdev;
+ int i;
+
+ if (!work)
+ return;
+
+ dwork = to_delayed_work(work);
+ vdev = container_of(dwork, struct vpu_dev, watchdog);
+
+ mutex_lock(&vdev->dev_mutex);
+ for (i = 0; i < vdev->core_num; i++)
+ handle_vpu_core_watchdog(&vdev->core_dev[i]);
+ mutex_unlock(&vdev->dev_mutex);
+
+ for (i = 0; i < vdev->core_num; i++)
+ handle_core_minors(&vdev->core_dev[i]);
+
+ vdev->heartbeat++;
+ schedule_delayed_work(&vdev->watchdog,
+ msecs_to_jiffies(VPU_WATCHDOG_INTERVAL_MS));
+}
+
+static int init_vpu_core_dev(struct core_device *core_dev)
+{
+ int ret;
+
+ if (!core_dev)
+ return -EINVAL;
+
+ mutex_init(&core_dev->cmd_mutex);
+ init_completion(&core_dev->start_cmp);
+ init_completion(&core_dev->snap_done_cmp);
+
+ core_dev->workqueue = alloc_workqueue("vpu",
+ WQ_UNBOUND | WQ_MEM_RECLAIM, 1);
+ if (!core_dev->workqueue) {
+ vpu_err("%s unable to alloc workqueue\n", __func__);
+ ret = -ENOMEM;
+ return ret;
+ }
+
+ INIT_WORK(&core_dev->msg_work, vpu_enc_msg_run_work);
+
+ ret = vpu_enc_mu_init(core_dev);
+ if (ret) {
+ vpu_err("%s vpu mu init failed\n", __func__);
+ goto error;
+ }
+ //firmware space for M0
+ core_dev->m0_p_fw_space_vir =
+ ioremap_wc(core_dev->m0_p_fw_space_phy, core_dev->fw_buf_size);
+ if (!core_dev->m0_p_fw_space_vir)
+ vpu_err("failed to remap space for M0 firmware\n");
+
+ cleanup_firmware_memory(core_dev);
+
+ core_dev->m0_rpc_virt =
+ ioremap_wc(core_dev->m0_rpc_phy,
+ core_dev->rpc_buf_size + core_dev->print_buf_size);
+ if (!core_dev->m0_rpc_virt)
+ vpu_err("failed to remap space for shared memory\n");
+
+ memset_io(core_dev->m0_rpc_virt, 0, core_dev->rpc_buf_size);
+
+ reset_vpu_core_dev(core_dev);
+
+ init_vpu_attrs(core_dev);
+
+ scnprintf(core_dev->name, sizeof(core_dev->name) - 1,
+ "core.%d", core_dev->id);
+ sysfs_attr_init(&core_dev->core_attr.attr);
+ core_dev->core_attr.attr.name = core_dev->name;
+ core_dev->core_attr.attr.mode = VERIFY_OCTAL_PERMISSIONS(0444);
+ core_dev->core_attr.show = show_core_info;
+ device_create_file(core_dev->generic_dev, &core_dev->core_attr);
+
+ return 0;
+error:
+ if (core_dev->workqueue) {
+ destroy_workqueue(core_dev->workqueue);
+ core_dev->workqueue = NULL;
+ }
+ return ret;
+}
+
+static int uninit_vpu_core_dev(struct core_device *core_dev)
+{
+ if (!core_dev)
+ return -EINVAL;
+
+ if (core_dev->core_attr.attr.name)
+ device_remove_file(core_dev->generic_dev, &core_dev->core_attr);
+ release_vpu_attrs(core_dev);
+ if (core_dev->workqueue) {
+ cancel_work_sync(&core_dev->msg_work);
+ destroy_workqueue(core_dev->workqueue);
+ core_dev->workqueue = NULL;
+ }
+
+ if (core_dev->m0_p_fw_space_vir) {
+ iounmap(core_dev->m0_p_fw_space_vir);
+ core_dev->m0_p_fw_space_vir = NULL;
+ }
+ core_dev->m0_p_fw_space_phy = 0;
+
+ if (core_dev->m0_rpc_virt) {
+ iounmap(core_dev->m0_rpc_virt);
+ core_dev->m0_rpc_virt = NULL;
+ }
+ core_dev->m0_rpc_phy = 0;
+
+ if (core_dev->mu_base_virtaddr)
+ core_dev->mu_base_virtaddr = NULL;
+
+ if (core_dev->generic_dev) {
+ put_device(core_dev->generic_dev);
+ core_dev->generic_dev = NULL;
+ }
+
+ return 0;
+}
+
+static void init_vpu_enc_watchdog(struct vpu_dev *vdev)
+{
+ if (!vdev)
+ return;
+
+ INIT_DELAYED_WORK(&vdev->watchdog, vpu_enc_watchdog_handler);
+ schedule_delayed_work(&vdev->watchdog,
+ msecs_to_jiffies(VPU_WATCHDOG_INTERVAL_MS));
+}
+
+static int check_vpu_encoder_is_available(void)
+{
+ sc_ipc_t mu_ipc;
+ sc_ipc_id_t mu_id;
+ uint32_t fuse = 0xffff;
+ int ret;
+
+ ret = sc_ipc_getMuID(&mu_id);
+ if (ret) {
+ vpu_err("sc_ipc_getMuID() can't obtain mu id SCI! %d\n",
+ ret);
+ return -EINVAL;
+ }
+
+ ret = sc_ipc_open(&mu_ipc, mu_id);
+ if (ret) {
+ vpu_err("sc_ipc_getMuID() can't open MU channel to SCU! %d\n",
+ ret);
+ return -EINVAL;
+ }
+
+ ret = sc_misc_otp_fuse_read(mu_ipc, VPU_DISABLE_BITS, &fuse);
+ sc_ipc_close(mu_ipc);
+ if (ret) {
+ vpu_err("sc_misc_otp_fuse_read fail! %d\n", ret);
+ return -EINVAL;
+ }
+
+ vpu_dbg(LVL_INFO, "mu_id = %d, fuse[7] = 0x%x\n", mu_id, fuse);
+ if (fuse & VPU_ENCODER_MASK) {
+ vpu_err("----Error, VPU Encoder is disabled\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static const struct of_device_id vpu_enc_of_match[];
+static int vpu_enc_probe(struct platform_device *pdev)
+{
+ struct vpu_dev *dev;
+ struct device_node *np = pdev->dev.of_node;
+ const struct of_device_id *dev_id = NULL;
+ struct resource *res = NULL;
+ u_int32 i;
+ int ret;
+
+ if (!np) {
+ vpu_err("error: %s of_node is NULL\n", __func__);
+ return -EINVAL;
+ }
+
+ dev_id = of_match_device(vpu_enc_of_match, &pdev->dev);
+ if (!dev_id) {
+ vpu_err("unmatch vpu encoder device\n");
+ return -EINVAL;
+ }
+ vpu_dbg(LVL_INFO, "probe %s\n", dev_id->compatible);
+
+ if (check_vpu_encoder_is_available())
+ return -EINVAL;
+
+ dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL);
+ if (!dev)
+ return -ENOMEM;
+ dev->plat_type = *(enum PLAT_TYPE *)dev_id->data;
+ dev->plat_dev = pdev;
+ dev->generic_dev = get_device(&pdev->dev);
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+ if (!res)
+ goto error_put_dev;
+
+ dev->reg_vpu_base = res->start;
+ dev->reg_vpu_size = resource_size(res);
+
+ ret = parse_dt_info(dev, np);
+ if (ret) {
+ vpu_err("parse device tree fail\n");
+ goto error_put_dev;
+ }
+
+ dev->regs_base = ioremap(dev->reg_vpu_base, dev->reg_vpu_size);
+ if (!dev->regs_base) {
+ vpu_err("%s could not map regs_base\n", __func__);
+ ret = PTR_ERR(dev->regs_base);
+ goto error_put_dev;
+ }
+
+ ret = vpu_enc_init_reserved_memory(&dev->reserved_mem);
+ if (ret) {
+ vpu_err("%s couldn't init reserved memory\n", __func__);
+ goto error_iounmap;
+ }
+
+ ret = v4l2_device_register(&pdev->dev, &dev->v4l2_dev);
+ if (ret) {
+ vpu_err("%s unable to register v4l2 dev\n", __func__);
+ goto error_reserved_mem;
+ }
+
+ platform_set_drvdata(pdev, dev);
+
+ ret = create_vpu_video_device(dev);
+ if (ret) {
+ vpu_err("create vpu video device fail\n");
+ goto error_unreg_v4l2;
+ }
+
+ pm_runtime_enable(&pdev->dev);
+ pm_runtime_get_sync(&pdev->dev);
+
+ vpu_enc_enable_hw(dev);
+
+ mutex_init(&dev->dev_mutex);
+ for (i = 0; i < dev->core_num; i++) {
+ dev->core_dev[i].id = i;
+ dev->core_dev[i].generic_dev = get_device(dev->generic_dev);
+ dev->core_dev[i].vdev = dev;
+ ret = init_vpu_core_dev(&dev->core_dev[i]);
+ if (ret)
+ break;
+ }
+ if (i == 0)
+ goto error_init_core;
+ dev->core_num = i;
+
+ pm_runtime_put_sync(&pdev->dev);
+
+ device_create_file(&pdev->dev, &dev_attr_meminfo);
+ device_create_file(&pdev->dev, &dev_attr_buffer);
+ device_create_file(&pdev->dev, &dev_attr_fpsinfo);
+ device_create_file(&pdev->dev, &dev_attr_vpuinfo);
+ init_vpu_enc_watchdog(dev);
+ vpu_dbg(LVL_INFO, "VPU Encoder registered\n");
+
+ return 0;
+
+error_init_core:
+ for (i = 0; i < dev->core_num; i++)
+ uninit_vpu_core_dev(&dev->core_dev[i]);
+
+ vpu_enc_disable_hw(dev);
+ pm_runtime_put_sync(&pdev->dev);
+ pm_runtime_disable(&pdev->dev);
+
+ if (dev->pvpu_encoder_dev) {
+ video_unregister_device(dev->pvpu_encoder_dev);
+ dev->pvpu_encoder_dev = NULL;
+ }
+error_unreg_v4l2:
+ v4l2_device_unregister(&dev->v4l2_dev);
+error_reserved_mem:
+ vpu_enc_release_reserved_memory(&dev->reserved_mem);
+error_iounmap:
+ if (dev->regs_base) {
+ iounmap(dev->regs_base);
+ dev->regs_base = NULL;
+ }
+error_put_dev:
+ if (dev->generic_dev) {
+ put_device(dev->generic_dev);
+ dev->generic_dev = NULL;
+ }
+ return -EINVAL;
+}
+
+static int vpu_enc_remove(struct platform_device *pdev)
+{
+ struct vpu_dev *dev = platform_get_drvdata(pdev);
+ u_int32 i;
+
+ cancel_delayed_work_sync(&dev->watchdog);
+ device_remove_file(&pdev->dev, &dev_attr_vpuinfo);
+ device_remove_file(&pdev->dev, &dev_attr_fpsinfo);
+ device_remove_file(&pdev->dev, &dev_attr_buffer);
+ device_remove_file(&pdev->dev, &dev_attr_meminfo);
+
+ pm_runtime_get_sync(&pdev->dev);
+ for (i = 0; i < dev->core_num; i++)
+ uninit_vpu_core_dev(&dev->core_dev[i]);
+
+ vpu_enc_disable_hw(dev);
+ pm_runtime_put_sync(&pdev->dev);
+ pm_runtime_disable(&pdev->dev);
+
+ if (video_get_drvdata(dev->pvpu_encoder_dev))
+ video_unregister_device(dev->pvpu_encoder_dev);
+
+ v4l2_device_unregister(&dev->v4l2_dev);
+ vpu_enc_release_reserved_memory(&dev->reserved_mem);
+ if (dev->regs_base) {
+ iounmap(dev->regs_base);
+ dev->regs_base = NULL;
+ }
+ if (dev->generic_dev) {
+ put_device(dev->generic_dev);
+ dev->generic_dev = NULL;
+ }
+
+ vpu_dbg(LVL_INFO, "VPU Encoder removed\n");
+
+ return 0;
+}
+
+static int vpu_enc_runtime_suspend(struct device *dev)
+{
+ return 0;
+}
+
+static int vpu_enc_runtime_resume(struct device *dev)
+{
+ return 0;
+}
+
+static int is_core_activated(struct core_device *core)
+{
+ WARN_ON(!core);
+
+ if (readl_relaxed(core->mu_base_virtaddr + MU_B0_REG_CONTROL) == 0)
+ return false;
+ else
+ return true;
+}
+
+static int is_need_shapshot(struct vpu_ctx *ctx)
+{
+ if (!test_bit(VPU_ENC_STATUS_INITIALIZED, &ctx->status))
+ return 0;
+ if (!test_bit(VPU_ENC_STATUS_CONFIGURED, &ctx->status))
+ return 0;
+ if (test_bit(VPU_ENC_STATUS_CLOSED, &ctx->status))
+ return 0;
+ if (test_bit(VPU_ENC_STATUS_STOP_SEND, &ctx->status))
+ return 0;
+ if (test_bit(VPU_ENC_STATUS_STOP_DONE, &ctx->status))
+ return 0;
+
+ return 1;
+}
+
+static int vpu_enc_snapshot(struct vpu_ctx *ctx)
+{
+ int ret;
+
+ if (!ctx)
+ return -EINVAL;
+
+ vpu_dbg(LVL_INFO, "core[%d] snapshot\n", ctx->core_dev->id);
+ vpu_ctx_send_cmd(ctx, GTB_ENC_CMD_SNAPSHOT, 0, NULL);
+ ret = wait_for_completion_timeout(&ctx->core_dev->snap_done_cmp,
+ msecs_to_jiffies(1000));
+ if (!ret)
+ vpu_err("error:wait for snapdone event timeout!\n");
+ else
+ ctx->core_dev->snapshot = true;
+
+ return 0;
+}
+
+static int resume_from_snapshot(struct core_device *core)
+{
+ int ret = 0;
+
+ if (!core)
+ return -EINVAL;
+ if (!core->snapshot)
+ return 0;
+
+ vpu_dbg(LVL_INFO, "core[%d] resume from snapshot\n", core->id);
+
+ init_completion(&core->start_cmp);
+ set_vpu_fw_addr(core->vdev, core);
+ ret = wait_for_start_done(core, 1);
+ if (ret) {
+ set_core_force_release(core);
+ reset_vpu_core_dev(core);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int re_download_firmware(struct core_device *core)
+{
+ if (!core)
+ return -EINVAL;
+
+ vpu_dbg(LVL_INFO, "re download firmware for core[%d]\n", core->id);
+
+ reset_vpu_core_dev(core);
+ return download_vpu_firmware(core->vdev, core);
+}
+
+static int suspend_instance(struct vpu_ctx *ctx)
+{
+ int ret = 0;
+
+ if (!ctx)
+ return 0;
+
+ if (test_bit(VPU_ENC_STATUS_STOP_REQ, &ctx->status) ||
+ test_bit(VPU_ENC_STATUS_STOP_SEND, &ctx->status))
+ wait_for_stop_done(ctx);
+
+ mutex_lock(&ctx->instance_mutex);
+ if (!ctx->core_dev->snapshot && is_need_shapshot(ctx))
+ ret = vpu_enc_snapshot(ctx);
+ set_bit(VPU_ENC_STATUS_SNAPSHOT, &ctx->status);
+ mutex_unlock(&ctx->instance_mutex);
+
+ return ret;
+}
+
+static int resume_instance(struct vpu_ctx *ctx)
+{
+ if (!ctx)
+ return 0;
+
+ clear_bit(VPU_ENC_STATUS_SNAPSHOT, &ctx->status);
+
+ return 0;
+}
+
+static int suspend_core(struct core_device *core)
+{
+ int i;
+ int ret = 0;
+
+ WARN_ON(!core);
+
+ core->snapshot = false;
+
+ if (!core->fw_is_ready)
+ return 0;
+
+ for (i = 0; i < core->supported_instance_count; i++) {
+ if (!core->ctx[i])
+ continue;
+ ret = suspend_instance(core->ctx[i]);
+ if (ret)
+ return ret;
+ }
+
+ for (i = 0; i < core->supported_instance_count; i++)
+ vpu_ctx_power_off(core->ctx[i]);
+
+ core->suspend = true;
+
+ return 0;
+}
+
+static int resume_core(struct core_device *core)
+{
+ int ret = 0;
+ u32 instance_count = 0;
+ int i;
+
+ WARN_ON(!core);
+
+ if (!core->suspend)
+ return 0;
+
+ for (i = 0; i < core->supported_instance_count; i++) {
+ if (!core->ctx[i])
+ continue;
+ instance_count++;
+ vpu_ctx_power_on(core->ctx[i]);
+ resume_instance(core->ctx[i]);
+ }
+
+ /* if the core isn't activated, it means it has been power off and on */
+ if (!is_core_activated(core)) {
+ if (!core->vdev->hw_enable)
+ vpu_enc_enable_hw(core->vdev);
+ if (core->snapshot)
+ ret = resume_from_snapshot(core);
+ else if (instance_count)
+ ret = re_download_firmware(core);
+ else
+ reset_vpu_core_dev(core);
+ } else {
+ if (core->snapshot || instance_count)
+ ret = sw_reset_firmware(core, 1);
+ }
+
+ core->snapshot = false;
+ core->suspend = false;
+
+ return ret;
+}
+
+static int vpu_enc_suspend(struct device *dev)
+{
+ struct vpu_dev *vpudev = (struct vpu_dev *)dev_get_drvdata(dev);
+ int i;
+ int ret = 0;
+
+ vpu_dbg(LVL_INFO, "suspend\n");
+
+ mutex_lock(&vpudev->dev_mutex);
+ pm_runtime_get_sync(dev);
+ for (i = 0; i < vpudev->core_num; i++) {
+ ret = suspend_core(&vpudev->core_dev[i]);
+ if (ret)
+ break;
+ }
+ pm_runtime_put_sync(dev);
+ mutex_unlock(&vpudev->dev_mutex);
+
+ vpu_dbg(LVL_INFO, "suspend done\n");
+
+ return ret;
+}
+
+static int vpu_enc_resume(struct device *dev)
+{
+ struct vpu_dev *vpudev = (struct vpu_dev *)dev_get_drvdata(dev);
+ int i;
+ int ret = 0;
+
+ vpu_dbg(LVL_INFO, "resume\n");
+
+ mutex_lock(&vpudev->dev_mutex);
+ pm_runtime_get_sync(dev);
+ vpudev->hw_enable = false;
+ for (i = 0; i < vpudev->core_num; i++) {
+ ret = resume_core(&vpudev->core_dev[i]);
+ if (ret)
+ break;
+ }
+ vpudev->hw_enable = true;
+ pm_runtime_put_sync(dev);
+ mutex_unlock(&vpudev->dev_mutex);
+
+ vpu_dbg(LVL_INFO, "resume done\n");
+
+ return ret;
+}
+
+static const struct dev_pm_ops vpu_enc_pm_ops = {
+ SET_RUNTIME_PM_OPS(vpu_enc_runtime_suspend, vpu_enc_runtime_resume, NULL)
+ SET_SYSTEM_SLEEP_PM_OPS(vpu_enc_suspend, vpu_enc_resume)
+};
+
+static enum PLAT_TYPE supported_plat_types[PLAT_TYPE_RESERVED] = {
+ [IMX8QXP] = IMX8QXP,
+ [IMX8QM] = IMX8QM,
+};
+
+static const struct of_device_id vpu_enc_of_match[] = {
+ { .compatible = "nxp,imx8qm-b0-vpuenc",
+ .data = (void *)&supported_plat_types[IMX8QM]
+ },
+ { .compatible = "nxp,imx8qxp-b0-vpuenc",
+ .data = (void *)&supported_plat_types[IMX8QXP]
+ },
+ {}
+}
+MODULE_DEVICE_TABLE(of, vpu_enc_of_match);
+
+static struct platform_driver vpu_enc_driver = {
+ .probe = vpu_enc_probe,
+ .remove = vpu_enc_remove,
+ .driver = {
+ .name = "vpu-b0-encoder",
+ .of_match_table = vpu_enc_of_match,
+ .pm = &vpu_enc_pm_ops,
+ },
+};
+module_platform_driver(vpu_enc_driver);
+
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("Linux VPU driver for Freescale i.MX/MXC");
+MODULE_LICENSE("GPL");
+MODULE_VERSION(VPU_ENC_DRIVER_VERSION);
+
+module_param(vpu_dbg_level_encoder, int, 0644);
+MODULE_PARM_DESC(vpu_dbg_level_encoder, "Debug level (0-4)");
+
+module_param(reset_on_hang, int, 0644);
+MODULE_PARM_DESC(reset_on_hang, "reset on hang (0-1)");
+
+module_param(show_detail_index, int, 0644);
+MODULE_PARM_DESC(show_detail_index, "show memory detail info index");
+
+module_param(debug_firmware_bitmap, long, 0644);
+MODULE_PARM_DESC(debug_firmware_bitmap, "firmware debug info switch");
+
diff --git a/drivers/mxc/vpu_windsor/vpu_encoder_b0.h b/drivers/mxc/vpu_windsor/vpu_encoder_b0.h
new file mode 100644
index 000000000000..14aedd5d8b9f
--- /dev/null
+++ b/drivers/mxc/vpu_windsor/vpu_encoder_b0.h
@@ -0,0 +1,468 @@
+/*
+ * Copyright 2018 NXP
+ */
+
+/*
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/*!
+ * @file vpu_encoder_b0.h
+ *
+ * @brief VPU ENCODER B0 definition
+ *
+ */
+#ifndef __VPU_ENCODER_B0_H__
+#define __VPU_ENCODER_B0_H__
+
+#include <linux/irqreturn.h>
+#include <linux/mutex.h>
+#include <linux/videodev2.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-fh.h>
+#include <media/videobuf2-v4l2.h>
+#include <soc/imx8/sc/svc/irq/api.h>
+#include <soc/imx8/sc/ipc.h>
+#include <soc/imx8/sc/sci.h>
+#include <linux/mx8_mu.h>
+#include <media/v4l2-event.h>
+#include "vpu_encoder_rpc.h"
+#include "vpu_encoder_config.h"
+
+extern unsigned int vpu_dbg_level_encoder;
+
+#define v4l2_fh_to_ctx(__fh) \
+ container_of(__fh, struct vpu_ctx, fh)
+#define v4l2_ctrl_to_ctx(__ctrl) \
+ container_of((__ctrl)->handler, struct vpu_ctx, ctrl_handler)
+
+#define VPU_ENC_MAX_CORE_NUM 2
+#define VPU_MAX_BUFFER 32
+#define M0FW_FILENAME "vpu/vpu_fw_imx8_enc.bin"
+#define MMAP_BUF_TYPE_SHIFT 28
+#define MMAP_BUF_TYPE_MASK 0xF0000000
+#define M0_BOOT_SIZE_DEFAULT 0x1000000
+#define M0_BOOT_SIZE_MIN 0x100000
+#define RPC_SIZE_DEFAULT 0x80000
+#define RPC_SIZE_MIN 0x20000
+#define PRINT_SIZE_DEFAULT 0x80000
+#define PRINT_SIZE_MIN 0x20000
+#define STREAM_SIZE 0x300000
+#define MU_B0_REG_CONTROL (0x10000 + 0x24)
+
+#define MIN_BUFFER_COUNT 3
+#define BITRATE_COEF 1024
+#define BITRATE_LOW_THRESHOLD (16)
+#define BITRATE_HIGH_THRESHOLD (240 * 1024)
+#define BITRATE_DEFAULT_TARGET (2 * 1024)
+#define BITRATE_DEFAULT_PEAK (8 * 1024)
+#define GOP_H_THRESHOLD 300
+#define GOP_L_THRESHOLD 1
+#define GOP_DEFAULT 30
+#define BFRAMES_H_THRESHOLD 4
+#define BFRAMES_L_THRESHOLD 0
+#define BFRAMES_DEFAULT 2
+#define QP_MAX 51
+#define QP_MIN 0
+#define QP_DEFAULT 25
+
+#define VPU_DISABLE_BITS 0x7
+#define VPU_ENCODER_MASK 0x1
+
+#define ENCODER_NODE_NUMBER 13 //use /dev/video13 as encoder node
+struct vpu_v4l2_control {
+ uint32_t id;
+ enum v4l2_ctrl_type type;
+ uint32_t minimum;
+ uint32_t maximum;
+ uint32_t step;
+ uint32_t default_value;
+ uint32_t menu_skip_mask;
+ bool is_volatile;
+};
+
+typedef enum{
+ INIT_DONE = 1,
+ RPC_BUF_OFFSET,
+ BOOT_ADDRESS,
+ COMMAND,
+ EVENT
+} MSG_Type;
+
+enum PLAT_TYPE {
+ IMX8QXP = 0,
+ IMX8QM = 1,
+ IMX8DM,
+ IMX8DX,
+ PLAT_TYPE_RESERVED
+};
+
+enum QUEUE_TYPE {
+ V4L2_SRC = 0,
+ V4L2_DST = 1,
+};
+
+enum vpu_video_standard {
+ VPU_VIDEO_UNDEFINED = 0,
+ VPU_VIDEO_AVC = 1,
+ VPU_VIDEO_VC1 = 2,
+ VPU_VIDEO_MPEG2 = 3,
+ VPU_VIDEO_AVS = 4,
+ VPU_VIDEO_ASP = 5,
+ VPU_VIDEO_JPEG = 6,
+ VPU_VIDEO_RV8 = 7,
+ VPU_VIDEO_RV9 = 8,
+ VPU_VIDEO_VP6 = 9,
+ VPU_VIDEO_SPK = 10,
+ VPU_VIDEO_VP8 = 11,
+ VPU_VIDEO_AVC_MVC = 12,
+ VPU_VIDEO_HEVC = 13,
+ VPU_VIDEO_VP9 = 14,
+};
+
+#define VPU_PIX_FMT_AVS v4l2_fourcc('A', 'V', 'S', '0')
+#define VPU_PIX_FMT_ASP v4l2_fourcc('A', 'S', 'P', '0')
+#define VPU_PIX_FMT_RV8 v4l2_fourcc('R', 'V', '8', '0')
+#define VPU_PIX_FMT_RV9 v4l2_fourcc('R', 'V', '9', '0')
+#define VPU_PIX_FMT_VP6 v4l2_fourcc('V', 'P', '6', '0')
+#define VPU_PIX_FMT_SPK v4l2_fourcc('S', 'P', 'K', '0')
+#define VPU_PIX_FMT_HEVC v4l2_fourcc('H', 'E', 'V', 'C')
+#define VPU_PIX_FMT_VP9 v4l2_fourcc('V', 'P', '9', '0')
+#define VPU_PIX_FMT_LOGO v4l2_fourcc('L', 'O', 'G', 'O')
+
+#define VPU_PIX_FMT_TILED_8 v4l2_fourcc('Z', 'T', '0', '8')
+#define VPU_PIX_FMT_TILED_10 v4l2_fourcc('Z', 'T', '1', '0')
+
+enum vpu_pixel_format {
+ VPU_HAS_COLOCATED = 0x00000001,
+ VPU_HAS_SPLIT_FLD = 0x00000002,
+ VPU_PF_MASK = ~(VPU_HAS_COLOCATED | VPU_HAS_SPLIT_FLD),
+
+ VPU_IS_TILED = 0x000000100,
+ VPU_HAS_10BPP = 0x00000200,
+
+ VPU_IS_PLANAR = 0x00001000,
+ VPU_IS_SEMIPLANAR = 0x00002000,
+ VPU_IS_PACKED = 0x00004000,
+
+ // Merged definitions using above flags:
+ VPU_PF_UNDEFINED = 0,
+ VPU_PF_YUV420_SEMIPLANAR = 0x00010000 | VPU_IS_SEMIPLANAR,
+ VPU_PF_YUV420_PLANAR = 0x00020000 | VPU_IS_PLANAR,
+ VPU_PF_UYVY = 0x00040000 | VPU_IS_PACKED,
+ VPU_PF_TILED_8BPP = 0x00080000 | VPU_IS_TILED | VPU_IS_SEMIPLANAR,
+ VPU_PF_TILED_10BPP = 0x00100000 | VPU_IS_TILED | VPU_IS_SEMIPLANAR | VPU_HAS_10BPP,
+};
+
+struct vpu_ctx;
+struct core_device;
+struct vpu_dev;
+struct vpu_v4l2_fmt {
+ char *name;
+ unsigned int fourcc;
+ unsigned int num_planes;
+ unsigned int venc_std;
+ unsigned int is_yuv;
+};
+
+struct vb2_data_req {
+ struct list_head list;
+ struct vb2_buffer *vb2_buf;
+ u_int32 sequence;
+ u_int32 buffer_flags;
+};
+
+enum ENC_RW_FLAG {
+ VPU_ENC_FLAG_WRITEABLE,
+ VPU_ENC_FLAG_READABLE
+};
+
+struct queue_data {
+ unsigned int width;
+ unsigned int height;
+ unsigned int sizeimage[VB2_MAX_PLANES];
+ struct v4l2_rect rect;
+ int buf_type; // v4l2_buf_type
+ bool vb2_q_inited;
+ struct vb2_queue vb2_q; // vb2 queue
+ struct list_head drv_q; // driver queue
+ struct semaphore drv_q_lock;
+ struct vb2_data_req vb2_reqs[VPU_MAX_BUFFER];
+ enum QUEUE_TYPE type;
+ struct vpu_v4l2_fmt *supported_fmts;
+ unsigned int fmt_count;
+ struct vpu_v4l2_fmt *current_fmt;
+ unsigned long rw_flag;
+ struct list_head frame_q;
+ atomic64_t frame_count;
+ struct list_head frame_idle;
+ struct vpu_ctx *ctx;
+ char desc[64];
+};
+
+struct vpu_strip_info {
+ unsigned long count;
+ unsigned long max;
+ unsigned long total;
+};
+
+struct vpu_fps_sts {
+ unsigned int thd;
+ unsigned int times;
+ unsigned long frame_number;
+ struct timespec ts;
+ unsigned long fps;
+};
+
+struct vpu_statistic {
+ unsigned long cmd[GTB_ENC_CMD_RESERVED + 1];
+ unsigned long event[VID_API_ENC_EVENT_RESERVED + 1];
+ unsigned long current_cmd;
+ unsigned long current_event;
+ struct timespec ts_cmd;
+ struct timespec ts_event;
+ unsigned long yuv_count;
+ unsigned long encoded_count;
+ unsigned long h264_count;
+ struct {
+ struct vpu_strip_info fw;
+ struct vpu_strip_info begin;
+ struct vpu_strip_info eos;
+ } strip_sts;
+ bool fps_sts_enable;
+ struct vpu_fps_sts fps[VPU_FPS_STS_CNT];
+ unsigned long timestamp_overwrite;
+};
+
+struct vpu_attr {
+ struct device_attribute dev_attr;
+ char name[64];
+ u32 index;
+ struct core_device *core;
+
+ pid_t pid;
+ pid_t tgid;
+
+ struct vpu_statistic statistic;
+ MEDIAIP_ENC_PARAM param;
+
+ unsigned long ts_start[2];
+ unsigned long msg_count;
+ atomic64_t total_dma_size;
+
+ bool created;
+};
+
+struct print_buf_desc {
+ u32 start_h_phy;
+ u32 start_h_vir;
+ u32 start_m;
+ u32 bytes;
+ u32 read;
+ u32 write;
+ char buffer[0];
+};
+
+struct core_device {
+ void *m0_p_fw_space_vir;
+ u_int32 m0_p_fw_space_phy;
+ u32 fw_buf_size;
+ u32 fw_actual_size;
+ void *m0_rpc_virt;
+ u_int32 m0_rpc_phy;
+ u32 rpc_buf_size;
+ u32 print_buf_size;
+ u32 rpc_actual_size;
+ struct print_buf_desc *print_buf;
+
+ struct mutex cmd_mutex;
+ bool fw_is_ready;
+ bool firmware_started;
+ struct completion start_cmp;
+ struct completion snap_done_cmp;
+ struct workqueue_struct *workqueue;
+ struct work_struct msg_work;
+ void __iomem *mu_base_virtaddr;
+ unsigned int vpu_mu_id;
+ int vpu_mu_init;
+
+ u32 supported_instance_count;
+ struct vpu_ctx *ctx[VID_API_NUM_STREAMS];
+ struct vpu_attr attr[VID_API_NUM_STREAMS];
+ struct shared_addr shared_mem;
+ u32 id;
+ u32 reg_base;
+ u32 reg_size;
+ u32 reg_csr_base;
+ u32 reg_csr_size;
+ int irq;
+ struct device *generic_dev;
+ struct vpu_dev *vdev;
+ bool snapshot;
+ bool suspend;
+ bool hang;
+ struct device_attribute core_attr;
+ char name[64];
+ unsigned long reset_times;
+};
+
+struct vpu_enc_mem_item {
+ struct list_head list;
+ void *virt_addr;
+ unsigned long phy_addr;
+ unsigned long size;
+ unsigned long offset;
+};
+
+struct vpu_enc_mem_info {
+ void *virt_addr;
+ unsigned long phy_addr;
+ unsigned long size;
+ unsigned long bytesused;
+ struct list_head memorys;
+ spinlock_t lock;
+};
+
+struct vpu_dev {
+ struct device *generic_dev;
+ struct v4l2_device v4l2_dev;
+ struct video_device *pvpu_encoder_dev;
+ struct platform_device *plat_dev;
+ struct clk *clk_m0;
+ u32 reg_vpu_base;
+ u32 reg_vpu_size;
+ u32 reg_rpc_system;
+ void __iomem *regs_base;
+ struct mutex dev_mutex;
+ struct core_device core_dev[VPU_ENC_MAX_CORE_NUM];
+ u_int32 plat_type;
+ u_int32 core_num;
+ bool hw_enable;
+
+ struct delayed_work watchdog;
+ u8 heartbeat;
+
+ struct {
+ u32 min_width;
+ u32 max_width;
+ u32 step_width;
+ u32 min_height;
+ u32 max_height;
+ u32 step_height;
+ } supported_size;
+ struct {
+ u32 min;
+ u32 max;
+ u32 step;
+ } supported_fps;
+ struct vpu_enc_mem_info reserved_mem;
+};
+
+struct buffer_addr {
+ void *virt_addr;
+ dma_addr_t phy_addr;
+ u_int32 size;
+};
+
+enum {
+ VPU_ENC_STATUS_INITIALIZED,
+ VPU_ENC_STATUS_OUTPUT_READY = 18,
+ VPU_ENC_STATUS_DATA_READY = 19,
+ VPU_ENC_STATUS_SNAPSHOT = 20,
+ VPU_ENC_STATUS_FORCE_RELEASE = 21,
+ VPU_ENC_STATUS_EOS_SEND = 22,
+ VPU_ENC_STATUS_START_SEND = 23,
+ VPU_ENC_STATUS_START_DONE = 24,
+ VPU_ENC_STATUS_STOP_REQ = 25,
+ VPU_ENC_STATUS_STOP_SEND = 26,
+ VPU_ENC_STATUS_STOP_DONE = 27,
+ VPU_ENC_STATUS_CLOSED = 28,
+ VPU_ENC_STATUS_CONFIGURED = 29,
+ VPU_ENC_STATUS_HANG = 30,
+ VPU_ENC_STATUS_KEY_FRAME = 31
+};
+
+struct vpu_ctx {
+ struct vpu_dev *dev;
+ struct v4l2_fh fh;
+
+ struct v4l2_ctrl_handler ctrl_handler;
+ bool ctrl_inited;
+
+ int str_index;
+ unsigned long status;
+ struct queue_data q_data[2];
+ struct mutex instance_mutex;
+ struct work_struct instance_work;
+ struct workqueue_struct *instance_wq;
+ bool ctx_released;
+ struct buffer_addr encoder_stream;
+ struct buffer_addr encFrame[MEDIAIP_MAX_NUM_WINDSOR_SRC_FRAMES];
+ struct buffer_addr refFrame[MEDIAIP_MAX_NUM_WINDSOR_REF_FRAMES];
+ struct buffer_addr actFrame;
+ struct buffer_addr enc_buffer;
+ MEDIAIP_ENC_MEM_REQ_DATA mem_req;
+ struct core_device *core_dev;
+
+ struct completion stop_cmp;
+ bool power_status;
+
+ struct list_head msg_q;
+ struct list_head idle_q;
+
+ struct vpu_statistic sts;
+ unsigned int frozen_count;
+ u_int32 sequence;
+ s64 timestams[VPU_ENC_SEQ_CAPACITY];
+};
+
+#define LVL_ERR (1 << 0)
+#define LVL_WARN (1 << 1)
+#define LVL_ALL (1 << 2)
+#define LVL_IRQ (1 << 3)
+#define LVL_INFO (1 << 4)
+#define LVL_CMD (1 << 5)
+#define LVL_EVT (1 << 6)
+#define LVL_DEBUG (1 << 7)
+#define LVL_CTRL (1 << 8)
+#define LVL_RPC (1 << 9)
+#define LVL_MSG (1 << 10)
+#define LVL_MEM (1 << 11)
+#define LVL_BUF (1 << 12)
+#define LVL_FRAME (1 << 13)
+#define LVL_FUNC (1 << 16)
+
+#ifndef TAG
+#define TAG "[VPU Encoder]\t "
+#endif
+
+#define vpu_dbg(level, fmt, arg...) \
+ do { \
+ if ((vpu_dbg_level_encoder & (level)) || ((level) & LVL_ERR)) \
+ pr_info(TAG""fmt, ## arg); \
+ } while (0)
+
+#define vpu_err(fmt, arg...) vpu_dbg(LVL_ERR, fmt, ##arg)
+#define vpu_log_func() vpu_dbg(LVL_FUNC, "%s()\n", __func__)
+
+u32 cpu_phy_to_mu(struct core_device *dev, u32 addr);
+struct vpu_attr *get_vpu_ctx_attr(struct vpu_ctx *ctx);
+struct vpu_ctx *get_vpu_attr_ctx(struct vpu_attr *attr);
+
+#ifndef VPU_SAFE_RELEASE
+#define VPU_SAFE_RELEASE(p, func) \
+ do {\
+ if (p) {\
+ func(p);\
+ p = NULL;\
+ } \
+ } while (0)
+#endif
+
+#endif
diff --git a/drivers/mxc/vpu_windsor/vpu_encoder_config.h b/drivers/mxc/vpu_windsor/vpu_encoder_config.h
new file mode 100644
index 000000000000..dee84033ebdb
--- /dev/null
+++ b/drivers/mxc/vpu_windsor/vpu_encoder_config.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright(c) 2018 NXP. All rights reserved.
+ *
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * vpu_encoder_config.h
+ *
+ * Author Ming Qian<ming.qian@nxp.com>
+ */
+#ifndef _VPU_ENCODER_CONFIG_H
+#define _VPU_ENCODER_CONFIG_H
+
+#define VPU_ENC_WIDTH_MAX 1920
+#define VPU_ENC_HEIGHT_MAX 1080
+#define VPU_ENC_WIDTH_MIN 64
+#define VPU_ENC_HEIGHT_MIN 48
+#define VPU_ENC_WIDTH_STEP 16
+#define VPU_ENC_HEIGHT_STEP 2
+#define VPU_ENC_FRAMERATE_MAX 120
+#define VPU_ENC_FRAMERATE_MIN 1
+#define VPU_ENC_FRAMERATE_STEP 1
+
+#define VPU_ENC_WIDTH_DEFAULT 1920
+#define VPU_ENC_HEIGHT_DEFAULT 1080
+#define VPU_ENC_FRAMERATE_DEFAULT 30
+
+#define VPU_MEM_PATTERN 0x5a5a5a5a
+
+#define VPU_TAIL_SERACH_SIZE 16
+#define VPU_STRM_END_PATTERN {0x0, 0x0, 0x1, 0xb}
+#define VPU_STRM_BEGIN_PATTERN {0x0, 0x0, 0x1}
+
+#define MSG_DATA_DEFAULT_SIZE 256
+#define MSG_COUNT_THD 16
+#define FRAME_COUNT_THD 16
+
+#define VPU_WATCHDOG_INTERVAL_MS 1000
+#define VPU_ENC_HANG_THD 15
+
+#define VPU_FPS_STS_CNT 3
+#define VPU_FPS_STS_THDS {1, 3, 0}
+#define VPU_FPS_COEF 100
+
+#define VPU_DETAIL_INDEX_DFT 0xffff
+
+#define VPU_MU_MAX_ADDRESS 0x40000000
+#define VPU_ENC_SEQ_CAPACITY 32
+#define VPU_ENC_INVALID_TIMESTAMP 0
+
+#endif
diff --git a/drivers/mxc/vpu_windsor/vpu_encoder_ctrl.c b/drivers/mxc/vpu_windsor/vpu_encoder_ctrl.c
new file mode 100644
index 000000000000..37aee18aabf6
--- /dev/null
+++ b/drivers/mxc/vpu_windsor/vpu_encoder_ctrl.c
@@ -0,0 +1,609 @@
+/*
+ * Copyright(c) 2018 NXP. All rights reserved.
+ *
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file vpu_encoder_ctrl.c
+ *
+ * Author Ming Qian<ming.qian@nxp.com>
+ */
+
+#define TAG "[VPU Encoder Ctrl]\t "
+#include <media/v4l2-ctrls.h>
+
+#include "vpu_encoder_b0.h"
+#include "vpu_encoder_ctrl.h"
+
+// H264 level is maped like level 5.1 to uLevel 51, except level 1b to uLevel 14
+const u_int32 h264_level[] = {
+ [V4L2_MPEG_VIDEO_H264_LEVEL_1_0] = 10,
+ [V4L2_MPEG_VIDEO_H264_LEVEL_1B] = 14,
+ [V4L2_MPEG_VIDEO_H264_LEVEL_1_1] = 11,
+ [V4L2_MPEG_VIDEO_H264_LEVEL_1_2] = 12,
+ [V4L2_MPEG_VIDEO_H264_LEVEL_1_3] = 13,
+ [V4L2_MPEG_VIDEO_H264_LEVEL_2_0] = 20,
+ [V4L2_MPEG_VIDEO_H264_LEVEL_2_1] = 21,
+ [V4L2_MPEG_VIDEO_H264_LEVEL_2_2] = 22,
+ [V4L2_MPEG_VIDEO_H264_LEVEL_3_0] = 30,
+ [V4L2_MPEG_VIDEO_H264_LEVEL_3_1] = 31,
+ [V4L2_MPEG_VIDEO_H264_LEVEL_3_2] = 32,
+ [V4L2_MPEG_VIDEO_H264_LEVEL_4_0] = 40,
+ [V4L2_MPEG_VIDEO_H264_LEVEL_4_1] = 41,
+ [V4L2_MPEG_VIDEO_H264_LEVEL_4_2] = 42,
+ [V4L2_MPEG_VIDEO_H264_LEVEL_5_0] = 50,
+ [V4L2_MPEG_VIDEO_H264_LEVEL_5_1] = 51
+};
+
+static int set_h264_profile(struct v4l2_ctrl *ctrl)
+{
+ struct vpu_ctx *ctx = v4l2_ctrl_to_ctx(ctrl);
+ struct vpu_attr *attr = get_vpu_ctx_attr(ctx);
+ pMEDIAIP_ENC_PARAM param = &attr->param;
+
+ mutex_lock(&ctx->instance_mutex);
+ switch (ctrl->val) {
+ case V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE:
+ vpu_dbg(LVL_CTRL, "set h264 profile baseline\n");
+ param->eProfile = MEDIAIP_ENC_PROF_H264_BP;
+ break;
+ case V4L2_MPEG_VIDEO_H264_PROFILE_MAIN:
+ vpu_dbg(LVL_CTRL, "set h264 profile main\n");
+ param->eProfile = MEDIAIP_ENC_PROF_H264_MP;
+ break;
+ case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH:
+ vpu_dbg(LVL_CTRL, "set h264 profile high\n");
+ param->eProfile = MEDIAIP_ENC_PROF_H264_HP;
+ break;
+ default:
+ vpu_err("not support H264 profile %d, set to main\n",
+ ctrl->val);
+ param->eProfile = MEDIAIP_ENC_PROF_H264_MP;
+ break;
+ }
+ mutex_unlock(&ctx->instance_mutex);
+
+ return 0;
+}
+
+static int set_h264_level(struct v4l2_ctrl *ctrl)
+{
+ struct vpu_ctx *ctx = v4l2_ctrl_to_ctx(ctrl);
+ struct vpu_attr *attr = get_vpu_ctx_attr(ctx);
+ pMEDIAIP_ENC_PARAM param = &attr->param;
+
+ mutex_lock(&ctx->instance_mutex);
+ param->uLevel = h264_level[ctrl->val];
+ mutex_unlock(&ctx->instance_mutex);
+
+ vpu_dbg(LVL_CTRL, "set h264 level to %d (%d)\n",
+ ctrl->val, h264_level[ctrl->val]);
+
+ return 0;
+}
+
+static int set_bitrate_mode(struct v4l2_ctrl *ctrl)
+{
+ struct vpu_ctx *ctx = v4l2_ctrl_to_ctx(ctrl);
+ struct vpu_attr *attr = get_vpu_ctx_attr(ctx);
+ pMEDIAIP_ENC_PARAM param = &attr->param;
+
+ mutex_lock(&ctx->instance_mutex);
+ switch (ctrl->val) {
+ case V4L2_MPEG_VIDEO_BITRATE_MODE_VBR:
+ vpu_dbg(LVL_CTRL, "set bitrate mode VBR\n");
+ param->eBitRateMode =
+ MEDIAIP_ENC_BITRATECONTROLMODE_CONSTANT_QP;
+ break;
+ case V4L2_MPEG_VIDEO_BITRATE_MODE_CBR:
+ vpu_dbg(LVL_CTRL, "set bitrate mode CBR\n");
+ param->eBitRateMode = MEDIAIP_ENC_BITRATECONTROLMODE_CBR;
+ break;
+ default:
+ vpu_err("not support bitrate mode %d, set to cbr\n",
+ ctrl->val);
+ param->eBitRateMode = MEDIAIP_ENC_BITRATECONTROLMODE_CBR;
+ break;
+ }
+ mutex_unlock(&ctx->instance_mutex);
+
+ return 0;
+}
+
+static int set_bitrate(struct v4l2_ctrl *ctrl)
+{
+ struct vpu_ctx *ctx = v4l2_ctrl_to_ctx(ctrl);
+ struct vpu_attr *attr = get_vpu_ctx_attr(ctx);
+ pMEDIAIP_ENC_PARAM param = &attr->param;
+
+ vpu_dbg(LVL_CTRL, "set bitrate %d\n", ctrl->val);
+ mutex_lock(&ctx->instance_mutex);
+ param->uTargetBitrate = ctrl->val / BITRATE_COEF;
+ if (param->uMaxBitRate < param->uTargetBitrate)
+ param->uMaxBitRate = param->uTargetBitrate;
+ mutex_unlock(&ctx->instance_mutex);
+
+ return 0;
+}
+
+static int set_bitrate_peak(struct v4l2_ctrl *ctrl)
+{
+ struct vpu_ctx *ctx = v4l2_ctrl_to_ctx(ctrl);
+ struct vpu_attr *attr = get_vpu_ctx_attr(ctx);
+ pMEDIAIP_ENC_PARAM param = &attr->param;
+
+ vpu_dbg(LVL_CTRL, "set peak bitrate %d\n", ctrl->val);
+ mutex_lock(&ctx->instance_mutex);
+ param->uMaxBitRate = ctrl->val / BITRATE_COEF;
+ if (param->uTargetBitrate > param->uMaxBitRate)
+ param->uTargetBitrate = param->uMaxBitRate;
+ mutex_unlock(&ctx->instance_mutex);
+
+ return 0;
+}
+
+static int set_gop_size(struct v4l2_ctrl *ctrl)
+{
+ struct vpu_ctx *ctx = v4l2_ctrl_to_ctx(ctrl);
+ struct vpu_attr *attr = get_vpu_ctx_attr(ctx);
+ pMEDIAIP_ENC_PARAM param = &attr->param;
+
+ vpu_dbg(LVL_CTRL, "set gop size %d\n", ctrl->val);
+ mutex_lock(&ctx->instance_mutex);
+ param->uIFrameInterval = ctrl->val;
+ mutex_unlock(&ctx->instance_mutex);
+
+ return 0;
+}
+
+static int set_i_period(struct v4l2_ctrl *ctrl)
+{
+ struct vpu_ctx *ctx = v4l2_ctrl_to_ctx(ctrl);
+ struct vpu_attr *attr = get_vpu_ctx_attr(ctx);
+ pMEDIAIP_ENC_PARAM param = &attr->param;
+
+ vpu_dbg(LVL_CTRL, "set iframe interval %d\n", ctrl->val);
+ mutex_lock(&ctx->instance_mutex);
+ param->uIFrameInterval = ctrl->val;
+ mutex_unlock(&ctx->instance_mutex);
+
+ return 0;
+}
+
+static int get_gop_size(struct v4l2_ctrl *ctrl)
+{
+ struct vpu_ctx *ctx = v4l2_ctrl_to_ctx(ctrl);
+ struct vpu_attr *attr = get_vpu_ctx_attr(ctx);
+ pMEDIAIP_ENC_PARAM param = &attr->param;
+
+ vpu_dbg(LVL_CTRL, "get gop size\n");
+ ctrl->val = param->uIFrameInterval;
+
+ return 0;
+}
+
+static int set_b_frames(struct v4l2_ctrl *ctrl)
+{
+ struct vpu_ctx *ctx = v4l2_ctrl_to_ctx(ctrl);
+ struct vpu_attr *attr = get_vpu_ctx_attr(ctx);
+ pMEDIAIP_ENC_PARAM param = &attr->param;
+
+ vpu_dbg(LVL_CTRL, "set bframes %d\n", ctrl->val);
+ mutex_lock(&ctx->instance_mutex);
+ param->uGopBLength = ctrl->val;
+ mutex_unlock(&ctx->instance_mutex);
+
+ return 0;
+}
+
+static int set_qp(struct v4l2_ctrl *ctrl)
+{
+ struct vpu_ctx *ctx = v4l2_ctrl_to_ctx(ctrl);
+ struct vpu_attr *attr = get_vpu_ctx_attr(ctx);
+ pMEDIAIP_ENC_PARAM param = &attr->param;
+
+ vpu_dbg(LVL_CTRL, "set qp %d\n", ctrl->val);
+ mutex_lock(&ctx->instance_mutex);
+ param->uInitSliceQP = ctrl->val;
+ mutex_unlock(&ctx->instance_mutex);
+
+ return 0;
+}
+
+static int get_min_buffers_for_output(struct v4l2_ctrl *ctrl)
+{
+ vpu_dbg(LVL_CTRL, "get min buffers for output\n");
+
+ ctrl->val = MIN_BUFFER_COUNT;
+
+ return 0;
+}
+
+static int set_display_re_ordering(struct v4l2_ctrl *ctrl)
+{
+ struct vpu_ctx *ctx = v4l2_ctrl_to_ctx(ctrl);
+ struct vpu_attr *attr = get_vpu_ctx_attr(ctx);
+ pMEDIAIP_ENC_PARAM param = &attr->param;
+
+ vpu_dbg(LVL_CTRL, "set lowlatencymode %d\n", ctrl->val);
+ mutex_lock(&ctx->instance_mutex);
+ if (ctrl->val)
+ param->uLowLatencyMode = 1;
+ else
+ param->uLowLatencyMode = 0;
+ mutex_unlock(&ctx->instance_mutex);
+
+ return 0;
+}
+
+static int set_force_key_frame(struct v4l2_ctrl *ctrl)
+{
+ struct vpu_ctx *ctx = v4l2_ctrl_to_ctx(ctrl);
+
+ vpu_dbg(LVL_CTRL, "force key frame\n");
+ set_bit(VPU_ENC_STATUS_KEY_FRAME, &ctx->status);
+
+ return 0;
+}
+
+static int add_ctrl_h264_profile(struct vpu_ctx *ctx)
+{
+ static const struct v4l2_ctrl_ops ctrl_h264_profile_ops = {
+ .s_ctrl = set_h264_profile,
+ };
+ struct v4l2_ctrl *ctrl;
+
+ ctrl = v4l2_ctrl_new_std_menu(&ctx->ctrl_handler,
+ &ctrl_h264_profile_ops,
+ V4L2_CID_MPEG_VIDEO_H264_PROFILE,
+ V4L2_MPEG_VIDEO_H264_PROFILE_HIGH,
+ 0xa,
+ V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE);
+ if (!ctrl) {
+ vpu_err("add ctrl h264 profile fail\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int add_ctrl_h264_level(struct vpu_ctx *ctx)
+{
+ static const struct v4l2_ctrl_ops ctrl_h264_level_ops = {
+ .s_ctrl = set_h264_level,
+ };
+ struct v4l2_ctrl *ctrl;
+
+ ctrl = v4l2_ctrl_new_std_menu(&ctx->ctrl_handler,
+ &ctrl_h264_level_ops,
+ V4L2_CID_MPEG_VIDEO_H264_LEVEL,
+ V4L2_MPEG_VIDEO_H264_LEVEL_5_1,
+ 0x0,
+ V4L2_MPEG_VIDEO_H264_LEVEL_4_0);
+ if (!ctrl) {
+ vpu_err("add ctrl h264 level fail\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int add_ctrl_bitrate_mode(struct vpu_ctx *ctx)
+{
+ static const struct v4l2_ctrl_ops ctrl_bitrate_mode_ops = {
+ .s_ctrl = set_bitrate_mode,
+ };
+ struct v4l2_ctrl *ctrl;
+
+ ctrl = v4l2_ctrl_new_std_menu(&ctx->ctrl_handler,
+ &ctrl_bitrate_mode_ops,
+ V4L2_CID_MPEG_VIDEO_BITRATE_MODE,
+ V4L2_MPEG_VIDEO_BITRATE_MODE_CBR,
+ 0x0,
+ V4L2_MPEG_VIDEO_BITRATE_MODE_VBR);
+ if (!ctrl) {
+ vpu_err("add ctrl bitrate mode fail\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int add_ctrl_bitrate(struct vpu_ctx *ctx)
+{
+ static const struct v4l2_ctrl_ops ctrl_bitrate_ops = {
+ .s_ctrl = set_bitrate,
+ };
+ struct v4l2_ctrl *ctrl;
+
+ ctrl = v4l2_ctrl_new_std(&ctx->ctrl_handler,
+ &ctrl_bitrate_ops,
+ V4L2_CID_MPEG_VIDEO_BITRATE,
+ BITRATE_LOW_THRESHOLD * BITRATE_COEF,
+ BITRATE_HIGH_THRESHOLD * BITRATE_COEF,
+ BITRATE_COEF,
+ BITRATE_DEFAULT_TARGET * BITRATE_COEF);
+ if (!ctrl) {
+ vpu_err("add ctrl bitrate fail\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int add_ctrl_bitrate_peak(struct vpu_ctx *ctx)
+{
+ static const struct v4l2_ctrl_ops ctrl_bitrate_ops = {
+ .s_ctrl = set_bitrate_peak,
+ };
+ struct v4l2_ctrl *ctrl;
+
+ ctrl = v4l2_ctrl_new_std(&ctx->ctrl_handler,
+ &ctrl_bitrate_ops,
+ V4L2_CID_MPEG_VIDEO_BITRATE_PEAK,
+ BITRATE_LOW_THRESHOLD * BITRATE_COEF,
+ BITRATE_HIGH_THRESHOLD * BITRATE_COEF,
+ BITRATE_COEF,
+ BITRATE_DEFAULT_PEAK * BITRATE_COEF);
+ if (!ctrl) {
+ vpu_err("add ctrl bitrate peak fail\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int add_ctrl_gop_size(struct vpu_ctx *ctx)
+{
+ static const struct v4l2_ctrl_ops ctrl_gop_ops = {
+ .s_ctrl = set_gop_size,
+ .g_volatile_ctrl = get_gop_size,
+ };
+ struct v4l2_ctrl *ctrl;
+
+ ctrl = v4l2_ctrl_new_std(&ctx->ctrl_handler,
+ &ctrl_gop_ops,
+ V4L2_CID_MPEG_VIDEO_GOP_SIZE,
+ GOP_L_THRESHOLD,
+ GOP_H_THRESHOLD,
+ 1,
+ GOP_DEFAULT);
+ if (!ctrl) {
+ vpu_err("add ctrl gop size fail\n");
+ return -EINVAL;
+ }
+
+ ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE;
+ ctrl->flags |= V4L2_CTRL_FLAG_EXECUTE_ON_WRITE;
+
+ return 0;
+}
+
+static int add_ctrl_i_period(struct vpu_ctx *ctx)
+{
+ static const struct v4l2_ctrl_ops ctrl_i_period_ops = {
+ .s_ctrl = set_i_period,
+ .g_volatile_ctrl = get_gop_size,
+ };
+ struct v4l2_ctrl *ctrl;
+
+ ctrl = v4l2_ctrl_new_std(&ctx->ctrl_handler,
+ &ctrl_i_period_ops,
+ V4L2_CID_MPEG_VIDEO_H264_I_PERIOD,
+ GOP_L_THRESHOLD,
+ GOP_H_THRESHOLD,
+ 1,
+ GOP_DEFAULT);
+
+ if (!ctrl) {
+ vpu_err("add ctrl i period fail\n");
+ return -EINVAL;
+ }
+
+ ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE;
+ ctrl->flags |= V4L2_CTRL_FLAG_EXECUTE_ON_WRITE;
+
+ return 0;
+}
+
+static int add_ctrl_b_frames(struct vpu_ctx *ctx)
+{
+ static const struct v4l2_ctrl_ops ctrl_b_frames = {
+ .s_ctrl = set_b_frames,
+ };
+ struct v4l2_ctrl *ctrl;
+
+ ctrl = v4l2_ctrl_new_std(&ctx->ctrl_handler,
+ &ctrl_b_frames,
+ V4L2_CID_MPEG_VIDEO_B_FRAMES,
+ BFRAMES_L_THRESHOLD,
+ BFRAMES_H_THRESHOLD,
+ 1,
+ BFRAMES_DEFAULT);
+
+ if (!ctrl) {
+ vpu_err("add ctrl b frames fail\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int add_ctrl_i_frame_qp(struct vpu_ctx *ctx)
+{
+ static const struct v4l2_ctrl_ops ctrl_iframe_qp_ops = {
+ .s_ctrl = set_qp,
+ };
+ struct v4l2_ctrl *ctrl;
+
+ ctrl = v4l2_ctrl_new_std(&ctx->ctrl_handler,
+ &ctrl_iframe_qp_ops,
+ V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP,
+ QP_MIN,
+ QP_MAX,
+ 1,
+ QP_DEFAULT);
+ if (!ctrl) {
+ vpu_err("add ctrl h264 I frame qp fail\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int add_ctrl_p_frame_qp(struct vpu_ctx *ctx)
+{
+ static const struct v4l2_ctrl_ops ctrl_pframe_qp_ops = {
+ .s_ctrl = set_qp,
+ };
+ struct v4l2_ctrl *ctrl;
+
+ ctrl = v4l2_ctrl_new_std(&ctx->ctrl_handler,
+ &ctrl_pframe_qp_ops,
+ V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP,
+ QP_MIN,
+ QP_MAX,
+ 1,
+ QP_DEFAULT);
+ if (!ctrl) {
+ vpu_err("add ctrl h264 P frame qp fail\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int add_ctrl_b_frame_qp(struct vpu_ctx *ctx)
+{
+ static const struct v4l2_ctrl_ops ctrl_bframe_qp_ops = {
+ .s_ctrl = set_qp,
+ };
+ struct v4l2_ctrl *ctrl;
+
+ ctrl = v4l2_ctrl_new_std(&ctx->ctrl_handler,
+ &ctrl_bframe_qp_ops,
+ V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP,
+ QP_MIN,
+ QP_MAX,
+ 1,
+ QP_DEFAULT);
+ if (!ctrl) {
+ vpu_err("add ctrl h264 B frame qp fail\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int add_ctrl_min_buffers_for_output(struct vpu_ctx *ctx)
+{
+ static const struct v4l2_ctrl_ops ctrl_min_buffers_ops = {
+ .g_volatile_ctrl = get_min_buffers_for_output,
+ };
+ struct v4l2_ctrl *ctrl;
+
+ ctrl = v4l2_ctrl_new_std(&ctx->ctrl_handler,
+ &ctrl_min_buffers_ops,
+ V4L2_CID_MIN_BUFFERS_FOR_OUTPUT,
+ 1,
+ 32,
+ 1,
+ MIN_BUFFER_COUNT);
+ if (!ctrl) {
+ vpu_err("add ctrl min buffers for output fail\n");
+ return -EINVAL;
+ }
+
+ ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE;
+
+ return 0;
+}
+
+static int add_ctrl_display_re_ordering(struct vpu_ctx *ctx)
+{
+ static const struct v4l2_ctrl_ops re_ordering_ops = {
+ .s_ctrl = set_display_re_ordering,
+ };
+ struct v4l2_ctrl *ctrl;
+
+ ctrl = v4l2_ctrl_new_std(&ctx->ctrl_handler,
+ &re_ordering_ops,
+ V4L2_CID_MPEG_VIDEO_H264_ASO,
+ 0, 1, 1, 1);
+ if (!ctrl) {
+ vpu_err("add ctrl display re ordering fail\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int add_ctrl_force_key_frame(struct vpu_ctx *ctx)
+{
+ static const struct v4l2_ctrl_ops force_key_frame_ops = {
+ .s_ctrl = set_force_key_frame,
+ };
+ struct v4l2_ctrl *ctrl;
+
+ ctrl = v4l2_ctrl_new_std(&ctx->ctrl_handler,
+ &force_key_frame_ops,
+ V4L2_CID_MPEG_VIDEO_FORCE_KEY_FRAME,
+ 0, 0, 0, 0);
+ if (!ctrl) {
+ vpu_err("add ctrl force key frame fail\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int vpu_enc_register_ctrls(struct vpu_ctx *ctx)
+{
+ add_ctrl_h264_profile(ctx);
+ add_ctrl_h264_level(ctx);
+ add_ctrl_bitrate_mode(ctx);
+ add_ctrl_bitrate(ctx);
+ add_ctrl_bitrate_peak(ctx);
+ add_ctrl_gop_size(ctx);
+ add_ctrl_i_period(ctx);
+ add_ctrl_b_frames(ctx);
+ add_ctrl_i_frame_qp(ctx);
+ add_ctrl_p_frame_qp(ctx);
+ add_ctrl_b_frame_qp(ctx);
+ add_ctrl_min_buffers_for_output(ctx);
+ add_ctrl_display_re_ordering(ctx);
+ add_ctrl_force_key_frame(ctx);
+
+ return 0;
+}
+
+int vpu_enc_setup_ctrls(struct vpu_ctx *ctx)
+{
+ vpu_log_func();
+
+ v4l2_ctrl_handler_init(&ctx->ctrl_handler, 11);
+ vpu_enc_register_ctrls(ctx);
+ if (ctx->ctrl_handler.error) {
+ vpu_err("control initialization error (%d)\n",
+ ctx->ctrl_handler.error);
+ return -EINVAL;
+ }
+ ctx->ctrl_inited = true;
+ return v4l2_ctrl_handler_setup(&ctx->ctrl_handler);
+}
+
+int vpu_enc_free_ctrls(struct vpu_ctx *ctx)
+{
+ vpu_log_func();
+
+ if (ctx->ctrl_inited) {
+ v4l2_ctrl_handler_free(&ctx->ctrl_handler);
+ ctx->ctrl_inited = false;
+ }
+
+ return 0;
+}
diff --git a/drivers/mxc/vpu_windsor/vpu_encoder_ctrl.h b/drivers/mxc/vpu_windsor/vpu_encoder_ctrl.h
new file mode 100644
index 000000000000..5fc98187dc6d
--- /dev/null
+++ b/drivers/mxc/vpu_windsor/vpu_encoder_ctrl.h
@@ -0,0 +1,19 @@
+/*
+ * Copyright(c) 2018 NXP. All rights reserved.
+ *
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * vpu_encoder_ctrl.h
+ *
+ * Author Ming Qian<ming.qian@nxp.com>
+ */
+#ifndef _VPU_ENCODER_CTRL_H
+#define _VPU_ENCODER_CTRL_H
+
+#include "mediasys_types.h"
+
+int vpu_enc_setup_ctrls(struct vpu_ctx *ctx);
+int vpu_enc_free_ctrls(struct vpu_ctx *ctx);
+
+#endif
diff --git a/drivers/mxc/vpu_windsor/vpu_encoder_mem.c b/drivers/mxc/vpu_windsor/vpu_encoder_mem.c
new file mode 100644
index 000000000000..ab8d09d5aa20
--- /dev/null
+++ b/drivers/mxc/vpu_windsor/vpu_encoder_mem.c
@@ -0,0 +1,619 @@
+/*
+ * Copyright(c) 2018 NXP. All rights reserved.
+ *
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * vpu_encoder_mem.c
+ *
+ * Author Ming Qian<ming.qian@nxp.com>
+ */
+
+#define TAG "[VPU Encoder Mem]\t "
+#include <linux/kernel.h>
+#include <linux/dma-mapping.h>
+#include "vpu_encoder_config.h"
+#include "vpu_encoder_b0.h"
+#include "vpu_encoder_mem.h"
+
+int vpu_enc_init_reserved_memory(struct vpu_enc_mem_info *info)
+{
+ if (!info || !info->phy_addr || !info->size)
+ return -EINVAL;
+
+ info->virt_addr = ioremap_wc(info->phy_addr, info->size);
+ if (!info->virt_addr)
+ return -EINVAL;
+ memset_io(info->virt_addr, 0, info->size);
+ info->bytesused = 0;
+ INIT_LIST_HEAD(&info->memorys);
+ spin_lock_init(&info->lock);
+
+ return 0;
+}
+
+void vpu_enc_release_reserved_memory(struct vpu_enc_mem_info *info)
+{
+ struct vpu_enc_mem_item *item = NULL;
+ struct vpu_enc_mem_item *tmp = NULL;
+
+ if (!info)
+ return;
+
+ spin_lock(&info->lock);
+ list_for_each_entry_safe(item, tmp, &info->memorys, list) {
+ list_del_init(&item->list);
+ info->bytesused -= item->size;
+ vpu_dbg(LVL_MEM, "free reserved memory %ld\n", item->size);
+ VPU_SAFE_RELEASE(item, vfree);
+ }
+ spin_unlock(&info->lock);
+
+ if (info->virt_addr) {
+ iounmap(info->virt_addr);
+ info->virt_addr = NULL;
+ }
+}
+
+int vpu_enc_alloc_reserved_mem(struct vpu_enc_mem_info *info,
+ struct buffer_addr *buffer)
+{
+ struct vpu_enc_mem_item *item = NULL;
+ struct list_head *pos = NULL;
+ unsigned long offset = 0;
+ int ret;
+
+ if (!info || !buffer)
+ return -EINVAL;
+
+ spin_lock(&info->lock);
+ if (buffer->size + info->bytesused > info->size) {
+ ret = -ENOMEM;
+ goto exit;
+ }
+
+ list_for_each_entry(item, &info->memorys, list) {
+ if (item->offset - offset >= buffer->size) {
+ pos = &item->list;
+ break;
+ }
+ offset = item->offset + item->size;
+ }
+ if (!pos && info->size - offset >= buffer->size)
+ pos = &info->memorys;
+ if (!pos) {
+ ret = -ENOMEM;
+ goto exit;
+ }
+ item = vzalloc(sizeof(*item));
+ if (!item) {
+ ret = -EINVAL;
+ goto exit;
+ }
+ item->offset = offset;
+ item->virt_addr = info->virt_addr + offset;
+ item->phy_addr = info->phy_addr + offset;
+ item->size = buffer->size;
+ list_add_tail(&item->list, pos);
+ info->bytesused += buffer->size;
+ vpu_dbg(LVL_MEM, "alloc reserved memory <0x%lx 0x%lx(%ld)>\n",
+ item->phy_addr, item->size, item->size);
+ buffer->virt_addr = item->virt_addr;
+ buffer->phy_addr = item->phy_addr;
+ ret = 0;
+exit:
+ spin_unlock(&info->lock);
+ return ret;
+}
+
+int vpu_enc_free_reserved_mem(struct vpu_enc_mem_info *info,
+ struct buffer_addr *buffer)
+{
+ struct vpu_enc_mem_item *item = NULL;
+ struct vpu_enc_mem_item *tmp = NULL;
+ unsigned long offset;
+ int ret = -EINVAL;
+
+ if (!info || !buffer)
+ return -EINVAL;
+ if (!buffer->virt_addr)
+ return 0;
+
+ if (buffer->phy_addr < info->phy_addr) {
+ vpu_err("invalid reserved memory addr : 0x%llx %d\n",
+ buffer->phy_addr, buffer->size);
+ return -EINVAL;
+ }
+
+ offset = buffer->phy_addr - info->phy_addr;
+ if (offset + buffer->size > info->size) {
+ vpu_err("invalid reserved memory addr : 0x%llx %d\n",
+ buffer->phy_addr, buffer->size);
+ return -EINVAL;
+ }
+
+ spin_lock(&info->lock);
+ list_for_each_entry_safe(item, tmp, &info->memorys, list) {
+ if (offset < item->offset)
+ continue;
+ if (offset + buffer->size > item->offset + item->size)
+ continue;
+ list_del_init(&item->list);
+ info->bytesused -= item->size;
+ vpu_dbg(LVL_MEM, "free reserved memory <0x%lx 0x%lx(%ld)>\n",
+ item->phy_addr, item->size, item->size);
+ VPU_SAFE_RELEASE(item, vfree);
+ ret = 0;
+ break;
+ }
+ spin_unlock(&info->lock);
+
+ return ret;
+}
+
+void vpu_enc_add_dma_size(struct vpu_attr *attr, unsigned long size)
+{
+ if (!attr)
+ return;
+
+ atomic64_add(size, &attr->total_dma_size);
+}
+
+void vpu_enc_sub_dma_size(struct vpu_attr *attr, unsigned long size)
+{
+ if (!attr)
+ return;
+
+ atomic64_sub(size, &attr->total_dma_size);
+}
+
+int vpu_enc_alloc_dma_buffer(struct vpu_ctx *ctx, struct buffer_addr *buffer)
+{
+ if (!ctx || !ctx->dev || !buffer || !buffer->size)
+ return -EINVAL;
+
+ vpu_dbg(LVL_MEM, "alloc coherent dma %d\n", buffer->size);
+ buffer->virt_addr = dma_alloc_coherent(ctx->dev->generic_dev,
+ buffer->size,
+ (dma_addr_t *)&buffer->phy_addr,
+ GFP_KERNEL | GFP_DMA32);
+ if (!buffer->virt_addr) {
+ vpu_err("encoder alloc coherent dma(%d) fail\n",
+ buffer->size);
+ return -ENOMEM;
+ }
+ memset_io(buffer->virt_addr, 0, buffer->size);
+ vpu_enc_add_dma_size(get_vpu_ctx_attr(ctx), buffer->size);
+
+ return 0;
+}
+
+void vpu_enc_init_dma_buffer(struct buffer_addr *buffer)
+{
+ if (!buffer)
+ return;
+
+ buffer->virt_addr = NULL;
+ buffer->phy_addr = 0;
+ buffer->size = 0;
+}
+
+int vpu_enc_free_dma_buffer(struct vpu_ctx *ctx, struct buffer_addr *buffer)
+{
+ if (!ctx || !ctx->dev || !buffer)
+ return -EINVAL;
+
+ if (!buffer->virt_addr)
+ return 0;
+
+ vpu_dbg(LVL_MEM, "free coherent dma %d\n", buffer->size);
+ vpu_enc_sub_dma_size(get_vpu_ctx_attr(ctx), buffer->size);
+ dma_free_coherent(ctx->dev->generic_dev, buffer->size,
+ buffer->virt_addr, buffer->phy_addr);
+
+ vpu_enc_init_dma_buffer(buffer);
+
+ return 0;
+}
+
+static bool check_mem_resource_is_valid(MEDIAIP_ENC_MEM_RESOURCE *resource)
+{
+ if (!resource)
+ return false;
+ if (resource->uMemVirtAddr >= VPU_MU_MAX_ADDRESS)
+ return false;
+ if (resource->uMemVirtAddr + resource->uMemSize > VPU_MU_MAX_ADDRESS)
+ return false;
+ return true;
+}
+
+static u32 get_enc_alloc_size(u32 size)
+{
+ u32 esize = ALIGN(size, PAGE_SIZE);
+
+ if (esize < size + sizeof(u32))
+ esize += PAGE_SIZE;
+
+ return esize;
+}
+
+static int alloc_mem_res(struct vpu_ctx *ctx, struct buffer_addr *buffer,
+ MEDIAIP_ENC_MEM_RESOURCE *resource, u32 size)
+{
+ int ret;
+
+ if (!ctx || !buffer || !resource)
+ return -EINVAL;
+
+ if (!size) {
+ vpu_err("invalid memory resource size : %d\n", size);
+ return -EINVAL;
+ }
+
+ buffer->size = get_enc_alloc_size(size);
+ ret = vpu_enc_alloc_dma_buffer(ctx, buffer);
+ if (ret)
+ return ret;
+
+ resource->uMemPhysAddr = buffer->phy_addr;
+ resource->uMemVirtAddr = cpu_phy_to_mu(ctx->core_dev, buffer->phy_addr);
+ resource->uMemSize = size;
+
+ return 0;
+}
+
+static int free_mem_res(struct vpu_ctx *ctx, struct buffer_addr *buffer,
+ MEDIAIP_ENC_MEM_RESOURCE *resource)
+{
+ if (!ctx || !buffer || !resource)
+ return -EINVAL;
+
+ vpu_enc_free_dma_buffer(ctx, buffer);
+
+ resource->uMemPhysAddr = 0;
+ resource->uMemVirtAddr = 0;
+ resource->uMemSize = 0;
+
+ return 0;
+}
+
+static int alloc_reserved_mem_res(struct vpu_ctx *ctx,
+ struct buffer_addr *buffer,
+ MEDIAIP_ENC_MEM_RESOURCE *resource,
+ u32 size)
+{
+ int ret;
+
+ if (!ctx || !ctx->dev || !buffer || !resource)
+ return -EINVAL;
+
+ if (!size) {
+ vpu_err("invalid memory resource size : %d\n", size);
+ return -EINVAL;
+ }
+
+ buffer->size = get_enc_alloc_size(size);
+ ret = vpu_enc_alloc_reserved_mem(&ctx->dev->reserved_mem, buffer);
+ if (ret)
+ return ret;
+
+ resource->uMemPhysAddr = buffer->phy_addr;
+ resource->uMemVirtAddr = cpu_phy_to_mu(ctx->core_dev, buffer->phy_addr);
+ resource->uMemSize = size;
+
+ return 0;
+}
+
+static int free_reserved_mem_res(struct vpu_ctx *ctx,
+ struct buffer_addr *buffer,
+ MEDIAIP_ENC_MEM_RESOURCE *resource)
+{
+ if (!ctx || !ctx->dev || !buffer || !resource)
+ return -EINVAL;
+
+ vpu_enc_free_reserved_mem(&ctx->dev->reserved_mem, buffer);
+
+ resource->uMemPhysAddr = 0;
+ resource->uMemVirtAddr = 0;
+ resource->uMemSize = 0;
+
+ return 0;
+}
+
+static int free_enc_frames(struct vpu_ctx *ctx, pMEDIAIP_ENC_MEM_POOL pool)
+{
+ int i;
+
+ vpu_log_func();
+ for (i = 0; i < ctx->mem_req.uEncFrmNum; i++)
+ free_mem_res(ctx, &ctx->encFrame[i],
+ &pool->tEncFrameBuffers[i]);
+
+ return 0;
+}
+
+static int alloc_enc_frames(struct vpu_ctx *ctx, pMEDIAIP_ENC_MEM_POOL pool)
+{
+ int i;
+ int ret;
+
+ vpu_log_func();
+ for (i = 0; i < ctx->mem_req.uEncFrmNum; i++) {
+ ret = alloc_mem_res(ctx,
+ &ctx->encFrame[i],
+ &pool->tEncFrameBuffers[i],
+ ctx->mem_req.uEncFrmSize);
+ if (ret) {
+ vpu_err("alloc enc frame[%d] fail\n", i);
+ goto error;
+ }
+ vpu_dbg(LVL_MEM, "encFrame[%d]: 0x%llx,%d(%d)\n", i,
+ ctx->encFrame[i].phy_addr,
+ ctx->mem_req.uEncFrmSize,
+ ctx->encFrame[i].size);
+ }
+
+ return 0;
+error:
+ free_enc_frames(ctx, pool);
+ return ret;
+}
+
+static int free_ref_frames(struct vpu_ctx *ctx, pMEDIAIP_ENC_MEM_POOL pool)
+{
+ int i;
+
+ vpu_log_func();
+ for (i = 0; i < ctx->mem_req.uRefFrmNum; i++)
+ free_mem_res(ctx, &ctx->refFrame[i],
+ &pool->tRefFrameBuffers[i]);
+
+ return 0;
+}
+
+static int alloc_ref_frames(struct vpu_ctx *ctx, pMEDIAIP_ENC_MEM_POOL pool)
+{
+ int i;
+ int ret;
+
+ vpu_log_func();
+ for (i = 0; i < ctx->mem_req.uRefFrmNum; i++) {
+ ret = alloc_mem_res(ctx,
+ &ctx->refFrame[i],
+ &pool->tRefFrameBuffers[i],
+ ctx->mem_req.uRefFrmSize);
+ if (ret) {
+ vpu_err("alloc ref frame[%d] fail\n", i);
+ goto error;
+ }
+ vpu_dbg(LVL_MEM, "refFrame[%d]: 0x%llx,%d(%d)\n", i,
+ ctx->refFrame[i].phy_addr,
+ ctx->mem_req.uRefFrmSize,
+ ctx->refFrame[i].size);
+ }
+
+ return 0;
+error:
+ free_ref_frames(ctx, pool);
+ return ret;
+}
+
+static int free_act_frame(struct vpu_ctx *ctx, pMEDIAIP_ENC_MEM_POOL pool)
+{
+ if (!ctx || !pool)
+ return -EINVAL;
+
+ vpu_log_func();
+ free_reserved_mem_res(ctx, &ctx->actFrame, &pool->tActFrameBufferArea);
+
+ return 0;
+}
+
+static int alloc_act_frame(struct vpu_ctx *ctx, pMEDIAIP_ENC_MEM_POOL pool)
+{
+ int ret = 0;
+
+ vpu_log_func();
+ ret = alloc_reserved_mem_res(ctx,
+ &ctx->actFrame,
+ &pool->tActFrameBufferArea,
+ ctx->mem_req.uActBufSize);
+ if (ret) {
+ vpu_err("alloc act frame fail\n");
+ return ret;
+ }
+
+ if (!check_mem_resource_is_valid(&pool->tActFrameBufferArea)) {
+ vpu_err("invalid actFrames address, 0x%x, 0x%x, 0x%x\n",
+ pool->tActFrameBufferArea.uMemPhysAddr,
+ pool->tActFrameBufferArea.uMemVirtAddr,
+ pool->tActFrameBufferArea.uMemSize);
+ free_act_frame(ctx, pool);
+ return -EINVAL;
+ }
+
+ vpu_dbg(LVL_MEM, "actFrame: 0x%llx, %d(%d)\n",
+ ctx->actFrame.phy_addr,
+ ctx->mem_req.uActBufSize,
+ ctx->actFrame.size);
+ return 0;
+}
+
+static void set_mem_pattern(u32 *ptr)
+{
+ if (!ptr)
+ return;
+ *ptr = VPU_MEM_PATTERN;
+}
+
+static int check_mem_pattern(u32 *ptr)
+{
+ if (!ptr)
+ return -EINVAL;
+
+ if (*ptr != VPU_MEM_PATTERN)
+ return -EINVAL;
+
+ return 0;
+}
+
+static void vpu_enc_set_mem_pattern(struct vpu_ctx *ctx)
+{
+ int i;
+
+ if (!ctx)
+ return;
+
+ for (i = 0; i < MEDIAIP_MAX_NUM_WINDSOR_SRC_FRAMES; i++) {
+ if (!ctx->encFrame[i].virt_addr)
+ continue;
+ set_mem_pattern(ctx->encFrame[i].virt_addr +
+ ctx->mem_req.uEncFrmSize);
+ }
+
+ for (i = 0; i < MEDIAIP_MAX_NUM_WINDSOR_REF_FRAMES; i++) {
+ if (!ctx->refFrame[i].virt_addr)
+ continue;
+ set_mem_pattern(ctx->refFrame[i].virt_addr +
+ ctx->mem_req.uRefFrmSize);
+ }
+
+ if (ctx->actFrame.virt_addr)
+ set_mem_pattern(ctx->actFrame.virt_addr +
+ ctx->mem_req.uActBufSize);
+}
+
+int vpu_enc_check_mem_overstep(struct vpu_ctx *ctx)
+{
+ int i;
+ int ret;
+ int flag = 0;
+
+ if (!ctx)
+ return -EINVAL;
+
+ for (i = 0; i < MEDIAIP_MAX_NUM_WINDSOR_SRC_FRAMES; i++) {
+ if (!ctx->encFrame[i].virt_addr)
+ continue;
+ ret = check_mem_pattern(ctx->encFrame[i].virt_addr +
+ ctx->mem_req.uEncFrmSize);
+ if (ret) {
+ vpu_err("***error:[%d][%d]encFrame[%d] out of bounds\n",
+ ctx->core_dev->id, ctx->str_index, i);
+ flag = 1;
+ }
+ }
+
+ for (i = 0; i < MEDIAIP_MAX_NUM_WINDSOR_REF_FRAMES; i++) {
+ if (!ctx->refFrame[i].virt_addr)
+ continue;
+ ret = check_mem_pattern(ctx->refFrame[i].virt_addr +
+ ctx->mem_req.uRefFrmSize);
+ if (ret) {
+ vpu_err("***error:[%d][%d]refFrame[%d] out of bounds\n",
+ ctx->core_dev->id, ctx->str_index, i);
+ flag = 1;
+ }
+ }
+
+ if (ctx->actFrame.virt_addr) {
+ ret = check_mem_pattern(ctx->actFrame.virt_addr +
+ ctx->mem_req.uActBufSize);
+ if (ret) {
+ vpu_err("***error:[%d][%d]actFrame out of bounds\n",
+ ctx->core_dev->id, ctx->str_index);
+ flag = 1;
+ }
+ }
+
+ if (flag) {
+ vpu_err("Error:Memory out of bounds in [%d][%d]\n",
+ ctx->core_dev->id, ctx->str_index);
+ vpu_enc_set_mem_pattern(ctx);
+ }
+
+ return 0;
+}
+
+int vpu_enc_alloc_mem(struct vpu_ctx *ctx,
+ MEDIAIP_ENC_MEM_REQ_DATA *req_data,
+ pMEDIAIP_ENC_MEM_POOL pool)
+{
+ int ret;
+
+ if (!ctx || !req_data || !pool)
+ return -EINVAL;
+
+ if (ctx->mem_req.uEncFrmSize < req_data->uEncFrmSize ||
+ ctx->mem_req.uEncFrmNum < req_data->uEncFrmNum) {
+ free_enc_frames(ctx, pool);
+ ctx->mem_req.uEncFrmSize = req_data->uEncFrmSize;
+ ctx->mem_req.uEncFrmNum = req_data->uEncFrmNum;
+ ret = alloc_enc_frames(ctx, pool);
+ if (ret)
+ return ret;
+ }
+
+ if (ctx->mem_req.uRefFrmSize < req_data->uRefFrmSize ||
+ ctx->mem_req.uRefFrmNum < req_data->uRefFrmNum) {
+ free_ref_frames(ctx, pool);
+ ctx->mem_req.uRefFrmSize = req_data->uRefFrmSize;
+ ctx->mem_req.uRefFrmNum = req_data->uRefFrmNum;
+ ret = alloc_ref_frames(ctx, pool);
+ if (ret)
+ goto error_alloc_refs;
+ }
+
+ if (ctx->mem_req.uActBufSize < req_data->uActBufSize) {
+ free_act_frame(ctx, pool);
+ ctx->mem_req.uActBufSize = req_data->uActBufSize;
+ ret = alloc_act_frame(ctx, pool);
+ if (ret)
+ goto error_alloc_act;
+ }
+
+ vpu_enc_set_mem_pattern(ctx);
+
+ return 0;
+error_alloc_act:
+ free_ref_frames(ctx, pool);
+error_alloc_refs:
+ free_enc_frames(ctx, pool);
+ return ret;
+}
+
+int vpu_enc_free_mem(struct vpu_ctx *ctx, pMEDIAIP_ENC_MEM_POOL pool)
+{
+ if (!ctx || !pool)
+ return -EINVAL;
+
+ free_act_frame(ctx, pool);
+ free_ref_frames(ctx, pool);
+ free_enc_frames(ctx, pool);
+
+ return 0;
+}
+
+int vpu_enc_alloc_stream(struct vpu_ctx *ctx)
+{
+ int ret;
+
+ if (ctx->encoder_stream.virt_addr)
+ return 0;
+
+ ctx->encoder_stream.size = STREAM_SIZE;
+ ret = vpu_enc_alloc_dma_buffer(ctx, &ctx->encoder_stream);
+ if (ret) {
+ vpu_err("alloc encoder stream buffer fail\n");
+ return -ENOMEM;
+ }
+ vpu_dbg(LVL_MEM, "encoder_stream: 0x%llx, %d\n",
+ ctx->encoder_stream.phy_addr, ctx->encoder_stream.size);
+
+ return 0;
+}
+
+void vpu_enc_free_stream(struct vpu_ctx *ctx)
+{
+ vpu_enc_free_dma_buffer(ctx, &ctx->encoder_stream);
+}
diff --git a/drivers/mxc/vpu_windsor/vpu_encoder_mem.h b/drivers/mxc/vpu_windsor/vpu_encoder_mem.h
new file mode 100644
index 000000000000..2423943cc8a9
--- /dev/null
+++ b/drivers/mxc/vpu_windsor/vpu_encoder_mem.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright(c) 2018 NXP. All rights reserved.
+ *
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * vpu_encoder_mem.h
+ *
+ * Author Ming Qian<ming.qian@nxp.com>
+ */
+#ifndef _VPU_ENCODER_MEM_H
+#define _VPU_ENCODER_MEM_H
+
+#include "vpu_encoder_b0.h"
+
+int vpu_enc_init_reserved_memory(struct vpu_enc_mem_info *info);
+void vpu_enc_release_reserved_memory(struct vpu_enc_mem_info *info);
+void vpu_enc_add_dma_size(struct vpu_attr *attr, unsigned long size);
+void vpu_enc_sub_dma_size(struct vpu_attr *attr, unsigned long size);
+int vpu_enc_alloc_dma_buffer(struct vpu_ctx *ctx, struct buffer_addr *buffer);
+int vpu_enc_free_dma_buffer(struct vpu_ctx *ctx, struct buffer_addr *buffer);
+void vpu_enc_init_dma_buffer(struct buffer_addr *buffer);
+int vpu_enc_check_mem_overstep(struct vpu_ctx *ctx);
+int vpu_enc_alloc_mem(struct vpu_ctx *ctx,
+ MEDIAIP_ENC_MEM_REQ_DATA *req_data,
+ pMEDIAIP_ENC_MEM_POOL pool);
+int vpu_enc_free_mem(struct vpu_ctx *ctx, pMEDIAIP_ENC_MEM_POOL pool);
+int vpu_enc_alloc_stream(struct vpu_ctx *ctx);
+void vpu_enc_free_stream(struct vpu_ctx *ctx);
+
+#endif
diff --git a/drivers/mxc/vpu_windsor/vpu_encoder_rpc.c b/drivers/mxc/vpu_windsor/vpu_encoder_rpc.c
new file mode 100644
index 000000000000..f670a940c8db
--- /dev/null
+++ b/drivers/mxc/vpu_windsor/vpu_encoder_rpc.c
@@ -0,0 +1,448 @@
+/*
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2018 NXP. All rights reserved.
+ *
+ * This program 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.
+ *
+ * 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.
+ * The full GNU General Public License is included in this distribution
+ * in the file called LICENSE.GPL.
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2018 NXP. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include "vpu_encoder_rpc.h"
+
+void rpc_init_shared_memory_encoder(struct shared_addr *This,
+ unsigned long long base_phy_addr,
+ void *base_virt_addr,
+ u_int32 total_size,
+ u32 *actual_size)
+{
+ pENC_RPC_HOST_IFACE pSharedInterface;
+ unsigned int phy_addr;
+ unsigned int i;
+ unsigned int temp_addr;
+ BUFFER_DESCRIPTOR_TYPE *pSharedCmdBufDescPtr;
+ BUFFER_DESCRIPTOR_TYPE *pSharedMsgBufDescPtr;
+ pMEDIA_ENC_API_CONTROL_INTERFACE pEncCtrlInterface;
+
+ This->shared_mem_phy = base_phy_addr;
+ This->shared_mem_vir = base_virt_addr;
+ This->base_offset = (unsigned long long)(base_virt_addr - base_phy_addr);
+
+ pSharedInterface = (pENC_RPC_HOST_IFACE)This->shared_mem_vir;
+ This->pSharedInterface = pSharedInterface;
+
+ pSharedInterface->FwExecBaseAddr = base_phy_addr;
+ pSharedInterface->FwExecAreaSize = total_size;
+
+ pSharedCmdBufDescPtr = (BUFFER_DESCRIPTOR_TYPE *)&pSharedInterface->StreamCmdBufferDesc;
+ pSharedMsgBufDescPtr = (BUFFER_DESCRIPTOR_TYPE *)&pSharedInterface->StreamMsgBufferDesc;
+
+ phy_addr = base_phy_addr + sizeof(ENC_RPC_HOST_IFACE);
+ This->cmd_mem_phy = phy_addr;
+ This->cmd_mem_vir = This->shared_mem_vir + sizeof(ENC_RPC_HOST_IFACE);
+
+ pSharedCmdBufDescPtr->wptr = phy_addr;
+ pSharedCmdBufDescPtr->rptr = pSharedCmdBufDescPtr->wptr;
+ pSharedCmdBufDescPtr->start = pSharedCmdBufDescPtr->wptr;
+ pSharedCmdBufDescPtr->end = pSharedCmdBufDescPtr->start + CMD_SIZE;
+
+ phy_addr += CMD_SIZE;
+ This->msg_mem_phy = phy_addr;
+ This->msg_mem_vir = This->cmd_mem_vir + CMD_SIZE;
+
+ pSharedMsgBufDescPtr->wptr = phy_addr;
+ pSharedMsgBufDescPtr->rptr = pSharedMsgBufDescPtr->wptr;
+ pSharedMsgBufDescPtr->start = pSharedMsgBufDescPtr->wptr;
+ pSharedMsgBufDescPtr->end = pSharedMsgBufDescPtr->start + MSG_SIZE;
+
+ phy_addr += MSG_SIZE;
+
+ for (i = 0; i < VID_API_NUM_STREAMS; i++) {
+ pSharedInterface->pEncCtrlInterface[i] = phy_addr;
+ phy_addr += sizeof(MEDIA_ENC_API_CONTROL_INTERFACE);
+ }
+
+ for (i = 0; i < VID_API_NUM_STREAMS; i++) {
+ temp_addr = pSharedInterface->pEncCtrlInterface[i];
+ pEncCtrlInterface = (pMEDIA_ENC_API_CONTROL_INTERFACE)(temp_addr + This->base_offset);
+ pEncCtrlInterface->pEncYUVBufferDesc = phy_addr;
+ phy_addr += sizeof(MEDIAIP_ENC_YUV_BUFFER_DESC);
+ pEncCtrlInterface->pEncStreamBufferDesc = phy_addr;
+ phy_addr += sizeof(BUFFER_DESCRIPTOR_TYPE);
+ pEncCtrlInterface->pEncExpertModeParam = phy_addr;
+ phy_addr += sizeof(MEDIAIP_ENC_EXPERT_MODE_PARAM);
+ pEncCtrlInterface->pEncParam = phy_addr;
+ phy_addr += sizeof(MEDIAIP_ENC_PARAM);
+ pEncCtrlInterface->pEncMemPool = phy_addr;
+ phy_addr += sizeof(MEDIAIP_ENC_MEM_POOL);
+ pEncCtrlInterface->pEncEncodingStatus = phy_addr;
+ phy_addr += sizeof(ENC_ENCODING_STATUS);
+ pEncCtrlInterface->pEncDSAStatus = phy_addr;
+ phy_addr += sizeof(ENC_DSA_STATUS_t);
+ }
+ if (actual_size)
+ *actual_size = phy_addr - base_phy_addr;
+}
+
+void rpc_set_system_cfg_value_encoder(void *Interface, u_int32 regs_base, u_int32 core_id)
+{
+ pENC_RPC_HOST_IFACE pSharedInterface;
+ MEDIAIP_FW_SYSTEM_CONFIG *pSystemCfg;
+
+ pSharedInterface = (pENC_RPC_HOST_IFACE)Interface;
+ pSystemCfg = &pSharedInterface->sSystemCfg;
+ pSystemCfg->uNumWindsors = 1;
+ pSystemCfg->uWindsorIrqPin[0x0][0x0] = 0x4; // PAL_IRQ_WINDSOR_LOW
+ pSystemCfg->uWindsorIrqPin[0x0][0x1] = 0x5; // PAL_IRQ_WINDSOR_HI
+ pSystemCfg->uMaloneBaseAddress[0] = (unsigned int)(regs_base + 0x180000);
+ if (core_id == 0)
+ pSystemCfg->uWindsorBaseAddress[0] = (unsigned int)(regs_base + 0x800000);
+ else
+ pSystemCfg->uWindsorBaseAddress[0] = (unsigned int)(regs_base + 0xa00000);
+ pSystemCfg->uMaloneBaseAddress[0x1] = 0x0;
+ pSystemCfg->uHifOffset[0x0] = 0x1C000;
+ pSystemCfg->uHifOffset[0x1] = 0x0;
+
+ pSystemCfg->uDPVBaseAddr = 0x0;
+ pSystemCfg->uDPVIrqPin = 0x0;
+ pSystemCfg->uPixIfBaseAddr = (unsigned int)(regs_base + 0x180000 + 0x20000);
+ pSystemCfg->uFSLCacheBaseAddr[0] = (unsigned int)(regs_base + 0x60000);
+ pSystemCfg->uFSLCacheBaseAddr[1] = (unsigned int)(regs_base + 0x68000);
+}
+
+u_int32 rpc_MediaIPFW_Video_buffer_space_check_encoder(BUFFER_DESCRIPTOR_TYPE *pBufDesc,
+ BOOL bFull,
+ u_int32 uSize,
+ u_int32 *puUpdateAddress)
+{
+ u_int32 uPtr1;
+ u_int32 uPtr2;
+ u_int32 start;
+ u_int32 end;
+ u_int32 uTemp;
+
+ /* bFull is FALSE when send message, write data */
+ /* bFull is TRUE when process commands, read data */
+ uPtr1 = (bFull) ? pBufDesc->rptr : pBufDesc->wptr;
+ uPtr2 = (bFull) ? pBufDesc->wptr : pBufDesc->rptr;
+
+ if (uPtr1 == uPtr2) {
+ if (bFull)
+ /* No data at all to read */
+ return 0;
+ else {
+ /* wrt pointer equal to read pointer thus the */
+ /* buffer is completely empty for further writes */
+ start = pBufDesc->start;
+ end = pBufDesc->end;
+ /* The address to be returned in this case is for */
+ /* the updated write pointer. */
+ uTemp = uPtr1 + uSize;
+ if (uTemp >= end)
+ uTemp += (start - end);
+ *puUpdateAddress = uTemp;
+ return (end - start);
+ }
+ } else if (uPtr1 < uPtr2) {
+ /* return updated rd pointer address */
+ /* In this case if size was too big - we expect the */
+ /* external ftn to compare the size against the */
+ /* space returned.
+ */
+ *puUpdateAddress = uPtr1 + uSize;
+ return (uPtr2 - uPtr1);
+ }
+ /* We know the system has looped!! */
+ start = pBufDesc->start;
+ end = pBufDesc->end;
+ uTemp = uPtr1 + uSize;
+ if (uTemp >= end)
+ uTemp += (start - end);
+ *puUpdateAddress = uTemp;
+ return ((end - uPtr1) + (uPtr2 - start));
+}
+
+static void rpc_update_cmd_buffer_ptr_encoder(BUFFER_DESCRIPTOR_TYPE *pCmdDesc)
+{
+ u_int32 uWritePtr;
+
+ /*avoid sw reset fail*/
+ mb();
+ uWritePtr = pCmdDesc->wptr + 4;
+ if (uWritePtr >= pCmdDesc->end)
+ uWritePtr = pCmdDesc->start;
+ pCmdDesc->wptr = uWritePtr;
+}
+
+void rpc_send_cmd_buf_encoder(struct shared_addr *This,
+ u_int32 idx,
+ u_int32 cmdid,
+ u_int32 cmdnum,
+ u_int32 *local_cmddata)
+{
+ pENC_RPC_HOST_IFACE pSharedInterface = (pENC_RPC_HOST_IFACE)This->shared_mem_vir;
+ BUFFER_DESCRIPTOR_TYPE *pCmdDesc = &pSharedInterface->StreamCmdBufferDesc;
+ u_int32 *cmddata;
+ u_int32 i;
+ u_int32 *cmdword = (u_int32 *)(This->cmd_mem_vir+pCmdDesc->wptr - pCmdDesc->start);
+
+ *cmdword = 0;
+ *cmdword |= ((idx & 0x000000ff) << 24);
+ *cmdword |= ((cmdnum & 0x000000ff) << 16);
+ *cmdword |= ((cmdid & 0x00003fff) << 0);
+ rpc_update_cmd_buffer_ptr_encoder(pCmdDesc);
+
+ for (i = 0; i < cmdnum; i++) {
+ cmddata = (u_int32 *)(This->cmd_mem_vir+pCmdDesc->wptr - pCmdDesc->start);
+ *cmddata = local_cmddata[i];
+ rpc_update_cmd_buffer_ptr_encoder(pCmdDesc);
+ }
+}
+
+u_int32 rpc_MediaIPFW_Video_message_check_encoder(struct shared_addr *This)
+{
+ u_int32 uSpace;
+ u_int32 uIgnore;
+ pENC_RPC_HOST_IFACE pSharedInterface = (pENC_RPC_HOST_IFACE)This->shared_mem_vir;
+ BUFFER_DESCRIPTOR_TYPE *pMsgDesc = &pSharedInterface->StreamMsgBufferDesc;
+ u_int32 msgword;
+ u_int32 msgnum;
+
+ uSpace = rpc_MediaIPFW_Video_buffer_space_check_encoder(pMsgDesc, TRUE, 0, &uIgnore);
+ uSpace = (uSpace >> 2);
+ if (uSpace) {
+ /* get current msgword word */
+ msgword = *((u_int32 *)(This->msg_mem_vir+pMsgDesc->rptr - pMsgDesc->start));
+ /* Find the number of additional words */
+ msgnum = ((msgword & 0x00ff0000) >> 16);
+
+ /*
+ * * Check the number of message words against
+ * * 1) a limit - some sort of maximum or at least
+ * * the size of the SW buffer the message is read into
+ * * 2) The space reported (where space is write ptr - read ptr in 32bit words)
+ * * It must be less than space (as opposed to <=) because
+ * * the message itself is not included in msgword
+ */
+ if (msgnum < VID_API_MESSAGE_LIMIT) {
+ if (msgnum < uSpace)
+ return API_MSG_AVAILABLE;
+ else
+ return API_MSG_INCOMPLETE;
+ } else
+ return API_MSG_BUFFER_ERROR;
+ }
+ return API_MSG_UNAVAILABLE;
+}
+
+static void rpc_update_msg_buffer_ptr_encoder(BUFFER_DESCRIPTOR_TYPE *pMsgDesc)
+{
+ u_int32 uReadPtr;
+
+ uReadPtr = pMsgDesc->rptr + 4;
+ if (uReadPtr >= pMsgDesc->end)
+ uReadPtr = pMsgDesc->start;
+ pMsgDesc->rptr = uReadPtr;
+}
+
+u32 rpc_read_msg_u32(struct shared_addr *shared_mem)
+{
+ u32 msgword;
+ u32 *ptr = NULL;
+ pENC_RPC_HOST_IFACE iface = NULL;
+ BUFFER_DESCRIPTOR_TYPE *msg_buf = NULL;
+
+ if (!shared_mem)
+ return 0;
+
+ iface = shared_mem->pSharedInterface;
+ msg_buf = &iface->StreamMsgBufferDesc;
+ ptr = shared_mem->msg_mem_vir + msg_buf->rptr - msg_buf->start;
+ rpc_update_msg_buffer_ptr_encoder(msg_buf);
+ msgword = *ptr;
+
+ return msgword;
+}
+
+int rpc_read_msg_array(struct shared_addr *shared_mem, u32 *buf, u32 number)
+{
+ int i;
+ u32 val;
+
+ if (!shared_mem)
+ return -EINVAL;
+
+ for (i = 0; i < number; i++) {
+ val = rpc_read_msg_u32(shared_mem);
+ if (buf)
+ buf[i] = val;
+ }
+
+ return 0;
+}
+
+int rpc_get_msg_header(struct shared_addr *shared_mem, struct msg_header *msg)
+{
+ u32 msgword;
+
+ if (!shared_mem || !msg)
+ return -EINVAL;
+
+ msgword = rpc_read_msg_u32(shared_mem);
+ msg->idx = ((msgword & 0xff000000) >> 24);
+ msg->msgnum = ((msgword & 0x00ff0000) >> 16);
+ msg->msgid = ((msgword & 0x00003fff) >> 0);
+
+ return 0;
+}
+
+static void *phy_to_virt(u_int32 src, unsigned long long offset)
+{
+ void *result;
+
+ result = (void *)(src + offset);
+ return result;
+}
+
+#define GET_CTRL_INTERFACE_MEMBER(shared_mem, index, name, member) \
+ do {\
+ pENC_RPC_HOST_IFACE iface = shared_mem->pSharedInterface; \
+ pMEDIA_ENC_API_CONTROL_INTERFACE ctrl_interface =\
+ phy_to_virt(iface->pEncCtrlInterface[index],\
+ shared_mem->base_offset);\
+ name = phy_to_virt(ctrl_interface->member,\
+ shared_mem->base_offset);\
+ } while (0)
+
+pMEDIAIP_ENC_YUV_BUFFER_DESC rpc_get_yuv_buffer_desc(
+ struct shared_addr *shared_mem, int index)
+{
+ pMEDIAIP_ENC_YUV_BUFFER_DESC desc = NULL;
+
+ GET_CTRL_INTERFACE_MEMBER(shared_mem, index, desc, pEncYUVBufferDesc);
+
+ return desc;
+}
+
+pBUFFER_DESCRIPTOR_TYPE rpc_get_stream_buffer_desc(
+ struct shared_addr *shared_mem, int index)
+{
+ pBUFFER_DESCRIPTOR_TYPE desc = NULL;
+
+ GET_CTRL_INTERFACE_MEMBER(shared_mem, index,
+ desc, pEncStreamBufferDesc);
+
+ return desc;
+}
+
+pMEDIAIP_ENC_EXPERT_MODE_PARAM rpc_get_expert_mode_param(
+ struct shared_addr *shared_mem, int index)
+{
+ pMEDIAIP_ENC_EXPERT_MODE_PARAM param = NULL;
+
+ GET_CTRL_INTERFACE_MEMBER(shared_mem, index,
+ param, pEncExpertModeParam);
+
+ return param;
+}
+
+pMEDIAIP_ENC_PARAM rpc_get_enc_param(
+ struct shared_addr *shared_mem, int index)
+{
+ pMEDIAIP_ENC_PARAM param = NULL;
+
+ GET_CTRL_INTERFACE_MEMBER(shared_mem, index, param, pEncParam);
+
+ return param;
+}
+
+pMEDIAIP_ENC_MEM_POOL rpc_get_mem_pool(
+ struct shared_addr *shared_mem, int index)
+{
+ pMEDIAIP_ENC_MEM_POOL pool = NULL;
+
+ GET_CTRL_INTERFACE_MEMBER(shared_mem, index, pool, pEncMemPool);
+
+ return pool;
+}
+
+pENC_ENCODING_STATUS rpc_get_encoding_status(
+ struct shared_addr *shared_mem, int index)
+{
+ pENC_ENCODING_STATUS encoding_status = NULL;
+
+ GET_CTRL_INTERFACE_MEMBER(shared_mem, index,
+ encoding_status, pEncEncodingStatus);
+
+ return encoding_status;
+}
+
+pENC_DSA_STATUS_t rpc_get_dsa_status(struct shared_addr *shared_mem, int index)
+{
+ pENC_DSA_STATUS_t dsa_status = NULL;
+
+ GET_CTRL_INTERFACE_MEMBER(shared_mem, index, dsa_status, pEncDSAStatus);
+
+ return dsa_status;
+}
+
+void rpc_set_print_buffer(struct shared_addr *shared_mem,
+ unsigned long print_phy_addr, u32 size)
+{
+ pENC_RPC_HOST_IFACE pSharedInterface;
+ pBUFFER_DESCRIPTOR_TYPE debugBufDesc;
+
+
+ pSharedInterface = shared_mem->pSharedInterface;
+ debugBufDesc = &pSharedInterface->DebugBufferDesc;
+
+ debugBufDesc->start = print_phy_addr;
+ debugBufDesc->end = debugBufDesc->start + size;
+ debugBufDesc->wptr = debugBufDesc->rptr = debugBufDesc->start;
+}
diff --git a/drivers/mxc/vpu_windsor/vpu_encoder_rpc.h b/drivers/mxc/vpu_windsor/vpu_encoder_rpc.h
new file mode 100644
index 000000000000..934b542a4929
--- /dev/null
+++ b/drivers/mxc/vpu_windsor/vpu_encoder_rpc.h
@@ -0,0 +1,132 @@
+/*
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2018 NXP. All rights reserved.
+ *
+ * This program 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.
+ *
+ * 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.
+ * The full GNU General Public License is included in this distribution
+ * in the file called LICENSE.GPL.
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2018 NXP. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __VPU_ENCODER_RPC_H__
+#define __VPU_ENCODER_RPC_H__
+
+#include "mediasys_types.h"
+
+#define CMD_SIZE 2560
+#define MSG_SIZE 25600
+#define CODEC_SIZE 0x1000
+#define JPEG_SIZE 0x1000
+#define SEQ_SIZE 0x1000
+#define GOP_SIZE 0x1000
+#define PIC_SIZE 0x1000
+#define QMETER_SIZE 0x1000
+#define DEBUG_SIZE 0x1000
+#define ENG_SIZE 0x1000
+#define LOCAL_MSG_NUM VID_API_MESSAGE_LIMIT
+
+struct shared_addr {
+ pENC_RPC_HOST_IFACE pSharedInterface;
+ unsigned long long shared_mem_phy;
+ void *shared_mem_vir;
+ unsigned long long cmd_mem_phy;
+ void *cmd_mem_vir;
+ unsigned long long msg_mem_phy;
+ void *msg_mem_vir;
+ unsigned long long codec_mem_phy;
+ void *codec_mem_vir;
+ unsigned long long jpeg_mem_phy;
+ void *jpeg_mem_vir;
+ unsigned long long seq_mem_phy;
+ void *seq_mem_vir;
+ unsigned long long pic_mem_phy;
+ void *pic_mem_vir;
+ unsigned long long gop_mem_phy;
+ void *gop_mem_vir;
+ unsigned long long qmeter_mem_phy;
+ void *qmeter_mem_vir;
+ unsigned long long base_offset;
+};
+
+struct msg_header {
+ u32 idx;
+ u32 msgnum;
+ u32 msgid;
+};
+
+void rpc_init_shared_memory_encoder(struct shared_addr *This,
+ unsigned long long base_phy_addr,
+ void *base_virt_addr,
+ u_int32 total_size,
+ u32 *actual_size);
+void rpc_set_system_cfg_value_encoder(void *Interface, u_int32 regs_base, u_int32 core_id);
+void rpc_send_cmd_buf_encoder(struct shared_addr *This,
+ u_int32 idx,
+ u_int32 cmdid,
+ u_int32 cmdnum,
+ u_int32 *local_cmddata);
+u32 rpc_read_msg_u32(struct shared_addr *shared_mem);
+int rpc_read_msg_array(struct shared_addr *shared_mem, u32 *buf, u32 number);
+int rpc_get_msg_header(struct shared_addr *shared_mem, struct msg_header *msg);
+
+pMEDIAIP_ENC_YUV_BUFFER_DESC rpc_get_yuv_buffer_desc(
+ struct shared_addr *shared_mem, int index);
+pBUFFER_DESCRIPTOR_TYPE rpc_get_stream_buffer_desc(
+ struct shared_addr *shared_mem, int index);
+pMEDIAIP_ENC_EXPERT_MODE_PARAM rpc_get_expert_mode_param(
+ struct shared_addr *shared_mem, int index);
+pMEDIAIP_ENC_PARAM rpc_get_enc_param(
+ struct shared_addr *shared_mem, int index);
+pMEDIAIP_ENC_MEM_POOL rpc_get_mem_pool(
+ struct shared_addr *shared_mem, int index);
+pENC_ENCODING_STATUS rpc_get_encoding_status(
+ struct shared_addr *shared_mem, int index);
+pENC_DSA_STATUS_t rpc_get_dsa_status(struct shared_addr *shared_mem, int index);
+void rpc_set_print_buffer(struct shared_addr *shared_mem,
+ unsigned long print_phy_addr, u32 size);
+
+#endif
diff --git a/drivers/mxc/vpu_windsor/vpu_event_msg.c b/drivers/mxc/vpu_windsor/vpu_event_msg.c
new file mode 100644
index 000000000000..7ac7accfda3a
--- /dev/null
+++ b/drivers/mxc/vpu_windsor/vpu_event_msg.c
@@ -0,0 +1,237 @@
+/*
+ * Copyright(c) 2018 NXP. All rights reserved.
+ *
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * vpu_event_msg.c
+ *
+ * Author Ming Qian<ming.qian@nxp.com>
+ */
+#define TAG "[VPU Encoder Msg]\t "
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/vmalloc.h>
+
+#include "vpu_encoder_b0.h"
+#include "vpu_event_msg.h"
+
+static atomic64_t total_ext_data = ATOMIC64_INIT(0);
+
+static struct vpu_event_msg *alloc_event_msg(void)
+{
+ struct vpu_event_msg *msg = NULL;
+
+ msg = vzalloc(sizeof(*msg));
+
+ return msg;
+}
+
+static void free_event_msg(struct vpu_event_msg *msg)
+{
+ if (!msg)
+ return;
+
+ free_msg_ext_buffer(msg);
+ VPU_SAFE_RELEASE(msg, vfree);
+}
+
+static void set_msg_count(struct vpu_ctx *ctx, unsigned long count)
+{
+ struct vpu_attr *attr = get_vpu_ctx_attr(ctx);
+
+ if (attr)
+ attr->msg_count = count;
+}
+
+static void inc_msg_count(struct vpu_ctx *ctx)
+{
+ struct vpu_attr *attr = get_vpu_ctx_attr(ctx);
+
+ if (attr)
+ attr->msg_count++;
+}
+
+static void dec_msg_count(struct vpu_ctx *ctx)
+{
+ struct vpu_attr *attr = get_vpu_ctx_attr(ctx);
+
+ if (attr)
+ attr->msg_count--;
+}
+
+static bool is_msg_count_full(struct vpu_ctx *ctx)
+{
+ struct vpu_attr *attr = get_vpu_ctx_attr(ctx);
+
+ if (!attr)
+ return false;
+ if (attr->msg_count > MSG_COUNT_THD)
+ return true;
+ return false;
+}
+
+void cleanup_ctx_msg_queue(struct vpu_ctx *ctx)
+{
+ struct vpu_event_msg *msg;
+ struct vpu_event_msg *tmp;
+
+ WARN_ON(!ctx);
+
+ vpu_log_func();
+ mutex_lock(&ctx->instance_mutex);
+ list_for_each_entry_safe(msg, tmp, &ctx->msg_q, list) {
+ list_del_init(&msg->list);
+ vpu_dbg(LVL_MSG, "drop core[%d] ctx[%d] msg:[%d]\n",
+ ctx->core_dev->id, ctx->str_index, msg->msgid);
+ VPU_SAFE_RELEASE(msg, free_event_msg);
+ dec_msg_count(ctx);
+ }
+
+ list_for_each_entry_safe(msg, tmp, &ctx->idle_q, list) {
+ list_del_init(&msg->list);
+ VPU_SAFE_RELEASE(msg, free_event_msg);
+ dec_msg_count(ctx);
+ }
+ mutex_unlock(&ctx->instance_mutex);
+}
+
+static int increase_idle_msg(struct vpu_ctx *ctx, u32 count)
+{
+ int i;
+
+ for (i = 0; i < count; i++) {
+ struct vpu_event_msg *msg = alloc_event_msg();
+
+ if (!msg)
+ continue;
+ list_add_tail(&msg->list, &ctx->idle_q);
+ inc_msg_count(ctx);
+ }
+
+ return 0;
+}
+
+int init_ctx_msg_queue(struct vpu_ctx *ctx)
+{
+ WARN_ON(!ctx);
+ if (!ctx)
+ return -EINVAL;
+
+ vpu_log_func();
+ mutex_lock(&ctx->instance_mutex);
+
+ set_msg_count(ctx, 0);
+ INIT_LIST_HEAD(&ctx->msg_q);
+ INIT_LIST_HEAD(&ctx->idle_q);
+
+ mutex_unlock(&ctx->instance_mutex);
+
+ return 0;
+}
+
+struct vpu_event_msg *get_idle_msg(struct vpu_ctx *ctx)
+{
+ struct vpu_event_msg *msg = NULL;
+
+ WARN_ON(!ctx);
+
+ mutex_lock(&ctx->instance_mutex);
+ if (list_empty(&ctx->idle_q))
+ increase_idle_msg(ctx, 1);
+
+ msg = list_first_entry(&ctx->idle_q, struct vpu_event_msg, list);
+ if (msg)
+ list_del_init(&msg->list);
+
+ mutex_unlock(&ctx->instance_mutex);
+
+ return msg;
+}
+
+void put_idle_msg(struct vpu_ctx *ctx, struct vpu_event_msg *msg)
+{
+ WARN_ON(!ctx);
+
+ if (!ctx || !msg)
+ return;
+
+ free_msg_ext_buffer(msg);
+
+ mutex_lock(&ctx->instance_mutex);
+ if (is_msg_count_full(ctx)) {
+ VPU_SAFE_RELEASE(msg, free_event_msg);
+ dec_msg_count(ctx);
+ } else {
+ list_add_tail(&msg->list, &ctx->idle_q);
+ }
+ mutex_unlock(&ctx->instance_mutex);
+}
+
+struct vpu_event_msg *pop_event_msg(struct vpu_ctx *ctx)
+{
+ struct vpu_event_msg *msg = NULL;
+
+ WARN_ON(!ctx);
+
+ mutex_lock(&ctx->instance_mutex);
+ if (list_empty(&ctx->msg_q))
+ goto exit;
+
+ msg = list_first_entry(&ctx->msg_q, struct vpu_event_msg, list);
+ if (msg)
+ list_del_init(&msg->list);
+
+exit:
+ mutex_unlock(&ctx->instance_mutex);
+ return msg;
+}
+
+void push_back_event_msg(struct vpu_ctx *ctx, struct vpu_event_msg *msg)
+{
+ WARN_ON(!ctx);
+
+ if (!ctx || !msg)
+ return;
+
+ mutex_lock(&ctx->instance_mutex);
+ list_add_tail(&msg->list, &ctx->msg_q);
+ mutex_unlock(&ctx->instance_mutex);
+}
+
+int alloc_msg_ext_buffer(struct vpu_event_msg *msg, u32 number)
+{
+ WARN_ON(!msg);
+
+ if (!msg || !number)
+ return -EINVAL;
+
+ msg->ext_data = vzalloc(number * sizeof(u32));
+ if (!msg->ext_data)
+ return -ENOMEM;
+ msg->number = number;
+
+ atomic64_add(number, &total_ext_data);
+ vpu_dbg(LVL_MSG, "++++alloc %d msg ext data: %lld\n",
+ number, get_total_ext_data_number());
+
+ return 0;
+}
+
+void free_msg_ext_buffer(struct vpu_event_msg *msg)
+{
+ WARN_ON(!msg);
+
+ if (!msg || !msg->ext_data)
+ return;
+
+ atomic64_sub(msg->number, &total_ext_data);
+ VPU_SAFE_RELEASE(msg->ext_data, vfree);
+ vpu_dbg(LVL_MSG, "----free %d msg ext data: %lld\n",
+ msg->number, get_total_ext_data_number());
+}
+
+long long get_total_ext_data_number(void)
+{
+ return atomic64_read(&total_ext_data);
+}
diff --git a/drivers/mxc/vpu_windsor/vpu_event_msg.h b/drivers/mxc/vpu_windsor/vpu_event_msg.h
new file mode 100644
index 000000000000..cc02956eab6c
--- /dev/null
+++ b/drivers/mxc/vpu_windsor/vpu_event_msg.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright(c) 2018 NXP. All rights reserved.
+ *
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * vpu_event_msg.h
+ *
+ * Author Ming Qian<ming.qian@nxp.com>
+ */
+#ifndef _VPU_EVENT_MSG_H
+#define _VPU_EVENT_MSG_H
+
+#include "vpu_encoder_config.h"
+
+struct vpu_event_msg {
+ struct list_head list;
+ u32 idx;
+ u32 msgid;
+ u32 number;
+ u32 data[MSG_DATA_DEFAULT_SIZE];
+ u32 *ext_data;
+};
+
+int init_ctx_msg_queue(struct vpu_ctx *ctx);
+void cleanup_ctx_msg_queue(struct vpu_ctx *ctx);
+struct vpu_event_msg *get_idle_msg(struct vpu_ctx *ctx);
+void put_idle_msg(struct vpu_ctx *ctx, struct vpu_event_msg *msg);
+struct vpu_event_msg *pop_event_msg(struct vpu_ctx *ctx);
+void push_back_event_msg(struct vpu_ctx *ctx, struct vpu_event_msg *msg);
+int alloc_msg_ext_buffer(struct vpu_event_msg *msg, u32 number);
+void free_msg_ext_buffer(struct vpu_event_msg *msg);
+long long get_total_ext_data_number(void);
+
+#endif
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index f3357091e9d1..a0e41e82201a 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -485,4 +485,8 @@ config FUJITSU_ES
source "drivers/net/hyperv/Kconfig"
+config IVSHMEM_NET
+ tristate "IVSHMEM virtual network device"
+ depends on PCI
+
endif # NETDEVICES
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index f07c0bae1f67..55128b05efd1 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -75,3 +75,5 @@ obj-$(CONFIG_HYPERV_NET) += hyperv/
obj-$(CONFIG_NTB_NETDEV) += ntb_netdev.o
obj-$(CONFIG_FUJITSU_ES) += fjes/
+
+obj-$(CONFIG_IVSHMEM_NET) += ivshmem-net.o
diff --git a/drivers/net/can/Kconfig b/drivers/net/can/Kconfig
index ac4ff394bc56..8b43edd2e4b4 100644
--- a/drivers/net/can/Kconfig
+++ b/drivers/net/can/Kconfig
@@ -99,7 +99,7 @@ config CAN_BFIN
config CAN_FLEXCAN
tristate "Support for Freescale FLEXCAN based chips"
- depends on ARM || PPC
+ depends on ARM || ARM64 || PPC
---help---
Say Y here if you want to support for Freescale FlexCAN.
diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c
index 84dd79041285..f263ab39174c 100644
--- a/drivers/net/can/flexcan.c
+++ b/drivers/net/can/flexcan.c
@@ -26,16 +26,27 @@
#include <linux/can/error.h>
#include <linux/can/led.h>
#include <linux/can/rx-offload.h>
+#include <linux/can/platform/flexcan.h>
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/mfd/syscon.h>
+#include <linux/mfd/syscon/imx6q-iomuxc-gpr.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/regmap.h>
#include <linux/regulator/consumer.h>
+#ifdef CONFIG_ARCH_MXC_ARM64
+#include <soc/imx8/sc/sci.h>
+#endif
+
#define DRV_NAME "flexcan"
/* 8 for RX fifo and 2 error handling */
@@ -60,6 +71,7 @@
#define FLEXCAN_MCR_IRMQ BIT(16)
#define FLEXCAN_MCR_LPRIO_EN BIT(13)
#define FLEXCAN_MCR_AEN BIT(12)
+#define FLEXCAN_MCR_FDEN BIT(11)
/* MCR_MAXMB: maximum used MBs is MAXMB + 1 */
#define FLEXCAN_MCR_MAXMB(x) ((x) & 0x7f)
#define FLEXCAN_MCR_IDAM_A (0x0 << 8)
@@ -99,6 +111,7 @@
#define FLEXCAN_CTRL2_MRP BIT(18)
#define FLEXCAN_CTRL2_RRS BIT(17)
#define FLEXCAN_CTRL2_EACEN BIT(16)
+#define FLEXCAN_CTRL2_ISOCANFDEN BIT(12)
/* FLEXCAN memory error control register (MECR) bits */
#define FLEXCAN_MECR_ECRWRDIS BIT(31)
@@ -142,7 +155,23 @@
(FLEXCAN_ESR_ERR_BUS | FLEXCAN_ESR_ERR_STATE)
#define FLEXCAN_ESR_ALL_INT \
(FLEXCAN_ESR_TWRN_INT | FLEXCAN_ESR_RWRN_INT | \
- FLEXCAN_ESR_BOFF_INT | FLEXCAN_ESR_ERR_INT)
+ FLEXCAN_ESR_BOFF_INT | FLEXCAN_ESR_ERR_INT | \
+ FLEXCAN_ESR_WAK_INT)
+
+/* FLEXCAN Bit Timing register (CBT) bits */
+#define FLEXCAN_CBT_BTF BIT(31)
+#define FLEXCAN_CBT_EPRESDIV(x) (((x) & 0x3ff) << 21)
+#define FLEXCAN_CBT_ERJW(x) (((x) & 0x1f) << 16)
+#define FLEXCAN_CBT_EPROPSEG(x) (((x) & 0x3f) << 10)
+#define FLEXCAN_CBT_EPSEG1(x) (((x) & 0x1f) << 5)
+#define FLEXCAN_CBT_EPSEG2(x) ((x) & 0x1f)
+
+/* FLEXCAN FD Bit Timing register (FDCBT) bits */
+#define FLEXCAN_FDCBT_FPRESDIV(x) (((x) & 0x3ff) << 20)
+#define FLEXCAN_FDCBT_FRJW(x) (((x) & 0x07) << 16)
+#define FLEXCAN_FDCBT_FPROPSEG(x) (((x) & 0x1f) << 10)
+#define FLEXCAN_FDCBT_FPSEG1(x) (((x) & 0x07) << 5)
+#define FLEXCAN_FDCBT_FPSEG2(x) ((x) & 0x07)
/* FLEXCAN interrupt flag register (IFLAG) bits */
/* Errata ERR005829 step7: Reserve first valid MB */
@@ -150,14 +179,22 @@
#define FLEXCAN_TX_MB_OFF_FIFO 9
#define FLEXCAN_TX_MB_RESERVED_OFF_TIMESTAMP 0
#define FLEXCAN_TX_MB_OFF_TIMESTAMP 1
+#define FLEXCAN_TX_MB_RESERVED_OFF_TIMESTAMP_FD 0
+#define FLEXCAN_TX_MB_OFF_TIMESTAMP_FD 1
#define FLEXCAN_RX_MB_OFF_TIMESTAMP_FIRST (FLEXCAN_TX_MB_OFF_TIMESTAMP + 1)
#define FLEXCAN_RX_MB_OFF_TIMESTAMP_LAST 63
+#define FLEXCAN_RX_MB_OFF_TIMESTAMP_FD_FIRST (FLEXCAN_TX_MB_OFF_TIMESTAMP_FD + 1)
+#define FLEXCAN_RX_MB_OFF_TIMESTAMP_FD_LAST 13
#define FLEXCAN_IFLAG_MB(x) BIT(x)
#define FLEXCAN_IFLAG_RX_FIFO_OVERFLOW BIT(7)
#define FLEXCAN_IFLAG_RX_FIFO_WARN BIT(6)
#define FLEXCAN_IFLAG_RX_FIFO_AVAILABLE BIT(5)
/* FLEXCAN message buffers */
+#define FLEXCAN_MB_CNT_EDL BIT(31)
+#define FLEXCAN_MB_CNT_BRS BIT(30)
+#define FLEXCAN_MB_CNT_ESI BIT(29)
+
#define FLEXCAN_MB_CODE_MASK (0xf << 24)
#define FLEXCAN_MB_CODE_RX_BUSY_BIT (0x1 << 24)
#define FLEXCAN_MB_CODE_RX_INACTIVE (0x0 << 24)
@@ -177,7 +214,9 @@
#define FLEXCAN_MB_CNT_LENGTH(x) (((x) & 0xf) << 16)
#define FLEXCAN_MB_CNT_TIMESTAMP(x) ((x) & 0xffff)
-#define FLEXCAN_TIMEOUT_US (250)
+#define FLEXCAN_FDCTRL_FDRATE BIT(31)
+
+#define FLEXCAN_TIMEOUT_US (50)
/* FLEXCAN hardware feature flags
*
@@ -199,13 +238,53 @@
#define FLEXCAN_QUIRK_DISABLE_MECR BIT(4) /* Disable Memory error detection */
#define FLEXCAN_QUIRK_USE_OFF_TIMESTAMP BIT(5) /* Use timestamp based offloading */
#define FLEXCAN_QUIRK_BROKEN_PERR_STATE BIT(6) /* No interrupt for error passive */
+#define FLEXCAN_QUIRK_TIMESTAMP_SUPPORT_FD BIT(7) /* Use timestamp then support can fd mode */
-/* Structure of the message buffer */
-struct flexcan_mb {
- u32 can_ctrl;
- u32 can_id;
- u32 data[2];
-};
+/* Message Buffer */
+#define FLEXCAN_MB_CTRL 0x0
+#define FLEXCAN_MB_ID 0x4
+#define FLEXCAN_MB_DATA(n) (0x8 + ((n) << 2))
+
+#define FLEXCAN_MB 0x80
+#define FLEXCAN_MB_NUM 64
+#define FLEXCAN_MB_FD_NUM 14
+#define FLEXCAN_MB_SIZE 16
+#define FLEXCAN_MB_FD_SIZE 72
+
+/* CAN FD Memory Partition
+ *
+ * When CAN FD is enabled, the FlexCAN RAM can be partitioned in
+ * blocks of 512 bytes. Each block can accommodate a number of
+ * Message Buffers which depends on the configuration provided
+ * by CAN_FDCTRL[MBDSRn] bit fields where we all set to 64 bytes
+ * per Message Buffer and 7 MBs per Block by default.
+ *
+ * There're two RAM blocks: RAM block 0,1
+ */
+#define FLEXCAN_CANFD_MB_OFFSET(n) (((n) / 7) * 512 + ((n) % 7) * \
+ FLEXCAN_MB_FD_SIZE)
+#define FLEXCAN_CANFD_MBDSR_MASK 0x6db0000
+#define FLEXCAN_CANFD_MBDSR_SHIFT 16
+#define FLEXCAN_CANFD_MBDSR_DEFAULT 0x6db
+
+/*
+ * NOTE:
+ * To minimize errors when processing FD frames, use the same value
+ * for FPRESDIV and PRESDIV (in CAN_CBT or CAN_CTRL1).
+ * For more details refer to the first NOTE in section CAN FD frames.
+ *
+ * CAN FD supported rates combinations
+ *
+ * Combination 1:
+ * Bitrate: 225000 375000 400000 425000 500000 875000
+ * Data rate: 1000000
+ *
+ * Combination 2:
+ * Bitrate: 550000 600000 625000 650000 675000 750000 775000
+ * 800000 850000 925000 950000 975000 1000000
+ * Data rate: 1500000 2000000 2500000 3000000 3500000 4000000
+ * 5000000
+ */
/* Structure of the hardware registers */
struct flexcan_regs {
@@ -232,18 +311,9 @@ struct flexcan_regs {
u32 crcr; /* 0x44 */
u32 rxfgmask; /* 0x48 */
u32 rxfir; /* 0x4c */
- u32 _reserved3[12]; /* 0x50 */
- struct flexcan_mb mb[64]; /* 0x80 */
- /* FIFO-mode:
- * MB
- * 0x080...0x08f 0 RX message buffer
- * 0x090...0x0df 1-5 reserverd
- * 0x0e0...0x0ff 6-7 8 entry ID table
- * (mx25, mx28, mx35, mx53)
- * 0x0e0...0x2df 6-7..37 8..128 entry ID table
- * size conf'ed via ctrl2::RFFN
- * (mx6, vf610)
- */
+ u32 cbt; /* 0x50 */
+ u32 _reserved3[11]; /* 0x54 */
+ u32 _reserved8[64*4]; /* 0x80 */ /* 64 mailbox */
u32 _reserved4[256]; /* 0x480 */
u32 rximr[64]; /* 0x880 */
u32 _reserved5[24]; /* 0x980 */
@@ -257,28 +327,53 @@ struct flexcan_regs {
u32 rerrdr; /* 0xaf4 */
u32 rerrsynr; /* 0xaf8 */
u32 errsr; /* 0xafc */
+ u32 _reserved7[64]; /* 0xb00 */
+ u32 fdctrl; /* 0xc00 */
+ u32 fdcbt; /* 0xc04 */
+ u32 fdcrc; /* 0xc08 */
};
struct flexcan_devtype_data {
u32 quirks; /* quirks needed for different IP cores */
};
+struct flexcan_stop_mode {
+ struct regmap *gpr;
+ u8 req_gpr;
+ u8 req_bit;
+ u8 ack_gpr;
+ u8 ack_bit;
+};
struct flexcan_priv {
struct can_priv can;
struct can_rx_offload offload;
struct flexcan_regs __iomem *regs;
- struct flexcan_mb __iomem *tx_mb;
- struct flexcan_mb __iomem *tx_mb_reserved;
+ void __iomem *base;
+ u8 tx_mb_reserved_idx;
u8 tx_mb_idx;
u32 reg_ctrl_default;
u32 reg_imask1_default;
u32 reg_imask2_default;
+ struct device *dev;
struct clk *clk_ipg;
struct clk *clk_per;
+ struct flexcan_platform_data *pdata;
const struct flexcan_devtype_data *devtype_data;
struct regulator *reg_xceiver;
+ int id;
+ struct flexcan_stop_mode stm;
+#ifdef CONFIG_ARCH_MXC_ARM64
+ sc_ipc_t ipc_handle;
+#endif
+ bool wakeup;
+
+ u32 mb_size;
+ u32 mb_num;
+
+ /* Selects the clock source to CAN Protocol Engine (PE), 1 by default*/
+ u32 clk_src;
};
static const struct flexcan_devtype_data fsl_p1010_devtype_data = {
@@ -295,6 +390,12 @@ static const struct flexcan_devtype_data fsl_imx6q_devtype_data = {
FLEXCAN_QUIRK_USE_OFF_TIMESTAMP | FLEXCAN_QUIRK_BROKEN_PERR_STATE,
};
+static struct flexcan_devtype_data fsl_imx8qm_devtype_data = {
+ .quirks = FLEXCAN_QUIRK_DISABLE_RXFG | FLEXCAN_QUIRK_ENABLE_EACEN_RRS |
+ FLEXCAN_QUIRK_USE_OFF_TIMESTAMP | FLEXCAN_QUIRK_BROKEN_PERR_STATE |
+ FLEXCAN_QUIRK_TIMESTAMP_SUPPORT_FD,
+};
+
static const struct flexcan_devtype_data fsl_vf610_devtype_data = {
.quirks = FLEXCAN_QUIRK_DISABLE_RXFG | FLEXCAN_QUIRK_ENABLE_EACEN_RRS |
FLEXCAN_QUIRK_DISABLE_MECR | FLEXCAN_QUIRK_USE_OFF_TIMESTAMP |
@@ -313,6 +414,30 @@ static const struct can_bittiming_const flexcan_bittiming_const = {
.brp_inc = 1,
};
+static const struct can_bittiming_const flexcan_fd_bittiming_const = {
+ .name = DRV_NAME,
+ .tseg1_min = 2,
+ .tseg1_max = 64,
+ .tseg2_min = 1,
+ .tseg2_max = 32,
+ .sjw_max = 32,
+ .brp_min = 1,
+ .brp_max = 1024,
+ .brp_inc = 1,
+};
+
+static const struct can_bittiming_const flexcan_fd_data_bittiming_const = {
+ .name = DRV_NAME,
+ .tseg1_min = 1,
+ .tseg1_max = 39,
+ .tseg2_min = 1,
+ .tseg2_max = 8,
+ .sjw_max = 8,
+ .brp_min = 1,
+ .brp_max = 1024,
+ .brp_inc = 1,
+};
+
/* Abstract off the read/write for arm versus ppc. This
* assumes that PPC uses big-endian registers and everything
* else uses little-endian registers, independent of CPU
@@ -328,6 +453,29 @@ static inline void flexcan_write(u32 val, void __iomem *addr)
{
out_be32(addr, val);
}
+
+static inline u32 flexcan_mb_read(const struct flexcan_priv *priv,
+ u32 index, unsigned int offset)
+{
+ if (priv->can.ctrlmode & CAN_CTRLMODE_FD)
+ return in_be32(priv->base + FLEXCAN_MB +
+ FLEXCAN_CANFD_MB_OFFSET(index) + offset);
+ else
+ return in_be32(priv->base + FLEXCAN_MB +
+ priv->mb_size * index + offset);
+}
+
+static inline void flexcan_mb_write(const struct flexcan_priv *priv,
+ u32 index, unsigned int offset,
+ u32 val)
+{
+ if (priv->can.ctrlmode & CAN_CTRLMODE_FD)
+ out_be32(val, priv->base + FLEXCAN_MB +
+ FLEXCAN_CANFD_MB_OFFSET(index) + offset);
+ else
+ out_be32(val, priv->base + FLEXCAN_MB +
+ priv->mb_size * index + offset);
+}
#else
static inline u32 flexcan_read(void __iomem *addr)
{
@@ -338,6 +486,29 @@ static inline void flexcan_write(u32 val, void __iomem *addr)
{
writel(val, addr);
}
+
+static inline u32 flexcan_mb_read(const struct flexcan_priv *priv,
+ u32 index, unsigned int offset)
+{
+ if (priv->can.ctrlmode & CAN_CTRLMODE_FD)
+ return readl(priv->base + FLEXCAN_MB +
+ FLEXCAN_CANFD_MB_OFFSET(index) + offset);
+ else
+ return readl(priv->base + FLEXCAN_MB +
+ priv->mb_size * index + offset);
+}
+
+static inline void flexcan_mb_write(const struct flexcan_priv *priv,
+ u32 index, unsigned int offset,
+ u32 val)
+{
+ if (priv->can.ctrlmode & CAN_CTRLMODE_FD)
+ writel(val, priv->base + FLEXCAN_MB +
+ FLEXCAN_CANFD_MB_OFFSET(index) + offset);
+ else
+ writel(val, priv->base + FLEXCAN_MB +
+ priv->mb_size * index + offset);
+}
#endif
static inline void flexcan_error_irq_enable(const struct flexcan_priv *priv)
@@ -356,8 +527,102 @@ static inline void flexcan_error_irq_disable(const struct flexcan_priv *priv)
flexcan_write(reg_ctrl, &regs->ctrl);
}
+static int flexcan_clks_enable(const struct flexcan_priv *priv)
+{
+ int err;
+
+ err = clk_prepare_enable(priv->clk_ipg);
+ if (err)
+ return err;
+
+ err = clk_prepare_enable(priv->clk_per);
+ if (err)
+ clk_disable_unprepare(priv->clk_ipg);
+
+ return err;
+}
+
+static void flexcan_clks_disable(const struct flexcan_priv *priv)
+{
+ clk_disable_unprepare(priv->clk_ipg);
+ clk_disable_unprepare(priv->clk_per);
+}
+
+static void flexcan_wake_mask_enable(struct flexcan_priv *priv)
+{
+ struct flexcan_regs __iomem *regs = priv->regs;
+ u32 reg_mcr;
+
+ reg_mcr = flexcan_read(&regs->mcr);
+ reg_mcr |= FLEXCAN_MCR_WAK_MSK;
+ flexcan_write(reg_mcr, &regs->mcr);
+}
+
+static void flexcan_wake_mask_disable(struct flexcan_priv *priv)
+{
+ struct flexcan_regs __iomem *regs = priv->regs;
+ u32 reg_mcr;
+
+ reg_mcr = flexcan_read(&regs->mcr);
+ reg_mcr &= ~FLEXCAN_MCR_WAK_MSK;
+ flexcan_write(reg_mcr, &regs->mcr);
+}
+
+#ifdef CONFIG_ARCH_MXC_ARM64
+static void imx8_ipg_stop_enable(struct flexcan_priv *priv, bool enabled)
+{
+ struct device_node *np = priv->dev->of_node;
+ u32 rsrc_id, val;
+ int idx;
+
+ idx = of_alias_get_id(np, "can");
+ if (idx == 0)
+ rsrc_id = SC_R_CAN_0;
+ else if (idx == 1)
+ rsrc_id = SC_R_CAN_1;
+ else
+ rsrc_id = SC_R_CAN_2;
+
+ val = enabled ? 1 : 0;
+ sc_misc_set_control(priv->ipc_handle, rsrc_id, SC_C_IPG_STOP, val);
+}
+#else
+static void imx8_ipg_stop_enable(struct flexcan_priv *priv, bool enabled) {}
+#endif
+
+static inline void flexcan_enter_stop_mode(struct flexcan_priv *priv)
+{
+ /* enable stop request */
+ if (priv->stm.gpr) {
+ if (priv->devtype_data->quirks & FLEXCAN_QUIRK_DISABLE_RXFG)
+ regmap_update_bits(priv->stm.gpr, priv->stm.req_gpr,
+ 1 << priv->stm.req_bit, 1 << priv->stm.req_bit);
+ } else {
+ if (priv->devtype_data->quirks & FLEXCAN_QUIRK_TIMESTAMP_SUPPORT_FD)
+ imx8_ipg_stop_enable(priv, true);
+ }
+}
+
+static inline void flexcan_exit_stop_mode(struct flexcan_priv *priv)
+{
+ /* remove stop request */
+ if (priv->stm.gpr) {
+ if (priv->devtype_data->quirks & FLEXCAN_QUIRK_DISABLE_RXFG)
+ regmap_update_bits(priv->stm.gpr, priv->stm.req_gpr,
+ 1 << priv->stm.req_bit, 0);
+ } else {
+ if (priv->devtype_data->quirks & FLEXCAN_QUIRK_TIMESTAMP_SUPPORT_FD)
+ imx8_ipg_stop_enable(priv, false);
+ }
+}
+
static inline int flexcan_transceiver_enable(const struct flexcan_priv *priv)
{
+ if (priv->pdata && priv->pdata->transceiver_switch) {
+ priv->pdata->transceiver_switch(1);
+ return 0;
+ }
+
if (!priv->reg_xceiver)
return 0;
@@ -366,6 +631,11 @@ static inline int flexcan_transceiver_enable(const struct flexcan_priv *priv)
static inline int flexcan_transceiver_disable(const struct flexcan_priv *priv)
{
+ if (priv->pdata && priv->pdata->transceiver_switch) {
+ priv->pdata->transceiver_switch(0);
+ return 0;
+ }
+
if (!priv->reg_xceiver)
return 0;
@@ -440,7 +710,7 @@ static int flexcan_chip_unfreeze(struct flexcan_priv *priv)
flexcan_write(reg, &regs->mcr);
while (timeout-- && (flexcan_read(&regs->mcr) & FLEXCAN_MCR_FRZ_ACK))
- udelay(10);
+ udelay(20);
if (flexcan_read(&regs->mcr) & FLEXCAN_MCR_FRZ_ACK)
return -ETIMEDOUT;
@@ -482,19 +752,11 @@ static int flexcan_get_berr_counter(const struct net_device *dev,
const struct flexcan_priv *priv = netdev_priv(dev);
int err;
- err = clk_prepare_enable(priv->clk_ipg);
- if (err)
- return err;
-
- err = clk_prepare_enable(priv->clk_per);
- if (err)
- goto out_disable_ipg;
+ pm_runtime_get_sync(priv->dev);
err = __flexcan_get_berr_counter(dev, bec);
- clk_disable_unprepare(priv->clk_per);
- out_disable_ipg:
- clk_disable_unprepare(priv->clk_ipg);
+ pm_runtime_put(priv->dev);
return err;
}
@@ -502,10 +764,12 @@ static int flexcan_get_berr_counter(const struct net_device *dev,
static int flexcan_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
const struct flexcan_priv *priv = netdev_priv(dev);
- struct can_frame *cf = (struct can_frame *)skb->data;
- u32 can_id;
+ struct flexcan_regs __iomem *regs = priv->regs;
+ struct canfd_frame *cf = (struct canfd_frame *)skb->data;
+ u32 can_id, reg_fdctrl;
u32 data;
- u32 ctrl = FLEXCAN_MB_CODE_TX_DATA | (cf->can_dlc << 16);
+ u32 ctrl = FLEXCAN_MB_CODE_TX_DATA | (can_len2dlc(cf->len) << 16);
+ u32 i;
if (can_dropped_invalid_skb(dev, skb))
return NETDEV_TX_OK;
@@ -522,27 +786,34 @@ static int flexcan_start_xmit(struct sk_buff *skb, struct net_device *dev)
if (cf->can_id & CAN_RTR_FLAG)
ctrl |= FLEXCAN_MB_CNT_RTR;
- if (cf->can_dlc > 0) {
- data = be32_to_cpup((__be32 *)&cf->data[0]);
- flexcan_write(data, &priv->tx_mb->data[0]);
- }
- if (cf->can_dlc > 4) {
- data = be32_to_cpup((__be32 *)&cf->data[4]);
- flexcan_write(data, &priv->tx_mb->data[1]);
+ for (i = 0; i < cf->len; i += 4) {
+ data = be32_to_cpup((__be32 *)&cf->data[i]);
+ flexcan_mb_write(priv, priv->tx_mb_idx, FLEXCAN_MB_DATA(i / 4), data);
}
can_put_echo_skb(skb, dev, 0);
- flexcan_write(can_id, &priv->tx_mb->can_id);
- flexcan_write(ctrl, &priv->tx_mb->can_ctrl);
+ if (priv->can.ctrlmode & CAN_CTRLMODE_FD) {
+ reg_fdctrl = flexcan_read(&regs->fdctrl) &
+ ~FLEXCAN_FDCTRL_FDRATE;
+ if (cf->flags & CANFD_BRS) {
+ reg_fdctrl |= FLEXCAN_FDCTRL_FDRATE;
+ ctrl |= FLEXCAN_MB_CNT_BRS;
+ }
+ flexcan_write(reg_fdctrl, &regs->fdctrl);
+ ctrl |= FLEXCAN_MB_CNT_EDL;
+ }
+
+ flexcan_mb_write(priv, priv->tx_mb_idx, FLEXCAN_MB_ID, can_id);
+ flexcan_mb_write(priv, priv->tx_mb_idx, FLEXCAN_MB_CTRL, ctrl);
/* Errata ERR005829 step8:
* Write twice INACTIVE(0x8) code to first MB.
*/
- flexcan_write(FLEXCAN_MB_CODE_TX_INACTIVE,
- &priv->tx_mb_reserved->can_ctrl);
- flexcan_write(FLEXCAN_MB_CODE_TX_INACTIVE,
- &priv->tx_mb_reserved->can_ctrl);
+ flexcan_mb_write(priv, priv->tx_mb_reserved_idx, FLEXCAN_MB_CTRL,
+ FLEXCAN_MB_CODE_TX_INACTIVE);
+ flexcan_mb_write(priv, priv->tx_mb_reserved_idx, FLEXCAN_MB_CTRL,
+ FLEXCAN_MB_CODE_TX_INACTIVE);
return NETDEV_TX_OK;
}
@@ -648,19 +919,19 @@ static inline struct flexcan_priv *rx_offload_to_priv(struct can_rx_offload *off
}
static unsigned int flexcan_mailbox_read(struct can_rx_offload *offload,
- struct can_frame *cf,
+ struct canfd_frame *cf,
u32 *timestamp, unsigned int n)
{
struct flexcan_priv *priv = rx_offload_to_priv(offload);
struct flexcan_regs __iomem *regs = priv->regs;
- struct flexcan_mb __iomem *mb = &regs->mb[n];
u32 reg_ctrl, reg_id, reg_iflag1;
+ u32 i;
if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) {
u32 code;
do {
- reg_ctrl = flexcan_read(&mb->can_ctrl);
+ reg_ctrl = flexcan_mb_read(priv, n, FLEXCAN_MB_CTRL);
} while (reg_ctrl & FLEXCAN_MB_CODE_RX_BUSY_BIT);
/* is this MB empty? */
@@ -679,24 +950,38 @@ static unsigned int flexcan_mailbox_read(struct can_rx_offload *offload,
if (!(reg_iflag1 & FLEXCAN_IFLAG_RX_FIFO_AVAILABLE))
return 0;
- reg_ctrl = flexcan_read(&mb->can_ctrl);
+ reg_ctrl = flexcan_mb_read(priv, n, FLEXCAN_MB_CTRL);
}
/* increase timstamp to full 32 bit */
*timestamp = reg_ctrl << 16;
- reg_id = flexcan_read(&mb->can_id);
+ reg_id = flexcan_mb_read(priv, n, FLEXCAN_MB_ID);
if (reg_ctrl & FLEXCAN_MB_CNT_IDE)
cf->can_id = ((reg_id >> 0) & CAN_EFF_MASK) | CAN_EFF_FLAG;
else
cf->can_id = (reg_id >> 18) & CAN_SFF_MASK;
- if (reg_ctrl & FLEXCAN_MB_CNT_RTR)
+ if (reg_ctrl & FLEXCAN_MB_CNT_EDL)
+ cf->len = can_dlc2len((reg_ctrl >> 16) & 0x0F);
+ else
+ cf->len = get_can_dlc((reg_ctrl >> 16) & 0x0F);
+
+ if (reg_ctrl & FLEXCAN_MB_CNT_ESI) {
+ cf->flags |= CANFD_ESI;
+ netdev_warn(priv->can.dev, "ESI Error\n");
+ }
+
+ if (!(reg_ctrl & FLEXCAN_MB_CNT_EDL) && reg_ctrl & FLEXCAN_MB_CNT_RTR) {
cf->can_id |= CAN_RTR_FLAG;
- cf->can_dlc = get_can_dlc((reg_ctrl >> 16) & 0xf);
+ } else {
+ if (reg_ctrl & FLEXCAN_MB_CNT_BRS)
+ cf->flags |= CANFD_BRS;
- *(__be32 *)(cf->data + 0) = cpu_to_be32(flexcan_read(&mb->data[0]));
- *(__be32 *)(cf->data + 4) = cpu_to_be32(flexcan_read(&mb->data[1]));
+ for (i = 0; i < cf->len; i += 4)
+ *(__be32 *)(cf->data + i) = cpu_to_be32(flexcan_mb_read(priv,
+ n, FLEXCAN_MB_DATA(i / 4)));
+ }
/* mark as read */
if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) {
@@ -773,8 +1058,8 @@ static irqreturn_t flexcan_irq(int irq, void *dev_id)
can_led_event(dev, CAN_LED_EVENT_TX);
/* after sending a RTR frame MB is in RX mode */
- flexcan_write(FLEXCAN_MB_CODE_TX_INACTIVE,
- &priv->tx_mb->can_ctrl);
+ flexcan_mb_write(priv, priv->tx_mb_idx, FLEXCAN_MB_CTRL,
+ FLEXCAN_MB_CODE_TX_INACTIVE);
flexcan_write(FLEXCAN_IFLAG_MB(priv->tx_mb_idx), &regs->iflag1);
netif_wake_queue(dev);
}
@@ -843,38 +1128,77 @@ static void flexcan_set_bittiming(struct net_device *dev)
{
const struct flexcan_priv *priv = netdev_priv(dev);
const struct can_bittiming *bt = &priv->can.bittiming;
+ const struct can_bittiming *dbt = &priv->can.data_bittiming;
struct flexcan_regs __iomem *regs = priv->regs;
u32 reg;
reg = flexcan_read(&regs->ctrl);
- reg &= ~(FLEXCAN_CTRL_PRESDIV(0xff) |
- FLEXCAN_CTRL_RJW(0x3) |
- FLEXCAN_CTRL_PSEG1(0x7) |
- FLEXCAN_CTRL_PSEG2(0x7) |
- FLEXCAN_CTRL_PROPSEG(0x7) |
- FLEXCAN_CTRL_LPB |
- FLEXCAN_CTRL_SMP |
- FLEXCAN_CTRL_LOM);
-
- reg |= FLEXCAN_CTRL_PRESDIV(bt->brp - 1) |
- FLEXCAN_CTRL_PSEG1(bt->phase_seg1 - 1) |
- FLEXCAN_CTRL_PSEG2(bt->phase_seg2 - 1) |
- FLEXCAN_CTRL_RJW(bt->sjw - 1) |
- FLEXCAN_CTRL_PROPSEG(bt->prop_seg - 1);
-
+ reg &= ~(FLEXCAN_CTRL_LPB | FLEXCAN_CTRL_SMP | FLEXCAN_CTRL_LOM);
if (priv->can.ctrlmode & CAN_CTRLMODE_LOOPBACK)
reg |= FLEXCAN_CTRL_LPB;
if (priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY)
reg |= FLEXCAN_CTRL_LOM;
if (priv->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES)
reg |= FLEXCAN_CTRL_SMP;
-
- netdev_dbg(dev, "writing ctrl=0x%08x\n", reg);
flexcan_write(reg, &regs->ctrl);
- /* print chip status */
- netdev_dbg(dev, "%s: mcr=0x%08x ctrl=0x%08x\n", __func__,
- flexcan_read(&regs->mcr), flexcan_read(&regs->ctrl));
+ if (priv->can.ctrlmode_supported & CAN_CTRLMODE_FD) {
+ reg = FLEXCAN_CBT_EPRESDIV(bt->brp - 1) |
+ FLEXCAN_CBT_EPSEG1(bt->phase_seg1 - 1) |
+ FLEXCAN_CBT_EPSEG2(bt->phase_seg2 - 1) |
+ FLEXCAN_CBT_ERJW(bt->sjw - 1) |
+ FLEXCAN_CBT_EPROPSEG(bt->prop_seg - 1) |
+ FLEXCAN_CBT_BTF;
+ flexcan_write(reg, &regs->cbt);
+
+ netdev_dbg(dev, "bt: prediv %d seg1 %d seg2 %d rjw %d propseg %d\n",
+ bt->brp - 1, bt->phase_seg1 - 1, bt->phase_seg2 - 1,
+ bt->sjw - 1, bt->prop_seg - 1);
+
+ if (priv->can.ctrlmode & CAN_CTRLMODE_FD) {
+ reg = FLEXCAN_FDCBT_FPRESDIV(dbt->brp - 1) |
+ FLEXCAN_FDCBT_FPSEG1(dbt->phase_seg1 - 1) |
+ FLEXCAN_FDCBT_FPSEG2(dbt->phase_seg2 - 1) |
+ FLEXCAN_FDCBT_FRJW(dbt->sjw - 1) |
+ FLEXCAN_FDCBT_FPROPSEG(dbt->prop_seg);
+ flexcan_write(reg, &regs->fdcbt);
+
+ if (bt->brp != dbt->brp)
+ netdev_warn(dev, "PRESDIV not the same, may risk transfer errors\n");
+
+ netdev_dbg(dev, "fdbt: prediv %d seg1 %d seg2 %d rjw %d propseg %d\n",
+ dbt->brp - 1, dbt->phase_seg1 - 1, dbt->phase_seg2 - 1,
+ dbt->sjw - 1, dbt->prop_seg);
+
+ netdev_dbg(dev, "%s: mcr=0x%08x ctrl=0x%08x cbt=0x%08x fdcbt=0x%08x\n",
+ __func__, flexcan_read(&regs->mcr),
+ flexcan_read(&regs->ctrl),
+ flexcan_read(&regs->cbt),
+ flexcan_read(&regs->fdcbt));
+ }
+ } else {
+ reg = flexcan_read(&regs->ctrl);
+ reg &= ~(FLEXCAN_CTRL_PRESDIV(0xff) |
+ FLEXCAN_CTRL_RJW(0x3) |
+ FLEXCAN_CTRL_PSEG1(0x7) |
+ FLEXCAN_CTRL_PSEG2(0x7) |
+ FLEXCAN_CTRL_PROPSEG(0x7));
+
+ reg |= FLEXCAN_CTRL_PRESDIV(bt->brp - 1) |
+ FLEXCAN_CTRL_PSEG1(bt->phase_seg1 - 1) |
+ FLEXCAN_CTRL_PSEG2(bt->phase_seg2 - 1) |
+ FLEXCAN_CTRL_RJW(bt->sjw - 1) |
+ FLEXCAN_CTRL_PROPSEG(bt->prop_seg - 1);
+ flexcan_write(reg, &regs->ctrl);
+
+ netdev_dbg(dev, "bt: prediv %d seg1 %d seg2 %d rjw %d propseg %d\n",
+ bt->brp - 1, bt->phase_seg1 - 1, bt->phase_seg2 - 1,
+ bt->sjw - 1, bt->prop_seg - 1);
+
+ /* print chip status */
+ netdev_dbg(dev, "%s: mcr=0x%08x ctrl=0x%08x\n", __func__,
+ flexcan_read(&regs->mcr), flexcan_read(&regs->ctrl));
+ }
}
/* flexcan_chip_start
@@ -886,7 +1210,7 @@ static int flexcan_chip_start(struct net_device *dev)
{
struct flexcan_priv *priv = netdev_priv(dev);
struct flexcan_regs __iomem *regs = priv->regs;
- u32 reg_mcr, reg_ctrl, reg_ctrl2, reg_mecr;
+ u32 reg_mcr, reg_ctrl, reg_ctrl2, reg_mecr, reg_fdctrl;
int err, i;
/* enable module */
@@ -926,6 +1250,10 @@ static int flexcan_chip_start(struct net_device *dev)
reg_mcr |= FLEXCAN_MCR_FEN |
FLEXCAN_MCR_MAXMB(priv->tx_mb_idx);
}
+
+ /* enable self wakeup */
+ reg_mcr |= FLEXCAN_MCR_SLF_WAK;
+
netdev_dbg(dev, "%s: writing mcr=0x%08x", __func__, reg_mcr);
flexcan_write(reg_mcr, &regs->mcr);
@@ -968,25 +1296,57 @@ static int flexcan_chip_start(struct net_device *dev)
flexcan_write(reg_ctrl2, &regs->ctrl2);
}
+ /* CAN FD initialization
+ *
+ * disable BRS by default
+ * Message Buffer Data Size 64 bytes per MB
+ * disable Transceiver Delay Compensation
+ * Configure Message Buffer according to CAN FD mode enabled or not
+ */
+ if (priv->can.ctrlmode & CAN_CTRLMODE_FD) {
+ reg_fdctrl = flexcan_read(&regs->fdctrl) &
+ ~FLEXCAN_CANFD_MBDSR_MASK;
+ reg_fdctrl |= FLEXCAN_CANFD_MBDSR_DEFAULT <<
+ FLEXCAN_CANFD_MBDSR_SHIFT;
+ flexcan_write(reg_fdctrl, &regs->fdctrl);
+ reg_mcr = flexcan_read(&regs->mcr);
+ flexcan_write(reg_mcr | FLEXCAN_MCR_FDEN, &regs->mcr);
+
+ if (!(priv->can.ctrlmode & CAN_CTRLMODE_FD_NON_ISO)) {
+ reg_ctrl2 = flexcan_read(&regs->ctrl2);
+ flexcan_write(reg_ctrl2 | FLEXCAN_CTRL2_ISOCANFDEN, &regs->ctrl2);
+ }
+
+ priv->offload.is_canfd = true;
+
+ priv->mb_size = FLEXCAN_MB_FD_SIZE;
+ priv->mb_num = FLEXCAN_MB_FD_NUM;
+ } else {
+ priv->offload.is_canfd = false;
+
+ priv->mb_size = FLEXCAN_MB_SIZE;
+ priv->mb_num = FLEXCAN_MB_NUM;
+ }
+
/* clear and invalidate all mailboxes first */
- for (i = priv->tx_mb_idx; i < ARRAY_SIZE(regs->mb); i++) {
- flexcan_write(FLEXCAN_MB_CODE_RX_INACTIVE,
- &regs->mb[i].can_ctrl);
+ for (i = priv->tx_mb_idx; i < priv->mb_num ; i++) {
+ flexcan_mb_write(priv, i, FLEXCAN_MB_CTRL,
+ FLEXCAN_MB_CODE_RX_INACTIVE);
}
if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) {
for (i = priv->offload.mb_first; i <= priv->offload.mb_last; i++)
- flexcan_write(FLEXCAN_MB_CODE_RX_EMPTY,
- &regs->mb[i].can_ctrl);
+ flexcan_mb_write(priv, i, FLEXCAN_MB_CTRL,
+ FLEXCAN_MB_CODE_RX_EMPTY);
}
/* Errata ERR005829: mark first TX mailbox as INACTIVE */
- flexcan_write(FLEXCAN_MB_CODE_TX_INACTIVE,
- &priv->tx_mb_reserved->can_ctrl);
+ flexcan_mb_write(priv, priv->tx_mb_reserved_idx, FLEXCAN_MB_CTRL,
+ FLEXCAN_MB_CODE_TX_INACTIVE);
/* mark TX mailbox as INACTIVE */
- flexcan_write(FLEXCAN_MB_CODE_TX_INACTIVE,
- &priv->tx_mb->can_ctrl);
+ flexcan_mb_write(priv, priv->tx_mb_idx, FLEXCAN_MB_CTRL,
+ FLEXCAN_MB_CODE_TX_INACTIVE);
/* acceptance mask/acceptance code (accept everything) */
flexcan_write(0x0, &regs->rxgmask);
@@ -997,7 +1357,7 @@ static int flexcan_chip_start(struct net_device *dev)
flexcan_write(0x0, &regs->rxfgmask);
/* clear acceptance filters */
- for (i = 0; i < ARRAY_SIZE(regs->mb); i++)
+ for (i = priv->tx_mb_idx; i < priv->mb_num ; i++)
flexcan_write(0, &regs->rximr[i]);
/* On Vybrid, disable memory error detection interrupts
@@ -1052,6 +1412,7 @@ static int flexcan_chip_start(struct net_device *dev)
flexcan_transceiver_disable(priv);
out_chip_disable:
flexcan_chip_disable(priv);
+
return err;
}
@@ -1083,17 +1444,13 @@ static int flexcan_open(struct net_device *dev)
struct flexcan_priv *priv = netdev_priv(dev);
int err;
- err = clk_prepare_enable(priv->clk_ipg);
+ err = pm_runtime_get_sync(priv->dev);
if (err)
return err;
- err = clk_prepare_enable(priv->clk_per);
- if (err)
- goto out_disable_ipg;
-
err = open_candev(dev);
if (err)
- goto out_disable_per;
+ goto out_pm_runtime;
err = request_irq(dev->irq, flexcan_irq, IRQF_SHARED, dev->name, dev);
if (err)
@@ -1104,6 +1461,8 @@ static int flexcan_open(struct net_device *dev)
if (err)
goto out_free_irq;
+ device_set_wakeup_capable(priv->dev, priv->wakeup);
+
can_led_event(dev, CAN_LED_EVENT_OPEN);
can_rx_offload_enable(&priv->offload);
@@ -1115,10 +1474,9 @@ static int flexcan_open(struct net_device *dev)
free_irq(dev->irq, dev);
out_close:
close_candev(dev);
- out_disable_per:
- clk_disable_unprepare(priv->clk_per);
- out_disable_ipg:
- clk_disable_unprepare(priv->clk_ipg);
+
+ out_pm_runtime:
+ pm_runtime_put(priv->dev);
return err;
}
@@ -1132,13 +1490,15 @@ static int flexcan_close(struct net_device *dev)
flexcan_chip_stop(dev);
free_irq(dev->irq, dev);
- clk_disable_unprepare(priv->clk_per);
- clk_disable_unprepare(priv->clk_ipg);
close_candev(dev);
+ device_set_wakeup_capable(priv->dev, false);
+
can_led_event(dev, CAN_LED_EVENT_STOP);
+ pm_runtime_put(priv->dev);
+
return 0;
}
@@ -1175,21 +1535,16 @@ static int register_flexcandev(struct net_device *dev)
struct flexcan_regs __iomem *regs = priv->regs;
u32 reg, err;
- err = clk_prepare_enable(priv->clk_ipg);
- if (err)
- return err;
-
- err = clk_prepare_enable(priv->clk_per);
- if (err)
- goto out_disable_ipg;
-
/* select "bus clock", chip must be disabled */
err = flexcan_chip_disable(priv);
if (err)
- goto out_disable_per;
- reg = flexcan_read(&regs->ctrl);
- reg |= FLEXCAN_CTRL_CLK_SRC;
- flexcan_write(reg, &regs->ctrl);
+ return err;
+
+ if (priv->clk_src) {
+ reg = flexcan_read(&regs->ctrl);
+ reg |= FLEXCAN_CTRL_CLK_SRC;
+ flexcan_write(reg, &regs->ctrl);
+ }
err = flexcan_chip_enable(priv);
if (err)
@@ -1218,10 +1573,6 @@ static int register_flexcandev(struct net_device *dev)
/* disable core and turn off clocks */
out_chip_disable:
flexcan_chip_disable(priv);
- out_disable_per:
- clk_disable_unprepare(priv->clk_per);
- out_disable_ipg:
- clk_disable_unprepare(priv->clk_ipg);
return err;
}
@@ -1231,7 +1582,86 @@ static void unregister_flexcandev(struct net_device *dev)
unregister_candev(dev);
}
+#ifdef CONFIG_ARCH_MXC_ARM64
+static int imx8_sc_ipc_fetch(struct platform_device *pdev)
+{
+ struct net_device *dev = platform_get_drvdata(pdev);
+ struct flexcan_priv *priv;
+ sc_err_t sc_err = SC_ERR_NONE;
+ u32 mu_id;
+
+ priv = netdev_priv(dev);
+
+ sc_err = sc_ipc_getMuID(&mu_id);
+ if (sc_err != SC_ERR_NONE) {
+ pr_err("FLEXCAN ipg stop: Get MU ID failed\n");
+ return sc_err;
+ }
+
+ sc_err = sc_ipc_open(&priv->ipc_handle, mu_id);
+ if (sc_err != SC_ERR_NONE) {
+ pr_err("FLEXCAN ipg stop: Open MU channel failed\n");
+ return sc_err;
+ }
+
+ return sc_err;
+}
+#else
+static int imx8_sc_ipc_fetch(struct platform_device *pdev) { return 0; }
+#endif
+
+static int flexcan_of_parse_stop_mode(struct platform_device *pdev)
+{
+ struct net_device *dev = platform_get_drvdata(pdev);
+ struct device_node *np = pdev->dev.of_node;
+ struct device_node *node;
+ struct flexcan_priv *priv;
+ phandle phandle;
+ u32 out_val[5];
+ int ret;
+
+ if (!np)
+ return -EINVAL;
+ /*
+ * stop mode property format is:
+ * <&gpr req_gpr req_bit ack_gpr ack_bit>.
+ */
+ ret = of_property_read_u32_array(np, "stop-mode", out_val, 5);
+ if (ret) {
+ dev_dbg(&pdev->dev, "no stop-mode property\n");
+ return ret;
+ }
+ phandle = *out_val;
+
+ node = of_find_node_by_phandle(phandle);
+ if (!node) {
+ dev_dbg(&pdev->dev, "could not find gpr node by phandle\n");
+ return PTR_ERR(node);
+ }
+
+ priv = netdev_priv(dev);
+ priv->stm.gpr = syscon_node_to_regmap(node);
+ if (IS_ERR(priv->stm.gpr)) {
+ dev_dbg(&pdev->dev, "could not find gpr regmap\n");
+ return PTR_ERR(priv->stm.gpr);
+ }
+
+ of_node_put(node);
+
+ priv->stm.req_gpr = out_val[1];
+ priv->stm.req_bit = out_val[2];
+ priv->stm.ack_gpr = out_val[3];
+ priv->stm.ack_bit = out_val[4];
+
+ dev_dbg(&pdev->dev, "gpr %s req_gpr 0x%x req_bit %u ack_gpr 0x%x ack_bit %u\n",
+ node->full_name, priv->stm.req_gpr,
+ priv->stm.req_bit, priv->stm.ack_gpr,
+ priv->stm.ack_bit);
+ return 0;
+}
+
static const struct of_device_id flexcan_of_match[] = {
+ { .compatible = "fsl,imx8qm-flexcan", .data = &fsl_imx8qm_devtype_data, },
{ .compatible = "fsl,imx6q-flexcan", .data = &fsl_imx6q_devtype_data, },
{ .compatible = "fsl,imx28-flexcan", .data = &fsl_imx28_devtype_data, },
{ .compatible = "fsl,p1010-flexcan", .data = &fsl_p1010_devtype_data, },
@@ -1258,6 +1688,7 @@ static int flexcan_probe(struct platform_device *pdev)
struct flexcan_regs __iomem *regs;
int err, irq;
u32 clock_freq = 0;
+ u32 clk_src = 1;
reg_xceiver = devm_regulator_get(&pdev->dev, "xceiver");
if (PTR_ERR(reg_xceiver) == -EPROBE_DEFER)
@@ -1265,9 +1696,12 @@ static int flexcan_probe(struct platform_device *pdev)
else if (IS_ERR(reg_xceiver))
reg_xceiver = NULL;
- if (pdev->dev.of_node)
+ if (pdev->dev.of_node) {
of_property_read_u32(pdev->dev.of_node,
"clock-frequency", &clock_freq);
+ of_property_read_u32(pdev->dev.of_node,
+ "clk-src", &clk_src);
+ }
if (!clock_freq) {
clk_ipg = devm_clk_get(&pdev->dev, "ipg");
@@ -1315,27 +1749,46 @@ static int flexcan_probe(struct platform_device *pdev)
dev->flags |= IFF_ECHO;
priv = netdev_priv(dev);
+ priv->dev = &pdev->dev;
+ priv->clk_src = clk_src;
priv->can.clock.freq = clock_freq;
priv->can.bittiming_const = &flexcan_bittiming_const;
+ priv->can.data_bittiming_const = &flexcan_fd_data_bittiming_const;
priv->can.do_set_mode = flexcan_set_mode;
priv->can.do_get_berr_counter = flexcan_get_berr_counter;
priv->can.ctrlmode_supported = CAN_CTRLMODE_LOOPBACK |
CAN_CTRLMODE_LISTENONLY | CAN_CTRLMODE_3_SAMPLES |
CAN_CTRLMODE_BERR_REPORTING;
priv->regs = regs;
+ priv->base = regs;
priv->clk_ipg = clk_ipg;
priv->clk_per = clk_per;
+ priv->pdata = dev_get_platdata(&pdev->dev);
priv->devtype_data = devtype_data;
priv->reg_xceiver = reg_xceiver;
+ priv->offload.is_canfd = false;
if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) {
- priv->tx_mb_idx = FLEXCAN_TX_MB_OFF_TIMESTAMP;
- priv->tx_mb_reserved = &regs->mb[FLEXCAN_TX_MB_RESERVED_OFF_TIMESTAMP];
+ if (priv->devtype_data->quirks & FLEXCAN_QUIRK_TIMESTAMP_SUPPORT_FD) {
+ priv->can.ctrlmode_supported |= CAN_CTRLMODE_FD | CAN_CTRLMODE_FD_NON_ISO;
+ priv->can.bittiming_const = &flexcan_fd_bittiming_const;
+
+ priv->tx_mb_reserved_idx = FLEXCAN_TX_MB_RESERVED_OFF_TIMESTAMP_FD;
+ priv->tx_mb_idx = FLEXCAN_TX_MB_OFF_TIMESTAMP_FD;
+ } else {
+ priv->tx_mb_reserved_idx = FLEXCAN_TX_MB_RESERVED_OFF_TIMESTAMP;
+ priv->tx_mb_idx = FLEXCAN_TX_MB_OFF_TIMESTAMP;
+ }
} else {
+ if (priv->devtype_data->quirks & FLEXCAN_QUIRK_TIMESTAMP_SUPPORT_FD) {
+ dev_err(&pdev->dev, "canfd mode can't work on fifo mode\n");
+ err = -EINVAL;
+ goto failed_offload;
+ }
+
+ priv->tx_mb_reserved_idx = FLEXCAN_TX_MB_RESERVED_OFF_FIFO;
priv->tx_mb_idx = FLEXCAN_TX_MB_OFF_FIFO;
- priv->tx_mb_reserved = &regs->mb[FLEXCAN_TX_MB_RESERVED_OFF_FIFO];
}
- priv->tx_mb = &regs->mb[priv->tx_mb_idx];
priv->reg_imask1_default = FLEXCAN_IFLAG_MB(priv->tx_mb_idx);
priv->reg_imask2_default = 0;
@@ -1345,8 +1798,13 @@ static int flexcan_probe(struct platform_device *pdev)
if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) {
u64 imask;
- priv->offload.mb_first = FLEXCAN_RX_MB_OFF_TIMESTAMP_FIRST;
- priv->offload.mb_last = FLEXCAN_RX_MB_OFF_TIMESTAMP_LAST;
+ if (priv->devtype_data->quirks & FLEXCAN_QUIRK_TIMESTAMP_SUPPORT_FD) {
+ priv->offload.mb_first = FLEXCAN_RX_MB_OFF_TIMESTAMP_FD_FIRST;
+ priv->offload.mb_last = FLEXCAN_RX_MB_OFF_TIMESTAMP_FD_LAST;
+ } else {
+ priv->offload.mb_first = FLEXCAN_RX_MB_OFF_TIMESTAMP_FIRST;
+ priv->offload.mb_last = FLEXCAN_RX_MB_OFF_TIMESTAMP_LAST;
+ }
imask = GENMASK_ULL(priv->offload.mb_last, priv->offload.mb_first);
priv->reg_imask1_default |= imask;
@@ -1361,22 +1819,50 @@ static int flexcan_probe(struct platform_device *pdev)
if (err)
goto failed_offload;
+ pm_runtime_enable(&pdev->dev);
+ err = pm_runtime_get_sync(&pdev->dev);
+ if (err < 0) {
+ dev_err(&pdev->dev, "pm_runtime_get failed(%d)\n", err);
+ goto failed_rpm_disable;
+ }
+
err = register_flexcandev(dev);
if (err) {
dev_err(&pdev->dev, "registering netdev failed\n");
- goto failed_register;
+ goto failed_rpm_put;
}
devm_can_led_init(dev);
+ priv->wakeup = true;
+ if (priv->devtype_data->quirks & FLEXCAN_QUIRK_TIMESTAMP_SUPPORT_FD) {
+ err = imx8_sc_ipc_fetch(pdev);
+ if (err) {
+ priv->wakeup = false;
+ dev_dbg(&pdev->dev, "failed to fetch scu ipc\n");
+ }
+ } else if (priv->devtype_data->quirks & FLEXCAN_QUIRK_DISABLE_RXFG) {
+ err = flexcan_of_parse_stop_mode(pdev);
+ if (err) {
+ priv->wakeup = false;;
+ dev_dbg(&pdev->dev, "failed to parse stop-mode\n");
+ }
+ }
+
+ pm_runtime_put(&pdev->dev);
+
dev_info(&pdev->dev, "device registered (reg_base=%p, irq=%d)\n",
priv->regs, dev->irq);
return 0;
+ failed_rpm_put:
+ pm_runtime_put(priv->dev);
+ failed_rpm_disable:
+ pm_runtime_disable(&pdev->dev);
failed_offload:
- failed_register:
free_candev(dev);
+
return err;
}
@@ -1385,7 +1871,11 @@ static int flexcan_remove(struct platform_device *pdev)
struct net_device *dev = platform_get_drvdata(pdev);
struct flexcan_priv *priv = netdev_priv(dev);
+#ifdef CONFIG_ARCH_MXC_ARM64
+ sc_ipc_close(priv->ipc_handle);
+#endif
unregister_flexcandev(dev);
+ pm_runtime_disable(&pdev->dev);
can_rx_offload_del(&priv->offload);
free_candev(dev);
@@ -1396,38 +1886,106 @@ static int __maybe_unused flexcan_suspend(struct device *device)
{
struct net_device *dev = dev_get_drvdata(device);
struct flexcan_priv *priv = netdev_priv(dev);
- int err;
+ int ret = 0;
if (netif_running(dev)) {
- err = flexcan_chip_disable(priv);
- if (err)
- return err;
netif_stop_queue(dev);
netif_device_detach(dev);
+ /*
+ * if wakeup is enabled, enter stop mode
+ * else enter disabled mode.
+ */
+ if (device_may_wakeup(device)) {
+ enable_irq_wake(dev->irq);
+ flexcan_enter_stop_mode(priv);
+ } else {
+ flexcan_chip_stop(dev);
+ ret = pm_runtime_force_suspend(device);
+
+ pinctrl_pm_select_sleep_state(device);
+ }
}
priv->can.state = CAN_STATE_SLEEPING;
- return 0;
+ return ret;
}
static int __maybe_unused flexcan_resume(struct device *device)
{
struct net_device *dev = dev_get_drvdata(device);
struct flexcan_priv *priv = netdev_priv(dev);
- int err;
+ int err = 0;
priv->can.state = CAN_STATE_ERROR_ACTIVE;
if (netif_running(dev)) {
netif_device_attach(dev);
netif_start_queue(dev);
- err = flexcan_chip_enable(priv);
- if (err)
- return err;
+
+ if (device_may_wakeup(device)) {
+ flexcan_wake_mask_disable(priv);
+ } else {
+ pinctrl_pm_select_default_state(device);
+
+ err = pm_runtime_force_resume(device);
+ if (err)
+ return err;
+ err = flexcan_chip_start(dev);
+ }
}
+
+ return err;
+}
+
+static int __maybe_unused flexcan_runtime_suspend(struct device *device)
+{
+ struct net_device *dev = dev_get_drvdata(device);
+ struct flexcan_priv *priv = netdev_priv(dev);
+
+ flexcan_clks_disable(priv);
+
+ return 0;
+}
+
+static int __maybe_unused flexcan_runtime_resume(struct device *device)
+{
+ struct net_device *dev = dev_get_drvdata(device);
+ struct flexcan_priv *priv = netdev_priv(dev);
+
+ flexcan_clks_enable(priv);
+
+ return 0;
+}
+
+static int __maybe_unused flexcan_noirq_suspend(struct device *device)
+{
+ struct net_device *dev = dev_get_drvdata(device);
+ struct flexcan_priv *priv = netdev_priv(dev);
+
+ if (netif_running(dev) && device_may_wakeup(device)) {
+ flexcan_wake_mask_enable(priv);
+ }
+
+ return 0;
+}
+
+static int __maybe_unused flexcan_noirq_resume(struct device *device)
+{
+ struct net_device *dev = dev_get_drvdata(device);
+ struct flexcan_priv *priv = netdev_priv(dev);
+
+ if (netif_running(dev) && device_may_wakeup(device)) {
+ disable_irq_wake(dev->irq);
+ flexcan_exit_stop_mode(priv);
+ }
+
return 0;
}
-static SIMPLE_DEV_PM_OPS(flexcan_pm_ops, flexcan_suspend, flexcan_resume);
+static const struct dev_pm_ops flexcan_pm_ops = {
+ SET_SYSTEM_SLEEP_PM_OPS(flexcan_suspend, flexcan_resume)
+ SET_RUNTIME_PM_OPS(flexcan_runtime_suspend, flexcan_runtime_resume, NULL)
+ SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(flexcan_noirq_suspend, flexcan_noirq_resume)
+};
static struct platform_driver flexcan_driver = {
.driver = {
diff --git a/drivers/net/can/rx-offload.c b/drivers/net/can/rx-offload.c
index 54ffd1e91a69..08fa75d6c605 100644
--- a/drivers/net/can/rx-offload.c
+++ b/drivers/net/can/rx-offload.c
@@ -55,11 +55,11 @@ static int can_rx_offload_napi_poll(struct napi_struct *napi, int quota)
while ((work_done < quota) &&
(skb = skb_dequeue(&offload->skb_queue))) {
- struct can_frame *cf = (struct can_frame *)skb->data;
+ struct canfd_frame *cf = (struct canfd_frame *)skb->data;
work_done++;
stats->rx_packets++;
- stats->rx_bytes += cf->can_dlc;
+ stats->rx_bytes += cf->len;
netif_receive_skb(skb);
}
@@ -142,23 +142,20 @@ can_rx_offload_offload_one(struct can_rx_offload *offload, unsigned int n)
{
struct sk_buff *skb = NULL, *skb_error = NULL;
struct can_rx_offload_cb *cb;
- struct can_frame *cf;
+ struct canfd_frame *cf;
int ret;
- if (likely(skb_queue_len(&offload->skb_queue) <
+ /* If queue is full or skb not available, read to discard mailbox */
+ if (likely(skb_queue_len(&offload->skb_queue) <=
offload->skb_queue_len_max)) {
- skb = alloc_can_skb(offload->dev, &cf);
- if (unlikely(!skb))
- skb_error = ERR_PTR(-ENOMEM); /* skb alloc failed */
- } else {
- skb_error = ERR_PTR(-ENOBUFS); /* skb_queue is full */
+ if (offload->is_canfd)
+ skb = alloc_canfd_skb(offload->dev, &cf);
+ else
+ skb = alloc_can_skb(offload->dev, (struct can_frame **)&cf);
}
- /* If queue is full or skb not available, drop by reading into
- * overflow buffer.
- */
- if (unlikely(skb_error)) {
- struct can_frame cf_overflow;
+ if (!skb) {
+ struct canfd_frame cf_overflow;
u32 timestamp;
ret = offload->mailbox_read(offload, &cf_overflow,
diff --git a/drivers/net/ethernet/freescale/Kconfig b/drivers/net/ethernet/freescale/Kconfig
index 6e490fd2345d..f9d3300d4b2b 100644
--- a/drivers/net/ethernet/freescale/Kconfig
+++ b/drivers/net/ethernet/freescale/Kconfig
@@ -8,7 +8,7 @@ config NET_VENDOR_FREESCALE
depends on FSL_SOC || QUICC_ENGINE || CPM1 || CPM2 || PPC_MPC512x || \
M523x || M527x || M5272 || M528x || M520x || M532x || \
ARCH_MXC || ARCH_MXS || (PPC_MPC52xx && PPC_BESTCOMM) || \
- ARCH_LAYERSCAPE || COMPILE_TEST
+ ARCH_LAYERSCAPE || ARCH_MXC_ARM64 || COMPILE_TEST
---help---
If you have a network (Ethernet) card belonging to this class, say Y.
@@ -22,8 +22,8 @@ if NET_VENDOR_FREESCALE
config FEC
tristate "FEC ethernet controller (of ColdFire and some i.MX CPUs)"
depends on (M523x || M527x || M5272 || M528x || M520x || M532x || \
- ARCH_MXC || SOC_IMX28)
- default ARCH_MXC || SOC_IMX28 if ARM
+ ARM || ARM64)
+ default y
select PHYLIB
imply PTP_1588_CLOCK
---help---
diff --git a/drivers/net/ethernet/freescale/Makefile b/drivers/net/ethernet/freescale/Makefile
index ed8ad0fefbda..823f75a84809 100644
--- a/drivers/net/ethernet/freescale/Makefile
+++ b/drivers/net/ethernet/freescale/Makefile
@@ -4,7 +4,7 @@
#
obj-$(CONFIG_FEC) += fec.o
-fec-objs :=fec_main.o fec_ptp.o
+fec-objs :=fec_main.o fec_fixup.o fec_ptp.o
obj-$(CONFIG_FEC_MPC52xx) += fec_mpc52xx.o
ifeq ($(CONFIG_FEC_MPC52xx_MDIO),y)
diff --git a/drivers/net/ethernet/freescale/fec.h b/drivers/net/ethernet/freescale/fec.h
index 4d4f16ad88c3..14a2c2e7e027 100644
--- a/drivers/net/ethernet/freescale/fec.h
+++ b/drivers/net/ethernet/freescale/fec.h
@@ -16,11 +16,13 @@
#include <linux/clocksource.h>
#include <linux/net_tstamp.h>
+#include <linux/pm_qos.h>
#include <linux/ptp_clock_kernel.h>
#include <linux/timecounter.h>
#if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x) || \
- defined(CONFIG_M520x) || defined(CONFIG_M532x) || defined(CONFIG_ARM)
+ defined(CONFIG_M520x) || defined(CONFIG_M532x) || defined(CONFIG_ARM) || \
+ defined(CONFIG_ARM64)
/*
* Just figures, Motorola would have to change the offsets for
* registers in the same peripheral device on different models
@@ -76,6 +78,8 @@
#define FEC_R_DES_ACTIVE_2 0x1e8 /* Rx descriptor active for ring 2 */
#define FEC_X_DES_ACTIVE_2 0x1ec /* Tx descriptor active for ring 2 */
#define FEC_QOS_SCHEME 0x1f0 /* Set multi queues Qos scheme */
+#define FEC_LPI_SLEEP 0x1f4 /* Set IEEE802.3az LPI Sleep Ts time */
+#define FEC_LPI_WAKE 0x1f8 /* Set IEEE802.3az LPI Wake Tw time */
#define FEC_MIIGSK_CFGR 0x300 /* MIIGSK Configuration reg */
#define FEC_MIIGSK_ENR 0x308 /* MIIGSK Enable reg */
@@ -195,7 +199,7 @@
* Evidently, ARM SoCs have the FEC block generated in a
* little endian mode so adjust endianness accordingly.
*/
-#if defined(CONFIG_ARM)
+#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
#define fec32_to_cpu le32_to_cpu
#define fec16_to_cpu le16_to_cpu
#define cpu_to_fec32 cpu_to_le32
@@ -293,7 +297,7 @@ struct bufdesc_ex {
/* This device has up to three irqs on some platforms */
-#define FEC_IRQ_NUM 3
+#define FEC_IRQ_NUM 4
/* Maximum number of queues supported
* ENET with AVB IP can support up to 3 independent tx queues and rx queues.
@@ -354,6 +358,8 @@ struct bufdesc_ex {
#define FLAG_RX_CSUM_ENABLED (BD_ENET_RX_ICE | BD_ENET_RX_PCR)
#define FLAG_RX_CSUM_ERROR (BD_ENET_RX_ICE | BD_ENET_RX_PCR)
+#define FEC0_MII_BUS_SHARE_TRUE 1
+
/* Interrupt events/masks. */
#define FEC_ENET_HBERR ((uint)0x80000000) /* Heartbeat error */
#define FEC_ENET_BABR ((uint)0x40000000) /* Babbling receiver */
@@ -379,6 +385,10 @@ struct bufdesc_ex {
#define FEC_NAPI_IMASK FEC_ENET_MII
#define FEC_RX_DISABLED_IMASK (FEC_DEFAULT_IMASK & (~FEC_ENET_RXF))
+#define FEC_ENET_ETHEREN ((uint)0x00000002)
+#define FEC_ENET_TXC_DLY ((uint)0x00010000)
+#define FEC_ENET_RXC_DLY ((uint)0x00020000)
+
/* ENET interrupt coalescing macro define */
#define FEC_ITR_CLK_SEL (0x1 << 30)
#define FEC_ITR_EN (0x1 << 31)
@@ -455,6 +465,30 @@ struct bufdesc_ex {
* those FIFO receive registers are resolved in other platforms.
*/
#define FEC_QUIRK_HAS_FRREG (1 << 16)
+/*
+ * i.MX6Q/DL ENET cannot wake up system in wait mode because ENET tx & rx
+ * interrupt signal don't connect to GPC. So use pm qos to avoid cpu enter
+ * to wait mode.
+ */
+#define FEC_QUIRK_BUG_WAITMODE (1 << 16)
+
+/* PHY fixup flag define */
+#define FEC_QUIRK_AR8031_FIXUP (1 << 16)
+
+/* i.MX8QM/QXP ENET IP version add new feture to generate delayed TXC/RXC
+ * as an alternative option to make sure it can work well with various PHYs.
+ * - For the implementation of delayed TXC, ENET will take synchronized 250/125MHz
+ * clocks to generate 2ns delay by registering original TXC with positive edge
+ * of inverted 250MHz clock.
+ * - For the implementation of delayed RXC, there will be buffers in the subsystem
+ * level. The exact length of delay buffers will be decided when closing I/O timing.
+ */
+#define FEC_QUIRK_DELAYED_CLKS_SUPPORT (1 << 17)
+/* i.MX8MQ ENET IP version add new feature to support IEEE 802.3az EEE
+ * standard. For the transmission, MAC supply two user registers to set
+ * Sleep (TS) and Wake (TW) time.
+ */
+#define FEC_QUIRK_HAS_EEE (1 << 18)
struct bufdesc_prop {
int qid;
@@ -469,6 +503,12 @@ struct bufdesc_prop {
unsigned char dsize_log2;
};
+struct fec_enet_stop_mode {
+ struct regmap *gpr;
+ u8 req_gpr;
+ u8 req_bit;
+};
+
struct fec_enet_priv_tx_q {
struct bufdesc_prop bd;
unsigned char *tx_bounce[TX_RING_SIZE];
@@ -506,6 +546,7 @@ struct fec_enet_private {
struct clk *clk_ref;
struct clk *clk_enet_out;
struct clk *clk_ptp;
+ struct clk *clk_2x_txclk;
bool ptp_clk_on;
struct mutex ptp_clk_mutex;
@@ -531,10 +572,15 @@ struct fec_enet_private {
/* Phylib and MDIO interface */
struct mii_bus *mii_bus;
int mii_timeout;
+ int mii_bus_share;
+ bool active_in_suspend;
uint phy_speed;
phy_interface_t phy_interface;
struct device_node *phy_node;
int link;
+ bool fixed_link;
+ bool rgmii_txc_dly;
+ bool rgmii_rxc_dly;
int full_duplex;
int speed;
struct completion mdio_done;
@@ -542,7 +588,9 @@ struct fec_enet_private {
bool bufdesc_ex;
int pause_flag;
int wol_flag;
+ int wake_irq;
u32 quirks;
+ u32 fixups;
struct napi_struct napi;
int csum_flags;
@@ -562,6 +610,7 @@ struct fec_enet_private {
int hwts_tx_en;
struct delayed_work time_keep;
struct regulator *reg_phy;
+ struct pm_qos_request pm_qos_req;
unsigned int tx_align;
unsigned int rx_align;
@@ -573,6 +622,10 @@ struct fec_enet_private {
unsigned int tx_time_itr;
unsigned int itr_clk_rate;
+ /* tx lpi eee mode */
+ struct ethtool_eee eee;
+ unsigned int clk_ref_rate;
+
u32 rx_copybreak;
/* ptp clock period in ns*/
@@ -584,6 +637,8 @@ struct fec_enet_private {
int pps_enable;
unsigned int next_counter;
+ struct fec_enet_stop_mode gpr;
+
u64 ethtool_stats[0];
};
@@ -593,6 +648,10 @@ void fec_ptp_start_cyclecounter(struct net_device *ndev);
int fec_ptp_set(struct net_device *ndev, struct ifreq *ifr);
int fec_ptp_get(struct net_device *ndev, struct ifreq *ifr);
uint fec_ptp_check_pps_event(struct fec_enet_private *fep);
+void fec_enet_register_fixup(struct net_device *ndev);
+int of_fec_enet_parse_fixup(struct device_node *np);
+void fec_enet_get_mac_from_fuse(struct device_node *np, unsigned char *mac);
+void fec_enet_ipg_stop_misc_set(struct device_node *np, bool enabled);
/****************************************************************************/
#endif /* FEC_H */
diff --git a/drivers/net/ethernet/freescale/fec_fixup.c b/drivers/net/ethernet/freescale/fec_fixup.c
new file mode 100644
index 000000000000..d2e2d50cb28f
--- /dev/null
+++ b/drivers/net/ethernet/freescale/fec_fixup.c
@@ -0,0 +1,278 @@
+/*
+ * Copyright 2017 NXP
+ *
+ * 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/netdevice.h>
+#include <linux/phy.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#ifdef CONFIG_ARCH_MXC_ARM64
+#include <soc/imx8/sc/sci.h>
+#endif
+#include "fec.h"
+
+#define PHY_ID_AR8031 0x004dd074
+
+#define IMX8QM_FUSE_MAC0_WORD0 452
+#define IMX8QM_FUSE_MAC0_WORD1 453
+#define IMX8QM_FUSE_MAC1_WORD0 454
+#define IMX8QM_FUSE_MAC1_WORD1 455
+#define IMX8QXP_FUSE_MAC0_WORD0 708
+#define IMX8QXP_FUSE_MAC0_WORD1 709
+#define IMX8QXP_FUSE_MAC1_WORD0 710
+#define IMX8QXP_FUSE_MAC1_WORD1 711
+#define IMX8M_OCOTP_MAC_ADDR0_OFF 0x640
+#define IMX8M_OCOTP_MAC_ADDR1_OFF 0x650
+
+enum imx_soc_type {
+ IMX8QM_FUSE = 0,
+ IMX8QXP_FUSE,
+};
+
+struct imx_fuse_mac_addr {
+ u32 fuse_mac0_word0;
+ u32 fuse_mac0_word1;
+ u32 fuse_mac1_word0;
+ u32 fuse_mac1_word1;
+};
+
+static struct imx_fuse_mac_addr imx8_fuse_mapping[] = {
+ {
+ .fuse_mac0_word0 = IMX8QM_FUSE_MAC0_WORD0,
+ .fuse_mac0_word1 = IMX8QM_FUSE_MAC0_WORD1,
+ .fuse_mac1_word0 = IMX8QM_FUSE_MAC1_WORD0,
+ .fuse_mac1_word1 = IMX8QM_FUSE_MAC1_WORD1,
+ }, {
+ .fuse_mac0_word0 = IMX8QXP_FUSE_MAC0_WORD0,
+ .fuse_mac0_word1 = IMX8QXP_FUSE_MAC0_WORD1,
+ .fuse_mac1_word0 = IMX8QXP_FUSE_MAC1_WORD0,
+ .fuse_mac1_word1 = IMX8QXP_FUSE_MAC1_WORD1,
+ }, {
+ /* sentinel */
+ }
+};
+
+static int ar8031_phy_fixup(struct phy_device *dev)
+{
+ u16 val;
+
+ /* Set RGMII IO voltage to 1.8V */
+ phy_write(dev, 0x1d, 0x1f);
+ phy_write(dev, 0x1e, 0x8);
+
+ /* Disable phy AR8031 SmartEEE function */
+ phy_write(dev, 0xd, 0x3);
+ phy_write(dev, 0xe, 0x805d);
+ phy_write(dev, 0xd, 0x4003);
+ val = phy_read(dev, 0xe);
+ val &= ~(0x1 << 8);
+ phy_write(dev, 0xe, val);
+
+ /* Introduce tx clock delay */
+ phy_write(dev, 0x1d, 0x5);
+ phy_write(dev, 0x1e, 0x100);
+
+ return 0;
+}
+
+void fec_enet_register_fixup(struct net_device *ndev)
+{
+ struct fec_enet_private *fep = netdev_priv(ndev);
+ int err;
+
+ if (!IS_BUILTIN(CONFIG_PHYLIB))
+ return;
+
+ if (fep->fixups & FEC_QUIRK_AR8031_FIXUP) {
+ static int ar8031_registered = 0;
+
+ if (ar8031_registered)
+ return;
+ err = phy_register_fixup_for_uid(PHY_ID_AR8031, 0xffffffef,
+ ar8031_phy_fixup);
+ if (err)
+ netdev_info(ndev, "Cannot register PHY board fixup\n");
+ ar8031_registered = 1;
+ }
+}
+
+int of_fec_enet_parse_fixup(struct device_node *np)
+{
+ int fixups = 0;
+
+ if (of_get_property(np, "fsl,ar8031-phy-fixup", NULL))
+ fixups |= FEC_QUIRK_AR8031_FIXUP;
+
+ return fixups;
+}
+
+static void imx8mq_get_mac_from_fuse(int dev_id, unsigned char *mac)
+{
+ struct device_node *ocotp_np;
+ void __iomem *base;
+ u32 value;
+
+ ocotp_np = of_find_compatible_node(NULL, NULL, "fsl,imx7d-ocotp");
+ if (!ocotp_np) {
+ pr_warn("failed to find ocotp node\n");
+ return;
+ }
+
+ base = of_iomap(ocotp_np, 0);
+ if (!base) {
+ pr_warn("failed to map ocotp\n");
+ goto put_ocotp_node;
+ }
+
+ value = readl_relaxed(base + IMX8M_OCOTP_MAC_ADDR1_OFF);
+ mac[0] = (value >> 8);
+ mac[1] = value;
+
+ value = readl_relaxed(base + IMX8M_OCOTP_MAC_ADDR0_OFF);
+ mac[2] = value >> 24;
+ mac[3] = value >> 16;
+ mac[4] = value >> 8;
+ mac[5] = value;
+
+put_ocotp_node:
+ of_node_put(ocotp_np);
+}
+
+#ifdef CONFIG_ARCH_MXC_ARM64
+static void imx8qm_get_mac_from_fuse(int dev_id, unsigned char *mac,
+ struct imx_fuse_mac_addr *fuse_mapping)
+{
+ uint32_t mu_id;
+ sc_ipc_t ipc_handle;
+ sc_err_t sc_err = SC_ERR_NONE;
+ uint32_t val1 = 0, val2 = 0;
+ uint32_t word1, word2;
+
+ sc_err = sc_ipc_getMuID(&mu_id);
+ if (sc_err != SC_ERR_NONE) {
+ pr_err("FEC MAC fuse: Get MU ID failed\n");
+ return;
+ }
+
+ sc_err = sc_ipc_open(&ipc_handle, mu_id);
+ if (sc_err != SC_ERR_NONE) {
+ pr_err("FEC MAC fuse: Open MU channel failed\n");
+ return;
+ }
+
+ if (dev_id == 0) {
+ word1 = fuse_mapping->fuse_mac0_word0;
+ word2 = fuse_mapping->fuse_mac0_word1;
+ } else {
+ word1 = fuse_mapping->fuse_mac1_word0;
+ word2 = fuse_mapping->fuse_mac1_word1;
+ }
+
+ sc_err = sc_misc_otp_fuse_read(ipc_handle, word1, &val1);
+ if (sc_err != SC_ERR_NONE) {
+ pr_err("FEC MAC fuse %d read error: %d\n", word1, sc_err);
+ sc_ipc_close(ipc_handle);
+ return;
+ }
+
+ sc_err = sc_misc_otp_fuse_read(ipc_handle, word2, &val2);
+ if (sc_err != SC_ERR_NONE) {
+ pr_err("FEC MAC fuse %d read error: %d\n", word2, sc_err);
+ sc_ipc_close(ipc_handle);
+ return;
+ }
+
+ mac[0] = val1;
+ mac[1] = val1 >> 8;
+ mac[2] = val1 >> 16;
+ mac[3] = val1 >> 24;
+ mac[4] = val2;
+ mac[5] = val2 >> 8;
+
+ sc_ipc_close(ipc_handle);
+}
+
+static void imx8qm_ipg_stop_enable(int dev_id, bool enabled)
+{
+ uint32_t mu_id;
+ sc_ipc_t ipc_handle;
+ sc_err_t sc_err = SC_ERR_NONE;
+ uint32_t rsrc_id, val;
+
+ sc_err = sc_ipc_getMuID(&mu_id);
+ if (sc_err != SC_ERR_NONE) {
+ pr_err("FEC ipg stop: Get MU ID failed\n");
+ return;
+ }
+
+ sc_err = sc_ipc_open(&ipc_handle, mu_id);
+ if (sc_err != SC_ERR_NONE) {
+ pr_err("FEC ipg stop: Open MU channel failed\n");
+ return;
+ }
+
+ if (dev_id == 0)
+ rsrc_id = SC_R_ENET_0;
+ else
+ rsrc_id = SC_R_ENET_1;
+
+ val = enabled ? 1 : 0;
+ sc_err = sc_misc_set_control(ipc_handle, rsrc_id, SC_C_IPG_STOP, val);
+ if (sc_err != SC_ERR_NONE)
+ pr_err("FEC ipg stop set error: %d\n", sc_err);
+
+ sc_ipc_close(ipc_handle);
+}
+#else
+static void imx8qm_get_mac_from_fuse(int dev_id, unsigned char *mac,
+ struct imx_fuse_mac_addr *fuse_mapping) {}
+static void imx8qm_ipg_stop_enable(int dev_id, bool enabled) {}
+#endif
+
+void fec_enet_get_mac_from_fuse(struct device_node *np, unsigned char *mac)
+{
+ int idx;
+
+ if (!np)
+ return;
+
+ idx = of_alias_get_id(np, "ethernet");
+ if (idx < 0)
+ idx = 0;
+
+ if (of_machine_is_compatible("fsl,imx8qm"))
+ imx8qm_get_mac_from_fuse(idx, mac,
+ &imx8_fuse_mapping[IMX8QM_FUSE]);
+ else if (of_machine_is_compatible("fsl,imx8qxp"))
+ imx8qm_get_mac_from_fuse(idx, mac,
+ &imx8_fuse_mapping[IMX8QXP_FUSE]);
+ else if (of_machine_is_compatible("fsl,imx8mq") ||
+ of_machine_is_compatible("fsl,imx8mm"))
+ imx8mq_get_mac_from_fuse(idx, mac);
+}
+
+void fec_enet_ipg_stop_misc_set(struct device_node *np, bool enabled)
+{
+ int idx;
+
+ if (!np)
+ return;
+
+ idx = of_alias_get_id(np, "ethernet");
+ if (idx < 0)
+ idx = 0;
+
+ if (of_machine_is_compatible("fsl,imx8qm") ||
+ of_machine_is_compatible("fsl,imx8qxp"))
+ imx8qm_ipg_stop_enable(idx, enabled);
+}
diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
index 62bc19bedb06..636742cbfbba 100644
--- a/drivers/net/ethernet/freescale/fec_main.c
+++ b/drivers/net/ethernet/freescale/fec_main.c
@@ -18,13 +18,14 @@
* Bug fixes and cleanup by Philippe De Muyter (phdm@macqel.be)
* Copyright (c) 2004-2006 Macq Electronique SA.
*
- * Copyright (C) 2010-2011 Freescale Semiconductor, Inc.
+ * Copyright (C) 2010-2014 Freescale Semiconductor, Inc.
+ *
+ * Copyright 2017-2018 NXP
*/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/string.h>
-#include <linux/pm_runtime.h>
#include <linux/ptrace.h>
#include <linux/errno.h>
#include <linux/ioport.h>
@@ -47,6 +48,7 @@
#include <linux/io.h>
#include <linux/irq.h>
#include <linux/clk.h>
+#include <linux/clk/clk-conf.h>
#include <linux/platform_device.h>
#include <linux/mdio.h>
#include <linux/phy.h>
@@ -59,10 +61,14 @@
#include <linux/regulator/consumer.h>
#include <linux/if_vlan.h>
#include <linux/pinctrl/consumer.h>
+#include <linux/pm_runtime.h>
+#include <linux/busfreq-imx.h>
#include <linux/prefetch.h>
-#include <soc/imx/cpuidle.h>
+#include <linux/mfd/syscon.h>
+#include <linux/regmap.h>
#include <asm/cacheflush.h>
+#include <soc/imx/cpuidle.h>
#include "fec.h"
@@ -72,6 +78,7 @@ static void fec_enet_itr_coal_init(struct net_device *ndev);
#define DRIVER_NAME "fec"
#define FEC_ENET_GET_QUQUE(_x) ((_x == 0) ? 1 : ((_x == 1) ? 2 : 0))
+static const u16 fec_enet_vlan_pri_to_queue[8] = {1, 1, 1, 1, 2, 2, 2, 2};
/* Pause frame feild and FIFO threshold */
#define FEC_ENET_FCE (1 << 5)
@@ -104,7 +111,7 @@ static struct platform_device_id fec_devtype[] = {
.driver_data = FEC_QUIRK_ENET_MAC | FEC_QUIRK_HAS_GBIT |
FEC_QUIRK_HAS_BUFDESC_EX | FEC_QUIRK_HAS_CSUM |
FEC_QUIRK_HAS_VLAN | FEC_QUIRK_ERR006358 |
- FEC_QUIRK_HAS_RACC,
+ FEC_QUIRK_HAS_RACC | FEC_QUIRK_BUG_WAITMODE,
}, {
.name = "mvf600-fec",
.driver_data = FEC_QUIRK_ENET_MAC | FEC_QUIRK_HAS_RACC,
@@ -123,6 +130,22 @@ static struct platform_device_id fec_devtype[] = {
FEC_QUIRK_BUG_CAPTURE | FEC_QUIRK_HAS_RACC |
FEC_QUIRK_HAS_COALESCE,
}, {
+ .name = "imx8qm-fec",
+ .driver_data = FEC_QUIRK_ENET_MAC | FEC_QUIRK_HAS_GBIT |
+ FEC_QUIRK_HAS_BUFDESC_EX | FEC_QUIRK_HAS_CSUM |
+ FEC_QUIRK_HAS_VLAN | FEC_QUIRK_HAS_AVB |
+ FEC_QUIRK_ERR007885 | FEC_QUIRK_BUG_CAPTURE |
+ FEC_QUIRK_HAS_RACC | FEC_QUIRK_HAS_COALESCE |
+ FEC_QUIRK_DELAYED_CLKS_SUPPORT,
+ }, {
+ .name = "imx8mq-fec",
+ .driver_data = FEC_QUIRK_ENET_MAC | FEC_QUIRK_HAS_GBIT |
+ FEC_QUIRK_HAS_BUFDESC_EX | FEC_QUIRK_HAS_CSUM |
+ FEC_QUIRK_HAS_VLAN | FEC_QUIRK_HAS_AVB |
+ FEC_QUIRK_ERR007885 | FEC_QUIRK_BUG_CAPTURE |
+ FEC_QUIRK_HAS_RACC | FEC_QUIRK_HAS_COALESCE |
+ FEC_QUIRK_HAS_EEE,
+ }, {
/* sentinel */
}
};
@@ -136,6 +159,8 @@ enum imx_fec_type {
MVF600_FEC,
IMX6SX_FEC,
IMX6UL_FEC,
+ IMX8QM_FEC,
+ IMX8MQ_FEC,
};
static const struct of_device_id fec_dt_ids[] = {
@@ -146,6 +171,8 @@ static const struct of_device_id fec_dt_ids[] = {
{ .compatible = "fsl,mvf600-fec", .data = &fec_devtype[MVF600_FEC], },
{ .compatible = "fsl,imx6sx-fec", .data = &fec_devtype[IMX6SX_FEC], },
{ .compatible = "fsl,imx6ul-fec", .data = &fec_devtype[IMX6UL_FEC], },
+ { .compatible = "fsl,imx8qm-fec", .data = &fec_devtype[IMX8QM_FEC], },
+ { .compatible = "fsl,imx8mq-fec", .data = &fec_devtype[IMX8MQ_FEC], },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, fec_dt_ids);
@@ -197,7 +224,8 @@ MODULE_PARM_DESC(macaddr, "FEC Ethernet MAC address");
* account when setting it.
*/
#if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x) || \
- defined(CONFIG_M520x) || defined(CONFIG_M532x) || defined(CONFIG_ARM)
+ defined(CONFIG_M520x) || defined(CONFIG_M532x) || defined(CONFIG_ARM) || \
+ defined(CONFIG_ARM64)
#define OPT_FRAME_SIZE (PKT_MAXBUF_SIZE << 16)
#else
#define OPT_FRAME_SIZE 0
@@ -226,7 +254,15 @@ MODULE_PARM_DESC(macaddr, "FEC Ethernet MAC address");
#define FEC_WOL_FLAG_ENABLE (0x1 << 1)
#define FEC_WOL_FLAG_SLEEP_ON (0x1 << 2)
-#define COPYBREAK_DEFAULT 256
+/* By default, set the copybreak to 1518,
+ * then the RX path always keep DMA memory unchanged, and
+ * allocate one new skb and copy DMA memory data to the new skb
+ * buffer, which can improve the performance when SMMU is enabled.
+ *
+ * The driver support .set_tunable() interface for ethtool, user
+ * can dynamicly change the copybreak value.
+ */
+#define COPYBREAK_DEFAULT 1518
/* Max number of allowed TCP segments for software TSO */
#define FEC_MAX_TSO_SEGS 100
@@ -909,7 +945,7 @@ fec_restart(struct net_device *ndev)
u32 val;
u32 temp_mac[2];
u32 rcntl = OPT_FRAME_SIZE | 0x04;
- u32 ecntl = 0x2; /* ETHEREN */
+ u32 ecntl = FEC_ENET_ETHEREN; /* ETHEREN */
/* Whack a reset. We should wait for this.
* For i.MX6SX SOC, enet use AXI bus, we use disable MAC
@@ -968,6 +1004,7 @@ fec_restart(struct net_device *ndev)
writel(val, fep->hwp + FEC_RACC);
writel(PKT_MAXBUF_SIZE, fep->hwp + FEC_FTRL);
}
+ writel(PKT_MAXBUF_SIZE, fep->hwp + FEC_FTRL);
#endif
/*
@@ -1063,6 +1100,13 @@ fec_restart(struct net_device *ndev)
if (fep->bufdesc_ex)
ecntl |= (1 << 4);
+ if (fep->quirks & FEC_QUIRK_DELAYED_CLKS_SUPPORT &&
+ fep->rgmii_txc_dly)
+ ecntl |= FEC_ENET_TXC_DLY;
+ if (fep->quirks & FEC_QUIRK_DELAYED_CLKS_SUPPORT &&
+ fep->rgmii_rxc_dly)
+ ecntl |= FEC_ENET_RXC_DLY;
+
#ifndef CONFIG_M5272
/* Enable the MIB statistic event counters */
writel(0 << 31, fep->hwp + FEC_MIB_CTRLSTAT);
@@ -1086,11 +1130,40 @@ fec_restart(struct net_device *ndev)
}
+static int fec_enet_stop_mode(struct fec_enet_private *fep, bool enabled)
+{
+ struct fec_platform_data *pdata = fep->pdev->dev.platform_data;
+ struct device_node *np = fep->pdev->dev.of_node;
+
+ if (fep->gpr.gpr) {
+ if (enabled)
+ regmap_update_bits(fep->gpr.gpr, fep->gpr.req_gpr,
+ 1 << fep->gpr.req_bit,
+ 1 << fep->gpr.req_bit);
+ else
+ regmap_update_bits(fep->gpr.gpr, fep->gpr.req_gpr,
+ 1 << fep->gpr.req_bit,
+ 0);
+ } else if (pdata && pdata->sleep_mode_enable) {
+ pdata->sleep_mode_enable(enabled);
+ } else {
+ fec_enet_ipg_stop_misc_set(np, enabled);
+ }
+
+ return 0;
+}
+
+static inline void fec_irqs_disable(struct net_device *ndev)
+{
+ struct fec_enet_private *fep = netdev_priv(ndev);
+
+ writel(0, fep->hwp + FEC_IMASK);
+}
+
static void
fec_stop(struct net_device *ndev)
{
struct fec_enet_private *fep = netdev_priv(ndev);
- struct fec_platform_data *pdata = fep->pdev->dev.platform_data;
u32 rmii_mode = readl(fep->hwp + FEC_R_CNTRL) & (1 << 8);
u32 val;
@@ -1113,15 +1186,14 @@ fec_stop(struct net_device *ndev)
writel(1, fep->hwp + FEC_ECNTRL);
udelay(10);
}
- writel(FEC_DEFAULT_IMASK, fep->hwp + FEC_IMASK);
+ writel(FEC_ENET_MII, fep->hwp + FEC_IMASK);
} else {
- writel(FEC_DEFAULT_IMASK | FEC_ENET_WAKEUP, fep->hwp + FEC_IMASK);
+ writel(FEC_ENET_MII | FEC_ENET_WAKEUP, fep->hwp + FEC_IMASK);
val = readl(fep->hwp + FEC_ECNTRL);
val |= (FEC_ECR_MAGICEN | FEC_ECR_SLEEP);
writel(val, fep->hwp + FEC_ECNTRL);
- if (pdata && pdata->sleep_mode_enable)
- pdata->sleep_mode_enable(true);
+ fec_enet_stop_mode(fep, true);
}
writel(fep->phy_speed, fep->hwp + FEC_MII_SPEED);
@@ -1639,7 +1711,7 @@ static void fec_get_mac(struct net_device *ndev)
{
struct fec_enet_private *fep = netdev_priv(ndev);
struct fec_platform_data *pdata = dev_get_platdata(&fep->pdev->dev);
- unsigned char *iap, tmpaddr[ETH_ALEN];
+ unsigned char *iap, tmpaddr[ETH_ALEN] = {0};
/*
* try to get mac address in following order:
@@ -1669,8 +1741,14 @@ static void fec_get_mac(struct net_device *ndev)
if (FEC_FLASHMAC)
iap = (unsigned char *)FEC_FLASHMAC;
#else
- if (pdata)
+ if (pdata) {
iap = (unsigned char *)&pdata->mac;
+ } else {
+ struct device_node *np = fep->pdev->dev.of_node;
+
+ fec_enet_get_mac_from_fuse(np, tmpaddr);
+ iap = &tmpaddr[0];
+ }
#endif
}
@@ -1774,6 +1852,7 @@ static int fec_enet_mdio_read(struct mii_bus *bus, int mii_id, int regnum)
struct fec_enet_private *fep = bus->priv;
struct device *dev = &fep->pdev->dev;
unsigned long time_left;
+ uint int_events;
int ret = 0;
ret = pm_runtime_get_sync(dev);
@@ -1793,9 +1872,12 @@ static int fec_enet_mdio_read(struct mii_bus *bus, int mii_id, int regnum)
usecs_to_jiffies(FEC_MII_TIMEOUT));
if (time_left == 0) {
fep->mii_timeout = 1;
- netdev_err(fep->netdev, "MDIO read timeout\n");
- ret = -ETIMEDOUT;
- goto out;
+ int_events = readl(fep->hwp + FEC_IEVENT);
+ if (!(int_events & FEC_ENET_MII)) {
+ netdev_err(fep->netdev, "MDIO read timeout\n");
+ ret = -ETIMEDOUT;
+ goto out;
+ }
}
ret = FEC_MMFR_DATA(readl(fep->hwp + FEC_MII_DATA));
@@ -1854,7 +1936,6 @@ static int fec_enet_clk_enable(struct net_device *ndev, bool enable)
ret = clk_prepare_enable(fep->clk_enet_out);
if (ret)
return ret;
-
if (fep->clk_ptp) {
mutex_lock(&fep->ptp_clk_mutex);
ret = clk_prepare_enable(fep->clk_ptp);
@@ -1870,6 +1951,10 @@ static int fec_enet_clk_enable(struct net_device *ndev, bool enable)
ret = clk_prepare_enable(fep->clk_ref);
if (ret)
goto failed_clk_ref;
+
+ ret = clk_prepare_enable(fep->clk_2x_txclk);
+ if (ret)
+ goto failed_clk_2x_txclk;
} else {
clk_disable_unprepare(fep->clk_enet_out);
if (fep->clk_ptp) {
@@ -1879,13 +1964,17 @@ static int fec_enet_clk_enable(struct net_device *ndev, bool enable)
mutex_unlock(&fep->ptp_clk_mutex);
}
clk_disable_unprepare(fep->clk_ref);
+ clk_disable_unprepare(fep->clk_2x_txclk);
}
return 0;
-failed_clk_ref:
+failed_clk_2x_txclk:
if (fep->clk_ref)
clk_disable_unprepare(fep->clk_ref);
+failed_clk_ref:
+ if (fep->clk_ptp)
+ clk_disable_unprepare(fep->clk_ptp);
failed_clk_ptp:
if (fep->clk_enet_out)
clk_disable_unprepare(fep->clk_enet_out);
@@ -1893,6 +1982,25 @@ failed_clk_ptp:
return ret;
}
+static int fec_restore_mii_bus(struct net_device *ndev)
+{
+ struct fec_enet_private *fep = netdev_priv(ndev);
+ int ret;
+
+ ret = pm_runtime_get_sync(&fep->pdev->dev);
+ if (ret < 0)
+ return ret;
+
+ writel(0xffc00000, fep->hwp + FEC_IEVENT);
+ writel(fep->phy_speed, fep->hwp + FEC_MII_SPEED);
+ writel(FEC_ENET_MII, fep->hwp + FEC_IMASK);
+ writel(FEC_ENET_ETHEREN, fep->hwp + FEC_ECNTRL);
+
+ pm_runtime_mark_last_busy(&fep->pdev->dev);
+ pm_runtime_put_autosuspend(&fep->pdev->dev);
+ return 0;
+}
+
static int fec_enet_mii_probe(struct net_device *ndev)
{
struct fec_enet_private *fep = netdev_priv(ndev);
@@ -1962,6 +2070,7 @@ static int fec_enet_mii_probe(struct net_device *ndev)
static int fec_enet_mii_init(struct platform_device *pdev)
{
static struct mii_bus *fec0_mii_bus;
+ static int *fec_mii_bus_share;
struct net_device *ndev = platform_get_drvdata(pdev);
struct fec_enet_private *fep = netdev_priv(ndev);
struct device_node *node;
@@ -1988,6 +2097,7 @@ static int fec_enet_mii_init(struct platform_device *pdev)
/* fec1 uses fec0 mii_bus */
if (mii_cnt && fec0_mii_bus) {
fep->mii_bus = fec0_mii_bus;
+ *fec_mii_bus_share = FEC0_MII_BUS_SHARE_TRUE;
mii_cnt++;
return 0;
}
@@ -2051,6 +2161,8 @@ static int fec_enet_mii_init(struct platform_device *pdev)
if (node) {
err = of_mdiobus_register(fep->mii_bus, node);
of_node_put(node);
+ } else if (fep->phy_node && !fep->fixed_link) {
+ err = -EPROBE_DEFER;
} else {
err = mdiobus_register(fep->mii_bus);
}
@@ -2061,8 +2173,10 @@ static int fec_enet_mii_init(struct platform_device *pdev)
mii_cnt++;
/* save fec0 mii_bus */
- if (fep->quirks & FEC_QUIRK_SINGLE_MDIO)
+ if (fep->quirks & FEC_QUIRK_SINGLE_MDIO) {
fec0_mii_bus = fep->mii_bus;
+ fec_mii_bus_share = &fep->mii_bus_share;
+ }
return 0;
@@ -2106,7 +2220,8 @@ static int fec_enet_get_regs_len(struct net_device *ndev)
/* List of registers that can be safety be read to dump them with ethtool */
#if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x) || \
- defined(CONFIG_M520x) || defined(CONFIG_M532x) || defined(CONFIG_ARM)
+ defined(CONFIG_M520x) || defined(CONFIG_M532x) || defined(CONFIG_ARM) || \
+ defined(CONFIG_ARM64)
static u32 fec_enet_register_offset[] = {
FEC_IEVENT, FEC_IMASK, FEC_R_DES_ACTIVE_0, FEC_X_DES_ACTIVE_0,
FEC_ECNTRL, FEC_MII_DATA, FEC_MII_SPEED, FEC_MIB_CTRLSTAT, FEC_R_CNTRL,
@@ -2552,6 +2667,92 @@ static int fec_enet_set_tunable(struct net_device *netdev,
return ret;
}
+/* LPI Sleep Ts count base on tx clk (clk_ref).
+ * The lpi sleep cnt value = X us / (cycle_ns)
+ */
+static int fec_enet_us_to_tx_cycle(struct net_device *ndev, int us)
+{
+ struct fec_enet_private *fep = netdev_priv(ndev);
+
+ return us * (fep->clk_ref_rate / 1000) / 1000;
+}
+
+static int fec_enet_eee_mode_set(struct net_device *ndev, bool enable)
+{
+ struct fec_enet_private *fep = netdev_priv(ndev);
+ struct ethtool_eee *p = &fep->eee;
+ unsigned int sleep_cycle, wake_cycle;
+ int ret = 0;
+
+ if (enable) {
+ ret = phy_init_eee(ndev->phydev, 0);
+ if (ret)
+ return ret;
+
+ sleep_cycle = fec_enet_us_to_tx_cycle(ndev, p->tx_lpi_timer);
+ wake_cycle = sleep_cycle;
+ } else {
+ sleep_cycle = 0;
+ wake_cycle = 0;
+ }
+
+ p->tx_lpi_enabled = enable;
+ p->eee_enabled = enable;
+ p->eee_active = enable;
+
+ writel(sleep_cycle, fep->hwp + FEC_LPI_SLEEP);
+ writel(wake_cycle, fep->hwp + FEC_LPI_WAKE);
+
+ return 0;
+}
+
+static int
+fec_enet_get_eee(struct net_device *ndev, struct ethtool_eee *edata)
+{
+ struct fec_enet_private *fep = netdev_priv(ndev);
+ struct ethtool_eee *p = &fep->eee;
+
+ if (!(fep->quirks & FEC_QUIRK_HAS_EEE))
+ return -EOPNOTSUPP;
+
+ if (!netif_running(ndev))
+ return -ENETDOWN;
+
+ edata->eee_enabled = p->eee_enabled;
+ edata->eee_active = p->eee_active;
+ edata->tx_lpi_timer = p->tx_lpi_timer;
+ edata->tx_lpi_enabled = p->tx_lpi_enabled;
+
+ return phy_ethtool_get_eee(ndev->phydev, edata);
+}
+
+static int
+fec_enet_set_eee(struct net_device *ndev, struct ethtool_eee *edata)
+{
+ struct fec_enet_private *fep = netdev_priv(ndev);
+ struct ethtool_eee *p = &fep->eee;
+ int ret = 0;
+
+ if (!(fep->quirks & FEC_QUIRK_HAS_EEE))
+ return -EOPNOTSUPP;
+
+ if (!netif_running(ndev))
+ return -ENETDOWN;
+
+ p->tx_lpi_timer = edata->tx_lpi_timer;
+
+ if (!edata->eee_enabled || !edata->tx_lpi_enabled ||
+ !edata->tx_lpi_timer)
+ ret = fec_enet_eee_mode_set(ndev, false);
+ else
+ ret = fec_enet_eee_mode_set(ndev, true);
+
+ if (ret)
+ return ret;
+
+ return phy_ethtool_set_eee(ndev->phydev, edata);
+}
+
static void
fec_enet_get_wol(struct net_device *ndev, struct ethtool_wolinfo *wol)
{
@@ -2577,15 +2778,10 @@ fec_enet_set_wol(struct net_device *ndev, struct ethtool_wolinfo *wol)
return -EINVAL;
device_set_wakeup_enable(&ndev->dev, wol->wolopts & WAKE_MAGIC);
- if (device_may_wakeup(&ndev->dev)) {
+ if (device_may_wakeup(&ndev->dev))
fep->wol_flag |= FEC_WOL_FLAG_ENABLE;
- if (fep->irq[0] > 0)
- enable_irq_wake(fep->irq[0]);
- } else {
+ else
fep->wol_flag &= (~FEC_WOL_FLAG_ENABLE);
- if (fep->irq[0] > 0)
- disable_irq_wake(fep->irq[0]);
- }
return 0;
}
@@ -2610,6 +2806,8 @@ static const struct ethtool_ops fec_enet_ethtool_ops = {
.set_tunable = fec_enet_set_tunable,
.get_wol = fec_enet_get_wol,
.set_wol = fec_enet_set_wol,
+ .get_eee = fec_enet_get_eee,
+ .set_eee = fec_enet_set_eee,
.get_link_ksettings = phy_ethtool_get_link_ksettings,
.set_link_ksettings = phy_ethtool_set_link_ksettings,
};
@@ -2840,10 +3038,29 @@ static int fec_enet_alloc_buffers(struct net_device *ndev)
return 0;
}
+static inline bool fec_enet_irq_workaround(struct fec_enet_private *fep)
+{
+ struct device_node *np = fep->pdev->dev.of_node;
+ struct device_node *intr_node;
+
+ intr_node = of_parse_phandle(np, "interrupts-extended", 0);
+ if (intr_node && !strcmp(intr_node->name, "gpio")) {
+ /*
+ * If the interrupt controller is a GPIO node, it must have
+ * applied the workaround for WAIT mode bug.
+ */
+ return true;
+ }
+
+ return false;
+}
+
static int
fec_enet_open(struct net_device *ndev)
{
struct fec_enet_private *fep = netdev_priv(ndev);
+ const struct platform_device_id *id_entry =
+ platform_get_device_id(fep->pdev);
int ret;
ret = pm_runtime_get_sync(&fep->pdev->dev);
@@ -2878,6 +3095,16 @@ fec_enet_open(struct net_device *ndev)
phy_start(ndev->phydev);
netif_tx_start_all_queues(ndev);
+ if ((id_entry->driver_data & FEC_QUIRK_BUG_WAITMODE) &&
+ !fec_enet_irq_workaround(fep))
+ pm_qos_add_request(&fep->pm_qos_req,
+ PM_QOS_CPU_DMA_LATENCY,
+ 0);
+ else
+ pm_qos_add_request(&fep->pm_qos_req,
+ PM_QOS_CPU_DMA_LATENCY,
+ PM_QOS_DEFAULT_VALUE);
+
device_set_wakeup_enable(&ndev->dev, fep->wol_flag &
FEC_WOL_FLAG_ENABLE);
@@ -2890,7 +3117,8 @@ err_enet_alloc:
clk_enable:
pm_runtime_mark_last_busy(&fep->pdev->dev);
pm_runtime_put_autosuspend(&fep->pdev->dev);
- pinctrl_pm_select_sleep_state(&fep->pdev->dev);
+ if (!fep->mii_bus_share)
+ pinctrl_pm_select_sleep_state(&fep->pdev->dev);
return ret;
}
@@ -2908,6 +3136,7 @@ fec_enet_close(struct net_device *ndev)
}
phy_disconnect(ndev->phydev);
+ ndev->phydev = NULL;
if (fep->quirks & FEC_QUIRK_ERR006687)
imx6q_cpuidle_fec_irqs_unused();
@@ -2915,7 +3144,9 @@ fec_enet_close(struct net_device *ndev)
fec_enet_update_ethtool_stats(ndev);
fec_enet_clk_enable(ndev, false);
- pinctrl_pm_select_sleep_state(&fep->pdev->dev);
+ pm_qos_remove_request(&fep->pm_qos_req);
+ if (!fep->mii_bus_share)
+ pinctrl_pm_select_sleep_state(&fep->pdev->dev);
pm_runtime_mark_last_busy(&fep->pdev->dev);
pm_runtime_put_autosuspend(&fep->pdev->dev);
@@ -3085,10 +3316,42 @@ static int fec_set_features(struct net_device *netdev,
return 0;
}
+u16 fec_enet_get_raw_vlan_tci(struct sk_buff *skb)
+{
+ struct vlan_ethhdr *vhdr;
+ unsigned short vlan_TCI = 0;
+
+ if (skb->protocol == ntohs(ETH_P_ALL)) {
+ vhdr = (struct vlan_ethhdr *)(skb->data);
+ vlan_TCI = ntohs(vhdr->h_vlan_TCI);
+ }
+
+ return vlan_TCI;
+}
+
+u16 fec_enet_select_queue(struct net_device *ndev, struct sk_buff *skb,
+ void *accel_priv, select_queue_fallback_t fallback)
+{
+ struct fec_enet_private *fep = netdev_priv(ndev);
+ const struct platform_device_id *id_entry =
+ platform_get_device_id(fep->pdev);
+ u16 vlan_tag;
+
+ if (!(id_entry->driver_data & FEC_QUIRK_HAS_AVB))
+ return skb_tx_hash(ndev, skb);
+
+ vlan_tag = fec_enet_get_raw_vlan_tci(skb);
+ if (!vlan_tag)
+ return vlan_tag;
+
+ return fec_enet_vlan_pri_to_queue[vlan_tag >> 13];
+}
+
static const struct net_device_ops fec_netdev_ops = {
.ndo_open = fec_enet_open,
.ndo_stop = fec_enet_close,
.ndo_start_xmit = fec_enet_start_xmit,
+ .ndo_select_queue = fec_enet_select_queue,
.ndo_set_rx_mode = set_multicast_list,
.ndo_validate_addr = eth_validate_addr,
.ndo_tx_timeout = fec_timeout,
@@ -3124,7 +3387,7 @@ static int fec_enet_init(struct net_device *ndev)
unsigned dsize_log2 = __fls(dsize);
WARN_ON(dsize != (1 << dsize_log2));
-#if defined(CONFIG_ARM)
+#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
fep->rx_align = 0xf;
fep->tx_align = 0xf;
#else
@@ -3319,6 +3582,41 @@ fec_enet_get_queue_num(struct platform_device *pdev, int *num_tx, int *num_rx)
}
+static void fec_enet_of_parse_stop_mode(struct platform_device *pdev)
+{
+ struct net_device *dev = platform_get_drvdata(pdev);
+ struct device_node *np = pdev->dev.of_node;
+ struct fec_enet_private *fep = netdev_priv(dev);
+ struct device_node *node;
+ phandle phandle;
+ u32 out_val[3];
+ int ret;
+
+ ret = of_property_read_u32_array(np, "stop-mode", out_val, 3);
+ if (ret) {
+ dev_dbg(&pdev->dev, "no stop-mode property\n");
+ return;
+ }
+
+ phandle = *out_val;
+ node = of_find_node_by_phandle(phandle);
+ if (!node) {
+ dev_dbg(&pdev->dev, "could not find gpr node by phandle\n");
+ return;
+ }
+
+ fep->gpr.gpr = syscon_node_to_regmap(node);
+ if (IS_ERR(fep->gpr.gpr)) {
+ dev_dbg(&pdev->dev, "could not find gpr regmap\n");
+ return;
+ }
+
+ of_node_put(node);
+
+ fep->gpr.req_gpr = out_val[1];
+ fep->gpr.req_bit = out_val[2];
+}
+
static int
fec_probe(struct platform_device *pdev)
{
@@ -3381,9 +3679,17 @@ fec_probe(struct platform_device *pdev)
!of_property_read_bool(np, "fsl,err006687-workaround-present"))
fep->quirks |= FEC_QUIRK_ERR006687;
+ fec_enet_of_parse_stop_mode(pdev);
+
if (of_get_property(np, "fsl,magic-packet", NULL))
fep->wol_flag |= FEC_WOL_HAS_MAGIC_PACKET;
+ if (of_get_property(np, "fsl,rgmii_txc_dly", NULL))
+ fep->rgmii_txc_dly = true;
+
+ if (of_get_property(np, "fsl,rgmii_rxc_dly", NULL))
+ fep->rgmii_rxc_dly = true;
+
phy_node = of_parse_phandle(np, "phy-handle", 0);
if (!phy_node && of_phy_is_fixed_link(np)) {
ret = of_phy_register_fixed_link(np);
@@ -3393,6 +3699,7 @@ fec_probe(struct platform_device *pdev)
goto failed_phy;
}
phy_node = of_node_get(np);
+ fep->fixed_link = true;
}
fep->phy_node = phy_node;
@@ -3407,6 +3714,8 @@ fec_probe(struct platform_device *pdev)
fep->phy_interface = ret;
}
+ request_bus_freq(BUS_FREQ_HIGH);
+
fep->clk_ipg = devm_clk_get(&pdev->dev, "ipg");
if (IS_ERR(fep->clk_ipg)) {
ret = PTR_ERR(fep->clk_ipg);
@@ -3418,7 +3727,6 @@ fec_probe(struct platform_device *pdev)
ret = PTR_ERR(fep->clk_ahb);
goto failed_clk;
}
-
fep->itr_clk_rate = clk_get_rate(fep->clk_ahb);
/* enet_out is optional, depends on board */
@@ -3433,6 +3741,12 @@ fec_probe(struct platform_device *pdev)
fep->clk_ref = devm_clk_get(&pdev->dev, "enet_clk_ref");
if (IS_ERR(fep->clk_ref))
fep->clk_ref = NULL;
+ fep->clk_ref_rate = clk_get_rate(fep->clk_ref);
+
+ /* clk_2x_txclk is optional, depends on board */
+ fep->clk_2x_txclk = devm_clk_get(&pdev->dev, "enet_2x_txclk");
+ if (IS_ERR(fep->clk_2x_txclk))
+ fep->clk_2x_txclk = NULL;
fep->bufdesc_ex = fep->quirks & FEC_QUIRK_HAS_BUFDESC_EX;
fep->clk_ptp = devm_clk_get(&pdev->dev, "ptp");
@@ -3458,7 +3772,6 @@ fec_probe(struct platform_device *pdev)
if (ret) {
dev_err(&pdev->dev,
"Failed to enable phy regulator: %d\n", ret);
- clk_disable_unprepare(fep->clk_ipg);
goto failed_regulator;
}
} else {
@@ -3502,7 +3815,17 @@ fec_probe(struct platform_device *pdev)
fep->irq[i] = irq;
}
+ ret = of_property_read_u32(np, "fsl,wakeup_irq", &irq);
+ if (!ret && irq < FEC_IRQ_NUM)
+ fep->wake_irq = fep->irq[irq];
+ else
+ fep->wake_irq = fep->irq[0];
+
init_completion(&fep->mdio_done);
+
+ /* board only enable one mii bus in default */
+ if (!of_get_property(np, "fsl,mii-exclusive", NULL))
+ fep->quirks |= FEC_QUIRK_SINGLE_MDIO;
ret = fec_enet_mii_init(pdev);
if (ret)
goto failed_mii_init;
@@ -3516,6 +3839,11 @@ fec_probe(struct platform_device *pdev)
if (ret)
goto failed_register;
+ if (!fep->fixed_link) {
+ fep->fixups = of_fec_enet_parse_fixup(np);
+ fec_enet_register_fixup(ndev);
+ }
+
device_init_wakeup(&ndev->dev, fep->wol_flag &
FEC_WOL_HAS_MAGIC_PACKET);
@@ -3539,7 +3867,6 @@ failed_init:
if (fep->reg_phy)
regulator_disable(fep->reg_phy);
failed_reset:
- pm_runtime_put_noidle(&pdev->dev);
pm_runtime_disable(&pdev->dev);
failed_regulator:
clk_disable_unprepare(fep->clk_ahb);
@@ -3595,6 +3922,7 @@ static int __maybe_unused fec_suspend(struct device *dev)
{
struct net_device *ndev = dev_get_drvdata(dev);
struct fec_enet_private *fep = netdev_priv(ndev);
+ int ret = 0;
rtnl_lock();
if (netif_running(ndev)) {
@@ -3606,9 +3934,21 @@ static int __maybe_unused fec_suspend(struct device *dev)
netif_device_detach(ndev);
netif_tx_unlock_bh(ndev);
fec_stop(ndev);
- fec_enet_clk_enable(ndev, false);
- if (!(fep->wol_flag & FEC_WOL_FLAG_ENABLE))
+ if (!(fep->wol_flag & FEC_WOL_FLAG_ENABLE)) {
+ fec_irqs_disable(ndev);
pinctrl_pm_select_sleep_state(&fep->pdev->dev);
+ } else {
+ disable_irq(fep->wake_irq);
+ enable_irq_wake(fep->wake_irq);
+ }
+ fec_enet_clk_enable(ndev, false);
+ fep->active_in_suspend = !pm_runtime_status_suspended(dev);
+ if (fep->active_in_suspend)
+ ret = pm_runtime_force_suspend(dev);
+ if (ret < 0)
+ return ret;
+ } else if (fep->mii_bus_share && !ndev->phydev) {
+ pinctrl_pm_select_sleep_state(&fep->pdev->dev);
}
rtnl_unlock();
@@ -3628,8 +3968,7 @@ static int __maybe_unused fec_resume(struct device *dev)
{
struct net_device *ndev = dev_get_drvdata(dev);
struct fec_enet_private *fep = netdev_priv(ndev);
- struct fec_platform_data *pdata = fep->pdev->dev.platform_data;
- int ret;
+ int ret = 0;
int val;
if (fep->reg_phy && !(fep->wol_flag & FEC_WOL_FLAG_ENABLE)) {
@@ -3640,14 +3979,18 @@ static int __maybe_unused fec_resume(struct device *dev)
rtnl_lock();
if (netif_running(ndev)) {
+ if (fep->active_in_suspend)
+ pm_runtime_force_resume(dev);
ret = fec_enet_clk_enable(ndev, true);
if (ret) {
rtnl_unlock();
goto failed_clk;
}
+
if (fep->wol_flag & FEC_WOL_FLAG_ENABLE) {
- if (pdata && pdata->sleep_mode_enable)
- pdata->sleep_mode_enable(false);
+ disable_irq_wake(fep->wake_irq);
+ fec_enet_stop_mode(fep, false);
+ enable_irq(fep->wake_irq);
val = readl(fep->hwp + FEC_ECNTRL);
val &= ~(FEC_ECR_MAGICEN | FEC_ECR_SLEEP);
writel(val, fep->hwp + FEC_ECNTRL);
@@ -3661,10 +4004,14 @@ static int __maybe_unused fec_resume(struct device *dev)
netif_tx_unlock_bh(ndev);
napi_enable(&fep->napi);
phy_start(ndev->phydev);
+ } else if (fep->mii_bus_share && !ndev->phydev) {
+ pinctrl_pm_select_default_state(&fep->pdev->dev);
+ /* And then recovery mii bus */
+ ret = fec_restore_mii_bus(ndev);
}
rtnl_unlock();
- return 0;
+ return ret;
failed_clk:
if (fep->reg_phy)
@@ -3679,6 +4026,7 @@ static int __maybe_unused fec_runtime_suspend(struct device *dev)
clk_disable_unprepare(fep->clk_ahb);
clk_disable_unprepare(fep->clk_ipg);
+ release_bus_freq(BUS_FREQ_HIGH);
return 0;
}
@@ -3689,6 +4037,7 @@ static int __maybe_unused fec_runtime_resume(struct device *dev)
struct fec_enet_private *fep = netdev_priv(ndev);
int ret;
+ request_bus_freq(BUS_FREQ_HIGH);
ret = clk_prepare_enable(fep->clk_ahb);
if (ret)
return ret;
diff --git a/drivers/net/ethernet/freescale/fec_ptp.c b/drivers/net/ethernet/freescale/fec_ptp.c
index 6ebad3fac81d..07a471144bfe 100644
--- a/drivers/net/ethernet/freescale/fec_ptp.c
+++ b/drivers/net/ethernet/freescale/fec_ptp.c
@@ -579,6 +579,10 @@ void fec_ptp_init(struct platform_device *pdev)
fep->ptp_caps.enable = fec_ptp_enable;
fep->cycle_speed = clk_get_rate(fep->clk_ptp);
+ if (!fep->cycle_speed) {
+ fep->cycle_speed = NSEC_PER_SEC;
+ dev_err(&fep->pdev->dev, "clk_ptp clock rate is zero\n");
+ }
fep->ptp_inc = NSEC_PER_SEC / fep->cycle_speed;
spin_lock_init(&fep->tmreg_lock);
diff --git a/drivers/net/ivshmem-net.c b/drivers/net/ivshmem-net.c
new file mode 100644
index 000000000000..aba77c232c48
--- /dev/null
+++ b/drivers/net/ivshmem-net.c
@@ -0,0 +1,984 @@
+/*
+ * Copyright 2016 Mans Rullgard <mans@mansr.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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/io.h>
+#include <linux/bitops.h>
+#include <linux/interrupt.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/rtnetlink.h>
+#include <linux/virtio_ring.h>
+
+#define DRV_NAME "ivshmem-net"
+
+#define JAILHOUSE_CFG_SHMEM_PTR 0x40
+#define JAILHOUSE_CFG_SHMEM_SZ 0x48
+
+#define IVSHMEM_INTX_ENABLE 0x1
+
+#define IVSHM_NET_STATE_RESET 0
+#define IVSHM_NET_STATE_INIT 1
+#define IVSHM_NET_STATE_READY 2
+#define IVSHM_NET_STATE_RUN 3
+
+#define IVSHM_NET_FLAG_RUN 0
+
+#define IVSHM_NET_MTU_MIN 256
+#define IVSHM_NET_MTU_MAX 65535
+#define IVSHM_NET_MTU_DEF 16384
+
+#define IVSHM_NET_FRAME_SIZE(s) ALIGN(18 + (s), SMP_CACHE_BYTES)
+
+#define IVSHM_NET_VQ_ALIGN 64
+
+struct ivshmem_regs {
+ u32 intxctrl;
+ u32 istat;
+ u32 ivpos;
+ u32 doorbell;
+ u32 lstate;
+ u32 rstate;
+};
+
+struct ivshm_net_queue {
+ struct vring vr;
+ u32 free_head;
+ u32 num_free;
+ u32 num_added;
+ u16 last_avail_idx;
+ u16 last_used_idx;
+
+ void *data;
+ void *end;
+ u32 size;
+ u32 head;
+ u32 tail;
+};
+
+struct ivshm_net_stats {
+ u32 interrupts;
+ u32 tx_packets;
+ u32 tx_notify;
+ u32 tx_pause;
+ u32 rx_packets;
+ u32 rx_notify;
+ u32 napi_poll;
+ u32 napi_complete;
+ u32 napi_poll_n[10];
+};
+
+struct ivshm_net {
+ struct ivshm_net_queue rx;
+ struct ivshm_net_queue tx;
+
+ u32 vrsize;
+ u32 qlen;
+ u32 qsize;
+
+ spinlock_t tx_free_lock;
+ spinlock_t tx_clean_lock;
+
+ struct napi_struct napi;
+
+ u32 lstate;
+ u32 rstate;
+
+ unsigned long flags;
+
+ struct workqueue_struct *state_wq;
+ struct work_struct state_work;
+
+ struct ivshm_net_stats stats;
+
+ struct ivshmem_regs __iomem *ivshm_regs;
+ void *shm;
+ phys_addr_t shmaddr;
+ resource_size_t shmlen;
+ u32 peer_id;
+
+ struct pci_dev *pdev;
+};
+
+static void *ivshm_net_desc_data(struct ivshm_net *in,
+ struct ivshm_net_queue *q,
+ struct vring_desc *desc,
+ u32 *len)
+{
+ u64 offs = READ_ONCE(desc->addr);
+ u32 dlen = READ_ONCE(desc->len);
+ u16 flags = READ_ONCE(desc->flags);
+ void *data;
+
+ if (flags)
+ return NULL;
+
+ if (offs >= in->shmlen)
+ return NULL;
+
+ data = in->shm + offs;
+
+ if (data < q->data || data >= q->end)
+ return NULL;
+
+ if (dlen > q->end - data)
+ return NULL;
+
+ *len = dlen;
+
+ return data;
+}
+
+static void ivshm_net_init_queue(struct ivshm_net *in,
+ struct ivshm_net_queue *q,
+ void *mem, unsigned int len)
+{
+ memset(q, 0, sizeof(*q));
+
+ vring_init(&q->vr, len, mem, IVSHM_NET_VQ_ALIGN);
+ q->data = mem + in->vrsize;
+ q->end = q->data + in->qsize;
+ q->size = in->qsize;
+}
+
+static void ivshm_net_init_queues(struct net_device *ndev)
+{
+ struct ivshm_net *in = netdev_priv(ndev);
+ int ivpos = readl(&in->ivshm_regs->ivpos);
+ void *tx;
+ void *rx;
+ int i;
+
+ tx = in->shm + ivpos * in->shmlen / 2;
+ rx = in->shm + !ivpos * in->shmlen / 2;
+
+ memset(tx, 0, in->shmlen / 2);
+
+ ivshm_net_init_queue(in, &in->rx, rx, in->qlen);
+ ivshm_net_init_queue(in, &in->tx, tx, in->qlen);
+
+ swap(in->rx.vr.used, in->tx.vr.used);
+
+ in->tx.num_free = in->tx.vr.num;
+
+ for (i = 0; i < in->tx.vr.num - 1; i++)
+ in->tx.vr.desc[i].next = i + 1;
+}
+
+static int ivshm_net_calc_qsize(struct net_device *ndev)
+{
+ struct ivshm_net *in = netdev_priv(ndev);
+ unsigned int vrsize;
+ unsigned int qsize;
+ unsigned int qlen;
+
+ for (qlen = 4096; qlen > 32; qlen >>= 1) {
+ vrsize = vring_size(qlen, IVSHM_NET_VQ_ALIGN);
+ vrsize = ALIGN(vrsize, IVSHM_NET_VQ_ALIGN);
+ if (vrsize < in->shmlen / 16)
+ break;
+ }
+
+ if (vrsize > in->shmlen / 2)
+ return -EINVAL;
+
+ qsize = in->shmlen / 2 - vrsize;
+
+ if (qsize < 4 * IVSHM_NET_MTU_MIN)
+ return -EINVAL;
+
+ in->vrsize = vrsize;
+ in->qlen = qlen;
+ in->qsize = qsize;
+
+ return 0;
+}
+
+static void ivshm_net_notify_tx(struct ivshm_net *in, unsigned int num)
+{
+ u16 evt, old, new;
+
+ virt_mb();
+
+ evt = READ_ONCE(vring_avail_event(&in->tx.vr));
+ old = in->tx.last_avail_idx - num;
+ new = in->tx.last_avail_idx;
+
+ if (vring_need_event(evt, new, old)) {
+ writel(in->peer_id << 16, &in->ivshm_regs->doorbell);
+ in->stats.tx_notify++;
+ }
+}
+
+static void ivshm_net_enable_rx_irq(struct ivshm_net *in)
+{
+ vring_avail_event(&in->rx.vr) = in->rx.last_avail_idx;
+ virt_wmb();
+}
+
+static void ivshm_net_notify_rx(struct ivshm_net *in, unsigned int num)
+{
+ u16 evt, old, new;
+
+ virt_mb();
+
+ evt = vring_used_event(&in->rx.vr);
+ old = in->rx.last_used_idx - num;
+ new = in->rx.last_used_idx;
+
+ if (vring_need_event(evt, new, old)) {
+ writel(in->peer_id << 16, &in->ivshm_regs->doorbell);
+ in->stats.rx_notify++;
+ }
+}
+
+static void ivshm_net_enable_tx_irq(struct ivshm_net *in)
+{
+ vring_used_event(&in->tx.vr) = in->tx.last_used_idx;
+ virt_wmb();
+}
+
+static bool ivshm_net_rx_avail(struct ivshm_net *in)
+{
+ virt_mb();
+ return READ_ONCE(in->rx.vr.avail->idx) != in->rx.last_avail_idx;
+}
+
+static size_t ivshm_net_tx_space(struct ivshm_net *in)
+{
+ struct ivshm_net_queue *tx = &in->tx;
+ u32 tail = tx->tail;
+ u32 head = tx->head;
+ u32 space;
+
+ if (head < tail)
+ space = tail - head;
+ else
+ space = max(tx->size - head, tail);
+
+ return space;
+}
+
+static bool ivshm_net_tx_ok(struct ivshm_net *in, unsigned int mtu)
+{
+ return in->tx.num_free >= 2 &&
+ ivshm_net_tx_space(in) >= 2 * IVSHM_NET_FRAME_SIZE(mtu);
+}
+
+static u32 ivshm_net_tx_advance(struct ivshm_net_queue *q, u32 *pos, u32 len)
+{
+ u32 p = *pos;
+
+ len = IVSHM_NET_FRAME_SIZE(len);
+
+ if (q->size - p < len)
+ p = 0;
+ *pos = p + len;
+
+ return p;
+}
+
+static int ivshm_net_tx_frame(struct net_device *ndev, struct sk_buff *skb)
+{
+ struct ivshm_net *in = netdev_priv(ndev);
+ struct ivshm_net_queue *tx = &in->tx;
+ struct vring *vr = &tx->vr;
+ struct vring_desc *desc;
+ unsigned int desc_idx;
+ unsigned int avail;
+ u32 head;
+ void *buf;
+
+ BUG_ON(tx->num_free < 1);
+
+ spin_lock(&in->tx_free_lock);
+ desc_idx = tx->free_head;
+ desc = &vr->desc[desc_idx];
+ tx->free_head = desc->next;
+ tx->num_free--;
+ spin_unlock(&in->tx_free_lock);
+
+ head = ivshm_net_tx_advance(tx, &tx->head, skb->len);
+
+ buf = tx->data + head;
+ skb_copy_and_csum_dev(skb, buf);
+
+ desc->addr = buf - in->shm;
+ desc->len = skb->len;
+ desc->flags = 0;
+
+ avail = tx->last_avail_idx++ & (vr->num - 1);
+ vr->avail->ring[avail] = desc_idx;
+ tx->num_added++;
+
+ if (!skb->xmit_more) {
+ virt_store_release(&vr->avail->idx, tx->last_avail_idx);
+ ivshm_net_notify_tx(in, tx->num_added);
+ tx->num_added = 0;
+ }
+
+ return 0;
+}
+
+static void ivshm_net_tx_clean(struct net_device *ndev)
+{
+ struct ivshm_net *in = netdev_priv(ndev);
+ struct ivshm_net_queue *tx = &in->tx;
+ struct vring_used_elem *used;
+ struct vring *vr = &tx->vr;
+ struct vring_desc *desc;
+ struct vring_desc *fdesc;
+ unsigned int num;
+ u16 used_idx;
+ u16 last;
+ u32 fhead;
+
+ if (!spin_trylock(&in->tx_clean_lock))
+ return;
+
+ used_idx = virt_load_acquire(&vr->used->idx);
+ last = tx->last_used_idx;
+
+ fdesc = NULL;
+ fhead = 0;
+ num = 0;
+
+ while (last != used_idx) {
+ void *data;
+ u32 len;
+ u32 tail;
+
+ used = vr->used->ring + (last % vr->num);
+ if (used->id >= vr->num || used->len != 1) {
+ netdev_err(ndev, "invalid tx used->id %d ->len %d\n",
+ used->id, used->len);
+ break;
+ }
+
+ desc = &vr->desc[used->id];
+
+ data = ivshm_net_desc_data(in, &in->tx, desc, &len);
+ if (!data) {
+ netdev_err(ndev, "bad tx descriptor, data == NULL\n");
+ break;
+ }
+
+ tail = ivshm_net_tx_advance(tx, &tx->tail, len);
+ if (data != tx->data + tail) {
+ netdev_err(ndev, "bad tx descriptor\n");
+ break;
+ }
+
+ if (!num)
+ fdesc = desc;
+ else
+ desc->next = fhead;
+
+ fhead = used->id;
+ last++;
+ num++;
+ }
+
+ tx->last_used_idx = last;
+
+ spin_unlock(&in->tx_clean_lock);
+
+ if (num) {
+ spin_lock(&in->tx_free_lock);
+ fdesc->next = tx->free_head;
+ tx->free_head = fhead;
+ tx->num_free += num;
+ BUG_ON(tx->num_free > vr->num);
+ spin_unlock(&in->tx_free_lock);
+ }
+}
+
+static struct vring_desc *ivshm_net_rx_desc(struct net_device *ndev)
+{
+ struct ivshm_net *in = netdev_priv(ndev);
+ struct ivshm_net_queue *rx = &in->rx;
+ struct vring *vr = &rx->vr;
+ unsigned int avail;
+ u16 avail_idx;
+
+ avail_idx = virt_load_acquire(&vr->avail->idx);
+
+ if (avail_idx == rx->last_avail_idx)
+ return NULL;
+
+ avail = vr->avail->ring[rx->last_avail_idx++ & (vr->num - 1)];
+ if (avail >= vr->num) {
+ netdev_err(ndev, "invalid rx avail %d\n", avail);
+ return NULL;
+ }
+
+ return &vr->desc[avail];
+}
+
+static void ivshm_net_rx_finish(struct ivshm_net *in, struct vring_desc *desc)
+{
+ struct ivshm_net_queue *rx = &in->rx;
+ struct vring *vr = &rx->vr;
+ unsigned int desc_id = desc - vr->desc;
+ unsigned int used;
+
+ used = rx->last_used_idx++ & (vr->num - 1);
+ vr->used->ring[used].id = desc_id;
+ vr->used->ring[used].len = 1;
+
+ virt_store_release(&vr->used->idx, rx->last_used_idx);
+}
+
+static int ivshm_net_poll(struct napi_struct *napi, int budget)
+{
+ struct net_device *ndev = napi->dev;
+ struct ivshm_net *in = container_of(napi, struct ivshm_net, napi);
+ int received = 0;
+
+ in->stats.napi_poll++;
+
+ ivshm_net_tx_clean(ndev);
+
+ while (received < budget) {
+ struct vring_desc *desc;
+ struct sk_buff *skb;
+ void *data;
+ u32 len;
+
+ desc = ivshm_net_rx_desc(ndev);
+ if (!desc)
+ break;
+
+ data = ivshm_net_desc_data(in, &in->rx, desc, &len);
+ if (!data) {
+ netdev_err(ndev, "bad rx descriptor\n");
+ break;
+ }
+
+ skb = napi_alloc_skb(napi, len);
+
+ if (skb) {
+ memcpy(skb_put(skb, len), data, len);
+ skb->protocol = eth_type_trans(skb, ndev);
+ napi_gro_receive(napi, skb);
+ }
+
+ ndev->stats.rx_packets++;
+ ndev->stats.rx_bytes += len;
+
+ ivshm_net_rx_finish(in, desc);
+ received++;
+ }
+
+ if (received < budget) {
+ in->stats.napi_complete++;
+ napi_complete_done(napi, received);
+ ivshm_net_enable_rx_irq(in);
+ if (ivshm_net_rx_avail(in))
+ napi_schedule(napi);
+ }
+
+ if (received)
+ ivshm_net_notify_rx(in, received);
+
+ in->stats.rx_packets += received;
+ in->stats.napi_poll_n[received ? 1 + min(ilog2(received), 8) : 0]++;
+
+ if (ivshm_net_tx_ok(in, ndev->mtu))
+ netif_wake_queue(ndev);
+
+ return received;
+}
+
+static netdev_tx_t ivshm_net_xmit(struct sk_buff *skb, struct net_device *ndev)
+{
+ struct ivshm_net *in = netdev_priv(ndev);
+
+ ivshm_net_tx_clean(ndev);
+
+ if (!ivshm_net_tx_ok(in, ndev->mtu)) {
+ ivshm_net_enable_tx_irq(in);
+ netif_stop_queue(ndev);
+ skb->xmit_more = 0;
+ in->stats.tx_pause++;
+ }
+
+ ivshm_net_tx_frame(ndev, skb);
+
+ in->stats.tx_packets++;
+ ndev->stats.tx_packets++;
+ ndev->stats.tx_bytes += skb->len;
+
+ dev_consume_skb_any(skb);
+
+ return NETDEV_TX_OK;
+}
+
+static void ivshm_net_set_state(struct ivshm_net *in, u32 state)
+{
+ virt_wmb();
+ WRITE_ONCE(in->lstate, state);
+ writel(state, &in->ivshm_regs->lstate);
+}
+
+static void ivshm_net_run(struct net_device *ndev)
+{
+ struct ivshm_net *in = netdev_priv(ndev);
+
+ if (in->lstate < IVSHM_NET_STATE_READY)
+ return;
+
+ if (!netif_running(ndev))
+ return;
+
+ if (test_and_set_bit(IVSHM_NET_FLAG_RUN, &in->flags))
+ return;
+
+ netif_start_queue(ndev);
+ napi_enable(&in->napi);
+ napi_schedule(&in->napi);
+ ivshm_net_set_state(in, IVSHM_NET_STATE_RUN);
+}
+
+static void ivshm_net_do_stop(struct net_device *ndev)
+{
+ struct ivshm_net *in = netdev_priv(ndev);
+
+ ivshm_net_set_state(in, IVSHM_NET_STATE_RESET);
+
+ if (!test_and_clear_bit(IVSHM_NET_FLAG_RUN, &in->flags))
+ return;
+
+ netif_stop_queue(ndev);
+ napi_disable(&in->napi);
+}
+
+static void ivshm_net_state_change(struct work_struct *work)
+{
+ struct ivshm_net *in = container_of(work, struct ivshm_net, state_work);
+ struct net_device *ndev = in->napi.dev;
+ u32 rstate = readl(&in->ivshm_regs->rstate);
+
+ switch (in->lstate) {
+ case IVSHM_NET_STATE_RESET:
+ /*
+ * Wait for the remote to leave READY/RUN before transitioning
+ * to INIT.
+ */
+ if (rstate < IVSHM_NET_STATE_READY)
+ ivshm_net_set_state(in, IVSHM_NET_STATE_INIT);
+ break;
+
+ case IVSHM_NET_STATE_INIT:
+ /*
+ * Wait for the remote to leave RESET before performing the
+ * initialization and moving to READY.
+ */
+ if (rstate > IVSHM_NET_STATE_RESET) {
+ ivshm_net_init_queues(ndev);
+ ivshm_net_set_state(in, IVSHM_NET_STATE_READY);
+
+ rtnl_lock();
+ call_netdevice_notifiers(NETDEV_CHANGEADDR, ndev);
+ rtnl_unlock();
+ }
+ break;
+
+ case IVSHM_NET_STATE_READY:
+ /*
+ * Link is up and we are running once the remote is in READY or
+ * RUN.
+ */
+ if (rstate >= IVSHM_NET_STATE_READY) {
+ netif_carrier_on(ndev);
+ ivshm_net_run(ndev);
+ break;
+ }
+ /* fall through */
+ case IVSHM_NET_STATE_RUN:
+ /*
+ * If the remote goes to RESET, we need to follow immediately.
+ */
+ if (rstate == IVSHM_NET_STATE_RESET) {
+ netif_carrier_off(ndev);
+ ivshm_net_do_stop(ndev);
+ }
+ break;
+ }
+
+ virt_wmb();
+ WRITE_ONCE(in->rstate, rstate);
+}
+
+static void ivshm_net_check_state(struct net_device *ndev)
+{
+ struct ivshm_net *in = netdev_priv(ndev);
+ u32 rstate = readl(&in->ivshm_regs->rstate);
+
+ if (rstate != in->rstate || !test_bit(IVSHM_NET_FLAG_RUN, &in->flags))
+ queue_work(in->state_wq, &in->state_work);
+}
+
+static irqreturn_t ivshm_net_int(int irq, void *data)
+{
+ struct net_device *ndev = data;
+ struct ivshm_net *in = netdev_priv(ndev);
+
+ in->stats.interrupts++;
+
+ ivshm_net_check_state(ndev);
+ napi_schedule_irqoff(&in->napi);
+
+ return IRQ_HANDLED;
+}
+
+static int ivshm_net_open(struct net_device *ndev)
+{
+ netdev_reset_queue(ndev);
+ ndev->operstate = IF_OPER_UP;
+ ivshm_net_run(ndev);
+
+ return 0;
+}
+
+static int ivshm_net_stop(struct net_device *ndev)
+{
+ ndev->operstate = IF_OPER_DOWN;
+ ivshm_net_do_stop(ndev);
+
+ return 0;
+}
+
+static int ivshm_net_change_mtu(struct net_device *ndev, int mtu)
+{
+ struct ivshm_net *in = netdev_priv(ndev);
+ struct ivshm_net_queue *tx = &in->tx;
+
+ if (mtu < IVSHM_NET_MTU_MIN || mtu > IVSHM_NET_MTU_MAX)
+ return -EINVAL;
+
+ if (in->tx.size / mtu < 4)
+ return -EINVAL;
+
+ if (ivshm_net_tx_space(in) < 2 * IVSHM_NET_FRAME_SIZE(mtu))
+ return -EBUSY;
+
+ if (in->tx.size - tx->head < IVSHM_NET_FRAME_SIZE(mtu) &&
+ tx->head < tx->tail)
+ return -EBUSY;
+
+ netif_tx_lock_bh(ndev);
+ if (in->tx.size - tx->head < IVSHM_NET_FRAME_SIZE(mtu))
+ tx->head = 0;
+ netif_tx_unlock_bh(ndev);
+
+ ndev->mtu = mtu;
+
+ return 0;
+}
+
+#ifdef CONFIG_NET_POLL_CONTROLLER
+static void ivshm_net_poll_controller(struct net_device *ndev)
+{
+ struct ivshm_net *in = netdev_priv(ndev);
+
+ napi_schedule(&in->napi);
+}
+#endif
+
+static const struct net_device_ops ivshm_net_ops = {
+ .ndo_open = ivshm_net_open,
+ .ndo_stop = ivshm_net_stop,
+ .ndo_start_xmit = ivshm_net_xmit,
+ .ndo_change_mtu = ivshm_net_change_mtu,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_validate_addr = eth_validate_addr,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_poll_controller = ivshm_net_poll_controller,
+#endif
+};
+
+static const char ivshm_net_stats[][ETH_GSTRING_LEN] = {
+ "interrupts",
+ "tx_packets",
+ "tx_notify",
+ "tx_pause",
+ "rx_packets",
+ "rx_notify",
+ "napi_poll",
+ "napi_complete",
+ "napi_poll_0",
+ "napi_poll_1",
+ "napi_poll_2",
+ "napi_poll_4",
+ "napi_poll_8",
+ "napi_poll_16",
+ "napi_poll_32",
+ "napi_poll_64",
+ "napi_poll_128",
+ "napi_poll_256",
+};
+
+#define NUM_STATS ARRAY_SIZE(ivshm_net_stats)
+
+static int ivshm_net_get_sset_count(struct net_device *ndev, int sset)
+{
+ if (sset == ETH_SS_STATS)
+ return NUM_STATS;
+
+ return -EOPNOTSUPP;
+}
+
+static void ivshm_net_get_strings(struct net_device *ndev, u32 sset, u8 *buf)
+{
+ if (sset == ETH_SS_STATS)
+ memcpy(buf, &ivshm_net_stats, sizeof(ivshm_net_stats));
+}
+
+static void ivshm_net_get_ethtool_stats(struct net_device *ndev,
+ struct ethtool_stats *estats, u64 *st)
+{
+ struct ivshm_net *in = netdev_priv(ndev);
+ unsigned int n = 0;
+ unsigned int i;
+
+ st[n++] = in->stats.interrupts;
+ st[n++] = in->stats.tx_packets;
+ st[n++] = in->stats.tx_notify;
+ st[n++] = in->stats.tx_pause;
+ st[n++] = in->stats.rx_packets;
+ st[n++] = in->stats.rx_notify;
+ st[n++] = in->stats.napi_poll;
+ st[n++] = in->stats.napi_complete;
+
+ for (i = 0; i < ARRAY_SIZE(in->stats.napi_poll_n); i++)
+ st[n++] = in->stats.napi_poll_n[i];
+
+ memset(&in->stats, 0, sizeof(in->stats));
+}
+
+#define IVSHM_NET_REGS_LEN (3 * sizeof(u32) + 6 * sizeof(u16))
+
+static int ivshm_net_get_regs_len(struct net_device *ndev)
+{
+ return IVSHM_NET_REGS_LEN;
+}
+
+static void ivshm_net_get_regs(struct net_device *ndev,
+ struct ethtool_regs *regs, void *p)
+{
+ struct ivshm_net *in = netdev_priv(ndev);
+ u32 *reg32 = p;
+ u16 *reg16;
+
+ *reg32++ = in->lstate;
+ *reg32++ = in->rstate;
+ *reg32++ = in->qlen;
+
+ reg16 = (u16 *)reg32;
+
+ *reg16++ = in->tx.vr.avail ? in->tx.vr.avail->idx : 0;
+ *reg16++ = in->tx.vr.used ? in->tx.vr.used->idx : 0;
+ *reg16++ = in->tx.vr.avail ? vring_avail_event(&in->tx.vr) : 0;
+
+ *reg16++ = in->rx.vr.avail ? in->rx.vr.avail->idx : 0;
+ *reg16++ = in->rx.vr.used ? in->rx.vr.used->idx : 0;
+ *reg16++ = in->rx.vr.avail ? vring_avail_event(&in->rx.vr) : 0;
+}
+
+static const struct ethtool_ops ivshm_net_ethtool_ops = {
+ .get_sset_count = ivshm_net_get_sset_count,
+ .get_strings = ivshm_net_get_strings,
+ .get_ethtool_stats = ivshm_net_get_ethtool_stats,
+ .get_regs_len = ivshm_net_get_regs_len,
+ .get_regs = ivshm_net_get_regs,
+};
+
+static int ivshm_net_probe(struct pci_dev *pdev,
+ const struct pci_device_id *id)
+{
+ struct net_device *ndev;
+ struct ivshm_net *in;
+ struct ivshmem_regs __iomem *regs;
+ resource_size_t shmaddr;
+ resource_size_t shmlen;
+ char *device_name;
+ void *shm;
+ u32 ivpos;
+ int ret;
+
+ ret = pcim_enable_device(pdev);
+ if (ret) {
+ dev_err(&pdev->dev, "pci_enable_device: %d\n", ret);
+ return ret;
+ }
+
+ ret = pcim_iomap_regions(pdev, BIT(0), DRV_NAME);
+ if (ret) {
+ dev_err(&pdev->dev, "pcim_iomap_regions: %d\n", ret);
+ return ret;
+ }
+
+ regs = pcim_iomap_table(pdev)[0];
+
+ shmlen = pci_resource_len(pdev, 2);
+
+ if (shmlen) {
+ shmaddr = pci_resource_start(pdev, 2);
+ } else {
+ union { u64 v; u32 hl[2]; } val;
+
+ pci_read_config_dword(pdev, JAILHOUSE_CFG_SHMEM_PTR,
+ &val.hl[0]);
+ pci_read_config_dword(pdev, JAILHOUSE_CFG_SHMEM_PTR + 4,
+ &val.hl[1]);
+ shmaddr = val.v;
+
+ pci_read_config_dword(pdev, JAILHOUSE_CFG_SHMEM_SZ,
+ &val.hl[0]);
+ pci_read_config_dword(pdev, JAILHOUSE_CFG_SHMEM_SZ + 4,
+ &val.hl[1]);
+ shmlen = val.v;
+ }
+
+
+ if (!devm_request_mem_region(&pdev->dev, shmaddr, shmlen, DRV_NAME))
+ return -EBUSY;
+
+ shm = devm_memremap(&pdev->dev, shmaddr, shmlen, MEMREMAP_WB);
+ if (!shm)
+ return -ENOMEM;
+
+ ivpos = readl(&regs->ivpos);
+ if (ivpos > 1) {
+ dev_err(&pdev->dev, "invalid IVPosition %d\n", ivpos);
+ return -EINVAL;
+ }
+
+ device_name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "%s[%s]", DRV_NAME,
+ dev_name(&pdev->dev));
+ if (!device_name)
+ return -ENOMEM;
+
+ ndev = alloc_etherdev(sizeof(*in));
+ if (!ndev)
+ return -ENOMEM;
+
+ pci_set_drvdata(pdev, ndev);
+ SET_NETDEV_DEV(ndev, &pdev->dev);
+
+ in = netdev_priv(ndev);
+ in->ivshm_regs = regs;
+ in->shm = shm;
+ in->shmaddr = shmaddr;
+ in->shmlen = shmlen;
+ in->peer_id = !ivpos;
+ in->pdev = pdev;
+ spin_lock_init(&in->tx_free_lock);
+ spin_lock_init(&in->tx_clean_lock);
+
+ ret = ivshm_net_calc_qsize(ndev);
+ if (ret)
+ goto err_free;
+
+ in->state_wq = alloc_ordered_workqueue(device_name, 0);
+ if (!in->state_wq)
+ goto err_free;
+
+ INIT_WORK(&in->state_work, ivshm_net_state_change);
+
+ eth_random_addr(ndev->dev_addr);
+ ndev->netdev_ops = &ivshm_net_ops;
+ ndev->ethtool_ops = &ivshm_net_ethtool_ops;
+ ndev->mtu = min_t(u32, IVSHM_NET_MTU_DEF, in->qsize / 16);
+ ndev->hw_features = NETIF_F_HW_CSUM | NETIF_F_SG;
+ ndev->features = ndev->hw_features;
+
+ netif_carrier_off(ndev);
+ netif_napi_add(ndev, &in->napi, ivshm_net_poll, NAPI_POLL_WEIGHT);
+
+ ret = register_netdev(ndev);
+ if (ret)
+ goto err_wq;
+
+ ret = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_LEGACY | PCI_IRQ_MSIX);
+ if (ret < 0)
+ goto err_alloc_irq;
+
+ ret = request_irq(pci_irq_vector(pdev, 0), ivshm_net_int, 0,
+ device_name, ndev);
+ if (ret)
+ goto err_request_irq;
+
+ pci_set_master(pdev);
+ if (!pdev->msix_enabled)
+ writel(IVSHMEM_INTX_ENABLE, &in->ivshm_regs->intxctrl);
+
+ writel(IVSHM_NET_STATE_RESET, &in->ivshm_regs->lstate);
+ ivshm_net_check_state(ndev);
+
+ return 0;
+
+err_request_irq:
+ pci_free_irq_vectors(pdev);
+err_alloc_irq:
+ unregister_netdev(ndev);
+err_wq:
+ destroy_workqueue(in->state_wq);
+err_free:
+ free_netdev(ndev);
+
+ return ret;
+}
+
+static void ivshm_net_remove(struct pci_dev *pdev)
+{
+ struct net_device *ndev = pci_get_drvdata(pdev);
+ struct ivshm_net *in = netdev_priv(ndev);
+
+ writel(IVSHM_NET_STATE_RESET, &in->ivshm_regs->lstate);
+
+ if (!pdev->msix_enabled)
+ writel(0, &in->ivshm_regs->intxctrl);
+ free_irq(pci_irq_vector(pdev, 0), ndev);
+ pci_free_irq_vectors(pdev);
+
+ unregister_netdev(ndev);
+ cancel_work_sync(&in->state_work);
+ destroy_workqueue(in->state_wq);
+ free_netdev(ndev);
+}
+
+static const struct pci_device_id ivshm_net_id_table[] = {
+ { PCI_DEVICE(PCI_VENDOR_ID_REDHAT_QUMRANET, 0x1110),
+ (PCI_CLASS_OTHERS << 16) | (0x01 << 8), 0xffff00 },
+ { 0 }
+};
+MODULE_DEVICE_TABLE(pci, ivshm_net_id_table);
+
+static struct pci_driver ivshm_net_driver = {
+ .name = DRV_NAME,
+ .id_table = ivshm_net_id_table,
+ .probe = ivshm_net_probe,
+ .remove = ivshm_net_remove,
+};
+module_pci_driver(ivshm_net_driver);
+
+MODULE_AUTHOR("Mans Rullgard <mans@mansr.com>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
index cd931cf9dcc2..d9b51a7fddb1 100644
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -356,6 +356,11 @@ config NATIONAL_PHY
---help---
Currently supports the DP83865 PHY.
+config NXP_TJA110X_PHY
+ tristate "NXP TJA110X PHY support"
+ ---help---
+ Currently supports the TJA110X PHY.
+
config QSEMI_PHY
tristate "Quality Semiconductor PHYs"
---help---
diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile
index 00f097e18c68..c2a05f753b89 100644
--- a/drivers/net/phy/Makefile
+++ b/drivers/net/phy/Makefile
@@ -71,6 +71,7 @@ obj-$(CONFIG_MICREL_PHY) += micrel.o
obj-$(CONFIG_MICROCHIP_PHY) += microchip.o
obj-$(CONFIG_MICROSEMI_PHY) += mscc.o
obj-$(CONFIG_NATIONAL_PHY) += national.o
+obj-$(CONFIG_NXP_TJA110X_PHY) += tja110x.o
obj-$(CONFIG_QSEMI_PHY) += qsemi.o
obj-$(CONFIG_REALTEK_PHY) += realtek.o
obj-$(CONFIG_ROCKCHIP_PHY) += rockchip.o
diff --git a/drivers/net/phy/at803x.c b/drivers/net/phy/at803x.c
index e911e4990b20..7e72e4b5a626 100644
--- a/drivers/net/phy/at803x.c
+++ b/drivers/net/phy/at803x.c
@@ -18,6 +18,7 @@
#include <linux/etherdevice.h>
#include <linux/of_gpio.h>
#include <linux/gpio/consumer.h>
+#include <linux/phy.h>
#define AT803X_INTR_ENABLE 0x12
#define AT803X_INTR_ENABLE_AUTONEG_ERR BIT(15)
@@ -39,11 +40,13 @@
#define AT803X_LOC_MAC_ADDR_0_15_OFFSET 0x804C
#define AT803X_LOC_MAC_ADDR_16_31_OFFSET 0x804B
#define AT803X_LOC_MAC_ADDR_32_47_OFFSET 0x804A
+#define AT803X_SMARTEEE_CTL3_OFFSET 0x805D
#define AT803X_MMD_ACCESS_CONTROL 0x0D
#define AT803X_MMD_ACCESS_CONTROL_DATA 0x0E
#define AT803X_FUNC_DATA 0x4003
#define AT803X_REG_CHIP_CONFIG 0x1f
#define AT803X_BT_BX_REG_SEL 0x8000
+#define AT803X_SMARTEEE_DISABLED_VAL 0x1000
#define AT803X_DEBUG_ADDR 0x1D
#define AT803X_DEBUG_DATA 0x1E
@@ -60,11 +63,22 @@
#define AT803X_DEBUG_REG_5 0x05
#define AT803X_DEBUG_TX_CLK_DLY_EN BIT(8)
+#define AT803X_DEBUG_REG_31 0x1f
+#define AT803X_VDDIO_1P8V_EN 0x8
+
#define ATH8030_PHY_ID 0x004dd076
#define ATH8031_PHY_ID 0x004dd074
#define ATH8035_PHY_ID 0x004dd072
#define AT803X_PHY_ID_MASK 0xffffffef
+/* LED_ACT is busy on blinding even if no any frame transferring,
+ * it may cause by PHY/RJ45 power supply issue, the fixup flag just
+ * to do sw workaround for the issue.
+ */
+#define AT803X_LED_ACT_BLINDING_WORKAROUND (1 << 0)
+#define AT803X_EEE_FEATURE_DISABLE (1 << 1)
+#define AT803X_VDDIO_1P8V (1 << 2)
+
MODULE_DESCRIPTION("Atheros 803x PHY driver");
MODULE_AUTHOR("Matus Ujhelyi");
MODULE_LICENSE("GPL");
@@ -72,6 +86,7 @@ MODULE_LICENSE("GPL");
struct at803x_priv {
bool phy_reset:1;
struct gpio_desc *gpiod_reset;
+ u32 quirks;
};
struct at803x_context {
@@ -111,16 +126,57 @@ static int at803x_debug_reg_mask(struct phy_device *phydev, u16 reg,
return phy_write(phydev, AT803X_DEBUG_DATA, val);
}
-static inline int at803x_enable_rx_delay(struct phy_device *phydev)
+static inline int at803x_set_rx_delay(struct phy_device *phydev, bool is_enabled)
{
- return at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_0, 0,
- AT803X_DEBUG_RX_CLK_DLY_EN);
+ if (is_enabled)
+ return at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_0, 0,
+ AT803X_DEBUG_RX_CLK_DLY_EN);
+ else
+ return at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_0,
+ AT803X_DEBUG_RX_CLK_DLY_EN, 0);
}
-static inline int at803x_enable_tx_delay(struct phy_device *phydev)
+static inline int at803x_set_tx_delay(struct phy_device *phydev, bool is_enabled)
{
- return at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_5, 0,
- AT803X_DEBUG_TX_CLK_DLY_EN);
+ if (is_enabled)
+ return at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_5, 0,
+ AT803X_DEBUG_TX_CLK_DLY_EN);
+ else
+ return at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_5,
+ AT803X_DEBUG_TX_CLK_DLY_EN, 0);
+}
+
+static inline int at803x_set_vddio_1p8v(struct phy_device *phydev)
+{
+ return at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_31, 0,
+ AT803X_VDDIO_1P8V_EN);
+}
+
+static int at803x_disable_eee(struct phy_device *phydev)
+{
+ int ret;
+
+ ret = phy_write(phydev, AT803X_MMD_ACCESS_CONTROL,
+ AT803X_DEVICE_ADDR);
+ if (ret < 0)
+ return ret;
+
+ ret = phy_write(phydev, AT803X_MMD_ACCESS_CONTROL_DATA,
+ AT803X_SMARTEEE_CTL3_OFFSET);
+ if (ret < 0)
+ return ret;
+
+ ret = phy_write(phydev, AT803X_MMD_ACCESS_CONTROL,
+ AT803X_FUNC_DATA);
+ if (ret < 0)
+ return ret;
+
+ ret = phy_write(phydev, AT803X_MMD_ACCESS_CONTROL_DATA,
+ AT803X_SMARTEEE_DISABLED_VAL);
+ if (ret < 0)
+ return ret;
+
+ return 0;
}
/* save relevant PHY registers to private copy */
@@ -256,6 +312,15 @@ static int at803x_probe(struct phy_device *phydev)
if (!priv)
return -ENOMEM;
+ if (of_property_read_bool(dev->of_node, "at803x,led-act-blind-workaround"))
+ priv->quirks |= AT803X_LED_ACT_BLINDING_WORKAROUND;
+
+ if (of_property_read_bool(dev->of_node, "at803x,eee-disabled"))
+ priv->quirks |= AT803X_EEE_FEATURE_DISABLE;
+
+ if (of_property_read_bool(dev->of_node, "at803x,vddio-1p8v"))
+ priv->quirks |= AT803X_VDDIO_1P8V;
+
if (phydev->drv->phy_id != ATH8030_PHY_ID)
goto does_not_require_reset_workaround;
@@ -274,21 +339,44 @@ does_not_require_reset_workaround:
static int at803x_config_init(struct phy_device *phydev)
{
int ret;
+ struct at803x_priv *priv = phydev->priv;
ret = genphy_config_init(phydev);
if (ret < 0)
return ret;
+ /* Firstly clear the default status in HW reset or
+ * the bits set by bootloader.
+ */
+ ret = at803x_set_rx_delay(phydev, false);
+ if (ret < 0)
+ return ret;
+ ret = at803x_set_tx_delay(phydev, false);
+ if (ret < 0)
+ return ret;
+
if (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID ||
phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) {
- ret = at803x_enable_rx_delay(phydev);
+ ret = at803x_set_rx_delay(phydev, true);
if (ret < 0)
return ret;
}
if (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID ||
phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) {
- ret = at803x_enable_tx_delay(phydev);
+ ret = at803x_set_tx_delay(phydev, true);
+ if (ret < 0)
+ return ret;
+ }
+
+ if (priv->quirks & AT803X_VDDIO_1P8V) {
+ ret = at803x_set_vddio_1p8v(phydev);
+ if (ret < 0)
+ return ret;
+ }
+
+ if (priv->quirks & AT803X_EEE_FEATURE_DISABLE) {
+ ret = at803x_disable_eee(phydev);
if (ret < 0)
return ret;
}
@@ -360,6 +448,37 @@ static void at803x_link_change_notify(struct phy_device *phydev)
}
}
+int at803x_config_aneg(struct phy_device *phydev)
+{
+ struct at803x_priv *priv = phydev->priv;
+ int result;
+
+ /* Only restart aneg if we are advertising something different
+ * than we were before.
+ */
+ result = genphy_config_aneg_check(phydev);
+ if (result > 0) {
+ /* do autonegotiation here */
+ result = phy_read(phydev, MII_BMCR);
+ if (result < 0)
+ return result;
+
+ /* firstly power down here */
+ if (priv->quirks & AT803X_LED_ACT_BLINDING_WORKAROUND) {
+ phy_write(phydev, MII_BMCR, BMCR_PDOWN);
+ msleep(1);
+ }
+
+ result |= BMCR_ANENABLE | BMCR_ANRESTART;
+ /* Don't isolate the PHY if we're negotiating */
+ result &= ~BMCR_ISOLATE;
+
+ result = phy_write(phydev, MII_BMCR, result);
+ }
+
+ return result;
+}
+
static int at803x_aneg_done(struct phy_device *phydev)
{
int ccr;
@@ -439,7 +558,7 @@ static struct phy_driver at803x_driver[] = {
.resume = at803x_resume,
.features = PHY_GBIT_FEATURES,
.flags = PHY_HAS_INTERRUPT,
- .config_aneg = genphy_config_aneg,
+ .config_aneg = at803x_config_aneg,
.read_status = genphy_read_status,
.aneg_done = at803x_aneg_done,
.ack_interrupt = &at803x_ack_interrupt,
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index ed7e3c70b511..9152e0e7e3b6 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -85,13 +85,23 @@ static bool mdio_bus_phy_may_suspend(struct phy_device *phydev)
if (!drv || !phydrv->suspend)
return false;
- /* PHY not attached? May suspend if the PHY has not already been
- * suspended as part of a prior call to phy_disconnect() ->
- * phy_detach() -> phy_suspend() because the parent netdev might be the
- * MDIO bus driver and clock gated at this point.
+ /*
+ * netdev is NULL has three cases:
+ * - phy is not found
+ * - phy is found, match to general phy driver
+ * - phy is found, match to specifical phy driver
+ *
+ * Case 1: phy is not found, cannot communicate by MDIO bus.
+ * Case 2: phy is found:
+ * if phy dev driver probe/bind err, netdev is not __open__ status,
+ * mdio bus is unregistered.
+ * if phy is detached, phy had entered suspended status.
+ * Case 3: phy is found, phy is detached, phy had entered suspended status.
+ *
+ * So, in here, it shouldn't set phy to suspend by calling mdio bus.
*/
if (!netdev)
- return !phydev->suspended;
+ return false;
/* Don't suspend PHY if the attached netdev parent may wakeup.
* The parent may point to a PCI device, as in tg3 driver.
@@ -1384,15 +1394,7 @@ int genphy_restart_aneg(struct phy_device *phydev)
}
EXPORT_SYMBOL(genphy_restart_aneg);
-/**
- * genphy_config_aneg - restart auto-negotiation or write BMCR
- * @phydev: target phy_device struct
- *
- * Description: If auto-negotiation is enabled, we configure the
- * advertising, and then restart auto-negotiation. If it is not
- * enabled, then we write the BMCR.
- */
-int genphy_config_aneg(struct phy_device *phydev)
+int genphy_config_aneg_check(struct phy_device *phydev)
{
int err, changed;
@@ -1420,11 +1422,28 @@ int genphy_config_aneg(struct phy_device *phydev)
changed = 1; /* do restart aneg */
}
+ return changed;
+}
+EXPORT_SYMBOL(genphy_config_aneg_check);
+
+/**
+ * genphy_config_aneg - restart auto-negotiation or write BMCR
+ * @phydev: target phy_device struct
+ *
+ * Description: If auto-negotiation is enabled, we configure the
+ * advertising, and then restart auto-negotiation. If it is not
+ * enabled, then we write the BMCR.
+ */
+int genphy_config_aneg(struct phy_device *phydev)
+{
+ int result;
+
/* Only restart aneg if we are advertising something different
* than we were before.
*/
- if (changed > 0)
- return genphy_restart_aneg(phydev);
+ result = genphy_config_aneg_check(phydev);
+ if (result > 0)
+ result = genphy_restart_aneg(phydev);
return 0;
}
diff --git a/drivers/net/phy/tja110x.c b/drivers/net/phy/tja110x.c
new file mode 100644
index 000000000000..58c2618f28e4
--- /dev/null
+++ b/drivers/net/phy/tja110x.c
@@ -0,0 +1,2542 @@
+/*
+ * Copyright 2017-2018 NXP
+ *
+ * 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/init.h>
+#include <linux/netdevice.h>
+#include <linux/of_mdio.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/mii.h>
+#include <linux/phy.h>
+#include <linux/delay.h>
+
+#include "tja110x.h"
+
+/* load driver for TJA1102p1. It needs to be ensured,
+ * that no other mdio device with phy id 0 is present
+ */
+#define CONFIG_TJA1102_FIX
+
+/* listen for NETDEV_GOING_DOWN and NETDEV_UP of the ethernet interface,
+ * that controls the mdio bus to which the nxp phy(s) is/are connected to.
+ * Polling is stopped/started accordingly, to prevent mdio read timeouts
+ * This fix requires MDIO_INTERFACE_NAME and MII_BUS_NAME to be set
+ */
+#define NETDEV_NOTIFICATION_FIX
+
+/* Name of the eth interface, that controlls the mdio bus,
+ * to which the phy(s) is/are connected to
+ */
+#ifndef MDIO_INTERFACE_NAME
+#define MDIO_INTERFACE_NAME "eth0"
+#endif
+
+/* Name of the mdio bus,
+ * to which the phy(s) is/are connected to
+ */
+#ifndef MII_BUS_NAME
+#define MII_BUS_NAME "fec_enet_mii_bus"
+#endif
+
+#define TJA110X_REFCLK_IN (1 << 0)
+
+/* Variable can be modified via parameter passed at load time
+ * A nonzero value indicates that we should operate in managed mode
+ */
+static int managed_mode;
+/* Permission: do not show up in sysfs */
+module_param(managed_mode, int, 0000);
+MODULE_PARM_DESC(managed_mode, "Use PHY in managed or autonomous mode");
+
+/* A nonzero value indicates that we should not poll the interrupt register */
+static int no_poll;
+/* Permission: do not show up in sysfs */
+module_param(no_poll, int, 0000);
+MODULE_PARM_DESC(no_poll, "Do not poll the interrupt register");
+
+/* Detemines the level of verbosity for debug messages */
+static int verbosity;
+/* Permission: do not show up in sysfs */
+module_param(verbosity, int, 0000);
+MODULE_PARM_DESC(verbosity, "Set verbosity level");
+
+/* Called to initialize the PHY,
+ * including after a reset
+ */
+static int nxp_config_init(struct phy_device *phydev)
+{
+ struct nxp_specific_data *nxp_specific = phydev->priv;
+ int reg_val;
+ int reg_name, reg_value = -1, reg_mask;
+ int err;
+
+ if (verbosity > 0)
+ dev_alert(&phydev->mdio.dev, "initializing phy %x\n", phydev->mdio.addr);
+
+ /* set features of the PHY */
+ reg_val = phy_read(phydev, MII_BMSR);
+ if (reg_val < 0)
+ goto phy_read_error;
+ if (reg_val & BMSR_ESTATEN) {
+ reg_val = phy_read(phydev, MII_ESTATUS);
+
+ if (reg_val < 0)
+ goto phy_read_error;
+
+ if (reg_val & ESTATUS_100T1_FULL) {
+ /* update phydev to include the supported features */
+ phydev->supported |= SUPPORTED_100BASET1_FULL;
+ phydev->advertising |= ADVERTISED_100BASET1_FULL;
+ }
+ }
+
+ /* enable configuration register access once during initialization */
+ err = phy_configure_bit(phydev, MII_ECTRL, ECTRL_CONFIG_EN, 1);
+ if (err < 0)
+ goto phy_configure_error;
+
+ /* -enter managed or autonomous mode,
+ * depending on the value of managed_mode.
+ * The register layout changed between TJA1100 and TJA1102
+ * -configure LED mode (only tja1100 has LEDs)
+ */
+ switch (phydev->phy_id & NXP_PHY_ID_MASK) {
+ case NXP_PHY_ID_TJA1100:
+ reg_name = MII_CFG1;
+ reg_value = TJA1100_CFG1_LED_EN | CFG1_LED_LINKUP;
+ if (!managed_mode)
+ reg_value |= TJA1100_CFG1_AUTO_OP;
+ reg_mask = TJA1100_CFG1_AUTO_OP |
+ TJA1100_CFG1_LED_EN | TJA1100_CFG1_LED_MODE;
+
+ if (nxp_specific->quirks & TJA110X_REFCLK_IN) {
+ reg_value |= TJA1100_CFG1_MII_MODE_REFCLK_IN;
+ reg_mask |= CFG1_MII_MODE;
+ }
+ break;
+ case NXP_PHY_ID_TJA1101:
+ /* fall through */
+ case NXP_PHY_ID_TJA1102P0:
+ reg_name = MII_COMMCFG;
+ reg_value = 0;
+ if (!managed_mode)
+ reg_value |= COMMCFG_AUTO_OP;
+ reg_mask = COMMCFG_AUTO_OP;
+ break;
+
+ case NXP_PHY_ID_TJA1102P1:
+ /* does not have an auto_op bit */
+ break;
+
+ default:
+ goto unsupported_phy_error;
+ }
+
+ /* only configure the phys that have an auto_op bit or leds */
+ if (reg_value != -1) {
+ err = phy_configure_bits(phydev, reg_name, reg_mask, reg_value);
+ if (err < 0)
+ goto phy_configure_error;
+ }
+
+ /* enable sleep confirm */
+ err = phy_configure_bit(phydev, MII_CFG1, CFG1_SLEEP_CONFIRM, 1);
+ if (err < 0)
+ goto phy_configure_error;
+
+ /* set sleep request timeout to 16ms */
+ err = phy_configure_bits(phydev, MII_CFG2, CFG2_SLEEP_REQUEST_TO,
+ SLEEP_REQUEST_TO_16MS);
+ if (err < 0)
+ goto phy_configure_error;
+
+ /* if in managed mode:
+ * -go to normal mode, if currently in standby
+ * (PHY might be pinstrapped to managed mode,
+ * and therefore not in normal mode yet)
+ * -enable link control
+ */
+ if (managed_mode) {
+ reg_val = phy_read(phydev, MII_ECTRL);
+ if (reg_val < 0)
+ goto phy_read_error;
+
+ /* mask power mode bits */
+ reg_val &= ECTRL_POWER_MODE;
+
+ if (reg_val == POWER_MODE_STANDBY) {
+ err = phydev->drv->resume(phydev);
+ if (err < 0)
+ goto phy_pmode_transit_error;
+ }
+
+ set_link_control(phydev, 1);
+ }
+
+ /* clear any pending interrupts */
+ phydev->drv->ack_interrupt(phydev);
+
+ phydev->irq = PHY_POLL;
+
+ /* enable all interrupts */
+ phydev->interrupts = PHY_INTERRUPT_ENABLED;
+ phydev->drv->config_intr(phydev);
+
+ /* Setup and queue a polling function */
+ if (!no_poll) {
+ setup_polling(phydev);
+ start_polling(phydev);
+ }
+
+ return 0;
+
+/* error handling */
+phy_read_error:
+ dev_err(&phydev->mdio.dev, "read error: config_init failed\n");
+ return reg_val;
+
+phy_pmode_transit_error:
+ dev_err(&phydev->mdio.dev, "pmode error: config_init failed\n");
+ return err;
+
+phy_configure_error:
+ dev_err(&phydev->mdio.dev, "read/write error: config_init failed\n");
+ return err;
+
+unsupported_phy_error:
+ dev_err(&phydev->mdio.dev, "unsupported phy, config_init failed\n");
+ return -1;
+}
+
+/* Called during discovery.
+ * Used to set up device-specific structures
+ */
+static int nxp_probe(struct phy_device *phydev)
+{
+ int err;
+ struct device *dev = &phydev->mdio.dev;
+ struct nxp_specific_data *nxp_specific;
+
+ if (verbosity > 0)
+ dev_alert(&phydev->mdio.dev, "probing PHY %x\n", phydev->mdio.addr);
+
+ nxp_specific = kzalloc(sizeof(*nxp_specific), GFP_KERNEL);
+ if (!nxp_specific)
+ goto phy_allocation_error;
+
+ if (of_property_read_bool(dev->of_node, "tja110x,refclk_in"))
+ nxp_specific->quirks |= TJA110X_REFCLK_IN;
+
+ nxp_specific->is_master = get_master_cfg(phydev);
+ nxp_specific->is_polling = 0;
+ nxp_specific->is_poll_setup = 0;
+
+ phydev->priv = nxp_specific;
+
+ /* register sysfs files */
+ err = sysfs_create_group(&phydev->mdio.dev.kobj, &nxp_attribute_group);
+ if (err)
+ goto register_sysfs_error;
+
+ return 0;
+
+/* error handling */
+register_sysfs_error:
+ dev_err(&phydev->mdio.dev, "sysfs file creation failed\n");
+ return -ENOMEM;
+
+phy_allocation_error:
+ dev_err(&phydev->mdio.dev, "memory allocation for priv data failed\n");
+ return -ENOMEM;
+}
+
+/* Clears up any memory, removes sysfs nodes and cancels polling */
+static void nxp_remove(struct phy_device *phydev)
+{
+ if (verbosity > 0)
+ dev_alert(&phydev->mdio.dev, "removing PHY %x\n", phydev->mdio.addr);
+
+ /* unregister sysfs files */
+ sysfs_remove_group(&phydev->mdio.dev.kobj, &nxp_attribute_group);
+
+ if (!no_poll)
+ stop_polling(phydev);
+
+ /* free custom data struct */
+ if (phydev->priv) {
+ kzfree(phydev->priv);
+ phydev->priv = NULL;
+ }
+}
+
+/* Clears any pending interrupts */
+static int nxp_ack_interrupt(struct phy_device *phydev)
+{
+ int err;
+
+ if (verbosity > 3)
+ dev_alert(&phydev->mdio.dev, "acknowledging interrupt of PHY %x\n",
+ phydev->mdio.addr);
+
+ /* interrupts are acknowledged by reading, ie. clearing MII_INTSRC */
+ err = phy_read(phydev, MII_INTSRC);
+ if (err < 0)
+ goto phy_read_error;
+ return 0;
+
+/* error handling */
+phy_read_error:
+ dev_err(&phydev->mdio.dev, "read error: ack_interrupt failed\n");
+ return err;
+}
+
+/* Checks if the PHY generated an interrupt */
+static int nxp_did_interrupt(struct phy_device *phydev)
+{
+ int reg_val;
+
+ reg_val = phy_read(phydev, MII_INTSRC);
+ if (reg_val < 0)
+ goto phy_read_error;
+
+ /* return bitmask of possible interrupts bits that are set */
+ return (reg_val & INTERRUPT_ALL);
+
+/* error handling */
+phy_read_error:
+ dev_err(&phydev->mdio.dev, "read error: did_interrupt failed\n");
+ return 0;
+}
+
+/* Enables or disables interrupts */
+static int nxp_config_intr(struct phy_device *phydev)
+{
+ int err;
+ int interrupts;
+
+ if (verbosity > 0)
+ dev_alert(&phydev->mdio.dev,
+ "configuring interrupts of phy %x to [%x]\n",
+ phydev->mdio.addr, phydev->interrupts);
+
+ interrupts = phydev->interrupts;
+
+ if (interrupts == PHY_INTERRUPT_ENABLED) {
+ /* enable all interrupts
+ * PHY_INTERRUPT_ENABLED macro does not interfere with any
+ * of the possible interrupt source macros
+ */
+ err = phy_write(phydev, MII_INTMASK, INTERRUPT_ALL);
+ } else if (interrupts == PHY_INTERRUPT_DISABLED) {
+ /* disable all interrupts */
+ err = phy_write(phydev, MII_INTMASK, INTERRUPT_NONE);
+ } else {
+ /* interpret value of interrupts as interrupt mask */
+ err = phy_write(phydev, MII_INTMASK, interrupts);
+ }
+
+ if (err < 0)
+ goto phy_write_error;
+ return 0;
+
+phy_write_error:
+ dev_err(&phydev->mdio.dev, "write error: config_intr failed\n");
+ return err;
+}
+
+/* interrupt handler for pwon interrupts */
+static inline void handle_pwon_interrupt(struct phy_device *phydev)
+{
+ if (verbosity > 0)
+ dev_alert(&phydev->mdio.dev,
+ "reinitializing phy [%08x] @ [%04x] after powerdown\n",
+ phydev->phy_id, phydev->mdio.addr);
+ /* after a power down reinitialize the phy */
+ phydev->drv->config_init(phydev);
+
+ /* update master/slave setting */
+ ((struct nxp_specific_data *)phydev->priv)->is_master =
+ get_master_cfg(phydev);
+
+ /* For TJA1102, pwon interrupts only exist on TJA1102p0
+ * Find TJA1102p1 to reinitialize it too
+ */
+ if ((phydev->phy_id & NXP_PHY_ID_MASK) == NXP_PHY_ID_TJA1102P0) {
+ int p1_addr = phydev->mdio.addr + 1;
+ struct phy_device *phydevp1;
+
+ if (p1_addr >= PHY_MAX_ADDR)
+ return;
+
+ phydevp1 = mdiobus_get_phy(phydev->mdio.bus, p1_addr);
+ if (!phydevp1)
+ return;
+
+ if (verbosity > 0)
+ dev_alert(&phydev->mdio.dev,
+ "reinit phy [%08x] @ [%04x] after pDown\n",
+ phydevp1->phy_id, phydevp1->mdio.addr);
+ phydevp1->drv->config_init(phydevp1);
+ ((struct nxp_specific_data *)phydevp1->priv)->is_master =
+ get_master_cfg(phydevp1);
+ }
+}
+
+/* interrupt handler for undervoltage recovery interrupts */
+static inline void handle_uvr_interrupt(struct phy_device *phydev)
+{
+ if (verbosity > 0)
+ dev_alert(&phydev->mdio.dev,
+ "resuming phy [%08x] @ [%04x] after uvr\n",
+ phydev->phy_id, phydev->mdio.addr);
+ phydev->drv->resume(phydev);
+
+ /* For TJA1102, UVR interrupts only exist on TJA1102p0
+ * Find TJA1102p1 to resume it too
+ */
+ if ((phydev->phy_id & NXP_PHY_ID_MASK) == NXP_PHY_ID_TJA1102P0) {
+ int p1_addr = phydev->mdio.addr + 1;
+ struct phy_device *phydevp1;
+
+ if (p1_addr >= PHY_MAX_ADDR)
+ return;
+
+ phydevp1 = mdiobus_get_phy(phydev->mdio.bus, p1_addr);
+ if (!phydevp1)
+ return;
+
+ if (verbosity > 0)
+ dev_alert(&phydev->mdio.dev,
+ "resuming phy [%08x] @ [%04x] after uvr\n",
+ phydevp1->phy_id, phydevp1->mdio.addr);
+ phydevp1->drv->resume(phydevp1);
+ }
+}
+
+/* polling function, that is executed regularly to handle phy interrupts */
+static void poll(struct work_struct *work)
+{
+ int interrupts, interrupt_mask;
+ struct phy_device *phydev =
+ container_of(work, struct phy_device, phy_queue);
+
+ /* query phy for interrupts */
+ interrupts = nxp_did_interrupt(phydev);
+
+ /* mask out all disabled interrupts */
+ interrupt_mask = phy_read(phydev, MII_INTMASK);
+ if (verbosity > 4)
+ dev_alert(&phydev->mdio.dev,
+ "interrupt on phy [%08x]@[%04x], mask [%08x], ISR [%08x]\n",
+ phydev->phy_id, phydev->mdio.addr, interrupt_mask, interrupts);
+
+ interrupts &= interrupt_mask;
+
+ /* handle interrupts
+ * - reinitialize after power down
+ * - resume PHY after an external WAKEUP was received
+ * - resume PHY after an undervoltage recovery
+ * - adjust state on link changes
+ * - check for some PHY errors
+ */
+
+ /* SMI not disabled and read was successful */
+ if ((interrupts != 0xffff) && (interrupt_mask >= 0)) {
+ if (interrupts & INTERRUPT_PWON)
+ handle_pwon_interrupt(phydev);
+ else if (interrupts & INTERRUPT_UV_RECOVERY)
+ handle_uvr_interrupt(phydev);
+ else if (interrupts & INTERRUPT_WAKEUP)
+ phydev->drv->resume(phydev);
+
+ /* warnings */
+ if (interrupts & INTERRUPT_PHY_INIT_FAIL)
+ dev_err(&phydev->mdio.dev, "PHY initialization failed\n");
+ if (interrupts & INTERRUPT_LINK_STATUS_FAIL)
+ dev_err(&phydev->mdio.dev, "PHY link status failed\n");
+ if (interrupts & INTERRUPT_SYM_ERR)
+ dev_err(&phydev->mdio.dev, "PHY symbol error detected\n");
+ if (interrupts & INTERRUPT_SNR_WARNING)
+ dev_err(&phydev->mdio.dev, "PHY SNR warning\n");
+ if (interrupts & INTERRUPT_CONTROL_ERROR)
+ dev_err(&phydev->mdio.dev, "PHY control error\n");
+ if (interrupts & INTERRUPT_UV_ERR)
+ dev_err(&phydev->mdio.dev, "PHY undervoltage error\n");
+ if (interrupts & INTERRUPT_TEMP_ERROR)
+ dev_err(&phydev->mdio.dev, "PHY temperature error\n");
+
+ /* Notify state machine about any link changes */
+ if (interrupts & INTERRUPT_LINK_STATUS_UP ||
+ interrupts & INTERRUPT_LINK_STATUS_FAIL) {
+ mutex_lock(&phydev->lock);
+
+ /* only indicate a link change to state machine
+ * if phydev is attached to a netdevice
+ */
+ if (phydev->attached_dev)
+ phydev->state = PHY_CHANGELINK;
+
+ if (verbosity > 1)
+ dev_alert(&phydev->mdio.dev,
+ "state was %d, now going %s\n", phydev->state,
+ (interrupts & INTERRUPT_LINK_STATUS_UP) ?
+ "UP":"DOWN");
+ phydev->link =
+ (interrupts & INTERRUPT_LINK_STATUS_UP) ? 1 : 0;
+ mutex_unlock(&phydev->lock);
+ }
+ }
+
+ /* requeue poll function */
+ msleep(POLL_PAUSE); /* msleep is non-blocking */
+ queue_work(system_power_efficient_wq, &phydev->phy_queue);
+}
+
+static void setup_polling(struct phy_device *phydev)
+{
+ /*
+ * The phy_queue is normally used to schedule the interrupt handler
+ * from interrupt context after an irq has been received.
+ * Here it is repurposed as scheduling mechanism for the poll function
+ */
+ struct nxp_specific_data *priv = phydev->priv;
+
+ if (!priv->is_poll_setup) {
+ if (verbosity > 0)
+ dev_alert(&phydev->mdio.dev,
+ "initialize polling for PHY %x\n", phydev->mdio.addr);
+ cancel_work_sync(&phydev->phy_queue);
+ INIT_WORK(&phydev->phy_queue, poll);
+ priv->is_poll_setup = 1;
+ }
+}
+
+static void start_polling(struct phy_device *phydev)
+{
+ struct nxp_specific_data *priv = phydev->priv;
+
+ if (priv->is_poll_setup && !priv->is_polling) {
+ if (verbosity > 0)
+ dev_alert(&phydev->mdio.dev, "start polling PHY %x\n",
+ phydev->mdio.addr);
+ /* schedule execution of polling function */
+ queue_work(system_power_efficient_wq, &phydev->phy_queue);
+ priv->is_polling = 1;
+ }
+}
+
+static void stop_polling(struct phy_device *phydev)
+{
+ struct nxp_specific_data *priv = phydev->priv;
+
+ if (priv->is_poll_setup && priv->is_polling) {
+ if (verbosity > 0)
+ dev_alert(&phydev->mdio.dev, "stop polling PHY %x\n",
+ phydev->mdio.addr);
+ /* cancel scheduled work */
+ cancel_work_sync(&phydev->phy_queue);
+ priv->is_polling = 0;
+ }
+}
+
+/* helper function, waits until a given condition is met
+ *
+ * The function delays until the part of the register at reg_addr,
+ * defined by reg_mask equals cond, or a timeout (timeout*DELAY_LENGTH) occurs.
+ * @return 0 if condition is met, <0 if timeout or read error occurred
+ */
+static int wait_on_condition(struct phy_device *phydev, int reg_addr,
+ int reg_mask, int cond, int timeout)
+{
+ int reg_val;
+
+ if (verbosity > 3)
+ dev_alert(&phydev->mdio.dev, "waiting on condidition\n");
+
+ do {
+ udelay(DELAY_LENGTH);
+ reg_val = phy_read(phydev, reg_addr);
+ if (reg_val < 0)
+ return reg_val;
+ } while ((reg_val & reg_mask) != cond && --timeout);
+
+ if (verbosity > 3)
+ dev_alert(&phydev->mdio.dev, "%s",
+ (timeout?"condidition met\n" : "timeout occured\n"));
+
+ if (timeout)
+ return 0;
+ return -1;
+}
+
+/* helper function, enables or disables link control */
+static void set_link_control(struct phy_device *phydev, int enable_link_control)
+{
+ int err;
+
+ err = phy_configure_bit(phydev, MII_ECTRL, ECTRL_LINK_CONTROL,
+ enable_link_control);
+ if (err < 0)
+ goto phy_configure_error;
+ if (verbosity > 1)
+ dev_alert(&phydev->mdio.dev,
+ "set link ctrl to [%d] for phy %x completed\n",
+ enable_link_control, phydev->mdio.addr);
+
+ return;
+
+phy_configure_error:
+ dev_err(&phydev->mdio.dev, "phy r/w error: setting link control failed\n");
+ return;
+}
+
+/* Helper function, configures phy as master or slave
+ * @param phydev the phy to be configured
+ * @param setMaster ==0: set to slave
+ * !=0: set to master
+ * @return 0 on success, error code on failure
+ */
+static int set_master_cfg(struct phy_device *phydev, int setMaster)
+{
+ int err;
+
+ /* disable link control prior to master/slave cfg */
+ set_link_control(phydev, 0);
+
+ /* write configuration to the phy */
+ err = phy_configure_bit(phydev, MII_CFG1, CFG1_MASTER_SLAVE, setMaster);
+ if (err < 0)
+ goto phy_configure_error;
+
+ if (verbosity > 1)
+ dev_alert(&phydev->mdio.dev, "set master cfg completed\n");
+
+ /* enable link control after master/slave cfg was set */
+ set_link_control(phydev, 1);
+
+ return 0;
+
+/* error handling */
+phy_configure_error:
+ dev_err(&phydev->mdio.dev, "phy r/w error: set_master_cfg failed\n");
+ return err;
+}
+
+/* Helper function, reads master/slave configuration of phy
+ * @param phydev the phy to be read
+ *
+ * @return ==0: is slave
+ * !=0: is master
+ */
+static int get_master_cfg(struct phy_device *phydev)
+{
+ int reg_val;
+
+ if (verbosity > 1)
+ dev_alert(&phydev->mdio.dev, "getting master cfg PHY %x\n",
+ phydev->mdio.addr);
+
+ /* read the current configuration */
+ reg_val = phy_read(phydev, MII_CFG1);
+ if (reg_val < 0)
+ goto phy_read_error;
+
+ return reg_val & CFG1_MASTER_SLAVE;
+
+/* error handling */
+phy_read_error:
+ dev_err(&phydev->mdio.dev, "read error: get_master_cfg failed\n");
+ return reg_val;
+}
+
+/* retrieves the link status from COMMSTAT register */
+static int get_link_status(struct phy_device *phydev)
+{
+ int reg_val;
+
+ reg_val = phy_read(phydev, MII_COMMSTAT);
+ if (reg_val < 0)
+ goto phy_read_error;
+
+ if (verbosity > 0) {
+ if (reg_val & COMMSTAT_LOC_RCVR_STATUS)
+ dev_alert(&phydev->mdio.dev, "local receiver OK\n");
+ else
+ dev_alert(&phydev->mdio.dev, "local receiver NOT OK\n");
+ }
+
+ return reg_val & COMMSTAT_LINK_UP;
+
+/* error handling */
+phy_read_error:
+ dev_err(&phydev->mdio.dev, "read error: get_link_status failed\n");
+ return reg_val;
+}
+
+/* issues a sleep request, if in managed mode */
+static int nxp_sleep(struct phy_device *phydev)
+{
+ int err;
+
+ if (verbosity > 0)
+ dev_alert(&phydev->mdio.dev, "PHY %x going to sleep\n",
+ phydev->mdio.addr);
+
+ if (!managed_mode)
+ goto phy_auto_op_error;
+
+ /* clear power mode bits and set them to sleep request */
+ err = phy_configure_bits(phydev, MII_ECTRL, ECTRL_POWER_MODE,
+ POWER_MODE_SLEEPREQUEST);
+ if (err < 0)
+ goto phy_configure_error;
+
+ if ((phydev->phy_id & NXP_PHY_ID_MASK) == NXP_PHY_ID_TJA1102P0 ||
+ (phydev->phy_id & NXP_PHY_ID_MASK) == NXP_PHY_ID_TJA1102P1 ||
+ (phydev->phy_id & NXP_PHY_ID_MASK) == NXP_PHY_ID_TJA1101) {
+ /* tja1102 and tja1102 have an extra sleep state indicator
+ * in ECTRL.
+ * If transition is successful this can be detected immediately,
+ * without waiting for SLEEP_REQUEST_TO to pass
+ */
+ err = wait_on_condition(phydev, MII_ECTRL, ECTRL_POWER_MODE,
+ POWER_MODE_SLEEP, SLEEP_REQUEST_TO);
+ if (err < 0)
+ goto phy_transition_error;
+ } else if ((phydev->phy_id & NXP_PHY_ID_MASK) == NXP_PHY_ID_TJA1100) {
+ /* TJA1100 disables SMI when entering SLEEP
+ * The SMI bus is pulled up, that means every
+ * SMI read will return 0xffff.
+ * We can use this to check if PHY entered SLEEP.
+ */
+ err = wait_on_condition(phydev, MII_ECTRL,
+ 0xffff, 0xffff, SLEEP_REQUEST_TO);
+ if (err < 0)
+ goto phy_transition_error;
+ }
+
+ return 0;
+
+/* error handling */
+phy_auto_op_error:
+ dev_info(&phydev->mdio.dev, "phy is in auto mode: sleep not possible\n");
+ return 0;
+
+phy_configure_error:
+ dev_err(&phydev->mdio.dev, "phy r/w error: entering sleep failed\n");
+ return err;
+
+phy_transition_error:
+ dev_err(&phydev->mdio.dev, "sleep request timed out\n");
+ return err;
+}
+
+/* wakes up the phy from sleep mode */
+static int wakeup_from_sleep(struct phy_device *phydev)
+{
+ int err;
+ unsigned long wakeup_delay;
+ struct nxp_specific_data *nxp_specific = phydev->priv;
+
+ if (verbosity > 0)
+ dev_alert(&phydev->mdio.dev, "PHY %x waking up from sleep\n",
+ phydev->mdio.addr);
+
+ if (!managed_mode)
+ goto phy_auto_op_error;
+
+ /* set power mode bits to standby mode */
+ err = phy_configure_bits(phydev, MII_ECTRL, ECTRL_POWER_MODE,
+ POWER_MODE_STANDBY);
+ if (err < 0)
+ goto phy_configure_error;
+
+ /* wait until power mode transition is completed */
+ err = wait_on_condition(phydev, MII_ECTRL, ECTRL_POWER_MODE,
+ POWER_MODE_STANDBY, POWER_MODE_TIMEOUT);
+ if (err < 0)
+ goto phy_transition_error;
+
+ /* set power mode bits to normal mode */
+ err = phy_configure_bits(phydev, MII_ECTRL, ECTRL_POWER_MODE,
+ POWER_MODE_NORMAL);
+ if (err < 0)
+ goto phy_configure_error;
+
+ if (!(nxp_specific->quirks & TJA110X_REFCLK_IN)) {
+ /* wait until the PLL is locked, indicating a completed transition */
+ err = wait_on_condition(phydev, MII_GENSTAT, GENSTAT_PLL_LOCKED,
+ GENSTAT_PLL_LOCKED, POWER_MODE_TIMEOUT);
+ if (err < 0)
+ goto phy_transition_error;
+ }
+
+ /* if phy is configured as slave, also send a wakeup request
+ * to master
+ */
+ if (!((struct nxp_specific_data *)phydev->priv)->is_master) {
+ if (verbosity > 0)
+ dev_alert(&phydev->mdio.dev,
+ "Phy is slave, send wakeup request master\n");
+ /* link control must be reset for wake request */
+ set_link_control(phydev, 0);
+
+ /* start sending bus wakeup signal */
+ err = phy_configure_bit(phydev, MII_ECTRL,
+ ECTRL_WAKE_REQUEST, 1);
+ if (err < 0)
+ goto phy_configure_error;
+
+ switch (phydev->phy_id & NXP_PHY_ID_MASK) {
+ case NXP_PHY_ID_TJA1100:
+ wakeup_delay = TJA100_WAKE_REQUEST_TIMEOUT_US;
+ break;
+ case NXP_PHY_ID_TJA1102P0:
+ /* fall through */
+ case NXP_PHY_ID_TJA1101:
+ /* fall through */
+ case NXP_PHY_ID_TJA1102P1:
+ wakeup_delay = TJA102_WAKE_REQUEST_TIMEOUT_US;
+ break;
+ default:
+ goto unsupported_phy_error;
+ }
+
+ /* wait until link partner is guranteed to be awake */
+ usleep_range(wakeup_delay, wakeup_delay + 1U);
+
+ /* stop sending bus wakeup signal */
+ err = phy_configure_bit(phydev, MII_ECTRL,
+ ECTRL_WAKE_REQUEST, 0);
+ if (err < 0)
+ goto phy_configure_error;
+ }
+
+ /* reenable link control */
+ set_link_control(phydev, 1);
+
+ return 0;
+
+/* error handling */
+phy_auto_op_error:
+ dev_dbg(&phydev->mdio.dev, "phy is in auto mode: wakeup not possible\n");
+ return 0;
+
+phy_configure_error:
+ dev_err(&phydev->mdio.dev, "phy r/w error: wakeup failed\n");
+ return err;
+
+phy_transition_error:
+ dev_err(&phydev->mdio.dev, "power mode transition failed\n");
+ return err;
+
+unsupported_phy_error:
+ dev_err(&phydev->mdio.dev, "unsupported phy, wakeup failed\n");
+ return -1;
+}
+
+/* send a wakeup request to the link partner */
+static int wakeup_from_normal(struct phy_device *phydev)
+{
+ int err;
+
+ if (verbosity > 0)
+ dev_alert(&phydev->mdio.dev,
+ "PHY %x waking up from normal (send wur)\n", phydev->mdio.addr);
+
+ /* start sending bus wakeup signal */
+ err = phy_configure_bit(phydev, MII_ECTRL, ECTRL_WAKE_REQUEST, 1);
+ if (err < 0)
+ goto phy_configure_error;
+
+ /* stop sending bus wakeup signal */
+ err = phy_configure_bit(phydev, MII_ECTRL, ECTRL_WAKE_REQUEST, 0);
+ if (err < 0)
+ goto phy_configure_error;
+
+ return 0;
+
+/* error handling */
+phy_configure_error:
+ dev_err(&phydev->mdio.dev, "phy r/w error: wakeup_from_normal failed\n");
+ return err;
+}
+
+/* wake up phy if is in sleep mode, send wakeup request if in normal mode */
+static int nxp_wakeup(struct phy_device *phydev)
+{
+ int reg_val;
+ int err = 0;
+
+ reg_val = phy_read(phydev, MII_ECTRL);
+ if (reg_val < 0)
+ goto phy_read_error;
+
+ reg_val &= ECTRL_POWER_MODE;
+ switch (reg_val) {
+ case POWER_MODE_NORMAL:
+ err = wakeup_from_normal(phydev);
+ break;
+ case POWER_MODE_SLEEP:
+ err = wakeup_from_sleep(phydev);
+ break;
+ case 0xffff & ECTRL_POWER_MODE:
+ /* TJA1100 disables SMI during sleep */
+ goto phy_SMI_disabled;
+ default:
+ break;
+ }
+ if (err < 0)
+ goto phy_configure_error;
+
+ return 0;
+
+/* error handling */
+phy_read_error:
+ dev_err(&phydev->mdio.dev, "read error: nxp_wakeup failed\n");
+ return reg_val;
+
+phy_SMI_disabled:
+ dev_err(&phydev->mdio.dev, "SMI interface disabled, cannot be woken up\n");
+ return 0;
+
+phy_configure_error:
+ dev_err(&phydev->mdio.dev, "phy r/w error: wakeup_from_normal failed\n");
+ return err;
+}
+
+/* power mode transition to standby */
+static int nxp_suspend(struct phy_device *phydev)
+{
+ int err = 0;
+
+ if (verbosity > 0)
+ dev_alert(&phydev->mdio.dev, "suspending PHY %x\n", phydev->mdio.addr);
+
+ if (!managed_mode)
+ goto phy_auto_op_error;
+
+ mutex_lock(&phydev->lock);
+ /* set BMCR_PDOWN bit in MII_BMCR register */
+ err = phy_configure_bit(phydev, MII_BMCR, BMCR_PDOWN, 1);
+ if (err < 0)
+ dev_err(&phydev->mdio.dev, "phy r/w error: resume failed\n");
+ mutex_unlock(&phydev->lock);
+
+ return err;
+
+phy_auto_op_error:
+ dev_dbg(&phydev->mdio.dev, "phy is in auto mode: suspend not possible\n");
+ return 0;
+}
+
+/* power mode transition from standby to normal */
+static int nxp_resume(struct phy_device *phydev)
+{
+ int err;
+ struct nxp_specific_data *nxp_specific = phydev->priv;
+
+ if (verbosity > 0)
+ dev_alert(&phydev->mdio.dev, "resuming PHY %x\n", phydev->mdio.addr);
+
+ /* clear BMCR_PDOWN bit in MII_BMCR register */
+ err = phy_configure_bit(phydev, MII_BMCR, BMCR_PDOWN, 0);
+ if (err < 0)
+ goto phy_configure_error;
+
+ /* transit to normal mode */
+ err = phy_configure_bits(phydev, MII_ECTRL, ECTRL_POWER_MODE,
+ POWER_MODE_NORMAL);
+ if (err < 0)
+ goto phy_configure_error;
+
+ /* wait until power mode transition is completed */
+ err = wait_on_condition(phydev, MII_ECTRL, ECTRL_POWER_MODE,
+ POWER_MODE_NORMAL, POWER_MODE_TIMEOUT);
+ if (err < 0)
+ goto phy_transition_error;
+
+ if (!(nxp_specific->quirks & TJA110X_REFCLK_IN)) {
+ /* wait until the PLL is locked, indicating a completed transition */
+ err = wait_on_condition(phydev, MII_GENSTAT, GENSTAT_PLL_LOCKED,
+ GENSTAT_PLL_LOCKED, POWER_MODE_TIMEOUT);
+ if (err < 0)
+ goto phy_pll_error;
+ }
+
+ /* reenable link control */
+ set_link_control(phydev, 1);
+
+ return 0;
+
+/* error handling */
+phy_configure_error:
+ dev_err(&phydev->mdio.dev, "phy r/w error: resume failed\n");
+ return err;
+
+phy_transition_error:
+ dev_err(&phydev->mdio.dev, "power mode transition failed\n");
+ return err;
+
+phy_pll_error:
+ dev_err(&phydev->mdio.dev, "Error: PLL is unstable and not locked\n");
+ return err;
+}
+
+/* Configures the autonegotiation capabilities */
+static int nxp_config_aneg(struct phy_device *phydev)
+{
+ if (verbosity > 0)
+ dev_alert(&phydev->mdio.dev, "configuring autoneg\n");
+
+ /* disable autoneg and manually configure speed, duplex, pause frames */
+ phydev->autoneg = 0;
+
+ phydev->speed = SPEED_100;
+ phydev->duplex = DUPLEX_FULL;
+
+ phydev->pause = 0;
+ phydev->asym_pause = 0;
+
+ return 0;
+}
+
+/* helper function, enters the test mode specified by tmode
+ * @return 0 if test mode was entered, <0 on read or write error
+ */
+static int enter_test_mode(struct phy_device *phydev, enum test_mode tmode)
+{
+ int reg_val = -1;
+ int err;
+
+ if (verbosity > 1)
+ dev_alert(&phydev->mdio.dev, "phy %x entering test mode: %d\n",
+ phydev->mdio.addr, tmode);
+ switch (tmode) {
+ case NO_TMODE:
+ reg_val = ECTRL_NO_TMODE;
+ break;
+ case TMODE1:
+ reg_val = ECTRL_TMODE1;
+ break;
+ case TMODE2:
+ reg_val = ECTRL_TMODE2;
+ break;
+ case TMODE3:
+ reg_val = ECTRL_TMODE3;
+ break;
+ case TMODE4:
+ reg_val = ECTRL_TMODE4;
+ break;
+ case TMODE5:
+ reg_val = ECTRL_TMODE5;
+ break;
+ case TMODE6:
+ reg_val = ECTRL_TMODE6;
+ break;
+ default:
+ break;
+ }
+
+ if (reg_val >= 0) {
+ /* set test mode bits accordingly */
+ err = phy_configure_bits(phydev, MII_ECTRL, ECTRL_TEST_MODE,
+ reg_val);
+ if (err < 0)
+ goto phy_configure_error;
+ }
+
+ return 0;
+
+/* error handling */
+phy_configure_error:
+ dev_err(&phydev->mdio.dev, "phy r/w error: setting test mode failed\n");
+ return err;
+}
+
+/* helper function, enables or disables loopback mode
+ * @return 0 if loopback mode was configured, <0 on read or write error
+ */
+static int set_loopback(struct phy_device *phydev, int enable_loopback)
+{
+ int err;
+
+ if (verbosity > 1)
+ dev_alert(&phydev->mdio.dev, "phy %x setting loopback: %d\n",
+ phydev->mdio.addr, enable_loopback);
+ err = phy_configure_bit(phydev, MII_BMCR, BMCR_LOOPBACK,
+ enable_loopback);
+ if (err < 0)
+ goto phy_configure_error;
+
+ return 0;
+
+/* error handling */
+phy_configure_error:
+ dev_err(&phydev->mdio.dev, "phy r/w error: configuring loopback failed\n");
+ return err;
+}
+
+/* helper function, enters the loopback mode specified by lmode
+ * @return 0 if loopback mode was entered, <0 on read or write error
+ */
+static int enter_loopback_mode(struct phy_device *phydev,
+ enum loopback_mode lmode)
+{
+ int reg_val = -1;
+ int err;
+
+ /* disable link control prior to loopback cfg */
+ set_link_control(phydev, 0);
+
+ switch (lmode) {
+ case NO_LMODE:
+ if (verbosity > 1)
+ dev_alert(&phydev->mdio.dev,
+ "phy %x disabling loopback mode\n", phydev->mdio.addr);
+ /* disable loopback */
+ err = set_loopback(phydev, 0);
+ if (err < 0)
+ goto phy_set_loopback_error;
+ break;
+ case INTERNAL_LMODE:
+ reg_val = ECTRL_INTERNAL_LMODE;
+ break;
+ case EXTERNAL_LMODE:
+ reg_val = ECTRL_EXTERNAL_LMODE;
+ break;
+ case REMOTE_LMODE:
+ reg_val = ECTRL_REMOTE_LMODE;
+ break;
+ default:
+ break;
+ }
+
+ if (reg_val >= 0) {
+ if (verbosity > 1)
+ dev_alert(&phydev->mdio.dev, "setting loopback mode %d\n",
+ lmode);
+ err = phy_configure_bits(phydev, MII_ECTRL,
+ ECTRL_LOOPBACK_MODE, reg_val);
+ if (err < 0)
+ goto phy_configure_error;
+
+ /* enable loopback */
+ err = set_loopback(phydev, 1);
+ if (err < 0)
+ goto phy_set_loopback_error;
+ }
+
+ /* enable link control after loopback cfg was set */
+ set_link_control(phydev, 1);
+
+ return 0;
+
+/* error handling */
+phy_set_loopback_error:
+ dev_err(&phydev->mdio.dev, "error: enable/disable loopback failed\n");
+ return err;
+
+phy_configure_error:
+ dev_err(&phydev->mdio.dev, "phy r/w error: setting loopback mode failed\n");
+ return err;
+}
+
+/* helper function, enters the led mode specified by lmode
+ * @return 0 if led mode was entered, <0 on read or write error
+ */
+static int enter_led_mode(struct phy_device *phydev, enum led_mode lmode)
+{
+ int reg_val = -1;
+ int err;
+
+ switch (lmode) {
+ case NO_LED_MODE:
+ /* disable led */
+ err = phy_configure_bit(phydev, MII_CFG1,
+ TJA1100_CFG1_LED_EN, 0);
+ if (err < 0)
+ goto phy_configure_error;
+ break;
+ case LINKUP_LED_MODE:
+ reg_val = CFG1_LED_LINKUP;
+ break;
+ case FRAMEREC_LED_MODE:
+ reg_val = CFG1_LED_FRAMEREC;
+ break;
+ case SYMERR_LED_MODE:
+ reg_val = CFG1_LED_SYMERR;
+ break;
+ case CRSSIG_LED_MODE:
+ reg_val = CFG1_LED_CRSSIG;
+ break;
+ default:
+ break;
+ }
+
+ if (reg_val >= 0) {
+ err = phy_configure_bits(phydev, MII_CFG1,
+ TJA1100_CFG1_LED_MODE, reg_val);
+ if (err < 0)
+ goto phy_configure_error;
+
+ /* enable led */
+ err = phy_configure_bit(phydev, MII_CFG1,
+ TJA1100_CFG1_LED_EN, 1);
+ if (err < 0)
+ goto phy_configure_error;
+ }
+
+ return 0;
+
+/* error handling */
+phy_configure_error:
+ dev_err(&phydev->mdio.dev, "phy r/w error: setting led mode failed\n");
+ return err;
+}
+
+/* This function handles read accesses to the node 'master_cfg' in
+ * sysfs.
+ * Depending on current configuration of the phy, the node reads
+ * 'master' or 'slave'
+ */
+static ssize_t sysfs_get_master_cfg(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int is_master;
+ struct phy_device *phydev = to_phy_device(dev);
+
+ is_master = get_master_cfg(phydev);
+
+ /* write result into the buffer */
+ return scnprintf(buf, PAGE_SIZE, "%s\n",
+ is_master ? "master" : "slave");
+}
+
+/* This function handles write accesses to the node 'master_cfg' in sysfs.
+ * Depending on the value written to it, the phy is configured as
+ * master or slave
+ */
+static ssize_t sysfs_set_master_cfg(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int err;
+ int setMaster;
+ struct phy_device *phydev = to_phy_device(dev);
+
+ if (verbosity > 1)
+ dev_alert(&phydev->mdio.dev, "setting master cfg PHY %x\n",
+ phydev->mdio.addr);
+
+ /* parse the buffer */
+ err = kstrtoint(buf, 10, &setMaster);
+ if (err < 0)
+ goto phy_parse_error;
+
+ /* write configuration to the phy */
+ err = set_master_cfg(phydev, setMaster);
+ if (err < 0)
+ goto phy_cfg_error;
+
+ /* update phydev */
+ ((struct nxp_specific_data *)phydev->priv)->is_master = setMaster;
+
+ return count;
+
+/* error handling */
+phy_parse_error:
+ dev_err(&phydev->mdio.dev, "parse error: sysfs_set_master_cfg failed\n");
+ return err;
+
+phy_cfg_error:
+ dev_err(&phydev->mdio.dev, "phy cfg error: sysfs_set_master_cfg failed\n");
+ return err;
+}
+
+/* This function handles read accesses to the node 'power_cfg' in sysfs.
+ * Reading the node returns the current power state
+ */
+static ssize_t sysfs_get_power_cfg(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int reg_val;
+ char *pmode;
+ struct phy_device *phydev = to_phy_device(dev);
+
+ if (verbosity > 1)
+ dev_alert(&phydev->mdio.dev, "getting power cfg\n");
+
+ reg_val = phy_read(phydev, MII_ECTRL);
+ if (reg_val < 0)
+ goto phy_read_error;
+
+ /* mask power mode bits */
+ reg_val &= ECTRL_POWER_MODE;
+
+ switch (reg_val) {
+ case POWER_MODE_NORMAL:
+ pmode = "POWER_MODE_NORMAL\n";
+ break;
+ case POWER_MODE_SLEEPREQUEST:
+ pmode = "POWER_MODE_SLEEPREQUEST\n";
+ break;
+ case POWER_MODE_SLEEP:
+ pmode = "POWER_MODE_SLEEP\n";
+ break;
+ case POWER_MODE_SILENT:
+ pmode = "POWER_MODE_SILENT\n";
+ break;
+ case POWER_MODE_STANDBY:
+ pmode = "POWER_MODE_STANDBY\n";
+ break;
+ case POWER_MODE_NOCHANGE:
+ pmode = "POWER_MODE_NOCHANGE\n";
+ break;
+ default:
+ if (verbosity > 1)
+ dev_alert(&phydev->mdio.dev,
+ "unknown reg val is [%08x]\n", reg_val);
+ pmode = "unknown\n";
+ }
+
+ /* write result into the buffer */
+ return scnprintf(buf, PAGE_SIZE, pmode);
+
+/* error handling */
+phy_read_error:
+ dev_err(&phydev->mdio.dev, "read error: sysfs_get_power_cfg failed\n");
+ return reg_val;
+}
+
+/* This function handles write accesses to the node 'power_cfg' in
+ * sysfs.
+ * Depending on the value written to it, the phy enters a certain
+ * power state.
+ */
+static ssize_t sysfs_set_power_cfg(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int err;
+ int pmode;
+ struct phy_device *phydev = to_phy_device(dev);
+
+ /* parse the buffer */
+ err = kstrtoint(buf, 10, &pmode);
+ if (err < 0)
+ goto phy_parse_error;
+
+ if (verbosity > 1)
+ dev_alert(&phydev->mdio.dev, "set pmode to %d\n", pmode);
+
+ switch (pmode) {
+ case 0:
+ err = phydev->drv->suspend(phydev);
+ break;
+ case 1:
+ err = phydev->drv->resume(phydev);
+ break;
+ case 2:
+ err = nxp_sleep(phydev);
+ break;
+ case 3:
+ err = nxp_wakeup(phydev);
+ break;
+ default:
+ break;
+ }
+
+ if (err)
+ goto phy_pmode_transit_error;
+
+ return count;
+
+/* error handling */
+phy_parse_error:
+ dev_err(&phydev->mdio.dev, "parse error: sysfs_set_power_cfg failed\n");
+ return err;
+
+phy_pmode_transit_error:
+ dev_err(&phydev->mdio.dev, "pmode error: sysfs_set_power_cfg failed\n");
+ return err;
+}
+
+/* This function handles read accesses to the node 'loopback_cfg' in sysfs
+ * Reading the node returns the current loopback configuration
+ */
+static ssize_t sysfs_get_loopback_cfg(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int reg_val;
+ char *lmode;
+ struct phy_device *phydev = to_phy_device(dev);
+
+ if (verbosity > 1)
+ dev_alert(&phydev->mdio.dev, "getting loopback cfg\n");
+
+ reg_val = phy_read(phydev, MII_BMCR);
+ if (reg_val < 0)
+ goto phy_read_error;
+
+ if (reg_val & BMCR_LOOPBACK) {
+ /* loopback enabled */
+ reg_val = phy_read(phydev, MII_ECTRL);
+ if (reg_val < 0)
+ goto phy_read_error;
+
+ /* mask loopback mode bits */
+ reg_val &= ECTRL_LOOPBACK_MODE;
+
+ switch (reg_val) {
+ case ECTRL_INTERNAL_LMODE:
+ lmode = "INTERNAL_LOOPBACK\n";
+ break;
+ case ECTRL_EXTERNAL_LMODE:
+ lmode = "EXTERNAL_LOOPBACK\n";
+ break;
+ case ECTRL_REMOTE_LMODE:
+ lmode = "REMOTE_LOOPBACK\n";
+ break;
+ default:
+ lmode = "unknown\n";
+ if (verbosity > 1)
+ dev_alert(&phydev->mdio.dev,
+ "unknown reg val is [%08x]\n", reg_val);
+ }
+ } else {
+ /* loopback disabled */
+ lmode = "LOOPBACK_DISABLED\n";
+ }
+
+ /* write result into the buffer */
+ return scnprintf(buf, PAGE_SIZE, lmode);
+
+/* error handling */
+phy_read_error:
+ dev_err(&phydev->mdio.dev, "read error: sysfs_get_loopback_cfg failed\n");
+ return reg_val;
+}
+
+/* This function handles write accesses to the node 'loopback_cfg'
+ * in sysfs.
+ * Depending on the value written to it, the phy enters a certain
+ * loopback state.
+ */
+static ssize_t sysfs_set_loopback_cfg(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int err;
+ int lmode;
+ struct phy_device *phydev = to_phy_device(dev);
+
+ if (!managed_mode)
+ goto phy_auto_op_error;
+
+ if (verbosity > 1)
+ dev_alert(&phydev->mdio.dev, "setting loopback cfg PHY %x\n",
+ phydev->mdio.addr);
+
+ /* parse the buffer */
+ err = kstrtoint(buf, 10, &lmode);
+ if (err < 0)
+ goto phy_parse_error;
+
+ switch (lmode) {
+ case 0:
+ err = enter_loopback_mode(phydev, NO_LMODE);
+ if (!no_poll)
+ start_polling(phydev);
+ break;
+ case 1:
+ if (!no_poll)
+ stop_polling(phydev);
+ err = enter_loopback_mode(phydev, INTERNAL_LMODE);
+ break;
+ case 2:
+ if (!no_poll)
+ stop_polling(phydev);
+ err = enter_loopback_mode(phydev, EXTERNAL_LMODE);
+ break;
+ case 3:
+ if (!no_poll)
+ stop_polling(phydev);
+ err = enter_loopback_mode(phydev, REMOTE_LMODE);
+ break;
+ default:
+ break;
+ }
+
+ if (err)
+ goto phy_lmode_transit_error;
+
+ return count;
+
+/* error handling */
+phy_auto_op_error:
+ dev_info(&phydev->mdio.dev, "phy is in auto mode: loopback not available\n");
+ return count;
+
+phy_parse_error:
+ dev_err(&phydev->mdio.dev, "parse error: sysfs_set_loopback_cfg failed\n");
+ return err;
+
+phy_lmode_transit_error:
+ dev_err(&phydev->mdio.dev, "lmode error: sysfs_set_loopback_cfg failed\n");
+ return err;
+}
+
+/* This function handles read accesses to the node 'cable_test' in sysfs
+ * Reading the node executes a cable test and returns the result
+ */
+static ssize_t sysfs_get_cable_test(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int reg_val;
+ int err;
+ char *c_test_result;
+ struct phy_device *phydev = to_phy_device(dev);
+
+ if (!managed_mode)
+ goto phy_auto_op_error;
+
+ if (verbosity > 1)
+ dev_alert(&phydev->mdio.dev, "phy %x executing cable test\n",
+ phydev->mdio.addr);
+
+ /* disable link control prior to cable test */
+ set_link_control(phydev, 0);
+
+ /* execute a cable test */
+ err = phy_configure_bit(phydev, MII_ECTRL, ECTRL_CABLE_TEST, 1);
+ if (err < 0)
+ goto phy_configure_error;
+
+ /* wait until test is completed */
+ err = wait_on_condition(phydev, MII_ECTRL, ECTRL_CABLE_TEST,
+ 0, CABLE_TEST_TIMEOUT);
+ if (err < 0)
+ goto phy_transition_error;
+
+ /* evaluate the test results */
+ reg_val = phy_read(phydev, MII_EXTERNAL_STATUS);
+ if (reg_val < 0)
+ goto phy_read_error;
+
+ if (reg_val & EXTSTAT_SHORT_DETECT)
+ c_test_result = "SHORT_DETECT\n";
+ else if (reg_val & EXTSTAT_OPEN_DETECT)
+ c_test_result = "OPEN_DETECT\n";
+ else
+ c_test_result = "NO_ERROR\n";
+
+ /* reenable link control after cable test */
+ set_link_control(phydev, 1);
+
+ /* write result into the buffer */
+ return scnprintf(buf, PAGE_SIZE, c_test_result);
+
+/* error handling */
+phy_auto_op_error:
+ dev_info(&phydev->mdio.dev, "phy is in auto mode: cabletest not available\n");
+ return 0;
+
+phy_read_error:
+ dev_err(&phydev->mdio.dev, "read error: sysfs_get_cable_test failed\n");
+ return reg_val;
+
+phy_configure_error:
+ dev_err(&phydev->mdio.dev, "phy r/w error: sysfs_get_cable_test failed\n");
+ return err;
+
+phy_transition_error:
+ dev_err(&phydev->mdio.dev, "Timeout: cable test failed to finish in time\n");
+ return err;
+}
+
+/* This function handles read accesses to the node 'test_mode' in sysfs
+ * Reading the node returns the current test mode configuration
+ */
+static ssize_t sysfs_get_test_mode(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int reg_val;
+ char *tmode;
+ struct phy_device *phydev = to_phy_device(dev);
+
+ reg_val = phy_read(phydev, MII_ECTRL);
+ if (reg_val < 0)
+ goto phy_read_error;
+
+ /* mask test mode bits */
+ reg_val &= ECTRL_TEST_MODE;
+
+ switch (reg_val) {
+ case ECTRL_NO_TMODE:
+ tmode = "NO_TMODE\n";
+ break;
+ case ECTRL_TMODE1:
+ tmode = "TMODE1\n";
+ break;
+ case ECTRL_TMODE2:
+ tmode = "TMODE2\n";
+ break;
+ case ECTRL_TMODE3:
+ tmode = "TMODE3\n";
+ break;
+ case ECTRL_TMODE4:
+ tmode = "TMODE4\n";
+ break;
+ case ECTRL_TMODE5:
+ tmode = "TMODE5\n";
+ break;
+ case ECTRL_TMODE6:
+ tmode = "TMODE6\n";
+ break;
+ default:
+ tmode = "unknown\n";
+ if (verbosity > 1)
+ dev_alert(&phydev->mdio.dev,
+ "unknown reg val is [%08x]\n", reg_val);
+ }
+
+ /* write result into the buffer */
+ return scnprintf(buf, PAGE_SIZE, tmode);
+
+/* error handling */
+phy_read_error:
+ dev_err(&phydev->mdio.dev, "read error: sysfs_get_test_mode failed\n");
+ return reg_val;
+}
+
+/* This function handles write accesses to the node 'test_mode' in sysfs
+ * Depending on the value written to it, the phy enters a certain test mode
+ */
+static ssize_t sysfs_set_test_mode(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int err;
+ int tmode;
+ struct phy_device *phydev = to_phy_device(dev);
+
+ if (!managed_mode)
+ goto phy_auto_op_error;
+
+ /* parse the buffer */
+ err = kstrtoint(buf, 10, &tmode);
+ if (err < 0)
+ goto phy_parse_error;
+
+ switch (tmode) {
+ case 0:
+ err = enter_test_mode(phydev, NO_TMODE);
+ /* enable link control after exiting test */
+ set_link_control(phydev, 1);
+ break;
+ case 1:
+ /* disbale link control before entering test */
+ set_link_control(phydev, 0);
+ err = enter_test_mode(phydev, TMODE1);
+ break;
+ case 2:
+ /* disbale link control before entering test */
+ set_link_control(phydev, 0);
+ err = enter_test_mode(phydev, TMODE2);
+ break;
+ case 3:
+ /* disbale link control before entering test */
+ set_link_control(phydev, 0);
+ err = enter_test_mode(phydev, TMODE3);
+ break;
+ case 4:
+ /* disbale link control before entering test */
+ set_link_control(phydev, 0);
+ err = enter_test_mode(phydev, TMODE4);
+ break;
+ case 5:
+ /* disbale link control before entering test */
+ set_link_control(phydev, 0);
+ err = enter_test_mode(phydev, TMODE5);
+ break;
+ case 6:
+ /* disbale link control before entering test */
+ set_link_control(phydev, 0);
+ err = enter_test_mode(phydev, TMODE6);
+ break;
+ default:
+ break;
+ }
+
+ if (err)
+ goto phy_tmode_transit_error;
+
+ return count;
+
+/* error handling */
+phy_auto_op_error:
+ dev_info(&phydev->mdio.dev, "phy is in auto mode: testmodes not available\n");
+ return count;
+
+phy_parse_error:
+ dev_err(&phydev->mdio.dev, "parse error: sysfs_get_test_mode failed\n");
+ return err;
+
+phy_tmode_transit_error:
+ dev_err(&phydev->mdio.dev, "tmode error: sysfs_get_test_mode failed\n");
+ return err;
+}
+
+/* This function handles read accesses to the node 'led_cfg' in sysfs.
+ * Reading the node returns the current led configuration
+ */
+static ssize_t sysfs_get_led_cfg(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int reg_val;
+ char *lmode;
+ struct phy_device *phydev = to_phy_device(dev);
+
+ lmode = "DISABLED\n";
+
+ /* only TJA1100 has leds */
+ if ((phydev->phy_id & NXP_PHY_ID_MASK) == NXP_PHY_ID_TJA1100) {
+ reg_val = phy_read(phydev, MII_CFG1);
+ if (reg_val < 0)
+ goto phy_read_error;
+
+ if (reg_val & TJA1100_CFG1_LED_EN) {
+ /* mask led mode bits */
+ reg_val &= TJA1100_CFG1_LED_MODE;
+
+ switch (reg_val) {
+ case CFG1_LED_LINKUP:
+ lmode = "LINKUP\n";
+ break;
+ case CFG1_LED_FRAMEREC:
+ lmode = "FRAMEREC\n";
+ break;
+ case CFG1_LED_SYMERR:
+ lmode = "SYMERR\n";
+ break;
+ case CFG1_LED_CRSSIG:
+ lmode = "CRSSIG\n";
+ break;
+ default:
+ lmode = "unknown\n";
+ if (verbosity > 1)
+ dev_alert(&phydev->mdio.dev,
+ "unknown reg val is [%08x]\n", reg_val);
+ }
+ }
+ }
+
+ /* write result into the buffer */
+ return scnprintf(buf, PAGE_SIZE, lmode);
+
+/* error handling */
+phy_read_error:
+ dev_err(&phydev->mdio.dev, "read error: sysfs_get_led_cfg failed\n");
+ return reg_val;
+}
+
+/* This function handles write accesses to the node 'led_cfg' in sysfs
+ * Depending on the value written to it, the led mode is configured
+ * accordingly.
+ */
+static ssize_t sysfs_set_led_cfg(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int err;
+ int lmode;
+ struct phy_device *phydev = to_phy_device(dev);
+
+ if ((phydev->phy_id & NXP_PHY_ID_MASK) != NXP_PHY_ID_TJA1100)
+ goto no_led_error;
+
+ /* parse the buffer */
+ err = kstrtoint(buf, 10, &lmode);
+ if (err < 0)
+ goto phy_parse_error;
+
+ switch (lmode) {
+ case 0:
+ err = enter_led_mode(phydev, NO_LED_MODE);
+ break;
+ case 1:
+ err = enter_led_mode(phydev, LINKUP_LED_MODE);
+ break;
+ case 2:
+ err = enter_led_mode(phydev, FRAMEREC_LED_MODE);
+ break;
+ case 3:
+ err = enter_led_mode(phydev, SYMERR_LED_MODE);
+ break;
+ case 4:
+ err = enter_led_mode(phydev, CRSSIG_LED_MODE);
+ break;
+ default:
+ break;
+ }
+
+ if (err)
+ goto phy_lmode_transit_error;
+
+ return count;
+
+/* error handling */
+phy_parse_error:
+ dev_err(&phydev->mdio.dev, "parse error: sysfs_set_led_cfg failed\n");
+ return err;
+
+phy_lmode_transit_error:
+ dev_err(&phydev->mdio.dev, "lmode error: sysfs_set_led_cfg failed\n");
+ return err;
+
+no_led_error:
+ dev_info(&phydev->mdio.dev, "phy has no led support\n");
+ return count;
+}
+
+/* This function handles read accesses to the node 'link_status' in sysfs
+ * Depending on current link status of the phy, the node reads
+ * 'up' or 'down'
+ */
+static ssize_t sysfs_get_link_status(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int linkup;
+ struct phy_device *phydev = to_phy_device(dev);
+
+ linkup = get_link_status(phydev);
+
+ /* write result into the buffer */
+ return scnprintf(buf, PAGE_SIZE, "%s\n", linkup ? "up" : "down");
+}
+
+/* This function handles read accesses to the node 'wakeup_cfg' in sysfs
+ * Reading the node returns the current status of the bits
+ * FWDPHYLOC, REMWUPHY, LOCWUPHY, FWDPHYREM
+ */
+static ssize_t sysfs_get_wakeup_cfg(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int reg_val;
+ int fwdphyloc_en, remwuphy_en, locwuphy_en, fwdphyrem_en;
+ struct phy_device *phydev = to_phy_device(dev);
+
+ if ((phydev->phy_id & NXP_PHY_ID_MASK) == NXP_PHY_ID_TJA1102P0 ||
+ (phydev->phy_id & NXP_PHY_ID_MASK) == NXP_PHY_ID_TJA1102P1 ||
+ (phydev->phy_id & NXP_PHY_ID_MASK) == NXP_PHY_ID_TJA1101) {
+ reg_val = phy_read(phydev, MII_CFG1);
+ if (reg_val < 0)
+ goto phy_read_error;
+
+ fwdphyloc_en = 0;
+ remwuphy_en = 0;
+ locwuphy_en = 0;
+ fwdphyrem_en = 0;
+
+ if (reg_val & TJA1102_CFG1_FWDPHYLOC)
+ fwdphyloc_en = 1;
+ if (reg_val & CFG1_REMWUPHY)
+ remwuphy_en = 1;
+ if (reg_val & CFG1_LOCWUPHY)
+ locwuphy_en = 1;
+ if (reg_val & CFG1_FWDPHYREM)
+ fwdphyrem_en = 1;
+ } else if ((phydev->phy_id & NXP_PHY_ID_MASK) == NXP_PHY_ID_TJA1100) {
+ remwuphy_en = 1; /* not configurable, always enabled */
+ fwdphyloc_en = 0; /* not supported */
+
+ /* The status LED and WAKE input share a pin, so ultimately
+ * configuration depends on the hardware setup.
+ * If LED is disabled, we assume the pin is used for WAKE.
+ * In this case, the phy wakes up upon local wakeup event
+ * via the WAKE pin and also forwards it.
+ */
+ reg_val = phy_read(phydev, MII_CFG1);
+ if (reg_val < 0)
+ goto phy_read_error;
+
+ if (reg_val & TJA1100_CFG1_LED_EN) {
+ locwuphy_en = 0;
+ fwdphyrem_en = 0;
+ } else {
+ locwuphy_en = 1;
+ fwdphyrem_en = 1;
+ }
+ } else {
+ goto unsupported_phy_error;
+ }
+
+ /* write result into the buffer */
+ return scnprintf(buf, PAGE_SIZE,
+ "fwdphyloc[%s], remwuphy[%s], locwuphy[%s], fwdphyrem[%s]\n",
+ (fwdphyloc_en ? "on" : "off"),
+ (remwuphy_en ? "on" : "off"),
+ (locwuphy_en ? "on" : "off"),
+ (fwdphyrem_en ? "on" : "off"));
+
+/* error handling */
+phy_read_error:
+ dev_err(&phydev->mdio.dev, "read error: sysfs_get_wakeup_cfg failed\n");
+ return reg_val;
+
+unsupported_phy_error:
+ dev_err(&phydev->mdio.dev, "unsupported phy, sysfs_get_wakeup_cfg failed\n");
+ return -1;
+}
+
+/* This function handles write accesses to the node 'wakeup_cfg' in sysfs
+ * Depending on the hexadecimal value written, the bits
+ * FWDPHYLOC, REMWUPHY, LOCWUPHY, FWDPHYREM are configured
+ */
+static ssize_t sysfs_set_wakeup_cfg(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int err, reg_val, reg_mask, wakeup_cfg;
+ struct phy_device *phydev = to_phy_device(dev);
+
+ /* parse the buffer */
+ err = kstrtoint(buf, 16, &wakeup_cfg);
+ if (err < 0)
+ goto phy_parse_error;
+
+ if ((phydev->phy_id & NXP_PHY_ID_MASK) == NXP_PHY_ID_TJA1102P0 ||
+ (phydev->phy_id & NXP_PHY_ID_MASK) == NXP_PHY_ID_TJA1102P1 ||
+ (phydev->phy_id & NXP_PHY_ID_MASK) == NXP_PHY_ID_TJA1101) {
+ reg_val = 0;
+
+ /* the first 4 bits of the supplied hexadecimal value
+ * are interpreted as the wakeup configuration
+ */
+ if (wakeup_cfg & SYSFS_FWDPHYLOC)
+ reg_val |= TJA1102_CFG1_FWDPHYLOC;
+ if (wakeup_cfg & SYSFS_REMWUPHY)
+ reg_val |= CFG1_REMWUPHY;
+ if (wakeup_cfg & SYSFS_LOCWUPHY)
+ reg_val |= CFG1_LOCWUPHY;
+ if (wakeup_cfg & SYSFS_FWDPHYREM)
+ reg_val |= CFG1_FWDPHYREM;
+
+ reg_mask = (TJA1102_CFG1_FWDPHYLOC | CFG1_REMWUPHY |
+ CFG1_LOCWUPHY | CFG1_FWDPHYREM);
+
+ err = phy_configure_bits(phydev, MII_CFG1, reg_mask, reg_val);
+ if (err < 0)
+ goto phy_configure_error;
+ } else if ((phydev->phy_id & NXP_PHY_ID_MASK) == NXP_PHY_ID_TJA1100) {
+ /* FWDPHYLOC MUST be off
+ * REMWUPHY MUST be on
+ * only LOCWUPHY and FWDPHYREM are configurable
+ * Possible configurations:
+ * - BOTH enabled (then led MUST be off)
+ * - BOTH disabled (then led CAN be on)
+ * all other configurations are invalid.
+ *
+ * Therefore valid values to write to sysfs are:
+ * - 2 (LOCWUPHY and FWDPHYREM off)
+ * - E (LOCWUPHY and FWDPHYREM on)
+ */
+ if (((wakeup_cfg & SYSFS_LOCWUPHY) !=
+ (wakeup_cfg & SYSFS_FWDPHYREM)) ||
+ wakeup_cfg & SYSFS_FWDPHYLOC ||
+ !(wakeup_cfg & SYSFS_REMWUPHY)) {
+ dev_alert(&phydev->mdio.dev, "Invalid configuration\n");
+ } else if (wakeup_cfg & SYSFS_LOCWUPHY &&
+ wakeup_cfg & SYSFS_FWDPHYREM) {
+ err = enter_led_mode(phydev, NO_LED_MODE);
+ if (err)
+ goto phy_lmode_transit_error;
+ }
+ }
+
+ return count;
+
+/* error handling */
+phy_parse_error:
+ dev_err(&phydev->mdio.dev, "parse error: sysfs_set_wakeup_cfg failed\n");
+ return err;
+
+phy_configure_error:
+ dev_err(&phydev->mdio.dev, "phy r/w error: sysfs_set_wakeup_cfg failed\n");
+ return err;
+
+phy_lmode_transit_error:
+ dev_err(&phydev->mdio.dev, "lmode error: sysfs_set_wakeup_cfg failed\n");
+ return err;
+}
+
+/* This function handles read accesses to the node 'snr_wlimit_cfg' in sysfs.
+ * Reading the node returns the current snr warning limit.
+ */
+static ssize_t sysfs_get_snr_wlimit_cfg(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ int reg_val;
+ char *snr_limit;
+ struct phy_device *phydev = to_phy_device(dev);
+
+ reg_val = phy_read(phydev, MII_CFG2);
+ if (reg_val < 0)
+ goto phy_read_error;
+
+ /* mask snr wlimit bits */
+ reg_val &= CFG2_SNR_WLIMIT;
+
+ switch (reg_val) {
+ case SNR_CLASS_NONE:
+ snr_limit = "no fail limit\n";
+ break;
+ case SNR_CLASS_A:
+ snr_limit = "CLASS_A\n";
+ break;
+ case SNR_CLASS_B:
+ snr_limit = "CLASS_B\n";
+ break;
+ case SNR_CLASS_C:
+ snr_limit = "CLASS_C\n";
+ break;
+ case SNR_CLASS_D:
+ snr_limit = "CLASS_D\n";
+ break;
+ case SNR_CLASS_E:
+ snr_limit = "CLASS_E\n";
+ break;
+ case SNR_CLASS_F:
+ snr_limit = "CLASS_F\n";
+ break;
+ case SNR_CLASS_G:
+ snr_limit = "CLASS_G\n";
+ break;
+ default:
+ snr_limit = "unknown\n";
+ }
+
+ /* write result into the buffer */
+ return scnprintf(buf, PAGE_SIZE, snr_limit);
+
+/* error handling */
+phy_read_error:
+ dev_err(&phydev->mdio.dev, "read error: sysfs_get_snr_wlimit_cfg failed\n");
+ return reg_val;
+}
+
+/* This function handles write accesses to the node 'snr_wlimit_cfg' in sysfs
+ * Depending on the value written to it, the snr warning limit is configured
+ * accordingly.
+ */
+static ssize_t sysfs_set_snr_wlimit_cfg(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int err, snr_limit, reg_val;
+ struct phy_device *phydev = to_phy_device(dev);
+
+ /* parse the buffer */
+ err = kstrtoint(buf, 10, &snr_limit);
+ if (err < 0)
+ goto phy_parse_error;
+
+ switch (snr_limit) {
+ case 0:
+ reg_val = SNR_CLASS_NONE;
+ break;
+ case 1:
+ reg_val = SNR_CLASS_A;
+ break;
+ case 2:
+ reg_val = SNR_CLASS_B;
+ break;
+ case 3:
+ reg_val = SNR_CLASS_C;
+ break;
+ case 4:
+ reg_val = SNR_CLASS_D;
+ break;
+ case 5:
+ reg_val = SNR_CLASS_E;
+ break;
+ case 6:
+ reg_val = SNR_CLASS_F;
+ break;
+ case 7:
+ reg_val = SNR_CLASS_G;
+ break;
+ default:
+ reg_val = -1;
+ break;
+ }
+
+ if (reg_val != -1) {
+ err = phy_configure_bits(phydev, MII_CFG2,
+ CFG2_SNR_WLIMIT, reg_val);
+ if (err)
+ goto phy_configure_error;
+ }
+
+ return count;
+
+/* error handling */
+phy_parse_error:
+ dev_err(&phydev->mdio.dev, "parse error: sysfs_set_snr_wlimit_cfg failed\n");
+ return err;
+
+phy_configure_error:
+ dev_err(&phydev->mdio.dev,
+ "phy r/w error: sysfs_set_snr_wlimit_cfg failed\n");
+ return err;
+}
+
+/* r/w access for everyone */
+static DEVICE_ATTR(master_cfg, S_IWUSR | S_IRUSR,
+ sysfs_get_master_cfg, sysfs_set_master_cfg);
+static DEVICE_ATTR(power_cfg, S_IWUSR | S_IRUSR,
+ sysfs_get_power_cfg, sysfs_set_power_cfg);
+static DEVICE_ATTR(loopback_cfg, S_IWUSR | S_IRUSR,
+ sysfs_get_loopback_cfg, sysfs_set_loopback_cfg);
+static DEVICE_ATTR(cable_test, S_IRUSR, sysfs_get_cable_test, NULL);
+static DEVICE_ATTR(test_mode, S_IWUSR | S_IRUSR,
+ sysfs_get_test_mode, sysfs_set_test_mode);
+static DEVICE_ATTR(led_cfg, S_IWUSR | S_IRUSR,
+ sysfs_get_led_cfg, sysfs_set_led_cfg);
+static DEVICE_ATTR(link_status, S_IRUSR, sysfs_get_link_status, NULL);
+static DEVICE_ATTR(wakeup_cfg, S_IWUSR | S_IRUSR,
+ sysfs_get_wakeup_cfg, sysfs_set_wakeup_cfg);
+static DEVICE_ATTR(snr_wlimit_cfg, S_IWUSR | S_IRUSR,
+ sysfs_get_snr_wlimit_cfg, sysfs_set_snr_wlimit_cfg);
+
+static struct attribute *nxp_sysfs_entries[] = {
+ &dev_attr_master_cfg.attr,
+ &dev_attr_power_cfg.attr,
+ &dev_attr_loopback_cfg.attr,
+ &dev_attr_cable_test.attr,
+ &dev_attr_test_mode.attr,
+ &dev_attr_led_cfg.attr,
+ &dev_attr_link_status.attr,
+ &dev_attr_wakeup_cfg.attr,
+ &dev_attr_snr_wlimit_cfg.attr,
+ NULL
+};
+
+static struct attribute_group nxp_attribute_group = {
+ .name = "configuration",
+ .attrs = nxp_sysfs_entries,
+};
+
+/* helper function, configures a register of phydev
+ *
+ * The function sets the bit of register reg_name,
+ * defined by bit_mask to 0 if (bit_value == 0), else to 1
+ * @return 0 if configuration completed, <0 if read/write
+ * error occurred
+ */
+static inline int phy_configure_bit(struct phy_device *phydev, int reg_name,
+ int bit_mask, int bit_value)
+{
+ int reg_val, err;
+
+ if (verbosity > 2)
+ dev_alert(&phydev->mdio.dev, "%s bit on mask [%08x] of reg [%d] of phy %x\n", (bit_value?"enabling":"disabling"),
+ bit_mask, reg_name, phydev->mdio.addr);
+
+ reg_val = phy_read(phydev, reg_name);
+ if (reg_val < 0)
+ goto phy_read_error;
+
+ if (bit_value)
+ reg_val |= bit_mask;
+ else
+ reg_val &= ~bit_mask;
+
+ err = phy_write(phydev, reg_name, reg_val);
+ if (err < 0)
+ goto phy_write_error;
+
+ return 0;
+
+/* error handling */
+phy_read_error:
+ dev_err(&phydev->mdio.dev, "read error: phy config failed\n");
+ return reg_val;
+
+phy_write_error:
+ dev_err(&phydev->mdio.dev, "write error: phy config failed\n");
+ return err;
+}
+
+/* helper function, configures a register of phydev
+ *
+ * The function sets the bits of register reg_name,
+ * defined by bit_mask to bit_value
+ * @return 0 if configuration completed, <0 if read/write
+ * error occurred
+ */
+static inline int phy_configure_bits(struct phy_device *phydev, int reg_name,
+ int bit_mask, int bit_value)
+{
+ int reg_val, err;
+
+ if (verbosity > 2)
+ dev_alert(&phydev->mdio.dev, "set mask [%08x] of reg [%d] of phy %x to value [%08x]\n",
+ bit_mask, reg_name, phydev->mdio.addr, bit_value);
+
+ reg_val = phy_read(phydev, reg_name);
+ if (reg_val < 0)
+ goto phy_read_error;
+
+ reg_val &= ~bit_mask;
+ reg_val |= bit_value;
+
+ err = phy_write(phydev, reg_name, reg_val);
+ if (err < 0)
+ goto phy_write_error;
+
+ return 0;
+
+/* error handling */
+phy_read_error:
+ dev_err(&phydev->mdio.dev, "read error: phy config failed\n");
+ return reg_val;
+
+phy_write_error:
+ dev_err(&phydev->mdio.dev, "write error: phy config failed\n");
+ return err;
+}
+
+#ifdef NETDEV_NOTIFICATION_FIX
+static struct class *bus_class_from_net_device(struct net_device *net_device,
+ const char *required_name)
+{
+ struct class *bus_class;
+
+ if (!net_device ||
+ !net_device->phydev ||
+ !net_device->phydev->mdio.bus ||
+ !net_device->phydev->mdio.bus->dev.class ||
+ !net_device->phydev->mdio.bus->dev.class->name)
+ return NULL;
+
+ bus_class = net_device->phydev->mdio.bus->dev.class;
+ if (strcmp(bus_class->name, required_name) != 0)
+ return NULL;
+
+ return bus_class;
+}
+
+static int mdio_bus_name_matches(struct device *found_device,
+ const void *desired_name)
+{
+ struct mii_bus *mdio_bus;
+
+ /* Since we know 'found_dev' belongs to a class with the name
+ 'mdio_bus', we assume it is a member of a 'struct mii_bus',
+ and therefore it is safe to call container_of */
+ mdio_bus = container_of(found_device, struct mii_bus, dev);
+
+ /* Double check that this is indeed a 'struct mii_bus'. If it is,
+ it's state should be MDIO_REGISTERED at this point. If it is not, it is
+ either not a 'struct mii_bus', either it is in an undesired state. */
+ if (mdio_bus->state != MDIOBUS_REGISTERED)
+ return 0;
+
+ if (strcmp(mdio_bus->name, (char *)desired_name) == 0)
+ return 1;
+ return 0;
+}
+
+static struct mii_bus *find_mdio_bus_by_name(const char *name,
+ struct class *mdio_bus_class)
+{
+ struct device *found_device;
+
+ found_device = class_find_device(mdio_bus_class,
+ NULL,
+ (void *)name,
+ mdio_bus_name_matches);
+ if (found_device)
+ return container_of(found_device, struct mii_bus, dev);
+ else
+ return NULL;
+}
+
+/* helper function, check if given phy id belongs to a nxp phy
+ *
+ * @return 0 if not an nxp phy, != 0 else
+ */
+static int is_nxp_phy(int phy_id)
+{
+ return ((phy_id & NXP_PHY_ID_MASK) == NXP_PHY_ID_TJA1100 ||
+ (phy_id & NXP_PHY_ID_MASK) == NXP_PHY_ID_TJA1101 ||
+ (phy_id & NXP_PHY_ID_MASK) == NXP_PHY_ID_TJA1102P0 ||
+ (phy_id & NXP_PHY_ID_MASK) == NXP_PHY_ID_TJA1102P1 ||
+ (phy_id & NXP_PHY_ID_MASK) == NXP_PHY_ID_TJA1102S);
+
+}
+
+/* traverse the phy_map of the given mdio_bus, and manipulate any phys found
+ * that are found according to the value of the event, ie.
+ * - start (resume) on NETDEV_UP
+ * - stop (suspend) on NETDEV_GOING_DOWN
+ */
+static void mdio_netdev_change_event(struct mii_bus *mdio_bus, int event)
+{
+ /* normally on NETDEV_GOING_DOWN the kernel calls ndo_stop()
+ * of the eth controller, which stops and disconnects the one phy
+ * that is associated with the ethernet controller
+ * [see fec_enet_close() in fec_main.c l 2740].
+ * We need to do this manually for every NXP phy,
+ * however we do not (necessarily) have an attached_dev, so phy_detach,
+ * which is called by phy_disconnect(), would crash
+ */
+ int phy_addr;
+ struct phy_device *phydev;
+
+ for (phy_addr = 0; phy_addr < PHY_MAX_ADDR; phy_addr++) {
+ phydev = mdiobus_get_phy(mdio_bus, phy_addr);
+ if (!phydev)
+ continue;
+
+ if (!is_nxp_phy(phydev->phy_id) || !phydev->priv)
+ continue;
+
+ if (event == NETDEV_GOING_DOWN) {
+ /* stop polling,
+ * as mdio bus will become unavailable as soon as
+ * fec_runtime_suspend() (fec_main.c l4801) is called
+ */
+ if (!no_poll)
+ stop_polling(phydev);
+
+ /* sets state to PHY_HALTED */
+ phy_stop(phydev);
+ } else if (event == NETDEV_UP) {
+ /* updates the phy state and resumes,
+ * if state previously was PHY_HALTED
+ */
+ phy_start(phydev);
+
+ if (!no_poll)
+ start_polling(phydev);
+ }
+ }
+}
+
+/* callback, called whenever a netdev changes its state.
+ *
+ * Handles only NETDEV_GOING_DOWN and NETDEV_UP events of interface called
+ * MDIO_INTERFACE_NAME. Phys on the mdio bus "fec_enet_mii_bus"
+ * are stopped (suspended) and started (resumed) accordingly.
+ *
+ * @return NOTIFY_DONE
+ */
+static int netdev_state_change_event(struct notifier_block *unused,
+ unsigned long event, void *ptr)
+{
+ struct net_device *dev = netdev_notifier_info_to_dev(ptr);
+ struct mii_bus *mdio_bus;
+ struct class *bus_class;
+ struct net_device *net_device;
+
+ /* currently the eth0 interface controlls the mdio bus.
+ * However as CONFIG_FIXED_PHY is configured,
+ * eth0 is associated with "Fixed MDIO Bus", but the phydev
+ * is associated with "fec_enet_mii_bus". If eth0 goes down,
+ * only devices on "Fixed MDIO Bus" are notified (ie removed).
+ * We need to manually listen to eth0 events
+ * stops the phy and the polling
+ */
+ if (event != NETDEV_GOING_DOWN && event != NETDEV_UP)
+ goto skip;
+
+ if (strcmp(dev->name, MDIO_INTERFACE_NAME) != 0)
+ goto skip;
+
+ net_device = first_net_device(&init_net);
+ do {
+ bus_class = bus_class_from_net_device(net_device, "mdio_bus");
+ if (!bus_class)
+ continue;
+ mdio_bus = find_mdio_bus_by_name(MII_BUS_NAME, bus_class);
+ if (!mdio_bus)
+ continue;
+
+ if (verbosity > 0)
+ pr_alert("NXP PHY: received event [%lx] for [%s]: Notifying phys on bus [%s]\n",
+ event, dev->name, mdio_bus->name);
+
+ mdio_netdev_change_event(mdio_bus, event);
+ } while ((net_device = next_net_device(net_device)));
+
+skip:
+ return NOTIFY_DONE;
+}
+
+/* netdev notification infrastructure */
+struct notifier_block netdev_notifier = {
+ .notifier_call = netdev_state_change_event
+};
+#endif
+
+static struct phy_driver nxp_drivers[] = {
+{
+ .phy_id = NXP_PHY_ID_TJA1100,
+ .name = "TJA1100",
+ .phy_id_mask = NXP_PHY_ID_MASK,
+ .features = (SUPPORTED_TP | SUPPORTED_MII | SUPPORTED_100BASET1_FULL),
+ .flags = 0,
+ .probe = &nxp_probe,
+ .remove = &nxp_remove,
+ .config_init = &nxp_config_init,
+ .config_aneg = &nxp_config_aneg,
+ .read_status = &genphy_read_status,
+ .resume = &nxp_resume,
+ .suspend = &nxp_suspend,
+ .config_intr = &nxp_config_intr,
+ .ack_interrupt = &nxp_ack_interrupt,
+ .did_interrupt = &nxp_did_interrupt,
+}, {
+ .phy_id = NXP_PHY_ID_TJA1102P0,
+ .name = "TJA1102_p0",
+ .phy_id_mask = NXP_PHY_ID_MASK,
+ .features = (SUPPORTED_TP | SUPPORTED_MII | SUPPORTED_100BASET1_FULL),
+ .flags = 0,
+ .probe = &nxp_probe,
+ .remove = &nxp_remove,
+ .config_init = &nxp_config_init,
+ .config_aneg = &nxp_config_aneg,
+ .read_status = &genphy_read_status,
+ .resume = &nxp_resume,
+ .suspend = &nxp_suspend,
+ .config_intr = &nxp_config_intr,
+ .ack_interrupt = &nxp_ack_interrupt,
+ .did_interrupt = &nxp_did_interrupt,
+}, {
+ .phy_id = NXP_PHY_ID_TJA1101,
+ .name = "TJA1101",
+ .phy_id_mask = NXP_PHY_ID_MASK,
+ .features = (SUPPORTED_TP | SUPPORTED_MII | SUPPORTED_100BASET1_FULL),
+ .flags = 0,
+ .probe = &nxp_probe,
+ .remove = &nxp_remove,
+ .config_init = &nxp_config_init,
+ .config_aneg = &nxp_config_aneg,
+ .read_status = &genphy_read_status,
+ .resume = &nxp_resume,
+ .suspend = &nxp_suspend,
+ .config_intr = &nxp_config_intr,
+ .ack_interrupt = &nxp_ack_interrupt,
+ .did_interrupt = &nxp_did_interrupt,
+}, {
+ .phy_id = NXP_PHY_ID_TJA1102S,
+ .name = "TJA1102S",
+ .phy_id_mask = NXP_PHY_ID_MASK,
+ .features = (SUPPORTED_TP | SUPPORTED_MII | SUPPORTED_100BASET1_FULL),
+ .flags = 0,
+ .probe = &nxp_probe,
+ .remove = &nxp_remove,
+ .config_init = &nxp_config_init,
+ .config_aneg = &nxp_config_aneg,
+ .read_status = &genphy_read_status,
+ .resume = &nxp_resume,
+ .suspend = &nxp_suspend,
+ .config_intr = &nxp_config_intr,
+ .ack_interrupt = &nxp_ack_interrupt,
+ .did_interrupt = &nxp_did_interrupt,
+#ifdef CONFIG_TJA1102_FIX
+}, {
+ .phy_id = NXP_PHY_ID_TJA1102P1,
+ .name = "TJA1102_p1",
+ .phy_id_mask = NXP_PHY_ID_MASK,
+ .features = (SUPPORTED_TP | SUPPORTED_MII | SUPPORTED_100BASET1_FULL),
+ .flags = 0,
+ .probe = &nxp_probe,
+ .remove = &nxp_remove,
+ .config_init = &nxp_config_init,
+ .config_aneg = &nxp_config_aneg,
+ .read_status = &genphy_read_status,
+ .resume = &nxp_resume,
+ .suspend = &nxp_suspend,
+ .config_intr = &nxp_config_intr,
+ .ack_interrupt = &nxp_ack_interrupt,
+ .did_interrupt = &nxp_did_interrupt,
+#endif
+} };
+
+/* module init function */
+static int __init nxp_init(void)
+{
+ int err;
+
+ pr_alert("NXP PHY: loading NXP PHY driver: [%s%s]\n",
+ (managed_mode ? "managed mode" : "autonomous mode"),
+ (no_poll ? ", polling disabled" : ""));
+
+ err = phy_drivers_register(nxp_drivers, ARRAY_SIZE(nxp_drivers), THIS_MODULE);
+ if (err)
+ goto drv_registration_error;
+
+#ifdef NETDEV_NOTIFICATION_FIX
+ if (!no_poll) {
+ err = register_netdevice_notifier(&netdev_notifier);
+ if (err)
+ goto notification_registration_error;
+ }
+#endif
+
+ return 0;
+
+/* error handling */
+drv_registration_error:
+ pr_err("NXP PHY: driver registration failed\n");
+ return err;
+
+#ifdef NETDEV_NOTIFICATION_FIX
+notification_registration_error:
+ pr_err("NXP PHY: could not register notification handler\n");
+ unregister_netdevice_notifier(&netdev_notifier);
+ return err;
+#endif
+}
+
+module_init(nxp_init);
+
+/* module exit function */
+static void __exit nxp_exit(void)
+{
+ pr_alert("NXP PHY: unloading NXP PHY driver\n");
+#ifdef NETDEV_NOTIFICATION_FIX
+ if (!no_poll)
+ unregister_netdevice_notifier(&netdev_notifier);
+#endif
+ phy_drivers_unregister(nxp_drivers, ARRAY_SIZE(nxp_drivers));
+}
+
+module_exit(nxp_exit);
+
+/* use module device table for hotplugging support */
+static struct mdio_device_id __maybe_unused nxp_tbl[] = {
+ {NXP_PHY_ID_TJA1100, NXP_PHY_ID_MASK},
+ {NXP_PHY_ID_TJA1102P0, NXP_PHY_ID_MASK},
+ {NXP_PHY_ID_TJA1102S, NXP_PHY_ID_MASK},
+ {}
+};
+
+MODULE_DEVICE_TABLE(mdio, nxp_tbl);
+
+MODULE_DESCRIPTION("NXP PHY driver");
+MODULE_AUTHOR("Marco Hartmann");
+MODULE_LICENSE("GPL");
+MODULE_VERSION("0.3");
diff --git a/drivers/net/phy/tja110x.h b/drivers/net/phy/tja110x.h
new file mode 100644
index 000000000000..113dd14d5585
--- /dev/null
+++ b/drivers/net/phy/tja110x.h
@@ -0,0 +1,274 @@
+/*
+ * Copyright 2017 NXP
+ *
+ * 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 _NXP_PHY_H
+#define _NXP_PHY_H
+
+ /* PHY IDs */
+#define NXP_PHY_ID_TJA1100 (0x0180DC40U)
+#define NXP_PHY_ID_TJA1101 (0x0180DD00U)
+#define NXP_PHY_ID_TJA1102P0 (0x0180DC80U)
+#define NXP_PHY_ID_TJA1102P1 (0x00000000U)
+#define NXP_PHY_ID_TJA1102S (0x0180DC90U) /* only P0 is available */
+
+/* masks out the revision number */
+#define NXP_PHY_ID_MASK (0xFFFFFFF0U)
+
+#endif /* _NXP_PHY_H */
+
+/* NXP specific registers */
+
+/* extended_control register (TJA1100 and TJA1102) */
+#define MII_ECTRL (0x11U)
+/* configuration_1 register (TJA1100 and TJA1102) */
+#define MII_CFG1 (0x12U)
+/* configuration_2 register (TJA1100 and TJA1102) */
+#define MII_CFG2 (0x13U)
+/* symbol_error_counter register (TJA1100 and TJA1102) */
+#define MII_SYMERRCNT (0x14U)
+/* interrupt_source_flag register (TJA1100 and TJA1102) */
+#define MII_INTSRC (0x15U)
+/* interrupt_mask register (TJA1100 and TJA1102) */
+#define MII_INTMASK (0x16U)
+/* communication_status register (TJA1100 and TJA1102) */
+#define MII_COMMSTAT (0x17U)
+/* general_status register (TJA1100 and TJA1102) */
+#define MII_GENSTAT (0x18U)
+/* external_status register (TJA1100 and TJA1102) */
+#define MII_EXTERNAL_STATUS (0x19U)
+/* link_fail_counter register (TJA1100 and TJA1102) */
+#define MII_LINK_FAIL_COUNTER (0x1AU)
+/* common_configuration register (only TJA1102) */
+#define MII_COMMCFG (0x1BU)
+/* configuration_3 register (only TJA1102) */
+#define MII_CONFIGURATION_3 (0x1CU)
+
+/* extended_control register */
+#define ECTRL_LINK_CONTROL BIT(15)
+#define ECTRL_POWER_MODE (0x00007800U)
+#define ECTRL_SLAVE_JITTER_TEST BIT(10)
+#define ECTRL_TRAINING_RESTART BIT(9)
+#define ECTRL_TEST_MODE (0x000001C0U)
+#define ECTRL_CABLE_TEST BIT(5)
+#define ECTRL_LOOPBACK_MODE (0x00000018U)
+#define ECTRL_CONFIG_EN BIT(2)
+#define ECTRL_WAKE_REQUEST BIT(0)
+#define CABLE_TEST_TIMEOUT 1U /* cable test takes <= 1*100us */
+
+/* register values of the different power modes */
+#define POWER_MODE_NOCHANGE (0x00000000U)
+#define POWER_MODE_NORMAL (0x00001800U)
+#define POWER_MODE_SLEEPREQUEST (0x00005800U)
+#define POWER_MODE_STANDBY (0x00006000U)
+#define POWER_MODE_SILENT (0x00004800U)
+#define POWER_MODE_SLEEP (0x00005000U)
+
+/* timeouts for different power mode transitions */
+#define POWER_MODE_TIMEOUT 200U
+#define SLEEP_REQUEST_TO 160U /* 16ms = 160*100us */
+
+/* duration necessary for a reliable wake up of the link partner (in us) */
+#define TJA100_WAKE_REQUEST_TIMEOUT_US 5000U
+#define TJA102_WAKE_REQUEST_TIMEOUT_US 1300U
+
+/* configuration_1 register */
+#define CFG1_MASTER_SLAVE BIT(15)
+#define TJA1100_CFG1_AUTO_OP BIT(14)
+#define TJA1102_CFG1_FWDPHYLOC BIT(14)
+#define CFG1_LINK_LENGTH (0x00003000U)
+#define CFG1_REMWUPHY BIT(11)
+#define CFG1_LOCWUPHY BIT(10)
+#define CFG1_MII_MODE (0x00000300U)
+#define TJA1100_CFG1_MII_MODE_REFCLK_IN 0x100
+#define CFG1_MII_DRIVER BIT(7)
+#define CFG1_SLEEP_CONFIRM BIT(6)
+#define TJA1100_CFG1_LED_MODE (0x00000030U)
+#define TJA1100_CFG1_LED_EN BIT(3)
+#define CFG1_FWDPHYREM BIT(2)
+#define CFG1_AUTO_PWD BIT(1)
+#define CFG1_LPS_ACTIVE BIT(0)
+
+/* configuration_2 register */
+#define CFG2_PHYAD (0x0000F800U)
+#define CFG2_SNR_AVERAGING (0x00000600U)
+#define CFG2_SNR_WLIMIT (0x000001C0U)
+#define CFG2_SNR_FAILLIMIT (0x00000038U)
+#define CFG2_JUMBO_ENABLE BIT(2)
+#define CFG2_SLEEP_REQUEST_TO (0x00000003U)
+
+#define SLEEP_REQUEST_TO_16MS (0x00000003U)
+
+/* symbol_error_counter register */
+#define SYMERRCNT_SYM_ERR_CNT (0xFFFFFFFFU)
+
+/* interrupt_source_flag register */
+#define INTERRUPT_PWON BIT(15)
+#define INTERRUPT_WAKEUP BIT(14)
+#define INTERRUPT_WUR_RECEIVED BIT(13)
+#define INTERRUPT_LPS_RECEIVED BIT(12)
+#define INTERRUPT_PHY_INIT_FAIL BIT(11)
+#define INTERRUPT_LINK_STATUS_FAIL BIT(10)
+#define INTERRUPT_LINK_STATUS_UP BIT(9)
+#define INTERRUPT_SYM_ERR BIT(8)
+#define INTERRUPT_TRAINING_FAILED BIT(7)
+#define INTERRUPT_SNR_WARNING BIT(6)
+#define INTERRUPT_CONTROL_ERROR BIT(5)
+#define INTERRUPT_TXEN_CLAMPED BIT(4)
+#define INTERRUPT_UV_ERR BIT(3)
+#define INTERRUPT_UV_RECOVERY BIT(2)
+#define INTERRUPT_TEMP_ERROR BIT(1)
+#define INTERRUPT_SLEEP_ABORT BIT(0)
+#define INTERRUPT_NONE (0x00000000U)
+#define INTERRUPT_ALL (0x0000FFFFU)
+
+/* communication_status register */
+#define COMMSTAT_LINK_UP BIT(15)
+#define COMMSTAT_TX_MODE (0x00006000U)
+#define COMMSTAT_LOC_RCVR_STATUS BIT(12)
+#define COMMSTAT_REM_RCVR_STATUS BIT(11)
+#define COMMSTAT_SCR_LOCKED BIT(10)
+#define COMMSTAT_SSD_ERROR BIT(9)
+#define COMMSTAT_ESD_ERROR BIT(8)
+#define COMMSTAT_SNR (0x000000E0U)
+#define COMMSTAT_RECEIVE_ERROR BIT(4)
+#define COMMSTAT_TRANSMIT_ERROR BIT(3)
+#define COMMSTAT_PHY_STATE (0x00000007U)
+
+/* register category general_status */
+#define GENSTAT_INT_STATUS BIT(15)
+#define GENSTAT_PLL_LOCKED BIT(14)
+#define GENSTAT_LOCAL_WU BIT(13)
+#define GENSTAT_REMOTE_WU BIT(12)
+#define GENSTAT_DATA_DET_WU BIT(11)
+#define GENSTAT_EN_STATUS BIT(10)
+#define GENSTAT_RESET_STATUS BIT(9)
+#define GENSTAT_LINKFAIL_CNT (0x000000F8U)
+
+/* common_configuration register */
+#define COMMCFG_AUTO_OP BIT(15)
+
+/* External status register */
+#define EXTSTAT_OPEN_DETECT BIT(7)
+#define EXTSTAT_SHORT_DETECT BIT(8)
+
+/*
+ * Indicator for BRR support in ESTATUS register
+ * and in phydev->supported member.
+ * Not yet present in include/uapi/linux/mii.h and
+ * include/uapi/linux/ethtool.h
+ */
+#define ESTATUS_100T1_FULL BIT(7)
+#define SUPPORTED_100BASET1_FULL BIT(27)
+#define ADVERTISED_100BASET1_FULL BIT(27)
+
+/* length of delay during one loop iteration in
+ * wait_on_condition (in us)
+ */
+#define DELAY_LENGTH 100U
+
+/* length of delay during two pollings (in ms) */
+#define POLL_PAUSE 50U
+
+/* possible test modes of the PHY */
+enum test_mode {
+ NO_TMODE = 1,
+ TMODE1,
+ TMODE2,
+ TMODE3,
+ TMODE4,
+ TMODE5,
+ TMODE6
+};
+
+ /* register values of the different test modes */
+ #define ECTRL_NO_TMODE (0x000000U) /* no test mode */
+ #define ECTRL_TMODE1 (0x000040U)
+ #define ECTRL_TMODE2 (0x000080U)
+ #define ECTRL_TMODE3 (0x0000C0U)
+ #define ECTRL_TMODE4 (0x000100U)
+ #define ECTRL_TMODE5 (0x000140U)
+ /* scrambler, descrambler bypassed */
+ #define ECTRL_TMODE6 (0x000180U)
+
+/* possible loopback modes of the PHY */
+enum loopback_mode {
+ NO_LMODE = 1,
+ INTERNAL_LMODE,
+ EXTERNAL_LMODE,
+ REMOTE_LMODE
+};
+
+/* register values of the different loopback modes */
+#define ECTRL_INTERNAL_LMODE (0x000000U)
+#define ECTRL_EXTERNAL_LMODE (0x000008U)
+#define ECTRL_REMOTE_LMODE (0x000018U)
+
+/* possible led modes of the PHY */
+enum led_mode {
+ NO_LED_MODE = 1,
+ LINKUP_LED_MODE,
+ FRAMEREC_LED_MODE,
+ SYMERR_LED_MODE,
+ CRSSIG_LED_MODE
+};
+
+/* register values of the different led modes */
+#define CFG1_LED_LINKUP (0x00000000U)
+#define CFG1_LED_FRAMEREC (0x00000010U)
+#define CFG1_LED_SYMERR (0x00000020U)
+#define CFG1_LED_CRSSIG (0x00000030U)
+
+/* values written to sysfs nodes */
+#define SYSFS_FWDPHYLOC BIT(0)
+#define SYSFS_REMWUPHY BIT(1)
+#define SYSFS_LOCWUPHY BIT(2)
+#define SYSFS_FWDPHYREM BIT(3)
+
+/* nxp specific data */
+struct nxp_specific_data {
+ int is_master;
+ int is_poll_setup;
+ int is_polling;
+
+ u32 quirks;
+};
+
+/* register values of the different led modes */
+#define SNR_CLASS_NONE (0x00000000U)
+#define SNR_CLASS_A (0x00000040U)
+#define SNR_CLASS_B (0x00000080U)
+#define SNR_CLASS_C (0x000000C0U)
+#define SNR_CLASS_D (0x00000100U)
+#define SNR_CLASS_E (0x00000140U)
+#define SNR_CLASS_F (0x00000180U)
+#define SNR_CLASS_G (0x000001C0U)
+
+/* Helper Function prototypes */
+static int set_master_cfg(struct phy_device *phydev, int setMaster);
+static int get_master_cfg(struct phy_device *phydev);
+static int wait_on_condition(struct phy_device *phydev, int reg_addr,
+ int reg_mask, int cond, int timeout);
+static void set_link_control(struct phy_device *phydev,
+ int enable_link_control);
+static inline int phy_configure_bit(struct phy_device *phydev,
+ int reg_name, int bit_mask,
+ int bit_value);
+static inline int phy_configure_bits(struct phy_device *phydev,
+ int reg_name, int bit_mask,
+ int bit_value);
+static int nxp_resume(struct phy_device *phydev);
+static int nxp_ack_interrupt(struct phy_device *phydev);
+static void poll(struct work_struct *work);
+static void setup_polling(struct phy_device *phydev);
+static void start_polling(struct phy_device *phydev);
+static void stop_polling(struct phy_device *phydev);
+
+static struct attribute *nxp_sysfs_entries[];
+static struct attribute_group nxp_attribute_group;
diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c
index a4f635820f35..1c183cd26e94 100644
--- a/drivers/net/wireless/ath/ath10k/core.c
+++ b/drivers/net/wireless/ath/ath10k/core.c
@@ -1198,7 +1198,7 @@ static int ath10k_core_fetch_board_data_api_n(struct ath10k *ar,
out:
if (!ar->normal_mode_fw.board_data || !ar->normal_mode_fw.board_len) {
- ath10k_err(ar,
+ ath10k_dbg(ar, ATH10K_DBG_BOOT,
"failed to fetch board data for %s from %s/%s\n",
boardname, ar->hw_params.fw.dir, filename);
ret = -ENODATA;
@@ -2301,7 +2301,7 @@ static int ath10k_core_probe_fw(struct ath10k *ar)
ret = ath10k_core_fetch_firmware_files(ar);
if (ret) {
- ath10k_err(ar, "could not fetch firmware files (%d)\n", ret);
+ ath10k_dbg(ar, ATH10K_DBG_BOOT, "could not fetch firmware files (%d)\n", ret);
goto err_power_down;
}
diff --git a/drivers/net/wireless/ath/ath10k/pci.c b/drivers/net/wireless/ath/ath10k/pci.c
index f9e409caca68..03a84c6fb0c6 100644
--- a/drivers/net/wireless/ath/ath10k/pci.c
+++ b/drivers/net/wireless/ath/ath10k/pci.c
@@ -1790,6 +1790,10 @@ static void ath10k_pci_hif_stop(struct ath10k *ar)
ath10k_pci_safe_chip_reset(ar);
ath10k_pci_flush(ar);
+ ath10k_pci_sleep_sync(ar);
+
+ napi_synchronize(&ar->napi);
+ napi_disable(&ar->napi);
spin_lock_irqsave(&ar_pci->ps_lock, flags);
WARN_ON(ar_pci->ps_wake_refcount > 0);
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
index dd6e27513cc1..6e0a31b2b1cb 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
@@ -47,6 +47,7 @@
#include "sdio.h"
#include "core.h"
#include "common.h"
+#include "cfg80211.h"
#define SDIOH_API_ACCESS_RETRY_LIMIT 2
@@ -54,6 +55,7 @@
#define SDIO_FUNC1_BLOCKSIZE 64
#define SDIO_FUNC2_BLOCKSIZE 512
+#define SDIO_4373_FUNC2_BLOCKSIZE 256
/* Maximum milliseconds to wait for F2 to come up */
#define SDIO_WAIT_F2RDY 3000
@@ -1038,6 +1040,7 @@ static void brcmf_sdiod_host_fixup(struct mmc_host *host)
static int brcmf_sdiod_probe(struct brcmf_sdio_dev *sdiodev)
{
int ret = 0;
+ unsigned int f2_blksz = SDIO_FUNC2_BLOCKSIZE;
sdiodev->num_funcs = 2;
@@ -1049,11 +1052,18 @@ static int brcmf_sdiod_probe(struct brcmf_sdio_dev *sdiodev)
sdio_release_host(sdiodev->func[1]);
goto out;
}
- ret = sdio_set_block_size(sdiodev->func[2], SDIO_FUNC2_BLOCKSIZE);
+
+ if (sdiodev->func[0]->device == SDIO_DEVICE_ID_CYPRESS_4373) {
+ f2_blksz = SDIO_4373_FUNC2_BLOCKSIZE;
+ }
+
+ ret = sdio_set_block_size(sdiodev->func[2], f2_blksz);
if (ret) {
brcmf_err("Failed to set F2 blocksize\n");
sdio_release_host(sdiodev->func[1]);
goto out;
+ } else {
+ brcmf_dbg(SDIO, "set F2 blocksize to %d\n", f2_blksz);
}
/* increase F2 timeout */
@@ -1101,12 +1111,14 @@ static const struct sdio_device_id brcmf_sdmmc_ids[] = {
BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_43364),
BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_4335_4339),
BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_4339),
+ BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_43428),
BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_43430),
BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_4345),
BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_43455),
BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_4354),
BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_4356),
BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_CYPRESS_4373),
+ BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_CYPRESS_43012),
{ /* end: all zeroes */ }
};
MODULE_DEVICE_TABLE(sdio, brcmf_sdmmc_ids);
@@ -1173,6 +1185,7 @@ static int brcmf_ops_sdio_probe(struct sdio_func *func,
dev_set_drvdata(&func->dev, bus_if);
dev_set_drvdata(&sdiodev->func[1]->dev, bus_if);
sdiodev->dev = &sdiodev->func[1]->dev;
+ dev_set_drvdata(&sdiodev->func[2]->dev, bus_if);
brcmf_sdiod_change_state(sdiodev, BRCMF_SDIOD_DOWN);
@@ -1189,6 +1202,7 @@ static int brcmf_ops_sdio_probe(struct sdio_func *func,
fail:
dev_set_drvdata(&func->dev, NULL);
dev_set_drvdata(&sdiodev->func[1]->dev, NULL);
+ dev_set_drvdata(&sdiodev->func[2]->dev, NULL);
kfree(sdiodev->func[0]);
kfree(sdiodev);
kfree(bus_if);
@@ -1245,14 +1259,26 @@ static int brcmf_ops_sdio_suspend(struct device *dev)
struct brcmf_bus *bus_if;
struct brcmf_sdio_dev *sdiodev;
mmc_pm_flag_t sdio_flags;
+ struct brcmf_cfg80211_info *config;
+ int retry = BRCMF_PM_WAIT_MAXRETRY;
func = container_of(dev, struct sdio_func, dev);
+ bus_if = dev_get_drvdata(dev);
+ config = bus_if->drvr->config;
+
brcmf_dbg(SDIO, "Enter: F%d\n", func->num);
+
+ while (retry &&
+ config->pm_state == BRCMF_CFG80211_PM_STATE_SUSPENDING) {
+ usleep_range(10000, 20000);
+ retry--;
+ }
+ if (!retry && config->pm_state == BRCMF_CFG80211_PM_STATE_SUSPENDING)
+ brcmf_err("timed out wait for cfg80211 suspended\n");
+
if (func->num != SDIO_FUNC_1)
return 0;
-
- bus_if = dev_get_drvdata(dev);
sdiodev = bus_if->bus_priv.sdio;
brcmf_sdiod_freezer_on(sdiodev);
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h
index 163ddc49f951..0b76a615708e 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h
@@ -71,6 +71,7 @@ struct brcmf_bus_dcmd {
* @wowl_config: specify if dongle is configured for wowl when going to suspend
* @get_ramsize: obtain size of device memory.
* @get_memdump: obtain device memory dump in provided buffer.
+ * @get_fwname: obtain firmware name.
*
* This structure provides an abstract interface towards the
* bus specific driver. For control messages to common driver
@@ -87,6 +88,8 @@ struct brcmf_bus_ops {
void (*wowl_config)(struct device *dev, bool enabled);
size_t (*get_ramsize)(struct device *dev);
int (*get_memdump)(struct device *dev, void *data, size_t len);
+ int (*get_fwname)(struct device *dev, uint chip, uint chiprev,
+ unsigned char *fw_name);
};
@@ -224,6 +227,13 @@ int brcmf_bus_get_memdump(struct brcmf_bus *bus, void *data, size_t len)
return bus->ops->get_memdump(bus->dev, data, len);
}
+static inline
+int brcmf_bus_get_fwname(struct brcmf_bus *bus, uint chip, uint chiprev,
+ unsigned char *fw_name)
+{
+ return bus->ops->get_fwname(bus->dev, chip, chiprev, fw_name);
+}
+
/*
* interface functions from common layer
*/
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
index 04fa66ed99a0..76ad2b182358 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
@@ -1760,6 +1760,14 @@ brcmf_set_key_mgmt(struct net_device *ndev, struct cfg80211_connect_params *sme)
case WLAN_AKM_SUITE_PSK:
val = WPA2_AUTH_PSK;
break;
+ case WLAN_AKM_SUITE_FT_8021X:
+ val = WPA2_AUTH_UNSPECIFIED | WPA2_AUTH_FT;
+ if (sme->want_1x)
+ profile->use_fwsup = BRCMF_PROFILE_FWSUP_1X;
+ break;
+ case WLAN_AKM_SUITE_FT_PSK:
+ val = WPA2_AUTH_PSK | WPA2_AUTH_FT;
+ break;
default:
brcmf_err("invalid cipher group (%d)\n",
sme->crypto.cipher_group);
@@ -3615,7 +3623,7 @@ static void brcmf_report_wowl_wakeind(struct wiphy *wiphy, struct brcmf_if *ifp)
err = brcmf_fil_iovar_data_get(ifp, "wowl_wakeind", &wake_ind_le,
sizeof(wake_ind_le));
if (err) {
- brcmf_err("Get wowl_wakeind failed, err = %d\n", err);
+ brcmf_dbg(INFO, "cannet get wowl_wakeind, err = %d\n", err);
return;
}
@@ -3683,10 +3691,24 @@ static s32 brcmf_cfg80211_resume(struct wiphy *wiphy)
struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
struct net_device *ndev = cfg_to_ndev(cfg);
struct brcmf_if *ifp = netdev_priv(ndev);
+ struct brcmf_pub *drvr = ifp->drvr;
+ struct brcmf_bus *bus_if = drvr->bus_if;
+ struct brcmf_cfg80211_info *config = drvr->config;
+ int retry = BRCMF_PM_WAIT_MAXRETRY;
brcmf_dbg(TRACE, "Enter\n");
+ config->pm_state = BRCMF_CFG80211_PM_STATE_RESUMING;
+
if (cfg->wowl.active) {
+ /* wait for bus resumed */
+ while (retry && bus_if->state != BRCMF_BUS_UP) {
+ usleep_range(10000, 20000);
+ retry--;
+ }
+ if (!retry && bus_if->state != BRCMF_BUS_UP)
+ brcmf_err("timed out wait for bus resume\n");
+
brcmf_report_wowl_wakeind(wiphy, ifp);
brcmf_fil_iovar_int_set(ifp, "wowl_clear", 0);
brcmf_config_wowl_pattern(ifp, "clr", NULL, 0, NULL, 0);
@@ -3702,7 +3724,12 @@ static s32 brcmf_cfg80211_resume(struct wiphy *wiphy)
brcmf_notify_sched_scan_results);
cfg->wowl.nd_enabled = false;
}
+
+ /* disable packet filters */
+ brcmf_pktfilter_enable(ifp->ndev, false);
+
}
+ config->pm_state = BRCMF_CFG80211_PM_STATE_RESUMED;
return 0;
}
@@ -3760,6 +3787,9 @@ static void brcmf_configure_wowl(struct brcmf_cfg80211_info *cfg,
brcmf_fil_iovar_int_set(ifp, "wowl_activate", 1);
brcmf_bus_wowl_config(cfg->pub->bus_if, true);
cfg->wowl.active = true;
+
+ /* enable packet filters */
+ brcmf_pktfilter_enable(ifp->ndev, true);
}
static s32 brcmf_cfg80211_suspend(struct wiphy *wiphy,
@@ -3769,9 +3799,12 @@ static s32 brcmf_cfg80211_suspend(struct wiphy *wiphy,
struct net_device *ndev = cfg_to_ndev(cfg);
struct brcmf_if *ifp = netdev_priv(ndev);
struct brcmf_cfg80211_vif *vif;
+ struct brcmf_cfg80211_info *config = ifp->drvr->config;
brcmf_dbg(TRACE, "Enter\n");
+ config->pm_state = BRCMF_CFG80211_PM_STATE_SUSPENDING;
+
/* if the primary net_device is not READY there is nothing
* we can do but pray resume goes smoothly.
*/
@@ -3786,7 +3819,8 @@ static s32 brcmf_cfg80211_suspend(struct wiphy *wiphy,
if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status))
brcmf_abort_scanning(cfg);
- if (wowl == NULL) {
+ if (!wowl || !test_bit(BRCMF_VIF_STATUS_CONNECTED,
+ &ifp->vif->sme_state)) {
brcmf_bus_wowl_config(cfg->pub->bus_if, false);
list_for_each_entry(vif, &cfg->vif_list, list) {
if (!test_bit(BRCMF_VIF_STATUS_READY, &vif->sme_state))
@@ -3806,14 +3840,19 @@ static s32 brcmf_cfg80211_suspend(struct wiphy *wiphy,
brcmf_set_mpc(ifp, 1);
} else {
- /* Configure WOWL paramaters */
- brcmf_configure_wowl(cfg, ifp, wowl);
+ /* Configure WOWL parameters */
+ if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_WOWL))
+ brcmf_configure_wowl(cfg, ifp, wowl);
}
exit:
- brcmf_dbg(TRACE, "Exit\n");
+ /* set cfg80211 pm state to cfg80211 suspended state */
+ config->pm_state = BRCMF_CFG80211_PM_STATE_SUSPENDED;
+
/* clear any scanning activity */
cfg->scan_status = 0;
+
+ brcmf_dbg(TRACE, "Exit\n");
return 0;
}
@@ -4622,9 +4661,7 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
}
}
- if ((dev_role == NL80211_IFTYPE_AP) &&
- ((ifp->ifidx == 0) ||
- !brcmf_feat_is_enabled(ifp, BRCMF_FEAT_RSDB))) {
+ if ((dev_role == NL80211_IFTYPE_AP) && (ifp->ifidx == 0)) {
err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_DOWN, 1);
if (err < 0) {
brcmf_err("BRCMF_C_DOWN error %d\n", err);
@@ -5255,6 +5292,26 @@ static int brcmf_cfg80211_del_pmk(struct wiphy *wiphy, struct net_device *dev,
return brcmf_set_pmk(ifp, NULL, 0);
}
+static int
+brcmf_cfg80211_change_bss(struct wiphy *wiphy, struct net_device *dev,
+ struct bss_parameters *params)
+{
+ struct brcmf_if *ifp;
+ int ret = 0;
+ u32 ap_isolate;
+
+ brcmf_dbg(TRACE, "Enter\n");
+ ifp = netdev_priv(dev);
+ if (params->ap_isolate >= 0) {
+ ap_isolate = (u32)params->ap_isolate;
+ ret = brcmf_fil_iovar_int_set(ifp, "ap_isolate", ap_isolate);
+ if (ret < 0)
+ brcmf_err("ap_isolate iovar failed: ret=%d\n", ret);
+ }
+
+ return ret;
+}
+
static struct cfg80211_ops brcmf_cfg80211_ops = {
.add_virtual_intf = brcmf_cfg80211_add_iface,
.del_virtual_intf = brcmf_cfg80211_del_iface,
@@ -5300,6 +5357,7 @@ static struct cfg80211_ops brcmf_cfg80211_ops = {
.update_connect_params = brcmf_cfg80211_update_conn_params,
.set_pmk = brcmf_cfg80211_set_pmk,
.del_pmk = brcmf_cfg80211_del_pmk,
+ .change_bss = brcmf_cfg80211_change_bss,
};
struct brcmf_cfg80211_vif *brcmf_alloc_vif(struct brcmf_cfg80211_info *cfg,
@@ -5434,11 +5492,124 @@ static void brcmf_clear_assoc_ies(struct brcmf_cfg80211_info *cfg)
conn_info->resp_ie_len = 0;
}
+u8 brcmf_map_prio_to_prec(void *config, u8 prio)
+{
+ struct brcmf_cfg80211_info *cfg = (struct brcmf_cfg80211_info *)config;
+
+ if (!cfg)
+ return (prio == PRIO_8021D_NONE || prio == PRIO_8021D_BE) ?
+ (prio ^ 2) : prio;
+
+ /* For those AC(s) with ACM flag set to 1, convert its 4-level priority
+ * to an 8-level precedence which is the same as BE's */
+ if (prio > PRIO_8021D_EE &&
+ cfg->ac_priority[prio] == cfg->ac_priority[PRIO_8021D_BE])
+ return cfg->ac_priority[prio] * 2;
+
+ /* Conversion of 4-level priority to 8-level precedence */
+ if (prio == PRIO_8021D_BE || prio == PRIO_8021D_BK ||
+ prio == PRIO_8021D_CL || prio == PRIO_8021D_VO)
+ return cfg->ac_priority[prio] * 2;
+ else
+ return cfg->ac_priority[prio] * 2 + 1;
+}
+
+u8 brcmf_map_prio_to_aci(void *config, u8 prio)
+{
+ /* Prio here refers to the 802.1d priority in range of 0 to 7.
+ * ACI here refers to the WLAN AC Index in range of 0 to 3.
+ * This function will return ACI corresponding to input prio.
+ */
+ struct brcmf_cfg80211_info *cfg = (struct brcmf_cfg80211_info *)config;
+
+ if (cfg)
+ return cfg->ac_priority[prio];
+
+ return prio;
+}
+
+static void brcmf_wifi_prioritize_acparams(const
+ struct brcmf_cfg80211_edcf_acparam *acp, u8 *priority)
+{
+ u8 aci;
+ u8 aifsn;
+ u8 ecwmin;
+ u8 ecwmax;
+ u8 acm;
+ u8 ranking_basis[EDCF_AC_COUNT];
+ u8 aci_prio[EDCF_AC_COUNT]; /* AC_BE, AC_BK, AC_VI, AC_VO */
+ u8 index;
+
+ for (aci = 0; aci < EDCF_AC_COUNT; aci++, acp++) {
+ aifsn = acp->ACI & EDCF_AIFSN_MASK;
+ acm = (acp->ACI & EDCF_ACM_MASK) ? 1 : 0;
+ ecwmin = acp->ECW & EDCF_ECWMIN_MASK;
+ ecwmax = (acp->ECW & EDCF_ECWMAX_MASK) >> EDCF_ECWMAX_SHIFT;
+ brcmf_dbg(CONN, "ACI %d aifsn %d acm %d ecwmin %d ecwmax %d\n",
+ aci, aifsn, acm, ecwmin, ecwmax);
+ /* Default AC_VO will be the lowest ranking value */
+ ranking_basis[aci] = aifsn + ecwmin + ecwmax;
+ /* Initialise priority starting at 0 (AC_BE) */
+ aci_prio[aci] = 0;
+
+ /* If ACM is set, STA can't use this AC as per 802.11.
+ * Change the ranking to BE
+ */
+ if (aci != AC_BE && aci != AC_BK && acm == 1)
+ ranking_basis[aci] = ranking_basis[AC_BE];
+ }
+
+ /* Ranking method which works for AC priority
+ * swapping when values for cwmin, cwmax and aifsn are varied
+ * Compare each aci_prio against each other aci_prio
+ */
+ for (aci = 0; aci < EDCF_AC_COUNT; aci++) {
+ for (index = 0; index < EDCF_AC_COUNT; index++) {
+ if (index != aci) {
+ /* Smaller ranking value has higher priority,
+ * so increment priority for each ACI which has
+ * a higher ranking value
+ */
+ if (ranking_basis[aci] < ranking_basis[index])
+ aci_prio[aci]++;
+ }
+ }
+ }
+
+ /* By now, aci_prio[] will be in range of 0 to 3.
+ * Use ACI prio to get the new priority value for
+ * each 802.1d traffic type, in this range.
+ */
+
+ /* 802.1d 0,3 maps to BE */
+ priority[0] = aci_prio[AC_BE];
+ priority[3] = aci_prio[AC_BE];
+
+ /* 802.1d 1,2 maps to BK */
+ priority[1] = aci_prio[AC_BK];
+ priority[2] = aci_prio[AC_BK];
+
+ /* 802.1d 4,5 maps to VO */
+ priority[4] = aci_prio[AC_VI];
+ priority[5] = aci_prio[AC_VI];
+
+ /* 802.1d 6,7 maps to VO */
+ priority[6] = aci_prio[AC_VO];
+ priority[7] = aci_prio[AC_VO];
+
+ brcmf_dbg(CONN, "Adj prio BE 0->%d, BK 1->%d, BK 2->%d, BE 3->%d\n",
+ priority[0], priority[1], priority[2], priority[3]);
+
+ brcmf_dbg(CONN, "Adj prio VI 4->%d, VI 5->%d, VO 6->%d, VO 7->%d\n",
+ priority[4], priority[5], priority[6], priority[7]);
+}
+
static s32 brcmf_get_assoc_ies(struct brcmf_cfg80211_info *cfg,
struct brcmf_if *ifp)
{
struct brcmf_cfg80211_assoc_ielen_le *assoc_info;
struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
+ struct brcmf_cfg80211_edcf_acparam edcf_acparam_info[EDCF_AC_COUNT];
u32 req_len;
u32 resp_len;
s32 err = 0;
@@ -5487,6 +5658,17 @@ static s32 brcmf_get_assoc_ies(struct brcmf_cfg80211_info *cfg,
GFP_KERNEL);
if (!conn_info->resp_ie)
conn_info->resp_ie_len = 0;
+
+ err = brcmf_fil_iovar_data_get(ifp, "wme_ac_sta",
+ edcf_acparam_info,
+ sizeof(edcf_acparam_info));
+ if (err) {
+ brcmf_err("could not get wme_ac_sta (%d)\n", err);
+ return err;
+ }
+
+ brcmf_wifi_prioritize_acparams(edcf_acparam_info,
+ cfg->ac_priority);
} else {
conn_info->resp_ie_len = 0;
conn_info->resp_ie = NULL;
@@ -5797,6 +5979,25 @@ static void brcmf_init_conf(struct brcmf_cfg80211_conf *conf)
conf->retry_long = (u32)-1;
}
+static void brcmf_init_wmm_prio(u8 *priority)
+{
+ /* Initialize AC priority array to default
+ * 802.1d priority as per following table:
+ * 802.1d prio 0,3 maps to BE
+ * 802.1d prio 1,2 maps to BK
+ * 802.1d prio 4,5 maps to VI
+ * 802.1d prio 6,7 maps to VO
+ */
+ priority[0] = AC_BE;
+ priority[3] = AC_BE;
+ priority[1] = AC_BK;
+ priority[2] = AC_BK;
+ priority[4] = AC_VI;
+ priority[5] = AC_VI;
+ priority[6] = AC_VO;
+ priority[7] = AC_VO;
+}
+
static void brcmf_register_event_handlers(struct brcmf_cfg80211_info *cfg)
{
brcmf_fweh_register(cfg->pub, BRCMF_E_LINK,
@@ -5892,6 +6093,7 @@ static s32 wl_init_priv(struct brcmf_cfg80211_info *cfg)
mutex_init(&cfg->usr_sync);
brcmf_init_escan(cfg);
brcmf_init_conf(cfg->conf);
+ brcmf_init_wmm_prio(cfg->ac_priority);
init_completion(&cfg->vif_disabled);
return err;
}
@@ -6408,6 +6610,16 @@ brcmf_txrx_stypes[NUM_NL80211_IFTYPES] = {
.tx = 0xffff,
.rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
+ },
+ [NL80211_IFTYPE_AP] = {
+ .tx = 0xffff,
+ .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
+ BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
+ BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
+ BIT(IEEE80211_STYPE_DISASSOC >> 4) |
+ BIT(IEEE80211_STYPE_AUTH >> 4) |
+ BIT(IEEE80211_STYPE_DEAUTH >> 4) |
+ BIT(IEEE80211_STYPE_ACTION >> 4)
}
};
@@ -6553,6 +6765,7 @@ static void brcmf_wiphy_wowl_params(struct wiphy *wiphy, struct brcmf_if *ifp)
#ifdef CONFIG_PM
struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
struct wiphy_wowlan_support *wowl;
+ struct cfg80211_wowlan *brcmf_wowlan_config = NULL;
wowl = kmemdup(&brcmf_wowlan_support, sizeof(brcmf_wowlan_support),
GFP_KERNEL);
@@ -6575,6 +6788,27 @@ static void brcmf_wiphy_wowl_params(struct wiphy *wiphy, struct brcmf_if *ifp)
}
wiphy->wowlan = wowl;
+
+ /* wowlan_config structure report for kernels */
+ brcmf_wowlan_config = kzalloc(sizeof(*brcmf_wowlan_config),
+ GFP_KERNEL);
+ if (brcmf_wowlan_config) {
+ brcmf_wowlan_config->any = false;
+ brcmf_wowlan_config->disconnect = true;
+ brcmf_wowlan_config->eap_identity_req = true;
+ brcmf_wowlan_config->four_way_handshake = true;
+ brcmf_wowlan_config->rfkill_release = false;
+ brcmf_wowlan_config->patterns = NULL;
+ brcmf_wowlan_config->n_patterns = 0;
+ brcmf_wowlan_config->tcp = NULL;
+ if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_WOWL_GTK))
+ brcmf_wowlan_config->gtk_rekey_failure = true;
+ else
+ brcmf_wowlan_config->gtk_rekey_failure = false;
+ } else {
+ brcmf_err("Can not allocate memory for brcm_wowlan_config\n");
+ }
+ wiphy->wowlan_config = brcmf_wowlan_config;
#endif
}
@@ -6626,6 +6860,7 @@ static int brcmf_setup_wiphy(struct wiphy *wiphy, struct brcmf_if *ifp)
wiphy->flags |= WIPHY_FLAG_NETNS_OK |
WIPHY_FLAG_PS_ON_BY_DEFAULT |
+ WIPHY_FLAG_HAVE_AP_SME |
WIPHY_FLAG_OFFCHAN_TX |
WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_TDLS))
@@ -6648,8 +6883,7 @@ static int brcmf_setup_wiphy(struct wiphy *wiphy, struct brcmf_if *ifp)
wiphy->vendor_commands = brcmf_vendor_cmds;
wiphy->n_vendor_commands = BRCMF_VNDR_CMDS_LAST - 1;
- if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_WOWL))
- brcmf_wiphy_wowl_params(wiphy, ifp);
+ brcmf_wiphy_wowl_params(wiphy, ifp);
err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BANDLIST, &bandlist,
sizeof(bandlist));
if (err) {
@@ -6706,6 +6940,7 @@ static s32 brcmf_config_dongle(struct brcmf_cfg80211_info *cfg)
struct wireless_dev *wdev;
struct brcmf_if *ifp;
s32 power_mode;
+ s32 eap_restrict;
s32 err = 0;
if (cfg->dongle_up)
@@ -6730,6 +6965,14 @@ static s32 brcmf_config_dongle(struct brcmf_cfg80211_info *cfg)
err = brcmf_dongle_roam(ifp);
if (err)
goto default_conf_out;
+
+ eap_restrict = ifp->drvr->settings->eap_restrict;
+ if (eap_restrict) {
+ err = brcmf_fil_iovar_int_set(ifp, "eap_restrict",
+ eap_restrict);
+ if (err)
+ brcmf_info("eap_restrict error (%d)\n", err);
+ }
err = brcmf_cfg80211_change_iface(wdev->wiphy, ndev, wdev->iftype,
NULL);
if (err)
@@ -7018,6 +7261,7 @@ struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr,
cfg->wiphy = wiphy;
cfg->ops = ops;
cfg->pub = drvr;
+ cfg->pm_state = BRCMF_CFG80211_PM_STATE_RESUMED;
init_vif_event(&cfg->vif_event);
INIT_LIST_HEAD(&cfg->vif_list);
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h
index 7b2835e5e434..00faae6e50ab 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h
@@ -34,6 +34,23 @@
#define WL_ROAM_TRIGGER_LEVEL -75
#define WL_ROAM_DELTA 20
+/* WME Access Category Indices (ACIs) */
+#define AC_BE 0 /* Best Effort */
+#define AC_BK 1 /* Background */
+#define AC_VI 2 /* Video */
+#define AC_VO 3 /* Voice */
+#define EDCF_AC_COUNT 4
+#define MAX_8021D_PRIO 8
+
+#define EDCF_ACI_MASK 0x60
+#define EDCF_ACI_SHIFT 5
+#define EDCF_ACM_MASK 0x10
+#define EDCF_ECWMIN_MASK 0x0f
+#define EDCF_ECWMAX_SHIFT 4
+#define EDCF_AIFSN_MASK 0x0f
+#define EDCF_AIFSN_MAX 15
+#define EDCF_ECWMAX_MASK 0xf0
+
/* Keep BRCMF_ESCAN_BUF_SIZE below 64K (65536). Allocing over 64K can be
* problematic on some systems and should be avoided.
*/
@@ -86,6 +103,15 @@
#define BRCMF_VIF_EVENT_TIMEOUT msecs_to_jiffies(1500)
+#define BRCMF_PM_WAIT_MAXRETRY 100
+
+/* cfg80211 wowlan definitions */
+#define WL_WOWLAN_MAX_PATTERNS 8
+#define WL_WOWLAN_MIN_PATTERN_LEN 1
+#define WL_WOWLAN_MAX_PATTERN_LEN 255
+#define WL_WOWLAN_PKT_FILTER_ID_FIRST 201
+#define WL_WOWLAN_PKT_FILTER_ID_LAST (WL_WOWLAN_PKT_FILTER_ID_FIRST + \
+ WL_WOWLAN_MAX_PATTERNS - 1)
/**
* enum brcmf_scan_status - scan engine status
*
@@ -156,6 +182,13 @@ enum brcmf_vif_status {
BRCMF_VIF_STATUS_ASSOC_SUCCESS,
};
+enum brcmf_cfg80211_pm_state {
+ BRCMF_CFG80211_PM_STATE_RESUMED,
+ BRCMF_CFG80211_PM_STATE_RESUMING,
+ BRCMF_CFG80211_PM_STATE_SUSPENDED,
+ BRCMF_CFG80211_PM_STATE_SUSPENDING,
+};
+
/**
* struct vif_saved_ie - holds saved IEs for a virtual interface.
*
@@ -214,6 +247,12 @@ struct brcmf_cfg80211_assoc_ielen_le {
__le32 resp_len;
};
+struct brcmf_cfg80211_edcf_acparam {
+ u8 ACI;
+ u8 ECW;
+ u16 TXOP; /* stored in network order (ls octet first) */
+};
+
/* dongle escan state */
enum wl_escan_state {
WL_ESCAN_STATE_IDLE,
@@ -335,6 +374,8 @@ struct brcmf_cfg80211_info {
struct brcmf_assoclist_le assoclist;
struct brcmf_cfg80211_wowl wowl;
struct brcmf_pno_info *pno;
+ u8 ac_priority[MAX_8021D_PRIO];
+ u8 pm_state;
};
/**
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c
index c5d1a1cbf601..a62acf76f258 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c
@@ -165,6 +165,7 @@ struct sbconfig {
#define SRCI_LSS_MASK 0x00f00000
#define SRCI_LSS_SHIFT 20
#define SRCI_SRNB_MASK 0xf0
+#define SRCI_SRNB_MASK_EXT 0x100
#define SRCI_SRNB_SHIFT 4
#define SRCI_SRBSZ_MASK 0xf
#define SRCI_SRBSZ_SHIFT 0
@@ -443,11 +444,25 @@ static void brcmf_chip_ai_resetcore(struct brcmf_core_priv *core, u32 prereset,
{
struct brcmf_chip_priv *ci;
int count;
+ struct brcmf_core *d11core2 = NULL;
+ struct brcmf_core_priv *d11priv2 = NULL;
ci = core->chip;
+ /* special handle two D11 cores reset */
+ if (core->pub.id == BCMA_CORE_80211) {
+ d11core2 = brcmf_chip_get_d11core(&ci->pub, 1);
+ if (d11core2) {
+ brcmf_dbg(INFO, "found two d11 cores, reset both\n");
+ d11priv2 = container_of(d11core2, struct brcmf_core_priv,
+ pub);
+ }
+ }
+
/* must disable first to work for arbitrary current core state */
brcmf_chip_ai_coredisable(core, prereset, reset);
+ if (d11priv2)
+ brcmf_chip_ai_coredisable(d11priv2, prereset, reset);
count = 0;
while (ci->ops->read32(ci->ctx, core->wrapbase + BCMA_RESET_CTL) &
@@ -459,9 +474,30 @@ static void brcmf_chip_ai_resetcore(struct brcmf_core_priv *core, u32 prereset,
usleep_range(40, 60);
}
+ if (d11priv2) {
+ count = 0;
+ while (ci->ops->read32(ci->ctx,
+ d11priv2->wrapbase + BCMA_RESET_CTL) &
+ BCMA_RESET_CTL_RESET) {
+ ci->ops->write32(ci->ctx,
+ d11priv2->wrapbase + BCMA_RESET_CTL,
+ 0);
+ count++;
+ if (count > 50)
+ break;
+ usleep_range(40, 60);
+ }
+ }
+
ci->ops->write32(ci->ctx, core->wrapbase + BCMA_IOCTL,
postreset | BCMA_IOCTL_CLK);
ci->ops->read32(ci->ctx, core->wrapbase + BCMA_IOCTL);
+
+ if (d11priv2) {
+ ci->ops->write32(ci->ctx, d11priv2->wrapbase + BCMA_IOCTL,
+ postreset | BCMA_IOCTL_CLK);
+ ci->ops->read32(ci->ctx, d11priv2->wrapbase + BCMA_IOCTL);
+ }
}
static char *brcmf_chip_name(uint chipid, char *buf, uint len)
@@ -592,7 +628,13 @@ static void brcmf_chip_socram_ramsize(struct brcmf_core_priv *sr, u32 *ramsize,
if (lss != 0)
*ramsize += (1 << ((lss - 1) + SR_BSZ_BASE));
} else {
- nb = (coreinfo & SRCI_SRNB_MASK) >> SRCI_SRNB_SHIFT;
+ /* length of SRAM Banks increased for corerev greater than 23 */
+ if (sr->pub.rev >= 23) {
+ nb = (coreinfo & (SRCI_SRNB_MASK | SRCI_SRNB_MASK_EXT))
+ >> SRCI_SRNB_SHIFT;
+ } else {
+ nb = (coreinfo & SRCI_SRNB_MASK) >> SRCI_SRNB_SHIFT;
+ }
for (i = 0; i < nb; i++) {
retent = brcmf_chip_socram_banksize(sr, i, &banksize);
*ramsize += banksize;
@@ -1112,6 +1154,21 @@ void brcmf_chip_detach(struct brcmf_chip *pub)
kfree(chip);
}
+struct brcmf_core *brcmf_chip_get_d11core(struct brcmf_chip *pub, u8 unit)
+{
+ struct brcmf_chip_priv *chip;
+ struct brcmf_core_priv *core;
+
+ chip = container_of(pub, struct brcmf_chip_priv, pub);
+ list_for_each_entry(core, &chip->cores, list) {
+ if (core->pub.id == BCMA_CORE_80211) {
+ if (unit-- == 0)
+ return &core->pub;
+ }
+ }
+ return NULL;
+}
+
struct brcmf_core *brcmf_chip_get_core(struct brcmf_chip *pub, u16 coreid)
{
struct brcmf_chip_priv *chip;
@@ -1322,7 +1379,7 @@ bool brcmf_chip_set_active(struct brcmf_chip *pub, u32 rstvec)
bool brcmf_chip_sr_capable(struct brcmf_chip *pub)
{
- u32 base, addr, reg, pmu_cc3_mask = ~0;
+ u32 base, addr, reg, sr_eng_en, pmu_cc3_mask = ~0;
struct brcmf_chip_priv *chip;
struct brcmf_core *pmu = brcmf_chip_get_pmu(pub);
@@ -1338,6 +1395,7 @@ bool brcmf_chip_sr_capable(struct brcmf_chip *pub)
switch (pub->chip) {
case BRCM_CC_4354_CHIP_ID:
case BRCM_CC_4356_CHIP_ID:
+ case BRCM_CC_4345_CHIP_ID:
/* explicitly check SR engine enable bit */
pmu_cc3_mask = BIT(2);
/* fall-through */
@@ -1354,6 +1412,17 @@ bool brcmf_chip_sr_capable(struct brcmf_chip *pub)
addr = CORE_CC_REG(base, sr_control1);
reg = chip->ops->read32(chip->ctx, addr);
return reg != 0;
+ case CY_CC_4373_CHIP_ID:
+ /* explicitly check SR engine enable bit */
+ sr_eng_en = BIT(0);
+ addr = CORE_CC_REG(base, sr_control0);
+ reg = chip->ops->read32(chip->ctx, addr);
+ return (reg & sr_eng_en) != 0;
+ case CY_CC_43012_CHIP_ID:
+ addr = CORE_CC_REG(pmu->base, retention_ctl);
+ reg = chip->ops->read32(chip->ctx, addr);
+ return (reg & (PMU_RCTL_MACPHY_DISABLE_MASK |
+ PMU_RCTL_LOGIC_DISABLE_MASK)) == 0;
default:
addr = CORE_CC_REG(pmu->base, pmucapabilities_ext);
reg = chip->ops->read32(chip->ctx, addr);
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.h
index dd0ec3eba6a9..fe80270d856c 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.h
@@ -86,6 +86,7 @@ void brcmf_chip_detach(struct brcmf_chip *chip);
struct brcmf_core *brcmf_chip_get_core(struct brcmf_chip *chip, u16 coreid);
struct brcmf_core *brcmf_chip_get_chipcommon(struct brcmf_chip *chip);
struct brcmf_core *brcmf_chip_get_pmu(struct brcmf_chip *pub);
+struct brcmf_core *brcmf_chip_get_d11core(struct brcmf_chip *pub, u8 unit);
bool brcmf_chip_iscoreup(struct brcmf_core *core);
void brcmf_chip_coredisable(struct brcmf_core *core, u32 prereset, u32 reset);
void brcmf_chip_resetcore(struct brcmf_core *core, u32 prereset, u32 reset,
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
index 7a2b49587b4d..7ca24d5e1b5b 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
@@ -18,6 +18,7 @@
#include <linux/string.h>
#include <linux/netdevice.h>
#include <linux/module.h>
+#include <linux/firmware.h>
#include <brcmu_wifi.h>
#include <brcmu_utils.h>
#include "core.h"
@@ -28,6 +29,7 @@
#include "tracepoint.h"
#include "common.h"
#include "of.h"
+#include "firmware.h"
MODULE_AUTHOR("Broadcom Corporation");
MODULE_DESCRIPTION("Broadcom 802.11 wireless LAN fullmac driver.");
@@ -73,6 +75,14 @@ static int brcmf_roamoff;
module_param_named(roamoff, brcmf_roamoff, int, S_IRUSR);
MODULE_PARM_DESC(roamoff, "Do not use internal roaming engine");
+static int brcmf_eap_restrict;
+module_param_named(eap_restrict, brcmf_eap_restrict, int, 0400);
+MODULE_PARM_DESC(eap_restrict, "Block non-802.1X frames until auth finished");
+
+static int brcmf_sdio_wq_highpri;
+module_param_named(sdio_wq_highpri, brcmf_sdio_wq_highpri, int, 0);
+MODULE_PARM_DESC(sdio_wq_highpri, "SDIO workqueue is set to high priority");
+
#ifdef DEBUG
/* always succeed brcmf_bus_started() */
static int brcmf_ignore_probe_fail;
@@ -104,16 +114,141 @@ void brcmf_c_set_joinpref_default(struct brcmf_if *ifp)
brcmf_err("Set join_pref error (%d)\n", err);
}
+static int brcmf_c_download(struct brcmf_if *ifp, u16 flag,
+ struct brcmf_dload_data_le *dload_buf,
+ u32 len)
+{
+ s32 err;
+
+ flag |= (DLOAD_HANDLER_VER << DLOAD_FLAG_VER_SHIFT);
+ dload_buf->flag = cpu_to_le16(flag);
+ dload_buf->dload_type = cpu_to_le16(DL_TYPE_CLM);
+ dload_buf->len = cpu_to_le32(len);
+ dload_buf->crc = cpu_to_le32(0);
+ len = sizeof(*dload_buf) + len - 1;
+
+ err = brcmf_fil_iovar_data_set(ifp, "clmload", dload_buf, len);
+
+ return err;
+}
+
+static int brcmf_c_get_clm_name(struct brcmf_if *ifp, u8 *clm_name)
+{
+ struct brcmf_bus *bus = ifp->drvr->bus_if;
+ struct brcmf_rev_info *ri = &ifp->drvr->revinfo;
+ u8 fw_name[BRCMF_FW_NAME_LEN];
+ u8 *ptr;
+ size_t len;
+ s32 err;
+
+ memset(fw_name, 0, BRCMF_FW_NAME_LEN);
+ err = brcmf_bus_get_fwname(bus, ri->chipnum, ri->chiprev, fw_name);
+ if (err) {
+ brcmf_err("get firmware name failed (%d)\n", err);
+ goto done;
+ }
+
+ /* generate CLM blob file name */
+ ptr = strrchr(fw_name, '.');
+ if (!ptr) {
+ err = -ENOENT;
+ goto done;
+ }
+
+ len = ptr - fw_name + 1;
+ if (len + strlen(".clm_blob") > BRCMF_FW_NAME_LEN) {
+ err = -E2BIG;
+ } else {
+ strlcpy(clm_name, fw_name, len);
+ strlcat(clm_name, ".clm_blob", BRCMF_FW_NAME_LEN);
+ }
+done:
+ return err;
+}
+
+static int brcmf_c_process_clm_blob(struct brcmf_if *ifp)
+{
+ struct device *dev = ifp->drvr->bus_if->dev;
+ struct brcmf_dload_data_le *chunk_buf;
+ const struct firmware *clm = NULL;
+ u8 clm_name[BRCMF_FW_NAME_LEN];
+ u32 chunk_len;
+ u32 datalen;
+ u32 cumulative_len;
+ u16 dl_flag = DL_BEGIN;
+ u32 status;
+ s32 err;
+
+ brcmf_dbg(TRACE, "Enter\n");
+
+ memset(clm_name, 0, BRCMF_FW_NAME_LEN);
+ err = brcmf_c_get_clm_name(ifp, clm_name);
+ if (err) {
+ brcmf_err("get CLM blob file name failed (%d)\n", err);
+ return err;
+ }
+
+ err = request_firmware(&clm, clm_name, dev);
+ if (err) {
+ brcmf_info("no clm_blob available(err=%d), device may have limited channels available\n",
+ err);
+ return 0;
+ }
+
+ chunk_buf = kzalloc(sizeof(*chunk_buf) + MAX_CHUNK_LEN - 1, GFP_KERNEL);
+ if (!chunk_buf) {
+ err = -ENOMEM;
+ goto done;
+ }
+
+ datalen = clm->size;
+ cumulative_len = 0;
+ do {
+ if (datalen > MAX_CHUNK_LEN) {
+ chunk_len = MAX_CHUNK_LEN;
+ } else {
+ chunk_len = datalen;
+ dl_flag |= DL_END;
+ }
+ memcpy(chunk_buf->data, clm->data + cumulative_len, chunk_len);
+
+ err = brcmf_c_download(ifp, dl_flag, chunk_buf, chunk_len);
+
+ dl_flag &= ~DL_BEGIN;
+
+ cumulative_len += chunk_len;
+ datalen -= chunk_len;
+ } while ((datalen > 0) && (err == 0));
+
+ if (err) {
+ brcmf_err("clmload (%zu byte file) failed (%d); ",
+ clm->size, err);
+ /* Retrieve clmload_status and print */
+ err = brcmf_fil_iovar_int_get(ifp, "clmload_status", &status);
+ if (err)
+ brcmf_err("get clmload_status failed (%d)\n", err);
+ else
+ brcmf_dbg(INFO, "clmload_status=%d\n", status);
+ err = -EIO;
+ }
+
+ kfree(chunk_buf);
+done:
+ release_firmware(clm);
+ return err;
+}
+
int brcmf_c_preinit_dcmds(struct brcmf_if *ifp)
{
s8 eventmask[BRCMF_EVENTING_MASK_LEN];
u8 buf[BRCMF_DCMD_SMLEN];
struct brcmf_rev_info_le revinfo;
struct brcmf_rev_info *ri;
+ char *clmver;
char *ptr;
s32 err;
- /* retreive mac address */
+ /* retrieve mac addresses */
err = brcmf_fil_iovar_data_get(ifp, "cur_etheraddr", ifp->mac_addr,
sizeof(ifp->mac_addr));
if (err < 0) {
@@ -148,6 +283,13 @@ int brcmf_c_preinit_dcmds(struct brcmf_if *ifp)
}
ri->result = err;
+ /* Do any CLM downloading */
+ err = brcmf_c_process_clm_blob(ifp);
+ if (err < 0) {
+ brcmf_err("download CLM blob file failed, %d\n", err);
+ goto done;
+ }
+
/* query for 'ver' to get version info from firmware */
memset(buf, 0, sizeof(buf));
strcpy(buf, "ver");
@@ -167,6 +309,26 @@ int brcmf_c_preinit_dcmds(struct brcmf_if *ifp)
ptr = strrchr(buf, ' ') + 1;
strlcpy(ifp->drvr->fwver, ptr, sizeof(ifp->drvr->fwver));
+ /* Query for 'clmver' to get CLM version info from firmware */
+ memset(buf, 0, sizeof(buf));
+ err = brcmf_fil_iovar_data_get(ifp, "clmver", buf, sizeof(buf));
+ if (err) {
+ brcmf_dbg(TRACE, "retrieving clmver failed, %d\n", err);
+ } else {
+ clmver = (char *)buf;
+ /* store CLM version for adding it to revinfo debugfs file */
+ memcpy(ifp->drvr->clmver, clmver, sizeof(ifp->drvr->clmver));
+
+ /* Replace all newline/linefeed characters with space
+ * character
+ */
+ ptr = clmver;
+ while ((ptr = strnchr(ptr, '\n', sizeof(buf))) != NULL)
+ *ptr = ' ';
+
+ brcmf_dbg(INFO, "CLM version = %s\n", clmver);
+ }
+
/* set mpc */
err = brcmf_fil_iovar_int_set(ifp, "mpc", 1);
if (err) {
@@ -212,6 +374,12 @@ int brcmf_c_preinit_dcmds(struct brcmf_if *ifp)
/* Enable tx beamforming, errors can be ignored (not supported) */
(void)brcmf_fil_iovar_int_set(ifp, "txbf", 1);
+ /* add unicast packet filter */
+ err = brcmf_pktfilter_add_remove(ifp->ndev,
+ BRCMF_UNICAST_FILTER_NUM, true);
+ if (err)
+ brcmf_info("Add unicast filter error (%d)\n", err);
+
/* do bus specific preinit here */
err = brcmf_bus_preinit(ifp->drvr->bus_if);
done:
@@ -282,11 +450,13 @@ struct brcmf_mp_device *brcmf_get_module_param(struct device *dev,
if (!settings)
return NULL;
- /* start by using the module paramaters */
+ /* start by using the module parameters */
settings->p2p_enable = !!brcmf_p2p_enable;
settings->feature_disable = brcmf_feature_disable;
settings->fcmode = brcmf_fcmode;
settings->roamoff = !!brcmf_roamoff;
+ settings->eap_restrict = !!brcmf_eap_restrict;
+ settings->sdio_wq_highpri = !!brcmf_sdio_wq_highpri;
#ifdef DEBUG
settings->ignore_probe_fail = !!brcmf_ignore_probe_fail;
#endif
@@ -297,6 +467,7 @@ struct brcmf_mp_device *brcmf_get_module_param(struct device *dev,
/* See if there is any device specific platform data configured */
found = false;
if (brcmfmac_pdata) {
+ pinctrl_pm_select_default_state(brcmfmac_pdata->dev);
for (i = 0; i < brcmfmac_pdata->device_count; i++) {
device_pd = &brcmfmac_pdata->devices[i];
if ((device_pd->bus_type == bus_type) &&
@@ -329,10 +500,30 @@ void brcmf_release_module_param(struct brcmf_mp_device *module_param)
static int __init brcmf_common_pd_probe(struct platform_device *pdev)
{
+ int err;
+ struct brcmfmac_platform_data pdata = {
+ .power_on = NULL,
+ .power_off = NULL,
+ .fw_alternative_path = NULL,
+ .device_count = 0,
+ };
+
brcmf_dbg(INFO, "Enter\n");
brcmfmac_pdata = dev_get_platdata(&pdev->dev);
+ if (!brcmfmac_pdata) {
+ err = platform_device_add_data(pdev, &pdata,
+ sizeof(pdata));
+ if (err)
+ brcmf_err("platform data allocation failed\n");
+ brcmfmac_pdata = dev_get_platdata(&pdev->dev);
+ pinctrl_pm_select_idle_state(&pdev->dev);
+ }
+
+ if (!brcmfmac_pdata)
+ return 0;
+ brcmfmac_pdata->dev = &pdev->dev;
if (brcmfmac_pdata->power_on)
brcmfmac_pdata->power_on();
@@ -343,7 +534,7 @@ static int brcmf_common_pd_remove(struct platform_device *pdev)
{
brcmf_dbg(INFO, "Enter\n");
- if (brcmfmac_pdata->power_off)
+ if (brcmfmac_pdata && brcmfmac_pdata->power_off)
brcmfmac_pdata->power_off();
return 0;
@@ -368,7 +559,7 @@ static int __init brcmfmac_module_init(void)
if (err == -ENODEV)
brcmf_dbg(INFO, "No platform data available.\n");
- /* Initialize global module paramaters */
+ /* Initialize global module parameters */
brcmf_mp_attach();
/* Continue the initialization by registering the different busses */
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h
index a62f8e70b320..f415f208db40 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h
@@ -49,6 +49,8 @@ extern struct brcmf_mp_global_t brcmf_mp_global;
* @feature_disable: Feature_disable bitmask.
* @fcmode: FWS flow control.
* @roamoff: Firmware roaming off?
+ * @eap_restrict: Not allow data tx/rx until 802.1X auth succeeds
+ * @sdio_wq_highpri: Tasks submitted to SDIO workqueue will run immediately.
* @ignore_probe_fail: Ignore probe failure.
* @country_codes: If available, pointer to struct for translating country codes
* @bus: Bus specific platform data. Only SDIO at the mmoment.
@@ -58,6 +60,9 @@ struct brcmf_mp_device {
unsigned int feature_disable;
int fcmode;
bool roamoff;
+ bool eap_restrict;
+ int sdio_dpc_prio;
+ bool sdio_wq_highpri;
bool ignore_probe_fail;
struct brcmfmac_pd_cc *country_codes;
union {
@@ -75,4 +80,8 @@ void brcmf_release_module_param(struct brcmf_mp_device *module_param);
/* Sets dongle media info (drv_version, mac address). */
int brcmf_c_preinit_dcmds(struct brcmf_if *ifp);
+u8 brcmf_map_prio_to_prec(void *cfg, u8 prio);
+
+u8 brcmf_map_prio_to_aci(void *cfg, u8 prio);
+
#endif /* BRCMFMAC_COMMON_H */
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
index bfc0e37b7f34..df3061467c57 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
@@ -371,6 +371,11 @@ void brcmf_txfinalize(struct brcmf_if *ifp, struct sk_buff *txp, bool success)
struct ethhdr *eh;
u16 type;
+ if (!ifp) {
+ brcmu_pkt_buf_free_skb(txp);
+ return;
+ }
+
eh = (struct ethhdr *)(txp->data);
type = ntohs(eh->h_proto);
@@ -414,8 +419,6 @@ static int brcmf_netdev_stop(struct net_device *ndev)
brcmf_cfg80211_down(ndev);
- brcmf_fil_iovar_data_set(ifp, "arp_hostip_clear", NULL, 0);
-
brcmf_net_setcarrier(ifp, false);
return 0;
@@ -955,6 +958,8 @@ static int brcmf_revinfo_read(struct seq_file *s, void *data)
seq_printf(s, "anarev: %u\n", ri->anarev);
seq_printf(s, "nvramrev: %08x\n", ri->nvramrev);
+ seq_printf(s, "clmver: %s\n", bus_if->drvr->clmver);
+
return 0;
}
@@ -1201,3 +1206,177 @@ void __exit brcmf_core_exit(void)
#endif
}
+int
+brcmf_pktfilter_add_remove(struct net_device *ndev, int filter_num, bool add)
+{
+ struct brcmf_if *ifp = netdev_priv(ndev);
+ struct brcmf_pub *drvr = ifp->drvr;
+ struct brcmf_pkt_filter_le *pkt_filter;
+ int filter_fixed_len = offsetof(struct brcmf_pkt_filter_le, u);
+ int pattern_fixed_len = offsetof(struct brcmf_pkt_filter_pattern_le,
+ mask_and_pattern);
+ u16 mask_and_pattern[MAX_PKTFILTER_PATTERN_SIZE];
+ int buflen = 0;
+ int ret = 0;
+
+ brcmf_dbg(INFO, "%s packet filter number %d\n",
+ (add ? "add" : "remove"), filter_num);
+
+ pkt_filter = kzalloc(sizeof(*pkt_filter) +
+ (MAX_PKTFILTER_PATTERN_SIZE * 2), GFP_ATOMIC);
+ if (!pkt_filter)
+ return -ENOMEM;
+
+ switch (filter_num) {
+ case BRCMF_UNICAST_FILTER_NUM:
+ pkt_filter->id = 100;
+ pkt_filter->type = 0;
+ pkt_filter->negate_match = 0;
+ pkt_filter->u.pattern.offset = 0;
+ pkt_filter->u.pattern.size_bytes = 1;
+ mask_and_pattern[0] = 0x0001;
+ break;
+ case BRCMF_BROADCAST_FILTER_NUM:
+ //filter_pattern = "101 0 0 0 0xFFFFFFFFFFFF 0xFFFFFFFFFFFF";
+ pkt_filter->id = 101;
+ pkt_filter->type = 0;
+ pkt_filter->negate_match = 0;
+ pkt_filter->u.pattern.offset = 0;
+ pkt_filter->u.pattern.size_bytes = 6;
+ mask_and_pattern[0] = 0xFFFF;
+ mask_and_pattern[1] = 0xFFFF;
+ mask_and_pattern[2] = 0xFFFF;
+ mask_and_pattern[3] = 0xFFFF;
+ mask_and_pattern[4] = 0xFFFF;
+ mask_and_pattern[5] = 0xFFFF;
+ break;
+ case BRCMF_MULTICAST4_FILTER_NUM:
+ //filter_pattern = "102 0 0 0 0xFFFFFF 0x01005E";
+ pkt_filter->id = 102;
+ pkt_filter->type = 0;
+ pkt_filter->negate_match = 0;
+ pkt_filter->u.pattern.offset = 0;
+ pkt_filter->u.pattern.size_bytes = 3;
+ mask_and_pattern[0] = 0xFFFF;
+ mask_and_pattern[1] = 0x01FF;
+ mask_and_pattern[2] = 0x5E00;
+ break;
+ case BRCMF_MULTICAST6_FILTER_NUM:
+ //filter_pattern = "103 0 0 0 0xFFFF 0x3333";
+ pkt_filter->id = 103;
+ pkt_filter->type = 0;
+ pkt_filter->negate_match = 0;
+ pkt_filter->u.pattern.offset = 0;
+ pkt_filter->u.pattern.size_bytes = 2;
+ mask_and_pattern[0] = 0xFFFF;
+ mask_and_pattern[1] = 0x3333;
+ break;
+ case BRCMF_MDNS_FILTER_NUM:
+ //filter_pattern = "104 0 0 0 0xFFFFFFFFFFFF 0x01005E0000FB";
+ pkt_filter->id = 104;
+ pkt_filter->type = 0;
+ pkt_filter->negate_match = 0;
+ pkt_filter->u.pattern.offset = 0;
+ pkt_filter->u.pattern.size_bytes = 6;
+ mask_and_pattern[0] = 0xFFFF;
+ mask_and_pattern[1] = 0xFFFF;
+ mask_and_pattern[2] = 0xFFFF;
+ mask_and_pattern[3] = 0x0001;
+ mask_and_pattern[4] = 0x005E;
+ mask_and_pattern[5] = 0xFB00;
+ break;
+ case BRCMF_ARP_FILTER_NUM:
+ //filter_pattern = "105 0 0 12 0xFFFF 0x0806";
+ pkt_filter->id = 105;
+ pkt_filter->type = 0;
+ pkt_filter->negate_match = 0;
+ pkt_filter->u.pattern.offset = 12;
+ pkt_filter->u.pattern.size_bytes = 2;
+ mask_and_pattern[0] = 0xFFFF;
+ mask_and_pattern[1] = 0x0608;
+ break;
+ case BRCMF_BROADCAST_ARP_FILTER_NUM:
+ //filter_pattern = "106 0 0 0
+ //0xFFFFFFFFFFFF0000000000000806
+ //0xFFFFFFFFFFFF0000000000000806";
+ pkt_filter->id = 106;
+ pkt_filter->type = 0;
+ pkt_filter->negate_match = 0;
+ pkt_filter->u.pattern.offset = 0;
+ pkt_filter->u.pattern.size_bytes = 14;
+ mask_and_pattern[0] = 0xFFFF;
+ mask_and_pattern[1] = 0xFFFF;
+ mask_and_pattern[2] = 0xFFFF;
+ mask_and_pattern[3] = 0x0000;
+ mask_and_pattern[4] = 0x0000;
+ mask_and_pattern[5] = 0x0000;
+ mask_and_pattern[6] = 0x0608;
+ mask_and_pattern[7] = 0xFFFF;
+ mask_and_pattern[8] = 0xFFFF;
+ mask_and_pattern[9] = 0xFFFF;
+ mask_and_pattern[10] = 0x0000;
+ mask_and_pattern[11] = 0x0000;
+ mask_and_pattern[12] = 0x0000;
+ mask_and_pattern[13] = 0x0608;
+ break;
+ default:
+ ret = -EINVAL;
+ goto failed;
+ }
+ memcpy(pkt_filter->u.pattern.mask_and_pattern, mask_and_pattern,
+ pkt_filter->u.pattern.size_bytes * 2);
+ buflen = filter_fixed_len + pattern_fixed_len +
+ pkt_filter->u.pattern.size_bytes * 2;
+
+ if (add) {
+ /* Add filter */
+ ret = brcmf_fil_iovar_data_set(ifp, "pkt_filter_add",
+ pkt_filter, buflen);
+ if (ret)
+ goto failed;
+ drvr->pkt_filter[filter_num].id = pkt_filter->id;
+ drvr->pkt_filter[filter_num].enable = 0;
+
+ } else {
+ /* Delete filter */
+ ret = brcmf_fil_iovar_int_set(ifp, "pkt_filter_delete",
+ pkt_filter->id);
+ if (ret == -ENOENT)
+ ret = 0;
+ if (ret)
+ goto failed;
+
+ drvr->pkt_filter[filter_num].id = 0;
+ drvr->pkt_filter[filter_num].enable = 0;
+ }
+failed:
+ if (ret)
+ brcmf_err("%s packet filter failed, ret=%d\n",
+ (add ? "add" : "remove"), ret);
+
+ kfree(pkt_filter);
+ return ret;
+}
+
+int brcmf_pktfilter_enable(struct net_device *ndev, bool enable)
+{
+ struct brcmf_if *ifp = netdev_priv(ndev);
+ struct brcmf_pub *drvr = ifp->drvr;
+ int ret = 0;
+ int idx = 0;
+
+ for (idx = 0; idx < MAX_PKT_FILTER_COUNT; ++idx) {
+ if (drvr->pkt_filter[idx].id != 0) {
+ drvr->pkt_filter[idx].enable = enable;
+ ret = brcmf_fil_iovar_data_set(ifp, "pkt_filter_enable",
+ &drvr->pkt_filter[idx],
+ sizeof(struct brcmf_pkt_filter_enable_le));
+ if (ret) {
+ brcmf_err("%s packet filter id(%d) failed, ret=%d\n",
+ (enable ? "enable" : "disable"),
+ drvr->pkt_filter[idx].id, ret);
+ }
+ }
+ }
+ return ret;
+}
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h
index a4dd313140f3..e38f78e4d92c 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h
@@ -23,6 +23,7 @@
#include <net/cfg80211.h>
#include "fweh.h"
+#include "fwil_types.h"
#define TOE_TX_CSUM_OL 0x00000001
#define TOE_RX_CSUM_OL 0x00000002
@@ -36,7 +37,7 @@
#define BRCMF_DCMD_MEDLEN 1536
#define BRCMF_DCMD_MAXLEN 8192
-/* IOCTL from host to device are limited in lenght. A device can only handle
+/* IOCTL from host to device are limited in length. A device can only handle
* ethernet frame size. This limitation is to be applied by protocol layer.
*/
#define BRCMF_TX_IOCTL_MAX_MSG_SIZE (ETH_FRAME_LEN+ETH_FCS_LEN)
@@ -141,6 +142,10 @@ struct brcmf_pub {
struct notifier_block inetaddr_notifier;
struct notifier_block inet6addr_notifier;
struct brcmf_mp_device *settings;
+
+ u8 clmver[BRCMF_DCMD_SMLEN];
+ struct brcmf_pkt_filter_enable_le pkt_filter[MAX_PKT_FILTER_COUNT];
+
};
/* forward declarations */
@@ -214,5 +219,7 @@ void brcmf_netif_rx(struct brcmf_if *ifp, struct sk_buff *skb);
void brcmf_net_setcarrier(struct brcmf_if *ifp, bool on);
int __init brcmf_core_init(void);
void __exit brcmf_core_exit(void);
-
+int brcmf_pktfilter_add_remove(struct net_device *ndev, int filter_num,
+ bool add);
+int brcmf_pktfilter_enable(struct net_device *ndev, bool enable);
#endif /* BRCMFMAC_CORE_H */
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c
index 53ae30259989..c7c3563f9a53 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c
@@ -132,11 +132,16 @@ static void brcmf_feat_iovar_data_set(struct brcmf_if *ifp,
static void brcmf_feat_firmware_capabilities(struct brcmf_if *ifp)
{
- char caps[256];
+ char caps[512];
enum brcmf_feat_id id;
- int i;
+ int i, err;
+
+ err = brcmf_fil_iovar_data_get(ifp, "cap", caps, sizeof(caps));
+ if (err) {
+ brcmf_err("could not get firmware cap (%d)\n", err);
+ return;
+ }
- brcmf_fil_iovar_data_get(ifp, "cap", caps, sizeof(caps));
brcmf_dbg(INFO, "[ %s]\n", caps);
for (i = 0; i < ARRAY_SIZE(brcmf_fwcap_map); i++) {
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil.c
index f6a2df94dba7..b839756f2891 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil.c
@@ -110,7 +110,7 @@ brcmf_fil_cmd_data(struct brcmf_if *ifp, u32 cmd, void *data, u32 len, bool set)
s32 err;
if (drvr->bus_if->state != BRCMF_BUS_UP) {
- brcmf_err("bus is down. we have nothing to do.\n");
+ brcmf_dbg(FIL, "bus is down. we have nothing to do.\n");
return -EIO;
}
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h
index e0d22fedb2b4..9616c94afb76 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h
@@ -128,6 +128,19 @@
#define BRCMF_WOWL_MAXPATTERNS 8
#define BRCMF_WOWL_MAXPATTERNSIZE 128
+enum {
+ BRCMF_UNICAST_FILTER_NUM = 0,
+ BRCMF_BROADCAST_FILTER_NUM,
+ BRCMF_MULTICAST4_FILTER_NUM,
+ BRCMF_MULTICAST6_FILTER_NUM,
+ BRCMF_MDNS_FILTER_NUM,
+ BRCMF_ARP_FILTER_NUM,
+ BRCMF_BROADCAST_ARP_FILTER_NUM,
+ MAX_PKT_FILTER_COUNT
+};
+
+#define MAX_PKTFILTER_PATTERN_SIZE 16
+
#define BRCMF_COUNTRY_BUF_SZ 4
#define BRCMF_ANT_MAX 4
@@ -155,6 +168,21 @@
#define BRCMF_MFP_CAPABLE 1
#define BRCMF_MFP_REQUIRED 2
+/* MAX_CHUNK_LEN is the maximum length for data passing to firmware in each
+ * ioctl. It is relatively small because firmware has small maximum size input
+ * playload restriction for ioctls.
+ */
+#define MAX_CHUNK_LEN 1400
+
+#define DLOAD_HANDLER_VER 1 /* Downloader version */
+#define DLOAD_FLAG_VER_MASK 0xf000 /* Downloader version mask */
+#define DLOAD_FLAG_VER_SHIFT 12 /* Downloader version shift */
+
+#define DL_BEGIN 0x0002
+#define DL_END 0x0004
+
+#define DL_TYPE_CLM 2
+
/* join preference types for join_pref iovar */
enum brcmf_join_pref_types {
BRCMF_JOIN_PREF_RSSI = 1,
@@ -827,6 +855,22 @@ struct brcmf_pno_macaddr_le {
};
/**
+ * struct brcmf_dload_data_le - data passing to firmware for downloading
+ * @flag: flags related to download data.
+ * @dload_type: type of download data.
+ * @len: length in bytes of download data.
+ * @crc: crc of download data.
+ * @data: download data.
+ */
+struct brcmf_dload_data_le {
+ __le16 flag;
+ __le16 dload_type;
+ __le32 len;
+ __le32 crc;
+ u8 data[1];
+};
+
+/**
* struct brcmf_pno_bssid_le - bssid configuration for PNO scan.
*
* @bssid: BSS network identifier.
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c
index 2370060ef980..22f68051ddb7 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c
@@ -415,7 +415,7 @@ struct brcmf_fws_mac_descriptor {
u8 traffic_lastreported_bmp;
};
-#define BRCMF_FWS_HANGER_MAXITEMS 1024
+#define BRCMF_FWS_HANGER_MAXITEMS 3072
/**
* enum brcmf_fws_hanger_item_state - state of hanger item.
@@ -511,6 +511,7 @@ struct brcmf_fws_info {
struct work_struct fws_dequeue_work;
u32 fifo_enqpkt[BRCMF_FWS_FIFO_COUNT];
int fifo_credit[BRCMF_FWS_FIFO_COUNT];
+ int init_fifo_credit[BRCMF_FWS_FIFO_COUNT];
int credits_borrowed[BRCMF_FWS_FIFO_AC_VO + 1];
int deq_node_pos[BRCMF_FWS_FIFO_COUNT];
u32 fifo_credit_map;
@@ -1241,6 +1242,9 @@ static void brcmf_fws_return_credits(struct brcmf_fws_info *fws,
}
fws->fifo_credit[fifo] += credits;
+ if (fws->fifo_credit[fifo] > fws->init_fifo_credit[fifo])
+ fws->fifo_credit[fifo] = fws->init_fifo_credit[fifo];
+
}
static void brcmf_fws_schedule_deq(struct brcmf_fws_info *fws)
@@ -1455,9 +1459,10 @@ static int brcmf_fws_txstatus_suppressed(struct brcmf_fws_info *fws, int fifo,
static int
brcmf_fws_txs_process(struct brcmf_fws_info *fws, u8 flags, u32 hslot,
- u32 genbit, u16 seq)
+ u32 genbit, u16 seq, u8 compcnt)
{
u32 fifo;
+ u8 cnt = 0;
int ret;
bool remove_from_hanger = true;
struct sk_buff *skb;
@@ -1468,60 +1473,71 @@ brcmf_fws_txs_process(struct brcmf_fws_info *fws, u8 flags, u32 hslot,
brcmf_dbg(DATA, "flags %d\n", flags);
if (flags == BRCMF_FWS_TXSTATUS_DISCARD)
- fws->stats.txs_discard++;
+ fws->stats.txs_discard += compcnt;
else if (flags == BRCMF_FWS_TXSTATUS_CORE_SUPPRESS) {
- fws->stats.txs_supp_core++;
+ fws->stats.txs_supp_core += compcnt;
remove_from_hanger = false;
} else if (flags == BRCMF_FWS_TXSTATUS_FW_PS_SUPPRESS) {
- fws->stats.txs_supp_ps++;
+ fws->stats.txs_supp_ps += compcnt;
remove_from_hanger = false;
} else if (flags == BRCMF_FWS_TXSTATUS_FW_TOSSED)
- fws->stats.txs_tossed++;
+ fws->stats.txs_tossed += compcnt;
else if (flags == BRCMF_FWS_TXSTATUS_HOST_TOSSED)
- fws->stats.txs_host_tossed++;
+ fws->stats.txs_host_tossed += compcnt;
else
brcmf_err("unexpected txstatus\n");
- ret = brcmf_fws_hanger_poppkt(&fws->hanger, hslot, &skb,
- remove_from_hanger);
- if (ret != 0) {
- brcmf_err("no packet in hanger slot: hslot=%d\n", hslot);
- return ret;
- }
+ while (cnt < compcnt) {
+ ret = brcmf_fws_hanger_poppkt(&fws->hanger, hslot, &skb,
+ remove_from_hanger);
+ if (ret != 0) {
+ brcmf_err("no packet in hanger slot: hslot=%d\n",
+ hslot);
+ goto cont;
+ }
- skcb = brcmf_skbcb(skb);
- entry = skcb->mac;
- if (WARN_ON(!entry)) {
- brcmu_pkt_buf_free_skb(skb);
- return -EINVAL;
- }
- entry->transit_count--;
- if (entry->suppressed && entry->suppr_transit_count)
- entry->suppr_transit_count--;
+ skcb = brcmf_skbcb(skb);
+ entry = skcb->mac;
+ if (WARN_ON(!entry)) {
+ brcmu_pkt_buf_free_skb(skb);
+ goto cont;
+ }
+ entry->transit_count--;
+ if (entry->suppressed && entry->suppr_transit_count)
+ entry->suppr_transit_count--;
- brcmf_dbg(DATA, "%s flags %d htod %X seq %X\n", entry->name, flags,
- skcb->htod, seq);
+ brcmf_dbg(DATA, "%s flags %d htod %X seq %X\n", entry->name,
+ flags, skcb->htod, seq);
- /* pick up the implicit credit from this packet */
- fifo = brcmf_skb_htod_tag_get_field(skb, FIFO);
- if ((fws->fcmode == BRCMF_FWS_FCMODE_IMPLIED_CREDIT) ||
- (brcmf_skb_if_flags_get_field(skb, REQ_CREDIT)) ||
- (flags == BRCMF_FWS_TXSTATUS_HOST_TOSSED)) {
- brcmf_fws_return_credits(fws, fifo, 1);
- brcmf_fws_schedule_deq(fws);
- }
- brcmf_fws_macdesc_return_req_credit(skb);
+ /* pick up the implicit credit from this packet */
+ fifo = brcmf_skb_htod_tag_get_field(skb, FIFO);
+ if ((fws->fcmode == BRCMF_FWS_FCMODE_IMPLIED_CREDIT) ||
+ (brcmf_skb_if_flags_get_field(skb, REQ_CREDIT)) ||
+ (flags == BRCMF_FWS_TXSTATUS_HOST_TOSSED)) {
+ brcmf_fws_return_credits(fws, fifo, 1);
+ brcmf_fws_schedule_deq(fws);
+ }
+ brcmf_fws_macdesc_return_req_credit(skb);
- ret = brcmf_proto_hdrpull(fws->drvr, false, skb, &ifp);
- if (ret) {
- brcmu_pkt_buf_free_skb(skb);
- return -EINVAL;
+ ret = brcmf_proto_hdrpull(fws->drvr, false, skb, &ifp);
+ if (ret) {
+ brcmu_pkt_buf_free_skb(skb);
+ goto cont;
+ }
+ if (!remove_from_hanger)
+ ret = brcmf_fws_txstatus_suppressed(fws, fifo, skb,
+ genbit, seq);
+ if (remove_from_hanger || ret)
+ brcmf_txfinalize(ifp, skb, true);
+
+cont:
+ hslot = (hslot + 1) & (BRCMF_FWS_TXSTAT_HSLOT_MASK >>
+ BRCMF_FWS_TXSTAT_HSLOT_SHIFT);
+ if (BRCMF_FWS_MODE_GET_REUSESEQ(fws->mode))
+ seq = (seq + 1) & BRCMF_SKB_HTOD_SEQ_NR_MASK;
+
+ cnt++;
}
- if (!remove_from_hanger)
- ret = brcmf_fws_txstatus_suppressed(fws, fifo, skb,
- genbit, seq);
- if (remove_from_hanger || ret)
- brcmf_txfinalize(ifp, skb, true);
return 0;
}
@@ -1547,7 +1563,8 @@ static int brcmf_fws_fifocreditback_indicate(struct brcmf_fws_info *fws,
return BRCMF_FWS_RET_OK_SCHEDULE;
}
-static int brcmf_fws_txstatus_indicate(struct brcmf_fws_info *fws, u8 *data)
+static int brcmf_fws_txstatus_indicate(struct brcmf_fws_info *fws, u8 type,
+ u8 *data)
{
__le32 status_le;
__le16 seq_le;
@@ -1556,23 +1573,31 @@ static int brcmf_fws_txstatus_indicate(struct brcmf_fws_info *fws, u8 *data)
u32 genbit;
u8 flags;
u16 seq;
+ u8 compcnt;
+ u8 compcnt_offset = BRCMF_FWS_TYPE_TXSTATUS_LEN;
- fws->stats.txs_indicate++;
memcpy(&status_le, data, sizeof(status_le));
status = le32_to_cpu(status_le);
flags = brcmf_txstatus_get_field(status, FLAGS);
hslot = brcmf_txstatus_get_field(status, HSLOT);
genbit = brcmf_txstatus_get_field(status, GENERATION);
if (BRCMF_FWS_MODE_GET_REUSESEQ(fws->mode)) {
- memcpy(&seq_le, &data[BRCMF_FWS_TYPE_PKTTAG_LEN],
+ memcpy(&seq_le, &data[BRCMF_FWS_TYPE_TXSTATUS_LEN],
sizeof(seq_le));
seq = le16_to_cpu(seq_le);
+ compcnt_offset += BRCMF_FWS_TYPE_SEQ_LEN;
} else {
seq = 0;
}
+ if (type == BRCMF_FWS_TYPE_COMP_TXSTATUS)
+ compcnt = data[compcnt_offset];
+ else
+ compcnt = 1;
+ fws->stats.txs_indicate += compcnt;
+
brcmf_fws_lock(fws);
- brcmf_fws_txs_process(fws, flags, hslot, genbit, seq);
+ brcmf_fws_txs_process(fws, flags, hslot, genbit, seq, compcnt);
brcmf_fws_unlock(fws);
return BRCMF_FWS_RET_OK_NOSCHEDULE;
}
@@ -1599,19 +1624,21 @@ static int brcmf_fws_notify_credit_map(struct brcmf_if *ifp,
brcmf_err("event payload too small (%d)\n", e->datalen);
return -EINVAL;
}
- if (fws->creditmap_received)
- return 0;
fws->creditmap_received = true;
brcmf_dbg(TRACE, "enter: credits %pM\n", credits);
brcmf_fws_lock(fws);
for (i = 0; i < ARRAY_SIZE(fws->fifo_credit); i++) {
- if (*credits)
+ fws->fifo_credit[i] += credits[i] - fws->init_fifo_credit[i];
+ fws->init_fifo_credit[i] = credits[i];
+ if (fws->fifo_credit[i] > 0)
fws->fifo_credit_map |= 1 << i;
else
fws->fifo_credit_map &= ~(1 << i);
- fws->fifo_credit[i] = *credits++;
+ if (fws->fifo_credit[i] < 0)
+ brcmf_err("fifo_credit[%d] value is negative(%d)\n",
+ i, fws->fifo_credit[i]);
}
brcmf_fws_schedule_deq(fws);
brcmf_fws_unlock(fws);
@@ -1845,6 +1872,9 @@ void brcmf_fws_hdrpull(struct brcmf_if *ifp, s16 siglen, struct sk_buff *skb)
WARN_ON(siglen > skb->len);
+ if (siglen > skb->len)
+ siglen = skb->len;
+
if (!siglen)
return;
/* if flow control disabled, skip to packet data and leave */
@@ -1886,8 +1916,6 @@ void brcmf_fws_hdrpull(struct brcmf_if *ifp, s16 siglen, struct sk_buff *skb)
err = BRCMF_FWS_RET_OK_NOSCHEDULE;
switch (type) {
- case BRCMF_FWS_TYPE_COMP_TXSTATUS:
- break;
case BRCMF_FWS_TYPE_HOST_REORDER_RXPKTS:
rd = (struct brcmf_skb_reorder_data *)skb->cb;
rd->reorder = data;
@@ -1910,7 +1938,8 @@ void brcmf_fws_hdrpull(struct brcmf_if *ifp, s16 siglen, struct sk_buff *skb)
err = brcmf_fws_request_indicate(fws, type, data);
break;
case BRCMF_FWS_TYPE_TXSTATUS:
- brcmf_fws_txstatus_indicate(fws, data);
+ case BRCMF_FWS_TYPE_COMP_TXSTATUS:
+ brcmf_fws_txstatus_indicate(fws, type, data);
break;
case BRCMF_FWS_TYPE_FIFO_CREDITBACK:
err = brcmf_fws_fifocreditback_indicate(fws, data);
@@ -1999,7 +2028,7 @@ static void brcmf_fws_rollback_toq(struct brcmf_fws_info *fws,
fws->stats.rollback_failed++;
hslot = brcmf_skb_htod_tag_get_field(skb, HSLOT);
brcmf_fws_txs_process(fws, BRCMF_FWS_TXSTATUS_HOST_TOSSED,
- hslot, 0, 0);
+ hslot, 0, 0, 1);
} else {
fws->stats.rollback_success++;
brcmf_fws_return_credits(fws, fifo, 1);
@@ -2017,7 +2046,7 @@ static int brcmf_fws_borrow_credit(struct brcmf_fws_info *fws)
}
for (lender_ac = 0; lender_ac <= BRCMF_FWS_FIFO_AC_VO; lender_ac++) {
- if (fws->fifo_credit[lender_ac]) {
+ if (fws->fifo_credit[lender_ac] > 0) {
fws->credits_borrowed[lender_ac]++;
fws->fifo_credit[lender_ac]--;
if (fws->fifo_credit[lender_ac] == 0)
@@ -2096,6 +2125,7 @@ static int brcmf_fws_assign_htod(struct brcmf_fws_info *fws, struct sk_buff *p,
int brcmf_fws_process_skb(struct brcmf_if *ifp, struct sk_buff *skb)
{
+ struct brcmf_pub *drvr = ifp->drvr;
struct brcmf_fws_info *fws = drvr_to_fws(ifp->drvr);
struct brcmf_skbuff_cb *skcb = brcmf_skbcb(skb);
struct ethhdr *eh = (struct ethhdr *)(skb->data);
@@ -2109,8 +2139,10 @@ int brcmf_fws_process_skb(struct brcmf_if *ifp, struct sk_buff *skb)
skcb->if_flags = 0;
skcb->state = BRCMF_FWS_SKBSTATE_NEW;
brcmf_skb_if_flags_set_field(skb, INDEX, ifp->ifidx);
+
+ /* mapping from 802.1d priority to firmware fifo index */
if (!multicast)
- fifo = brcmf_fws_prio2fifo[skb->priority];
+ fifo = brcmf_map_prio_to_aci(drvr->config, skb->priority);
brcmf_fws_lock(fws);
if (fifo != BRCMF_FWS_FIFO_AC_BE && fifo < BRCMF_FWS_FIFO_BCMC)
@@ -2216,8 +2248,9 @@ static void brcmf_fws_dequeue_worker(struct work_struct *worker)
}
continue;
}
- while ((fws->fifo_credit[fifo]) || ((!fws->bcmc_credit_check) &&
- (fifo == BRCMF_FWS_FIFO_BCMC))) {
+ while ((fws->fifo_credit[fifo] > 0) ||
+ ((!fws->bcmc_credit_check) &&
+ (fifo == BRCMF_FWS_FIFO_BCMC))) {
skb = brcmf_fws_deq(fws, fifo);
if (!skb)
break;
@@ -2228,7 +2261,7 @@ static void brcmf_fws_dequeue_worker(struct work_struct *worker)
break;
}
if ((fifo == BRCMF_FWS_FIFO_AC_BE) &&
- (fws->fifo_credit[fifo] == 0) &&
+ (fws->fifo_credit[fifo] <= 0) &&
(!fws->bus_flow_blocked)) {
while (brcmf_fws_borrow_credit(fws) == 0) {
skb = brcmf_fws_deq(fws, fifo);
@@ -2321,7 +2354,7 @@ struct brcmf_fws_info *brcmf_fws_attach(struct brcmf_pub *drvr)
struct brcmf_if *ifp;
u32 tlv = BRCMF_FWS_FLAGS_RSSI_SIGNALS;
int rc;
- u32 mode;
+ u32 mode = 0;
fws = kzalloc(sizeof(*fws), GFP_KERNEL);
if (!fws) {
@@ -2458,7 +2491,8 @@ void brcmf_fws_bustxfail(struct brcmf_fws_info *fws, struct sk_buff *skb)
}
brcmf_fws_lock(fws);
hslot = brcmf_skb_htod_tag_get_field(skb, HSLOT);
- brcmf_fws_txs_process(fws, BRCMF_FWS_TXSTATUS_HOST_TOSSED, hslot, 0, 0);
+ brcmf_fws_txs_process(fws, BRCMF_FWS_TXSTATUS_HOST_TOSSED, hslot, 0, 0,
+ 1);
brcmf_fws_unlock(fws);
}
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c
index aee6e5937c41..fb19ab792f81 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c
@@ -30,14 +30,22 @@ void brcmf_of_probe(struct device *dev, enum brcmf_bus_type bus_type,
struct device_node *np = dev->of_node;
int irq;
u32 irqf;
- u32 val;
+ u32 val32;
+ u16 val16;
if (!np || bus_type != BRCMF_BUSTYPE_SDIO ||
!of_device_is_compatible(np, "brcm,bcm4329-fmac"))
return;
- if (of_property_read_u32(np, "brcm,drive-strength", &val) == 0)
- sdio->drive_strength = val;
+ if (of_property_read_u32(np, "brcm,drive-strength", &val32) == 0)
+ sdio->drive_strength = val32;
+
+ sdio->broken_sg_support = of_property_read_bool(np,
+ "brcm,broken_sg_support");
+ if (of_property_read_u16(np, "brcm,sd_head_align", &val16) == 0)
+ sdio->sd_head_align = val16;
+ if (of_property_read_u16(np, "brcm,sd_sgentry_align", &val16) == 0)
+ sdio->sd_sgentry_align = val16;
/* make sure there are interrupts defined in the node */
if (!of_find_property(np, "interrupts", NULL))
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c
index 4a883f4bbf88..52016373dce7 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c
@@ -467,10 +467,21 @@ static int brcmf_p2p_set_firmware(struct brcmf_if *ifp, u8 *p2p_mac)
*/
static void brcmf_p2p_generate_bss_mac(struct brcmf_p2p_info *p2p, u8 *dev_addr)
{
+ struct brcmf_if *pri_ifp = p2p->bss_idx[P2PAPI_BSSCFG_PRIMARY].vif->ifp;
bool random_addr = false;
+ bool local_admin = false;
- if (!dev_addr || is_zero_ether_addr(dev_addr))
- random_addr = true;
+ if (!dev_addr || is_zero_ether_addr(dev_addr)) {
+ /* If the primary interface address is already locally
+ * administered, create a new random address.
+ */
+ if (pri_ifp->mac_addr[0] & 0x02) {
+ random_addr = true;
+ } else {
+ dev_addr = pri_ifp->mac_addr;
+ local_admin = true;
+ }
+ }
/* Generate the P2P Device Address obtaining a random ethernet
* address with the locally administered bit set.
@@ -480,6 +491,9 @@ static void brcmf_p2p_generate_bss_mac(struct brcmf_p2p_info *p2p, u8 *dev_addr)
else
memcpy(p2p->dev_addr, dev_addr, ETH_ALEN);
+ if (local_admin)
+ p2p->dev_addr[0] |= 0x02;
+
/* Generate the P2P Interface Address. If the discovery and connection
* BSSCFGs need to simultaneously co-exist, then this address must be
* different from the P2P Device Address, but also locally administered.
@@ -1498,6 +1512,7 @@ static s32 brcmf_p2p_tx_action_frame(struct brcmf_p2p_info *p2p,
struct brcmf_fil_af_params_le *af_params)
{
struct brcmf_cfg80211_vif *vif;
+ struct brcmf_p2p_action_frame *p2p_act_frame;
s32 err = 0;
s32 timeout = 0;
@@ -1507,7 +1522,13 @@ static s32 brcmf_p2p_tx_action_frame(struct brcmf_p2p_info *p2p,
clear_bit(BRCMF_P2P_STATUS_ACTION_TX_COMPLETED, &p2p->status);
clear_bit(BRCMF_P2P_STATUS_ACTION_TX_NOACK, &p2p->status);
- vif = p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif;
+ /* check if it is a p2p_presence response */
+ p2p_act_frame = (struct brcmf_p2p_action_frame *) af_params->action_frame.data;
+ if (p2p_act_frame->subtype == P2P_AF_PRESENCE_RSP)
+ vif = p2p->bss_idx[P2PAPI_BSSCFG_CONNECTION].vif;
+ else
+ vif = p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif;
+
err = brcmf_fil_bsscfg_data_set(vif->ifp, "actframe", af_params,
sizeof(*af_params));
if (err) {
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
index e6e9b00b79d7..ed72c928151f 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
@@ -39,6 +39,7 @@
#include "chip.h"
#include "core.h"
#include "common.h"
+#include "cfg80211.h"
enum brcmf_pcie_state {
@@ -78,7 +79,7 @@ static struct brcmf_firmware_mapping brcmf_pcie_fwnames[] = {
BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4371_CHIP_ID, 0xFFFFFFFF, 4371),
};
-#define BRCMF_PCIE_FW_UP_TIMEOUT 2000 /* msec */
+#define BRCMF_PCIE_FW_UP_TIMEOUT 5000 /* msec */
#define BRCMF_PCIE_REG_MAP_SIZE (32 * 1024)
@@ -184,7 +185,7 @@ static struct brcmf_firmware_mapping brcmf_pcie_fwnames[] = {
#define BRCMF_H2D_HOST_D0_INFORM_IN_USE 0x00000008
#define BRCMF_H2D_HOST_D0_INFORM 0x00000010
-#define BRCMF_PCIE_MBDATA_TIMEOUT msecs_to_jiffies(2000)
+#define BRCMF_PCIE_MBDATA_TIMEOUT msecs_to_jiffies(5000)
#define BRCMF_PCIE_CFGREG_STATUS_CMD 0x4
#define BRCMF_PCIE_CFGREG_PM_CSR 0x4C
@@ -671,7 +672,6 @@ brcmf_pcie_send_mb_data(struct brcmf_pciedev_info *devinfo, u32 htod_mb_data)
brcmf_pcie_write_tcm32(devinfo, addr, htod_mb_data);
pci_write_config_dword(devinfo->pdev, BRCMF_PCIE_REG_SBMBX, 1);
- pci_write_config_dword(devinfo->pdev, BRCMF_PCIE_REG_SBMBX, 1);
return 0;
}
@@ -1350,6 +1350,24 @@ static int brcmf_pcie_get_memdump(struct device *dev, void *data, size_t len)
return 0;
}
+static int brcmf_pcie_get_fwname(struct device *dev, u32 chip, u32 chiprev,
+ u8 *fw_name)
+{
+ struct brcmf_bus *bus_if = dev_get_drvdata(dev);
+ struct brcmf_pciedev *buspub = bus_if->bus_priv.pcie;
+ struct brcmf_pciedev_info *devinfo = buspub->devinfo;
+ int ret = 0;
+
+ if (devinfo->fw_name[0] != '\0')
+ strlcpy(fw_name, devinfo->fw_name, BRCMF_FW_NAME_LEN);
+ else
+ ret = brcmf_fw_map_chip_to_name(chip, chiprev,
+ brcmf_pcie_fwnames,
+ ARRAY_SIZE(brcmf_pcie_fwnames),
+ fw_name, NULL);
+
+ return ret;
+}
static const struct brcmf_bus_ops brcmf_pcie_bus_ops = {
.txdata = brcmf_pcie_tx,
@@ -1359,6 +1377,7 @@ static const struct brcmf_bus_ops brcmf_pcie_bus_ops = {
.wowl_config = brcmf_pcie_wowl_config,
.get_ramsize = brcmf_pcie_get_ramsize,
.get_memdump = brcmf_pcie_get_memdump,
+ .get_fwname = brcmf_pcie_get_fwname,
};
@@ -1869,11 +1888,22 @@ static int brcmf_pcie_pm_enter_D3(struct device *dev)
{
struct brcmf_pciedev_info *devinfo;
struct brcmf_bus *bus;
+ struct brcmf_cfg80211_info *config;
+ int retry = BRCMF_PM_WAIT_MAXRETRY;
brcmf_dbg(PCIE, "Enter\n");
bus = dev_get_drvdata(dev);
devinfo = bus->bus_priv.pcie->devinfo;
+ config = bus->drvr->config;
+
+ while (retry &&
+ config->pm_state == BRCMF_CFG80211_PM_STATE_SUSPENDING) {
+ usleep_range(10000, 20000);
+ retry--;
+ }
+ if (!retry && config->pm_state == BRCMF_CFG80211_PM_STATE_SUSPENDING)
+ brcmf_err("timed out wait for cfg80211 suspended\n");
brcmf_bus_change_state(bus, BRCMF_BUS_DOWN);
@@ -1913,6 +1943,7 @@ static int brcmf_pcie_pm_leave_D3(struct device *dev)
if (brcmf_pcie_send_mb_data(devinfo, BRCMF_H2D_HOST_D0_INFORM))
goto cleanup;
brcmf_dbg(PCIE, "Hot resume, continue....\n");
+ msleep(10);
devinfo->state = BRCMFMAC_PCIE_STATE_UP;
brcmf_pcie_select_core(devinfo, BCMA_CORE_PCIE2);
brcmf_bus_change_state(bus, BRCMF_BUS_UP);
@@ -1953,6 +1984,7 @@ static const struct dev_pm_ops brcmf_pciedrvr_pm = {
static const struct pci_device_id brcmf_pcie_devid_table[] = {
BRCMF_PCIE_DEVICE(BRCM_PCIE_4350_DEVICE_ID),
+ BRCMF_PCIE_DEVICE_SUB(BRCM_PCIE_4355_DEVICE_ID,BRCM_PCIE_VENDOR_ID_BROADCOM,BRCM_PCIE_4355_DEVICE_ID),
BRCMF_PCIE_DEVICE(BRCM_PCIE_4356_DEVICE_ID),
BRCMF_PCIE_DEVICE(BRCM_PCIE_43567_DEVICE_ID),
BRCMF_PCIE_DEVICE(BRCM_PCIE_43570_DEVICE_ID),
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.c
index ffa243e2e2d0..55974a43796a 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.c
@@ -496,6 +496,11 @@ int brcmf_pno_stop_sched_scan(struct brcmf_if *ifp, u64 reqid)
brcmf_dbg(TRACE, "reqid=%llu\n", reqid);
pi = ifp_to_pno(ifp);
+
+ /* No PNO reqeuset */
+ if (!pi->n_reqs)
+ return 0;
+
err = brcmf_pno_remove_request(pi, reqid);
if (err)
return err;
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
index 4c28b04ea605..c363e4f598d2 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
@@ -45,10 +45,22 @@
#include "core.h"
#include "common.h"
#include "bcdc.h"
+#include "fwil.h"
#define DCMD_RESP_TIMEOUT msecs_to_jiffies(2500)
#define CTL_DONE_TIMEOUT msecs_to_jiffies(2500)
-
+#define ULP_HUDI_PROC_DONE_TIME msecs_to_jiffies(2500)
+
+#define DEFAULT_F2_WATERMARK 0x8
+#define CY_4373_F2_WATERMARK 0x40
+#define CY_43012_F2_WATERMARK 0x60
+#define CY_43455_F2_WATERMARK 0x60
+#define CY_43455_MES_WATERMARK 0x50
+#define CY_43455_MESBUSYCTRL (CY_43455_MES_WATERMARK | \
+ SBSDIO_MESBUSYCTRL_ENAB)
+#define CY_4339_F2_WATERMARK 48
+#define CY_4339_MES_WATERMARK 80
+#define CY_4339_MESBUSYCTRL (CY_4339_MES_WATERMARK | SBSDIO_MESBUSYCTRL_ENAB)
#ifdef DEBUG
#define BRCMF_TRAP_INFO_SIZE 80
@@ -138,6 +150,8 @@ struct rte_console {
/* 1: isolate internal sdio signals, put external pads in tri-state; requires
* sdio bus power cycle to clear (rev 9) */
#define SBSDIO_DEVCTL_PADS_ISO 0x08
+/* 1: enable F2 Watermark */
+#define SBSDIO_DEVCTL_F2WM_ENAB 0x10
/* Force SD->SB reset mapping (rev 11) */
#define SBSDIO_DEVCTL_SB_RST_CTL 0x30
/* Determined by CoreControl bit */
@@ -316,14 +330,9 @@ struct rte_console {
#define MAX_KSO_ATTEMPTS (PMU_MAX_TRANSITION_DLY/KSO_WAIT_US)
#define BRCMF_SDIO_MAX_ACCESS_ERRORS 5
-/*
- * Conversion of 802.1D priority to precedence level
- */
-static uint prio2prec(u32 prio)
-{
- return (prio == PRIO_8021D_NONE || prio == PRIO_8021D_BE) ?
- (prio^2) : prio;
-}
+static void brcmf_sdio_firmware_callback(struct device *dev, int err,
+ const struct firmware *code,
+ void *nvram, u32 nvram_len);
#ifdef DEBUG
/* Device console log buffer state */
@@ -619,6 +628,7 @@ BRCMF_FW_NVRAM_DEF(43455, "brcmfmac43455-sdio.bin", "brcmfmac43455-sdio.txt");
BRCMF_FW_NVRAM_DEF(4354, "brcmfmac4354-sdio.bin", "brcmfmac4354-sdio.txt");
BRCMF_FW_NVRAM_DEF(4356, "brcmfmac4356-sdio.bin", "brcmfmac4356-sdio.txt");
BRCMF_FW_NVRAM_DEF(4373, "brcmfmac4373-sdio.bin", "brcmfmac4373-sdio.txt");
+BRCMF_FW_NVRAM_DEF(43012, "brcmfmac43012-sdio.bin", "brcmfmac43012-sdio.txt");
static struct brcmf_firmware_mapping brcmf_sdio_fwnames[] = {
BRCMF_FW_NVRAM_ENTRY(BRCM_CC_43143_CHIP_ID, 0xFFFFFFFF, 43143),
@@ -638,7 +648,8 @@ static struct brcmf_firmware_mapping brcmf_sdio_fwnames[] = {
BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4345_CHIP_ID, 0xFFFFFFC0, 43455),
BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4354_CHIP_ID, 0xFFFFFFFF, 4354),
BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4356_CHIP_ID, 0xFFFFFFFF, 4356),
- BRCMF_FW_NVRAM_ENTRY(CY_CC_4373_CHIP_ID, 0xFFFFFFFF, 4373)
+ BRCMF_FW_NVRAM_ENTRY(CY_CC_4373_CHIP_ID, 0xFFFFFFFF, 4373),
+ BRCMF_FW_NVRAM_ENTRY(CY_CC_43012_CHIP_ID, 0xFFFFFFFF, 43012)
};
static void pkt_align(struct sk_buff *p, int len, int align)
@@ -699,6 +710,15 @@ brcmf_sdio_kso_control(struct brcmf_sdio *bus, bool on)
brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_FUNC1_SLEEPCSR,
wr_val, &err);
+ /* In case of 43012 chip, the chip could go down immediately after
+ * KSO bit is cleared. So the further reads of KSO register could
+ * fail. Thereby just bailing out immediately after clearing KSO
+ * bit, to avoid polling of KSO bit.
+ */
+ if (!on && (bus->ci->chip == CY_CC_43012_CHIP_ID)) {
+ return err;
+ }
+
if (on) {
/* device WAKEUP through KSO:
* write bit 0 & read back until
@@ -2313,6 +2333,7 @@ static uint brcmf_sdio_sendfromq(struct brcmf_sdio *bus, uint maxframes)
&prec_out);
if (pkt == NULL)
break;
+ skb_orphan(pkt);
__skb_queue_tail(&pktq, pkt);
}
spin_unlock_bh(&bus->txq_lock);
@@ -2442,9 +2463,20 @@ static void brcmf_sdio_bus_stop(struct device *dev)
/* Force backplane clocks to assure F2 interrupt propagates */
saveclk = brcmf_sdiod_regrb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR,
&err);
- if (!err)
- brcmf_sdiod_regwb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR,
- (saveclk | SBSDIO_FORCE_HT), &err);
+ if (!err) {
+ if (bus->ci->chip == CY_CC_43012_CHIP_ID) {
+ brcmf_sdiod_regwb(sdiodev,
+ SBSDIO_FUNC1_CHIPCLKCSR,
+ (saveclk |
+ SBSDIO_HT_AVAIL_REQ),
+ &err);
+ } else {
+ brcmf_sdiod_regwb(sdiodev,
+ SBSDIO_FUNC1_CHIPCLKCSR,
+ (saveclk | SBSDIO_FORCE_HT),
+ &err);
+ }
+ }
if (err)
brcmf_err("Failed to force clock for F2: err %d\n",
err);
@@ -2521,6 +2553,149 @@ static int brcmf_sdio_intr_rstatus(struct brcmf_sdio *bus)
return ret;
}
+/* This Function is used to retrieve important
+ * details from dongle related to ULP mode Mostly
+ * values/SHM details that will be vary depending
+ * on the firmware branches
+ */
+static void
+brcmf_sdio_ulp_preinit(struct device *dev)
+{
+ struct brcmf_bus *bus_if = dev_get_drvdata(dev);
+ struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
+ struct brcmf_if *ifp = bus_if->drvr->iflist[0];
+ s32 err = 0;
+
+ brcmf_dbg(TRACE, "Enter\n");
+
+ /* Query ulp_sdioctrl iovar to get the ULP related SHM offsets */
+ err = brcmf_fil_iovar_data_get(ifp, "ulp_sdioctrl", &sdiodev->shm_ulp,
+ sizeof(sdiodev->shm_ulp));
+ if (err)
+ brcmf_err("ulp_sdioctrl iovar returned err = %d\n", err);
+
+ sdiodev->ulp = false;
+
+ brcmf_dbg(TRACE, "m_ulp_ctrl_sdio[%x] m_ulp_wakeevt_ind [%x]\n",
+ M_DS1_CTRL_SDIO(sdiodev->shm_ulp),
+ M_WAKEEVENT_IND(sdiodev->shm_ulp));
+ brcmf_dbg(TRACE, "m_ulp_wakeind [%x]\n",
+ M_ULP_WAKE_IND(sdiodev->shm_ulp));
+}
+
+/* Reinitialize ARM because In DS1 mode ARM got off */
+static int
+brcmf_sdio_ulp_reinit_fw(struct brcmf_sdio *bus)
+{
+ struct brcmf_sdio_dev *sdiodev = bus->sdiodev;
+ int err = 0;
+
+ /* After firmware redownload tx/rx seq are reset accordingly
+ * these values are reset on FMAC side tx_max is initially set to 4,
+ * which later is updated by FW.
+ */
+ bus->tx_seq = 0;
+ bus->rx_seq = 0;
+ bus->tx_max = 4;
+
+ err = brcmf_fw_get_firmwares(sdiodev->dev, BRCMF_FW_REQUEST_NVRAM,
+ sdiodev->fw_name, sdiodev->nvram_name,
+ brcmf_sdio_firmware_callback);
+ if (err != 0)
+ brcmf_err("async firmware request failed: %d\n", err);
+ return err;
+}
+
+/* Check if device is in DS1 mode and handshake with ULP UCODE */
+static bool
+brcmf_sdio_ulp_pre_redownload_check(struct brcmf_sdio *bus)
+{
+ int err = 0;
+ u32 value = 0;
+ u32 val32, ulp_wake_ind, wowl_wake_ind;
+ int reg_addr;
+ unsigned long timeout;
+
+ value = brcmf_sdiod_regrb(bus->sdiodev, SDIO_CCCR_IOEx, &err);
+
+ if (value == SDIO_FUNC_ENABLE_1) {
+ brcmf_dbg(SDIO, "GOT THE INTERRUPT FROM UCODE\n");
+ bus->sdiodev->ulp = true;
+ ulp_wake_ind = D11SHM_RD(bus->sdiodev, M_ULP_WAKE_IND(
+ bus->sdiodev->shm_ulp), &err) >> 16;
+ wowl_wake_ind = D11SHM_RD(bus->sdiodev, M_WAKEEVENT_IND(
+ bus->sdiodev->shm_ulp), &err) >> 16;
+
+ brcmf_dbg(SDIO, "wowl_wake_ind: 0x%08x, ulp_wake_ind: 0x%08x\n",
+ wowl_wake_ind, ulp_wake_ind);
+
+ if (wowl_wake_ind || ulp_wake_ind) {
+ /* TX wake Don't do anything.
+ * Just bail out and re-download firmware.
+ */
+ } else {
+ /* RX wake negotiate with MAC */
+ brcmf_dbg(SDIO, "M_DS1_CTRL_SDIO: 0x%08x\n",
+ (u32)D11SHM_RD(bus->sdiodev,
+ M_DS1_CTRL_SDIO(bus->sdiodev->shm_ulp),
+ &err));
+ D11SHM_WR(bus->sdiodev, M_DS1_CTRL_SDIO(
+ bus->sdiodev->shm_ulp),
+ C_DS1_CTRL_SDIO_DS1_EXIT |
+ C_DS1_CTRL_REQ_VALID,
+ &err);
+ val32 = D11REG_RD(bus->sdiodev,
+ D11_MACCONTROL_REG, &err);
+ val32 = val32 | D11_MACCONTROL_REG_WAKE;
+ D11REG_WR(bus->sdiodev,
+ D11_MACCONTROL_REG, val32, &err);
+
+ /* Poll for PROC_DONE to be set by ucode */
+ value = D11SHM_RD(bus->sdiodev,
+ M_DS1_CTRL_SDIO(
+ bus->sdiodev->shm_ulp), &err);
+ /* Wait here (polling) for C_DS1_CTRL_PROC_DONE */
+ timeout = jiffies + ULP_HUDI_PROC_DONE_TIME;
+ while (!(value & C_DS1_CTRL_PROC_DONE)) {
+ value = D11SHM_RD(bus->sdiodev,
+ M_DS1_CTRL_SDIO(
+ bus->sdiodev->shm_ulp), &err);
+ if (time_after(jiffies, timeout))
+ break;
+ usleep_range(1000, 2000);
+ }
+ brcmf_dbg(SDIO, "M_DS1_CTRL_SDIO: 0x%08x\n",
+ (u32)D11SHM_RD(bus->sdiodev,
+ M_DS1_CTRL_SDIO(
+ bus->sdiodev->shm_ulp), &err));
+ value = D11SHM_RD(bus->sdiodev,
+ M_DS1_CTRL_SDIO(
+ bus->sdiodev->shm_ulp), &err);
+ if (!(value & C_DS1_CTRL_PROC_DONE)) {
+ brcmf_err("%s: timeout Failed to enter DS1 Exit state!\n",
+ __func__);
+ return false;
+ }
+ }
+ ulp_wake_ind = D11SHM_RD(bus->sdiodev, M_ULP_WAKE_IND(
+ bus->sdiodev->shm_ulp), &err) >> 16;
+ wowl_wake_ind = D11SHM_RD(bus->sdiodev, M_WAKEEVENT_IND(
+ bus->sdiodev->shm_ulp), &err) >> 16;
+ brcmf_dbg(SDIO, "wowl_wake_ind: 0x%08x, ulp_wake_ind: 0x%08x\n",
+ wowl_wake_ind, ulp_wake_ind);
+ reg_addr = CORE_CC_REG(
+ brcmf_chip_get_pmu(bus->ci)->base, min_res_mask);
+ brcmf_sdiod_regwl(bus->sdiodev, reg_addr,
+ DEFAULT_43012_MIN_RES_MASK, &err);
+ if (err)
+ brcmf_err("min_res_mask failed\n");
+
+ return true;
+ }
+
+ return false;
+}
+
static void brcmf_sdio_dpc(struct brcmf_sdio *bus)
{
u32 newstatus = 0;
@@ -2593,6 +2768,8 @@ static void brcmf_sdio_dpc(struct brcmf_sdio *bus)
if (intstatus & I_HMB_HOST_INT) {
intstatus &= ~I_HMB_HOST_INT;
intstatus |= brcmf_sdio_hostmail(bus);
+ if (brcmf_sdio_ulp_pre_redownload_check(bus))
+ brcmf_sdio_ulp_reinit_fw(bus);
}
sdio_release_host(bus->sdiodev->func[1]);
@@ -2747,7 +2924,13 @@ static int brcmf_sdio_bus_txdata(struct device *dev, struct sk_buff *pkt)
skb_push(pkt, bus->tx_hdrlen);
/* precondition: IS_ALIGNED((unsigned long)(pkt->data), 2) */
- prec = prio2prec((pkt->priority & PRIOMASK));
+ /* In WLAN, priority is always set by the AP using WMM parameters
+ * and this need not always follow the standard 802.1d priority.
+ * Based on AP WMM config, map from 802.1d priority to corresponding
+ * precedence level.
+ */
+ prec = brcmf_map_prio_to_prec(bus_if->drvr->config,
+ (pkt->priority & PRIOMASK));
/* Check for existing queue, current flow-control,
pending event, or pending clock */
@@ -3338,34 +3521,50 @@ static void brcmf_sdio_sr_init(struct brcmf_sdio *bus)
{
int err = 0;
u8 val;
+ u8 wakeupctrl;
+ u8 cardcap;
+ u8 chipclkcsr;
brcmf_dbg(TRACE, "Enter\n");
+ if (bus->ci->chip == CY_CC_43012_CHIP_ID) {
+ wakeupctrl = SBSDIO_FUNC1_WCTRL_ALPWAIT_SHIFT;
+ chipclkcsr = SBSDIO_HT_AVAIL_REQ;
+ } else {
+ wakeupctrl = SBSDIO_FUNC1_WCTRL_HTWAIT_SHIFT;
+ chipclkcsr = SBSDIO_FORCE_HT;
+ }
+
+ if (bus->ci->chip == CY_CC_43012_CHIP_ID ||
+ bus->ci->chip == BRCM_CC_4339_CHIP_ID ||
+ bus->ci->chip == BRCM_CC_4354_CHIP_ID ||
+ bus->ci->chip == BRCM_CC_4345_CHIP_ID) {
+ cardcap = SDIO_CCCR_BRCM_CARDCAP_CMD_NODEC;
+ } else {
+ cardcap = (SDIO_CCCR_BRCM_CARDCAP_CMD14_SUPPORT |
+ SDIO_CCCR_BRCM_CARDCAP_CMD14_EXT);
+ }
+
val = brcmf_sdiod_regrb(bus->sdiodev, SBSDIO_FUNC1_WAKEUPCTRL, &err);
if (err) {
brcmf_err("error reading SBSDIO_FUNC1_WAKEUPCTRL\n");
return;
}
-
- val |= 1 << SBSDIO_FUNC1_WCTRL_HTWAIT_SHIFT;
+ val |= 1 << wakeupctrl;
brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_FUNC1_WAKEUPCTRL, val, &err);
if (err) {
brcmf_err("error writing SBSDIO_FUNC1_WAKEUPCTRL\n");
return;
}
-
- /* Add CMD14 Support */
brcmf_sdiod_regwb(bus->sdiodev, SDIO_CCCR_BRCM_CARDCAP,
- (SDIO_CCCR_BRCM_CARDCAP_CMD14_SUPPORT |
- SDIO_CCCR_BRCM_CARDCAP_CMD14_EXT),
+ cardcap,
&err);
if (err) {
brcmf_err("error writing SDIO_CCCR_BRCM_CARDCAP\n");
return;
}
-
brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR,
- SBSDIO_FORCE_HT, &err);
+ chipclkcsr, &err);
if (err) {
brcmf_err("error writing SBSDIO_FUNC1_CHIPCLKCSR\n");
return;
@@ -3439,6 +3638,10 @@ static int brcmf_sdio_bus_preinit(struct device *dev)
if (err < 0)
goto done;
+ /* initialize SHM address from firmware for DS1 */
+ if (!bus->sdiodev->ulp)
+ brcmf_sdio_ulp_preinit(dev);
+
bus->tx_hdrlen = SDPCM_HWHDR_LEN + SDPCM_SWHDR_LEN;
if (sdiodev->sg_support) {
bus->txglom = false;
@@ -3979,6 +4182,24 @@ brcmf_sdio_watchdog(unsigned long data)
}
}
+static int brcmf_sdio_get_fwname(struct device *dev, u32 chip, u32 chiprev,
+ u8 *fw_name)
+{
+ struct brcmf_bus *bus_if = dev_get_drvdata(dev);
+ struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
+ int ret = 0;
+
+ if (sdiodev->fw_name[0] != '\0')
+ strlcpy(fw_name, sdiodev->fw_name, BRCMF_FW_NAME_LEN);
+ else
+ ret = brcmf_fw_map_chip_to_name(chip, chiprev,
+ brcmf_sdio_fwnames,
+ ARRAY_SIZE(brcmf_sdio_fwnames),
+ fw_name, NULL);
+
+ return ret;
+}
+
static const struct brcmf_bus_ops brcmf_sdio_bus_ops = {
.stop = brcmf_sdio_bus_stop,
.preinit = brcmf_sdio_bus_preinit,
@@ -3989,6 +4210,7 @@ static const struct brcmf_bus_ops brcmf_sdio_bus_ops = {
.wowl_config = brcmf_sdio_wowl_config,
.get_ramsize = brcmf_sdio_bus_get_ramsize,
.get_memdump = brcmf_sdio_bus_get_memdump,
+ .get_fwname = brcmf_sdio_get_fwname,
};
static void brcmf_sdio_firmware_callback(struct device *dev, int err,
@@ -3999,6 +4221,7 @@ static void brcmf_sdio_firmware_callback(struct device *dev, int err,
struct brcmf_sdio_dev *sdiodev;
struct brcmf_sdio *bus;
u8 saveclk;
+ u8 devctl;
brcmf_dbg(TRACE, "Enter: dev=%s, err=%d\n", dev_name(dev), err);
bus_if = dev_get_drvdata(dev);
@@ -4032,8 +4255,14 @@ static void brcmf_sdio_firmware_callback(struct device *dev, int err,
/* Force clocks on backplane to be sure F2 interrupt propagates */
saveclk = brcmf_sdiod_regrb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, &err);
if (!err) {
- brcmf_sdiod_regwb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR,
- (saveclk | SBSDIO_FORCE_HT), &err);
+ if (bus->ci->chip == CY_CC_43012_CHIP_ID) {
+ brcmf_sdiod_regwb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR,
+ (saveclk | SBSDIO_HT_AVAIL_REQ),
+ &err);
+ } else {
+ brcmf_sdiod_regwb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR,
+ (saveclk | SBSDIO_FORCE_HT), &err);
+ }
}
if (err) {
brcmf_err("Failed to force clock for F2: err %d\n", err);
@@ -4054,8 +4283,56 @@ static void brcmf_sdio_firmware_callback(struct device *dev, int err,
bus->hostintmask = HOSTINTMASK;
w_sdreg32(bus, bus->hostintmask,
offsetof(struct sdpcmd_regs, hostintmask));
-
- brcmf_sdiod_regwb(sdiodev, SBSDIO_WATERMARK, 8, &err);
+ switch (sdiodev->func[0]->device) {
+ case SDIO_DEVICE_ID_CYPRESS_4373:
+ brcmf_dbg(INFO, "set F2 watermark to 0x%x*4 bytes\n",
+ CY_4373_F2_WATERMARK);
+ brcmf_sdiod_regwb(sdiodev, SBSDIO_WATERMARK, CY_4373_F2_WATERMARK, &err);
+ devctl = brcmf_sdiod_regrb(sdiodev, SBSDIO_DEVICE_CTL, &err);
+ devctl |= SBSDIO_DEVCTL_F2WM_ENAB;
+ brcmf_sdiod_regwb(sdiodev, SBSDIO_DEVICE_CTL, devctl, &err);
+ break;
+ case SDIO_DEVICE_ID_CYPRESS_43012:
+ brcmf_dbg(INFO, "set F2 watermark to 0x%x*4 bytes for 43012\n",
+ CY_43012_F2_WATERMARK);
+ brcmf_sdiod_regwb(sdiodev,
+ SBSDIO_WATERMARK,
+ CY_43012_F2_WATERMARK, &err);
+ devctl = brcmf_sdiod_regrb(sdiodev,
+ SBSDIO_DEVICE_CTL, &err);
+ devctl |= SBSDIO_DEVCTL_F2WM_ENAB;
+ brcmf_sdiod_regwb(sdiodev,
+ SBSDIO_DEVICE_CTL, devctl, &err);
+ break;
+ case SDIO_DEVICE_ID_BROADCOM_43455:
+ brcmf_dbg(INFO, "set F2 watermark to 0x%x*4 bytes for 43455\n",
+ CY_43455_F2_WATERMARK);
+ brcmf_sdiod_regwb(sdiodev, SBSDIO_WATERMARK,
+ CY_43455_F2_WATERMARK, &err);
+ devctl = brcmf_sdiod_regrb(sdiodev, SBSDIO_DEVICE_CTL,
+ &err);
+ devctl |= SBSDIO_DEVCTL_F2WM_ENAB;
+ brcmf_sdiod_regwb(sdiodev, SBSDIO_DEVICE_CTL, devctl,
+ &err);
+ brcmf_sdiod_regwb(sdiodev, SBSDIO_FUNC1_MESBUSYCTRL,
+ CY_43455_MESBUSYCTRL, &err);
+ break;
+ case SDIO_DEVICE_ID_BROADCOM_4339:
+ brcmf_sdiod_regwb(sdiodev,
+ SBSDIO_WATERMARK,
+ CY_4339_F2_WATERMARK, &err);
+ devctl = brcmf_sdiod_regrb(sdiodev,
+ SBSDIO_DEVICE_CTL, &err);
+ devctl |= SBSDIO_DEVCTL_F2WM_ENAB;
+ brcmf_sdiod_regwb(sdiodev,
+ SBSDIO_DEVICE_CTL, devctl, &err);
+ brcmf_sdiod_regwb(sdiodev,
+ SBSDIO_FUNC1_MESBUSYCTRL, CY_4339_MESBUSYCTRL, &err);
+ break;
+ default:
+ brcmf_sdiod_regwb(sdiodev, SBSDIO_WATERMARK, DEFAULT_F2_WATERMARK, &err);
+ break;
+ }
} else {
/* Disable F2 again */
sdio_disable_func(sdiodev->func[SDIO_FUNC_2]);
@@ -4085,11 +4362,18 @@ static void brcmf_sdio_firmware_callback(struct device *dev, int err,
sdio_release_host(sdiodev->func[1]);
- err = brcmf_bus_started(dev);
- if (err != 0) {
- brcmf_err("dongle is not responding\n");
- goto fail;
+ /* Waking up from deep sleep don't requirerd to reint the sdio bus
+ * as all sdiod core registers will get restored by Firmware using
+ * FCBS engine.
+ */
+ if (!bus->sdiodev->ulp) {
+ err = brcmf_bus_started(dev);
+ if (err != 0) {
+ brcmf_err("dongle is not responding\n");
+ goto fail;
+ }
}
+
return;
release:
@@ -4121,9 +4405,21 @@ struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev)
bus->txminmax = BRCMF_TXMINMAX;
bus->tx_seq = SDPCM_SEQ_WRAP - 1;
+ /* attempt to attach to the dongle */
+ if (!(brcmf_sdio_probe_attach(bus))) {
+ brcmf_err("brcmf_sdio_probe_attach failed\n");
+ goto fail;
+ }
+
/* single-threaded workqueue */
- wq = alloc_ordered_workqueue("brcmf_wq/%s", WQ_MEM_RECLAIM,
- dev_name(&sdiodev->func[1]->dev));
+ if (sdiodev->settings->sdio_wq_highpri) {
+ wq = alloc_workqueue("brcmf_wq/%s",
+ WQ_HIGHPRI | WQ_MEM_RECLAIM | WQ_UNBOUND,
+ 1, dev_name(&sdiodev->func[1]->dev));
+ } else {
+ wq = alloc_ordered_workqueue("brcmf_wq/%s", WQ_MEM_RECLAIM,
+ dev_name(&sdiodev->func[1]->dev));
+ }
if (!wq) {
brcmf_err("insufficient memory to create txworkqueue\n");
goto fail;
@@ -4132,12 +4428,6 @@ struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev)
INIT_WORK(&bus->datawork, brcmf_sdio_dataworker);
bus->brcmf_wq = wq;
- /* attempt to attach to the dongle */
- if (!(brcmf_sdio_probe_attach(bus))) {
- brcmf_err("brcmf_sdio_probe_attach failed\n");
- goto fail;
- }
-
spin_lock_init(&bus->rxctl_lock);
spin_lock_init(&bus->txq_lock);
init_waitqueue_head(&bus->ctrl_wait);
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h
index f3da32fc6360..7989980dc27f 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h
@@ -107,6 +107,8 @@
#define SBSDIO_FUNC1_RFRAMEBCHI 0x1001C
/* MesBusyCtl (rev 11) */
#define SBSDIO_FUNC1_MESBUSYCTRL 0x1001D
+/* Enable busy capability for MES access */
+#define SBSDIO_MESBUSYCTRL_ENAB 0x80
/* Sdio Core Rev 12 */
#define SBSDIO_FUNC1_WAKEUPCTRL 0x1001E
#define SBSDIO_FUNC1_WCTRL_ALPWAIT_MASK 0x1
@@ -177,6 +179,17 @@ struct brcmf_sdreg {
struct brcmf_sdio;
struct brcmf_sdiod_freezer;
+/* ULP SHM Offsets info */
+struct ulp_shm_info {
+ u32 m_ulp_ctrl_sdio;
+ u32 m_ulp_wakeevt_ind;
+ u32 m_ulp_wakeind;
+};
+
+struct fmac_ulp {
+ struct ulp_shm_info ulp_shm_offset;
+};
+
struct brcmf_sdio_dev {
struct sdio_func *func[SDIO_MAX_FUNCS];
u8 num_funcs; /* Supported funcs on client */
@@ -201,6 +214,8 @@ struct brcmf_sdio_dev {
bool wowl_enabled;
enum brcmf_sdiod_state state;
struct brcmf_sdiod_freezer *freezer;
+ struct fmac_ulp shm_ulp;
+ bool ulp;
};
/* sdio core registers */
@@ -376,4 +391,51 @@ void brcmf_sdio_wowl_config(struct device *dev, bool enabled);
int brcmf_sdio_sleep(struct brcmf_sdio *bus, bool sleep);
void brcmf_sdio_trigger_dpc(struct brcmf_sdio *bus);
+/* SHM offsets */
+#define M_DS1_CTRL_SDIO(ptr) ((ptr).ulp_shm_offset.m_ulp_ctrl_sdio)
+#define M_WAKEEVENT_IND(ptr) ((ptr).ulp_shm_offset.m_ulp_wakeevt_ind)
+#define M_ULP_WAKE_IND(ptr) ((ptr).ulp_shm_offset.m_ulp_wakeind)
+
+#define D11_BASE_ADDR 0x18001000
+#define D11_AXI_BASE_ADDR 0xE8000000
+#define D11_SHM_BASE_ADDR (D11_AXI_BASE_ADDR + 0x4000)
+
+#define D11REG_ADDR(offset) (D11_BASE_ADDR + (offset))
+#define D11IHR_ADDR(offset) (D11_AXI_BASE_ADDR + 0x400 + (2 * (offset)))
+#define D11SHM_ADDR(offset) (D11_SHM_BASE_ADDR + (offset))
+
+/* MacControl register */
+#define D11_MACCONTROL_REG D11REG_ADDR(0x120)
+#define D11_MACCONTROL_REG_WAKE 0x4000000
+
+/* Following are the offsets in M_DRVR_UCODE_IF_PTR block. Start address of
+ * M_DRVR_UCODE_IF_PTR block is present in M_DRVR_UCODE_IF_PTR.
+ */
+
+/* M_ULP_WAKE_IND bits */
+#define ULP_WAKE_IND_WATCHDOG_EXP 0x1
+#define ULP_WAKE_IND_FCBS_ERROR 0x2
+#define ULP_WAKE_IND_RE_TRANSMIT_ERR 0x4
+#define ULP_WAKE_IND_HOST_WKUP 0x8
+#define ULP_WAKE_IND_INVALID_FCBS_BLK 0x10
+
+#define C_DS1_CTRL_SDIO_DS1_SLEEP 0x1
+#define C_DS1_CTRL_SDIO_MAC_ON 0x2
+#define C_DS1_CTRL_SDIO_RADIO_PHY_ON 0x4
+#define C_DS1_CTRL_SDIO_DS1_EXIT 0x8
+#define C_DS1_CTRL_PROC_DONE 0x100
+#define C_DS1_CTRL_REQ_VALID 0x200
+
+#define D11SHM_WR(sdh, offset, val, ret) \
+ brcmf_sdiod_regwl(sdh, D11SHM_ADDR(offset), val, ret)
+
+#define D11SHM_RD(sdh, offset, ret) \
+ brcmf_sdiod_regrl(sdh, D11SHM_ADDR(offset), ret)
+
+#define D11REG_WR(sdh, addr, val, ret) \
+ brcmf_sdiod_regwl(sdh, addr, val, ret)
+
+#define D11REG_RD(sdh, addr, ret) \
+ brcmf_sdiod_regrl(sdh, addr, ret)
+
#endif /* BRCMFMAC_SDIO_H */
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c
index be855aa32154..a23764db4609 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c
@@ -30,6 +30,7 @@
#include "core.h"
#include "common.h"
#include "bcdc.h"
+#include "cfg80211.h"
#define IOCTL_RESP_TIMEOUT msecs_to_jiffies(2000)
@@ -1134,12 +1135,30 @@ static void brcmf_usb_wowl_config(struct device *dev, bool enabled)
device_set_wakeup_enable(devinfo->dev, false);
}
+static int brcmf_usb_get_fwname(struct device *dev, u32 chip, u32 chiprev,
+ u8 *fw_name)
+{
+ struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev);
+ int ret = 0;
+
+ if (devinfo->fw_name[0] != '\0')
+ strlcpy(fw_name, devinfo->fw_name, BRCMF_FW_NAME_LEN);
+ else
+ ret = brcmf_fw_map_chip_to_name(chip, chiprev,
+ brcmf_usb_fwnames,
+ ARRAY_SIZE(brcmf_usb_fwnames),
+ fw_name, NULL);
+
+ return ret;
+}
+
static const struct brcmf_bus_ops brcmf_usb_bus_ops = {
.txdata = brcmf_usb_tx,
.stop = brcmf_usb_down,
.txctl = brcmf_usb_tx_ctlpkt,
.rxctl = brcmf_usb_rx_ctlpkt,
.wowl_config = brcmf_usb_wowl_config,
+ .get_fwname = brcmf_usb_get_fwname,
};
static int brcmf_usb_bus_setup(struct brcmf_usbdev_info *devinfo)
@@ -1426,8 +1445,22 @@ static int brcmf_usb_suspend(struct usb_interface *intf, pm_message_t state)
{
struct usb_device *usb = interface_to_usbdev(intf);
struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(&usb->dev);
+ struct brcmf_bus *bus;
+ struct brcmf_cfg80211_info *config;
+ int retry = BRCMF_PM_WAIT_MAXRETRY;
brcmf_dbg(USB, "Enter\n");
+
+ bus = devinfo->bus_pub.bus;
+ config = bus->drvr->config;
+ while (retry &&
+ config->pm_state == BRCMF_CFG80211_PM_STATE_SUSPENDING) {
+ usleep_range(10000, 20000);
+ retry--;
+ }
+ if (!retry && config->pm_state == BRCMF_CFG80211_PM_STATE_SUSPENDING)
+ brcmf_err("timed out wait for cfg80211 suspended\n");
+
devinfo->bus_pub.state = BRCMFMAC_USB_STATE_SLEEP;
if (devinfo->wowl_enabled)
brcmf_cancel_all_urbs(devinfo);
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor.c
index d493021f6031..fbbdb815ff73 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor.c
@@ -81,8 +81,12 @@ static int brcmf_cfg80211_vndr_cmds_dcmd_handler(struct wiphy *wiphy,
else
ret = brcmf_fil_cmd_data_get(ifp, cmdhdr->cmd, dcmd_buf,
ret_len);
- if (ret != 0)
+
+ if (ret != 0) {
+ brcmf_dbg(INFO, "error(%d), return -EPERM\n", ret);
+ ret = -EPERM;
goto exit;
+ }
wr_pointer = dcmd_buf;
while (ret_len > 0) {
diff --git a/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h b/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h
index 57544a3a3ce4..31580360081c 100644
--- a/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h
+++ b/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h
@@ -59,6 +59,7 @@
#define BRCM_CC_4366_CHIP_ID 0x4366
#define BRCM_CC_4371_CHIP_ID 0x4371
#define CY_CC_4373_CHIP_ID 0x4373
+#define CY_CC_43012_CHIP_ID 43012
/* USB Device IDs */
#define BRCM_USB_43143_DEVICE_ID 0xbd1e
@@ -73,6 +74,7 @@
/* PCIE Device IDs */
#define BRCM_PCIE_4350_DEVICE_ID 0x43a3
#define BRCM_PCIE_4354_DEVICE_ID 0x43df
+#define BRCM_PCIE_4355_DEVICE_ID 0x4355
#define BRCM_PCIE_4356_DEVICE_ID 0x43ec
#define BRCM_PCIE_43567_DEVICE_ID 0x43d3
#define BRCM_PCIE_43570_DEVICE_ID 0x43d9
diff --git a/drivers/net/wireless/broadcom/brcm80211/include/brcmu_wifi.h b/drivers/net/wireless/broadcom/brcm80211/include/brcmu_wifi.h
index 75b2a0438cfa..dddebaa60352 100644
--- a/drivers/net/wireless/broadcom/brcm80211/include/brcmu_wifi.h
+++ b/drivers/net/wireless/broadcom/brcm80211/include/brcmu_wifi.h
@@ -239,6 +239,7 @@ static inline bool ac_bitmap_tst(u8 bitmap, int prec)
#define WPA2_AUTH_RESERVED4 0x0400
#define WPA2_AUTH_RESERVED5 0x0800
#define WPA2_AUTH_1X_SHA256 0x1000 /* 1X with SHA256 key derivation */
+#define WPA2_AUTH_FT 0x4000 /* Fast BSS Transition */
#define WPA2_AUTH_PSK_SHA256 0x8000 /* PSK with SHA256 key derivation */
#define DOT11_DEFAULT_RTS_LEN 2347
diff --git a/drivers/net/wireless/broadcom/brcm80211/include/chipcommon.h b/drivers/net/wireless/broadcom/brcm80211/include/chipcommon.h
index e1fd499930a0..1f23092cdad9 100644
--- a/drivers/net/wireless/broadcom/brcm80211/include/chipcommon.h
+++ b/drivers/net/wireless/broadcom/brcm80211/include/chipcommon.h
@@ -298,6 +298,8 @@ struct chipcregs {
* Maximum delay for the PMU state transition in us.
* This is an upper bound intended for spinwaits etc.
*/
-#define PMU_MAX_TRANSITION_DLY 15000
+#define PMU_MAX_TRANSITION_DLY 15000
+
+#define DEFAULT_43012_MIN_RES_MASK 0x0f8bfe77
#endif /* _SBCHIPC_H */
diff --git a/drivers/nvme/target/io-cmd.c b/drivers/nvme/target/io-cmd.c
index 0d4c23dc4532..db632818777d 100644
--- a/drivers/nvme/target/io-cmd.c
+++ b/drivers/nvme/target/io-cmd.c
@@ -94,7 +94,7 @@ static void nvmet_execute_rw(struct nvmet_req *req)
cookie = submit_bio(bio);
- blk_mq_poll(bdev_get_queue(req->ns->bdev), cookie);
+ blk_poll(bdev_get_queue(req->ns->bdev), cookie);
}
static void nvmet_execute_flush(struct nvmet_req *req)
diff --git a/drivers/nvmem/Kconfig b/drivers/nvmem/Kconfig
index 101ced4c84be..c88df4783ed2 100644
--- a/drivers/nvmem/Kconfig
+++ b/drivers/nvmem/Kconfig
@@ -26,7 +26,19 @@ config NVMEM_IMX_IIM
config NVMEM_IMX_OCOTP
tristate "i.MX6 On-Chip OTP Controller support"
- depends on SOC_IMX6 || COMPILE_TEST
+ depends on SOC_IMX6 || ARCH_MXC_ARM64 || COMPILE_TEST
+ depends on HAS_IOMEM
+ help
+ This is a driver for the On-Chip OTP Controller (OCOTP) available on
+ i.MX6 SoCs, providing access to 4 Kbits of one-time programmable
+ eFuses.
+
+ This driver can also be built as a module. If so, the module
+ will be called nvmem-imx-ocotp.
+
+config NVMEM_IMX_SCU_OCOTP
+ tristate "i.MX8QM On-Chip OTP Controller support"
+ depends on ARCH_MXC_ARM64|| COMPILE_TEST
depends on HAS_IOMEM
help
This is a driver for the On-Chip OTP Controller (OCOTP) available on
diff --git a/drivers/nvmem/Makefile b/drivers/nvmem/Makefile
index 6f7a77fb3ee7..9ebfab960256 100644
--- a/drivers/nvmem/Makefile
+++ b/drivers/nvmem/Makefile
@@ -13,6 +13,8 @@ obj-$(CONFIG_NVMEM_IMX_IIM) += nvmem-imx-iim.o
nvmem-imx-iim-y := imx-iim.o
obj-$(CONFIG_NVMEM_IMX_OCOTP) += nvmem-imx-ocotp.o
nvmem-imx-ocotp-y := imx-ocotp.o
+obj-$(CONFIG_NVMEM_IMX_SCU_OCOTP) += nvmem-imx-scu-ocotp.o
+nvmem-imx-scu-ocotp-y := imx-scu-ocotp.o
obj-$(CONFIG_NVMEM_LPC18XX_EEPROM) += nvmem_lpc18xx_eeprom.o
nvmem_lpc18xx_eeprom-y := lpc18xx_eeprom.o
obj-$(CONFIG_NVMEM_LPC18XX_OTP) += nvmem_lpc18xx_otp.o
diff --git a/drivers/nvmem/imx-ocotp.c b/drivers/nvmem/imx-ocotp.c
index 193ca8fd350a..a4ddab73d2c9 100644
--- a/drivers/nvmem/imx-ocotp.c
+++ b/drivers/nvmem/imx-ocotp.c
@@ -3,6 +3,8 @@
*
* Copyright (c) 2015 Pengutronix, Philipp Zabel <p.zabel@pengutronix.de>
*
+ * Copyright 2017 NXP
+ *
* Based on the barebox ocotp driver,
* Copyright (c) 2010 Baruch Siach <baruch@tkos.co.il>,
* Orex Computed Radiography
@@ -114,22 +116,29 @@ static int imx_ocotp_read(void *context, unsigned int offset,
{
struct ocotp_priv *priv = context;
unsigned int count;
- u32 *buf = val;
+ u8 *buf, *p;
int i, ret;
- u32 index;
+ u32 index, num_bytes;
index = offset >> 2;
- count = bytes >> 2;
+ num_bytes = round_up((offset % 4) + bytes, 4);
+ count = num_bytes >> 2;
if (count > (priv->nregs - index))
count = priv->nregs - index;
mutex_lock(&ocotp_mutex);
+ p = kzalloc(num_bytes, GFP_KERNEL);
+ if (!p)
+ return -ENOMEM;
+ buf = p;
+
ret = clk_prepare_enable(priv->clk);
if (ret < 0) {
mutex_unlock(&ocotp_mutex);
dev_err(priv->dev, "failed to prepare/enable ocotp clk\n");
+ kfree(p);
return ret;
}
@@ -140,7 +149,7 @@ static int imx_ocotp_read(void *context, unsigned int offset,
}
for (i = index; i < (index + count); i++) {
- *buf++ = readl(priv->base + IMX_OCOTP_OFFSET_B0W0 +
+ *(u32 *)buf = readl(priv->base + IMX_OCOTP_OFFSET_B0W0 +
i * IMX_OCOTP_OFFSET_PER_WORD);
/* 47.3.1.2
@@ -149,14 +158,22 @@ static int imx_ocotp_read(void *context, unsigned int offset,
* software before any new write, read or reload access can be
* issued
*/
- if (*(buf - 1) == IMX_OCOTP_READ_LOCKED_VAL)
+ if (*((u32*)buf) == IMX_OCOTP_READ_LOCKED_VAL)
imx_ocotp_clr_err_if_set(priv->base);
+
+ buf += 4;
}
ret = 0;
+ index = offset % 4;
+ memcpy(val, &p[index], bytes);
+
read_end:
clk_disable_unprepare(priv->clk);
mutex_unlock(&ocotp_mutex);
+
+ kfree(p);
+
return ret;
}
@@ -302,7 +319,7 @@ static struct nvmem_config imx_ocotp_nvmem_config = {
.name = "imx-ocotp",
.read_only = false,
.word_size = 4,
- .stride = 4,
+ .stride = 1,
.owner = THIS_MODULE,
.reg_read = imx_ocotp_read,
.reg_write = imx_ocotp_write,
@@ -314,6 +331,7 @@ static const struct of_device_id imx_ocotp_dt_ids[] = {
{ .compatible = "fsl,imx6sx-ocotp", (void *)128 },
{ .compatible = "fsl,imx6ul-ocotp", (void *)128 },
{ .compatible = "fsl,imx7d-ocotp", (void *)64 },
+ { .compatible = "fsl,imx8mq-ocotp", (void *)256 },
{ },
};
MODULE_DEVICE_TABLE(of, imx_ocotp_dt_ids);
@@ -343,6 +361,7 @@ static int imx_ocotp_probe(struct platform_device *pdev)
of_id = of_match_device(imx_ocotp_dt_ids, dev);
priv->nregs = (unsigned long)of_id->data;
+ priv->dev = dev;
imx_ocotp_nvmem_config.size = 4 * priv->nregs;
imx_ocotp_nvmem_config.dev = dev;
imx_ocotp_nvmem_config.priv = priv;
diff --git a/drivers/nvmem/imx-scu-ocotp.c b/drivers/nvmem/imx-scu-ocotp.c
new file mode 100644
index 000000000000..ee2d0bdc81fb
--- /dev/null
+++ b/drivers/nvmem/imx-scu-ocotp.c
@@ -0,0 +1,180 @@
+/*
+ * i.MX6 OCOTP fusebox driver
+ *
+ * Copyright (c) 2015 Pengutronix, Philipp Zabel <p.zabel@pengutronix.de>
+ *
+ * Based on the barebox ocotp driver,
+ * Copyright (c) 2010 Baruch Siach <baruch@tkos.co.il>,
+ * Orex Computed Radiography
+ *
+ * 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.
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/clk.h>
+#include <linux/device.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/nvmem-provider.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <soc/imx8/sc/sci.h>
+
+enum ocotp_devtype {
+ IMX8QM,
+ IMX8QXP,
+};
+
+struct ocotp_devtype_data {
+ int devtype;
+ int nregs;
+};
+
+struct ocotp_priv {
+ struct device *dev;
+ struct ocotp_devtype_data *data;
+ sc_ipc_t nvmem_ipc;
+};
+
+static struct ocotp_devtype_data imx8qm_data = {
+ .devtype = IMX8QM,
+ .nregs = 800,
+};
+
+static struct ocotp_devtype_data imx8qxp_data = {
+ .devtype = IMX8QXP,
+ .nregs = 800,
+};
+
+static int imx_scu_ocotp_read(void *context, unsigned int offset,
+ void *val, size_t bytes)
+{
+ struct ocotp_priv *priv = context;
+ sc_err_t sciErr = SC_ERR_NONE;
+ unsigned int count;
+ u32 index;
+ u32 num_bytes;
+ int i;
+ u8 *buf, *p;
+
+ index = offset >> 2;
+ num_bytes = round_up((offset % 4) + bytes, 4);
+ count = num_bytes >> 2;
+
+ if (count > (priv->data->nregs - index))
+ count = priv->data->nregs - index;
+
+ p = kzalloc(num_bytes, GFP_KERNEL);
+ if (!p)
+ return -ENOMEM;
+
+ buf = p;
+
+ for (i = index; i < (index + count); i++) {
+ if (priv->data->devtype == IMX8QXP) {
+ if ((i > 271) && (i < 544)) {
+ *(u32 *)buf = 0;
+ buf += 4;
+ continue;
+ }
+ }
+
+ sciErr = sc_misc_otp_fuse_read(priv->nvmem_ipc, i, (u32 *)buf);
+ if (sciErr != SC_ERR_NONE) {
+ kfree(p);
+ return -EIO;
+ }
+ buf += 4;
+ }
+
+ index = offset % 4;
+ memcpy(val, &p[index], bytes);
+
+ kfree(p);
+
+ return 0;
+}
+
+static struct nvmem_config imx_scu_ocotp_nvmem_config = {
+ .name = "imx-ocotp",
+ .read_only = true,
+ .word_size = 4,
+ .stride = 1,
+ .owner = THIS_MODULE,
+ .reg_read = imx_scu_ocotp_read,
+};
+
+static const struct of_device_id imx_scu_ocotp_dt_ids[] = {
+ { .compatible = "fsl,imx8qm-ocotp", (void *)&imx8qm_data },
+ { .compatible = "fsl,imx8qxp-ocotp", (void *)&imx8qxp_data },
+ { },
+};
+MODULE_DEVICE_TABLE(of, imx_scu_ocotp_dt_ids);
+
+static int imx_scu_ocotp_probe(struct platform_device *pdev)
+{
+ const struct of_device_id *of_id;
+ struct device *dev = &pdev->dev;
+ struct ocotp_priv *priv;
+ struct nvmem_device *nvmem;
+ uint32_t mu_id;
+ sc_err_t sciErr = SC_ERR_NONE;
+
+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ sciErr = sc_ipc_getMuID(&mu_id);
+ if (sciErr != SC_ERR_NONE) {
+ pr_info("pinctrl: Cannot obtain MU ID\n");
+ return -EIO;
+ }
+
+ sciErr = sc_ipc_open(&priv->nvmem_ipc, mu_id);
+
+ if (sciErr != SC_ERR_NONE) {
+ pr_info("pinctrl: Cannot open MU channel to SCU\n");
+ return -EIO;
+ };
+
+ of_id = of_match_device(imx_scu_ocotp_dt_ids, dev);
+ priv->data = (struct ocotp_devtype_data *)of_id->data;
+ priv->dev = dev;
+ imx_scu_ocotp_nvmem_config.size = 4 * priv->data->nregs;
+ imx_scu_ocotp_nvmem_config.dev = dev;
+ imx_scu_ocotp_nvmem_config.priv = priv;
+ nvmem = nvmem_register(&imx_scu_ocotp_nvmem_config);
+ if (IS_ERR(nvmem))
+ return PTR_ERR(nvmem);
+
+ platform_set_drvdata(pdev, nvmem);
+
+ return 0;
+}
+
+static int imx_scu_ocotp_remove(struct platform_device *pdev)
+{
+ struct nvmem_device *nvmem = platform_get_drvdata(pdev);
+
+ return nvmem_unregister(nvmem);
+}
+
+static struct platform_driver imx_scu_ocotp_driver = {
+ .probe = imx_scu_ocotp_probe,
+ .remove = imx_scu_ocotp_remove,
+ .driver = {
+ .name = "imx_scu_ocotp",
+ .of_match_table = imx_scu_ocotp_dt_ids,
+ },
+};
+module_platform_driver(imx_scu_ocotp_driver);
+
+MODULE_AUTHOR("Peng Fan <peng.fan@nxp.com>");
+MODULE_DESCRIPTION("i.MX8QM OCOTP fuse box driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/of/base.c b/drivers/of/base.c
index 41b254be0295..afbe54edaa1a 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -1666,6 +1666,36 @@ static void of_alias_add(struct alias_prop *ap, struct device_node *np,
ap->alias, ap->stem, ap->id, np);
}
+/*
+ * of_alias_max_index() - get the maximum index for a given alias stem
+ * @stem: The alias stem for which the maximum index is searched for
+ *
+ * Given an alias stem (the alias without the number) this function
+ * returns the maximum number for which an alias exists.
+ *
+ * Return: The maximum existing alias index or -ENODEV if no alias
+ * exists for this stem.
+ */
+int of_alias_max_index(const char *stem)
+{
+ struct alias_prop *app;
+ int max = -ENODEV;
+
+ mutex_lock(&of_mutex);
+
+ list_for_each_entry(app, &aliases_lookup, link) {
+ if (strcmp(app->stem, stem))
+ continue;
+ if (app->id > max)
+ max = app->id;
+ }
+
+ mutex_unlock(&of_mutex);
+
+ return max;
+}
+EXPORT_SYMBOL_GPL(of_alias_max_index);
+
/**
* of_alias_scan - Scan all properties of the 'aliases' node
*
diff --git a/drivers/of/of_reserved_mem.c b/drivers/of/of_reserved_mem.c
index 32771c2ced7b..9c643b9d6c54 100644
--- a/drivers/of/of_reserved_mem.c
+++ b/drivers/of/of_reserved_mem.c
@@ -31,11 +31,15 @@ static int reserved_mem_count;
#if defined(CONFIG_HAVE_MEMBLOCK)
#include <linux/memblock.h>
-int __init __weak early_init_dt_alloc_reserved_memory_arch(phys_addr_t size,
- phys_addr_t align, phys_addr_t start, phys_addr_t end, bool nomap,
- phys_addr_t *res_base)
+int __init __weak early_init_dt_alloc_reserved_memory_arch(unsigned long node,
+ phys_addr_t size, phys_addr_t align, phys_addr_t start, phys_addr_t end,
+ bool nomap, phys_addr_t *res_base)
{
phys_addr_t base;
+ phys_addr_t highmem_start;
+
+ highmem_start = __pa(high_memory - 1) + 1;
+
/*
* We use __memblock_alloc_base() because memblock_alloc_base()
* panic()s on allocation failure.
@@ -53,15 +57,34 @@ int __init __weak early_init_dt_alloc_reserved_memory_arch(phys_addr_t size,
return -ENOMEM;
}
+ /*
+ * Sanity check for the cma reserved region:If the reserved region
+ * crosses the low/high memory boundary, try to fix it up and then
+ * fall back to allocate the cma region from the low mememory space.
+ */
+
+ if (IS_ENABLED(CONFIG_CMA)
+ && of_flat_dt_is_compatible(node, "shared-dma-pool")
+ && of_get_flat_dt_prop(node, "reusable", NULL) && !nomap) {
+ if (base < highmem_start && (base + size) > highmem_start) {
+ memblock_free(base, size);
+ base = memblock_alloc_range(size, align, start,
+ highmem_start,
+ MEMBLOCK_NONE);
+ if (!base)
+ return -ENOMEM;
+ }
+ }
+
*res_base = base;
if (nomap)
return memblock_remove(base, size);
return 0;
}
#else
-int __init __weak early_init_dt_alloc_reserved_memory_arch(phys_addr_t size,
- phys_addr_t align, phys_addr_t start, phys_addr_t end, bool nomap,
- phys_addr_t *res_base)
+int __init __weak early_init_dt_alloc_reserved_memory_arch(unsigned long node,
+ phys_addr_t size, phys_addr_t align, phys_addr_t start, phys_addr_t end,
+ bool nomap, phys_addr_t *res_base)
{
pr_err("Reserved memory not supported, ignoring region 0x%llx%s\n",
size, nomap ? " (nomap)" : "");
@@ -155,8 +178,8 @@ static int __init __reserved_mem_alloc_size(unsigned long node,
end = start + dt_mem_next_cell(dt_root_size_cells,
&prop);
- ret = early_init_dt_alloc_reserved_memory_arch(size,
- align, start, end, nomap, &base);
+ ret = early_init_dt_alloc_reserved_memory_arch(node,
+ size, align, start, end, nomap, &base);
if (ret == 0) {
pr_debug("allocated memory for '%s' node: base %pa, size %ld MiB\n",
uname, &base,
@@ -167,8 +190,8 @@ static int __init __reserved_mem_alloc_size(unsigned long node,
}
} else {
- ret = early_init_dt_alloc_reserved_memory_arch(size, align,
- 0, 0, nomap, &base);
+ ret = early_init_dt_alloc_reserved_memory_arch(node,
+ size, align, 0, 0, nomap, &base);
if (ret == 0)
pr_debug("allocated memory for '%s' node: base %pa, size %ld MiB\n",
uname, &base, (unsigned long)size / SZ_1M);
diff --git a/drivers/pci/dwc/Kconfig b/drivers/pci/dwc/Kconfig
index 22ec82fcdea2..86220a14573f 100644
--- a/drivers/pci/dwc/Kconfig
+++ b/drivers/pci/dwc/Kconfig
@@ -73,11 +73,33 @@ config PCI_EXYNOS
config PCI_IMX6
bool "Freescale i.MX6 PCIe controller"
depends on PCI
- depends on SOC_IMX6Q
+ depends on SOC_IMX6Q || SOC_IMX6SX || SOC_IMX7D || ARCH_MXC_ARM64
depends on PCI_MSI_IRQ_DOMAIN
select PCIEPORTBUS
select PCIE_DW_HOST
+config PCI_IMX6_COMPLIANCE_TEST
+ bool "Enable pcie compliance tests on imx6"
+ depends on PCI_IMX6
+ default n
+ help
+ Say Y here if you want do the compliance tests on imx6 pcie rc found
+ on FSL iMX SoCs. The pcie clks wouldn't be turned off, and the link
+ speed wouldn't be limited to gen1 when the Y is set here.
+
+config EP_MODE_IN_EP_RC_SYS
+ bool "PCI Express EP mode in the IMX6 RC/EP interconnection system"
+ depends on PCI_IMX6
+
+config RC_MODE_IN_EP_RC_SYS
+ bool "PCI Express RC mode in the IMX6 RC/EP interconnection system"
+ depends on PCI_IMX6 && EP_MODE_IN_EP_RC_SYS!=y
+
+config PCI_IMX_EP_DRV
+ bool "i.MX6 PCI Express EP skeleton driver"
+ depends on RC_MODE_IN_EP_RC_SYS
+ default y
+
config PCIE_SPEAR13XX
bool "STMicroelectronics SPEAr PCIe controller"
depends on PCI
diff --git a/drivers/pci/dwc/Makefile b/drivers/pci/dwc/Makefile
index e73661182da0..5cab3341c404 100644
--- a/drivers/pci/dwc/Makefile
+++ b/drivers/pci/dwc/Makefile
@@ -8,6 +8,7 @@ ifneq ($(filter y,$(CONFIG_PCI_DRA7XX_HOST) $(CONFIG_PCI_DRA7XX_EP)),)
endif
obj-$(CONFIG_PCI_EXYNOS) += pci-exynos.o
obj-$(CONFIG_PCI_IMX6) += pci-imx6.o
+obj-$(CONFIG_PCI_IMX_EP_DRV) += pci-imx6-ep-driver.o
obj-$(CONFIG_PCIE_SPEAR13XX) += pcie-spear13xx.o
obj-$(CONFIG_PCI_KEYSTONE) += pci-keystone-dw.o pci-keystone.o
obj-$(CONFIG_PCI_LAYERSCAPE) += pci-layerscape.o
diff --git a/drivers/pci/dwc/pci-imx6-ep-driver.c b/drivers/pci/dwc/pci-imx6-ep-driver.c
new file mode 100644
index 000000000000..4ea0782a4c60
--- /dev/null
+++ b/drivers/pci/dwc/pci-imx6-ep-driver.c
@@ -0,0 +1,209 @@
+/*
+ * PCIe endpoint skeleton driver for IMX6 SOCs
+ *
+ * Copyright (C) 2014-2015 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/pci-aspm.h>
+#include <linux/slab.h>
+#include <linux/dma-mapping.h>
+#include <linux/delay.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+
+#define DRV_DESCRIPTION "i.MX PCIE endpoint device driver"
+#define DRV_VERSION "version 0.1"
+#define DRV_NAME "imx_pcie_ep"
+
+struct imx_pcie_ep_priv {
+ struct pci_dev *pci_dev;
+ void __iomem *hw_base;
+};
+
+/**
+ * imx_pcie_ep_probe - Device Initialization Routine
+ * @pdev: PCI device information struct
+ * @id: entry in id_tbl
+ *
+ * Returns 0 on success, negative on failure
+ **/
+static int imx_pcie_ep_probe(struct pci_dev *pdev,
+ const struct pci_device_id *id)
+{
+ int ret = 0, index = 0, found = 0;
+ unsigned int hard_wired = 0, msi_addr = 0, cpu_base;
+ struct resource cfg_res;
+ const char *name = NULL;
+ struct device_node *np = NULL;
+ struct device *dev = &pdev->dev;
+ struct imx_pcie_ep_priv *priv;
+
+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv) {
+ dev_err(dev, "can't alloc imx pcie priv\n");
+ return -ENOMEM;
+ }
+
+ priv->pci_dev = pdev;
+
+ if (pci_enable_device(pdev)) {
+ ret = -ENODEV;
+ goto out;
+ }
+ pci_set_master(pdev);
+
+ pci_set_drvdata(pdev, priv);
+
+ priv->hw_base = pci_iomap(pdev, 0, 0);
+ if (!priv->hw_base) {
+ ret = -ENODEV;
+ goto err_pci_disable;
+ }
+
+ pr_info("pci_resource_len = 0x%08llx\n",
+ (unsigned long long) pci_resource_len(pdev, 0));
+ pr_info("pci_resource_base = %p\n", priv->hw_base);
+
+ ret = pci_enable_msi(priv->pci_dev);
+ if (ret < 0) {
+ dev_err(dev, "can't enable msi\n");
+ goto err_pci_unmap_mmio;
+ }
+
+ /* Use the first none-hard-wired port as ep */
+ while ((np = of_find_node_by_type(np, "pci"))) {
+ if (of_property_read_u32(np, "hard-wired", &hard_wired)) {
+ hard_wired = 0;
+ break;
+ }
+ }
+ if (of_property_read_u32(np, "cpu-base-addr", &cpu_base))
+ cpu_base = 0;
+
+ while (!of_property_read_string_index(np, "reg-names", index, &name)) {
+ if (strcmp("config", name)) {
+ index++;
+ continue;
+ }
+
+ /* We have a match and @index is where it's at */
+ found = 1;
+ break;
+ }
+
+ if (!found) {
+ dev_err(dev, "can't find config reg space.\n");
+ ret = -EINVAL;
+ goto err_pci_disable_msi;
+ }
+
+ ret = of_address_to_resource(np, index, &cfg_res);
+ if (ret) {
+ dev_err(dev, "can't get cfg_res.\n");
+ ret = -EINVAL;
+ goto err_pci_disable_msi;
+ } else {
+ msi_addr = cfg_res.start + resource_size(&cfg_res);
+ }
+
+ pr_info("pci_msi_addr = 0x%08x, cpu_base 0x%08x\n", msi_addr, cpu_base);
+ pci_bus_write_config_dword(pdev->bus, 0, 0x54, msi_addr);
+ if (cpu_base) {
+ msi_addr = msi_addr & 0xFFFFFFF;
+ msi_addr |= (cpu_base & 0xF0000000);
+ }
+ pci_bus_write_config_dword(pdev->bus->parent, 0, 0x820, msi_addr);
+
+ /* configure rc's msi cap */
+ pci_bus_read_config_dword(pdev->bus->parent, 0, 0x50, &ret);
+ ret |= (PCI_MSI_FLAGS_ENABLE << 16);
+ pci_bus_write_config_dword(pdev->bus->parent, 0, 0x50, ret);
+ pci_bus_write_config_dword(pdev->bus->parent, 0, 0x828, 0x1);
+ pci_bus_write_config_dword(pdev->bus->parent, 0, 0x82C, 0xFFFFFFFE);
+
+ return 0;
+
+err_pci_disable_msi:
+ pci_disable_msi(pdev);
+err_pci_unmap_mmio:
+ pci_iounmap(pdev, priv->hw_base);
+err_pci_disable:
+ pci_disable_device(pdev);
+out:
+ kfree(priv);
+ return ret;
+}
+
+static void imx_pcie_ep_remove(struct pci_dev *pdev)
+{
+ struct imx_pcie_ep_priv *priv = pci_get_drvdata(pdev);
+
+ if (!priv)
+ return;
+ pr_info("***imx pcie ep driver unload***\n");
+}
+
+static struct pci_device_id imx_pcie_ep_ids[] = {
+ {
+ .class = PCI_CLASS_MEMORY_RAM << 8,
+ .class_mask = ~0,
+ .vendor = 0xbeaf,
+ .device = 0xdead,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ },
+ { } /* terminate list */
+};
+MODULE_DEVICE_TABLE(pci, imx_pcie_ep_ids);
+
+static struct pci_driver imx_pcie_ep_driver = {
+ .name = DRV_NAME,
+ .id_table = imx_pcie_ep_ids,
+ .probe = imx_pcie_ep_probe,
+ .remove = imx_pcie_ep_remove,
+};
+
+static int __init imx_pcie_ep_init(void)
+{
+ int ret;
+ pr_info(DRV_DESCRIPTION ", " DRV_VERSION "\n");
+
+ ret = pci_register_driver(&imx_pcie_ep_driver);
+ if (ret)
+ pr_err("Unable to initialize PCI module\n");
+
+ return ret;
+}
+
+static void __exit imx_pcie_ep_exit(void)
+{
+ pci_unregister_driver(&imx_pcie_ep_driver);
+}
+
+module_exit(imx_pcie_ep_exit);
+module_init(imx_pcie_ep_init);
+
+MODULE_DESCRIPTION(DRV_DESCRIPTION);
+MODULE_VERSION(DRV_VERSION);
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("imx_pcie_ep");
diff --git a/drivers/pci/dwc/pci-imx6.c b/drivers/pci/dwc/pci-imx6.c
index 5509b6e2de94..54459b52f526 100644
--- a/drivers/pci/dwc/pci-imx6.c
+++ b/drivers/pci/dwc/pci-imx6.c
@@ -11,6 +11,7 @@
* published by the Free Software Foundation.
*/
+#include <dt-bindings/soc/imx8_hsio.h>
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/gpio.h>
@@ -21,8 +22,12 @@
#include <linux/module.h>
#include <linux/of_gpio.h>
#include <linux/of_device.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/of_pci.h>
#include <linux/pci.h>
#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
#include <linux/regmap.h>
#include <linux/regulator/consumer.h>
#include <linux/resource.h>
@@ -30,37 +35,69 @@
#include <linux/types.h>
#include <linux/interrupt.h>
#include <linux/reset.h>
+#include <linux/busfreq-imx.h>
+#include <linux/regulator/consumer.h>
#include "pcie-designware.h"
-#define to_imx6_pcie(x) dev_get_drvdata((x)->dev)
+#define to_imx_pcie(x) dev_get_drvdata((x)->dev)
-enum imx6_pcie_variants {
+enum imx_pcie_variants {
IMX6Q,
IMX6SX,
IMX6QP,
IMX7D,
+ IMX8QM,
+ IMX8QXP,
+ IMX8MQ,
+ IMX8MM,
};
-struct imx6_pcie {
+/*
+ * The default value of the reserved ddr memory
+ * used to verify EP/RC memory space access operations.
+ * The layout of the 1G ddr on SD boards
+ * [imx6qdl-sd-ard boards]0x1000_0000 ~ 0x4FFF_FFFF
+ * [imx6sx,imx7d platforms]0x8000_0000 ~ 0xBFFF_FFFF
+ *
+ */
+static u32 ddr_test_region = 0, test_region_size = SZ_2M;
+static bool dma_w_end, dma_r_end, dma_en;
+
+struct imx_pcie {
struct dw_pcie *pci;
+ u32 ext_osc;
+ u32 ctrl_id;
+ u32 cpu_base;
+ u32 hard_wired;
+ int clkreq_gpio;
+ int dis_gpio;
+ int power_on_gpio;
int reset_gpio;
bool gpio_active_high;
struct clk *pcie_bus;
struct clk *pcie_phy;
struct clk *pcie_inbound_axi;
+ struct clk *pcie_per;
struct clk *pcie;
+ struct clk *pcie_ext_src;
struct regmap *iomuxc_gpr;
- struct reset_control *pciephy_reset;
- struct reset_control *apps_reset;
- enum imx6_pcie_variants variant;
+ enum imx_pcie_variants variant;
+ u32 hsio_cfg;
u32 tx_deemph_gen1;
u32 tx_deemph_gen2_3p5db;
u32 tx_deemph_gen2_6db;
u32 tx_swing_full;
u32 tx_swing_low;
+ u32 dma_unroll_offset;
int link_gen;
struct regulator *vpcie;
+ struct regmap *reg_src;
+ struct regmap *reg_gpc;
+ void __iomem *phy_base;
+ struct regulator *pcie_phy_regulator;
+ struct regulator *pcie_bus_regulator;
+ struct regulator *epdev_on;
};
/* Parameters for the waiting for PCIe PHY PLL to lock on i.MX7 */
@@ -73,7 +110,6 @@ struct imx6_pcie {
#define PCIE_RC_LCR_MAX_LINK_SPEEDS_GEN1 0x1
#define PCIE_RC_LCR_MAX_LINK_SPEEDS_GEN2 0x2
#define PCIE_RC_LCR_MAX_LINK_SPEEDS_MASK 0xf
-
#define PCIE_RC_LCSR 0x80
/* PCIe Port Logic registers (memory-mapped) */
@@ -81,8 +117,15 @@ struct imx6_pcie {
#define PCIE_PL_PFLR (PL_OFFSET + 0x08)
#define PCIE_PL_PFLR_LINK_STATE_MASK (0x3f << 16)
#define PCIE_PL_PFLR_FORCE_LINK (1 << 15)
+#define PCIE_PORT_LINK_CONTROL 0x710
+#define PORT_LINK_MODE_MASK (0x3f << 16)
+#define PORT_LINK_MODE_1_LANES (0x1 << 16)
+#define PORT_LINK_MODE_2_LANES (0x3 << 16)
+
#define PCIE_PHY_DEBUG_R0 (PL_OFFSET + 0x28)
#define PCIE_PHY_DEBUG_R1 (PL_OFFSET + 0x2c)
+#define PCIE_PHY_DEBUG_R1_XMLH_LINK_IN_TRAINING (1 << 29)
+#define PCIE_PHY_DEBUG_R1_XMLH_LINK_UP (1 << 4)
#define PCIE_PHY_CTRL (PL_OFFSET + 0x114)
#define PCIE_PHY_CTRL_DATA_LOC 0
@@ -96,6 +139,43 @@ struct imx6_pcie {
#define PCIE_LINK_WIDTH_SPEED_CONTROL 0x80C
#define PORT_LOGIC_SPEED_CHANGE (0x1 << 17)
+#define PORT_LOGIC_LINK_WIDTH_MASK (0x1f << 8)
+#define PORT_LOGIC_LINK_WIDTH_1_LANES (0x1 << 8)
+#define PORT_LOGIC_LINK_WIDTH_2_LANES (0x2 << 8)
+
+#define PCIE_MISC_CTRL (PL_OFFSET + 0x1BC)
+#define PCIE_MISC_DBI_RO_WR_EN BIT(0)
+
+#define PCIE_ATU_VIEWPORT 0x900
+
+/* DMA registers */
+#define MAX_PCIE_DMA_CHANNELS 8
+#define DMA_UNROLL_CDM_OFFSET (0x7 << 19)
+#define DMA_REG_OFFSET 0x970
+#define DMA_CTRL_VIEWPORT_OFF (DMA_REG_OFFSET + 0x8)
+#define DMA_WRITE_ENGINE_EN_OFF (DMA_REG_OFFSET + 0xC)
+#define DMA_WRITE_ENGINE_EN BIT(0)
+#define DMA_WRITE_DOORBELL (DMA_REG_OFFSET + 0x10)
+#define DMA_READ_ENGINE_EN_OFF (DMA_REG_OFFSET + 0x2C)
+#define DMA_READ_ENGINE_EN BIT(0)
+#define DMA_READ_DOORBELL (DMA_REG_OFFSET + 0x30)
+#define DMA_WRITE_INT_STS (DMA_REG_OFFSET + 0x4C)
+#define DMA_WRITE_INT_MASK (DMA_REG_OFFSET + 0x54)
+#define DMA_WRITE_INT_CLR (DMA_REG_OFFSET + 0x58)
+#define DMA_READ_INT_STS (DMA_REG_OFFSET + 0xA0)
+#define DMA_READ_INT_MASK (DMA_REG_OFFSET + 0xA8)
+#define DMA_READ_INT_CLR (DMA_REG_OFFSET + 0xAC)
+#define DMA_DONE_INT_STS 0xFF
+#define DMA_ABORT_INT_STS (0xFF << 16)
+#define DMA_VIEWPOT_SEL_OFF (DMA_REG_OFFSET + 0xFC)
+#define DMA_CHANNEL_CTRL_1 (DMA_REG_OFFSET + 0x100)
+#define DMA_CHANNEL_CTRL_1_LIE BIT(3)
+#define DMA_CHANNEL_CTRL_2 (DMA_REG_OFFSET + 0x104)
+#define DMA_TRANSFER_SIZE (DMA_REG_OFFSET + 0x108)
+#define DMA_SAR_LOW (DMA_REG_OFFSET + 0x10C)
+#define DMA_SAR_HIGH (DMA_REG_OFFSET + 0x110)
+#define DMA_DAR_LOW (DMA_REG_OFFSET + 0x114)
+#define DMA_DAR_HIGH (DMA_REG_OFFSET + 0x118)
/* PHY registers (not memory-mapped) */
#define PCIE_PHY_RX_ASIC_OUT 0x100D
@@ -105,9 +185,134 @@ struct imx6_pcie {
#define PHY_RX_OVRD_IN_LO_RX_DATA_EN (1 << 5)
#define PHY_RX_OVRD_IN_LO_RX_PLL_EN (1 << 3)
-static int pcie_phy_poll_ack(struct imx6_pcie *imx6_pcie, int exp_val)
+#define SSP_CR_SUP_DIG_MPLL_OVRD_IN_LO 0x0011
+/* FIELD: RES_ACK_IN_OVRD [15:15]
+ * FIELD: RES_ACK_IN [14:14]
+ * FIELD: RES_REQ_IN_OVRD [13:13]
+ * FIELD: RES_REQ_IN [12:12]
+ * FIELD: RTUNE_REQ_OVRD [11:11]
+ * FIELD: RTUNE_REQ [10:10]
+ * FIELD: MPLL_MULTIPLIER_OVRD [9:9]
+ * FIELD: MPLL_MULTIPLIER [8:2]
+ * FIELD: MPLL_EN_OVRD [1:1]
+ * FIELD: MPLL_EN [0:0]
+ */
+
+#define SSP_CR_SUP_DIG_ATEOVRD 0x0010
+/* FIELD: ateovrd_en [2:2]
+ * FIELD: ref_usb2_en [1:1]
+ * FIELD: ref_clkdiv2 [0:0]
+ */
+
+/* iMX7 PCIe PHY registers */
+#define PCIE_PHY_CMN_REG4 0x14
+#define PCIE_PHY_CMN_REG4_DCC_FB_EN (0x29)
+
+#define PCIE_PHY_CMN_REG24 0x90
+#define PCIE_PHY_CMN_REG24_RX_EQ BIT(6)
+#define PCIE_PHY_CMN_REG24_RX_EQ_SEL BIT(3)
+
+#define PCIE_PHY_CMN_REG26 0x98
+#define PCIE_PHY_CMN_REG26_ATT_MODE 0xBC
+
+#define PCIE_PHY_CMN_REG62 0x188
+#define PCIE_PHY_CMN_REG62_PLL_CLK_OUT 0x08
+#define PCIE_PHY_CMN_REG64 0x190
+#define PCIE_PHY_CMN_REG64_AUX_RX_TX_TERM 0x8C
+#define PCIE_PHY_CMN_REG75 0x1D4
+#define PCIE_PHY_CMN_REG75_PLL_DONE 0x3
+#define PCIE_PHY_TRSV_REG5 0x414
+#define PCIE_PHY_TRSV_REG5_GEN1_DEEMP 0x2D
+#define PCIE_PHY_TRSV_REG6 0x418
+#define PCIE_PHY_TRSV_REG6_GEN2_DEEMP 0xF
+
+/* iMX8 HSIO registers */
+#define IMX8QM_LPCG_PHYX2_OFFSET 0x00000
+#define IMX8QM_LPCG_PHYX1_OFFSET 0x10000
+#define IMX8QM_CSR_PHYX2_OFFSET 0x90000
+#define IMX8QM_CSR_PHYX1_OFFSET 0xA0000
+#define IMX8QM_CSR_PHYX_STTS0_OFFSET 0x4
+#define IMX8QM_CSR_PCIEA_OFFSET 0xB0000
+#define IMX8QM_CSR_PCIEB_OFFSET 0xC0000
+#define IMX8QM_CSR_PCIE_CTRL1_OFFSET 0x4
+#define IMX8QM_CSR_PCIE_CTRL2_OFFSET 0x8
+#define IMX8QM_CSR_PCIE_STTS0_OFFSET 0xC
+#define IMX8QM_CSR_MISC_OFFSET 0xE0000
+
+#define IMX8QM_LPCG_PHY_PCG0 BIT(1)
+#define IMX8QM_LPCG_PHY_PCG1 BIT(5)
+
+#define IMX8QM_CTRL_LTSSM_ENABLE BIT(4)
+#define IMX8QM_CTRL_READY_ENTR_L23 BIT(5)
+#define IMX8QM_CTRL_PM_XMT_TURNOFF BIT(9)
+#define IMX8QM_CTRL_BUTTON_RST_N BIT(21)
+#define IMX8QM_CTRL_PERST_N BIT(22)
+#define IMX8QM_CTRL_POWER_UP_RST_N BIT(23)
+
+#define IMX8QM_CTRL_STTS0_PM_LINKST_IN_L2 BIT(13)
+#define IMX8QM_CTRL_STTS0_PM_REQ_CORE_RST BIT(19)
+#define IMX8QM_STTS0_LANE0_TX_PLL_LOCK BIT(4)
+#define IMX8QM_STTS0_LANE1_TX_PLL_LOCK BIT(12)
+
+#define IMX8QM_PCIE_TYPE_MASK (0xF << 24)
+
+#define IMX8QM_PHYX2_CTRL0_APB_MASK 0x3
+#define IMX8QM_PHY_APB_RSTN_0 BIT(0)
+#define IMX8QM_PHY_APB_RSTN_1 BIT(1)
+
+#define IMX8QM_MISC_IOB_RXENA BIT(0)
+#define IMX8QM_MISC_IOB_TXENA BIT(1)
+#define IMX8QM_CSR_MISC_IOB_A_0_TXOE BIT(2)
+#define IMX8QM_CSR_MISC_IOB_A_0_M1M0_MASK (0x3 << 3)
+#define IMX8QM_CSR_MISC_IOB_A_0_M1M0_2 BIT(4)
+#define IMX8QM_MISC_PHYX1_EPCS_SEL BIT(12)
+#define IMX8QM_MISC_PCIE_AB_SELECT BIT(13)
+
+#define IMX8MQ_PCIE_LINK_CAP_REG_OFFSET 0x7C
+#define IMX8MQ_PCIE_LINK_CAP_L1EL_64US (0x6 << 15)
+#define IMX8MQ_SRC_PCIEPHY_RCR_OFFSET 0x2C
+#define IMX8MQ_SRC_PCIE2PHY_RCR_OFFSET 0x48
+#define IMX8MQ_PCIEPHY_DOMAIN_EN (BIT(31) | (0xF << 24))
+#define IMX8MQ_PCIEPHY_PWR_ON_RST BIT(0)
+#define IMX8MQ_PCIEPHY_G_RST BIT(1)
+#define IMX8MQ_PCIEPHY_BTN BIT(2)
+#define IMX8MQ_PCIEPHY_PERST BIT(3)
+#define IMX8MQ_PCIE_CTRL_APPS_CLK_REQ BIT(4)
+#define IMX8MQ_PCIE_CTRL_APPS_EN BIT(6)
+#define IMX8MQ_PCIE_CTRL_APPS_TURNOFF BIT(11)
+#define IMX8MQ_PCIE_L1SUB_CTRL1_REG_OFFSET 0x170
+#define IMX8MQ_PCIE_L1SUB_CTRL1_REG_EN_MASK 0xF
+
+#define IMX8MQ_GPC_PGC_CPU_0_1_MAPPING_OFFSET 0xEC
+#define IMX8MQ_GPC_PU_PGC_SW_PUP_REQ_OFFSET 0xF8
+#define IMX8MQ_GPC_PU_PGC_SW_PDN_REQ_OFFSET 0x104
+#define IMX8MQ_GPC_PGC_PCIE_CTRL_OFFSET 0xC40
+#define IMX8MQ_GPC_PGC_PCIE2_CTRL_OFFSET 0xF00
+#define IMX8MQ_GPC_PGC_PCIE_A53_DOMAIN BIT(3)
+#define IMX8MQ_GPC_PU_PGC_PCIE_SW_PWR_REQ BIT(1)
+#define IMX8MQ_GPC_PGC_PCIE2_BIT_OFFSET 12
+#define IMX8MQ_GPC_PCG_PCIE_CTRL_PCR BIT(0)
+#define IMX8MQ_GPR_PCIE_REF_USE_PAD BIT(9)
+#define IMX8MQ_GPR_PCIE_CLK_REQ_OVERRIDE_EN BIT(10)
+#define IMX8MQ_GPR_PCIE_CLK_REQ_OVERRIDE BIT(11)
+#define IMX8MQ_ANA_PLLOUT_REG 0x74
+#define IMX8MQ_ANA_PLLOUT_CKE BIT(4)
+#define IMX8MQ_ANA_PLLOUT_SEL_MASK 0xF
+#define IMX8MQ_ANA_PLLOUT_SEL_SYSPLL1 0xB
+#define IMX8MQ_ANA_PLLOUT_DIV_REG 0x7C
+#define IMX8MQ_ANA_PLLOUT_SYSPLL1_DIV 0x7
+
+#define IMX8MM_GPR_PCIE_REF_CLK_SEL (0x3 << 24)
+#define IMX8MM_GPR_PCIE_REF_CLK_PLL (0x3 << 24)
+#define IMX8MM_GPR_PCIE_REF_CLK_EXT (0x2 << 24)
+#define IMX8MM_GPR_PCIE_AUX_EN BIT(19)
+#define IMX8MM_GPR_PCIE_CMN_RST BIT(18)
+#define IMX8MM_GPR_PCIE_POWER_OFF BIT(17)
+#define IMX8MM_GPR_PCIE_SSC_EN BIT(16)
+
+static int pcie_phy_poll_ack(struct imx_pcie *imx_pcie, int exp_val)
{
- struct dw_pcie *pci = imx6_pcie->pci;
+ struct dw_pcie *pci = imx_pcie->pci;
u32 val;
u32 max_iterations = 10;
u32 wait_counter = 0;
@@ -126,9 +331,9 @@ static int pcie_phy_poll_ack(struct imx6_pcie *imx6_pcie, int exp_val)
return -ETIMEDOUT;
}
-static int pcie_phy_wait_ack(struct imx6_pcie *imx6_pcie, int addr)
+static int pcie_phy_wait_ack(struct imx_pcie *imx_pcie, int addr)
{
- struct dw_pcie *pci = imx6_pcie->pci;
+ struct dw_pcie *pci = imx_pcie->pci;
u32 val;
int ret;
@@ -138,24 +343,24 @@ static int pcie_phy_wait_ack(struct imx6_pcie *imx6_pcie, int addr)
val |= (0x1 << PCIE_PHY_CTRL_CAP_ADR_LOC);
dw_pcie_writel_dbi(pci, PCIE_PHY_CTRL, val);
- ret = pcie_phy_poll_ack(imx6_pcie, 1);
+ ret = pcie_phy_poll_ack(imx_pcie, 1);
if (ret)
return ret;
val = addr << PCIE_PHY_CTRL_DATA_LOC;
dw_pcie_writel_dbi(pci, PCIE_PHY_CTRL, val);
- return pcie_phy_poll_ack(imx6_pcie, 0);
+ return pcie_phy_poll_ack(imx_pcie, 0);
}
/* Read from the 16-bit PCIe PHY control registers (not memory-mapped) */
-static int pcie_phy_read(struct imx6_pcie *imx6_pcie, int addr, int *data)
+static int pcie_phy_read(struct imx_pcie *imx_pcie, int addr, int *data)
{
- struct dw_pcie *pci = imx6_pcie->pci;
+ struct dw_pcie *pci = imx_pcie->pci;
u32 val, phy_ctl;
int ret;
- ret = pcie_phy_wait_ack(imx6_pcie, addr);
+ ret = pcie_phy_wait_ack(imx_pcie, addr);
if (ret)
return ret;
@@ -163,7 +368,7 @@ static int pcie_phy_read(struct imx6_pcie *imx6_pcie, int addr, int *data)
phy_ctl = 0x1 << PCIE_PHY_CTRL_RD_LOC;
dw_pcie_writel_dbi(pci, PCIE_PHY_CTRL, phy_ctl);
- ret = pcie_phy_poll_ack(imx6_pcie, 1);
+ ret = pcie_phy_poll_ack(imx_pcie, 1);
if (ret)
return ret;
@@ -173,18 +378,18 @@ static int pcie_phy_read(struct imx6_pcie *imx6_pcie, int addr, int *data)
/* deassert Read signal */
dw_pcie_writel_dbi(pci, PCIE_PHY_CTRL, 0x00);
- return pcie_phy_poll_ack(imx6_pcie, 0);
+ return pcie_phy_poll_ack(imx_pcie, 0);
}
-static int pcie_phy_write(struct imx6_pcie *imx6_pcie, int addr, int data)
+static int pcie_phy_write(struct imx_pcie *imx_pcie, int addr, int data)
{
- struct dw_pcie *pci = imx6_pcie->pci;
+ struct dw_pcie *pci = imx_pcie->pci;
u32 var;
int ret;
/* write addr */
/* cap addr */
- ret = pcie_phy_wait_ack(imx6_pcie, addr);
+ ret = pcie_phy_wait_ack(imx_pcie, addr);
if (ret)
return ret;
@@ -195,7 +400,7 @@ static int pcie_phy_write(struct imx6_pcie *imx6_pcie, int addr, int data)
var |= (0x1 << PCIE_PHY_CTRL_CAP_DAT_LOC);
dw_pcie_writel_dbi(pci, PCIE_PHY_CTRL, var);
- ret = pcie_phy_poll_ack(imx6_pcie, 1);
+ ret = pcie_phy_poll_ack(imx_pcie, 1);
if (ret)
return ret;
@@ -204,7 +409,7 @@ static int pcie_phy_write(struct imx6_pcie *imx6_pcie, int addr, int data)
dw_pcie_writel_dbi(pci, PCIE_PHY_CTRL, var);
/* wait for ack de-assertion */
- ret = pcie_phy_poll_ack(imx6_pcie, 0);
+ ret = pcie_phy_poll_ack(imx_pcie, 0);
if (ret)
return ret;
@@ -213,7 +418,7 @@ static int pcie_phy_write(struct imx6_pcie *imx6_pcie, int addr, int data)
dw_pcie_writel_dbi(pci, PCIE_PHY_CTRL, var);
/* wait for ack */
- ret = pcie_phy_poll_ack(imx6_pcie, 1);
+ ret = pcie_phy_poll_ack(imx_pcie, 1);
if (ret)
return ret;
@@ -222,7 +427,7 @@ static int pcie_phy_write(struct imx6_pcie *imx6_pcie, int addr, int data)
dw_pcie_writel_dbi(pci, PCIE_PHY_CTRL, var);
/* wait for ack de-assertion */
- ret = pcie_phy_poll_ack(imx6_pcie, 0);
+ ret = pcie_phy_poll_ack(imx_pcie, 0);
if (ret)
return ret;
@@ -231,25 +436,29 @@ static int pcie_phy_write(struct imx6_pcie *imx6_pcie, int addr, int data)
return 0;
}
-static void imx6_pcie_reset_phy(struct imx6_pcie *imx6_pcie)
+static void imx_pcie_reset_phy(struct imx_pcie *imx_pcie)
{
u32 tmp;
- pcie_phy_read(imx6_pcie, PHY_RX_OVRD_IN_LO, &tmp);
- tmp |= (PHY_RX_OVRD_IN_LO_RX_DATA_EN |
- PHY_RX_OVRD_IN_LO_RX_PLL_EN);
- pcie_phy_write(imx6_pcie, PHY_RX_OVRD_IN_LO, tmp);
+ if (imx_pcie->variant == IMX6Q || imx_pcie->variant == IMX6SX
+ || imx_pcie->variant == IMX6QP) {
+ pcie_phy_read(imx_pcie, PHY_RX_OVRD_IN_LO, &tmp);
+ tmp |= (PHY_RX_OVRD_IN_LO_RX_DATA_EN |
+ PHY_RX_OVRD_IN_LO_RX_PLL_EN);
+ pcie_phy_write(imx_pcie, PHY_RX_OVRD_IN_LO, tmp);
- usleep_range(2000, 3000);
+ usleep_range(2000, 3000);
- pcie_phy_read(imx6_pcie, PHY_RX_OVRD_IN_LO, &tmp);
- tmp &= ~(PHY_RX_OVRD_IN_LO_RX_DATA_EN |
- PHY_RX_OVRD_IN_LO_RX_PLL_EN);
- pcie_phy_write(imx6_pcie, PHY_RX_OVRD_IN_LO, tmp);
+ pcie_phy_read(imx_pcie, PHY_RX_OVRD_IN_LO, &tmp);
+ tmp &= ~(PHY_RX_OVRD_IN_LO_RX_DATA_EN |
+ PHY_RX_OVRD_IN_LO_RX_PLL_EN);
+ pcie_phy_write(imx_pcie, PHY_RX_OVRD_IN_LO, tmp);
+ }
}
+#ifdef CONFIG_ARM
/* Added for PCI abort handling */
-static int imx6q_pcie_abort_handler(unsigned long addr,
+static int imx_pcie_abort_handler(unsigned long addr,
unsigned int fsr, struct pt_regs *regs)
{
unsigned long pc = instruction_pointer(regs);
@@ -281,40 +490,92 @@ static int imx6q_pcie_abort_handler(unsigned long addr,
return 1;
}
+#endif
-static void imx6_pcie_assert_core_reset(struct imx6_pcie *imx6_pcie)
+static void imx_pcie_assert_core_reset(struct imx_pcie *imx_pcie)
{
- struct device *dev = imx6_pcie->pci->dev;
+ struct device *dev = imx_pcie->pci->dev;
+ u32 val;
+ int i;
- switch (imx6_pcie->variant) {
- case IMX7D:
- reset_control_assert(imx6_pcie->pciephy_reset);
- reset_control_assert(imx6_pcie->apps_reset);
- break;
+ switch (imx_pcie->variant) {
case IMX6SX:
- regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
+ regmap_update_bits(imx_pcie->iomuxc_gpr, IOMUXC_GPR12,
IMX6SX_GPR12_PCIE_TEST_POWERDOWN,
IMX6SX_GPR12_PCIE_TEST_POWERDOWN);
/* Force PCIe PHY reset */
- regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR5,
+ regmap_update_bits(imx_pcie->iomuxc_gpr, IOMUXC_GPR5,
IMX6SX_GPR5_PCIE_BTNRST_RESET,
IMX6SX_GPR5_PCIE_BTNRST_RESET);
break;
case IMX6QP:
- regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1,
+ regmap_update_bits(imx_pcie->iomuxc_gpr, IOMUXC_GPR1,
IMX6Q_GPR1_PCIE_SW_RST,
IMX6Q_GPR1_PCIE_SW_RST);
break;
case IMX6Q:
- regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1,
+ regmap_update_bits(imx_pcie->iomuxc_gpr, IOMUXC_GPR1,
IMX6Q_GPR1_PCIE_TEST_PD, 1 << 18);
- regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1,
+ regmap_update_bits(imx_pcie->iomuxc_gpr, IOMUXC_GPR1,
IMX6Q_GPR1_PCIE_REF_CLK_EN, 0 << 16);
break;
+ case IMX7D:
+ /* G_RST */
+ regmap_update_bits(imx_pcie->reg_src, 0x2c, BIT(1), BIT(1));
+ /* BTNRST */
+ regmap_update_bits(imx_pcie->reg_src, 0x2c, BIT(2), BIT(2));
+ break;
+ case IMX8QXP:
+ val = IMX8QM_CSR_PCIEB_OFFSET;
+ regmap_update_bits(imx_pcie->iomuxc_gpr,
+ val + IMX8QM_CSR_PCIE_CTRL2_OFFSET,
+ IMX8QM_CTRL_BUTTON_RST_N,
+ IMX8QM_CTRL_BUTTON_RST_N);
+ regmap_update_bits(imx_pcie->iomuxc_gpr,
+ val + IMX8QM_CSR_PCIE_CTRL2_OFFSET,
+ IMX8QM_CTRL_PERST_N,
+ IMX8QM_CTRL_PERST_N);
+ regmap_update_bits(imx_pcie->iomuxc_gpr,
+ val + IMX8QM_CSR_PCIE_CTRL2_OFFSET,
+ IMX8QM_CTRL_POWER_UP_RST_N,
+ IMX8QM_CTRL_POWER_UP_RST_N);
+ break;
+ case IMX8QM:
+ for (i = 0; i <= imx_pcie->ctrl_id; i++) {
+ val = IMX8QM_CSR_PCIEA_OFFSET + i * SZ_64K;
+ regmap_update_bits(imx_pcie->iomuxc_gpr,
+ val + IMX8QM_CSR_PCIE_CTRL2_OFFSET,
+ IMX8QM_CTRL_BUTTON_RST_N,
+ IMX8QM_CTRL_BUTTON_RST_N);
+ regmap_update_bits(imx_pcie->iomuxc_gpr,
+ val + IMX8QM_CSR_PCIE_CTRL2_OFFSET,
+ IMX8QM_CTRL_PERST_N,
+ IMX8QM_CTRL_PERST_N);
+ regmap_update_bits(imx_pcie->iomuxc_gpr,
+ val + IMX8QM_CSR_PCIE_CTRL2_OFFSET,
+ IMX8QM_CTRL_POWER_UP_RST_N,
+ IMX8QM_CTRL_POWER_UP_RST_N);
+ }
+ break;
+ case IMX8MQ:
+ case IMX8MM:
+ if (imx_pcie->ctrl_id == 0)
+ val = IMX8MQ_SRC_PCIEPHY_RCR_OFFSET;
+ else
+ val = IMX8MQ_SRC_PCIE2PHY_RCR_OFFSET;
+ /* Do RSTs */
+ regmap_update_bits(imx_pcie->reg_src, val,
+ IMX8MQ_PCIEPHY_BTN | IMX8MQ_PCIEPHY_DOMAIN_EN,
+ IMX8MQ_PCIEPHY_BTN | IMX8MQ_PCIEPHY_DOMAIN_EN);
+ regmap_update_bits(imx_pcie->reg_src, val,
+ IMX8MQ_PCIEPHY_G_RST |
+ IMX8MQ_PCIEPHY_DOMAIN_EN,
+ IMX8MQ_PCIEPHY_G_RST |
+ IMX8MQ_PCIEPHY_DOMAIN_EN);
}
- if (imx6_pcie->vpcie && regulator_is_enabled(imx6_pcie->vpcie) > 0) {
- int ret = regulator_disable(imx6_pcie->vpcie);
+ if (imx_pcie->vpcie && regulator_is_enabled(imx_pcie->vpcie) > 0) {
+ int ret = regulator_disable(imx_pcie->vpcie);
if (ret)
dev_err(dev, "failed to disable vpcie regulator: %d\n",
@@ -322,27 +583,28 @@ static void imx6_pcie_assert_core_reset(struct imx6_pcie *imx6_pcie)
}
}
-static int imx6_pcie_enable_ref_clk(struct imx6_pcie *imx6_pcie)
+static int imx_pcie_enable_ref_clk(struct imx_pcie *imx_pcie)
{
- struct dw_pcie *pci = imx6_pcie->pci;
- struct device *dev = pci->dev;
+ u32 val;
int ret = 0;
+ struct dw_pcie *pci = imx_pcie->pci;
+ struct device *dev = pci->dev;
- switch (imx6_pcie->variant) {
+ switch (imx_pcie->variant) {
case IMX6SX:
- ret = clk_prepare_enable(imx6_pcie->pcie_inbound_axi);
+ ret = clk_prepare_enable(imx_pcie->pcie_inbound_axi);
if (ret) {
dev_err(dev, "unable to enable pcie_axi clock\n");
break;
}
- regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
+ regmap_update_bits(imx_pcie->iomuxc_gpr, IOMUXC_GPR12,
IMX6SX_GPR12_PCIE_TEST_POWERDOWN, 0);
break;
case IMX6QP: /* FALLTHROUGH */
case IMX6Q:
/* power up core phy and enable ref clock */
- regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1,
+ regmap_update_bits(imx_pcie->iomuxc_gpr, IOMUXC_GPR1,
IMX6Q_GPR1_PCIE_TEST_PD, 0 << 18);
/*
* the async reset input need ref clock to sync internally,
@@ -351,182 +613,818 @@ static int imx6_pcie_enable_ref_clk(struct imx6_pcie *imx6_pcie)
* add one ~10us delay here.
*/
udelay(10);
- regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1,
+ regmap_update_bits(imx_pcie->iomuxc_gpr, IOMUXC_GPR1,
IMX6Q_GPR1_PCIE_REF_CLK_EN, 1 << 16);
break;
case IMX7D:
break;
+ case IMX8MQ:
+ case IMX8MM:
+ /*
+ * Set the over ride low and enabled
+ * make sure that REF_CLK is turned on.
+ */
+ if (imx_pcie->ctrl_id == 0)
+ val = IOMUXC_GPR14;
+ else
+ val = IOMUXC_GPR16;
+
+ regmap_update_bits(imx_pcie->iomuxc_gpr, val,
+ IMX8MQ_GPR_PCIE_CLK_REQ_OVERRIDE,
+ 0);
+ regmap_update_bits(imx_pcie->iomuxc_gpr, val,
+ IMX8MQ_GPR_PCIE_CLK_REQ_OVERRIDE_EN,
+ IMX8MQ_GPR_PCIE_CLK_REQ_OVERRIDE_EN);
+
+ break;
+ case IMX8QXP:
+ case IMX8QM:
+ ret = clk_prepare_enable(imx_pcie->pcie_inbound_axi);
+ if (ret) {
+ dev_err(dev, "unable to enable pcie_axi clock\n");
+ break;
+ }
+ ret = clk_prepare_enable(imx_pcie->pcie_per);
+ if (ret) {
+ dev_err(dev, "unable to enable pcie_per clock\n");
+ clk_disable_unprepare(imx_pcie->pcie_inbound_axi);
+ break;
+ }
+
+ break;
}
return ret;
}
-static void imx7d_pcie_wait_for_phy_pll_lock(struct imx6_pcie *imx6_pcie)
+static int imx7d_pcie_wait_for_phy_pll_lock(struct imx_pcie *imx_pcie)
{
u32 val;
unsigned int retries;
- struct device *dev = imx6_pcie->pci->dev;
+ struct device *dev = imx_pcie->pci->dev;
for (retries = 0; retries < PHY_PLL_LOCK_WAIT_MAX_RETRIES; retries++) {
- regmap_read(imx6_pcie->iomuxc_gpr, IOMUXC_GPR22, &val);
+ regmap_read(imx_pcie->iomuxc_gpr, IOMUXC_GPR22, &val);
if (val & IMX7D_GPR22_PCIE_PHY_PLL_LOCKED)
- return;
+ return 0;
- usleep_range(PHY_PLL_LOCK_WAIT_USLEEP_MIN,
- PHY_PLL_LOCK_WAIT_USLEEP_MAX);
+ udelay(PHY_PLL_LOCK_WAIT_USLEEP_MIN);
}
dev_err(dev, "PCIe PLL lock timeout\n");
+ return -ENODEV;
}
-static void imx6_pcie_deassert_core_reset(struct imx6_pcie *imx6_pcie)
+static int imx8_pcie_wait_for_phy_pll_lock(struct imx_pcie *imx_pcie)
{
- struct dw_pcie *pci = imx6_pcie->pci;
+ u32 val, tmp, orig;
+ unsigned int retries = 0;
+ struct dw_pcie *pci = imx_pcie->pci;
struct device *dev = pci->dev;
- int ret;
- if (imx6_pcie->vpcie && !regulator_is_enabled(imx6_pcie->vpcie)) {
- ret = regulator_enable(imx6_pcie->vpcie);
+ if (imx_pcie->variant == IMX8MM) {
+ for (retries = 0; retries < PHY_PLL_LOCK_WAIT_MAX_RETRIES;
+ retries++) {
+ tmp = readl(imx_pcie->phy_base + PCIE_PHY_CMN_REG75);
+ if (tmp == PCIE_PHY_CMN_REG75_PLL_DONE)
+ break;
+ udelay(10);
+ }
+ } else if (imx_pcie->variant == IMX8QXP
+ || imx_pcie->variant == IMX8QM) {
+ for (retries = 0; retries < PHY_PLL_LOCK_WAIT_MAX_RETRIES;
+ retries++) {
+ if (imx_pcie->hsio_cfg == PCIEAX1PCIEBX1SATA) {
+ regmap_read(imx_pcie->iomuxc_gpr,
+ IMX8QM_CSR_PHYX2_OFFSET + 0x4,
+ &tmp);
+ if (imx_pcie->ctrl_id == 0) /* pciea 1 lanes */
+ orig = IMX8QM_STTS0_LANE0_TX_PLL_LOCK;
+ else /* pcieb 1 lanes */
+ orig = IMX8QM_STTS0_LANE1_TX_PLL_LOCK;
+ tmp &= orig;
+ if (tmp == orig) {
+ regmap_update_bits(imx_pcie->iomuxc_gpr,
+ IMX8QM_LPCG_PHYX2_OFFSET,
+ IMX8QM_LPCG_PHY_PCG0
+ | IMX8QM_LPCG_PHY_PCG1,
+ IMX8QM_LPCG_PHY_PCG0
+ | IMX8QM_LPCG_PHY_PCG1);
+ break;
+ }
+ }
+
+ if (imx_pcie->hsio_cfg == PCIEAX2PCIEBX1) {
+ val = IMX8QM_CSR_PHYX2_OFFSET
+ + imx_pcie->ctrl_id * SZ_64K;
+ regmap_read(imx_pcie->iomuxc_gpr,
+ val + IMX8QM_CSR_PHYX_STTS0_OFFSET,
+ &tmp);
+ orig = IMX8QM_STTS0_LANE0_TX_PLL_LOCK;
+ if (imx_pcie->ctrl_id == 0) /* pciea 2 lanes */
+ orig |= IMX8QM_STTS0_LANE1_TX_PLL_LOCK;
+ tmp &= orig;
+ if (tmp == orig) {
+ val = IMX8QM_CSR_PHYX2_OFFSET
+ + imx_pcie->ctrl_id * SZ_64K;
+ regmap_update_bits(imx_pcie->iomuxc_gpr,
+ val, IMX8QM_LPCG_PHY_PCG0,
+ IMX8QM_LPCG_PHY_PCG0);
+ break;
+ }
+ }
+ udelay(10);
+ }
+ }
+
+ if (retries >= PHY_PLL_LOCK_WAIT_MAX_RETRIES) {
+ dev_info(dev, "pcie phy pll can't be locked.\n");
+ return -ENODEV;
+ } else {
+ dev_info(dev, "pcie phy pll is locked.\n");
+ return 0;
+ }
+}
+
+static int imx_pcie_deassert_core_reset(struct imx_pcie *imx_pcie)
+{
+ struct dw_pcie *pci = imx_pcie->pci;
+ struct pcie_port *pp = &pci->pp;
+ struct device *dev = pci->dev;
+ int ret, i;
+ u32 val, tmp;
+
+ if (imx_pcie->vpcie && !regulator_is_enabled(imx_pcie->vpcie)) {
+ ret = regulator_enable(imx_pcie->vpcie);
if (ret) {
dev_err(dev, "failed to enable vpcie regulator: %d\n",
ret);
- return;
+ return ret;
}
}
- ret = clk_prepare_enable(imx6_pcie->pcie_phy);
+ if (gpio_is_valid(imx_pcie->power_on_gpio))
+ gpio_set_value_cansleep(imx_pcie->power_on_gpio, 1);
+
+ ret = clk_prepare_enable(imx_pcie->pcie);
if (ret) {
- dev_err(dev, "unable to enable pcie_phy clock\n");
- goto err_pcie_phy;
+ dev_err(dev, "unable to enable pcie clock\n");
+ goto err_pcie;
}
- ret = clk_prepare_enable(imx6_pcie->pcie_bus);
+ if (imx_pcie->ext_osc && (imx_pcie->variant == IMX6QP))
+ clk_set_parent(imx_pcie->pcie_bus,
+ imx_pcie->pcie_ext_src);
+ ret = clk_prepare_enable(imx_pcie->pcie_bus);
if (ret) {
dev_err(dev, "unable to enable pcie_bus clock\n");
goto err_pcie_bus;
}
- ret = clk_prepare_enable(imx6_pcie->pcie);
+ ret = clk_prepare_enable(imx_pcie->pcie_phy);
if (ret) {
- dev_err(dev, "unable to enable pcie clock\n");
- goto err_pcie;
+ dev_err(dev, "unable to enable pcie_phy clock\n");
+ goto err_pcie_phy;
}
- ret = imx6_pcie_enable_ref_clk(imx6_pcie);
+ ret = imx_pcie_enable_ref_clk(imx_pcie);
if (ret) {
dev_err(dev, "unable to enable pcie ref clock\n");
goto err_ref_clk;
}
/* allow the clocks to stabilize */
- usleep_range(200, 500);
-
- /* Some boards don't have PCIe reset GPIO. */
- if (gpio_is_valid(imx6_pcie->reset_gpio)) {
- gpio_set_value_cansleep(imx6_pcie->reset_gpio,
- imx6_pcie->gpio_active_high);
- msleep(100);
- gpio_set_value_cansleep(imx6_pcie->reset_gpio,
- !imx6_pcie->gpio_active_high);
- }
+ udelay(200);
- switch (imx6_pcie->variant) {
- case IMX7D:
- reset_control_deassert(imx6_pcie->pciephy_reset);
- imx7d_pcie_wait_for_phy_pll_lock(imx6_pcie);
- break;
+ switch (imx_pcie->variant) {
case IMX6SX:
- regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR5,
+ regmap_update_bits(imx_pcie->iomuxc_gpr, IOMUXC_GPR5,
IMX6SX_GPR5_PCIE_BTNRST_RESET, 0);
break;
case IMX6QP:
- regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1,
+ regmap_update_bits(imx_pcie->iomuxc_gpr, IOMUXC_GPR1,
+ IMX6Q_GPR1_PCIE_SW_RST, 0);
+
+ udelay(200);
+
+ /* Configure the PHY when 100Mhz external OSC is used as input clock */
+ if (!imx_pcie->ext_osc)
+ break;
+
+ mdelay(4);
+ pcie_phy_read(imx_pcie, SSP_CR_SUP_DIG_MPLL_OVRD_IN_LO, &val);
+ /* MPLL_MULTIPLIER [8:2] */
+ val &= ~(0x7F << 2);
+ val |= (0x19 << 2);
+ /* MPLL_MULTIPLIER_OVRD [9:9] */
+ val |= (0x1 << 9);
+ pcie_phy_write(imx_pcie, SSP_CR_SUP_DIG_MPLL_OVRD_IN_LO, val);
+ mdelay(4);
+
+ pcie_phy_read(imx_pcie, SSP_CR_SUP_DIG_ATEOVRD, &val);
+ /* ref_clkdiv2 [0:0] */
+ val &= ~0x1;
+ /* ateovrd_en [2:2] */
+ val |= 0x4;
+ pcie_phy_write(imx_pcie, SSP_CR_SUP_DIG_ATEOVRD, val);
+ mdelay(4);
+
+ break;
+ case IMX6Q:
+ regmap_update_bits(imx_pcie->iomuxc_gpr, IOMUXC_GPR1,
IMX6Q_GPR1_PCIE_SW_RST, 0);
+ /*
+ * some delay are required by 6qp, after the SW_RST is
+ * cleared, before access the cfg register.
+ */
+ udelay(200);
+ break;
+ case IMX7D:
+ /* wait for more than 10us to release phy g_rst and btnrst */
+ udelay(10);
+ regmap_update_bits(imx_pcie->reg_src, 0x2c, BIT(6), 0);
+ regmap_update_bits(imx_pcie->reg_src, 0x2c, BIT(1), 0);
+
+ /* Add the workaround for ERR010728 */
+ if (unlikely(imx_pcie->phy_base == NULL)) {
+ dev_err(dev, "phy base shouldn't be null.\n");
+ } else {
+ /* De-assert DCC_FB_EN by writing data "0x29". */
+ writel(PCIE_PHY_CMN_REG4_DCC_FB_EN,
+ imx_pcie->phy_base + PCIE_PHY_CMN_REG4);
+ /* Assert RX_EQS and RX_EQS_SEL */
+ writel(PCIE_PHY_CMN_REG24_RX_EQ_SEL
+ | PCIE_PHY_CMN_REG24_RX_EQ,
+ imx_pcie->phy_base + PCIE_PHY_CMN_REG24);
+ /* Assert ATT_MODE by writing data "0xBC". */
+ writel(PCIE_PHY_CMN_REG26_ATT_MODE,
+ imx_pcie->phy_base + PCIE_PHY_CMN_REG26);
+ }
+
+ regmap_update_bits(imx_pcie->reg_src, 0x2c, BIT(2), 0);
+
+ /* wait for phy pll lock firstly. */
+ if (imx7d_pcie_wait_for_phy_pll_lock(imx_pcie))
+ ret = -ENODEV;
+ break;
+ case IMX8QXP:
+ case IMX8QM:
+ /* bit19 PM_REQ_CORE_RST of pciex#_stts0 should be cleared. */
+ for (i = 0; i < 100; i++) {
+ val = IMX8QM_CSR_PCIEA_OFFSET
+ + imx_pcie->ctrl_id * SZ_64K;
+ regmap_read(imx_pcie->iomuxc_gpr,
+ val + IMX8QM_CSR_PCIE_STTS0_OFFSET,
+ &tmp);
+ if ((tmp & IMX8QM_CTRL_STTS0_PM_REQ_CORE_RST) == 0)
+ break;
+ udelay(10);
+ }
+
+ if ((tmp & IMX8QM_CTRL_STTS0_PM_REQ_CORE_RST) != 0)
+ dev_err(dev, "ERROR PM_REQ_CORE_RST is still set.\n");
+
+ /* wait for phy pll lock firstly. */
+ if (imx8_pcie_wait_for_phy_pll_lock(imx_pcie)) {
+ ret = -ENODEV;
+ break;
+ }
+
+ /* set up the cpu address offset */
+ if (imx_pcie->cpu_base)
+ pp->cpu_addr_offset = imx_pcie->cpu_base
+ - pp->mem_base;
+ else
+ pp->cpu_addr_offset = 0;
- usleep_range(200, 500);
+ if (dw_pcie_readl_dbi(pci, PCIE_MISC_CTRL) == 0)
+ dw_pcie_writel_dbi(pci, PCIE_MISC_CTRL,
+ PCIE_MISC_DBI_RO_WR_EN);
break;
- case IMX6Q: /* Nothing to do */
+ case IMX8MM:
+ case IMX8MQ:
+ /* wait for more than 10us to release phy g_rst and btnrst */
+ udelay(10);
+ if (imx_pcie->ctrl_id == 0)
+ val = IMX8MQ_SRC_PCIEPHY_RCR_OFFSET;
+ else
+ val = IMX8MQ_SRC_PCIE2PHY_RCR_OFFSET;
+ regmap_update_bits(imx_pcie->reg_src, val,
+ IMX8MQ_PCIEPHY_BTN |
+ IMX8MQ_PCIEPHY_DOMAIN_EN,
+ IMX8MQ_PCIEPHY_DOMAIN_EN);
+ regmap_update_bits(imx_pcie->reg_src, val,
+ IMX8MQ_PCIEPHY_G_RST |
+ IMX8MQ_PCIEPHY_DOMAIN_EN,
+ IMX8MQ_PCIEPHY_DOMAIN_EN);
+
+ udelay(100);
+ /* wait for phy pll lock firstly. */
+ if (imx8_pcie_wait_for_phy_pll_lock(imx_pcie)) {
+ ret = -ENODEV;
+ break;
+ }
+
+ /*
+ * Configure the CLK_REQ# high, let the L1SS
+ * automatically controlled by HW.
+ */
+ regmap_update_bits(imx_pcie->reg_src, val,
+ IMX8MQ_PCIE_CTRL_APPS_CLK_REQ,
+ IMX8MQ_PCIE_CTRL_APPS_CLK_REQ);
+ regmap_update_bits(imx_pcie->reg_src, val,
+ IMX8MQ_PCIE_CTRL_APPS_EN |
+ IMX8MQ_PCIEPHY_DOMAIN_EN,
+ IMX8MQ_PCIEPHY_DOMAIN_EN);
+
+ if (dw_pcie_readl_dbi(pci, PCIE_MISC_CTRL) == 0)
+ dw_pcie_writel_dbi(pci, PCIE_MISC_CTRL,
+ PCIE_MISC_DBI_RO_WR_EN);
+ /*
+ * Configure the L1 latency of rc to less than 64us
+ * Otherwise, the L1/L1SUB wouldn't be enable by ASPM.
+ */
+ val = readl(pci->dbi_base + SZ_1M +
+ IMX8MQ_PCIE_LINK_CAP_REG_OFFSET);
+ val &= ~PCI_EXP_LNKCAP_L1EL;
+ val |= IMX8MQ_PCIE_LINK_CAP_L1EL_64US;
+ writel(val, pci->dbi_base + SZ_1M +
+ IMX8MQ_PCIE_LINK_CAP_REG_OFFSET);
break;
}
- return;
+ /* Some boards don't have PCIe reset GPIO. */
+ if (gpio_is_valid(imx_pcie->reset_gpio)) {
+ gpio_set_value_cansleep(imx_pcie->reset_gpio,
+ imx_pcie->gpio_active_high);
+ mdelay(20);
+ gpio_set_value_cansleep(imx_pcie->reset_gpio,
+ !imx_pcie->gpio_active_high);
+ mdelay(20);
+ }
+
+ if (ret == 0)
+ return ret;
err_ref_clk:
- clk_disable_unprepare(imx6_pcie->pcie);
-err_pcie:
- clk_disable_unprepare(imx6_pcie->pcie_bus);
-err_pcie_bus:
- clk_disable_unprepare(imx6_pcie->pcie_phy);
+ clk_disable_unprepare(imx_pcie->pcie_phy);
err_pcie_phy:
- if (imx6_pcie->vpcie && regulator_is_enabled(imx6_pcie->vpcie) > 0) {
- ret = regulator_disable(imx6_pcie->vpcie);
+ clk_disable_unprepare(imx_pcie->pcie_bus);
+err_pcie_bus:
+ clk_disable_unprepare(imx_pcie->pcie);
+err_pcie:
+ if (imx_pcie->vpcie && regulator_is_enabled(imx_pcie->vpcie) > 0) {
+ ret = regulator_disable(imx_pcie->vpcie);
if (ret)
dev_err(dev, "failed to disable vpcie regulator: %d\n",
ret);
}
+ return ret;
}
-static void imx6_pcie_init_phy(struct imx6_pcie *imx6_pcie)
+static void imx_pcie_phy_pwr_up(struct imx_pcie *imx_pcie)
{
- switch (imx6_pcie->variant) {
- case IMX7D:
- regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
+ u32 val, offset;
+ unsigned long timeout = jiffies + msecs_to_jiffies(500);
+ struct device *dev = imx_pcie->pci->dev;
+
+ if ((imx_pcie->variant != IMX8MQ) && (imx_pcie->variant != IMX8MM))
+ return;
+ /*
+ * Power up PHY.
+ * pcie phy ref clock select by gpr configuration.
+ * 1? external osc : internal pll
+ */
+
+ if (imx_pcie->ctrl_id == 0)
+ offset = 0;
+ else
+ offset = IMX8MQ_GPC_PGC_PCIE2_BIT_OFFSET;
+
+ regmap_update_bits(imx_pcie->reg_gpc,
+ IMX8MQ_GPC_PGC_CPU_0_1_MAPPING_OFFSET,
+ IMX8MQ_GPC_PGC_PCIE_A53_DOMAIN << offset,
+ IMX8MQ_GPC_PGC_PCIE_A53_DOMAIN << offset);
+ regmap_update_bits(imx_pcie->reg_gpc,
+ IMX8MQ_GPC_PU_PGC_SW_PUP_REQ_OFFSET,
+ IMX8MQ_GPC_PU_PGC_PCIE_SW_PWR_REQ << offset,
+ IMX8MQ_GPC_PU_PGC_PCIE_SW_PWR_REQ << offset);
+
+ regmap_read(imx_pcie->reg_gpc,
+ IMX8MQ_GPC_PU_PGC_SW_PUP_REQ_OFFSET,
+ &val);
+ while (val & (IMX8MQ_GPC_PU_PGC_PCIE_SW_PWR_REQ << offset)) {
+ regmap_read(imx_pcie->reg_gpc,
+ IMX8MQ_GPC_PU_PGC_SW_PUP_REQ_OFFSET,
+ &val);
+ if (time_after(jiffies, timeout)) {
+ dev_err(dev, "CAN NOT PWR UP PCIE%d PHY!\n",
+ imx_pcie->ctrl_id);
+ break;
+ }
+ }
+ udelay(1);
+}
+
+static void imx_pcie_phy_pwr_dn(struct imx_pcie *imx_pcie)
+{
+ u32 val, offset;
+ unsigned long timeout = jiffies + msecs_to_jiffies(500);
+ struct device *dev = imx_pcie->pci->dev;
+
+ if ((imx_pcie->variant != IMX8MQ) && (imx_pcie->variant != IMX8MM))
+ return;
+ /*
+ * Power up PHY.
+ * pcie phy ref clock select by gpr configuration.
+ * 1? external osc : internal pll
+ */
+
+ if (imx_pcie->ctrl_id == 0) {
+ offset = 0;
+ regmap_update_bits(imx_pcie->reg_gpc,
+ IMX8MQ_GPC_PGC_PCIE_CTRL_OFFSET,
+ IMX8MQ_GPC_PCG_PCIE_CTRL_PCR,
+ IMX8MQ_GPC_PCG_PCIE_CTRL_PCR);
+ } else {
+ offset = IMX8MQ_GPC_PGC_PCIE2_BIT_OFFSET;
+ regmap_update_bits(imx_pcie->reg_gpc,
+ IMX8MQ_GPC_PGC_PCIE2_CTRL_OFFSET,
+ IMX8MQ_GPC_PCG_PCIE_CTRL_PCR,
+ IMX8MQ_GPC_PCG_PCIE_CTRL_PCR);
+ }
+
+ regmap_update_bits(imx_pcie->reg_gpc,
+ IMX8MQ_GPC_PGC_CPU_0_1_MAPPING_OFFSET,
+ IMX8MQ_GPC_PGC_PCIE_A53_DOMAIN << offset,
+ IMX8MQ_GPC_PGC_PCIE_A53_DOMAIN << offset);
+ regmap_update_bits(imx_pcie->reg_gpc,
+ IMX8MQ_GPC_PU_PGC_SW_PDN_REQ_OFFSET,
+ IMX8MQ_GPC_PU_PGC_PCIE_SW_PWR_REQ << offset,
+ IMX8MQ_GPC_PU_PGC_PCIE_SW_PWR_REQ << offset);
+
+ regmap_read(imx_pcie->reg_gpc,
+ IMX8MQ_GPC_PU_PGC_SW_PDN_REQ_OFFSET,
+ &val);
+ while (val & (IMX8MQ_GPC_PU_PGC_PCIE_SW_PWR_REQ << offset)) {
+ regmap_read(imx_pcie->reg_gpc,
+ IMX8MQ_GPC_PU_PGC_SW_PDN_REQ_OFFSET,
+ &val);
+ if (time_after(jiffies, timeout)) {
+ dev_err(dev, "CAN NOT PWR DN PCIE%d PHY!\n",
+ imx_pcie->ctrl_id);
+ break;
+ }
+ }
+ udelay(1);
+}
+
+static void imx_pcie_init_phy(struct imx_pcie *imx_pcie)
+{
+ u32 tmp, val;
+ int ret;
+ struct device_node *np;
+ void __iomem *base;
+
+ if (imx_pcie->variant == IMX8QM
+ || imx_pcie->variant == IMX8QXP) {
+ switch (imx_pcie->hsio_cfg) {
+ case PCIEAX2SATA:
+ /*
+ * bit 0 rx ena 1.
+ * bit12 PHY_X1_EPCS_SEL 1.
+ * bit13 phy_ab_select 0.
+ */
+ regmap_update_bits(imx_pcie->iomuxc_gpr,
+ IMX8QM_CSR_PHYX2_OFFSET,
+ IMX8QM_PHYX2_CTRL0_APB_MASK,
+ IMX8QM_PHY_APB_RSTN_0
+ | IMX8QM_PHY_APB_RSTN_1);
+
+ regmap_update_bits(imx_pcie->iomuxc_gpr,
+ IMX8QM_CSR_MISC_OFFSET,
+ IMX8QM_MISC_PHYX1_EPCS_SEL,
+ IMX8QM_MISC_PHYX1_EPCS_SEL);
+ regmap_update_bits(imx_pcie->iomuxc_gpr,
+ IMX8QM_CSR_MISC_OFFSET,
+ IMX8QM_MISC_PCIE_AB_SELECT,
+ 0);
+ break;
+
+ case PCIEAX1PCIEBX1SATA:
+ tmp = IMX8QM_PHY_APB_RSTN_1;
+ tmp |= IMX8QM_PHY_APB_RSTN_0;
+ regmap_update_bits(imx_pcie->iomuxc_gpr,
+ IMX8QM_CSR_PHYX2_OFFSET,
+ IMX8QM_PHYX2_CTRL0_APB_MASK, tmp);
+
+ regmap_update_bits(imx_pcie->iomuxc_gpr,
+ IMX8QM_CSR_MISC_OFFSET,
+ IMX8QM_MISC_PHYX1_EPCS_SEL,
+ IMX8QM_MISC_PHYX1_EPCS_SEL);
+ regmap_update_bits(imx_pcie->iomuxc_gpr,
+ IMX8QM_CSR_MISC_OFFSET,
+ IMX8QM_MISC_PCIE_AB_SELECT,
+ IMX8QM_MISC_PCIE_AB_SELECT);
+ break;
+
+ case PCIEAX2PCIEBX1:
+ /*
+ * bit 0 rx ena 1.
+ * bit12 PHY_X1_EPCS_SEL 0.
+ * bit13 phy_ab_select 1.
+ */
+ if (imx_pcie->ctrl_id)
+ regmap_update_bits(imx_pcie->iomuxc_gpr,
+ IMX8QM_CSR_PHYX1_OFFSET,
+ IMX8QM_PHY_APB_RSTN_0,
+ IMX8QM_PHY_APB_RSTN_0);
+ else
+ regmap_update_bits(imx_pcie->iomuxc_gpr,
+ IMX8QM_CSR_PHYX2_OFFSET,
+ IMX8QM_PHYX2_CTRL0_APB_MASK,
+ IMX8QM_PHY_APB_RSTN_0
+ | IMX8QM_PHY_APB_RSTN_1);
+
+ regmap_update_bits(imx_pcie->iomuxc_gpr,
+ IMX8QM_CSR_MISC_OFFSET,
+ IMX8QM_MISC_PHYX1_EPCS_SEL,
+ 0);
+ regmap_update_bits(imx_pcie->iomuxc_gpr,
+ IMX8QM_CSR_MISC_OFFSET,
+ IMX8QM_MISC_PCIE_AB_SELECT,
+ IMX8QM_MISC_PCIE_AB_SELECT);
+ break;
+ }
+
+ if (imx_pcie->ext_osc) {
+ regmap_update_bits(imx_pcie->iomuxc_gpr,
+ IMX8QM_CSR_MISC_OFFSET,
+ IMX8QM_MISC_IOB_RXENA,
+ IMX8QM_MISC_IOB_RXENA);
+ regmap_update_bits(imx_pcie->iomuxc_gpr,
+ IMX8QM_CSR_MISC_OFFSET,
+ IMX8QM_MISC_IOB_TXENA,
+ 0);
+ } else {
+ /* Try to used the internal pll as ref clk */
+ regmap_update_bits(imx_pcie->iomuxc_gpr,
+ IMX8QM_CSR_MISC_OFFSET,
+ IMX8QM_MISC_IOB_RXENA,
+ 0);
+ regmap_update_bits(imx_pcie->iomuxc_gpr,
+ IMX8QM_CSR_MISC_OFFSET,
+ IMX8QM_MISC_IOB_TXENA,
+ IMX8QM_MISC_IOB_TXENA);
+ regmap_update_bits(imx_pcie->iomuxc_gpr,
+ IMX8QM_CSR_MISC_OFFSET,
+ IMX8QM_CSR_MISC_IOB_A_0_TXOE
+ | IMX8QM_CSR_MISC_IOB_A_0_M1M0_MASK,
+ IMX8QM_CSR_MISC_IOB_A_0_TXOE
+ | IMX8QM_CSR_MISC_IOB_A_0_M1M0_2);
+ }
+ } else if (imx_pcie->variant == IMX8MQ || imx_pcie->variant == IMX8MM) {
+ imx_pcie_phy_pwr_up(imx_pcie);
+
+ if (imx_pcie->ctrl_id == 0)
+ val = IOMUXC_GPR14;
+ else
+ val = IOMUXC_GPR16;
+
+ if (imx_pcie->ext_osc) {
+ regmap_update_bits(imx_pcie->iomuxc_gpr, val,
+ IMX8MQ_GPR_PCIE_REF_USE_PAD,
+ IMX8MQ_GPR_PCIE_REF_USE_PAD);
+ if (imx_pcie->variant == IMX8MM) {
+ dev_info(imx_pcie->pci->dev,
+ "Initialize PHY with EXT REfCLK!.\n");
+ regmap_update_bits(imx_pcie->iomuxc_gpr, val,
+ IMX8MQ_GPR_PCIE_REF_USE_PAD,
+ 0);
+ regmap_update_bits(imx_pcie->iomuxc_gpr, val,
+ IMX8MM_GPR_PCIE_REF_CLK_SEL,
+ IMX8MM_GPR_PCIE_REF_CLK_SEL);
+ regmap_update_bits(imx_pcie->iomuxc_gpr, val,
+ IMX8MM_GPR_PCIE_AUX_EN,
+ IMX8MM_GPR_PCIE_AUX_EN);
+ regmap_update_bits(imx_pcie->iomuxc_gpr, val,
+ IMX8MM_GPR_PCIE_POWER_OFF,
+ 0);
+ regmap_update_bits(imx_pcie->iomuxc_gpr, val,
+ IMX8MM_GPR_PCIE_SSC_EN,
+ 0);
+ regmap_update_bits(imx_pcie->iomuxc_gpr, val,
+ IMX8MM_GPR_PCIE_REF_CLK_SEL,
+ IMX8MM_GPR_PCIE_REF_CLK_EXT);
+ udelay(100);
+ /* Do the PHY common block reset */
+ regmap_update_bits(imx_pcie->iomuxc_gpr, val,
+ IMX8MM_GPR_PCIE_CMN_RST,
+ IMX8MM_GPR_PCIE_CMN_RST);
+ udelay(200);
+ dev_info(imx_pcie->pci->dev,
+ "PHY Initialization End!.\n");
+ }
+ } else {
+ if (imx_pcie->variant == IMX8MM) {
+ /* Configure the internal PLL as REF clock */
+ dev_info(imx_pcie->pci->dev,
+ "Initialize PHY with PLL REfCLK!.\n");
+ regmap_update_bits(imx_pcie->iomuxc_gpr, val,
+ IMX8MQ_GPR_PCIE_REF_USE_PAD,
+ 0);
+ regmap_update_bits(imx_pcie->iomuxc_gpr, val,
+ IMX8MM_GPR_PCIE_REF_CLK_SEL,
+ IMX8MM_GPR_PCIE_REF_CLK_SEL);
+ regmap_update_bits(imx_pcie->iomuxc_gpr, val,
+ IMX8MM_GPR_PCIE_AUX_EN,
+ IMX8MM_GPR_PCIE_AUX_EN);
+ regmap_update_bits(imx_pcie->iomuxc_gpr, val,
+ IMX8MM_GPR_PCIE_POWER_OFF,
+ 0);
+ regmap_update_bits(imx_pcie->iomuxc_gpr, val,
+ IMX8MM_GPR_PCIE_SSC_EN,
+ 0);
+ regmap_update_bits(imx_pcie->iomuxc_gpr, val,
+ IMX8MM_GPR_PCIE_REF_CLK_SEL,
+ IMX8MM_GPR_PCIE_REF_CLK_PLL);
+ udelay(100);
+ /* Configure the PHY */
+ writel(PCIE_PHY_CMN_REG62_PLL_CLK_OUT,
+ imx_pcie->phy_base + PCIE_PHY_CMN_REG62);
+ writel(PCIE_PHY_CMN_REG64_AUX_RX_TX_TERM,
+ imx_pcie->phy_base + PCIE_PHY_CMN_REG64);
+
+ /* Do the PHY common block reset */
+ regmap_update_bits(imx_pcie->iomuxc_gpr, val,
+ IMX8MM_GPR_PCIE_CMN_RST,
+ IMX8MM_GPR_PCIE_CMN_RST);
+ udelay(200);
+ dev_info(imx_pcie->pci->dev,
+ "PHY Initialization End!.\n");
+ } else {
+ np = of_find_compatible_node(NULL, NULL,
+ "fsl,imx8mq-anatop");
+ base = of_iomap(np, 0);
+ WARN_ON(!base);
+
+ val = readl(base + IMX8MQ_ANA_PLLOUT_REG);
+ val &= ~IMX8MQ_ANA_PLLOUT_SEL_MASK;
+ val |= IMX8MQ_ANA_PLLOUT_SEL_SYSPLL1;
+ writel(val, base + IMX8MQ_ANA_PLLOUT_REG);
+ /* SYS_PLL1 is 800M, PCIE REF CLK is 100M */
+ val = readl(base + IMX8MQ_ANA_PLLOUT_DIV_REG);
+ val |= IMX8MQ_ANA_PLLOUT_SYSPLL1_DIV;
+ writel(val, base + IMX8MQ_ANA_PLLOUT_DIV_REG);
+
+ val = readl(base + IMX8MQ_ANA_PLLOUT_REG);
+ val |= IMX8MQ_ANA_PLLOUT_CKE;
+ writel(val, base + IMX8MQ_ANA_PLLOUT_REG);
+ }
+ }
+ /*
+ * In order to pass the compliance tests.
+ * Configure the TRSV regiser of iMX8MM PCIe PHY.
+ */
+ if (imx_pcie->variant == IMX8MM) {
+ writel(PCIE_PHY_TRSV_REG5_GEN1_DEEMP,
+ imx_pcie->phy_base + PCIE_PHY_TRSV_REG5);
+ writel(PCIE_PHY_TRSV_REG6_GEN2_DEEMP,
+ imx_pcie->phy_base + PCIE_PHY_TRSV_REG6);
+ }
+ } else if (imx_pcie->variant == IMX7D) {
+ /* Enable PCIe PHY 1P0D */
+ regulator_set_voltage(imx_pcie->pcie_phy_regulator,
+ 1000000, 1000000);
+ ret = regulator_enable(imx_pcie->pcie_phy_regulator);
+ if (ret)
+ dev_err(imx_pcie->pci->dev,
+ "failed to enable pcie regulator\n");
+
+ /* pcie phy ref clock select; 1? internal pll : external osc */
+ regmap_update_bits(imx_pcie->iomuxc_gpr, IOMUXC_GPR12,
IMX7D_GPR12_PCIE_PHY_REFCLK_SEL, 0);
- break;
- case IMX6SX:
- regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
+ } else if (imx_pcie->variant == IMX6SX) {
+ /* Force PCIe PHY reset */
+ regmap_update_bits(imx_pcie->iomuxc_gpr, IOMUXC_GPR5,
+ IMX6SX_GPR5_PCIE_BTNRST_RESET,
+ IMX6SX_GPR5_PCIE_BTNRST_RESET);
+
+ regulator_set_voltage(imx_pcie->pcie_phy_regulator,
+ 1100000, 1100000);
+ ret = regulator_enable(imx_pcie->pcie_phy_regulator);
+ if (ret)
+ dev_err(imx_pcie->pci->dev,
+ "failed to enable pcie regulator.\n");
+ regmap_update_bits(imx_pcie->iomuxc_gpr, IOMUXC_GPR12,
IMX6SX_GPR12_PCIE_RX_EQ_MASK,
IMX6SX_GPR12_PCIE_RX_EQ_2);
- /* FALLTHROUGH */
- default:
- regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
+ }
+
+ if (imx_pcie->pcie_bus_regulator != NULL) {
+ ret = regulator_enable(imx_pcie->pcie_bus_regulator);
+ if (ret)
+ dev_err(imx_pcie->pci->dev, "failed to enable pcie regulator.\n");
+ }
+
+ if ((imx_pcie->variant == IMX6Q) || (imx_pcie->variant == IMX6QP)
+ || (imx_pcie->variant == IMX6SX)) {
+ regmap_update_bits(imx_pcie->iomuxc_gpr, IOMUXC_GPR12,
IMX6Q_GPR12_PCIE_CTL_2, 0 << 10);
/* configure constant input signal to the pcie ctrl and phy */
- regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
- IMX6Q_GPR12_LOS_LEVEL, 9 << 4);
+ regmap_update_bits(imx_pcie->iomuxc_gpr, IOMUXC_GPR12,
+ IMX6Q_GPR12_LOS_LEVEL, IMX6Q_GPR12_LOS_LEVEL_9);
- regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR8,
+ regmap_update_bits(imx_pcie->iomuxc_gpr, IOMUXC_GPR8,
IMX6Q_GPR8_TX_DEEMPH_GEN1,
- imx6_pcie->tx_deemph_gen1 << 0);
- regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR8,
+ imx_pcie->tx_deemph_gen1 << 0);
+ regmap_update_bits(imx_pcie->iomuxc_gpr, IOMUXC_GPR8,
IMX6Q_GPR8_TX_DEEMPH_GEN2_3P5DB,
- imx6_pcie->tx_deemph_gen2_3p5db << 6);
- regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR8,
+ imx_pcie->tx_deemph_gen2_3p5db << 6);
+ regmap_update_bits(imx_pcie->iomuxc_gpr, IOMUXC_GPR8,
IMX6Q_GPR8_TX_DEEMPH_GEN2_6DB,
- imx6_pcie->tx_deemph_gen2_6db << 12);
- regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR8,
+ imx_pcie->tx_deemph_gen2_6db << 12);
+ regmap_update_bits(imx_pcie->iomuxc_gpr, IOMUXC_GPR8,
IMX6Q_GPR8_TX_SWING_FULL,
- imx6_pcie->tx_swing_full << 18);
- regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR8,
+ imx_pcie->tx_swing_full << 18);
+ regmap_update_bits(imx_pcie->iomuxc_gpr, IOMUXC_GPR8,
IMX6Q_GPR8_TX_SWING_LOW,
- imx6_pcie->tx_swing_low << 25);
- break;
+ imx_pcie->tx_swing_low << 25);
}
- regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
- IMX6Q_GPR12_DEVICE_TYPE, PCI_EXP_TYPE_ROOT_PORT << 12);
+ /* configure the device type */
+ if (IS_ENABLED(CONFIG_EP_MODE_IN_EP_RC_SYS)) {
+ if (imx_pcie->variant == IMX8QM
+ || imx_pcie->variant == IMX8QXP) {
+ val = IMX8QM_CSR_PCIEA_OFFSET
+ + imx_pcie->ctrl_id * SZ_64K;
+ regmap_update_bits(imx_pcie->iomuxc_gpr,
+ val, IMX8QM_PCIE_TYPE_MASK,
+ PCI_EXP_TYPE_ENDPOINT << 24);
+ } else {
+ if (unlikely(imx_pcie->ctrl_id))
+ /* iMX8MQ second PCIE */
+ regmap_update_bits(imx_pcie->iomuxc_gpr,
+ IOMUXC_GPR12,
+ IMX6Q_GPR12_DEVICE_TYPE >> 4,
+ PCI_EXP_TYPE_ENDPOINT << 8);
+ else
+ regmap_update_bits(imx_pcie->iomuxc_gpr,
+ IOMUXC_GPR12,
+ IMX6Q_GPR12_DEVICE_TYPE,
+ PCI_EXP_TYPE_ENDPOINT << 12);
+ }
+ } else {
+ if (imx_pcie->variant == IMX8QM
+ || imx_pcie->variant == IMX8QXP) {
+ val = IMX8QM_CSR_PCIEA_OFFSET
+ + imx_pcie->ctrl_id * SZ_64K;
+ regmap_update_bits(imx_pcie->iomuxc_gpr,
+ val, IMX8QM_PCIE_TYPE_MASK,
+ PCI_EXP_TYPE_ROOT_PORT << 24);
+ } else {
+ if (unlikely(imx_pcie->ctrl_id))
+ /* iMX8MQ second PCIE */
+ regmap_update_bits(imx_pcie->iomuxc_gpr,
+ IOMUXC_GPR12,
+ IMX6Q_GPR12_DEVICE_TYPE >> 4,
+ PCI_EXP_TYPE_ROOT_PORT << 8);
+ else
+ regmap_update_bits(imx_pcie->iomuxc_gpr,
+ IOMUXC_GPR12,
+ IMX6Q_GPR12_DEVICE_TYPE,
+ PCI_EXP_TYPE_ROOT_PORT << 12);
+ }
+ }
}
-static int imx6_pcie_wait_for_link(struct imx6_pcie *imx6_pcie)
+static int imx_pcie_wait_for_link(struct imx_pcie *imx_pcie)
{
- struct dw_pcie *pci = imx6_pcie->pci;
+ int count = 20000;
+ struct dw_pcie *pci = imx_pcie->pci;
struct device *dev = pci->dev;
/* check if the link is up or not */
- if (!dw_pcie_wait_for_link(pci))
- return 0;
+ while (!dw_pcie_link_up(pci)) {
+ udelay(10);
+ if (--count)
+ continue;
+
+ dev_err(dev, "phy link never came up\n");
+ dev_dbg(dev, "DEBUG_R0: 0x%08x, DEBUG_R1: 0x%08x\n",
+ dw_pcie_readl_dbi(pci, PCIE_PHY_DEBUG_R0),
+ dw_pcie_readl_dbi(pci, PCIE_PHY_DEBUG_R1));
+ return -ETIMEDOUT;
+ }
- dev_dbg(dev, "DEBUG_R0: 0x%08x, DEBUG_R1: 0x%08x\n",
- dw_pcie_readl_dbi(pci, PCIE_PHY_DEBUG_R0),
- dw_pcie_readl_dbi(pci, PCIE_PHY_DEBUG_R1));
- return -ETIMEDOUT;
+ return 0;
}
-static int imx6_pcie_wait_for_speed_change(struct imx6_pcie *imx6_pcie)
+static int imx_pcie_wait_for_speed_change(struct imx_pcie *imx_pcie)
{
- struct dw_pcie *pci = imx6_pcie->pci;
+ struct dw_pcie *pci = imx_pcie->pci;
struct device *dev = pci->dev;
u32 tmp;
unsigned int retries;
@@ -536,25 +1434,116 @@ static int imx6_pcie_wait_for_speed_change(struct imx6_pcie *imx6_pcie)
/* Test if the speed change finished. */
if (!(tmp & PORT_LOGIC_SPEED_CHANGE))
return 0;
- usleep_range(100, 1000);
+ udelay(100);
}
dev_err(dev, "Speed change timeout\n");
return -EINVAL;
}
-static irqreturn_t imx6_pcie_msi_handler(int irq, void *arg)
+static irqreturn_t imx_pcie_msi_handler(int irq, void *arg)
{
- struct imx6_pcie *imx6_pcie = arg;
- struct dw_pcie *pci = imx6_pcie->pci;
+ struct imx_pcie *imx_pcie = arg;
+ struct dw_pcie *pci = imx_pcie->pci;
struct pcie_port *pp = &pci->pp;
return dw_handle_msi_irq(pp);
}
-static int imx6_pcie_establish_link(struct imx6_pcie *imx6_pcie)
+static void pci_imx_clk_disable(struct device *dev)
+{
+ u32 val;
+ struct imx_pcie *imx_pcie = dev_get_drvdata(dev);
+
+ clk_disable_unprepare(imx_pcie->pcie);
+ clk_disable_unprepare(imx_pcie->pcie_phy);
+ clk_disable_unprepare(imx_pcie->pcie_bus);
+ switch (imx_pcie->variant) {
+ case IMX6Q:
+ break;
+ case IMX6SX:
+ clk_disable_unprepare(imx_pcie->pcie_inbound_axi);
+ break;
+ case IMX6QP:
+ regmap_update_bits(imx_pcie->iomuxc_gpr, IOMUXC_GPR1,
+ IMX6Q_GPR1_PCIE_REF_CLK_EN, 0);
+ regmap_update_bits(imx_pcie->iomuxc_gpr, IOMUXC_GPR1,
+ IMX6Q_GPR1_PCIE_TEST_PD,
+ IMX6Q_GPR1_PCIE_TEST_PD);
+ break;
+ case IMX7D:
+ /* turn off external osc input */
+ regmap_update_bits(imx_pcie->iomuxc_gpr, IOMUXC_GPR12,
+ BIT(5), BIT(5));
+ break;
+ /*
+ * Disable the over ride.
+ * Configure the CLK_REQ# high, let the L1SS automatically
+ * controlled by HW when link is up.
+ * Otherwise, turn off the REF_CLK to save power consumption.
+ */
+ case IMX8MQ:
+ case IMX8MM:
+ if (imx_pcie->ctrl_id == 0)
+ val = IOMUXC_GPR14;
+ else
+ val = IOMUXC_GPR16;
+
+ regmap_update_bits(imx_pcie->iomuxc_gpr, val,
+ IMX8MQ_GPR_PCIE_CLK_REQ_OVERRIDE_EN,
+ 0);
+ break;
+ case IMX8QXP:
+ case IMX8QM:
+ clk_disable_unprepare(imx_pcie->pcie_per);
+ clk_disable_unprepare(imx_pcie->pcie_inbound_axi);
+ break;
+ }
+}
+
+static void pci_imx_ltssm_enable(struct device *dev)
+{
+ u32 val;
+ struct imx_pcie *imx_pcie = dev_get_drvdata(dev);
+
+ switch (imx_pcie->variant) {
+ case IMX6Q:
+ case IMX6SX:
+ case IMX6QP:
+ regmap_update_bits(imx_pcie->iomuxc_gpr, IOMUXC_GPR12,
+ IMX6Q_GPR12_PCIE_CTL_2,
+ IMX6Q_GPR12_PCIE_CTL_2);
+ break;
+ case IMX7D:
+ case IMX8MQ:
+ case IMX8MM:
+ if (imx_pcie->ctrl_id == 0)
+ val = IMX8MQ_SRC_PCIEPHY_RCR_OFFSET;
+ else
+ val = IMX8MQ_SRC_PCIE2PHY_RCR_OFFSET;
+ regmap_update_bits(imx_pcie->reg_src, val,
+ IMX8MQ_PCIE_CTRL_APPS_EN |
+ IMX8MQ_PCIEPHY_DOMAIN_EN,
+ IMX8MQ_PCIE_CTRL_APPS_EN |
+ IMX8MQ_PCIEPHY_DOMAIN_EN);
+ break;
+ case IMX8QXP:
+ case IMX8QM:
+ /* Bit4 of the CTRL2 */
+ val = IMX8QM_CSR_PCIEA_OFFSET
+ + imx_pcie->ctrl_id * SZ_64K;
+ regmap_update_bits(imx_pcie->iomuxc_gpr,
+ val + IMX8QM_CSR_PCIE_CTRL2_OFFSET,
+ IMX8QM_CTRL_LTSSM_ENABLE,
+ IMX8QM_CTRL_LTSSM_ENABLE);
+ break;
+ }
+
+}
+
+static int imx_pcie_establish_link(struct imx_pcie *imx_pcie)
{
- struct dw_pcie *pci = imx6_pcie->pci;
+ struct dw_pcie *pci = imx_pcie->pci;
struct device *dev = pci->dev;
u32 tmp;
int ret;
@@ -564,27 +1553,25 @@ static int imx6_pcie_establish_link(struct imx6_pcie *imx6_pcie)
* started in Gen2 mode, there is a possibility the devices on the
* bus will not be detected at all. This happens with PCIe switches.
*/
- tmp = dw_pcie_readl_dbi(pci, PCIE_RC_LCR);
- tmp &= ~PCIE_RC_LCR_MAX_LINK_SPEEDS_MASK;
- tmp |= PCIE_RC_LCR_MAX_LINK_SPEEDS_GEN1;
- dw_pcie_writel_dbi(pci, PCIE_RC_LCR, tmp);
+ if (!IS_ENABLED(CONFIG_PCI_IMX6_COMPLIANCE_TEST)) {
+ tmp = dw_pcie_readl_dbi(pci, PCIE_RC_LCR);
+ tmp &= ~PCIE_RC_LCR_MAX_LINK_SPEEDS_MASK;
+ tmp |= PCIE_RC_LCR_MAX_LINK_SPEEDS_GEN1;
+ dw_pcie_writel_dbi(pci, PCIE_RC_LCR, tmp);
+ }
/* Start LTSSM. */
- if (imx6_pcie->variant == IMX7D)
- reset_control_deassert(imx6_pcie->apps_reset);
- else
- regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
- IMX6Q_GPR12_PCIE_CTL_2, 1 << 10);
+ pci_imx_ltssm_enable(dev);
- ret = imx6_pcie_wait_for_link(imx6_pcie);
+ ret = imx_pcie_wait_for_link(imx_pcie);
if (ret)
goto err_reset_phy;
- if (imx6_pcie->link_gen == 2) {
+ if (imx_pcie->link_gen >= 2) {
/* Allow Gen2 mode after the link is up. */
tmp = dw_pcie_readl_dbi(pci, PCIE_RC_LCR);
tmp &= ~PCIE_RC_LCR_MAX_LINK_SPEEDS_MASK;
- tmp |= PCIE_RC_LCR_MAX_LINK_SPEEDS_GEN2;
+ tmp |= imx_pcie->link_gen;
dw_pcie_writel_dbi(pci, PCIE_RC_LCR, tmp);
/*
@@ -595,7 +1582,7 @@ static int imx6_pcie_establish_link(struct imx6_pcie *imx6_pcie)
tmp |= PORT_LOGIC_SPEED_CHANGE;
dw_pcie_writel_dbi(pci, PCIE_LINK_WIDTH_SPEED_CONTROL, tmp);
- if (imx6_pcie->variant != IMX7D) {
+ if (imx_pcie->variant != IMX7D) {
/*
* On i.MX7, DIRECT_SPEED_CHANGE behaves differently
* from i.MX6 family when no link speed transition
@@ -605,15 +1592,14 @@ static int imx6_pcie_establish_link(struct imx6_pcie *imx6_pcie)
* failure.
*/
- ret = imx6_pcie_wait_for_speed_change(imx6_pcie);
+ ret = imx_pcie_wait_for_speed_change(imx_pcie);
if (ret) {
- dev_err(dev, "Failed to bring link up!\n");
- goto err_reset_phy;
+ dev_info(dev, "Roll back to GEN1 link!\n");
}
}
/* Make sure link training is finished as well! */
- ret = imx6_pcie_wait_for_link(imx6_pcie);
+ ret = imx_pcie_wait_for_link(imx_pcie);
if (ret) {
dev_err(dev, "Failed to bring link up!\n");
goto err_reset_phy;
@@ -630,35 +1616,63 @@ err_reset_phy:
dev_dbg(dev, "PHY DEBUG_R0=0x%08x DEBUG_R1=0x%08x\n",
dw_pcie_readl_dbi(pci, PCIE_PHY_DEBUG_R0),
dw_pcie_readl_dbi(pci, PCIE_PHY_DEBUG_R1));
- imx6_pcie_reset_phy(imx6_pcie);
+ imx_pcie_reset_phy(imx_pcie);
+
+ if (!IS_ENABLED(CONFIG_PCI_IMX6_COMPLIANCE_TEST)) {
+ pci_imx_clk_disable(dev);
+ pm_runtime_put_sync(pci->dev);
+ imx_pcie_phy_pwr_dn(imx_pcie);
+ if (imx_pcie->pcie_phy_regulator != NULL)
+ regulator_disable(imx_pcie->pcie_phy_regulator);
+ if (imx_pcie->pcie_bus_regulator != NULL)
+ regulator_disable(imx_pcie->pcie_bus_regulator);
+ }
+
return ret;
}
-static int imx6_pcie_host_init(struct pcie_port *pp)
+static int imx_pcie_host_init(struct pcie_port *pp)
{
+ int ret;
struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
- struct imx6_pcie *imx6_pcie = to_imx6_pcie(pci);
+ struct imx_pcie *imx_pcie = to_imx_pcie(pci);
- imx6_pcie_assert_core_reset(imx6_pcie);
- imx6_pcie_init_phy(imx6_pcie);
- imx6_pcie_deassert_core_reset(imx6_pcie);
- dw_pcie_setup_rc(pp);
- imx6_pcie_establish_link(imx6_pcie);
+ /* enable disp_mix power domain */
+ pm_runtime_get_sync(pci->dev);
- if (IS_ENABLED(CONFIG_PCI_MSI))
- dw_pcie_msi_init(pp);
+ imx_pcie_assert_core_reset(imx_pcie);
+ imx_pcie_init_phy(imx_pcie);
+ ret = imx_pcie_deassert_core_reset(imx_pcie);
+ if (ret < 0)
+ return ret;
+
+ if (!IS_ENABLED(CONFIG_EP_MODE_IN_EP_RC_SYS)) {
+ dw_pcie_setup_rc(pp);
+ ret = imx_pcie_establish_link(imx_pcie);
+ if (ret < 0)
+ return ret;
+
+ if (IS_ENABLED(CONFIG_PCI_MSI))
+ dw_pcie_msi_init(pp);
+ }
return 0;
}
-static const struct dw_pcie_host_ops imx6_pcie_host_ops = {
- .host_init = imx6_pcie_host_init,
+static int imx_pcie_link_up(struct dw_pcie *pci)
+{
+ return dw_pcie_readl_dbi(pci, PCIE_PHY_DEBUG_R1) &
+ PCIE_PHY_DEBUG_R1_XMLH_LINK_UP;
+}
+
+static const struct dw_pcie_host_ops imx_pcie_host_ops = {
+ .host_init = imx_pcie_host_init,
};
-static int imx6_add_pcie_port(struct imx6_pcie *imx6_pcie,
+static int imx_add_pcie_port(struct imx_pcie *imx_pcie,
struct platform_device *pdev)
{
- struct dw_pcie *pci = imx6_pcie->pci;
+ struct dw_pcie *pci = imx_pcie->pci;
struct pcie_port *pp = &pci->pp;
struct device *dev = &pdev->dev;
int ret;
@@ -671,9 +1685,9 @@ static int imx6_add_pcie_port(struct imx6_pcie *imx6_pcie,
}
ret = devm_request_irq(dev, pp->msi_irq,
- imx6_pcie_msi_handler,
+ imx_pcie_msi_handler,
IRQF_SHARED | IRQF_NO_THREAD,
- "mx6-pcie-msi", imx6_pcie);
+ "mx6-pcie-msi", imx_pcie);
if (ret) {
dev_err(dev, "failed to request MSI irq\n");
return ret;
@@ -681,7 +1695,7 @@ static int imx6_add_pcie_port(struct imx6_pcie *imx6_pcie,
}
pp->root_bus_nr = -1;
- pp->ops = &imx6_pcie_host_ops;
+ pp->ops = &imx_pcie_host_ops;
ret = dw_pcie_host_init(pp);
if (ret) {
@@ -693,20 +1707,582 @@ static int imx6_add_pcie_port(struct imx6_pcie *imx6_pcie,
}
static const struct dw_pcie_ops dw_pcie_ops = {
- /* No special ops needed, but pcie-designware still expects this struct */
+ .link_up = imx_pcie_link_up,
+};
+
+static ssize_t imx_pcie_bar0_addr_info(struct device *dev,
+ struct device_attribute *devattr, char *buf)
+{
+ struct imx_pcie *imx_pcie = dev_get_drvdata(dev);
+ struct dw_pcie *pci = imx_pcie->pci;
+
+ return sprintf(buf, "imx-pcie-bar0-addr-info start 0x%08x\n",
+ readl(pci->dbi_base + PCI_BASE_ADDRESS_0));
+}
+
+static ssize_t imx_pcie_bar0_addr_start(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ u32 bar_start;
+ struct imx_pcie *imx_pcie = dev_get_drvdata(dev);
+ struct dw_pcie *pci = imx_pcie->pci;
+
+ sscanf(buf, "%x\n", &bar_start);
+ writel(bar_start, pci->dbi_base + PCI_BASE_ADDRESS_0);
+
+ return count;
+}
+
+static void imx_pcie_regions_setup(struct device *dev)
+{
+ struct imx_pcie *imx_pcie = dev_get_drvdata(dev);
+ struct dw_pcie *pci = imx_pcie->pci;
+ struct pcie_port *pp = &pci->pp;
+
+ switch (imx_pcie->variant) {
+ case IMX8QM:
+ case IMX8QXP:
+ case IMX8MQ:
+ case IMX8MM:
+ /*
+ * RPMSG reserved 4Mbytes, but only used up to 2Mbytes.
+ * The left 2Mbytes can be used here.
+ */
+ if (ddr_test_region == 0)
+ dev_err(dev, "invalid ddr test region.\n");
+ break;
+ case IMX6SX:
+ case IMX7D:
+ ddr_test_region = 0xb0000000;
+ break;
+
+ case IMX6Q:
+ case IMX6QP:
+ ddr_test_region = 0x40000000;
+ break;
+ }
+ dev_info(dev, "ddr_test_region is 0x%08x.\n", ddr_test_region);
+
+ dw_pcie_prog_outbound_atu(pci, 2, 0, pp->mem_base,
+ ddr_test_region, test_region_size);
+}
+
+static ssize_t imx_pcie_memw_info(struct device *dev,
+ struct device_attribute *devattr, char *buf)
+{
+ return sprintf(buf, "imx-pcie-rc-memw-info start 0x%08x, size 0x%08x\n",
+ ddr_test_region, test_region_size);
+}
+
+static ssize_t
+imx_pcie_memw_start(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ u32 memw_start;
+ struct imx_pcie *imx_pcie = dev_get_drvdata(dev);
+
+ sscanf(buf, "%x\n", &memw_start);
+
+ if (imx_pcie->variant == IMX7D || imx_pcie->variant == IMX6SX) {
+ if (memw_start < 0x80000000 || memw_start > 0xb0000000) {
+ dev_err(dev, "Invalid memory start addr.\n");
+ dev_info(dev, "e.x: echo 0xb0000000 > /sys/...");
+ return -1;
+ }
+ } else {
+ if (memw_start < 0x10000000 || memw_start > 0x40000000) {
+ dev_err(dev, "Invalid imx6q sd memory start addr.\n");
+ dev_info(dev, "e.x: echo 0x30000000 > /sys/...");
+ return -1;
+ }
+ }
+
+ if (ddr_test_region != memw_start) {
+ ddr_test_region = memw_start;
+ imx_pcie_regions_setup(dev);
+ }
+
+ return count;
+}
+
+static ssize_t
+imx_pcie_memw_size(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ u32 memw_size;
+
+ sscanf(buf, "%x\n", &memw_size);
+
+ if ((memw_size > (SZ_16M - SZ_1M)) || (memw_size < SZ_64K)) {
+ dev_err(dev, "Invalid, should be [SZ_64K,SZ_16M - SZ_1MB].\n");
+ dev_info(dev, "For example: echo 0x200000 > /sys/...");
+ return -1;
+ }
+
+ if (test_region_size != memw_size) {
+ test_region_size = memw_size;
+ imx_pcie_regions_setup(dev);
+ }
+
+ return count;
+}
+
+static ssize_t imx_pcie_bus_freq(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ int ret;
+ u32 bus_freq;
+
+ ret = sscanf(buf, "%x\n", &bus_freq);
+ if (ret != 1)
+ return -EINVAL;
+ if (bus_freq) {
+ dev_info(dev, "pcie request bus freq high.\n");
+ request_bus_freq(BUS_FREQ_HIGH);
+ } else {
+ dev_info(dev, "pcie release bus freq high.\n");
+ release_bus_freq(BUS_FREQ_HIGH);
+ }
+
+ return count;
+}
+
+static DEVICE_ATTR(memw_info, S_IRUGO, imx_pcie_memw_info, NULL);
+static DEVICE_ATTR(memw_start_set, S_IWUSR, NULL, imx_pcie_memw_start);
+static DEVICE_ATTR(memw_size_set, S_IWUSR, NULL, imx_pcie_memw_size);
+static DEVICE_ATTR(ep_bar0_addr, S_IWUSR | S_IRUGO, imx_pcie_bar0_addr_info,
+ imx_pcie_bar0_addr_start);
+static DEVICE_ATTR(bus_freq, 0200, NULL, imx_pcie_bus_freq);
+
+static struct attribute *imx_pcie_ep_attrs[] = {
+ /*
+ * The start address, and the limitation (64KB ~ (16MB - 1MB))
+ * of the ddr mem window reserved by RC, and used for EP to access.
+ * BTW, these attrs are only configured at EP side.
+ */
+ &dev_attr_memw_info.attr,
+ &dev_attr_memw_start_set.attr,
+ &dev_attr_memw_size_set.attr,
+ &dev_attr_ep_bar0_addr.attr,
+ NULL
+};
+
+static struct attribute *imx_pcie_rc_attrs[] = {
+ &dev_attr_bus_freq.attr,
+ NULL
+};
+
+static struct attribute_group imx_pcie_attrgroup = {
+ .attrs = imx_pcie_ep_attrs,
};
-static int imx6_pcie_probe(struct platform_device *pdev)
+static void imx_pcie_setup_ep(struct dw_pcie *pci)
+{
+ int ret;
+ u32 val;
+ u32 lanes;
+ struct device_node *np = pci->dev->of_node;
+
+ ret = of_property_read_u32(np, "num-lanes", &lanes);
+ if (ret)
+ lanes = 0;
+
+ /* set the number of lanes */
+ val = dw_pcie_readl_dbi(pci, PCIE_PORT_LINK_CONTROL);
+ val &= ~PORT_LINK_MODE_MASK;
+ switch (lanes) {
+ case 1:
+ val |= PORT_LINK_MODE_1_LANES;
+ break;
+ case 2:
+ val |= PORT_LINK_MODE_2_LANES;
+ break;
+ default:
+ dev_err(pci->dev, "num-lanes %u: invalid value\n", lanes);
+ return;
+ }
+ dw_pcie_writel_dbi(pci, PCIE_PORT_LINK_CONTROL, val);
+
+ /* set link width speed control register */
+ val = dw_pcie_readl_dbi(pci, PCIE_LINK_WIDTH_SPEED_CONTROL);
+ val &= ~PORT_LOGIC_LINK_WIDTH_MASK;
+ switch (lanes) {
+ case 1:
+ val |= PORT_LOGIC_LINK_WIDTH_1_LANES;
+ break;
+ case 2:
+ val |= PORT_LOGIC_LINK_WIDTH_2_LANES;
+ break;
+ }
+ dw_pcie_writel_dbi(pci, PCIE_LINK_WIDTH_SPEED_CONTROL, val);
+
+ /* get iATU unroll support */
+ val = dw_pcie_readl_dbi(pci, PCIE_ATU_VIEWPORT);
+ if (val == 0xffffffff)
+ pci->iatu_unroll_enabled = 1;
+ dev_info(pci->dev, "iATU unroll: %s\n",
+ pci->iatu_unroll_enabled ? "enabled" : "disabled");
+
+ /* CMD reg:I/O space, MEM space, and Bus Master Enable */
+ writel(readl(pci->dbi_base + PCI_COMMAND)
+ | PCI_COMMAND_IO
+ | PCI_COMMAND_MEMORY
+ | PCI_COMMAND_MASTER,
+ pci->dbi_base + PCI_COMMAND);
+
+ /*
+ * configure the class_rev(emaluate one memory ram ep device),
+ * bar0 and bar1 of ep
+ */
+ writel(0xdeadbeaf, pci->dbi_base + PCI_VENDOR_ID);
+ writel((readl(pci->dbi_base + PCI_CLASS_REVISION) & 0xFFFF)
+ | (PCI_CLASS_MEMORY_RAM << 16),
+ pci->dbi_base + PCI_CLASS_REVISION);
+ writel(0xdeadbeaf, pci->dbi_base
+ + PCI_SUBSYSTEM_VENDOR_ID);
+
+ /* 32bit none-prefetchable 8M bytes memory on bar0 */
+ writel(0x0, pci->dbi_base + PCI_BASE_ADDRESS_0);
+ writel(SZ_8M - 1, pci->dbi_base + (1 << 12)
+ + PCI_BASE_ADDRESS_0);
+
+ /* None used bar1 */
+ writel(0x0, pci->dbi_base + PCI_BASE_ADDRESS_1);
+ writel(0, pci->dbi_base + (1 << 12) + PCI_BASE_ADDRESS_1);
+
+ /* 4K bytes IO on bar2 */
+ writel(0x1, pci->dbi_base + PCI_BASE_ADDRESS_2);
+ writel(SZ_4K - 1, pci->dbi_base + (1 << 12) +
+ PCI_BASE_ADDRESS_2);
+
+ /*
+ * 32bit prefetchable 1M bytes memory on bar3
+ * FIXME BAR MASK3 is not changable, the size
+ * is fixed to 256 bytes.
+ */
+ writel(0x8, pci->dbi_base + PCI_BASE_ADDRESS_3);
+ writel(SZ_1M - 1, pci->dbi_base + (1 << 12)
+ + PCI_BASE_ADDRESS_3);
+
+ /*
+ * 64bit prefetchable 1M bytes memory on bar4-5.
+ * FIXME BAR4,5 are not enabled yet
+ */
+ writel(0xc, pci->dbi_base + PCI_BASE_ADDRESS_4);
+ writel(SZ_1M - 1, pci->dbi_base + (1 << 12)
+ + PCI_BASE_ADDRESS_4);
+ writel(0, pci->dbi_base + (1 << 12) + PCI_BASE_ADDRESS_5);
+}
+
+#ifdef CONFIG_PM_SLEEP
+/* PM_TURN_OFF */
+static void pci_imx_pm_turn_off(struct imx_pcie *imx_pcie)
+{
+ int i;
+ u32 dst, val;
+ struct device *dev = imx_pcie->pci->dev;
+
+ /* PM_TURN_OFF */
+ switch (imx_pcie->variant) {
+ case IMX6SX:
+ regmap_update_bits(imx_pcie->iomuxc_gpr, IOMUXC_GPR12,
+ IMX6SX_GPR12_PCIE_PM_TURN_OFF,
+ IMX6SX_GPR12_PCIE_PM_TURN_OFF);
+ regmap_update_bits(imx_pcie->iomuxc_gpr, IOMUXC_GPR12,
+ IMX6SX_GPR12_PCIE_PM_TURN_OFF, 0);
+ break;
+ case IMX6QP:
+ regmap_update_bits(imx_pcie->iomuxc_gpr, IOMUXC_GPR12,
+ IMX6Q_GPR12_PCIE_PM_TURN_OFF,
+ IMX6Q_GPR12_PCIE_PM_TURN_OFF);
+ regmap_update_bits(imx_pcie->iomuxc_gpr, IOMUXC_GPR12,
+ IMX6Q_GPR12_PCIE_PM_TURN_OFF, 0);
+ break;
+ case IMX7D:
+ case IMX8MQ:
+ case IMX8MM:
+ if (imx_pcie->ctrl_id == 0)
+ dst = IMX8MQ_SRC_PCIEPHY_RCR_OFFSET;
+ else
+ dst = IMX8MQ_SRC_PCIE2PHY_RCR_OFFSET;
+ regmap_update_bits(imx_pcie->reg_src, dst,
+ IMX8MQ_PCIE_CTRL_APPS_TURNOFF |
+ IMX8MQ_PCIEPHY_DOMAIN_EN,
+ IMX8MQ_PCIE_CTRL_APPS_TURNOFF |
+ IMX8MQ_PCIEPHY_DOMAIN_EN);
+ regmap_update_bits(imx_pcie->reg_src, dst,
+ IMX8MQ_PCIE_CTRL_APPS_TURNOFF |
+ IMX8MQ_PCIEPHY_DOMAIN_EN,
+ IMX8MQ_PCIEPHY_DOMAIN_EN);
+ break;
+ case IMX8QXP:
+ case IMX8QM:
+ dst = IMX8QM_CSR_PCIEA_OFFSET + imx_pcie->ctrl_id * SZ_64K;
+ regmap_update_bits(imx_pcie->iomuxc_gpr,
+ dst + IMX8QM_CSR_PCIE_CTRL2_OFFSET,
+ IMX8QM_CTRL_PM_XMT_TURNOFF,
+ IMX8QM_CTRL_PM_XMT_TURNOFF);
+ regmap_update_bits(imx_pcie->iomuxc_gpr,
+ dst + IMX8QM_CSR_PCIE_CTRL2_OFFSET,
+ IMX8QM_CTRL_PM_XMT_TURNOFF,
+ 0);
+ regmap_update_bits(imx_pcie->iomuxc_gpr,
+ dst + IMX8QM_CSR_PCIE_CTRL2_OFFSET,
+ IMX8QM_CTRL_READY_ENTR_L23,
+ IMX8QM_CTRL_READY_ENTR_L23);
+ /* check the L2 is entered or not. */
+ for (i = 0; i < 10000; i++) {
+ regmap_read(imx_pcie->iomuxc_gpr,
+ dst + IMX8QM_CSR_PCIE_STTS0_OFFSET,
+ &val);
+ if (val & IMX8QM_CTRL_STTS0_PM_LINKST_IN_L2)
+ break;
+ udelay(10);
+ }
+ if ((val & IMX8QM_CTRL_STTS0_PM_LINKST_IN_L2) == 0)
+ dev_err(dev, "PCIE%d can't enter into L2.\n",
+ imx_pcie->ctrl_id);
+ break;
+ case IMX6Q:
+ dev_info(dev, "Info: don't support pm_turn_off yet.\n");
+ return;
+ }
+
+ udelay(1000);
+ if (gpio_is_valid(imx_pcie->reset_gpio))
+ gpio_set_value_cansleep(imx_pcie->reset_gpio, 0);
+}
+
+static int pci_imx_suspend_noirq(struct device *dev)
+{
+ struct imx_pcie *imx_pcie = dev_get_drvdata(dev);
+ struct pcie_port *pp = &imx_pcie->pci->pp;
+
+ if (IS_ENABLED(CONFIG_PCI_MSI))
+ dw_pcie_msi_cfg_store(pp);
+
+ pci_imx_pm_turn_off(imx_pcie);
+
+ if (unlikely(imx_pcie->variant == IMX6Q)) {
+ /*
+ * L2 can exit by 'reset' or Inband beacon (from remote EP)
+ * toggling phy_powerdown has same effect as 'inband beacon'
+ * So, toggle bit18 of GPR1, used as a workaround of errata
+ * "PCIe PCIe does not support L2 Power Down"
+ */
+ regmap_update_bits(imx_pcie->iomuxc_gpr, IOMUXC_GPR1,
+ IMX6Q_GPR1_PCIE_TEST_PD,
+ IMX6Q_GPR1_PCIE_TEST_PD);
+ } else {
+ pci_imx_clk_disable(dev);
+
+ imx_pcie_phy_pwr_dn(imx_pcie);
+ /* Power down PCIe PHY. */
+ if (imx_pcie->pcie_phy_regulator != NULL)
+ regulator_disable(imx_pcie->pcie_phy_regulator);
+ if (imx_pcie->pcie_bus_regulator != NULL)
+ regulator_disable(imx_pcie->pcie_bus_regulator);
+ }
+
+ return 0;
+}
+
+static void pci_imx_ltssm_disable(struct device *dev)
+{
+ u32 val;
+ struct imx_pcie *imx_pcie = dev_get_drvdata(dev);
+
+ switch (imx_pcie->variant) {
+ case IMX6Q:
+ case IMX6SX:
+ case IMX6QP:
+ regmap_update_bits(imx_pcie->iomuxc_gpr, IOMUXC_GPR12,
+ IMX6Q_GPR12_PCIE_CTL_2, 0);
+ break;
+ case IMX7D:
+ case IMX8MQ:
+ case IMX8MM:
+ if (imx_pcie->ctrl_id == 0)
+ val = IMX8MQ_SRC_PCIEPHY_RCR_OFFSET;
+ else
+ val = IMX8MQ_SRC_PCIE2PHY_RCR_OFFSET;
+ regmap_update_bits(imx_pcie->reg_src, val,
+ IMX8MQ_PCIE_CTRL_APPS_EN |
+ IMX8MQ_PCIEPHY_DOMAIN_EN,
+ IMX8MQ_PCIEPHY_DOMAIN_EN);
+ break;
+ case IMX8QXP:
+ case IMX8QM:
+ /* Bit4 of the CTRL2 */
+ val = IMX8QM_CSR_PCIEA_OFFSET
+ + imx_pcie->ctrl_id * SZ_64K;
+ regmap_update_bits(imx_pcie->iomuxc_gpr,
+ val + IMX8QM_CSR_PCIE_CTRL2_OFFSET,
+ IMX8QM_CTRL_LTSSM_ENABLE, 0);
+ regmap_update_bits(imx_pcie->iomuxc_gpr,
+ val + IMX8QM_CSR_PCIE_CTRL2_OFFSET,
+ IMX8QM_CTRL_READY_ENTR_L23, 0);
+ break;
+ }
+}
+
+static int pci_imx_resume_noirq(struct device *dev)
+{
+ int ret = 0;
+ struct imx_pcie *imx_pcie = dev_get_drvdata(dev);
+ struct pcie_port *pp = &imx_pcie->pci->pp;
+
+ if (unlikely(imx_pcie->variant == IMX6Q)) {
+ /*
+ * L2 can exit by 'reset' or Inband beacon (from remote EP)
+ * toggling phy_powerdown has same effect as 'inband beacon'
+ * So, toggle bit18 of GPR1, used as a workaround of errata
+ * "PCIe PCIe does not support L2 Power Down"
+ */
+ regmap_update_bits(imx_pcie->iomuxc_gpr, IOMUXC_GPR1,
+ IMX6Q_GPR1_PCIE_TEST_PD, 0);
+ } else {
+ pci_imx_ltssm_disable(dev);
+ imx_pcie_assert_core_reset(imx_pcie);
+ imx_pcie_init_phy(imx_pcie);
+ ret = imx_pcie_deassert_core_reset(imx_pcie);
+ if (ret < 0)
+ return ret;
+
+ /*
+ * controller maybe turn off, re-configure again
+ */
+ dw_pcie_setup_rc(pp);
+
+ if (IS_ENABLED(CONFIG_PCI_MSI))
+ dw_pcie_msi_cfg_restore(pp);
+ pci_imx_ltssm_enable(dev);
+
+ ret = imx_pcie_wait_for_link(imx_pcie);
+ if (ret < 0)
+ dev_info(dev, "pcie link is down after resume.\n");
+ }
+
+ return ret;
+}
+
+static const struct dev_pm_ops pci_imx_pm_ops = {
+ .suspend_noirq = pci_imx_suspend_noirq,
+ .resume_noirq = pci_imx_resume_noirq,
+ .freeze_noirq = pci_imx_suspend_noirq,
+ .thaw_noirq = pci_imx_resume_noirq,
+ .poweroff_noirq = pci_imx_suspend_noirq,
+ .restore_noirq = pci_imx_resume_noirq,
+};
+#endif
+
+static irqreturn_t imx_pcie_dma_isr(int irq, void *param)
+{
+ u32 irqs, offset;
+ struct pcie_port *pp = (struct pcie_port *)param;
+ struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
+ struct imx_pcie *imx_pcie = to_imx_pcie(pci);
+
+ offset = imx_pcie->dma_unroll_offset;
+
+ /* check write isr */
+ irqs = readl(pci->dbi_base + offset + DMA_WRITE_INT_STS);
+ if (irqs & DMA_DONE_INT_STS) {
+ /* write 1 clear */
+ writel(irqs & DMA_DONE_INT_STS,
+ pci->dbi_base + offset + DMA_WRITE_INT_CLR);
+ dma_w_end = 1;
+ } else if (irqs & DMA_ABORT_INT_STS) {
+ pr_info("imx pcie dma write error 0x%0x.\n", irqs);
+ }
+ /* check read isr */
+ irqs = readl(pci->dbi_base + offset + DMA_READ_INT_STS);
+ if (irqs & DMA_DONE_INT_STS) {
+ /* write 1 clear */
+ writel(irqs & DMA_DONE_INT_STS,
+ pci->dbi_base + offset + DMA_READ_INT_CLR);
+ dma_r_end = 1;
+ } else if (irqs & DMA_ABORT_INT_STS) {
+ pr_info("imx pcie dma read error 0x%0x.", irqs);
+ }
+ return IRQ_HANDLED;
+}
+
+/**
+ * imx_pcie_local_dma_start - Start one local iMX PCIE DMA.
+ * @pp: the port start the dma transmission.
+ * @dir: direction of the dma, 1 read, 0 write;
+ * @chl: the channel num of the iMX PCIE DMA(0 - 7).
+ * @src: source DMA address.
+ * @dst: destination DMA address.
+ * @len: transfer length.
+ */
+static int imx_pcie_local_dma_start(struct pcie_port *pp, bool dir,
+ unsigned int chl, dma_addr_t src, dma_addr_t dst,
+ unsigned int len)
+{
+ u32 offset, doorbell, unroll_cal;
+ struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
+ struct imx_pcie *imx_pcie = to_imx_pcie(pci);
+
+ if (pp == NULL)
+ return -EINVAL;
+ if (chl > MAX_PCIE_DMA_CHANNELS)
+ return -EINVAL;
+
+ offset = imx_pcie->dma_unroll_offset;
+ /* enable dma engine, dir 1:read. 0:write. */
+ if (dir)
+ writel(DMA_READ_ENGINE_EN,
+ pci->dbi_base + offset
+ + DMA_READ_ENGINE_EN_OFF);
+ else
+ writel(DMA_WRITE_ENGINE_EN,
+ pci->dbi_base + offset
+ + DMA_WRITE_ENGINE_EN_OFF);
+ writel(0x0, pci->dbi_base + offset + DMA_WRITE_INT_MASK);
+ writel(0x0, pci->dbi_base + offset + DMA_READ_INT_MASK);
+ /* ch dir and ch num */
+ if (offset == 0) {
+ writel((dir << 31) | chl, pci->dbi_base + DMA_VIEWPOT_SEL_OFF);
+ writel(DMA_CHANNEL_CTRL_1_LIE,
+ pci->dbi_base + DMA_CHANNEL_CTRL_1);
+ writel(0x0, pci->dbi_base + DMA_CHANNEL_CTRL_2);
+ writel(len, pci->dbi_base + DMA_TRANSFER_SIZE);
+ writel((u32)src, pci->dbi_base + DMA_SAR_LOW);
+ writel(0x0, pci->dbi_base + DMA_SAR_HIGH);
+ writel((u32)dst, pci->dbi_base + DMA_DAR_LOW);
+ writel(0x0, pci->dbi_base + DMA_DAR_HIGH);
+ } else {
+ unroll_cal = DMA_UNROLL_CDM_OFFSET
+ + 0x200 * (chl + 1) + 0x100 * dir;
+ writel(DMA_CHANNEL_CTRL_1_LIE, pci->dbi_base + unroll_cal);
+ writel(0x0, pci->dbi_base + unroll_cal + 0x4);
+ writel(len, pci->dbi_base + unroll_cal + 0x8);
+ writel((u32)src, pci->dbi_base + unroll_cal + 0xc);
+ writel(0x0, pci->dbi_base + unroll_cal + 0x10);
+ writel((u32)dst, pci->dbi_base + unroll_cal + 0x14);
+ writel(0x0, pci->dbi_base + unroll_cal + 0x18);
+ }
+
+ doorbell = dir ? DMA_READ_DOORBELL : DMA_WRITE_DOORBELL;
+ writel(chl, pci->dbi_base + offset + doorbell);
+
+ return 0;
+}
+
+static int imx_pcie_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct dw_pcie *pci;
- struct imx6_pcie *imx6_pcie;
- struct resource *dbi_base;
- struct device_node *node = dev->of_node;
+ struct imx_pcie *imx_pcie;
+ struct resource *res, reserved_res;
+ struct device_node *reserved_node, *node = dev->of_node;
int ret;
+ u32 val;
- imx6_pcie = devm_kzalloc(dev, sizeof(*imx6_pcie), GFP_KERNEL);
- if (!imx6_pcie)
+ imx_pcie = devm_kzalloc(dev, sizeof(*imx_pcie), GFP_KERNEL);
+ if (!imx_pcie)
return -ENOMEM;
pci = devm_kzalloc(dev, sizeof(*pci), GFP_KERNEL);
@@ -716,22 +2292,93 @@ static int imx6_pcie_probe(struct platform_device *pdev)
pci->dev = dev;
pci->ops = &dw_pcie_ops;
- imx6_pcie->pci = pci;
- imx6_pcie->variant =
- (enum imx6_pcie_variants)of_device_get_match_data(dev);
+ imx_pcie->pci = pci;
+ imx_pcie->variant =
+ (enum imx_pcie_variants)of_device_get_match_data(dev);
+
+ if (of_property_read_u32(node, "hsio-cfg", &imx_pcie->hsio_cfg))
+ imx_pcie->hsio_cfg = 0;
+
+ if (of_property_read_u32(node, "ctrl-id", &imx_pcie->ctrl_id))
+ imx_pcie->ctrl_id = 0;
- dbi_base = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- pci->dbi_base = devm_ioremap_resource(dev, dbi_base);
+ if (of_property_read_u32(node, "cpu-base-addr", &imx_pcie->cpu_base))
+ imx_pcie->cpu_base = 0;
+ if (of_property_read_u32(node, "hard-wired", &imx_pcie->hard_wired))
+ imx_pcie->hard_wired = 0;
+
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "phy");
+ if (res)
+ imx_pcie->phy_base = devm_ioremap_resource(dev, res);
+ else
+ imx_pcie->phy_base = NULL;
+
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dbi");
+ if (res)
+ pci->dbi_base = devm_ioremap_resource(dev, res);
+ else
+ dev_err(dev, "missing *dbi* reg space\n");
if (IS_ERR(pci->dbi_base))
return PTR_ERR(pci->dbi_base);
+ reserved_node = of_parse_phandle(node, "reserved-region", 0);
+ if (!reserved_node) {
+ dev_info(dev, "no reserved region node.\n");
+ } else {
+ if (of_address_to_resource(reserved_node, 0, &reserved_res)) {
+ dev_err(dev, "failed to get reserved region address\n");
+ of_node_put(reserved_node);
+ return -EINVAL;
+ }
+ ddr_test_region = reserved_res.start + SZ_2M;
+ of_node_put(reserved_node);
+ }
+
/* Fetch GPIOs */
- imx6_pcie->reset_gpio = of_get_named_gpio(node, "reset-gpio", 0);
- imx6_pcie->gpio_active_high = of_property_read_bool(node,
+ imx_pcie->clkreq_gpio = of_get_named_gpio(node, "clkreq-gpio", 0);
+ if (gpio_is_valid(imx_pcie->clkreq_gpio)) {
+ ret = devm_gpio_request_one(&pdev->dev, imx_pcie->clkreq_gpio,
+ GPIOF_OUT_INIT_LOW, "PCIe CLKREQ");
+ if (ret) {
+ dev_err(&pdev->dev, "unable to get clkreq gpio\n");
+ return ret;
+ }
+ } else if (imx_pcie->clkreq_gpio == -EPROBE_DEFER) {
+ return imx_pcie->clkreq_gpio;
+ }
+
+ imx_pcie->dis_gpio = of_get_named_gpio(node, "disable-gpio", 0);
+ if (gpio_is_valid(imx_pcie->dis_gpio)) {
+ ret = devm_gpio_request_one(&pdev->dev, imx_pcie->dis_gpio,
+ GPIOF_OUT_INIT_HIGH, "PCIe DIS");
+ if (ret) {
+ dev_err(&pdev->dev, "unable to get disable gpio\n");
+ return ret;
+ }
+ } else if (imx_pcie->dis_gpio == -EPROBE_DEFER) {
+ return imx_pcie->dis_gpio;
+ }
+
+ imx_pcie->power_on_gpio = of_get_named_gpio(node, "power-on-gpio", 0);
+ if (gpio_is_valid(imx_pcie->power_on_gpio)) {
+ ret = devm_gpio_request_one(&pdev->dev,
+ imx_pcie->power_on_gpio,
+ GPIOF_OUT_INIT_LOW,
+ "PCIe power enable");
+ if (ret) {
+ dev_err(&pdev->dev, "unable to get power-on gpio\n");
+ return ret;
+ }
+ } else if (imx_pcie->power_on_gpio == -EPROBE_DEFER) {
+ return imx_pcie->power_on_gpio;
+ }
+
+ imx_pcie->reset_gpio = of_get_named_gpio(node, "reset-gpio", 0);
+ imx_pcie->gpio_active_high = of_property_read_bool(node,
"reset-gpio-active-high");
- if (gpio_is_valid(imx6_pcie->reset_gpio)) {
- ret = devm_gpio_request_one(dev, imx6_pcie->reset_gpio,
- imx6_pcie->gpio_active_high ?
+ if (gpio_is_valid(imx_pcie->reset_gpio)) {
+ ret = devm_gpio_request_one(dev, imx_pcie->reset_gpio,
+ imx_pcie->gpio_active_high ?
GPIOF_OUT_INIT_HIGH :
GPIOF_OUT_INIT_LOW,
"PCIe reset");
@@ -739,146 +2386,492 @@ static int imx6_pcie_probe(struct platform_device *pdev)
dev_err(dev, "unable to get reset gpio\n");
return ret;
}
- } else if (imx6_pcie->reset_gpio == -EPROBE_DEFER) {
- return imx6_pcie->reset_gpio;
+ } else if (imx_pcie->reset_gpio == -EPROBE_DEFER) {
+ return imx_pcie->reset_gpio;
+ }
+
+ imx_pcie->epdev_on = devm_regulator_get(&pdev->dev, "epdev_on");
+ if (IS_ERR(imx_pcie->epdev_on)) {
+ if (PTR_ERR(imx_pcie->epdev_on) == -EPROBE_DEFER)
+ return -EPROBE_DEFER;
+ dev_info(dev, "no ep regulator found\n");
+ imx_pcie->epdev_on = NULL;
+ } else {
+ ret = regulator_enable(imx_pcie->epdev_on);
+ if (ret)
+ dev_err(dev, "failed to enable the epdev_on regulator\n");
}
/* Fetch clocks */
- imx6_pcie->pcie_phy = devm_clk_get(dev, "pcie_phy");
- if (IS_ERR(imx6_pcie->pcie_phy)) {
+ imx_pcie->pcie_phy = devm_clk_get(dev, "pcie_phy");
+ if (IS_ERR(imx_pcie->pcie_phy)) {
dev_err(dev, "pcie_phy clock source missing or invalid\n");
- return PTR_ERR(imx6_pcie->pcie_phy);
+ return PTR_ERR(imx_pcie->pcie_phy);
}
- imx6_pcie->pcie_bus = devm_clk_get(dev, "pcie_bus");
- if (IS_ERR(imx6_pcie->pcie_bus)) {
+ imx_pcie->pcie_bus = devm_clk_get(dev, "pcie_bus");
+ if (IS_ERR(imx_pcie->pcie_bus)) {
dev_err(dev, "pcie_bus clock source missing or invalid\n");
- return PTR_ERR(imx6_pcie->pcie_bus);
+ return PTR_ERR(imx_pcie->pcie_bus);
+ }
+
+ if (of_property_read_u32(node, "ext_osc", &imx_pcie->ext_osc) < 0)
+ imx_pcie->ext_osc = 0;
+
+ if (imx_pcie->ext_osc && (imx_pcie->variant == IMX6QP)) {
+ /* Change the pcie_bus clock to pcie external OSC */
+ imx_pcie->pcie_bus = devm_clk_get(&pdev->dev, "pcie_ext");
+ if (IS_ERR(imx_pcie->pcie_bus)) {
+ dev_err(&pdev->dev,
+ "pcie_bus clock source missing or invalid\n");
+ return PTR_ERR(imx_pcie->pcie_bus);
+ }
+
+ imx_pcie->pcie_ext_src = devm_clk_get(&pdev->dev,
+ "pcie_ext_src");
+ if (IS_ERR(imx_pcie->pcie_ext_src)) {
+ dev_err(&pdev->dev,
+ "pcie_ext_src clk src missing or invalid\n");
+ return PTR_ERR(imx_pcie->pcie_ext_src);
+ }
}
- imx6_pcie->pcie = devm_clk_get(dev, "pcie");
- if (IS_ERR(imx6_pcie->pcie)) {
+ imx_pcie->pcie = devm_clk_get(dev, "pcie");
+ if (IS_ERR(imx_pcie->pcie)) {
dev_err(dev, "pcie clock source missing or invalid\n");
- return PTR_ERR(imx6_pcie->pcie);
+ return PTR_ERR(imx_pcie->pcie);
}
- switch (imx6_pcie->variant) {
- case IMX6SX:
- imx6_pcie->pcie_inbound_axi = devm_clk_get(dev,
- "pcie_inbound_axi");
- if (IS_ERR(imx6_pcie->pcie_inbound_axi)) {
- dev_err(dev, "pcie_inbound_axi clock missing or invalid\n");
- return PTR_ERR(imx6_pcie->pcie_inbound_axi);
+ if (imx_pcie->variant == IMX6QP) {
+ imx_pcie->pcie_bus_regulator = devm_regulator_get(dev,
+ "pcie-bus");
+ if (PTR_ERR(imx_pcie->pcie_bus_regulator) == -EPROBE_DEFER)
+ return -EPROBE_DEFER;
+ if (IS_ERR(imx_pcie->pcie_bus_regulator))
+ imx_pcie->pcie_bus_regulator = NULL;
+ } else {
+ imx_pcie->pcie_bus_regulator = NULL;
+ }
+
+ /* Grab GPR config register range */
+ if (imx_pcie->variant == IMX7D) {
+ imx_pcie->iomuxc_gpr =
+ syscon_regmap_lookup_by_compatible
+ ("fsl,imx7d-iomuxc-gpr");
+ imx_pcie->reg_src =
+ syscon_regmap_lookup_by_compatible("fsl,imx7d-src");
+ if (IS_ERR(imx_pcie->reg_src)) {
+ dev_err(&pdev->dev,
+ "imx7d pcie phy src missing or invalid\n");
+ return PTR_ERR(imx_pcie->reg_src);
}
- break;
- case IMX7D:
- imx6_pcie->pciephy_reset = devm_reset_control_get_exclusive(dev,
- "pciephy");
- if (IS_ERR(imx6_pcie->pciephy_reset)) {
- dev_err(dev, "Failed to get PCIEPHY reset control\n");
- return PTR_ERR(imx6_pcie->pciephy_reset);
+ imx_pcie->pcie_phy_regulator = devm_regulator_get(&pdev->dev,
+ "pcie-phy");
+ } else if (imx_pcie->variant == IMX8MQ || imx_pcie->variant == IMX8MM) {
+ imx_pcie->iomuxc_gpr =
+ syscon_regmap_lookup_by_compatible
+ ("fsl,imx7d-iomuxc-gpr");
+ imx_pcie->reg_src =
+ syscon_regmap_lookup_by_compatible("fsl,imx8mq-src");
+ if (IS_ERR(imx_pcie->reg_src)) {
+ dev_err(&pdev->dev,
+ "imx8mq pcie phy src missing or invalid\n");
+ return PTR_ERR(imx_pcie->reg_src);
+ }
+ imx_pcie->reg_gpc =
+ syscon_regmap_lookup_by_compatible("fsl,imx8mq-gpc");
+ if (IS_ERR(imx_pcie->reg_gpc)) {
+ dev_err(&pdev->dev,
+ "imx8mq pcie phy src missing or invalid\n");
+ return PTR_ERR(imx_pcie->reg_gpc);
+ }
+ } else if (imx_pcie->variant == IMX6SX) {
+ imx_pcie->pcie_inbound_axi = devm_clk_get(&pdev->dev,
+ "pcie_inbound_axi");
+ if (IS_ERR(imx_pcie->pcie_inbound_axi)) {
+ dev_err(&pdev->dev,
+ "pcie clock source missing or invalid\n");
+ return PTR_ERR(imx_pcie->pcie_inbound_axi);
}
- imx6_pcie->apps_reset = devm_reset_control_get_exclusive(dev,
- "apps");
- if (IS_ERR(imx6_pcie->apps_reset)) {
- dev_err(dev, "Failed to get PCIE APPS reset control\n");
- return PTR_ERR(imx6_pcie->apps_reset);
+ imx_pcie->pcie_phy_regulator = devm_regulator_get(&pdev->dev,
+ "pcie-phy");
+
+ imx_pcie->iomuxc_gpr =
+ syscon_regmap_lookup_by_compatible
+ ("fsl,imx6sx-iomuxc-gpr");
+ } else if (imx_pcie->variant == IMX8QM
+ || imx_pcie->variant == IMX8QXP) {
+ imx_pcie->pcie_per = devm_clk_get(dev, "pcie_per");
+ if (IS_ERR(imx_pcie->pcie_per)) {
+ dev_err(dev, "pcie_per clock source missing or invalid\n");
+ return PTR_ERR(imx_pcie->pcie_per);
}
- break;
- default:
- break;
- }
- /* Grab GPR config register range */
- imx6_pcie->iomuxc_gpr =
+ imx_pcie->iomuxc_gpr =
+ syscon_regmap_lookup_by_phandle(node, "hsio");
+ imx_pcie->pcie_inbound_axi = devm_clk_get(&pdev->dev,
+ "pcie_inbound_axi");
+ if (IS_ERR(imx_pcie->pcie_inbound_axi)) {
+ dev_err(&pdev->dev,
+ "pcie clock source missing or invalid\n");
+ return PTR_ERR(imx_pcie->pcie_inbound_axi);
+ }
+ } else {
+ imx_pcie->iomuxc_gpr =
syscon_regmap_lookup_by_compatible("fsl,imx6q-iomuxc-gpr");
- if (IS_ERR(imx6_pcie->iomuxc_gpr)) {
+ }
+
+ if (IS_ERR(imx_pcie->iomuxc_gpr)) {
dev_err(dev, "unable to find iomuxc registers\n");
- return PTR_ERR(imx6_pcie->iomuxc_gpr);
+ return PTR_ERR(imx_pcie->iomuxc_gpr);
}
/* Grab PCIe PHY Tx Settings */
if (of_property_read_u32(node, "fsl,tx-deemph-gen1",
- &imx6_pcie->tx_deemph_gen1))
- imx6_pcie->tx_deemph_gen1 = 0;
+ &imx_pcie->tx_deemph_gen1))
+ imx_pcie->tx_deemph_gen1 = 20;
if (of_property_read_u32(node, "fsl,tx-deemph-gen2-3p5db",
- &imx6_pcie->tx_deemph_gen2_3p5db))
- imx6_pcie->tx_deemph_gen2_3p5db = 0;
+ &imx_pcie->tx_deemph_gen2_3p5db))
+ imx_pcie->tx_deemph_gen2_3p5db = 20;
if (of_property_read_u32(node, "fsl,tx-deemph-gen2-6db",
- &imx6_pcie->tx_deemph_gen2_6db))
- imx6_pcie->tx_deemph_gen2_6db = 20;
+ &imx_pcie->tx_deemph_gen2_6db))
+ imx_pcie->tx_deemph_gen2_6db = 20;
if (of_property_read_u32(node, "fsl,tx-swing-full",
- &imx6_pcie->tx_swing_full))
- imx6_pcie->tx_swing_full = 127;
+ &imx_pcie->tx_swing_full))
+ imx_pcie->tx_swing_full = 115;
if (of_property_read_u32(node, "fsl,tx-swing-low",
- &imx6_pcie->tx_swing_low))
- imx6_pcie->tx_swing_low = 127;
+ &imx_pcie->tx_swing_low))
+ imx_pcie->tx_swing_low = 115;
/* Limit link speed */
ret = of_property_read_u32(node, "fsl,max-link-speed",
- &imx6_pcie->link_gen);
+ &imx_pcie->link_gen);
if (ret)
- imx6_pcie->link_gen = 1;
+ imx_pcie->link_gen = 1;
- imx6_pcie->vpcie = devm_regulator_get_optional(&pdev->dev, "vpcie");
- if (IS_ERR(imx6_pcie->vpcie)) {
- if (PTR_ERR(imx6_pcie->vpcie) != -ENODEV)
- return PTR_ERR(imx6_pcie->vpcie);
- imx6_pcie->vpcie = NULL;
+ imx_pcie->vpcie = devm_regulator_get_optional(&pdev->dev, "vpcie");
+ if (IS_ERR(imx_pcie->vpcie)) {
+ if (PTR_ERR(imx_pcie->vpcie) == -EPROBE_DEFER)
+ return -EPROBE_DEFER;
+ imx_pcie->vpcie = NULL;
}
- platform_set_drvdata(pdev, imx6_pcie);
+ platform_set_drvdata(pdev, imx_pcie);
+
+ if (IS_ENABLED(CONFIG_EP_MODE_IN_EP_RC_SYS)
+ && (imx_pcie->hard_wired == 0)) {
+ int i = 0, irq;
+ void *test_reg1, *test_reg2;
+ dma_addr_t test_reg1_dma, test_reg2_dma;
+ void __iomem *pcie_arb_base_addr;
+ struct timeval tv1s, tv1e, tv2s, tv2e;
+ u32 tv_count1, tv_count2;
+ struct device_node *np = node;
+ struct pcie_port *pp = &pci->pp;
+ LIST_HEAD(res);
+ struct resource_entry *win, *tmp;
+ unsigned long timeout = jiffies + msecs_to_jiffies(300000);
+
+ /* add attributes for device */
+ imx_pcie_attrgroup.attrs = imx_pcie_ep_attrs;
+ ret = sysfs_create_group(&pdev->dev.kobj, &imx_pcie_attrgroup);
+ if (ret)
+ return -EINVAL;
- ret = imx6_add_pcie_port(imx6_pcie, pdev);
- if (ret < 0)
- return ret;
+ ret = of_pci_get_host_bridge_resources(np, 0, 0xff, &res,
+ &pp->io_base);
+ if (ret)
+ return ret;
+
+ ret = devm_request_pci_bus_resources(&pdev->dev, &res);
+ if (ret) {
+ dev_err(dev, "missing ranges property\n");
+ pci_free_resource_list(&res);
+ return ret;
+ }
+
+ /* Get the I/O and memory ranges from DT */
+ resource_list_for_each_entry_safe(win, tmp, &res) {
+ switch (resource_type(win->res)) {
+ case IORESOURCE_MEM:
+ pp->mem = win->res;
+ pp->mem->name = "MEM";
+ pp->mem_size = resource_size(pp->mem);
+ pp->mem_bus_addr = pp->mem->start - win->offset;
+ break;
+ }
+ }
+
+ pp->mem_base = pp->mem->start;
+ pp->ops = &imx_pcie_host_ops;
+ dev_info(dev, " try to initialize pcie ep.\n");
+ ret = imx_pcie_host_init(pp);
+ if (ret) {
+ dev_info(dev, " fail to initialize pcie ep.\n");
+ return ret;
+ }
+
+ imx_pcie_setup_ep(pci);
+ platform_set_drvdata(pdev, imx_pcie);
+ imx_pcie_regions_setup(dev);
+
+ /*
+ * iMX6SX PCIe has the stand-alone power domain.
+ * refer to the initialization for iMX6SX PCIe,
+ * release the PCIe PHY reset here,
+ * before LTSSM enable is set
+ * .
+ */
+ if (imx_pcie->variant == IMX6SX)
+ regmap_update_bits(imx_pcie->iomuxc_gpr, IOMUXC_GPR5,
+ BIT(19), 0 << 19);
+
+ /* assert LTSSM enable */
+ pci_imx_ltssm_enable(dev);
+
+ dev_info(dev, "PCIe EP: waiting for link up...\n");
+ /* link is indicated by the bit4 of DB_R1 register */
+ do {
+ usleep_range(10, 20);
+ if (time_after(jiffies, timeout)) {
+ dev_info(dev, "PCIe EP: link down.\n");
+ return 0;
+ }
+ } while ((readl(pci->dbi_base + PCIE_PHY_DEBUG_R1) & 0x10) == 0);
+ /* self io test */
+ /* Check the DMA INT exist or not */
+ irq = of_irq_get(node, 1);
+ if (irq > 0)
+ dma_en = 1;
+ else
+ dma_en = 0;
+ if (dma_en) {
+ /* configure the DMA INT ISR */
+ ret = request_irq(irq, imx_pcie_dma_isr,
+ IRQF_SHARED, "imx-pcie-dma", pp);
+ if (ret) {
+ pr_err("register interrupt %d failed, rc %d\n",
+ irq, ret);
+ dma_en = 0;
+ }
+ test_reg1 = dma_alloc_coherent(dev, test_region_size,
+ &test_reg1_dma, GFP_KERNEL);
+ test_reg2 = dma_alloc_coherent(dev, test_region_size,
+ &test_reg2_dma, GFP_KERNEL);
+ if (!(test_reg1 && test_reg2))
+ dma_en = 0; /* Roll back to PIO. */
+ dma_r_end = dma_w_end = 0;
+
+ val = readl(pci->dbi_base + DMA_CTRL_VIEWPORT_OFF);
+ if (val == 0xffffffff)
+ imx_pcie->dma_unroll_offset =
+ DMA_UNROLL_CDM_OFFSET - DMA_REG_OFFSET;
+ else
+ imx_pcie->dma_unroll_offset = 0;
+ }
+
+ if (unlikely(dma_en == 0)) {
+ test_reg1 = devm_kzalloc(&pdev->dev,
+ test_region_size, GFP_KERNEL);
+ if (!test_reg1) {
+ ret = -ENOMEM;
+ return ret;
+ }
+
+ test_reg2 = devm_kzalloc(&pdev->dev,
+ test_region_size, GFP_KERNEL);
+ if (!test_reg2) {
+ ret = -ENOMEM;
+ return ret;
+ }
+ }
+
+ pcie_arb_base_addr = ioremap_nocache(pp->mem_base,
+ test_region_size);
+ if (!pcie_arb_base_addr) {
+ dev_err(dev, "ioremap error in ep io test\n");
+ ret = -ENOMEM;
+ return ret;
+ }
+
+ for (i = 0; i < test_region_size; i = i + 4) {
+ writel(0xE6600D00 + i, test_reg1 + i);
+ writel(0xDEADBEAF, test_reg2 + i);
+ }
+
+ /* PCIe EP start the data transfer after link up */
+ dev_info(dev, "pcie ep: Starting data transfer...\n");
+ do_gettimeofday(&tv1s);
+
+ /* EP write the test region to remote RC's DDR memory */
+ if (dma_en) {
+ imx_pcie_local_dma_start(pp, 0, 0, test_reg1_dma,
+ pp->mem_base + pp->cpu_addr_offset,
+ test_region_size);
+ timeout = jiffies + msecs_to_jiffies(300);
+ do {
+ udelay(1);
+ if (time_after(jiffies, timeout)) {
+ dev_info(dev, "dma write no end ...\n");
+ break;
+ }
+ } while (!dma_w_end);
+ } else {
+ memcpy((unsigned int *)pcie_arb_base_addr,
+ (unsigned int *)test_reg1,
+ test_region_size);
+ }
+
+ do_gettimeofday(&tv1e);
+
+ do_gettimeofday(&tv2s);
+ /* EP read the test region back from remote RC's DDR memory */
+ if (dma_en) {
+ imx_pcie_local_dma_start(pp, 1, 0,
+ pp->mem_base + pp->cpu_addr_offset,
+ test_reg2_dma, test_region_size);
+ timeout = jiffies + msecs_to_jiffies(300);
+ do {
+ udelay(1);
+ if (time_after(jiffies, timeout)) {
+ dev_info(dev, "dma read no end\n");
+ break;
+ }
+ } while (!dma_r_end);
+ } else {
+ memcpy((unsigned int *)test_reg2,
+ (unsigned int *)pcie_arb_base_addr,
+ test_region_size);
+ }
+
+ do_gettimeofday(&tv2e);
+ if (memcmp(test_reg2, test_reg1, test_region_size) == 0) {
+ tv_count1 = (tv1e.tv_sec - tv1s.tv_sec)
+ * USEC_PER_SEC
+ + tv1e.tv_usec - tv1s.tv_usec;
+ tv_count2 = (tv2e.tv_sec - tv2s.tv_sec)
+ * USEC_PER_SEC
+ + tv2e.tv_usec - tv2s.tv_usec;
+
+ dev_info(dev, "pcie ep: Data %s transfer is successful."
+ " tv_count1 %dus,"
+ " tv_count2 %dus.\n",
+ dma_en ? "DMA" : "PIO",
+ tv_count1, tv_count2);
+ dev_info(dev, "pcie ep: Data write speed:%ldMB/s.\n",
+ ((test_region_size/1024)
+ * MSEC_PER_SEC)
+ /(tv_count1));
+ dev_info(dev, "pcie ep: Data read speed:%ldMB/s.\n",
+ ((test_region_size/1024)
+ * MSEC_PER_SEC)
+ /(tv_count2));
+ } else {
+ dev_info(dev, "pcie ep: Data transfer is failed.\n");
+ } /* end of self io test. */
+ } else {
+ /* add attributes for bus freq */
+ imx_pcie_attrgroup.attrs = imx_pcie_rc_attrs;
+ ret = sysfs_create_group(&pdev->dev.kobj, &imx_pcie_attrgroup);
+ if (ret)
+ return -EINVAL;
+
+ ret = imx_add_pcie_port(imx_pcie, pdev);
+ if (ret < 0) {
+ if (IS_ENABLED(CONFIG_PCI_IMX6_COMPLIANCE_TEST)) {
+ /* The PCIE clocks wouldn't be turned off */
+ dev_info(dev, "To do the compliance tests.\n");
+ ret = 0;
+ } else {
+ dev_err(dev, "unable to add pcie port.\n");
+ }
+ return ret;
+ }
+ /*
+ * If the L1SS is enabled,
+ * disable the over ride after link up.
+ * Let the the CLK_REQ# controlled by HW L1SS
+ * automatically.
+ */
+ switch (imx_pcie->variant) {
+ case IMX8MQ:
+ case IMX8MM:
+ val = readl(pci->dbi_base +
+ IMX8MQ_PCIE_L1SUB_CTRL1_REG_OFFSET);
+ if (val & IMX8MQ_PCIE_L1SUB_CTRL1_REG_EN_MASK) {
+ if (imx_pcie->ctrl_id == 0)
+ val = IOMUXC_GPR14;
+ else
+ val = IOMUXC_GPR16;
+
+ regmap_update_bits(imx_pcie->iomuxc_gpr, val,
+ IMX8MQ_GPR_PCIE_CLK_REQ_OVERRIDE_EN,
+ 0);
+ }
+ break;
+ default:
+ break;
+ }
+
+ if (IS_ENABLED(CONFIG_RC_MODE_IN_EP_RC_SYS)
+ && (imx_pcie->hard_wired == 0))
+ imx_pcie_regions_setup(&pdev->dev);
+ }
return 0;
}
-static void imx6_pcie_shutdown(struct platform_device *pdev)
+static void imx_pcie_shutdown(struct platform_device *pdev)
{
- struct imx6_pcie *imx6_pcie = platform_get_drvdata(pdev);
+ struct imx_pcie *imx_pcie = platform_get_drvdata(pdev);
/* bring down link, so bootloader gets clean state in case of reboot */
- imx6_pcie_assert_core_reset(imx6_pcie);
+ if (imx_pcie->variant == IMX6Q)
+ imx_pcie_assert_core_reset(imx_pcie);
}
-static const struct of_device_id imx6_pcie_of_match[] = {
+static const struct of_device_id imx_pcie_of_match[] = {
{ .compatible = "fsl,imx6q-pcie", .data = (void *)IMX6Q, },
{ .compatible = "fsl,imx6sx-pcie", .data = (void *)IMX6SX, },
{ .compatible = "fsl,imx6qp-pcie", .data = (void *)IMX6QP, },
{ .compatible = "fsl,imx7d-pcie", .data = (void *)IMX7D, },
+ { .compatible = "fsl,imx8qm-pcie", .data = (void *)IMX8QM, },
+ { .compatible = "fsl,imx8qxp-pcie", .data = (void *)IMX8QXP, },
+ { .compatible = "fsl,imx8mq-pcie", .data = (void *)IMX8MQ, },
+ { .compatible = "fsl,imx8mm-pcie", .data = (void *)IMX8MM, },
{},
};
-static struct platform_driver imx6_pcie_driver = {
+static struct platform_driver imx_pcie_driver = {
.driver = {
.name = "imx6q-pcie",
- .of_match_table = imx6_pcie_of_match,
+ .of_match_table = imx_pcie_of_match,
.suppress_bind_attrs = true,
+ .pm = &pci_imx_pm_ops,
},
- .probe = imx6_pcie_probe,
- .shutdown = imx6_pcie_shutdown,
+ .probe = imx_pcie_probe,
+ .shutdown = imx_pcie_shutdown,
};
-static int __init imx6_pcie_init(void)
+static int __init imx_pcie_init(void)
{
+#ifdef CONFIG_ARM
/*
* Since probe() can be deferred we need to make sure that
* hook_fault_code is not called after __init memory is freed
- * by kernel and since imx6q_pcie_abort_handler() is a no-op,
+ * by kernel and since imx_pcie_abort_handler() is a no-op,
* we can install the handler here without risking it
* accessing some uninitialized driver state.
*/
- hook_fault_code(8, imx6q_pcie_abort_handler, SIGBUS, 0,
+ hook_fault_code(8, imx_pcie_abort_handler, SIGBUS, 0,
"external abort on non-linefetch");
+#endif
- return platform_driver_register(&imx6_pcie_driver);
+ return platform_driver_register(&imx_pcie_driver);
}
-device_initcall(imx6_pcie_init);
+device_initcall(imx_pcie_init);
diff --git a/drivers/pci/dwc/pcie-designware-host.c b/drivers/pci/dwc/pcie-designware-host.c
index 58b38c54a7cf..4acd0babc248 100644
--- a/drivers/pci/dwc/pcie-designware-host.c
+++ b/drivers/pci/dwc/pcie-designware-host.c
@@ -92,16 +92,38 @@ irqreturn_t dw_handle_msi_irq(struct pcie_port *pp)
void dw_pcie_msi_init(struct pcie_port *pp)
{
- u64 msi_target;
+ struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
+ dma_addr_t msi_addr;
- pp->msi_data = __get_free_pages(GFP_KERNEL, 0);
- msi_target = virt_to_phys((void *)pp->msi_data);
+ dma_alloc_coherent(pci->dev, 64, &msi_addr, GFP_KERNEL);
+ pp->msi_target = (u64)msi_addr;
/* program the msi_data */
dw_pcie_wr_own_conf(pp, PCIE_MSI_ADDR_LO, 4,
- (u32)(msi_target & 0xffffffff));
+ (u32)(pp->msi_target & 0xffffffff));
dw_pcie_wr_own_conf(pp, PCIE_MSI_ADDR_HI, 4,
- (u32)(msi_target >> 32 & 0xffffffff));
+ (u32)(pp->msi_target >> 32 & 0xffffffff));
+}
+
+void dw_pcie_msi_cfg_store(struct pcie_port *pp)
+{
+ int i;
+
+ for (i = 0; i < MAX_MSI_CTRLS; i++)
+ dw_pcie_rd_own_conf(pp, PCIE_MSI_INTR0_ENABLE + i * 12, 4,
+ &pp->msi_enable[i]);
+}
+
+void dw_pcie_msi_cfg_restore(struct pcie_port *pp)
+{
+ int i;
+
+ for (i = 0; i < MAX_MSI_CTRLS; i++) {
+ dw_pcie_wr_own_conf(pp, PCIE_MSI_ADDR_LO, 4, pp->msi_target);
+ dw_pcie_wr_own_conf(pp, PCIE_MSI_ADDR_HI, 4, 0);
+ dw_pcie_wr_own_conf(pp, PCIE_MSI_INTR0_ENABLE + i * 12, 4,
+ pp->msi_enable[i]);
+ }
}
static void dw_pcie_msi_clear_irq(struct pcie_port *pp, int irq)
@@ -191,15 +213,12 @@ no_valid_irq:
static void dw_msi_setup_msg(struct pcie_port *pp, unsigned int irq, u32 pos)
{
struct msi_msg msg;
- u64 msi_target;
if (pp->ops->get_msi_addr)
- msi_target = pp->ops->get_msi_addr(pp);
- else
- msi_target = virt_to_phys((void *)pp->msi_data);
+ pp->msi_target = pp->ops->get_msi_addr(pp);
- msg.address_lo = (u32)(msi_target & 0xffffffff);
- msg.address_hi = (u32)(msi_target >> 32 & 0xffffffff);
+ msg.address_lo = (u32)(pp->msi_target & 0xffffffff);
+ msg.address_hi = (u32)(pp->msi_target >> 32 & 0xffffffff);
if (pp->ops->get_msi_data)
msg.data = pp->ops->get_msi_data(pp, pos);
@@ -215,9 +234,6 @@ static int dw_msi_setup_irq(struct msi_controller *chip, struct pci_dev *pdev,
int irq, pos;
struct pcie_port *pp = pdev->bus->sysdata;
- if (desc->msi_attrib.is_msix)
- return -EINVAL;
-
irq = assign_irq(1, desc, &pos);
if (irq < 0)
return irq;
@@ -235,9 +251,20 @@ static int dw_msi_setup_irqs(struct msi_controller *chip, struct pci_dev *pdev,
struct msi_desc *desc;
struct pcie_port *pp = pdev->bus->sysdata;
- /* MSI-X interrupts are not supported */
- if (type == PCI_CAP_ID_MSIX)
- return -EINVAL;
+ if (type == PCI_CAP_ID_MSIX) {
+ if ((MAX_MSI_IRQS - bitmap_weight(pp->msi_irq_in_use,
+ MAX_MSI_IRQS)) < nvec)
+ return -ENOSPC;
+
+ for_each_pci_msi_entry(desc, pdev) {
+ int ret = dw_msi_setup_irq(chip, pdev, desc);
+
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+ }
WARN_ON(!list_is_singular(&pdev->dev.msi_list));
desc = list_entry(pdev->dev.msi_list.next, struct msi_desc, list);
@@ -637,9 +664,11 @@ void dw_pcie_setup_rc(struct pcie_port *pp)
dev_dbg(pci->dev, "iATU unroll: %s\n",
pci->iatu_unroll_enabled ? "enabled" : "disabled");
- dw_pcie_prog_outbound_atu(pci, PCIE_ATU_REGION_INDEX0,
- PCIE_ATU_TYPE_MEM, pp->mem_base,
- pp->mem_bus_addr, pp->mem_size);
+ if (!IS_ENABLED(CONFIG_EP_MODE_IN_EP_RC_SYS)
+ && !IS_ENABLED(CONFIG_RC_MODE_IN_EP_RC_SYS))
+ dw_pcie_prog_outbound_atu(pci, PCIE_ATU_REGION_INDEX0,
+ PCIE_ATU_TYPE_MEM, pp->mem_base,
+ pp->mem_bus_addr, pp->mem_size);
if (pci->num_viewport > 2)
dw_pcie_prog_outbound_atu(pci, PCIE_ATU_REGION_INDEX2,
PCIE_ATU_TYPE_IO, pp->io_base,
diff --git a/drivers/pci/dwc/pcie-designware.c b/drivers/pci/dwc/pcie-designware.c
index a06ad2c65174..327b924d1da0 100644
--- a/drivers/pci/dwc/pcie-designware.c
+++ b/drivers/pci/dwc/pcie-designware.c
@@ -148,6 +148,9 @@ void dw_pcie_prog_outbound_atu(struct dw_pcie *pci, int index, int type,
{
u32 retries, val;
+ if (cpu_addr >= pci->pp.mem_base)
+ cpu_addr = cpu_addr + pci->pp.cpu_addr_offset;
+
if (pci->ops->cpu_addr_fixup)
cpu_addr = pci->ops->cpu_addr_fixup(cpu_addr);
diff --git a/drivers/pci/dwc/pcie-designware.h b/drivers/pci/dwc/pcie-designware.h
index ba9dedc31bfa..4c1cb8ba952b 100644
--- a/drivers/pci/dwc/pcie-designware.h
+++ b/drivers/pci/dwc/pcie-designware.h
@@ -165,6 +165,7 @@ struct pcie_port {
u64 mem_base;
phys_addr_t mem_bus_addr;
u32 mem_size;
+ int cpu_addr_offset;
struct resource *cfg;
struct resource *io;
struct resource *mem;
@@ -173,7 +174,8 @@ struct pcie_port {
const struct dw_pcie_host_ops *ops;
int msi_irq;
struct irq_domain *irq_domain;
- unsigned long msi_data;
+ u64 msi_target;
+ unsigned int msi_enable[MAX_MSI_CTRLS];
DECLARE_BITMAP(msi_irq_in_use, MAX_MSI_IRQS);
};
@@ -313,6 +315,8 @@ static inline void dw_pcie_dbi_ro_wr_dis(struct dw_pcie *pci)
#ifdef CONFIG_PCIE_DW_HOST
irqreturn_t dw_handle_msi_irq(struct pcie_port *pp);
void dw_pcie_msi_init(struct pcie_port *pp);
+void dw_pcie_msi_cfg_store(struct pcie_port *pp);
+void dw_pcie_msi_cfg_restore(struct pcie_port *pp);
void dw_pcie_setup_rc(struct pcie_port *pp);
int dw_pcie_host_init(struct pcie_port *pp);
#else
@@ -325,6 +329,14 @@ static inline void dw_pcie_msi_init(struct pcie_port *pp)
{
}
+static inline void dw_pcie_msi_cfg_store(struct pcie_port *pp)
+{
+}
+
+static inline void dw_pcie_msi_cfg_restore(struct pcie_port *pp)
+{
+}
+
static inline void dw_pcie_setup_rc(struct pcie_port *pp)
{
}
diff --git a/drivers/pci/host/Kconfig b/drivers/pci/host/Kconfig
index b868803792d8..2a1b87fc1c07 100644
--- a/drivers/pci/host/Kconfig
+++ b/drivers/pci/host/Kconfig
@@ -65,6 +65,7 @@ config PCI_HOST_GENERIC
depends on (ARM || ARM64) && OF
select PCI_HOST_COMMON
select IRQ_DOMAIN
+ select PCI_DOMAINS
help
Say Y here if you want to support a simple generic PCI host
controller, such as the one emulated by kvmtool.
diff --git a/drivers/pci/host/pci-host-common.c b/drivers/pci/host/pci-host-common.c
index 148896f73c06..ec523cdc1b5f 100644
--- a/drivers/pci/host/pci-host-common.c
+++ b/drivers/pci/host/pci-host-common.c
@@ -176,5 +176,19 @@ int pci_host_common_probe(struct platform_device *pdev,
}
pci_bus_add_devices(bus);
+
+ platform_set_drvdata(pdev, bus);
+ return 0;
+}
+
+int pci_host_common_remove(struct platform_device *pdev)
+{
+ struct pci_bus *bus = platform_get_drvdata(pdev);
+
+ pci_lock_rescan_remove();
+ pci_stop_root_bus(bus);
+ pci_remove_root_bus(bus);
+ pci_unlock_rescan_remove();
+
return 0;
}
diff --git a/drivers/pci/host/pci-host-generic.c b/drivers/pci/host/pci-host-generic.c
index 7d709a7e0aa8..b35057e6e4f8 100644
--- a/drivers/pci/host/pci-host-generic.c
+++ b/drivers/pci/host/pci-host-generic.c
@@ -63,5 +63,6 @@ static struct platform_driver gen_pci_driver = {
.suppress_bind_attrs = true,
},
.probe = gen_pci_probe,
+ .remove = pci_host_common_remove,
};
builtin_platform_driver(gen_pci_driver);
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index c847b5554db6..8c1c32bc0921 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -5456,15 +5456,14 @@ static void pci_no_domains(void)
#endif
}
-#ifdef CONFIG_PCI_DOMAINS
+#ifdef CONFIG_PCI_DOMAINS_GENERIC
static atomic_t __domain_nr = ATOMIC_INIT(-1);
-int pci_get_new_domain_nr(void)
+static int pci_get_new_domain_nr(void)
{
return atomic_inc_return(&__domain_nr);
}
-#ifdef CONFIG_PCI_DOMAINS_GENERIC
static int of_pci_bus_find_domain_nr(struct device *parent)
{
static int use_dt_domains = -1;
@@ -5518,7 +5517,6 @@ int pci_bus_find_domain_nr(struct pci_bus *bus, struct device *parent)
acpi_pci_bus_find_domain_nr(bus);
}
#endif
-#endif
/**
* pci_ext_cfg_avail - can we access extended PCI config space?
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index 45c3fbd38f50..754073ff99cc 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -2378,6 +2378,8 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VT3351, quirk_disab
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VT3364, quirk_disable_all_msi);
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8380_0, quirk_disable_all_msi);
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SI, 0x0761, quirk_disable_all_msi);
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_BROADCOM, 0x43ec, quirk_disable_all_msi);
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_BROADCOM, 0x43ef, quirk_disable_all_msi);
/* Disable MSI on chipsets that are known to not support it */
static void quirk_disable_msi(struct pci_dev *dev)
diff --git a/drivers/perf/Kconfig b/drivers/perf/Kconfig
index e5197ffb7422..99d11f883901 100644
--- a/drivers/perf/Kconfig
+++ b/drivers/perf/Kconfig
@@ -36,6 +36,9 @@ config QCOM_L3_PMU
Adds the L3 cache PMU into the perf events subsystem for
monitoring L3 cache events.
+config IMX8_DDR_PERF
+ tristate "Freescale i.MX8 DDR perf monitor"
+
config XGENE_PMU
depends on ARCH_XGENE
bool "APM X-Gene SoC PMU"
diff --git a/drivers/perf/Makefile b/drivers/perf/Makefile
index 9402dc8ff22c..476f99e8c944 100644
--- a/drivers/perf/Makefile
+++ b/drivers/perf/Makefile
@@ -3,4 +3,5 @@ obj-$(CONFIG_ARM_PMU) += arm_pmu.o arm_pmu_platform.o
obj-$(CONFIG_ARM_PMU_ACPI) += arm_pmu_acpi.o
obj-$(CONFIG_QCOM_L2_PMU) += qcom_l2_pmu.o
obj-$(CONFIG_QCOM_L3_PMU) += qcom_l3_pmu.o
+obj-$(CONFIG_IMX8_DDR_PERF) += ddr-perf.o
obj-$(CONFIG_XGENE_PMU) += xgene_pmu.o
diff --git a/drivers/perf/ddr-perf.c b/drivers/perf/ddr-perf.c
new file mode 100644
index 000000000000..73fe52ee8b95
--- /dev/null
+++ b/drivers/perf/ddr-perf.c
@@ -0,0 +1,531 @@
+/*
+ * Copyright 2017 NXP
+ * Copyright 2016 Freescale Semiconductor, Inc.
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/of_irq.h>
+#include <linux/perf_event.h>
+#include <linux/slab.h>
+
+
+#define COUNTER_CNTL 0x0
+#define COUNTER_READ 0x20
+
+#define COUNTER_DPCR1 0x30
+
+#define CNTL_OVER 0x1
+#define CNTL_CLEAR 0x2
+#define CNTL_EN 0x4
+#define CNTL_EN_MASK 0xFFFFFFFB
+#define CNTL_CLEAR_MASK 0xFFFFFFFD
+#define CNTL_OVER_MASK 0xFFFFFFFE
+
+#define CNTL_CSV_SHIFT 24
+#define CNTL_CSV_MASK (0xFF << CNTL_CSV_SHIFT)
+
+#define EVENT_CYCLES_ID 0
+#define EVENT_CYCLES_COUNTER 0
+#define NUM_COUNTER 4
+#define MAX_EVENT 3
+
+#define to_ddr_pmu(p) container_of(p, struct ddr_pmu, pmu)
+
+#define DDR_PERF_DEV_NAME "ddr_perf"
+
+static DEFINE_IDA(ddr_ida);
+
+PMU_EVENT_ATTR_STRING(cycles, ddr_perf_cycles, "event=0x00");
+PMU_EVENT_ATTR_STRING(selfresh, ddr_perf_selfresh, "event=0x01");
+PMU_EVENT_ATTR_STRING(read-access, ddr_perf_read_accesses, "event=0x04");
+PMU_EVENT_ATTR_STRING(write-access, ddr_perf_write_accesses, "event=0x05");
+PMU_EVENT_ATTR_STRING(read-queue-depth, ddr_perf_read_queue_depth,
+ "event=0x08");
+PMU_EVENT_ATTR_STRING(write-queue-depth, ddr_perf_write_queue_depth,
+ "event=0x09");
+PMU_EVENT_ATTR_STRING(lp-read-credit-cnt, ddr_perf_lp_read_credit_cnt,
+ "event=0x10");
+PMU_EVENT_ATTR_STRING(hp-read-credit-cnt, ddr_perf_hp_read_credit_cnt,
+ "event=0x11");
+PMU_EVENT_ATTR_STRING(write-credit-cnt, ddr_perf_write_credit_cnt,
+ "event=0x12");
+PMU_EVENT_ATTR_STRING(read-command, ddr_perf_read_command, "event=0x20");
+PMU_EVENT_ATTR_STRING(write-command, ddr_perf_write_command, "event=0x21");
+PMU_EVENT_ATTR_STRING(read-modify-write-command,
+ ddr_perf_read_modify_write_command, "event=0x22");
+PMU_EVENT_ATTR_STRING(hp-read, ddr_perf_hp_read, "event=0x23");
+PMU_EVENT_ATTR_STRING(hp-req-nodcredit, ddr_perf_hp_req_nocredit, "event=0x24");
+PMU_EVENT_ATTR_STRING(hp-xact-credit, ddr_perf_hp_xact_credit, "event=0x25");
+PMU_EVENT_ATTR_STRING(lp-req-nocredit, ddr_perf_lp_req_nocredit, "event=0x26");
+PMU_EVENT_ATTR_STRING(lp-xact-credit, ddr_perf_lp_xact_credit, "event=0x27");
+PMU_EVENT_ATTR_STRING(wr-xact-credit, ddr_perf_wr_xact_credit, "event=0x29");
+PMU_EVENT_ATTR_STRING(read-cycles, ddr_perf_read_cycles, "event=0x2a");
+PMU_EVENT_ATTR_STRING(write-cycles, ddr_perf_write_cycles, "event=0x2b");
+PMU_EVENT_ATTR_STRING(read-write-transition, ddr_perf_read_write_transition,
+ "event=0x30");
+PMU_EVENT_ATTR_STRING(precharge, ddr_perf_precharge, "event=0x31");
+PMU_EVENT_ATTR_STRING(activate, ddr_perf_activate, "event=0x32");
+PMU_EVENT_ATTR_STRING(load-mode, ddr_perf_load_mode, "event=0x33");
+PMU_EVENT_ATTR_STRING(mwr, ddr_perf_mwr, "event=0x34");
+PMU_EVENT_ATTR_STRING(read, ddr_perf_read, "event=0x35");
+PMU_EVENT_ATTR_STRING(read-activate, ddr_perf_read_activate, "event=0x36");
+PMU_EVENT_ATTR_STRING(refresh, ddr_perf_refresh, "event=0x37");
+PMU_EVENT_ATTR_STRING(write, ddr_perf_write, "event=0x38");
+PMU_EVENT_ATTR_STRING(raw-hazard, ddr_perf_raw_hazard, "event=0x39");
+
+PMU_EVENT_ATTR_STRING(axid-read, ddr_perf_axid_read, "event=0x41");
+PMU_EVENT_ATTR_STRING(axid-write, ddr_perf_axid_write, "event=0x42");
+
+#define DDR_CAP_AXI_ID 0x1
+
+struct fsl_ddr_devtype_data {
+ unsigned int flags;
+};
+
+static const struct fsl_ddr_devtype_data imx8_data;
+static const struct fsl_ddr_devtype_data imx8m_data = {
+ .flags = DDR_CAP_AXI_ID,
+};
+
+static const struct of_device_id imx_ddr_pmu_dt_ids[] = {
+ { .compatible = "fsl,imx8-ddr-pmu", .data = (void*)&imx8_data},
+ { .compatible = "fsl,imx8m-ddr-pmu", .data = (void*)&imx8m_data},
+ { /* sentinel */ }
+};
+
+struct ddr_pmu {
+ struct pmu pmu;
+ void __iomem *base;
+ cpumask_t cpu;
+ struct hlist_node node;
+ struct device *dev;
+ struct perf_event *active_events[NUM_COUNTER];
+ int total_events;
+ bool cycles_active;
+ struct fsl_ddr_devtype_data *devtype;
+};
+
+static ssize_t ddr_perf_cpumask_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct ddr_pmu *pmu = dev_get_drvdata(dev);
+
+ return cpumap_print_to_pagebuf(true, buf, &pmu->cpu);
+}
+
+static struct device_attribute ddr_perf_cpumask_attr =
+ __ATTR(cpumask, 0444, ddr_perf_cpumask_show, NULL);
+
+static struct attribute *ddr_perf_cpumask_attrs[] = {
+ &ddr_perf_cpumask_attr.attr,
+ NULL,
+};
+
+static struct attribute_group ddr_perf_cpumask_attr_group = {
+ .attrs = ddr_perf_cpumask_attrs,
+};
+
+static struct attribute *ddr_perf_events_attrs[] = {
+ &ddr_perf_cycles.attr.attr,
+ &ddr_perf_selfresh.attr.attr,
+ &ddr_perf_read_accesses.attr.attr,
+ &ddr_perf_write_accesses.attr.attr,
+ &ddr_perf_read_queue_depth.attr.attr,
+ &ddr_perf_write_queue_depth.attr.attr,
+ &ddr_perf_lp_read_credit_cnt.attr.attr,
+ &ddr_perf_hp_read_credit_cnt.attr.attr,
+ &ddr_perf_write_credit_cnt.attr.attr,
+ &ddr_perf_read_command.attr.attr,
+ &ddr_perf_write_command.attr.attr,
+ &ddr_perf_read_modify_write_command.attr.attr,
+ &ddr_perf_hp_read.attr.attr,
+ &ddr_perf_hp_req_nocredit.attr.attr,
+ &ddr_perf_hp_xact_credit.attr.attr,
+ &ddr_perf_lp_req_nocredit.attr.attr,
+ &ddr_perf_lp_xact_credit.attr.attr,
+ &ddr_perf_wr_xact_credit.attr.attr,
+ &ddr_perf_read_cycles.attr.attr,
+ &ddr_perf_write_cycles.attr.attr,
+ &ddr_perf_read_write_transition.attr.attr,
+ &ddr_perf_precharge.attr.attr,
+ &ddr_perf_activate.attr.attr,
+ &ddr_perf_load_mode.attr.attr,
+ &ddr_perf_mwr.attr.attr,
+ &ddr_perf_read.attr.attr,
+ &ddr_perf_read_activate.attr.attr,
+ &ddr_perf_refresh.attr.attr,
+ &ddr_perf_write.attr.attr,
+ &ddr_perf_raw_hazard.attr.attr,
+ &ddr_perf_axid_read.attr.attr,
+ &ddr_perf_axid_write.attr.attr,
+ NULL,
+};
+
+static struct attribute_group ddr_perf_events_attr_group = {
+ .name = "events",
+ .attrs = ddr_perf_events_attrs,
+};
+
+PMU_FORMAT_ATTR(event, "config:0-63");
+PMU_FORMAT_ATTR(axi_id, "config1:0-63");
+
+static struct attribute *ddr_perf_format_attrs[] = {
+ &format_attr_event.attr,
+ &format_attr_axi_id.attr,
+ NULL,
+};
+
+static struct attribute_group ddr_perf_format_attr_group = {
+ .name = "format",
+ .attrs = ddr_perf_format_attrs,
+};
+
+static const struct attribute_group *attr_groups[] = {
+ &ddr_perf_events_attr_group,
+ &ddr_perf_format_attr_group,
+ &ddr_perf_cpumask_attr_group,
+ NULL,
+};
+
+static u32 ddr_perf_alloc_counter(struct ddr_pmu *pmu, int event)
+{
+ int i;
+
+ /* Always map cycle event to counter 0 */
+ if (event == EVENT_CYCLES_ID)
+ return EVENT_CYCLES_COUNTER;
+
+ for (i = 1; i < NUM_COUNTER; i++)
+ if (pmu->active_events[i] == NULL)
+ return i;
+
+ return -ENOENT;
+}
+
+static u32 ddr_perf_free_counter(struct ddr_pmu *pmu, int counter)
+{
+ if (counter < 0 || counter >= NUM_COUNTER)
+ return -ENOENT;
+
+ pmu->active_events[counter] = NULL;
+
+ return 0;
+}
+
+static u32 ddr_perf_read_counter(struct ddr_pmu *pmu, int counter)
+{
+ return readl(pmu->base + COUNTER_READ + counter * 4);
+}
+
+static int ddr_perf_event_init(struct perf_event *event)
+{
+ struct ddr_pmu *pmu = to_ddr_pmu(event->pmu);
+ struct hw_perf_event *hwc = &event->hw;
+
+ if (event->attr.type != event->pmu->type)
+ return -ENOENT;
+
+ if (is_sampling_event(event) || event->attach_state & PERF_ATTACH_TASK)
+ return -EOPNOTSUPP;
+
+ if (event->cpu < 0) {
+ dev_warn(pmu->dev, "Can't provide per-task data!\n");
+ return -EOPNOTSUPP;
+ }
+
+ if (event->attr.exclude_user ||
+ event->attr.exclude_kernel ||
+ event->attr.exclude_hv ||
+ event->attr.exclude_idle ||
+ event->attr.exclude_host ||
+ event->attr.exclude_guest ||
+ event->attr.sample_period)
+ return -EINVAL;
+
+ event->cpu = cpumask_first(&pmu->cpu);
+ hwc->idx = -1;
+
+ return 0;
+}
+
+
+static void ddr_perf_event_update(struct perf_event *event)
+{
+ struct ddr_pmu *pmu = to_ddr_pmu(event->pmu);
+ struct hw_perf_event *hwc = &event->hw;
+ u64 delta, prev_raw_count, new_raw_count;
+ int counter = hwc->idx;
+
+ do {
+ prev_raw_count = local64_read(&hwc->prev_count);
+ new_raw_count = ddr_perf_read_counter(pmu, counter);
+ } while (local64_cmpxchg(&hwc->prev_count, prev_raw_count,
+ new_raw_count) != prev_raw_count);
+
+ delta = (new_raw_count - prev_raw_count) & 0xFFFFFFFF;
+
+ local64_add(delta, &event->count);
+}
+
+static void ddr_perf_event_enable(struct ddr_pmu *pmu, int config,
+ int counter, bool enable)
+{
+ u8 reg = counter * 4 + COUNTER_CNTL;
+ int val;
+
+ if (enable) {
+ /* Clear counter, then enable it. */
+ writel(0, pmu->base + reg);
+ val = CNTL_EN | CNTL_CLEAR;
+ val |= (config << CNTL_CSV_SHIFT) & CNTL_CSV_MASK;
+ } else {
+ /* Disable counter */
+ val = readl(pmu->base + reg) & CNTL_EN_MASK;
+ }
+
+ writel(val, pmu->base + reg);
+
+ if (config == EVENT_CYCLES_ID)
+ pmu->cycles_active = enable;
+}
+
+static void ddr_perf_event_start(struct perf_event *event, int flags)
+{
+ struct ddr_pmu *pmu = to_ddr_pmu(event->pmu);
+ struct hw_perf_event *hwc = &event->hw;
+ int counter = hwc->idx;
+
+ if (pmu->devtype->flags & DDR_CAP_AXI_ID) {
+ if (event->attr.config == 0x41 ||
+ event->attr.config == 0x42) {
+ int val = event->attr.config1;
+ writel(val, pmu->base + COUNTER_DPCR1);
+ }
+ }
+
+ local64_set(&hwc->prev_count, 0);
+
+ ddr_perf_event_enable(pmu, event->attr.config, counter, true);
+ /*
+ * If the cycles counter wasn't explicitly selected,
+ * we will enable it now.
+ */
+ if (counter > 0 && !pmu->cycles_active)
+ ddr_perf_event_enable(pmu, EVENT_CYCLES_ID,
+ EVENT_CYCLES_COUNTER, true);
+}
+
+static int ddr_perf_event_add(struct perf_event *event, int flags)
+{
+ struct ddr_pmu *pmu = to_ddr_pmu(event->pmu);
+ struct hw_perf_event *hwc = &event->hw;
+ int counter;
+ int cfg = event->attr.config;
+
+ counter = ddr_perf_alloc_counter(pmu, cfg);
+ if (counter < 0) {
+ dev_warn(pmu->dev, "There are not enough counters\n");
+ return -EOPNOTSUPP;
+ }
+
+ pmu->active_events[counter] = event;
+ pmu->total_events++;
+ hwc->idx = counter;
+
+ if (flags & PERF_EF_START)
+ ddr_perf_event_start(event, flags);
+
+ local64_set(&hwc->prev_count, ddr_perf_read_counter(pmu, counter));
+
+ return 0;
+}
+
+static void ddr_perf_event_stop(struct perf_event *event, int flags)
+{
+ struct ddr_pmu *pmu = to_ddr_pmu(event->pmu);
+ struct hw_perf_event *hwc = &event->hw;
+ int counter = hwc->idx;
+
+ ddr_perf_event_enable(pmu, event->attr.config, counter, false);
+ ddr_perf_event_update(event);
+}
+
+static void ddr_perf_event_del(struct perf_event *event, int flags)
+{
+ struct ddr_pmu *pmu = to_ddr_pmu(event->pmu);
+ struct hw_perf_event *hwc = &event->hw;
+ int counter = hwc->idx;
+
+ ddr_perf_event_stop(event, PERF_EF_UPDATE);
+
+ ddr_perf_free_counter(pmu, counter);
+ pmu->total_events--;
+ hwc->idx = -1;
+
+ /* If all events have stopped, stop the cycles counter as well */
+ if ((pmu->total_events == 0) && pmu->cycles_active)
+ ddr_perf_event_enable(pmu, EVENT_CYCLES_ID,
+ EVENT_CYCLES_COUNTER, false);
+}
+
+static int ddr_perf_init(struct ddr_pmu *pmu, void __iomem *base,
+ struct device *dev)
+{
+ *pmu = (struct ddr_pmu) {
+ .pmu = (struct pmu) {
+ .task_ctx_nr = perf_invalid_context,
+ .attr_groups = attr_groups,
+ .event_init = ddr_perf_event_init,
+ .add = ddr_perf_event_add,
+ .del = ddr_perf_event_del,
+ .start = ddr_perf_event_start,
+ .stop = ddr_perf_event_stop,
+ .read = ddr_perf_event_update,
+ },
+ .base = base,
+ .dev = dev,
+ };
+
+ return ida_simple_get(&ddr_ida, 0, 0, GFP_KERNEL);
+}
+
+static irqreturn_t ddr_perf_irq_handler(int irq, void *p)
+{
+ int i;
+ u8 reg;
+ int val;
+ int counter;
+ struct ddr_pmu *pmu = (struct ddr_pmu *) p;
+ struct perf_event *event;
+
+ /*
+ * The cycles counter has overflowed. Update all of the local counter
+ * values, then reset the cycles counter, so the others can continue
+ * counting.
+ */
+ for (i = 0; i <= pmu->total_events; i++) {
+ if (pmu->active_events[i] != NULL) {
+ event = pmu->active_events[i];
+ counter = event->hw.idx;
+ reg = counter * 4 + COUNTER_CNTL;
+ val = readl(pmu->base + reg);
+ ddr_perf_event_update(event);
+ if (val & CNTL_OVER) {
+ /* Clear counter, then re-enable it. */
+ ddr_perf_event_enable(pmu, event->attr.config,
+ counter, true);
+ /* Update event again to reset prev_count */
+ ddr_perf_event_update(event);
+ }
+ }
+ }
+
+ /*
+ * Reset the cycles counter regardless if it was explicitly
+ * enabled or not.
+ */
+ ddr_perf_event_enable(pmu, EVENT_CYCLES_ID,
+ EVENT_CYCLES_COUNTER, true);
+
+ return IRQ_HANDLED;
+}
+
+static int ddr_perf_probe(struct platform_device *pdev)
+{
+ struct ddr_pmu *pmu;
+ struct device_node *np;
+ void __iomem *base;
+ struct resource *iomem;
+ char *name;
+ int num;
+ int ret;
+ u32 irq;
+ const struct of_device_id *of_id =
+ of_match_device(imx_ddr_pmu_dt_ids, &pdev->dev);
+
+ iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ base = devm_ioremap_resource(&pdev->dev, iomem);
+ if (IS_ERR(base)) {
+ ret = PTR_ERR(base);
+ return ret;
+ }
+
+ np = pdev->dev.of_node;
+
+ pmu = kzalloc(sizeof(*pmu), GFP_KERNEL);
+ if (!pmu)
+ return -ENOMEM;
+
+ num = ddr_perf_init(pmu, base, &pdev->dev);
+ name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "ddr%d", num);
+
+ pmu->devtype = (struct fsl_ddr_devtype_data *)of_id->data;
+
+ cpumask_set_cpu(smp_processor_id(), &pmu->cpu);
+ ret = perf_pmu_register(&(pmu->pmu), name, -1);
+ if (ret)
+ goto ddr_perf_err;
+
+ /* Request irq */
+ irq = of_irq_get(np, 0);
+ if (irq < 0) {
+ pr_err("Failed to get irq: %d", irq);
+ goto ddr_perf_err;
+ }
+
+ ret = devm_request_threaded_irq(&pdev->dev, irq,
+ ddr_perf_irq_handler, NULL,
+ IRQF_TRIGGER_RISING | IRQF_ONESHOT,
+ DDR_PERF_DEV_NAME,
+ pmu);
+ if (ret < 0) {
+ pr_err("Request irq failed: %d", ret);
+ goto ddr_perf_irq_err;
+ }
+
+ return 0;
+
+ddr_perf_irq_err:
+ perf_pmu_unregister(&(pmu->pmu));
+ddr_perf_err:
+ pr_warn("i.MX8 DDR Perf PMU failed (%d), disabled\n", ret);
+ kfree(pmu);
+ return ret;
+}
+
+
+static int ddr_perf_remove(struct platform_device *pdev)
+{
+ struct ddr_pmu *pmu = platform_get_drvdata(pdev);
+
+ perf_pmu_unregister(&pmu->pmu);
+ kfree(pmu);
+
+ return 0;
+}
+
+static struct platform_driver imx_ddr_pmu_driver = {
+ .driver = {
+ .name = "imx-ddr-pmu",
+ .of_match_table = imx_ddr_pmu_dt_ids,
+ },
+ .probe = ddr_perf_probe,
+ .remove = ddr_perf_remove,
+};
+
+static int __init imx_ddr_pmu_init(void)
+{
+ return platform_driver_register(&imx_ddr_pmu_driver);
+}
+
+module_init(imx_ddr_pmu_init);
+
diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
index 5c8d452e35e2..c03c66281991 100644
--- a/drivers/phy/Kconfig
+++ b/drivers/phy/Kconfig
@@ -40,6 +40,30 @@ config PHY_XGENE
help
This option enables support for APM X-Gene SoC multi-purpose PHY.
+config PHY_MIXEL_LVDS
+ bool
+ depends on OF
+ select GENERIC_PHY
+ default ARCH_FSL_IMX8QM
+
+config PHY_MIXEL_LVDS_COMBO
+ bool
+ depends on OF
+ select GENERIC_PHY
+ default ARCH_FSL_IMX8QXP
+
+config PHY_MIXEL_MIPI_DSI
+ bool
+ depends on OF
+ select GENERIC_PHY
+ default ARCH_FSL_IMX8QM || ARCH_FSL_IMX8QXP
+
+config PHY_FSL_IMX8MQ_USB
+ bool
+ depends on OF
+ select GENERIC_PHY
+ default ARCH_FSL_IMX8MQ
+
source "drivers/phy/allwinner/Kconfig"
source "drivers/phy/amlogic/Kconfig"
source "drivers/phy/broadcom/Kconfig"
diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
index 84e3bd9c5665..94e7ca81151a 100644
--- a/drivers/phy/Makefile
+++ b/drivers/phy/Makefile
@@ -7,6 +7,10 @@ obj-$(CONFIG_GENERIC_PHY) += phy-core.o
obj-$(CONFIG_PHY_LPC18XX_USB_OTG) += phy-lpc18xx-usb-otg.o
obj-$(CONFIG_PHY_XGENE) += phy-xgene.o
obj-$(CONFIG_PHY_PISTACHIO_USB) += phy-pistachio-usb.o
+obj-$(CONFIG_PHY_MIXEL_LVDS) += phy-mixel-lvds.o
+obj-$(CONFIG_PHY_MIXEL_LVDS_COMBO) += phy-mixel-lvds-combo.o
+obj-$(CONFIG_PHY_MIXEL_MIPI_DSI) += phy-mixel-mipi-dsi.o
+obj-$(CONFIG_PHY_FSL_IMX8MQ_USB) += phy-fsl-imx8mq-usb.o
obj-$(CONFIG_ARCH_SUNXI) += allwinner/
obj-$(CONFIG_ARCH_MESON) += amlogic/
obj-$(CONFIG_LANTIQ) += lantiq/
diff --git a/drivers/phy/phy-fsl-imx8mq-usb.c b/drivers/phy/phy-fsl-imx8mq-usb.c
new file mode 100644
index 000000000000..3705546b056e
--- /dev/null
+++ b/drivers/phy/phy-fsl-imx8mq-usb.c
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 2017 NXP.
+ *
+ * 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/clk.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/phy/phy.h>
+#include <linux/io.h>
+
+#define PHY_CTRL0 0x0
+#define PHY_CTRL0_REF_SSP_EN BIT(2)
+#define PHY_CTRL0_SSC_RANGE_MASK (7 << 21)
+#define PHY_CTRL0_SSC_RANGE_4003PPM (0x2 << 21)
+
+#define PHY_CTRL1 0x4
+#define PHY_CTRL1_RESET BIT(0)
+#define PHY_CTRL1_COMMONONN BIT(1)
+#define PHY_CTRL1_ATERESET BIT(3)
+#define PHY_CTRL1_VDATSRCENB0 BIT(19)
+#define PHY_CTRL1_VDATDETENB0 BIT(20)
+
+#define PHY_CTRL2 0x8
+#define PHY_CTRL2_TXENABLEN0 BIT(8)
+
+struct imx8mq_usb_phy {
+ struct phy *phy;
+ struct clk *clk;
+ void __iomem *base;
+};
+
+static int imx8mq_phy_start(struct phy *_phy)
+{
+ struct imx8mq_usb_phy *phy = phy_get_drvdata(_phy);
+
+ return clk_prepare_enable(phy->clk);
+}
+
+static int imx8mq_phy_exit(struct phy *_phy)
+{
+ struct imx8mq_usb_phy *phy = phy_get_drvdata(_phy);
+
+ clk_disable_unprepare(phy->clk);
+
+ return 0;
+}
+
+static struct phy_ops imx8mq_usb_phy_ops = {
+ .init = imx8mq_phy_start,
+ .exit = imx8mq_phy_exit,
+ .owner = THIS_MODULE,
+};
+
+static void imx8mq_usb_phy_init(struct imx8mq_usb_phy *phy)
+{
+ u32 value;
+
+ value = readl(phy->base + PHY_CTRL1);
+ value &= ~(PHY_CTRL1_VDATSRCENB0 | PHY_CTRL1_VDATDETENB0 |
+ PHY_CTRL1_COMMONONN);
+ value |= PHY_CTRL1_RESET | PHY_CTRL1_ATERESET;
+ writel(value, phy->base + PHY_CTRL1);
+
+ value = readl(phy->base + PHY_CTRL0);
+ value |= PHY_CTRL0_REF_SSP_EN;
+ value &= ~PHY_CTRL0_SSC_RANGE_MASK;
+ value |= PHY_CTRL0_SSC_RANGE_4003PPM;
+ writel(value, phy->base + PHY_CTRL0);
+
+ value = readl(phy->base + PHY_CTRL2);
+ value |= PHY_CTRL2_TXENABLEN0;
+ writel(value, phy->base + PHY_CTRL2);
+
+ value = readl(phy->base + PHY_CTRL1);
+ value &= ~(PHY_CTRL1_RESET | PHY_CTRL1_ATERESET);
+ writel(value, phy->base + PHY_CTRL1);
+}
+
+static int imx8mq_usb_phy_probe(struct platform_device *pdev)
+{
+ struct phy_provider *phy_provider;
+ struct device *dev = &pdev->dev;
+ struct imx8mq_usb_phy *imx_phy;
+ struct resource *res;
+
+ imx_phy = devm_kzalloc(dev, sizeof(*imx_phy), GFP_KERNEL);
+ if (!imx_phy)
+ return -ENOMEM;
+
+ imx_phy->clk = devm_clk_get(dev, "usb_phy_root_clk");
+ if (IS_ERR(imx_phy->clk)) {
+ dev_err(dev, "failed to get imx8mq usb phy clock\n");
+ return PTR_ERR(imx_phy->clk);
+ }
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ imx_phy->base = devm_ioremap_resource(dev, res);
+ if (IS_ERR(imx_phy->base))
+ return PTR_ERR(imx_phy->base);
+
+ imx_phy->phy = devm_phy_create(dev, NULL, &imx8mq_usb_phy_ops);
+ if (IS_ERR(imx_phy->phy))
+ return PTR_ERR(imx_phy->phy);
+
+ phy_set_drvdata(imx_phy->phy, imx_phy);
+
+ imx8mq_usb_phy_init(imx_phy);
+
+ phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
+
+ return PTR_ERR_OR_ZERO(phy_provider);
+}
+
+static const struct of_device_id imx8mq_usb_phy_of_match[] = {
+ {.compatible = "fsl,imx8mq-usb-phy",},
+ { },
+};
+MODULE_DEVICE_TABLE(of, imx8mq_usb_phy_of_match);
+
+static struct platform_driver imx8mq_usb_phy_driver = {
+ .probe = imx8mq_usb_phy_probe,
+ .driver = {
+ .name = "imx8mq-usb-phy",
+ .of_match_table = imx8mq_usb_phy_of_match,
+ }
+};
+module_platform_driver(imx8mq_usb_phy_driver);
+
+MODULE_DESCRIPTION("FSL IMX8MQ USB PHY driver");
+MODULE_ALIAS("platform:imx8mq-usb-phy");
+MODULE_LICENSE("GPL");
diff --git a/drivers/phy/phy-mixel-lvds-combo.c b/drivers/phy/phy-mixel-lvds-combo.c
new file mode 100644
index 000000000000..3b888b110e0d
--- /dev/null
+++ b/drivers/phy/phy-mixel-lvds-combo.c
@@ -0,0 +1,285 @@
+/*
+ * Copyright 2017 NXP
+ *
+ * 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/clk.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/phy/phy.h>
+#include <linux/phy/phy-mixel-lvds-combo.h>
+#include <linux/platform_device.h>
+
+/* Control and Status Registers(CSR) */
+#define PHY_CTRL 0x00
+#define CCM(n) (((n) & 0x7) << 5)
+#define CCM_MASK 0xe0
+#define CA(n) (((n) & 0x7) << 2)
+#define CA_MASK 0x1c
+#define RFB BIT(1)
+#define LVDS_EN BIT(0)
+
+#define SS 0x20
+#define CH_HSYNC_M(id) BIT(0 + ((id) * 2))
+#define CH_VSYNC_M(id) BIT(1 + ((id) * 2))
+#define CH_PHSYNC(id) BIT(0 + ((id) * 2))
+#define CH_PVSYNC(id) BIT(1 + ((id) * 2))
+
+#define ULPS 0x30
+#define ULPS_MASK 0x1f
+#define LANE(n) BIT(n)
+
+#define DPI 0x40
+#define COLOR_CODE_MASK 0x7
+#define BIT16_CFG1 0x0
+#define BIT16_CFG2 0x1
+#define BIT16_CFG3 0x2
+#define BIT18_CFG1 0x3
+#define BIT18_CFG2 0x4
+#define BIT24 0x5
+
+/* controller registers */
+#define PD_TX 0x300
+#define PD_PLL 0x31c
+
+struct mixel_lvds_phy {
+ struct device *dev;
+ void __iomem *csr_base;
+ void __iomem *ctrl_base;
+ struct mutex lock;
+ struct phy *phy;
+ struct clk *phy_clk;
+};
+
+static inline u32 phy_csr_read(struct phy *phy, unsigned int reg)
+{
+ struct mixel_lvds_phy *lvds_phy = phy_get_drvdata(phy);
+
+ return readl(lvds_phy->csr_base + reg);
+}
+
+static inline void phy_csr_write(struct phy *phy, u32 value, unsigned int reg)
+{
+ struct mixel_lvds_phy *lvds_phy = phy_get_drvdata(phy);
+
+ writel(value, lvds_phy->csr_base + reg);
+}
+
+static inline u32 phy_ctrl_read(struct phy *phy, unsigned int reg)
+{
+ struct mixel_lvds_phy *lvds_phy = phy_get_drvdata(phy);
+
+ return readl(lvds_phy->ctrl_base + reg);
+}
+
+static inline void phy_ctrl_write(struct phy *phy, u32 value, unsigned int reg)
+{
+ struct mixel_lvds_phy *lvds_phy = phy_get_drvdata(phy);
+
+ writel(value, lvds_phy->ctrl_base + reg);
+}
+
+void mixel_phy_combo_lvds_set_phy_speed(struct phy *phy,
+ unsigned long phy_clk_rate)
+{
+ struct mixel_lvds_phy *lvds_phy = phy_get_drvdata(phy);
+
+ /*
+ * To workaround setting clock rate failure issue
+ * when the system resumes back from PM sleep mode,
+ * we need to get the clock rate before setting it's
+ * rate, otherwise, setting the clock rate will fail.
+ */
+ clk_get_rate(lvds_phy->phy_clk);
+ clk_set_rate(lvds_phy->phy_clk, phy_clk_rate);
+}
+EXPORT_SYMBOL_GPL(mixel_phy_combo_lvds_set_phy_speed);
+
+void mixel_phy_combo_lvds_set_hsync_pol(struct phy *phy, bool active_high)
+{
+ struct mixel_lvds_phy *lvds_phy = phy_get_drvdata(phy);
+ u32 val;
+
+ clk_prepare_enable(lvds_phy->phy_clk);
+ mutex_lock(&lvds_phy->lock);
+ val = phy_csr_read(phy, SS);
+ val &= ~(CH_HSYNC_M(0) | CH_HSYNC_M(1));
+ if (active_high)
+ val |= (CH_PHSYNC(0) | CH_PHSYNC(1));
+ phy_csr_write(phy, val, SS);
+ mutex_unlock(&lvds_phy->lock);
+ clk_disable_unprepare(lvds_phy->phy_clk);
+}
+EXPORT_SYMBOL_GPL(mixel_phy_combo_lvds_set_hsync_pol);
+
+void mixel_phy_combo_lvds_set_vsync_pol(struct phy *phy, bool active_high)
+{
+ struct mixel_lvds_phy *lvds_phy = phy_get_drvdata(phy);
+ u32 val;
+
+ clk_prepare_enable(lvds_phy->phy_clk);
+ mutex_lock(&lvds_phy->lock);
+ val = phy_csr_read(phy, SS);
+ val &= ~(CH_VSYNC_M(0) | CH_VSYNC_M(1));
+ if (active_high)
+ val |= (CH_PVSYNC(0) | CH_PVSYNC(1));
+ phy_csr_write(phy, val, SS);
+ mutex_unlock(&lvds_phy->lock);
+ clk_disable_unprepare(lvds_phy->phy_clk);
+}
+EXPORT_SYMBOL_GPL(mixel_phy_combo_lvds_set_vsync_pol);
+
+static int mixel_lvds_combo_phy_init(struct phy *phy)
+{
+ struct mixel_lvds_phy *lvds_phy = phy_get_drvdata(phy);
+ u32 val;
+
+ clk_prepare_enable(lvds_phy->phy_clk);
+ mutex_lock(&lvds_phy->lock);
+ val = phy_csr_read(phy, PHY_CTRL);
+ val &= ~(CCM_MASK | CA_MASK);
+ val |= (CCM(0x5) | CA(0x4) | RFB);
+ phy_csr_write(phy, val, PHY_CTRL);
+
+ val = phy_csr_read(phy, DPI);
+ val &= ~COLOR_CODE_MASK;
+ val |= BIT24;
+ phy_csr_write(phy, val, DPI);
+ mutex_unlock(&lvds_phy->lock);
+ clk_disable_unprepare(lvds_phy->phy_clk);
+
+ return 0;
+}
+
+static int mixel_lvds_combo_phy_power_on(struct phy *phy)
+{
+ struct mixel_lvds_phy *lvds_phy = phy_get_drvdata(phy);
+ u32 val;
+
+ clk_prepare_enable(lvds_phy->phy_clk);
+ mutex_lock(&lvds_phy->lock);
+ phy_ctrl_write(phy, 0, PD_PLL);
+ phy_ctrl_write(phy, 0, PD_TX);
+
+ val = phy_csr_read(phy, ULPS);
+ val &= ~ULPS_MASK;
+ phy_csr_write(phy, val, ULPS);
+
+ val = phy_csr_read(phy, PHY_CTRL);
+ val |= LVDS_EN;
+ phy_csr_write(phy, val, PHY_CTRL);
+ mutex_unlock(&lvds_phy->lock);
+
+ usleep_range(500, 1000);
+
+ return 0;
+}
+
+static int mixel_lvds_combo_phy_power_off(struct phy *phy)
+{
+ struct mixel_lvds_phy *lvds_phy = phy_get_drvdata(phy);
+ u32 val;
+
+ mutex_lock(&lvds_phy->lock);
+ val = phy_csr_read(phy, PHY_CTRL);
+ val &= ~LVDS_EN;
+ phy_csr_write(phy, val, PHY_CTRL);
+
+ val = phy_csr_read(phy, ULPS);
+ val |= ULPS_MASK;
+ phy_csr_write(phy, val, ULPS);
+
+ phy_ctrl_write(phy, 1, PD_TX);
+ phy_ctrl_write(phy, 1, PD_PLL);
+ mutex_unlock(&lvds_phy->lock);
+ clk_disable_unprepare(lvds_phy->phy_clk);
+
+ return 0;
+}
+
+static const struct phy_ops mixel_lvds_combo_phy_ops = {
+ .init = mixel_lvds_combo_phy_init,
+ .power_on = mixel_lvds_combo_phy_power_on,
+ .power_off = mixel_lvds_combo_phy_power_off,
+ .owner = THIS_MODULE,
+};
+
+static int mixel_lvds_combo_phy_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct resource *res;
+ struct phy_provider *phy_provider;
+ struct mixel_lvds_phy *lvds_phy;
+
+ lvds_phy = devm_kzalloc(dev, sizeof(*lvds_phy), GFP_KERNEL);
+ if (!lvds_phy)
+ return -ENOMEM;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res)
+ return -ENODEV;
+
+ lvds_phy->csr_base = devm_ioremap(dev, res->start, SZ_256);
+ if (!lvds_phy->csr_base)
+ return -ENOMEM;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+ if (!res)
+ return -ENODEV;
+
+ lvds_phy->ctrl_base = devm_ioremap(dev, res->start, SZ_4K);
+ if (!lvds_phy->ctrl_base)
+ return -ENOMEM;
+
+ lvds_phy->phy_clk = devm_clk_get(dev, "phy");
+ if (IS_ERR(lvds_phy->phy_clk)) {
+ dev_err(dev, "cannot get phy clock\n");
+ return PTR_ERR(lvds_phy->phy_clk);
+ }
+
+ lvds_phy->dev = dev;
+ mutex_init(&lvds_phy->lock);
+
+ lvds_phy->phy = devm_phy_create(dev, NULL, &mixel_lvds_combo_phy_ops);
+ if (IS_ERR(lvds_phy->phy)) {
+ dev_err(dev, "failed to create phy\n");
+ return PTR_ERR(lvds_phy->phy);
+ }
+
+ phy_set_drvdata(lvds_phy->phy, lvds_phy);
+
+ phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
+
+ return PTR_ERR_OR_ZERO(phy_provider);
+}
+
+static const struct of_device_id mixel_lvds_combo_phy_of_match[] = {
+ { .compatible = "mixel,lvds-combo-phy" },
+ {}
+};
+MODULE_DEVICE_TABLE(of, mixel_lvds_combo_phy_of_match);
+
+static struct platform_driver mixel_lvds_combo_phy_driver = {
+ .probe = mixel_lvds_combo_phy_probe,
+ .driver = {
+ .name = "mixel-lvds-combo-phy",
+ .of_match_table = mixel_lvds_combo_phy_of_match,
+ }
+};
+module_platform_driver(mixel_lvds_combo_phy_driver);
+
+MODULE_AUTHOR("NXP Semiconductor");
+MODULE_DESCRIPTION("Mixel LVDS combo PHY driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/phy/phy-mixel-lvds.c b/drivers/phy/phy-mixel-lvds.c
new file mode 100644
index 000000000000..31188884f331
--- /dev/null
+++ b/drivers/phy/phy-mixel-lvds.c
@@ -0,0 +1,309 @@
+/*
+ * Copyright 2017 NXP
+ *
+ * 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/clk.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/phy/phy.h>
+#include <linux/phy/phy-mixel-lvds.h>
+#include <linux/platform_device.h>
+
+#define SET 0x4
+#define CLR 0x8
+#define TOG 0xc
+
+#define PHY_CTRL 0x0
+#define M(n) (((n) & 0x3) << 17)
+#define M_MASK 0x60000
+#define CCM(n) (((n) & 0x7) << 14)
+#define CCM_MASK 0x1c000
+#define CA(n) (((n) & 0x7) << 11)
+#define CA_MASK 0x3800
+#define TST(n) (((n) & 0x3f) << 5)
+#define TST_MASK 0x7e0
+#define CH_EN(id) BIT(3 + (id))
+#define NB BIT(2)
+#define RFB BIT(1)
+#define PD BIT(0)
+
+#define PHY_STATUS 0x10
+#define LOCK BIT(0)
+
+#define PHY_SS_CTRL 0x20
+#define CH_HSYNC_M(id) BIT(0 + ((id) * 2))
+#define CH_VSYNC_M(id) BIT(1 + ((id) * 2))
+#define CH_PHSYNC(id) BIT(0 + ((id) * 2))
+#define CH_PVSYNC(id) BIT(1 + ((id) * 2))
+
+struct mixel_lvds_phy {
+ struct phy *phy;
+ unsigned int id;
+};
+
+struct mixel_lvds_phy_priv {
+ struct device *dev;
+ void __iomem *base;
+ struct mutex lock;
+ struct clk *phy_clk;
+ struct mixel_lvds_phy *phys[2];
+};
+
+static inline u32 phy_read(struct phy *phy, unsigned int reg)
+{
+ struct mixel_lvds_phy_priv *priv = dev_get_drvdata(phy->dev.parent);
+
+ return readl(priv->base + reg);
+}
+
+static inline void phy_write(struct phy *phy, u32 value, unsigned int reg)
+{
+ struct mixel_lvds_phy_priv *priv = dev_get_drvdata(phy->dev.parent);
+
+ writel(value, priv->base + reg);
+}
+
+void mixel_phy_lvds_set_phy_speed(struct phy *phy, unsigned long phy_clk_rate)
+{
+ struct mixel_lvds_phy_priv *priv = dev_get_drvdata(phy->dev.parent);
+ u32 val;
+
+ /* assuming NB is zero - 7bits per channel */
+ clk_prepare_enable(priv->phy_clk);
+ mutex_lock(&priv->lock);
+ val = phy_read(phy, PHY_CTRL);
+ val &= ~M_MASK;
+ if (phy_clk_rate < 44000000)
+ val |= M(0x2);
+ else if (phy_clk_rate < 90000000)
+ val |= M(0x1);
+ else
+ val |= M(0x0);
+ phy_write(phy, val, PHY_CTRL);
+ mutex_unlock(&priv->lock);
+ clk_disable_unprepare(priv->phy_clk);
+
+ /*
+ * To workaround setting clock rate failure issue
+ * when the system resumes back from PM sleep mode,
+ * we need to get the clock rate before setting it's
+ * rate, otherwise, setting the clock rate will fail.
+ */
+ clk_get_rate(priv->phy_clk);
+ clk_set_rate(priv->phy_clk, phy_clk_rate);
+}
+EXPORT_SYMBOL_GPL(mixel_phy_lvds_set_phy_speed);
+
+void mixel_phy_lvds_set_hsync_pol(struct phy *phy, bool active_high)
+{
+ struct mixel_lvds_phy_priv *priv = dev_get_drvdata(phy->dev.parent);
+ struct mixel_lvds_phy *lvds_phy = phy_get_drvdata(phy);
+ unsigned int id = lvds_phy->id;
+ u32 val;
+
+ clk_prepare_enable(priv->phy_clk);
+ mutex_lock(&priv->lock);
+ val = phy_read(phy, PHY_SS_CTRL);
+ val &= ~CH_HSYNC_M(id);
+ if (active_high)
+ val |= CH_PHSYNC(id);
+ phy_write(phy, val, PHY_SS_CTRL);
+ mutex_unlock(&priv->lock);
+ clk_disable_unprepare(priv->phy_clk);
+}
+EXPORT_SYMBOL_GPL(mixel_phy_lvds_set_hsync_pol);
+
+void mixel_phy_lvds_set_vsync_pol(struct phy *phy, bool active_high)
+{
+ struct mixel_lvds_phy_priv *priv = dev_get_drvdata(phy->dev.parent);
+ struct mixel_lvds_phy *lvds_phy = phy_get_drvdata(phy);
+ unsigned int id = lvds_phy->id;
+ u32 val;
+
+ clk_prepare_enable(priv->phy_clk);
+ mutex_lock(&priv->lock);
+ val = phy_read(phy, PHY_SS_CTRL);
+ val &= ~CH_VSYNC_M(id);
+ if (active_high)
+ val |= CH_PVSYNC(id);
+ phy_write(phy, val, PHY_SS_CTRL);
+ mutex_unlock(&priv->lock);
+ clk_disable_unprepare(priv->phy_clk);
+}
+EXPORT_SYMBOL_GPL(mixel_phy_lvds_set_vsync_pol);
+
+static int mixel_lvds_phy_init(struct phy *phy)
+{
+ struct mixel_lvds_phy_priv *priv = dev_get_drvdata(phy->dev.parent);
+ u32 val;
+
+ clk_prepare_enable(priv->phy_clk);
+ mutex_lock(&priv->lock);
+ val = phy_read(phy, PHY_CTRL);
+ val &= ~(M_MASK | CCM_MASK | CA_MASK | TST_MASK | NB | PD);
+ val |= (M(0x0) | CCM(0x5) | CA(0x4) | TST(0x25) | RFB);
+ phy_write(phy, val, PHY_CTRL);
+ mutex_unlock(&priv->lock);
+ clk_disable_unprepare(priv->phy_clk);
+
+ return 0;
+}
+
+static int mixel_lvds_phy_power_on(struct phy *phy)
+{
+ struct mixel_lvds_phy_priv *priv = dev_get_drvdata(phy->dev.parent);
+ struct mixel_lvds_phy *lvds_phy = phy_get_drvdata(phy);
+ unsigned int id = lvds_phy->id;
+
+ clk_prepare_enable(priv->phy_clk);
+
+ mutex_lock(&priv->lock);
+ phy_write(phy, CH_EN(id), PHY_CTRL + SET);
+ mutex_unlock(&priv->lock);
+
+ usleep_range(500, 1000);
+
+ return 0;
+}
+
+static int mixel_lvds_phy_power_off(struct phy *phy)
+{
+ struct mixel_lvds_phy_priv *priv = dev_get_drvdata(phy->dev.parent);
+ struct mixel_lvds_phy *lvds_phy = phy_get_drvdata(phy);
+ unsigned int id = lvds_phy->id;
+
+ mutex_lock(&priv->lock);
+ phy_write(phy, CH_EN(id), PHY_CTRL + CLR);
+ mutex_unlock(&priv->lock);
+
+ clk_disable_unprepare(priv->phy_clk);
+
+ return 0;
+}
+
+static const struct phy_ops mixel_lvds_phy_ops = {
+ .init = mixel_lvds_phy_init,
+ .power_on = mixel_lvds_phy_power_on,
+ .power_off = mixel_lvds_phy_power_off,
+ .owner = THIS_MODULE,
+};
+
+static int mixel_lvds_phy_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct device_node *np = dev->of_node;
+ struct device_node *child;
+ struct resource *res;
+ struct phy_provider *phy_provider;
+ struct mixel_lvds_phy_priv *priv;
+ struct mixel_lvds_phy *lvds_phy;
+ struct phy *phy;
+ u32 phy_id;
+ int ret;
+
+ if (!np)
+ return -ENODEV;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res)
+ return -ENODEV;
+
+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ priv->base = devm_ioremap(dev, res->start, SZ_256);
+ if (!priv->base)
+ return -ENOMEM;
+
+ priv->dev = dev;
+
+ priv->phy_clk = devm_clk_get(dev, "phy");
+ if (IS_ERR(priv->phy_clk)) {
+ dev_err(dev, "cannot get phy clock\n");
+ return PTR_ERR(priv->phy_clk);
+ }
+
+ mutex_init(&priv->lock);
+ dev_set_drvdata(dev, priv);
+
+ for_each_available_child_of_node(np, child) {
+ if (of_property_read_u32(child, "reg", &phy_id)) {
+ dev_err(dev, "missing reg property in node %s\n",
+ child->name);
+ ret = -EINVAL;
+ goto put_child;
+ }
+
+ if (phy_id >= ARRAY_SIZE(priv->phys)) {
+ dev_err(dev, "invalid reg in node %s\n", child->name);
+ ret = -EINVAL;
+ goto put_child;
+ }
+
+ if (priv->phys[phy_id]) {
+ dev_err(dev, "duplicated phy id: %u\n", phy_id);
+ ret = -EINVAL;
+ goto put_child;
+ }
+
+ lvds_phy = devm_kzalloc(dev, sizeof(*lvds_phy), GFP_KERNEL);
+ if (!lvds_phy) {
+ ret = -ENOMEM;
+ goto put_child;
+ }
+
+ phy = devm_phy_create(dev, child, &mixel_lvds_phy_ops);
+ if (IS_ERR(phy)) {
+ dev_err(dev, "failed to create phy\n");
+ ret = PTR_ERR(phy);
+ goto put_child;
+ }
+
+ lvds_phy->phy = phy;
+ lvds_phy->id = phy_id;
+ priv->phys[phy_id] = lvds_phy;
+
+ phy_set_drvdata(phy, lvds_phy);
+ }
+
+ phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
+
+ return PTR_ERR_OR_ZERO(phy_provider);
+
+put_child:
+ of_node_put(child);
+ return ret;
+}
+
+static const struct of_device_id mixel_lvds_phy_of_match[] = {
+ { .compatible = "mixel,lvds-phy" },
+ {}
+};
+MODULE_DEVICE_TABLE(of, mixel_lvds_phy_of_match);
+
+static struct platform_driver mixel_lvds_phy_driver = {
+ .probe = mixel_lvds_phy_probe,
+ .driver = {
+ .name = "mixel-lvds-phy",
+ .of_match_table = mixel_lvds_phy_of_match,
+ }
+};
+module_platform_driver(mixel_lvds_phy_driver);
+
+MODULE_AUTHOR("NXP Semiconductor");
+MODULE_DESCRIPTION("Mixel LVDS PHY driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/phy/phy-mixel-mipi-dsi.c b/drivers/phy/phy-mixel-mipi-dsi.c
new file mode 100644
index 000000000000..493612649e3d
--- /dev/null
+++ b/drivers/phy/phy-mixel-mipi-dsi.c
@@ -0,0 +1,545 @@
+/*
+ * Copyright 2018 NXP
+ *
+ * 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/delay.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/phy/phy-mixel-mipi-dsi.h>
+#include <linux/phy/phy.h>
+#include <linux/platform_device.h>
+#include <soc/imx8/sc/sci.h>
+
+#define DPHY_PD_DPHY 0x00
+#define DPHY_M_PRG_HS_PREPARE 0x04
+#define DPHY_MC_PRG_HS_PREPARE 0x08
+#define DPHY_M_PRG_HS_ZERO 0x0c
+#define DPHY_MC_PRG_HS_ZERO 0x10
+#define DPHY_M_PRG_HS_TRAIL 0x14
+#define DPHY_MC_PRG_HS_TRAIL 0x18
+#define DPHY_PD_PLL 0x1c
+#define DPHY_TST 0x20
+#define DPHY_CN 0x24
+#define DPHY_CM 0x28
+#define DPHY_CO 0x2c
+#define DPHY_LOCK 0x30
+#define DPHY_LOCK_BYP 0x34
+
+#define MBPS(x) ((x) * 1000000)
+
+#define DATA_RATE_MAX_SPEED MBPS(1500)
+#define DATA_RATE_MIN_SPEED MBPS(80)
+
+#define CN_BUF 0xcb7a89c0
+#define CO_BUF 0x63
+#define CM(x) ( \
+ ((x) < 32)?0xe0|((x)-16) : \
+ ((x) < 64)?0xc0|((x)-32) : \
+ ((x) < 128)?0x80|((x)-64) : \
+ ((x) - 128))
+#define CN(x) (((x) == 1)?0x1f : (((CN_BUF)>>((x)-1))&0x1f))
+#define CO(x) ((CO_BUF)>>(8-(x))&0x3)
+
+/* PHY power on is LOW_ENABLE */
+#define PWR_ON 0
+#define PWR_OFF 1
+
+struct pll_divider {
+ u32 cm;
+ u32 cn;
+ u32 co;
+};
+
+struct devtype {
+ bool have_sc;
+ u8 reg_tx_rcal;
+ u8 reg_auto_pd_en;
+ u8 reg_rxlprp;
+ u8 reg_rxcdrp;
+ u8 reg_rxhs_settle;
+ u8 reg_bypass_pll;
+};
+
+struct mixel_mipi_phy_priv {
+ struct device *dev;
+ void __iomem *base;
+ const struct devtype *plat_data;
+ sc_rsrc_t mipi_id;
+ struct pll_divider divider;
+ struct mutex lock;
+ unsigned long data_rate;
+};
+
+
+static inline u32 phy_read(struct phy *phy, unsigned int reg)
+{
+ struct mixel_mipi_phy_priv *priv = phy_get_drvdata(phy);
+
+ return readl(priv->base + reg);
+}
+
+static inline void phy_write(struct phy *phy, u32 value, unsigned int reg)
+{
+ struct mixel_mipi_phy_priv *priv = phy_get_drvdata(phy);
+
+ writel(value, priv->base + reg);
+}
+
+/*
+ * mixel_phy_mipi_set_phy_speed:
+ * Input params:
+ * bit_clk: PHY PLL needed output clock
+ * ref_clk: reference input clock for the PHY PLL
+ *
+ * Returns:
+ * 0: if the bit_clk can be achieved for the given ref_clk
+ * -EINVAL: otherwise
+ */
+int mixel_phy_mipi_set_phy_speed(struct phy *phy,
+ unsigned long bit_clk,
+ unsigned long ref_clk,
+ bool best_match)
+{
+ struct mixel_mipi_phy_priv *priv = dev_get_drvdata(phy->dev.parent);
+ u32 div_rate;
+ u32 numerator = 0;
+ u32 denominator = 1;
+
+ if (bit_clk > DATA_RATE_MAX_SPEED || bit_clk < DATA_RATE_MIN_SPEED)
+ return -EINVAL;
+
+ /* simulated fixed point with 3 decimals */
+ div_rate = (bit_clk * 1000) / ref_clk;
+
+ while (denominator <= 256) {
+ if (div_rate % 1000 == 0)
+ numerator = div_rate / 1000;
+ if (numerator > 15)
+ break;
+ denominator = denominator << 1;
+ div_rate = div_rate << 1;
+ }
+
+ /* CM ranges between 16 and 255 */
+ /* CN ranges between 1 and 32 */
+ /* CO is power of 2: 1, 2, 4, 8 */
+ if (best_match && numerator < 16)
+ numerator = div_rate / 1000;
+
+ if (best_match && numerator > 255) {
+ while (numerator > 255 && denominator > 1) {
+ numerator = DIV_ROUND_UP(numerator, 2);
+ denominator = denominator >> 1;
+ }
+ }
+
+ if (numerator < 16 || numerator > 255)
+ return -EINVAL;
+
+ if (best_match)
+ numerator = DIV_ROUND_UP(numerator, denominator) * denominator;
+
+ priv->divider.cn = 1;
+ if (denominator > 8) {
+ priv->divider.cn = denominator >> 3;
+ denominator = 8;
+ }
+ priv->divider.co = denominator;
+ priv->divider.cm = numerator;
+
+ priv->data_rate = bit_clk;
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(mixel_phy_mipi_set_phy_speed);
+
+static int mixel_mipi_phy_enable(struct phy *phy, u32 reset)
+{
+ struct mixel_mipi_phy_priv *priv = phy_get_drvdata(phy);
+ sc_err_t sci_err = 0;
+ sc_ipc_t ipc_handle = 0;
+ u32 mu_id;
+
+ sci_err = sc_ipc_getMuID(&mu_id);
+ if (sci_err != SC_ERR_NONE) {
+ dev_err(&phy->dev, "Failed to get MU ID (%d)\n", sci_err);
+ return -ENODEV;
+ }
+ sci_err = sc_ipc_open(&ipc_handle, mu_id);
+ if (sci_err != SC_ERR_NONE) {
+ dev_err(&phy->dev, "Failed to open IPC (%d)\n", sci_err);
+ return -ENODEV;
+ }
+
+ sci_err = sc_misc_set_control(ipc_handle,
+ priv->mipi_id,
+ SC_C_PHY_RESET,
+ reset);
+ if (sci_err != SC_ERR_NONE) {
+ dev_err(&phy->dev, "Failed to reset DPHY (%d)\n", sci_err);
+ sc_ipc_close(ipc_handle);
+ return -ENODEV;
+ }
+
+ sc_ipc_close(ipc_handle);
+
+ return 0;
+}
+
+/*
+ * We tried our best here to use the values as specified in
+ * Reference Manual, but we got unstable results. So, these values
+ * are hacked from their original explanation as found in RM.
+ */
+static void mixel_phy_set_prg_regs(struct phy *phy)
+{
+ struct mixel_mipi_phy_priv *priv = phy_get_drvdata(phy);
+ unsigned int hs_reg;
+
+ /* MC_PRG_HS_PREPARE = 1.0 * Ttxescape if DPHY_MC_PRG_HS_PREPARE = 0
+ *
+ * MC_PRG_HS_PREPARE = 1.5 * Ttxescape if DPHY_MC_PRG_HS_PREPARE = 1
+ *
+ * Assume Ftxescape is 18-20 MHz with DPHY_MC_PRG_HS_PREPARE = 0,
+ * this gives 55-50 ns.
+ * The specification is 38 to 95 ns.
+ */
+ phy_write(phy, 0x00, DPHY_MC_PRG_HS_PREPARE);
+
+ /* PRG_HS_PREPARE
+ * for PRG_HS_PREPARE = 00, THS-PREPARE = 1 * TxClkEsc Period
+ * PRG_HS_PREPARE = 01, THS-PREPARE = 1.5 * TxClkEsc Period
+ * PRG_HS_PREPARE = 10, THS-PREPARE = 2 * TxClkEsc Period
+ * PRG_HS_PREPARE = 11, THS-PREPARE = 2.5 * TxClkEsc Period
+ *
+ * The specification for THS-PREPARE is
+ * Min (40ns + 4*UI)
+ * Max 85ns +6*UI
+ */
+ if (priv->data_rate <= MBPS(61))
+ phy_write(phy, 0x03, DPHY_M_PRG_HS_PREPARE);
+ else if (priv->data_rate <= MBPS(90))
+ phy_write(phy, 0x02, DPHY_M_PRG_HS_PREPARE);
+ else if (priv->data_rate <= MBPS(500))
+ phy_write(phy, 0x01, DPHY_M_PRG_HS_PREPARE);
+ else
+ phy_write(phy, 0x00, DPHY_M_PRG_HS_PREPARE);
+
+ /* MC_PRG_HS_ZERO
+ *
+ * T-CLK-ZERO = ( MC_PRG_HS_ZERO + 3) * (TxByteClkHS Period)
+ *
+ * The minimum specification for THS-PREPARE is 262 ns.
+ *
+ */
+ hs_reg =
+ /* simplified equation y = .034x - 2.5
+ *
+ * This a linear interpolation of the values from the
+ * PHY user guide
+ */
+ (34 * (priv->data_rate/1000000) - 2500) / 1000;
+
+ if (hs_reg < 1)
+ hs_reg = 1;
+ phy_write(phy, hs_reg, DPHY_MC_PRG_HS_ZERO);
+
+ /* M_PRG_HS_ZERO
+ *
+ * TT-HS-ZERO =(M_PRG_HS_ZERO + 6) * (TxByteClkHS Period)
+ *
+ * The minimum specification for THS-ZERO 105ns + 6*UI.
+ *
+ */
+ hs_reg =
+ /* simplified equation y = .0144x - 4.75
+ *
+ * This a linear interpolation of the values from the
+ * PHY user guide
+ */
+
+ (144 * (priv->data_rate/1000000) - 47500) / 10000;
+
+ if (hs_reg < 1)
+ hs_reg = 1;
+ phy_write(phy, hs_reg, DPHY_M_PRG_HS_ZERO);
+
+ /* MC_PRG_HS_TRAIL and M_PRG_HS_TRAIL
+ *
+ * THS-TRAIL =(PRG_HS_TRAIL) * (TxByteClkHS Period)
+ *
+ * The specification for THS-TRAIL is
+ * Min (60ns + 4*UI)
+ * Typical (82.5ns + 8*UI)
+ * Max (105ns + 12*UI)
+ *
+ */
+
+ hs_reg =
+ /* simplified equation y = .0103x + 1
+ *
+ * This a linear interpolation of the values from the
+ * PHY user guide
+ */
+ (103 * (priv->data_rate/1000000) + 10000) / 10000;
+
+ if (hs_reg > 15)
+ hs_reg = 15;
+ if (hs_reg < 1)
+ hs_reg = 1;
+
+ phy_write(phy, hs_reg, DPHY_MC_PRG_HS_TRAIL);
+ phy_write(phy, hs_reg, DPHY_M_PRG_HS_TRAIL);
+
+ /* M_PRG_RXHS_SETTLE */
+ if (priv->plat_data->reg_rxhs_settle == 0xFF)
+ return;
+ if (priv->data_rate < MBPS(80))
+ phy_write(phy, 0x0d, priv->plat_data->reg_rxhs_settle);
+ else if (priv->data_rate < MBPS(90))
+ phy_write(phy, 0x0c, priv->plat_data->reg_rxhs_settle);
+ else if (priv->data_rate < MBPS(125))
+ phy_write(phy, 0x0b, priv->plat_data->reg_rxhs_settle);
+ else if (priv->data_rate < MBPS(150))
+ phy_write(phy, 0x0a, priv->plat_data->reg_rxhs_settle);
+ else if (priv->data_rate < MBPS(225))
+ phy_write(phy, 0x09, priv->plat_data->reg_rxhs_settle);
+ else if (priv->data_rate < MBPS(500))
+ phy_write(phy, 0x08, priv->plat_data->reg_rxhs_settle);
+ else
+ phy_write(phy, 0x07, priv->plat_data->reg_rxhs_settle);
+
+}
+
+static int mixel_mipi_phy_init(struct phy *phy)
+{
+ struct mixel_mipi_phy_priv *priv = dev_get_drvdata(phy->dev.parent);
+
+ mutex_lock(&priv->lock);
+
+ phy_write(phy, PWR_OFF, DPHY_PD_PLL);
+ phy_write(phy, PWR_OFF, DPHY_PD_DPHY);
+
+ if (priv->plat_data->have_sc) {
+ int ret;
+ ret = mixel_mipi_phy_enable(phy, 0);
+ if (ret)
+ return ret;
+ }
+
+ mixel_phy_set_prg_regs(phy);
+
+ phy_write(phy, 0x00, DPHY_LOCK_BYP);
+ if (priv->plat_data->reg_tx_rcal != 0xFF)
+ phy_write(phy, 0x01, priv->plat_data->reg_tx_rcal);
+ if (priv->plat_data->reg_auto_pd_en != 0xFF)
+ phy_write(phy, 0x00, priv->plat_data->reg_auto_pd_en);
+ if (priv->plat_data->reg_rxlprp != 0xFF)
+ phy_write(phy, 0x02, priv->plat_data->reg_rxlprp);
+ if (priv->plat_data->reg_rxcdrp != 0xFF)
+ phy_write(phy, 0x02, priv->plat_data->reg_rxcdrp);
+ phy_write(phy, 0x25, DPHY_TST);
+
+ /* VCO = REF_CLK * CM / CN * CO */
+ if (priv->divider.cm < 16 || priv->divider.cm > 255 ||
+ priv->divider.cn < 1 || priv->divider.cn > 32 ||
+ priv->divider.co < 1 || priv->divider.co > 8) {
+ dev_err(&phy->dev, "Invalid CM/CN/CO values! (%u/%u/%u)\n",
+ priv->divider.cm, priv->divider.cn, priv->divider.co);
+ mutex_unlock(&priv->lock);
+ return -EINVAL;
+ }
+ dev_dbg(&phy->dev, "Using CM:%u CN:%u CO:%u\n",
+ priv->divider.cm, priv->divider.cn, priv->divider.co);
+ phy_write(phy, CM(priv->divider.cm), DPHY_CM);
+ phy_write(phy, CN(priv->divider.cn), DPHY_CN);
+ phy_write(phy, CO(priv->divider.co), DPHY_CO);
+
+ mutex_unlock(&priv->lock);
+
+ return 0;
+}
+
+static int mixel_mipi_phy_exit(struct phy *phy)
+{
+ phy_write(phy, 0, DPHY_CM);
+ phy_write(phy, 0, DPHY_CN);
+ phy_write(phy, 0, DPHY_CO);
+
+ return 0;
+}
+
+static int mixel_mipi_phy_power_on(struct phy *phy)
+{
+ struct mixel_mipi_phy_priv *priv = phy_get_drvdata(phy);
+ u32 lock, timeout;
+ int ret = 0;
+
+ mutex_lock(&priv->lock);
+
+ phy_write(phy, PWR_ON, DPHY_PD_PLL);
+
+ timeout = 100;
+ while (!(lock = phy_read(phy, DPHY_LOCK))) {
+ udelay(10);
+ if (--timeout == 0) {
+ dev_err(&phy->dev, "Could not get DPHY lock!\n");
+ phy_write(phy, PWR_OFF, DPHY_PD_PLL);
+ mutex_unlock(&priv->lock);
+ return -EINVAL;
+ }
+ }
+ dev_dbg(&phy->dev, "DPHY lock acquired after %d tries\n",
+ (100 - timeout));
+
+ phy_write(phy, PWR_ON, DPHY_PD_DPHY);
+
+ if (priv->plat_data->have_sc)
+ ret = mixel_mipi_phy_enable(phy, 1);
+
+ mutex_unlock(&priv->lock);
+
+ return ret;
+}
+
+static int mixel_mipi_phy_power_off(struct phy *phy)
+{
+ struct mixel_mipi_phy_priv *priv = phy_get_drvdata(phy);
+ int ret = 0;
+
+ mutex_lock(&priv->lock);
+
+ phy_write(phy, PWR_OFF, DPHY_PD_PLL);
+ phy_write(phy, PWR_OFF, DPHY_PD_DPHY);
+
+ if (priv->plat_data->have_sc)
+ ret = mixel_mipi_phy_enable(phy, 0);
+
+ mutex_unlock(&priv->lock);
+
+ return ret;
+}
+
+static const struct phy_ops mixel_mipi_phy_ops = {
+ .init = mixel_mipi_phy_init,
+ .exit = mixel_mipi_phy_exit,
+ .power_on = mixel_mipi_phy_power_on,
+ .power_off = mixel_mipi_phy_power_off,
+ .owner = THIS_MODULE,
+};
+
+static struct devtype imx8qm_dev = {
+ .have_sc = true,
+ .reg_tx_rcal = 0xFF,
+ .reg_auto_pd_en = 0x38,
+ .reg_rxlprp = 0x3c,
+ .reg_rxcdrp = 0x40,
+ .reg_rxhs_settle = 0x44,
+ .reg_bypass_pll = 0xFF,
+};
+static struct devtype imx8qxp_dev = {
+ .have_sc = true,
+ .reg_tx_rcal = 0xFF,
+ .reg_auto_pd_en = 0x38,
+ .reg_rxlprp = 0x3c,
+ .reg_rxcdrp = 0x40,
+ .reg_rxhs_settle = 0x44,
+ .reg_bypass_pll = 0xFF,
+};
+static struct devtype imx8mq_dev = {
+ .have_sc = false,
+ .reg_tx_rcal = 0x38,
+ .reg_auto_pd_en = 0x3c,
+ .reg_rxlprp = 0x40,
+ .reg_rxcdrp = 0x44,
+ .reg_rxhs_settle = 0x48,
+ .reg_bypass_pll = 0x4c,
+};
+
+static const struct of_device_id mixel_mipi_phy_of_match[] = {
+ { .compatible = "mixel,imx8qm-mipi-dsi-phy", .data = &imx8qm_dev },
+ { .compatible = "mixel,imx8qxp-mipi-dsi-phy", .data = &imx8qxp_dev },
+ { .compatible = "mixel,imx8mq-mipi-dsi-phy", .data = &imx8mq_dev },
+ {}
+};
+MODULE_DEVICE_TABLE(of, mixel_mipi_phy_of_match);
+
+static int mixel_mipi_phy_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct device_node *np = dev->of_node;
+ const struct of_device_id *of_id =
+ of_match_device(mixel_mipi_phy_of_match, dev);
+ struct phy_provider *phy_provider;
+ struct mixel_mipi_phy_priv *priv;
+ struct resource *res;
+ struct phy *phy;
+ int phy_id = 0;
+
+ if (!np)
+ return -ENODEV;
+
+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res)
+ return -ENODEV;
+
+ priv->base = devm_ioremap(dev, res->start, SZ_256);
+ if (IS_ERR(priv->base))
+ return PTR_ERR(priv->base);
+
+ priv->plat_data = of_id->data;
+
+ phy_id = of_alias_get_id(np, "dsi_phy");
+ if (phy_id < 0) {
+ dev_err(dev, "No dsi_phy alias found!");
+ return phy_id;
+ }
+
+ priv->mipi_id = phy_id?SC_R_MIPI_1:SC_R_MIPI_0;
+
+ priv->dev = dev;
+
+ mutex_init(&priv->lock);
+ dev_set_drvdata(dev, priv);
+
+ phy = devm_phy_create(dev, np, &mixel_mipi_phy_ops);
+ if (IS_ERR(phy)) {
+ dev_err(dev, "Failed to create phy\n");
+ return PTR_ERR(phy);
+ }
+ phy_set_drvdata(phy, priv);
+
+ phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
+
+ return PTR_ERR_OR_ZERO(phy_provider);
+}
+
+static struct platform_driver mixel_mipi_phy_driver = {
+ .probe = mixel_mipi_phy_probe,
+ .driver = {
+ .name = "mixel-mipi-dsi-phy",
+ .of_match_table = mixel_mipi_phy_of_match,
+ }
+};
+module_platform_driver(mixel_mipi_phy_driver);
+
+MODULE_AUTHOR("NXP Semiconductor");
+MODULE_DESCRIPTION("Mixel MIPI-DSI PHY driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/pinctrl/devicetree.c b/drivers/pinctrl/devicetree.c
index c4aa411f5935..1be9527b6537 100644
--- a/drivers/pinctrl/devicetree.c
+++ b/drivers/pinctrl/devicetree.c
@@ -18,6 +18,7 @@
#include <linux/device.h>
#include <linux/of.h>
+#include <linux/of_gpio.h>
#include <linux/pinctrl/pinctrl.h>
#include <linux/slab.h>
@@ -186,6 +187,46 @@ bool pinctrl_dt_has_hogs(struct pinctrl_dev *pctldev)
return prop ? true : false;
}
+static int dt_gpio_assert_pinctrl(struct pinctrl *p)
+{
+ struct device_node *np = p->dev->of_node;
+ enum of_gpio_flags flags;
+ int gpio;
+ int index = 0;
+ int ret;
+
+ if (!of_find_property(np, "pinctrl-assert-gpios", NULL))
+ return 0; /* Missing the property, so nothing to be done */
+
+ for (;; index++) {
+ gpio = of_get_named_gpio_flags(np, "pinctrl-assert-gpios",
+ index, &flags);
+ if (gpio < 0) {
+ if (gpio == -EPROBE_DEFER)
+ return gpio;
+ break; /* End of the phandle list */
+ }
+
+ if (!gpio_is_valid(gpio))
+ return -EINVAL;
+
+ ret = devm_gpio_request_one(p->dev, gpio, GPIOF_OUT_INIT_LOW,
+ NULL);
+ if (ret < 0)
+ return ret;
+
+ if (flags & OF_GPIO_ACTIVE_LOW)
+ continue;
+
+ if (gpio_cansleep(gpio))
+ gpio_set_value_cansleep(gpio, 1);
+ else
+ gpio_set_value(gpio, 1);
+ }
+
+ return 0;
+}
+
int pinctrl_dt_to_map(struct pinctrl *p, struct pinctrl_dev *pctldev)
{
struct device_node *np = p->dev->of_node;
@@ -206,6 +247,12 @@ int pinctrl_dt_to_map(struct pinctrl *p, struct pinctrl_dev *pctldev)
return 0;
}
+ ret = dt_gpio_assert_pinctrl(p);
+ if (ret) {
+ dev_dbg(p->dev, "failed to assert pinctrl setting: %d\n", ret);
+ return ret;
+ }
+
/* We may store pointers to property names within the node */
of_node_get(np);
diff --git a/drivers/pinctrl/freescale/Kconfig b/drivers/pinctrl/freescale/Kconfig
index 4dbc576ae27c..97abcb11e565 100644
--- a/drivers/pinctrl/freescale/Kconfig
+++ b/drivers/pinctrl/freescale/Kconfig
@@ -5,6 +5,12 @@ config PINCTRL_IMX
select GENERIC_PINCONF
select REGMAP
+config PINCTRL_IMX_SCU
+ bool
+
+config PINCTRL_IMX_MEMMAP
+ bool
+
config PINCTRL_IMX1_CORE
bool
select PINMUX
@@ -37,6 +43,7 @@ config PINCTRL_IMX25
depends on OF
depends on SOC_IMX25
select PINCTRL_IMX
+ select PINCTRL_IMX_MEMMAP
help
Say Y here to enable the imx25 pinctrl driver
@@ -44,6 +51,7 @@ config PINCTRL_IMX35
bool "IMX35 pinctrl driver"
depends on SOC_IMX35
select PINCTRL_IMX
+ select PINCTRL_IMX_MEMMAP
help
Say Y here to enable the imx35 pinctrl driver
@@ -51,6 +59,7 @@ config PINCTRL_IMX50
bool "IMX50 pinctrl driver"
depends on SOC_IMX50
select PINCTRL_IMX
+ select PINCTRL_IMX_MEMMAP
help
Say Y here to enable the imx50 pinctrl driver
@@ -58,6 +67,7 @@ config PINCTRL_IMX51
bool "IMX51 pinctrl driver"
depends on SOC_IMX51
select PINCTRL_IMX
+ select PINCTRL_IMX_MEMMAP
help
Say Y here to enable the imx51 pinctrl driver
@@ -65,6 +75,7 @@ config PINCTRL_IMX53
bool "IMX53 pinctrl driver"
depends on SOC_IMX53
select PINCTRL_IMX
+ select PINCTRL_IMX_MEMMAP
help
Say Y here to enable the imx53 pinctrl driver
@@ -72,6 +83,7 @@ config PINCTRL_IMX6Q
bool "IMX6Q/DL pinctrl driver"
depends on SOC_IMX6Q
select PINCTRL_IMX
+ select PINCTRL_IMX_MEMMAP
help
Say Y here to enable the imx6q/dl pinctrl driver
@@ -79,6 +91,7 @@ config PINCTRL_IMX6SL
bool "IMX6SL pinctrl driver"
depends on SOC_IMX6SL
select PINCTRL_IMX
+ select PINCTRL_IMX_MEMMAP
help
Say Y here to enable the imx6sl pinctrl driver
@@ -86,6 +99,7 @@ config PINCTRL_IMX6SX
bool "IMX6SX pinctrl driver"
depends on SOC_IMX6SX
select PINCTRL_IMX
+ select PINCTRL_IMX_MEMMAP
help
Say Y here to enable the imx6sx pinctrl driver
@@ -93,13 +107,23 @@ config PINCTRL_IMX6UL
bool "IMX6UL pinctrl driver"
depends on SOC_IMX6UL
select PINCTRL_IMX
+ select PINCTRL_IMX_MEMMAP
help
Say Y here to enable the imx6ul pinctrl driver
+config PINCTRL_IMX6SLL
+ bool "IMX6SLL pinctrl driver"
+ depends on SOC_IMX6SLL
+ select PINCTRL_IMX
+ select PINCTRL_IMX_MEMMAP
+ help
+ Say Y here to enable the imx6sll pinctrl driver
+
config PINCTRL_IMX7D
bool "IMX7D pinctrl driver"
depends on SOC_IMX7D
select PINCTRL_IMX
+ select PINCTRL_IMX_MEMMAP
help
Say Y here to enable the imx7d pinctrl driver
@@ -107,13 +131,47 @@ config PINCTRL_IMX7ULP
bool "IMX7ULP pinctrl driver"
depends on SOC_IMX7ULP
select PINCTRL_IMX
+ select PINCTRL_IMX_MEMMAP
help
Say Y here to enable the imx7ulp pinctrl driver
+config PINCTRL_IMX8QM
+ bool "IMX8QM pinctrl driver"
+ depends on ARCH_FSL_IMX8QM
+ select PINCTRL_IMX
+ select PINCTRL_IMX_SCU
+ help
+ Say Y here to enable the imx8qm pinctrl driver
+
+config PINCTRL_IMX8QXP
+ bool "IMX8QXP pinctrl driver"
+ depends on ARCH_FSL_IMX8QXP
+ select PINCTRL_IMX
+ select PINCTRL_IMX_SCU
+ help
+ Say Y here to enable the imx8qxp pinctrl driver
+
+config PINCTRL_IMX8MQ
+ bool "IMX8MQ pinctrl driver"
+ depends on ARCH_FSL_IMX8MQ
+ select PINCTRL_IMX
+ select PINCTRL_IMX_MEMMAP
+ help
+ Say Y here to enable the imx8mq pinctrl driver
+
+config PINCTRL_IMX8MM
+ bool "IMX8MM pinctrl driver"
+ depends on ARCH_FSL_IMX8MM
+ select PINCTRL_IMX
+ select PINCTRL_IMX_MEMMAP
+ help
+ Say Y here to enable the imx8mm pinctrl driver
+
config PINCTRL_VF610
bool "Freescale Vybrid VF610 pinctrl driver"
depends on SOC_VF610
select PINCTRL_IMX
+ select PINCTRL_IMX_MEMMAP
help
Say Y here to enable the Freescale Vybrid VF610 pinctrl driver
diff --git a/drivers/pinctrl/freescale/Makefile b/drivers/pinctrl/freescale/Makefile
index 19bb9a55a567..a359dad7a23e 100644
--- a/drivers/pinctrl/freescale/Makefile
+++ b/drivers/pinctrl/freescale/Makefile
@@ -1,6 +1,8 @@
# SPDX-License-Identifier: GPL-2.0
# Freescale pin control drivers
obj-$(CONFIG_PINCTRL_IMX) += pinctrl-imx.o
+obj-$(CONFIG_PINCTRL_IMX_MEMMAP)+= pinctrl-memmap.o
+obj-$(CONFIG_PINCTRL_IMX_SCU) += pinctrl-scu.o
obj-$(CONFIG_PINCTRL_IMX1_CORE) += pinctrl-imx1-core.o
obj-$(CONFIG_PINCTRL_IMX1) += pinctrl-imx1.o
obj-$(CONFIG_PINCTRL_IMX21) += pinctrl-imx21.o
@@ -14,8 +16,13 @@ obj-$(CONFIG_PINCTRL_IMX6Q) += pinctrl-imx6dl.o
obj-$(CONFIG_PINCTRL_IMX6SL) += pinctrl-imx6sl.o
obj-$(CONFIG_PINCTRL_IMX6SX) += pinctrl-imx6sx.o
obj-$(CONFIG_PINCTRL_IMX6UL) += pinctrl-imx6ul.o
+obj-$(CONFIG_PINCTRL_IMX6SLL) += pinctrl-imx6sll.o
obj-$(CONFIG_PINCTRL_IMX7D) += pinctrl-imx7d.o
obj-$(CONFIG_PINCTRL_IMX7ULP) += pinctrl-imx7ulp.o
+obj-$(CONFIG_PINCTRL_IMX8QM) += pinctrl-imx8qm.o
+obj-$(CONFIG_PINCTRL_IMX8QXP) += pinctrl-imx8qxp.o
+obj-$(CONFIG_PINCTRL_IMX8MQ) += pinctrl-imx8mq.o
+obj-$(CONFIG_PINCTRL_IMX8MM) += pinctrl-imx8mm.o
obj-$(CONFIG_PINCTRL_VF610) += pinctrl-vf610.o
obj-$(CONFIG_PINCTRL_MXS) += pinctrl-mxs.o
obj-$(CONFIG_PINCTRL_IMX23) += pinctrl-imx23.o
diff --git a/drivers/pinctrl/freescale/pinctrl-imx.c b/drivers/pinctrl/freescale/pinctrl-imx.c
index 17f2c5a505b2..c658fbd9856e 100644
--- a/drivers/pinctrl/freescale/pinctrl-imx.c
+++ b/drivers/pinctrl/freescale/pinctrl-imx.c
@@ -33,7 +33,6 @@
/* The bits in CONFIG cell defined in binding doc*/
#define IMX_NO_PAD_CTL 0x80000000 /* no pin config need */
-#define IMX_PAD_SION 0x40000000 /* set SION */
static inline const struct group_desc *imx_pinctrl_find_group_by_name(
struct pinctrl_dev *pctldev,
@@ -80,11 +79,15 @@ static int imx_dt_node_to_map(struct pinctrl_dev *pctldev,
return -EINVAL;
}
- for (i = 0; i < grp->num_pins; i++) {
- struct imx_pin *pin = &((struct imx_pin *)(grp->data))[i];
+ if (info->flags & IMX8_USE_SCU) {
+ map_num += grp->num_pins;
+ } else {
+ for (i = 0; i < grp->num_pins; i++) {
+ struct imx_pin *pin = &((struct imx_pin *)(grp->data))[i];
- if (!(pin->config & IMX_NO_PAD_CTL))
- map_num++;
+ if (!(pin->pin_conf.pin_memmap.config & IMX_NO_PAD_CTL))
+ map_num++;
+ }
}
new_map = kmalloc(sizeof(struct pinctrl_map) * map_num, GFP_KERNEL);
@@ -110,11 +113,20 @@ static int imx_dt_node_to_map(struct pinctrl_dev *pctldev,
for (i = j = 0; i < grp->num_pins; i++) {
struct imx_pin *pin = &((struct imx_pin *)(grp->data))[i];
- if (!(pin->config & IMX_NO_PAD_CTL)) {
+ if (info->flags & IMX8_USE_SCU) {
new_map[j].type = PIN_MAP_TYPE_CONFIGS_PIN;
new_map[j].data.configs.group_or_pin =
pin_get_name(pctldev, pin->pin);
- new_map[j].data.configs.configs = &pin->config;
+ new_map[j].data.configs.configs =
+ (unsigned long *)&pin->pin_conf.pin_scu;
+ new_map[j].data.configs.num_configs = 2;
+ j++;
+ } else if (!(pin->pin_conf.pin_memmap.config & IMX_NO_PAD_CTL)) {
+ new_map[j].type = PIN_MAP_TYPE_CONFIGS_PIN;
+ new_map[j].data.configs.group_or_pin =
+ pin_get_name(pctldev, pin->pin);
+ new_map[j].data.configs.configs =
+ &pin->pin_conf.pin_memmap.config;
new_map[j].data.configs.num_configs = 1;
j++;
}
@@ -147,9 +159,8 @@ static int imx_pmx_set(struct pinctrl_dev *pctldev, unsigned selector,
{
struct imx_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev);
struct imx_pinctrl_soc_info *info = ipctl->info;
- const struct imx_pin_reg *pin_reg;
- unsigned int npins, pin_id;
- int i;
+ unsigned int npins;
+ int i, err;
struct group_desc *grp = NULL;
struct function_desc *func = NULL;
@@ -172,72 +183,12 @@ static int imx_pmx_set(struct pinctrl_dev *pctldev, unsigned selector,
for (i = 0; i < npins; i++) {
struct imx_pin *pin = &((struct imx_pin *)(grp->data))[i];
-
- pin_id = pin->pin;
- pin_reg = &info->pin_regs[pin_id];
-
- if (pin_reg->mux_reg == -1) {
- dev_dbg(ipctl->dev, "Pin(%s) does not support mux function\n",
- info->pins[pin_id].name);
- continue;
- }
-
- if (info->flags & SHARE_MUX_CONF_REG) {
- u32 reg;
- reg = readl(ipctl->base + pin_reg->mux_reg);
- reg &= ~info->mux_mask;
- reg |= (pin->mux_mode << info->mux_shift);
- writel(reg, ipctl->base + pin_reg->mux_reg);
- dev_dbg(ipctl->dev, "write: offset 0x%x val 0x%x\n",
- pin_reg->mux_reg, reg);
- } else {
- writel(pin->mux_mode, ipctl->base + pin_reg->mux_reg);
- dev_dbg(ipctl->dev, "write: offset 0x%x val 0x%x\n",
- pin_reg->mux_reg, pin->mux_mode);
- }
-
- /*
- * If the select input value begins with 0xff, it's a quirky
- * select input and the value should be interpreted as below.
- * 31 23 15 7 0
- * | 0xff | shift | width | select |
- * It's used to work around the problem that the select
- * input for some pin is not implemented in the select
- * input register but in some general purpose register.
- * We encode the select input value, width and shift of
- * the bit field into input_val cell of pin function ID
- * in device tree, and then decode them here for setting
- * up the select input bits in general purpose register.
- */
- if (pin->input_val >> 24 == 0xff) {
- u32 val = pin->input_val;
- u8 select = val & 0xff;
- u8 width = (val >> 8) & 0xff;
- u8 shift = (val >> 16) & 0xff;
- u32 mask = ((1 << width) - 1) << shift;
- /*
- * The input_reg[i] here is actually some IOMUXC general
- * purpose register, not regular select input register.
- */
- val = readl(ipctl->base + pin->input_reg);
- val &= ~mask;
- val |= select << shift;
- writel(val, ipctl->base + pin->input_reg);
- } else if (pin->input_reg) {
- /*
- * Regular select input register can never be at offset
- * 0, and we only print register value for regular case.
- */
- if (ipctl->input_sel_base)
- writel(pin->input_val, ipctl->input_sel_base +
- pin->input_reg);
- else
- writel(pin->input_val, ipctl->base +
- pin->input_reg);
- dev_dbg(ipctl->dev,
- "==>select_input: offset 0x%x val 0x%x\n",
- pin->input_reg, pin->input_val);
- }
+ if (info->flags & IMX8_USE_SCU)
+ err = imx_pmx_set_one_pin_scu(ipctl, pin);
+ else
+ err = imx_pmx_set_one_pin_mem(ipctl, pin);
+ if (err)
+ return err;
}
return 0;
@@ -310,21 +261,12 @@ static int imx_pinconf_get(struct pinctrl_dev *pctldev,
unsigned pin_id, unsigned long *config)
{
struct imx_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev);
- struct imx_pinctrl_soc_info *info = ipctl->info;
- const struct imx_pin_reg *pin_reg = &info->pin_regs[pin_id];
+ const struct imx_pinctrl_soc_info *info = ipctl->info;
- if (pin_reg->conf_reg == -1) {
- dev_err(info->dev, "Pin(%s) does not support config function\n",
- info->pins[pin_id].name);
- return -EINVAL;
- }
-
- *config = readl(ipctl->base + pin_reg->conf_reg);
-
- if (info->flags & SHARE_MUX_CONF_REG)
- *config &= ~info->mux_mask;
-
- return 0;
+ if (info->flags & IMX8_USE_SCU)
+ return imx_pinconf_backend_get_scu(pctldev, pin_id, config);
+ else
+ return imx_pinconf_backend_get_mem(pctldev, pin_id, config);
}
static int imx_pinconf_set(struct pinctrl_dev *pctldev,
@@ -332,52 +274,32 @@ static int imx_pinconf_set(struct pinctrl_dev *pctldev,
unsigned num_configs)
{
struct imx_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev);
- struct imx_pinctrl_soc_info *info = ipctl->info;
- const struct imx_pin_reg *pin_reg = &info->pin_regs[pin_id];
- int i;
+ const struct imx_pinctrl_soc_info *info = ipctl->info;
- if (pin_reg->conf_reg == -1) {
- dev_err(info->dev, "Pin(%s) does not support config function\n",
- info->pins[pin_id].name);
- return -EINVAL;
- }
-
- dev_dbg(ipctl->dev, "pinconf set pin %s\n",
- info->pins[pin_id].name);
-
- for (i = 0; i < num_configs; i++) {
- if (info->flags & SHARE_MUX_CONF_REG) {
- u32 reg;
- reg = readl(ipctl->base + pin_reg->conf_reg);
- reg &= info->mux_mask;
- reg |= configs[i];
- writel(reg, ipctl->base + pin_reg->conf_reg);
- dev_dbg(ipctl->dev, "write: offset 0x%x val 0x%x\n",
- pin_reg->conf_reg, reg);
- } else {
- writel(configs[i], ipctl->base + pin_reg->conf_reg);
- dev_dbg(ipctl->dev, "write: offset 0x%x val 0x%lx\n",
- pin_reg->conf_reg, configs[i]);
- }
- } /* for each config */
-
- return 0;
+ if (info->flags & IMX8_USE_SCU)
+ return imx_pinconf_backend_set_scu(pctldev, pin_id, configs, num_configs);
+ else
+ return imx_pinconf_backend_set_mem(pctldev, pin_id, configs, num_configs);
}
static void imx_pinconf_dbg_show(struct pinctrl_dev *pctldev,
struct seq_file *s, unsigned pin_id)
{
struct imx_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev);
- struct imx_pinctrl_soc_info *info = ipctl->info;
- const struct imx_pin_reg *pin_reg = &info->pin_regs[pin_id];
+ const struct imx_pinctrl_soc_info *info = ipctl->info;
unsigned long config;
+ int ret;
+
+ if (info->flags & IMX8_USE_SCU)
+ ret = imx_pinconf_backend_get_scu(pctldev, pin_id, &config);
+ else
+ ret = imx_pinconf_backend_get_mem(pctldev, pin_id, &config);
- if (!pin_reg || pin_reg->conf_reg == -1) {
+ if (ret) {
seq_printf(s, "N/A");
return;
}
- config = readl(ipctl->base + pin_reg->conf_reg);
seq_printf(s, "0x%lx", config);
}
@@ -419,6 +341,7 @@ static const struct pinconf_ops imx_pinconf_ops = {
* Each pin represented in fsl,pins consists of 5 u32 PIN_FUNC_ID and
* 1 u32 CONFIG, so 24 types in total for each pin.
*/
+#define FSL_IMX8_PIN_SIZE 12
#define FSL_PIN_SIZE 24
#define SHARE_FSL_PIN_SIZE 20
@@ -429,13 +352,15 @@ static int imx_pinctrl_parse_groups(struct device_node *np,
{
struct imx_pinctrl_soc_info *info = ipctl->info;
int size, pin_size;
- const __be32 *list;
- int i;
+ const __be32 *list, **list_p;
u32 config;
+ int i;
dev_dbg(info->dev, "group(%d): %s\n", index, np->name);
- if (info->flags & SHARE_MUX_CONF_REG)
+ if (info->flags & IMX8_USE_SCU)
+ pin_size = FSL_IMX8_PIN_SIZE;
+ else if (info->flags & SHARE_MUX_CONF_REG)
pin_size = SHARE_FSL_PIN_SIZE;
else
pin_size = FSL_PIN_SIZE;
@@ -466,6 +391,8 @@ static int imx_pinctrl_parse_groups(struct device_node *np,
}
}
+ list_p = &list;
+
/* we do not check return since it's safe node passed down */
if (!size || size % pin_size) {
dev_err(info->dev, "Invalid fsl,pins or pins property in node %pOF\n", np);
@@ -484,48 +411,14 @@ static int imx_pinctrl_parse_groups(struct device_node *np,
return -ENOMEM;
for (i = 0; i < grp->num_pins; i++) {
- u32 mux_reg = be32_to_cpu(*list++);
- u32 conf_reg;
- unsigned int pin_id;
- struct imx_pin_reg *pin_reg;
struct imx_pin *pin = &((struct imx_pin *)(grp->data))[i];
- if (!(info->flags & ZERO_OFFSET_VALID) && !mux_reg)
- mux_reg = -1;
-
- if (info->flags & SHARE_MUX_CONF_REG) {
- conf_reg = mux_reg;
- } else {
- conf_reg = be32_to_cpu(*list++);
- if (!conf_reg)
- conf_reg = -1;
- }
-
- pin_id = (mux_reg != -1) ? mux_reg / 4 : conf_reg / 4;
- pin_reg = &info->pin_regs[pin_id];
- pin->pin = pin_id;
- grp->pins[i] = pin_id;
- pin_reg->mux_reg = mux_reg;
- pin_reg->conf_reg = conf_reg;
- pin->input_reg = be32_to_cpu(*list++);
- pin->mux_mode = be32_to_cpu(*list++);
- pin->input_val = be32_to_cpu(*list++);
-
- if (info->generic_pinconf) {
- /* generic pin config decoded */
- pin->config = config;
- } else {
- /* legacy pin config read from devicetree */
- config = be32_to_cpu(*list++);
-
- /* SION bit is in mux register */
- if (config & IMX_PAD_SION)
- pin->mux_mode |= IOMUXC_CONFIG_SION;
- pin->config = config & ~IMX_PAD_SION;
- }
-
- dev_dbg(info->dev, "%s: 0x%x 0x%08lx", info->pins[pin_id].name,
- pin->mux_mode, pin->config);
+ if (info->flags & IMX8_USE_SCU)
+ imx_pinctrl_parse_pin_scu(info, &grp->pins[i],
+ pin, list_p, config);
+ else
+ imx_pinctrl_parse_pin_mem(info, &grp->pins[i],
+ pin, list_p, config);
}
return 0;
@@ -700,34 +593,36 @@ int imx_pinctrl_probe(struct platform_device *pdev,
if (!ipctl)
return -ENOMEM;
- info->pin_regs = devm_kmalloc(&pdev->dev, sizeof(*info->pin_regs) *
- info->npins, GFP_KERNEL);
- if (!info->pin_regs)
- return -ENOMEM;
+ if (!(info->flags & IMX8_USE_SCU)) {
+ info->pin_regs = devm_kmalloc(&pdev->dev, sizeof(*info->pin_regs) *
+ info->npins, GFP_KERNEL);
+ if (!info->pin_regs)
+ return -ENOMEM;
- for (i = 0; i < info->npins; i++) {
- info->pin_regs[i].mux_reg = -1;
- info->pin_regs[i].conf_reg = -1;
- }
+ for (i = 0; i < info->npins; i++) {
+ info->pin_regs[i].mux_reg = -1;
+ info->pin_regs[i].conf_reg = -1;
+ }
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- ipctl->base = devm_ioremap_resource(&pdev->dev, res);
- if (IS_ERR(ipctl->base))
- return PTR_ERR(ipctl->base);
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ ipctl->base = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(ipctl->base))
+ return PTR_ERR(ipctl->base);
- if (of_property_read_bool(dev_np, "fsl,input-sel")) {
- np = of_parse_phandle(dev_np, "fsl,input-sel", 0);
- if (!np) {
- dev_err(&pdev->dev, "iomuxc fsl,input-sel property not found\n");
- return -EINVAL;
- }
+ if (of_property_read_bool(dev_np, "fsl,input-sel")) {
+ np = of_parse_phandle(dev_np, "fsl,input-sel", 0);
+ if (!np) {
+ dev_err(&pdev->dev, "iomuxc fsl,input-sel property not found\n");
+ return -EINVAL;
+ }
- ipctl->input_sel_base = of_iomap(np, 0);
- of_node_put(np);
- if (!ipctl->input_sel_base) {
- dev_err(&pdev->dev,
- "iomuxc input select base address not found\n");
- return -ENOMEM;
+ ipctl->input_sel_base = of_iomap(np, 0);
+ of_node_put(np);
+ if (!ipctl->input_sel_base) {
+ dev_err(&pdev->dev,
+ "iomuxc input select base address not found\n");
+ return -ENOMEM;
+ }
}
}
@@ -779,3 +674,23 @@ free:
return ret;
}
+
+int imx_pinctrl_suspend(struct device *dev)
+{
+ struct imx_pinctrl *ipctl = dev_get_drvdata(dev);
+
+ if (!ipctl)
+ return -EINVAL;
+
+ return pinctrl_force_sleep(ipctl->pctl);
+}
+
+int imx_pinctrl_resume(struct device *dev)
+{
+ struct imx_pinctrl *ipctl = dev_get_drvdata(dev);
+
+ if (!ipctl)
+ return -EINVAL;
+
+ return pinctrl_force_default(ipctl->pctl);
+}
diff --git a/drivers/pinctrl/freescale/pinctrl-imx.h b/drivers/pinctrl/freescale/pinctrl-imx.h
index 5aa22b52c1d4..aea94337609d 100644
--- a/drivers/pinctrl/freescale/pinctrl-imx.h
+++ b/drivers/pinctrl/freescale/pinctrl-imx.h
@@ -3,6 +3,7 @@
*
* Copyright (C) 2012 Freescale Semiconductor, Inc.
* Copyright (C) 2012 Linaro Ltd.
+ * Copyright 2017 NXP
*
* Author: Dong Aisheng <dong.aisheng@linaro.org>
*
@@ -31,14 +32,26 @@ extern struct pinmux_ops imx_pmx_ops;
* @input_val: the select input value for this pin.
* @configs: the config for this pin.
*/
-struct imx_pin {
- unsigned int pin;
+struct imx_pin_memmap {
unsigned int mux_mode;
u16 input_reg;
unsigned int input_val;
unsigned long config;
};
+struct imx_pin_scu {
+ unsigned long mux;
+ unsigned long config;
+};
+
+struct imx_pin {
+ unsigned int pin;
+ union {
+ struct imx_pin_memmap pin_memmap;
+ struct imx_pin_scu pin_scu;
+ } pin_conf;
+};
+
/**
* struct imx_pin_reg - describe a pin reg map
* @mux_reg: mux register offset
@@ -70,6 +83,8 @@ struct imx_pinctrl_soc_info {
/* MUX_MODE shift and mask in case SHARE_MUX_CONF_REG */
unsigned int mux_mask;
u8 mux_shift;
+ u32 ibe_bit;
+ u32 obe_bit;
/* generic pinconf */
bool generic_pinconf;
@@ -106,6 +121,12 @@ struct imx_pinctrl {
#define SHARE_MUX_CONF_REG 0x1
#define ZERO_OFFSET_VALID 0x2
+#define IMX8_ENABLE_MUX_CONFIG (1 << 29)
+#define IMX8_ENABLE_PAD_CONFIG (1 << 30)
+#define IMX8_USE_SCU (1 << 31)
+
+#define BM_IMX8_GP_ENABLE (1 << 30)
+#define BM_IMX8_IFMUX_ENABLE (1 << 31)
#define NO_MUX 0x0
#define NO_PAD 0x0
@@ -118,4 +139,71 @@ struct imx_pinctrl {
int imx_pinctrl_probe(struct platform_device *pdev,
struct imx_pinctrl_soc_info *info);
+int imx_pinctrl_suspend(struct device *dev);
+int imx_pinctrl_resume(struct device *dev);
+
+#ifdef CONFIG_PINCTRL_IMX_MEMMAP
+int imx_pmx_set_one_pin_mem(struct imx_pinctrl *ipctl, struct imx_pin *pin);
+int imx_pinconf_backend_get_mem(struct pinctrl_dev *pctldev, unsigned pin_id,
+ unsigned long *config);
+int imx_pinconf_backend_set_mem(struct pinctrl_dev *pctldev, unsigned pin_id,
+ unsigned long *configs, unsigned num_configs);
+int imx_pinctrl_parse_pin_mem(struct imx_pinctrl_soc_info *info,
+ unsigned int *pin_id, struct imx_pin *pin, const __be32 **list_p,
+ u32 generic_config);
+#else
+static inline int imx_pmx_set_one_pin_mem(struct imx_pinctrl *ipctl, struct imx_pin *pin)
+{
+ return 0;
+}
+static inline int imx_pinconf_backend_get_mem(struct pinctrl_dev *pctldev, unsigned pin_id,
+ unsigned long *config)
+{
+ return 0;
+}
+static inline int imx_pinconf_backend_set_mem(struct pinctrl_dev *pctldev, unsigned pin_id,
+ unsigned long *configs, unsigned num_configs)
+{
+ return 0;
+}
+static inline int imx_pinctrl_parse_pin_mem(struct imx_pinctrl_soc_info *info,
+ unsigned int *pin_id, struct imx_pin *pin, const __be32 **list_p,
+ u32 generic_config)
+{
+ return 0;
+}
+#endif
+
+#ifdef CONFIG_PINCTRL_IMX_SCU
+int imx_pmx_set_one_pin_scu(struct imx_pinctrl *ipctl, struct imx_pin *pin);
+int imx_pinconf_backend_get_scu(struct pinctrl_dev *pctldev, unsigned pin_id,
+ unsigned long *config);
+int imx_pinconf_backend_set_scu(struct pinctrl_dev *pctldev, unsigned pin_id,
+ unsigned long *configs, unsigned num_configs);
+int imx_pinctrl_parse_pin_scu(struct imx_pinctrl_soc_info *info,
+ unsigned int *pin_id, struct imx_pin *pin, const __be32 **list_p,
+ u32 generic_config);
+#else
+static inline int imx_pmx_set_one_pin_scu(struct imx_pinctrl *ipctl, struct imx_pin *pin)
+{
+ return 0;
+}
+static inline int imx_pinconf_backend_get_scu(struct pinctrl_dev *pctldev, unsigned pin_id,
+ unsigned long *config)
+{
+ return 0;
+}
+static inline int imx_pinconf_backend_set_scu(struct pinctrl_dev *pctldev, unsigned pin_id,
+ unsigned long *configs, unsigned num_configs)
+{
+ return 0;
+}
+static inline int imx_pinctrl_parse_pin_scu(struct imx_pinctrl_soc_info *info,
+ unsigned int *pin_id, struct imx_pin *pin, const __be32 **list_p,
+ u32 generic_config)
+{
+ return 0;
+}
+#endif
+
#endif /* __DRIVERS_PINCTRL_IMX_H */
diff --git a/drivers/pinctrl/freescale/pinctrl-imx6sll.c b/drivers/pinctrl/freescale/pinctrl-imx6sll.c
new file mode 100644
index 000000000000..371fb143e039
--- /dev/null
+++ b/drivers/pinctrl/freescale/pinctrl-imx6sll.c
@@ -0,0 +1,388 @@
+/*
+ * Copyright (C) 2016 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/err.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/pinctrl/pinctrl.h>
+
+#include "pinctrl-imx.h"
+
+enum imx6sll_pads {
+ MX6SLL_PAD_RESERVE0 = 0,
+ MX6SLL_PAD_RESERVE1 = 1,
+ MX6SLL_PAD_RESERVE2 = 2,
+ MX6SLL_PAD_RESERVE3 = 3,
+ MX6SLL_PAD_RESERVE4 = 4,
+ MX6SLL_PAD_WDOG_B = 5,
+ MX6SLL_PAD_REF_CLK_24M = 6,
+ MX6SLL_PAD_REF_CLK_32K = 7,
+ MX6SLL_PAD_PWM1 = 8,
+ MX6SLL_PAD_KEY_COL0 = 9,
+ MX6SLL_PAD_KEY_ROW0 = 10,
+ MX6SLL_PAD_KEY_COL1 = 11,
+ MX6SLL_PAD_KEY_ROW1 = 12,
+ MX6SLL_PAD_KEY_COL2 = 13,
+ MX6SLL_PAD_KEY_ROW2 = 14,
+ MX6SLL_PAD_KEY_COL3 = 15,
+ MX6SLL_PAD_KEY_ROW3 = 16,
+ MX6SLL_PAD_KEY_COL4 = 17,
+ MX6SLL_PAD_KEY_ROW4 = 18,
+ MX6SLL_PAD_KEY_COL5 = 19,
+ MX6SLL_PAD_KEY_ROW5 = 20,
+ MX6SLL_PAD_KEY_COL6 = 21,
+ MX6SLL_PAD_KEY_ROW6 = 22,
+ MX6SLL_PAD_KEY_COL7 = 23,
+ MX6SLL_PAD_KEY_ROW7 = 24,
+ MX6SLL_PAD_EPDC_DATA00 = 25,
+ MX6SLL_PAD_EPDC_DATA01 = 26,
+ MX6SLL_PAD_EPDC_DATA02 = 27,
+ MX6SLL_PAD_EPDC_DATA03 = 28,
+ MX6SLL_PAD_EPDC_DATA04 = 29,
+ MX6SLL_PAD_EPDC_DATA05 = 30,
+ MX6SLL_PAD_EPDC_DATA06 = 31,
+ MX6SLL_PAD_EPDC_DATA07 = 32,
+ MX6SLL_PAD_EPDC_DATA08 = 33,
+ MX6SLL_PAD_EPDC_DATA09 = 34,
+ MX6SLL_PAD_EPDC_DATA10 = 35,
+ MX6SLL_PAD_EPDC_DATA11 = 36,
+ MX6SLL_PAD_EPDC_DATA12 = 37,
+ MX6SLL_PAD_EPDC_DATA13 = 38,
+ MX6SLL_PAD_EPDC_DATA14 = 39,
+ MX6SLL_PAD_EPDC_DATA15 = 40,
+ MX6SLL_PAD_EPDC_SDCLK = 41,
+ MX6SLL_PAD_EPDC_SDLE = 42,
+ MX6SLL_PAD_EPDC_SDOE = 43,
+ MX6SLL_PAD_EPDC_SDSHR = 44,
+ MX6SLL_PAD_EPDC_SDCE0 = 45,
+ MX6SLL_PAD_EPDC_SDCE1 = 46,
+ MX6SLL_PAD_EPDC_SDCE2 = 47,
+ MX6SLL_PAD_EPDC_SDCE3 = 48,
+ MX6SLL_PAD_EPDC_GDCLK = 49,
+ MX6SLL_PAD_EPDC_GDOE = 50,
+ MX6SLL_PAD_EPDC_GDRL = 51,
+ MX6SLL_PAD_EPDC_GDSP = 52,
+ MX6SLL_PAD_EPDC_VCOM0 = 53,
+ MX6SLL_PAD_EPDC_VCOM1 = 54,
+ MX6SLL_PAD_EPDC_BDR0 = 55,
+ MX6SLL_PAD_EPDC_BDR1 = 56,
+ MX6SLL_PAD_EPDC_PWR_CTRL0 = 57,
+ MX6SLL_PAD_EPDC_PWR_CTRL1 = 58,
+ MX6SLL_PAD_EPDC_PWR_CTRL2 = 59,
+ MX6SLL_PAD_EPDC_PWR_CTRL3 = 60,
+ MX6SLL_PAD_EPDC_PWR_COM = 61,
+ MX6SLL_PAD_EPDC_PWR_INT = 62,
+ MX6SLL_PAD_EPDC_PWR_STAT = 63,
+ MX6SLL_PAD_EPDC_PWR_WAKE = 64,
+ MX6SLL_PAD_LCD_CLK = 65,
+ MX6SLL_PAD_LCD_ENABLE = 66,
+ MX6SLL_PAD_LCD_HSYNC = 67,
+ MX6SLL_PAD_LCD_VSYNC = 68,
+ MX6SLL_PAD_LCD_RESET = 69,
+ MX6SLL_PAD_LCD_DATA00 = 70,
+ MX6SLL_PAD_LCD_DATA01 = 71,
+ MX6SLL_PAD_LCD_DATA02 = 72,
+ MX6SLL_PAD_LCD_DATA03 = 73,
+ MX6SLL_PAD_LCD_DATA04 = 74,
+ MX6SLL_PAD_LCD_DATA05 = 75,
+ MX6SLL_PAD_LCD_DATA06 = 76,
+ MX6SLL_PAD_LCD_DATA07 = 77,
+ MX6SLL_PAD_LCD_DATA08 = 78,
+ MX6SLL_PAD_LCD_DATA09 = 79,
+ MX6SLL_PAD_LCD_DATA10 = 80,
+ MX6SLL_PAD_LCD_DATA11 = 81,
+ MX6SLL_PAD_LCD_DATA12 = 82,
+ MX6SLL_PAD_LCD_DATA13 = 83,
+ MX6SLL_PAD_LCD_DATA14 = 84,
+ MX6SLL_PAD_LCD_DATA15 = 85,
+ MX6SLL_PAD_LCD_DATA16 = 86,
+ MX6SLL_PAD_LCD_DATA17 = 87,
+ MX6SLL_PAD_LCD_DATA18 = 88,
+ MX6SLL_PAD_LCD_DATA19 = 89,
+ MX6SLL_PAD_LCD_DATA20 = 90,
+ MX6SLL_PAD_LCD_DATA21 = 91,
+ MX6SLL_PAD_LCD_DATA22 = 92,
+ MX6SLL_PAD_LCD_DATA23 = 93,
+ MX6SLL_PAD_AUD_RXFS = 94,
+ MX6SLL_PAD_AUD_RXC = 95,
+ MX6SLL_PAD_AUD_RXD = 96,
+ MX6SLL_PAD_AUD_TXC = 97,
+ MX6SLL_PAD_AUD_TXFS = 98,
+ MX6SLL_PAD_AUD_TXD = 99,
+ MX6SLL_PAD_AUD_MCLK = 100,
+ MX6SLL_PAD_UART1_RXD = 101,
+ MX6SLL_PAD_UART1_TXD = 102,
+ MX6SLL_PAD_I2C1_SCL = 103,
+ MX6SLL_PAD_I2C1_SDA = 104,
+ MX6SLL_PAD_I2C2_SCL = 105,
+ MX6SLL_PAD_I2C2_SDA = 106,
+ MX6SLL_PAD_ECSPI1_SCLK = 107,
+ MX6SLL_PAD_ECSPI1_MOSI = 108,
+ MX6SLL_PAD_ECSPI1_MISO = 109,
+ MX6SLL_PAD_ECSPI1_SS0 = 110,
+ MX6SLL_PAD_ECSPI2_SCLK = 111,
+ MX6SLL_PAD_ECSPI2_MOSI = 112,
+ MX6SLL_PAD_ECSPI2_MISO = 113,
+ MX6SLL_PAD_ECSPI2_SS0 = 114,
+ MX6SLL_PAD_SD1_CLK = 115,
+ MX6SLL_PAD_SD1_CMD = 116,
+ MX6SLL_PAD_SD1_DATA0 = 117,
+ MX6SLL_PAD_SD1_DATA1 = 118,
+ MX6SLL_PAD_SD1_DATA2 = 119,
+ MX6SLL_PAD_SD1_DATA3 = 120,
+ MX6SLL_PAD_SD1_DATA4 = 121,
+ MX6SLL_PAD_SD1_DATA5 = 122,
+ MX6SLL_PAD_SD1_DATA6 = 123,
+ MX6SLL_PAD_SD1_DATA7 = 124,
+ MX6SLL_PAD_SD2_RESET = 125,
+ MX6SLL_PAD_SD2_CLK = 126,
+ MX6SLL_PAD_SD2_CMD = 127,
+ MX6SLL_PAD_SD2_DATA0 = 128,
+ MX6SLL_PAD_SD2_DATA1 = 129,
+ MX6SLL_PAD_SD2_DATA2 = 130,
+ MX6SLL_PAD_SD2_DATA3 = 131,
+ MX6SLL_PAD_SD2_DATA4 = 132,
+ MX6SLL_PAD_SD2_DATA5 = 133,
+ MX6SLL_PAD_SD2_DATA6 = 134,
+ MX6SLL_PAD_SD2_DATA7 = 135,
+ MX6SLL_PAD_SD3_CLK = 136,
+ MX6SLL_PAD_SD3_CMD = 137,
+ MX6SLL_PAD_SD3_DATA0 = 138,
+ MX6SLL_PAD_SD3_DATA1 = 139,
+ MX6SLL_PAD_SD3_DATA2 = 140,
+ MX6SLL_PAD_SD3_DATA3 = 141,
+ MX6SLL_PAD_GPIO4_IO20 = 142,
+ MX6SLL_PAD_GPIO4_IO21 = 143,
+ MX6SLL_PAD_GPIO4_IO19 = 144,
+ MX6SLL_PAD_GPIO4_IO25 = 145,
+ MX6SLL_PAD_GPIO4_IO18 = 146,
+ MX6SLL_PAD_GPIO4_IO24 = 147,
+ MX6SLL_PAD_GPIO4_IO23 = 148,
+ MX6SLL_PAD_GPIO4_IO17 = 149,
+ MX6SLL_PAD_GPIO4_IO22 = 150,
+ MX6SLL_PAD_GPIO4_IO16 = 151,
+ MX6SLL_PAD_GPIO4_IO26 = 152,
+};
+
+enum imx6sll_lpsr_pads {
+ MX6SLL_PAD_SNVS_TAMPER = 0,
+ MX6SLL_PAD_SNVS_PMIC_ON_REQ = 1,
+ MX6SLL_PAD_SNVS_PMIC_STBY_REQ = 2,
+ MX6SLL_PAD_SNVS_BOOT_MODE0 = 3,
+ MX6SLL_PAD_SNVS_BOOT_MODE1 = 4,
+};
+
+/* Pad names for the pinmux subsystem */
+static const struct pinctrl_pin_desc imx6sll_pinctrl_pads[] = {
+ IMX_PINCTRL_PIN(MX6SLL_PAD_RESERVE0),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_RESERVE1),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_RESERVE2),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_RESERVE3),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_RESERVE4),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_WDOG_B),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_REF_CLK_24M),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_REF_CLK_32K),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_PWM1),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_KEY_COL0),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_KEY_ROW0),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_KEY_COL1),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_KEY_ROW1),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_KEY_COL2),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_KEY_ROW2),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_KEY_COL3),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_KEY_ROW3),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_KEY_COL4),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_KEY_ROW4),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_KEY_COL5),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_KEY_ROW5),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_KEY_COL6),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_KEY_ROW6),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_KEY_COL7),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_KEY_ROW7),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_EPDC_DATA00),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_EPDC_DATA01),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_EPDC_DATA02),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_EPDC_DATA03),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_EPDC_DATA04),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_EPDC_DATA05),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_EPDC_DATA06),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_EPDC_DATA07),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_EPDC_DATA08),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_EPDC_DATA09),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_EPDC_DATA10),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_EPDC_DATA11),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_EPDC_DATA12),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_EPDC_DATA13),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_EPDC_DATA14),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_EPDC_DATA15),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_EPDC_SDCLK),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_EPDC_SDLE),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_EPDC_SDOE),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_EPDC_SDSHR),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_EPDC_SDCE0),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_EPDC_SDCE1),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_EPDC_SDCE2),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_EPDC_SDCE3),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_EPDC_GDCLK),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_EPDC_GDOE),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_EPDC_GDRL),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_EPDC_GDSP),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_EPDC_VCOM0),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_EPDC_VCOM1),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_EPDC_BDR0),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_EPDC_BDR1),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_EPDC_PWR_CTRL0),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_EPDC_PWR_CTRL1),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_EPDC_PWR_CTRL2),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_EPDC_PWR_CTRL3),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_EPDC_PWR_COM),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_EPDC_PWR_INT),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_EPDC_PWR_STAT),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_EPDC_PWR_WAKE),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_LCD_CLK),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_LCD_ENABLE),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_LCD_HSYNC),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_LCD_VSYNC),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_LCD_RESET),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_LCD_DATA00),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_LCD_DATA01),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_LCD_DATA02),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_LCD_DATA03),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_LCD_DATA04),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_LCD_DATA05),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_LCD_DATA06),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_LCD_DATA07),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_LCD_DATA08),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_LCD_DATA09),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_LCD_DATA10),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_LCD_DATA11),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_LCD_DATA12),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_LCD_DATA13),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_LCD_DATA14),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_LCD_DATA15),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_LCD_DATA16),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_LCD_DATA17),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_LCD_DATA18),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_LCD_DATA19),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_LCD_DATA20),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_LCD_DATA21),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_LCD_DATA22),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_LCD_DATA23),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_AUD_RXFS),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_AUD_RXC),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_AUD_RXD),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_AUD_TXC),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_AUD_TXFS),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_AUD_TXD),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_AUD_MCLK),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_UART1_RXD),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_UART1_TXD),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_I2C1_SCL),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_I2C1_SDA),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_I2C2_SCL),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_I2C2_SDA),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_ECSPI1_SCLK),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_ECSPI1_MOSI),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_ECSPI1_MISO),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_ECSPI1_SS0),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_ECSPI2_SCLK),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_ECSPI2_MOSI),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_ECSPI2_MISO),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_ECSPI2_SS0),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_SD1_CLK),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_SD1_CMD),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_SD1_DATA0),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_SD1_DATA1),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_SD1_DATA2),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_SD1_DATA3),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_SD1_DATA4),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_SD1_DATA5),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_SD1_DATA6),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_SD1_DATA7),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_SD2_RESET),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_SD2_CLK),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_SD2_CMD),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_SD2_DATA0),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_SD2_DATA1),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_SD2_DATA2),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_SD2_DATA3),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_SD2_DATA4),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_SD2_DATA5),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_SD2_DATA6),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_SD2_DATA7),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_SD3_CLK),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_SD3_CMD),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_SD3_DATA0),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_SD3_DATA1),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_SD3_DATA2),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_SD3_DATA3),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_GPIO4_IO20),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_GPIO4_IO21),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_GPIO4_IO19),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_GPIO4_IO25),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_GPIO4_IO18),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_GPIO4_IO24),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_GPIO4_IO23),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_GPIO4_IO17),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_GPIO4_IO22),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_GPIO4_IO16),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_GPIO4_IO26),
+};
+
+static struct imx_pinctrl_soc_info imx6sll_pinctrl_info = {
+ .pins = imx6sll_pinctrl_pads,
+ .npins = ARRAY_SIZE(imx6sll_pinctrl_pads),
+};
+
+static struct of_device_id imx6sll_pinctrl_of_match[] = {
+ { .compatible = "fsl,imx6sll-iomuxc", .data = &imx6sll_pinctrl_info, },
+ { /* sentinel */ }
+};
+
+static int imx6sll_pinctrl_probe(struct platform_device *pdev)
+{
+ const struct of_device_id *match;
+ struct imx_pinctrl_soc_info *pinctrl_info;
+
+ match = of_match_device(imx6sll_pinctrl_of_match, &pdev->dev);
+
+ if (!match)
+ return -ENODEV;
+
+ pinctrl_info = (struct imx_pinctrl_soc_info *) match->data;
+
+ return imx_pinctrl_probe(pdev, pinctrl_info);
+}
+
+static struct platform_driver imx6sll_pinctrl_driver = {
+ .driver = {
+ .name = "imx6sll-pinctrl",
+ .owner = THIS_MODULE,
+ .of_match_table = of_match_ptr(imx6sll_pinctrl_of_match),
+ },
+ .probe = imx6sll_pinctrl_probe,
+};
+
+static int __init imx6sll_pinctrl_init(void)
+{
+ return platform_driver_register(&imx6sll_pinctrl_driver);
+}
+arch_initcall(imx6sll_pinctrl_init);
+
+static void __exit imx6sll_pinctrl_exit(void)
+{
+ platform_driver_unregister(&imx6sll_pinctrl_driver);
+}
+module_exit(imx6sll_pinctrl_exit);
+
+MODULE_AUTHOR("Bai Ping <ping.bai@nxp.com>");
+MODULE_DESCRIPTION("Freescale imx6sll pinctrl driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/pinctrl/freescale/pinctrl-imx6ul.c b/drivers/pinctrl/freescale/pinctrl-imx6ul.c
index 1aeb840aae1d..cbad1c69226d 100644
--- a/drivers/pinctrl/freescale/pinctrl-imx6ul.c
+++ b/drivers/pinctrl/freescale/pinctrl-imx6ul.c
@@ -150,6 +150,21 @@ enum imx6ul_pads {
MX6UL_PAD_CSI_DATA07 = 128,
};
+enum imx6ull_lpsr_pads {
+ MX6ULL_PAD_BOOT_MODE0 = 0,
+ MX6ULL_PAD_BOOT_MODE1 = 1,
+ MX6ULL_PAD_SNVS_TAMPER0 = 2,
+ MX6ULL_PAD_SNVS_TAMPER1 = 3,
+ MX6ULL_PAD_SNVS_TAMPER2 = 4,
+ MX6ULL_PAD_SNVS_TAMPER3 = 5,
+ MX6ULL_PAD_SNVS_TAMPER4 = 6,
+ MX6ULL_PAD_SNVS_TAMPER5 = 7,
+ MX6ULL_PAD_SNVS_TAMPER6 = 8,
+ MX6ULL_PAD_SNVS_TAMPER7 = 9,
+ MX6ULL_PAD_SNVS_TAMPER8 = 10,
+ MX6ULL_PAD_SNVS_TAMPER9 = 11,
+};
+
/* Pad names for the pinmux subsystem */
static const struct pinctrl_pin_desc imx6ul_pinctrl_pads[] = {
IMX_PINCTRL_PIN(MX6UL_PAD_RESERVE0),
@@ -283,20 +298,53 @@ static const struct pinctrl_pin_desc imx6ul_pinctrl_pads[] = {
IMX_PINCTRL_PIN(MX6UL_PAD_CSI_DATA07),
};
+/* pad for i.MX6ULL lpsr pinmux */
+static struct pinctrl_pin_desc imx6ull_snvs_pinctrl_pads[] = {
+ IMX_PINCTRL_PIN(MX6ULL_PAD_BOOT_MODE0),
+ IMX_PINCTRL_PIN(MX6ULL_PAD_BOOT_MODE1),
+ IMX_PINCTRL_PIN(MX6ULL_PAD_SNVS_TAMPER0),
+ IMX_PINCTRL_PIN(MX6ULL_PAD_SNVS_TAMPER1),
+ IMX_PINCTRL_PIN(MX6ULL_PAD_SNVS_TAMPER2),
+ IMX_PINCTRL_PIN(MX6ULL_PAD_SNVS_TAMPER3),
+ IMX_PINCTRL_PIN(MX6ULL_PAD_SNVS_TAMPER4),
+ IMX_PINCTRL_PIN(MX6ULL_PAD_SNVS_TAMPER5),
+ IMX_PINCTRL_PIN(MX6ULL_PAD_SNVS_TAMPER6),
+ IMX_PINCTRL_PIN(MX6ULL_PAD_SNVS_TAMPER7),
+ IMX_PINCTRL_PIN(MX6ULL_PAD_SNVS_TAMPER8),
+ IMX_PINCTRL_PIN(MX6ULL_PAD_SNVS_TAMPER9),
+};
+
static struct imx_pinctrl_soc_info imx6ul_pinctrl_info = {
.pins = imx6ul_pinctrl_pads,
.npins = ARRAY_SIZE(imx6ul_pinctrl_pads),
.gpr_compatible = "fsl,imx6ul-iomuxc-gpr",
};
+static struct imx_pinctrl_soc_info imx6ull_snvs_pinctrl_info = {
+ .pins = imx6ull_snvs_pinctrl_pads,
+ .npins = ARRAY_SIZE(imx6ull_snvs_pinctrl_pads),
+ .flags = ZERO_OFFSET_VALID,
+};
+
static struct of_device_id imx6ul_pinctrl_of_match[] = {
- { .compatible = "fsl,imx6ul-iomuxc", },
+ { .compatible = "fsl,imx6ul-iomuxc", .data = &imx6ul_pinctrl_info, },
+ { .compatible = "fsl,imx6ull-iomuxc-snvs", .data = &imx6ull_snvs_pinctrl_info, },
{ /* sentinel */ }
};
static int imx6ul_pinctrl_probe(struct platform_device *pdev)
{
- return imx_pinctrl_probe(pdev, &imx6ul_pinctrl_info);
+ const struct of_device_id *match;
+ struct imx_pinctrl_soc_info *pinctrl_info;
+
+ match = of_match_device(imx6ul_pinctrl_of_match, &pdev->dev);
+
+ if (!match)
+ return -ENODEV;
+
+ pinctrl_info = (struct imx_pinctrl_soc_info *) match->data;
+
+ return imx_pinctrl_probe(pdev, pinctrl_info);
}
static struct platform_driver imx6ul_pinctrl_driver = {
diff --git a/drivers/pinctrl/freescale/pinctrl-imx7d.c b/drivers/pinctrl/freescale/pinctrl-imx7d.c
index 754159ee7b1e..7709c6ae6347 100644
--- a/drivers/pinctrl/freescale/pinctrl-imx7d.c
+++ b/drivers/pinctrl/freescale/pinctrl-imx7d.c
@@ -391,10 +391,27 @@ static int imx7d_pinctrl_probe(struct platform_device *pdev)
return imx_pinctrl_probe(pdev, pinctrl_info);
}
+static int imx7d_pinctrl_suspend(struct device *dev)
+{
+
+ return imx_pinctrl_suspend(dev);
+}
+
+static int imx7d_pinctrl_resume(struct device *dev)
+{
+
+ return imx_pinctrl_resume(dev);
+}
+
+static const struct dev_pm_ops imx7d_pinctrl_pm_ops = {
+ SET_LATE_SYSTEM_SLEEP_PM_OPS(imx7d_pinctrl_suspend, imx7d_pinctrl_resume)
+};
+
static struct platform_driver imx7d_pinctrl_driver = {
.driver = {
.name = "imx7d-pinctrl",
.of_match_table = of_match_ptr(imx7d_pinctrl_of_match),
+ .pm = &imx7d_pinctrl_pm_ops,
},
.probe = imx7d_pinctrl_probe,
};
diff --git a/drivers/pinctrl/freescale/pinctrl-imx7ulp.c b/drivers/pinctrl/freescale/pinctrl-imx7ulp.c
index b7bebb292f37..d29235c3ac07 100644
--- a/drivers/pinctrl/freescale/pinctrl-imx7ulp.c
+++ b/drivers/pinctrl/freescale/pinctrl-imx7ulp.c
@@ -21,6 +21,58 @@
#include "pinctrl-imx.h"
enum imx7ulp_pads {
+ IMX7ULP_PAD_PTA0 = 0,
+ IMX7ULP_PAD_PTA1,
+ IMX7ULP_PAD_PTA2,
+ IMX7ULP_PAD_PTA3,
+ IMX7ULP_PAD_PTA4,
+ IMX7ULP_PAD_PTA5,
+ IMX7ULP_PAD_PTA6,
+ IMX7ULP_PAD_PTA7,
+ IMX7ULP_PAD_PTA8,
+ IMX7ULP_PAD_PTA9,
+ IMX7ULP_PAD_PTA10,
+ IMX7ULP_PAD_PTA11,
+ IMX7ULP_PAD_PTA12,
+ IMX7ULP_PAD_PTA13,
+ IMX7ULP_PAD_PTA14,
+ IMX7ULP_PAD_PTA15,
+ IMX7ULP_PAD_PTA16,
+ IMX7ULP_PAD_PTA17,
+ IMX7ULP_PAD_PTA18,
+ IMX7ULP_PAD_PTA19,
+ IMX7ULP_PAD_PTA20,
+ IMX7ULP_PAD_PTA21,
+ IMX7ULP_PAD_PTA22,
+ IMX7ULP_PAD_PTA23,
+ IMX7ULP_PAD_PTA24,
+ IMX7ULP_PAD_PTA25,
+ IMX7ULP_PAD_PTA26,
+ IMX7ULP_PAD_PTA27,
+ IMX7ULP_PAD_PTA28,
+ IMX7ULP_PAD_PTA29,
+ IMX7ULP_PAD_PTA30,
+ IMX7ULP_PAD_PTA31,
+ IMX7ULP_PAD_PTB0,
+ IMX7ULP_PAD_PTB1,
+ IMX7ULP_PAD_PTB2,
+ IMX7ULP_PAD_PTB3,
+ IMX7ULP_PAD_PTB4,
+ IMX7ULP_PAD_PTB5,
+ IMX7ULP_PAD_PTB6,
+ IMX7ULP_PAD_PTB7,
+ IMX7ULP_PAD_PTB8,
+ IMX7ULP_PAD_PTB9,
+ IMX7ULP_PAD_PTB10,
+ IMX7ULP_PAD_PTB11,
+ IMX7ULP_PAD_PTB12,
+ IMX7ULP_PAD_PTB13,
+ IMX7ULP_PAD_PTB14,
+ IMX7ULP_PAD_PTB15,
+ IMX7ULP_PAD_PTB16,
+ IMX7ULP_PAD_PTB17,
+ IMX7ULP_PAD_PTB18,
+ IMX7ULP_PAD_PTB19 = 51,
IMX7ULP_PAD_PTC0 = 0,
IMX7ULP_PAD_PTC1,
IMX7ULP_PAD_PTC2,
@@ -140,7 +192,63 @@ enum imx7ulp_pads {
};
/* Pad names for the pinmux subsystem */
-static const struct pinctrl_pin_desc imx7ulp_pinctrl_pads[] = {
+static const struct pinctrl_pin_desc imx7ulp_pinctrl_pads_0[] = {
+ IMX_PINCTRL_PIN(IMX7ULP_PAD_PTA0),
+ IMX_PINCTRL_PIN(IMX7ULP_PAD_PTA1),
+ IMX_PINCTRL_PIN(IMX7ULP_PAD_PTA2),
+ IMX_PINCTRL_PIN(IMX7ULP_PAD_PTA3),
+ IMX_PINCTRL_PIN(IMX7ULP_PAD_PTA4),
+ IMX_PINCTRL_PIN(IMX7ULP_PAD_PTA5),
+ IMX_PINCTRL_PIN(IMX7ULP_PAD_PTA6),
+ IMX_PINCTRL_PIN(IMX7ULP_PAD_PTA7),
+ IMX_PINCTRL_PIN(IMX7ULP_PAD_PTA8),
+ IMX_PINCTRL_PIN(IMX7ULP_PAD_PTA9),
+ IMX_PINCTRL_PIN(IMX7ULP_PAD_PTA10),
+ IMX_PINCTRL_PIN(IMX7ULP_PAD_PTA11),
+ IMX_PINCTRL_PIN(IMX7ULP_PAD_PTA12),
+ IMX_PINCTRL_PIN(IMX7ULP_PAD_PTA13),
+ IMX_PINCTRL_PIN(IMX7ULP_PAD_PTA14),
+ IMX_PINCTRL_PIN(IMX7ULP_PAD_PTA15),
+ IMX_PINCTRL_PIN(IMX7ULP_PAD_PTA16),
+ IMX_PINCTRL_PIN(IMX7ULP_PAD_PTA17),
+ IMX_PINCTRL_PIN(IMX7ULP_PAD_PTA18),
+ IMX_PINCTRL_PIN(IMX7ULP_PAD_PTA19),
+ IMX_PINCTRL_PIN(IMX7ULP_PAD_PTA20),
+ IMX_PINCTRL_PIN(IMX7ULP_PAD_PTA21),
+ IMX_PINCTRL_PIN(IMX7ULP_PAD_PTA22),
+ IMX_PINCTRL_PIN(IMX7ULP_PAD_PTA23),
+ IMX_PINCTRL_PIN(IMX7ULP_PAD_PTA24),
+ IMX_PINCTRL_PIN(IMX7ULP_PAD_PTA25),
+ IMX_PINCTRL_PIN(IMX7ULP_PAD_PTA26),
+ IMX_PINCTRL_PIN(IMX7ULP_PAD_PTA27),
+ IMX_PINCTRL_PIN(IMX7ULP_PAD_PTA28),
+ IMX_PINCTRL_PIN(IMX7ULP_PAD_PTA29),
+ IMX_PINCTRL_PIN(IMX7ULP_PAD_PTA30),
+ IMX_PINCTRL_PIN(IMX7ULP_PAD_PTA31),
+ IMX_PINCTRL_PIN(IMX7ULP_PAD_PTB0),
+ IMX_PINCTRL_PIN(IMX7ULP_PAD_PTB1),
+ IMX_PINCTRL_PIN(IMX7ULP_PAD_PTB2),
+ IMX_PINCTRL_PIN(IMX7ULP_PAD_PTB3),
+ IMX_PINCTRL_PIN(IMX7ULP_PAD_PTB4),
+ IMX_PINCTRL_PIN(IMX7ULP_PAD_PTB5),
+ IMX_PINCTRL_PIN(IMX7ULP_PAD_PTB6),
+ IMX_PINCTRL_PIN(IMX7ULP_PAD_PTB7),
+ IMX_PINCTRL_PIN(IMX7ULP_PAD_PTB8),
+ IMX_PINCTRL_PIN(IMX7ULP_PAD_PTB9),
+ IMX_PINCTRL_PIN(IMX7ULP_PAD_PTB10),
+ IMX_PINCTRL_PIN(IMX7ULP_PAD_PTB11),
+ IMX_PINCTRL_PIN(IMX7ULP_PAD_PTB12),
+ IMX_PINCTRL_PIN(IMX7ULP_PAD_PTB13),
+ IMX_PINCTRL_PIN(IMX7ULP_PAD_PTB14),
+ IMX_PINCTRL_PIN(IMX7ULP_PAD_PTB15),
+ IMX_PINCTRL_PIN(IMX7ULP_PAD_PTB16),
+ IMX_PINCTRL_PIN(IMX7ULP_PAD_PTB17),
+ IMX_PINCTRL_PIN(IMX7ULP_PAD_PTB18),
+ IMX_PINCTRL_PIN(IMX7ULP_PAD_PTB19),
+};
+
+/* Pad names for the pinmux subsystem */
+static const struct pinctrl_pin_desc imx7ulp_pinctrl_pads_1[] = {
IMX_PINCTRL_PIN(IMX7ULP_PAD_PTC0),
IMX_PINCTRL_PIN(IMX7ULP_PAD_PTC1),
IMX_PINCTRL_PIN(IMX7ULP_PAD_PTC2),
@@ -325,29 +433,70 @@ static int imx7ulp_pmx_gpio_set_direction(struct pinctrl_dev *pctldev,
return 0;
}
-static struct imx_pinctrl_soc_info imx7ulp_pinctrl_info = {
- .pins = imx7ulp_pinctrl_pads,
- .npins = ARRAY_SIZE(imx7ulp_pinctrl_pads),
+static struct imx_pinctrl_soc_info imx7ulp_pinctrl_info_0 = {
+ .pins = imx7ulp_pinctrl_pads_0,
+ .npins = ARRAY_SIZE(imx7ulp_pinctrl_pads_0),
+ .flags = ZERO_OFFSET_VALID | SHARE_MUX_CONF_REG,
+ .gpio_set_direction = imx7ulp_pmx_gpio_set_direction,
+ .mux_mask = BM_MUX_MODE,
+ .mux_shift = BP_MUX_MODE,
+ .decodes = imx7ulp_cfg_decodes,
+ .num_decodes = ARRAY_SIZE(imx7ulp_cfg_decodes),
+ .fixup = imx7ulp_cfg_params_fixup,
+ .ibe_bit = BIT(16),
+ .obe_bit = BIT(17),
+};
+
+static struct imx_pinctrl_soc_info imx7ulp_pinctrl_info_1 = {
+ .pins = imx7ulp_pinctrl_pads_1,
+ .npins = ARRAY_SIZE(imx7ulp_pinctrl_pads_1),
.flags = ZERO_OFFSET_VALID | SHARE_MUX_CONF_REG,
.gpio_set_direction = imx7ulp_pmx_gpio_set_direction,
.mux_mask = BM_MUX_MODE,
.mux_shift = BP_MUX_MODE,
- .generic_pinconf = true,
.decodes = imx7ulp_cfg_decodes,
.num_decodes = ARRAY_SIZE(imx7ulp_cfg_decodes),
.fixup = imx7ulp_cfg_params_fixup,
+ .ibe_bit = BIT(16),
+ .obe_bit = BIT(17),
};
-static const struct of_device_id imx7ulp_pinctrl_of_match[] = {
- { .compatible = "fsl,imx7ulp-iomuxc1", },
+static struct of_device_id imx7ulp_pinctrl_of_match[] = {
+ { .compatible = "fsl,imx7ulp-iomuxc-0", .data = &imx7ulp_pinctrl_info_0 },
+ { .compatible = "fsl,imx7ulp-iomuxc-1", .data = &imx7ulp_pinctrl_info_1,},
{ /* sentinel */ }
};
static int imx7ulp_pinctrl_probe(struct platform_device *pdev)
{
- return imx_pinctrl_probe(pdev, &imx7ulp_pinctrl_info);
+ const struct of_device_id *match;
+ struct imx_pinctrl_soc_info *pinctrl_info;
+
+ match = of_match_device(imx7ulp_pinctrl_of_match, &pdev->dev);
+
+ if (!match)
+ return -ENODEV;
+
+ pinctrl_info = (struct imx_pinctrl_soc_info *) match->data;
+
+ return imx_pinctrl_probe(pdev, pinctrl_info);
+}
+
+static int __maybe_unused imx7ulp_pinctrl_suspend(struct device *dev)
+{
+ return imx_pinctrl_suspend(dev);
+}
+
+static int __maybe_unused imx7ulp_pinctrl_resume(struct device *dev)
+{
+ return imx_pinctrl_resume(dev);
}
+static const struct dev_pm_ops imx7ulp_pinctrl_pm_ops = {
+ SET_LATE_SYSTEM_SLEEP_PM_OPS(imx7ulp_pinctrl_suspend,
+ imx7ulp_pinctrl_resume)
+};
+
static struct platform_driver imx7ulp_pinctrl_driver = {
.driver = {
.name = "imx7ulp-pinctrl",
diff --git a/drivers/pinctrl/freescale/pinctrl-imx8mm.c b/drivers/pinctrl/freescale/pinctrl-imx8mm.c
new file mode 100644
index 000000000000..b88d5b9f5717
--- /dev/null
+++ b/drivers/pinctrl/freescale/pinctrl-imx8mm.c
@@ -0,0 +1,384 @@
+/*
+ * Copyright 2017-2018 NXP
+ *
+ * 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/err.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/pinctrl/pinctrl.h>
+
+#include "pinctrl-imx.h"
+
+enum imx8mm_pads {
+ MX8MM_PAD_RESERVE0 = 0,
+ MX8MM_PAD_RESERVE1 = 1,
+ MX8MM_PAD_RESERVE2 = 2,
+ MX8MM_PAD_RESERVE3 = 3,
+ MX8MM_PAD_RESERVE4 = 4,
+ MX8MM_PAD_RESERVE5 = 5,
+ MX8MM_PAD_RESERVE6 = 6,
+ MX8MM_PAD_RESERVE7 = 7,
+ MX8MM_PAD_RESERVE8 = 8,
+ MX8MM_PAD_RESERVE9 = 9,
+ MX8MM_IOMUXC_GPIO1_IO00 = 10,
+ MX8MM_IOMUXC_GPIO1_IO01 = 11,
+ MX8MM_IOMUXC_GPIO1_IO02 = 12,
+ MX8MM_IOMUXC_GPIO1_IO03 = 13,
+ MX8MM_IOMUXC_GPIO1_IO04 = 14,
+ MX8MM_IOMUXC_GPIO1_IO05 = 15,
+ MX8MM_IOMUXC_GPIO1_IO06 = 16,
+ MX8MM_IOMUXC_GPIO1_IO07 = 17,
+ MX8MM_IOMUXC_GPIO1_IO08 = 18,
+ MX8MM_IOMUXC_GPIO1_IO09 = 19,
+ MX8MM_IOMUXC_GPIO1_IO10 = 20,
+ MX8MM_IOMUXC_GPIO1_IO11 = 21,
+ MX8MM_IOMUXC_GPIO1_IO12 = 22,
+ MX8MM_IOMUXC_GPIO1_IO13 = 23,
+ MX8MM_IOMUXC_GPIO1_IO14 = 24,
+ MX8MM_IOMUXC_GPIO1_IO15 = 25,
+ MX8MM_IOMUXC_ENET_MDC = 26,
+ MX8MM_IOMUXC_ENET_MDIO = 27,
+ MX8MM_IOMUXC_ENET_TD3 = 28,
+ MX8MM_IOMUXC_ENET_TD2 = 29,
+ MX8MM_IOMUXC_ENET_TD1 = 30,
+ MX8MM_IOMUXC_ENET_TD0 = 31,
+ MX8MM_IOMUXC_ENET_TX_CTL = 32,
+ MX8MM_IOMUXC_ENET_TXC = 33,
+ MX8MM_IOMUXC_ENET_RX_CTL = 34,
+ MX8MM_IOMUXC_ENET_RXC = 35,
+ MX8MM_IOMUXC_ENET_RD0 = 36,
+ MX8MM_IOMUXC_ENET_RD1 = 37,
+ MX8MM_IOMUXC_ENET_RD2 = 38,
+ MX8MM_IOMUXC_ENET_RD3 = 39,
+ MX8MM_IOMUXC_SD1_CLK = 40,
+ MX8MM_IOMUXC_SD1_CMD = 41,
+ MX8MM_IOMUXC_SD1_DATA0 = 42,
+ MX8MM_IOMUXC_SD1_DATA1 = 43,
+ MX8MM_IOMUXC_SD1_DATA2 = 44,
+ MX8MM_IOMUXC_SD1_DATA3 = 45,
+ MX8MM_IOMUXC_SD1_DATA4 = 46,
+ MX8MM_IOMUXC_SD1_DATA5 = 47,
+ MX8MM_IOMUXC_SD1_DATA6 = 48,
+ MX8MM_IOMUXC_SD1_DATA7 = 49,
+ MX8MM_IOMUXC_SD1_RESET_B = 50,
+ MX8MM_IOMUXC_SD1_STROBE = 51,
+ MX8MM_IOMUXC_SD2_CD_B = 52,
+ MX8MM_IOMUXC_SD2_CLK = 53,
+ MX8MM_IOMUXC_SD2_CMD = 54,
+ MX8MM_IOMUXC_SD2_DATA0 = 55,
+ MX8MM_IOMUXC_SD2_DATA1 = 56,
+ MX8MM_IOMUXC_SD2_DATA2 = 57,
+ MX8MM_IOMUXC_SD2_DATA3 = 58,
+ MX8MM_IOMUXC_SD2_RESET_B = 59,
+ MX8MM_IOMUXC_SD2_WP = 60,
+ MX8MM_IOMUXC_NAND_ALE = 61,
+ MX8MM_IOMUXC_NAND_CE0 = 62,
+ MX8MM_IOMUXC_NAND_CE1 = 63,
+ MX8MM_IOMUXC_NAND_CE2 = 64,
+ MX8MM_IOMUXC_NAND_CE3 = 65,
+ MX8MM_IOMUXC_NAND_CLE = 66,
+ MX8MM_IOMUXC_NAND_DATA00 = 67,
+ MX8MM_IOMUXC_NAND_DATA01 = 68,
+ MX8MM_IOMUXC_NAND_DATA02 = 69,
+ MX8MM_IOMUXC_NAND_DATA03 = 70,
+ MX8MM_IOMUXC_NAND_DATA04 = 71,
+ MX8MM_IOMUXC_NAND_DATA05 = 72,
+ MX8MM_IOMUXC_NAND_DATA06 = 73,
+ MX8MM_IOMUXC_NAND_DATA07 = 74,
+ MX8MM_IOMUXC_NAND_DQS = 75,
+ MX8MM_IOMUXC_NAND_RE_B = 76,
+ MX8MM_IOMUXC_NAND_READY_B = 77,
+ MX8MM_IOMUXC_NAND_WE_B = 78,
+ MX8MM_IOMUXC_NAND_WP_B = 79,
+ MX8MM_IOMUXC_SAI5_RXFS = 80,
+ MX8MM_IOMUXC_SAI5_RXC = 81,
+ MX8MM_IOMUXC_SAI5_RXD0 = 82,
+ MX8MM_IOMUXC_SAI5_RXD1 = 83,
+ MX8MM_IOMUXC_SAI5_RXD2 = 84,
+ MX8MM_IOMUXC_SAI5_RXD3 = 85,
+ MX8MM_IOMUXC_SAI5_MCLK = 86,
+ MX8MM_IOMUXC_SAI1_RXFS = 87,
+ MX8MM_IOMUXC_SAI1_RXC = 88,
+ MX8MM_IOMUXC_SAI1_RXD0 = 89,
+ MX8MM_IOMUXC_SAI1_RXD1 = 90,
+ MX8MM_IOMUXC_SAI1_RXD2 = 91,
+ MX8MM_IOMUXC_SAI1_RXD3 = 92,
+ MX8MM_IOMUXC_SAI1_RXD4 = 93,
+ MX8MM_IOMUXC_SAI1_RXD5 = 94,
+ MX8MM_IOMUXC_SAI1_RXD6 = 95,
+ MX8MM_IOMUXC_SAI1_RXD7 = 96,
+ MX8MM_IOMUXC_SAI1_TXFS = 97,
+ MX8MM_IOMUXC_SAI1_TXC = 98,
+ MX8MM_IOMUXC_SAI1_TXD0 = 99,
+ MX8MM_IOMUXC_SAI1_TXD1 = 100,
+ MX8MM_IOMUXC_SAI1_TXD2 = 101,
+ MX8MM_IOMUXC_SAI1_TXD3 = 102,
+ MX8MM_IOMUXC_SAI1_TXD4 = 103,
+ MX8MM_IOMUXC_SAI1_TXD5 = 104,
+ MX8MM_IOMUXC_SAI1_TXD6 = 105,
+ MX8MM_IOMUXC_SAI1_TXD7 = 106,
+ MX8MM_IOMUXC_SAI1_MCLK = 107,
+ MX8MM_IOMUXC_SAI2_RXFS = 108,
+ MX8MM_IOMUXC_SAI2_RXC = 109,
+ MX8MM_IOMUXC_SAI2_RXD0 = 110,
+ MX8MM_IOMUXC_SAI2_TXFS = 111,
+ MX8MM_IOMUXC_SAI2_TXC = 112,
+ MX8MM_IOMUXC_SAI2_TXD0 = 113,
+ MX8MM_IOMUXC_SAI2_MCLK = 114,
+ MX8MM_IOMUXC_SAI3_RXFS = 115,
+ MX8MM_IOMUXC_SAI3_RXC = 116,
+ MX8MM_IOMUXC_SAI3_RXD = 117,
+ MX8MM_IOMUXC_SAI3_TXFS = 118,
+ MX8MM_IOMUXC_SAI3_TXC = 119,
+ MX8MM_IOMUXC_SAI3_TXD = 120,
+ MX8MM_IOMUXC_SAI3_MCLK = 121,
+ MX8MM_IOMUXC_SPDIF_TX = 122,
+ MX8MM_IOMUXC_SPDIF_RX = 123,
+ MX8MM_IOMUXC_SPDIF_EXT_CLK = 124,
+ MX8MM_IOMUXC_ECSPI1_SCLK = 125,
+ MX8MM_IOMUXC_ECSPI1_MOSI = 126,
+ MX8MM_IOMUXC_ECSPI1_MISO = 127,
+ MX8MM_IOMUXC_ECSPI1_SS0 = 128,
+ MX8MM_IOMUXC_ECSPI2_SCLK = 129,
+ MX8MM_IOMUXC_ECSPI2_MOSI = 130,
+ MX8MM_IOMUXC_ECSPI2_MISO = 131,
+ MX8MM_IOMUXC_ECSPI2_SS0 = 132,
+ MX8MM_IOMUXC_I2C1_SCL = 133,
+ MX8MM_IOMUXC_I2C1_SDA = 134,
+ MX8MM_IOMUXC_I2C2_SCL = 135,
+ MX8MM_IOMUXC_I2C2_SDA = 136,
+ MX8MM_IOMUXC_I2C3_SCL = 137,
+ MX8MM_IOMUXC_I2C3_SDA = 138,
+ MX8MM_IOMUXC_I2C4_SCL = 139,
+ MX8MM_IOMUXC_I2C4_SDA = 140,
+ MX8MM_IOMUXC_UART1_RXD = 141,
+ MX8MM_IOMUXC_UART1_TXD = 142,
+ MX8MM_IOMUXC_UART2_RXD = 143,
+ MX8MM_IOMUXC_UART2_TXD = 144,
+ MX8MM_IOMUXC_UART3_RXD = 145,
+ MX8MM_IOMUXC_UART3_TXD = 146,
+ MX8MM_IOMUXC_UART4_RXD = 147,
+ MX8MM_IOMUXC_UART4_TXD = 148,
+};
+
+/* Pad names for the pinmux subsystem */
+static const struct pinctrl_pin_desc imx8mm_pinctrl_pads[] = {
+ IMX_PINCTRL_PIN(MX8MM_PAD_RESERVE0),
+ IMX_PINCTRL_PIN(MX8MM_PAD_RESERVE1),
+ IMX_PINCTRL_PIN(MX8MM_PAD_RESERVE2),
+ IMX_PINCTRL_PIN(MX8MM_PAD_RESERVE3),
+ IMX_PINCTRL_PIN(MX8MM_PAD_RESERVE4),
+ IMX_PINCTRL_PIN(MX8MM_PAD_RESERVE5),
+ IMX_PINCTRL_PIN(MX8MM_PAD_RESERVE6),
+ IMX_PINCTRL_PIN(MX8MM_PAD_RESERVE7),
+ IMX_PINCTRL_PIN(MX8MM_PAD_RESERVE8),
+ IMX_PINCTRL_PIN(MX8MM_PAD_RESERVE9),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_GPIO1_IO00),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_GPIO1_IO01),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_GPIO1_IO02),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_GPIO1_IO03),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_GPIO1_IO04),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_GPIO1_IO05),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_GPIO1_IO06),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_GPIO1_IO07),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_GPIO1_IO08),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_GPIO1_IO09),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_GPIO1_IO10),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_GPIO1_IO11),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_GPIO1_IO12),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_GPIO1_IO13),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_GPIO1_IO14),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_GPIO1_IO15),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_ENET_MDC),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_ENET_MDIO),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_ENET_TD3),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_ENET_TD2),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_ENET_TD1),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_ENET_TD0),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_ENET_TX_CTL),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_ENET_TXC),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_ENET_RX_CTL),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_ENET_RXC),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_ENET_RD0),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_ENET_RD1),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_ENET_RD2),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_ENET_RD3),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_SD1_CLK),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_SD1_CMD),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_SD1_DATA0),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_SD1_DATA1),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_SD1_DATA2),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_SD1_DATA3),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_SD1_DATA4),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_SD1_DATA5),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_SD1_DATA6),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_SD1_DATA7),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_SD1_RESET_B),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_SD1_STROBE),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_SD2_CD_B),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_SD2_CLK),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_SD2_CMD),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_SD2_DATA0),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_SD2_DATA1),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_SD2_DATA2),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_SD2_DATA3),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_SD2_RESET_B),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_SD2_WP),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_NAND_ALE),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_NAND_CE0),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_NAND_CE1),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_NAND_CE2),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_NAND_CE3),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_NAND_CLE),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_NAND_DATA00),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_NAND_DATA01),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_NAND_DATA02),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_NAND_DATA03),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_NAND_DATA04),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_NAND_DATA05),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_NAND_DATA06),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_NAND_DATA07),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_NAND_DQS),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_NAND_RE_B),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_NAND_READY_B),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_NAND_WE_B),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_NAND_WP_B),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_SAI5_RXFS),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_SAI5_RXC),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_SAI5_RXD0),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_SAI5_RXD1),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_SAI5_RXD2),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_SAI5_RXD3),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_SAI5_MCLK),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_SAI1_RXFS),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_SAI1_RXC),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_SAI1_RXD0),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_SAI1_RXD1),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_SAI1_RXD2),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_SAI1_RXD3),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_SAI1_RXD4),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_SAI1_RXD5),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_SAI1_RXD6),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_SAI1_RXD7),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_SAI1_TXFS),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_SAI1_TXC),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_SAI1_TXD0),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_SAI1_TXD1),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_SAI1_TXD2),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_SAI1_TXD3),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_SAI1_TXD4),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_SAI1_TXD5),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_SAI1_TXD6),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_SAI1_TXD7),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_SAI1_MCLK),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_SAI2_RXFS),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_SAI2_RXC),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_SAI2_RXD0),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_SAI2_TXFS),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_SAI2_TXC),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_SAI2_TXD0),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_SAI2_MCLK),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_SAI3_RXFS),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_SAI3_RXC),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_SAI3_RXD),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_SAI3_TXFS),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_SAI3_TXC),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_SAI3_TXD),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_SAI3_MCLK),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_SPDIF_TX),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_SPDIF_RX),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_SPDIF_EXT_CLK),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_ECSPI1_SCLK),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_ECSPI1_MOSI),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_ECSPI1_MISO),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_ECSPI1_SS0),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_ECSPI2_SCLK),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_ECSPI2_MOSI),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_ECSPI2_MISO),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_ECSPI2_SS0),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_I2C1_SCL),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_I2C1_SDA),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_I2C2_SCL),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_I2C2_SDA),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_I2C3_SCL),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_I2C3_SDA),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_I2C4_SCL),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_I2C4_SDA),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_UART1_RXD),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_UART1_TXD),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_UART2_RXD),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_UART2_TXD),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_UART3_RXD),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_UART3_TXD),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_UART4_RXD),
+ IMX_PINCTRL_PIN(MX8MM_IOMUXC_UART4_TXD),
+};
+
+static struct imx_pinctrl_soc_info imx8mm_pinctrl_info = {
+ .pins = imx8mm_pinctrl_pads,
+ .npins = ARRAY_SIZE(imx8mm_pinctrl_pads),
+ .gpr_compatible = "fsl,imx8mm-iomuxc-gpr",
+};
+
+static struct of_device_id imx8mm_pinctrl_of_match[] = {
+ { .compatible = "fsl,imx8mm-iomuxc", .data = &imx8mm_pinctrl_info, },
+ { /* sentinel */ }
+};
+
+static int imx8mm_pinctrl_probe(struct platform_device *pdev)
+{
+ const struct of_device_id *match;
+ struct imx_pinctrl_soc_info *pinctrl_info;
+
+ match = of_match_device(imx8mm_pinctrl_of_match, &pdev->dev);
+
+ if (!match)
+ return -ENODEV;
+
+ pinctrl_info = (struct imx_pinctrl_soc_info *) match->data;
+
+ return imx_pinctrl_probe(pdev, pinctrl_info);
+}
+
+static int imx8mm_pinctrl_suspend(struct device *dev)
+{
+
+ return imx_pinctrl_suspend(dev);
+}
+
+static int imx8mm_pinctrl_resume(struct device *dev)
+{
+
+ return imx_pinctrl_resume(dev);
+}
+
+static const struct dev_pm_ops imx8mm_pinctrl_pm_ops = {
+ SET_LATE_SYSTEM_SLEEP_PM_OPS(imx8mm_pinctrl_suspend, imx8mm_pinctrl_resume)
+};
+
+static struct platform_driver imx8mm_pinctrl_driver = {
+ .driver = {
+ .name = "imx8mm-pinctrl",
+ .of_match_table = of_match_ptr(imx8mm_pinctrl_of_match),
+ .pm = &imx8mm_pinctrl_pm_ops,
+ },
+ .probe = imx8mm_pinctrl_probe,
+};
+
+static int __init imx8mm_pinctrl_init(void)
+{
+ return platform_driver_register(&imx8mm_pinctrl_driver);
+}
+arch_initcall(imx8mm_pinctrl_init);
diff --git a/drivers/pinctrl/freescale/pinctrl-imx8mq.c b/drivers/pinctrl/freescale/pinctrl-imx8mq.c
new file mode 100644
index 000000000000..06585061cfa8
--- /dev/null
+++ b/drivers/pinctrl/freescale/pinctrl-imx8mq.c
@@ -0,0 +1,385 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017 NXP
+ *
+ * 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/err.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/pinctrl/pinctrl.h>
+
+#include "pinctrl-imx.h"
+
+enum imx8mq_pads {
+ MX8MQ_PAD_RESERVE0 = 0,
+ MX8MQ_PAD_RESERVE1 = 1,
+ MX8MQ_PAD_RESERVE2 = 2,
+ MX8MQ_PAD_RESERVE3 = 3,
+ MX8MQ_PAD_RESERVE4 = 4,
+ MX8MQ_IOMUXC_PMIC_STBY_REQ_CCMSRCGPCMIX = 5,
+ MX8MQ_IOMUXC_PMIC_ON_REQ_SNVSMIX = 6,
+ MX8MQ_IOMUXC_ONOFF_SNVSMIX = 7,
+ MX8MQ_IOMUXC_POR_B_SNVSMIX = 8,
+ MX8MQ_IOMUXC_RTC_RESET_B_SNVSMIX = 9,
+ MX8MQ_IOMUXC_GPIO1_IO00 = 10,
+ MX8MQ_IOMUXC_GPIO1_IO01 = 11,
+ MX8MQ_IOMUXC_GPIO1_IO02 = 12,
+ MX8MQ_IOMUXC_GPIO1_IO03 = 13,
+ MX8MQ_IOMUXC_GPIO1_IO04 = 14,
+ MX8MQ_IOMUXC_GPIO1_IO05 = 15,
+ MX8MQ_IOMUXC_GPIO1_IO06 = 16,
+ MX8MQ_IOMUXC_GPIO1_IO07 = 17,
+ MX8MQ_IOMUXC_GPIO1_IO08 = 18,
+ MX8MQ_IOMUXC_GPIO1_IO09 = 19,
+ MX8MQ_IOMUXC_GPIO1_IO10 = 20,
+ MX8MQ_IOMUXC_GPIO1_IO11 = 21,
+ MX8MQ_IOMUXC_GPIO1_IO12 = 22,
+ MX8MQ_IOMUXC_GPIO1_IO13 = 23,
+ MX8MQ_IOMUXC_GPIO1_IO14 = 24,
+ MX8MQ_IOMUXC_GPIO1_IO15 = 25,
+ MX8MQ_IOMUXC_ENET_MDC = 26,
+ MX8MQ_IOMUXC_ENET_MDIO = 27,
+ MX8MQ_IOMUXC_ENET_TD3 = 28,
+ MX8MQ_IOMUXC_ENET_TD2 = 29,
+ MX8MQ_IOMUXC_ENET_TD1 = 30,
+ MX8MQ_IOMUXC_ENET_TD0 = 31,
+ MX8MQ_IOMUXC_ENET_TX_CTL = 32,
+ MX8MQ_IOMUXC_ENET_TXC = 33,
+ MX8MQ_IOMUXC_ENET_RX_CTL = 34,
+ MX8MQ_IOMUXC_ENET_RXC = 35,
+ MX8MQ_IOMUXC_ENET_RD0 = 36,
+ MX8MQ_IOMUXC_ENET_RD1 = 37,
+ MX8MQ_IOMUXC_ENET_RD2 = 38,
+ MX8MQ_IOMUXC_ENET_RD3 = 39,
+ MX8MQ_IOMUXC_SD1_CLK = 40,
+ MX8MQ_IOMUXC_SD1_CMD = 41,
+ MX8MQ_IOMUXC_SD1_DATA0 = 42,
+ MX8MQ_IOMUXC_SD1_DATA1 = 43,
+ MX8MQ_IOMUXC_SD1_DATA2 = 44,
+ MX8MQ_IOMUXC_SD1_DATA3 = 45,
+ MX8MQ_IOMUXC_SD1_DATA4 = 46,
+ MX8MQ_IOMUXC_SD1_DATA5 = 47,
+ MX8MQ_IOMUXC_SD1_DATA6 = 48,
+ MX8MQ_IOMUXC_SD1_DATA7 = 49,
+ MX8MQ_IOMUXC_SD1_RESET_B = 50,
+ MX8MQ_IOMUXC_SD1_STROBE = 51,
+ MX8MQ_IOMUXC_SD2_CD_B = 52,
+ MX8MQ_IOMUXC_SD2_CLK = 53,
+ MX8MQ_IOMUXC_SD2_CMD = 54,
+ MX8MQ_IOMUXC_SD2_DATA0 = 55,
+ MX8MQ_IOMUXC_SD2_DATA1 = 56,
+ MX8MQ_IOMUXC_SD2_DATA2 = 57,
+ MX8MQ_IOMUXC_SD2_DATA3 = 58,
+ MX8MQ_IOMUXC_SD2_RESET_B = 59,
+ MX8MQ_IOMUXC_SD2_WP = 60,
+ MX8MQ_IOMUXC_NAND_ALE = 61,
+ MX8MQ_IOMUXC_NAND_CE0_B = 62,
+ MX8MQ_IOMUXC_NAND_CE1_B = 63,
+ MX8MQ_IOMUXC_NAND_CE2_B = 64,
+ MX8MQ_IOMUXC_NAND_CE3_B = 65,
+ MX8MQ_IOMUXC_NAND_CLE = 66,
+ MX8MQ_IOMUXC_NAND_DATA00 = 67,
+ MX8MQ_IOMUXC_NAND_DATA01 = 68,
+ MX8MQ_IOMUXC_NAND_DATA02 = 69,
+ MX8MQ_IOMUXC_NAND_DATA03 = 70,
+ MX8MQ_IOMUXC_NAND_DATA04 = 71,
+ MX8MQ_IOMUXC_NAND_DATA05 = 72,
+ MX8MQ_IOMUXC_NAND_DATA06 = 73,
+ MX8MQ_IOMUXC_NAND_DATA07 = 74,
+ MX8MQ_IOMUXC_NAND_DQS = 75,
+ MX8MQ_IOMUXC_NAND_RE_B = 76,
+ MX8MQ_IOMUXC_NAND_READY_B = 77,
+ MX8MQ_IOMUXC_NAND_WE_B = 78,
+ MX8MQ_IOMUXC_NAND_WP_B = 79,
+ MX8MQ_IOMUXC_SAI5_RXFS = 80,
+ MX8MQ_IOMUXC_SAI5_RXC = 81,
+ MX8MQ_IOMUXC_SAI5_RXD0 = 82,
+ MX8MQ_IOMUXC_SAI5_RXD1 = 83,
+ MX8MQ_IOMUXC_SAI5_RXD2 = 84,
+ MX8MQ_IOMUXC_SAI5_RXD3 = 85,
+ MX8MQ_IOMUXC_SAI5_MCLK = 86,
+ MX8MQ_IOMUXC_SAI1_RXFS = 87,
+ MX8MQ_IOMUXC_SAI1_RXC = 88,
+ MX8MQ_IOMUXC_SAI1_RXD0 = 89,
+ MX8MQ_IOMUXC_SAI1_RXD1 = 90,
+ MX8MQ_IOMUXC_SAI1_RXD2 = 91,
+ MX8MQ_IOMUXC_SAI1_RXD3 = 92,
+ MX8MQ_IOMUXC_SAI1_RXD4 = 93,
+ MX8MQ_IOMUXC_SAI1_RXD5 = 94,
+ MX8MQ_IOMUXC_SAI1_RXD6 = 95,
+ MX8MQ_IOMUXC_SAI1_RXD7 = 96,
+ MX8MQ_IOMUXC_SAI1_TXFS = 97,
+ MX8MQ_IOMUXC_SAI1_TXC = 98,
+ MX8MQ_IOMUXC_SAI1_TXD0 = 99,
+ MX8MQ_IOMUXC_SAI1_TXD1 = 100,
+ MX8MQ_IOMUXC_SAI1_TXD2 = 101,
+ MX8MQ_IOMUXC_SAI1_TXD3 = 102,
+ MX8MQ_IOMUXC_SAI1_TXD4 = 103,
+ MX8MQ_IOMUXC_SAI1_TXD5 = 104,
+ MX8MQ_IOMUXC_SAI1_TXD6 = 105,
+ MX8MQ_IOMUXC_SAI1_TXD7 = 106,
+ MX8MQ_IOMUXC_SAI1_MCLK = 107,
+ MX8MQ_IOMUXC_SAI2_RXFS = 108,
+ MX8MQ_IOMUXC_SAI2_RXC = 109,
+ MX8MQ_IOMUXC_SAI2_RXD0 = 110,
+ MX8MQ_IOMUXC_SAI2_TXFS = 111,
+ MX8MQ_IOMUXC_SAI2_TXC = 112,
+ MX8MQ_IOMUXC_SAI2_TXD0 = 113,
+ MX8MQ_IOMUXC_SAI2_MCLK = 114,
+ MX8MQ_IOMUXC_SAI3_RXFS = 115,
+ MX8MQ_IOMUXC_SAI3_RXC = 116,
+ MX8MQ_IOMUXC_SAI3_RXD = 117,
+ MX8MQ_IOMUXC_SAI3_TXFS = 118,
+ MX8MQ_IOMUXC_SAI3_TXC = 119,
+ MX8MQ_IOMUXC_SAI3_TXD = 120,
+ MX8MQ_IOMUXC_SAI3_MCLK = 121,
+ MX8MQ_IOMUXC_SPDIF_TX = 122,
+ MX8MQ_IOMUXC_SPDIF_RX = 123,
+ MX8MQ_IOMUXC_SPDIF_EXT_CLK = 124,
+ MX8MQ_IOMUXC_ECSPI1_SCLK = 125,
+ MX8MQ_IOMUXC_ECSPI1_MOSI = 126,
+ MX8MQ_IOMUXC_ECSPI1_MISO = 127,
+ MX8MQ_IOMUXC_ECSPI1_SS0 = 128,
+ MX8MQ_IOMUXC_ECSPI2_SCLK = 129,
+ MX8MQ_IOMUXC_ECSPI2_MOSI = 130,
+ MX8MQ_IOMUXC_ECSPI2_MISO = 131,
+ MX8MQ_IOMUXC_ECSPI2_SS0 = 132,
+ MX8MQ_IOMUXC_I2C1_SCL = 133,
+ MX8MQ_IOMUXC_I2C1_SDA = 134,
+ MX8MQ_IOMUXC_I2C2_SCL = 135,
+ MX8MQ_IOMUXC_I2C2_SDA = 136,
+ MX8MQ_IOMUXC_I2C3_SCL = 137,
+ MX8MQ_IOMUXC_I2C3_SDA = 138,
+ MX8MQ_IOMUXC_I2C4_SCL = 139,
+ MX8MQ_IOMUXC_I2C4_SDA = 140,
+ MX8MQ_IOMUXC_UART1_RXD = 141,
+ MX8MQ_IOMUXC_UART1_TXD = 142,
+ MX8MQ_IOMUXC_UART2_RXD = 143,
+ MX8MQ_IOMUXC_UART2_TXD = 144,
+ MX8MQ_IOMUXC_UART3_RXD = 145,
+ MX8MQ_IOMUXC_UART3_TXD = 146,
+ MX8MQ_IOMUXC_UART4_RXD = 147,
+ MX8MQ_IOMUXC_UART4_TXD = 148,
+};
+
+/* Pad names for the pinmux subsystem */
+static const struct pinctrl_pin_desc imx8mq_pinctrl_pads[] = {
+ IMX_PINCTRL_PIN(MX8MQ_PAD_RESERVE0),
+ IMX_PINCTRL_PIN(MX8MQ_PAD_RESERVE1),
+ IMX_PINCTRL_PIN(MX8MQ_PAD_RESERVE2),
+ IMX_PINCTRL_PIN(MX8MQ_PAD_RESERVE3),
+ IMX_PINCTRL_PIN(MX8MQ_PAD_RESERVE4),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_PMIC_STBY_REQ_CCMSRCGPCMIX),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_PMIC_ON_REQ_SNVSMIX),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_ONOFF_SNVSMIX),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_POR_B_SNVSMIX),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_RTC_RESET_B_SNVSMIX),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_GPIO1_IO00),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_GPIO1_IO01),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_GPIO1_IO02),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_GPIO1_IO03),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_GPIO1_IO04),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_GPIO1_IO05),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_GPIO1_IO06),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_GPIO1_IO07),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_GPIO1_IO08),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_GPIO1_IO09),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_GPIO1_IO10),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_GPIO1_IO11),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_GPIO1_IO12),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_GPIO1_IO13),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_GPIO1_IO14),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_GPIO1_IO15),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_ENET_MDC),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_ENET_MDIO),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_ENET_TD3),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_ENET_TD2),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_ENET_TD1),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_ENET_TD0),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_ENET_TX_CTL),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_ENET_TXC),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_ENET_RX_CTL),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_ENET_RXC),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_ENET_RD0),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_ENET_RD1),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_ENET_RD2),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_ENET_RD3),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_SD1_CLK),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_SD1_CMD),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_SD1_DATA0),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_SD1_DATA1),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_SD1_DATA2),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_SD1_DATA3),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_SD1_DATA4),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_SD1_DATA5),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_SD1_DATA6),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_SD1_DATA7),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_SD1_RESET_B),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_SD1_STROBE),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_SD2_CD_B),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_SD2_CLK),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_SD2_CMD),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_SD2_DATA0),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_SD2_DATA1),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_SD2_DATA2),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_SD2_DATA3),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_SD2_RESET_B),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_SD2_WP),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_NAND_ALE),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_NAND_CE0_B),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_NAND_CE1_B),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_NAND_CE2_B),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_NAND_CE3_B),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_NAND_CLE),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_NAND_DATA00),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_NAND_DATA01),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_NAND_DATA02),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_NAND_DATA03),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_NAND_DATA04),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_NAND_DATA05),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_NAND_DATA06),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_NAND_DATA07),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_NAND_DQS),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_NAND_RE_B),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_NAND_READY_B),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_NAND_WE_B),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_NAND_WP_B),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_SAI5_RXFS),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_SAI5_RXC),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_SAI5_RXD0),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_SAI5_RXD1),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_SAI5_RXD2),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_SAI5_RXD3),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_SAI5_MCLK),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_SAI1_RXFS),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_SAI1_RXC),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_SAI1_RXD0),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_SAI1_RXD1),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_SAI1_RXD2),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_SAI1_RXD3),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_SAI1_RXD4),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_SAI1_RXD5),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_SAI1_RXD6),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_SAI1_RXD7),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_SAI1_TXFS),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_SAI1_TXC),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_SAI1_TXD0),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_SAI1_TXD1),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_SAI1_TXD2),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_SAI1_TXD3),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_SAI1_TXD4),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_SAI1_TXD5),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_SAI1_TXD6),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_SAI1_TXD7),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_SAI1_MCLK),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_SAI2_RXFS),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_SAI2_RXC),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_SAI2_RXD0),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_SAI2_TXFS),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_SAI2_TXC),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_SAI2_TXD0),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_SAI2_MCLK),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_SAI3_RXFS),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_SAI3_RXC),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_SAI3_RXD),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_SAI3_TXFS),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_SAI3_TXC),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_SAI3_TXD),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_SAI3_MCLK),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_SPDIF_TX),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_SPDIF_RX),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_SPDIF_EXT_CLK),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_ECSPI1_SCLK),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_ECSPI1_MOSI),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_ECSPI1_MISO),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_ECSPI1_SS0),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_ECSPI2_SCLK),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_ECSPI2_MOSI),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_ECSPI2_MISO),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_ECSPI2_SS0),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_I2C1_SCL),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_I2C1_SDA),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_I2C2_SCL),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_I2C2_SDA),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_I2C3_SCL),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_I2C3_SDA),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_I2C4_SCL),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_I2C4_SDA),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_UART1_RXD),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_UART1_TXD),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_UART2_RXD),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_UART2_TXD),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_UART3_RXD),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_UART3_TXD),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_UART4_RXD),
+ IMX_PINCTRL_PIN(MX8MQ_IOMUXC_UART4_TXD),
+};
+
+static struct imx_pinctrl_soc_info imx8mq_pinctrl_info = {
+ .pins = imx8mq_pinctrl_pads,
+ .npins = ARRAY_SIZE(imx8mq_pinctrl_pads),
+ .gpr_compatible = "fsl,imx8mq-iomuxc-gpr",
+};
+
+static struct of_device_id imx8mq_pinctrl_of_match[] = {
+ { .compatible = "fsl,imx8mq-iomuxc", .data = &imx8mq_pinctrl_info, },
+ { /* sentinel */ }
+};
+
+static int imx8mq_pinctrl_probe(struct platform_device *pdev)
+{
+ const struct of_device_id *match;
+ struct imx_pinctrl_soc_info *pinctrl_info;
+
+ match = of_match_device(imx8mq_pinctrl_of_match, &pdev->dev);
+
+ if (!match)
+ return -ENODEV;
+
+ pinctrl_info = (struct imx_pinctrl_soc_info *) match->data;
+
+ return imx_pinctrl_probe(pdev, pinctrl_info);
+}
+
+static int imx8mq_pinctrl_suspend(struct device *dev)
+{
+
+ return imx_pinctrl_suspend(dev);
+}
+
+static int imx8mq_pinctrl_resume(struct device *dev)
+{
+
+ return imx_pinctrl_resume(dev);
+}
+
+static const struct dev_pm_ops imx8mq_pinctrl_pm_ops = {
+ SET_LATE_SYSTEM_SLEEP_PM_OPS(imx8mq_pinctrl_suspend, imx8mq_pinctrl_resume)
+};
+
+static struct platform_driver imx8mq_pinctrl_driver = {
+ .driver = {
+ .name = "imx8mq-pinctrl",
+ .of_match_table = of_match_ptr(imx8mq_pinctrl_of_match),
+ .pm = &imx8mq_pinctrl_pm_ops,
+ },
+ .probe = imx8mq_pinctrl_probe,
+};
+
+static int __init imx8mq_pinctrl_init(void)
+{
+ return platform_driver_register(&imx8mq_pinctrl_driver);
+}
+arch_initcall(imx8mq_pinctrl_init);
diff --git a/drivers/pinctrl/freescale/pinctrl-imx8qm.c b/drivers/pinctrl/freescale/pinctrl-imx8qm.c
new file mode 100644
index 000000000000..665c0b4429ef
--- /dev/null
+++ b/drivers/pinctrl/freescale/pinctrl-imx8qm.c
@@ -0,0 +1,358 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017 NXP
+ *
+ * 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/err.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/pinctrl/pinctrl.h>
+#include <dt-bindings/pinctrl/pads-imx8qm.h>
+#include <soc/imx8/sc/sci.h>
+
+#include "pinctrl-imx.h"
+
+extern sc_ipc_t pinctrl_ipcHandle;
+
+static const struct pinctrl_pin_desc imx8qm_pinctrl_pads[] = {
+ IMX_PINCTRL_PIN(SC_P_SIM0_CLK),
+ IMX_PINCTRL_PIN(SC_P_SIM0_RST),
+ IMX_PINCTRL_PIN(SC_P_SIM0_IO),
+ IMX_PINCTRL_PIN(SC_P_SIM0_PD),
+ IMX_PINCTRL_PIN(SC_P_SIM0_POWER_EN),
+ IMX_PINCTRL_PIN(SC_P_SIM0_GPIO0_00),
+ IMX_PINCTRL_PIN(SC_P_COMP_CTL_GPIO_1V8_3V3_SIM),
+ IMX_PINCTRL_PIN(SC_P_M40_I2C0_SCL),
+ IMX_PINCTRL_PIN(SC_P_M40_I2C0_SDA),
+ IMX_PINCTRL_PIN(SC_P_M40_GPIO0_00),
+ IMX_PINCTRL_PIN(SC_P_M40_GPIO0_01),
+ IMX_PINCTRL_PIN(SC_P_M41_I2C0_SCL),
+ IMX_PINCTRL_PIN(SC_P_M41_I2C0_SDA),
+ IMX_PINCTRL_PIN(SC_P_M41_GPIO0_00),
+ IMX_PINCTRL_PIN(SC_P_M41_GPIO0_01),
+ IMX_PINCTRL_PIN(SC_P_GPT0_CLK),
+ IMX_PINCTRL_PIN(SC_P_GPT0_CAPTURE),
+ IMX_PINCTRL_PIN(SC_P_GPT0_COMPARE),
+ IMX_PINCTRL_PIN(SC_P_GPT1_CLK),
+ IMX_PINCTRL_PIN(SC_P_GPT1_CAPTURE),
+ IMX_PINCTRL_PIN(SC_P_GPT1_COMPARE),
+ IMX_PINCTRL_PIN(SC_P_UART0_RX),
+ IMX_PINCTRL_PIN(SC_P_UART0_TX),
+ IMX_PINCTRL_PIN(SC_P_UART0_RTS_B),
+ IMX_PINCTRL_PIN(SC_P_UART0_CTS_B),
+ IMX_PINCTRL_PIN(SC_P_UART1_TX),
+ IMX_PINCTRL_PIN(SC_P_UART1_RX),
+ IMX_PINCTRL_PIN(SC_P_UART1_RTS_B),
+ IMX_PINCTRL_PIN(SC_P_UART1_CTS_B),
+ IMX_PINCTRL_PIN(SC_P_COMP_CTL_GPIO_1V8_3V3_GPIOLH),
+ IMX_PINCTRL_PIN(SC_P_SCU_PMIC_MEMC_ON),
+ IMX_PINCTRL_PIN(SC_P_SCU_WDOG_OUT),
+ IMX_PINCTRL_PIN(SC_P_PMIC_I2C_SDA),
+ IMX_PINCTRL_PIN(SC_P_PMIC_I2C_SCL),
+ IMX_PINCTRL_PIN(SC_P_PMIC_EARLY_WARNING),
+ IMX_PINCTRL_PIN(SC_P_PMIC_INT_B),
+ IMX_PINCTRL_PIN(SC_P_SCU_GPIO0_00),
+ IMX_PINCTRL_PIN(SC_P_SCU_GPIO0_01),
+ IMX_PINCTRL_PIN(SC_P_SCU_GPIO0_02),
+ IMX_PINCTRL_PIN(SC_P_SCU_GPIO0_03),
+ IMX_PINCTRL_PIN(SC_P_SCU_GPIO0_04),
+ IMX_PINCTRL_PIN(SC_P_SCU_GPIO0_05),
+ IMX_PINCTRL_PIN(SC_P_SCU_GPIO0_06),
+ IMX_PINCTRL_PIN(SC_P_SCU_GPIO0_07),
+ IMX_PINCTRL_PIN(SC_P_SCU_BOOT_MODE0),
+ IMX_PINCTRL_PIN(SC_P_SCU_BOOT_MODE1),
+ IMX_PINCTRL_PIN(SC_P_SCU_BOOT_MODE2),
+ IMX_PINCTRL_PIN(SC_P_SCU_BOOT_MODE3),
+ IMX_PINCTRL_PIN(SC_P_SCU_BOOT_MODE4),
+ IMX_PINCTRL_PIN(SC_P_SCU_BOOT_MODE5),
+ IMX_PINCTRL_PIN(SC_P_LVDS0_GPIO00),
+ IMX_PINCTRL_PIN(SC_P_LVDS0_GPIO01),
+ IMX_PINCTRL_PIN(SC_P_LVDS0_I2C0_SCL),
+ IMX_PINCTRL_PIN(SC_P_LVDS0_I2C0_SDA),
+ IMX_PINCTRL_PIN(SC_P_LVDS0_I2C1_SCL),
+ IMX_PINCTRL_PIN(SC_P_LVDS0_I2C1_SDA),
+ IMX_PINCTRL_PIN(SC_P_LVDS1_GPIO00),
+ IMX_PINCTRL_PIN(SC_P_LVDS1_GPIO01),
+ IMX_PINCTRL_PIN(SC_P_LVDS1_I2C0_SCL),
+ IMX_PINCTRL_PIN(SC_P_LVDS1_I2C0_SDA),
+ IMX_PINCTRL_PIN(SC_P_LVDS1_I2C1_SCL),
+ IMX_PINCTRL_PIN(SC_P_LVDS1_I2C1_SDA),
+ IMX_PINCTRL_PIN(SC_P_COMP_CTL_GPIO_1V8_3V3_LVDSGPIO),
+ IMX_PINCTRL_PIN(SC_P_MIPI_DSI0_I2C0_SCL),
+ IMX_PINCTRL_PIN(SC_P_MIPI_DSI0_I2C0_SDA),
+ IMX_PINCTRL_PIN(SC_P_MIPI_DSI0_GPIO0_00),
+ IMX_PINCTRL_PIN(SC_P_MIPI_DSI0_GPIO0_01),
+ IMX_PINCTRL_PIN(SC_P_MIPI_DSI1_I2C0_SCL),
+ IMX_PINCTRL_PIN(SC_P_MIPI_DSI1_I2C0_SDA),
+ IMX_PINCTRL_PIN(SC_P_MIPI_DSI1_GPIO0_00),
+ IMX_PINCTRL_PIN(SC_P_MIPI_DSI1_GPIO0_01),
+ IMX_PINCTRL_PIN(SC_P_COMP_CTL_GPIO_1V8_3V3_MIPIDSIGPIO),
+ IMX_PINCTRL_PIN(SC_P_MIPI_CSI0_MCLK_OUT),
+ IMX_PINCTRL_PIN(SC_P_MIPI_CSI0_I2C0_SCL),
+ IMX_PINCTRL_PIN(SC_P_MIPI_CSI0_I2C0_SDA),
+ IMX_PINCTRL_PIN(SC_P_MIPI_CSI0_GPIO0_00),
+ IMX_PINCTRL_PIN(SC_P_MIPI_CSI0_GPIO0_01),
+ IMX_PINCTRL_PIN(SC_P_MIPI_CSI1_MCLK_OUT),
+ IMX_PINCTRL_PIN(SC_P_MIPI_CSI1_GPIO0_00),
+ IMX_PINCTRL_PIN(SC_P_MIPI_CSI1_GPIO0_01),
+ IMX_PINCTRL_PIN(SC_P_MIPI_CSI1_I2C0_SCL),
+ IMX_PINCTRL_PIN(SC_P_MIPI_CSI1_I2C0_SDA),
+ IMX_PINCTRL_PIN(SC_P_HDMI_TX0_TS_SCL),
+ IMX_PINCTRL_PIN(SC_P_HDMI_TX0_TS_SDA),
+ IMX_PINCTRL_PIN(SC_P_COMP_CTL_GPIO_3V3_HDMIGPIO),
+ IMX_PINCTRL_PIN(SC_P_ESAI1_FSR),
+ IMX_PINCTRL_PIN(SC_P_ESAI1_FST),
+ IMX_PINCTRL_PIN(SC_P_ESAI1_SCKR),
+ IMX_PINCTRL_PIN(SC_P_ESAI1_SCKT),
+ IMX_PINCTRL_PIN(SC_P_ESAI1_TX0),
+ IMX_PINCTRL_PIN(SC_P_ESAI1_TX1),
+ IMX_PINCTRL_PIN(SC_P_ESAI1_TX2_RX3),
+ IMX_PINCTRL_PIN(SC_P_ESAI1_TX3_RX2),
+ IMX_PINCTRL_PIN(SC_P_ESAI1_TX4_RX1),
+ IMX_PINCTRL_PIN(SC_P_ESAI1_TX5_RX0),
+ IMX_PINCTRL_PIN(SC_P_SPDIF0_RX),
+ IMX_PINCTRL_PIN(SC_P_SPDIF0_TX),
+ IMX_PINCTRL_PIN(SC_P_SPDIF0_EXT_CLK),
+ IMX_PINCTRL_PIN(SC_P_SPI3_SCK),
+ IMX_PINCTRL_PIN(SC_P_SPI3_SDO),
+ IMX_PINCTRL_PIN(SC_P_SPI3_SDI),
+ IMX_PINCTRL_PIN(SC_P_SPI3_CS0),
+ IMX_PINCTRL_PIN(SC_P_SPI3_CS1),
+ IMX_PINCTRL_PIN(SC_P_COMP_CTL_GPIO_1V8_3V3_GPIORHB),
+ IMX_PINCTRL_PIN(SC_P_ESAI0_FSR),
+ IMX_PINCTRL_PIN(SC_P_ESAI0_FST),
+ IMX_PINCTRL_PIN(SC_P_ESAI0_SCKR),
+ IMX_PINCTRL_PIN(SC_P_ESAI0_SCKT),
+ IMX_PINCTRL_PIN(SC_P_ESAI0_TX0),
+ IMX_PINCTRL_PIN(SC_P_ESAI0_TX1),
+ IMX_PINCTRL_PIN(SC_P_ESAI0_TX2_RX3),
+ IMX_PINCTRL_PIN(SC_P_ESAI0_TX3_RX2),
+ IMX_PINCTRL_PIN(SC_P_ESAI0_TX4_RX1),
+ IMX_PINCTRL_PIN(SC_P_ESAI0_TX5_RX0),
+ IMX_PINCTRL_PIN(SC_P_MCLK_IN0),
+ IMX_PINCTRL_PIN(SC_P_MCLK_OUT0),
+ IMX_PINCTRL_PIN(SC_P_COMP_CTL_GPIO_1V8_3V3_GPIORHC),
+ IMX_PINCTRL_PIN(SC_P_SPI0_SCK),
+ IMX_PINCTRL_PIN(SC_P_SPI0_SDO),
+ IMX_PINCTRL_PIN(SC_P_SPI0_SDI),
+ IMX_PINCTRL_PIN(SC_P_SPI0_CS0),
+ IMX_PINCTRL_PIN(SC_P_SPI0_CS1),
+ IMX_PINCTRL_PIN(SC_P_SPI2_SCK),
+ IMX_PINCTRL_PIN(SC_P_SPI2_SDO),
+ IMX_PINCTRL_PIN(SC_P_SPI2_SDI),
+ IMX_PINCTRL_PIN(SC_P_SPI2_CS0),
+ IMX_PINCTRL_PIN(SC_P_SPI2_CS1),
+ IMX_PINCTRL_PIN(SC_P_SAI1_RXC),
+ IMX_PINCTRL_PIN(SC_P_SAI1_RXD),
+ IMX_PINCTRL_PIN(SC_P_SAI1_RXFS),
+ IMX_PINCTRL_PIN(SC_P_SAI1_TXC),
+ IMX_PINCTRL_PIN(SC_P_SAI1_TXD),
+ IMX_PINCTRL_PIN(SC_P_SAI1_TXFS),
+ IMX_PINCTRL_PIN(SC_P_COMP_CTL_GPIO_1V8_3V3_GPIORHT),
+ IMX_PINCTRL_PIN(SC_P_ADC_IN7),
+ IMX_PINCTRL_PIN(SC_P_ADC_IN6),
+ IMX_PINCTRL_PIN(SC_P_ADC_IN5),
+ IMX_PINCTRL_PIN(SC_P_ADC_IN4),
+ IMX_PINCTRL_PIN(SC_P_ADC_IN3),
+ IMX_PINCTRL_PIN(SC_P_ADC_IN2),
+ IMX_PINCTRL_PIN(SC_P_ADC_IN1),
+ IMX_PINCTRL_PIN(SC_P_ADC_IN0),
+ IMX_PINCTRL_PIN(SC_P_MLB_SIG),
+ IMX_PINCTRL_PIN(SC_P_MLB_CLK),
+ IMX_PINCTRL_PIN(SC_P_MLB_DATA),
+ IMX_PINCTRL_PIN(SC_P_COMP_CTL_GPIO_1V8_3V3_GPIOLHT),
+ IMX_PINCTRL_PIN(SC_P_FLEXCAN0_RX),
+ IMX_PINCTRL_PIN(SC_P_FLEXCAN0_TX),
+ IMX_PINCTRL_PIN(SC_P_FLEXCAN1_RX),
+ IMX_PINCTRL_PIN(SC_P_FLEXCAN1_TX),
+ IMX_PINCTRL_PIN(SC_P_FLEXCAN2_RX),
+ IMX_PINCTRL_PIN(SC_P_FLEXCAN2_TX),
+ IMX_PINCTRL_PIN(SC_P_COMP_CTL_GPIO_1V8_3V3_GPIOTHR),
+ IMX_PINCTRL_PIN(SC_P_USB_SS3_TC0),
+ IMX_PINCTRL_PIN(SC_P_USB_SS3_TC1),
+ IMX_PINCTRL_PIN(SC_P_USB_SS3_TC2),
+ IMX_PINCTRL_PIN(SC_P_USB_SS3_TC3),
+ IMX_PINCTRL_PIN(SC_P_COMP_CTL_GPIO_3V3_USB3IO),
+ IMX_PINCTRL_PIN(SC_P_USDHC1_RESET_B),
+ IMX_PINCTRL_PIN(SC_P_USDHC1_VSELECT),
+ IMX_PINCTRL_PIN(SC_P_USDHC2_RESET_B),
+ IMX_PINCTRL_PIN(SC_P_USDHC2_VSELECT),
+ IMX_PINCTRL_PIN(SC_P_USDHC2_WP),
+ IMX_PINCTRL_PIN(SC_P_USDHC2_CD_B),
+ IMX_PINCTRL_PIN(SC_P_COMP_CTL_GPIO_1V8_3V3_VSELSEP),
+ IMX_PINCTRL_PIN(SC_P_ENET0_MDIO),
+ IMX_PINCTRL_PIN(SC_P_ENET0_MDC),
+ IMX_PINCTRL_PIN(SC_P_ENET0_REFCLK_125M_25M),
+ IMX_PINCTRL_PIN(SC_P_ENET1_REFCLK_125M_25M),
+ IMX_PINCTRL_PIN(SC_P_ENET1_MDIO),
+ IMX_PINCTRL_PIN(SC_P_ENET1_MDC),
+ IMX_PINCTRL_PIN(SC_P_COMP_CTL_GPIO_1V8_3V3_GPIOCT),
+ IMX_PINCTRL_PIN(SC_P_QSPI1A_SS0_B),
+ IMX_PINCTRL_PIN(SC_P_QSPI1A_SS1_B),
+ IMX_PINCTRL_PIN(SC_P_QSPI1A_SCLK),
+ IMX_PINCTRL_PIN(SC_P_QSPI1A_DQS),
+ IMX_PINCTRL_PIN(SC_P_QSPI1A_DATA3),
+ IMX_PINCTRL_PIN(SC_P_QSPI1A_DATA2),
+ IMX_PINCTRL_PIN(SC_P_QSPI1A_DATA1),
+ IMX_PINCTRL_PIN(SC_P_QSPI1A_DATA0),
+ IMX_PINCTRL_PIN(SC_P_COMP_CTL_GPIO_1V8_3V3_QSPI1),
+ IMX_PINCTRL_PIN(SC_P_QSPI0A_DATA0),
+ IMX_PINCTRL_PIN(SC_P_QSPI0A_DATA1),
+ IMX_PINCTRL_PIN(SC_P_QSPI0A_DATA2),
+ IMX_PINCTRL_PIN(SC_P_QSPI0A_DATA3),
+ IMX_PINCTRL_PIN(SC_P_QSPI0A_DQS),
+ IMX_PINCTRL_PIN(SC_P_QSPI0A_SS0_B),
+ IMX_PINCTRL_PIN(SC_P_QSPI0A_SS1_B),
+ IMX_PINCTRL_PIN(SC_P_QSPI0A_SCLK),
+ IMX_PINCTRL_PIN(SC_P_QSPI0B_SCLK),
+ IMX_PINCTRL_PIN(SC_P_QSPI0B_DATA0),
+ IMX_PINCTRL_PIN(SC_P_QSPI0B_DATA1),
+ IMX_PINCTRL_PIN(SC_P_QSPI0B_DATA2),
+ IMX_PINCTRL_PIN(SC_P_QSPI0B_DATA3),
+ IMX_PINCTRL_PIN(SC_P_QSPI0B_DQS),
+ IMX_PINCTRL_PIN(SC_P_QSPI0B_SS0_B),
+ IMX_PINCTRL_PIN(SC_P_QSPI0B_SS1_B),
+ IMX_PINCTRL_PIN(SC_P_COMP_CTL_GPIO_1V8_3V3_QSPI0),
+ IMX_PINCTRL_PIN(SC_P_PCIE_CTRL0_CLKREQ_B),
+ IMX_PINCTRL_PIN(SC_P_PCIE_CTRL0_WAKE_B),
+ IMX_PINCTRL_PIN(SC_P_PCIE_CTRL0_PERST_B),
+ IMX_PINCTRL_PIN(SC_P_PCIE_CTRL1_CLKREQ_B),
+ IMX_PINCTRL_PIN(SC_P_PCIE_CTRL1_WAKE_B),
+ IMX_PINCTRL_PIN(SC_P_PCIE_CTRL1_PERST_B),
+ IMX_PINCTRL_PIN(SC_P_COMP_CTL_GPIO_1V8_3V3_PCIESEP),
+ IMX_PINCTRL_PIN(SC_P_USB_HSIC0_DATA),
+ IMX_PINCTRL_PIN(SC_P_USB_HSIC0_STROBE),
+ IMX_PINCTRL_PIN(SC_P_CALIBRATION_0_HSIC),
+ IMX_PINCTRL_PIN(SC_P_CALIBRATION_1_HSIC),
+ IMX_PINCTRL_PIN(SC_P_EMMC0_CLK),
+ IMX_PINCTRL_PIN(SC_P_EMMC0_CMD),
+ IMX_PINCTRL_PIN(SC_P_EMMC0_DATA0),
+ IMX_PINCTRL_PIN(SC_P_EMMC0_DATA1),
+ IMX_PINCTRL_PIN(SC_P_EMMC0_DATA2),
+ IMX_PINCTRL_PIN(SC_P_EMMC0_DATA3),
+ IMX_PINCTRL_PIN(SC_P_EMMC0_DATA4),
+ IMX_PINCTRL_PIN(SC_P_EMMC0_DATA5),
+ IMX_PINCTRL_PIN(SC_P_EMMC0_DATA6),
+ IMX_PINCTRL_PIN(SC_P_EMMC0_DATA7),
+ IMX_PINCTRL_PIN(SC_P_EMMC0_STROBE),
+ IMX_PINCTRL_PIN(SC_P_EMMC0_RESET_B),
+ IMX_PINCTRL_PIN(SC_P_COMP_CTL_GPIO_1V8_3V3_SD1FIX),
+ IMX_PINCTRL_PIN(SC_P_USDHC1_CLK),
+ IMX_PINCTRL_PIN(SC_P_USDHC1_CMD),
+ IMX_PINCTRL_PIN(SC_P_USDHC1_DATA0),
+ IMX_PINCTRL_PIN(SC_P_USDHC1_DATA1),
+ IMX_PINCTRL_PIN(SC_P_CTL_NAND_RE_P_N),
+ IMX_PINCTRL_PIN(SC_P_USDHC1_DATA2),
+ IMX_PINCTRL_PIN(SC_P_USDHC1_DATA3),
+ IMX_PINCTRL_PIN(SC_P_CTL_NAND_DQS_P_N),
+ IMX_PINCTRL_PIN(SC_P_USDHC1_DATA4),
+ IMX_PINCTRL_PIN(SC_P_USDHC1_DATA5),
+ IMX_PINCTRL_PIN(SC_P_USDHC1_DATA6),
+ IMX_PINCTRL_PIN(SC_P_USDHC1_DATA7),
+ IMX_PINCTRL_PIN(SC_P_USDHC1_STROBE),
+ IMX_PINCTRL_PIN(SC_P_COMP_CTL_GPIO_1V8_3V3_VSEL2),
+ IMX_PINCTRL_PIN(SC_P_USDHC2_CLK),
+ IMX_PINCTRL_PIN(SC_P_USDHC2_CMD),
+ IMX_PINCTRL_PIN(SC_P_USDHC2_DATA0),
+ IMX_PINCTRL_PIN(SC_P_USDHC2_DATA1),
+ IMX_PINCTRL_PIN(SC_P_USDHC2_DATA2),
+ IMX_PINCTRL_PIN(SC_P_USDHC2_DATA3),
+ IMX_PINCTRL_PIN(SC_P_COMP_CTL_GPIO_1V8_3V3_VSEL3),
+ IMX_PINCTRL_PIN(SC_P_ENET0_RGMII_TXC),
+ IMX_PINCTRL_PIN(SC_P_ENET0_RGMII_TX_CTL),
+ IMX_PINCTRL_PIN(SC_P_ENET0_RGMII_TXD0),
+ IMX_PINCTRL_PIN(SC_P_ENET0_RGMII_TXD1),
+ IMX_PINCTRL_PIN(SC_P_ENET0_RGMII_TXD2),
+ IMX_PINCTRL_PIN(SC_P_ENET0_RGMII_TXD3),
+ IMX_PINCTRL_PIN(SC_P_ENET0_RGMII_RXC),
+ IMX_PINCTRL_PIN(SC_P_ENET0_RGMII_RX_CTL),
+ IMX_PINCTRL_PIN(SC_P_ENET0_RGMII_RXD0),
+ IMX_PINCTRL_PIN(SC_P_ENET0_RGMII_RXD1),
+ IMX_PINCTRL_PIN(SC_P_ENET0_RGMII_RXD2),
+ IMX_PINCTRL_PIN(SC_P_ENET0_RGMII_RXD3),
+ IMX_PINCTRL_PIN(SC_P_COMP_CTL_GPIO_1V8_3V3_ENET_ENETB),
+ IMX_PINCTRL_PIN(SC_P_ENET1_RGMII_TXC),
+ IMX_PINCTRL_PIN(SC_P_ENET1_RGMII_TX_CTL),
+ IMX_PINCTRL_PIN(SC_P_ENET1_RGMII_TXD0),
+ IMX_PINCTRL_PIN(SC_P_ENET1_RGMII_TXD1),
+ IMX_PINCTRL_PIN(SC_P_ENET1_RGMII_TXD2),
+ IMX_PINCTRL_PIN(SC_P_ENET1_RGMII_TXD3),
+ IMX_PINCTRL_PIN(SC_P_ENET1_RGMII_RXC),
+ IMX_PINCTRL_PIN(SC_P_ENET1_RGMII_RX_CTL),
+ IMX_PINCTRL_PIN(SC_P_ENET1_RGMII_RXD0),
+ IMX_PINCTRL_PIN(SC_P_ENET1_RGMII_RXD1),
+ IMX_PINCTRL_PIN(SC_P_ENET1_RGMII_RXD2),
+ IMX_PINCTRL_PIN(SC_P_ENET1_RGMII_RXD3),
+ IMX_PINCTRL_PIN(SC_P_COMP_CTL_GPIO_1V8_3V3_ENET_ENETA),
+};
+
+static struct imx_pinctrl_soc_info imx8qm_pinctrl_info = {
+ .pins = imx8qm_pinctrl_pads,
+ .npins = ARRAY_SIZE(imx8qm_pinctrl_pads),
+ .flags = IMX8_USE_SCU | SHARE_MUX_CONF_REG
+ | IMX8_ENABLE_MUX_CONFIG | IMX8_ENABLE_PAD_CONFIG,
+};
+
+static struct of_device_id imx8qm_pinctrl_of_match[] = {
+ { .compatible = "fsl,imx8qm-iomuxc", },
+ { /* sentinel */ }
+};
+
+static int imx8qm_pinctrl_probe(struct platform_device *pdev)
+{
+ uint32_t mu_id;
+ sc_err_t sciErr = SC_ERR_NONE;
+
+ sciErr = sc_ipc_getMuID(&mu_id);
+ if (sciErr != SC_ERR_NONE) {
+ pr_info("pinctrl: Cannot obtain MU ID\n");
+ return sciErr;
+ }
+
+ sciErr = sc_ipc_open(&pinctrl_ipcHandle, mu_id);
+
+ if (sciErr != SC_ERR_NONE) {
+ pr_info("pinctrl: Cannot open MU channel to SCU\n");
+ return sciErr;
+ };
+
+ return imx_pinctrl_probe(pdev, &imx8qm_pinctrl_info);
+}
+
+static struct platform_driver imx8qm_pinctrl_driver = {
+ .driver = {
+ .name = "imx8qm-pinctrl",
+ .owner = THIS_MODULE,
+ .of_match_table = of_match_ptr(imx8qm_pinctrl_of_match),
+ },
+ .probe = imx8qm_pinctrl_probe,
+};
+
+static int __init imx8qm_pinctrl_init(void)
+{
+ return platform_driver_register(&imx8qm_pinctrl_driver);
+}
+arch_initcall(imx8qm_pinctrl_init);
+
+static void __exit imx8qm_pinctrl_exit(void)
+{
+ platform_driver_unregister(&imx8qm_pinctrl_driver);
+}
+module_exit(imx8qm_pinctrl_exit);
+
+MODULE_AUTHOR("Anson Huang <Anson.Huang@nxp.com>");
+MODULE_DESCRIPTION("Freescale imx8qm pinctrl driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/pinctrl/freescale/pinctrl-imx8qxp.c b/drivers/pinctrl/freescale/pinctrl-imx8qxp.c
new file mode 100644
index 000000000000..120c282771bf
--- /dev/null
+++ b/drivers/pinctrl/freescale/pinctrl-imx8qxp.c
@@ -0,0 +1,263 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017 NXP
+ *
+ * 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/err.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/pinctrl/pinctrl.h>
+#include <dt-bindings/pinctrl/pads-imx8qxp.h>
+#include <soc/imx8/sc/sci.h>
+
+#include "pinctrl-imx.h"
+
+extern sc_ipc_t pinctrl_ipcHandle;
+
+static const struct pinctrl_pin_desc imx8qxp_pinctrl_pads[] = {
+ IMX_PINCTRL_PIN(SC_P_PCIE_CTRL0_PERST_B),
+ IMX_PINCTRL_PIN(SC_P_PCIE_CTRL0_CLKREQ_B),
+ IMX_PINCTRL_PIN(SC_P_PCIE_CTRL0_WAKE_B),
+ IMX_PINCTRL_PIN(SC_P_COMP_CTL_GPIO_1V8_3V3_PCIESEP),
+ IMX_PINCTRL_PIN(SC_P_USB_SS3_TC0),
+ IMX_PINCTRL_PIN(SC_P_USB_SS3_TC1),
+ IMX_PINCTRL_PIN(SC_P_USB_SS3_TC2),
+ IMX_PINCTRL_PIN(SC_P_USB_SS3_TC3),
+ IMX_PINCTRL_PIN(SC_P_COMP_CTL_GPIO_3V3_USB3IO),
+ IMX_PINCTRL_PIN(SC_P_EMMC0_CLK),
+ IMX_PINCTRL_PIN(SC_P_EMMC0_CMD),
+ IMX_PINCTRL_PIN(SC_P_EMMC0_DATA0),
+ IMX_PINCTRL_PIN(SC_P_EMMC0_DATA1),
+ IMX_PINCTRL_PIN(SC_P_EMMC0_DATA2),
+ IMX_PINCTRL_PIN(SC_P_EMMC0_DATA3),
+ IMX_PINCTRL_PIN(SC_P_COMP_CTL_GPIO_1V8_3V3_SD1FIX0),
+ IMX_PINCTRL_PIN(SC_P_EMMC0_DATA4),
+ IMX_PINCTRL_PIN(SC_P_EMMC0_DATA5),
+ IMX_PINCTRL_PIN(SC_P_EMMC0_DATA6),
+ IMX_PINCTRL_PIN(SC_P_EMMC0_DATA7),
+ IMX_PINCTRL_PIN(SC_P_EMMC0_STROBE),
+ IMX_PINCTRL_PIN(SC_P_EMMC0_RESET_B),
+ IMX_PINCTRL_PIN(SC_P_COMP_CTL_GPIO_1V8_3V3_SD1FIX1),
+ IMX_PINCTRL_PIN(SC_P_USDHC1_RESET_B),
+ IMX_PINCTRL_PIN(SC_P_USDHC1_VSELECT),
+ IMX_PINCTRL_PIN(SC_P_CTL_NAND_RE_P_N),
+ IMX_PINCTRL_PIN(SC_P_USDHC1_WP),
+ IMX_PINCTRL_PIN(SC_P_USDHC1_CD_B),
+ IMX_PINCTRL_PIN(SC_P_CTL_NAND_DQS_P_N),
+ IMX_PINCTRL_PIN(SC_P_COMP_CTL_GPIO_1V8_3V3_VSELSEP),
+ IMX_PINCTRL_PIN(SC_P_USDHC1_CLK),
+ IMX_PINCTRL_PIN(SC_P_USDHC1_CMD),
+ IMX_PINCTRL_PIN(SC_P_USDHC1_DATA0),
+ IMX_PINCTRL_PIN(SC_P_USDHC1_DATA1),
+ IMX_PINCTRL_PIN(SC_P_USDHC1_DATA2),
+ IMX_PINCTRL_PIN(SC_P_USDHC1_DATA3),
+ IMX_PINCTRL_PIN(SC_P_COMP_CTL_GPIO_1V8_3V3_VSEL3),
+ IMX_PINCTRL_PIN(SC_P_ENET0_RGMII_TXC),
+ IMX_PINCTRL_PIN(SC_P_ENET0_RGMII_TX_CTL),
+ IMX_PINCTRL_PIN(SC_P_ENET0_RGMII_TXD0),
+ IMX_PINCTRL_PIN(SC_P_ENET0_RGMII_TXD1),
+ IMX_PINCTRL_PIN(SC_P_ENET0_RGMII_TXD2),
+ IMX_PINCTRL_PIN(SC_P_ENET0_RGMII_TXD3),
+ IMX_PINCTRL_PIN(SC_P_COMP_CTL_GPIO_1V8_3V3_ENET_ENETB0),
+ IMX_PINCTRL_PIN(SC_P_ENET0_RGMII_RXC),
+ IMX_PINCTRL_PIN(SC_P_ENET0_RGMII_RX_CTL),
+ IMX_PINCTRL_PIN(SC_P_ENET0_RGMII_RXD0),
+ IMX_PINCTRL_PIN(SC_P_ENET0_RGMII_RXD1),
+ IMX_PINCTRL_PIN(SC_P_ENET0_RGMII_RXD2),
+ IMX_PINCTRL_PIN(SC_P_ENET0_RGMII_RXD3),
+ IMX_PINCTRL_PIN(SC_P_COMP_CTL_GPIO_1V8_3V3_ENET_ENETB1),
+ IMX_PINCTRL_PIN(SC_P_ENET0_REFCLK_125M_25M),
+ IMX_PINCTRL_PIN(SC_P_ENET0_MDIO),
+ IMX_PINCTRL_PIN(SC_P_ENET0_MDC),
+ IMX_PINCTRL_PIN(SC_P_COMP_CTL_GPIO_1V8_3V3_GPIOCT),
+ IMX_PINCTRL_PIN(SC_P_ESAI0_FSR),
+ IMX_PINCTRL_PIN(SC_P_ESAI0_FST),
+ IMX_PINCTRL_PIN(SC_P_ESAI0_SCKR),
+ IMX_PINCTRL_PIN(SC_P_ESAI0_SCKT),
+ IMX_PINCTRL_PIN(SC_P_ESAI0_TX0),
+ IMX_PINCTRL_PIN(SC_P_ESAI0_TX1),
+ IMX_PINCTRL_PIN(SC_P_ESAI0_TX2_RX3),
+ IMX_PINCTRL_PIN(SC_P_ESAI0_TX3_RX2),
+ IMX_PINCTRL_PIN(SC_P_ESAI0_TX4_RX1),
+ IMX_PINCTRL_PIN(SC_P_ESAI0_TX5_RX0),
+ IMX_PINCTRL_PIN(SC_P_SPDIF0_RX),
+ IMX_PINCTRL_PIN(SC_P_SPDIF0_TX),
+ IMX_PINCTRL_PIN(SC_P_SPDIF0_EXT_CLK),
+ IMX_PINCTRL_PIN(SC_P_COMP_CTL_GPIO_1V8_3V3_GPIORHB),
+ IMX_PINCTRL_PIN(SC_P_SPI3_SCK),
+ IMX_PINCTRL_PIN(SC_P_SPI3_SDO),
+ IMX_PINCTRL_PIN(SC_P_SPI3_SDI),
+ IMX_PINCTRL_PIN(SC_P_SPI3_CS0),
+ IMX_PINCTRL_PIN(SC_P_SPI3_CS1),
+ IMX_PINCTRL_PIN(SC_P_MCLK_IN1),
+ IMX_PINCTRL_PIN(SC_P_MCLK_IN0),
+ IMX_PINCTRL_PIN(SC_P_MCLK_OUT0),
+ IMX_PINCTRL_PIN(SC_P_UART1_TX),
+ IMX_PINCTRL_PIN(SC_P_UART1_RX),
+ IMX_PINCTRL_PIN(SC_P_UART1_RTS_B),
+ IMX_PINCTRL_PIN(SC_P_UART1_CTS_B),
+ IMX_PINCTRL_PIN(SC_P_COMP_CTL_GPIO_1V8_3V3_GPIORHK),
+ IMX_PINCTRL_PIN(SC_P_SAI0_TXD),
+ IMX_PINCTRL_PIN(SC_P_SAI0_TXC),
+ IMX_PINCTRL_PIN(SC_P_SAI0_RXD),
+ IMX_PINCTRL_PIN(SC_P_SAI0_TXFS),
+ IMX_PINCTRL_PIN(SC_P_SAI1_RXD),
+ IMX_PINCTRL_PIN(SC_P_SAI1_RXC),
+ IMX_PINCTRL_PIN(SC_P_SAI1_RXFS),
+ IMX_PINCTRL_PIN(SC_P_SPI2_CS0),
+ IMX_PINCTRL_PIN(SC_P_SPI2_SDO),
+ IMX_PINCTRL_PIN(SC_P_SPI2_SDI),
+ IMX_PINCTRL_PIN(SC_P_SPI2_SCK),
+ IMX_PINCTRL_PIN(SC_P_SPI0_SCK),
+ IMX_PINCTRL_PIN(SC_P_SPI0_SDI),
+ IMX_PINCTRL_PIN(SC_P_SPI0_SDO),
+ IMX_PINCTRL_PIN(SC_P_SPI0_CS1),
+ IMX_PINCTRL_PIN(SC_P_SPI0_CS0),
+ IMX_PINCTRL_PIN(SC_P_COMP_CTL_GPIO_1V8_3V3_GPIORHT),
+ IMX_PINCTRL_PIN(SC_P_ADC_IN1),
+ IMX_PINCTRL_PIN(SC_P_ADC_IN0),
+ IMX_PINCTRL_PIN(SC_P_ADC_IN3),
+ IMX_PINCTRL_PIN(SC_P_ADC_IN2),
+ IMX_PINCTRL_PIN(SC_P_ADC_IN5),
+ IMX_PINCTRL_PIN(SC_P_ADC_IN4),
+ IMX_PINCTRL_PIN(SC_P_FLEXCAN0_RX),
+ IMX_PINCTRL_PIN(SC_P_FLEXCAN0_TX),
+ IMX_PINCTRL_PIN(SC_P_FLEXCAN1_RX),
+ IMX_PINCTRL_PIN(SC_P_FLEXCAN1_TX),
+ IMX_PINCTRL_PIN(SC_P_FLEXCAN2_RX),
+ IMX_PINCTRL_PIN(SC_P_FLEXCAN2_TX),
+ IMX_PINCTRL_PIN(SC_P_UART0_RX),
+ IMX_PINCTRL_PIN(SC_P_UART0_TX),
+ IMX_PINCTRL_PIN(SC_P_UART2_TX),
+ IMX_PINCTRL_PIN(SC_P_UART2_RX),
+ IMX_PINCTRL_PIN(SC_P_COMP_CTL_GPIO_1V8_3V3_GPIOLH),
+ IMX_PINCTRL_PIN(SC_P_MIPI_DSI0_I2C0_SCL),
+ IMX_PINCTRL_PIN(SC_P_MIPI_DSI0_I2C0_SDA),
+ IMX_PINCTRL_PIN(SC_P_MIPI_DSI0_GPIO0_00),
+ IMX_PINCTRL_PIN(SC_P_MIPI_DSI0_GPIO0_01),
+ IMX_PINCTRL_PIN(SC_P_MIPI_DSI1_I2C0_SCL),
+ IMX_PINCTRL_PIN(SC_P_MIPI_DSI1_I2C0_SDA),
+ IMX_PINCTRL_PIN(SC_P_MIPI_DSI1_GPIO0_00),
+ IMX_PINCTRL_PIN(SC_P_MIPI_DSI1_GPIO0_01),
+ IMX_PINCTRL_PIN(SC_P_COMP_CTL_GPIO_1V8_3V3_MIPIDSIGPIO),
+ IMX_PINCTRL_PIN(SC_P_JTAG_TRST_B),
+ IMX_PINCTRL_PIN(SC_P_PMIC_I2C_SCL),
+ IMX_PINCTRL_PIN(SC_P_PMIC_I2C_SDA),
+ IMX_PINCTRL_PIN(SC_P_PMIC_INT_B),
+ IMX_PINCTRL_PIN(SC_P_SCU_GPIO0_00),
+ IMX_PINCTRL_PIN(SC_P_SCU_GPIO0_01),
+ IMX_PINCTRL_PIN(SC_P_SCU_PMIC_STANDBY),
+ IMX_PINCTRL_PIN(SC_P_SCU_BOOT_MODE0),
+ IMX_PINCTRL_PIN(SC_P_SCU_BOOT_MODE1),
+ IMX_PINCTRL_PIN(SC_P_SCU_BOOT_MODE2),
+ IMX_PINCTRL_PIN(SC_P_SCU_BOOT_MODE3),
+ IMX_PINCTRL_PIN(SC_P_CSI_D00),
+ IMX_PINCTRL_PIN(SC_P_CSI_D01),
+ IMX_PINCTRL_PIN(SC_P_CSI_D02),
+ IMX_PINCTRL_PIN(SC_P_CSI_D03),
+ IMX_PINCTRL_PIN(SC_P_CSI_D04),
+ IMX_PINCTRL_PIN(SC_P_CSI_D05),
+ IMX_PINCTRL_PIN(SC_P_CSI_D06),
+ IMX_PINCTRL_PIN(SC_P_CSI_D07),
+ IMX_PINCTRL_PIN(SC_P_CSI_HSYNC),
+ IMX_PINCTRL_PIN(SC_P_CSI_VSYNC),
+ IMX_PINCTRL_PIN(SC_P_CSI_PCLK),
+ IMX_PINCTRL_PIN(SC_P_CSI_MCLK),
+ IMX_PINCTRL_PIN(SC_P_CSI_EN),
+ IMX_PINCTRL_PIN(SC_P_CSI_RESET),
+ IMX_PINCTRL_PIN(SC_P_COMP_CTL_GPIO_1V8_3V3_GPIORHD),
+ IMX_PINCTRL_PIN(SC_P_MIPI_CSI0_MCLK_OUT),
+ IMX_PINCTRL_PIN(SC_P_MIPI_CSI0_I2C0_SCL),
+ IMX_PINCTRL_PIN(SC_P_MIPI_CSI0_I2C0_SDA),
+ IMX_PINCTRL_PIN(SC_P_MIPI_CSI0_GPIO0_01),
+ IMX_PINCTRL_PIN(SC_P_MIPI_CSI0_GPIO0_00),
+ IMX_PINCTRL_PIN(SC_P_QSPI0A_DATA0),
+ IMX_PINCTRL_PIN(SC_P_QSPI0A_DATA1),
+ IMX_PINCTRL_PIN(SC_P_QSPI0A_DATA2),
+ IMX_PINCTRL_PIN(SC_P_QSPI0A_DATA3),
+ IMX_PINCTRL_PIN(SC_P_QSPI0A_DQS),
+ IMX_PINCTRL_PIN(SC_P_QSPI0A_SS0_B),
+ IMX_PINCTRL_PIN(SC_P_QSPI0A_SS1_B),
+ IMX_PINCTRL_PIN(SC_P_QSPI0A_SCLK),
+ IMX_PINCTRL_PIN(SC_P_COMP_CTL_GPIO_1V8_3V3_QSPI0A),
+ IMX_PINCTRL_PIN(SC_P_QSPI0B_SCLK),
+ IMX_PINCTRL_PIN(SC_P_QSPI0B_DATA0),
+ IMX_PINCTRL_PIN(SC_P_QSPI0B_DATA1),
+ IMX_PINCTRL_PIN(SC_P_QSPI0B_DATA2),
+ IMX_PINCTRL_PIN(SC_P_QSPI0B_DATA3),
+ IMX_PINCTRL_PIN(SC_P_QSPI0B_DQS),
+ IMX_PINCTRL_PIN(SC_P_QSPI0B_SS0_B),
+ IMX_PINCTRL_PIN(SC_P_QSPI0B_SS1_B),
+ IMX_PINCTRL_PIN(SC_P_COMP_CTL_GPIO_1V8_3V3_QSPI0B),
+};
+
+static struct imx_pinctrl_soc_info imx8qxp_pinctrl_info = {
+ .pins = imx8qxp_pinctrl_pads,
+ .npins = ARRAY_SIZE(imx8qxp_pinctrl_pads),
+ .flags = IMX8_USE_SCU | SHARE_MUX_CONF_REG
+ | IMX8_ENABLE_MUX_CONFIG | IMX8_ENABLE_PAD_CONFIG,
+};
+
+static struct of_device_id imx8qxp_pinctrl_of_match[] = {
+ { .compatible = "fsl,imx8qxp-iomuxc", },
+ { /* sentinel */ }
+};
+
+static int imx8qxp_pinctrl_probe(struct platform_device *pdev)
+{
+ uint32_t mu_id;
+ sc_err_t sciErr = SC_ERR_NONE;
+
+ sciErr = sc_ipc_getMuID(&mu_id);
+ if (sciErr != SC_ERR_NONE) {
+ pr_info("pinctrl: Cannot obtain MU ID\n");
+ return sciErr;
+ }
+
+ sciErr = sc_ipc_open(&pinctrl_ipcHandle, mu_id);
+
+ if (sciErr != SC_ERR_NONE) {
+ pr_info("pinctrl: Cannot open MU channel to SCU\n");
+ return sciErr;
+ };
+
+ return imx_pinctrl_probe(pdev, &imx8qxp_pinctrl_info);
+}
+
+static struct platform_driver imx8qxp_pinctrl_driver = {
+ .driver = {
+ .name = "imx8qxp-pinctrl",
+ .owner = THIS_MODULE,
+ .of_match_table = of_match_ptr(imx8qxp_pinctrl_of_match),
+ },
+ .probe = imx8qxp_pinctrl_probe,
+};
+
+static int __init imx8qxp_pinctrl_init(void)
+{
+ return platform_driver_register(&imx8qxp_pinctrl_driver);
+}
+arch_initcall(imx8qxp_pinctrl_init);
+
+static void __exit imx8qxp_pinctrl_exit(void)
+{
+ platform_driver_unregister(&imx8qxp_pinctrl_driver);
+}
+module_exit(imx8qxp_pinctrl_exit);
+
+MODULE_AUTHOR("Peng Fan <peng.fan@nxp.com>");
+MODULE_DESCRIPTION("Freescale imx8qxp pinctrl driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/pinctrl/freescale/pinctrl-memmap.c b/drivers/pinctrl/freescale/pinctrl-memmap.c
new file mode 100644
index 000000000000..963fab100d9d
--- /dev/null
+++ b/drivers/pinctrl/freescale/pinctrl-memmap.c
@@ -0,0 +1,212 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017 NXP
+ *
+ * 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/err.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/pinctrl/machine.h>
+#include <linux/pinctrl/pinconf.h>
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/pinctrl/pinmux.h>
+#include <linux/slab.h>
+
+#include "../core.h"
+#include "pinctrl-imx.h"
+
+#define IMX_PAD_SION 0x40000000 /* set SION */
+
+int imx_pmx_set_one_pin_mem(struct imx_pinctrl *ipctl, struct imx_pin *pin)
+{
+ const struct imx_pinctrl_soc_info *info = ipctl->info;
+ unsigned int pin_id = pin->pin;
+ struct imx_pin_reg *pin_reg;
+ struct imx_pin_memmap *pin_memmap;
+ pin_reg = &info->pin_regs[pin_id];
+ pin_memmap = &pin->pin_conf.pin_memmap;
+
+ if (pin_reg->mux_reg == -1) {
+ dev_err(ipctl->dev, "Pin(%s) does not support mux function\n",
+ info->pins[pin_id].name);
+ return 0;
+ }
+
+ if (info->flags & SHARE_MUX_CONF_REG) {
+ u32 reg;
+ reg = readl(ipctl->base + pin_reg->mux_reg);
+ reg &= ~info->mux_mask;
+ reg |= (pin_memmap->mux_mode << info->mux_shift);
+ writel(reg, ipctl->base + pin_reg->mux_reg);
+ dev_dbg(ipctl->dev, "write: offset 0x%x val 0x%x\n",
+ pin_reg->mux_reg, reg);
+ } else {
+ writel(pin_memmap->mux_mode, ipctl->base + pin_reg->mux_reg);
+ dev_dbg(ipctl->dev, "write: offset 0x%x val 0x%x\n",
+ pin_reg->mux_reg, pin_memmap->mux_mode);
+ }
+
+ /*
+ * If the select input value begins with 0xff, it's a quirky
+ * select input and the value should be interpreted as below.
+ * 31 23 15 7 0
+ * | 0xff | shift | width | select |
+ * It's used to work around the problem that the select
+ * input for some pin is not implemented in the select
+ * input register but in some general purpose register.
+ * We encode the select input value, width and shift of
+ * the bit field into input_val cell of pin function ID
+ * in device tree, and then decode them here for setting
+ * up the select input bits in general purpose register.
+ */
+ if (pin_memmap->input_val >> 24 == 0xff) {
+ u32 val = pin_memmap->input_val;
+ u8 select = val & 0xff;
+ u8 width = (val >> 8) & 0xff;
+ u8 shift = (val >> 16) & 0xff;
+ u32 mask = ((1 << width) - 1) << shift;
+ /*
+ * The input_reg[i] here is actually some IOMUXC general
+ * purpose register, not regular select input register.
+ */
+ val = readl(ipctl->base + pin_memmap->input_reg);
+ val &= ~mask;
+ val |= select << shift;
+ writel(val, ipctl->base + pin_memmap->input_reg);
+ } else if (pin_memmap->input_reg) {
+ /*
+ * Regular select input register can never be at offset
+ * 0, and we only print register value for regular case.
+ */
+ if (ipctl->input_sel_base)
+ writel(pin_memmap->input_val, ipctl->input_sel_base +
+ pin_memmap->input_reg);
+ else
+ writel(pin_memmap->input_val, ipctl->base +
+ pin_memmap->input_reg);
+ dev_dbg(ipctl->dev,
+ "==>select_input: offset 0x%x val 0x%x\n",
+ pin_memmap->input_reg, pin_memmap->input_val);
+ }
+
+ return 0;
+}
+
+int imx_pinconf_backend_get_mem(struct pinctrl_dev *pctldev,
+ unsigned pin_id, unsigned long *config)
+{
+ struct imx_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev);
+ struct imx_pinctrl_soc_info *info = ipctl->info;
+ const struct imx_pin_reg *pin_reg = &info->pin_regs[pin_id];
+
+ if (pin_reg->conf_reg == -1) {
+ dev_err(info->dev, "Pin(%s) does not support config function\n",
+ info->pins[pin_id].name);
+ return -EINVAL;
+ }
+
+ *config = readl(ipctl->base + pin_reg->conf_reg);
+
+ if (info->flags & SHARE_MUX_CONF_REG)
+ *config &= ~info->mux_mask;
+
+ return 0;
+}
+
+int imx_pinconf_backend_set_mem(struct pinctrl_dev *pctldev,
+ unsigned pin_id, unsigned long *configs,
+ unsigned num_configs)
+{
+ struct imx_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev);
+ struct imx_pinctrl_soc_info *info = ipctl->info;
+ const struct imx_pin_reg *pin_reg = &info->pin_regs[pin_id];
+ int i;
+
+ if (pin_reg->conf_reg == -1) {
+ dev_err(info->dev, "Pin(%s) does not support config function\n",
+ info->pins[pin_id].name);
+ return -EINVAL;
+ }
+
+ dev_dbg(ipctl->dev, "pinconf set pin %s\n",
+ info->pins[pin_id].name);
+
+ for (i = 0; i < num_configs; i++) {
+ if (info->flags & SHARE_MUX_CONF_REG) {
+ u32 reg;
+ reg = readl(ipctl->base + pin_reg->conf_reg);
+ reg &= info->mux_mask;
+ reg |= configs[i];
+ writel(reg, ipctl->base + pin_reg->conf_reg);
+ dev_dbg(ipctl->dev, "write: offset 0x%x val 0x%x\n",
+ pin_reg->conf_reg, reg);
+ } else {
+ writel(configs[i], ipctl->base + pin_reg->conf_reg);
+ dev_dbg(ipctl->dev, "write: offset 0x%x val 0x%lx\n",
+ pin_reg->conf_reg, configs[i]);
+ }
+ } /* for each config */
+
+ return 0;
+}
+
+int imx_pinctrl_parse_pin_mem(struct imx_pinctrl_soc_info *info,
+ unsigned int *grp_pin_id, struct imx_pin *pin,
+ const __be32 **list_p, u32 generic_config)
+{
+ struct imx_pin_memmap *pin_memmap = &pin->pin_conf.pin_memmap;
+ u32 mux_reg = be32_to_cpu(*((*list_p)++));
+ u32 conf_reg;
+ u32 config;
+ unsigned int pin_id;
+ struct imx_pin_reg *pin_reg;
+
+ if (info->flags & SHARE_MUX_CONF_REG) {
+ conf_reg = mux_reg;
+ } else {
+ conf_reg = be32_to_cpu(*((*list_p)++));
+ if (!conf_reg)
+ conf_reg = -1;
+ }
+
+ pin_id = (mux_reg != -1) ? mux_reg / 4 : conf_reg / 4;
+ pin_reg = &info->pin_regs[pin_id];
+ pin->pin = pin_id;
+ *grp_pin_id = pin_id;
+ pin_reg->mux_reg = mux_reg;
+ pin_reg->conf_reg = conf_reg;
+ pin_memmap->input_reg = be32_to_cpu(*((*list_p)++));
+ pin_memmap->mux_mode = be32_to_cpu(*((*list_p)++));
+ pin_memmap->input_val = be32_to_cpu((*(*list_p)++));
+
+ if (info->generic_pinconf) {
+ /* generic pin config decoded */
+ pin_memmap->config = generic_config;
+ } else {
+ /* legacy pin config read from devicetree */
+ config = be32_to_cpu(*((*list_p)++));
+
+ /* SION bit is in mux register */
+ if (config & IMX_PAD_SION)
+ pin_memmap->mux_mode |= IOMUXC_CONFIG_SION;
+ pin_memmap->config = config & ~IMX_PAD_SION;
+ }
+
+ dev_dbg(info->dev, "%s: 0x%x 0x%08lx", info->pins[pin_id].name,
+ pin_memmap->mux_mode, pin_memmap->config);
+
+ return 0;
+}
diff --git a/drivers/pinctrl/freescale/pinctrl-scu.c b/drivers/pinctrl/freescale/pinctrl-scu.c
new file mode 100644
index 000000000000..61dd50f565eb
--- /dev/null
+++ b/drivers/pinctrl/freescale/pinctrl-scu.c
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017 NXP
+ *
+ * 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/err.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/pinctrl/machine.h>
+#include <linux/pinctrl/pinconf.h>
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/pinctrl/pinmux.h>
+#include <linux/slab.h>
+#include <soc/imx8/sc/sci.h>
+
+#include "../core.h"
+#include "pinctrl-imx.h"
+
+sc_ipc_t pinctrl_ipcHandle;
+
+int imx_pmx_set_one_pin_scu(struct imx_pinctrl *ipctl, struct imx_pin *pin)
+{
+ return 0;
+}
+
+int imx_pinconf_backend_get_scu(struct pinctrl_dev *pctldev, unsigned pin_id,
+ unsigned long *config)
+{
+ sc_err_t err = SC_ERR_NONE;
+ sc_ipc_t ipc = pinctrl_ipcHandle;
+
+ if (ipc == -1) {
+ printk("IPC handle not initialized!\n");
+ return -EIO;
+ }
+
+ err = sc_pad_get(ipc, pin_id, (unsigned int *)config);
+
+ if (err != SC_ERR_NONE)
+ return -EIO;
+
+ return 0;
+}
+
+int imx_pinconf_backend_set_scu(struct pinctrl_dev *pctldev, unsigned pin_id,
+ unsigned long *configs, unsigned num_configs)
+{
+ sc_err_t err = SC_ERR_NONE;
+ sc_ipc_t ipc = pinctrl_ipcHandle;
+ struct imx_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev);
+ const struct imx_pinctrl_soc_info *info = ipctl->info;
+ /*
+ * Mux should be done in pmx set, but we do not have a good api
+ * to handle that in scfw, so config it in pad conf func
+ */
+ unsigned int mux = configs[0];
+ unsigned int val = configs[1];
+
+ if (ipc == -1) {
+ printk("IPC handle not initialized!\n");
+ return -EIO;
+ }
+
+ if (info->flags & IMX8_ENABLE_MUX_CONFIG)
+ val |= BM_IMX8_IFMUX_ENABLE;
+
+ if (info->flags & IMX8_ENABLE_PAD_CONFIG)
+ val |= BM_IMX8_GP_ENABLE;
+
+ if (info->flags & SHARE_MUX_CONF_REG) {
+ val |= (mux << 27) & (0x7 << 27);
+ err = sc_pad_set(ipc, pin_id, val);
+ }
+
+ if (err != SC_ERR_NONE)
+ return -EIO;
+
+ return 0;
+}
+
+int imx_pinctrl_parse_pin_scu(struct imx_pinctrl_soc_info *info,
+ unsigned int *pin_id, struct imx_pin *pin,
+ const __be32 **list_p, u32 generic_config)
+{
+ struct imx_pin_scu *pin_scu = &pin->pin_conf.pin_scu;
+
+ pin->pin = be32_to_cpu(*((*list_p)++));
+ *pin_id = pin->pin;
+ pin_scu->mux = be32_to_cpu(*((*list_p)++));
+ pin_scu->config = be32_to_cpu(*((*list_p)++));
+
+ dev_dbg(info->dev, "%s: 0x%lx 0x%lx",
+ info->pins[pin->pin].name, pin_scu->mux, pin_scu->config);
+
+ return 0;
+}
diff --git a/drivers/pinctrl/freescale/pinctrl-vf610.c b/drivers/pinctrl/freescale/pinctrl-vf610.c
index ac18bb6d6d5e..cfc9dfa68517 100644
--- a/drivers/pinctrl/freescale/pinctrl-vf610.c
+++ b/drivers/pinctrl/freescale/pinctrl-vf610.c
@@ -326,6 +326,8 @@ static struct imx_pinctrl_soc_info vf610_pinctrl_info = {
.gpio_set_direction = vf610_pmx_gpio_set_direction,
.mux_mask = 0x700000,
.mux_shift = 20,
+ .ibe_bit = BIT(0),
+ .obe_bit = BIT(1),
};
static const struct of_device_id vf610_pinctrl_of_match[] = {
diff --git a/drivers/power/supply/Kconfig b/drivers/power/supply/Kconfig
index 5ab90c1f3f7c..ea17cca4fb90 100644
--- a/drivers/power/supply/Kconfig
+++ b/drivers/power/supply/Kconfig
@@ -366,6 +366,12 @@ config CHARGER_PCF50633
help
Say Y to include support for NXP PCF50633 Main Battery Charger.
+config CHARGER_PF1550
+ tristate "Freescale PF1550 battery charger driver"
+ depends on MFD_PF1550
+ help
+ Say Y to enable support for the Freescale PF1550 battery charger.
+
config BATTERY_JZ4740
tristate "Ingenic JZ4740 battery"
depends on MACH_JZ4740
@@ -401,6 +407,14 @@ config CHARGER_ISP1704
Say Y to enable support for USB Charger Detection with
ISP1707/ISP1704 USB transceivers.
+config SABRESD_MAX8903
+ tristate "Sabresd Board Battery DC-DC Charger for USB and Adapter Power"
+ depends on TOUCHSCREEN_MAX11801
+ help
+ Say Y to enable support for the MAX8903 DC-DC charger and sysfs on
+ sabresd board.The driver supports controlling charger and battery
+ based on the status of charger connections with interrupt handlers.
+
config CHARGER_MAX8903
tristate "MAX8903 Battery DC-DC Charger for USB and Adapter Power"
help
diff --git a/drivers/power/supply/Makefile b/drivers/power/supply/Makefile
index aae4e4a8bbb3..c3f368601a54 100644
--- a/drivers/power/supply/Makefile
+++ b/drivers/power/supply/Makefile
@@ -54,11 +54,13 @@ obj-$(CONFIG_BATTERY_S3C_ADC) += s3c_adc_battery.o
obj-$(CONFIG_BATTERY_TWL4030_MADC) += twl4030_madc_battery.o
obj-$(CONFIG_CHARGER_88PM860X) += 88pm860x_charger.o
obj-$(CONFIG_CHARGER_PCF50633) += pcf50633-charger.o
+obj-$(CONFIG_CHARGER_PF1550) += pf1550_charger.o
obj-$(CONFIG_BATTERY_JZ4740) += jz4740-battery.o
obj-$(CONFIG_BATTERY_RX51) += rx51_battery.o
obj-$(CONFIG_AB8500_BM) += ab8500_bmdata.o ab8500_charger.o ab8500_fg.o ab8500_btemp.o abx500_chargalg.o pm2301_charger.o
obj-$(CONFIG_CHARGER_CPCAP) += cpcap-charger.o
obj-$(CONFIG_CHARGER_ISP1704) += isp1704_charger.o
+obj-$(CONFIG_SABRESD_MAX8903) += sabresd_battery.o
obj-$(CONFIG_CHARGER_MAX8903) += max8903_charger.o
obj-$(CONFIG_CHARGER_TWL4030) += twl4030_charger.o
obj-$(CONFIG_CHARGER_LP8727) += lp8727_charger.o
diff --git a/drivers/power/supply/pf1550_charger.c b/drivers/power/supply/pf1550_charger.c
new file mode 100644
index 000000000000..d14ef2b29ffd
--- /dev/null
+++ b/drivers/power/supply/pf1550_charger.c
@@ -0,0 +1,656 @@
+/*
+ * pf1550_charger.c - regulator driver for the PF1550
+ *
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Robin Gong <yibin.gong@freescale.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/interrupt.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/power_supply.h>
+#include <linux/regmap.h>
+#include <linux/mfd/pf1550.h>
+
+#define PF1550_CHARGER_NAME "pf1550-charger"
+#define PF1550_DEFAULT_CONSTANT_VOLT 4200000
+#define PF1550_DEFAULT_MIN_SYSTEM_VOLT 3500000
+#define PF1550_DEFAULT_THERMAL_TEMP 75
+
+static const char *pf1550_charger_model = "PF1550";
+static const char *pf1550_charger_manufacturer = "Freescale";
+
+struct pf1550_charger {
+ struct device *dev;
+ struct pf1550_dev *pf1550;
+ struct power_supply *charger;
+ struct power_supply_desc psy_desc;
+ int irq;
+ struct delayed_work irq_work;
+ struct mutex mutex;
+
+ u32 constant_volt;
+ u32 min_system_volt;
+ u32 thermal_regulation_temp;
+};
+
+static struct pf1550_irq_info pf1550_charger_irqs[] = {
+ { PF1550_CHARG_IRQ_BAT2SOCI, "BAT2SOC" },
+ { PF1550_CHARG_IRQ_BATI, "BAT" },
+ { PF1550_CHARG_IRQ_CHGI, "CHG" },
+ { PF1550_CHARG_IRQ_VBUSI, "VBUS" },
+ { PF1550_CHARG_IRQ_THMI, "THM" },
+};
+
+static int pf1550_get_charger_state(struct regmap *regmap, int *val)
+{
+ int ret;
+ unsigned int data;
+
+ ret = regmap_read(regmap, PF1550_CHARG_REG_CHG_SNS, &data);
+ if (ret < 0)
+ return ret;
+
+ data &= PF1550_CHG_SNS_MASK;
+
+ switch (data) {
+ case PF1550_CHG_PRECHARGE:
+ case PF1550_CHG_CONSTANT_CURRENT:
+ case PF1550_CHG_CONSTANT_VOL:
+ case PF1550_CHG_EOC:
+ *val = POWER_SUPPLY_STATUS_CHARGING;
+ break;
+ case PF1550_CHG_DONE:
+ *val = POWER_SUPPLY_STATUS_FULL;
+ break;
+ case PF1550_CHG_TIMER_FAULT:
+ case PF1550_CHG_SUSPEND:
+ *val = POWER_SUPPLY_STATUS_NOT_CHARGING;
+ break;
+ case PF1550_CHG_OFF_INV:
+ case PF1550_CHG_OFF_TEMP:
+ case PF1550_CHG_LINEAR_ONLY:
+ *val = POWER_SUPPLY_STATUS_DISCHARGING;
+ break;
+ default:
+ *val = POWER_SUPPLY_STATUS_UNKNOWN;
+ }
+
+ return 0;
+}
+
+static int pf1550_get_charge_type(struct regmap *regmap, int *val)
+{
+ int ret;
+ unsigned int data;
+
+ ret = regmap_read(regmap, PF1550_CHARG_REG_CHG_SNS, &data);
+ if (ret < 0)
+ return ret;
+
+ data &= PF1550_CHG_SNS_MASK;
+
+ switch (data) {
+ case PF1550_CHG_SNS_MASK:
+ *val = POWER_SUPPLY_CHARGE_TYPE_TRICKLE;
+ break;
+ case PF1550_CHG_CONSTANT_CURRENT:
+ case PF1550_CHG_CONSTANT_VOL:
+ case PF1550_CHG_EOC:
+ *val = POWER_SUPPLY_CHARGE_TYPE_FAST;
+ break;
+ case PF1550_CHG_DONE:
+ case PF1550_CHG_TIMER_FAULT:
+ case PF1550_CHG_SUSPEND:
+ case PF1550_CHG_OFF_INV:
+ case PF1550_CHG_BAT_OVER:
+ case PF1550_CHG_OFF_TEMP:
+ case PF1550_CHG_LINEAR_ONLY:
+ *val = POWER_SUPPLY_CHARGE_TYPE_NONE;
+ break;
+ default:
+ *val = POWER_SUPPLY_CHARGE_TYPE_UNKNOWN;
+ }
+
+ return 0;
+}
+
+/*
+ * Supported health statuses:
+ * - POWER_SUPPLY_HEALTH_DEAD
+ * - POWER_SUPPLY_HEALTH_GOOD
+ * - POWER_SUPPLY_HEALTH_OVERVOLTAGE
+ * - POWER_SUPPLY_HEALTH_UNKNOWN
+ */
+static int pf1550_get_battery_health(struct regmap *regmap, int *val)
+{
+ int ret;
+ unsigned int data;
+
+ ret = regmap_read(regmap, PF1550_CHARG_REG_BATT_SNS, &data);
+ if (ret < 0)
+ return ret;
+
+ data &= PF1550_BAT_SNS_MASK;
+
+ switch (data) {
+ case PF1550_BAT_NO_DETECT:
+ *val = POWER_SUPPLY_HEALTH_DEAD;
+ break;
+ case PF1550_BAT_NO_VBUS:
+ case PF1550_BAT_LOW_THAN_PRECHARG:
+ case PF1550_BAT_CHARG_FAIL:
+ case PF1550_BAT_HIGH_THAN_PRECHARG:
+ *val = POWER_SUPPLY_HEALTH_GOOD;
+ break;
+ case PF1550_BAT_OVER_VOL:
+ *val = POWER_SUPPLY_HEALTH_OVERVOLTAGE;
+ break;
+ default:
+ *val = POWER_SUPPLY_HEALTH_UNKNOWN;
+ break;
+ }
+
+ return 0;
+}
+
+static int pf1550_get_present(struct regmap *regmap, int *val)
+{
+ unsigned int data;
+ int ret;
+
+ ret = regmap_read(regmap, PF1550_CHARG_REG_BATT_SNS, &data);
+ if (ret < 0)
+ return ret;
+
+ data &= PF1550_BAT_SNS_MASK;
+ *val = (data == PF1550_BAT_NO_DETECT) ? 0 : 1;
+
+ return 0;
+}
+
+static int pf1550_get_online(struct regmap *regmap, int *val)
+{
+ unsigned int data;
+ int ret;
+
+ ret = regmap_read(regmap, PF1550_CHARG_REG_VBUS_SNS, &data);
+ if (ret < 0)
+ return ret;
+
+ *val = (data & PF1550_VBUS_VALID) ? 1 : 0;
+
+ return 0;
+}
+
+static void pf1550_chg_bat_isr(struct pf1550_charger *chg)
+{
+ unsigned int data;
+
+ if (regmap_read(chg->pf1550->regmap, PF1550_CHARG_REG_BATT_SNS, &data)) {
+ dev_err(chg->dev, "Read BATT_SNS error.\n");
+ return;
+ }
+
+ switch (data & PF1550_BAT_SNS_MASK) {
+ case PF1550_BAT_NO_VBUS:
+ dev_dbg(chg->dev, "No valid VBUS input.\n");
+ break;
+ case PF1550_BAT_LOW_THAN_PRECHARG:
+ dev_dbg(chg->dev, "VBAT < VPRECHG.LB.\n");
+ break;
+ case PF1550_BAT_CHARG_FAIL:
+ dev_dbg(chg->dev, "Battery charging failed.\n");
+ break;
+ case PF1550_BAT_HIGH_THAN_PRECHARG:
+ dev_dbg(chg->dev, "VBAT > VPRECHG.LB.\n");
+ break;
+ case PF1550_BAT_OVER_VOL:
+ dev_dbg(chg->dev, "VBAT > VBATOV.\n");
+ break;
+ case PF1550_BAT_NO_DETECT:
+ dev_dbg(chg->dev, "Battery not detected.\n");
+ break;
+ default:
+ dev_err(chg->dev, "Unknown value read:%x\n",
+ data & PF1550_CHG_SNS_MASK);
+ }
+}
+
+static void pf1550_chg_chg_isr(struct pf1550_charger *chg)
+{
+ unsigned int data;
+
+ if (regmap_read(chg->pf1550->regmap, PF1550_CHARG_REG_CHG_SNS, &data)) {
+ dev_err(chg->dev, "Read CHG_SNS error.\n");
+ return;
+ }
+
+ switch (data & PF1550_CHG_SNS_MASK) {
+ case PF1550_CHG_PRECHARGE:
+ dev_dbg(chg->dev, "In pre-charger mode.\n");
+ break;
+ case PF1550_CHG_CONSTANT_CURRENT:
+ dev_dbg(chg->dev, "In fast-charge constant current mode.\n");
+ break;
+ case PF1550_CHG_CONSTANT_VOL:
+ dev_dbg(chg->dev, "In fast-charge constant voltage mode.\n");
+ break;
+ case PF1550_CHG_EOC:
+ dev_dbg(chg->dev, "In EOC mode.\n");
+ break;
+ case PF1550_CHG_DONE:
+ dev_dbg(chg->dev, "In DONE mode.\n");
+ break;
+ case PF1550_CHG_TIMER_FAULT:
+ dev_info(chg->dev, "In timer fault mode.\n");
+ break;
+ case PF1550_CHG_SUSPEND:
+ dev_info(chg->dev, "In thermistor suspend mode.\n");
+ break;
+ case PF1550_CHG_OFF_INV:
+ dev_info(chg->dev, "Input invalid, charger off.\n");
+ break;
+ case PF1550_CHG_BAT_OVER:
+ dev_info(chg->dev, "Battery over-voltage.\n");
+ break;
+ case PF1550_CHG_OFF_TEMP:
+ dev_info(chg->dev, "Temp high, charger off.\n");
+ break;
+ case PF1550_CHG_LINEAR_ONLY:
+ dev_dbg(chg->dev, "In Linear mode, not charging.\n");
+ break;
+ default:
+ dev_err(chg->dev, "Unknown value read:%x\n",
+ data & PF1550_CHG_SNS_MASK);
+ }
+}
+
+static void pf1550_chg_vbus_isr(struct pf1550_charger *chg)
+{
+ enum power_supply_type old_type;
+ unsigned int data;
+
+ if (regmap_read(chg->pf1550->regmap, PF1550_CHARG_REG_VBUS_SNS, &data)) {
+ dev_err(chg->dev, "Read VBUS_SNS error.\n");
+ return;
+ }
+
+ old_type = chg->psy_desc.type;
+
+ if (data & PF1550_VBUS_UVLO) {
+ chg->psy_desc.type = POWER_SUPPLY_TYPE_BATTERY;
+ dev_dbg(chg->dev, "VBUS deattached.\n");
+ }
+ if (data & PF1550_VBUS_IN2SYS)
+ dev_dbg(chg->dev, "VBUS_IN2SYS_SNS.\n");
+ if (data & PF1550_VBUS_OVLO)
+ dev_dbg(chg->dev, "VBUS_OVLO_SNS.\n");
+ if (data & PF1550_VBUS_VALID) {
+ chg->psy_desc.type = POWER_SUPPLY_TYPE_MAINS;
+ dev_dbg(chg->dev, "VBUS attached.\n");
+ }
+
+ if (old_type != chg->psy_desc.type)
+ power_supply_changed(chg->charger);
+}
+
+static irqreturn_t pf1550_charger_irq_handler(int irq, void *data)
+{
+ struct pf1550_charger *chg = data;
+
+ chg->irq = irq;
+ schedule_delayed_work(&chg->irq_work, msecs_to_jiffies(10));
+
+ return IRQ_HANDLED;
+}
+
+static void pf1550_charger_irq_work(struct work_struct *work)
+{
+ struct pf1550_charger *chg = container_of(to_delayed_work(work),
+ struct pf1550_charger,
+ irq_work);
+ int i, irq_type = -1;
+ unsigned int status;
+
+ if (!chg->charger)
+ return;
+
+ mutex_lock(&chg->mutex);
+
+ for (i = 0; i < ARRAY_SIZE(pf1550_charger_irqs); i++)
+ if (chg->irq == pf1550_charger_irqs[i].virq)
+ irq_type = pf1550_charger_irqs[i].irq;
+
+ switch (irq_type) {
+ case PF1550_CHARG_IRQ_BAT2SOCI:
+ dev_info(chg->dev, "BAT to SYS Overcurrent interrupt.\n");
+ break;
+ case PF1550_CHARG_IRQ_BATI:
+ pf1550_chg_bat_isr(chg);
+ break;
+ case PF1550_CHARG_IRQ_CHGI:
+ pf1550_chg_chg_isr(chg);
+ break;
+ case PF1550_CHARG_IRQ_VBUSI:
+ pf1550_chg_vbus_isr(chg);
+ break;
+ case PF1550_CHARG_IRQ_THMI:
+ dev_info(chg->dev, "Thermal interrupt.\n");
+ break;
+ default:
+ dev_err(chg->dev, "unknown interrupt occurred.\n");
+ }
+
+ if (regmap_read(chg->pf1550->regmap, PF1550_CHARG_REG_CHG_INT, &status))
+ dev_err(chg->dev, "Read CHG_INT error.\n");
+ if (regmap_write(chg->pf1550->regmap, PF1550_CHARG_REG_CHG_INT, status))
+ dev_err(chg->dev, "clear CHG_INT error.\n");
+
+ mutex_unlock(&chg->mutex);
+}
+
+static enum power_supply_property pf1550_charger_props[] = {
+ POWER_SUPPLY_PROP_STATUS,
+ POWER_SUPPLY_PROP_CHARGE_TYPE,
+ POWER_SUPPLY_PROP_HEALTH,
+ POWER_SUPPLY_PROP_PRESENT,
+ POWER_SUPPLY_PROP_ONLINE,
+ POWER_SUPPLY_PROP_MODEL_NAME,
+ POWER_SUPPLY_PROP_MANUFACTURER,
+};
+
+static int pf1550_charger_get_property(struct power_supply *psy,
+ enum power_supply_property psp,
+ union power_supply_propval *val)
+{
+ struct pf1550_charger *chg = power_supply_get_drvdata(psy);
+ struct regmap *regmap = chg->pf1550->regmap;
+ int ret = 0;
+
+ switch (psp) {
+ case POWER_SUPPLY_PROP_STATUS:
+ ret = pf1550_get_charger_state(regmap, &val->intval);
+ break;
+ case POWER_SUPPLY_PROP_CHARGE_TYPE:
+ ret = pf1550_get_charge_type(regmap, &val->intval);
+ break;
+ case POWER_SUPPLY_PROP_HEALTH:
+ ret = pf1550_get_battery_health(regmap, &val->intval);
+ break;
+ case POWER_SUPPLY_PROP_PRESENT:
+ ret = pf1550_get_present(regmap, &val->intval);
+ break;
+ case POWER_SUPPLY_PROP_ONLINE:
+ ret = pf1550_get_online(regmap, &val->intval);
+ break;
+ case POWER_SUPPLY_PROP_MODEL_NAME:
+ val->strval = pf1550_charger_model;
+ break;
+ case POWER_SUPPLY_PROP_MANUFACTURER:
+ val->strval = pf1550_charger_manufacturer;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return ret;
+}
+
+static int pf1550_set_constant_volt(struct pf1550_charger *chg,
+ unsigned int uvolt)
+{
+ unsigned int data;
+
+ if (uvolt >= 3500000 && uvolt <= 4440000)
+ data = 8 + (uvolt - 3500000) / 20000;
+ else {
+ dev_err(chg->dev, "Wrong value for constant voltage\n");
+ return -EINVAL;
+ }
+
+ dev_dbg(chg->dev, "Charging constant voltage: %u (0x%x)\n", uvolt,
+ data);
+
+ return regmap_update_bits(chg->pf1550->regmap,
+ PF1550_CHARG_REG_BATT_REG,
+ PF1550_CHARG_REG_BATT_REG_CHGCV_MASK, data);
+}
+
+static int pf1550_set_min_system_volt(struct pf1550_charger *chg,
+ unsigned int uvolt)
+{
+ unsigned int data;
+
+ switch (uvolt) {
+ case 3500000:
+ data = 0x0;
+ break;
+ case 3700000:
+ data = 0x1;
+ break;
+ case 4300000:
+ data = 0x2;
+ break;
+ default:
+ dev_err(chg->dev, "Wrong value for minimum system voltage\n");
+ return -EINVAL;
+ }
+
+ data <<= PF1550_CHARG_REG_BATT_REG_VMINSYS_SHIFT;
+
+ dev_dbg(chg->dev, "Minimum system regulation voltage: %u (0x%x)\n",
+ uvolt, data);
+
+ return regmap_update_bits(chg->pf1550->regmap,
+ PF1550_CHARG_REG_BATT_REG,
+ PF1550_CHARG_REG_BATT_REG_VMINSYS_MASK, data);
+}
+
+static int pf1550_set_thermal_regulation_temp(struct pf1550_charger *chg,
+ unsigned int cels)
+{
+ unsigned int data;
+
+ switch (cels) {
+ case 60:
+ data = 0x0;
+ break;
+ case 75:
+ data = 0x1;
+ break;
+ case 90:
+ data = 0x2;
+ break;
+ case 105:
+ data = 0x3;
+ break;
+ default:
+ dev_err(chg->dev, "Wrong value for thermal temperature\n");
+ return -EINVAL;
+ }
+
+ data <<= PF1550_CHARG_REG_THM_REG_CNFG_REGTEMP_SHIFT;
+
+ dev_dbg(chg->dev, "Thermal regulation loop temperature: %u (0x%x)\n",
+ cels, data);
+
+ return regmap_update_bits(chg->pf1550->regmap,
+ PF1550_CHARG_REG_THM_REG_CNFG,
+ PF1550_CHARG_REG_THM_REG_CNFG_REGTEMP_MASK, data);
+}
+
+/*
+ * Sets charger registers to proper and safe default values.
+ */
+static int pf1550_reg_init(struct pf1550_charger *chg)
+{
+ int ret;
+ unsigned int data;
+
+ /* Unmask charger interrupt, mask DPMI and reserved bit */
+ ret = regmap_write(chg->pf1550->regmap, PF1550_CHARG_REG_CHG_INT_MASK,
+ 0x51);
+ if (ret) {
+ dev_err(chg->dev, "Error unmask charger interrupt: %d\n", ret);
+ return ret;
+ }
+
+ ret = regmap_read(chg->pf1550->regmap, PF1550_CHARG_REG_VBUS_SNS,
+ &data);
+ if (ret) {
+ dev_err(chg->dev, "Read charg vbus_sns error: %d\n", ret);
+ return ret;
+ }
+
+ if (data & PF1550_VBUS_VALID)
+ chg->psy_desc.type = POWER_SUPPLY_TYPE_MAINS;
+
+ ret = pf1550_set_constant_volt(chg, chg->constant_volt);
+ if (ret)
+ return ret;
+
+ ret = pf1550_set_min_system_volt(chg, chg->min_system_volt);
+ if (ret)
+ return ret;
+
+ ret = pf1550_set_thermal_regulation_temp(chg,
+ chg->thermal_regulation_temp);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+static int pf1550_dt_init(struct device *dev, struct pf1550_charger *chg)
+{
+ struct device_node *np = dev->of_node;
+
+ if (!np) {
+ dev_err(dev, "no charger OF node\n");
+ return -EINVAL;
+ }
+
+ if (of_property_read_u32(np, "fsl,constant-microvolt",
+ &chg->constant_volt))
+ chg->constant_volt = PF1550_DEFAULT_CONSTANT_VOLT;
+
+ if (of_property_read_u32(np, "fsl,min-system-microvolt",
+ &chg->min_system_volt))
+ chg->min_system_volt = PF1550_DEFAULT_MIN_SYSTEM_VOLT;
+
+ if (of_property_read_u32(np, "fsl,thermal-regulation",
+ &chg->thermal_regulation_temp))
+ chg->thermal_regulation_temp = PF1550_DEFAULT_THERMAL_TEMP;
+
+ return 0;
+}
+
+static int pf1550_charger_probe(struct platform_device *pdev)
+{
+ struct pf1550_charger *chg;
+ struct power_supply_config psy_cfg = {};
+ struct pf1550_dev *pf1550 = dev_get_drvdata(pdev->dev.parent);
+ int i, ret;
+
+ chg = devm_kzalloc(&pdev->dev, sizeof(*chg), GFP_KERNEL);
+ if (!chg)
+ return -ENOMEM;
+
+ chg->dev = &pdev->dev;
+ chg->pf1550 = pf1550;
+
+ platform_set_drvdata(pdev, chg);
+
+ ret = pf1550_dt_init(&pdev->dev, chg);
+ if (ret)
+ return ret;
+
+ mutex_init(&chg->mutex);
+
+ INIT_DELAYED_WORK(&chg->irq_work, pf1550_charger_irq_work);
+
+ for (i = 0; i < ARRAY_SIZE(pf1550_charger_irqs); i++) {
+ struct pf1550_irq_info *charger_irq =
+ &pf1550_charger_irqs[i];
+ unsigned int virq = 0;
+
+ virq = regmap_irq_get_virq(pf1550->irq_data_charger,
+ charger_irq->irq);
+ if (!virq)
+ return -EINVAL;
+
+ charger_irq->virq = virq;
+
+ ret = devm_request_threaded_irq(&pdev->dev, virq, NULL,
+ pf1550_charger_irq_handler,
+ IRQF_NO_SUSPEND,
+ charger_irq->name, chg);
+ if (ret) {
+ dev_err(&pdev->dev,
+ "failed: irq request (IRQ: %d, error :%d)\n",
+ charger_irq->irq, ret);
+ return ret;
+ }
+ }
+
+ psy_cfg.drv_data = chg;
+
+ chg->psy_desc.name = PF1550_CHARGER_NAME;
+ chg->psy_desc.type = POWER_SUPPLY_TYPE_BATTERY;
+ chg->psy_desc.get_property = pf1550_charger_get_property;
+ chg->psy_desc.properties = pf1550_charger_props;
+ chg->psy_desc.num_properties = ARRAY_SIZE(pf1550_charger_props);
+
+ chg->charger = power_supply_register(&pdev->dev, &chg->psy_desc,
+ &psy_cfg);
+ if (IS_ERR(chg->charger)) {
+ dev_err(&pdev->dev, "failed: power supply register\n");
+ ret = PTR_ERR(chg->charger);
+ return ret;
+ }
+
+ ret = pf1550_reg_init(chg);
+
+ return ret;
+}
+
+static int pf1550_charger_remove(struct platform_device *pdev)
+{
+ struct pf1550_charger *chg = platform_get_drvdata(pdev);
+
+ cancel_delayed_work_sync(&chg->irq_work);
+ power_supply_unregister(chg->charger);
+
+ return 0;
+}
+
+static const struct platform_device_id pf1550_charger_id[] = {
+ { "pf1550-charger", 0, },
+ { }
+};
+MODULE_DEVICE_TABLE(platform, pf1550_charger_id);
+
+static struct platform_driver pf1550_charger_driver = {
+ .driver = {
+ .name = "pf1550-charger",
+ },
+ .probe = pf1550_charger_probe,
+ .remove = pf1550_charger_remove,
+ .id_table = pf1550_charger_id,
+};
+module_platform_driver(pf1550_charger_driver);
+
+MODULE_AUTHOR("Robin Gong <yibin.gong@freescale.com>");
+MODULE_DESCRIPTION("PF1550 charger driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/power/supply/sabresd_battery.c b/drivers/power/supply/sabresd_battery.c
new file mode 100644
index 000000000000..5f479f83525a
--- /dev/null
+++ b/drivers/power/supply/sabresd_battery.c
@@ -0,0 +1,1014 @@
+/*
+ * sabresd_battery.c - Maxim 8903 USB/Adapter Charger Driver
+ *
+ * Copyright (C) 2011 Samsung Electronics
+ * Copyright (C) 2011-2015 Freescale Semiconductor, Inc.
+ * Based on max8903_charger.c
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <linux/delay.h>
+#include <linux/gpio.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/of_gpio.h>
+#include <linux/power_supply.h>
+#include <linux/platform_device.h>
+#include <linux/power/sabresd_battery.h>
+#include <linux/slab.h>
+
+#define BATTERY_UPDATE_INTERVAL 5 /*seconds*/
+#define LOW_VOLT_THRESHOLD 2800000
+#define HIGH_VOLT_THRESHOLD 4200000
+#define ADC_SAMPLE_COUNT 6
+
+struct max8903_data {
+ struct max8903_pdata *pdata;
+ struct device *dev;
+ struct power_supply *psy;
+ struct power_supply *usb;
+ struct power_supply *bat;
+ struct power_supply *detect_usb;
+ bool fault;
+ bool usb_in;
+ bool ta_in;
+ bool chg_state;
+ struct delayed_work work;
+ unsigned int interval;
+ unsigned short thermal_raw;
+ int voltage_uV;
+ int current_uA;
+ int battery_status;
+ int charger_online;
+ int charger_voltage_uV;
+ int real_capacity;
+ int percent;
+ int old_percent;
+ int usb_charger_online;
+ int first_delay_count;
+};
+
+typedef struct {
+ u32 voltage;
+ u32 percent;
+} battery_capacity , *pbattery_capacity;
+
+static int offset_discharger;
+static int offset_charger;
+static int offset_usb_charger;
+
+static battery_capacity chargingTable[] = {
+ {4050, 99},
+ {4040, 98},
+ {4020, 97},
+ {4010, 96},
+ {3990, 95},
+ {3980, 94},
+ {3970, 93},
+ {3960, 92},
+ {3950, 91},
+ {3940, 90},
+ {3930, 85},
+ {3920, 81},
+ {3910, 77},
+ {3900, 73},
+ {3890, 70},
+ {3860, 65},
+ {3830, 60},
+ {3780, 55},
+ {3760, 50},
+ {3740, 45},
+ {3720, 40},
+ {3700, 35},
+ {3680, 30},
+ {3660, 25},
+ {3640, 20},
+ {3620, 17},
+ {3600, 14},
+ {3580, 13},
+ {3560, 12},
+ {3540, 11},
+ {3520, 10},
+ {3500, 9},
+ {3480, 8},
+ {3460, 7},
+ {3440, 6},
+ {3430, 5},
+ {3420, 4},
+ {3020, 0},
+};
+
+static battery_capacity dischargingTable[] = {
+ {4050, 100},
+ {4035, 99},
+ {4020, 98},
+ {4010, 97},
+ {4000, 96},
+ {3990, 96},
+ {3980, 95},
+ {3970, 92},
+ {3960, 91},
+ {3950, 90},
+ {3940, 88},
+ {3930, 86},
+ {3920, 84},
+ {3910, 82},
+ {3900, 80},
+ {3890, 74},
+ {3860, 69},
+ {3830, 64},
+ {3780, 59},
+ {3760, 54},
+ {3740, 49},
+ {3720, 44},
+ {3700, 39},
+ {3680, 34},
+ {3660, 29},
+ {3640, 24},
+ {3620, 19},
+ {3600, 14},
+ {3580, 13},
+ {3560, 12},
+ {3540, 11},
+ {3520, 10},
+ {3500, 9},
+ {3480, 8},
+ {3460, 7},
+ {3440, 6},
+ {3430, 5},
+ {3420, 4},
+ {3020, 0},
+};
+
+u32 calibrate_battery_capability_percent(struct max8903_data *data)
+{
+ u8 i;
+ pbattery_capacity pTable;
+ u32 tableSize;
+
+ if (data->battery_status == POWER_SUPPLY_STATUS_DISCHARGING) {
+ pTable = dischargingTable;
+ tableSize = sizeof(dischargingTable)/
+ sizeof(dischargingTable[0]);
+ } else {
+ pTable = chargingTable;
+ tableSize = sizeof(chargingTable)/
+ sizeof(chargingTable[0]);
+ }
+ for (i = 0; i < tableSize; i++) {
+ if (data->voltage_uV >= pTable[i].voltage)
+ return pTable[i].percent;
+ }
+
+ return 0;
+}
+
+static enum power_supply_property max8903_charger_props[] = {
+ POWER_SUPPLY_PROP_ONLINE,
+};
+
+static enum power_supply_property max8903_battery_props[] = {
+ POWER_SUPPLY_PROP_VOLTAGE_NOW,
+ POWER_SUPPLY_PROP_STATUS,
+ POWER_SUPPLY_PROP_PRESENT,
+ POWER_SUPPLY_PROP_CAPACITY,
+ POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN,
+ POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
+ POWER_SUPPLY_PROP_HEALTH,
+ POWER_SUPPLY_PROP_CAPACITY_LEVEL,
+};
+
+extern int max11801_read_adc(void);
+
+static void max8903_charger_update_status(struct max8903_data *data)
+{
+ if (data->ta_in) {
+ data->charger_online = 1;
+ } else if (data->usb_in) {
+ data->usb_charger_online = 1;
+ } else {
+ data->charger_online = 0;
+ data->usb_charger_online = 0;
+ }
+
+ if (!data->charger_online && !data->usb_charger_online) {
+ data->battery_status = POWER_SUPPLY_STATUS_DISCHARGING;
+ } else if (gpio_get_value(data->pdata->chg) == 0) {
+ data->battery_status = POWER_SUPPLY_STATUS_CHARGING;
+ } else if ((data->ta_in || data->usb_in) &&
+ gpio_get_value(data->pdata->chg) > 0) {
+ if (!data->pdata->feature_flag) {
+ if (data->percent >= 99)
+ data->battery_status = POWER_SUPPLY_STATUS_FULL;
+ else
+ data->battery_status =
+ POWER_SUPPLY_STATUS_NOT_CHARGING;
+ } else {
+ data->battery_status = POWER_SUPPLY_STATUS_FULL;
+ }
+ }
+}
+
+u32 calibration_voltage(struct max8903_data *data)
+{
+ u32 voltage_data = 0;
+ int adc_val = 0;
+ int i;
+ int offset;
+
+ if (!data->charger_online && !data->usb_charger_online)
+ offset = offset_discharger;
+ else if (data->usb_charger_online)
+ offset = offset_usb_charger;
+ else if (data->charger_online)
+ offset = offset_charger;
+
+ /* simple average */
+ for (i = 0; i < ADC_SAMPLE_COUNT; i++) {
+ adc_val = max11801_read_adc();
+ /* Check if touch driver is probed */
+ if (max11801_read_adc() < 0)
+ break;
+ voltage_data += adc_val - offset;
+ }
+ voltage_data = voltage_data / ADC_SAMPLE_COUNT;
+ dev_dbg(data->dev, "volt: %d\n", voltage_data);
+
+ return voltage_data;
+}
+
+static void max8903_battery_update_status(struct max8903_data *data)
+{
+ if (!data->pdata->feature_flag) {
+ data->voltage_uV = calibration_voltage(data);
+ data->percent = calibrate_battery_capability_percent(data);
+ if (data->percent != data->old_percent) {
+ data->old_percent = data->percent;
+ power_supply_changed(data->bat);
+ }
+ /*
+ * because boot time gap between led framwork and charger
+ * framwork,when system boots with charger attatched,
+ * charger led framwork loses the first charger online event,
+ * add once extra power_supply_changed can fix this issure
+ */
+ if (data->first_delay_count < 200) {
+ data->first_delay_count = data->first_delay_count + 1;
+ power_supply_changed(data->bat);
+ }
+ }
+}
+
+static int max8903_battery_get_property(struct power_supply *bat,
+ enum power_supply_property psp,
+ union power_supply_propval *val)
+{
+ struct max8903_data *di = power_supply_get_drvdata(bat);
+
+ switch (psp) {
+ case POWER_SUPPLY_PROP_STATUS:
+ val->intval = POWER_SUPPLY_STATUS_UNKNOWN;
+ if (gpio_get_value(di->pdata->chg) == 0) {
+ di->battery_status = POWER_SUPPLY_STATUS_CHARGING;
+ } else if ((di->ta_in || di->usb_in) &&
+ gpio_get_value(di->pdata->chg) > 0) {
+ if (!di->pdata->feature_flag) {
+ if (di->percent >= 99)
+ di->battery_status =
+ POWER_SUPPLY_STATUS_FULL;
+ else
+ di->battery_status =
+ POWER_SUPPLY_STATUS_NOT_CHARGING;
+ } else {
+ di->battery_status = POWER_SUPPLY_STATUS_FULL;
+ }
+ }
+ val->intval = di->battery_status;
+ return 0;
+ default:
+ break;
+ }
+
+ switch (psp) {
+ case POWER_SUPPLY_PROP_VOLTAGE_NOW:
+ val->intval = di->voltage_uV;
+ break;
+ case POWER_SUPPLY_PROP_CHARGE_NOW:
+ val->intval = 0;
+ break;
+ case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN:
+ val->intval = HIGH_VOLT_THRESHOLD;
+ break;
+ case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN:
+ val->intval = LOW_VOLT_THRESHOLD;
+ break;
+ case POWER_SUPPLY_PROP_PRESENT:
+ val->intval = 1;
+ break;
+ case POWER_SUPPLY_PROP_CAPACITY:
+ val->intval = di->percent < 0 ? 0 :
+ (di->percent > 100 ? 100 : di->percent);
+ break;
+ case POWER_SUPPLY_PROP_HEALTH:
+ val->intval = POWER_SUPPLY_HEALTH_GOOD;
+ if (di->fault)
+ val->intval = POWER_SUPPLY_HEALTH_UNSPEC_FAILURE;
+ break;
+ case POWER_SUPPLY_PROP_CAPACITY_LEVEL:
+ if (di->battery_status == POWER_SUPPLY_STATUS_FULL)
+ val->intval = POWER_SUPPLY_CAPACITY_LEVEL_FULL;
+ else if (di->percent <= 15)
+ val->intval = POWER_SUPPLY_CAPACITY_LEVEL_LOW;
+ else
+ val->intval = POWER_SUPPLY_CAPACITY_LEVEL_NORMAL;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int max8903_get_property(struct power_supply *psy,
+ enum power_supply_property psp,
+ union power_supply_propval *val)
+{
+ struct max8903_data *data = power_supply_get_drvdata(psy);
+
+ switch (psp) {
+ case POWER_SUPPLY_PROP_ONLINE:
+ val->intval = 0;
+ if (data->ta_in)
+ val->intval = 1;
+ data->charger_online = val->intval;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int max8903_get_usb_property(struct power_supply *usb,
+ enum power_supply_property psp,
+ union power_supply_propval *val)
+{
+ struct max8903_data *data = power_supply_get_drvdata(usb);
+
+ switch (psp) {
+ case POWER_SUPPLY_PROP_ONLINE:
+ val->intval = 0;
+ if (data->usb_in)
+ val->intval = 1;
+ data->usb_charger_online = val->intval;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static irqreturn_t max8903_dcin(int irq, void *_data)
+{
+ struct max8903_data *data = _data;
+ struct max8903_pdata *pdata = data->pdata;
+ bool ta_in = false;
+
+ if (pdata->dok)
+ ta_in = gpio_get_value(pdata->dok) ? false : true;
+
+ if (ta_in == data->ta_in)
+ return IRQ_HANDLED;
+
+ data->ta_in = ta_in;
+ dev_info(data->dev, "TA(DC-IN) Charger %s.\n", ta_in ?
+ "Connected" : "Disconnected");
+ max8903_charger_update_status(data);
+ power_supply_changed(data->psy);
+ power_supply_changed(data->bat);
+
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t max8903_usbin(int irq, void *_data)
+{
+ struct max8903_data *data = _data;
+ struct max8903_pdata *pdata = data->pdata;
+ bool usb_in = false;
+
+ if (pdata->uok)
+ usb_in = gpio_get_value(pdata->uok) ? false : true;
+ if (usb_in == data->usb_in)
+ return IRQ_HANDLED;
+ data->usb_in = usb_in;
+ dev_info(data->dev, "USB Charger %s.\n", usb_in ?
+ "Connected" : "Disconnected");
+ max8903_charger_update_status(data);
+ power_supply_changed(data->bat);
+ power_supply_changed(data->usb);
+
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t max8903_fault(int irq, void *_data)
+{
+ struct max8903_data *data = _data;
+ struct max8903_pdata *pdata = data->pdata;
+ bool fault;
+
+ fault = gpio_get_value(pdata->flt) ? false : true;
+
+ if (fault == data->fault)
+ return IRQ_HANDLED;
+ data->fault = fault;
+
+ if (fault)
+ dev_err(data->dev, "Charger suffers a fault and stops.\n");
+ else
+ dev_err(data->dev, "Charger recovered from a fault.\n");
+ max8903_charger_update_status(data);
+ power_supply_changed(data->psy);
+ power_supply_changed(data->bat);
+ power_supply_changed(data->usb);
+
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t max8903_chg(int irq, void *_data)
+{
+ struct max8903_data *data = _data;
+ struct max8903_pdata *pdata = data->pdata;
+ int chg_state;
+
+ chg_state = gpio_get_value(pdata->chg) ? false : true;
+
+ if (chg_state == data->chg_state)
+ return IRQ_HANDLED;
+ data->chg_state = chg_state;
+ max8903_charger_update_status(data);
+ power_supply_changed(data->psy);
+ power_supply_changed(data->bat);
+ power_supply_changed(data->usb);
+
+ return IRQ_HANDLED;
+}
+
+static void max8903_battery_work(struct work_struct *work)
+{
+ struct max8903_data *data;
+
+ data = container_of(work, struct max8903_data, work.work);
+ data->interval = HZ * BATTERY_UPDATE_INTERVAL;
+
+ max8903_charger_update_status(data);
+ max8903_battery_update_status(data);
+ dev_dbg(data->dev, "battery voltage: %4d mV\n", data->voltage_uV);
+ dev_dbg(data->dev, "charger online status: %d\n",
+ data->charger_online);
+ dev_dbg(data->dev, "battery status : %d\n" , data->battery_status);
+ dev_dbg(data->dev, "battery capacity percent: %3d\n", data->percent);
+ dev_dbg(data->dev, "data->usb_in: %x , data->ta_in: %x\n",
+ data->usb_in, data->ta_in);
+ /* reschedule for the next time */
+ schedule_delayed_work(&data->work, data->interval);
+}
+
+static ssize_t max8903_voltage_offset_discharger_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ return sprintf(buf, "read offset_discharger:%04d\n",
+ offset_discharger);
+}
+
+static ssize_t max8903_voltage_offset_discharger_store(struct device *dev,
+ struct device_attribute *attr, const char *buf,
+ size_t count)
+{
+ int ret;
+ unsigned long data;
+
+ ret = kstrtoul(buf, 10, &data);
+ offset_discharger = (int)data;
+ pr_info("read offset_discharger:%04d\n", offset_discharger);
+
+ return count;
+}
+
+static ssize_t max8903_voltage_offset_charger_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ return sprintf(buf, "read offset_charger:%04d\n",
+ offset_charger);
+}
+
+static ssize_t max8903_voltage_offset_charger_store(struct device *dev,
+ struct device_attribute *attr, const char *buf,
+ size_t count)
+{
+ int ret;
+ unsigned long data;
+
+ ret = kstrtoul(buf, 10, &data);
+ offset_charger = (int)data;
+ pr_info("read offset_charger:%04d\n", offset_charger);
+ return count;
+}
+
+static ssize_t max8903_voltage_offset_usb_charger_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ return sprintf(buf, "read offset_usb_charger:%04d\n",
+ offset_usb_charger);
+}
+
+static ssize_t max8903_voltage_offset_usb_charger_store(struct device *dev,
+ struct device_attribute *attr, const char *buf,
+ size_t count)
+{
+ int ret;
+ unsigned long data;
+
+ ret = kstrtoul(buf, 10, &data);
+ offset_usb_charger = (int)data;
+ pr_info("read offset_charger:%04d\n", offset_usb_charger);
+
+ return count;
+}
+
+static struct device_attribute max8903_discharger_dev_attr = {
+ .attr = {
+ .name = "max8903_ctl_offset_discharger",
+ .mode = S_IRUSR | S_IWUSR,
+ },
+ .show = max8903_voltage_offset_discharger_show,
+ .store = max8903_voltage_offset_discharger_store,
+};
+
+static struct device_attribute max8903_charger_dev_attr = {
+ .attr = {
+ .name = "max8903_ctl_offset_charger",
+ .mode = S_IRUSR | S_IWUSR,
+ },
+ .show = max8903_voltage_offset_charger_show,
+ .store = max8903_voltage_offset_charger_store,
+};
+
+static struct device_attribute max8903_usb_charger_dev_attr = {
+ .attr = {
+ .name = "max8903_ctl_offset_usb_charger",
+ .mode = S_IRUSR | S_IWUSR,
+ },
+ .show = max8903_voltage_offset_usb_charger_show,
+ .store = max8903_voltage_offset_usb_charger_store,
+};
+
+#if defined(CONFIG_OF)
+static const struct of_device_id max8903_dt_ids[] = {
+ { .compatible = "fsl,max8903-charger", },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, max8903_dt_ids);
+
+static struct max8903_pdata *max8903_of_populate_pdata(
+ struct device *dev)
+{
+ struct device_node *of_node = dev->of_node;
+ struct max8903_pdata *pdata = dev->platform_data;
+
+ if (!of_node || pdata)
+ return pdata;
+
+ pdata = devm_kzalloc(dev, sizeof(struct max8903_pdata),
+ GFP_KERNEL);
+ if (!pdata)
+ return pdata;
+
+ if (of_get_property(of_node, "fsl,dcm_always_high", NULL))
+ pdata->dcm_always_high = true;
+ if (of_get_property(of_node, "fsl,dc_valid", NULL))
+ pdata->dc_valid = true;
+ if (of_get_property(of_node, "fsl,usb_valid", NULL))
+ pdata->usb_valid = true;
+ if (of_get_property(of_node, "fsl,adc_disable", NULL))
+ pdata->feature_flag = true;
+
+ if (pdata->dc_valid) {
+ pdata->dok = of_get_named_gpio(of_node, "dok_input", 0);
+ if (!gpio_is_valid(pdata->dok)) {
+ dev_err(dev, "pin pdata->dok: invalid gpio %d\n", pdata->dok);
+ return NULL;
+ }
+ }
+ if (pdata->usb_valid) {
+ pdata->uok = of_get_named_gpio(of_node, "uok_input", 0);
+ if (!gpio_is_valid(pdata->uok)) {
+ dev_err(dev, "pin pdata->uok: invalid gpio %d\n", pdata->uok);
+ return NULL;
+ }
+ }
+ pdata->chg = of_get_named_gpio(of_node, "chg_input", 0);
+ if (!gpio_is_valid(pdata->chg)) {
+ dev_err(dev, "pin pdata->chg: invalid gpio %d\n", pdata->chg);
+ return NULL;
+ }
+ pdata->flt = of_get_named_gpio(of_node, "flt_input", 0);
+ if (!gpio_is_valid(pdata->flt)) {
+ dev_err(dev, "pin pdata->flt: invalid gpio %d\n", pdata->flt);
+ return NULL;
+ }
+
+ /* no need check offset without adc converter */
+ if (!pdata->feature_flag) {
+ if (of_property_read_u32(of_node, "offset-charger",
+ &offset_charger))
+ dev_err(dev, "Not setting offset-charger in dts!\n");
+
+ if (of_property_read_u32(of_node, "offset-discharger",
+ &offset_discharger))
+ dev_err(dev, "Not setting offset-discharger in dts!\n");
+
+ if (of_property_read_u32(of_node, "offset-usb-charger",
+ &offset_usb_charger))
+ dev_err(dev, "Not setting offset-usb-charger in dts!\n");
+ }
+
+ return pdata;
+}
+#endif
+
+static const struct power_supply_desc max8903_ac_desc = {
+ .name = "max8903-ac",
+ .type = POWER_SUPPLY_TYPE_MAINS,
+ .get_property = max8903_get_property,
+ .properties = max8903_charger_props,
+ .num_properties = ARRAY_SIZE(max8903_charger_props),
+};
+
+static const struct power_supply_desc max8903_usb_desc = {
+ .name = "max8903-usb",
+ .type = POWER_SUPPLY_TYPE_USB,
+ .get_property = max8903_get_usb_property,
+ .properties = max8903_charger_props,
+ .num_properties = ARRAY_SIZE(max8903_charger_props),
+};
+
+static const struct power_supply_desc max8903_bat_desc = {
+ .name = "max8903-charger",
+ .type = POWER_SUPPLY_TYPE_BATTERY,
+ .properties = max8903_battery_props,
+ .num_properties = ARRAY_SIZE(max8903_battery_props),
+ .get_property = max8903_battery_get_property,
+ .use_for_apm = 1,
+};
+
+static int max8903_probe(struct platform_device *pdev)
+{
+ struct max8903_data *data;
+ struct device *dev = &pdev->dev;
+ struct max8903_pdata *pdata = pdev->dev.platform_data;
+ int ret = 0;
+ int gpio = 0;
+ int ta_in = 0;
+ int usb_in = 0;
+ struct power_supply_config psy_cfg = {};
+
+ data = devm_kzalloc(dev, sizeof(struct max8903_data), GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
+
+ pdata = pdev->dev.platform_data;
+ if (!pdata) {
+ pdata = max8903_of_populate_pdata(&pdev->dev);
+ if (!pdata)
+ return -EINVAL;
+ }
+
+ data->first_delay_count = 0;
+ data->pdata = pdata;
+ data->dev = dev;
+ data->usb_in = 0;
+ data->ta_in = 0;
+ platform_set_drvdata(pdev, data);
+
+ if (pdata->dc_valid == false && pdata->usb_valid == false) {
+ dev_err(dev, "No valid power sources.\n");
+ ret = -EINVAL;
+ goto err;
+ }
+ if (pdata->dc_valid) {
+ if (pdata->dok && pdata->dcm_always_high) {
+ gpio = pdata->dok;
+ ret = gpio_request_one(gpio, GPIOF_IN, "max8903-DOK");
+ if (ret) {
+ dev_err(dev, "request max8903-DOK error!!\n");
+ goto err;
+ }
+ ta_in = gpio_get_value(gpio) ? 0 : 1;
+ } else {
+ dev_err(dev, "When DC is wired, DOK and DCM should be"
+ " wired as well or set dcm always high!\n");
+ ret = -EINVAL;
+ goto err;
+ }
+ }
+
+ if (pdata->usb_valid) {
+ if (pdata->uok) {
+ gpio = pdata->uok;
+ ret = gpio_request_one(gpio, GPIOF_IN, "max8903-UOK");
+ if (ret) {
+ dev_err(dev, "request max8903-UOK error!!\n");
+ goto err;
+ }
+ usb_in = gpio_get_value(gpio) ? 0 : 1;
+ } else {
+ dev_err(dev, "When USB is wired, UOK should be wired"
+ " as well.\n");
+ ret = -EINVAL;
+ goto err;
+ }
+ }
+
+ if (pdata->chg) {
+ ret = gpio_request_one(pdata->chg, GPIOF_IN, "max8903-CHG");
+ if (ret) {
+ dev_err(dev, "request max8903-CHG error!!\n");
+ goto err;
+ }
+ }
+
+ if (pdata->flt) {
+ ret = gpio_request_one(pdata->flt, GPIOF_IN, "max8903-FLT");
+ if (ret) {
+ dev_err(dev, "request max8903-FLT error!!\n");
+ goto err;
+ }
+ }
+
+ data->fault = false;
+ data->ta_in = ta_in;
+ data->usb_in = usb_in;
+
+ psy_cfg.of_node = dev->of_node;
+ psy_cfg.drv_data = data;
+
+ data->psy = power_supply_register(dev, &max8903_ac_desc, &psy_cfg);
+ if (IS_ERR(data->psy)) {
+ dev_err(dev, "failed: power supply register.\n");
+ goto err;
+ }
+
+ data->usb = power_supply_register(dev, &max8903_usb_desc, &psy_cfg);
+ if (IS_ERR(data->usb)) {
+ dev_err(dev, "failed: power supply register.\n");
+ goto err_psy;
+ }
+
+ data->bat = power_supply_register(dev, &max8903_bat_desc, &psy_cfg);
+ if (IS_ERR(data->bat)) {
+ dev_err(data->dev, "failed to register battery\n");
+ goto err_usb;
+ }
+
+ INIT_DELAYED_WORK(&data->work, max8903_battery_work);
+ schedule_delayed_work(&data->work, data->interval);
+
+ if (pdata->dc_valid) {
+ ret = request_threaded_irq(gpio_to_irq(pdata->dok), NULL,
+ max8903_dcin, IRQF_TRIGGER_FALLING |
+ IRQF_TRIGGER_RISING | IRQF_ONESHOT, "MAX8903 DC IN",
+ data);
+ if (ret) {
+ dev_err(dev, "Cannot request irq %d for DC (%d)\n",
+ gpio_to_irq(pdata->dok), ret);
+ goto err_dc_irq;
+ }
+ }
+
+ if (pdata->usb_valid) {
+ ret = request_threaded_irq(gpio_to_irq(pdata->uok), NULL,
+ max8903_usbin, IRQF_TRIGGER_FALLING |
+ IRQF_TRIGGER_RISING | IRQF_ONESHOT, "MAX8903 USB IN",
+ data);
+ if (ret) {
+ dev_err(dev, "Cannot request irq %d for USB (%d)\n",
+ gpio_to_irq(pdata->uok), ret);
+ goto err_usb_irq;
+ }
+ }
+
+ if (pdata->flt) {
+ ret = request_threaded_irq(gpio_to_irq(pdata->flt), NULL,
+ max8903_fault, IRQF_TRIGGER_FALLING |
+ IRQF_TRIGGER_RISING | IRQF_ONESHOT, "MAX8903 Fault",
+ data);
+ if (ret) {
+ dev_err(dev, "Cannot request irq %d for Fault (%d)\n",
+ gpio_to_irq(pdata->flt), ret);
+ goto err_flt_irq;
+ }
+ }
+
+ if (pdata->chg) {
+ ret = request_threaded_irq(gpio_to_irq(pdata->chg), NULL,
+ max8903_chg, IRQF_TRIGGER_FALLING |
+ IRQF_TRIGGER_RISING | IRQF_ONESHOT, "MAX8903 Status",
+ data);
+ if (ret) {
+ dev_err(dev, "Cannot request irq %d for Status (%d)\n",
+ gpio_to_irq(pdata->flt), ret);
+ goto err_chg_irq;
+ }
+ }
+
+ ret = device_create_file(&pdev->dev, &max8903_discharger_dev_attr);
+ if (ret)
+ dev_err(&pdev->dev, "create device file failed!\n");
+ ret = device_create_file(&pdev->dev, &max8903_charger_dev_attr);
+ if (ret)
+ dev_err(&pdev->dev, "create device file failed!\n");
+ ret = device_create_file(&pdev->dev, &max8903_usb_charger_dev_attr);
+ if (ret)
+ dev_err(&pdev->dev, "create device file failed!\n");
+
+ device_set_wakeup_capable(&pdev->dev, true);
+
+ max8903_charger_update_status(data);
+ max8903_battery_update_status(data);
+
+ return 0;
+err_chg_irq:
+ if (pdata->chg)
+ free_irq(gpio_to_irq(pdata->chg), data);
+err_flt_irq:
+ if (pdata->flt)
+ free_irq(gpio_to_irq(pdata->flt), data);
+err_usb_irq:
+ if (pdata->usb_valid)
+ free_irq(gpio_to_irq(pdata->uok), data);
+err_dc_irq:
+ if (pdata->dc_valid)
+ free_irq(gpio_to_irq(pdata->dok), data);
+ cancel_delayed_work(&data->work);
+ power_supply_unregister(data->bat);
+err_usb:
+ power_supply_unregister(data->usb);
+err_psy:
+ power_supply_unregister(data->psy);
+err:
+ if (pdata->uok)
+ gpio_free(pdata->uok);
+ if (pdata->dok)
+ gpio_free(pdata->dok);
+ if (pdata->flt)
+ gpio_free(pdata->flt);
+ if (pdata->chg)
+ gpio_free(pdata->chg);
+ return ret;
+}
+
+static int max8903_remove(struct platform_device *pdev)
+{
+ struct max8903_data *data = platform_get_drvdata(pdev);
+ if (data) {
+ struct max8903_pdata *pdata = data->pdata;
+
+ cancel_delayed_work_sync(&data->work);
+ power_supply_unregister(data->psy);
+ power_supply_unregister(data->usb);
+ power_supply_unregister(data->bat);
+
+ if (pdata->flt) {
+ free_irq(gpio_to_irq(pdata->flt), data);
+ gpio_free(pdata->flt);
+ }
+ if (pdata->usb_valid && pdata->uok) {
+ free_irq(gpio_to_irq(pdata->uok), data);
+ gpio_free(pdata->uok);
+ }
+ if (pdata->dc_valid) {
+ if (pdata->dok) {
+ free_irq(gpio_to_irq(pdata->dok), data);
+ gpio_free(pdata->dok);
+ } else if (pdata->chg) {
+ free_irq(gpio_to_irq(pdata->chg), data);
+ gpio_free(pdata->chg);
+ }
+ }
+
+ device_remove_file(&pdev->dev, &max8903_discharger_dev_attr);
+ device_remove_file(&pdev->dev, &max8903_charger_dev_attr);
+ device_remove_file(&pdev->dev, &max8903_usb_charger_dev_attr);
+
+ platform_set_drvdata(pdev, NULL);
+ kfree(data);
+ }
+
+ return 0;
+}
+
+static int max8903_suspend(struct platform_device *pdev,
+ pm_message_t state)
+{
+ struct max8903_data *data = platform_get_drvdata(pdev);
+ int irq;
+ if (data) {
+ struct max8903_pdata *pdata = data->pdata;
+ if (pdata) {
+ if (pdata->dc_valid && device_may_wakeup(&pdev->dev)) {
+ irq = gpio_to_irq(pdata->dok);
+ enable_irq_wake(irq);
+ }
+
+ if (pdata->usb_valid && device_may_wakeup(&pdev->dev)) {
+ irq = gpio_to_irq(pdata->uok);
+ enable_irq_wake(irq);
+ }
+ cancel_delayed_work(&data->work);
+ }
+ }
+ return 0;
+}
+
+static int max8903_resume(struct platform_device *pdev)
+{
+ struct max8903_data *data = platform_get_drvdata(pdev);
+ bool ta_in = false;
+ bool usb_in = false;
+ int irq;
+
+ if (data) {
+ struct max8903_pdata *pdata = data->pdata;
+
+ if (pdata) {
+ if (pdata->dok)
+ ta_in = gpio_get_value(pdata->dok) ? false : true;
+ if (pdata->uok)
+ usb_in = gpio_get_value(pdata->uok) ? false : true;
+
+ if (ta_in != data->ta_in) {
+ data->ta_in = ta_in;
+ dev_info(data->dev, "TA(DC-IN) Charger %s.\n", ta_in ?
+ "Connected" : "Disconnected");
+ max8903_charger_update_status(data);
+ power_supply_changed(data->psy);
+ }
+
+ if (usb_in != data->usb_in) {
+ data->usb_in = usb_in;
+ dev_info(data->dev, "USB Charger %s.\n", usb_in ?
+ "Connected" : "Disconnected");
+ max8903_charger_update_status(data);
+ power_supply_changed(data->usb);
+ }
+
+ if (pdata->dc_valid && device_may_wakeup(&pdev->dev)) {
+ irq = gpio_to_irq(pdata->dok);
+ disable_irq_wake(irq);
+ }
+ if (pdata->usb_valid && device_may_wakeup(&pdev->dev)) {
+ irq = gpio_to_irq(pdata->uok);
+ disable_irq_wake(irq);
+ }
+
+ schedule_delayed_work(&data->work,
+ BATTERY_UPDATE_INTERVAL);
+ }
+ }
+
+ return 0;
+}
+
+static struct platform_driver max8903_driver = {
+ .probe = max8903_probe,
+ .remove = max8903_remove,
+ .suspend = max8903_suspend,
+ .resume = max8903_resume,
+ .driver = {
+ .name = "max8903-charger",
+ .owner = THIS_MODULE,
+ .of_match_table = max8903_dt_ids,
+ },
+};
+module_platform_driver(max8903_driver);
+
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("Sabresd Battery Driver");
+MODULE_ALIAS("sabresd_battery");
diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig
index 763ee50ea57d..6950a8caca36 100644
--- a/drivers/pwm/Kconfig
+++ b/drivers/pwm/Kconfig
@@ -201,13 +201,22 @@ config PWM_IMG
config PWM_IMX
tristate "i.MX PWM support"
- depends on ARCH_MXC
+ depends on ARCH_MXC || ARCH_MXC_ARM64
help
Generic PWM framework driver for i.MX.
To compile this driver as a module, choose M here: the module
will be called pwm-imx.
+config PWM_TPM
+ tristate "i.MX TPM PWM support"
+ depends on ARCH_MXC
+ help
+ Generic PWM framework driver for i.MX TPM.
+
+ To compile this driver as a module, choose M here: the module
+ will be called pwm-tpm.
+
config PWM_JZ4740
tristate "Ingenic JZ4740 PWM support"
depends on MACH_JZ4740
diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile
index 0258a745f30c..c8182bcd00e8 100644
--- a/drivers/pwm/Makefile
+++ b/drivers/pwm/Makefile
@@ -19,6 +19,7 @@ obj-$(CONFIG_PWM_FSL_FTM) += pwm-fsl-ftm.o
obj-$(CONFIG_PWM_HIBVT) += pwm-hibvt.o
obj-$(CONFIG_PWM_IMG) += pwm-img.o
obj-$(CONFIG_PWM_IMX) += pwm-imx.o
+obj-$(CONFIG_PWM_TPM) += pwm-tpm.o
obj-$(CONFIG_PWM_JZ4740) += pwm-jz4740.o
obj-$(CONFIG_PWM_LP3943) += pwm-lp3943.o
obj-$(CONFIG_PWM_LPC18XX_SCT) += pwm-lpc18xx-sct.o
diff --git a/drivers/pwm/pwm-fsl-ftm.c b/drivers/pwm/pwm-fsl-ftm.c
index 557b4ea16796..96fa304caca0 100644
--- a/drivers/pwm/pwm-fsl-ftm.c
+++ b/drivers/pwm/pwm-fsl-ftm.c
@@ -86,7 +86,9 @@ struct fsl_pwm_chip {
struct regmap *regmap;
int period_ns;
+ bool has_pwmen;
+ struct clk *ipg_clk;
struct clk *clk[FSL_PWM_CLK_MAX];
};
@@ -95,18 +97,39 @@ static inline struct fsl_pwm_chip *to_fsl_chip(struct pwm_chip *chip)
return container_of(chip, struct fsl_pwm_chip, chip);
}
+static inline int fsl_pwm_mode_enable(struct fsl_pwm_chip *fpc)
+{
+ if (!fpc)
+ return -ENODEV;
+
+ if (fpc->ipg_clk)
+ clk_prepare_enable(fpc->ipg_clk);
+
+ return clk_prepare_enable(fpc->clk[FSL_PWM_CLK_SYS]);
+}
+
+static inline void fsl_pwm_mode_disable(struct fsl_pwm_chip *fpc)
+{
+ if (!fpc)
+ return;
+
+ clk_disable_unprepare(fpc->clk[FSL_PWM_CLK_SYS]);
+ if (fpc->ipg_clk)
+ clk_disable_unprepare(fpc->ipg_clk);
+}
+
static int fsl_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm)
{
struct fsl_pwm_chip *fpc = to_fsl_chip(chip);
- return clk_prepare_enable(fpc->clk[FSL_PWM_CLK_SYS]);
+ return fsl_pwm_mode_enable(fpc);
}
static void fsl_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm)
{
struct fsl_pwm_chip *fpc = to_fsl_chip(chip);
- clk_disable_unprepare(fpc->clk[FSL_PWM_CLK_SYS]);
+ fsl_pwm_mode_disable(fpc);
}
static int fsl_pwm_calculate_default_ps(struct fsl_pwm_chip *fpc,
@@ -323,6 +346,9 @@ static int fsl_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
mutex_lock(&fpc->lock);
regmap_update_bits(fpc->regmap, FTM_OUTMASK, BIT(pwm->hwpwm), 0);
+ if (fpc->has_pwmen)
+ regmap_update_bits(fpc->regmap, FTM_SC,
+ BIT(pwm->hwpwm + 16), BIT(pwm->hwpwm + 16));
ret = fsl_counter_clock_enable(fpc);
mutex_unlock(&fpc->lock);
@@ -336,6 +362,10 @@ static void fsl_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
u32 val;
mutex_lock(&fpc->lock);
+
+ if (fpc->has_pwmen)
+ regmap_update_bits(fpc->regmap, FTM_SC, BIT(pwm->hwpwm + 16), 0);
+
regmap_update_bits(fpc->regmap, FTM_OUTMASK, BIT(pwm->hwpwm),
BIT(pwm->hwpwm));
@@ -363,7 +393,7 @@ static int fsl_pwm_init(struct fsl_pwm_chip *fpc)
{
int ret;
- ret = clk_prepare_enable(fpc->clk[FSL_PWM_CLK_SYS]);
+ ret = fsl_pwm_mode_enable(fpc);
if (ret)
return ret;
@@ -371,7 +401,7 @@ static int fsl_pwm_init(struct fsl_pwm_chip *fpc)
regmap_write(fpc->regmap, FTM_OUTINIT, 0x00);
regmap_write(fpc->regmap, FTM_OUTMASK, 0xFF);
- clk_disable_unprepare(fpc->clk[FSL_PWM_CLK_SYS]);
+ fsl_pwm_mode_disable(fpc);
return 0;
}
@@ -422,7 +452,12 @@ static int fsl_pwm_probe(struct platform_device *pdev)
return PTR_ERR(fpc->regmap);
}
+ fpc->ipg_clk = devm_clk_get(&pdev->dev, "ipg");
+ if (IS_ERR(fpc->ipg_clk))
+ fpc->ipg_clk = 0;
+
fpc->clk[FSL_PWM_CLK_SYS] = devm_clk_get(&pdev->dev, "ftm_sys");
+
if (IS_ERR(fpc->clk[FSL_PWM_CLK_SYS])) {
dev_err(&pdev->dev, "failed to get \"ftm_sys\" clock\n");
return PTR_ERR(fpc->clk[FSL_PWM_CLK_SYS]);
@@ -446,6 +481,8 @@ static int fsl_pwm_probe(struct platform_device *pdev)
fpc->chip.of_pwm_n_cells = 3;
fpc->chip.base = -1;
fpc->chip.npwm = 8;
+ fpc->has_pwmen = of_property_read_bool(pdev->dev.of_node,
+ "ftm-has-pwmen-bits");
ret = pwmchip_add(&fpc->chip);
if (ret < 0) {
@@ -480,7 +517,7 @@ static int fsl_pwm_suspend(struct device *dev)
if (!test_bit(PWMF_REQUESTED, &pwm->flags))
continue;
- clk_disable_unprepare(fpc->clk[FSL_PWM_CLK_SYS]);
+ fsl_pwm_mode_disable(fpc);
if (!pwm_is_enabled(pwm))
continue;
@@ -503,7 +540,7 @@ static int fsl_pwm_resume(struct device *dev)
if (!test_bit(PWMF_REQUESTED, &pwm->flags))
continue;
- clk_prepare_enable(fpc->clk[FSL_PWM_CLK_SYS]);
+ fsl_pwm_mode_enable(fpc);
if (!pwm_is_enabled(pwm))
continue;
diff --git a/drivers/pwm/pwm-imx.c b/drivers/pwm/pwm-imx.c
index 2ba5c3a398ff..e67a6172deea 100644
--- a/drivers/pwm/pwm-imx.c
+++ b/drivers/pwm/pwm-imx.c
@@ -1,4 +1,6 @@
/*
+ * Copyright 2017-2018 NXP
+ *
* simple driver for PWM (Pulse Width Modulator) controller
*
* This program is free software; you can redistribute it and/or modify
@@ -50,6 +52,8 @@
struct imx_chip {
struct clk *clk_per;
+ struct clk *clk_ipg;
+ struct clk *clk_32k;
void __iomem *mmio_base;
@@ -58,6 +62,45 @@ struct imx_chip {
#define to_imx_chip(chip) container_of(chip, struct imx_chip, chip)
+static int imx_pwm_clk_prepare_enable(struct pwm_chip *chip)
+{
+ struct imx_chip *imx = to_imx_chip(chip);
+ int ret;
+
+ if (imx->clk_32k) {
+ ret = clk_prepare_enable(imx->clk_32k);
+ if (ret)
+ goto err1;
+ }
+
+ ret = clk_prepare_enable(imx->clk_per);
+ if (ret)
+ goto err2;
+
+ ret = clk_prepare_enable(imx->clk_ipg);
+ if (ret)
+ goto err3;
+
+ return 0;
+err3:
+ clk_disable_unprepare(imx->clk_per);
+err2:
+ if (imx->clk_32k)
+ clk_disable_unprepare(imx->clk_32k);
+err1:
+ return ret;
+}
+
+static void imx_pwm_clk_disable_unprepare(struct pwm_chip *chip)
+{
+ struct imx_chip *imx = to_imx_chip(chip);
+
+ clk_disable_unprepare(imx->clk_ipg);
+ clk_disable_unprepare(imx->clk_per);
+ if (imx->clk_32k)
+ clk_disable_unprepare(imx->clk_32k);
+}
+
static int imx_pwm_config_v1(struct pwm_chip *chip,
struct pwm_device *pwm, int duty_ns, int period_ns)
{
@@ -199,7 +242,7 @@ static int imx_pwm_apply_v2(struct pwm_chip *chip, struct pwm_device *pwm,
if (cstate.enabled) {
imx_pwm_wait_fifo_slot(chip, pwm);
} else {
- ret = clk_prepare_enable(imx->clk_per);
+ ret = imx_pwm_clk_prepare_enable(chip);
if (ret)
return ret;
@@ -221,7 +264,7 @@ static int imx_pwm_apply_v2(struct pwm_chip *chip, struct pwm_device *pwm,
} else if (cstate.enabled) {
writel(0, imx->mmio_base + MX3_PWMCR);
- clk_disable_unprepare(imx->clk_per);
+ imx_pwm_clk_disable_unprepare(chip);
}
return 0;
@@ -285,6 +328,17 @@ static int imx_pwm_probe(struct platform_device *pdev)
return PTR_ERR(imx->clk_per);
}
+ imx->clk_ipg = devm_clk_get(&pdev->dev, "ipg");
+ if (IS_ERR(imx->clk_ipg)) {
+ dev_err(&pdev->dev, "getting ipg clock failed with %ld\n",
+ PTR_ERR(imx->clk_ipg));
+ return PTR_ERR(imx->clk_ipg);
+ }
+
+ imx->clk_32k = devm_clk_get(&pdev->dev, "32k");
+ if (IS_ERR(imx->clk_32k))
+ imx->clk_32k = NULL;
+
imx->chip.ops = data->ops;
imx->chip.dev = &pdev->dev;
imx->chip.base = -1;
diff --git a/drivers/pwm/pwm-tpm.c b/drivers/pwm/pwm-tpm.c
new file mode 100644
index 000000000000..98cdcceb5f11
--- /dev/null
+++ b/drivers/pwm/pwm-tpm.c
@@ -0,0 +1,258 @@
+/*
+ * Copyright 2017-2018 NXP.
+ *
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#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_address.h>
+#include <linux/platform_device.h>
+#include <linux/pwm.h>
+#include <linux/slab.h>
+
+#define TPM_GLOBAL 0x8
+#define TPM_SC 0x10
+#define TPM_CNT 0x14
+#define TPM_MOD 0x18
+#define TPM_C0SC 0x20
+#define TPM_C0V 0x24
+
+#define SC_CMOD 3
+#define SC_CPWMS BIT(5)
+#define MSnB BIT(5)
+#define MSnA BIT(4)
+#define ELSnB BIT(3)
+#define ELSnA BIT(2)
+
+#define PERIOD_PERIOD_MAX 0x10000
+#define PERIOD_DIV_MAX 8
+
+struct tpm_pwm_chip {
+ struct pwm_chip chip;
+ struct clk *clk;
+ void __iomem *base;
+};
+
+static const unsigned int prediv[8] = {
+ 1, 2, 4, 8, 16, 32, 64, 128
+};
+
+#define to_tpm_pwm_chip(_chip) container_of(_chip, struct tpm_pwm_chip, chip)
+
+static int tpm_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
+ int duty_ns, int period_ns)
+{
+ struct tpm_pwm_chip *tpm = to_tpm_pwm_chip(chip);
+ int ret, val, div = 0;
+ unsigned int period_cycles, duty_cycles;
+ unsigned long rate;
+ u64 c;
+
+ rate = clk_get_rate(tpm->clk);
+ /* calculate the period_cycles and duty_cycles */
+ while (1) {
+ c = rate / prediv[div];
+ c = c * period_ns;
+ do_div(c, 1000000000);
+ if (c < PERIOD_PERIOD_MAX)
+ break;
+ div++;
+ if (div >= 8)
+ return -EINVAL;
+ }
+
+ /* enable the clock before writing the register */
+ if (!pwm_is_enabled(pwm)) {
+ ret = clk_prepare_enable(tpm->clk);
+ if (ret)
+ return ret;
+ }
+
+ /* set the pre-scale */
+ val = readl(tpm->base + TPM_SC);
+ val &= ~0x7;
+ val |= div;
+ writel(val, tpm->base + TPM_SC);
+
+ period_cycles = c;
+ c *= duty_ns;
+ do_div(c, period_ns);
+ duty_cycles = c;
+
+ writel(period_cycles & 0xffff, tpm->base + TPM_MOD);
+ writel(duty_cycles & 0xffff, tpm->base + TPM_C0V + pwm->hwpwm * 0x8);
+
+ /* if pwm is not enabled, disable clk after setting */
+ if (!pwm_is_enabled(pwm))
+ clk_disable_unprepare(tpm->clk);
+
+ return 0;
+}
+
+static int tpm_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
+{
+ struct tpm_pwm_chip *tpm = to_tpm_pwm_chip(chip);
+ int val;
+
+ clk_prepare_enable(tpm->clk);
+ /*
+ * To enable a tpm channel, CPWMS = 0, MSnB:MSnA = 0x0,
+ * for TPM normal polarity ELSnB:ELSnA = 2b'10,
+ * inverse ELSnB:ELSnA = 2b'01
+ */
+ val = readl(tpm->base + TPM_C0SC + pwm->hwpwm * 0x8);
+
+ val &= ~(MSnB | MSnA | ELSnB | ELSnA);
+ val |= MSnB;
+ val |= pwm->state.polarity ? ELSnA : ELSnB;
+
+ writel(val, tpm->base + TPM_C0SC + pwm->hwpwm * 0x8);
+
+ /* start the counter */
+ val = readl(tpm->base + TPM_SC);
+ val |= 0x1 << SC_CMOD;
+ writel(val, tpm->base + TPM_SC);
+
+ return 0;
+}
+
+static void tpm_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
+{
+ struct tpm_pwm_chip *tpm = to_tpm_pwm_chip(chip);
+
+ clk_disable_unprepare(tpm->clk);
+}
+
+static int tpm_pwm_set_polarity(struct pwm_chip *chip,
+ struct pwm_device *pwm,
+ enum pwm_polarity polarity)
+{
+ struct tpm_pwm_chip *tpm = to_tpm_pwm_chip(chip);
+ int ret, val;
+
+ /* enable the clock before writing the register */
+ if (!pwm_is_enabled(pwm)) {
+ ret = clk_prepare_enable(tpm->clk);
+ if (ret)
+ return ret;
+ }
+
+ val = readl(tpm->base + TPM_C0SC + pwm->hwpwm * 0x8);
+ val &= ~(ELSnB | ELSnA);
+ val |= pwm->state.polarity ? ELSnA : ELSnB;
+ writel(val, tpm->base + TPM_C0SC + pwm->hwpwm * 0x8);
+
+ if (!pwm_is_enabled(pwm))
+ clk_disable_unprepare(tpm->clk);
+
+ return 0;
+}
+
+static const struct pwm_ops tpm_pwm_ops = {
+ .config = tpm_pwm_config,
+ .enable = tpm_pwm_enable,
+ .disable = tpm_pwm_disable,
+ .set_polarity = tpm_pwm_set_polarity,
+ .owner = THIS_MODULE,
+};
+
+static int tpm_pwm_probe(struct platform_device *pdev)
+{
+ struct device_node *np = pdev->dev.of_node;
+ struct tpm_pwm_chip *tpm;
+ struct resource *res;
+ int ret;
+
+ tpm = devm_kzalloc(&pdev->dev, sizeof(*tpm), GFP_KERNEL);
+ if (!tpm)
+ return -ENOMEM;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ tpm->base = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(tpm->base))
+ return PTR_ERR(tpm->base);
+
+ tpm->clk = devm_clk_get(&pdev->dev, NULL);
+ if (IS_ERR(tpm->clk))
+ return PTR_ERR(tpm->clk);
+
+ tpm->chip.dev = &pdev->dev;
+ tpm->chip.ops = &tpm_pwm_ops;
+ tpm->chip.base = -1;
+ /*
+ * init the number of pwm in the pwm chip. if no "fsl,pwm-number"
+ * found, init the npwm to 2, as tpm module has at least two pwm channel
+ */
+ ret = of_property_read_u32(np, "nxp,pwm-number", &tpm->chip.npwm);
+ if (ret < 0) {
+ dev_info(&pdev->dev, "default two pwm channel");
+ tpm->chip.npwm = 2;
+ }
+
+ ret = pwmchip_add(&tpm->chip);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "failed to add pwm chip %d\n", ret);
+ return ret;
+ }
+
+ platform_set_drvdata(pdev, tpm);
+
+ return 0;
+}
+
+static int tpm_pwm_remove(struct platform_device *pdev)
+{
+ struct tpm_pwm_chip *tpm = platform_get_drvdata(pdev);
+
+ return pwmchip_remove(&tpm->chip);
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int tpm_pwm_suspend(struct device *dev)
+{
+ pinctrl_pm_select_sleep_state(dev);
+
+ return 0;
+}
+
+static int tpm_pwm_resume(struct device *dev)
+{
+ pinctrl_pm_select_default_state(dev);
+
+ return 0;
+};
+#endif
+
+static SIMPLE_DEV_PM_OPS(tpm_pwm_pm, tpm_pwm_suspend, tpm_pwm_resume);
+
+static const struct of_device_id tpm_pwm_dt_ids[] = {
+ { .compatible = "nxp,tpm-pwm", },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, tpm_pwm_dt_ids);
+
+static struct platform_driver tpm_pwm_driver = {
+ .driver = {
+ .name = "tpm-pwm",
+ .of_match_table = tpm_pwm_dt_ids,
+ .pm = &tpm_pwm_pm,
+ },
+ .probe = tpm_pwm_probe,
+ .remove = tpm_pwm_remove,
+};
+module_platform_driver(tpm_pwm_driver);
+
+MODULE_ALIAS("platform:tpm-pwm");
+MODULE_AUTHOR("Jacky Bai <ping.bai@nxp.com>");
+MODULE_DESCRIPTION("NXP TPM PWM Driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index 0fd6195601ba..5361947ea726 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -421,6 +421,10 @@ config REGULATOR_MAX1586
regulator via I2C bus. The provided regulator is suitable
for PXA27x chips to control VCC_CORE and VCC_USIM voltages.
+config REGULATOR_MAX17135
+ tristate "Maxim MAX17135 Regulator Support"
+ depends on MFD_MAX17135
+
config REGULATOR_MAX77620
tristate "Maxim 77620/MAX20024 voltage regulator"
depends on MFD_MAX77620
@@ -643,6 +647,21 @@ config REGULATOR_PV88090
Say y here to support the voltage regulators and convertors
on PV88090
+config REGULATOR_PF1550
+ tristate "Freescale PF1550 regulator"
+ depends on MFD_PF1550
+ help
+ This driver controls a PF1550 regulator via I2C bus.
+ The regulators include three switch and three ldo.
+
+config REGULATOR_PF1550_RPMSG
+ tristate "Freescale PF1550 rpmsg regulator driver"
+ depends on RPMSG
+ help
+ This driver controls a PF1550 regulator which connected in M4
+ side via RPMSG.The regulators include three switch and three
+ ldo.
+
config REGULATOR_PWM
tristate "PWM voltage regulator"
depends on PWM
@@ -958,5 +977,11 @@ config REGULATOR_WM8994
This driver provides support for the voltage regulators on the
WM8994 CODEC.
+config REGULATOR_BD71837
+ tristate "RoHM BD71837 Power Regulator"
+ depends on MFD_BD71837
+ help
+ This driver supports BD71837 voltage regulator chips.
+
endif
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
index 80ffc57a9ca3..1bddbefbc8e7 100644
--- a/drivers/regulator/Makefile
+++ b/drivers/regulator/Makefile
@@ -56,6 +56,7 @@ obj-$(CONFIG_REGULATOR_LTC3589) += ltc3589.o
obj-$(CONFIG_REGULATOR_LTC3676) += ltc3676.o
obj-$(CONFIG_REGULATOR_MAX14577) += max14577-regulator.o
obj-$(CONFIG_REGULATOR_MAX1586) += max1586.o
+obj-$(CONFIG_REGULATOR_MAX17135) += max17135-regulator.o
obj-$(CONFIG_REGULATOR_MAX77620) += max77620-regulator.o
obj-$(CONFIG_REGULATOR_MAX8649) += max8649.o
obj-$(CONFIG_REGULATOR_MAX8660) += max8660.o
@@ -79,6 +80,8 @@ obj-$(CONFIG_REGULATOR_QCOM_RPM) += qcom_rpm-regulator.o
obj-$(CONFIG_REGULATOR_QCOM_SMD_RPM) += qcom_smd-regulator.o
obj-$(CONFIG_REGULATOR_QCOM_SPMI) += qcom_spmi-regulator.o
obj-$(CONFIG_REGULATOR_PALMAS) += palmas-regulator.o
+obj-$(CONFIG_REGULATOR_PF1550) += pf1550.o
+obj-$(CONFIG_REGULATOR_PF1550_RPMSG) += pf1550-regulator-rpmsg.o
obj-$(CONFIG_REGULATOR_PFUZE100) += pfuze100-regulator.o
obj-$(CONFIG_REGULATOR_PV88060) += pv88060-regulator.o
obj-$(CONFIG_REGULATOR_PV88080) += pv88080-regulator.o
@@ -122,6 +125,7 @@ obj-$(CONFIG_REGULATOR_WM831X) += wm831x-ldo.o
obj-$(CONFIG_REGULATOR_WM8350) += wm8350-regulator.o
obj-$(CONFIG_REGULATOR_WM8400) += wm8400-regulator.o
obj-$(CONFIG_REGULATOR_WM8994) += wm8994-regulator.o
+obj-$(CONFIG_REGULATOR_BD71837) += bd71837-regulator.o
ccflags-$(CONFIG_REGULATOR_DEBUG) += -DDEBUG
diff --git a/drivers/regulator/anatop-regulator.c b/drivers/regulator/anatop-regulator.c
index 7d6478e6a503..7480ccdd93b8 100644
--- a/drivers/regulator/anatop-regulator.c
+++ b/drivers/regulator/anatop-regulator.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright (C) 2011-2015 Freescale Semiconductor, Inc. All Rights Reserved.
*/
/*
@@ -38,6 +38,8 @@
#define LDO_POWER_GATE 0x00
#define LDO_FET_FULL_ON 0x1f
+#define LDO_MIN_DROPOUT_UV 125000
+
struct anatop_regulator {
u32 control_reg;
struct regmap *anatop;
@@ -53,8 +55,12 @@ struct anatop_regulator {
struct regulator_init_data *initdata;
bool bypass;
int sel;
+ u32 enable_bit;
};
+static struct anatop_regulator *vddpu;
+static struct anatop_regulator *vddsoc;
+
static int anatop_regmap_set_voltage_time_sel(struct regulator_dev *reg,
unsigned int old_sel,
unsigned int new_sel)
@@ -81,21 +87,32 @@ static int anatop_regmap_set_voltage_time_sel(struct regulator_dev *reg,
return ret;
}
-static int anatop_regmap_enable(struct regulator_dev *reg)
+static int anatop_core_regmap_enable(struct regulator_dev *reg)
{
struct anatop_regulator *anatop_reg = rdev_get_drvdata(reg);
int sel;
+ /*
+ * The vddpu has to stay at the same voltage level as vddsoc
+ * whenever it's about to be enabled.
+ */
+ if (anatop_reg == vddpu && vddsoc) {
+ anatop_reg->sel = vddsoc->sel;
+ anatop_reg->bypass = vddsoc->bypass;
+ if (anatop_reg->bypass)
+ anatop_reg->rdesc.min_dropout_uV = 0;
+ }
+
sel = anatop_reg->bypass ? LDO_FET_FULL_ON : anatop_reg->sel;
return regulator_set_voltage_sel_regmap(reg, sel);
}
-static int anatop_regmap_disable(struct regulator_dev *reg)
+static int anatop_core_regmap_disable(struct regulator_dev *reg)
{
return regulator_set_voltage_sel_regmap(reg, LDO_POWER_GATE);
}
-static int anatop_regmap_is_enabled(struct regulator_dev *reg)
+static int anatop_core_regmap_is_enabled(struct regulator_dev *reg)
{
return regulator_get_voltage_sel_regmap(reg) != LDO_POWER_GATE;
}
@@ -106,7 +123,7 @@ static int anatop_regmap_core_set_voltage_sel(struct regulator_dev *reg,
struct anatop_regulator *anatop_reg = rdev_get_drvdata(reg);
int ret;
- if (anatop_reg->bypass || !anatop_regmap_is_enabled(reg)) {
+ if (anatop_reg->bypass || !anatop_core_regmap_is_enabled(reg)) {
anatop_reg->sel = selector;
return 0;
}
@@ -121,7 +138,7 @@ static int anatop_regmap_core_get_voltage_sel(struct regulator_dev *reg)
{
struct anatop_regulator *anatop_reg = rdev_get_drvdata(reg);
- if (anatop_reg->bypass || !anatop_regmap_is_enabled(reg))
+ if (anatop_reg->bypass || !anatop_core_regmap_is_enabled(reg))
return anatop_reg->sel;
return regulator_get_voltage_sel_regmap(reg);
@@ -152,11 +169,52 @@ static int anatop_regmap_set_bypass(struct regulator_dev *reg, bool enable)
sel = enable ? LDO_FET_FULL_ON : anatop_reg->sel;
anatop_reg->bypass = enable;
+ if (anatop_reg->bypass)
+ anatop_reg->rdesc.min_dropout_uV = 0;
+ else
+ anatop_reg->rdesc.min_dropout_uV = LDO_MIN_DROPOUT_UV;
return regulator_set_voltage_sel_regmap(reg, sel);
}
+static int anatop_regmap_enable(struct regulator_dev *reg)
+{
+ u32 val;
+ struct anatop_regulator *anatop_reg = rdev_get_drvdata(reg);
+
+ regmap_read(anatop_reg->anatop, anatop_reg->control_reg, &val);
+ val |= (1 << anatop_reg->enable_bit);
+ regmap_write(anatop_reg->anatop, anatop_reg->control_reg, val);
+
+ return 0;
+}
+
+static int anatop_regmap_disable(struct regulator_dev *reg)
+{
+ u32 val;
+ struct anatop_regulator *anatop_reg = rdev_get_drvdata(reg);
+
+ regmap_read(anatop_reg->anatop, anatop_reg->control_reg, &val);
+ val &= ~(1 << anatop_reg->enable_bit);
+ regmap_write(anatop_reg->anatop, anatop_reg->control_reg, val);
+
+ return 0;
+}
+
+static int anatop_regmap_is_enabled(struct regulator_dev *reg)
+{
+ u32 val;
+ struct anatop_regulator *anatop_reg = rdev_get_drvdata(reg);
+
+ regmap_read(anatop_reg->anatop, anatop_reg->control_reg, &val);
+
+ return !!(val & (1 << anatop_reg->enable_bit));
+}
+
static struct regulator_ops anatop_rops = {
+ .enable = anatop_regmap_enable,
+ .disable = anatop_regmap_disable,
+ .is_enabled = anatop_regmap_is_enabled,
.set_voltage_sel = regulator_set_voltage_sel_regmap,
.get_voltage_sel = regulator_get_voltage_sel_regmap,
.list_voltage = regulator_list_voltage_linear,
@@ -164,9 +222,9 @@ static struct regulator_ops anatop_rops = {
};
static struct regulator_ops anatop_core_rops = {
- .enable = anatop_regmap_enable,
- .disable = anatop_regmap_disable,
- .is_enabled = anatop_regmap_is_enabled,
+ .enable = anatop_core_regmap_enable,
+ .disable = anatop_core_regmap_disable,
+ .is_enabled = anatop_core_regmap_is_enabled,
.set_voltage_sel = anatop_regmap_core_set_voltage_sel,
.set_voltage_time_sel = anatop_regmap_set_voltage_time_sel,
.get_voltage_sel = anatop_regmap_core_get_voltage_sel,
@@ -210,6 +268,11 @@ static int anatop_regulator_probe(struct platform_device *pdev)
initdata->supply_regulator = "vin";
sreg->initdata = initdata;
+ if (strcmp(rdesc->name, "vddpu") == 0)
+ vddpu = sreg;
+ else if (strcmp(rdesc->name, "vddsoc") == 0)
+ vddsoc = sreg;
+
anatop_np = of_get_parent(np);
if (!anatop_np)
return -ENODEV;
@@ -263,6 +326,9 @@ static int anatop_regulator_probe(struct platform_device *pdev)
of_property_read_u32(np, "anatop-delay-bit-shift",
&sreg->delay_bit_shift);
+ /* Only 3p0, 2p5, and 1p1 has enable bit */
+ of_property_read_u32(np, "anatop-enable-bit", &sreg->enable_bit);
+
rdesc->n_voltages = (sreg->max_voltage - sreg->min_voltage) / 25000 + 1
+ sreg->min_bit_val;
rdesc->min_uV = sreg->min_voltage;
@@ -271,7 +337,7 @@ static int anatop_regulator_probe(struct platform_device *pdev)
rdesc->vsel_reg = sreg->control_reg;
rdesc->vsel_mask = ((1 << sreg->vol_bit_width) - 1) <<
sreg->vol_bit_shift;
- rdesc->min_dropout_uV = 125000;
+ rdesc->min_dropout_uV = LDO_MIN_DROPOUT_UV;
config.dev = &pdev->dev;
config.init_data = initdata;
@@ -293,6 +359,7 @@ static int anatop_regulator_probe(struct platform_device *pdev)
if (sreg->sel == LDO_FET_FULL_ON) {
sreg->sel = 0;
sreg->bypass = true;
+ rdesc->min_dropout_uV = 0;
}
/*
@@ -304,7 +371,7 @@ static int anatop_regulator_probe(struct platform_device *pdev)
sreg->sel = 22;
/* set the default voltage of the pcie phy to be 1.100v */
- if (!sreg->sel && !strcmp(rdesc->name, "vddpcie"))
+ if (!sreg->sel && !strcmp(rdesc->name, "vddpcie-phy"))
sreg->sel = 0x10;
if (!sreg->bypass && !sreg->sel) {
@@ -330,9 +397,10 @@ static int anatop_regulator_probe(struct platform_device *pdev)
/* register regulator */
rdev = devm_regulator_register(dev, rdesc, &config);
if (IS_ERR(rdev)) {
- dev_err(dev, "failed to register %s\n",
- rdesc->name);
- return PTR_ERR(rdev);
+ ret = PTR_ERR(rdev);
+ if (ret != -EPROBE_DEFER)
+ dev_err(dev, "failed to register %s\n", rdesc->name);
+ return ret;
}
platform_set_drvdata(pdev, rdev);
diff --git a/drivers/regulator/bd71837-regulator.c b/drivers/regulator/bd71837-regulator.c
new file mode 100644
index 000000000000..0052f0212a27
--- /dev/null
+++ b/drivers/regulator/bd71837-regulator.c
@@ -0,0 +1,1054 @@
+/*
+ * @file bd71837-regulator.c ROHM BD71837MWV regulator driver
+ *
+ * @author: cpham2403@gmail.com
+ * Copyright 2017.
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ */
+#define DEBUG
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/err.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/machine.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/gpio.h>
+#include <linux/mfd/bd71837.h>
+#include <linux/regulator/of_regulator.h>
+
+#define BD71837_DVS_BUCK_NUM 4 /* Buck 1/2/3/4 support DVS */
+#define BD71837_DVS_RUN_IDLE_SUSP 3
+#define BD71837_DVS_RUN_IDLE 2
+#define BD71837_DVS_RUN 1
+
+struct bd71837_buck_dvs {
+ u32 voltage[BD71837_DVS_RUN_IDLE_SUSP];
+};
+
+/** @brief bd71837 regulator type */
+struct bd71837_pmic {
+ struct regulator_desc descs[BD71837_REGULATOR_CNT]; /**< regulator description to system */
+ struct bd71837 *mfd; /**< parent device */
+ struct device *dev; /**< regulator kernel device */
+ struct regulator_dev *rdev[BD71837_REGULATOR_CNT]; /**< regulator device of system */
+ struct bd71837_buck_dvs buck_dvs[BD71837_DVS_BUCK_NUM]; /**< buck1/2 dvs */
+ int reg_index;
+};
+
+/*
+ * BUCK1/2/3/4
+ * BUCK1RAMPRATE[1:0] BUCK1 DVS ramp rate setting
+ * 00: 10.00mV/usec 10mV 1uS
+ * 01: 5.00mV/usec 10mV 2uS
+ * 10: 2.50mV/usec 10mV 4uS
+ * 11: 1.25mV/usec 10mV 8uS
+ */
+static int bd71837_buck1234_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay)
+{
+ struct bd71837_pmic *pmic = rdev_get_drvdata(rdev);
+ struct bd71837 *mfd = pmic->mfd;
+ int id = rdev->desc->id;
+ unsigned int ramp_value = BUCK1_RAMPRATE_10P00MV;
+
+ dev_dbg(pmic->dev, "Buck[%d] Set Ramp = %d\n", id + 1, ramp_delay);
+ switch (ramp_delay) {
+ case 1 ... 1250:
+ ramp_value = BUCK1_RAMPRATE_1P25MV;
+ break;
+ case 1251 ... 2500:
+ ramp_value = BUCK1_RAMPRATE_2P50MV;
+ break;
+ case 2501 ... 5000:
+ ramp_value = BUCK1_RAMPRATE_5P00MV;
+ break;
+ case 5001 ... 10000:
+ ramp_value = BUCK1_RAMPRATE_10P00MV;
+ break;
+ default:
+ ramp_value = BUCK1_RAMPRATE_10P00MV;
+ dev_err(pmic->dev, "%s: ramp_delay: %d not supported, setting 10000mV//us\n",
+ rdev->desc->name, ramp_delay);
+ }
+
+ return regmap_update_bits(mfd->regmap, BD71837_REG_BUCK1_CTRL + id,
+ BUCK1_RAMPRATE_MASK, ramp_value << 6);
+}
+
+static struct regulator_ops bd71837_ldo_regulator_ops = {
+ .enable = regulator_enable_regmap,
+ .disable = regulator_disable_regmap,
+ .is_enabled = regulator_is_enabled_regmap,
+ .list_voltage = regulator_list_voltage_linear_range,
+ .set_voltage_sel = regulator_set_voltage_sel_regmap,
+ .get_voltage_sel = regulator_get_voltage_sel_regmap,
+};
+
+static struct regulator_ops bd71837_fixed_regulator_ops = {
+ .enable = regulator_enable_regmap,
+ .disable = regulator_disable_regmap,
+ .is_enabled = regulator_is_enabled_regmap,
+ .list_voltage = regulator_list_voltage_linear,
+};
+
+static struct regulator_ops bd71837_buck_regulator_ops = {
+ .is_enabled = regulator_is_enabled_regmap,
+ .list_voltage = regulator_list_voltage_linear_range,
+ .set_voltage_sel = regulator_set_voltage_sel_regmap,
+ .get_voltage_sel = regulator_get_voltage_sel_regmap,
+ .set_voltage_time_sel = regulator_set_voltage_time_sel,
+};
+
+static struct regulator_ops bd71837_buck1234_regulator_ops = {
+ .is_enabled = regulator_is_enabled_regmap,
+ .list_voltage = regulator_list_voltage_linear_range,
+ .set_voltage_sel = regulator_set_voltage_sel_regmap,
+ .get_voltage_sel = regulator_get_voltage_sel_regmap,
+ .set_voltage_time_sel = regulator_set_voltage_time_sel,
+ .set_ramp_delay = bd71837_buck1234_set_ramp_delay,
+};
+
+/*
+ * BUCK1/2/3/4
+ * 0.70 to 1.30V (10mV step)
+ */
+static const struct regulator_linear_range bd71837_buck1234_voltage_ranges[] = {
+ REGULATOR_LINEAR_RANGE(700000, 0x00, 0x3C, 10000),
+ REGULATOR_LINEAR_RANGE(1300000, 0x3D, 0x3F, 0),
+};
+
+/*
+ * BUCK5
+ * 0.9V to 1.35V ()
+ */
+static const struct regulator_linear_range bd71837_buck5_voltage_ranges[] = {
+ REGULATOR_LINEAR_RANGE(700000, 0x00, 0x03, 100000),
+ REGULATOR_LINEAR_RANGE(1050000, 0x04, 0x05, 50000),
+ REGULATOR_LINEAR_RANGE(1200000, 0x06, 0x07, 150000),
+};
+
+/*
+ * BUCK6
+ * 3.0V to 3.3V (step 100mV)
+ */
+static const struct regulator_linear_range bd71837_buck6_voltage_ranges[] = {
+ REGULATOR_LINEAR_RANGE(3000000, 0x00, 0x03, 100000),
+};
+
+/*
+ * BUCK7
+ * 1.605V to 1.995V ()
+ * 000 = 1.605V
+ * 001 = 1.695V
+ * 010 = 1.755V
+ * 011 = 1.8V (Initial)
+ * 100 = 1.845V
+ * 101 = 1.905V
+ * 110 = 1.95V
+ * 111 = 1.995V
+ */
+static const struct regulator_linear_range bd71837_buck7_voltage_ranges[] = {
+ REGULATOR_LINEAR_RANGE(1605000, 0x00, 0x01, 90000),
+ REGULATOR_LINEAR_RANGE(1755000, 0x02, 0x03, 45000),
+ REGULATOR_LINEAR_RANGE(1845000, 0x04, 0x05, 60000),
+ REGULATOR_LINEAR_RANGE(1950000, 0x06, 0x07, 45000),
+};
+
+/*
+ * BUCK8
+ * 0.8V to 1.40V (step 10mV)
+ */
+static const struct regulator_linear_range bd71837_buck8_voltage_ranges[] = {
+ REGULATOR_LINEAR_RANGE(800000, 0x00, 0x3C, 10000),
+ REGULATOR_LINEAR_RANGE(1400000, 0x3D, 0x3F, 0),
+};
+
+/*
+ * LDO1
+ * 3.0 to 3.3V (100mV step)
+ */
+static const struct regulator_linear_range bd71837_ldo1_voltage_ranges[] = {
+ REGULATOR_LINEAR_RANGE(3000000, 0x00, 0x03, 100000),
+};
+
+/*
+ * LDO3
+ * 1.8 to 3.3V (100mV step)
+ */
+static const struct regulator_linear_range bd71837_ldo3_voltage_ranges[] = {
+ REGULATOR_LINEAR_RANGE(1800000, 0x00, 0x0F, 100000),
+};
+
+/*
+ * LDO4
+ * 0.9 to 1.8V (100mV step)
+ */
+static const struct regulator_linear_range bd71837_ldo4_voltage_ranges[] = {
+ REGULATOR_LINEAR_RANGE(900000, 0x00, 0x09, 100000),
+ REGULATOR_LINEAR_RANGE(1800000, 0x0A, 0x0F, 0),
+};
+
+/*
+ * LDO5
+ * 1.8 to 3.3V (100mV step)
+ */
+static const struct regulator_linear_range bd71837_ldo5_voltage_ranges[] = {
+ REGULATOR_LINEAR_RANGE(1800000, 0x00, 0x0F, 100000),
+};
+
+/*
+ * LDO6
+ * 0.9 to 1.8V (100mV step)
+ */
+static const struct regulator_linear_range bd71837_ldo6_voltage_ranges[] = {
+ REGULATOR_LINEAR_RANGE(900000, 0x00, 0x09, 100000),
+ REGULATOR_LINEAR_RANGE(1800000, 0x0A, 0x0F, 0),
+};
+
+/*
+ * LDO7
+ * 1.8 to 3.3V (100mV step)
+ */
+static const struct regulator_linear_range bd71837_ldo7_voltage_ranges[] = {
+ REGULATOR_LINEAR_RANGE(1800000, 0x00, 0x0F, 100000),
+};
+
+static const struct regulator_desc bd71837_regulators[] = {
+ {
+ .name = "BUCK1",
+ .id = BD71837_BUCK1,
+ .ops = &bd71837_buck1234_regulator_ops,
+ .type = REGULATOR_VOLTAGE,
+ .n_voltages = BD71837_BUCK1_VOLTAGE_NUM,
+ .linear_ranges = bd71837_buck1234_voltage_ranges,
+ .n_linear_ranges = ARRAY_SIZE(bd71837_buck1234_voltage_ranges),
+ .vsel_reg = BD71837_REG_BUCK1_VOLT_RUN,
+ .vsel_mask = BUCK1_RUN_MASK,
+ .enable_reg = BD71837_REG_BUCK1_CTRL,
+ .enable_mask = BUCK1_SEL|BUCK1_EN,
+ .owner = THIS_MODULE,
+ },
+ {
+ .name = "BUCK2",
+ .id = BD71837_BUCK2,
+ .ops = &bd71837_buck1234_regulator_ops,
+ .type = REGULATOR_VOLTAGE,
+ .n_voltages = BD71837_BUCK2_VOLTAGE_NUM,
+ .linear_ranges = bd71837_buck1234_voltage_ranges,
+ .n_linear_ranges = ARRAY_SIZE(bd71837_buck1234_voltage_ranges),
+ .vsel_reg = BD71837_REG_BUCK2_VOLT_RUN,
+ .vsel_mask = BUCK2_RUN_MASK,
+ .enable_reg = BD71837_REG_BUCK2_CTRL,
+ .enable_mask = BUCK2_SEL|BUCK2_EN,
+ .owner = THIS_MODULE,
+ },
+ {
+ .name = "BUCK3",
+ .id = BD71837_BUCK3,
+ .ops = &bd71837_buck1234_regulator_ops,
+ .type = REGULATOR_VOLTAGE,
+ .n_voltages = BD71837_BUCK3_VOLTAGE_NUM,
+ .linear_ranges = bd71837_buck1234_voltage_ranges,
+ .n_linear_ranges = ARRAY_SIZE(bd71837_buck1234_voltage_ranges),
+ .vsel_reg = BD71837_REG_BUCK3_VOLT_RUN,
+ .vsel_mask = BUCK3_RUN_MASK,
+ .enable_reg = BD71837_REG_BUCK3_CTRL,
+ .enable_mask = BUCK3_SEL|BUCK3_EN,
+ .owner = THIS_MODULE,
+ },
+ {
+ .name = "BUCK4",
+ .id = BD71837_BUCK4,
+ .ops = &bd71837_buck1234_regulator_ops,
+ .type = REGULATOR_VOLTAGE,
+ .n_voltages = BD71837_BUCK4_VOLTAGE_NUM,
+ .linear_ranges = bd71837_buck1234_voltage_ranges,
+ .n_linear_ranges = ARRAY_SIZE(bd71837_buck1234_voltage_ranges),
+ .vsel_reg = BD71837_REG_BUCK4_VOLT_RUN,
+ .vsel_mask = BUCK4_RUN_MASK,
+ .enable_reg = BD71837_REG_BUCK4_CTRL,
+ .enable_mask = BUCK4_SEL|BUCK4_EN,
+ .owner = THIS_MODULE,
+ },
+ {
+ .name = "BUCK5",
+ .id = BD71837_BUCK5,
+ .ops = &bd71837_buck_regulator_ops,
+ .type = REGULATOR_VOLTAGE,
+ .n_voltages = BD71837_BUCK5_VOLTAGE_NUM,
+ .linear_ranges = bd71837_buck5_voltage_ranges,
+ .n_linear_ranges = ARRAY_SIZE(bd71837_buck5_voltage_ranges),
+ .vsel_reg = BD71837_REG_BUCK5_VOLT,
+ .vsel_mask = BUCK5_MASK,
+ .enable_reg = BD71837_REG_BUCK5_CTRL,
+ .enable_mask = BUCK5_SEL|BUCK5_EN,
+ .owner = THIS_MODULE,
+ },
+ {
+ .name = "BUCK6",
+ .id = BD71837_BUCK6,
+ .ops = &bd71837_buck_regulator_ops,
+ .type = REGULATOR_VOLTAGE,
+ .n_voltages = BD71837_BUCK6_VOLTAGE_NUM,
+ .linear_ranges = bd71837_buck6_voltage_ranges,
+ .n_linear_ranges = ARRAY_SIZE(bd71837_buck6_voltage_ranges),
+ .vsel_reg = BD71837_REG_BUCK6_VOLT,
+ .vsel_mask = BUCK6_MASK,
+ .enable_reg = BD71837_REG_BUCK6_CTRL,
+ .enable_mask = BUCK6_SEL|BUCK6_EN,
+ .owner = THIS_MODULE,
+ },
+ {
+ .name = "BUCK7",
+ .id = BD71837_BUCK7,
+ .ops = &bd71837_buck_regulator_ops,
+ .type = REGULATOR_VOLTAGE,
+ .n_voltages = BD71837_BUCK7_VOLTAGE_NUM,
+ .linear_ranges = bd71837_buck7_voltage_ranges,
+ .n_linear_ranges = ARRAY_SIZE(bd71837_buck7_voltage_ranges),
+ .vsel_reg = BD71837_REG_BUCK7_VOLT,
+ .vsel_mask = BUCK7_MASK,
+ .enable_reg = BD71837_REG_BUCK7_CTRL,
+ .enable_mask = BUCK7_SEL|BUCK7_EN,
+ .owner = THIS_MODULE,
+ },
+ {
+ .name = "BUCK8",
+ .id = BD71837_BUCK8,
+ .ops = &bd71837_buck_regulator_ops,
+ .type = REGULATOR_VOLTAGE,
+ .n_voltages = BD71837_BUCK8_VOLTAGE_NUM,
+ .linear_ranges = bd71837_buck8_voltage_ranges,
+ .n_linear_ranges = ARRAY_SIZE(bd71837_buck8_voltage_ranges),
+ .vsel_reg = BD71837_REG_BUCK8_VOLT,
+ .vsel_mask = BUCK8_MASK,
+ .enable_reg = BD71837_REG_BUCK8_CTRL,
+ .enable_mask = BUCK8_SEL|BUCK8_EN,
+ .owner = THIS_MODULE,
+ },
+ {
+ .name = "LDO1",
+ .id = BD71837_LDO1,
+ .ops = &bd71837_ldo_regulator_ops,
+ .type = REGULATOR_VOLTAGE,
+ .n_voltages = BD71837_LDO1_VOLTAGE_NUM,
+ .linear_ranges = bd71837_ldo1_voltage_ranges,
+ .n_linear_ranges = ARRAY_SIZE(bd71837_ldo1_voltage_ranges),
+ .vsel_reg = BD71837_REG_LDO1_VOLT,
+ .vsel_mask = LDO1_MASK,
+ .enable_reg = BD71837_REG_LDO1_VOLT,
+ .enable_mask = LDO1_EN,
+ .owner = THIS_MODULE,
+ },
+ /*
+ * LDO2 0.9V
+ * Fixed voltage
+ */
+ {
+ .name = "LDO2",
+ .id = BD71837_LDO2,
+ .ops = &bd71837_fixed_regulator_ops,
+ .type = REGULATOR_VOLTAGE,
+ .n_voltages = BD71837_LDO2_VOLTAGE_NUM,
+ .min_uV = 900000,
+ .enable_reg = BD71837_REG_LDO2_VOLT,
+ .enable_mask = LDO2_EN,
+ .owner = THIS_MODULE,
+ },
+ {
+ .name = "LDO3",
+ .id = BD71837_LDO3,
+ .ops = &bd71837_ldo_regulator_ops,
+ .type = REGULATOR_VOLTAGE,
+ .n_voltages = BD71837_LDO3_VOLTAGE_NUM,
+ .linear_ranges = bd71837_ldo3_voltage_ranges,
+ .n_linear_ranges = ARRAY_SIZE(bd71837_ldo3_voltage_ranges),
+ .vsel_reg = BD71837_REG_LDO3_VOLT,
+ .vsel_mask = LDO3_MASK,
+ .enable_reg = BD71837_REG_LDO3_VOLT,
+ .enable_mask = LDO3_EN,
+ .owner = THIS_MODULE,
+ },
+ {
+ .name = "LDO4",
+ .id = BD71837_LDO4,
+ .ops = &bd71837_ldo_regulator_ops,
+ .type = REGULATOR_VOLTAGE,
+ .n_voltages = BD71837_LDO4_VOLTAGE_NUM,
+ .linear_ranges = bd71837_ldo4_voltage_ranges,
+ .n_linear_ranges = ARRAY_SIZE(bd71837_ldo4_voltage_ranges),
+ .vsel_reg = BD71837_REG_LDO4_VOLT,
+ .vsel_mask = LDO4_MASK,
+ .enable_reg = BD71837_REG_LDO4_VOLT,
+ .enable_mask = LDO4_EN,
+ .owner = THIS_MODULE,
+ },
+ {
+ .name = "LDO5",
+ .id = BD71837_LDO5,
+ .ops = &bd71837_ldo_regulator_ops,
+ .type = REGULATOR_VOLTAGE,
+ .n_voltages = BD71837_LDO5_VOLTAGE_NUM,
+ .linear_ranges = bd71837_ldo5_voltage_ranges,
+ .n_linear_ranges = ARRAY_SIZE(bd71837_ldo5_voltage_ranges),
+ .vsel_reg = BD71837_REG_LDO5_VOLT,
+ .vsel_mask = LDO5_MASK,
+ .enable_reg = BD71837_REG_LDO5_VOLT,
+ .enable_mask = LDO5_EN,
+ .owner = THIS_MODULE,
+ },
+ {
+ .name = "LDO6",
+ .id = BD71837_LDO6,
+ .ops = &bd71837_ldo_regulator_ops,
+ .type = REGULATOR_VOLTAGE,
+ .n_voltages = BD71837_LDO6_VOLTAGE_NUM,
+ .linear_ranges = bd71837_ldo6_voltage_ranges,
+ .n_linear_ranges = ARRAY_SIZE(bd71837_ldo6_voltage_ranges),
+ .vsel_reg = BD71837_REG_LDO6_VOLT,
+ .vsel_mask = LDO6_MASK,
+ .enable_reg = BD71837_REG_LDO6_VOLT,
+ .enable_mask = LDO6_EN,
+ .owner = THIS_MODULE,
+ },
+ {
+ .name = "LDO7",
+ .id = BD71837_LDO7,
+ .ops = &bd71837_ldo_regulator_ops,
+ .type = REGULATOR_VOLTAGE,
+ .n_voltages = BD71837_LDO7_VOLTAGE_NUM,
+ .linear_ranges = bd71837_ldo7_voltage_ranges,
+ .n_linear_ranges = ARRAY_SIZE(bd71837_ldo7_voltage_ranges),
+ .vsel_reg = BD71837_REG_LDO7_VOLT,
+ .vsel_mask = LDO7_MASK,
+ .enable_reg = BD71837_REG_LDO7_VOLT,
+ .enable_mask = LDO7_EN,
+ .owner = THIS_MODULE,
+ },
+};
+
+#ifdef CONFIG_OF
+
+static struct of_regulator_match bd71837_matches[] = {
+ { .name = "buck1", },
+ { .name = "buck2", },
+ { .name = "buck3", },
+ { .name = "buck4", },
+ { .name = "buck5", },
+ { .name = "buck6", },
+ { .name = "buck7", },
+ { .name = "buck8", },
+ { .name = "ldo1", },
+ { .name = "ldo2", },
+ { .name = "ldo3", },
+ { .name = "ldo4", },
+ { .name = "ldo5", },
+ { .name = "ldo6", },
+ { .name = "ldo7", },
+};
+
+/**@brief parse bd71837 regulator device tree
+ * @param pdev platform device of bd71837 regulator
+ * @param bd71837_reg_matches return regualtor matches
+ * @retval 0 parse success
+ * @retval NULL parse fail
+ */
+static int bd71837_parse_dt_reg_data(
+ struct platform_device *pdev,
+ struct of_regulator_match **reg_matches)
+{
+ // struct bd71837 *bd71837 = dev_get_drvdata(pdev->dev.parent);
+ struct device_node *np, *regulators;
+ struct of_regulator_match *matches;
+ int ret, count;
+
+ np = of_node_get(pdev->dev.parent->of_node);
+ regulators = of_find_node_by_name(np, "regulators");
+ if (!regulators) {
+ dev_err(&pdev->dev, "regulator node not found\n");
+ return -EINVAL;
+ }
+
+ count = ARRAY_SIZE(bd71837_matches);
+ matches = bd71837_matches;
+
+ ret = of_regulator_match(&pdev->dev, regulators, matches, count);
+ of_node_put(regulators);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "Error parsing regulator init data: %d\n",
+ ret);
+ return ret;
+ }
+
+ *reg_matches = matches;
+
+ return 0;
+}
+#else
+static inline int bd71837_parse_dt_reg_data(
+ struct platform_device *pdev,
+ struct of_regulator_match **reg_matches)
+{
+ *reg_matches = NULL;
+ return 0;
+}
+#endif
+
+/** @brief retrive out32k output value */
+static ssize_t show_value(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ struct bd71837_pmic *pmic = dev_get_drvdata(dev);
+ int o;
+
+ o = bd71837_reg_read(pmic->mfd, BD71837_REG_OUT32K);
+ o = (o & OUT32K_EN) != 0;
+
+ return sprintf(buf, "%d\n", o);
+}
+
+/** @brief set o output value */
+static ssize_t set_value(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct bd71837_pmic *pmic = dev_get_drvdata(dev);
+ int o, r;
+
+ if (sscanf(buf, "%d", &o) < 1) {
+ return -EINVAL;
+ }
+
+ if (o != 0) {
+ o = OUT32K_EN;
+ }
+ r = bd71837_update_bits(pmic->mfd, BD71837_REG_OUT32K, OUT32K_EN, o);
+ if (r < 0) {
+ return r;
+ }
+ return count;
+}
+
+/** @brief list all supported values */
+static ssize_t available_values(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ return sprintf(buf, "0 1 \n");
+}
+
+/** @brief directly set raw value to chip register, format: 'register value' */
+static ssize_t bd71837_sysfs_set_registers(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf,
+ size_t count)
+{
+ struct bd71837_pmic *pmic = dev_get_drvdata(dev);
+ ssize_t ret = 0;
+ unsigned int reg;
+ unsigned int val;
+
+ ret = sscanf(buf, "%x %x", &reg, &val);
+ if (ret < 1) {
+ pmic->reg_index = -1;
+ dev_err(pmic->dev, "registers set: <reg> <value>\n");
+ return count;
+ }
+
+ if (ret == 1 && reg < BD71837_MAX_REGISTER) {
+ pmic->reg_index = reg;
+ dev_info(pmic->dev, "registers set: reg=0x%x\n", reg);
+ return count;
+ }
+
+ if (reg > BD71837_MAX_REGISTER) {
+ dev_err(pmic->dev, "reg=%d out of Max=%d\n", reg, BD71837_MAX_REGISTER);
+ return -EINVAL;
+ }
+ dev_info(pmic->dev, "registers set: reg=0x%x, val=0x%x\n", reg, val);
+ ret = bd71837_reg_write(pmic->mfd, reg, val);
+ if (ret < 0)
+ return ret;
+ return count;
+}
+
+/** @brief print value of chip register, format: 'register=value' */
+static ssize_t bd71837_sysfs_print_reg(struct bd71837_pmic *pmic,
+ u8 reg,
+ char *buf)
+{
+ int ret = bd71837_reg_read(pmic->mfd, reg);
+ if (ret < 0)
+ return sprintf(buf, "%#.2x=error %d\n", reg, ret);
+ return sprintf(buf, "[0x%.2X] = %.2X\n", reg, ret);
+}
+
+/** @brief show all raw values of chip register, format per line: 'register=value' */
+static ssize_t bd71837_sysfs_show_registers(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct bd71837_pmic *pmic = dev_get_drvdata(dev);
+ ssize_t ret = 0;
+ int i;
+
+ dev_info(pmic->dev, "register: index[0x%x]\n", pmic->reg_index);
+ if (pmic->reg_index >= 0) {
+ ret += bd71837_sysfs_print_reg(pmic, pmic->reg_index, buf + ret);
+ } else {
+ for (i = 0; i < BD71837_MAX_REGISTER; i++) {
+ ret += bd71837_sysfs_print_reg(pmic, i, buf + ret);
+ }
+ }
+ return ret;
+}
+
+static DEVICE_ATTR(out32k_value, S_IWUSR | S_IRUGO, show_value, set_value);
+static DEVICE_ATTR(available_value, S_IWUSR | S_IRUGO, available_values, NULL);
+static DEVICE_ATTR(registers, S_IWUSR | S_IRUGO,
+ bd71837_sysfs_show_registers, bd71837_sysfs_set_registers);
+
+/** @brief device sysfs attribute table, about o */
+static struct attribute *clk_attributes[] = {
+ &dev_attr_out32k_value.attr,
+ &dev_attr_available_value.attr,
+ &dev_attr_registers.attr,
+ NULL
+};
+
+static const struct attribute_group clk_attr_group = {
+ .attrs = clk_attributes,
+};
+
+/*----------------------------------------------------------------------*/
+#ifdef CONFIG_OF
+/** @brief buck1/2 dvs enable/voltage from device tree
+ * @param pdev platfrom device pointer
+ * @param buck_dvs pointer
+ * @return void
+ */
+static void of_bd71837_buck_dvs(struct platform_device *pdev, struct bd71837_buck_dvs *buck_dvs)
+{
+ struct device_node *pmic_np;
+
+ pmic_np = of_node_get(pdev->dev.parent->of_node);
+ if (!pmic_np) {
+ dev_err(&pdev->dev, "could not find pmic sub-node\n");
+ return;
+ }
+
+ if (of_get_property(pmic_np, "bd71837,pmic-buck1-uses-i2c-dvs", NULL)) {
+ if (of_property_read_u32_array(pmic_np,
+ "bd71837,pmic-buck1-dvs-voltage",
+ &buck_dvs[0].voltage[0], BD71837_DVS_RUN_IDLE_SUSP)) {
+ dev_err(&pdev->dev, "buck1 voltages not specified\n");
+ }
+ }
+
+ if (of_get_property(pmic_np, "bd71837,pmic-buck2-uses-i2c-dvs", NULL)) {
+ if (of_property_read_u32_array(pmic_np,
+ "bd71837,pmic-buck2-dvs-voltage",
+ &buck_dvs[1].voltage[0], BD71837_DVS_RUN_IDLE)) {
+ dev_err(&pdev->dev, "buck2 voltages not specified\n");
+ }
+ }
+
+ if (of_get_property(pmic_np, "bd71837,pmic-buck3-uses-i2c-dvs", NULL)) {
+ if (of_property_read_u32_array(pmic_np,
+ "bd71837,pmic-buck3-dvs-voltage",
+ &buck_dvs[2].voltage[0], BD71837_DVS_RUN)) {
+ dev_err(&pdev->dev, "buck3 voltages not specified\n");
+ }
+ }
+ if (of_get_property(pmic_np, "bd71837,pmic-buck4-uses-i2c-dvs", NULL)) {
+ if (of_property_read_u32_array(pmic_np,
+ "bd71837,pmic-buck4-dvs-voltage",
+ &buck_dvs[3].voltage[0], BD71837_DVS_RUN)) {
+ dev_err(&pdev->dev, "buck4 voltages not specified\n");
+ }
+ }
+}
+#else
+static void of_bd71837_buck_dvs(struct platform_device *pdev, struct bd71837_buck_dvs *buck_dvs)
+{
+ buck_dvs[0].voltage[0] = BUCK1_RUN_DEFAULT;
+ buck_dvs[0].voltage[1] = BUCK1_IDLE_DEFAULT;
+ buck_dvs[0].voltage[2] = BUCK1_SUSP_DEFAULT;
+ buck_dvs[1].voltage[0] = BUCK2_RUN_DEFAULT;
+ buck_dvs[1].voltage[1] = BUCK2_IDLE_DEFAULT;
+ buck_dvs[1].voltage[2] = 0; /* Not supported */
+ buck_dvs[2].voltage[0] = BUCK3_RUN_DEFAULT;
+ buck_dvs[2].voltage[1] = 0; /* Not supported */
+ buck_dvs[2].voltage[2] = 0; /* Not supported */
+ buck_dvs[3].voltage[0] = BUCK4_RUN_DEFAULT;
+ buck_dvs[3].voltage[1] = 0; /* Not supported */
+ buck_dvs[3].voltage[2] = 0; /* Not supported */
+}
+#endif
+
+static int bd71837_buck1234_dvs_init(struct bd71837_pmic *pmic)
+{
+ struct bd71837 *bd71837 = pmic->mfd;
+ struct bd71837_buck_dvs *buck_dvs = &pmic->buck_dvs[0];
+ int i, ret, val, selector = 0;
+ u8 reg_run, reg_idle, reg_susp;
+ u8 reg_run_msk, reg_idle_msk, reg_susp_msk;
+
+ for (i = 0; i < BD71837_DVS_BUCK_NUM; i++, buck_dvs++) {
+ switch (i) {
+ case 0:
+ default:
+ reg_run = BD71837_REG_BUCK1_VOLT_RUN;
+ reg_run_msk = BUCK1_RUN_MASK;
+ reg_idle = BD71837_REG_BUCK1_VOLT_IDLE;
+ reg_idle_msk = BUCK1_IDLE_MASK;
+ reg_susp = BD71837_REG_BUCK1_VOLT_SUSP;
+ reg_susp_msk = BUCK1_SUSP_MASK;
+ break;
+ case 1:
+ reg_run = BD71837_REG_BUCK2_VOLT_RUN;
+ reg_run_msk = BUCK2_RUN_MASK;
+ reg_idle = BD71837_REG_BUCK2_VOLT_IDLE;
+ reg_idle_msk = BUCK2_IDLE_MASK;
+ reg_susp = 0;
+ break;
+ case 2:
+ reg_run = BD71837_REG_BUCK3_VOLT_RUN;
+ reg_run_msk = BUCK3_RUN_MASK;
+ reg_idle = 0;
+ reg_susp = 0;
+ break;
+ case 3:
+ reg_run = BD71837_REG_BUCK4_VOLT_RUN;
+ reg_run_msk = BUCK4_RUN_MASK;
+ reg_idle = 0;
+ reg_susp = 0;
+ break;
+ }
+
+ dev_dbg(pmic->dev, "Buck%d: DVS Run-Idle-Susp[%d - %d - %d].\n", i+1, buck_dvs->voltage[0], buck_dvs->voltage[1], buck_dvs->voltage[2]);
+ if (reg_run > 0) {
+ selector = regulator_map_voltage_iterate(pmic->rdev[i], buck_dvs->voltage[0], buck_dvs->voltage[0]);
+ if (selector < 0) {
+ dev_dbg(pmic->dev, "%s(): not found selector for Run voltage [%d]\n", __func__, buck_dvs->voltage[0]);
+ } else {
+ val = (selector & reg_run_msk);
+ ret = bd71837_reg_write(bd71837, reg_run, val);
+ if (ret < 0)
+ return ret;
+ }
+ }
+ if (reg_idle > 0) {
+ selector = regulator_map_voltage_iterate(pmic->rdev[i], buck_dvs->voltage[1], buck_dvs->voltage[1]);
+ if (selector < 0) {
+ dev_dbg(pmic->dev, "%s(): not found selector for Idle voltage [%d]\n", __func__, buck_dvs->voltage[1]);
+ } else {
+ val = (selector & reg_idle_msk);
+ ret = bd71837_reg_write(bd71837, reg_idle, val);
+ if (ret < 0)
+ return ret;
+ }
+ }
+ if (reg_susp > 0) {
+ selector = regulator_map_voltage_iterate(pmic->rdev[i], buck_dvs->voltage[2], buck_dvs->voltage[2]);
+ if (selector < 0) {
+ dev_dbg(pmic->dev, "%s(): not found selector for Susp voltage [%d]\n", __func__, buck_dvs->voltage[2]);
+ } else {
+ val = (selector & reg_susp_msk);
+ ret = bd71837_reg_write(bd71837, reg_susp, val);
+ if (ret < 0)
+ return ret;
+ }
+ }
+ }
+ return 0;
+}
+
+/**@brief bd71837 pmic interrupt
+ * @param irq system irq
+ * @param pwrsys bd71837 power device of system
+ * @retval IRQ_HANDLED success
+ * @retval IRQ_NONE error
+ */
+static irqreturn_t bd71837_pmic_interrupt(int irq, void *pwrsys)
+{
+ struct device *dev = pwrsys;
+ struct bd71837 *mfd = dev_get_drvdata(dev->parent);
+ // struct bd71837_power *pwr = dev_get_drvdata(dev);
+ int reg;
+
+ bd71837_debug(BD71837_DBG0, "bd71837_pmic_interrupt() in.\n");
+
+ reg = bd71837_reg_read(mfd, BD71837_REG_IRQ);
+ if (reg < 0)
+ return IRQ_NONE;
+
+ if (reg & IRQ_SWRST) {
+ bd71837_debug(BD71837_DBG0, "IRQ_SWRST\n");
+ }
+ if (reg & IRQ_PWRON_S) {
+ bd71837_debug(BD71837_DBG0, "IRQ_PWRON_S\n");
+ }
+ if (reg & IRQ_PWRON_L) {
+ bd71837_debug(BD71837_DBG0, "IRQ_PWRON_L\n");
+ }
+ if (reg & IRQ_PWRON) {
+ bd71837_debug(BD71837_DBG0, "IRQ_PWRON\n");
+ }
+ if (reg & IRQ_WDOG) {
+ bd71837_debug(BD71837_DBG0, "IRQ_WDOG\n");
+ }
+ if (reg & IRQ_ON_REQ) {
+ bd71837_debug(BD71837_DBG0, "IRQ_ON_REQ\n");
+ }
+ if (reg & IRQ_STBY_REQ) {
+ bd71837_debug(BD71837_DBG0, "IRQ_STBY_REQ\n");
+ }
+
+ reg = bd71837_reg_write(mfd, BD71837_REG_IRQ, reg);
+ if (reg < 0)
+ return IRQ_NONE;
+
+ return IRQ_HANDLED;
+}
+
+/**@brief probe bd71837 regulator device
+ @param pdev bd71837 regulator platform device
+ @retval 0 success
+ @retval negative fail
+*/
+static int bd71837_probe(struct platform_device *pdev)
+{
+ struct bd71837_pmic *pmic;
+ struct bd71837_board *pdata;
+ struct regulator_config config = {};
+ struct bd71837 *bd71837 = dev_get_drvdata(pdev->dev.parent);
+ struct of_regulator_match *matches = NULL;
+ int i = 0, err, irq = 0, ret = 0;
+
+ pmic = kzalloc(sizeof(*pmic), GFP_KERNEL);
+ if (!pmic) {
+ dev_err(&pdev->dev, "Memory allocation failed for pmic\n");
+ return -ENOMEM;
+ }
+
+ memcpy(pmic->descs, bd71837_regulators, sizeof(pmic->descs));
+
+ pmic->dev = &pdev->dev;
+ pmic->mfd = bd71837;
+ platform_set_drvdata(pdev, pmic);
+ pdata = dev_get_platdata(bd71837->dev);
+
+ if (!pdata && bd71837->dev->of_node) {
+ bd71837_parse_dt_reg_data(pdev, &matches);
+ if (matches == NULL) {
+ dev_err(&pdev->dev, "Platform data not found\n");
+ return -EINVAL;
+ }
+ }
+
+ /* Get buck dvs parameters */
+ of_bd71837_buck_dvs(pdev, &pmic->buck_dvs[0]);
+
+ /* Register LOCK release */
+ err = bd71837_reg_write(bd71837, BD71837_REG_REGLOCK, 0x0);
+ if (err != 0) {
+ dev_err(&pdev->dev, "Failed to write LOCK register(%d)\n", err);
+ goto err;
+ }
+
+ for (i = 0; i < BD71837_REGULATOR_CNT; i++) {
+ struct regulator_init_data *init_data;
+ struct regulator_desc *desc;
+ struct regulator_dev *rdev;
+
+ desc = &pmic->descs[i];
+ desc->name = bd71837_matches[i].name;
+
+ if (pdata) {
+ init_data = pdata->init_data[i];
+ } else {
+ init_data = bd71837_matches[i].init_data;
+ }
+
+ config.dev = pmic->dev;
+ config.init_data = init_data;
+ config.driver_data = pmic;
+ config.regmap = bd71837->regmap;
+ if (matches)
+ config.of_node = matches[i].of_node;
+ dev_info(config.dev, "regulator register name '%s'\n", desc->name);
+
+ rdev = regulator_register(desc, &config);
+ if (IS_ERR(rdev)) {
+ dev_err(bd71837->dev,
+ "failed to register %s regulator\n",
+ desc->name);
+ err = PTR_ERR(rdev);
+ goto err;
+ }
+ pmic->rdev[i] = rdev;
+ }
+
+ /* Init sysfs registers */
+ pmic->reg_index = -1;
+
+ err = sysfs_create_group(&pdev->dev.kobj, &clk_attr_group);
+ if (err != 0) {
+ dev_err(&pdev->dev, "Failed to create attribute group: %d\n", err);
+ goto err;
+ }
+
+ /* Init Buck1/2/3/4 dvs */
+ err = bd71837_buck1234_dvs_init(pmic);
+ if (err != 0) {
+ dev_err(&pdev->dev, "Failed to buck12 dvs: %d\n", err);
+ goto err;
+ }
+
+ /* Add Interrupt */
+ irq = platform_get_irq(pdev, 0); // get irq number
+ if (irq <= 0) {
+ dev_warn(&pdev->dev, "platform irq error # %d\n", irq);
+ return -ENXIO;
+ }
+ ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
+ bd71837_pmic_interrupt, IRQF_TRIGGER_LOW | IRQF_EARLY_RESUME,
+ dev_name(&pdev->dev), &pdev->dev);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "IRQ %d is not free.\n", irq);
+ }
+
+ /* Un-mask IRQ Interrupt */
+ ret = bd71837_reg_write(bd71837, BD71837_REG_MIRQ, 0);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "Write Un-mask 'BD71837_REG_MIRQ': failed!\n");
+ ret = -EIO;
+ goto err;
+ }
+
+ return 0;
+
+err:
+ while (--i >= 0)
+ regulator_unregister(pmic->rdev[i]);
+
+ kfree(pmic);
+ return err;
+}
+
+/**@brief remove bd71837 regulator device
+ @param pdev bd71837 regulator platform device
+ @return 0
+*/
+static int __exit bd71837_remove(struct platform_device *pdev)
+{
+ struct bd71837_pmic *pmic = platform_get_drvdata(pdev);
+ int i;
+
+ sysfs_remove_group(&pdev->dev.kobj, &clk_attr_group);
+
+ for (i = 0; i < BD71837_REGULATOR_CNT; i++)
+ regulator_unregister(pmic->rdev[i]);
+
+ kfree(pmic);
+ return 0;
+}
+
+static struct platform_driver bd71837_driver = {
+ .driver = {
+ .name = "bd71837-pmic",
+ .owner = THIS_MODULE,
+ },
+ .probe = bd71837_probe,
+ .remove = bd71837_remove,
+};
+
+/**@brief module initialize function */
+static int __init bd71837_init(void)
+{
+ return platform_driver_register(&bd71837_driver);
+}
+subsys_initcall(bd71837_init);
+
+/**@brief module deinitialize function */
+static void __exit bd71837_cleanup(void)
+{
+ platform_driver_unregister(&bd71837_driver);
+}
+module_exit(bd71837_cleanup);
+
+MODULE_AUTHOR("Cong Pham <cpham2403@gmail.com>");
+MODULE_DESCRIPTION("BD71837 voltage regulator driver");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:bd71837-pmic");
+
+/*-------------------------------------------------------*/
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/proc_fs.h>
+#include <asm/uaccess.h>
+
+#define PROCFS_NAME "bd71837"
+#define BD71837_REV "BD71837 Driver: Rev002\n"
+
+#define BD71837_BUF_SIZE 1024
+static char procfs_buffer[BD71837_BUF_SIZE];
+/**
+ * This function is called then the /proc file is read
+ *
+ */
+static int onetime;
+static ssize_t bd71837_proc_read (struct file *file, char __user *buffer, size_t count, loff_t *data)
+{
+ int ret = 0, error = 0;
+ if (onetime == 0) {
+ onetime = 1;
+ memset(procfs_buffer, 0, BD71837_BUF_SIZE);
+ sprintf(procfs_buffer, "%s", BD71837_REV);
+ ret = strlen(procfs_buffer);
+ error = copy_to_user(buffer, procfs_buffer, strlen(procfs_buffer));
+ } else {
+ //Clear for next time
+ onetime = 0;
+ }
+ return (error != 0) ? 0 : ret;
+}
+
+static ssize_t bd71837_proc_write (struct file *file, const char __user *buffer, size_t count, loff_t *data)
+{
+ sscanf(buffer, "0x%x", &bd71837_debug_mask);
+ printk("bd71837: bd71837_debug_mask=0x%08x\n", bd71837_debug_mask);
+ return count;
+}
+
+static const struct file_operations bd71837_proc_fops = {
+ .owner = THIS_MODULE,
+ .read = bd71837_proc_read,
+ .write = bd71837_proc_write,
+};
+
+/**
+ *This function is called when the module is loaded
+ *
+ */
+int bd71837_revision_init(void)
+{
+ struct proc_dir_entry *bd71837_proc_entry;
+
+ /* create the /proc/bd71837 */
+ bd71837_proc_entry = proc_create(PROCFS_NAME, 0644, NULL, &bd71837_proc_fops);
+ if (bd71837_proc_entry == NULL) {
+ printk("Error: Could not initialize /proc/%s\n", PROCFS_NAME);
+ return -ENOMEM;
+ }
+
+ return 0;
+}
+module_init(bd71837_revision_init);
+/*-------------------------------------------------------*/
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index d2428c262b7c..b5eb8482f633 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -1099,7 +1099,7 @@ static int set_machine_constraints(struct regulator_dev *rdev,
}
}
- if ((rdev->constraints->ramp_delay || rdev->constraints->ramp_disable)
+ if ((rdev->constraints->ramp_delay && !rdev->constraints->ramp_disable)
&& ops->set_ramp_delay) {
ret = ops->set_ramp_delay(rdev, rdev->constraints->ramp_delay);
if (ret < 0) {
@@ -2086,6 +2086,7 @@ static int _regulator_do_enable(struct regulator_dev *rdev)
{
int ret, delay;
+ _notifier_call_chain(rdev, REGULATOR_EVENT_PRE_DO_ENABLE, NULL);
/* Query before enabling in case configuration dependent. */
ret = _regulator_get_enable_time(rdev);
if (ret >= 0) {
@@ -2145,6 +2146,7 @@ static int _regulator_do_enable(struct regulator_dev *rdev)
_regulator_enable_delay(delay);
trace_regulator_enable_complete(rdev_get_name(rdev));
+ _notifier_call_chain(rdev, REGULATOR_EVENT_AFT_DO_ENABLE, NULL);
return 0;
}
@@ -2226,6 +2228,7 @@ static int _regulator_do_disable(struct regulator_dev *rdev)
{
int ret;
+ _notifier_call_chain(rdev, REGULATOR_EVENT_PRE_DO_DISABLE, NULL);
trace_regulator_disable(rdev_get_name(rdev));
if (rdev->ena_pin) {
@@ -2897,6 +2900,35 @@ out:
return ret;
}
+static bool _regulator_is_bypass(struct regulator_dev *rdev)
+{
+ bool bypassed = false;
+
+ if (rdev->desc->ops->get_bypass)
+ rdev->desc->ops->get_bypass(rdev, &bypassed);
+
+ return bypassed;
+}
+
+static inline bool _regulator_should_adjust_supply(struct regulator_dev *rdev)
+{
+ /* Check for adjustable supply */
+ if (!rdev->supply)
+ return false;
+ if (!regulator_ops_is_valid(rdev->supply->rdev, REGULATOR_CHANGE_VOLTAGE))
+ return false;
+
+ /* Check for need to adjust supply */
+ if (rdev->desc->min_dropout_uV)
+ return true;
+ if (_regulator_is_bypass(rdev))
+ return true;
+ if (!(rdev->desc->ops->get_voltage || rdev->desc->ops->get_voltage_sel))
+ return true;
+
+ return false;
+}
+
static int regulator_set_voltage_unlocked(struct regulator *regulator,
int min_uV, int max_uV)
{
@@ -2949,11 +2981,7 @@ static int regulator_set_voltage_unlocked(struct regulator *regulator,
if (ret < 0)
goto out2;
- if (rdev->supply &&
- regulator_ops_is_valid(rdev->supply->rdev,
- REGULATOR_CHANGE_VOLTAGE) &&
- (rdev->desc->min_dropout_uV || !(rdev->desc->ops->get_voltage ||
- rdev->desc->ops->get_voltage_sel))) {
+ if (_regulator_should_adjust_supply(rdev)) {
int current_supply_uV;
int selector;
diff --git a/drivers/regulator/fixed.c b/drivers/regulator/fixed.c
index 988a7472c2ab..136a9a3c7e30 100644
--- a/drivers/regulator/fixed.c
+++ b/drivers/regulator/fixed.c
@@ -30,6 +30,7 @@
#include <linux/of_gpio.h>
#include <linux/regulator/of_regulator.h>
#include <linux/regulator/machine.h>
+#include <linux/pinctrl/consumer.h>
struct fixed_voltage_data {
struct regulator_desc desc;
@@ -83,6 +84,7 @@ of_get_fixed_voltage_config(struct device *dev,
return ERR_PTR(config->gpio);
of_property_read_u32(np, "startup-delay-us", &config->startup_delay);
+ of_property_read_u32(np, "off-on-delay", &config->off_on_delay);
config->enable_high = of_property_read_bool(np, "enable-active-high");
config->gpio_is_open_drain = of_property_read_bool(np,
@@ -133,6 +135,7 @@ static int reg_fixed_voltage_probe(struct platform_device *pdev)
drvdata->desc.ops = &fixed_voltage_ops;
drvdata->desc.enable_time = config->startup_delay;
+ drvdata->desc.off_on_delay = config->off_on_delay;
if (config->input_supply) {
drvdata->desc.supply_name = devm_kstrdup(&pdev->dev,
@@ -199,11 +202,32 @@ static const struct of_device_id fixed_of_match[] = {
MODULE_DEVICE_TABLE(of, fixed_of_match);
#endif
+#ifdef CONFIG_PM_SLEEP
+static int reg_fixed_voltage_suspend(struct device *dev)
+{
+ pinctrl_pm_select_sleep_state(dev);
+
+ return 0;
+}
+static int reg_fixed_voltage_resume(struct device *dev)
+{
+ pinctrl_pm_select_default_state(dev);
+
+ return 0;
+}
+#endif
+
+static const struct dev_pm_ops reg_fixed_voltage_pm_ops = {
+ SET_LATE_SYSTEM_SLEEP_PM_OPS(reg_fixed_voltage_suspend,
+ reg_fixed_voltage_resume)
+};
+
static struct platform_driver regulator_fixed_voltage_driver = {
.probe = reg_fixed_voltage_probe,
.driver = {
.name = "reg-fixed-voltage",
.of_match_table = of_match_ptr(fixed_of_match),
+ .pm = &reg_fixed_voltage_pm_ops,
},
};
diff --git a/drivers/regulator/max17135-regulator.c b/drivers/regulator/max17135-regulator.c
new file mode 100644
index 000000000000..90a2665c3d64
--- /dev/null
+++ b/drivers/regulator/max17135-regulator.c
@@ -0,0 +1,858 @@
+/*
+ * Copyright (C) 2010-2015 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/mutex.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/of_regulator.h>
+#include <linux/mfd/max17135.h>
+#include <linux/gpio.h>
+#include <linux/of_gpio.h>
+
+/*
+ * Regulator definitions
+ * *_MIN_uV - minimum microvolt for regulator
+ * *_MAX_uV - maximum microvolt for regulator
+ * *_STEP_uV - microvolts between regulator output levels
+ * *_MIN_VAL - minimum register field value for regulator
+ * *_MAX_VAL - maximum register field value for regulator
+ */
+#define MAX17135_HVINP_MIN_uV 5000000
+#define MAX17135_HVINP_MAX_uV 20000000
+#define MAX17135_HVINP_STEP_uV 1000000
+#define MAX17135_HVINP_MIN_VAL 0
+#define MAX17135_HVINP_MAX_VAL 12
+
+#define MAX17135_HVINN_MIN_uV 5000000
+#define MAX17135_HVINN_MAX_uV 20000000
+#define MAX17135_HVINN_STEP_uV 1000000
+#define MAX17135_HVINN_MIN_VAL 0
+#define MAX17135_HVINN_MAX_VAL 1
+
+#define MAX17135_GVDD_MIN_uV 5000000
+#define MAX17135_GVDD_MAX_uV 20000000
+#define MAX17135_GVDD_STEP_uV 1000000
+#define MAX17135_GVDD_MIN_VAL 0
+#define MAX17135_GVDD_MAX_VAL 1
+
+#define MAX17135_GVEE_MIN_uV 5000000
+#define MAX17135_GVEE_MAX_uV 20000000
+#define MAX17135_GVEE_STEP_uV 1000000
+#define MAX17135_GVEE_MIN_VAL 0
+#define MAX17135_GVEE_MAX_VAL 1
+
+#define MAX17135_VCOM_MIN_VAL 0
+#define MAX17135_VCOM_MAX_VAL 255
+
+#define MAX17135_VNEG_MIN_uV 5000000
+#define MAX17135_VNEG_MAX_uV 20000000
+#define MAX17135_VNEG_STEP_uV 1000000
+#define MAX17135_VNEG_MIN_VAL 0
+#define MAX17135_VNEG_MAX_VAL 1
+
+#define MAX17135_VPOS_MIN_uV 5000000
+#define MAX17135_VPOS_MAX_uV 20000000
+#define MAX17135_VPOS_STEP_uV 1000000
+#define MAX17135_VPOS_MIN_VAL 0
+#define MAX17135_VPOS_MAX_VAL 1
+
+struct max17135_vcom_programming_data {
+ int vcom_min_uV;
+ int vcom_max_uV;
+ int vcom_step_uV;
+};
+
+struct max17135_data {
+ int num_regulators;
+ struct max17135 *max17135;
+ struct regulator_dev **rdev;
+};
+
+static long unsigned int max17135_pass_num = { 1 };
+static int max17135_vcom = { -1250000 };
+
+struct max17135_vcom_programming_data vcom_data[2] = {
+ {
+ -4325000,
+ -500000,
+ 15000,
+ },
+ {
+ -3050000,
+ -500000,
+ 10000,
+ },
+};
+
+static int max17135_is_power_good(struct max17135 *max17135);
+
+/*
+ * Regulator operations
+ */
+static int max17135_hvinp_set_voltage(struct regulator_dev *reg,
+ int minuV, int uV, unsigned *selector)
+{
+ unsigned int reg_val;
+ unsigned int fld_val;
+
+ if ((uV >= MAX17135_HVINP_MIN_uV) &&
+ (uV <= MAX17135_HVINP_MAX_uV))
+ fld_val = (uV - MAX17135_HVINP_MIN_uV) /
+ MAX17135_HVINP_STEP_uV;
+ else
+ return -EINVAL;
+
+ max17135_reg_read(REG_MAX17135_HVINP, &reg_val);
+
+ reg_val &= ~BITFMASK(HVINP);
+ reg_val |= BITFVAL(HVINP, fld_val); /* shift to correct bit */
+
+ return max17135_reg_write(REG_MAX17135_HVINP, reg_val);
+}
+
+static int max17135_hvinp_get_voltage(struct regulator_dev *reg)
+{
+ unsigned int reg_val;
+ unsigned int fld_val;
+ int volt;
+
+ max17135_reg_read(REG_MAX17135_HVINP, &reg_val);
+
+ fld_val = (reg_val & BITFMASK(HVINP)) >> HVINP_LSH;
+
+ if ((fld_val >= MAX17135_HVINP_MIN_VAL) &&
+ (fld_val <= MAX17135_HVINP_MAX_VAL)) {
+ volt = (fld_val * MAX17135_HVINP_STEP_uV) +
+ MAX17135_HVINP_MIN_uV;
+ } else {
+ printk(KERN_ERR "MAX17135: HVINP voltage is out of range\n");
+ volt = 0;
+ }
+ return volt;
+}
+
+static int max17135_hvinp_enable(struct regulator_dev *reg)
+{
+ return 0;
+}
+
+static int max17135_hvinp_disable(struct regulator_dev *reg)
+{
+ return 0;
+}
+
+/* Convert uV to the VCOM register bitfield setting */
+static inline int vcom_uV_to_rs(int uV, int pass_num)
+{
+ return (vcom_data[pass_num].vcom_max_uV - uV)
+ / vcom_data[pass_num].vcom_step_uV;
+}
+
+/* Convert the VCOM register bitfield setting to uV */
+static inline int vcom_rs_to_uV(int rs, int pass_num)
+{
+ return vcom_data[pass_num].vcom_max_uV
+ - (vcom_data[pass_num].vcom_step_uV * rs);
+}
+
+/*
+ * This function should only be called with positive voltage values because
+ * negative ones are considered errors by the regulator core implementation.
+ *
+ * The given positive value if the absolute value of the desired negative one.
+ */
+static int max17135_vcom_set_voltage(struct regulator_dev *reg,
+ int minuV, int uV, unsigned *selector)
+{
+ struct max17135 *max17135 = rdev_get_drvdata(reg);
+ unsigned int reg_val;
+ int vcom_read;
+
+ /* Transform uV for our negative land values */
+ uV = -uV;
+
+ if ((uV < vcom_data[max17135->pass_num-1].vcom_min_uV)
+ || (uV > vcom_data[max17135->pass_num-1].vcom_max_uV))
+ return -EINVAL;
+
+ max17135_reg_read(REG_MAX17135_DVR, &reg_val);
+
+ /*
+ * Only program VCOM if it is not set to the desired value.
+ * Programming VCOM excessively degrades ability to keep
+ * DVR register value persistent.
+ */
+ vcom_read = vcom_rs_to_uV(reg_val, max17135->pass_num-1);
+ if (vcom_read != max17135->vcom_uV) {
+ reg_val &= ~BITFMASK(DVR);
+ reg_val |= BITFVAL(DVR, vcom_uV_to_rs(uV,
+ max17135->pass_num-1));
+ max17135_reg_write(REG_MAX17135_DVR, reg_val);
+
+ reg_val = BITFVAL(CTRL_DVR, true); /* shift to correct bit */
+ return max17135_reg_write(REG_MAX17135_PRGM_CTRL, reg_val);
+ }
+
+ return 0;
+}
+
+/*
+ * This function should only return positive voltage values because negative
+ * ones are considered errors by the regulator core implementation.
+ */
+static int max17135_vcom_get_voltage(struct regulator_dev *reg)
+{
+ struct max17135 *max17135 = rdev_get_drvdata(reg);
+ unsigned int reg_val;
+ int uV;
+
+ max17135_reg_read(REG_MAX17135_DVR, &reg_val);
+ uV = vcom_rs_to_uV(BITFEXT(reg_val, DVR), max17135->pass_num-1);
+
+ /* Transform uV to positive value */
+ uV = -uV;
+
+ return uV;
+}
+
+static int max17135_vcom_enable(struct regulator_dev *reg)
+{
+ struct max17135 *max17135 = rdev_get_drvdata(reg);
+ int uV;
+
+ /*
+ * Check to see if we need to set the VCOM voltage.
+ * Should only be done one time. And, we can
+ * only change vcom voltage if we have been enabled.
+ */
+ if (!max17135->vcom_setup && max17135_is_power_good(max17135)) {
+ uV = (-1) * max17135->vcom_uV;
+
+ max17135_vcom_set_voltage(reg, uV, uV, NULL);
+ max17135->vcom_setup = true;
+ }
+
+ /* enable VCOM regulator output */
+ if (max17135->pass_num == 1)
+ gpio_set_value(max17135->gpio_pmic_vcom_ctrl, 1);
+ else {
+ unsigned int reg_val;
+
+ max17135_reg_read(REG_MAX17135_ENABLE, &reg_val);
+ reg_val &= ~BITFMASK(VCOM_ENABLE);
+ reg_val |= BITFVAL(VCOM_ENABLE, 1); /* shift to correct bit */
+ max17135_reg_write(REG_MAX17135_ENABLE, reg_val);
+ }
+
+ return 0;
+}
+
+static int max17135_vcom_disable(struct regulator_dev *reg)
+{
+ struct max17135 *max17135 = rdev_get_drvdata(reg);
+
+ if (max17135->pass_num == 1)
+ gpio_set_value(max17135->gpio_pmic_vcom_ctrl, 0);
+ else {
+ unsigned int reg_val;
+
+ max17135_reg_read(REG_MAX17135_ENABLE, &reg_val);
+ reg_val &= ~BITFMASK(VCOM_ENABLE);
+ max17135_reg_write(REG_MAX17135_ENABLE, reg_val);
+ }
+
+ return 0;
+}
+
+static int max17135_vcom_is_enabled(struct regulator_dev *reg)
+{
+ struct max17135 *max17135 = rdev_get_drvdata(reg);
+
+ /* read VCOM regulator enable setting */
+ if (max17135->pass_num == 1) {
+ int gpio = gpio_get_value(max17135->gpio_pmic_vcom_ctrl);
+ if (gpio == 0)
+ return 0;
+ else
+ return 1;
+ } else {
+ unsigned int reg_val;
+
+ max17135_reg_read(REG_MAX17135_ENABLE, &reg_val);
+ reg_val &= BITFMASK(VCOM_ENABLE);
+ if (reg_val != 0)
+ return 1;
+ else
+ return 0;
+ }
+}
+
+static int max17135_is_power_good(struct max17135 *max17135)
+{
+ unsigned int reg_val;
+ unsigned int fld_val;
+
+ max17135_reg_read(REG_MAX17135_FAULT, &reg_val);
+ fld_val = (reg_val & BITFMASK(FAULT_POK)) >> FAULT_POK_LSH;
+
+ /* Check the POK bit */
+ return fld_val;
+}
+
+static int max17135_wait_power_good(struct max17135 *max17135)
+{
+ int i;
+
+ for (i = 0; i < max17135->max_wait * 3; i++) {
+ if (max17135_is_power_good(max17135))
+ return 0;
+
+ msleep(1);
+ }
+
+ return -ETIMEDOUT;
+}
+
+static int max17135_display_enable(struct regulator_dev *reg)
+{
+ struct max17135 *max17135 = rdev_get_drvdata(reg);
+
+ /* The Pass 1 parts cannot turn on the PMIC via I2C. */
+ if (max17135->pass_num == 1)
+ gpio_set_value(max17135->gpio_pmic_wakeup, 1);
+ else {
+ unsigned int reg_val;
+
+ max17135_reg_read(REG_MAX17135_ENABLE, &reg_val);
+ reg_val &= ~BITFMASK(ENABLE);
+ reg_val |= BITFVAL(ENABLE, 1);
+ max17135_reg_write(REG_MAX17135_ENABLE, reg_val);
+ }
+
+ return max17135_wait_power_good(max17135);
+}
+
+static int max17135_display_disable(struct regulator_dev *reg)
+{
+ struct max17135 *max17135 = rdev_get_drvdata(reg);
+
+ if (max17135->pass_num == 1)
+ gpio_set_value(max17135->gpio_pmic_wakeup, 0);
+ else {
+ unsigned int reg_val;
+
+ max17135_reg_read(REG_MAX17135_ENABLE, &reg_val);
+ reg_val &= ~BITFMASK(ENABLE);
+ max17135_reg_write(REG_MAX17135_ENABLE, reg_val);
+ }
+
+ msleep(max17135->max_wait);
+
+ return 0;
+}
+
+static int max17135_display_is_enabled(struct regulator_dev *reg)
+{
+ struct max17135 *max17135 = rdev_get_drvdata(reg);
+ int gpio = gpio_get_value(max17135->gpio_pmic_wakeup);
+
+ if (gpio == 0)
+ return 0;
+ else
+ return 1;
+}
+
+static int max17135_v3p3_enable(struct regulator_dev *reg)
+{
+ struct max17135 *max17135 = rdev_get_drvdata(reg);
+
+ gpio_set_value(max17135->gpio_pmic_v3p3, 1);
+ return 0;
+}
+
+static int max17135_v3p3_disable(struct regulator_dev *reg)
+{
+ struct max17135 *max17135 = rdev_get_drvdata(reg);
+
+ gpio_set_value(max17135->gpio_pmic_v3p3, 0);
+ return 0;
+}
+
+static int max17135_v3p3_is_enabled(struct regulator_dev *reg)
+{
+ struct max17135 *max17135 = rdev_get_drvdata(reg);
+ int gpio = gpio_get_value(max17135->gpio_pmic_v3p3);
+
+ if (gpio == 0)
+ return 0;
+ else
+ return 1;
+}
+
+/*
+ * Regulator operations
+ */
+
+static struct regulator_ops max17135_display_ops = {
+ .enable = max17135_display_enable,
+ .disable = max17135_display_disable,
+ .is_enabled = max17135_display_is_enabled,
+};
+
+static struct regulator_ops max17135_gvdd_ops = {
+};
+
+static struct regulator_ops max17135_gvee_ops = {
+};
+
+static struct regulator_ops max17135_hvinn_ops = {
+};
+
+static struct regulator_ops max17135_hvinp_ops = {
+ .enable = max17135_hvinp_enable,
+ .disable = max17135_hvinp_disable,
+ .get_voltage = max17135_hvinp_get_voltage,
+ .set_voltage = max17135_hvinp_set_voltage,
+};
+
+static struct regulator_ops max17135_vcom_ops = {
+ .enable = max17135_vcom_enable,
+ .disable = max17135_vcom_disable,
+ .get_voltage = max17135_vcom_get_voltage,
+ .set_voltage = max17135_vcom_set_voltage,
+ .is_enabled = max17135_vcom_is_enabled,
+};
+
+static struct regulator_ops max17135_vneg_ops = {
+};
+
+static struct regulator_ops max17135_vpos_ops = {
+};
+
+static struct regulator_ops max17135_v3p3_ops = {
+ .enable = max17135_v3p3_enable,
+ .disable = max17135_v3p3_disable,
+ .is_enabled = max17135_v3p3_is_enabled,
+};
+
+
+/*
+ * Regulator descriptors
+ */
+static struct regulator_desc max17135_reg[MAX17135_NUM_REGULATORS] = {
+{
+ .name = "DISPLAY",
+ .id = MAX17135_DISPLAY,
+ .ops = &max17135_display_ops,
+ .type = REGULATOR_VOLTAGE,
+ .owner = THIS_MODULE,
+},
+{
+ .name = "GVDD",
+ .id = MAX17135_GVDD,
+ .ops = &max17135_gvdd_ops,
+ .type = REGULATOR_VOLTAGE,
+ .owner = THIS_MODULE,
+},
+{
+ .name = "GVEE",
+ .id = MAX17135_GVEE,
+ .ops = &max17135_gvee_ops,
+ .type = REGULATOR_VOLTAGE,
+ .owner = THIS_MODULE,
+},
+{
+ .name = "HVINN",
+ .id = MAX17135_HVINN,
+ .ops = &max17135_hvinn_ops,
+ .type = REGULATOR_VOLTAGE,
+ .owner = THIS_MODULE,
+},
+{
+ .name = "HVINP",
+ .id = MAX17135_HVINP,
+ .ops = &max17135_hvinp_ops,
+ .type = REGULATOR_VOLTAGE,
+ .owner = THIS_MODULE,
+},
+{
+ .name = "VCOM",
+ .id = MAX17135_VCOM,
+ .ops = &max17135_vcom_ops,
+ .type = REGULATOR_VOLTAGE,
+ .owner = THIS_MODULE,
+},
+{
+ .name = "VNEG",
+ .id = MAX17135_VNEG,
+ .ops = &max17135_vneg_ops,
+ .type = REGULATOR_VOLTAGE,
+ .owner = THIS_MODULE,
+},
+{
+ .name = "VPOS",
+ .id = MAX17135_VPOS,
+ .ops = &max17135_vpos_ops,
+ .type = REGULATOR_VOLTAGE,
+ .owner = THIS_MODULE,
+},
+{
+ .name = "V3P3",
+ .id = MAX17135_V3P3,
+ .ops = &max17135_v3p3_ops,
+ .type = REGULATOR_VOLTAGE,
+ .owner = THIS_MODULE,
+},
+};
+
+static void max17135_setup_timings(struct max17135 *max17135)
+{
+ unsigned int reg_val;
+
+ int timing1, timing2, timing3, timing4,
+ timing5, timing6, timing7, timing8;
+
+ max17135_reg_read(REG_MAX17135_TIMING1, &timing1);
+ max17135_reg_read(REG_MAX17135_TIMING2, &timing2);
+ max17135_reg_read(REG_MAX17135_TIMING3, &timing3);
+ max17135_reg_read(REG_MAX17135_TIMING4, &timing4);
+ max17135_reg_read(REG_MAX17135_TIMING5, &timing5);
+ max17135_reg_read(REG_MAX17135_TIMING6, &timing6);
+ max17135_reg_read(REG_MAX17135_TIMING7, &timing7);
+ max17135_reg_read(REG_MAX17135_TIMING8, &timing8);
+
+ if ((timing1 != max17135->gvee_pwrup) ||
+ (timing2 != max17135->vneg_pwrup) ||
+ (timing3 != max17135->vpos_pwrup) ||
+ (timing4 != max17135->gvdd_pwrup) ||
+ (timing5 != max17135->gvdd_pwrdn) ||
+ (timing6 != max17135->vpos_pwrdn) ||
+ (timing7 != max17135->vneg_pwrdn) ||
+ (timing8 != max17135->gvee_pwrdn)) {
+ max17135_reg_write(REG_MAX17135_TIMING1, max17135->gvee_pwrup);
+ max17135_reg_write(REG_MAX17135_TIMING2, max17135->vneg_pwrup);
+ max17135_reg_write(REG_MAX17135_TIMING3, max17135->vpos_pwrup);
+ max17135_reg_write(REG_MAX17135_TIMING4, max17135->gvdd_pwrup);
+ max17135_reg_write(REG_MAX17135_TIMING5, max17135->gvdd_pwrdn);
+ max17135_reg_write(REG_MAX17135_TIMING6, max17135->vpos_pwrdn);
+ max17135_reg_write(REG_MAX17135_TIMING7, max17135->vneg_pwrdn);
+ max17135_reg_write(REG_MAX17135_TIMING8, max17135->gvee_pwrdn);
+
+ reg_val = BITFVAL(CTRL_TIMING, true); /* shift to correct bit */
+ max17135_reg_write(REG_MAX17135_PRGM_CTRL, reg_val);
+ }
+}
+
+#define CHECK_PROPERTY_ERROR_KFREE(prop) \
+do { \
+ int ret = of_property_read_u32(max17135->dev->of_node, \
+ #prop, &max17135->prop); \
+ if (ret < 0) { \
+ return ret; \
+ } \
+} while (0);
+
+#ifdef CONFIG_OF
+static int max17135_pmic_dt_parse_pdata(struct platform_device *pdev,
+ struct max17135_platform_data *pdata)
+{
+ struct max17135 *max17135 = dev_get_drvdata(pdev->dev.parent);
+ struct device_node *pmic_np, *regulators_np, *reg_np;
+ struct max17135_regulator_data *rdata;
+ int i, ret;
+
+ pmic_np = of_node_get(max17135->dev->of_node);
+ if (!pmic_np) {
+ dev_err(&pdev->dev, "could not find pmic sub-node\n");
+ return -ENODEV;
+ }
+
+ regulators_np = of_find_node_by_name(pmic_np, "regulators");
+ if (!regulators_np) {
+ dev_err(&pdev->dev, "could not find regulators sub-node\n");
+ return -EINVAL;
+ }
+
+ pdata->num_regulators = of_get_child_count(regulators_np);
+ dev_dbg(&pdev->dev, "num_regulators %d\n", pdata->num_regulators);
+
+ rdata = devm_kzalloc(&pdev->dev, sizeof(*rdata) *
+ pdata->num_regulators, GFP_KERNEL);
+ if (!rdata) {
+ of_node_put(regulators_np);
+ dev_err(&pdev->dev, "could not allocate memory for"
+ "regulator data\n");
+ return -ENOMEM;
+ }
+
+ pdata->regulators = rdata;
+ for_each_child_of_node(regulators_np, reg_np) {
+ for (i = 0; i < ARRAY_SIZE(max17135_reg); i++)
+ if (!of_node_cmp(reg_np->name, max17135_reg[i].name))
+ break;
+
+ if (i == ARRAY_SIZE(max17135_reg)) {
+ dev_warn(&pdev->dev, "don't know how to configure"
+ "regulator %s\n", reg_np->name);
+ continue;
+ }
+
+ rdata->id = i;
+ rdata->initdata = of_get_regulator_init_data(&pdev->dev,
+ reg_np,
+ &max17135_reg[i]);
+ rdata->reg_node = reg_np;
+ rdata++;
+ }
+ of_node_put(regulators_np);
+
+ CHECK_PROPERTY_ERROR_KFREE(vneg_pwrup);
+ CHECK_PROPERTY_ERROR_KFREE(gvee_pwrup);
+ CHECK_PROPERTY_ERROR_KFREE(vpos_pwrup);
+ CHECK_PROPERTY_ERROR_KFREE(gvdd_pwrup);
+ CHECK_PROPERTY_ERROR_KFREE(gvdd_pwrdn);
+ CHECK_PROPERTY_ERROR_KFREE(vpos_pwrdn);
+ CHECK_PROPERTY_ERROR_KFREE(gvee_pwrdn);
+ CHECK_PROPERTY_ERROR_KFREE(vneg_pwrdn);
+
+ dev_dbg(&pdev->dev, "vneg_pwrup %d, vneg_pwrdn %d, vpos_pwrup %d,"
+ "vpos_pwrdn %d, gvdd_pwrup %d, gvdd_pwrdn %d, gvee_pwrup %d,"
+ "gvee_pwrdn %d\n", max17135->vneg_pwrup, max17135->vneg_pwrdn,
+ max17135->vpos_pwrup, max17135->vpos_pwrdn,
+ max17135->gvdd_pwrup, max17135->gvdd_pwrdn,
+ max17135->gvee_pwrup, max17135->gvee_pwrdn);
+
+ max17135->max_wait = max17135->vpos_pwrup + max17135->vneg_pwrup +
+ max17135->gvdd_pwrup + max17135->gvee_pwrup;
+
+ max17135->gpio_pmic_wakeup = of_get_named_gpio(pmic_np,
+ "gpio_pmic_wakeup", 0);
+ if (!gpio_is_valid(max17135->gpio_pmic_wakeup)) {
+ dev_err(&pdev->dev, "no epdc pmic wakeup pin available\n");
+ goto err;
+ }
+ ret = devm_gpio_request_one(&pdev->dev, max17135->gpio_pmic_wakeup,
+ GPIOF_OUT_INIT_LOW, "epdc-pmic-wake");
+ if (ret < 0)
+ goto err;
+
+ max17135->gpio_pmic_vcom_ctrl = of_get_named_gpio(pmic_np,
+ "gpio_pmic_vcom_ctrl", 0);
+ if (!gpio_is_valid(max17135->gpio_pmic_vcom_ctrl)) {
+ dev_err(&pdev->dev, "no epdc pmic vcom_ctrl pin available\n");
+ goto err;
+ }
+ ret = devm_gpio_request_one(&pdev->dev, max17135->gpio_pmic_vcom_ctrl,
+ GPIOF_OUT_INIT_LOW, "epdc-vcom");
+ if (ret < 0)
+ goto err;
+
+ max17135->gpio_pmic_v3p3 = of_get_named_gpio(pmic_np,
+ "gpio_pmic_v3p3", 0);
+ if (!gpio_is_valid(max17135->gpio_pmic_v3p3)) {
+ dev_err(&pdev->dev, "no epdc pmic v3p3 pin available\n");
+ goto err;
+ }
+ ret = devm_gpio_request_one(&pdev->dev, max17135->gpio_pmic_v3p3,
+ GPIOF_OUT_INIT_LOW, "epdc-v3p3");
+ if (ret < 0)
+ goto err;
+
+ max17135->gpio_pmic_intr = of_get_named_gpio(pmic_np,
+ "gpio_pmic_intr", 0);
+ if (!gpio_is_valid(max17135->gpio_pmic_intr)) {
+ dev_err(&pdev->dev, "no epdc pmic intr pin available\n");
+ goto err;
+ }
+ ret = devm_gpio_request_one(&pdev->dev, max17135->gpio_pmic_intr,
+ GPIOF_IN, "epdc-pmic-int");
+ if (ret < 0)
+ goto err;
+
+ max17135->gpio_pmic_pwrgood = of_get_named_gpio(pmic_np,
+ "gpio_pmic_pwrgood", 0);
+ if (!gpio_is_valid(max17135->gpio_pmic_pwrgood)) {
+ dev_err(&pdev->dev, "no epdc pmic pwrgood pin available\n");
+ goto err;
+ }
+ ret = devm_gpio_request_one(&pdev->dev, max17135->gpio_pmic_pwrgood,
+ GPIOF_IN, "epdc-pwrstat");
+ if (ret < 0)
+ goto err;
+
+err:
+ return 0;
+
+}
+#else
+static int max17135_pmic_dt_parse_pdata(struct platform_device *pdev,
+ struct max17135 *max17135)
+{
+ return 0;
+}
+#endif /* !CONFIG_OF */
+
+/*
+ * Regulator init/probing/exit functions
+ */
+static int max17135_regulator_probe(struct platform_device *pdev)
+{
+ struct max17135 *max17135 = dev_get_drvdata(pdev->dev.parent);
+ struct max17135_platform_data *pdata = max17135->pdata;
+ struct max17135_data *priv;
+ struct regulator_dev **rdev;
+ struct regulator_config config = { };
+ int size, i, ret = 0;
+
+ if (max17135->dev->of_node) {
+ ret = max17135_pmic_dt_parse_pdata(pdev, pdata);
+ if (ret)
+ return ret;
+ }
+ priv = devm_kzalloc(&pdev->dev, sizeof(struct max17135_data),
+ GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ size = sizeof(struct regulator_dev *) * pdata->num_regulators;
+ priv->rdev = devm_kzalloc(&pdev->dev, size, GFP_KERNEL);
+ if (!priv->rdev)
+ return -ENOMEM;
+
+ rdev = priv->rdev;
+ priv->num_regulators = pdata->num_regulators;
+ platform_set_drvdata(pdev, priv);
+
+ max17135->vcom_setup = false;
+ max17135->pass_num = max17135_pass_num;
+ max17135->vcom_uV = max17135_vcom;
+
+ for (i = 0; i < pdata->num_regulators; i++) {
+ int id = pdata->regulators[i].id;
+
+ config.dev = max17135->dev;
+ config.init_data = pdata->regulators[i].initdata;
+ config.driver_data = max17135;
+ config.of_node = pdata->regulators[i].reg_node;
+
+ rdev[i] = regulator_register(&max17135_reg[id], &config);
+ if (IS_ERR(rdev[i])) {
+ ret = PTR_ERR(rdev[i]);
+ dev_err(&pdev->dev, "regulator init failed for %d\n",
+ id);
+ rdev[i] = NULL;
+ goto err;
+ }
+ }
+
+ /*
+ * Set up PMIC timing values.
+ * Should only be done one time! Timing values may only be
+ * changed a limited number of times according to spec.
+ */
+ max17135_setup_timings(max17135);
+
+ return 0;
+err:
+ while (--i >= 0)
+ regulator_unregister(rdev[i]);
+ return ret;
+}
+
+static int max17135_regulator_remove(struct platform_device *pdev)
+{
+ struct max17135_data *priv = platform_get_drvdata(pdev);
+ struct regulator_dev **rdev = priv->rdev;
+ int i;
+
+ for (i = 0; i < priv->num_regulators; i++)
+ regulator_unregister(rdev[i]);
+ return 0;
+}
+
+static const struct platform_device_id max17135_pmic_id[] = {
+ { "max17135-pmic", 0},
+ { /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(platform, max17135_pmic_id);
+
+static struct platform_driver max17135_regulator_driver = {
+ .probe = max17135_regulator_probe,
+ .remove = max17135_regulator_remove,
+ .id_table = max17135_pmic_id,
+ .driver = {
+ .name = "max17135-pmic",
+ },
+};
+
+static int __init max17135_regulator_init(void)
+{
+ return platform_driver_register(&max17135_regulator_driver);
+}
+subsys_initcall_sync(max17135_regulator_init);
+
+static void __exit max17135_regulator_exit(void)
+{
+ platform_driver_unregister(&max17135_regulator_driver);
+}
+module_exit(max17135_regulator_exit);
+
+/*
+ * Parse user specified options (`max17135:')
+ * example:
+ * max17135:pass=2,vcom=-1250000
+ */
+static int __init max17135_setup(char *options)
+{
+ int ret;
+ char *opt;
+ while ((opt = strsep(&options, ",")) != NULL) {
+ if (!*opt)
+ continue;
+ if (!strncmp(opt, "pass=", 5)) {
+ ret = kstrtoul(opt + 5, 0, &max17135_pass_num);
+ if (ret < 0)
+ return ret;
+ }
+ if (!strncmp(opt, "vcom=", 5)) {
+ int offs = 5;
+ if (opt[5] == '-')
+ offs = 6;
+ ret = kstrtoul(opt + offs, 0,
+ (long *)&max17135_vcom);
+ if (ret < 0)
+ return ret;
+ max17135_vcom = -max17135_vcom;
+ }
+ }
+
+ return 1;
+}
+
+__setup("max17135:", max17135_setup);
+
+/* Module information */
+MODULE_DESCRIPTION("MAX17135 regulator driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/regulator/pf1550-regulator-rpmsg.c b/drivers/regulator/pf1550-regulator-rpmsg.c
new file mode 100644
index 000000000000..11a893373390
--- /dev/null
+++ b/drivers/regulator/pf1550-regulator-rpmsg.c
@@ -0,0 +1,512 @@
+/*
+ * pf1550.c - regulator driver for the PF1550
+ *
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright (C) 2017 NXP.
+ * Robin Gong <yibin.gong@freescale.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/err.h>
+#include <linux/slab.h>
+#include <linux/imx_rpmsg.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/pm_qos.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/of_regulator.h>
+#include <linux/regulator/machine.h>
+#include <linux/rpmsg.h>
+#include <linux/uaccess.h>
+#include <linux/virtio.h>
+
+#define PF1550_DBGFS
+#define PF1550_MAX_REGULATOR 7
+#define RPMSG_TIMEOUT 1000
+
+enum pf1550_regs {
+ PF1550_SW1,
+ PF1550_SW2,
+ PF1550_SW3,
+ PF1550_VREFDDR,
+ PF1550_LDO1,
+ PF1550_LDO2,
+ PF1550_LDO3,
+};
+
+enum pf1550_rpmsg_cmd {
+ PF1550_ENABLE,
+ PF1550_DISABLE,
+ PF1550_IS_ENABLED,
+ PF1550_SET_VOL,
+ PF1550_GET_VOL,
+ PF1550_GET_REG,
+ PF1550_SET_REG,
+};
+
+enum pf1550_resp {
+ PF1550_SUCCESS,
+ PF1550_FAILED,
+ PF1550_UNSURPPORT,
+};
+
+enum pf1550_status {
+ PF1550_DISABLED,
+ PF1550_ENABLED,
+};
+
+struct pf1550_regulator_info {
+ struct rpmsg_device *rpdev;
+ struct device *dev;
+ struct pf1550_regulator_rpmsg *msg;
+ struct completion cmd_complete;
+ struct pm_qos_request pm_qos_req;
+ struct mutex lock;
+ struct regulator_desc *regulators;
+};
+
+static struct pf1550_regulator_info pf1550_info;
+
+struct pf1550_regulator_rpmsg {
+ /* common head */
+ struct imx_rpmsg_head header;
+ /* pmic structure */
+ union {
+ u8 regulator;
+ u8 reg;
+ };
+ u8 response;
+ u8 status;
+ union {
+ u32 voltage; /* uV */
+ u32 val;
+ };
+} __attribute__ ((packed));
+
+static int pf1550_send_message(struct pf1550_regulator_rpmsg *msg,
+ struct pf1550_regulator_info *info)
+{
+ int err;
+
+ if (!info->rpdev) {
+ dev_dbg(info->dev,
+ "rpmsg channel not ready, m4 image ready?\n");
+ return -EINVAL;
+ }
+
+ mutex_lock(&info->lock);
+ pm_qos_add_request(&info->pm_qos_req, PM_QOS_CPU_DMA_LATENCY, 0);
+
+ msg->header.cate = IMX_RPMSG_PMIC;
+ msg->header.major = IMX_RMPSG_MAJOR;
+ msg->header.minor = IMX_RMPSG_MINOR;
+ msg->header.type = 0;
+
+ /* wait response from rpmsg */
+ reinit_completion(&info->cmd_complete);
+
+ err = rpmsg_send(info->rpdev->ept, (void *)msg,
+ sizeof(struct pf1550_regulator_rpmsg));
+ if (err) {
+ dev_err(&info->rpdev->dev, "rpmsg_send failed: %d\n", err);
+ goto err_out;
+ }
+ err = wait_for_completion_timeout(&info->cmd_complete,
+ msecs_to_jiffies(RPMSG_TIMEOUT));
+ if (!err) {
+ dev_err(&info->rpdev->dev, "rpmsg_send timeout!\n");
+ err = -ETIMEDOUT;
+ goto err_out;
+ }
+
+ err = 0;
+
+err_out:
+ pm_qos_remove_request(&info->pm_qos_req);
+ mutex_unlock(&info->lock);
+
+ dev_dbg(&info->rpdev->dev, "cmd:%d, reg:%d, resp:%d.\n",
+ msg->header.cmd, msg->regulator, msg->response);
+
+ return err;
+}
+
+static int pf1550_enable(struct regulator_dev *reg)
+{
+ struct pf1550_regulator_info *info = rdev_get_drvdata(reg);
+ struct pf1550_regulator_rpmsg msg;
+
+ msg.header.cmd = PF1550_ENABLE;
+ msg.regulator = reg->desc->id;
+
+ return pf1550_send_message(&msg, info);
+}
+
+static int pf1550_disable(struct regulator_dev *reg)
+{
+ struct pf1550_regulator_info *info = rdev_get_drvdata(reg);
+ struct pf1550_regulator_rpmsg msg;
+
+ msg.header.cmd = PF1550_DISABLE;
+ msg.regulator = reg->desc->id;
+
+ return pf1550_send_message(&msg, info);
+}
+
+static int pf1550_is_enabled(struct regulator_dev *reg)
+{
+ struct pf1550_regulator_info *info = rdev_get_drvdata(reg);
+ struct pf1550_regulator_rpmsg msg;
+ int err;
+
+ msg.header.cmd = PF1550_IS_ENABLED;
+ msg.regulator = reg->desc->id;
+
+ err = pf1550_send_message(&msg, info);
+ if (err)
+ return err;
+ /* Here SUCCESS means ENABLED */
+ if (info->msg->status == PF1550_ENABLED)
+ return 1;
+ else
+ return 0;
+}
+
+static int pf1550_set_voltage(struct regulator_dev *reg,
+ int minuV, int uV, unsigned *selector)
+{
+ struct pf1550_regulator_info *info = rdev_get_drvdata(reg);
+ struct pf1550_regulator_rpmsg msg;
+ int err;
+
+ msg.header.cmd = PF1550_SET_VOL;
+ msg.regulator = reg->desc->id;
+ msg.voltage = minuV;
+
+ err = pf1550_send_message(&msg, info);
+ if (err)
+ return err;
+
+ if (info->msg->response == PF1550_UNSURPPORT) {
+ dev_err(info->dev, "Voltages not allowed to set to %d!\n", uV);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int pf1550_get_voltage(struct regulator_dev *reg)
+{
+ struct pf1550_regulator_info *info = rdev_get_drvdata(reg);
+ struct pf1550_regulator_rpmsg msg;
+ int err;
+
+ msg.header.cmd = PF1550_GET_VOL;
+ msg.regulator = reg->desc->id;
+ msg.voltage = 0;
+
+ err = pf1550_send_message(&msg, info);
+ if (err)
+ return err;
+
+ return info->msg->voltage;
+}
+
+/* return the fix voltage */
+static int pf1550_get_fix_voltage(struct regulator_dev *dev)
+{
+ return dev->desc->fixed_uV;
+}
+
+static struct regulator_ops pf1550_sw_ops = {
+ .set_voltage = pf1550_set_voltage,
+ .get_voltage = pf1550_get_voltage,
+};
+
+static struct regulator_ops pf1550_ldo_ops = {
+ .enable = pf1550_enable,
+ .disable = pf1550_disable,
+ .is_enabled = pf1550_is_enabled,
+ .set_voltage = pf1550_set_voltage,
+ .get_voltage = pf1550_get_voltage,
+};
+
+static struct regulator_ops pf1550_fixed_ops = {
+ .enable = pf1550_enable,
+ .disable = pf1550_disable,
+ .get_voltage = pf1550_get_fix_voltage,
+ .is_enabled = pf1550_is_enabled,
+};
+
+static struct regulator_desc pf1550_regulators[PF1550_MAX_REGULATOR] = {
+{
+ .name = "SW1",
+ .of_match = of_match_ptr("SW1"),
+ .id = PF1550_SW1,
+ .ops = &pf1550_sw_ops,
+ .type = REGULATOR_VOLTAGE,
+ .owner = THIS_MODULE,
+},
+{
+ .name = "SW2",
+ .of_match = of_match_ptr("SW2"),
+ .id = PF1550_SW2,
+ .ops = &pf1550_sw_ops,
+ .type = REGULATOR_VOLTAGE,
+ .owner = THIS_MODULE,
+},
+{
+ .name = "SW3",
+ .of_match = of_match_ptr("SW3"),
+ .id = PF1550_SW3,
+ .ops = &pf1550_sw_ops,
+ .type = REGULATOR_VOLTAGE,
+ .owner = THIS_MODULE,
+},
+{
+ .name = "VREFDDR",
+ .of_match = of_match_ptr("VREFDDR"),
+ .id = PF1550_VREFDDR,
+ .ops = &pf1550_fixed_ops,
+ .type = REGULATOR_VOLTAGE,
+ .fixed_uV = 1200000,
+ .owner = THIS_MODULE,
+},
+{
+ .name = "LDO1",
+ .of_match = of_match_ptr("LDO1"),
+ .id = PF1550_LDO1,
+ .ops = &pf1550_ldo_ops,
+ .type = REGULATOR_VOLTAGE,
+ .owner = THIS_MODULE,
+},
+{
+ .name = "LDO2",
+ .of_match = of_match_ptr("LDO2"),
+ .id = PF1550_LDO2,
+ .ops = &pf1550_ldo_ops,
+ .type = REGULATOR_VOLTAGE,
+ .owner = THIS_MODULE,
+},
+{
+ .name = "LDO3",
+ .of_match = of_match_ptr("LDO3"),
+ .id = PF1550_LDO3,
+ .ops = &pf1550_ldo_ops,
+ .type = REGULATOR_VOLTAGE,
+ .owner = THIS_MODULE,
+},
+};
+
+
+static int rpmsg_regulator_cb(struct rpmsg_device *rpdev, void *data, int len,
+ void *priv, u32 src)
+{
+ struct pf1550_regulator_rpmsg *msg = (struct pf1550_regulator_rpmsg *)data;
+
+
+ dev_dbg(&rpdev->dev, "get from%d: cmd:%d, reg:%d, resp:%d.\n",
+ src, msg->header.cmd, msg->regulator, msg->response);
+
+ pf1550_info.msg = msg;
+
+ complete(&pf1550_info.cmd_complete);
+
+ return 0;
+}
+
+static int rpmsg_regulator_probe(struct rpmsg_device *rpdev)
+{
+ pf1550_info.rpdev = rpdev;
+
+ init_completion(&pf1550_info.cmd_complete);
+ mutex_init(&pf1550_info.lock);
+
+ dev_info(&rpdev->dev, "new channel: 0x%x -> 0x%x!\n",
+ rpdev->src, rpdev->dst);
+ return 0;
+}
+
+static void rpmsg_regulator_remove(struct rpmsg_device *rpdev)
+{
+ dev_info(&rpdev->dev, "rpmsg regulator driver is removed\n");
+}
+
+static struct rpmsg_device_id rpmsg_regulator_id_table[] = {
+ { .name = "rpmsg-regulator-channel" },
+ { },
+};
+
+static struct rpmsg_driver rpmsg_regulator_driver = {
+ .drv.name = "regulator_rpmsg",
+ .drv.owner = THIS_MODULE,
+ .id_table = rpmsg_regulator_id_table,
+ .probe = rpmsg_regulator_probe,
+ .callback = rpmsg_regulator_cb,
+ .remove = rpmsg_regulator_remove,
+};
+
+#ifdef PF1550_DBGFS
+#define MAX_REGS 0xff
+
+/*
+ * Alligned the below two functions as the same as regmap_map_read_file
+ * and regmap_map_write_file in regmap-debugfs.c
+ */
+static ssize_t pf1550_registers_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int i;
+ struct platform_device *pdev = to_platform_device(dev);
+ struct pf1550_regulator_info *info = platform_get_drvdata(pdev);
+ struct pf1550_regulator_rpmsg msg;
+ int err;
+ size_t bufpos = 0, count = MAX_REGS * 7;
+
+ for (i = 0; i < MAX_REGS; i++) {
+ snprintf(buf + bufpos, count - bufpos, "%.*x: ", 2, i);
+ bufpos += 4;
+
+ msg.header.cmd = PF1550_GET_REG;
+ msg.reg = i;
+ msg.val = 0;
+
+ err = pf1550_send_message(&msg, info);
+ if (err)
+ return err;
+
+ if (info->msg->response != PF1550_SUCCESS) {
+ dev_err(info->dev, "Get register failed %x, resp=%x!\n",
+ i, info->msg->response);
+ return -EINVAL;
+ }
+
+ snprintf(buf + bufpos, count - bufpos, "%.*x\n", 2,
+ info->msg->val);
+ bufpos += 2;
+
+ buf[bufpos++] = '\n';
+ }
+
+ return bufpos;
+}
+
+static ssize_t pf1550_register_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct pf1550_regulator_info *info = platform_get_drvdata(pdev);
+ struct pf1550_regulator_rpmsg msg;
+ char *start = (char *)buf;
+ unsigned long reg, value;
+ int err;
+
+ while (*start == ' ')
+ start++;
+ reg = simple_strtoul(start, &start, 16);
+
+ while (*start == ' ')
+ start++;
+ if (kstrtoul(start, 16, &value))
+ return -EINVAL;
+
+ msg.header.cmd = PF1550_SET_REG;
+ msg.reg = reg;
+ msg.val = value;
+
+ err = pf1550_send_message(&msg, info);
+ if (err)
+ return err;
+
+ if (info->msg->response != PF1550_SUCCESS) {
+ dev_err(info->dev, "set register failed %lx!\n", reg);
+ return -EINVAL;
+ }
+
+ return size;
+}
+
+static DEVICE_ATTR(regs, 0644, pf1550_registers_show, pf1550_register_store);
+#endif
+
+static int pf1550_regulator_probe(struct platform_device *pdev)
+{
+ struct device_node *np = pdev->dev.of_node;
+ int i;
+ struct regulator_config config = { };
+
+ if (!np)
+ return -ENODEV;
+
+ config.dev = &pdev->dev;
+ config.driver_data = &pf1550_info;
+ pf1550_info.dev = &pdev->dev;
+ pf1550_info.regulators = pf1550_regulators;
+
+ for (i = 0; i < ARRAY_SIZE(pf1550_regulators); i++) {
+ struct regulator_dev *rdev;
+ struct regulator_desc *desc;
+
+ desc = &pf1550_info.regulators[i];
+ rdev = devm_regulator_register(&pdev->dev, desc, &config);
+ if (IS_ERR(rdev)) {
+ dev_err(&pdev->dev,
+ "Failed to initialize regulator-%d\n", i);
+ return PTR_ERR(rdev);
+ }
+ }
+
+#ifdef PF1550_DBGFS
+ i = sysfs_create_file(&config.dev->kobj, &dev_attr_regs.attr);
+ if (i) {
+ dev_err(&pdev->dev, "Failed to create pf1550 debug sysfs.\n");
+ return i;
+ }
+#endif
+
+ platform_set_drvdata(pdev, &pf1550_info);
+
+ return 0;
+}
+
+static const struct of_device_id pf1550_regulator_id[] = {
+ {"fsl,pf1550-rpmsg",},
+ {},
+};
+
+MODULE_DEVICE_TABLE(of, pf1550_regulator_id);
+
+static struct platform_driver pf1550_regulator_driver = {
+ .driver = {
+ .name = "pf1550-rpmsg",
+ .owner = THIS_MODULE,
+ .of_match_table = pf1550_regulator_id,
+ },
+ .probe = pf1550_regulator_probe,
+};
+
+static int __init pf1550_rpmsg_init(void)
+{
+ return register_rpmsg_driver(&rpmsg_regulator_driver);
+}
+
+module_platform_driver(pf1550_regulator_driver);
+module_init(pf1550_rpmsg_init);
+
+MODULE_DESCRIPTION("Freescale PF1550 regulator rpmsg driver");
+MODULE_AUTHOR("Robin Gong <yibin.gong@freescale.com>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/regulator/pf1550.c b/drivers/regulator/pf1550.c
new file mode 100644
index 000000000000..f6837052859b
--- /dev/null
+++ b/drivers/regulator/pf1550.c
@@ -0,0 +1,390 @@
+/*
+ * pf1550.c - regulator driver for the PF1550
+ *
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Robin Gong <yibin.gong@freescale.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.
+ *
+ * This driver is based on pfuze100-regulator.c
+ */
+
+#include <linux/err.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+#include <linux/mfd/pf1550.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/of_regulator.h>
+#include <linux/regulator/machine.h>
+#include <linux/platform_device.h>
+
+#define PF1550_MAX_REGULATOR 7
+
+struct pf1550_desc {
+ struct regulator_desc desc;
+ unsigned char stby_reg;
+ unsigned char stby_mask;
+};
+
+struct pf1550_regulator_info {
+ struct device *dev;
+ struct pf1550_dev *pf1550;
+ struct pf1550_desc regulator_descs[PF1550_MAX_REGULATOR];
+ int irq;
+};
+
+static struct pf1550_irq_info pf1550_regulator_irqs[] = {
+ { PF1550_PMIC_IRQ_SW1_LS, "sw1-lowside" },
+ { PF1550_PMIC_IRQ_SW2_LS, "sw2-lowside" },
+ { PF1550_PMIC_IRQ_SW3_LS, "sw3-lowside" },
+
+ { PF1550_PMIC_IRQ_SW1_HS, "sw1-highside" },
+ { PF1550_PMIC_IRQ_SW2_HS, "sw2-highside" },
+ { PF1550_PMIC_IRQ_SW3_HS, "sw3-highside" },
+
+ { PF1550_PMIC_IRQ_LDO1_FAULT, "ldo1-fault" },
+ { PF1550_PMIC_IRQ_LDO2_FAULT, "ldo2-fault" },
+ { PF1550_PMIC_IRQ_LDO3_FAULT, "ldo3-fault" },
+
+ { PF1550_PMIC_IRQ_TEMP_110, "temp-110" },
+ { PF1550_PMIC_IRQ_TEMP_125, "temp-125" },
+};
+
+static const int pf1550_sw12_volts[] = {
+ 1100000, 1200000, 1350000, 1500000, 1800000, 2500000, 3000000, 3300000,
+};
+
+static const int pf1550_ldo13_volts[] = {
+ 750000, 800000, 850000, 900000, 950000, 1000000, 1050000, 1100000,
+ 1150000, 1200000, 1250000, 1300000, 1350000, 1400000, 1450000, 1500000,
+ 1800000, 1900000, 2000000, 2100000, 2200000, 2300000, 2400000, 2500000,
+ 2600000, 2700000, 2800000, 2900000, 3000000, 3100000, 3200000, 3300000,
+};
+
+static int pf1550_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay)
+{
+ int id = rdev_get_id(rdev);
+ unsigned int ramp_bits;
+ int ret;
+
+ if (id < PF1550_VREFDDR) {
+ ramp_delay = 6250 / ramp_delay;
+ ramp_bits = ramp_delay >> 1;
+ ret = regmap_update_bits(rdev->regmap,
+ rdev->desc->vsel_reg + 4,
+ 0x10, ramp_bits << 4);
+ if (ret < 0)
+ dev_err(&rdev->dev, "ramp failed, err %d\n", ret);
+ } else
+ ret = -EACCES;
+
+ return ret;
+}
+
+static struct regulator_ops pf1550_sw1_ops = {
+ .list_voltage = regulator_list_voltage_table,
+ .set_voltage_sel = regulator_set_voltage_sel_regmap,
+ .get_voltage_sel = regulator_get_voltage_sel_regmap,
+ .set_voltage_time_sel = regulator_set_voltage_time_sel,
+ .set_ramp_delay = pf1550_set_ramp_delay,
+};
+
+static struct regulator_ops pf1550_sw2_ops = {
+ .list_voltage = regulator_list_voltage_linear,
+ .set_voltage_sel = regulator_set_voltage_sel_regmap,
+ .get_voltage_sel = regulator_get_voltage_sel_regmap,
+ .set_voltage_time_sel = regulator_set_voltage_time_sel,
+ .set_ramp_delay = pf1550_set_ramp_delay,
+};
+
+static struct regulator_ops pf1550_ldo1_ops = {
+ .enable = regulator_enable_regmap,
+ .disable = regulator_disable_regmap,
+ .is_enabled = regulator_is_enabled_regmap,
+ .list_voltage = regulator_list_voltage_table,
+ .map_voltage = regulator_map_voltage_ascend,
+ .set_voltage_sel = regulator_set_voltage_sel_regmap,
+ .get_voltage_sel = regulator_get_voltage_sel_regmap,
+};
+
+static struct regulator_ops pf1550_ldo2_ops = {
+ .enable = regulator_enable_regmap,
+ .disable = regulator_disable_regmap,
+ .is_enabled = regulator_is_enabled_regmap,
+ .list_voltage = regulator_list_voltage_linear,
+ .set_voltage_sel = regulator_set_voltage_sel_regmap,
+ .get_voltage_sel = regulator_get_voltage_sel_regmap,
+};
+
+static struct regulator_ops pf1550_fixed_ops = {
+ .enable = regulator_enable_regmap,
+ .disable = regulator_disable_regmap,
+ .is_enabled = regulator_is_enabled_regmap,
+ .list_voltage = regulator_list_voltage_linear,
+};
+
+#define PF_VREF(_chip, _name, voltage) { \
+ .desc = { \
+ .name = #_name, \
+ .of_match = of_match_ptr(#_name), \
+ .regulators_node = of_match_ptr("regulators"), \
+ .n_voltages = 1, \
+ .ops = &pf1550_fixed_ops, \
+ .type = REGULATOR_VOLTAGE, \
+ .id = _chip ## _ ## _name, \
+ .owner = THIS_MODULE, \
+ .min_uV = (voltage), \
+ .enable_reg = _chip ## _PMIC_REG_ ## _name ## _CTRL, \
+ .enable_mask = 0x1, \
+ }, \
+ .stby_reg = _chip ## _PMIC_REG_ ## _name ## _CTRL, \
+ .stby_mask = 0x2, \
+}
+
+#define PF_SW1(_chip, _name, mask, voltages) { \
+ .desc = { \
+ .name = #_name, \
+ .of_match = of_match_ptr(#_name), \
+ .regulators_node = of_match_ptr("regulators"), \
+ .n_voltages = ARRAY_SIZE(voltages), \
+ .ops = &pf1550_sw1_ops, \
+ .type = REGULATOR_VOLTAGE, \
+ .id = _chip ## _ ## _name, \
+ .owner = THIS_MODULE, \
+ .volt_table = voltages, \
+ .vsel_reg = _chip ## _PMIC_REG_ ## _name ## _VOLT, \
+ .vsel_mask = (mask), \
+ }, \
+ .stby_reg = _chip ## _PMIC_REG_ ## _name ## _STBY_VOLT, \
+ .stby_mask = (mask), \
+}
+
+#define PF_SW3(_chip, _name, min, max, mask, step) { \
+ .desc = { \
+ .name = #_name, \
+ .of_match = of_match_ptr(#_name), \
+ .regulators_node = of_match_ptr("regulators"), \
+ .n_voltages = ((max) - (min)) / (step) + 1, \
+ .ops = &pf1550_sw2_ops, \
+ .type = REGULATOR_VOLTAGE, \
+ .id = _chip ## _ ## _name, \
+ .owner = THIS_MODULE, \
+ .min_uV = (min), \
+ .uV_step = (step), \
+ .vsel_reg = _chip ## _PMIC_REG_ ## _name ## _VOLT, \
+ .vsel_mask = (mask), \
+ }, \
+ .stby_reg = _chip ## _PMIC_REG_ ## _name ## _STBY_VOLT, \
+ .stby_mask = (mask), \
+}
+
+#define PF_LDO1(_chip, _name, mask, voltages) { \
+ .desc = { \
+ .name = #_name, \
+ .of_match = of_match_ptr(#_name), \
+ .regulators_node = of_match_ptr("regulators"), \
+ .n_voltages = ARRAY_SIZE(voltages), \
+ .ops = &pf1550_ldo1_ops, \
+ .type = REGULATOR_VOLTAGE, \
+ .id = _chip ## _ ## _name, \
+ .owner = THIS_MODULE, \
+ .volt_table = voltages, \
+ .vsel_reg = _chip ## _PMIC_REG_ ## _name ## _VOLT, \
+ .vsel_mask = (mask), \
+ .enable_reg = _chip ## _PMIC_REG_ ## _name ## _CTRL, \
+ .enable_mask = 0x1, \
+ }, \
+ .stby_reg = _chip ## _PMIC_REG_ ## _name ## _CTRL, \
+ .stby_mask = 0x2, \
+}
+
+#define PF_LDO2(_chip, _name, mask, min, max, step) { \
+ .desc = { \
+ .name = #_name, \
+ .of_match = of_match_ptr(#_name), \
+ .regulators_node = of_match_ptr("regulators"), \
+ .n_voltages = ((max) - (min)) / (step) + 1, \
+ .ops = &pf1550_ldo2_ops, \
+ .type = REGULATOR_VOLTAGE, \
+ .id = _chip ## _ ## _name, \
+ .owner = THIS_MODULE, \
+ .min_uV = (min), \
+ .uV_step = (step), \
+ .vsel_reg = _chip ## _PMIC_REG_ ## _name ## _VOLT, \
+ .vsel_mask = (mask), \
+ .enable_reg = _chip ## _PMIC_REG_ ## _name ## _CTRL, \
+ .enable_mask = 0x1, \
+ }, \
+ .stby_reg = _chip ## _PMIC_REG_ ## _name ## _CTRL, \
+ .stby_mask = 0x2, \
+}
+
+static struct pf1550_desc pf1550_regulators[] = {
+ PF_SW3(PF1550, SW1, 600000, 1387500, 0x3f, 12500),
+ PF_SW3(PF1550, SW2, 600000, 1387500, 0x3f, 12500),
+ PF_SW3(PF1550, SW3, 1800000, 3300000, 0xf, 100000),
+ PF_VREF(PF1550, VREFDDR, 1200000),
+ PF_LDO1(PF1550, LDO1, 0x1f, pf1550_ldo13_volts),
+ PF_LDO2(PF1550, LDO2, 0xf, 1800000, 3300000, 100000),
+ PF_LDO1(PF1550, LDO3, 0x1f, pf1550_ldo13_volts),
+};
+
+static irqreturn_t pf1550_regulator_irq_handler(int irq, void *data)
+{
+ struct pf1550_regulator_info *info = data;
+ int i, irq_type = -1;
+
+ info->irq = irq;
+
+ for (i = 0; i < ARRAY_SIZE(pf1550_regulator_irqs); i++)
+ if (info->irq == pf1550_regulator_irqs[i].virq)
+ irq_type = pf1550_regulator_irqs[i].irq;
+
+ switch (irq_type) {
+ case PF1550_PMIC_IRQ_SW1_LS:
+ case PF1550_PMIC_IRQ_SW2_LS:
+ case PF1550_PMIC_IRQ_SW3_LS:
+ dev_info(info->dev, "lowside interrupt trigged! irq_type=%d\n",
+ irq_type);
+ break;
+ case PF1550_PMIC_IRQ_SW1_HS:
+ case PF1550_PMIC_IRQ_SW2_HS:
+ case PF1550_PMIC_IRQ_SW3_HS:
+ dev_info(info->dev, "highside interrupt triggered! irq_type=%d\n",
+ irq_type);
+ break;
+ case PF1550_PMIC_IRQ_LDO1_FAULT:
+ case PF1550_PMIC_IRQ_LDO2_FAULT:
+ case PF1550_PMIC_IRQ_LDO3_FAULT:
+ dev_info(info->dev, "ldo fault triggered! irq_type=%d\n",
+ irq_type);
+ break;
+ case PF1550_PMIC_IRQ_TEMP_110:
+ case PF1550_PMIC_IRQ_TEMP_125:
+ dev_info(info->dev, "thermal exception triggered! irq_type=%d\n",
+ irq_type);
+ break;
+ default:
+ dev_err(info->dev, "regulator interrupt: irq %d occurred\n",
+ irq_type);
+ }
+
+ return IRQ_HANDLED;
+}
+
+static int pf1550_regulator_probe(struct platform_device *pdev)
+{
+ struct pf1550_dev *iodev = dev_get_drvdata(pdev->dev.parent);
+ struct device_node *np = pdev->dev.of_node;
+ struct pf1550_regulator_info *info;
+ int i, ret = 0;
+ struct regulator_config config = { };
+
+ if (!np)
+ return -ENODEV;
+
+ info = devm_kzalloc(&pdev->dev, sizeof(struct pf1550_regulator_info),
+ GFP_KERNEL);
+ if (!info)
+ return -ENOMEM;
+
+ config.dev = iodev->dev;
+ config.regmap = iodev->regmap;
+ info->dev = &pdev->dev;
+ info->pf1550 = iodev;
+
+ memcpy(info->regulator_descs, pf1550_regulators,
+ sizeof(info->regulator_descs));
+
+ for (i = 0; i < ARRAY_SIZE(pf1550_regulators); i++) {
+ struct regulator_dev *rdev;
+ struct regulator_desc *desc;
+ unsigned int val;
+
+ desc = &info->regulator_descs[i].desc;
+
+ if (desc->id == PF1550_SW2) {
+ pf1550_read_otp(info->pf1550, 0x1f, &val);
+ /* OTP_SW2_DVS_ENB == 1? */
+ if ((val & 0x8)) {
+ desc->volt_table = pf1550_sw12_volts;
+ desc->n_voltages = ARRAY_SIZE(pf1550_sw12_volts);
+ desc->ops = &pf1550_sw1_ops;
+ }
+ }
+
+ rdev = devm_regulator_register(&pdev->dev, desc, &config);
+ if (IS_ERR(rdev)) {
+ dev_err(&pdev->dev,
+ "Failed to initialize regulator-%d\n", i);
+ return PTR_ERR(rdev);
+ }
+ }
+
+ platform_set_drvdata(pdev, info);
+
+ for (i = 0; i < ARRAY_SIZE(pf1550_regulator_irqs); i++) {
+ struct pf1550_irq_info *regulator_irq =
+ &pf1550_regulator_irqs[i];
+ unsigned int virq = 0;
+
+ virq = regmap_irq_get_virq(iodev->irq_data_regulator,
+ regulator_irq->irq);
+
+ if (!virq)
+ return -EINVAL;
+ regulator_irq->virq = virq;
+
+ ret = devm_request_threaded_irq(&pdev->dev, virq, NULL,
+ pf1550_regulator_irq_handler,
+ IRQF_NO_SUSPEND,
+ regulator_irq->name, info);
+ if (ret) {
+ dev_err(&pdev->dev,
+ "failed: irq request (IRQ: %d, error :%d)\n",
+ regulator_irq->irq, ret);
+ return ret;
+ }
+ }
+
+ /* unmask all exception interrupts for regulators */
+ regmap_write(info->pf1550->regmap, PF1550_PMIC_REG_SW_INT_MASK0, 0);
+ regmap_write(info->pf1550->regmap, PF1550_PMIC_REG_SW_INT_MASK1, 0);
+ regmap_write(info->pf1550->regmap, PF1550_PMIC_REG_LDO_INT_MASK0, 0);
+ regmap_write(info->pf1550->regmap, PF1550_PMIC_REG_TEMP_INT_MASK0, 0);
+
+ return 0;
+}
+
+static const struct platform_device_id pf1550_regulator_id[] = {
+ {"pf1550-regulator", PF1550},
+ {},
+};
+
+MODULE_DEVICE_TABLE(platform, pf1550_regulator_id);
+
+static struct platform_driver pf1550_regulator_driver = {
+ .driver = {
+ .name = "pf1550-regulator",
+ },
+ .probe = pf1550_regulator_probe,
+ .id_table = pf1550_regulator_id,
+};
+
+module_platform_driver(pf1550_regulator_driver);
+
+MODULE_DESCRIPTION("Freescale PF1550 regulator driver");
+MODULE_AUTHOR("Robin Gong <yibin.gong@freescale.com>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/regulator/pfuze100-regulator.c b/drivers/regulator/pfuze100-regulator.c
index 4f205366d8ae..72523851319a 100644
--- a/drivers/regulator/pfuze100-regulator.c
+++ b/drivers/regulator/pfuze100-regulator.c
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2011-2013 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2017 NXP
*
* 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
@@ -35,6 +36,15 @@
#define PFUZE100_STANDBY_OFFSET 1
#define PFUZE100_MODE_OFFSET 3
#define PFUZE100_CONF_OFFSET 4
+/*
+ * below regs will lost after exit from LPSR mode(PFUZE3000), need to be saved
+ * and restored:
+ * 0x20~0x40: 33
+ * 0x66~0x71: 12
+ * 0x7f: 1
+ * total 46 registers.
+ */
+#define PFUZE100_REG_SAVED_NUM (33 + 12 + 1)
#define PFUZE100_DEVICEID 0x0
#define PFUZE100_REVID 0x3
@@ -69,6 +79,8 @@ struct pfuze_chip {
int chip_id;
struct regmap *regmap;
struct device *dev;
+ bool need_restore;
+ unsigned int reg_save_array[PFUZE100_REG_SAVED_NUM];
struct pfuze_regulator regulator_descs[PFUZE100_MAX_REGULATOR];
struct regulator_dev *regulators[PFUZE100_MAX_REGULATOR];
struct pfuze_regulator *pfuze_regulators;
@@ -86,6 +98,13 @@ static const int pfuze100_coin[] = {
2500000, 2700000, 2800000, 2900000, 3000000, 3100000, 3200000, 3300000,
};
+static const int pfuze3000_sw1a[] = {
+ 700000, 725000, 750000, 775000, 800000, 825000, 850000, 875000,
+ 900000, 925000, 950000, 975000, 1000000, 1025000, 1050000, 1075000,
+ 1100000, 1125000, 1150000, 1175000, 1200000, 1225000, 1250000, 1275000,
+ 1300000, 1325000, 1350000, 1375000, 1400000, 1425000, 1800000, 3300000,
+};
+
static const int pfuze3000_sw2lo[] = {
1500000, 1550000, 1600000, 1650000, 1700000, 1750000, 1800000, 1850000,
};
@@ -148,6 +167,9 @@ static const struct regulator_ops pfuze100_fixed_regulator_ops = {
};
static const struct regulator_ops pfuze100_sw_regulator_ops = {
+ .enable = regulator_enable_regmap,
+ .disable = regulator_disable_regmap,
+ .is_enabled = regulator_is_enabled_regmap,
.list_voltage = regulator_list_voltage_linear,
.set_voltage_sel = regulator_set_voltage_sel_regmap,
.get_voltage_sel = regulator_get_voltage_sel_regmap,
@@ -194,6 +216,11 @@ static const struct regulator_ops pfuze100_swb_regulator_ops = {
.uV_step = (step), \
.vsel_reg = (base) + PFUZE100_VOL_OFFSET, \
.vsel_mask = 0x3f, \
+ .enable_reg = (base) + PFUZE100_MODE_OFFSET, \
+ .enable_val = 0xc, \
+ .disable_val = 0x0, \
+ .enable_mask = 0xf, \
+ .enable_time = 500, \
}, \
.stby_reg = (base) + PFUZE100_STANDBY_OFFSET, \
.stby_mask = 0x3f, \
@@ -344,7 +371,7 @@ static struct pfuze_regulator pfuze200_regulators[] = {
};
static struct pfuze_regulator pfuze3000_regulators[] = {
- PFUZE100_SW_REG(PFUZE3000, SW1A, PFUZE100_SW1ABVOL, 700000, 1475000, 25000),
+ PFUZE100_SWB_REG(PFUZE3000, SW1A, PFUZE100_SW1ABVOL, 0x1f, pfuze3000_sw1a),
PFUZE100_SW_REG(PFUZE3000, SW1B, PFUZE100_SW1CVOL, 700000, 1475000, 25000),
PFUZE100_SWB_REG(PFUZE3000, SW2, PFUZE100_SW2VOL, 0x7, pfuze3000_sw2lo),
PFUZE3000_SW3_REG(PFUZE3000, SW3, PFUZE100_SW3AVOL, 900000, 1650000, 50000),
@@ -666,14 +693,95 @@ static int pfuze100_regulator_probe(struct i2c_client *client,
}
}
+
+ if (of_get_property(client->dev.of_node, "fsl,lpsr-mode", NULL))
+ pfuze_chip->need_restore = true;
+
+ return 0;
+}
+
+static int pfuze_reg_save_restore(struct pfuze_chip *pfuze_chip, int start,
+ int end, int index, bool save)
+{
+ int i, ret;
+
+ for (i = 0; i < end - start + 1; i++) {
+ if (save)
+ ret = regmap_read(pfuze_chip->regmap, start + i,
+ &pfuze_chip->reg_save_array[index + i]);
+ else
+ ret = regmap_write(pfuze_chip->regmap, start + i,
+ pfuze_chip->reg_save_array[index + i]);
+
+ if (ret)
+ return ret;
+ }
+
+ return index + i;
+}
+
+static int pfuze_suspend(struct device *dev)
+{
+ struct pfuze_chip *pfuze_chip = i2c_get_clientdata(to_i2c_client(dev));
+ int index = 0;
+
+ if (pfuze_chip->need_restore) {
+ /* 0x20~0x40 */
+ index = pfuze_reg_save_restore(pfuze_chip, 0x20, 0x40, index, true);
+ if (index < 0)
+ goto err_ret;
+ /* 0x66~0x71 */
+ index = pfuze_reg_save_restore(pfuze_chip, 0x66, 0x71, ++index, true);
+ if (index < 0)
+ goto err_ret;
+ /* 0x7f */
+ index = pfuze_reg_save_restore(pfuze_chip, 0x7f, 0x7f, ++index, true);
+ if (index < 0)
+ goto err_ret;
+ }
+
return 0;
+
+err_ret:
+ return index;
}
+static int pfuze_resume(struct device *dev)
+{
+ struct pfuze_chip *pfuze_chip = i2c_get_clientdata(to_i2c_client(dev));
+ int index = 0;
+
+ if (pfuze_chip->need_restore) {
+ /* 0x20~0x40 */
+ index = pfuze_reg_save_restore(pfuze_chip, 0x20, 0x40, index, false);
+ if (index < 0)
+ goto err_ret;
+ /* 0x66~0x71 */
+ index = pfuze_reg_save_restore(pfuze_chip, 0x66, 0x71, ++index, false);
+ if (index < 0)
+ goto err_ret;
+ /* 0x7f */
+ index = pfuze_reg_save_restore(pfuze_chip, 0x7f, 0x7f, ++index, false);
+ if (index < 0)
+ goto err_ret;
+ }
+
+ return 0;
+
+err_ret:
+ return index;
+}
+
+static const struct dev_pm_ops pfuze_pm_ops = {
+ SET_SYSTEM_SLEEP_PM_OPS(pfuze_suspend, pfuze_resume)
+};
+
static struct i2c_driver pfuze_driver = {
.id_table = pfuze_device_id,
.driver = {
.name = "pfuze100-regulator",
.of_match_table = pfuze_dt_ids,
+ .pm = &pfuze_pm_ops,
},
.probe = pfuze100_regulator_probe,
};
diff --git a/drivers/regulator/userspace-consumer.c b/drivers/regulator/userspace-consumer.c
index 765acc11c9c8..9d6c07976fa5 100644
--- a/drivers/regulator/userspace-consumer.c
+++ b/drivers/regulator/userspace-consumer.c
@@ -22,6 +22,8 @@
#include <linux/platform_device.h>
#include <linux/regulator/consumer.h>
#include <linux/regulator/userspace-consumer.h>
+#include <linux/of.h>
+#include <linux/regulator/of_regulator.h>
#include <linux/slab.h>
struct userspace_consumer_data {
@@ -105,6 +107,39 @@ static const struct attribute_group attr_group = {
.attrs = attributes,
};
+#if defined(CONFIG_OF)
+static struct regulator_userspace_consumer_data*
+ of_get_uc_config(struct device *dev, struct device_node *np)
+{
+ struct regulator_userspace_consumer_data *ucd;
+ int r;
+
+ ucd = devm_kzalloc(dev, sizeof(struct regulator_userspace_consumer_data)
+ + sizeof(struct regulator_bulk_data),
+ GFP_KERNEL);
+ if (ucd == NULL)
+ return NULL;
+
+ r = of_property_read_string(np, "uc-name", &ucd->name);
+ if (r) {
+ goto err;
+ }
+
+ ucd->num_supplies = 1;
+ ucd->supplies = (struct regulator_bulk_data *)&ucd[1];
+
+ r = of_property_read_string(np, "suck-supply", &ucd->supplies->supply);
+ if (r) {
+ goto err;
+ }
+ return ucd;
+
+err:
+ devm_kfree(dev, ucd);
+ return NULL;
+}
+#endif
+
static int regulator_userspace_consumer_probe(struct platform_device *pdev)
{
struct regulator_userspace_consumer_data *pdata;
@@ -112,6 +147,11 @@ static int regulator_userspace_consumer_probe(struct platform_device *pdev)
int ret;
pdata = dev_get_platdata(&pdev->dev);
+#if defined(CONFIG_OF)
+ if (!pdata && pdev->dev.of_node) {
+ pdata = of_get_uc_config(&pdev->dev, pdev->dev.of_node);
+ }
+#endif
if (!pdata)
return -EINVAL;
@@ -151,6 +191,8 @@ static int regulator_userspace_consumer_probe(struct platform_device *pdev)
drvdata->enabled = pdata->init_on;
platform_set_drvdata(pdev, drvdata);
+ dev_info(&pdev->dev, "attached: %s\n", drvdata->name);
+
return 0;
err_enable:
@@ -171,11 +213,22 @@ static int regulator_userspace_consumer_remove(struct platform_device *pdev)
return 0;
}
+#if defined(CONFIG_OF)
+static const struct of_device_id uc_of_match[] = {
+ { .compatible = "userspace_consumer", },
+ {},
+};
+#endif
+
static struct platform_driver regulator_userspace_consumer_driver = {
.probe = regulator_userspace_consumer_probe,
.remove = regulator_userspace_consumer_remove,
.driver = {
.name = "reg-userspace-consumer",
+ .owner = THIS_MODULE,
+#if defined(CONFIG_OF)
+ .of_match_table = of_match_ptr(uc_of_match),
+#endif
},
};
diff --git a/drivers/regulator/virtual.c b/drivers/regulator/virtual.c
index a6f1c7a9914f..115b9b350f76 100644
--- a/drivers/regulator/virtual.c
+++ b/drivers/regulator/virtual.c
@@ -15,8 +15,11 @@
#include <linux/mutex.h>
#include <linux/platform_device.h>
#include <linux/regulator/consumer.h>
+#include <linux/regulator/of_regulator.h>
#include <linux/slab.h>
#include <linux/module.h>
+#include <linux/of.h>
+
struct virtual_consumer_data {
struct mutex lock;
@@ -285,9 +288,22 @@ static const struct attribute_group regulator_virtual_attr_group = {
.attrs = regulator_virtual_attributes,
};
+static const char *of_get_virt_regulator_config(struct device *dev, struct device_node *np)
+{
+ const char *reg_id;
+ int r;
+
+ r = of_property_read_string(np, "virtual-supply", &reg_id);
+ if (r) {
+ return NULL;
+ }
+ return reg_id;
+}
+
static int regulator_virtual_probe(struct platform_device *pdev)
{
char *reg_id = dev_get_platdata(&pdev->dev);
+ struct device_node *np = pdev->dev.of_node;
struct virtual_consumer_data *drvdata;
int ret;
@@ -296,6 +312,15 @@ static int regulator_virtual_probe(struct platform_device *pdev)
if (drvdata == NULL)
return -ENOMEM;
+ if (np) {
+ reg_id = (char *)of_get_virt_regulator_config(&pdev->dev, np);
+ }
+
+ if (reg_id == NULL) {
+ dev_err(&pdev->dev, "Fail to get reg_id");
+ return -EINVAL;
+ }
+
mutex_init(&drvdata->lock);
drvdata->regulator = devm_regulator_get(&pdev->dev, reg_id);
@@ -318,6 +343,8 @@ static int regulator_virtual_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, drvdata);
+ dev_info(&pdev->dev, "attached: %s\n", reg_id);
+
return 0;
}
@@ -330,14 +357,25 @@ static int regulator_virtual_remove(struct platform_device *pdev)
if (drvdata->enabled)
regulator_disable(drvdata->regulator);
+ platform_set_drvdata(pdev, NULL);
+
return 0;
}
+#if defined(CONFIG_OF)
+static const struct of_device_id regulator_virtual_of_match[] = {
+ { .compatible = "regulator-virtual", },
+ {},
+};
+#endif
+
static struct platform_driver regulator_virtual_consumer_driver = {
.probe = regulator_virtual_probe,
.remove = regulator_virtual_remove,
.driver = {
.name = "reg-virt-consumer",
+ .owner = THIS_MODULE,
+ .of_match_table = of_match_ptr(regulator_virtual_of_match),
},
};
diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig
index e2baecbb9dd3..676e3e3f5440 100644
--- a/drivers/reset/Kconfig
+++ b/drivers/reset/Kconfig
@@ -54,6 +54,14 @@ config RESET_LANTIQ
help
This enables the reset controller driver for Lantiq / Intel XWAY SoCs.
+config RESET_GPIO
+ tristate "GPIO reset controller support"
+ default y
+ depends on GPIOLIB && OF
+ help
+ This driver provides support for reset lines that are controlled
+ directly by GPIOs.
+
config RESET_LPC18XX
bool "LPC18xx/43xx Reset Driver" if COMPILE_TEST
default ARCH_LPC18XX
diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile
index c1fd702ac57c..48e16f91915f 100644
--- a/drivers/reset/Makefile
+++ b/drivers/reset/Makefile
@@ -9,6 +9,7 @@ obj-$(CONFIG_RESET_BERLIN) += reset-berlin.o
obj-$(CONFIG_RESET_HSDK) += reset-hsdk.o
obj-$(CONFIG_RESET_IMX7) += reset-imx7.o
obj-$(CONFIG_RESET_LANTIQ) += reset-lantiq.o
+obj-$(CONFIG_RESET_GPIO) += gpio-reset.o
obj-$(CONFIG_RESET_LPC18XX) += reset-lpc18xx.o
obj-$(CONFIG_RESET_MESON) += reset-meson.o
obj-$(CONFIG_RESET_OXNAS) += reset-oxnas.o
diff --git a/drivers/reset/gpio-reset.c b/drivers/reset/gpio-reset.c
new file mode 100644
index 000000000000..49e63f8dd436
--- /dev/null
+++ b/drivers/reset/gpio-reset.c
@@ -0,0 +1,216 @@
+/*
+ * GPIO Reset Controller driver
+ *
+ * Copyright 2013 Philipp Zabel, Pengutronix
+ *
+ * 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/delay.h>
+#include <linux/err.h>
+#include <linux/gpio.h>
+#include <linux/module.h>
+#include <linux/of_gpio.h>
+#include <linux/platform_device.h>
+#include <linux/reset-controller.h>
+
+struct gpio_reset_data {
+ struct reset_controller_dev rcdev;
+ unsigned int gpio;
+ bool active_low;
+ s32 delay_us;
+ s32 post_delay_ms;
+};
+
+static void gpio_reset_set(struct reset_controller_dev *rcdev, int asserted)
+{
+ struct gpio_reset_data *drvdata = container_of(rcdev,
+ struct gpio_reset_data, rcdev);
+ int value = asserted;
+
+ if (drvdata->active_low)
+ value = !value;
+
+ gpio_set_value_cansleep(drvdata->gpio, value);
+}
+
+static int gpio_reset(struct reset_controller_dev *rcdev, unsigned long id)
+{
+ struct gpio_reset_data *drvdata = container_of(rcdev,
+ struct gpio_reset_data, rcdev);
+
+ if (drvdata->delay_us < 0)
+ return -ENOSYS;
+
+ gpio_reset_set(rcdev, 1);
+ udelay(drvdata->delay_us);
+ gpio_reset_set(rcdev, 0);
+
+ if (drvdata->post_delay_ms < 0)
+ return 0;
+
+ msleep(drvdata->post_delay_ms);
+ return 0;
+}
+
+static int gpio_reset_assert(struct reset_controller_dev *rcdev,
+ unsigned long id)
+{
+ gpio_reset_set(rcdev, 1);
+
+ return 0;
+}
+
+static int gpio_reset_deassert(struct reset_controller_dev *rcdev,
+ unsigned long id)
+{
+ gpio_reset_set(rcdev, 0);
+
+ return 0;
+}
+
+static struct reset_control_ops gpio_reset_ops = {
+ .reset = gpio_reset,
+ .assert = gpio_reset_assert,
+ .deassert = gpio_reset_deassert,
+};
+
+static int of_gpio_reset_xlate(struct reset_controller_dev *rcdev,
+ const struct of_phandle_args *reset_spec)
+{
+ if (WARN_ON(reset_spec->args_count != 0))
+ return -EINVAL;
+
+ return 0;
+}
+
+static int gpio_reset_probe(struct platform_device *pdev)
+{
+ struct device_node *np = pdev->dev.of_node;
+ struct gpio_reset_data *drvdata;
+ enum of_gpio_flags flags;
+ unsigned long gpio_flags;
+ bool initially_in_reset;
+ int ret;
+
+ drvdata = devm_kzalloc(&pdev->dev, sizeof(*drvdata), GFP_KERNEL);
+ if (drvdata == NULL)
+ return -ENOMEM;
+
+ if (of_gpio_named_count(np, "reset-gpios") != 1) {
+ dev_err(&pdev->dev,
+ "reset-gpios property missing, or not a single gpio\n");
+ return -EINVAL;
+ }
+
+ drvdata->gpio = of_get_named_gpio_flags(np, "reset-gpios", 0, &flags);
+ if (drvdata->gpio == -EPROBE_DEFER) {
+ return drvdata->gpio;
+ } else if (!gpio_is_valid(drvdata->gpio)) {
+ dev_err(&pdev->dev, "invalid reset gpio: %d\n", drvdata->gpio);
+ return drvdata->gpio;
+ }
+
+ drvdata->active_low = flags & OF_GPIO_ACTIVE_LOW;
+
+ ret = of_property_read_u32(np, "reset-delay-us", &drvdata->delay_us);
+ if (ret < 0)
+ drvdata->delay_us = -1;
+ else if (drvdata->delay_us < 0)
+ dev_warn(&pdev->dev, "reset delay too high\n");
+
+ /* It is optional.
+ * Some devices need some milliseconds to wait after reset.
+ */
+ ret = of_property_read_u32(np, "reset-post-delay-ms", &drvdata->post_delay_ms);
+ if (ret < 0)
+ drvdata->post_delay_ms = -1;
+
+ initially_in_reset = of_property_read_bool(np, "initially-in-reset");
+ if (drvdata->active_low ^ initially_in_reset)
+ gpio_flags = GPIOF_OUT_INIT_HIGH;
+ else
+ gpio_flags = GPIOF_OUT_INIT_LOW;
+
+ ret = devm_gpio_request_one(&pdev->dev, drvdata->gpio, gpio_flags, NULL);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "failed to request gpio %d: %d\n",
+ drvdata->gpio, ret);
+ return ret;
+ }
+
+ platform_set_drvdata(pdev, drvdata);
+
+ drvdata->rcdev.of_node = np;
+ drvdata->rcdev.owner = THIS_MODULE;
+ drvdata->rcdev.nr_resets = 1;
+ drvdata->rcdev.ops = &gpio_reset_ops;
+ drvdata->rcdev.of_xlate = of_gpio_reset_xlate;
+ reset_controller_register(&drvdata->rcdev);
+
+ return 0;
+}
+
+static int gpio_reset_remove(struct platform_device *pdev)
+{
+ struct gpio_reset_data *drvdata = platform_get_drvdata(pdev);
+
+ reset_controller_unregister(&drvdata->rcdev);
+
+ return 0;
+}
+
+static struct of_device_id gpio_reset_dt_ids[] = {
+ { .compatible = "gpio-reset" },
+ { }
+};
+
+#ifdef CONFIG_PM_SLEEP
+static int gpio_reset_suspend(struct device *dev)
+{
+ pinctrl_pm_select_sleep_state(dev);
+
+ return 0;
+}
+static int gpio_reset_resume(struct device *dev)
+{
+ pinctrl_pm_select_default_state(dev);
+
+ return 0;
+}
+#endif
+
+static const struct dev_pm_ops gpio_reset_pm_ops = {
+ SET_LATE_SYSTEM_SLEEP_PM_OPS(gpio_reset_suspend, gpio_reset_resume)
+};
+
+static struct platform_driver gpio_reset_driver = {
+ .probe = gpio_reset_probe,
+ .remove = gpio_reset_remove,
+ .driver = {
+ .name = "gpio-reset",
+ .owner = THIS_MODULE,
+ .of_match_table = of_match_ptr(gpio_reset_dt_ids),
+ .pm = &gpio_reset_pm_ops,
+ },
+};
+
+static int __init gpio_reset_init(void)
+{
+ return platform_driver_register(&gpio_reset_driver);
+}
+arch_initcall(gpio_reset_init);
+
+static void __exit gpio_reset_exit(void)
+{
+ platform_driver_unregister(&gpio_reset_driver);
+}
+module_exit(gpio_reset_exit);
+
+MODULE_AUTHOR("Philipp Zabel <p.zabel@pengutronix.de>");
+MODULE_DESCRIPTION("gpio reset controller");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:gpio-reset");
+MODULE_DEVICE_TABLE(of, gpio_reset_dt_ids);
diff --git a/drivers/rpmsg/Kconfig b/drivers/rpmsg/Kconfig
index 0fe6eac46512..3979e01368f6 100644
--- a/drivers/rpmsg/Kconfig
+++ b/drivers/rpmsg/Kconfig
@@ -51,4 +51,19 @@ config RPMSG_VIRTIO
select RPMSG
select VIRTIO
+config HAVE_IMX_RPMSG
+ bool "IMX RPMSG driver on the AMP SOCs"
+ select RPMSG
+ select RPMSG_VIRTIO
+
+config IMX_RPMSG_PINGPONG
+ tristate "IMX RPMSG pingpong driver -- loadable modules only"
+ default m
+ depends on RPMSG && m
+
+config IMX_RPMSG_TTY
+ tristate "IMX RPMSG tty driver -- loadable modules only"
+ default m
+ depends on RPMSG && m
+
endmenu
diff --git a/drivers/rpmsg/Makefile b/drivers/rpmsg/Makefile
index 9aa859502d27..3a1f0e97e3c0 100644
--- a/drivers/rpmsg/Makefile
+++ b/drivers/rpmsg/Makefile
@@ -6,3 +6,6 @@ obj-$(CONFIG_RPMSG_QCOM_GLINK_NATIVE) += qcom_glink_native.o
obj-$(CONFIG_RPMSG_QCOM_GLINK_SMEM) += qcom_glink_smem.o
obj-$(CONFIG_RPMSG_QCOM_SMD) += qcom_smd.o
obj-$(CONFIG_RPMSG_VIRTIO) += virtio_rpmsg_bus.o
+obj-$(CONFIG_HAVE_IMX_RPMSG) += imx_rpmsg.o
+obj-$(CONFIG_IMX_RPMSG_PINGPONG) += imx_rpmsg_pingpong.o
+obj-$(CONFIG_IMX_RPMSG_TTY) += imx_rpmsg_tty.o
diff --git a/drivers/rpmsg/imx_rpmsg.c b/drivers/rpmsg/imx_rpmsg.c
new file mode 100644
index 000000000000..4e557d59b438
--- /dev/null
+++ b/drivers/rpmsg/imx_rpmsg.c
@@ -0,0 +1,838 @@
+/*
+ * Copyright (C) 2015 Freescale Semiconductor, Inc.
+ * Copyright 2017-2018 NXP
+ *
+ * derived from the omap-rpmsg implementation.
+ *
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/notifier.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/of_irq.h>
+#include <linux/of_reserved_mem.h>
+#include <linux/platform_device.h>
+#include <linux/rpmsg.h>
+#include <linux/slab.h>
+#include <linux/virtio.h>
+#include <linux/virtio_config.h>
+#include <linux/virtio_ids.h>
+#include <linux/virtio_ring.h>
+#include <linux/imx_rpmsg.h>
+#include <linux/mx8_mu.h>
+#ifdef CONFIG_ARCH_MXC_ARM64
+#include <soc/imx8/sc/sci.h>
+#include <soc/imx8/sc/svc/irq/api.h>
+#endif
+#include "rpmsg_internal.h"
+
+enum imx_rpmsg_variants {
+ IMX6SX,
+ IMX7D,
+ IMX7ULP,
+ IMX8MQ,
+ IMX8QXP,
+ IMX8QM,
+};
+
+struct imx_virdev {
+ struct virtio_device vdev;
+ unsigned int vring[2];
+ struct virtqueue *vq[2];
+ int base_vq_id;
+ int num_of_vqs;
+ u32 vproc_id;
+ struct notifier_block nb;
+};
+
+struct imx_rpmsg_vproc {
+ char *rproc_name;
+ struct mutex lock;
+ struct clk *mu_clk;
+ enum imx_rpmsg_variants variant;
+ int vdev_nums;
+ int first_notify;
+ u32 none_suspend;
+#define MAX_VDEV_NUMS 8
+ struct imx_virdev *ivdev[MAX_VDEV_NUMS];
+ void __iomem *mu_base;
+ struct delayed_work rpmsg_work;
+ struct blocking_notifier_head notifier;
+#define MAX_NUM 10 /* enlarge it if overflow happen */
+ u32 m4_message[MAX_NUM];
+ u32 in_idx;
+ u32 out_idx;
+ u32 core_id;
+ u32 mub_partition;
+ struct notifier_block *pnotifier;
+ spinlock_t mu_lock;
+ struct platform_device *pdev;
+};
+
+/*
+ * For now, allocate 256 buffers of 512 bytes for each side. each buffer
+ * will then have 16B for the msg header and 496B for the payload.
+ * This will require a total space of 256KB for the buffers themselves, and
+ * 3 pages for every vring (the size of the vring depends on the number of
+ * buffers it supports).
+ */
+#define RPMSG_NUM_BUFS (512)
+#define RPMSG_BUF_SIZE (512)
+#define RPMSG_BUFS_SPACE (RPMSG_NUM_BUFS * RPMSG_BUF_SIZE)
+
+/*
+ * The alignment between the consumer and producer parts of the vring.
+ * Note: this is part of the "wire" protocol. If you change this, you need
+ * to update your BIOS image as well
+ */
+#define RPMSG_VRING_ALIGN (4096)
+
+/* With 256 buffers, our vring will occupy 3 pages */
+#define RPMSG_RING_SIZE ((DIV_ROUND_UP(vring_size(RPMSG_NUM_BUFS / 2, \
+ RPMSG_VRING_ALIGN), PAGE_SIZE)) * PAGE_SIZE)
+
+#define to_imx_virdev(vd) container_of(vd, struct imx_virdev, vdev)
+
+/* Flag 0 of ASR, 1 indicated that remote processor is ready */
+#define REMOTE_IS_READY BIT(0)
+/*
+ * The time consumption by remote ready is less than 1ms in the
+ * evaluation. Set the max wait timeout as 50ms here.
+ */
+#define REMOTE_READY_WAIT_MAX_RETRIES 500
+
+struct imx_rpmsg_vq_info {
+ __u16 num; /* number of entries in the virtio_ring */
+ __u16 vq_id; /* a globaly unique index of this virtqueue */
+ void *addr; /* address where we mapped the virtio ring */
+ struct imx_rpmsg_vproc *rpdev;
+};
+
+static int imx_rpmsg_partion_notify0(struct notifier_block *nb,
+ unsigned long event, void *group);
+static int imx_rpmsg_partion_notify1(struct notifier_block *nb,
+ unsigned long event, void *group);
+
+static struct imx_rpmsg_vproc imx_rpmsg_vprocs[];
+
+static u64 imx_rpmsg_get_features(struct virtio_device *vdev)
+{
+ /* VIRTIO_RPMSG_F_NS has been made private */
+ return 1 << 0;
+}
+
+static int imx_rpmsg_finalize_features(struct virtio_device *vdev)
+{
+ /* Give virtio_ring a chance to accept features */
+ vring_transport_features(vdev);
+ return 0;
+}
+
+/* kick the remote processor, and let it know which virtqueue to poke at */
+static bool imx_rpmsg_notify(struct virtqueue *vq)
+{
+ unsigned int mu_rpmsg = 0;
+ struct imx_rpmsg_vq_info *rpvq = vq->priv;
+
+ mu_rpmsg = rpvq->vq_id << 16;
+ mutex_lock(&rpvq->rpdev->lock);
+ /*
+ * Send the index of the triggered virtqueue as the mu payload.
+ * Use the timeout MU send message here.
+ * Since that M4 core may not be loaded, and the first MSG may
+ * not be handled by M4 when multi-vdev is enabled.
+ * To make sure that the message wound't be discarded when M4
+ * is running normally or in the suspend mode. Only use
+ * the timeout mechanism by the first notify when the vdev is
+ * registered.
+ * ~14ms is required by M4 ready to process the MU message from
+ * cold boot. Set the wait time 20ms here.
+ */
+ if (unlikely(rpvq->rpdev->first_notify > 0)) {
+ rpvq->rpdev->first_notify--;
+ MU_SendMessageTimeout(rpvq->rpdev->mu_base, 1, mu_rpmsg, 2000);
+ } else {
+ MU_SendMessage(rpvq->rpdev->mu_base, 1, mu_rpmsg);
+ }
+ mutex_unlock(&rpvq->rpdev->lock);
+
+ return true;
+}
+
+static int imx_mu_rpmsg_callback(struct notifier_block *this,
+ unsigned long index, void *data)
+{
+ u32 mu_msg = (phys_addr_t) data;
+ struct imx_virdev *virdev;
+
+ virdev = container_of(this, struct imx_virdev, nb);
+
+ pr_debug("%s mu_msg: 0x%x\n", __func__, mu_msg);
+ /* ignore vq indices which are clearly not for us */
+ mu_msg = mu_msg >> 16;
+ if (mu_msg < virdev->base_vq_id || mu_msg > virdev->base_vq_id + 1) {
+ pr_debug("mu_msg: 0x%x is invalid\n", mu_msg);
+ return NOTIFY_DONE;
+ }
+
+ mu_msg -= virdev->base_vq_id;
+
+ /*
+ * Currently both PENDING_MSG and explicit-virtqueue-index
+ * messaging are supported.
+ * Whatever approach is taken, at this point 'mu_msg' contains
+ * the index of the vring which was just triggered.
+ */
+ if (mu_msg < virdev->num_of_vqs)
+ vring_interrupt(mu_msg, virdev->vq[mu_msg]);
+
+ return NOTIFY_DONE;
+}
+
+static int imx_mu_rpmsg_register_nb(struct imx_rpmsg_vproc *rpdev,
+ struct notifier_block *nb)
+{
+ if ((rpdev == NULL) || (nb == NULL))
+ return -EINVAL;
+
+ blocking_notifier_chain_register(&(rpdev->notifier), nb);
+
+ return 0;
+}
+
+static int imx_mu_rpmsg_unregister_nb(struct imx_rpmsg_vproc *rpdev,
+ struct notifier_block *nb)
+{
+ if ((rpdev == NULL) || (nb == NULL))
+ return -EINVAL;
+
+ blocking_notifier_chain_unregister(&(rpdev->notifier), nb);
+
+ return 0;
+}
+
+static struct virtqueue *rp_find_vq(struct virtio_device *vdev,
+ unsigned int index,
+ void (*callback)(struct virtqueue *vq),
+ const char *name,
+ bool ctx)
+{
+ struct imx_virdev *virdev = to_imx_virdev(vdev);
+ int id = virdev->vproc_id;
+ struct imx_rpmsg_vproc *rpdev = &imx_rpmsg_vprocs[id];
+ struct imx_rpmsg_vq_info *rpvq;
+ struct virtqueue *vq;
+ int err;
+
+ rpvq = kmalloc(sizeof(*rpvq), GFP_KERNEL);
+ if (!rpvq)
+ return ERR_PTR(-ENOMEM);
+
+ /* ioremap'ing normal memory, so we cast away sparse's complaints */
+ rpvq->addr = (__force void *) ioremap_nocache(virdev->vring[index],
+ RPMSG_RING_SIZE);
+ if (!rpvq->addr) {
+ err = -ENOMEM;
+ goto free_rpvq;
+ }
+
+ memset_io(rpvq->addr, 0, RPMSG_RING_SIZE);
+
+ pr_debug("vring%d: phys 0x%x, virt 0x%p\n", index, virdev->vring[index],
+ rpvq->addr);
+
+ vq = vring_new_virtqueue(index, RPMSG_NUM_BUFS / 2, RPMSG_VRING_ALIGN,
+ vdev, true, ctx,
+ rpvq->addr,
+ imx_rpmsg_notify, callback,
+ name);
+ if (!vq) {
+ pr_err("vring_new_virtqueue failed\n");
+ err = -ENOMEM;
+ goto unmap_vring;
+ }
+
+ virdev->vq[index] = vq;
+ vq->priv = rpvq;
+ /* system-wide unique id for this virtqueue */
+ rpvq->vq_id = virdev->base_vq_id + index;
+ rpvq->rpdev = rpdev;
+ mutex_init(&rpdev->lock);
+
+ return vq;
+
+unmap_vring:
+ /* iounmap normal memory, so make sparse happy */
+ iounmap((__force void __iomem *) rpvq->addr);
+free_rpvq:
+ kfree(rpvq);
+ return ERR_PTR(err);
+}
+
+static void imx_rpmsg_del_vqs(struct virtio_device *vdev)
+{
+ struct virtqueue *vq, *n;
+ struct imx_virdev *virdev = to_imx_virdev(vdev);
+ int id = virdev->vproc_id;
+ struct imx_rpmsg_vproc *rpdev = &imx_rpmsg_vprocs[id];
+
+ list_for_each_entry_safe(vq, n, &vdev->vqs, list) {
+ struct imx_rpmsg_vq_info *rpvq = vq->priv;
+
+ iounmap(rpvq->addr);
+ vring_del_virtqueue(vq);
+ kfree(rpvq);
+ }
+
+ if (&virdev->nb)
+ imx_mu_rpmsg_unregister_nb(rpdev, &virdev->nb);
+}
+
+static int imx_rpmsg_find_vqs(struct virtio_device *vdev, unsigned int nvqs,
+ struct virtqueue *vqs[],
+ vq_callback_t *callbacks[],
+ const char * const names[],
+ const bool *ctx,
+ struct irq_affinity *desc)
+{
+ struct imx_virdev *virdev = to_imx_virdev(vdev);
+ int id = virdev->vproc_id;
+ struct imx_rpmsg_vproc *rpdev = &imx_rpmsg_vprocs[id];
+ int i, err;
+
+ /* we maintain two virtqueues per remote processor (for RX and TX) */
+ if (nvqs != 2)
+ return -EINVAL;
+
+ for (i = 0; i < nvqs; ++i) {
+ vqs[i] = rp_find_vq(vdev, i, callbacks[i], names[i],
+ ctx ? ctx[i] : false);
+ if (IS_ERR(vqs[i])) {
+ err = PTR_ERR(vqs[i]);
+ goto error;
+ }
+ }
+
+ virdev->num_of_vqs = nvqs;
+
+ virdev->nb.notifier_call = imx_mu_rpmsg_callback;
+ imx_mu_rpmsg_register_nb(rpdev, &virdev->nb);
+
+ return 0;
+
+error:
+ imx_rpmsg_del_vqs(vdev);
+ return err;
+}
+
+static void imx_rpmsg_reset(struct virtio_device *vdev)
+{
+ dev_dbg(&vdev->dev, "reset !\n");
+}
+
+static u8 imx_rpmsg_get_status(struct virtio_device *vdev)
+{
+ return 0;
+}
+
+static void imx_rpmsg_set_status(struct virtio_device *vdev, u8 status)
+{
+ dev_dbg(&vdev->dev, "%s new status: %d\n", __func__, status);
+}
+
+static void imx_rpmsg_vproc_release(struct device *dev)
+{
+ /* this handler is provided so driver core doesn't yell at us */
+}
+
+static struct virtio_config_ops imx_rpmsg_config_ops = {
+ .get_features = imx_rpmsg_get_features,
+ .finalize_features = imx_rpmsg_finalize_features,
+ .find_vqs = imx_rpmsg_find_vqs,
+ .del_vqs = imx_rpmsg_del_vqs,
+ .reset = imx_rpmsg_reset,
+ .set_status = imx_rpmsg_set_status,
+ .get_status = imx_rpmsg_get_status,
+};
+
+static struct notifier_block imx_rpmsg_partion_notifier[] = {
+ {
+ .notifier_call = imx_rpmsg_partion_notify0,
+ },
+ {
+ .notifier_call = imx_rpmsg_partion_notify1,
+ },
+};
+
+static struct imx_rpmsg_vproc imx_rpmsg_vprocs[] = {
+ {
+ .rproc_name = "m4",
+ .pnotifier = &imx_rpmsg_partion_notifier[0],
+ },
+ {
+ .rproc_name = "m4",
+ .pnotifier = &imx_rpmsg_partion_notifier[1],
+ },
+};
+
+static const struct of_device_id imx_rpmsg_dt_ids[] = {
+ { .compatible = "fsl,imx6sx-rpmsg", .data = (void *)IMX6SX, },
+ { .compatible = "fsl,imx7d-rpmsg", .data = (void *)IMX7D, },
+ { .compatible = "fsl,imx7ulp-rpmsg", .data = (void *)IMX7ULP, },
+ { .compatible = "fsl,imx8mq-rpmsg", .data = (void *)IMX8MQ, },
+ { .compatible = "fsl,imx8qxp-rpmsg", .data = (void *)IMX8QXP, },
+ { .compatible = "fsl,imx8qm-rpmsg", .data = (void *)IMX8QM, },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, imx_rpmsg_dt_ids);
+
+static int set_vring_phy_buf(struct platform_device *pdev,
+ struct imx_rpmsg_vproc *rpdev, int vdev_nums)
+{
+ struct resource *res;
+ resource_size_t size;
+ unsigned int start, end;
+ int i, ret = 0;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (res) {
+ size = resource_size(res);
+ start = res->start;
+ end = res->start + size;
+ for (i = 0; i < vdev_nums; i++) {
+ rpdev->ivdev[i] = kzalloc(sizeof(struct imx_virdev),
+ GFP_KERNEL);
+ if (!rpdev->ivdev[i])
+ return -ENOMEM;
+
+ rpdev->ivdev[i]->vring[0] = start;
+ rpdev->ivdev[i]->vring[1] = start +
+ 0x8000;
+ start += 0x10000;
+ if (start > end) {
+ pr_err("Too small memory size %x!\n",
+ (u32)size);
+ ret = -EINVAL;
+ break;
+ }
+ }
+ } else {
+ return -ENOMEM;
+ }
+
+ return ret;
+}
+
+static void rpmsg_work_handler(struct work_struct *work)
+{
+ u32 message;
+ unsigned long flags;
+ struct delayed_work *dwork = to_delayed_work(work);
+ struct imx_rpmsg_vproc *rpdev = container_of(dwork,
+ struct imx_rpmsg_vproc, rpmsg_work);
+
+ spin_lock_irqsave(&rpdev->mu_lock, flags);
+ /* handle all incoming mu message */
+ while (rpdev->in_idx != rpdev->out_idx) {
+ message = rpdev->m4_message[rpdev->out_idx % MAX_NUM];
+ spin_unlock_irqrestore(&rpdev->mu_lock, flags);
+
+ blocking_notifier_call_chain(&(rpdev->notifier), 4,
+ (void *)(phys_addr_t)message);
+
+ spin_lock_irqsave(&rpdev->mu_lock, flags);
+ rpdev->m4_message[rpdev->out_idx % MAX_NUM] = 0;
+ rpdev->out_idx++;
+ }
+ spin_unlock_irqrestore(&rpdev->mu_lock, flags);
+}
+
+static irqreturn_t imx_mu_rpmsg_isr(int irq, void *param)
+{
+ u32 irqs, message;
+ unsigned long flags;
+ struct imx_rpmsg_vproc *rpdev = (struct imx_rpmsg_vproc *)param;
+
+ irqs = MU_ReadStatus(rpdev->mu_base);
+
+ /* RPMSG */
+ if (irqs & (1 << 26)) {
+ spin_lock_irqsave(&rpdev->mu_lock, flags);
+ /* get message from receive buffer */
+ MU_ReceiveMsg(rpdev->mu_base, 1, &message);
+ rpdev->m4_message[rpdev->in_idx % MAX_NUM] = message;
+ rpdev->in_idx++;
+ /*
+ * Too many mu message not be handled in timely, can enlarge
+ * MAX_NUM
+ */
+ if (rpdev->in_idx == rpdev->out_idx) {
+ spin_unlock_irqrestore(&rpdev->mu_lock, flags);
+ pr_err("MU overflow!\n");
+ return IRQ_HANDLED;
+ }
+ spin_unlock_irqrestore(&rpdev->mu_lock, flags);
+
+ schedule_delayed_work(&(rpdev->rpmsg_work), 0);
+ }
+
+ return IRQ_HANDLED;
+}
+
+static int imx_rpmsg_mu_init(struct imx_rpmsg_vproc *rpdev)
+{
+ int ret = 0;
+
+ /*
+ * bit26 is used by rpmsg channels.
+ * bit0 of MX7ULP_MU_CR used to let m4 to know MU is ready now
+ */
+ MU_Init(rpdev->mu_base);
+ if (rpdev->variant == IMX7ULP) {
+ MU_EnableRxFullInt(rpdev->mu_base, 1);
+ ret = MU_SetFn(rpdev->mu_base, 1);
+ } else {
+ MU_EnableRxFullInt(rpdev->mu_base, 1);
+ }
+
+ return ret;
+}
+
+void imx_rpmsg_restore(struct imx_rpmsg_vproc *rpdev)
+{
+ int i;
+ u32 flags = 0;
+ int vdev_nums = rpdev->vdev_nums;
+
+ for (i = 0; i < vdev_nums; i++) {
+ unregister_virtio_device(&rpdev->ivdev[i]->vdev);
+ kfree(rpdev->ivdev[i]);
+ }
+
+ /* Make a double check that remote processor is ready or not */
+ for (i = 0; i < REMOTE_READY_WAIT_MAX_RETRIES; i++) {
+ if (rpdev->none_suspend)
+ flags = MU_ReadStatus(rpdev->mu_base);
+ if (flags & REMOTE_IS_READY)
+ break;
+ usleep_range(100, 200);
+ }
+ if (unlikely((flags & REMOTE_IS_READY) == 0)) {
+ pr_err("Wait for remote ready timeout, assume it's dead.\n");
+ /*
+ * In order to make the codes to be robust and back compatible.
+ * When wait remote ready timeout, use the MU_SendMessageTimeout
+ * to send the first kick-off message when register the vdev.
+ */
+ rpdev->first_notify = rpdev->vdev_nums;
+ }
+
+ /* Allocate and setup ivdev again to register virtio devices */
+ if (set_vring_phy_buf(rpdev->pdev, rpdev, rpdev->vdev_nums))
+ pr_err("No vring buffer.\n");
+
+ for (i = 0; i < vdev_nums; i++) {
+ rpdev->ivdev[i]->vdev.id.device = VIRTIO_ID_RPMSG;
+ rpdev->ivdev[i]->vdev.config = &imx_rpmsg_config_ops;
+ rpdev->ivdev[i]->vdev.dev.parent = &rpdev->pdev->dev;
+ rpdev->ivdev[i]->vdev.dev.release = imx_rpmsg_vproc_release;
+ rpdev->ivdev[i]->base_vq_id = i * 2;
+ rpdev->ivdev[i]->vproc_id = rpdev->core_id;
+
+ if (register_virtio_device(&rpdev->ivdev[i]->vdev))
+ pr_err("%s failed to register rpdev.\n", __func__);
+ }
+}
+
+static int imx_rpmsg_partion_notify0(struct notifier_block *nb,
+ unsigned long event, void *group)
+{
+#ifdef CONFIG_ARCH_MXC_ARM64
+ struct imx_rpmsg_vproc *rpdev = &imx_rpmsg_vprocs[0];
+
+ /* Ignore other irqs */
+ if (!((event & BIT(rpdev->mub_partition)) &&
+ (*(sc_irq_group_t *)group == SC_IRQ_GROUP_REBOOTED)))
+ return 0;
+
+ imx_rpmsg_restore(rpdev);
+ pr_info("Patition%d reset!\n", rpdev->mub_partition);
+#endif
+ return 0;
+}
+
+static int imx_rpmsg_partion_notify1(struct notifier_block *nb,
+ unsigned long event, void *group)
+{
+#ifdef CONFIG_ARCH_MXC_ARM64
+ struct imx_rpmsg_vproc *rpdev = &imx_rpmsg_vprocs[1];
+
+ /* Ignore other irqs */
+ if (!((event & BIT(rpdev->mub_partition)) &&
+ (*(sc_irq_group_t *)group == SC_IRQ_GROUP_REBOOTED)))
+ return 0;
+
+ imx_rpmsg_restore(rpdev);
+ pr_info("Patition%d reset!\n", rpdev->mub_partition);
+#endif
+ return 0;
+}
+
+static int imx_rpmsg_probe(struct platform_device *pdev)
+{
+ int core_id, j, ret = 0;
+ u32 irq;
+ struct device_node *np_mu;
+ struct device *dev = &pdev->dev;
+ struct device_node *np = pdev->dev.of_node;
+ struct imx_rpmsg_vproc *rpdev;
+
+ if (of_property_read_u32(np, "multi-core-id", &core_id))
+ core_id = 0;
+ rpdev = &imx_rpmsg_vprocs[core_id];
+ rpdev->core_id = core_id;
+ rpdev->variant = (enum imx_rpmsg_variants)of_device_get_match_data(dev);
+
+ /* Initialize the mu unit used by rpmsg */
+ if (rpdev->core_id == 1)
+ np_mu = of_find_compatible_node(NULL, NULL,
+ "fsl,imx-mu-rpmsg1");
+ else
+ np_mu = of_find_compatible_node(NULL, NULL, "fsl,imx6sx-mu");
+ if (!np_mu) {
+ pr_info("Cannot find MU-RPMSG entry in device tree\n");
+ return -EINVAL;
+ }
+ rpdev->mu_base = of_iomap(np_mu, 0);
+ WARN_ON(!rpdev->mu_base);
+
+ spin_lock_init(&rpdev->mu_lock);
+
+ if (rpdev->variant == IMX7ULP)
+ irq = of_irq_get(np_mu, 1);
+ else
+ irq = of_irq_get(np_mu, 0);
+
+ ret = request_irq(irq, imx_mu_rpmsg_isr,
+ IRQF_EARLY_RESUME | IRQF_SHARED,
+ "imx-mu-rpmsg", rpdev);
+ if (ret) {
+ pr_err("%s: register interrupt %d failed, rc %d\n",
+ __func__, irq, ret);
+ return ret;
+ }
+
+ if (rpdev->variant == IMX6SX || rpdev->variant == IMX7ULP) {
+ rpdev->mu_clk = NULL;
+ } else {
+ rpdev->mu_clk = of_clk_get(np_mu, 0);
+ if (IS_ERR(rpdev->mu_clk)) {
+ pr_err("mu clock source missing or invalid\n");
+ return PTR_ERR(rpdev->mu_clk);
+ }
+ ret = clk_prepare_enable(rpdev->mu_clk);
+ if (ret) {
+ pr_err("unable to enable mu clock\n");
+ return ret;
+ }
+ }
+
+ ret = imx_rpmsg_mu_init(rpdev);
+ if (ret) {
+ pr_err("unable to initialize mu module.\n");
+ goto vdev_err_out;
+ }
+ INIT_DELAYED_WORK(&(rpdev->rpmsg_work), rpmsg_work_handler);
+ BLOCKING_INIT_NOTIFIER_HEAD(&(rpdev->notifier));
+
+ pr_info("MU is ready for cross core communication!\n");
+
+ ret = of_property_read_u32(np, "vdev-nums", &rpdev->vdev_nums);
+ if (ret)
+ rpdev->vdev_nums = 1;
+ if (rpdev->vdev_nums > MAX_VDEV_NUMS) {
+ pr_err("vdev-nums exceed the max %d\n", MAX_VDEV_NUMS);
+ ret = -EINVAL;
+ goto vdev_err_out;
+ }
+ rpdev->first_notify = rpdev->vdev_nums;
+
+ if (!strcmp(rpdev->rproc_name, "m4")) {
+ ret = set_vring_phy_buf(pdev, rpdev,
+ rpdev->vdev_nums);
+ if (ret) {
+ pr_err("No vring buffer.\n");
+ ret = -ENOMEM;
+ goto vdev_err_out;
+ }
+ } else {
+ pr_err("No remote m4 processor.\n");
+ ret = -ENODEV;
+ goto vdev_err_out;
+ }
+
+
+ if (rpdev->variant == IMX8QM || rpdev->variant == IMX8QXP) {
+ if (of_reserved_mem_device_init(&pdev->dev)) {
+ dev_err(&pdev->dev,
+ "dev doesn't have specific DMA pool.\n");
+ ret = -ENOMEM;
+ goto vdev_err_out;
+ }
+ }
+ for (j = 0; j < rpdev->vdev_nums; j++) {
+ pr_debug("%s rpdev%d vdev%d: vring0 0x%x, vring1 0x%x\n",
+ __func__, rpdev->core_id, rpdev->vdev_nums,
+ rpdev->ivdev[j]->vring[0],
+ rpdev->ivdev[j]->vring[1]);
+ rpdev->ivdev[j]->vdev.id.device = VIRTIO_ID_RPMSG;
+ rpdev->ivdev[j]->vdev.config = &imx_rpmsg_config_ops;
+ rpdev->pdev = pdev;
+ rpdev->ivdev[j]->vdev.dev.parent = &pdev->dev;
+ rpdev->ivdev[j]->vdev.dev.release = imx_rpmsg_vproc_release;
+ rpdev->ivdev[j]->base_vq_id = j * 2;
+ rpdev->ivdev[j]->vproc_id = rpdev->core_id;
+
+ ret = register_virtio_device(&rpdev->ivdev[j]->vdev);
+ if (ret) {
+ pr_err("%s failed to register rpdev: %d\n",
+ __func__, ret);
+ goto err_out;
+ }
+ }
+
+ platform_set_drvdata(pdev, rpdev);
+
+#ifdef CONFIG_ARCH_MXC_ARM64
+ if (rpdev->variant == IMX8QXP || rpdev->variant == IMX8QM) {
+ uint32_t mu_id;
+ sc_err_t sciErr;
+ static sc_ipc_t mu_ipchandle;
+ uint32_t irq_status;
+
+ /* Get muB partition id and enable irq in SCFW then */
+ if (of_property_read_u32(np, "mub-partition",
+ &rpdev->mub_partition))
+ rpdev->mub_partition = 3; /* default partition 3 */
+
+ sciErr = sc_ipc_getMuID(&mu_id);
+ if (sciErr != SC_ERR_NONE) {
+ pr_err("can't obtain mu id: %d\n", sciErr);
+ return sciErr;
+ }
+
+ sciErr = sc_ipc_open(&mu_ipchandle, mu_id);
+
+ if (sciErr != SC_ERR_NONE) {
+ pr_err("can't get ipc handler: %d\n", sciErr);
+ return sciErr;
+ };
+
+ /* Clear any pending partition reset interrupt during
+ * rpmsg probe.
+ */
+ sciErr = sc_irq_status(mu_ipchandle, SC_R_MU_1A,
+ SC_IRQ_GROUP_REBOOTED,
+ &irq_status);
+ if (sciErr != SC_ERR_NONE)
+ pr_info("Cannot get partition reboot interrupt status\n");
+
+ /* Request for the partition reset interrupt. */
+ sciErr = sc_irq_enable(mu_ipchandle, SC_R_MU_1A,
+ SC_IRQ_GROUP_REBOOTED,
+ BIT(rpdev->mub_partition), true);
+ if (sciErr)
+ pr_info("Cannot request partition reset interrupt\n");
+
+ return register_scu_notifier(rpdev->pnotifier);
+
+ }
+#endif
+
+ return ret;
+
+err_out:
+ if (rpdev->variant == IMX8QM || rpdev->variant == IMX8QXP)
+ of_reserved_mem_device_release(&pdev->dev);
+vdev_err_out:
+ if (rpdev->mu_clk)
+ clk_disable_unprepare(rpdev->mu_clk);
+ return ret;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int imx_rpmsg_noirq_suspend(struct device *dev)
+{
+ struct imx_rpmsg_vproc *rpdev = dev_get_drvdata(dev);
+
+ rpdev->none_suspend = 0;
+ if (rpdev->mu_clk)
+ clk_disable_unprepare(rpdev->mu_clk);
+
+ return 0;
+}
+
+static int imx_rpmsg_noirq_resume(struct device *dev)
+{
+ struct imx_rpmsg_vproc *rpdev = dev_get_drvdata(dev);
+ int ret;
+
+ if (rpdev->mu_clk) {
+ ret = clk_prepare_enable(rpdev->mu_clk);
+ if (ret) {
+ pr_err("unable to enable mu clock\n");
+ return ret;
+ }
+ }
+ ret = imx_rpmsg_mu_init(rpdev);
+ rpdev->none_suspend = 1;
+
+ return ret;
+}
+#endif
+
+static const struct dev_pm_ops imx_rpmsg_pm_ops = {
+ SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(imx_rpmsg_noirq_suspend,
+ imx_rpmsg_noirq_resume)
+};
+
+static struct platform_driver imx_rpmsg_driver = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "imx-rpmsg",
+ .of_match_table = imx_rpmsg_dt_ids,
+ .pm = &imx_rpmsg_pm_ops,
+ },
+ .probe = imx_rpmsg_probe,
+};
+
+static int __init imx_rpmsg_init(void)
+{
+ int ret;
+
+ ret = platform_driver_register(&imx_rpmsg_driver);
+ if (ret)
+ pr_err("Unable to initialize rpmsg driver\n");
+ else
+ pr_info("imx rpmsg driver is registered.\n");
+
+ return ret;
+}
+
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("iMX remote processor messaging virtio device");
+MODULE_LICENSE("GPL v2");
+arch_initcall(imx_rpmsg_init);
diff --git a/drivers/rpmsg/imx_rpmsg_pingpong.c b/drivers/rpmsg/imx_rpmsg_pingpong.c
new file mode 100644
index 000000000000..3aa545fcfe14
--- /dev/null
+++ b/drivers/rpmsg/imx_rpmsg_pingpong.c
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2015 Freescale Semiconductor, Inc.
+ *
+ * derived from the omap-rpmsg implementation.
+ * Remote processor messaging transport - pingpong driver
+ *
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/virtio.h>
+#include <linux/rpmsg.h>
+
+#define MSG "hello world!"
+static unsigned int rpmsg_pingpong;
+
+static int rpmsg_pingpong_cb(struct rpmsg_device *rpdev, void *data, int len,
+ void *priv, u32 src)
+{
+ int err;
+
+ /* reply */
+ rpmsg_pingpong = *(unsigned int *)data;
+ pr_info("get %d (src: 0x%x)\n", rpmsg_pingpong, src);
+
+ /* pingpongs should not live forever */
+ if (rpmsg_pingpong > 100) {
+ dev_info(&rpdev->dev, "goodbye!\n");
+ return 0;
+ }
+ rpmsg_pingpong++;
+ err = rpmsg_sendto(rpdev->ept, (void *)(&rpmsg_pingpong), 4, src);
+
+ if (err)
+ dev_err(&rpdev->dev, "rpmsg_send failed: %d\n", err);
+
+ return err;
+}
+
+static int rpmsg_pingpong_probe(struct rpmsg_device *rpdev)
+{
+ int err;
+
+ dev_info(&rpdev->dev, "new channel: 0x%x -> 0x%x!\n",
+ rpdev->src, rpdev->dst);
+
+ /*
+ * send a message to our remote processor, and tell remote
+ * processor about this channel
+ */
+ err = rpmsg_send(rpdev->ept, MSG, strlen(MSG));
+ if (err) {
+ dev_err(&rpdev->dev, "rpmsg_send failed: %d\n", err);
+ return err;
+ }
+
+ rpmsg_pingpong = 0;
+ err = rpmsg_sendto(rpdev->ept, (void *)(&rpmsg_pingpong), 4, rpdev->dst);
+ if (err) {
+ dev_err(&rpdev->dev, "rpmsg_send failed: %d\n", err);
+ return err;
+ }
+
+ return 0;
+}
+
+static void rpmsg_pingpong_remove(struct rpmsg_device *rpdev)
+{
+ dev_info(&rpdev->dev, "rpmsg pingpong driver is removed\n");
+}
+
+static struct rpmsg_device_id rpmsg_driver_pingpong_id_table[] = {
+ { .name = "rpmsg-openamp-demo-channel" },
+ { .name = "rpmsg-openamp-demo-channel-1" },
+ { },
+};
+MODULE_DEVICE_TABLE(rpmsg, rpmsg_driver_pingpong_id_table);
+
+static struct rpmsg_driver rpmsg_pingpong_driver = {
+ .drv.name = KBUILD_MODNAME,
+ .drv.owner = THIS_MODULE,
+ .id_table = rpmsg_driver_pingpong_id_table,
+ .probe = rpmsg_pingpong_probe,
+ .callback = rpmsg_pingpong_cb,
+ .remove = rpmsg_pingpong_remove,
+};
+
+static int __init init(void)
+{
+ return register_rpmsg_driver(&rpmsg_pingpong_driver);
+}
+
+static void __exit fini(void)
+{
+ unregister_rpmsg_driver(&rpmsg_pingpong_driver);
+}
+module_init(init);
+module_exit(fini);
+
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("iMX virtio remote processor messaging pingpong driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/rpmsg/imx_rpmsg_tty.c b/drivers/rpmsg/imx_rpmsg_tty.c
new file mode 100644
index 000000000000..8228c0da287a
--- /dev/null
+++ b/drivers/rpmsg/imx_rpmsg_tty.c
@@ -0,0 +1,252 @@
+/*
+ * Copyright (C) 2015-2016 Freescale Semiconductor, Inc.
+ * Copyright (C) 2017 NXP
+ *
+ * derived from the omap-rpmsg implementation.
+ * Remote processor messaging transport - tty driver
+ *
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/delay.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/rpmsg.h>
+#include <linux/tty.h>
+#include <linux/tty_driver.h>
+#include <linux/tty_flip.h>
+#include <linux/virtio.h>
+
+/* this needs to be less then (RPMSG_BUF_SIZE - sizeof(struct rpmsg_hdr)) */
+#define RPMSG_MAX_SIZE 256
+#define MSG "hello world!"
+
+/*
+ * struct rpmsgtty_port - Wrapper struct for imx rpmsg tty port.
+ * @port: TTY port data
+ */
+struct rpmsgtty_port {
+ struct tty_port port;
+ spinlock_t rx_lock;
+ struct rpmsg_device *rpdev;
+ struct tty_driver *rpmsgtty_driver;
+};
+
+static int rpmsg_tty_cb(struct rpmsg_device *rpdev, void *data, int len,
+ void *priv, u32 src)
+{
+ int space;
+ unsigned char *cbuf;
+ struct rpmsgtty_port *cport = dev_get_drvdata(&rpdev->dev);
+
+ /* flush the recv-ed none-zero data to tty node */
+ if (len == 0)
+ return 0;
+
+ dev_dbg(&rpdev->dev, "msg(<- src 0x%x) len %d\n", src, len);
+
+ print_hex_dump(KERN_DEBUG, __func__, DUMP_PREFIX_NONE, 16, 1,
+ data, len, true);
+
+ spin_lock_bh(&cport->rx_lock);
+ space = tty_prepare_flip_string(&cport->port, &cbuf, len);
+ if (space <= 0) {
+ dev_err(&rpdev->dev, "No memory for tty_prepare_flip_string\n");
+ spin_unlock_bh(&cport->rx_lock);
+ return -ENOMEM;
+ }
+
+ memcpy(cbuf, data, len);
+ tty_flip_buffer_push(&cport->port);
+ spin_unlock_bh(&cport->rx_lock);
+
+ return 0;
+}
+
+static struct tty_port_operations rpmsgtty_port_ops = { };
+
+static int rpmsgtty_install(struct tty_driver *driver, struct tty_struct *tty)
+{
+ struct rpmsgtty_port *cport = driver->driver_state;
+
+ return tty_port_install(&cport->port, driver, tty);
+}
+
+static int rpmsgtty_open(struct tty_struct *tty, struct file *filp)
+{
+ return tty_port_open(tty->port, tty, filp);
+}
+
+static void rpmsgtty_close(struct tty_struct *tty, struct file *filp)
+{
+ return tty_port_close(tty->port, tty, filp);
+}
+
+static int rpmsgtty_write(struct tty_struct *tty, const unsigned char *buf,
+ int total)
+{
+ int count, ret = 0;
+ const unsigned char *tbuf;
+ struct rpmsgtty_port *rptty_port = container_of(tty->port,
+ struct rpmsgtty_port, port);
+ struct rpmsg_device *rpdev = rptty_port->rpdev;
+
+ if (NULL == buf) {
+ pr_err("buf shouldn't be null.\n");
+ return -ENOMEM;
+ }
+
+ count = total;
+ tbuf = buf;
+ do {
+ /* send a message to our remote processor */
+ ret = rpmsg_send(rpdev->ept, (void *)tbuf,
+ count > RPMSG_MAX_SIZE ? RPMSG_MAX_SIZE : count);
+ if (ret) {
+ dev_err(&rpdev->dev, "rpmsg_send failed: %d\n", ret);
+ return ret;
+ }
+
+ if (count > RPMSG_MAX_SIZE) {
+ count -= RPMSG_MAX_SIZE;
+ tbuf += RPMSG_MAX_SIZE;
+ } else {
+ count = 0;
+ }
+ } while (count > 0);
+
+ return total;
+}
+
+static int rpmsgtty_write_room(struct tty_struct *tty)
+{
+ /* report the space in the rpmsg buffer */
+ return RPMSG_MAX_SIZE;
+}
+
+static const struct tty_operations imxrpmsgtty_ops = {
+ .install = rpmsgtty_install,
+ .open = rpmsgtty_open,
+ .close = rpmsgtty_close,
+ .write = rpmsgtty_write,
+ .write_room = rpmsgtty_write_room,
+};
+
+static int rpmsg_tty_probe(struct rpmsg_device *rpdev)
+{
+ int ret;
+ struct rpmsgtty_port *cport;
+ struct tty_driver *rpmsgtty_driver;
+
+ dev_info(&rpdev->dev, "new channel: 0x%x -> 0x%x!\n",
+ rpdev->src, rpdev->dst);
+
+ cport = devm_kzalloc(&rpdev->dev, sizeof(*cport), GFP_KERNEL);
+ if (!cport)
+ return -ENOMEM;
+
+ rpmsgtty_driver = tty_alloc_driver(1, TTY_DRIVER_UNNUMBERED_NODE);
+ if (IS_ERR(rpmsgtty_driver)) {
+ kfree(cport);
+ return PTR_ERR(rpmsgtty_driver);
+ }
+
+ rpmsgtty_driver->driver_name = "rpmsg_tty";
+ rpmsgtty_driver->name = kasprintf(GFP_KERNEL, "ttyRPMSG%d", rpdev->dst);
+ rpmsgtty_driver->major = UNNAMED_MAJOR;
+ rpmsgtty_driver->minor_start = 0;
+ rpmsgtty_driver->type = TTY_DRIVER_TYPE_CONSOLE;
+ rpmsgtty_driver->init_termios = tty_std_termios;
+
+ tty_set_operations(rpmsgtty_driver, &imxrpmsgtty_ops);
+
+ tty_port_init(&cport->port);
+ cport->port.ops = &rpmsgtty_port_ops;
+ spin_lock_init(&cport->rx_lock);
+ cport->port.low_latency = cport->port.flags | ASYNC_LOW_LATENCY;
+ cport->rpdev = rpdev;
+ dev_set_drvdata(&rpdev->dev, cport);
+ rpmsgtty_driver->driver_state = cport;
+ cport->rpmsgtty_driver = rpmsgtty_driver;
+
+ ret = tty_register_driver(cport->rpmsgtty_driver);
+ if (ret < 0) {
+ pr_err("Couldn't install rpmsg tty driver: ret %d\n", ret);
+ goto error1;
+ } else {
+ pr_info("Install rpmsg tty driver!\n");
+ }
+
+ /*
+ * send a message to our remote processor, and tell remote
+ * processor about this channel
+ */
+ ret = rpmsg_send(rpdev->ept, MSG, strlen(MSG));
+ if (ret) {
+ dev_err(&rpdev->dev, "rpmsg_send failed: %d\n", ret);
+ goto error;
+ }
+
+ return 0;
+
+error:
+ tty_unregister_driver(cport->rpmsgtty_driver);
+error1:
+ put_tty_driver(cport->rpmsgtty_driver);
+ tty_port_destroy(&cport->port);
+ cport->rpmsgtty_driver = NULL;
+ kfree(cport);
+
+ return ret;
+}
+
+static void rpmsg_tty_remove(struct rpmsg_device *rpdev)
+{
+ struct rpmsgtty_port *cport = dev_get_drvdata(&rpdev->dev);
+
+ dev_info(&rpdev->dev, "rpmsg tty driver is removed\n");
+
+ tty_unregister_driver(cport->rpmsgtty_driver);
+ kfree(cport->rpmsgtty_driver->name);
+ put_tty_driver(cport->rpmsgtty_driver);
+ tty_port_destroy(&cport->port);
+ cport->rpmsgtty_driver = NULL;
+}
+
+static struct rpmsg_device_id rpmsg_driver_tty_id_table[] = {
+ { .name = "rpmsg-virtual-tty-channel-1" },
+ { .name = "rpmsg-virtual-tty-channel" },
+ { .name = "rpmsg-openamp-demo-channel" },
+ { },
+};
+MODULE_DEVICE_TABLE(rpmsg, rpmsg_driver_tty_id_table);
+
+static struct rpmsg_driver rpmsg_tty_driver = {
+ .drv.name = KBUILD_MODNAME,
+ .drv.owner = THIS_MODULE,
+ .id_table = rpmsg_driver_tty_id_table,
+ .probe = rpmsg_tty_probe,
+ .callback = rpmsg_tty_cb,
+ .remove = rpmsg_tty_remove,
+};
+
+static int __init init(void)
+{
+ return register_rpmsg_driver(&rpmsg_tty_driver);
+}
+
+static void __exit fini(void)
+{
+ unregister_rpmsg_driver(&rpmsg_tty_driver);
+}
+module_init(init);
+module_exit(fini);
+
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("iMX virtio remote processor messaging tty driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/rpmsg/virtio_rpmsg_bus.c b/drivers/rpmsg/virtio_rpmsg_bus.c
index 82b83002fcba..5e264b9338c6 100644
--- a/drivers/rpmsg/virtio_rpmsg_bus.c
+++ b/drivers/rpmsg/virtio_rpmsg_bus.c
@@ -64,6 +64,7 @@
struct virtproc_info {
struct virtio_device *vdev;
struct virtqueue *rvq, *svq;
+ struct device *bufs_dev;
void *rbufs, *sbufs;
unsigned int num_bufs;
unsigned int buf_size;
@@ -204,16 +205,17 @@ static const struct rpmsg_endpoint_ops virtio_endpoint_ops = {
* location (in vmalloc or in kernel).
*/
static void
-rpmsg_sg_init(struct scatterlist *sg, void *cpu_addr, unsigned int len)
+rpmsg_sg_init(struct virtproc_info *vrp, struct scatterlist *sg,
+ void *cpu_addr, unsigned int len)
{
- if (is_vmalloc_addr(cpu_addr)) {
- sg_init_table(sg, 1);
- sg_set_page(sg, vmalloc_to_page(cpu_addr), len,
- offset_in_page(cpu_addr));
- } else {
- WARN_ON(!virt_addr_valid(cpu_addr));
- sg_init_one(sg, cpu_addr, len);
- }
+ unsigned int offset;
+ dma_addr_t dev_add = vrp->bufs_dma + (cpu_addr - vrp->rbufs);
+ struct page *page = pfn_to_page(PHYS_PFN(dma_to_phys(vrp->bufs_dev,
+ dev_add)));
+
+ offset = offset_in_page(cpu_addr);
+ sg_init_table(sg, 1);
+ sg_set_page(sg, page, len, offset);
}
/**
@@ -634,7 +636,7 @@ static int rpmsg_send_offchannel_raw(struct rpmsg_device *rpdev,
msg, sizeof(*msg) + msg->len, true);
#endif
- rpmsg_sg_init(&sg, msg, sizeof(*msg) + len);
+ rpmsg_sg_init(vrp, &sg, msg, sizeof(*msg) + len);
mutex_lock(&vrp->tx_lock);
@@ -758,7 +760,7 @@ static int rpmsg_recv_single(struct virtproc_info *vrp, struct device *dev,
dev_warn(dev, "msg received with no recipient\n");
/* publish the real size of the buffer */
- rpmsg_sg_init(&sg, msg, vrp->buf_size);
+ rpmsg_sg_init(vrp, &sg, msg, vrp->buf_size);
/* add the buffer back to the remote processor's virtqueue */
err = virtqueue_add_inbuf(vrp->rvq, &sg, 1, msg, GFP_KERNEL);
@@ -924,9 +926,16 @@ static int rpmsg_probe(struct virtio_device *vdev)
total_buf_space, &vrp->bufs_dma,
GFP_KERNEL);
if (!bufs_va) {
- err = -ENOMEM;
- goto vqs_del;
- }
+ bufs_va = dma_alloc_coherent(vdev->dev.parent,
+ total_buf_space, &vrp->bufs_dma,
+ GFP_KERNEL);
+ if (!bufs_va) {
+ err = -ENOMEM;
+ goto vqs_del;
+ } else
+ vrp->bufs_dev = vdev->dev.parent;
+ } else
+ vrp->bufs_dev = vdev->dev.parent->parent;
dev_dbg(&vdev->dev, "buffers: va %p, dma %pad\n",
bufs_va, &vrp->bufs_dma);
@@ -942,7 +951,7 @@ static int rpmsg_probe(struct virtio_device *vdev)
struct scatterlist sg;
void *cpu_addr = vrp->rbufs + i * vrp->buf_size;
- rpmsg_sg_init(&sg, cpu_addr, vrp->buf_size);
+ rpmsg_sg_init(vrp, &sg, cpu_addr, vrp->buf_size);
err = virtqueue_add_inbuf(vrp->rvq, &sg, 1, cpu_addr,
GFP_KERNEL);
@@ -988,7 +997,7 @@ static int rpmsg_probe(struct virtio_device *vdev)
return 0;
free_coherent:
- dma_free_coherent(vdev->dev.parent->parent, total_buf_space,
+ dma_free_coherent(vrp->bufs_dev, total_buf_space,
bufs_va, vrp->bufs_dma);
vqs_del:
vdev->config->del_vqs(vrp->vdev);
@@ -1023,7 +1032,7 @@ static void rpmsg_remove(struct virtio_device *vdev)
vdev->config->del_vqs(vrp->vdev);
- dma_free_coherent(vdev->dev.parent->parent, total_buf_space,
+ dma_free_coherent(vrp->bufs_dev, total_buf_space,
vrp->rbufs, vrp->bufs_dma);
kfree(vrp);
@@ -1058,7 +1067,7 @@ static int __init rpmsg_init(void)
return ret;
}
-subsys_initcall(rpmsg_init);
+arch_initcall(rpmsg_init);
static void __exit rpmsg_fini(void)
{
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index e0e58f3b1420..f90aca3f9353 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -1677,6 +1677,20 @@ config RTC_DRV_SNVS
This driver can also be built as a module, if so, the module
will be called "rtc-snvs".
+config RTC_DRV_IMX_SC
+ tristate "NXP SC RTC support"
+ depends on OF
+ help
+ If you say yes here you get support for the NXP SC
+ RTC module.
+
+config RTC_DRV_IMX_RPMSG
+ tristate "NXP RPMSG RTC support"
+ depends on OF
+ help
+ If you say yes here you get support for the NXP RPMSG
+ RTC module.
+
config RTC_DRV_SIRFSOC
tristate "SiRFSOC RTC"
depends on ARCH_SIRF
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
index 0bf1fc02b82c..23a9d6d60784 100644
--- a/drivers/rtc/Makefile
+++ b/drivers/rtc/Makefile
@@ -147,6 +147,8 @@ obj-$(CONFIG_RTC_DRV_SA1100) += rtc-sa1100.o
obj-$(CONFIG_RTC_DRV_SH) += rtc-sh.o
obj-$(CONFIG_RTC_DRV_SIRFSOC) += rtc-sirfsoc.o
obj-$(CONFIG_RTC_DRV_SNVS) += rtc-snvs.o
+obj-$(CONFIG_RTC_DRV_IMX_SC) += rtc-imx-sc.o
+obj-$(CONFIG_RTC_DRV_IMX_RPMSG) += rtc-imx-rpmsg.o
obj-$(CONFIG_RTC_DRV_SPEAR) += rtc-spear.o
obj-$(CONFIG_RTC_DRV_STARFIRE) += rtc-starfire.o
obj-$(CONFIG_RTC_DRV_STK17TA8) += rtc-stk17ta8.o
diff --git a/drivers/rtc/rtc-imx-rpmsg.c b/drivers/rtc/rtc-imx-rpmsg.c
new file mode 100644
index 000000000000..d381cb0c59b5
--- /dev/null
+++ b/drivers/rtc/rtc-imx-rpmsg.c
@@ -0,0 +1,383 @@
+/*
+ * Copyright 2017-2018 NXP
+ *
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/imx_rpmsg.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/pm_qos.h>
+#include <linux/rpmsg.h>
+#include <linux/rtc.h>
+
+#define RPMSG_TIMEOUT 1000
+
+#define RTC_RPMSG_SEND 0x0
+#define RTC_RPMSG_RECEIVE 0x1
+#define RTC_RPMSG_NOTIFY 0x2
+
+enum rtc_rpmsg_cmd {
+ RTC_RPMSG_SET_TIME,
+ RTC_RPMSG_GET_TIME,
+ RTC_RPMSG_SET_ALARM,
+ RTC_RPMSG_GET_ALARM,
+ RTC_RPMSG_ENABLE_ALARM,
+};
+
+struct rtc_rpmsg_data {
+ struct imx_rpmsg_head header;
+ u8 reserved0;
+ union {
+ u8 reserved1;
+ u8 ret;
+ };
+ union {
+ u32 reserved2;
+ u32 sec;
+ };
+ union {
+ u8 enable;
+ u8 reserved3;
+ };
+ union {
+ u8 pending;
+ u8 reserved4;
+ };
+} __attribute__ ((packed));
+
+struct rtc_rpmsg_info {
+ struct rpmsg_device *rpdev;
+ struct device *dev;
+ struct rtc_rpmsg_data *msg;
+ struct pm_qos_request pm_qos_req;
+ struct completion cmd_complete;
+ struct mutex lock;
+};
+
+static struct rtc_rpmsg_info rtc_rpmsg;
+
+struct imx_rpmsg_rtc_data {
+ struct rtc_device *rtc;
+ spinlock_t lock;
+};
+
+struct imx_rpmsg_rtc_data *data;
+
+static int rtc_send_message(struct rtc_rpmsg_data *msg,
+ struct rtc_rpmsg_info *info, bool ack)
+{
+ int err;
+
+ if (!info->rpdev) {
+ dev_dbg(info->dev,
+ "rpmsg channel not ready, m4 image ready?\n");
+ return -EINVAL;
+ }
+
+ mutex_lock(&info->lock);
+ pm_qos_add_request(&info->pm_qos_req,
+ PM_QOS_CPU_DMA_LATENCY, 0);
+
+ reinit_completion(&info->cmd_complete);
+
+ err = rpmsg_send(info->rpdev->ept, (void *)msg,
+ sizeof(struct rtc_rpmsg_data));
+
+ if (err) {
+ dev_err(&info->rpdev->dev, "rpmsg_send failed: %d\n", err);
+ goto err_out;
+ }
+
+ if (ack) {
+ err = wait_for_completion_timeout(&info->cmd_complete,
+ msecs_to_jiffies(RPMSG_TIMEOUT));
+ if (!err) {
+ dev_err(&info->rpdev->dev, "rpmsg_send timeout!\n");
+ err = -ETIMEDOUT;
+ goto err_out;
+ }
+
+ if (info->msg->ret != 0) {
+ dev_err(&info->rpdev->dev, "rpmsg not ack %d!\n",
+ info->msg->ret);
+ err = -EINVAL;
+ goto err_out;
+ }
+
+ err = 0;
+ }
+
+err_out:
+ pm_qos_remove_request(&info->pm_qos_req);
+ mutex_unlock(&info->lock);
+
+ return err;
+}
+
+static int imx_rpmsg_rtc_read_time(struct device *dev, struct rtc_time *tm)
+{
+ struct rtc_rpmsg_data msg;
+ int ret;
+
+ msg.header.cate = IMX_RPMSG_RTC;
+ msg.header.major = IMX_RMPSG_MAJOR;
+ msg.header.minor = IMX_RMPSG_MINOR;
+ msg.header.type = RTC_RPMSG_SEND;
+ msg.header.cmd = RTC_RPMSG_GET_TIME;
+
+ ret = rtc_send_message(&msg, &rtc_rpmsg, true);
+ if (ret)
+ return ret;
+
+ rtc_time_to_tm(rtc_rpmsg.msg->sec, tm);
+
+ return 0;
+}
+
+static int imx_rpmsg_rtc_set_time(struct device *dev, struct rtc_time *tm)
+{
+ struct rtc_rpmsg_data msg;
+ unsigned long time;
+ int ret;
+
+ rtc_tm_to_time(tm, &time);
+
+ msg.header.cate = IMX_RPMSG_RTC;
+ msg.header.major = IMX_RMPSG_MAJOR;
+ msg.header.minor = IMX_RMPSG_MINOR;
+ msg.header.type = RTC_RPMSG_SEND;
+ msg.header.cmd = RTC_RPMSG_SET_TIME;
+ msg.sec = time;
+
+ ret = rtc_send_message(&msg, &rtc_rpmsg, true);
+ if (ret)
+ return ret;
+
+ return rtc_rpmsg.msg->ret;
+}
+
+static int imx_rpmsg_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
+{
+ struct rtc_rpmsg_data msg;
+ int ret;
+
+ msg.header.cate = IMX_RPMSG_RTC;
+ msg.header.major = IMX_RMPSG_MAJOR;
+ msg.header.minor = IMX_RMPSG_MINOR;
+ msg.header.type = RTC_RPMSG_SEND;
+ msg.header.cmd = RTC_RPMSG_GET_ALARM;
+
+ ret = rtc_send_message(&msg, &rtc_rpmsg, true);
+ if (ret)
+ return ret;
+
+ rtc_time_to_tm(rtc_rpmsg.msg->sec, &alrm->time);
+ alrm->pending = rtc_rpmsg.msg->pending;
+
+ return rtc_rpmsg.msg->ret;
+}
+
+static int imx_rpmsg_rtc_alarm_irq_enable(struct device *dev,
+ unsigned int enable)
+{
+ struct rtc_rpmsg_data msg;
+ int ret;
+
+ msg.header.cate = IMX_RPMSG_RTC;
+ msg.header.major = IMX_RMPSG_MAJOR;
+ msg.header.minor = IMX_RMPSG_MINOR;
+ msg.header.type = RTC_RPMSG_SEND;
+ msg.header.cmd = RTC_RPMSG_ENABLE_ALARM;
+ msg.enable = enable;
+
+ ret = rtc_send_message(&msg, &rtc_rpmsg, true);
+ if (ret)
+ return ret;
+
+ return rtc_rpmsg.msg->ret;
+}
+
+static int imx_rpmsg_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
+{
+ struct rtc_rpmsg_data msg;
+ unsigned long time;
+ int ret;
+
+ rtc_tm_to_time(&alrm->time, &time);
+
+ msg.header.cate = IMX_RPMSG_RTC;
+ msg.header.major = IMX_RMPSG_MAJOR;
+ msg.header.minor = IMX_RMPSG_MINOR;
+ msg.header.type = RTC_RPMSG_SEND;
+ msg.header.cmd = RTC_RPMSG_SET_ALARM;
+ msg.sec = time;
+ msg.enable = alrm->enabled;
+
+ ret = rtc_send_message(&msg, &rtc_rpmsg, true);
+ if (ret)
+ return ret;
+
+ return rtc_rpmsg.msg->ret;
+}
+
+static int imx_rpmsg_rtc_alarm_irq_update(void)
+{
+ rtc_update_irq(data->rtc, 1, RTC_IRQF);
+
+ return 0;
+}
+
+static const struct rtc_class_ops imx_rpmsg_rtc_ops = {
+ .read_time = imx_rpmsg_rtc_read_time,
+ .set_time = imx_rpmsg_rtc_set_time,
+ .read_alarm = imx_rpmsg_rtc_read_alarm,
+ .set_alarm = imx_rpmsg_rtc_set_alarm,
+ .alarm_irq_enable = imx_rpmsg_rtc_alarm_irq_enable,
+};
+
+static struct rpmsg_device_id rtc_rpmsg_id_table[] = {
+ { .name = "rpmsg-rtc-channel" },
+ { },
+};
+
+static int rtc_rpmsg_probe(struct rpmsg_device *rpdev)
+{
+ int ret = 0;
+
+ dev_info(&rpdev->dev, "new channel: 0x%x -> 0x%x!\n",
+ rpdev->src, rpdev->dst);
+
+ rtc_rpmsg.rpdev = rpdev;
+ mutex_init(&rtc_rpmsg.lock);
+
+ init_completion(&rtc_rpmsg.cmd_complete);
+
+ return ret;
+}
+
+static int rtc_rpmsg_cb(struct rpmsg_device *rpdev, void *data, int len,
+ void *priv, u32 src)
+{
+ struct rtc_rpmsg_data *msg = (struct rtc_rpmsg_data *)data;
+
+ if (msg->header.type == RTC_RPMSG_RECEIVE) {
+ rtc_rpmsg.msg = msg;
+ complete(&rtc_rpmsg.cmd_complete);
+ return 0;
+ } else if (msg->header.type == RTC_RPMSG_NOTIFY) {
+ rtc_rpmsg.msg = msg;
+ imx_rpmsg_rtc_alarm_irq_update();
+ } else
+ dev_err(&rtc_rpmsg.rpdev->dev, "wrong command type!\n");
+
+ return 0;
+}
+
+static void rtc_rpmsg_remove(struct rpmsg_device *rpdev)
+{
+ dev_info(&rpdev->dev, "rtc rpmsg driver is removed\n");
+}
+
+static struct rpmsg_driver rtc_rpmsg_driver = {
+ .drv.name = "rtc_rpmsg",
+ .drv.owner = THIS_MODULE,
+ .id_table = rtc_rpmsg_id_table,
+ .probe = rtc_rpmsg_probe,
+ .callback = rtc_rpmsg_cb,
+ .remove = rtc_rpmsg_remove,
+};
+
+static int imx_rpmsg_rtc_probe(struct platform_device *pdev)
+{
+ int ret = 0;
+
+ data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
+
+ platform_set_drvdata(pdev, data);
+ device_init_wakeup(&pdev->dev, true);
+
+ data->rtc = devm_rtc_device_register(&pdev->dev, pdev->name,
+ &imx_rpmsg_rtc_ops, THIS_MODULE);
+ if (IS_ERR(data->rtc)) {
+ ret = PTR_ERR(data->rtc);
+ dev_err(&pdev->dev, "failed to register rtc: %d\n", ret);
+ goto error_rtc_device_register;
+ }
+
+ ret = register_rpmsg_driver(&rtc_rpmsg_driver);
+ if (ret)
+ dev_err(&pdev->dev, "failed to register rpmsg for rtc: %d\n",
+ ret);
+
+error_rtc_device_register:
+ return ret;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int imx_rpmsg_rtc_suspend(struct device *dev)
+{
+ return 0;
+}
+
+static int imx_rpmsg_rtc_suspend_noirq(struct device *dev)
+{
+ return 0;
+}
+
+static int imx_rpmsg_rtc_resume(struct device *dev)
+{
+ return 0;
+}
+
+static int imx_rpmsg_rtc_resume_noirq(struct device *dev)
+{
+ return 0;
+}
+
+static const struct dev_pm_ops imx_rpmsg_rtc_pm_ops = {
+ .suspend = imx_rpmsg_rtc_suspend,
+ .suspend_noirq = imx_rpmsg_rtc_suspend_noirq,
+ .resume = imx_rpmsg_rtc_resume,
+ .resume_noirq = imx_rpmsg_rtc_resume_noirq,
+};
+
+#define IMX_RPMSG_RTC_PM_OPS (&imx_rpmsg_rtc_pm_ops)
+
+#else
+
+#define IMX8_RPMSG_RTC_PM_OPS NULL
+
+#endif
+
+static const struct of_device_id imx_rpmsg_rtc_dt_ids[] = {
+ { .compatible = "fsl,imx-rpmsg-rtc", },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, imx_rpmsg_rtc_dt_ids);
+
+static struct platform_driver imx_rpmsg_rtc_driver = {
+ .driver = {
+ .name = "imx_rpmsg_rtc",
+ .pm = IMX_RPMSG_RTC_PM_OPS,
+ .of_match_table = imx_rpmsg_rtc_dt_ids,
+ },
+ .probe = imx_rpmsg_rtc_probe,
+};
+module_platform_driver(imx_rpmsg_rtc_driver);
+
+MODULE_AUTHOR("Anson Huang <Anson.Huang@nxp.com>");
+MODULE_DESCRIPTION("NXP i.MX RPMSG RTC Driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/rtc/rtc-imx-sc.c b/drivers/rtc/rtc-imx-sc.c
new file mode 100644
index 000000000000..909d7c2a7005
--- /dev/null
+++ b/drivers/rtc/rtc-imx-sc.c
@@ -0,0 +1,219 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017 NXP
+ *
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/arm-smccc.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/rtc.h>
+#include <soc/imx/fsl_sip.h>
+#include <soc/imx8/sc/sci.h>
+#include <soc/imx8/sc/svc/irq/api.h>
+
+sc_ipc_t timer_ipcHandle;
+
+struct imx_sc_rtc_data {
+ struct rtc_device *rtc;
+ spinlock_t lock;
+};
+
+struct imx_sc_rtc_data *data;
+
+static int imx_sc_rtc_alarm_sc_notify(struct notifier_block *nb,
+ unsigned long event, void *group)
+{
+ u32 events = 0;
+
+ /* ignore non-rtc irq */
+ if (!((event & SC_IRQ_RTC) &&
+ (*(sc_irq_group_t *)group == SC_IRQ_GROUP_RTC)))
+ return 0;
+
+ rtc_update_irq(data->rtc, 1, events);
+
+ return 0;
+}
+
+static struct notifier_block imx_sc_rtc_alarm_sc_notifier = {
+ .notifier_call = imx_sc_rtc_alarm_sc_notify,
+};
+
+static int imx_sc_rtc_read_time(struct device *dev, struct rtc_time *tm)
+{
+ u32 time = 0;
+ sc_err_t sciErr = SC_ERR_NONE;
+
+ if (!timer_ipcHandle)
+ return -ENODEV;
+
+ sciErr = sc_timer_get_rtc_sec1970(timer_ipcHandle, &time);
+ if (sciErr) {
+ dev_err_once(dev, "failed to read time: %d\n", sciErr);
+ return -EINVAL;
+ }
+
+ rtc_time_to_tm(time, tm);
+
+ return 0;
+}
+
+static int imx_sc_rtc_set_time(struct device *dev, struct rtc_time *tm)
+{
+ struct arm_smccc_res res;
+
+ /* pack 2 time parameters into 1 register, 16 bits for each */
+ arm_smccc_smc(FSL_SIP_SRTC, FSL_SIP_SRTC_SET_TIME,
+ ((tm->tm_year + 1900) << 16) | (tm->tm_mon + 1),
+ (tm->tm_mday << 16) | tm->tm_hour,
+ (tm->tm_min << 16) | tm->tm_sec,
+ 0, 0, 0, &res);
+
+ return res.a0;
+}
+
+static int imx_sc_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
+{
+ return 0;
+}
+
+static int imx_sc_rtc_alarm_irq_enable(struct device *dev, unsigned int enable)
+{
+ return 0;
+}
+
+static int imx_sc_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
+{
+ sc_err_t sciErr = SC_ERR_NONE;
+ struct rtc_time *alrm_tm = &alrm->time;
+
+ if (!timer_ipcHandle)
+ return -ENODEV;
+
+ sciErr = sc_timer_set_rtc_alarm(timer_ipcHandle,
+ alrm_tm->tm_year + 1900,
+ alrm_tm->tm_mon + 1,
+ alrm_tm->tm_mday,
+ alrm_tm->tm_hour,
+ alrm_tm->tm_min,
+ alrm_tm->tm_sec);
+
+ return 0;
+}
+
+static const struct rtc_class_ops imx_sc_rtc_ops = {
+ .read_time = imx_sc_rtc_read_time,
+ .set_time = imx_sc_rtc_set_time,
+ .read_alarm = imx_sc_rtc_read_alarm,
+ .set_alarm = imx_sc_rtc_set_alarm,
+ .alarm_irq_enable = imx_sc_rtc_alarm_irq_enable,
+};
+
+static int imx_sc_rtc_probe(struct platform_device *pdev)
+{
+ int ret = 0;
+ uint32_t mu_id;
+ sc_err_t sciErr;
+
+ data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
+
+ platform_set_drvdata(pdev, data);
+
+ device_init_wakeup(&pdev->dev, true);
+ data->rtc = devm_rtc_device_register(&pdev->dev, pdev->name,
+ &imx_sc_rtc_ops, THIS_MODULE);
+ if (IS_ERR(data->rtc)) {
+ ret = PTR_ERR(data->rtc);
+ dev_err(&pdev->dev, "failed to register rtc: %d\n", ret);
+ goto error_rtc_device_register;
+ }
+
+ sciErr = sc_ipc_getMuID(&mu_id);
+ if (sciErr != SC_ERR_NONE) {
+ dev_err(&pdev->dev, "can not obtain mu id: %d\n", sciErr);
+ return sciErr;
+ }
+
+ sciErr = sc_ipc_open(&timer_ipcHandle, mu_id);
+
+ if (sciErr != SC_ERR_NONE) {
+ dev_err(&pdev->dev, "can not open mu channel to scu: %d\n", sciErr);
+ return sciErr;
+ };
+
+ register_scu_notifier(&imx_sc_rtc_alarm_sc_notifier);
+
+error_rtc_device_register:
+
+ return ret;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int imx_sc_rtc_suspend(struct device *dev)
+{
+ return 0;
+}
+
+static int imx_sc_rtc_suspend_noirq(struct device *dev)
+{
+ return 0;
+}
+
+static int imx_sc_rtc_resume(struct device *dev)
+{
+ return 0;
+}
+
+static int imx_sc_rtc_resume_noirq(struct device *dev)
+{
+ return 0;
+}
+
+static const struct dev_pm_ops imx_sc_rtc_pm_ops = {
+ .suspend = imx_sc_rtc_suspend,
+ .suspend_noirq = imx_sc_rtc_suspend_noirq,
+ .resume = imx_sc_rtc_resume,
+ .resume_noirq = imx_sc_rtc_resume_noirq,
+};
+
+#define IMX_SC_RTC_PM_OPS (&imx_sc_rtc_pm_ops)
+
+#else
+
+#define IMX8_SC_RTC_PM_OPS NULL
+
+#endif
+
+static const struct of_device_id imx_sc_dt_ids[] = {
+ { .compatible = "fsl,imx-sc-rtc", },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, imx_sc_dt_ids);
+
+static struct platform_driver imx_sc_rtc_driver = {
+ .driver = {
+ .name = "imx_sc_rtc",
+ .pm = IMX_SC_RTC_PM_OPS,
+ .of_match_table = imx_sc_dt_ids,
+ },
+ .probe = imx_sc_rtc_probe,
+};
+module_platform_driver(imx_sc_rtc_driver);
+
+MODULE_AUTHOR("Anson Huang <Anson.Huang@nxp.com>");
+MODULE_DESCRIPTION("NXP i.MX SC RTC Driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/rtc/rtc-snvs.c b/drivers/rtc/rtc-snvs.c
index 7aa2c5ea0de4..58e2a7bde3a5 100644
--- a/drivers/rtc/rtc-snvs.c
+++ b/drivers/rtc/rtc-snvs.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011-2012 Freescale Semiconductor, Inc.
+ * Copyright (C) 2011-2016 Freescale Semiconductor, Inc.
*
* The code contained herein is licensed under the GNU General Public
* License. You may obtain a copy of the GNU General Public License
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
index bdec5f429440..0b6a3ab8e0ab 100644
--- a/drivers/scsi/scsi_error.c
+++ b/drivers/scsi/scsi_error.c
@@ -61,6 +61,12 @@ static int scsi_eh_try_stu(struct scsi_cmnd *scmd);
static int scsi_try_to_abort_cmd(struct scsi_host_template *,
struct scsi_cmnd *);
+#ifdef CONFIG_AHCI_IMX
+extern void *sg_io_buffer_hack;
+#else
+#define sg_io_buffer_hack NULL
+#endif
+
/* called with shost->host_lock held */
void scsi_eh_wakeup(struct Scsi_Host *shost)
{
@@ -69,6 +75,11 @@ void scsi_eh_wakeup(struct Scsi_Host *shost)
wake_up_process(shost->ehandler);
SCSI_LOG_ERROR_RECOVERY(5, shost_printk(KERN_INFO, shost,
"Waking error handler thread\n"));
+ } else if ((shost->host_failed > 0) || (sg_io_buffer_hack != NULL)) {
+ trace_scsi_eh_wakeup(shost);
+ wake_up_process(shost->ehandler);
+ SCSI_LOG_ERROR_RECOVERY(5, shost_printk(KERN_INFO, shost,
+ "Waking error handler thread\n"));
}
}
@@ -2144,8 +2155,15 @@ int scsi_error_handler(void *data)
if (kthread_should_stop())
break;
+ /*
+ * Do not go to sleep, when there is host_failed when the
+ * one-PRD per command workaroud is tiggered.
+ * Because that ata/scsi subsystem maybe hang, when CD_ROM
+ * and HDD are accessed simultaneously.
+ */
if ((shost->host_failed == 0 && shost->host_eh_scheduled == 0) ||
- shost->host_failed != atomic_read(&shost->host_busy)) {
+ ((shost->host_failed != atomic_read(&shost->host_busy)) &&
+ (sg_io_buffer_hack == NULL) && (shost->host_failed > 0))) {
SCSI_LOG_ERROR_RECOVERY(1,
shost_printk(KERN_INFO, shost,
"scsi_eh_%d: sleeping\n",
diff --git a/drivers/soc/Makefile b/drivers/soc/Makefile
index 36dec140ea0d..e60a4a710c39 100644
--- a/drivers/soc/Makefile
+++ b/drivers/soc/Makefile
@@ -9,7 +9,7 @@ obj-y += bcm/
obj-$(CONFIG_ARCH_DOVE) += dove/
obj-$(CONFIG_MACH_DOVE) += dove/
obj-y += fsl/
-obj-$(CONFIG_ARCH_MXC) += imx/
+obj-y += imx/
obj-$(CONFIG_SOC_XWAY) += lantiq/
obj-$(CONFIG_ARCH_MEDIATEK) += mediatek/
obj-$(CONFIG_ARCH_MESON) += amlogic/
diff --git a/drivers/soc/imx/Kconfig b/drivers/soc/imx/Kconfig
index a5b86a28f343..3a1fa180f28f 100644
--- a/drivers/soc/imx/Kconfig
+++ b/drivers/soc/imx/Kconfig
@@ -1,5 +1,40 @@
menu "i.MX SoC drivers"
+menuconfig ARCH_MXC_ARM64
+ bool "NXP i.MX family"
+ depends on ARM64
+ help
+ Support for NXP MXC/iMX-based ARM64 family of processors
+
+if ARCH_MXC_ARM64
+
+config ARCH_FSL_IMX8QM
+ bool "i.MX8QM"
+ select HAVE_IMX_MU
+ select HAVE_IMX_RPMSG
+ select HAVE_IMX8_SOC
+
+config ARCH_FSL_IMX8QXP
+ bool "i.MX8QXP"
+ select HAVE_IMX_MU
+ select HAVE_IMX_RPMSG
+ select HAVE_IMX8_SOC
+ select CLKSRC_IMX_GPT
+
+config ARCH_FSL_IMX8MQ
+ bool "i.MX8MQ"
+ select HAVE_IMX_MU
+ select HAVE_IMX_RPMSG
+ select HAVE_IMX8_SOC
+
+config ARCH_FSL_IMX8MM
+ bool "i.MX8MM"
+ select HAVE_IMX_MU
+ select HAVE_IMX_RPMSG
+ select HAVE_IMX8_SOC
+
+endif
+
config IMX7_PM_DOMAINS
bool "i.MX7 PM domains"
depends on SOC_IMX7D || (COMPILE_TEST && OF)
@@ -7,4 +42,14 @@ config IMX7_PM_DOMAINS
select PM_GENERIC_DOMAINS
default y if SOC_IMX7D
+config HAVE_IMX_MU
+ bool
+
+config HAVE_IMX8_SOC
+ bool
+
+config HAVE_IMX_RPMSG
+ select RPMSG_VIRTIO
+ select RPMSG
+ bool
endmenu
diff --git a/drivers/soc/imx/Makefile b/drivers/soc/imx/Makefile
index aab41a5cc317..2606ddfd945b 100644
--- a/drivers/soc/imx/Makefile
+++ b/drivers/soc/imx/Makefile
@@ -1,2 +1,8 @@
obj-$(CONFIG_HAVE_IMX_GPC) += gpc.o
obj-$(CONFIG_IMX7_PM_DOMAINS) += gpcv2.o
+obj-$(CONFIG_HAVE_IMX_MU) += mu/
+obj-$(CONFIG_ARCH_FSL_IMX8QM) += sc/
+obj-$(CONFIG_ARCH_FSL_IMX8QM) += pm-domains.o
+obj-$(CONFIG_ARCH_FSL_IMX8MQ) += busfreq-imx8mq.o gpc-psci.o
+obj-$(CONFIG_ARCH_FSL_IMX8MM) += gpc-psci.o
+obj-$(CONFIG_HAVE_IMX8_SOC) += soc-imx8.o
diff --git a/drivers/soc/imx/busfreq-imx8mq.c b/drivers/soc/imx/busfreq-imx8mq.c
new file mode 100644
index 000000000000..441d5229f5c3
--- /dev/null
+++ b/drivers/soc/imx/busfreq-imx8mq.c
@@ -0,0 +1,748 @@
+/*
+ * Copyright 2017-2018 NXP
+ *
+ * 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/arm-smccc.h>
+#include <linux/busfreq-imx.h>
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/cpumask.h>
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/mutex.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/proc_fs.h>
+#include <linux/reboot.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/smp.h>
+#include <linux/suspend.h>
+#include <soc/imx/fsl_sip.h>
+#include <soc/imx/revision.h>
+#include <soc/imx8/soc.h>
+
+#define HIGH_FREQ_3200MTS 0x0
+#define AUDIO_FREQ_400MTS 0x1
+#define LOW_BUS_FREQ_100MTS 0x2
+#define LOW_BUS_FREQ_667MTS 0x1
+#define WAIT_BUS_FREQ_DONE 0xf
+
+static struct device *busfreq_dev;
+static int low_bus_freq_mode;
+static int audio_bus_freq_mode;
+static int high_bus_freq_mode;
+static int bus_freq_scaling_initialized;
+static int bus_freq_scaling_is_active;
+static int high_bus_count, audio_bus_count, low_bus_count;
+static int cur_bus_freq_mode;
+static int busfreq_suspended;
+static bool cancel_reduce_bus_freq;
+
+static struct clk *dram_pll_clk;
+static struct clk *sys1_pll_800m;
+static struct clk *sys1_pll_400m;
+static struct clk *sys1_pll_100m;
+static struct clk *sys1_pll_40m;
+static struct clk *dram_alt_src;
+static struct clk *dram_alt_root;
+static struct clk *dram_core_clk;
+static struct clk *dram_apb_src;
+static struct clk *dram_apb_pre_div;
+static struct clk *noc_div;
+static struct clk *main_axi_src;
+static struct clk *ahb_div;
+static struct clk *osc_25m;
+static struct clk *sys2_pll_333m;
+
+static struct delayed_work low_bus_freq_handler;
+static struct delayed_work bus_freq_daemon;
+
+DEFINE_MUTEX(bus_freq_mutex);
+
+static irqreturn_t wait_in_wfe_irq(int irq, void *dev_id)
+{
+ struct arm_smccc_res res;
+ /* call smc trap to ATF */
+ arm_smccc_smc(FSL_SIP_DDR_DVFS, WAIT_BUS_FREQ_DONE, 0,
+ 0, 0, 0, 0, 0, &res);
+
+ return IRQ_HANDLED;
+}
+
+static void update_bus_freq(int target_freq)
+{
+ struct arm_smccc_res res;
+ u32 online_cpus = 0;
+ int cpu = 0;
+
+ local_irq_disable();
+
+ for_each_online_cpu(cpu) {
+ online_cpus |= (1 << (cpu * 8));
+ }
+ /* change the ddr freqency */
+ arm_smccc_smc(FSL_SIP_DDR_DVFS, target_freq, online_cpus,
+ 0, 0, 0, 0, 0, &res);
+
+ local_irq_enable();
+}
+
+static void reduce_bus_freq(void)
+{
+ u32 rate;
+
+ high_bus_freq_mode = 0;
+
+ /*
+ * below piece of code has some redundant part, keep
+ * it at present, we may need update the audio freq
+ * in the future if needed.
+ */
+ if (audio_bus_count) {
+ if (cur_bus_freq_mode == BUS_FREQ_HIGH) {
+
+ if (of_machine_is_compatible("fsl,imx8mq")) {
+ if (imx8_get_soc_revision() < IMX_CHIP_REVISION_2_1) {
+ update_bus_freq(LOW_BUS_FREQ_667MTS);
+
+ /*
+ * the dram_apb and dram_core clk rate is changed
+ * in ATF side, below two lines of code is just used
+ * to upate the clock tree info in kernel side.
+ */
+ clk_set_rate(dram_apb_pre_div, 160000000);
+ clk_get_rate(dram_pll_clk);
+ } else {
+ /* prepare the necessary clk before frequency change */
+ clk_prepare_enable(sys1_pll_40m);
+ clk_prepare_enable(dram_alt_root);
+ clk_prepare_enable(sys1_pll_100m);
+
+ update_bus_freq(LOW_BUS_FREQ_100MTS);
+
+ clk_set_parent(dram_alt_src, sys1_pll_100m);
+ clk_set_parent(dram_core_clk, dram_alt_root);
+ clk_set_parent(dram_apb_src, sys1_pll_40m);
+ clk_set_rate(dram_apb_pre_div, 20000000);
+ clk_disable_unprepare(sys1_pll_100m);
+ clk_disable_unprepare(sys1_pll_40m);
+ clk_disable_unprepare(dram_alt_root);
+ }
+ /* reduce the NOC & bus clock */
+ rate = clk_get_rate(noc_div);
+ if (rate == 0) {
+ WARN_ON(1);
+ return;
+ }
+ clk_set_rate(noc_div, rate / 8);
+ } else {
+ /* prepare the necessary clk before frequency change */
+ clk_prepare_enable(sys1_pll_40m);
+ clk_prepare_enable(dram_alt_root);
+ clk_prepare_enable(sys1_pll_100m);
+
+ update_bus_freq(LOW_BUS_FREQ_100MTS);
+
+ /* correct the clock tree info */
+ clk_set_parent(dram_alt_src, sys1_pll_100m);
+ clk_set_parent(dram_core_clk, dram_alt_root);
+ clk_set_parent(dram_apb_src, sys1_pll_40m);
+ clk_set_rate(dram_apb_pre_div, 20000000);
+ clk_disable_unprepare(sys1_pll_100m);
+ clk_disable_unprepare(sys1_pll_40m);
+ clk_disable_unprepare(dram_alt_root);
+
+ /* change the NOC rate */
+ rate = clk_get_rate(noc_div);
+ if (rate == 0) {
+ WARN_ON(1);
+ return;
+ }
+ clk_set_rate(noc_div, rate / 5);
+ }
+ rate = clk_get_rate(ahb_div);
+ if (rate == 0) {
+ WARN_ON(1);
+ return;
+ }
+ clk_set_rate(ahb_div, rate / 6);
+ clk_set_parent(main_axi_src, osc_25m);
+ }
+
+ low_bus_freq_mode = 0;
+ audio_bus_freq_mode = 1;
+ cur_bus_freq_mode = BUS_FREQ_AUDIO;
+ } else {
+ if (cur_bus_freq_mode == BUS_FREQ_HIGH) {
+ if (of_machine_is_compatible("fsl,imx8mq")) {
+ if (imx8_get_soc_revision() < IMX_CHIP_REVISION_2_1) {
+ update_bus_freq(LOW_BUS_FREQ_667MTS);
+
+ /*
+ * the dram_apb and dram_core clk rate is changed
+ * in ATF side, below two lines of code is just used
+ * to upate the clock tree info in kernel side.
+ */
+ clk_set_rate(dram_apb_pre_div, 160000000);
+ clk_get_rate(dram_pll_clk);
+ } else {
+ /* prepare the necessary clk before frequency change */
+ clk_prepare_enable(sys1_pll_40m);
+ clk_prepare_enable(dram_alt_root);
+ clk_prepare_enable(sys1_pll_100m);
+
+ update_bus_freq(LOW_BUS_FREQ_100MTS);
+
+ clk_set_parent(dram_alt_src, sys1_pll_100m);
+ clk_set_parent(dram_core_clk, dram_alt_root);
+ clk_set_parent(dram_apb_src, sys1_pll_40m);
+ clk_set_rate(dram_apb_pre_div, 20000000);
+ clk_disable_unprepare(sys1_pll_100m);
+ clk_disable_unprepare(sys1_pll_40m);
+ clk_disable_unprepare(dram_alt_root);
+ }
+ /* reduce the NOC & bus clock */
+ rate = clk_get_rate(noc_div);
+ if (rate == 0) {
+ WARN_ON(1);
+ return;
+ }
+ clk_set_rate(noc_div, rate / 8);
+ } else {
+ /* prepare the necessary clk before frequency change */
+ clk_prepare_enable(sys1_pll_40m);
+ clk_prepare_enable(dram_alt_root);
+ clk_prepare_enable(sys1_pll_100m);
+
+ update_bus_freq(LOW_BUS_FREQ_100MTS);
+
+ /* correct the clock tree info */
+ clk_set_parent(dram_alt_src, sys1_pll_100m);
+ clk_set_parent(dram_core_clk, dram_alt_root);
+ clk_set_parent(dram_apb_src, sys1_pll_40m);
+ clk_set_rate(dram_apb_pre_div, 20000000);
+ clk_disable_unprepare(sys1_pll_100m);
+ clk_disable_unprepare(sys1_pll_40m);
+ clk_disable_unprepare(dram_alt_root);
+
+ /* change the NOC clock rate */
+ rate = clk_get_rate(noc_div);
+ if (rate == 0) {
+ WARN_ON(1);
+ return;
+ }
+ clk_set_rate(noc_div, rate / 5);
+ }
+
+ rate = clk_get_rate(ahb_div);
+ if (rate == 0) {
+ WARN_ON(1);
+ return;
+ }
+ clk_set_rate(ahb_div, rate / 6);
+ clk_set_parent(main_axi_src, osc_25m);
+ }
+
+ low_bus_freq_mode = 1;
+ audio_bus_freq_mode = 0;
+ cur_bus_freq_mode = BUS_FREQ_LOW;
+ }
+
+ if (audio_bus_freq_mode)
+ printk(KERN_DEBUG "ddrc freq set to audio bus mode\n");
+ if (low_bus_freq_mode)
+ printk(KERN_DEBUG "ddrc freq set to low bus mode\n");
+}
+
+static void reduce_bus_freq_handler(struct work_struct *work)
+{
+ mutex_lock(&bus_freq_mutex);
+
+ if (!cancel_reduce_bus_freq)
+ reduce_bus_freq();
+
+ mutex_unlock(&bus_freq_mutex);
+}
+
+static int set_low_bus_freq(void)
+{
+ if (busfreq_suspended)
+ return 0;
+
+ if (!bus_freq_scaling_initialized || !bus_freq_scaling_is_active)
+ return 0;
+
+ cancel_reduce_bus_freq = false;
+
+ /*
+ * check to see if we need to got from low bus
+ * freq mode to audio bus freq mode.
+ * If so, the change needs to be done immediately.
+ */
+ if (audio_bus_count && low_bus_freq_mode)
+ reduce_bus_freq();
+ else
+ schedule_delayed_work(&low_bus_freq_handler,
+ usecs_to_jiffies(1000000));
+
+ return 0;
+}
+
+static inline void cancel_low_bus_freq_handler(void)
+{
+ cancel_delayed_work(&low_bus_freq_handler);
+ cancel_reduce_bus_freq = true;
+}
+
+static int set_high_bus_freq(int high_bus_freq)
+{
+ if (bus_freq_scaling_initialized || bus_freq_scaling_is_active)
+ cancel_low_bus_freq_handler();
+
+ if (busfreq_suspended)
+ return 0;
+
+ if (!bus_freq_scaling_initialized || !bus_freq_scaling_is_active)
+ return 0;
+
+ if (high_bus_freq_mode)
+ return 0;
+
+ if (of_machine_is_compatible("fsl,imx8mq")) {
+ if (imx8_get_soc_revision() < IMX_CHIP_REVISION_2_1) {
+ /* switch the DDR freqeuncy */
+ update_bus_freq(HIGH_FREQ_3200MTS);
+
+ clk_set_rate(dram_apb_pre_div, 200000000);
+ clk_get_rate(dram_pll_clk);
+ } else {
+ /* enable the clks needed in frequency */
+ clk_prepare_enable(sys1_pll_800m);
+ clk_prepare_enable(dram_pll_clk);
+
+ /* switch the DDR freqeuncy */
+ update_bus_freq(HIGH_FREQ_3200MTS);
+
+ /* correct the clock tree info */
+ clk_set_parent(dram_apb_src, sys1_pll_800m);
+ clk_set_rate(dram_apb_pre_div, 160000000);
+ clk_set_parent(dram_core_clk, dram_pll_clk);
+ clk_disable_unprepare(sys1_pll_800m);
+ clk_disable_unprepare(dram_pll_clk);
+ }
+ clk_set_rate(noc_div, 800000000);
+ } else {
+ /* enable the clks needed in frequency */
+ clk_prepare_enable(sys1_pll_800m);
+ clk_prepare_enable(dram_pll_clk);
+
+ /* switch the DDR freqeuncy */
+ update_bus_freq(HIGH_FREQ_3200MTS);
+
+ /* correct the clock tree info */
+ clk_set_parent(dram_apb_src, sys1_pll_800m);
+ clk_set_rate(dram_apb_pre_div, 160000000);
+ clk_set_parent(dram_core_clk, dram_pll_clk);
+ clk_disable_unprepare(sys1_pll_800m);
+ clk_disable_unprepare(dram_pll_clk);
+ clk_set_rate(noc_div, 750000000);
+ }
+
+ clk_set_rate(ahb_div, 133333333);
+ clk_set_parent(main_axi_src, sys2_pll_333m);
+
+ high_bus_freq_mode = 1;
+ audio_bus_freq_mode = 0;
+ low_bus_freq_mode = 0;
+ cur_bus_freq_mode = BUS_FREQ_HIGH;
+
+ if (high_bus_freq_mode)
+ printk(KERN_DEBUG "ddrc freq set to high bus mode\n");
+
+ return 0;
+}
+
+void request_bus_freq(enum bus_freq_mode mode)
+{
+ mutex_lock(&bus_freq_mutex);
+
+ if (mode == BUS_FREQ_HIGH)
+ high_bus_count++;
+ else if (mode == BUS_FREQ_AUDIO)
+ audio_bus_count++;
+ else if (mode == BUS_FREQ_LOW)
+ low_bus_count++;
+
+ if (busfreq_suspended || !bus_freq_scaling_initialized ||
+ !bus_freq_scaling_is_active) {
+ mutex_unlock(&bus_freq_mutex);
+ return;
+ }
+
+ cancel_low_bus_freq_handler();
+
+ if ((mode == BUS_FREQ_HIGH) && (!high_bus_freq_mode)) {
+ set_high_bus_freq(1);
+ mutex_unlock(&bus_freq_mutex);
+ return;
+ }
+
+ if ((mode == BUS_FREQ_AUDIO) && (!high_bus_freq_mode) &&
+ (!audio_bus_freq_mode)) {
+ set_low_bus_freq();
+ mutex_unlock(&bus_freq_mutex);
+ return;
+ }
+
+ mutex_unlock(&bus_freq_mutex);
+}
+EXPORT_SYMBOL(request_bus_freq);
+
+void release_bus_freq(enum bus_freq_mode mode)
+{
+ mutex_lock(&bus_freq_mutex);
+ if (mode == BUS_FREQ_HIGH) {
+ if (high_bus_count == 0) {
+ dev_err(busfreq_dev, "high bus count mismatch!\n");
+ dump_stack();
+ mutex_unlock(&bus_freq_mutex);
+ return;
+ }
+ high_bus_count--;
+ } else if (mode == BUS_FREQ_AUDIO) {
+ if (audio_bus_count == 0) {
+ dev_err(busfreq_dev, "audio bus count mismatch!\n");
+ dump_stack();
+ mutex_unlock(&bus_freq_mutex);
+ return;
+ }
+ audio_bus_count--;
+ } else if (mode == BUS_FREQ_LOW) {
+ if (low_bus_count == 0) {
+ dev_err(busfreq_dev, "low bus count mismatch!\n");
+ dump_stack();
+ mutex_unlock(&bus_freq_mutex);
+ return;
+ }
+ low_bus_count--;
+ }
+
+ if (busfreq_suspended || !bus_freq_scaling_initialized ||
+ !bus_freq_scaling_is_active) {
+ mutex_unlock(&bus_freq_mutex);
+ return;
+ }
+
+ if ((!audio_bus_freq_mode) && (high_bus_count == 0) &&
+ (audio_bus_count != 0)) {
+ set_low_bus_freq();
+ mutex_unlock(&bus_freq_mutex);
+ return;
+ }
+
+ if ((!low_bus_freq_mode) && (high_bus_count == 0) &&
+ (audio_bus_count == 0)) {
+ set_low_bus_freq();
+ mutex_unlock(&bus_freq_mutex);
+ return;
+ }
+
+ mutex_unlock(&bus_freq_mutex);
+}
+EXPORT_SYMBOL(release_bus_freq);
+
+int get_bus_freq_mode(void)
+{
+ return cur_bus_freq_mode;
+}
+EXPORT_SYMBOL(get_bus_freq_mode);
+
+static void bus_freq_daemon_handler(struct work_struct *work)
+{
+ mutex_lock(&bus_freq_mutex);
+ if ((!low_bus_freq_mode) && (high_bus_count == 0) &&
+ (audio_bus_count == 0))
+ set_low_bus_freq();
+ mutex_unlock(&bus_freq_mutex);
+}
+
+static ssize_t bus_freq_scaling_enable_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ if (bus_freq_scaling_is_active)
+ return sprintf(buf, "Bus frequency scaling is enabled\n");
+ else
+ return sprintf(buf, "Bus frequency scaling is disabled\n");
+}
+
+static ssize_t bus_freq_scaling_enable_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+ if (strncmp(buf, "1", 1) == 0) {
+ bus_freq_scaling_is_active = 1;
+ set_high_bus_freq(1);
+ /*
+ * We set bus freq to higher at the beginning,
+ * so we use this daemon thread to make sure system
+ * can enter low bus mode if there is no high bus request pending
+ */
+ schedule_delayed_work(&bus_freq_daemon,
+ usecs_to_jiffies(5000000));
+ } else if (strncmp(buf, "0", 1) == 0) {
+ if (bus_freq_scaling_is_active)
+ set_high_bus_freq(1);
+ bus_freq_scaling_is_active = 0;
+ }
+ return size;
+}
+
+static int bus_freq_pm_notify(struct notifier_block *nb, unsigned long event,
+ void *dummy)
+{
+ mutex_lock(&bus_freq_mutex);
+
+ if (event == PM_SUSPEND_PREPARE) {
+ high_bus_count++;
+ set_high_bus_freq(1);
+ busfreq_suspended = 1;
+ } else if (event == PM_POST_SUSPEND) {
+ busfreq_suspended = 0;
+ high_bus_count--;
+ schedule_delayed_work(&bus_freq_daemon,
+ usecs_to_jiffies(5000000));
+ }
+
+ mutex_unlock(&bus_freq_mutex);
+
+ return NOTIFY_OK;
+}
+
+static int busfreq_reboot_notifier_event(struct notifier_block *this,
+ unsigned long event, void *ptr)
+{
+ /* System is rebooting. Set the system into high_bus_freq_mode. */
+ request_bus_freq(BUS_FREQ_HIGH);
+
+ return 0;
+}
+
+static struct notifier_block imx_bus_freq_pm_notifier = {
+ .notifier_call = bus_freq_pm_notify,
+};
+
+static struct notifier_block imx_busfreq_reboot_notifier = {
+ .notifier_call = busfreq_reboot_notifier_event,
+};
+
+static DEVICE_ATTR(enable, 0644, bus_freq_scaling_enable_show,
+ bus_freq_scaling_enable_store);
+
+static int init_busfreq_irq(struct platform_device *busfreq_pdev)
+{
+ struct device *dev = &busfreq_pdev->dev;
+ u32 cpu;
+ int err;
+
+ for_each_online_cpu(cpu) {
+ int irq;
+ /*
+ * set up a reserved interrupt to get all
+ * the active cores into a WFE state before
+ * changing the DDR frequency.
+ */
+ irq = platform_get_irq(busfreq_pdev, cpu);
+ err = request_irq(irq, wait_in_wfe_irq,
+ IRQF_PERCPU, "ddrc", NULL);
+ if (err) {
+ dev_err(dev, "Busfreq request irq failed %d, err = %d\n",
+ irq, err);
+ return err;
+ }
+ err = irq_set_affinity(irq, cpumask_of(cpu));
+ if (err) {
+ dev_err(dev, "busfreq can't set irq affinity irq = %d\n", irq);
+ return err;
+ }
+ }
+
+ return 0;
+}
+
+static int imx8mq_init_busfreq_clk(struct platform_device *pdev)
+{
+ dram_pll_clk = devm_clk_get(&pdev->dev, "dram_pll");
+ sys1_pll_800m = devm_clk_get(&pdev->dev, "sys1_pll_800m");
+ sys1_pll_400m = devm_clk_get(&pdev->dev, "sys1_pll_400m");
+ sys1_pll_100m = devm_clk_get(&pdev->dev, "sys1_pll_100m");
+ sys1_pll_40m = devm_clk_get(&pdev->dev, "sys1_pll_40m");
+ dram_alt_src = devm_clk_get(&pdev->dev, "dram_alt_src");
+ dram_alt_root = devm_clk_get(&pdev->dev, "dram_alt_root");
+ dram_core_clk = devm_clk_get(&pdev->dev, "dram_core");
+ dram_apb_src = devm_clk_get(&pdev->dev, "dram_apb_src");
+ dram_apb_pre_div = devm_clk_get(&pdev->dev, "dram_apb_pre_div");
+ noc_div = devm_clk_get(&pdev->dev, "noc_div");
+ ahb_div = devm_clk_get(&pdev->dev, "ahb_div");
+ main_axi_src = devm_clk_get(&pdev->dev, "main_axi_src");
+ osc_25m = devm_clk_get(&pdev->dev, "osc_25m");
+ sys2_pll_333m = devm_clk_get(&pdev->dev, "sys2_pll_333m");
+
+ if (IS_ERR(dram_pll_clk) || IS_ERR(sys1_pll_400m) || IS_ERR(sys1_pll_100m) ||
+ IS_ERR(sys1_pll_40m) || IS_ERR(dram_alt_src) || IS_ERR(dram_alt_root) ||
+ IS_ERR(dram_core_clk) || IS_ERR(dram_apb_src) || IS_ERR(dram_apb_pre_div)
+ || IS_ERR(noc_div) || IS_ERR(main_axi_src) || IS_ERR(ahb_div)
+ || IS_ERR(osc_25m) || IS_ERR(sys2_pll_333m)) {
+ dev_err(&pdev->dev, "failed to get busfreq clk\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int imx8mm_init_busfreq_clk(struct platform_device *pdev)
+{
+ dram_pll_clk = devm_clk_get(&pdev->dev, "dram_pll");
+ dram_alt_src = devm_clk_get(&pdev->dev, "dram_alt_src");
+ dram_alt_root = devm_clk_get(&pdev->dev, "dram_alt_root");
+ dram_core_clk = devm_clk_get(&pdev->dev, "dram_core");
+ dram_apb_src = devm_clk_get(&pdev->dev, "dram_apb_src");
+ dram_apb_pre_div = devm_clk_get(&pdev->dev, "dram_apb_pre_div");
+ sys1_pll_800m = devm_clk_get(&pdev->dev, "sys_pll1_800m");
+ sys1_pll_100m = devm_clk_get(&pdev->dev, "sys_pll1_100m");
+ sys1_pll_40m = devm_clk_get(&pdev->dev, "sys_pll1_40m");
+ noc_div = devm_clk_get(&pdev->dev, "noc_div");
+ ahb_div = devm_clk_get(&pdev->dev, "ahb_div");
+ main_axi_src = devm_clk_get(&pdev->dev, "main_axi_src");
+ osc_25m = devm_clk_get(&pdev->dev, "osc_24m");
+ sys2_pll_333m = devm_clk_get(&pdev->dev, "sys_pll2_333m");
+
+ if (IS_ERR(dram_pll_clk) || IS_ERR(dram_alt_src) || IS_ERR(dram_alt_root) ||
+ IS_ERR(dram_core_clk) || IS_ERR(dram_apb_src) || IS_ERR(dram_apb_pre_div) ||
+ IS_ERR(sys1_pll_800m) || IS_ERR(sys1_pll_100m) || IS_ERR(sys1_pll_40m) ||
+ IS_ERR(osc_25m) || IS_ERR(noc_div) || IS_ERR(main_axi_src) || IS_ERR(ahb_div) ||
+ IS_ERR(sys2_pll_333m)) {
+ dev_err(&pdev->dev, "failed to get busfreq clk\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+/*!
+ * This is the probe routine for the bus frequency driver.
+ *
+ * @param pdev The platform device structure
+ *
+ * @return The function returns 0 on success
+ *
+ */
+static int busfreq_probe(struct platform_device *pdev)
+{
+ int err;
+
+ busfreq_dev = &pdev->dev;
+
+ /* get the clock for DDRC */
+ if (of_machine_is_compatible("fsl,imx8mq"))
+ err = imx8mq_init_busfreq_clk(pdev);
+ else
+ err = imx8mm_init_busfreq_clk(pdev);
+
+ if (err) {
+ dev_err(busfreq_dev, "init clk failed\n");
+ return err;
+ }
+
+ /* init the irq used for ddr frequency change */
+ err = init_busfreq_irq(pdev);
+ if (err) {
+ dev_err(busfreq_dev, "init busfreq irq failed!\n");
+ return err;
+ }
+
+ /* create the sysfs file */
+ err = sysfs_create_file(&busfreq_dev->kobj, &dev_attr_enable.attr);
+ if (err) {
+ dev_err(busfreq_dev,
+ "Unable to register sysdev entry for BUSFREQ");
+ return err;
+ }
+
+ high_bus_freq_mode = 1;
+ low_bus_freq_mode = 0;
+ audio_bus_freq_mode = 0;
+ cur_bus_freq_mode = BUS_FREQ_HIGH;
+
+ bus_freq_scaling_is_active = 1;
+ bus_freq_scaling_initialized = 1;
+
+ INIT_DELAYED_WORK(&low_bus_freq_handler, reduce_bus_freq_handler);
+ INIT_DELAYED_WORK(&bus_freq_daemon, bus_freq_daemon_handler);
+ register_pm_notifier(&imx_bus_freq_pm_notifier);
+ register_reboot_notifier(&imx_busfreq_reboot_notifier);
+
+ /* enter low bus mode if no high speed device enabled */
+ schedule_delayed_work(&bus_freq_daemon, msecs_to_jiffies(10000));
+
+ return 0;
+}
+
+static const struct of_device_id imx_busfreq_ids[] = {
+ { .compatible = "fsl,imx_busfreq", },
+ { /*sentinel */}
+};
+
+static struct platform_driver busfreq_driver = {
+ .driver = {
+ .name = "imx_busfreq",
+ .owner = THIS_MODULE,
+ .of_match_table = imx_busfreq_ids,
+ },
+ .probe = busfreq_probe,
+};
+
+/*!
+ * Initialise the busfreq_driver.
+ *
+ * @return The function always returns 0.
+ */
+static int __init busfreq_init(void)
+{
+ if (platform_driver_register(&busfreq_driver) != 0)
+ return -ENODEV;
+
+ printk(KERN_INFO "Bus freq driver module loaded\n");
+
+ return 0;
+}
+
+static void __exit busfreq_cleanup(void)
+{
+ sysfs_remove_file(&busfreq_dev->kobj, &dev_attr_enable.attr);
+
+ /* Unregister the device structure */
+ platform_driver_unregister(&busfreq_driver);
+ bus_freq_scaling_initialized = 0;
+}
+
+module_init(busfreq_init);
+module_exit(busfreq_cleanup);
+
+MODULE_AUTHOR("NXP Semiconductor, Inc.");
+MODULE_DESCRIPTION("Busfreq driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/soc/imx/gpc-psci.c b/drivers/soc/imx/gpc-psci.c
new file mode 100644
index 000000000000..d3867e18ee23
--- /dev/null
+++ b/drivers/soc/imx/gpc-psci.c
@@ -0,0 +1,425 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017 NXP
+ *
+ * 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/arm-smccc.h>
+#include <linux/clk.h>
+#include <linux/cpumask.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/irqchip.h>
+#include <linux/irqchip/arm-gic.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/consumer.h>
+#include <linux/pm_domain.h>
+#include <soc/imx/fsl_sip.h>
+
+#define GPC_MAX_IRQS (4 * 32)
+
+struct imx_gpc_pm_domain {
+ const char name[30];
+ struct device *dev;
+ struct generic_pm_domain pd;
+ u32 gpc_domain_id;
+ struct clk **clks;
+ unsigned int num_clks;
+ struct regulator *reg;
+};
+
+enum imx_gpc_pm_domain_state {
+ GPC_PD_STATE_OFF,
+ GPC_PD_STATE_ON,
+};
+
+#define to_imx_gpc_pm_domain(_genpd) container_of(_genpd, struct imx_gpc_pm_domain, pd)
+
+static DEFINE_SPINLOCK(gpc_psci_lock);
+static DEFINE_MUTEX(gpc_pd_mutex);
+
+static void imx_gpc_psci_irq_unmask(struct irq_data *d)
+{
+ struct arm_smccc_res res;
+
+ spin_lock(&gpc_psci_lock);
+ arm_smccc_smc(FSL_SIP_GPC, FSL_SIP_CONFIG_GPC_UNMASK, d->hwirq,
+ 0, 0, 0, 0, 0, &res);
+ spin_unlock(&gpc_psci_lock);
+
+ irq_chip_unmask_parent(d);
+}
+
+static void imx_gpc_psci_irq_mask(struct irq_data *d)
+{
+ struct arm_smccc_res res;
+
+ spin_lock(&gpc_psci_lock);
+ arm_smccc_smc(FSL_SIP_GPC, FSL_SIP_CONFIG_GPC_MASK, d->hwirq,
+ 0, 0, 0, 0, 0, &res);
+ spin_unlock(&gpc_psci_lock);
+
+ irq_chip_mask_parent(d);
+}
+static int imx_gpc_psci_irq_set_wake(struct irq_data *d, unsigned int on)
+{
+ struct arm_smccc_res res;
+
+ spin_lock(&gpc_psci_lock);
+ arm_smccc_smc(FSL_SIP_GPC, FSL_SIP_CONFIG_GPC_SET_WAKE, d->hwirq,
+ on, 0, 0, 0, 0, &res);
+ spin_unlock(&gpc_psci_lock);
+
+ return 0;
+}
+
+static int imx_gpc_psci_irq_set_affinity(struct irq_data *d,
+ const struct cpumask *dest, bool force)
+{
+ /* parse the cpu of irq affinity */
+ struct arm_smccc_res res;
+ int cpu = cpumask_any_and(dest, cpu_online_mask);
+
+ irq_chip_set_affinity_parent(d, dest, force);
+
+ spin_lock(&gpc_psci_lock);
+ arm_smccc_smc(FSL_SIP_GPC, 0x4, d->hwirq,
+ cpu, 0, 0, 0, 0, &res);
+ spin_unlock(&gpc_psci_lock);
+
+ return 0;
+}
+
+static struct irq_chip imx_gpc_psci_chip = {
+ .name = "GPC-PSCI",
+ .irq_eoi = irq_chip_eoi_parent,
+ .irq_mask = imx_gpc_psci_irq_mask,
+ .irq_unmask = imx_gpc_psci_irq_unmask,
+ .irq_retrigger = irq_chip_retrigger_hierarchy,
+ .irq_set_wake = imx_gpc_psci_irq_set_wake,
+ .irq_set_affinity = imx_gpc_psci_irq_set_affinity,
+};
+
+static int imx_gpc_psci_domain_translate(struct irq_domain *d,
+ struct irq_fwspec *fwspec,
+ unsigned long *hwirq,
+ unsigned int *type)
+{
+ if (is_of_node(fwspec->fwnode)) {
+ if (fwspec->param_count != 3)
+ return -EINVAL;
+
+ /* No PPI should point to this domain */
+ if (fwspec->param[0] != 0)
+ return -EINVAL;
+
+ *hwirq = fwspec->param[1];
+ *type = fwspec->param[2];
+ return 0;
+ }
+
+ return -EINVAL;
+}
+
+static int imx_gpc_psci_domain_alloc(struct irq_domain *domain,
+ unsigned int irq,
+ unsigned int nr_irqs, void *data)
+{
+ struct irq_fwspec *fwspec = data;
+ struct irq_fwspec parent_fwspec;
+ irq_hw_number_t hwirq;
+ int i;
+
+ if (fwspec->param_count != 3)
+ return -EINVAL; /* Not GIC compliant */
+ if (fwspec->param[0] != 0)
+ return -EINVAL; /* No PPI should point to this domain */
+
+ hwirq = fwspec->param[1];
+ if (hwirq >= GPC_MAX_IRQS)
+ return -EINVAL; /* Can't deal with this */
+
+ for (i = 0; i < nr_irqs; i++)
+ irq_domain_set_hwirq_and_chip(domain, irq + i, hwirq + i,
+ &imx_gpc_psci_chip, NULL);
+
+ parent_fwspec = *fwspec;
+ parent_fwspec.fwnode = domain->parent->fwnode;
+
+ return irq_domain_alloc_irqs_parent(domain, irq, nr_irqs,
+ &parent_fwspec);
+}
+
+static struct irq_domain_ops imx_gpc_psci_domain_ops = {
+ .translate = imx_gpc_psci_domain_translate,
+ .alloc = imx_gpc_psci_domain_alloc,
+ .free = irq_domain_free_irqs_common,
+};
+
+static int __init imx_gpc_psci_init(struct device_node *node,
+ struct device_node *parent)
+{
+ struct irq_domain *parent_domain, *domain;
+
+ if (!parent) {
+ pr_err("%s: no parent, giving up\n", node->full_name);
+ return -ENODEV;
+ }
+
+ parent_domain = irq_find_host(parent);
+ if (!parent_domain) {
+ pr_err("%s: unable to obtain parent domain\n", node->full_name);
+ return -ENXIO;
+ }
+
+ domain = irq_domain_add_hierarchy(parent_domain, 0, GPC_MAX_IRQS,
+ node, &imx_gpc_psci_domain_ops,
+ NULL);
+ if (!domain)
+ return -ENOMEM;
+
+ return 0;
+}
+IRQCHIP_DECLARE(imx_gpc_psci, "fsl,imx8mq-gpc", imx_gpc_psci_init);
+
+static int imx_gpc_pd_power_on(struct generic_pm_domain *domain)
+{
+ struct imx_gpc_pm_domain *pd = to_imx_gpc_pm_domain(domain);
+ struct arm_smccc_res res;
+ int index, ret = 0;
+
+ /* power on the external supply */
+ if (pd->reg) {
+ ret = regulator_enable(pd->reg);
+ if (ret) {
+ dev_warn(pd->dev, "failed to power up the reg%d\n", ret);
+ return ret;
+ }
+ }
+
+ /* enable the necessary clks needed by the power domain */
+ if (pd->num_clks) {
+ for (index = 0; index < pd->num_clks; index++)
+ clk_prepare_enable(pd->clks[index]);
+ }
+
+ mutex_lock(&gpc_pd_mutex);
+ arm_smccc_smc(FSL_SIP_GPC, FSL_SIP_CONFIG_GPC_PM_DOMAIN, pd->gpc_domain_id,
+ GPC_PD_STATE_ON, 0, 0, 0, 0, &res);
+ mutex_unlock(&gpc_pd_mutex);
+
+ return 0;
+}
+
+static int imx_gpc_pd_power_off(struct generic_pm_domain *domain)
+{
+ struct imx_gpc_pm_domain *pd = to_imx_gpc_pm_domain(domain);
+ struct arm_smccc_res res;
+ int index, ret = 0;
+
+ mutex_lock(&gpc_pd_mutex);
+ arm_smccc_smc(FSL_SIP_GPC, FSL_SIP_CONFIG_GPC_PM_DOMAIN, pd->gpc_domain_id,
+ GPC_PD_STATE_OFF, 0, 0, 0, 0, &res);
+ mutex_unlock(&gpc_pd_mutex);
+
+ /* power off the external supply */
+ if (pd->reg) {
+ ret = regulator_disable(pd->reg);
+ if (ret) {
+ dev_warn(pd->dev, "failed to power off the reg%d\n", ret);
+ return ret;
+ }
+ }
+
+ /* disable the necessary clks when power domain on finished */
+ if (pd->num_clks) {
+ for (index = 0; index < pd->num_clks; index++)
+ clk_disable_unprepare(pd->clks[index]);
+ }
+
+ return ret;
+};
+
+static int imx8m_pd_clk_init(struct device_node *np,
+ struct imx_gpc_pm_domain *domain)
+{
+ struct property *pp;
+ struct clk **clks;
+ int index;
+
+ pp = of_find_property(np, "clocks", NULL);
+ if (pp)
+ domain->num_clks = pp->length / 8;
+ else
+ domain->num_clks = 0;
+
+ if (domain->num_clks) {
+ clks = kcalloc(domain->num_clks, sizeof(*clks), GFP_KERNEL);
+ if (!clks) {
+ domain->num_clks = 0;
+ domain->clks = NULL;
+ return -ENOMEM;
+ }
+
+ domain->clks = clks;
+ }
+
+ for (index = 0; index < domain->num_clks; index++) {
+ clks[index] = of_clk_get(np, index);
+ if (IS_ERR(clks[index])) {
+ for (index = 0; index < domain->num_clks; index++) {
+ if (!IS_ERR(clks[index]))
+ clk_put(clks[index]);
+ }
+
+ domain->num_clks = 0;
+ domain->clks = NULL;
+ kfree(clks);
+ pr_warn("imx8m domain clock init failed\n");
+ return -ENODEV;
+ }
+ }
+
+ return 0;
+}
+
+static int imx8m_add_subdomain(struct device_node *parent,
+ struct generic_pm_domain *parent_pd)
+{
+ struct device_node *child_node;
+ struct imx_gpc_pm_domain *child_domain;
+ int ret = 0;
+
+ /* add each of the child domain of parent */
+ for_each_child_of_node(parent, child_node) {
+ if (!of_device_is_available(child_node))
+ continue;
+
+ child_domain = kzalloc(sizeof(*child_domain), GFP_KERNEL);
+ if (!child_domain)
+ return -ENOMEM;
+
+ ret = of_property_read_string(child_node, "domain-name",
+ &child_domain->pd.name);
+ if (ret)
+ goto exit;
+
+ ret = of_property_read_u32(child_node, "domain-id",
+ &child_domain->gpc_domain_id);
+ if (ret)
+ goto exit;
+
+ child_domain->pd.power_off = imx_gpc_pd_power_off;
+ child_domain->pd.power_on = imx_gpc_pd_power_on;
+ /* no reg for subdomains */
+ child_domain->reg = NULL;
+
+ imx8m_pd_clk_init(child_node, child_domain);
+
+ /* power domains as off at boot */
+ pm_genpd_init(&child_domain->pd, NULL, true);
+
+ /* add subdomain of parent power domain */
+ pm_genpd_add_subdomain(parent_pd, &child_domain->pd);
+
+ ret = of_genpd_add_provider_simple(child_node,
+ &child_domain->pd);
+ if (ret)
+ pr_err("failed to add subdomain\n");
+ }
+
+ return 0;
+exit:
+ kfree(child_domain);
+ return ret;
+};
+
+static int imx_gpc_pm_domain_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct device_node *np = dev->of_node;
+ struct imx_gpc_pm_domain *imx_pm_domain;
+ int ret = 0;
+
+ if (!np) {
+ dev_err(dev, "power domain device tree node not found\n");
+ return -ENODEV;
+ }
+
+ imx_pm_domain = devm_kzalloc(dev, sizeof(*imx_pm_domain), GFP_KERNEL);
+ if (!imx_pm_domain)
+ return -ENOMEM;
+ imx_pm_domain->dev = dev;
+
+ ret = of_property_read_string(np, "domain-name", &imx_pm_domain->pd.name);
+ if (ret) {
+ dev_err(dev, "get domain name failed\n");
+ return -EINVAL;
+ }
+
+ ret = of_property_read_u32(np, "domain-id", &imx_pm_domain->gpc_domain_id);
+ if (ret) {
+ dev_err(dev, "get domain id failed\n");
+ return -EINVAL;
+ }
+
+ imx_pm_domain->reg = devm_regulator_get_optional(dev, "power");
+ if (IS_ERR(imx_pm_domain->reg)) {
+ if (PTR_ERR(imx_pm_domain->reg) == -EPROBE_DEFER)
+ return -EPROBE_DEFER;
+
+ imx_pm_domain->reg = NULL;
+ }
+
+ imx8m_pd_clk_init(np, imx_pm_domain);
+
+ imx_pm_domain->pd.power_off = imx_gpc_pd_power_off;
+ imx_pm_domain->pd.power_on = imx_gpc_pd_power_on;
+ /* all power domains as off at boot */
+ pm_genpd_init(&imx_pm_domain->pd, NULL, true);
+
+ ret = of_genpd_add_provider_simple(np,
+ &imx_pm_domain->pd);
+
+ /* add subdomain */
+ ret = imx8m_add_subdomain(np, &imx_pm_domain->pd);
+ if (ret)
+ dev_warn(dev, "please check the child power domain init\n");
+
+ return 0;
+}
+
+static const struct of_device_id imx_gpc_pm_domain_ids[] = {
+ {.compatible = "fsl,imx8mq-pm-domain"},
+ {.compatible = "fsl,imx8mm-pm-domain"},
+ {},
+};
+
+static struct platform_driver imx_gpc_pm_domain_driver = {
+ .driver = {
+ .name = "imx8m_gpc_pm_domain",
+ .owner = THIS_MODULE,
+ .of_match_table = imx_gpc_pm_domain_ids,
+ },
+ .probe = imx_gpc_pm_domain_probe,
+};
+
+module_platform_driver(imx_gpc_pm_domain_driver);
+
+MODULE_AUTHOR("NXP");
+MODULE_DESCRIPTION("NXP i.MX8M GPC power domain driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/soc/imx/gpc.c b/drivers/soc/imx/gpc.c
index 3a12123de466..c95fa4071850 100644
--- a/drivers/soc/imx/gpc.c
+++ b/drivers/soc/imx/gpc.c
@@ -19,8 +19,15 @@
#include <linux/regmap.h>
#include <linux/regulator/consumer.h>
+#include <soc/imx/revision.h>
+
#define GPC_CNTR 0x000
+#define GPC_CNTR_PCIE_PHY_PDU_SHIFT 0x7
+#define GPC_CNTR_PCIE_PHY_PDN_SHIFT 0x6
+#define PGC_PCIE_PHY_CTRL 0x200
+#define PGC_PCIE_PHY_PDN_EN 0x1
+
#define GPC_PGC_CTRL_OFFS 0x0
#define GPC_PGC_PUPSCR_OFFS 0x4
#define GPC_PGC_PDNSCR_OFFS 0x8
@@ -29,6 +36,10 @@
#define GPC_PGC_PCI_PDN 0x200
#define GPC_PGC_PCI_SR 0x20c
+#define GPC_PGC_DISP_PGCR_OFFSET 0x240
+#define GPC_PGC_DISP_PUPSCR_OFFSET 0x244
+#define GPC_PGC_DISP_PDNSCR_OFFSET 0x248
+#define GPC_PGC_DISP_SR_OFFSET 0x24c
#define GPC_PGC_GPU_PDN 0x260
#define GPC_PGC_GPU_PUPSCR 0x264
@@ -38,13 +49,30 @@
#define GPC_PGC_DISP_PDN 0x240
#define GPC_PGC_DISP_SR 0x24c
-#define GPU_VPU_PUP_REQ BIT(1)
-#define GPU_VPU_PDN_REQ BIT(0)
-
-#define GPC_CLK_MAX 6
+#define GPC_CLK_MAX 10
+#define DEFAULT_IPG_RATE 66000000
+#define GPC_PU_UP_DELAY_MARGIN 2
#define PGC_DOMAIN_FLAG_NO_PD BIT(0)
+static void __iomem *gpc_base;
+static struct clk *ipg_clk;
+
+static inline bool cpu_is_imx6sx(void)
+{
+ return of_machine_is_compatible("fsl,imx6sx");
+}
+
+static inline bool cpu_is_imx6sl(void)
+{
+ return of_machine_is_compatible("fsl,imx6sl");
+}
+
+static inline bool cpu_is_imx6q(void)
+{
+ return of_machine_is_compatible("fsl,imx6q");
+}
+
struct imx_pm_domain {
struct generic_pm_domain base;
struct regmap *regmap;
@@ -63,15 +91,12 @@ to_imx_pm_domain(struct generic_pm_domain *genpd)
return container_of(genpd, struct imx_pm_domain, base);
}
-static int imx6_pm_domain_power_off(struct generic_pm_domain *genpd)
+static void _imx6_pm_domain_power_off(struct generic_pm_domain *genpd)
{
struct imx_pm_domain *pd = to_imx_pm_domain(genpd);
int iso, iso2sw;
u32 val;
- if (pd->flags & PGC_DOMAIN_FLAG_NO_PD)
- return -EBUSY;
-
/* Read ISO and ISO2SW power down delays */
regmap_read(pd->regmap, pd->reg_offs + GPC_PGC_PDNSCR_OFFS, &val);
iso = val & 0x3f;
@@ -88,25 +113,34 @@ static int imx6_pm_domain_power_off(struct generic_pm_domain *genpd)
/* Wait ISO + ISO2SW IPG clock cycles */
udelay(DIV_ROUND_UP(iso + iso2sw, pd->ipg_rate_mhz));
+ while (readl_relaxed(gpc_base + GPC_CNTR) & val)
+ ;
+}
+
+static int imx6_pm_domain_power_off(struct generic_pm_domain *genpd)
+{
+ struct imx_pm_domain *pd = to_imx_pm_domain(genpd);
+
+ if (pd->flags & PGC_DOMAIN_FLAG_NO_PD)
+ return -EBUSY;
+
+ _imx6_pm_domain_power_off(genpd);
+
if (pd->supply)
regulator_disable(pd->supply);
return 0;
}
-static int imx6_pm_domain_power_on(struct generic_pm_domain *genpd)
+static void _imx6_pm_domain_power_on(struct generic_pm_domain *genpd)
{
struct imx_pm_domain *pd = to_imx_pm_domain(genpd);
- int i, ret, sw, sw2iso;
- u32 val;
+ int i;
+ u32 val, ipg_rate = clk_get_rate(ipg_clk);
- if (pd->supply) {
- ret = regulator_enable(pd->supply);
- if (ret) {
- pr_err("%s: failed to enable regulator: %d\n",
- __func__, ret);
- return ret;
- }
+ if (ipg_rate == 0) {
+ WARN_ON(1);
+ return;
}
/* Enable reset clocks for all devices in the domain */
@@ -117,25 +151,106 @@ static int imx6_pm_domain_power_on(struct generic_pm_domain *genpd)
regmap_update_bits(pd->regmap, pd->reg_offs + GPC_PGC_CTRL_OFFS,
0x1, 0x1);
- /* Read ISO and ISO2SW power up delays */
- regmap_read(pd->regmap, pd->reg_offs + GPC_PGC_PUPSCR_OFFS, &val);
- sw = val & 0x3f;
- sw2iso = (val >> 8) & 0x3f;
-
/* Request GPC to power up domain */
val = BIT(pd->cntr_pdn_bit + 1);
regmap_update_bits(pd->regmap, GPC_CNTR, val, val);
- /* Wait ISO + ISO2SW IPG clock cycles */
- udelay(DIV_ROUND_UP(sw + sw2iso, pd->ipg_rate_mhz));
+ while (readl_relaxed(gpc_base + GPC_CNTR) & val)
+ ;
+ /* Wait power switch done */
+ udelay(2 * DEFAULT_IPG_RATE / ipg_rate +
+ GPC_PU_UP_DELAY_MARGIN);
/* Disable reset clocks for all devices in the domain */
for (i = 0; i < pd->num_clks; i++)
clk_disable_unprepare(pd->clk[i]);
+}
+
+static int imx6_pm_domain_power_on(struct generic_pm_domain *genpd)
+{
+ struct imx_pm_domain *pd = to_imx_pm_domain(genpd);
+ int ret;
+
+ if (pd->supply) {
+ ret = regulator_enable(pd->supply);
+ if (ret) {
+ pr_err("%s: failed to enable regulator: %d\n",
+ __func__, ret);
+ return ret;
+ }
+ }
+
+ _imx6_pm_domain_power_on(genpd);
return 0;
}
+static int imx6_pm_dispmix_on(struct generic_pm_domain *genpd)
+{
+ struct imx_pm_domain *pd = to_imx_pm_domain(genpd);
+ u32 val = readl_relaxed(gpc_base + GPC_CNTR);
+ u32 ipg_rate = clk_get_rate(ipg_clk);
+ int i;
+
+ if (ipg_rate == 0) {
+ WARN_ON(1);
+ return -EINVAL;
+ }
+
+ if ((cpu_is_imx6sl() &&
+ imx_get_soc_revision() >= IMX_CHIP_REVISION_1_2) || cpu_is_imx6sx()) {
+
+ /* Enable reset clocks for all devices in the disp domain */
+ for (i = 0; i < pd->num_clks; i++)
+ clk_prepare_enable(pd->clk[i]);
+
+ writel_relaxed(0x0, gpc_base + GPC_PGC_DISP_PGCR_OFFSET);
+ writel_relaxed(0x20 | val, gpc_base + GPC_CNTR);
+ while (readl_relaxed(gpc_base + GPC_CNTR) & 0x20)
+ ;
+
+ writel_relaxed(0x1, gpc_base + GPC_PGC_DISP_SR_OFFSET);
+
+ /* Wait power switch done */
+ udelay(2 * DEFAULT_IPG_RATE / ipg_rate +
+ GPC_PU_UP_DELAY_MARGIN);
+
+ /* Disable reset clocks for all devices in the disp domain */
+ for (i = 0; i < pd->num_clks; i++)
+ clk_disable_unprepare(pd->clk[i]);
+ }
+ return 0;
+}
+
+static int imx6_pm_dispmix_off(struct generic_pm_domain *genpd)
+{
+ struct imx_pm_domain *pd = to_imx_pm_domain(genpd);
+ u32 val = readl_relaxed(gpc_base + GPC_CNTR);
+ int i;
+
+ if ((cpu_is_imx6sl() &&
+ imx_get_soc_revision() >= IMX_CHIP_REVISION_1_2) || cpu_is_imx6sx()) {
+
+ /* Enable reset clocks for all devices in the disp domain */
+ for (i = 0; i < pd->num_clks; i++)
+ clk_prepare_enable(pd->clk[i]);
+
+ writel_relaxed(0xFFFFFFFF,
+ gpc_base + GPC_PGC_DISP_PUPSCR_OFFSET);
+ writel_relaxed(0xFFFFFFFF,
+ gpc_base + GPC_PGC_DISP_PDNSCR_OFFSET);
+ writel_relaxed(0x1, gpc_base + GPC_PGC_DISP_PGCR_OFFSET);
+ writel_relaxed(0x10 | val, gpc_base + GPC_CNTR);
+ while (readl_relaxed(gpc_base + GPC_CNTR) & 0x10)
+ ;
+
+ /* Disable reset clocks for all devices in the disp domain */
+ for (i = 0; i < pd->num_clks; i++)
+ clk_disable_unprepare(pd->clk[i]);
+ }
+ return 0;
+}
+
static int imx_pgc_get_clocks(struct device *dev, struct imx_pm_domain *domain)
{
int i, ret;
@@ -185,6 +300,8 @@ static int imx_pgc_parse_dt(struct device *dev, struct imx_pm_domain *domain)
return imx_pgc_get_clocks(dev, domain);
}
+static void imx_gpc_handle_ldobypass(struct platform_device *pdev);
+
static int imx_pgc_power_domain_probe(struct platform_device *pdev)
{
struct imx_pm_domain *domain = pdev->dev.platform_data;
@@ -211,6 +328,10 @@ static int imx_pgc_power_domain_probe(struct platform_device *pdev)
device_link_add(dev, dev->parent, DL_FLAG_AUTOREMOVE);
+ /* Mark PU regulator as bypass */
+ if (pdev->id == 1)
+ imx_gpc_handle_ldobypass(to_platform_device(pdev->dev.parent));
+
return 0;
genpd_err:
@@ -275,8 +396,8 @@ static struct imx_pm_domain imx_gpc_domains[] = {
}, {
.base = {
.name = "DISPLAY",
- .power_off = imx6_pm_domain_power_off,
- .power_on = imx6_pm_domain_power_on,
+ .power_off = imx6_pm_dispmix_off,
+ .power_on = imx6_pm_dispmix_on,
},
.reg_offs = 0x240,
.cntr_pdn_bit = 4,
@@ -303,10 +424,16 @@ static const struct imx_gpc_dt_data imx6sl_dt_data = {
.err009619_present = false,
};
+static const struct imx_gpc_dt_data imx6sx_dt_data = {
+ .num_domains = 3,
+ .err009619_present = false,
+};
+
static const struct of_device_id imx_gpc_dt_ids[] = {
{ .compatible = "fsl,imx6q-gpc", .data = &imx6q_dt_data },
{ .compatible = "fsl,imx6qp-gpc", .data = &imx6qp_dt_data },
{ .compatible = "fsl,imx6sl-gpc", .data = &imx6sl_dt_data },
+ { .compatible = "fsl,imx6sx-gpc", .data = &imx6sx_dt_data },
{ }
};
@@ -341,32 +468,92 @@ static struct genpd_onecell_data imx_gpc_onecell_data = {
.num_domains = 2,
};
+/* exported for suspend/resume code in arch/arm/mach-imx/gpc.c */
+void _imx6_pm_pu_power_off(void)
+{
+ _imx6_pm_domain_power_off(&imx_gpc_domains[GPC_PGC_DOMAIN_PU].base);
+}
+EXPORT_SYMBOL_GPL(_imx6_pm_pu_power_off);
+
+void _imx6_pm_pu_power_on(void)
+{
+ _imx6_pm_domain_power_on(&imx_gpc_domains[GPC_PGC_DOMAIN_PU].base);
+}
+EXPORT_SYMBOL_GPL(_imx6_pm_pu_power_on);
+
static int imx_gpc_old_dt_init(struct device *dev, struct regmap *regmap,
unsigned int num_domains)
{
+ struct clk *clk;
struct imx_pm_domain *domain;
- int i, ret;
+ bool is_off;
+ int pu_clks, disp_clks, ipg_clks = 1;
+ int i = 0, k = 0, ret;
+
+ struct imx_pm_domain *pu_domain = &imx_gpc_domains[GPC_PGC_DOMAIN_PU];
+ struct imx_pm_domain *disp_domain = &imx_gpc_domains[GPC_PGC_DOMAIN_DISPLAY];
+
+ if ((cpu_is_imx6sl() &&
+ imx_get_soc_revision() >= IMX_CHIP_REVISION_1_2)) {
+ pu_clks = 2;
+ disp_clks = 5;
+ } else if (cpu_is_imx6sx()) {
+ pu_clks = 1;
+ disp_clks = 7;
+ } else {
+ pu_clks = 6;
+ disp_clks = 0;
+ }
+
+ /* Get pu domain clks */
+ for (i = 0; i < pu_clks ; i++) {
+ clk = of_clk_get(dev->of_node, i);
+ if (IS_ERR(clk))
+ break;
+ pu_domain->clk[i] = clk;
+ }
+ pu_domain->num_clks = i;
+
+ ipg_clk = of_clk_get(dev->of_node, pu_clks);
+
+ /* Get disp domain clks */
+ for (i = pu_clks + ipg_clks; i < pu_clks + ipg_clks + disp_clks;
+ i++) {
+ clk = of_clk_get(dev->of_node, i);
+ if (IS_ERR(clk))
+ break;
+ disp_domain->clk[k++] = clk;
+ }
+ disp_domain->num_clks = k;
for (i = 0; i < num_domains; i++) {
domain = &imx_gpc_domains[i];
domain->regmap = regmap;
domain->ipg_rate_mhz = 66;
- if (i == 1) {
+ if (i == GPC_PGC_DOMAIN_PU) {
domain->supply = devm_regulator_get(dev, "pu");
if (IS_ERR(domain->supply))
return PTR_ERR(domain->supply);;
- ret = imx_pgc_get_clocks(dev, domain);
- if (ret)
- goto clk_err;
-
domain->base.power_on(&domain->base);
}
}
+ is_off = IS_ENABLED(CONFIG_PM);
+ if (is_off && !(cpu_is_imx6q() &&
+ imx_get_soc_revision() == IMX_CHIP_REVISION_2_0)) {
+ _imx6_pm_domain_power_off(&pu_domain->base);
+ } else {
+ /*
+ * Enable power if compiled without CONFIG_PM in case the
+ * bootloader disabled it.
+ */
+ imx6_pm_domain_power_on(&pu_domain->base);
+ }
+
for (i = 0; i < num_domains; i++)
- pm_genpd_init(&imx_gpc_domains[i].base, NULL, false);
+ pm_genpd_init(&imx_gpc_domains[i].base, NULL, is_off);
if (IS_ENABLED(CONFIG_PM_GENERIC_DOMAINS)) {
ret = of_genpd_add_provider_onecell(dev->of_node,
@@ -378,13 +565,55 @@ static int imx_gpc_old_dt_init(struct device *dev, struct regmap *regmap,
return 0;
genpd_err:
- for (i = 0; i < num_domains; i++)
+ for (i = 0; i < num_domains; i++) {
pm_genpd_remove(&imx_gpc_domains[i].base);
- imx_pgc_put_clocks(&imx_gpc_domains[GPC_PGC_DOMAIN_PU]);
-clk_err:
+ imx_pgc_put_clocks(&imx_gpc_domains[i]);
+ }
return ret;
}
+static void imx_gpc_handle_ldobypass(struct platform_device *pdev)
+{
+ struct regulator *pu_reg = imx_gpc_domains[GPC_PGC_DOMAIN_PU].supply;
+ u32 bypass = 0;
+ int ret;
+
+ ret = of_property_read_u32(pdev->dev.of_node, "fsl,ldo-bypass", &bypass);
+ if (ret && ret != -EINVAL)
+ dev_warn(&pdev->dev, "failed to read fsl,ldo-bypass property: %d\n", ret);
+
+ /* We only bypass pu since arm and soc has been set in u-boot */
+ if (pu_reg && bypass) {
+ regulator_allow_bypass(pu_reg, true);
+ }
+}
+
+static struct notifier_block nb_pcie;
+
+static int imx_pcie_regulator_notify(struct notifier_block *nb,
+ unsigned long event,
+ void *ignored)
+{
+ u32 value = readl_relaxed(gpc_base + GPC_CNTR);
+
+ switch (event) {
+ case REGULATOR_EVENT_PRE_DO_ENABLE:
+ value |= 1 << GPC_CNTR_PCIE_PHY_PDU_SHIFT;
+ writel_relaxed(value, gpc_base + GPC_CNTR);
+ break;
+ case REGULATOR_EVENT_PRE_DO_DISABLE:
+ value |= 1 << GPC_CNTR_PCIE_PHY_PDN_SHIFT;
+ writel_relaxed(value, gpc_base + GPC_CNTR);
+ writel_relaxed(PGC_PCIE_PHY_PDN_EN,
+ gpc_base + PGC_PCIE_PHY_CTRL);
+ break;
+ default:
+ break;
+ }
+
+ return NOTIFY_OK;
+}
+
static int imx_gpc_probe(struct platform_device *pdev)
{
const struct of_device_id *of_id =
@@ -407,6 +636,7 @@ static int imx_gpc_probe(struct platform_device *pdev)
base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(base))
return PTR_ERR(base);
+ gpc_base = base;
regmap = devm_regmap_init_mmio_clk(&pdev->dev, NULL, base,
&imx_gpc_regmap_config);
@@ -427,11 +657,12 @@ static int imx_gpc_probe(struct platform_device *pdev)
of_id_data->num_domains);
if (ret)
return ret;
+
+ imx_gpc_handle_ldobypass(pdev);
} else {
struct imx_pm_domain *domain;
struct platform_device *pd_pdev;
struct device_node *np;
- struct clk *ipg_clk;
unsigned int ipg_rate_mhz;
int domain_index;
@@ -472,6 +703,25 @@ static int imx_gpc_probe(struct platform_device *pdev)
}
}
+ if (of_machine_is_compatible("fsl,imx6sx")) {
+ struct regulator *pcie_reg;
+
+ pcie_reg = devm_regulator_get(&pdev->dev, "pcie-phy");
+ if (IS_ERR(pcie_reg)) {
+ ret = PTR_ERR(pcie_reg);
+ dev_info(&pdev->dev, "pcie regulator not ready.\n");
+ return ret;
+ }
+ nb_pcie.notifier_call = &imx_pcie_regulator_notify;
+
+ ret = regulator_register_notifier(pcie_reg, &nb_pcie);
+ if (ret) {
+ dev_err(&pdev->dev,
+ "pcie regulator notifier request failed\n");
+ return ret;
+ }
+ }
+
return 0;
}
diff --git a/drivers/soc/imx/gpcv2.c b/drivers/soc/imx/gpcv2.c
index 6ef18cf8f243..5373eba6be85 100644
--- a/drivers/soc/imx/gpcv2.c
+++ b/drivers/soc/imx/gpcv2.c
@@ -18,6 +18,7 @@
#include <linux/pm_domain.h>
#include <linux/regmap.h>
#include <linux/regulator/consumer.h>
+#include <linux/io.h>
#include <dt-bindings/power/imx7-power.h>
#define GPC_LPCR_A7_BSC 0x000
@@ -45,6 +46,7 @@
* GPC_PGC memory map are incorrect, below offset
* values are from design RTL.
*/
+
#define PGC_MIPI 16
#define PGC_PCIE 17
#define PGC_USB_HSIC 20
@@ -258,6 +260,207 @@ static struct platform_driver imx7_pgc_domain_driver = {
};
builtin_platform_driver(imx7_pgc_domain_driver)
+/* Some drivers rely on regulator notifiers to switch pgc on/off */
+
+#define GPC_PGC_MIPI_PHY 0xc00
+#define GPC_PGC_PCIE_PHY 0xc40
+#define GPC_PGC_USB_OTG1_PHY 0xc80
+#define GPC_PGC_USB_OTG2_PHY 0xcc0
+#define GPC_PGC_USB_HSIC_PHY 0xd00
+
+#define BM_GPC_PGC_PCG 0x1
+
+static void __iomem *gpc_base;
+static struct notifier_block nb_mipi, nb_pcie, nb_usb_hsic;
+
+static void imx_gpcv2_set_m_core_pgc(bool enable, u32 offset)
+{
+ u32 val = readl_relaxed(gpc_base + offset) & (~BM_GPC_PGC_PCG);
+
+ if (enable)
+ val |= BM_GPC_PGC_PCG;
+
+ writel_relaxed(val, gpc_base + offset);
+}
+
+static int imx_mipi_regulator_notify(struct notifier_block *nb,
+ unsigned long event,
+ void *ignored)
+{
+ u32 val = 0;
+
+ val = readl_relaxed(gpc_base + GPC_PGC_CPU_MAPPING);
+ writel_relaxed(val | BIT(2), gpc_base + GPC_PGC_CPU_MAPPING);
+
+ switch (event) {
+ case REGULATOR_EVENT_AFT_DO_ENABLE:
+ /*
+ * For imx7d pcie phy, VDD18 turn on time has to wait
+ * at least 0.1 .s after VDD10 turns on.
+ */
+ udelay(1);
+ val = readl_relaxed(gpc_base + GPC_PU_PGC_SW_PUP_REQ);
+ writel_relaxed(val | BIT(0), gpc_base + GPC_PU_PGC_SW_PUP_REQ);
+ while (readl_relaxed(gpc_base + GPC_PU_PGC_SW_PUP_REQ) & BIT(0))
+ ;
+ break;
+ case REGULATOR_EVENT_PRE_DO_DISABLE:
+ /* only disable phy need to set PGC bit, enable does NOT need */
+ imx_gpcv2_set_m_core_pgc(true, GPC_PGC_MIPI_PHY);
+ val = readl_relaxed(gpc_base + GPC_PU_PGC_SW_PDN_REQ);
+ writel_relaxed(val | BIT(0), gpc_base + GPC_PU_PGC_SW_PDN_REQ);
+ while (readl_relaxed(gpc_base + GPC_PU_PGC_SW_PDN_REQ) & BIT(0))
+ ;
+ imx_gpcv2_set_m_core_pgc(false, GPC_PGC_MIPI_PHY);
+ /*
+ * For imx7d pcie phy, VDD18 turn off time has to advance
+ * at least 0.1 .s before VDD10 turns off.
+ */
+ udelay(1);
+ break;
+ default:
+ break;
+ }
+
+ val = readl_relaxed(gpc_base + GPC_PGC_CPU_MAPPING);
+ writel_relaxed(val & ~BIT(2), gpc_base + GPC_PGC_CPU_MAPPING);
+
+ return NOTIFY_OK;
+}
+
+static int imx_pcie_regulator_notify(struct notifier_block *nb,
+ unsigned long event,
+ void *ignored)
+{
+ u32 val = 0;
+
+ val = readl_relaxed(gpc_base + GPC_PGC_CPU_MAPPING);
+ writel_relaxed(val | BIT(3), gpc_base + GPC_PGC_CPU_MAPPING);
+
+ switch (event) {
+ case REGULATOR_EVENT_AFT_DO_ENABLE:
+ /*
+ * For imx7d pcie phy, VDD18 turn on time has to wait
+ * at least 0.1 .s after VDD10 turns on.
+ */
+ udelay(1);
+ val = readl_relaxed(gpc_base + GPC_PU_PGC_SW_PUP_REQ);
+ writel_relaxed(val | BIT(1), gpc_base + GPC_PU_PGC_SW_PUP_REQ);
+ while (readl_relaxed(gpc_base + GPC_PU_PGC_SW_PUP_REQ) & BIT(1))
+ ;
+ break;
+ case REGULATOR_EVENT_PRE_DO_DISABLE:
+ /* only disable phy need to set PGC bit, enable does NOT need */
+ imx_gpcv2_set_m_core_pgc(true, GPC_PGC_PCIE_PHY);
+ val = readl_relaxed(gpc_base + GPC_PU_PGC_SW_PDN_REQ);
+ writel_relaxed(val | BIT(1), gpc_base + GPC_PU_PGC_SW_PDN_REQ);
+ while (readl_relaxed(gpc_base + GPC_PU_PGC_SW_PDN_REQ) & BIT(1))
+ ;
+ imx_gpcv2_set_m_core_pgc(false, GPC_PGC_PCIE_PHY);
+ /*
+ * For imx7d pcie phy, VDD18 turn off time has to advance
+ * at least 0.1 .s before VDD10 turns off.
+ */
+ udelay(1);
+ break;
+ default:
+ break;
+ }
+
+ val = readl_relaxed(gpc_base + GPC_PGC_CPU_MAPPING);
+ writel_relaxed(val & ~BIT(3), gpc_base + GPC_PGC_CPU_MAPPING);
+
+ return NOTIFY_OK;
+}
+
+static int imx_usb_hsic_regulator_notify(struct notifier_block *nb,
+ unsigned long event,
+ void *ignored)
+{
+ u32 val = 0;
+
+ val = readl_relaxed(gpc_base + GPC_PGC_CPU_MAPPING);
+ writel_relaxed(val | BIT(6), gpc_base + GPC_PGC_CPU_MAPPING);
+
+ switch (event) {
+ case REGULATOR_EVENT_PRE_DO_ENABLE:
+ val = readl_relaxed(gpc_base + GPC_PU_PGC_SW_PUP_REQ);
+ writel_relaxed(val | BIT(4), gpc_base + GPC_PU_PGC_SW_PUP_REQ);
+ while (readl_relaxed(gpc_base + GPC_PU_PGC_SW_PUP_REQ) & BIT(4))
+ ;
+ break;
+ case REGULATOR_EVENT_PRE_DO_DISABLE:
+ /* only disable phy need to set PGC bit, enable does NOT need */
+ imx_gpcv2_set_m_core_pgc(true, GPC_PGC_USB_HSIC_PHY);
+ val = readl_relaxed(gpc_base + GPC_PU_PGC_SW_PDN_REQ);
+ writel_relaxed(val | BIT(4), gpc_base + GPC_PU_PGC_SW_PDN_REQ);
+ while (readl_relaxed(gpc_base + GPC_PU_PGC_SW_PDN_REQ) & BIT(4))
+ ;
+ imx_gpcv2_set_m_core_pgc(false, GPC_PGC_USB_HSIC_PHY);
+ break;
+ default:
+ break;
+ }
+
+ val = readl_relaxed(gpc_base + GPC_PGC_CPU_MAPPING);
+ writel_relaxed(val & ~BIT(6), gpc_base + GPC_PGC_CPU_MAPPING);
+
+ return NOTIFY_OK;
+}
+
+static int imx_gpcv2_init_regnb(struct platform_device *pdev)
+{
+ int ret;
+ struct regulator *mipi_reg, *pcie_reg, *usb_hsic_reg;
+
+ mipi_reg = devm_regulator_get(&pdev->dev, "mipi-phy");
+ if (IS_ERR(mipi_reg)) {
+ ret = PTR_ERR(mipi_reg);
+ dev_info(&pdev->dev, "mipi regulator not ready.\n");
+ return ret;
+ }
+ nb_mipi.notifier_call = &imx_mipi_regulator_notify;
+
+ ret = regulator_register_notifier(mipi_reg, &nb_mipi);
+ if (ret) {
+ dev_err(&pdev->dev,
+ "mipi regulator notifier request failed.\n");
+ return ret;
+ }
+
+ pcie_reg = devm_regulator_get(&pdev->dev, "pcie-phy");
+ if (IS_ERR(pcie_reg)) {
+ ret = PTR_ERR(pcie_reg);
+ dev_info(&pdev->dev, "pcie regulator not ready.\n");
+ return ret;
+ }
+ nb_pcie.notifier_call = &imx_pcie_regulator_notify;
+
+ ret = regulator_register_notifier(pcie_reg, &nb_pcie);
+ if (ret) {
+ dev_err(&pdev->dev,
+ "pcie regulator notifier request failed\n");
+ return ret;
+ }
+
+ usb_hsic_reg = devm_regulator_get(&pdev->dev, "vcc");
+ if (IS_ERR(usb_hsic_reg)) {
+ ret = PTR_ERR(usb_hsic_reg);
+ dev_err(&pdev->dev, "usb hsic regulator not ready.\n");
+ return ret;
+ }
+ nb_usb_hsic.notifier_call = &imx_usb_hsic_regulator_notify;
+
+ ret = regulator_register_notifier(usb_hsic_reg, &nb_usb_hsic);
+ if (ret) {
+ dev_err(&pdev->dev,
+ "usb hsic regulator notifier request failed\n");
+ return ret;
+ }
+
+ return 0;
+}
+
static int imx_gpcv2_probe(struct platform_device *pdev)
{
static const struct regmap_range yes_ranges[] = {
@@ -299,6 +502,7 @@ static int imx_gpcv2_probe(struct platform_device *pdev)
base = devm_ioremap_resource(dev, res);
if (IS_ERR(base))
return PTR_ERR(base);
+ gpc_base = base;
regmap = devm_regmap_init_mmio(dev, base, &regmap_config);
if (IS_ERR(regmap)) {
@@ -359,7 +563,7 @@ static int imx_gpcv2_probe(struct platform_device *pdev)
}
}
- return 0;
+ return imx_gpcv2_init_regnb(pdev);
}
static const struct of_device_id imx_gpcv2_dt_ids[] = {
diff --git a/drivers/soc/imx/mu/Makefile b/drivers/soc/imx/mu/Makefile
new file mode 100644
index 000000000000..922308c3f90f
--- /dev/null
+++ b/drivers/soc/imx/mu/Makefile
@@ -0,0 +1 @@
+obj-y += mx8_mu.o
diff --git a/drivers/soc/imx/mu/mx8_mu.c b/drivers/soc/imx/mu/mx8_mu.c
new file mode 100644
index 000000000000..2cd6dc880bbe
--- /dev/null
+++ b/drivers/soc/imx/mu/mx8_mu.c
@@ -0,0 +1,187 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017 NXP
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/mx8_mu.h>
+#include <linux/of.h>
+
+static int version;
+
+/*!
+ * This function sets the Flag n of the MU.
+ */
+int32_t MU_SetFn(void __iomem *base, uint32_t Fn)
+{
+ uint32_t reg, offset;
+
+ reg = Fn & (~MU_CR_Fn_MASK1);
+ if (reg > 0)
+ return -EINVAL;
+
+ offset = unlikely(version == MU_VER_ID_V10)
+ ? MU_V10_ACR_OFFSET1 : MU_ACR_OFFSET1;
+
+ reg = readl_relaxed(base + offset);
+ /* Clear ABFn. */
+ reg &= ~MU_CR_Fn_MASK1;
+ reg |= Fn;
+ writel_relaxed(reg, base + offset);
+
+ return 0;
+}
+
+/*!
+ * This function reads the status from status register.
+ */
+uint32_t MU_ReadStatus(void __iomem *base)
+{
+ uint32_t reg, offset;
+
+ offset = unlikely(version == MU_VER_ID_V10)
+ ? MU_V10_ASR_OFFSET1 : MU_ASR_OFFSET1;
+
+ reg = readl_relaxed(base + offset);
+
+ return reg;
+}
+
+/*!
+ * This function enables specific RX full interrupt.
+ */
+void MU_EnableRxFullInt(void __iomem *base, uint32_t index)
+{
+ uint32_t reg, offset;
+
+ offset = unlikely(version == MU_VER_ID_V10)
+ ? MU_V10_ACR_OFFSET1 : MU_ACR_OFFSET1;
+
+ reg = readl_relaxed(base + offset);
+ reg &= ~(MU_CR_GIRn_MASK1 | MU_CR_NMI_MASK1);
+ reg |= MU_CR_RIE0_MASK1 >> index;
+ writel_relaxed(reg, base + offset);
+}
+
+/*!
+ * This function enables specific general purpose interrupt.
+ */
+void MU_EnableGeneralInt(void __iomem *base, uint32_t index)
+{
+ uint32_t reg, offset;
+
+ offset = unlikely(version == MU_VER_ID_V10)
+ ? MU_V10_ACR_OFFSET1 : MU_ACR_OFFSET1;
+
+ reg = readl_relaxed(base + offset);
+ reg &= ~(MU_CR_GIRn_MASK1 | MU_CR_NMI_MASK1);
+ reg |= MU_CR_GIE0_MASK1 >> index;
+ writel_relaxed(reg, base + offset);
+}
+
+/*
+ * Wait and send message to the other core.
+ */
+void MU_SendMessage(void __iomem *base, uint32_t regIndex, uint32_t msg)
+{
+ uint32_t mask = MU_SR_TE0_MASK1 >> regIndex;
+
+ if (unlikely(version == MU_VER_ID_V10)) {
+ /* Wait TX register to be empty. */
+ while (!(readl_relaxed(base + MU_V10_ASR_OFFSET1) & mask))
+ ;
+ writel_relaxed(msg, base + MU_V10_ATR0_OFFSET1
+ + (regIndex * 4));
+ } else {
+ /* Wait TX register to be empty. */
+ while (!(readl_relaxed(base + MU_ASR_OFFSET1) & mask))
+ ;
+ writel_relaxed(msg, base + MU_ATR0_OFFSET1 + (regIndex * 4));
+ }
+}
+
+/*
+ * Wait and send message to the other core with timeout mechanism.
+ */
+void MU_SendMessageTimeout(void __iomem *base, uint32_t regIndex, uint32_t msg,
+ uint32_t t)
+{
+ uint32_t mask = MU_SR_TE0_MASK1 >> regIndex;
+ uint32_t timeout = t;
+
+ if (unlikely(version == MU_VER_ID_V10)) {
+ /* Wait TX register to be empty. */
+ while (!(readl_relaxed(base + MU_V10_ASR_OFFSET1) & mask)) {
+ udelay(10);
+ if (timeout-- == 0)
+ return;
+ };
+
+ writel_relaxed(msg, base + MU_V10_ATR0_OFFSET1
+ + (regIndex * 4));
+ } else {
+ /* Wait TX register to be empty. */
+ while (!(readl_relaxed(base + MU_ASR_OFFSET1) & mask)) {
+ udelay(10);
+ if (timeout-- == 0)
+ return;
+ };
+
+ writel_relaxed(msg, base + MU_ATR0_OFFSET1 + (regIndex * 4));
+ }
+}
+
+/*
+ * Wait to receive message from the other core.
+ */
+void MU_ReceiveMsg(void __iomem *base, uint32_t regIndex, uint32_t *msg)
+{
+ uint32_t mask = MU_SR_RF0_MASK1 >> regIndex;
+
+ if (unlikely(version == MU_VER_ID_V10)) {
+ /* Wait RX register to be full. */
+ while (!(readl_relaxed(base + MU_V10_ASR_OFFSET1) & mask))
+ ;
+ *msg = readl_relaxed(base + MU_V10_ARR0_OFFSET1
+ + (regIndex * 4));
+ } else {
+ /* Wait RX register to be full. */
+ while (!(readl_relaxed(base + MU_ASR_OFFSET1) & mask))
+ ;
+ *msg = readl_relaxed(base + MU_ARR0_OFFSET1 + (regIndex * 4));
+ }
+}
+
+
+
+void MU_Init(void __iomem *base)
+{
+ uint32_t reg, offset;
+
+ version = readl_relaxed(base) >> 16;
+
+ offset = unlikely(version == MU_VER_ID_V10)
+ ? MU_V10_ACR_OFFSET1 : MU_ACR_OFFSET1;
+
+ reg = readl_relaxed(base + offset);
+ /* Clear GIEn, TIEn, GIRn and ABFn. */
+ reg &= ~(MU_CR_GIEn_MASK1 | MU_CR_TIEn_MASK1
+ | MU_CR_GIRn_MASK1 | MU_CR_NMI_MASK1 | MU_CR_Fn_MASK1);
+
+ /*
+ * i.MX6SX and i.MX7D have multi-core power management which need
+ * to use RIE interrupts.
+ */
+ if (!(of_machine_is_compatible("fsl,imx6sx") ||
+ of_machine_is_compatible("fsl,imx7d")))
+ reg &= ~MU_CR_RIEn_MASK1;
+
+ writel_relaxed(reg, base + offset);
+}
+
+/**@}*/
+
diff --git a/drivers/soc/imx/pm-domain-imx8.h b/drivers/soc/imx/pm-domain-imx8.h
new file mode 100644
index 000000000000..a9489a82d6f8
--- /dev/null
+++ b/drivers/soc/imx/pm-domain-imx8.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2016 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.
+ *
+ * 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 PM_DOMAIN_IMX8_H
+#define PM_DOMAIN_IMX8_H
+
+#include <linux/clk.h>
+#include <linux/pm_domain.h>
+#include <soc/imx8/sc/sci.h>
+
+#define DEFAULT_DEV_LATENCY_NS 250000
+
+struct platform_device;
+
+struct imx8_pm_rsrc_clks {
+ struct clk *clk;
+ struct clk *parent;
+ struct device *dev;
+ u32 rate;
+ struct list_head node;
+};
+
+struct imx8_pm_domain {
+ const char *name;
+ struct generic_pm_domain pd;
+ struct dev_power_governor *gov;
+ int (*suspend)(void);
+ void (*resume)(void);
+ sc_rsrc_t rsrc_id;
+ bool runtime_idle_active;
+ struct list_head clks;
+
+ /* indicate the possible clk state lost */
+ bool clk_state_saved;
+ bool clk_state_may_lost;
+};
+
+static inline
+struct imx8_pm_domain *to_imx8_pd(struct generic_pm_domain *d)
+{
+ return container_of(d, struct imx8_pm_domain, pd);
+}
+
+struct pm_domain_device {
+ const char *domain_name;
+ struct platform_device *pdev;
+};
+
+#endif /* PM_DOMAIN_IMX8_H */
diff --git a/drivers/soc/imx/pm-domains.c b/drivers/soc/imx/pm-domains.c
new file mode 100644
index 000000000000..a585fa1f802f
--- /dev/null
+++ b/drivers/soc/imx/pm-domains.c
@@ -0,0 +1,658 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017 NXP
+ *
+ * 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/arm-smccc.h>
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/console.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/irqchip.h>
+#include <linux/irqchip/arm-gic.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_runtime.h>
+#include <linux/pm_clock.h>
+#include <linux/slab.h>
+#include <linux/syscore_ops.h>
+
+#include <soc/imx/fsl_sip.h>
+#include <soc/imx8/sc/sci.h>
+
+#include "pm-domain-imx8.h"
+
+static sc_ipc_t pm_ipc_handle;
+static sc_rsrc_t early_power_on_rsrc[] = {
+ SC_R_LAST, SC_R_LAST, SC_R_LAST, SC_R_LAST, SC_R_LAST,
+ SC_R_LAST, SC_R_LAST, SC_R_LAST, SC_R_LAST, SC_R_LAST,
+};
+static sc_rsrc_t rsrc_debug_console;
+
+#define IMX8_WU_MAX_IRQS (((SC_R_LAST + 31) / 32 ) * 32 )
+static sc_rsrc_t irq2rsrc[IMX8_WU_MAX_IRQS];
+static sc_rsrc_t wakeup_rsrc_id[IMX8_WU_MAX_IRQS / 32];
+static DEFINE_SPINLOCK(imx8_wu_lock);
+static DEFINE_MUTEX(rsrc_pm_list_lock);
+
+enum imx_pd_state {
+ PD_LP,
+ PD_OFF,
+};
+
+struct clk_stat {
+ struct clk *clk;
+ struct clk *parent;
+ unsigned long rate;
+};
+
+static int imx8_pd_power(struct generic_pm_domain *domain, bool power_on)
+{
+ struct imx8_pm_domain *pd;
+ sc_err_t sci_err = SC_ERR_NONE;
+
+ pd = container_of(domain, struct imx8_pm_domain, pd);
+
+ if (pd->rsrc_id == SC_R_NONE)
+ return 0;
+
+ /* keep uart console power on for no_console_suspend */
+ if (pd->rsrc_id == rsrc_debug_console &&
+ !console_suspend_enabled && !power_on)
+ return 0;
+
+ /* keep resource power on if it is a wakeup source */
+ if (!power_on && ((1 << pd->rsrc_id % 32) &
+ wakeup_rsrc_id[pd->rsrc_id / 32]))
+ return 0;
+
+ sci_err = sc_pm_set_resource_power_mode(pm_ipc_handle, pd->rsrc_id,
+ (power_on) ? SC_PM_PW_MODE_ON :
+ pd->pd.state_idx ? SC_PM_PW_MODE_OFF : SC_PM_PW_MODE_LP);
+ if (sci_err) {
+ pr_err("Failed power operation on resource %d sc_err %d\n",
+ pd->rsrc_id, sci_err);
+ return -EINVAL;
+ }
+
+ /* keep HDMI TX resource power on */
+ if (power_on && (pd->rsrc_id == SC_R_HDMI ||
+ pd->rsrc_id == SC_R_HDMI_I2S ||
+ pd->rsrc_id == SC_R_HDMI_I2C_0 ||
+ pd->rsrc_id == SC_R_HDMI_PLL_0 ||
+ pd->rsrc_id == SC_R_HDMI_PLL_1))
+ pd->pd.flags |= GENPD_FLAG_ALWAYS_ON;
+
+ return 0;
+}
+
+static int imx8_pd_power_on(struct generic_pm_domain *domain)
+{
+ struct imx8_pm_domain *pd;
+ struct imx8_pm_rsrc_clks *imx8_rsrc_clk;
+ int ret = 0;
+
+ pd = container_of(domain, struct imx8_pm_domain, pd);
+
+ ret = imx8_pd_power(domain, true);
+ if (ret)
+ return ret;
+
+ if (!list_empty(&pd->clks) && (pd->pd.state_idx == PD_OFF)) {
+
+ if (pd->clk_state_saved) {
+ /*
+ * The SS is powered on restore the clock rates that
+ * may be lost.
+ */
+ list_for_each_entry(imx8_rsrc_clk, &pd->clks, node) {
+
+ if (imx8_rsrc_clk->parent)
+ clk_set_parent(imx8_rsrc_clk->clk,
+ imx8_rsrc_clk->parent);
+
+ if (imx8_rsrc_clk->rate) {
+ /*
+ * Need to read the clock so that rate in
+ * Linux is reset.
+ */
+ clk_get_rate(imx8_rsrc_clk->clk);
+ /* Restore the clock rate. */
+ clk_set_rate(imx8_rsrc_clk->clk,
+ imx8_rsrc_clk->rate);
+ }
+ }
+ } else if (pd->clk_state_may_lost) {
+ struct clk_stat *clk_stats;
+ int count = 0;
+ int i = 0;
+ /*
+ * The SS is powered down before without saving clk rates,
+ * try to restore the lost clock rates if any
+ *
+ * As a parent clk rate restore will cause the clk recalc
+ * to all possible child clks which may result in child clk
+ * previous state lost due to power domain lost before, we
+ * have to first walk through all child clks to retrieve the
+ * state via clk_hw_get_rate which bypassed the clk recalc,
+ * then we can restore them one by one.
+ */
+ list_for_each_entry(imx8_rsrc_clk, &pd->clks, node)
+ count++;
+
+ clk_stats = kzalloc(count * sizeof(*clk_stats), GFP_KERNEL);
+ if (!clk_stats) {
+ pr_warn("%s: failed to alloc mem for clk state recovery\n", pd->name);
+ return -ENOMEM;
+ }
+
+ list_for_each_entry(imx8_rsrc_clk, &pd->clks, node) {
+ clk_stats[i].clk = imx8_rsrc_clk->clk;
+ clk_stats[i].parent = clk_get_parent(imx8_rsrc_clk->clk);
+ clk_stats[i].rate = clk_hw_get_rate(__clk_get_hw(imx8_rsrc_clk->clk));
+ i++;
+ }
+
+ for (i = 0; i < count; i++) {
+ /* restore parent first */
+ if (clk_stats[i].parent)
+ clk_set_parent(clk_stats[i].clk, clk_stats[i].parent);
+
+ if (clk_stats[i].rate) {
+ /* invalid cached rate first by get rate once */
+ clk_get_rate(clk_stats[i].clk);
+ /* restore the lost rate */
+ clk_set_rate(clk_stats[i].clk, clk_stats[i].rate);
+ }
+ }
+
+ kfree(clk_stats);
+ }
+ }
+
+ return 0;
+}
+
+static int imx8_pd_power_off(struct generic_pm_domain *domain)
+{
+ struct imx8_pm_domain *pd;
+ struct imx8_pm_rsrc_clks *imx8_rsrc_clk;
+
+ pd = container_of(domain, struct imx8_pm_domain, pd);
+
+ if (!list_empty(&pd->clks) && (pd->pd.state_idx == PD_OFF)) {
+ /*
+ * The SS is going to be powered off, store the clock rates
+ * that may be lost.
+ */
+ list_for_each_entry(imx8_rsrc_clk, &pd->clks, node) {
+ imx8_rsrc_clk->parent = clk_get_parent(imx8_rsrc_clk->clk);
+ imx8_rsrc_clk->rate = clk_hw_get_rate(__clk_get_hw(imx8_rsrc_clk->clk));
+ }
+ pd->clk_state_saved = true;
+ pd->clk_state_may_lost = false;
+ } else if (pd->pd.state_idx == PD_OFF) {
+ pd->clk_state_saved = false;
+ pd->clk_state_may_lost = true;
+ } else {
+ pd->clk_state_saved = false;
+ pd->clk_state_may_lost = false;
+ }
+ return imx8_pd_power(domain, false);
+}
+
+static int imx8_attach_dev(struct generic_pm_domain *genpd, struct device *dev)
+{
+ struct imx8_pm_domain *pd;
+ struct device_node *node = dev->of_node;
+ struct of_phandle_args clkspec;
+ int rc, index, num_clks;
+
+ pd = container_of(genpd, struct imx8_pm_domain, pd);
+
+ num_clks = of_count_phandle_with_args(node, "assigned-clocks",
+ "#clock-cells");
+ if (num_clks == -EINVAL)
+ pr_err("%s: Invalid value of assigned-clocks property at %s\n",
+ pd->name, node->full_name);
+
+ for (index = 0; index < num_clks; index++) {
+ struct imx8_pm_rsrc_clks *imx8_rsrc_clk;
+
+ rc = of_parse_phandle_with_args(node, "assigned-clocks",
+ "#clock-cells", index, &clkspec);
+ if (rc < 0) {
+ /* skip empty (null) phandles */
+ if (rc == -ENOENT)
+ continue;
+ else
+ return rc;
+ }
+ if (clkspec.np == node)
+ return 0;
+
+ imx8_rsrc_clk = devm_kzalloc(dev, sizeof(*imx8_rsrc_clk),
+ GFP_KERNEL);
+ if (!imx8_rsrc_clk)
+ return -ENOMEM;
+
+ imx8_rsrc_clk->dev = dev;
+ imx8_rsrc_clk->clk = of_clk_get_from_provider(&clkspec);
+ if (!IS_ERR(imx8_rsrc_clk->clk))
+ list_add_tail(&imx8_rsrc_clk->node, &pd->clks);
+ }
+ return 0;
+}
+
+static void imx8_detach_dev(struct generic_pm_domain *genpd, struct device *dev)
+{
+ struct imx8_pm_domain *pd;
+ struct imx8_pm_rsrc_clks *imx8_rsrc_clk, *tmp;
+
+ pd = container_of(genpd, struct imx8_pm_domain, pd);
+
+ /* Free all the clock entry nodes. */
+ if (list_empty(&pd->clks))
+ return;
+
+ list_for_each_entry_safe(imx8_rsrc_clk, tmp, &pd->clks, node) {
+ /* only delete those clocks belonged to this devive */
+ if (imx8_rsrc_clk->dev != dev)
+ continue;
+ list_del(&imx8_rsrc_clk->node);
+ devm_kfree(dev, imx8_rsrc_clk);
+ }
+}
+
+static int imx8_pm_domains_suspend(void)
+{
+ struct arm_smccc_res res;
+ unsigned int i;
+
+ for (i = 0; i < IMX8_WU_MAX_IRQS / 32; i++) {
+ if (wakeup_rsrc_id[i] != 0) {
+ arm_smccc_smc(FSL_SIP_WAKEUP_SRC,
+ FSL_SIP_WAKEUP_SRC_IRQSTEER, 0,
+ 0, 0, 0, 0, 0, &res);
+ return 0;
+ }
+ }
+
+ arm_smccc_smc(FSL_SIP_WAKEUP_SRC,
+ FSL_SIP_WAKEUP_SRC_SCU, 0,
+ 0, 0, 0, 0, 0, &res);
+
+ return 0;
+}
+
+static void imx8_pm_domains_resume(void)
+{
+ sc_err_t sci_err = SC_ERR_NONE;
+ int i;
+
+ for (i = 0; i < (sizeof(early_power_on_rsrc) /
+ sizeof(sc_rsrc_t)); i++) {
+ if (early_power_on_rsrc[i] != SC_R_LAST) {
+ sci_err = sc_pm_set_resource_power_mode(pm_ipc_handle,
+ early_power_on_rsrc[i], SC_PM_PW_MODE_ON);
+ if (sci_err != SC_ERR_NONE)
+ pr_err("fail to power on resource %d\n",
+ early_power_on_rsrc[i]);
+ }
+ }
+}
+
+struct syscore_ops imx8_pm_domains_syscore_ops = {
+ .suspend = imx8_pm_domains_suspend,
+ .resume = imx8_pm_domains_resume,
+};
+
+static void imx8_pd_setup(struct imx8_pm_domain *pd)
+{
+ pd->pd.states = kzalloc(2 * sizeof(struct genpd_power_state), GFP_KERNEL);
+ BUG_ON(!pd->pd.states);
+
+ pd->pd.power_off = imx8_pd_power_off;
+ pd->pd.power_on = imx8_pd_power_on;
+ pd->pd.attach_dev = imx8_attach_dev;
+ pd->pd.detach_dev = imx8_detach_dev;
+
+ pd->pd.states[0].power_off_latency_ns = 25000;
+ pd->pd.states[0].power_on_latency_ns = 25000;
+ pd->pd.states[1].power_off_latency_ns = 2500000;
+ pd->pd.states[1].power_on_latency_ns = 2500000;
+
+ pd->pd.state_count = 2;
+}
+
+static int __init imx8_add_pm_domains(struct device_node *parent,
+ struct generic_pm_domain *genpd_parent)
+{
+ struct device_node *np;
+ static int index;
+
+ for_each_child_of_node(parent, np) {
+ struct imx8_pm_domain *imx8_pd;
+ sc_rsrc_t rsrc_id;
+ u32 wakeup_irq;
+
+ if (!of_device_is_available(np))
+ continue;
+
+ imx8_pd = kzalloc(sizeof(*imx8_pd), GFP_KERNEL);
+ if (!imx8_pd)
+ return -ENOMEM;
+
+ if (!of_property_read_string(np, "name", &imx8_pd->pd.name))
+ imx8_pd->name = imx8_pd->pd.name;
+
+ if (!of_property_read_u32(np, "reg", &rsrc_id))
+ imx8_pd->rsrc_id = rsrc_id;
+
+ if (imx8_pd->rsrc_id != SC_R_NONE) {
+ imx8_pd_setup(imx8_pd);
+
+ if (of_property_read_bool(np, "early_power_on")
+ && index < (sizeof(early_power_on_rsrc) /
+ sizeof(sc_rsrc_t))) {
+ early_power_on_rsrc[index++] = imx8_pd->rsrc_id;
+ }
+ if (of_property_read_bool(np, "debug_console"))
+ rsrc_debug_console = imx8_pd->rsrc_id;
+ if (!of_property_read_u32(np, "wakeup-irq",
+ &wakeup_irq))
+ irq2rsrc[wakeup_irq] = imx8_pd->rsrc_id;
+ }
+ INIT_LIST_HEAD(&imx8_pd->clks);
+ pm_genpd_init(&imx8_pd->pd, NULL, true);
+
+ if (genpd_parent)
+ pm_genpd_add_subdomain(genpd_parent, &imx8_pd->pd);
+
+ of_genpd_add_provider_simple(np, &imx8_pd->pd);
+
+ imx8_add_pm_domains(np, &imx8_pd->pd);
+ }
+ return 0;
+}
+
+static int __init imx8_init_pm_domains(void)
+{
+ struct device_node *np;
+ sc_err_t sci_err;
+ sc_rsrc_t rsrc_id;
+ uint32_t mu_id;
+
+ /* skip pm domains for non-SCFW system */
+ if (!of_find_compatible_node(NULL, NULL, "nxp,imx8-pd"))
+ return 0;
+
+ pr_info("***** imx8_init_pm_domains *****\n");
+
+ for_each_compatible_node(np, NULL, "nxp,imx8-pd") {
+ struct imx8_pm_domain *imx8_pd;
+
+ if (!of_device_is_available(np))
+ continue;
+
+ imx8_pd = kzalloc(sizeof(struct imx8_pm_domain), GFP_KERNEL);
+ if (!imx8_pd) {
+ pr_err("%s: failed to allocate memory for domain\n",
+ __func__);
+ return -ENOMEM;
+ }
+ if (!of_property_read_string(np, "name", &imx8_pd->pd.name))
+ imx8_pd->name = imx8_pd->pd.name;
+
+ if (!of_property_read_u32(np, "reg", &rsrc_id))
+ imx8_pd->rsrc_id = rsrc_id;
+
+ if (imx8_pd->rsrc_id != SC_R_NONE)
+ imx8_pd_setup(imx8_pd);
+
+ INIT_LIST_HEAD(&imx8_pd->clks);
+
+ pm_genpd_init(&imx8_pd->pd, NULL, true);
+ of_genpd_add_provider_simple(np, &imx8_pd->pd);
+ imx8_add_pm_domains(np, &imx8_pd->pd);
+ }
+
+ sci_err = sc_ipc_getMuID(&mu_id);
+ if (sci_err != SC_ERR_NONE) {
+ pr_info("Cannot obtain MU ID\n");
+ return sci_err;
+ }
+
+ sci_err = sc_ipc_open(&pm_ipc_handle, mu_id);
+ register_syscore_ops(&imx8_pm_domains_syscore_ops);
+
+ return 0;
+}
+
+early_initcall(imx8_init_pm_domains);
+
+static int imx8_wu_irq_set_wake(struct irq_data *d, unsigned int on)
+{
+ unsigned int idx = irq2rsrc[d->hwirq] / 32;
+ u32 mask = 1 << irq2rsrc[d->hwirq] % 32;
+
+ spin_lock(&imx8_wu_lock);
+ wakeup_rsrc_id[idx] = on ? wakeup_rsrc_id[idx] | mask :
+ wakeup_rsrc_id[idx] & ~mask;
+ spin_unlock(&imx8_wu_lock);
+
+ return 0;
+}
+
+static struct irq_chip imx8_wu_chip = {
+ .name = "IMX8-WU",
+ .irq_eoi = irq_chip_eoi_parent,
+ .irq_mask = irq_chip_mask_parent,
+ .irq_unmask = irq_chip_unmask_parent,
+ .irq_retrigger = irq_chip_retrigger_hierarchy,
+ .irq_set_wake = imx8_wu_irq_set_wake,
+ .irq_set_affinity = irq_chip_set_affinity_parent,
+};
+
+static int imx8_wu_domain_translate(struct irq_domain *d,
+ struct irq_fwspec *fwspec,
+ unsigned long *hwirq,
+ unsigned int *type)
+{
+ if (is_of_node(fwspec->fwnode)) {
+ if (fwspec->param_count != 3)
+ return -EINVAL;
+ /* No PPI should point to this domain */
+ if (fwspec->param[0] != 0)
+ return -EINVAL;
+ *hwirq = fwspec->param[1];
+ *type = fwspec->param[2];
+ return 0;
+ }
+
+ return -EINVAL;
+}
+
+static int imx8_wu_domain_alloc(struct irq_domain *domain,
+ unsigned int irq,
+ unsigned int nr_irqs, void *data)
+{
+ struct irq_fwspec *fwspec = data;
+ struct irq_fwspec parent_fwspec;
+ irq_hw_number_t hwirq;
+ int i;
+
+ if (fwspec->param_count != 3)
+ return -EINVAL; /* Not GIC compliant */
+ if (fwspec->param[0] != 0)
+ return -EINVAL; /* No PPI should point to this domain */
+
+ hwirq = fwspec->param[1];
+ if (hwirq >= IMX8_WU_MAX_IRQS)
+ return -EINVAL; /* Can't deal with this */
+
+ for (i = 0; i < nr_irqs; i++)
+ irq_domain_set_hwirq_and_chip(domain, irq + i, hwirq + i,
+ &imx8_wu_chip, NULL);
+
+ parent_fwspec = *fwspec;
+ parent_fwspec.fwnode = domain->parent->fwnode;
+
+ return irq_domain_alloc_irqs_parent(domain, irq, nr_irqs,
+ &parent_fwspec);
+}
+
+static const struct irq_domain_ops imx8_wu_domain_ops = {
+ .translate = imx8_wu_domain_translate,
+ .alloc = imx8_wu_domain_alloc,
+ .free = irq_domain_free_irqs_common,
+};
+
+static int __init imx8_wu_init(struct device_node *node,
+ struct device_node *parent)
+{
+ struct irq_domain *parent_domain, *domain;
+
+ if (!parent) {
+ pr_err("%s: no parent, giving up\n", node->full_name);
+ return -ENODEV;
+ }
+
+ parent_domain = irq_find_host(parent);
+ if (!parent_domain) {
+ pr_err("%s: unable to obtain parent domain\n", node->full_name);
+ return -ENXIO;
+ }
+
+ domain = irq_domain_add_hierarchy(parent_domain, 0, IMX8_WU_MAX_IRQS,
+ node, &imx8_wu_domain_ops,
+ NULL);
+ if (!domain)
+ return -ENOMEM;
+
+ return 0;
+}
+IRQCHIP_DECLARE(imx8_wakeup_unit, "fsl,imx8-wu", imx8_wu_init);
+
+/*** debugfs support ***/
+
+#ifdef CONFIG_DEBUG_FS
+#include <linux/pm.h>
+#include <linux/device.h>
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>
+#include <linux/init.h>
+#include <linux/kobject.h>
+
+#define SC_PM_PW_MODE_FAIL (SC_PM_PW_MODE_ON + 1)
+static struct dentry *imx8_rsrc_pm_debugfs_dir;
+
+static int imx8_rsrc_pm_summary_one(struct seq_file *s,
+ sc_rsrc_t rsrc_id)
+{
+ static const char * const status_lookup[] = {
+ [SC_PM_PW_MODE_OFF] = "OFF",
+ [SC_PM_PW_MODE_STBY] = "STBY",
+ [SC_PM_PW_MODE_LP] = "LP",
+ [SC_PM_PW_MODE_ON] = "ON",
+ [SC_PM_PW_MODE_FAIL] = "FAIL",
+ };
+ sc_err_t sci_err = SC_ERR_NONE;
+ sc_pm_power_mode_t mode;
+ char state[16];
+
+ sci_err = sc_pm_get_resource_power_mode(pm_ipc_handle, rsrc_id, &mode);
+ if (sci_err) {
+ pr_debug("failed to get power mode on resource %d, ret %d\n",
+ rsrc_id, sci_err);
+ mode = SC_PM_PW_MODE_FAIL;
+ }
+
+ if (WARN_ON(mode >= ARRAY_SIZE(status_lookup)))
+ return 0;
+
+ snprintf(state, sizeof(state), "%s", status_lookup[mode]);
+ seq_printf(s, "%-30d %-15s ", rsrc_id, state);
+ seq_puts(s, "\n");
+
+ return 0;
+}
+
+static int imx8_rsrc_pm_summary_show(struct seq_file *s, void *data)
+{
+ int ret = 0;
+ int i;
+
+ seq_puts(s, "resource_id power_mode\n");
+ seq_puts(s, "---------------------------------------------\n");
+
+ ret = mutex_lock_interruptible(&rsrc_pm_list_lock);
+ if (ret)
+ return -ERESTARTSYS;
+
+ for (i = 0; i < SC_R_LAST; i++) {
+ ret = imx8_rsrc_pm_summary_one(s, i);
+ if (ret)
+ break;
+ }
+ mutex_unlock(&rsrc_pm_list_lock);
+
+ return ret;
+}
+
+static int imx8_rsrc_pm_summary_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, imx8_rsrc_pm_summary_show, NULL);
+}
+
+static const struct file_operations imx8_rsrc_pm_summary_fops = {
+ .open = imx8_rsrc_pm_summary_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
+static int __init imx8_pm_debug_init(void)
+{
+ struct dentry *d;
+
+ /* skip for non-SCFW system */
+ if (!of_find_compatible_node(NULL, NULL, "nxp,imx8-pd"))
+ return 0;
+
+ imx8_rsrc_pm_debugfs_dir = debugfs_create_dir("imx_rsrc_pm", NULL);
+
+ if (!imx8_rsrc_pm_debugfs_dir)
+ return -ENOMEM;
+
+ d = debugfs_create_file("imx_rsrc_pm_summary", 0444,
+ imx8_rsrc_pm_debugfs_dir, NULL,
+ &imx8_rsrc_pm_summary_fops);
+ if (!d)
+ return -ENOMEM;
+
+ return 0;
+}
+late_initcall(imx8_pm_debug_init);
+
+static void __exit imx8_rsrc_pm_debug_exit(void)
+{
+ debugfs_remove_recursive(imx8_rsrc_pm_debugfs_dir);
+}
+__exitcall(imx8_rsrc_pm_debug_exit);
+#endif /* CONFIG_DEBUG_FS */
diff --git a/drivers/soc/imx/sc/Makefile b/drivers/soc/imx/sc/Makefile
new file mode 100644
index 000000000000..aa22af211519
--- /dev/null
+++ b/drivers/soc/imx/sc/Makefile
@@ -0,0 +1,9 @@
+obj-y += main/ipc.o
+obj-y += svc/misc/rpc_clnt.o
+obj-y += svc/pad/rpc_clnt.o
+obj-y += svc/pm/rpc_clnt.o
+obj-y += svc/rm/rpc_clnt.o
+obj-y += svc/timer/rpc_clnt.o
+obj-y += svc/irq/rpc_clnt.o
+obj-y += svc/seco/rpc_clnt.o
+
diff --git a/drivers/soc/imx/sc/main/ipc.c b/drivers/soc/imx/sc/main/ipc.c
new file mode 100644
index 000000000000..c070089dbfcd
--- /dev/null
+++ b/drivers/soc/imx/sc/main/ipc.c
@@ -0,0 +1,420 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017-2018 NXP
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+/* Includes */
+#include <linux/arm-smccc.h>
+#include <linux/err.h>
+#include <linux/kernel.h>
+#include <linux/of.h>
+#include <linux/of_irq.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/of_fdt.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/mx8_mu.h>
+#include <linux/syscore_ops.h>
+
+#include <soc/imx/fsl_hvc.h>
+#include <soc/imx8/sc/svc/irq/api.h>
+#include <soc/imx8/sc/ipc.h>
+#include <soc/imx8/sc/sci.h>
+
+#include "rpc.h"
+
+/* Local Defines */
+#define MU_SIZE 0x10000
+
+/* Local Types */
+unsigned int scu_mu_id;
+static void __iomem *mu_base_virtaddr;
+static struct delayed_work scu_mu_work;
+static sc_ipc_t mu_ipcHandle;
+
+/* Local functions */
+
+/* Local variables */
+static uint32_t gIPCport;
+static bool scu_mu_init;
+
+DEFINE_MUTEX(scu_mu_mutex);
+
+static BLOCKING_NOTIFIER_HEAD(SCU_notifier_chain);
+
+EXPORT_SYMBOL(sc_pm_set_resource_power_mode);
+EXPORT_SYMBOL(sc_pm_get_resource_power_mode);
+EXPORT_SYMBOL(sc_pm_cpu_start);
+EXPORT_SYMBOL(sc_misc_set_control);
+EXPORT_SYMBOL(sc_pm_clock_enable);
+EXPORT_SYMBOL(sc_pm_set_clock_rate);
+/*--------------------------------------------------------------------------*/
+/* RPC command/response */
+/*--------------------------------------------------------------------------*/
+void sc_call_rpc(sc_ipc_t handle, sc_rpc_msg_t *msg, sc_bool_t no_resp)
+{
+ struct arm_smccc_res res;
+
+ if (in_interrupt()) {
+ pr_warn("Cannot make SC IPC calls from an interrupt context\n");
+ dump_stack();
+ return;
+ }
+ mutex_lock(&scu_mu_mutex);
+
+ if (xen_initial_domain()) {
+ arm_smccc_hvc(FSL_HVC_SC, (uint64_t)msg, no_resp, 0, 0, 0, 0,
+ 0, &res);
+ if (res.a0)
+ printk("Error FSL_HVC_SC %ld\n", res.a0);
+ } else {
+ sc_ipc_write(handle, msg);
+ if (!no_resp)
+ sc_ipc_read(handle, msg);
+ }
+
+ mutex_unlock(&scu_mu_mutex);
+}
+EXPORT_SYMBOL(sc_call_rpc);
+
+/*--------------------------------------------------------------------------*/
+/* Get MU base address for specified IPC channel */
+/*--------------------------------------------------------------------------*/
+static uint32_t *sc_ipc_get_mu_base(uint32_t id)
+{
+ uint32_t *base;
+
+ /* Check parameters */
+ if (id >= SC_NUM_IPC)
+ base = NULL;
+ else
+ base = (uint32_t *) (mu_base_virtaddr + (id * MU_SIZE));
+
+ return base;
+}
+
+/*--------------------------------------------------------------------------*/
+/* Get the MU ID used by Linux */
+/*--------------------------------------------------------------------------*/
+int sc_ipc_getMuID(uint32_t *mu_id)
+{
+ if (scu_mu_init) {
+ *mu_id = scu_mu_id;
+ return SC_ERR_NONE;
+ }
+ return SC_ERR_UNAVAILABLE;
+}
+
+EXPORT_SYMBOL(sc_ipc_getMuID);
+
+/*--------------------------------------------------------------------------*/
+/* Open an IPC channel */
+/*--------------------------------------------------------------------------*/
+sc_err_t sc_ipc_requestInt(sc_ipc_t *handle, uint32_t id)
+{
+ return SC_ERR_NONE;
+}
+
+/*--------------------------------------------------------------------------*/
+/* Open an IPC channel */
+/*--------------------------------------------------------------------------*/
+sc_err_t sc_ipc_open(sc_ipc_t *handle, uint32_t id)
+{
+ uint32_t *base;
+
+ mutex_lock(&scu_mu_mutex);
+
+ if (!scu_mu_init) {
+ mutex_unlock(&scu_mu_mutex);
+ return SC_ERR_UNAVAILABLE;
+ }
+ /* Get MU base associated with IPC channel */
+ base = sc_ipc_get_mu_base(id);
+
+ if (base == NULL) {
+ mutex_unlock(&scu_mu_mutex);
+ return SC_ERR_IPC;
+ }
+
+ *handle = (sc_ipc_t) task_pid_vnr(current);
+
+ mutex_unlock(&scu_mu_mutex);
+
+ return SC_ERR_NONE;
+}
+EXPORT_SYMBOL(sc_ipc_open);
+/*--------------------------------------------------------------------------*/
+/* Close an IPC channel */
+/*--------------------------------------------------------------------------*/
+void sc_ipc_close(sc_ipc_t handle)
+{
+ uint32_t *base;
+
+ mutex_lock(&scu_mu_mutex);
+
+ if (!scu_mu_init) {
+ mutex_unlock(&scu_mu_mutex);
+ return;
+ }
+
+ /* Get MU base associated with IPC channel */
+ base = sc_ipc_get_mu_base(gIPCport);
+
+ /* TBD ***** What needs to be done here? */
+ mutex_unlock(&scu_mu_mutex);
+}
+EXPORT_SYMBOL(sc_ipc_close);
+
+/*!
+ * This function reads a message from an IPC channel.
+ *
+ * @param[in] ipc id of channel read from
+ * @param[out] data pointer to message buffer to read
+ *
+ * This function will block if no message is available to be read.
+ */
+void sc_ipc_read(sc_ipc_t handle, void *data)
+{
+ uint32_t *base;
+ uint8_t count = 0;
+ sc_rpc_msg_t *msg = (sc_rpc_msg_t *) data;
+
+ /* Get MU base associated with IPC channel */
+ base = sc_ipc_get_mu_base(gIPCport);
+
+ if ((base == NULL) || (msg == NULL))
+ return;
+
+ /* Read first word */
+ MU_ReceiveMsg(base, 0, (uint32_t *) msg);
+ count++;
+
+ /* Check size */
+ if (msg->size > SC_RPC_MAX_MSG) {
+ *((uint32_t *) msg) = 0;
+ return;
+ }
+
+ /* Read remaining words */
+ while (count < msg->size) {
+ MU_ReceiveMsg(base, count % MU_RR_COUNT,
+ &(msg->DATA.u32[count - 1]));
+ count++;
+ }
+}
+
+/*!
+ * This function writes a message to an IPC channel.
+ *
+ * @param[in] ipc id of channel to write to
+ * @param[in] data pointer to message buffer to write
+ *
+ * This function will block if the outgoing buffer is full.
+ */
+void sc_ipc_write(sc_ipc_t handle, const void *data)
+{
+ uint32_t *base;
+ uint8_t count = 0;
+ sc_rpc_msg_t *msg = (sc_rpc_msg_t *) data;
+
+ /* Get MU base associated with IPC channel */
+ base = sc_ipc_get_mu_base(gIPCport);
+
+ if ((base == NULL) || (msg == NULL))
+ return;
+
+ /* Check size */
+ if (msg->size > SC_RPC_MAX_MSG)
+ return;
+
+ /* Write first word */
+ MU_SendMessage(base, 0, *((uint32_t *) msg));
+ count++;
+
+ /* Write remaining words */
+ while (count < msg->size) {
+ MU_SendMessage(base, count % MU_TR_COUNT, msg->DATA.u32[count - 1]);
+ count++;
+ }
+}
+
+int register_scu_notifier(struct notifier_block *nb)
+{
+ return blocking_notifier_chain_register(&SCU_notifier_chain, nb);
+}
+
+EXPORT_SYMBOL(register_scu_notifier);
+
+int unregister_scu_notifier(struct notifier_block *nb)
+{
+ return blocking_notifier_chain_unregister(&SCU_notifier_chain, nb);
+}
+
+EXPORT_SYMBOL(unregister_scu_notifier);
+
+static int SCU_notifier_call_chain(unsigned long status, sc_irq_group_t *group)
+{
+ return blocking_notifier_call_chain(&SCU_notifier_chain, status,
+ (void *)group);
+}
+
+static void scu_mu_work_handler(struct work_struct *work)
+{
+ uint32_t irq_status;
+ sc_err_t sciErr;
+ sc_irq_group_t i;
+
+ /* Walk all groups interrupt callback, callback will judge if it's
+ * the right group for itself, return directly if not.
+ */
+ for (i = 0; i < SC_IRQ_NUM_GROUP; i++) {
+ sciErr = sc_irq_status(mu_ipcHandle, SC_R_MU_1A, i,
+ &irq_status);
+ /* no irq? */
+ if (!irq_status)
+ continue;
+
+ SCU_notifier_call_chain(irq_status, &i);
+ }
+}
+
+static irqreturn_t imx8_scu_mu_isr(int irq, void *param)
+{
+ u32 irqs;
+
+ irqs = (readl_relaxed(mu_base_virtaddr + 0x20) & (0xf << 28));
+ if (irqs) {
+ /* Clear the General Interrupt */
+ writel_relaxed(irqs, mu_base_virtaddr + 0x20);
+ /* Setup a bottom-half to handle the irq work. */
+ schedule_delayed_work(&scu_mu_work, 0);
+ }
+ return IRQ_HANDLED;
+}
+
+static void imx8_mu_resume(void)
+{
+ int i;
+
+ MU_Init(mu_base_virtaddr);
+ for (i = 0; i < MU_RR_COUNT; i++)
+ MU_EnableGeneralInt(mu_base_virtaddr, i);
+}
+
+struct syscore_ops imx8_mu_syscore_ops = {
+ .resume = imx8_mu_resume,
+};
+
+/*Initialization of the MU code. */
+int __init imx8_mu_init(void)
+{
+ struct device_node *np;
+ int irq;
+ int err;
+ sc_err_t sciErr;
+
+ /*
+ * Get the address of MU to be used for communication with the SCU
+ */
+ np = of_find_compatible_node(NULL, NULL, "fsl,imx8-mu");
+ if (!np) {
+ pr_info("Cannot find MU entry in device tree\n");
+ return 0;
+ }
+ mu_base_virtaddr = of_iomap(np, 0);
+ WARN_ON(!mu_base_virtaddr);
+
+ err = of_property_read_u32_index(np, "fsl,scu_ap_mu_id", 0, &scu_mu_id);
+ if (err)
+ pr_info("imx8_mu_init: Cannot get mu_id err = %d\n", err);
+
+ irq = of_irq_get(np, 0);
+
+ if (irq <= 0) {
+ /* SCU works just fine without irq */
+ pr_warn("imx8_mu_init: no irq: %d\n", irq);
+ } else {
+ err = request_irq(irq, imx8_scu_mu_isr,
+ IRQF_EARLY_RESUME, "imx8_mu_isr", NULL);
+ if (err) {
+ pr_err("imx8_mu_init: request_irq %d failed: %d\n",
+ irq, err);
+ return err;
+ }
+
+ irq_set_irq_wake(irq, 1);
+ }
+
+ if (!scu_mu_init) {
+ uint32_t i;
+
+ INIT_DELAYED_WORK(&scu_mu_work, scu_mu_work_handler);
+
+ /* Init MU */
+ MU_Init(mu_base_virtaddr);
+
+#if 1
+ /* Enable all RX interrupts */
+ for (i = 0; i < MU_RR_COUNT; i++)
+ MU_EnableGeneralInt(mu_base_virtaddr, i);
+#endif
+ gIPCport = scu_mu_id;
+ scu_mu_init = true;
+ }
+
+ sciErr = sc_ipc_open(&mu_ipcHandle, scu_mu_id);
+ if (sciErr != SC_ERR_NONE) {
+ pr_info("Cannot open MU channel to SCU\n");
+ return sciErr;
+ };
+
+ /* Request for the high temp interrupt. */
+ sciErr = sc_irq_enable(mu_ipcHandle, SC_R_MU_1A, SC_IRQ_GROUP_TEMP,
+ SC_IRQ_TEMP_PMIC0_HIGH, true);
+
+ if (sciErr)
+ pr_info("Cannot request PMIC0_TEMP interrupt\n");
+
+ /* Request for the high temp interrupt. */
+ sciErr = sc_irq_enable(mu_ipcHandle, SC_R_MU_1A, SC_IRQ_GROUP_TEMP,
+ SC_IRQ_TEMP_PMIC1_HIGH, true);
+
+ if (sciErr)
+ pr_info("Cannot request PMIC1_TEMP interrupt\n");
+
+ /* Request for the rtc alarm interrupt. */
+ sciErr = sc_irq_enable(mu_ipcHandle, SC_R_MU_1A, SC_IRQ_GROUP_RTC,
+ SC_IRQ_RTC, true);
+
+ if (sciErr)
+ pr_info("Cannot request ALARM_RTC interrupt\n");
+
+ /* Request for the ON/OFF interrupt. */
+ sciErr = sc_irq_enable(mu_ipcHandle, SC_R_MU_1A, SC_IRQ_GROUP_WAKE,
+ SC_IRQ_BUTTON, true);
+
+ if (sciErr)
+ pr_info("Cannot request ON/OFF interrupt\n");
+
+ /* Request for the watchdog interrupt. */
+ sciErr = sc_irq_enable(mu_ipcHandle, SC_R_MU_1A, SC_IRQ_GROUP_WDOG,
+ SC_IRQ_WDOG, true);
+
+ if (sciErr)
+ pr_info("Cannot request WDOG interrupt\n");
+
+ sciErr = sc_irq_enable(mu_ipcHandle, SC_R_MU_1A, SC_IRQ_GROUP_WAKE,
+ SC_IRQ_PAD, true);
+ if (sciErr)
+ pr_info("Cannot request PAD interrupt\n");
+
+ register_syscore_ops(&imx8_mu_syscore_ops);
+
+ pr_info("*****Initialized MU\n");
+ return scu_mu_id;
+}
+
+early_initcall(imx8_mu_init);
diff --git a/drivers/soc/imx/sc/main/rpc.h b/drivers/soc/imx/sc/main/rpc.h
new file mode 100644
index 000000000000..d9a8cb8170ac
--- /dev/null
+++ b/drivers/soc/imx/sc/main/rpc.h
@@ -0,0 +1,158 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017-2019 NXP
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+/*!
+ * Header file for the RPC implementation.
+ */
+
+#ifndef SC_RPC_H
+#define SC_RPC_H
+
+/* Includes */
+
+#include <soc/imx8/sc/types.h>
+#include <soc/imx8/sc/ipc.h>
+
+/* Defines */
+
+#define SCFW_API_VERSION_MAJOR 1U
+#define SCFW_API_VERSION_MINOR 4U
+
+#define SC_RPC_VERSION 1U
+
+#define SC_RPC_MAX_MSG 8U
+
+#define RPC_VER(MESG) ((MESG)->version)
+#define RPC_SIZE(MESG) ((MESG)->size)
+#define RPC_SVC(MESG) ((MESG)->svc)
+#define RPC_FUNC(MESG) ((MESG)->func)
+#define RPC_R8(MESG) ((MESG)->func)
+#define RPC_I32(MESG, IDX) ((MESG)->DATA.i32[(IDX) / 4U])
+#define RPC_I16(MESG, IDX) ((MESG)->DATA.i16[(IDX) / 2U])
+#define RPC_I8(MESG, IDX) ((MESG)->DATA.i8[(IDX)])
+#define RPC_U32(MESG, IDX) ((MESG)->DATA.u32[(IDX) / 4U])
+#define RPC_U16(MESG, IDX) ((MESG)->DATA.u16[(IDX) / 2U])
+#define RPC_U8(MESG, IDX) ((MESG)->DATA.u8[(IDX)])
+
+#define SC_RPC_SVC_UNKNOWN 0U
+#define SC_RPC_SVC_RETURN 1U
+#define SC_RPC_SVC_PM 2U
+#define SC_RPC_SVC_RM 3U
+#define SC_RPC_SVC_TIMER 5U
+#define SC_RPC_SVC_PAD 6U
+#define SC_RPC_SVC_MISC 7U
+#define SC_RPC_SVC_IRQ 8U
+#define SC_RPC_SVC_SECO 9U
+#define SC_RPC_SVC_ABORT 10U
+
+#define SC_RPC_ASYNC_STATE_RD_START 0U
+#define SC_RPC_ASYNC_STATE_RD_ACTIVE 1U
+#define SC_RPC_ASYNC_STATE_RD_DONE 2U
+#define SC_RPC_ASYNC_STATE_WR_START 3U
+#define SC_RPC_ASYNC_STATE_WR_ACTIVE 4U
+#define SC_RPC_ASYNC_STATE_WR_DONE 5U
+
+#define SC_RPC_MU_GIR_SVC 0x1U
+#define SC_RPC_MU_GIR_WAKE 0x2U
+#define SC_RPC_MU_GIR_BOOT 0x4U
+#define SC_RPC_MU_GIR_DBG 0x8U
+
+#define I8(X) ((int8_t) (X))
+#define I16(X) ((int16_t) (X))
+#define I32(X) ((int32_t) (X))
+#define I64(X) ((int64_t) (X))
+#define U8(X) ((uint8_t) (X))
+#define U16(X) ((uint16_t) (X))
+#define U32(X) ((uint32_t) (X))
+#define U64(X) ((uint64_t) (X))
+
+#define PTR_I8(X) ((int8_t *) (X))
+#define PTR_I16(X) ((int16_t *) (X))
+#define PTR_I32(X) ((int32_t *) (X))
+#define PTR_I64(X) ((int64_t *) (X))
+#define PTR_U8(X) ((uint8_t *) (X))
+#define PTR_U16(X) ((uint16_t *) (X))
+#define PTR_U32(X) ((uint32_t *) (X))
+#define PTR_U64(X) ((uint64_t *) (X))
+
+#define U2B(X) (((X) != 0U) ? SC_TRUE : SC_FALSE)
+#define U2B32(X) (((X) != 0UL) ? SC_TRUE : SC_FALSE)
+#define B2U8(X) (((X) != SC_FALSE) ? U8(0x01U) : U8(0x00U))
+#define B2U16(X) (((X) != SC_FALSE) ? U16(0x01U) : U16(0x00U))
+#define B2U32(X) (((X) != SC_FALSE) ? U32(0x01U) : U32(0x00U))
+
+/* Types */
+
+typedef uint8_t sc_rpc_svc_t;
+
+typedef struct {
+ uint8_t version;
+ uint8_t size;
+ uint8_t svc;
+ uint8_t func;
+ union {
+ int32_t i32[(SC_RPC_MAX_MSG - 1U)];
+ int16_t i16[(SC_RPC_MAX_MSG - 1U) * 2U];
+ int8_t i8[(SC_RPC_MAX_MSG - 1U) * 4U];
+ uint32_t u32[(SC_RPC_MAX_MSG - 1U)];
+ uint16_t u16[(SC_RPC_MAX_MSG - 1U) * 2U];
+ uint8_t u8[(SC_RPC_MAX_MSG - 1U) * 4U];
+ } DATA;
+} sc_rpc_msg_t;
+
+typedef uint8_t sc_rpc_async_state_t;
+
+typedef struct {
+ sc_rpc_async_state_t state;
+ uint8_t wordIdx;
+ sc_rpc_msg_t msg;
+ uint32_t timeStamp;
+} sc_rpc_async_msg_t;
+
+/* Functions */
+
+/*!
+ * This is an internal function to send an RPC message over an IPC
+ * channel. It is called by client-side SCFW API function shims.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in,out] msg handle to a message
+ * @param[in] no_resp response flag
+ *
+ * If \a no_resp is SC_FALSE then this function waits for a response
+ * and returns the result in \a msg.
+ */
+void sc_call_rpc(sc_ipc_t ipc, sc_rpc_msg_t *msg, sc_bool_t no_resp);
+
+/*!
+ * This is an internal function to dispath an RPC call that has
+ * arrived via IPC over an MU. It is called by server-side SCFW.
+ *
+ * @param[in] mu MU message arrived on
+ * @param[in,out] msg handle to a message
+ *
+ * The function result is returned in \a msg.
+ */
+void sc_rpc_dispatch(sc_rsrc_t mu, sc_rpc_msg_t *msg);
+
+/*!
+ * This function translates an RPC message and forwards on to the
+ * normal RPC API. It is used only by hypervisors.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in,out] msg handle to a message
+ *
+ * This function decodes a message, calls macros to translate the
+ * resources, pads, addresses, partitions, memory regions, etc. and
+ * then forwards on to the hypervisors SCFW API.Return results are
+ * translated back abd placed back into the message to be returned
+ * to the original API.
+ */
+void sc_rpc_xlate(sc_ipc_t ipc, sc_rpc_msg_t *msg);
+
+#endif /* SC_RPC_H */
+
diff --git a/drivers/soc/imx/sc/svc/irq/rpc.h b/drivers/soc/imx/sc/svc/irq/rpc.h
new file mode 100644
index 000000000000..2590e9ebd896
--- /dev/null
+++ b/drivers/soc/imx/sc/svc/irq/rpc.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017-2019 NXP
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+/*!
+ * Header file for the IRQ RPC implementation.
+ *
+ * @addtogroup IRQ_SVC
+ * @{
+ */
+
+#ifndef SC_IRQ_RPC_H
+#define SC_IRQ_RPC_H
+
+/* Includes */
+
+/* Defines */
+
+/*!
+ * @name Defines for RPC IRQ function calls
+ */
+/*@{*/
+#define IRQ_FUNC_UNKNOWN 0 /* Unknown function */
+#define IRQ_FUNC_ENABLE 1U /* Index for irq_enable() RPC call */
+#define IRQ_FUNC_STATUS 2U /* Index for irq_status() RPC call */
+/*@}*/
+
+/* Types */
+
+/* Functions */
+
+/*!
+ * This function dispatches an incoming IRQ RPC request.
+ *
+ * @param[in] caller_pt caller partition
+ * @param[in] msg pointer to RPC message
+ */
+void irq_dispatch(sc_rm_pt_t caller_pt, sc_rsrc_t mu, sc_rpc_msg_t *msg);
+
+#endif /* SC_IRQ_RPC_H */
+
+/**@}*/
+
diff --git a/drivers/soc/imx/sc/svc/irq/rpc_clnt.c b/drivers/soc/imx/sc/svc/irq/rpc_clnt.c
new file mode 100644
index 000000000000..9cea4d7ce8c6
--- /dev/null
+++ b/drivers/soc/imx/sc/svc/irq/rpc_clnt.c
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017-2019 NXP
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+/*!
+ * File containing client-side RPC functions for the IRQ service. These
+ * functions are ported to clients that communicate to the SC.
+ *
+ * @addtogroup IRQ_SVC
+ * @{
+ */
+
+/* Includes */
+
+#include <soc/imx8/sc/types.h>
+#include <soc/imx8/sc/svc/rm/api.h>
+#include <soc/imx8/sc/svc/irq/api.h>
+#include "../../main/rpc.h"
+#include "rpc.h"
+
+/* Local Defines */
+
+/* Local Types */
+
+/* Local Functions */
+
+sc_err_t sc_irq_enable(sc_ipc_t ipc, sc_rsrc_t resource,
+ sc_irq_group_t group, uint32_t mask, sc_bool_t enable)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_IRQ);
+ RPC_FUNC(&msg) = U8(IRQ_FUNC_ENABLE);
+ RPC_U32(&msg, 0U) = U32(mask);
+ RPC_U16(&msg, 4U) = U16(resource);
+ RPC_U8(&msg, 6U) = U8(group);
+ RPC_U8(&msg, 7U) = B2U8(enable);
+ RPC_SIZE(&msg) = 3U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_irq_status(sc_ipc_t ipc, sc_rsrc_t resource,
+ sc_irq_group_t group, uint32_t *status)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_IRQ);
+ RPC_FUNC(&msg) = U8(IRQ_FUNC_STATUS);
+ RPC_U16(&msg, 0U) = U16(resource);
+ RPC_U8(&msg, 2U) = U8(group);
+ RPC_SIZE(&msg) = 2U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ if (status != NULL)
+ *status = RPC_U32(&msg, 0U);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+/**@}*/
+
diff --git a/drivers/soc/imx/sc/svc/misc/rpc.h b/drivers/soc/imx/sc/svc/misc/rpc.h
new file mode 100644
index 000000000000..c31d193121ff
--- /dev/null
+++ b/drivers/soc/imx/sc/svc/misc/rpc.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017-2019 NXP
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+/*!
+ * Header file for the MISC RPC implementation.
+ *
+ * @addtogroup MISC_SVC
+ * @{
+ */
+
+#ifndef SC_MISC_RPC_H
+#define SC_MISC_RPC_H
+
+/* Includes */
+
+/* Defines */
+
+/*!
+ * @name Defines for RPC MISC function calls
+ */
+/*@{*/
+#define MISC_FUNC_UNKNOWN 0 /* Unknown function */
+#define MISC_FUNC_SET_CONTROL 1U /* Index for misc_set_control() RPC call */
+#define MISC_FUNC_GET_CONTROL 2U /* Index for misc_get_control() RPC call */
+#define MISC_FUNC_SET_MAX_DMA_GROUP 4U /* Index for misc_set_max_dma_group() RPC call */
+#define MISC_FUNC_SET_DMA_GROUP 5U /* Index for misc_set_dma_group() RPC call */
+#define MISC_FUNC_SECO_IMAGE_LOAD 8U /* Index for misc_seco_image_load() RPC call */
+#define MISC_FUNC_SECO_AUTHENTICATE 9U /* Index for misc_seco_authenticate() RPC call */
+#define MISC_FUNC_SECO_FUSE_WRITE 20U /* Index for misc_seco_fuse_write() RPC call */
+#define MISC_FUNC_SECO_ENABLE_DEBUG 21U /* Index for misc_seco_enable_debug() RPC call */
+#define MISC_FUNC_SECO_FORWARD_LIFECYCLE 22U /* Index for misc_seco_forward_lifecycle() RPC call */
+#define MISC_FUNC_SECO_RETURN_LIFECYCLE 23U /* Index for misc_seco_return_lifecycle() RPC call */
+#define MISC_FUNC_SECO_BUILD_INFO 24U /* Index for misc_seco_build_info() RPC call */
+#define MISC_FUNC_SECO_CHIP_INFO 25U /* Index for misc_seco_chip_info() RPC call */
+#define MISC_FUNC_SECO_ATTEST_MODE 27U /* Index for misc_seco_attest_mode() RPC call */
+#define MISC_FUNC_SECO_ATTEST 28U /* Index for misc_seco_attest() RPC call */
+#define MISC_FUNC_SECO_GET_ATTEST_PKEY 31U /* Index for misc_seco_get_attest_pkey() RPC call */
+#define MISC_FUNC_SECO_GET_ATTEST_SIGN 29U /* Index for misc_seco_get_attest_sign() RPC call */
+#define MISC_FUNC_SECO_ATTEST_VERIFY 30U /* Index for misc_seco_attest_verify() RPC call */
+#define MISC_FUNC_SECO_COMMIT 32U /* Index for misc_seco_commit() RPC call */
+#define MISC_FUNC_DEBUG_OUT 10U /* Index for misc_debug_out() RPC call */
+#define MISC_FUNC_WAVEFORM_CAPTURE 6U /* Index for misc_waveform_capture() RPC call */
+#define MISC_FUNC_BUILD_INFO 15U /* Index for misc_build_info() RPC call */
+#define MISC_FUNC_API_VER 35U /* Index for misc_api_ver() RPC call */
+#define MISC_FUNC_UNIQUE_ID 19U /* Index for misc_unique_id() RPC call */
+#define MISC_FUNC_SET_ARI 3U /* Index for misc_set_ari() RPC call */
+#define MISC_FUNC_BOOT_STATUS 7U /* Index for misc_boot_status() RPC call */
+#define MISC_FUNC_BOOT_DONE 14U /* Index for misc_boot_done() RPC call */
+#define MISC_FUNC_OTP_FUSE_READ 11U /* Index for misc_otp_fuse_read() RPC call */
+#define MISC_FUNC_OTP_FUSE_WRITE 17U /* Index for misc_otp_fuse_write() RPC call */
+#define MISC_FUNC_SET_TEMP 12U /* Index for misc_set_temp() RPC call */
+#define MISC_FUNC_GET_TEMP 13U /* Index for misc_get_temp() RPC call */
+#define MISC_FUNC_GET_BOOT_DEV 16U /* Index for misc_get_boot_dev() RPC call */
+#define MISC_FUNC_GET_BOOT_TYPE 33U /* Index for misc_get_boot_type() RPC call */
+#define MISC_FUNC_GET_BUTTON_STATUS 18U /* Index for misc_get_button_status() RPC call */
+#define MISC_FUNC_ROMPATCH_CHECKSUM 26U /* Index for misc_rompatch_checksum() RPC call */
+#define MISC_FUNC_BOARD_IOCTL 34U /* Index for misc_board_ioctl() RPC call */
+/*@}*/
+
+/* Types */
+
+/* Functions */
+
+/*!
+ * This function dispatches an incoming MISC RPC request.
+ *
+ * @param[in] caller_pt caller partition
+ * @param[in] msg pointer to RPC message
+ */
+void misc_dispatch(sc_rm_pt_t caller_pt, sc_rsrc_t mu, sc_rpc_msg_t *msg);
+
+#endif /* SC_MISC_RPC_H */
+
+/**@}*/
+
diff --git a/drivers/soc/imx/sc/svc/misc/rpc_clnt.c b/drivers/soc/imx/sc/svc/misc/rpc_clnt.c
new file mode 100644
index 000000000000..257264d394b6
--- /dev/null
+++ b/drivers/soc/imx/sc/svc/misc/rpc_clnt.c
@@ -0,0 +1,707 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017-2019 NXP
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+/*!
+ * File containing client-side RPC functions for the MISC service. These
+ * functions are ported to clients that communicate to the SC.
+ *
+ * @addtogroup MISC_SVC
+ * @{
+ */
+
+/* Includes */
+
+#include <soc/imx8/sc/types.h>
+#include <soc/imx8/sc/svc/rm/api.h>
+#include <soc/imx8/sc/svc/misc/api.h>
+#include "../../main/rpc.h"
+#include "rpc.h"
+
+/* Local Defines */
+
+/* Local Types */
+
+/* Local Functions */
+
+sc_err_t sc_misc_set_control(sc_ipc_t ipc, sc_rsrc_t resource,
+ sc_ctrl_t ctrl, uint32_t val)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_MISC);
+ RPC_FUNC(&msg) = U8(MISC_FUNC_SET_CONTROL);
+ RPC_U32(&msg, 0U) = U32(ctrl);
+ RPC_U32(&msg, 4U) = U32(val);
+ RPC_U16(&msg, 8U) = U16(resource);
+ RPC_SIZE(&msg) = 4U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_misc_get_control(sc_ipc_t ipc, sc_rsrc_t resource,
+ sc_ctrl_t ctrl, uint32_t *val)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_MISC);
+ RPC_FUNC(&msg) = U8(MISC_FUNC_GET_CONTROL);
+ RPC_U32(&msg, 0U) = U32(ctrl);
+ RPC_U16(&msg, 4U) = U16(resource);
+ RPC_SIZE(&msg) = 3U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ if (val != NULL)
+ *val = RPC_U32(&msg, 0U);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_misc_set_max_dma_group(sc_ipc_t ipc, sc_rm_pt_t pt,
+ sc_misc_dma_group_t max)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_MISC);
+ RPC_FUNC(&msg) = U8(MISC_FUNC_SET_MAX_DMA_GROUP);
+ RPC_U8(&msg, 0U) = U8(pt);
+ RPC_U8(&msg, 1U) = U8(max);
+ RPC_SIZE(&msg) = 2U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_misc_set_dma_group(sc_ipc_t ipc, sc_rsrc_t resource,
+ sc_misc_dma_group_t group)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_MISC);
+ RPC_FUNC(&msg) = U8(MISC_FUNC_SET_DMA_GROUP);
+ RPC_U16(&msg, 0U) = U16(resource);
+ RPC_U8(&msg, 2U) = U8(group);
+ RPC_SIZE(&msg) = 2U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_misc_seco_image_load(sc_ipc_t ipc, sc_faddr_t addr_src,
+ sc_faddr_t addr_dst, uint32_t len, sc_bool_t fw)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_MISC);
+ RPC_FUNC(&msg) = U8(MISC_FUNC_SECO_IMAGE_LOAD);
+ RPC_U32(&msg, 0U) = U32(addr_src >> 32ULL);
+ RPC_U32(&msg, 4U) = U32(addr_src);
+ RPC_U32(&msg, 8U) = U32(addr_dst >> 32ULL);
+ RPC_U32(&msg, 12U) = U32(addr_dst);
+ RPC_U32(&msg, 16U) = U32(len);
+ RPC_U8(&msg, 20U) = B2U8(fw);
+ RPC_SIZE(&msg) = 7U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_misc_seco_authenticate(sc_ipc_t ipc,
+ sc_misc_seco_auth_cmd_t cmd, sc_faddr_t addr)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_MISC);
+ RPC_FUNC(&msg) = U8(MISC_FUNC_SECO_AUTHENTICATE);
+ RPC_U32(&msg, 0U) = U32(addr >> 32ULL);
+ RPC_U32(&msg, 4U) = U32(addr);
+ RPC_U8(&msg, 8U) = U8(cmd);
+ RPC_SIZE(&msg) = 4U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_misc_seco_fuse_write(sc_ipc_t ipc, sc_faddr_t addr)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_MISC);
+ RPC_FUNC(&msg) = U8(MISC_FUNC_SECO_FUSE_WRITE);
+ RPC_U32(&msg, 0U) = U32(addr >> 32ULL);
+ RPC_U32(&msg, 4U) = U32(addr);
+ RPC_SIZE(&msg) = 3U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_misc_seco_enable_debug(sc_ipc_t ipc, sc_faddr_t addr)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_MISC);
+ RPC_FUNC(&msg) = U8(MISC_FUNC_SECO_ENABLE_DEBUG);
+ RPC_U32(&msg, 0U) = U32(addr >> 32ULL);
+ RPC_U32(&msg, 4U) = U32(addr);
+ RPC_SIZE(&msg) = 3U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_misc_seco_forward_lifecycle(sc_ipc_t ipc, uint32_t change)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_MISC);
+ RPC_FUNC(&msg) = U8(MISC_FUNC_SECO_FORWARD_LIFECYCLE);
+ RPC_U32(&msg, 0U) = U32(change);
+ RPC_SIZE(&msg) = 2U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_misc_seco_return_lifecycle(sc_ipc_t ipc, sc_faddr_t addr)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_MISC);
+ RPC_FUNC(&msg) = U8(MISC_FUNC_SECO_RETURN_LIFECYCLE);
+ RPC_U32(&msg, 0U) = U32(addr >> 32ULL);
+ RPC_U32(&msg, 4U) = U32(addr);
+ RPC_SIZE(&msg) = 3U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+void sc_misc_seco_build_info(sc_ipc_t ipc, uint32_t *version,
+ uint32_t *commit)
+{
+ sc_rpc_msg_t msg;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_MISC);
+ RPC_FUNC(&msg) = U8(MISC_FUNC_SECO_BUILD_INFO);
+ RPC_SIZE(&msg) = 1U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ if (version != NULL)
+ *version = RPC_U32(&msg, 0U);
+
+ if (commit != NULL)
+ *commit = RPC_U32(&msg, 4U);
+
+ return;
+}
+
+sc_err_t sc_misc_seco_chip_info(sc_ipc_t ipc, uint16_t *lc,
+ uint16_t *monotonic, uint32_t *uid_l, uint32_t *uid_h)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_MISC);
+ RPC_FUNC(&msg) = U8(MISC_FUNC_SECO_CHIP_INFO);
+ RPC_SIZE(&msg) = 1U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ if (uid_l != NULL)
+ *uid_l = RPC_U32(&msg, 0U);
+
+ if (uid_h != NULL)
+ *uid_h = RPC_U32(&msg, 4U);
+
+ if (lc != NULL)
+ *lc = RPC_U16(&msg, 8U);
+
+ if (monotonic != NULL)
+ *monotonic = RPC_U16(&msg, 10U);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_misc_seco_attest_mode(sc_ipc_t ipc, uint32_t mode)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_MISC);
+ RPC_FUNC(&msg) = U8(MISC_FUNC_SECO_ATTEST_MODE);
+ RPC_U32(&msg, 0U) = U32(mode);
+ RPC_SIZE(&msg) = 2U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_misc_seco_attest(sc_ipc_t ipc, uint64_t nonce)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_MISC);
+ RPC_FUNC(&msg) = U8(MISC_FUNC_SECO_ATTEST);
+ RPC_U32(&msg, 0U) = U32(nonce >> 32ULL);
+ RPC_U32(&msg, 4U) = U32(nonce);
+ RPC_SIZE(&msg) = 3U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_misc_seco_get_attest_pkey(sc_ipc_t ipc, sc_faddr_t addr)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_MISC);
+ RPC_FUNC(&msg) = U8(MISC_FUNC_SECO_GET_ATTEST_PKEY);
+ RPC_U32(&msg, 0U) = U32(addr >> 32ULL);
+ RPC_U32(&msg, 4U) = U32(addr);
+ RPC_SIZE(&msg) = 3U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_misc_seco_get_attest_sign(sc_ipc_t ipc, sc_faddr_t addr)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_MISC);
+ RPC_FUNC(&msg) = U8(MISC_FUNC_SECO_GET_ATTEST_SIGN);
+ RPC_U32(&msg, 0U) = U32(addr >> 32ULL);
+ RPC_U32(&msg, 4U) = U32(addr);
+ RPC_SIZE(&msg) = 3U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_misc_seco_attest_verify(sc_ipc_t ipc, sc_faddr_t addr)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_MISC);
+ RPC_FUNC(&msg) = U8(MISC_FUNC_SECO_ATTEST_VERIFY);
+ RPC_U32(&msg, 0U) = U32(addr >> 32ULL);
+ RPC_U32(&msg, 4U) = U32(addr);
+ RPC_SIZE(&msg) = 3U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_misc_seco_commit(sc_ipc_t ipc, uint32_t *info)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_MISC);
+ RPC_FUNC(&msg) = U8(MISC_FUNC_SECO_COMMIT);
+ RPC_U32(&msg, 0U) = *PTR_U32(info);
+ RPC_SIZE(&msg) = 2U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ *info = RPC_U32(&msg, 0U);
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+void sc_misc_debug_out(sc_ipc_t ipc, uint8_t ch)
+{
+ sc_rpc_msg_t msg;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_MISC);
+ RPC_FUNC(&msg) = U8(MISC_FUNC_DEBUG_OUT);
+ RPC_U8(&msg, 0U) = U8(ch);
+ RPC_SIZE(&msg) = 2U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ return;
+}
+
+sc_err_t sc_misc_waveform_capture(sc_ipc_t ipc, sc_bool_t enable)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_MISC);
+ RPC_FUNC(&msg) = U8(MISC_FUNC_WAVEFORM_CAPTURE);
+ RPC_U8(&msg, 0U) = B2U8(enable);
+ RPC_SIZE(&msg) = 2U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+void sc_misc_build_info(sc_ipc_t ipc, uint32_t *build,
+ uint32_t *commit)
+{
+ sc_rpc_msg_t msg;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_MISC);
+ RPC_FUNC(&msg) = U8(MISC_FUNC_BUILD_INFO);
+ RPC_SIZE(&msg) = 1U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ if (build != NULL)
+ *build = RPC_U32(&msg, 0U);
+
+ if (commit != NULL)
+ *commit = RPC_U32(&msg, 4U);
+}
+
+void sc_misc_api_ver(sc_ipc_t ipc, uint16_t *cl_maj,
+ uint16_t *cl_min, uint16_t *sv_maj, uint16_t *sv_min)
+{
+ sc_rpc_msg_t msg;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_MISC);
+ RPC_FUNC(&msg) = U8(MISC_FUNC_API_VER);
+ RPC_SIZE(&msg) = 1U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ if (cl_maj != NULL)
+ *cl_maj = SCFW_API_VERSION_MAJOR;
+
+ if (cl_min != NULL)
+ *cl_min = SCFW_API_VERSION_MINOR;
+
+ if (sv_maj != NULL)
+ *sv_maj = RPC_U16(&msg, 4U);
+
+ if (sv_min != NULL)
+ *sv_min = RPC_U16(&msg, 6U);
+}
+
+void sc_misc_unique_id(sc_ipc_t ipc, uint32_t *id_l,
+ uint32_t *id_h)
+{
+ sc_rpc_msg_t msg;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_MISC);
+ RPC_FUNC(&msg) = U8(MISC_FUNC_UNIQUE_ID);
+ RPC_SIZE(&msg) = 1U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ if (id_l != NULL)
+ *id_l = RPC_U32(&msg, 0U);
+
+ if (id_h != NULL)
+ *id_h = RPC_U32(&msg, 4U);
+
+ return;
+}
+
+sc_err_t sc_misc_set_ari(sc_ipc_t ipc, sc_rsrc_t resource,
+ sc_rsrc_t resource_mst, uint16_t ari, sc_bool_t enable)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_MISC);
+ RPC_FUNC(&msg) = U8(MISC_FUNC_SET_ARI);
+ RPC_U16(&msg, 0U) = U16(resource);
+ RPC_U16(&msg, 2U) = U16(resource_mst);
+ RPC_U16(&msg, 4U) = U16(ari);
+ RPC_U8(&msg, 6U) = B2U8(enable);
+ RPC_SIZE(&msg) = 3U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+void sc_misc_boot_status(sc_ipc_t ipc, sc_misc_boot_status_t status)
+{
+ sc_rpc_msg_t msg;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_MISC);
+ RPC_FUNC(&msg) = U8(MISC_FUNC_BOOT_STATUS);
+ RPC_U8(&msg, 0U) = U8(status);
+ RPC_SIZE(&msg) = 2U;
+
+ sc_call_rpc(ipc, &msg, SC_TRUE);
+
+ return;
+}
+
+sc_err_t sc_misc_boot_done(sc_ipc_t ipc, sc_rsrc_t cpu)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_MISC);
+ RPC_FUNC(&msg) = U8(MISC_FUNC_BOOT_DONE);
+ RPC_U16(&msg, 0U) = U16(cpu);
+ RPC_SIZE(&msg) = 2U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_misc_otp_fuse_read(sc_ipc_t ipc, uint32_t word, uint32_t *val)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_MISC);
+ RPC_FUNC(&msg) = U8(MISC_FUNC_OTP_FUSE_READ);
+ RPC_U32(&msg, 0U) = U32(word);
+ RPC_SIZE(&msg) = 2U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ if (val != NULL)
+ *val = RPC_U32(&msg, 0U);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_misc_otp_fuse_write(sc_ipc_t ipc, uint32_t word, uint32_t val)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_MISC);
+ RPC_FUNC(&msg) = U8(MISC_FUNC_OTP_FUSE_WRITE);
+ RPC_U32(&msg, 0U) = U32(word);
+ RPC_U32(&msg, 4U) = U32(val);
+ RPC_SIZE(&msg) = 3U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_misc_set_temp(sc_ipc_t ipc, sc_rsrc_t resource,
+ sc_misc_temp_t temp, int16_t celsius, int8_t tenths)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_MISC);
+ RPC_FUNC(&msg) = U8(MISC_FUNC_SET_TEMP);
+ RPC_U16(&msg, 0U) = U16(resource);
+ RPC_I16(&msg, 2U) = I16(celsius);
+ RPC_U8(&msg, 4U) = U8(temp);
+ RPC_I8(&msg, 5U) = I8(tenths);
+ RPC_SIZE(&msg) = 3U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_misc_get_temp(sc_ipc_t ipc, sc_rsrc_t resource,
+ sc_misc_temp_t temp, int16_t *celsius, int8_t *tenths)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_MISC);
+ RPC_FUNC(&msg) = U8(MISC_FUNC_GET_TEMP);
+ RPC_U16(&msg, 0U) = U16(resource);
+ RPC_U8(&msg, 2U) = U8(temp);
+ RPC_SIZE(&msg) = 2U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ if (celsius != NULL)
+ *celsius = RPC_I16(&msg, 0U);
+
+ result = RPC_R8(&msg);
+ if (tenths != NULL)
+ *tenths = RPC_I8(&msg, 2U);
+
+ return (sc_err_t)result;
+}
+
+void sc_misc_get_boot_dev(sc_ipc_t ipc, sc_rsrc_t *dev)
+{
+ sc_rpc_msg_t msg;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_MISC);
+ RPC_FUNC(&msg) = U8(MISC_FUNC_GET_BOOT_DEV);
+ RPC_SIZE(&msg) = 1U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ if (dev != NULL)
+ *dev = RPC_U16(&msg, 0U);
+}
+
+sc_err_t sc_misc_get_boot_type(sc_ipc_t ipc, sc_misc_bt_t *type)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_MISC);
+ RPC_FUNC(&msg) = U8(MISC_FUNC_GET_BOOT_TYPE);
+ RPC_SIZE(&msg) = 1U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ if (type != NULL)
+ *type = RPC_U8(&msg, 0U);
+
+ return (sc_err_t)result;
+}
+
+void sc_misc_get_button_status(sc_ipc_t ipc, sc_bool_t *status)
+{
+ sc_rpc_msg_t msg;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_MISC);
+ RPC_FUNC(&msg) = U8(MISC_FUNC_GET_BUTTON_STATUS);
+ RPC_SIZE(&msg) = 1U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ if (status != NULL)
+ *status = U2B(RPC_U8(&msg, 0U));
+}
+
+sc_err_t sc_misc_rompatch_checksum(sc_ipc_t ipc, uint32_t *checksum)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_MISC);
+ RPC_FUNC(&msg) = U8(MISC_FUNC_ROMPATCH_CHECKSUM);
+ RPC_SIZE(&msg) = 1U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ if (checksum != NULL)
+ *checksum = RPC_U32(&msg, 0U);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_misc_board_ioctl(sc_ipc_t ipc, uint32_t *parm1,
+ uint32_t *parm2, uint32_t *parm3)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_MISC);
+ RPC_FUNC(&msg) = U8(MISC_FUNC_BOARD_IOCTL);
+ RPC_U32(&msg, 0U) = *PTR_U32(parm1);
+ RPC_U32(&msg, 4U) = *PTR_U32(parm2);
+ RPC_U32(&msg, 8U) = *PTR_U32(parm3);
+ RPC_SIZE(&msg) = 4U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ *parm1 = RPC_U32(&msg, 0U);
+ *parm2 = RPC_U32(&msg, 4U);
+ *parm3 = RPC_U32(&msg, 8U);
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+/**@}*/
+
diff --git a/drivers/soc/imx/sc/svc/pad/rpc.h b/drivers/soc/imx/sc/svc/pad/rpc.h
new file mode 100644
index 000000000000..c72947ebf123
--- /dev/null
+++ b/drivers/soc/imx/sc/svc/pad/rpc.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017-2019 NXP
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+/*!
+ * Header file for the PAD RPC implementation.
+ *
+ * @addtogroup PAD_SVC
+ * @{
+ */
+
+#ifndef SC_PAD_RPC_H
+#define SC_PAD_RPC_H
+
+/* Includes */
+
+/* Defines */
+
+/*!
+ * @name Defines for RPC PAD function calls
+ */
+/*@{*/
+#define PAD_FUNC_UNKNOWN 0 /* Unknown function */
+#define PAD_FUNC_SET_MUX 1U /* Index for pad_set_mux() RPC call */
+#define PAD_FUNC_GET_MUX 6U /* Index for pad_get_mux() RPC call */
+#define PAD_FUNC_SET_GP 2U /* Index for pad_set_gp() RPC call */
+#define PAD_FUNC_GET_GP 7U /* Index for pad_get_gp() RPC call */
+#define PAD_FUNC_SET_WAKEUP 4U /* Index for pad_set_wakeup() RPC call */
+#define PAD_FUNC_GET_WAKEUP 9U /* Index for pad_get_wakeup() RPC call */
+#define PAD_FUNC_SET_ALL 5U /* Index for pad_set_all() RPC call */
+#define PAD_FUNC_GET_ALL 10U /* Index for pad_get_all() RPC call */
+#define PAD_FUNC_SET 15U /* Index for pad_set() RPC call */
+#define PAD_FUNC_GET 16U /* Index for pad_get() RPC call */
+#define PAD_FUNC_SET_GP_28FDSOI 11U /* Index for pad_set_gp_28fdsoi() RPC call */
+#define PAD_FUNC_GET_GP_28FDSOI 12U /* Index for pad_get_gp_28fdsoi() RPC call */
+#define PAD_FUNC_SET_GP_28FDSOI_HSIC 3U /* Index for pad_set_gp_28fdsoi_hsic() RPC call */
+#define PAD_FUNC_GET_GP_28FDSOI_HSIC 8U /* Index for pad_get_gp_28fdsoi_hsic() RPC call */
+#define PAD_FUNC_SET_GP_28FDSOI_COMP 13U /* Index for pad_set_gp_28fdsoi_comp() RPC call */
+#define PAD_FUNC_GET_GP_28FDSOI_COMP 14U /* Index for pad_get_gp_28fdsoi_comp() RPC call */
+/*@}*/
+
+/* Types */
+
+/* Functions */
+
+/*!
+ * This function dispatches an incoming PAD RPC request.
+ *
+ * @param[in] caller_pt caller partition
+ * @param[in] msg pointer to RPC message
+ */
+void pad_dispatch(sc_rm_pt_t caller_pt, sc_rsrc_t mu, sc_rpc_msg_t *msg);
+
+#endif /* SC_PAD_RPC_H */
+
+/**@}*/
+
diff --git a/drivers/soc/imx/sc/svc/pad/rpc_clnt.c b/drivers/soc/imx/sc/svc/pad/rpc_clnt.c
new file mode 100644
index 000000000000..da78b98b4927
--- /dev/null
+++ b/drivers/soc/imx/sc/svc/pad/rpc_clnt.c
@@ -0,0 +1,423 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017-2019 NXP
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+/*!
+ * File containing client-side RPC functions for the PAD service. These
+ * functions are ported to clients that communicate to the SC.
+ *
+ * @addtogroup PAD_SVC
+ * @{
+ */
+
+/* Includes */
+
+#include <soc/imx8/sc/types.h>
+#include <soc/imx8/sc/svc/rm/api.h>
+#include <soc/imx8/sc/svc/pad/api.h>
+#include "../../main/rpc.h"
+#include "rpc.h"
+
+/* Local Defines */
+
+/* Local Types */
+
+/* Local Functions */
+
+sc_err_t sc_pad_set_mux(sc_ipc_t ipc, sc_pad_t pad,
+ uint8_t mux, sc_pad_config_t config, sc_pad_iso_t iso)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_PAD);
+ RPC_FUNC(&msg) = U8(PAD_FUNC_SET_MUX);
+ RPC_U16(&msg, 0U) = U16(pad);
+ RPC_U8(&msg, 2U) = U8(mux);
+ RPC_U8(&msg, 3U) = U8(config);
+ RPC_U8(&msg, 4U) = U8(iso);
+ RPC_SIZE(&msg) = 3U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_pad_get_mux(sc_ipc_t ipc, sc_pad_t pad,
+ uint8_t *mux, sc_pad_config_t *config, sc_pad_iso_t *iso)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_PAD);
+ RPC_FUNC(&msg) = U8(PAD_FUNC_GET_MUX);
+ RPC_U16(&msg, 0U) = U16(pad);
+ RPC_SIZE(&msg) = 2U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ if (mux != NULL)
+ *mux = RPC_U8(&msg, 0U);
+
+ if (config != NULL)
+ *config = RPC_U8(&msg, 1U);
+
+ if (iso != NULL)
+ *iso = RPC_U8(&msg, 2U);
+
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_pad_set_gp(sc_ipc_t ipc, sc_pad_t pad, uint32_t ctrl)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_PAD);
+ RPC_FUNC(&msg) = U8(PAD_FUNC_SET_GP);
+ RPC_U32(&msg, 0U) = U32(ctrl);
+ RPC_U16(&msg, 4U) = U16(pad);
+ RPC_SIZE(&msg) = 3U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_pad_get_gp(sc_ipc_t ipc, sc_pad_t pad, uint32_t *ctrl)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_PAD);
+ RPC_FUNC(&msg) = U8(PAD_FUNC_GET_GP);
+ RPC_U16(&msg, 0U) = U16(pad);
+ RPC_SIZE(&msg) = 2U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ if (ctrl != NULL)
+ *ctrl = RPC_U32(&msg, 0U);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_pad_set_wakeup(sc_ipc_t ipc, sc_pad_t pad,
+ sc_pad_wakeup_t wakeup)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_PAD);
+ RPC_FUNC(&msg) = U8(PAD_FUNC_SET_WAKEUP);
+ RPC_U16(&msg, 0U) = U16(pad);
+ RPC_U8(&msg, 2U) = U8(wakeup);
+ RPC_SIZE(&msg) = 2U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_pad_get_wakeup(sc_ipc_t ipc, sc_pad_t pad,
+ sc_pad_wakeup_t *wakeup)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_PAD);
+ RPC_FUNC(&msg) = U8(PAD_FUNC_GET_WAKEUP);
+ RPC_U16(&msg, 0U) = U16(pad);
+ RPC_SIZE(&msg) = 2U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ if (wakeup != NULL)
+ *wakeup = RPC_U8(&msg, 0U);
+
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_pad_set_all(sc_ipc_t ipc, sc_pad_t pad, uint8_t mux,
+ sc_pad_config_t config, sc_pad_iso_t iso, uint32_t ctrl,
+ sc_pad_wakeup_t wakeup)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_PAD);
+ RPC_FUNC(&msg) = U8(PAD_FUNC_SET_ALL);
+ RPC_U32(&msg, 0U) = U32(ctrl);
+ RPC_U16(&msg, 4U) = U16(pad);
+ RPC_U8(&msg, 6U) = U8(mux);
+ RPC_U8(&msg, 7U) = U8(config);
+ RPC_U8(&msg, 8U) = U8(iso);
+ RPC_U8(&msg, 9U) = U8(wakeup);
+ RPC_SIZE(&msg) = 4U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_pad_get_all(sc_ipc_t ipc, sc_pad_t pad, uint8_t *mux,
+ sc_pad_config_t *config, sc_pad_iso_t *iso, uint32_t *ctrl,
+ sc_pad_wakeup_t *wakeup)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_PAD);
+ RPC_FUNC(&msg) = U8(PAD_FUNC_GET_ALL);
+ RPC_U16(&msg, 0U) = U16(pad);
+ RPC_SIZE(&msg) = 2U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ if (ctrl != NULL)
+ *ctrl = RPC_U32(&msg, 0U);
+
+ result = RPC_R8(&msg);
+ if (mux != NULL)
+ *mux = RPC_U8(&msg, 4U);
+
+ if (config != NULL)
+ *config = RPC_U8(&msg, 5U);
+
+ if (iso != NULL)
+ *iso = RPC_U8(&msg, 6U);
+
+ if (wakeup != NULL)
+ *wakeup = RPC_U8(&msg, 7U);
+
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_pad_set(sc_ipc_t ipc, sc_pad_t pad, uint32_t val)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_PAD);
+ RPC_FUNC(&msg) = U8(PAD_FUNC_SET);
+ RPC_U32(&msg, 0U) = U32(val);
+ RPC_U16(&msg, 4U) = U16(pad);
+ RPC_SIZE(&msg) = 3U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_pad_get(sc_ipc_t ipc, sc_pad_t pad, uint32_t *val)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_PAD);
+ RPC_FUNC(&msg) = U8(PAD_FUNC_GET);
+ RPC_U16(&msg, 0U) = U16(pad);
+ RPC_SIZE(&msg) = 2U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ if (val != NULL)
+ *val = RPC_U32(&msg, 0U);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_pad_set_gp_28fdsoi(sc_ipc_t ipc, sc_pad_t pad,
+ sc_pad_28fdsoi_dse_t dse, sc_pad_28fdsoi_ps_t ps)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_PAD);
+ RPC_FUNC(&msg) = U8(PAD_FUNC_SET_GP_28FDSOI);
+ RPC_U16(&msg, 0U) = U16(pad);
+ RPC_U8(&msg, 2U) = U8(dse);
+ RPC_U8(&msg, 3U) = U8(ps);
+ RPC_SIZE(&msg) = 2U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_pad_get_gp_28fdsoi(sc_ipc_t ipc, sc_pad_t pad,
+ sc_pad_28fdsoi_dse_t *dse, sc_pad_28fdsoi_ps_t *ps)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_PAD);
+ RPC_FUNC(&msg) = U8(PAD_FUNC_GET_GP_28FDSOI);
+ RPC_U16(&msg, 0U) = U16(pad);
+ RPC_SIZE(&msg) = 2U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ if (dse != NULL)
+ *dse = RPC_U8(&msg, 0U);
+
+ if (ps != NULL)
+ *ps = RPC_U8(&msg, 1U);
+
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_pad_set_gp_28fdsoi_hsic(sc_ipc_t ipc, sc_pad_t pad,
+ sc_pad_28fdsoi_dse_t dse, sc_bool_t hys, sc_pad_28fdsoi_pus_t pus,
+ sc_bool_t pke, sc_bool_t pue)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_PAD);
+ RPC_FUNC(&msg) = U8(PAD_FUNC_SET_GP_28FDSOI_HSIC);
+ RPC_U16(&msg, 0U) = U16(pad);
+ RPC_U8(&msg, 2U) = U8(dse);
+ RPC_U8(&msg, 3U) = U8(pus);
+ RPC_U8(&msg, 4U) = B2U8(hys);
+ RPC_U8(&msg, 5U) = B2U8(pke);
+ RPC_U8(&msg, 6U) = B2U8(pue);
+ RPC_SIZE(&msg) = 3U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_pad_get_gp_28fdsoi_hsic(sc_ipc_t ipc, sc_pad_t pad,
+ sc_pad_28fdsoi_dse_t *dse, sc_bool_t *hys, sc_pad_28fdsoi_pus_t *pus,
+ sc_bool_t *pke, sc_bool_t *pue)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_PAD);
+ RPC_FUNC(&msg) = U8(PAD_FUNC_GET_GP_28FDSOI_HSIC);
+ RPC_U16(&msg, 0U) = U16(pad);
+ RPC_SIZE(&msg) = 2U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ if (dse != NULL)
+ *dse = RPC_U8(&msg, 0U);
+
+ if (pus != NULL)
+ *pus = RPC_U8(&msg, 1U);
+
+ if (hys != NULL)
+ *hys = U2B(RPC_U8(&msg, 2U));
+
+ if (pke != NULL)
+ *pke = U2B(RPC_U8(&msg, 3U));
+
+ if (pue != NULL)
+ *pue = U2B(RPC_U8(&msg, 4U));
+
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_pad_set_gp_28fdsoi_comp(sc_ipc_t ipc, sc_pad_t pad,
+ uint8_t compen, sc_bool_t fastfrz, uint8_t rasrcp, uint8_t rasrcn,
+ sc_bool_t nasrc_sel, sc_bool_t psw_ovr)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_PAD);
+ RPC_FUNC(&msg) = U8(PAD_FUNC_SET_GP_28FDSOI_COMP);
+ RPC_U16(&msg, 0U) = U16(pad);
+ RPC_U8(&msg, 2U) = U8(compen);
+ RPC_U8(&msg, 3U) = U8(rasrcp);
+ RPC_U8(&msg, 4U) = U8(rasrcn);
+ RPC_U8(&msg, 5U) = B2U8(fastfrz);
+ RPC_U8(&msg, 6U) = B2U8(nasrc_sel);
+ RPC_U8(&msg, 7U) = B2U8(psw_ovr);
+ RPC_SIZE(&msg) = 3U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_pad_get_gp_28fdsoi_comp(sc_ipc_t ipc, sc_pad_t pad,
+ uint8_t *compen, sc_bool_t *fastfrz, uint8_t *rasrcp, uint8_t *rasrcn,
+ sc_bool_t *nasrc_sel, sc_bool_t *compok, uint8_t *nasrc, sc_bool_t *psw_ovr)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_PAD);
+ RPC_FUNC(&msg) = U8(PAD_FUNC_GET_GP_28FDSOI_COMP);
+ RPC_U16(&msg, 0U) = U16(pad);
+ RPC_SIZE(&msg) = 2U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ if (compen != NULL)
+ *compen = RPC_U8(&msg, 0U);
+
+ if (rasrcp != NULL)
+ *rasrcp = RPC_U8(&msg, 1U);
+
+ if (rasrcn != NULL)
+ *rasrcn = RPC_U8(&msg, 2U);
+
+ if (nasrc != NULL)
+ *nasrc = RPC_U8(&msg, 3U);
+
+ if (fastfrz != NULL)
+ *fastfrz = U2B(RPC_U8(&msg, 4U));
+
+ if (nasrc_sel != NULL)
+ *nasrc_sel = U2B(RPC_U8(&msg, 5U));
+
+ if (compok != NULL)
+ *compok = U2B(RPC_U8(&msg, 6U));
+
+ if (psw_ovr != NULL)
+ *psw_ovr = U2B(RPC_U8(&msg, 7U));
+
+ return (sc_err_t)result;
+}
+
+/**@}*/
+
diff --git a/drivers/soc/imx/sc/svc/pm/rpc.h b/drivers/soc/imx/sc/svc/pm/rpc.h
new file mode 100644
index 000000000000..fe6ac6fe5cad
--- /dev/null
+++ b/drivers/soc/imx/sc/svc/pm/rpc.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017-2019 NXP
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+/*!
+ * Header file for the PM RPC implementation.
+ *
+ * @addtogroup PM_SVC
+ * @{
+ */
+
+#ifndef SC_PM_RPC_H
+#define SC_PM_RPC_H
+
+/* Includes */
+
+/* Defines */
+
+/*!
+ * @name Defines for RPC PM function calls
+ */
+/*@{*/
+#define PM_FUNC_UNKNOWN 0 /* Unknown function */
+#define PM_FUNC_SET_SYS_POWER_MODE 19U /* Index for pm_set_sys_power_mode() RPC call */
+#define PM_FUNC_SET_PARTITION_POWER_MODE 1U /* Index for pm_set_partition_power_mode() RPC call */
+#define PM_FUNC_GET_SYS_POWER_MODE 2U /* Index for pm_get_sys_power_mode() RPC call */
+#define PM_FUNC_SET_RESOURCE_POWER_MODE 3U /* Index for pm_set_resource_power_mode() RPC call */
+#define PM_FUNC_SET_RESOURCE_POWER_MODE_ALL 22U /* Index for pm_set_resource_power_mode_all() RPC call */
+#define PM_FUNC_GET_RESOURCE_POWER_MODE 4U /* Index for pm_get_resource_power_mode() RPC call */
+#define PM_FUNC_REQ_LOW_POWER_MODE 16U /* Index for pm_req_low_power_mode() RPC call */
+#define PM_FUNC_REQ_CPU_LOW_POWER_MODE 20U /* Index for pm_req_cpu_low_power_mode() RPC call */
+#define PM_FUNC_SET_CPU_RESUME_ADDR 17U /* Index for pm_set_cpu_resume_addr() RPC call */
+#define PM_FUNC_SET_CPU_RESUME 21U /* Index for pm_set_cpu_resume() RPC call */
+#define PM_FUNC_REQ_SYS_IF_POWER_MODE 18U /* Index for pm_req_sys_if_power_mode() RPC call */
+#define PM_FUNC_SET_CLOCK_RATE 5U /* Index for pm_set_clock_rate() RPC call */
+#define PM_FUNC_GET_CLOCK_RATE 6U /* Index for pm_get_clock_rate() RPC call */
+#define PM_FUNC_CLOCK_ENABLE 7U /* Index for pm_clock_enable() RPC call */
+#define PM_FUNC_SET_CLOCK_PARENT 14U /* Index for pm_set_clock_parent() RPC call */
+#define PM_FUNC_GET_CLOCK_PARENT 15U /* Index for pm_get_clock_parent() RPC call */
+#define PM_FUNC_RESET 13U /* Index for pm_reset() RPC call */
+#define PM_FUNC_RESET_REASON 10U /* Index for pm_reset_reason() RPC call */
+#define PM_FUNC_GET_RESET_PART 26U /* Index for pm_get_reset_part() RPC call */
+#define PM_FUNC_BOOT 8U /* Index for pm_boot() RPC call */
+#define PM_FUNC_SET_BOOT_PARM 27U /* Index for pm_set_boot_parm() RPC call */
+#define PM_FUNC_REBOOT 9U /* Index for pm_reboot() RPC call */
+#define PM_FUNC_REBOOT_PARTITION 12U /* Index for pm_reboot_partition() RPC call */
+#define PM_FUNC_REBOOT_CONTINUE 25U /* Index for pm_reboot_continue() RPC call */
+#define PM_FUNC_CPU_START 11U /* Index for pm_cpu_start() RPC call */
+#define PM_FUNC_CPU_RESET 23U /* Index for pm_cpu_reset() RPC call */
+#define PM_FUNC_IS_PARTITION_STARTED 24U /* Index for pm_is_partition_started() RPC call */
+/*@}*/
+
+/* Types */
+
+/* Functions */
+
+/*!
+ * This function dispatches an incoming PM RPC request.
+ *
+ * @param[in] caller_pt caller partition
+ * @param[in] msg pointer to RPC message
+ */
+void pm_dispatch(sc_rm_pt_t caller_pt, sc_rsrc_t mu, sc_rpc_msg_t *msg);
+
+#endif /* SC_PM_RPC_H */
+
+/**@}*/
+
diff --git a/drivers/soc/imx/sc/svc/pm/rpc_clnt.c b/drivers/soc/imx/sc/svc/pm/rpc_clnt.c
new file mode 100644
index 000000000000..3170a0d42623
--- /dev/null
+++ b/drivers/soc/imx/sc/svc/pm/rpc_clnt.c
@@ -0,0 +1,561 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017-2019 NXP
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+/*!
+ * File containing client-side RPC functions for the PM service. These
+ * functions are ported to clients that communicate to the SC.
+ *
+ * @addtogroup PM_SVC
+ * @{
+ */
+
+/* Includes */
+
+#include <soc/imx8/sc/types.h>
+#include <soc/imx8/sc/svc/rm/api.h>
+#include <soc/imx8/sc/svc/pm/api.h>
+#include "../../main/rpc.h"
+#include "rpc.h"
+
+/* Local Defines */
+
+/* Local Types */
+
+/* Local Functions */
+
+sc_err_t sc_pm_set_sys_power_mode(sc_ipc_t ipc, sc_pm_power_mode_t mode)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_PM);
+ RPC_FUNC(&msg) = U8(PM_FUNC_SET_SYS_POWER_MODE);
+ RPC_U8(&msg, 0U) = U8(mode);
+ RPC_SIZE(&msg) = 2U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_pm_set_partition_power_mode(sc_ipc_t ipc, sc_rm_pt_t pt,
+ sc_pm_power_mode_t mode)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_PM);
+ RPC_FUNC(&msg) = U8(PM_FUNC_SET_PARTITION_POWER_MODE);
+ RPC_U8(&msg, 0U) = U8(pt);
+ RPC_U8(&msg, 1U) = U8(mode);
+ RPC_SIZE(&msg) = 2U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_pm_get_sys_power_mode(sc_ipc_t ipc, sc_rm_pt_t pt,
+ sc_pm_power_mode_t *mode)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_PM);
+ RPC_FUNC(&msg) = U8(PM_FUNC_GET_SYS_POWER_MODE);
+ RPC_U8(&msg, 0U) = U8(pt);
+ RPC_SIZE(&msg) = 2U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ if (mode != NULL)
+ *mode = RPC_U8(&msg, 0U);
+
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_pm_set_resource_power_mode(sc_ipc_t ipc, sc_rsrc_t resource,
+ sc_pm_power_mode_t mode)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_PM);
+ RPC_FUNC(&msg) = U8(PM_FUNC_SET_RESOURCE_POWER_MODE);
+ RPC_U16(&msg, 0U) = U16(resource);
+ RPC_U8(&msg, 2U) = U8(mode);
+ RPC_SIZE(&msg) = 2U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_pm_set_resource_power_mode_all(sc_ipc_t ipc,
+ sc_rm_pt_t pt, sc_pm_power_mode_t mode, sc_rsrc_t exclude)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_PM);
+ RPC_FUNC(&msg) = U8(PM_FUNC_SET_RESOURCE_POWER_MODE_ALL);
+ RPC_U16(&msg, 0U) = U16(exclude);
+ RPC_U8(&msg, 2U) = U8(pt);
+ RPC_U8(&msg, 3U) = U8(mode);
+ RPC_SIZE(&msg) = 2U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_pm_get_resource_power_mode(sc_ipc_t ipc, sc_rsrc_t resource,
+ sc_pm_power_mode_t *mode)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_PM);
+ RPC_FUNC(&msg) = U8(PM_FUNC_GET_RESOURCE_POWER_MODE);
+ RPC_U16(&msg, 0U) = U16(resource);
+ RPC_SIZE(&msg) = 2U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ if (mode != NULL)
+ *mode = RPC_U8(&msg, 0U);
+
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_pm_req_low_power_mode(sc_ipc_t ipc, sc_rsrc_t resource,
+ sc_pm_power_mode_t mode)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_PM);
+ RPC_FUNC(&msg) = U8(PM_FUNC_REQ_LOW_POWER_MODE);
+ RPC_U16(&msg, 0U) = U16(resource);
+ RPC_U8(&msg, 2U) = U8(mode);
+ RPC_SIZE(&msg) = 2U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_pm_req_cpu_low_power_mode(sc_ipc_t ipc, sc_rsrc_t resource,
+ sc_pm_power_mode_t mode, sc_pm_wake_src_t wake_src)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_PM);
+ RPC_FUNC(&msg) = U8(PM_FUNC_REQ_CPU_LOW_POWER_MODE);
+ RPC_U16(&msg, 0U) = U16(resource);
+ RPC_U8(&msg, 2U) = U8(mode);
+ RPC_U8(&msg, 3U) = U8(wake_src);
+ RPC_SIZE(&msg) = 2U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_pm_set_cpu_resume_addr(sc_ipc_t ipc, sc_rsrc_t resource,
+ sc_faddr_t address)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_PM);
+ RPC_FUNC(&msg) = U8(PM_FUNC_SET_CPU_RESUME_ADDR);
+ RPC_U32(&msg, 0U) = U32(address >> 32ULL);
+ RPC_U32(&msg, 4U) = U32(address);
+ RPC_U16(&msg, 8U) = U16(resource);
+ RPC_SIZE(&msg) = 4U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_pm_set_cpu_resume(sc_ipc_t ipc, sc_rsrc_t resource,
+ sc_bool_t isPrimary, sc_faddr_t address)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_PM);
+ RPC_FUNC(&msg) = U8(PM_FUNC_SET_CPU_RESUME);
+ RPC_U32(&msg, 0U) = U32(address >> 32ULL);
+ RPC_U32(&msg, 4U) = U32(address);
+ RPC_U16(&msg, 8U) = U16(resource);
+ RPC_U8(&msg, 10U) = B2U8(isPrimary);
+ RPC_SIZE(&msg) = 4U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_pm_req_sys_if_power_mode(sc_ipc_t ipc, sc_rsrc_t resource,
+ sc_pm_sys_if_t sys_if, sc_pm_power_mode_t hpm, sc_pm_power_mode_t lpm)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_PM);
+ RPC_FUNC(&msg) = U8(PM_FUNC_REQ_SYS_IF_POWER_MODE);
+ RPC_U16(&msg, 0U) = U16(resource);
+ RPC_U8(&msg, 2U) = U8(sys_if);
+ RPC_U8(&msg, 3U) = U8(hpm);
+ RPC_U8(&msg, 4U) = U8(lpm);
+ RPC_SIZE(&msg) = 3U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_pm_set_clock_rate(sc_ipc_t ipc, sc_rsrc_t resource,
+ sc_pm_clk_t clk, sc_pm_clock_rate_t *rate)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_PM);
+ RPC_FUNC(&msg) = U8(PM_FUNC_SET_CLOCK_RATE);
+ RPC_U32(&msg, 0U) = *PTR_U32(rate);
+ RPC_U16(&msg, 4U) = U16(resource);
+ RPC_U8(&msg, 6U) = U8(clk);
+ RPC_SIZE(&msg) = 3U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ *rate = RPC_U32(&msg, 0U);
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_pm_get_clock_rate(sc_ipc_t ipc, sc_rsrc_t resource,
+ sc_pm_clk_t clk, sc_pm_clock_rate_t *rate)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_PM);
+ RPC_FUNC(&msg) = U8(PM_FUNC_GET_CLOCK_RATE);
+ RPC_U16(&msg, 0U) = U16(resource);
+ RPC_U8(&msg, 2U) = U8(clk);
+ RPC_SIZE(&msg) = 2U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ if (rate != NULL)
+ *rate = RPC_U32(&msg, 0U);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_pm_clock_enable(sc_ipc_t ipc, sc_rsrc_t resource,
+ sc_pm_clk_t clk, sc_bool_t enable, sc_bool_t autog)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_PM);
+ RPC_FUNC(&msg) = U8(PM_FUNC_CLOCK_ENABLE);
+ RPC_U16(&msg, 0U) = U16(resource);
+ RPC_U8(&msg, 2U) = U8(clk);
+ RPC_U8(&msg, 3U) = B2U8(enable);
+ RPC_U8(&msg, 4U) = B2U8(autog);
+ RPC_SIZE(&msg) = 3U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_pm_set_clock_parent(sc_ipc_t ipc, sc_rsrc_t resource,
+ sc_pm_clk_t clk, sc_pm_clk_parent_t parent)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_PM);
+ RPC_FUNC(&msg) = U8(PM_FUNC_SET_CLOCK_PARENT);
+ RPC_U16(&msg, 0U) = U16(resource);
+ RPC_U8(&msg, 2U) = U8(clk);
+ RPC_U8(&msg, 3U) = U8(parent);
+ RPC_SIZE(&msg) = 2U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_pm_get_clock_parent(sc_ipc_t ipc, sc_rsrc_t resource,
+ sc_pm_clk_t clk, sc_pm_clk_parent_t *parent)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_PM);
+ RPC_FUNC(&msg) = U8(PM_FUNC_GET_CLOCK_PARENT);
+ RPC_U16(&msg, 0U) = U16(resource);
+ RPC_U8(&msg, 2U) = U8(clk);
+ RPC_SIZE(&msg) = 2U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ if (parent != NULL)
+ *parent = RPC_U8(&msg, 0U);
+
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_pm_reset(sc_ipc_t ipc, sc_pm_reset_type_t type)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_PM);
+ RPC_FUNC(&msg) = U8(PM_FUNC_RESET);
+ RPC_U8(&msg, 0U) = U8(type);
+ RPC_SIZE(&msg) = 2U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_pm_reset_reason(sc_ipc_t ipc, sc_pm_reset_reason_t *reason)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_PM);
+ RPC_FUNC(&msg) = U8(PM_FUNC_RESET_REASON);
+ RPC_SIZE(&msg) = 1U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ if (reason != NULL)
+ *reason = RPC_U8(&msg, 0U);
+
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_pm_get_reset_part(sc_ipc_t ipc, sc_rm_pt_t *pt)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_PM);
+ RPC_FUNC(&msg) = U8(PM_FUNC_GET_RESET_PART);
+ RPC_SIZE(&msg) = 1U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ if (pt != NULL)
+ *pt = RPC_U8(&msg, 0U);
+
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_pm_boot(sc_ipc_t ipc, sc_rm_pt_t pt,
+ sc_rsrc_t resource_cpu, sc_faddr_t boot_addr,
+ sc_rsrc_t resource_mu, sc_rsrc_t resource_dev)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_PM);
+ RPC_FUNC(&msg) = U8(PM_FUNC_BOOT);
+ RPC_U32(&msg, 0U) = U32(boot_addr >> 32ULL);
+ RPC_U32(&msg, 4U) = U32(boot_addr);
+ RPC_U16(&msg, 8U) = U16(resource_cpu);
+ RPC_U16(&msg, 10U) = U16(resource_mu);
+ RPC_U16(&msg, 12U) = U16(resource_dev);
+ RPC_U8(&msg, 14U) = U8(pt);
+ RPC_SIZE(&msg) = 5U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_pm_set_boot_parm(sc_ipc_t ipc,
+ sc_rsrc_t resource_cpu, sc_faddr_t boot_addr,
+ sc_rsrc_t resource_mu, sc_rsrc_t resource_dev)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_PM);
+ RPC_FUNC(&msg) = U8(PM_FUNC_SET_BOOT_PARM);
+ RPC_U32(&msg, 0U) = U32(boot_addr >> 32ULL);
+ RPC_U32(&msg, 4U) = U32(boot_addr);
+ RPC_U16(&msg, 8U) = U16(resource_cpu);
+ RPC_U16(&msg, 10U) = U16(resource_mu);
+ RPC_U16(&msg, 12U) = U16(resource_dev);
+ RPC_SIZE(&msg) = 5U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t) result;
+}
+
+void sc_pm_reboot(sc_ipc_t ipc, sc_pm_reset_type_t type)
+{
+ sc_rpc_msg_t msg;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_PM);
+ RPC_FUNC(&msg) = U8(PM_FUNC_REBOOT);
+ RPC_U8(&msg, 0U) = U8(type);
+ RPC_SIZE(&msg) = 2U;
+
+ sc_call_rpc(ipc, &msg, SC_TRUE);
+}
+
+sc_err_t sc_pm_reboot_partition(sc_ipc_t ipc, sc_rm_pt_t pt,
+ sc_pm_reset_type_t type)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_PM);
+ RPC_FUNC(&msg) = U8(PM_FUNC_REBOOT_PARTITION);
+ RPC_U8(&msg, 0U) = U8(pt);
+ RPC_U8(&msg, 1U) = U8(type);
+ RPC_SIZE(&msg) = 2U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_pm_reboot_continue(sc_ipc_t ipc, sc_rm_pt_t pt)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_PM);
+ RPC_FUNC(&msg) = U8(PM_FUNC_REBOOT_CONTINUE);
+ RPC_U8(&msg, 0U) = U8(pt);
+ RPC_SIZE(&msg) = 2U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_pm_cpu_start(sc_ipc_t ipc, sc_rsrc_t resource, sc_bool_t enable,
+ sc_faddr_t address)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_PM);
+ RPC_FUNC(&msg) = U8(PM_FUNC_CPU_START);
+ RPC_U32(&msg, 0U) = U32(address >> 32ULL);
+ RPC_U32(&msg, 4U) = U32(address);
+ RPC_U16(&msg, 8U) = U16(resource);
+ RPC_U8(&msg, 10U) = B2U8(enable);
+ RPC_SIZE(&msg) = 4U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+void sc_pm_cpu_reset(sc_ipc_t ipc, sc_rsrc_t resource, sc_faddr_t address)
+{
+ sc_rpc_msg_t msg;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_PM);
+ RPC_FUNC(&msg) = U8(PM_FUNC_CPU_RESET);
+ RPC_U32(&msg, 0U) = U32(address >> 32ULL);
+ RPC_U32(&msg, 4U) = U32(address);
+ RPC_U16(&msg, 8U) = U16(resource);
+ RPC_SIZE(&msg) = 4U;
+
+ sc_call_rpc(ipc, &msg, SC_TRUE);
+
+ return;
+}
+
+sc_bool_t sc_pm_is_partition_started(sc_ipc_t ipc, sc_rm_pt_t pt)
+{
+ sc_rpc_msg_t msg;
+ sc_bool_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_PM);
+ RPC_FUNC(&msg) = U8(PM_FUNC_IS_PARTITION_STARTED);
+ RPC_U8(&msg, 0U) = U8(pt);
+ RPC_SIZE(&msg) = 2U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = U2B(RPC_R8(&msg));
+ return result;
+}
+
+/**@}*/
+
diff --git a/drivers/soc/imx/sc/svc/rm/rpc.h b/drivers/soc/imx/sc/svc/rm/rpc.h
new file mode 100644
index 000000000000..67c5dd53c626
--- /dev/null
+++ b/drivers/soc/imx/sc/svc/rm/rpc.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017-2019 NXP
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+/*!
+ * Header file for the RM RPC implementation.
+ *
+ * @addtogroup RM_SVC
+ * @{
+ */
+
+#ifndef SC_RM_RPC_H
+#define SC_RM_RPC_H
+
+/* Includes */
+
+/* Defines */
+
+/*!
+ * @name Defines for RPC RM function calls
+ */
+/*@{*/
+#define RM_FUNC_UNKNOWN 0 /* Unknown function */
+#define RM_FUNC_PARTITION_ALLOC 1U /* Index for rm_partition_alloc() RPC call */
+#define RM_FUNC_SET_CONFIDENTIAL 31U /* Index for rm_set_confidential() RPC call */
+#define RM_FUNC_PARTITION_FREE 2U /* Index for rm_partition_free() RPC call */
+#define RM_FUNC_GET_DID 26U /* Index for rm_get_did() RPC call */
+#define RM_FUNC_PARTITION_STATIC 3U /* Index for rm_partition_static() RPC call */
+#define RM_FUNC_PARTITION_LOCK 4U /* Index for rm_partition_lock() RPC call */
+#define RM_FUNC_GET_PARTITION 5U /* Index for rm_get_partition() RPC call */
+#define RM_FUNC_SET_PARENT 6U /* Index for rm_set_parent() RPC call */
+#define RM_FUNC_MOVE_ALL 7U /* Index for rm_move_all() RPC call */
+#define RM_FUNC_ASSIGN_RESOURCE 8U /* Index for rm_assign_resource() RPC call */
+#define RM_FUNC_SET_RESOURCE_MOVABLE 9U /* Index for rm_set_resource_movable() RPC call */
+#define RM_FUNC_SET_SUBSYS_RSRC_MOVABLE 28U /* Index for rm_set_subsys_rsrc_movable() RPC call */
+#define RM_FUNC_SET_MASTER_ATTRIBUTES 10U /* Index for rm_set_master_attributes() RPC call */
+#define RM_FUNC_SET_MASTER_SID 11U /* Index for rm_set_master_sid() RPC call */
+#define RM_FUNC_SET_PERIPHERAL_PERMISSIONS 12U /* Index for rm_set_peripheral_permissions() RPC call */
+#define RM_FUNC_IS_RESOURCE_OWNED 13U /* Index for rm_is_resource_owned() RPC call */
+#define RM_FUNC_GET_RESOURCE_OWNER 33U /* Index for rm_get_resource_owner() RPC call */
+#define RM_FUNC_IS_RESOURCE_MASTER 14U /* Index for rm_is_resource_master() RPC call */
+#define RM_FUNC_IS_RESOURCE_PERIPHERAL 15U /* Index for rm_is_resource_peripheral() RPC call */
+#define RM_FUNC_GET_RESOURCE_INFO 16U /* Index for rm_get_resource_info() RPC call */
+#define RM_FUNC_MEMREG_ALLOC 17U /* Index for rm_memreg_alloc() RPC call */
+#define RM_FUNC_MEMREG_SPLIT 29U /* Index for rm_memreg_split() RPC call */
+#define RM_FUNC_MEMREG_FRAG 32U /* Index for rm_memreg_frag() RPC call */
+#define RM_FUNC_MEMREG_FREE 18U /* Index for rm_memreg_free() RPC call */
+#define RM_FUNC_FIND_MEMREG 30U /* Index for rm_find_memreg() RPC call */
+#define RM_FUNC_ASSIGN_MEMREG 19U /* Index for rm_assign_memreg() RPC call */
+#define RM_FUNC_SET_MEMREG_PERMISSIONS 20U /* Index for rm_set_memreg_permissions() RPC call */
+#define RM_FUNC_IS_MEMREG_OWNED 21U /* Index for rm_is_memreg_owned() RPC call */
+#define RM_FUNC_GET_MEMREG_INFO 22U /* Index for rm_get_memreg_info() RPC call */
+#define RM_FUNC_ASSIGN_PAD 23U /* Index for rm_assign_pad() RPC call */
+#define RM_FUNC_SET_PAD_MOVABLE 24U /* Index for rm_set_pad_movable() RPC call */
+#define RM_FUNC_IS_PAD_OWNED 25U /* Index for rm_is_pad_owned() RPC call */
+#define RM_FUNC_DUMP 27U /* Index for rm_dump() RPC call */
+/*@}*/
+
+/* Types */
+
+/* Functions */
+
+/*!
+ * This function dispatches an incoming RM RPC request.
+ *
+ * @param[in] caller_pt caller partition
+ * @param[in] msg pointer to RPC message
+ */
+void rm_dispatch(sc_rm_pt_t caller_pt, sc_rsrc_t mu, sc_rpc_msg_t *msg);
+
+#endif /* SC_RM_RPC_H */
+
+/**@}*/
+
diff --git a/drivers/soc/imx/sc/svc/rm/rpc_clnt.c b/drivers/soc/imx/sc/svc/rm/rpc_clnt.c
new file mode 100644
index 000000000000..86f9370c0b8c
--- /dev/null
+++ b/drivers/soc/imx/sc/svc/rm/rpc_clnt.c
@@ -0,0 +1,672 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017-2019 NXP
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+/*!
+ * File containing client-side RPC functions for the RM service. These
+ * functions are ported to clients that communicate to the SC.
+ *
+ * @addtogroup RM_SVC
+ * @{
+ */
+
+/* Includes */
+
+#include <soc/imx8/sc/types.h>
+#include <soc/imx8/sc/svc/rm/api.h>
+#include "../../main/rpc.h"
+#include "rpc.h"
+
+/* Local Defines */
+
+/* Local Types */
+
+/* Local Functions */
+
+sc_err_t sc_rm_partition_alloc(sc_ipc_t ipc, sc_rm_pt_t *pt, sc_bool_t secure,
+ sc_bool_t isolated, sc_bool_t restricted, sc_bool_t grant, sc_bool_t coherent)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_RM);
+ RPC_FUNC(&msg) = U8(RM_FUNC_PARTITION_ALLOC);
+ RPC_U8(&msg, 0U) = B2U8(secure);
+ RPC_U8(&msg, 1U) = B2U8(isolated);
+ RPC_U8(&msg, 2U) = B2U8(restricted);
+ RPC_U8(&msg, 3U) = B2U8(grant);
+ RPC_U8(&msg, 4U) = B2U8(coherent);
+ RPC_SIZE(&msg) = 3U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ if (pt != NULL)
+ *pt = RPC_U8(&msg, 0U);
+
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_rm_set_confidential(sc_ipc_t ipc, sc_rm_pt_t pt, sc_bool_t retro)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_RM);
+ RPC_FUNC(&msg) = U8(RM_FUNC_SET_CONFIDENTIAL);
+ RPC_U8(&msg, 0U) = U8(pt);
+ RPC_U8(&msg, 1U) = B2U8(retro);
+ RPC_SIZE(&msg) = 2U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_rm_partition_free(sc_ipc_t ipc, sc_rm_pt_t pt)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_RM);
+ RPC_FUNC(&msg) = U8(RM_FUNC_PARTITION_FREE);
+ RPC_U8(&msg, 0U) = U8(pt);
+ RPC_SIZE(&msg) = 2U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+sc_rm_did_t sc_rm_get_did(sc_ipc_t ipc)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_RM);
+ RPC_FUNC(&msg) = U8(RM_FUNC_GET_DID);
+ RPC_SIZE(&msg) = 1U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ return (sc_rm_did_t)result;
+}
+
+sc_err_t sc_rm_partition_static(sc_ipc_t ipc, sc_rm_pt_t pt,
+ sc_rm_did_t did)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_RM);
+ RPC_FUNC(&msg) = U8(RM_FUNC_PARTITION_STATIC);
+ RPC_U8(&msg, 0U) = U8(pt);
+ RPC_U8(&msg, 1U) = U8(did);
+ RPC_SIZE(&msg) = 2U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_rm_partition_lock(sc_ipc_t ipc, sc_rm_pt_t pt)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_RM);
+ RPC_FUNC(&msg) = U8(RM_FUNC_PARTITION_LOCK);
+ RPC_U8(&msg, 0U) = U8(pt);
+ RPC_SIZE(&msg) = 2U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_rm_get_partition(sc_ipc_t ipc, sc_rm_pt_t *pt)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_RM);
+ RPC_FUNC(&msg) = U8(RM_FUNC_GET_PARTITION);
+ RPC_SIZE(&msg) = 1U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ if (pt != NULL)
+ *pt = RPC_U8(&msg, 0U);
+
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_rm_set_parent(sc_ipc_t ipc, sc_rm_pt_t pt,
+ sc_rm_pt_t pt_parent)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_RM);
+ RPC_FUNC(&msg) = U8(RM_FUNC_SET_PARENT);
+ RPC_U8(&msg, 0U) = U8(pt);
+ RPC_U8(&msg, 1U) = U8(pt_parent);
+ RPC_SIZE(&msg) = 2U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_rm_move_all(sc_ipc_t ipc, sc_rm_pt_t pt_src, sc_rm_pt_t pt_dst,
+ sc_bool_t move_rsrc, sc_bool_t move_pads)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_RM);
+ RPC_FUNC(&msg) = U8(RM_FUNC_MOVE_ALL);
+ RPC_U8(&msg, 0U) = U8(pt_src);
+ RPC_U8(&msg, 1U) = U8(pt_dst);
+ RPC_U8(&msg, 2U) = B2U8(move_rsrc);
+ RPC_U8(&msg, 3U) = B2U8(move_pads);
+ RPC_SIZE(&msg) = 2U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_rm_assign_resource(sc_ipc_t ipc, sc_rm_pt_t pt,
+ sc_rsrc_t resource)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_RM);
+ RPC_FUNC(&msg) = U8(RM_FUNC_ASSIGN_RESOURCE);
+ RPC_U16(&msg, 0U) = U16(resource);
+ RPC_U8(&msg, 2U) = U8(pt);
+ RPC_SIZE(&msg) = 2U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_rm_set_resource_movable(sc_ipc_t ipc, sc_rsrc_t resource_fst,
+ sc_rsrc_t resource_lst, sc_bool_t movable)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_RM);
+ RPC_FUNC(&msg) = U8(RM_FUNC_SET_RESOURCE_MOVABLE);
+ RPC_U16(&msg, 0U) = U16(resource_fst);
+ RPC_U16(&msg, 2U) = U16(resource_lst);
+ RPC_U8(&msg, 4U) = B2U8(movable);
+ RPC_SIZE(&msg) = 3U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_rm_set_subsys_rsrc_movable(sc_ipc_t ipc, sc_rsrc_t resource,
+ sc_bool_t movable)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_RM);
+ RPC_FUNC(&msg) = U8(RM_FUNC_SET_SUBSYS_RSRC_MOVABLE);
+ RPC_U16(&msg, 0U) = U16(resource);
+ RPC_U8(&msg, 2U) = B2U8(movable);
+ RPC_SIZE(&msg) = 2U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_rm_set_master_attributes(sc_ipc_t ipc, sc_rsrc_t resource,
+ sc_rm_spa_t sa, sc_rm_spa_t pa, sc_bool_t smmu_bypass)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_RM);
+ RPC_FUNC(&msg) = U8(RM_FUNC_SET_MASTER_ATTRIBUTES);
+ RPC_U16(&msg, 0U) = U16(resource);
+ RPC_U8(&msg, 2U) = U8(sa);
+ RPC_U8(&msg, 3U) = U8(pa);
+ RPC_U8(&msg, 4U) = B2U8(smmu_bypass);
+ RPC_SIZE(&msg) = 3U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_rm_set_master_sid(sc_ipc_t ipc, sc_rsrc_t resource,
+ sc_rm_sid_t sid)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_RM);
+ RPC_FUNC(&msg) = U8(RM_FUNC_SET_MASTER_SID);
+ RPC_U16(&msg, 0U) = U16(resource);
+ RPC_U16(&msg, 2U) = U16(sid);
+ RPC_SIZE(&msg) = 2U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_rm_set_peripheral_permissions(sc_ipc_t ipc, sc_rsrc_t resource,
+ sc_rm_pt_t pt, sc_rm_perm_t perm)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_RM);
+ RPC_FUNC(&msg) = U8(RM_FUNC_SET_PERIPHERAL_PERMISSIONS);
+ RPC_U16(&msg, 0U) = U16(resource);
+ RPC_U8(&msg, 2U) = U8(pt);
+ RPC_U8(&msg, 3U) = U8(perm);
+ RPC_SIZE(&msg) = 2U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+sc_bool_t sc_rm_is_resource_owned(sc_ipc_t ipc, sc_rsrc_t resource)
+{
+ sc_rpc_msg_t msg;
+ sc_bool_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_RM);
+ RPC_FUNC(&msg) = U8(RM_FUNC_IS_RESOURCE_OWNED);
+ RPC_U16(&msg, 0U) = U16(resource);
+ RPC_SIZE(&msg) = 2U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = U2B(RPC_R8(&msg));
+ return result;
+}
+
+sc_err_t sc_rm_get_resource_owner(sc_ipc_t ipc, sc_rsrc_t resource,
+ sc_rm_pt_t *pt)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_RM);
+ RPC_FUNC(&msg) = U8(RM_FUNC_GET_RESOURCE_OWNER);
+ RPC_U16(&msg, 0U) = U16(resource);
+ RPC_SIZE(&msg) = 2U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ if (pt != NULL)
+ *pt = RPC_U8(&msg, 0U);
+
+ return (sc_err_t)result;
+}
+
+sc_bool_t sc_rm_is_resource_master(sc_ipc_t ipc, sc_rsrc_t resource)
+{
+ sc_rpc_msg_t msg;
+ sc_bool_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_RM);
+ RPC_FUNC(&msg) = U8(RM_FUNC_IS_RESOURCE_MASTER);
+ RPC_U16(&msg, 0U) = U16(resource);
+ RPC_SIZE(&msg) = 2U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = U2B(RPC_R8(&msg));
+ return result;
+}
+
+sc_bool_t sc_rm_is_resource_peripheral(sc_ipc_t ipc, sc_rsrc_t resource)
+{
+ sc_rpc_msg_t msg;
+ sc_bool_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_RM);
+ RPC_FUNC(&msg) = U8(RM_FUNC_IS_RESOURCE_PERIPHERAL);
+ RPC_U16(&msg, 0U) = U16(resource);
+ RPC_SIZE(&msg) = 2U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = U2B(RPC_R8(&msg));
+ return result;
+}
+
+sc_err_t sc_rm_get_resource_info(sc_ipc_t ipc, sc_rsrc_t resource,
+ sc_rm_sid_t *sid)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_RM);
+ RPC_FUNC(&msg) = U8(RM_FUNC_GET_RESOURCE_INFO);
+ RPC_U16(&msg, 0U) = U16(resource);
+ RPC_SIZE(&msg) = 2U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ if (sid != NULL)
+ *sid = RPC_U16(&msg, 0U);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_rm_memreg_alloc(sc_ipc_t ipc, sc_rm_mr_t *mr,
+ sc_faddr_t addr_start, sc_faddr_t addr_end)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_RM);
+ RPC_FUNC(&msg) = U8(RM_FUNC_MEMREG_ALLOC);
+ RPC_U32(&msg, 0U) = U32(addr_start >> 32ULL);
+ RPC_U32(&msg, 4U) = U32(addr_start);
+ RPC_U32(&msg, 8U) = U32(addr_end >> 32ULL);
+ RPC_U32(&msg, 12U) = U32(addr_end);
+ RPC_SIZE(&msg) = 5U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ if (mr != NULL)
+ *mr = RPC_U8(&msg, 0U);
+
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_rm_memreg_split(sc_ipc_t ipc, sc_rm_mr_t mr,
+ sc_rm_mr_t *mr_ret, sc_faddr_t addr_start, sc_faddr_t addr_end)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_RM);
+ RPC_FUNC(&msg) = U8(RM_FUNC_MEMREG_SPLIT);
+ RPC_U32(&msg, 0U) = U32(addr_start >> 32ULL);
+ RPC_U32(&msg, 4U) = U32(addr_start);
+ RPC_U32(&msg, 8U) = U32(addr_end >> 32ULL);
+ RPC_U32(&msg, 12U) = U32(addr_end);
+ RPC_U8(&msg, 16U) = U8(mr);
+ RPC_SIZE(&msg) = 6U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ if (mr_ret != NULL)
+ *mr_ret = RPC_U8(&msg, 0U);
+
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_rm_memreg_frag(sc_ipc_t ipc, sc_rm_mr_t *mr_ret,
+ sc_faddr_t addr_start, sc_faddr_t addr_end)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_RM);
+ RPC_FUNC(&msg) = U8(RM_FUNC_MEMREG_FRAG);
+ RPC_U32(&msg, 0U) = U32(addr_start >> 32ULL);
+ RPC_U32(&msg, 4U) = U32(addr_start);
+ RPC_U32(&msg, 8U) = U32(addr_end >> 32ULL);
+ RPC_U32(&msg, 12U) = U32(addr_end);
+ RPC_SIZE(&msg) = 5U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ if (mr_ret != NULL)
+ *mr_ret = RPC_U8(&msg, 0U);
+
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_rm_memreg_free(sc_ipc_t ipc, sc_rm_mr_t mr)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_RM);
+ RPC_FUNC(&msg) = U8(RM_FUNC_MEMREG_FREE);
+ RPC_U8(&msg, 0U) = U8(mr);
+ RPC_SIZE(&msg) = 2U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_rm_find_memreg(sc_ipc_t ipc, sc_rm_mr_t *mr,
+ sc_faddr_t addr_start, sc_faddr_t addr_end)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_RM);
+ RPC_FUNC(&msg) = U8(RM_FUNC_FIND_MEMREG);
+ RPC_U32(&msg, 0U) = U32(addr_start >> 32ULL);
+ RPC_U32(&msg, 4U) = U32(addr_start);
+ RPC_U32(&msg, 8U) = U32(addr_end >> 32ULL);
+ RPC_U32(&msg, 12U) = U32(addr_end);
+ RPC_SIZE(&msg) = 5U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ if (mr != NULL)
+ *mr = RPC_U8(&msg, 0U);
+
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_rm_assign_memreg(sc_ipc_t ipc, sc_rm_pt_t pt, sc_rm_mr_t mr)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_RM);
+ RPC_FUNC(&msg) = U8(RM_FUNC_ASSIGN_MEMREG);
+ RPC_U8(&msg, 0U) = U8(pt);
+ RPC_U8(&msg, 1U) = U8(mr);
+ RPC_SIZE(&msg) = 2U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_rm_set_memreg_permissions(sc_ipc_t ipc, sc_rm_mr_t mr,
+ sc_rm_pt_t pt, sc_rm_perm_t perm)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_RM);
+ RPC_FUNC(&msg) = U8(RM_FUNC_SET_MEMREG_PERMISSIONS);
+ RPC_U8(&msg, 0U) = U8(mr);
+ RPC_U8(&msg, 1U) = U8(pt);
+ RPC_U8(&msg, 2U) = U8(perm);
+ RPC_SIZE(&msg) = 2U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+sc_bool_t sc_rm_is_memreg_owned(sc_ipc_t ipc, sc_rm_mr_t mr)
+{
+ sc_rpc_msg_t msg;
+ sc_bool_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_RM);
+ RPC_FUNC(&msg) = U8(RM_FUNC_IS_MEMREG_OWNED);
+ RPC_U8(&msg, 0U) = U8(mr);
+ RPC_SIZE(&msg) = 2U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = U2B(RPC_R8(&msg));
+ return result;
+}
+
+sc_err_t sc_rm_get_memreg_info(sc_ipc_t ipc, sc_rm_mr_t mr,
+ sc_faddr_t *addr_start, sc_faddr_t *addr_end)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_RM);
+ RPC_FUNC(&msg) = U8(RM_FUNC_GET_MEMREG_INFO);
+ RPC_U8(&msg, 0U) = U8(mr);
+ RPC_SIZE(&msg) = 2U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ if (addr_start != NULL)
+ *addr_start = ((uint64_t) RPC_U32(&msg, 0U) << 32U) | RPC_U32(&msg, 4U);
+
+ if (addr_end != NULL)
+ *addr_end = ((uint64_t) RPC_U32(&msg, 8U) << 32U) | RPC_U32(&msg, 12U);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_rm_assign_pad(sc_ipc_t ipc, sc_rm_pt_t pt, sc_pad_t pad)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_RM);
+ RPC_FUNC(&msg) = U8(RM_FUNC_ASSIGN_PAD);
+ RPC_U16(&msg, 0U) = U16(pad);
+ RPC_U8(&msg, 2U) = U8(pt);
+ RPC_SIZE(&msg) = 2U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_rm_set_pad_movable(sc_ipc_t ipc, sc_pad_t pad_fst,
+ sc_pad_t pad_lst, sc_bool_t movable)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_RM);
+ RPC_FUNC(&msg) = U8(RM_FUNC_SET_PAD_MOVABLE);
+ RPC_U16(&msg, 0U) = U16(pad_fst);
+ RPC_U16(&msg, 2U) = U16(pad_lst);
+ RPC_U8(&msg, 4U) = B2U8(movable);
+ RPC_SIZE(&msg) = 3U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+sc_bool_t sc_rm_is_pad_owned(sc_ipc_t ipc, sc_pad_t pad)
+{
+ sc_rpc_msg_t msg;
+ sc_bool_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_RM);
+ RPC_FUNC(&msg) = U8(RM_FUNC_IS_PAD_OWNED);
+ RPC_U8(&msg, 0U) = U8(pad);
+ RPC_SIZE(&msg) = 2U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = U2B(RPC_R8(&msg));
+ return result;
+}
+
+void sc_rm_dump(sc_ipc_t ipc)
+{
+ sc_rpc_msg_t msg;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_RM);
+ RPC_FUNC(&msg) = U8(RM_FUNC_DUMP);
+ RPC_SIZE(&msg) = 1U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+}
+
+/**@}*/
+
diff --git a/drivers/soc/imx/sc/svc/seco/rpc.h b/drivers/soc/imx/sc/svc/seco/rpc.h
new file mode 100644
index 000000000000..ecc7311e7be9
--- /dev/null
+++ b/drivers/soc/imx/sc/svc/seco/rpc.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017-2019 NXP
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+/*!
+ * Header file for the SECO RPC implementation.
+ *
+ * @addtogroup SECO_SVC
+ * @{
+ */
+
+#ifndef SC_SECO_RPC_H
+#define SC_SECO_RPC_H
+
+/* Includes */
+
+/* Defines */
+
+/*!
+ * @name Defines for RPC SECO function calls
+ */
+/*@{*/
+#define SECO_FUNC_UNKNOWN 0 /* Unknown function */
+#define SECO_FUNC_IMAGE_LOAD 1U /* Index for seco_image_load() RPC call */
+#define SECO_FUNC_AUTHENTICATE 2U /* Index for seco_authenticate() RPC call */
+#define SECO_FUNC_FORWARD_LIFECYCLE 3U /* Index for seco_forward_lifecycle() RPC call */
+#define SECO_FUNC_RETURN_LIFECYCLE 4U /* Index for seco_return_lifecycle() RPC call */
+#define SECO_FUNC_COMMIT 5U /* Index for seco_commit() RPC call */
+#define SECO_FUNC_ATTEST_MODE 6U /* Index for seco_attest_mode() RPC call */
+#define SECO_FUNC_ATTEST 7U /* Index for seco_attest() RPC call */
+#define SECO_FUNC_GET_ATTEST_PKEY 8U /* Index for seco_get_attest_pkey() RPC call */
+#define SECO_FUNC_GET_ATTEST_SIGN 9U /* Index for seco_get_attest_sign() RPC call */
+#define SECO_FUNC_ATTEST_VERIFY 10U /* Index for seco_attest_verify() RPC call */
+#define SECO_FUNC_GEN_KEY_BLOB 11U /* Index for seco_gen_key_blob() RPC call */
+#define SECO_FUNC_LOAD_KEY 12U /* Index for seco_load_key() RPC call */
+#define SECO_FUNC_GET_MP_KEY 13U /* Index for seco_get_mp_key() RPC call */
+#define SECO_FUNC_UPDATE_MPMR 14U /* Index for seco_update_mpmr() RPC call */
+#define SECO_FUNC_GET_MP_SIGN 15U /* Index for seco_get_mp_sign() RPC call */
+#define SECO_FUNC_BUILD_INFO 16U /* Index for seco_build_info() RPC call */
+#define SECO_FUNC_CHIP_INFO 17U /* Index for seco_chip_info() RPC call */
+#define SECO_FUNC_ENABLE_DEBUG 18U /* Index for seco_enable_debug() RPC call */
+#define SECO_FUNC_GET_EVENT 19U /* Index for seco_get_event() RPC call */
+#define SECO_FUNC_FUSE_WRITE 20U /* Index for seco_fuse_write() RPC call */
+/*@}*/
+
+/* Types */
+
+/* Functions */
+
+/*!
+ * This function dispatches an incoming SECO RPC request.
+ *
+ * @param[in] caller_pt caller partition
+ * @param[in] msg pointer to RPC message
+ */
+void seco_dispatch(sc_rm_pt_t caller_pt, sc_rsrc_t mu, sc_rpc_msg_t *msg);
+
+#endif /* SC_SECO_RPC_H */
+
+/**@}*/
+
diff --git a/drivers/soc/imx/sc/svc/seco/rpc_clnt.c b/drivers/soc/imx/sc/svc/seco/rpc_clnt.c
new file mode 100644
index 000000000000..cc23324ee20c
--- /dev/null
+++ b/drivers/soc/imx/sc/svc/seco/rpc_clnt.c
@@ -0,0 +1,430 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017-2019 NXP
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+/*!
+ * File containing client-side RPC functions for the SECO service. These
+ * functions are ported to clients that communicate to the SC.
+ *
+ * @addtogroup SECO_SVC
+ * @{
+ */
+
+/* Includes */
+
+#include <soc/imx8/sc/types.h>
+#include <soc/imx8/sc/svc/rm/api.h>
+#include <soc/imx8/sc/svc/seco/api.h>
+#include "../../main/rpc.h"
+#include "rpc.h"
+
+/* Local Defines */
+
+/* Local Types */
+
+/* Local Functions */
+
+sc_err_t sc_seco_image_load(sc_ipc_t ipc, sc_faddr_t addr_src,
+ sc_faddr_t addr_dst, uint32_t len, sc_bool_t fw)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_SECO);
+ RPC_FUNC(&msg) = U8(SECO_FUNC_IMAGE_LOAD);
+ RPC_U32(&msg, 0U) = U32(addr_src >> 32ULL);
+ RPC_U32(&msg, 4U) = U32(addr_src);
+ RPC_U32(&msg, 8U) = U32(addr_dst >> 32ULL);
+ RPC_U32(&msg, 12U) = U32(addr_dst);
+ RPC_U32(&msg, 16U) = U32(len);
+ RPC_U8(&msg, 20U) = B2U8(fw);
+ RPC_SIZE(&msg) = 7U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_seco_authenticate(sc_ipc_t ipc,
+ sc_seco_auth_cmd_t cmd, sc_faddr_t addr)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_SECO);
+ RPC_FUNC(&msg) = U8(SECO_FUNC_AUTHENTICATE);
+ RPC_U32(&msg, 0U) = U32(addr >> 32ULL);
+ RPC_U32(&msg, 4U) = U32(addr);
+ RPC_U8(&msg, 8U) = U8(cmd);
+ RPC_SIZE(&msg) = 4U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_seco_forward_lifecycle(sc_ipc_t ipc, uint32_t change)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_SECO);
+ RPC_FUNC(&msg) = U8(SECO_FUNC_FORWARD_LIFECYCLE);
+ RPC_U32(&msg, 0U) = U32(change);
+ RPC_SIZE(&msg) = 2U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_seco_return_lifecycle(sc_ipc_t ipc, sc_faddr_t addr)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_SECO);
+ RPC_FUNC(&msg) = U8(SECO_FUNC_RETURN_LIFECYCLE);
+ RPC_U32(&msg, 0U) = U32(addr >> 32ULL);
+ RPC_U32(&msg, 4U) = U32(addr);
+ RPC_SIZE(&msg) = 3U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_seco_commit(sc_ipc_t ipc, uint32_t *info)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_SECO);
+ RPC_FUNC(&msg) = U8(SECO_FUNC_COMMIT);
+ RPC_U32(&msg, 0U) = *PTR_U32(info);
+ RPC_SIZE(&msg) = 2U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ *info = RPC_U32(&msg, 0U);
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_seco_attest_mode(sc_ipc_t ipc, uint32_t mode)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_SECO);
+ RPC_FUNC(&msg) = U8(SECO_FUNC_ATTEST_MODE);
+ RPC_U32(&msg, 0U) = U32(mode);
+ RPC_SIZE(&msg) = 2U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_seco_attest(sc_ipc_t ipc, uint64_t nonce)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_SECO);
+ RPC_FUNC(&msg) = U8(SECO_FUNC_ATTEST);
+ RPC_U32(&msg, 0U) = U32(nonce >> 32ULL);
+ RPC_U32(&msg, 4U) = U32(nonce);
+ RPC_SIZE(&msg) = 3U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_seco_get_attest_pkey(sc_ipc_t ipc, sc_faddr_t addr)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_SECO);
+ RPC_FUNC(&msg) = U8(SECO_FUNC_GET_ATTEST_PKEY);
+ RPC_U32(&msg, 0U) = U32(addr >> 32ULL);
+ RPC_U32(&msg, 4U) = U32(addr);
+ RPC_SIZE(&msg) = 3U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_seco_get_attest_sign(sc_ipc_t ipc, sc_faddr_t addr)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_SECO);
+ RPC_FUNC(&msg) = U8(SECO_FUNC_GET_ATTEST_SIGN);
+ RPC_U32(&msg, 0U) = U32(addr >> 32ULL);
+ RPC_U32(&msg, 4U) = U32(addr);
+ RPC_SIZE(&msg) = 3U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_seco_attest_verify(sc_ipc_t ipc, sc_faddr_t addr)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_SECO);
+ RPC_FUNC(&msg) = U8(SECO_FUNC_ATTEST_VERIFY);
+ RPC_U32(&msg, 0U) = U32(addr >> 32ULL);
+ RPC_U32(&msg, 4U) = U32(addr);
+ RPC_SIZE(&msg) = 3U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_seco_gen_key_blob(sc_ipc_t ipc, uint32_t id,
+ sc_faddr_t load_addr, sc_faddr_t export_addr, uint16_t max_size)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_SECO);
+ RPC_FUNC(&msg) = U8(SECO_FUNC_GEN_KEY_BLOB);
+ RPC_U32(&msg, 0U) = U32(load_addr >> 32ULL);
+ RPC_U32(&msg, 4U) = U32(load_addr);
+ RPC_U32(&msg, 8U) = U32(export_addr >> 32ULL);
+ RPC_U32(&msg, 12U) = U32(export_addr);
+ RPC_U32(&msg, 16U) = U32(id);
+ RPC_U16(&msg, 20U) = U16(max_size);
+ RPC_SIZE(&msg) = 7U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_seco_load_key(sc_ipc_t ipc, uint32_t id,
+ sc_faddr_t addr)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_SECO);
+ RPC_FUNC(&msg) = U8(SECO_FUNC_LOAD_KEY);
+ RPC_U32(&msg, 0U) = U32(addr >> 32ULL);
+ RPC_U32(&msg, 4U) = U32(addr);
+ RPC_U32(&msg, 8U) = U32(id);
+ RPC_SIZE(&msg) = 4U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_seco_get_mp_key(sc_ipc_t ipc, sc_faddr_t dst_addr,
+ uint16_t dst_size)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_SECO);
+ RPC_FUNC(&msg) = U8(SECO_FUNC_GET_MP_KEY);
+ RPC_U32(&msg, 0U) = U32(dst_addr >> 32ULL);
+ RPC_U32(&msg, 4U) = U32(dst_addr);
+ RPC_U16(&msg, 8U) = U16(dst_size);
+ RPC_SIZE(&msg) = 4U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_seco_update_mpmr(sc_ipc_t ipc, sc_faddr_t addr,
+ uint8_t size, uint8_t lock)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_SECO);
+ RPC_FUNC(&msg) = U8(SECO_FUNC_UPDATE_MPMR);
+ RPC_U32(&msg, 0U) = U32(addr >> 32ULL);
+ RPC_U32(&msg, 4U) = U32(addr);
+ RPC_U8(&msg, 8U) = U8(size);
+ RPC_U8(&msg, 9U) = U8(lock);
+ RPC_SIZE(&msg) = 4U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_seco_get_mp_sign(sc_ipc_t ipc, sc_faddr_t msg_addr,
+ uint16_t msg_size, sc_faddr_t dst_addr, uint16_t dst_size)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_SECO);
+ RPC_FUNC(&msg) = U8(SECO_FUNC_GET_MP_SIGN);
+ RPC_U32(&msg, 0U) = U32(msg_addr >> 32ULL);
+ RPC_U32(&msg, 4U) = U32(msg_addr);
+ RPC_U32(&msg, 8U) = U32(dst_addr >> 32ULL);
+ RPC_U32(&msg, 12U) = U32(dst_addr);
+ RPC_U16(&msg, 16U) = U16(msg_size);
+ RPC_U16(&msg, 18U) = U16(dst_size);
+ RPC_SIZE(&msg) = 6U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+void sc_seco_build_info(sc_ipc_t ipc, uint32_t *version,
+ uint32_t *commit)
+{
+ sc_rpc_msg_t msg;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_SECO);
+ RPC_FUNC(&msg) = U8(SECO_FUNC_BUILD_INFO);
+ RPC_SIZE(&msg) = 1U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ if (version != NULL)
+ *version = RPC_U32(&msg, 0U);
+
+ if (commit != NULL)
+ *commit = RPC_U32(&msg, 4U);
+
+ return;
+}
+
+sc_err_t sc_seco_chip_info(sc_ipc_t ipc, uint16_t *lc,
+ uint16_t *monotonic, uint32_t *uid_l, uint32_t *uid_h)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_SECO);
+ RPC_FUNC(&msg) = U8(SECO_FUNC_CHIP_INFO);
+ RPC_SIZE(&msg) = 1U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ if (uid_l != NULL)
+ *uid_l = RPC_U32(&msg, 0U);
+
+ if (uid_h != NULL)
+ *uid_h = RPC_U32(&msg, 4U);
+
+ if (lc != NULL)
+ *lc = RPC_U16(&msg, 8U);
+
+ if (monotonic != NULL)
+ *monotonic = RPC_U16(&msg, 10U);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_seco_enable_debug(sc_ipc_t ipc, sc_faddr_t addr)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_SECO);
+ RPC_FUNC(&msg) = U8(SECO_FUNC_ENABLE_DEBUG);
+ RPC_U32(&msg, 0U) = U32(addr >> 32ULL);
+ RPC_U32(&msg, 4U) = U32(addr);
+ RPC_SIZE(&msg) = 3U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_seco_get_event(sc_ipc_t ipc, uint8_t idx,
+ uint32_t *event)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_SECO);
+ RPC_FUNC(&msg) = U8(SECO_FUNC_GET_EVENT);
+ RPC_U8(&msg, 0U) = U8(idx);
+ RPC_SIZE(&msg) = 2U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ if (event != NULL)
+ *event = RPC_U32(&msg, 0U);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_seco_fuse_write(sc_ipc_t ipc, sc_faddr_t addr)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_SECO);
+ RPC_FUNC(&msg) = U8(SECO_FUNC_FUSE_WRITE);
+ RPC_U32(&msg, 0U) = U32(addr >> 32ULL);
+ RPC_U32(&msg, 4U) = U32(addr);
+ RPC_SIZE(&msg) = 3U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+/**@}*/
+
diff --git a/drivers/soc/imx/sc/svc/timer/rpc.h b/drivers/soc/imx/sc/svc/timer/rpc.h
new file mode 100644
index 000000000000..549265c6c01a
--- /dev/null
+++ b/drivers/soc/imx/sc/svc/timer/rpc.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017-2019 NXP
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+/*!
+ * Header file for the TIMER RPC implementation.
+ *
+ * @addtogroup TIMER_SVC
+ * @{
+ */
+
+#ifndef SC_TIMER_RPC_H
+#define SC_TIMER_RPC_H
+
+/* Includes */
+
+/* Defines */
+
+/*!
+ * @name Defines for RPC TIMER function calls
+ */
+/*@{*/
+#define TIMER_FUNC_UNKNOWN 0 /* Unknown function */
+#define TIMER_FUNC_SET_WDOG_TIMEOUT 1U /* Index for timer_set_wdog_timeout() RPC call */
+#define TIMER_FUNC_SET_WDOG_PRE_TIMEOUT 12U /* Index for timer_set_wdog_pre_timeout() RPC call */
+#define TIMER_FUNC_START_WDOG 2U /* Index for timer_start_wdog() RPC call */
+#define TIMER_FUNC_STOP_WDOG 3U /* Index for timer_stop_wdog() RPC call */
+#define TIMER_FUNC_PING_WDOG 4U /* Index for timer_ping_wdog() RPC call */
+#define TIMER_FUNC_GET_WDOG_STATUS 5U /* Index for timer_get_wdog_status() RPC call */
+#define TIMER_FUNC_PT_GET_WDOG_STATUS 13U /* Index for timer_pt_get_wdog_status() RPC call */
+#define TIMER_FUNC_SET_WDOG_ACTION 10U /* Index for timer_set_wdog_action() RPC call */
+#define TIMER_FUNC_SET_RTC_TIME 6U /* Index for timer_set_rtc_time() RPC call */
+#define TIMER_FUNC_GET_RTC_TIME 7U /* Index for timer_get_rtc_time() RPC call */
+#define TIMER_FUNC_GET_RTC_SEC1970 9U /* Index for timer_get_rtc_sec1970() RPC call */
+#define TIMER_FUNC_SET_RTC_ALARM 8U /* Index for timer_set_rtc_alarm() RPC call */
+#define TIMER_FUNC_SET_RTC_PERIODIC_ALARM 14U /* Index for timer_set_rtc_periodic_alarm() RPC call */
+#define TIMER_FUNC_CANCEL_RTC_ALARM 15U /* Index for timer_cancel_rtc_alarm() RPC call */
+#define TIMER_FUNC_SET_RTC_CALB 11U /* Index for timer_set_rtc_calb() RPC call */
+#define TIMER_FUNC_SET_SYSCTR_ALARM 16U /* Index for timer_set_sysctr_alarm() RPC call */
+#define TIMER_FUNC_SET_SYSCTR_PERIODIC_ALARM 17U /* Index for timer_set_sysctr_periodic_alarm() RPC call */
+#define TIMER_FUNC_CANCEL_SYSCTR_ALARM 18U /* Index for timer_cancel_sysctr_alarm() RPC call */
+/*@}*/
+
+/* Types */
+
+/* Functions */
+
+/*!
+ * This function dispatches an incoming TIMER RPC request.
+ *
+ * @param[in] caller_pt caller partition
+ * @param[in] msg pointer to RPC message
+ */
+void timer_dispatch(sc_rm_pt_t caller_pt, sc_rsrc_t mu, sc_rpc_msg_t *msg);
+
+#endif /* SC_TIMER_RPC_H */
+
+/**@}*/
+
diff --git a/drivers/soc/imx/sc/svc/timer/rpc_clnt.c b/drivers/soc/imx/sc/svc/timer/rpc_clnt.c
new file mode 100644
index 000000000000..3ab677f4f760
--- /dev/null
+++ b/drivers/soc/imx/sc/svc/timer/rpc_clnt.c
@@ -0,0 +1,392 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017-2019 NXP
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+/*!
+ * File containing client-side RPC functions for the TIMER service. These
+ * functions are ported to clients that communicate to the SC.
+ *
+ * @addtogroup TIMER_SVC
+ * @{
+ */
+
+/* Includes */
+
+#include <soc/imx8/sc/types.h>
+#include <soc/imx8/sc/svc/rm/api.h>
+#include <soc/imx8/sc/svc/timer/api.h>
+#include "../../main/rpc.h"
+#include "rpc.h"
+
+/* Local Defines */
+
+/* Local Types */
+
+/* Local Functions */
+
+sc_err_t sc_timer_set_wdog_timeout(sc_ipc_t ipc,
+ sc_timer_wdog_time_t timeout)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_TIMER);
+ RPC_FUNC(&msg) = U8(TIMER_FUNC_SET_WDOG_TIMEOUT);
+ RPC_U32(&msg, 0U) = U32(timeout);
+ RPC_SIZE(&msg) = 2U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_timer_set_wdog_pre_timeout(sc_ipc_t ipc,
+ sc_timer_wdog_time_t pre_timeout)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_TIMER);
+ RPC_FUNC(&msg) = U8(TIMER_FUNC_SET_WDOG_PRE_TIMEOUT);
+ RPC_U32(&msg, 0U) = U32(pre_timeout);
+ RPC_SIZE(&msg) = 2U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_timer_start_wdog(sc_ipc_t ipc, sc_bool_t lock)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_TIMER);
+ RPC_FUNC(&msg) = U8(TIMER_FUNC_START_WDOG);
+ RPC_U8(&msg, 0U) = B2U8(lock);
+ RPC_SIZE(&msg) = 2U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_timer_stop_wdog(sc_ipc_t ipc)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_TIMER);
+ RPC_FUNC(&msg) = U8(TIMER_FUNC_STOP_WDOG);
+ RPC_SIZE(&msg) = 1U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_timer_ping_wdog(sc_ipc_t ipc)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_TIMER);
+ RPC_FUNC(&msg) = U8(TIMER_FUNC_PING_WDOG);
+ RPC_SIZE(&msg) = 1U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_timer_get_wdog_status(sc_ipc_t ipc,
+ sc_timer_wdog_time_t *timeout, sc_timer_wdog_time_t *max_timeout,
+ sc_timer_wdog_time_t *remaining_time)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_TIMER);
+ RPC_FUNC(&msg) = U8(TIMER_FUNC_GET_WDOG_STATUS);
+ RPC_SIZE(&msg) = 1U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ if (timeout != NULL)
+ *timeout = RPC_U32(&msg, 0U);
+
+ if (max_timeout != NULL)
+ *max_timeout = RPC_U32(&msg, 4U);
+
+ if (remaining_time != NULL)
+ *remaining_time = RPC_U32(&msg, 8U);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_timer_pt_get_wdog_status(sc_ipc_t ipc, sc_rm_pt_t pt, sc_bool_t *enb,
+ sc_timer_wdog_time_t *timeout, sc_timer_wdog_time_t *remaining_time)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_TIMER);
+ RPC_FUNC(&msg) = U8(TIMER_FUNC_PT_GET_WDOG_STATUS);
+ RPC_U8(&msg, 0U) = U8(pt);
+ RPC_SIZE(&msg) = 2U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ if (timeout != NULL)
+ *timeout = RPC_U32(&msg, 0U);
+
+ if (remaining_time != NULL)
+ *remaining_time = RPC_U32(&msg, 4U);
+
+ result = RPC_R8(&msg);
+ if (enb != NULL)
+ *enb = U2B(RPC_U8(&msg, 8U));
+
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_timer_set_wdog_action(sc_ipc_t ipc,
+ sc_rm_pt_t pt, sc_timer_wdog_action_t action)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_TIMER);
+ RPC_FUNC(&msg) = U8(TIMER_FUNC_SET_WDOG_ACTION);
+ RPC_U8(&msg, 0U) = U8(pt);
+ RPC_U8(&msg, 1U) = U8(action);
+ RPC_SIZE(&msg) = 2U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_timer_set_rtc_time(sc_ipc_t ipc, uint16_t year, uint8_t mon,
+ uint8_t day, uint8_t hour, uint8_t min, uint8_t sec)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_TIMER);
+ RPC_FUNC(&msg) = U8(TIMER_FUNC_SET_RTC_TIME);
+ RPC_U16(&msg, 0U) = U16(year);
+ RPC_U8(&msg, 2U) = U8(mon);
+ RPC_U8(&msg, 3U) = U8(day);
+ RPC_U8(&msg, 4U) = U8(hour);
+ RPC_U8(&msg, 5U) = U8(min);
+ RPC_U8(&msg, 6U) = U8(sec);
+ RPC_SIZE(&msg) = 3U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_timer_get_rtc_time(sc_ipc_t ipc, uint16_t *year, uint8_t *mon,
+ uint8_t *day, uint8_t *hour, uint8_t *min, uint8_t *sec)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_TIMER);
+ RPC_FUNC(&msg) = U8(TIMER_FUNC_GET_RTC_TIME);
+ RPC_SIZE(&msg) = 1U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ if (year != NULL)
+ *year = RPC_U16(&msg, 0U);
+
+ result = RPC_R8(&msg);
+ if (mon != NULL)
+ *mon = RPC_U8(&msg, 2U);
+
+ if (day != NULL)
+ *day = RPC_U8(&msg, 3U);
+
+ if (hour != NULL)
+ *hour = RPC_U8(&msg, 4U);
+
+ if (min != NULL)
+ *min = RPC_U8(&msg, 5U);
+
+ if (sec != NULL)
+ *sec = RPC_U8(&msg, 6U);
+
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_timer_get_rtc_sec1970(sc_ipc_t ipc, uint32_t *sec)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_TIMER);
+ RPC_FUNC(&msg) = U8(TIMER_FUNC_GET_RTC_SEC1970);
+ RPC_SIZE(&msg) = 1U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ if (sec != NULL)
+ *sec = RPC_U32(&msg, 0U);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_timer_set_rtc_alarm(sc_ipc_t ipc, uint16_t year, uint8_t mon,
+ uint8_t day, uint8_t hour, uint8_t min, uint8_t sec)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_TIMER);
+ RPC_FUNC(&msg) = U8(TIMER_FUNC_SET_RTC_ALARM);
+ RPC_U16(&msg, 0U) = U16(year);
+ RPC_U8(&msg, 2U) = U8(mon);
+ RPC_U8(&msg, 3U) = U8(day);
+ RPC_U8(&msg, 4U) = U8(hour);
+ RPC_U8(&msg, 5U) = U8(min);
+ RPC_U8(&msg, 6U) = U8(sec);
+ RPC_SIZE(&msg) = 3U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_timer_set_rtc_periodic_alarm(sc_ipc_t ipc, uint32_t sec)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_TIMER);
+ RPC_FUNC(&msg) = U8(TIMER_FUNC_SET_RTC_PERIODIC_ALARM);
+ RPC_U32(&msg, 0U) = U32(sec);
+ RPC_SIZE(&msg) = 2U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_timer_cancel_rtc_alarm(sc_ipc_t ipc)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_TIMER);
+ RPC_FUNC(&msg) = U8(TIMER_FUNC_CANCEL_RTC_ALARM);
+ RPC_SIZE(&msg) = 1U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_timer_set_rtc_calb(sc_ipc_t ipc, int8_t count)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_TIMER);
+ RPC_FUNC(&msg) = U8(TIMER_FUNC_SET_RTC_CALB);
+ RPC_I8(&msg, 0U) = I8(count);
+ RPC_SIZE(&msg) = 2U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_timer_set_sysctr_alarm(sc_ipc_t ipc, uint64_t ticks)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_TIMER);
+ RPC_FUNC(&msg) = U8(TIMER_FUNC_SET_SYSCTR_ALARM);
+ RPC_U32(&msg, 0U) = U32(ticks >> 32ULL);
+ RPC_U32(&msg, 4U) = U32(ticks);
+ RPC_SIZE(&msg) = 3U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_timer_set_sysctr_periodic_alarm(sc_ipc_t ipc,
+ uint64_t ticks)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_TIMER);
+ RPC_FUNC(&msg) = U8(TIMER_FUNC_SET_SYSCTR_PERIODIC_ALARM);
+ RPC_U32(&msg, 0U) = U32(ticks >> 32ULL);
+ RPC_U32(&msg, 4U) = U32(ticks);
+ RPC_SIZE(&msg) = 3U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_timer_cancel_sysctr_alarm(sc_ipc_t ipc)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = U8(SC_RPC_SVC_TIMER);
+ RPC_FUNC(&msg) = U8(TIMER_FUNC_CANCEL_SYSCTR_ALARM);
+ RPC_SIZE(&msg) = 1U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+/**@}*/
+
diff --git a/drivers/soc/imx/soc-imx8.c b/drivers/soc/imx/soc-imx8.c
new file mode 100644
index 000000000000..bcef07394f89
--- /dev/null
+++ b/drivers/soc/imx/soc-imx8.c
@@ -0,0 +1,627 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017-2018 NXP
+ *
+ * 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/arm-smccc.h>
+#include <linux/cpu.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/of_address.h>
+#include <linux/pm_opp.h>
+#include <linux/slab.h>
+#include <linux/sys_soc.h>
+#include <linux/platform_device.h>
+#include <linux/of.h>
+
+#include <soc/imx8/sc/types.h>
+#include <soc/imx8/sc/sci.h>
+#include <soc/imx8/soc.h>
+#include <soc/imx/revision.h>
+#include <soc/imx/src.h>
+#include <soc/imx/fsl_sip.h>
+
+struct imx8_soc_data {
+ char *name;
+ u32 (*soc_revision)(void);
+};
+
+static u32 imx8_soc_id;
+static u32 imx8_soc_rev = IMX_CHIP_REVISION_UNKNOWN;
+static u64 imx8_soc_uid;
+
+static const struct imx8_soc_data *soc_data;
+
+static inline void imx8_set_soc_revision(u32 rev)
+{
+ imx8_soc_rev = rev;
+}
+
+unsigned int imx8_get_soc_revision(void)
+{
+ return imx8_soc_rev;
+}
+
+static inline void imx8_set_soc_id(u32 id)
+{
+ imx8_soc_id = id;
+}
+
+inline bool cpu_is_imx8qm(void)
+{
+ return imx8_soc_id == IMX_SOC_IMX8QM;
+}
+
+inline bool cpu_is_imx8qxp(void)
+{
+ return imx8_soc_id == IMX_SOC_IMX8QXP;
+}
+
+inline bool cpu_is_imx8mq(void)
+{
+ return imx8_soc_id == IMX_SOC_IMX8MQ;
+}
+
+static u32 imx_init_revision_from_atf(void)
+{
+ struct arm_smccc_res res;
+ u32 digprog;
+ u32 id, rev;
+
+ arm_smccc_smc(FSL_SIP_GET_SOC_INFO, 0, 0,
+ 0, 0, 0, 0, 0, &res);
+ digprog = res.a0;
+
+ /*
+ * Bit [23:16] is the silicon ID
+ * Bit[7:4] is the base layer revision,
+ * Bit[3:0] is the metal layer revision
+ * e.g. 0x10 stands for Tapeout 1.0
+ */
+
+ rev = digprog & 0xff;
+ id = digprog >> 16 & 0xff;
+
+ imx8_set_soc_id(id);
+ imx8_set_soc_revision(rev);
+
+ return rev;
+}
+
+static u32 imx_init_revision_from_scu(void)
+{
+ uint32_t mu_id;
+ sc_err_t sc_err = SC_ERR_NONE;
+ sc_ipc_t ipc_handle;
+ u32 id, rev;
+ u32 uid_l = 0, uid_h = 0;
+
+ sc_err = sc_ipc_getMuID(&mu_id);
+ if (sc_err != SC_ERR_NONE) {
+ WARN(1, "%s: Cannot obtain MU ID\n", __func__);
+
+ return IMX_CHIP_REVISION_UNKNOWN;
+ }
+
+ sc_err = sc_ipc_open(&ipc_handle, mu_id);
+ if (sc_err != SC_ERR_NONE) {
+ WARN(1, "%s: Cannot open MU channel\n", __func__);
+
+ return IMX_CHIP_REVISION_UNKNOWN;
+ };
+
+ sc_err = sc_misc_get_control(ipc_handle, SC_R_SYSTEM, SC_C_ID, &id);
+ if (sc_err != SC_ERR_NONE) {
+ WARN(1, "%s: Cannot get control\n", __func__);
+
+ return IMX_CHIP_REVISION_UNKNOWN;
+ };
+
+ rev = (id >> 5) & 0xf;
+ rev = (((rev >> 2) + 1) << 4) | (rev & 0x3);
+ id &= 0x1f;
+
+ imx8_set_soc_id(id);
+ imx8_set_soc_revision(rev);
+
+ sc_misc_unique_id(ipc_handle, &uid_l, &uid_h);
+
+ imx8_soc_uid = uid_h;
+ imx8_soc_uid <<= 32;
+ imx8_soc_uid |= uid_l;
+
+ return rev;
+}
+
+bool TKT340553_SW_WORKAROUND;
+
+static u32 imx8qm_soc_revision(void)
+{
+ u32 rev = imx_init_revision_from_scu();
+
+ if (rev == IMX_CHIP_REVISION_1_0 || rev == IMX_CHIP_REVISION_1_1)
+ TKT340553_SW_WORKAROUND = true;
+
+ return rev;
+}
+
+static u32 imx8qxp_soc_revision(void)
+{
+ return imx_init_revision_from_scu();
+}
+
+#define OCOTP_UID_LOW 0x410
+#define OCOTP_UID_HIGH 0x420
+
+static u64 imx8mq_soc_get_soc_uid(void)
+{
+ struct device_node *np;
+ void __iomem *base;
+
+ u64 val = 0;
+
+ np = of_find_compatible_node(NULL, NULL, "fsl,imx8mq-ocotp");
+ if (!np) {
+ pr_warn("failed to find ocotp node\n");
+ return val;
+ }
+
+ base = of_iomap(np, 0);
+ if (!base) {
+ pr_warn("failed to map ocotp\n");
+ goto put_node;
+ }
+
+ val = readl_relaxed(base + OCOTP_UID_HIGH);
+ val <<= 32;
+ val |= readl_relaxed(base + OCOTP_UID_LOW);
+
+ iounmap(base);
+
+put_node:
+ of_node_put(np);
+ return val;
+}
+
+static u32 imx8mq_soc_revision(void)
+{
+ imx8_soc_uid = imx8mq_soc_get_soc_uid();
+ return imx_init_revision_from_atf();
+}
+
+static u32 imx8mm_soc_revision(void)
+{
+ imx8_soc_uid = imx8mq_soc_get_soc_uid();
+ return imx_init_revision_from_atf();
+}
+
+static struct imx8_soc_data imx8qm_soc_data = {
+ .name = "i.MX8QM",
+ .soc_revision = imx8qm_soc_revision,
+};
+
+static struct imx8_soc_data imx8qxp_soc_data = {
+ .name = "i.MX8QXP",
+ .soc_revision = imx8qxp_soc_revision,
+};
+
+static struct imx8_soc_data imx8mq_soc_data = {
+ .name = "i.MX8MQ",
+ .soc_revision = imx8mq_soc_revision,
+};
+
+static struct imx8_soc_data imx8mm_soc_data = {
+ .name = "i.MX8MM",
+ .soc_revision = imx8mm_soc_revision,
+};
+
+static const struct of_device_id imx8_soc_match[] = {
+ { .compatible = "fsl,imx8qm", .data = &imx8qm_soc_data, },
+ { .compatible = "fsl,imx8qxp", .data = &imx8qxp_soc_data, },
+ { .compatible = "fsl,imx8mq", .data = &imx8mq_soc_data, },
+ { .compatible = "fsl,imx8mm", .data = &imx8mm_soc_data, },
+ { }
+};
+
+static int __init imx8_revision_init(void)
+{
+ struct device_node *root;
+ const struct of_device_id *id;
+ const char *machine;
+ u32 rev = IMX_CHIP_REVISION_UNKNOWN;
+ int ret;
+
+ root = of_find_node_by_path("/");
+ ret = of_property_read_string(root, "model", &machine);
+ if (ret)
+ return -ENODEV;
+
+ id = of_match_node(imx8_soc_match, root);
+ if (!id)
+ return -ENODEV;
+
+ of_node_put(root);
+
+ soc_data = id->data;
+ if (soc_data && soc_data->soc_revision)
+ rev = soc_data->soc_revision();
+
+ if (rev == IMX_CHIP_REVISION_UNKNOWN)
+ pr_info("CPU identified as %s, unknown revision\n",
+ soc_data->name);
+ else
+ pr_info("CPU identified as %s, silicon rev %d.%d\n",
+ soc_data->name, (rev >> 4) & 0xf, rev & 0xf);
+
+ return 0;
+}
+early_initcall(imx8_revision_init);
+
+static ssize_t imx8_get_soc_uid(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ return sprintf(buf, "%016llX\n", imx8_soc_uid);
+}
+
+static struct device_attribute imx8_uid =
+ __ATTR(soc_uid, 0444, imx8_get_soc_uid, NULL);
+
+static void __init imx8mq_noc_init(void)
+{
+ struct arm_smccc_res res;
+
+ pr_info("Config NOC for VPU and CPU\n");
+
+ arm_smccc_smc(FSL_SIP_NOC, FSL_SIP_NOC_PRIORITY, NOC_CPU_PRIORITY,
+ 0x80000300, 0, 0, 0, 0, &res);
+ if (res.a0)
+ pr_err("Config NOC for CPU fail!\n");
+
+ arm_smccc_smc(FSL_SIP_NOC, FSL_SIP_NOC_PRIORITY, NOC_VPU_PRIORITY,
+ 0x80000300, 0, 0, 0, 0, &res);
+ if (res.a0)
+ pr_err("Config NOC for VPU fail!\n");
+}
+
+static int __init imx8_soc_init(void)
+{
+ struct soc_device_attribute *soc_dev_attr;
+ struct soc_device *soc_dev;
+ u32 soc_rev;
+ int ret;
+
+ soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);
+ if (!soc_dev_attr)
+ return -ENODEV;
+
+ soc_dev_attr->family = "Freescale i.MX";
+
+ if (soc_data)
+ soc_dev_attr->soc_id = soc_data->name;
+
+ soc_rev = imx8_get_soc_revision();
+ soc_dev_attr->revision = kasprintf(GFP_KERNEL, "%d.%d",
+ (soc_rev >> 4) & 0xf,
+ soc_rev & 0xf);
+ if (!soc_dev_attr->revision)
+ goto free_soc;
+
+ of_property_read_string(of_root, "model", &soc_dev_attr->machine);
+
+ soc_dev = soc_device_register(soc_dev_attr);
+ if (IS_ERR(soc_dev))
+ goto free_rev;
+
+ ret = device_create_file(soc_device_to_device(soc_dev), &imx8_uid);
+ if (ret) {
+ pr_err("could not register sysfs entry\n");
+ return ret;
+ }
+
+ if (of_machine_is_compatible("fsl,imx8mq"))
+ imx8mq_noc_init();
+
+ return 0;
+
+free_rev:
+ kfree(soc_dev_attr->revision);
+free_soc:
+ kfree(soc_dev_attr);
+ return -ENODEV;
+}
+device_initcall(imx8_soc_init);
+
+#define OCOTP_CFG3 0x440
+#define OCOTP_CFG3_SPEED_GRADING_SHIFT 8
+#define OCOTP_CFG3_SPEED_GRADING_MASK (0x7 << 8)
+#define OCOTP_CFG3_SPEED_2GHZ 4
+#define OCOTP_CFG3_SPEED_1P8GHZ 3
+#define OCOTP_CFG3_SPEED_1P6GHZ 2
+#define OCOTP_CFG3_SPEED_1P2GHZ 1
+#define OCOTP_CFG3_SPEED_800MHZ 0
+#define OCOTP_CFG3_SPEED_1P0GHZ 1
+#define OCOTP_CFG3_SPEED_1P3GHZ 2
+#define OCOTP_CFG3_SPEED_1P5GHZ 3
+#define OCOTP_CFG3_MKT_SEGMENT_SHIFT 6
+#define OCOTP_CFG3_MKT_SEGMENT_MASK (0x3 << 6)
+#define OCOTP_CFG3_CONSUMER 0
+#define OCOTP_CFG3_EXT_CONSUMER 1
+#define OCOTP_CFG3_INDUSTRIAL 2
+#define OCOTP_CFG3_AUTO 3
+
+static void __init imx8mq_opp_check_speed_grading(struct device *cpu_dev)
+{
+ struct device_node *np;
+ void __iomem *base;
+ u32 val, speed_grading;
+
+ np = of_find_compatible_node(NULL, NULL, "fsl,imx8mq-ocotp");
+ if (!np) {
+ pr_warn("failed to find ocotp node\n");
+ return;
+ }
+
+ base = of_iomap(np, 0);
+ if (!base) {
+ pr_warn("failed to map ocotp\n");
+ goto put_node;
+ }
+ val = readl_relaxed(base + OCOTP_CFG3);
+ speed_grading = (val >> OCOTP_CFG3_SPEED_GRADING_SHIFT) & 0x3;
+ val >>= OCOTP_CFG3_MKT_SEGMENT_SHIFT;
+ val &= 0x3;
+
+ switch (val) {
+ case OCOTP_CFG3_CONSUMER:
+ if (dev_pm_opp_disable(cpu_dev, 800000000))
+ pr_warn("failed to disable 800MHz OPP!\n");
+ if (dev_pm_opp_disable(cpu_dev, 1300000000))
+ pr_warn("failed to disable 1.3GHz OPP!\n");
+ if (speed_grading != OCOTP_CFG3_SPEED_1P5GHZ) {
+ if (dev_pm_opp_disable(cpu_dev, 1500000000))
+ pr_warn("failed to disable 1.5GHz OPP!\n");
+ }
+ break;
+ case OCOTP_CFG3_INDUSTRIAL:
+ if (dev_pm_opp_disable(cpu_dev, 1000000000))
+ pr_warn("failed to disable 1GHz OPP!\n");
+ if (dev_pm_opp_disable(cpu_dev, 1500000000))
+ pr_warn("failed to disable 1.5GHz OPP!\n");
+ if (speed_grading != OCOTP_CFG3_SPEED_1P3GHZ) {
+ if (dev_pm_opp_disable(cpu_dev, 1300000000))
+ pr_warn("failed to disable 1.3GHz OPP!\n");
+ }
+ break;
+ default:
+ /* consumer part for default */
+ if (dev_pm_opp_disable(cpu_dev, 800000000))
+ pr_warn("failed to disable 800MHz OPP!\n");
+ if (dev_pm_opp_disable(cpu_dev, 1300000000))
+ pr_warn("failed to disable 1.3GHz OPP!\n");
+ if (speed_grading != OCOTP_CFG3_SPEED_1P5GHZ) {
+ if (dev_pm_opp_disable(cpu_dev, 1500000000))
+ pr_warn("failed to disable 1.5GHz OPP!\n");
+ }
+ break;
+ }
+
+ iounmap(base);
+
+put_node:
+ of_node_put(np);
+}
+
+static void __init imx8mm_opp_check_speed_grading(struct device *cpu_dev)
+{
+ struct device_node *np;
+ void __iomem *base;
+ u32 val, market;
+
+ np = of_find_compatible_node(NULL, NULL, "fsl,imx8mq-ocotp");
+ if (!np) {
+ pr_warn("failed to find ocotp node\n");
+ return;
+ }
+
+ base = of_iomap(np, 0);
+ if (!base) {
+ pr_warn("failed to map ocotp\n");
+ goto put_node;
+ }
+ val = readl_relaxed(base + OCOTP_CFG3);
+ /* market segment bit[7:6] */
+ market = (val & OCOTP_CFG3_MKT_SEGMENT_MASK)
+ >> OCOTP_CFG3_MKT_SEGMENT_SHIFT;
+ /* speed grading bit[10:8] */
+ val = (val & OCOTP_CFG3_SPEED_GRADING_MASK)
+ >> OCOTP_CFG3_SPEED_GRADING_SHIFT;
+
+ switch (market) {
+ case OCOTP_CFG3_CONSUMER:
+ if (val < OCOTP_CFG3_SPEED_1P8GHZ)
+ if (dev_pm_opp_disable(cpu_dev, 1800000000))
+ pr_warn("failed to disable 1.8GHz OPP!\n");
+ if (val < OCOTP_CFG3_SPEED_1P6GHZ)
+ if (dev_pm_opp_disable(cpu_dev, 1600000000))
+ pr_warn("failed to disable 1.6GHz OPP!\n");
+ break;
+ case OCOTP_CFG3_INDUSTRIAL:
+ if (dev_pm_opp_disable(cpu_dev, 1800000000))
+ pr_warn("failed to disable 1.8GHz OPP!\n");
+ if (val < OCOTP_CFG3_SPEED_1P6GHZ)
+ if (dev_pm_opp_disable(cpu_dev, 1600000000))
+ pr_warn("failed to disable 1.6GHz OPP!\n");
+ break;
+ default:
+ break;
+ }
+
+ iounmap(base);
+
+put_node:
+ of_node_put(np);
+}
+
+static void __init imx8mq_opp_init(void)
+{
+ struct device_node *np;
+ struct device *cpu_dev = get_cpu_device(0);
+
+ if (!cpu_dev) {
+ pr_warn("failed to get cpu0 device\n");
+ return;
+ }
+ np = of_node_get(cpu_dev->of_node);
+ if (!np) {
+ pr_warn("failed to find cpu0 node\n");
+ return;
+ }
+
+ if (dev_pm_opp_of_add_table(cpu_dev)) {
+ pr_warn("failed to init OPP table\n");
+ goto put_node;
+ }
+
+ if (of_machine_is_compatible("fsl,imx8mq"))
+ imx8mq_opp_check_speed_grading(cpu_dev);
+ else if (of_machine_is_compatible("fsl,imx8mm"))
+ imx8mm_opp_check_speed_grading(cpu_dev);
+
+put_node:
+ of_node_put(np);
+}
+
+static int __init imx8_register_cpufreq(void)
+{
+ if (of_machine_is_compatible("fsl,imx8mq") ||
+ of_machine_is_compatible("fsl,imx8mm")) {
+ imx8mq_opp_init();
+ platform_device_register_simple("imx8mq-cpufreq", -1, NULL, 0);
+ } else {
+ platform_device_register_simple("imx8-cpufreq", -1, NULL, 0);
+ }
+
+ return 0;
+}
+late_initcall(imx8_register_cpufreq);
+
+/* To indicate M4 enabled or not on i.MX8MQ */
+static bool m4_is_enabled;
+bool imx_src_is_m4_enabled(void)
+{
+ return m4_is_enabled;
+}
+
+int check_m4_enabled(void)
+{
+ struct arm_smccc_res res;
+
+ arm_smccc_smc(FSL_SIP_SRC, FSL_SIP_SRC_M4_STARTED, 0,
+ 0, 0, 0, 0, 0, &res);
+ m4_is_enabled = !!res.a0;
+
+ if (m4_is_enabled)
+ pr_info("M4 is started\n");
+
+ return 0;
+}
+
+#define IMX8MQ_FEATURE_BITS 0x450
+#define IMX8MQ_FEATURE_HDCP (1<<27)
+
+static bool imx8mq_soc_is_hdcp_available(void)
+{
+ struct device_node *np;
+ void __iomem *base;
+
+ u32 val = 0xffffffff; /* HDCP disabled */
+
+ np = of_find_compatible_node(NULL, NULL, "fsl,imx8mq-ocotp");
+ if (!np) {
+ pr_warn("failed to find ocotp node\n");
+ return val;
+ }
+
+ base = of_iomap(np, 0);
+ if (!base) {
+ pr_warn("failed to map ocotp\n");
+ goto put_node;
+ }
+
+ val = readl_relaxed(base + IMX8MQ_FEATURE_BITS);
+ pr_debug("%s(), val 0x%08x hdcp %u\n", __func__, val,
+ (val & IMX8MQ_FEATURE_HDCP));
+
+ iounmap(base);
+
+put_node:
+ of_node_put(np);
+
+ if ((val & IMX8MQ_FEATURE_HDCP) == 0) {
+ pr_debug("HDCP is enabled\n");
+ return true;
+ }
+ pr_debug("HDCP is disabled\n");
+ return false;
+}
+
+#define IMX8QM_FEATURE_BITS 0x3
+#define IMX8QM_FEATURE_HDCP (1<<3)
+
+static int imx8qm_soc_is_hdcp_available(void)
+{
+ sc_ipc_t mu_ipc;
+ sc_ipc_id_t mu_id;
+ uint32_t fuse = 0xffffffff;
+ int ret;
+
+ ret = sc_ipc_getMuID(&mu_id);
+ if (ret) {
+ pr_warn("sc_ipc_getMuID() can't obtain mu id SCI! %d\n",
+ ret);
+ return false;
+ }
+
+ ret = sc_ipc_open(&mu_ipc, mu_id);
+ if (ret) {
+ pr_warn("sc_ipc_getMuID() can't open MU channel to SCU! %d\n",
+ ret);
+ return false;
+ }
+
+ ret = sc_misc_otp_fuse_read(mu_ipc, IMX8QM_FEATURE_BITS, &fuse);
+ sc_ipc_close(mu_ipc);
+ if (ret) {
+ pr_warn("sc_misc_otp_fuse_read fail! %d\n", ret);
+ return false;
+ }
+
+ pr_debug("mu_id = %d, fuse[3] = 0x%x\n", mu_id, fuse);
+
+ if ((fuse & IMX8QM_FEATURE_HDCP) == 0) {
+ pr_debug("HDCP is enabled\n");
+ return true;
+ }
+ pr_debug("HDCP is disabled\n");
+ return false;
+}
+
+bool check_hdcp_enabled(void)
+{
+ if (cpu_is_imx8mq())
+ return imx8mq_soc_is_hdcp_available();
+ if (cpu_is_imx8qm())
+ return imx8qm_soc_is_hdcp_available();
+ return false;
+}
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index a75f2a2cf780..f06e271a9e54 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -273,7 +273,7 @@ config SPI_FALCON
config SPI_FSL_LPSPI
tristate "Freescale i.MX LPSPI controller"
- depends on ARCH_MXC || COMPILE_TEST
+ depends on ARCH_MXC || ARCH_MXC_ARM64 || COMPILE_TEST
help
This enables Freescale i.MX LPSPI controllers in master mode.
@@ -302,7 +302,7 @@ config SPI_IMG_SPFI
config SPI_IMX
tristate "Freescale i.MX SPI controllers"
- depends on ARCH_MXC || COMPILE_TEST
+ depends on ARCH_MXC || ARCH_MXC_ARM64 || COMPILE_TEST
select SPI_BITBANG
help
This enables using the Freescale i.MX SPI controllers in master
diff --git a/drivers/spi/spi-fsl-lpspi.c b/drivers/spi/spi-fsl-lpspi.c
index 8fe51f7541bb..a3d3abfefbb7 100644
--- a/drivers/spi/spi-fsl-lpspi.c
+++ b/drivers/spi/spi-fsl-lpspi.c
@@ -18,7 +18,10 @@
#include <linux/clk.h>
#include <linux/completion.h>
#include <linux/delay.h>
+#include <linux/dmaengine.h>
+#include <linux/dma-mapping.h>
#include <linux/err.h>
+#include <linux/gpio.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/irq.h>
@@ -26,14 +29,23 @@
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_device.h>
+#include <linux/of_gpio.h>
#include <linux/platform_device.h>
+#include <linux/platform_data/dma-imx.h>
+#include <linux/platform_data/spi-imx.h>
#include <linux/slab.h>
#include <linux/spi/spi.h>
#include <linux/spi/spi_bitbang.h>
#include <linux/types.h>
+#include <linux/pm_runtime.h>
#define DRIVER_NAME "fsl_lpspi"
+#define FSL_LPSPI_RPM_TIMEOUT 50 /* 50ms */
+
+/* The maximum bytes that edma can transfer once.*/
+#define FSL_LPSPI_MAX_EDMA_BYTES ((1 << 15) - 1)
+
/* i.MX7ULP LPSPI registers */
#define IMX7ULP_VERID 0x0
#define IMX7ULP_PARAM 0x4
@@ -58,16 +70,24 @@
#define CR_RTF BIT(8)
#define CR_RST BIT(1)
#define CR_MEN BIT(0)
+#define SR_MBF BIT(24)
#define SR_TCF BIT(10)
+#define SR_FCF BIT(9)
#define SR_RDF BIT(1)
#define SR_TDF BIT(0)
#define IER_TCIE BIT(10)
+#define IER_FCIE BIT(9)
#define IER_RDIE BIT(1)
#define IER_TDIE BIT(0)
+#define DER_RDDE BIT(1)
+#define DER_TDDE BIT(0)
#define CFGR1_PCSCFG BIT(27)
+#define CFGR1_PINCFG (BIT(24)|BIT(25))
#define CFGR1_PCSPOL BIT(8)
#define CFGR1_NOSTALL BIT(3)
#define CFGR1_MASTER BIT(0)
+#define FSR_RXCOUNT (0xFF << 16)
+#define FSR_TXCOUNT (0xFF)
#define RSR_RXEMPTY BIT(1)
#define TCR_CPOL BIT(31)
#define TCR_CPHA BIT(30)
@@ -89,7 +109,11 @@ struct lpspi_config {
struct fsl_lpspi_data {
struct device *dev;
void __iomem *base;
- struct clk *clk;
+ unsigned long base_phys;
+ struct clk *clk_ipg;
+ struct clk *clk_per;
+ bool is_slave;
+ bool is_first_byte;
void *rx_buf;
const void *tx_buf;
@@ -97,11 +121,21 @@ struct fsl_lpspi_data {
void (*rx)(struct fsl_lpspi_data *);
u32 remain;
+ u8 watermark;
u8 txfifosize;
u8 rxfifosize;
struct lpspi_config config;
struct completion xfer_done;
+
+ bool slave_aborted;
+
+ /* DMA */
+ bool usedma;
+ struct completion dma_rx_completion;
+ struct completion dma_tx_completion;
+
+ int chipselect[0];
};
static const struct of_device_id fsl_lpspi_dt_ids[] = {
@@ -148,37 +182,62 @@ static void fsl_lpspi_intctrl(struct fsl_lpspi_data *fsl_lpspi,
writel(enable, fsl_lpspi->base + IMX7ULP_IER);
}
-static int lpspi_prepare_xfer_hardware(struct spi_master *master)
+static int fsl_lpspi_bytes_per_word(const int bpw)
+{
+ return DIV_ROUND_UP(bpw, BITS_PER_BYTE);
+}
+
+static bool fsl_lpspi_can_dma(struct spi_controller *controller,
+ struct spi_device *spi,
+ struct spi_transfer *transfer)
{
- struct fsl_lpspi_data *fsl_lpspi = spi_master_get_devdata(master);
+ unsigned int bytes_per_word;
- return clk_prepare_enable(fsl_lpspi->clk);
+ if (!controller->dma_rx)
+ return false;
+
+ bytes_per_word = fsl_lpspi_bytes_per_word(transfer->bits_per_word);
+ if (bytes_per_word != 1 && bytes_per_word != 2 && bytes_per_word != 4)
+ return false;
+
+ return true;
}
-static int lpspi_unprepare_xfer_hardware(struct spi_master *master)
+static int lpspi_prepare_xfer_hardware(struct spi_controller *controller)
{
- struct fsl_lpspi_data *fsl_lpspi = spi_master_get_devdata(master);
+ struct fsl_lpspi_data *fsl_lpspi =
+ spi_controller_get_devdata(controller);
+ int ret;
- clk_disable_unprepare(fsl_lpspi->clk);
+ ret = pm_runtime_get_sync(fsl_lpspi->dev);
+ if (ret < 0) {
+ dev_err(fsl_lpspi->dev, "failed to enable clock\n");
+ return ret;
+ }
return 0;
}
-static int fsl_lpspi_txfifo_empty(struct fsl_lpspi_data *fsl_lpspi)
+static int lpspi_unprepare_xfer_hardware(struct spi_controller *controller)
{
- u32 txcnt;
- unsigned long orig_jiffies = jiffies;
+ struct fsl_lpspi_data *fsl_lpspi =
+ spi_controller_get_devdata(controller);
- do {
- txcnt = readl(fsl_lpspi->base + IMX7ULP_FSR) & 0xff;
+ pm_runtime_mark_last_busy(fsl_lpspi->dev);
+ pm_runtime_put_autosuspend(fsl_lpspi->dev);
- if (time_after(jiffies, orig_jiffies + msecs_to_jiffies(500))) {
- dev_dbg(fsl_lpspi->dev, "txfifo empty timeout\n");
- return -ETIMEDOUT;
- }
- cond_resched();
+ return 0;
+}
- } while (txcnt);
+static int fsl_lpspi_prepare_message(struct spi_controller *controller,
+ struct spi_message *msg)
+{
+ struct fsl_lpspi_data *fsl_lpspi = spi_controller_get_devdata(controller);
+ struct spi_device *spi = msg->spi;
+ int gpio = fsl_lpspi->chipselect[spi->chip_select];
+
+ if (gpio_is_valid(gpio))
+ gpio_direction_output(gpio, spi->mode & SPI_CS_HIGH ? 0 : 1);
return 0;
}
@@ -186,6 +245,7 @@ static int fsl_lpspi_txfifo_empty(struct fsl_lpspi_data *fsl_lpspi)
static void fsl_lpspi_write_tx_fifo(struct fsl_lpspi_data *fsl_lpspi)
{
u8 txfifo_cnt;
+ u32 temp;
txfifo_cnt = readl(fsl_lpspi->base + IMX7ULP_FSR) & 0xff;
@@ -196,9 +256,15 @@ static void fsl_lpspi_write_tx_fifo(struct fsl_lpspi_data *fsl_lpspi)
txfifo_cnt++;
}
- if (!fsl_lpspi->remain && (txfifo_cnt < fsl_lpspi->txfifosize))
- writel(0, fsl_lpspi->base + IMX7ULP_TDR);
- else
+ if (txfifo_cnt < fsl_lpspi->txfifosize) {
+ if (!fsl_lpspi->is_slave) {
+ temp = readl(fsl_lpspi->base + IMX7ULP_TCR);
+ temp &= ~TCR_CONTC;
+ writel(temp, fsl_lpspi->base + IMX7ULP_TCR);
+ }
+
+ fsl_lpspi_intctrl(fsl_lpspi, IER_FCIE);
+ } else
fsl_lpspi_intctrl(fsl_lpspi, IER_TDIE);
}
@@ -208,27 +274,32 @@ static void fsl_lpspi_read_rx_fifo(struct fsl_lpspi_data *fsl_lpspi)
fsl_lpspi->rx(fsl_lpspi);
}
-static void fsl_lpspi_set_cmd(struct fsl_lpspi_data *fsl_lpspi,
- bool is_first_xfer)
+static void fsl_lpspi_set_cmd(struct fsl_lpspi_data *fsl_lpspi)
{
u32 temp = 0;
- temp |= fsl_lpspi->config.bpw - 1;
- temp |= fsl_lpspi->config.prescale << 27;
- temp |= (fsl_lpspi->config.mode & 0x3) << 30;
- temp |= (fsl_lpspi->config.chip_select & 0x3) << 24;
-
- /*
- * Set TCR_CONT will keep SS asserted after current transfer.
- * For the first transfer, clear TCR_CONTC to assert SS.
- * For subsequent transfer, set TCR_CONTC to keep SS asserted.
- */
- temp |= TCR_CONT;
- if (is_first_xfer)
- temp &= ~TCR_CONTC;
- else
- temp |= TCR_CONTC;
-
+ if (!fsl_lpspi->is_slave) {
+ temp |= fsl_lpspi->config.bpw - 1;
+ temp |= fsl_lpspi->config.prescale << 27;
+ temp |= (fsl_lpspi->config.mode & 0x3) << 30;
+ temp |= (fsl_lpspi->config.chip_select & 0x3) << 24;
+
+ /*
+ * Set TCR_CONT will keep SS asserted after current transfer.
+ * For the first transfer, clear TCR_CONTC to assert SS.
+ * For subsequent transfer, set TCR_CONTC to keep SS asserted.
+ */
+ if (!fsl_lpspi->usedma) {
+ temp |= TCR_CONT;
+ if (fsl_lpspi->is_first_byte)
+ temp &= ~TCR_CONTC;
+ else
+ temp |= TCR_CONTC;
+ }
+ } else {
+ temp |= fsl_lpspi->config.bpw - 1;
+ temp |= (fsl_lpspi->config.mode & 0x3) << 30;
+ }
writel(temp, fsl_lpspi->base + IMX7ULP_TCR);
dev_dbg(fsl_lpspi->dev, "TCR=0x%x\n", temp);
@@ -238,7 +309,11 @@ static void fsl_lpspi_set_watermark(struct fsl_lpspi_data *fsl_lpspi)
{
u32 temp;
- temp = fsl_lpspi->txfifosize >> 1 | (fsl_lpspi->rxfifosize >> 1) << 16;
+ if (!fsl_lpspi->usedma)
+ temp = fsl_lpspi->watermark >> 1 |
+ (fsl_lpspi->watermark >> 1) << 16;
+ else
+ temp = fsl_lpspi->watermark >> 1;
writel(temp, fsl_lpspi->base + IMX7ULP_FCR);
@@ -251,7 +326,14 @@ static int fsl_lpspi_set_bitrate(struct fsl_lpspi_data *fsl_lpspi)
unsigned int perclk_rate, scldiv;
u8 prescale;
- perclk_rate = clk_get_rate(fsl_lpspi->clk);
+ perclk_rate = clk_get_rate(fsl_lpspi->clk_per);
+
+ if (config.speed_hz > perclk_rate / 2) {
+ dev_err(fsl_lpspi->dev,
+ "per-clk should be at least two times of transfer speed");
+ return -EINVAL;
+ }
+
for (prescale = 0; prescale < 8; prescale++) {
scldiv = perclk_rate /
(clkdivs[prescale] * config.speed_hz) - 2;
@@ -264,30 +346,79 @@ static int fsl_lpspi_set_bitrate(struct fsl_lpspi_data *fsl_lpspi)
if (prescale == 8 && scldiv >= 256)
return -EINVAL;
- writel(scldiv, fsl_lpspi->base + IMX7ULP_CCR);
+ writel(scldiv | (scldiv << 8) | ((scldiv >> 1) << 16),
+ fsl_lpspi->base + IMX7ULP_CCR);
- dev_dbg(fsl_lpspi->dev, "perclk=%d, speed=%d, prescale =%d, scldiv=%d\n",
+ dev_dbg(fsl_lpspi->dev, "perclk=%d, speed=%d, prescale=%d, scldiv=%d\n",
perclk_rate, config.speed_hz, prescale, scldiv);
return 0;
}
-static int fsl_lpspi_config(struct fsl_lpspi_data *fsl_lpspi)
+static int fsl_lpspi_dma_configure(struct spi_controller *controller)
{
- u32 temp;
int ret;
+ enum dma_slave_buswidth buswidth;
+ struct dma_slave_config rx = {}, tx = {};
+ struct fsl_lpspi_data *fsl_lpspi =
+ spi_controller_get_devdata(controller);
+
+ switch (fsl_lpspi_bytes_per_word(fsl_lpspi->config.bpw)) {
+ case 4:
+ buswidth = DMA_SLAVE_BUSWIDTH_4_BYTES;
+ break;
+ case 2:
+ buswidth = DMA_SLAVE_BUSWIDTH_2_BYTES;
+ break;
+ case 1:
+ buswidth = DMA_SLAVE_BUSWIDTH_1_BYTE;
+ break;
+ default:
+ return -EINVAL;
+ }
- temp = CR_RST;
- writel(temp, fsl_lpspi->base + IMX7ULP_CR);
- writel(0, fsl_lpspi->base + IMX7ULP_CR);
+ tx.direction = DMA_MEM_TO_DEV;
+ tx.dst_addr = fsl_lpspi->base_phys + IMX7ULP_TDR;
+ tx.dst_addr_width = buswidth;
+ tx.dst_maxburst = 1;
+ ret = dmaengine_slave_config(controller->dma_tx, &tx);
+ if (ret) {
+ dev_err(fsl_lpspi->dev, "TX dma configuration failed with %d\n",
+ ret);
+ return ret;
+ }
- ret = fsl_lpspi_set_bitrate(fsl_lpspi);
- if (ret)
+ rx.direction = DMA_DEV_TO_MEM;
+ rx.src_addr = fsl_lpspi->base_phys + IMX7ULP_RDR;
+ rx.src_addr_width = buswidth;
+ rx.src_maxburst = 1;
+ ret = dmaengine_slave_config(controller->dma_rx, &rx);
+ if (ret) {
+ dev_err(fsl_lpspi->dev, "RX dma configuration failed with %d\n",
+ ret);
return ret;
+ }
+
+ return 0;
+}
+
+static int fsl_lpspi_config(struct fsl_lpspi_data *fsl_lpspi)
+{
+ u32 temp;
+ int ret;
+
+ if (!fsl_lpspi->is_slave) {
+ ret = fsl_lpspi_set_bitrate(fsl_lpspi);
+ if (ret)
+ return ret;
+ }
fsl_lpspi_set_watermark(fsl_lpspi);
- temp = CFGR1_PCSCFG | CFGR1_MASTER;
+ if (!fsl_lpspi->is_slave)
+ temp = CFGR1_MASTER;
+ else
+ temp = CFGR1_PINCFG;
if (fsl_lpspi->config.mode & SPI_CS_HIGH)
temp |= CFGR1_PCSPOL;
writel(temp, fsl_lpspi->base + IMX7ULP_CFGR1);
@@ -296,17 +427,27 @@ static int fsl_lpspi_config(struct fsl_lpspi_data *fsl_lpspi)
temp |= CR_RRF | CR_RTF | CR_MEN;
writel(temp, fsl_lpspi->base + IMX7ULP_CR);
+ temp = 0;
+ if (fsl_lpspi->usedma)
+ temp = DER_TDDE | DER_RDDE;
+ writel(temp, fsl_lpspi->base + IMX7ULP_DER);
+
return 0;
}
-static void fsl_lpspi_setup_transfer(struct spi_device *spi,
+static int fsl_lpspi_setup_transfer(struct spi_controller *controller,
+ struct spi_device *spi,
struct spi_transfer *t)
{
- struct fsl_lpspi_data *fsl_lpspi = spi_master_get_devdata(spi->master);
+ struct fsl_lpspi_data *fsl_lpspi =
+ spi_controller_get_devdata(spi->controller);
+
+ if (t == NULL)
+ return -EINVAL;
fsl_lpspi->config.mode = spi->mode;
- fsl_lpspi->config.bpw = t ? t->bits_per_word : spi->bits_per_word;
- fsl_lpspi->config.speed_hz = t ? t->speed_hz : spi->max_speed_hz;
+ fsl_lpspi->config.bpw = t->bits_per_word;
+ fsl_lpspi->config.speed_hz = t->speed_hz;
fsl_lpspi->config.chip_select = spi->chip_select;
if (!fsl_lpspi->config.speed_hz)
@@ -326,14 +467,250 @@ static void fsl_lpspi_setup_transfer(struct spi_device *spi,
fsl_lpspi->tx = fsl_lpspi_buf_tx_u32;
}
- fsl_lpspi_config(fsl_lpspi);
+ if (t->len <= fsl_lpspi->txfifosize)
+ fsl_lpspi->watermark = t->len;
+ else
+ fsl_lpspi->watermark = fsl_lpspi->txfifosize;
+
+ if (fsl_lpspi_can_dma(controller, spi, t))
+ fsl_lpspi->usedma = 1;
+ else
+ fsl_lpspi->usedma = 0;
+
+ return fsl_lpspi_config(fsl_lpspi);
}
-static int fsl_lpspi_transfer_one(struct spi_master *master,
- struct spi_device *spi,
+static int fsl_lpspi_slave_abort(struct spi_controller *controller)
+{
+ struct fsl_lpspi_data *fsl_lpspi =
+ spi_controller_get_devdata(controller);
+
+ fsl_lpspi->slave_aborted = true;
+ if (!fsl_lpspi->usedma)
+ complete(&fsl_lpspi->xfer_done);
+ else {
+ complete(&fsl_lpspi->dma_tx_completion);
+ complete(&fsl_lpspi->dma_rx_completion);
+ }
+ return 0;
+}
+
+static int fsl_lpspi_wait_for_completion(struct spi_controller *controller)
+{
+ struct fsl_lpspi_data *fsl_lpspi =
+ spi_controller_get_devdata(controller);
+
+ if (fsl_lpspi->is_slave) {
+ if (wait_for_completion_interruptible(&fsl_lpspi->xfer_done) ||
+ fsl_lpspi->slave_aborted) {
+ dev_dbg(fsl_lpspi->dev, "interrupted\n");
+ return -EINTR;
+ }
+ } else {
+ if (!wait_for_completion_timeout(&fsl_lpspi->xfer_done, HZ)) {
+ dev_dbg(fsl_lpspi->dev, "wait for completion timeout\n");
+ return -ETIMEDOUT;
+ }
+ }
+
+ return 0;
+}
+
+static int fsl_lpspi_reset(struct fsl_lpspi_data *fsl_lpspi)
+{
+ u32 temp;
+
+ if (!fsl_lpspi->usedma) {
+ /* Disable all interrupt */
+ fsl_lpspi_intctrl(fsl_lpspi, 0);
+ }
+
+ /* W1C for all flags in SR */
+ temp = 0x3F << 8;
+ writel(temp, fsl_lpspi->base + IMX7ULP_SR);
+
+ /* Clear FIFO and disable module */
+ temp = CR_RRF | CR_RTF;
+ writel(temp, fsl_lpspi->base + IMX7ULP_CR);
+
+ return 0;
+}
+
+static void fsl_lpspi_dma_rx_callback(void *cookie)
+{
+ struct fsl_lpspi_data *fsl_lpspi = (struct fsl_lpspi_data *)cookie;
+
+ complete(&fsl_lpspi->dma_rx_completion);
+}
+
+static void fsl_lpspi_dma_tx_callback(void *cookie)
+{
+ struct fsl_lpspi_data *fsl_lpspi = (struct fsl_lpspi_data *)cookie;
+
+ complete(&fsl_lpspi->dma_tx_completion);
+}
+
+static int fsl_lpspi_calculate_timeout(struct fsl_lpspi_data *fsl_lpspi,
+ int size)
+{
+ unsigned long timeout = 0;
+
+ /* Time with actual data transfer and CS change delay related to HW */
+ timeout = (8 + 4) * size / fsl_lpspi->config.speed_hz;
+
+ /* Add extra second for scheduler related activities */
+ timeout += 1;
+
+ /* Double calculated timeout */
+ return msecs_to_jiffies(2 * timeout * MSEC_PER_SEC);
+}
+
+static int fsl_lpspi_dma_transfer(struct spi_controller *controller,
+ struct fsl_lpspi_data *fsl_lpspi,
+ struct spi_transfer *transfer)
+{
+ struct dma_async_tx_descriptor *desc_tx, *desc_rx;
+ unsigned long transfer_timeout;
+ unsigned long timeout;
+ struct sg_table *tx = &transfer->tx_sg, *rx = &transfer->rx_sg;
+ int ret;
+
+ ret = fsl_lpspi_dma_configure(controller);
+ if (ret)
+ return ret;
+
+ desc_rx = dmaengine_prep_slave_sg(controller->dma_rx,
+ rx->sgl, rx->nents, DMA_DEV_TO_MEM,
+ DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+ if (!desc_rx)
+ return -EINVAL;
+
+ desc_rx->callback = fsl_lpspi_dma_rx_callback;
+ desc_rx->callback_param = (void *)fsl_lpspi;
+ dmaengine_submit(desc_rx);
+ reinit_completion(&fsl_lpspi->dma_rx_completion);
+ dma_async_issue_pending(controller->dma_rx);
+
+ desc_tx = dmaengine_prep_slave_sg(controller->dma_tx,
+ tx->sgl, tx->nents, DMA_MEM_TO_DEV,
+ DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+ if (!desc_tx) {
+ dmaengine_terminate_all(controller->dma_tx);
+ return -EINVAL;
+ }
+
+ desc_tx->callback = fsl_lpspi_dma_tx_callback;
+ desc_tx->callback_param = (void *)fsl_lpspi;
+ dmaengine_submit(desc_tx);
+ reinit_completion(&fsl_lpspi->dma_tx_completion);
+ dma_async_issue_pending(controller->dma_tx);
+
+ fsl_lpspi->slave_aborted = false;
+
+ if (!fsl_lpspi->is_slave) {
+ transfer_timeout = fsl_lpspi_calculate_timeout(fsl_lpspi,
+ transfer->len);
+
+ /* Wait eDMA to finish the data transfer.*/
+ timeout = wait_for_completion_timeout(&fsl_lpspi->dma_tx_completion,
+ transfer_timeout);
+ if (!timeout) {
+ dev_err(fsl_lpspi->dev, "I/O Error in DMA TX\n");
+ dmaengine_terminate_all(controller->dma_tx);
+ dmaengine_terminate_all(controller->dma_rx);
+ fsl_lpspi_reset(fsl_lpspi);
+ return -ETIMEDOUT;
+ }
+
+ timeout = wait_for_completion_timeout(&fsl_lpspi->dma_rx_completion,
+ transfer_timeout);
+ if (!timeout) {
+ dev_err(fsl_lpspi->dev, "I/O Error in DMA RX\n");
+ dmaengine_terminate_all(controller->dma_tx);
+ dmaengine_terminate_all(controller->dma_rx);
+ fsl_lpspi_reset(fsl_lpspi);
+ return -ETIMEDOUT;
+ }
+ } else {
+ if (wait_for_completion_interruptible(&fsl_lpspi->dma_tx_completion) ||
+ fsl_lpspi->slave_aborted) {
+ dev_dbg(fsl_lpspi->dev,
+ "I/O Error in DMA TX interrupted\n");
+ dmaengine_terminate_all(controller->dma_tx);
+ dmaengine_terminate_all(controller->dma_rx);
+ fsl_lpspi_reset(fsl_lpspi);
+ return -EINTR;
+ }
+
+ if (wait_for_completion_interruptible(&fsl_lpspi->dma_rx_completion) ||
+ fsl_lpspi->slave_aborted) {
+ dev_dbg(fsl_lpspi->dev,
+ "I/O Error in DMA RX interrupted\n");
+ dmaengine_terminate_all(controller->dma_tx);
+ dmaengine_terminate_all(controller->dma_rx);
+ fsl_lpspi_reset(fsl_lpspi);
+ return -EINTR;
+ }
+ }
+
+ fsl_lpspi_reset(fsl_lpspi);
+
+ return 0;
+}
+
+static void fsl_lpspi_dma_exit(struct spi_controller *controller)
+{
+ if (controller->dma_rx) {
+ dma_release_channel(controller->dma_rx);
+ controller->dma_rx = NULL;
+ }
+
+ if (controller->dma_tx) {
+ dma_release_channel(controller->dma_tx);
+ controller->dma_tx = NULL;
+ }
+}
+
+static int fsl_lpspi_dma_init(struct device *dev,
+ struct fsl_lpspi_data *fsl_lpspi,
+ struct spi_controller *controller)
+{
+ int ret;
+
+ /* Prepare for TX DMA: */
+ controller->dma_tx = dma_request_slave_channel_reason(dev, "tx");
+ if (IS_ERR(controller->dma_tx)) {
+ ret = PTR_ERR(controller->dma_tx);
+ dev_dbg(dev, "can't get the TX DMA channel, error %d!\n", ret);
+ controller->dma_tx = NULL;
+ goto err;
+ }
+
+ /* Prepare for RX DMA: */
+ controller->dma_rx = dma_request_slave_channel_reason(dev, "rx");
+ if (IS_ERR(controller->dma_rx)) {
+ ret = PTR_ERR(controller->dma_rx);
+ dev_dbg(dev, "can't get the RX DMA channel, error %d\n", ret);
+ controller->dma_rx = NULL;
+ goto err;
+ }
+
+ init_completion(&fsl_lpspi->dma_rx_completion);
+ init_completion(&fsl_lpspi->dma_tx_completion);
+ controller->can_dma = fsl_lpspi_can_dma;
+ controller->max_dma_len = FSL_LPSPI_MAX_EDMA_BYTES;
+
+ return 0;
+err:
+ fsl_lpspi_dma_exit(controller);
+ return ret;
+}
+
+static int fsl_lpspi_pio_transfer(struct spi_controller *controller,
struct spi_transfer *t)
{
- struct fsl_lpspi_data *fsl_lpspi = spi_master_get_devdata(master);
+ struct fsl_lpspi_data *fsl_lpspi =
+ spi_controller_get_devdata(controller);
int ret;
fsl_lpspi->tx_buf = t->tx_buf;
@@ -341,110 +718,178 @@ static int fsl_lpspi_transfer_one(struct spi_master *master,
fsl_lpspi->remain = t->len;
reinit_completion(&fsl_lpspi->xfer_done);
- fsl_lpspi_write_tx_fifo(fsl_lpspi);
+ fsl_lpspi->slave_aborted = false;
- ret = wait_for_completion_timeout(&fsl_lpspi->xfer_done, HZ);
- if (!ret) {
- dev_dbg(fsl_lpspi->dev, "wait for completion timeout\n");
- return -ETIMEDOUT;
- }
+ fsl_lpspi_write_tx_fifo(fsl_lpspi);
- ret = fsl_lpspi_txfifo_empty(fsl_lpspi);
+ ret = fsl_lpspi_wait_for_completion(controller);
if (ret)
return ret;
- fsl_lpspi_read_rx_fifo(fsl_lpspi);
+ fsl_lpspi_reset(fsl_lpspi);
return 0;
}
-static int fsl_lpspi_transfer_one_msg(struct spi_master *master,
- struct spi_message *msg)
+static int fsl_lpspi_transfer_one(struct spi_controller *controller,
+ struct spi_device *spi,
+ struct spi_transfer *t)
{
- struct fsl_lpspi_data *fsl_lpspi = spi_master_get_devdata(master);
- struct spi_device *spi = msg->spi;
- struct spi_transfer *xfer;
- bool is_first_xfer = true;
- u32 temp;
- int ret = 0;
-
- msg->status = 0;
- msg->actual_length = 0;
-
- list_for_each_entry(xfer, &msg->transfers, transfer_list) {
- fsl_lpspi_setup_transfer(spi, xfer);
- fsl_lpspi_set_cmd(fsl_lpspi, is_first_xfer);
-
- is_first_xfer = false;
+ struct fsl_lpspi_data *fsl_lpspi =
+ spi_controller_get_devdata(controller);
+ int ret;
- ret = fsl_lpspi_transfer_one(master, spi, xfer);
- if (ret < 0)
- goto complete;
+ fsl_lpspi->is_first_byte = true;
+ ret = fsl_lpspi_setup_transfer(controller, spi, t);
+ if (ret < 0)
+ return ret;
- msg->actual_length += xfer->len;
- }
+ fsl_lpspi_set_cmd(fsl_lpspi);
+ fsl_lpspi->is_first_byte = false;
-complete:
- /* de-assert SS, then finalize current message */
- temp = readl(fsl_lpspi->base + IMX7ULP_TCR);
- temp &= ~TCR_CONTC;
- writel(temp, fsl_lpspi->base + IMX7ULP_TCR);
-
- msg->status = ret;
- spi_finalize_current_message(master);
+ if (fsl_lpspi->usedma)
+ ret = fsl_lpspi_dma_transfer(controller, fsl_lpspi, t);
+ else
+ ret = fsl_lpspi_pio_transfer(controller, t);
+ if (ret < 0)
+ return ret;
- return ret;
+ return 0;
}
static irqreturn_t fsl_lpspi_isr(int irq, void *dev_id)
{
+ u32 temp_SR, temp_IER;
struct fsl_lpspi_data *fsl_lpspi = dev_id;
- u32 temp;
+ temp_IER = readl(fsl_lpspi->base + IMX7ULP_IER);
fsl_lpspi_intctrl(fsl_lpspi, 0);
- temp = readl(fsl_lpspi->base + IMX7ULP_SR);
+ temp_SR = readl(fsl_lpspi->base + IMX7ULP_SR);
fsl_lpspi_read_rx_fifo(fsl_lpspi);
- if (temp & SR_TDF) {
+ if ((temp_SR & SR_TDF) && (temp_IER & IER_TDIE)) {
fsl_lpspi_write_tx_fifo(fsl_lpspi);
+ return IRQ_HANDLED;
+ }
- if (!fsl_lpspi->remain)
- complete(&fsl_lpspi->xfer_done);
+ if (temp_SR & SR_MBF ||
+ readl(fsl_lpspi->base + IMX7ULP_FSR) & FSR_TXCOUNT) {
+ writel(SR_FCF, fsl_lpspi->base + IMX7ULP_SR);
+ fsl_lpspi_intctrl(fsl_lpspi, IER_FCIE);
+ return IRQ_HANDLED;
+ }
+ if (temp_SR & SR_FCF && (temp_IER & IER_FCIE)) {
+ writel(SR_FCF, fsl_lpspi->base + IMX7ULP_SR);
+ complete(&fsl_lpspi->xfer_done);
return IRQ_HANDLED;
}
return IRQ_NONE;
}
+static int fsl_lpspi_runtime_resume(struct device *dev)
+{
+ struct fsl_lpspi_data *fsl_lpspi = dev_get_drvdata(dev);
+ int ret;
+
+ ret = clk_prepare_enable(fsl_lpspi->clk_per);
+ if (ret)
+ return ret;
+
+ ret = clk_prepare_enable(fsl_lpspi->clk_ipg);
+ if (ret) {
+ clk_disable_unprepare(fsl_lpspi->clk_per);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int fsl_lpspi_runtime_suspend(struct device *dev)
+{
+ struct fsl_lpspi_data *fsl_lpspi = dev_get_drvdata(dev);
+
+ clk_disable_unprepare(fsl_lpspi->clk_per);
+ clk_disable_unprepare(fsl_lpspi->clk_ipg);
+
+ return 0;
+}
+
+static int fsl_lpspi_init_rpm(struct fsl_lpspi_data *fsl_lpspi)
+{
+ struct device *dev = fsl_lpspi->dev;
+
+ pm_runtime_enable(dev);
+ pm_runtime_set_autosuspend_delay(dev, FSL_LPSPI_RPM_TIMEOUT);
+ pm_runtime_use_autosuspend(dev);
+
+ return 0;
+}
+
static int fsl_lpspi_probe(struct platform_device *pdev)
{
+ struct device_node *np = pdev->dev.of_node;
struct fsl_lpspi_data *fsl_lpspi;
- struct spi_master *master;
+ struct spi_controller *controller;
+ struct spi_imx_master *lpspi_platform_info =
+ dev_get_platdata(&pdev->dev);
struct resource *res;
- int ret, irq;
+ int i, ret, irq;
u32 temp;
- master = spi_alloc_master(&pdev->dev, sizeof(struct fsl_lpspi_data));
- if (!master)
+ if (of_property_read_bool((&pdev->dev)->of_node, "spi-slave"))
+ controller = spi_alloc_slave(&pdev->dev,
+ sizeof(struct fsl_lpspi_data));
+ else
+ controller = spi_alloc_master(&pdev->dev,
+ sizeof(struct fsl_lpspi_data));
+
+ if (!controller)
return -ENOMEM;
- platform_set_drvdata(pdev, master);
+ platform_set_drvdata(pdev, controller);
- master->bits_per_word_mask = SPI_BPW_RANGE_MASK(8, 32);
- master->bus_num = pdev->id;
+ controller->bits_per_word_mask = SPI_BPW_RANGE_MASK(8, 32);
+ controller->bus_num = pdev->id;
- fsl_lpspi = spi_master_get_devdata(master);
+ fsl_lpspi = spi_controller_get_devdata(controller);
fsl_lpspi->dev = &pdev->dev;
+ dev_set_drvdata(&pdev->dev, fsl_lpspi);
+ fsl_lpspi->is_slave = of_property_read_bool((&pdev->dev)->of_node,
+ "spi-slave");
+
+ if (!fsl_lpspi->is_slave) {
+ for (i = 0; i < controller->num_chipselect; i++) {
+ int cs_gpio = of_get_named_gpio(np, "cs-gpios", i);
+
+ if (!gpio_is_valid(cs_gpio) && lpspi_platform_info)
+ cs_gpio = lpspi_platform_info->chipselect[i];
+
+ fsl_lpspi->chipselect[i] = cs_gpio;
+ if (!gpio_is_valid(cs_gpio))
+ continue;
+
+ ret = devm_gpio_request(&pdev->dev, fsl_lpspi->chipselect[i],
+ DRIVER_NAME);
+ if (ret) {
+ dev_err(&pdev->dev, "can't get cs gpios\n");
+ goto out_controller_put;
+ }
+ }
+ controller->cs_gpios = fsl_lpspi->chipselect;
+ controller->prepare_message = fsl_lpspi_prepare_message;
+ }
- master->transfer_one_message = fsl_lpspi_transfer_one_msg;
- master->prepare_transfer_hardware = lpspi_prepare_xfer_hardware;
- master->unprepare_transfer_hardware = lpspi_unprepare_xfer_hardware;
- master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH;
- master->flags = SPI_MASTER_MUST_RX | SPI_MASTER_MUST_TX;
- master->dev.of_node = pdev->dev.of_node;
- master->bus_num = pdev->id;
+ controller->transfer_one = fsl_lpspi_transfer_one;
+ controller->prepare_transfer_hardware = lpspi_prepare_xfer_hardware;
+ controller->unprepare_transfer_hardware = lpspi_unprepare_xfer_hardware;
+ controller->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH;
+ controller->flags = SPI_MASTER_MUST_RX | SPI_MASTER_MUST_TX;
+ controller->dev.of_node = pdev->dev.of_node;
+ controller->bus_num = pdev->id;
+ controller->slave_abort = fsl_lpspi_slave_abort;
init_completion(&fsl_lpspi->xfer_done);
@@ -452,74 +897,127 @@ static int fsl_lpspi_probe(struct platform_device *pdev)
fsl_lpspi->base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(fsl_lpspi->base)) {
ret = PTR_ERR(fsl_lpspi->base);
- goto out_master_put;
+ goto out_controller_put;
}
+ fsl_lpspi->base_phys = res->start;
irq = platform_get_irq(pdev, 0);
if (irq < 0) {
ret = irq;
- goto out_master_put;
+ goto out_controller_put;
}
ret = devm_request_irq(&pdev->dev, irq, fsl_lpspi_isr, 0,
dev_name(&pdev->dev), fsl_lpspi);
if (ret) {
dev_err(&pdev->dev, "can't get irq%d: %d\n", irq, ret);
- goto out_master_put;
+ goto out_controller_put;
}
- fsl_lpspi->clk = devm_clk_get(&pdev->dev, "ipg");
- if (IS_ERR(fsl_lpspi->clk)) {
- ret = PTR_ERR(fsl_lpspi->clk);
- goto out_master_put;
+ fsl_lpspi->clk_per = devm_clk_get(&pdev->dev, "per");
+ if (IS_ERR(fsl_lpspi->clk_per)) {
+ ret = PTR_ERR(fsl_lpspi->clk_per);
+ goto out_controller_put;
}
- ret = clk_prepare_enable(fsl_lpspi->clk);
- if (ret) {
- dev_err(&pdev->dev, "can't enable lpspi clock, ret=%d\n", ret);
- goto out_master_put;
+ fsl_lpspi->clk_ipg = devm_clk_get(&pdev->dev, "ipg");
+ if (IS_ERR(fsl_lpspi->clk_ipg)) {
+ ret = PTR_ERR(fsl_lpspi->clk_ipg);
+ goto out_controller_put;
+ }
+
+ /* enable the clock */
+ ret = fsl_lpspi_init_rpm(fsl_lpspi);
+ if (ret)
+ goto out_controller_put;
+
+ ret = pm_runtime_get_sync(fsl_lpspi->dev);
+ if (ret < 0) {
+ dev_err(fsl_lpspi->dev, "failed to enable clock\n");
+ return ret;
}
temp = readl(fsl_lpspi->base + IMX7ULP_PARAM);
fsl_lpspi->txfifosize = 1 << (temp & 0x0f);
fsl_lpspi->rxfifosize = 1 << ((temp >> 8) & 0x0f);
- clk_disable_unprepare(fsl_lpspi->clk);
+ ret = fsl_lpspi_dma_init(&pdev->dev, fsl_lpspi, controller);
+ if (ret == -EPROBE_DEFER)
+ goto out_controller_put;
- ret = devm_spi_register_master(&pdev->dev, master);
+ if (ret < 0)
+ dev_err(&pdev->dev, "dma setup error %d, use pio\n", ret);
+
+ ret = devm_spi_register_controller(&pdev->dev, controller);
if (ret < 0) {
- dev_err(&pdev->dev, "spi_register_master error.\n");
- goto out_master_put;
+ dev_err(&pdev->dev, "spi_register_controller error.\n");
+ goto out_controller_put;
}
return 0;
-out_master_put:
- spi_master_put(master);
+out_controller_put:
+ spi_controller_put(controller);
return ret;
}
static int fsl_lpspi_remove(struct platform_device *pdev)
{
- struct spi_master *master = platform_get_drvdata(pdev);
- struct fsl_lpspi_data *fsl_lpspi = spi_master_get_devdata(master);
+ struct spi_controller *controller = platform_get_drvdata(pdev);
+ struct fsl_lpspi_data *fsl_lpspi =
+ spi_controller_get_devdata(controller);
+
+ pm_runtime_disable(fsl_lpspi->dev);
- clk_disable_unprepare(fsl_lpspi->clk);
+ spi_master_put(controller);
return 0;
}
+#ifdef CONFIG_PM_SLEEP
+static int fsl_lpspi_suspend(struct device *dev)
+{
+ int ret;
+
+ pinctrl_pm_select_sleep_state(dev);
+ ret = pm_runtime_force_suspend(dev);
+ return ret;
+}
+
+static int fsl_lpspi_resume(struct device *dev)
+{
+ int ret;
+
+ ret = pm_runtime_force_resume(dev);
+ if (ret) {
+ dev_err(dev, "Error in resume: %d\n", ret);
+ return ret;
+ }
+
+ pinctrl_pm_select_default_state(dev);
+
+ return 0;
+}
+#endif /* CONFIG_PM_SLEEP */
+
+static const struct dev_pm_ops fsl_lpspi_pm_ops = {
+ SET_RUNTIME_PM_OPS(fsl_lpspi_runtime_suspend,
+ fsl_lpspi_runtime_resume, NULL)
+ SET_SYSTEM_SLEEP_PM_OPS(fsl_lpspi_suspend, fsl_lpspi_resume)
+};
+
static struct platform_driver fsl_lpspi_driver = {
.driver = {
.name = DRIVER_NAME,
.of_match_table = fsl_lpspi_dt_ids,
+ .pm = &fsl_lpspi_pm_ops,
},
.probe = fsl_lpspi_probe,
.remove = fsl_lpspi_remove,
};
module_platform_driver(fsl_lpspi_driver);
-MODULE_DESCRIPTION("LPSPI Master Controller driver");
+MODULE_DESCRIPTION("LPSPI Controller driver");
MODULE_AUTHOR("Gao Pan <pandy.gao@nxp.com>");
MODULE_LICENSE("GPL");
diff --git a/drivers/spi/spi-imx.c b/drivers/spi/spi-imx.c
index df18d07d544d..9c3902555730 100644
--- a/drivers/spi/spi-imx.c
+++ b/drivers/spi/spi-imx.c
@@ -53,10 +53,13 @@
/* generic defines to abstract from the different register layouts */
#define MXC_INT_RR (1 << 0) /* Receive data ready interrupt */
#define MXC_INT_TE (1 << 1) /* Transmit FIFO empty interrupt */
+#define MXC_INT_RDR BIT(4) /* Receive date threshold interrupt */
/* The maximum bytes that a sdma BD can transfer.*/
#define MAX_SDMA_BD_BYTES (1 << 15)
#define MX51_ECSPI_CTRL_MAX_BURST 512
+/* The maximum bytes that IMX53_ECSPI can transfer in slave mode.*/
+#define MX53_MAX_TRANSFER_BYTES 512
enum spi_imx_devtype {
IMX1_CSPI,
@@ -66,18 +69,21 @@ enum spi_imx_devtype {
IMX35_CSPI, /* CSPI on all i.mx except above */
IMX51_ECSPI, /* ECSPI on i.mx51 */
IMX53_ECSPI, /* ECSPI on i.mx53 and later */
+ IMX6UL_ECSPI,
};
struct spi_imx_data;
struct spi_imx_devtype_data {
void (*intctrl)(struct spi_imx_data *, int);
- int (*prepare_message)(struct spi_imx_data *, struct spi_message *);
int (*config)(struct spi_device *);
void (*trigger)(struct spi_imx_data *);
int (*rx_available)(struct spi_imx_data *);
void (*reset)(struct spi_imx_data *);
+ void (*setup_wml)(struct spi_imx_data *);
+ void (*disable)(struct spi_imx_data *);
bool has_dmamode;
+ bool has_slavemode;
unsigned int fifo_size;
bool dynamic_burst;
enum spi_imx_devtype devtype;
@@ -109,6 +115,11 @@ struct spi_imx_data {
unsigned int dynamic_burst, read_u32;
unsigned int word_mask;
+ /* Slave mode */
+ bool slave_mode;
+ bool slave_aborted;
+ unsigned int slave_burst;
+
/* DMA */
bool usedma;
u32 wml;
@@ -130,7 +141,8 @@ static inline int is_imx35_cspi(struct spi_imx_data *d)
static inline int is_imx51_ecspi(struct spi_imx_data *d)
{
- return d->devtype_data->devtype == IMX51_ECSPI;
+ return d->devtype_data->devtype == IMX51_ECSPI ||
+ d->devtype_data->devtype == IMX6UL_ECSPI;
}
static inline int is_imx53_ecspi(struct spi_imx_data *d)
@@ -217,25 +229,22 @@ static bool spi_imx_can_dma(struct spi_master *master, struct spi_device *spi,
struct spi_transfer *transfer)
{
struct spi_imx_data *spi_imx = spi_master_get_devdata(master);
- unsigned int bytes_per_word, i;
+ unsigned int bytes_per_word;
if (!master->dma_rx)
return false;
+ if (spi_imx->slave_mode)
+ return false;
+
bytes_per_word = spi_imx_bytes_per_word(transfer->bits_per_word);
if (bytes_per_word != 1 && bytes_per_word != 2 && bytes_per_word != 4)
return false;
- for (i = spi_imx->devtype_data->fifo_size / 2; i > 0; i--) {
- if (!(transfer->len % (i * bytes_per_word)))
- break;
- }
-
- if (i == 0)
+ if (transfer->len < spi_imx->devtype_data->fifo_size / 2)
return false;
- spi_imx->wml = i;
spi_imx->dynamic_burst = 0;
return true;
@@ -263,6 +272,7 @@ static bool spi_imx_can_dma(struct spi_master *master, struct spi_device *spi,
#define MX51_ECSPI_INT 0x10
#define MX51_ECSPI_INT_TEEN (1 << 0)
#define MX51_ECSPI_INT_RREN (1 << 3)
+#define MX51_ECSPI_INT_RDREN (1 << 4)
#define MX51_ECSPI_DMA 0x14
#define MX51_ECSPI_DMA_TX_WML(wml) ((wml) & 0x3f)
@@ -379,6 +389,44 @@ static void spi_imx_buf_tx_swap(struct spi_imx_data *spi_imx)
spi_imx_buf_tx_u16(spi_imx);
}
+static void mx53_ecspi_rx_slave(struct spi_imx_data *spi_imx)
+{
+ u32 val = be32_to_cpu(readl(spi_imx->base + MXC_CSPIRXDATA));
+
+ if (spi_imx->rx_buf) {
+ int n_bytes = spi_imx->slave_burst % sizeof(val);
+
+ if (!n_bytes)
+ n_bytes = sizeof(val);
+
+ memcpy(spi_imx->rx_buf,
+ ((u8 *)&val) + sizeof(val) - n_bytes, n_bytes);
+
+ spi_imx->rx_buf += n_bytes;
+ spi_imx->slave_burst -= n_bytes;
+ }
+}
+
+static void mx53_ecspi_tx_slave(struct spi_imx_data *spi_imx)
+{
+ u32 val = 0;
+ int n_bytes = spi_imx->count % sizeof(val);
+
+ if (!n_bytes)
+ n_bytes = sizeof(val);
+
+ if (spi_imx->tx_buf) {
+ memcpy(((u8 *)&val) + sizeof(val) - n_bytes,
+ spi_imx->tx_buf, n_bytes);
+ val = cpu_to_be32(val);
+ spi_imx->tx_buf += n_bytes;
+ }
+
+ spi_imx->count -= n_bytes;
+
+ writel(val, spi_imx->base + MXC_CSPITXDATA);
+}
+
/* MX51 eCSPI */
static unsigned int mx51_ecspi_clkdiv(struct spi_imx_data *spi_imx,
unsigned int fspi, unsigned int *fres)
@@ -428,34 +476,49 @@ static void mx51_ecspi_intctrl(struct spi_imx_data *spi_imx, int enable)
if (enable & MXC_INT_RR)
val |= MX51_ECSPI_INT_RREN;
+ if (enable & MXC_INT_RDR)
+ val |= MX51_ECSPI_INT_RDREN;
+
writel(val, spi_imx->base + MX51_ECSPI_INT);
}
static void mx51_ecspi_trigger(struct spi_imx_data *spi_imx)
{
- u32 reg;
-
- reg = readl(spi_imx->base + MX51_ECSPI_CTRL);
- reg |= MX51_ECSPI_CTRL_XCH;
+ u32 reg = readl(spi_imx->base + MX51_ECSPI_CTRL);
+ /*
+ * To workaround ERR008517, SDMA script need use XCH instead of SMC
+ * just like PIO mode and it fix on i.mx6ul
+ */
+ if (!spi_imx->usedma)
+ reg |= MX51_ECSPI_CTRL_XCH;
+ else if (spi_imx->devtype_data->devtype == IMX6UL_ECSPI)
+ reg |= MX51_ECSPI_CTRL_SMC;
+ else
+ reg &= ~MX51_ECSPI_CTRL_SMC;
writel(reg, spi_imx->base + MX51_ECSPI_CTRL);
}
-static int mx51_ecspi_prepare_message(struct spi_imx_data *spi_imx,
- struct spi_message *msg)
+static void mx51_ecspi_disable(struct spi_imx_data *spi_imx)
+{
+ u32 ctrl;
+
+ ctrl = readl(spi_imx->base + MX51_ECSPI_CTRL);
+ ctrl &= ~MX51_ECSPI_CTRL_ENABLE;
+ writel(ctrl, spi_imx->base + MX51_ECSPI_CTRL);
+}
+
+static int mx51_ecspi_config(struct spi_device *spi)
{
- struct spi_device *spi = msg->spi;
+ struct spi_imx_data *spi_imx = spi_master_get_devdata(spi->master);
u32 ctrl = MX51_ECSPI_CTRL_ENABLE;
- u32 testreg;
+ u32 clk = spi_imx->speed_hz, delay, reg;
u32 cfg = readl(spi_imx->base + MX51_ECSPI_CONFIG);
- /*
- * The hardware seems to have a race condition when changing modes. The
- * current assumption is that the selection of the channel arrives
- * earlier in the hardware than the mode bits when they are written at
- * the same time.
- * So set master mode for all channels as we do not support slave mode.
- */
- ctrl |= MX51_ECSPI_CTRL_MODE_MASK;
+ /* set Master or Slave mode */
+ if (spi_imx->slave_mode)
+ ctrl &= ~MX51_ECSPI_CTRL_MODE_MASK;
+ else
+ ctrl |= MX51_ECSPI_CTRL_MODE_MASK;
/*
* Enable SPI_RDY handling (falling edge/level triggered).
@@ -463,23 +526,29 @@ static int mx51_ecspi_prepare_message(struct spi_imx_data *spi_imx,
if (spi->mode & SPI_READY)
ctrl |= MX51_ECSPI_CTRL_DRCTL(spi_imx->spi_drctl);
+ /* set clock speed */
+ ctrl |= mx51_ecspi_clkdiv(spi_imx, spi_imx->speed_hz, &clk);
+ spi_imx->spi_bus_clk = clk;
+
/* set chip select to use */
ctrl |= MX51_ECSPI_CTRL_CS(spi->chip_select);
+ if (spi_imx->slave_mode)
+ ctrl |= (spi_imx->slave_burst * 8 - 1)
+ << MX51_ECSPI_CTRL_BL_OFFSET;
+ else
+ ctrl |= (spi_imx->bits_per_word - 1)
+ << MX51_ECSPI_CTRL_BL_OFFSET;
+
/*
- * The ctrl register must be written first, with the EN bit set other
- * registers must not be written to.
+ * eCSPI burst completion by Chip Select signal in Slave mode
+ * is not functional for imx53 Soc, config SPI burst completed when
+ * BURST_LENGTH + 1 bits are received
*/
- writel(ctrl, spi_imx->base + MX51_ECSPI_CTRL);
-
- testreg = readl(spi_imx->base + MX51_ECSPI_TESTREG);
- if (spi->mode & SPI_LOOP)
- testreg |= MX51_ECSPI_TESTREG_LBC;
+ if (spi_imx->slave_mode && is_imx53_ecspi(spi_imx))
+ cfg &= ~MX51_ECSPI_CONFIG_SBBCTRL(spi->chip_select);
else
- testreg &= ~MX51_ECSPI_TESTREG_LBC;
- writel(testreg, spi_imx->base + MX51_ECSPI_TESTREG);
-
- cfg |= MX51_ECSPI_CONFIG_SBBCTRL(spi->chip_select);
+ cfg |= MX51_ECSPI_CONFIG_SBBCTRL(spi->chip_select);
if (spi->mode & SPI_CPHA)
cfg |= MX51_ECSPI_CONFIG_SCLKPHA(spi->chip_select);
@@ -493,38 +562,26 @@ static int mx51_ecspi_prepare_message(struct spi_imx_data *spi_imx,
cfg &= ~MX51_ECSPI_CONFIG_SCLKPOL(spi->chip_select);
cfg &= ~MX51_ECSPI_CONFIG_SCLKCTL(spi->chip_select);
}
-
if (spi->mode & SPI_CS_HIGH)
cfg |= MX51_ECSPI_CONFIG_SSBPOL(spi->chip_select);
else
cfg &= ~MX51_ECSPI_CONFIG_SSBPOL(spi->chip_select);
- writel(cfg, spi_imx->base + MX51_ECSPI_CONFIG);
-
- return 0;
-}
-
-static int mx51_ecspi_config(struct spi_device *spi)
-{
- struct spi_imx_data *spi_imx = spi_master_get_devdata(spi->master);
- u32 ctrl = readl(spi_imx->base + MX51_ECSPI_CTRL);
- u32 clk = spi_imx->speed_hz, delay;
-
- /* Clear BL field and set the right value */
- ctrl &= ~MX51_ECSPI_CTRL_BL_MASK;
- ctrl |= (spi_imx->bits_per_word - 1) << MX51_ECSPI_CTRL_BL_OFFSET;
-
- /* set clock speed */
- ctrl &= ~(0xf << MX51_ECSPI_CTRL_POSTDIV_OFFSET |
- 0xf << MX51_ECSPI_CTRL_PREDIV_OFFSET);
- ctrl |= mx51_ecspi_clkdiv(spi_imx, spi_imx->speed_hz, &clk);
- spi_imx->spi_bus_clk = clk;
-
if (spi_imx->usedma)
ctrl |= MX51_ECSPI_CTRL_SMC;
+ /* CTRL register always go first to bring out controller from reset */
writel(ctrl, spi_imx->base + MX51_ECSPI_CTRL);
+ reg = readl(spi_imx->base + MX51_ECSPI_TESTREG);
+ if (spi->mode & SPI_LOOP)
+ reg |= MX51_ECSPI_TESTREG_LBC;
+ else
+ reg &= ~MX51_ECSPI_TESTREG_LBC;
+ writel(reg, spi_imx->base + MX51_ECSPI_TESTREG);
+
+ writel(cfg, spi_imx->base + MX51_ECSPI_CONFIG);
+
/*
* Wait until the changes in the configuration register CONFIGREG
* propagate into the hardware. It takes exactly one tick of the
@@ -542,17 +599,26 @@ static int mx51_ecspi_config(struct spi_device *spi)
else /* SCLK is _very_ slow */
usleep_range(delay, delay + 10);
+ return 0;
+}
+
+static void mx51_setup_wml(struct spi_imx_data *spi_imx)
+{
+ int tx_wml = 0;
+
/*
* Configure the DMA register: setup the watermark
* and enable DMA request.
*/
- writel(MX51_ECSPI_DMA_RX_WML(spi_imx->wml) |
- MX51_ECSPI_DMA_TX_WML(spi_imx->wml) |
- MX51_ECSPI_DMA_RXT_WML(spi_imx->wml) |
- MX51_ECSPI_DMA_TEDEN | MX51_ECSPI_DMA_RXDEN |
- MX51_ECSPI_DMA_RXTDEN, spi_imx->base + MX51_ECSPI_DMA);
+ if (spi_imx->devtype_data->devtype == IMX6UL_ECSPI)
+ tx_wml = spi_imx->wml;
- return 0;
+ if (spi_imx->usedma)
+ writel(MX51_ECSPI_DMA_RX_WML(spi_imx->wml - 1) |
+ MX51_ECSPI_DMA_TX_WML(tx_wml) |
+ MX51_ECSPI_DMA_RXT_WML(spi_imx->wml) |
+ MX51_ECSPI_DMA_TEDEN | MX51_ECSPI_DMA_RXDEN |
+ MX51_ECSPI_DMA_RXTDEN, spi_imx->base + MX51_ECSPI_DMA);
}
static int mx51_ecspi_rx_available(struct spi_imx_data *spi_imx)
@@ -619,12 +685,6 @@ static void mx31_trigger(struct spi_imx_data *spi_imx)
writel(reg, spi_imx->base + MXC_CSPICTRL);
}
-static int mx31_prepare_message(struct spi_imx_data *spi_imx,
- struct spi_message *msg)
-{
- return 0;
-}
-
static int mx31_config(struct spi_device *spi)
{
struct spi_imx_data *spi_imx = spi_master_get_devdata(spi->master);
@@ -721,12 +781,6 @@ static void mx21_trigger(struct spi_imx_data *spi_imx)
writel(reg, spi_imx->base + MXC_CSPICTRL);
}
-static int mx21_prepare_message(struct spi_imx_data *spi_imx,
- struct spi_message *msg)
-{
- return 0;
-}
-
static int mx21_config(struct spi_device *spi)
{
struct spi_imx_data *spi_imx = spi_master_get_devdata(spi->master);
@@ -796,12 +850,6 @@ static void mx1_trigger(struct spi_imx_data *spi_imx)
writel(reg, spi_imx->base + MXC_CSPICTRL);
}
-static int mx1_prepare_message(struct spi_imx_data *spi_imx,
- struct spi_message *msg)
-{
- return 0;
-}
-
static int mx1_config(struct spi_device *spi)
{
struct spi_imx_data *spi_imx = spi_master_get_devdata(spi->master);
@@ -836,7 +884,6 @@ static void mx1_reset(struct spi_imx_data *spi_imx)
static struct spi_imx_devtype_data imx1_cspi_devtype_data = {
.intctrl = mx1_intctrl,
- .prepare_message = mx1_prepare_message,
.config = mx1_config,
.trigger = mx1_trigger,
.rx_available = mx1_rx_available,
@@ -844,12 +891,12 @@ static struct spi_imx_devtype_data imx1_cspi_devtype_data = {
.fifo_size = 8,
.has_dmamode = false,
.dynamic_burst = false,
+ .has_slavemode = false,
.devtype = IMX1_CSPI,
};
static struct spi_imx_devtype_data imx21_cspi_devtype_data = {
.intctrl = mx21_intctrl,
- .prepare_message = mx21_prepare_message,
.config = mx21_config,
.trigger = mx21_trigger,
.rx_available = mx21_rx_available,
@@ -857,13 +904,13 @@ static struct spi_imx_devtype_data imx21_cspi_devtype_data = {
.fifo_size = 8,
.has_dmamode = false,
.dynamic_burst = false,
+ .has_slavemode = false,
.devtype = IMX21_CSPI,
};
static struct spi_imx_devtype_data imx27_cspi_devtype_data = {
/* i.mx27 cspi shares the functions with i.mx21 one */
.intctrl = mx21_intctrl,
- .prepare_message = mx21_prepare_message,
.config = mx21_config,
.trigger = mx21_trigger,
.rx_available = mx21_rx_available,
@@ -871,12 +918,12 @@ static struct spi_imx_devtype_data imx27_cspi_devtype_data = {
.fifo_size = 8,
.has_dmamode = false,
.dynamic_burst = false,
+ .has_slavemode = false,
.devtype = IMX27_CSPI,
};
static struct spi_imx_devtype_data imx31_cspi_devtype_data = {
.intctrl = mx31_intctrl,
- .prepare_message = mx31_prepare_message,
.config = mx31_config,
.trigger = mx31_trigger,
.rx_available = mx31_rx_available,
@@ -884,13 +931,13 @@ static struct spi_imx_devtype_data imx31_cspi_devtype_data = {
.fifo_size = 8,
.has_dmamode = false,
.dynamic_burst = false,
+ .has_slavemode = false,
.devtype = IMX31_CSPI,
};
static struct spi_imx_devtype_data imx35_cspi_devtype_data = {
/* i.mx35 and later cspi shares the functions with i.mx31 one */
.intctrl = mx31_intctrl,
- .prepare_message = mx31_prepare_message,
.config = mx31_config,
.trigger = mx31_trigger,
.rx_available = mx31_rx_available,
@@ -898,35 +945,54 @@ static struct spi_imx_devtype_data imx35_cspi_devtype_data = {
.fifo_size = 8,
.has_dmamode = true,
.dynamic_burst = false,
+ .has_slavemode = false,
.devtype = IMX35_CSPI,
};
static struct spi_imx_devtype_data imx51_ecspi_devtype_data = {
.intctrl = mx51_ecspi_intctrl,
- .prepare_message = mx51_ecspi_prepare_message,
.config = mx51_ecspi_config,
.trigger = mx51_ecspi_trigger,
.rx_available = mx51_ecspi_rx_available,
.reset = mx51_ecspi_reset,
+ .setup_wml = mx51_setup_wml,
.fifo_size = 64,
.has_dmamode = true,
.dynamic_burst = true,
+ .has_slavemode = true,
+ .disable = mx51_ecspi_disable,
.devtype = IMX51_ECSPI,
};
static struct spi_imx_devtype_data imx53_ecspi_devtype_data = {
.intctrl = mx51_ecspi_intctrl,
- .prepare_message = mx51_ecspi_prepare_message,
.config = mx51_ecspi_config,
.trigger = mx51_ecspi_trigger,
.rx_available = mx51_ecspi_rx_available,
.reset = mx51_ecspi_reset,
.fifo_size = 64,
.has_dmamode = true,
+ .has_slavemode = true,
+ .disable = mx51_ecspi_disable,
.devtype = IMX53_ECSPI,
};
-static const struct platform_device_id spi_imx_devtype[] = {
+static struct spi_imx_devtype_data imx6ul_ecspi_devtype_data = {
+ .intctrl = mx51_ecspi_intctrl,
+ .config = mx51_ecspi_config,
+ .trigger = mx51_ecspi_trigger,
+ .rx_available = mx51_ecspi_rx_available,
+ .reset = mx51_ecspi_reset,
+ .setup_wml = mx51_setup_wml,
+ .fifo_size = 64,
+ .has_dmamode = true,
+ .dynamic_burst = true,
+ .has_slavemode = true,
+ .disable = mx51_ecspi_disable,
+ .devtype = IMX6UL_ECSPI,
+};
+
+static struct platform_device_id spi_imx_devtype[] = {
{
.name = "imx1-cspi",
.driver_data = (kernel_ulong_t) &imx1_cspi_devtype_data,
@@ -949,6 +1015,9 @@ static const struct platform_device_id spi_imx_devtype[] = {
.name = "imx53-ecspi",
.driver_data = (kernel_ulong_t) &imx53_ecspi_devtype_data,
}, {
+ .name = "imx6ul-ecspi",
+ .driver_data = (kernel_ulong_t) &imx6ul_ecspi_devtype_data,
+ }, {
/* sentinel */
}
};
@@ -961,6 +1030,7 @@ static const struct of_device_id spi_imx_dt_ids[] = {
{ .compatible = "fsl,imx35-cspi", .data = &imx35_cspi_devtype_data, },
{ .compatible = "fsl,imx51-ecspi", .data = &imx51_ecspi_devtype_data, },
{ .compatible = "fsl,imx53-ecspi", .data = &imx53_ecspi_devtype_data, },
+ { .compatible = "fsl,imx6ul-ecspi", .data = &imx6ul_ecspi_devtype_data, },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, spi_imx_dt_ids);
@@ -990,14 +1060,16 @@ static void spi_imx_push(struct spi_imx_data *spi_imx)
spi_imx->txfifo++;
}
- spi_imx->devtype_data->trigger(spi_imx);
+ if (!spi_imx->slave_mode)
+ spi_imx->devtype_data->trigger(spi_imx);
}
static irqreturn_t spi_imx_isr(int irq, void *dev_id)
{
struct spi_imx_data *spi_imx = dev_id;
- while (spi_imx->devtype_data->rx_available(spi_imx)) {
+ while (spi_imx->txfifo &&
+ spi_imx->devtype_data->rx_available(spi_imx)) {
spi_imx->rx(spi_imx);
spi_imx->txfifo--;
}
@@ -1070,7 +1142,6 @@ static int spi_imx_setupxfer(struct spi_device *spi,
struct spi_transfer *t)
{
struct spi_imx_data *spi_imx = spi_master_get_devdata(spi->master);
- int ret;
if (!t)
return 0;
@@ -1079,7 +1150,7 @@ static int spi_imx_setupxfer(struct spi_device *spi,
spi_imx->speed_hz = t->speed_hz;
/* Initialize the functions for transfer */
- if (spi_imx->devtype_data->dynamic_burst) {
+ if (spi_imx->devtype_data->dynamic_burst && !spi_imx->slave_mode) {
u32 mask;
spi_imx->dynamic_burst = 0;
@@ -1117,10 +1188,10 @@ static int spi_imx_setupxfer(struct spi_device *spi,
else
spi_imx->usedma = 0;
- if (spi_imx->usedma) {
- ret = spi_imx_dma_configure(spi->master);
- if (ret)
- return ret;
+ if (spi_imx->slave_mode) {
+ spi_imx->rx = mx53_ecspi_rx_slave;
+ spi_imx->tx = mx53_ecspi_tx_slave;
+ spi_imx->slave_burst = t->len;
}
spi_imx->devtype_data->config(spi);
@@ -1148,10 +1219,6 @@ static int spi_imx_sdma_init(struct device *dev, struct spi_imx_data *spi_imx,
{
int ret;
- /* use pio mode for i.mx6dl chip TKT238285 */
- if (of_machine_is_compatible("fsl,imx6dl"))
- return 0;
-
spi_imx->wml = spi_imx->devtype_data->fifo_size / 2;
/* Prepare for TX DMA: */
@@ -1221,6 +1288,31 @@ static int spi_imx_dma_transfer(struct spi_imx_data *spi_imx,
unsigned long timeout;
struct spi_master *master = spi_imx->bitbang.master;
struct sg_table *tx = &transfer->tx_sg, *rx = &transfer->rx_sg;
+ struct scatterlist *last_sg = sg_last(rx->sgl, rx->nents);
+ unsigned int bytes_per_word, i;
+ int ret;
+
+ /* Get the right burst length from the last sg to ensure no tail data */
+ bytes_per_word = spi_imx_bytes_per_word(transfer->bits_per_word);
+ for (i = spi_imx->devtype_data->fifo_size / 2; i > 0; i--) {
+ if (!(sg_dma_len(last_sg) % (i * bytes_per_word)))
+ break;
+ }
+ /* Use 1 as wml in case no available burst length got */
+ if (i == 0)
+ i = 1;
+ spi_imx->wml = i;
+
+ ret = spi_imx_dma_configure(master);
+ if (ret)
+ return ret;
+
+ if (!spi_imx->devtype_data->setup_wml) {
+ dev_err(spi_imx->dev, "No setup_wml()?\n");
+ return -EINVAL;
+ }
+
+ spi_imx->devtype_data->setup_wml(spi_imx);
/*
* The TX DMA setup starts the transfer, so make sure RX is configured
@@ -1254,6 +1346,8 @@ static int spi_imx_dma_transfer(struct spi_imx_data *spi_imx,
transfer_timeout = spi_imx_calculate_timeout(spi_imx, transfer->len);
+ spi_imx->devtype_data->trigger(spi_imx);
+
/* Wait SDMA to finish the data transfer.*/
timeout = wait_for_completion_timeout(&spi_imx->dma_tx_completion,
transfer_timeout);
@@ -1307,11 +1401,61 @@ static int spi_imx_pio_transfer(struct spi_device *spi,
return transfer->len;
}
+static int spi_imx_pio_transfer_slave(struct spi_device *spi,
+ struct spi_transfer *transfer)
+{
+ struct spi_imx_data *spi_imx = spi_master_get_devdata(spi->master);
+ int ret = transfer->len;
+
+ if ((is_imx51_ecspi(spi_imx) || is_imx53_ecspi(spi_imx)) &&
+ transfer->len > MX53_MAX_TRANSFER_BYTES) {
+ dev_err(&spi->dev, "Transaction too big, max size is %d bytes\n",
+ MX53_MAX_TRANSFER_BYTES);
+ return -EMSGSIZE;
+ }
+
+ spi_imx->tx_buf = transfer->tx_buf;
+ spi_imx->rx_buf = transfer->rx_buf;
+ spi_imx->count = transfer->len;
+ spi_imx->txfifo = 0;
+
+ reinit_completion(&spi_imx->xfer_done);
+ spi_imx->slave_aborted = false;
+
+ spi_imx_push(spi_imx);
+
+ spi_imx->devtype_data->intctrl(spi_imx, MXC_INT_TE | MXC_INT_RDR);
+
+ if (wait_for_completion_interruptible(&spi_imx->xfer_done) ||
+ spi_imx->slave_aborted) {
+ dev_dbg(&spi->dev, "interrupted\n");
+ ret = -EINTR;
+ }
+
+ /* ecspi has a HW issue when works in Slave mode,
+ * after 64 words writtern to TXFIFO, even TXFIFO becomes empty,
+ * ECSPI_TXDATA keeps shift out the last word data,
+ * so we have to disable ECSPI when in slave mode after the
+ * transfer completes
+ */
+ if (spi_imx->devtype_data->disable)
+ spi_imx->devtype_data->disable(spi_imx);
+
+ return ret;
+}
+
static int spi_imx_transfer(struct spi_device *spi,
struct spi_transfer *transfer)
{
struct spi_imx_data *spi_imx = spi_master_get_devdata(spi->master);
+ /* flush rxfifo before transfer */
+ while (spi_imx->devtype_data->rx_available(spi_imx))
+ spi_imx->rx(spi_imx);
+
+ if (spi_imx->slave_mode)
+ return spi_imx_pio_transfer_slave(spi, transfer);
+
if (spi_imx->usedma)
return spi_imx_dma_transfer(spi_imx, transfer);
else
@@ -1345,23 +1489,17 @@ spi_imx_prepare_message(struct spi_master *master, struct spi_message *msg)
struct spi_imx_data *spi_imx = spi_master_get_devdata(master);
int ret;
- ret = clk_enable(spi_imx->clk_per);
+ ret = clk_prepare_enable(spi_imx->clk_per);
if (ret)
return ret;
- ret = clk_enable(spi_imx->clk_ipg);
+ ret = clk_prepare_enable(spi_imx->clk_ipg);
if (ret) {
- clk_disable(spi_imx->clk_per);
+ clk_disable_unprepare(spi_imx->clk_per);
return ret;
}
- ret = spi_imx->devtype_data->prepare_message(spi_imx, msg);
- if (ret) {
- clk_disable(spi_imx->clk_ipg);
- clk_disable(spi_imx->clk_per);
- }
-
- return ret;
+ return 0;
}
static int
@@ -1369,8 +1507,18 @@ spi_imx_unprepare_message(struct spi_master *master, struct spi_message *msg)
{
struct spi_imx_data *spi_imx = spi_master_get_devdata(master);
- clk_disable(spi_imx->clk_ipg);
- clk_disable(spi_imx->clk_per);
+ clk_disable_unprepare(spi_imx->clk_ipg);
+ clk_disable_unprepare(spi_imx->clk_per);
+ return 0;
+}
+
+static int spi_imx_slave_abort(struct spi_master *master)
+{
+ struct spi_imx_data *spi_imx = spi_master_get_devdata(master);
+
+ spi_imx->slave_aborted = true;
+ complete(&spi_imx->xfer_done);
+
return 0;
}
@@ -1384,14 +1532,24 @@ static int spi_imx_probe(struct platform_device *pdev)
struct spi_master *master;
struct spi_imx_data *spi_imx;
struct resource *res;
- int i, ret, irq, spi_drctl;
+ int i, ret, irq, spi_drctl, num_cs;
+ const struct spi_imx_devtype_data *devtype_data = of_id ? of_id->data :
+ (struct spi_imx_devtype_data *)pdev->id_entry->driver_data;
+ bool slave_mode;
if (!np && !mxc_platform_info) {
dev_err(&pdev->dev, "can't get the platform data\n");
return -EINVAL;
}
- master = spi_alloc_master(&pdev->dev, sizeof(struct spi_imx_data));
+ slave_mode = devtype_data->has_slavemode &&
+ of_property_read_bool(np, "spi-slave");
+ if (slave_mode)
+ master = spi_alloc_slave(&pdev->dev,
+ sizeof(struct spi_imx_data));
+ else
+ master = spi_alloc_master(&pdev->dev,
+ sizeof(struct spi_imx_data));
if (!master)
return -ENOMEM;
@@ -1406,23 +1564,51 @@ static int spi_imx_probe(struct platform_device *pdev)
master->bits_per_word_mask = SPI_BPW_RANGE_MASK(1, 32);
master->bus_num = np ? -1 : pdev->id;
+ ret = of_property_read_u32(np, "fsl,spi-num-chipselects", &num_cs);
+ if (ret < 0) {
+ if (mxc_platform_info) {
+ num_cs = mxc_platform_info->num_chipselect;
+ master->num_chipselect = num_cs;
+ }
+ } else {
+ master->num_chipselect = num_cs;
+ }
+
spi_imx = spi_master_get_devdata(master);
spi_imx->bitbang.master = master;
spi_imx->dev = &pdev->dev;
+ spi_imx->slave_mode = slave_mode;
- spi_imx->devtype_data = of_id ? of_id->data :
- (struct spi_imx_devtype_data *)pdev->id_entry->driver_data;
+ spi_imx->devtype_data = devtype_data;
- if (mxc_platform_info) {
- master->num_chipselect = mxc_platform_info->num_chipselect;
- master->cs_gpios = devm_kzalloc(&master->dev,
+ master->cs_gpios = devm_kzalloc(&master->dev,
sizeof(int) * master->num_chipselect, GFP_KERNEL);
- if (!master->cs_gpios)
- return -ENOMEM;
- for (i = 0; i < master->num_chipselect; i++)
- master->cs_gpios[i] = mxc_platform_info->chipselect[i];
- }
+ if (!spi_imx->slave_mode) {
+ if (!master->cs_gpios) {
+ dev_err(&pdev->dev, "No CS GPIOs available\n");
+ ret = -EINVAL;
+ goto out_master_put;
+ }
+
+ for (i = 0; i < master->num_chipselect; i++) {
+ int cs_gpio = of_get_named_gpio(np, "cs-gpios", i);
+ if (!gpio_is_valid(cs_gpio) && mxc_platform_info)
+ cs_gpio = mxc_platform_info->chipselect[i];
+
+ master->cs_gpios[i] = cs_gpio;
+ if (!gpio_is_valid(cs_gpio))
+ continue;
+
+ ret = devm_gpio_request(&pdev->dev, master->cs_gpios[i],
+ DRIVER_NAME);
+ if (ret) {
+ dev_err(&pdev->dev, "Can't get CS GPIO %i\n",
+ master->cs_gpios[i]);
+ goto out_master_put;
+ }
+ }
+ }
spi_imx->bitbang.chipselect = spi_imx_chipselect;
spi_imx->bitbang.setup_transfer = spi_imx_setupxfer;
@@ -1431,6 +1617,7 @@ static int spi_imx_probe(struct platform_device *pdev)
spi_imx->bitbang.master->cleanup = spi_imx_cleanup;
spi_imx->bitbang.master->prepare_message = spi_imx_prepare_message;
spi_imx->bitbang.master->unprepare_message = spi_imx_unprepare_message;
+ spi_imx->bitbang.master->slave_abort = spi_imx_slave_abort;
spi_imx->bitbang.master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH \
| SPI_NO_CS;
if (is_imx35_cspi(spi_imx) || is_imx51_ecspi(spi_imx) ||
@@ -1508,29 +1695,10 @@ static int spi_imx_probe(struct platform_device *pdev)
goto out_clk_put;
}
- if (!master->cs_gpios) {
- dev_err(&pdev->dev, "No CS GPIOs available\n");
- ret = -EINVAL;
- goto out_clk_put;
- }
-
- for (i = 0; i < master->num_chipselect; i++) {
- if (!gpio_is_valid(master->cs_gpios[i]))
- continue;
-
- ret = devm_gpio_request(&pdev->dev, master->cs_gpios[i],
- DRIVER_NAME);
- if (ret) {
- dev_err(&pdev->dev, "Can't get CS GPIO %i\n",
- master->cs_gpios[i]);
- goto out_clk_put;
- }
- }
-
dev_info(&pdev->dev, "probed\n");
- clk_disable(spi_imx->clk_ipg);
- clk_disable(spi_imx->clk_per);
+ clk_disable_unprepare(spi_imx->clk_ipg);
+ clk_disable_unprepare(spi_imx->clk_per);
return ret;
out_clk_put:
@@ -1570,11 +1738,31 @@ static int spi_imx_remove(struct platform_device *pdev)
return 0;
}
+#ifdef CONFIG_PM_SLEEP
+static int spi_imx_suspend(struct device *dev)
+{
+ pinctrl_pm_select_sleep_state(dev);
+ return 0;
+}
+
+static int spi_imx_resume(struct device *dev)
+{
+ pinctrl_pm_select_default_state(dev);
+ return 0;
+}
+
+static SIMPLE_DEV_PM_OPS(imx_spi_pm, spi_imx_suspend, spi_imx_resume);
+#define IMX_SPI_PM (&imx_spi_pm)
+#else
+#define IMX_SPI_PM NULL
+#endif
+
static struct platform_driver spi_imx_driver = {
.driver = {
.name = DRIVER_NAME,
.of_match_table = spi_imx_dt_ids,
- },
+ .pm = IMX_SPI_PM,
+ },
.id_table = spi_imx_devtype,
.probe = spi_imx_probe,
.remove = spi_imx_remove,
diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile
index 6e536020029a..c603c4b604a0 100644
--- a/drivers/staging/Makefile
+++ b/drivers/staging/Makefile
@@ -27,7 +27,7 @@ obj-$(CONFIG_FB_XGI) += xgifb/
obj-$(CONFIG_USB_EMXX) += emxx_udc/
obj-$(CONFIG_SPEAKUP) += speakup/
obj-$(CONFIG_MFD_NVEC) += nvec/
-obj-$(CONFIG_ANDROID) += android/
+obj-y += android/
obj-$(CONFIG_STAGING_BOARD) += board/
obj-$(CONFIG_LTE_GDM724X) += gdm724x/
obj-$(CONFIG_FIREWIRE_SERIAL) += fwserial/
diff --git a/drivers/staging/android/Kconfig b/drivers/staging/android/Kconfig
index 71a50b99caff..ac03e23e5c62 100644
--- a/drivers/staging/android/Kconfig
+++ b/drivers/staging/android/Kconfig
@@ -14,8 +14,8 @@ config ASHMEM
It is, in theory, a good memory allocator for low-memory devices,
because it can discard shared memory units when under memory pressure.
-source "drivers/staging/android/ion/Kconfig"
-
endif # if ANDROID
+source "drivers/staging/android/ion/Kconfig"
+
endmenu
diff --git a/drivers/staging/typec/pd.h b/drivers/staging/typec/pd.h
index 30b32ad72acd..7eea92ef2d9a 100644
--- a/drivers/staging/typec/pd.h
+++ b/drivers/staging/typec/pd.h
@@ -260,16 +260,16 @@ static inline unsigned int rdo_max_power(u32 rdo)
#define PD_T_NO_RESPONSE 5000 /* 4.5 - 5.5 seconds */
#define PD_T_DB_DETECT 10000 /* 10 - 15 seconds */
#define PD_T_SEND_SOURCE_CAP 150 /* 100 - 200 ms */
-#define PD_T_SENDER_RESPONSE 60 /* 24 - 30 ms, relaxed */
+#define PD_T_SENDER_RESPONSE 25 /* 24 - 30 ms, relaxed */
#define PD_T_SOURCE_ACTIVITY 45
#define PD_T_SINK_ACTIVITY 135
-#define PD_T_SINK_WAIT_CAP 240
+#define PD_T_SINK_WAIT_CAP 400
#define PD_T_PS_TRANSITION 500
#define PD_T_SRC_TRANSITION 35
#define PD_T_DRP_SNK 40
#define PD_T_DRP_SRC 30
-#define PD_T_PS_SOURCE_OFF 920
-#define PD_T_PS_SOURCE_ON 480
+#define PD_T_PS_SOURCE_OFF 790
+#define PD_T_PS_SOURCE_ON 400
#define PD_T_PS_HARD_RESET 30
#define PD_T_SRC_RECOVER 760
#define PD_T_SRC_RECOVER_MAX 1000
@@ -284,8 +284,8 @@ static inline unsigned int rdo_max_power(u32 rdo)
#define PD_T_DRP_TRY 100 /* 75 - 150 ms */
#define PD_T_DRP_TRYWAIT 600 /* 400 - 800 ms */
-#define PD_T_CC_DEBOUNCE 200 /* 100 - 200 ms */
-#define PD_T_PD_DEBOUNCE 20 /* 10 - 20 ms */
+#define PD_T_CC_DEBOUNCE 110 /* 100 - 200 ms */
+#define PD_T_PD_DEBOUNCE 10 /* 10 - 20 ms */
#define PD_N_CAPS_COUNT (PD_T_NO_RESPONSE / PD_T_SEND_SOURCE_CAP)
#define PD_N_HARD_RESET_COUNT 2
diff --git a/drivers/staging/typec/tcpci.c b/drivers/staging/typec/tcpci.c
index df72d8b01e73..f4ae8f55992a 100644
--- a/drivers/staging/typec/tcpci.c
+++ b/drivers/staging/typec/tcpci.c
@@ -21,6 +21,8 @@
#include <linux/interrupt.h>
#include <linux/regmap.h>
#include <linux/usb/typec.h>
+#include <linux/of_gpio.h>
+#include <linux/extcon.h>
#include "pd.h"
#include "tcpci.h"
@@ -31,14 +33,25 @@
struct tcpci {
struct device *dev;
struct i2c_client *client;
+ struct extcon_dev *edev;
struct tcpm_port *port;
struct regmap *regmap;
bool controls_vbus;
+ bool drive_vbus;
+ bool sink_disable;
+ struct gpio_desc *ss_sel_gpio;
struct tcpc_dev tcpc;
+ unsigned int irq_mask;
+};
+
+static const unsigned int tcpci_extcon_cable[] = {
+ EXTCON_USB_HOST,
+ EXTCON_USB,
+ EXTCON_NONE,
};
static inline struct tcpci *tcpc_to_tcpci(struct tcpc_dev *tcpc)
@@ -57,6 +70,31 @@ static int tcpci_write16(struct tcpci *tcpci, unsigned int reg, u16 val)
return regmap_raw_write(tcpci->regmap, reg, &val, sizeof(u16));
}
+static int tcpci_vbus_force_discharge(struct tcpc_dev *tcpc, bool enable)
+{
+ struct tcpci *tcpci = tcpc_to_tcpci(tcpc);
+ unsigned int reg;
+ int ret;
+
+ if (enable)
+ regmap_write(tcpci->regmap,
+ TCPC_VBUS_VOLTAGE_ALARM_LO_CFG, 0x1c);
+ else
+ regmap_write(tcpci->regmap,
+ TCPC_VBUS_VOLTAGE_ALARM_LO_CFG, 0);
+
+ regmap_read(tcpci->regmap, TCPC_POWER_CTRL, &reg);
+ if (enable)
+ reg |= TCPC_POWER_CTRL_FORCEDISCH;
+ else
+ reg &= ~TCPC_POWER_CTRL_FORCEDISCH;
+ ret = regmap_write(tcpci->regmap, TCPC_POWER_CTRL, reg);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
static int tcpci_set_cc(struct tcpc_dev *tcpc, enum typec_cc_status cc)
{
struct tcpci *tcpci = tcpc_to_tcpci(tcpc);
@@ -105,28 +143,79 @@ static int tcpci_set_cc(struct tcpc_dev *tcpc, enum typec_cc_status cc)
}
static int tcpci_start_drp_toggling(struct tcpc_dev *tcpc,
- enum typec_cc_status cc)
+ enum typec_cc_status cc, int attach)
{
struct tcpci *tcpci = tcpc_to_tcpci(tcpc);
- unsigned int reg = TCPC_ROLE_CTRL_DRP;
+ unsigned int reg = 0;
- switch (cc) {
- default:
- case TYPEC_CC_RP_DEF:
- reg |= (TCPC_ROLE_CTRL_RP_VAL_DEF <<
- TCPC_ROLE_CTRL_RP_VAL_SHIFT);
- break;
- case TYPEC_CC_RP_1_5:
- reg |= (TCPC_ROLE_CTRL_RP_VAL_1_5 <<
- TCPC_ROLE_CTRL_RP_VAL_SHIFT);
- break;
- case TYPEC_CC_RP_3_0:
- reg |= (TCPC_ROLE_CTRL_RP_VAL_3_0 <<
- TCPC_ROLE_CTRL_RP_VAL_SHIFT);
- break;
+ /* Only set DRP bit for auto toggle when unattached */
+ if (attach) {
+ switch (cc) {
+ case TYPEC_CC_RP_DEF:
+ if (attach >> TYPEC_POLARITY_CC2)
+ reg |= TCPC_ROLE_CTRL_CC_RP <<
+ TCPC_ROLE_CTRL_CC2_SHIFT;
+ else if (attach >> TYPEC_POLARITY_CC1)
+ reg |= TCPC_ROLE_CTRL_CC_RP <<
+ TCPC_ROLE_CTRL_CC1_SHIFT;
+
+ reg |= (TCPC_ROLE_CTRL_RP_VAL_DEF <<
+ TCPC_ROLE_CTRL_RP_VAL_SHIFT);
+ break;
+ case TYPEC_CC_RP_1_5:
+ if (attach >> TYPEC_POLARITY_CC2)
+ reg |= TCPC_ROLE_CTRL_CC_RP <<
+ TCPC_ROLE_CTRL_CC2_SHIFT;
+ else if (attach >> TYPEC_POLARITY_CC1)
+ reg |= TCPC_ROLE_CTRL_CC_RP <<
+ TCPC_ROLE_CTRL_CC1_SHIFT;
+
+ reg |= (TCPC_ROLE_CTRL_RP_VAL_1_5 <<
+ TCPC_ROLE_CTRL_RP_VAL_SHIFT);
+ break;
+ case TYPEC_CC_RP_3_0:
+ if (attach >> TYPEC_POLARITY_CC2)
+ reg |= TCPC_ROLE_CTRL_CC_RP <<
+ TCPC_ROLE_CTRL_CC2_SHIFT;
+ else if (attach >> TYPEC_POLARITY_CC1)
+ reg |= TCPC_ROLE_CTRL_CC_RP <<
+ TCPC_ROLE_CTRL_CC1_SHIFT;
+
+ reg |= (TCPC_ROLE_CTRL_RP_VAL_3_0 <<
+ TCPC_ROLE_CTRL_RP_VAL_SHIFT);
+ break;
+ case TYPEC_CC_RD:
+ if (attach >> TYPEC_POLARITY_CC2)
+ reg |= TCPC_ROLE_CTRL_CC_RD <<
+ TCPC_ROLE_CTRL_CC2_SHIFT;
+ else if (attach >> TYPEC_POLARITY_CC1)
+ reg |= TCPC_ROLE_CTRL_CC_RD <<
+ TCPC_ROLE_CTRL_CC1_SHIFT;
+ break;
+ default:
+ break;
+ }
+
+ /* keep the un-touched cc line to be open */
+ if (attach >> TYPEC_POLARITY_CC2)
+ reg |= TCPC_ROLE_CTRL_CC_OPEN <<
+ TCPC_ROLE_CTRL_CC1_SHIFT;
+ else if (attach >> TYPEC_POLARITY_CC1)
+ reg |= TCPC_ROLE_CTRL_CC_OPEN <<
+ TCPC_ROLE_CTRL_CC2_SHIFT;
+ } else { /* Not attached */
+ if (cc == TYPEC_CC_RD)
+ reg = TCPC_ROLE_CTRL_DRP | 0xa; /* Rd */
+ else
+ reg = TCPC_ROLE_CTRL_DRP | 0x5; /* Rp */
}
- return regmap_write(tcpci->regmap, TCPC_ROLE_CTRL, reg);
+ regmap_write(tcpci->regmap, TCPC_ROLE_CTRL, reg);
+
+ if (!attach)
+ regmap_write(tcpci->regmap, TCPC_COMMAND,
+ TCPC_CMD_LOOK4CONNECTION);
+ return 0;
}
static enum typec_cc_status tcpci_to_typec_cc(unsigned int cc, bool sink)
@@ -181,19 +270,33 @@ static int tcpci_set_polarity(struct tcpc_dev *tcpc,
return 0;
}
-static int tcpci_set_vconn(struct tcpc_dev *tcpc, bool enable)
+static int tcpci_set_ss_mux(struct tcpc_dev *tcpc,
+ enum typec_cc_polarity polarity)
{
struct tcpci *tcpci = tcpc_to_tcpci(tcpc);
- int ret;
- ret = regmap_write(tcpci->regmap, TCPC_POWER_CTRL,
- enable ? TCPC_POWER_CTRL_VCONN_ENABLE : 0);
- if (ret < 0)
- return ret;
+ if (!tcpci->ss_sel_gpio)
+ return 0;
+
+ if (polarity == TYPEC_POLARITY_CC1)
+ gpiod_set_value_cansleep(tcpci->ss_sel_gpio, 1);
+ else
+ gpiod_set_value_cansleep(tcpci->ss_sel_gpio, 0);
return 0;
}
+static int tcpci_set_vconn(struct tcpc_dev *tcpc, bool enable)
+{
+ struct tcpci *tcpci = tcpc_to_tcpci(tcpc);
+ int ret;
+
+ ret = regmap_update_bits(tcpci->regmap, TCPC_POWER_CTRL,
+ TCPC_POWER_CTRL_VCONN_ENABLE,
+ enable ? TCPC_POWER_CTRL_VCONN_ENABLE : 0);
+ return ret;
+}
+
static int tcpci_set_roles(struct tcpc_dev *tcpc, bool attached,
enum typec_role role, enum typec_data_role data)
{
@@ -210,6 +313,11 @@ static int tcpci_set_roles(struct tcpc_dev *tcpc, bool attached,
if (ret < 0)
return ret;
+ if (data == TYPEC_HOST)
+ extcon_set_state_sync(tcpci->edev, EXTCON_USB_HOST, true);
+ else
+ extcon_set_state_sync(tcpci->edev, EXTCON_USB_HOST, false);
+
return 0;
}
@@ -238,7 +346,34 @@ static int tcpci_get_vbus(struct tcpc_dev *tcpc)
if (ret < 0)
return ret;
- return !!(reg & TCPC_POWER_STATUS_VBUS_PRES);
+ ret = !!(reg & TCPC_POWER_STATUS_VBUS_PRES);
+
+ /*
+ * If the vbus is not from itself for source, we
+ * assume the vbus is from the port partner, this
+ * is to work around the case of connect to legacy
+ * Host like PC via a fixed Rp pull up cable, so
+ * we notify the possible EXTCON_USB connection.
+ */
+ if (!tcpci->drive_vbus)
+ extcon_set_state_sync(tcpci->edev, EXTCON_USB, ret);
+
+ return ret;
+}
+
+static unsigned int tcpci_get_vbus_vol(struct tcpc_dev *tcpc)
+{
+ struct tcpci *tcpci = tcpc_to_tcpci(tcpc);
+ unsigned int reg, ret = 0;
+
+ ret = regmap_read(tcpci->regmap, TCPC_VBUS_VOLTAGE, &reg);
+
+ /* Convert it to be the vol number(mv) */
+ ret = ((reg & TCPC_VBUS_VOL_MASK) <<
+ ((reg & TCPC_VBUS_VOL_SCALE_FACTOR_MASK) >>
+ TCPC_VBUS_VOL_SCALE_FACTOR_SHIFT)) * TCPC_VBUS_VOL_MV_UNIT;
+
+ return ret;
}
static int tcpci_set_vbus(struct tcpc_dev *tcpc, bool source, bool sink)
@@ -246,13 +381,14 @@ static int tcpci_set_vbus(struct tcpc_dev *tcpc, bool source, bool sink)
struct tcpci *tcpci = tcpc_to_tcpci(tcpc);
int ret;
- /* Disable both source and sink first before enabling anything */
-
- if (!source) {
+ /* Only disable source if it was enabled */
+ if (!source && tcpci->drive_vbus) {
ret = regmap_write(tcpci->regmap, TCPC_COMMAND,
TCPC_CMD_DISABLE_SRC_VBUS);
if (ret < 0)
return ret;
+
+ tcpci->drive_vbus = false;
}
if (!sink) {
@@ -262,14 +398,19 @@ static int tcpci_set_vbus(struct tcpc_dev *tcpc, bool source, bool sink)
return ret;
}
+ /* Enable force discharge */
+ if (!source && !sink)
+ tcpci_vbus_force_discharge(tcpc, true);
+
if (source) {
ret = regmap_write(tcpci->regmap, TCPC_COMMAND,
TCPC_CMD_SRC_VBUS_DEFAULT);
if (ret < 0)
return ret;
+ tcpci->drive_vbus = true;
}
- if (sink) {
+ if (sink && !tcpci->sink_disable) {
ret = regmap_write(tcpci->regmap, TCPC_COMMAND,
TCPC_CMD_SINK_VBUS);
if (ret < 0)
@@ -313,6 +454,35 @@ static int tcpci_pd_transmit(struct tcpc_dev *tcpc,
return 0;
}
+static int tcpci_vbus_detect(struct tcpc_dev *tcpc, bool enable)
+{
+ struct tcpci *tcpci = tcpc_to_tcpci(tcpc);
+ int ret;
+
+ if (enable) {
+ ret = regmap_write(tcpci->regmap, TCPC_COMMAND,
+ TCPC_CMD_ENABLE_VBUS_DETECT);
+ if (ret < 0)
+ return ret;
+ } else {
+ ret = regmap_write(tcpci->regmap, TCPC_COMMAND,
+ TCPC_CMD_DISABLE_VBUS_DETECT);
+ if (ret < 0)
+ return ret;
+ }
+
+ return 0;
+}
+
+static void tcpci_bist_mode(struct tcpc_dev *tcpc, bool enable)
+{
+ struct tcpci *tcpci = tcpc_to_tcpci(tcpc);
+
+ regmap_update_bits(tcpci->regmap, TCPC_TCPC_CTRL,
+ TCPC_TCPC_CTRL_BIST_MODE,
+ enable ? TCPC_TCPC_CTRL_BIST_MODE : 0);
+}
+
static int tcpci_init(struct tcpc_dev *tcpc)
{
struct tcpci *tcpci = tcpc_to_tcpci(tcpc);
@@ -336,6 +506,9 @@ static int tcpci_init(struct tcpc_dev *tcpc)
if (ret < 0)
return ret;
+ /* Clear fault condition */
+ regmap_write(tcpci->regmap, TCPC_FAULT_STATUS, 0x80);
+
if (tcpci->controls_vbus)
reg = TCPC_POWER_STATUS_VBUS_PRES;
else
@@ -344,11 +517,20 @@ static int tcpci_init(struct tcpc_dev *tcpc)
if (ret < 0)
return ret;
+ /* Enable Voltage Alarms Power status reporting */
+ regmap_read(tcpci->regmap, TCPC_POWER_CTRL, &reg);
+ reg &= ~TCPC_POWER_CTRL_DIS_VOL_ALARM;
+ ret = regmap_write(tcpci->regmap, TCPC_POWER_CTRL, reg);
+
reg = TCPC_ALERT_TX_SUCCESS | TCPC_ALERT_TX_FAILED |
TCPC_ALERT_TX_DISCARDED | TCPC_ALERT_RX_STATUS |
- TCPC_ALERT_RX_HARD_RST | TCPC_ALERT_CC_STATUS;
+ TCPC_ALERT_RX_HARD_RST | TCPC_ALERT_CC_STATUS |
+ TCPC_ALERT_RX_BUF_OVF | TCPC_ALERT_FAULT |
+ TCPC_ALERT_V_ALARM_LO;
if (tcpci->controls_vbus)
reg |= TCPC_ALERT_POWER_STATUS;
+ tcpci->irq_mask = reg;
+
return tcpci_write16(tcpci, TCPC_ALERT_MASK, reg);
}
@@ -360,10 +542,10 @@ static irqreturn_t tcpci_irq(int irq, void *dev_id)
tcpci_read16(tcpci, TCPC_ALERT, &status);
/*
- * Clear alert status for everything except RX_STATUS, which shouldn't
+ * Clear alert status for enabled irq except RX_STATUS, which shouldn't
* be cleared until we have successfully retrieved message.
*/
- if (status & ~TCPC_ALERT_RX_STATUS)
+ if ((status & ~TCPC_ALERT_RX_STATUS) & tcpci->irq_mask)
tcpci_write16(tcpci, TCPC_ALERT,
status & ~TCPC_ALERT_RX_STATUS);
@@ -371,6 +553,9 @@ static irqreturn_t tcpci_irq(int irq, void *dev_id)
tcpm_cc_change(tcpci->port);
if (status & TCPC_ALERT_POWER_STATUS) {
+ /* Read power status to clear the event */
+ regmap_read(tcpci->regmap, TCPC_POWER_STATUS, &reg);
+
regmap_read(tcpci->regmap, TCPC_POWER_STATUS_MASK, &reg);
/*
@@ -383,6 +568,9 @@ static irqreturn_t tcpci_irq(int irq, void *dev_id)
tcpm_vbus_change(tcpci->port);
}
+ if (status & TCPC_ALERT_V_ALARM_LO)
+ tcpm_vbus_low_alarm(tcpci->port);
+
if (status & TCPC_ALERT_RX_STATUS) {
struct pd_message msg;
unsigned int cnt;
@@ -392,6 +580,12 @@ static irqreturn_t tcpci_irq(int irq, void *dev_id)
tcpci_read16(tcpci, TCPC_RX_HDR, &reg);
msg.header = reg;
+ /*
+ * TCPC_RX_BYTE_CNT is the number of bytes in the
+ * RX_BUFFER_DATA_OBJECTS plus three (for the RX_BUF_FRAME_TYPE
+ * and RX_BUF_HEADER).
+ */
+ cnt -= 3;
if (WARN_ON(cnt > sizeof(msg.payload)))
cnt = sizeof(msg.payload);
@@ -405,6 +599,17 @@ static irqreturn_t tcpci_irq(int irq, void *dev_id)
tcpm_pd_receive(tcpci->port, &msg);
}
+ if (status & TCPC_ALERT_RX_BUF_OVF)
+ tcpci_write16(tcpci, TCPC_ALERT,
+ TCPC_ALERT_RX_BUF_OVF | TCPC_ALERT_RX_STATUS);
+
+ /* Clear the fault status anyway */
+ if (status & TCPC_ALERT_FAULT) {
+ regmap_read(tcpci->regmap, TCPC_FAULT_STATUS, &reg);
+ regmap_write(tcpci->regmap, TCPC_FAULT_STATUS,
+ reg | TCPC_FAULT_STATUS_CLEAR);
+ }
+
if (status & TCPC_ALERT_RX_HARD_RST)
tcpm_pd_hard_reset(tcpci->port);
@@ -430,12 +635,166 @@ static const struct tcpc_config tcpci_tcpc_config = {
.default_role = TYPEC_SINK,
};
+/* Populate struct tcpc_config from ACPI/device-tree */
static int tcpci_parse_config(struct tcpci *tcpci)
{
+ struct tcpc_config *tcfg;
+ int ret = -EINVAL;
+
tcpci->controls_vbus = true; /* XXX */
- /* TODO: Populate struct tcpc_config from ACPI/device-tree */
- tcpci->tcpc.config = &tcpci_tcpc_config;
+ /* Alloc tcpc_config struct */
+ tcpci->tcpc.config = devm_kzalloc(tcpci->dev, sizeof(*tcfg),
+ GFP_KERNEL);
+ if (!tcpci->tcpc.config)
+ return -ENOMEM;
+
+ tcfg = tcpci->tcpc.config;
+
+ /* Get the port-type */
+ tcfg->type = typec_get_port_type(tcpci->dev);
+ if (tcfg->type == TYPEC_PORT_TYPE_UNKNOWN) {
+ dev_err(tcpci->dev, "typec port type is NOT correct!\n");
+ return -EINVAL;
+ }
+
+ if (tcfg->type == TYPEC_PORT_UFP)
+ goto sink;
+
+ /* Check source pdo array size */
+ ret = device_property_read_u32_array(tcpci->dev, "src-pdos", NULL, 0);
+ if (ret <= 0) {
+ dev_err(tcpci->dev, "typec source pdo is missing!\n");
+ return -EINVAL;
+ }
+
+ tcfg->nr_src_pdo = ret;
+
+ /* Alloc src_pdo based on the array size */
+ tcfg->src_pdo = devm_kzalloc(tcpci->dev,
+ sizeof(*tcfg->src_pdo) * tcfg->nr_src_pdo, GFP_KERNEL);
+ if (!tcfg->src_pdo)
+ return -ENOMEM;
+
+ /* Read out source pdo array */
+ ret = device_property_read_u32_array(tcpci->dev, "src-pdos",
+ tcfg->src_pdo, tcfg->nr_src_pdo);
+ if (ret) {
+ dev_err(tcpci->dev, "Failed to read src pdo!\n");
+ return -EINVAL;
+ }
+
+ if (tcfg->type == TYPEC_PORT_DFP)
+ return 0;
+
+ /* Get the default-role */
+ tcfg->default_role = typec_get_power_role(tcpci->dev);
+ if (tcfg->default_role == TYPEC_ROLE_UNKNOWN) {
+ dev_err(tcpci->dev, "typec power role is NOT correct!\n");
+ return -EINVAL;
+ }
+
+ /*
+ * In case DRP only for data role, power role is source only
+ * we can use this property to disable power sink.
+ */
+ if (device_property_read_bool(tcpci->dev, "sink-disable")) {
+ tcpci->sink_disable = true;
+
+ /* Provide a sink PDO to setup a PD session */
+ tcfg->nr_snk_pdo = 1;
+ tcfg->snk_pdo = devm_kzalloc(tcpci->dev,
+ sizeof(*tcfg->snk_pdo), GFP_KERNEL);
+ if (!tcfg->snk_pdo)
+ return -ENOMEM;
+
+ /*
+ * Sink PDO setting:
+ * - Voltage in 50mV units: 5V
+ * - Operational Current in 10mA units: 100mA
+ */
+ *tcfg->snk_pdo = PDO_FIXED(5000,
+ 100,
+ PDO_FIXED_DUAL_ROLE |
+ PDO_FIXED_EXTPOWER |
+ PDO_FIXED_USB_COMM |
+ PDO_FIXED_DATA_SWAP);
+ tcfg->max_snk_mv = 5000;
+ tcfg->max_snk_ma = 2000;
+ tcfg->max_snk_mw = 10000;
+ tcfg->operating_snk_mw = 500;
+
+ return 0;
+ }
+
+sink:
+ /* Check the num of snk pdo */
+ ret = device_property_read_u32_array(tcpci->dev,
+ "snk-pdos", NULL, 0);
+ if (ret <= 0) {
+ dev_err(tcpci->dev, "typec sink pdo is missing!\n");
+ return -EINVAL;
+ }
+
+ tcfg->nr_snk_pdo = ret;
+
+ /* alloc snk_pdo based on the array size */
+ tcfg->snk_pdo = devm_kzalloc(tcpci->dev,
+ sizeof(*tcfg->snk_pdo) * tcfg->nr_snk_pdo, GFP_KERNEL);
+ if (!tcfg->snk_pdo)
+ return -ENOMEM;
+
+ /* Read out sink pdo array */
+ ret = device_property_read_u32_array(tcpci->dev, "snk-pdos",
+ tcfg->snk_pdo, tcfg->nr_snk_pdo);
+ if (ret) {
+ dev_err(tcpci->dev, "Failed to read snk pdo!\n");
+ return -EINVAL;
+ }
+
+ /* Get the max-snk-mv max-snk-ma op-snk-mw */
+ if (device_property_read_u32(tcpci->dev, "max-snk-mv",
+ &tcfg->max_snk_mv) ||
+ device_property_read_u32(tcpci->dev, "max-snk-ma",
+ &tcfg->max_snk_ma) ||
+ device_property_read_u32(tcpci->dev, "max-snk-mw",
+ &tcfg->max_snk_mw) ||
+ device_property_read_u32(tcpci->dev, "op-snk-mw",
+ &tcfg->operating_snk_mw)) {
+ ret = -EINVAL;
+ goto snk_setting_wrong;
+ }
+
+ return 0;
+
+snk_setting_wrong:
+ if (tcfg->type == TYPEC_PORT_DRP ||
+ tcfg->type == TYPEC_PORT_UFP)
+ dev_err(tcpci->dev, "Failed to read snk setting!\n");
+
+ return ret;
+}
+
+static int tcpci_ss_mux_control_init(struct tcpci *tcpci)
+{
+ struct device *dev = tcpci->dev;
+ struct gpio_desc *gpiod_reset;
+
+ gpiod_reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH);
+ if (IS_ERR(gpiod_reset)) {
+ dev_err(dev, "Failed to request reset gpio.");
+ return PTR_ERR(gpiod_reset);
+ }
+
+ if (gpiod_reset)
+ usleep_range(700, 1000);
+
+ tcpci->ss_sel_gpio = devm_gpiod_get_optional(dev, "ss-sel",
+ GPIOD_OUT_HIGH);
+ if (IS_ERR(tcpci->ss_sel_gpio)) {
+ dev_err(dev, "Failed to request super speed mux sel gpio.");
+ return PTR_ERR(tcpci->ss_sel_gpio);
+ }
return 0;
}
@@ -465,27 +824,56 @@ static int tcpci_probe(struct i2c_client *client,
tcpci->tcpc.set_polarity = tcpci_set_polarity;
tcpci->tcpc.set_vconn = tcpci_set_vconn;
tcpci->tcpc.start_drp_toggling = tcpci_start_drp_toggling;
+ tcpci->tcpc.vbus_detect = tcpci_vbus_detect;
+ tcpci->tcpc.vbus_discharge = tcpci_vbus_force_discharge;
+ tcpci->tcpc.get_vbus_vol = tcpci_get_vbus_vol;
+ tcpci->tcpc.bist_mode = tcpci_bist_mode;
+ tcpci->tcpc.ss_mux_sel = tcpci_set_ss_mux;
tcpci->tcpc.set_pd_rx = tcpci_set_pd_rx;
tcpci->tcpc.set_roles = tcpci_set_roles;
tcpci->tcpc.pd_transmit = tcpci_pd_transmit;
+ /* Allocate extcon device */
+ tcpci->edev = devm_extcon_dev_allocate(&client->dev,
+ tcpci_extcon_cable);
+ if (IS_ERR(tcpci->edev)) {
+ dev_err(&client->dev, "failed to allocate extcon dev.\n");
+ return -ENOMEM;
+ }
+
+ err = devm_extcon_dev_register(&client->dev, tcpci->edev);
+ if (err) {
+ dev_err(&client->dev, "failed to register extcon dev.\n");
+ return err;
+ }
+
err = tcpci_parse_config(tcpci);
if (err < 0)
return err;
- /* Disable chip interrupts */
- tcpci_write16(tcpci, TCPC_ALERT_MASK, 0);
+ tcpci->port = tcpm_register_port(tcpci->dev, &tcpci->tcpc);
+ if (IS_ERR(tcpci->port))
+ return PTR_ERR(tcpci->port);
+
+ err = tcpci_ss_mux_control_init(tcpci);
+ if (err)
+ goto err1;
+ irq_set_status_flags(client->irq, IRQ_DISABLE_UNLAZY);
err = devm_request_threaded_irq(tcpci->dev, client->irq, NULL,
tcpci_irq,
IRQF_ONESHOT | IRQF_TRIGGER_LOW,
dev_name(tcpci->dev), tcpci);
if (err < 0)
- return err;
+ goto err1;
- tcpci->port = tcpm_register_port(tcpci->dev, &tcpci->tcpc);
- return PTR_ERR_OR_ZERO(tcpci->port);
+ device_set_wakeup_capable(tcpci->dev, true);
+
+ return 0;
+err1:
+ tcpm_unregister_port(tcpci->port);
+ return err;
}
static int tcpci_remove(struct i2c_client *client)
@@ -493,10 +881,39 @@ static int tcpci_remove(struct i2c_client *client)
struct tcpci *tcpci = i2c_get_clientdata(client);
tcpm_unregister_port(tcpci->port);
+ irq_clear_status_flags(client->irq, IRQ_DISABLE_UNLAZY);
return 0;
}
+static int tcpci_suspend(struct device *dev)
+{
+ struct tcpci *tcpci = dev_get_drvdata(dev);
+
+ if (device_may_wakeup(dev))
+ enable_irq_wake(tcpci->client->irq);
+ else
+ disable_irq(tcpci->client->irq);
+
+ return 0;
+}
+
+static int tcpci_resume(struct device *dev)
+{
+ struct tcpci *tcpci = dev_get_drvdata(dev);
+
+ if (device_may_wakeup(dev))
+ disable_irq_wake(tcpci->client->irq);
+ else
+ enable_irq(tcpci->client->irq);
+
+ return 0;
+}
+
+static const struct dev_pm_ops tcpci_pm_ops = {
+ SET_SYSTEM_SLEEP_PM_OPS(tcpci_suspend, tcpci_resume)
+};
+
static const struct i2c_device_id tcpci_id[] = {
{ "tcpci", 0 },
{ }
@@ -514,6 +931,7 @@ MODULE_DEVICE_TABLE(of, tcpci_of_match);
static struct i2c_driver tcpci_i2c_driver = {
.driver = {
.name = "tcpci",
+ .pm = &tcpci_pm_ops,
.of_match_table = of_match_ptr(tcpci_of_match),
},
.probe = tcpci_probe,
diff --git a/drivers/staging/typec/tcpci.h b/drivers/staging/typec/tcpci.h
index 10b04c8723da..8b261a456917 100644
--- a/drivers/staging/typec/tcpci.h
+++ b/drivers/staging/typec/tcpci.h
@@ -41,9 +41,11 @@
#define TCPC_ALERT_MASK 0x12
#define TCPC_POWER_STATUS_MASK 0x14
#define TCPC_FAULT_STATUS_MASK 0x15
+#define TCPC_FAULT_STATUS_CLEAR BIT(7)
#define TCPC_CONFIG_STD_OUTPUT 0x18
#define TCPC_TCPC_CTRL 0x19
+#define TCPC_TCPC_CTRL_BIST_MODE BIT(1)
#define TCPC_TCPC_CTRL_ORIENTATION BIT(0)
#define TCPC_ROLE_CTRL 0x1a
@@ -66,6 +68,8 @@
#define TCPC_POWER_CTRL 0x1c
#define TCPC_POWER_CTRL_VCONN_ENABLE BIT(0)
+#define TCPC_POWER_CTRL_FORCEDISCH BIT(2)
+#define TCPC_POWER_CTRL_DIS_VOL_ALARM BIT(5)
#define TCPC_CC_STATUS 0x1d
#define TCPC_CC_STATUS_TERM BIT(4)
@@ -125,6 +129,11 @@
#define TCPC_TX_DATA 0x54 /* through 0x6f */
#define TCPC_VBUS_VOLTAGE 0x70
+#define TCPC_VBUS_VOL_MASK 0x3ff
+#define TCPC_VBUS_VOL_SCALE_FACTOR_MASK 0xc00
+#define TCPC_VBUS_VOL_SCALE_FACTOR_SHIFT 10
+#define TCPC_VBUS_VOL_MV_UNIT 25
+
#define TCPC_VBUS_SINK_DISCONNECT_THRESH 0x72
#define TCPC_VBUS_STOP_DISCHARGE_THRESH 0x74
#define TCPC_VBUS_VOLTAGE_ALARM_HI_CFG 0x76
diff --git a/drivers/staging/typec/tcpm.c b/drivers/staging/typec/tcpm.c
index f237e31926f4..eb125a1549f7 100644
--- a/drivers/staging/typec/tcpm.c
+++ b/drivers/staging/typec/tcpm.c
@@ -19,6 +19,7 @@
#include <linux/device.h>
#include <linux/jiffies.h>
#include <linux/kernel.h>
+#include <linux/ktime.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/proc_fs.h>
@@ -28,6 +29,8 @@
#include <linux/spinlock.h>
#include <linux/usb/typec.h>
#include <linux/workqueue.h>
+#include <linux/busfreq-imx.h>
+#include <linux/pm_qos.h>
#include "pd.h"
#include "pd_vdo.h"
@@ -92,6 +95,7 @@
S(PR_SWAP_SRC_SNK_SOURCE_OFF), \
S(PR_SWAP_SRC_SNK_SOURCE_OFF_CC_DEBOUNCED), \
S(PR_SWAP_SRC_SNK_SINK_ON), \
+ S(PR_SWAP_SNK_SRC_ASSERT_RP), \
S(PR_SWAP_SNK_SRC_SINK_OFF), \
S(PR_SWAP_SNK_SRC_SOURCE_ON), \
S(PR_SWAP_SNK_SRC_SOURCE_ON_VBUS_RAMPED_UP), \
@@ -160,6 +164,7 @@ enum pd_msg_request {
#define TCPM_CC_EVENT BIT(0)
#define TCPM_VBUS_EVENT BIT(1)
#define TCPM_RESET_EVENT BIT(2)
+#define TCPM_VBUS_LOW_ALARM BIT(3)
#define LOG_BUFFER_ENTRIES 1024
#define LOG_BUFFER_ENTRY_SIZE 128
@@ -294,6 +299,10 @@ struct tcpm_port {
/* Deadline in jiffies to exit src_try_wait state */
unsigned long max_wait;
+ /* Send response timer */
+ struct hrtimer snd_res_timer;
+ struct pm_qos_request pm_qos_req;
+
#ifdef CONFIG_DEBUG_FS
struct dentry *dentry;
struct mutex logbuffer_lock; /* log buffer access lock */
@@ -837,6 +846,33 @@ static int tcpm_pd_send_sink_caps(struct tcpm_port *port)
return tcpm_pd_transmit(port, TCPC_TX_SOP, &msg);
}
+static void tcpm_qos_handling(struct tcpm_port *port)
+{
+ enum tcpm_state idle_state;
+
+ if (port->typec_caps.type == TYPEC_PORT_UFP)
+ idle_state = SNK_UNATTACHED;
+ else if (port->typec_caps.type == TYPEC_PORT_DFP)
+ idle_state = SNK_UNATTACHED;
+ else if (port->typec_caps.type == TYPEC_PORT_DRP)
+ idle_state = DRP_TOGGLING;
+ else
+ return;
+
+ if ((port->prev_state == SNK_READY || port->prev_state == SRC_READY ||
+ port->prev_state == idle_state)) {
+ /* Hold high bus before leave those states */
+ request_bus_freq(BUS_FREQ_HIGH);
+ pm_qos_add_request(&port->pm_qos_req,
+ PM_QOS_CPU_DMA_LATENCY, 0);
+ } else if ((port->state == SNK_READY || port->state == SRC_READY ||
+ port->state == idle_state)) {
+ /* Release high bus after enter those states */
+ pm_qos_remove_request(&port->pm_qos_req);
+ release_bus_freq(BUS_FREQ_HIGH);
+ }
+}
+
static void tcpm_set_state(struct tcpm_port *port, enum tcpm_state state,
unsigned int delay_ms)
{
@@ -855,6 +891,7 @@ static void tcpm_set_state(struct tcpm_port *port, enum tcpm_state state,
port->delayed_state = INVALID_STATE;
port->prev_state = port->state;
port->state = state;
+ tcpm_qos_handling(port);
/*
* Don't re-queue the state machine work item if we're currently
* in the state machine and we're immediately changing states.
@@ -1330,6 +1367,7 @@ static void tcpm_pd_data_request(struct tcpm_port *port,
break;
}
port->sink_request = le32_to_cpu(msg->payload[0]);
+ hrtimer_cancel(&port->snd_res_timer);
tcpm_set_state(port, SRC_NEGOTIATE_CAPABILITIES, 0);
break;
case PD_DATA_SINK_CAP:
@@ -1381,7 +1419,8 @@ static void tcpm_pd_ctrl_request(struct tcpm_port *port,
tcpm_queue_message(port, PD_MSG_DATA_SINK_CAP);
break;
default:
- tcpm_queue_message(port, PD_MSG_CTRL_REJECT);
+ hrtimer_cancel(&port->snd_res_timer);
+ tcpm_set_state(port, SOFT_RESET_SEND, 0);
break;
}
break;
@@ -1409,7 +1448,7 @@ static void tcpm_pd_ctrl_request(struct tcpm_port *port,
tcpm_set_state(port, PR_SWAP_SRC_SNK_SINK_ON, 0);
break;
case PR_SWAP_SNK_SRC_SINK_OFF:
- tcpm_set_state(port, PR_SWAP_SNK_SRC_SOURCE_ON, 0);
+ tcpm_set_state(port, PR_SWAP_SNK_SRC_ASSERT_RP, 0);
break;
case VCONN_SWAP_WAIT_FOR_VCONN:
tcpm_set_state(port, VCONN_SWAP_TURN_OFF_VCONN, 0);
@@ -1422,6 +1461,7 @@ static void tcpm_pd_ctrl_request(struct tcpm_port *port,
case PD_CTRL_WAIT:
switch (port->state) {
case SNK_NEGOTIATE_CAPABILITIES:
+ hrtimer_cancel(&port->snd_res_timer);
/* USB PD specification, Figure 8-43 */
if (port->explicit_contract)
next_state = SNK_READY;
@@ -1451,15 +1491,22 @@ static void tcpm_pd_ctrl_request(struct tcpm_port *port,
case PD_CTRL_ACCEPT:
switch (port->state) {
case SNK_NEGOTIATE_CAPABILITIES:
+ hrtimer_cancel(&port->snd_res_timer);
tcpm_set_state(port, SNK_TRANSITION_SINK, 0);
break;
case SOFT_RESET_SEND:
- port->message_id = 0;
port->rx_msgid = -1;
- if (port->pwr_role == TYPEC_SOURCE)
+ /*
+ * After reset data sent, the msg id is updated
+ * by pd_transmit(0+1), now the other end gives
+ * an accept so we can go on with msg id 1.
+ */
+ if (port->pwr_role == TYPEC_SOURCE) {
next_state = SRC_SEND_CAPABILITIES;
- else
+ } else {
+ port->message_id = 0;
next_state = SNK_WAIT_CAPABILITIES;
+ }
tcpm_set_state(port, next_state, 0);
break;
case DR_SWAP_SEND:
@@ -1618,6 +1665,7 @@ static int tcpm_pd_send_control(struct tcpm_port *port,
static bool tcpm_send_queued_message(struct tcpm_port *port)
{
enum pd_msg_request queued_message;
+ int ret = 0;
do {
queued_message = port->queued_message;
@@ -1625,22 +1673,28 @@ static bool tcpm_send_queued_message(struct tcpm_port *port)
switch (queued_message) {
case PD_MSG_CTRL_WAIT:
- tcpm_pd_send_control(port, PD_CTRL_WAIT);
+ ret = tcpm_pd_send_control(port, PD_CTRL_WAIT);
break;
case PD_MSG_CTRL_REJECT:
- tcpm_pd_send_control(port, PD_CTRL_REJECT);
+ ret = tcpm_pd_send_control(port, PD_CTRL_REJECT);
break;
case PD_MSG_DATA_SINK_CAP:
- tcpm_pd_send_sink_caps(port);
+ ret = tcpm_pd_send_sink_caps(port);
break;
case PD_MSG_DATA_SOURCE_CAP:
- tcpm_pd_send_source_caps(port);
+ ret = tcpm_pd_send_source_caps(port);
break;
default:
break;
}
} while (port->queued_message != PD_MSG_NONE);
+ if (ret) {
+ tcpm_set_state(port, SOFT_RESET_SEND, 0);
+ tcpm_log(port, "TCPM sending message failure!");
+ return false;
+ }
+
if (port->delayed_state != INVALID_STATE) {
if (time_is_after_jiffies(port->delayed_runtime)) {
mod_delayed_work(port->wq, &port->state_machine,
@@ -1871,13 +1925,25 @@ static int tcpm_set_charge(struct tcpm_port *port, bool charge)
static bool tcpm_start_drp_toggling(struct tcpm_port *port)
{
- int ret;
+ int ret = 0;
+
+ tcpm_log(port, "Start DRP toggling");
+ /* First toggle Rp if current state is SNK_UNATTACHED */
if (port->tcpc->start_drp_toggling &&
- port->port_type == TYPEC_PORT_DRP) {
- tcpm_log_force(port, "Start DRP toggling");
- ret = port->tcpc->start_drp_toggling(port->tcpc,
- tcpm_rp_cc(port));
+ port->port_type == TYPEC_PORT_DRP) {
+ if (port->state == SRC_UNATTACHED)
+ ret = port->tcpc->start_drp_toggling(port->tcpc,
+ tcpm_rp_cc(port), 0);
+ else if (port->state == SNK_UNATTACHED)
+ ret = port->tcpc->start_drp_toggling(port->tcpc,
+ TYPEC_CC_RD, 0);
+ else if (port->state == SRC_ATTACHED)
+ ret = port->tcpc->start_drp_toggling(port->tcpc,
+ tcpm_rp_cc(port), 0x1 << port->polarity);
+ else if (port->state == SNK_ATTACHED)
+ ret = port->tcpc->start_drp_toggling(port->tcpc,
+ TYPEC_CC_RD, 0x1 << port->polarity);
if (!ret)
return true;
}
@@ -1885,6 +1951,15 @@ static bool tcpm_start_drp_toggling(struct tcpm_port *port)
return false;
}
+static bool tcpm_vbus_is_low(struct tcpm_port *port)
+{
+ if (port->tcpc->get_vbus_vol &&
+ port->tcpc->get_vbus_vol(port->tcpc) > TCPM_VBUS_PRESENT_LEVEL)
+ return false;
+ else
+ return true;
+}
+
static void tcpm_set_cc(struct tcpm_port *port, enum typec_cc_status cc)
{
tcpm_log(port, "cc:=%d", cc);
@@ -1929,6 +2004,13 @@ static void tcpm_typec_connect(struct tcpm_port *port)
}
}
+static void tcpm_bist_handle(struct tcpm_port *port, bool enable)
+{
+ /* Enable or disable BIST test mode */
+ if (port->tcpc && port->tcpc->bist_mode)
+ port->tcpc->bist_mode(port->tcpc, enable);
+}
+
static int tcpm_src_attach(struct tcpm_port *port)
{
enum typec_cc_polarity polarity =
@@ -1943,6 +2025,11 @@ static int tcpm_src_attach(struct tcpm_port *port)
if (ret < 0)
return ret;
+ if (port->tcpc->ss_mux_sel)
+ port->tcpc->ss_mux_sel(port->tcpc, polarity);
+
+ tcpm_start_drp_toggling(port);
+
ret = tcpm_set_roles(port, true, TYPEC_SOURCE, TYPEC_HOST);
if (ret < 0)
return ret;
@@ -2020,8 +2107,11 @@ static void tcpm_reset_port(struct tcpm_port *port)
*/
port->rx_msgid = -1;
+ tcpm_bist_handle(port, false);
port->tcpc->set_pd_rx(port->tcpc, false);
- tcpm_init_vbus(port); /* also disables charging */
+ /* Don't disable charging if boot from dead battery */
+ if (!port->vbus_never_low)
+ tcpm_init_vbus(port);
tcpm_init_vconn(port);
tcpm_set_current_limit(port, 0, 0);
tcpm_set_polarity(port, TYPEC_POLARITY_CC1);
@@ -2043,21 +2133,28 @@ static void tcpm_detach(struct tcpm_port *port)
static void tcpm_src_detach(struct tcpm_port *port)
{
+ port->data_role = TYPEC_DEVICE;
tcpm_detach(port);
}
static int tcpm_snk_attach(struct tcpm_port *port)
{
+ enum typec_cc_polarity polarity = port->cc2 != TYPEC_CC_OPEN ?
+ TYPEC_POLARITY_CC2 : TYPEC_POLARITY_CC1;
int ret;
if (port->attached)
return 0;
- ret = tcpm_set_polarity(port, port->cc2 != TYPEC_CC_OPEN ?
- TYPEC_POLARITY_CC2 : TYPEC_POLARITY_CC1);
+ ret = tcpm_set_polarity(port, polarity);
if (ret < 0)
return ret;
+ if (port->tcpc->ss_mux_sel)
+ port->tcpc->ss_mux_sel(port->tcpc, polarity);
+
+ tcpm_start_drp_toggling(port);
+
ret = tcpm_set_roles(port, true, TYPEC_SINK, TYPEC_DEVICE);
if (ret < 0)
return ret;
@@ -2104,6 +2201,12 @@ static void tcpm_acc_detach(struct tcpm_port *port)
tcpm_detach(port);
}
+static void tcpm_vbus_det(struct tcpm_port *port, bool enable)
+{
+ if (port->tcpc && port->tcpc->vbus_detect)
+ port->tcpc->vbus_detect(port->tcpc, true);
+}
+
static inline enum tcpm_state hard_reset_state(struct tcpm_port *port)
{
if (port->hard_reset_count < PD_N_HARD_RESET_COUNT)
@@ -2171,6 +2274,16 @@ static enum typec_pwr_opmode tcpm_get_pwr_opmode(enum typec_cc_status cc)
}
}
+static enum hrtimer_restart tcpm_sender_res_handle(struct hrtimer *data)
+{
+ struct tcpm_port *port = container_of(data, struct tcpm_port,
+ snd_res_timer);
+
+ tcpm_log_force(port, "Sender response timeout!");
+ tcpm_set_state(port, HARD_RESET_SEND, 0);
+ return HRTIMER_NORESTART;
+}
+
static void run_state_machine(struct tcpm_port *port)
{
int ret;
@@ -2265,9 +2378,14 @@ static void run_state_machine(struct tcpm_port *port)
break;
case SRC_ATTACHED:
- ret = tcpm_src_attach(port);
- tcpm_set_state(port, SRC_UNATTACHED,
+ if (tcpm_vbus_is_low(port)) {
+ ret = tcpm_src_attach(port);
+ tcpm_set_state(port, SRC_UNATTACHED,
ret < 0 ? 0 : PD_T_PS_SOURCE_ON);
+ } else {
+ tcpm_log(port, "Sink shouldn't provide vbus!");
+ tcpm_set_state(port, SRC_UNATTACHED, 10);
+ }
break;
case SRC_STARTUP:
opmode = tcpm_get_pwr_opmode(tcpm_rp_cc(port));
@@ -2290,16 +2408,12 @@ static void run_state_machine(struct tcpm_port *port)
tcpm_set_state(port, SRC_SEND_CAPABILITIES,
PD_T_SEND_SOURCE_CAP);
} else {
- /*
- * Per standard, we should clear the reset counter here.
- * However, that can result in state machine hang-ups.
- * Reset it only in READY state to improve stability.
- */
- /* port->hard_reset_count = 0; */
+ port->hard_reset_count = 0;
port->caps_count = 0;
port->pd_capable = true;
- tcpm_set_state_cond(port, hard_reset_state(port),
- PD_T_SEND_SOURCE_CAP);
+ hrtimer_start(&port->snd_res_timer,
+ ms_to_ktime(PD_T_SENDER_RESPONSE),
+ HRTIMER_MODE_REL);
}
break;
case SRC_NEGOTIATE_CAPABILITIES:
@@ -2370,10 +2484,11 @@ static void run_state_machine(struct tcpm_port *port)
if ((port->cc1 == TYPEC_CC_OPEN &&
port->cc2 != TYPEC_CC_OPEN) ||
(port->cc1 != TYPEC_CC_OPEN &&
- port->cc2 == TYPEC_CC_OPEN))
+ port->cc2 == TYPEC_CC_OPEN)) {
tcpm_set_state(port, SNK_DEBOUNCED,
PD_T_CC_DEBOUNCE);
- else if (tcpm_port_is_disconnected(port))
+ tcpm_vbus_det(port, true);
+ } else if (tcpm_port_is_disconnected(port))
tcpm_set_state(port, SNK_UNATTACHED,
PD_T_PD_DEBOUNCE);
break;
@@ -2498,7 +2613,6 @@ static void run_state_machine(struct tcpm_port *port)
* Do this only once.
*/
if (port->vbus_never_low) {
- port->vbus_never_low = false;
tcpm_set_state(port, SOFT_RESET_SEND,
PD_T_SINK_WAIT_CAP);
} else {
@@ -2514,8 +2628,9 @@ static void run_state_machine(struct tcpm_port *port)
/* Let the Source send capabilities again. */
tcpm_set_state(port, SNK_WAIT_CAPABILITIES, 0);
} else {
- tcpm_set_state_cond(port, hard_reset_state(port),
- PD_T_SENDER_RESPONSE);
+ hrtimer_start(&port->snd_res_timer,
+ ms_to_ktime(PD_T_SENDER_RESPONSE),
+ HRTIMER_MODE_REL);
}
break;
case SNK_TRANSITION_SINK:
@@ -2613,7 +2728,10 @@ static void run_state_machine(struct tcpm_port *port)
* to PE_SNK_Transition_to_default.
*/
tcpm_set_attached_state(port, true);
- tcpm_set_state(port, SNK_STARTUP, 0);
+ if (tcpm_port_is_disconnected(port))
+ tcpm_set_state(port, unattached_state(port), 0);
+ else
+ tcpm_set_state(port, SNK_STARTUP, 0);
break;
/* Soft_Reset states */
@@ -2629,11 +2747,23 @@ static void run_state_machine(struct tcpm_port *port)
case SOFT_RESET_SEND:
port->message_id = 0;
port->rx_msgid = -1;
- if (tcpm_pd_send_control(port, PD_CTRL_SOFT_RESET))
- tcpm_set_state_cond(port, hard_reset_state(port), 0);
- else
+ if (tcpm_pd_send_control(port, PD_CTRL_SOFT_RESET)) {
+ if (port->vbus_never_low)
+ /*
+ * No ack from source, we keep a
+ * non-PD session as it is(only 5V)
+ * because it may be the system power
+ * source.
+ */
+ tcpm_set_state(port, SNK_READY, 0);
+ else
+ tcpm_set_state_cond(port,
+ hard_reset_state(port), 0);
+ } else {
tcpm_set_state_cond(port, hard_reset_state(port),
PD_T_SENDER_RESPONSE);
+ }
+ port->vbus_never_low = false;
break;
/* DR_Swap states */
@@ -2710,7 +2840,7 @@ static void run_state_machine(struct tcpm_port *port)
tcpm_set_state(port, ERROR_RECOVERY, 0);
break;
}
- tcpm_set_state_cond(port, SNK_UNATTACHED, PD_T_PS_SOURCE_ON);
+ tcpm_set_state_cond(port, ERROR_RECOVERY, PD_T_PS_SOURCE_ON);
break;
case PR_SWAP_SRC_SNK_SINK_ON:
tcpm_set_state(port, SNK_STARTUP, 0);
@@ -2720,9 +2850,11 @@ static void run_state_machine(struct tcpm_port *port)
tcpm_set_state(port, hard_reset_state(port),
PD_T_PS_SOURCE_OFF);
break;
- case PR_SWAP_SNK_SRC_SOURCE_ON:
+ case PR_SWAP_SNK_SRC_ASSERT_RP:
tcpm_set_cc(port, tcpm_rp_cc(port));
tcpm_set_vbus(port, true);
+ break;
+ case PR_SWAP_SNK_SRC_SOURCE_ON:
/*
* allow time VBUS ramp-up, must be < tNewSrc
* Also, this window overlaps with CC debounce as well.
@@ -2788,6 +2920,7 @@ static void run_state_machine(struct tcpm_port *port)
break;
case BIST_RX:
+ tcpm_bist_handle(port, true);
switch (BDO_MODE_MASK(port->bist_request)) {
case BDO_MODE_CARRIER2:
tcpm_pd_transmit(port, TCPC_TX_BIST_MODE_2, NULL);
@@ -2795,8 +2928,6 @@ static void run_state_machine(struct tcpm_port *port)
default:
break;
}
- /* Always switch to unattached state */
- tcpm_set_state(port, unattached_state(port), 0);
break;
case ERROR_RECOVERY:
tcpm_swap_complete(port, -EPROTO);
@@ -2839,6 +2970,7 @@ static void tcpm_state_machine_work(struct work_struct *work)
port->prev_state = port->state;
port->state = port->delayed_state;
port->delayed_state = INVALID_STATE;
+ tcpm_qos_handling(port);
}
/*
@@ -2851,7 +2983,6 @@ static void tcpm_state_machine_work(struct work_struct *work)
if (port->queued_message)
tcpm_send_queued_message(port);
} while (port->state != prev_state && !port->delayed_state);
-
done:
port->state_machine_running = false;
mutex_unlock(&port->lock);
@@ -2925,6 +3056,9 @@ static void _tcpm_cc_change(struct tcpm_port *port, enum typec_cc_status cc1,
new_state = SNK_UNATTACHED;
else if (port->vbus_present)
new_state = tcpm_try_src(port) ? SRC_TRY : SNK_ATTACHED;
+ else if (cc1 > TYPEC_CC_RP_DEF || cc2 > TYPEC_CC_RP_DEF)
+ /* CC changes on pull-up value */
+ new_state = SNK_ATTACH_WAIT;
else
new_state = SNK_UNATTACHED;
if (new_state != port->delayed_state)
@@ -3000,10 +3134,12 @@ static void _tcpm_cc_change(struct tcpm_port *port, enum typec_cc_status cc1,
/* Do nothing, waiting for tCCDebounce */
break;
case PR_SWAP_SNK_SRC_SINK_OFF:
+ case PR_SWAP_SNK_SRC_ASSERT_RP:
case PR_SWAP_SRC_SNK_TRANSITION_OFF:
case PR_SWAP_SRC_SNK_SOURCE_OFF:
case PR_SWAP_SRC_SNK_SOURCE_OFF_CC_DEBOUNCED:
case PR_SWAP_SNK_SRC_SOURCE_ON:
+ case ERROR_RECOVERY:
/*
* CC state change is expected in PR_SWAP
* Ignore it.
@@ -3071,6 +3207,10 @@ static void _tcpm_pd_vbus_on(struct tcpm_port *port)
case SRC_TRY_DEBOUNCE:
/* Do nothing, waiting for sink detection */
break;
+ case PR_SWAP_SNK_SRC_ASSERT_RP:
+ /* If vbus is reached, start source on to send PS_RDY */
+ tcpm_set_state(port, PR_SWAP_SNK_SRC_SOURCE_ON, 0);
+ break;
default:
break;
}
@@ -3114,7 +3254,13 @@ static void _tcpm_pd_vbus_off(struct tcpm_port *port)
break;
case PR_SWAP_SRC_SNK_TRANSITION_OFF:
- tcpm_set_state(port, PR_SWAP_SRC_SNK_SOURCE_OFF, 0);
+ /*
+ * At this moment, vbus may only fall to be below 4v,
+ * we need wait tPSSourceOff and let vbus discharge
+ * finished.
+ */
+ if (!port->tcpc->vbus_discharge)
+ tcpm_set_state(port, PR_SWAP_SRC_SNK_SOURCE_OFF, 0);
break;
case PR_SWAP_SNK_SRC_SINK_OFF:
@@ -3149,6 +3295,22 @@ static void _tcpm_pd_hard_reset(struct tcpm_port *port)
0);
}
+static void _tcpm_vbus_discharge(struct tcpm_port *port, bool on)
+{
+ tcpm_log_force(port, "%s force discharge", on ? "Enable":"Disable");
+
+ /*
+ * By vbus discharge and low alarm, now we can disable
+ * vbus discharge.
+ */
+ if (port->tcpc && port->tcpc->vbus_discharge)
+ port->tcpc->vbus_discharge(port->tcpc, false);
+
+ /* We can transit to PR_SWAP_SRC_SNK_SOURCE_OFF safely */
+ if (port->state == PR_SWAP_SRC_SNK_TRANSITION_OFF)
+ tcpm_set_state(port, PR_SWAP_SRC_SNK_SOURCE_OFF, 0);
+}
+
static void tcpm_pd_event_handler(struct work_struct *work)
{
struct tcpm_port *port = container_of(work, struct tcpm_port,
@@ -3173,6 +3335,10 @@ static void tcpm_pd_event_handler(struct work_struct *work)
else
_tcpm_pd_vbus_off(port);
}
+
+ if (events & TCPM_VBUS_LOW_ALARM)
+ _tcpm_vbus_discharge(port, false);
+
if (events & TCPM_CC_EVENT) {
enum typec_cc_status cc1, cc2;
@@ -3203,6 +3369,15 @@ void tcpm_vbus_change(struct tcpm_port *port)
}
EXPORT_SYMBOL_GPL(tcpm_vbus_change);
+void tcpm_vbus_low_alarm(struct tcpm_port *port)
+{
+ spin_lock(&port->pd_event_lock);
+ port->pd_events |= TCPM_VBUS_LOW_ALARM;
+ spin_unlock(&port->pd_event_lock);
+ queue_work(port->wq, &port->event_work);
+}
+EXPORT_SYMBOL_GPL(tcpm_vbus_low_alarm);
+
void tcpm_pd_hard_reset(struct tcpm_port *port)
{
spin_lock(&port->pd_event_lock);
@@ -3386,29 +3561,34 @@ static void tcpm_init(struct tcpm_port *port)
{
enum typec_cc_status cc1, cc2;
- port->tcpc->init(port->tcpc);
-
- tcpm_reset_port(port);
-
/*
- * XXX
- * Should possibly wait for VBUS to settle if it was enabled locally
- * since tcpm_reset_port() will disable VBUS.
+ * Possibly the vbus was enabled locally which is wrong, we can
+ * firstly disable power sink then start tcpm state transition
+ * to fix it, this is different from dead battery case which can
+ * detect RP on cc , in case of dead battery boot, we don't disable
+ * vbus sink for charging.
*/
+ if (port->tcpc->get_cc(port->tcpc, &cc1, &cc2))
+ return;
+
port->vbus_present = port->tcpc->get_vbus(port->tcpc);
- if (port->vbus_present)
+ if ((cc1 >= TYPEC_CC_RP_DEF || cc2 >= TYPEC_CC_RP_DEF) &&
+ port->vbus_present)
port->vbus_never_low = true;
+ tcpm_reset_port(port);
+
tcpm_set_state(port, tcpm_default_state(port), 0);
- if (port->tcpc->get_cc(port->tcpc, &cc1, &cc2) == 0)
- _tcpm_cc_change(port, cc1, cc2);
+ _tcpm_cc_change(port, cc1, cc2);
/*
* Some adapters need a clean slate at startup, and won't recover
* otherwise. So do not try to be fancy and force a clean disconnect.
*/
- tcpm_set_state(port, PORT_RESET, 0);
+ /*tcpm_set_state(port, PORT_RESET, 0);*/
+
+ port->tcpc->init(port->tcpc);
}
static int tcpm_port_type_set(const struct typec_capability *cap,
@@ -3550,7 +3730,7 @@ struct tcpm_port *tcpm_register_port(struct device *dev, struct tcpc_dev *tcpc)
mutex_init(&port->lock);
mutex_init(&port->swap_lock);
- port->wq = create_singlethread_workqueue(dev_name(dev));
+ port->wq = create_freezable_workqueue(dev_name(dev));
if (!port->wq)
return ERR_PTR(-ENOMEM);
INIT_DELAYED_WORK(&port->state_machine, tcpm_state_machine_work);
@@ -3621,8 +3801,14 @@ struct tcpm_port *tcpm_register_port(struct device *dev, struct tcpc_dev *tcpc)
}
}
+ hrtimer_init(&port->snd_res_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
+ port->snd_res_timer.function = tcpm_sender_res_handle;
+
tcpm_debugfs_init(port);
mutex_lock(&port->lock);
+ request_bus_freq(BUS_FREQ_HIGH);
+ pm_qos_add_request(&port->pm_qos_req, PM_QOS_CPU_DMA_LATENCY, 0);
+
tcpm_init(port);
mutex_unlock(&port->lock);
diff --git a/drivers/staging/typec/tcpm.h b/drivers/staging/typec/tcpm.h
index 7e9a6b7b5cd6..cc1bb8e1eadc 100644
--- a/drivers/staging/typec/tcpm.h
+++ b/drivers/staging/typec/tcpm.h
@@ -19,6 +19,9 @@
#include <linux/usb/typec.h>
#include "pd.h"
+/* VBUS off level should be lower than it */
+#define TCPM_VBUS_PRESENT_LEVEL 600
+
enum typec_cc_status {
TYPEC_CC_OPEN,
TYPEC_CC_RA,
@@ -55,10 +58,10 @@ enum tcpm_transmit_type {
};
struct tcpc_config {
- const u32 *src_pdo;
+ u32 *src_pdo;
unsigned int nr_src_pdo;
- const u32 *snk_pdo;
+ u32 *snk_pdo;
unsigned int nr_snk_pdo;
const u32 *snk_vdo;
@@ -105,7 +108,7 @@ struct tcpc_mux_dev {
};
struct tcpc_dev {
- const struct tcpc_config *config;
+ struct tcpc_config *config;
int (*init)(struct tcpc_dev *dev);
int (*get_vbus)(struct tcpc_dev *dev);
@@ -116,6 +119,8 @@ struct tcpc_dev {
* tcpcs may include BC1.2 charger detection and use that in this case.
*/
int (*get_current_limit)(struct tcpc_dev *dev);
+ /* Optional, get the vbus voltage(mv) */
+ unsigned int (*get_vbus_vol)(struct tcpc_dev *dev);
int (*set_cc)(struct tcpc_dev *dev, enum typec_cc_status cc);
int (*get_cc)(struct tcpc_dev *dev, enum typec_cc_status *cc1,
enum typec_cc_status *cc2);
@@ -128,10 +133,16 @@ struct tcpc_dev {
int (*set_roles)(struct tcpc_dev *dev, bool attached,
enum typec_role role, enum typec_data_role data);
int (*start_drp_toggling)(struct tcpc_dev *dev,
- enum typec_cc_status cc);
+ enum typec_cc_status cc, int attach);
int (*try_role)(struct tcpc_dev *dev, int role);
int (*pd_transmit)(struct tcpc_dev *dev, enum tcpm_transmit_type type,
const struct pd_message *msg);
+ int (*vbus_detect)(struct tcpc_dev *dev, bool enable);
+ int (*vbus_discharge)(struct tcpc_dev *tcpc, bool enable);
+ void (*bist_mode)(struct tcpc_dev *tcpc, bool enable);
+ int (*ss_mux_sel)(struct tcpc_dev *dev,
+ enum typec_cc_polarity polarity);
+
struct tcpc_mux_dev *mux;
};
@@ -157,5 +168,6 @@ void tcpm_pd_transmit_complete(struct tcpm_port *port,
enum tcpm_transmit_status status);
void tcpm_pd_hard_reset(struct tcpm_port *port);
void tcpm_tcpc_reset(struct tcpm_port *port);
+void tcpm_vbus_low_alarm(struct tcpm_port *port);
#endif /* __LINUX_USB_TCPM_H */
diff --git a/drivers/staging/vboxvideo/vbox_mode.c b/drivers/staging/vboxvideo/vbox_mode.c
index 6f08dc966719..b265fe924556 100644
--- a/drivers/staging/vboxvideo/vbox_mode.c
+++ b/drivers/staging/vboxvideo/vbox_mode.c
@@ -377,7 +377,7 @@ static struct drm_encoder *vbox_best_single_encoder(struct drm_connector
/* pick the encoder ids */
if (enc_id)
- return drm_encoder_find(connector->dev, enc_id);
+ return drm_encoder_find(connector->dev, NULL, enc_id);
return NULL;
}
diff --git a/drivers/tee/optee/call.c b/drivers/tee/optee/call.c
index f7b7b404c990..c07b654ef797 100644
--- a/drivers/tee/optee/call.c
+++ b/drivers/tee/optee/call.c
@@ -22,6 +22,11 @@
#include "optee_private.h"
#include "optee_smc.h"
+#if defined(CONFIG_SOC_IMX6) || defined(CONFIG_SOC_IMX7) \
+ || (CONFIG_HAVE_IMX8_SOC)
+#include <linux/busfreq-imx.h>
+#endif
+
struct optee_call_waiter {
struct list_head list_node;
struct completion c;
@@ -139,8 +144,19 @@ u32 optee_do_call_with_arg(struct tee_context *ctx, phys_addr_t parg)
param.a0 = OPTEE_SMC_CALL_WITH_ARG;
reg_pair_from_64(&param.a1, &param.a2, parg);
+
/* Initialize waiter */
optee_cq_wait_init(&optee->call_queue, &w);
+
+#if defined(CONFIG_SOC_IMX6) || defined(CONFIG_SOC_IMX7) \
+ || (CONFIG_HAVE_IMX8_SOC)
+ /*
+ * Request Busfreq to HIGH to prevent DDR self-refresh while
+ * executing Secure stuff
+ */
+ request_bus_freq(BUS_FREQ_HIGH);
+#endif
+
while (true) {
struct arm_smccc_res res;
@@ -166,6 +182,14 @@ u32 optee_do_call_with_arg(struct tee_context *ctx, phys_addr_t parg)
}
}
+#if defined(CONFIG_SOC_IMX6) || defined(CONFIG_SOC_IMX7) \
+ || (CONFIG_HAVE_IMX8_SOC)
+ /*
+ * Release Busfreq from HIGH
+ */
+ release_bus_freq(BUS_FREQ_HIGH);
+#endif
+
/*
* We're done with our thread in secure world, if there's any
* thread waiters wake up one.
diff --git a/drivers/tee/optee/core.c b/drivers/tee/optee/core.c
index 834884c370c5..5f0f4ebff4c2 100644
--- a/drivers/tee/optee/core.c
+++ b/drivers/tee/optee/core.c
@@ -29,6 +29,10 @@
#include "optee_private.h"
#include "optee_smc.h"
+#ifdef CONFIG_OUTER_CACHE
+#include <asm/outercache.h>
+#endif
+
#define DRIVER_NAME "optee"
#define OPTEE_SHM_NUM_PRIV_PAGES 1
@@ -187,12 +191,12 @@ static int optee_open(struct tee_context *ctx)
if (teedev == optee->supp_teedev) {
bool busy = true;
- mutex_lock(&optee->supp.ctx_mutex);
+ mutex_lock(&optee->supp.mutex);
if (!optee->supp.ctx) {
busy = false;
optee->supp.ctx = ctx;
}
- mutex_unlock(&optee->supp.ctx_mutex);
+ mutex_unlock(&optee->supp.mutex);
if (busy) {
kfree(ctxdata);
return -EBUSY;
@@ -252,11 +256,8 @@ static void optee_release(struct tee_context *ctx)
ctx->data = NULL;
- if (teedev == optee->supp_teedev) {
- mutex_lock(&optee->supp.ctx_mutex);
- optee->supp.ctx = NULL;
- mutex_unlock(&optee->supp.ctx_mutex);
- }
+ if (teedev == optee->supp_teedev)
+ optee_supp_release(&optee->supp);
}
static const struct tee_driver_ops optee_ops = {
@@ -407,6 +408,70 @@ out:
return pool;
}
+#ifdef CONFIG_OUTER_CACHE
+/**
+ * @brief Call the TEE to get a shared mutex between TEE and Linux to
+ * do Outer Cache maintenance
+ *
+ * @param[in] invoke_fn Reference to the SMC call function
+ *
+ * @retval 0 Success
+ * @retval -EINVAL Invalid value
+ * @retval -ENOMEM Not enought memory
+ */
+static int optee_outercache_mutex(optee_invoke_fn *invoke_fn)
+{
+ struct arm_smccc_res res;
+
+ int ret = -EINVAL;
+ void *vaddr = NULL;
+ phys_addr_t paddr = 0;
+
+ /* Get the Physical Address of the mutex allocated in the SHM */
+ invoke_fn(OPTEE_SMC_L2CC_MUTEX,
+ OPTEE_SMC_L2CC_MUTEX_GET_ADDR, 0, 0, 0, 0, 0, 0, &res);
+
+ if (res.a0 != OPTEE_SMC_RETURN_OK) {
+ pr_warn("no TZ l2cc mutex service supported\n");
+ goto out;
+ }
+
+ paddr = (unsigned long)reg_pair_to_ptr(res.a2, res.a3);
+ pr_debug("outer cache shared mutex paddr 0x%lx\n", (unsigned long)paddr);
+
+ /* Remap the Mutex into a cacheable area */
+ vaddr = memremap(paddr, sizeof(u32), MEMREMAP_WB);
+ if (vaddr == NULL) {
+ pr_warn("TZ l2cc mutex: ioremap failed\n");
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ pr_debug("outer cache shared mutex vaddr %p\n", vaddr);
+
+ if (outer_mutex(vaddr)) {
+ pr_warn("TZ l2cc mutex: outer cache refused\n");
+ goto out;
+ }
+
+ invoke_fn(OPTEE_SMC_L2CC_MUTEX,
+ OPTEE_SMC_L2CC_MUTEX_ENABLE, 0, 0, 0, 0, 0, 0, &res);
+
+ if (res.a0 != OPTEE_SMC_RETURN_OK) {
+ pr_warn("TZ l2cc mutex disabled: TZ enable failed\n");
+ goto out;
+ }
+
+ ret = 0;
+
+out:
+ pr_info("teetz outer mutex: ret=%d pa=0x%lx va=0x%p\n",
+ ret, (unsigned long)paddr, vaddr);
+
+ return ret;
+}
+#endif
+
/* Simple wrapper functions to be able to use a function pointer */
static void optee_smccc_smc(unsigned long a0, unsigned long a1,
unsigned long a2, unsigned long a3,
@@ -486,6 +551,17 @@ static struct optee *optee_probe(struct device_node *np)
if (IS_ERR(pool))
return (void *)pool;
+#ifdef CONFIG_OUTER_CACHE
+
+ /* Try to get a Share Mutex to do L2 Cache maintenance */
+ if (of_find_compatible_node(NULL, NULL, "arm,pl310-cache")) {
+ rc = optee_outercache_mutex(invoke_fn);
+ if (rc)
+ goto err;
+ }
+
+#endif
+
optee = kzalloc(sizeof(*optee), GFP_KERNEL);
if (!optee) {
rc = -ENOMEM;
diff --git a/drivers/tee/optee/optee_private.h b/drivers/tee/optee/optee_private.h
index c374cd594314..3e7da187acbe 100644
--- a/drivers/tee/optee/optee_private.h
+++ b/drivers/tee/optee/optee_private.h
@@ -53,36 +53,24 @@ struct optee_wait_queue {
* @ctx the context of current connected supplicant.
* if !NULL the supplicant device is available for use,
* else busy
- * @ctx_mutex: held while accessing @ctx
- * @func: supplicant function id to call
- * @ret: call return value
- * @num_params: number of elements in @param
- * @param: parameters for @func
- * @req_posted: if true, a request has been posted to the supplicant
- * @supp_next_send: if true, next step is for supplicant to send response
- * @thrd_mutex: held by the thread doing a request to supplicant
- * @supp_mutex: held by supplicant while operating on this struct
- * @data_to_supp: supplicant is waiting on this for next request
- * @data_from_supp: requesting thread is waiting on this to get the result
+ * @mutex: held while accessing content of this struct
+ * @req_id: current request id if supplicant is doing synchronous
+ * communication, else -1
+ * @reqs: queued request not yet retrieved by supplicant
+ * @idr: IDR holding all requests currently being processed
+ * by supplicant
+ * @reqs_c: completion used by supplicant when waiting for a
+ * request to be queued.
*/
struct optee_supp {
+ /* Serializes access to this struct */
+ struct mutex mutex;
struct tee_context *ctx;
- /* Serializes access of ctx */
- struct mutex ctx_mutex;
-
- u32 func;
- u32 ret;
- size_t num_params;
- struct tee_param *param;
-
- bool req_posted;
- bool supp_next_send;
- /* Serializes access to this struct for requesting thread */
- struct mutex thrd_mutex;
- /* Serializes access to this struct for supplicant threads */
- struct mutex supp_mutex;
- struct completion data_to_supp;
- struct completion data_from_supp;
+
+ int req_id;
+ struct list_head reqs;
+ struct idr idr;
+ struct completion reqs_c;
};
/**
@@ -142,6 +130,7 @@ int optee_supp_read(struct tee_context *ctx, void __user *buf, size_t len);
int optee_supp_write(struct tee_context *ctx, void __user *buf, size_t len);
void optee_supp_init(struct optee_supp *supp);
void optee_supp_uninit(struct optee_supp *supp);
+void optee_supp_release(struct optee_supp *supp);
int optee_supp_recv(struct tee_context *ctx, u32 *func, u32 *num_params,
struct tee_param *param);
diff --git a/drivers/tee/optee/optee_smc.h b/drivers/tee/optee/optee_smc.h
index 069c8e1429de..e47b53376616 100644
--- a/drivers/tee/optee/optee_smc.h
+++ b/drivers/tee/optee/optee_smc.h
@@ -198,6 +198,49 @@ struct optee_smc_get_shm_config_result {
};
/*
+ * Configures L2CC mutex
+ *
+ * Disables, enables usage of L2CC mutex. Returns or sets physical address
+ * of L2CC mutex.
+ *
+ * Call register usage:
+ * a0 SMC Function ID, OPTEE_SMC_L2CC_MUTEX
+ * a1 OPTEE_SMC_L2CC_MUTEX_GET_ADDR Get physical address of mutex
+ * OPTEE_SMC_L2CC_MUTEX_SET_ADDR Set physical address of mutex
+ * OPTEE_SMC_L2CC_MUTEX_ENABLE Enable usage of mutex
+ * OPTEE_SMC_L2CC_MUTEX_DISABLE Disable usage of mutex
+ * a2 if a1 == OPTEE_SMC_L2CC_MUTEX_SET_ADDR, upper 32bit of a 64bit
+ * physical address of mutex
+ * a3 if a1 == OPTEE_SMC_L2CC_MUTEX_SET_ADDR, lower 32bit of a 64bit
+ * physical address of mutex
+ * a3-6 Not used
+ * a7 Hypervisor Client ID register
+ *
+ * Have config return register usage:
+ * a0 OPTEE_SMC_RETURN_OK
+ * a1 Preserved
+ * a2 if a1 == OPTEE_SMC_L2CC_MUTEX_GET_ADDR, upper 32bit of a 64bit
+ * physical address of mutex
+ * a3 if a1 == OPTEE_SMC_L2CC_MUTEX_GET_ADDR, lower 32bit of a 64bit
+ * physical address of mutex
+ * a3-7 Preserved
+ *
+ * Error return register usage:
+ * a0 OPTEE_SMC_RETURN_ENOTAVAIL Physical address not available
+ * OPTEE_SMC_RETURN_EBADADDR Bad supplied physical address
+ * OPTEE_SMC_RETURN_EBADCMD Unsupported value in a1
+ * a1-7 Preserved
+ */
+#define OPTEE_SMC_L2CC_MUTEX_GET_ADDR 0
+#define OPTEE_SMC_L2CC_MUTEX_SET_ADDR 1
+#define OPTEE_SMC_L2CC_MUTEX_ENABLE 2
+#define OPTEE_SMC_L2CC_MUTEX_DISABLE 3
+
+#define OPTEE_SMC_FUNCID_L2CC_MUTEX 8
+#define OPTEE_SMC_L2CC_MUTEX \
+ OPTEE_SMC_FAST_CALL_VAL(OPTEE_SMC_FUNCID_L2CC_MUTEX)
+
+/*
* Exchanges capabilities between normal world and secure world
*
* Call register usage:
diff --git a/drivers/tee/optee/rpc.c b/drivers/tee/optee/rpc.c
index cef417f4f4d2..c6df4317ca9f 100644
--- a/drivers/tee/optee/rpc.c
+++ b/drivers/tee/optee/rpc.c
@@ -192,10 +192,10 @@ static struct tee_shm *cmd_alloc_suppl(struct tee_context *ctx, size_t sz)
if (ret)
return ERR_PTR(-ENOMEM);
- mutex_lock(&optee->supp.ctx_mutex);
+ mutex_lock(&optee->supp.mutex);
/* Increases count as secure world doesn't have a reference */
shm = tee_shm_get_from_id(optee->supp.ctx, param.u.value.c);
- mutex_unlock(&optee->supp.ctx_mutex);
+ mutex_unlock(&optee->supp.mutex);
return shm;
}
diff --git a/drivers/tee/optee/supp.c b/drivers/tee/optee/supp.c
index b4ea0678a436..df35fc01fd3e 100644
--- a/drivers/tee/optee/supp.c
+++ b/drivers/tee/optee/supp.c
@@ -16,21 +16,61 @@
#include <linux/uaccess.h>
#include "optee_private.h"
+struct optee_supp_req {
+ struct list_head link;
+
+ bool busy;
+ u32 func;
+ u32 ret;
+ size_t num_params;
+ struct tee_param *param;
+
+ struct completion c;
+};
+
void optee_supp_init(struct optee_supp *supp)
{
memset(supp, 0, sizeof(*supp));
- mutex_init(&supp->ctx_mutex);
- mutex_init(&supp->thrd_mutex);
- mutex_init(&supp->supp_mutex);
- init_completion(&supp->data_to_supp);
- init_completion(&supp->data_from_supp);
+ mutex_init(&supp->mutex);
+ init_completion(&supp->reqs_c);
+ idr_init(&supp->idr);
+ INIT_LIST_HEAD(&supp->reqs);
+ supp->req_id = -1;
}
void optee_supp_uninit(struct optee_supp *supp)
{
- mutex_destroy(&supp->ctx_mutex);
- mutex_destroy(&supp->thrd_mutex);
- mutex_destroy(&supp->supp_mutex);
+ mutex_destroy(&supp->mutex);
+ idr_destroy(&supp->idr);
+}
+
+void optee_supp_release(struct optee_supp *supp)
+{
+ int id;
+ struct optee_supp_req *req;
+ struct optee_supp_req *req_tmp;
+
+ mutex_lock(&supp->mutex);
+
+ /* Abort all request retrieved by supplicant */
+ idr_for_each_entry(&supp->idr, req, id) {
+ req->busy = false;
+ idr_remove(&supp->idr, id);
+ req->ret = TEEC_ERROR_COMMUNICATION;
+ complete(&req->c);
+ }
+
+ /* Abort all queued requests */
+ list_for_each_entry_safe(req, req_tmp, &supp->reqs, link) {
+ list_del(&req->link);
+ req->ret = TEEC_ERROR_COMMUNICATION;
+ complete(&req->c);
+ }
+
+ supp->ctx = NULL;
+ supp->req_id = -1;
+
+ mutex_unlock(&supp->mutex);
}
/**
@@ -44,53 +84,42 @@ void optee_supp_uninit(struct optee_supp *supp)
*/
u32 optee_supp_thrd_req(struct tee_context *ctx, u32 func, size_t num_params,
struct tee_param *param)
+
{
- bool interruptable;
struct optee *optee = tee_get_drvdata(ctx->teedev);
struct optee_supp *supp = &optee->supp;
+ struct optee_supp_req *req = kzalloc(sizeof(*req), GFP_KERNEL);
+ bool interruptable;
u32 ret;
- /*
- * Other threads blocks here until we've copied our answer from
- * supplicant.
- */
- while (mutex_lock_interruptible(&supp->thrd_mutex)) {
- /* See comment below on when the RPC can be interrupted. */
- mutex_lock(&supp->ctx_mutex);
- interruptable = !supp->ctx;
- mutex_unlock(&supp->ctx_mutex);
- if (interruptable)
- return TEEC_ERROR_COMMUNICATION;
- }
+ if (!req)
+ return TEEC_ERROR_OUT_OF_MEMORY;
- /*
- * We have exclusive access now since the supplicant at this
- * point is either doing a
- * wait_for_completion_interruptible(&supp->data_to_supp) or is in
- * userspace still about to do the ioctl() to enter
- * optee_supp_recv() below.
- */
+ init_completion(&req->c);
+ req->func = func;
+ req->num_params = num_params;
+ req->param = param;
- supp->func = func;
- supp->num_params = num_params;
- supp->param = param;
- supp->req_posted = true;
+ /* Insert the request in the request list */
+ mutex_lock(&supp->mutex);
+ list_add_tail(&req->link, &supp->reqs);
+ mutex_unlock(&supp->mutex);
- /* Let supplicant get the data */
- complete(&supp->data_to_supp);
+ /* Tell an eventual waiter there's a new request */
+ complete(&supp->reqs_c);
/*
* Wait for supplicant to process and return result, once we've
- * returned from wait_for_completion(data_from_supp) we have
+ * returned from wait_for_completion(&req->c) successfully we have
* exclusive access again.
*/
- while (wait_for_completion_interruptible(&supp->data_from_supp)) {
- mutex_lock(&supp->ctx_mutex);
+ while (wait_for_completion_interruptible(&req->c)) {
+ mutex_lock(&supp->mutex);
interruptable = !supp->ctx;
if (interruptable) {
/*
* There's no supplicant available and since the
- * supp->ctx_mutex currently is held none can
+ * supp->mutex currently is held none can
* become available until the mutex released
* again.
*
@@ -101,24 +130,91 @@ u32 optee_supp_thrd_req(struct tee_context *ctx, u32 func, size_t num_params,
* will serve all requests in a timely manner and
* interrupting then wouldn't make sense.
*/
- supp->ret = TEEC_ERROR_COMMUNICATION;
- init_completion(&supp->data_to_supp);
+ interruptable = !req->busy;
+ if (!req->busy)
+ list_del(&req->link);
}
- mutex_unlock(&supp->ctx_mutex);
- if (interruptable)
+ mutex_unlock(&supp->mutex);
+
+ if (interruptable) {
+ req->ret = TEEC_ERROR_COMMUNICATION;
break;
+ }
}
- ret = supp->ret;
- supp->param = NULL;
- supp->req_posted = false;
-
- /* We're done, let someone else talk to the supplicant now. */
- mutex_unlock(&supp->thrd_mutex);
+ ret = req->ret;
+ kfree(req);
return ret;
}
+static struct optee_supp_req *supp_pop_entry(struct optee_supp *supp,
+ int num_params, int *id)
+{
+ struct optee_supp_req *req;
+
+ if (supp->req_id != -1) {
+ /*
+ * Supplicant should not mix synchronous and asnynchronous
+ * requests.
+ */
+ return ERR_PTR(-EINVAL);
+ }
+
+ if (list_empty(&supp->reqs))
+ return NULL;
+
+ req = list_first_entry(&supp->reqs, struct optee_supp_req, link);
+
+ if (num_params < req->num_params) {
+ /* Not enough room for parameters */
+ return ERR_PTR(-EINVAL);
+ }
+
+ *id = idr_alloc(&supp->idr, req, 1, 0, GFP_KERNEL);
+ if (*id < 0)
+ return ERR_PTR(-ENOMEM);
+
+ list_del(&req->link);
+ req->busy = true;
+
+ return req;
+}
+
+static int supp_check_recv_params(size_t num_params, struct tee_param *params,
+ size_t *num_meta)
+{
+ size_t n;
+
+ if (!num_params)
+ return -EINVAL;
+
+ /*
+ * If there's memrefs we need to decrease those as they where
+ * increased earlier and we'll even refuse to accept any below.
+ */
+ for (n = 0; n < num_params; n++)
+ if (tee_param_is_memref(params + n) && params[n].u.memref.shm)
+ tee_shm_put(params[n].u.memref.shm);
+
+ /*
+ * We only expect parameters as TEE_IOCTL_PARAM_ATTR_TYPE_NONE with
+ * or without the TEE_IOCTL_PARAM_ATTR_META bit set.
+ */
+ for (n = 0; n < num_params; n++)
+ if (params[n].attr &&
+ params[n].attr != TEE_IOCTL_PARAM_ATTR_META)
+ return -EINVAL;
+
+ /* At most we'll need one meta parameter so no need to check for more */
+ if (params->attr == TEE_IOCTL_PARAM_ATTR_META)
+ *num_meta = 1;
+ else
+ *num_meta = 0;
+
+ return 0;
+}
+
/**
* optee_supp_recv() - receive request for supplicant
* @ctx: context receiving the request
@@ -135,65 +231,99 @@ int optee_supp_recv(struct tee_context *ctx, u32 *func, u32 *num_params,
struct tee_device *teedev = ctx->teedev;
struct optee *optee = tee_get_drvdata(teedev);
struct optee_supp *supp = &optee->supp;
+ struct optee_supp_req *req = NULL;
+ int id;
+ size_t num_meta;
int rc;
- /*
- * In case two threads in one supplicant is calling this function
- * simultaneously we need to protect the data with a mutex which
- * we'll release before returning.
- */
- mutex_lock(&supp->supp_mutex);
+ rc = supp_check_recv_params(*num_params, param, &num_meta);
+ if (rc)
+ return rc;
+
+ while (true) {
+ mutex_lock(&supp->mutex);
+ req = supp_pop_entry(supp, *num_params - num_meta, &id);
+ mutex_unlock(&supp->mutex);
+
+ if (req) {
+ if (IS_ERR(req))
+ return PTR_ERR(req);
+ break;
+ }
- if (supp->supp_next_send) {
/*
- * optee_supp_recv() has been called again without
- * a optee_supp_send() in between. Supplicant has
- * probably been restarted before it was able to
- * write back last result. Abort last request and
- * wait for a new.
+ * If we didn't get a request we'll block in
+ * wait_for_completion() to avoid needless spinning.
+ *
+ * This is where supplicant will be hanging most of
+ * the time, let's make this interruptable so we
+ * can easily restart supplicant if needed.
*/
- if (supp->req_posted) {
- supp->ret = TEEC_ERROR_COMMUNICATION;
- supp->supp_next_send = false;
- complete(&supp->data_from_supp);
- }
+ if (wait_for_completion_interruptible(&supp->reqs_c))
+ return -ERESTARTSYS;
}
- /*
- * This is where supplicant will be hanging most of the
- * time, let's make this interruptable so we can easily
- * restart supplicant if needed.
- */
- if (wait_for_completion_interruptible(&supp->data_to_supp)) {
- rc = -ERESTARTSYS;
- goto out;
+ if (num_meta) {
+ /*
+ * tee-supplicant support meta parameters -> requsts can be
+ * processed asynchronously.
+ */
+ param->attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INOUT |
+ TEE_IOCTL_PARAM_ATTR_META;
+ param->u.value.a = id;
+ param->u.value.b = 0;
+ param->u.value.c = 0;
+ } else {
+ mutex_lock(&supp->mutex);
+ supp->req_id = id;
+ mutex_unlock(&supp->mutex);
}
- /* We have exlusive access to the data */
+ *func = req->func;
+ *num_params = req->num_params + num_meta;
+ memcpy(param + num_meta, req->param,
+ sizeof(struct tee_param) * req->num_params);
- if (*num_params < supp->num_params) {
- /*
- * Not enough room for parameters, tell supplicant
- * it failed and abort last request.
- */
- supp->ret = TEEC_ERROR_COMMUNICATION;
- rc = -EINVAL;
- complete(&supp->data_from_supp);
- goto out;
+ return 0;
+}
+
+static struct optee_supp_req *supp_pop_req(struct optee_supp *supp,
+ size_t num_params,
+ struct tee_param *param,
+ size_t *num_meta)
+{
+ struct optee_supp_req *req;
+ int id;
+ size_t nm;
+ const u32 attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INOUT |
+ TEE_IOCTL_PARAM_ATTR_META;
+
+ if (!num_params)
+ return ERR_PTR(-EINVAL);
+
+ if (supp->req_id == -1) {
+ if (param->attr != attr)
+ return ERR_PTR(-EINVAL);
+ id = param->u.value.a;
+ nm = 1;
+ } else {
+ id = supp->req_id;
+ nm = 0;
}
- *func = supp->func;
- *num_params = supp->num_params;
- memcpy(param, supp->param,
- sizeof(struct tee_param) * supp->num_params);
+ req = idr_find(&supp->idr, id);
+ if (!req)
+ return ERR_PTR(-ENOENT);
- /* Allow optee_supp_send() below to do its work */
- supp->supp_next_send = true;
+ if ((num_params - nm) != req->num_params)
+ return ERR_PTR(-EINVAL);
- rc = 0;
-out:
- mutex_unlock(&supp->supp_mutex);
- return rc;
+ req->busy = false;
+ idr_remove(&supp->idr, id);
+ supp->req_id = -1;
+ *num_meta = nm;
+
+ return req;
}
/**
@@ -211,63 +341,42 @@ int optee_supp_send(struct tee_context *ctx, u32 ret, u32 num_params,
struct tee_device *teedev = ctx->teedev;
struct optee *optee = tee_get_drvdata(teedev);
struct optee_supp *supp = &optee->supp;
+ struct optee_supp_req *req;
size_t n;
- int rc = 0;
+ size_t num_meta;
- /*
- * We still have exclusive access to the data since that's how we
- * left it when returning from optee_supp_read().
- */
-
- /* See comment on mutex in optee_supp_read() above */
- mutex_lock(&supp->supp_mutex);
-
- if (!supp->supp_next_send) {
- /*
- * Something strange is going on, supplicant shouldn't
- * enter optee_supp_send() in this state
- */
- rc = -ENOENT;
- goto out;
- }
+ mutex_lock(&supp->mutex);
+ req = supp_pop_req(supp, num_params, param, &num_meta);
+ mutex_unlock(&supp->mutex);
- if (num_params != supp->num_params) {
- /*
- * Something is wrong, let supplicant restart. Next call to
- * optee_supp_recv() will give an error to the requesting
- * thread and release it.
- */
- rc = -EINVAL;
- goto out;
+ if (IS_ERR(req)) {
+ /* Something is wrong, let supplicant restart. */
+ return PTR_ERR(req);
}
/* Update out and in/out parameters */
- for (n = 0; n < num_params; n++) {
- struct tee_param *p = supp->param + n;
+ for (n = 0; n < req->num_params; n++) {
+ struct tee_param *p = req->param + n;
- switch (p->attr) {
+ switch (p->attr & TEE_IOCTL_PARAM_ATTR_TYPE_MASK) {
case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT:
case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INOUT:
- p->u.value.a = param[n].u.value.a;
- p->u.value.b = param[n].u.value.b;
- p->u.value.c = param[n].u.value.c;
+ p->u.value.a = param[n + num_meta].u.value.a;
+ p->u.value.b = param[n + num_meta].u.value.b;
+ p->u.value.c = param[n + num_meta].u.value.c;
break;
case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT:
case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT:
- p->u.memref.size = param[n].u.memref.size;
+ p->u.memref.size = param[n + num_meta].u.memref.size;
break;
default:
break;
}
}
- supp->ret = ret;
-
- /* Allow optee_supp_recv() above to do its work */
- supp->supp_next_send = false;
+ req->ret = ret;
/* Let the requesting thread continue */
- complete(&supp->data_from_supp);
-out:
- mutex_unlock(&supp->supp_mutex);
- return rc;
+ complete(&req->c);
+
+ return 0;
}
diff --git a/drivers/tee/tee_core.c b/drivers/tee/tee_core.c
index a548c3695797..5bb93ca50399 100644
--- a/drivers/tee/tee_core.c
+++ b/drivers/tee/tee_core.c
@@ -38,15 +38,13 @@ static DEFINE_SPINLOCK(driver_lock);
static struct class *tee_class;
static dev_t tee_devt;
-static int tee_open(struct inode *inode, struct file *filp)
+static struct tee_context *teedev_open(struct tee_device *teedev)
{
int rc;
- struct tee_device *teedev;
struct tee_context *ctx;
- teedev = container_of(inode->i_cdev, struct tee_device, cdev);
if (!tee_device_get(teedev))
- return -EINVAL;
+ return ERR_PTR(-EINVAL);
ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
if (!ctx) {
@@ -56,22 +54,20 @@ static int tee_open(struct inode *inode, struct file *filp)
ctx->teedev = teedev;
INIT_LIST_HEAD(&ctx->list_shm);
- filp->private_data = ctx;
rc = teedev->desc->ops->open(ctx);
if (rc)
goto err;
- return 0;
+ return ctx;
err:
kfree(ctx);
tee_device_put(teedev);
- return rc;
+ return ERR_PTR(rc);
+
}
-static int tee_release(struct inode *inode, struct file *filp)
+static void teedev_close_context(struct tee_context *ctx)
{
- struct tee_context *ctx = filp->private_data;
- struct tee_device *teedev = ctx->teedev;
struct tee_shm *shm;
ctx->teedev->desc->ops->release(ctx);
@@ -79,8 +75,25 @@ static int tee_release(struct inode *inode, struct file *filp)
list_for_each_entry(shm, &ctx->list_shm, link)
shm->ctx = NULL;
mutex_unlock(&ctx->teedev->mutex);
+ tee_device_put(ctx->teedev);
kfree(ctx);
- tee_device_put(teedev);
+}
+
+static int tee_open(struct inode *inode, struct file *filp)
+{
+ struct tee_context *ctx;
+
+ ctx = teedev_open(container_of(inode->i_cdev, struct tee_device, cdev));
+ if (IS_ERR(ctx))
+ return PTR_ERR(ctx);
+
+ filp->private_data = ctx;
+ return 0;
+}
+
+static int tee_release(struct inode *inode, struct file *filp)
+{
+ teedev_close_context(filp->private_data);
return 0;
}
@@ -138,6 +151,42 @@ static int tee_ioctl_shm_alloc(struct tee_context *ctx,
return ret;
}
+static int tee_ioctl_shm_register_fd(struct tee_context *ctx,
+ struct tee_ioctl_shm_register_fd_data __user *udata)
+{
+ struct tee_ioctl_shm_register_fd_data data;
+ struct tee_shm *shm;
+ long ret;
+
+ if (copy_from_user(&data, udata, sizeof(data)))
+ return -EFAULT;
+
+ /* Currently no input flags are supported */
+ if (data.flags)
+ return -EINVAL;
+
+ shm = tee_shm_register_fd(ctx, data.fd);
+ if (IS_ERR_OR_NULL(shm))
+ return -EINVAL;
+
+ data.id = shm->id;
+ data.flags = shm->flags;
+ data.size = shm->size;
+
+ if (copy_to_user(udata, &data, sizeof(data)))
+ ret = -EFAULT;
+ else
+ ret = tee_shm_get_fd(shm);
+
+ /*
+ * When user space closes the file descriptor the shared memory
+ * should be freed or if tee_shm_get_fd() failed then it will
+ * be freed immediately.
+ */
+ tee_shm_put(shm);
+ return ret;
+}
+
static int params_from_user(struct tee_context *ctx, struct tee_param *params,
size_t num_params,
struct tee_ioctl_param __user *uparams)
@@ -152,11 +201,11 @@ static int params_from_user(struct tee_context *ctx, struct tee_param *params,
return -EFAULT;
/* All unused attribute bits has to be zero */
- if (ip.attr & ~TEE_IOCTL_PARAM_ATTR_TYPE_MASK)
+ if (ip.attr & ~TEE_IOCTL_PARAM_ATTR_MASK)
return -EINVAL;
params[n].attr = ip.attr;
- switch (ip.attr) {
+ switch (ip.attr & TEE_IOCTL_PARAM_ATTR_TYPE_MASK) {
case TEE_IOCTL_PARAM_ATTR_TYPE_NONE:
case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT:
break;
@@ -232,18 +281,6 @@ static int params_to_user(struct tee_ioctl_param __user *uparams,
return 0;
}
-static bool param_is_memref(struct tee_param *param)
-{
- switch (param->attr & TEE_IOCTL_PARAM_ATTR_TYPE_MASK) {
- case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT:
- case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT:
- case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT:
- return true;
- default:
- return false;
- }
-}
-
static int tee_ioctl_open_session(struct tee_context *ctx,
struct tee_ioctl_buf_data __user *ubuf)
{
@@ -307,7 +344,7 @@ out:
if (params) {
/* Decrease ref count for all valid shared memory pointers */
for (n = 0; n < arg.num_params; n++)
- if (param_is_memref(params + n) &&
+ if (tee_param_is_memref(params + n) &&
params[n].u.memref.shm)
tee_shm_put(params[n].u.memref.shm);
kfree(params);
@@ -369,7 +406,7 @@ out:
if (params) {
/* Decrease ref count for all valid shared memory pointers */
for (n = 0; n < arg.num_params; n++)
- if (param_is_memref(params + n) &&
+ if (tee_param_is_memref(params + n) &&
params[n].u.memref.shm)
tee_shm_put(params[n].u.memref.shm);
kfree(params);
@@ -417,8 +454,8 @@ static int params_to_supp(struct tee_context *ctx,
struct tee_ioctl_param ip;
struct tee_param *p = params + n;
- ip.attr = p->attr & TEE_IOCTL_PARAM_ATTR_TYPE_MASK;
- switch (p->attr) {
+ ip.attr = p->attr;
+ switch (p->attr & TEE_IOCTL_PARAM_ATTR_TYPE_MASK) {
case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT:
case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INOUT:
ip.a = p->u.value.a;
@@ -482,6 +519,10 @@ static int tee_ioctl_supp_recv(struct tee_context *ctx,
if (!params)
return -ENOMEM;
+ rc = params_from_user(ctx, params, num_params, uarg->params);
+ if (rc)
+ goto out;
+
rc = ctx->teedev->desc->ops->supp_recv(ctx, &func, &num_params, params);
if (rc)
goto out;
@@ -511,11 +552,11 @@ static int params_from_supp(struct tee_param *params, size_t num_params,
return -EFAULT;
/* All unused attribute bits has to be zero */
- if (ip.attr & ~TEE_IOCTL_PARAM_ATTR_TYPE_MASK)
+ if (ip.attr & ~TEE_IOCTL_PARAM_ATTR_MASK)
return -EINVAL;
p->attr = ip.attr;
- switch (ip.attr) {
+ switch (ip.attr & TEE_IOCTL_PARAM_ATTR_TYPE_MASK) {
case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT:
case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INOUT:
/* Only out and in/out values can be updated */
@@ -597,6 +638,8 @@ static long tee_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
return tee_ioctl_version(ctx, uarg);
case TEE_IOC_SHM_ALLOC:
return tee_ioctl_shm_alloc(ctx, uarg);
+ case TEE_IOC_SHM_REGISTER_FD:
+ return tee_ioctl_shm_register_fd(ctx, uarg);
case TEE_IOC_OPEN_SESSION:
return tee_ioctl_open_session(ctx, uarg);
case TEE_IOC_INVOKE:
@@ -873,6 +916,96 @@ void *tee_get_drvdata(struct tee_device *teedev)
}
EXPORT_SYMBOL_GPL(tee_get_drvdata);
+struct match_dev_data {
+ struct tee_ioctl_version_data *vers;
+ const void *data;
+ int (*match)(struct tee_ioctl_version_data *, const void *);
+};
+
+static int match_dev(struct device *dev, const void *data)
+{
+ const struct match_dev_data *match_data = data;
+ struct tee_device *teedev = container_of(dev, struct tee_device, dev);
+
+ teedev->desc->ops->get_version(teedev, match_data->vers);
+ return match_data->match(match_data->vers, match_data->data);
+}
+
+struct tee_context *tee_client_open_context(struct tee_context *start,
+ int (*match)(struct tee_ioctl_version_data *,
+ const void *),
+ const void *data, struct tee_ioctl_version_data *vers)
+{
+ struct device *dev = NULL;
+ struct device *put_dev = NULL;
+ struct tee_context *ctx = NULL;
+ struct tee_ioctl_version_data v;
+ struct match_dev_data match_data = { vers ? vers : &v, data, match };
+
+ if (start)
+ dev = &start->teedev->dev;
+
+ do {
+ dev = class_find_device(tee_class, dev, &match_data, match_dev);
+ if (!dev) {
+ ctx = ERR_PTR(-ENOENT);
+ break;
+ }
+
+ put_device(put_dev);
+ put_dev = dev;
+
+ ctx = teedev_open(container_of(dev, struct tee_device, dev));
+ } while (IS_ERR(ctx) && PTR_ERR(ctx) != -ENOMEM);
+
+ put_device(put_dev);
+ return ctx;
+}
+EXPORT_SYMBOL_GPL(tee_client_open_context);
+
+void tee_client_close_context(struct tee_context *ctx)
+{
+ teedev_close_context(ctx);
+}
+
+EXPORT_SYMBOL_GPL(tee_client_close_context);
+
+void tee_client_get_version(struct tee_context *ctx,
+ struct tee_ioctl_version_data *vers)
+{
+ ctx->teedev->desc->ops->get_version(ctx->teedev, vers);
+}
+EXPORT_SYMBOL_GPL(tee_client_get_version);
+
+
+int tee_client_open_session(struct tee_context *ctx,
+ struct tee_ioctl_open_session_arg *arg,
+ struct tee_param *param)
+{
+ if (!ctx->teedev->desc->ops->open_session)
+ return -EINVAL;
+ return ctx->teedev->desc->ops->open_session(ctx, arg, param);
+}
+EXPORT_SYMBOL_GPL(tee_client_open_session);
+
+int tee_client_close_session(struct tee_context *ctx, u32 session)
+{
+ if (!ctx->teedev->desc->ops->close_session)
+ return -EINVAL;
+ return ctx->teedev->desc->ops->close_session(ctx, session);
+}
+EXPORT_SYMBOL_GPL(tee_client_close_session);
+
+int tee_client_invoke_func(struct tee_context *ctx,
+ struct tee_ioctl_invoke_arg *arg,
+ struct tee_param *param)
+{
+ if (!ctx->teedev->desc->ops->invoke_func)
+ return -EINVAL;
+ return ctx->teedev->desc->ops->invoke_func(ctx, arg, param);
+}
+EXPORT_SYMBOL_GPL(tee_client_invoke_func);
+
static int __init tee_init(void)
{
int rc;
diff --git a/drivers/tee/tee_shm.c b/drivers/tee/tee_shm.c
index ea3ce4e17b85..8164a1d0617d 100644
--- a/drivers/tee/tee_shm.c
+++ b/drivers/tee/tee_shm.c
@@ -20,10 +20,17 @@
#include <linux/tee_drv.h>
#include "tee_private.h"
+/* extra references appended to shm object for registered shared memory */
+struct tee_shm_dmabuf_ref {
+ struct tee_shm shm;
+ struct dma_buf *dmabuf;
+ struct dma_buf_attachment *attach;
+ struct sg_table *sgt;
+};
+
static void tee_shm_release(struct tee_shm *shm)
{
struct tee_device *teedev = shm->teedev;
- struct tee_shm_pool_mgr *poolm;
mutex_lock(&teedev->mutex);
idr_remove(&teedev->idr, shm->id);
@@ -31,14 +38,26 @@ static void tee_shm_release(struct tee_shm *shm)
list_del(&shm->link);
mutex_unlock(&teedev->mutex);
- if (shm->flags & TEE_SHM_DMA_BUF)
- poolm = &teedev->pool->dma_buf_mgr;
- else
- poolm = &teedev->pool->private_mgr;
+ if (shm->flags & TEE_SHM_EXT_DMA_BUF) {
+ struct tee_shm_dmabuf_ref *ref;
- poolm->ops->free(poolm, shm);
- kfree(shm);
+ ref = container_of(shm, struct tee_shm_dmabuf_ref, shm);
+ dma_buf_unmap_attachment(ref->attach, ref->sgt,
+ DMA_BIDIRECTIONAL);
+ dma_buf_detach(shm->dmabuf, ref->attach);
+ dma_buf_put(ref->dmabuf);
+ } else {
+ struct tee_shm_pool_mgr *poolm;
+
+ if (shm->flags & TEE_SHM_DMA_BUF)
+ poolm = &teedev->pool->dma_buf_mgr;
+ else
+ poolm = &teedev->pool->private_mgr;
+
+ poolm->ops->free(poolm, shm);
+ }
+ kfree(shm);
tee_device_put(teedev);
}
@@ -190,6 +209,100 @@ err_dev_put:
}
EXPORT_SYMBOL_GPL(tee_shm_alloc);
+struct tee_shm *tee_shm_register_fd(struct tee_context *ctx, int fd)
+{
+ struct tee_shm_dmabuf_ref *ref;
+ void *rc;
+ DEFINE_DMA_BUF_EXPORT_INFO(exp_info);
+
+ if (!tee_device_get(ctx->teedev))
+ return ERR_PTR(-EINVAL);
+
+ ref = kzalloc(sizeof(*ref), GFP_KERNEL);
+ if (!ref) {
+ rc = ERR_PTR(-ENOMEM);
+ goto err;
+ }
+
+ ref->shm.ctx = ctx;
+ ref->shm.teedev = ctx->teedev;
+ ref->shm.id = -1;
+
+ ref->dmabuf = dma_buf_get(fd);
+ if (!ref->dmabuf) {
+ rc = ERR_PTR(-EINVAL);
+ goto err;
+ }
+
+ ref->attach = dma_buf_attach(ref->dmabuf, &ref->shm.teedev->dev);
+ if (IS_ERR_OR_NULL(ref->attach)) {
+ rc = ERR_PTR(-EINVAL);
+ goto err;
+ }
+
+ ref->sgt = dma_buf_map_attachment(ref->attach, DMA_BIDIRECTIONAL);
+ if (IS_ERR_OR_NULL(ref->sgt)) {
+ rc = ERR_PTR(-EINVAL);
+ goto err;
+ }
+
+ if (sg_nents(ref->sgt->sgl) != 1) {
+ rc = ERR_PTR(-EINVAL);
+ goto err;
+ }
+
+ ref->shm.paddr = sg_dma_address(ref->sgt->sgl);
+ ref->shm.size = sg_dma_len(ref->sgt->sgl);
+ ref->shm.flags = TEE_SHM_DMA_BUF | TEE_SHM_EXT_DMA_BUF;
+
+ mutex_lock(&ref->shm.teedev->mutex);
+ ref->shm.id = idr_alloc(&ref->shm.teedev->idr, &ref->shm,
+ 1, 0, GFP_KERNEL);
+ mutex_unlock(&ref->shm.teedev->mutex);
+ if (ref->shm.id < 0) {
+ rc = ERR_PTR(ref->shm.id);
+ goto err;
+ }
+
+ /* export a dmabuf to later get a userland ref */
+ exp_info.ops = &tee_shm_dma_buf_ops;
+ exp_info.size = ref->shm.size;
+ exp_info.flags = O_RDWR;
+ exp_info.priv = &ref->shm;
+
+ ref->shm.dmabuf = dma_buf_export(&exp_info);
+ if (IS_ERR(ref->shm.dmabuf)) {
+ rc = ERR_PTR(-EINVAL);
+ goto err;
+ }
+
+ mutex_lock(&ref->shm.teedev->mutex);
+ list_add_tail(&ref->shm.link, &ctx->list_shm);
+ mutex_unlock(&ref->shm.teedev->mutex);
+
+ return &ref->shm;
+
+err:
+ if (ref) {
+ if (ref->shm.id >= 0) {
+ mutex_lock(&ctx->teedev->mutex);
+ idr_remove(&ctx->teedev->idr, ref->shm.id);
+ mutex_unlock(&ctx->teedev->mutex);
+ }
+ if (ref->sgt)
+ dma_buf_unmap_attachment(ref->attach, ref->sgt,
+ DMA_BIDIRECTIONAL);
+ if (ref->attach)
+ dma_buf_detach(ref->dmabuf, ref->attach);
+ if (ref->dmabuf)
+ dma_buf_put(ref->dmabuf);
+ }
+ kfree(ref);
+ tee_device_put(ctx->teedev);
+ return rc;
+}
+EXPORT_SYMBOL_GPL(tee_shm_register_fd);
+
/**
* tee_shm_get_fd() - Increase reference count and return file descriptor
* @shm: Shared memory handle
@@ -197,10 +310,9 @@ EXPORT_SYMBOL_GPL(tee_shm_alloc);
*/
int tee_shm_get_fd(struct tee_shm *shm)
{
- u32 req_flags = TEE_SHM_MAPPED | TEE_SHM_DMA_BUF;
int fd;
- if ((shm->flags & req_flags) != req_flags)
+ if (!(shm->flags & TEE_SHM_DMA_BUF))
return -EINVAL;
get_dma_buf(shm->dmabuf);
@@ -239,6 +351,8 @@ EXPORT_SYMBOL_GPL(tee_shm_free);
*/
int tee_shm_va2pa(struct tee_shm *shm, void *va, phys_addr_t *pa)
{
+ if (!(shm->flags & TEE_SHM_MAPPED))
+ return -EINVAL;
/* Check that we're in the range of the shm */
if ((char *)va < (char *)shm->kaddr)
return -EINVAL;
@@ -259,6 +373,8 @@ EXPORT_SYMBOL_GPL(tee_shm_va2pa);
*/
int tee_shm_pa2va(struct tee_shm *shm, phys_addr_t pa, void **va)
{
+ if (!(shm->flags & TEE_SHM_MAPPED))
+ return -EINVAL;
/* Check that we're in the range of the shm */
if (pa < shm->paddr)
return -EINVAL;
@@ -285,6 +401,8 @@ EXPORT_SYMBOL_GPL(tee_shm_pa2va);
*/
void *tee_shm_get_va(struct tee_shm *shm, size_t offs)
{
+ if (!(shm->flags & TEE_SHM_MAPPED))
+ return ERR_PTR(-EINVAL);
if (offs >= shm->size)
return ERR_PTR(-EINVAL);
return (char *)shm->kaddr + offs;
diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig
index e3f0d1fd1720..2b8f3afb6bed 100644
--- a/drivers/thermal/Kconfig
+++ b/drivers/thermal/Kconfig
@@ -214,6 +214,35 @@ config IMX_THERMAL
cpufreq is used as the cooling device to throttle CPUs when the
passive trip is crossed.
+config IMX8M_THERMAL
+ tristate "i.MX8M Thermal Monitoring Unit"
+ depends on THERMAL_OF
+ depends on HAS_IOMEM
+ help
+ Support for Thermal Monitoring Unit (TMU) found on i.MX8M platforms.
+ It supports one critical trip point and one passive trip point. The
+ cpufreq is used as the cooling device to throttle CPUs when the
+ passive trip is crossed.
+
+config IMX8MM_THERMAL
+ tristate "i.MX8MM Thermal Monitor Unit"
+ depends on THERMAL_OF
+ depends on HAS_IOMEM
+ help
+ Support for Thermal Monitor Unit (TMU) found on i.MX8MM platforms.
+ It supports one critical trip point and one passive trip point. The
+ cpufreq is used as the cooling device to throttle CPUs when the
+ passive trip is crossed.
+
+config IMX_SC_THERMAL
+ tristate "thermal sensor driver for NXP i.MX8 SoCs"
+ depends on THERMAL_OF && ARCH_MXC_ARM64
+ help
+ Support for Temperature Monitor (TEMPMON) found on NXP i.MX SOCs
+ with system controller.
+ cpufreq is used as the cooling device to throttle CPUs when the
+ passive trip is crossed.
+
config MAX77620_THERMAL
tristate "Temperature sensor driver for Maxim MAX77620 PMIC"
depends on MFD_MAX77620
@@ -234,6 +263,13 @@ config QORIQ_THERMAL
cpufreq is used as the cooling device to throttle CPUs when the
passive trip is crossed.
+config DEVICE_THERMAL
+ tristate "generic device cooling support"
+ help
+ Support for device cooling.
+ It supports notification of crossing passive trip for devices,
+ devices need to do their own actions to cool down the SOC.
+
config SPEAR_THERMAL
tristate "SPEAr thermal sensor driver"
depends on PLAT_SPEAR || COMPILE_TEST
diff --git a/drivers/thermal/Makefile b/drivers/thermal/Makefile
index 195cd08fbc30..20086be7fe23 100644
--- a/drivers/thermal/Makefile
+++ b/drivers/thermal/Makefile
@@ -41,8 +41,12 @@ obj-$(CONFIG_DB8500_THERMAL) += db8500_thermal.o
obj-$(CONFIG_ARMADA_THERMAL) += armada_thermal.o
obj-$(CONFIG_TANGO_THERMAL) += tango_thermal.o
obj-$(CONFIG_IMX_THERMAL) += imx_thermal.o
+obj-$(CONFIG_IMX8M_THERMAL) += qoriq_thermal.o
+obj-$(CONFIG_IMX8MM_THERMAL) += imx8mm_thermal.o
+obj-$(CONFIG_IMX_SC_THERMAL) += imx_sc_thermal.o
obj-$(CONFIG_MAX77620_THERMAL) += max77620_thermal.o
obj-$(CONFIG_QORIQ_THERMAL) += qoriq_thermal.o
+obj-$(CONFIG_DEVICE_THERMAL) += device_cooling.o
obj-$(CONFIG_DA9062_THERMAL) += da9062-thermal.o
obj-$(CONFIG_INTEL_POWERCLAMP) += intel_powerclamp.o
obj-$(CONFIG_X86_PKG_TEMP_THERMAL) += x86_pkg_temp_thermal.o
diff --git a/drivers/thermal/device_cooling.c b/drivers/thermal/device_cooling.c
new file mode 100644
index 000000000000..844b074a2532
--- /dev/null
+++ b/drivers/thermal/device_cooling.c
@@ -0,0 +1,151 @@
+/*
+ * Copyright (C) 2013-2015 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/module.h>
+#include <linux/thermal.h>
+#include <linux/err.h>
+#include <linux/slab.h>
+
+struct devfreq_cooling_device {
+ int id;
+ struct thermal_cooling_device *cool_dev;
+ unsigned int devfreq_state;
+};
+
+static DEFINE_IDR(devfreq_idr);
+static DEFINE_MUTEX(devfreq_cooling_lock);
+
+#define MAX_STATE 1
+
+static BLOCKING_NOTIFIER_HEAD(devfreq_cooling_chain_head);
+
+int register_devfreq_cooling_notifier(struct notifier_block *nb)
+{
+ return blocking_notifier_chain_register(
+ &devfreq_cooling_chain_head, nb);
+}
+EXPORT_SYMBOL_GPL(register_devfreq_cooling_notifier);
+
+int unregister_devfreq_cooling_notifier(struct notifier_block *nb)
+{
+ return blocking_notifier_chain_unregister(
+ &devfreq_cooling_chain_head, nb);
+}
+EXPORT_SYMBOL_GPL(unregister_devfreq_cooling_notifier);
+
+static int devfreq_cooling_notifier_call_chain(unsigned long val)
+{
+ return (blocking_notifier_call_chain(
+ &devfreq_cooling_chain_head, val, NULL)
+ == NOTIFY_BAD) ? -EINVAL : 0;
+}
+
+static int devfreq_set_cur_state(struct thermal_cooling_device *cdev,
+ unsigned long state)
+{
+ struct devfreq_cooling_device *devfreq_device = cdev->devdata;
+ int ret;
+
+ ret = devfreq_cooling_notifier_call_chain(state);
+ if (ret)
+ return -EINVAL;
+ devfreq_device->devfreq_state = state;
+
+ return 0;
+}
+
+static int devfreq_get_max_state(struct thermal_cooling_device *cdev,
+ unsigned long *state)
+{
+ *state = MAX_STATE;
+
+ return 0;
+}
+
+static int devfreq_get_cur_state(struct thermal_cooling_device *cdev,
+ unsigned long *state)
+{
+ struct devfreq_cooling_device *devfreq_device = cdev->devdata;
+
+ *state = devfreq_device->devfreq_state;
+
+ return 0;
+}
+
+static struct thermal_cooling_device_ops const devfreq_cooling_ops = {
+ .get_max_state = devfreq_get_max_state,
+ .get_cur_state = devfreq_get_cur_state,
+ .set_cur_state = devfreq_set_cur_state,
+};
+
+static int get_idr(struct idr *idr, int *id)
+{
+ int ret;
+
+ mutex_lock(&devfreq_cooling_lock);
+ ret = idr_alloc(idr, NULL, 0, 0, GFP_KERNEL);
+ mutex_unlock(&devfreq_cooling_lock);
+ if (unlikely(ret < 0))
+ return ret;
+ *id = ret;
+
+ return 0;
+}
+
+static void release_idr(struct idr *idr, int id)
+{
+ mutex_lock(&devfreq_cooling_lock);
+ idr_remove(idr, id);
+ mutex_unlock(&devfreq_cooling_lock);
+}
+
+struct thermal_cooling_device *devfreq_cooling_register(void)
+{
+ struct thermal_cooling_device *cool_dev;
+ struct devfreq_cooling_device *devfreq_dev = NULL;
+ char dev_name[THERMAL_NAME_LENGTH];
+ int ret = 0;
+
+ devfreq_dev = kzalloc(sizeof(struct devfreq_cooling_device),
+ GFP_KERNEL);
+ if (!devfreq_dev)
+ return ERR_PTR(-ENOMEM);
+
+ ret = get_idr(&devfreq_idr, &devfreq_dev->id);
+ if (ret) {
+ kfree(devfreq_dev);
+ return ERR_PTR(-EINVAL);
+ }
+
+ snprintf(dev_name, sizeof(dev_name), "thermal-devfreq-%d",
+ devfreq_dev->id);
+
+ cool_dev = thermal_cooling_device_register(dev_name, devfreq_dev,
+ &devfreq_cooling_ops);
+ if (!cool_dev) {
+ release_idr(&devfreq_idr, devfreq_dev->id);
+ kfree(devfreq_dev);
+ return ERR_PTR(-EINVAL);
+ }
+ devfreq_dev->cool_dev = cool_dev;
+ devfreq_dev->devfreq_state = 0;
+
+ return cool_dev;
+}
+EXPORT_SYMBOL_GPL(devfreq_cooling_register);
+
+void devfreq_cooling_unregister(struct thermal_cooling_device *cdev)
+{
+ struct devfreq_cooling_device *devfreq_dev = cdev->devdata;
+
+ thermal_cooling_device_unregister(devfreq_dev->cool_dev);
+ release_idr(&devfreq_idr, devfreq_dev->id);
+ kfree(devfreq_dev);
+}
+EXPORT_SYMBOL_GPL(devfreq_cooling_unregister);
diff --git a/drivers/thermal/imx8mm_thermal.c b/drivers/thermal/imx8mm_thermal.c
new file mode 100644
index 000000000000..a6ce9f36168f
--- /dev/null
+++ b/drivers/thermal/imx8mm_thermal.c
@@ -0,0 +1,240 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2018 NXP.
+ *
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/device_cooling.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include <linux/thermal.h>
+
+#include "thermal_core.h"
+
+#define TER 0x0 /* TMU enable */
+#define TSR 0x4 /* TMU status */
+#define TIER 0x8 /* TMU interrupt enable */
+#define TIDR 0xc /* TMU interrupt detect */
+#define TMHTITR 0x10 /* TMU high immediate threshold */
+#define TMHTATR 0x14 /* TMU high average threshold */
+#define TMHTCATR 0x18 /* TMU high average critical threshold */
+#define TSCR 0x1c /* TMU sensor val(raw, no calibration) */
+#define TRITSR 0x20 /* TMU immediate temp */
+#define TRATSR 0x24 /* TMU average temp */
+
+#define TER_EN BIT(31)
+#define TRITSR_VALID BIT(31)
+#define TEMP_VAL_MASK 0xff
+
+#define TEMP_LOW_LIMIT 10
+
+#define IMX_TEMP_PASSIVE_COOL_DELTA 10000
+
+struct imx8mm_tmu {
+ struct thermal_zone_device *tzd;
+ struct thermal_cooling_device *cdev;
+ struct clk *clk;
+ void __iomem *tmu_base;
+ bool enabled;
+ int temp_passive;
+ int temp_critical;
+};
+
+/* The driver support 1 passive trip point and 1 critical trip point */
+enum imx_thermal_trip {
+ IMX_TRIP_PASSIVE,
+ IMX_TRIP_CRITICAL,
+ IMX_TRIP_NUM,
+};
+
+static int tmu_get_temp(void *data, int *temp)
+{
+ struct imx8mm_tmu *tmu = data;
+ u32 val;
+
+ /* the temp sensor need about 1ms to finish the measurement */
+ msleep(1);
+
+ /* read the calibrated temp value */
+ val = readl_relaxed(tmu->tmu_base + TRITSR) & TEMP_VAL_MASK;
+
+ /* check if the temp in the sensor's range */
+ if (val < TEMP_LOW_LIMIT)
+ return -EAGAIN;
+
+ *temp = val * 1000;
+
+ return 0;
+}
+
+static int tmu_get_trend(void *p, int trip, enum thermal_trend *trend)
+{
+ int trip_temp;
+ struct imx8mm_tmu *tmu = p;
+
+ if (!tmu->tzd)
+ return 0;
+
+ trip_temp = (trip == IMX_TRIP_PASSIVE) ? tmu->temp_passive : tmu->temp_critical;
+
+ if (tmu->tzd->temperature >= (trip_temp - IMX_TEMP_PASSIVE_COOL_DELTA))
+ *trend = THERMAL_TREND_RAISE_FULL;
+ else
+ *trend = THERMAL_TREND_DROP_FULL;
+
+ return 0;
+}
+
+static int tmu_set_trip_temp(void *p, int trip, int temp)
+{
+ struct imx8mm_tmu *tmu = p;
+
+ if (trip == IMX_TRIP_CRITICAL)
+ tmu->temp_critical = temp;
+
+ if (trip == IMX_TRIP_PASSIVE)
+ tmu->temp_passive = temp;
+
+ return 0;
+}
+
+static struct thermal_zone_of_device_ops tmu_tz_ops = {
+ .get_temp = tmu_get_temp,
+ .get_trend = tmu_get_trend,
+ .set_trip_temp = tmu_set_trip_temp,
+};
+
+static const struct of_device_id imx8mm_tmu_table[] = {
+ { .compatible = "fsl,imx8mm-tmu", },
+ { },
+};
+
+static int imx8mm_tmu_probe(struct platform_device *pdev)
+{
+ int ret;
+ u32 val;
+ struct imx8mm_tmu *tmu;
+ const struct thermal_trip *trips;
+ struct device_node *np = pdev->dev.of_node;
+
+ if (!np) {
+ dev_err(&pdev->dev, "device node NOT found\n");
+ return -ENODEV;
+ }
+
+ tmu = devm_kzalloc(&pdev->dev, sizeof(*tmu), GFP_KERNEL);
+ if (!tmu)
+ return -ENOMEM;
+
+ platform_set_drvdata(pdev, tmu);
+
+ tmu->tmu_base = of_iomap(np, 0);
+ if (!tmu->tmu_base) {
+ dev_err(&pdev->dev, "Failed to map the memory\n");
+ return -ENODEV;
+ }
+
+ tmu->clk = devm_clk_get(&pdev->dev, NULL);
+ if (IS_ERR(tmu->clk)) {
+ ret = PTR_ERR(tmu->clk);
+ dev_err(&pdev->dev, "Failed to get the tmu clk\n");
+ goto err;
+ }
+
+ /* register the thermal zone sensor */
+ tmu->tzd = devm_thermal_zone_of_sensor_register(&pdev->dev, 0, tmu, &tmu_tz_ops);
+
+ if (IS_ERR(tmu->tzd)) {
+ ret = PTR_ERR(tmu->tzd);
+ dev_err(&pdev->dev, "Failed to register thermal zone sensor %d\n", ret);
+ goto err;
+ }
+
+ tmu->cdev = devfreq_cooling_register();
+ if (IS_ERR(tmu->cdev)) {
+ ret = PTR_ERR(tmu->cdev);
+ if (ret != -EPROBE_DEFER)
+ dev_err(&pdev->dev, "failed to register devfreq cooling device %d\n", ret);
+ goto err;
+ }
+
+ ret = thermal_zone_bind_cooling_device(tmu->tzd,
+ IMX_TRIP_PASSIVE,
+ tmu->cdev,
+ THERMAL_NO_LIMIT,
+ THERMAL_NO_LIMIT,
+ THERMAL_WEIGHT_DEFAULT);
+ if (ret) {
+ dev_err(&pdev->dev,
+ "binding zone %s with cdev %s failed:%d\n",
+ tmu->tzd->type, tmu->cdev->type, ret);
+ devfreq_cooling_unregister(tmu->cdev);
+ goto err;
+ }
+
+ trips = of_thermal_get_trip_points(tmu->tzd);
+
+ /* get the thermal trip temp */
+ tmu->temp_passive = trips[0].temperature;
+ tmu->temp_critical = trips[1].temperature;
+
+ /* enable the tmu clock */
+ ret = clk_prepare_enable(tmu->clk);
+ if (ret) {
+ dev_warn(&pdev->dev, "tmu clock enable failed:%d\n", ret);
+ thermal_zone_unbind_cooling_device(tmu->tzd, IMX_TRIP_PASSIVE, tmu->cdev);
+ devfreq_cooling_unregister(tmu->cdev);
+ goto err;
+ }
+
+ /* enable the monitor */
+ val = readl_relaxed(tmu->tmu_base + TER);
+ val |= TER_EN;
+ writel_relaxed(val, tmu->tmu_base + TER);
+
+ return 0;
+err:
+ iounmap(tmu->tmu_base);
+ return ret;
+}
+
+static int imx8mm_tmu_remove(struct platform_device *pdev)
+{
+ u32 val;
+ struct imx8mm_tmu *tmu = platform_get_drvdata(pdev);
+
+ thermal_zone_unbind_cooling_device(tmu->tzd, IMX_TRIP_PASSIVE, tmu->cdev);
+ devfreq_cooling_unregister(tmu->cdev);
+
+ /* disable TMU */
+ val = readl_relaxed(tmu->tmu_base + TER);
+ val &= ~TER_EN;
+ writel_relaxed(val, tmu->tmu_base + TER);
+
+ /* disable TMU clk */
+ clk_disable_unprepare(tmu->clk);
+
+ iounmap(tmu->tmu_base);
+
+ return 0;
+}
+
+static struct platform_driver imx8mm_tmu = {
+ .driver = {
+ .name = "i.mx8mm_thermal",
+ .of_match_table = imx8mm_tmu_table,
+ },
+ .probe = imx8mm_tmu_probe,
+ .remove = imx8mm_tmu_remove,
+};
+module_platform_driver(imx8mm_tmu);
+
+MODULE_AUTHOR("Jacky Bai <ping.bai@nxp.com>");
+MODULE_DESCRIPTION("i.MX8MM Thermal Monitor Unit driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/thermal/imx_sc_thermal.c b/drivers/thermal/imx_sc_thermal.c
new file mode 100644
index 000000000000..8c5049020cd8
--- /dev/null
+++ b/drivers/thermal/imx_sc_thermal.c
@@ -0,0 +1,242 @@
+/*
+ * Copyright 2017-2018 NXP.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/err.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/device_cooling.h>
+#include <linux/platform_device.h>
+#include <linux/pm.h>
+#include <linux/slab.h>
+#include <linux/thermal.h>
+#include <soc/imx8/sc/sci.h>
+
+#include "thermal_core.h"
+
+#define IMX_SC_TEMP_PASSIVE_COOL_DELTA 10000
+
+struct imx_sc_sensor {
+ struct thermal_zone_device *tzd;
+ struct thermal_cooling_device *cdev;
+ sc_rsrc_t hw_id;
+ int temp_passive;
+ int temp_critical;
+};
+
+struct imx_sc_tsens_device {
+ u32 sensor_num;
+ struct imx_sc_sensor sensor[0];
+};
+
+/* The driver support 1 passive trip point and 1 critical trip point */
+enum imx_thermal_trip {
+ IMX_TRIP_PASSIVE,
+ IMX_TRIP_CRITICAL,
+ IMX_TRIP_NUM,
+};
+
+static const sc_rsrc_t imx8qm_sensor_hw_id[] = {
+ SC_R_A53, SC_R_A72, SC_R_GPU_0_PID0, SC_R_GPU_1_PID0,
+ SC_R_DRC_0, SC_R_PMIC_0, SC_R_PMIC_1, SC_R_PMIC_2,
+};
+
+static const sc_rsrc_t imx8qxp_sensor_hw_id[] = {
+ SC_R_SYSTEM, SC_R_DRC_0, SC_R_PMIC_0,
+ SC_R_PMIC_1, SC_R_PMIC_2,
+};
+
+const int *sensor_hw_id;
+sc_ipc_t tsens_ipcHandle;
+
+static int imx_sc_tsens_get_temp(void *data, int *temp)
+{
+ struct imx_sc_sensor *sensor = data;
+ sc_err_t sciErr;
+ int16_t celsius;
+ int8_t tenths;
+
+ sciErr = sc_misc_get_temp(tsens_ipcHandle, sensor->hw_id,
+ SC_C_TEMP, &celsius, &tenths);
+ /*
+ * if the SS power domain is down, read temp will fail, so
+ * we can return the temp of CPU domain instead.
+ */
+ if (sciErr != SC_ERR_NONE) {
+ sciErr = sc_misc_get_temp(tsens_ipcHandle,
+ sensor_hw_id[topology_physical_package_id(smp_processor_id())],
+ SC_C_TEMP, &celsius, &tenths);
+ if (sciErr != SC_ERR_NONE) {
+ pr_err("read temp sensor:%d failed\n", sensor->hw_id);
+ return -EINVAL;
+ }
+ }
+ *temp = celsius * 1000 + tenths * 100;
+
+ return 0;
+}
+
+static int imx_sc_tsens_get_trend(void *p, int trip, enum thermal_trend *trend)
+{
+ int trip_temp;
+ struct imx_sc_sensor *sensor = p;
+
+ if (!sensor->tzd)
+ return 0;
+
+ trip_temp = (trip == IMX_TRIP_PASSIVE) ? sensor->temp_passive :
+ sensor->temp_critical;
+
+ if (sensor->tzd->temperature >=
+ (trip_temp - IMX_SC_TEMP_PASSIVE_COOL_DELTA))
+ *trend = THERMAL_TREND_RAISE_FULL;
+ else
+ *trend = THERMAL_TREND_DROP_FULL;
+
+ return 0;
+}
+
+static int imx_sc_set_trip_temp(void *p, int trip,
+ int temp)
+{
+ struct imx_sc_sensor *sensor = p;
+
+ if (trip == IMX_TRIP_CRITICAL)
+ sensor->temp_critical = temp;
+
+ if (trip == IMX_TRIP_PASSIVE)
+ sensor->temp_passive = temp;
+
+ return 0;
+}
+
+static const struct thermal_zone_of_device_ops imx_sc_tsens_ops = {
+ .get_temp = imx_sc_tsens_get_temp,
+ .get_trend = imx_sc_tsens_get_trend,
+ .set_trip_temp = imx_sc_set_trip_temp,
+};
+
+static const struct of_device_id imx_sc_tsens_table[] = {
+ { .compatible = "nxp,imx8qm-sc-tsens", .data = &imx8qm_sensor_hw_id, },
+ { .compatible = "nxp,imx8qxp-sc-tsens", .data = &imx8qxp_sensor_hw_id, },
+ {},
+};
+
+MODULE_DEVICE_TABLE(of, imx_sc_tsens_table);
+
+static int imx_sc_tsens_probe(struct platform_device *pdev)
+{
+ struct device_node *tz_np, *child_tz_np = NULL;
+ struct device_node *np = pdev->dev.of_node;
+ struct imx_sc_tsens_device *tsens_dev;
+ struct imx_sc_sensor *sensor;
+ const struct thermal_trip *trip;
+ struct thermal_zone_device *tzd;
+ sc_err_t sciErr;
+ uint32_t mu_id;
+ u32 tsens_num;
+ int ret, sensor_id;
+
+ sciErr = sc_ipc_getMuID(&mu_id);
+ if (sciErr != SC_ERR_NONE) {
+ dev_err(&pdev->dev, "Can not get the mu id: %d\n", sciErr);
+ return -ENODEV;
+ };
+
+ sciErr = sc_ipc_open(&tsens_ipcHandle, mu_id);
+ if (sciErr != SC_ERR_NONE) {
+ dev_err(&pdev->dev, "open mu channel failed: %d\n", sciErr);
+ return -EINVAL;
+ };
+ sensor_hw_id = of_device_get_match_data(&pdev->dev);
+
+ /* get the temp sensor number from device node */
+ of_property_read_u32(np, "tsens-num", &tsens_num);
+ if (!tsens_num) {
+ dev_err(&pdev->dev, "no temp sensor number provided!\n");
+ return -EINVAL;
+ }
+
+ tsens_dev = devm_kzalloc(&pdev->dev, sizeof(*tsens_dev) +
+ tsens_num * sizeof(*sensor), GFP_KERNEL);
+ if (!tsens_dev)
+ return -ENOMEM;
+
+ tsens_dev->sensor_num = tsens_num;
+
+ tz_np = of_find_node_by_name(NULL, "thermal-zones");
+ if (!tz_np)
+ return -ENODEV;
+
+ for (sensor_id = 0; sensor_id < tsens_num; sensor_id++) {
+ child_tz_np = of_get_next_child(tz_np, child_tz_np);
+ if (!of_device_is_available(child_tz_np))
+ continue;
+
+ sensor = &tsens_dev->sensor[sensor_id];
+ sensor->hw_id = sensor_hw_id[sensor_id];
+ tzd = devm_thermal_zone_of_sensor_register(&pdev->dev, sensor_id, sensor,
+ &imx_sc_tsens_ops);
+ if (IS_ERR(tzd)) {
+ dev_err(&pdev->dev, "failed to register temp sensor: %d\n", sensor_id);
+ ret = -EINVAL;
+ goto failed;
+ }
+ sensor->tzd = tzd;
+ trip = of_thermal_get_trip_points(sensor->tzd);
+ sensor->temp_passive = trip[0].temperature;
+ sensor->temp_critical = trip[1].temperature;
+
+ sensor->cdev = devfreq_cooling_register();
+ if (IS_ERR(sensor->cdev)) {
+ dev_err(&pdev->dev,
+ "failed to register devfreq cooling device: %d\n",
+ ret);
+ goto failed;
+ }
+
+ ret = thermal_zone_bind_cooling_device(sensor->tzd,
+ IMX_TRIP_PASSIVE,
+ sensor->cdev,
+ THERMAL_NO_LIMIT,
+ THERMAL_NO_LIMIT,
+ THERMAL_WEIGHT_DEFAULT);
+ if (ret) {
+ dev_err(&sensor->tzd->device,
+ "binding zone %s with cdev %s failed:%d\n",
+ sensor->tzd->type, sensor->cdev->type, ret);
+ devfreq_cooling_unregister(sensor->cdev);
+ goto failed;
+ }
+ }
+
+ return 0;
+failed:
+ return ret;
+}
+
+static int imx_sc_tsens_remove(struct platform_device *pdev)
+{
+ return 0;
+}
+
+static struct platform_driver imx_sc_tsens_driver = {
+ .probe = imx_sc_tsens_probe,
+ .remove = imx_sc_tsens_remove,
+ .driver = {
+ .name = "imx-sc-thermal",
+ .of_match_table = imx_sc_tsens_table,
+ },
+};
+
+module_platform_driver(imx_sc_tsens_driver);
+
+MODULE_AUTHOR("Jacky Bai<ping.bai@nxp.com");
+MODULE_DESCRIPTION("Thermal driver for NXP i.MX SoCs with system controller");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/thermal/imx_thermal.c b/drivers/thermal/imx_thermal.c
index 41c6154ae856..deb2d16f893f 100644
--- a/drivers/thermal/imx_thermal.c
+++ b/drivers/thermal/imx_thermal.c
@@ -1,17 +1,19 @@
/*
- * Copyright 2013 Freescale Semiconductor, Inc.
+ * Copyright 2013-2016 Freescale Semiconductor, Inc.
+ * Copyright 2017 NXP.
*
* 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/busfreq-imx.h>
#include <linux/clk.h>
#include <linux/cpufreq.h>
#include <linux/cpu_cooling.h>
#include <linux/delay.h>
#include <linux/device.h>
+#include <linux/device_cooling.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/io.h>
@@ -38,17 +40,20 @@
#define MISC1_IRQ_TEMPLOW (1 << 28)
#define MISC1_IRQ_TEMPPANIC (1 << 27)
-#define TEMPSENSE0 0x0180
-#define TEMPSENSE0_ALARM_VALUE_SHIFT 20
-#define TEMPSENSE0_ALARM_VALUE_MASK (0xfff << TEMPSENSE0_ALARM_VALUE_SHIFT)
-#define TEMPSENSE0_TEMP_CNT_SHIFT 8
-#define TEMPSENSE0_TEMP_CNT_MASK (0xfff << TEMPSENSE0_TEMP_CNT_SHIFT)
-#define TEMPSENSE0_FINISHED (1 << 2)
-#define TEMPSENSE0_MEASURE_TEMP (1 << 1)
-#define TEMPSENSE0_POWER_DOWN (1 << 0)
-
-#define TEMPSENSE1 0x0190
-#define TEMPSENSE1_MEASURE_FREQ 0xffff
+/* i.MX6 specific */
+#define IMX6_TEMPSENSE0 0X180
+#define IMX6_TEMPSENSE0_ALARM_VALUE_SHIFT 20
+#define IMX6_TEMPSENSE0_ALARM_VALUE_MASK (0xfff << 20)
+#define IMX6_TEMPSENSE0_TEMP_CNT_SHIFT 8
+#define IMX6_TEMPSENSE0_TEMP_CNT_MASK (0xfff << 8)
+#define IMX6_TEMPSENSE0_FINISHED (1 << 2)
+#define IMX6_TEMPSENSE0_MEASURE_TEMP (1 << 1)
+#define IMX6_TEMPSENSE0_POWER_DOWN (1 << 0)
+
+#define IMX6_TEMPSENSE1 0X190
+#define IMX6_TEMPSENSE1_MEASURE_FREQ 0xffff
+#define IMX6_TEMPSENSE1_MEASURE_FREQ_SHIFT 0
+
/* Below TEMPSENSE2 is only for TEMPMON_IMX6SX */
#define TEMPSENSE2 0x0290
#define TEMPSENSE2_LOW_VALUE_SHIFT 0
@@ -59,6 +64,29 @@
#define OCOTP_MEM0 0x0480
#define OCOTP_ANA1 0x04e0
+/* i.MX7D specific */
+#define IMX7_ANADIG_DIGPROG 0x800
+#define IMX7_TEMPSENSE0 0X300
+#define IMX7_TEMPSENSE0_PANIC_ALARM_SHIFT 18
+#define IMX7_TEMPSENSE0_PANIC_ALARM_MASK (0x1ff << 18)
+#define IMX7_TEMPSENSE0_HIGH_ALARM_SHIFT 9
+#define IMX7_TEMPSENSE0_HIGH_ALARM_MASK (0x1ff << 9)
+#define IMX7_TEMPSENSE0_LOW_ALARM_SHIFT 0
+#define IMX7_TEMPSENSE0_LOW_ALARM_MASK 0x1ff
+
+#define IMX7_TEMPSENSE1 0X310
+#define IMX7_TEMPSENSE1_MEASURE_FREQ_SHIFT 16
+#define IMX7_TEMPSENSE1_MEASURE_FREQ_MASK (0xffff << 16)
+#define IMX7_TEMPSENSE1_FINISHED (1 << 11)
+#define IMX7_TEMPSENSE1_MEASURE_TEMP (1 << 10)
+#define IMX7_TEMPSENSE1_POWER_DOWN (1 << 9)
+#define IMX7_TEMPSENSE1_TEMP_VALUE_SHIFT 0
+#define IMX7_TEMPSENSE1_TEMP_VALUE_MASK 0x1ff
+
+#define IMX6_OCOTP_ANA1 0x04e0
+#define IMX7_OCOTP_ANA1 0x04f0
+#define IMX7_OCOTP_TESTER3 0x0440
+
/* The driver supports 1 passive trip point and 1 critical trip point */
enum imx_thermal_trip {
IMX_TRIP_PASSIVE,
@@ -66,32 +94,134 @@ enum imx_thermal_trip {
IMX_TRIP_NUM,
};
+#define IMX_TEMP_PASSIVE_COOL_DELTA 10000
+
#define IMX_POLLING_DELAY 2000 /* millisecond */
#define IMX_PASSIVE_DELAY 1000
#define FACTOR0 10000000
-#define FACTOR1 15976
-#define FACTOR2 4297157
+#define FACTOR1 15423
+#define FACTOR2 4148468
+#define OFFSET 3580661
#define TEMPMON_IMX6Q 1
#define TEMPMON_IMX6SX 2
+#define TEMPMON_IMX7 3
+
+/* the register offsets and bitfields may change across
+ * i.MX SOCs, use below struct as a description of the
+ * register.
+ */
struct thermal_soc_data {
+ u32 sensor_ctrl; /* tempmon sensor basic control */
+ u32 power_down_mask;
+ u32 measure_temp_mask;
+
+ u32 measure_freq_ctrl;
+ u32 measure_freq_mask;
+ u32 measure_freq_shift;
+
+ u32 temp_data;
+ u32 temp_value_mask;
+ u32 temp_value_shift;
+ u32 temp_valid_mask;
+
+ u32 panic_alarm_ctrl;
+ u32 panic_alarm_mask;
+ u32 panic_alarm_shift;
+
+ u32 high_alarm_ctrl;
+ u32 high_alarm_mask;
+ u32 high_alarm_shift;
+
+ u32 low_alarm_ctrl;
+ u32 low_alarm_mask;
+ u32 low_alarm_shift;
+
u32 version;
};
static struct thermal_soc_data thermal_imx6q_data = {
.version = TEMPMON_IMX6Q,
+
+ .sensor_ctrl = IMX6_TEMPSENSE0,
+ .power_down_mask = IMX6_TEMPSENSE0_POWER_DOWN,
+ .measure_temp_mask = IMX6_TEMPSENSE0_MEASURE_TEMP,
+
+ .measure_freq_ctrl = IMX6_TEMPSENSE1,
+ .measure_freq_shift = IMX6_TEMPSENSE1_MEASURE_FREQ_SHIFT,
+ .measure_freq_mask = IMX6_TEMPSENSE1_MEASURE_FREQ,
+
+ .temp_data = IMX6_TEMPSENSE0,
+ .temp_value_mask = IMX6_TEMPSENSE0_TEMP_CNT_MASK,
+ .temp_value_shift = IMX6_TEMPSENSE0_TEMP_CNT_SHIFT,
+ .temp_valid_mask = IMX6_TEMPSENSE0_FINISHED,
+
+ .high_alarm_ctrl = IMX6_TEMPSENSE0,
+ .high_alarm_mask = IMX6_TEMPSENSE0_ALARM_VALUE_MASK,
+ .high_alarm_shift = IMX6_TEMPSENSE0_ALARM_VALUE_SHIFT,
};
static struct thermal_soc_data thermal_imx6sx_data = {
.version = TEMPMON_IMX6SX,
+
+ .sensor_ctrl = IMX6_TEMPSENSE0,
+ .power_down_mask = IMX6_TEMPSENSE0_POWER_DOWN,
+ .measure_temp_mask = IMX6_TEMPSENSE0_MEASURE_TEMP,
+
+ .measure_freq_ctrl = IMX6_TEMPSENSE1,
+ .measure_freq_shift = IMX6_TEMPSENSE1_MEASURE_FREQ_SHIFT,
+ .measure_freq_mask = IMX6_TEMPSENSE1_MEASURE_FREQ,
+
+ .temp_data = IMX6_TEMPSENSE0,
+ .temp_value_mask = IMX6_TEMPSENSE0_TEMP_CNT_MASK,
+ .temp_value_shift = IMX6_TEMPSENSE0_TEMP_CNT_SHIFT,
+ .temp_valid_mask = IMX6_TEMPSENSE0_FINISHED,
+
+ .high_alarm_ctrl = IMX6_TEMPSENSE0,
+ .high_alarm_mask = IMX6_TEMPSENSE0_ALARM_VALUE_MASK,
+ .high_alarm_shift = IMX6_TEMPSENSE0_ALARM_VALUE_SHIFT,
+
+ .panic_alarm_ctrl = TEMPSENSE2,
+ .panic_alarm_mask = TEMPSENSE2_PANIC_VALUE_MASK,
+ .panic_alarm_shift = TEMPSENSE2_PANIC_VALUE_SHIFT,
+};
+
+static struct thermal_soc_data thermal_imx7d_data = {
+ .version = TEMPMON_IMX7,
+
+ .sensor_ctrl = IMX7_TEMPSENSE1,
+ .power_down_mask = IMX7_TEMPSENSE1_POWER_DOWN,
+ .measure_temp_mask = IMX7_TEMPSENSE1_MEASURE_TEMP,
+
+ .measure_freq_ctrl = IMX7_TEMPSENSE1,
+ .measure_freq_shift = IMX7_TEMPSENSE1_MEASURE_FREQ_SHIFT,
+ .measure_freq_mask = IMX7_TEMPSENSE1_MEASURE_FREQ_MASK,
+
+ .temp_data = IMX7_TEMPSENSE1,
+ .temp_value_mask = IMX7_TEMPSENSE1_TEMP_VALUE_MASK,
+ .temp_value_shift = IMX7_TEMPSENSE1_TEMP_VALUE_SHIFT,
+ .temp_valid_mask = IMX7_TEMPSENSE1_FINISHED,
+
+ .panic_alarm_ctrl = IMX7_TEMPSENSE1,
+ .panic_alarm_mask = IMX7_TEMPSENSE0_PANIC_ALARM_MASK,
+ .panic_alarm_shift = IMX7_TEMPSENSE0_PANIC_ALARM_SHIFT,
+
+ .high_alarm_ctrl = IMX7_TEMPSENSE0,
+ .high_alarm_mask = IMX7_TEMPSENSE0_HIGH_ALARM_MASK,
+ .high_alarm_shift = IMX7_TEMPSENSE0_HIGH_ALARM_SHIFT,
+
+ .low_alarm_ctrl = IMX7_TEMPSENSE0,
+ .low_alarm_mask = IMX7_TEMPSENSE0_LOW_ALARM_MASK,
+ .low_alarm_shift = IMX7_TEMPSENSE0_LOW_ALARM_SHIFT,
+
};
struct imx_thermal_data {
struct cpufreq_policy *policy;
struct thermal_zone_device *tz;
- struct thermal_cooling_device *cdev;
+ struct thermal_cooling_device *cdev[2];
enum thermal_device_mode mode;
struct regmap *tempmon;
u32 c1, c2; /* See formula in imx_get_sensor_data() */
@@ -103,55 +233,78 @@ struct imx_thermal_data {
bool irq_enabled;
int irq;
struct clk *thermal_clk;
+ struct mutex mutex;
const struct thermal_soc_data *socdata;
const char *temp_grade;
};
+static struct imx_thermal_data *imx_thermal_data;
+static int skip_finish_check;
+static u32 imx7_lpsr_save[2];
+
static void imx_set_panic_temp(struct imx_thermal_data *data,
int panic_temp)
{
+ const struct thermal_soc_data *soc_data = data->socdata;
struct regmap *map = data->tempmon;
int critical_value;
- critical_value = (data->c2 - panic_temp) / data->c1;
- regmap_write(map, TEMPSENSE2 + REG_CLR, TEMPSENSE2_PANIC_VALUE_MASK);
- regmap_write(map, TEMPSENSE2 + REG_SET, critical_value <<
- TEMPSENSE2_PANIC_VALUE_SHIFT);
+ if (data->socdata->version == TEMPMON_IMX7)
+ critical_value = panic_temp / 1000 + data->c1 - 25;
+ else
+ critical_value = (data->c2 - panic_temp) / data->c1;
+
+ regmap_write(map, soc_data->panic_alarm_ctrl + REG_CLR,
+ soc_data->panic_alarm_mask);
+ regmap_write(map, soc_data->panic_alarm_ctrl + REG_SET,
+ critical_value << soc_data->panic_alarm_shift);
}
static void imx_set_alarm_temp(struct imx_thermal_data *data,
int alarm_temp)
{
+ const struct thermal_soc_data *soc_data = data->socdata;
struct regmap *map = data->tempmon;
int alarm_value;
data->alarm_temp = alarm_temp;
- alarm_value = (data->c2 - alarm_temp) / data->c1;
- regmap_write(map, TEMPSENSE0 + REG_CLR, TEMPSENSE0_ALARM_VALUE_MASK);
- regmap_write(map, TEMPSENSE0 + REG_SET, alarm_value <<
- TEMPSENSE0_ALARM_VALUE_SHIFT);
+
+ if (data->socdata->version == TEMPMON_IMX7)
+ alarm_value = alarm_temp / 1000 + data->c1 - 25;
+ else
+ alarm_value = (data->c2 - alarm_temp) / data->c1;
+
+ regmap_write(map, soc_data->high_alarm_ctrl + REG_CLR,
+ soc_data->high_alarm_mask);
+ regmap_write(map, soc_data->high_alarm_ctrl + REG_SET,
+ alarm_value << soc_data->high_alarm_shift);
}
static int imx_get_temp(struct thermal_zone_device *tz, int *temp)
{
struct imx_thermal_data *data = tz->devdata;
+ const struct thermal_soc_data *soc_data = data->socdata;
struct regmap *map = data->tempmon;
unsigned int n_meas;
bool wait;
u32 val;
+ mutex_lock(&data->mutex);
if (data->mode == THERMAL_DEVICE_ENABLED) {
/* Check if a measurement is currently in progress */
- regmap_read(map, TEMPSENSE0, &val);
- wait = !(val & TEMPSENSE0_FINISHED);
+ regmap_read(map, soc_data->temp_data, &val);
+ wait = !(val & soc_data->temp_valid_mask);
} else {
/*
* Every time we measure the temperature, we will power on the
* temperature sensor, enable measurements, take a reading,
* disable measurements, power off the temperature sensor.
*/
- regmap_write(map, TEMPSENSE0 + REG_CLR, TEMPSENSE0_POWER_DOWN);
- regmap_write(map, TEMPSENSE0 + REG_SET, TEMPSENSE0_MEASURE_TEMP);
+ clk_prepare_enable(data->thermal_clk);
+ regmap_write(map, soc_data->sensor_ctrl + REG_CLR,
+ soc_data->power_down_mask);
+ regmap_write(map, soc_data->sensor_ctrl + REG_SET,
+ soc_data->measure_temp_mask);
wait = true;
}
@@ -160,25 +313,41 @@ static int imx_get_temp(struct thermal_zone_device *tz, int *temp)
* According to the temp sensor designers, it may require up to ~17us
* to complete a measurement.
*/
- if (wait)
- usleep_range(20, 50);
-
- regmap_read(map, TEMPSENSE0, &val);
+ if (wait) {
+ /*
+ * On i.MX7 TO1.0, the finish bit can only keep 1us after
+ * the measured data available. It is hard for software to
+ * polling this bit. So wait for 20ms to make sure the
+ * measured data is valid.
+ */
+ if (data->socdata->version == TEMPMON_IMX7 && skip_finish_check)
+ msleep(20);
+ else
+ usleep_range(20, 50);
+ regmap_read(map, soc_data->temp_data, &val);
+ }
if (data->mode != THERMAL_DEVICE_ENABLED) {
- regmap_write(map, TEMPSENSE0 + REG_CLR, TEMPSENSE0_MEASURE_TEMP);
- regmap_write(map, TEMPSENSE0 + REG_SET, TEMPSENSE0_POWER_DOWN);
+ regmap_write(map, soc_data->sensor_ctrl + REG_CLR,
+ soc_data->measure_temp_mask);
+ regmap_write(map, soc_data->sensor_ctrl + REG_SET,
+ soc_data->power_down_mask);
+ clk_disable_unprepare(data->thermal_clk);
}
- if ((val & TEMPSENSE0_FINISHED) == 0) {
+ if (!skip_finish_check && ((val & soc_data->temp_valid_mask) == 0)) {
dev_dbg(&tz->device, "temp measurement never finished\n");
+ mutex_unlock(&data->mutex);
return -EAGAIN;
}
- n_meas = (val & TEMPSENSE0_TEMP_CNT_MASK) >> TEMPSENSE0_TEMP_CNT_SHIFT;
-
+ n_meas = (val & soc_data->temp_value_mask) >> soc_data->temp_value_shift;
/* See imx_get_sensor_data() for formula derivation */
*temp = data->c2 - n_meas * data->c1;
+ if (data->socdata->version == TEMPMON_IMX7)
+ *temp = (n_meas - data->c1 + 25) * 1000;
+ else
+ *temp = data->c2 - n_meas * data->c1;
/* Update alarm value to next higher trip point for TEMPMON_IMX6Q */
if (data->socdata->version == TEMPMON_IMX6Q) {
@@ -203,6 +372,7 @@ static int imx_get_temp(struct thermal_zone_device *tz, int *temp)
data->irq_enabled = true;
enable_irq(data->irq);
}
+ mutex_unlock(&data->mutex);
return 0;
}
@@ -221,22 +391,26 @@ static int imx_set_mode(struct thermal_zone_device *tz,
enum thermal_device_mode mode)
{
struct imx_thermal_data *data = tz->devdata;
+ const struct thermal_soc_data *soc_data = data->socdata;
struct regmap *map = data->tempmon;
if (mode == THERMAL_DEVICE_ENABLED) {
tz->polling_delay = IMX_POLLING_DELAY;
tz->passive_delay = IMX_PASSIVE_DELAY;
- regmap_write(map, TEMPSENSE0 + REG_CLR, TEMPSENSE0_POWER_DOWN);
- regmap_write(map, TEMPSENSE0 + REG_SET, TEMPSENSE0_MEASURE_TEMP);
-
+ regmap_write(map, soc_data->sensor_ctrl + REG_CLR,
+ soc_data->power_down_mask);
+ regmap_write(map, soc_data->sensor_ctrl + REG_SET,
+ soc_data->measure_temp_mask);
if (!data->irq_enabled) {
data->irq_enabled = true;
enable_irq(data->irq);
}
} else {
- regmap_write(map, TEMPSENSE0 + REG_CLR, TEMPSENSE0_MEASURE_TEMP);
- regmap_write(map, TEMPSENSE0 + REG_SET, TEMPSENSE0_POWER_DOWN);
+ regmap_write(map, soc_data->sensor_ctrl + REG_CLR,
+ soc_data->measure_temp_mask);
+ regmap_write(map, soc_data->sensor_ctrl + REG_SET,
+ soc_data->power_down_mask);
tz->polling_delay = 0;
tz->passive_delay = 0;
@@ -284,17 +458,18 @@ static int imx_set_trip_temp(struct thermal_zone_device *tz, int trip,
{
struct imx_thermal_data *data = tz->devdata;
- /* do not allow changing critical threshold */
- if (trip == IMX_TRIP_CRITICAL)
- return -EPERM;
-
- /* do not allow passive to be set higher than critical */
- if (temp < 0 || temp > data->temp_critical)
- return -EINVAL;
-
- data->temp_passive = temp;
+ if (trip == IMX_TRIP_CRITICAL) {
+ data->temp_critical = temp;
+ if (data->socdata->version == TEMPMON_IMX6SX)
+ imx_set_panic_temp(data, temp);
+ }
- imx_set_alarm_temp(data, temp);
+ if (trip == IMX_TRIP_PASSIVE) {
+ if (temp > (data->temp_max - (1000 * 10)))
+ return -EINVAL;
+ data->temp_passive = temp;
+ imx_set_alarm_temp(data, temp);
+ }
return 0;
}
@@ -334,6 +509,23 @@ static int imx_unbind(struct thermal_zone_device *tz,
return 0;
}
+static int imx_get_trend(struct thermal_zone_device *tz,
+ int trip, enum thermal_trend *trend)
+{
+ int ret;
+ int trip_temp;
+
+ ret = imx_get_trip_temp(tz, trip, &trip_temp);
+ if (ret < 0)
+ return ret;
+
+ if (tz->temperature >= (trip_temp - IMX_TEMP_PASSIVE_COOL_DELTA))
+ *trend = THERMAL_TREND_RAISE_FULL;
+ else
+ *trend = THERMAL_TREND_DROP_FULL;
+
+ return 0;
+}
static struct thermal_zone_device_ops imx_tz_ops = {
.bind = imx_bind,
.unbind = imx_unbind,
@@ -344,69 +536,102 @@ static struct thermal_zone_device_ops imx_tz_ops = {
.get_trip_temp = imx_get_trip_temp,
.get_crit_temp = imx_get_crit_temp,
.set_trip_temp = imx_set_trip_temp,
+ .get_trend = imx_get_trend,
};
-static int imx_get_sensor_data(struct platform_device *pdev)
+static inline void imx6_calibrate_data(struct imx_thermal_data *data, u32 val)
{
- struct imx_thermal_data *data = platform_get_drvdata(pdev);
- struct regmap *map;
- int t1, n1;
- int ret;
- u32 val;
+ int t1, t2, n1, n2;
u64 temp64;
-
- map = syscon_regmap_lookup_by_phandle(pdev->dev.of_node,
- "fsl,tempmon-data");
- if (IS_ERR(map)) {
- ret = PTR_ERR(map);
- dev_err(&pdev->dev, "failed to get sensor regmap: %d\n", ret);
- return ret;
- }
-
- ret = regmap_read(map, OCOTP_ANA1, &val);
- if (ret) {
- dev_err(&pdev->dev, "failed to read sensor data: %d\n", ret);
- return ret;
- }
-
- if (val == 0 || val == ~0) {
- dev_err(&pdev->dev, "invalid sensor calibration data\n");
- return -EINVAL;
- }
-
/*
* Sensor data layout:
* [31:20] - sensor value @ 25C
+ * [19:8] - sensor value of hot
+ * [7:0] - hot temperature value
* Use universal formula now and only need sensor value @ 25C
* slope = 0.4297157 - (0.0015976 * 25C fuse)
*/
n1 = val >> 20;
+ n2 = (val & 0xfff00) >> 8;
+ t2 = val & 0xff;
t1 = 25; /* t1 always 25C */
/*
* Derived from linear interpolation:
* slope = 0.4297157 - (0.0015976 * 25C fuse)
* slope = (FACTOR2 - FACTOR1 * n1) / FACTOR0
+ * offset = OFFSET / 1000000
* (Nmeas - n1) / (Tmeas - t1) = slope
* We want to reduce this down to the minimum computation necessary
* for each temperature read. Also, we want Tmeas in millicelsius
* and we don't want to lose precision from integer division. So...
- * Tmeas = (Nmeas - n1) / slope + t1
- * milli_Tmeas = 1000 * (Nmeas - n1) / slope + 1000 * t1
- * milli_Tmeas = -1000 * (n1 - Nmeas) / slope + 1000 * t1
+ * Tmeas = (Nmeas - n1) / slope + t1 + offset
+ * milli_Tmeas = 1000 * (Nmeas - n1) / slope + 1000 * t1 + OFFSET / 1000
+ * milli_Tmeas = -1000 * (n1 - Nmeas) / slope + 1000 * t1 + OFFSET /1000
* Let constant c1 = (-1000 / slope)
- * milli_Tmeas = (n1 - Nmeas) * c1 + 1000 * t1
- * Let constant c2 = n1 *c1 + 1000 * t1
+ * milli_Tmeas = (n1 - Nmeas) * c1 + 1000 * t1 + OFFSET / 1000
+ * Let constant c2 = n1 *c1 + 1000 * t1 + OFFSET / 1000
* milli_Tmeas = c2 - Nmeas * c1
*/
temp64 = FACTOR0;
temp64 *= 1000;
do_div(temp64, FACTOR1 * n1 - FACTOR2);
data->c1 = temp64;
- data->c2 = n1 * data->c1 + 1000 * t1;
+ temp64 = OFFSET;
+ do_div(temp64, 1000);
+ data->c2 = n1 * data->c1 + 1000 * t1 + temp64;
+}
+
+/*
+ * On i.MX7, we only use the calibration data at 25C to get the temp,
+ * Tmeas = ( Nmeas - n1) + 25; n1 is the fuse value for 25C.
+ */
+static inline void imx7_calibrate_data(struct imx_thermal_data *data, u32 val)
+{
+ data->c1 = (val >> 9) & 0x1ff;
+}
+
+static int imx_get_sensor_data(struct platform_device *pdev)
+{
+ struct imx_thermal_data *data = platform_get_drvdata(pdev);
+ struct regmap *map;
+ int ret;
+ u32 val;
+
+ map = syscon_regmap_lookup_by_phandle(pdev->dev.of_node,
+ "fsl,tempmon-data");
+ if (IS_ERR(map)) {
+ ret = PTR_ERR(map);
+ dev_err(&pdev->dev, "failed to get sensor regmap: %d\n", ret);
+ return ret;
+ }
+
+ if (data->socdata->version == TEMPMON_IMX7)
+ ret = regmap_read(map, IMX7_OCOTP_ANA1, &val);
+ else
+ ret = regmap_read(map, IMX6_OCOTP_ANA1, &val);
+
+ if (ret) {
+ dev_err(&pdev->dev, "failed to read sensor data: %d\n", ret);
+ return ret;
+ }
+
+ if (val == 0 || val == ~0) {
+ dev_err(&pdev->dev, "invalid sensor calibration data\n");
+ return -EINVAL;
+ }
+
+ if (data->socdata->version == TEMPMON_IMX7)
+ imx7_calibrate_data(data, val);
+ else
+ imx6_calibrate_data(data, val);
/* use OTP for thermal grade */
- ret = regmap_read(map, OCOTP_MEM0, &val);
+ if (data->socdata->version == TEMPMON_IMX7)
+ ret = regmap_read(map, IMX7_OCOTP_TESTER3, &val);
+ else
+ ret = regmap_read(map, OCOTP_MEM0, &val);
+
if (ret) {
dev_err(&pdev->dev, "failed to read temp grade: %d\n", ret);
return ret;
@@ -467,20 +692,68 @@ static irqreturn_t imx_thermal_alarm_irq_thread(int irq, void *dev)
static const struct of_device_id of_imx_thermal_match[] = {
{ .compatible = "fsl,imx6q-tempmon", .data = &thermal_imx6q_data, },
{ .compatible = "fsl,imx6sx-tempmon", .data = &thermal_imx6sx_data, },
+ { .compatible = "fsl,imx7d-tempmon", .data = &thermal_imx7d_data, },
{ /* end */ }
};
MODULE_DEVICE_TABLE(of, of_imx_thermal_match);
+static int thermal_notifier_event(struct notifier_block *this,
+ unsigned long event, void *ptr)
+{
+ const struct thermal_soc_data *soc_data = imx_thermal_data->socdata;
+ struct regmap *map = imx_thermal_data->tempmon;
+
+ mutex_lock(&imx_thermal_data->mutex);
+
+ switch (event) {
+ /*
+ * In low_bus_freq_mode, the thermal sensor auto measurement
+ * can be disabled to low the power consumption.
+ */
+ case LOW_BUSFREQ_ENTER:
+ regmap_write(map, soc_data->sensor_ctrl + REG_CLR,
+ soc_data->measure_temp_mask);
+ regmap_write(map, soc_data->sensor_ctrl + REG_SET,
+ soc_data->power_down_mask);
+ imx_thermal_data->mode = THERMAL_DEVICE_DISABLED;
+ disable_irq(imx_thermal_data->irq);
+ clk_disable_unprepare(imx_thermal_data->thermal_clk);
+ break;
+
+ /* Enabled thermal auto measurement when exiting low_bus_freq_mode */
+ case LOW_BUSFREQ_EXIT:
+ clk_prepare_enable(imx_thermal_data->thermal_clk);
+ regmap_write(map, soc_data->sensor_ctrl + REG_CLR,
+ soc_data->power_down_mask);
+ regmap_write(map, soc_data->sensor_ctrl + REG_SET,
+ soc_data->measure_temp_mask);
+ imx_thermal_data->mode = THERMAL_DEVICE_ENABLED;
+ enable_irq(imx_thermal_data->irq);
+ break;
+
+ default:
+ break;
+ }
+ mutex_unlock(&imx_thermal_data->mutex);
+
+ return NOTIFY_OK;
+}
+
+static struct notifier_block thermal_notifier = {
+ .notifier_call = thermal_notifier_event,
+};
+
static int imx_thermal_probe(struct platform_device *pdev)
{
struct imx_thermal_data *data;
struct regmap *map;
int measure_freq;
- int ret;
+ int ret, revision;
data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
if (!data)
return -ENOMEM;
+ imx_thermal_data = data;
map = syscon_regmap_lookup_by_phandle(pdev->dev.of_node, "fsl,tempmon");
if (IS_ERR(map)) {
@@ -520,12 +793,25 @@ static int imx_thermal_probe(struct platform_device *pdev)
return ret;
}
+ /*
+ * for i.MX7D TO1.0, finish bit is not available, check the
+ * SOC revision to skip checking the finish bit status.
+ */
+ regmap_read(map, IMX7_ANADIG_DIGPROG, &revision);
+ if ((revision & 0xff) == 0x10)
+ skip_finish_check = 1;
+
/* Make sure sensor is in known good state for measurements */
- regmap_write(map, TEMPSENSE0 + REG_CLR, TEMPSENSE0_POWER_DOWN);
- regmap_write(map, TEMPSENSE0 + REG_CLR, TEMPSENSE0_MEASURE_TEMP);
- regmap_write(map, TEMPSENSE1 + REG_CLR, TEMPSENSE1_MEASURE_FREQ);
- regmap_write(map, MISC0 + REG_SET, MISC0_REFTOP_SELBIASOFF);
- regmap_write(map, TEMPSENSE0 + REG_SET, TEMPSENSE0_POWER_DOWN);
+ regmap_write(map, data->socdata->sensor_ctrl + REG_CLR,
+ data->socdata->power_down_mask);
+ regmap_write(map, data->socdata->sensor_ctrl + REG_CLR,
+ data->socdata->measure_temp_mask);
+ regmap_write(map, data->socdata->measure_freq_ctrl + REG_CLR,
+ data->socdata->measure_freq_mask);
+ if (data->socdata->version != TEMPMON_IMX7)
+ regmap_write(map, MISC0 + REG_SET, MISC0_REFTOP_SELBIASOFF);
+ regmap_write(map, data->socdata->sensor_ctrl + REG_SET,
+ data->socdata->power_down_mask);
data->policy = cpufreq_cpu_get(0);
if (!data->policy) {
@@ -533,12 +819,25 @@ static int imx_thermal_probe(struct platform_device *pdev)
return -EPROBE_DEFER;
}
- data->cdev = cpufreq_cooling_register(data->policy);
- if (IS_ERR(data->cdev)) {
- ret = PTR_ERR(data->cdev);
- dev_err(&pdev->dev,
- "failed to register cpufreq cooling device: %d\n", ret);
- cpufreq_cpu_put(data->policy);
+ data->cdev[0] = cpufreq_cooling_register(data->policy);
+ if (IS_ERR(data->cdev[0])) {
+ ret = PTR_ERR(data->cdev[0]);
+ if (ret != -EPROBE_DEFER)
+ dev_err(&pdev->dev,
+ "failed to register cpufreq cooling device: %d\n",
+ ret);
+ return ret;
+ }
+
+ data->cdev[1] = devfreq_cooling_register();
+ if (IS_ERR(data->cdev[1])) {
+ ret = PTR_ERR(data->cdev[1]);
+ if (ret != -EPROBE_DEFER) {
+ dev_err(&pdev->dev,
+ "failed to register cpufreq cooling device: %d\n",
+ ret);
+ cpufreq_cooling_unregister(data->cdev[0]);
+ }
return ret;
}
@@ -548,7 +847,7 @@ static int imx_thermal_probe(struct platform_device *pdev)
if (ret != -EPROBE_DEFER)
dev_err(&pdev->dev,
"failed to get thermal clk: %d\n", ret);
- cpufreq_cooling_unregister(data->cdev);
+ cpufreq_cooling_unregister(data->cdev[0]);
cpufreq_cpu_put(data->policy);
return ret;
}
@@ -563,14 +862,16 @@ static int imx_thermal_probe(struct platform_device *pdev)
ret = clk_prepare_enable(data->thermal_clk);
if (ret) {
dev_err(&pdev->dev, "failed to enable thermal clk: %d\n", ret);
- cpufreq_cooling_unregister(data->cdev);
+ cpufreq_cooling_unregister(data->cdev[0]);
+ devfreq_cooling_unregister(data->cdev[1]);
cpufreq_cpu_put(data->policy);
return ret;
}
+ mutex_init(&data->mutex);
data->tz = thermal_zone_device_register("imx_thermal_zone",
IMX_TRIP_NUM,
- BIT(IMX_TRIP_PASSIVE), data,
+ (1 << IMX_TRIP_NUM) - 1, data,
&imx_tz_ops, NULL,
IMX_PASSIVE_DELAY,
IMX_POLLING_DELAY);
@@ -579,7 +880,8 @@ static int imx_thermal_probe(struct platform_device *pdev)
dev_err(&pdev->dev,
"failed to register thermal zone device %d\n", ret);
clk_disable_unprepare(data->thermal_clk);
- cpufreq_cooling_unregister(data->cdev);
+ cpufreq_cooling_unregister(data->cdev[0]);
+ devfreq_cooling_unregister(data->cdev[1]);
cpufreq_cpu_put(data->policy);
return ret;
}
@@ -590,16 +892,20 @@ static int imx_thermal_probe(struct platform_device *pdev)
data->temp_passive / 1000);
/* Enable measurements at ~ 10 Hz */
- regmap_write(map, TEMPSENSE1 + REG_CLR, TEMPSENSE1_MEASURE_FREQ);
+ regmap_write(map, data->socdata->measure_freq_ctrl + REG_CLR,
+ data->socdata->measure_freq_mask);
measure_freq = DIV_ROUND_UP(32768, 10); /* 10 Hz */
- regmap_write(map, TEMPSENSE1 + REG_SET, measure_freq);
+ regmap_write(map, data->socdata->measure_freq_ctrl + REG_SET,
+ measure_freq << data->socdata->measure_freq_shift);
imx_set_alarm_temp(data, data->temp_passive);
if (data->socdata->version == TEMPMON_IMX6SX)
imx_set_panic_temp(data, data->temp_critical);
- regmap_write(map, TEMPSENSE0 + REG_CLR, TEMPSENSE0_POWER_DOWN);
- regmap_write(map, TEMPSENSE0 + REG_SET, TEMPSENSE0_MEASURE_TEMP);
+ regmap_write(map, data->socdata->sensor_ctrl + REG_CLR,
+ data->socdata->power_down_mask);
+ regmap_write(map, data->socdata->sensor_ctrl + REG_SET,
+ data->socdata->measure_temp_mask);
data->irq_enabled = true;
data->mode = THERMAL_DEVICE_ENABLED;
@@ -611,11 +917,16 @@ static int imx_thermal_probe(struct platform_device *pdev)
dev_err(&pdev->dev, "failed to request alarm irq: %d\n", ret);
clk_disable_unprepare(data->thermal_clk);
thermal_zone_device_unregister(data->tz);
- cpufreq_cooling_unregister(data->cdev);
+ cpufreq_cooling_unregister(data->cdev[0]);
+ devfreq_cooling_unregister(data->cdev[1]);
cpufreq_cpu_put(data->policy);
return ret;
}
+ /* register the busfreq notifier called in low bus freq */
+ if (data->socdata->version != TEMPMON_IMX7)
+ register_busfreq_notifier(&thermal_notifier);
+
return 0;
}
@@ -625,12 +936,18 @@ static int imx_thermal_remove(struct platform_device *pdev)
struct regmap *map = data->tempmon;
/* Disable measurements */
- regmap_write(map, TEMPSENSE0 + REG_SET, TEMPSENSE0_POWER_DOWN);
+ regmap_write(map, data->socdata->sensor_ctrl + REG_SET,
+ data->socdata->power_down_mask);
if (!IS_ERR(data->thermal_clk))
clk_disable_unprepare(data->thermal_clk);
+ /* unregister the busfreq notifier called in low bus freq */
+ if (data->socdata->version != TEMPMON_IMX7)
+ unregister_busfreq_notifier(&thermal_notifier);
+
thermal_zone_device_unregister(data->tz);
- cpufreq_cooling_unregister(data->cdev);
+ cpufreq_cooling_unregister(data->cdev[0]);
+ devfreq_cooling_unregister(data->cdev[1]);
cpufreq_cpu_put(data->policy);
return 0;
@@ -648,8 +965,20 @@ static int imx_thermal_suspend(struct device *dev)
* temperature will be read as the thermal sensor is powered
* down.
*/
- regmap_write(map, TEMPSENSE0 + REG_CLR, TEMPSENSE0_MEASURE_TEMP);
- regmap_write(map, TEMPSENSE0 + REG_SET, TEMPSENSE0_POWER_DOWN);
+ regmap_write(map, data->socdata->sensor_ctrl + REG_CLR,
+ data->socdata->measure_temp_mask);
+ regmap_write(map, data->socdata->sensor_ctrl + REG_SET,
+ data->socdata->power_down_mask);
+
+ /*
+ * Save the temp sensor registers of i.MX7D as the tempmon
+ * will lost power in LPSR mode
+ */
+ if (data->socdata->version == TEMPMON_IMX7) {
+ regmap_read(map, data->socdata->sensor_ctrl, &imx7_lpsr_save[0]);
+ regmap_read(map, data->socdata->high_alarm_ctrl, &imx7_lpsr_save[1]);
+ }
+
data->mode = THERMAL_DEVICE_DISABLED;
clk_disable_unprepare(data->thermal_clk);
@@ -665,9 +994,21 @@ static int imx_thermal_resume(struct device *dev)
ret = clk_prepare_enable(data->thermal_clk);
if (ret)
return ret;
+
+ /*
+ * restore the temp sensor registers of i.MX7D as the tempmon
+ * will lost power in LPSR mode
+ */
+ if (data->socdata->version == TEMPMON_IMX7) {
+ regmap_write(map, data->socdata->sensor_ctrl, imx7_lpsr_save[0]);
+ regmap_write(map, data->socdata->high_alarm_ctrl, imx7_lpsr_save[1]);
+ }
+
/* Enabled thermal sensor after resume */
- regmap_write(map, TEMPSENSE0 + REG_CLR, TEMPSENSE0_POWER_DOWN);
- regmap_write(map, TEMPSENSE0 + REG_SET, TEMPSENSE0_MEASURE_TEMP);
+ regmap_write(map, data->socdata->sensor_ctrl + REG_CLR,
+ data->socdata->power_down_mask);
+ regmap_write(map, data->socdata->sensor_ctrl + REG_SET,
+ data->socdata->measure_temp_mask);
data->mode = THERMAL_DEVICE_ENABLED;
return 0;
diff --git a/drivers/thermal/qoriq_thermal.c b/drivers/thermal/qoriq_thermal.c
index c866cc165960..c832ee825fff 100644
--- a/drivers/thermal/qoriq_thermal.c
+++ b/drivers/thermal/qoriq_thermal.c
@@ -1,5 +1,6 @@
/*
* Copyright 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017 NXP.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
@@ -14,6 +15,7 @@
#include <linux/module.h>
#include <linux/platform_device.h>
+#include <linux/device_cooling.h>
#include <linux/err.h>
#include <linux/io.h>
#include <linux/of.h>
@@ -24,6 +26,8 @@
#define SITES_MAX 16
+#define TMU_TEMP_PASSIVE_COOL_DELTA 10000
+
/*
* QorIQ TMU Registers
*/
@@ -74,9 +78,18 @@ struct qoriq_tmu_regs {
*/
struct qoriq_tmu_data {
struct thermal_zone_device *tz;
+ struct thermal_cooling_device *cdev;
struct qoriq_tmu_regs __iomem *regs;
int sensor_id;
bool little_endian;
+ int temp_passive;
+ int temp_critical;
+};
+
+enum tmu_trip {
+ TMU_TRIP_PASSIVE,
+ TMU_TRIP_CRITICAL,
+ TMU_TRIP_NUM,
};
static void tmu_write(struct qoriq_tmu_data *p, u32 val, void __iomem *addr)
@@ -188,13 +201,51 @@ static void qoriq_tmu_init_device(struct qoriq_tmu_data *data)
tmu_write(data, TMR_DISABLE, &data->regs->tmr);
}
+static int tmu_get_trend(void *p,
+ int trip, enum thermal_trend *trend)
+{
+ int trip_temp;
+ struct qoriq_tmu_data *data = p;
+
+ if (!data->tz)
+ return 0;
+
+ trip_temp = (trip == TMU_TRIP_PASSIVE) ? data->temp_passive :
+ data->temp_critical;
+
+ if (data->tz->temperature >=
+ (trip_temp - TMU_TEMP_PASSIVE_COOL_DELTA))
+ *trend = THERMAL_TREND_RAISE_FULL;
+ else
+ *trend = THERMAL_TREND_DROP_FULL;
+
+ return 0;
+}
+
+static int tmu_set_trip_temp(void *p, int trip,
+ int temp)
+{
+ struct qoriq_tmu_data *data = p;
+
+ if (trip == TMU_TRIP_CRITICAL)
+ data->temp_critical = temp;
+
+ if (trip == TMU_TRIP_PASSIVE)
+ data->temp_passive = temp;
+
+ return 0;
+}
+
static const struct thermal_zone_of_device_ops tmu_tz_ops = {
.get_temp = tmu_get_temp,
+ .get_trend = tmu_get_trend,
+ .set_trip_temp = tmu_set_trip_temp,
};
static int qoriq_tmu_probe(struct platform_device *pdev)
{
int ret;
+ const struct thermal_trip *trip;
struct qoriq_tmu_data *data;
struct device_node *np = pdev->dev.of_node;
u32 site = 0;
@@ -242,6 +293,34 @@ static int qoriq_tmu_probe(struct platform_device *pdev)
goto err_tmu;
}
+ data->cdev = devfreq_cooling_register();
+ if (IS_ERR(data->cdev)) {
+ ret = PTR_ERR(data->cdev);
+ if (ret != -EPROBE_DEFER)
+ dev_err(&pdev->dev,
+ "failed to register devfreq cooling device: %d\n",
+ ret);
+ return ret;
+ }
+
+ ret = thermal_zone_bind_cooling_device(data->tz,
+ TMU_TRIP_PASSIVE,
+ data->cdev,
+ THERMAL_NO_LIMIT,
+ THERMAL_NO_LIMIT,
+ THERMAL_WEIGHT_DEFAULT);
+ if (ret) {
+ dev_err(&data->tz->device,
+ "binding zone %s with cdev %s failed:%d\n",
+ data->tz->type, data->cdev->type, ret);
+ devfreq_cooling_unregister(data->cdev);
+ return ret;
+ }
+
+ trip = of_thermal_get_trip_points(data->tz);
+ data->temp_passive = trip[0].temperature;
+ data->temp_critical = trip[1].temperature;
+
/* Enable monitoring */
site |= 0x1 << (15 - data->sensor_id);
tmu_write(data, site | TMR_ME | TMR_ALPF, &data->regs->tmr);
@@ -261,6 +340,7 @@ static int qoriq_tmu_remove(struct platform_device *pdev)
{
struct qoriq_tmu_data *data = platform_get_drvdata(pdev);
+ devfreq_cooling_unregister(data->cdev);
thermal_zone_of_sensor_unregister(&pdev->dev, data->tz);
/* Disable monitoring */
@@ -305,6 +385,7 @@ static SIMPLE_DEV_PM_OPS(qoriq_tmu_pm_ops,
static const struct of_device_id qoriq_tmu_match[] = {
{ .compatible = "fsl,qoriq-tmu", },
+ { .compatible = "fsl,imx8mq-tmu",},
{},
};
MODULE_DEVICE_TABLE(of, qoriq_tmu_match);
diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig
index b788fee54249..b7c9fb35627b 100644
--- a/drivers/tty/serial/Kconfig
+++ b/drivers/tty/serial/Kconfig
@@ -587,7 +587,7 @@ config BFIN_UART3_CTSRTS
config SERIAL_IMX
tristate "IMX serial port support"
depends on HAS_DMA
- depends on ARCH_MXC || COMPILE_TEST
+ depends on ARCH_MXC || ARCH_MXC_ARM64 || COMPILE_TEST
select SERIAL_CORE
select RATIONAL
select SERIAL_MCTRL_GPIO if GPIOLIB
diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c
index fb2dcb3f8591..472c9a04ed6b 100644
--- a/drivers/tty/serial/fsl_lpuart.c
+++ b/drivers/tty/serial/fsl_lpuart.c
@@ -2,6 +2,7 @@
* Freescale lpuart serial port driver
*
* Copyright 2012-2014 Freescale Semiconductor, Inc.
+ * Copyright 2017 NXP
*
* 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
@@ -15,6 +16,7 @@
#include <linux/clk.h>
#include <linux/console.h>
+#include <linux/delay.h>
#include <linux/dma-mapping.h>
#include <linux/dmaengine.h>
#include <linux/dmapool.h>
@@ -24,6 +26,8 @@
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/of_dma.h>
+#include <linux/pm_runtime.h>
+#include <linux/reset.h>
#include <linux/serial_core.h>
#include <linux/slab.h>
#include <linux/tty_flip.h>
@@ -127,11 +131,17 @@
#define UARTFIFO 0x18
#define UARTWATER 0x1c
+/* 32-bit global registers only for i.MX7ulp/MX8x
+ * The driver only use the reset feature to reset HW.
+ */
+#define UART_GLOBAL 0x8
+
#define UARTBAUD_MAEN1 0x80000000
#define UARTBAUD_MAEN2 0x40000000
#define UARTBAUD_M10 0x20000000
#define UARTBAUD_TDMAE 0x00800000
#define UARTBAUD_RDMAE 0x00200000
+#define UARTBAUD_RIDMAE 0x00100000
#define UARTBAUD_MATCFG 0x00400000
#define UARTBAUD_BOTHEDGE 0x00020000
#define UARTBAUD_RESYNCDIS 0x00010000
@@ -180,7 +190,7 @@
#define UARTCTRL_SBK 0x00010000
#define UARTCTRL_MA1IE 0x00008000
#define UARTCTRL_MA2IE 0x00004000
-#define UARTCTRL_IDLECFG 0x00000100
+#define UARTCTRL_IDLECFG_OFF 0x8
#define UARTCTRL_LOOPS 0x00000080
#define UARTCTRL_DOZEEN 0x00000040
#define UARTCTRL_RSRC 0x00000020
@@ -195,9 +205,12 @@
#define UARTDATA_FRETSC 0x00002000
#define UARTDATA_RXEMPT 0x00001000
#define UARTDATA_IDLINE 0x00000800
+#define UARTDATA_INVALID 0x0000F000
#define UARTDATA_MASK 0x3ff
#define UARTMODIR_IREN 0x00020000
+#define UARTMODIR_RTSWATER_S 0x8
+#define UARTMODIR_RTSWATER_M 0x0000ff00
#define UARTMODIR_TXCTSSRC 0x00000020
#define UARTMODIR_TXCTSC 0x00000010
#define UARTMODIR_RXRTSE 0x00000008
@@ -211,6 +224,8 @@
#define UARTFIFO_RXUF 0x00010000
#define UARTFIFO_TXFLUSH 0x00008000
#define UARTFIFO_RXFLUSH 0x00004000
+#define UARTFIFO_RXIDEN_MASK 0x7
+#define UARTFIFO_RXIDEN_OFF 10
#define UARTFIFO_TXOFE 0x00000200
#define UARTFIFO_RXUFE 0x00000100
#define UARTFIFO_TXFE 0x00000080
@@ -226,8 +241,14 @@
#define UARTWATER_TXWATER_OFF 0
#define UARTWATER_RXWATER_OFF 16
-/* Rx DMA timeout in ms, which is used to calculate Rx ring buffer size */
-#define DMA_RX_TIMEOUT (10)
+#define UART_GLOBAL_RST 0x2
+#define RST_HW_MIN_US 20
+#define RST_HW_MAX_US 40
+
+#define UARTFIFO_RXIDEN_RDRF 0x3
+#define UARTCTRL_IDLECFG 0x7
+#define FSL_UART_RX_DMA_BUFFER_SIZE 128
+#define UART_AUTOSUSPEND_TIMEOUT 3000
#define DRIVER_NAME "fsl-lpuart"
#define DEV_NAME "ttyLP"
@@ -238,26 +259,37 @@
struct lpuart_port {
struct uart_port port;
- struct clk *clk;
+ void __iomem *regbase;
+
+ struct clk *ipg_clk;
+ struct clk *per_clk;
unsigned int txfifo_size;
unsigned int rxfifo_size;
+ unsigned int txfifo_watermark;
+ unsigned int rxfifo_watermark;
+
+ unsigned int rts_watermark;
+ bool dma_eeop;
bool lpuart_dma_tx_use;
bool lpuart_dma_rx_use;
+ bool dma_rx_chan_active;
struct dma_chan *dma_tx_chan;
struct dma_chan *dma_rx_chan;
struct dma_async_tx_descriptor *dma_tx_desc;
struct dma_async_tx_descriptor *dma_rx_desc;
+ dma_addr_t dma_rx_buf_bus;
dma_cookie_t dma_tx_cookie;
dma_cookie_t dma_rx_cookie;
+ unsigned char *dma_rx_buf_virt;
unsigned int dma_tx_bytes;
unsigned int dma_rx_bytes;
+ size_t rxdma_len;
bool dma_tx_in_progress;
+ bool dma_rx_in_progress;
unsigned int dma_rx_timeout;
struct timer_list lpuart_timer;
struct scatterlist rx_sgl, tx_sgl[2];
- struct circ_buf rx_ring;
- int rx_dma_rng_buf_len;
unsigned int dma_tx_nents;
wait_queue_head_t dma_wait;
};
@@ -284,12 +316,21 @@ static const struct of_device_id lpuart_dt_ids[] = {
{ .compatible = "fsl,vf610-lpuart", .data = &vf_data, },
{ .compatible = "fsl,ls1021a-lpuart", .data = &ls_data, },
{ .compatible = "fsl,imx7ulp-lpuart", .data = &imx_data, },
+ { .compatible = "fsl,imx8qm-lpuart", .data = &imx_data, },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, lpuart_dt_ids);
+static bool lpuart_is_32(struct lpuart_port *sport)
+{
+ return sport->port.iotype == UPIO_MEM32 ||
+ sport->port.iotype == UPIO_MEM32BE;
+}
+
/* Forward declare this for the dma callbacks*/
+static int lpuart_dma_rx(struct lpuart_port *sport);
static void lpuart_dma_tx_complete(void *arg);
+static inline void lpuart_prepare_rx(struct lpuart_port *sport);
static inline u32 lpuart32_read(struct uart_port *port, u32 off)
{
@@ -316,6 +357,33 @@ static inline void lpuart32_write(struct uart_port *port, u32 val,
}
}
+static int lpuart_hw_reset(struct lpuart_port *sport)
+{
+ struct uart_port *port = &sport->port;
+ struct device_node *np = sport->port.dev->of_node;
+ int ret;
+
+ if (uart_console(port))
+ return 0;
+
+ ret = clk_prepare_enable(sport->ipg_clk);
+ if (ret) {
+ dev_err(sport->port.dev, "failed to enable uart ipg clk: %d\n", ret);
+ return ret;
+ }
+
+ if (np && (of_device_is_compatible(np, "fsl,imx7ulp-lpuart") ||
+ of_device_is_compatible(np, "fsl,imx8qm-lpuart"))) {
+ writel(UART_GLOBAL_RST, sport->regbase + UART_GLOBAL);
+ usleep_range(RST_HW_MIN_US, RST_HW_MAX_US);
+ writel(0, sport->regbase + UART_GLOBAL);
+ usleep_range(RST_HW_MIN_US, RST_HW_MAX_US);
+ }
+
+ clk_disable_unprepare(sport->ipg_clk);
+ return 0;
+}
+
static void lpuart_stop_tx(struct uart_port *port)
{
unsigned char temp;
@@ -350,19 +418,46 @@ static void lpuart32_stop_rx(struct uart_port *port)
lpuart32_write(port, temp & ~UARTCTRL_RE, UARTCTRL);
}
+static void lpuart_recal_min_trans_size(struct lpuart_port *sport)
+{
+ struct circ_buf *xmit = &sport->port.state->xmit;
+ u32 txcount, rxcount;
+
+ sport->dma_tx_bytes = uart_circ_chars_pending(xmit);
+
+ /* lpuart32 and loopback mode re-calculate the trans size */
+ if (!lpuart_is_32(sport) || !(sport->port.mctrl & TIOCM_LOOP))
+ return;
+
+ txcount = lpuart32_read(&sport->port, UARTWATER);
+ txcount = txcount >> UARTWATER_TXCNT_OFF;
+ txcount &= UARTWATER_COUNT_MASK;
+ rxcount = lpuart32_read(&sport->port, UARTWATER);
+ rxcount = rxcount >> UARTWATER_RXCNT_OFF;
+ txcount = min_t(unsigned int, sport->txfifo_size - txcount,
+ sport->rxfifo_size - rxcount);
+ sport->dma_tx_bytes = min_t(unsigned int, txcount, sport->dma_tx_bytes);
+}
+
static void lpuart_dma_tx(struct lpuart_port *sport)
{
struct circ_buf *xmit = &sport->port.state->xmit;
struct scatterlist *sgl = sport->tx_sgl;
struct device *dev = sport->port.dev;
+ u32 toend_cnt;
int ret;
if (sport->dma_tx_in_progress)
return;
- sport->dma_tx_bytes = uart_circ_chars_pending(xmit);
+ lpuart_recal_min_trans_size(sport);
+ if (!sport->dma_tx_bytes)
+ return;
- if (xmit->tail < xmit->head || xmit->head == 0) {
+ toend_cnt = CIRC_CNT_TO_END(xmit->head, xmit->tail, UART_XMIT_SIZE);
+
+ if (xmit->tail < xmit->head || xmit->head == 0 ||
+ (sport->port.mctrl & TIOCM_LOOP && sport->dma_tx_bytes <= toend_cnt)) {
sport->dma_tx_nents = 1;
sg_init_one(sgl, xmit->buf + xmit->tail, sport->dma_tx_bytes);
} else {
@@ -370,7 +465,8 @@ static void lpuart_dma_tx(struct lpuart_port *sport)
sg_init_table(sgl, 2);
sg_set_buf(sgl, xmit->buf + xmit->tail,
UART_XMIT_SIZE - xmit->tail);
- sg_set_buf(sgl + 1, xmit->buf, xmit->head);
+ sg_set_buf(sgl + 1, xmit->buf, sport->dma_tx_bytes -
+ (UART_XMIT_SIZE - xmit->tail));
}
ret = dma_map_sg(dev, sgl, sport->dma_tx_nents, DMA_TO_DEVICE);
@@ -403,6 +499,10 @@ static void lpuart_dma_tx_complete(void *arg)
unsigned long flags;
spin_lock_irqsave(&sport->port.lock, flags);
+ if (!sport->dma_tx_in_progress) {
+ spin_unlock_irqrestore(&sport->port.lock, flags);
+ return;
+ }
dma_unmap_sg(sport->port.dev, sgl, sport->dma_tx_nents, DMA_TO_DEVICE);
@@ -410,18 +510,16 @@ static void lpuart_dma_tx_complete(void *arg)
sport->port.icount.tx += sport->dma_tx_bytes;
sport->dma_tx_in_progress = false;
- spin_unlock_irqrestore(&sport->port.lock, flags);
if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
uart_write_wakeup(&sport->port);
if (waitqueue_active(&sport->dma_wait)) {
wake_up(&sport->dma_wait);
+ spin_unlock_irqrestore(&sport->port.lock, flags);
return;
}
- spin_lock_irqsave(&sport->port.lock, flags);
-
if (!uart_circ_empty(xmit) && !uart_tx_stopped(&sport->port))
lpuart_dma_tx(sport);
@@ -435,15 +533,18 @@ static int lpuart_dma_tx_request(struct uart_port *port)
struct dma_slave_config dma_tx_sconfig = {};
int ret;
- dma_tx_sconfig.dst_addr = sport->port.mapbase + UARTDR;
+ if (lpuart_is_32(sport))
+ dma_tx_sconfig.dst_addr = sport->port.mapbase + UARTDATA;
+ else
+ dma_tx_sconfig.dst_addr = sport->port.mapbase + UARTDR;
dma_tx_sconfig.dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
dma_tx_sconfig.dst_maxburst = 1;
dma_tx_sconfig.direction = DMA_MEM_TO_DEV;
ret = dmaengine_slave_config(sport->dma_tx_chan, &dma_tx_sconfig);
- if (ret) {
+ if (ret < 0) {
dev_err(sport->port.dev,
- "DMA slave config failed, err = %d\n", ret);
+ "Dma slave config failed, err = %d\n", ret);
return ret;
}
@@ -453,6 +554,7 @@ static int lpuart_dma_tx_request(struct uart_port *port)
static void lpuart_flush_buffer(struct uart_port *port)
{
struct lpuart_port *sport = container_of(port, struct lpuart_port, port);
+ u32 val;
if (sport->lpuart_dma_tx_use) {
if (sport->dma_tx_in_progress) {
@@ -462,6 +564,16 @@ static void lpuart_flush_buffer(struct uart_port *port)
}
dmaengine_terminate_all(sport->dma_tx_chan);
}
+
+ if (lpuart_is_32(sport)) {
+ val = lpuart32_read(&sport->port, UARTFIFO);
+ val |= UARTFIFO_TXFLUSH | UARTFIFO_RXFLUSH;
+ lpuart32_write(&sport->port, val, UARTFIFO);
+ } else {
+ val = readb(sport->port.membase + UARTPFIFO);
+ val |= UARTCFIFO_TXFLUSH | UARTCFIFO_RXFLUSH;
+ writeb(val, sport->port.membase + UARTCFIFO);
+ }
}
#if defined(CONFIG_CONSOLE_POLL)
@@ -623,13 +735,13 @@ static void lpuart_start_tx(struct uart_port *port)
struct circ_buf *xmit = &sport->port.state->xmit;
unsigned char temp;
- temp = readb(port->membase + UARTCR2);
- writeb(temp | UARTCR2_TIE, port->membase + UARTCR2);
-
if (sport->lpuart_dma_tx_use) {
if (!uart_circ_empty(xmit) && !uart_tx_stopped(port))
lpuart_dma_tx(sport);
} else {
+ temp = readb(port->membase + UARTCR2);
+ writeb(temp | UARTCR2_TIE, port->membase + UARTCR2);
+
if (readb(port->membase + UARTSR1) & UARTSR1_TDRE)
lpuart_transmit_buffer(sport);
}
@@ -638,13 +750,32 @@ static void lpuart_start_tx(struct uart_port *port)
static void lpuart32_start_tx(struct uart_port *port)
{
struct lpuart_port *sport = container_of(port, struct lpuart_port, port);
+ struct circ_buf *xmit = &sport->port.state->xmit;
unsigned long temp;
- temp = lpuart32_read(port, UARTCTRL);
- lpuart32_write(port, temp | UARTCTRL_TIE, UARTCTRL);
+ if (sport->lpuart_dma_tx_use) {
+ if (!uart_circ_empty(xmit) && !uart_tx_stopped(port))
+ lpuart_dma_tx(sport);
+ } else {
+ temp = lpuart32_read(port, UARTCTRL);
+ lpuart32_write(port, temp | UARTCTRL_TIE, UARTCTRL);
+ if (lpuart32_read(&sport->port, UARTSTAT) & UARTSTAT_TDRE)
+ lpuart32_transmit_buffer(sport);
+ }
+}
- if (lpuart32_read(port, UARTSTAT) & UARTSTAT_TDRE)
- lpuart32_transmit_buffer(sport);
+static void
+lpuart_uart_pm(struct uart_port *port, unsigned int state, unsigned int oldstate)
+{
+ switch (state) {
+ case UART_PM_STATE_OFF:
+ pm_runtime_mark_last_busy(port->dev);
+ pm_runtime_put_autosuspend(port->dev);
+ break;
+ default:
+ pm_runtime_get_sync(port->dev);
+ break;
+ }
}
/* return TIOCSER_TEMT when transmitter is not busy */
@@ -666,14 +797,18 @@ static unsigned int lpuart_tx_empty(struct uart_port *port)
static unsigned int lpuart32_tx_empty(struct uart_port *port)
{
- return (lpuart32_read(port, UARTSTAT) & UARTSTAT_TC) ?
- TIOCSER_TEMT : 0;
-}
+ struct lpuart_port *sport = container_of(port,
+ struct lpuart_port, port);
+ unsigned int sr1 = lpuart32_read(port, UARTSTAT);
+ unsigned int sfifo = lpuart32_read(port, UARTFIFO);
-static bool lpuart_is_32(struct lpuart_port *sport)
-{
- return sport->port.iotype == UPIO_MEM32 ||
- sport->port.iotype == UPIO_MEM32BE;
+ if (sport->dma_tx_in_progress)
+ return 0;
+
+ if (sr1 & UARTSTAT_TC && sfifo & UARTFIFO_TXEMPT)
+ return TIOCSER_TEMT;
+
+ return 0;
}
static irqreturn_t lpuart_txint(int irq, void *dev_id)
@@ -788,13 +923,19 @@ static irqreturn_t lpuart32_rxint(int irq, void *dev_id)
while (!(lpuart32_read(&sport->port, UARTFIFO) & UARTFIFO_RXEMPT)) {
flg = TTY_NORMAL;
sport->port.icount.rx++;
+
/*
* to clear the FE, OR, NF, FE, PE flags,
* read STAT then read DATA reg
*/
sr = lpuart32_read(&sport->port, UARTSTAT);
rx = lpuart32_read(&sport->port, UARTDATA);
- rx &= 0x3ff;
+
+ if ((sr & UARTSTAT_FE) && (rx & UARTDATA_FRETSC) &&
+ !(rx & UARTDATA_MASK)) {
+ if (uart_handle_break(&sport->port))
+ continue;
+ }
if (uart_handle_sysrq_char(&sport->port, (unsigned char)rx))
continue;
@@ -827,8 +968,13 @@ static irqreturn_t lpuart32_rxint(int irq, void *dev_id)
#ifdef SUPPORT_SYSRQ
sport->port.sysrq = 0;
#endif
+ continue;
}
+ if (rx & UARTDATA_INVALID)
+ continue;
+
+ rx &= UARTDATA_MASK;
tty_insert_flip_char(port, rx, flg);
}
@@ -842,14 +988,19 @@ out:
static irqreturn_t lpuart_int(int irq, void *dev_id)
{
struct lpuart_port *sport = dev_id;
- unsigned char sts;
+ unsigned char sts, crdma;
sts = readb(sport->port.membase + UARTSR1);
+ crdma = readb(sport->port.membase + UARTCR5);
- if (sts & UARTSR1_RDRF)
- lpuart_rxint(irq, dev_id);
+ if (sts & UARTSR1_RDRF && !(crdma & UARTCR5_RDMAS)) {
+ if (sport->lpuart_dma_rx_use)
+ lpuart_prepare_rx(sport);
+ else
+ lpuart_rxint(irq, dev_id);
+ }
- if (sts & UARTSR1_TDRE)
+ if (sts & UARTSR1_TDRE && !sport->lpuart_dma_tx_use)
lpuart_txint(irq, dev_id);
return IRQ_HANDLED;
@@ -858,196 +1009,163 @@ static irqreturn_t lpuart_int(int irq, void *dev_id)
static irqreturn_t lpuart32_int(int irq, void *dev_id)
{
struct lpuart_port *sport = dev_id;
- unsigned long sts, rxcount;
+ unsigned long sts, rxcount, crdma;
sts = lpuart32_read(&sport->port, UARTSTAT);
rxcount = lpuart32_read(&sport->port, UARTWATER);
rxcount = rxcount >> UARTWATER_RXCNT_OFF;
+ crdma = lpuart32_read(&sport->port, UARTBAUD);
+
+ if (!sts)
+ return IRQ_NONE;
+
+ if (!(crdma & UARTBAUD_RDMAE) && rxcount > 0) {
+ if (!sport->lpuart_dma_rx_use ||
+ (sts & (UARTSTAT_PE | UARTSTAT_NF | UARTSTAT_FE)))
+ lpuart32_rxint(irq, dev_id);
+ else if (sport->lpuart_dma_rx_use && sport->dma_rx_chan_active)
+ lpuart_prepare_rx(sport);
+ } else if (!(crdma & UARTBAUD_RDMAE) && (sts & UARTSTAT_IDLE) &&
+ !(sport->lpuart_dma_rx_use && sport->dma_eeop &&
+ rxcount > 0)) {
+ lpuart32_write(&sport->port, UARTSTAT_IDLE, UARTSTAT);
+ }
- if (sts & UARTSTAT_RDRF || rxcount > 0)
- lpuart32_rxint(irq, dev_id);
-
- if ((sts & UARTSTAT_TDRE) &&
- !(lpuart32_read(&sport->port, UARTBAUD) & UARTBAUD_TDMAE))
+ if (sts & UARTSTAT_TDRE && !sport->lpuart_dma_tx_use)
lpuart_txint(irq, dev_id);
+ sts &= ~UARTSTAT_IDLE;
lpuart32_write(&sport->port, sts, UARTSTAT);
return IRQ_HANDLED;
}
-static void lpuart_copy_rx_to_tty(struct lpuart_port *sport)
+static void lpuart_copy_rx_to_tty(struct lpuart_port *sport,
+ struct tty_port *tty, int count)
{
- struct tty_port *port = &sport->port.state->port;
- struct dma_tx_state state;
- enum dma_status dmastat;
- struct circ_buf *ring = &sport->rx_ring;
- unsigned long flags;
- int count = 0;
- unsigned char sr;
-
- sr = readb(sport->port.membase + UARTSR1);
-
- if (sr & (UARTSR1_PE | UARTSR1_FE)) {
- /* Read DR to clear the error flags */
- readb(sport->port.membase + UARTDR);
+ int copied;
- if (sr & UARTSR1_PE)
- sport->port.icount.parity++;
- else if (sr & UARTSR1_FE)
- sport->port.icount.frame++;
- }
-
- async_tx_ack(sport->dma_rx_desc);
-
- spin_lock_irqsave(&sport->port.lock, flags);
+ sport->port.icount.rx += count;
- dmastat = dmaengine_tx_status(sport->dma_rx_chan,
- sport->dma_rx_cookie,
- &state);
-
- if (dmastat == DMA_ERROR) {
- dev_err(sport->port.dev, "Rx DMA transfer failed!\n");
- spin_unlock_irqrestore(&sport->port.lock, flags);
+ if (!tty) {
+ dev_err(sport->port.dev, "No tty port\n");
return;
}
- /* CPU claims ownership of RX DMA buffer */
- dma_sync_sg_for_cpu(sport->port.dev, &sport->rx_sgl, 1, DMA_FROM_DEVICE);
+ dma_sync_single_for_cpu(sport->port.dev, sport->dma_rx_buf_bus,
+ sport->rxdma_len, DMA_FROM_DEVICE);
+ copied = tty_insert_flip_string(tty,
+ ((unsigned char *)(sport->dma_rx_buf_virt)), count);
- /*
- * ring->head points to the end of data already written by the DMA.
- * ring->tail points to the beginning of data to be read by the
- * framework.
- * The current transfer size should not be larger than the dma buffer
- * length.
- */
- ring->head = sport->rx_sgl.length - state.residue;
- BUG_ON(ring->head > sport->rx_sgl.length);
- /*
- * At this point ring->head may point to the first byte right after the
- * last byte of the dma buffer:
- * 0 <= ring->head <= sport->rx_sgl.length
- *
- * However ring->tail must always points inside the dma buffer:
- * 0 <= ring->tail <= sport->rx_sgl.length - 1
- *
- * Since we use a ring buffer, we have to handle the case
- * where head is lower than tail. In such a case, we first read from
- * tail to the end of the buffer then reset tail.
- */
- if (ring->head < ring->tail) {
- count = sport->rx_sgl.length - ring->tail;
+ if (copied != count)
+ sport->port.icount.buf_overrun += count - copied;
+ sport->port.icount.rx += copied;
+}
- tty_insert_flip_string(port, ring->buf + ring->tail, count);
- ring->tail = 0;
- sport->port.icount.rx += count;
- }
+static void lpuart_dma_stop(struct lpuart_port *sport, bool enable_pio)
+{
+ unsigned int temp;
+ unsigned int crdma;
- /* Finally we read data from tail to head */
- if (ring->tail < ring->head) {
- count = ring->head - ring->tail;
- tty_insert_flip_string(port, ring->buf + ring->tail, count);
- /* Wrap ring->head if needed */
- if (ring->head >= sport->rx_sgl.length)
- ring->head = 0;
- ring->tail = ring->head;
- sport->port.icount.rx += count;
+ if (lpuart_is_32(sport)) {
+ lpuart32_write(&sport->port, UARTSTAT_IDLE, UARTSTAT);
+ crdma = lpuart32_read(&sport->port, UARTBAUD);
+ lpuart32_write(&sport->port, crdma & ~(UARTBAUD_RDMAE | UARTBAUD_RIDMAE),
+ UARTBAUD);
+ if (enable_pio) {
+ temp = lpuart32_read(&sport->port, UARTCTRL);
+ temp |= (UARTCTRL_RIE | UARTCTRL_ILIE);
+ lpuart32_write(&sport->port, temp, UARTCTRL);
+ }
+ } else {
+ temp = readb(sport->port.membase + UARTCR5);
+ writeb(temp & ~UARTCR5_RDMAS, sport->port.membase + UARTCR5);
}
+}
+
+static void lpuart_dma_rx_complete(void *arg)
+{
+ struct lpuart_port *sport = arg;
+ struct tty_port *port = &sport->port.state->port;
+ unsigned long flags;
+ struct dma_tx_state state;
+ int count, rxcount;
- dma_sync_sg_for_device(sport->port.dev, &sport->rx_sgl, 1,
- DMA_FROM_DEVICE);
+ if (!sport->dma_eeop)
+ mod_timer(&sport->lpuart_timer,
+ jiffies + sport->dma_rx_timeout);
+ spin_lock_irqsave(&sport->port.lock, flags);
+ sport->dma_rx_in_progress = false;
+ dmaengine_tx_status(sport->dma_rx_chan, sport->dma_rx_cookie, &state);
+ count = sport->rxdma_len - state.residue;
spin_unlock_irqrestore(&sport->port.lock, flags);
+ lpuart_copy_rx_to_tty(sport, port, count);
tty_flip_buffer_push(port);
- mod_timer(&sport->lpuart_timer, jiffies + sport->dma_rx_timeout);
-}
-static void lpuart_dma_rx_complete(void *arg)
-{
- struct lpuart_port *sport = arg;
+ spin_lock_irqsave(&sport->port.lock, flags);
- lpuart_copy_rx_to_tty(sport);
-}
+ /* For end of packet, clear the idle flag to avoid to trigger
+ * the next transfer. Only i.MX8x lpuart support EEOP.
+ */
+ if (sport->dma_eeop && lpuart_is_32(sport)) {
+ rxcount = lpuart32_read(&sport->port, UARTWATER);
+ rxcount = rxcount >> UARTWATER_RXCNT_OFF;
+ if (!rxcount)
+ lpuart32_write(&sport->port, UARTSTAT_IDLE, UARTSTAT);
+ }
-static void lpuart_timer_func(unsigned long data)
-{
- struct lpuart_port *sport = (struct lpuart_port *)data;
+ if (!sport->dma_eeop && count < sport->rxfifo_watermark)
+ lpuart_dma_stop(sport, true);
+ else
+ lpuart_dma_rx(sport);
- lpuart_copy_rx_to_tty(sport);
+ spin_unlock_irqrestore(&sport->port.lock, flags);
}
-static inline int lpuart_start_rx_dma(struct lpuart_port *sport)
+static void lpuart_timer_func(unsigned long data)
{
- struct dma_slave_config dma_rx_sconfig = {};
- struct circ_buf *ring = &sport->rx_ring;
- int ret, nent;
- int bits, baud;
+ struct lpuart_port *sport = (struct lpuart_port *)data;
struct tty_port *port = &sport->port.state->port;
- struct tty_struct *tty = port->tty;
- struct ktermios *termios = &tty->termios;
-
- baud = tty_get_baud_rate(tty);
-
- bits = (termios->c_cflag & CSIZE) == CS7 ? 9 : 10;
- if (termios->c_cflag & PARENB)
- bits++;
+ struct dma_tx_state state;
+ unsigned long flags;
+ int count;
- /*
- * Calculate length of one DMA buffer size to keep latency below
- * 10ms at any baud rate.
- */
- sport->rx_dma_rng_buf_len = (DMA_RX_TIMEOUT * baud / bits / 1000) * 2;
- sport->rx_dma_rng_buf_len = (1 << (fls(sport->rx_dma_rng_buf_len) - 1));
- if (sport->rx_dma_rng_buf_len < 16)
- sport->rx_dma_rng_buf_len = 16;
-
- ring->buf = kmalloc(sport->rx_dma_rng_buf_len, GFP_ATOMIC);
- if (!ring->buf) {
- dev_err(sport->port.dev, "Ring buf alloc failed\n");
- return -ENOMEM;
- }
+ del_timer(&sport->lpuart_timer);
+ dmaengine_pause(sport->dma_rx_chan);
+ dmaengine_tx_status(sport->dma_rx_chan, sport->dma_rx_cookie, &state);
+ dmaengine_terminate_all(sport->dma_rx_chan);
+ count = sport->rxdma_len - state.residue;
- sg_init_one(&sport->rx_sgl, ring->buf, sport->rx_dma_rng_buf_len);
- sg_set_buf(&sport->rx_sgl, ring->buf, sport->rx_dma_rng_buf_len);
- nent = dma_map_sg(sport->port.dev, &sport->rx_sgl, 1, DMA_FROM_DEVICE);
+ spin_lock_irqsave(&sport->port.lock, flags);
- if (!nent) {
- dev_err(sport->port.dev, "DMA Rx mapping error\n");
- return -EINVAL;
- }
+ sport->dma_rx_in_progress = false;
+ lpuart_copy_rx_to_tty(sport, port, count);
+ tty_flip_buffer_push(port);
+ lpuart_dma_stop(sport, true);
- dma_rx_sconfig.src_addr = sport->port.mapbase + UARTDR;
- dma_rx_sconfig.src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
- dma_rx_sconfig.src_maxburst = 1;
- dma_rx_sconfig.direction = DMA_DEV_TO_MEM;
- ret = dmaengine_slave_config(sport->dma_rx_chan, &dma_rx_sconfig);
+ spin_unlock_irqrestore(&sport->port.lock, flags);
+}
- if (ret < 0) {
- dev_err(sport->port.dev,
- "DMA Rx slave config failed, err = %d\n", ret);
- return ret;
- }
+static int lpuart_dma_rx(struct lpuart_port *sport)
+{
+ dma_sync_single_for_device(sport->port.dev, sport->dma_rx_buf_bus,
+ sport->rxdma_len, DMA_FROM_DEVICE);
+ sport->dma_rx_desc = dmaengine_prep_slave_single(sport->dma_rx_chan,
+ sport->dma_rx_buf_bus, sport->rxdma_len,
+ DMA_DEV_TO_MEM, DMA_PREP_INTERRUPT);
- sport->dma_rx_desc = dmaengine_prep_dma_cyclic(sport->dma_rx_chan,
- sg_dma_address(&sport->rx_sgl),
- sport->rx_sgl.length,
- sport->rx_sgl.length / 2,
- DMA_DEV_TO_MEM,
- DMA_PREP_INTERRUPT);
if (!sport->dma_rx_desc) {
- dev_err(sport->port.dev, "Cannot prepare cyclic DMA\n");
- return -EFAULT;
+ dev_err(sport->port.dev, "Not able to get desc for rx\n");
+ return -EIO;
}
sport->dma_rx_desc->callback = lpuart_dma_rx_complete;
sport->dma_rx_desc->callback_param = sport;
+ sport->dma_rx_in_progress = true;
sport->dma_rx_cookie = dmaengine_submit(sport->dma_rx_desc);
dma_async_issue_pending(sport->dma_rx_chan);
- writeb(readb(sport->port.membase + UARTCR5) | UARTCR5_RDMAS,
- sport->port.membase + UARTCR5);
-
return 0;
}
@@ -1056,15 +1174,43 @@ static void lpuart_dma_rx_free(struct uart_port *port)
struct lpuart_port *sport = container_of(port,
struct lpuart_port, port);
- if (sport->dma_rx_chan)
- dmaengine_terminate_all(sport->dma_rx_chan);
+ sport->dma_rx_chan_active = false;
+ dma_unmap_single(sport->port.dev, sport->dma_rx_buf_bus,
+ sport->rxdma_len, DMA_FROM_DEVICE);
+
+ devm_kfree(sport->port.dev, sport->dma_rx_buf_virt);
+ sport->dma_rx_buf_bus = 0;
+ sport->dma_rx_buf_virt = NULL;
+}
- dma_unmap_sg(sport->port.dev, &sport->rx_sgl, 1, DMA_FROM_DEVICE);
- kfree(sport->rx_ring.buf);
- sport->rx_ring.tail = 0;
- sport->rx_ring.head = 0;
- sport->dma_rx_desc = NULL;
- sport->dma_rx_cookie = -EINVAL;
+static inline void lpuart_prepare_rx(struct lpuart_port *sport)
+{
+ unsigned long flags;
+ unsigned int temp;
+ unsigned int crdma;
+
+ spin_lock_irqsave(&sport->port.lock, flags);
+
+ if (!sport->dma_eeop) {
+ sport->lpuart_timer.expires = jiffies + sport->dma_rx_timeout;
+ add_timer(&sport->lpuart_timer);
+ }
+
+ lpuart_dma_rx(sport);
+ if (lpuart_is_32(sport)) {
+ temp = lpuart32_read(&sport->port, UARTCTRL);
+ temp &= ~(UARTCTRL_RIE | UARTCTRL_ILIE);
+ lpuart32_write(&sport->port, temp, UARTCTRL);
+ crdma = lpuart32_read(&sport->port, UARTBAUD);
+ if (sport->dma_eeop)
+ crdma |= UARTBAUD_RIDMAE;
+ lpuart32_write(&sport->port, crdma | UARTBAUD_RDMAE, UARTBAUD);
+ } else {
+ temp = readb(sport->port.membase + UARTCR5);
+ writeb(temp | UARTCR5_RDMAS, sport->port.membase + UARTCR5);
+ }
+
+ spin_unlock_irqrestore(&sport->port.lock, flags);
}
static int lpuart_config_rs485(struct uart_port *port,
@@ -1145,11 +1291,15 @@ static unsigned int lpuart32_get_mctrl(struct uart_port *port)
if (reg & UARTMODIR_RXRTSE)
temp |= TIOCM_RTS;
+ if (lpuart32_read(port, UARTCTRL) & UARTCTRL_LOOPS)
+ temp |= TIOCM_LOOP;
+
return temp;
}
static void lpuart_set_mctrl(struct uart_port *port, unsigned int mctrl)
{
+ /* No flow control for user handle */
unsigned char temp;
struct lpuart_port *sport = container_of(port,
struct lpuart_port, port);
@@ -1173,16 +1323,13 @@ static void lpuart32_set_mctrl(struct uart_port *port, unsigned int mctrl)
{
unsigned long temp;
- temp = lpuart32_read(port, UARTMODIR) &
- ~(UARTMODIR_RXRTSE | UARTMODIR_TXCTSE);
-
- if (mctrl & TIOCM_RTS)
- temp |= UARTMODIR_RXRTSE;
-
- if (mctrl & TIOCM_CTS)
- temp |= UARTMODIR_TXCTSE;
+ temp = lpuart32_read(port, UARTCTRL);
+ if (mctrl & TIOCM_LOOP)
+ temp |= UARTCTRL_LOOPS;
+ else
+ temp &= ~UARTCTRL_LOOPS;
- lpuart32_write(port, temp, UARTMODIR);
+ lpuart32_write(port, temp, UARTCTRL);
}
static void lpuart_break_ctl(struct uart_port *port, int break_state)
@@ -1245,6 +1392,7 @@ static void lpuart32_setup_watermark(struct lpuart_port *sport)
{
unsigned long val, ctrl;
unsigned long ctrl_saved;
+ unsigned long rxiden_cnt = UARTFIFO_RXIDEN_RDRF;
ctrl = lpuart32_read(&sport->port, UARTCTRL);
ctrl_saved = ctrl;
@@ -1256,22 +1404,77 @@ static void lpuart32_setup_watermark(struct lpuart_port *sport)
val = lpuart32_read(&sport->port, UARTFIFO);
val |= UARTFIFO_TXFE | UARTFIFO_RXFE;
val |= UARTFIFO_TXFLUSH | UARTFIFO_RXFLUSH;
+ val &= ~(UARTFIFO_RXIDEN_MASK << UARTFIFO_RXIDEN_OFF);
+ if (sport->dma_eeop)
+ rxiden_cnt = 0;
+ val |= ((rxiden_cnt & UARTFIFO_RXIDEN_MASK) <<
+ UARTFIFO_RXIDEN_OFF);
lpuart32_write(&sport->port, val, UARTFIFO);
/* set the watermark */
- val = (0x1 << UARTWATER_RXWATER_OFF) | (0x0 << UARTWATER_TXWATER_OFF);
+ if (uart_console(&sport->port)) {
+ val = (0x1 << UARTWATER_RXWATER_OFF) |
+ (0x0 << UARTWATER_TXWATER_OFF);
+ } else {
+ val = lpuart32_read(&sport->port, UARTMODIR);
+ val = sport->rts_watermark << UARTMODIR_RTSWATER_S;
+ lpuart32_write(&sport->port, val, UARTMODIR);
+ val = (sport->rxfifo_watermark << UARTWATER_RXWATER_OFF) |
+ (sport->txfifo_watermark << UARTWATER_TXWATER_OFF);
+ }
lpuart32_write(&sport->port, val, UARTWATER);
/* Restore cr2 */
lpuart32_write(&sport->port, ctrl_saved, UARTCTRL);
}
-static void rx_dma_timer_init(struct lpuart_port *sport)
+static int lpuart_dma_rx_request(struct uart_port *port)
{
- setup_timer(&sport->lpuart_timer, lpuart_timer_func,
- (unsigned long)sport);
- sport->lpuart_timer.expires = jiffies + sport->dma_rx_timeout;
- add_timer(&sport->lpuart_timer);
+ struct lpuart_port *sport = container_of(port,
+ struct lpuart_port, port);
+ struct dma_slave_config dma_rx_sconfig;
+ dma_addr_t dma_bus;
+ unsigned char *dma_buf;
+ int ret;
+
+ dma_buf = devm_kzalloc(sport->port.dev,
+ sport->rxdma_len, GFP_KERNEL);
+
+ if (!dma_buf) {
+ dev_err(sport->port.dev, "Dma rx alloc failed\n");
+ return -ENOMEM;
+ }
+
+ dma_bus = dma_map_single(sport->port.dev, dma_buf,
+ sport->rxdma_len, DMA_FROM_DEVICE);
+
+ if (dma_mapping_error(sport->port.dev, dma_bus)) {
+ dev_err(sport->port.dev, "dma_map_single rx failed\n");
+ return -ENOMEM;
+ }
+
+ if (lpuart_is_32(sport))
+ dma_rx_sconfig.src_addr = sport->port.mapbase + UARTDATA;
+ else
+ dma_rx_sconfig.src_addr = sport->port.mapbase + UARTDR;
+
+ dma_rx_sconfig.src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
+ dma_rx_sconfig.src_maxburst = 1;
+ dma_rx_sconfig.direction = DMA_DEV_TO_MEM;
+ ret = dmaengine_slave_config(sport->dma_rx_chan, &dma_rx_sconfig);
+
+ if (ret < 0) {
+ dev_err(sport->port.dev,
+ "Dma slave config failed, err = %d\n", ret);
+ return ret;
+ }
+
+ sport->dma_rx_buf_virt = dma_buf;
+ sport->dma_rx_buf_bus = dma_bus;
+ sport->dma_rx_in_progress = false;
+ sport->dma_rx_chan_active = true;
+
+ return 0;
}
static int lpuart_startup(struct uart_port *port)
@@ -1290,63 +1493,95 @@ static int lpuart_startup(struct uart_port *port)
sport->rxfifo_size = 0x1 << (((temp >> UARTPFIFO_RXSIZE_OFF) &
UARTPFIFO_FIFOSIZE_MASK) + 1);
+ sport->rxdma_len = FSL_UART_RX_DMA_BUFFER_SIZE;
- spin_lock_irqsave(&sport->port.lock, flags);
-
- lpuart_setup_watermark(sport);
-
- temp = readb(sport->port.membase + UARTCR2);
- temp |= (UARTCR2_RIE | UARTCR2_TIE | UARTCR2_RE | UARTCR2_TE);
- writeb(temp, sport->port.membase + UARTCR2);
-
- if (sport->dma_rx_chan && !lpuart_start_rx_dma(sport)) {
- /* set Rx DMA timeout */
- sport->dma_rx_timeout = msecs_to_jiffies(DMA_RX_TIMEOUT);
- if (!sport->dma_rx_timeout)
- sport->dma_rx_timeout = 1;
-
+ if (sport->dma_rx_chan && !lpuart_dma_rx_request(port)) {
sport->lpuart_dma_rx_use = true;
- rx_dma_timer_init(sport);
- } else {
+ setup_timer(&sport->lpuart_timer, lpuart_timer_func,
+ (unsigned long)sport);
+ } else
sport->lpuart_dma_rx_use = false;
- }
+
if (sport->dma_tx_chan && !lpuart_dma_tx_request(port)) {
init_waitqueue_head(&sport->dma_wait);
sport->lpuart_dma_tx_use = true;
temp = readb(port->membase + UARTCR5);
+ temp &= ~UARTCR5_RDMAS;
writeb(temp | UARTCR5_TDMAS, port->membase + UARTCR5);
- } else {
+ } else
sport->lpuart_dma_tx_use = false;
- }
- spin_unlock_irqrestore(&sport->port.lock, flags);
+ spin_lock_irqsave(&sport->port.lock, flags);
+
+ lpuart_setup_watermark(sport);
+ temp = readb(sport->port.membase + UARTCR2);
+ temp |= (UARTCR2_RIE | UARTCR2_RE | UARTCR2_TE);
+ writeb(temp, sport->port.membase + UARTCR2);
+
+ spin_unlock_irqrestore(&sport->port.lock, flags);
return 0;
}
static int lpuart32_startup(struct uart_port *port)
{
struct lpuart_port *sport = container_of(port, struct lpuart_port, port);
+ struct tty_port *tty_port = &sport->port.state->port;
unsigned long flags;
unsigned long temp;
+ int ret;
+
+ /* some modem may need reset */
+ if (!tty_port_suspended(tty_port)) {
+ ret = device_reset(sport->port.dev);
+ if (ret && ret != -ENOENT)
+ return ret;
+ }
/* determine FIFO size */
temp = lpuart32_read(&sport->port, UARTFIFO);
sport->txfifo_size = 0x1 << (((temp >> UARTFIFO_TXSIZE_OFF) &
- UARTFIFO_FIFOSIZE_MASK) - 1);
+ UARTFIFO_FIFOSIZE_MASK) + 1);
+
+ sport->port.fifosize = sport->txfifo_size;
sport->rxfifo_size = 0x1 << (((temp >> UARTFIFO_RXSIZE_OFF) &
- UARTFIFO_FIFOSIZE_MASK) - 1);
+ UARTFIFO_FIFOSIZE_MASK) + 1);
+
+ sport->txfifo_watermark = sport->txfifo_size >> 1;
+ sport->rxfifo_watermark = 1;
+ sport->rts_watermark = sport->rxfifo_size >> 1;
+ sport->rxdma_len = FSL_UART_RX_DMA_BUFFER_SIZE;
+
+ if (sport->dma_rx_chan && !lpuart_dma_rx_request(port)) {
+ sport->lpuart_dma_rx_use = true;
+ if (!sport->dma_eeop)
+ setup_timer(&sport->lpuart_timer,
+ lpuart_timer_func,
+ (unsigned long)sport);
+ } else
+ sport->lpuart_dma_rx_use = false;
+
+
+ if (sport->dma_tx_chan && !lpuart_dma_tx_request(port)) {
+ init_waitqueue_head(&sport->dma_wait);
+ sport->lpuart_dma_tx_use = true;
+ temp = lpuart32_read(&sport->port, UARTBAUD);
+ temp |= UARTBAUD_TDMAE;
+ lpuart32_write(&sport->port, temp, UARTBAUD);
+ } else
+ sport->lpuart_dma_tx_use = false;
spin_lock_irqsave(&sport->port.lock, flags);
lpuart32_setup_watermark(sport);
temp = lpuart32_read(&sport->port, UARTCTRL);
- temp |= (UARTCTRL_RIE | UARTCTRL_TIE | UARTCTRL_RE | UARTCTRL_TE);
+ temp |= (UARTCTRL_RIE | UARTCTRL_RE | UARTCTRL_TE);
temp |= UARTCTRL_ILIE;
+ temp |= UARTCTRL_IDLECFG << UARTCTRL_IDLECFG_OFF;
lpuart32_write(&sport->port, temp, UARTCTRL);
spin_unlock_irqrestore(&sport->port.lock, flags);
@@ -1358,6 +1593,7 @@ static void lpuart_shutdown(struct uart_port *port)
struct lpuart_port *sport = container_of(port, struct lpuart_port, port);
unsigned char temp;
unsigned long flags;
+ int ret;
spin_lock_irqsave(&port->lock, flags);
@@ -1370,35 +1606,66 @@ static void lpuart_shutdown(struct uart_port *port)
spin_unlock_irqrestore(&port->lock, flags);
if (sport->lpuart_dma_rx_use) {
+ sport->dma_rx_in_progress = false;
+ dmaengine_terminate_all(sport->dma_rx_chan);
del_timer_sync(&sport->lpuart_timer);
lpuart_dma_rx_free(&sport->port);
}
if (sport->lpuart_dma_tx_use) {
- if (wait_event_interruptible(sport->dma_wait,
- !sport->dma_tx_in_progress) != false) {
+ ret = wait_event_interruptible_timeout(sport->dma_wait,
+ !sport->dma_tx_in_progress, msecs_to_jiffies(1));
+ if (ret <= 0) {
sport->dma_tx_in_progress = false;
dmaengine_terminate_all(sport->dma_tx_chan);
}
-
- lpuart_stop_tx(port);
}
}
static void lpuart32_shutdown(struct uart_port *port)
{
+ struct lpuart_port *sport = container_of(port, struct lpuart_port, port);
unsigned long temp;
unsigned long flags;
+ int ret;
spin_lock_irqsave(&port->lock, flags);
+ /* clear statue */
+ temp = lpuart32_read(&sport->port, UARTSTAT);
+ lpuart32_write(&sport->port, temp, UARTSTAT);
+
+ /* disable Rx/Tx DMA */
+ temp = lpuart32_read(port, UARTBAUD);
+ temp &= ~(UARTBAUD_TDMAE | UARTBAUD_RDMAE | UARTBAUD_RIDMAE);
+ lpuart32_write(port, temp, UARTBAUD);
+
/* disable Rx/Tx and interrupts */
temp = lpuart32_read(port, UARTCTRL);
- temp &= ~(UARTCTRL_TE | UARTCTRL_RE |
- UARTCTRL_TIE | UARTCTRL_TCIE | UARTCTRL_RIE);
+ temp &= ~(UARTCTRL_TE | UARTCTRL_RE | UARTCTRL_TIE |
+ UARTCTRL_TCIE | UARTCTRL_RIE | UARTCTRL_ILIE |
+ UARTCTRL_LOOPS);
lpuart32_write(port, temp, UARTCTRL);
+ lpuart32_write(port, 0, UARTMODIR);
spin_unlock_irqrestore(&port->lock, flags);
+
+ if (sport->lpuart_dma_rx_use) {
+ sport->dma_rx_in_progress = false;
+ dmaengine_terminate_all(sport->dma_rx_chan);
+ if (!sport->dma_eeop)
+ del_timer_sync(&sport->lpuart_timer);
+ lpuart_dma_rx_free(&sport->port);
+ }
+
+ if (sport->lpuart_dma_tx_use) {
+ ret = wait_event_interruptible_timeout(sport->dma_wait,
+ !sport->dma_tx_in_progress, msecs_to_jiffies(1));
+ if (ret <= 0) {
+ sport->dma_tx_in_progress = false;
+ dmaengine_terminate_all(sport->dma_tx_chan);
+ }
+ }
}
static void
@@ -1526,6 +1793,17 @@ lpuart_set_termios(struct uart_port *port, struct ktermios *termios,
/* update the per-port timeout */
uart_update_timeout(port, termios->c_cflag, baud);
+ if (sport->lpuart_dma_rx_use) {
+ /* Calculate delay for 1.5 DMA buffers */
+ sport->dma_rx_timeout = (sport->port.timeout - HZ / 50) *
+ sport->rxdma_len * 3 /
+ sport->rxfifo_size / 2;
+ dev_dbg(port->dev, "DMA Rx t-out %ums, tty t-out %u jiffies\n",
+ sport->dma_rx_timeout * 1000 / HZ, sport->port.timeout);
+ if (sport->dma_rx_timeout < msecs_to_jiffies(20))
+ sport->dma_rx_timeout = msecs_to_jiffies(20);
+ }
+
/* wait transmit engin complete */
while (!(readb(sport->port.membase + UARTSR1) & UARTSR1_TC))
barrier();
@@ -1550,13 +1828,6 @@ lpuart_set_termios(struct uart_port *port, struct ktermios *termios,
/* restore control register */
writeb(old_cr2, sport->port.membase + UARTCR2);
- if (old && sport->lpuart_dma_rx_use) {
- if (!lpuart_start_rx_dma(sport))
- rx_dma_timer_init(sport);
- else
- sport->lpuart_dma_rx_use = false;
- }
-
spin_unlock_irqrestore(&sport->port.lock, flags);
}
@@ -1608,7 +1879,7 @@ lpuart32_serial_setbrg(struct lpuart_port *sport, unsigned int baudrate)
}
}
- /* handle buadrate outside acceptable rate */
+ /* handle baudrate outside acceptable rate */
if (baud_diff > ((baudrate / 100) * 3))
dev_warn(sport->port.dev,
"unacceptable baud rate difference of more than 3%%\n");
@@ -1624,8 +1895,6 @@ lpuart32_serial_setbrg(struct lpuart_port *sport, unsigned int baudrate)
tmp &= ~UARTBAUD_SBR_MASK;
tmp |= sbr & UARTBAUD_SBR_MASK;
- tmp &= ~(UARTBAUD_TDMAE | UARTBAUD_RDMAE);
-
lpuart32_write(&sport->port, tmp, UARTBAUD);
}
@@ -1677,7 +1946,9 @@ lpuart32_set_termios(struct uart_port *port, struct ktermios *termios,
}
if (termios->c_cflag & CSTOPB)
- termios->c_cflag &= ~CSTOPB;
+ bd |= UARTBAUD_SBNS;
+ else
+ bd &= ~UARTBAUD_SBNS;
/* parity must be enabled when CS7 to match 8-bits format */
if ((termios->c_cflag & CSIZE) == CS7)
@@ -1728,20 +1999,35 @@ lpuart32_set_termios(struct uart_port *port, struct ktermios *termios,
/* update the per-port timeout */
uart_update_timeout(port, termios->c_cflag, baud);
- /* wait transmit engin complete */
+ if (sport->lpuart_dma_rx_use && !sport->dma_eeop) {
+ /* Calculate delay for 1.5 DMA buffers */
+ sport->dma_rx_timeout = (sport->port.timeout - HZ / 50) *
+ sport->rxdma_len * 3 /
+ sport->rxfifo_size / 2;
+ dev_dbg(port->dev, "DMA Rx t-out %ums, tty t-out %u jiffies\n",
+ sport->dma_rx_timeout * 1000 / HZ, sport->port.timeout);
+ if (sport->dma_rx_timeout < msecs_to_jiffies(20))
+ sport->dma_rx_timeout = msecs_to_jiffies(20);
+ }
+
+ /* wait transmit engin complete, there disable flow control */
+ lpuart32_write(&sport->port, 0, UARTMODIR);
while (!(lpuart32_read(&sport->port, UARTSTAT) & UARTSTAT_TC))
barrier();
/* disable transmit and receive */
lpuart32_write(&sport->port, old_ctrl & ~(UARTCTRL_TE | UARTCTRL_RE),
- UARTCTRL);
+ UARTCTRL);
+ lpuart32_write(&sport->port, bd, UARTBAUD);
lpuart32_serial_setbrg(sport, baud);
lpuart32_write(&sport->port, modem, UARTMODIR);
lpuart32_write(&sport->port, ctrl, UARTCTRL);
- /* restore control register */
spin_unlock_irqrestore(&sport->port.lock, flags);
+
+ /* wait baud rate stable */
+ usleep_range(1000, 2000);
}
static const char *lpuart_type(struct uart_port *port)
@@ -1795,6 +2081,7 @@ static const struct uart_ops lpuart_pops = {
.break_ctl = lpuart_break_ctl,
.startup = lpuart_startup,
.shutdown = lpuart_shutdown,
+ .pm = lpuart_uart_pm,
.set_termios = lpuart_set_termios,
.type = lpuart_type,
.request_port = lpuart_request_port,
@@ -1819,6 +2106,7 @@ static const struct uart_ops lpuart32_pops = {
.break_ctl = lpuart32_break_ctl,
.startup = lpuart32_startup,
.shutdown = lpuart32_shutdown,
+ .pm = lpuart_uart_pm,
.set_termios = lpuart32_set_termios,
.type = lpuart_type,
.request_port = lpuart_request_port,
@@ -1956,7 +2244,10 @@ lpuart_console_get_options(struct lpuart_port *sport, int *baud,
brfa = readb(sport->port.membase + UARTCR4);
brfa &= UARTCR4_BRFA_MASK;
- uartclk = clk_get_rate(sport->clk);
+ if (sport->per_clk)
+ uartclk = clk_get_rate(sport->per_clk);
+ else
+ uartclk = clk_get_rate(sport->ipg_clk);
/*
* baud = mod_clk/(16*(sbr[13]+(brfa)/32)
*/
@@ -1972,7 +2263,7 @@ lpuart32_console_get_options(struct lpuart_port *sport, int *baud,
int *parity, int *bits)
{
unsigned long cr, bd;
- unsigned int sbr, uartclk, baud_raw;
+ unsigned int sbr, osr, uartclk, baud_raw;
cr = lpuart32_read(&sport->port, UARTCTRL);
cr &= UARTCTRL_TE | UARTCTRL_RE;
@@ -1999,12 +2290,13 @@ lpuart32_console_get_options(struct lpuart_port *sport, int *baud,
bd = lpuart32_read(&sport->port, UARTBAUD);
bd &= UARTBAUD_SBR_MASK;
sbr = bd;
- uartclk = clk_get_rate(sport->clk);
- /*
- * baud = mod_clk/(16*(sbr[13]+(brfa)/32)
- */
- baud_raw = uartclk / (16 * sbr);
+ osr = (bd >> UARTBAUD_OSR_SHIFT) & UARTBAUD_OSR_MASK;
+ if (sport->per_clk)
+ uartclk = clk_get_rate(sport->per_clk);
+ else
+ uartclk = clk_get_rate(sport->ipg_clk);
+ baud_raw = uartclk / ((osr + 1) * sbr);
if (*baud != baud_raw)
printk(KERN_INFO "Serial: Console lpuart rounded baud rate"
"from %d to %d\n", baud_raw, *baud);
@@ -2114,11 +2406,13 @@ static int __init lpuart32_imx_early_console_setup(struct earlycon_device *devic
return 0;
}
+// make lpuart32 mean imx:
OF_EARLYCON_DECLARE(lpuart, "fsl,vf610-lpuart", lpuart_early_console_setup);
-OF_EARLYCON_DECLARE(lpuart32, "fsl,ls1021a-lpuart", lpuart32_early_console_setup);
+OF_EARLYCON_DECLARE(lpuart32ls, "fsl,ls1021a-lpuart", lpuart32_early_console_setup);
OF_EARLYCON_DECLARE(lpuart32, "fsl,imx7ulp-lpuart", lpuart32_imx_early_console_setup);
+OF_EARLYCON_DECLARE(lpuart32, "fsl,imx8qm-lpuart", lpuart32_imx_early_console_setup);
EARLYCON_DECLARE(lpuart, lpuart_early_console_setup);
-EARLYCON_DECLARE(lpuart32, lpuart32_early_console_setup);
+EARLYCON_DECLARE(lpuart32, lpuart32_imx_early_console_setup);
#define LPUART_CONSOLE (&lpuart_console)
#define LPUART32_CONSOLE (&lpuart32_console)
@@ -2143,14 +2437,14 @@ static int lpuart_probe(struct platform_device *pdev)
struct device_node *np = pdev->dev.of_node;
struct lpuart_port *sport;
struct resource *res;
+ unsigned long cr_32;
+ unsigned char cr_8;
int ret;
sport = devm_kzalloc(&pdev->dev, sizeof(*sport), GFP_KERNEL);
if (!sport)
return -ENOMEM;
- pdev->dev.coherent_dma_mask = 0;
-
ret = of_alias_get_id(np, "serial");
if (ret < 0) {
dev_err(&pdev->dev, "failed to get alias id, errno %d\n", ret);
@@ -2161,13 +2455,16 @@ static int lpuart_probe(struct platform_device *pdev)
return -EINVAL;
}
sport->port.line = ret;
+ sport->dma_eeop = of_device_is_compatible(np, "fsl,imx8qm-lpuart");
+
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
sport->port.membase = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(sport->port.membase))
return PTR_ERR(sport->port.membase);
+ sport->regbase = sport->port.membase;
sport->port.membase += sdata->reg_off;
- sport->port.mapbase = res->start;
+ sport->port.mapbase = res->start + sdata->reg_off;
sport->port.dev = &pdev->dev;
sport->port.type = PORT_LPUART;
ret = platform_get_irq(pdev, 0);
@@ -2183,27 +2480,50 @@ static int lpuart_probe(struct platform_device *pdev)
sport->port.ops = &lpuart_pops;
sport->port.flags = UPF_BOOT_AUTOCONF;
- sport->port.rs485_config = lpuart_config_rs485;
+ if (!lpuart_is_32(sport))
+ sport->port.rs485_config = lpuart_config_rs485;
- sport->clk = devm_clk_get(&pdev->dev, "ipg");
- if (IS_ERR(sport->clk)) {
- ret = PTR_ERR(sport->clk);
- dev_err(&pdev->dev, "failed to get uart clk: %d\n", ret);
+ sport->ipg_clk = devm_clk_get(&pdev->dev, "ipg");
+ if (IS_ERR(sport->ipg_clk)) {
+ ret = PTR_ERR(sport->ipg_clk);
+ dev_err(&pdev->dev, "failed to get ipg clk: %d\n", ret);
return ret;
}
+ sport->per_clk = devm_clk_get(&pdev->dev, "per");
+ if (IS_ERR(sport->per_clk))
+ sport->per_clk = NULL;
- ret = clk_prepare_enable(sport->clk);
+ ret = clk_prepare_enable(sport->ipg_clk);
if (ret) {
+ dev_err(&pdev->dev, "failed to enable uart ipg clk: %d\n", ret);
+ return ret;
+ }
+ ret = clk_prepare_enable(sport->per_clk);
+ if (ret) {
+ clk_disable_unprepare(sport->ipg_clk);
dev_err(&pdev->dev, "failed to enable uart clk: %d\n", ret);
return ret;
}
-
- sport->port.uartclk = clk_get_rate(sport->clk);
+ if (sport->per_clk)
+ sport->port.uartclk = clk_get_rate(sport->per_clk);
+ else
+ sport->port.uartclk = clk_get_rate(sport->ipg_clk);
lpuart_ports[sport->port.line] = sport;
platform_set_drvdata(pdev, &sport->port);
+ /* Disable interrupts before request irq */
+ if (lpuart_is_32(sport)) {
+ cr_32 = lpuart32_read(&sport->port, UARTCTRL);
+ cr_32 &= ~(UARTCTRL_TIE | UARTCTRL_TCIE | UARTCTRL_RIE | UARTCTRL_ILIE);
+ lpuart32_write(&sport->port, cr_32, UARTCTRL);
+ } else {
+ cr_8 = readb(sport->port.membase + UARTCR2);
+ cr_8 &= ~(UARTCR2_TIE | UARTCR2_TCIE | UARTCR2_RIE | UARTCR2_ILIE);
+ writeb(cr_8, sport->port.membase + UARTCR2);
+ }
+
if (lpuart_is_32(sport)) {
lpuart_reg.cons = LPUART32_CONSOLE;
ret = devm_request_irq(&pdev->dev, sport->port.irq, lpuart32_int, 0,
@@ -2217,21 +2537,29 @@ static int lpuart_probe(struct platform_device *pdev)
if (ret)
goto failed_irq_request;
+ pm_runtime_use_autosuspend(&pdev->dev);
+ pm_runtime_set_autosuspend_delay(&pdev->dev, UART_AUTOSUSPEND_TIMEOUT);
+ pm_runtime_set_active(&pdev->dev);
+ pm_runtime_enable(&pdev->dev);
+
ret = uart_add_one_port(&lpuart_reg, &sport->port);
if (ret)
goto failed_attach_port;
+ ret = lpuart_hw_reset(sport);
+ if (ret)
+ goto failed_attach_port;
+
sport->dma_tx_chan = dma_request_slave_channel(sport->port.dev, "tx");
if (!sport->dma_tx_chan)
- dev_info(sport->port.dev, "DMA tx channel request failed, "
- "operating without tx DMA\n");
+ dev_info(sport->port.dev, "NO DMA tx channel, run at cpu mode\n");
sport->dma_rx_chan = dma_request_slave_channel(sport->port.dev, "rx");
if (!sport->dma_rx_chan)
- dev_info(sport->port.dev, "DMA rx channel request failed, "
- "operating without rx DMA\n");
+ dev_info(sport->port.dev, "NO DMA rx channel, run at cpu mode\n");
- if (of_property_read_bool(np, "linux,rs485-enabled-at-boot-time")) {
+ if (!lpuart_is_32(sport) &&
+ of_property_read_bool(np, "linux,rs485-enabled-at-boot-time")) {
sport->port.rs485.flags |= SER_RS485_ENABLED;
sport->port.rs485.flags |= SER_RS485_RTS_ON_SEND;
writeb(UARTMODEM_TXRTSE, sport->port.membase + UARTMODEM);
@@ -2240,8 +2568,12 @@ static int lpuart_probe(struct platform_device *pdev)
return 0;
failed_attach_port:
+ pm_runtime_disable(&pdev->dev);
+ pm_runtime_set_suspended(&pdev->dev);
+ pm_runtime_dont_use_autosuspend(&pdev->dev);
failed_irq_request:
- clk_disable_unprepare(sport->clk);
+ clk_disable_unprepare(sport->per_clk);
+ clk_disable_unprepare(sport->ipg_clk);
return ret;
}
@@ -2251,7 +2583,8 @@ static int lpuart_remove(struct platform_device *pdev)
uart_remove_one_port(&lpuart_reg, &sport->port);
- clk_disable_unprepare(sport->clk);
+ clk_disable_unprepare(sport->per_clk);
+ clk_disable_unprepare(sport->ipg_clk);
if (sport->dma_tx_chan)
dma_release_channel(sport->dma_tx_chan);
@@ -2259,109 +2592,366 @@ static int lpuart_remove(struct platform_device *pdev)
if (sport->dma_rx_chan)
dma_release_channel(sport->dma_rx_chan);
+ clk_disable_unprepare(sport->per_clk);
+ clk_disable_unprepare(sport->ipg_clk);
+ pm_runtime_disable(&pdev->dev);
+ pm_runtime_set_suspended(&pdev->dev);
+ pm_runtime_dont_use_autosuspend(&pdev->dev);
return 0;
}
#ifdef CONFIG_PM_SLEEP
-static int lpuart_suspend(struct device *dev)
+static int lpuart_runtime_suspend(struct device *dev)
{
- struct lpuart_port *sport = dev_get_drvdata(dev);
- unsigned long temp;
- bool irq_wake;
+ struct platform_device *pdev = to_platform_device(dev);
+ struct lpuart_port *sport = platform_get_drvdata(pdev);
+
+ clk_disable_unprepare(sport->per_clk);
+ clk_disable_unprepare(sport->ipg_clk);
+
+ return 0;
+};
+
+static int lpuart_runtime_resume(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct lpuart_port *sport = platform_get_drvdata(pdev);
+ int ret;
+
+ ret = clk_prepare_enable(sport->ipg_clk);
+ if (ret)
+ return ret;
+ ret = clk_prepare_enable(sport->per_clk);
+ if (ret) {
+ clk_disable_unprepare(sport->ipg_clk);
+ return ret;
+ }
+
+ return 0;
+};
+
+static void serial_lpuart_enable_wakeup(struct lpuart_port *sport, bool on)
+{
+ unsigned int val;
if (lpuart_is_32(sport)) {
- /* disable Rx/Tx and interrupts */
- temp = lpuart32_read(&sport->port, UARTCTRL);
- temp &= ~(UARTCTRL_TE | UARTCTRL_TIE | UARTCTRL_TCIE);
- lpuart32_write(&sport->port, temp, UARTCTRL);
+ val = lpuart32_read(&sport->port, UARTCTRL);
+ if (on)
+ val |= (UARTCTRL_RIE | UARTCTRL_ILIE);
+ else
+ val &= ~(UARTCTRL_RIE | UARTCTRL_ILIE);
+ lpuart32_write(&sport->port, val, UARTCTRL);
} else {
- /* disable Rx/Tx and interrupts */
- temp = readb(sport->port.membase + UARTCR2);
- temp &= ~(UARTCR2_TE | UARTCR2_TIE | UARTCR2_TCIE);
- writeb(temp, sport->port.membase + UARTCR2);
+ val = readb(sport->port.membase + UARTCR2);
+ if (on)
+ val |= UARTCR2_RIE;
+ else
+ val &= ~UARTCR2_RIE;
+ writeb(val, sport->port.membase + UARTCR2);
+ }
+}
+
+static bool lpuart_uport_is_active(struct lpuart_port *sport)
+{
+ struct tty_port *port = &sport->port.state->port;
+ struct tty_struct *tty;
+ struct device *tty_dev;
+ int may_wake = 0;
+
+ tty = tty_port_tty_get(port);
+ if (tty) {
+ tty_dev = tty->dev;
+ may_wake = device_may_wakeup(tty_dev);
+ tty_kref_put(tty);
+ }
+
+ if ((tty_port_initialized(port) && may_wake) ||
+ (!console_suspend_enabled && uart_console(&sport->port)))
+ return true;
+
+ return false;
+}
+
+static int lpuart_suspend_noirq(struct device *dev)
+{
+ struct lpuart_port *sport = dev_get_drvdata(dev);
+ bool irq_wake = irqd_is_wakeup_set(irq_get_irq_data(sport->port.irq));
+
+ if (lpuart_uport_is_active(sport))
+ serial_lpuart_enable_wakeup(sport, !!irq_wake);
+
+ pinctrl_pm_select_sleep_state(dev);
+
+ return 0;
+}
+
+static int lpuart_resume_noirq(struct device *dev)
+{
+ struct lpuart_port *sport = dev_get_drvdata(dev);
+ unsigned int val;
+
+ pinctrl_pm_select_default_state(dev);
+
+ if (lpuart_uport_is_active(sport)) {
+ serial_lpuart_enable_wakeup(sport, false);
+
+ /* clear the wakeup flags */
+ if (lpuart_is_32(sport)) {
+ val = lpuart32_read(&sport->port, UARTSTAT);
+ lpuart32_write(&sport->port, val, UARTSTAT);
+ }
}
+ return 0;
+}
+
+static int lpuart_suspend(struct device *dev)
+{
+ struct lpuart_port *sport = dev_get_drvdata(dev);
+ unsigned long temp;
+ unsigned long flags;
+
uart_suspend_port(&lpuart_reg, &sport->port);
- /* uart_suspend_port() might set wakeup flag */
- irq_wake = irqd_is_wakeup_set(irq_get_irq_data(sport->port.irq));
+ if (lpuart_uport_is_active(sport)) {
+ spin_lock_irqsave(&sport->port.lock, flags);
+ if (lpuart_is_32(sport)) {
+ temp = lpuart32_read(&sport->port, UARTCTRL);
+ temp &= ~(UARTCTRL_TE | UARTCTRL_TIE | UARTCTRL_TCIE);
+ lpuart32_write(&sport->port, temp, UARTCTRL);
+ } else {
+ temp = readb(sport->port.membase + UARTCR2);
+ temp &= ~(UARTCR2_TE | UARTCR2_TIE | UARTCR2_TCIE);
+ writeb(temp, sport->port.membase + UARTCR2);
+ }
+ spin_unlock_irqrestore(&sport->port.lock, flags);
- if (sport->lpuart_dma_rx_use) {
- /*
- * EDMA driver during suspend will forcefully release any
- * non-idle DMA channels. If port wakeup is enabled or if port
- * is console port or 'no_console_suspend' is set the Rx DMA
- * cannot resume as as expected, hence gracefully release the
- * Rx DMA path before suspend and start Rx DMA path on resume.
- */
- if (irq_wake) {
- del_timer_sync(&sport->lpuart_timer);
+ if (sport->lpuart_dma_rx_use) {
+ spin_lock_irqsave(&sport->port.lock, flags);
+ lpuart_dma_stop(sport, false);
+ spin_unlock_irqrestore(&sport->port.lock, flags);
+
+ dmaengine_terminate_all(sport->dma_rx_chan);
+ if (!sport->dma_eeop)
+ del_timer_sync(&sport->lpuart_timer);
lpuart_dma_rx_free(&sport->port);
}
- /* Disable Rx DMA to use UART port as wakeup source */
- writeb(readb(sport->port.membase + UARTCR5) & ~UARTCR5_RDMAS,
- sport->port.membase + UARTCR5);
- }
+ if (sport->lpuart_dma_tx_use) {
+ spin_lock_irqsave(&sport->port.lock, flags);
+ if (lpuart_is_32(sport)) {
+ temp = lpuart32_read(&sport->port, UARTBAUD);
+ temp &= ~UARTBAUD_TDMAE;
+ lpuart32_write(&sport->port, temp, UARTBAUD);
+ } else {
+ temp = readb(sport->port.membase + UARTCR5);
+ temp &= ~UARTCR5_TDMAS;
+ writeb(temp, sport->port.membase + UARTCR5);
+ }
+ spin_unlock_irqrestore(&sport->port.lock, flags);
- if (sport->lpuart_dma_tx_use) {
- sport->dma_tx_in_progress = false;
- dmaengine_terminate_all(sport->dma_tx_chan);
+ sport->dma_tx_in_progress = false;
+ dmaengine_terminate_all(sport->dma_tx_chan);
+ }
+ } else if (pm_runtime_active(sport->port.dev)) {
+ clk_disable_unprepare(sport->per_clk);
+ clk_disable_unprepare(sport->ipg_clk);
+ pm_runtime_disable(sport->port.dev);
+ pm_runtime_set_suspended(sport->port.dev);
}
- if (sport->port.suspended && !irq_wake)
- clk_disable_unprepare(sport->clk);
-
return 0;
}
-static int lpuart_resume(struct device *dev)
+static void lpuart_console_fixup(struct lpuart_port *sport)
+{
+ struct tty_port *port = &sport->port.state->port;
+ struct uart_port *uport = &sport->port;
+ struct device_node *np = sport->port.dev->of_node;
+ struct ktermios termios;
+
+ if (!lpuart_is_32(sport) || !np)
+ return;
+
+ /* i.MX7ULP enter VLLS mode that lpuart module power off and registers
+ * all lost no matter the port is wakeup source.
+ * For console port, console baud rate setting lost and print messy
+ * log when enable the console port as wakeup source. To avoid the
+ * issue happen, user should not enable uart port as wakeup source
+ * in VLLS mode, or restore console setting here.
+ */
+ if (of_device_is_compatible(np, "fsl,imx7ulp-lpuart") &&
+ lpuart_uport_is_active(sport) && console_suspend_enabled &&
+ uart_console(&sport->port)) {
+
+ mutex_lock(&port->mutex);
+ memset(&termios, 0, sizeof(struct ktermios));
+ termios.c_cflag = uport->cons->cflag;
+ if (port->tty && termios.c_cflag == 0)
+ termios = port->tty->termios;
+ uport->ops->set_termios(uport, &termios, NULL);
+ mutex_unlock(&port->mutex);
+ }
+}
+
+static inline void lpuart32_resume_init(struct lpuart_port *sport)
{
- struct lpuart_port *sport = dev_get_drvdata(dev);
- bool irq_wake = irqd_is_wakeup_set(irq_get_irq_data(sport->port.irq));
unsigned long temp;
+ unsigned long flags;
+
+ spin_lock_irqsave(&sport->port.lock, flags);
+ lpuart32_setup_watermark(sport);
- if (sport->port.suspended && !irq_wake)
- clk_prepare_enable(sport->clk);
+ temp = lpuart32_read(&sport->port, UARTCTRL);
+ temp |= (UARTCTRL_RIE | UARTCTRL_TIE | UARTCTRL_RE |
+ UARTCTRL_TE | UARTCTRL_ILIE);
- if (lpuart_is_32(sport)) {
- lpuart32_setup_watermark(sport);
+ if (sport->dma_rx_chan)
+ temp &= ~(UARTCTRL_RIE | UARTCTRL_ILIE | UARTCTRL_RE);
+
+ if (sport->dma_tx_chan)
+ temp &= ~(UARTCTRL_TIE | UARTCTRL_TE);
+
+ lpuart32_write(&sport->port, temp, UARTCTRL);
+ spin_unlock_irqrestore(&sport->port.lock, flags);
+
+ if (sport->lpuart_dma_rx_use) {
+ if (!lpuart_dma_rx_request(&sport->port)) {
+ sport->lpuart_dma_rx_use = true;
+ if (!sport->dma_eeop)
+ setup_timer(&sport->lpuart_timer,
+ lpuart_timer_func,
+ (unsigned long)sport);
+ } else {
+ sport->lpuart_dma_rx_use = false;
+ }
+
+ spin_lock_irqsave(&sport->port.lock, flags);
temp = lpuart32_read(&sport->port, UARTCTRL);
- temp |= (UARTCTRL_RIE | UARTCTRL_TIE | UARTCTRL_RE |
- UARTCTRL_TE | UARTCTRL_ILIE);
+ temp |= (UARTCTRL_RIE | UARTCTRL_ILIE | UARTCTRL_RE);
+ temp |= UARTCTRL_IDLECFG << UARTCTRL_IDLECFG_OFF;
lpuart32_write(&sport->port, temp, UARTCTRL);
- } else {
- lpuart_setup_watermark(sport);
- temp = readb(sport->port.membase + UARTCR2);
- temp |= (UARTCR2_RIE | UARTCR2_TIE | UARTCR2_RE | UARTCR2_TE);
- writeb(temp, sport->port.membase + UARTCR2);
+ spin_unlock_irqrestore(&sport->port.lock, flags);
}
+ if (sport->lpuart_dma_tx_use) {
+ if (!lpuart_dma_tx_request(&sport->port)) {
+ init_waitqueue_head(&sport->dma_wait);
+ spin_lock_irqsave(&sport->port.lock, flags);
+ temp = lpuart32_read(&sport->port, UARTBAUD);
+ temp |= UARTBAUD_TDMAE;
+ lpuart32_write(&sport->port, temp, UARTBAUD);
+ spin_unlock_irqrestore(&sport->port.lock, flags);
+ } else {
+ sport->lpuart_dma_tx_use = false;
+ }
+
+ spin_lock_irqsave(&sport->port.lock, flags);
+ temp = lpuart32_read(&sport->port, UARTCTRL);
+ temp |= UARTCTRL_TE;
+ lpuart32_write(&sport->port, temp, UARTCTRL);
+ spin_unlock_irqrestore(&sport->port.lock, flags);
+ }
+}
+
+static inline void lpuart_resume_init(struct lpuart_port *sport)
+{
+ unsigned char temp;
+ unsigned long flags;
+
+ spin_lock_irqsave(&sport->port.lock, flags);
+ lpuart_setup_watermark(sport);
+ temp = readb(sport->port.membase + UARTCR2);
+ temp |= (UARTCR2_RIE | UARTCR2_TIE | UARTCR2_RE | UARTCR2_TE);
+
+ if (sport->dma_rx_chan)
+ temp &= ~(UARTCR2_RIE | UARTCR2_RE);
+
+ if (sport->dma_tx_chan)
+ temp &= ~(UARTCR2_TIE | UARTCR2_TE);
+
+ writeb(temp, sport->port.membase + UARTCR2);
+ spin_unlock_irqrestore(&sport->port.lock, flags);
+
if (sport->lpuart_dma_rx_use) {
- if (irq_wake) {
- if (!lpuart_start_rx_dma(sport))
- rx_dma_timer_init(sport);
- else
- sport->lpuart_dma_rx_use = false;
+ if (!lpuart_dma_rx_request(&sport->port)) {
+ sport->lpuart_dma_rx_use = true;
+ setup_timer(&sport->lpuart_timer,
+ lpuart_timer_func,
+ (unsigned long)sport);
+ } else {
+ sport->lpuart_dma_rx_use = false;
}
+
+ spin_lock_irqsave(&sport->port.lock, flags);
+ temp = readb(sport->port.membase + UARTCR2);
+ temp |= (UARTCR2_RIE | UARTCR2_RE);
+ writeb(temp, sport->port.membase + UARTCR2);
+ spin_unlock_irqrestore(&sport->port.lock, flags);
}
- if (sport->dma_tx_chan && !lpuart_dma_tx_request(&sport->port)) {
+ if (sport->lpuart_dma_tx_use) {
+ if (!lpuart_dma_tx_request(&sport->port)) {
init_waitqueue_head(&sport->dma_wait);
- sport->lpuart_dma_tx_use = true;
- writeb(readb(sport->port.membase + UARTCR5) |
- UARTCR5_TDMAS, sport->port.membase + UARTCR5);
- } else {
- sport->lpuart_dma_tx_use = false;
+ spin_lock_irqsave(&sport->port.lock, flags);
+ temp = readb(sport->port.membase + UARTCR5);
+ temp |= UARTCR5_TDMAS;
+ writeb(temp, sport->port.membase + UARTCR5);
+ spin_unlock_irqrestore(&sport->port.lock, flags);
+ } else {
+ sport->lpuart_dma_tx_use = false;
+ }
+
+ spin_lock_irqsave(&sport->port.lock, flags);
+ temp = readb(sport->port.membase + UARTCR2);
+ temp |= UARTCR2_TE;
+ writeb(temp, sport->port.membase + UARTCR2);
+ spin_unlock_irqrestore(&sport->port.lock, flags);
}
+}
+
+static int lpuart_resume(struct device *dev)
+{
+ struct lpuart_port *sport = dev_get_drvdata(dev);
+ int ret;
+ if (lpuart_uport_is_active(sport)) {
+ if (lpuart_is_32(sport))
+ lpuart32_resume_init(sport);
+ else
+ lpuart_resume_init(sport);
+ } else if (pm_runtime_active(sport->port.dev)) {
+ ret = clk_prepare_enable(sport->ipg_clk);
+ if (ret)
+ return ret;
+ ret = clk_prepare_enable(sport->per_clk);
+ if (ret) {
+ clk_disable_unprepare(sport->ipg_clk);
+ return ret;
+ }
+ pm_runtime_set_active(sport->port.dev);
+ pm_runtime_enable(sport->port.dev);
+ }
+
+ lpuart_console_fixup(sport);
uart_resume_port(&lpuart_reg, &sport->port);
return 0;
}
-#endif
-static SIMPLE_DEV_PM_OPS(lpuart_pm_ops, lpuart_suspend, lpuart_resume);
+static const struct dev_pm_ops lpuart_pm_ops = {
+ SET_RUNTIME_PM_OPS(lpuart_runtime_suspend,
+ lpuart_runtime_resume, NULL)
+ SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(lpuart_suspend_noirq,
+ lpuart_resume_noirq)
+ SET_SYSTEM_SLEEP_PM_OPS(lpuart_suspend, lpuart_resume)
+};
+#define SERIAL_LPUART_PM_OPS (&lpuart_pm_ops)
+
+#else /* !CONFIG_PM_SLEEP */
+
+#define SERIAL_LPUART_PM_OPS NULL
+#endif /* CONFIG_PM_SLEEP */
static struct platform_driver lpuart_driver = {
.probe = lpuart_probe,
@@ -2369,7 +2959,7 @@ static struct platform_driver lpuart_driver = {
.driver = {
.name = "fsl-lpuart",
.of_match_table = lpuart_dt_ids,
- .pm = &lpuart_pm_ops,
+ .pm = SERIAL_LPUART_PM_OPS,
},
};
diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c
index aae68230fb7b..d018968e3b2f 100644
--- a/drivers/tty/serial/imx.c
+++ b/drivers/tty/serial/imx.c
@@ -34,6 +34,7 @@
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/rational.h>
+#include <linux/reset.h>
#include <linux/slab.h>
#include <linux/of.h>
#include <linux/of_device.h>
@@ -41,6 +42,7 @@
#include <linux/dma-mapping.h>
#include <asm/irq.h>
+#include <linux/busfreq-imx.h>
#include <linux/platform_data/serial-imx.h>
#include <linux/platform_data/dma-imx.h>
@@ -185,6 +187,8 @@
#define DRIVER_NAME "IMX-uart"
#define UART_NR 8
+#define IMX_RXBD_NUM 20
+#define IMX_MODULE_MAX_CLK_RATE 80000000
/* i.MX21 type uart runs on all i.mx except i.MX1 and i.MX6q */
enum imx_uart_type {
@@ -200,6 +204,24 @@ struct imx_uart_data {
enum imx_uart_type devtype;
};
+struct imx_dma_bufinfo {
+ bool filled;
+ unsigned int rx_bytes;
+};
+
+struct imx_dma_rxbuf {
+ unsigned int periods;
+ unsigned int period_len;
+ unsigned int buf_len;
+
+ void *buf;
+ dma_addr_t dmaaddr;
+ unsigned int cur_idx;
+ unsigned int last_completed_idx;
+ dma_cookie_t cookie;
+ struct imx_dma_bufinfo buf_info[IMX_RXBD_NUM];
+};
+
struct imx_port {
struct uart_port port;
struct timer_list timer;
@@ -219,15 +241,16 @@ struct imx_port {
unsigned int dma_is_rxing:1;
unsigned int dma_is_txing:1;
struct dma_chan *dma_chan_rx, *dma_chan_tx;
- struct scatterlist rx_sgl, tx_sgl[2];
- void *rx_buf;
- struct circ_buf rx_ring;
- unsigned int rx_periods;
- dma_cookie_t rx_cookie;
+ struct scatterlist tx_sgl[2];
+ struct imx_dma_rxbuf rx_buf;
unsigned int tx_bytes;
unsigned int dma_tx_nents;
+ struct work_struct tsk_dma_tx;
+ wait_queue_head_t dma_wait;
unsigned int saved_reg[10];
bool context_saved;
+#define DMA_TX_IS_WORKING 1
+ unsigned long flags;
};
struct imx_port_ucrs {
@@ -404,12 +427,14 @@ static void imx_stop_rx(struct uart_port *port)
}
}
- temp = readl(sport->port.membase + UCR2);
- writel(temp & ~UCR2_RXEN, sport->port.membase + UCR2);
-
- /* disable the `Receiver Ready Interrrupt` */
+ /* disable the Receiver Ready and overrun Interrrupt */
temp = readl(sport->port.membase + UCR1);
writel(temp & ~UCR1_RRDYEN, sport->port.membase + UCR1);
+ temp = readl(sport->port.membase + UCR4);
+ writel(temp & ~UCR4_OREN, sport->port.membase + UCR4);
+
+ temp = readl(sport->port.membase + UCR2);
+ writel(temp & ~UCR2_RXEN, sport->port.membase + UCR2);
}
/*
@@ -424,7 +449,6 @@ static void imx_enable_ms(struct uart_port *port)
mctrl_gpio_enable_ms(sport->gpios);
}
-static void imx_dma_tx(struct imx_port *sport);
static inline void imx_transmit_buffer(struct imx_port *sport)
{
struct circ_buf *xmit = &sport->port.state->xmit;
@@ -455,7 +479,7 @@ static inline void imx_transmit_buffer(struct imx_port *sport)
writel(temp, sport->port.membase + UCR1);
} else {
writel(temp, sport->port.membase + UCR1);
- imx_dma_tx(sport);
+ schedule_work(&sport->tsk_dma_tx);
}
}
@@ -484,87 +508,99 @@ static void dma_tx_callback(void *data)
struct scatterlist *sgl = &sport->tx_sgl[0];
struct circ_buf *xmit = &sport->port.state->xmit;
unsigned long flags;
- unsigned long temp;
+ /* update the stat */
spin_lock_irqsave(&sport->port.lock, flags);
+ /* user call .flush() before the code slice coming */
+ if (!sport->dma_is_txing) {
+ spin_unlock_irqrestore(&sport->port.lock, flags);
+ return;
+ }
+ sport->dma_is_txing = 0;
- dma_unmap_sg(sport->port.dev, sgl, sport->dma_tx_nents, DMA_TO_DEVICE);
-
- temp = readl(sport->port.membase + UCR1);
- temp &= ~UCR1_TDMAEN;
- writel(temp, sport->port.membase + UCR1);
-
- /* update the stat */
xmit->tail = (xmit->tail + sport->tx_bytes) & (UART_XMIT_SIZE - 1);
sport->port.icount.tx += sport->tx_bytes;
+ spin_unlock_irqrestore(&sport->port.lock, flags);
- dev_dbg(sport->port.dev, "we finish the TX DMA.\n");
+ dma_unmap_sg(sport->port.dev, sgl, sport->dma_tx_nents, DMA_TO_DEVICE);
- sport->dma_is_txing = 0;
+ dev_dbg(sport->port.dev, "we finish the TX DMA.\n");
- if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
- uart_write_wakeup(&sport->port);
+ clear_bit(DMA_TX_IS_WORKING, &sport->flags);
+ smp_mb__after_atomic();
+ uart_write_wakeup(&sport->port);
if (!uart_circ_empty(xmit) && !uart_tx_stopped(&sport->port))
- imx_dma_tx(sport);
+ schedule_work(&sport->tsk_dma_tx);
- spin_unlock_irqrestore(&sport->port.lock, flags);
+ if (waitqueue_active(&sport->dma_wait)) {
+ wake_up(&sport->dma_wait);
+ dev_dbg(sport->port.dev, "exit in %s.\n", __func__);
+ return;
+ }
}
-static void imx_dma_tx(struct imx_port *sport)
+static void dma_tx_work(struct work_struct *w)
{
+ struct imx_port *sport = container_of(w, struct imx_port, tsk_dma_tx);
struct circ_buf *xmit = &sport->port.state->xmit;
struct scatterlist *sgl = sport->tx_sgl;
struct dma_async_tx_descriptor *desc;
struct dma_chan *chan = sport->dma_chan_tx;
struct device *dev = sport->port.dev;
+ unsigned long flags;
unsigned long temp;
int ret;
- if (sport->dma_is_txing)
+ if (test_and_set_bit(DMA_TX_IS_WORKING, &sport->flags))
return;
+ spin_lock_irqsave(&sport->port.lock, flags);
sport->tx_bytes = uart_circ_chars_pending(xmit);
- if (xmit->tail < xmit->head) {
- sport->dma_tx_nents = 1;
- sg_init_one(sgl, xmit->buf + xmit->tail, sport->tx_bytes);
- } else {
- sport->dma_tx_nents = 2;
- sg_init_table(sgl, 2);
- sg_set_buf(sgl, xmit->buf + xmit->tail,
- UART_XMIT_SIZE - xmit->tail);
- sg_set_buf(sgl + 1, xmit->buf, xmit->head);
- }
-
- ret = dma_map_sg(dev, sgl, sport->dma_tx_nents, DMA_TO_DEVICE);
- if (ret == 0) {
- dev_err(dev, "DMA mapping error for TX.\n");
- return;
- }
- desc = dmaengine_prep_slave_sg(chan, sgl, sport->dma_tx_nents,
- DMA_MEM_TO_DEV, DMA_PREP_INTERRUPT);
- if (!desc) {
- dma_unmap_sg(dev, sgl, sport->dma_tx_nents,
- DMA_TO_DEVICE);
- dev_err(dev, "We cannot prepare for the TX slave dma!\n");
- return;
- }
- desc->callback = dma_tx_callback;
- desc->callback_param = sport;
+ if (sport->tx_bytes > 0) {
+ if (xmit->tail > xmit->head && xmit->head > 0) {
+ sport->dma_tx_nents = 2;
+ sg_init_table(sgl, 2);
+ sg_set_buf(sgl, xmit->buf + xmit->tail,
+ UART_XMIT_SIZE - xmit->tail);
+ sg_set_buf(sgl + 1, xmit->buf, xmit->head);
+ } else {
+ sport->dma_tx_nents = 1;
+ sg_init_one(sgl, xmit->buf + xmit->tail, sport->tx_bytes);
+ }
+ spin_unlock_irqrestore(&sport->port.lock, flags);
- dev_dbg(dev, "TX: prepare to send %lu bytes by DMA.\n",
- uart_circ_chars_pending(xmit));
+ ret = dma_map_sg(dev, sgl, sport->dma_tx_nents, DMA_TO_DEVICE);
+ if (ret == 0) {
+ dev_err(dev, "DMA mapping error for TX.\n");
+ goto err_out;
+ }
+ desc = dmaengine_prep_slave_sg(chan, sgl, sport->dma_tx_nents,
+ DMA_MEM_TO_DEV, DMA_PREP_INTERRUPT);
+ if (!desc) {
+ dev_err(dev, "We cannot prepare for the TX slave dma!\n");
+ goto err_out;
+ }
+ desc->callback = dma_tx_callback;
+ desc->callback_param = sport;
- temp = readl(sport->port.membase + UCR1);
- temp |= UCR1_TDMAEN;
- writel(temp, sport->port.membase + UCR1);
+ dev_dbg(dev, "TX: prepare to send %lu bytes by DMA.\n",
+ uart_circ_chars_pending(xmit));
+ /* fire it */
+ sport->dma_is_txing = 1;
+ dmaengine_submit(desc);
+ dma_async_issue_pending(chan);
- /* fire it */
- sport->dma_is_txing = 1;
- dmaengine_submit(desc);
- dma_async_issue_pending(chan);
- return;
+ temp = readl(sport->port.membase + UCR1);
+ temp |= UCR1_TDMAEN;
+ writel(temp, sport->port.membase + UCR1);
+ return;
+ }
+ spin_unlock_irqrestore(&sport->port.lock, flags);
+err_out:
+ clear_bit(DMA_TX_IS_WORKING, &sport->flags);
+ smp_mb__after_atomic();
}
/*
@@ -609,7 +645,7 @@ static void imx_start_tx(struct uart_port *port)
if (!uart_circ_empty(&port->state->xmit) &&
!uart_tx_stopped(port))
- imx_dma_tx(sport);
+ schedule_work(&sport->tsk_dma_tx);
return;
}
}
@@ -733,43 +769,22 @@ static void imx_disable_rx_int(struct imx_port *sport)
writel(temp, sport->port.membase + UCR4);
}
-static void clear_rx_errors(struct imx_port *sport);
-static int start_rx_dma(struct imx_port *sport);
-/*
- * If the RXFIFO is filled with some data, and then we
- * arise a DMA operation to receive them.
- */
-static void imx_dma_rxint(struct imx_port *sport)
-{
- unsigned long temp;
- unsigned long flags;
-
- spin_lock_irqsave(&sport->port.lock, flags);
-
- temp = readl(sport->port.membase + USR2);
- if ((temp & USR2_RDR) && !sport->dma_is_rxing) {
-
- imx_disable_rx_int(sport);
-
- /* tell the DMA to receive the data. */
- start_rx_dma(sport);
- }
-
- spin_unlock_irqrestore(&sport->port.lock, flags);
-}
-
/*
* We have a modem side uart, so the meanings of RTS and CTS are inverted.
*/
static unsigned int imx_get_hwmctrl(struct imx_port *sport)
{
- unsigned int tmp = TIOCM_DSR;
- unsigned usr1 = readl(sport->port.membase + USR1);
- unsigned usr2 = readl(sport->port.membase + USR2);
+ unsigned int tmp = TIOCM_DSR | TIOCM_CAR;
+ unsigned int usr1 = readl(sport->port.membase + USR1);
+ unsigned int usr2 = readl(sport->port.membase + USR2);
+ unsigned int ucr2 = readl(sport->port.membase + UCR2);
if (usr1 & USR1_RTSS)
tmp |= TIOCM_CTS;
+ if (ucr2 & UCR2_CTS)
+ tmp |= TIOCM_RTS;
+
/* in DCE mode DCDIN is always 0 */
if (!(usr2 & USR2_DCDIN))
tmp |= TIOCM_CAR;
@@ -778,6 +793,9 @@ static unsigned int imx_get_hwmctrl(struct imx_port *sport)
if (!(readl(sport->port.membase + USR2) & USR2_RIIN))
tmp |= TIOCM_RI;
+ if (readl(sport->port.membase + uts_reg(sport)) & UTS_LOOP)
+ tmp |= TIOCM_LOOP;
+
return tmp;
}
@@ -813,26 +831,22 @@ static irqreturn_t imx_int(int irq, void *dev_id)
struct imx_port *sport = dev_id;
unsigned int sts;
unsigned int sts2;
- irqreturn_t ret = IRQ_NONE;
sts = readl(sport->port.membase + USR1);
sts2 = readl(sport->port.membase + USR2);
- if (sts & (USR1_RRDY | USR1_AGTIM)) {
- if (sport->dma_is_enabled)
- imx_dma_rxint(sport);
- else
- imx_rxint(irq, dev_id);
- ret = IRQ_HANDLED;
+ if ((sts & USR1_RRDY || sts & USR1_AGTIM) &&
+ !sport->dma_is_enabled) {
+ if (sts & USR1_AGTIM)
+ writel(USR1_AGTIM, sport->port.membase + USR1);
+ imx_rxint(irq, dev_id);
}
if ((sts & USR1_TRDY &&
readl(sport->port.membase + UCR1) & UCR1_TXMPTYEN) ||
(sts2 & USR2_TXDC &&
- readl(sport->port.membase + UCR4) & UCR4_TCEN)) {
+ readl(sport->port.membase + UCR4) & UCR4_TCEN))
imx_txint(irq, dev_id);
- ret = IRQ_HANDLED;
- }
if (sts & USR1_DTRD) {
unsigned long flags;
@@ -843,27 +857,20 @@ static irqreturn_t imx_int(int irq, void *dev_id)
spin_lock_irqsave(&sport->port.lock, flags);
imx_mctrl_check(sport);
spin_unlock_irqrestore(&sport->port.lock, flags);
-
- ret = IRQ_HANDLED;
}
- if (sts & USR1_RTSD) {
+ if (sts & USR1_RTSD)
imx_rtsint(irq, dev_id);
- ret = IRQ_HANDLED;
- }
- if (sts & USR1_AWAKE) {
+ if (sts & USR1_AWAKE)
writel(USR1_AWAKE, sport->port.membase + USR1);
- ret = IRQ_HANDLED;
- }
if (sts2 & USR2_ORE) {
sport->port.icount.overrun++;
writel(USR2_ORE, sport->port.membase + USR2);
- ret = IRQ_HANDLED;
}
- return ret;
+ return IRQ_HANDLED;
}
/*
@@ -883,6 +890,9 @@ static unsigned int imx_tx_empty(struct uart_port *port)
return ret;
}
+/*
+ * We have a modem side uart, so the meanings of RTS and CTS are inverted.
+ */
static unsigned int imx_get_mctrl(struct uart_port *port)
{
struct imx_port *sport = (struct imx_port *)port;
@@ -939,6 +949,97 @@ static void imx_break_ctl(struct uart_port *port, int break_state)
spin_unlock_irqrestore(&sport->port.lock, flags);
}
+#define TXTL 2 /* reset default */
+#define RXTL 1 /* For console port */
+#define RXTL_UART 16 /* For uart */
+
+static int imx_setup_ufcr(struct imx_port *sport, unsigned int mode)
+{
+ unsigned int val;
+ unsigned int rx_fifo_trig;
+
+ if (uart_console(&sport->port))
+ rx_fifo_trig = RXTL;
+ else
+ rx_fifo_trig = RXTL_UART;
+
+ /* set receiver / transmitter trigger level */
+ val = readl(sport->port.membase + UFCR) & (UFCR_RFDIV | UFCR_DCEDTE);
+ val |= TXTL << UFCR_TXTL_SHF | rx_fifo_trig;
+ writel(val, sport->port.membase + UFCR);
+ return 0;
+}
+
+#define RX_BUF_SIZE (PAGE_SIZE)
+static void dma_rx_push_data(struct imx_port *sport, struct tty_struct *tty,
+ unsigned int start, unsigned int end)
+{
+ unsigned int i;
+ struct tty_port *port = &sport->port.state->port;
+
+ for (i = start; i < end; i++) {
+ if (sport->rx_buf.buf_info[i].filled) {
+ tty_insert_flip_string(port, sport->rx_buf.buf + (i
+ * RX_BUF_SIZE), sport->rx_buf.buf_info[i].rx_bytes);
+ tty_flip_buffer_push(port);
+ sport->rx_buf.buf_info[i].filled = false;
+ sport->rx_buf.last_completed_idx++;
+ sport->rx_buf.last_completed_idx %= IMX_RXBD_NUM;
+ sport->port.icount.rx += sport->rx_buf.buf_info[i].rx_bytes;
+ }
+ }
+}
+
+static void dma_rx_work(struct imx_port *sport)
+{
+ struct tty_struct *tty = sport->port.state->port.tty;
+ unsigned int cur_idx = sport->rx_buf.cur_idx;
+
+ if (sport->rx_buf.last_completed_idx < cur_idx) {
+ dma_rx_push_data(sport, tty, sport->rx_buf.last_completed_idx + 1, cur_idx);
+ } else if (sport->rx_buf.last_completed_idx == (IMX_RXBD_NUM - 1)) {
+ dma_rx_push_data(sport, tty, 0, cur_idx);
+ } else {
+ dma_rx_push_data(sport, tty, sport->rx_buf.last_completed_idx + 1,
+ IMX_RXBD_NUM);
+ dma_rx_push_data(sport, tty, 0, cur_idx);
+ }
+}
+
+static void imx_rx_dma_done(struct imx_port *sport)
+{
+ sport->dma_is_rxing = 0;
+
+ /* Is the shutdown waiting for us? */
+ if (waitqueue_active(&sport->dma_wait))
+ wake_up(&sport->dma_wait);
+}
+
+static void clear_rx_errors(struct imx_port *sport)
+{
+ unsigned int status_usr1, status_usr2;
+
+ status_usr1 = readl(sport->port.membase + USR1);
+ status_usr2 = readl(sport->port.membase + USR2);
+
+ if (status_usr2 & USR2_BRCD) {
+ sport->port.icount.brk++;
+ writel(USR2_BRCD, sport->port.membase + USR2);
+ } else if (status_usr1 & USR1_FRAMERR) {
+ sport->port.icount.frame++;
+ writel(USR1_FRAMERR, sport->port.membase + USR1);
+ } else if (status_usr1 & USR1_PARITYERR) {
+ sport->port.icount.parity++;
+ writel(USR1_PARITYERR, sport->port.membase + USR1);
+ }
+
+ if (status_usr2 & USR2_ORE) {
+ sport->port.icount.overrun++;
+ writel(USR2_ORE, sport->port.membase + USR2);
+ }
+
+}
+
/*
* This is our per-port timeout handler, for checking the
* modem status signals.
@@ -957,188 +1058,103 @@ static void imx_timeout(unsigned long data)
}
}
-#define RX_BUF_SIZE (PAGE_SIZE)
-
/*
- * There are two kinds of RX DMA interrupts(such as in the MX6Q):
+ * There are three kinds of RX DMA interrupts(such as in the MX6Q):
* [1] the RX DMA buffer is full.
- * [2] the aging timer expires
+ * [2] the Aging timer expires(wait for 8 bytes long)
+ * [3] the Idle Condition Detect(enabled the UCR4_IDDMAEN).
*
- * Condition [2] is triggered when a character has been sitting in the FIFO
- * for at least 8 byte durations.
+ * The [2] is trigger when a character was been sitting in the FIFO
+ * meanwhile [3] can wait for 32 bytes long when the RX line is
+ * on IDLE state and RxFIFO is empty.
*/
static void dma_rx_callback(void *data)
{
struct imx_port *sport = data;
struct dma_chan *chan = sport->dma_chan_rx;
- struct scatterlist *sgl = &sport->rx_sgl;
- struct tty_port *port = &sport->port.state->port;
+ struct tty_struct *tty = sport->port.state->port.tty;
struct dma_tx_state state;
- struct circ_buf *rx_ring = &sport->rx_ring;
enum dma_status status;
- unsigned int w_bytes = 0;
- unsigned int r_bytes;
- unsigned int bd_size;
+ unsigned int count;
- status = dmaengine_tx_status(chan, (dma_cookie_t)0, &state);
+ /* If we have finish the reading. we will not accept any more data. */
+ if (tty->closing) {
+ imx_rx_dma_done(sport);
+ return;
+ }
+ status = dmaengine_tx_status(chan, sport->rx_buf.cookie, &state);
if (status == DMA_ERROR) {
dev_err(sport->port.dev, "DMA transaction error.\n");
clear_rx_errors(sport);
return;
}
- if (!(sport->port.ignore_status_mask & URXD_DUMMY_READ)) {
-
- /*
- * The state-residue variable represents the empty space
- * relative to the entire buffer. Taking this in consideration
- * the head is always calculated base on the buffer total
- * length - DMA transaction residue. The UART script from the
- * SDMA firmware will jump to the next buffer descriptor,
- * once a DMA transaction if finalized (IMX53 RM - A.4.1.2.4).
- * Taking this in consideration the tail is always at the
- * beginning of the buffer descriptor that contains the head.
- */
-
- /* Calculate the head */
- rx_ring->head = sg_dma_len(sgl) - state.residue;
-
- /* Calculate the tail. */
- bd_size = sg_dma_len(sgl) / sport->rx_periods;
- rx_ring->tail = ((rx_ring->head-1) / bd_size) * bd_size;
-
- if (rx_ring->head <= sg_dma_len(sgl) &&
- rx_ring->head > rx_ring->tail) {
-
- /* Move data from tail to head */
- r_bytes = rx_ring->head - rx_ring->tail;
+ count = RX_BUF_SIZE - state.residue;
+ sport->rx_buf.buf_info[sport->rx_buf.cur_idx].filled = true;
+ sport->rx_buf.buf_info[sport->rx_buf.cur_idx].rx_bytes = count;
+ sport->rx_buf.cur_idx++;
+ sport->rx_buf.cur_idx %= IMX_RXBD_NUM;
+ dev_dbg(sport->port.dev, "We get %d bytes.\n", count);
- /* CPU claims ownership of RX DMA buffer */
- dma_sync_sg_for_cpu(sport->port.dev, sgl, 1,
- DMA_FROM_DEVICE);
+ if (sport->rx_buf.cur_idx == sport->rx_buf.last_completed_idx)
+ dev_err(sport->port.dev, "overwrite!\n");
- w_bytes = tty_insert_flip_string(port,
- sport->rx_buf + rx_ring->tail, r_bytes);
-
- /* UART retrieves ownership of RX DMA buffer */
- dma_sync_sg_for_device(sport->port.dev, sgl, 1,
- DMA_FROM_DEVICE);
-
- if (w_bytes != r_bytes)
- sport->port.icount.buf_overrun++;
-
- sport->port.icount.rx += w_bytes;
- } else {
- WARN_ON(rx_ring->head > sg_dma_len(sgl));
- WARN_ON(rx_ring->head <= rx_ring->tail);
- }
- }
-
- if (w_bytes) {
- tty_flip_buffer_push(port);
- dev_dbg(sport->port.dev, "We get %d bytes.\n", w_bytes);
- }
+ if (count)
+ dma_rx_work(sport);
}
-/* RX DMA buffer periods */
-#define RX_DMA_PERIODS 4
-
static int start_rx_dma(struct imx_port *sport)
{
- struct scatterlist *sgl = &sport->rx_sgl;
struct dma_chan *chan = sport->dma_chan_rx;
- struct device *dev = sport->port.dev;
struct dma_async_tx_descriptor *desc;
- int ret;
-
- sport->rx_ring.head = 0;
- sport->rx_ring.tail = 0;
- sport->rx_periods = RX_DMA_PERIODS;
- sg_init_one(sgl, sport->rx_buf, RX_BUF_SIZE);
- ret = dma_map_sg(dev, sgl, 1, DMA_FROM_DEVICE);
- if (ret == 0) {
- dev_err(dev, "DMA mapping error for RX.\n");
- return -EINVAL;
- }
-
- desc = dmaengine_prep_dma_cyclic(chan, sg_dma_address(sgl),
- sg_dma_len(sgl), sg_dma_len(sgl) / sport->rx_periods,
+ sport->rx_buf.periods = IMX_RXBD_NUM;
+ sport->rx_buf.period_len = RX_BUF_SIZE;
+ sport->rx_buf.buf_len = IMX_RXBD_NUM * RX_BUF_SIZE;
+ sport->rx_buf.cur_idx = 0;
+ sport->rx_buf.last_completed_idx = -1;
+ desc = dmaengine_prep_dma_cyclic(chan, sport->rx_buf.dmaaddr,
+ sport->rx_buf.buf_len, sport->rx_buf.period_len,
DMA_DEV_TO_MEM, DMA_PREP_INTERRUPT);
-
if (!desc) {
- dma_unmap_sg(dev, sgl, 1, DMA_FROM_DEVICE);
- dev_err(dev, "We cannot prepare for the RX slave dma!\n");
+ dev_err(sport->port.dev, "Prepare for the RX slave dma failed!\n");
return -EINVAL;
}
+
desc->callback = dma_rx_callback;
desc->callback_param = sport;
- dev_dbg(dev, "RX: prepare for the DMA.\n");
- sport->rx_cookie = dmaengine_submit(desc);
+ dev_dbg(sport->port.dev, "RX: prepare for the DMA.\n");
+ sport->rx_buf.cookie = dmaengine_submit(desc);
dma_async_issue_pending(chan);
- return 0;
-}
-
-static void clear_rx_errors(struct imx_port *sport)
-{
- unsigned int status_usr1, status_usr2;
-
- status_usr1 = readl(sport->port.membase + USR1);
- status_usr2 = readl(sport->port.membase + USR2);
-
- if (status_usr2 & USR2_BRCD) {
- sport->port.icount.brk++;
- writel(USR2_BRCD, sport->port.membase + USR2);
- } else if (status_usr1 & USR1_FRAMERR) {
- sport->port.icount.frame++;
- writel(USR1_FRAMERR, sport->port.membase + USR1);
- } else if (status_usr1 & USR1_PARITYERR) {
- sport->port.icount.parity++;
- writel(USR1_PARITYERR, sport->port.membase + USR1);
- }
- if (status_usr2 & USR2_ORE) {
- sport->port.icount.overrun++;
- writel(USR2_ORE, sport->port.membase + USR2);
- }
-
-}
-
-#define TXTL_DEFAULT 2 /* reset default */
-#define RXTL_DEFAULT 1 /* reset default */
-#define TXTL_DMA 8 /* DMA burst setting */
-#define RXTL_DMA 9 /* DMA burst setting */
-
-static void imx_setup_ufcr(struct imx_port *sport,
- unsigned char txwl, unsigned char rxwl)
-{
- unsigned int val;
-
- /* set receiver / transmitter trigger level */
- val = readl(sport->port.membase + UFCR) & (UFCR_RFDIV | UFCR_DCEDTE);
- val |= txwl << UFCR_TXTL_SHF | rxwl;
- writel(val, sport->port.membase + UFCR);
+ sport->dma_is_rxing = 1;
+ return 0;
}
static void imx_uart_dma_exit(struct imx_port *sport)
{
if (sport->dma_chan_rx) {
- dmaengine_terminate_sync(sport->dma_chan_rx);
dma_release_channel(sport->dma_chan_rx);
sport->dma_chan_rx = NULL;
- sport->rx_cookie = -EINVAL;
- kfree(sport->rx_buf);
- sport->rx_buf = NULL;
+
+ if (sport->rx_buf.buf) {
+ dma_free_coherent(sport->port.dev, IMX_RXBD_NUM * RX_BUF_SIZE,
+ (void *)sport->rx_buf.buf,
+ sport->rx_buf.dmaaddr);
+ sport->rx_buf.buf = NULL;
+ }
}
if (sport->dma_chan_tx) {
- dmaengine_terminate_sync(sport->dma_chan_tx);
dma_release_channel(sport->dma_chan_tx);
sport->dma_chan_tx = NULL;
}
+ if (sport->dma_is_inited)
+ release_bus_freq(BUS_FREQ_HIGH);
+
sport->dma_is_inited = 0;
}
@@ -1146,7 +1162,7 @@ static int imx_uart_dma_init(struct imx_port *sport)
{
struct dma_slave_config slave_config = {};
struct device *dev = sport->port.dev;
- int ret;
+ int ret, i;
/* Prepare for RX : */
sport->dma_chan_rx = dma_request_slave_channel(dev, "rx");
@@ -1159,20 +1175,25 @@ static int imx_uart_dma_init(struct imx_port *sport)
slave_config.direction = DMA_DEV_TO_MEM;
slave_config.src_addr = sport->port.mapbase + URXD0;
slave_config.src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
- /* one byte less than the watermark level to enable the aging timer */
- slave_config.src_maxburst = RXTL_DMA - 1;
+ slave_config.src_maxburst = RXTL_UART;
ret = dmaengine_slave_config(sport->dma_chan_rx, &slave_config);
if (ret) {
dev_err(dev, "error in RX dma configuration.\n");
goto err;
}
- sport->rx_buf = kzalloc(PAGE_SIZE, GFP_KERNEL);
- if (!sport->rx_buf) {
+ sport->rx_buf.buf = dma_alloc_coherent(sport->port.dev, IMX_RXBD_NUM * RX_BUF_SIZE,
+ &sport->rx_buf.dmaaddr, GFP_KERNEL);
+ if (!sport->rx_buf.buf) {
+ dev_err(dev, "cannot alloc DMA buffer.\n");
ret = -ENOMEM;
goto err;
}
- sport->rx_ring.buf = sport->rx_buf;
+
+ for (i = 0; i < IMX_RXBD_NUM; i++) {
+ sport->rx_buf.buf_info[i].rx_bytes = 0;
+ sport->rx_buf.buf_info[i].filled = false;
+ }
/* Prepare for TX : */
sport->dma_chan_tx = dma_request_slave_channel(dev, "tx");
@@ -1185,7 +1206,7 @@ static int imx_uart_dma_init(struct imx_port *sport)
slave_config.direction = DMA_MEM_TO_DEV;
slave_config.dst_addr = sport->port.mapbase + URTX0;
slave_config.dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
- slave_config.dst_maxburst = TXTL_DMA;
+ slave_config.dst_maxburst = TXTL;
ret = dmaengine_slave_config(sport->dma_chan_tx, &slave_config);
if (ret) {
dev_err(dev, "error in TX dma configuration.");
@@ -1193,6 +1214,7 @@ static int imx_uart_dma_init(struct imx_port *sport)
}
sport->dma_is_inited = 1;
+ request_bus_freq(BUS_FREQ_HIGH);
return 0;
err:
@@ -1204,16 +1226,20 @@ static void imx_enable_dma(struct imx_port *sport)
{
unsigned long temp;
+ init_waitqueue_head(&sport->dma_wait);
+ sport->flags = 0;
+
/* set UCR1 */
temp = readl(sport->port.membase + UCR1);
- temp |= UCR1_RDMAEN | UCR1_TDMAEN | UCR1_ATDMAEN;
+ temp |= UCR1_RDMAEN | UCR1_TDMAEN | UCR1_ATDMAEN |
+ /* wait for 32 idle frames for IDDMA interrupt */
+ UCR1_ICD_REG(3);
writel(temp, sport->port.membase + UCR1);
- temp = readl(sport->port.membase + UCR2);
- temp |= UCR2_ATEN;
- writel(temp, sport->port.membase + UCR2);
-
- imx_setup_ufcr(sport, TXTL_DMA, RXTL_DMA);
+ /* set UCR4 */
+ temp = readl(sport->port.membase + UCR4);
+ temp |= UCR4_IDDMAEN;
+ writel(temp, sport->port.membase + UCR4);
sport->dma_is_enabled = 1;
}
@@ -1229,10 +1255,13 @@ static void imx_disable_dma(struct imx_port *sport)
/* clear UCR2 */
temp = readl(sport->port.membase + UCR2);
- temp &= ~(UCR2_CTSC | UCR2_CTS | UCR2_ATEN);
+ temp &= ~(UCR2_CTSC | UCR2_CTS);
writel(temp, sport->port.membase + UCR2);
- imx_setup_ufcr(sport, TXTL_DEFAULT, RXTL_DEFAULT);
+ /* clear UCR4 */
+ temp = readl(sport->port.membase + UCR4);
+ temp &= ~UCR4_IDDMAEN;
+ writel(temp, sport->port.membase + UCR4);
sport->dma_is_enabled = 0;
}
@@ -1243,9 +1272,17 @@ static void imx_disable_dma(struct imx_port *sport)
static int imx_startup(struct uart_port *port)
{
struct imx_port *sport = (struct imx_port *)port;
+ struct tty_port *tty_port = &sport->port.state->port;
int retval, i;
unsigned long flags, temp;
+ /* some modem may need reset */
+ if (!tty_port_suspended(tty_port)) {
+ retval = device_reset(sport->port.dev);
+ if (retval && retval != -ENOENT)
+ return retval;
+ }
+
retval = clk_prepare_enable(sport->clk_per);
if (retval)
return retval;
@@ -1255,7 +1292,7 @@ static int imx_startup(struct uart_port *port)
return retval;
}
- imx_setup_ufcr(sport, TXTL_DEFAULT, RXTL_DEFAULT);
+ imx_setup_ufcr(sport, 0);
/* disable the DREN bit (Data Ready interrupt enable) before
* requesting IRQs
@@ -1268,11 +1305,6 @@ static int imx_startup(struct uart_port *port)
writel(temp & ~UCR4_DREN, sport->port.membase + UCR4);
- /* Can we enable the DMA support? */
- if (!uart_console(port) && !sport->dma_is_inited)
- imx_uart_dma_init(sport);
-
- spin_lock_irqsave(&sport->port.lock, flags);
/* Reset fifo's and state machines */
i = 100;
@@ -1283,20 +1315,28 @@ static int imx_startup(struct uart_port *port)
while (!(readl(sport->port.membase + UCR2) & UCR2_SRST) && (--i > 0))
udelay(1);
+ /* Can we enable the DMA support? */
+ if (is_imx6q_uart(sport) && !uart_console(port)
+ && !sport->dma_is_inited)
+ imx_uart_dma_init(sport);
+
+ if (sport->dma_is_inited)
+ INIT_WORK(&sport->tsk_dma_tx, dma_tx_work);
+
+ spin_lock_irqsave(&sport->port.lock, flags);
+
/*
* Finally, clear and enable interrupts
*/
- writel(USR1_RTSD | USR1_DTRD, sport->port.membase + USR1);
+ writel(USR1_RTSD, sport->port.membase + USR1);
writel(USR2_ORE, sport->port.membase + USR2);
- if (sport->dma_is_inited && !sport->dma_is_enabled)
- imx_enable_dma(sport);
-
temp = readl(sport->port.membase + UCR1);
- temp |= UCR1_RRDYEN | UCR1_UARTEN;
+ if (!sport->dma_is_inited)
+ temp |= UCR1_RRDYEN;
if (sport->have_rtscts)
- temp |= UCR1_RTSDEN;
-
+ temp |= UCR1_RTSDEN;
+ temp |= UCR1_UARTEN;
writel(temp, sport->port.membase + UCR1);
temp = readl(sport->port.membase + UCR4);
@@ -1354,10 +1394,20 @@ static void imx_shutdown(struct uart_port *port)
unsigned long flags;
if (sport->dma_is_enabled) {
- sport->dma_is_rxing = 0;
- sport->dma_is_txing = 0;
- dmaengine_terminate_sync(sport->dma_chan_tx);
- dmaengine_terminate_sync(sport->dma_chan_rx);
+ int ret;
+
+ /* We have to wait for the DMA to finish. */
+ ret = wait_event_interruptible_timeout(sport->dma_wait,
+ !sport->dma_is_rxing && !sport->dma_is_txing,
+ msecs_to_jiffies(1));
+ if (ret <= 0) {
+ sport->dma_is_rxing = 0;
+ sport->dma_is_txing = 0;
+ dmaengine_terminate_all(sport->dma_chan_tx);
+ dmaengine_terminate_all(sport->dma_chan_rx);
+ }
+
+ cancel_work_sync(&sport->tsk_dma_tx);
spin_lock_irqsave(&sport->port.lock, flags);
imx_stop_tx(port);
@@ -1413,7 +1463,9 @@ static void imx_flush_buffer(struct uart_port *port)
temp = readl(sport->port.membase + UCR1);
temp &= ~UCR1_TDMAEN;
writel(temp, sport->port.membase + UCR1);
- sport->dma_is_txing = false;
+ sport->dma_is_txing = 0;
+ clear_bit(DMA_TX_IS_WORKING, &sport->flags);
+ smp_mb__after_atomic();
}
/*
@@ -1446,10 +1498,9 @@ imx_set_termios(struct uart_port *port, struct ktermios *termios,
{
struct imx_port *sport = (struct imx_port *)port;
unsigned long flags;
- unsigned long ucr2, old_ucr1, old_ucr2;
- unsigned int baud, quot;
+ unsigned long ucr2, old_ucr1, old_txrxen, baud, quot;
unsigned int old_csize = old ? old->c_cflag & CSIZE : CS8;
- unsigned long div, ufcr;
+ unsigned int div, ufcr;
unsigned long num, denom;
uint64_t tdiv64;
@@ -1497,7 +1548,6 @@ imx_set_termios(struct uart_port *port, struct ktermios *termios,
imx_port_rts_inactive(sport, &ucr2);
}
-
if (termios->c_cflag & CSTOPB)
ucr2 |= UCR2_STPB;
if (termios->c_cflag & PARENB) {
@@ -1557,10 +1607,10 @@ imx_set_termios(struct uart_port *port, struct ktermios *termios,
barrier();
/* then, disable everything */
- old_ucr2 = readl(sport->port.membase + UCR2);
- writel(old_ucr2 & ~(UCR2_TXEN | UCR2_RXEN),
+ old_txrxen = readl(sport->port.membase + UCR2);
+ writel(old_txrxen & ~(UCR2_TXEN | UCR2_RXEN),
sport->port.membase + UCR2);
- old_ucr2 &= (UCR2_TXEN | UCR2_RXEN | UCR2_ATEN);
+ old_txrxen &= (UCR2_TXEN | UCR2_RXEN);
/* custom-baudrate handling */
div = sport->port.uartclk / (baud * 16);
@@ -1599,11 +1649,21 @@ imx_set_termios(struct uart_port *port, struct ktermios *termios,
writel(old_ucr1, sport->port.membase + UCR1);
/* set the parity, stop bits and data size */
- writel(ucr2 | old_ucr2, sport->port.membase + UCR2);
+ writel(ucr2 | old_txrxen, sport->port.membase + UCR2);
if (UART_ENABLE_MS(&sport->port, termios->c_cflag))
imx_enable_ms(&sport->port);
+ if (sport->dma_is_inited && !sport->dma_is_enabled) {
+ imx_enable_dma(sport);
+ start_rx_dma(sport);
+ }
+
+ if (!sport->dma_is_enabled) {
+ ucr2 = readl(sport->port.membase + UCR2);
+ writel(ucr2 | UCR2_ATEN, sport->port.membase + UCR2);
+ }
+
spin_unlock_irqrestore(&sport->port.lock, flags);
}
@@ -1669,7 +1729,7 @@ static int imx_poll_init(struct uart_port *port)
if (retval)
clk_disable_unprepare(sport->clk_ipg);
- imx_setup_ufcr(sport, TXTL_DEFAULT, RXTL_DEFAULT);
+ imx_setup_ufcr(sport, 0);
spin_lock_irqsave(&sport->port.lock, flags);
@@ -1944,7 +2004,7 @@ imx_console_setup(struct console *co, char *options)
else
imx_console_get_options(sport, &baud, &parity, &bits);
- imx_setup_ufcr(sport, TXTL_DEFAULT, RXTL_DEFAULT);
+ imx_setup_ufcr(sport, 0);
retval = uart_set_options(&sport->port, co, baud, parity, bits, flow);
@@ -2146,6 +2206,14 @@ static int serial_imx_probe(struct platform_device *pdev)
}
sport->port.uartclk = clk_get_rate(sport->clk_per);
+ if (sport->port.uartclk > IMX_MODULE_MAX_CLK_RATE) {
+ ret = clk_set_rate(sport->clk_per, IMX_MODULE_MAX_CLK_RATE);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "clk_set_rate() failed\n");
+ return ret;
+ }
+ }
+ sport->port.uartclk = clk_get_rate(sport->clk_per);
/* For register access, we only need to enable the ipg clock. */
ret = clk_prepare_enable(sport->clk_ipg);
@@ -2246,9 +2314,12 @@ static int serial_imx_remove(struct platform_device *pdev)
static void serial_imx_restore_context(struct imx_port *sport)
{
+ unsigned long flags = 0;
+
if (!sport->context_saved)
return;
+ spin_lock_irqsave(&sport->port.lock, flags);
writel(sport->saved_reg[4], sport->port.membase + UFCR);
writel(sport->saved_reg[5], sport->port.membase + UESC);
writel(sport->saved_reg[6], sport->port.membase + UTIM);
@@ -2260,11 +2331,15 @@ static void serial_imx_restore_context(struct imx_port *sport)
writel(sport->saved_reg[2], sport->port.membase + UCR3);
writel(sport->saved_reg[3], sport->port.membase + UCR4);
sport->context_saved = false;
+ spin_unlock_irqrestore(&sport->port.lock, flags);
}
static void serial_imx_save_context(struct imx_port *sport)
{
+ unsigned long flags = 0;
+
/* Save necessary regs */
+ spin_lock_irqsave(&sport->port.lock, flags);
sport->saved_reg[0] = readl(sport->port.membase + UCR1);
sport->saved_reg[1] = readl(sport->port.membase + UCR2);
sport->saved_reg[2] = readl(sport->port.membase + UCR3);
@@ -2276,12 +2351,20 @@ static void serial_imx_save_context(struct imx_port *sport)
sport->saved_reg[8] = readl(sport->port.membase + UBMR);
sport->saved_reg[9] = readl(sport->port.membase + IMX21_UTS);
sport->context_saved = true;
+
+ if (uart_console(&sport->port) && sport->port.sysrq)
+ sport->saved_reg[0] |= UCR1_RRDYEN;
+ spin_unlock_irqrestore(&sport->port.lock, flags);
}
static void serial_imx_enable_wakeup(struct imx_port *sport, bool on)
{
unsigned int val;
+ val = readl(sport->port.membase + USR1);
+ if (val & (USR1_AWAKE | USR1_RTSD))
+ writel(USR1_AWAKE | USR1_RTSD, sport->port.membase + USR1);
+
val = readl(sport->port.membase + UCR3);
if (on)
val |= UCR3_AWAKEN;
@@ -2309,10 +2392,15 @@ static int imx_serial_port_suspend_noirq(struct device *dev)
if (ret)
return ret;
+ /* enable wakeup from i.MX UART */
+ serial_imx_enable_wakeup(sport, true);
+
serial_imx_save_context(sport);
clk_disable(sport->clk_ipg);
+ pinctrl_pm_select_sleep_state(dev);
+
return 0;
}
@@ -2322,12 +2410,17 @@ static int imx_serial_port_resume_noirq(struct device *dev)
struct imx_port *sport = platform_get_drvdata(pdev);
int ret;
+ pinctrl_pm_select_default_state(dev);
+
ret = clk_enable(sport->clk_ipg);
if (ret)
return ret;
serial_imx_restore_context(sport);
+ /* disable wakeup from i.MX UART */
+ serial_imx_enable_wakeup(sport, false);
+
clk_disable(sport->clk_ipg);
return 0;
@@ -2338,9 +2431,6 @@ static int imx_serial_port_suspend(struct device *dev)
struct platform_device *pdev = to_platform_device(dev);
struct imx_port *sport = platform_get_drvdata(pdev);
- /* enable wakeup from i.MX UART */
- serial_imx_enable_wakeup(sport, true);
-
uart_suspend_port(&imx_reg, &sport->port);
disable_irq(sport->port.irq);
@@ -2353,9 +2443,6 @@ static int imx_serial_port_resume(struct device *dev)
struct platform_device *pdev = to_platform_device(dev);
struct imx_port *sport = platform_get_drvdata(pdev);
- /* disable wakeup from i.MX UART */
- serial_imx_enable_wakeup(sport, false);
-
uart_resume_port(&imx_reg, &sport->port);
enable_irq(sport->port.irq);
diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig
index 72eb3e41e3b6..5e810e2ae7df 100644
--- a/drivers/usb/Kconfig
+++ b/drivers/usb/Kconfig
@@ -125,6 +125,8 @@ source "drivers/usb/chipidea/Kconfig"
source "drivers/usb/isp1760/Kconfig"
+source "drivers/usb/cdns3/Kconfig"
+
comment "USB port drivers"
if USB
diff --git a/drivers/usb/Makefile b/drivers/usb/Makefile
index 060643a1b5c8..4a96f18a616f 100644
--- a/drivers/usb/Makefile
+++ b/drivers/usb/Makefile
@@ -11,6 +11,7 @@ obj-$(CONFIG_USB_SUPPORT) += phy/
obj-$(CONFIG_USB_DWC3) += dwc3/
obj-$(CONFIG_USB_DWC2) += dwc2/
obj-$(CONFIG_USB_ISP1760) += isp1760/
+obj-$(CONFIG_USB_CDNS3) += cdns3/
obj-$(CONFIG_USB_MON) += mon/
obj-$(CONFIG_USB_MTU3) += mtu3/
diff --git a/drivers/usb/cdns3/Kconfig b/drivers/usb/cdns3/Kconfig
new file mode 100644
index 000000000000..165afdb99d15
--- /dev/null
+++ b/drivers/usb/cdns3/Kconfig
@@ -0,0 +1,26 @@
+config USB_CDNS3
+ tristate "Cadence USB3 Dual-Role Controller"
+ depends on ((USB_XHCI_HCD && USB_GADGET) || (USB_XHCI_HCD && !USB_GADGET) || (!USB_XHCI_HCD && USB_GADGET)) && HAS_DMA
+ select EXTCON
+ help
+ Say Y here if your system has a cadence USB3 dual-role controller.
+ It supports: dual-role switch Host-only, and Peripheral-only.
+
+ When compiled dynamically, the module will be called cdns3.ko.
+
+if USB_CDNS3
+
+config USB_CDNS3_GADGET
+ bool "Cadence USB3 device controller"
+ depends on USB_GADGET
+ help
+ Say Y here to enable device controller functionality of the
+ cadence usb3 driver.
+
+config USB_CDNS3_HOST
+ bool "Cadence USB3 host controller"
+ depends on USB_XHCI_HCD
+ help
+ Say Y here to enable host controller functionality of the
+ cadence usb3 driver.
+endif
diff --git a/drivers/usb/cdns3/Makefile b/drivers/usb/cdns3/Makefile
new file mode 100644
index 000000000000..7328cb9fcc89
--- /dev/null
+++ b/drivers/usb/cdns3/Makefile
@@ -0,0 +1,5 @@
+obj-$(CONFIG_USB_CDNS3) += cdns3.o
+
+cdns3-y := core.o
+cdns3-$(CONFIG_USB_CDNS3_GADGET) += gadget.o
+cdns3-$(CONFIG_USB_CDNS3_HOST) += host.o
diff --git a/drivers/usb/cdns3/cdns3-nxp-reg-def.h b/drivers/usb/cdns3/cdns3-nxp-reg-def.h
new file mode 100644
index 000000000000..4ac73005c023
--- /dev/null
+++ b/drivers/usb/cdns3/cdns3-nxp-reg-def.h
@@ -0,0 +1,174 @@
+/**
+ * cdns3-nxp-reg-def.h - nxp wrap layer register definition
+ *
+ * Copyright 2017 NXP
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 of
+ * the License 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 __DRIVERS_USB_CDNS3_NXP_H
+#define __DRIVERS_USB_CDNS3_NXP_H
+
+#define USB3_CORE_CTRL1 0x00
+#define USB3_CORE_CTRL2 0x04
+#define USB3_INT_REG 0x08
+#define USB3_CORE_STATUS 0x0c
+#define XHCI_DEBUG_LINK_ST 0x10
+#define XHCI_DEBUG_BUS 0x14
+#define USB3_SSPHY_CTRL1 0x40
+#define USB3_SSPHY_CTRL2 0x44
+#define USB3_SSPHY_STATUS 0x4c
+#define USB2_PHY_CTRL1 0x50
+#define USB2_PHY_CTRL2 0x54
+#define USB2_PHY_STATUS 0x5c
+
+/* Register bits definition */
+
+/* USB3_CORE_CTRL1 */
+#define SW_RESET_MASK (0x3f << 26)
+#define PWR_SW_RESET (1 << 31)
+#define APB_SW_RESET (1 << 30)
+#define AXI_SW_RESET (1 << 29)
+#define RW_SW_RESET (1 << 28)
+#define PHY_SW_RESET (1 << 27)
+#define PHYAHB_SW_RESET (1 << 26)
+#define ALL_SW_RESET (PWR_SW_RESET | APB_SW_RESET | AXI_SW_RESET | \
+ RW_SW_RESET | PHY_SW_RESET | PHYAHB_SW_RESET)
+#define OC_DISABLE (1 << 9)
+#define MDCTRL_CLK_SEL (1 << 7)
+#define MODE_STRAP_MASK (0x7)
+#define DEV_MODE (1 << 2)
+#define HOST_MODE (1 << 1)
+#define OTG_MODE (1 << 0)
+
+/* USB3_INT_REG */
+#define CLK_125_REQ (1 << 29)
+#define LPM_CLK_REQ (1 << 28)
+#define DEVU3_WAEKUP_EN (1 << 14)
+#define OTG_WAKEUP_EN (1 << 12)
+#define DEV_INT_EN (3 << 8) /* DEV INT b9:8 */
+#define HOST_INT1_EN (1 << 0) /* HOST INT b7:0 */
+
+/* USB3_CORE_STATUS */
+#define MDCTRL_CLK_STATUS (1 << 15)
+#define DEV_POWER_ON_READY (1 << 13)
+#define HOST_POWER_ON_READY (1 << 12)
+
+/* USB3_SSPHY_STATUS */
+#define PHY_REFCLK_REQ (1 << 0)
+
+
+/* PHY register definition */
+#define PHY_PMA_CMN_CTRL1 (0xC800 * 4)
+#define TB_ADDR_CMN_DIAG_HSCLK_SEL (0x01e0 * 4)
+#define TB_ADDR_CMN_PLL0_VCOCAL_INIT_TMR (0x0084 * 4)
+#define TB_ADDR_CMN_PLL0_VCOCAL_ITER_TMR (0x0085 * 4)
+#define TB_ADDR_CMN_PLL0_INTDIV (0x0094 * 4)
+#define TB_ADDR_CMN_PLL0_FRACDIV (0x0095 * 4)
+#define TB_ADDR_CMN_PLL0_HIGH_THR (0x0096 * 4)
+#define TB_ADDR_CMN_PLL0_SS_CTRL1 (0x0098 * 4)
+#define TB_ADDR_CMN_PLL0_SS_CTRL2 (0x0099 * 4)
+#define TB_ADDR_CMN_PLL0_DSM_DIAG (0x0097 * 4)
+#define TB_ADDR_CMN_DIAG_PLL0_OVRD (0x01c2 * 4)
+#define TB_ADDR_CMN_DIAG_PLL0_FBH_OVRD (0x01c0 * 4)
+#define TB_ADDR_CMN_DIAG_PLL0_FBL_OVRD (0x01c1 * 4)
+#define TB_ADDR_CMN_DIAG_PLL0_V2I_TUNE (0x01C5 * 4)
+#define TB_ADDR_CMN_DIAG_PLL0_CP_TUNE (0x01C6 * 4)
+#define TB_ADDR_CMN_DIAG_PLL0_LF_PROG (0x01C7 * 4)
+#define TB_ADDR_CMN_DIAG_PLL0_TEST_MODE (0x01c4 * 4)
+#define TB_ADDR_CMN_PSM_CLK_CTRL (0x0061 * 4)
+#define TB_ADDR_XCVR_DIAG_RX_LANE_CAL_RST_TMR (0x40ea * 4)
+#define TB_ADDR_XCVR_PSM_RCTRL (0x4001 * 4)
+#define TB_ADDR_TX_PSC_A0 (0x4100 * 4)
+#define TB_ADDR_TX_PSC_A1 (0x4101 * 4)
+#define TB_ADDR_TX_PSC_A2 (0x4102 * 4)
+#define TB_ADDR_TX_PSC_A3 (0x4103 * 4)
+#define TB_ADDR_TX_DIAG_ECTRL_OVRD (0x41f5 * 4)
+#define TB_ADDR_TX_PSC_CAL (0x4106 * 4)
+#define TB_ADDR_TX_PSC_RDY (0x4107 * 4)
+#define TB_ADDR_RX_PSC_A0 (0x8000 * 4)
+#define TB_ADDR_RX_PSC_A1 (0x8001 * 4)
+#define TB_ADDR_RX_PSC_A2 (0x8002 * 4)
+#define TB_ADDR_RX_PSC_A3 (0x8003 * 4)
+#define TB_ADDR_RX_PSC_CAL (0x8006 * 4)
+#define TB_ADDR_RX_PSC_RDY (0x8007 * 4)
+#define TB_ADDR_TX_TXCC_MGNLS_MULT_000 (0x4058 * 4)
+#define TB_ADDR_TX_DIAG_BGREF_PREDRV_DELAY (0x41e7 * 4)
+#define TB_ADDR_RX_SLC_CU_ITER_TMR (0x80e3 * 4)
+#define TB_ADDR_RX_SIGDET_HL_FILT_TMR (0x8090 * 4)
+#define TB_ADDR_RX_SAMP_DAC_CTRL (0x8058 * 4)
+#define TB_ADDR_RX_DIAG_SIGDET_TUNE (0x81dc * 4)
+#define TB_ADDR_RX_DIAG_LFPSDET_TUNE2 (0x81df * 4)
+#define TB_ADDR_RX_DIAG_BS_TM (0x81f5 * 4)
+#define TB_ADDR_RX_DIAG_DFE_CTRL1 (0x81d3 * 4)
+#define TB_ADDR_RX_DIAG_ILL_IQE_TRIM4 (0x81c7 * 4)
+#define TB_ADDR_RX_DIAG_ILL_E_TRIM0 (0x81c2 * 4)
+#define TB_ADDR_RX_DIAG_ILL_IQ_TRIM0 (0x81c1 * 4)
+#define TB_ADDR_RX_DIAG_ILL_IQE_TRIM6 (0x81c9 * 4)
+#define TB_ADDR_RX_DIAG_RXFE_TM3 (0x81f8 * 4)
+#define TB_ADDR_RX_DIAG_RXFE_TM4 (0x81f9 * 4)
+#define TB_ADDR_RX_DIAG_LFPSDET_TUNE (0x81dd * 4)
+#define TB_ADDR_RX_DIAG_DFE_CTRL3 (0x81d5 * 4)
+#define TB_ADDR_RX_DIAG_SC2C_DELAY (0x81e1 * 4)
+#define TB_ADDR_RX_REE_VGA_GAIN_NODFE (0x81bf * 4)
+#define TB_ADDR_XCVR_PSM_CAL_TMR (0x4002 * 4)
+#define TB_ADDR_XCVR_PSM_A0BYP_TMR (0x4004 * 4)
+#define TB_ADDR_XCVR_PSM_A0IN_TMR (0x4003 * 4)
+#define TB_ADDR_XCVR_PSM_A1IN_TMR (0x4005 * 4)
+#define TB_ADDR_XCVR_PSM_A2IN_TMR (0x4006 * 4)
+#define TB_ADDR_XCVR_PSM_A3IN_TMR (0x4007 * 4)
+#define TB_ADDR_XCVR_PSM_A4IN_TMR (0x4008 * 4)
+#define TB_ADDR_XCVR_PSM_A5IN_TMR (0x4009 * 4)
+#define TB_ADDR_XCVR_PSM_A0OUT_TMR (0x400a * 4)
+#define TB_ADDR_XCVR_PSM_A1OUT_TMR (0x400b * 4)
+#define TB_ADDR_XCVR_PSM_A2OUT_TMR (0x400c * 4)
+#define TB_ADDR_XCVR_PSM_A3OUT_TMR (0x400d * 4)
+#define TB_ADDR_XCVR_PSM_A4OUT_TMR (0x400e * 4)
+#define TB_ADDR_XCVR_PSM_A5OUT_TMR (0x400f * 4)
+#define TB_ADDR_TX_RCVDET_EN_TMR (0x4122 * 4)
+#define TB_ADDR_TX_RCVDET_ST_TMR (0x4123 * 4)
+#define TB_ADDR_XCVR_DIAG_LANE_FCM_EN_MGN_TMR (0x40f2 * 4)
+#define TB_ADDR_TX_RCVDETSC_CTRL (0x4124 * 4)
+
+/* Register bits definition */
+
+/* TB_ADDR_TX_RCVDETSC_CTRL */
+#define RXDET_IN_P3_32KHZ (1 << 0)
+
+/* OTG registers definition */
+#define OTGSTS 0x4
+#define OTGREFCLK 0xc
+
+/* Register bits definition */
+/* OTGSTS */
+#define OTG_NRDY (1 << 11)
+/* OTGREFCLK */
+#define OTG_STB_CLK_SWITCH_EN (1 << 31)
+
+/* xHCI registers definition */
+#define XECP_PORT_CAP_REG 0x8000
+#define XECP_PM_PMCSR 0x8018
+#define XECP_AUX_CTRL_REG1 0x8120
+
+/* Register bits definition */
+/* XECP_PORT_CAP_REG */
+#define LPM_2_STB_SWITCH_EN (1 << 25)
+
+/* XECP_AUX_CTRL_REG1 */
+#define CFG_RXDET_P3_EN (1 << 15)
+
+/* XECP_PM_PMCSR */
+#define PS_MASK (3 << 0)
+#define PS_D0 0
+#define PS_D1 (1 << 0)
+#endif /* __DRIVERS_USB_CDNS3_NXP_H */
diff --git a/drivers/usb/cdns3/core.c b/drivers/usb/cdns3/core.c
new file mode 100644
index 000000000000..b8a183f03af7
--- /dev/null
+++ b/drivers/usb/cdns3/core.c
@@ -0,0 +1,1009 @@
+/**
+ * core.c - Cadence USB3 DRD Controller Core file
+ *
+ * Copyright 2017 NXP
+ *
+ * Authors: Peter Chen <peter.chen@nxp.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 of
+ * the License 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/module.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/io.h>
+#include <linux/clk.h>
+#include <linux/usb/of.h>
+#include <linux/usb/phy.h>
+#include <linux/extcon.h>
+#include <linux/pm_runtime.h>
+
+#include "cdns3-nxp-reg-def.h"
+#include "core.h"
+#include "host-export.h"
+#include "gadget-export.h"
+
+static void cdns3_usb_phy_init(void __iomem *regs)
+{
+ u32 value;
+
+ pr_debug("begin of %s\n", __func__);
+
+ writel(0x0830, regs + PHY_PMA_CMN_CTRL1);
+ writel(0x10, regs + TB_ADDR_CMN_DIAG_HSCLK_SEL);
+ writel(0x00F0, regs + TB_ADDR_CMN_PLL0_VCOCAL_INIT_TMR);
+ writel(0x0018, regs + TB_ADDR_CMN_PLL0_VCOCAL_ITER_TMR);
+ writel(0x00D0, regs + TB_ADDR_CMN_PLL0_INTDIV);
+ writel(0x4aaa, regs + TB_ADDR_CMN_PLL0_FRACDIV);
+ writel(0x0034, regs + TB_ADDR_CMN_PLL0_HIGH_THR);
+ writel(0x1ee, regs + TB_ADDR_CMN_PLL0_SS_CTRL1);
+ writel(0x7F03, regs + TB_ADDR_CMN_PLL0_SS_CTRL2);
+ writel(0x0020, regs + TB_ADDR_CMN_PLL0_DSM_DIAG);
+ writel(0x0000, regs + TB_ADDR_CMN_DIAG_PLL0_OVRD);
+ writel(0x0000, regs + TB_ADDR_CMN_DIAG_PLL0_FBH_OVRD);
+ writel(0x0000, regs + TB_ADDR_CMN_DIAG_PLL0_FBL_OVRD);
+ writel(0x0007, regs + TB_ADDR_CMN_DIAG_PLL0_V2I_TUNE);
+ writel(0x0027, regs + TB_ADDR_CMN_DIAG_PLL0_CP_TUNE);
+ writel(0x0008, regs + TB_ADDR_CMN_DIAG_PLL0_LF_PROG);
+ writel(0x0022, regs + TB_ADDR_CMN_DIAG_PLL0_TEST_MODE);
+ writel(0x000a, regs + TB_ADDR_CMN_PSM_CLK_CTRL);
+ writel(0x139, regs + TB_ADDR_XCVR_DIAG_RX_LANE_CAL_RST_TMR);
+ writel(0xbefc, regs + TB_ADDR_XCVR_PSM_RCTRL);
+
+ writel(0x7799, regs + TB_ADDR_TX_PSC_A0);
+ writel(0x7798, regs + TB_ADDR_TX_PSC_A1);
+ writel(0x509b, regs + TB_ADDR_TX_PSC_A2);
+ writel(0x3, regs + TB_ADDR_TX_DIAG_ECTRL_OVRD);
+ writel(0x509b, regs + TB_ADDR_TX_PSC_A3);
+ writel(0x2090, regs + TB_ADDR_TX_PSC_CAL);
+ writel(0x2090, regs + TB_ADDR_TX_PSC_RDY);
+
+ writel(0xA6FD, regs + TB_ADDR_RX_PSC_A0);
+ writel(0xA6FD, regs + TB_ADDR_RX_PSC_A1);
+ writel(0xA410, regs + TB_ADDR_RX_PSC_A2);
+ writel(0x2410, regs + TB_ADDR_RX_PSC_A3);
+
+ writel(0x23FF, regs + TB_ADDR_RX_PSC_CAL);
+ writel(0x2010, regs + TB_ADDR_RX_PSC_RDY);
+
+ writel(0x0020, regs + TB_ADDR_TX_TXCC_MGNLS_MULT_000);
+ writel(0x00ff, regs + TB_ADDR_TX_DIAG_BGREF_PREDRV_DELAY);
+ writel(0x0002, regs + TB_ADDR_RX_SLC_CU_ITER_TMR);
+ writel(0x0013, regs + TB_ADDR_RX_SIGDET_HL_FILT_TMR);
+ writel(0x0000, regs + TB_ADDR_RX_SAMP_DAC_CTRL);
+ writel(0x1004, regs + TB_ADDR_RX_DIAG_SIGDET_TUNE);
+ writel(0x4041, regs + TB_ADDR_RX_DIAG_LFPSDET_TUNE2);
+ writel(0x0480, regs + TB_ADDR_RX_DIAG_BS_TM);
+ writel(0x8006, regs + TB_ADDR_RX_DIAG_DFE_CTRL1);
+ writel(0x003f, regs + TB_ADDR_RX_DIAG_ILL_IQE_TRIM4);
+ writel(0x543f, regs + TB_ADDR_RX_DIAG_ILL_E_TRIM0);
+ writel(0x543f, regs + TB_ADDR_RX_DIAG_ILL_IQ_TRIM0);
+ writel(0x0000, regs + TB_ADDR_RX_DIAG_ILL_IQE_TRIM6);
+ writel(0x8000, regs + TB_ADDR_RX_DIAG_RXFE_TM3);
+ writel(0x0003, regs + TB_ADDR_RX_DIAG_RXFE_TM4);
+ writel(0x2408, regs + TB_ADDR_RX_DIAG_LFPSDET_TUNE);
+ writel(0x05ca, regs + TB_ADDR_RX_DIAG_DFE_CTRL3);
+ writel(0x0258, regs + TB_ADDR_RX_DIAG_SC2C_DELAY);
+ writel(0x1fff, regs + TB_ADDR_RX_REE_VGA_GAIN_NODFE);
+
+ writel(0x02c6, regs + TB_ADDR_XCVR_PSM_CAL_TMR);
+ writel(0x0002, regs + TB_ADDR_XCVR_PSM_A0BYP_TMR);
+ writel(0x02c6, regs + TB_ADDR_XCVR_PSM_A0IN_TMR);
+ writel(0x0010, regs + TB_ADDR_XCVR_PSM_A1IN_TMR);
+ writel(0x0010, regs + TB_ADDR_XCVR_PSM_A2IN_TMR);
+ writel(0x0010, regs + TB_ADDR_XCVR_PSM_A3IN_TMR);
+ writel(0x0010, regs + TB_ADDR_XCVR_PSM_A4IN_TMR);
+ writel(0x0010, regs + TB_ADDR_XCVR_PSM_A5IN_TMR);
+
+ writel(0x0002, regs + TB_ADDR_XCVR_PSM_A0OUT_TMR);
+ writel(0x0002, regs + TB_ADDR_XCVR_PSM_A1OUT_TMR);
+ writel(0x0002, regs + TB_ADDR_XCVR_PSM_A2OUT_TMR);
+ writel(0x0002, regs + TB_ADDR_XCVR_PSM_A3OUT_TMR);
+ writel(0x0002, regs + TB_ADDR_XCVR_PSM_A4OUT_TMR);
+ writel(0x0002, regs + TB_ADDR_XCVR_PSM_A5OUT_TMR);
+
+ /* Change rx detect parameter */
+ writel(0x960, regs + TB_ADDR_TX_RCVDET_EN_TMR);
+ writel(0x01e0, regs + TB_ADDR_TX_RCVDET_ST_TMR);
+ writel(0x0090, regs + TB_ADDR_XCVR_DIAG_LANE_FCM_EN_MGN_TMR);
+
+ /* RXDET_IN_P3_32KHZ, Receiver detect slow clock enable */
+ value = readl(regs + TB_ADDR_TX_RCVDETSC_CTRL);
+ value |= RXDET_IN_P3_32KHZ;
+ writel(value, regs + TB_ADDR_TX_RCVDETSC_CTRL);
+
+ udelay(10);
+
+ pr_debug("end of %s\n", __func__);
+}
+
+static void cdns_set_role(struct cdns3 *cdns, enum cdns3_roles role)
+{
+ u32 value;
+ int timeout_us = 100000;
+ void __iomem *xhci_regs = cdns->xhci_regs;
+
+ if (role == CDNS3_ROLE_END)
+ return;
+
+ /* Wait clk value */
+ value = readl(cdns->none_core_regs + USB3_SSPHY_STATUS);
+ writel(value, cdns->none_core_regs + USB3_SSPHY_STATUS);
+ udelay(1);
+ value = readl(cdns->none_core_regs + USB3_SSPHY_STATUS);
+ while ((value & 0xf0000000) != 0xf0000000 && timeout_us-- > 0) {
+ value = readl(cdns->none_core_regs + USB3_SSPHY_STATUS);
+ dev_dbg(cdns->dev, "clkvld:0x%x\n", value);
+ udelay(1);
+ }
+
+ if (timeout_us <= 0)
+ dev_err(cdns->dev, "wait clkvld timeout\n");
+
+ /* Set all Reset bits */
+ value = readl(cdns->none_core_regs + USB3_CORE_CTRL1);
+ value |= ALL_SW_RESET;
+ writel(value, cdns->none_core_regs + USB3_CORE_CTRL1);
+ udelay(1);
+
+ if (role == CDNS3_ROLE_HOST) {
+ value = readl(cdns->none_core_regs + USB3_CORE_CTRL1);
+ value = (value & ~MODE_STRAP_MASK) | HOST_MODE | OC_DISABLE;
+ writel(value, cdns->none_core_regs + USB3_CORE_CTRL1);
+ value &= ~PHYAHB_SW_RESET;
+ writel(value, cdns->none_core_regs + USB3_CORE_CTRL1);
+ mdelay(1);
+ cdns3_usb_phy_init(cdns->phy_regs);
+ /* Force B Session Valid as 1 */
+ writel(0x0060, cdns->phy_regs + 0x380a4);
+ mdelay(1);
+
+ value = readl(cdns->none_core_regs + USB3_INT_REG);
+ value |= HOST_INT1_EN;
+ writel(value, cdns->none_core_regs + USB3_INT_REG);
+
+ value = readl(cdns->none_core_regs + USB3_CORE_CTRL1);
+ value &= ~ALL_SW_RESET;
+ writel(value, cdns->none_core_regs + USB3_CORE_CTRL1);
+
+ dev_dbg(cdns->dev, "wait xhci_power_on_ready\n");
+
+ value = readl(cdns->none_core_regs + USB3_CORE_STATUS);
+ timeout_us = 100000;
+ while (!(value & HOST_POWER_ON_READY) && timeout_us-- > 0) {
+ value = readl(cdns->none_core_regs + USB3_CORE_STATUS);
+ udelay(1);
+ }
+
+ if (timeout_us <= 0)
+ dev_err(cdns->dev, "wait xhci_power_on_ready timeout\n");
+
+ value = readl(xhci_regs + XECP_PORT_CAP_REG);
+ value |= LPM_2_STB_SWITCH_EN;
+ writel(value, xhci_regs + XECP_PORT_CAP_REG);
+
+ mdelay(1);
+
+ dev_dbg(cdns->dev, "switch to host role successfully\n");
+ } else { /* gadget mode */
+ value = readl(cdns->none_core_regs + USB3_CORE_CTRL1);
+ value = (value & ~MODE_STRAP_MASK) | DEV_MODE;
+ writel(value, cdns->none_core_regs + USB3_CORE_CTRL1);
+ value &= ~PHYAHB_SW_RESET;
+ writel(value, cdns->none_core_regs + USB3_CORE_CTRL1);
+
+ cdns3_usb_phy_init(cdns->phy_regs);
+ /* Force B Session Valid as 1 */
+ writel(0x0060, cdns->phy_regs + 0x380a4);
+ value = readl(cdns->none_core_regs + USB3_INT_REG);
+ value |= DEV_INT_EN;
+ writel(value, cdns->none_core_regs + USB3_INT_REG);
+
+ value = readl(cdns->none_core_regs + USB3_CORE_CTRL1);
+ value &= ~ALL_SW_RESET;
+ writel(value, cdns->none_core_regs + USB3_CORE_CTRL1);
+
+ dev_dbg(cdns->dev, "wait gadget_power_on_ready\n");
+
+ value = readl(cdns->none_core_regs + USB3_CORE_STATUS);
+ timeout_us = 100000;
+ while (!(value & DEV_POWER_ON_READY) && timeout_us-- > 0) {
+ value = readl(cdns->none_core_regs + USB3_CORE_STATUS);
+ udelay(1);
+ }
+
+ if (timeout_us <= 0)
+ dev_err(cdns->dev,
+ "wait gadget_power_on_ready timeout\n");
+
+ mdelay(1);
+
+ dev_dbg(cdns->dev, "switch to gadget role successfully\n");
+ }
+}
+
+static enum cdns3_roles cdns3_get_role(struct cdns3 *cdns)
+{
+ if (cdns->roles[CDNS3_ROLE_HOST] && cdns->roles[CDNS3_ROLE_GADGET]) {
+ if (extcon_get_state(cdns->extcon, EXTCON_USB_HOST))
+ return CDNS3_ROLE_HOST;
+ else if (extcon_get_state(cdns->extcon, EXTCON_USB))
+ return CDNS3_ROLE_GADGET;
+ else
+ return CDNS3_ROLE_END;
+ } else {
+ return cdns->roles[CDNS3_ROLE_HOST]
+ ? CDNS3_ROLE_HOST
+ : CDNS3_ROLE_GADGET;
+ }
+}
+
+/**
+ * cdns3_core_init_role - initialize role of operation
+ * @cdns: Pointer to cdns3 structure
+ *
+ * Returns 0 on success otherwise negative errno
+ */
+static int cdns3_core_init_role(struct cdns3 *cdns)
+{
+ struct device *dev = cdns->dev;
+ enum usb_dr_mode dr_mode = usb_get_dr_mode(dev);
+
+ cdns->role = CDNS3_ROLE_END;
+ if (dr_mode == USB_DR_MODE_UNKNOWN)
+ dr_mode = USB_DR_MODE_OTG;
+
+ if (dr_mode == USB_DR_MODE_OTG || dr_mode == USB_DR_MODE_HOST) {
+ if (cdns3_host_init(cdns))
+ dev_info(dev, "doesn't support host\n");
+ }
+
+ if (dr_mode == USB_DR_MODE_OTG || dr_mode == USB_DR_MODE_PERIPHERAL) {
+ if (cdns3_gadget_init(cdns))
+ dev_info(dev, "doesn't support gadget\n");
+ }
+
+ if (!cdns->roles[CDNS3_ROLE_HOST] && !cdns->roles[CDNS3_ROLE_GADGET]) {
+ dev_err(dev, "no supported roles\n");
+ return -ENODEV;
+ }
+
+ return 0;
+}
+
+/**
+ * cdns3_irq - interrupt handler for cdns3 core device
+ *
+ * @irq: irq number for cdns3 core device
+ * @data: structure of cdns3
+ *
+ * Returns IRQ_HANDLED or IRQ_NONE
+ */
+static irqreturn_t cdns3_irq(int irq, void *data)
+{
+ struct cdns3 *cdns = data;
+ irqreturn_t ret = IRQ_NONE;
+
+ if (cdns->in_lpm) {
+ disable_irq_nosync(cdns->irq);
+ cdns->wakeup_int = true;
+ pm_runtime_get(cdns->dev);
+ return IRQ_HANDLED;
+ }
+
+ /* Handle device/host interrupt */
+ if (cdns->role != CDNS3_ROLE_END)
+ ret = cdns3_role(cdns)->irq(cdns);
+
+ return ret;
+}
+
+static int cdns3_get_clks(struct device *dev)
+{
+ struct cdns3 *cdns = dev_get_drvdata(dev);
+ int ret = 0;
+
+ cdns->cdns3_clks[0] = devm_clk_get(dev, "usb3_lpm_clk");
+ if (IS_ERR(cdns->cdns3_clks[0])) {
+ ret = PTR_ERR(cdns->cdns3_clks[0]);
+ dev_err(dev, "Failed to get usb3_lpm_clk, err=%d\n", ret);
+ return ret;
+ }
+
+ cdns->cdns3_clks[1] = devm_clk_get(dev, "usb3_bus_clk");
+ if (IS_ERR(cdns->cdns3_clks[1])) {
+ ret = PTR_ERR(cdns->cdns3_clks[1]);
+ dev_err(dev, "Failed to get usb3_bus_clk, err=%d\n", ret);
+ return ret;
+ }
+
+ cdns->cdns3_clks[2] = devm_clk_get(dev, "usb3_aclk");
+ if (IS_ERR(cdns->cdns3_clks[2])) {
+ ret = PTR_ERR(cdns->cdns3_clks[2]);
+ dev_err(dev, "Failed to get usb3_aclk, err=%d\n", ret);
+ return ret;
+ }
+
+ cdns->cdns3_clks[3] = devm_clk_get(dev, "usb3_ipg_clk");
+ if (IS_ERR(cdns->cdns3_clks[3])) {
+ ret = PTR_ERR(cdns->cdns3_clks[3]);
+ dev_err(dev, "Failed to get usb3_ipg_clk, err=%d\n", ret);
+ return ret;
+ }
+
+ cdns->cdns3_clks[4] = devm_clk_get(dev, "usb3_core_pclk");
+ if (IS_ERR(cdns->cdns3_clks[4])) {
+ ret = PTR_ERR(cdns->cdns3_clks[4]);
+ dev_err(dev, "Failed to get usb3_core_pclk, err=%d\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int cdns3_prepare_enable_clks(struct device *dev)
+{
+ struct cdns3 *cdns = dev_get_drvdata(dev);
+ int i, j, ret = 0;
+
+ for (i = 0; i < CDNS3_NUM_OF_CLKS; i++) {
+ ret = clk_prepare_enable(cdns->cdns3_clks[i]);
+ if (ret) {
+ dev_err(dev,
+ "Failed to prepare/enable cdns3 clk, err=%d\n",
+ ret);
+ goto err;
+ }
+ }
+
+ return ret;
+err:
+ for (j = i; j > 0; j--)
+ clk_disable_unprepare(cdns->cdns3_clks[j - 1]);
+
+ return ret;
+}
+
+static void cdns3_disable_unprepare_clks(struct device *dev)
+{
+ struct cdns3 *cdns = dev_get_drvdata(dev);
+ int i;
+
+ for (i = CDNS3_NUM_OF_CLKS - 1; i >= 0; i--)
+ clk_disable_unprepare(cdns->cdns3_clks[i]);
+}
+
+static void cdns3_remove_roles(struct cdns3 *cdns)
+{
+ cdns3_gadget_remove(cdns);
+ cdns3_host_remove(cdns);
+}
+
+static int cdns3_do_role_switch(struct cdns3 *cdns, enum cdns3_roles role)
+{
+ int ret = 0;
+ enum cdns3_roles current_role;
+
+ dev_dbg(cdns->dev, "current role is %d, switch to %d\n",
+ cdns->role, role);
+
+ if (cdns->role == role)
+ return 0;
+
+ pm_runtime_get_sync(cdns->dev);
+ current_role = cdns->role;
+ cdns3_role_stop(cdns);
+ if (role == CDNS3_ROLE_END) {
+ /* Force B Session Valid as 0 */
+ writel(0x0040, cdns->phy_regs + 0x380a4);
+ pm_runtime_put_sync(cdns->dev);
+ return 0;
+ }
+
+ cdns_set_role(cdns, role);
+ ret = cdns3_role_start(cdns, role);
+ if (ret) {
+ /* Back to current role */
+ dev_err(cdns->dev, "set %d has failed, back to %d\n",
+ role, current_role);
+ cdns_set_role(cdns, current_role);
+ ret = cdns3_role_start(cdns, current_role);
+ }
+
+ pm_runtime_put_sync(cdns->dev);
+ return ret;
+}
+
+/**
+ * cdns3_role_switch - work queue handler for role switch
+ *
+ * @work: work queue item structure
+ *
+ * Handles below events:
+ * - Role switch for dual-role devices
+ * - CDNS3_ROLE_GADGET <--> CDNS3_ROLE_END for peripheral-only devices
+ */
+static void cdns3_role_switch(struct work_struct *work)
+{
+ struct cdns3 *cdns = container_of(work, struct cdns3,
+ role_switch_wq);
+ bool device, host;
+
+ host = extcon_get_state(cdns->extcon, EXTCON_USB_HOST);
+ device = extcon_get_state(cdns->extcon, EXTCON_USB);
+
+ if (host) {
+ if (cdns->roles[CDNS3_ROLE_HOST])
+ cdns3_do_role_switch(cdns, CDNS3_ROLE_HOST);
+ return;
+ }
+
+ if (device)
+ cdns3_do_role_switch(cdns, CDNS3_ROLE_GADGET);
+ else
+ cdns3_do_role_switch(cdns, CDNS3_ROLE_END);
+}
+
+static int cdns3_extcon_notifier(struct notifier_block *nb, unsigned long event,
+ void *ptr)
+{
+ struct cdns3 *cdns = container_of(nb, struct cdns3, extcon_nb);
+
+ queue_work(system_freezable_wq, &cdns->role_switch_wq);
+
+ return NOTIFY_DONE;
+}
+
+static int cdns3_register_extcon(struct cdns3 *cdns)
+{
+ struct extcon_dev *extcon;
+ struct device *dev = cdns->dev;
+ int ret;
+
+ if (of_property_read_bool(dev->of_node, "extcon")) {
+ extcon = extcon_get_edev_by_phandle(dev, 0);
+ if (IS_ERR(extcon))
+ return PTR_ERR(extcon);
+
+ ret = devm_extcon_register_notifier(dev, extcon,
+ EXTCON_USB_HOST, &cdns->extcon_nb);
+ if (ret < 0) {
+ dev_err(dev, "register Host Connector failed\n");
+ return ret;
+ }
+
+ ret = devm_extcon_register_notifier(dev, extcon,
+ EXTCON_USB, &cdns->extcon_nb);
+ if (ret < 0) {
+ dev_err(dev, "register Device Connector failed\n");
+ return ret;
+ }
+
+ cdns->extcon = extcon;
+ cdns->extcon_nb.notifier_call = cdns3_extcon_notifier;
+ }
+
+ return 0;
+}
+
+/**
+ * cdns3_probe - probe for cdns3 core device
+ * @pdev: Pointer to cdns3 core platform device
+ *
+ * Returns 0 on success otherwise negative errno
+ */
+static int cdns3_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct resource *res;
+ struct cdns3 *cdns;
+ void __iomem *regs;
+ int ret;
+
+ cdns = devm_kzalloc(dev, sizeof(*cdns), GFP_KERNEL);
+ if (!cdns)
+ return -ENOMEM;
+
+ cdns->dev = dev;
+ platform_set_drvdata(pdev, cdns);
+
+ res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+ if (!res) {
+ dev_err(dev, "missing IRQ\n");
+ return -ENODEV;
+ }
+ cdns->irq = res->start;
+
+ /*
+ * Request memory region
+ * region-0: nxp wrap registers
+ * region-1: xHCI
+ * region-2: Peripheral
+ * region-3: PHY registers
+ * region-4: OTG registers
+ */
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ regs = devm_ioremap_resource(dev, res);
+ if (IS_ERR(regs))
+ return PTR_ERR(regs);
+ cdns->none_core_regs = regs;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+ regs = devm_ioremap_resource(dev, res);
+ if (IS_ERR(regs))
+ return PTR_ERR(regs);
+ cdns->xhci_regs = regs;
+ cdns->xhci_res = res;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 2);
+ regs = devm_ioremap_resource(dev, res);
+ if (IS_ERR(regs))
+ return PTR_ERR(regs);
+ cdns->dev_regs = regs;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 3);
+ regs = devm_ioremap_resource(dev, res);
+ if (IS_ERR(regs))
+ return PTR_ERR(regs);
+ cdns->phy_regs = regs;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 4);
+ regs = devm_ioremap_resource(dev, res);
+ if (IS_ERR(regs))
+ return PTR_ERR(regs);
+ cdns->otg_regs = regs;
+
+ mutex_init(&cdns->mutex);
+ ret = cdns3_get_clks(dev);
+ if (ret)
+ return ret;
+
+ ret = cdns3_prepare_enable_clks(dev);
+ if (ret)
+ return ret;
+
+ cdns->usbphy = devm_usb_get_phy_by_phandle(dev, "cdns3,usbphy", 0);
+ if (IS_ERR(cdns->usbphy)) {
+ ret = PTR_ERR(cdns->usbphy);
+ if (ret == -ENODEV)
+ ret = -EINVAL;
+ goto err1;
+ }
+
+ ret = usb_phy_init(cdns->usbphy);
+ if (ret)
+ goto err1;
+
+ ret = cdns3_core_init_role(cdns);
+ if (ret)
+ goto err2;
+
+ if (cdns->roles[CDNS3_ROLE_GADGET]) {
+ INIT_WORK(&cdns->role_switch_wq, cdns3_role_switch);
+ ret = cdns3_register_extcon(cdns);
+ if (ret)
+ goto err3;
+ }
+
+ cdns->role = cdns3_get_role(cdns);
+ dev_dbg(dev, "the init role is %d\n", cdns->role);
+ cdns_set_role(cdns, cdns->role);
+ ret = cdns3_role_start(cdns, cdns->role);
+ if (ret) {
+ dev_err(dev, "can't start %s role\n",
+ cdns3_role(cdns)->name);
+ goto err3;
+ }
+
+ ret = devm_request_irq(dev, cdns->irq, cdns3_irq, IRQF_SHARED,
+ dev_name(dev), cdns);
+ if (ret)
+ goto err4;
+
+ device_set_wakeup_capable(dev, true);
+ pm_runtime_set_active(dev);
+ pm_runtime_enable(dev);
+ /*
+ * The controller needs less time between bus and controller suspend,
+ * and we also needs a small delay to avoid frequently entering low
+ * power mode.
+ */
+ pm_runtime_set_autosuspend_delay(dev, 20);
+ pm_runtime_mark_last_busy(dev);
+ pm_runtime_use_autosuspend(dev);
+ dev_dbg(dev, "Cadence USB3 core: probe succeed\n");
+
+ return 0;
+
+err4:
+ cdns3_role_stop(cdns);
+err3:
+ cdns3_remove_roles(cdns);
+err2:
+ usb_phy_shutdown(cdns->usbphy);
+err1:
+ cdns3_disable_unprepare_clks(dev);
+ return ret;
+}
+
+/**
+ * cdns3_remove - unbind our drd driver and clean up
+ * @pdev: Pointer to Linux platform device
+ *
+ * Returns 0 on success otherwise negative errno
+ */
+static int cdns3_remove(struct platform_device *pdev)
+{
+ struct cdns3 *cdns = platform_get_drvdata(pdev);
+
+ pm_runtime_get_sync(&pdev->dev);
+ pm_runtime_disable(&pdev->dev);
+ pm_runtime_put_noidle(&pdev->dev);
+ cdns3_remove_roles(cdns);
+ usb_phy_shutdown(cdns->usbphy);
+ cdns3_disable_unprepare_clks(&pdev->dev);
+
+ return 0;
+}
+
+#ifdef CONFIG_OF
+static const struct of_device_id of_cdns3_match[] = {
+ { .compatible = "Cadence,usb3" },
+ { },
+};
+MODULE_DEVICE_TABLE(of, of_cdns3_match);
+#endif
+
+#ifdef CONFIG_PM
+static inline bool controller_power_is_lost(struct cdns3 *cdns)
+{
+ u32 value;
+
+ value = readl(cdns->none_core_regs + USB3_CORE_CTRL1);
+ if ((value & SW_RESET_MASK) == ALL_SW_RESET)
+ return true;
+ else
+ return false;
+}
+
+static void cdns3_set_wakeup(void *none_core_regs, bool enable)
+{
+ u32 value;
+
+ if (enable) {
+ /* Enable wakeup and phy_refclk_req */
+ value = readl(none_core_regs + USB3_INT_REG);
+ value |= OTG_WAKEUP_EN | DEVU3_WAEKUP_EN;
+ writel(value, none_core_regs + USB3_INT_REG);
+ } else {
+ /* disable wakeup and phy_refclk_req */
+ value = readl(none_core_regs + USB3_INT_REG);
+ value &= ~(OTG_WAKEUP_EN | DEVU3_WAEKUP_EN);
+ writel(value, none_core_regs + USB3_INT_REG);
+ }
+}
+
+static void cdns3_enter_suspend(struct cdns3 *cdns, bool suspend, bool wakeup)
+{
+ void __iomem *otg_regs = cdns->otg_regs;
+ void __iomem *xhci_regs = cdns->xhci_regs;
+ void __iomem *none_core_regs = cdns->none_core_regs;
+ u32 value;
+ int timeout_us = 100000;
+
+ if (cdns->role == CDNS3_ROLE_GADGET) {
+ if (suspend) {
+ /* When at device mode, set controller at reset mode */
+ value = readl(cdns->none_core_regs + USB3_CORE_CTRL1);
+ value |= ALL_SW_RESET;
+ writel(value, cdns->none_core_regs + USB3_CORE_CTRL1);
+ }
+ return;
+ } else if (cdns->role == CDNS3_ROLE_END) {
+ return;
+ }
+
+ if (suspend) {
+ if (cdns3_role(cdns)->suspend)
+ cdns3_role(cdns)->suspend(cdns, wakeup);
+
+ /* SW request low power when all usb ports allow to it ??? */
+ value = readl(xhci_regs + XECP_PM_PMCSR);
+ value &= ~PS_MASK;
+ value |= PS_D1;
+ writel(value, xhci_regs + XECP_PM_PMCSR);
+
+ /* mdctrl_clk_sel */
+ value = readl(none_core_regs + USB3_CORE_CTRL1);
+ value |= MDCTRL_CLK_SEL;
+ writel(value, none_core_regs + USB3_CORE_CTRL1);
+
+ /* wait for mdctrl_clk_status */
+ value = readl(none_core_regs + USB3_CORE_STATUS);
+ while (!(value & MDCTRL_CLK_STATUS) && timeout_us-- > 0) {
+ value = readl(none_core_regs + USB3_CORE_STATUS);
+ udelay(1);
+ }
+
+ if (timeout_us <= 0)
+ dev_err(cdns->dev, "wait mdctrl_clk_status timeout\n");
+
+ dev_dbg(cdns->dev, "mdctrl_clk_status is set\n");
+
+ /* wait lpm_clk_req to be 0 */
+ value = readl(none_core_regs + USB3_INT_REG);
+ timeout_us = 100000;
+ while ((value & LPM_CLK_REQ) && timeout_us-- > 0) {
+ value = readl(none_core_regs + USB3_INT_REG);
+ udelay(1);
+ }
+
+ if (timeout_us <= 0)
+ dev_err(cdns->dev, "wait lpm_clk_req timeout\n");
+
+ dev_dbg(cdns->dev, "lpm_clk_req cleared\n");
+
+ /* wait phy_refclk_req to be 0 */
+ value = readl(none_core_regs + USB3_SSPHY_STATUS);
+ timeout_us = 100000;
+ while ((value & PHY_REFCLK_REQ) && timeout_us-- > 0) {
+ value = readl(none_core_regs + USB3_SSPHY_STATUS);
+ udelay(1);
+ }
+
+ if (timeout_us <= 0)
+ dev_err(cdns->dev, "wait phy_refclk_req timeout\n");
+
+ dev_dbg(cdns->dev, "phy_refclk_req cleared\n");
+
+ cdns3_set_wakeup(none_core_regs, true);
+ } else {
+ value = readl(none_core_regs + USB3_INT_REG);
+ /* wait CLK_125_REQ to be 1 */
+ value = readl(none_core_regs + USB3_INT_REG);
+ while (!(value & CLK_125_REQ) && timeout_us-- > 0) {
+ value = readl(none_core_regs + USB3_INT_REG);
+ udelay(1);
+ }
+
+ cdns3_set_wakeup(none_core_regs, false);
+
+ /* SW request D0 */
+ value = readl(xhci_regs + XECP_PM_PMCSR);
+ value &= ~PS_MASK;
+ value |= PS_D0;
+ writel(value, xhci_regs + XECP_PM_PMCSR);
+
+ /* clr CFG_RXDET_P3_EN */
+ value = readl(xhci_regs + XECP_AUX_CTRL_REG1);
+ value &= ~CFG_RXDET_P3_EN;
+ writel(value, xhci_regs + XECP_AUX_CTRL_REG1);
+
+ /* clear mdctrl_clk_sel */
+ value = readl(none_core_regs + USB3_CORE_CTRL1);
+ value &= ~MDCTRL_CLK_SEL;
+ writel(value, none_core_regs + USB3_CORE_CTRL1);
+
+ /* wait for mdctrl_clk_status is cleared */
+ value = readl(none_core_regs + USB3_CORE_STATUS);
+ timeout_us = 100000;
+ while ((value & MDCTRL_CLK_STATUS) && timeout_us-- > 0) {
+ value = readl(none_core_regs + USB3_CORE_STATUS);
+ udelay(1);
+ }
+
+ if (timeout_us <= 0)
+ dev_err(cdns->dev, "wait mdctrl_clk_status timeout\n");
+
+ dev_dbg(cdns->dev, "mdctrl_clk_status cleared\n");
+
+ /* Wait until OTG_NRDY is 0 */
+ value = readl(otg_regs + OTGSTS);
+ timeout_us = 100000;
+ while ((value & OTG_NRDY) && timeout_us-- > 0) {
+ value = readl(otg_regs + OTGSTS);
+ udelay(1);
+ }
+
+ if (timeout_us <= 0)
+ dev_err(cdns->dev, "wait OTG ready timeout\n");
+
+ value = readl(none_core_regs + USB3_CORE_STATUS);
+ timeout_us = 100000;
+ while (!(value & HOST_POWER_ON_READY) && timeout_us-- > 0) {
+ value = readl(none_core_regs + USB3_CORE_STATUS);
+ udelay(1);
+ }
+
+ if (timeout_us <= 0)
+ dev_err(cdns->dev, "wait xhci_power_on_ready timeout\n");
+ }
+}
+
+static void cdns3_controller_suspend(struct cdns3 *cdns, bool wakeup)
+{
+ disable_irq(cdns->irq);
+ cdns3_enter_suspend(cdns, true, wakeup);
+ usb_phy_set_suspend(cdns->usbphy, 1);
+ cdns->in_lpm = true;
+ enable_irq(cdns->irq);
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int cdns3_suspend(struct device *dev)
+{
+ struct cdns3 *cdns = dev_get_drvdata(dev);
+ bool wakeup = device_may_wakeup(dev);
+
+ dev_dbg(dev, "at %s\n", __func__);
+
+ if (pm_runtime_status_suspended(dev))
+ pm_runtime_resume(dev);
+
+ cdns3_controller_suspend(cdns, wakeup);
+ cdns3_disable_unprepare_clks(dev);
+ if (wakeup)
+ enable_irq_wake(cdns->irq);
+
+ return 0;
+}
+
+static int cdns3_resume(struct device *dev)
+{
+ struct cdns3 *cdns = dev_get_drvdata(dev);
+ int ret;
+ bool power_lost;
+
+ dev_dbg(dev, "at %s\n", __func__);
+ if (!cdns->in_lpm) {
+ WARN_ON(1);
+ return 0;
+ }
+
+ ret = cdns3_prepare_enable_clks(dev);
+ if (ret)
+ return ret;
+
+ usb_phy_set_suspend(cdns->usbphy, 0);
+ cdns->in_lpm = false;
+ if (device_may_wakeup(dev))
+ disable_irq_wake(cdns->irq);
+ power_lost = controller_power_is_lost(cdns);
+ if (power_lost) {
+ dev_dbg(dev, "power is lost, the role is %d\n", cdns->role);
+ cdns_set_role(cdns, cdns->role);
+ if ((cdns->role != CDNS3_ROLE_END)
+ && cdns3_role(cdns)->resume) {
+ /* Force B Session Valid as 1 */
+ writel(0x0060, cdns->phy_regs + 0x380a4);
+ cdns3_role(cdns)->resume(cdns, true);
+ }
+ } else {
+ cdns3_enter_suspend(cdns, false, false);
+ if (cdns->wakeup_int) {
+ cdns->wakeup_int = false;
+ pm_runtime_mark_last_busy(cdns->dev);
+ pm_runtime_put_autosuspend(cdns->dev);
+ enable_irq(cdns->irq);
+ }
+
+ if ((cdns->role != CDNS3_ROLE_END) && cdns3_role(cdns)->resume)
+ cdns3_role(cdns)->resume(cdns, false);
+ }
+
+ pm_runtime_disable(dev);
+ pm_runtime_set_active(dev);
+ pm_runtime_enable(dev);
+
+ if (cdns->role == CDNS3_ROLE_HOST) {
+ /*
+ * There is no PM APIs for cdns->host_dev, we can only do
+ * it at its parent PM APIs
+ */
+ pm_runtime_disable(cdns->host_dev);
+ pm_runtime_set_active(cdns->host_dev);
+ pm_runtime_enable(cdns->host_dev);
+ }
+
+ dev_dbg(dev, "at end of %s\n", __func__);
+
+ return 0;
+}
+#endif /* CONFIG_PM_SLEEP */
+static int cdns3_runtime_suspend(struct device *dev)
+{
+ struct cdns3 *cdns = dev_get_drvdata(dev);
+
+ dev_dbg(dev, "at the begin of %s\n", __func__);
+ if (cdns->in_lpm) {
+ WARN_ON(1);
+ return 0;
+ }
+
+ cdns3_controller_suspend(cdns, true);
+ cdns3_disable_unprepare_clks(dev);
+
+ dev_dbg(dev, "at the end of %s\n", __func__);
+
+ return 0;
+}
+
+static int cdns3_runtime_resume(struct device *dev)
+{
+ struct cdns3 *cdns = dev_get_drvdata(dev);
+ int ret;
+
+ if (!cdns->in_lpm) {
+ WARN_ON(1);
+ return 0;
+ }
+
+ ret = cdns3_prepare_enable_clks(dev);
+ if (ret)
+ return ret;
+
+ usb_phy_set_suspend(cdns->usbphy, 0);
+ cdns3_enter_suspend(cdns, false, false);
+ cdns->in_lpm = 0;
+
+ if (cdns->role == CDNS3_ROLE_HOST) {
+ if (cdns->wakeup_int) {
+ cdns->wakeup_int = false;
+ pm_runtime_mark_last_busy(cdns->dev);
+ pm_runtime_put_autosuspend(cdns->dev);
+ enable_irq(cdns->irq);
+ }
+
+ if ((cdns->role != CDNS3_ROLE_END) && cdns3_role(cdns)->resume)
+ cdns3_role(cdns)->resume(cdns, false);
+ }
+
+ dev_dbg(dev, "at %s\n", __func__);
+ return 0;
+}
+#endif /* CONFIG_PM */
+static const struct dev_pm_ops cdns3_pm_ops = {
+ SET_SYSTEM_SLEEP_PM_OPS(cdns3_suspend, cdns3_resume)
+ SET_RUNTIME_PM_OPS(cdns3_runtime_suspend, cdns3_runtime_resume, NULL)
+};
+
+static struct platform_driver cdns3_driver = {
+ .probe = cdns3_probe,
+ .remove = cdns3_remove,
+ .driver = {
+ .name = "cdns-usb3",
+ .of_match_table = of_match_ptr(of_cdns3_match),
+ .pm = &cdns3_pm_ops,
+ },
+};
+
+static int __init cdns3_driver_platform_register(void)
+{
+ cdns3_host_driver_init();
+ return platform_driver_register(&cdns3_driver);
+}
+module_init(cdns3_driver_platform_register);
+
+static void __exit cdns3_driver_platform_unregister(void)
+{
+ platform_driver_unregister(&cdns3_driver);
+}
+module_exit(cdns3_driver_platform_unregister);
+
+MODULE_ALIAS("platform:cdns-usb3");
+MODULE_AUTHOR("Peter Chen <peter.chen@nxp.com>");
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("Cadence USB3 DRD Controller Driver");
diff --git a/drivers/usb/cdns3/core.h b/drivers/usb/cdns3/core.h
new file mode 100644
index 000000000000..738dbfa836cf
--- /dev/null
+++ b/drivers/usb/cdns3/core.h
@@ -0,0 +1,131 @@
+/**
+ * core.h - Cadence USB3 DRD Controller Core header file
+ *
+ * Copyright 2017 NXP
+ *
+ * Authors: Peter Chen <peter.chen@nxp.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 of
+ * the License 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 __DRIVERS_USB_CDNS3_CORE_H
+#define __DRIVERS_USB_CDNS3_CORE_H
+
+struct cdns3;
+enum cdns3_roles {
+ CDNS3_ROLE_HOST = 0,
+ CDNS3_ROLE_GADGET,
+ CDNS3_ROLE_END,
+};
+
+/**
+ * struct cdns3_role_driver - host/gadget role driver
+ * @start: start this role
+ * @stop: stop this role
+ * @suspend: suspend callback for this role
+ * @resume: resume callback for this role
+ * @irq: irq handler for this role
+ * @name: role name string (host/gadget)
+ */
+struct cdns3_role_driver {
+ int (*start)(struct cdns3 *);
+ void (*stop)(struct cdns3 *);
+ int (*suspend)(struct cdns3 *, bool do_wakeup);
+ int (*resume)(struct cdns3 *, bool hibernated);
+ irqreturn_t (*irq)(struct cdns3 *);
+ const char *name;
+};
+
+#define CDNS3_NUM_OF_CLKS 5
+/**
+ * struct cdns3 - Representation of Cadence USB3 DRD controller.
+ * @dev: pointer to Cadence device struct
+ * @xhci_regs: pointer to base of xhci registers
+ * @xhci_res: the resource for xhci
+ * @dev_regs: pointer to base of dev registers
+ * @none_core_regs: pointer to base of nxp wrapper registers
+ * @phy_regs: pointer to base of phy registers
+ * @otg_regs: pointer to base of otg registers
+ * @irq: irq number for controller
+ * @roles: array of supported roles for this controller
+ * @role: current role
+ * @host_dev: the child host device pointer for cdns3 core
+ * @gadget_dev: the child gadget device pointer for cdns3 core
+ * @usbphy: usbphy for this controller
+ * @cdns3_clks: Clock pointer array for cdns3 core
+ * @extcon: Type-C extern connector
+ * @extcon_nb: notifier block for Type-C extern connector
+ * @role_switch_wq: work queue item for role switch
+ * @in_lpm: the controller in low power mode
+ * @wakeup_int: the wakeup interrupt
+ * @mutex: the mutex for concurrent code at driver
+ */
+struct cdns3 {
+ struct device *dev;
+ void __iomem *xhci_regs;
+ struct resource *xhci_res;
+ struct usbss_dev_register_block_type __iomem *dev_regs;
+ void __iomem *none_core_regs;
+ void __iomem *phy_regs;
+ void __iomem *otg_regs;
+ int irq;
+ struct cdns3_role_driver *roles[CDNS3_ROLE_END];
+ enum cdns3_roles role;
+ struct device *host_dev;
+ struct device *gadget_dev;
+ struct usb_phy *usbphy;
+ struct clk *cdns3_clks[CDNS3_NUM_OF_CLKS];
+ struct extcon_dev *extcon;
+ struct notifier_block extcon_nb;
+ struct work_struct role_switch_wq;
+ bool in_lpm;
+ bool wakeup_int;
+ struct mutex mutex;
+};
+
+static inline struct cdns3_role_driver *cdns3_role(struct cdns3 *cdns)
+{
+ WARN_ON(cdns->role >= CDNS3_ROLE_END || !cdns->roles[cdns->role]);
+ return cdns->roles[cdns->role];
+}
+
+static inline int cdns3_role_start(struct cdns3 *cdns, enum cdns3_roles role)
+{
+ int ret;
+ if (role >= CDNS3_ROLE_END)
+ return 0;
+
+ if (!cdns->roles[role])
+ return -ENXIO;
+
+ mutex_lock(&cdns->mutex);
+ cdns->role = role;
+ ret = cdns->roles[role]->start(cdns);
+ mutex_unlock(&cdns->mutex);
+ return ret;
+}
+
+static inline void cdns3_role_stop(struct cdns3 *cdns)
+{
+ enum cdns3_roles role = cdns->role;
+
+ if (role == CDNS3_ROLE_END)
+ return;
+
+ mutex_lock(&cdns->mutex);
+ cdns->roles[role]->stop(cdns);
+ cdns->role = CDNS3_ROLE_END;
+ mutex_unlock(&cdns->mutex);
+}
+
+#endif /* __DRIVERS_USB_CDNS3_CORE_H */
diff --git a/drivers/usb/cdns3/dev-regs-macro.h b/drivers/usb/cdns3/dev-regs-macro.h
new file mode 100644
index 000000000000..5b307623afec
--- /dev/null
+++ b/drivers/usb/cdns3/dev-regs-macro.h
@@ -0,0 +1,894 @@
+/**
+ * dev-regs-macro.h - Cadence USB3 Device register definition
+ *
+ * Copyright (C) 2016 Cadence Design Systems - http://www.cadence.com
+ * Copyright 2017 NXP
+ *
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#ifndef __REG_USBSS_DEV_ADDR_MAP_MACRO_H__
+#define __REG_USBSS_DEV_ADDR_MAP_MACRO_H__
+
+
+/* macros for BlueprintGlobalNameSpace::USB_CONF */
+#ifndef __USB_CONF_MACRO__
+#define __USB_CONF_MACRO__
+
+/* macros for field CFGRST */
+#define USB_CONF__CFGRST__MASK 0x00000001U
+#define USB_CONF__CFGSET__MASK 0x00000002U
+#define USB_CONF__USB3DIS__MASK 0x00000008U
+#define USB_CONF__DEVEN__MASK 0x00004000U
+#define USB_CONF__DEVDS__MASK 0x00008000U
+#define USB_CONF__L1EN__MASK 0x00010000U
+#define USB_CONF__L1DS__MASK 0x00020000U
+#define USB_CONF__CLK2OFFDS__MASK 0x00080000U
+#define USB_CONF__U1EN__MASK 0x01000000U
+#define USB_CONF__U1DS__MASK 0x02000000U
+#define USB_CONF__U2EN__MASK 0x04000000U
+#define USB_CONF__U2DS__MASK 0x08000000U
+#endif /* __USB_CONF_MACRO__ */
+
+
+/* macros for usbss_dev_register_block.usb_conf */
+#ifndef __USB_STS_MACRO__
+#define __USB_STS_MACRO__
+
+/* macros for field CFGSTS */
+#define USB_STS__CFGSTS__MASK 0x00000001U
+#define USB_STS__USBSPEED__READ(src) (((uint32_t)(src) & 0x00000070U) >> 4)
+
+/* macros for field ENDIAN_MIRROR */
+#define USB_STS__LPMST__READ(src) (((uint32_t)(src) & 0x000c0000U) >> 18)
+
+/* macros for field USB2CONS */
+#define USB_STS__U1ENS__MASK 0x01000000U
+#define USB_STS__U2ENS__MASK 0x02000000U
+#define USB_STS__LST__READ(src) (((uint32_t)(src) & 0x3c000000U) >> 26)
+
+/* macros for field DMAOFF */
+#endif /* __USB_STS_MACRO__ */
+
+
+/* macros for usbss_dev_register_block.usb_sts */
+#ifndef __USB_CMD_MACRO__
+#define __USB_CMD_MACRO__
+
+/* macros for field SET_ADDR */
+#define USB_CMD__SET_ADDR__MASK 0x00000001U
+#define USB_CMD__STMODE 0x00000200U
+#define USB_CMD__TMODE_SEL(x) (x << 10)
+#define USB_CMD__FADDR__WRITE(src) (((uint32_t)(src) << 1) & 0x000000feU)
+#endif /* __USB_CMD_MACRO__ */
+
+
+/* macros for usbss_dev_register_block.usb_cmd */
+#ifndef __USB_ITPN_MACRO__
+#define __USB_ITPN_MACRO__
+
+/* macros for field ITPN */
+#endif /* __USB_ITPN_MACRO__ */
+
+
+/* macros for usbss_dev_register_block.usb_iptn */
+#ifndef __USB_LPM_MACRO__
+#define __USB_LPM_MACRO__
+
+/* macros for field HIRD */
+#endif /* __USB_LPM_MACRO__ */
+
+
+/* macros for usbss_dev_register_block.usb_lpm */
+#ifndef __USB_IEN_MACRO__
+#define __USB_IEN_MACRO__
+
+/* macros for field CONIEN */
+#define USB_IEN__CONIEN__MASK 0x00000001U
+#define USB_IEN__DISIEN__MASK 0x00000002U
+#define USB_IEN__UWRESIEN__MASK 0x00000004U
+#define USB_IEN__UHRESIEN__MASK 0x00000008U
+#define USB_IEN__U3EXTIEN__MASK 0x00000020U
+#define USB_IEN__CON2IEN__MASK 0x00010000U
+#define USB_IEN__U2RESIEN__MASK 0x00040000U
+#define USB_IEN__L2ENTIEN__MASK 0x00100000U
+#define USB_IEN__L2EXTIEN__MASK 0x00200000U
+#endif /* __USB_IEN_MACRO__ */
+
+
+/* macros for usbss_dev_register_block.usb_ien */
+#ifndef __USB_ISTS_MACRO__
+#define __USB_ISTS_MACRO__
+
+/* macros for field CONI */
+#define USB_ISTS__CONI__SHIFT 0
+#define USB_ISTS__DISI__SHIFT 1
+#define USB_ISTS__UWRESI__SHIFT 2
+#define USB_ISTS__UHRESI__SHIFT 3
+#define USB_ISTS__U3EXTI__SHIFT 5
+#define USB_ISTS__CON2I__SHIFT 16
+#define USB_ISTS__DIS2I__SHIFT 17
+#define USB_ISTS__DIS2I__MASK 0x00020000U
+#define USB_ISTS__U2RESI__SHIFT 18
+#define USB_ISTS__L2ENTI__SHIFT 20
+#define USB_ISTS__L2EXTI__SHIFT 21
+#endif /* __USB_ISTS_MACRO__ */
+
+
+/* macros for usbss_dev_register_block.usb_ists */
+#ifndef __EP_SEL_MACRO__
+#define __EP_SEL_MACRO__
+
+/* macros for field EPNO */
+#endif /* __EP_SEL_MACRO__ */
+
+
+/* macros for usbss_dev_register_block.ep_sel */
+#ifndef __EP_TRADDR_MACRO__
+#define __EP_TRADDR_MACRO__
+
+/* macros for field TRADDR */
+#define EP_TRADDR__TRADDR__WRITE(src) ((uint32_t)(src) & 0xffffffffU)
+#endif /* __EP_TRADDR_MACRO__ */
+
+
+/* macros for usbss_dev_register_block.ep_traddr */
+#ifndef __EP_CFG_MACRO__
+#define __EP_CFG_MACRO__
+
+/* macros for field ENABLE */
+#define EP_CFG__ENABLE__MASK 0x00000001U
+#define EP_CFG__EPTYPE__WRITE(src) (((uint32_t)(src) << 1) & 0x00000006U)
+#define EP_CFG__MAXBURST__WRITE(src) (((uint32_t)(src) << 8) & 0x00000f00U)
+#define EP_CFG__MAXPKTSIZE__WRITE(src) (((uint32_t)(src) << 16) & 0x07ff0000U)
+#define EP_CFG__BUFFERING__WRITE(src) (((uint32_t)(src) << 27) & 0xf8000000U)
+#endif /* __EP_CFG_MACRO__ */
+
+
+/* macros for usbss_dev_register_block.ep_cfg */
+#ifndef __EP_CMD_MACRO__
+#define __EP_CMD_MACRO__
+
+/* macros for field EPRST */
+#define EP_CMD__EPRST__MASK 0x00000001U
+#define EP_CMD__SSTALL__MASK 0x00000002U
+#define EP_CMD__CSTALL__MASK 0x00000004U
+#define EP_CMD__ERDY__MASK 0x00000008U
+#define EP_CMD__REQ_CMPL__MASK 0x00000020U
+#define EP_CMD__DRDY__MASK 0x00000040U
+#define EP_CMD__DFLUSH__MASK 0x00000080U
+#endif /* __EP_CMD_MACRO__ */
+
+
+/* macros for usbss_dev_register_block.ep_cmd */
+#ifndef __EP_STS_MACRO__
+#define __EP_STS_MACRO__
+
+/* macros for field SETUP */
+#define EP_STS__SETUP__MASK 0x00000001U
+#define EP_STS__STALL__MASK 0x00000002U
+#define EP_STS__IOC__MASK 0x00000004U
+#define EP_STS__ISP__MASK 0x00000008U
+#define EP_STS__DESCMIS__MASK 0x00000010U
+#define EP_STS__TRBERR__MASK 0x00000080U
+#define EP_STS__NRDY__MASK 0x00000100U
+#define EP_STS__DBUSY__MASK 0x00000200U
+#define EP_STS__OUTSMM__MASK 0x00004000U
+#define EP_STS__ISOERR__MASK 0x00008000U
+#endif /* __EP_STS_MACRO__ */
+
+
+/* macros for usbss_dev_register_block.ep_sts */
+#ifndef __EP_STS_SID_MACRO__
+#define __EP_STS_SID_MACRO__
+
+/* macros for field SID */
+#endif /* __EP_STS_SID_MACRO__ */
+
+
+/* macros for usbss_dev_register_block.ep_sts_sid */
+#ifndef __EP_STS_EN_MACRO__
+#define __EP_STS_EN_MACRO__
+
+/* macros for field SETUPEN */
+#define EP_STS_EN__SETUPEN__MASK 0x00000001U
+#define EP_STS_EN__DESCMISEN__MASK 0x00000010U
+#define EP_STS_EN__TRBERREN__MASK 0x00000080U
+#endif /* __EP_STS_EN_MACRO__ */
+
+
+/* macros for usbss_dev_register_block.ep_sts_en */
+#ifndef __DRBL_MACRO__
+#define __DRBL_MACRO__
+
+/* macros for field DRBL0O */
+#endif /* __DRBL_MACRO__ */
+
+
+/* macros for usbss_dev_register_block.drbl */
+#ifndef __EP_IEN_MACRO__
+#define __EP_IEN_MACRO__
+
+/* macros for field EOUTEN0 */
+#define EP_IEN__EOUTEN0__MASK 0x00000001U
+#define EP_IEN__EINEN0__MASK 0x00010000U
+#endif /* __EP_IEN_MACRO__ */
+
+
+/* macros for usbss_dev_register_block.ep_ien */
+#ifndef __EP_ISTS_MACRO__
+#define __EP_ISTS_MACRO__
+
+/* macros for field EOUT0 */
+#define EP_ISTS__EOUT0__MASK 0x00000001U
+#define EP_ISTS__EIN0__MASK 0x00010000U
+#endif /* __EP_ISTS_MACRO__ */
+
+
+/* macros for usbss_dev_register_block.ep_ists */
+#ifndef __USB_PWR_MACRO__
+#define __USB_PWR_MACRO__
+
+/* macros for field PSO_EN */
+#endif /* __USB_PWR_MACRO__ */
+
+
+/* macros for usbss_dev_register_block.usb_pwr */
+#ifndef __USB_CONF2_MACRO__
+#define __USB_CONF2_MACRO__
+
+/* macros for field AHB_RETRY_EN */
+#endif /* __USB_CONF2_MACRO__ */
+
+
+/* macros for usbss_dev_register_block.usb_conf2 */
+#ifndef __USB_CAP1_MACRO__
+#define __USB_CAP1_MACRO__
+
+/* macros for field SFR_TYPE */
+#endif /* __USB_CAP1_MACRO__ */
+
+
+/* macros for usbss_dev_register_block.usb_cap1 */
+#ifndef __USB_CAP2_MACRO__
+#define __USB_CAP2_MACRO__
+
+/* macros for field ACTUAL_MEM_SIZE */
+#endif /* __USB_CAP2_MACRO__ */
+
+
+/* macros for usbss_dev_register_block.usb_cap2 */
+#ifndef __USB_CAP3_MACRO__
+#define __USB_CAP3_MACRO__
+
+/* macros for field EPOUT_N */
+#endif /* __USB_CAP3_MACRO__ */
+
+
+/* macros for usbss_dev_register_block.usb_cap3 */
+#ifndef __USB_CAP4_MACRO__
+#define __USB_CAP4_MACRO__
+
+/* macros for field EPOUTI_N */
+#endif /* __USB_CAP4_MACRO__ */
+
+
+/* macros for usbss_dev_register_block.usb_cap4 */
+#ifndef __USB_CAP5_MACRO__
+#define __USB_CAP5_MACRO__
+
+/* macros for field EPOUTI_N */
+#endif /* __USB_CAP5_MACRO__ */
+
+
+/* macros for usbss_dev_register_block.usb_cap5 */
+#ifndef __USB_CAP6_MACRO__
+#define __USB_CAP6_MACRO__
+
+/* macros for field VERSION */
+#endif /* __USB_CAP6_MACRO__ */
+
+
+/* macros for usbss_dev_register_block.usb_cap6 */
+#ifndef __USB_CPKT1_MACRO__
+#define __USB_CPKT1_MACRO__
+
+/* macros for field CPKT1 */
+#endif /* __USB_CPKT1_MACRO__ */
+
+
+/* macros for usbss_dev_register_block.usb_cpkt1 */
+#ifndef __USB_CPKT2_MACRO__
+#define __USB_CPKT2_MACRO__
+
+/* macros for field CPKT2 */
+#endif /* __USB_CPKT2_MACRO__ */
+
+
+/* macros for usbss_dev_register_block.usb_cpkt2 */
+#ifndef __USB_CPKT3_MACRO__
+#define __USB_CPKT3_MACRO__
+
+/* macros for field CPKT3 */
+#endif /* __USB_CPKT3_MACRO__ */
+
+
+/* macros for usbss_dev_register_block.usb_cpkt3 */
+#ifndef __CFG_REG1_MACRO__
+#define __CFG_REG1_MACRO__
+
+/* macros for field DEBOUNCER_CNT */
+#endif /* __CFG_REG1_MACRO__ */
+
+
+/* macros for usbss_dev_register_block.cfg_reg1 */
+#ifndef __DBG_LINK1_MACRO__
+#define __DBG_LINK1_MACRO__
+
+/* macros for field LFPS_MIN_DET_U1_EXIT */
+#define DBG_LINK1__LFPS_MIN_GEN_U1_EXIT__WRITE(src) \
+ (((uint32_t)(src)\
+ << 8) & 0x0000ff00U)
+#define DBG_LINK1__LFPS_MIN_GEN_U1_EXIT_SET__MASK 0x02000000U
+#endif /* __DBG_LINK1_MACRO__ */
+
+
+/* macros for usbss_dev_register_block.dbg_link1 */
+#ifndef __DBG_LINK2_MACRO__
+#define __DBG_LINK2_MACRO__
+
+/* macros for field RXEQTR_AVAL */
+#endif /* __DBG_LINK2_MACRO__ */
+
+
+/* macros for usbss_dev_register_block.dbg_link2 */
+#ifndef __CFG_REG4_MACRO__
+#define __CFG_REG4_MACRO__
+
+/* macros for field RXDETECT_QUIET_TIMEOUT */
+#endif /* __CFG_REG4_MACRO__ */
+
+
+/* macros for usbss_dev_register_block.cfg_reg4 */
+#ifndef __CFG_REG5_MACRO__
+#define __CFG_REG5_MACRO__
+
+/* macros for field U3_HDSK_FAIL_TIMEOUT */
+#endif /* __CFG_REG5_MACRO__ */
+
+
+/* macros for usbss_dev_register_block.cfg_reg5 */
+#ifndef __CFG_REG6_MACRO__
+#define __CFG_REG6_MACRO__
+
+/* macros for field SSINACTIVE_QUIET_TIMEOUT */
+#endif /* __CFG_REG6_MACRO__ */
+
+
+/* macros for usbss_dev_register_block.cfg_reg6 */
+#ifndef __CFG_REG7_MACRO__
+#define __CFG_REG7_MACRO__
+
+/* macros for field POLLING_LFPS_TIMEOUT */
+#endif /* __CFG_REG7_MACRO__ */
+
+
+/* macros for usbss_dev_register_block.cfg_reg7 */
+#ifndef __CFG_REG8_MACRO__
+#define __CFG_REG8_MACRO__
+
+/* macros for field POLLING_ACTIVE_TIMEOUT */
+#endif /* __CFG_REG8_MACRO__ */
+
+
+/* macros for usbss_dev_register_block.cfg_reg8 */
+#ifndef __CFG_REG9_MACRO__
+#define __CFG_REG9_MACRO__
+
+/* macros for field POLLING_IDLE_TIMEOUT */
+#endif /* __CFG_REG9_MACRO__ */
+
+
+/* macros for usbss_dev_register_block.cfg_reg9 */
+#ifndef __CFG_REG10_MACRO__
+#define __CFG_REG10_MACRO__
+
+/* macros for field POLLING_CONF_TIMEOUT */
+#endif /* __CFG_REG10_MACRO__ */
+
+
+/* macros for usbss_dev_register_block.cfg_reg10 */
+#ifndef __CFG_REG11_MACRO__
+#define __CFG_REG11_MACRO__
+
+/* macros for field RECOVERY_ACTIVE_TIMEOUT */
+#endif /* __CFG_REG11_MACRO__ */
+
+
+/* macros for usbss_dev_register_block.cfg_reg11 */
+#ifndef __CFG_REG12_MACRO__
+#define __CFG_REG12_MACRO__
+
+/* macros for field RECOVERY_CONF_TIMEOUT */
+#endif /* __CFG_REG12_MACRO__ */
+
+
+/* macros for usbss_dev_register_block.cfg_reg12 */
+#ifndef __CFG_REG13_MACRO__
+#define __CFG_REG13_MACRO__
+
+/* macros for field RECOVERY_IDLE_TIMEOUT */
+#endif /* __CFG_REG13_MACRO__ */
+
+
+/* macros for usbss_dev_register_block.cfg_reg13 */
+#ifndef __CFG_REG14_MACRO__
+#define __CFG_REG14_MACRO__
+
+/* macros for field HOTRESET_ACTIVE_TIMEOUT */
+#endif /* __CFG_REG14_MACRO__ */
+
+
+/* macros for usbss_dev_register_block.cfg_reg14 */
+#ifndef __CFG_REG15_MACRO__
+#define __CFG_REG15_MACRO__
+
+/* macros for field HOTRESET_EXIT_TIMEOUT */
+#endif /* __CFG_REG15_MACRO__ */
+
+
+/* macros for usbss_dev_register_block.cfg_reg15 */
+#ifndef __CFG_REG16_MACRO__
+#define __CFG_REG16_MACRO__
+
+/* macros for field LFPS_PING_REPEAT */
+#endif /* __CFG_REG16_MACRO__ */
+
+
+/* macros for usbss_dev_register_block.cfg_reg16 */
+#ifndef __CFG_REG17_MACRO__
+#define __CFG_REG17_MACRO__
+
+/* macros for field PENDING_HP_TIMEOUT */
+#endif /* __CFG_REG17_MACRO__ */
+
+
+/* macros for usbss_dev_register_block.cfg_reg17 */
+#ifndef __CFG_REG18_MACRO__
+#define __CFG_REG18_MACRO__
+
+/* macros for field CREDIT_HP_TIMEOUT */
+#endif /* __CFG_REG18_MACRO__ */
+
+
+/* macros for usbss_dev_register_block.cfg_reg18 */
+#ifndef __CFG_REG19_MACRO__
+#define __CFG_REG19_MACRO__
+
+/* macros for field LUP_TIMEOUT */
+#endif /* __CFG_REG19_MACRO__ */
+
+
+/* macros for usbss_dev_register_block.cfg_reg19 */
+#ifndef __CFG_REG20_MACRO__
+#define __CFG_REG20_MACRO__
+
+/* macros for field LDN_TIMEOUT */
+#endif /* __CFG_REG20_MACRO__ */
+
+
+/* macros for usbss_dev_register_block.cfg_reg20 */
+#ifndef __CFG_REG21_MACRO__
+#define __CFG_REG21_MACRO__
+
+/* macros for field PM_LC_TIMEOUT */
+#endif /* __CFG_REG21_MACRO__ */
+
+
+/* macros for usbss_dev_register_block.cfg_reg21 */
+#ifndef __CFG_REG22_MACRO__
+#define __CFG_REG22_MACRO__
+
+/* macros for field PM_ENTRY_TIMEOUT */
+#endif /* __CFG_REG22_MACRO__ */
+
+
+/* macros for usbss_dev_register_block.cfg_reg22 */
+#ifndef __CFG_REG23_MACRO__
+#define __CFG_REG23_MACRO__
+
+/* macros for field UX_EXIT_TIMEOUT */
+#endif /* __CFG_REG23_MACRO__ */
+
+
+/* macros for usbss_dev_register_block.cfg_reg23 */
+#ifndef __CFG_REG24_MACRO__
+#define __CFG_REG24_MACRO__
+
+/* macros for field LFPS_DET_RESET_MIN */
+#endif /* __CFG_REG24_MACRO__ */
+
+
+/* macros for usbss_dev_register_block.cfg_reg24 */
+#ifndef __CFG_REG25_MACRO__
+#define __CFG_REG25_MACRO__
+
+/* macros for field LFPS_DET_RESET_MAX */
+#endif /* __CFG_REG25_MACRO__ */
+
+
+/* macros for usbss_dev_register_block.cfg_reg25 */
+#ifndef __CFG_REG26_MACRO__
+#define __CFG_REG26_MACRO__
+
+/* macros for field LFPS_DET_POLLING_MIN */
+#endif /* __CFG_REG26_MACRO__ */
+
+
+/* macros for usbss_dev_register_block.cfg_reg26 */
+#ifndef __CFG_REG27_MACRO__
+#define __CFG_REG27_MACRO__
+
+/* macros for field LFPS_DET_POLLING_MAX */
+#endif /* __CFG_REG27_MACRO__ */
+
+
+/* macros for usbss_dev_register_block.cfg_reg27 */
+#ifndef __CFG_REG28_MACRO__
+#define __CFG_REG28_MACRO__
+
+/* macros for field LFPS_DET_PING_MIN */
+#endif /* __CFG_REG28_MACRO__ */
+
+
+/* macros for usbss_dev_register_block.cfg_reg28 */
+#ifndef __CFG_REG29_MACRO__
+#define __CFG_REG29_MACRO__
+
+/* macros for field LFPS_DET_PING_MAX */
+#endif /* __CFG_REG29_MACRO__ */
+
+
+/* macros for usbss_dev_register_block.cfg_reg29 */
+#ifndef __CFG_REG30_MACRO__
+#define __CFG_REG30_MACRO__
+
+/* macros for field LFPS_DET_U1EXIT_MIN */
+#endif /* __CFG_REG30_MACRO__ */
+
+
+/* macros for usbss_dev_register_block.cfg_reg30 */
+#ifndef __CFG_REG31_MACRO__
+#define __CFG_REG31_MACRO__
+
+/* macros for field LFPS_DET_U1EXIT_MAX */
+#endif /* __CFG_REG31_MACRO__ */
+
+
+/* macros for usbss_dev_register_block.cfg_reg31 */
+#ifndef __CFG_REG32_MACRO__
+#define __CFG_REG32_MACRO__
+
+/* macros for field LFPS_DET_U2EXIT_MIN */
+#endif /* __CFG_REG32_MACRO__ */
+
+
+/* macros for usbss_dev_register_block.cfg_reg32 */
+#ifndef __CFG_REG33_MACRO__
+#define __CFG_REG33_MACRO__
+
+/* macros for field LFPS_DET_U2EXIT_MAX */
+#endif /* __CFG_REG33_MACRO__ */
+
+
+/* macros for usbss_dev_register_block.cfg_reg33 */
+#ifndef __CFG_REG34_MACRO__
+#define __CFG_REG34_MACRO__
+
+/* macros for field LFPS_DET_U3EXIT_MIN */
+#endif /* __CFG_REG34_MACRO__ */
+
+
+/* macros for usbss_dev_register_block.cfg_reg34 */
+#ifndef __CFG_REG35_MACRO__
+#define __CFG_REG35_MACRO__
+
+/* macros for field LFPS_DET_U3EXIT_MAX */
+#endif /* __CFG_REG35_MACRO__ */
+
+
+/* macros for usbss_dev_register_block.cfg_reg35 */
+#ifndef __CFG_REG36_MACRO__
+#define __CFG_REG36_MACRO__
+
+/* macros for field LFPS_GEN_PING */
+#endif /* __CFG_REG36_MACRO__ */
+
+
+/* macros for usbss_dev_register_block.cfg_reg36 */
+#ifndef __CFG_REG37_MACRO__
+#define __CFG_REG37_MACRO__
+
+/* macros for field LFPS_GEN_POLLING */
+#endif /* __CFG_REG37_MACRO__ */
+
+
+/* macros for usbss_dev_register_block.cfg_reg37 */
+#ifndef __CFG_REG38_MACRO__
+#define __CFG_REG38_MACRO__
+
+/* macros for field LFPS_GEN_U1EXIT */
+#endif /* __CFG_REG38_MACRO__ */
+
+
+/* macros for usbss_dev_register_block.cfg_reg38 */
+#ifndef __CFG_REG39_MACRO__
+#define __CFG_REG39_MACRO__
+
+/* macros for field LFPS_GEN_U3EXIT */
+#endif /* __CFG_REG39_MACRO__ */
+
+
+/* macros for usbss_dev_register_block.cfg_reg39 */
+#ifndef __CFG_REG40_MACRO__
+#define __CFG_REG40_MACRO__
+
+/* macros for field LFPS_MIN_GEN_U1EXIT */
+#endif /* __CFG_REG40_MACRO__ */
+
+
+/* macros for usbss_dev_register_block.cfg_reg40 */
+#ifndef __CFG_REG41_MACRO__
+#define __CFG_REG41_MACRO__
+
+/* macros for field LFPS_MIN_GEN_U2EXIT */
+#endif /* __CFG_REG41_MACRO__ */
+
+
+/* macros for usbss_dev_register_block.cfg_reg41 */
+#ifndef __CFG_REG42_MACRO__
+#define __CFG_REG42_MACRO__
+
+/* macros for field LFPS_POLLING_REPEAT */
+#endif /* __CFG_REG42_MACRO__ */
+
+
+/* macros for usbss_dev_register_block.cfg_reg42 */
+#ifndef __CFG_REG43_MACRO__
+#define __CFG_REG43_MACRO__
+
+/* macros for field LFPS_POLLING_MAX_TREPEAT */
+#endif /* __CFG_REG43_MACRO__ */
+
+
+/* macros for usbss_dev_register_block.cfg_reg43 */
+#ifndef __CFG_REG44_MACRO__
+#define __CFG_REG44_MACRO__
+
+/* macros for field LFPS_POLLING_MIN_TREPEAT */
+#endif /* __CFG_REG44_MACRO__ */
+
+
+/* macros for usbss_dev_register_block.cfg_reg44 */
+#ifndef __CFG_REG45_MACRO__
+#define __CFG_REG45_MACRO__
+
+/* macros for field ITP_WAKEUP_TIMEOUT */
+#endif /* __CFG_REG45_MACRO__ */
+
+
+/* macros for usbss_dev_register_block.cfg_reg45 */
+#ifndef __CFG_REG46_MACRO__
+#define __CFG_REG46_MACRO__
+
+/* macros for field TSEQ_QUANTITY */
+#endif /* __CFG_REG46_MACRO__ */
+
+
+/* macros for usbss_dev_register_block.cfg_reg46 */
+#ifndef __CFG_REG47_MACRO__
+#define __CFG_REG47_MACRO__
+
+/* macros for field ERDY_TIMEOUT_CNT */
+#endif /* __CFG_REG47_MACRO__ */
+
+
+/* macros for usbss_dev_register_block.cfg_reg47 */
+#ifndef __CFG_REG48_MACRO__
+#define __CFG_REG48_MACRO__
+
+/* macros for field TWTRSTFS_J_CNT */
+#endif /* __CFG_REG48_MACRO__ */
+
+
+/* macros for usbss_dev_register_block.cfg_reg48 */
+#ifndef __CFG_REG49_MACRO__
+#define __CFG_REG49_MACRO__
+
+/* macros for field TUCH_CNT */
+#endif /* __CFG_REG49_MACRO__ */
+
+
+/* macros for usbss_dev_register_block.cfg_reg49 */
+#ifndef __CFG_REG50_MACRO__
+#define __CFG_REG50_MACRO__
+
+/* macros for field TWAITCHK_CNT */
+#endif /* __CFG_REG50_MACRO__ */
+
+
+/* macros for usbss_dev_register_block.cfg_reg50 */
+#ifndef __CFG_REG51_MACRO__
+#define __CFG_REG51_MACRO__
+
+/* macros for field TWTFS_CNT */
+#endif /* __CFG_REG51_MACRO__ */
+
+
+/* macros for usbss_dev_register_block.cfg_reg51 */
+#ifndef __CFG_REG52_MACRO__
+#define __CFG_REG52_MACRO__
+
+/* macros for field TWTREV_CNT */
+#endif /* __CFG_REG52_MACRO__ */
+
+
+/* macros for usbss_dev_register_block.cfg_reg52 */
+#ifndef __CFG_REG53_MACRO__
+#define __CFG_REG53_MACRO__
+
+/* macros for field TWTRSTHS_CNT */
+#endif /* __CFG_REG53_MACRO__ */
+
+
+/* macros for usbss_dev_register_block.cfg_reg53 */
+#ifndef __CFG_REG54_MACRO__
+#define __CFG_REG54_MACRO__
+
+/* macros for field TWTRSM_CNT */
+#endif /* __CFG_REG54_MACRO__ */
+
+
+/* macros for usbss_dev_register_block.cfg_reg54 */
+#ifndef __CFG_REG55_MACRO__
+#define __CFG_REG55_MACRO__
+
+/* macros for field TDRSMUP_CNT */
+#endif /* __CFG_REG55_MACRO__ */
+
+
+/* macros for usbss_dev_register_block.cfg_reg55 */
+#ifndef __CFG_REG56_MACRO__
+#define __CFG_REG56_MACRO__
+
+/* macros for field TOUTHS_CNT */
+#endif /* __CFG_REG56_MACRO__ */
+
+
+/* macros for usbss_dev_register_block.cfg_reg56 */
+#ifndef __CFG_REG57_MACRO__
+#define __CFG_REG57_MACRO__
+
+/* macros for field LFPS_DEB_WIDTH */
+#endif /* __CFG_REG57_MACRO__ */
+
+
+/* macros for usbss_dev_register_block.cfg_reg57 */
+#ifndef __CFG_REG58_MACRO__
+#define __CFG_REG58_MACRO__
+
+/* macros for field LFPS_GEN_U2EXIT */
+#endif /* __CFG_REG58_MACRO__ */
+
+
+/* macros for usbss_dev_register_block.cfg_reg58 */
+#ifndef __CFG_REG59_MACRO__
+#define __CFG_REG59_MACRO__
+
+/* macros for field LFPS_MIN_GEN_U3EXIT */
+#endif /* __CFG_REG59_MACRO__ */
+
+
+/* macros for usbss_dev_register_block.cfg_reg59 */
+#ifndef __CFG_REG60_MACRO__
+#define __CFG_REG60_MACRO__
+
+/* macros for field PORT_CONFIG_TIMEOUT */
+#endif /* __CFG_REG60_MACRO__ */
+
+
+/* macros for usbss_dev_register_block.cfg_reg60 */
+#ifndef __CFG_REG61_MACRO__
+#define __CFG_REG61_MACRO__
+
+/* macros for field LFPS_POL_LFPS_TO_RXEQ */
+#endif /* __CFG_REG61_MACRO__ */
+
+
+/* macros for usbss_dev_register_block.cfg_reg61 */
+#ifndef __CFG_REG62_MACRO__
+#define __CFG_REG62_MACRO__
+
+/* macros for field PHY_TX_LATENCY */
+#endif /* __CFG_REG62_MACRO__ */
+
+
+/* macros for usbss_dev_register_block.cfg_reg62 */
+#ifndef __CFG_REG63_MACRO__
+#define __CFG_REG63_MACRO__
+
+/* macros for field U2_INACTIVITY_TMOUT */
+#endif /* __CFG_REG63_MACRO__ */
+
+
+/* macros for usbss_dev_register_block.cfg_reg63 */
+#ifndef __CFG_REG64_MACRO__
+#define __CFG_REG64_MACRO__
+
+/* macros for field TFILTSE0 */
+#endif /* __CFG_REG64_MACRO__ */
+
+
+/* macros for usbss_dev_register_block.cfg_reg64 */
+#ifndef __CFG_REG65_MACRO__
+#define __CFG_REG65_MACRO__
+
+/* macros for field TFILT */
+#endif /* __CFG_REG65_MACRO__ */
+
+
+/* macros for usbss_dev_register_block.cfg_reg65 */
+#ifndef __CFG_REG66_MACRO__
+#define __CFG_REG66_MACRO__
+
+/* macros for field TWTRSTFS_SE0 */
+#endif /* __CFG_REG66_MACRO__ */
+
+
+/* macros for usbss_dev_register_block.cfg_reg66 */
+#ifndef __DMA_AXI_CTRL_MACRO__
+#define __DMA_AXI_CTRL_MACRO__
+
+/* macros for field MAWPROT */
+#endif /* __DMA_AXI_CTRL_MACRO__ */
+
+
+/* macros for usbss_dev_register_block.dma_axi_ctrl */
+#ifndef __DMA_AXI_ID_MACRO__
+#define __DMA_AXI_ID_MACRO__
+
+/* macros for field MAW_ID */
+#endif /* __DMA_AXI_ID_MACRO__ */
+
+
+/* macros for usbss_dev_register_block.dma_axi_id */
+#ifndef __DMA_AXI_CAP_MACRO__
+#define __DMA_AXI_CAP_MACRO__
+
+/* macros for field RESERVED0 */
+#endif /* __DMA_AXI_CAP_MACRO__ */
+
+
+/* macros for usbss_dev_register_block.dma_axi_cap */
+#ifndef __DMA_AXI_CTRL0_MACRO__
+#define __DMA_AXI_CTRL0_MACRO__
+
+/* macros for field B_MAX */
+#endif /* __DMA_AXI_CTRL0_MACRO__ */
+
+
+/* macros for usbss_dev_register_block.dma_axi_ctrl0 */
+#ifndef __DMA_AXI_CTRL1_MACRO__
+#define __DMA_AXI_CTRL1_MACRO__
+
+/* macros for field ROT */
+#endif /* __DMA_AXI_CTRL1_MACRO__ */
+
+
+/* macros for usbss_dev_register_block.dma_axi_ctrl1 */
+#endif /* __REG_USBSS_DEV_ADDR_MAP_MACRO_H__ */
diff --git a/drivers/usb/cdns3/dev-regs-map.h b/drivers/usb/cdns3/dev-regs-map.h
new file mode 100644
index 000000000000..ef9cfe2ff342
--- /dev/null
+++ b/drivers/usb/cdns3/dev-regs-map.h
@@ -0,0 +1,126 @@
+/**
+ * dev-regs-map.h - Cadence USB3 Device register map definition
+ *
+ * Copyright (C) 2016 Cadence Design Systems - http://www.cadence.com
+ * Copyright 2017 NXP
+ *
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+
+#ifndef __REG_USBSS_DEV_ADDR_MAP_H__
+#define __REG_USBSS_DEV_ADDR_MAP_H__
+
+#include "dev-regs-macro.h"
+
+struct usbss_dev_register_block_type {
+ uint32_t usb_conf; /* 0x0 - 0x4 */
+ uint32_t usb_sts; /* 0x4 - 0x8 */
+ uint32_t usb_cmd; /* 0x8 - 0xc */
+ uint32_t usb_iptn; /* 0xc - 0x10 */
+ uint32_t usb_lpm; /* 0x10 - 0x14 */
+ uint32_t usb_ien; /* 0x14 - 0x18 */
+ uint32_t usb_ists; /* 0x18 - 0x1c */
+ uint32_t ep_sel; /* 0x1c - 0x20 */
+ uint32_t ep_traddr; /* 0x20 - 0x24 */
+ uint32_t ep_cfg; /* 0x24 - 0x28 */
+ uint32_t ep_cmd; /* 0x28 - 0x2c */
+ uint32_t ep_sts; /* 0x2c - 0x30 */
+ uint32_t ep_sts_sid; /* 0x30 - 0x34 */
+ uint32_t ep_sts_en; /* 0x34 - 0x38 */
+ uint32_t drbl; /* 0x38 - 0x3c */
+ uint32_t ep_ien; /* 0x3c - 0x40 */
+ uint32_t ep_ists; /* 0x40 - 0x44 */
+ uint32_t usb_pwr; /* 0x44 - 0x48 */
+ uint32_t usb_conf2; /* 0x48 - 0x4c */
+ uint32_t usb_cap1; /* 0x4c - 0x50 */
+ uint32_t usb_cap2; /* 0x50 - 0x54 */
+ uint32_t usb_cap3; /* 0x54 - 0x58 */
+ uint32_t usb_cap4; /* 0x58 - 0x5c */
+ uint32_t usb_cap5; /* 0x5c - 0x60 */
+ uint32_t PAD2_73; /* 0x60 - 0x64 */
+ uint32_t usb_cpkt1; /* 0x64 - 0x68 */
+ uint32_t usb_cpkt2; /* 0x68 - 0x6c */
+ uint32_t usb_cpkt3; /* 0x6c - 0x70 */
+ char pad__0[0x90]; /* 0x70 - 0x100 */
+ uint32_t PAD2_78; /* 0x100 - 0x104 */
+ uint32_t dbg_link1; /* 0x104 - 0x108 */
+ uint32_t PAD2_80; /* 0x108 - 0x10c */
+ uint32_t PAD2_81; /* 0x10c - 0x110 */
+ uint32_t PAD2_82; /* 0x110 - 0x114 */
+ uint32_t PAD2_83; /* 0x114 - 0x118 */
+ uint32_t PAD2_84; /* 0x118 - 0x11c */
+ uint32_t PAD2_85; /* 0x11c - 0x120 */
+ uint32_t PAD2_86; /* 0x120 - 0x124 */
+ uint32_t PAD2_87; /* 0x124 - 0x128 */
+ uint32_t PAD2_88; /* 0x128 - 0x12c */
+ uint32_t PAD2_89; /* 0x12c - 0x130 */
+ uint32_t PAD2_90; /* 0x130 - 0x134 */
+ uint32_t PAD2_91; /* 0x134 - 0x138 */
+ uint32_t PAD2_92; /* 0x138 - 0x13c */
+ uint32_t PAD2_93; /* 0x13c - 0x140 */
+ uint32_t PAD2_94; /* 0x140 - 0x144 */
+ uint32_t PAD2_95; /* 0x144 - 0x148 */
+ uint32_t PAD2_96; /* 0x148 - 0x14c */
+ uint32_t PAD2_97; /* 0x14c - 0x150 */
+ uint32_t PAD2_98; /* 0x150 - 0x154 */
+ uint32_t PAD2_99; /* 0x154 - 0x158 */
+ uint32_t PAD2_100; /* 0x158 - 0x15c */
+ uint32_t PAD2_101; /* 0x15c - 0x160 */
+ uint32_t PAD2_102; /* 0x160 - 0x164 */
+ uint32_t PAD2_103; /* 0x164 - 0x168 */
+ uint32_t PAD2_104; /* 0x168 - 0x16c */
+ uint32_t PAD2_105; /* 0x16c - 0x170 */
+ uint32_t PAD2_106; /* 0x170 - 0x174 */
+ uint32_t PAD2_107; /* 0x174 - 0x178 */
+ uint32_t PAD2_108; /* 0x178 - 0x17c */
+ uint32_t PAD2_109; /* 0x17c - 0x180 */
+ uint32_t PAD2_110; /* 0x180 - 0x184 */
+ uint32_t PAD2_111; /* 0x184 - 0x188 */
+ uint32_t PAD2_112; /* 0x188 - 0x18c */
+ char pad__1[0x20]; /* 0x18c - 0x1ac */
+ uint32_t PAD2_114; /* 0x1ac - 0x1b0 */
+ uint32_t PAD2_115; /* 0x1b0 - 0x1b4 */
+ uint32_t PAD2_116; /* 0x1b4 - 0x1b8 */
+ uint32_t PAD2_117; /* 0x1b8 - 0x1bc */
+ uint32_t PAD2_118; /* 0x1bc - 0x1c0 */
+ uint32_t PAD2_119; /* 0x1c0 - 0x1c4 */
+ uint32_t PAD2_120; /* 0x1c4 - 0x1c8 */
+ uint32_t PAD2_121; /* 0x1c8 - 0x1cc */
+ uint32_t PAD2_122; /* 0x1cc - 0x1d0 */
+ uint32_t PAD2_123; /* 0x1d0 - 0x1d4 */
+ uint32_t PAD2_124; /* 0x1d4 - 0x1d8 */
+ uint32_t PAD2_125; /* 0x1d8 - 0x1dc */
+ uint32_t PAD2_126; /* 0x1dc - 0x1e0 */
+ uint32_t PAD2_127; /* 0x1e0 - 0x1e4 */
+ uint32_t PAD2_128; /* 0x1e4 - 0x1e8 */
+ uint32_t PAD2_129; /* 0x1e8 - 0x1ec */
+ uint32_t PAD2_130; /* 0x1ec - 0x1f0 */
+ uint32_t PAD2_131; /* 0x1f0 - 0x1f4 */
+ uint32_t PAD2_132; /* 0x1f4 - 0x1f8 */
+ uint32_t PAD2_133; /* 0x1f8 - 0x1fc */
+ uint32_t PAD2_134; /* 0x1fc - 0x200 */
+ uint32_t PAD2_135; /* 0x200 - 0x204 */
+ uint32_t PAD2_136; /* 0x204 - 0x208 */
+ uint32_t PAD2_137; /* 0x208 - 0x20c */
+ uint32_t PAD2_138; /* 0x20c - 0x210 */
+ uint32_t PAD2_139; /* 0x210 - 0x214 */
+ uint32_t PAD2_140; /* 0x214 - 0x218 */
+ uint32_t PAD2_141; /* 0x218 - 0x21c */
+ uint32_t PAD2_142; /* 0x21c - 0x220 */
+ uint32_t PAD2_143; /* 0x220 - 0x224 */
+ uint32_t PAD2_144; /* 0x224 - 0x228 */
+ char pad__2[0xd8]; /* 0x228 - 0x300 */
+ uint32_t dma_axi_ctrl; /* 0x300 - 0x304 */
+ uint32_t PAD2_147; /* 0x304 - 0x308 */
+ uint32_t PAD2_148; /* 0x308 - 0x30c */
+ uint32_t PAD2_149; /* 0x30c - 0x310 */
+ uint32_t PAD2_150; /* 0x310 - 0x314 */
+};
+
+#endif /* __REG_USBSS_DEV_ADDR_MAP_H__ */
diff --git a/drivers/usb/cdns3/gadget-export.h b/drivers/usb/cdns3/gadget-export.h
new file mode 100644
index 000000000000..e085ed38ea05
--- /dev/null
+++ b/drivers/usb/cdns3/gadget-export.h
@@ -0,0 +1,36 @@
+/*
+ * gadget-export.h - Gadget Export APIs
+ *
+ * Copyright 2017 NXP
+ * Authors: Peter Chen <peter.chen@nxp.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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#ifndef __CDNS3_GADGET_EXPORT_H
+#define __CDNS3_GADGET_EXPORT_H
+
+#ifdef CONFIG_USB_CDNS3_GADGET
+
+int cdns3_gadget_init(struct cdns3 *cdns);
+void cdns3_gadget_remove(struct cdns3 *cdns);
+#else
+
+static inline int cdns3_gadget_init(struct cdns3 *cdns)
+{
+ return -ENXIO;
+}
+
+static inline void cdns3_gadget_remove(struct cdns3 *cdns)
+{
+
+}
+
+#endif
+
+#endif /* __CDNS3_GADGET_EXPORT_H */
diff --git a/drivers/usb/cdns3/gadget.c b/drivers/usb/cdns3/gadget.c
new file mode 100644
index 000000000000..a15a89a64a13
--- /dev/null
+++ b/drivers/usb/cdns3/gadget.c
@@ -0,0 +1,2555 @@
+/**
+ * gadget.c - Cadence USB3 Device Core file
+ *
+ * Copyright (C) 2016 Cadence Design Systems - http://www.cadence.com
+ * Copyright 2017 NXP
+ *
+ * Authors: Pawel Jez <pjez@cadence.com>,
+ * Konrad Kociolek <konrad@cadence.com>
+ * Peter Chen <peter.chen@nxp.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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/platform_device.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/interrupt.h>
+#include <linux/dma-mapping.h>
+#include <linux/pm_runtime.h>
+#include <linux/usb/composite.h>
+#include <linux/of_platform.h>
+#include <linux/usb/gadget.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/byteorder/generic.h>
+#include <linux/ctype.h>
+
+#include "core.h"
+#include "gadget-export.h"
+#include "gadget.h"
+#include "io.h"
+
+/*-------------------------------------------------------------------------*/
+/* Function declarations */
+
+static void select_ep(struct usb_ss_dev *usb_ss, u32 ep);
+static int usb_ss_allocate_trb_pool(struct usb_ss_endpoint *usb_ss_ep);
+static void cdns_ep_stall_flush(struct usb_ss_endpoint *usb_ss_ep);
+static void cdns_ep0_config(struct usb_ss_dev *usb_ss);
+static void cdns_gadget_unconfig(struct usb_ss_dev *usb_ss);
+static void cdns_ep0_run_transfer(struct usb_ss_dev *usb_ss,
+ dma_addr_t dma_addr, unsigned int length, int erdy);
+static int cdns_ep_run_transfer(struct usb_ss_endpoint *usb_ss_ep);
+static int cdns_get_setup_ret(struct usb_ss_dev *usb_ss,
+ struct usb_ctrlrequest *ctrl_req);
+static int cdns_req_ep0_set_address(struct usb_ss_dev *usb_ss,
+ struct usb_ctrlrequest *ctrl_req);
+static int cdns_req_ep0_get_status(struct usb_ss_dev *usb_ss,
+ struct usb_ctrlrequest *ctrl_req);
+static int cdns_req_ep0_handle_feature(struct usb_ss_dev *usb_ss,
+ struct usb_ctrlrequest *ctrl_req, int set);
+static int cdns_req_ep0_set_sel(struct usb_ss_dev *usb_ss,
+ struct usb_ctrlrequest *ctrl_req);
+static int cdns_req_ep0_set_isoch_delay(struct usb_ss_dev *usb_ss,
+ struct usb_ctrlrequest *ctrl_req);
+static int cdns_req_ep0_set_configuration(struct usb_ss_dev *usb_ss,
+ struct usb_ctrlrequest *ctrl_req);
+static int cdns_ep0_standard_request(struct usb_ss_dev *usb_ss,
+ struct usb_ctrlrequest *ctrl_req);
+static void cdns_ep0_setup_phase(struct usb_ss_dev *usb_ss);
+static int cdns_check_ep_interrupt_proceed(struct usb_ss_endpoint *usb_ss_ep);
+static void cdns_check_ep0_interrupt_proceed(struct usb_ss_dev *usb_ss,
+ int dir);
+static void cdns_check_usb_interrupt_proceed(struct usb_ss_dev *usb_ss,
+ u32 usb_ists);
+static int usb_ss_gadget_ep0_enable(struct usb_ep *ep,
+ const struct usb_endpoint_descriptor *desc);
+static int usb_ss_gadget_ep0_disable(struct usb_ep *ep);
+static int usb_ss_gadget_ep0_set_halt(struct usb_ep *ep, int value);
+static int usb_ss_gadget_ep0_queue(struct usb_ep *ep,
+ struct usb_request *request, gfp_t gfp_flags);
+static int usb_ss_gadget_ep_enable(struct usb_ep *ep,
+ const struct usb_endpoint_descriptor *desc);
+static int usb_ss_gadget_ep_disable(struct usb_ep *ep);
+static struct usb_request *usb_ss_gadget_ep_alloc_request(struct usb_ep *ep,
+ gfp_t gfp_flags);
+static void usb_ss_gadget_ep_free_request(struct usb_ep *ep,
+ struct usb_request *request);
+static int usb_ss_gadget_ep_queue(struct usb_ep *ep,
+ struct usb_request *request, gfp_t gfp_flags);
+static int usb_ss_gadget_ep_dequeue(struct usb_ep *ep,
+ struct usb_request *request);
+static int usb_ss_gadget_ep_set_halt(struct usb_ep *ep, int value);
+static int usb_ss_gadget_ep_set_wedge(struct usb_ep *ep);
+static int usb_ss_gadget_get_frame(struct usb_gadget *gadget);
+static int usb_ss_gadget_wakeup(struct usb_gadget *gadget);
+static int usb_ss_gadget_set_selfpowered(struct usb_gadget *gadget,
+ int is_selfpowered);
+static int usb_ss_gadget_pullup(struct usb_gadget *gadget, int is_on);
+static int usb_ss_gadget_udc_start(struct usb_gadget *gadget,
+ struct usb_gadget_driver *driver);
+static int usb_ss_gadget_udc_stop(struct usb_gadget *gadget);
+static int usb_ss_init_ep(struct usb_ss_dev *usb_ss);
+static int usb_ss_init_ep0(struct usb_ss_dev *usb_ss);
+static void __cdns3_gadget_start(struct usb_ss_dev *usb_ss);
+static void cdns_prepare_setup_packet(struct usb_ss_dev *usb_ss);
+static void cdns_ep_config(struct usb_ss_endpoint *usb_ss_ep);
+static void cdns_enable_l1(struct usb_ss_dev *usb_ss, int enable);
+static void __pending_setup_status_handler(struct usb_ss_dev *usb_ss);
+static void cdns_enable_u1(struct usb_ss_dev *usb_ss, int enable);
+static void cdns_enable_u2(struct usb_ss_dev *usb_ss, int enable);
+
+static struct usb_endpoint_descriptor cdns3_gadget_ep0_desc = {
+ .bLength = USB_DT_ENDPOINT_SIZE,
+ .bDescriptorType = USB_DT_ENDPOINT,
+ .bmAttributes = USB_ENDPOINT_XFER_CONTROL,
+};
+
+static u32 gadget_readl(struct usb_ss_dev *usb_ss, uint32_t __iomem *reg)
+{
+ return cdns_readl(reg);
+}
+
+static void gadget_writel(struct usb_ss_dev *usb_ss,
+ uint32_t __iomem *reg, u32 value)
+{
+ cdns_writel(reg, value);
+}
+
+/**
+ * next_request - returns next request from list
+ * @list: list containing requests
+ *
+ * Returns request or NULL if no requests in list
+ */
+static struct usb_request *next_request(struct list_head *list)
+{
+ if (list_empty(list))
+ return NULL;
+ return list_first_entry(list, struct usb_request, list);
+}
+
+/**
+ * wait_reg_bit - Read reg and compare until equal to specific value
+ * @reg: the register address to read
+ * @value: the value to compare
+ * @wait_value: 0 or 1
+ * @timeout_ms: timeout value in milliseconds, must be larger than 1
+ *
+ * Returns -ETIMEDOUT if timeout occurs
+ */
+static int wait_reg_bit(struct usb_ss_dev *usb_ss, u32 __iomem *reg,
+ u32 value, int wait_value, int timeout_ms)
+{
+ u32 temp;
+
+ WARN_ON(timeout_ms <= 0);
+ timeout_ms *= 100;
+ temp = cdns_readl(reg);
+ while (timeout_ms-- > 0) {
+ if (!!(temp & value) == wait_value)
+ return 0;
+ temp = cdns_readl(reg);
+ udelay(10);
+ }
+
+ dev_err(&usb_ss->dev, "wait register timeout %s\n", __func__);
+ return -ETIMEDOUT;
+}
+
+static int wait_reg_bit_set(struct usb_ss_dev *usb_ss, u32 __iomem *reg,
+ u32 value, int timeout_ms)
+{
+ return wait_reg_bit(usb_ss, reg, value, 1, timeout_ms);
+}
+
+static int wait_reg_bit_clear(struct usb_ss_dev *usb_ss, u32 __iomem *reg,
+ u32 value, int timeout_ms)
+{
+ return wait_reg_bit(usb_ss, reg, value, 0, timeout_ms);
+}
+
+/**
+ * select_ep - selects endpoint
+ * @usb_ss: extended gadget object
+ * @ep: endpoint address
+ */
+static void select_ep(struct usb_ss_dev *usb_ss, u32 ep)
+{
+ if (!usb_ss || !usb_ss->regs) {
+ dev_err(&usb_ss->dev, "Failed to select endpoint!\n");
+ return;
+ }
+
+ gadget_writel(usb_ss, &usb_ss->regs->ep_sel, ep);
+}
+
+/**
+ * usb_ss_allocate_trb_pool - Allocates TRB's pool for selected endpoint
+ * @usb_ss_ep: extended endpoint object
+ *
+ * Function will return 0 on success or -ENOMEM on allocation error
+ */
+static int usb_ss_allocate_trb_pool(struct usb_ss_endpoint *usb_ss_ep)
+{
+ struct usb_ss_dev *usb_ss = usb_ss_ep->usb_ss;
+
+ if (!usb_ss_ep->trb_pool) {
+ usb_ss_ep->trb_pool = dma_zalloc_coherent(usb_ss->sysdev,
+ sizeof(struct usb_ss_trb) * USB_SS_TRBS_NUM,
+ &usb_ss_ep->trb_pool_dma, GFP_DMA);
+ if (!usb_ss_ep->trb_pool)
+ return -ENOMEM;
+ }
+
+ if (!usb_ss_ep->cpu_addr) {
+ usb_ss_ep->cpu_addr = dma_alloc_coherent(usb_ss->sysdev,
+ CDNS3_UNALIGNED_BUF_SIZE,
+ &usb_ss_ep->dma_addr, GFP_DMA);
+ if (!usb_ss_ep->cpu_addr)
+ return -ENOMEM;
+ }
+
+ return 0;
+}
+
+/**
+ * cdns_data_flush - do flush data at onchip buffer
+ * @usb_ss_ep: extended endpoint object
+ *
+ * Endpoint must be selected before call to this function
+ *
+ * Returns zero on success or negative value on failure
+ */
+static int cdns_data_flush(struct usb_ss_endpoint *usb_ss_ep)
+{
+ struct usb_ss_dev *usb_ss = usb_ss_ep->usb_ss;
+
+ gadget_writel(usb_ss, &usb_ss->regs->ep_cmd,
+ EP_CMD__DFLUSH__MASK);
+ /* wait for DFLUSH cleared */
+ return wait_reg_bit_clear(usb_ss, &usb_ss->regs->ep_cmd,
+ EP_CMD__DFLUSH__MASK, 100);
+}
+
+/**
+ * cdns_ep_stall_flush - Stalls and flushes selected endpoint
+ * @usb_ss_ep: extended endpoint object
+ *
+ * Endpoint must be selected before call to this function
+ */
+static void cdns_ep_stall_flush(struct usb_ss_endpoint *usb_ss_ep)
+{
+ struct usb_ss_dev *usb_ss = usb_ss_ep->usb_ss;
+
+ gadget_writel(usb_ss, &usb_ss->regs->ep_cmd,
+ EP_CMD__DFLUSH__MASK | EP_CMD__ERDY__MASK |
+ EP_CMD__SSTALL__MASK);
+
+ /* wait for DFLUSH cleared */
+ wait_reg_bit_clear(usb_ss, &usb_ss->regs->ep_cmd,
+ EP_CMD__DFLUSH__MASK, 100);
+ usb_ss_ep->stalled_flag = 1;
+}
+
+/**
+ * cdns_ep0_config - Configures default endpoint
+ * @usb_ss: extended gadget object
+ *
+ * Functions sets parameters: maximal packet size and enables interrupts
+ */
+static void cdns_ep0_config(struct usb_ss_dev *usb_ss)
+{
+ u32 reg, max_packet_size = 0;
+
+ switch (usb_ss->gadget.speed) {
+ case USB_SPEED_UNKNOWN:
+ max_packet_size = ENDPOINT_MAX_PACKET_SIZE_0;
+ usb_ss->gadget.ep0->maxpacket = ENDPOINT_MAX_PACKET_SIZE_0;
+ cdns3_gadget_ep0_desc.wMaxPacketSize = cpu_to_le16(0);
+ break;
+
+ case USB_SPEED_LOW:
+ max_packet_size = ENDPOINT_MAX_PACKET_SIZE_8;
+ usb_ss->gadget.ep0->maxpacket = ENDPOINT_MAX_PACKET_SIZE_8;
+ cdns3_gadget_ep0_desc.wMaxPacketSize = cpu_to_le16(8);
+ break;
+
+ case USB_SPEED_FULL:
+ max_packet_size = ENDPOINT_MAX_PACKET_SIZE_64;
+ usb_ss->gadget.ep0->maxpacket = ENDPOINT_MAX_PACKET_SIZE_64;
+ cdns3_gadget_ep0_desc.wMaxPacketSize = cpu_to_le16(64);
+ break;
+
+ case USB_SPEED_HIGH:
+ max_packet_size = ENDPOINT_MAX_PACKET_SIZE_64;
+ usb_ss->gadget.ep0->maxpacket = ENDPOINT_MAX_PACKET_SIZE_64;
+ cdns3_gadget_ep0_desc.wMaxPacketSize = cpu_to_le16(64);
+ break;
+
+ case USB_SPEED_WIRELESS:
+ max_packet_size = ENDPOINT_MAX_PACKET_SIZE_64;
+ usb_ss->gadget.ep0->maxpacket = ENDPOINT_MAX_PACKET_SIZE_64;
+ cdns3_gadget_ep0_desc.wMaxPacketSize = cpu_to_le16(64);
+ break;
+
+ case USB_SPEED_SUPER:
+ max_packet_size = ENDPOINT_MAX_PACKET_SIZE_512;
+ usb_ss->gadget.ep0->maxpacket = ENDPOINT_MAX_PACKET_SIZE_512;
+ cdns3_gadget_ep0_desc.wMaxPacketSize = cpu_to_le16(512);
+ break;
+
+ case USB_SPEED_SUPER_PLUS:
+ dev_warn(&usb_ss->dev, "USB 3.1 is not supported\n");
+ usb_ss->gadget.ep0->maxpacket = ENDPOINT_MAX_PACKET_SIZE_512;
+ cdns3_gadget_ep0_desc.wMaxPacketSize = cpu_to_le16(512);
+ max_packet_size = ENDPOINT_MAX_PACKET_SIZE_512;
+ break;
+ }
+
+ /* init ep out */
+ select_ep(usb_ss, USB_DIR_OUT);
+
+ gadget_writel(usb_ss, &usb_ss->regs->ep_cfg,
+ EP_CFG__ENABLE__MASK |
+ EP_CFG__MAXPKTSIZE__WRITE(max_packet_size));
+ gadget_writel(usb_ss, &usb_ss->regs->ep_sts_en,
+ EP_STS_EN__SETUPEN__MASK |
+ EP_STS_EN__DESCMISEN__MASK |
+ EP_STS_EN__TRBERREN__MASK);
+
+ /* init ep in */
+ select_ep(usb_ss, USB_DIR_IN);
+
+ gadget_writel(usb_ss, &usb_ss->regs->ep_cfg,
+ EP_CFG__ENABLE__MASK |
+ EP_CFG__MAXPKTSIZE__WRITE(max_packet_size));
+ gadget_writel(usb_ss, &usb_ss->regs->ep_sts_en,
+ EP_STS_EN__SETUPEN__MASK |
+ EP_STS_EN__TRBERREN__MASK);
+
+ reg = gadget_readl(usb_ss, &usb_ss->regs->usb_conf);
+ reg |= USB_CONF__U1DS__MASK | USB_CONF__U2DS__MASK;
+ gadget_writel(usb_ss, &usb_ss->regs->usb_conf, reg);
+
+ cdns_prepare_setup_packet(usb_ss);
+}
+
+/**
+ * cdns_gadget_unconfig - Unconfigures device controller
+ * @usb_ss: extended gadget object
+ */
+static void cdns_gadget_unconfig(struct usb_ss_dev *usb_ss)
+{
+ /* RESET CONFIGURATION */
+ gadget_writel(usb_ss, &usb_ss->regs->usb_conf,
+ USB_CONF__CFGRST__MASK);
+
+ cdns_enable_l1(usb_ss, 0);
+ usb_ss->hw_configured_flag = 0;
+ usb_ss->onchip_mem_allocated_size = 0;
+ usb_ss->out_mem_is_allocated = 0;
+}
+
+/**
+ * cdns_ep0_run_transfer - Do transfer on default endpoint hardware
+ * @usb_ss: extended gadget object
+ * @dma_addr: physical address where data is/will be stored
+ * @length: data length
+ * @erdy: set it to 1 when ERDY packet should be sent -
+ * exit from flow control state
+ */
+static void cdns_ep0_run_transfer(struct usb_ss_dev *usb_ss,
+ dma_addr_t dma_addr, unsigned int length, int erdy)
+{
+ usb_ss->trb_ep0[0] = TRB_SET_DATA_BUFFER_POINTER(dma_addr);
+ usb_ss->trb_ep0[1] = TRB_SET_TRANSFER_LENGTH((u32)length);
+ usb_ss->trb_ep0[2] = TRB_SET_CYCLE_BIT |
+ TRB_SET_INT_ON_COMPLETION | TRB_TYPE_NORMAL;
+
+ dev_dbg(&usb_ss->dev, "DRBL(%02X)\n",
+ usb_ss->ep0_data_dir ? USB_DIR_IN : USB_DIR_OUT);
+
+ select_ep(usb_ss, usb_ss->ep0_data_dir
+ ? USB_DIR_IN : USB_DIR_OUT);
+
+ gadget_writel(usb_ss, &usb_ss->regs->ep_traddr,
+ EP_TRADDR__TRADDR__WRITE(usb_ss->trb_ep0_dma));
+ gadget_writel(usb_ss, &usb_ss->regs->ep_cmd,
+ EP_CMD__DRDY__MASK); /* drbl */
+
+ if (erdy)
+ gadget_writel(usb_ss, &usb_ss->regs->ep_cmd,
+ EP_CMD__ERDY__MASK);
+}
+
+/**
+ * cdns_ep_run_transfer - Do transfer on no-default endpoint hardware
+ * @usb_ss_ep: extended endpoint object
+ *
+ * Returns zero on success or negative value on failure
+ */
+static int cdns_ep_run_transfer(struct usb_ss_endpoint *usb_ss_ep)
+{
+ dma_addr_t trb_dma;
+ struct usb_request *request = next_request(&usb_ss_ep->request_list);
+ struct usb_ss_dev *usb_ss = usb_ss_ep->usb_ss;
+ int sg_iter = 0;
+ struct usb_ss_trb *trb;
+
+ if (request == NULL)
+ return -EINVAL;
+
+ if (request->num_sgs > USB_SS_TRBS_NUM)
+ return -EINVAL;
+
+ dev_dbg(&usb_ss->dev, "DRBL(%02X)\n",
+ usb_ss_ep->endpoint.desc->bEndpointAddress);
+
+ usb_ss_ep->hw_pending_flag = 1;
+ trb_dma = request->dma;
+
+ /* must allocate buffer aligned to 8 */
+ if ((request->dma % ADDR_MODULO_8)) {
+ if (request->length <= CDNS3_UNALIGNED_BUF_SIZE) {
+ memcpy(usb_ss_ep->cpu_addr, request->buf,
+ request->length);
+ trb_dma = usb_ss_ep->dma_addr;
+ } else {
+ return -ENOMEM;
+ }
+ }
+
+ trb = usb_ss_ep->trb_pool;
+
+ do {
+ /* fill TRB */
+ trb->offset0 = TRB_SET_DATA_BUFFER_POINTER(request->num_sgs == 0
+ ? trb_dma : request->sg[sg_iter].dma_address);
+
+ trb->offset4 = TRB_SET_BURST_LENGTH(16) |
+ TRB_SET_TRANSFER_LENGTH(request->num_sgs == 0 ?
+ request->length : request->sg[sg_iter].length);
+
+ trb->offset8 = TRB_SET_CYCLE_BIT
+ | TRB_SET_INT_ON_COMPLETION
+ | TRB_SET_INT_ON_SHORT_PACKET
+ | TRB_TYPE_NORMAL;
+
+ ++sg_iter;
+ ++trb;
+
+ } while (sg_iter < request->num_sgs);
+
+ /* arm transfer on selected endpoint */
+ select_ep(usb_ss_ep->usb_ss,
+ usb_ss_ep->endpoint.desc->bEndpointAddress);
+ gadget_writel(usb_ss, &usb_ss->regs->ep_traddr,
+ EP_TRADDR__TRADDR__WRITE(usb_ss_ep->trb_pool_dma));
+ gadget_writel(usb_ss, &usb_ss->regs->ep_cmd,
+ EP_CMD__DRDY__MASK); /* DRDY */
+ return 0;
+}
+
+/**
+ * cdns_get_setup_ret - Returns status of handling setup packet
+ * Setup is handled by gadget driver
+ * @usb_ss: extended gadget object
+ * @ctrl_req: pointer to received setup packet
+ *
+ * Returns zero on success or negative value on failure
+ */
+static int cdns_get_setup_ret(struct usb_ss_dev *usb_ss,
+ struct usb_ctrlrequest *ctrl_req)
+{
+ int ret;
+
+ spin_unlock(&usb_ss->lock);
+ usb_ss->setup_pending = 1;
+ ret = usb_ss->gadget_driver->setup(&usb_ss->gadget, ctrl_req);
+ usb_ss->setup_pending = 0;
+ spin_lock(&usb_ss->lock);
+ return ret;
+}
+
+static void cdns_prepare_setup_packet(struct usb_ss_dev *usb_ss)
+{
+ usb_ss->ep0_data_dir = 0;
+ cdns_ep0_run_transfer(usb_ss, usb_ss->setup_dma, 8, 0);
+}
+
+/**
+ * cdns_req_ep0_set_address - Handling of SET_ADDRESS standard USB request
+ * @usb_ss: extended gadget object
+ * @ctrl_req: pointer to received setup packet
+ *
+ * Returns 0 if success, error code on error
+ */
+static int cdns_req_ep0_set_address(struct usb_ss_dev *usb_ss,
+ struct usb_ctrlrequest *ctrl_req)
+{
+ enum usb_device_state device_state = usb_ss->gadget.state;
+ u32 reg;
+ u32 addr;
+
+ addr = le16_to_cpu(ctrl_req->wValue);
+
+ if (addr > DEVICE_ADDRESS_MAX) {
+ dev_err(&usb_ss->dev,
+ "Device address (%d) cannot be greater than %d\n",
+ addr, DEVICE_ADDRESS_MAX);
+ return -EINVAL;
+ }
+
+ if (device_state == USB_STATE_CONFIGURED) {
+ dev_err(&usb_ss->dev, "USB device already configured\n");
+ return -EINVAL;
+ }
+
+ reg = gadget_readl(usb_ss, &usb_ss->regs->usb_cmd);
+
+ gadget_writel(usb_ss, &usb_ss->regs->usb_cmd, reg
+ | USB_CMD__FADDR__WRITE(addr)
+ | USB_CMD__SET_ADDR__MASK);
+
+ usb_gadget_set_state(&usb_ss->gadget,
+ (addr ? USB_STATE_ADDRESS : USB_STATE_DEFAULT));
+
+ cdns_prepare_setup_packet(usb_ss);
+
+ gadget_writel(usb_ss, &usb_ss->regs->ep_cmd,
+ EP_CMD__ERDY__MASK | EP_CMD__REQ_CMPL__MASK);
+ return 0;
+}
+
+/**
+ * cdns_req_ep0_get_status - Handling of GET_STATUS standard USB request
+ * @usb_ss: extended gadget object
+ * @ctrl_req: pointer to received setup packet
+ *
+ * Returns 0 if success, error code on error
+ */
+static int cdns_req_ep0_get_status(struct usb_ss_dev *usb_ss,
+ struct usb_ctrlrequest *ctrl_req)
+{
+ u16 usb_status = 0;
+ unsigned int length = 2;
+ u32 recip = ctrl_req->bRequestType & USB_RECIP_MASK;
+ u32 reg;
+
+ switch (recip) {
+
+ case USB_RECIP_DEVICE:
+ /* handling otg features */
+ if (ctrl_req->wIndex == OTG_STS_SELECTOR) {
+ length = 1;
+ usb_status = usb_ss->gadget.host_request_flag;
+ } else {
+
+ reg = gadget_readl(usb_ss, &usb_ss->regs->usb_sts);
+
+ if (reg & USB_STS__U1ENS__MASK)
+ usb_status |= 1uL << USB_DEV_STAT_U1_ENABLED;
+
+ if (reg & USB_STS__U2ENS__MASK)
+ usb_status |= 1uL << USB_DEV_STAT_U2_ENABLED;
+
+ if (usb_ss->wake_up_flag)
+ usb_status |= 1uL << USB_DEVICE_REMOTE_WAKEUP;
+
+ /* self powered */
+ usb_status |= usb_ss->gadget.is_selfpowered;
+ }
+ break;
+
+ case USB_RECIP_INTERFACE:
+ return cdns_get_setup_ret(usb_ss, ctrl_req);
+
+ case USB_RECIP_ENDPOINT:
+ /* check if endpoint is stalled */
+ select_ep(usb_ss, ctrl_req->wIndex);
+ if (gadget_readl(usb_ss, &usb_ss->regs->ep_sts)
+ & EP_STS__STALL__MASK)
+ usb_status = 1;
+ break;
+
+ default:
+ return -EINVAL;
+ }
+
+ *(u16 *)usb_ss->setup = cpu_to_le16(usb_status);
+
+ usb_ss->actual_ep0_request = NULL;
+ cdns_ep0_run_transfer(usb_ss, usb_ss->setup_dma, length, 1);
+ return 0;
+}
+
+/**
+ * cdns_req_ep0_handle_feature -
+ * Handling of GET/SET_FEATURE standard USB request
+ *
+ * @usb_ss: extended gadget object
+ * @ctrl_req: pointer to received setup packet
+ * @set: must be set to 1 for SET_FEATURE request
+ *
+ * Returns 0 if success, error code on error
+ */
+static int cdns_req_ep0_handle_feature(struct usb_ss_dev *usb_ss,
+ struct usb_ctrlrequest *ctrl_req, int set)
+{
+ u32 recip = ctrl_req->bRequestType & USB_RECIP_MASK;
+ struct usb_ss_endpoint *usb_ss_ep;
+ u32 reg;
+ u8 tmode = 0;
+ int ret = 0;
+
+ switch (recip) {
+ case USB_RECIP_DEVICE:
+ switch (ctrl_req->wValue) {
+ case USB_DEVICE_U1_ENABLE:
+ if (usb_ss->gadget.state != USB_STATE_CONFIGURED)
+ return -EINVAL;
+ if (usb_ss->gadget.speed != USB_SPEED_SUPER)
+ return -EINVAL;
+
+ if (set)
+ /* set U1EN */
+ cdns_enable_u1(usb_ss, 1);
+ else
+ /* set U1 disable */
+ cdns_enable_u1(usb_ss, 0);
+ break;
+ case USB_DEVICE_U2_ENABLE:
+ if (usb_ss->gadget.state != USB_STATE_CONFIGURED)
+ return -EINVAL;
+ if (usb_ss->gadget.speed != USB_SPEED_SUPER)
+ return -EINVAL;
+
+ if (set)
+ /* set U2EN */
+ cdns_enable_u2(usb_ss, 1);
+ else
+ /* set U2 disable */
+ cdns_enable_u2(usb_ss, 0);
+ break;
+ case USB_DEVICE_A_ALT_HNP_SUPPORT:
+ break;
+ case USB_DEVICE_A_HNP_SUPPORT:
+ break;
+ case USB_DEVICE_B_HNP_ENABLE:
+ if (!usb_ss->gadget.b_hnp_enable && set)
+ usb_ss->gadget.b_hnp_enable = 1;
+ break;
+ case USB_DEVICE_REMOTE_WAKEUP:
+ usb_ss->wake_up_flag = !!set;
+ break;
+ case USB_DEVICE_TEST_MODE:
+ if (usb_ss->gadget.state != USB_STATE_CONFIGURED)
+ return -EINVAL;
+ if (usb_ss->gadget.speed != USB_SPEED_HIGH &&
+ usb_ss->gadget.speed != USB_SPEED_FULL)
+ return -EINVAL;
+ if (ctrl_req->wLength != 0 ||
+ ctrl_req->bRequestType & USB_DIR_IN) {
+ dev_err(&usb_ss->dev, "req is error\n");
+ return -EINVAL;
+ }
+ tmode = le16_to_cpu(ctrl_req->wIndex) >> 8;
+ switch (tmode) {
+ case TEST_J:
+ case TEST_K:
+ case TEST_SE0_NAK:
+ case TEST_PACKET:
+ reg = gadget_readl(usb_ss,
+ &usb_ss->regs->usb_cmd);
+ tmode -= 1;
+ reg |= USB_CMD__STMODE |
+ USB_CMD__TMODE_SEL(tmode);
+ gadget_writel(usb_ss, &usb_ss->regs->usb_cmd,
+ reg);
+ dev_info(&usb_ss->dev,
+ "set test mode, val=0x%x", reg);
+ break;
+ default:
+ return -EINVAL;
+ }
+ break;
+
+ default:
+ return -EINVAL;
+
+ }
+ break;
+ case USB_RECIP_INTERFACE:
+ return cdns_get_setup_ret(usb_ss, ctrl_req);
+ case USB_RECIP_ENDPOINT:
+ select_ep(usb_ss, ctrl_req->wIndex);
+ if (set) {
+ /* set stall */
+ gadget_writel(usb_ss, &usb_ss->regs->ep_cmd,
+ EP_CMD__SSTALL__MASK);
+
+ /* handle non zero endpoint software endpoint */
+ if (ctrl_req->wIndex & 0x7F) {
+ usb_ss_ep = usb_ss->eps[CAST_EP_ADDR_TO_INDEX(
+ ctrl_req->wIndex)];
+ usb_ss_ep->stalled_flag = 1;
+ }
+ } else {
+ struct usb_request *request;
+
+ if (ctrl_req->wIndex & 0x7F) {
+ if (usb_ss->eps[CAST_EP_ADDR_TO_INDEX(
+ ctrl_req->wIndex)]->wedge_flag)
+ goto jmp_wedge;
+ }
+
+ /* clear stall */
+ gadget_writel(usb_ss, &usb_ss->regs->ep_cmd,
+ EP_CMD__CSTALL__MASK | EP_CMD__EPRST__MASK);
+ /* wait for EPRST cleared */
+ ret = wait_reg_bit_clear(usb_ss, &usb_ss->regs->ep_cmd,
+ EP_CMD__EPRST__MASK, 100);
+
+ /* handle non zero endpoint software endpoint */
+ if (ctrl_req->wIndex & 0x7F) {
+ usb_ss_ep = usb_ss->eps[CAST_EP_ADDR_TO_INDEX(
+ ctrl_req->wIndex)];
+ usb_ss_ep->stalled_flag = 0;
+
+ request = next_request(
+ &usb_ss_ep->request_list);
+ if (request)
+ cdns_ep_run_transfer(usb_ss_ep);
+ }
+ }
+jmp_wedge:
+ select_ep(usb_ss, 0x00);
+ break;
+
+ default:
+ return -EINVAL;
+ }
+
+ gadget_writel(usb_ss, &usb_ss->regs->ep_cmd,
+ EP_CMD__ERDY__MASK | EP_CMD__REQ_CMPL__MASK);
+ return ret;
+}
+
+/**
+ * cdns_req_ep0_set_sel - Handling of SET_SEL standard USB request
+ * @usb_ss: extended gadget object
+ * @ctrl_req: pointer to received setup packet
+ *
+ * Returns 0 if success, error code on error
+ */
+static int cdns_req_ep0_set_sel(struct usb_ss_dev *usb_ss,
+ struct usb_ctrlrequest *ctrl_req)
+{
+ if (usb_ss->gadget.state < USB_STATE_ADDRESS)
+ return -EINVAL;
+
+ if (ctrl_req->wLength != 6) {
+ dev_err(&usb_ss->dev, "Set SEL should be 6 bytes, got %d\n",
+ ctrl_req->wLength);
+ return -EINVAL;
+ }
+
+ usb_ss->ep0_data_dir = 0;
+ usb_ss->actual_ep0_request = NULL;
+ cdns_ep0_run_transfer(usb_ss, usb_ss->setup_dma, 6, 1);
+ return 0;
+}
+
+/**
+ * cdns_req_ep0_set_isoch_delay -
+ * Handling of GET_ISOCH_DELAY standard USB request
+ * @usb_ss: extended gadget object
+ * @ctrl_req: pointer to received setup packet
+ *
+ * Returns 0 if success, error code on error
+ */
+static int cdns_req_ep0_set_isoch_delay(struct usb_ss_dev *usb_ss,
+ struct usb_ctrlrequest *ctrl_req)
+{
+ if (ctrl_req->wIndex || ctrl_req->wLength)
+ return -EINVAL;
+
+ usb_ss->isoch_delay = ctrl_req->wValue;
+ gadget_writel(usb_ss, &usb_ss->regs->ep_cmd,
+ EP_CMD__ERDY__MASK | EP_CMD__REQ_CMPL__MASK);
+ return 0;
+}
+
+static void cdns_enable_l1(struct usb_ss_dev *usb_ss, int enable)
+{
+ if (enable)
+ gadget_writel(usb_ss, &usb_ss->regs->usb_conf,
+ USB_CONF__L1EN__MASK);
+ else
+ gadget_writel(usb_ss, &usb_ss->regs->usb_conf,
+ USB_CONF__L1DS__MASK);
+}
+
+static void cdns_enable_u1(struct usb_ss_dev *usb_ss, int enable)
+{
+ if (enable)
+ gadget_writel(usb_ss, &usb_ss->regs->usb_conf,
+ USB_CONF__U1EN__MASK);
+ else
+ gadget_writel(usb_ss, &usb_ss->regs->usb_conf,
+ USB_CONF__U1DS__MASK);
+}
+
+static void cdns_enable_u2(struct usb_ss_dev *usb_ss, int enable)
+{
+ if (enable)
+ gadget_writel(usb_ss, &usb_ss->regs->usb_conf,
+ USB_CONF__U2EN__MASK);
+ else
+ gadget_writel(usb_ss, &usb_ss->regs->usb_conf,
+ USB_CONF__U2DS__MASK);
+}
+
+/**
+ * cdns_req_ep0_set_configuration - Handling of SET_CONFIG standard USB request
+ * @usb_ss: extended gadget object
+ * @ctrl_req: pointer to received setup packet
+ *
+ * Returns 0 if success, 0x7FFF on deferred status stage, error code on error
+ */
+static int cdns_req_ep0_set_configuration(struct usb_ss_dev *usb_ss,
+ struct usb_ctrlrequest *ctrl_req)
+{
+ enum usb_device_state device_state = usb_ss->gadget.state;
+ u32 config = le16_to_cpu(ctrl_req->wValue);
+ struct usb_ep *ep;
+ struct usb_ss_endpoint *usb_ss_ep, *temp_ss_ep;
+ int i, result = 0;
+
+ switch (device_state) {
+ case USB_STATE_ADDRESS:
+ /* Configure non-control EPs */
+ list_for_each_entry_safe(usb_ss_ep, temp_ss_ep,
+ &usb_ss->ep_match_list, ep_match_pending_list)
+ cdns_ep_config(usb_ss_ep);
+
+ result = cdns_get_setup_ret(usb_ss, ctrl_req);
+
+ if (result != 0)
+ return result;
+
+ if (config) {
+ if (!usb_ss->hw_configured_flag) {
+ /* SET CONFIGURATION */
+ gadget_writel(usb_ss, &usb_ss->regs->usb_conf,
+ USB_CONF__CFGSET__MASK);
+ gadget_writel(usb_ss, &usb_ss->regs->ep_cmd,
+ EP_CMD__ERDY__MASK |
+ EP_CMD__REQ_CMPL__MASK);
+ /* wait until configuration set */
+ result = wait_reg_bit_set(usb_ss,
+ &usb_ss->regs->usb_sts,
+ USB_STS__CFGSTS__MASK, 100);
+ usb_ss->hw_configured_flag = 1;
+ cdns_enable_l1(usb_ss, 1);
+ if (usb_ss->gadget.speed == USB_SPEED_SUPER) {
+ cdns_enable_u1(usb_ss, 1);
+ cdns_enable_u2(usb_ss, 1);
+ }
+
+ list_for_each_entry(ep,
+ &usb_ss->gadget.ep_list,
+ ep_list) {
+ if (ep->enabled)
+ cdns_ep_run_transfer(
+ to_usb_ss_ep(ep));
+ }
+ }
+ } else {
+ cdns_gadget_unconfig(usb_ss);
+ for (i = 0; i < usb_ss->ep_nums; i++)
+ usb_ss->eps[i]->endpoint.enabled = 0;
+ usb_gadget_set_state(&usb_ss->gadget,
+ USB_STATE_ADDRESS);
+ }
+ break;
+ case USB_STATE_CONFIGURED:
+ result = cdns_get_setup_ret(usb_ss, ctrl_req);
+ if (!config && !result) {
+ cdns_gadget_unconfig(usb_ss);
+ for (i = 0; i < usb_ss->ep_nums; i++)
+ usb_ss->eps[i]->endpoint.enabled = 0;
+ usb_gadget_set_state(&usb_ss->gadget,
+ USB_STATE_ADDRESS);
+ }
+ break;
+ default:
+ result = -EINVAL;
+ }
+
+ return result;
+}
+
+/**
+ * cdns_ep0_standard_request - Handling standard USB requests
+ * @usb_ss: extended gadget object
+ * @ctrl_req: pointer to received setup packet
+ *
+ * Returns 0 if success, error code on error
+ */
+static int cdns_ep0_standard_request(struct usb_ss_dev *usb_ss,
+ struct usb_ctrlrequest *ctrl_req)
+{
+ switch (ctrl_req->bRequest) {
+ case USB_REQ_SET_ADDRESS:
+ return cdns_req_ep0_set_address(usb_ss, ctrl_req);
+ case USB_REQ_SET_CONFIGURATION:
+ return cdns_req_ep0_set_configuration(usb_ss, ctrl_req);
+ case USB_REQ_GET_STATUS:
+ return cdns_req_ep0_get_status(usb_ss, ctrl_req);
+ case USB_REQ_CLEAR_FEATURE:
+ return cdns_req_ep0_handle_feature(usb_ss, ctrl_req, 0);
+ case USB_REQ_SET_FEATURE:
+ return cdns_req_ep0_handle_feature(usb_ss, ctrl_req, 1);
+ case USB_REQ_SET_SEL:
+ return cdns_req_ep0_set_sel(usb_ss, ctrl_req);
+ case USB_REQ_SET_ISOCH_DELAY:
+ return cdns_req_ep0_set_isoch_delay(usb_ss, ctrl_req);
+ default:
+ return cdns_get_setup_ret(usb_ss, ctrl_req);
+ }
+}
+
+/**
+ * cdns_ep0_setup_phase - Handling setup USB requests
+ * @usb_ss: extended gadget object
+ */
+static void cdns_ep0_setup_phase(struct usb_ss_dev *usb_ss)
+{
+ int result;
+ struct usb_ctrlrequest *ctrl_req =
+ (struct usb_ctrlrequest *)usb_ss->setup;
+
+ if ((ctrl_req->bRequestType & USB_TYPE_MASK) == USB_TYPE_STANDARD)
+ result = cdns_ep0_standard_request(usb_ss, ctrl_req);
+ else
+ result = cdns_get_setup_ret(usb_ss, ctrl_req);
+
+ if (result != 0 && result != USB_GADGET_DELAYED_STATUS) {
+ dev_dbg(&usb_ss->dev, "STALL(00) %d\n", result);
+ /* set_stall on ep0 */
+ select_ep(usb_ss, 0x00);
+ gadget_writel(usb_ss, &usb_ss->regs->ep_cmd,
+ EP_CMD__SSTALL__MASK);
+ gadget_writel(usb_ss, &usb_ss->regs->ep_cmd,
+ EP_CMD__ERDY__MASK | EP_CMD__REQ_CMPL__MASK);
+ }
+}
+
+/**
+ * cdns_check_ep_interrupt_proceed - Processes interrupt related to endpoint
+ * @usb_ss_ep: extended endpoint object
+ *
+ * Returns 0
+ */
+static int cdns_check_ep_interrupt_proceed(struct usb_ss_endpoint *usb_ss_ep)
+{
+ struct usb_ss_dev *usb_ss = usb_ss_ep->usb_ss;
+ struct usb_request *request;
+ u32 ep_sts_reg;
+
+ select_ep(usb_ss, usb_ss_ep->endpoint.address);
+ ep_sts_reg = gadget_readl(usb_ss, &usb_ss->regs->ep_sts);
+
+ dev_dbg(&usb_ss->dev, "EP_STS: %08X\n", ep_sts_reg);
+
+ if (ep_sts_reg & EP_STS__TRBERR__MASK) {
+ gadget_writel(usb_ss,
+ &usb_ss->regs->ep_sts, EP_STS__TRBERR__MASK);
+
+ dev_dbg(&usb_ss->dev, "TRBERR(%02X)\n",
+ usb_ss_ep->endpoint.desc->bEndpointAddress);
+ }
+
+ if (ep_sts_reg & EP_STS__ISOERR__MASK) {
+ gadget_writel(usb_ss,
+ &usb_ss->regs->ep_sts, EP_STS__ISOERR__MASK);
+ dev_dbg(&usb_ss->dev, "ISOERR(%02X)\n",
+ usb_ss_ep->endpoint.desc->bEndpointAddress);
+ }
+
+ if (ep_sts_reg & EP_STS__OUTSMM__MASK) {
+ gadget_writel(usb_ss, &usb_ss->regs->ep_sts,
+ EP_STS__OUTSMM__MASK);
+ dev_dbg(&usb_ss->dev, "OUTSMM(%02X)\n",
+ usb_ss_ep->endpoint.desc->bEndpointAddress);
+ }
+
+ if (ep_sts_reg & EP_STS__NRDY__MASK) {
+ gadget_writel(usb_ss,
+ &usb_ss->regs->ep_sts, EP_STS__NRDY__MASK);
+ dev_dbg(&usb_ss->dev, "NRDY(%02X)\n",
+ usb_ss_ep->endpoint.desc->bEndpointAddress);
+ }
+
+ if ((ep_sts_reg & EP_STS__IOC__MASK)
+ || (ep_sts_reg & EP_STS__ISP__MASK)) {
+ gadget_writel(usb_ss, &usb_ss->regs->ep_sts,
+ EP_STS__IOC__MASK | EP_STS__ISP__MASK);
+
+ /* get just completed request */
+ request = next_request(&usb_ss_ep->request_list);
+ if (!request)
+ return 0;
+
+ if ((request->dma % ADDR_MODULO_8) &&
+ (usb_ss_ep->dir == USB_DIR_OUT))
+ memcpy(request->buf, usb_ss_ep->cpu_addr,
+ request->length);
+
+ usb_gadget_unmap_request_by_dev(usb_ss->sysdev, request,
+ usb_ss_ep->endpoint.desc->bEndpointAddress
+ & ENDPOINT_DIR_MASK);
+
+ request->status = 0;
+ request->actual =
+ le32_to_cpu(((u32 *) usb_ss_ep->trb_pool)[1])
+ & ACTUAL_TRANSFERRED_BYTES_MASK;
+
+ dev_dbg(&usb_ss->dev, "IOC(%02X) %d\n",
+ usb_ss_ep->endpoint.desc->bEndpointAddress,
+ request->actual);
+
+ list_del(&request->list);
+
+ usb_ss_ep->hw_pending_flag = 0;
+ if (request->complete) {
+ spin_unlock(&usb_ss->lock);
+ usb_gadget_giveback_request(&usb_ss_ep->endpoint,
+ request);
+ spin_lock(&usb_ss->lock);
+ }
+
+ if (request->buf == usb_ss->zlp_buf)
+ kfree(request);
+
+ /* handle deferred STALL */
+ if (usb_ss_ep->stalled_flag) {
+ cdns_ep_stall_flush(usb_ss_ep);
+ return 0;
+ }
+
+ /* exit if hardware transfer already started */
+ if (usb_ss_ep->hw_pending_flag)
+ return 0;
+
+ /* if any request queued run it! */
+ if (!list_empty(&usb_ss_ep->request_list))
+ cdns_ep_run_transfer(usb_ss_ep);
+ }
+
+ if (ep_sts_reg & EP_STS__DESCMIS__MASK) {
+ gadget_writel(usb_ss,
+ &usb_ss->regs->ep_sts, EP_STS__DESCMIS__MASK);
+ dev_dbg(&usb_ss->dev, "DESCMIS(%02X)\n",
+ usb_ss_ep->endpoint.desc->bEndpointAddress);
+ }
+
+ return 0;
+}
+
+/**
+ * cdns_check_ep0_interrupt_proceed - Processes interrupt related to endpoint 0
+ * @usb_ss: extended gadget object
+ * @dir: 1 for IN direction, 0 for OUT direction
+ */
+static void cdns_check_ep0_interrupt_proceed(struct usb_ss_dev *usb_ss, int dir)
+{
+ u32 ep_sts_reg;
+ int i;
+
+ select_ep(usb_ss, 0 | (dir ? USB_DIR_IN : USB_DIR_OUT));
+ ep_sts_reg = gadget_readl(usb_ss, &usb_ss->regs->ep_sts);
+
+ dev_dbg(&usb_ss->dev, "EP_STS: %08X\n", ep_sts_reg);
+
+ __pending_setup_status_handler(usb_ss);
+
+ if ((ep_sts_reg & EP_STS__SETUP__MASK) && (dir == 0)) {
+ dev_dbg(&usb_ss->dev, "SETUP(%02X)\n", 0x00);
+
+ gadget_writel(usb_ss, &usb_ss->regs->ep_sts,
+ EP_STS__SETUP__MASK |
+ EP_STS__IOC__MASK | EP_STS__ISP__MASK);
+
+ dev_dbg(&usb_ss->dev, "SETUP: ");
+ for (i = 0; i < 8; i++)
+ dev_dbg(&usb_ss->dev, "%02X ", usb_ss->setup[i]);
+ dev_dbg(&usb_ss->dev, "\nSTATE: %d\n", usb_ss->gadget.state);
+ usb_ss->ep0_data_dir = usb_ss->setup[0] & USB_DIR_IN;
+ cdns_ep0_setup_phase(usb_ss);
+ ep_sts_reg &= ~(EP_STS__SETUP__MASK |
+ EP_STS__IOC__MASK |
+ EP_STS__ISP__MASK);
+ }
+
+ if (ep_sts_reg & EP_STS__TRBERR__MASK) {
+ gadget_writel(usb_ss,
+ &usb_ss->regs->ep_sts, EP_STS__TRBERR__MASK);
+ dev_dbg(&usb_ss->dev, "TRBERR(%02X)\n",
+ dir ? USB_DIR_IN : USB_DIR_OUT);
+ }
+
+ if (ep_sts_reg & EP_STS__DESCMIS__MASK) {
+ gadget_writel(usb_ss,
+ &usb_ss->regs->ep_sts, EP_STS__DESCMIS__MASK);
+
+ dev_dbg(&usb_ss->dev, "DESCMIS(%02X)\n",
+ dir ? USB_DIR_IN : USB_DIR_OUT);
+
+ if (dir == 0 && !usb_ss->setup_pending) {
+ usb_ss->ep0_data_dir = 0;
+ cdns_ep0_run_transfer(usb_ss,
+ usb_ss->setup_dma, 8, 0);
+ }
+ }
+
+ if ((ep_sts_reg & EP_STS__IOC__MASK)
+ || (ep_sts_reg & EP_STS__ISP__MASK)) {
+ gadget_writel(usb_ss,
+ &usb_ss->regs->ep_sts, EP_STS__IOC__MASK);
+ if (usb_ss->actual_ep0_request) {
+ usb_gadget_unmap_request_by_dev(usb_ss->sysdev,
+ usb_ss->actual_ep0_request,
+ usb_ss->ep0_data_dir);
+
+ usb_ss->actual_ep0_request->actual =
+ le32_to_cpu((usb_ss->trb_ep0)[1])
+ & ACTUAL_TRANSFERRED_BYTES_MASK;
+
+ dev_dbg(&usb_ss->dev, "IOC(%02X) %d\n",
+ dir ? USB_DIR_IN : USB_DIR_OUT,
+ usb_ss->actual_ep0_request->actual);
+ list_del_init(&usb_ss->actual_ep0_request->list);
+ }
+
+ if (usb_ss->actual_ep0_request
+ && usb_ss->actual_ep0_request->complete) {
+ spin_unlock(&usb_ss->lock);
+ usb_ss->actual_ep0_request->complete(usb_ss->gadget.ep0,
+ usb_ss->actual_ep0_request);
+ spin_lock(&usb_ss->lock);
+ }
+ cdns_prepare_setup_packet(usb_ss);
+ gadget_writel(usb_ss,
+ &usb_ss->regs->ep_cmd, EP_CMD__REQ_CMPL__MASK);
+ }
+}
+
+/**
+ * cdns_check_usb_interrupt_proceed - Processes interrupt related to device
+ * @usb_ss: extended gadget object
+ * @usb_ists: bitmap representation of device's reported interrupts
+ * (usb_ists register value)
+ */
+static void cdns_check_usb_interrupt_proceed(struct usb_ss_dev *usb_ss,
+ u32 usb_ists)
+{
+ int interrupt_bit = ffs(usb_ists) - 1;
+ int speed;
+ u32 val;
+
+ dev_dbg(&usb_ss->dev, "USB interrupt detected\n");
+
+ switch (interrupt_bit) {
+ case USB_ISTS__CON2I__SHIFT:
+ /* FS/HS Connection detected */
+ dev_dbg(&usb_ss->dev,
+ "[Interrupt] FS/HS Connection detected\n");
+ val = gadget_readl(usb_ss, &usb_ss->regs->usb_sts);
+ speed = USB_STS__USBSPEED__READ(val);
+ if (speed == USB_SPEED_WIRELESS)
+ speed = USB_SPEED_SUPER;
+ dev_dbg(&usb_ss->dev, "Speed value: %s (%d), usbsts:0x%x\n",
+ usb_speed_string(speed), speed, val);
+ usb_ss->gadget.speed = speed;
+ usb_ss->is_connected = 1;
+ usb_gadget_set_state(&usb_ss->gadget, USB_STATE_POWERED);
+ cdns_ep0_config(usb_ss);
+ break;
+ case USB_ISTS__CONI__SHIFT:
+ /* SS Connection detected */
+ dev_dbg(&usb_ss->dev, "[Interrupt] SS Connection detected\n");
+ val = gadget_readl(usb_ss, &usb_ss->regs->usb_sts);
+ speed = USB_STS__USBSPEED__READ(val);
+ if (speed == USB_SPEED_WIRELESS)
+ speed = USB_SPEED_SUPER;
+ dev_dbg(&usb_ss->dev, "Speed value: %s (%d), usbsts:0x%x\n",
+ usb_speed_string(speed), speed, val);
+ usb_ss->gadget.speed = speed;
+ usb_ss->is_connected = 1;
+ usb_gadget_set_state(&usb_ss->gadget, USB_STATE_POWERED);
+ cdns_ep0_config(usb_ss);
+ break;
+ case USB_ISTS__DIS2I__SHIFT:
+ case USB_ISTS__DISI__SHIFT:
+ /* SS Disconnection detected */
+ val = gadget_readl(usb_ss, &usb_ss->regs->usb_sts);
+ dev_dbg(&usb_ss->dev,
+ "[Interrupt] Disconnection detected: usbsts:0x%x\n",
+ val);
+ if (usb_ss->gadget_driver
+ && usb_ss->gadget_driver->disconnect) {
+
+ spin_unlock(&usb_ss->lock);
+ usb_ss->gadget_driver->disconnect(&usb_ss->gadget);
+ spin_lock(&usb_ss->lock);
+ }
+ usb_ss->gadget.speed = USB_SPEED_UNKNOWN;
+ usb_gadget_set_state(&usb_ss->gadget, USB_STATE_NOTATTACHED);
+ usb_ss->is_connected = 0;
+ cdns_gadget_unconfig(usb_ss);
+ break;
+ case USB_ISTS__L2ENTI__SHIFT:
+ dev_dbg(&usb_ss->dev,
+ "[Interrupt] Device suspended\n");
+ break;
+ case USB_ISTS__L2EXTI__SHIFT:
+ dev_dbg(&usb_ss->dev, "[Interrupt] L2 exit detected\n");
+ /*
+ * Exit from standby mode
+ * on L2 exit (Suspend in HS/FS or SS)
+ */
+ break;
+ case USB_ISTS__U3EXTI__SHIFT:
+ /*
+ * Exit from standby mode
+ * on U3 exit (Suspend in HS/FS or SS)
+ */
+ dev_dbg(&usb_ss->dev, "[Interrupt] U3 exit detected\n");
+ break;
+
+ /* resets cases */
+ case USB_ISTS__UWRESI__SHIFT:
+ case USB_ISTS__UHRESI__SHIFT:
+ case USB_ISTS__U2RESI__SHIFT:
+ dev_dbg(&usb_ss->dev, "[Interrupt] Reset detected\n");
+ speed = USB_STS__USBSPEED__READ(
+ gadget_readl(usb_ss, &usb_ss->regs->usb_sts));
+ if (speed == USB_SPEED_WIRELESS)
+ speed = USB_SPEED_SUPER;
+ usb_gadget_set_state(&usb_ss->gadget, USB_STATE_DEFAULT);
+ usb_ss->gadget.speed = speed;
+ cdns_gadget_unconfig(usb_ss);
+ cdns_ep0_config(usb_ss);
+ break;
+ default:
+ break;
+ }
+
+ /* Clear interrupt bit */
+ gadget_writel(usb_ss, &usb_ss->regs->usb_ists, (1uL << interrupt_bit));
+}
+
+/**
+ * cdns_irq_handler - irq line interrupt handler
+ * @cdns: cdns3 instance
+ *
+ * Returns IRQ_HANDLED when interrupt raised by USBSS_DEV,
+ * IRQ_NONE when interrupt raised by other device connected
+ * to the irq line
+ */
+static irqreturn_t cdns_irq_handler_thread(struct cdns3 *cdns)
+{
+ struct usb_ss_dev *usb_ss =
+ container_of(cdns->gadget_dev, struct usb_ss_dev, dev);
+ u32 reg;
+ enum irqreturn ret = IRQ_NONE;
+ unsigned long flags;
+
+ spin_lock_irqsave(&usb_ss->lock, flags);
+
+ /* check USB device interrupt */
+ reg = gadget_readl(usb_ss, &usb_ss->regs->usb_ists);
+ if (reg) {
+ dev_dbg(&usb_ss->dev, "usb_ists: %08X\n", reg);
+ cdns_check_usb_interrupt_proceed(usb_ss, reg);
+ ret = IRQ_HANDLED;
+ }
+
+ /* check endpoint interrupt */
+ reg = gadget_readl(usb_ss, &usb_ss->regs->ep_ists);
+ if (reg != 0) {
+ dev_dbg(&usb_ss->dev, "ep_ists: %08X\n", reg);
+ } else {
+ if (gadget_readl(usb_ss, &usb_ss->regs->usb_sts) &
+ USB_STS__CFGSTS__MASK)
+ ret = IRQ_HANDLED;
+ goto irqend;
+ }
+
+ /* handle default endpoint OUT */
+ if (reg & EP_ISTS__EOUT0__MASK) {
+ cdns_check_ep0_interrupt_proceed(usb_ss, 0);
+ ret = IRQ_HANDLED;
+ }
+
+ /* handle default endpoint IN */
+ if (reg & EP_ISTS__EIN0__MASK) {
+ cdns_check_ep0_interrupt_proceed(usb_ss, 1);
+ ret = IRQ_HANDLED;
+ }
+
+ /* check if interrupt from non default endpoint, if no exit */
+ reg &= ~(EP_ISTS__EOUT0__MASK | EP_ISTS__EIN0__MASK);
+ if (!reg)
+ goto irqend;
+
+ do {
+ unsigned int bit_pos = ffs(reg);
+ u32 bit_mask = 1 << (bit_pos - 1);
+
+ dev_dbg(&usb_ss->dev, "Interrupt on index: %d bitmask %08X\n",
+ CAST_EP_REG_POS_TO_INDEX(bit_pos), bit_mask);
+ cdns_check_ep_interrupt_proceed(
+ usb_ss->eps[CAST_EP_REG_POS_TO_INDEX(bit_pos)]);
+ reg &= ~bit_mask;
+ ret = IRQ_HANDLED;
+ } while (reg);
+
+irqend:
+ spin_unlock_irqrestore(&usb_ss->lock, flags);
+ return ret;
+}
+
+/**
+ * usb_ss_gadget_ep0_enable
+ * Function shouldn't be called by gadget driver,
+ * endpoint 0 is allways active
+ */
+static int usb_ss_gadget_ep0_enable(struct usb_ep *ep,
+ const struct usb_endpoint_descriptor *desc)
+{
+ return -EINVAL;
+}
+
+/**
+ * usb_ss_gadget_ep0_disable
+ * Function shouldn't be called by gadget driver,
+ * endpoint 0 is allways active
+ */
+static int usb_ss_gadget_ep0_disable(struct usb_ep *ep)
+{
+ return -EINVAL;
+}
+
+/**
+ * usb_ss_gadget_ep0_set_halt
+ * @ep: pointer to endpoint zero object
+ * @value: 1 for set stall, 0 for clear stall
+ *
+ * Returns 0
+ */
+static int usb_ss_gadget_ep0_set_halt(struct usb_ep *ep, int value)
+{
+ /* TODO */
+ return 0;
+}
+
+static void __pending_setup_status_handler(struct usb_ss_dev *usb_ss)
+{
+ struct usb_request *request = usb_ss->pending_status_request;
+
+ if (usb_ss->status_completion_no_call && request && request->complete) {
+ request->complete(usb_ss->gadget.ep0, request);
+ usb_ss->status_completion_no_call = 0;
+ }
+}
+
+static void pending_setup_status_handler(struct work_struct *work)
+{
+ struct usb_ss_dev *usb_ss = container_of(work, struct usb_ss_dev,
+ pending_status_wq);
+ unsigned long flags;
+
+ spin_lock_irqsave(&usb_ss->lock, flags);
+ __pending_setup_status_handler(usb_ss);
+ spin_unlock_irqrestore(&usb_ss->lock, flags);
+}
+
+/**
+ * usb_ss_gadget_ep0_queue Transfer data on endpoint zero
+ * @ep: pointer to endpoint zero object
+ * @request: pointer to request object
+ * @gfp_flags: gfp flags
+ *
+ * Returns 0 on success, error code elsewhere
+ */
+static int usb_ss_gadget_ep0_queue(struct usb_ep *ep,
+ struct usb_request *request, gfp_t gfp_flags)
+{
+ int ret = 0;
+ unsigned long flags;
+ int erdy_sent = 0;
+ /* get extended endpoint */
+ struct usb_ss_endpoint *usb_ss_ep =
+ to_usb_ss_ep(ep);
+ struct usb_ss_dev *usb_ss = usb_ss_ep->usb_ss;
+
+ dev_dbg(&usb_ss->dev, "QUEUE(%02X) %d\n",
+ usb_ss->ep0_data_dir ? USB_DIR_IN : USB_DIR_OUT,
+ request->length);
+
+ /* send STATUS stage */
+ if (request->length == 0 && request->zero == 0) {
+ spin_lock_irqsave(&usb_ss->lock, flags);
+ select_ep(usb_ss, 0x00);
+ if (!usb_ss->hw_configured_flag) {
+ gadget_writel(usb_ss, &usb_ss->regs->usb_conf,
+ USB_CONF__CFGSET__MASK); /* SET CONFIGURATION */
+ gadget_writel(usb_ss, &usb_ss->regs->ep_cmd,
+ EP_CMD__ERDY__MASK | EP_CMD__REQ_CMPL__MASK);
+ /* wait until configuration set */
+ ret = wait_reg_bit_set(usb_ss, &usb_ss->regs->usb_sts,
+ USB_STS__CFGSTS__MASK, 100);
+ erdy_sent = 1;
+ usb_ss->hw_configured_flag = 1;
+ cdns_enable_l1(usb_ss, 1);
+ /* Enable U1/U2 at Configuration state */
+ if (usb_ss->gadget.speed == USB_SPEED_SUPER) {
+ cdns_enable_u1(usb_ss, 1);
+ cdns_enable_u2(usb_ss, 1);
+ }
+
+ list_for_each_entry(ep,
+ &usb_ss->gadget.ep_list,
+ ep_list) {
+
+ if (ep->enabled)
+ cdns_ep_run_transfer(
+ to_usb_ss_ep(ep));
+ }
+ }
+ if (!erdy_sent)
+ gadget_writel(usb_ss, &usb_ss->regs->ep_cmd,
+ EP_CMD__ERDY__MASK | EP_CMD__REQ_CMPL__MASK);
+
+ cdns_prepare_setup_packet(usb_ss);
+ request->actual = 0;
+ usb_ss->status_completion_no_call = true;
+ usb_ss->pending_status_request = request;
+ spin_unlock_irqrestore(&usb_ss->lock, flags);
+ /*
+ * Since there is no completion interrupt for status stage,
+ * it needs to call ->completion in software after
+ * ep0_queue is back.
+ */
+ queue_work(system_freezable_wq, &usb_ss->pending_status_wq);
+ return 0;
+ }
+
+ spin_lock_irqsave(&usb_ss->lock, flags);
+ if (!list_empty(&usb_ss_ep->request_list)) {
+ dev_err(&usb_ss->dev,
+ "can't handle multiple requests for ep0\n");
+ spin_unlock_irqrestore(&usb_ss->lock, flags);
+ return -EOPNOTSUPP;
+ }
+
+ ret = usb_gadget_map_request_by_dev(usb_ss->sysdev, request,
+ usb_ss->ep0_data_dir);
+ if (ret) {
+ spin_unlock_irqrestore(&usb_ss->lock, flags);
+ dev_err(&usb_ss->dev, "failed to map request\n");
+ return -EINVAL;
+ }
+
+ usb_ss->actual_ep0_request = request;
+ cdns_ep0_run_transfer(usb_ss, request->dma, request->length, 1);
+ list_add_tail(&request->list, &usb_ss_ep->request_list);
+ spin_unlock_irqrestore(&usb_ss->lock, flags);
+ return ret;
+}
+/**
+ * ep_onchip_buffer_alloc - Try to allocate onchip buf for EP
+ *
+ * The real allocation will occur during write to EP_CFG register,
+ * this function is used to check if the 'size' allocation is allowed.
+ *
+ * @usb_ss: extended gadget object
+ * @size: the size (KB) for EP would like to allocate
+ * @is_in: the direction for EP
+ *
+ * Return 0 if the later allocation is allowed or negative value on failure
+ */
+
+static int ep_onchip_buffer_alloc(struct usb_ss_dev *usb_ss,
+ int size, int is_in)
+{
+ if (is_in) {
+ usb_ss->onchip_mem_allocated_size += size;
+ } else if (!usb_ss->out_mem_is_allocated) {
+ /* ALL OUT EPs are shared the same chunk onchip memory */
+ usb_ss->onchip_mem_allocated_size += size;
+ usb_ss->out_mem_is_allocated = 1;
+ }
+
+ if (usb_ss->onchip_mem_allocated_size > CDNS3_ONCHIP_BUF_SIZE) {
+ usb_ss->onchip_mem_allocated_size -= size;
+ return -EPERM;
+ } else {
+ return 0;
+ }
+}
+
+/**
+ * cdns_ep_config Configure hardware endpoint
+ * @usb_ss_ep: extended endpoint object
+ */
+static void cdns_ep_config(struct usb_ss_endpoint *usb_ss_ep)
+{
+ struct usb_ss_dev *usb_ss = usb_ss_ep->usb_ss;
+ u32 ep_cfg = 0;
+ u32 max_packet_size = 0;
+ u32 bEndpointAddress = usb_ss_ep->num | usb_ss_ep->dir;
+ u32 interrupt_mask = 0;
+ int is_in = !!usb_ss_ep->dir;
+ bool is_iso_ep = (usb_ss_ep->type == USB_ENDPOINT_XFER_ISOC);
+ int default_buf_size = CDNS3_EP_BUF_SIZE;
+
+ dev_dbg(&usb_ss->dev, "%s: %s addr=0x%x\n", __func__,
+ usb_ss_ep->name, bEndpointAddress);
+
+ if (is_iso_ep) {
+ ep_cfg = EP_CFG__EPTYPE__WRITE(USB_ENDPOINT_XFER_ISOC);
+ interrupt_mask = INTERRUPT_MASK;
+ } else {
+ ep_cfg = EP_CFG__EPTYPE__WRITE(USB_ENDPOINT_XFER_BULK);
+ }
+
+ switch (usb_ss->gadget.speed) {
+ case USB_SPEED_UNKNOWN:
+ max_packet_size = ENDPOINT_MAX_PACKET_SIZE_0;
+ break;
+ case USB_SPEED_LOW:
+ max_packet_size = ENDPOINT_MAX_PACKET_SIZE_8;
+ break;
+ case USB_SPEED_FULL:
+ max_packet_size = (is_iso_ep ?
+ ENDPOINT_MAX_PACKET_SIZE_1023 :
+ ENDPOINT_MAX_PACKET_SIZE_64);
+ break;
+ case USB_SPEED_HIGH:
+ max_packet_size = (is_iso_ep ?
+ ENDPOINT_MAX_PACKET_SIZE_1024 :
+ ENDPOINT_MAX_PACKET_SIZE_512);
+ break;
+ case USB_SPEED_WIRELESS:
+ max_packet_size = ENDPOINT_MAX_PACKET_SIZE_512;
+ break;
+ case USB_SPEED_SUPER:
+ max_packet_size = ENDPOINT_MAX_PACKET_SIZE_1024;
+ break;
+ case USB_SPEED_SUPER_PLUS:
+ dev_warn(&usb_ss->dev, "USB 3.1 is not supported\n");
+ max_packet_size = ENDPOINT_MAX_PACKET_SIZE_1024;
+ break;
+ }
+
+ if (ep_onchip_buffer_alloc(usb_ss, default_buf_size, is_in)) {
+ dev_err(&usb_ss->dev, "onchip mem is full, ep is invalid\n");
+ return;
+ }
+
+ ep_cfg |= EP_CFG__MAXPKTSIZE__WRITE(max_packet_size) |
+ EP_CFG__BUFFERING__WRITE(default_buf_size - 1) |
+ EP_CFG__MAXBURST__WRITE(usb_ss_ep->endpoint.maxburst);
+
+ select_ep(usb_ss, bEndpointAddress);
+ gadget_writel(usb_ss, &usb_ss->regs->ep_cfg, ep_cfg);
+ gadget_writel(usb_ss, &usb_ss->regs->ep_sts_en,
+ EP_STS_EN__TRBERREN__MASK | interrupt_mask);
+
+ /* enable interrupt for selected endpoint */
+ ep_cfg = gadget_readl(usb_ss, &usb_ss->regs->ep_ien);
+ ep_cfg |= CAST_EP_ADDR_TO_BIT_POS(bEndpointAddress);
+ gadget_writel(usb_ss, &usb_ss->regs->ep_ien, ep_cfg);
+}
+
+/**
+ * usb_ss_gadget_ep_enable Enable endpoint
+ * @ep: endpoint object
+ * @desc: endpoint descriptor
+ *
+ * Returns 0 on success, error code elsewhere
+ */
+static int usb_ss_gadget_ep_enable(struct usb_ep *ep,
+ const struct usb_endpoint_descriptor *desc)
+{
+ struct usb_ss_endpoint *usb_ss_ep;
+ struct usb_ss_dev *usb_ss;
+ unsigned long flags;
+ int ret;
+ u32 ep_cfg;
+
+ usb_ss_ep = to_usb_ss_ep(ep);
+ usb_ss = usb_ss_ep->usb_ss;
+
+ if (!ep || !desc || desc->bDescriptorType != USB_DT_ENDPOINT) {
+ dev_err(&usb_ss->dev, "usb-ss: invalid parameters\n");
+ return -EINVAL;
+ }
+
+ if (!desc->wMaxPacketSize) {
+ dev_err(&usb_ss->dev, "usb-ss: missing wMaxPacketSize\n");
+ return -EINVAL;
+ }
+
+ ret = usb_ss_allocate_trb_pool(usb_ss_ep);
+ if (ret)
+ return ret;
+
+ dev_dbg(&usb_ss->dev, "Enabling endpoint: %s, addr=0x%x\n",
+ ep->name, desc->bEndpointAddress);
+ spin_lock_irqsave(&usb_ss->lock, flags);
+ select_ep(usb_ss, desc->bEndpointAddress);
+ gadget_writel(usb_ss, &usb_ss->regs->ep_cmd,
+ EP_CMD__EPRST__MASK);
+ ret = wait_reg_bit_clear(usb_ss, &usb_ss->regs->ep_cmd,
+ EP_CMD__EPRST__MASK, 100);
+ ep_cfg = gadget_readl(usb_ss, &usb_ss->regs->ep_cfg);
+ ep_cfg |= EP_CFG__ENABLE__MASK;
+ gadget_writel(usb_ss, &usb_ss->regs->ep_cfg, ep_cfg);
+
+ ep->enabled = 1;
+ ep->desc = desc;
+ usb_ss_ep->hw_pending_flag = 0;
+ usb_ss_ep->stalled_flag = 0;
+ spin_unlock_irqrestore(&usb_ss->lock, flags);
+ return 0;
+}
+
+/* Find correct direction for HW endpoint according to description */
+static int ep_dir_is_correct(struct usb_endpoint_descriptor *desc,
+ struct usb_ss_endpoint *usb_ss_ep)
+{
+ return (usb_ss_ep->endpoint.caps.dir_in &&
+ !!(desc->bEndpointAddress & USB_DIR_IN))
+ || (usb_ss_ep->endpoint.caps.dir_out
+ && ((desc->bEndpointAddress & 0x80) == USB_DIR_OUT));
+}
+
+static struct usb_ss_endpoint *find_available_ss_ep(
+ struct usb_ss_dev *usb_ss,
+ struct usb_endpoint_descriptor *desc)
+{
+ struct usb_ep *ep;
+ struct usb_ss_endpoint *usb_ss_ep;
+
+ list_for_each_entry(ep, &usb_ss->gadget.ep_list, ep_list) {
+ unsigned long num;
+ int ret;
+ /* ep name pattern likes epXin or epXout */
+ char c[2] = {ep->name[2], '\0'};
+
+ ret = kstrtoul(c, 10, &num);
+ if (ret)
+ return ERR_PTR(ret);
+
+ usb_ss_ep = to_usb_ss_ep(ep);
+ if (ep_dir_is_correct(desc, usb_ss_ep)) {
+ if (!usb_ss_ep->used) {
+ usb_ss_ep->num = num;
+ usb_ss_ep->used = true;
+ return usb_ss_ep;
+ }
+ }
+ }
+ return ERR_PTR(-ENOENT);
+}
+
+static struct usb_ep *usb_ss_gadget_match_ep(struct usb_gadget *gadget,
+ struct usb_endpoint_descriptor *desc,
+ struct usb_ss_ep_comp_descriptor *comp_desc)
+{
+ struct usb_ss_dev *usb_ss = gadget_to_usb_ss(gadget);
+ struct usb_ss_endpoint *usb_ss_ep;
+ unsigned long flags;
+
+ usb_ss_ep = find_available_ss_ep(usb_ss, desc);
+ if (IS_ERR(usb_ss_ep)) {
+ dev_err(&usb_ss->dev, "no available ep\n");
+ return NULL;
+ }
+
+ dev_dbg(&usb_ss->dev, "match endpoint: %s\n", usb_ss_ep->name);
+ spin_lock_irqsave(&usb_ss->lock, flags);
+ usb_ss_ep->endpoint.desc = desc;
+ usb_ss_ep->dir = usb_endpoint_dir_in(desc) ? USB_DIR_IN : USB_DIR_OUT;
+ usb_ss_ep->type = usb_endpoint_type(desc);
+
+ list_add_tail(&usb_ss_ep->ep_match_pending_list,
+ &usb_ss->ep_match_list);
+ spin_unlock_irqrestore(&usb_ss->lock, flags);
+ return &usb_ss_ep->endpoint;
+}
+
+static void usb_ss_free_trb_pool(struct usb_ss_endpoint *usb_ss_ep)
+{
+ struct usb_ss_dev *usb_ss = usb_ss_ep->usb_ss;
+
+ if (usb_ss_ep->trb_pool) {
+ dma_free_coherent(usb_ss->sysdev,
+ sizeof(struct usb_ss_trb) * USB_SS_TRBS_NUM,
+ usb_ss_ep->trb_pool, usb_ss_ep->trb_pool_dma);
+ usb_ss_ep->trb_pool = NULL;
+ }
+
+ if (usb_ss_ep->cpu_addr) {
+ dma_free_coherent(usb_ss->sysdev, CDNS3_UNALIGNED_BUF_SIZE,
+ usb_ss_ep->cpu_addr, usb_ss_ep->dma_addr);
+ usb_ss_ep->cpu_addr = NULL;
+ }
+}
+
+/**
+ * usb_ss_gadget_ep_disable Disable endpoint
+ * @ep: endpoint object
+ *
+ * Returns 0 on success, error code elsewhere
+ */
+static int usb_ss_gadget_ep_disable(struct usb_ep *ep)
+{
+ struct usb_ss_endpoint *usb_ss_ep;
+ struct usb_ss_dev *usb_ss;
+ unsigned long flags;
+ int ret = 0;
+ struct usb_request *request;
+ u32 ep_cfg;
+
+ if (!ep) {
+ pr_debug("usb-ss: invalid parameters\n");
+ return -EINVAL;
+ }
+
+ usb_ss_ep = to_usb_ss_ep(ep);
+ usb_ss = usb_ss_ep->usb_ss;
+
+ spin_lock_irqsave(&usb_ss->lock, flags);
+ if (!usb_ss->start_gadget) {
+ dev_dbg(&usb_ss->dev,
+ "Disabling endpoint at disconnection: %s\n", ep->name);
+ spin_unlock_irqrestore(&usb_ss->lock, flags);
+ return 0;
+ }
+
+ dev_dbg(&usb_ss->dev,
+ "Disabling endpoint: %s\n", ep->name);
+
+ select_ep(usb_ss, ep->desc->bEndpointAddress);
+ ret = cdns_data_flush(usb_ss_ep);
+ while (!list_empty(&usb_ss_ep->request_list)) {
+
+ request = next_request(&usb_ss_ep->request_list);
+ usb_gadget_unmap_request_by_dev(usb_ss->sysdev, request,
+ ep->desc->bEndpointAddress & USB_DIR_IN);
+ request->status = -ESHUTDOWN;
+ list_del(&request->list);
+ spin_unlock(&usb_ss->lock);
+ usb_gadget_giveback_request(ep, request);
+ spin_lock(&usb_ss->lock);
+ }
+
+ ep_cfg = gadget_readl(usb_ss, &usb_ss->regs->ep_cfg);
+ ep_cfg &= ~EP_CFG__ENABLE__MASK;
+ gadget_writel(usb_ss, &usb_ss->regs->ep_cfg, ep_cfg);
+ ep->desc = NULL;
+ ep->enabled = 0;
+
+ spin_unlock_irqrestore(&usb_ss->lock, flags);
+
+ return ret;
+}
+
+/**
+ * usb_ss_gadget_ep_alloc_request Allocates request
+ * @ep: endpoint object associated with request
+ * @gfp_flags: gfp flags
+ *
+ * Returns allocated request address, NULL on allocation error
+ */
+static struct usb_request *usb_ss_gadget_ep_alloc_request(struct usb_ep *ep,
+ gfp_t gfp_flags)
+{
+ struct usb_request *request;
+
+ request = kzalloc(sizeof(struct usb_request), gfp_flags);
+ if (!request)
+ return NULL;
+
+ return request;
+}
+
+/**
+ * usb_ss_gadget_ep_free_request Free memory occupied by request
+ * @ep: endpoint object associated with request
+ * @request: request to free memory
+ */
+static void usb_ss_gadget_ep_free_request(struct usb_ep *ep,
+ struct usb_request *request)
+{
+ kfree(request);
+ request = NULL;
+}
+
+/**
+ * usb_ss_gadget_ep_queue Transfer data on endpoint
+ * @ep: endpoint object
+ * @request: request object
+ * @gfp_flags: gfp flags
+ *
+ * Returns 0 on success, error code elsewhere
+ */
+static int __usb_ss_gadget_ep_queue(struct usb_ep *ep,
+ struct usb_request *request, gfp_t gfp_flags)
+{
+ struct usb_ss_endpoint *usb_ss_ep =
+ to_usb_ss_ep(ep);
+ struct usb_ss_dev *usb_ss = usb_ss_ep->usb_ss;
+ int ret = 0;
+ int empty_list = 0;
+
+ request->actual = 0;
+ request->status = -EINPROGRESS;
+
+ dev_dbg(&usb_ss->dev,
+ "Queuing endpoint: %s\n", usb_ss_ep->name);
+
+ dev_dbg(&usb_ss->dev, "QUEUE(%02X) %d\n",
+ ep->desc->bEndpointAddress, request->length);
+
+ ret = usb_gadget_map_request_by_dev(usb_ss->sysdev, request,
+ ep->desc->bEndpointAddress & USB_DIR_IN);
+
+ if (ret)
+ return ret;
+
+ empty_list = list_empty(&usb_ss_ep->request_list);
+ list_add_tail(&request->list, &usb_ss_ep->request_list);
+
+ if (!usb_ss->hw_configured_flag)
+ return 0;
+
+ if (empty_list) {
+ if (!usb_ss_ep->stalled_flag)
+ ret = cdns_ep_run_transfer(usb_ss_ep);
+ }
+
+ return ret;
+}
+
+static int usb_ss_gadget_ep_queue(struct usb_ep *ep,
+ struct usb_request *request, gfp_t gfp_flags)
+{
+ struct usb_ss_endpoint *usb_ss_ep = to_usb_ss_ep(ep);
+ struct usb_ss_dev *usb_ss = usb_ss_ep->usb_ss;
+ struct usb_request *zlp_request;
+ unsigned long flags;
+ int ret;
+
+ spin_lock_irqsave(&usb_ss->lock, flags);
+
+ ret = __usb_ss_gadget_ep_queue(ep, request, gfp_flags);
+ if (ret == 0 && request->zero && request->length &&
+ (request->length % ep->maxpacket == 0)) {
+ zlp_request = usb_ss_gadget_ep_alloc_request(ep, GFP_ATOMIC);
+ zlp_request->length = 0;
+ zlp_request->buf = usb_ss->zlp_buf;
+
+ dev_dbg(&usb_ss->dev, "Queuing ZLP for endpoint: %s\n",
+ usb_ss_ep->name);
+ ret = __usb_ss_gadget_ep_queue(ep, zlp_request, gfp_flags);
+ }
+
+ spin_unlock_irqrestore(&usb_ss->lock, flags);
+ return ret;
+}
+
+/**
+ * usb_ss_gadget_ep_dequeue Remove request from transfer queue
+ * @ep: endpoint object associated with request
+ * @request: request object
+ *
+ * Returns 0 on success, error code elsewhere
+ */
+static int usb_ss_gadget_ep_dequeue(struct usb_ep *ep,
+ struct usb_request *request)
+{
+ struct usb_ss_endpoint *usb_ss_ep =
+ to_usb_ss_ep(ep);
+ struct usb_ss_dev *usb_ss = usb_ss_ep->usb_ss;
+ unsigned long flags;
+ struct usb_request *req, *req_temp;
+ int ret = 0;
+
+ if (ep == NULL || request == NULL || ep->desc == NULL)
+ return -EINVAL;
+
+ spin_lock_irqsave(&usb_ss->lock, flags);
+ dev_dbg(&usb_ss->dev, "DEQUEUE(%02X) %d\n",
+ ep->address, request->length);
+
+ select_ep(usb_ss, ep->desc->bEndpointAddress);
+ if (usb_ss->start_gadget)
+ ret = cdns_data_flush(usb_ss_ep);
+
+ list_for_each_entry_safe(req, req_temp,
+ &usb_ss_ep->request_list, list) {
+ if (request == req) {
+ request->status = -ECONNRESET;
+ usb_gadget_unmap_request_by_dev(usb_ss->sysdev, request,
+ ep->address & USB_DIR_IN);
+ list_del_init(&request->list);
+ if (request->complete) {
+ spin_unlock(&usb_ss->lock);
+ usb_gadget_giveback_request
+ (&usb_ss_ep->endpoint, request);
+ spin_lock(&usb_ss->lock);
+ }
+ break;
+ }
+ }
+
+ spin_unlock_irqrestore(&usb_ss->lock, flags);
+ if (&usb_ss_ep->endpoint == usb_ss->gadget.ep0)
+ flush_work(&usb_ss->pending_status_wq);
+
+ return ret;
+}
+
+/**
+ * usb_ss_gadget_ep_set_halt Sets/clears stall on selected endpoint
+ * @ep: endpoint object to set/clear stall on
+ * @value: 1 for set stall, 0 for clear stall
+ *
+ * Returns 0 on success, error code elsewhere
+ */
+static int usb_ss_gadget_ep_set_halt(struct usb_ep *ep, int value)
+{
+ struct usb_ss_endpoint *usb_ss_ep =
+ to_usb_ss_ep(ep);
+ struct usb_ss_dev *usb_ss = usb_ss_ep->usb_ss;
+ unsigned long flags;
+ int ret = 0;
+
+ /* return error when endpoint disabled */
+ if (!ep->enabled)
+ return -EPERM;
+
+ /* if actual transfer is pending defer setting stall on this endpoint */
+ if (usb_ss_ep->hw_pending_flag && value) {
+ usb_ss_ep->stalled_flag = 1;
+ return 0;
+ }
+
+ dev_dbg(&usb_ss->dev, "HALT(%02X) %d\n", ep->address, value);
+
+ spin_lock_irqsave(&usb_ss->lock, flags);
+
+ select_ep(usb_ss, ep->desc->bEndpointAddress);
+ if (value) {
+ cdns_ep_stall_flush(usb_ss_ep);
+ } else {
+ /*
+ * TODO:
+ * epp->wedgeFlag = 0;
+ */
+ usb_ss_ep->wedge_flag = 0;
+ gadget_writel(usb_ss, &usb_ss->regs->ep_cmd,
+ EP_CMD__CSTALL__MASK | EP_CMD__EPRST__MASK);
+ /* wait for EPRST cleared */
+ ret = wait_reg_bit_clear(usb_ss, &usb_ss->regs->ep_cmd,
+ EP_CMD__EPRST__MASK, 100);
+ usb_ss_ep->stalled_flag = 0;
+ }
+ usb_ss_ep->hw_pending_flag = 0;
+ spin_unlock_irqrestore(&usb_ss->lock, flags);
+
+ return ret;
+}
+
+/**
+ * usb_ss_gadget_ep_set_wedge Set wedge on selected endpoint
+ * @ep: endpoint object
+ *
+ * Returns 0
+ */
+static int usb_ss_gadget_ep_set_wedge(struct usb_ep *ep)
+{
+ struct usb_ss_endpoint *usb_ss_ep = to_usb_ss_ep(ep);
+ struct usb_ss_dev *usb_ss = usb_ss_ep->usb_ss;
+
+ dev_dbg(&usb_ss->dev, "WEDGE(%02X)\n", ep->address);
+ usb_ss_gadget_ep_set_halt(ep, 1);
+ usb_ss_ep->wedge_flag = 1;
+ return 0;
+}
+
+static const struct usb_ep_ops usb_ss_gadget_ep0_ops = {
+ .enable = usb_ss_gadget_ep0_enable,
+ .disable = usb_ss_gadget_ep0_disable,
+ .alloc_request = usb_ss_gadget_ep_alloc_request,
+ .free_request = usb_ss_gadget_ep_free_request,
+ .queue = usb_ss_gadget_ep0_queue,
+ .dequeue = usb_ss_gadget_ep_dequeue,
+ .set_halt = usb_ss_gadget_ep0_set_halt,
+ .set_wedge = usb_ss_gadget_ep_set_wedge,
+};
+
+static const struct usb_ep_ops usb_ss_gadget_ep_ops = {
+ .enable = usb_ss_gadget_ep_enable,
+ .disable = usb_ss_gadget_ep_disable,
+ .alloc_request = usb_ss_gadget_ep_alloc_request,
+ .free_request = usb_ss_gadget_ep_free_request,
+ .queue = usb_ss_gadget_ep_queue,
+ .dequeue = usb_ss_gadget_ep_dequeue,
+ .set_halt = usb_ss_gadget_ep_set_halt,
+ .set_wedge = usb_ss_gadget_ep_set_wedge,
+};
+
+/**
+ * usb_ss_gadget_get_frame Returns number of actual ITP frame
+ * @gadget: gadget object
+ *
+ * Returns number of actual ITP frame
+ */
+static int usb_ss_gadget_get_frame(struct usb_gadget *gadget)
+{
+ struct usb_ss_dev *usb_ss = gadget_to_usb_ss(gadget);
+
+ dev_dbg(&usb_ss->dev, "usb_ss_gadget_get_frame\n");
+ return gadget_readl(usb_ss, &usb_ss->regs->usb_iptn);
+}
+
+static int usb_ss_gadget_wakeup(struct usb_gadget *gadget)
+{
+ struct usb_ss_dev *usb_ss = gadget_to_usb_ss(gadget);
+
+ dev_dbg(&usb_ss->dev, "usb_ss_gadget_wakeup\n");
+ return 0;
+}
+
+static int usb_ss_gadget_set_selfpowered(struct usb_gadget *gadget,
+ int is_selfpowered)
+{
+ struct usb_ss_dev *usb_ss = gadget_to_usb_ss(gadget);
+ unsigned long flags;
+
+ dev_dbg(&usb_ss->dev, "usb_ss_gadget_set_selfpowered: %d\n",
+ is_selfpowered);
+
+ spin_lock_irqsave(&usb_ss->lock, flags);
+ gadget->is_selfpowered = !!is_selfpowered;
+ spin_unlock_irqrestore(&usb_ss->lock, flags);
+ return 0;
+}
+
+static int usb_ss_gadget_pullup(struct usb_gadget *gadget, int is_on)
+{
+ struct usb_ss_dev *usb_ss = gadget_to_usb_ss(gadget);
+
+ if (!usb_ss->start_gadget)
+ return 0;
+
+ dev_dbg(&usb_ss->dev, "usb_ss_gadget_pullup: %d\n", is_on);
+
+ if (is_on)
+ gadget_writel(usb_ss, &usb_ss->regs->usb_conf,
+ USB_CONF__DEVEN__MASK);
+ else
+ gadget_writel(usb_ss, &usb_ss->regs->usb_conf,
+ USB_CONF__DEVDS__MASK);
+
+ return 0;
+}
+
+/**
+ * usb_ss_gadget_udc_start Gadget start
+ * @gadget: gadget object
+ * @driver: driver which operates on this gadget
+ *
+ * Returns 0 on success, error code elsewhere
+ */
+static int usb_ss_gadget_udc_start(struct usb_gadget *gadget,
+ struct usb_gadget_driver *driver)
+{
+ struct usb_ss_dev *usb_ss = gadget_to_usb_ss(gadget);
+ unsigned long flags;
+
+ if (usb_ss->gadget_driver) {
+ dev_err(&usb_ss->dev, "%s is already bound to %s\n",
+ usb_ss->gadget.name,
+ usb_ss->gadget_driver->driver.name);
+ return -EBUSY;
+ }
+
+ dev_dbg(&usb_ss->dev, "%s begins\n", __func__);
+
+ spin_lock_irqsave(&usb_ss->lock, flags);
+ usb_ss->gadget_driver = driver;
+ if (!usb_ss->start_gadget) {
+ spin_unlock_irqrestore(&usb_ss->lock, flags);
+ return 0;
+ }
+
+ __cdns3_gadget_start(usb_ss);
+ spin_unlock_irqrestore(&usb_ss->lock, flags);
+ dev_dbg(&usb_ss->dev, "%s ends\n", __func__);
+ return 0;
+}
+
+/**
+ * usb_ss_gadget_udc_stop Stops gadget
+ * @gadget: gadget object
+ *
+ * Returns 0
+ */
+static int usb_ss_gadget_udc_stop(struct usb_gadget *gadget)
+{
+ struct usb_ss_dev *usb_ss = gadget_to_usb_ss(gadget);
+ struct usb_ep *ep;
+ struct usb_ss_endpoint *usb_ss_ep, *temp_ss_ep;
+ int i;
+ u32 bEndpointAddress;
+ int ret = 0;
+
+ usb_ss->gadget_driver = NULL;
+ usb_ss->status_completion_no_call = 0;
+ list_for_each_entry_safe(usb_ss_ep, temp_ss_ep,
+ &usb_ss->ep_match_list, ep_match_pending_list) {
+ list_del(&usb_ss_ep->ep_match_pending_list);
+ usb_ss_ep->used = false;
+ }
+
+ usb_ss->onchip_mem_allocated_size = 0;
+ usb_ss->out_mem_is_allocated = 0;
+ usb_ss->gadget.speed = USB_SPEED_UNKNOWN;
+ for (i = 0; i < usb_ss->ep_nums ; i++)
+ usb_ss_free_trb_pool(usb_ss->eps[i]);
+
+ if (!usb_ss->start_gadget)
+ return 0;
+
+ list_for_each_entry(ep, &usb_ss->gadget.ep_list, ep_list) {
+ usb_ss_ep = to_usb_ss_ep(ep);
+ bEndpointAddress = usb_ss_ep->num | usb_ss_ep->dir;
+ select_ep(usb_ss, bEndpointAddress);
+ gadget_writel(usb_ss, &usb_ss->regs->ep_cmd,
+ EP_CMD__EPRST__MASK);
+ ret = wait_reg_bit_clear(usb_ss, &usb_ss->regs->ep_cmd,
+ EP_CMD__EPRST__MASK, 100);
+ }
+
+ /* disable interrupt for device */
+ gadget_writel(usb_ss, &usb_ss->regs->usb_ien, 0);
+ gadget_writel(usb_ss, &usb_ss->regs->usb_conf, USB_CONF__DEVDS__MASK);
+
+ return ret;
+}
+
+static const struct usb_gadget_ops usb_ss_gadget_ops = {
+ .get_frame = usb_ss_gadget_get_frame,
+ .wakeup = usb_ss_gadget_wakeup,
+ .set_selfpowered = usb_ss_gadget_set_selfpowered,
+ .pullup = usb_ss_gadget_pullup,
+ .udc_start = usb_ss_gadget_udc_start,
+ .udc_stop = usb_ss_gadget_udc_stop,
+ .match_ep = usb_ss_gadget_match_ep,
+};
+
+/**
+ * usb_ss_init_ep Initializes software endpoints of gadget
+ * @usb_ss: extended gadget object
+ *
+ * Returns 0 on success, error code elsewhere
+ */
+static int usb_ss_init_ep(struct usb_ss_dev *usb_ss)
+{
+ struct usb_ss_endpoint *usb_ss_ep;
+ u32 ep_enabled_reg, iso_ep_reg, bulk_ep_reg;
+ int i;
+ int ep_reg_pos, ep_dir, ep_number;
+ int found_endpoints = 0;
+
+ /* Read it from USB_CAP3 to USB_CAP5 */
+ ep_enabled_reg = 0x00ff00ff;
+ iso_ep_reg = 0x00fe00fe;
+ bulk_ep_reg = 0x00fe00fe;
+
+ dev_dbg(&usb_ss->dev, "Initializing non-zero endpoints\n");
+
+ for (i = 0; i < USB_SS_ENDPOINTS_MAX_COUNT; i++) {
+ ep_number = (i / 2) + 1;
+ ep_dir = i % 2;
+ ep_reg_pos = (16 * ep_dir) + ep_number;
+
+ if (!(ep_enabled_reg & (1uL << ep_reg_pos)))
+ continue;
+
+ /* create empty endpoint object */
+ usb_ss_ep = devm_kzalloc(&usb_ss->dev, sizeof(*usb_ss_ep),
+ GFP_KERNEL);
+ if (!usb_ss_ep)
+ return -ENOMEM;
+
+ /* set parent of endpoint object */
+ usb_ss_ep->usb_ss = usb_ss;
+
+ /* set index of endpoint in endpoints container */
+ usb_ss->eps[found_endpoints++] = usb_ss_ep;
+
+ /* set name of endpoint */
+ snprintf(usb_ss_ep->name, sizeof(usb_ss_ep->name), "ep%d%s",
+ ep_number, !!ep_dir ? "in" : "out");
+ usb_ss_ep->endpoint.name = usb_ss_ep->name;
+ dev_dbg(&usb_ss->dev, "Initializing endpoint: %s\n",
+ usb_ss_ep->name);
+
+ usb_ep_set_maxpacket_limit(&usb_ss_ep->endpoint,
+ ENDPOINT_MAX_PACKET_LIMIT);
+ usb_ss_ep->endpoint.max_streams = ENDPOINT_MAX_STREAMS;
+ usb_ss_ep->endpoint.ops = &usb_ss_gadget_ep_ops;
+ if (ep_dir)
+ usb_ss_ep->endpoint.caps.dir_in = 1;
+ else
+ usb_ss_ep->endpoint.caps.dir_out = 1;
+
+ /* check endpoint type */
+ if (iso_ep_reg & (1uL << ep_reg_pos))
+ usb_ss_ep->endpoint.caps.type_iso = 1;
+
+ if (bulk_ep_reg & (1uL << ep_reg_pos)) {
+ usb_ss_ep->endpoint.caps.type_bulk = 1;
+ usb_ss_ep->endpoint.caps.type_int = 1;
+ usb_ss_ep->endpoint.maxburst = CDNS3_EP_BUF_SIZE - 1;
+ }
+
+ list_add_tail(&usb_ss_ep->endpoint.ep_list,
+ &usb_ss->gadget.ep_list);
+ INIT_LIST_HEAD(&usb_ss_ep->request_list);
+ INIT_LIST_HEAD(&usb_ss_ep->ep_match_pending_list);
+ }
+
+ usb_ss->ep_nums = found_endpoints;
+ return 0;
+}
+
+/**
+ * usb_ss_init_ep0 Initializes software endpoint 0 of gadget
+ * @usb_ss: extended gadget object
+ *
+ * Returns 0 on success, error code elsewhere
+ */
+static int usb_ss_init_ep0(struct usb_ss_dev *usb_ss)
+{
+ struct usb_ss_endpoint *ep0;
+
+ dev_dbg(&usb_ss->dev, "Initializing EP0\n");
+ ep0 = devm_kzalloc(&usb_ss->dev, sizeof(struct usb_ss_endpoint),
+ GFP_KERNEL);
+
+ if (!ep0)
+ return -ENOMEM;
+
+ /* fill CDNS fields */
+ ep0->usb_ss = usb_ss;
+ sprintf(ep0->name, "ep0");
+
+ /* fill linux fields */
+ ep0->endpoint.ops = &usb_ss_gadget_ep0_ops;
+ ep0->endpoint.maxburst = 1;
+ usb_ep_set_maxpacket_limit(&ep0->endpoint, ENDPOINT0_MAX_PACKET_LIMIT);
+ ep0->endpoint.address = 0;
+ ep0->endpoint.enabled = 1;
+ ep0->endpoint.caps.type_control = 1;
+ ep0->endpoint.caps.dir_in = 1;
+ ep0->endpoint.caps.dir_out = 1;
+ ep0->endpoint.name = ep0->name;
+ ep0->endpoint.desc = &cdns3_gadget_ep0_desc;
+ usb_ss->gadget.ep0 = &ep0->endpoint;
+ INIT_LIST_HEAD(&ep0->request_list);
+
+ return 0;
+}
+
+static void cdns3_gadget_release(struct device *dev)
+{
+ struct usb_ss_dev *usb_ss = container_of(dev, struct usb_ss_dev, dev);
+
+ dev_dbg(dev, "releasing '%s'\n", dev_name(dev));
+ kfree(usb_ss);
+}
+
+static int __cdns3_gadget_init(struct cdns3 *cdns)
+{
+ struct usb_ss_dev *usb_ss;
+ int ret;
+ struct device *dev;
+
+ usb_ss = kzalloc(sizeof(*usb_ss), GFP_KERNEL);
+ if (!usb_ss)
+ return -ENOMEM;
+
+ dev = &usb_ss->dev;
+ dev->release = cdns3_gadget_release;
+ dev->parent = cdns->dev;
+ dev_set_name(dev, "gadget-cdns3");
+ cdns->gadget_dev = dev;
+ usb_ss->sysdev = cdns->dev;
+ ret = device_register(dev);
+ if (ret)
+ goto err1;
+
+ usb_ss->regs = cdns->dev_regs;
+
+ /* fill gadget fields */
+ usb_ss->gadget.ops = &usb_ss_gadget_ops;
+ usb_ss->gadget.max_speed = USB_SPEED_SUPER;
+ usb_ss->gadget.speed = USB_SPEED_UNKNOWN;
+ usb_ss->gadget.name = "usb-ss-gadget";
+ usb_ss->gadget.sg_supported = 1;
+ usb_ss->is_connected = 0;
+ spin_lock_init(&usb_ss->lock);
+ INIT_WORK(&usb_ss->pending_status_wq, pending_setup_status_handler);
+
+ usb_ss->in_standby_mode = 1;
+
+ /* initialize endpoint container */
+ INIT_LIST_HEAD(&usb_ss->gadget.ep_list);
+ INIT_LIST_HEAD(&usb_ss->ep_match_list);
+ ret = usb_ss_init_ep0(usb_ss);
+ if (ret) {
+ dev_err(dev, "Failed to create endpoint 0\n");
+ ret = -ENOMEM;
+ goto err2;
+ }
+
+ ret = usb_ss_init_ep(usb_ss);
+ if (ret) {
+ dev_err(dev, "Failed to create non zero endpoints\n");
+ ret = -ENOMEM;
+ goto err2;
+ }
+
+ /* allocate memory for default endpoint TRB */
+ usb_ss->trb_ep0 = (u32 *)dma_alloc_coherent(usb_ss->sysdev, 20,
+ &usb_ss->trb_ep0_dma, GFP_DMA);
+ if (!usb_ss->trb_ep0) {
+ dev_err(dev, "Failed to allocate memory for ep0 TRB\n");
+ ret = -ENOMEM;
+ goto err2;
+ }
+
+ /* allocate memory for setup packet buffer */
+ usb_ss->setup = (u8 *)dma_alloc_coherent(usb_ss->sysdev, 8,
+ &usb_ss->setup_dma,
+ GFP_DMA);
+ if (!usb_ss->setup) {
+ dev_err(dev, "Failed to allocate memory for SETUP buffer\n");
+ ret = -ENOMEM;
+ goto err3;
+ }
+
+ /* add USB gadget device */
+ ret = usb_add_gadget_udc(&usb_ss->dev, &usb_ss->gadget);
+ if (ret < 0) {
+ dev_err(dev, "Failed to register USB device controller\n");
+ goto err4;
+ }
+
+ usb_ss->zlp_buf = kzalloc(ENDPOINT_ZLP_BUF_SIZE, GFP_KERNEL);
+ if (!usb_ss->zlp_buf) {
+ ret = -ENOMEM;
+ goto err4;
+ }
+
+ return 0;
+err4:
+ dma_free_coherent(usb_ss->sysdev, 8, usb_ss->setup,
+ usb_ss->setup_dma);
+err3:
+ dma_free_coherent(usb_ss->sysdev, 20, usb_ss->trb_ep0,
+ usb_ss->trb_ep0_dma);
+err2:
+ device_del(dev);
+err1:
+ put_device(dev);
+ cdns->gadget_dev = NULL;
+ return ret;
+}
+
+/**
+ * cdns3_gadget_remove: parent must call this to remove UDC
+ *
+ * cdns: cdns3 instance
+ *
+ */
+void cdns3_gadget_remove(struct cdns3 *cdns)
+{
+ struct usb_ss_dev *usb_ss;
+
+ if (!cdns->roles[CDNS3_ROLE_GADGET])
+ return;
+
+ usb_ss = container_of(cdns->gadget_dev, struct usb_ss_dev, dev);
+ usb_del_gadget_udc(&usb_ss->gadget);
+ dma_free_coherent(usb_ss->sysdev, 8, usb_ss->setup, usb_ss->setup_dma);
+ dma_free_coherent(usb_ss->sysdev, 20, usb_ss->trb_ep0,
+ usb_ss->trb_ep0_dma);
+ kfree(usb_ss->zlp_buf);
+ device_unregister(cdns->gadget_dev);
+ cdns->gadget_dev = NULL;
+}
+
+static void __cdns3_gadget_start(struct usb_ss_dev *usb_ss)
+{
+
+ /* configure endpoint 0 hardware */
+ cdns_ep0_config(usb_ss);
+
+ /* enable interrupts for endpoint 0 (in and out) */
+ gadget_writel(usb_ss, &usb_ss->regs->ep_ien,
+ EP_IEN__EOUTEN0__MASK | EP_IEN__EINEN0__MASK);
+
+ /* enable interrupt for device */
+ gadget_writel(usb_ss, &usb_ss->regs->usb_ien,
+ USB_IEN__U2RESIEN__MASK
+ | USB_ISTS__DIS2I__MASK
+ | USB_IEN__CON2IEN__MASK
+ | USB_IEN__UHRESIEN__MASK
+ | USB_IEN__UWRESIEN__MASK
+ | USB_IEN__DISIEN__MASK
+ | USB_IEN__CONIEN__MASK
+ | USB_IEN__U3EXTIEN__MASK
+ | USB_IEN__L2ENTIEN__MASK
+ | USB_IEN__L2EXTIEN__MASK);
+
+ gadget_writel(usb_ss, &usb_ss->regs->usb_conf,
+ USB_CONF__CLK2OFFDS__MASK
+ /* | USB_CONF__USB3DIS__MASK */
+ | USB_CONF__L1DS__MASK);
+
+ gadget_writel(usb_ss, &usb_ss->regs->usb_conf,
+ USB_CONF__U1DS__MASK
+ | USB_CONF__U2DS__MASK
+ );
+
+ gadget_writel(usb_ss, &usb_ss->regs->usb_conf, USB_CONF__DEVEN__MASK);
+}
+
+static int cdns3_gadget_start(struct cdns3 *cdns)
+{
+ struct usb_ss_dev *usb_ss = container_of(cdns->gadget_dev,
+ struct usb_ss_dev, dev);
+ unsigned long flags;
+
+ dev_dbg(&usb_ss->dev, "%s begins\n", __func__);
+
+ pm_runtime_get_sync(cdns->dev);
+ spin_lock_irqsave(&usb_ss->lock, flags);
+ usb_ss->start_gadget = 1;
+ if (!usb_ss->gadget_driver) {
+ spin_unlock_irqrestore(&usb_ss->lock, flags);
+ return 0;
+ }
+
+ __cdns3_gadget_start(usb_ss);
+ usb_ss->in_standby_mode = 0;
+ spin_unlock_irqrestore(&usb_ss->lock, flags);
+ dev_dbg(&usb_ss->dev, "%s ends\n", __func__);
+ return 0;
+}
+
+static void __cdns3_gadget_stop(struct cdns3 *cdns)
+{
+ struct usb_ss_dev *usb_ss;
+ unsigned long flags;
+
+ usb_ss = container_of(cdns->gadget_dev, struct usb_ss_dev, dev);
+ if (usb_ss->gadget_driver)
+ usb_ss->gadget_driver->disconnect(&usb_ss->gadget);
+ usb_gadget_disconnect(&usb_ss->gadget);
+ spin_lock_irqsave(&usb_ss->lock, flags);
+ usb_ss->gadget.speed = USB_SPEED_UNKNOWN;
+ usb_gadget_set_state(&usb_ss->gadget, USB_STATE_NOTATTACHED);
+ /* disable interrupt for device */
+ gadget_writel(usb_ss, &usb_ss->regs->usb_ien, 0);
+ gadget_writel(usb_ss, &usb_ss->regs->usb_conf, USB_CONF__DEVDS__MASK);
+ usb_ss->start_gadget = 0;
+ spin_unlock_irqrestore(&usb_ss->lock, flags);
+}
+
+static void cdns3_gadget_stop(struct cdns3 *cdns)
+{
+ if (cdns->role == CDNS3_ROLE_GADGET)
+ __cdns3_gadget_stop(cdns);
+ pm_runtime_mark_last_busy(cdns->dev);
+ pm_runtime_put_autosuspend(cdns->dev);
+}
+
+static int cdns3_gadget_suspend(struct cdns3 *cdns, bool do_wakeup)
+{
+ __cdns3_gadget_stop(cdns);
+ return 0;
+}
+
+static int cdns3_gadget_resume(struct cdns3 *cdns, bool hibernated)
+{
+ struct usb_ss_dev *usb_ss = container_of(cdns->gadget_dev,
+ struct usb_ss_dev, dev);
+ unsigned long flags;
+
+ spin_lock_irqsave(&usb_ss->lock, flags);
+ usb_ss->start_gadget = 1;
+ if (!usb_ss->gadget_driver) {
+ spin_unlock_irqrestore(&usb_ss->lock, flags);
+ return 0;
+ }
+
+ __cdns3_gadget_start(usb_ss);
+ usb_ss->in_standby_mode = 0;
+ spin_unlock_irqrestore(&usb_ss->lock, flags);
+ return 0;
+}
+
+/**
+ * cdns3_gadget_init - initialize device structure
+ *
+ * cdns: cdns3 instance
+ *
+ * This function initializes the gadget.
+ */
+int cdns3_gadget_init(struct cdns3 *cdns)
+{
+ struct cdns3_role_driver *rdrv;
+
+ rdrv = devm_kzalloc(cdns->dev, sizeof(*rdrv), GFP_KERNEL);
+ if (!rdrv)
+ return -ENOMEM;
+
+ rdrv->start = cdns3_gadget_start;
+ rdrv->stop = cdns3_gadget_stop;
+ rdrv->suspend = cdns3_gadget_suspend;
+ rdrv->resume = cdns3_gadget_resume;
+ rdrv->irq = cdns_irq_handler_thread;
+ rdrv->name = "gadget";
+ cdns->roles[CDNS3_ROLE_GADGET] = rdrv;
+ return __cdns3_gadget_init(cdns);
+}
diff --git a/drivers/usb/cdns3/gadget.h b/drivers/usb/cdns3/gadget.h
new file mode 100644
index 000000000000..f0a576d8a4ea
--- /dev/null
+++ b/drivers/usb/cdns3/gadget.h
@@ -0,0 +1,225 @@
+/**
+ * gadget.h - Cadence USB3 device Controller Core file
+ *
+ * Copyright (C) 2016 Cadence Design Systems - http://www.cadence.com
+ * Copyright 2017 NXP
+ *
+ * Authors: Pawel Jez <pjez@cadence.com>,
+ * Konrad Kociolek <konrad@cadence.com>,
+ * Peter Chen <peter.chen@nxp.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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+#ifndef __DRIVERS_CDNS3_GADGET
+#define __DRIVERS_CDNS3_GADGET
+
+#include "dev-regs-map.h"
+
+#if IS_ENABLED(CONFIG_USB_CDNS_MISC)
+#include "cdns_misc.h"
+#endif
+
+#define gadget_to_usb_ss(g) \
+ (container_of(g, struct usb_ss_dev, gadget))
+
+#define to_usb_ss_ep(ep) \
+ (container_of(ep, struct usb_ss_endpoint, endpoint))
+
+#define ep_to_usb_ss_ep(ep) \
+ (container_of(ep, struct usb_ss_endpoint, endpoint))
+
+/*-------------------------------------------------------------------------*/
+/* TRB macros */
+
+/* Common TRB fields */
+#define TRB_SET_CYCLE_BIT 1uL
+#define TRB_SET_CHAIN_BIT 0x10
+
+/* offset 0 */
+#define TRB_DATA_BUFFER_POINTER_MASK 0xFFFFFFFF
+#define TRB_SET_DATA_BUFFER_POINTER(p) (p & TRB_DATA_BUFFER_POINTER_MASK)
+
+/* offset 4 */
+#define TRB_TRANSFER_LENGTH_MASK 0x1FFFF
+#define TRB_SET_TRANSFER_LENGTH(l) (l & TRB_TRANSFER_LENGTH_MASK)
+
+#define TRB_BURST_LENGTH_MASK 0xFF
+#define TRB_SET_BURST_LENGTH(l) ((l & TRB_BURST_LENGTH_MASK) << 24)
+
+/* offset 8 */
+#define TRB_SET_INT_ON_SHORT_PACKET 0x04
+#define TRB_SET_FIFO_MODE 0x08
+#define TRB_SET_INT_ON_COMPLETION 0x20
+
+#define TRB_TYPE_NORMAL 0x400
+
+#define TRB_STREAM_ID_MASK 0xFFFF
+#define TRB_SET_STREAM_ID(sid) ((sid & TRB_STREAM_ID_MASK) << 16)
+
+/*-------------------------------------------------------------------------*/
+/* Driver numeric constants */
+
+
+#define DEVICE_ADDRESS_MAX 127
+
+/* Endpoint init values */
+#define ENDPOINT_MAX_PACKET_LIMIT 1024
+#define ENDPOINT_MAX_STREAMS 15
+
+#define ENDPOINT0_MAX_PACKET_LIMIT 512
+
+/* All endpoints except EP0 */
+#define USB_SS_ENDPOINTS_MAX_COUNT 30
+
+#define USB_SS_TRBS_NUM 32
+
+/* Standby mode */
+#define STB_CLK_SWITCH_DONE_MASK 0x200
+#define STB_CLK_SWITCH_EN_MASK 0x100
+#define STB_CLK_SWITCH_EN_SHIFT 8
+
+#define ENDPOINT_MAX_PACKET_SIZE_0 0
+#define ENDPOINT_MAX_PACKET_SIZE_8 8
+#define ENDPOINT_MAX_PACKET_SIZE_64 64
+#define ENDPOINT_MAX_PACKET_SIZE_512 512
+#define ENDPOINT_MAX_PACKET_SIZE_1023 1023
+#define ENDPOINT_MAX_PACKET_SIZE_1024 1024
+
+#define SS_LINK_STATE_U3 3
+#define FSHS_LPM_STATE_L2 2
+
+#define ADDR_MODULO_8 8
+
+#define INTERRUPT_MASK 0xFFFFFFFF
+
+#define ACTUAL_TRANSFERRED_BYTES_MASK 0x1FFFF
+
+#define ENDPOINT_DIR_MASK 0x80
+
+#define ENDPOINT_ZLP_BUF_SIZE 1024
+/*-------------------------------------------------------------------------*/
+
+/**
+ * IS_REG_REQUIRING_ACTIVE_REF_CLOCK - Macro checks if desired
+ * register requires active clock, it involves such registers as:
+ * EP_CFG, EP_TR_ADDR, EP_CMD, EP_SEL, USB_CONF
+ * @usb_ss: extended gadget object
+ * @reg: register address
+ */
+#define IS_REG_REQUIRING_ACTIVE_REF_CLOCK(usb_ss, reg) (!reg || \
+ (reg >= &usb_ss->regs->ep_sel && reg <= &usb_ss->regs->ep_cmd))
+
+/**
+ * CAST_EP_REG_POS_TO_INDEX - Macro converts bit position of ep_ists register to
+ * index of endpoint object in usb_ss_dev.eps[] container
+ * @i: bit position of endpoint for which endpoint object is required
+ *
+ * Remember that endpoint container doesn't contain default endpoint
+ */
+#define CAST_EP_REG_POS_TO_INDEX(i) (((i) / 16) + ((((i) % 16) - 2) * 2))
+
+/**
+ * CAST_EP_ADDR_TO_INDEX - Macro converts endpoint address to
+ * index of endpoint object in usb_ss_dev.eps[] container
+ * @ep_addr: endpoint address for which endpoint object is required
+ *
+ * Remember that endpoint container doesn't contain default endpoint
+ */
+#define CAST_EP_ADDR_TO_INDEX(ep_addr) \
+ (((ep_addr & 0x7F) - 1) + ((ep_addr & 0x80) ? 1 : 0))
+
+/**
+ * CAST_EP_ADDR_TO_BIT_POS - Macro converts endpoint address to
+ * bit position in ep_ists register
+ * @ep_addr: endpoint address for which bit position is required
+ *
+ * Remember that endpoint container doesn't contain default endpoint
+ */
+#define CAST_EP_ADDR_TO_BIT_POS(ep_addr) \
+ (((uint32_t)1 << (ep_addr & 0x7F)) << ((ep_addr & 0x80) ? 16 : 0))
+
+
+#define CAST_INDEX_TO_EP_ADDR(index) \
+ ((index / 2 + 1) | ((index % 2) ? 0x80 : 0x00))
+
+/* 18KB is the total size, and 2KB is used for EP0 and configuration */
+#define CDNS3_ONCHIP_BUF_SIZE 16 /* KB */
+#define CDNS3_EP_BUF_SIZE 2 /* KB */
+#define CDNS3_UNALIGNED_BUF_SIZE 16384 /* Bytes */
+/*-------------------------------------------------------------------------*/
+/* Used structs */
+
+struct usb_ss_trb {
+ u32 offset0;
+ u32 offset4;
+ u32 offset8;
+};
+
+struct usb_ss_dev;
+
+struct usb_ss_endpoint {
+ struct usb_ep endpoint;
+ struct list_head request_list;
+ struct list_head ep_match_pending_list;
+
+ struct usb_ss_trb *trb_pool;
+ dma_addr_t trb_pool_dma;
+
+ struct usb_ss_dev *usb_ss;
+ char name[20];
+ int hw_pending_flag;
+ int stalled_flag;
+ int wedge_flag;
+ void *cpu_addr;
+ dma_addr_t dma_addr;
+ u8 dir;
+ u8 num;
+ u8 type;
+ bool used;
+};
+
+struct usb_ss_dev {
+ struct device dev;
+ struct usbss_dev_register_block_type __iomem *regs;
+
+ struct usb_gadget gadget;
+ struct usb_gadget_driver *gadget_driver;
+
+ dma_addr_t setup_dma;
+ dma_addr_t trb_ep0_dma;
+ u32 *trb_ep0;
+ u8 *setup;
+ void *zlp_buf;
+
+ struct usb_ss_endpoint *eps[USB_SS_ENDPOINTS_MAX_COUNT];
+ int ep_nums;
+ struct usb_request *actual_ep0_request;
+ int ep0_data_dir;
+ int hw_configured_flag;
+ int wake_up_flag;
+ u16 isoch_delay;
+ spinlock_t lock;
+
+ unsigned is_connected:1;
+ unsigned in_standby_mode:1;
+ unsigned status_completion_no_call:1;
+
+ u32 usb_ien;
+ u32 ep_ien;
+ int setup_pending;
+ struct device *sysdev;
+ bool start_gadget; /* The device mode is enabled */
+ struct list_head ep_match_list;
+ int onchip_mem_allocated_size; /* KB */
+ /* Memory is allocated for OUT */
+ int out_mem_is_allocated:1;
+ struct work_struct pending_status_wq;
+ struct usb_request *pending_status_request;
+};
+
+#endif /* __DRIVERS_CDNS3_GADGET */
diff --git a/drivers/usb/cdns3/host-export.h b/drivers/usb/cdns3/host-export.h
new file mode 100644
index 000000000000..a981d5cf3658
--- /dev/null
+++ b/drivers/usb/cdns3/host-export.h
@@ -0,0 +1,43 @@
+/*
+ * host-export.h - Host Export APIs
+ *
+ * Copyright 2017 NXP
+ * Authors: Peter Chen <peter.chen@nxp.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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#ifndef __DRIVERS_USB_CDNS3_HOST_H
+#define __DRIVERS_USB_CDNS3_HOST_H
+
+#ifdef CONFIG_USB_CDNS3_HOST
+
+int cdns3_host_init(struct cdns3 *cdns);
+void cdns3_host_remove(struct cdns3 *cdns);
+void cdns3_host_driver_init(void);
+
+#else
+
+static inline int cdns3_host_init(struct cdns3 *cdns)
+{
+ return -ENXIO;
+}
+
+static inline void cdns3_host_remove(struct cdns3 *cdns)
+{
+
+}
+
+static inline void cdns3_host_driver_init(void)
+{
+
+}
+
+#endif /* CONFIG_USB_CDNS3_HOST */
+
+#endif /* __DRIVERS_USB_CDNS3_HOST_H */
diff --git a/drivers/usb/cdns3/host.c b/drivers/usb/cdns3/host.c
new file mode 100644
index 000000000000..37bbae183ef0
--- /dev/null
+++ b/drivers/usb/cdns3/host.c
@@ -0,0 +1,286 @@
+/*
+ * host.c - Cadence USB3 host controller driver
+ *
+ * Copyright 2017 NXP
+ * Authors: Peter Chen <peter.chen@nxp.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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/kernel.h>
+#include <linux/device.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <linux/dma-mapping.h>
+#include <linux/usb.h>
+#include <linux/usb/hcd.h>
+#include <linux/pm_runtime.h>
+#include <linux/usb/of.h>
+
+#include "../host/xhci.h"
+
+#include "core.h"
+#include "host-export.h"
+#include "cdns3-nxp-reg-def.h"
+
+static struct hc_driver __read_mostly xhci_cdns3_hc_driver;
+
+static void xhci_cdns3_quirks(struct device *dev, struct xhci_hcd *xhci)
+{
+ /*
+ * As of now platform drivers don't provide MSI support so we ensure
+ * here that the generic code does not try to make a pci_dev from our
+ * dev struct in order to setup MSI
+ */
+ xhci->quirks |= (XHCI_PLAT | XHCI_CDNS_HOST);
+}
+
+static int xhci_cdns3_setup(struct usb_hcd *hcd)
+{
+ int ret;
+ struct xhci_hcd *xhci = hcd_to_xhci(hcd);
+ u32 command;
+
+ ret = xhci_gen_setup(hcd, xhci_cdns3_quirks);
+ if (ret)
+ return ret;
+ /* set usbcmd.EU3S */
+ command = readl(&xhci->op_regs->command);
+ command |= CMD_PM_INDEX;
+ writel(command, &xhci->op_regs->command);
+
+ return 0;
+}
+
+struct cdns3_host {
+ struct device dev;
+ struct usb_hcd *hcd;
+ struct cdns3 *cdns;
+};
+
+static int xhci_cdns3_bus_suspend(struct usb_hcd *hcd)
+{
+ struct device *dev = hcd->self.controller;
+ struct cdns3_host *host = container_of(dev, struct cdns3_host, dev);
+ struct cdns3 *cdns = host->cdns;
+ void __iomem *xhci_regs = cdns->xhci_regs;
+ u32 value;
+ int ret;
+
+ ret = xhci_bus_suspend(hcd);
+ if (ret)
+ return ret;
+
+ value = readl(xhci_regs + XECP_AUX_CTRL_REG1);
+ value |= CFG_RXDET_P3_EN;
+ writel(value, xhci_regs + XECP_AUX_CTRL_REG1);
+
+ return 0;
+}
+
+static const struct xhci_driver_overrides xhci_cdns3_overrides __initconst = {
+ .extra_priv_size = sizeof(struct xhci_hcd),
+ .reset = xhci_cdns3_setup,
+ .bus_suspend = xhci_cdns3_bus_suspend,
+};
+
+static irqreturn_t cdns3_host_irq(struct cdns3 *cdns)
+{
+ struct device *dev = cdns->host_dev;
+ struct usb_hcd *hcd;
+
+ if (dev)
+ hcd = dev_get_drvdata(dev);
+ else
+ return IRQ_NONE;
+
+ if (hcd)
+ return usb_hcd_irq(cdns->irq, hcd);
+ else
+ return IRQ_NONE;
+}
+
+static void cdns3_host_release(struct device *dev)
+{
+ struct cdns3_host *host = container_of(dev, struct cdns3_host, dev);
+
+ dev_dbg(dev, "releasing '%s'\n", dev_name(dev));
+ kfree(host);
+}
+
+static int cdns3_host_start(struct cdns3 *cdns)
+{
+ struct cdns3_host *host;
+ struct device *dev;
+ struct device *sysdev;
+ struct xhci_hcd *xhci;
+ int ret;
+
+ host = kzalloc(sizeof(*host), GFP_KERNEL);
+ if (!host)
+ return -ENOMEM;
+
+ dev = &host->dev;
+ dev->release = cdns3_host_release;
+ dev->parent = cdns->dev;
+ dev_set_name(dev, "xhci-cdns3");
+ cdns->host_dev = dev;
+ host->cdns = cdns;
+ ret = device_register(dev);
+ if (ret)
+ goto err1;
+
+ sysdev = cdns->dev;
+ /* Try to set 64-bit DMA first */
+ if (WARN_ON(!sysdev->dma_mask))
+ /* Platform did not initialize dma_mask */
+ ret = dma_coerce_mask_and_coherent(sysdev,
+ DMA_BIT_MASK(64));
+ else
+ ret = dma_set_mask_and_coherent(sysdev, DMA_BIT_MASK(64));
+
+ /* If setting 64-bit DMA mask fails, fall back to 32-bit DMA mask */
+ if (ret) {
+ ret = dma_set_mask_and_coherent(sysdev, DMA_BIT_MASK(32));
+ if (ret)
+ return ret;
+ }
+ pm_runtime_set_active(dev);
+ pm_runtime_no_callbacks(dev);
+ pm_runtime_enable(dev);
+
+ host->hcd = __usb_create_hcd(&xhci_cdns3_hc_driver, sysdev, dev,
+ dev_name(dev), NULL);
+ if (!host->hcd) {
+ ret = -ENOMEM;
+ goto err2;
+ }
+
+ host->hcd->regs = cdns->xhci_regs;
+ host->hcd->rsrc_start = cdns->xhci_res->start;
+ host->hcd->rsrc_len = resource_size(cdns->xhci_res);
+
+ device_wakeup_enable(host->hcd->self.controller);
+
+ xhci = hcd_to_xhci(host->hcd);
+
+ xhci->quirks = XHCI_SKIP_ACCESS_RESERVED_REG;
+ xhci->main_hcd = host->hcd;
+ xhci->shared_hcd = __usb_create_hcd(&xhci_cdns3_hc_driver, sysdev, dev,
+ dev_name(dev), host->hcd);
+ if (!xhci->shared_hcd) {
+ ret = -ENOMEM;
+ goto err3;
+ }
+ host->hcd->tpl_support = of_usb_host_tpl_support(sysdev->of_node);
+ xhci->shared_hcd->tpl_support = host->hcd->tpl_support;
+
+ ret = usb_add_hcd(host->hcd, 0, IRQF_SHARED);
+ if (ret)
+ goto err4;
+
+ ret = usb_add_hcd(xhci->shared_hcd, 0, IRQF_SHARED);
+ if (ret)
+ goto err5;
+
+ device_set_wakeup_capable(dev, true);
+ dev_dbg(dev, "%s ends\n", __func__);
+
+ return 0;
+
+err5:
+ usb_remove_hcd(host->hcd);
+err4:
+ usb_put_hcd(xhci->shared_hcd);
+err3:
+ usb_put_hcd(host->hcd);
+err2:
+ device_del(dev);
+err1:
+ put_device(dev);
+ cdns->host_dev = NULL;
+ return ret;
+}
+
+static void cdns3_host_stop(struct cdns3 *cdns)
+{
+ struct device *dev = cdns->host_dev;
+ struct usb_hcd *hcd, *shared_hcd;
+ struct xhci_hcd *xhci;
+
+ if (dev) {
+ hcd = dev_get_drvdata(dev);
+ xhci = hcd_to_xhci(hcd);
+ shared_hcd = xhci->shared_hcd;
+ xhci->xhc_state |= XHCI_STATE_REMOVING;
+ usb_remove_hcd(shared_hcd);
+ xhci->shared_hcd = NULL;
+ usb_remove_hcd(hcd);
+ synchronize_irq(cdns->irq);
+ usb_put_hcd(shared_hcd);
+ usb_put_hcd(hcd);
+ cdns->host_dev = NULL;
+ pm_runtime_set_suspended(dev);
+ pm_runtime_disable(dev);
+ device_del(dev);
+ put_device(dev);
+ }
+}
+
+static int cdns3_host_suspend(struct cdns3 *cdns, bool do_wakeup)
+{
+ struct device *dev = cdns->host_dev;
+ struct xhci_hcd *xhci;
+
+ if (!dev)
+ return 0;
+
+ xhci = hcd_to_xhci(dev_get_drvdata(dev));
+ return xhci_suspend(xhci, do_wakeup);
+}
+
+static int cdns3_host_resume(struct cdns3 *cdns, bool hibernated)
+{
+ struct device *dev = cdns->host_dev;
+ struct xhci_hcd *xhci;
+
+ if (!dev)
+ return 0;
+
+ xhci = hcd_to_xhci(dev_get_drvdata(dev));
+ return xhci_resume(xhci, hibernated);
+}
+
+int cdns3_host_init(struct cdns3 *cdns)
+{
+ struct cdns3_role_driver *rdrv;
+
+ rdrv = devm_kzalloc(cdns->dev, sizeof(*rdrv), GFP_KERNEL);
+ if (!rdrv)
+ return -ENOMEM;
+
+ rdrv->start = cdns3_host_start;
+ rdrv->stop = cdns3_host_stop;
+ rdrv->irq = cdns3_host_irq;
+ rdrv->suspend = cdns3_host_suspend;
+ rdrv->resume = cdns3_host_resume;
+ rdrv->name = "host";
+ cdns->roles[CDNS3_ROLE_HOST] = rdrv;
+
+ return 0;
+}
+
+void cdns3_host_remove(struct cdns3 *cdns)
+{
+ cdns3_host_stop(cdns);
+}
+
+void __init cdns3_host_driver_init(void)
+{
+ xhci_init_driver(&xhci_cdns3_hc_driver, &xhci_cdns3_overrides);
+}
diff --git a/drivers/usb/cdns3/io.h b/drivers/usb/cdns3/io.h
new file mode 100644
index 000000000000..c16edbf54b8b
--- /dev/null
+++ b/drivers/usb/cdns3/io.h
@@ -0,0 +1,35 @@
+/**
+ * io.h - Cadence USB3 IO Header
+ *
+ * Copyright (C) 2016 Cadence Design Systems - https://www.cadence.com/
+ *
+ * Authors: Rafal Ozieblo <rafalo@cadence.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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#ifndef __DRIVERS_USB_CDNS_IO_H
+#define __DRIVERS_USB_CDNS_IO_H
+
+#include <linux/io.h>
+
+static inline u32 cdns_readl(uint32_t __iomem *reg)
+{
+ u32 value = 0;
+
+ value = readl(reg);
+ return value;
+}
+
+static inline void cdns_writel(uint32_t __iomem *reg, u32 value)
+{
+ writel(value, reg);
+}
+
+
+#endif /* __DRIVERS_USB_CDNS_IO_H */
diff --git a/drivers/usb/chipidea/ci.h b/drivers/usb/chipidea/ci.h
index 6743f85b1b7a..fbd600e25545 100644
--- a/drivers/usb/chipidea/ci.h
+++ b/drivers/usb/chipidea/ci.h
@@ -128,12 +128,16 @@ enum ci_revision {
* @start: start this role
* @stop: stop this role
* @irq: irq handler for this role
+ * @suspend: system suspend handler for this role
+ * @resume: system resume handler for this role
* @name: role name string (host/gadget)
*/
struct ci_role_driver {
int (*start)(struct ci_hdrc *);
void (*stop)(struct ci_hdrc *);
irqreturn_t (*irq)(struct ci_hdrc *);
+ void (*suspend)(struct ci_hdrc *);
+ void (*resume)(struct ci_hdrc *, bool power_lost);
const char *name;
};
@@ -199,12 +203,16 @@ struct hw_bank {
* @debugfs: root dentry for this controller in debugfs
* @id_event: indicates there is an id event, and handled at ci_otg_work
* @b_sess_valid_event: indicates there is a vbus event, and handled
+ * @vbus_glitch_check_event: check if vbus change is a glitch
* at ci_otg_work
* @imx28_write_fix: Freescale imx28 needs swp instruction for writing
* @supports_runtime_pm: if runtime pm is supported
* @in_lpm: if the core in low power mode
* @wakeup_int: if wakeup interrupt occur
* @rev: The revision number for controller
+ * @mutex: protect code from concorrent running
+ * @power_lost_work: work item when controller power is lost
+ * @power_lost_wq: work queue for controller power is lost
*/
struct ci_hdrc {
struct device *dev;
@@ -254,11 +262,26 @@ struct ci_hdrc {
struct dentry *debugfs;
bool id_event;
bool b_sess_valid_event;
+ bool vbus_glitch_check_event;
bool imx28_write_fix;
bool supports_runtime_pm;
bool in_lpm;
bool wakeup_int;
enum ci_revision rev;
+ /* register save area for suspend&resume */
+ u32 pm_command;
+ u32 pm_status;
+ u32 pm_intr_enable;
+ u32 pm_frame_index;
+ u32 pm_segment;
+ u32 pm_frame_list;
+ u32 pm_async_next;
+ u32 pm_configured_flag;
+ u32 pm_portsc;
+ u32 pm_usbmode;
+ struct work_struct power_lost_work;
+ struct workqueue_struct *power_lost_wq;
+ struct mutex mutex;
};
static inline struct ci_role_driver *ci_role(struct ci_hdrc *ci)
@@ -278,9 +301,21 @@ static inline int ci_role_start(struct ci_hdrc *ci, enum ci_role role)
return -ENXIO;
ret = ci->roles[role]->start(ci);
- if (!ret)
- ci->role = role;
- return ret;
+ if (ret)
+ return ret;
+
+ ci->role = role;
+
+ if (ci->usb_phy) {
+ if (role == CI_ROLE_HOST)
+ usb_phy_set_mode(ci->usb_phy,
+ USB_MODE_HOST);
+ else
+ usb_phy_set_mode(ci->usb_phy,
+ USB_MODE_DEVICE);
+ }
+
+ return 0;
}
static inline void ci_role_stop(struct ci_hdrc *ci)
@@ -293,6 +328,9 @@ static inline void ci_role_stop(struct ci_hdrc *ci)
ci->role = CI_ROLE_END;
ci->roles[role]->stop(ci);
+
+ if (ci->usb_phy)
+ usb_phy_set_mode(ci->usb_phy, USB_MODE_NONE);
}
/**
@@ -452,6 +490,7 @@ u8 hw_port_test_get(struct ci_hdrc *ci);
void hw_phymode_configure(struct ci_hdrc *ci);
void ci_platform_configure(struct ci_hdrc *ci);
+int hw_controller_reset(struct ci_hdrc *ci);
int dbg_create_files(struct ci_hdrc *ci);
diff --git a/drivers/usb/chipidea/ci_hdrc_imx.c b/drivers/usb/chipidea/ci_hdrc_imx.c
index 5f4a8157fad8..483e89ce1800 100644
--- a/drivers/usb/chipidea/ci_hdrc_imx.c
+++ b/drivers/usb/chipidea/ci_hdrc_imx.c
@@ -1,5 +1,6 @@
/*
- * Copyright 2012 Freescale Semiconductor, Inc.
+ * Copyright 2012-2016 Freescale Semiconductor, Inc.
+ * Copyright 2017 NXP
* Copyright (C) 2012 Marek Vasut <marex@denx.de>
* on behalf of DENX Software Engineering GmbH
*
@@ -20,6 +21,13 @@
#include <linux/usb/chipidea.h>
#include <linux/usb/of.h>
#include <linux/clk.h>
+#include <linux/of_device.h>
+#include <linux/regmap.h>
+#include <linux/mfd/syscon.h>
+#include <linux/regulator/consumer.h>
+#include <linux/busfreq-imx.h>
+#include <linux/pm_qos.h>
+#include <linux/usb/of.h>
#include "ci.h"
#include "ci_hdrc_imx.h"
@@ -41,25 +49,29 @@ static const struct ci_hdrc_imx_platform_flag imx27_usb_data = {
static const struct ci_hdrc_imx_platform_flag imx28_usb_data = {
.flags = CI_HDRC_IMX28_WRITE_FIX |
CI_HDRC_TURN_VBUS_EARLY_ON |
- CI_HDRC_DISABLE_STREAMING,
+ CI_HDRC_DISABLE_STREAMING |
+ CI_HDRC_IMX_EHCI_QUIRK,
};
static const struct ci_hdrc_imx_platform_flag imx6q_usb_data = {
.flags = CI_HDRC_SUPPORTS_RUNTIME_PM |
CI_HDRC_TURN_VBUS_EARLY_ON |
- CI_HDRC_DISABLE_STREAMING,
+ CI_HDRC_DISABLE_STREAMING |
+ CI_HDRC_IMX_EHCI_QUIRK,
};
static const struct ci_hdrc_imx_platform_flag imx6sl_usb_data = {
.flags = CI_HDRC_SUPPORTS_RUNTIME_PM |
CI_HDRC_TURN_VBUS_EARLY_ON |
- CI_HDRC_DISABLE_HOST_STREAMING,
+ CI_HDRC_DISABLE_HOST_STREAMING |
+ CI_HDRC_IMX_EHCI_QUIRK,
};
static const struct ci_hdrc_imx_platform_flag imx6sx_usb_data = {
.flags = CI_HDRC_SUPPORTS_RUNTIME_PM |
CI_HDRC_TURN_VBUS_EARLY_ON |
- CI_HDRC_DISABLE_HOST_STREAMING,
+ CI_HDRC_DISABLE_HOST_STREAMING |
+ CI_HDRC_IMX_EHCI_QUIRK,
};
static const struct ci_hdrc_imx_platform_flag imx6ul_usb_data = {
@@ -71,6 +83,16 @@ static const struct ci_hdrc_imx_platform_flag imx7d_usb_data = {
.flags = CI_HDRC_SUPPORTS_RUNTIME_PM,
};
+static const struct ci_hdrc_imx_platform_flag imx7ulp_usb_data = {
+ .flags = CI_HDRC_SUPPORTS_RUNTIME_PM |
+ CI_HDRC_IMX_EHCI_QUIRK |
+ CI_HDRC_PMQOS,
+};
+
+static const struct ci_hdrc_imx_platform_flag imx8qm_usb_data = {
+ .flags = CI_HDRC_SUPPORTS_RUNTIME_PM,
+};
+
static const struct of_device_id ci_hdrc_imx_dt_ids[] = {
{ .compatible = "fsl,imx23-usb", .data = &imx23_usb_data},
{ .compatible = "fsl,imx28-usb", .data = &imx28_usb_data},
@@ -80,6 +102,8 @@ static const struct of_device_id ci_hdrc_imx_dt_ids[] = {
{ .compatible = "fsl,imx6sx-usb", .data = &imx6sx_usb_data},
{ .compatible = "fsl,imx6ul-usb", .data = &imx6ul_usb_data},
{ .compatible = "fsl,imx7d-usb", .data = &imx7d_usb_data},
+ { .compatible = "fsl,imx7ulp-usb", .data = &imx7ulp_usb_data},
+ { .compatible = "fsl,imx8qm-usb", .data = &imx8qm_usb_data},
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, ci_hdrc_imx_dt_ids);
@@ -91,12 +115,18 @@ struct ci_hdrc_imx_data {
struct imx_usbmisc_data *usbmisc_data;
bool supports_runtime_pm;
bool in_lpm;
+ struct regmap *anatop;
+ struct pinctrl *pinctrl;
+ struct pinctrl_state *pinctrl_hsic_active;
+ struct regulator *hsic_pad_regulator;
+ const struct ci_hdrc_imx_platform_flag *data;
/* SoC before i.mx6 (except imx23/imx28) needs three clks */
bool need_three_clks;
struct clk *clk_ipg;
struct clk *clk_ahb;
struct clk *clk_per;
/* --------------------------------- */
+ struct pm_qos_request pm_qos_req;
};
/* Common functions shared by usbmisc drivers */
@@ -144,12 +174,40 @@ static struct imx_usbmisc_data *usbmisc_get_init_data(struct device *dev)
if (of_find_property(np, "over-current-active-high", NULL))
data->oc_polarity = 1;
+ if (of_find_property(np, "power-polarity-active-high", NULL))
+ data->pwr_polarity = 1;
+
if (of_find_property(np, "external-vbus-divider", NULL))
data->evdo = 1;
if (of_usb_get_phy_mode(np) == USBPHY_INTERFACE_MODE_ULPI)
data->ulpi = 1;
+ if (of_find_property(np, "osc-clkgate-delay", NULL)) {
+ ret = of_property_read_u32(np, "osc-clkgate-delay",
+ &data->osc_clkgate_delay);
+ if (ret) {
+ dev_err(dev,
+ "failed to get osc-clkgate-delay value\n");
+ return ERR_PTR(ret);
+ }
+ /*
+ * 0 <= osc_clkgate_delay <=7
+ * - 0x0 (default) is 0.5ms,
+ * - 0x1-0x7: 1-7ms
+ */
+ if (data->osc_clkgate_delay > 7) {
+ dev_err(dev,
+ "value of osc-clkgate-delay is incorrect\n");
+ return ERR_PTR(-EINVAL);
+ }
+ }
+
+ of_property_read_u32(np, "picophy,pre-emp-curr-control",
+ &data->emp_curr_control);
+ of_property_read_u32(np, "picophy,dc-vol-level-adjust",
+ &data->dc_vol_level_adjust);
+
return data;
}
@@ -251,41 +309,135 @@ static void imx_disable_unprepare_clks(struct device *dev)
}
}
+static int ci_hdrc_imx_notify_event(struct ci_hdrc *ci, unsigned event)
+{
+ struct device *dev = ci->dev->parent;
+ struct ci_hdrc_imx_data *data = dev_get_drvdata(dev);
+ int ret = 0;
+ struct imx_usbmisc_data *mdata = data->usbmisc_data;
+
+ switch (event) {
+ case CI_HDRC_CONTROLLER_VBUS_EVENT:
+ if (ci->vbus_active)
+ ret = imx_usbmisc_charger_detection(mdata, true);
+ else
+ ret = imx_usbmisc_charger_detection(mdata, false);
+ break;
+ case CI_HDRC_IMX_HSIC_ACTIVE_EVENT:
+ if (!IS_ERR(data->pinctrl) &&
+ !IS_ERR(data->pinctrl_hsic_active)) {
+ ret = pinctrl_select_state(data->pinctrl,
+ data->pinctrl_hsic_active);
+ if (ret)
+ dev_err(dev,
+ "hsic_active select failed, err=%d\n",
+ ret);
+ return ret;
+ }
+ break;
+ case CI_HDRC_IMX_HSIC_SUSPEND_EVENT:
+ if (data->usbmisc_data) {
+ ret = imx_usbmisc_hsic_set_connect(data->usbmisc_data);
+ if (ret)
+ dev_err(dev,
+ "hsic_set_connect failed, err=%d\n",
+ ret);
+ return ret;
+ }
+ break;
+ case CI_HDRC_IMX_TERM_SELECT_OVERRIDE_FS:
+ if (data->usbmisc_data)
+ return imx_usbmisc_term_select_override(
+ data->usbmisc_data, true, 1);
+ break;
+ case CI_HDRC_IMX_TERM_SELECT_OVERRIDE_OFF:
+ if (data->usbmisc_data)
+ return imx_usbmisc_term_select_override(
+ data->usbmisc_data, false, 0);
+ break;
+ default:
+ dev_dbg(dev, "unknown event\n");
+ }
+
+ return ret;
+}
+
static int ci_hdrc_imx_probe(struct platform_device *pdev)
{
struct ci_hdrc_imx_data *data;
struct ci_hdrc_platform_data pdata = {
.name = dev_name(&pdev->dev),
.capoffset = DEF_CAPOFFSET,
+ .notify_event = ci_hdrc_imx_notify_event,
};
int ret;
const struct of_device_id *of_id;
const struct ci_hdrc_imx_platform_flag *imx_platform_flag;
+ struct device *dev = &pdev->dev;
+ struct device_node *np = dev->of_node;
+ struct pinctrl_state *pinctrl_hsic_idle;
- of_id = of_match_device(ci_hdrc_imx_dt_ids, &pdev->dev);
+ of_id = of_match_device(ci_hdrc_imx_dt_ids, dev);
if (!of_id)
return -ENODEV;
imx_platform_flag = of_id->data;
- data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
+ data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
if (!data)
return -ENOMEM;
platform_set_drvdata(pdev, data);
- data->usbmisc_data = usbmisc_get_init_data(&pdev->dev);
+
+ data->data = imx_platform_flag;
+ pdata.flags |= imx_platform_flag->flags;
+ data->usbmisc_data = usbmisc_get_init_data(dev);
if (IS_ERR(data->usbmisc_data))
return PTR_ERR(data->usbmisc_data);
- ret = imx_get_clks(&pdev->dev);
+ data->pinctrl = devm_pinctrl_get(dev);
+ if (IS_ERR(data->pinctrl)) {
+ dev_dbg(dev, "pinctrl get failed, err=%ld\n",
+ PTR_ERR(data->pinctrl));
+ } else {
+ pinctrl_hsic_idle = pinctrl_lookup_state(data->pinctrl, "idle");
+ if (IS_ERR(pinctrl_hsic_idle)) {
+ dev_dbg(dev,
+ "pinctrl_hsic_idle lookup failed, err=%ld\n",
+ PTR_ERR(pinctrl_hsic_idle));
+ } else {
+ ret = pinctrl_select_state(data->pinctrl,
+ pinctrl_hsic_idle);
+ if (ret) {
+ dev_err(dev,
+ "hsic_idle select failed, err=%d\n",
+ ret);
+ return ret;
+ }
+ }
+
+ data->pinctrl_hsic_active = pinctrl_lookup_state(data->pinctrl,
+ "active");
+ if (IS_ERR(data->pinctrl_hsic_active))
+ dev_dbg(dev,
+ "pinctrl_hsic_active lookup failed, err=%ld\n",
+ PTR_ERR(data->pinctrl_hsic_active));
+ }
+
+ ret = imx_get_clks(dev);
if (ret)
return ret;
- ret = imx_prepare_enable_clks(&pdev->dev);
+ request_bus_freq(BUS_FREQ_HIGH);
+ if (pdata.flags & CI_HDRC_PMQOS)
+ pm_qos_add_request(&data->pm_qos_req,
+ PM_QOS_CPU_DMA_LATENCY, 0);
+
+ ret = imx_prepare_enable_clks(dev);
if (ret)
- return ret;
+ goto err_bus_freq;
- data->phy = devm_usb_get_phy_by_phandle(&pdev->dev, "fsl,usbphy", 0);
+ data->phy = devm_usb_get_phy_by_phandle(dev, "fsl,usbphy", 0);
if (IS_ERR(data->phy)) {
ret = PTR_ERR(data->phy);
/* Return -EINVAL if no usbphy is available */
@@ -295,46 +447,107 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev)
}
pdata.usb_phy = data->phy;
- pdata.flags |= imx_platform_flag->flags;
+ data->usbmisc_data->usb_phy = data->phy;
if (pdata.flags & CI_HDRC_SUPPORTS_RUNTIME_PM)
data->supports_runtime_pm = true;
+ if (of_find_property(np, "ci-disable-lpm", NULL)) {
+ data->supports_runtime_pm = false;
+ pdata.flags &= ~CI_HDRC_SUPPORTS_RUNTIME_PM;
+ }
+
+ if (of_usb_get_phy_mode(dev->of_node) == USBPHY_INTERFACE_MODE_HSIC) {
+ pdata.flags |= CI_HDRC_IMX_IS_HSIC;
+ data->usbmisc_data->hsic = 1;
+ data->hsic_pad_regulator = devm_regulator_get(dev, "pad");
+ if (PTR_ERR(data->hsic_pad_regulator) == -EPROBE_DEFER) {
+ ret = -EPROBE_DEFER;
+ goto err_clk;
+ } else if (PTR_ERR(data->hsic_pad_regulator) == -ENODEV) {
+ /* no pad regualator is needed */
+ data->hsic_pad_regulator = NULL;
+ } else if (IS_ERR(data->hsic_pad_regulator)) {
+ dev_err(dev, "Get hsic pad regulator error: %ld\n",
+ PTR_ERR(data->hsic_pad_regulator));
+ ret = PTR_ERR(data->hsic_pad_regulator);
+ goto err_clk;
+ }
+
+ if (data->hsic_pad_regulator) {
+ ret = regulator_enable(data->hsic_pad_regulator);
+ if (ret) {
+ dev_err(dev,
+ "Fail to enable hsic pad regulator\n");
+ goto err_clk;
+ }
+ }
+ }
+
+ if (of_find_property(np, "fsl,anatop", NULL) && data->usbmisc_data) {
+ data->anatop = syscon_regmap_lookup_by_phandle(np,
+ "fsl,anatop");
+ if (IS_ERR(data->anatop)) {
+ dev_dbg(dev, "failed to find regmap for anatop\n");
+ ret = PTR_ERR(data->anatop);
+ goto disable_hsic_regulator;
+ }
+ data->usbmisc_data->anatop = data->anatop;
+ }
+
ret = imx_usbmisc_init(data->usbmisc_data);
if (ret) {
- dev_err(&pdev->dev, "usbmisc init failed, ret=%d\n", ret);
- goto err_clk;
+ dev_err(dev, "usbmisc init failed, ret=%d\n", ret);
+ goto disable_hsic_regulator;
}
- data->ci_pdev = ci_hdrc_add_device(&pdev->dev,
+ data->ci_pdev = ci_hdrc_add_device(dev,
pdev->resource, pdev->num_resources,
&pdata);
if (IS_ERR(data->ci_pdev)) {
ret = PTR_ERR(data->ci_pdev);
if (ret != -EPROBE_DEFER)
- dev_err(&pdev->dev,
+ dev_err(dev,
"ci_hdrc_add_device failed, err=%d\n", ret);
- goto err_clk;
+ goto disable_hsic_regulator;
}
ret = imx_usbmisc_init_post(data->usbmisc_data);
if (ret) {
- dev_err(&pdev->dev, "usbmisc post failed, ret=%d\n", ret);
+ dev_err(dev, "usbmisc post failed, ret=%d\n", ret);
goto disable_device;
}
+ ret = imx_usbmisc_set_wakeup(data->usbmisc_data, false);
+ if (ret) {
+ dev_err(dev, "usbmisc set_wakeup failed, ret=%d\n", ret);
+ goto disable_device;
+ }
+
+ /* usbmisc needs to know dr mode to choose wakeup setting */
+ if (data->usbmisc_data)
+ data->usbmisc_data->available_role =
+ ci_hdrc_query_available_role(data->ci_pdev);
+
if (data->supports_runtime_pm) {
- pm_runtime_set_active(&pdev->dev);
- pm_runtime_enable(&pdev->dev);
+ pm_runtime_set_active(dev);
+ pm_runtime_enable(dev);
}
- device_set_wakeup_capable(&pdev->dev, true);
+ device_set_wakeup_capable(dev, true);
return 0;
disable_device:
ci_hdrc_remove_device(data->ci_pdev);
+disable_hsic_regulator:
+ if (data->hsic_pad_regulator)
+ ret = regulator_disable(data->hsic_pad_regulator);
err_clk:
imx_disable_unprepare_clks(&pdev->dev);
+err_bus_freq:
+ if (pdata.flags & CI_HDRC_PMQOS)
+ pm_qos_remove_request(&data->pm_qos_req);
+ release_bus_freq(BUS_FREQ_HIGH);
return ret;
}
@@ -349,6 +562,11 @@ static int ci_hdrc_imx_remove(struct platform_device *pdev)
}
ci_hdrc_remove_device(data->ci_pdev);
imx_disable_unprepare_clks(&pdev->dev);
+ if (data->data->flags & CI_HDRC_PMQOS)
+ pm_qos_remove_request(&data->pm_qos_req);
+ release_bus_freq(BUS_FREQ_HIGH);
+ if (data->hsic_pad_regulator)
+ regulator_disable(data->hsic_pad_regulator);
return 0;
}
@@ -362,10 +580,23 @@ static void ci_hdrc_imx_shutdown(struct platform_device *pdev)
static int imx_controller_suspend(struct device *dev)
{
struct ci_hdrc_imx_data *data = dev_get_drvdata(dev);
+ int ret;
dev_dbg(dev, "at %s\n", __func__);
+ if (data->usbmisc_data) {
+ ret = imx_usbmisc_hsic_set_clk(data->usbmisc_data, false);
+ if (ret) {
+ dev_err(dev,
+ "usbmisc hsic_set_clk failed, ret=%d\n", ret);
+ return ret;
+ }
+ }
+
imx_disable_unprepare_clks(dev);
+ if (data->data->flags & CI_HDRC_PMQOS)
+ pm_qos_remove_request(&data->pm_qos_req);
+ release_bus_freq(BUS_FREQ_HIGH);
data->in_lpm = true;
return 0;
@@ -378,27 +609,51 @@ static int imx_controller_resume(struct device *dev)
dev_dbg(dev, "at %s\n", __func__);
- if (!data->in_lpm) {
- WARN_ON(1);
+ if (!data->in_lpm)
return 0;
- }
+ request_bus_freq(BUS_FREQ_HIGH);
+ if (data->data->flags & CI_HDRC_PMQOS)
+ pm_qos_add_request(&data->pm_qos_req,
+ PM_QOS_CPU_DMA_LATENCY, 0);
ret = imx_prepare_enable_clks(dev);
if (ret)
- return ret;
+ goto err_bus_freq;
data->in_lpm = false;
+ ret = imx_usbmisc_power_lost_check(data->usbmisc_data);
+ /* re-init if resume from power lost */
+ if (ret > 0) {
+ ret = imx_usbmisc_init(data->usbmisc_data);
+ if (ret) {
+ dev_err(dev, "usbmisc init failed, ret=%d\n", ret);
+ goto clk_disable;
+ }
+ }
+
ret = imx_usbmisc_set_wakeup(data->usbmisc_data, false);
if (ret) {
dev_err(dev, "usbmisc set_wakeup failed, ret=%d\n", ret);
goto clk_disable;
}
+ ret = imx_usbmisc_hsic_set_clk(data->usbmisc_data, true);
+ if (ret) {
+ dev_err(dev, "usbmisc hsic_set_clk failed, ret=%d\n", ret);
+ goto hsic_set_clk_fail;
+ }
+
return 0;
+hsic_set_clk_fail:
+ imx_usbmisc_set_wakeup(data->usbmisc_data, true);
clk_disable:
imx_disable_unprepare_clks(dev);
+err_bus_freq:
+ if (data->data->flags & CI_HDRC_PMQOS)
+ pm_qos_remove_request(&data->pm_qos_req);
+ release_bus_freq(BUS_FREQ_HIGH);
return ret;
}
@@ -422,7 +677,12 @@ static int ci_hdrc_imx_suspend(struct device *dev)
}
}
- return imx_controller_suspend(dev);
+ ret = imx_controller_suspend(dev);
+ if (ret)
+ return ret;
+
+ pinctrl_pm_select_sleep_state(dev);
+ return ret;
}
static int ci_hdrc_imx_resume(struct device *dev)
@@ -430,6 +690,7 @@ static int ci_hdrc_imx_resume(struct device *dev)
struct ci_hdrc_imx_data *data = dev_get_drvdata(dev);
int ret;
+ pinctrl_pm_select_default_state(dev);
ret = imx_controller_resume(dev);
if (!ret && data->supports_runtime_pm) {
pm_runtime_disable(dev);
@@ -446,10 +707,8 @@ static int ci_hdrc_imx_runtime_suspend(struct device *dev)
struct ci_hdrc_imx_data *data = dev_get_drvdata(dev);
int ret;
- if (data->in_lpm) {
- WARN_ON(1);
+ if (data->in_lpm)
return 0;
- }
ret = imx_usbmisc_set_wakeup(data->usbmisc_data, true);
if (ret) {
diff --git a/drivers/usb/chipidea/ci_hdrc_imx.h b/drivers/usb/chipidea/ci_hdrc_imx.h
index d666c9f036ba..76512e5d27ad 100644
--- a/drivers/usb/chipidea/ci_hdrc_imx.h
+++ b/drivers/usb/chipidea/ci_hdrc_imx.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2012 Freescale Semiconductor, Inc.
+ * Copyright 2012-2015 Freescale Semiconductor, Inc.
*
* The code contained herein is licensed under the GNU General Public
* License. You may obtain a copy of the GNU General Public License
@@ -11,19 +11,39 @@
#ifndef __DRIVER_USB_CHIPIDEA_CI_HDRC_IMX_H
#define __DRIVER_USB_CHIPIDEA_CI_HDRC_IMX_H
+#include <linux/usb/otg.h>
+#include <linux/usb/phy.h>
struct imx_usbmisc_data {
struct device *dev;
int index;
+ struct regmap *anatop;
+ struct usb_phy *usb_phy;
unsigned int disable_oc:1; /* over current detect disabled */
unsigned int oc_polarity:1; /* over current polarity if oc enabled */
+ unsigned int pwr_polarity:1; /* polarity of enable vbus from pmic */
unsigned int evdo:1; /* set external vbus divider option */
unsigned int ulpi:1; /* connected to an ULPI phy */
+ unsigned int hsic:1; /* HSIC controlller */
+ /*
+ * Specifies the delay between powering up the xtal 24MHz clock
+ * and release the clock to the digital logic inside the analog block
+ */
+ unsigned int osc_clkgate_delay;
+ enum usb_dr_mode available_role;
+ int emp_curr_control;
+ int dc_vol_level_adjust;
};
int imx_usbmisc_init(struct imx_usbmisc_data *);
int imx_usbmisc_init_post(struct imx_usbmisc_data *);
int imx_usbmisc_set_wakeup(struct imx_usbmisc_data *, bool);
+int imx_usbmisc_charger_detection(struct imx_usbmisc_data *data, bool connect);
+int imx_usbmisc_power_lost_check(struct imx_usbmisc_data *);
+int imx_usbmisc_hsic_set_connect(struct imx_usbmisc_data *);
+int imx_usbmisc_hsic_set_clk(struct imx_usbmisc_data *, bool);
+int imx_usbmisc_term_select_override(struct imx_usbmisc_data *data,
+ bool enable, int val);
#endif /* __DRIVER_USB_CHIPIDEA_CI_HDRC_IMX_H */
diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c
index 70306ae039c0..09d50c2b02e2 100644
--- a/drivers/usb/chipidea/core.c
+++ b/drivers/usb/chipidea/core.c
@@ -477,7 +477,7 @@ void ci_platform_configure(struct ci_hdrc *ci)
*
* This function returns an error code
*/
-static int hw_controller_reset(struct ci_hdrc *ci)
+int hw_controller_reset(struct ci_hdrc *ci)
{
int count = 0;
@@ -574,7 +574,7 @@ static irqreturn_t ci_irq(int irq, void *data)
* and disconnection events.
*/
if (ci->is_otg && (otgsc & OTGSC_BSVIE) && (otgsc & OTGSC_BSVIS)) {
- ci->b_sess_valid_event = true;
+ ci->vbus_glitch_check_event = true;
/* Clear BSV irq */
hw_write_otgsc(ci, OTGSC_BSVIS, OTGSC_BSVIS);
ci_otg_queue_work(ci);
@@ -690,6 +690,12 @@ static int ci_get_platdata(struct device *dev,
if (of_find_property(dev->of_node, "non-zero-ttctrl-ttha", NULL))
platdata->flags |= CI_HDRC_SET_NON_ZERO_TTHA;
+ /* "imx-usb-charger-detection is legacy compatible */
+ if (of_find_property(dev->of_node, "phy-charger-detection", NULL) ||
+ of_find_property(dev->of_node, "imx-usb-charger-detection",
+ NULL))
+ platdata->flags |= CI_HDRC_PHY_CHARGER_DETECTION;
+
ext_id = ERR_PTR(-ENODEV);
ext_vbus = ERR_PTR(-ENODEV);
if (of_property_read_bool(dev->of_node, "extcon")) {
@@ -814,12 +820,39 @@ void ci_hdrc_remove_device(struct platform_device *pdev)
}
EXPORT_SYMBOL_GPL(ci_hdrc_remove_device);
+/**
+ * ci_hdrc_query_available_role: get runtime available operation mode
+ *
+ * The glue layer can get current operation mode (host/peripheral/otg)
+ * This function should be called after ci core device has created.
+ *
+ * @pdev: the platform device of ci core.
+ *
+ * Return USB_DR_MODE_XXX.
+ */
+enum usb_dr_mode ci_hdrc_query_available_role(struct platform_device *pdev)
+{
+ struct ci_hdrc *ci = platform_get_drvdata(pdev);
+
+ if (!ci)
+ return USB_DR_MODE_UNKNOWN;
+ if (ci->roles[CI_ROLE_HOST] && ci->roles[CI_ROLE_GADGET])
+ return USB_DR_MODE_OTG;
+ else if (ci->roles[CI_ROLE_HOST])
+ return USB_DR_MODE_HOST;
+ else if (ci->roles[CI_ROLE_GADGET])
+ return USB_DR_MODE_PERIPHERAL;
+ else
+ return USB_DR_MODE_UNKNOWN;
+}
+EXPORT_SYMBOL_GPL(ci_hdrc_query_available_role);
+
static inline void ci_role_destroy(struct ci_hdrc *ci)
{
- ci_hdrc_gadget_destroy(ci);
- ci_hdrc_host_destroy(ci);
if (ci->is_otg && ci->roles[CI_ROLE_GADGET])
ci_hdrc_otg_destroy(ci);
+ ci_hdrc_gadget_destroy(ci);
+ ci_hdrc_host_destroy(ci);
}
static void ci_get_otg_capable(struct ci_hdrc *ci)
@@ -891,6 +924,55 @@ static const struct attribute_group ci_attr_group = {
.attrs = ci_attrs,
};
+static enum ci_role ci_get_role(struct ci_hdrc *ci)
+{
+ if (ci->roles[CI_ROLE_HOST] && ci->roles[CI_ROLE_GADGET]) {
+ if (ci->is_otg) {
+ hw_write_otgsc(ci, OTGSC_IDIE, OTGSC_IDIE);
+ return ci_otg_role(ci);
+ } else {
+ /*
+ * If the controller is not OTG capable, but support
+ * role switch, the defalt role is gadget, and the
+ * user can switch it through debugfs.
+ */
+ return CI_ROLE_GADGET;
+ }
+ } else {
+ return ci->roles[CI_ROLE_HOST]
+ ? CI_ROLE_HOST
+ : CI_ROLE_GADGET;
+ }
+}
+
+static void ci_start_new_role(struct ci_hdrc *ci)
+{
+ enum ci_role role = ci_get_role(ci);
+
+ if (ci->role != role) {
+ ci_handle_id_switch(ci);
+ } else if (role == CI_ROLE_GADGET) {
+ if (ci->vbus_active)
+ usb_gadget_vbus_disconnect(&ci->gadget);
+ ci_handle_vbus_connected(ci);
+ }
+}
+
+static void ci_power_lost_work(struct work_struct *work)
+{
+ struct ci_hdrc *ci = container_of(work, struct ci_hdrc,
+ power_lost_work);
+
+ disable_irq_nosync(ci->irq);
+ pm_runtime_get_sync(ci->dev);
+ if (!ci_otg_is_fsm_mode(ci))
+ ci_start_new_role(ci);
+ else
+ ci_hdrc_otg_fsm_restart(ci);
+ pm_runtime_put_sync(ci->dev);
+ enable_irq(ci->irq);
+}
+
static int ci_hdrc_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
@@ -1019,30 +1101,15 @@ static int ci_hdrc_probe(struct platform_device *pdev)
}
}
- if (ci->roles[CI_ROLE_HOST] && ci->roles[CI_ROLE_GADGET]) {
- if (ci->is_otg) {
- ci->role = ci_otg_role(ci);
- /* Enable ID change irq */
- hw_write_otgsc(ci, OTGSC_IDIE, OTGSC_IDIE);
- } else {
- /*
- * If the controller is not OTG capable, but support
- * role switch, the defalt role is gadget, and the
- * user can switch it through debugfs.
- */
- ci->role = CI_ROLE_GADGET;
- }
- } else {
- ci->role = ci->roles[CI_ROLE_HOST]
- ? CI_ROLE_HOST
- : CI_ROLE_GADGET;
+ ci->role = ci_get_role(ci);
+ /* only update vbus status for peripheral */
+ if (ci->role == CI_ROLE_GADGET) {
+ /* Let DP pull down if it isn't currently */
+ hw_write(ci, OP_USBCMD, USBCMD_RS, 0);
+ ci_handle_vbus_connected(ci);
}
if (!ci_otg_is_fsm_mode(ci)) {
- /* only update vbus status for peripheral */
- if (ci->role == CI_ROLE_GADGET)
- ci_handle_vbus_change(ci);
-
ret = ci_role_start(ci, ci->role);
if (ret) {
dev_err(dev, "can't start %s role\n",
@@ -1072,6 +1139,9 @@ static int ci_hdrc_probe(struct platform_device *pdev)
ci_hdrc_otg_fsm_start(ci);
device_set_wakeup_capable(&pdev->dev, true);
+
+ mutex_init(&ci->mutex);
+
ret = dbg_create_files(ci);
if (ret)
goto stop;
@@ -1080,8 +1150,19 @@ static int ci_hdrc_probe(struct platform_device *pdev)
if (ret)
goto remove_debug;
+ /* Init workqueue for controller power lost handling */
+ ci->power_lost_wq = create_freezable_workqueue("ci_power_lost");
+ if (!ci->power_lost_wq) {
+ dev_err(ci->dev, "can't create power_lost workqueue\n");
+ goto remove_sys_group;
+ }
+
+ INIT_WORK(&ci->power_lost_work, ci_power_lost_work);
+
return 0;
+remove_sys_group:
+ sysfs_remove_group(&ci->dev->kobj, &ci_attr_group);
remove_debug:
dbg_remove_files(ci);
stop:
@@ -1109,6 +1190,8 @@ static int ci_hdrc_remove(struct platform_device *pdev)
pm_runtime_put_noidle(&pdev->dev);
}
+ flush_workqueue(ci->power_lost_wq);
+ destroy_workqueue(ci->power_lost_wq);
dbg_remove_files(ci);
sysfs_remove_group(&ci->dev->kobj, &ci_attr_group);
ci_role_destroy(ci);
@@ -1137,13 +1220,10 @@ static void ci_otg_fsm_wakeup_by_srp(struct ci_hdrc *ci)
{
if ((ci->fsm.otg->state == OTG_STATE_A_IDLE) &&
(ci->fsm.a_bus_drop == 1) && (ci->fsm.a_bus_req == 0)) {
- if (!hw_read_otgsc(ci, OTGSC_ID)) {
- ci->fsm.a_srp_det = 1;
- ci->fsm.a_bus_drop = 0;
- } else {
+ if (!hw_read_otgsc(ci, OTGSC_ID))
+ otg_add_timer(&ci->fsm, A_DP_END);
+ else
ci->fsm.id = 1;
- }
- ci_otg_queue_work(ci);
}
}
@@ -1159,6 +1239,29 @@ static void ci_controller_suspend(struct ci_hdrc *ci)
enable_irq(ci->irq);
}
+/*
+ * Handle the wakeup interrupt triggered by extcon connector
+ * We need to call ci_irq again for extcon since the first
+ * interrupt (wakeup int) only let the controller be out of
+ * low power mode, but not handle any interrupts.
+ */
+static void ci_extcon_wakeup_int(struct ci_hdrc *ci)
+{
+ struct ci_hdrc_cable *cable_id, *cable_vbus;
+ u32 otgsc = hw_read_otgsc(ci, ~0);
+
+ cable_id = &ci->platdata->id_extcon;
+ cable_vbus = &ci->platdata->vbus_extcon;
+
+ if (!IS_ERR(cable_id->edev) && ci->is_otg &&
+ (otgsc & OTGSC_IDIE) && (otgsc & OTGSC_IDIS))
+ ci_irq(ci->irq, ci);
+
+ if (!IS_ERR(cable_vbus->edev) && ci->is_otg &&
+ (otgsc & OTGSC_BSVIE) && (otgsc & OTGSC_BSVIS))
+ ci_irq(ci->irq, ci);
+}
+
static int ci_controller_resume(struct device *dev)
{
struct ci_hdrc *ci = dev_get_drvdata(dev);
@@ -1166,10 +1269,8 @@ static int ci_controller_resume(struct device *dev)
dev_dbg(dev, "at %s\n", __func__);
- if (!ci->in_lpm) {
- WARN_ON(1);
+ if (!ci->in_lpm)
return 0;
- }
ci_hdrc_enter_lpm(ci, false);
@@ -1191,6 +1292,7 @@ static int ci_controller_resume(struct device *dev)
enable_irq(ci->irq);
if (ci_otg_is_fsm_mode(ci))
ci_otg_fsm_wakeup_by_srp(ci);
+ ci_extcon_wakeup_int(ci);
}
return 0;
@@ -1201,6 +1303,7 @@ static int ci_suspend(struct device *dev)
{
struct ci_hdrc *ci = dev_get_drvdata(dev);
+ flush_workqueue(ci->power_lost_wq);
if (ci->wq)
flush_workqueue(ci->wq);
/*
@@ -1217,6 +1320,10 @@ static int ci_suspend(struct device *dev)
return 0;
}
+ /* Extra routine per role before system suspend */
+ if (ci->role != CI_ROLE_END && ci_role(ci)->suspend)
+ ci_role(ci)->suspend(ci);
+
if (device_may_wakeup(dev)) {
if (ci_otg_is_fsm_mode(ci))
ci_otg_fsm_suspend_for_srp(ci);
@@ -1233,8 +1340,18 @@ static int ci_suspend(struct device *dev)
static int ci_resume(struct device *dev)
{
struct ci_hdrc *ci = dev_get_drvdata(dev);
+ bool power_lost = false;
+ u32 sample_reg_val;
int ret;
+ /* Check if controller resume from power lost */
+ sample_reg_val = hw_read(ci, OP_ENDPTLISTADDR, ~0);
+ if (sample_reg_val == 0)
+ power_lost = true;
+ else if (sample_reg_val == 0xFFFFFFFF)
+ /* Restore value 0 if it was set for power lost check */
+ hw_write(ci, OP_ENDPTLISTADDR, ~0, 0);
+
if (device_may_wakeup(dev))
disable_irq_wake(ci->irq);
@@ -1242,6 +1359,19 @@ static int ci_resume(struct device *dev)
if (ret)
return ret;
+ if (power_lost) {
+ /* shutdown and re-init for phy */
+ ci_usb_phy_exit(ci);
+ ci_usb_phy_init(ci);
+ }
+
+ /* Extra routine per role after system resume */
+ if (ci->role != CI_ROLE_END && ci_role(ci)->resume)
+ ci_role(ci)->resume(ci, power_lost);
+
+ if (power_lost)
+ queue_work(ci->power_lost_wq, &ci->power_lost_work);
+
if (ci->supports_runtime_pm) {
pm_runtime_disable(dev);
pm_runtime_set_active(dev);
@@ -1258,10 +1388,8 @@ static int ci_runtime_suspend(struct device *dev)
dev_dbg(dev, "at %s\n", __func__);
- if (ci->in_lpm) {
- WARN_ON(1);
+ if (ci->in_lpm)
return 0;
- }
if (ci_otg_is_fsm_mode(ci))
ci_otg_fsm_suspend_for_srp(ci);
diff --git a/drivers/usb/chipidea/host.c b/drivers/usb/chipidea/host.c
index 18cb8e46262d..37367a395cd1 100644
--- a/drivers/usb/chipidea/host.c
+++ b/drivers/usb/chipidea/host.c
@@ -25,6 +25,7 @@
#include <linux/usb/hcd.h>
#include <linux/usb/chipidea.h>
#include <linux/regulator/consumer.h>
+#include <linux/imx_gpc.h>
#include "../host/ehci.h"
@@ -34,11 +35,29 @@
static struct hc_driver __read_mostly ci_ehci_hc_driver;
static int (*orig_bus_suspend)(struct usb_hcd *hcd);
+static int (*orig_bus_resume)(struct usb_hcd *hcd);
+static int (*orig_hub_control)(struct usb_hcd *hcd,
+ u16 typeReq, u16 wValue, u16 wIndex,
+ char *buf, u16 wLength);
struct ehci_ci_priv {
struct regulator *reg_vbus;
};
+/* This function is used to override WKCN, WKDN, and WKOC */
+static void ci_ehci_override_wakeup_flag(struct ehci_hcd *ehci,
+ u32 __iomem *reg, u32 flags, bool set)
+{
+ u32 val = ehci_readl(ehci, reg);
+
+ if (set)
+ val |= flags;
+ else
+ val &= ~flags;
+
+ ehci_writel(ehci, val, reg);
+}
+
static int ehci_ci_portpower(struct usb_hcd *hcd, int portnum, bool enable)
{
struct ehci_hcd *ehci = hcd_to_ehci(hcd);
@@ -108,9 +127,164 @@ static const struct ehci_driver_overrides ehci_ci_overrides = {
.reset = ehci_ci_reset,
};
+static int ci_imx_ehci_bus_resume(struct usb_hcd *hcd)
+{
+ struct ehci_hcd *ehci = hcd_to_ehci(hcd);
+ int port;
+
+ int ret = orig_bus_resume(hcd);
+
+ if (ret)
+ return ret;
+
+ port = HCS_N_PORTS(ehci->hcs_params);
+ while (port--) {
+ u32 __iomem *reg = &ehci->regs->port_status[port];
+ u32 portsc = ehci_readl(ehci, reg);
+ /*
+ * Notify PHY after resume signal has finished, it is
+ * for global suspend case.
+ */
+ if (hcd->usb_phy
+ && test_bit(port, &ehci->bus_suspended)
+ && (portsc & PORT_CONNECT)
+ && (ehci_port_speed(ehci, portsc) ==
+ USB_PORT_STAT_HIGH_SPEED))
+ /* notify the USB PHY */
+ usb_phy_notify_resume(hcd->usb_phy, USB_SPEED_HIGH);
+ }
+
+ return 0;
+}
+
+#ifdef CONFIG_USB_OTG
+
+static int ci_start_port_reset(struct usb_hcd *hcd, unsigned port)
+{
+ struct ehci_hcd *ehci = hcd_to_ehci(hcd);
+ u32 __iomem *reg;
+ u32 status;
+
+ if (!port)
+ return -EINVAL;
+ port--;
+ /* start port reset before HNP protocol time out */
+ reg = &ehci->regs->port_status[port];
+ status = ehci_readl(ehci, reg);
+ if (!(status & PORT_CONNECT))
+ return -ENODEV;
+
+ /* khubd will finish the reset later */
+ if (ehci_is_TDI(ehci))
+ ehci_writel(ehci, status | (PORT_RESET & ~PORT_RWC_BITS), reg);
+ else
+ ehci_writel(ehci, status | PORT_RESET, reg);
+
+ return 0;
+}
+
+#else
+
+#define ci_start_port_reset NULL
+
+#endif
+
+/* The below code is based on tegra ehci driver */
+static int ci_imx_ehci_hub_control(
+ struct usb_hcd *hcd,
+ u16 typeReq,
+ u16 wValue,
+ u16 wIndex,
+ char *buf,
+ u16 wLength
+)
+{
+ struct ehci_hcd *ehci = hcd_to_ehci(hcd);
+ u32 __iomem *status_reg;
+ u32 temp;
+ unsigned long flags;
+ int retval = 0;
+ struct device *dev = hcd->self.controller;
+ struct ci_hdrc *ci = dev_get_drvdata(dev);
+
+ status_reg = &ehci->regs->port_status[(wIndex & 0xff) - 1];
+
+ spin_lock_irqsave(&ehci->lock, flags);
+
+ if (typeReq == SetPortFeature && wValue == USB_PORT_FEAT_SUSPEND) {
+ temp = ehci_readl(ehci, status_reg);
+ if ((temp & PORT_PE) == 0 || (temp & PORT_RESET) != 0) {
+ retval = -EPIPE;
+ goto done;
+ }
+
+ temp &= ~(PORT_RWC_BITS | PORT_WKCONN_E);
+ temp |= PORT_WKDISC_E | PORT_WKOC_E;
+ ehci_writel(ehci, temp | PORT_SUSPEND, status_reg);
+
+ /*
+ * If a transaction is in progress, there may be a delay in
+ * suspending the port. Poll until the port is suspended.
+ */
+ if (ehci_handshake(ehci, status_reg, PORT_SUSPEND,
+ PORT_SUSPEND, 5000))
+ ehci_err(ehci, "timeout waiting for SUSPEND\n");
+
+ if (ci->platdata->flags & CI_HDRC_IMX_IS_HSIC) {
+ if (ci->platdata->notify_event)
+ ci->platdata->notify_event
+ (ci, CI_HDRC_IMX_HSIC_SUSPEND_EVENT);
+ ci_ehci_override_wakeup_flag(ehci, status_reg,
+ PORT_WKDISC_E | PORT_WKCONN_E, false);
+ }
+
+ spin_unlock_irqrestore(&ehci->lock, flags);
+ if (ehci_port_speed(ehci, temp) ==
+ USB_PORT_STAT_HIGH_SPEED && hcd->usb_phy) {
+ /* notify the USB PHY */
+ usb_phy_notify_suspend(hcd->usb_phy, USB_SPEED_HIGH);
+ }
+ spin_lock_irqsave(&ehci->lock, flags);
+
+ set_bit((wIndex & 0xff) - 1, &ehci->suspended_ports);
+ goto done;
+ }
+
+ /*
+ * After resume has finished, it needs do some post resume
+ * operation for some SoCs.
+ */
+ else if (typeReq == ClearPortFeature &&
+ wValue == USB_PORT_FEAT_C_SUSPEND) {
+
+ /* Make sure the resume has finished, it should be finished */
+ if (ehci_handshake(ehci, status_reg, PORT_RESUME, 0, 25000))
+ ehci_err(ehci, "timeout waiting for resume\n");
+
+ temp = ehci_readl(ehci, status_reg);
+
+ if (ehci_port_speed(ehci, temp) ==
+ USB_PORT_STAT_HIGH_SPEED && hcd->usb_phy) {
+ /* notify the USB PHY */
+ usb_phy_notify_resume(hcd->usb_phy, USB_SPEED_HIGH);
+ }
+ }
+
+ spin_unlock_irqrestore(&ehci->lock, flags);
+
+ /* Handle the hub control events here */
+ return orig_hub_control(hcd, typeReq, wValue, wIndex, buf, wLength);
+done:
+ spin_unlock_irqrestore(&ehci->lock, flags);
+ return retval;
+}
+
static irqreturn_t host_irq(struct ci_hdrc *ci)
{
- return usb_hcd_irq(ci->irq, ci->hcd);
+ if (ci->hcd)
+ return usb_hcd_irq(ci->irq, ci->hcd);
+ else
+ return IRQ_NONE;
}
static int host_start(struct ci_hdrc *ci)
@@ -164,6 +338,13 @@ static int host_start(struct ci_hdrc *ci)
}
}
+ if (ci_otg_is_fsm_mode(ci)) {
+ if (ci->fsm.id && ci->fsm.otg->state <= OTG_STATE_B_HOST)
+ hcd->self.is_b_host = 1;
+ else
+ hcd->self.is_b_host = 0;
+ }
+
ret = usb_add_hcd(hcd, 0, 0);
if (ret) {
goto disable_reg;
@@ -173,11 +354,17 @@ static int host_start(struct ci_hdrc *ci)
ci->hcd = hcd;
if (ci_otg_is_fsm_mode(ci)) {
+ hcd->self.otg_fsm = &ci->fsm;
otg->host = &hcd->self;
hcd->self.otg_port = 1;
}
}
+ if (ci->platdata->notify_event &&
+ (ci->platdata->flags & CI_HDRC_IMX_IS_HSIC))
+ ci->platdata->notify_event
+ (ci, CI_HDRC_IMX_HSIC_ACTIVE_EVENT);
+
return ret;
disable_reg:
@@ -205,16 +392,123 @@ static void host_stop(struct ci_hdrc *ci)
if (ci->platdata->reg_vbus && !ci_otg_is_fsm_mode(ci) &&
(ci->platdata->flags & CI_HDRC_TURN_VBUS_EARLY_ON))
regulator_disable(ci->platdata->reg_vbus);
+ if (hcd->self.is_b_host)
+ hcd->self.is_b_host = 0;
}
ci->hcd = NULL;
ci->otg.host = NULL;
}
+bool ci_hdrc_host_has_device(struct ci_hdrc *ci)
+{
+ struct usb_device *roothub;
+ int i;
+
+ if ((ci->role == CI_ROLE_HOST) && ci->hcd) {
+ roothub = ci->hcd->self.root_hub;
+ for (i = 0; i < roothub->maxchild; ++i) {
+ if (usb_hub_find_child(roothub, (i + 1)))
+ return true;
+ }
+ }
+ return false;
+}
+
+static void ci_hdrc_host_save_for_power_lost(struct ci_hdrc *ci)
+{
+ struct ehci_hcd *ehci;
+
+ if (!ci->hcd)
+ return;
+
+ ehci = hcd_to_ehci(ci->hcd);
+ /* save EHCI registers */
+ ci->pm_usbmode = ehci_readl(ehci, &ehci->regs->usbmode);
+ ci->pm_command = ehci_readl(ehci, &ehci->regs->command);
+ ci->pm_command &= ~CMD_RUN;
+ ci->pm_status = ehci_readl(ehci, &ehci->regs->status);
+ ci->pm_intr_enable = ehci_readl(ehci, &ehci->regs->intr_enable);
+ ci->pm_frame_index = ehci_readl(ehci, &ehci->regs->frame_index);
+ ci->pm_segment = ehci_readl(ehci, &ehci->regs->segment);
+ ci->pm_frame_list = ehci_readl(ehci, &ehci->regs->frame_list);
+ ci->pm_async_next = ehci_readl(ehci, &ehci->regs->async_next);
+ ci->pm_configured_flag =
+ ehci_readl(ehci, &ehci->regs->configured_flag);
+ ci->pm_portsc = ehci_readl(ehci, &ehci->regs->port_status[0]);
+}
+
+static void ci_hdrc_host_restore_from_power_lost(struct ci_hdrc *ci)
+{
+ struct ehci_hcd *ehci;
+ unsigned long flags;
+ u32 tmp;
+ int step_ms;
+ /*
+ * If the vbus is off during system suspend, most of devices will pull
+ * DP up within 200ms when they see vbus, set 1000ms for safety.
+ */
+ int timeout_ms = 1000;
+
+ if (!ci->hcd)
+ return;
+
+ hw_controller_reset(ci);
+
+ ehci = hcd_to_ehci(ci->hcd);
+ spin_lock_irqsave(&ehci->lock, flags);
+ /* Restore EHCI registers */
+ ehci_writel(ehci, ci->pm_usbmode, &ehci->regs->usbmode);
+ ehci_writel(ehci, ci->pm_portsc, &ehci->regs->port_status[0]);
+ ehci_writel(ehci, ci->pm_command, &ehci->regs->command);
+ ehci_writel(ehci, ci->pm_intr_enable, &ehci->regs->intr_enable);
+ ehci_writel(ehci, ci->pm_frame_index, &ehci->regs->frame_index);
+ ehci_writel(ehci, ci->pm_segment, &ehci->regs->segment);
+ ehci_writel(ehci, ci->pm_frame_list, &ehci->regs->frame_list);
+ ehci_writel(ehci, ci->pm_async_next, &ehci->regs->async_next);
+ ehci_writel(ehci, ci->pm_configured_flag,
+ &ehci->regs->configured_flag);
+ /* Restore the PHY's connect notifier setting */
+ if (ci->pm_portsc & PORTSC_HSP)
+ usb_phy_notify_connect(ci->usb_phy, USB_SPEED_HIGH);
+
+ tmp = ehci_readl(ehci, &ehci->regs->command);
+ tmp |= CMD_RUN;
+ ehci_writel(ehci, tmp, &ehci->regs->command);
+ spin_unlock_irqrestore(&ehci->lock, flags);
+
+ if (!(ci->pm_portsc & PORTSC_CCS))
+ return;
+
+ for (step_ms = 0; step_ms < timeout_ms; step_ms += 25) {
+ if (ehci_readl(ehci, &ehci->regs->port_status[0]) & PORTSC_CCS)
+ break;
+ msleep(25);
+ }
+}
+
+static void ci_hdrc_host_suspend(struct ci_hdrc *ci)
+{
+ if (ci_hdrc_host_has_device(ci))
+ imx_gpc_mf_request_on(ci->irq, 1);
+
+ ci_hdrc_host_save_for_power_lost(ci);
+}
+
+static void ci_hdrc_host_resume(struct ci_hdrc *ci, bool power_lost)
+{
+ imx_gpc_mf_request_on(ci->irq, 0);
+
+ if (power_lost)
+ ci_hdrc_host_restore_from_power_lost(ci);
+}
void ci_hdrc_host_destroy(struct ci_hdrc *ci)
{
- if (ci->role == CI_ROLE_HOST && ci->hcd)
+ if (ci->role == CI_ROLE_HOST && ci->hcd) {
+ disable_irq_nosync(ci->irq);
host_stop(ci);
+ enable_irq(ci->irq);
+ }
}
static int ci_ehci_bus_suspend(struct usb_hcd *hcd)
@@ -222,6 +516,8 @@ static int ci_ehci_bus_suspend(struct usb_hcd *hcd)
struct ehci_hcd *ehci = hcd_to_ehci(hcd);
int port;
u32 tmp;
+ struct device *dev = hcd->self.controller;
+ struct ci_hdrc *ci = dev_get_drvdata(dev);
int ret = orig_bus_suspend(hcd);
@@ -251,6 +547,30 @@ static int ci_ehci_bus_suspend(struct usb_hcd *hcd)
* It needs a short delay between set RS bit and PHCD.
*/
usleep_range(150, 200);
+
+ /*
+ * If a transaction is in progress, there may be
+ * a delay in suspending the port. Poll until the
+ * port is suspended.
+ */
+ if (test_bit(port, &ehci->bus_suspended) &&
+ ehci_handshake(ehci, reg, PORT_SUSPEND,
+ PORT_SUSPEND, 5000))
+ ehci_err(ehci, "timeout waiting for SUSPEND\n");
+
+ if (ci->platdata->flags & CI_HDRC_IMX_IS_HSIC)
+ ci_ehci_override_wakeup_flag(ehci, reg,
+ PORT_WKDISC_E | PORT_WKCONN_E, false);
+
+ if (hcd->usb_phy && test_bit(port, &ehci->bus_suspended)
+ && (ehci_port_speed(ehci, portsc) ==
+ USB_PORT_STAT_HIGH_SPEED))
+ /*
+ * notify the USB PHY, it is for global
+ * suspend case.
+ */
+ usb_phy_notify_suspend(hcd->usb_phy,
+ USB_SPEED_HIGH);
break;
}
}
@@ -272,6 +592,8 @@ int ci_hdrc_host_init(struct ci_hdrc *ci)
rdrv->start = host_start;
rdrv->stop = host_stop;
rdrv->irq = host_irq;
+ rdrv->suspend = ci_hdrc_host_suspend;
+ rdrv->resume = ci_hdrc_host_resume;
rdrv->name = "host";
ci->roles[CI_ROLE_HOST] = rdrv;
@@ -282,5 +604,11 @@ void ci_hdrc_host_driver_init(void)
{
ehci_init_driver(&ci_ehci_hc_driver, &ehci_ci_overrides);
orig_bus_suspend = ci_ehci_hc_driver.bus_suspend;
+ orig_bus_resume = ci_ehci_hc_driver.bus_resume;
+ orig_hub_control = ci_ehci_hc_driver.hub_control;
+
ci_ehci_hc_driver.bus_suspend = ci_ehci_bus_suspend;
+ ci_ehci_hc_driver.bus_resume = ci_imx_ehci_bus_resume;
+ ci_ehci_hc_driver.hub_control = ci_imx_ehci_hub_control;
+ ci_ehci_hc_driver.start_port_reset = ci_start_port_reset;
}
diff --git a/drivers/usb/chipidea/host.h b/drivers/usb/chipidea/host.h
index 70112cf0f195..448df8894e26 100644
--- a/drivers/usb/chipidea/host.h
+++ b/drivers/usb/chipidea/host.h
@@ -7,6 +7,7 @@
int ci_hdrc_host_init(struct ci_hdrc *ci);
void ci_hdrc_host_destroy(struct ci_hdrc *ci);
void ci_hdrc_host_driver_init(void);
+bool ci_hdrc_host_has_device(struct ci_hdrc *ci);
#else
@@ -20,11 +21,16 @@ static inline void ci_hdrc_host_destroy(struct ci_hdrc *ci)
}
-static void ci_hdrc_host_driver_init(void)
+static inline void ci_hdrc_host_driver_init(void)
{
}
+static inline bool ci_hdrc_host_has_device(struct ci_hdrc *ci)
+{
+ return false;
+}
+
#endif
#endif /* __DRIVERS_USB_CHIPIDEA_HOST_H */
diff --git a/drivers/usb/chipidea/otg.c b/drivers/usb/chipidea/otg.c
index 8bf4032226ed..412232d84ff1 100644
--- a/drivers/usb/chipidea/otg.c
+++ b/drivers/usb/chipidea/otg.c
@@ -1,7 +1,8 @@
/*
* otg.c - ChipIdea USB IP core OTG driver
*
- * Copyright (C) 2013 Freescale Semiconductor, Inc.
+ * Copyright (C) 2013-2016 Freescale Semiconductor, Inc.
+ * Copyright 2017 NXP
*
* Author: Peter Chen
*
@@ -23,6 +24,7 @@
#include "bits.h"
#include "otg.h"
#include "otg_fsm.h"
+#include "host.h"
/**
* hw_read_otgsc returns otgsc register bits value.
@@ -129,6 +131,46 @@ enum ci_role ci_otg_role(struct ci_hdrc *ci)
return role;
}
+/*
+ * Handling vbus glitch
+ * We only need to consider glitch for without usb connection,
+ * With usb connection, we consider it as real disconnection.
+ *
+ * If the vbus can't be kept above B session valid for timeout value,
+ * we think it is a vbus glitch, otherwise it's a valid vbus.
+ */
+#define CI_VBUS_CONNECT_TIMEOUT_MS 300
+static int ci_is_vbus_glitch(struct ci_hdrc *ci)
+{
+ int i;
+
+ for (i = 0; i < CI_VBUS_CONNECT_TIMEOUT_MS/20; i++) {
+ if (hw_read_otgsc(ci, OTGSC_AVV)) {
+ return 0;
+ } else if (!hw_read_otgsc(ci, OTGSC_BSV)) {
+ dev_warn(ci->dev, "there is a vbus glitch\n");
+ return 1;
+ }
+ msleep(20);
+ }
+
+ return 0;
+}
+
+void ci_handle_vbus_connected(struct ci_hdrc *ci)
+{
+ /*
+ * TODO: if the platform does not supply 5v to udc, or use other way
+ * to supply 5v, it needs to use other conditions to call
+ * usb_gadget_vbus_connect.
+ */
+ if (!ci->is_otg)
+ return;
+
+ if (hw_read_otgsc(ci, OTGSC_BSV) && !ci_is_vbus_glitch(ci))
+ usb_gadget_vbus_connect(&ci->gadget);
+}
+
void ci_handle_vbus_change(struct ci_hdrc *ci)
{
if (!ci->is_otg)
@@ -165,10 +207,13 @@ static int hw_wait_vbus_lower_bsv(struct ci_hdrc *ci)
return 0;
}
-static void ci_handle_id_switch(struct ci_hdrc *ci)
+void ci_handle_id_switch(struct ci_hdrc *ci)
{
- enum ci_role role = ci_otg_role(ci);
+ enum ci_role role;
+ int ret = 0;
+ mutex_lock(&ci->mutex);
+ role = ci_otg_role(ci);
if (role != ci->role) {
dev_dbg(ci->dev, "switching from %s to %s\n",
ci_role(ci)->name, ci->roles[role]->name);
@@ -184,14 +229,57 @@ static void ci_handle_id_switch(struct ci_hdrc *ci)
* care vbus on the board, since it will not affect
* external connector status.
*/
- hw_wait_vbus_lower_bsv(ci);
+ ret = hw_wait_vbus_lower_bsv(ci);
+ else if (ci->vbus_active)
+ /*
+ * If the role switch happens(e.g. during
+ * system sleep), and we lose vbus drop
+ * event, disconnect gadget for it before
+ * start host.
+ */
+ usb_gadget_vbus_disconnect(&ci->gadget);
ci_role_start(ci, role);
/* vbus change may have already occurred */
if (role == CI_ROLE_GADGET)
ci_handle_vbus_change(ci);
+
+ /*
+ * If the role switch happens(e.g. during system
+ * sleep) and vbus keeps on afterwards, we connect
+ * gadget as vbus connect event lost.
+ */
+ if (ret == -ETIMEDOUT)
+ usb_gadget_vbus_connect(&ci->gadget);
+ }
+ mutex_unlock(&ci->mutex);
+}
+
+static void ci_handle_vbus_glitch(struct ci_hdrc *ci)
+{
+ bool valid_vbus_change = false;
+
+ if (hw_read_otgsc(ci, OTGSC_BSV)) {
+ if (!ci_is_vbus_glitch(ci)) {
+ if (ci_otg_is_fsm_mode(ci)) {
+ ci->fsm.b_sess_vld = 1;
+ ci->fsm.b_ssend_srp = 0;
+ otg_del_timer(&ci->fsm, B_SSEND_SRP);
+ otg_del_timer(&ci->fsm, B_SRP_FAIL);
+ }
+ valid_vbus_change = true;
+ }
+ } else {
+ if (ci->vbus_active && !ci_otg_is_fsm_mode(ci))
+ valid_vbus_change = true;
+ }
+
+ if (valid_vbus_change) {
+ ci->b_sess_valid_event = true;
+ ci_otg_queue_work(ci);
}
}
+
/**
* ci_otg_work - perform otg (vbus/id) event handle
* @work: work struct
@@ -200,6 +288,15 @@ static void ci_otg_work(struct work_struct *work)
{
struct ci_hdrc *ci = container_of(work, struct ci_hdrc, work);
+ if (ci->vbus_glitch_check_event) {
+ ci->vbus_glitch_check_event = false;
+ pm_runtime_get_sync(ci->dev);
+ ci_handle_vbus_glitch(ci);
+ pm_runtime_put_sync(ci->dev);
+ enable_irq(ci->irq);
+ return;
+ }
+
if (ci_otg_is_fsm_mode(ci) && !ci_otg_fsm_work(ci)) {
enable_irq(ci->irq);
return;
@@ -248,13 +345,14 @@ int ci_hdrc_otg_init(struct ci_hdrc *ci)
*/
void ci_hdrc_otg_destroy(struct ci_hdrc *ci)
{
+ /* Disable all OTG irq and clear status */
+ hw_write_otgsc(ci, OTGSC_INT_EN_BITS | OTGSC_INT_STATUS_BITS,
+ OTGSC_INT_STATUS_BITS);
if (ci->wq) {
flush_workqueue(ci->wq);
destroy_workqueue(ci->wq);
+ ci->wq = NULL;
}
- /* Disable all OTG irq and clear status */
- hw_write_otgsc(ci, OTGSC_INT_EN_BITS | OTGSC_INT_STATUS_BITS,
- OTGSC_INT_STATUS_BITS);
if (ci_otg_is_fsm_mode(ci))
ci_hdrc_otg_fsm_remove(ci);
}
diff --git a/drivers/usb/chipidea/otg.h b/drivers/usb/chipidea/otg.h
index a5557c70034a..95fa6c2b675a 100644
--- a/drivers/usb/chipidea/otg.h
+++ b/drivers/usb/chipidea/otg.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013-2014 Freescale Semiconductor, Inc.
+ * Copyright (C) 2013-2015 Freescale Semiconductor, Inc.
*
* Author: Peter Chen
*
@@ -17,11 +17,17 @@ int ci_hdrc_otg_init(struct ci_hdrc *ci);
void ci_hdrc_otg_destroy(struct ci_hdrc *ci);
enum ci_role ci_otg_role(struct ci_hdrc *ci);
void ci_handle_vbus_change(struct ci_hdrc *ci);
+void ci_handle_id_switch(struct ci_hdrc *ci);
+void ci_handle_vbus_connected(struct ci_hdrc *ci);
static inline void ci_otg_queue_work(struct ci_hdrc *ci)
{
- disable_irq_nosync(ci->irq);
- if (queue_work(ci->wq, &ci->work) == false)
- enable_irq(ci->irq);
+ if (ci->wq) {
+ disable_irq_nosync(ci->irq);
+ if (!queue_work(ci->wq, &ci->work))
+ enable_irq(ci->irq);
+ } else {
+ WARN_ON(!ci->wq);
+ }
}
#endif /* __DRIVERS_USB_CHIPIDEA_OTG_H */
diff --git a/drivers/usb/chipidea/otg_fsm.c b/drivers/usb/chipidea/otg_fsm.c
index 5ea0246f650d..b5d079a54aa8 100644
--- a/drivers/usb/chipidea/otg_fsm.c
+++ b/drivers/usb/chipidea/otg_fsm.c
@@ -28,7 +28,10 @@
#include "ci.h"
#include "bits.h"
#include "otg.h"
+#include "udc.h"
#include "otg_fsm.h"
+#include "udc.h"
+#include "host.h"
/* Add for otg: interact with user space app */
static ssize_t
@@ -215,6 +218,11 @@ static unsigned otg_timer_ms[] = {
0,
TB_DATA_PLS,
TB_SSEND_SRP,
+ TA_DP_END,
+ TA_TST_MAINT,
+ TB_SRP_REQD,
+ TB_TST_SUSP,
+ 0,
};
/*
@@ -300,6 +308,7 @@ static int a_wait_vfall_tmout(struct ci_hdrc *ci)
static int a_wait_bcon_tmout(struct ci_hdrc *ci)
{
ci->fsm.a_wait_bcon_tmout = 1;
+ dev_warn(ci->dev, "Device No Response\n");
return 0;
}
@@ -312,6 +321,7 @@ static int a_aidl_bdis_tmout(struct ci_hdrc *ci)
static int b_ase0_brst_tmout(struct ci_hdrc *ci)
{
ci->fsm.b_ase0_brst_tmout = 1;
+ dev_warn(ci->dev, "Device No Response\n");
return 0;
}
@@ -336,6 +346,7 @@ static int b_se0_srp_tmout(struct ci_hdrc *ci)
static int b_srp_fail_tmout(struct ci_hdrc *ci)
{
ci->fsm.b_srp_done = 1;
+ dev_warn(ci->dev, "Device No Response\n");
return 1;
}
@@ -360,6 +371,57 @@ static int b_ssend_srp_tmout(struct ci_hdrc *ci)
return 1;
}
+static int a_dp_end_tmout(struct ci_hdrc *ci)
+{
+ ci->fsm.a_bus_drop = 0;
+ ci->fsm.a_srp_det = 1;
+ return 0;
+}
+
+static int a_tst_maint_tmout(struct ci_hdrc *ci)
+{
+ ci->fsm.tst_maint = 0;
+ if (ci->fsm.otg_vbus_off) {
+ ci->fsm.otg_vbus_off = 0;
+ dev_dbg(ci->dev,
+ "test device does not disconnect, end the session!\n");
+ }
+
+ /* End the session */
+ ci->fsm.a_bus_req = 0;
+ ci->fsm.a_bus_drop = 1;
+ return 0;
+}
+
+/*
+ * otg_srp_reqd feature
+ * After A(PET) turn off vbus, B(UUT) should start this timer to do SRP
+ * when the timer expires.
+ */
+static int b_srp_reqd_tmout(struct ci_hdrc *ci)
+{
+ ci->fsm.otg_srp_reqd = 0;
+ if (ci->fsm.otg->state == OTG_STATE_B_IDLE) {
+ ci->fsm.b_bus_req = 1;
+ return 0;
+ }
+ return 1;
+}
+
+/*
+ * otg_hnp_reqd feature
+ * After B(UUT) switch to host, B should hand host role back
+ * to A(PET) within TB_TST_SUSP after setting configuration.
+ */
+static int b_tst_susp_tmout(struct ci_hdrc *ci)
+{
+ if (ci->fsm.otg->state == OTG_STATE_B_HOST) {
+ ci->fsm.b_bus_req = 0;
+ return 0;
+ }
+ return 1;
+}
+
/*
* Keep this list in the same order as timers indexed
* by enum otg_fsm_timer in include/linux/usb/otg-fsm.h
@@ -377,6 +439,11 @@ static int (*otg_timer_handlers[])(struct ci_hdrc *) = {
NULL, /* A_WAIT_ENUM */
b_data_pls_tmout, /* B_DATA_PLS */
b_ssend_srp_tmout, /* B_SSEND_SRP */
+ a_dp_end_tmout, /* A_DP_END */
+ a_tst_maint_tmout, /* A_TST_MAINT */
+ b_srp_reqd_tmout, /* B_SRP_REQD */
+ b_tst_susp_tmout, /* B_TST_SUSP */
+ NULL, /* HNP_POLLING */
};
/*
@@ -463,6 +530,9 @@ static void ci_otg_drv_vbus(struct otg_fsm *fsm, int on)
struct ci_hdrc *ci = container_of(fsm, struct ci_hdrc, fsm);
if (on) {
+ ci->platdata->notify_event(ci,
+ CI_HDRC_IMX_TERM_SELECT_OVERRIDE_OFF);
+
/* Enable power power */
hw_write(ci, OP_PORTSC, PORTSC_W1C_BITS | PORTSC_PP,
PORTSC_PP);
@@ -486,6 +556,7 @@ static void ci_otg_drv_vbus(struct otg_fsm *fsm, int on)
fsm->a_bus_drop = 1;
fsm->a_bus_req = 0;
+ fsm->b_conn = 0;
}
}
@@ -562,11 +633,16 @@ static int ci_otg_start_host(struct otg_fsm *fsm, int on)
static int ci_otg_start_gadget(struct otg_fsm *fsm, int on)
{
struct ci_hdrc *ci = container_of(fsm, struct ci_hdrc, fsm);
+ unsigned long flags;
+ int gadget_ready = 0;
- if (on)
- usb_gadget_vbus_connect(&ci->gadget);
- else
- usb_gadget_vbus_disconnect(&ci->gadget);
+ spin_lock_irqsave(&ci->lock, flags);
+ ci->vbus_active = on;
+ if (ci->driver)
+ gadget_ready = 1;
+ spin_unlock_irqrestore(&ci->lock, flags);
+ if (gadget_ready)
+ ci_hdrc_gadget_connect(&ci->gadget, on);
return 0;
}
@@ -584,13 +660,26 @@ static struct otg_fsm_ops ci_otg_ops = {
int ci_otg_fsm_work(struct ci_hdrc *ci)
{
- /*
- * Don't do fsm transition for B device
- * when there is no gadget class driver
- */
- if (ci->fsm.id && !(ci->driver) &&
- ci->fsm.otg->state < OTG_STATE_A_IDLE)
- return 0;
+ if (ci->fsm.id && ci->fsm.otg->state < OTG_STATE_A_IDLE) {
+ unsigned long flags;
+
+ /* Charger detection */
+ spin_lock_irqsave(&ci->lock, flags);
+ if (ci->b_sess_valid_event) {
+ ci->b_sess_valid_event = false;
+ ci->vbus_active = ci->fsm.b_sess_vld;
+ spin_unlock_irqrestore(&ci->lock, flags);
+ ci_usb_charger_connect(ci, ci->fsm.b_sess_vld);
+ spin_lock_irqsave(&ci->lock, flags);
+ }
+ spin_unlock_irqrestore(&ci->lock, flags);
+ /*
+ * Don't do fsm transition for B device if gadget
+ * driver is not binded.
+ */
+ if (!ci->driver)
+ return 0;
+ }
pm_runtime_get_sync(ci->dev);
if (otg_statemachine(&ci->fsm)) {
@@ -612,10 +701,14 @@ int ci_otg_fsm_work(struct ci_hdrc *ci)
PORTSC_PP, 0);
hw_write_otgsc(ci, OTGSC_DPIS, OTGSC_DPIS);
hw_write_otgsc(ci, OTGSC_DPIE, OTGSC_DPIE);
+ /* FS termination override if needed */
+ ci->platdata->notify_event(ci,
+ CI_HDRC_IMX_TERM_SELECT_OVERRIDE_FS);
}
if (ci->id_event)
ci->id_event = false;
} else if (ci->fsm.otg->state == OTG_STATE_B_IDLE) {
+ ci->fsm.b_sess_vld = hw_read_otgsc(ci, OTGSC_BSV);
if (ci->fsm.b_sess_vld) {
ci->fsm.power_up = 0;
/*
@@ -624,7 +717,8 @@ int ci_otg_fsm_work(struct ci_hdrc *ci)
*/
ci_otg_queue_work(ci);
}
- } else if (ci->fsm.otg->state == OTG_STATE_A_HOST) {
+ } else if (ci->fsm.otg->state == OTG_STATE_A_HOST ||
+ ci->fsm.otg->state == OTG_STATE_A_WAIT_VFALL) {
pm_runtime_mark_last_busy(ci->dev);
pm_runtime_put_autosuspend(ci->dev);
return 0;
@@ -678,25 +772,16 @@ static void ci_otg_fsm_event(struct ci_hdrc *ci)
}
break;
case OTG_STATE_A_PERIPHERAL:
- if (intr_sts & USBi_SLI) {
- fsm->b_bus_suspend = 1;
+ if (intr_sts & USBi_SLI)
/*
* Init a timer to know how long this suspend
* will continue, if time out, indicates B no longer
* wants to be host role
*/
ci_otg_add_timer(ci, A_BIDL_ADIS);
- }
- if (intr_sts & USBi_URI)
+ if (intr_sts & (USBi_URI | USBi_PCI))
ci_otg_del_timer(ci, A_BIDL_ADIS);
-
- if (intr_sts & USBi_PCI) {
- if (fsm->b_bus_suspend == 1) {
- ci_otg_del_timer(ci, A_BIDL_ADIS);
- fsm->b_bus_suspend = 0;
- }
- }
break;
case OTG_STATE_A_SUSPEND:
if ((intr_sts & USBi_PCI) && !port_conn) {
@@ -713,6 +798,15 @@ static void ci_otg_fsm_event(struct ci_hdrc *ci)
case OTG_STATE_A_HOST:
if ((intr_sts & USBi_PCI) && !port_conn) {
fsm->b_conn = 0;
+ if (fsm->tst_maint) {
+ ci_otg_del_timer(ci, A_TST_MAINT);
+ if (fsm->otg_vbus_off) {
+ fsm->a_bus_req = 0;
+ fsm->a_bus_drop = 1;
+ fsm->otg_vbus_off = 0;
+ }
+ fsm->tst_maint = 0;
+ }
ci_otg_queue_work(ci);
}
break;
@@ -746,26 +840,36 @@ irqreturn_t ci_otg_fsm_irq(struct ci_hdrc *ci)
if (otg_int_src) {
if (otg_int_src & OTGSC_DPIS) {
hw_write_otgsc(ci, OTGSC_DPIS, OTGSC_DPIS);
- fsm->a_srp_det = 1;
- fsm->a_bus_drop = 0;
+ ci->platdata->notify_event(ci,
+ CI_HDRC_IMX_TERM_SELECT_OVERRIDE_OFF);
+ ci_otg_add_timer(ci, A_DP_END);
} else if (otg_int_src & OTGSC_IDIS) {
hw_write_otgsc(ci, OTGSC_IDIS, OTGSC_IDIS);
if (fsm->id == 0) {
fsm->a_bus_drop = 0;
fsm->a_bus_req = 1;
ci->id_event = true;
+ } else {
+ /*
+ * Disable term select override and data pulse
+ * for B device.
+ */
+ ci->platdata->notify_event(ci,
+ CI_HDRC_IMX_TERM_SELECT_OVERRIDE_OFF);
}
} else if (otg_int_src & OTGSC_BSVIS) {
hw_write_otgsc(ci, OTGSC_BSVIS, OTGSC_BSVIS);
- if (otgsc & OTGSC_BSV) {
- fsm->b_sess_vld = 1;
- ci_otg_del_timer(ci, B_SSEND_SRP);
- ci_otg_del_timer(ci, B_SRP_FAIL);
- fsm->b_ssend_srp = 0;
- } else {
+ if (!(otgsc & OTGSC_BSV) && fsm->b_sess_vld) {
+ ci->b_sess_valid_event = true;
fsm->b_sess_vld = 0;
if (fsm->id)
ci_otg_add_timer(ci, B_SSEND_SRP);
+ if (fsm->b_bus_req)
+ fsm->b_bus_req = 0;
+ if (fsm->otg_srp_reqd)
+ ci_otg_add_timer(ci, B_SRP_REQD);
+ } else {
+ ci->vbus_glitch_check_event = true;
}
} else if (otg_int_src & OTGSC_AVVIS) {
hw_write_otgsc(ci, OTGSC_AVVIS, OTGSC_AVVIS);
@@ -802,6 +906,7 @@ int ci_hdrc_otg_fsm_init(struct ci_hdrc *ci)
ci->otg.gadget = &ci->gadget;
ci->fsm.otg = &ci->otg;
ci->fsm.power_up = 1;
+ ci->fsm.hnp_polling = 1;
ci->fsm.id = hw_read_otgsc(ci, OTGSC_ID) ? 1 : 0;
ci->fsm.otg->state = OTG_STATE_UNDEFINED;
ci->fsm.ops = &ci_otg_ops;
@@ -844,5 +949,56 @@ int ci_hdrc_otg_fsm_init(struct ci_hdrc *ci)
void ci_hdrc_otg_fsm_remove(struct ci_hdrc *ci)
{
+ enum otg_fsm_timer i;
+
+ mutex_lock(&ci->fsm.lock);
+ ci->fsm.otg->state = OTG_STATE_UNDEFINED;
+ mutex_unlock(&ci->fsm.lock);
+
+ for (i = 0; i < NUM_OTG_FSM_TIMERS; i++)
+ otg_del_timer(&ci->fsm, i);
+
+ ci->enabled_otg_timer_bits = 0;
+
+ /* Turn off vbus if vbus is on */
+ if (ci->fsm.drv_vbus)
+ otg_drv_vbus(&ci->fsm, 0);
+
sysfs_remove_group(&ci->dev->kobj, &inputs_attr_group);
}
+
+/* Restart OTG fsm if resume from power lost */
+void ci_hdrc_otg_fsm_restart(struct ci_hdrc *ci)
+{
+ struct otg_fsm *fsm = &ci->fsm;
+ int id_status = fsm->id;
+
+ /* Update fsm if power lost in peripheral state */
+ if (ci->fsm.otg->state == OTG_STATE_B_PERIPHERAL) {
+ fsm->b_sess_vld = 0;
+ otg_statemachine(fsm);
+ }
+
+ hw_write_otgsc(ci, OTGSC_IDIE, OTGSC_IDIE);
+ hw_write_otgsc(ci, OTGSC_AVVIE, OTGSC_AVVIE);
+
+ /* Update fsm variables for restart */
+ fsm->id = hw_read_otgsc(ci, OTGSC_ID) ? 1 : 0;
+ if (fsm->id) {
+ fsm->b_ssend_srp =
+ hw_read_otgsc(ci, OTGSC_BSV) ? 0 : 1;
+ fsm->b_sess_vld =
+ hw_read_otgsc(ci, OTGSC_BSV) ? 1 : 0;
+ } else if (fsm->id != id_status) {
+ /* ID changes to be 0 */
+ fsm->a_bus_drop = 0;
+ fsm->a_bus_req = 1;
+ ci->id_event = true;
+ }
+
+ if (ci_hdrc_host_has_device(ci) &&
+ !hw_read(ci, OP_PORTSC, PORTSC_CCS))
+ fsm->b_conn = 0;
+
+ ci_otg_fsm_work(ci);
+}
diff --git a/drivers/usb/chipidea/otg_fsm.h b/drivers/usb/chipidea/otg_fsm.h
index 6366fe398ba6..ff77d2e1bb64 100644
--- a/drivers/usb/chipidea/otg_fsm.h
+++ b/drivers/usb/chipidea/otg_fsm.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2014 Freescale Semiconductor, Inc.
+ * Copyright (C) 2014-2015 Freescale Semiconductor, Inc.
*
* Author: Jun Li
*
@@ -25,7 +25,7 @@
* ->DC Electrical Timing
*/
/* Wait for VBUS Fall */
-#define TA_WAIT_VFALL (1000) /* a_wait_vfall: section 7.1.7
+#define TA_WAIT_VFALL (500) /* a_wait_vfall: section 7.1.7
* a_wait_vfall_tmr: section: 7.4.5.2
*/
/* Wait for B-Connect */
@@ -38,9 +38,13 @@
* TA_AIDL_BDIS: section 5.5, Table 5-1
*/
/* B-Idle to A-Disconnect */
-#define TA_BIDL_ADIS (500) /* TA_BIDL_ADIS: section 5.2.1
- * 500ms is used for B switch to host
- * for safe
+#define TA_BIDL_ADIS (160) /* TA_BIDL_ADIS: section 5.2.1
+ * 155ms ~ 200 ms
+ */
+
+#define TA_DP_END (200)
+#define TA_TST_MAINT (9900) /* OTG test device session maintain
+ * timer, 9.9s~10.1s
*/
/*
@@ -63,6 +67,14 @@
#define TB_SSEND_SRP (1500) /* minimum 1.5 sec, section:5.1.2 */
#define TB_AIDL_BDIS (20) /* 4ms ~ 150ms, section 5.2.1 */
+#define TB_SRP_REQD (2000) /* For otg_srp_reqd to start data
+ * pulse after A(PET) turn off v-bus
+ */
+
+#define TB_TST_SUSP (20) /* B-dev hand host role back to A-dev
+ * via suspend bus after set config.
+ * max: 100ms
+ */
#if IS_ENABLED(CONFIG_USB_OTG_FSM)
@@ -71,6 +83,7 @@ int ci_otg_fsm_work(struct ci_hdrc *ci);
irqreturn_t ci_otg_fsm_irq(struct ci_hdrc *ci);
void ci_hdrc_otg_fsm_start(struct ci_hdrc *ci);
void ci_hdrc_otg_fsm_remove(struct ci_hdrc *ci);
+void ci_hdrc_otg_fsm_restart(struct ci_hdrc *ci);
#else
@@ -99,6 +112,11 @@ static inline void ci_hdrc_otg_fsm_remove(struct ci_hdrc *ci)
}
+static inline void ci_hdrc_otg_fsm_restart(struct ci_hdrc *ci)
+{
+
+}
+
#endif
#endif /* __DRIVERS_USB_CHIPIDEA_OTG_FSM_H */
diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c
index e3a44bea7bb7..6afb31d99b0a 100644
--- a/drivers/usb/chipidea/udc.c
+++ b/drivers/usb/chipidea/udc.c
@@ -752,6 +752,11 @@ __acquires(ci->lock)
{
int retval;
+ if (ci_otg_is_fsm_mode(ci)) {
+ ci->fsm.otg_srp_reqd = 0;
+ ci->fsm.otg_hnp_reqd = 0;
+ }
+
spin_unlock(&ci->lock);
if (ci->gadget.speed != USB_SPEED_UNKNOWN)
usb_gadget_udc_reset(&ci->gadget, ci->driver);
@@ -875,7 +880,10 @@ __acquires(hwep->lock)
return -ENOMEM;
req->complete = isr_get_status_complete;
- req->length = 2;
+ if (setup->wIndex == OTG_STS_SELECTOR)
+ req->length = 1;
+ else
+ req->length = 2;
req->buf = kzalloc(req->length, gfp_flags);
if (req->buf == NULL) {
retval = -ENOMEM;
@@ -883,8 +891,16 @@ __acquires(hwep->lock)
}
if ((setup->bRequestType & USB_RECIP_MASK) == USB_RECIP_DEVICE) {
- *(u16 *)req->buf = (ci->remote_wakeup << 1) |
- ci->gadget.is_selfpowered;
+ if ((setup->wIndex == OTG_STS_SELECTOR) &&
+ ci_otg_is_fsm_mode(ci)) {
+ if (ci->gadget.host_request_flag)
+ *(u8 *)req->buf = HOST_REQUEST_FLAG;
+ else
+ *(u8 *)req->buf = 0;
+ } else {
+ *(u16 *)req->buf = (ci->remote_wakeup << 1) |
+ ci->gadget.is_selfpowered;
+ }
} else if ((setup->bRequestType & USB_RECIP_MASK) \
== USB_RECIP_ENDPOINT) {
dir = (le16_to_cpu(setup->wIndex) & USB_ENDPOINT_DIR_MASK) ?
@@ -1006,6 +1022,28 @@ static int otg_a_alt_hnp_support(struct ci_hdrc *ci)
return isr_setup_status_phase(ci);
}
+static int otg_srp_reqd(struct ci_hdrc *ci)
+{
+ if (ci_otg_is_fsm_mode(ci)) {
+ ci->fsm.otg_srp_reqd = 1;
+ return isr_setup_status_phase(ci);
+ } else {
+ return -ENOTSUPP;
+ }
+}
+
+static int otg_hnp_reqd(struct ci_hdrc *ci)
+{
+ if (ci_otg_is_fsm_mode(ci)) {
+ ci->fsm.otg_hnp_reqd = 1;
+ ci->fsm.b_bus_req = 1;
+ ci->gadget.host_request_flag = 1;
+ return isr_setup_status_phase(ci);
+ } else {
+ return -ENOTSUPP;
+ }
+}
+
/**
* isr_setup_packet_handler: setup packet handler
* @ci: UDC descriptor
@@ -1076,8 +1114,9 @@ __acquires(ci->lock)
type != (USB_DIR_IN|USB_RECIP_ENDPOINT) &&
type != (USB_DIR_IN|USB_RECIP_INTERFACE))
goto delegate;
- if (le16_to_cpu(req.wLength) != 2 ||
- le16_to_cpu(req.wValue) != 0)
+ if ((le16_to_cpu(req.wLength) != 2 &&
+ le16_to_cpu(req.wLength) != 1) ||
+ le16_to_cpu(req.wValue) != 0)
break;
err = isr_get_status_response(ci, &req);
break;
@@ -1128,6 +1167,12 @@ __acquires(ci->lock)
err = isr_setup_status_phase(
ci);
break;
+ case TEST_OTG_SRP_REQD:
+ err = otg_srp_reqd(ci);
+ break;
+ case TEST_OTG_HNP_REQD:
+ err = otg_hnp_reqd(ci);
+ break;
default:
break;
}
@@ -1538,27 +1583,19 @@ static int ci_udc_vbus_session(struct usb_gadget *_gadget, int is_active)
gadget_ready = 1;
spin_unlock_irqrestore(&ci->lock, flags);
- if (gadget_ready) {
- if (is_active) {
- pm_runtime_get_sync(&_gadget->dev);
- hw_device_reset(ci);
- hw_device_state(ci, ci->ep0out->qh.dma);
- usb_gadget_set_state(_gadget, USB_STATE_POWERED);
- usb_udc_vbus_handler(_gadget, true);
- } else {
- usb_udc_vbus_handler(_gadget, false);
- if (ci->driver)
- ci->driver->disconnect(&ci->gadget);
- hw_device_state(ci, 0);
- if (ci->platdata->notify_event)
- ci->platdata->notify_event(ci,
- CI_HDRC_CONTROLLER_STOPPED_EVENT);
- _gadget_stop_activity(&ci->gadget);
- pm_runtime_put_sync(&_gadget->dev);
- usb_gadget_set_state(_gadget, USB_STATE_NOTATTACHED);
- }
+ if (ci->usb_phy) {
+ /* Charger Detection */
+ ci_usb_charger_connect(ci, is_active);
+
+ if (is_active)
+ usb_phy_set_event(ci->usb_phy, USB_EVENT_VBUS);
+ else
+ usb_phy_set_event(ci->usb_phy, USB_EVENT_NONE);
}
+ if (gadget_ready)
+ ci_hdrc_gadget_connect(_gadget, is_active);
+
return 0;
}
@@ -1623,12 +1660,12 @@ static int ci_udc_pullup(struct usb_gadget *_gadget, int is_on)
if (ci_otg_is_fsm_mode(ci) || ci->role == CI_ROLE_HOST)
return 0;
- pm_runtime_get_sync(&ci->gadget.dev);
+ pm_runtime_get_sync(ci->dev);
if (is_on)
hw_write(ci, OP_USBCMD, USBCMD_RS, USBCMD_RS);
else
hw_write(ci, OP_USBCMD, USBCMD_RS, 0);
- pm_runtime_put_sync(&ci->gadget.dev);
+ pm_runtime_put_sync(ci->dev);
return 0;
}
@@ -1779,23 +1816,14 @@ static int ci_udc_start(struct usb_gadget *gadget,
ci->driver = driver;
/* Start otg fsm for B-device */
- if (ci_otg_is_fsm_mode(ci) && ci->fsm.id) {
- ci_hdrc_otg_fsm_start(ci);
+ if (ci_otg_is_fsm_mode(ci)) {
+ if (ci->fsm.id)
+ ci_hdrc_otg_fsm_start(ci);
return retval;
}
- pm_runtime_get_sync(&ci->gadget.dev);
- if (ci->vbus_active) {
- hw_device_reset(ci);
- } else {
- usb_udc_vbus_handler(&ci->gadget, false);
- pm_runtime_put_sync(&ci->gadget.dev);
- return retval;
- }
-
- retval = hw_device_state(ci, ci->ep0out->qh.dma);
- if (retval)
- pm_runtime_put_sync(&ci->gadget.dev);
+ if (ci->vbus_active)
+ ci_hdrc_gadget_connect(&ci->gadget, 1);
return retval;
}
@@ -1834,7 +1862,7 @@ static int ci_udc_stop(struct usb_gadget *gadget)
CI_HDRC_CONTROLLER_STOPPED_EVENT);
_gadget_stop_activity(&ci->gadget);
spin_lock_irqsave(&ci->lock, flags);
- pm_runtime_put(&ci->gadget.dev);
+ pm_runtime_put(ci->dev);
}
ci->driver = NULL;
@@ -1880,6 +1908,9 @@ static irqreturn_t udc_irq(struct ci_hdrc *ci)
if (USBi_PCI & intr) {
ci->gadget.speed = hw_port_is_high_speed(ci) ?
USB_SPEED_HIGH : USB_SPEED_FULL;
+ if (ci->usb_phy)
+ usb_phy_set_event(ci->usb_phy,
+ USB_EVENT_ENUMERATED);
if (ci->suspended) {
if (ci->driver->resume) {
spin_unlock(&ci->lock);
@@ -1966,9 +1997,6 @@ static int udc_start(struct ci_hdrc *ci)
if (retval)
goto destroy_eps;
- pm_runtime_no_callbacks(&ci->gadget.dev);
- pm_runtime_enable(&ci->gadget.dev);
-
return retval;
destroy_eps:
@@ -1998,10 +2026,67 @@ void ci_hdrc_gadget_destroy(struct ci_hdrc *ci)
dma_pool_destroy(ci->qh_pool);
}
+int ci_usb_charger_connect(struct ci_hdrc *ci, int is_active)
+{
+ int ret = 0;
+
+ if (!(ci->platdata->flags & CI_HDRC_PHY_CHARGER_DETECTION))
+ return 0;
+
+ pm_runtime_get_sync(ci->dev);
+
+ if (ci->usb_phy->charger_detect) {
+ usb_phy_set_charger_state(ci->usb_phy, is_active ?
+ USB_CHARGER_PRESENT : USB_CHARGER_ABSENT);
+ } else if (ci->platdata->notify_event) {
+ ret = ci->platdata->notify_event(ci,
+ CI_HDRC_CONTROLLER_VBUS_EVENT);
+ schedule_work(&ci->usb_phy->chg_work);
+ }
+
+ pm_runtime_put_sync(ci->dev);
+
+ return ret;
+}
+
+/**
+ * ci_hdrc_gadget_connect: caller make sure gadget driver is binded
+ */
+void ci_hdrc_gadget_connect(struct usb_gadget *gadget, int is_active)
+{
+ struct ci_hdrc *ci = container_of(gadget, struct ci_hdrc, gadget);
+
+ if (is_active) {
+ pm_runtime_get_sync(ci->dev);
+ hw_device_reset(ci);
+ hw_device_state(ci, ci->ep0out->qh.dma);
+ usb_gadget_set_state(gadget, USB_STATE_POWERED);
+ usb_udc_vbus_handler(gadget, true);
+ } else {
+ usb_udc_vbus_handler(gadget, false);
+ if (ci->driver)
+ ci->driver->disconnect(gadget);
+ hw_device_state(ci, 0);
+ if (ci->platdata->notify_event)
+ ci->platdata->notify_event(ci,
+ CI_HDRC_CONTROLLER_STOPPED_EVENT);
+ _gadget_stop_activity(gadget);
+ pm_runtime_put_sync(ci->dev);
+ usb_gadget_set_state(gadget, USB_STATE_NOTATTACHED);
+ }
+}
+
static int udc_id_switch_for_device(struct ci_hdrc *ci)
{
- if (ci->is_otg)
- /* Clear and enable BSV irq */
+ if (!ci->is_otg)
+ return 0;
+
+ /*
+ * Clear and enable BSV irq for A-device switch to B-device
+ * (in otg fsm mode, means A_IDLE->B_DILE) due to ID change.
+ */
+ if (!ci_otg_is_fsm_mode(ci) ||
+ ci->fsm.otg->state == OTG_STATE_A_IDLE)
hw_write_otgsc(ci, OTGSC_BSVIS | OTGSC_BSVIE,
OTGSC_BSVIS | OTGSC_BSVIE);
@@ -2010,16 +2095,59 @@ static int udc_id_switch_for_device(struct ci_hdrc *ci)
static void udc_id_switch_for_host(struct ci_hdrc *ci)
{
+ if (!ci->is_otg)
+ return;
+
/*
- * host doesn't care B_SESSION_VALID event
- * so clear and disbale BSV irq
+ * Clear and disbale BSV irq for B-device switch to A-device
+ * (in otg fsm mode, means B_IDLE->A_IDLE) due to ID change.
*/
- if (ci->is_otg)
+ if (!ci_otg_is_fsm_mode(ci) ||
+ ci->fsm.otg->state == OTG_STATE_B_IDLE ||
+ ci->fsm.otg->state == OTG_STATE_UNDEFINED)
hw_write_otgsc(ci, OTGSC_BSVIE | OTGSC_BSVIS, OTGSC_BSVIS);
ci->vbus_active = 0;
}
+static void udc_suspend_for_power_lost(struct ci_hdrc *ci)
+{
+ /*
+ * Set OP_ENDPTLISTADDR to be non-zero for
+ * checking if controller resume from power lost
+ * in non-host mode.
+ */
+ if (hw_read(ci, OP_ENDPTLISTADDR, ~0) == 0)
+ hw_write(ci, OP_ENDPTLISTADDR, ~0, ~0);
+}
+
+/* Power lost with device mode */
+static void udc_resume_from_power_lost(struct ci_hdrc *ci)
+{
+ if (ci->is_otg)
+ hw_write_otgsc(ci, OTGSC_BSVIS | OTGSC_BSVIE,
+ OTGSC_BSVIS | OTGSC_BSVIE);
+}
+
+static void udc_suspend(struct ci_hdrc *ci)
+{
+ udc_suspend_for_power_lost(ci);
+
+ if (ci->driver && ci->vbus_active &&
+ (ci->gadget.state != USB_STATE_SUSPENDED))
+ usb_gadget_disconnect(&ci->gadget);
+}
+
+static void udc_resume(struct ci_hdrc *ci, bool power_lost)
+{
+ if (power_lost) {
+ udc_resume_from_power_lost(ci);
+ } else {
+ if (ci->driver && ci->vbus_active)
+ usb_gadget_connect(&ci->gadget);
+ }
+}
+
/**
* ci_hdrc_gadget_init - initialize device related bits
* ci: the controller
@@ -2041,6 +2169,8 @@ int ci_hdrc_gadget_init(struct ci_hdrc *ci)
rdrv->start = udc_id_switch_for_device;
rdrv->stop = udc_id_switch_for_host;
rdrv->irq = udc_irq;
+ rdrv->suspend = udc_suspend;
+ rdrv->resume = udc_resume;
rdrv->name = "gadget";
ret = udc_start(ci);
diff --git a/drivers/usb/chipidea/udc.h b/drivers/usb/chipidea/udc.h
index 2ecd1174d66c..7b7622a68b5f 100644
--- a/drivers/usb/chipidea/udc.h
+++ b/drivers/usb/chipidea/udc.h
@@ -85,6 +85,8 @@ struct ci_hw_req {
int ci_hdrc_gadget_init(struct ci_hdrc *ci);
void ci_hdrc_gadget_destroy(struct ci_hdrc *ci);
+int ci_usb_charger_connect(struct ci_hdrc *ci, int is_active);
+void ci_hdrc_gadget_connect(struct usb_gadget *gadget, int is_active);
#else
@@ -98,6 +100,17 @@ static inline void ci_hdrc_gadget_destroy(struct ci_hdrc *ci)
}
+static inline int ci_usb_charger_connect(struct ci_hdrc *ci, int is_active)
+{
+ return 0;
+}
+
+static inline void ci_hdrc_gadget_connect(struct usb_gadget *gadget,
+ int is_active)
+{
+
+}
+
#endif
#endif /* __DRIVERS_USB_CHIPIDEA_UDC_H */
diff --git a/drivers/usb/chipidea/usbmisc_imx.c b/drivers/usb/chipidea/usbmisc_imx.c
index b7477fd4443a..bb45161f5c05 100644
--- a/drivers/usb/chipidea/usbmisc_imx.c
+++ b/drivers/usb/chipidea/usbmisc_imx.c
@@ -1,5 +1,6 @@
/*
- * Copyright 2012 Freescale Semiconductor, Inc.
+ * Copyright 2012-2016 Freescale Semiconductor, Inc.
+ * Copyright 2017 NXP
*
* The code contained herein is licensed under the GNU General Public
* License. You may obtain a copy of the GNU General Public License
@@ -14,6 +15,8 @@
#include <linux/err.h>
#include <linux/io.h>
#include <linux/delay.h>
+#include <linux/regmap.h>
+#include <linux/regulator/consumer.h>
#include "ci_hdrc_imx.h"
@@ -69,11 +72,24 @@
#define MX6_BM_NON_BURST_SETTING BIT(1)
#define MX6_BM_OVER_CUR_DIS BIT(7)
#define MX6_BM_OVER_CUR_POLARITY BIT(8)
+#define MX6_BM_PRW_POLARITY BIT(9)
#define MX6_BM_WAKEUP_ENABLE BIT(10)
+#define MX6_BM_UTMI_ON_CLOCK BIT(13)
#define MX6_BM_ID_WAKEUP BIT(16)
#define MX6_BM_VBUS_WAKEUP BIT(17)
#define MX6SX_BM_DPDM_WAKEUP_EN BIT(29)
#define MX6_BM_WAKEUP_INTR BIT(31)
+
+#define MX6_USB_HSIC_CTRL_OFFSET 0x10
+/* Send resume signal without 480Mhz PHY clock */
+#define MX6SX_BM_HSIC_AUTO_RESUME BIT(23)
+/* set before portsc.suspendM = 1 */
+#define MX6_BM_HSIC_DEV_CONN BIT(21)
+/* HSIC enable */
+#define MX6_BM_HSIC_EN BIT(12)
+/* Force HSIC module 480M clock on, even when in Host is in suspend mode */
+#define MX6_BM_HSIC_CLK_ON BIT(11)
+
#define MX6_USB_OTG1_PHY_CTRL 0x18
/* For imx6dql, it is host-only controller, for later imx6, it is otg's */
#define MX6_USB_OTG2_PHY_CTRL 0x1c
@@ -86,12 +102,65 @@
#define VF610_OVER_CUR_DIS BIT(7)
#define MX7D_USBNC_USB_CTRL2 0x4
+/* The default DM/DP value is pull-down */
+#define MX7D_USBNC_USB_CTRL2_DM_OVERRIDE_EN BIT(15)
+#define MX7D_USBNC_USB_CTRL2_DM_OVERRIDE_VAL BIT(14)
+#define MX7D_USBNC_USB_CTRL2_DP_OVERRIDE_EN BIT(13)
+#define MX7D_USBNC_USB_CTRL2_DP_OVERRIDE_VAL BIT(12)
+#define MX7D_USBNC_USB_CTRL2_DP_DM_MASK (BIT(12) | BIT(13) | \
+ BIT(14) | BIT(15))
+#define MX7D_USBNC_USB_CTRL2_OPMODE_OVERRIDE_EN BIT(8)
+#define MX7D_USBNC_USB_CTRL2_OPMODE_OVERRIDE_MASK (BIT(7) | BIT(6))
+#define MX7D_USBNC_USB_CTRL2_OPMODE(v) (v << 6)
+#define MX7D_USBNC_USB_CTRL2_OPMODE_NON_DRIVING MX7D_USBNC_USB_CTRL2_OPMODE(1)
+#define MX7D_USBNC_USB_CTRL2_TERMSEL_OVERRIDE_EN BIT(5)
+#define MX7D_USBNC_USB_CTRL2_TERMSEL_OVERRIDE_VAL BIT(4)
+#define MX7D_USBNC_AUTO_RESUME BIT(2)
+
#define MX7D_USB_VBUS_WAKEUP_SOURCE_MASK 0x3
#define MX7D_USB_VBUS_WAKEUP_SOURCE(v) (v << 0)
#define MX7D_USB_VBUS_WAKEUP_SOURCE_VBUS MX7D_USB_VBUS_WAKEUP_SOURCE(0)
#define MX7D_USB_VBUS_WAKEUP_SOURCE_AVALID MX7D_USB_VBUS_WAKEUP_SOURCE(1)
#define MX7D_USB_VBUS_WAKEUP_SOURCE_BVALID MX7D_USB_VBUS_WAKEUP_SOURCE(2)
#define MX7D_USB_VBUS_WAKEUP_SOURCE_SESS_END MX7D_USB_VBUS_WAKEUP_SOURCE(3)
+#define MX7D_USB_TERMSEL_OVERRIDE BIT(4)
+#define MX7D_USB_TERMSEL_OVERRIDE_EN BIT(5)
+
+#define MX7D_USB_OTG_PHY_CFG1 0x30
+#define TXPREEMPAMPTUNE0_BIT 28
+#define TXPREEMPAMPTUNE0_MASK (3 << 28)
+#define TXVREFTUNE0_BIT 20
+#define TXVREFTUNE0_MASK (0xf << 20)
+
+#define MX7D_USB_OTG_PHY_CFG2_CHRG_DCDENB BIT(3)
+#define MX7D_USB_OTG_PHY_CFG2_CHRG_VDATSRCENB0 BIT(2)
+#define MX7D_USB_OTG_PHY_CFG2_CHRG_VDATDETENB0 BIT(1)
+#define MX7D_USB_OTG_PHY_CFG2_CHRG_CHRGSEL BIT(0)
+#define MX7D_USB_OTG_PHY_CFG2 0x34
+
+#define MX7D_USB_OTG_PHY_STATUS 0x3c
+#define MX7D_USB_OTG_PHY_STATUS_CHRGDET BIT(29)
+#define MX7D_USB_OTG_PHY_STATUS_VBUS_VLD BIT(3)
+#define MX7D_USB_OTG_PHY_STATUS_LINE_STATE1 BIT(1)
+#define MX7D_USB_OTG_PHY_STATUS_LINE_STATE0 BIT(0)
+
+#define ANADIG_ANA_MISC0 0x150
+#define ANADIG_ANA_MISC0_SET 0x154
+#define ANADIG_ANA_MISC0_CLK_DELAY(x) ((x >> 26) & 0x7)
+
+#define ANADIG_USB1_CHRG_DETECT_SET 0x1b4
+#define ANADIG_USB1_CHRG_DETECT_CLR 0x1b8
+#define ANADIG_USB1_CHRG_DETECT_EN_B BIT(20)
+#define ANADIG_USB1_CHRG_DETECT_CHK_CHRG_B BIT(19)
+#define ANADIG_USB1_CHRG_DETECT_CHK_CONTACT BIT(18)
+
+#define ANADIG_USB1_VBUS_DET_STAT 0x1c0
+#define ANADIG_USB1_VBUS_DET_STAT_VBUS_VALID BIT(3)
+
+#define ANADIG_USB1_CHRG_DET_STAT 0x1d0
+#define ANADIG_USB1_CHRG_DET_STAT_DM_STATE BIT(2)
+#define ANADIG_USB1_CHRG_DET_STAT_CHRG_DETECTED BIT(1)
+#define ANADIG_USB1_CHRG_DET_STAT_PLUG_CONTACT BIT(0)
struct usbmisc_ops {
/* It's called once when probe a usb device */
@@ -100,14 +169,28 @@ struct usbmisc_ops {
int (*post)(struct imx_usbmisc_data *data);
/* It's called when we need to enable/disable usb wakeup */
int (*set_wakeup)(struct imx_usbmisc_data *data, bool enabled);
+ /* usb charger detection */
+ int (*charger_detection)(struct imx_usbmisc_data *data);
+ /* It's called when system resume from usb power lost */
+ int (*power_lost_check)(struct imx_usbmisc_data *data);
+ /* It's called before setting portsc.suspendM */
+ int (*hsic_set_connect)(struct imx_usbmisc_data *data);
+ /* It's called during suspend/resume */
+ int (*hsic_set_clk)(struct imx_usbmisc_data *data, bool enabled);
+ /* override UTMI termination select */
+ int (*term_select_override)(struct imx_usbmisc_data *data,
+ bool enable, int val);
};
struct imx_usbmisc {
void __iomem *base;
spinlock_t lock;
const struct usbmisc_ops *ops;
+ struct mutex mutex;
};
+static struct regulator *vbus_wakeup_reg;
+
static inline bool is_imx53_usbmisc(struct imx_usbmisc_data *data);
static int usbmisc_imx25_init(struct imx_usbmisc_data *data)
@@ -297,15 +380,86 @@ static int usbmisc_imx53_init(struct imx_usbmisc_data *data)
return 0;
}
+static int usbmisc_imx6_hsic_set_connect(struct imx_usbmisc_data *data)
+{
+ unsigned long flags;
+ u32 val, offset;
+ struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev);
+ int ret = 0;
+
+ spin_lock_irqsave(&usbmisc->lock, flags);
+ if (data->index == 2 || data->index == 3) {
+ offset = (data->index - 2) * 4;
+ } else if (data->index == 0) {
+ /*
+ * For controllers later than imx7d (imx7d is included),
+ * each controller has its own non core register region.
+ * And the controllers before than imx7d, the 1st controller
+ * is not HSIC controller.
+ */
+ offset = 0;
+ } else {
+ dev_err(data->dev, "index is error for usbmisc\n");
+ offset = 0;
+ ret = -EINVAL;
+ }
+
+ val = readl(usbmisc->base + MX6_USB_HSIC_CTRL_OFFSET + offset);
+ if (!(val & MX6_BM_HSIC_DEV_CONN))
+ writel(val | MX6_BM_HSIC_DEV_CONN,
+ usbmisc->base + MX6_USB_HSIC_CTRL_OFFSET + offset);
+ spin_unlock_irqrestore(&usbmisc->lock, flags);
+
+ return ret;
+}
+
+static int usbmisc_imx6_hsic_set_clk(struct imx_usbmisc_data *data, bool on)
+{
+ unsigned long flags;
+ u32 val, offset;
+ struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev);
+ int ret = 0;
+
+ spin_lock_irqsave(&usbmisc->lock, flags);
+ if (data->index == 2 || data->index == 3) {
+ offset = (data->index - 2) * 4;
+ } else if (data->index == 0) {
+ offset = 0;
+ } else {
+ dev_err(data->dev, "index is error for usbmisc\n");
+ offset = 0;
+ ret = -EINVAL;
+ }
+
+ val = readl(usbmisc->base + MX6_USB_HSIC_CTRL_OFFSET + offset);
+ val |= MX6_BM_HSIC_EN | MX6_BM_HSIC_CLK_ON;
+ if (on)
+ val |= MX6_BM_HSIC_CLK_ON;
+ else
+ val &= ~MX6_BM_HSIC_CLK_ON;
+ writel(val, usbmisc->base + MX6_USB_HSIC_CTRL_OFFSET + offset);
+ spin_unlock_irqrestore(&usbmisc->lock, flags);
+
+ return 0;
+}
+
+static u32 imx6q_finalize_wakeup_setting(struct imx_usbmisc_data *data)
+{
+ if (data->available_role == USB_DR_MODE_PERIPHERAL)
+ return MX6_BM_VBUS_WAKEUP;
+ else if (data->available_role == USB_DR_MODE_OTG)
+ return MX6_BM_VBUS_WAKEUP | MX6_BM_ID_WAKEUP;
+
+ return 0;
+}
+
static int usbmisc_imx6q_set_wakeup
(struct imx_usbmisc_data *data, bool enabled)
{
struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev);
unsigned long flags;
- u32 val;
- u32 wakeup_setting = (MX6_BM_WAKEUP_ENABLE |
- MX6_BM_VBUS_WAKEUP | MX6_BM_ID_WAKEUP);
int ret = 0;
+ u32 val, wakeup_setting = MX6_BM_WAKEUP_ENABLE;
if (data->index > 3)
return -EINVAL;
@@ -313,15 +467,20 @@ static int usbmisc_imx6q_set_wakeup
spin_lock_irqsave(&usbmisc->lock, flags);
val = readl(usbmisc->base + data->index * 4);
if (enabled) {
- val |= wakeup_setting;
- writel(val, usbmisc->base + data->index * 4);
+ wakeup_setting |= imx6q_finalize_wakeup_setting(data);
+ writel(val | wakeup_setting, usbmisc->base + data->index * 4);
+ spin_unlock_irqrestore(&usbmisc->lock, flags);
+ if (vbus_wakeup_reg)
+ ret = regulator_enable(vbus_wakeup_reg);
} else {
if (val & MX6_BM_WAKEUP_INTR)
pr_debug("wakeup int at ci_hdrc.%d\n", data->index);
- val &= ~wakeup_setting;
- writel(val, usbmisc->base + data->index * 4);
+ wakeup_setting |= MX6_BM_VBUS_WAKEUP | MX6_BM_ID_WAKEUP;
+ writel(val & ~wakeup_setting, usbmisc->base + data->index * 4);
+ spin_unlock_irqrestore(&usbmisc->lock, flags);
+ if (vbus_wakeup_reg && regulator_is_enabled(vbus_wakeup_reg))
+ regulator_disable(vbus_wakeup_reg);
}
- spin_unlock_irqrestore(&usbmisc->lock, flags);
return ret;
}
@@ -330,7 +489,7 @@ static int usbmisc_imx6q_init(struct imx_usbmisc_data *data)
{
struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev);
unsigned long flags;
- u32 reg;
+ u32 reg, val;
if (data->index > 3)
return -EINVAL;
@@ -353,6 +512,27 @@ static int usbmisc_imx6q_init(struct imx_usbmisc_data *data)
writel(reg | MX6_BM_NON_BURST_SETTING,
usbmisc->base + data->index * 4);
+ /* For HSIC controller */
+ if (data->index == 2 || data->index == 3) {
+ val = readl(usbmisc->base + data->index * 4);
+ writel(val | MX6_BM_UTMI_ON_CLOCK,
+ usbmisc->base + data->index * 4);
+ val = readl(usbmisc->base + MX6_USB_HSIC_CTRL_OFFSET
+ + (data->index - 2) * 4);
+ val |= MX6_BM_HSIC_EN | MX6_BM_HSIC_CLK_ON;
+ writel(val, usbmisc->base + MX6_USB_HSIC_CTRL_OFFSET
+ + (data->index - 2) * 4);
+
+ /*
+ * Need to add delay to wait 24M OSC to be stable,
+ * It is board specific.
+ */
+ regmap_read(data->anatop, ANADIG_ANA_MISC0, &val);
+ /* 0 <= data->osc_clkgate_delay <= 7 */
+ if (data->osc_clkgate_delay > ANADIG_ANA_MISC0_CLK_DELAY(val))
+ regmap_write(data->anatop, ANADIG_ANA_MISC0_SET,
+ (data->osc_clkgate_delay) << 26);
+ }
spin_unlock_irqrestore(&usbmisc->lock, flags);
usbmisc_imx6q_set_wakeup(data, false);
@@ -369,9 +549,9 @@ static int usbmisc_imx6sx_init(struct imx_usbmisc_data *data)
usbmisc_imx6q_init(data);
+ spin_lock_irqsave(&usbmisc->lock, flags);
if (data->index == 0 || data->index == 1) {
reg = usbmisc->base + MX6_USB_OTG1_PHY_CTRL + data->index * 4;
- spin_lock_irqsave(&usbmisc->lock, flags);
/* Set vbus wakeup source as bvalid */
val = readl(reg);
writel(val | MX6SX_USB_VBUS_WAKEUP_SOURCE_BVALID, reg);
@@ -382,9 +562,18 @@ static int usbmisc_imx6sx_init(struct imx_usbmisc_data *data)
val = readl(usbmisc->base + data->index * 4);
writel(val & ~MX6SX_BM_DPDM_WAKEUP_EN,
usbmisc->base + data->index * 4);
- spin_unlock_irqrestore(&usbmisc->lock, flags);
}
+ /* For HSIC controller */
+ if (data->index == 2) {
+ val = readl(usbmisc->base + MX6_USB_HSIC_CTRL_OFFSET
+ + (data->index - 2) * 4);
+ val |= MX6SX_BM_HSIC_AUTO_RESUME;
+ writel(val, usbmisc->base + MX6_USB_HSIC_CTRL_OFFSET
+ + (data->index - 2) * 4);
+ }
+ spin_unlock_irqrestore(&usbmisc->lock, flags);
+
return 0;
}
@@ -414,16 +603,17 @@ static int usbmisc_imx7d_set_wakeup
struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev);
unsigned long flags;
u32 val;
- u32 wakeup_setting = (MX6_BM_WAKEUP_ENABLE |
- MX6_BM_VBUS_WAKEUP | MX6_BM_ID_WAKEUP);
+ u32 wakeup_setting = MX6_BM_WAKEUP_ENABLE;
spin_lock_irqsave(&usbmisc->lock, flags);
val = readl(usbmisc->base);
if (enabled) {
+ wakeup_setting |= imx6q_finalize_wakeup_setting(data);
writel(val | wakeup_setting, usbmisc->base);
} else {
if (val & MX6_BM_WAKEUP_INTR)
dev_dbg(data->dev, "wakeup int\n");
+ wakeup_setting |= MX6_BM_VBUS_WAKEUP | MX6_BM_ID_WAKEUP;
writel(val & ~wakeup_setting, usbmisc->base);
}
spin_unlock_irqrestore(&usbmisc->lock, flags);
@@ -448,12 +638,336 @@ static int usbmisc_imx7d_init(struct imx_usbmisc_data *data)
/* High active */
reg &= ~(MX6_BM_OVER_CUR_DIS | MX6_BM_OVER_CUR_POLARITY);
}
+
+ if (data->pwr_polarity)
+ reg |= MX6_BM_PRW_POLARITY;
+
writel(reg, usbmisc->base);
+ /* SoC non-burst setting */
+ reg = readl(usbmisc->base);
+ writel(reg | MX6_BM_NON_BURST_SETTING, usbmisc->base);
+
+ if (!data->hsic) {
+ reg = readl(usbmisc->base + MX7D_USBNC_USB_CTRL2);
+ reg &= ~MX7D_USB_VBUS_WAKEUP_SOURCE_MASK;
+ writel(reg | MX7D_USB_VBUS_WAKEUP_SOURCE_BVALID
+ | MX7D_USBNC_AUTO_RESUME,
+ usbmisc->base + MX7D_USBNC_USB_CTRL2);
+ /* PHY tuning for signal quality */
+ reg = readl(usbmisc->base + MX7D_USB_OTG_PHY_CFG1);
+ if (data->emp_curr_control && data->emp_curr_control <=
+ (TXPREEMPAMPTUNE0_MASK >> TXPREEMPAMPTUNE0_BIT)) {
+ reg &= ~TXPREEMPAMPTUNE0_MASK;
+ reg |= (data->emp_curr_control << TXPREEMPAMPTUNE0_BIT);
+ }
+
+ if (data->dc_vol_level_adjust && data->dc_vol_level_adjust <=
+ (TXVREFTUNE0_MASK >> TXVREFTUNE0_BIT)) {
+ reg &= ~TXVREFTUNE0_MASK;
+ reg |= (data->dc_vol_level_adjust << TXVREFTUNE0_BIT);
+ }
+
+ writel(reg, usbmisc->base + MX7D_USB_OTG_PHY_CFG1);
+ }
+
+ spin_unlock_irqrestore(&usbmisc->lock, flags);
+
+ usbmisc_imx7d_set_wakeup(data, false);
+
+ return 0;
+}
+
+static int usbmisc_imx7d_power_lost_check(struct imx_usbmisc_data *data)
+{
+ struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev);
+ unsigned long flags;
+ u32 val;
+
+ spin_lock_irqsave(&usbmisc->lock, flags);
+ val = readl(usbmisc->base);
+ spin_unlock_irqrestore(&usbmisc->lock, flags);
+ /*
+ * Here use a power on reset value to judge
+ * if the controller experienced a power lost
+ */
+ if (val == 0x30001000)
+ return 1;
+ else
+ return 0;
+}
+
+
+static int usbmisc_imx6sx_power_lost_check(struct imx_usbmisc_data *data)
+{
+ struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev);
+ unsigned long flags;
+ u32 val;
+
+ spin_lock_irqsave(&usbmisc->lock, flags);
+ val = readl(usbmisc->base + data->index * 4);
+ spin_unlock_irqrestore(&usbmisc->lock, flags);
+ /*
+ * Here use a power on reset value to judge
+ * if the controller experienced a power lost
+ */
+ if (val == 0x30001000)
+ return 1;
+ else
+ return 0;
+}
+
+static int imx7d_charger_secondary_detection(struct imx_usbmisc_data *data)
+{
+ struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev);
+ struct usb_phy *usb_phy = data->usb_phy;
+ int val, bak_val;
+
+ /* Pull up DP */
+ val = readl(usbmisc->base + MX7D_USBNC_USB_CTRL2);
+ bak_val = val;
+ val &= ~MX7D_USBNC_USB_CTRL2_DP_DM_MASK;
+ val |= MX7D_USBNC_USB_CTRL2_DM_OVERRIDE_EN |
+ MX7D_USBNC_USB_CTRL2_DP_OVERRIDE_EN;
+ val |= MX7D_USBNC_USB_CTRL2_TERMSEL_OVERRIDE_EN |
+ MX7D_USBNC_USB_CTRL2_TERMSEL_OVERRIDE_VAL;
+ writel(val, usbmisc->base + MX7D_USBNC_USB_CTRL2);
+
+ msleep(80);
+
+ val = readl(usbmisc->base + MX7D_USB_OTG_PHY_STATUS);
+ if (val & MX7D_USB_OTG_PHY_STATUS_LINE_STATE1) {
+ dev_dbg(data->dev, "It is a dedicate charging port\n");
+ usb_phy->chg_type = DCP_TYPE;
+ } else {
+ dev_dbg(data->dev, "It is a charging downstream port\n");
+ usb_phy->chg_type = CDP_TYPE;
+ }
+ writel(bak_val, usbmisc->base + MX7D_USBNC_USB_CTRL2);
+
+ return 0;
+}
+
+static void imx7_disable_charger_detector(struct imx_usbmisc_data *data)
+{
+ struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev);
+ unsigned long flags;
+ u32 val;
+
+ spin_lock_irqsave(&usbmisc->lock, flags);
+ val = readl(usbmisc->base + MX7D_USB_OTG_PHY_CFG2);
+ val &= ~(MX7D_USB_OTG_PHY_CFG2_CHRG_DCDENB |
+ MX7D_USB_OTG_PHY_CFG2_CHRG_VDATSRCENB0 |
+ MX7D_USB_OTG_PHY_CFG2_CHRG_VDATDETENB0 |
+ MX7D_USB_OTG_PHY_CFG2_CHRG_CHRGSEL);
+ writel(val, usbmisc->base + MX7D_USB_OTG_PHY_CFG2);
+
+ /* Set OPMODE to be 2'b00 and disable its override */
+ val = readl(usbmisc->base + MX7D_USBNC_USB_CTRL2);
+ val &= ~MX7D_USBNC_USB_CTRL2_OPMODE_OVERRIDE_MASK;
+ writel(val, usbmisc->base + MX7D_USBNC_USB_CTRL2);
+
+ val = readl(usbmisc->base + MX7D_USBNC_USB_CTRL2);
+ writel(val & ~MX7D_USBNC_USB_CTRL2_OPMODE_OVERRIDE_EN,
+ usbmisc->base + MX7D_USBNC_USB_CTRL2);
+ spin_unlock_irqrestore(&usbmisc->lock, flags);
+}
+
+static int imx7d_charger_data_contact_detect(struct imx_usbmisc_data *data)
+{
+ struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev);
+ unsigned long flags;
+ u32 val;
+ int i, data_pin_contact_count = 0;
+
+ spin_lock_irqsave(&usbmisc->lock, flags);
+
+ /* check if vbus is valid */
+ val = readl(usbmisc->base + MX7D_USB_OTG_PHY_STATUS);
+ if (!(val & MX7D_USB_OTG_PHY_STATUS_VBUS_VLD)) {
+ dev_err(data->dev, "vbus is error\n");
+ spin_unlock_irqrestore(&usbmisc->lock, flags);
+ return -EINVAL;
+ }
+
+ /*
+ * - Do not check whether a charger is connected to the USB port
+ * - Check whether the USB plug has been in contact with each other
+ */
+ val = readl(usbmisc->base + MX7D_USB_OTG_PHY_CFG2);
+ writel(val | MX7D_USB_OTG_PHY_CFG2_CHRG_DCDENB,
+ usbmisc->base + MX7D_USB_OTG_PHY_CFG2);
+
+ spin_unlock_irqrestore(&usbmisc->lock, flags);
+
+ /* Check if plug is connected */
+ for (i = 0; i < 100; i = i + 1) {
+ val = readl(usbmisc->base + MX7D_USB_OTG_PHY_STATUS);
+ if (!(val & MX7D_USB_OTG_PHY_STATUS_LINE_STATE0)) {
+ if (data_pin_contact_count++ > 5)
+ /* Data pin makes contact */
+ break;
+ else
+ usleep_range(5000, 10000);
+ } else {
+ data_pin_contact_count = 0;
+ usleep_range(5000, 6000);
+ }
+ }
+
+ if (i == 100) {
+ dev_err(data->dev,
+ "VBUS is coming from a dedicated power supply.\n");
+ imx7_disable_charger_detector(data);
+ return -ENXIO;
+ }
+
+ return 0;
+}
+
+static int imx7d_charger_primary_detection(struct imx_usbmisc_data *data)
+{
+ struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev);
+ struct usb_phy *usb_phy = data->usb_phy;
+ unsigned long flags;
+ u32 val;
+ int ret;
+
+ ret = imx7d_charger_data_contact_detect(data);
+ if (ret)
+ return ret;
+
+ spin_lock_irqsave(&usbmisc->lock, flags);
+ /* Set OPMODE to be non-driving mode */
+ val = readl(usbmisc->base + MX7D_USBNC_USB_CTRL2);
+ val &= ~MX7D_USBNC_USB_CTRL2_OPMODE_OVERRIDE_MASK;
+ val |= MX7D_USBNC_USB_CTRL2_OPMODE_NON_DRIVING;
+ writel(val, usbmisc->base + MX7D_USBNC_USB_CTRL2);
+
+ val = readl(usbmisc->base + MX7D_USBNC_USB_CTRL2);
+ writel(val | MX7D_USBNC_USB_CTRL2_OPMODE_OVERRIDE_EN,
+ usbmisc->base + MX7D_USBNC_USB_CTRL2);
+
+ /*
+ * - Do check whether a charger is connected to the USB port
+ * - Do not Check whether the USB plug has been in contact with
+ * each other
+ */
+ val = readl(usbmisc->base + MX7D_USB_OTG_PHY_CFG2);
+ writel(val | MX7D_USB_OTG_PHY_CFG2_CHRG_VDATSRCENB0 |
+ MX7D_USB_OTG_PHY_CFG2_CHRG_VDATDETENB0,
+ usbmisc->base + MX7D_USB_OTG_PHY_CFG2);
+ spin_unlock_irqrestore(&usbmisc->lock, flags);
+
+ usleep_range(1000, 2000);
+
+ /* Check if it is a charger */
+ val = readl(usbmisc->base + MX7D_USB_OTG_PHY_STATUS);
+ if (!(val & MX7D_USB_OTG_PHY_STATUS_CHRGDET)) {
+ dev_dbg(data->dev, "It is a stardard downstream port\n");
+ usb_phy->chg_type = SDP_TYPE;
+ }
+
+ imx7_disable_charger_detector(data);
+
+ return 0;
+}
+
+static int imx7d_charger_detection(struct imx_usbmisc_data *data)
+{
+ struct usb_phy *usb_phy = data->usb_phy;
+ int ret;
+
+ ret = imx7d_charger_primary_detection(data);
+ if (ret)
+ return ret;
+
+ if (usb_phy->chg_type != SDP_TYPE)
+ ret = imx7d_charger_secondary_detection(data);
+
+ return ret;
+}
+
+static int usbmisc_term_select_override(struct imx_usbmisc_data *data,
+ bool enable, int val)
+{
+ struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev);
+ unsigned long flags;
+ u32 reg;
+
+ spin_lock_irqsave(&usbmisc->lock, flags);
+
reg = readl(usbmisc->base + MX7D_USBNC_USB_CTRL2);
- reg &= ~MX7D_USB_VBUS_WAKEUP_SOURCE_MASK;
- writel(reg | MX7D_USB_VBUS_WAKEUP_SOURCE_BVALID,
- usbmisc->base + MX7D_USBNC_USB_CTRL2);
+ if (enable) {
+ if (val)
+ writel(reg | MX7D_USB_TERMSEL_OVERRIDE,
+ usbmisc->base + MX7D_USBNC_USB_CTRL2);
+ else
+ writel(reg & ~MX7D_USB_TERMSEL_OVERRIDE,
+ usbmisc->base + MX7D_USBNC_USB_CTRL2);
+
+ reg = readl(usbmisc->base + MX7D_USBNC_USB_CTRL2);
+ writel(reg | MX7D_USB_TERMSEL_OVERRIDE_EN,
+ usbmisc->base + MX7D_USBNC_USB_CTRL2);
+ } else {
+ writel(reg & ~MX7D_USB_TERMSEL_OVERRIDE_EN,
+ usbmisc->base + MX7D_USBNC_USB_CTRL2);
+ }
+
+ spin_unlock_irqrestore(&usbmisc->lock, flags);
+
+ return 0;
+}
+
+static int usbmisc_imx7ulp_init(struct imx_usbmisc_data *data)
+{
+ struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev);
+ unsigned long flags;
+ u32 reg;
+
+ if (data->index >= 1)
+ return -EINVAL;
+
+ spin_lock_irqsave(&usbmisc->lock, flags);
+ reg = readl(usbmisc->base);
+ if (data->disable_oc) {
+ reg |= MX6_BM_OVER_CUR_DIS;
+ } else if (data->oc_polarity == 1) {
+ /* High active */
+ reg &= ~(MX6_BM_OVER_CUR_DIS | MX6_BM_OVER_CUR_POLARITY);
+ }
+
+ if (data->pwr_polarity)
+ reg |= MX6_BM_PRW_POLARITY;
+
+ writel(reg, usbmisc->base);
+
+ /* SoC non-burst setting */
+ reg = readl(usbmisc->base);
+ writel(reg | MX6_BM_NON_BURST_SETTING, usbmisc->base);
+
+ if (data->hsic) {
+ reg = readl(usbmisc->base);
+ writel(reg | MX6_BM_UTMI_ON_CLOCK, usbmisc->base);
+
+ reg = readl(usbmisc->base + MX6_USB_HSIC_CTRL_OFFSET);
+ reg |= MX6_BM_HSIC_EN | MX6_BM_HSIC_CLK_ON;
+ writel(reg, usbmisc->base + MX6_USB_HSIC_CTRL_OFFSET);
+
+ /*
+ * For non-HSIC controller, the autoresume is enabled
+ * at MXS PHY driver (usbphy_ctrl bit18).
+ */
+ reg = readl(usbmisc->base + MX7D_USBNC_USB_CTRL2);
+ writel(reg | MX7D_USBNC_AUTO_RESUME,
+ usbmisc->base + MX7D_USBNC_USB_CTRL2);
+ } else {
+ reg = readl(usbmisc->base + MX7D_USBNC_USB_CTRL2);
+ reg &= ~MX7D_USB_VBUS_WAKEUP_SOURCE_MASK;
+ writel(reg | MX7D_USB_VBUS_WAKEUP_SOURCE_BVALID,
+ usbmisc->base + MX7D_USBNC_USB_CTRL2);
+ }
+
spin_unlock_irqrestore(&usbmisc->lock, flags);
usbmisc_imx7d_set_wakeup(data, false);
@@ -481,6 +995,8 @@ static const struct usbmisc_ops imx53_usbmisc_ops = {
static const struct usbmisc_ops imx6q_usbmisc_ops = {
.set_wakeup = usbmisc_imx6q_set_wakeup,
.init = usbmisc_imx6q_init,
+ .hsic_set_connect = usbmisc_imx6_hsic_set_connect,
+ .hsic_set_clk = usbmisc_imx6_hsic_set_clk,
};
static const struct usbmisc_ops vf610_usbmisc_ops = {
@@ -490,11 +1006,25 @@ static const struct usbmisc_ops vf610_usbmisc_ops = {
static const struct usbmisc_ops imx6sx_usbmisc_ops = {
.set_wakeup = usbmisc_imx6q_set_wakeup,
.init = usbmisc_imx6sx_init,
+ .power_lost_check = usbmisc_imx6sx_power_lost_check,
+ .hsic_set_connect = usbmisc_imx6_hsic_set_connect,
+ .hsic_set_clk = usbmisc_imx6_hsic_set_clk,
};
static const struct usbmisc_ops imx7d_usbmisc_ops = {
.init = usbmisc_imx7d_init,
.set_wakeup = usbmisc_imx7d_set_wakeup,
+ .power_lost_check = usbmisc_imx7d_power_lost_check,
+ .charger_detection = imx7d_charger_detection,
+ .term_select_override = usbmisc_term_select_override,
+};
+
+static const struct usbmisc_ops imx7ulp_usbmisc_ops = {
+ .init = usbmisc_imx7ulp_init,
+ .set_wakeup = usbmisc_imx7d_set_wakeup,
+ .power_lost_check = usbmisc_imx7d_power_lost_check,
+ .hsic_set_connect = usbmisc_imx6_hsic_set_connect,
+ .hsic_set_clk = usbmisc_imx6_hsic_set_clk,
};
static inline bool is_imx53_usbmisc(struct imx_usbmisc_data *data)
@@ -546,6 +1076,97 @@ int imx_usbmisc_set_wakeup(struct imx_usbmisc_data *data, bool enabled)
}
EXPORT_SYMBOL_GPL(imx_usbmisc_set_wakeup);
+int imx_usbmisc_charger_detection(struct imx_usbmisc_data *data, bool connect)
+{
+ struct imx_usbmisc *usbmisc;
+ struct usb_phy *usb_phy;
+ int ret = 0;
+
+ if (!data)
+ return -EINVAL;
+
+ usbmisc = dev_get_drvdata(data->dev);
+ usb_phy = data->usb_phy;
+ if (!usbmisc->ops->charger_detection)
+ return -ENOTSUPP;
+
+ mutex_lock(&usbmisc->mutex);
+ if (connect) {
+ ret = usbmisc->ops->charger_detection(data);
+ if (ret) {
+ dev_err(data->dev,
+ "Error occurs during detection: %d\n",
+ ret);
+ usb_phy->chg_state = USB_CHARGER_ABSENT;
+ } else {
+ usb_phy->chg_state = USB_CHARGER_PRESENT;
+ }
+ } else {
+ usb_phy->chg_state = USB_CHARGER_ABSENT;
+ usb_phy->chg_type = UNKNOWN_TYPE;
+ }
+ mutex_unlock(&usbmisc->mutex);
+ return ret;
+}
+EXPORT_SYMBOL_GPL(imx_usbmisc_charger_detection);
+
+int imx_usbmisc_power_lost_check(struct imx_usbmisc_data *data)
+{
+ struct imx_usbmisc *usbmisc;
+
+ if (!data)
+ return 0;
+
+ usbmisc = dev_get_drvdata(data->dev);
+ if (!usbmisc->ops->power_lost_check)
+ return 0;
+ return usbmisc->ops->power_lost_check(data);
+}
+EXPORT_SYMBOL_GPL(imx_usbmisc_power_lost_check);
+
+int imx_usbmisc_hsic_set_connect(struct imx_usbmisc_data *data)
+{
+ struct imx_usbmisc *usbmisc;
+
+ if (!data)
+ return 0;
+
+ usbmisc = dev_get_drvdata(data->dev);
+ if (!usbmisc->ops->hsic_set_connect || !data->hsic)
+ return 0;
+ return usbmisc->ops->hsic_set_connect(data);
+}
+EXPORT_SYMBOL_GPL(imx_usbmisc_hsic_set_connect);
+
+int imx_usbmisc_hsic_set_clk(struct imx_usbmisc_data *data, bool on)
+{
+ struct imx_usbmisc *usbmisc;
+
+ if (!data)
+ return 0;
+
+ usbmisc = dev_get_drvdata(data->dev);
+ if (!usbmisc->ops->hsic_set_clk || !data->hsic)
+ return 0;
+ return usbmisc->ops->hsic_set_clk(data, on);
+}
+EXPORT_SYMBOL_GPL(imx_usbmisc_hsic_set_clk);
+
+int imx_usbmisc_term_select_override(struct imx_usbmisc_data *data,
+ bool enable, int val)
+{
+ struct imx_usbmisc *usbmisc;
+
+ if (!data)
+ return 0;
+
+ usbmisc = dev_get_drvdata(data->dev);
+ if (!usbmisc->ops->term_select_override)
+ return 0;
+ return usbmisc->ops->term_select_override(data, enable, val);
+}
+EXPORT_SYMBOL_GPL(imx_usbmisc_term_select_override);
+
static const struct of_device_id usbmisc_imx_dt_ids[] = {
{
.compatible = "fsl,imx25-usbmisc",
@@ -587,6 +1208,10 @@ static const struct of_device_id usbmisc_imx_dt_ids[] = {
.compatible = "fsl,imx7d-usbmisc",
.data = &imx7d_usbmisc_ops,
},
+ {
+ .compatible = "fsl,imx7ulp-usbmisc",
+ .data = &imx7ulp_usbmisc_ops,
+ },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, usbmisc_imx_dt_ids);
@@ -606,6 +1231,7 @@ static int usbmisc_imx_probe(struct platform_device *pdev)
return -ENOMEM;
spin_lock_init(&data->lock);
+ mutex_init(&data->mutex);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
data->base = devm_ioremap_resource(&pdev->dev, res);
@@ -615,6 +1241,18 @@ static int usbmisc_imx_probe(struct platform_device *pdev)
data->ops = (const struct usbmisc_ops *)of_id->data;
platform_set_drvdata(pdev, data);
+ vbus_wakeup_reg = devm_regulator_get(&pdev->dev, "vbus-wakeup");
+ if (PTR_ERR(vbus_wakeup_reg) == -EPROBE_DEFER)
+ return -EPROBE_DEFER;
+ else if (PTR_ERR(vbus_wakeup_reg) == -ENODEV)
+ /* no vbus regualator is needed */
+ vbus_wakeup_reg = NULL;
+ else if (IS_ERR(vbus_wakeup_reg)) {
+ dev_err(&pdev->dev, "Getting regulator error: %ld\n",
+ PTR_ERR(vbus_wakeup_reg));
+ return PTR_ERR(vbus_wakeup_reg);
+ }
+
return 0;
}
diff --git a/drivers/usb/common/usb-otg-fsm.c b/drivers/usb/common/usb-otg-fsm.c
index b8fe31e409a5..1476c10c5a7c 100644
--- a/drivers/usb/common/usb-otg-fsm.c
+++ b/drivers/usb/common/usb-otg-fsm.c
@@ -75,6 +75,7 @@ static void otg_leave_state(struct otg_fsm *fsm, enum usb_otg_state old_state)
switch (old_state) {
case OTG_STATE_B_IDLE:
otg_del_timer(fsm, B_SE0_SRP);
+ otg_del_timer(fsm, B_SRP_FAIL);
fsm->b_se0_srp = 0;
fsm->adp_sns = 0;
fsm->adp_prb = 0;
@@ -92,6 +93,11 @@ static void otg_leave_state(struct otg_fsm *fsm, enum usb_otg_state old_state)
fsm->b_ase0_brst_tmout = 0;
break;
case OTG_STATE_B_HOST:
+ if (fsm->otg_hnp_reqd) {
+ fsm->otg_hnp_reqd = 0;
+ fsm->b_bus_req = 0;
+ }
+ fsm->a_conn = 0;
break;
case OTG_STATE_A_IDLE:
fsm->adp_prb = 0;
@@ -138,8 +144,10 @@ static void otg_hnp_polling_work(struct work_struct *work)
enum usb_otg_state state = fsm->otg->state;
u8 flag;
int retval;
+ struct usb_otg_descriptor *desc = NULL;
- if (state != OTG_STATE_A_HOST && state != OTG_STATE_B_HOST)
+ if ((state != OTG_STATE_A_HOST || !fsm->b_hnp_enable) &&
+ state != OTG_STATE_B_HOST)
return;
udev = usb_hub_find_child(fsm->otg->host->root_hub, 1);
@@ -149,6 +157,31 @@ static void otg_hnp_polling_work(struct work_struct *work)
return;
}
+ if (udev->state != USB_STATE_CONFIGURED) {
+ dev_dbg(&udev->dev, "the B dev is not resumed!\n");
+ schedule_delayed_work(&fsm->hnp_polling_work,
+ msecs_to_jiffies(T_HOST_REQ_POLL));
+ return;
+ }
+
+ /*
+ * Legacy otg test device does not support HNP polling,
+ * start HNP directly for legacy otg test device.
+ */
+ if (fsm->tst_maint &&
+ (__usb_get_extra_descriptor(udev->rawdescriptors[0],
+ le16_to_cpu(udev->config[0].desc.wTotalLength),
+ USB_DT_OTG, (void **) &desc) == 0)) {
+ /* shorter bLength of OTG 1.3 or earlier */
+ if (desc->bLength < 5) {
+ fsm->a_bus_req = 0;
+ fsm->tst_maint = 0;
+ otg_del_timer(fsm, A_TST_MAINT);
+ *fsm->host_req_flag = HOST_REQUEST_FLAG;
+ return;
+ }
+ }
+
*fsm->host_req_flag = 0;
/* Get host request flag from connected USB device */
retval = usb_control_msg(udev,
@@ -190,6 +223,11 @@ static void otg_hnp_polling_work(struct work_struct *work)
fsm->otg->host->b_hnp_enable = 1;
}
fsm->a_bus_req = 0;
+ if (fsm->tst_maint) {
+ fsm->tst_maint = 0;
+ fsm->otg_vbus_off = 0;
+ otg_del_timer(fsm, A_TST_MAINT);
+ }
} else if (state == OTG_STATE_B_HOST) {
fsm->b_bus_req = 0;
}
@@ -231,6 +269,10 @@ static int otg_set_state(struct otg_fsm *fsm, enum usb_otg_state new_state)
otg_start_adp_sns(fsm);
otg_set_protocol(fsm, PROTO_UNDEF);
otg_add_timer(fsm, B_SE0_SRP);
+ if (fsm->otg_hnp_reqd) {
+ fsm->otg_hnp_reqd = 0;
+ fsm->b_bus_req = 0;
+ }
break;
case OTG_STATE_B_SRP_INIT:
otg_start_pulse(fsm);
@@ -243,6 +285,7 @@ static int otg_set_state(struct otg_fsm *fsm, enum usb_otg_state new_state)
otg_loc_sof(fsm, 0);
otg_set_protocol(fsm, PROTO_GADGET);
otg_loc_conn(fsm, 1);
+ fsm->b_bus_req = 0;
break;
case OTG_STATE_B_WAIT_ACON:
otg_chrg_vbus(fsm, 0);
@@ -257,8 +300,6 @@ static int otg_set_state(struct otg_fsm *fsm, enum usb_otg_state new_state)
otg_loc_conn(fsm, 0);
otg_loc_sof(fsm, 1);
otg_set_protocol(fsm, PROTO_HOST);
- usb_bus_start_enum(fsm->otg->host,
- fsm->otg->host->otg_port);
otg_start_hnp_polling(fsm);
break;
case OTG_STATE_A_IDLE:
@@ -413,8 +454,7 @@ int otg_statemachine(struct otg_fsm *fsm)
case OTG_STATE_A_HOST:
if (fsm->id || fsm->a_bus_drop)
otg_set_state(fsm, OTG_STATE_A_WAIT_VFALL);
- else if ((!fsm->a_bus_req || fsm->a_suspend_req_inf) &&
- fsm->otg->host->b_hnp_enable)
+ else if (!fsm->a_bus_req || fsm->a_suspend_req_inf)
otg_set_state(fsm, OTG_STATE_A_SUSPEND);
else if (!fsm->b_conn)
otg_set_state(fsm, OTG_STATE_A_WAIT_BCON);
@@ -422,9 +462,9 @@ int otg_statemachine(struct otg_fsm *fsm)
otg_set_state(fsm, OTG_STATE_A_VBUS_ERR);
break;
case OTG_STATE_A_SUSPEND:
- if (!fsm->b_conn && fsm->otg->host->b_hnp_enable)
+ if (!fsm->b_conn && fsm->a_set_b_hnp_en)
otg_set_state(fsm, OTG_STATE_A_PERIPHERAL);
- else if (!fsm->b_conn && !fsm->otg->host->b_hnp_enable)
+ else if (!fsm->b_conn && !fsm->a_set_b_hnp_en)
otg_set_state(fsm, OTG_STATE_A_WAIT_BCON);
else if (fsm->a_bus_req || fsm->b_bus_resume)
otg_set_state(fsm, OTG_STATE_A_HOST);
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
index 5fcea1114e2f..745698feef07 100644
--- a/drivers/usb/core/hcd.c
+++ b/drivers/usb/core/hcd.c
@@ -2243,6 +2243,140 @@ int usb_hcd_get_frame_number (struct usb_device *udev)
}
/*-------------------------------------------------------------------------*/
+#ifdef CONFIG_USB_HCD_TEST_MODE
+
+static void usb_ehset_completion(struct urb *urb)
+{
+ struct completion *done = urb->context;
+
+ complete(done);
+}
+/*
+ * Allocate and initialize a control URB. This request will be used by the
+ * EHSET SINGLE_STEP_SET_FEATURE test in which the DATA and STATUS stages
+ * of the GetDescriptor request are sent 15 seconds after the SETUP stage.
+ * Return NULL if failed.
+ */
+static struct urb *request_single_step_set_feature_urb(
+ struct usb_device *udev,
+ void *dr,
+ void *buf,
+ struct completion *done
+) {
+ struct urb *urb;
+ struct usb_hcd *hcd = bus_to_hcd(udev->bus);
+ struct usb_host_endpoint *ep;
+
+ urb = usb_alloc_urb(0, GFP_KERNEL);
+ if (!urb)
+ return NULL;
+
+ urb->pipe = usb_rcvctrlpipe(udev, 0);
+ ep = (usb_pipein(urb->pipe) ? udev->ep_in : udev->ep_out)
+ [usb_pipeendpoint(urb->pipe)];
+ if (!ep) {
+ usb_free_urb(urb);
+ return NULL;
+ }
+
+ urb->ep = ep;
+ urb->dev = udev;
+ urb->setup_packet = (void *)dr;
+ urb->transfer_buffer = buf;
+ urb->transfer_buffer_length = USB_DT_DEVICE_SIZE;
+ urb->complete = usb_ehset_completion;
+ urb->status = -EINPROGRESS;
+ urb->actual_length = 0;
+ urb->transfer_flags = URB_DIR_IN;
+ usb_get_urb(urb);
+ atomic_inc(&urb->use_count);
+ atomic_inc(&urb->dev->urbnum);
+ urb->setup_dma = dma_map_single(
+ hcd->self.sysdev,
+ urb->setup_packet,
+ sizeof(struct usb_ctrlrequest),
+ DMA_TO_DEVICE);
+ urb->transfer_dma = dma_map_single(
+ hcd->self.sysdev,
+ urb->transfer_buffer,
+ urb->transfer_buffer_length,
+ DMA_FROM_DEVICE);
+ urb->context = done;
+ return urb;
+}
+
+int ehset_single_step_set_feature(struct usb_hcd *hcd, int port)
+{
+ int retval = -ENOMEM;
+ struct usb_ctrlrequest *dr;
+ struct urb *urb;
+ struct usb_device *udev;
+ struct usb_device_descriptor *buf;
+ DECLARE_COMPLETION_ONSTACK(done);
+
+ /* Obtain udev of the rhub's child port */
+ udev = usb_hub_find_child(hcd->self.root_hub, port);
+ if (!udev) {
+ dev_err(hcd->self.controller, "No device attached to the RootHub\n");
+ return -ENODEV;
+ }
+ buf = kmalloc(USB_DT_DEVICE_SIZE, GFP_KERNEL);
+ if (!buf)
+ return -ENOMEM;
+
+ dr = kmalloc(sizeof(struct usb_ctrlrequest), GFP_KERNEL);
+ if (!dr) {
+ kfree(buf);
+ return -ENOMEM;
+ }
+
+ /* Fill Setup packet for GetDescriptor */
+ dr->bRequestType = USB_DIR_IN;
+ dr->bRequest = USB_REQ_GET_DESCRIPTOR;
+ dr->wValue = cpu_to_le16(USB_DT_DEVICE << 8);
+ dr->wIndex = 0;
+ dr->wLength = cpu_to_le16(USB_DT_DEVICE_SIZE);
+ urb = request_single_step_set_feature_urb(udev, dr, buf, &done);
+ if (!urb)
+ goto cleanup;
+
+ /* Submit just the SETUP stage */
+ retval = hcd->driver->submit_single_step_set_feature(hcd, urb, 1);
+ if (retval)
+ goto out1;
+ if (!wait_for_completion_timeout(&done, msecs_to_jiffies(2000))) {
+ usb_kill_urb(urb);
+ retval = -ETIMEDOUT;
+ dev_err(hcd->self.controller,
+ "%s SETUP stage timed out on ep0\n", __func__);
+ goto out1;
+ }
+ msleep(15 * 1000);
+
+ /* Complete remaining DATA and STATUS stages using the same URB */
+ urb->status = -EINPROGRESS;
+ usb_get_urb(urb);
+ atomic_inc(&urb->use_count);
+ atomic_inc(&urb->dev->urbnum);
+ retval = hcd->driver->submit_single_step_set_feature(hcd, urb, 0);
+ if (!retval && !wait_for_completion_timeout(&done,
+ msecs_to_jiffies(2000))) {
+ usb_kill_urb(urb);
+ retval = -ETIMEDOUT;
+ dev_err(hcd->self.controller,
+ "%s IN stage timed out on ep0\n", __func__);
+ }
+out1:
+ usb_free_urb(urb);
+cleanup:
+ kfree(dr);
+ kfree(buf);
+ return retval;
+}
+EXPORT_SYMBOL_GPL(ehset_single_step_set_feature);
+#endif /* CONFIG_USB_HCD_TEST_MODE */
+
+/*-------------------------------------------------------------------------*/
#ifdef CONFIG_PM
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 4efccf8bf99f..d80ba41185a0 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -23,6 +23,7 @@
#include <linux/usbdevice_fs.h>
#include <linux/usb/hcd.h>
#include <linux/usb/otg.h>
+#include <linux/usb/otg-fsm.h>
#include <linux/usb/quirks.h>
#include <linux/workqueue.h>
#include <linux/mutex.h>
@@ -1132,6 +1133,10 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type)
need_debounce_delay = true;
usb_clear_port_feature(hub->hdev, port1,
USB_PORT_FEAT_C_CONNECTION);
+#ifdef CONFIG_USB_OTG
+ if (hdev->bus->is_b_host)
+ usb_bus_start_enum(hdev->bus, port1);
+#endif
}
if (portchange & USB_PORT_STAT_C_ENABLE) {
need_debounce_delay = true;
@@ -2230,9 +2235,9 @@ static inline void announce_device(struct usb_device *udev) { }
*/
static int usb_enumerate_device_otg(struct usb_device *udev)
{
+#ifdef CONFIG_USB_OTG
int err = 0;
-#ifdef CONFIG_USB_OTG
/*
* OTG-aware devices on OTG-capable root hubs may be able to use SRP,
* to wake us after we've powered off VBUS; and HNP, switching roles
@@ -2273,6 +2278,12 @@ static int usb_enumerate_device_otg(struct usb_device *udev)
err);
bus->b_hnp_enable = 0;
}
+
+ if (bus->otg_fsm) {
+ bus->otg_fsm->b_hnp_enable = 1;
+ if (bus->b_hnp_enable)
+ bus->otg_fsm->a_set_b_hnp_en = 1;
+ }
} else if (desc->bLength == sizeof
(struct usb_otg_descriptor)) {
/* Set a_alt_hnp_support for legacy otg device */
@@ -2289,7 +2300,7 @@ static int usb_enumerate_device_otg(struct usb_device *udev)
}
}
#endif
- return err;
+ return 0;
}
@@ -2311,6 +2322,7 @@ static int usb_enumerate_device(struct usb_device *udev)
{
int err;
struct usb_hcd *hcd = bus_to_hcd(udev->bus);
+ struct otg_fsm *fsm = udev->bus->otg_fsm;
if (udev->config == NULL) {
err = usb_get_configuration(udev);
@@ -2342,8 +2354,10 @@ static int usb_enumerate_device(struct usb_device *udev)
err = usb_port_suspend(udev, PMSG_AUTO_SUSPEND);
if (err < 0)
dev_dbg(&udev->dev, "HNP fail, %d\n", err);
+ return -ENOTSUPP;
+ } else if (!fsm || !fsm->b_hnp_enable || !fsm->hnp_polling) {
+ return -ENOTSUPP;
}
- return -ENOTSUPP;
}
usb_detect_interface_quirks(udev);
@@ -4570,7 +4584,8 @@ hub_port_init(struct usb_hub *hub, struct usb_device *udev, int port1,
}
if (r) {
if (r != -ENODEV)
- dev_err(&udev->dev, "device descriptor read/64, error %d\n",
+ dev_err(&udev->dev,
+ "device no response, device descriptor read/64, error %d\n",
r);
retval = -EMSGSIZE;
continue;
diff --git a/drivers/usb/core/otg_whitelist.h b/drivers/usb/core/otg_whitelist.h
index 085049d37d7a..68b4f7e80b47 100644
--- a/drivers/usb/core/otg_whitelist.h
+++ b/drivers/usb/core/otg_whitelist.h
@@ -17,35 +17,64 @@
*/
static struct usb_device_id whitelist_table[] = {
-
-/* hubs are optional in OTG, but very handy ... */
-{ USB_DEVICE_INFO(USB_CLASS_HUB, 0, 0), },
-{ USB_DEVICE_INFO(USB_CLASS_HUB, 0, 1), },
-
-#ifdef CONFIG_USB_PRINTER /* ignoring nonstatic linkage! */
-/* FIXME actually, printers are NOT supposed to use device classes;
- * they're supposed to use interface classes...
- */
-{ USB_DEVICE_INFO(7, 1, 1) },
-{ USB_DEVICE_INFO(7, 1, 2) },
-{ USB_DEVICE_INFO(7, 1, 3) },
+/* Add FSL i.mx whitelist, the default list is for USB Compliance Test */
+#if defined(CONFIG_USB_EHSET_TEST_FIXTURE) \
+ || defined(CONFIG_USB_EHSET_TEST_FIXTURE_MODULE)
+#define TEST_SE0_NAK_PID 0x0101
+#define TEST_J_PID 0x0102
+#define TEST_K_PID 0x0103
+#define TEST_PACKET_PID 0x0104
+#define TEST_HS_HOST_PORT_SUSPEND_RESUME 0x0106
+#define TEST_SINGLE_STEP_GET_DEV_DESC 0x0107
+#define TEST_SINGLE_STEP_SET_FEATURE 0x0108
+#define TEST_OTG_TEST_DEVICE_SUPPORT 0x0200
+{ USB_DEVICE(0x1a0a, TEST_SE0_NAK_PID) },
+{ USB_DEVICE(0x1a0a, TEST_J_PID) },
+{ USB_DEVICE(0x1a0a, TEST_K_PID) },
+{ USB_DEVICE(0x1a0a, TEST_PACKET_PID) },
+{ USB_DEVICE(0x1a0a, TEST_HS_HOST_PORT_SUSPEND_RESUME) },
+{ USB_DEVICE(0x1a0a, TEST_SINGLE_STEP_GET_DEV_DESC) },
+{ USB_DEVICE(0x1a0a, TEST_SINGLE_STEP_SET_FEATURE) },
+{ USB_DEVICE(0x1a0a, TEST_OTG_TEST_DEVICE_SUPPORT) },
#endif
-#ifdef CONFIG_USB_NET_CDCETHER
-/* Linux-USB CDC Ethernet gadget */
-{ USB_DEVICE(0x0525, 0xa4a1), },
-/* Linux-USB CDC Ethernet + RNDIS gadget */
-{ USB_DEVICE(0x0525, 0xa4a2), },
-#endif
+#define USB_INTERFACE_CLASS_INFO(cl) \
+ .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS, \
+ .bInterfaceClass = (cl)
-#if IS_ENABLED(CONFIG_USB_TEST)
-/* gadget zero, for testing */
-{ USB_DEVICE(0x0525, 0xa4a0), },
+{USB_INTERFACE_CLASS_INFO(USB_CLASS_HUB) },
+#if defined(CONFIG_USB_STORAGE) || defined(CONFIG_USB_STORAGE_MODULE)
+{USB_INTERFACE_CLASS_INFO(USB_CLASS_MASS_STORAGE) },
+#endif
+#if defined(CONFIG_USB_HID) || defined(CONFIG_USB_HID_MODULE)
+{USB_INTERFACE_CLASS_INFO(USB_CLASS_HID) },
#endif
{ } /* Terminating entry */
};
+static bool match_int_class(struct usb_device_id *id, struct usb_device *udev)
+{
+ struct usb_host_config *c;
+ int num_configs, i;
+
+ /* Copy the code from generic.c */
+ c = udev->config;
+ num_configs = udev->descriptor.bNumConfigurations;
+ for (i = 0; i < num_configs; (i++, c++)) {
+ struct usb_interface_descriptor *desc = NULL;
+
+ /* It's possible that a config has no interfaces! */
+ if (c->desc.bNumInterfaces > 0)
+ desc = &c->intf_cache[0]->altsetting->desc;
+
+ if (desc && (desc->bInterfaceClass == id->bInterfaceClass))
+ return true;
+ }
+
+ return false;
+}
+
static int is_targeted(struct usb_device *dev)
{
struct usb_device_id *id = whitelist_table;
@@ -60,6 +89,19 @@ static int is_targeted(struct usb_device *dev)
le16_to_cpu(dev->descriptor.idProduct) == 0x0200))
return 1;
+ /* Unknown Device Not Supporting HNP */
+ if ((le16_to_cpu(dev->descriptor.idVendor) == 0x1a0a &&
+ le16_to_cpu(dev->descriptor.idProduct) == 0x0201)) {
+ dev_warn(&dev->dev, "Unsupported Device\n");
+ return 0;
+ }
+ /* Unknown Device Supporting HNP */
+ if ((le16_to_cpu(dev->descriptor.idVendor) == 0x1a0a &&
+ le16_to_cpu(dev->descriptor.idProduct) == 0x0202)) {
+ dev_warn(&dev->dev, "Device no Responding\n");
+ return 0;
+ }
+
/* NOTE: can't use usb_match_id() since interface caches
* aren't set up yet. this is cut/paste from that code.
*/
@@ -94,6 +136,10 @@ static int is_targeted(struct usb_device *dev)
(id->bDeviceProtocol != dev->descriptor.bDeviceProtocol))
continue;
+ if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_CLASS) &&
+ (!match_int_class(id, dev)))
+ continue;
+
return 1;
}
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index a497b878c3e2..06839e02ebff 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -192,6 +192,30 @@ void dwc3_set_mode(struct dwc3 *dwc, u32 mode)
queue_work(system_freezable_wq, &dwc->drd_work);
}
+static int dwc3_set_suspend_clk(struct dwc3 *dwc)
+{
+ u32 reg, scale;
+
+ /*
+ * DWC3_GCTL.PWRDNSCALE: The USB3 suspend_clk input replaces
+ * pipe3_rx_pclk as a clock source to a small part of the USB3
+ * core that operates when the SS PHY is in its lowest power
+ * (P3) state, and therefore does not provide a clock.
+ * The Power Down Scale field specifies how many suspend_clk
+ * periods fit into a 16 kHz clock period. When performing the
+ * division, round up the remainder.
+ */
+ if (!device_property_read_u32(dwc->dev, "snps,power-down-scale",
+ &scale)) {
+ reg = dwc3_readl(dwc->regs, DWC3_GCTL);
+ reg &= ~(DWC3_GCTL_PWRDNSCALE_MASK);
+ reg |= DWC3_GCTL_PWRDNSCALE(scale);
+ dwc3_writel(dwc->regs, DWC3_GCTL, reg);
+ }
+
+ return 0;
+}
+
u32 dwc3_core_fifo_space(struct dwc3_ep *dep, u8 type)
{
struct dwc3 *dwc = dep->dwc;
@@ -806,6 +830,9 @@ static int dwc3_core_init(struct dwc3 *dwc)
dwc->ulpi_ready = true;
}
+ /* Set suspend_clk */
+ dwc3_set_suspend_clk(dwc);
+
if (!dwc->phys_ready) {
ret = dwc3_core_get_phy(dwc);
if (ret)
@@ -969,6 +996,7 @@ static int dwc3_core_init_mode(struct dwc3 *dwc)
switch (dwc->dr_mode) {
case USB_DR_MODE_PERIPHERAL:
+ dwc->current_dr_role = DWC3_GCTL_PRTCAP_DEVICE;
dwc3_set_prtcap(dwc, DWC3_GCTL_PRTCAP_DEVICE);
if (dwc->usb2_phy)
@@ -984,6 +1012,7 @@ static int dwc3_core_init_mode(struct dwc3 *dwc)
}
break;
case USB_DR_MODE_HOST:
+ dwc->current_dr_role = DWC3_GCTL_PRTCAP_HOST;
dwc3_set_prtcap(dwc, DWC3_GCTL_PRTCAP_HOST);
if (dwc->usb2_phy)
@@ -1229,6 +1258,19 @@ static int dwc3_probe(struct platform_device *pdev)
dwc3_get_properties(dwc);
+ if (dwc->dr_mode == USB_DR_MODE_OTG) {
+ dwc->otg_caps.otg_rev = 0x0300;
+ dwc->otg_caps.hnp_support = true;
+ dwc->otg_caps.srp_support = true;
+ dwc->otg_caps.adp_support = true;
+
+ /* Update otg capabilities by DT properties */
+ ret = of_usb_update_otg_caps(dev->of_node,
+ &dwc->otg_caps);
+ if (ret)
+ goto err0;
+ }
+
platform_set_drvdata(pdev, dwc);
dwc3_cache_hwparams(dwc);
@@ -1339,21 +1381,19 @@ static int dwc3_suspend_common(struct dwc3 *dwc)
{
unsigned long flags;
- switch (dwc->dr_mode) {
- case USB_DR_MODE_PERIPHERAL:
- case USB_DR_MODE_OTG:
+ switch (dwc->current_dr_role) {
+ case DWC3_GCTL_PRTCAP_DEVICE:
spin_lock_irqsave(&dwc->lock, flags);
dwc3_gadget_suspend(dwc);
spin_unlock_irqrestore(&dwc->lock, flags);
+ dwc3_core_exit(dwc);
break;
- case USB_DR_MODE_HOST:
+ case DWC3_GCTL_PRTCAP_HOST:
default:
/* do nothing */
break;
}
- dwc3_core_exit(dwc);
-
return 0;
}
@@ -1362,18 +1402,17 @@ static int dwc3_resume_common(struct dwc3 *dwc)
unsigned long flags;
int ret;
- ret = dwc3_core_init(dwc);
- if (ret)
- return ret;
+ switch (dwc->current_dr_role) {
+ case DWC3_GCTL_PRTCAP_DEVICE:
+ ret = dwc3_core_init(dwc);
+ if (ret)
+ return ret;
- switch (dwc->dr_mode) {
- case USB_DR_MODE_PERIPHERAL:
- case USB_DR_MODE_OTG:
spin_lock_irqsave(&dwc->lock, flags);
dwc3_gadget_resume(dwc);
spin_unlock_irqrestore(&dwc->lock, flags);
- /* FALLTHROUGH */
- case USB_DR_MODE_HOST:
+ break;
+ case DWC3_GCTL_PRTCAP_HOST:
default:
/* do nothing */
break;
@@ -1384,7 +1423,7 @@ static int dwc3_resume_common(struct dwc3 *dwc)
static int dwc3_runtime_checks(struct dwc3 *dwc)
{
- switch (dwc->dr_mode) {
+ switch (dwc->current_dr_role) {
case USB_DR_MODE_PERIPHERAL:
case USB_DR_MODE_OTG:
if (dwc->connected)
@@ -1427,12 +1466,11 @@ static int dwc3_runtime_resume(struct device *dev)
if (ret)
return ret;
- switch (dwc->dr_mode) {
- case USB_DR_MODE_PERIPHERAL:
- case USB_DR_MODE_OTG:
+ switch (dwc->current_dr_role) {
+ case DWC3_GCTL_PRTCAP_DEVICE:
dwc3_gadget_process_pending_events(dwc);
break;
- case USB_DR_MODE_HOST:
+ case DWC3_GCTL_PRTCAP_HOST:
default:
/* do nothing */
break;
@@ -1448,13 +1486,12 @@ static int dwc3_runtime_idle(struct device *dev)
{
struct dwc3 *dwc = dev_get_drvdata(dev);
- switch (dwc->dr_mode) {
- case USB_DR_MODE_PERIPHERAL:
- case USB_DR_MODE_OTG:
+ switch (dwc->current_dr_role) {
+ case DWC3_GCTL_PRTCAP_DEVICE:
if (dwc3_runtime_checks(dwc))
return -EBUSY;
break;
- case USB_DR_MODE_HOST:
+ case DWC3_GCTL_PRTCAP_HOST:
default:
/* do nothing */
break;
diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
index 40bf0e0768d9..354bddf5ed44 100644
--- a/drivers/usb/dwc3/core.h
+++ b/drivers/usb/dwc3/core.h
@@ -183,6 +183,7 @@
/* Global Configuration Register */
#define DWC3_GCTL_PWRDNSCALE(n) ((n) << 19)
+#define DWC3_GCTL_PWRDNSCALE_MASK DWC3_GCTL_PWRDNSCALE(0x1fff)
#define DWC3_GCTL_U2RSTECN BIT(16)
#define DWC3_GCTL_RAMCLKSEL(x) (((x) & DWC3_GCTL_CLK_MASK) << 6)
#define DWC3_GCTL_CLK_BUS (0)
@@ -872,6 +873,7 @@ struct dwc3_scratchpad_array {
* @dis_metastability_quirk: set to disable metastability quirk.
* @imod_interval: set the interrupt moderation interval in 250ns
* increments or 0 to disable.
+ * @otg_caps: the OTG capabilities from hardware point
*/
struct dwc3 {
struct work_struct drd_work;
@@ -1029,6 +1031,8 @@ struct dwc3 {
unsigned dis_metastability_quirk:1;
u16 imod_interval;
+
+ struct usb_otg_caps otg_caps;
};
#define work_to_dwc(w) (container_of((w), struct dwc3, drd_work))
diff --git a/drivers/usb/dwc3/dwc3-of-simple.c b/drivers/usb/dwc3/dwc3-of-simple.c
index acf41ba3638d..216ae3886186 100644
--- a/drivers/usb/dwc3/dwc3-of-simple.c
+++ b/drivers/usb/dwc3/dwc3-of-simple.c
@@ -181,6 +181,7 @@ static const struct of_device_id of_dwc3_simple_match[] = {
{ .compatible = "xlnx,zynqmp-dwc3" },
{ .compatible = "cavium,octeon-7130-usb-uctl" },
{ .compatible = "sprd,sc9860-dwc3" },
+ { .compatible = "fsl, imx8mq-dwc3" },
{ /* Sentinel */ }
};
MODULE_DEVICE_TABLE(of, of_dwc3_simple_match);
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index e96b22d6fa52..707646b95d25 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -26,6 +26,7 @@
#include <linux/io.h>
#include <linux/list.h>
#include <linux/dma-mapping.h>
+#include <linux/busfreq-imx.h>
#include <linux/usb/ch9.h>
#include <linux/usb/gadget.h>
@@ -276,7 +277,11 @@ int dwc3_send_gadget_ep_cmd(struct dwc3_ep *dep, unsigned cmd,
{
const struct usb_endpoint_descriptor *desc = dep->endpoint.desc;
struct dwc3 *dwc = dep->dwc;
- u32 timeout = 1000;
+ /*
+ * FIXME need check why 500 times check
+ * is not enough.
+ */
+ u32 timeout = 20000;
u32 saved_config = 0;
u32 reg;
@@ -2675,14 +2680,20 @@ static void dwc3_gadget_disconnect_interrupt(struct dwc3 *dwc)
dwc->setup_packet_pending = false;
usb_gadget_set_state(&dwc->gadget, USB_STATE_NOTATTACHED);
- dwc->connected = false;
+ if (dwc->connected) {
+ release_bus_freq(BUS_FREQ_HIGH);
+ dwc->connected = false;
+ }
}
static void dwc3_gadget_reset_interrupt(struct dwc3 *dwc)
{
u32 reg;
- dwc->connected = true;
+ if (!dwc->connected) {
+ request_bus_freq(BUS_FREQ_HIGH);
+ dwc->connected = true;
+ }
/*
* WORKAROUND: DWC3 revisions <1.88a have an issue which
@@ -3257,7 +3268,10 @@ int dwc3_gadget_init(struct dwc3 *dwc)
dwc->gadget.speed = USB_SPEED_UNKNOWN;
dwc->gadget.sg_supported = true;
dwc->gadget.name = "dwc3-gadget";
- dwc->gadget.is_otg = dwc->dr_mode == USB_DR_MODE_OTG;
+ dwc->gadget.is_otg = (dwc->dr_mode == USB_DR_MODE_OTG) &&
+ (dwc->otg_caps.hnp_support ||
+ dwc->otg_caps.srp_support ||
+ dwc->otg_caps.adp_support);
/*
* FIXME We might be setting max_speed to <SUPER, however versions
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
index 31cce7805eb2..53114b126f42 100644
--- a/drivers/usb/gadget/Kconfig
+++ b/drivers/usb/gadget/Kconfig
@@ -343,6 +343,12 @@ config USB_CONFIGFS_MASS_STORAGE
device (in much the same way as the "loop" device driver),
specified as a module parameter or sysfs option.
+config FSL_UTP
+ bool "UTP over Storage Gadget"
+ depends on USB_CONFIGFS_MASS_STORAGE
+ help
+ Freescale's extension to MSC protocol
+
config USB_CONFIGFS_F_LB_SS
bool "Loopback and sourcesink function (for testing)"
depends on USB_CONFIGFS
diff --git a/drivers/usb/gadget/function/f_mass_storage.c b/drivers/usb/gadget/function/f_mass_storage.c
index 41b5baa1f43b..5ec48dbaff6b 100644
--- a/drivers/usb/gadget/function/f_mass_storage.c
+++ b/drivers/usb/gadget/function/f_mass_storage.c
@@ -333,8 +333,15 @@ struct fsg_dev {
struct usb_ep *bulk_in;
struct usb_ep *bulk_out;
+#ifdef CONFIG_FSL_UTP
+ void *utp;
+#endif
};
+#ifdef CONFIG_FSL_UTP
+#include "fsl_updater.h"
+#endif
+
static inline int __fsg_is_set(struct fsg_common *common,
const char *func, unsigned line)
{
@@ -1118,6 +1125,15 @@ static int do_request_sense(struct fsg_common *common, struct fsg_buffhd *bh)
}
#endif
+#ifdef CONFIG_FSL_UTP
+ if (is_utp_device(common->fsg) &&
+ utp_get_sense(common->fsg) == 0) {
+ /* got the sense from the UTP */
+ sd = UTP_CTX(common->fsg)->sd;
+ sdinfo = UTP_CTX(common->fsg)->sdinfo;
+ valid = 0;
+ } else
+#endif
if (!curlun) { /* Unsupported LUNs are okay */
common->bad_lun_okay = 1;
sd = SS_LOGICAL_UNIT_NOT_SUPPORTED;
@@ -1139,6 +1155,10 @@ static int do_request_sense(struct fsg_common *common, struct fsg_buffhd *bh)
buf[7] = 18 - 8; /* Additional sense length */
buf[12] = ASC(sd);
buf[13] = ASCQ(sd);
+#ifdef CONFIG_FSL_UTP
+ if (is_utp_device(common->fsg))
+ put_unaligned_be32(UTP_CTX(common->fsg)->sdinfo_h, &buf[8]);
+#endif
return 18;
}
@@ -1625,7 +1645,20 @@ static void send_status(struct fsg_common *common)
sd = SS_INVALID_COMMAND;
} else if (sd != SS_NO_SENSE) {
DBG(common, "sending command-failure status\n");
- status = US_BULK_STAT_FAIL;
+#ifdef CONFIG_FSL_UTP
+ /*
+ * mfgtool host frequently reset bus during transfer
+ * - the response in csw to request sense will be 1
+ * due to UTP change some storage information
+ * - host will reset the bus if response to request sense is 1
+ * - change the response to 0 if CONFIG_FSL_UTP is defined
+ */
+ if (is_utp_device(common->fsg))
+ status = US_BULK_STAT_OK;
+ else
+#endif
+ status = US_BULK_STAT_FAIL;
+
VDBG(common, " sense data: SK x%02x, ASC x%02x, ASCQ x%02x;"
" info x%x\n",
SK(sd), ASC(sd), ASCQ(sd), sdinfo);
@@ -1815,6 +1848,14 @@ static int do_scsi_command(struct fsg_common *common)
common->phase_error = 0;
common->short_packet_received = 0;
+#ifdef CONFIG_FSL_UTP
+ if (is_utp_device(common->fsg))
+ reply = utp_handle_message(common->fsg, common->cmnd, reply);
+
+ if (reply != -EINVAL)
+ return reply;
+#endif
+
down_read(&common->filesem); /* We're using the backing file */
switch (common->cmnd[0]) {
@@ -2461,6 +2502,18 @@ static int fsg_main_thread(void *common_)
/* Allow the thread to be frozen */
set_freezable();
+ /*
+ * Arrange for userspace references to be interpreted as kernel
+ * pointers. That way we can pass a kernel pointer to a routine
+ * that expects a __user pointer and it will work okay.
+ */
+#ifdef CONFIG_FSL_UTP
+ if (!is_utp_device(common->fsg))
+ set_fs(get_ds());
+#else
+ set_fs(get_ds());
+#endif
+
/* The main loop */
while (common->state != FSG_STATE_TERMINATED) {
if (exception_in_progress(common) || signal_pending(current)) {
@@ -2909,6 +2962,10 @@ static void fsg_common_release(struct kref *ref)
/*-------------------------------------------------------------------------*/
+#ifdef CONFIG_FSL_UTP
+#include "fsl_updater.c"
+#endif
+
static int fsg_bind(struct usb_configuration *c, struct usb_function *f)
{
struct fsg_dev *fsg = fsg_from_func(f);
@@ -2960,6 +3017,11 @@ static int fsg_bind(struct usb_configuration *c, struct usb_function *f)
fsg_intf_desc.bInterfaceNumber = i;
fsg->interface_number = i;
+#ifdef CONFIG_FSL_UTP
+ if (is_utp_device(fsg))
+ utp_init(fsg);
+#endif
+
/* Find all the endpoints we will use */
ep = usb_ep_autoconfig(gadget, &fsg_fs_bulk_in_desc);
if (!ep)
@@ -3022,6 +3084,12 @@ static void fsg_unbind(struct usb_configuration *c, struct usb_function *f)
}
usb_free_all_descriptors(&fsg->function);
+
+#ifdef CONFIG_FSL_UTP
+ if (is_utp_device(common->fsg))
+ utp_exit(fsg);
+#endif
+
}
static inline struct fsg_lun_opts *to_fsg_lun_opts(struct config_item *item)
diff --git a/drivers/usb/gadget/function/fsl_updater.c b/drivers/usb/gadget/function/fsl_updater.c
new file mode 100644
index 000000000000..eec5bf1f8f1e
--- /dev/null
+++ b/drivers/usb/gadget/function/fsl_updater.c
@@ -0,0 +1,644 @@
+/*
+ * Freescale UUT driver
+ *
+ * Copyright 2008-2016 Freescale Semiconductor, Inc.
+ * Copyright 2008-2009 Embedded Alley Solutions, Inc All Rights Reserved.
+ * Copyright 2017 NXP
+ */
+
+/*
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+static bool is_utp_device(struct fsg_dev *fsg)
+{
+ struct usb_device_descriptor *pdesc;
+
+ if (!fsg || !fsg->common || !fsg->common->cdev)
+ return false;
+
+ pdesc = &fsg->common->cdev->desc;
+ if (pdesc->idVendor == UTP_IDVENDOR &&
+ pdesc->idProduct == UTP_IDPRODUCT)
+ return true;
+
+ return false;
+}
+
+static u64 get_be64(u8 *buf)
+{
+ return ((u64)get_unaligned_be32(buf) << 32) |
+ get_unaligned_be32(buf + 4);
+}
+
+static DEFINE_IDA(utp_ida);
+
+static int utp_init(struct fsg_dev *fsg)
+{
+ struct utp_context *utp;
+ int index;
+
+ utp = vzalloc(sizeof(struct utp_context));
+ if (!utp)
+ return -EIO;
+
+ init_waitqueue_head(&utp->wq);
+ init_waitqueue_head(&utp->list_full_wq);
+
+ INIT_LIST_HEAD(&utp->read);
+ INIT_LIST_HEAD(&utp->write);
+ mutex_init(&utp->lock);
+
+ /* the max message is 64KB */
+ utp->buffer = vmalloc(0x10000);
+ if (!utp->buffer) {
+ vfree(utp);
+ return -EIO;
+ }
+
+ utp->utp_version = 0x1ull;
+ fsg->utp = utp;
+ utp->utp_dev.minor = MISC_DYNAMIC_MINOR;
+ utp->utp_dev.fops = &utp_fops;
+
+ index = ida_simple_get(&utp_ida, 0, 0, GFP_KERNEL);
+ if (index == 0)
+ snprintf(utp->utp_name, 8, "utp");
+ else
+ snprintf(utp->utp_name, 8, "utp%d", index);
+
+ utp->utp_dev.name = utp->utp_name;
+ return misc_register(&utp->utp_dev);
+}
+
+static void utp_exit(struct fsg_dev *fsg)
+{
+ struct utp_context *utp;
+ utp = UTP_CTX(fsg);
+
+ misc_deregister(&utp->utp_dev);
+
+ vfree(utp->buffer);
+ vfree(utp);
+}
+
+static struct utp_user_data *utp_user_data_alloc(size_t size)
+{
+ struct utp_user_data *uud;
+
+ uud = vmalloc(size + sizeof(*uud));
+ if (!uud)
+ return uud;
+ memset(uud, 0, size + sizeof(*uud));
+ uud->data.size = size + sizeof(uud->data);
+ INIT_LIST_HEAD(&uud->link);
+ return uud;
+}
+
+static void utp_user_data_free(struct utp_context *utp, struct utp_user_data *uud)
+{
+ mutex_lock(&utp->lock);
+ list_del(&uud->link);
+ mutex_unlock(&utp->lock);
+ vfree(uud);
+}
+
+/* Get the number of element for list */
+static u32 count_list(struct utp_context *utp, struct list_head *l)
+{
+ u32 count = 0;
+ struct list_head *tmp;
+
+ mutex_lock(&utp->lock);
+ list_for_each(tmp, l) {
+ count++;
+ }
+ mutex_unlock(&utp->lock);
+
+ return count;
+}
+
+/* The routine will not go on if utp_context.queue is empty */
+#define WAIT_ACTIVITY(utp, queue) \
+ wait_event_interruptible(utp->wq, !list_empty(&utp->queue))
+
+/* Called by userspace program (uuc) */
+static ssize_t utp_file_read(struct file *file,
+ char __user *buf,
+ size_t size,
+ loff_t *off)
+{
+ struct utp_user_data *uud;
+ size_t size_to_put;
+ int free = 0;
+
+ struct miscdevice *misc = (struct miscdevice *)file->private_data;
+ struct utp_context *utp = container_of(misc, struct utp_context, utp_dev);
+
+ WAIT_ACTIVITY(utp, read);
+
+ mutex_lock(&utp->lock);
+ uud = list_first_entry(&utp->read, struct utp_user_data, link);
+ mutex_unlock(&utp->lock);
+ size_to_put = uud->data.size;
+
+ if (size >= size_to_put)
+ free = !0;
+ if (copy_to_user(buf, &uud->data, size_to_put)) {
+ printk(KERN_INFO "[ %s ] copy error\n", __func__);
+ return -EACCES;
+ }
+ if (free)
+ utp_user_data_free(utp, uud);
+ else {
+ pr_info("sizeof = %zd, size = %zd\n",
+ sizeof(uud->data),
+ uud->data.size);
+
+ pr_err("Will not free utp_user_data, because buffer size = %zd need to put %zd\n",
+ size, size_to_put);
+ }
+
+ /*
+ * The user program has already finished data process,
+ * go on getting data from the host
+ */
+ wake_up(&utp->list_full_wq);
+
+ return size_to_put;
+}
+
+static ssize_t utp_file_write(struct file *file, const char __user *buf,
+ size_t size, loff_t *off)
+{
+ struct utp_user_data *uud;
+
+ struct miscdevice *misc = (struct miscdevice *)file->private_data;
+ struct utp_context *utp = container_of(misc, struct utp_context, utp_dev);
+
+ if (size < sizeof(uud->data))
+ return -EINVAL;
+ uud = utp_user_data_alloc(size);
+ if (uud == NULL)
+ return -ENOMEM;
+ if (copy_from_user(&uud->data, buf, size)) {
+ printk(KERN_INFO "[ %s ] copy error!\n", __func__);
+ vfree(uud);
+ return -EACCES;
+ }
+ mutex_lock(&utp->lock);
+ list_add_tail(&uud->link, &utp->write);
+ /* Go on EXEC routine process */
+ wake_up(&utp->wq);
+ mutex_unlock(&utp->lock);
+ return size;
+}
+
+/*
+ * uuc should change to use soc bus infrastructure to soc information
+ * /sys/devices/soc0/soc_id
+ * this function can be removed.
+ */
+static long
+utp_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+ int cpu_id = 0;
+
+ switch (cmd) {
+ case UTP_GET_CPU_ID:
+ return put_user(cpu_id, (int __user *)arg);
+ default:
+ return -ENOIOCTLCMD;
+ }
+}
+
+/* Will be called when the host wants to get the sense data */
+static int utp_get_sense(struct fsg_dev *fsg)
+{
+ if (UTP_CTX(fsg)->processed == 0)
+ return -1;
+
+ UTP_CTX(fsg)->processed = 0;
+ return 0;
+}
+
+static int utp_do_read(struct fsg_dev *fsg, void *data, size_t size)
+{
+ struct fsg_buffhd *bh;
+ int rc;
+ u32 amount_left;
+ unsigned int amount;
+
+ /* Get the starting Logical Block Address and check that it's
+ * not too big */
+
+ amount_left = size;
+ if (unlikely(amount_left == 0))
+ return -EIO; /* No default reply*/
+
+ pr_debug("%s: sending %zd\n", __func__, size);
+ for (;;) {
+ /* Figure out how much we need to read:
+ * Try to read the remaining amount.
+ * But don't read more than the buffer size.
+ * And don't try to read past the end of the file.
+ * Finally, if we're not at a page boundary, don't read past
+ * the next page.
+ * If this means reading 0 then we were asked to read past
+ * the end of file. */
+ amount = min((unsigned int) amount_left, FSG_BUFLEN);
+
+ /* Wait for the next buffer to become available */
+ bh = fsg->common->next_buffhd_to_fill;
+ while (bh->state != BUF_STATE_EMPTY) {
+ rc = sleep_thread(fsg->common, true, bh);
+ if (rc)
+ return rc;
+ }
+
+ /* If we were asked to read past the end of file,
+ * end with an empty buffer. */
+ if (amount == 0) {
+ bh->inreq->length = 0;
+ bh->state = BUF_STATE_FULL;
+ break;
+ }
+
+ /* Perform the read */
+ pr_info("Copied to %p, %d bytes started from %zd\n",
+ bh->buf, amount, size - amount_left);
+ /* from upt buffer to file_storeage buffer */
+ memcpy(bh->buf, data + size - amount_left, amount);
+ amount_left -= amount;
+ fsg->common->residue -= amount;
+
+ bh->inreq->length = amount;
+ bh->state = BUF_STATE_FULL;
+
+ /* Send this buffer and go read some more */
+ bh->inreq->zero = 0;
+
+ /* USB Physical transfer: Data from device to host */
+ start_transfer(fsg, fsg->bulk_in, bh->inreq);
+
+ fsg->common->next_buffhd_to_fill = bh->next;
+
+ if (amount_left <= 0)
+ break;
+ }
+
+ return size - amount_left;
+}
+
+static int utp_do_write(struct fsg_dev *fsg, void *data, size_t size)
+{
+ struct fsg_buffhd *bh;
+ int get_some_more;
+ u32 amount_left_to_req, amount_left_to_write;
+ unsigned int amount;
+ int rc;
+ loff_t offset;
+
+ /* Carry out the file writes */
+ get_some_more = 1;
+ amount_left_to_req = amount_left_to_write = size;
+
+ if (unlikely(amount_left_to_write == 0))
+ return -EIO;
+
+ offset = 0;
+ while (amount_left_to_write > 0) {
+
+ /* Queue a request for more data from the host */
+ bh = fsg->common->next_buffhd_to_fill;
+ if (bh->state == BUF_STATE_EMPTY && get_some_more) {
+
+ /* Figure out how much we want to get:
+ * Try to get the remaining amount.
+ * But don't get more than the buffer size.
+ * And don't try to go past the end of the file.
+ * If we're not at a page boundary,
+ * don't go past the next page.
+ * If this means getting 0, then we were asked
+ * to write past the end of file.
+ * Finally, round down to a block boundary. */
+ amount = min(amount_left_to_req, FSG_BUFLEN);
+
+ if (amount == 0) {
+ get_some_more = 0;
+ /* cry now */
+ continue;
+ }
+
+ /* Get the next buffer */
+ amount_left_to_req -= amount;
+ if (amount_left_to_req == 0)
+ get_some_more = 0;
+
+ /* amount is always divisible by 512, hence by
+ * the bulk-out maxpacket size */
+ set_bulk_out_req_length(fsg->common, bh, amount);
+ bh->outreq->short_not_ok = 1;
+ start_transfer(fsg, fsg->bulk_out, bh->outreq);
+ fsg->common->next_buffhd_to_fill = bh->next;
+ continue;
+ }
+
+ /* Write the received data to the backing file */
+ bh = fsg->common->next_buffhd_to_drain;
+ if (bh->state == BUF_STATE_EMPTY && !get_some_more)
+ break; /* We stopped early */
+ if (bh->state == BUF_STATE_FULL) {
+ smp_rmb();
+ fsg->common->next_buffhd_to_drain = bh->next;
+ bh->state = BUF_STATE_EMPTY;
+
+ /* Did something go wrong with the transfer? */
+ if (bh->outreq->status != 0)
+ /* cry again, COMMUNICATION_FAILURE */
+ break;
+
+ amount = bh->outreq->actual;
+
+ /* Perform the write */
+ memcpy(data + offset, bh->buf, amount);
+
+ offset += amount;
+ if (signal_pending(current))
+ return -EINTR; /* Interrupted!*/
+ amount_left_to_write -= amount;
+ fsg->common->residue -= amount;
+
+ /* Did the host decide to stop early? */
+ if (bh->outreq->actual != bh->outreq->length) {
+ fsg->common->short_packet_received = 1;
+ break;
+ }
+ continue;
+ }
+
+ /* Wait for something to happen */
+ rc = sleep_thread(fsg->common, true, bh);
+ if (rc)
+ return rc;
+ }
+
+ return -EIO;
+}
+
+static inline void utp_set_sense(struct fsg_dev *fsg, u16 code, u64 reply)
+{
+ UTP_CTX(fsg)->processed = true;
+ UTP_CTX(fsg)->sdinfo = reply & 0xFFFFFFFF;
+ UTP_CTX(fsg)->sdinfo_h = (reply >> 32) & 0xFFFFFFFF;
+ UTP_CTX(fsg)->sd = (UTP_SENSE_KEY << 16) | code;
+}
+
+static void utp_poll(struct fsg_dev *fsg)
+{
+ struct utp_context *ctx = UTP_CTX(fsg);
+ struct utp_user_data *uud = NULL;
+
+ mutex_lock(&ctx->lock);
+ if (!list_empty(&ctx->write))
+ uud = list_first_entry(&ctx->write, struct utp_user_data, link);
+ mutex_unlock(&ctx->lock);
+
+ if (uud) {
+ if (uud->data.flags & UTP_FLAG_STATUS) {
+ printk(KERN_WARNING "%s: exit with status %d\n",
+ __func__, uud->data.status);
+ UTP_SS_EXIT(fsg, uud->data.status);
+ } else if (uud->data.flags & UTP_FLAG_REPORT_BUSY) {
+ UTP_SS_BUSY(fsg, --ctx->counter);
+ } else {
+ printk("%s: pass returned.\n", __func__);
+ UTP_SS_PASS(fsg);
+ }
+ utp_user_data_free(ctx, uud);
+ } else {
+ if (ctx->cur_state & UTP_FLAG_DATA) {
+ if (count_list(ctx, &ctx->read) < 7) {
+ pr_debug("%s: pass returned in POLL stage. \n", __func__);
+ UTP_SS_PASS(fsg);
+ ctx->cur_state = 0;
+ return;
+ }
+ }
+ UTP_SS_BUSY(fsg, --ctx->counter);
+ }
+}
+
+static int utp_exec(struct fsg_dev *fsg,
+ char *command,
+ int cmdsize,
+ unsigned long long payload)
+{
+ struct utp_user_data *uud = NULL, *uud2r;
+ struct utp_context *ctx = UTP_CTX(fsg);
+
+ ctx->counter = 0xFFFF;
+ uud2r = utp_user_data_alloc(cmdsize + 1);
+ if (!uud2r)
+ return -ENOMEM;
+ uud2r->data.flags = UTP_FLAG_COMMAND;
+ uud2r->data.payload = payload;
+ strncpy(uud2r->data.command, command, cmdsize);
+
+ mutex_lock(&ctx->lock);
+ list_add_tail(&uud2r->link, &ctx->read);
+ mutex_unlock(&ctx->lock);
+ /* wake up the read routine */
+ wake_up(&ctx->wq);
+
+ if (command[0] == '!') /* there will be no response */
+ return 0;
+
+ /*
+ * the user program (uuc) will return utp_message
+ * and add list to write list
+ */
+ WAIT_ACTIVITY(ctx, write);
+
+ mutex_lock(&ctx->lock);
+ if (!list_empty(&ctx->write)) {
+ uud = list_first_entry(&ctx->write, struct utp_user_data, link);
+#ifdef DEBUG
+ pr_info("UUD:\n\tFlags = %02X\n", uud->data.flags);
+ if (uud->data.flags & UTP_FLAG_DATA) {
+ pr_info("\tbufsize = %d\n", uud->data.bufsize);
+ print_hex_dump(KERN_DEBUG, "\t", DUMP_PREFIX_NONE,
+ 16, 2, uud->data.data, uud->data.bufsize, true);
+ }
+ if (uud->data.flags & UTP_FLAG_REPORT_BUSY)
+ pr_info("\tBUSY\n");
+#endif
+ } else {
+ pr_err("UTP write list is empty.\n");
+ mutex_unlock(&ctx->lock);
+ return 0;
+ }
+ mutex_unlock(&ctx->lock);
+
+ if (uud->data.flags & UTP_FLAG_DATA) {
+ memcpy(ctx->buffer, uud->data.data, uud->data.bufsize);
+ UTP_SS_SIZE(fsg, uud->data.bufsize);
+ } else if (uud->data.flags & UTP_FLAG_REPORT_BUSY) {
+ UTP_SS_BUSY(fsg, ctx->counter);
+ } else if (uud->data.flags & UTP_FLAG_STATUS) {
+ printk(KERN_WARNING "%s: exit with status %d\n", __func__,
+ uud->data.status);
+ UTP_SS_EXIT(fsg, uud->data.status);
+ } else {
+ pr_debug("%s: pass returned in EXEC stage. \n", __func__);
+ UTP_SS_PASS(fsg);
+ }
+ utp_user_data_free(ctx, uud);
+ return 0;
+}
+
+static int utp_send_status(struct fsg_dev *fsg)
+{
+ struct fsg_buffhd *bh;
+ u8 status = US_BULK_STAT_OK;
+ struct bulk_cs_wrap *csw;
+ int rc;
+
+ /* Wait for the next buffer to become available */
+ bh = fsg->common->next_buffhd_to_fill;
+ while (bh->state != BUF_STATE_EMPTY) {
+ rc = sleep_thread(fsg->common, true, bh);
+ if (rc)
+ return rc;
+ }
+
+ if (fsg->common->phase_error) {
+ DBG(fsg, "sending phase-error status\n");
+ status = US_BULK_STAT_PHASE;
+
+ } else if ((UTP_CTX(fsg)->sd & 0xFFFF) != UTP_REPLY_PASS) {
+ status = US_BULK_STAT_FAIL;
+ }
+
+ csw = bh->buf;
+
+ /* Store and send the Bulk-only CSW */
+ csw->Signature = __constant_cpu_to_le32(US_BULK_CS_SIGN);
+ csw->Tag = fsg->common->tag;
+ csw->Residue = cpu_to_le32(fsg->common->residue);
+ csw->Status = status;
+
+ bh->inreq->length = US_BULK_CS_WRAP_LEN;
+ bh->inreq->zero = 0;
+ start_transfer(fsg, fsg->bulk_in, bh->inreq);
+ fsg->common->next_buffhd_to_fill = bh->next;
+ return 0;
+}
+
+static int utp_handle_message(struct fsg_dev *fsg,
+ char *cdb_data,
+ int default_reply)
+{
+ struct utp_msg *m = (struct utp_msg *)cdb_data;
+ void *data = NULL;
+ int r;
+ struct utp_user_data *uud2r;
+ unsigned long long param;
+ unsigned long tag;
+
+ if (m->f0 != 0xF0)
+ return default_reply;
+
+ tag = get_unaligned_be32((void *)&m->utp_msg_tag);
+ param = get_be64((void *)&m->param);
+ pr_debug("Type 0x%x, tag 0x%08lx, param %llx\n",
+ m->utp_msg_type, tag, param);
+
+ switch ((enum utp_msg_type)m->utp_msg_type) {
+
+ case UTP_POLL:
+ if (get_be64((void *)&m->param) == 1) {
+ pr_debug("%s: version request\n", __func__);
+ UTP_SS_EXIT(fsg, UTP_CTX(fsg)->utp_version);
+ break;
+ }
+ utp_poll(fsg);
+ break;
+ case UTP_EXEC:
+ pr_debug("%s: EXEC\n", __func__);
+ data = vmalloc(fsg->common->data_size);
+ memset(data, 0, fsg->common->data_size);
+ /* copy data from usb buffer to utp buffer */
+ utp_do_write(fsg, data, fsg->common->data_size);
+ utp_exec(fsg, data, fsg->common->data_size, param);
+ vfree(data);
+ break;
+ case UTP_GET: /* data from device to host */
+ pr_debug("%s: GET, %d bytes\n", __func__,
+ fsg->common->data_size);
+ r = utp_do_read(fsg, UTP_CTX(fsg)->buffer,
+ fsg->common->data_size);
+ UTP_SS_PASS(fsg);
+ break;
+ case UTP_PUT:
+ UTP_CTX(fsg)->cur_state = UTP_FLAG_DATA;
+ pr_debug("%s: PUT, Received %d bytes\n", __func__, fsg->common->data_size);/* data from host to device */
+ uud2r = utp_user_data_alloc(fsg->common->data_size);
+ if (!uud2r)
+ return -ENOMEM;
+ uud2r->data.bufsize = fsg->common->data_size;
+ uud2r->data.flags = UTP_FLAG_DATA;
+ utp_do_write(fsg, uud2r->data.data, fsg->common->data_size);
+ /* don't know what will be written */
+ mutex_lock(&UTP_CTX(fsg)->lock);
+ list_add_tail(&uud2r->link, &UTP_CTX(fsg)->read);
+ mutex_unlock(&UTP_CTX(fsg)->lock);
+ wake_up(&UTP_CTX(fsg)->wq);
+ /*
+ * Return PASS or FAIL according to uuc's status
+ * Please open it if need to check uuc's status
+ * and use another version uuc
+ */
+#if 0
+ struct utp_user_data *uud = NULL;
+ struct utp_context *ctx;
+ WAIT_ACTIVITY(write);
+ ctx = UTP_CTX(fsg);
+ mutex_lock(&ctx->lock);
+
+ if (!list_empty(&ctx->write))
+ uud = list_first_entry(&ctx->write,
+ struct utp_user_data, link);
+
+ mutex_unlock(&ctx->lock);
+ if (uud) {
+ if (uud->data.flags & UTP_FLAG_STATUS) {
+ printk(KERN_WARNING "%s: exit with status %d\n",
+ __func__, uud->data.status);
+ UTP_SS_EXIT(fsg, uud->data.status);
+ } else {
+ pr_debug("%s: pass\n", __func__);
+ UTP_SS_PASS(fsg);
+ }
+ utp_user_data_free(uud);
+ } else{
+ UTP_SS_PASS(fsg);
+ }
+#endif
+ if (count_list(UTP_CTX(fsg), &UTP_CTX(fsg)->read) < 7) {
+ UTP_CTX(fsg)->cur_state = 0;
+ UTP_SS_PASS(fsg);
+ } else
+ UTP_SS_BUSY(fsg, UTP_CTX(fsg)->counter);
+
+ break;
+ }
+
+ utp_send_status(fsg);
+ return -1;
+}
diff --git a/drivers/usb/gadget/function/fsl_updater.h b/drivers/usb/gadget/function/fsl_updater.h
new file mode 100644
index 000000000000..044beb0e2114
--- /dev/null
+++ b/drivers/usb/gadget/function/fsl_updater.h
@@ -0,0 +1,152 @@
+/*
+ * Freescale UUT driver
+ *
+ * Copyright 2008-2016 Freescale Semiconductor, Inc.
+ * Copyright 2008-2009 Embedded Alley Solutions, Inc All Rights Reserved.
+ * Copyright 2017 NXP
+ */
+
+/*
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#ifndef __FSL_UPDATER_H
+#define __FSL_UPDATER_H
+
+#include <linux/miscdevice.h>
+#include <linux/list.h>
+#include <linux/vmalloc.h>
+#include <linux/ioctl.h>
+/* #include <mach/hardware.h> */
+struct utp_context;
+
+static int utp_init(struct fsg_dev *fsg);
+static void utp_exit(struct fsg_dev *fsg);
+static ssize_t utp_file_read(struct file *file,
+ char __user *buf,
+ size_t size,
+ loff_t *off);
+
+static ssize_t utp_file_write(struct file *file,
+ const char __user *buf,
+ size_t size,
+ loff_t *off);
+
+static bool is_utp_device(struct fsg_dev *fsg);
+static long utp_ioctl(struct file *file,
+ unsigned int cmd, unsigned long arg);
+static struct utp_user_data *utp_user_data_alloc(size_t size);
+static void utp_user_data_free(struct utp_context *utp, struct utp_user_data *uud);
+static int utp_get_sense(struct fsg_dev *fsg);
+static int utp_do_read(struct fsg_dev *fsg, void *data, size_t size);
+static int utp_do_write(struct fsg_dev *fsg, void *data, size_t size);
+static inline void utp_set_sense(struct fsg_dev *fsg, u16 code, u64 reply);
+static int utp_handle_message(struct fsg_dev *fsg,
+ char *cdb_data,
+ int default_reply);
+
+#define UTP_REPLY_PASS 0
+#define UTP_REPLY_EXIT 0x8001
+#define UTP_REPLY_BUSY 0x8002
+#define UTP_REPLY_SIZE 0x8003
+#define UTP_SENSE_KEY 9
+
+#define UTP_MINOR 222
+/* MISC_DYNAMIC_MINOR would be better, but... */
+
+#define UTP_IDVENDOR 0x066F
+#define UTP_IDPRODUCT 0x37FF
+
+#define UTP_COMMAND_SIZE 80
+
+#define UTP_SS_EXIT(fsg, r) utp_set_sense(fsg, UTP_REPLY_EXIT, (u64)r)
+#define UTP_SS_PASS(fsg) utp_set_sense(fsg, UTP_REPLY_PASS, 0)
+#define UTP_SS_BUSY(fsg, r) utp_set_sense(fsg, UTP_REPLY_BUSY, (u64)r)
+#define UTP_SS_SIZE(fsg, r) utp_set_sense(fsg, UTP_REPLY_SIZE, (u64)r)
+
+#define UTP_IOCTL_BASE 'U'
+#define UTP_GET_CPU_ID _IOR(UTP_IOCTL_BASE, 0, int)
+/* the structure of utp message which is mapped to 16-byte SCSI CBW's CDB */
+#pragma pack(1)
+struct utp_msg {
+ u8 f0;
+ u8 utp_msg_type;
+ u32 utp_msg_tag;
+ union {
+ struct {
+ u32 param_lsb;
+ u32 param_msb;
+ };
+ u64 param;
+ };
+};
+
+enum utp_msg_type {
+ UTP_POLL = 0,
+ UTP_EXEC,
+ UTP_GET,
+ UTP_PUT,
+};
+
+struct utp_context {
+ wait_queue_head_t wq;
+ wait_queue_head_t list_full_wq;
+ struct mutex lock;
+ struct list_head read;
+ struct list_head write;
+ u32 sd, sdinfo, sdinfo_h; /* sense data */
+ int processed;
+ u8 *buffer;
+ u32 counter;
+ u64 utp_version;
+ u32 cur_state;
+ struct miscdevice utp_dev;
+ char utp_name[8];
+};
+
+static const struct file_operations utp_fops = {
+ .open = nonseekable_open,
+ .read = utp_file_read,
+ .write = utp_file_write,
+ /* .ioctl = utp_ioctl, */
+ .unlocked_ioctl = utp_ioctl,
+};
+
+#define UTP_FLAG_COMMAND 0x00000001
+#define UTP_FLAG_DATA 0x00000002
+#define UTP_FLAG_STATUS 0x00000004
+#define UTP_FLAG_REPORT_BUSY 0x10000000
+struct utp_message {
+ u32 flags;
+ size_t size;
+ union {
+ struct {
+ u64 payload;
+ char command[1];
+ };
+ struct {
+ size_t bufsize;
+ u8 data[1];
+ };
+ u32 status;
+ };
+};
+
+struct utp_user_data {
+ struct list_head link;
+ struct utp_message data;
+};
+#pragma pack()
+
+static inline struct utp_context *UTP_CTX(struct fsg_dev *fsg)
+{
+ return (struct utp_context *)fsg->utp;
+}
+
+#endif /* __FSL_UPDATER_H */
+
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index 6e834b83a104..5ad03525e7f7 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -93,7 +93,7 @@ module_param (log2_irq_thresh, int, S_IRUGO);
MODULE_PARM_DESC (log2_irq_thresh, "log2 IRQ latency, 1-64 microframes");
/* initial park setting: slower than hw default */
-static unsigned park = 0;
+static unsigned park = 3;
module_param (park, uint, S_IRUGO);
MODULE_PARM_DESC (park, "park setting; 1-3 back-to-back async packets");
@@ -1244,6 +1244,10 @@ static const struct hc_driver ehci_hc_driver = {
* device support
*/
.free_dev = ehci_remove_device,
+#ifdef CONFIG_USB_HCD_TEST_MODE
+ /* EH SINGLE_STEP_SET_FEATURE test support */
+ .submit_single_step_set_feature = ehci_submit_single_step_set_feature,
+#endif
};
void ehci_init_driver(struct hc_driver *drv,
diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c
index 37ef2ac9cdae..ab4788cfcc1d 100644
--- a/drivers/usb/host/ehci-hub.c
+++ b/drivers/usb/host/ehci-hub.c
@@ -730,145 +730,6 @@ ehci_hub_descriptor (
}
/*-------------------------------------------------------------------------*/
-#ifdef CONFIG_USB_HCD_TEST_MODE
-
-#define EHSET_TEST_SINGLE_STEP_SET_FEATURE 0x06
-
-static void usb_ehset_completion(struct urb *urb)
-{
- struct completion *done = urb->context;
-
- complete(done);
-}
-static int submit_single_step_set_feature(
- struct usb_hcd *hcd,
- struct urb *urb,
- int is_setup
-);
-
-/*
- * Allocate and initialize a control URB. This request will be used by the
- * EHSET SINGLE_STEP_SET_FEATURE test in which the DATA and STATUS stages
- * of the GetDescriptor request are sent 15 seconds after the SETUP stage.
- * Return NULL if failed.
- */
-static struct urb *request_single_step_set_feature_urb(
- struct usb_device *udev,
- void *dr,
- void *buf,
- struct completion *done
-) {
- struct urb *urb;
- struct usb_hcd *hcd = bus_to_hcd(udev->bus);
- struct usb_host_endpoint *ep;
-
- urb = usb_alloc_urb(0, GFP_KERNEL);
- if (!urb)
- return NULL;
-
- urb->pipe = usb_rcvctrlpipe(udev, 0);
- ep = (usb_pipein(urb->pipe) ? udev->ep_in : udev->ep_out)
- [usb_pipeendpoint(urb->pipe)];
- if (!ep) {
- usb_free_urb(urb);
- return NULL;
- }
-
- urb->ep = ep;
- urb->dev = udev;
- urb->setup_packet = (void *)dr;
- urb->transfer_buffer = buf;
- urb->transfer_buffer_length = USB_DT_DEVICE_SIZE;
- urb->complete = usb_ehset_completion;
- urb->status = -EINPROGRESS;
- urb->actual_length = 0;
- urb->transfer_flags = URB_DIR_IN;
- usb_get_urb(urb);
- atomic_inc(&urb->use_count);
- atomic_inc(&urb->dev->urbnum);
- urb->setup_dma = dma_map_single(
- hcd->self.sysdev,
- urb->setup_packet,
- sizeof(struct usb_ctrlrequest),
- DMA_TO_DEVICE);
- urb->transfer_dma = dma_map_single(
- hcd->self.sysdev,
- urb->transfer_buffer,
- urb->transfer_buffer_length,
- DMA_FROM_DEVICE);
- urb->context = done;
- return urb;
-}
-
-static int ehset_single_step_set_feature(struct usb_hcd *hcd, int port)
-{
- int retval = -ENOMEM;
- struct usb_ctrlrequest *dr;
- struct urb *urb;
- struct usb_device *udev;
- struct ehci_hcd *ehci = hcd_to_ehci(hcd);
- struct usb_device_descriptor *buf;
- DECLARE_COMPLETION_ONSTACK(done);
-
- /* Obtain udev of the rhub's child port */
- udev = usb_hub_find_child(hcd->self.root_hub, port);
- if (!udev) {
- ehci_err(ehci, "No device attached to the RootHub\n");
- return -ENODEV;
- }
- buf = kmalloc(USB_DT_DEVICE_SIZE, GFP_KERNEL);
- if (!buf)
- return -ENOMEM;
-
- dr = kmalloc(sizeof(struct usb_ctrlrequest), GFP_KERNEL);
- if (!dr) {
- kfree(buf);
- return -ENOMEM;
- }
-
- /* Fill Setup packet for GetDescriptor */
- dr->bRequestType = USB_DIR_IN;
- dr->bRequest = USB_REQ_GET_DESCRIPTOR;
- dr->wValue = cpu_to_le16(USB_DT_DEVICE << 8);
- dr->wIndex = 0;
- dr->wLength = cpu_to_le16(USB_DT_DEVICE_SIZE);
- urb = request_single_step_set_feature_urb(udev, dr, buf, &done);
- if (!urb)
- goto cleanup;
-
- /* Submit just the SETUP stage */
- retval = submit_single_step_set_feature(hcd, urb, 1);
- if (retval)
- goto out1;
- if (!wait_for_completion_timeout(&done, msecs_to_jiffies(2000))) {
- usb_kill_urb(urb);
- retval = -ETIMEDOUT;
- ehci_err(ehci, "%s SETUP stage timed out on ep0\n", __func__);
- goto out1;
- }
- msleep(15 * 1000);
-
- /* Complete remaining DATA and STATUS stages using the same URB */
- urb->status = -EINPROGRESS;
- usb_get_urb(urb);
- atomic_inc(&urb->use_count);
- atomic_inc(&urb->dev->urbnum);
- retval = submit_single_step_set_feature(hcd, urb, 0);
- if (!retval && !wait_for_completion_timeout(&done,
- msecs_to_jiffies(2000))) {
- usb_kill_urb(urb);
- retval = -ETIMEDOUT;
- ehci_err(ehci, "%s IN stage timed out on ep0\n", __func__);
- }
-out1:
- usb_free_urb(urb);
-cleanup:
- kfree(dr);
- kfree(buf);
- return retval;
-}
-#endif /* CONFIG_USB_HCD_TEST_MODE */
-/*-------------------------------------------------------------------------*/
int ehci_hub_control(
struct usb_hcd *hcd,
@@ -943,7 +804,7 @@ int ehci_hub_control(
break;
#ifdef CONFIG_USB_OTG
if ((hcd->self.otg_port == (wIndex + 1))
- && hcd->self.b_hnp_enable) {
+ && hcd->self.b_hnp_enable && !hcd->self.otg_fsm) {
otg_start_hnp(hcd->usb_phy->otg);
break;
}
diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c
index 8f3f055c05fa..a33c49cae3de 100644
--- a/drivers/usb/host/ehci-q.c
+++ b/drivers/usb/host/ehci-q.c
@@ -1167,7 +1167,7 @@ submit_async (
* performed; TRUE - SETUP and FALSE - IN+STATUS
* Returns 0 if success
*/
-static int submit_single_step_set_feature(
+static int ehci_submit_single_step_set_feature(
struct usb_hcd *hcd,
struct urb *urb,
int is_setup
@@ -1201,10 +1201,10 @@ static int submit_single_step_set_feature(
* 15 secs after the setup
*/
if (is_setup) {
- /* SETUP pid */
+ /* SETUP pid, and interrupt after SETUP completion */
qtd_fill(ehci, qtd, urb->setup_dma,
sizeof(struct usb_ctrlrequest),
- token | (2 /* "setup" */ << 8), 8);
+ QTD_IOC | token | (2 /* "setup" */ << 8), 8);
submit_async(ehci, urb, &qtd_list, GFP_ATOMIC);
return 0; /*Return now; we shall come back after 15 seconds*/
@@ -1241,12 +1241,8 @@ static int submit_single_step_set_feature(
qtd_prev->hw_next = QTD_NEXT(ehci, qtd->qtd_dma);
list_add_tail(&qtd->qtd_list, head);
- /* dont fill any data in such packets */
- qtd_fill(ehci, qtd, 0, 0, token, 0);
-
- /* by default, enable interrupt on urb completion */
- if (likely(!(urb->transfer_flags & URB_NO_INTERRUPT)))
- qtd->hw_token |= cpu_to_hc32(ehci, QTD_IOC);
+ /* Interrupt after STATUS completion */
+ qtd_fill(ehci, qtd, 0, 0, token | QTD_IOC, 0);
submit_async(ehci, urb, &qtd_list, GFP_KERNEL);
diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c
index f5f2c83a2c66..60f0d515a26b 100644
--- a/drivers/usb/host/pci-quirks.c
+++ b/drivers/usb/host/pci-quirks.c
@@ -1274,23 +1274,3 @@ static void quirk_usb_early_handoff(struct pci_dev *pdev)
}
DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_ANY_ID, PCI_ANY_ID,
PCI_CLASS_SERIAL_USB, 8, quirk_usb_early_handoff);
-
-bool usb_xhci_needs_pci_reset(struct pci_dev *pdev)
-{
- /*
- * Our dear uPD72020{1,2} friend only partially resets when
- * asked to via the XHCI interface, and may end up doing DMA
- * at the wrong addresses, as it keeps the top 32bit of some
- * addresses from its previous programming under obscure
- * circumstances.
- * Give it a good wack at probe time. Unfortunately, this
- * needs to happen before we've had a chance to discover any
- * quirk, or the system will be in a rather bad state.
- */
- if (pdev->vendor == PCI_VENDOR_ID_RENESAS &&
- (pdev->device == 0x0014 || pdev->device == 0x0015))
- return true;
-
- return false;
-}
-EXPORT_SYMBOL_GPL(usb_xhci_needs_pci_reset);
diff --git a/drivers/usb/host/pci-quirks.h b/drivers/usb/host/pci-quirks.h
index 4ca0d9b7e463..63c633077d9e 100644
--- a/drivers/usb/host/pci-quirks.h
+++ b/drivers/usb/host/pci-quirks.h
@@ -16,7 +16,6 @@ void usb_asmedia_modifyflowcontrol(struct pci_dev *pdev);
void usb_enable_intel_xhci_ports(struct pci_dev *xhci_pdev);
void usb_disable_xhci_ports(struct pci_dev *xhci_pdev);
void sb800_prefetch(struct device *dev, int on);
-bool usb_xhci_needs_pci_reset(struct pci_dev *pdev);
bool usb_amd_pt_check_port(struct device *device, int port);
#else
struct pci_dev;
diff --git a/drivers/usb/host/xhci-dbg.c b/drivers/usb/host/xhci-dbg.c
index 2c83b37ae8f2..0bd8e6b260a0 100644
--- a/drivers/usb/host/xhci-dbg.c
+++ b/drivers/usb/host/xhci-dbg.c
@@ -238,6 +238,9 @@ void xhci_print_run_regs(struct xhci_hcd *xhci)
xhci_dbg(xhci, " %p: Microframe index = 0x%x\n",
&xhci->run_regs->microframe_index,
(unsigned int) temp);
+ if (xhci->quirks & XHCI_SKIP_ACCESS_RESERVED_REG)
+ return;
+
for (i = 0; i < 7; i++) {
temp = readl(&xhci->run_regs->rsvd[i]);
if (temp != XHCI_INIT_VALUE)
@@ -251,7 +254,8 @@ void xhci_print_registers(struct xhci_hcd *xhci)
{
xhci_print_cap_regs(xhci);
xhci_print_op_regs(xhci);
- xhci_print_ports(xhci);
+ if (!(xhci->quirks & XHCI_SKIP_ACCESS_RESERVED_REG))
+ xhci_print_ports(xhci);
}
void xhci_dbg_erst(struct xhci_hcd *xhci, struct xhci_erst *erst)
diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c
index 95503bb9b067..6bd3eaa30688 100644
--- a/drivers/usb/host/xhci-hub.c
+++ b/drivers/usb/host/xhci-hub.c
@@ -1321,6 +1321,15 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
/* 4.19.6 Port Test Modes (USB2 Test Mode) */
if (hcd->speed != HCD_USB2)
goto error;
+#ifdef CONFIG_USB_HCD_TEST_MODE
+ if (test_mode == EHSET_TEST_SINGLE_STEP_SET_FEATURE) {
+ spin_unlock_irqrestore(&xhci->lock, flags);
+ retval = ehset_single_step_set_feature(hcd,
+ wIndex + 1);
+ spin_lock_irqsave(&xhci->lock, flags);
+ break;
+ }
+#endif
if (test_mode > TEST_FORCE_EN || test_mode < TEST_J)
goto error;
retval = xhci_enter_test_mode(xhci, test_mode, wIndex,
@@ -1583,6 +1592,7 @@ int xhci_bus_suspend(struct usb_hcd *hcd)
spin_unlock_irqrestore(&xhci->lock, flags);
return 0;
}
+EXPORT_SYMBOL(xhci_bus_suspend);
/*
* Workaround for missing Cold Attach Status (CAS) if device re-plugged in S3.
diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c
index 021a2d320acc..4f51feeec6fa 100644
--- a/drivers/usb/host/xhci-pci.c
+++ b/drivers/usb/host/xhci-pci.c
@@ -303,13 +303,6 @@ static int xhci_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
driver = (struct hc_driver *)id->driver_data;
- /* For some HW implementation, a XHCI reset is just not enough... */
- if (usb_xhci_needs_pci_reset(dev)) {
- dev_info(&dev->dev, "Resetting\n");
- if (pci_reset_function_locked(dev))
- dev_warn(&dev->dev, "Reset failed");
- }
-
/* Prevent runtime suspending between USB-2 and USB-3 initialization */
pm_runtime_get_noresume(&dev->dev);
diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c
index 108a212294bf..eaed46b1c846 100644
--- a/drivers/usb/host/xhci-plat.c
+++ b/drivers/usb/host/xhci-plat.c
@@ -20,6 +20,8 @@
#include <linux/usb/phy.h>
#include <linux/slab.h>
#include <linux/acpi.h>
+#include <linux/busfreq-imx.h>
+#include <linux/usb/of.h>
#include "xhci.h"
#include "xhci-plat.h"
@@ -266,6 +268,9 @@ static int xhci_plat_probe(struct platform_device *pdev)
if (device_property_read_bool(sysdev, "usb3-lpm-capable"))
xhci->quirks |= XHCI_LPM_SUPPORT;
+ if (device_property_read_bool(sysdev, "usb3-resume-missing-cas"))
+ xhci->quirks |= XHCI_MISSING_CAS;
+
if (device_property_read_bool(&pdev->dev, "quirk-broken-port-ped"))
xhci->quirks |= XHCI_BROKEN_PORT_PED;
@@ -281,6 +286,10 @@ static int xhci_plat_probe(struct platform_device *pdev)
goto put_usb3_hcd;
}
+ request_bus_freq(BUS_FREQ_HIGH);
+ hcd->tpl_support = of_usb_host_tpl_support(sysdev->of_node);
+ xhci->shared_hcd->tpl_support = hcd->tpl_support;
+
ret = usb_add_hcd(hcd, irq, IRQF_SHARED);
if (ret)
goto disable_usb_phy;
@@ -295,12 +304,6 @@ static int xhci_plat_probe(struct platform_device *pdev)
device_enable_async_suspend(&pdev->dev);
pm_runtime_put_noidle(&pdev->dev);
- /*
- * Prevent runtime pm from being on as default, users should enable
- * runtime pm using power/control in sysfs.
- */
- pm_runtime_forbid(&pdev->dev);
-
return 0;
@@ -309,6 +312,7 @@ dealloc_usb2_hcd:
disable_usb_phy:
usb_phy_shutdown(hcd->usb_phy);
+ release_bus_freq(BUS_FREQ_HIGH);
put_usb3_hcd:
usb_put_hcd(xhci->shared_hcd);
@@ -347,6 +351,9 @@ static int xhci_plat_remove(struct platform_device *dev)
clk_disable_unprepare(clk);
usb_put_hcd(hcd);
+ if (!pm_runtime_suspended(&dev->dev))
+ release_bus_freq(BUS_FREQ_HIGH);
+
pm_runtime_set_suspended(&dev->dev);
pm_runtime_disable(&dev->dev);
@@ -384,18 +391,14 @@ static int __maybe_unused xhci_plat_resume(struct device *dev)
static int __maybe_unused xhci_plat_runtime_suspend(struct device *dev)
{
- struct usb_hcd *hcd = dev_get_drvdata(dev);
- struct xhci_hcd *xhci = hcd_to_xhci(hcd);
-
- return xhci_suspend(xhci, true);
+ release_bus_freq(BUS_FREQ_HIGH);
+ return 0;
}
static int __maybe_unused xhci_plat_runtime_resume(struct device *dev)
{
- struct usb_hcd *hcd = dev_get_drvdata(dev);
- struct xhci_hcd *xhci = hcd_to_xhci(hcd);
-
- return xhci_resume(xhci, 0);
+ request_bus_freq(BUS_FREQ_HIGH);
+ return 0;
}
static const struct dev_pm_ops xhci_plat_pm_ops = {
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index 89af395cd89c..d70aae05769b 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -1640,6 +1640,11 @@ static void handle_port_status(struct xhci_hcd *xhci,
if ((major_revision == 0x03) != (hcd->speed >= HCD_USB3))
hcd = xhci->shared_hcd;
+ if (!hcd) {
+ bogus_port_status = true;
+ goto cleanup;
+ }
+
if (major_revision == 0) {
xhci_warn(xhci, "Event for port %u not in "
"Extended Capabilities, ignoring.\n",
@@ -2063,12 +2068,9 @@ static int process_ctrl_td(struct xhci_hcd *xhci, struct xhci_td *td,
switch (trb_comp_code) {
case COMP_SUCCESS:
- if (trb_type != TRB_STATUS) {
- xhci_warn(xhci, "WARN: Success on ctrl %s TRB without IOC set?\n",
+ if (trb_type != TRB_STATUS)
+ xhci_dbg(xhci, "Success on ctrl %s TRB without IOC set?\n",
(trb_type == TRB_DATA) ? "data" : "setup");
- *status = -ESHUTDOWN;
- break;
- }
*status = 0;
break;
case COMP_SHORT_PACKET:
@@ -3524,6 +3526,129 @@ int xhci_queue_ctrl_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
return 0;
}
+#ifdef CONFIG_USB_HCD_TEST_MODE
+/*
+ * This function prepare TRBs and submits them for the
+ * SINGLE_STEP_SET_FEATURE Test.
+ * This is done in two parts: first SETUP req for GetDesc is sent then
+ * 15 seconds later, the IN stage for GetDesc starts to req data from dev
+ *
+ * is_setup : argument decides which of the two stage needs to be
+ * performed; TRUE - SETUP and FALSE - IN+STATUS
+ * Returns 0 if success
+ */
+int xhci_submit_single_step_set_feature(struct usb_hcd *hcd,
+ struct urb *urb, int is_setup)
+{
+ int slot_id;
+ unsigned int ep_index;
+ struct xhci_ring *ep_ring;
+ int ret;
+ struct usb_ctrlrequest *setup;
+ struct xhci_generic_trb *start_trb;
+ int start_cycle;
+ u32 field, length_field, remainder;
+ struct urb_priv *urb_priv;
+ struct xhci_td *td;
+ struct xhci_hcd *xhci = hcd_to_xhci(hcd);
+
+ /* urb_priv will be free after transcation has completed */
+ urb_priv = kzalloc(sizeof(struct urb_priv) +
+ sizeof(struct xhci_td), GFP_KERNEL);
+ if (!urb_priv)
+ return -ENOMEM;
+
+ td = &urb_priv->td[0];
+ urb_priv->num_tds = 1;
+ urb_priv->num_tds_done = 0;
+ urb->hcpriv = urb_priv;
+
+ ep_ring = xhci_urb_to_transfer_ring(xhci, urb);
+ if (!ep_ring) {
+ ret = -EINVAL;
+ goto free_priv;
+ }
+
+ slot_id = urb->dev->slot_id;
+ ep_index = xhci_get_endpoint_index(&urb->ep->desc);
+
+ setup = (struct usb_ctrlrequest *) urb->setup_packet;
+ if (is_setup) {
+ ret = prepare_transfer(xhci, xhci->devs[slot_id],
+ ep_index, urb->stream_id,
+ 1, urb, 0, GFP_KERNEL);
+ if (ret < 0)
+ goto free_priv;
+
+ start_trb = &ep_ring->enqueue->generic;
+ start_cycle = ep_ring->cycle_state;
+ /* Save the DMA address of the last TRB in the TD */
+ td->last_trb = ep_ring->enqueue;
+ field = TRB_IOC | TRB_IDT | TRB_TYPE(TRB_SETUP) | start_cycle;
+ /* xHCI 1.0/1.1 6.4.1.2.1: Transfer Type field */
+ if ((xhci->hci_version >= 0x100) ||
+ (xhci->quirks & XHCI_MTK_HOST))
+ field |= TRB_TX_TYPE(TRB_DATA_IN);
+
+ queue_trb(xhci, ep_ring, false,
+ setup->bRequestType | setup->bRequest << 8 |
+ le16_to_cpu(setup->wValue) << 16,
+ le16_to_cpu(setup->wIndex) |
+ le16_to_cpu(setup->wLength) << 16,
+ TRB_LEN(8) | TRB_INTR_TARGET(0),
+ /* Immediate data in pointer */
+ field);
+ giveback_first_trb(xhci, slot_id, ep_index, urb->stream_id,
+ start_cycle, start_trb);
+ return 0;
+ }
+
+ ret = prepare_transfer(xhci, xhci->devs[slot_id],
+ ep_index, urb->stream_id,
+ 2, urb, 0, GFP_KERNEL);
+ if (ret < 0)
+ goto free_priv;
+
+ start_trb = &ep_ring->enqueue->generic;
+ start_cycle = ep_ring->cycle_state;
+ field = TRB_ISP | TRB_TYPE(TRB_DATA);
+
+ remainder = xhci_td_remainder(xhci, 0,
+ urb->transfer_buffer_length,
+ urb->transfer_buffer_length,
+ urb, 1);
+
+ length_field = TRB_LEN(urb->transfer_buffer_length) |
+ TRB_TD_SIZE(remainder) |
+ TRB_INTR_TARGET(0);
+
+ if (urb->transfer_buffer_length > 0) {
+ field |= TRB_DIR_IN;
+ queue_trb(xhci, ep_ring, true,
+ lower_32_bits(urb->transfer_dma),
+ upper_32_bits(urb->transfer_dma),
+ length_field,
+ field | ep_ring->cycle_state);
+ }
+
+ td->last_trb = ep_ring->enqueue;
+ field = TRB_IOC | TRB_TYPE(TRB_STATUS) | ep_ring->cycle_state;
+ queue_trb(xhci, ep_ring, false,
+ 0,
+ 0,
+ TRB_INTR_TARGET(0),
+ field);
+
+ giveback_first_trb(xhci, slot_id, ep_index, 0,
+ start_cycle, start_trb);
+
+ return 0;
+free_priv:
+ xhci_urb_free_priv(urb_priv);
+ return ret;
+}
+#endif /* CONFIG_USB_HCD_TEST_MODE */
+
/*
* The transfer burst count field of the isochronous TRB defines the number of
* bursts that are required to move all packets in this TD. Only SuperSpeed
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 6c0a0ca316d3..a161ccb829fa 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -203,7 +203,7 @@ int xhci_reset(struct xhci_hcd *xhci)
* Without this delay, the subsequent HC register access,
* may result in a system hang very rarely.
*/
- if (xhci->quirks & XHCI_INTEL_HOST)
+ if (xhci->quirks & (XHCI_INTEL_HOST | XHCI_CDNS_HOST))
udelay(1000);
ret = xhci_handshake(&xhci->op_regs->command,
@@ -5063,6 +5063,7 @@ static const struct hc_driver xhci_hc_driver = {
.enable_usb3_lpm_timeout = xhci_enable_usb3_lpm_timeout,
.disable_usb3_lpm_timeout = xhci_disable_usb3_lpm_timeout,
.find_raw_port_number = xhci_find_raw_port_number,
+ .submit_single_step_set_feature = xhci_submit_single_step_set_feature,
};
void xhci_init_driver(struct hc_driver *drv,
@@ -5079,6 +5080,8 @@ void xhci_init_driver(struct hc_driver *drv,
drv->reset = over->reset;
if (over->start)
drv->start = over->start;
+ if (over->bus_suspend)
+ drv->bus_suspend = over->bus_suspend;
}
}
EXPORT_SYMBOL_GPL(xhci_init_driver);
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index db1af99d53bd..6edb43a65f5a 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -1840,6 +1840,8 @@ struct xhci_hcd {
#define XHCI_INTEL_USB_ROLE_SW BIT_ULL(31)
#define XHCI_RESET_PLL_ON_DISCONNECT BIT_ULL(34)
#define XHCI_SNPS_BROKEN_SUSPEND BIT_ULL(35)
+#define XHCI_SKIP_ACCESS_RESERVED_REG (1 << 29)
+#define XHCI_CDNS_HOST (1 << 31)
unsigned int num_active_eps;
unsigned int limit_active_eps;
@@ -1880,6 +1882,7 @@ struct xhci_driver_overrides {
size_t extra_priv_size;
int (*reset)(struct usb_hcd *hcd);
int (*start)(struct usb_hcd *hcd);
+ int (*bus_suspend)(struct usb_hcd *hcd);
};
#define XHCI_CFC_DELAY 10
@@ -2097,6 +2100,16 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, u16 wIndex,
int xhci_hub_status_data(struct usb_hcd *hcd, char *buf);
int xhci_find_raw_port_number(struct usb_hcd *hcd, int port1);
void xhci_hc_died(struct xhci_hcd *xhci);
+#ifdef CONFIG_USB_HCD_TEST_MODE
+int xhci_submit_single_step_set_feature(struct usb_hcd *hcd,
+ struct urb *urb, int is_setup);
+#else
+static inline int xhci_submit_single_step_set_feature(struct usb_hcd *hcd,
+ struct urb *urb, int is_setup)
+{
+ return 0;
+}
+#endif
#ifdef CONFIG_PM
int xhci_bus_suspend(struct usb_hcd *hcd);
diff --git a/drivers/usb/misc/ehset.c b/drivers/usb/misc/ehset.c
index c31b4a33e6bb..f54473cd25b3 100644
--- a/drivers/usb/misc/ehset.c
+++ b/drivers/usb/misc/ehset.c
@@ -17,6 +17,7 @@
#include <linux/slab.h>
#include <linux/usb.h>
#include <linux/usb/ch11.h>
+#include <linux/usb/otg-fsm.h>
#define TEST_SE0_NAK_PID 0x0101
#define TEST_J_PID 0x0102
@@ -25,6 +26,7 @@
#define TEST_HS_HOST_PORT_SUSPEND_RESUME 0x0106
#define TEST_SINGLE_STEP_GET_DEV_DESC 0x0107
#define TEST_SINGLE_STEP_SET_FEATURE 0x0108
+#define TEST_OTG_TEST_DEVICE_SUPPORT 0x0200
static int ehset_probe(struct usb_interface *intf,
const struct usb_device_id *id)
@@ -35,6 +37,7 @@ static int ehset_probe(struct usb_interface *intf,
struct usb_device_descriptor *buf;
u8 portnum = dev->portnum;
u16 test_pid = le16_to_cpu(dev->descriptor.idProduct);
+ struct otg_fsm *fsm = dev->bus->otg_fsm;
switch (test_pid) {
case TEST_SE0_NAK_PID:
@@ -115,6 +118,27 @@ static int ehset_probe(struct usb_interface *intf,
NULL, 0, 60 * 1000);
break;
+ case TEST_OTG_TEST_DEVICE_SUPPORT:
+ if (!fsm)
+ return ret;
+
+ /* B host enumerate test device */
+ if (dev->bus->is_b_host) {
+ otg_add_timer(fsm, B_TST_SUSP);
+ ret = 0;
+ break;
+ }
+
+ mutex_lock(&fsm->lock);
+ fsm->tst_maint = 1;
+ if (le16_to_cpu(dev->descriptor.bcdDevice) & 0x1)
+ fsm->otg_vbus_off = 1;
+ else
+ fsm->otg_vbus_off = 0;
+ mutex_unlock(&fsm->lock);
+ otg_add_timer(fsm, A_TST_MAINT);
+ ret = 0;
+ break;
default:
dev_err(&intf->dev, "%s: unsupported PID: 0x%x\n",
__func__, test_pid);
@@ -135,6 +159,7 @@ static const struct usb_device_id ehset_id_table[] = {
{ USB_DEVICE(0x1a0a, TEST_HS_HOST_PORT_SUSPEND_RESUME) },
{ USB_DEVICE(0x1a0a, TEST_SINGLE_STEP_GET_DEV_DESC) },
{ USB_DEVICE(0x1a0a, TEST_SINGLE_STEP_SET_FEATURE) },
+ { USB_DEVICE(0x1a0a, TEST_OTG_TEST_DEVICE_SUPPORT) },
{ } /* Terminating entry */
};
MODULE_DEVICE_TABLE(usb, ehset_id_table);
diff --git a/drivers/usb/phy/Kconfig b/drivers/usb/phy/Kconfig
index 85a92d0813dd..2b64621ecb32 100644
--- a/drivers/usb/phy/Kconfig
+++ b/drivers/usb/phy/Kconfig
@@ -180,7 +180,7 @@ config USB_MV_OTG
config USB_MXS_PHY
tristate "Freescale MXS USB PHY support"
- depends on ARCH_MXC || ARCH_MXS
+ depends on ARCH_MXC || ARCH_MXS || ARCH_MXC_ARM64
select STMP_DEVICE
select USB_PHY
help
diff --git a/drivers/usb/phy/phy-mxs-usb.c b/drivers/usb/phy/phy-mxs-usb.c
index 0e2f1a36d315..18e256ad7ed6 100644
--- a/drivers/usb/phy/phy-mxs-usb.c
+++ b/drivers/usb/phy/phy-mxs-usb.c
@@ -1,5 +1,6 @@
/*
- * Copyright 2012-2014 Freescale Semiconductor, Inc.
+ * Copyright 2012-2016 Freescale Semiconductor, Inc.
+ * Copyright 2017 NXP
* Copyright (C) 2012 Marek Vasut <marex@denx.de>
* on behalf of DENX Software Engineering GmbH
*
@@ -23,9 +24,11 @@
#include <linux/of_device.h>
#include <linux/regmap.h>
#include <linux/mfd/syscon.h>
+#include <linux/regulator/consumer.h>
#define DRIVER_NAME "mxs_phy"
+/* Register Macro */
#define HW_USBPHY_PWD 0x00
#define HW_USBPHY_TX 0x10
#define HW_USBPHY_CTRL 0x30
@@ -43,6 +46,11 @@
#define GM_USBPHY_TX_TXCAL45DN(x) (((x) & 0xf) << 8)
#define GM_USBPHY_TX_D_CAL(x) (((x) & 0xf) << 0)
+/* imx7ulp */
+#define HW_USBPHY_PLL_SIC 0xa4
+#define HW_USBPHY_PLL_SIC_SET 0xa4
+#define HW_USBPHY_PLL_SIC_CLR 0xa8
+
#define BM_USBPHY_CTRL_SFTRST BIT(31)
#define BM_USBPHY_CTRL_CLKGATE BIT(30)
#define BM_USBPHY_CTRL_OTG_ID_VALUE BIT(27)
@@ -61,17 +69,44 @@
#define BM_USBPHY_IP_FIX (BIT(17) | BIT(18))
#define BM_USBPHY_DEBUG_CLKGATE BIT(30)
+/* imx7ulp */
+#define BM_USBPHY_PLL_LOCK BIT(31)
+#define BM_USBPHY_PLL_REG_ENABLE BIT(21)
+#define BM_USBPHY_PLL_BYPASS BIT(16)
+#define BM_USBPHY_PLL_POWER BIT(12)
+#define BM_USBPHY_PLL_EN_USB_CLKS BIT(6)
/* Anatop Registers */
+#define ANADIG_PLL_USB2 0x20
+#define ANADIG_PLL_USB2_SET 0x24
+#define ANADIG_PLL_USB2_CLR 0x28
+#define ANADIG_REG_1P1_SET 0x114
+#define ANADIG_REG_1P1_CLR 0x118
+
#define ANADIG_ANA_MISC0 0x150
#define ANADIG_ANA_MISC0_SET 0x154
#define ANADIG_ANA_MISC0_CLR 0x158
+#define ANADIG_USB1_CHRG_DETECT_SET 0x1b4
+#define ANADIG_USB1_CHRG_DETECT_CLR 0x1b8
+#define ANADIG_USB1_CHRG_DETECT_EN_B BIT(20)
+#define ANADIG_USB1_CHRG_DETECT_CHK_CHRG_B BIT(19)
+#define ANADIG_USB1_CHRG_DETECT_CHK_CONTACT BIT(18)
+
#define ANADIG_USB1_VBUS_DET_STAT 0x1c0
+#define ANADIG_USB1_VBUS_DET_STAT_VBUS_VALID BIT(3)
+
+#define ANADIG_USB1_CHRG_DET_STAT 0x1d0
+#define ANADIG_USB1_CHRG_DET_STAT_DM_STATE BIT(2)
+#define ANADIG_USB1_CHRG_DET_STAT_CHRG_DETECTED BIT(1)
+#define ANADIG_USB1_CHRG_DET_STAT_PLUG_CONTACT BIT(0)
+
#define ANADIG_USB2_VBUS_DET_STAT 0x220
#define ANADIG_USB1_LOOPBACK_SET 0x1e4
#define ANADIG_USB1_LOOPBACK_CLR 0x1e8
+#define ANADIG_USB1_LOOPBACK_UTMI_TESTSTART BIT(0)
+
#define ANADIG_USB2_LOOPBACK_SET 0x244
#define ANADIG_USB2_LOOPBACK_CLR 0x248
@@ -94,6 +129,41 @@
#define BM_ANADIG_USB2_MISC_RX_VPIN_FS BIT(29)
#define BM_ANADIG_USB2_MISC_RX_VMIN_FS BIT(28)
+#define BM_ANADIG_REG_1P1_ENABLE_WEAK_LINREG BIT(18)
+#define BM_ANADIG_REG_1P1_TRACK_VDD_SOC_CAP BIT(19)
+
+#define BM_ANADIG_PLL_USB2_HOLD_RING_OFF BIT(11)
+
+/* DCD module, the offset is 0x800 */
+#define DCD_CONTROL 0x800
+#define DCD_CLOCK (DCD_CONTROL + 0x4)
+#define DCD_STATUS (DCD_CONTROL + 0x8)
+
+#define DCD_CONTROL_SR BIT(25)
+#define DCD_CONTROL_START BIT(24)
+#define DCD_CONTROL_BC12 BIT(17)
+#define DCD_CONTROL_IE BIT(16)
+#define DCD_CONTROL_IF BIT(8)
+#define DCD_CONTROL_IACK BIT(0)
+
+#define DCD_CLOCK_MHZ BIT(0)
+
+#define DCD_STATUS_ACTIVE BIT(22)
+#define DCD_STATUS_TO BIT(21)
+#define DCD_STATUS_ERR BIT(20)
+#define DCD_STATUS_SEQ_STAT (BIT(18) | BIT(19))
+#define DCD_CHG_PORT BIT(19)
+#define DCD_CHG_DET (BIT(18) | BIT(19))
+#define DCD_CHG_DPIN BIT(18)
+#define DCD_STATUS_SEQ_RES (BIT(16) | BIT(17))
+#define DCD_SDP_PORT BIT(16)
+#define DCD_CDP_PORT BIT(17)
+#define DCD_DCP_PORT (BIT(16) | BIT(17))
+/* System Integration Module (SIM) Registers */
+#define SIM_GPR1 0x30
+
+#define USB_PHY_VLLS_WAKEUP_EN BIT(0)
+
#define to_mxs_phy(p) container_of((p), struct mxs_phy, phy)
/* Do disconnection between PHY and controller without vbus */
@@ -126,6 +196,19 @@
#define MXS_PHY_TX_D_CAL_MIN 79
#define MXS_PHY_TX_D_CAL_MAX 119
+/*
+ * At some versions, the PHY2's clock is controlled by hardware directly,
+ * eg, according to PHY's suspend status. In these PHYs, we only need to
+ * open the clock at the initialization and close it at its shutdown routine.
+ * It will be benefit for remote wakeup case which needs to send resume
+ * signal as soon as possible, and in this case, the resume signal can be sent
+ * out without software interfere.
+ */
+#define MXS_PHY_HARDWARE_CONTROL_PHY2_CLK BIT(4)
+
+/* The MXS PHYs which have DCD module for charger detection */
+#define MXS_PHY_HAS_DCD BIT(5)
+
struct mxs_phy_data {
unsigned int flags;
};
@@ -137,12 +220,14 @@ static const struct mxs_phy_data imx23_phy_data = {
static const struct mxs_phy_data imx6q_phy_data = {
.flags = MXS_PHY_SENDING_SOF_TOO_FAST |
MXS_PHY_DISCONNECT_LINE_WITHOUT_VBUS |
- MXS_PHY_NEED_IP_FIX,
+ MXS_PHY_NEED_IP_FIX |
+ MXS_PHY_HARDWARE_CONTROL_PHY2_CLK,
};
static const struct mxs_phy_data imx6sl_phy_data = {
.flags = MXS_PHY_DISCONNECT_LINE_WITHOUT_VBUS |
- MXS_PHY_NEED_IP_FIX,
+ MXS_PHY_NEED_IP_FIX |
+ MXS_PHY_HARDWARE_CONTROL_PHY2_CLK,
};
static const struct mxs_phy_data vf610_phy_data = {
@@ -151,14 +236,22 @@ static const struct mxs_phy_data vf610_phy_data = {
};
static const struct mxs_phy_data imx6sx_phy_data = {
- .flags = MXS_PHY_DISCONNECT_LINE_WITHOUT_VBUS,
+ .flags = MXS_PHY_DISCONNECT_LINE_WITHOUT_VBUS |
+ MXS_PHY_HARDWARE_CONTROL_PHY2_CLK,
};
static const struct mxs_phy_data imx6ul_phy_data = {
- .flags = MXS_PHY_DISCONNECT_LINE_WITHOUT_VBUS,
+ .flags = MXS_PHY_DISCONNECT_LINE_WITHOUT_VBUS |
+ MXS_PHY_HARDWARE_CONTROL_PHY2_CLK,
+};
+
+static const struct mxs_phy_data imx7ulp_phy_data = {
+ .flags = MXS_PHY_HAS_DCD,
};
static const struct of_device_id mxs_phy_dt_ids[] = {
+ { .compatible = "fsl,imx7ulp-usbphy", .data = &imx7ulp_phy_data, },
+ { .compatible = "fsl,imx6ul-usbphy", .data = &imx6sx_phy_data, },
{ .compatible = "fsl,imx6sx-usbphy", .data = &imx6sx_phy_data, },
{ .compatible = "fsl,imx6sl-usbphy", .data = &imx6sl_phy_data, },
{ .compatible = "fsl,imx6q-usbphy", .data = &imx6q_phy_data, },
@@ -174,9 +267,14 @@ struct mxs_phy {
struct clk *clk;
const struct mxs_phy_data *data;
struct regmap *regmap_anatop;
+ struct regmap *regmap_sim;
int port_id;
u32 tx_reg_set;
u32 tx_reg_mask;
+ struct regulator *phy_3p0;
+ bool hardware_control_phy2_clk;
+ enum usb_current_mode mode;
+ unsigned long clk_rate;
};
static inline bool is_imx6q_phy(struct mxs_phy *mxs_phy)
@@ -189,6 +287,16 @@ static inline bool is_imx6sl_phy(struct mxs_phy *mxs_phy)
return mxs_phy->data == &imx6sl_phy_data;
}
+static inline bool is_imx6ul_phy(struct mxs_phy *mxs_phy)
+{
+ return mxs_phy->data == &imx6ul_phy_data;
+}
+
+static inline bool is_imx7ulp_phy(struct mxs_phy *mxs_phy)
+{
+ return mxs_phy->data == &imx7ulp_phy_data;
+}
+
/*
* PHY needs some 32K cycles to switch from 32K clock to
* bus (such as AHB/AXI, etc) clock.
@@ -212,14 +320,69 @@ static void mxs_phy_tx_init(struct mxs_phy *mxs_phy)
}
}
+static int wait_for_pll_lock(const void __iomem *base)
+{
+ int loop_count = 100;
+
+ /* Wait for PLL to lock */
+ do {
+ if (readl(base + HW_USBPHY_PLL_SIC) & BM_USBPHY_PLL_LOCK)
+ break;
+ usleep_range(100, 150);
+ } while (loop_count-- > 0);
+
+ return readl(base + HW_USBPHY_PLL_SIC) & BM_USBPHY_PLL_LOCK
+ ? 0 : -ETIMEDOUT;
+}
+
+static int mxs_phy_pll_enable(void __iomem *base, bool enable)
+{
+ int ret = 0;
+
+ if (enable) {
+ writel(BM_USBPHY_PLL_REG_ENABLE, base + HW_USBPHY_PLL_SIC_SET);
+ writel(BM_USBPHY_PLL_BYPASS, base + HW_USBPHY_PLL_SIC_CLR);
+ writel(BM_USBPHY_PLL_POWER, base + HW_USBPHY_PLL_SIC_SET);
+ ret = wait_for_pll_lock(base);
+ if (ret)
+ return ret;
+ writel(BM_USBPHY_PLL_EN_USB_CLKS, base +
+ HW_USBPHY_PLL_SIC_SET);
+ } else {
+ writel(BM_USBPHY_PLL_EN_USB_CLKS, base +
+ HW_USBPHY_PLL_SIC_CLR);
+ writel(BM_USBPHY_PLL_POWER, base + HW_USBPHY_PLL_SIC_CLR);
+ writel(BM_USBPHY_PLL_BYPASS, base + HW_USBPHY_PLL_SIC_SET);
+ writel(BM_USBPHY_PLL_REG_ENABLE, base + HW_USBPHY_PLL_SIC_CLR);
+ }
+
+ return ret;
+}
+
static int mxs_phy_hw_init(struct mxs_phy *mxs_phy)
{
int ret;
void __iomem *base = mxs_phy->phy.io_priv;
+ if (is_imx7ulp_phy(mxs_phy)) {
+ ret = mxs_phy_pll_enable(base, true);
+ if (ret)
+ return ret;
+ }
+
ret = stmp_reset_block(base + HW_USBPHY_CTRL);
if (ret)
- return ret;
+ goto disable_pll;
+
+ if (mxs_phy->phy_3p0) {
+ ret = regulator_enable(mxs_phy->phy_3p0);
+ if (ret) {
+ dev_err(mxs_phy->phy.dev,
+ "Failed to enable 3p0 regulator, ret=%d\n",
+ ret);
+ goto disable_pll;
+ }
+ }
/* Power up the PHY */
writel(0, base + HW_USBPHY_PWD);
@@ -244,6 +407,11 @@ static int mxs_phy_hw_init(struct mxs_phy *mxs_phy)
mxs_phy_tx_init(mxs_phy);
return 0;
+
+disable_pll:
+ if (is_imx7ulp_phy(mxs_phy))
+ mxs_phy_pll_enable(base, false);
+ return ret;
}
/* Return true if the vbus is there */
@@ -301,21 +469,10 @@ static void __mxs_phy_disconnect_line(struct mxs_phy *mxs_phy, bool disconnect)
usleep_range(500, 1000);
}
-static bool mxs_phy_is_otg_host(struct mxs_phy *mxs_phy)
-{
- void __iomem *base = mxs_phy->phy.io_priv;
- u32 phyctrl = readl(base + HW_USBPHY_CTRL);
-
- if (IS_ENABLED(CONFIG_USB_OTG) &&
- !(phyctrl & BM_USBPHY_CTRL_OTG_ID_VALUE))
- return true;
-
- return false;
-}
-
static void mxs_phy_disconnect_line(struct mxs_phy *mxs_phy, bool on)
{
bool vbus_is_on = false;
+ enum usb_phy_events last_event = mxs_phy->phy.last_event;
/* If the SoCs don't need to disconnect line without vbus, quit */
if (!(mxs_phy->data->flags & MXS_PHY_DISCONNECT_LINE_WITHOUT_VBUS))
@@ -327,7 +484,8 @@ static void mxs_phy_disconnect_line(struct mxs_phy *mxs_phy, bool on)
vbus_is_on = mxs_phy_get_vbus_status(mxs_phy);
- if (on && !vbus_is_on && !mxs_phy_is_otg_host(mxs_phy))
+ if (on && ((!vbus_is_on && mxs_phy->mode != USB_MODE_HOST) ||
+ (last_event == USB_EVENT_VBUS)))
__mxs_phy_disconnect_line(mxs_phy, true);
else
__mxs_phy_disconnect_line(mxs_phy, false);
@@ -365,6 +523,9 @@ static void mxs_phy_shutdown(struct usb_phy *phy)
writel(BM_USBPHY_CTRL_CLKGATE,
phy->io_priv + HW_USBPHY_CTRL_SET);
+ if (mxs_phy->phy_3p0)
+ regulator_disable(mxs_phy->phy_3p0);
+
clk_disable_unprepare(mxs_phy->clk);
}
@@ -418,14 +579,49 @@ static int mxs_phy_suspend(struct usb_phy *x, int suspend)
} else {
writel(0xffffffff, x->io_priv + HW_USBPHY_PWD);
}
+
+ /*
+ * USB2 PLL use ring VCO, when the PLL power up, the ring
+ * VCO’s supply also ramp up. There is a possibility that
+ * the ring VCO start oscillation at multi nodes in this
+ * phase, especially for VCO which has many stages, then
+ * the multiwave will be kept until PLL power down. the bit
+ * hold_ring_off can force the VCO in one determined state
+ * to avoid the multiwave issue when VCO supply start ramp
+ * up.
+ */
+ if (mxs_phy->port_id == 1 && mxs_phy->regmap_anatop)
+ regmap_write(mxs_phy->regmap_anatop,
+ ANADIG_PLL_USB2_SET,
+ BM_ANADIG_PLL_USB2_HOLD_RING_OFF);
+
writel(BM_USBPHY_CTRL_CLKGATE,
x->io_priv + HW_USBPHY_CTRL_SET);
- clk_disable_unprepare(mxs_phy->clk);
+ if (!(mxs_phy->port_id == 1 &&
+ mxs_phy->hardware_control_phy2_clk))
+ clk_disable_unprepare(mxs_phy->clk);
} else {
mxs_phy_clock_switch_delay();
- ret = clk_prepare_enable(mxs_phy->clk);
- if (ret)
- return ret;
+ if (!(mxs_phy->port_id == 1 &&
+ mxs_phy->hardware_control_phy2_clk)) {
+ ret = clk_prepare_enable(mxs_phy->clk);
+ if (ret)
+ return ret;
+ }
+
+ /*
+ * Per IC design's requirement, hold_ring_off bit can be
+ * cleared 25us after PLL power up and 25us before any USB
+ * TX/RX.
+ */
+ if (mxs_phy->port_id == 1 && mxs_phy->regmap_anatop) {
+ udelay(25);
+ regmap_write(mxs_phy->regmap_anatop,
+ ANADIG_PLL_USB2_CLR,
+ BM_ANADIG_PLL_USB2_HOLD_RING_OFF);
+ udelay(25);
+ }
+
writel(BM_USBPHY_CTRL_CLKGATE,
x->io_priv + HW_USBPHY_CTRL_CLR);
writel(0, x->io_priv + HW_USBPHY_PWD);
@@ -479,6 +675,307 @@ static int mxs_phy_on_disconnect(struct usb_phy *phy,
return 0;
}
+static int mxs_phy_on_suspend(struct usb_phy *phy,
+ enum usb_device_speed speed)
+{
+ struct mxs_phy *mxs_phy = to_mxs_phy(phy);
+
+ dev_dbg(phy->dev, "%s device has suspended\n",
+ (speed == USB_SPEED_HIGH) ? "HS" : "FS/LS");
+
+ /* delay 4ms to wait bus entering idle */
+ usleep_range(4000, 5000);
+
+ if (mxs_phy->data->flags & MXS_PHY_ABNORMAL_IN_SUSPEND) {
+ writel_relaxed(0xffffffff, phy->io_priv + HW_USBPHY_PWD);
+ writel_relaxed(0, phy->io_priv + HW_USBPHY_PWD);
+ }
+
+ if (speed == USB_SPEED_HIGH)
+ writel_relaxed(BM_USBPHY_CTRL_ENHOSTDISCONDETECT,
+ phy->io_priv + HW_USBPHY_CTRL_CLR);
+
+ return 0;
+}
+
+#define MXS_USB_CHARGER_DATA_CONTACT_TIMEOUT 100
+static int mxs_charger_data_contact_detect(struct mxs_phy *x)
+{
+ struct regmap *regmap = x->regmap_anatop;
+ int i, stable_contact_count = 0;
+ u32 val;
+
+ /* Check if vbus is valid */
+ regmap_read(regmap, ANADIG_USB1_VBUS_DET_STAT, &val);
+ if (!(val & ANADIG_USB1_VBUS_DET_STAT_VBUS_VALID)) {
+ dev_err(x->phy.dev, "vbus is not valid\n");
+ return -EINVAL;
+ }
+
+ /* Enable charger detector */
+ regmap_write(regmap, ANADIG_USB1_CHRG_DETECT_CLR,
+ ANADIG_USB1_CHRG_DETECT_EN_B);
+ /*
+ * - Do not check whether a charger is connected to the USB port
+ * - Check whether the USB plug has been in contact with each other
+ */
+ regmap_write(regmap, ANADIG_USB1_CHRG_DETECT_SET,
+ ANADIG_USB1_CHRG_DETECT_CHK_CONTACT |
+ ANADIG_USB1_CHRG_DETECT_CHK_CHRG_B);
+
+ /* Check if plug is connected */
+ for (i = 0; i < MXS_USB_CHARGER_DATA_CONTACT_TIMEOUT; i++) {
+ regmap_read(regmap, ANADIG_USB1_CHRG_DET_STAT, &val);
+ if (val & ANADIG_USB1_CHRG_DET_STAT_PLUG_CONTACT) {
+ stable_contact_count++;
+ if (stable_contact_count > 5)
+ /* Data pin makes contact */
+ break;
+ else
+ usleep_range(5000, 10000);
+ } else {
+ stable_contact_count = 0;
+ usleep_range(5000, 6000);
+ }
+ }
+
+ if (i == MXS_USB_CHARGER_DATA_CONTACT_TIMEOUT) {
+ dev_err(x->phy.dev,
+ "Data pin can't make good contact.\n");
+ /* Disable charger detector */
+ regmap_write(regmap, ANADIG_USB1_CHRG_DETECT_SET,
+ ANADIG_USB1_CHRG_DETECT_EN_B |
+ ANADIG_USB1_CHRG_DETECT_CHK_CHRG_B);
+ return -ENXIO;
+ }
+ return 0;
+}
+
+/*
+ * The resume signal must be finished here.
+ */
+static int mxs_phy_on_resume(struct usb_phy *phy,
+ enum usb_device_speed speed)
+{
+ dev_dbg(phy->dev, "%s device has resumed\n",
+ (speed == USB_SPEED_HIGH) ? "HS" : "FS/LS");
+
+ if (speed == USB_SPEED_HIGH) {
+ /* Make sure the device has switched to High-Speed mode */
+ udelay(500);
+ writel_relaxed(BM_USBPHY_CTRL_ENHOSTDISCONDETECT,
+ phy->io_priv + HW_USBPHY_CTRL_SET);
+ }
+
+ return 0;
+}
+
+/*
+ * Set the usb current role for phy.
+ */
+static int mxs_phy_set_mode(struct usb_phy *phy,
+ enum usb_current_mode mode)
+{
+ struct mxs_phy *mxs_phy = to_mxs_phy(phy);
+
+ mxs_phy->mode = mode;
+
+ return 0;
+}
+
+static enum usb_charger_type mxs_charger_primary_detection(struct mxs_phy *x)
+{
+ struct regmap *regmap = x->regmap_anatop;
+ enum usb_charger_type chgr_type = UNKNOWN_TYPE;
+ u32 val;
+
+ /*
+ * - Do check whether a charger is connected to the USB port
+ * - Do not Check whether the USB plug has been in contact with
+ * each other
+ */
+ regmap_write(regmap, ANADIG_USB1_CHRG_DETECT_CLR,
+ ANADIG_USB1_CHRG_DETECT_CHK_CONTACT |
+ ANADIG_USB1_CHRG_DETECT_CHK_CHRG_B);
+
+ msleep(100);
+
+ /* Check if it is a charger */
+ regmap_read(regmap, ANADIG_USB1_CHRG_DET_STAT, &val);
+ if (!(val & ANADIG_USB1_CHRG_DET_STAT_CHRG_DETECTED)) {
+ chgr_type = SDP_TYPE;
+ dev_dbg(x->phy.dev, "It is a stardard downstream port\n");
+ }
+
+ /* Disable charger detector */
+ regmap_write(regmap, ANADIG_USB1_CHRG_DETECT_SET,
+ ANADIG_USB1_CHRG_DETECT_EN_B |
+ ANADIG_USB1_CHRG_DETECT_CHK_CHRG_B);
+
+ return chgr_type;
+}
+
+/*
+ * It must be called after DP is pulled up, which is used to
+ * differentiate DCP and CDP.
+ */
+static enum usb_charger_type mxs_charger_secondary_detection(struct mxs_phy *x)
+{
+ struct regmap *regmap = x->regmap_anatop;
+ int val;
+
+ msleep(80);
+
+ regmap_read(regmap, ANADIG_USB1_CHRG_DET_STAT, &val);
+ if (val & ANADIG_USB1_CHRG_DET_STAT_DM_STATE) {
+ dev_dbg(x->phy.dev, "It is a dedicate charging port\n");
+ return DCP_TYPE;
+ } else {
+ dev_dbg(x->phy.dev, "It is a charging downstream port\n");
+ return CDP_TYPE;
+ }
+}
+
+static enum usb_charger_type mxs_phy_charger_detect(struct usb_phy *phy)
+{
+ struct mxs_phy *mxs_phy = to_mxs_phy(phy);
+ struct regmap *regmap = mxs_phy->regmap_anatop;
+ void __iomem *base = phy->io_priv;
+ enum usb_charger_type chgr_type = UNKNOWN_TYPE;
+
+ if (mxs_charger_data_contact_detect(mxs_phy))
+ return chgr_type;
+
+ chgr_type = mxs_charger_primary_detection(mxs_phy);
+
+ if (chgr_type != SDP_TYPE) {
+ /* Pull up DP via test */
+ writel_relaxed(BM_USBPHY_DEBUG_CLKGATE,
+ base + HW_USBPHY_DEBUG_CLR);
+ regmap_write(regmap, ANADIG_USB1_LOOPBACK_SET,
+ ANADIG_USB1_LOOPBACK_UTMI_TESTSTART);
+
+ chgr_type = mxs_charger_secondary_detection(mxs_phy);
+
+ /* Stop the test */
+ regmap_write(regmap, ANADIG_USB1_LOOPBACK_CLR,
+ ANADIG_USB1_LOOPBACK_UTMI_TESTSTART);
+ writel_relaxed(BM_USBPHY_DEBUG_CLKGATE,
+ base + HW_USBPHY_DEBUG_SET);
+ }
+
+ return chgr_type;
+}
+
+static int mxs_phy_dcd_start(struct mxs_phy *mxs_phy)
+{
+ void __iomem *base = mxs_phy->phy.io_priv;
+ u32 value;
+
+ value = readl(base + DCD_CONTROL);
+ writel(value | DCD_CONTROL_SR, base + DCD_CONTROL);
+
+ if (!mxs_phy->clk_rate)
+ return -EINVAL;
+
+ value = readl(base + DCD_CONTROL);
+ writel(((mxs_phy->clk_rate / 1000000) << 2) | DCD_CLOCK_MHZ,
+ base + DCD_CLOCK);
+
+ value = readl(base + DCD_CONTROL);
+ value &= ~DCD_CONTROL_IE;
+ writel(value | DCD_CONTROL_BC12, base + DCD_CONTROL);
+
+ value = readl(base + DCD_CONTROL);
+ writel(value | DCD_CONTROL_START, base + DCD_CONTROL);
+
+ return 0;
+}
+
+
+#define DCD_CHARGING_DURTION 1000 /* One second according to BC 1.2 */
+static enum usb_charger_type mxs_phy_dcd_flow(struct usb_phy *phy)
+{
+ struct mxs_phy *mxs_phy = to_mxs_phy(phy);
+ void __iomem *base = mxs_phy->phy.io_priv;
+ u32 value;
+ int i = 0;
+ enum usb_charger_type chgr_type;
+
+ if (mxs_phy_dcd_start(mxs_phy))
+ return UNKNOWN_TYPE;
+
+ while (i++ <= (DCD_CHARGING_DURTION / 50)) {
+ value = readl(base + DCD_CONTROL);
+ if (value & DCD_CONTROL_IF) {
+ value = readl(base + DCD_STATUS);
+ if (value & DCD_STATUS_ACTIVE) {
+ dev_err(phy->dev, "still detecting\n");
+ chgr_type = UNKNOWN_TYPE;
+ break;
+ }
+
+ if (value & DCD_STATUS_TO) {
+ dev_err(phy->dev, "detect timeout\n");
+ chgr_type = UNKNOWN_TYPE;
+ break;
+ }
+
+ if (value & DCD_STATUS_ERR) {
+ dev_err(phy->dev, "detect error\n");
+ chgr_type = UNKNOWN_TYPE;
+ break;
+ }
+
+ if ((value & DCD_STATUS_SEQ_STAT) <= DCD_CHG_DPIN) {
+ dev_err(phy->dev, "error occurs\n");
+ chgr_type = UNKNOWN_TYPE;
+ break;
+ }
+
+ /* SDP */
+ if (((value & DCD_STATUS_SEQ_STAT) == DCD_CHG_PORT) &&
+ ((value & DCD_STATUS_SEQ_RES)
+ == DCD_SDP_PORT)) {
+ dev_dbg(phy->dev, "SDP\n");
+ chgr_type = SDP_TYPE;
+ break;
+ }
+
+ if ((value & DCD_STATUS_SEQ_STAT) == DCD_CHG_DET) {
+ if ((value & DCD_STATUS_SEQ_RES) ==
+ DCD_CDP_PORT) {
+ dev_dbg(phy->dev, "CDP\n");
+ chgr_type = CDP_TYPE;
+ break;
+ }
+
+ if ((value & DCD_STATUS_SEQ_RES) ==
+ DCD_DCP_PORT) {
+ dev_dbg(phy->dev, "DCP\n");
+ chgr_type = DCP_TYPE;
+ break;
+ }
+ }
+ dev_err(phy->dev, "unknown error occurs\n");
+ chgr_type = UNKNOWN_TYPE;
+ break;
+ }
+ msleep(50);
+ }
+
+ if (i > 20) {
+ dev_err(phy->dev, "charger detecting timeout\n");
+ chgr_type = UNKNOWN_TYPE;
+ }
+
+ /* disable dcd module */
+ readl(base + DCD_STATUS);
+ writel(DCD_CONTROL_IACK, base + DCD_CONTROL);
+ writel(DCD_CONTROL_SR, base + DCD_CONTROL);
+ return chgr_type;
+}
+
static int mxs_phy_probe(struct platform_device *pdev)
{
struct resource *res;
@@ -510,6 +1007,7 @@ static int mxs_phy_probe(struct platform_device *pdev)
if (!mxs_phy)
return -ENOMEM;
+ mxs_phy->clk_rate = clk_get_rate(clk);
/* Some SoCs don't have anatop registers */
if (of_get_property(np, "fsl,anatop", NULL)) {
mxs_phy->regmap_anatop = syscon_regmap_lookup_by_phandle
@@ -521,6 +1019,17 @@ static int mxs_phy_probe(struct platform_device *pdev)
}
}
+ /* Currently, only imx7ulp has SIM module */
+ if (of_get_property(np, "nxp,sim", NULL)) {
+ mxs_phy->regmap_sim = syscon_regmap_lookup_by_phandle
+ (np, "nxp,sim");
+ if (IS_ERR(mxs_phy->regmap_sim)) {
+ dev_dbg(&pdev->dev,
+ "failed to find regmap for sim\n");
+ return PTR_ERR(mxs_phy->regmap_sim);
+ }
+ }
+
/* Precompute which bits of the TX register are to be updated, if any */
if (!of_property_read_u32(np, "fsl,tx-cal-45-dn-ohms", &val) &&
val >= MXS_PHY_TX_CAL45_MIN && val <= MXS_PHY_TX_CAL45_MAX) {
@@ -556,6 +1065,8 @@ static int mxs_phy_probe(struct platform_device *pdev)
if (ret < 0)
dev_dbg(&pdev->dev, "failed to get alias id, errno %d\n", ret);
mxs_phy->port_id = ret;
+ mxs_phy->clk = clk;
+ mxs_phy->data = of_id->data;
mxs_phy->phy.io_priv = base;
mxs_phy->phy.dev = &pdev->dev;
@@ -567,9 +1078,33 @@ static int mxs_phy_probe(struct platform_device *pdev)
mxs_phy->phy.notify_disconnect = mxs_phy_on_disconnect;
mxs_phy->phy.type = USB_PHY_TYPE_USB2;
mxs_phy->phy.set_wakeup = mxs_phy_set_wakeup;
+ mxs_phy->phy.set_mode = mxs_phy_set_mode;
+ if (mxs_phy->data->flags & MXS_PHY_SENDING_SOF_TOO_FAST) {
+ mxs_phy->phy.notify_suspend = mxs_phy_on_suspend;
+ mxs_phy->phy.notify_resume = mxs_phy_on_resume;
+ }
- mxs_phy->clk = clk;
- mxs_phy->data = of_id->data;
+ if (mxs_phy->data->flags & MXS_PHY_HAS_DCD)
+ mxs_phy->phy.charger_detect = mxs_phy_dcd_flow;
+ else
+ mxs_phy->phy.charger_detect = mxs_phy_charger_detect;
+
+ mxs_phy->phy_3p0 = devm_regulator_get(&pdev->dev, "phy-3p0");
+ if (PTR_ERR(mxs_phy->phy_3p0) == -EPROBE_DEFER) {
+ return -EPROBE_DEFER;
+ } else if (PTR_ERR(mxs_phy->phy_3p0) == -ENODEV) {
+ /* not exist */
+ mxs_phy->phy_3p0 = NULL;
+ } else if (IS_ERR(mxs_phy->phy_3p0)) {
+ dev_err(&pdev->dev, "Getting regulator error: %ld\n",
+ PTR_ERR(mxs_phy->phy_3p0));
+ return PTR_ERR(mxs_phy->phy_3p0);
+ }
+ if (mxs_phy->phy_3p0)
+ regulator_set_voltage(mxs_phy->phy_3p0, 3200000, 3200000);
+
+ if (mxs_phy->data->flags & MXS_PHY_HARDWARE_CONTROL_PHY2_CLK)
+ mxs_phy->hardware_control_phy2_clk = true;
platform_set_drvdata(pdev, mxs_phy);
@@ -588,28 +1123,58 @@ static int mxs_phy_remove(struct platform_device *pdev)
}
#ifdef CONFIG_PM_SLEEP
+static void mxs_phy_wakeup_enable(struct mxs_phy *mxs_phy, bool on)
+{
+ u32 mask = USB_PHY_VLLS_WAKEUP_EN;
+
+ /* If the SoCs don't have SIM, quit */
+ if (!mxs_phy->regmap_sim)
+ return;
+
+ if (on) {
+ regmap_update_bits(mxs_phy->regmap_sim, SIM_GPR1, mask, mask);
+ udelay(500);
+ } else {
+ regmap_update_bits(mxs_phy->regmap_sim, SIM_GPR1, mask, 0);
+ }
+}
+
static void mxs_phy_enable_ldo_in_suspend(struct mxs_phy *mxs_phy, bool on)
{
- unsigned int reg = on ? ANADIG_ANA_MISC0_SET : ANADIG_ANA_MISC0_CLR;
+ unsigned int reg;
+ u32 value;
/* If the SoCs don't have anatop, quit */
if (!mxs_phy->regmap_anatop)
return;
- if (is_imx6q_phy(mxs_phy))
+ if (is_imx6q_phy(mxs_phy)) {
+ reg = on ? ANADIG_ANA_MISC0_SET : ANADIG_ANA_MISC0_CLR;
regmap_write(mxs_phy->regmap_anatop, reg,
BM_ANADIG_ANA_MISC0_STOP_MODE_CONFIG);
- else if (is_imx6sl_phy(mxs_phy))
+ } else if (is_imx6sl_phy(mxs_phy)) {
+ reg = on ? ANADIG_ANA_MISC0_SET : ANADIG_ANA_MISC0_CLR;
regmap_write(mxs_phy->regmap_anatop,
reg, BM_ANADIG_ANA_MISC0_STOP_MODE_CONFIG_SL);
+ } else if (is_imx6ul_phy(mxs_phy)) {
+ reg = on ? ANADIG_REG_1P1_SET : ANADIG_REG_1P1_CLR;
+ value = BM_ANADIG_REG_1P1_ENABLE_WEAK_LINREG |
+ BM_ANADIG_REG_1P1_TRACK_VDD_SOC_CAP;
+ if (mxs_phy_get_vbus_status(mxs_phy) && on)
+ regmap_write(mxs_phy->regmap_anatop, reg, value);
+ else if (!on)
+ regmap_write(mxs_phy->regmap_anatop, reg, value);
+ }
}
static int mxs_phy_system_suspend(struct device *dev)
{
struct mxs_phy *mxs_phy = dev_get_drvdata(dev);
- if (device_may_wakeup(dev))
+ if (device_may_wakeup(dev)) {
mxs_phy_enable_ldo_in_suspend(mxs_phy, true);
+ mxs_phy_wakeup_enable(mxs_phy, true);
+ }
return 0;
}
@@ -618,8 +1183,10 @@ static int mxs_phy_system_resume(struct device *dev)
{
struct mxs_phy *mxs_phy = dev_get_drvdata(dev);
- if (device_may_wakeup(dev))
+ if (device_may_wakeup(dev)) {
mxs_phy_enable_ldo_in_suspend(mxs_phy, false);
+ mxs_phy_wakeup_enable(mxs_phy, false);
+ }
return 0;
}
diff --git a/drivers/usb/phy/phy.c b/drivers/usb/phy/phy.c
index 89f4ac4cd93e..26c1616f36eb 100644
--- a/drivers/usb/phy/phy.c
+++ b/drivers/usb/phy/phy.c
@@ -327,6 +327,14 @@ static int devm_usb_phy_match(struct device *dev, void *res, void *match_data)
return *phy == match_data;
}
+static void usb_charger_init(struct usb_phy *usb_phy)
+{
+ usb_phy->chg_type = UNKNOWN_TYPE;
+ usb_phy->chg_state = USB_CHARGER_DEFAULT;
+ usb_phy_set_default_current(usb_phy);
+ INIT_WORK(&usb_phy->chg_work, usb_phy_notify_charger_work);
+}
+
static int usb_add_extcon(struct usb_phy *x)
{
int ret;
@@ -410,10 +418,6 @@ static int usb_add_extcon(struct usb_phy *x)
}
}
- usb_phy_set_default_current(x);
- INIT_WORK(&x->chg_work, usb_phy_notify_charger_work);
- x->chg_type = UNKNOWN_TYPE;
- x->chg_state = USB_CHARGER_DEFAULT;
if (x->type_nb.notifier_call)
__usb_phy_get_charger_type(x);
@@ -708,6 +712,7 @@ int usb_add_phy(struct usb_phy *x, enum usb_phy_type type)
return -EINVAL;
}
+ usb_charger_init(x);
ret = usb_add_extcon(x);
if (ret)
return ret;
@@ -753,6 +758,7 @@ int usb_add_phy_dev(struct usb_phy *x)
return -EINVAL;
}
+ usb_charger_init(x);
ret = usb_add_extcon(x);
if (ret)
return ret;
diff --git a/drivers/usb/typec/typec.c b/drivers/usb/typec/typec.c
index 24e355ba109d..5b8f5ac0bdd5 100644
--- a/drivers/usb/typec/typec.c
+++ b/drivers/usb/typec/typec.c
@@ -13,6 +13,7 @@
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/slab.h>
+#include <linux/of.h>
#include <linux/usb/typec.h>
struct typec_mode {
@@ -799,6 +800,12 @@ static const char * const typec_port_types[] = {
[TYPEC_PORT_DRP] = "dual",
};
+static const char *const typec_port_types_dt[] = {
+ [TYPEC_PORT_DFP] = "dfp",
+ [TYPEC_PORT_UFP] = "ufp",
+ [TYPEC_PORT_DRP] = "drp",
+};
+
static const char * const typec_port_types_drp[] = {
[TYPEC_PORT_DFP] = "dual [source] sink",
[TYPEC_PORT_UFP] = "dual source [sink]",
@@ -1150,6 +1157,47 @@ static const struct device_type typec_port_dev_type = {
.release = typec_release,
};
+static enum typec_port_type typec_get_port_type_from_string(const char *str)
+{
+ int ret;
+
+ ret = match_string(typec_port_types_dt, ARRAY_SIZE(typec_port_types_dt), str);
+ return (ret < 0) ? TYPEC_PORT_TYPE_UNKNOWN : ret;
+}
+
+enum typec_port_type typec_get_port_type(struct device *dev)
+{
+ const char *port_type;
+ int err;
+
+ err = device_property_read_string(dev, "port-type", &port_type);
+ if (err < 0)
+ return TYPEC_PORT_TYPE_UNKNOWN;
+
+ return typec_get_port_type_from_string(port_type);
+}
+EXPORT_SYMBOL_GPL(typec_get_port_type);
+
+static enum typec_role typec_get_power_role_from_string(const char *str)
+{
+ int ret;
+
+ ret = match_string(typec_roles, ARRAY_SIZE(typec_roles), str);
+ return (ret < 0) ? TYPEC_ROLE_UNKNOWN : ret;
+}
+
+enum typec_role typec_get_power_role(struct device *dev)
+{
+ const char *power_role;
+ int err;
+
+ err = device_property_read_string(dev, "default-role", &power_role);
+ if (err < 0)
+ return TYPEC_ROLE_UNKNOWN;
+
+ return typec_get_power_role_from_string(power_role);
+}
+EXPORT_SYMBOL_GPL(typec_get_power_role);
/* --------------------------------------- */
/* Driver callbacks to report role updates */
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 3c20af999893..21e9baf714ea 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -16,7 +16,7 @@ source "drivers/char/agp/Kconfig"
source "drivers/gpu/vga/Kconfig"
source "drivers/gpu/host1x/Kconfig"
-source "drivers/gpu/ipu-v3/Kconfig"
+source "drivers/gpu/imx/Kconfig"
source "drivers/gpu/drm/Kconfig"
diff --git a/drivers/video/backlight/gpio_backlight.c b/drivers/video/backlight/gpio_backlight.c
index e470da95d806..a1364e7f6812 100644
--- a/drivers/video/backlight/gpio_backlight.c
+++ b/drivers/video/backlight/gpio_backlight.c
@@ -158,10 +158,26 @@ static struct of_device_id gpio_backlight_of_match[] = {
MODULE_DEVICE_TABLE(of, gpio_backlight_of_match);
#endif
+static int gpio_backlight_suspend(struct device *dev)
+{
+ return 0;
+}
+
+static int gpio_backlight_resume(struct device *dev)
+{
+ return 0;
+}
+
+static const struct dev_pm_ops mipi_dsi_pm_ops = {
+ .suspend = gpio_backlight_suspend,
+ .resume = gpio_backlight_resume,
+};
+
static struct platform_driver gpio_backlight_driver = {
.driver = {
.name = "gpio-backlight",
.of_match_table = of_match_ptr(gpio_backlight_of_match),
+ .pm = &mipi_dsi_pm_ops,
},
.probe = gpio_backlight_probe,
};
diff --git a/drivers/video/backlight/pwm_bl.c b/drivers/video/backlight/pwm_bl.c
index 2a0ce0c68302..ec82637c26b4 100644
--- a/drivers/video/backlight/pwm_bl.c
+++ b/drivers/video/backlight/pwm_bl.c
@@ -41,6 +41,7 @@ struct pwm_bl_data {
int brightness);
int (*check_fb)(struct device *, struct fb_info *);
void (*exit)(struct device *);
+ char fb_id[16];
};
static void pwm_backlight_power_on(struct pwm_bl_data *pb, int brightness)
@@ -134,6 +135,17 @@ static const struct backlight_ops pwm_backlight_ops = {
};
#ifdef CONFIG_OF
+static int pwm_backlight_check_fb_name(struct device *dev, struct fb_info *info)
+{
+ struct backlight_device *bl = dev_get_drvdata(dev);
+ struct pwm_bl_data *pb = bl_get_data(bl);
+
+ if (strcmp(info->fix.id, pb->fb_id) == 0)
+ return true;
+
+ return false;
+}
+
static int pwm_backlight_parse_dt(struct device *dev,
struct platform_pwm_backlight_data *data)
{
@@ -142,6 +154,7 @@ static int pwm_backlight_parse_dt(struct device *dev,
int length;
u32 value;
int ret;
+ const char *names;
if (!node)
return -ENODEV;
@@ -178,6 +191,11 @@ static int pwm_backlight_parse_dt(struct device *dev,
data->max_brightness--;
}
+ if (!of_property_read_string(node, "fb-names", &names)){
+ strcpy(data->fb_id, names);
+ data->check_fb = &pwm_backlight_check_fb_name;
+ }
+
data->enable_gpio = -EINVAL;
return 0;
}
@@ -276,6 +294,7 @@ static int pwm_backlight_probe(struct platform_device *pdev)
pb->exit = data->exit;
pb->dev = &pdev->dev;
pb->enabled = false;
+ strcpy(pb->fb_id, data->fb_id);
pb->enable_gpio = devm_gpiod_get_optional(&pdev->dev, "enable",
GPIOD_ASIS);
diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig
index 5e58f5ec0a28..a2602792ce03 100644
--- a/drivers/video/fbdev/Kconfig
+++ b/drivers/video/fbdev/Kconfig
@@ -38,6 +38,23 @@ menuconfig FB
(e.g. an accelerated X server) and that are not frame buffer
device-aware may cause unexpected results. If unsure, say N.
+config FB_IMX64
+ bool "Enable framebuffer support for 64 bit platforms"
+ depends on FB && ARM64
+ default n
+ ---help---
+ Add framebuffer device support for 64 bit platforms. This is needed
+ only if you specifically need FBDEV support on your 64bit platform,
+ since it will soon become deprecated.
+
+config FB_IMX64_DEBUG
+ bool "Enable debug messages and operations for 64bit framebuffer devices"
+ depends on FB_IMX64
+ default n
+ ---help---
+ Select this option if you need to debug 64bit platforms specific
+ operations.
+
config FIRMWARE_EDID
bool "Enable firmware EDID"
depends on FB
@@ -2406,7 +2423,9 @@ config FB_JZ4740
config FB_MXS
tristate "MXS LCD framebuffer support"
- depends on FB && (ARCH_MXS || ARCH_MXC)
+ depends on (FB && (ARCH_MXS || ARCH_MXC)) || \
+ (FB_IMX64 && (ARCH_FSL_IMX8QM || ARCH_FSL_IMX8QXP || ARCH_FSL_IMX8MQ))
+ select FB_MXC_DISP_FRAMEWORK
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
@@ -2455,6 +2474,11 @@ source "drivers/video/fbdev/omap/Kconfig"
source "drivers/video/fbdev/omap2/Kconfig"
source "drivers/video/fbdev/mmp/Kconfig"
+if ARCH_MXC || \
+ (FB_IMX64 && (ARCH_FSL_IMX8QM || ARCH_FSL_IMX8QXP || ARCH_FSL_IMX8MQ))
+source "drivers/video/fbdev/mxc/Kconfig"
+endif
+
config FB_SH_MOBILE_MERAM
tristate "SuperH Mobile MERAM read ahead support"
depends on (SUPERH || ARCH_SHMOBILE)
diff --git a/drivers/video/fbdev/Makefile b/drivers/video/fbdev/Makefile
index 8895536a20d6..5230f9b8b75f 100644
--- a/drivers/video/fbdev/Makefile
+++ b/drivers/video/fbdev/Makefile
@@ -33,6 +33,7 @@ obj-$(CONFIG_FB_KYRO) += kyro/
obj-$(CONFIG_FB_SAVAGE) += savage/
obj-$(CONFIG_FB_GEODE) += geode/
obj-$(CONFIG_FB_MBX) += mbx/
+obj-$(CONFIG_FB_MXC) += mxc/
obj-$(CONFIG_FB_NEOMAGIC) += neofb.o
obj-$(CONFIG_FB_3DFX) += tdfxfb.o
obj-$(CONFIG_FB_CONTROL) += controlfb.o
diff --git a/drivers/video/fbdev/core/fbcon.c b/drivers/video/fbdev/core/fbcon.c
index 85787119bfbf..505115f94691 100644
--- a/drivers/video/fbdev/core/fbcon.c
+++ b/drivers/video/fbdev/core/fbcon.c
@@ -3226,6 +3226,8 @@ static void fbcon_new_modelist(struct fb_info *info)
if (!fb_display[i].mode)
continue;
vc = vc_cons[i].d;
+ if (!vc)
+ continue;
display_to_var(&var, &fb_display[i]);
mode = fb_find_nearest_mode(fb_display[i].mode,
&info->modelist);
diff --git a/drivers/video/fbdev/mxc/Kconfig b/drivers/video/fbdev/mxc/Kconfig
new file mode 100644
index 000000000000..fe2a566fc280
--- /dev/null
+++ b/drivers/video/fbdev/mxc/Kconfig
@@ -0,0 +1,146 @@
+config FB_MXC
+ tristate "MXC Framebuffer support"
+ depends on FB
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ select FB_MODE_HELPERS
+ default y
+ help
+ This is a framebuffer device for the MXC LCD Controller.
+ See <http://www.linux-fbdev.org/> for information on framebuffer
+ devices.
+
+ If you plan to use the LCD display with your MXC system, say
+ Y here.
+
+config FB_MXC_DISP_FRAMEWORK
+ tristate "Display driver framework"
+ help
+ This is a framework that helps with registration and data handling
+ between fb drivers and display drivers.
+
+ It is selected by drivers which use this framework as linkage code
+ between display controllers and panels.
+
+config FB_MXC_SYNC_PANEL
+ depends on FB_MXC && !FB_IMX64
+ depends on MXC_IPU_V3
+ select FB_MXC_DISP_FRAMEWORK
+ tristate "Synchronous Panel Framebuffer"
+
+config FB_MXC_OVERLAY
+ depends on FB_MXC
+ tristate "Overlay Framebuffer"
+ default n
+ help
+ Enhanced LCD controller of MXC has overlay function.
+
+config FB_MXC_MIPI_DSI
+ tristate "MXC MIPI_DSI"
+ depends on FB_MXC_SYNC_PANEL
+ depends on MXC_IPU_V3
+
+config FB_MXC_MIPI_DSI_SAMSUNG
+ tristate "MXC MIPI_DSI_SAMSUNG"
+ depends on FB_MXC_SYNC_PANEL
+ depends on FB_MXS
+
+config FB_MXC_MIPI_DSI_NORTHWEST
+ tristate "MXC MIPI_DSI_NORTHWEST"
+ depends on FB_MXC_DISP_FRAMEWORK || FB_MXC_SYNC_PANEL
+ depends on FB_MXS
+
+config FB_MXC_TRULY_WVGA_SYNC_PANEL
+ tristate "TRULY WVGA Panel"
+ depends on FB_MXC_DISP_FRAMEWORK || FB_MXC_SYNC_PANEL
+ depends on FB_MXC_MIPI_DSI || FB_MXC_MIPI_DSI_SAMSUNG || FB_MXC_MIPI_DSI_NORTHWEST
+
+config FB_MXC_TRULY_PANEL_TFT3P5079E
+ tristate "TRULY Panel TFT3P5079E"
+ depends on FB_MXC_DISP_FRAMEWORK || FB_MXC_SYNC_PANEL
+ depends on FB_MXC_MIPI_DSI_SAMSUNG
+
+config FB_MXC_TRULY_PANEL_TFT3P5581E
+ tristate "TRULY Panel TFT3P5581E"
+ depends on FB_MXC_DISP_FRAMEWORK || FB_MXC_SYNC_PANEL
+ depends on FB_MXC_MIPI_DSI_SAMSUNG || FB_MXC_MIPI_DSI_NORTHWEST
+
+config FB_MXC_RK_PANEL_RK055AHD042
+ tristate "ROCKTECH Panel RK055AHD042"
+ depends on FB_MXC_DISP_FRAMEWORK || FB_MXC_SYNC_PANEL
+ depends on FB_MXC_MIPI_DSI_NORTHWEST
+
+config FB_MXC_RK_PANEL_RK055IQH042
+ tristate "ROCKTECH Panel RK055IQH042"
+ depends on FB_MXC_DISP_FRAMEWORK || FB_MXC_SYNC_PANEL
+ depends on FB_MXC_MIPI_DSI_NORTHWEST
+
+config FB_MXC_LDB
+ tristate "MXC LDB"
+ depends on FB_MXC_SYNC_PANEL
+ depends on MXC_IPU_V3 || FB_MXS
+ select VIDEOMODE_HELPERS
+
+config FB_MXC_HDMI
+ depends on FB_MXC_SYNC_PANEL
+ depends on MXC_IPU_V3
+ depends on I2C
+ tristate "MXC HDMI driver support"
+ select MFD_MXC_HDMI
+ help
+ Driver for the on-chip MXC HDMI controller.
+
+config FB_MXC_EDID
+ depends on FB_MXC && I2C
+ tristate "MXC EDID support"
+ default y
+
+config FB_MXS_SII902X
+ tristate "Si Image SII9022 DVI/HDMI Interface Chip"
+ depends on FB_MXS && I2C
+
+config FB_MXC_DCIC
+ tristate "MXC DCIC"
+ depends on FB_MXC_SYNC_PANEL
+ depends on MXC_IPU_V3 || FB_MXS
+ select VIDEOMODE_HELPERS
+
+config FB_MXC_ADV7535
+ tristate "ADI ADV7535 support"
+ depends on I2C
+ depends on FB_MXC_MIPI_DSI || FB_MXC_MIPI_DSI_NORTHWEST
+ help
+ Driver support for the ADV7535 DSI-to-HDMI module
+
+config HANNSTAR_CABC
+ tristate "Hannstar CABC function"
+ help
+ Say yes here to support switching on/off Hannstar CABC
+ function. This function turns backlight density of a
+ display panel automatically according to the content
+ shown on the panel.
+
+config FB_MXC_EINK_PANEL
+ depends on FB_MXC
+ depends on DMA_ENGINE
+ select FB_DEFERRED_IO
+ tristate "E-Ink Panel Framebuffer"
+
+config FB_MXC_EINK_V2_PANEL
+ depends on FB_MXC
+ depends on DMA_ENGINE
+ select FB_DEFERRED_IO
+ tristate "E-Ink Panel Framebuffer based on EPDC V2"
+
+config FB_MXC_EINK_AUTO_UPDATE_MODE
+ bool "E-Ink Auto-update Mode Support"
+ depends on FB_MXC_EINK_PANEL
+
+config FB_DCSS
+ tristate "DCSS multi-layer framebuffer support"
+ depends on FB_MXC && ARCH_FSL_IMX8MQ
+ default y
+ help
+ Framebuffer support the DCSS controller in imx8mq platform.
+ DCSS support 3 layer compsition.
diff --git a/drivers/video/fbdev/mxc/Makefile b/drivers/video/fbdev/mxc/Makefile
new file mode 100644
index 000000000000..5b619152673f
--- /dev/null
+++ b/drivers/video/fbdev/mxc/Makefile
@@ -0,0 +1,20 @@
+obj-$(CONFIG_FB_MXC_MIPI_DSI) += mipi_dsi.o
+obj-$(CONFIG_FB_MXC_MIPI_DSI_SAMSUNG) += mipi_dsi_samsung.o
+obj-$(CONFIG_FB_MXC_MIPI_DSI_NORTHWEST) += mipi_dsi_northwest.o
+obj-$(CONFIG_FB_MXC_TRULY_WVGA_SYNC_PANEL) += mxcfb_hx8369_wvga.o
+obj-$(CONFIG_FB_MXC_TRULY_PANEL_TFT3P5079E) += mxcfb_otm8018b_wvga.o
+obj-$(CONFIG_FB_MXC_TRULY_PANEL_TFT3P5581E) += mxcfb_hx8363_wvga.o
+obj-$(CONFIG_FB_MXC_RK_PANEL_RK055AHD042) += mxcfb_rm68200_wxga.o
+obj-$(CONFIG_FB_MXC_RK_PANEL_RK055IQH042) += mxcfb_rm68191_qhd.o
+obj-$(CONFIG_FB_MXC_LDB) += ldb.o
+obj-$(CONFIG_FB_MXC_HDMI) += mxc_hdmi.o
+obj-$(CONFIG_FB_MXC_EDID) += mxc_edid.o
+obj-$(CONFIG_FB_MXC_ADV7535) += adv7535.o
+obj-$(CONFIG_FB_MXC_DISP_FRAMEWORK) += mxc_dispdrv.o
+obj-$(CONFIG_FB_MXC_SYNC_PANEL) += mxc_lcdif.o mxc_ipuv3_fb.o
+obj-$(CONFIG_FB_MXC_EINK_PANEL) += mxc_epdc_fb.o
+obj-$(CONFIG_FB_MXC_EINK_V2_PANEL) += mxc_epdc_v2_fb.o
+obj-$(CONFIG_FB_MXS_SII902X) += mxsfb_sii902x.o
+obj-$(CONFIG_FB_MXC_DCIC) += mxc_dcic.o
+obj-$(CONFIG_HANNSTAR_CABC) += hannstar_cabc.o
+obj-$(CONFIG_FB_DCSS) += imx_dcss.o
diff --git a/drivers/video/fbdev/mxc/adv7535.c b/drivers/video/fbdev/mxc/adv7535.c
new file mode 100644
index 000000000000..805a402631e1
--- /dev/null
+++ b/drivers/video/fbdev/mxc/adv7535.c
@@ -0,0 +1,376 @@
+/*
+ * Copyright 2017 NXP
+ *
+ * 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/device.h>
+#include <linux/i2c.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/of_graph.h>
+#include <linux/pm_runtime.h>
+#include <video/mxc_edid.h>
+
+#include "mipi_dsi.h"
+
+/* main registers addr*/
+#define ADV7535_CHIP_REVISION 0x0
+#define ADV7535_DSI_CEC_ADDR 0xE1
+
+#define TEST_PATTERN_ENABLE 0
+
+struct adv7535_info {
+ int rev;
+ struct device *dev;
+ struct i2c_client *i2c_main;
+ struct i2c_client *i2c_dsi_cec;
+ struct fb_videomode *fb_vmode;
+ unsigned int bpp;
+};
+
+static int adv7535_probe(struct i2c_client *client,
+ const struct i2c_device_id *id);
+static int adv7535_remove(struct i2c_client *client);
+static int adv7535_detect(struct i2c_client *client,
+ struct i2c_board_info *info);
+
+static const struct i2c_device_id adv7535_id[] = {
+ {"adv7535", 0},
+ {},
+};
+MODULE_DEVICE_TABLE(i2c, adv7535_id);
+
+static const struct of_device_id adv7535_dt_ids[] = {
+ { .compatible = "adi,adv7535", .data = NULL, },
+ { /* sentinel */ }
+};
+
+static struct i2c_driver adv7535_i2c_driver = {
+ .driver = {
+ .name = "adv7535",
+ .owner = THIS_MODULE,
+ .of_match_table = adv7535_dt_ids,
+ },
+ .probe = adv7535_probe,
+ .remove = adv7535_remove,
+ .id_table = adv7535_id,
+ .detect = adv7535_detect,
+};
+
+#define adv7535_write_reg(reg, val) { \
+ int err; \
+ \
+ err = i2c_smbus_write_byte_data(client, reg, val); \
+ if (err < 0) { \
+ dev_err(&client->dev, \
+ "%s:write reg error:reg=%2x, val=%2x\n",\
+ __func__, reg, val); \
+ return err; \
+ } \
+} \
+
+static int adv7535_detect(struct i2c_client *client,
+ struct i2c_board_info *info)
+{
+ s8 ret;
+ u8 chip_rev;
+ struct i2c_adapter *adapter = client->adapter;
+
+ /* check i2c functionality */
+ if (!i2c_check_functionality(adapter, I2C_FUNC_I2C |
+ I2C_FUNC_SMBUS_BYTE_DATA))
+ return -ENODEV;
+
+ /* i2c detection */
+ ret = i2c_smbus_read_byte_data(client,
+ ADV7535_CHIP_REVISION);
+ if (ret < 0) {
+ dev_err(&adapter->dev, "ADV7535 not found\n");
+ return -ENODEV;
+ }
+
+ chip_rev = ret;
+ if (chip_rev != 0x14) {
+ dev_info(&adapter->dev, "Unsupported chip id: 0x%2x\n",
+ chip_rev);
+ return -ENODEV;
+ }
+
+ dev_info(&adapter->dev, "chip_rev = 0x%x\n", ret);
+ return 0;
+}
+
+static int adv7535_setup_cfg(struct adv7535_info *info)
+{
+ struct i2c_client *client = NULL;
+
+ client = info->i2c_main;
+ adv7535_write_reg(0xd6, 0x48); /* HPD Override */
+ adv7535_write_reg(0x41, 0x10); /* Power Up */
+
+ adv7535_write_reg(0x16, 0x20); /* Fixed Init */
+ adv7535_write_reg(0x9A, 0xE0);
+ adv7535_write_reg(0xBA, 0x70);
+ adv7535_write_reg(0xDE, 0x82);
+ adv7535_write_reg(0xE4, 0x40);
+ adv7535_write_reg(0xE5, 0x80);
+
+ client = info->i2c_dsi_cec;
+ adv7535_write_reg(0x15, 0xD0);
+ adv7535_write_reg(0x17, 0xD0);
+ adv7535_write_reg(0x24, 0x20);
+ adv7535_write_reg(0x57, 0x11);
+
+ return 0;
+}
+
+static int adv7535_vmode_cfg(struct adv7535_info *info)
+{
+ struct i2c_client *client = NULL;
+ struct fb_videomode *fb_vmode = info->fb_vmode;
+ u32 line_length, frame_height;
+ u8 low, high;
+
+ line_length = fb_vmode->xres + fb_vmode->left_margin +
+ fb_vmode->right_margin + fb_vmode->hsync_len;
+ frame_height = fb_vmode->yres + fb_vmode->upper_margin +
+ fb_vmode->lower_margin + fb_vmode->vsync_len;
+
+ client = info->i2c_dsi_cec;
+#ifdef CONFIG_FB_IMX64
+ adv7535_write_reg(0x1C, 0x40); /* 4 Data Lanes */
+#else
+ adv7535_write_reg(0x1C, 0x20); /* 2 Data Lanes */
+#endif
+
+#if TEST_PATTERN_ENABLE
+ adv7535_write_reg(0x55, 0x80);
+ adv7535_write_reg(0x16, 0x1C);
+#else
+ adv7535_write_reg(0x16, 0x00); /* Pixel Clock */
+#endif
+ adv7535_write_reg(0x27, 0xCB); /* INT_TIMING_GEN */
+
+ /* video mode settings */
+ low = (line_length << 4);
+ high = (line_length >> 4);
+ adv7535_write_reg(0x28, high); /* Total Line Length */
+ adv7535_write_reg(0x29, low);
+
+ low = (fb_vmode->hsync_len << 4);
+ high = (fb_vmode->hsync_len >> 4);
+ adv7535_write_reg(0x2A, high); /* Hsync Active Width */
+ adv7535_write_reg(0x2B, low);
+
+ low = (fb_vmode->right_margin << 4);
+ high = (fb_vmode->right_margin >> 4);
+ adv7535_write_reg(0x2C, high); /* Horizontal FP Width */
+ adv7535_write_reg(0x2D, low);
+
+ low = (fb_vmode->left_margin << 4);
+ high = (fb_vmode->left_margin >> 4);
+ adv7535_write_reg(0x2E, high); /* Horizontal BP Width */
+ adv7535_write_reg(0x2F, low);
+
+ low = (frame_height << 4);
+ high = (frame_height >> 4);
+ adv7535_write_reg(0x30, high); /* Total Frame Height */
+ adv7535_write_reg(0x31, low);
+
+ low = (fb_vmode->vsync_len << 4);
+ high = (fb_vmode->vsync_len >> 4);
+ adv7535_write_reg(0x32, high); /* Vsync Active Height */
+ adv7535_write_reg(0x33, low);
+
+ low = (fb_vmode->lower_margin << 4);
+ high = (fb_vmode->lower_margin >> 4);
+ adv7535_write_reg(0x34, high); /* Vertical FP Height */
+ adv7535_write_reg(0x35, low);
+
+ low = (fb_vmode->upper_margin << 4);
+ high = (fb_vmode->upper_margin >> 4);
+ adv7535_write_reg(0x36, high); /* Vertical BP Height */
+ adv7535_write_reg(0x37, low);
+
+ /* Reset Internal Timing Generator */
+ adv7535_write_reg(0x27, 0xCB);
+ adv7535_write_reg(0x27, 0x8B);
+ adv7535_write_reg(0x27, 0xCB);
+
+ client = info->i2c_main;
+ adv7535_write_reg(0xAF, 0x16); /* HDMI Output */
+ adv7535_write_reg(0x55, 0x10); /* AVI Info-frame */
+#ifdef CONFIG_FB_IMX64
+ adv7535_write_reg(0x56, 0x28); /* 16:9 */
+#else
+ adv7535_write_reg(0x56, 0x18);
+#endif
+ adv7535_write_reg(0x40, 0x80); /* GCP Enable */
+ adv7535_write_reg(0x4C, 0x04); /* 24bpp */
+ adv7535_write_reg(0x49, 0x00);
+
+#ifdef CONFIG_FB_IMX64
+ /* low refresh rate */
+ if (fb_vmode->refresh < 50)
+ adv7535_write_reg(0x4A, 0x8C);
+#else
+ adv7535_write_reg(0x17, 0x60); /* VS & HS Low Polarity, DE disabled */
+#endif
+
+ /*TODO Audio Setup */
+
+ client = info->i2c_dsi_cec;
+ adv7535_write_reg(0xBE, 0x3D); /* CEC Power Mode */
+
+ adv7535_write_reg(0x03, 0x89);
+
+ return 0;
+}
+
+static int adv7535_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ u32 vmode_index;
+ int ret = 0, addr;
+ struct adv7535_info *info;
+ struct device *dev = &client->dev;
+ struct device_node *endpoint = NULL;
+
+ pr_info("adv7535 probing phase\n");
+ info = devm_kzalloc(dev, sizeof(*info), GFP_KERNEL);
+
+ if (!info)
+ return -ENOMEM;
+
+ info->dev = &client->dev;
+ info->i2c_main = client;
+ i2c_set_clientdata(client, info);
+
+ dev_info(dev, "main addr = 0x%x\n", info->i2c_main->addr);
+ /* get dsi source endpoint */
+ endpoint = of_graph_get_next_endpoint(dev->of_node, NULL);
+ if (!endpoint) {
+ dev_err(dev, "DSI source endpoint not exsit\n");
+ ret = -ENODEV;
+ goto err1;
+ }
+
+ info->fb_vmode = devm_kzalloc(dev, sizeof(struct fb_videomode),
+ GFP_KERNEL);
+ if (!info->fb_vmode) {
+ ret = -ENOMEM;
+ goto err1;
+ }
+
+ ret = of_property_read_u32(dev->of_node, "video-mode", &vmode_index);
+ if (ret < 0) {
+ dev_err(dev, "failed to get required video mode\n");
+ goto err2;
+ }
+ if (vmode_index >= ARRAY_SIZE(mxc_cea_mode))
+ goto err2;
+
+ memcpy(info->fb_vmode, &mxc_cea_mode[vmode_index],
+ sizeof(struct fb_videomode));
+
+ ret = of_property_read_u32(dev->of_node, "bpp", &info->bpp);
+ if (ret < 0) {
+ dev_err(dev, "failed to get bpp\n");
+ goto err2;
+ }
+
+ if ((ret = adv7535_detect(client, NULL)))
+ goto err2;
+
+ addr = i2c_smbus_read_byte_data(client,
+ ADV7535_DSI_CEC_ADDR);
+ if (addr < 0) {
+ dev_err(dev, "Cannot get dsi_cec addr\n");
+ ret = addr;
+ goto err2;
+ }
+
+ dev_info(dev, "dsi cec addr = 0x%x\n", addr);
+ info->i2c_dsi_cec = i2c_new_dummy(client->adapter, addr >> 1);
+ if (!info->i2c_dsi_cec) {
+ dev_err(dev, "Failed to allocate I2C device for dsi_cec\n");
+ ret = -ENOMEM;
+ goto err2;
+ }
+
+ i2c_set_clientdata(info->i2c_dsi_cec, info);
+
+ /*TODO interrupts */
+
+ if ((ret = adv7535_setup_cfg(info)))
+ goto err3;
+
+ if ((ret = adv7535_vmode_cfg(info)))
+ goto err3;
+
+#ifndef CONFIG_FB_IMX64
+ pm_runtime_enable(info->dev);
+#endif
+
+ dev_info(dev, "adv7535 probe finished\n");
+
+ return 0;
+err3:
+ i2c_unregister_device(info->i2c_dsi_cec);
+err2:
+ devm_kfree(dev, info->fb_vmode);
+err1:
+ devm_kfree(dev, info);
+
+ return ret;
+}
+
+static int adv7535_remove(struct i2c_client *client)
+{
+ struct adv7535_info *info;
+
+ info = i2c_get_clientdata(client);
+ i2c_set_clientdata(client, NULL);
+
+#ifndef CONFIG_FB_IMX64
+ pm_runtime_disable(info->dev);
+#endif
+
+ i2c_unregister_device(info->i2c_dsi_cec);
+
+ kfree(info->fb_vmode);
+ kfree(info);
+
+ return 0;
+}
+
+static __init int adv7535_init(void)
+{
+ u8 err = 0;
+
+
+ err = i2c_add_driver(&adv7535_i2c_driver);
+ if (err != 0)
+ pr_err("%s: i2c driver register failed, error = %d\n",
+ __func__, err);
+
+ pr_debug("%s (ret=%d)\n", __func__, err);
+ return err;
+}
+
+static void __exit adv7535_exit(void)
+{
+ i2c_del_driver(&adv7535_i2c_driver);
+}
+
+module_init(adv7535_init);
+module_exit(adv7535_exit);
+
+MODULE_AUTHOR("NXP Semiconductor");
+MODULE_DESCRIPTION("ADV7535 video encoder driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/video/fbdev/mxc/crtc.h b/drivers/video/fbdev/mxc/crtc.h
new file mode 100644
index 000000000000..8bd1c1b95bd1
--- /dev/null
+++ b/drivers/video/fbdev/mxc/crtc.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2014 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+#ifndef __CRTC__
+#define __CRTC__
+
+enum crtc {
+ CRTC_IPU_DI0,
+ CRTC_IPU_DI1,
+ CRTC_IPU1_DI0,
+ CRTC_IPU1_DI1,
+ CRTC_IPU2_DI0,
+ CRTC_IPU2_DI1,
+ CRTC_LCDIF,
+ CRTC_LCDIF1,
+ CRTC_LCDIF2,
+ CRTC_MAX,
+};
+
+struct ipu_di_crtc_map {
+ enum crtc crtc;
+ int ipu_id;
+ int ipu_di;
+};
+
+static const struct ipu_di_crtc_map ipu_di_crtc_maps[] = {
+ {CRTC_IPU1_DI0, 0 , 0}, {CRTC_IPU1_DI1, 0 , 1},
+ {CRTC_IPU2_DI0, 1 , 0}, {CRTC_IPU2_DI1, 1 , 1},
+};
+
+static inline int ipu_di_to_crtc(struct device *dev, int ipu_id,
+ int ipu_di, enum crtc *crtc)
+{
+ int i = 0;
+
+ for (; i < ARRAY_SIZE(ipu_di_crtc_maps); i++)
+ if (ipu_di_crtc_maps[i].ipu_id == ipu_id &&
+ ipu_di_crtc_maps[i].ipu_di == ipu_di) {
+ *crtc = ipu_di_crtc_maps[i].crtc;
+ return 0;
+ }
+
+ dev_err(dev, "failed to get valid ipu di crtc "
+ "ipu_id %d, ipu_di %d\n", ipu_id, ipu_di);
+ return -EINVAL;
+}
+
+#endif
diff --git a/drivers/video/fbdev/mxc/epdc_regs.h b/drivers/video/fbdev/mxc/epdc_regs.h
new file mode 100644
index 000000000000..d4e6e525b7b9
--- /dev/null
+++ b/drivers/video/fbdev/mxc/epdc_regs.h
@@ -0,0 +1,442 @@
+/*
+ * Copyright (C) 2010-2013 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+#ifndef __EPDC_REGS_INCLUDED__
+#define __EPDC_REGS_INCLUDED__
+
+extern void __iomem *epdc_base;
+
+/*************************************
+ * Register addresses
+ **************************************/
+
+#define EPDC_CTRL (epdc_base + 0x000)
+#define EPDC_CTRL_SET (epdc_base + 0x004)
+#define EPDC_CTRL_CLEAR (epdc_base + 0x008)
+#define EPDC_CTRL_TOGGLE (epdc_base + 0x00C)
+#define EPDC_WVADDR (epdc_base + 0x020)
+#define EPDC_WB_ADDR (epdc_base + 0x030)
+#define EPDC_RES (epdc_base + 0x040)
+#define EPDC_FORMAT (epdc_base + 0x050)
+#define EPDC_FORMAT_SET (epdc_base + 0x054)
+#define EPDC_FORMAT_CLEAR (epdc_base + 0x058)
+#define EPDC_FORMAT_TOGGLE (epdc_base + 0x05C)
+#define EPDC_FIFOCTRL (epdc_base + 0x0A0)
+#define EPDC_FIFOCTRL_SET (epdc_base + 0x0A4)
+#define EPDC_FIFOCTRL_CLEAR (epdc_base + 0x0A8)
+#define EPDC_FIFOCTRL_TOGGLE (epdc_base + 0x0AC)
+#define EPDC_UPD_ADDR (epdc_base + 0x100)
+#define EPDC_UPD_STRIDE (epdc_base + 0x110)
+#define EPDC_UPD_CORD (epdc_base + 0x120)
+#define EPDC_UPD_SIZE (epdc_base + 0x140)
+#define EPDC_UPD_CTRL (epdc_base + 0x160)
+#define EPDC_UPD_FIXED (epdc_base + 0x180)
+#define EPDC_TEMP (epdc_base + 0x1A0)
+#define EPDC_AUTOWV_LUT (epdc_base + 0x1C0)
+#define EPDC_TCE_CTRL (epdc_base + 0x200)
+#define EPDC_TCE_SDCFG (epdc_base + 0x220)
+#define EPDC_TCE_GDCFG (epdc_base + 0x240)
+#define EPDC_TCE_HSCAN1 (epdc_base + 0x260)
+#define EPDC_TCE_HSCAN2 (epdc_base + 0x280)
+#define EPDC_TCE_VSCAN (epdc_base + 0x2A0)
+#define EPDC_TCE_OE (epdc_base + 0x2C0)
+#define EPDC_TCE_POLARITY (epdc_base + 0x2E0)
+#define EPDC_TCE_TIMING1 (epdc_base + 0x300)
+#define EPDC_TCE_TIMING2 (epdc_base + 0x310)
+#define EPDC_TCE_TIMING3 (epdc_base + 0x320)
+#define EPDC_PIGEON_CTRL0 (epdc_base + 0x380)
+#define EPDC_PIGEON_CTRL1 (epdc_base + 0x390)
+#define EPDC_IRQ_MASK1 (epdc_base + 0x3C0)
+#define EPDC_IRQ_MASK1_SET (epdc_base + 0x3C4)
+#define EPDC_IRQ_MASK1_CLEAR (epdc_base + 0x3C8)
+#define EPDC_IRQ_MASK1_TOGGLE (epdc_base + 0x3CC)
+#define EPDC_IRQ_MASK2 (epdc_base + 0x3D0)
+#define EPDC_IRQ_MASK2_SET (epdc_base + 0x3D4)
+#define EPDC_IRQ_MASK2_CLEAR (epdc_base + 0x3D8)
+#define EPDC_IRQ_MASK2_TOGGLE (epdc_base + 0x3DC)
+#define EPDC_IRQ1 (epdc_base + 0x3E0)
+#define EPDC_IRQ1_SET (epdc_base + 0x3E4)
+#define EPDC_IRQ1_CLEAR (epdc_base + 0x3E8)
+#define EPDC_IRQ1_TOGGLE (epdc_base + 0x3EC)
+#define EPDC_IRQ2 (epdc_base + 0x3F0)
+#define EPDC_IRQ2_SET (epdc_base + 0x3F4)
+#define EPDC_IRQ2_CLEAR (epdc_base + 0x3F8)
+#define EPDC_IRQ2_TOGGLE (epdc_base + 0x3FC)
+#define EPDC_IRQ_MASK (epdc_base + 0x400)
+#define EPDC_IRQ_MASK_SET (epdc_base + 0x404)
+#define EPDC_IRQ_MASK_CLEAR (epdc_base + 0x408)
+#define EPDC_IRQ_MASK_TOGGLE (epdc_base + 0x40C)
+#define EPDC_IRQ (epdc_base + 0x420)
+#define EPDC_IRQ_SET (epdc_base + 0x424)
+#define EPDC_IRQ_CLEAR (epdc_base + 0x428)
+#define EPDC_IRQ_TOGGLE (epdc_base + 0x42C)
+#define EPDC_STATUS_LUTS (epdc_base + 0x440)
+#define EPDC_STATUS_LUTS_SET (epdc_base + 0x444)
+#define EPDC_STATUS_LUTS_CLEAR (epdc_base + 0x448)
+#define EPDC_STATUS_LUTS_TOGGLE (epdc_base + 0x44C)
+#define EPDC_STATUS_LUTS2 (epdc_base + 0x450)
+#define EPDC_STATUS_LUTS2_SET (epdc_base + 0x454)
+#define EPDC_STATUS_LUTS2_CLEAR (epdc_base + 0x458)
+#define EPDC_STATUS_LUTS2_TOGGLE (epdc_base + 0x45C)
+#define EPDC_STATUS_NEXTLUT (epdc_base + 0x460)
+#define EPDC_STATUS_COL (epdc_base + 0x480)
+#define EPDC_STATUS_COL2 (epdc_base + 0x490)
+#define EPDC_STATUS (epdc_base + 0x4A0)
+#define EPDC_STATUS_SET (epdc_base + 0x4A4)
+#define EPDC_STATUS_CLEAR (epdc_base + 0x4A8)
+#define EPDC_STATUS_TOGGLE (epdc_base + 0x4AC)
+#define EPDC_UPD_COL_CORD (epdc_base + 0x4C0)
+#define EPDC_UPD_COL_SIZE (epdc_base + 0x4E0)
+#define EPDC_DEBUG (epdc_base + 0x500)
+#define EPDC_DEBUG_LUT (epdc_base + 0x530)
+#define EPDC_HIST1_PARAM (epdc_base + 0x600)
+#define EPDC_HIST2_PARAM (epdc_base + 0x610)
+#define EPDC_HIST4_PARAM (epdc_base + 0x620)
+#define EPDC_HIST8_PARAM0 (epdc_base + 0x630)
+#define EPDC_HIST8_PARAM1 (epdc_base + 0x640)
+#define EPDC_HIST16_PARAM0 (epdc_base + 0x650)
+#define EPDC_HIST16_PARAM1 (epdc_base + 0x660)
+#define EPDC_HIST16_PARAM2 (epdc_base + 0x670)
+#define EPDC_HIST16_PARAM3 (epdc_base + 0x680)
+#define EPDC_GPIO (epdc_base + 0x700)
+#define EPDC_VERSION (epdc_base + 0x7F0)
+#define EPDC_PIGEON_0_0 (epdc_base + 0x800)
+#define EPDC_PIGEON_0_1 (epdc_base + 0x810)
+#define EPDC_PIGEON_0_2 (epdc_base + 0x820)
+#define EPDC_PIGEON_1_0 (epdc_base + 0x840)
+#define EPDC_PIGEON_1_1 (epdc_base + 0x850)
+#define EPDC_PIGEON_1_2 (epdc_base + 0x860)
+#define EPDC_PIGEON_2_0 (epdc_base + 0x880)
+#define EPDC_PIGEON_2_1 (epdc_base + 0x890)
+#define EPDC_PIGEON_2_2 (epdc_base + 0x8A0)
+#define EPDC_PIGEON_3_0 (epdc_base + 0x8C0)
+#define EPDC_PIGEON_3_1 (epdc_base + 0x8D0)
+#define EPDC_PIGEON_3_2 (epdc_base + 0x8E0)
+#define EPDC_PIGEON_4_0 (epdc_base + 0x900)
+#define EPDC_PIGEON_4_1 (epdc_base + 0x910)
+#define EPDC_PIGEON_4_2 (epdc_base + 0x920)
+#define EPDC_PIGEON_5_0 (epdc_base + 0x940)
+#define EPDC_PIGEON_5_1 (epdc_base + 0x950)
+#define EPDC_PIGEON_5_2 (epdc_base + 0x960)
+#define EPDC_PIGEON_6_0 (epdc_base + 0x980)
+#define EPDC_PIGEON_6_1 (epdc_base + 0x990)
+#define EPDC_PIGEON_6_2 (epdc_base + 0x9A0)
+#define EPDC_PIGEON_7_0 (epdc_base + 0x9C0)
+#define EPDC_PIGEON_7_1 (epdc_base + 0x9D0)
+#define EPDC_PIGEON_7_2 (epdc_base + 0x9E0)
+#define EPDC_PIGEON_8_0 (epdc_base + 0xA00)
+#define EPDC_PIGEON_8_1 (epdc_base + 0xA10)
+#define EPDC_PIGEON_8_2 (epdc_base + 0xA20)
+#define EPDC_PIGEON_9_0 (epdc_base + 0xA40)
+#define EPDC_PIGEON_9_1 (epdc_base + 0xA50)
+#define EPDC_PIGEON_9_2 (epdc_base + 0xA60)
+#define EPDC_PIGEON_10_0 (epdc_base + 0xA80)
+#define EPDC_PIGEON_10_1 (epdc_base + 0xA90)
+#define EPDC_PIGEON_10_2 (epdc_base + 0xAA0)
+#define EPDC_PIGEON_11_0 (epdc_base + 0xAC0)
+#define EPDC_PIGEON_11_1 (epdc_base + 0xAD0)
+#define EPDC_PIGEON_11_2 (epdc_base + 0xAE0)
+#define EPDC_PIGEON_12_0 (epdc_base + 0xB00)
+#define EPDC_PIGEON_12_1 (epdc_base + 0xB10)
+#define EPDC_PIGEON_12_2 (epdc_base + 0xB20)
+#define EPDC_PIGEON_13_0 (epdc_base + 0xB40)
+#define EPDC_PIGEON_13_1 (epdc_base + 0xB50)
+#define EPDC_PIGEON_13_2 (epdc_base + 0xB60)
+#define EPDC_PIGEON_14_0 (epdc_base + 0xB80)
+#define EPDC_PIGEON_14_1 (epdc_base + 0xB90)
+#define EPDC_PIGEON_14_2 (epdc_base + 0xBA0)
+#define EPDC_PIGEON_15_0 (epdc_base + 0xBC0)
+#define EPDC_PIGEON_15_1 (epdc_base + 0xBD0)
+#define EPDC_PIGEON_15_2 (epdc_base + 0xBE0)
+#define EPDC_WB_ADDR_TCE (epdc_base + 0xC10)
+
+/*
+ * Register field definitions
+ */
+
+enum {
+/* EPDC_CTRL field values */
+ EPDC_CTRL_SFTRST = 0x80000000,
+ EPDC_CTRL_CLKGATE = 0x40000000,
+ EPDC_CTRL_SRAM_POWERDOWN = 0x100,
+ EPDC_CTRL_UPD_DATA_SWIZZLE_MASK = 0xC0,
+ EPDC_CTRL_UPD_DATA_SWIZZLE_NO_SWAP = 0,
+ EPDC_CTRL_UPD_DATA_SWIZZLE_ALL_BYTES_SWAP = 0x40,
+ EPDC_CTRL_UPD_DATA_SWIZZLE_HWD_SWAP = 0x80,
+ EPDC_CTRL_UPD_DATA_SWIZZLE_HWD_BYTE_SWAP = 0xC0,
+ EPDC_CTRL_LUT_DATA_SWIZZLE_MASK = 0x30,
+ EPDC_CTRL_LUT_DATA_SWIZZLE_NO_SWAP = 0,
+ EPDC_CTRL_LUT_DATA_SWIZZLE_ALL_BYTES_SWAP = 0x10,
+ EPDC_CTRL_LUT_DATA_SWIZZLE_HWD_SWAP = 0x20,
+ EPDC_CTRL_LUT_DATA_SWIZZLE_HWD_BYTE_SWAP = 0x30,
+ EPDC_CTRL_BURST_LEN_8_8 = 0x1,
+ EPDC_CTRL_BURST_LEN_8_16 = 0,
+
+/* EPDC_RES field values */
+ EPDC_RES_VERTICAL_MASK = 0x1FFF0000,
+ EPDC_RES_VERTICAL_OFFSET = 16,
+ EPDC_RES_HORIZONTAL_MASK = 0x1FFF,
+ EPDC_RES_HORIZONTAL_OFFSET = 0,
+
+/* EPDC_FORMAT field values */
+ EPDC_FORMAT_BUF_PIXEL_SCALE_ROUND = 0x1000000,
+ EPDC_FORMAT_DEFAULT_TFT_PIXEL_MASK = 0xFF0000,
+ EPDC_FORMAT_DEFAULT_TFT_PIXEL_OFFSET = 16,
+ EPDC_FORMAT_BUF_PIXEL_FORMAT_MASK = 0x700,
+ EPDC_FORMAT_BUF_PIXEL_FORMAT_P2N = 0x200,
+ EPDC_FORMAT_BUF_PIXEL_FORMAT_P3N = 0x300,
+ EPDC_FORMAT_BUF_PIXEL_FORMAT_P4N = 0x400,
+ EPDC_FORMAT_BUF_PIXEL_FORMAT_P5N = 0x500,
+ EPDC_FORMAT_TFT_PIXEL_FORMAT_2BIT = 0x0,
+ EPDC_FORMAT_TFT_PIXEL_FORMAT_2BIT_VCOM = 0x1,
+ EPDC_FORMAT_TFT_PIXEL_FORMAT_4BIT = 0x2,
+ EPDC_FORMAT_TFT_PIXEL_FORMAT_4BIT_VCOM = 0x3,
+
+/* EPDC_FIFOCTRL field values */
+ EPDC_FIFOCTRL_ENABLE_PRIORITY = 0x80000000,
+ EPDC_FIFOCTRL_FIFO_INIT_LEVEL_MASK = 0xFF0000,
+ EPDC_FIFOCTRL_FIFO_INIT_LEVEL_OFFSET = 16,
+ EPDC_FIFOCTRL_FIFO_H_LEVEL_MASK = 0xFF00,
+ EPDC_FIFOCTRL_FIFO_H_LEVEL_OFFSET = 8,
+ EPDC_FIFOCTRL_FIFO_L_LEVEL_MASK = 0xFF,
+ EPDC_FIFOCTRL_FIFO_L_LEVEL_OFFSET = 0,
+
+/* EPDC_UPD_CORD field values */
+ EPDC_UPD_CORD_YCORD_MASK = 0x1FFF0000,
+ EPDC_UPD_CORD_YCORD_OFFSET = 16,
+ EPDC_UPD_CORD_XCORD_MASK = 0x1FFF,
+ EPDC_UPD_CORD_XCORD_OFFSET = 0,
+
+/* EPDC_UPD_SIZE field values */
+ EPDC_UPD_SIZE_HEIGHT_MASK = 0x1FFF0000,
+ EPDC_UPD_SIZE_HEIGHT_OFFSET = 16,
+ EPDC_UPD_SIZE_WIDTH_MASK = 0x1FFF,
+ EPDC_UPD_SIZE_WIDTH_OFFSET = 0,
+
+/* EPDC_UPD_CTRL field values */
+ EPDC_UPD_CTRL_USE_FIXED = 0x80000000,
+ EPDC_UPD_CTRL_LUT_SEL_MASK = 0x3F0000,
+ EPDC_UPD_CTRL_LUT_SEL_OFFSET = 16,
+ EPDC_UPD_CTRL_WAVEFORM_MODE_MASK = 0xFF00,
+ EPDC_UPD_CTRL_WAVEFORM_MODE_OFFSET = 8,
+ EPDC_UPD_CTRL_AUTOWV_PAUSE = 0x8,
+ EPDC_UPD_CTRL_AUTOWV = 0x4,
+ EPDC_UPD_CTRL_DRY_RUN = 0x2,
+ EPDC_UPD_CTRL_UPDATE_MODE_FULL = 0x1,
+
+/* EPDC_UPD_FIXED field values */
+ EPDC_UPD_FIXED_FIXNP_EN = 0x80000000,
+ EPDC_UPD_FIXED_FIXCP_EN = 0x40000000,
+ EPDC_UPD_FIXED_FIXNP_MASK = 0xFF00,
+ EPDC_UPD_FIXED_FIXNP_OFFSET = 8,
+ EPDC_UPD_FIXED_FIXCP_MASK = 0xFF,
+ EPDC_UPD_FIXED_FIXCP_OFFSET = 0,
+
+/* EPDC_AUTOWV_LUT field values */
+ EPDC_AUTOWV_LUT_DATA_MASK = 0xFF0000,
+ EPDC_AUTOWV_LUT_DATA_OFFSET = 16,
+ EPDC_AUTOWV_LUT_ADDR_MASK = 0xFF,
+ EPDC_AUTOWV_LUT_ADDR_OFFSET = 0,
+
+/* EPDC_TCE_CTRL field values */
+ EPDC_TCE_CTRL_VSCAN_HOLDOFF_MASK = 0x1FF0000,
+ EPDC_TCE_CTRL_VSCAN_HOLDOFF_OFFSET = 16,
+ EPDC_TCE_CTRL_VCOM_VAL_MASK = 0xC00,
+ EPDC_TCE_CTRL_VCOM_VAL_OFFSET = 10,
+ EPDC_TCE_CTRL_VCOM_MODE_AUTO = 0x200,
+ EPDC_TCE_CTRL_VCOM_MODE_MANUAL = 0x000,
+ EPDC_TCE_CTRL_DDR_MODE_ENABLE = 0x100,
+ EPDC_TCE_CTRL_LVDS_MODE_CE_ENABLE = 0x80,
+ EPDC_TCE_CTRL_LVDS_MODE_ENABLE = 0x40,
+ EPDC_TCE_CTRL_SCAN_DIR_1_UP = 0x20,
+ EPDC_TCE_CTRL_SCAN_DIR_0_UP = 0x10,
+ EPDC_TCE_CTRL_DUAL_SCAN_ENABLE = 0x8,
+ EPDC_TCE_CTRL_SDDO_WIDTH_16BIT = 0x4,
+ EPDC_TCE_CTRL_PIXELS_PER_SDCLK_2 = 1,
+ EPDC_TCE_CTRL_PIXELS_PER_SDCLK_4 = 2,
+ EPDC_TCE_CTRL_PIXELS_PER_SDCLK_8 = 3,
+
+/* EPDC_TCE_SDCFG field values */
+ EPDC_TCE_SDCFG_SDCLK_HOLD = 0x200000,
+ EPDC_TCE_SDCFG_SDSHR = 0x100000,
+ EPDC_TCE_SDCFG_NUM_CE_MASK = 0xF0000,
+ EPDC_TCE_SDCFG_NUM_CE_OFFSET = 16,
+ EPDC_TCE_SDCFG_SDDO_REFORMAT_STANDARD = 0,
+ EPDC_TCE_SDCFG_SDDO_REFORMAT_FLIP_PIXELS = 0x4000,
+ EPDC_TCE_SDCFG_SDDO_INVERT_ENABLE = 0x2000,
+ EPDC_TCE_SDCFG_PIXELS_PER_CE_MASK = 0x1FFF,
+ EPDC_TCE_SDCFG_PIXELS_PER_CE_OFFSET = 0,
+
+/* EPDC_TCE_GDCFG field values */
+ EPDC_TCE_SDCFG_GDRL = 0x10,
+ EPDC_TCE_SDCFG_GDOE_MODE_DELAYED_GDCLK = 0x2,
+ EPDC_TCE_SDCFG_GDSP_MODE_FRAME_SYNC = 0x1,
+ EPDC_TCE_SDCFG_GDSP_MODE_ONE_LINE = 0x0,
+
+/* EPDC_TCE_HSCAN1 field values */
+ EPDC_TCE_HSCAN1_LINE_SYNC_WIDTH_MASK = 0xFFF0000,
+ EPDC_TCE_HSCAN1_LINE_SYNC_WIDTH_OFFSET = 16,
+ EPDC_TCE_HSCAN1_LINE_SYNC_MASK = 0xFFF,
+ EPDC_TCE_HSCAN1_LINE_SYNC_OFFSET = 0,
+
+/* EPDC_TCE_HSCAN2 field values */
+ EPDC_TCE_HSCAN2_LINE_END_MASK = 0xFFF0000,
+ EPDC_TCE_HSCAN2_LINE_END_OFFSET = 16,
+ EPDC_TCE_HSCAN2_LINE_BEGIN_MASK = 0xFFF,
+ EPDC_TCE_HSCAN2_LINE_BEGIN_OFFSET = 0,
+
+/* EPDC_TCE_VSCAN field values */
+ EPDC_TCE_VSCAN_FRAME_END_MASK = 0xFF0000,
+ EPDC_TCE_VSCAN_FRAME_END_OFFSET = 16,
+ EPDC_TCE_VSCAN_FRAME_BEGIN_MASK = 0xFF00,
+ EPDC_TCE_VSCAN_FRAME_BEGIN_OFFSET = 8,
+ EPDC_TCE_VSCAN_FRAME_SYNC_MASK = 0xFF,
+ EPDC_TCE_VSCAN_FRAME_SYNC_OFFSET = 0,
+
+/* EPDC_TCE_OE field values */
+ EPDC_TCE_OE_SDOED_WIDTH_MASK = 0xFF000000,
+ EPDC_TCE_OE_SDOED_WIDTH_OFFSET = 24,
+ EPDC_TCE_OE_SDOED_DLY_MASK = 0xFF0000,
+ EPDC_TCE_OE_SDOED_DLY_OFFSET = 16,
+ EPDC_TCE_OE_SDOEZ_WIDTH_MASK = 0xFF00,
+ EPDC_TCE_OE_SDOEZ_WIDTH_OFFSET = 8,
+ EPDC_TCE_OE_SDOEZ_DLY_MASK = 0xFF,
+ EPDC_TCE_OE_SDOEZ_DLY_OFFSET = 0,
+
+/* EPDC_TCE_POLARITY field values */
+ EPDC_TCE_POLARITY_GDSP_POL_ACTIVE_HIGH = 0x10,
+ EPDC_TCE_POLARITY_GDOE_POL_ACTIVE_HIGH = 0x8,
+ EPDC_TCE_POLARITY_SDOE_POL_ACTIVE_HIGH = 0x4,
+ EPDC_TCE_POLARITY_SDLE_POL_ACTIVE_HIGH = 0x2,
+ EPDC_TCE_POLARITY_SDCE_POL_ACTIVE_HIGH = 0x1,
+
+/* EPDC_TCE_TIMING1 field values */
+ EPDC_TCE_TIMING1_SDLE_SHIFT_NONE = 0x00,
+ EPDC_TCE_TIMING1_SDLE_SHIFT_1 = 0x10,
+ EPDC_TCE_TIMING1_SDLE_SHIFT_2 = 0x20,
+ EPDC_TCE_TIMING1_SDLE_SHIFT_3 = 0x30,
+ EPDC_TCE_TIMING1_SDCLK_INVERT = 0x8,
+ EPDC_TCE_TIMING1_SDCLK_SHIFT_NONE = 0,
+ EPDC_TCE_TIMING1_SDCLK_SHIFT_1CYCLE = 1,
+ EPDC_TCE_TIMING1_SDCLK_SHIFT_2CYCLES = 2,
+ EPDC_TCE_TIMING1_SDCLK_SHIFT_3CYCLES = 3,
+
+/* EPDC_TCE_TIMING2 field values */
+ EPDC_TCE_TIMING2_GDCLK_HP_MASK = 0xFFFF0000,
+ EPDC_TCE_TIMING2_GDCLK_HP_OFFSET = 16,
+ EPDC_TCE_TIMING2_GDSP_OFFSET_MASK = 0xFFFF,
+ EPDC_TCE_TIMING2_GDSP_OFFSET_OFFSET = 0,
+
+/* EPDC_TCE_TIMING3 field values */
+ EPDC_TCE_TIMING3_GDOE_OFFSET_MASK = 0xFFFF0000,
+ EPDC_TCE_TIMING3_GDOE_OFFSET_OFFSET = 16,
+ EPDC_TCE_TIMING3_GDCLK_OFFSET_MASK = 0xFFFF,
+ EPDC_TCE_TIMING3_GDCLK_OFFSET_OFFSET = 0,
+
+/* EPDC_IRQ_MASK/EPDC_IRQ field values */
+ EPDC_IRQ_WB_CMPLT_IRQ = 0x10000,
+ EPDC_IRQ_LUT_COL_IRQ = 0x20000,
+ EPDC_IRQ_TCE_UNDERRUN_IRQ = 0x40000,
+ EPDC_IRQ_FRAME_END_IRQ = 0x80000,
+ EPDC_IRQ_BUS_ERROR_IRQ = 0x100000,
+ EPDC_IRQ_TCE_IDLE_IRQ = 0x200000,
+ EPDC_IRQ_UPD_DONE_IRQ = 0x400000,
+ EPDC_IRQ_PWR_IRQ = 0x800000,
+
+/* EPDC_STATUS_NEXTLUT field values */
+ EPDC_STATUS_NEXTLUT_NEXT_LUT_VALID = 0x100,
+ EPDC_STATUS_NEXTLUT_NEXT_LUT_MASK = 0x3F,
+ EPDC_STATUS_NEXTLUT_NEXT_LUT_OFFSET = 0,
+
+/* EPDC_STATUS field values */
+ EPDC_STATUS_HISTOGRAM_CP_MASK = 0x1F0000,
+ EPDC_STATUS_HISTOGRAM_CP_OFFSET = 16,
+ EPDC_STATUS_HISTOGRAM_NP_MASK = 0x1F00,
+ EPDC_STATUS_HISTOGRAM_NP_OFFSET = 8,
+ EPDC_STATUS_UPD_VOID = 0x8,
+ EPDC_STATUS_LUTS_UNDERRUN = 0x4,
+ EPDC_STATUS_LUTS_BUSY = 0x2,
+ EPDC_STATUS_WB_BUSY = 0x1,
+
+/* EPDC_UPD_COL_CORD field values */
+ EPDC_UPD_COL_CORD_YCORD_MASK = 0x1FFF0000,
+ EPDC_UPD_COL_CORD_YCORD_OFFSET = 16,
+ EPDC_UPD_COL_CORD_XCORD_MASK = 0x1FFF,
+ EPDC_UPD_COL_CORD_XCORD_OFFSET = 0,
+
+/* EPDC_UPD_COL_SIZE field values */
+ EPDC_UPD_COL_SIZE_HEIGHT_MASK = 0x1FFF0000,
+ EPDC_UPD_COL_SIZE_HEIGHT_OFFSET = 16,
+ EPDC_UPD_COL_SIZE_WIDTH_MASK = 0x1FFF,
+ EPDC_UPD_COL_SIZE_WIDTH_OFFSET = 0,
+
+/* EPDC_DEBUG field values */
+ EPDC_DEBUG_UNDERRUN_RECOVER = 0x2,
+ EPDC_DEBUG_COLLISION_OFF = 0x1,
+
+/* EPDC_HISTx_PARAM field values */
+ EPDC_HIST_PARAM_VALUE0_MASK = 0x1F,
+ EPDC_HIST_PARAM_VALUE0_OFFSET = 0,
+ EPDC_HIST_PARAM_VALUE1_MASK = 0x1F00,
+ EPDC_HIST_PARAM_VALUE1_OFFSET = 8,
+ EPDC_HIST_PARAM_VALUE2_MASK = 0x1F0000,
+ EPDC_HIST_PARAM_VALUE2_OFFSET = 16,
+ EPDC_HIST_PARAM_VALUE3_MASK = 0x1F000000,
+ EPDC_HIST_PARAM_VALUE3_OFFSET = 24,
+ EPDC_HIST_PARAM_VALUE4_MASK = 0x1F,
+ EPDC_HIST_PARAM_VALUE4_OFFSET = 0,
+ EPDC_HIST_PARAM_VALUE5_MASK = 0x1F00,
+ EPDC_HIST_PARAM_VALUE5_OFFSET = 8,
+ EPDC_HIST_PARAM_VALUE6_MASK = 0x1F0000,
+ EPDC_HIST_PARAM_VALUE6_OFFSET = 16,
+ EPDC_HIST_PARAM_VALUE7_MASK = 0x1F000000,
+ EPDC_HIST_PARAM_VALUE7_OFFSET = 24,
+ EPDC_HIST_PARAM_VALUE8_MASK = 0x1F,
+ EPDC_HIST_PARAM_VALUE8_OFFSET = 0,
+ EPDC_HIST_PARAM_VALUE9_MASK = 0x1F00,
+ EPDC_HIST_PARAM_VALUE9_OFFSET = 8,
+ EPDC_HIST_PARAM_VALUE10_MASK = 0x1F0000,
+ EPDC_HIST_PARAM_VALUE10_OFFSET = 16,
+ EPDC_HIST_PARAM_VALUE11_MASK = 0x1F000000,
+ EPDC_HIST_PARAM_VALUE11_OFFSET = 24,
+ EPDC_HIST_PARAM_VALUE12_MASK = 0x1F,
+ EPDC_HIST_PARAM_VALUE12_OFFSET = 0,
+ EPDC_HIST_PARAM_VALUE13_MASK = 0x1F00,
+ EPDC_HIST_PARAM_VALUE13_OFFSET = 8,
+ EPDC_HIST_PARAM_VALUE14_MASK = 0x1F0000,
+ EPDC_HIST_PARAM_VALUE14_OFFSET = 16,
+ EPDC_HIST_PARAM_VALUE15_MASK = 0x1F000000,
+ EPDC_HIST_PARAM_VALUE15_OFFSET = 24,
+
+/* EPDC_GPIO field values */
+ EPDC_GPIO_PWRCOM = 0x40,
+ EPDC_GPIO_PWRCTRL_MASK = 0x3C,
+ EPDC_GPIO_PWRCTRL_OFFSET = 2,
+ EPDC_GPIO_BDR_MASK = 0x3,
+ EPDC_GPIO_BDR_OFFSET = 0,
+
+/* EPDC_VERSION field values */
+ EPDC_VERSION_MAJOR_MASK = 0xFF000000,
+ EPDC_VERSION_MAJOR_OFFSET = 24,
+ EPDC_VERSION_MINOR_MASK = 0xFF0000,
+ EPDC_VERSION_MINOR_OFFSET = 16,
+ EPDC_VERSION_STEP_MASK = 0xFFFF,
+ EPDC_VERSION_STEP_OFFSET = 0,
+};
+
+#endif /* __EPDC_REGS_INCLUDED__ */
diff --git a/drivers/video/fbdev/mxc/epdc_v2_regs.h b/drivers/video/fbdev/mxc/epdc_v2_regs.h
new file mode 100644
index 000000000000..052df13151fc
--- /dev/null
+++ b/drivers/video/fbdev/mxc/epdc_v2_regs.h
@@ -0,0 +1,533 @@
+/*
+ * Copyright (C) 2014-2015 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+#ifndef __EPDC_REGS_INCLUDED__
+#define __EPDC_REGS_INCLUDED__
+
+extern void __iomem *epdc_v2_base;
+
+/*************************************
+ * Register addresses
+ **************************************/
+
+#define EPDC_CTRL (epdc_v2_base + 0x000)
+#define EPDC_CTRL_SET (epdc_v2_base + 0x004)
+#define EPDC_CTRL_CLEAR (epdc_v2_base + 0x008)
+#define EPDC_CTRL_TOGGLE (epdc_v2_base + 0x00C)
+#define EPDC_WVADDR (epdc_v2_base + 0x020)
+#define EPDC_WB_ADDR (epdc_v2_base + 0x030)
+#define EPDC_RES (epdc_v2_base + 0x040)
+#define EPDC_FORMAT (epdc_v2_base + 0x050)
+#define EPDC_FORMAT_SET (epdc_v2_base + 0x054)
+#define EPDC_FORMAT_CLEAR (epdc_v2_base + 0x058)
+#define EPDC_FORMAT_TOGGLE (epdc_v2_base + 0x05C)
+#define EPDC_WB_FIELD0 (epdc_v2_base + 0x060)
+#define EPDC_WB_FIELD0_SET (epdc_v2_base + 0x064)
+#define EPDC_WB_FIELD0_CLEAR (epdc_v2_base + 0x068)
+#define EPDC_WB_FIELD0_TOGGLE (epdc_v2_base + 0x06C)
+#define EPDC_WB_FIELD1 (epdc_v2_base + 0x070)
+#define EPDC_WB_FIELD1_SET (epdc_v2_base + 0x074)
+#define EPDC_WB_FIELD1_CLEAR (epdc_v2_base + 0x078)
+#define EPDC_WB_FIELD1_TOGGLE (epdc_v2_base + 0x07C)
+#define EPDC_WB_FIELD2 (epdc_v2_base + 0x080)
+#define EPDC_WB_FIELD2_SET (epdc_v2_base + 0x084)
+#define EPDC_WB_FIELD2_CLEAR (epdc_v2_base + 0x088)
+#define EPDC_WB_FIELD2_TOGGLE (epdc_v2_base + 0x08C)
+#define EPDC_WB_FIELD3 (epdc_v2_base + 0x090)
+#define EPDC_WB_FIELD3_SET (epdc_v2_base + 0x094)
+#define EPDC_WB_FIELD3_CLEAR (epdc_v2_base + 0x098)
+#define EPDC_WB_FIELD3_TOGGLE (epdc_v2_base + 0x09C)
+#define EPDC_FIFOCTRL (epdc_v2_base + 0x0A0)
+#define EPDC_FIFOCTRL_SET (epdc_v2_base + 0x0A4)
+#define EPDC_FIFOCTRL_CLEAR (epdc_v2_base + 0x0A8)
+#define EPDC_FIFOCTRL_TOGGLE (epdc_v2_base + 0x0AC)
+#define EPDC_UPD_ADDR (epdc_v2_base + 0x100)
+#define EPDC_UPD_STRIDE (epdc_v2_base + 0x110)
+#define EPDC_UPD_CORD (epdc_v2_base + 0x120)
+#define EPDC_UPD_SIZE (epdc_v2_base + 0x140)
+#define EPDC_UPD_CTRL (epdc_v2_base + 0x160)
+#define EPDC_UPD_FIXED (epdc_v2_base + 0x180)
+#define EPDC_TEMP (epdc_v2_base + 0x1A0)
+#define EPDC_AUTOWV_LUT (epdc_v2_base + 0x1C0)
+#define EPDC_LUT_STANDBY1 (epdc_v2_base + 0x1E0)
+#define EPDC_LUT_STANDBY1_SET (epdc_v2_base + 0x1E4)
+#define EPDC_LUT_STANDBY1_CLEAR (epdc_v2_base + 0x1E8)
+#define EPDC_LUT_STANDBY1_TOGGLE (epdc_v2_base + 0x1EC)
+#define EPDC_LUT_STANDBY2 (epdc_v2_base + 0x1F0)
+#define EPDC_LUT_STANDBY2_SET (epdc_v2_base + 0x1F4)
+#define EPDC_LUT_STANDBY2_CLEAR (epdc_v2_base + 0x1F8)
+#define EPDC_LUT_STANDBY2_TOGGLE (epdc_v2_base + 0x1FC)
+#define EPDC_TCE_CTRL (epdc_v2_base + 0x200)
+#define EPDC_TCE_SDCFG (epdc_v2_base + 0x220)
+#define EPDC_TCE_GDCFG (epdc_v2_base + 0x240)
+#define EPDC_TCE_HSCAN1 (epdc_v2_base + 0x260)
+#define EPDC_TCE_HSCAN2 (epdc_v2_base + 0x280)
+#define EPDC_TCE_VSCAN (epdc_v2_base + 0x2A0)
+#define EPDC_TCE_OE (epdc_v2_base + 0x2C0)
+#define EPDC_TCE_POLARITY (epdc_v2_base + 0x2E0)
+#define EPDC_TCE_TIMING1 (epdc_v2_base + 0x300)
+#define EPDC_TCE_TIMING2 (epdc_v2_base + 0x310)
+#define EPDC_TCE_TIMING3 (epdc_v2_base + 0x320)
+#define EPDC_PIGEON_CTRL0 (epdc_v2_base + 0x380)
+#define EPDC_PIGEON_CTRL1 (epdc_v2_base + 0x390)
+#define EPDC_IRQ_MASK1 (epdc_v2_base + 0x3C0)
+#define EPDC_IRQ_MASK1_SET (epdc_v2_base + 0x3C4)
+#define EPDC_IRQ_MASK1_CLEAR (epdc_v2_base + 0x3C8)
+#define EPDC_IRQ_MASK1_TOGGLE (epdc_v2_base + 0x3CC)
+#define EPDC_IRQ_MASK2 (epdc_v2_base + 0x3D0)
+#define EPDC_IRQ_MASK2_SET (epdc_v2_base + 0x3D4)
+#define EPDC_IRQ_MASK2_CLEAR (epdc_v2_base + 0x3D8)
+#define EPDC_IRQ_MASK2_TOGGLE (epdc_v2_base + 0x3DC)
+#define EPDC_IRQ1 (epdc_v2_base + 0x3E0)
+#define EPDC_IRQ1_SET (epdc_v2_base + 0x3E4)
+#define EPDC_IRQ1_CLEAR (epdc_v2_base + 0x3E8)
+#define EPDC_IRQ1_TOGGLE (epdc_v2_base + 0x3EC)
+#define EPDC_IRQ2 (epdc_v2_base + 0x3F0)
+#define EPDC_IRQ2_SET (epdc_v2_base + 0x3F4)
+#define EPDC_IRQ2_CLEAR (epdc_v2_base + 0x3F8)
+#define EPDC_IRQ2_TOGGLE (epdc_v2_base + 0x3FC)
+#define EPDC_IRQ_MASK (epdc_v2_base + 0x400)
+#define EPDC_IRQ_MASK_SET (epdc_v2_base + 0x404)
+#define EPDC_IRQ_MASK_CLEAR (epdc_v2_base + 0x408)
+#define EPDC_IRQ_MASK_TOGGLE (epdc_v2_base + 0x40C)
+#define EPDC_IRQ (epdc_v2_base + 0x420)
+#define EPDC_IRQ_SET (epdc_v2_base + 0x424)
+#define EPDC_IRQ_CLEAR (epdc_v2_base + 0x428)
+#define EPDC_IRQ_TOGGLE (epdc_v2_base + 0x42C)
+#define EPDC_STATUS_LUTS (epdc_v2_base + 0x440)
+#define EPDC_STATUS_LUTS_SET (epdc_v2_base + 0x444)
+#define EPDC_STATUS_LUTS_CLEAR (epdc_v2_base + 0x448)
+#define EPDC_STATUS_LUTS_TOGGLE (epdc_v2_base + 0x44C)
+#define EPDC_STATUS_LUTS2 (epdc_v2_base + 0x450)
+#define EPDC_STATUS_LUTS2_SET (epdc_v2_base + 0x454)
+#define EPDC_STATUS_LUTS2_CLEAR (epdc_v2_base + 0x458)
+#define EPDC_STATUS_LUTS2_TOGGLE (epdc_v2_base + 0x45C)
+#define EPDC_STATUS_NEXTLUT (epdc_v2_base + 0x460)
+#define EPDC_STATUS_COL (epdc_v2_base + 0x480)
+#define EPDC_STATUS_COL2 (epdc_v2_base + 0x490)
+#define EPDC_STATUS (epdc_v2_base + 0x4A0)
+#define EPDC_STATUS_SET (epdc_v2_base + 0x4A4)
+#define EPDC_STATUS_CLEAR (epdc_v2_base + 0x4A8)
+#define EPDC_STATUS_TOGGLE (epdc_v2_base + 0x4AC)
+#define EPDC_UPD_COL_CORD (epdc_v2_base + 0x4C0)
+#define EPDC_UPD_COL_SIZE (epdc_v2_base + 0x4E0)
+#define EPDC_DEBUG (epdc_v2_base + 0x500)
+#define EPDC_DEBUG_LUT (epdc_v2_base + 0x530)
+#define EPDC_HIST1_PARAM (epdc_v2_base + 0x600)
+#define EPDC_HIST2_PARAM (epdc_v2_base + 0x610)
+#define EPDC_HIST4_PARAM (epdc_v2_base + 0x620)
+#define EPDC_HIST8_PARAM0 (epdc_v2_base + 0x630)
+#define EPDC_HIST8_PARAM1 (epdc_v2_base + 0x640)
+#define EPDC_HIST16_PARAM0 (epdc_v2_base + 0x650)
+#define EPDC_HIST16_PARAM1 (epdc_v2_base + 0x660)
+#define EPDC_HIST16_PARAM2 (epdc_v2_base + 0x670)
+#define EPDC_HIST16_PARAM3 (epdc_v2_base + 0x680)
+#define EPDC_GPIO (epdc_v2_base + 0x700)
+#define EPDC_VERSION (epdc_v2_base + 0x7F0)
+#define EPDC_PIGEON_0_0 (epdc_v2_base + 0x800)
+#define EPDC_PIGEON_0_1 (epdc_v2_base + 0x810)
+#define EPDC_PIGEON_0_2 (epdc_v2_base + 0x820)
+#define EPDC_PIGEON_1_0 (epdc_v2_base + 0x840)
+#define EPDC_PIGEON_1_1 (epdc_v2_base + 0x850)
+#define EPDC_PIGEON_1_2 (epdc_v2_base + 0x860)
+#define EPDC_PIGEON_2_0 (epdc_v2_base + 0x880)
+#define EPDC_PIGEON_2_1 (epdc_v2_base + 0x890)
+#define EPDC_PIGEON_2_2 (epdc_v2_base + 0x8A0)
+#define EPDC_PIGEON_3_0 (epdc_v2_base + 0x8C0)
+#define EPDC_PIGEON_3_1 (epdc_v2_base + 0x8D0)
+#define EPDC_PIGEON_3_2 (epdc_v2_base + 0x8E0)
+#define EPDC_PIGEON_4_0 (epdc_v2_base + 0x900)
+#define EPDC_PIGEON_4_1 (epdc_v2_base + 0x910)
+#define EPDC_PIGEON_4_2 (epdc_v2_base + 0x920)
+#define EPDC_PIGEON_5_0 (epdc_v2_base + 0x940)
+#define EPDC_PIGEON_5_1 (epdc_v2_base + 0x950)
+#define EPDC_PIGEON_5_2 (epdc_v2_base + 0x960)
+#define EPDC_PIGEON_6_0 (epdc_v2_base + 0x980)
+#define EPDC_PIGEON_6_1 (epdc_v2_base + 0x990)
+#define EPDC_PIGEON_6_2 (epdc_v2_base + 0x9A0)
+#define EPDC_PIGEON_7_0 (epdc_v2_base + 0x9C0)
+#define EPDC_PIGEON_7_1 (epdc_v2_base + 0x9D0)
+#define EPDC_PIGEON_7_2 (epdc_v2_base + 0x9E0)
+#define EPDC_PIGEON_8_0 (epdc_v2_base + 0xA00)
+#define EPDC_PIGEON_8_1 (epdc_v2_base + 0xA10)
+#define EPDC_PIGEON_8_2 (epdc_v2_base + 0xA20)
+#define EPDC_PIGEON_9_0 (epdc_v2_base + 0xA40)
+#define EPDC_PIGEON_9_1 (epdc_v2_base + 0xA50)
+#define EPDC_PIGEON_9_2 (epdc_v2_base + 0xA60)
+#define EPDC_PIGEON_10_0 (epdc_v2_base + 0xA80)
+#define EPDC_PIGEON_10_1 (epdc_v2_base + 0xA90)
+#define EPDC_PIGEON_10_2 (epdc_v2_base + 0xAA0)
+#define EPDC_PIGEON_11_0 (epdc_v2_base + 0xAC0)
+#define EPDC_PIGEON_11_1 (epdc_v2_base + 0xAD0)
+#define EPDC_PIGEON_11_2 (epdc_v2_base + 0xAE0)
+#define EPDC_PIGEON_12_0 (epdc_v2_base + 0xB00)
+#define EPDC_PIGEON_12_1 (epdc_v2_base + 0xB10)
+#define EPDC_PIGEON_12_2 (epdc_v2_base + 0xB20)
+#define EPDC_PIGEON_13_0 (epdc_v2_base + 0xB40)
+#define EPDC_PIGEON_13_1 (epdc_v2_base + 0xB50)
+#define EPDC_PIGEON_13_2 (epdc_v2_base + 0xB60)
+#define EPDC_PIGEON_14_0 (epdc_v2_base + 0xB80)
+#define EPDC_PIGEON_14_1 (epdc_v2_base + 0xB90)
+#define EPDC_PIGEON_14_2 (epdc_v2_base + 0xBA0)
+#define EPDC_PIGEON_15_0 (epdc_v2_base + 0xBC0)
+#define EPDC_PIGEON_15_1 (epdc_v2_base + 0xBD0)
+#define EPDC_PIGEON_15_2 (epdc_v2_base + 0xBE0)
+#define EPDC_PIGEON_16_0 (epdc_v2_base + 0xC00)
+#define EPDC_PIGEON_16_1 (epdc_v2_base + 0xC10)
+#define EPDC_PIGEON_16_2 (epdc_v2_base + 0xC20)
+#define EPDC_WB_ADDR_TCE (epdc_v2_base + 0x010)
+
+/*
+ * Register field definitions
+ */
+
+enum {
+/* EPDC_CTRL field values */
+ EPDC_CTRL_SFTRST = 0x80000000,
+ EPDC_CTRL_CLKGATE = 0x40000000,
+ EPDC_CTRL_SRAM_POWERDOWN = 0x100,
+ EPDC_CTRL_UPD_DATA_SWIZZLE_MASK = 0xC0,
+ EPDC_CTRL_UPD_DATA_SWIZZLE_NO_SWAP = 0,
+ EPDC_CTRL_UPD_DATA_SWIZZLE_ALL_BYTES_SWAP = 0x40,
+ EPDC_CTRL_UPD_DATA_SWIZZLE_HWD_SWAP = 0x80,
+ EPDC_CTRL_UPD_DATA_SWIZZLE_HWD_BYTE_SWAP = 0xC0,
+ EPDC_CTRL_LUT_DATA_SWIZZLE_MASK = 0x30,
+ EPDC_CTRL_LUT_DATA_SWIZZLE_NO_SWAP = 0,
+ EPDC_CTRL_LUT_DATA_SWIZZLE_ALL_BYTES_SWAP = 0x10,
+ EPDC_CTRL_LUT_DATA_SWIZZLE_HWD_SWAP = 0x20,
+ EPDC_CTRL_LUT_DATA_SWIZZLE_HWD_BYTE_SWAP = 0x30,
+ EPDC_CTRL_BURST_LEN_8_8 = 0x1,
+ EPDC_CTRL_BURST_LEN_8_16 = 0,
+
+/* EPDC_RES field values */
+ EPDC_RES_VERTICAL_MASK = 0x1FFF0000,
+ EPDC_RES_VERTICAL_OFFSET = 16,
+ EPDC_RES_HORIZONTAL_MASK = 0x1FFF,
+ EPDC_RES_HORIZONTAL_OFFSET = 0,
+
+/* EPDC_FORMAT field values */
+ EPDC_FORMAT_BUF_PIXEL_SCALE_ROUND = 0x1000000,
+ EPDC_FORMAT_DEFAULT_TFT_PIXEL_MASK = 0xFF0000,
+ EPDC_FORMAT_DEFAULT_TFT_PIXEL_OFFSET = 16,
+ EPDC_FORMAT_WB_ADDR_NO_COPY = 0x4000,
+ EPDC_FORMAT_WB_TYPE_MASK = 0x3000,
+ EPDC_FORMAT_WB_TYPE_OFFSET = 12,
+ EPDC_FORMAT_WB_TYPE_WB_INTERNAL = 0x0,
+ EPDC_FORMAT_WB_TYPE_WB_WAVEFORM = 0x1000,
+ EPDC_FORMAT_WB_TYPE_WB_EXTERNAL16 = 0x2000,
+ EPDC_FORMAT_WB_TYPE_WB_EXTERNAL32 = 0x3000,
+ EPDC_FORMAT_WB_COMPRESS = 0x800,
+ EPDC_FORMAT_BUF_PIXEL_FORMAT_MASK = 0x700,
+ EPDC_FORMAT_BUF_PIXEL_FORMAT_P2N = 0x200,
+ EPDC_FORMAT_BUF_PIXEL_FORMAT_P3N = 0x300,
+ EPDC_FORMAT_BUF_PIXEL_FORMAT_P4N = 0x400,
+ EPDC_FORMAT_BUF_PIXEL_FORMAT_P5N = 0x500,
+ EPDC_FORMAT_TFT_PIXEL_FORMAT_2BIT = 0x0,
+ EPDC_FORMAT_TFT_PIXEL_FORMAT_2BIT_VCOM = 0x1,
+ EPDC_FORMAT_TFT_PIXEL_FORMAT_4BIT = 0x2,
+ EPDC_FORMAT_TFT_PIXEL_FORMAT_4BIT_VCOM = 0x3,
+
+/* EPDC_WB_FIELD field values */
+ EPDC_WB_FIELD_FIXED_MASK = 0xFF000000,
+ EPDC_WB_FIELD_FIXED_OFFSET = 24,
+ EPDC_WB_FIELD_USE_FIXED_MASK = 0x30000,
+ EPDC_WB_FIELD_USE_FIXED_OFFSET = 16,
+ EPDC_WB_FIELD_USE_FIXED_NO_FIXED = 0x0,
+ EPDC_WB_FIELD_USE_FIXED_USE_FIXED = 0x1,
+ EPDC_WB_FIELD_USE_FIXED_NE_FIXED = 0x2,
+ EPDC_WB_FIELD_USE_FIXED_EQ_FIXED = 0x3,
+ EPDC_WB_FIELD_USAGE_MASK = 0xE000,
+ EPDC_WB_FIELD_USAGE_OFFSET = 13,
+ EPDC_WB_FIELD_USAGE_NOT_USED = 0x0,
+ EPDC_WB_FIELD_USAGE_PARTIAL = 0x3,
+ EPDC_WB_FIELD_USAGE_LUT = 0x4,
+ EPDC_WB_FIELD_USAGE_CP = 0x5,
+ EPDC_WB_FIELD_USAGE_NP = 0x6,
+ EPDC_WB_FIELD_USAGE_PTS = 0x7,
+ EPDC_WB_FIELD_FROM_MASK = 0x1F00,
+ EPDC_WB_FIELD_FROM_OFFSET = 8,
+ EPDC_WB_FIELD_TO_MASK = 0xF0,
+ EPDC_WB_FIELD_TO_OFFSET = 4,
+ EPDC_WB_FIELD_LEN_MASK = 0xF,
+ EPDC_WB_FIELD_LEN_OFFSET = 0,
+
+/* EPDC_FIFOCTRL field values */
+ EPDC_FIFOCTRL_ENABLE_PRIORITY = 0x80000000,
+ EPDC_FIFOCTRL_FIFO_INIT_LEVEL_MASK = 0xFF0000,
+ EPDC_FIFOCTRL_FIFO_INIT_LEVEL_OFFSET = 16,
+ EPDC_FIFOCTRL_FIFO_H_LEVEL_MASK = 0xFF00,
+ EPDC_FIFOCTRL_FIFO_H_LEVEL_OFFSET = 8,
+ EPDC_FIFOCTRL_FIFO_L_LEVEL_MASK = 0xFF,
+ EPDC_FIFOCTRL_FIFO_L_LEVEL_OFFSET = 0,
+
+/* EPDC_UPD_CORD field values */
+ EPDC_UPD_CORD_YCORD_MASK = 0x1FFF0000,
+ EPDC_UPD_CORD_YCORD_OFFSET = 16,
+ EPDC_UPD_CORD_XCORD_MASK = 0x1FFF,
+ EPDC_UPD_CORD_XCORD_OFFSET = 0,
+
+/* EPDC_UPD_SIZE field values */
+ EPDC_UPD_SIZE_HEIGHT_MASK = 0x1FFF0000,
+ EPDC_UPD_SIZE_HEIGHT_OFFSET = 16,
+ EPDC_UPD_SIZE_WIDTH_MASK = 0x1FFF,
+ EPDC_UPD_SIZE_WIDTH_OFFSET = 0,
+
+/* EPDC_UPD_CTRL field values */
+ EPDC_UPD_CTRL_USE_FIXED = 0x80000000,
+ EPDC_UPD_CTRL_LUT_SEL_MASK = 0x3F0000,
+ EPDC_UPD_CTRL_LUT_SEL_OFFSET = 16,
+ EPDC_UPD_CTRL_WAVEFORM_MODE_MASK = 0xFF00,
+ EPDC_UPD_CTRL_WAVEFORM_MODE_OFFSET = 8,
+ EPDC_UPD_CTRL_NO_LUT_CANCEL = 0x10,
+ EPDC_UPD_CTRL_AUTOWV_PAUSE = 0x8,
+ EPDC_UPD_CTRL_AUTOWV = 0x4,
+ EPDC_UPD_CTRL_DRY_RUN = 0x2,
+ EPDC_UPD_CTRL_UPDATE_MODE_FULL = 0x1,
+
+/* EPDC_UPD_FIXED field values */
+ EPDC_UPD_FIXED_FIXNP_EN = 0x80000000,
+ EPDC_UPD_FIXED_FIXCP_EN = 0x40000000,
+ EPDC_UPD_FIXED_FIXNP_MASK = 0xFF00,
+ EPDC_UPD_FIXED_FIXNP_OFFSET = 8,
+ EPDC_UPD_FIXED_FIXCP_MASK = 0xFF,
+ EPDC_UPD_FIXED_FIXCP_OFFSET = 0,
+
+/* EPDC_AUTOWV_LUT field values */
+ EPDC_AUTOWV_LUT_DATA_MASK = 0xFF0000,
+ EPDC_AUTOWV_LUT_DATA_OFFSET = 16,
+ EPDC_AUTOWV_LUT_ADDR_MASK = 0x7,
+ EPDC_AUTOWV_LUT_ADDR_OFFSET = 0,
+
+/* EPDC_TCE_CTRL field values */
+ EPDC_TCE_CTRL_VSCAN_HOLDOFF_MASK = 0x1FF0000,
+ EPDC_TCE_CTRL_VSCAN_HOLDOFF_OFFSET = 16,
+ EPDC_TCE_CTRL_VCOM_VAL_MASK = 0xC00,
+ EPDC_TCE_CTRL_VCOM_VAL_OFFSET = 10,
+ EPDC_TCE_CTRL_VCOM_MODE_AUTO = 0x200,
+ EPDC_TCE_CTRL_VCOM_MODE_MANUAL = 0x000,
+ EPDC_TCE_CTRL_DDR_MODE_ENABLE = 0x100,
+ EPDC_TCE_CTRL_LVDS_MODE_CE_ENABLE = 0x80,
+ EPDC_TCE_CTRL_LVDS_MODE_ENABLE = 0x40,
+ EPDC_TCE_CTRL_SCAN_DIR_1_UP = 0x20,
+ EPDC_TCE_CTRL_SCAN_DIR_0_UP = 0x10,
+ EPDC_TCE_CTRL_DUAL_SCAN_ENABLE = 0x8,
+ EPDC_TCE_CTRL_SDDO_WIDTH_16BIT = 0x4,
+ EPDC_TCE_CTRL_PIXELS_PER_SDCLK_2 = 1,
+ EPDC_TCE_CTRL_PIXELS_PER_SDCLK_4 = 2,
+ EPDC_TCE_CTRL_PIXELS_PER_SDCLK_8 = 3,
+
+/* EPDC_TCE_SDCFG field values */
+ EPDC_TCE_SDCFG_SDCLK_HOLD = 0x200000,
+ EPDC_TCE_SDCFG_SDSHR = 0x100000,
+ EPDC_TCE_SDCFG_NUM_CE_MASK = 0xF0000,
+ EPDC_TCE_SDCFG_NUM_CE_OFFSET = 16,
+ EPDC_TCE_SDCFG_SDDO_REFORMAT_STANDARD = 0,
+ EPDC_TCE_SDCFG_SDDO_REFORMAT_FLIP_PIXELS = 0x4000,
+ EPDC_TCE_SDCFG_SDDO_INVERT_ENABLE = 0x2000,
+ EPDC_TCE_SDCFG_PIXELS_PER_CE_MASK = 0x1FFF,
+ EPDC_TCE_SDCFG_PIXELS_PER_CE_OFFSET = 0,
+
+/* EPDC_TCE_GDCFG field values */
+ EPDC_TCE_SDCFG_GDRL = 0x10,
+ EPDC_TCE_SDCFG_GDOE_MODE_DELAYED_GDCLK = 0x2,
+ EPDC_TCE_SDCFG_GDSP_MODE_FRAME_SYNC = 0x1,
+ EPDC_TCE_SDCFG_GDSP_MODE_ONE_LINE = 0x0,
+
+/* EPDC_TCE_HSCAN1 field values */
+ EPDC_TCE_HSCAN1_LINE_SYNC_WIDTH_MASK = 0xFFF0000,
+ EPDC_TCE_HSCAN1_LINE_SYNC_WIDTH_OFFSET = 16,
+ EPDC_TCE_HSCAN1_LINE_SYNC_MASK = 0xFFF,
+ EPDC_TCE_HSCAN1_LINE_SYNC_OFFSET = 0,
+
+/* EPDC_TCE_HSCAN2 field values */
+ EPDC_TCE_HSCAN2_LINE_END_MASK = 0xFFF0000,
+ EPDC_TCE_HSCAN2_LINE_END_OFFSET = 16,
+ EPDC_TCE_HSCAN2_LINE_BEGIN_MASK = 0xFFF,
+ EPDC_TCE_HSCAN2_LINE_BEGIN_OFFSET = 0,
+
+/* EPDC_TCE_VSCAN field values */
+ EPDC_TCE_VSCAN_FRAME_END_MASK = 0xFF0000,
+ EPDC_TCE_VSCAN_FRAME_END_OFFSET = 16,
+ EPDC_TCE_VSCAN_FRAME_BEGIN_MASK = 0xFF00,
+ EPDC_TCE_VSCAN_FRAME_BEGIN_OFFSET = 8,
+ EPDC_TCE_VSCAN_FRAME_SYNC_MASK = 0xFF,
+ EPDC_TCE_VSCAN_FRAME_SYNC_OFFSET = 0,
+
+/* EPDC_TCE_OE field values */
+ EPDC_TCE_OE_SDOED_WIDTH_MASK = 0xFF000000,
+ EPDC_TCE_OE_SDOED_WIDTH_OFFSET = 24,
+ EPDC_TCE_OE_SDOED_DLY_MASK = 0xFF0000,
+ EPDC_TCE_OE_SDOED_DLY_OFFSET = 16,
+ EPDC_TCE_OE_SDOEZ_WIDTH_MASK = 0xFF00,
+ EPDC_TCE_OE_SDOEZ_WIDTH_OFFSET = 8,
+ EPDC_TCE_OE_SDOEZ_DLY_MASK = 0xFF,
+ EPDC_TCE_OE_SDOEZ_DLY_OFFSET = 0,
+
+/* EPDC_TCE_POLARITY field values */
+ EPDC_TCE_POLARITY_GDSP_POL_ACTIVE_HIGH = 0x10,
+ EPDC_TCE_POLARITY_GDOE_POL_ACTIVE_HIGH = 0x8,
+ EPDC_TCE_POLARITY_SDOE_POL_ACTIVE_HIGH = 0x4,
+ EPDC_TCE_POLARITY_SDLE_POL_ACTIVE_HIGH = 0x2,
+ EPDC_TCE_POLARITY_SDCE_POL_ACTIVE_HIGH = 0x1,
+
+/* EPDC_TCE_TIMING1 field values */
+ EPDC_TCE_TIMING1_SDLE_SHIFT_NONE = 0x00,
+ EPDC_TCE_TIMING1_SDLE_SHIFT_1 = 0x10,
+ EPDC_TCE_TIMING1_SDLE_SHIFT_2 = 0x20,
+ EPDC_TCE_TIMING1_SDLE_SHIFT_3 = 0x30,
+ EPDC_TCE_TIMING1_SDCLK_INVERT = 0x8,
+ EPDC_TCE_TIMING1_SDCLK_SHIFT_NONE = 0,
+ EPDC_TCE_TIMING1_SDCLK_SHIFT_1CYCLE = 1,
+ EPDC_TCE_TIMING1_SDCLK_SHIFT_2CYCLES = 2,
+ EPDC_TCE_TIMING1_SDCLK_SHIFT_3CYCLES = 3,
+
+/* EPDC_TCE_TIMING2 field values */
+ EPDC_TCE_TIMING2_GDCLK_HP_MASK = 0xFFFF0000,
+ EPDC_TCE_TIMING2_GDCLK_HP_OFFSET = 16,
+ EPDC_TCE_TIMING2_GDSP_OFFSET_MASK = 0xFFFF,
+ EPDC_TCE_TIMING2_GDSP_OFFSET_OFFSET = 0,
+
+/* EPDC_TCE_TIMING3 field values */
+ EPDC_TCE_TIMING3_GDOE_OFFSET_MASK = 0xFFFF0000,
+ EPDC_TCE_TIMING3_GDOE_OFFSET_OFFSET = 16,
+ EPDC_TCE_TIMING3_GDCLK_OFFSET_MASK = 0xFFFF,
+ EPDC_TCE_TIMING3_GDCLK_OFFSET_OFFSET = 0,
+
+/* EPDC EPDC_PIGEON_CTRL0 field values */
+ EPDC_PIGEON_CTRL0_LD_PERIOD_MASK = 0xFFF0000,
+ EPDC_PIGEON_CTRL0_LD_PERIOD_OFFSET = 16,
+ EPDC_PIGEON_CTRL0_FD_PERIOD_MASK = 0xFFF,
+ EPDC_PIGEON_CTRL0_FD_PERIOD_OFFSET = 0,
+
+/* EPDC EPDC_PIGEON_CTRL1 field values */
+ EPDC_PIGEON_CTRL1_LD_PERIOD_MASK = 0xFFF0000,
+ EPDC_PIGEON_CTRL1_LD_PERIOD_OFFSET = 16,
+ EPDC_PIGEON_CTRL1_FD_PERIOD_MASK = 0xFFF,
+ EPDC_PIGEON_CTRL1_FD_PERIOD_OFFSET = 0,
+
+/* EPDC_IRQ_MASK/EPDC_IRQ field values */
+ EPDC_IRQ_WB_CMPLT_IRQ = 0x10000,
+ EPDC_IRQ_LUT_COL_IRQ = 0x20000,
+ EPDC_IRQ_TCE_UNDERRUN_IRQ = 0x40000,
+ EPDC_IRQ_FRAME_END_IRQ = 0x80000,
+ EPDC_IRQ_BUS_ERROR_IRQ = 0x100000,
+ EPDC_IRQ_TCE_IDLE_IRQ = 0x200000,
+ EPDC_IRQ_UPD_DONE_IRQ = 0x400000,
+ EPDC_IRQ_PWR_IRQ = 0x800000,
+
+/* EPDC_STATUS_NEXTLUT field values */
+ EPDC_STATUS_NEXTLUT_NEXT_LUT_VALID = 0x100,
+ EPDC_STATUS_NEXTLUT_NEXT_LUT_MASK = 0x3F,
+ EPDC_STATUS_NEXTLUT_NEXT_LUT_OFFSET = 0,
+
+/* EPDC_STATUS field values */
+ EPDC_STATUS_HISTOGRAM_CP_MASK = 0x1F0000,
+ EPDC_STATUS_HISTOGRAM_CP_OFFSET = 16,
+ EPDC_STATUS_HISTOGRAM_NP_MASK = 0x1F00,
+ EPDC_STATUS_HISTOGRAM_NP_OFFSET = 8,
+ EPDC_STATUS_UPD_VOID = 0x8,
+ EPDC_STATUS_LUTS_UNDERRUN = 0x4,
+ EPDC_STATUS_LUTS_BUSY = 0x2,
+ EPDC_STATUS_WB_BUSY = 0x1,
+
+/* EPDC_UPD_COL_CORD field values */
+ EPDC_UPD_COL_CORD_YCORD_MASK = 0x1FFF0000,
+ EPDC_UPD_COL_CORD_YCORD_OFFSET = 16,
+ EPDC_UPD_COL_CORD_XCORD_MASK = 0x1FFF,
+ EPDC_UPD_COL_CORD_XCORD_OFFSET = 0,
+
+/* EPDC_UPD_COL_SIZE field values */
+ EPDC_UPD_COL_SIZE_HEIGHT_MASK = 0x1FFF0000,
+ EPDC_UPD_COL_SIZE_HEIGHT_OFFSET = 16,
+ EPDC_UPD_COL_SIZE_WIDTH_MASK = 0x1FFF,
+ EPDC_UPD_COL_SIZE_WIDTH_OFFSET = 0,
+
+/* EPDC_DEBUG field values */
+ EPDC_DEBUG_DEBUG_LUT_SEL_MASK = 0x3F00000,
+ EPDC_DEBUG_DEBUG_LUT_SEL_OFFSET = 24,
+ EPDC_DEBUG_UBW_BURST_LEN_MASK = 0xF000,
+ EPDC_DEBUG_UBW_BURST_LEN_OFFSET = 12,
+ EPDC_DEBUG_UBR_BURST_LEN_MASK = 0xF00,
+ EPDC_DEBUG_UBR_BURST_LEN = 8,
+ EPDC_DEBUG_UPD_BURST_LEN_MASK = 0xF0,
+ EPDC_DEBUG_UPD_BURST_LEN_OFFSET = 4,
+ EPDC_DEBUG_UPDATE_SAME = 0x4,
+ EPDC_DEBUG_UNDERRUN_RECOVER = 0x2,
+ EPDC_DEBUG_COLLISION_OFF = 0x1,
+
+/* EPDC_DEBUG_LUT field values */
+ EPDC_DEBUG_LUT_LUTADDR_MASK = 0x3FF0000,
+ EPDC_DEBUG_LUT_LUTADDR_OFFSET = 16,
+ EPDC_DEBUG_LUT_FRAME_MASK = 0x7FE0,
+ EPDC_DEBUG_LUT_FRAME_OFFSET = 5,
+ EPDC_DEBUG_LUT_STATEMACHINE_MASK = 0x1F,
+ EPDC_DEBUG_LUT_STATEMACHINE_OFFSET = 0,
+
+/* EPDC_HISTx_PARAM field values */
+ EPDC_HIST_PARAM_VALUE0_MASK = 0x1F,
+ EPDC_HIST_PARAM_VALUE0_OFFSET = 0,
+ EPDC_HIST_PARAM_VALUE1_MASK = 0x1F00,
+ EPDC_HIST_PARAM_VALUE1_OFFSET = 8,
+ EPDC_HIST_PARAM_VALUE2_MASK = 0x1F0000,
+ EPDC_HIST_PARAM_VALUE2_OFFSET = 16,
+ EPDC_HIST_PARAM_VALUE3_MASK = 0x1F000000,
+ EPDC_HIST_PARAM_VALUE3_OFFSET = 24,
+ EPDC_HIST_PARAM_VALUE4_MASK = 0x1F,
+ EPDC_HIST_PARAM_VALUE4_OFFSET = 0,
+ EPDC_HIST_PARAM_VALUE5_MASK = 0x1F00,
+ EPDC_HIST_PARAM_VALUE5_OFFSET = 8,
+ EPDC_HIST_PARAM_VALUE6_MASK = 0x1F0000,
+ EPDC_HIST_PARAM_VALUE6_OFFSET = 16,
+ EPDC_HIST_PARAM_VALUE7_MASK = 0x1F000000,
+ EPDC_HIST_PARAM_VALUE7_OFFSET = 24,
+ EPDC_HIST_PARAM_VALUE8_MASK = 0x1F,
+ EPDC_HIST_PARAM_VALUE8_OFFSET = 0,
+ EPDC_HIST_PARAM_VALUE9_MASK = 0x1F00,
+ EPDC_HIST_PARAM_VALUE9_OFFSET = 8,
+ EPDC_HIST_PARAM_VALUE10_MASK = 0x1F0000,
+ EPDC_HIST_PARAM_VALUE10_OFFSET = 16,
+ EPDC_HIST_PARAM_VALUE11_MASK = 0x1F000000,
+ EPDC_HIST_PARAM_VALUE11_OFFSET = 24,
+ EPDC_HIST_PARAM_VALUE12_MASK = 0x1F,
+ EPDC_HIST_PARAM_VALUE12_OFFSET = 0,
+ EPDC_HIST_PARAM_VALUE13_MASK = 0x1F00,
+ EPDC_HIST_PARAM_VALUE13_OFFSET = 8,
+ EPDC_HIST_PARAM_VALUE14_MASK = 0x1F0000,
+ EPDC_HIST_PARAM_VALUE14_OFFSET = 16,
+ EPDC_HIST_PARAM_VALUE15_MASK = 0x1F000000,
+ EPDC_HIST_PARAM_VALUE15_OFFSET = 24,
+
+/* EPDC_GPIO field values */
+ EPDC_GPIO_PWRSTAT = 0x100,
+ EPDC_GPIO_PWRWAKE = 0x80,
+ EPDC_GPIO_PWRCOM = 0x40,
+ EPDC_GPIO_PWRCTRL_MASK = 0x3C,
+ EPDC_GPIO_PWRCTRL_OFFSET = 2,
+ EPDC_GPIO_BDR_MASK = 0x3,
+ EPDC_GPIO_BDR_OFFSET = 0,
+
+/* EPDC_VERSION field values */
+ EPDC_VERSION_MAJOR_MASK = 0xFF000000,
+ EPDC_VERSION_MAJOR_OFFSET = 24,
+ EPDC_VERSION_MINOR_MASK = 0xFF0000,
+ EPDC_VERSION_MINOR_OFFSET = 16,
+ EPDC_VERSION_STEP_MASK = 0xFFFF,
+ EPDC_VERSION_STEP_OFFSET = 0,
+};
+
+#endif /* __EPDC_REGS_INCLUDED__ */
diff --git a/drivers/video/fbdev/mxc/hannstar_cabc.c b/drivers/video/fbdev/mxc/hannstar_cabc.c
new file mode 100644
index 000000000000..14528c8c6511
--- /dev/null
+++ b/drivers/video/fbdev/mxc/hannstar_cabc.c
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2014-2015 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_gpio.h>
+#include <linux/platform_device.h>
+
+#define DRIVER_NAME "hannstar-cabc"
+
+static const struct of_device_id cabc_dt_ids[] = {
+ { .compatible = "hannstar,cabc", },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, cabc_dt_ids);
+
+static int cabc_probe(struct platform_device *pdev)
+{
+ struct device_node *np = pdev->dev.of_node, *pp;
+ int cabc_gpio, ret = 0;
+ bool cabc_enable;
+ unsigned long gpio_flag;
+ enum of_gpio_flags flags;
+
+ for_each_child_of_node(np, pp) {
+ if (!of_find_property(pp, "gpios", NULL)) {
+ dev_warn(&pdev->dev, "Found interface without "
+ "gpios\n");
+ continue;
+ }
+
+ cabc_gpio = of_get_gpio_flags(pp, 0, &flags);
+ if (!gpio_is_valid(cabc_gpio)) {
+ ret = cabc_gpio;
+ if (ret != -EPROBE_DEFER)
+ dev_err(&pdev->dev,
+ "Failed to get gpio flags, "
+ "error: %d\n", ret);
+ return ret;
+ }
+
+ cabc_enable = of_property_read_bool(pp, "cabc-enable");
+
+ if (flags & OF_GPIO_ACTIVE_LOW)
+ gpio_flag = cabc_enable ?
+ GPIOF_OUT_INIT_LOW : GPIOF_OUT_INIT_HIGH;
+ else
+ gpio_flag = cabc_enable ?
+ GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW;
+
+ devm_gpio_request_one(&pdev->dev, cabc_gpio,
+ gpio_flag, "hannstar-cabc");
+ }
+
+ return ret;
+}
+
+static struct platform_driver cabc_driver = {
+ .probe = cabc_probe,
+ .driver = {
+ .of_match_table = cabc_dt_ids,
+ .name = DRIVER_NAME,
+ .owner = THIS_MODULE,
+ },
+};
+module_platform_driver(cabc_driver);
+
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("Hannstar CABC driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:" DRIVER_NAME);
diff --git a/drivers/video/fbdev/mxc/imx_dcss.c b/drivers/video/fbdev/mxc/imx_dcss.c
new file mode 100644
index 000000000000..d2403314addb
--- /dev/null
+++ b/drivers/video/fbdev/mxc/imx_dcss.c
@@ -0,0 +1,3556 @@
+/*
+ * Copyright 2017 NXP
+ *
+ * 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/module.h>
+#include <linux/kernel.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+#include <linux/cache.h>
+#include <asm/cacheflush.h>
+#include <linux/uaccess.h>
+#include <linux/delay.h>
+#include <linux/dma-mapping.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/irqdesc.h>
+#include <linux/fb.h>
+#include <linux/freezer.h>
+#include <linux/kfifo.h>
+#include <linux/kthread.h>
+#include <linux/log2.h>
+#include <linux/regulator/consumer.h>
+#include <linux/scatterlist.h>
+#include <linux/videodev2.h>
+#include <video/mxc_edid.h>
+#include <linux/workqueue.h>
+
+#include "mxc_dispdrv.h"
+#include "imx_dcss_table.h"
+
+/* sub engines address start offset */
+#define HDR_CHAN1_START 0x00000
+#define HDR_CHAN2_START 0x04000
+#define HDR_CHAN3_START 0x08000
+#define HDR_OUT_START 0x0C000
+#define DOLBY_VISION_START 0x10000
+#define DOLBY_GRAPHIC_START 0x11000
+#define DOLBY_OUTPUT_START 0x12000
+#define DEC400D_CHAN1_START 0x15000
+#define DTRC_CHAN2_START 0x16000
+#define DTRC_CHAN3_START 0x17000
+#define DPR_CHAN1_START 0x18000
+#define DPR_CHAN2_START 0x19000
+#define DPR_CHAN3_START 0x1A000
+#define SUBSAM_START 0x1B000
+#define SCALER_CHAN1_START 0x1C000
+#define SCALER_CHAN2_START 0x1C400
+#define SCALER_CHAN3_START 0x1C800
+#define DTG_START 0x20000
+#define WR_SCL_START 0x21000
+#define RD_SRC_START 0x22000
+#define CTX_LD_START 0x23000
+#define LUT_LD_START 0x24000
+#define IRQ_STEER_START 0x2D000
+#define LPCG_START 0x2E000
+#define BLK_CTRL_START 0x2F000
+
+#define DCSS_MODE_SCALE_EN (1 << 0)
+#define DCSS_MODE_CSC_EN (1 << 1)
+#define DCSS_MODE_RESOLVE_EN (1 << 2)
+#define DCSS_MODE_DECOMPRESS_EN (1 << 3)
+#define DCSS_MODE_HDR10_EN (1 << 4)
+#define DCSS_MODE_DOLBY_EN (1 << 5)
+
+/* define several clocks rate */
+#define DISP_AXI_RATE 800000000
+#define DISP_APB_RATE 133000000
+#define DISP_RTRAM_RATE 400000000
+#define DISP_PIXEL_RATE 100000000
+
+#define TILE_TYPE_LINEAR 0x0
+#define TILE_TYPE_GPU_STANDARD 0x1
+#define TILE_TYPE_GPU_SUPER 0x2
+#define TILE_TYPE_VPU_2PYUV420 0x3
+#define TILE_TYPE_VPU_2PVP9 0x4
+
+#define PIXEL_STORE_NONCOMPRESS 0x1
+#define PIXEL_STORE_COMPRESS 0x2
+
+#define CSC_MODE_BYPASS 0x0
+#define CSC_MODE_YUV2RGB 0x1
+#define CSC_MODE_RGB2YUV 0x2
+
+#define HSYNC_ACTIVE_HIGH 0x1
+#define VSYNC_ACTIVE_HIGH 0x1
+#define DE_ACTIVE_HIGH 0x1
+
+/* pixel format macros */
+#define PIX_FMT_A8R8G8B8 0x1
+#define PIX_FMT_A2R10G10B10 0x2
+#define PIX_FMT_1PYUV422 0x3
+#define PIX_FMT_2PYUV420_8 0x4
+#define PIX_FMT_2PYUV420_10 0x5
+#define PIX_FMT_2PVP9_8 0x6
+#define PIX_FMT_2PVP9_10 0x7
+#define PIX_FMT_AYUV444 0x8
+
+/* more formats fourcc define */
+#define V4L2_PIX_FMT_A2R10G10B10 v4l2_fourcc('B', 'A', '3', '0') /* 32 ARGB-2-10-10-10 */
+
+#define MAX_WIDTH 4096
+#define MAX_HEIGHT 4096
+
+#define RED 0
+#define GREEN 1
+#define BLUE 2
+#define TRANSP 3
+
+#define CTXLD_TYPE_DB 0x1
+#define CTXLD_TYPE_SB 0x2
+
+#define DCSS_REGS_SIZE 0x30000
+#define DCSS_CFIFO_SIZE 0x100000 /* power of 2 */
+#define DCSS_IRQS_NUM 32
+
+/* define registers offset */
+#define CTXLD_CTRL_STATUS 0x0
+#define CTXLD_CTRL_STATUS_SET 0x4
+#define CTXLD_CTRL_STATUS_CLR 0x8
+#define CTXLD_CTRL_STATUS_TOG 0xC
+
+#define CTXLD_DB_BASE_ADDR 0x10
+#define CTXLD_DB_COUNT 0x14
+#define CTXLD_SB_BASE_ADDR 0x18
+#define CTXLD_SB_COUNT 0x1C
+
+#define TC_LINE1_INT 0x50
+#define TC_INTERRUPT_STATUS 0x5C
+#define TC_INTERRUPT_CONTROL 0x60
+#define TC_INTERRUPT_MASK 0x68
+
+/* define dcss state */
+#define DCSS_STATE_RESET 0x0
+#define DCSS_STATE_RUNNING 0x1
+#define DCSS_STATE_STOP 0x2
+
+/* io memory blocks number */
+#define IORESOURCE_MEM_NUM 0x2
+
+#define USE_CTXLD 0x1
+
+#define NAME_LEN 32
+
+/* TODO: DCSS IRQs indexes, more added later */
+#define IRQ_DPR_CH1 3
+#define IRQ_DPR_CH2 4
+#define IRQ_DPR_CH3 5
+#define IRQ_CTX_LD 6
+#define IRQ_TC_LINE1 8
+#define IRQ_DEC400D_CH1 15
+#define IRQ_DTRC_CH2 16
+#define IRQ_DTRC_CH3 17
+
+/* ctxld irqs status */
+#define RD_ERR (1 << 16)
+#define DB_COMP (1 << 17)
+#define SB_HP_COMP (1 << 18)
+#define SB_LP_COMP (1 << 19)
+#define AHB_ERR (1 << 22)
+
+/* ctxld irqs mask */
+#define RD_ERR_EN (1 << 2)
+#define DB_COMP_EN (1 << 3)
+#define SB_HP_COMP_EN (1 << 4)
+#define SB_LP_COMP_EN (1 << 5)
+#define AHB_ERR_EN (1 << 8)
+
+/* channels */
+#define DCSS_CHAN_MAIN 0
+#define DCSS_CHAN_SECONDARY 1
+#define DCSS_CHAN_THIRD 2
+/* all channels are disabled */
+#define DCSS_CHAN_NULL 3
+
+/**
+ * kfifo_to_end_len - returns the size from 'out' to buffer end
+ * this is a kfifo extend interface as required
+ */
+#define kfifo_to_end_len(fifo) ( \
+{ \
+ unsigned int ptr; \
+ \
+ if (!(fifo)->kfifo.in) \
+ ptr = 0; \
+ else \
+ ptr = ((((fifo)->kfifo.in - 1) & (fifo)->kfifo.mask) + 1); \
+ \
+ kfifo_size(fifo) - ptr; \
+} \
+)
+
+/* TODO: */
+struct coordinate {
+ uint32_t x;
+ uint32_t y;
+};
+
+struct rectangle {
+ uint32_t ulc_x;
+ uint32_t ulc_y;
+ uint32_t lrc_x;
+ uint32_t lrc_y;
+};
+
+struct pix_fmt_info {
+ uint32_t fourcc;
+ uint32_t bpp;
+ bool is_yuv;
+};
+
+struct dcss_pixmap {
+ uint32_t channel_id;
+ uint32_t width;
+ uint32_t height;
+ uint32_t bits_per_pixel;
+ uint32_t pitch;
+ struct rectangle crop; /* active area */
+ uint32_t format;
+ uint32_t tile_type; /* see TILE_TYPE_* macros */
+ uint32_t pixel_store; /* see PIXEL_STORE_* macros */
+ uint32_t flags;
+ dma_addr_t paddr;
+};
+
+/* Display state format in DRAM used by CTX_LD */
+struct ctxld_unit {
+ uint32_t reg_value;
+ uint32_t reg_offset;
+};
+
+/* ctxld buffer */
+struct cbuffer{
+ void *sb_addr;
+ void *db_addr;
+ uint32_t sb_len; /* buffer length in elements */
+ uint32_t db_len;
+ uint32_t sb_data_len; /* data length in elements */
+ uint32_t db_data_len;
+ uint32_t esize; /* size per element */
+};
+
+struct vsync_info {
+ wait_queue_head_t vwait;
+ unsigned long vcount;
+};
+
+struct ctxld_commit {
+ struct list_head list;
+ struct kref refcount;
+ struct work_struct work;
+ void *data;
+ uint32_t sb_data_len;
+ uint32_t sb_hp_data_len;
+ uint32_t db_data_len;
+ uint32_t sb_trig_pos;
+ uint32_t db_trig_pos;
+};
+
+struct ctxld_fifo {
+ uint32_t size;
+ void *vaddr;
+ dma_addr_t dma_handle;
+ struct list_head ctxld_list; /* manage context loader */
+ DECLARE_KFIFO_PTR(fifo, struct ctxld_unit);
+ struct scatterlist sgl[1];
+ uint32_t sgl_num;
+ struct workqueue_struct *ctxld_wq;
+ /* synchronization in two points:
+ * a. simutanous fifo commits
+ * b. queue waiting for cfifo flush
+ */
+ wait_queue_head_t cqueue;
+ struct completion complete;
+};
+
+/* channel info: 3 channels in DCSS */
+struct dcss_channel_info {
+ uint32_t channel_id;
+ uint32_t channel_en; /* channel 1 enable by default */
+ struct platform_device *pdev;
+ struct fb_info *fb_info;
+ struct dcss_pixmap input;
+ struct rectangle ch_pos; /* display position in dtg for one channel */
+ struct cbuffer cb;
+ uint32_t hdr10_in_addr;
+ uint32_t decomp_addr;
+ uint32_t dpr_addr;
+ uint32_t scaler_addr;
+ int blank; /* see FB_BLANK_* macros */
+ uint32_t csc_mode; /* see CSC_MODE_* macros */
+ bool dpr_scaler_en; /* record dpr and scaler enabled or not */
+ unsigned long update_stamp; /* default is ~0x0UL */
+
+ void *dev_data; /* pointer to dcss_info */
+};
+
+struct dcss_channels {
+ struct dcss_channel_info chan_info[3];
+ uint32_t hdr10_out_addr;
+ uint32_t subsam_addr;
+ uint32_t dtg_addr;
+ uint32_t wrscl_addr;
+ uint32_t rdsrc_addr;
+ uint32_t ctxld_addr;
+ uint32_t lutld_addr;
+ uint32_t hdmi_phy_addr;
+ uint32_t irq_steer_addr;
+ uint32_t lpcg_addr;
+ uint32_t blk_ctrl_addr;
+};
+
+/* display info: output to monitor */
+struct dcss_info {
+ struct platform_device *pdev;
+ void __iomem *base;
+ void __iomem *blkctl_base;
+ spinlock_t llock; /* list lock: for ctxld_list */
+ int irqs[DCSS_IRQS_NUM];
+ uint32_t irqs_num;
+ uint32_t dcss_state; /* see DCSS_STATE_* macros */
+ struct clk *clk_axi;
+ struct clk *clk_apb;
+ struct clk *clk_rtram;
+ struct clk *clk_dtrc;
+ struct clk *clk_pix;
+ struct regulator *power;
+ struct ctxld_fifo cfifo;
+ struct task_struct *handler;
+ struct dcss_pixmap *output;
+ struct dcss_channels chans; /* maximum 3 channels
+ * TODO: better change to layer
+ */
+ const struct fb_videomode *dft_disp_mode; /* Default display mode */
+ uint32_t tile_type; /* see TILE_TYPE_* macros */
+ uint32_t pixel_store; /* see PIXEL_STORE_* macros */
+ uint32_t csc_mode; /* see CSC_MODE_* macros */
+ uint32_t mode_flags; /* see DCSS_MODE_* macros */
+ uint32_t sync_flags; /* see FB_SYNC_* macros */
+ uint32_t hsync_pol;
+ uint32_t vsync_pol;
+ uint32_t de_pol;
+ char disp_dev[NAME_LEN];
+ struct mxc_dispdrv_handle *dispdrv;
+ struct vsync_info vinfo;
+
+ atomic_t flush;
+};
+
+const struct fb_videomode imx_cea_mode[100] = {
+ /* #1: 640x480p@59.94/60Hz 4:3 */
+ [1] = {
+ NULL, 60, 640, 480, 39722, 48, 16, 33, 10, 96, 2, 0,
+ FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_4_3, 0,
+ },
+ /* #2: 720x480p@59.94/60Hz 4:3 */
+ [2] = {
+ NULL, 60, 720, 480, 37037, 60, 16, 30, 9, 62, 6, 0,
+ FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_4_3, 0,
+ },
+ /* #3: 720x480p@59.94/60Hz 16:9 */
+ [3] = {
+ NULL, 60, 720, 480, 37037, 60, 16, 30, 9, 62, 6, 0,
+ FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_16_9, 0,
+ },
+ /* #4: 1280x720p@59.94/60Hz 16:9 */
+ [4] = {
+ NULL, 60, 1280, 720, 13468, 220, 110, 20, 5, 40, 5,
+ FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+ FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_16_9, 0
+ },
+ /* #5: 1920x1080i@59.94/60Hz 16:9 */
+ [5] = {
+ NULL, 60, 1920, 1080, 13763, 148, 88, 15, 2, 44, 5,
+ FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+ FB_VMODE_INTERLACED | FB_VMODE_ASPECT_16_9, 0,
+ },
+ /* #6: 720(1440)x480iH@59.94/60Hz 4:3 */
+ [6] = {
+ NULL, 60, 1440, 480, 18554/*37108*/, 114, 38, 15, 4, 124, 3, 0,
+ FB_VMODE_INTERLACED | FB_VMODE_ASPECT_4_3, 0,
+ },
+ /* #7: 720(1440)x480iH@59.94/60Hz 16:9 */
+ [7] = {
+ NULL, 60, 1440, 480, 18554/*37108*/, 114, 38, 15, 4, 124, 3, 0,
+ FB_VMODE_INTERLACED | FB_VMODE_ASPECT_16_9, 0,
+ },
+ /* #8: 720(1440)x240pH@59.94/60Hz 4:3 */
+ [8] = {
+ NULL, 60, 1440, 240, 37108, 114, 38, 15, 4, 124, 3, 0,
+ FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_4_3, 0,
+ },
+ /* #9: 720(1440)x240pH@59.94/60Hz 16:9 */
+ [9] = {
+ NULL, 60, 1440, 240, 37108, 114, 38, 15, 4, 124, 3, 0,
+ FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_16_9, 0,
+ },
+ /* #14: 1440x480p@59.94/60Hz 4:3 */
+ [14] = {
+ NULL, 60, 1440, 480, 18500, 120, 32, 30, 9, 124, 6, 0,
+ FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_4_3, 0,
+ },
+ /* #15: 1440x480p@59.94/60Hz 16:9 */
+ [15] = {
+ NULL, 60, 1440, 480, 18500, 120, 32, 30, 9, 124, 6, 0,
+ FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_16_9, 0,
+ },
+ /* #16: 1920x1080p@60Hz 16:9 */
+ [16] = {
+ NULL, 60, 1920, 1080, 6734, 148, 88, 36, 4, 44, 5,
+ FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+ FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_16_9, 0,
+ },
+ /* #17: 720x576pH@50Hz 4:3 */
+ [17] = {
+ NULL, 50, 720, 576, 37037, 68, 12, 39, 5, 64, 5, 0,
+ FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_4_3, 0,
+ },
+ /* #18: 720x576pH@50Hz 16:9 */
+ [18] = {
+ NULL, 50, 720, 576, 37037, 68, 12, 39, 5, 64, 5, 0,
+ FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_16_9, 0,
+ },
+ /* #19: 1280x720p@50Hz */
+ [19] = {
+ NULL, 50, 1280, 720, 13468, 220, 440, 20, 5, 40, 5,
+ FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+ FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_16_9, 0,
+ },
+ /* #20: 1920x1080i@50Hz */
+ [20] = {
+ NULL, 50, 1920, 1080, 13480, 148, 528, 15, 5, 528, 5,
+ FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+ FB_VMODE_INTERLACED | FB_VMODE_ASPECT_16_9, 0,
+ },
+ /* #23: 720(1440)x288pH@50Hz 4:3 */
+ [23] = {
+ NULL, 50, 1440, 288, 37037, 138, 24, 19, 2, 126, 3, 0,
+ FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_4_3, 0,
+ },
+ /* #24: 720(1440)x288pH@50Hz 16:9 */
+ [24] = {
+ NULL, 50, 1440, 288, 37037, 138, 24, 19, 2, 126, 3, 0,
+ FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_16_9, 0,
+ },
+ /* #29: 720(1440)x576pH@50Hz 4:3 */
+ [29] = {
+ NULL, 50, 1440, 576, 18518, 136, 24, 39, 5, 128, 5, 0,
+ FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_4_3, 0,
+ },
+ /* #30: 720(1440)x576pH@50Hz 16:9 */
+ [30] = {
+ NULL, 50, 1440, 576, 18518, 136, 24, 39, 5, 128, 5, 0,
+ FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_16_9, 0,
+ },
+ /* #31: 1920x1080p@50Hz */
+ [31] = {
+ NULL, 50, 1920, 1080, 6734, 148, 528, 36, 4, 44, 5,
+ FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+ FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_16_9, 0,
+ },
+ /* #32: 1920x1080p@23.98/24Hz */
+ [32] = {
+ NULL, 24, 1920, 1080, 13468, 148, 638, 36, 4, 44, 5,
+ FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+ FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_16_9, 0,
+ },
+ /* #33: 1920x1080p@25Hz */
+ [33] = {
+ NULL, 25, 1920, 1080, 13468, 148, 528, 36, 4, 44, 5,
+ FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+ FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_16_9, 0,
+ },
+ /* #34: 1920x1080p@30Hz */
+ [34] = {
+ NULL, 30, 1920, 1080, 13468, 148, 88, 36, 4, 44, 5,
+ FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+ FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_16_9, 0,
+ },
+ /* #41: 1280x720p@100Hz 16:9 */
+ [41] = {
+ NULL, 100, 1280, 720, 6734, 220, 440, 20, 5, 40, 5,
+ FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+ FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_16_9, 0
+ },
+ /* #47: 1280x720p@119.88/120Hz 16:9 */
+ [47] = {
+ NULL, 120, 1280, 720, 6734, 220, 110, 20, 5, 40, 5,
+ FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+ FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_16_9, 0
+ },
+ /* #95: 3840x2160p@30Hz 16:9 */
+ [95] = {
+ NULL, 30, 3840, 2160, 3367, 296, 176, 72, 8, 88, 10,
+ FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+ FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_16_9, 0
+ },
+ /* #97: 3840x2160p@60Hz 16:9 */
+ [97] = {
+ NULL, 30, 3840, 2160, 1684, 296, 176, 72, 8, 88, 10,
+ FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+ FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_16_9, 0
+ },
+};
+
+static const struct of_device_id dcss_dt_ids[] ={
+ { .compatible = "fsl,imx8mq-dcss", },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, dcss_dt_ids);
+
+static void dcss_free_fbmem(struct fb_info *fbi);
+static int dcss_open(struct fb_info *fbi, int user);
+static int dcss_check_var(struct fb_var_screeninfo *var,
+ struct fb_info *fbi);
+static int dcss_set_par(struct fb_info *fbi);
+static int dcss_setcolreg(unsigned regno, unsigned red, unsigned green,
+ unsigned blue, unsigned transp, struct fb_info *info);
+static int dcss_blank(int blank, struct fb_info *fbi);
+static int dcss_pan_display(struct fb_var_screeninfo *var,
+ struct fb_info *fbi);
+static int dcss_ioctl(struct fb_info *fbi, unsigned int cmd,
+ unsigned long arg);
+static int vcount_compare(unsigned long vcount,
+ struct vsync_info *vinfo);
+static int dcss_wait_for_vsync(unsigned long crtc,
+ struct dcss_info *info);
+static void flush_cfifo(struct ctxld_fifo *cfifo,
+ struct work_struct *work);
+
+static struct fb_ops dcss_ops = {
+ .owner = THIS_MODULE,
+ .fb_open = dcss_open,
+ .fb_check_var = dcss_check_var,
+ .fb_set_par = dcss_set_par,
+ .fb_setcolreg = dcss_setcolreg,
+ .fb_blank = dcss_blank,
+ .fb_pan_display = dcss_pan_display,
+ .fb_ioctl = dcss_ioctl,
+ .fb_fillrect = cfb_fillrect,
+ .fb_copyarea = cfb_copyarea,
+ .fb_imageblit = cfb_imageblit,
+};
+
+/* TODO: more added later */
+static const struct pix_fmt_info formats[] = {
+ {
+ .fourcc = V4L2_PIX_FMT_ARGB32,
+ .bpp = 32,
+ .is_yuv = false,
+ }, {
+ .fourcc = V4L2_PIX_FMT_A2R10G10B10,
+ .bpp = 32,
+ .is_yuv = false,
+ }, {
+ .fourcc = V4L2_PIX_FMT_YUYV,
+ .bpp = 16,
+ .is_yuv = true,
+ }, {
+ .fourcc = V4L2_PIX_FMT_YVYU,
+ .bpp = 16,
+ .is_yuv = true,
+ }, {
+ .fourcc = V4L2_PIX_FMT_UYVY,
+ .bpp = 16,
+ .is_yuv = true,
+ }, {
+ .fourcc = V4L2_PIX_FMT_VYUY,
+ .bpp = 16,
+ .is_yuv = true,
+ }, {
+ .fourcc = V4L2_PIX_FMT_YUV32,
+ .bpp = 32,
+ .is_yuv = true,
+ }, {
+ .fourcc = V4L2_PIX_FMT_NV12,
+ .bpp = 8,
+ .is_yuv = true,
+ },
+};
+
+static const struct fb_bitfield def_a8r8g8b8[] = {
+ [RED] = {
+ .offset = 16,
+ .length = 8,
+ .msb_right = 0,
+ },
+ [GREEN] = {
+ .offset = 8,
+ .length = 8,
+ .msb_right = 0,
+ },
+ [BLUE] = {
+ .offset = 0,
+ .length = 8,
+ .msb_right = 0,
+ },
+ [TRANSP] = {
+ .offset = 24,
+ .length = 8,
+ .msb_right = 0,
+ }
+};
+
+static const struct fb_bitfield def_a2r10g10b10[] = {
+ [RED] = {
+ .offset = 20,
+ .length = 10,
+ },
+ [GREEN] = {
+ .offset = 10,
+ .length = 10,
+ },
+ [BLUE] = {
+ .offset = 0,
+ .length = 10,
+ },
+ [TRANSP] = {
+ .offset = 30,
+ .length = 2,
+ }
+};
+
+static const struct pix_fmt_info *get_fmt_info(uint32_t fourcc)
+{
+ uint32_t i;
+
+ for (i = 0; i < ARRAY_SIZE(formats); i++) {
+ if (formats[i].fourcc == fourcc)
+ return &formats[i];
+ }
+
+ return NULL;
+}
+
+static int fmt_is_yuv(uint32_t fourcc)
+{
+ switch (fourcc) {
+ case V4L2_PIX_FMT_ARGB32:
+ case V4L2_PIX_FMT_A2R10G10B10:
+ return 0;
+ case V4L2_PIX_FMT_YUYV:
+ case V4L2_PIX_FMT_YVYU:
+ case V4L2_PIX_FMT_UYVY:
+ case V4L2_PIX_FMT_VYUY:
+ case V4L2_PIX_FMT_YUV32:
+ return 1;
+ case V4L2_PIX_FMT_NV12:
+ return 2;
+ default:
+ return -EINVAL;
+ }
+}
+
+/* TODO: writel ? */
+#define fill_unit(uint, offset, value) { \
+ unit->reg_value = value; \
+ unit->reg_offset = offset; \
+}
+
+static void fill_sb(struct cbuffer *cb,
+ uint32_t offset,
+ uint32_t value)
+{
+ struct ctxld_unit *unit = NULL;
+
+ BUG_ON(!cb);
+
+ if (unlikely(cb->sb_data_len == cb->sb_len)) {
+ /* sb is full */
+ BUG_ON(1);
+ }
+
+ unit = (struct ctxld_unit *)(cb->sb_addr + cb->sb_data_len * cb->esize);
+
+ fill_unit(unit, offset, value);
+ cb->sb_data_len++;
+}
+
+static void __maybe_unused fill_db(struct cbuffer *cb,
+ uint32_t offset,
+ uint32_t value)
+{
+ struct ctxld_unit *unit = NULL;
+
+ BUG_ON(!cb);
+
+ if (unlikely(cb->db_data_len == cb->db_len)) {
+ /* db is full */
+ BUG_ON(1);
+ }
+
+ unit = (struct ctxld_unit *)(cb->db_addr + cb->db_data_len * cb->esize);
+
+ fill_unit(unit, offset, value);
+ cb->db_data_len++;
+}
+
+static void ctxld_fifo_info_print(struct ctxld_fifo *cfifo)
+{
+ pr_debug("%s: print kfifo info: **********\n", __func__);
+ pr_debug("in = 0x%x, out = 0x%x, mask = 0x%x\n",
+ cfifo->fifo.kfifo.in,
+ cfifo->fifo.kfifo.out,
+ cfifo->fifo.kfifo.mask);
+}
+
+static int ctxld_fifo_alloc(struct device *dev,
+ struct ctxld_fifo *cfifo,
+ uint32_t fifo_size)
+{
+ if (!cfifo || fifo_size < 2)
+ return -EINVAL;
+
+ fifo_size = roundup_pow_of_two(fifo_size);
+ cfifo->vaddr = dma_alloc_coherent(dev, fifo_size,
+ &cfifo->dma_handle,
+ GFP_DMA | GFP_KERNEL);
+ if (!cfifo->vaddr) {
+ dev_err(dev, "allocate ctxld fifo failed\n");
+ return -ENOMEM;
+ }
+
+ cfifo->size = fifo_size;
+ kfifo_init(&cfifo->fifo, cfifo->vaddr, fifo_size);
+
+ /* TODO: sgl num can be changed if required */
+ cfifo->sgl_num = 1;
+
+ INIT_LIST_HEAD(&cfifo->ctxld_list);
+ init_waitqueue_head(&cfifo->cqueue);
+ init_completion(&cfifo->complete);
+
+ return 0;
+}
+
+static void ctxld_fifo_free(struct device *dev,
+ struct ctxld_fifo *cfifo)
+{
+ if (!cfifo)
+ return;
+
+ /* TODO: wait fifo flush empty */
+
+ kfifo_reset(&cfifo->fifo);
+
+ dma_free_coherent(dev, cfifo->size,
+ cfifo->vaddr,
+ cfifo->dma_handle);
+
+ cfifo->size = 0;
+ cfifo->vaddr = NULL;
+ cfifo->dma_handle = 0;
+
+ memset(cfifo->sgl, 0x0, sizeof(*cfifo->sgl));
+ cfifo->sgl_num = 0;
+}
+
+static int dcss_clks_get(struct dcss_info *info)
+{
+ int ret = 0;
+ struct platform_device *pdev = info->pdev;
+
+ info->clk_axi = devm_clk_get(&pdev->dev, "axi");
+ if (IS_ERR(info->clk_axi)) {
+ ret = PTR_ERR(info->clk_axi);
+ goto out;
+ }
+
+ info->clk_apb = devm_clk_get(&pdev->dev, "apb");
+ if (IS_ERR(info->clk_apb)) {
+ ret = PTR_ERR(info->clk_apb);
+ goto put_axi;
+ }
+
+ info->clk_rtram = devm_clk_get(&pdev->dev, "rtram");
+ if (IS_ERR(info->clk_rtram)) {
+ ret = PTR_ERR(info->clk_rtram);
+ goto put_apb;
+ }
+
+ info->clk_dtrc = devm_clk_get(&pdev->dev, "dtrc");
+ if (IS_ERR(info->clk_dtrc)) {
+ ret = PTR_ERR(info->clk_dtrc);
+ goto put_rtram;
+ }
+
+ info->clk_pix = devm_clk_get(&pdev->dev, "pix");
+ if (IS_ERR(info->clk_pix)) {
+ ret = PTR_ERR(info->clk_pix);
+ goto put_dtrc;
+ }
+
+ goto out;
+
+put_dtrc:
+ devm_clk_put(&pdev->dev, info->clk_dtrc);
+put_rtram:
+ devm_clk_put(&pdev->dev, info->clk_rtram);
+put_apb:
+ devm_clk_put(&pdev->dev, info->clk_apb);
+put_axi:
+ devm_clk_put(&pdev->dev, info->clk_axi);
+out:
+ return ret;
+}
+
+#if 0
+static void dcss_clks_put(struct dcss_info *info)
+{
+ struct platform_device *pdev = info->pdev;
+
+ devm_clk_put(&pdev->dev, info->clk_axi);
+ devm_clk_put(&pdev->dev, info->clk_apb);
+ devm_clk_put(&pdev->dev, info->clk_rtram);
+ devm_clk_put(&pdev->dev, info->clk_dtrc);
+ devm_clk_put(&pdev->dev, info->clk_pix);
+}
+#endif
+
+static void fb_var_to_pixmap(struct dcss_pixmap *pixmap,
+ struct fb_var_screeninfo *var)
+{
+ BUG_ON(!pixmap || !var);
+
+ pixmap->width = var->xres;
+ pixmap->height = var->yres;
+ pixmap->bits_per_pixel = var->bits_per_pixel;
+ pixmap->pitch = var->width * (var->bits_per_pixel >> 3);
+ pixmap->crop.ulc_x = 0;
+ pixmap->crop.ulc_y = 0;
+ pixmap->crop.lrc_x = var->xres;
+ pixmap->crop.lrc_y = var->yres;
+ pixmap->format = var->grayscale;
+
+ /* TODO possible passed through 'reserved' ? */
+ pixmap->tile_type = TILE_TYPE_LINEAR;
+ pixmap->pixel_store = PIXEL_STORE_NONCOMPRESS;
+}
+
+static int fill_one_chan_info(uint32_t chan_id,
+ struct dcss_channel_info *info)
+{
+ void *dsb; /* mem to store ctxld units */
+ struct cbuffer *cb;
+ struct platform_device *pdev;
+
+ BUG_ON(!info || IS_ERR(info));
+ pdev = info->pdev;
+
+ if (chan_id > 2) {
+ dev_err(&pdev->dev, "incorrect channel number: %d\n", chan_id);
+ return -EINVAL;
+ }
+
+ info->channel_id = chan_id;
+ info->channel_en = (chan_id == 0) ? 1 : 0;
+ info->blank = FB_BLANK_NORMAL;
+ info->update_stamp = ~0x0UL;
+
+ switch (chan_id) {
+ case 0:
+ info->hdr10_in_addr = HDR_CHAN1_START;
+ info->decomp_addr = DEC400D_CHAN1_START;
+ info->dpr_addr = DPR_CHAN1_START;
+ info->scaler_addr = SCALER_CHAN1_START;
+ break;
+ case 1:
+ info->hdr10_in_addr = HDR_CHAN2_START;
+ info->decomp_addr = DTRC_CHAN2_START;
+ info->dpr_addr = DPR_CHAN2_START;
+ info->scaler_addr = SCALER_CHAN2_START;
+ break;
+ case 2:
+ info->hdr10_in_addr = HDR_CHAN3_START;
+ info->decomp_addr = DTRC_CHAN3_START;
+ info->dpr_addr = DPR_CHAN3_START;
+ info->scaler_addr = SCALER_CHAN3_START;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ /* dsb is used to hold double & single buffer units */
+ dsb = devm_kzalloc(&pdev->dev, DCSS_REGS_SIZE << 1, GFP_KERNEL);
+ if (!dsb)
+ return -ENOMEM;
+
+ /* init cbuffer struct */
+ cb = &info->cb;
+ cb->esize = sizeof(struct ctxld_unit);
+
+ cb->sb_addr = dsb;
+ cb->sb_len = DCSS_REGS_SIZE / cb->esize;
+ cb->sb_data_len = 0x0;
+
+ cb->db_addr = dsb + DCSS_REGS_SIZE;
+ cb->db_len = DCSS_REGS_SIZE / cb->esize;
+ cb->db_data_len = 0x0;
+
+ return 0;
+}
+
+/* allocate fb info for one channel */
+static int alloc_one_fbinfo(struct dcss_channel_info *cinfo)
+{
+ struct platform_device *pdev;
+
+ BUG_ON(!cinfo || IS_ERR(cinfo));
+
+ pdev = cinfo->pdev;
+ if (!pdev)
+ return -ENODEV;
+
+ cinfo->fb_info = framebuffer_alloc(0, &pdev->dev);
+ if (!cinfo->fb_info) {
+ dev_err(&pdev->dev, "failed to alloc fb info for channel %d\n",
+ cinfo->channel_id);
+ return -ENOMEM;
+ }
+
+ cinfo->fb_info->par = cinfo;
+ INIT_LIST_HEAD(&cinfo->fb_info->modelist);
+
+ return 0;
+}
+
+static struct fb_info *get_one_fbinfo(uint32_t ch_id,
+ struct dcss_channels *chans)
+{
+ struct dcss_channel_info *cinfo;
+
+ if (ch_id > 2)
+ return NULL;
+
+ cinfo = &chans->chan_info[ch_id];
+
+ return cinfo->fb_info;
+}
+
+static int init_chan_pixmap(struct dcss_channel_info *cinfo)
+{
+ struct dcss_pixmap *pixmap;
+ struct fb_info *fbi;
+ struct fb_var_screeninfo *var;
+
+ BUG_ON(!cinfo || IS_ERR(cinfo));
+
+ pixmap = &cinfo->input;
+ fbi = cinfo->fb_info;
+ var = &fbi->var;
+
+ fb_var_to_pixmap(pixmap, var);
+
+ return 0;
+}
+
+static int init_ch_pos(struct dcss_channel_info *cinfo)
+{
+ struct rectangle *pos;
+ struct fb_info *fbi;
+ struct fb_var_screeninfo *var;
+
+ /* TODO: init ch_pos with var temporarily */
+ pos = &cinfo->ch_pos;
+ fbi = cinfo->fb_info;
+ var = &fbi->var;
+
+ pos->ulc_x = var->left_margin + var->hsync_len - 1;
+ pos->ulc_y = var->upper_margin + var->lower_margin +
+ var->vsync_len - 1;
+ pos->lrc_x = var->xres + var->left_margin +
+ var->hsync_len - 1;
+ pos->lrc_y = var->yres + var->upper_margin +
+ var->lower_margin + var->vsync_len - 1;
+
+ return 0;
+}
+
+static int dcss_init_chans(struct dcss_info *info)
+{
+ struct dcss_channels *dcss_chans = &info->chans;
+
+ /* init sharable info between chans */
+ dcss_chans->hdr10_out_addr = HDR_OUT_START;
+ dcss_chans->subsam_addr = SUBSAM_START;
+ dcss_chans->dtg_addr = DTG_START;
+ dcss_chans->wrscl_addr = WR_SCL_START;
+ dcss_chans->rdsrc_addr = RD_SRC_START;
+ dcss_chans->ctxld_addr = CTX_LD_START;
+ dcss_chans->lutld_addr = LUT_LD_START;
+ dcss_chans->hdmi_phy_addr = 0;
+ dcss_chans->irq_steer_addr = IRQ_STEER_START;
+ dcss_chans->lpcg_addr = LPCG_START;
+ dcss_chans->blk_ctrl_addr = BLK_CTRL_START;
+
+ return 0;
+}
+
+static int dcss_init_fbinfo(struct fb_info *fbi)
+{
+ int ret;
+ uint32_t luma_size;
+ struct dcss_channel_info *cinfo = fbi->par;
+ struct dcss_info *info = cinfo->dev_data;
+ struct fb_fix_screeninfo *fix = &fbi->fix;
+ struct fb_var_screeninfo *var = &fbi->var;
+ struct fb_modelist *modelist;
+
+ fbi->fbops = &dcss_ops;
+
+ /* init fix screeninfo */
+ fix->type = FB_TYPE_PACKED_PIXELS;
+ fix->ypanstep = 1;
+ fix->ywrapstep = 1;
+ fix->visual = FB_VISUAL_TRUECOLOR;
+ fix->accel = FB_ACCEL_NONE;
+
+ ret = fb_add_videomode(info->dft_disp_mode, &fbi->modelist);
+ if (ret)
+ return ret;
+
+ /* init var screeninfo */
+ modelist = list_first_entry(&fbi->modelist,
+ struct fb_modelist, list);
+ fb_videomode_to_var(var, &modelist->mode);
+ var->nonstd = 0;
+ var->activate = FB_ACTIVATE_NOW;
+ var->vmode = FB_VMODE_NONINTERLACED;
+ /* default format */
+ if (cinfo->channel_id == DCSS_CHAN_MAIN)
+ /* main channel is for graphic */
+ var->grayscale = V4L2_PIX_FMT_ARGB32;
+ else
+ /* other channels are for video */
+ var->grayscale = V4L2_PIX_FMT_NV12;
+
+ /* Allocate memory buffer: Maybe need alignment */
+ fix->smem_len = (fix->line_length * var->yres_virtual > SZ_32M) ?
+ fix->line_length * var->yres_virtual : SZ_32M;
+ fbi->screen_base = dma_alloc_writecombine(fbi->device, fix->smem_len,
+ (dma_addr_t *)&fix->smem_start,
+ GFP_DMA | GFP_KERNEL);
+ if (!fbi->screen_base) {
+ dev_err(fbi->device, "Unable to alloc fb memory\n");
+ fix->smem_len = 0;
+ fix->smem_start = 0;
+ return -ENOMEM;
+ }
+ dev_dbg(fbi->device, "%s: smem_start = 0x%lx, screen_base = 0x%p\n",
+ __func__, fix->smem_start, fbi->screen_base);
+
+ fbi->screen_size = fix->smem_len;
+
+ fbi->pseudo_palette = devm_kzalloc(fbi->device,
+ sizeof(u32) * 16, GFP_KERNEL);
+ if (!fbi->pseudo_palette) {
+ dev_err(fbi->device, "alloc pseudo_palette failed\n");
+ dcss_free_fbmem(fbi);
+ return -ENOMEM;
+ }
+
+ /* clear screen content to black */
+ switch (var->grayscale) {
+ case V4L2_PIX_FMT_ARGB32:
+ memset((void*)fbi->screen_base, 0x0, fix->smem_len);
+ break;
+ case V4L2_PIX_FMT_NV12:
+ /* set luma: 0x0 */
+ luma_size = var->xres * var->yres;
+ memset((void*)fbi->screen_base, 0x0, luma_size);
+ /* set chroma: 0x80 */
+ memset((void*)fbi->screen_base + luma_size, 0x80, luma_size);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ if (dcss_check_var(var, fbi)) {
+ devm_kfree(fbi->device, fbi->pseudo_palette);
+ dcss_free_fbmem(fbi);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static void dcss_free_fbmem(struct fb_info *fbi)
+{
+ struct fb_fix_screeninfo *fix = &fbi->fix;
+
+ dma_free_writecombine(fbi->device, fix->smem_len,
+ fbi->screen_base,
+ (dma_addr_t)fix->smem_start);
+
+ fbi->screen_base = NULL;
+ fix->smem_start = 0;
+ fix->smem_len = 0;
+}
+
+static int dcss_clks_enable(struct dcss_info *info)
+{
+ int ret = 0;
+ struct platform_device *pdev = info->pdev;
+
+ /* TODO: Add return value check */
+ ret = clk_prepare_enable(info->clk_axi);
+ if (ret) {
+ dev_err(&pdev->dev, "enable axi clock failed\n");
+ return ret;
+ }
+
+ ret = clk_prepare_enable(info->clk_apb);
+ if (ret) {
+ dev_err(&pdev->dev, "enable apb clock failed\n");
+ goto disable_axi;
+ }
+
+ ret = clk_prepare_enable(info->clk_rtram);
+ if (ret) {
+ dev_err(&pdev->dev, "enable rtram clock failed\n");
+ goto disable_apb;
+ }
+
+ ret = clk_prepare_enable(info->clk_dtrc);
+ if (ret) {
+ dev_err(&pdev->dev, "enable dtrc clock failed\n");
+ goto disable_rtram;
+ }
+
+ ret = clk_prepare_enable(info->clk_pix);
+ if (ret) {
+ dev_err(&pdev->dev, "enable pix clock failed\n");
+ goto disable_dtrc;
+ }
+
+ goto out;
+
+disable_dtrc:
+ clk_disable_unprepare(info->clk_dtrc);
+disable_rtram:
+ clk_disable_unprepare(info->clk_rtram);
+disable_apb:
+ clk_disable_unprepare(info->clk_apb);
+disable_axi:
+ clk_disable_unprepare(info->clk_axi);
+out:
+ return ret;
+}
+
+#if 0
+static void dcss_clks_disable(struct dcss_info *info)
+{
+ clk_disable_unprepare(info->clk_axi);
+ clk_disable_unprepare(info->clk_apb);
+ clk_disable_unprepare(info->clk_rtram);
+ clk_disable_unprepare(info->clk_dtrc);
+ clk_disable_unprepare(info->clk_pix);
+}
+#endif
+
+static int dcss_clks_rate_set(struct dcss_info *info)
+{
+ int ret;
+ uint32_t pix_clk_rate;
+ struct platform_device *pdev = info->pdev;
+
+ /* TODO: axi, abp, rtrm clock rate are set by uboot already */
+ ret = clk_set_rate(info->clk_axi, DISP_AXI_RATE);
+ if (ret) {
+ dev_err(&pdev->dev, "set axi clock rate failed\n");
+ return ret;
+ }
+
+ ret = clk_set_rate(info->clk_apb, DISP_APB_RATE);
+ if (ret) {
+ dev_err(&pdev->dev, "set apb clock rate failed\n");
+ return ret;
+ }
+
+ ret = clk_set_rate(info->clk_rtram, DISP_RTRAM_RATE);
+ if (ret) {
+ dev_err(&pdev->dev, "set rtram clock rate failed\n");
+ return ret;
+ }
+
+ pix_clk_rate = PICOS2KHZ(info->dft_disp_mode->pixclock) * 1000U;
+ dev_dbg(&pdev->dev, "%s: pix clock rate = %u\n", __func__, pix_clk_rate);
+
+ ret = clk_set_rate(info->clk_pix, pix_clk_rate);
+ if (ret) {
+ dev_err(&pdev->dev, "set pixel clock rate failed, ret = %d\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int dcss_dtrc_config(uint32_t dtrc_ch,
+ struct dcss_info *info,
+ bool decompress,
+ bool resolve)
+{
+ struct platform_device *pdev = info->pdev;
+ struct dcss_channel_info *chan_info;
+ struct cbuffer *cb;
+
+ if (dtrc_ch != 1 && dtrc_ch != 2) {
+ dev_err(&pdev->dev, "invalid dtrc channel number\n");
+ return -EINVAL;
+ }
+
+ chan_info = &info->chans.chan_info[dtrc_ch];
+ cb = &chan_info->cb;
+
+ if (!decompress && !resolve) {
+#if USE_CTXLD
+ /* Bypass DTRC */
+ fill_sb(cb, chan_info->decomp_addr + 0xc8, 0x2);
+#else
+ writel(0x2, info->base + chan_info->decomp_addr + 0xc8);
+#endif
+ } else {
+ /* TODO: decompress & resolve config */
+ ;
+ }
+
+ return 0;
+}
+
+static int dcss_decomp_config(uint32_t decomp_ch, struct dcss_info *info)
+{
+ bool need_decomp, need_resolve;
+ struct platform_device *pdev = info->pdev;
+ struct dcss_channel_info *chan_info;
+ struct dcss_pixmap *input;
+
+ if (decomp_ch > 2) {
+ dev_err(&pdev->dev, "invalid decompression channel number\n");
+ return -EINVAL;
+ }
+
+ chan_info = &info->chans.chan_info[decomp_ch];
+ input = &chan_info->input;
+
+ switch (input->pixel_store) {
+ case PIXEL_STORE_NONCOMPRESS:
+ need_decomp = false;
+ break;
+ case PIXEL_STORE_COMPRESS:
+ need_decomp = true;
+ break;
+ default:
+ dev_err(&pdev->dev, "invalid pixel store type\n");
+ return -EINVAL;
+ }
+
+ switch (input->tile_type) {
+ case TILE_TYPE_LINEAR:
+ case TILE_TYPE_GPU_STANDARD:
+ case TILE_TYPE_GPU_SUPER:
+ need_resolve = false;
+ break;
+ case TILE_TYPE_VPU_2PYUV420:
+ case TILE_TYPE_VPU_2PVP9:
+ need_resolve = true;
+ break;
+ default:
+ dev_err(&pdev->dev, "invalid buffer tile type\n");
+ return -EINVAL;
+ }
+
+ switch (decomp_ch) {
+ case 0: /* DEC400D */
+ break;
+ case 1: /* DTRC1 */
+ case 2: /* DTRC2 */
+ dcss_dtrc_config(decomp_ch, info,
+ need_decomp, need_resolve);
+ break;
+ default:
+ dev_err(&pdev->dev, "invalid ch num = %d\n", decomp_ch);
+ break;
+ }
+
+ return 0;
+}
+
+/* for both luma and chroma
+ */
+static int dpr_pix_x_calc(u32 pix_size,
+ u32 width,
+ u32 tile_type)
+{
+ unsigned int num_pix_x_in_64byte;
+ unsigned int pix_x_div_64byte_mod;
+ unsigned int pix_x_offset;
+
+ if (pix_size > 2)
+ return -EINVAL;
+
+ /* 1st calculation step */
+ switch (tile_type) {
+ case TILE_TYPE_LINEAR:
+ /* Divisable by 64 bytes */
+ num_pix_x_in_64byte = 64 / (1 << pix_size);
+ break;
+ /* 4x4 tile or super tile */
+ case TILE_TYPE_GPU_STANDARD:
+ case TILE_TYPE_GPU_SUPER:
+ BUG_ON(!pix_size);
+ num_pix_x_in_64byte = 64 / (4 * (1 << pix_size));
+ break;
+ /* 8bpp YUV420 8x8 tile */
+ case TILE_TYPE_VPU_2PYUV420:
+ BUG_ON(pix_size);
+ num_pix_x_in_64byte = 64 / (8 * (1 << pix_size));
+ break;
+ /* 8bpp or 10bpp VP9 4x4 tile */
+ case TILE_TYPE_VPU_2PVP9:
+ BUG_ON(pix_size == 2);
+ num_pix_x_in_64byte = 64 / (4 * (1 << pix_size));
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ /* 2nd calculation step */
+ pix_x_div_64byte_mod = width % num_pix_x_in_64byte;
+ pix_x_offset = !pix_x_div_64byte_mod ? 0 :
+ (num_pix_x_in_64byte - pix_x_div_64byte_mod);
+
+ return width + pix_x_offset;
+}
+
+/* Divisable by 4 or 8 */
+static int dpr_pix_y_calc(u32 rtr_lines,
+ u32 height,
+ u32 tile_type)
+{
+ unsigned int num_rows_buf;
+ unsigned int pix_y_mod = 0;
+ unsigned int pix_y_offset = 0;
+
+ if (rtr_lines != 0 && rtr_lines != 1)
+ return -EINVAL;
+
+ switch (tile_type) {
+ case TILE_TYPE_LINEAR:
+ num_rows_buf = rtr_lines ? 4 : 8;
+ break;
+ /* 4x4 tile or super tile */
+ case TILE_TYPE_GPU_STANDARD:
+ case TILE_TYPE_GPU_SUPER:
+ num_rows_buf = 4;
+ break;
+ /* 8bpp YUV420 8x8 tile */
+ case TILE_TYPE_VPU_2PYUV420:
+ num_rows_buf = 8;
+ break;
+ /* 8bpp or 10bpp VP9 4x4 tile */
+ case TILE_TYPE_VPU_2PVP9:
+ num_rows_buf = 4;
+ break;
+ default:
+ return -EINVAL;
+ }
+ pix_y_mod = height % num_rows_buf;
+ pix_y_offset = !pix_y_mod ? 0 : (num_rows_buf - pix_y_mod);
+
+ return height + pix_y_offset;
+}
+
+static int dcss_dpr_config(uint32_t dpr_ch, struct dcss_info *info)
+{
+ uint32_t pitch, pix_size;
+ uint32_t num_pix_x, num_pix_y;
+ bool need_resolve = false;
+ struct platform_device *pdev = info->pdev;
+ struct dcss_channels *chans = &info->chans;
+ struct dcss_channel_info *chan_info;
+ struct fb_info *fbi;
+ struct fb_fix_screeninfo *fix;
+ struct fb_var_screeninfo *var;
+ struct dcss_pixmap *input;
+ struct cbuffer *cb;
+
+ if (dpr_ch > 2) {
+ dev_err(&pdev->dev, "invalid dpr channel number\n");
+ return -EINVAL;
+ }
+
+ chan_info = &chans->chan_info[dpr_ch];
+ fbi = chan_info->fb_info;
+ fix = &fbi->fix;
+ var = &fbi->var;
+ input = &chan_info->input;
+
+ if (dpr_ch == 0) {
+ switch (input->tile_type) {
+ case TILE_TYPE_LINEAR:
+ need_resolve = false;
+ break;
+ case TILE_TYPE_GPU_STANDARD:
+ case TILE_TYPE_GPU_SUPER:
+ need_resolve = true;
+ break;
+ default:
+ return -EINVAL;
+ }
+ }
+ /* For channel 2,3, 'Tile Resolve' will be done by DTRC */
+
+#if !USE_CTXLD
+ writel(fix->smem_start, info->base + chan_info->dpr_addr + 0xc0);
+ writel(0x2, info->base + chan_info->dpr_addr + 0x90);
+ writel(var->xres, info->base + chan_info->dpr_addr + 0xa0);
+ writel(var->yres, info->base + chan_info->dpr_addr + 0xb0);
+
+ /* TODO: second plane config for YUV2P formats */
+ writel(fix->smem_start + var->xres * var->yres,
+ info->base + chan_info->dpr_addr + 0x110);
+ writel(var->xres, info->base + chan_info->dpr_addr + 0xf0);
+ writel(var->yres, info->base + chan_info->dpr_addr + 0x100);
+
+ /* TODO: calculate pitch for different formats */
+ pitch = (var->xres * (var->bits_per_pixel >> 3)) << 16;
+ writel(pitch, info->base + chan_info->dpr_addr + 0x70);
+
+ if (!need_resolve) {
+ /* Bypass resolve */
+ writel(0xe4203, info->base + chan_info->dpr_addr + 0x50);
+ } else {
+ /* configure resolve */
+ ;
+ }
+
+ writel(0x38, info->base + chan_info->dpr_addr + 0x200);
+ writel(0x4, info->base + chan_info->dpr_addr + 0x0);
+
+ /* Trigger DPR on */
+ writel(0x4, info->base + chan_info->dpr_addr + 0x0);
+ writel(0x5, info->base + chan_info->dpr_addr + 0x0);
+#else
+ cb = &chan_info->cb;
+
+ fill_sb(cb, chan_info->dpr_addr + 0xc0, fix->smem_start);
+ fill_sb(cb, chan_info->dpr_addr + 0x90, 0x2);
+
+ pix_size = ilog2(input->bits_per_pixel >> 3);
+
+ num_pix_x = dpr_pix_x_calc(pix_size, input->width, input->tile_type);
+ fill_sb(cb, chan_info->dpr_addr + 0xa0, num_pix_x);
+
+ switch (fmt_is_yuv(input->format)) {
+ case 0: /* RGB */
+ num_pix_y = dpr_pix_y_calc(1, input->height, input->tile_type);
+ fill_sb(cb, chan_info->dpr_addr + 0xb0, num_pix_y);
+
+ if (!need_resolve)
+ /* Bypass resolve */
+ fill_sb(cb, chan_info->dpr_addr + 0x50, 0xe4203);
+ else {
+ /* TODO: configure resolve */
+ ;
+ }
+ pitch = var->xres * (var->bits_per_pixel >> 3);
+ break;
+ case 1: /* TODO: YUV 1P */
+ return -EINVAL;
+ case 2: /* YUV 2P */
+ /* Two planes YUV format */
+ num_pix_y = dpr_pix_y_calc(0, input->height, input->tile_type);
+ fill_sb(cb, chan_info->dpr_addr + 0xb0, num_pix_y);
+
+ fill_sb(cb, chan_info->dpr_addr + 0x50, 0xc1);
+ fill_sb(cb, chan_info->dpr_addr + 0xe0, 0x2);
+
+ /* TODO: VPU always has 16bytes alignment in width */
+ pitch = ALIGN(var->xres * (var->bits_per_pixel >> 3), 16);
+ fill_sb(cb, chan_info->dpr_addr + 0x110,
+ fix->smem_start + pitch * var->yres);
+ fill_sb(cb, chan_info->dpr_addr + 0xf0, num_pix_x);
+
+ /* TODO: Require alignment handling:
+ * value must be evenly divisible by
+ * the number of rows programmed in
+ * MODE_CTRL0: RTR_4LINE_BUF_EN.
+ * UV height is 1/2 height of Luma.
+ */
+ num_pix_y = dpr_pix_y_calc(0, input->height >> 1, input->tile_type);
+ fill_sb(cb, chan_info->dpr_addr + 0x100, num_pix_y);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ /* TODO: calculate pitch for different formats */
+ /* config pitch */
+ fill_sb(cb, chan_info->dpr_addr + 0x70, pitch << 16);
+
+ fill_sb(cb, chan_info->dpr_addr + 0x200, 0x38);
+
+ /* Trigger DPR on */
+ fill_sb(cb, chan_info->dpr_addr + 0x0, 0x5);
+#endif
+
+ return 0;
+}
+
+static int dcss_scaler_config(uint32_t scaler_ch, struct dcss_info *info)
+{
+ struct platform_device *pdev = info->pdev;
+ struct dcss_channels *chans = &info->chans;
+ struct dcss_channel_info *chan_info;
+ struct fb_info *fbi;
+ struct fb_var_screeninfo *var;
+ struct dcss_pixmap *input;
+ struct cbuffer *cb;
+ int scale_v_luma_inc, scale_h_luma_inc;
+ uint32_t align_width, align_height;
+ const struct fb_videomode *dmode = info->dft_disp_mode;
+
+ if (scaler_ch > 2) {
+ dev_err(&pdev->dev, "invalid scaler channel number\n");
+ return -EINVAL;
+ }
+
+ chan_info = &chans->chan_info[scaler_ch];
+ fbi = chan_info->fb_info;
+ var = &fbi->var;
+ input = &chan_info->input;
+#if !USE_CTXLD
+ writel(0x0, info->base + chan_info->scaler_addr + 0x8);
+ writel(0x0, info->base + chan_info->scaler_addr + 0xc);
+ writel(0x2, info->base + chan_info->scaler_addr + 0x10); /* src format */
+ writel(0x2, info->base + chan_info->scaler_addr + 0x14); /* dst format */
+
+ writel((var->xres - 1) | (var->yres - 1) << 16,
+ info->base + chan_info->scaler_addr + 0x18); /* src resolution */
+ writel((var->xres - 1) | (var->yres - 1) << 16,
+ info->base + chan_info->scaler_addr + 0x1c);
+ writel((var->xres - 1) | (var->yres - 1) << 16,
+ info->base + chan_info->scaler_addr + 0x20); /* dst resolution */
+ writel((var->xres - 1) | (var->yres - 1) << 16,
+ info->base + chan_info->scaler_addr + 0x24);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x28);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x2c);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x30);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x34);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x38);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x3c);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x40);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x44);
+
+ /* scale ratio: ###.#_####_####_#### */
+ writel(0x0, info->base + chan_info->scaler_addr + 0x48);
+ writel(0x2000, info->base + chan_info->scaler_addr + 0x4c);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x50);
+ writel(0x2000, info->base + chan_info->scaler_addr + 0x54);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x58);
+ writel(0x2000, info->base + chan_info->scaler_addr + 0x5c);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x60);
+ writel(0x2000, info->base + chan_info->scaler_addr + 0x64);
+
+ writel(0x0, info->base + chan_info->scaler_addr + 0x80);
+
+ writel(0x40000, info->base + chan_info->scaler_addr + 0xc0);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x100);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x84);
+ writel(0x0, info->base + chan_info->scaler_addr + 0xc4);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x104);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x88);
+ writel(0x0, info->base + chan_info->scaler_addr + 0xc8);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x108);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x8c);
+ writel(0x0, info->base + chan_info->scaler_addr + 0xcc);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x10c);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x90);
+ writel(0x0, info->base + chan_info->scaler_addr + 0xd0);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x110);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x94);
+ writel(0x0, info->base + chan_info->scaler_addr + 0xd4);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x114);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x98);
+ writel(0x0, info->base + chan_info->scaler_addr + 0xd8);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x118);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x9c);
+ writel(0x0, info->base + chan_info->scaler_addr + 0xdc);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x11c);
+ writel(0x0, info->base + chan_info->scaler_addr + 0xa0);
+ writel(0x0, info->base + chan_info->scaler_addr + 0xe0);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x120);
+ writel(0x0, info->base + chan_info->scaler_addr + 0xa4);
+ writel(0x0, info->base + chan_info->scaler_addr + 0xe4);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x124);
+ writel(0x0, info->base + chan_info->scaler_addr + 0xa8);
+ writel(0x0, info->base + chan_info->scaler_addr + 0xe8);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x128);
+ writel(0x0, info->base + chan_info->scaler_addr + 0xac);
+ writel(0x0, info->base + chan_info->scaler_addr + 0xec);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x12c);
+ writel(0x0, info->base + chan_info->scaler_addr + 0xb0);
+ writel(0x0, info->base + chan_info->scaler_addr + 0xf0);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x130);
+ writel(0x0, info->base + chan_info->scaler_addr + 0xb4);
+ writel(0x0, info->base + chan_info->scaler_addr + 0xf4);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x134);
+ writel(0x0, info->base + chan_info->scaler_addr + 0xb8);
+ writel(0x0, info->base + chan_info->scaler_addr + 0xf8);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x138);
+ writel(0x0, info->base + chan_info->scaler_addr + 0xbc);
+ writel(0x0, info->base + chan_info->scaler_addr + 0xfc);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x13c);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x140);
+
+ writel(0x40000, info->base + chan_info->scaler_addr + 0x180);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x1c0);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x144);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x184);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x1c4);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x148);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x188);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x1c8);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x14c);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x18c);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x1cc);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x150);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x190);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x1d0);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x154);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x194);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x1d4);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x158);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x198);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x1d8);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x15c);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x19c);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x1dc);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x160);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x1a0);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x1e0);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x164);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x1a4);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x1e4);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x168);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x1a8);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x1e8);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x16c);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x1ac);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x1ec);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x170);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x1b0);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x1f0);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x174);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x1b4);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x1f4);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x178);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x1b8);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x1f8);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x17c);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x1bc);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x1fc);
+
+ writel(0x0, info->base + chan_info->scaler_addr + 0x300);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x340);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x380);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x304);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x344);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x384);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x308);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x348);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x388);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x30c);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x34c);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x38c);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x310);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x350);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x390);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x314);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x354);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x394);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x318);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x358);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x398);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x31c);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x35c);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x39c);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x320);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x360);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x3a0);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x324);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x364);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x3a4);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x328);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x368);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x3a8);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x32c);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x36c);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x3ac);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x330);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x370);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x3b0);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x334);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x374);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x3b4);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x338);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x378);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x3b8);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x33c);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x37c);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x3bc);
+
+ writel(0x0, info->base + chan_info->scaler_addr + 0x200);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x240);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x280);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x204);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x244);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x284);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x208);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x248);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x288);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x20c);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x24c);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x28c);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x210);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x250);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x290);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x214);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x254);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x294);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x218);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x258);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x298);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x21c);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x25c);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x29c);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x220);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x260);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x2a0);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x224);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x264);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x2a4);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x228);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x268);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x2a8);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x22c);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x26c);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x2ac);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x230);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x270);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x2b0);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x234);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x274);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x2b4);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x238);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x278);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x2b8);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x23c);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x27c);
+ writel(0x0, info->base + chan_info->scaler_addr + 0x2bc);
+
+ /* Trigger Scaler on */
+ writel(0x11, info->base + chan_info->scaler_addr + 0x0);
+#else
+ cb = &chan_info->cb;
+
+ switch (fmt_is_yuv(input->format)) {
+ case 0: /* ARGB8888 */
+ fill_sb(cb, chan_info->scaler_addr + 0x8, 0x0);
+ /* Scaler Input Format */
+ fill_sb(cb, chan_info->scaler_addr + 0x10, 0x2);
+ break;
+ case 1: /* TODO: YUV422 or YUV444 */
+ break;
+ case 2: /* YUV420 */
+ fill_sb(cb, chan_info->scaler_addr + 0x8, 0x3);
+ /* Scaler Input Format */
+ fill_sb(cb, chan_info->scaler_addr + 0x10, 0x0);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ /* Chroma and Luma bit depth */
+ fill_sb(cb, chan_info->scaler_addr + 0xc, 0x0);
+
+ /* Scaler Output Format
+ * TODO: set dst fmt always to RGB888/YUV444
+ */
+ fill_sb(cb, chan_info->scaler_addr + 0x14, 0x2);
+
+ /* Scaler Input Luma Resolution
+ * Alighment Workaround for YUV420:
+ * 'width' divisable by 16, 'height' divisable by 8.
+ */
+
+ if (fmt_is_yuv(input->format) == 2) {
+ align_width = round_down(input->width, 16);
+ align_height = round_down(input->height, 8);
+ } else {
+ align_width = input->width;
+ align_height = input->height;
+ }
+
+ fill_sb(cb, chan_info->scaler_addr + 0x18,
+ (align_height - 1) << 16 | (align_width - 1));
+
+ /* Scaler Input Chroma Resolution */
+ switch (fmt_is_yuv(input->format)) {
+ case 0: /* ARGB8888 */
+ fill_sb(cb, chan_info->scaler_addr + 0x1c,
+ (align_height - 1) << 16 | (align_width - 1));
+ break;
+ case 1: /* TODO: YUV422 or YUV444 */
+ break;
+ case 2: /* YUV420 */
+ fill_sb(cb, chan_info->scaler_addr + 0x1c,
+ ((align_height >> 1) - 1) << 16 |
+ ((align_width >> 1) - 1));
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ /* Scaler Output Luma Resolution
+ * TODO: It should be scaled result value.
+ */
+ fill_sb(cb, chan_info->scaler_addr + 0x20,
+ (dmode->yres - 1) << 16 | (dmode->xres - 1));
+
+ /* Scaler Output Chroma Resolution
+ * TODO: It should be scaled result value.
+ */
+ fill_sb(cb, chan_info->scaler_addr + 0x24,
+ (dmode->yres - 1) << 16 | (dmode->xres - 1));
+
+ fill_sb(cb, chan_info->scaler_addr + 0x28, 0x0);
+ fill_sb(cb, chan_info->scaler_addr + 0x2c, 0x0);
+ fill_sb(cb, chan_info->scaler_addr + 0x30, 0x0);
+ fill_sb(cb, chan_info->scaler_addr + 0x34, 0x0);
+ fill_sb(cb, chan_info->scaler_addr + 0x38, 0x0);
+ fill_sb(cb, chan_info->scaler_addr + 0x3c, 0x0);
+ fill_sb(cb, chan_info->scaler_addr + 0x40, 0x0);
+ fill_sb(cb, chan_info->scaler_addr + 0x44, 0x0);
+
+ /* scale ratio: ###.#_####_####_#### */
+ /* vertical ratio */
+ scale_v_luma_inc = ((align_height << 13) + (dmode->yres >> 1)) / dmode->yres;
+ /* horizontal ratio */
+ scale_h_luma_inc = ((align_width << 13) + (dmode->xres >> 1)) / dmode->xres;
+
+ fill_sb(cb, chan_info->scaler_addr + 0x48, 0x0);
+ fill_sb(cb, chan_info->scaler_addr + 0x4c, scale_v_luma_inc);
+ fill_sb(cb, chan_info->scaler_addr + 0x50, 0x0);
+ fill_sb(cb, chan_info->scaler_addr + 0x54, scale_h_luma_inc);
+
+ switch (fmt_is_yuv(input->format)) {
+ case 0: /* ARGB8888 */
+ /* Scale Vertical Chroma Start */
+ fill_sb(cb, chan_info->scaler_addr + 0x58, 0x0);
+
+ /* Scale Vertical Chroma Increment */
+ fill_sb(cb, chan_info->scaler_addr + 0x5c, scale_v_luma_inc);
+
+ /* Scale Horizontal Chroma Increment */
+ fill_sb(cb, chan_info->scaler_addr + 0x64, scale_h_luma_inc);
+ break;
+ case 1: /* TODO: YUV422 or YUV444 */
+ break;
+ case 2: /* YUV420 */
+ /* Scale Vertical Chroma Start */
+ fill_sb(cb, chan_info->scaler_addr + 0x58, 0x01fff800);
+
+ /* Scale Vertical Chroma Increment */
+ fill_sb(cb, chan_info->scaler_addr + 0x5c, scale_v_luma_inc >> 1);
+
+ /* Scale Horizontal Chroma Increment */
+ fill_sb(cb, chan_info->scaler_addr + 0x64, scale_h_luma_inc >> 1);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ /* Scale Horizontal Chroma Start */
+ fill_sb(cb, chan_info->scaler_addr + 0x60, 0x0);
+
+ /* Trigger SCALER on */
+ fill_sb(cb, chan_info->scaler_addr + 0x0, 0x11);
+#endif
+ return 0;
+}
+
+static int dcss_dtg_start(struct dcss_info *info)
+{
+ uint32_t dtg_lrc_x, dtg_lrc_y;
+ uint32_t dis_ulc_x, dis_ulc_y;
+ uint32_t dis_lrc_x, dis_lrc_y;
+ struct dcss_channels *chans = &info->chans;
+ struct dcss_channel_info *chan_info;
+ const struct fb_videomode *dmode;
+ struct cbuffer *cb;
+
+ chan_info = &chans->chan_info[0];
+ dmode = info->dft_disp_mode;
+ cb = &chan_info->cb;
+
+ /* Display Timing Config */
+ dtg_lrc_x = dmode->xres + dmode->left_margin +
+ dmode->right_margin + dmode->hsync_len - 1;
+ dtg_lrc_y = dmode->yres + dmode->upper_margin +
+ dmode->lower_margin + dmode->vsync_len - 1;
+ writel(dtg_lrc_y << 16 | dtg_lrc_x, info->base + chans->dtg_addr + 0x4);
+
+ /* global output timing */
+ dis_ulc_x = dmode->left_margin + dmode->hsync_len - 1;
+ dis_ulc_y = dmode->upper_margin + dmode->lower_margin +
+ dmode->vsync_len - 1;
+ writel(dis_ulc_y << 16 | dis_ulc_x, info->base + chans->dtg_addr + 0x8);
+
+ dis_lrc_x = dmode->xres + dmode->left_margin +
+ dmode->hsync_len - 1;
+ dis_lrc_y = dmode->yres + dmode->upper_margin +
+ dmode->lower_margin + dmode->vsync_len - 1;
+ writel(dis_lrc_y << 16 | dis_lrc_x, info->base + chans->dtg_addr + 0xc);
+
+ /* config db and sb loading position of ctxld */
+ writel(0xb000a, info->base + chans->dtg_addr + 0x28);
+
+ /* config background color for graph layer: black */
+ writel(0x0, info->base + chans->dtg_addr + 0x2c);
+
+ /* config background color for video layer: black */
+ writel(0x00080200, info->base + chans->dtg_addr + 0x30);
+
+ /* Trigger DTG on */
+ writel(0xff00518e, info->base + chans->dtg_addr + 0x0);
+
+ info->dcss_state = DCSS_STATE_RUNNING;
+
+ return 0;
+}
+
+static void dtg_channel_timing_config(int blank,
+ struct dcss_channel_info *cinfo)
+{
+ struct cbuffer *cb;
+ uint32_t ch_ulc_reg, ch_lrc_reg;
+ struct fb_info *fbi = cinfo->fb_info;
+ struct rectangle *pos = &cinfo->ch_pos;
+ struct platform_device *pdev = cinfo->pdev;
+ struct dcss_info *info = cinfo->dev_data;
+ struct dcss_channels *chans = &info->chans;
+
+ switch (fbi->node) {
+ case 0:
+ ch_ulc_reg = 0x10;
+ ch_lrc_reg = 0x14;
+ break;
+ case 1:
+ ch_ulc_reg = 0x18;
+ ch_lrc_reg = 0x1c;
+ break;
+ case 2:
+ ch_ulc_reg = 0x20;
+ ch_lrc_reg = 0x24;
+ break;
+ default:
+ dev_err(&pdev->dev, "%s: invalid channel number %d\n",
+ __func__, fbi->node);
+ return;
+ }
+
+ cb = &cinfo->cb;
+
+ switch (blank) {
+ case FB_BLANK_UNBLANK:
+ /* set display window for one channel */
+ fill_sb(cb, chans->dtg_addr + ch_ulc_reg,
+ pos->ulc_y << 16 | pos->ulc_x);
+ fill_sb(cb, chans->dtg_addr + ch_lrc_reg,
+ pos->lrc_y << 16 | pos->lrc_x);
+ break;
+ case FB_BLANK_NORMAL:
+ case FB_BLANK_VSYNC_SUSPEND:
+ case FB_BLANK_HSYNC_SUSPEND:
+ case FB_BLANK_POWERDOWN:
+ fill_sb(cb, chans->dtg_addr + ch_ulc_reg, 0x0);
+ fill_sb(cb, chans->dtg_addr + ch_lrc_reg, 0x0);
+ break;
+ default:
+ return;
+ }
+}
+
+static void dtg_global_timing_config(struct dcss_info *info)
+{
+ struct cbuffer *cb;
+ uint32_t dtg_lrc_x, dtg_lrc_y;
+ uint32_t dis_ulc_x, dis_ulc_y;
+ uint32_t dis_lrc_x, dis_lrc_y;
+ struct dcss_channels *chans = &info->chans;
+ struct dcss_channel_info *cmain;
+ const struct fb_videomode *dmode = info->dft_disp_mode;
+
+ /* only main channel can change dtg timings */
+ cmain = &chans->chan_info[DCSS_CHAN_MAIN];
+ cb = &cmain->cb;
+
+ /* Display Timing config */
+ dtg_lrc_x = dmode->xres + dmode->left_margin +
+ dmode->right_margin + dmode->hsync_len - 1;
+ dtg_lrc_y = dmode->yres + dmode->upper_margin +
+ dmode->lower_margin + dmode->vsync_len - 1;
+ fill_sb(cb, chans->dtg_addr + 0x4, dtg_lrc_y << 16 | dtg_lrc_x);
+
+ /* Active Region Timing config*/
+ dis_ulc_x = dmode->left_margin + dmode->hsync_len - 1;
+ dis_ulc_y = dmode->upper_margin + dmode->lower_margin +
+ dmode->vsync_len - 1;
+ fill_sb(cb, chans->dtg_addr + 0x8, dis_ulc_y << 16 | dis_ulc_x);
+
+ dis_lrc_x = dmode->xres + dmode->left_margin +
+ dmode->hsync_len - 1;
+ dis_lrc_y = dmode->yres + dmode->upper_margin +
+ dmode->lower_margin + dmode->vsync_len - 1;
+ fill_sb(cb, chans->dtg_addr + 0xc, dis_lrc_y << 16 | dis_lrc_x);
+}
+
+static int dcss_dtg_config(uint32_t ch_id, struct dcss_info *info)
+{
+ struct platform_device *pdev = info->pdev;
+ struct dcss_channels *chans = &info->chans;
+ struct dcss_channel_info *cinfo;
+
+ if (ch_id > 2) {
+ dev_err(&pdev->dev, "invalid channel id\n");
+ return -EINVAL;
+ }
+
+ cinfo = &chans->chan_info[ch_id];
+
+ if (ch_id == DCSS_CHAN_MAIN)
+ dtg_global_timing_config(info);
+
+ /* TODO: Channel Timing Config */
+ dtg_channel_timing_config(FB_BLANK_UNBLANK, cinfo);
+
+ return 0;
+}
+
+static int dcss_subsam_config(struct dcss_info *info)
+{
+ uint32_t hsync_pol, vsync_pol, de_pol;
+ uint32_t disp_lrc_x, disp_lrc_y;
+ uint32_t hsync_start, hsync_end;
+ uint32_t vsync_start, vsync_end;
+ uint32_t de_ulc_x, de_ulc_y;
+ uint32_t de_lrc_x, de_lrc_y;
+ struct dcss_channels *chans = &info->chans;
+ struct dcss_channel_info *chan_info;
+ struct cbuffer *cb;
+ const struct fb_videomode *dmode;
+
+ /* using channel 0 by default */
+ chan_info = &chans->chan_info[0];
+ cb = &chan_info->cb;
+ dmode = info->dft_disp_mode;
+
+ /* TODO: for 1080p only */
+ hsync_pol = 1;
+ vsync_pol = 1;
+ de_pol = 1;
+
+#if USE_CTXLD
+ /* 3 tap fir filters coefficients */
+ fill_sb(cb, chans->subsam_addr + 0x70, 0x41614161);
+ fill_sb(cb, chans->subsam_addr + 0x80, 0x03ff0000);
+ fill_sb(cb, chans->subsam_addr + 0x90, 0x03ff0000);
+#else
+ writel(0x41614161, info->base + chans->subsam_addr + 0x70);
+ writel(0x03ff0000, info->base + chans->subsam_addr + 0x80);
+ writel(0x03ff0000, info->base + chans->subsam_addr + 0x90);
+#endif
+
+ /* Timing Config */
+ disp_lrc_x = dmode->xres + dmode->left_margin +
+ dmode->right_margin + dmode->hsync_len - 1;
+ disp_lrc_y = dmode->yres + dmode->upper_margin +
+ dmode->lower_margin + dmode->vsync_len - 1;
+#if USE_CTXLD
+ fill_sb(cb, chans->subsam_addr + 0x10,
+ disp_lrc_y << 16 | disp_lrc_x);
+#else
+ writel(disp_lrc_y << 16 | disp_lrc_x,
+ info->base + chans->subsam_addr + 0x10);
+#endif
+
+ /* horizontal sync will be asserted when
+ * horizontal count == START
+ */
+ hsync_start = dmode->xres + dmode->left_margin +
+ dmode->right_margin + dmode->hsync_len - 1;
+ hsync_end = dmode->hsync_len - 1;
+#if USE_CTXLD
+ fill_sb(cb, chans->subsam_addr + 0x20,
+ (hsync_pol << 31) | hsync_end << 16 | hsync_start);
+#else
+ writel((hsync_pol << 31) | hsync_end << 16 | hsync_start,
+ info->base + chans->subsam_addr + 0x20);
+#endif
+
+ vsync_start = dmode->lower_margin - 1;
+ vsync_end = dmode->lower_margin + dmode->vsync_len - 1;
+#if USE_CTXLD
+ fill_sb(cb, chans->subsam_addr + 0x30,
+ (vsync_pol << 31) | vsync_end << 16 | vsync_start);
+#else
+ writel((vsync_pol << 31) | vsync_end << 16 | vsync_start,
+ info->base + chans->subsam_addr + 0x30);
+#endif
+
+ de_ulc_x = dmode->left_margin + dmode->hsync_len - 1;
+ de_ulc_y = dmode->upper_margin + dmode->lower_margin +
+ dmode->vsync_len;
+#if USE_CTXLD
+ fill_sb(cb, chans->subsam_addr + 0x40,
+ (de_pol << 31) | de_ulc_y << 16 | de_ulc_x);
+#else
+ writel((de_pol << 31) | de_ulc_y << 16 | de_ulc_x,
+ info->base + chans->subsam_addr + 0x40);
+#endif
+
+ de_lrc_x = dmode->xres + dmode->left_margin +
+ dmode->hsync_len - 1;
+ de_lrc_y = dmode->yres + dmode->upper_margin +
+ dmode->lower_margin + dmode->vsync_len - 1;
+#if USE_CTXLD
+ fill_sb(cb, chans->subsam_addr + 0x50,
+ de_lrc_y << 16 | de_lrc_x);
+
+ /* Trigger Subsam on */
+ fill_sb(cb, chans->subsam_addr + 0x0, 0x1);
+#else
+ writel(de_lrc_y << 16 | de_lrc_x,
+ info->base + chans->subsam_addr + 0x50);
+ writel(0x1, info->base + chans->subsam_addr + 0x0);
+#endif
+
+ return 0;
+}
+
+static void ctxld_irq_unmask(uint32_t irq_en, struct dcss_info *info)
+{
+ struct dcss_channels *chans = &info->chans;
+
+ writel(irq_en, info->base + chans->ctxld_addr + CTXLD_CTRL_STATUS_SET);
+}
+
+static void __maybe_unused dtg_irq_mask(unsigned long hwirq,
+ struct dcss_info *info)
+{
+ unsigned long irq_mask = 0;
+ struct dcss_channels *chans = &info->chans;
+
+ irq_mask = readl(info->base + chans->dtg_addr + TC_INTERRUPT_MASK);
+ writel(~(1 << (hwirq - 8)) & irq_mask,
+ info->base + chans->dtg_addr + TC_INTERRUPT_MASK);
+}
+
+static void dtg_irq_unmask(unsigned long hwirq,
+ struct dcss_info *info)
+{
+ unsigned long irq_mask = 0;
+ struct dcss_channels *chans = &info->chans;
+
+ irq_mask = readl(info->base + chans->dtg_addr + TC_INTERRUPT_MASK);
+
+ writel(1 << (hwirq - 8) | irq_mask,
+ info->base + chans->dtg_addr + TC_INTERRUPT_MASK);
+}
+
+static void dtg_irq_clear(unsigned long hwirq,
+ struct dcss_info *info)
+{
+ unsigned long irq_status = 0;
+ struct dcss_channels *chans = &info->chans;
+
+ irq_status = readl(info->base + chans->dtg_addr + TC_INTERRUPT_STATUS);
+ BUG_ON(!(irq_status & 1 << (hwirq - 8)));
+
+ /* write 1 to clear irq */
+ writel(1 << (hwirq - 8),
+ info->base + chans->dtg_addr + TC_INTERRUPT_CONTROL);
+}
+
+static void dcss_ctxld_config(struct work_struct *work)
+{
+ int ret;
+ uint32_t dsb_len, nsgl, esize, offset;
+ struct dcss_info *info;
+ struct platform_device *pdev;
+ struct dcss_channels *chans;
+ struct ctxld_commit *cc;
+ struct ctxld_fifo *cfifo;
+
+ cc = container_of(work, struct ctxld_commit, work);
+ info = (struct dcss_info *)cc->data;
+ pdev = info->pdev;
+ chans = &info->chans;
+ cfifo = &info->cfifo;
+ dsb_len = cc->sb_data_len + cc->db_data_len;
+ esize = kfifo_esize(&cfifo->fifo);
+
+ /* NOOP cc */
+ if (!cc->sb_data_len && !cc->db_data_len)
+ goto free_cc;
+
+ sg_init_table(cfifo->sgl, cfifo->sgl_num);
+ nsgl = kfifo_dma_out_prepare(&cfifo->fifo, cfifo->sgl,
+ cfifo->sgl_num, dsb_len);
+ BUG_ON(!nsgl);
+
+ if (nsgl == 1) {
+ if (cfifo->sgl[0].length != dsb_len * esize)
+ BUG_ON(1);
+ }
+
+ offset = cfifo->fifo.kfifo.out & cfifo->fifo.kfifo.mask;
+
+ /* configure sb buffer */
+ if (cc->sb_data_len) {
+ /* cfifo first store sb and than store db */
+ writel(cfifo->dma_handle + offset * esize,
+ info->base + chans->ctxld_addr + CTXLD_SB_BASE_ADDR);
+ writel(cc->sb_hp_data_len |
+ ((cc->sb_data_len - cc->sb_hp_data_len) << 16),
+ info->base + chans->ctxld_addr + CTXLD_SB_COUNT);
+ }
+
+ /* configure db buffer */
+ if (cc->db_data_len) {
+ writel(cfifo->dma_handle + (offset + cc->sb_data_len) * esize,
+ info->base + chans->ctxld_addr + CTXLD_DB_BASE_ADDR);
+ writel(cc->db_data_len,
+ info->base + chans->ctxld_addr + CTXLD_DB_COUNT);
+ }
+
+ /* enable ctx_ld */
+ writel(0x1, info->base + chans->ctxld_addr + CTXLD_CTRL_STATUS_SET);
+
+ /* wait finish */
+ reinit_completion(&cfifo->complete);
+ ret = wait_for_completion_timeout(&cfifo->complete, HZ);
+ if (!ret) /* timeout */
+ dev_err(&pdev->dev, "wait ctxld finish timeout\n");
+
+ ctxld_fifo_info_print(cfifo);
+ kfifo_dma_out_finish(&cfifo->fifo,
+ (cc->sb_data_len + cc->db_data_len) * esize);
+ ctxld_fifo_info_print(cfifo);
+
+free_cc:
+ kfree(cc);
+
+ dev_dbg(&pdev->dev, "finish ctxld config\n");
+}
+
+static void copy_data_to_cfifo(struct ctxld_fifo *cfifo,
+ struct cbuffer *cb,
+ struct ctxld_commit *cc)
+{
+ struct ctxld_unit *unit;
+ uint32_t count;
+
+ unit = (struct ctxld_unit *)cb->sb_addr;
+
+ if (cb->sb_data_len) {
+ count = kfifo_in(&cfifo->fifo, cb->sb_addr, cb->sb_data_len);
+ if (count != cb->sb_data_len) {
+ /* TODO: this case should be completely ignored */
+ pr_err("write sb data mismatch\n");
+ count = kfifo_out(&cfifo->fifo, cb->sb_addr, count);
+ WARN_ON(1);
+ }
+ cc->sb_hp_data_len += count;
+ cc->sb_data_len += count;
+ }
+
+ if (cb->db_data_len) {
+ count = kfifo_in(&cfifo->fifo, cb->db_addr, cb->db_data_len);
+ if (count != cb->db_data_len) {
+ /* TODO: this case should be completely ignored */
+ pr_err("write db data mismatch\n");
+ count = kfifo_out(&cfifo->fifo, cb->db_addr, count);
+ WARN_ON(1);
+ }
+ cc->db_data_len += count;
+ }
+}
+
+static struct ctxld_commit *alloc_cc(struct dcss_info *info)
+{
+ struct ctxld_commit *cc;
+
+ cc = kzalloc(sizeof(*cc), GFP_KERNEL);
+ if (!cc)
+ return ERR_PTR(-ENOMEM);
+
+ INIT_LIST_HEAD(&cc->list);
+ INIT_WORK(&cc->work, dcss_ctxld_config);
+ kref_init(&cc->refcount);
+ cc->data = info;
+
+ return cc;
+}
+
+static struct ctxld_commit *obtain_cc(int ch_id, struct dcss_info *info)
+{
+ int ret;
+ unsigned long irqflags;
+ struct dcss_channel_info *cinfo;
+ struct ctxld_commit *cc = NULL;
+ struct platform_device *pdev = info->pdev;
+ struct dcss_channels *chans = &info->chans;
+ struct ctxld_fifo *cfifo = &info->cfifo;
+ struct vsync_info *vinfo = &info->vinfo;
+
+ cinfo = &chans->chan_info[ch_id];
+
+ /* wait for next frame window */
+ ret = wait_event_interruptible_timeout(vinfo->vwait,
+ vcount_compare(cinfo->update_stamp, vinfo),
+ HZ);
+ if (!ret) {
+ dev_err(&pdev->dev, "wait next frame timeout\n");
+ return ERR_PTR(-EBUSY);
+ }
+
+ spin_lock_irqsave(&vinfo->vwait.lock, irqflags);
+
+ cinfo->update_stamp = vinfo->vcount;
+ if (!list_empty(&cfifo->ctxld_list)) {
+ cc = list_first_entry(&cfifo->ctxld_list,
+ struct ctxld_commit,
+ list);
+ kref_get(&cc->refcount);
+ }
+
+ spin_unlock_irqrestore(&vinfo->vwait.lock, irqflags);
+
+ if (!cc) {
+ cc = alloc_cc(info);
+ if (IS_ERR(cc))
+ return cc;
+
+ spin_lock_irqsave(&vinfo->vwait.lock, irqflags);
+
+ if (list_empty(&cfifo->ctxld_list))
+ list_add_tail(&cfifo->ctxld_list, &cc->list);
+ else {
+ kfree(cc);
+ cc = list_first_entry(&cfifo->ctxld_list,
+ struct ctxld_commit,
+ list);
+ }
+ kref_get(&cc->refcount);
+
+ spin_unlock_irqrestore(&vinfo->vwait.lock, irqflags);
+ }
+
+ return cc;
+}
+
+static void release_cc(struct kref *kref)
+{
+ unsigned long irqflags;
+ struct ctxld_commit *cc;
+ struct dcss_info *info;
+ struct vsync_info *vinfo;
+ struct ctxld_fifo *cfifo;
+
+ cc = container_of(kref, struct ctxld_commit, refcount);
+ info = (struct dcss_info *)cc->data;
+ vinfo = &info->vinfo;
+ cfifo = &info->cfifo;
+
+ spin_lock_irqsave(&vinfo->vwait.lock, irqflags);
+
+ list_del(&cc->list);
+ flush_cfifo(cfifo, &cc->work);
+
+ spin_unlock_irqrestore(&vinfo->vwait.lock, irqflags);
+}
+
+/**
+ * Only be called when 'vwait.lock' is hold
+ */
+static void release_cc_locked(struct kref *kref)
+{
+ struct ctxld_commit *cc;
+ struct dcss_info *info;
+ struct ctxld_fifo *cfifo;
+
+ cc = container_of(kref, struct ctxld_commit, refcount);
+ info = (struct dcss_info *)cc->data;
+ cfifo = &info->cfifo;
+
+ list_del(&cc->list);
+ flush_cfifo(cfifo, &cc->work);
+}
+
+static void flush_cfifo(struct ctxld_fifo *cfifo,
+ struct work_struct *work)
+{
+ int ret;
+
+ ret = queue_work(cfifo->ctxld_wq, work);
+
+ WARN(!ret, "work has already been queued\n");
+}
+
+static int defer_flush_cfifo(struct ctxld_fifo *cfifo)
+{
+ int i;
+ struct dcss_info *info;
+ struct dcss_channels *chans;
+ struct dcss_channel_info *cinfo;
+
+ info = container_of(cfifo, struct dcss_info, cfifo);
+ chans = &info->chans;
+
+ for (i = 0; i < 3; i++) {
+ cinfo = &chans->chan_info[i];
+ cinfo->update_stamp = info->vinfo.vcount;
+ }
+
+ return 0;
+}
+
+static int finish_cfifo(struct ctxld_fifo *cfifo)
+{
+ int ret;
+ struct dcss_info *info;
+
+ info = container_of(cfifo, struct dcss_info, cfifo);
+
+ ret = dcss_wait_for_vsync(0, info);
+ if (ret)
+ return ret;
+
+ flush_workqueue(cfifo->ctxld_wq);
+
+ return 0;
+}
+
+static int commit_cfifo(uint32_t channel,
+ struct dcss_info *info,
+ struct ctxld_commit *cc)
+{
+ uint32_t commit_size;
+ struct dcss_channels *chans;
+ struct dcss_channel_info *chan_info;
+ struct ctxld_fifo *cfifo;
+ struct cbuffer *cb;
+
+ cfifo = &info->cfifo;
+ chans = &info->chans;
+ chan_info = &chans->chan_info[channel];
+ cb = &chan_info->cb;
+ commit_size = cb->sb_data_len + cb->db_data_len;
+
+ spin_lock(&cfifo->cqueue.lock);
+
+ if (unlikely(atomic_read(&info->flush) == 1)) {
+ /* cancel this commit and restart it later */
+ kref_put(&cc->refcount, release_cc);
+
+ wait_event_interruptible_exclusive_locked(cfifo->cqueue,
+ atomic_read(&info->flush));
+
+ spin_unlock(&cfifo->cqueue.lock);
+ return -ERESTARTSYS;
+ } else {
+ if (unlikely(waitqueue_active(&cfifo->cqueue)))
+ wake_up_locked(&cfifo->cqueue);
+ }
+
+ if (unlikely(commit_size > kfifo_to_end_len(&cfifo->fifo))) {
+ atomic_set(&info->flush, 1);
+ spin_unlock(&cfifo->cqueue.lock);
+
+ /* cancel this commit and restart it later */
+ kref_put(&cc->refcount, release_cc);
+
+ /* Wait fifo flush empty to avoid fifo wrap */
+ finish_cfifo(cfifo);
+
+ spin_lock(&cfifo->cqueue.lock);
+
+ atomic_set(&info->flush, 0);
+ kfifo_reset(&cfifo->fifo);
+ if (waitqueue_active(&cfifo->cqueue))
+ wake_up_locked(&cfifo->cqueue);
+
+ spin_unlock(&cfifo->cqueue.lock);
+
+ return -ERESTART;
+ }
+
+ copy_data_to_cfifo(cfifo, cb, cc);
+
+ ctxld_fifo_info_print(cfifo);
+
+ /* empty sb and db buffer */
+ cb->db_data_len = 0;
+ cb->sb_data_len = 0;
+
+ spin_unlock(&cfifo->cqueue.lock);
+
+ return 0;
+}
+
+static int dcss_open(struct fb_info *fbi, int user)
+{
+ int fb_node = fbi->node;
+ struct dcss_channel_info *cinfo = fbi->par;
+ struct dcss_info *info = cinfo->dev_data;
+ struct dcss_channels *chans = &info->chans;
+ struct dcss_channel_info *chan_info;
+ struct cbuffer *cb;
+
+ if (fb_node < 0 || fb_node > 2)
+ BUG_ON(1);
+
+ chan_info = &chans->chan_info[fb_node];
+ cb = &chan_info->cb;
+
+ if (fb_node == 0)
+ return 0;
+
+ return 0;
+}
+
+static int dcss_check_var(struct fb_var_screeninfo *var,
+ struct fb_info *fbi)
+{
+ uint32_t fb_size;
+ uint32_t scale_ratio_mode_x, scale_ratio_mode_y;
+ uint32_t scale_ratio_x, scale_ratio_y;
+ struct dcss_channel_info *cinfo = fbi->par;
+ struct dcss_info *info = cinfo->dev_data;
+ struct platform_device *pdev = info->pdev;
+ const struct fb_bitfield *rgb = NULL;
+ const struct pix_fmt_info *format = NULL;
+ struct fb_fix_screeninfo *fix = &fbi->fix;
+ const struct fb_videomode *dmode = info->dft_disp_mode;
+
+ if (var->xres > MAX_WIDTH || var->yres > MAX_HEIGHT) {
+ dev_err(&pdev->dev, "unsupport display resolution\n");
+ return -EINVAL;
+ }
+
+ if (var->xres_virtual > var->xres) {
+ dev_err(&pdev->dev, "stride not supported\n");
+ return -EINVAL;
+ }
+
+ if (var->xres_virtual < var->xres)
+ var->xres_virtual = var->xres;
+ if (var->yres_virtual < var->yres)
+ var->yres_virtual = var->yres;
+
+ switch (var->grayscale) {
+ case 0: /* TODO: color */
+ case 1: /* grayscale */
+ return -EINVAL;
+ default: /* fourcc */
+ format = get_fmt_info(var->grayscale);
+ if (!format) {
+ dev_err(&pdev->dev, "unsupport pixel format\n");
+ return -EINVAL;
+ }
+ var->bits_per_pixel = format->bpp;
+ }
+
+ /* Add alignment check for scaler */
+ switch (fmt_is_yuv(var->grayscale)) {
+ case 0: /* ARGB8888 */
+ case 2: /* YUV420 */
+ if (ALIGN(var->xres, 4) != var->xres ||
+ ALIGN(var->yres, 4) != var->yres) {
+ dev_err(&pdev->dev, "width or height is not aligned\n");
+ return -EINVAL;
+ }
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ /* Add scale ratio check:
+ * Maximum scale down ratio is 1/7;
+ * Maximum scale up ratio is 8;
+ */
+ if (dmode->xres > var->xres) {
+ /* upscaling */
+ scale_ratio_mode_x = dmode->xres % var->xres;
+ scale_ratio_mode_y = dmode->yres % var->yres;
+ scale_ratio_x = (dmode->xres - scale_ratio_mode_x) / var->xres;
+ scale_ratio_y = (dmode->yres - scale_ratio_mode_y) / var->yres;
+ if (scale_ratio_x >= 8) {
+ if ((scale_ratio_x == 8 && scale_ratio_mode_x > 0) ||
+ (scale_ratio_x > 8)) {
+ dev_err(&pdev->dev, "unsupport scaling ration for width\n");
+ return -EINVAL;
+ }
+ }
+
+ if (scale_ratio_y >= 8) {
+ if ((scale_ratio_y == 8 && scale_ratio_mode_y > 0) ||
+ (scale_ratio_y > 8)) {
+ dev_err(&pdev->dev, "unsupport scaling ration for height\n");
+ return -EINVAL;
+ }
+ }
+ } else {
+ /* downscaling */
+ scale_ratio_mode_x = var->xres % dmode->xres;
+ scale_ratio_mode_y = var->yres % dmode->yres;
+ scale_ratio_x = (var->xres - scale_ratio_mode_x) / dmode->xres;
+ scale_ratio_y = (var->yres - scale_ratio_mode_y) / dmode->yres;
+ if (scale_ratio_x >= 7) {
+ if ((scale_ratio_x == 7 && scale_ratio_mode_x > 0) ||
+ (scale_ratio_x > 7)) {
+ dev_err(&pdev->dev, "unsupport scaling ration for width\n");
+ return -EINVAL;
+ }
+ }
+
+ if (scale_ratio_y >= 7) {
+ if ((scale_ratio_y == 7 && scale_ratio_mode_y > 0) ||
+ (scale_ratio_y > 7)) {
+ dev_err(&pdev->dev, "unsupport scaling ration for height\n");
+ return -EINVAL;
+ }
+ }
+ }
+
+ fix->line_length = var->xres * (var->bits_per_pixel >> 3);
+ fb_size = var->yres_virtual * fix->line_length;
+
+ if (fb_size > fix->smem_len) {
+ dev_err(&pdev->dev, "exceeds fb size limit!\n");
+ return -ENOMEM;
+ }
+
+ if (format && !format->is_yuv) {
+ switch (format->fourcc) {
+ case V4L2_PIX_FMT_ARGB32:
+ rgb = def_a8r8g8b8;
+ break;
+ case V4L2_PIX_FMT_A2R10G10B10:
+ rgb = def_a2r10g10b10;
+ break;
+ default:
+ dev_err(&pdev->dev, "unsupport pixel format\n");
+ return -EINVAL;
+ }
+
+ var->red = rgb[RED];
+ var->green = rgb[GREEN];
+ var->blue = rgb[BLUE];
+ var->transp = rgb[TRANSP];
+ } else {
+ /* TODO: YUV format */
+ ;
+ }
+
+ return 0;
+}
+
+static int config_channel_pipe(struct dcss_channel_info *cinfo)
+{
+ int ret = 0;
+ int fb_node;
+ struct fb_info *fbi = cinfo->fb_info;
+ struct dcss_info *info = cinfo->dev_data;
+ struct platform_device *pdev = info->pdev;
+
+ fb_node = fbi->node;
+
+ dev_dbg(&cinfo->pdev->dev, "begin config pipe %d\n", fb_node);
+
+ /* configure all the sub modules on one channel:
+ * 1. DEC400D/DTRC
+ * 2. DPR
+ * 3. SCALER
+ * 4. HDR10_INPUT
+ */
+ ret = dcss_decomp_config(fb_node, info);
+ if (ret) {
+ dev_err(&pdev->dev, "decomp config failed\n");
+ goto out;
+ }
+
+ ret = dcss_dpr_config(fb_node, info);
+ if (ret) {
+ dev_err(&pdev->dev, "dpr config failed\n");
+ goto out;
+ }
+
+ ret = dcss_scaler_config(fb_node, info);
+ if (ret) {
+ dev_err(&pdev->dev, "scaler config failed\n");
+ goto out;
+ }
+
+out:
+ return ret;
+}
+
+static int dcss_set_par(struct fb_info *fbi)
+{
+ int ret = 0;
+ int fb_node = fbi->node;
+ struct dcss_channel_info *cinfo = fbi->par;
+ struct dcss_info *info = cinfo->dev_data;
+ struct cbuffer *cb = &cinfo->cb;
+ struct ctxld_commit *cc;
+
+ if (fb_node < 0 || fb_node > 2)
+ BUG_ON(1);
+
+ /* TODO: add save/recovery when config failed */
+ fb_var_to_pixmap(&cinfo->input, &fbi->var);
+
+ ret = config_channel_pipe(cinfo);
+ if (ret)
+ goto fail;
+
+ ret = dcss_dtg_config(fb_node, info);
+ if (ret)
+ goto fail;
+
+#if USE_CTXLD
+restart:
+ cc = obtain_cc(fb_node, info);
+ if (IS_ERR(cc)) {
+ ret = PTR_ERR(cc);
+ goto fail;
+ }
+
+ ret = commit_cfifo(fb_node, info, cc);
+ if (ret == -ERESTART)
+ goto restart;
+
+ kref_put(&cc->refcount, release_cc);
+#endif
+
+ goto out;
+
+fail:
+ /* drop any ctxld_uint already
+ * been written to sb or db
+ */
+ cb->sb_data_len = 0;
+ cb->db_data_len = 0;
+out:
+ return ret;
+}
+
+static int dcss_setcolreg(unsigned regno, unsigned red, unsigned green,
+ unsigned blue, unsigned transp, struct fb_info *info)
+{
+ return 0;
+}
+
+static int dcss_channel_blank(int blank,
+ struct dcss_channel_info *cinfo)
+{
+ uint32_t dtg_ctrl;
+ struct dcss_info *info = cinfo->dev_data;
+ struct dcss_channels *chans = &info->chans;
+ struct cbuffer *cb = &cinfo->cb;
+
+ dtg_ctrl = readl(info->base + chans->dtg_addr + 0x0);
+
+ switch (blank) {
+ case FB_BLANK_UNBLANK:
+ /* set global alpha */
+ if (cinfo->channel_id == DCSS_CHAN_MAIN)
+ dtg_ctrl |= (0xff << 24);
+ else
+ dtg_ctrl &= ~(0xff << 24);
+ break;
+ case FB_BLANK_NORMAL:
+ case FB_BLANK_VSYNC_SUSPEND:
+ case FB_BLANK_HSYNC_SUSPEND:
+ case FB_BLANK_POWERDOWN:
+ /* clear global alpha */
+ if (cinfo->channel_id == DCSS_CHAN_MAIN)
+ dtg_ctrl &= ~(0xff << 24);
+ else
+ dtg_ctrl |= (0xff << 24);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ fill_sb(cb, chans->dtg_addr + 0x0, dtg_ctrl);
+
+ return 0;
+}
+
+static int dcss_blank(int blank, struct fb_info *fbi)
+{
+ int ret = 0;
+ int fb_node = fbi->node;
+ struct dcss_channel_info *cinfo = fbi->par;
+ struct dcss_info *info = cinfo->dev_data;
+ struct cbuffer *cb;
+ struct ctxld_commit *cc;
+
+ cb = &cinfo->cb;
+
+ dtg_channel_timing_config(blank, cinfo);
+ dcss_channel_blank(blank, cinfo);
+
+#if USE_CTXLD
+restart:
+ cc = obtain_cc(fb_node, info);
+ if (IS_ERR(cc)) {
+ ret = PTR_ERR(cc);
+ goto fail;
+ }
+
+ ret = commit_cfifo(fb_node, info, cc);
+ if (ret == -ERESTART)
+ goto restart;
+
+ kref_put(&cc->refcount, release_cc);
+#endif
+
+ cinfo->blank = blank;
+
+ goto out;
+
+fail:
+ /* drop any ctxld_uint already
+ * been written to sb or db
+ */
+ cb->sb_data_len = 0;
+ cb->db_data_len = 0;
+
+out:
+ return ret;
+}
+
+static int dcss_pan_display(struct fb_var_screeninfo *var,
+ struct fb_info *fbi)
+{
+ int ret = 0;
+ int fb_node = fbi->node;
+ uint32_t offset, pitch, luma_addr, chroma_addr = 0;
+ struct dcss_channel_info *cinfo = fbi->par;
+ struct dcss_info *info = cinfo->dev_data;
+ struct platform_device *pdev = info->pdev;
+ struct cbuffer *cb = &cinfo->cb;
+ struct dcss_pixmap *input = &cinfo->input;
+ struct ctxld_commit *cc;
+
+ /* TODO: change framebuffer memory start address */
+ luma_addr = var->reserved[0] ? var->reserved[0] :
+ fbi->fix.smem_start;
+
+ /* change display offset in framebuffer */
+ if (var->xoffset > 0) {
+ dev_dbg(&pdev->dev, "x panning not supported\n");
+ return -EINVAL;
+ }
+
+ if ((var->yoffset + var->yres > var->yres_virtual)) {
+ dev_err(&pdev->dev, "y panning exceeds\n");
+ return -EINVAL;
+ }
+
+ offset = fbi->fix.line_length * var->yoffset;
+
+ fill_sb(cb, cinfo->dpr_addr + 0xc0, luma_addr + offset);
+
+ /* Two planes YUV format */
+ if (fmt_is_yuv(input->format) == 2) {
+ pitch = ALIGN(var->xres * (var->bits_per_pixel >> 3), 16);
+ chroma_addr = luma_addr + pitch * var->yres;
+ fill_sb(cb,
+ cinfo->dpr_addr + 0x110,
+ chroma_addr + (offset >> 1));
+ }
+
+#if USE_CTXLD
+restart:
+ cc = obtain_cc(fb_node, info);
+ if (IS_ERR(cc)) {
+ ret = PTR_ERR(cc);
+ goto fail;
+ }
+
+ ret = commit_cfifo(fb_node, info, cc);
+ if (ret == -ERESTART)
+ goto restart;
+
+ kref_put(&cc->refcount, release_cc);
+#endif
+
+ goto out;
+
+fail:
+ /* drop any ctxld_uint already
+ * been written to sb or db
+ */
+ cb->sb_data_len = 0;
+ cb->db_data_len = 0;
+
+out:
+ return ret;
+}
+
+static int vcount_compare(unsigned long vcount,
+ struct vsync_info *vinfo)
+{
+ int ret = 0;
+ unsigned long irqflags;
+
+ spin_lock_irqsave(&vinfo->vwait.lock, irqflags);
+
+ ret = (vcount != vinfo->vcount) ? 1 : 0;
+
+ spin_unlock_irqrestore(&vinfo->vwait.lock, irqflags);
+
+ return ret;
+}
+
+static int dcss_wait_for_vsync(unsigned long crtc,
+ struct dcss_info *info)
+{
+ int ret = 0;
+ unsigned long irqflags, vcount;
+ struct platform_device *pdev = info->pdev;
+
+ spin_lock_irqsave(&info->vinfo.vwait.lock, irqflags);
+ vcount = info->vinfo.vcount;
+ spin_unlock_irqrestore(&info->vinfo.vwait.lock, irqflags);
+
+ ret = wait_event_interruptible_timeout(info->vinfo.vwait,
+ vcount_compare(vcount, &info->vinfo),
+ HZ);
+ if (!ret) {
+ dev_err(&pdev->dev, "wait vsync active timeout\n");
+ return -EBUSY;
+ }
+
+ return 0;
+}
+
+static int dcss_ioctl(struct fb_info *fbi, unsigned int cmd,
+ unsigned long arg)
+{
+ int ret = 0;
+ unsigned long crtc;
+ void __user *argp = (void __user *)arg;
+ struct dcss_channel_info *cinfo = fbi->par;
+ struct dcss_info *info = cinfo->dev_data;
+ struct platform_device *pdev = cinfo->pdev;
+
+ switch (cmd) {
+ case FBIO_WAITFORVSYNC:
+ if (copy_from_user(&crtc, argp, sizeof(unsigned long)))
+ return -EFAULT;
+
+ ret = dcss_wait_for_vsync(crtc, info);
+ break;
+ default:
+ dev_err(&pdev->dev, "invalid ioctl command: 0x%x\n", cmd);
+ ret = -EINVAL;
+ break;
+ }
+
+ return ret;
+}
+
+static void ctxld_irq_clear(struct dcss_info *info)
+{
+ uint32_t irq_status;
+ struct dcss_channels *chans = &info->chans;
+ struct platform_device *pdev = info->pdev;
+
+ irq_status = readl(info->base + chans->ctxld_addr + CTXLD_CTRL_STATUS);
+ dev_dbg(&pdev->dev, "ctxld irq_status before = 0x%x\n", irq_status);
+
+ if (irq_status & RD_ERR)
+ writel(RD_ERR, info->base + chans->ctxld_addr + CTXLD_CTRL_STATUS_CLR);
+
+ if (irq_status & DB_COMP)
+ writel(DB_COMP, info->base + chans->ctxld_addr + CTXLD_CTRL_STATUS_CLR);
+
+ if (irq_status & SB_HP_COMP)
+ writel(SB_HP_COMP,
+ info->base + chans->ctxld_addr + CTXLD_CTRL_STATUS_CLR);
+
+ if (irq_status & SB_LP_COMP)
+ writel(SB_LP_COMP,
+ info->base + chans->ctxld_addr + CTXLD_CTRL_STATUS_CLR);
+
+ if (irq_status & AHB_ERR)
+ writel(AHB_ERR,
+ info->base + chans->ctxld_addr + CTXLD_CTRL_STATUS_CLR);
+
+ irq_status = readl(info->base + chans->ctxld_addr + CTXLD_CTRL_STATUS);
+}
+
+static irqreturn_t dcss_irq_handler(int irq, void *dev_id)
+{
+ int ret;
+ struct irq_desc *desc;
+ uint32_t irq_status;
+ unsigned long irqflags;
+ struct dcss_info *info = (struct dcss_info *)dev_id;
+ struct dcss_channels *chans = &info->chans;
+ struct dcss_channel_info *chan;
+ struct ctxld_fifo *cfifo;
+ struct ctxld_commit *cc;
+
+ cfifo = &info->cfifo;
+ desc = irq_to_desc(irq);
+
+ switch (desc->irq_data.hwirq) {
+ case IRQ_DPR_CH1:
+ chan = &chans->chan_info[0];
+ irq_status = readl(info->base + chan->dpr_addr + 0x40);
+ writel(irq_status, info->base + chan->dpr_addr + 0x40);
+ break;
+ case IRQ_DPR_CH2:
+ break;
+ case IRQ_DPR_CH3:
+ break;
+ case IRQ_CTX_LD:
+ ctxld_irq_clear(info);
+ complete(&cfifo->complete);
+ break;
+ case IRQ_TC_LINE1:
+ dtg_irq_clear(IRQ_TC_LINE1, info);
+
+ spin_lock_irqsave(&info->vinfo.vwait.lock, irqflags);
+
+ /* unblock new commits */
+ info->vinfo.vcount++;
+
+ if (!list_empty(&cfifo->ctxld_list)) {
+ cc = list_first_entry(&cfifo->ctxld_list,
+ struct ctxld_commit,
+ list);
+
+ ret = kref_put(&cc->refcount, release_cc_locked);
+
+ /* 'cc' can not be released */
+ if (!ret)
+ defer_flush_cfifo(cfifo);
+ }
+
+ spin_unlock_irqrestore(&info->vinfo.vwait.lock, irqflags);
+
+ wake_up_all(&info->vinfo.vwait);
+ break;
+ case IRQ_DEC400D_CH1:
+ case IRQ_DTRC_CH2:
+ case IRQ_DTRC_CH3:
+ break;
+ }
+
+ return IRQ_HANDLED;
+}
+
+static int dcss_interrupts_init(struct dcss_info *info)
+{
+ int i, ret = 0;
+ struct irq_desc *desc;
+ struct dcss_channels *chans = &info->chans;
+ struct platform_device *pdev = info->pdev;
+
+ for (i = 0; i < DCSS_IRQS_NUM; i++) {
+ info->irqs[i] = platform_get_irq(pdev, i);
+ if (info->irqs[i] < 0)
+ break;
+
+ desc = irq_to_desc(info->irqs[i]);
+ switch (desc->irq_data.hwirq) {
+ case 6: /* CTX_LD */
+ ctxld_irq_unmask(SB_HP_COMP_EN, info);
+ break;
+ case 8: /* dtg_programmable_1: for vsync */
+ /* TODO: (0, 0) or (last, last)? */
+ writel(0x0, info->base + chans->dtg_addr + TC_LINE1_INT);
+ dtg_irq_unmask(IRQ_TC_LINE1, info);
+ break;
+ default: /* TODO: add support later */
+ continue;
+ }
+
+ ret = devm_request_irq(&pdev->dev, info->irqs[i],
+ dcss_irq_handler, 0,
+ dev_name(&pdev->dev), info);
+ if (ret) {
+ dev_err(&pdev->dev, "request_irq (%d) failed with error %d\n",
+ info->irqs[i], ret);
+ return ret;
+ }
+ }
+
+ if (i == 0)
+ return -ENXIO;
+
+ info->irqs_num = i + 1;
+
+ return 0;
+}
+
+static void __iomem *dev_iomem_init(struct platform_device *pdev,
+ unsigned int res_idx)
+{
+ struct resource *res;
+
+ if (res_idx > IORESOURCE_MEM_NUM)
+ return NULL;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, res_idx);
+ if (!res)
+ return ERR_PTR(-ENODEV);
+
+ return devm_ioremap_resource(&pdev->dev, res);
+}
+
+static int dcss_dispdrv_init(struct platform_device *pdev,
+ struct fb_info *fbi)
+{
+ struct dcss_channel_info *cinfo = fbi->par;
+ struct dcss_info *info = cinfo->dev_data;
+ struct mxc_dispdrv_setting setting;
+ char disp_dev[NAME_LEN];
+
+ memset(&setting, 0x0, sizeof(setting));
+ setting.fbi = fbi;
+ memcpy(disp_dev, info->disp_dev, strlen(info->disp_dev));
+ disp_dev[strlen(info->disp_dev)] = '\0';
+
+ info->dispdrv = mxc_dispdrv_gethandle(disp_dev, &setting);
+ if (IS_ERR(info->dispdrv)) {
+ dev_info(&pdev->dev, "no encoder driver exists\n");
+ return -EPROBE_DEFER;
+ }
+
+ dev_info(&pdev->dev, "%s encoder registered success\n", disp_dev);
+
+ return 0;
+}
+
+static int dcss_register_one_ch(uint32_t ch_id,
+ struct dcss_info *info)
+{
+ int ret = 0;
+ struct dcss_channels *chans;
+ struct dcss_channel_info *cinfo;
+
+ BUG_ON(ch_id > 2);
+
+ chans = &info->chans;
+ cinfo = &chans->chan_info[ch_id];
+
+ cinfo->pdev = info->pdev;
+ cinfo->dev_data = (void *)info;
+
+ ret = fill_one_chan_info(ch_id, cinfo);
+ if (ret) {
+ dev_err(&info->pdev->dev, "register channel %d failed\n", ch_id);
+ return ret;
+ }
+
+ return ret;
+}
+
+static int dcss_register_one_fb(struct dcss_channel_info *cinfo)
+{
+ int ret = 0;
+ struct fb_info *fbi;
+
+ ret = alloc_one_fbinfo(cinfo);
+ if (ret) {
+ dev_err(&cinfo->pdev->dev,
+ "register fb %d failed\n", cinfo->channel_id);
+ goto out;
+ }
+
+ fbi = cinfo->fb_info;
+ ret = dcss_init_fbinfo(fbi);
+ if (ret)
+ goto out;
+
+ init_chan_pixmap(cinfo);
+ init_ch_pos(cinfo);
+
+ if (cinfo->channel_id == 0) {
+ ret = dcss_dispdrv_init(cinfo->pdev, fbi);
+ if (ret == -EPROBE_DEFER) {
+ dev_info(&cinfo->pdev->dev,
+ "Defer fb probe for encoder unready\n");
+ goto out;
+ }
+ }
+
+ ret = register_framebuffer(fbi);
+ if (ret) {
+ dev_err(&cinfo->pdev->dev, "failed to register fb%d\n",
+ cinfo->channel_id);
+ goto out;
+ }
+
+out:
+ return ret;
+}
+
+static int read_dcss_properties(struct dcss_info *info)
+{
+ int ret = 0;
+ uint32_t disp_mode;
+ const char *disp_dev;
+ struct platform_device *pdev = info->pdev;
+ struct device_node *np = pdev->dev.of_node;
+
+ /* read disp-mode */
+ ret = of_property_read_u32(np, "disp-mode", &disp_mode);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "invalid disp-mode provided in dtb\n");
+ return -EINVAL;
+ }
+
+ info->dft_disp_mode = &imx_cea_mode[disp_mode];
+ if (!info->dft_disp_mode->xres)
+ return -EINVAL;
+
+ /* read disp-dev */
+ ret = of_property_read_string(np, "disp-dev", &disp_dev);
+ if (!ret) {
+ memcpy(info->disp_dev, disp_dev, strlen(disp_dev));
+ dev_info(&pdev->dev, "%s: disp_dev = %s\n", __func__,
+ info->disp_dev);
+ }
+
+ return 0;
+}
+
+static int dcss_info_init(struct dcss_info *info)
+{
+ int ret = 0;
+ struct platform_device *pdev = info->pdev;
+
+ spin_lock_init(&info->llock);
+
+ info->dcss_state = DCSS_STATE_RESET;
+
+ ret = read_dcss_properties(info);
+ if (ret)
+ return -ENODEV;
+
+ ret = dcss_init_chans(info);
+
+ info->base = dev_iomem_init(pdev, 0);
+ if (IS_ERR(info->base)) {
+ ret = PTR_ERR(info->base);
+ goto out;
+ }
+
+ info->blkctl_base = dev_iomem_init(pdev, 1);
+ if (IS_ERR(info->blkctl_base)) {
+ ret = PTR_ERR(info->blkctl_base);
+ goto out;
+ }
+
+ ret = dcss_clks_get(info);
+ if (ret)
+ goto out;
+
+ ret = dcss_clks_rate_set(info);
+ if (ret)
+ goto out;
+
+ ret = dcss_clks_enable(info);
+ if (ret)
+ goto out;
+
+ /* alloc ctxld fifo */
+ ret = ctxld_fifo_alloc(&pdev->dev, &info->cfifo, DCSS_CFIFO_SIZE);
+ if (ret) {
+ dev_err(&pdev->dev, "ctxld fifo alloc failed\n");
+ goto out;
+ }
+
+ info->cfifo.ctxld_wq = alloc_ordered_workqueue("ctxld-wq", WQ_FREEZABLE);
+ if (!info->cfifo.ctxld_wq) {
+ dev_err(&pdev->dev, "allocate ctxld wq failed\n");
+ ret = -EINVAL;
+ goto free_cfifo;
+ }
+
+ platform_set_drvdata(pdev, info);
+ init_waitqueue_head(&info->vinfo.vwait);
+ info->vinfo.vcount = 0;
+
+ goto out;
+
+free_cfifo:
+ ctxld_fifo_free(&pdev->dev, &info->cfifo);
+out:
+ return ret;
+}
+
+static int dcss_enable_encoder(struct dcss_info *info)
+{
+ int ret = 0;
+ struct fb_info *main_fbinfo;
+ struct platform_device *pdev;
+
+ if (!info->dispdrv)
+ goto out;
+
+ pdev = info->pdev;
+ main_fbinfo = get_one_fbinfo(0, &info->chans);
+
+ if (info->dispdrv->drv->setup) {
+ ret = info->dispdrv->drv->setup(info->dispdrv, main_fbinfo);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "setup encoder failed: %d\n", ret);
+ goto out;
+ }
+ }
+
+ if (info->dispdrv->drv->enable) {
+ ret = info->dispdrv->drv->enable(info->dispdrv, main_fbinfo);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "enable encoder failed: %d\n", ret);
+ goto out;
+ }
+ }
+
+out:
+ return ret;
+}
+
+static void dcss_fix_data_config(struct dcss_info *info)
+{
+ int i, esize;
+
+ esize = sizeof(struct data_unit);
+
+ /* SCALER COEFFS config */
+ for (i = 0; i < sizeof(scaler_coeffs_ch0) / esize; i++)
+ writel(scaler_coeffs_ch0[i].data,
+ info->base + scaler_coeffs_ch0[i].addr);
+
+ for (i = 0; i < sizeof(scaler_coeffs_ch1) / esize; i++)
+ writel(scaler_coeffs_ch1[i].data,
+ info->base + scaler_coeffs_ch1[i].addr);
+
+ /* HDR10 PIPE1 config */
+ for (i = 0; i < sizeof(hdr10_pipe1_lut_a0) / esize; i++)
+ writel(hdr10_pipe1_lut_a0[i].data,
+ info->base + hdr10_pipe1_lut_a0[i].addr);
+
+ for (i = 0; i < sizeof(hdr10_pipe1_lut_a1) / esize; i++)
+ writel(hdr10_pipe1_lut_a1[i].data,
+ info->base + hdr10_pipe1_lut_a1[i].addr);
+
+ for (i = 0; i < sizeof(hdr10_pipe1_lut_a2) / esize; i++)
+ writel(hdr10_pipe1_lut_a2[i].data,
+ info->base + hdr10_pipe1_lut_a2[i].addr);
+
+ for (i = 0; i < sizeof(hdr10_pipe1_csca) / esize; i++)
+ writel(hdr10_pipe1_csca[i].data,
+ info->base + hdr10_pipe1_csca[i].addr);
+
+ for (i = 0; i < sizeof(hdr10_pipe1_cscb) / esize; i++)
+ writel(hdr10_pipe1_cscb[i].data,
+ info->base + hdr10_pipe1_cscb[i].addr);
+
+ /* HDR10 PIPE2 config */
+ for (i = 0; i < sizeof(hdr10_pipe2_lut_a0) / esize; i++)
+ writel(hdr10_pipe2_lut_a0[i].data,
+ info->base + hdr10_pipe2_lut_a0[i].addr);
+
+ for (i = 0; i < sizeof(hdr10_pipe2_lut_a1) / esize; i++)
+ writel(hdr10_pipe2_lut_a1[i].data,
+ info->base + hdr10_pipe2_lut_a1[i].addr);
+
+ for (i = 0; i < sizeof(hdr10_pipe2_lut_a2) / esize; i++)
+ writel(hdr10_pipe2_lut_a2[i].data,
+ info->base + hdr10_pipe2_lut_a2[i].addr);
+
+ for (i = 0; i < sizeof(hdr10_pipe2_csca) / esize; i++)
+ writel(hdr10_pipe2_csca[i].data,
+ info->base + hdr10_pipe2_csca[i].addr);
+
+ for (i = 0; i < sizeof(hdr10_pipe2_cscb) / esize; i++)
+ writel(hdr10_pipe2_cscb[i].data,
+ info->base + hdr10_pipe2_cscb[i].addr);
+
+ /* HDR10 OPIPE config */
+ for (i = 0; i < sizeof(hdr10_opipe_a0) / esize; i++)
+ writel(hdr10_opipe_a0[i].data,
+ info->base + hdr10_opipe_a0[i].addr);
+
+ for (i = 0; i < sizeof(hdr10_opipe_a1) / esize; i++)
+ writel(hdr10_opipe_a1[i].data,
+ info->base + hdr10_opipe_a1[i].addr);
+
+ for (i = 0; i < sizeof(hdr10_opipe_a2) / esize; i++)
+ writel(hdr10_opipe_a2[i].data,
+ info->base + hdr10_opipe_a2[i].addr);
+
+ for (i = 0; i < sizeof(hdr10_opipe_csco) / esize; i++)
+ writel(hdr10_opipe_csco[i].data,
+ info->base + hdr10_opipe_csco[i].addr);
+}
+
+static int dcss_probe(struct platform_device *pdev)
+{
+ int ret = 0;
+ struct dcss_info *info;
+ struct fb_info *m_fbinfo;
+
+ info = devm_kzalloc(&pdev->dev, sizeof(struct dcss_info), GFP_KERNEL);
+ if (!info)
+ return -ENOMEM;
+ info->pdev = pdev;
+
+ ret = dcss_info_init(info);
+ if (ret)
+ goto kfree_info;
+
+ /* TODO: reset DCSS to make it clean */
+
+ /* Clocks select: before dcss de-resets */
+ if (!strcmp(info->disp_dev, "hdmi_disp"))
+ /* HDMI */
+ writel(0x0, info->blkctl_base + 0x10);
+ else
+ /* MIPI DSI */
+ writel(0x101, info->blkctl_base + 0x10);
+
+ /* Pull DCSS out of resets */
+ writel(0xffffffff, info->blkctl_base + 0x0);
+
+ /* TODO: config fixed data for DCSS */
+ dcss_fix_data_config(info);
+
+ dcss_interrupts_init(info);
+
+ ret = dcss_dtg_start(info);
+ if (ret)
+ goto kfree_info;
+
+ /* register channel 0: graphic */
+ ret = dcss_register_one_ch(0, info);
+ if (ret)
+ goto kfree_info;
+
+ /* register fb 0 */
+ ret = dcss_register_one_fb(&info->chans.chan_info[0]);
+ if (ret)
+ goto unregister_ch0;
+
+ /* enable encoder if exists */
+ dcss_enable_encoder(info);
+
+ ret = dcss_subsam_config(info);
+ if (ret)
+ goto unregister_fb0;
+
+ /* register channel 1: video */
+ ret = dcss_register_one_ch(1, info);
+ if (ret)
+ goto unregister_fb0;
+
+ /* register fb 1 */
+ ret = dcss_register_one_fb(&info->chans.chan_info[1]);
+ if (ret)
+ goto unregister_ch1;
+
+ /* unblank fb0 */
+ m_fbinfo = get_one_fbinfo(0, &info->chans);
+ dcss_blank(FB_BLANK_UNBLANK, m_fbinfo);
+
+ /* init fb1 */
+ dcss_set_par(get_one_fbinfo(1, &info->chans));
+
+ goto out;
+
+unregister_ch1:
+ /* TODO: add later */
+ ;
+unregister_fb0:
+ framebuffer_release(get_one_fbinfo(0, &info->chans));
+unregister_ch0:
+ /* TODO: add later */
+ ;
+kfree_info:
+ devm_kfree(&pdev->dev, info);
+out:
+ return ret;
+}
+
+static int dcss_remove(struct platform_device *pdev)
+{
+ return 0;
+}
+
+static void dcss_shutdown(struct platform_device *pdev)
+{
+}
+
+static struct platform_driver dcss_driver = {
+ .probe = dcss_probe,
+ .remove = dcss_remove,
+ .shutdown = dcss_shutdown,
+ .driver = {
+ .name = "dcss_fb",
+ .of_match_table = dcss_dt_ids,
+ },
+};
+
+module_platform_driver(dcss_driver);
+
+MODULE_DESCRIPTION("NXP DCSS framebuffer driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/video/fbdev/mxc/imx_dcss_table.h b/drivers/video/fbdev/mxc/imx_dcss_table.h
new file mode 100644
index 000000000000..6046a7a73251
--- /dev/null
+++ b/drivers/video/fbdev/mxc/imx_dcss_table.h
@@ -0,0 +1,9761 @@
+/*
+ * Copyright 2017 NXP
+ *
+ * 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
+ *
+ */
+
+/* data unit structure for coeffs */
+struct data_unit {
+ uint32_t addr;
+ uint32_t data;
+};
+
+struct data_unit scaler_coeffs_ch0[] = {
+ { 0x0001c300, 0x00000000 },
+ { 0x0001c304, 0x00000000 },
+ { 0x0001c308, 0x00000000 },
+ { 0x0001c30c, 0x00000000 },
+ { 0x0001c310, 0x00000000 },
+ { 0x0001c314, 0x00000000 },
+ { 0x0001c318, 0x00000000 },
+ { 0x0001c31c, 0x00000000 },
+ { 0x0001c320, 0x00000000 },
+ { 0x0001c324, 0x00000000 },
+ { 0x0001c328, 0x00000000 },
+ { 0x0001c32c, 0x00000000 },
+ { 0x0001c330, 0x00000000 },
+ { 0x0001c334, 0x00000000 },
+ { 0x0001c338, 0x00000000 },
+ { 0x0001c33c, 0x00000000 },
+ { 0x0001c340, 0x00040000 },
+ { 0x0001c344, 0x00040000 },
+ { 0x0001c348, 0x00040000 },
+ { 0x0001c34c, 0x00040000 },
+ { 0x0001c350, 0x00040000 },
+ { 0x0001c354, 0x00040000 },
+ { 0x0001c358, 0x00040000 },
+ { 0x0001c35c, 0x00040000 },
+ { 0x0001c360, 0x00040000 },
+ { 0x0001c364, 0x00040000 },
+ { 0x0001c368, 0x00040000 },
+ { 0x0001c36c, 0x00040000 },
+ { 0x0001c370, 0x00040000 },
+ { 0x0001c374, 0x00040000 },
+ { 0x0001c378, 0x00040000 },
+ { 0x0001c37c, 0x00040000 },
+ { 0x0001c380, 0x00000000 },
+ { 0x0001c384, 0x00000000 },
+ { 0x0001c388, 0x00000000 },
+ { 0x0001c38c, 0x00000000 },
+ { 0x0001c390, 0x00000000 },
+ { 0x0001c394, 0x00000000 },
+ { 0x0001c398, 0x00000000 },
+ { 0x0001c39c, 0x00000000 },
+ { 0x0001c3a0, 0x00000000 },
+ { 0x0001c3a4, 0x00000000 },
+ { 0x0001c3a8, 0x00000000 },
+ { 0x0001c3ac, 0x00000000 },
+ { 0x0001c3b0, 0x00000000 },
+ { 0x0001c3b4, 0x00000000 },
+ { 0x0001c3b8, 0x00000000 },
+ { 0x0001c3bc, 0x00000000 },
+
+ { 0x0001c140, 0x00000000 },
+ { 0x0001c144, 0x00000000 },
+ { 0x0001c148, 0x00000000 },
+ { 0x0001c14c, 0x00000000 },
+ { 0x0001c150, 0x00000000 },
+ { 0x0001c154, 0x00000000 },
+ { 0x0001c158, 0x00000000 },
+ { 0x0001c15c, 0x00000000 },
+ { 0x0001c160, 0x00000000 },
+ { 0x0001c164, 0x00000000 },
+ { 0x0001c168, 0x00000000 },
+ { 0x0001c16c, 0x00000000 },
+ { 0x0001c170, 0x00000000 },
+ { 0x0001c174, 0x00000000 },
+ { 0x0001c178, 0x00000000 },
+ { 0x0001c17c, 0x00000000 },
+ { 0x0001c180, 0x00040000 },
+ { 0x0001c184, 0x00040000 },
+ { 0x0001c188, 0x00040000 },
+ { 0x0001c18c, 0x00040000 },
+ { 0x0001c190, 0x00040000 },
+ { 0x0001c194, 0x00040000 },
+ { 0x0001c198, 0x00040000 },
+ { 0x0001c19c, 0x00040000 },
+ { 0x0001c1a0, 0x00040000 },
+ { 0x0001c1a4, 0x00040000 },
+ { 0x0001c1a8, 0x00040000 },
+ { 0x0001c1ac, 0x00040000 },
+ { 0x0001c1b0, 0x00040000 },
+ { 0x0001c1b4, 0x00040000 },
+ { 0x0001c1b8, 0x00040000 },
+ { 0x0001c1bc, 0x00040000 },
+ { 0x0001c1c0, 0x00000000 },
+ { 0x0001c1c4, 0x00000000 },
+ { 0x0001c1c8, 0x00000000 },
+ { 0x0001c1cc, 0x00000000 },
+ { 0x0001c1d0, 0x00000000 },
+ { 0x0001c1d4, 0x00000000 },
+ { 0x0001c1d8, 0x00000000 },
+ { 0x0001c1dc, 0x00000000 },
+ { 0x0001c1e0, 0x00000000 },
+ { 0x0001c1e4, 0x00000000 },
+ { 0x0001c1e8, 0x00000000 },
+ { 0x0001c1ec, 0x00000000 },
+ { 0x0001c1f0, 0x00000000 },
+ { 0x0001c1f4, 0x00000000 },
+ { 0x0001c1f8, 0x00000000 },
+ { 0x0001c1fc, 0x00000000 },
+
+ { 0x0001c200, 0x00000000 },
+ { 0x0001c204, 0x00000000 },
+ { 0x0001c208, 0x00000000 },
+ { 0x0001c20c, 0x00000000 },
+ { 0x0001c210, 0x00000000 },
+ { 0x0001c214, 0x00000000 },
+ { 0x0001c218, 0x00000000 },
+ { 0x0001c21c, 0x00000000 },
+ { 0x0001c220, 0x00000000 },
+ { 0x0001c224, 0x00000000 },
+ { 0x0001c228, 0x00000000 },
+ { 0x0001c22c, 0x00000000 },
+ { 0x0001c230, 0x00000000 },
+ { 0x0001c234, 0x00000000 },
+ { 0x0001c238, 0x00000000 },
+ { 0x0001c23c, 0x00000000 },
+ { 0x0001c240, 0x00040000 },
+ { 0x0001c244, 0x00040000 },
+ { 0x0001c248, 0x00040000 },
+ { 0x0001c24c, 0x00040000 },
+ { 0x0001c250, 0x00040000 },
+ { 0x0001c254, 0x00040000 },
+ { 0x0001c258, 0x00040000 },
+ { 0x0001c25c, 0x00040000 },
+ { 0x0001c260, 0x00040000 },
+ { 0x0001c264, 0x00040000 },
+ { 0x0001c268, 0x00040000 },
+ { 0x0001c26c, 0x00040000 },
+ { 0x0001c270, 0x00040000 },
+ { 0x0001c274, 0x00040000 },
+ { 0x0001c278, 0x00040000 },
+ { 0x0001c27c, 0x00040000 },
+ { 0x0001c280, 0x00000000 },
+ { 0x0001c284, 0x00000000 },
+ { 0x0001c288, 0x00000000 },
+ { 0x0001c28c, 0x00000000 },
+ { 0x0001c290, 0x00000000 },
+ { 0x0001c294, 0x00000000 },
+ { 0x0001c298, 0x00000000 },
+ { 0x0001c29c, 0x00000000 },
+ { 0x0001c2a0, 0x00000000 },
+ { 0x0001c2a4, 0x00000000 },
+ { 0x0001c2a8, 0x00000000 },
+ { 0x0001c2ac, 0x00000000 },
+ { 0x0001c2b0, 0x00000000 },
+ { 0x0001c2b4, 0x00000000 },
+ { 0x0001c2b8, 0x00000000 },
+ { 0x0001c2bc, 0x00000000 },
+
+ { 0x0001c080, 0x00000000 },
+ { 0x0001c084, 0x00000000 },
+ { 0x0001c088, 0x00000000 },
+ { 0x0001c08c, 0x00000000 },
+ { 0x0001c090, 0x00000000 },
+ { 0x0001c094, 0x00000000 },
+ { 0x0001c098, 0x00000000 },
+ { 0x0001c09c, 0x00000000 },
+ { 0x0001c0a0, 0x00000000 },
+ { 0x0001c0a4, 0x00000000 },
+ { 0x0001c0a8, 0x00000000 },
+ { 0x0001c0ac, 0x00000000 },
+ { 0x0001c0b0, 0x00000000 },
+ { 0x0001c0b4, 0x00000000 },
+ { 0x0001c0b8, 0x00000000 },
+ { 0x0001c0bc, 0x00000000 },
+ { 0x0001c0c0, 0x00040000 },
+ { 0x0001c0c4, 0x00040000 },
+ { 0x0001c0c8, 0x00040000 },
+ { 0x0001c0cc, 0x00040000 },
+ { 0x0001c0d0, 0x00040000 },
+ { 0x0001c0d4, 0x00040000 },
+ { 0x0001c0d8, 0x00040000 },
+ { 0x0001c0dc, 0x00040000 },
+ { 0x0001c0e0, 0x00040000 },
+ { 0x0001c0e4, 0x00040000 },
+ { 0x0001c0e8, 0x00040000 },
+ { 0x0001c0ec, 0x00040000 },
+ { 0x0001c0f0, 0x00040000 },
+ { 0x0001c0f4, 0x00040000 },
+ { 0x0001c0f8, 0x00040000 },
+ { 0x0001c0fc, 0x00040000 },
+ { 0x0001c100, 0x00000000 },
+ { 0x0001c104, 0x00000000 },
+ { 0x0001c108, 0x00000000 },
+ { 0x0001c10c, 0x00000000 },
+ { 0x0001c110, 0x00000000 },
+ { 0x0001c114, 0x00000000 },
+ { 0x0001c118, 0x00000000 },
+ { 0x0001c11c, 0x00000000 },
+ { 0x0001c120, 0x00000000 },
+ { 0x0001c124, 0x00000000 },
+ { 0x0001c128, 0x00000000 },
+ { 0x0001c12c, 0x00000000 },
+ { 0x0001c130, 0x00000000 },
+ { 0x0001c134, 0x00000000 },
+ { 0x0001c138, 0x00000000 },
+ { 0x0001c13c, 0x00000000 },
+};
+
+struct data_unit scaler_coeffs_ch1[] = {
+ { 0x0001c700, 0x00000000 },
+ { 0x0001c704, 0x00000000 },
+ { 0x0001c708, 0x00000000 },
+ { 0x0001c70c, 0x00000000 },
+ { 0x0001c710, 0x00000000 },
+ { 0x0001c714, 0x00000000 },
+ { 0x0001c718, 0x00000000 },
+ { 0x0001c71c, 0x00000000 },
+ { 0x0001c720, 0x00000000 },
+ { 0x0001c724, 0x00000061 },
+ { 0x0001c728, 0x00000041 },
+ { 0x0001c72c, 0x00000031 },
+ { 0x0001c730, 0x00000021 },
+ { 0x0001c734, 0x00000010 },
+ { 0x0001c738, 0x00000010 },
+ { 0x0001c73c, 0x00000000 },
+ { 0x0001c740, 0x06d32506 },
+ { 0x0001c744, 0x05432008 },
+ { 0x0001c748, 0x0403100a },
+ { 0x0001c74c, 0x0302f50d },
+ { 0x0001c750, 0x0242d110 },
+ { 0x0001c754, 0x01a2a413 },
+ { 0x0001c758, 0x01326f17 },
+ { 0x0001c75c, 0x00d2351b },
+ { 0x0001c760, 0x0091f71f },
+ { 0x0001c764, 0x0b823500 },
+ { 0x0001c768, 0x07a26f01 },
+ { 0x0001c76c, 0x03f2a401 },
+ { 0x0001c770, 0x0092d102 },
+ { 0x0001c774, 0x0d92f503 },
+ { 0x0001c778, 0x0af31004 },
+ { 0x0001c77c, 0x08b32005 },
+ { 0x0001c780, 0x0d000000 },
+ { 0x0001c784, 0x0b000000 },
+ { 0x0001c788, 0x0f001000 },
+ { 0x0001c78c, 0x09001000 },
+ { 0x0001c790, 0x09002000 },
+ { 0x0001c794, 0x0f003000 },
+ { 0x0001c798, 0x0a004000 },
+ { 0x0001c79c, 0x08006000 },
+ { 0x0001c7a0, 0x07009000 },
+ { 0x0001c7a4, 0x0d000000 },
+ { 0x0001c7a8, 0x03000000 },
+ { 0x0001c7ac, 0x0a000000 },
+ { 0x0001c7b0, 0x04000000 },
+ { 0x0001c7b4, 0x00000000 },
+ { 0x0001c7b8, 0x00000000 },
+ { 0x0001c7bc, 0x04000000 },
+
+ { 0x0001c540, 0x00000000 },
+ { 0x0001c544, 0x00000000 },
+ { 0x0001c548, 0x00000000 },
+ { 0x0001c54c, 0x00000000 },
+ { 0x0001c550, 0x00000000 },
+ { 0x0001c554, 0x00000000 },
+ { 0x0001c558, 0x00000000 },
+ { 0x0001c55c, 0x00000000 },
+ { 0x0001c560, 0x00000000 },
+ { 0x0001c564, 0x00000061 },
+ { 0x0001c568, 0x00000041 },
+ { 0x0001c56c, 0x00000031 },
+ { 0x0001c570, 0x00000021 },
+ { 0x0001c574, 0x00000010 },
+ { 0x0001c578, 0x00000010 },
+ { 0x0001c57c, 0x00000000 },
+ { 0x0001c580, 0x06d32506 },
+ { 0x0001c584, 0x05432008 },
+ { 0x0001c588, 0x0403100a },
+ { 0x0001c58c, 0x0302f50d },
+ { 0x0001c590, 0x0242d110 },
+ { 0x0001c594, 0x01a2a413 },
+ { 0x0001c598, 0x01326f17 },
+ { 0x0001c59c, 0x00d2351b },
+ { 0x0001c5a0, 0x0091f71f },
+ { 0x0001c5a4, 0x0b823500 },
+ { 0x0001c5a8, 0x07a26f01 },
+ { 0x0001c5ac, 0x03f2a401 },
+ { 0x0001c5b0, 0x0092d102 },
+ { 0x0001c5b4, 0x0d92f503 },
+ { 0x0001c5b8, 0x0af31004 },
+ { 0x0001c5bc, 0x08b32005 },
+ { 0x0001c5c0, 0x0d000000 },
+ { 0x0001c5c4, 0x0b000000 },
+ { 0x0001c5c8, 0x0f001000 },
+ { 0x0001c5cc, 0x09001000 },
+ { 0x0001c5d0, 0x09002000 },
+ { 0x0001c5d4, 0x0f003000 },
+ { 0x0001c5d8, 0x0a004000 },
+ { 0x0001c5dc, 0x08006000 },
+ { 0x0001c5e0, 0x07009000 },
+ { 0x0001c5e4, 0x0d000000 },
+ { 0x0001c5e8, 0x03000000 },
+ { 0x0001c5ec, 0x0a000000 },
+ { 0x0001c5f0, 0x04000000 },
+ { 0x0001c5f4, 0x00000000 },
+ { 0x0001c5f8, 0x00000000 },
+ { 0x0001c5fc, 0x04000000 },
+ { 0x0001c600, 0x00000000 },
+ { 0x0001c604, 0x00000000 },
+ { 0x0001c608, 0x00000000 },
+ { 0x0001c60c, 0x00000000 },
+ { 0x0001c610, 0x00000000 },
+ { 0x0001c614, 0x00000000 },
+ { 0x0001c618, 0x00000000 },
+ { 0x0001c61c, 0x00000000 },
+ { 0x0001c620, 0x00000000 },
+ { 0x0001c624, 0x00000061 },
+ { 0x0001c628, 0x00000041 },
+ { 0x0001c62c, 0x00000031 },
+ { 0x0001c630, 0x00000021 },
+ { 0x0001c634, 0x00000010 },
+ { 0x0001c638, 0x00000010 },
+ { 0x0001c63c, 0x00000000 },
+ { 0x0001c640, 0x06d32806 },
+ { 0x0001c644, 0x05532208 },
+ { 0x0001c648, 0x0413120a },
+ { 0x0001c64c, 0x0312f80d },
+ { 0x0001c650, 0x0242d310 },
+ { 0x0001c654, 0x01a2a614 },
+ { 0x0001c658, 0x01327117 },
+ { 0x0001c65c, 0x00d2361b },
+ { 0x0001c660, 0x0091f81f },
+ { 0x0001c664, 0x0b923600 },
+ { 0x0001c668, 0x07b27101 },
+ { 0x0001c66c, 0x0402a601 },
+ { 0x0001c670, 0x00a2d302 },
+ { 0x0001c674, 0x0da2f803 },
+ { 0x0001c678, 0x0af31204 },
+ { 0x0001c67c, 0x08b32205 },
+ { 0x0001c680, 0x0d000000 },
+ { 0x0001c684, 0x0b000000 },
+ { 0x0001c688, 0x0f001000 },
+ { 0x0001c68c, 0x0a001000 },
+ { 0x0001c690, 0x0a002000 },
+ { 0x0001c694, 0x00003000 },
+ { 0x0001c698, 0x0b004000 },
+ { 0x0001c69c, 0x09006000 },
+ { 0x0001c6a0, 0x08009000 },
+ { 0x0001c6a4, 0x0d000000 },
+ { 0x0001c6a8, 0x03000000 },
+ { 0x0001c6ac, 0x0a000000 },
+ { 0x0001c6b0, 0x04000000 },
+ { 0x0001c6b4, 0x01000000 },
+ { 0x0001c6b8, 0x01000000 },
+ { 0x0001c6bc, 0x05000000 },
+
+ { 0x0001c480, 0x00000000 },
+ { 0x0001c484, 0x00000000 },
+ { 0x0001c488, 0x00000000 },
+ { 0x0001c48c, 0x00000000 },
+ { 0x0001c490, 0x00000000 },
+ { 0x0001c494, 0x00000000 },
+ { 0x0001c498, 0x00000000 },
+ { 0x0001c49c, 0x00000000 },
+ { 0x0001c4a0, 0x00000000 },
+ { 0x0001c4a4, 0x00000061 },
+ { 0x0001c4a8, 0x00000041 },
+ { 0x0001c4ac, 0x00000031 },
+ { 0x0001c4b0, 0x00000021 },
+ { 0x0001c4b4, 0x00000010 },
+ { 0x0001c4b8, 0x00000010 },
+ { 0x0001c4bc, 0x00000000 },
+ { 0x0001c4c0, 0x06d32806 },
+ { 0x0001c4c4, 0x05532208 },
+ { 0x0001c4c8, 0x0413120a },
+ { 0x0001c4cc, 0x0312f80d },
+ { 0x0001c4d0, 0x0242d310 },
+ { 0x0001c4d4, 0x01a2a614 },
+ { 0x0001c4d8, 0x01327117 },
+ { 0x0001c4dc, 0x00d2361b },
+ { 0x0001c4e0, 0x0091f81f },
+ { 0x0001c4e4, 0x0b923600 },
+ { 0x0001c4e8, 0x07b27101 },
+ { 0x0001c4ec, 0x0402a601 },
+ { 0x0001c4f0, 0x00a2d302 },
+ { 0x0001c4f4, 0x0da2f803 },
+ { 0x0001c4f8, 0x0af31204 },
+ { 0x0001c4fc, 0x08b32205 },
+ { 0x0001c500, 0x0d000000 },
+ { 0x0001c504, 0x0b000000 },
+ { 0x0001c508, 0x0f001000 },
+ { 0x0001c50c, 0x0a001000 },
+ { 0x0001c510, 0x0a002000 },
+ { 0x0001c514, 0x00003000 },
+ { 0x0001c518, 0x0b004000 },
+ { 0x0001c51c, 0x09006000 },
+ { 0x0001c520, 0x08009000 },
+ { 0x0001c524, 0x0d000000 },
+ { 0x0001c528, 0x03000000 },
+ { 0x0001c52c, 0x0a000000 },
+ { 0x0001c530, 0x04000000 },
+ { 0x0001c534, 0x01000000 },
+ { 0x0001c538, 0x01000000 },
+ { 0x0001c53c, 0x05000000 },
+ { 0x0001c40c, 0x00000000 },
+ { 0x0001c424, 0x0437077f },
+ { 0x0001c414, 0x00000002 },
+ { 0x0001c420, 0x0437077f },
+ { 0x0001c464, 0x00001000 },
+ { 0x0001c460, 0x00000000 },
+ { 0x0001c454, 0x00002000 },
+ { 0x0001c450, 0x00000000 },
+ { 0x0001c444, 0x00000000 },
+ { 0x0001c438, 0x00000000 },
+ { 0x0001c43c, 0x00000000 },
+ { 0x0001c440, 0x00000000 },
+ { 0x0001c41c, 0x021b03bf },
+ { 0x0001c410, 0x00000000 },
+ { 0x0001c408, 0x00000003 },
+ { 0x0001c434, 0x00000000 },
+ { 0x0001c428, 0x00000000 },
+ { 0x0001c42c, 0x00000000 },
+ { 0x0001c430, 0x00000000 },
+ { 0x0001c418, 0x0437077f },
+ { 0x0001c45c, 0x00001000 },
+ { 0x0001c458, 0xfffff800 },
+ { 0x0001c44c, 0x00002000 },
+ { 0x0001c448, 0x00000000 },
+};
+
+struct data_unit hdr10_pipe1_lut_a0[] = {
+ { 0x00000000, 0x00000000 },
+ { 0x00000004, 0x00000003 },
+ { 0x00000008, 0x00000007 },
+ { 0x0000000c, 0x0000000a },
+ { 0x00000010, 0x0000000e },
+ { 0x00000014, 0x00000011 },
+ { 0x00000018, 0x00000015 },
+ { 0x0000001c, 0x00000018 },
+ { 0x00000020, 0x0000001c },
+ { 0x00000024, 0x00000020 },
+ { 0x00000028, 0x00000023 },
+ { 0x0000002c, 0x00000027 },
+ { 0x00000030, 0x0000002a },
+ { 0x00000034, 0x0000002e },
+ { 0x00000038, 0x00000031 },
+ { 0x0000003c, 0x00000035 },
+ { 0x00000040, 0x00000038 },
+ { 0x00000044, 0x0000003c },
+ { 0x00000048, 0x00000040 },
+ { 0x0000004c, 0x00000043 },
+ { 0x00000050, 0x00000047 },
+ { 0x00000054, 0x0000004a },
+ { 0x00000058, 0x0000004e },
+ { 0x0000005c, 0x00000051 },
+ { 0x00000060, 0x00000055 },
+ { 0x00000064, 0x00000058 },
+ { 0x00000068, 0x0000005c },
+ { 0x0000006c, 0x00000060 },
+ { 0x00000070, 0x00000063 },
+ { 0x00000074, 0x00000067 },
+ { 0x00000078, 0x0000006a },
+ { 0x0000007c, 0x0000006e },
+ { 0x00000080, 0x00000071 },
+ { 0x00000084, 0x00000075 },
+ { 0x00000088, 0x00000078 },
+ { 0x0000008c, 0x0000007c },
+ { 0x00000090, 0x00000080 },
+ { 0x00000094, 0x00000083 },
+ { 0x00000098, 0x00000087 },
+ { 0x0000009c, 0x0000008a },
+ { 0x000000a0, 0x0000008e },
+ { 0x000000a4, 0x00000091 },
+ { 0x000000a8, 0x00000095 },
+ { 0x000000ac, 0x00000099 },
+ { 0x000000b0, 0x0000009c },
+ { 0x000000b4, 0x000000a0 },
+ { 0x000000b8, 0x000000a3 },
+ { 0x000000bc, 0x000000a7 },
+ { 0x000000c0, 0x000000aa },
+ { 0x000000c4, 0x000000ae },
+ { 0x000000c8, 0x000000b1 },
+ { 0x000000cc, 0x000000b5 },
+ { 0x000000d0, 0x000000b9 },
+ { 0x000000d4, 0x000000bc },
+ { 0x000000d8, 0x000000c0 },
+ { 0x000000dc, 0x000000c3 },
+ { 0x000000e0, 0x000000c7 },
+ { 0x000000e4, 0x000000ca },
+ { 0x000000e8, 0x000000ce },
+ { 0x000000ec, 0x000000d1 },
+ { 0x000000f0, 0x000000d5 },
+ { 0x000000f4, 0x000000d9 },
+ { 0x000000f8, 0x000000dc },
+ { 0x000000fc, 0x000000e0 },
+ { 0x00000100, 0x000000e3 },
+ { 0x00000104, 0x000000e7 },
+ { 0x00000108, 0x000000ea },
+ { 0x0000010c, 0x000000ee },
+ { 0x00000110, 0x000000f1 },
+ { 0x00000114, 0x000000f5 },
+ { 0x00000118, 0x000000f9 },
+ { 0x0000011c, 0x000000fc },
+ { 0x00000120, 0x00000100 },
+ { 0x00000124, 0x00000103 },
+ { 0x00000128, 0x00000107 },
+ { 0x0000012c, 0x0000010a },
+ { 0x00000130, 0x0000010e },
+ { 0x00000134, 0x00000112 },
+ { 0x00000138, 0x00000115 },
+ { 0x0000013c, 0x00000119 },
+ { 0x00000140, 0x0000011c },
+ { 0x00000144, 0x00000120 },
+ { 0x00000148, 0x00000123 },
+ { 0x0000014c, 0x00000126 },
+ { 0x00000150, 0x0000012a },
+ { 0x00000154, 0x0000012d },
+ { 0x00000158, 0x00000131 },
+ { 0x0000015c, 0x00000134 },
+ { 0x00000160, 0x00000138 },
+ { 0x00000164, 0x0000013c },
+ { 0x00000168, 0x0000013f },
+ { 0x0000016c, 0x00000143 },
+ { 0x00000170, 0x00000147 },
+ { 0x00000174, 0x0000014b },
+ { 0x00000178, 0x0000014e },
+ { 0x0000017c, 0x00000152 },
+ { 0x00000180, 0x00000156 },
+ { 0x00000184, 0x0000015a },
+ { 0x00000188, 0x0000015e },
+ { 0x0000018c, 0x00000162 },
+ { 0x00000190, 0x00000166 },
+ { 0x00000194, 0x0000016a },
+ { 0x00000198, 0x0000016e },
+ { 0x0000019c, 0x00000172 },
+ { 0x000001a0, 0x00000176 },
+ { 0x000001a4, 0x0000017a },
+ { 0x000001a8, 0x0000017e },
+ { 0x000001ac, 0x00000182 },
+ { 0x000001b0, 0x00000186 },
+ { 0x000001b4, 0x0000018a },
+ { 0x000001b8, 0x0000018f },
+ { 0x000001bc, 0x00000193 },
+ { 0x000001c0, 0x00000197 },
+ { 0x000001c4, 0x0000019b },
+ { 0x000001c8, 0x000001a0 },
+ { 0x000001cc, 0x000001a4 },
+ { 0x000001d0, 0x000001a8 },
+ { 0x000001d4, 0x000001ad },
+ { 0x000001d8, 0x000001b1 },
+ { 0x000001dc, 0x000001b5 },
+ { 0x000001e0, 0x000001ba },
+ { 0x000001e4, 0x000001be },
+ { 0x000001e8, 0x000001c3 },
+ { 0x000001ec, 0x000001c7 },
+ { 0x000001f0, 0x000001cc },
+ { 0x000001f4, 0x000001d0 },
+ { 0x000001f8, 0x000001d5 },
+ { 0x000001fc, 0x000001d9 },
+ { 0x00000200, 0x000001de },
+ { 0x00000204, 0x000001e3 },
+ { 0x00000208, 0x000001e7 },
+ { 0x0000020c, 0x000001ec },
+ { 0x00000210, 0x000001f1 },
+ { 0x00000214, 0x000001f6 },
+ { 0x00000218, 0x000001fa },
+ { 0x0000021c, 0x000001ff },
+ { 0x00000220, 0x00000204 },
+ { 0x00000224, 0x00000209 },
+ { 0x00000228, 0x0000020e },
+ { 0x0000022c, 0x00000213 },
+ { 0x00000230, 0x00000217 },
+ { 0x00000234, 0x0000021c },
+ { 0x00000238, 0x00000221 },
+ { 0x0000023c, 0x00000226 },
+ { 0x00000240, 0x0000022b },
+ { 0x00000244, 0x00000230 },
+ { 0x00000248, 0x00000236 },
+ { 0x0000024c, 0x0000023b },
+ { 0x00000250, 0x00000240 },
+ { 0x00000254, 0x00000245 },
+ { 0x00000258, 0x0000024a },
+ { 0x0000025c, 0x0000024f },
+ { 0x00000260, 0x00000255 },
+ { 0x00000264, 0x0000025a },
+ { 0x00000268, 0x0000025f },
+ { 0x0000026c, 0x00000264 },
+ { 0x00000270, 0x0000026a },
+ { 0x00000274, 0x0000026f },
+ { 0x00000278, 0x00000274 },
+ { 0x0000027c, 0x0000027a },
+ { 0x00000280, 0x0000027f },
+ { 0x00000284, 0x00000285 },
+ { 0x00000288, 0x0000028a },
+ { 0x0000028c, 0x00000290 },
+ { 0x00000290, 0x00000295 },
+ { 0x00000294, 0x0000029b },
+ { 0x00000298, 0x000002a0 },
+ { 0x0000029c, 0x000002a6 },
+ { 0x000002a0, 0x000002ac },
+ { 0x000002a4, 0x000002b1 },
+ { 0x000002a8, 0x000002b7 },
+ { 0x000002ac, 0x000002bd },
+ { 0x000002b0, 0x000002c2 },
+ { 0x000002b4, 0x000002c8 },
+ { 0x000002b8, 0x000002ce },
+ { 0x000002bc, 0x000002d4 },
+ { 0x000002c0, 0x000002da },
+ { 0x000002c4, 0x000002df },
+ { 0x000002c8, 0x000002e5 },
+ { 0x000002cc, 0x000002eb },
+ { 0x000002d0, 0x000002f1 },
+ { 0x000002d4, 0x000002f7 },
+ { 0x000002d8, 0x000002fd },
+ { 0x000002dc, 0x00000303 },
+ { 0x000002e0, 0x00000309 },
+ { 0x000002e4, 0x0000030f },
+ { 0x000002e8, 0x00000315 },
+ { 0x000002ec, 0x0000031c },
+ { 0x000002f0, 0x00000322 },
+ { 0x000002f4, 0x00000328 },
+ { 0x000002f8, 0x0000032e },
+ { 0x000002fc, 0x00000334 },
+ { 0x00000300, 0x0000033b },
+ { 0x00000304, 0x00000341 },
+ { 0x00000308, 0x00000347 },
+ { 0x0000030c, 0x0000034d },
+ { 0x00000310, 0x00000354 },
+ { 0x00000314, 0x0000035a },
+ { 0x00000318, 0x00000361 },
+ { 0x0000031c, 0x00000367 },
+ { 0x00000320, 0x0000036d },
+ { 0x00000324, 0x00000374 },
+ { 0x00000328, 0x0000037a },
+ { 0x0000032c, 0x00000381 },
+ { 0x00000330, 0x00000388 },
+ { 0x00000334, 0x0000038e },
+ { 0x00000338, 0x00000395 },
+ { 0x0000033c, 0x0000039b },
+ { 0x00000340, 0x000003a2 },
+ { 0x00000344, 0x000003a9 },
+ { 0x00000348, 0x000003b0 },
+ { 0x0000034c, 0x000003b6 },
+ { 0x00000350, 0x000003bd },
+ { 0x00000354, 0x000003c4 },
+ { 0x00000358, 0x000003cb },
+ { 0x0000035c, 0x000003d2 },
+ { 0x00000360, 0x000003d8 },
+ { 0x00000364, 0x000003df },
+ { 0x00000368, 0x000003e6 },
+ { 0x0000036c, 0x000003ed },
+ { 0x00000370, 0x000003f4 },
+ { 0x00000374, 0x000003fb },
+ { 0x00000378, 0x00000402 },
+ { 0x0000037c, 0x00000409 },
+ { 0x00000380, 0x00000411 },
+ { 0x00000384, 0x00000418 },
+ { 0x00000388, 0x0000041f },
+ { 0x0000038c, 0x00000426 },
+ { 0x00000390, 0x0000042d },
+ { 0x00000394, 0x00000434 },
+ { 0x00000398, 0x0000043c },
+ { 0x0000039c, 0x00000443 },
+ { 0x000003a0, 0x0000044a },
+ { 0x000003a4, 0x00000452 },
+ { 0x000003a8, 0x00000459 },
+ { 0x000003ac, 0x00000460 },
+ { 0x000003b0, 0x00000468 },
+ { 0x000003b4, 0x0000046f },
+ { 0x000003b8, 0x00000477 },
+ { 0x000003bc, 0x0000047e },
+ { 0x000003c0, 0x00000486 },
+ { 0x000003c4, 0x0000048d },
+ { 0x000003c8, 0x00000495 },
+ { 0x000003cc, 0x0000049c },
+ { 0x000003d0, 0x000004a4 },
+ { 0x000003d4, 0x000004ac },
+ { 0x000003d8, 0x000004b3 },
+ { 0x000003dc, 0x000004bb },
+ { 0x000003e0, 0x000004c3 },
+ { 0x000003e4, 0x000004cb },
+ { 0x000003e8, 0x000004d3 },
+ { 0x000003ec, 0x000004da },
+ { 0x000003f0, 0x000004e2 },
+ { 0x000003f4, 0x000004ea },
+ { 0x000003f8, 0x000004f2 },
+ { 0x000003fc, 0x000004fa },
+ { 0x00000400, 0x00000502 },
+ { 0x00000404, 0x0000050a },
+ { 0x00000408, 0x00000512 },
+ { 0x0000040c, 0x0000051a },
+ { 0x00000410, 0x00000522 },
+ { 0x00000414, 0x0000052a },
+ { 0x00000418, 0x00000532 },
+ { 0x0000041c, 0x0000053a },
+ { 0x00000420, 0x00000543 },
+ { 0x00000424, 0x0000054b },
+ { 0x00000428, 0x00000553 },
+ { 0x0000042c, 0x0000055b },
+ { 0x00000430, 0x00000564 },
+ { 0x00000434, 0x0000056c },
+ { 0x00000438, 0x00000574 },
+ { 0x0000043c, 0x0000057d },
+ { 0x00000440, 0x00000585 },
+ { 0x00000444, 0x0000058d },
+ { 0x00000448, 0x00000596 },
+ { 0x0000044c, 0x0000059e },
+ { 0x00000450, 0x000005a7 },
+ { 0x00000454, 0x000005af },
+ { 0x00000458, 0x000005b8 },
+ { 0x0000045c, 0x000005c1 },
+ { 0x00000460, 0x000005c9 },
+ { 0x00000464, 0x000005d2 },
+ { 0x00000468, 0x000005db },
+ { 0x0000046c, 0x000005e3 },
+ { 0x00000470, 0x000005ec },
+ { 0x00000474, 0x000005f5 },
+ { 0x00000478, 0x000005fe },
+ { 0x0000047c, 0x00000606 },
+ { 0x00000480, 0x0000060f },
+ { 0x00000484, 0x00000618 },
+ { 0x00000488, 0x00000621 },
+ { 0x0000048c, 0x0000062a },
+ { 0x00000490, 0x00000633 },
+ { 0x00000494, 0x0000063c },
+ { 0x00000498, 0x00000645 },
+ { 0x0000049c, 0x0000064e },
+ { 0x000004a0, 0x00000657 },
+ { 0x000004a4, 0x00000660 },
+ { 0x000004a8, 0x00000669 },
+ { 0x000004ac, 0x00000672 },
+ { 0x000004b0, 0x0000067b },
+ { 0x000004b4, 0x00000685 },
+ { 0x000004b8, 0x0000068e },
+ { 0x000004bc, 0x00000697 },
+ { 0x000004c0, 0x000006a0 },
+ { 0x000004c4, 0x000006aa },
+ { 0x000004c8, 0x000006b3 },
+ { 0x000004cc, 0x000006bd },
+ { 0x000004d0, 0x000006c6 },
+ { 0x000004d4, 0x000006cf },
+ { 0x000004d8, 0x000006d9 },
+ { 0x000004dc, 0x000006e2 },
+ { 0x000004e0, 0x000006ec },
+ { 0x000004e4, 0x000006f5 },
+ { 0x000004e8, 0x000006ff },
+ { 0x000004ec, 0x00000709 },
+ { 0x000004f0, 0x00000712 },
+ { 0x000004f4, 0x0000071c },
+ { 0x000004f8, 0x00000726 },
+ { 0x000004fc, 0x0000072f },
+ { 0x00000500, 0x00000739 },
+ { 0x00000504, 0x00000743 },
+ { 0x00000508, 0x0000074d },
+ { 0x0000050c, 0x00000756 },
+ { 0x00000510, 0x00000760 },
+ { 0x00000514, 0x0000076a },
+ { 0x00000518, 0x00000774 },
+ { 0x0000051c, 0x0000077e },
+ { 0x00000520, 0x00000788 },
+ { 0x00000524, 0x00000792 },
+ { 0x00000528, 0x0000079c },
+ { 0x0000052c, 0x000007a6 },
+ { 0x00000530, 0x000007b0 },
+ { 0x00000534, 0x000007ba },
+ { 0x00000538, 0x000007c4 },
+ { 0x0000053c, 0x000007cf },
+ { 0x00000540, 0x000007d9 },
+ { 0x00000544, 0x000007e3 },
+ { 0x00000548, 0x000007ed },
+ { 0x0000054c, 0x000007f7 },
+ { 0x00000550, 0x00000802 },
+ { 0x00000554, 0x0000080c },
+ { 0x00000558, 0x00000816 },
+ { 0x0000055c, 0x00000821 },
+ { 0x00000560, 0x0000082b },
+ { 0x00000564, 0x00000836 },
+ { 0x00000568, 0x00000840 },
+ { 0x0000056c, 0x0000084b },
+ { 0x00000570, 0x00000855 },
+ { 0x00000574, 0x00000860 },
+ { 0x00000578, 0x0000086a },
+ { 0x0000057c, 0x00000875 },
+ { 0x00000580, 0x00000880 },
+ { 0x00000584, 0x0000088a },
+ { 0x00000588, 0x00000895 },
+ { 0x0000058c, 0x000008a0 },
+ { 0x00000590, 0x000008ab },
+ { 0x00000594, 0x000008b5 },
+ { 0x00000598, 0x000008c0 },
+ { 0x0000059c, 0x000008cb },
+ { 0x000005a0, 0x000008d6 },
+ { 0x000005a4, 0x000008e1 },
+ { 0x000005a8, 0x000008ec },
+ { 0x000005ac, 0x000008f7 },
+ { 0x000005b0, 0x00000902 },
+ { 0x000005b4, 0x0000090d },
+ { 0x000005b8, 0x00000918 },
+ { 0x000005bc, 0x00000923 },
+ { 0x000005c0, 0x0000092e },
+ { 0x000005c4, 0x00000939 },
+ { 0x000005c8, 0x00000944 },
+ { 0x000005cc, 0x00000950 },
+ { 0x000005d0, 0x0000095b },
+ { 0x000005d4, 0x00000966 },
+ { 0x000005d8, 0x00000971 },
+ { 0x000005dc, 0x0000097d },
+ { 0x000005e0, 0x00000988 },
+ { 0x000005e4, 0x00000993 },
+ { 0x000005e8, 0x0000099f },
+ { 0x000005ec, 0x000009aa },
+ { 0x000005f0, 0x000009b6 },
+ { 0x000005f4, 0x000009c1 },
+ { 0x000005f8, 0x000009cd },
+ { 0x000005fc, 0x000009d8 },
+ { 0x00000600, 0x000009e4 },
+ { 0x00000604, 0x000009f0 },
+ { 0x00000608, 0x000009fb },
+ { 0x0000060c, 0x00000a07 },
+ { 0x00000610, 0x00000a13 },
+ { 0x00000614, 0x00000a1e },
+ { 0x00000618, 0x00000a2a },
+ { 0x0000061c, 0x00000a36 },
+ { 0x00000620, 0x00000a42 },
+ { 0x00000624, 0x00000a4e },
+ { 0x00000628, 0x00000a59 },
+ { 0x0000062c, 0x00000a65 },
+ { 0x00000630, 0x00000a71 },
+ { 0x00000634, 0x00000a7d },
+ { 0x00000638, 0x00000a89 },
+ { 0x0000063c, 0x00000a95 },
+ { 0x00000640, 0x00000aa1 },
+ { 0x00000644, 0x00000aad },
+ { 0x00000648, 0x00000ab9 },
+ { 0x0000064c, 0x00000ac6 },
+ { 0x00000650, 0x00000ad2 },
+ { 0x00000654, 0x00000ade },
+ { 0x00000658, 0x00000aea },
+ { 0x0000065c, 0x00000af6 },
+ { 0x00000660, 0x00000b03 },
+ { 0x00000664, 0x00000b0f },
+ { 0x00000668, 0x00000b1b },
+ { 0x0000066c, 0x00000b28 },
+ { 0x00000670, 0x00000b34 },
+ { 0x00000674, 0x00000b41 },
+ { 0x00000678, 0x00000b4d },
+ { 0x0000067c, 0x00000b5a },
+ { 0x00000680, 0x00000b66 },
+ { 0x00000684, 0x00000b73 },
+ { 0x00000688, 0x00000b7f },
+ { 0x0000068c, 0x00000b8c },
+ { 0x00000690, 0x00000b98 },
+ { 0x00000694, 0x00000ba5 },
+ { 0x00000698, 0x00000bb2 },
+ { 0x0000069c, 0x00000bbf },
+ { 0x000006a0, 0x00000bcb },
+ { 0x000006a4, 0x00000bd8 },
+ { 0x000006a8, 0x00000be5 },
+ { 0x000006ac, 0x00000bf2 },
+ { 0x000006b0, 0x00000bff },
+ { 0x000006b4, 0x00000c0c },
+ { 0x000006b8, 0x00000c19 },
+ { 0x000006bc, 0x00000c25 },
+ { 0x000006c0, 0x00000c32 },
+ { 0x000006c4, 0x00000c40 },
+ { 0x000006c8, 0x00000c4d },
+ { 0x000006cc, 0x00000c5a },
+ { 0x000006d0, 0x00000c67 },
+ { 0x000006d4, 0x00000c74 },
+ { 0x000006d8, 0x00000c81 },
+ { 0x000006dc, 0x00000c8e },
+ { 0x000006e0, 0x00000c9c },
+ { 0x000006e4, 0x00000ca9 },
+ { 0x000006e8, 0x00000cb6 },
+ { 0x000006ec, 0x00000cc3 },
+ { 0x000006f0, 0x00000cd1 },
+ { 0x000006f4, 0x00000cde },
+ { 0x000006f8, 0x00000cec },
+ { 0x000006fc, 0x00000cf9 },
+ { 0x00000700, 0x00000d07 },
+ { 0x00000704, 0x00000d14 },
+ { 0x00000708, 0x00000d22 },
+ { 0x0000070c, 0x00000d2f },
+ { 0x00000710, 0x00000d3d },
+ { 0x00000714, 0x00000d4a },
+ { 0x00000718, 0x00000d58 },
+ { 0x0000071c, 0x00000d66 },
+ { 0x00000720, 0x00000d73 },
+ { 0x00000724, 0x00000d81 },
+ { 0x00000728, 0x00000d8f },
+ { 0x0000072c, 0x00000d9d },
+ { 0x00000730, 0x00000dab },
+ { 0x00000734, 0x00000db8 },
+ { 0x00000738, 0x00000dc6 },
+ { 0x0000073c, 0x00000dd4 },
+ { 0x00000740, 0x00000de2 },
+ { 0x00000744, 0x00000df0 },
+ { 0x00000748, 0x00000dfe },
+ { 0x0000074c, 0x00000e0c },
+ { 0x00000750, 0x00000e1a },
+ { 0x00000754, 0x00000e29 },
+ { 0x00000758, 0x00000e37 },
+ { 0x0000075c, 0x00000e45 },
+ { 0x00000760, 0x00000e53 },
+ { 0x00000764, 0x00000e61 },
+ { 0x00000768, 0x00000e70 },
+ { 0x0000076c, 0x00000e7e },
+ { 0x00000770, 0x00000e8c },
+ { 0x00000774, 0x00000e9a },
+ { 0x00000778, 0x00000ea9 },
+ { 0x0000077c, 0x00000eb7 },
+ { 0x00000780, 0x00000ec6 },
+ { 0x00000784, 0x00000ed4 },
+ { 0x00000788, 0x00000ee3 },
+ { 0x0000078c, 0x00000ef1 },
+ { 0x00000790, 0x00000f00 },
+ { 0x00000794, 0x00000f0e },
+ { 0x00000798, 0x00000f1d },
+ { 0x0000079c, 0x00000f2c },
+ { 0x000007a0, 0x00000f3a },
+ { 0x000007a4, 0x00000f49 },
+ { 0x000007a8, 0x00000f58 },
+ { 0x000007ac, 0x00000f67 },
+ { 0x000007b0, 0x00000f75 },
+ { 0x000007b4, 0x00000f84 },
+ { 0x000007b8, 0x00000f93 },
+ { 0x000007bc, 0x00000fa2 },
+ { 0x000007c0, 0x00000fb1 },
+ { 0x000007c4, 0x00000fc0 },
+ { 0x000007c8, 0x00000fcf },
+ { 0x000007cc, 0x00000fde },
+ { 0x000007d0, 0x00000fed },
+ { 0x000007d4, 0x00000ffc },
+ { 0x000007d8, 0x0000100b },
+ { 0x000007dc, 0x0000101a },
+ { 0x000007e0, 0x0000102a },
+ { 0x000007e4, 0x00001039 },
+ { 0x000007e8, 0x00001048 },
+ { 0x000007ec, 0x00001057 },
+ { 0x000007f0, 0x00001067 },
+ { 0x000007f4, 0x00001076 },
+ { 0x000007f8, 0x00001085 },
+ { 0x000007fc, 0x00001095 },
+ { 0x00000800, 0x000010a4 },
+ { 0x00000804, 0x000010b4 },
+ { 0x00000808, 0x000010c3 },
+ { 0x0000080c, 0x000010d3 },
+ { 0x00000810, 0x000010e2 },
+ { 0x00000814, 0x000010f2 },
+ { 0x00000818, 0x00001101 },
+ { 0x0000081c, 0x00001111 },
+ { 0x00000820, 0x00001121 },
+ { 0x00000824, 0x00001130 },
+ { 0x00000828, 0x00001140 },
+ { 0x0000082c, 0x00001150 },
+ { 0x00000830, 0x00001160 },
+ { 0x00000834, 0x0000116f },
+ { 0x00000838, 0x0000117f },
+ { 0x0000083c, 0x0000118f },
+ { 0x00000840, 0x0000119f },
+ { 0x00000844, 0x000011af },
+ { 0x00000848, 0x000011bf },
+ { 0x0000084c, 0x000011cf },
+ { 0x00000850, 0x000011df },
+ { 0x00000854, 0x000011ef },
+ { 0x00000858, 0x000011ff },
+ { 0x0000085c, 0x0000120f },
+ { 0x00000860, 0x0000121f },
+ { 0x00000864, 0x00001230 },
+ { 0x00000868, 0x00001240 },
+ { 0x0000086c, 0x00001250 },
+ { 0x00000870, 0x00001260 },
+ { 0x00000874, 0x00001271 },
+ { 0x00000878, 0x00001281 },
+ { 0x0000087c, 0x00001291 },
+ { 0x00000880, 0x000012a2 },
+ { 0x00000884, 0x000012b2 },
+ { 0x00000888, 0x000012c3 },
+ { 0x0000088c, 0x000012d3 },
+ { 0x00000890, 0x000012e4 },
+ { 0x00000894, 0x000012f4 },
+ { 0x00000898, 0x00001305 },
+ { 0x0000089c, 0x00001316 },
+ { 0x000008a0, 0x00001326 },
+ { 0x000008a4, 0x00001337 },
+ { 0x000008a8, 0x00001348 },
+ { 0x000008ac, 0x00001359 },
+ { 0x000008b0, 0x00001369 },
+ { 0x000008b4, 0x0000137a },
+ { 0x000008b8, 0x0000138b },
+ { 0x000008bc, 0x0000139c },
+ { 0x000008c0, 0x000013ad },
+ { 0x000008c4, 0x000013be },
+ { 0x000008c8, 0x000013cf },
+ { 0x000008cc, 0x000013e0 },
+ { 0x000008d0, 0x000013f1 },
+ { 0x000008d4, 0x00001402 },
+ { 0x000008d8, 0x00001413 },
+ { 0x000008dc, 0x00001424 },
+ { 0x000008e0, 0x00001435 },
+ { 0x000008e4, 0x00001446 },
+ { 0x000008e8, 0x00001458 },
+ { 0x000008ec, 0x00001469 },
+ { 0x000008f0, 0x0000147a },
+ { 0x000008f4, 0x0000148b },
+ { 0x000008f8, 0x0000149d },
+ { 0x000008fc, 0x000014ae },
+ { 0x00000900, 0x000014c0 },
+ { 0x00000904, 0x000014d1 },
+ { 0x00000908, 0x000014e3 },
+ { 0x0000090c, 0x000014f4 },
+ { 0x00000910, 0x00001506 },
+ { 0x00000914, 0x00001517 },
+ { 0x00000918, 0x00001529 },
+ { 0x0000091c, 0x0000153a },
+ { 0x00000920, 0x0000154c },
+ { 0x00000924, 0x0000155e },
+ { 0x00000928, 0x0000156f },
+ { 0x0000092c, 0x00001581 },
+ { 0x00000930, 0x00001593 },
+ { 0x00000934, 0x000015a5 },
+ { 0x00000938, 0x000015b7 },
+ { 0x0000093c, 0x000015c9 },
+ { 0x00000940, 0x000015db },
+ { 0x00000944, 0x000015ec },
+ { 0x00000948, 0x000015fe },
+ { 0x0000094c, 0x00001610 },
+ { 0x00000950, 0x00001623 },
+ { 0x00000954, 0x00001635 },
+ { 0x00000958, 0x00001647 },
+ { 0x0000095c, 0x00001659 },
+ { 0x00000960, 0x0000166b },
+ { 0x00000964, 0x0000167d },
+ { 0x00000968, 0x0000168f },
+ { 0x0000096c, 0x000016a2 },
+ { 0x00000970, 0x000016b4 },
+ { 0x00000974, 0x000016c6 },
+ { 0x00000978, 0x000016d9 },
+ { 0x0000097c, 0x000016eb },
+ { 0x00000980, 0x000016fe },
+ { 0x00000984, 0x00001710 },
+ { 0x00000988, 0x00001722 },
+ { 0x0000098c, 0x00001735 },
+ { 0x00000990, 0x00001748 },
+ { 0x00000994, 0x0000175a },
+ { 0x00000998, 0x0000176d },
+ { 0x0000099c, 0x0000177f },
+ { 0x000009a0, 0x00001792 },
+ { 0x000009a4, 0x000017a5 },
+ { 0x000009a8, 0x000017b8 },
+ { 0x000009ac, 0x000017ca },
+ { 0x000009b0, 0x000017dd },
+ { 0x000009b4, 0x000017f0 },
+ { 0x000009b8, 0x00001803 },
+ { 0x000009bc, 0x00001816 },
+ { 0x000009c0, 0x00001829 },
+ { 0x000009c4, 0x0000183c },
+ { 0x000009c8, 0x0000184f },
+ { 0x000009cc, 0x00001862 },
+ { 0x000009d0, 0x00001875 },
+ { 0x000009d4, 0x00001888 },
+ { 0x000009d8, 0x0000189b },
+ { 0x000009dc, 0x000018ae },
+ { 0x000009e0, 0x000018c1 },
+ { 0x000009e4, 0x000018d5 },
+ { 0x000009e8, 0x000018e8 },
+ { 0x000009ec, 0x000018fb },
+ { 0x000009f0, 0x0000190e },
+ { 0x000009f4, 0x00001922 },
+ { 0x000009f8, 0x00001935 },
+ { 0x000009fc, 0x00001949 },
+ { 0x00000a00, 0x0000195c },
+ { 0x00000a04, 0x0000196f },
+ { 0x00000a08, 0x00001983 },
+ { 0x00000a0c, 0x00001996 },
+ { 0x00000a10, 0x000019aa },
+ { 0x00000a14, 0x000019be },
+ { 0x00000a18, 0x000019d1 },
+ { 0x00000a1c, 0x000019e5 },
+ { 0x00000a20, 0x000019f9 },
+ { 0x00000a24, 0x00001a0c },
+ { 0x00000a28, 0x00001a20 },
+ { 0x00000a2c, 0x00001a34 },
+ { 0x00000a30, 0x00001a48 },
+ { 0x00000a34, 0x00001a5c },
+ { 0x00000a38, 0x00001a70 },
+ { 0x00000a3c, 0x00001a84 },
+ { 0x00000a40, 0x00001a97 },
+ { 0x00000a44, 0x00001aab },
+ { 0x00000a48, 0x00001ac0 },
+ { 0x00000a4c, 0x00001ad4 },
+ { 0x00000a50, 0x00001ae8 },
+ { 0x00000a54, 0x00001afc },
+ { 0x00000a58, 0x00001b10 },
+ { 0x00000a5c, 0x00001b24 },
+ { 0x00000a60, 0x00001b38 },
+ { 0x00000a64, 0x00001b4d },
+ { 0x00000a68, 0x00001b61 },
+ { 0x00000a6c, 0x00001b75 },
+ { 0x00000a70, 0x00001b8a },
+ { 0x00000a74, 0x00001b9e },
+ { 0x00000a78, 0x00001bb2 },
+ { 0x00000a7c, 0x00001bc7 },
+ { 0x00000a80, 0x00001bdb },
+ { 0x00000a84, 0x00001bf0 },
+ { 0x00000a88, 0x00001c04 },
+ { 0x00000a8c, 0x00001c19 },
+ { 0x00000a90, 0x00001c2e },
+ { 0x00000a94, 0x00001c42 },
+ { 0x00000a98, 0x00001c57 },
+ { 0x00000a9c, 0x00001c6c },
+ { 0x00000aa0, 0x00001c80 },
+ { 0x00000aa4, 0x00001c95 },
+ { 0x00000aa8, 0x00001caa },
+ { 0x00000aac, 0x00001cbf },
+ { 0x00000ab0, 0x00001cd4 },
+ { 0x00000ab4, 0x00001ce8 },
+ { 0x00000ab8, 0x00001cfd },
+ { 0x00000abc, 0x00001d12 },
+ { 0x00000ac0, 0x00001d27 },
+ { 0x00000ac4, 0x00001d3c },
+ { 0x00000ac8, 0x00001d51 },
+ { 0x00000acc, 0x00001d67 },
+ { 0x00000ad0, 0x00001d7c },
+ { 0x00000ad4, 0x00001d91 },
+ { 0x00000ad8, 0x00001da6 },
+ { 0x00000adc, 0x00001dbb },
+ { 0x00000ae0, 0x00001dd1 },
+ { 0x00000ae4, 0x00001de6 },
+ { 0x00000ae8, 0x00001dfb },
+ { 0x00000aec, 0x00001e10 },
+ { 0x00000af0, 0x00001e26 },
+ { 0x00000af4, 0x00001e3b },
+ { 0x00000af8, 0x00001e51 },
+ { 0x00000afc, 0x00001e66 },
+ { 0x00000b00, 0x00001e7c },
+ { 0x00000b04, 0x00001e91 },
+ { 0x00000b08, 0x00001ea7 },
+ { 0x00000b0c, 0x00001ebd },
+ { 0x00000b10, 0x00001ed2 },
+ { 0x00000b14, 0x00001ee8 },
+ { 0x00000b18, 0x00001efe },
+ { 0x00000b1c, 0x00001f13 },
+ { 0x00000b20, 0x00001f29 },
+ { 0x00000b24, 0x00001f3f },
+ { 0x00000b28, 0x00001f55 },
+ { 0x00000b2c, 0x00001f6b },
+ { 0x00000b30, 0x00001f81 },
+ { 0x00000b34, 0x00001f96 },
+ { 0x00000b38, 0x00001fac },
+ { 0x00000b3c, 0x00001fc2 },
+ { 0x00000b40, 0x00001fd9 },
+ { 0x00000b44, 0x00001fef },
+ { 0x00000b48, 0x00002005 },
+ { 0x00000b4c, 0x0000201b },
+ { 0x00000b50, 0x00002031 },
+ { 0x00000b54, 0x00002047 },
+ { 0x00000b58, 0x0000205d },
+ { 0x00000b5c, 0x00002074 },
+ { 0x00000b60, 0x0000208a },
+ { 0x00000b64, 0x000020a0 },
+ { 0x00000b68, 0x000020b7 },
+ { 0x00000b6c, 0x000020cd },
+ { 0x00000b70, 0x000020e4 },
+ { 0x00000b74, 0x000020fa },
+ { 0x00000b78, 0x00002111 },
+ { 0x00000b7c, 0x00002127 },
+ { 0x00000b80, 0x0000213e },
+ { 0x00000b84, 0x00002154 },
+ { 0x00000b88, 0x0000216b },
+ { 0x00000b8c, 0x00002182 },
+ { 0x00000b90, 0x00002198 },
+ { 0x00000b94, 0x000021af },
+ { 0x00000b98, 0x000021c6 },
+ { 0x00000b9c, 0x000021dd },
+ { 0x00000ba0, 0x000021f3 },
+ { 0x00000ba4, 0x0000220a },
+ { 0x00000ba8, 0x00002221 },
+ { 0x00000bac, 0x00002238 },
+ { 0x00000bb0, 0x0000224f },
+ { 0x00000bb4, 0x00002266 },
+ { 0x00000bb8, 0x0000227d },
+ { 0x00000bbc, 0x00002294 },
+ { 0x00000bc0, 0x000022ab },
+ { 0x00000bc4, 0x000022c2 },
+ { 0x00000bc8, 0x000022da },
+ { 0x00000bcc, 0x000022f1 },
+ { 0x00000bd0, 0x00002308 },
+ { 0x00000bd4, 0x0000231f },
+ { 0x00000bd8, 0x00002337 },
+ { 0x00000bdc, 0x0000234e },
+ { 0x00000be0, 0x00002365 },
+ { 0x00000be4, 0x0000237d },
+ { 0x00000be8, 0x00002394 },
+ { 0x00000bec, 0x000023ac },
+ { 0x00000bf0, 0x000023c3 },
+ { 0x00000bf4, 0x000023db },
+ { 0x00000bf8, 0x000023f2 },
+ { 0x00000bfc, 0x0000240a },
+ { 0x00000c00, 0x00002421 },
+ { 0x00000c04, 0x00002439 },
+ { 0x00000c08, 0x00002451 },
+ { 0x00000c0c, 0x00002469 },
+ { 0x00000c10, 0x00002480 },
+ { 0x00000c14, 0x00002498 },
+ { 0x00000c18, 0x000024b0 },
+ { 0x00000c1c, 0x000024c8 },
+ { 0x00000c20, 0x000024e0 },
+ { 0x00000c24, 0x000024f8 },
+ { 0x00000c28, 0x00002510 },
+ { 0x00000c2c, 0x00002528 },
+ { 0x00000c30, 0x00002540 },
+ { 0x00000c34, 0x00002558 },
+ { 0x00000c38, 0x00002570 },
+ { 0x00000c3c, 0x00002588 },
+ { 0x00000c40, 0x000025a0 },
+ { 0x00000c44, 0x000025b8 },
+ { 0x00000c48, 0x000025d0 },
+ { 0x00000c4c, 0x000025e9 },
+ { 0x00000c50, 0x00002601 },
+ { 0x00000c54, 0x00002619 },
+ { 0x00000c58, 0x00002632 },
+ { 0x00000c5c, 0x0000264a },
+ { 0x00000c60, 0x00002663 },
+ { 0x00000c64, 0x0000267b },
+ { 0x00000c68, 0x00002693 },
+ { 0x00000c6c, 0x000026ac },
+ { 0x00000c70, 0x000026c5 },
+ { 0x00000c74, 0x000026dd },
+ { 0x00000c78, 0x000026f6 },
+ { 0x00000c7c, 0x0000270e },
+ { 0x00000c80, 0x00002727 },
+ { 0x00000c84, 0x00002740 },
+ { 0x00000c88, 0x00002759 },
+ { 0x00000c8c, 0x00002771 },
+ { 0x00000c90, 0x0000278a },
+ { 0x00000c94, 0x000027a3 },
+ { 0x00000c98, 0x000027bc },
+ { 0x00000c9c, 0x000027d5 },
+ { 0x00000ca0, 0x000027ee },
+ { 0x00000ca4, 0x00002807 },
+ { 0x00000ca8, 0x00002820 },
+ { 0x00000cac, 0x00002839 },
+ { 0x00000cb0, 0x00002852 },
+ { 0x00000cb4, 0x0000286b },
+ { 0x00000cb8, 0x00002884 },
+ { 0x00000cbc, 0x0000289e },
+ { 0x00000cc0, 0x000028b7 },
+ { 0x00000cc4, 0x000028d0 },
+ { 0x00000cc8, 0x000028e9 },
+ { 0x00000ccc, 0x00002903 },
+ { 0x00000cd0, 0x0000291c },
+ { 0x00000cd4, 0x00002936 },
+ { 0x00000cd8, 0x0000294f },
+ { 0x00000cdc, 0x00002968 },
+ { 0x00000ce0, 0x00002982 },
+ { 0x00000ce4, 0x0000299c },
+ { 0x00000ce8, 0x000029b5 },
+ { 0x00000cec, 0x000029cf },
+ { 0x00000cf0, 0x000029e8 },
+ { 0x00000cf4, 0x00002a02 },
+ { 0x00000cf8, 0x00002a1c },
+ { 0x00000cfc, 0x00002a35 },
+ { 0x00000d00, 0x00002a4f },
+ { 0x00000d04, 0x00002a69 },
+ { 0x00000d08, 0x00002a83 },
+ { 0x00000d0c, 0x00002a9d },
+ { 0x00000d10, 0x00002ab7 },
+ { 0x00000d14, 0x00002ad1 },
+ { 0x00000d18, 0x00002aeb },
+ { 0x00000d1c, 0x00002b05 },
+ { 0x00000d20, 0x00002b1f },
+ { 0x00000d24, 0x00002b39 },
+ { 0x00000d28, 0x00002b53 },
+ { 0x00000d2c, 0x00002b6d },
+ { 0x00000d30, 0x00002b87 },
+ { 0x00000d34, 0x00002ba1 },
+ { 0x00000d38, 0x00002bbc },
+ { 0x00000d3c, 0x00002bd6 },
+ { 0x00000d40, 0x00002bf0 },
+ { 0x00000d44, 0x00002c0b },
+ { 0x00000d48, 0x00002c25 },
+ { 0x00000d4c, 0x00002c3f },
+ { 0x00000d50, 0x00002c5a },
+ { 0x00000d54, 0x00002c74 },
+ { 0x00000d58, 0x00002c8f },
+ { 0x00000d5c, 0x00002ca9 },
+ { 0x00000d60, 0x00002cc4 },
+ { 0x00000d64, 0x00002cdf },
+ { 0x00000d68, 0x00002cf9 },
+ { 0x00000d6c, 0x00002d14 },
+ { 0x00000d70, 0x00002d2f },
+ { 0x00000d74, 0x00002d49 },
+ { 0x00000d78, 0x00002d64 },
+ { 0x00000d7c, 0x00002d7f },
+ { 0x00000d80, 0x00002d9a },
+ { 0x00000d84, 0x00002db5 },
+ { 0x00000d88, 0x00002dd0 },
+ { 0x00000d8c, 0x00002deb },
+ { 0x00000d90, 0x00002e06 },
+ { 0x00000d94, 0x00002e21 },
+ { 0x00000d98, 0x00002e3c },
+ { 0x00000d9c, 0x00002e57 },
+ { 0x00000da0, 0x00002e72 },
+ { 0x00000da4, 0x00002e8d },
+ { 0x00000da8, 0x00002ea8 },
+ { 0x00000dac, 0x00002ec4 },
+ { 0x00000db0, 0x00002edf },
+ { 0x00000db4, 0x00002efa },
+ { 0x00000db8, 0x00002f16 },
+ { 0x00000dbc, 0x00002f31 },
+ { 0x00000dc0, 0x00002f4c },
+ { 0x00000dc4, 0x00002f68 },
+ { 0x00000dc8, 0x00002f83 },
+ { 0x00000dcc, 0x00002f9f },
+ { 0x00000dd0, 0x00002fba },
+ { 0x00000dd4, 0x00002fd6 },
+ { 0x00000dd8, 0x00002ff1 },
+ { 0x00000ddc, 0x0000300d },
+ { 0x00000de0, 0x00003029 },
+ { 0x00000de4, 0x00003044 },
+ { 0x00000de8, 0x00003060 },
+ { 0x00000dec, 0x0000307c },
+ { 0x00000df0, 0x00003098 },
+ { 0x00000df4, 0x000030b4 },
+ { 0x00000df8, 0x000030d0 },
+ { 0x00000dfc, 0x000030eb },
+ { 0x00000e00, 0x00003107 },
+ { 0x00000e04, 0x00003123 },
+ { 0x00000e08, 0x0000313f },
+ { 0x00000e0c, 0x0000315b },
+ { 0x00000e10, 0x00003178 },
+ { 0x00000e14, 0x00003194 },
+ { 0x00000e18, 0x000031b0 },
+ { 0x00000e1c, 0x000031cc },
+ { 0x00000e20, 0x000031e8 },
+ { 0x00000e24, 0x00003205 },
+ { 0x00000e28, 0x00003221 },
+ { 0x00000e2c, 0x0000323d },
+ { 0x00000e30, 0x0000325a },
+ { 0x00000e34, 0x00003276 },
+ { 0x00000e38, 0x00003292 },
+ { 0x00000e3c, 0x000032af },
+ { 0x00000e40, 0x000032cb },
+ { 0x00000e44, 0x000032e8 },
+ { 0x00000e48, 0x00003304 },
+ { 0x00000e4c, 0x00003321 },
+ { 0x00000e50, 0x0000333e },
+ { 0x00000e54, 0x0000335a },
+ { 0x00000e58, 0x00003377 },
+ { 0x00000e5c, 0x00003394 },
+ { 0x00000e60, 0x000033b1 },
+ { 0x00000e64, 0x000033cd },
+ { 0x00000e68, 0x000033ea },
+ { 0x00000e6c, 0x00003407 },
+ { 0x00000e70, 0x00003424 },
+ { 0x00000e74, 0x00003441 },
+ { 0x00000e78, 0x0000345e },
+ { 0x00000e7c, 0x0000347b },
+ { 0x00000e80, 0x00003498 },
+ { 0x00000e84, 0x000034b5 },
+ { 0x00000e88, 0x000034d2 },
+ { 0x00000e8c, 0x000034ef },
+ { 0x00000e90, 0x0000350d },
+ { 0x00000e94, 0x0000352a },
+ { 0x00000e98, 0x00003547 },
+ { 0x00000e9c, 0x00003564 },
+ { 0x00000ea0, 0x00003582 },
+ { 0x00000ea4, 0x0000359f },
+ { 0x00000ea8, 0x000035bc },
+ { 0x00000eac, 0x000035da },
+ { 0x00000eb0, 0x000035f7 },
+ { 0x00000eb4, 0x00003615 },
+ { 0x00000eb8, 0x00003632 },
+ { 0x00000ebc, 0x00003650 },
+ { 0x00000ec0, 0x0000366e },
+ { 0x00000ec4, 0x0000368b },
+ { 0x00000ec8, 0x000036a9 },
+ { 0x00000ecc, 0x000036c7 },
+ { 0x00000ed0, 0x000036e4 },
+ { 0x00000ed4, 0x00003702 },
+ { 0x00000ed8, 0x00003720 },
+ { 0x00000edc, 0x0000373e },
+ { 0x00000ee0, 0x0000375c },
+ { 0x00000ee4, 0x0000377a },
+ { 0x00000ee8, 0x00003798 },
+ { 0x00000eec, 0x000037b6 },
+ { 0x00000ef0, 0x000037d4 },
+ { 0x00000ef4, 0x000037f2 },
+ { 0x00000ef8, 0x00003810 },
+ { 0x00000efc, 0x0000382e },
+ { 0x00000f00, 0x0000384c },
+ { 0x00000f04, 0x0000386a },
+ { 0x00000f08, 0x00003888 },
+ { 0x00000f0c, 0x000038a7 },
+ { 0x00000f10, 0x000038c5 },
+ { 0x00000f14, 0x000038e3 },
+ { 0x00000f18, 0x00003902 },
+ { 0x00000f1c, 0x00003920 },
+ { 0x00000f20, 0x0000393f },
+ { 0x00000f24, 0x0000395d },
+ { 0x00000f28, 0x0000397c },
+ { 0x00000f2c, 0x0000399a },
+ { 0x00000f30, 0x000039b9 },
+ { 0x00000f34, 0x000039d7 },
+ { 0x00000f38, 0x000039f6 },
+ { 0x00000f3c, 0x00003a15 },
+ { 0x00000f40, 0x00003a33 },
+ { 0x00000f44, 0x00003a52 },
+ { 0x00000f48, 0x00003a71 },
+ { 0x00000f4c, 0x00003a90 },
+ { 0x00000f50, 0x00003aaf },
+ { 0x00000f54, 0x00003acd },
+ { 0x00000f58, 0x00003aec },
+ { 0x00000f5c, 0x00003b0b },
+ { 0x00000f60, 0x00003b2a },
+ { 0x00000f64, 0x00003b49 },
+ { 0x00000f68, 0x00003b68 },
+ { 0x00000f6c, 0x00003b87 },
+ { 0x00000f70, 0x00003ba7 },
+ { 0x00000f74, 0x00003bc6 },
+ { 0x00000f78, 0x00003be5 },
+ { 0x00000f7c, 0x00003c04 },
+ { 0x00000f80, 0x00003c24 },
+ { 0x00000f84, 0x00003c43 },
+ { 0x00000f88, 0x00003c62 },
+ { 0x00000f8c, 0x00003c82 },
+ { 0x00000f90, 0x00003ca1 },
+ { 0x00000f94, 0x00003cc0 },
+ { 0x00000f98, 0x00003ce0 },
+ { 0x00000f9c, 0x00003cff },
+ { 0x00000fa0, 0x00003d1f },
+ { 0x00000fa4, 0x00003d3f },
+ { 0x00000fa8, 0x00003d5e },
+ { 0x00000fac, 0x00003d7e },
+ { 0x00000fb0, 0x00003d9e },
+ { 0x00000fb4, 0x00003dbd },
+ { 0x00000fb8, 0x00003ddd },
+ { 0x00000fbc, 0x00003dfd },
+ { 0x00000fc0, 0x00003e1d },
+ { 0x00000fc4, 0x00003e3d },
+ { 0x00000fc8, 0x00003e5d },
+ { 0x00000fcc, 0x00003e7c },
+ { 0x00000fd0, 0x00003e9c },
+ { 0x00000fd4, 0x00003ebc },
+ { 0x00000fd8, 0x00003edc },
+ { 0x00000fdc, 0x00003efd },
+ { 0x00000fe0, 0x00003f1d },
+ { 0x00000fe4, 0x00003f3d },
+ { 0x00000fe8, 0x00003f5d },
+ { 0x00000fec, 0x00003f7d },
+ { 0x00000ff0, 0x00003f9e },
+ { 0x00000ff4, 0x00003fbe },
+ { 0x00000ff8, 0x00003fde },
+ { 0x00000ffc, 0x00003fff },
+};
+
+struct data_unit hdr10_pipe1_lut_a1[] = {
+ { 0x00001000, 0x00000000 },
+ { 0x00001004, 0x00000003 },
+ { 0x00001008, 0x00000007 },
+ { 0x0000100c, 0x0000000a },
+ { 0x00001010, 0x0000000e },
+ { 0x00001014, 0x00000011 },
+ { 0x00001018, 0x00000015 },
+ { 0x0000101c, 0x00000018 },
+ { 0x00001020, 0x0000001c },
+ { 0x00001024, 0x00000020 },
+ { 0x00001028, 0x00000023 },
+ { 0x0000102c, 0x00000027 },
+ { 0x00001030, 0x0000002a },
+ { 0x00001034, 0x0000002e },
+ { 0x00001038, 0x00000031 },
+ { 0x0000103c, 0x00000035 },
+ { 0x00001040, 0x00000038 },
+ { 0x00001044, 0x0000003c },
+ { 0x00001048, 0x00000040 },
+ { 0x0000104c, 0x00000043 },
+ { 0x00001050, 0x00000047 },
+ { 0x00001054, 0x0000004a },
+ { 0x00001058, 0x0000004e },
+ { 0x0000105c, 0x00000051 },
+ { 0x00001060, 0x00000055 },
+ { 0x00001064, 0x00000058 },
+ { 0x00001068, 0x0000005c },
+ { 0x0000106c, 0x00000060 },
+ { 0x00001070, 0x00000063 },
+ { 0x00001074, 0x00000067 },
+ { 0x00001078, 0x0000006a },
+ { 0x0000107c, 0x0000006e },
+ { 0x00001080, 0x00000071 },
+ { 0x00001084, 0x00000075 },
+ { 0x00001088, 0x00000078 },
+ { 0x0000108c, 0x0000007c },
+ { 0x00001090, 0x00000080 },
+ { 0x00001094, 0x00000083 },
+ { 0x00001098, 0x00000087 },
+ { 0x0000109c, 0x0000008a },
+ { 0x000010a0, 0x0000008e },
+ { 0x000010a4, 0x00000091 },
+ { 0x000010a8, 0x00000095 },
+ { 0x000010ac, 0x00000099 },
+ { 0x000010b0, 0x0000009c },
+ { 0x000010b4, 0x000000a0 },
+ { 0x000010b8, 0x000000a3 },
+ { 0x000010bc, 0x000000a7 },
+ { 0x000010c0, 0x000000aa },
+ { 0x000010c4, 0x000000ae },
+ { 0x000010c8, 0x000000b1 },
+ { 0x000010cc, 0x000000b5 },
+ { 0x000010d0, 0x000000b9 },
+ { 0x000010d4, 0x000000bc },
+ { 0x000010d8, 0x000000c0 },
+ { 0x000010dc, 0x000000c3 },
+ { 0x000010e0, 0x000000c7 },
+ { 0x000010e4, 0x000000ca },
+ { 0x000010e8, 0x000000ce },
+ { 0x000010ec, 0x000000d1 },
+ { 0x000010f0, 0x000000d5 },
+ { 0x000010f4, 0x000000d9 },
+ { 0x000010f8, 0x000000dc },
+ { 0x000010fc, 0x000000e0 },
+ { 0x00001100, 0x000000e3 },
+ { 0x00001104, 0x000000e7 },
+ { 0x00001108, 0x000000ea },
+ { 0x0000110c, 0x000000ee },
+ { 0x00001110, 0x000000f1 },
+ { 0x00001114, 0x000000f5 },
+ { 0x00001118, 0x000000f9 },
+ { 0x0000111c, 0x000000fc },
+ { 0x00001120, 0x00000100 },
+ { 0x00001124, 0x00000103 },
+ { 0x00001128, 0x00000107 },
+ { 0x0000112c, 0x0000010a },
+ { 0x00001130, 0x0000010e },
+ { 0x00001134, 0x00000112 },
+ { 0x00001138, 0x00000115 },
+ { 0x0000113c, 0x00000119 },
+ { 0x00001140, 0x0000011c },
+ { 0x00001144, 0x00000120 },
+ { 0x00001148, 0x00000123 },
+ { 0x0000114c, 0x00000126 },
+ { 0x00001150, 0x0000012a },
+ { 0x00001154, 0x0000012d },
+ { 0x00001158, 0x00000131 },
+ { 0x0000115c, 0x00000134 },
+ { 0x00001160, 0x00000138 },
+ { 0x00001164, 0x0000013c },
+ { 0x00001168, 0x0000013f },
+ { 0x0000116c, 0x00000143 },
+ { 0x00001170, 0x00000147 },
+ { 0x00001174, 0x0000014b },
+ { 0x00001178, 0x0000014e },
+ { 0x0000117c, 0x00000152 },
+ { 0x00001180, 0x00000156 },
+ { 0x00001184, 0x0000015a },
+ { 0x00001188, 0x0000015e },
+ { 0x0000118c, 0x00000162 },
+ { 0x00001190, 0x00000166 },
+ { 0x00001194, 0x0000016a },
+ { 0x00001198, 0x0000016e },
+ { 0x0000119c, 0x00000172 },
+ { 0x000011a0, 0x00000176 },
+ { 0x000011a4, 0x0000017a },
+ { 0x000011a8, 0x0000017e },
+ { 0x000011ac, 0x00000182 },
+ { 0x000011b0, 0x00000186 },
+ { 0x000011b4, 0x0000018a },
+ { 0x000011b8, 0x0000018f },
+ { 0x000011bc, 0x00000193 },
+ { 0x000011c0, 0x00000197 },
+ { 0x000011c4, 0x0000019b },
+ { 0x000011c8, 0x000001a0 },
+ { 0x000011cc, 0x000001a4 },
+ { 0x000011d0, 0x000001a8 },
+ { 0x000011d4, 0x000001ad },
+ { 0x000011d8, 0x000001b1 },
+ { 0x000011dc, 0x000001b5 },
+ { 0x000011e0, 0x000001ba },
+ { 0x000011e4, 0x000001be },
+ { 0x000011e8, 0x000001c3 },
+ { 0x000011ec, 0x000001c7 },
+ { 0x000011f0, 0x000001cc },
+ { 0x000011f4, 0x000001d0 },
+ { 0x000011f8, 0x000001d5 },
+ { 0x000011fc, 0x000001d9 },
+ { 0x00001200, 0x000001de },
+ { 0x00001204, 0x000001e3 },
+ { 0x00001208, 0x000001e7 },
+ { 0x0000120c, 0x000001ec },
+ { 0x00001210, 0x000001f1 },
+ { 0x00001214, 0x000001f6 },
+ { 0x00001218, 0x000001fa },
+ { 0x0000121c, 0x000001ff },
+ { 0x00001220, 0x00000204 },
+ { 0x00001224, 0x00000209 },
+ { 0x00001228, 0x0000020e },
+ { 0x0000122c, 0x00000213 },
+ { 0x00001230, 0x00000217 },
+ { 0x00001234, 0x0000021c },
+ { 0x00001238, 0x00000221 },
+ { 0x0000123c, 0x00000226 },
+ { 0x00001240, 0x0000022b },
+ { 0x00001244, 0x00000230 },
+ { 0x00001248, 0x00000236 },
+ { 0x0000124c, 0x0000023b },
+ { 0x00001250, 0x00000240 },
+ { 0x00001254, 0x00000245 },
+ { 0x00001258, 0x0000024a },
+ { 0x0000125c, 0x0000024f },
+ { 0x00001260, 0x00000255 },
+ { 0x00001264, 0x0000025a },
+ { 0x00001268, 0x0000025f },
+ { 0x0000126c, 0x00000264 },
+ { 0x00001270, 0x0000026a },
+ { 0x00001274, 0x0000026f },
+ { 0x00001278, 0x00000274 },
+ { 0x0000127c, 0x0000027a },
+ { 0x00001280, 0x0000027f },
+ { 0x00001284, 0x00000285 },
+ { 0x00001288, 0x0000028a },
+ { 0x0000128c, 0x00000290 },
+ { 0x00001290, 0x00000295 },
+ { 0x00001294, 0x0000029b },
+ { 0x00001298, 0x000002a0 },
+ { 0x0000129c, 0x000002a6 },
+ { 0x000012a0, 0x000002ac },
+ { 0x000012a4, 0x000002b1 },
+ { 0x000012a8, 0x000002b7 },
+ { 0x000012ac, 0x000002bd },
+ { 0x000012b0, 0x000002c2 },
+ { 0x000012b4, 0x000002c8 },
+ { 0x000012b8, 0x000002ce },
+ { 0x000012bc, 0x000002d4 },
+ { 0x000012c0, 0x000002da },
+ { 0x000012c4, 0x000002df },
+ { 0x000012c8, 0x000002e5 },
+ { 0x000012cc, 0x000002eb },
+ { 0x000012d0, 0x000002f1 },
+ { 0x000012d4, 0x000002f7 },
+ { 0x000012d8, 0x000002fd },
+ { 0x000012dc, 0x00000303 },
+ { 0x000012e0, 0x00000309 },
+ { 0x000012e4, 0x0000030f },
+ { 0x000012e8, 0x00000315 },
+ { 0x000012ec, 0x0000031c },
+ { 0x000012f0, 0x00000322 },
+ { 0x000012f4, 0x00000328 },
+ { 0x000012f8, 0x0000032e },
+ { 0x000012fc, 0x00000334 },
+ { 0x00001300, 0x0000033b },
+ { 0x00001304, 0x00000341 },
+ { 0x00001308, 0x00000347 },
+ { 0x0000130c, 0x0000034d },
+ { 0x00001310, 0x00000354 },
+ { 0x00001314, 0x0000035a },
+ { 0x00001318, 0x00000361 },
+ { 0x0000131c, 0x00000367 },
+ { 0x00001320, 0x0000036d },
+ { 0x00001324, 0x00000374 },
+ { 0x00001328, 0x0000037a },
+ { 0x0000132c, 0x00000381 },
+ { 0x00001330, 0x00000388 },
+ { 0x00001334, 0x0000038e },
+ { 0x00001338, 0x00000395 },
+ { 0x0000133c, 0x0000039b },
+ { 0x00001340, 0x000003a2 },
+ { 0x00001344, 0x000003a9 },
+ { 0x00001348, 0x000003b0 },
+ { 0x0000134c, 0x000003b6 },
+ { 0x00001350, 0x000003bd },
+ { 0x00001354, 0x000003c4 },
+ { 0x00001358, 0x000003cb },
+ { 0x0000135c, 0x000003d2 },
+ { 0x00001360, 0x000003d8 },
+ { 0x00001364, 0x000003df },
+ { 0x00001368, 0x000003e6 },
+ { 0x0000136c, 0x000003ed },
+ { 0x00001370, 0x000003f4 },
+ { 0x00001374, 0x000003fb },
+ { 0x00001378, 0x00000402 },
+ { 0x0000137c, 0x00000409 },
+ { 0x00001380, 0x00000411 },
+ { 0x00001384, 0x00000418 },
+ { 0x00001388, 0x0000041f },
+ { 0x0000138c, 0x00000426 },
+ { 0x00001390, 0x0000042d },
+ { 0x00001394, 0x00000434 },
+ { 0x00001398, 0x0000043c },
+ { 0x0000139c, 0x00000443 },
+ { 0x000013a0, 0x0000044a },
+ { 0x000013a4, 0x00000452 },
+ { 0x000013a8, 0x00000459 },
+ { 0x000013ac, 0x00000460 },
+ { 0x000013b0, 0x00000468 },
+ { 0x000013b4, 0x0000046f },
+ { 0x000013b8, 0x00000477 },
+ { 0x000013bc, 0x0000047e },
+ { 0x000013c0, 0x00000486 },
+ { 0x000013c4, 0x0000048d },
+ { 0x000013c8, 0x00000495 },
+ { 0x000013cc, 0x0000049c },
+ { 0x000013d0, 0x000004a4 },
+ { 0x000013d4, 0x000004ac },
+ { 0x000013d8, 0x000004b3 },
+ { 0x000013dc, 0x000004bb },
+ { 0x000013e0, 0x000004c3 },
+ { 0x000013e4, 0x000004cb },
+ { 0x000013e8, 0x000004d3 },
+ { 0x000013ec, 0x000004da },
+ { 0x000013f0, 0x000004e2 },
+ { 0x000013f4, 0x000004ea },
+ { 0x000013f8, 0x000004f2 },
+ { 0x000013fc, 0x000004fa },
+ { 0x00001400, 0x00000502 },
+ { 0x00001404, 0x0000050a },
+ { 0x00001408, 0x00000512 },
+ { 0x0000140c, 0x0000051a },
+ { 0x00001410, 0x00000522 },
+ { 0x00001414, 0x0000052a },
+ { 0x00001418, 0x00000532 },
+ { 0x0000141c, 0x0000053a },
+ { 0x00001420, 0x00000543 },
+ { 0x00001424, 0x0000054b },
+ { 0x00001428, 0x00000553 },
+ { 0x0000142c, 0x0000055b },
+ { 0x00001430, 0x00000564 },
+ { 0x00001434, 0x0000056c },
+ { 0x00001438, 0x00000574 },
+ { 0x0000143c, 0x0000057d },
+ { 0x00001440, 0x00000585 },
+ { 0x00001444, 0x0000058d },
+ { 0x00001448, 0x00000596 },
+ { 0x0000144c, 0x0000059e },
+ { 0x00001450, 0x000005a7 },
+ { 0x00001454, 0x000005af },
+ { 0x00001458, 0x000005b8 },
+ { 0x0000145c, 0x000005c1 },
+ { 0x00001460, 0x000005c9 },
+ { 0x00001464, 0x000005d2 },
+ { 0x00001468, 0x000005db },
+ { 0x0000146c, 0x000005e3 },
+ { 0x00001470, 0x000005ec },
+ { 0x00001474, 0x000005f5 },
+ { 0x00001478, 0x000005fe },
+ { 0x0000147c, 0x00000606 },
+ { 0x00001480, 0x0000060f },
+ { 0x00001484, 0x00000618 },
+ { 0x00001488, 0x00000621 },
+ { 0x0000148c, 0x0000062a },
+ { 0x00001490, 0x00000633 },
+ { 0x00001494, 0x0000063c },
+ { 0x00001498, 0x00000645 },
+ { 0x0000149c, 0x0000064e },
+ { 0x000014a0, 0x00000657 },
+ { 0x000014a4, 0x00000660 },
+ { 0x000014a8, 0x00000669 },
+ { 0x000014ac, 0x00000672 },
+ { 0x000014b0, 0x0000067b },
+ { 0x000014b4, 0x00000685 },
+ { 0x000014b8, 0x0000068e },
+ { 0x000014bc, 0x00000697 },
+ { 0x000014c0, 0x000006a0 },
+ { 0x000014c4, 0x000006aa },
+ { 0x000014c8, 0x000006b3 },
+ { 0x000014cc, 0x000006bd },
+ { 0x000014d0, 0x000006c6 },
+ { 0x000014d4, 0x000006cf },
+ { 0x000014d8, 0x000006d9 },
+ { 0x000014dc, 0x000006e2 },
+ { 0x000014e0, 0x000006ec },
+ { 0x000014e4, 0x000006f5 },
+ { 0x000014e8, 0x000006ff },
+ { 0x000014ec, 0x00000709 },
+ { 0x000014f0, 0x00000712 },
+ { 0x000014f4, 0x0000071c },
+ { 0x000014f8, 0x00000726 },
+ { 0x000014fc, 0x0000072f },
+ { 0x00001500, 0x00000739 },
+ { 0x00001504, 0x00000743 },
+ { 0x00001508, 0x0000074d },
+ { 0x0000150c, 0x00000756 },
+ { 0x00001510, 0x00000760 },
+ { 0x00001514, 0x0000076a },
+ { 0x00001518, 0x00000774 },
+ { 0x0000151c, 0x0000077e },
+ { 0x00001520, 0x00000788 },
+ { 0x00001524, 0x00000792 },
+ { 0x00001528, 0x0000079c },
+ { 0x0000152c, 0x000007a6 },
+ { 0x00001530, 0x000007b0 },
+ { 0x00001534, 0x000007ba },
+ { 0x00001538, 0x000007c4 },
+ { 0x0000153c, 0x000007cf },
+ { 0x00001540, 0x000007d9 },
+ { 0x00001544, 0x000007e3 },
+ { 0x00001548, 0x000007ed },
+ { 0x0000154c, 0x000007f7 },
+ { 0x00001550, 0x00000802 },
+ { 0x00001554, 0x0000080c },
+ { 0x00001558, 0x00000816 },
+ { 0x0000155c, 0x00000821 },
+ { 0x00001560, 0x0000082b },
+ { 0x00001564, 0x00000836 },
+ { 0x00001568, 0x00000840 },
+ { 0x0000156c, 0x0000084b },
+ { 0x00001570, 0x00000855 },
+ { 0x00001574, 0x00000860 },
+ { 0x00001578, 0x0000086a },
+ { 0x0000157c, 0x00000875 },
+ { 0x00001580, 0x00000880 },
+ { 0x00001584, 0x0000088a },
+ { 0x00001588, 0x00000895 },
+ { 0x0000158c, 0x000008a0 },
+ { 0x00001590, 0x000008ab },
+ { 0x00001594, 0x000008b5 },
+ { 0x00001598, 0x000008c0 },
+ { 0x0000159c, 0x000008cb },
+ { 0x000015a0, 0x000008d6 },
+ { 0x000015a4, 0x000008e1 },
+ { 0x000015a8, 0x000008ec },
+ { 0x000015ac, 0x000008f7 },
+ { 0x000015b0, 0x00000902 },
+ { 0x000015b4, 0x0000090d },
+ { 0x000015b8, 0x00000918 },
+ { 0x000015bc, 0x00000923 },
+ { 0x000015c0, 0x0000092e },
+ { 0x000015c4, 0x00000939 },
+ { 0x000015c8, 0x00000944 },
+ { 0x000015cc, 0x00000950 },
+ { 0x000015d0, 0x0000095b },
+ { 0x000015d4, 0x00000966 },
+ { 0x000015d8, 0x00000971 },
+ { 0x000015dc, 0x0000097d },
+ { 0x000015e0, 0x00000988 },
+ { 0x000015e4, 0x00000993 },
+ { 0x000015e8, 0x0000099f },
+ { 0x000015ec, 0x000009aa },
+ { 0x000015f0, 0x000009b6 },
+ { 0x000015f4, 0x000009c1 },
+ { 0x000015f8, 0x000009cd },
+ { 0x000015fc, 0x000009d8 },
+ { 0x00001600, 0x000009e4 },
+ { 0x00001604, 0x000009f0 },
+ { 0x00001608, 0x000009fb },
+ { 0x0000160c, 0x00000a07 },
+ { 0x00001610, 0x00000a13 },
+ { 0x00001614, 0x00000a1e },
+ { 0x00001618, 0x00000a2a },
+ { 0x0000161c, 0x00000a36 },
+ { 0x00001620, 0x00000a42 },
+ { 0x00001624, 0x00000a4e },
+ { 0x00001628, 0x00000a59 },
+ { 0x0000162c, 0x00000a65 },
+ { 0x00001630, 0x00000a71 },
+ { 0x00001634, 0x00000a7d },
+ { 0x00001638, 0x00000a89 },
+ { 0x0000163c, 0x00000a95 },
+ { 0x00001640, 0x00000aa1 },
+ { 0x00001644, 0x00000aad },
+ { 0x00001648, 0x00000ab9 },
+ { 0x0000164c, 0x00000ac6 },
+ { 0x00001650, 0x00000ad2 },
+ { 0x00001654, 0x00000ade },
+ { 0x00001658, 0x00000aea },
+ { 0x0000165c, 0x00000af6 },
+ { 0x00001660, 0x00000b03 },
+ { 0x00001664, 0x00000b0f },
+ { 0x00001668, 0x00000b1b },
+ { 0x0000166c, 0x00000b28 },
+ { 0x00001670, 0x00000b34 },
+ { 0x00001674, 0x00000b41 },
+ { 0x00001678, 0x00000b4d },
+ { 0x0000167c, 0x00000b5a },
+ { 0x00001680, 0x00000b66 },
+ { 0x00001684, 0x00000b73 },
+ { 0x00001688, 0x00000b7f },
+ { 0x0000168c, 0x00000b8c },
+ { 0x00001690, 0x00000b98 },
+ { 0x00001694, 0x00000ba5 },
+ { 0x00001698, 0x00000bb2 },
+ { 0x0000169c, 0x00000bbf },
+ { 0x000016a0, 0x00000bcb },
+ { 0x000016a4, 0x00000bd8 },
+ { 0x000016a8, 0x00000be5 },
+ { 0x000016ac, 0x00000bf2 },
+ { 0x000016b0, 0x00000bff },
+ { 0x000016b4, 0x00000c0c },
+ { 0x000016b8, 0x00000c19 },
+ { 0x000016bc, 0x00000c25 },
+ { 0x000016c0, 0x00000c32 },
+ { 0x000016c4, 0x00000c40 },
+ { 0x000016c8, 0x00000c4d },
+ { 0x000016cc, 0x00000c5a },
+ { 0x000016d0, 0x00000c67 },
+ { 0x000016d4, 0x00000c74 },
+ { 0x000016d8, 0x00000c81 },
+ { 0x000016dc, 0x00000c8e },
+ { 0x000016e0, 0x00000c9c },
+ { 0x000016e4, 0x00000ca9 },
+ { 0x000016e8, 0x00000cb6 },
+ { 0x000016ec, 0x00000cc3 },
+ { 0x000016f0, 0x00000cd1 },
+ { 0x000016f4, 0x00000cde },
+ { 0x000016f8, 0x00000cec },
+ { 0x000016fc, 0x00000cf9 },
+ { 0x00001700, 0x00000d07 },
+ { 0x00001704, 0x00000d14 },
+ { 0x00001708, 0x00000d22 },
+ { 0x0000170c, 0x00000d2f },
+ { 0x00001710, 0x00000d3d },
+ { 0x00001714, 0x00000d4a },
+ { 0x00001718, 0x00000d58 },
+ { 0x0000171c, 0x00000d66 },
+ { 0x00001720, 0x00000d73 },
+ { 0x00001724, 0x00000d81 },
+ { 0x00001728, 0x00000d8f },
+ { 0x0000172c, 0x00000d9d },
+ { 0x00001730, 0x00000dab },
+ { 0x00001734, 0x00000db8 },
+ { 0x00001738, 0x00000dc6 },
+ { 0x0000173c, 0x00000dd4 },
+ { 0x00001740, 0x00000de2 },
+ { 0x00001744, 0x00000df0 },
+ { 0x00001748, 0x00000dfe },
+ { 0x0000174c, 0x00000e0c },
+ { 0x00001750, 0x00000e1a },
+ { 0x00001754, 0x00000e29 },
+ { 0x00001758, 0x00000e37 },
+ { 0x0000175c, 0x00000e45 },
+ { 0x00001760, 0x00000e53 },
+ { 0x00001764, 0x00000e61 },
+ { 0x00001768, 0x00000e70 },
+ { 0x0000176c, 0x00000e7e },
+ { 0x00001770, 0x00000e8c },
+ { 0x00001774, 0x00000e9a },
+ { 0x00001778, 0x00000ea9 },
+ { 0x0000177c, 0x00000eb7 },
+ { 0x00001780, 0x00000ec6 },
+ { 0x00001784, 0x00000ed4 },
+ { 0x00001788, 0x00000ee3 },
+ { 0x0000178c, 0x00000ef1 },
+ { 0x00001790, 0x00000f00 },
+ { 0x00001794, 0x00000f0e },
+ { 0x00001798, 0x00000f1d },
+ { 0x0000179c, 0x00000f2c },
+ { 0x000017a0, 0x00000f3a },
+ { 0x000017a4, 0x00000f49 },
+ { 0x000017a8, 0x00000f58 },
+ { 0x000017ac, 0x00000f67 },
+ { 0x000017b0, 0x00000f75 },
+ { 0x000017b4, 0x00000f84 },
+ { 0x000017b8, 0x00000f93 },
+ { 0x000017bc, 0x00000fa2 },
+ { 0x000017c0, 0x00000fb1 },
+ { 0x000017c4, 0x00000fc0 },
+ { 0x000017c8, 0x00000fcf },
+ { 0x000017cc, 0x00000fde },
+ { 0x000017d0, 0x00000fed },
+ { 0x000017d4, 0x00000ffc },
+ { 0x000017d8, 0x0000100b },
+ { 0x000017dc, 0x0000101a },
+ { 0x000017e0, 0x0000102a },
+ { 0x000017e4, 0x00001039 },
+ { 0x000017e8, 0x00001048 },
+ { 0x000017ec, 0x00001057 },
+ { 0x000017f0, 0x00001067 },
+ { 0x000017f4, 0x00001076 },
+ { 0x000017f8, 0x00001085 },
+ { 0x000017fc, 0x00001095 },
+ { 0x00001800, 0x000010a4 },
+ { 0x00001804, 0x000010b4 },
+ { 0x00001808, 0x000010c3 },
+ { 0x0000180c, 0x000010d3 },
+ { 0x00001810, 0x000010e2 },
+ { 0x00001814, 0x000010f2 },
+ { 0x00001818, 0x00001101 },
+ { 0x0000181c, 0x00001111 },
+ { 0x00001820, 0x00001121 },
+ { 0x00001824, 0x00001130 },
+ { 0x00001828, 0x00001140 },
+ { 0x0000182c, 0x00001150 },
+ { 0x00001830, 0x00001160 },
+ { 0x00001834, 0x0000116f },
+ { 0x00001838, 0x0000117f },
+ { 0x0000183c, 0x0000118f },
+ { 0x00001840, 0x0000119f },
+ { 0x00001844, 0x000011af },
+ { 0x00001848, 0x000011bf },
+ { 0x0000184c, 0x000011cf },
+ { 0x00001850, 0x000011df },
+ { 0x00001854, 0x000011ef },
+ { 0x00001858, 0x000011ff },
+ { 0x0000185c, 0x0000120f },
+ { 0x00001860, 0x0000121f },
+ { 0x00001864, 0x00001230 },
+ { 0x00001868, 0x00001240 },
+ { 0x0000186c, 0x00001250 },
+ { 0x00001870, 0x00001260 },
+ { 0x00001874, 0x00001271 },
+ { 0x00001878, 0x00001281 },
+ { 0x0000187c, 0x00001291 },
+ { 0x00001880, 0x000012a2 },
+ { 0x00001884, 0x000012b2 },
+ { 0x00001888, 0x000012c3 },
+ { 0x0000188c, 0x000012d3 },
+ { 0x00001890, 0x000012e4 },
+ { 0x00001894, 0x000012f4 },
+ { 0x00001898, 0x00001305 },
+ { 0x0000189c, 0x00001316 },
+ { 0x000018a0, 0x00001326 },
+ { 0x000018a4, 0x00001337 },
+ { 0x000018a8, 0x00001348 },
+ { 0x000018ac, 0x00001359 },
+ { 0x000018b0, 0x00001369 },
+ { 0x000018b4, 0x0000137a },
+ { 0x000018b8, 0x0000138b },
+ { 0x000018bc, 0x0000139c },
+ { 0x000018c0, 0x000013ad },
+ { 0x000018c4, 0x000013be },
+ { 0x000018c8, 0x000013cf },
+ { 0x000018cc, 0x000013e0 },
+ { 0x000018d0, 0x000013f1 },
+ { 0x000018d4, 0x00001402 },
+ { 0x000018d8, 0x00001413 },
+ { 0x000018dc, 0x00001424 },
+ { 0x000018e0, 0x00001435 },
+ { 0x000018e4, 0x00001446 },
+ { 0x000018e8, 0x00001458 },
+ { 0x000018ec, 0x00001469 },
+ { 0x000018f0, 0x0000147a },
+ { 0x000018f4, 0x0000148b },
+ { 0x000018f8, 0x0000149d },
+ { 0x000018fc, 0x000014ae },
+ { 0x00001900, 0x000014c0 },
+ { 0x00001904, 0x000014d1 },
+ { 0x00001908, 0x000014e3 },
+ { 0x0000190c, 0x000014f4 },
+ { 0x00001910, 0x00001506 },
+ { 0x00001914, 0x00001517 },
+ { 0x00001918, 0x00001529 },
+ { 0x0000191c, 0x0000153a },
+ { 0x00001920, 0x0000154c },
+ { 0x00001924, 0x0000155e },
+ { 0x00001928, 0x0000156f },
+ { 0x0000192c, 0x00001581 },
+ { 0x00001930, 0x00001593 },
+ { 0x00001934, 0x000015a5 },
+ { 0x00001938, 0x000015b7 },
+ { 0x0000193c, 0x000015c9 },
+ { 0x00001940, 0x000015db },
+ { 0x00001944, 0x000015ec },
+ { 0x00001948, 0x000015fe },
+ { 0x0000194c, 0x00001610 },
+ { 0x00001950, 0x00001623 },
+ { 0x00001954, 0x00001635 },
+ { 0x00001958, 0x00001647 },
+ { 0x0000195c, 0x00001659 },
+ { 0x00001960, 0x0000166b },
+ { 0x00001964, 0x0000167d },
+ { 0x00001968, 0x0000168f },
+ { 0x0000196c, 0x000016a2 },
+ { 0x00001970, 0x000016b4 },
+ { 0x00001974, 0x000016c6 },
+ { 0x00001978, 0x000016d9 },
+ { 0x0000197c, 0x000016eb },
+ { 0x00001980, 0x000016fe },
+ { 0x00001984, 0x00001710 },
+ { 0x00001988, 0x00001722 },
+ { 0x0000198c, 0x00001735 },
+ { 0x00001990, 0x00001748 },
+ { 0x00001994, 0x0000175a },
+ { 0x00001998, 0x0000176d },
+ { 0x0000199c, 0x0000177f },
+ { 0x000019a0, 0x00001792 },
+ { 0x000019a4, 0x000017a5 },
+ { 0x000019a8, 0x000017b8 },
+ { 0x000019ac, 0x000017ca },
+ { 0x000019b0, 0x000017dd },
+ { 0x000019b4, 0x000017f0 },
+ { 0x000019b8, 0x00001803 },
+ { 0x000019bc, 0x00001816 },
+ { 0x000019c0, 0x00001829 },
+ { 0x000019c4, 0x0000183c },
+ { 0x000019c8, 0x0000184f },
+ { 0x000019cc, 0x00001862 },
+ { 0x000019d0, 0x00001875 },
+ { 0x000019d4, 0x00001888 },
+ { 0x000019d8, 0x0000189b },
+ { 0x000019dc, 0x000018ae },
+ { 0x000019e0, 0x000018c1 },
+ { 0x000019e4, 0x000018d5 },
+ { 0x000019e8, 0x000018e8 },
+ { 0x000019ec, 0x000018fb },
+ { 0x000019f0, 0x0000190e },
+ { 0x000019f4, 0x00001922 },
+ { 0x000019f8, 0x00001935 },
+ { 0x000019fc, 0x00001949 },
+ { 0x00001a00, 0x0000195c },
+ { 0x00001a04, 0x0000196f },
+ { 0x00001a08, 0x00001983 },
+ { 0x00001a0c, 0x00001996 },
+ { 0x00001a10, 0x000019aa },
+ { 0x00001a14, 0x000019be },
+ { 0x00001a18, 0x000019d1 },
+ { 0x00001a1c, 0x000019e5 },
+ { 0x00001a20, 0x000019f9 },
+ { 0x00001a24, 0x00001a0c },
+ { 0x00001a28, 0x00001a20 },
+ { 0x00001a2c, 0x00001a34 },
+ { 0x00001a30, 0x00001a48 },
+ { 0x00001a34, 0x00001a5c },
+ { 0x00001a38, 0x00001a70 },
+ { 0x00001a3c, 0x00001a84 },
+ { 0x00001a40, 0x00001a97 },
+ { 0x00001a44, 0x00001aab },
+ { 0x00001a48, 0x00001ac0 },
+ { 0x00001a4c, 0x00001ad4 },
+ { 0x00001a50, 0x00001ae8 },
+ { 0x00001a54, 0x00001afc },
+ { 0x00001a58, 0x00001b10 },
+ { 0x00001a5c, 0x00001b24 },
+ { 0x00001a60, 0x00001b38 },
+ { 0x00001a64, 0x00001b4d },
+ { 0x00001a68, 0x00001b61 },
+ { 0x00001a6c, 0x00001b75 },
+ { 0x00001a70, 0x00001b8a },
+ { 0x00001a74, 0x00001b9e },
+ { 0x00001a78, 0x00001bb2 },
+ { 0x00001a7c, 0x00001bc7 },
+ { 0x00001a80, 0x00001bdb },
+ { 0x00001a84, 0x00001bf0 },
+ { 0x00001a88, 0x00001c04 },
+ { 0x00001a8c, 0x00001c19 },
+ { 0x00001a90, 0x00001c2e },
+ { 0x00001a94, 0x00001c42 },
+ { 0x00001a98, 0x00001c57 },
+ { 0x00001a9c, 0x00001c6c },
+ { 0x00001aa0, 0x00001c80 },
+ { 0x00001aa4, 0x00001c95 },
+ { 0x00001aa8, 0x00001caa },
+ { 0x00001aac, 0x00001cbf },
+ { 0x00001ab0, 0x00001cd4 },
+ { 0x00001ab4, 0x00001ce8 },
+ { 0x00001ab8, 0x00001cfd },
+ { 0x00001abc, 0x00001d12 },
+ { 0x00001ac0, 0x00001d27 },
+ { 0x00001ac4, 0x00001d3c },
+ { 0x00001ac8, 0x00001d51 },
+ { 0x00001acc, 0x00001d67 },
+ { 0x00001ad0, 0x00001d7c },
+ { 0x00001ad4, 0x00001d91 },
+ { 0x00001ad8, 0x00001da6 },
+ { 0x00001adc, 0x00001dbb },
+ { 0x00001ae0, 0x00001dd1 },
+ { 0x00001ae4, 0x00001de6 },
+ { 0x00001ae8, 0x00001dfb },
+ { 0x00001aec, 0x00001e10 },
+ { 0x00001af0, 0x00001e26 },
+ { 0x00001af4, 0x00001e3b },
+ { 0x00001af8, 0x00001e51 },
+ { 0x00001afc, 0x00001e66 },
+ { 0x00001b00, 0x00001e7c },
+ { 0x00001b04, 0x00001e91 },
+ { 0x00001b08, 0x00001ea7 },
+ { 0x00001b0c, 0x00001ebd },
+ { 0x00001b10, 0x00001ed2 },
+ { 0x00001b14, 0x00001ee8 },
+ { 0x00001b18, 0x00001efe },
+ { 0x00001b1c, 0x00001f13 },
+ { 0x00001b20, 0x00001f29 },
+ { 0x00001b24, 0x00001f3f },
+ { 0x00001b28, 0x00001f55 },
+ { 0x00001b2c, 0x00001f6b },
+ { 0x00001b30, 0x00001f81 },
+ { 0x00001b34, 0x00001f96 },
+ { 0x00001b38, 0x00001fac },
+ { 0x00001b3c, 0x00001fc2 },
+ { 0x00001b40, 0x00001fd9 },
+ { 0x00001b44, 0x00001fef },
+ { 0x00001b48, 0x00002005 },
+ { 0x00001b4c, 0x0000201b },
+ { 0x00001b50, 0x00002031 },
+ { 0x00001b54, 0x00002047 },
+ { 0x00001b58, 0x0000205d },
+ { 0x00001b5c, 0x00002074 },
+ { 0x00001b60, 0x0000208a },
+ { 0x00001b64, 0x000020a0 },
+ { 0x00001b68, 0x000020b7 },
+ { 0x00001b6c, 0x000020cd },
+ { 0x00001b70, 0x000020e4 },
+ { 0x00001b74, 0x000020fa },
+ { 0x00001b78, 0x00002111 },
+ { 0x00001b7c, 0x00002127 },
+ { 0x00001b80, 0x0000213e },
+ { 0x00001b84, 0x00002154 },
+ { 0x00001b88, 0x0000216b },
+ { 0x00001b8c, 0x00002182 },
+ { 0x00001b90, 0x00002198 },
+ { 0x00001b94, 0x000021af },
+ { 0x00001b98, 0x000021c6 },
+ { 0x00001b9c, 0x000021dd },
+ { 0x00001ba0, 0x000021f3 },
+ { 0x00001ba4, 0x0000220a },
+ { 0x00001ba8, 0x00002221 },
+ { 0x00001bac, 0x00002238 },
+ { 0x00001bb0, 0x0000224f },
+ { 0x00001bb4, 0x00002266 },
+ { 0x00001bb8, 0x0000227d },
+ { 0x00001bbc, 0x00002294 },
+ { 0x00001bc0, 0x000022ab },
+ { 0x00001bc4, 0x000022c2 },
+ { 0x00001bc8, 0x000022da },
+ { 0x00001bcc, 0x000022f1 },
+ { 0x00001bd0, 0x00002308 },
+ { 0x00001bd4, 0x0000231f },
+ { 0x00001bd8, 0x00002337 },
+ { 0x00001bdc, 0x0000234e },
+ { 0x00001be0, 0x00002365 },
+ { 0x00001be4, 0x0000237d },
+ { 0x00001be8, 0x00002394 },
+ { 0x00001bec, 0x000023ac },
+ { 0x00001bf0, 0x000023c3 },
+ { 0x00001bf4, 0x000023db },
+ { 0x00001bf8, 0x000023f2 },
+ { 0x00001bfc, 0x0000240a },
+ { 0x00001c00, 0x00002421 },
+ { 0x00001c04, 0x00002439 },
+ { 0x00001c08, 0x00002451 },
+ { 0x00001c0c, 0x00002469 },
+ { 0x00001c10, 0x00002480 },
+ { 0x00001c14, 0x00002498 },
+ { 0x00001c18, 0x000024b0 },
+ { 0x00001c1c, 0x000024c8 },
+ { 0x00001c20, 0x000024e0 },
+ { 0x00001c24, 0x000024f8 },
+ { 0x00001c28, 0x00002510 },
+ { 0x00001c2c, 0x00002528 },
+ { 0x00001c30, 0x00002540 },
+ { 0x00001c34, 0x00002558 },
+ { 0x00001c38, 0x00002570 },
+ { 0x00001c3c, 0x00002588 },
+ { 0x00001c40, 0x000025a0 },
+ { 0x00001c44, 0x000025b8 },
+ { 0x00001c48, 0x000025d0 },
+ { 0x00001c4c, 0x000025e9 },
+ { 0x00001c50, 0x00002601 },
+ { 0x00001c54, 0x00002619 },
+ { 0x00001c58, 0x00002632 },
+ { 0x00001c5c, 0x0000264a },
+ { 0x00001c60, 0x00002663 },
+ { 0x00001c64, 0x0000267b },
+ { 0x00001c68, 0x00002693 },
+ { 0x00001c6c, 0x000026ac },
+ { 0x00001c70, 0x000026c5 },
+ { 0x00001c74, 0x000026dd },
+ { 0x00001c78, 0x000026f6 },
+ { 0x00001c7c, 0x0000270e },
+ { 0x00001c80, 0x00002727 },
+ { 0x00001c84, 0x00002740 },
+ { 0x00001c88, 0x00002759 },
+ { 0x00001c8c, 0x00002771 },
+ { 0x00001c90, 0x0000278a },
+ { 0x00001c94, 0x000027a3 },
+ { 0x00001c98, 0x000027bc },
+ { 0x00001c9c, 0x000027d5 },
+ { 0x00001ca0, 0x000027ee },
+ { 0x00001ca4, 0x00002807 },
+ { 0x00001ca8, 0x00002820 },
+ { 0x00001cac, 0x00002839 },
+ { 0x00001cb0, 0x00002852 },
+ { 0x00001cb4, 0x0000286b },
+ { 0x00001cb8, 0x00002884 },
+ { 0x00001cbc, 0x0000289e },
+ { 0x00001cc0, 0x000028b7 },
+ { 0x00001cc4, 0x000028d0 },
+ { 0x00001cc8, 0x000028e9 },
+ { 0x00001ccc, 0x00002903 },
+ { 0x00001cd0, 0x0000291c },
+ { 0x00001cd4, 0x00002936 },
+ { 0x00001cd8, 0x0000294f },
+ { 0x00001cdc, 0x00002968 },
+ { 0x00001ce0, 0x00002982 },
+ { 0x00001ce4, 0x0000299c },
+ { 0x00001ce8, 0x000029b5 },
+ { 0x00001cec, 0x000029cf },
+ { 0x00001cf0, 0x000029e8 },
+ { 0x00001cf4, 0x00002a02 },
+ { 0x00001cf8, 0x00002a1c },
+ { 0x00001cfc, 0x00002a35 },
+ { 0x00001d00, 0x00002a4f },
+ { 0x00001d04, 0x00002a69 },
+ { 0x00001d08, 0x00002a83 },
+ { 0x00001d0c, 0x00002a9d },
+ { 0x00001d10, 0x00002ab7 },
+ { 0x00001d14, 0x00002ad1 },
+ { 0x00001d18, 0x00002aeb },
+ { 0x00001d1c, 0x00002b05 },
+ { 0x00001d20, 0x00002b1f },
+ { 0x00001d24, 0x00002b39 },
+ { 0x00001d28, 0x00002b53 },
+ { 0x00001d2c, 0x00002b6d },
+ { 0x00001d30, 0x00002b87 },
+ { 0x00001d34, 0x00002ba1 },
+ { 0x00001d38, 0x00002bbc },
+ { 0x00001d3c, 0x00002bd6 },
+ { 0x00001d40, 0x00002bf0 },
+ { 0x00001d44, 0x00002c0b },
+ { 0x00001d48, 0x00002c25 },
+ { 0x00001d4c, 0x00002c3f },
+ { 0x00001d50, 0x00002c5a },
+ { 0x00001d54, 0x00002c74 },
+ { 0x00001d58, 0x00002c8f },
+ { 0x00001d5c, 0x00002ca9 },
+ { 0x00001d60, 0x00002cc4 },
+ { 0x00001d64, 0x00002cdf },
+ { 0x00001d68, 0x00002cf9 },
+ { 0x00001d6c, 0x00002d14 },
+ { 0x00001d70, 0x00002d2f },
+ { 0x00001d74, 0x00002d49 },
+ { 0x00001d78, 0x00002d64 },
+ { 0x00001d7c, 0x00002d7f },
+ { 0x00001d80, 0x00002d9a },
+ { 0x00001d84, 0x00002db5 },
+ { 0x00001d88, 0x00002dd0 },
+ { 0x00001d8c, 0x00002deb },
+ { 0x00001d90, 0x00002e06 },
+ { 0x00001d94, 0x00002e21 },
+ { 0x00001d98, 0x00002e3c },
+ { 0x00001d9c, 0x00002e57 },
+ { 0x00001da0, 0x00002e72 },
+ { 0x00001da4, 0x00002e8d },
+ { 0x00001da8, 0x00002ea8 },
+ { 0x00001dac, 0x00002ec4 },
+ { 0x00001db0, 0x00002edf },
+ { 0x00001db4, 0x00002efa },
+ { 0x00001db8, 0x00002f16 },
+ { 0x00001dbc, 0x00002f31 },
+ { 0x00001dc0, 0x00002f4c },
+ { 0x00001dc4, 0x00002f68 },
+ { 0x00001dc8, 0x00002f83 },
+ { 0x00001dcc, 0x00002f9f },
+ { 0x00001dd0, 0x00002fba },
+ { 0x00001dd4, 0x00002fd6 },
+ { 0x00001dd8, 0x00002ff1 },
+ { 0x00001ddc, 0x0000300d },
+ { 0x00001de0, 0x00003029 },
+ { 0x00001de4, 0x00003044 },
+ { 0x00001de8, 0x00003060 },
+ { 0x00001dec, 0x0000307c },
+ { 0x00001df0, 0x00003098 },
+ { 0x00001df4, 0x000030b4 },
+ { 0x00001df8, 0x000030d0 },
+ { 0x00001dfc, 0x000030eb },
+ { 0x00001e00, 0x00003107 },
+ { 0x00001e04, 0x00003123 },
+ { 0x00001e08, 0x0000313f },
+ { 0x00001e0c, 0x0000315b },
+ { 0x00001e10, 0x00003178 },
+ { 0x00001e14, 0x00003194 },
+ { 0x00001e18, 0x000031b0 },
+ { 0x00001e1c, 0x000031cc },
+ { 0x00001e20, 0x000031e8 },
+ { 0x00001e24, 0x00003205 },
+ { 0x00001e28, 0x00003221 },
+ { 0x00001e2c, 0x0000323d },
+ { 0x00001e30, 0x0000325a },
+ { 0x00001e34, 0x00003276 },
+ { 0x00001e38, 0x00003292 },
+ { 0x00001e3c, 0x000032af },
+ { 0x00001e40, 0x000032cb },
+ { 0x00001e44, 0x000032e8 },
+ { 0x00001e48, 0x00003304 },
+ { 0x00001e4c, 0x00003321 },
+ { 0x00001e50, 0x0000333e },
+ { 0x00001e54, 0x0000335a },
+ { 0x00001e58, 0x00003377 },
+ { 0x00001e5c, 0x00003394 },
+ { 0x00001e60, 0x000033b1 },
+ { 0x00001e64, 0x000033cd },
+ { 0x00001e68, 0x000033ea },
+ { 0x00001e6c, 0x00003407 },
+ { 0x00001e70, 0x00003424 },
+ { 0x00001e74, 0x00003441 },
+ { 0x00001e78, 0x0000345e },
+ { 0x00001e7c, 0x0000347b },
+ { 0x00001e80, 0x00003498 },
+ { 0x00001e84, 0x000034b5 },
+ { 0x00001e88, 0x000034d2 },
+ { 0x00001e8c, 0x000034ef },
+ { 0x00001e90, 0x0000350d },
+ { 0x00001e94, 0x0000352a },
+ { 0x00001e98, 0x00003547 },
+ { 0x00001e9c, 0x00003564 },
+ { 0x00001ea0, 0x00003582 },
+ { 0x00001ea4, 0x0000359f },
+ { 0x00001ea8, 0x000035bc },
+ { 0x00001eac, 0x000035da },
+ { 0x00001eb0, 0x000035f7 },
+ { 0x00001eb4, 0x00003615 },
+ { 0x00001eb8, 0x00003632 },
+ { 0x00001ebc, 0x00003650 },
+ { 0x00001ec0, 0x0000366e },
+ { 0x00001ec4, 0x0000368b },
+ { 0x00001ec8, 0x000036a9 },
+ { 0x00001ecc, 0x000036c7 },
+ { 0x00001ed0, 0x000036e4 },
+ { 0x00001ed4, 0x00003702 },
+ { 0x00001ed8, 0x00003720 },
+ { 0x00001edc, 0x0000373e },
+ { 0x00001ee0, 0x0000375c },
+ { 0x00001ee4, 0x0000377a },
+ { 0x00001ee8, 0x00003798 },
+ { 0x00001eec, 0x000037b6 },
+ { 0x00001ef0, 0x000037d4 },
+ { 0x00001ef4, 0x000037f2 },
+ { 0x00001ef8, 0x00003810 },
+ { 0x00001efc, 0x0000382e },
+ { 0x00001f00, 0x0000384c },
+ { 0x00001f04, 0x0000386a },
+ { 0x00001f08, 0x00003888 },
+ { 0x00001f0c, 0x000038a7 },
+ { 0x00001f10, 0x000038c5 },
+ { 0x00001f14, 0x000038e3 },
+ { 0x00001f18, 0x00003902 },
+ { 0x00001f1c, 0x00003920 },
+ { 0x00001f20, 0x0000393f },
+ { 0x00001f24, 0x0000395d },
+ { 0x00001f28, 0x0000397c },
+ { 0x00001f2c, 0x0000399a },
+ { 0x00001f30, 0x000039b9 },
+ { 0x00001f34, 0x000039d7 },
+ { 0x00001f38, 0x000039f6 },
+ { 0x00001f3c, 0x00003a15 },
+ { 0x00001f40, 0x00003a33 },
+ { 0x00001f44, 0x00003a52 },
+ { 0x00001f48, 0x00003a71 },
+ { 0x00001f4c, 0x00003a90 },
+ { 0x00001f50, 0x00003aaf },
+ { 0x00001f54, 0x00003acd },
+ { 0x00001f58, 0x00003aec },
+ { 0x00001f5c, 0x00003b0b },
+ { 0x00001f60, 0x00003b2a },
+ { 0x00001f64, 0x00003b49 },
+ { 0x00001f68, 0x00003b68 },
+ { 0x00001f6c, 0x00003b87 },
+ { 0x00001f70, 0x00003ba7 },
+ { 0x00001f74, 0x00003bc6 },
+ { 0x00001f78, 0x00003be5 },
+ { 0x00001f7c, 0x00003c04 },
+ { 0x00001f80, 0x00003c24 },
+ { 0x00001f84, 0x00003c43 },
+ { 0x00001f88, 0x00003c62 },
+ { 0x00001f8c, 0x00003c82 },
+ { 0x00001f90, 0x00003ca1 },
+ { 0x00001f94, 0x00003cc0 },
+ { 0x00001f98, 0x00003ce0 },
+ { 0x00001f9c, 0x00003cff },
+ { 0x00001fa0, 0x00003d1f },
+ { 0x00001fa4, 0x00003d3f },
+ { 0x00001fa8, 0x00003d5e },
+ { 0x00001fac, 0x00003d7e },
+ { 0x00001fb0, 0x00003d9e },
+ { 0x00001fb4, 0x00003dbd },
+ { 0x00001fb8, 0x00003ddd },
+ { 0x00001fbc, 0x00003dfd },
+ { 0x00001fc0, 0x00003e1d },
+ { 0x00001fc4, 0x00003e3d },
+ { 0x00001fc8, 0x00003e5d },
+ { 0x00001fcc, 0x00003e7c },
+ { 0x00001fd0, 0x00003e9c },
+ { 0x00001fd4, 0x00003ebc },
+ { 0x00001fd8, 0x00003edc },
+ { 0x00001fdc, 0x00003efd },
+ { 0x00001fe0, 0x00003f1d },
+ { 0x00001fe4, 0x00003f3d },
+ { 0x00001fe8, 0x00003f5d },
+ { 0x00001fec, 0x00003f7d },
+ { 0x00001ff0, 0x00003f9e },
+ { 0x00001ff4, 0x00003fbe },
+ { 0x00001ff8, 0x00003fde },
+ { 0x00001ffc, 0x00003fff },
+};
+
+struct data_unit hdr10_pipe1_lut_a2[] = {
+ { 0x00002000, 0x00000000 },
+ { 0x00002004, 0x00000003 },
+ { 0x00002008, 0x00000007 },
+ { 0x0000200c, 0x0000000a },
+ { 0x00002010, 0x0000000e },
+ { 0x00002014, 0x00000011 },
+ { 0x00002018, 0x00000015 },
+ { 0x0000201c, 0x00000018 },
+ { 0x00002020, 0x0000001c },
+ { 0x00002024, 0x00000020 },
+ { 0x00002028, 0x00000023 },
+ { 0x0000202c, 0x00000027 },
+ { 0x00002030, 0x0000002a },
+ { 0x00002034, 0x0000002e },
+ { 0x00002038, 0x00000031 },
+ { 0x0000203c, 0x00000035 },
+ { 0x00002040, 0x00000038 },
+ { 0x00002044, 0x0000003c },
+ { 0x00002048, 0x00000040 },
+ { 0x0000204c, 0x00000043 },
+ { 0x00002050, 0x00000047 },
+ { 0x00002054, 0x0000004a },
+ { 0x00002058, 0x0000004e },
+ { 0x0000205c, 0x00000051 },
+ { 0x00002060, 0x00000055 },
+ { 0x00002064, 0x00000058 },
+ { 0x00002068, 0x0000005c },
+ { 0x0000206c, 0x00000060 },
+ { 0x00002070, 0x00000063 },
+ { 0x00002074, 0x00000067 },
+ { 0x00002078, 0x0000006a },
+ { 0x0000207c, 0x0000006e },
+ { 0x00002080, 0x00000071 },
+ { 0x00002084, 0x00000075 },
+ { 0x00002088, 0x00000078 },
+ { 0x0000208c, 0x0000007c },
+ { 0x00002090, 0x00000080 },
+ { 0x00002094, 0x00000083 },
+ { 0x00002098, 0x00000087 },
+ { 0x0000209c, 0x0000008a },
+ { 0x000020a0, 0x0000008e },
+ { 0x000020a4, 0x00000091 },
+ { 0x000020a8, 0x00000095 },
+ { 0x000020ac, 0x00000099 },
+ { 0x000020b0, 0x0000009c },
+ { 0x000020b4, 0x000000a0 },
+ { 0x000020b8, 0x000000a3 },
+ { 0x000020bc, 0x000000a7 },
+ { 0x000020c0, 0x000000aa },
+ { 0x000020c4, 0x000000ae },
+ { 0x000020c8, 0x000000b1 },
+ { 0x000020cc, 0x000000b5 },
+ { 0x000020d0, 0x000000b9 },
+ { 0x000020d4, 0x000000bc },
+ { 0x000020d8, 0x000000c0 },
+ { 0x000020dc, 0x000000c3 },
+ { 0x000020e0, 0x000000c7 },
+ { 0x000020e4, 0x000000ca },
+ { 0x000020e8, 0x000000ce },
+ { 0x000020ec, 0x000000d1 },
+ { 0x000020f0, 0x000000d5 },
+ { 0x000020f4, 0x000000d9 },
+ { 0x000020f8, 0x000000dc },
+ { 0x000020fc, 0x000000e0 },
+ { 0x00002100, 0x000000e3 },
+ { 0x00002104, 0x000000e7 },
+ { 0x00002108, 0x000000ea },
+ { 0x0000210c, 0x000000ee },
+ { 0x00002110, 0x000000f1 },
+ { 0x00002114, 0x000000f5 },
+ { 0x00002118, 0x000000f9 },
+ { 0x0000211c, 0x000000fc },
+ { 0x00002120, 0x00000100 },
+ { 0x00002124, 0x00000103 },
+ { 0x00002128, 0x00000107 },
+ { 0x0000212c, 0x0000010a },
+ { 0x00002130, 0x0000010e },
+ { 0x00002134, 0x00000112 },
+ { 0x00002138, 0x00000115 },
+ { 0x0000213c, 0x00000119 },
+ { 0x00002140, 0x0000011c },
+ { 0x00002144, 0x00000120 },
+ { 0x00002148, 0x00000123 },
+ { 0x0000214c, 0x00000126 },
+ { 0x00002150, 0x0000012a },
+ { 0x00002154, 0x0000012d },
+ { 0x00002158, 0x00000131 },
+ { 0x0000215c, 0x00000134 },
+ { 0x00002160, 0x00000138 },
+ { 0x00002164, 0x0000013c },
+ { 0x00002168, 0x0000013f },
+ { 0x0000216c, 0x00000143 },
+ { 0x00002170, 0x00000147 },
+ { 0x00002174, 0x0000014b },
+ { 0x00002178, 0x0000014e },
+ { 0x0000217c, 0x00000152 },
+ { 0x00002180, 0x00000156 },
+ { 0x00002184, 0x0000015a },
+ { 0x00002188, 0x0000015e },
+ { 0x0000218c, 0x00000162 },
+ { 0x00002190, 0x00000166 },
+ { 0x00002194, 0x0000016a },
+ { 0x00002198, 0x0000016e },
+ { 0x0000219c, 0x00000172 },
+ { 0x000021a0, 0x00000176 },
+ { 0x000021a4, 0x0000017a },
+ { 0x000021a8, 0x0000017e },
+ { 0x000021ac, 0x00000182 },
+ { 0x000021b0, 0x00000186 },
+ { 0x000021b4, 0x0000018a },
+ { 0x000021b8, 0x0000018f },
+ { 0x000021bc, 0x00000193 },
+ { 0x000021c0, 0x00000197 },
+ { 0x000021c4, 0x0000019b },
+ { 0x000021c8, 0x000001a0 },
+ { 0x000021cc, 0x000001a4 },
+ { 0x000021d0, 0x000001a8 },
+ { 0x000021d4, 0x000001ad },
+ { 0x000021d8, 0x000001b1 },
+ { 0x000021dc, 0x000001b5 },
+ { 0x000021e0, 0x000001ba },
+ { 0x000021e4, 0x000001be },
+ { 0x000021e8, 0x000001c3 },
+ { 0x000021ec, 0x000001c7 },
+ { 0x000021f0, 0x000001cc },
+ { 0x000021f4, 0x000001d0 },
+ { 0x000021f8, 0x000001d5 },
+ { 0x000021fc, 0x000001d9 },
+ { 0x00002200, 0x000001de },
+ { 0x00002204, 0x000001e3 },
+ { 0x00002208, 0x000001e7 },
+ { 0x0000220c, 0x000001ec },
+ { 0x00002210, 0x000001f1 },
+ { 0x00002214, 0x000001f6 },
+ { 0x00002218, 0x000001fa },
+ { 0x0000221c, 0x000001ff },
+ { 0x00002220, 0x00000204 },
+ { 0x00002224, 0x00000209 },
+ { 0x00002228, 0x0000020e },
+ { 0x0000222c, 0x00000213 },
+ { 0x00002230, 0x00000217 },
+ { 0x00002234, 0x0000021c },
+ { 0x00002238, 0x00000221 },
+ { 0x0000223c, 0x00000226 },
+ { 0x00002240, 0x0000022b },
+ { 0x00002244, 0x00000230 },
+ { 0x00002248, 0x00000236 },
+ { 0x0000224c, 0x0000023b },
+ { 0x00002250, 0x00000240 },
+ { 0x00002254, 0x00000245 },
+ { 0x00002258, 0x0000024a },
+ { 0x0000225c, 0x0000024f },
+ { 0x00002260, 0x00000255 },
+ { 0x00002264, 0x0000025a },
+ { 0x00002268, 0x0000025f },
+ { 0x0000226c, 0x00000264 },
+ { 0x00002270, 0x0000026a },
+ { 0x00002274, 0x0000026f },
+ { 0x00002278, 0x00000274 },
+ { 0x0000227c, 0x0000027a },
+ { 0x00002280, 0x0000027f },
+ { 0x00002284, 0x00000285 },
+ { 0x00002288, 0x0000028a },
+ { 0x0000228c, 0x00000290 },
+ { 0x00002290, 0x00000295 },
+ { 0x00002294, 0x0000029b },
+ { 0x00002298, 0x000002a0 },
+ { 0x0000229c, 0x000002a6 },
+ { 0x000022a0, 0x000002ac },
+ { 0x000022a4, 0x000002b1 },
+ { 0x000022a8, 0x000002b7 },
+ { 0x000022ac, 0x000002bd },
+ { 0x000022b0, 0x000002c2 },
+ { 0x000022b4, 0x000002c8 },
+ { 0x000022b8, 0x000002ce },
+ { 0x000022bc, 0x000002d4 },
+ { 0x000022c0, 0x000002da },
+ { 0x000022c4, 0x000002df },
+ { 0x000022c8, 0x000002e5 },
+ { 0x000022cc, 0x000002eb },
+ { 0x000022d0, 0x000002f1 },
+ { 0x000022d4, 0x000002f7 },
+ { 0x000022d8, 0x000002fd },
+ { 0x000022dc, 0x00000303 },
+ { 0x000022e0, 0x00000309 },
+ { 0x000022e4, 0x0000030f },
+ { 0x000022e8, 0x00000315 },
+ { 0x000022ec, 0x0000031c },
+ { 0x000022f0, 0x00000322 },
+ { 0x000022f4, 0x00000328 },
+ { 0x000022f8, 0x0000032e },
+ { 0x000022fc, 0x00000334 },
+ { 0x00002300, 0x0000033b },
+ { 0x00002304, 0x00000341 },
+ { 0x00002308, 0x00000347 },
+ { 0x0000230c, 0x0000034d },
+ { 0x00002310, 0x00000354 },
+ { 0x00002314, 0x0000035a },
+ { 0x00002318, 0x00000361 },
+ { 0x0000231c, 0x00000367 },
+ { 0x00002320, 0x0000036d },
+ { 0x00002324, 0x00000374 },
+ { 0x00002328, 0x0000037a },
+ { 0x0000232c, 0x00000381 },
+ { 0x00002330, 0x00000388 },
+ { 0x00002334, 0x0000038e },
+ { 0x00002338, 0x00000395 },
+ { 0x0000233c, 0x0000039b },
+ { 0x00002340, 0x000003a2 },
+ { 0x00002344, 0x000003a9 },
+ { 0x00002348, 0x000003b0 },
+ { 0x0000234c, 0x000003b6 },
+ { 0x00002350, 0x000003bd },
+ { 0x00002354, 0x000003c4 },
+ { 0x00002358, 0x000003cb },
+ { 0x0000235c, 0x000003d2 },
+ { 0x00002360, 0x000003d8 },
+ { 0x00002364, 0x000003df },
+ { 0x00002368, 0x000003e6 },
+ { 0x0000236c, 0x000003ed },
+ { 0x00002370, 0x000003f4 },
+ { 0x00002374, 0x000003fb },
+ { 0x00002378, 0x00000402 },
+ { 0x0000237c, 0x00000409 },
+ { 0x00002380, 0x00000411 },
+ { 0x00002384, 0x00000418 },
+ { 0x00002388, 0x0000041f },
+ { 0x0000238c, 0x00000426 },
+ { 0x00002390, 0x0000042d },
+ { 0x00002394, 0x00000434 },
+ { 0x00002398, 0x0000043c },
+ { 0x0000239c, 0x00000443 },
+ { 0x000023a0, 0x0000044a },
+ { 0x000023a4, 0x00000452 },
+ { 0x000023a8, 0x00000459 },
+ { 0x000023ac, 0x00000460 },
+ { 0x000023b0, 0x00000468 },
+ { 0x000023b4, 0x0000046f },
+ { 0x000023b8, 0x00000477 },
+ { 0x000023bc, 0x0000047e },
+ { 0x000023c0, 0x00000486 },
+ { 0x000023c4, 0x0000048d },
+ { 0x000023c8, 0x00000495 },
+ { 0x000023cc, 0x0000049c },
+ { 0x000023d0, 0x000004a4 },
+ { 0x000023d4, 0x000004ac },
+ { 0x000023d8, 0x000004b3 },
+ { 0x000023dc, 0x000004bb },
+ { 0x000023e0, 0x000004c3 },
+ { 0x000023e4, 0x000004cb },
+ { 0x000023e8, 0x000004d3 },
+ { 0x000023ec, 0x000004da },
+ { 0x000023f0, 0x000004e2 },
+ { 0x000023f4, 0x000004ea },
+ { 0x000023f8, 0x000004f2 },
+ { 0x000023fc, 0x000004fa },
+ { 0x00002400, 0x00000502 },
+ { 0x00002404, 0x0000050a },
+ { 0x00002408, 0x00000512 },
+ { 0x0000240c, 0x0000051a },
+ { 0x00002410, 0x00000522 },
+ { 0x00002414, 0x0000052a },
+ { 0x00002418, 0x00000532 },
+ { 0x0000241c, 0x0000053a },
+ { 0x00002420, 0x00000543 },
+ { 0x00002424, 0x0000054b },
+ { 0x00002428, 0x00000553 },
+ { 0x0000242c, 0x0000055b },
+ { 0x00002430, 0x00000564 },
+ { 0x00002434, 0x0000056c },
+ { 0x00002438, 0x00000574 },
+ { 0x0000243c, 0x0000057d },
+ { 0x00002440, 0x00000585 },
+ { 0x00002444, 0x0000058d },
+ { 0x00002448, 0x00000596 },
+ { 0x0000244c, 0x0000059e },
+ { 0x00002450, 0x000005a7 },
+ { 0x00002454, 0x000005af },
+ { 0x00002458, 0x000005b8 },
+ { 0x0000245c, 0x000005c1 },
+ { 0x00002460, 0x000005c9 },
+ { 0x00002464, 0x000005d2 },
+ { 0x00002468, 0x000005db },
+ { 0x0000246c, 0x000005e3 },
+ { 0x00002470, 0x000005ec },
+ { 0x00002474, 0x000005f5 },
+ { 0x00002478, 0x000005fe },
+ { 0x0000247c, 0x00000606 },
+ { 0x00002480, 0x0000060f },
+ { 0x00002484, 0x00000618 },
+ { 0x00002488, 0x00000621 },
+ { 0x0000248c, 0x0000062a },
+ { 0x00002490, 0x00000633 },
+ { 0x00002494, 0x0000063c },
+ { 0x00002498, 0x00000645 },
+ { 0x0000249c, 0x0000064e },
+ { 0x000024a0, 0x00000657 },
+ { 0x000024a4, 0x00000660 },
+ { 0x000024a8, 0x00000669 },
+ { 0x000024ac, 0x00000672 },
+ { 0x000024b0, 0x0000067b },
+ { 0x000024b4, 0x00000685 },
+ { 0x000024b8, 0x0000068e },
+ { 0x000024bc, 0x00000697 },
+ { 0x000024c0, 0x000006a0 },
+ { 0x000024c4, 0x000006aa },
+ { 0x000024c8, 0x000006b3 },
+ { 0x000024cc, 0x000006bd },
+ { 0x000024d0, 0x000006c6 },
+ { 0x000024d4, 0x000006cf },
+ { 0x000024d8, 0x000006d9 },
+ { 0x000024dc, 0x000006e2 },
+ { 0x000024e0, 0x000006ec },
+ { 0x000024e4, 0x000006f5 },
+ { 0x000024e8, 0x000006ff },
+ { 0x000024ec, 0x00000709 },
+ { 0x000024f0, 0x00000712 },
+ { 0x000024f4, 0x0000071c },
+ { 0x000024f8, 0x00000726 },
+ { 0x000024fc, 0x0000072f },
+ { 0x00002500, 0x00000739 },
+ { 0x00002504, 0x00000743 },
+ { 0x00002508, 0x0000074d },
+ { 0x0000250c, 0x00000756 },
+ { 0x00002510, 0x00000760 },
+ { 0x00002514, 0x0000076a },
+ { 0x00002518, 0x00000774 },
+ { 0x0000251c, 0x0000077e },
+ { 0x00002520, 0x00000788 },
+ { 0x00002524, 0x00000792 },
+ { 0x00002528, 0x0000079c },
+ { 0x0000252c, 0x000007a6 },
+ { 0x00002530, 0x000007b0 },
+ { 0x00002534, 0x000007ba },
+ { 0x00002538, 0x000007c4 },
+ { 0x0000253c, 0x000007cf },
+ { 0x00002540, 0x000007d9 },
+ { 0x00002544, 0x000007e3 },
+ { 0x00002548, 0x000007ed },
+ { 0x0000254c, 0x000007f7 },
+ { 0x00002550, 0x00000802 },
+ { 0x00002554, 0x0000080c },
+ { 0x00002558, 0x00000816 },
+ { 0x0000255c, 0x00000821 },
+ { 0x00002560, 0x0000082b },
+ { 0x00002564, 0x00000836 },
+ { 0x00002568, 0x00000840 },
+ { 0x0000256c, 0x0000084b },
+ { 0x00002570, 0x00000855 },
+ { 0x00002574, 0x00000860 },
+ { 0x00002578, 0x0000086a },
+ { 0x0000257c, 0x00000875 },
+ { 0x00002580, 0x00000880 },
+ { 0x00002584, 0x0000088a },
+ { 0x00002588, 0x00000895 },
+ { 0x0000258c, 0x000008a0 },
+ { 0x00002590, 0x000008ab },
+ { 0x00002594, 0x000008b5 },
+ { 0x00002598, 0x000008c0 },
+ { 0x0000259c, 0x000008cb },
+ { 0x000025a0, 0x000008d6 },
+ { 0x000025a4, 0x000008e1 },
+ { 0x000025a8, 0x000008ec },
+ { 0x000025ac, 0x000008f7 },
+ { 0x000025b0, 0x00000902 },
+ { 0x000025b4, 0x0000090d },
+ { 0x000025b8, 0x00000918 },
+ { 0x000025bc, 0x00000923 },
+ { 0x000025c0, 0x0000092e },
+ { 0x000025c4, 0x00000939 },
+ { 0x000025c8, 0x00000944 },
+ { 0x000025cc, 0x00000950 },
+ { 0x000025d0, 0x0000095b },
+ { 0x000025d4, 0x00000966 },
+ { 0x000025d8, 0x00000971 },
+ { 0x000025dc, 0x0000097d },
+ { 0x000025e0, 0x00000988 },
+ { 0x000025e4, 0x00000993 },
+ { 0x000025e8, 0x0000099f },
+ { 0x000025ec, 0x000009aa },
+ { 0x000025f0, 0x000009b6 },
+ { 0x000025f4, 0x000009c1 },
+ { 0x000025f8, 0x000009cd },
+ { 0x000025fc, 0x000009d8 },
+ { 0x00002600, 0x000009e4 },
+ { 0x00002604, 0x000009f0 },
+ { 0x00002608, 0x000009fb },
+ { 0x0000260c, 0x00000a07 },
+ { 0x00002610, 0x00000a13 },
+ { 0x00002614, 0x00000a1e },
+ { 0x00002618, 0x00000a2a },
+ { 0x0000261c, 0x00000a36 },
+ { 0x00002620, 0x00000a42 },
+ { 0x00002624, 0x00000a4e },
+ { 0x00002628, 0x00000a59 },
+ { 0x0000262c, 0x00000a65 },
+ { 0x00002630, 0x00000a71 },
+ { 0x00002634, 0x00000a7d },
+ { 0x00002638, 0x00000a89 },
+ { 0x0000263c, 0x00000a95 },
+ { 0x00002640, 0x00000aa1 },
+ { 0x00002644, 0x00000aad },
+ { 0x00002648, 0x00000ab9 },
+ { 0x0000264c, 0x00000ac6 },
+ { 0x00002650, 0x00000ad2 },
+ { 0x00002654, 0x00000ade },
+ { 0x00002658, 0x00000aea },
+ { 0x0000265c, 0x00000af6 },
+ { 0x00002660, 0x00000b03 },
+ { 0x00002664, 0x00000b0f },
+ { 0x00002668, 0x00000b1b },
+ { 0x0000266c, 0x00000b28 },
+ { 0x00002670, 0x00000b34 },
+ { 0x00002674, 0x00000b41 },
+ { 0x00002678, 0x00000b4d },
+ { 0x0000267c, 0x00000b5a },
+ { 0x00002680, 0x00000b66 },
+ { 0x00002684, 0x00000b73 },
+ { 0x00002688, 0x00000b7f },
+ { 0x0000268c, 0x00000b8c },
+ { 0x00002690, 0x00000b98 },
+ { 0x00002694, 0x00000ba5 },
+ { 0x00002698, 0x00000bb2 },
+ { 0x0000269c, 0x00000bbf },
+ { 0x000026a0, 0x00000bcb },
+ { 0x000026a4, 0x00000bd8 },
+ { 0x000026a8, 0x00000be5 },
+ { 0x000026ac, 0x00000bf2 },
+ { 0x000026b0, 0x00000bff },
+ { 0x000026b4, 0x00000c0c },
+ { 0x000026b8, 0x00000c19 },
+ { 0x000026bc, 0x00000c25 },
+ { 0x000026c0, 0x00000c32 },
+ { 0x000026c4, 0x00000c40 },
+ { 0x000026c8, 0x00000c4d },
+ { 0x000026cc, 0x00000c5a },
+ { 0x000026d0, 0x00000c67 },
+ { 0x000026d4, 0x00000c74 },
+ { 0x000026d8, 0x00000c81 },
+ { 0x000026dc, 0x00000c8e },
+ { 0x000026e0, 0x00000c9c },
+ { 0x000026e4, 0x00000ca9 },
+ { 0x000026e8, 0x00000cb6 },
+ { 0x000026ec, 0x00000cc3 },
+ { 0x000026f0, 0x00000cd1 },
+ { 0x000026f4, 0x00000cde },
+ { 0x000026f8, 0x00000cec },
+ { 0x000026fc, 0x00000cf9 },
+ { 0x00002700, 0x00000d07 },
+ { 0x00002704, 0x00000d14 },
+ { 0x00002708, 0x00000d22 },
+ { 0x0000270c, 0x00000d2f },
+ { 0x00002710, 0x00000d3d },
+ { 0x00002714, 0x00000d4a },
+ { 0x00002718, 0x00000d58 },
+ { 0x0000271c, 0x00000d66 },
+ { 0x00002720, 0x00000d73 },
+ { 0x00002724, 0x00000d81 },
+ { 0x00002728, 0x00000d8f },
+ { 0x0000272c, 0x00000d9d },
+ { 0x00002730, 0x00000dab },
+ { 0x00002734, 0x00000db8 },
+ { 0x00002738, 0x00000dc6 },
+ { 0x0000273c, 0x00000dd4 },
+ { 0x00002740, 0x00000de2 },
+ { 0x00002744, 0x00000df0 },
+ { 0x00002748, 0x00000dfe },
+ { 0x0000274c, 0x00000e0c },
+ { 0x00002750, 0x00000e1a },
+ { 0x00002754, 0x00000e29 },
+ { 0x00002758, 0x00000e37 },
+ { 0x0000275c, 0x00000e45 },
+ { 0x00002760, 0x00000e53 },
+ { 0x00002764, 0x00000e61 },
+ { 0x00002768, 0x00000e70 },
+ { 0x0000276c, 0x00000e7e },
+ { 0x00002770, 0x00000e8c },
+ { 0x00002774, 0x00000e9a },
+ { 0x00002778, 0x00000ea9 },
+ { 0x0000277c, 0x00000eb7 },
+ { 0x00002780, 0x00000ec6 },
+ { 0x00002784, 0x00000ed4 },
+ { 0x00002788, 0x00000ee3 },
+ { 0x0000278c, 0x00000ef1 },
+ { 0x00002790, 0x00000f00 },
+ { 0x00002794, 0x00000f0e },
+ { 0x00002798, 0x00000f1d },
+ { 0x0000279c, 0x00000f2c },
+ { 0x000027a0, 0x00000f3a },
+ { 0x000027a4, 0x00000f49 },
+ { 0x000027a8, 0x00000f58 },
+ { 0x000027ac, 0x00000f67 },
+ { 0x000027b0, 0x00000f75 },
+ { 0x000027b4, 0x00000f84 },
+ { 0x000027b8, 0x00000f93 },
+ { 0x000027bc, 0x00000fa2 },
+ { 0x000027c0, 0x00000fb1 },
+ { 0x000027c4, 0x00000fc0 },
+ { 0x000027c8, 0x00000fcf },
+ { 0x000027cc, 0x00000fde },
+ { 0x000027d0, 0x00000fed },
+ { 0x000027d4, 0x00000ffc },
+ { 0x000027d8, 0x0000100b },
+ { 0x000027dc, 0x0000101a },
+ { 0x000027e0, 0x0000102a },
+ { 0x000027e4, 0x00001039 },
+ { 0x000027e8, 0x00001048 },
+ { 0x000027ec, 0x00001057 },
+ { 0x000027f0, 0x00001067 },
+ { 0x000027f4, 0x00001076 },
+ { 0x000027f8, 0x00001085 },
+ { 0x000027fc, 0x00001095 },
+ { 0x00002800, 0x000010a4 },
+ { 0x00002804, 0x000010b4 },
+ { 0x00002808, 0x000010c3 },
+ { 0x0000280c, 0x000010d3 },
+ { 0x00002810, 0x000010e2 },
+ { 0x00002814, 0x000010f2 },
+ { 0x00002818, 0x00001101 },
+ { 0x0000281c, 0x00001111 },
+ { 0x00002820, 0x00001121 },
+ { 0x00002824, 0x00001130 },
+ { 0x00002828, 0x00001140 },
+ { 0x0000282c, 0x00001150 },
+ { 0x00002830, 0x00001160 },
+ { 0x00002834, 0x0000116f },
+ { 0x00002838, 0x0000117f },
+ { 0x0000283c, 0x0000118f },
+ { 0x00002840, 0x0000119f },
+ { 0x00002844, 0x000011af },
+ { 0x00002848, 0x000011bf },
+ { 0x0000284c, 0x000011cf },
+ { 0x00002850, 0x000011df },
+ { 0x00002854, 0x000011ef },
+ { 0x00002858, 0x000011ff },
+ { 0x0000285c, 0x0000120f },
+ { 0x00002860, 0x0000121f },
+ { 0x00002864, 0x00001230 },
+ { 0x00002868, 0x00001240 },
+ { 0x0000286c, 0x00001250 },
+ { 0x00002870, 0x00001260 },
+ { 0x00002874, 0x00001271 },
+ { 0x00002878, 0x00001281 },
+ { 0x0000287c, 0x00001291 },
+ { 0x00002880, 0x000012a2 },
+ { 0x00002884, 0x000012b2 },
+ { 0x00002888, 0x000012c3 },
+ { 0x0000288c, 0x000012d3 },
+ { 0x00002890, 0x000012e4 },
+ { 0x00002894, 0x000012f4 },
+ { 0x00002898, 0x00001305 },
+ { 0x0000289c, 0x00001316 },
+ { 0x000028a0, 0x00001326 },
+ { 0x000028a4, 0x00001337 },
+ { 0x000028a8, 0x00001348 },
+ { 0x000028ac, 0x00001359 },
+ { 0x000028b0, 0x00001369 },
+ { 0x000028b4, 0x0000137a },
+ { 0x000028b8, 0x0000138b },
+ { 0x000028bc, 0x0000139c },
+ { 0x000028c0, 0x000013ad },
+ { 0x000028c4, 0x000013be },
+ { 0x000028c8, 0x000013cf },
+ { 0x000028cc, 0x000013e0 },
+ { 0x000028d0, 0x000013f1 },
+ { 0x000028d4, 0x00001402 },
+ { 0x000028d8, 0x00001413 },
+ { 0x000028dc, 0x00001424 },
+ { 0x000028e0, 0x00001435 },
+ { 0x000028e4, 0x00001446 },
+ { 0x000028e8, 0x00001458 },
+ { 0x000028ec, 0x00001469 },
+ { 0x000028f0, 0x0000147a },
+ { 0x000028f4, 0x0000148b },
+ { 0x000028f8, 0x0000149d },
+ { 0x000028fc, 0x000014ae },
+ { 0x00002900, 0x000014c0 },
+ { 0x00002904, 0x000014d1 },
+ { 0x00002908, 0x000014e3 },
+ { 0x0000290c, 0x000014f4 },
+ { 0x00002910, 0x00001506 },
+ { 0x00002914, 0x00001517 },
+ { 0x00002918, 0x00001529 },
+ { 0x0000291c, 0x0000153a },
+ { 0x00002920, 0x0000154c },
+ { 0x00002924, 0x0000155e },
+ { 0x00002928, 0x0000156f },
+ { 0x0000292c, 0x00001581 },
+ { 0x00002930, 0x00001593 },
+ { 0x00002934, 0x000015a5 },
+ { 0x00002938, 0x000015b7 },
+ { 0x0000293c, 0x000015c9 },
+ { 0x00002940, 0x000015db },
+ { 0x00002944, 0x000015ec },
+ { 0x00002948, 0x000015fe },
+ { 0x0000294c, 0x00001610 },
+ { 0x00002950, 0x00001623 },
+ { 0x00002954, 0x00001635 },
+ { 0x00002958, 0x00001647 },
+ { 0x0000295c, 0x00001659 },
+ { 0x00002960, 0x0000166b },
+ { 0x00002964, 0x0000167d },
+ { 0x00002968, 0x0000168f },
+ { 0x0000296c, 0x000016a2 },
+ { 0x00002970, 0x000016b4 },
+ { 0x00002974, 0x000016c6 },
+ { 0x00002978, 0x000016d9 },
+ { 0x0000297c, 0x000016eb },
+ { 0x00002980, 0x000016fe },
+ { 0x00002984, 0x00001710 },
+ { 0x00002988, 0x00001722 },
+ { 0x0000298c, 0x00001735 },
+ { 0x00002990, 0x00001748 },
+ { 0x00002994, 0x0000175a },
+ { 0x00002998, 0x0000176d },
+ { 0x0000299c, 0x0000177f },
+ { 0x000029a0, 0x00001792 },
+ { 0x000029a4, 0x000017a5 },
+ { 0x000029a8, 0x000017b8 },
+ { 0x000029ac, 0x000017ca },
+ { 0x000029b0, 0x000017dd },
+ { 0x000029b4, 0x000017f0 },
+ { 0x000029b8, 0x00001803 },
+ { 0x000029bc, 0x00001816 },
+ { 0x000029c0, 0x00001829 },
+ { 0x000029c4, 0x0000183c },
+ { 0x000029c8, 0x0000184f },
+ { 0x000029cc, 0x00001862 },
+ { 0x000029d0, 0x00001875 },
+ { 0x000029d4, 0x00001888 },
+ { 0x000029d8, 0x0000189b },
+ { 0x000029dc, 0x000018ae },
+ { 0x000029e0, 0x000018c1 },
+ { 0x000029e4, 0x000018d5 },
+ { 0x000029e8, 0x000018e8 },
+ { 0x000029ec, 0x000018fb },
+ { 0x000029f0, 0x0000190e },
+ { 0x000029f4, 0x00001922 },
+ { 0x000029f8, 0x00001935 },
+ { 0x000029fc, 0x00001949 },
+ { 0x00002a00, 0x0000195c },
+ { 0x00002a04, 0x0000196f },
+ { 0x00002a08, 0x00001983 },
+ { 0x00002a0c, 0x00001996 },
+ { 0x00002a10, 0x000019aa },
+ { 0x00002a14, 0x000019be },
+ { 0x00002a18, 0x000019d1 },
+ { 0x00002a1c, 0x000019e5 },
+ { 0x00002a20, 0x000019f9 },
+ { 0x00002a24, 0x00001a0c },
+ { 0x00002a28, 0x00001a20 },
+ { 0x00002a2c, 0x00001a34 },
+ { 0x00002a30, 0x00001a48 },
+ { 0x00002a34, 0x00001a5c },
+ { 0x00002a38, 0x00001a70 },
+ { 0x00002a3c, 0x00001a84 },
+ { 0x00002a40, 0x00001a97 },
+ { 0x00002a44, 0x00001aab },
+ { 0x00002a48, 0x00001ac0 },
+ { 0x00002a4c, 0x00001ad4 },
+ { 0x00002a50, 0x00001ae8 },
+ { 0x00002a54, 0x00001afc },
+ { 0x00002a58, 0x00001b10 },
+ { 0x00002a5c, 0x00001b24 },
+ { 0x00002a60, 0x00001b38 },
+ { 0x00002a64, 0x00001b4d },
+ { 0x00002a68, 0x00001b61 },
+ { 0x00002a6c, 0x00001b75 },
+ { 0x00002a70, 0x00001b8a },
+ { 0x00002a74, 0x00001b9e },
+ { 0x00002a78, 0x00001bb2 },
+ { 0x00002a7c, 0x00001bc7 },
+ { 0x00002a80, 0x00001bdb },
+ { 0x00002a84, 0x00001bf0 },
+ { 0x00002a88, 0x00001c04 },
+ { 0x00002a8c, 0x00001c19 },
+ { 0x00002a90, 0x00001c2e },
+ { 0x00002a94, 0x00001c42 },
+ { 0x00002a98, 0x00001c57 },
+ { 0x00002a9c, 0x00001c6c },
+ { 0x00002aa0, 0x00001c80 },
+ { 0x00002aa4, 0x00001c95 },
+ { 0x00002aa8, 0x00001caa },
+ { 0x00002aac, 0x00001cbf },
+ { 0x00002ab0, 0x00001cd4 },
+ { 0x00002ab4, 0x00001ce8 },
+ { 0x00002ab8, 0x00001cfd },
+ { 0x00002abc, 0x00001d12 },
+ { 0x00002ac0, 0x00001d27 },
+ { 0x00002ac4, 0x00001d3c },
+ { 0x00002ac8, 0x00001d51 },
+ { 0x00002acc, 0x00001d67 },
+ { 0x00002ad0, 0x00001d7c },
+ { 0x00002ad4, 0x00001d91 },
+ { 0x00002ad8, 0x00001da6 },
+ { 0x00002adc, 0x00001dbb },
+ { 0x00002ae0, 0x00001dd1 },
+ { 0x00002ae4, 0x00001de6 },
+ { 0x00002ae8, 0x00001dfb },
+ { 0x00002aec, 0x00001e10 },
+ { 0x00002af0, 0x00001e26 },
+ { 0x00002af4, 0x00001e3b },
+ { 0x00002af8, 0x00001e51 },
+ { 0x00002afc, 0x00001e66 },
+ { 0x00002b00, 0x00001e7c },
+ { 0x00002b04, 0x00001e91 },
+ { 0x00002b08, 0x00001ea7 },
+ { 0x00002b0c, 0x00001ebd },
+ { 0x00002b10, 0x00001ed2 },
+ { 0x00002b14, 0x00001ee8 },
+ { 0x00002b18, 0x00001efe },
+ { 0x00002b1c, 0x00001f13 },
+ { 0x00002b20, 0x00001f29 },
+ { 0x00002b24, 0x00001f3f },
+ { 0x00002b28, 0x00001f55 },
+ { 0x00002b2c, 0x00001f6b },
+ { 0x00002b30, 0x00001f81 },
+ { 0x00002b34, 0x00001f96 },
+ { 0x00002b38, 0x00001fac },
+ { 0x00002b3c, 0x00001fc2 },
+ { 0x00002b40, 0x00001fd9 },
+ { 0x00002b44, 0x00001fef },
+ { 0x00002b48, 0x00002005 },
+ { 0x00002b4c, 0x0000201b },
+ { 0x00002b50, 0x00002031 },
+ { 0x00002b54, 0x00002047 },
+ { 0x00002b58, 0x0000205d },
+ { 0x00002b5c, 0x00002074 },
+ { 0x00002b60, 0x0000208a },
+ { 0x00002b64, 0x000020a0 },
+ { 0x00002b68, 0x000020b7 },
+ { 0x00002b6c, 0x000020cd },
+ { 0x00002b70, 0x000020e4 },
+ { 0x00002b74, 0x000020fa },
+ { 0x00002b78, 0x00002111 },
+ { 0x00002b7c, 0x00002127 },
+ { 0x00002b80, 0x0000213e },
+ { 0x00002b84, 0x00002154 },
+ { 0x00002b88, 0x0000216b },
+ { 0x00002b8c, 0x00002182 },
+ { 0x00002b90, 0x00002198 },
+ { 0x00002b94, 0x000021af },
+ { 0x00002b98, 0x000021c6 },
+ { 0x00002b9c, 0x000021dd },
+ { 0x00002ba0, 0x000021f3 },
+ { 0x00002ba4, 0x0000220a },
+ { 0x00002ba8, 0x00002221 },
+ { 0x00002bac, 0x00002238 },
+ { 0x00002bb0, 0x0000224f },
+ { 0x00002bb4, 0x00002266 },
+ { 0x00002bb8, 0x0000227d },
+ { 0x00002bbc, 0x00002294 },
+ { 0x00002bc0, 0x000022ab },
+ { 0x00002bc4, 0x000022c2 },
+ { 0x00002bc8, 0x000022da },
+ { 0x00002bcc, 0x000022f1 },
+ { 0x00002bd0, 0x00002308 },
+ { 0x00002bd4, 0x0000231f },
+ { 0x00002bd8, 0x00002337 },
+ { 0x00002bdc, 0x0000234e },
+ { 0x00002be0, 0x00002365 },
+ { 0x00002be4, 0x0000237d },
+ { 0x00002be8, 0x00002394 },
+ { 0x00002bec, 0x000023ac },
+ { 0x00002bf0, 0x000023c3 },
+ { 0x00002bf4, 0x000023db },
+ { 0x00002bf8, 0x000023f2 },
+ { 0x00002bfc, 0x0000240a },
+ { 0x00002c00, 0x00002421 },
+ { 0x00002c04, 0x00002439 },
+ { 0x00002c08, 0x00002451 },
+ { 0x00002c0c, 0x00002469 },
+ { 0x00002c10, 0x00002480 },
+ { 0x00002c14, 0x00002498 },
+ { 0x00002c18, 0x000024b0 },
+ { 0x00002c1c, 0x000024c8 },
+ { 0x00002c20, 0x000024e0 },
+ { 0x00002c24, 0x000024f8 },
+ { 0x00002c28, 0x00002510 },
+ { 0x00002c2c, 0x00002528 },
+ { 0x00002c30, 0x00002540 },
+ { 0x00002c34, 0x00002558 },
+ { 0x00002c38, 0x00002570 },
+ { 0x00002c3c, 0x00002588 },
+ { 0x00002c40, 0x000025a0 },
+ { 0x00002c44, 0x000025b8 },
+ { 0x00002c48, 0x000025d0 },
+ { 0x00002c4c, 0x000025e9 },
+ { 0x00002c50, 0x00002601 },
+ { 0x00002c54, 0x00002619 },
+ { 0x00002c58, 0x00002632 },
+ { 0x00002c5c, 0x0000264a },
+ { 0x00002c60, 0x00002663 },
+ { 0x00002c64, 0x0000267b },
+ { 0x00002c68, 0x00002693 },
+ { 0x00002c6c, 0x000026ac },
+ { 0x00002c70, 0x000026c5 },
+ { 0x00002c74, 0x000026dd },
+ { 0x00002c78, 0x000026f6 },
+ { 0x00002c7c, 0x0000270e },
+ { 0x00002c80, 0x00002727 },
+ { 0x00002c84, 0x00002740 },
+ { 0x00002c88, 0x00002759 },
+ { 0x00002c8c, 0x00002771 },
+ { 0x00002c90, 0x0000278a },
+ { 0x00002c94, 0x000027a3 },
+ { 0x00002c98, 0x000027bc },
+ { 0x00002c9c, 0x000027d5 },
+ { 0x00002ca0, 0x000027ee },
+ { 0x00002ca4, 0x00002807 },
+ { 0x00002ca8, 0x00002820 },
+ { 0x00002cac, 0x00002839 },
+ { 0x00002cb0, 0x00002852 },
+ { 0x00002cb4, 0x0000286b },
+ { 0x00002cb8, 0x00002884 },
+ { 0x00002cbc, 0x0000289e },
+ { 0x00002cc0, 0x000028b7 },
+ { 0x00002cc4, 0x000028d0 },
+ { 0x00002cc8, 0x000028e9 },
+ { 0x00002ccc, 0x00002903 },
+ { 0x00002cd0, 0x0000291c },
+ { 0x00002cd4, 0x00002936 },
+ { 0x00002cd8, 0x0000294f },
+ { 0x00002cdc, 0x00002968 },
+ { 0x00002ce0, 0x00002982 },
+ { 0x00002ce4, 0x0000299c },
+ { 0x00002ce8, 0x000029b5 },
+ { 0x00002cec, 0x000029cf },
+ { 0x00002cf0, 0x000029e8 },
+ { 0x00002cf4, 0x00002a02 },
+ { 0x00002cf8, 0x00002a1c },
+ { 0x00002cfc, 0x00002a35 },
+ { 0x00002d00, 0x00002a4f },
+ { 0x00002d04, 0x00002a69 },
+ { 0x00002d08, 0x00002a83 },
+ { 0x00002d0c, 0x00002a9d },
+ { 0x00002d10, 0x00002ab7 },
+ { 0x00002d14, 0x00002ad1 },
+ { 0x00002d18, 0x00002aeb },
+ { 0x00002d1c, 0x00002b05 },
+ { 0x00002d20, 0x00002b1f },
+ { 0x00002d24, 0x00002b39 },
+ { 0x00002d28, 0x00002b53 },
+ { 0x00002d2c, 0x00002b6d },
+ { 0x00002d30, 0x00002b87 },
+ { 0x00002d34, 0x00002ba1 },
+ { 0x00002d38, 0x00002bbc },
+ { 0x00002d3c, 0x00002bd6 },
+ { 0x00002d40, 0x00002bf0 },
+ { 0x00002d44, 0x00002c0b },
+ { 0x00002d48, 0x00002c25 },
+ { 0x00002d4c, 0x00002c3f },
+ { 0x00002d50, 0x00002c5a },
+ { 0x00002d54, 0x00002c74 },
+ { 0x00002d58, 0x00002c8f },
+ { 0x00002d5c, 0x00002ca9 },
+ { 0x00002d60, 0x00002cc4 },
+ { 0x00002d64, 0x00002cdf },
+ { 0x00002d68, 0x00002cf9 },
+ { 0x00002d6c, 0x00002d14 },
+ { 0x00002d70, 0x00002d2f },
+ { 0x00002d74, 0x00002d49 },
+ { 0x00002d78, 0x00002d64 },
+ { 0x00002d7c, 0x00002d7f },
+ { 0x00002d80, 0x00002d9a },
+ { 0x00002d84, 0x00002db5 },
+ { 0x00002d88, 0x00002dd0 },
+ { 0x00002d8c, 0x00002deb },
+ { 0x00002d90, 0x00002e06 },
+ { 0x00002d94, 0x00002e21 },
+ { 0x00002d98, 0x00002e3c },
+ { 0x00002d9c, 0x00002e57 },
+ { 0x00002da0, 0x00002e72 },
+ { 0x00002da4, 0x00002e8d },
+ { 0x00002da8, 0x00002ea8 },
+ { 0x00002dac, 0x00002ec4 },
+ { 0x00002db0, 0x00002edf },
+ { 0x00002db4, 0x00002efa },
+ { 0x00002db8, 0x00002f16 },
+ { 0x00002dbc, 0x00002f31 },
+ { 0x00002dc0, 0x00002f4c },
+ { 0x00002dc4, 0x00002f68 },
+ { 0x00002dc8, 0x00002f83 },
+ { 0x00002dcc, 0x00002f9f },
+ { 0x00002dd0, 0x00002fba },
+ { 0x00002dd4, 0x00002fd6 },
+ { 0x00002dd8, 0x00002ff1 },
+ { 0x00002ddc, 0x0000300d },
+ { 0x00002de0, 0x00003029 },
+ { 0x00002de4, 0x00003044 },
+ { 0x00002de8, 0x00003060 },
+ { 0x00002dec, 0x0000307c },
+ { 0x00002df0, 0x00003098 },
+ { 0x00002df4, 0x000030b4 },
+ { 0x00002df8, 0x000030d0 },
+ { 0x00002dfc, 0x000030eb },
+ { 0x00002e00, 0x00003107 },
+ { 0x00002e04, 0x00003123 },
+ { 0x00002e08, 0x0000313f },
+ { 0x00002e0c, 0x0000315b },
+ { 0x00002e10, 0x00003178 },
+ { 0x00002e14, 0x00003194 },
+ { 0x00002e18, 0x000031b0 },
+ { 0x00002e1c, 0x000031cc },
+ { 0x00002e20, 0x000031e8 },
+ { 0x00002e24, 0x00003205 },
+ { 0x00002e28, 0x00003221 },
+ { 0x00002e2c, 0x0000323d },
+ { 0x00002e30, 0x0000325a },
+ { 0x00002e34, 0x00003276 },
+ { 0x00002e38, 0x00003292 },
+ { 0x00002e3c, 0x000032af },
+ { 0x00002e40, 0x000032cb },
+ { 0x00002e44, 0x000032e8 },
+ { 0x00002e48, 0x00003304 },
+ { 0x00002e4c, 0x00003321 },
+ { 0x00002e50, 0x0000333e },
+ { 0x00002e54, 0x0000335a },
+ { 0x00002e58, 0x00003377 },
+ { 0x00002e5c, 0x00003394 },
+ { 0x00002e60, 0x000033b1 },
+ { 0x00002e64, 0x000033cd },
+ { 0x00002e68, 0x000033ea },
+ { 0x00002e6c, 0x00003407 },
+ { 0x00002e70, 0x00003424 },
+ { 0x00002e74, 0x00003441 },
+ { 0x00002e78, 0x0000345e },
+ { 0x00002e7c, 0x0000347b },
+ { 0x00002e80, 0x00003498 },
+ { 0x00002e84, 0x000034b5 },
+ { 0x00002e88, 0x000034d2 },
+ { 0x00002e8c, 0x000034ef },
+ { 0x00002e90, 0x0000350d },
+ { 0x00002e94, 0x0000352a },
+ { 0x00002e98, 0x00003547 },
+ { 0x00002e9c, 0x00003564 },
+ { 0x00002ea0, 0x00003582 },
+ { 0x00002ea4, 0x0000359f },
+ { 0x00002ea8, 0x000035bc },
+ { 0x00002eac, 0x000035da },
+ { 0x00002eb0, 0x000035f7 },
+ { 0x00002eb4, 0x00003615 },
+ { 0x00002eb8, 0x00003632 },
+ { 0x00002ebc, 0x00003650 },
+ { 0x00002ec0, 0x0000366e },
+ { 0x00002ec4, 0x0000368b },
+ { 0x00002ec8, 0x000036a9 },
+ { 0x00002ecc, 0x000036c7 },
+ { 0x00002ed0, 0x000036e4 },
+ { 0x00002ed4, 0x00003702 },
+ { 0x00002ed8, 0x00003720 },
+ { 0x00002edc, 0x0000373e },
+ { 0x00002ee0, 0x0000375c },
+ { 0x00002ee4, 0x0000377a },
+ { 0x00002ee8, 0x00003798 },
+ { 0x00002eec, 0x000037b6 },
+ { 0x00002ef0, 0x000037d4 },
+ { 0x00002ef4, 0x000037f2 },
+ { 0x00002ef8, 0x00003810 },
+ { 0x00002efc, 0x0000382e },
+ { 0x00002f00, 0x0000384c },
+ { 0x00002f04, 0x0000386a },
+ { 0x00002f08, 0x00003888 },
+ { 0x00002f0c, 0x000038a7 },
+ { 0x00002f10, 0x000038c5 },
+ { 0x00002f14, 0x000038e3 },
+ { 0x00002f18, 0x00003902 },
+ { 0x00002f1c, 0x00003920 },
+ { 0x00002f20, 0x0000393f },
+ { 0x00002f24, 0x0000395d },
+ { 0x00002f28, 0x0000397c },
+ { 0x00002f2c, 0x0000399a },
+ { 0x00002f30, 0x000039b9 },
+ { 0x00002f34, 0x000039d7 },
+ { 0x00002f38, 0x000039f6 },
+ { 0x00002f3c, 0x00003a15 },
+ { 0x00002f40, 0x00003a33 },
+ { 0x00002f44, 0x00003a52 },
+ { 0x00002f48, 0x00003a71 },
+ { 0x00002f4c, 0x00003a90 },
+ { 0x00002f50, 0x00003aaf },
+ { 0x00002f54, 0x00003acd },
+ { 0x00002f58, 0x00003aec },
+ { 0x00002f5c, 0x00003b0b },
+ { 0x00002f60, 0x00003b2a },
+ { 0x00002f64, 0x00003b49 },
+ { 0x00002f68, 0x00003b68 },
+ { 0x00002f6c, 0x00003b87 },
+ { 0x00002f70, 0x00003ba7 },
+ { 0x00002f74, 0x00003bc6 },
+ { 0x00002f78, 0x00003be5 },
+ { 0x00002f7c, 0x00003c04 },
+ { 0x00002f80, 0x00003c24 },
+ { 0x00002f84, 0x00003c43 },
+ { 0x00002f88, 0x00003c62 },
+ { 0x00002f8c, 0x00003c82 },
+ { 0x00002f90, 0x00003ca1 },
+ { 0x00002f94, 0x00003cc0 },
+ { 0x00002f98, 0x00003ce0 },
+ { 0x00002f9c, 0x00003cff },
+ { 0x00002fa0, 0x00003d1f },
+ { 0x00002fa4, 0x00003d3f },
+ { 0x00002fa8, 0x00003d5e },
+ { 0x00002fac, 0x00003d7e },
+ { 0x00002fb0, 0x00003d9e },
+ { 0x00002fb4, 0x00003dbd },
+ { 0x00002fb8, 0x00003ddd },
+ { 0x00002fbc, 0x00003dfd },
+ { 0x00002fc0, 0x00003e1d },
+ { 0x00002fc4, 0x00003e3d },
+ { 0x00002fc8, 0x00003e5d },
+ { 0x00002fcc, 0x00003e7c },
+ { 0x00002fd0, 0x00003e9c },
+ { 0x00002fd4, 0x00003ebc },
+ { 0x00002fd8, 0x00003edc },
+ { 0x00002fdc, 0x00003efd },
+ { 0x00002fe0, 0x00003f1d },
+ { 0x00002fe4, 0x00003f3d },
+ { 0x00002fe8, 0x00003f5d },
+ { 0x00002fec, 0x00003f7d },
+ { 0x00002ff0, 0x00003f9e },
+ { 0x00002ff4, 0x00003fbe },
+ { 0x00002ff8, 0x00003fde },
+ { 0x00002ffc, 0x00003fff },
+};
+
+struct data_unit hdr10_pipe1_csca[] = {
+ { 0x00003004, 0x00004000 },
+ { 0x00003014, 0x00004000 },
+ { 0x00003024, 0x00004000 },
+ { 0x00003040, 0x000003ff },
+ { 0x00003044, 0x000003ff },
+ { 0x00003048, 0x000003ff },
+ { 0x0000304c, 0x0000000e },
+ { 0x00003068, 0x000003ff },
+ { 0x0000306c, 0x000003ff },
+ { 0x00003070, 0x000003ff },
+ { 0x00003080, 0x00000003 },
+ { 0x00003000, 0x00000003 },
+};
+
+struct data_unit hdr10_pipe1_cscb[] = {
+ { 0x00003804, 0x00007fe2 },
+ { 0x00003814, 0x00007fe2 },
+ { 0x00003824, 0x00007fe2 },
+ { 0x00003840, 0x00003fff },
+ { 0x00003844, 0x00003fff },
+ { 0x00003848, 0x00003fff },
+ { 0x0000384c, 0x00000001 },
+ { 0x00003868, 0x0ffc0000 },
+ { 0x0000386c, 0x0ffc0000 },
+ { 0x00003870, 0x0ffc0000 },
+ { 0x00003874, 0x00000000 },
+ { 0x00003800, 0x00000003 },
+};
+
+struct data_unit hdr10_pipe2_lut_a0[] = {
+ { 0x00004000, 0x00000000 },
+ { 0x00004004, 0x00000003 },
+ { 0x00004008, 0x00000007 },
+ { 0x0000400c, 0x0000000a },
+ { 0x00004010, 0x0000000e },
+ { 0x00004014, 0x00000011 },
+ { 0x00004018, 0x00000015 },
+ { 0x0000401c, 0x00000018 },
+ { 0x00004020, 0x0000001c },
+ { 0x00004024, 0x00000020 },
+ { 0x00004028, 0x00000023 },
+ { 0x0000402c, 0x00000027 },
+ { 0x00004030, 0x0000002a },
+ { 0x00004034, 0x0000002e },
+ { 0x00004038, 0x00000031 },
+ { 0x0000403c, 0x00000035 },
+ { 0x00004040, 0x00000038 },
+ { 0x00004044, 0x0000003c },
+ { 0x00004048, 0x00000040 },
+ { 0x0000404c, 0x00000043 },
+ { 0x00004050, 0x00000047 },
+ { 0x00004054, 0x0000004a },
+ { 0x00004058, 0x0000004e },
+ { 0x0000405c, 0x00000051 },
+ { 0x00004060, 0x00000055 },
+ { 0x00004064, 0x00000058 },
+ { 0x00004068, 0x0000005c },
+ { 0x0000406c, 0x00000060 },
+ { 0x00004070, 0x00000063 },
+ { 0x00004074, 0x00000067 },
+ { 0x00004078, 0x0000006a },
+ { 0x0000407c, 0x0000006e },
+ { 0x00004080, 0x00000071 },
+ { 0x00004084, 0x00000075 },
+ { 0x00004088, 0x00000078 },
+ { 0x0000408c, 0x0000007c },
+ { 0x00004090, 0x00000080 },
+ { 0x00004094, 0x00000083 },
+ { 0x00004098, 0x00000087 },
+ { 0x0000409c, 0x0000008a },
+ { 0x000040a0, 0x0000008e },
+ { 0x000040a4, 0x00000091 },
+ { 0x000040a8, 0x00000095 },
+ { 0x000040ac, 0x00000099 },
+ { 0x000040b0, 0x0000009c },
+ { 0x000040b4, 0x000000a0 },
+ { 0x000040b8, 0x000000a3 },
+ { 0x000040bc, 0x000000a7 },
+ { 0x000040c0, 0x000000aa },
+ { 0x000040c4, 0x000000ae },
+ { 0x000040c8, 0x000000b1 },
+ { 0x000040cc, 0x000000b5 },
+ { 0x000040d0, 0x000000b9 },
+ { 0x000040d4, 0x000000bc },
+ { 0x000040d8, 0x000000c0 },
+ { 0x000040dc, 0x000000c3 },
+ { 0x000040e0, 0x000000c7 },
+ { 0x000040e4, 0x000000ca },
+ { 0x000040e8, 0x000000ce },
+ { 0x000040ec, 0x000000d1 },
+ { 0x000040f0, 0x000000d5 },
+ { 0x000040f4, 0x000000d9 },
+ { 0x000040f8, 0x000000dc },
+ { 0x000040fc, 0x000000e0 },
+ { 0x00004100, 0x000000e3 },
+ { 0x00004104, 0x000000e7 },
+ { 0x00004108, 0x000000ea },
+ { 0x0000410c, 0x000000ee },
+ { 0x00004110, 0x000000f1 },
+ { 0x00004114, 0x000000f5 },
+ { 0x00004118, 0x000000f9 },
+ { 0x0000411c, 0x000000fc },
+ { 0x00004120, 0x00000100 },
+ { 0x00004124, 0x00000103 },
+ { 0x00004128, 0x00000107 },
+ { 0x0000412c, 0x0000010a },
+ { 0x00004130, 0x0000010e },
+ { 0x00004134, 0x00000112 },
+ { 0x00004138, 0x00000115 },
+ { 0x0000413c, 0x00000119 },
+ { 0x00004140, 0x0000011c },
+ { 0x00004144, 0x00000120 },
+ { 0x00004148, 0x00000123 },
+ { 0x0000414c, 0x00000126 },
+ { 0x00004150, 0x0000012a },
+ { 0x00004154, 0x0000012d },
+ { 0x00004158, 0x00000131 },
+ { 0x0000415c, 0x00000134 },
+ { 0x00004160, 0x00000138 },
+ { 0x00004164, 0x0000013c },
+ { 0x00004168, 0x0000013f },
+ { 0x0000416c, 0x00000143 },
+ { 0x00004170, 0x00000147 },
+ { 0x00004174, 0x0000014b },
+ { 0x00004178, 0x0000014e },
+ { 0x0000417c, 0x00000152 },
+ { 0x00004180, 0x00000156 },
+ { 0x00004184, 0x0000015a },
+ { 0x00004188, 0x0000015e },
+ { 0x0000418c, 0x00000162 },
+ { 0x00004190, 0x00000166 },
+ { 0x00004194, 0x0000016a },
+ { 0x00004198, 0x0000016e },
+ { 0x0000419c, 0x00000172 },
+ { 0x000041a0, 0x00000176 },
+ { 0x000041a4, 0x0000017a },
+ { 0x000041a8, 0x0000017e },
+ { 0x000041ac, 0x00000182 },
+ { 0x000041b0, 0x00000186 },
+ { 0x000041b4, 0x0000018a },
+ { 0x000041b8, 0x0000018f },
+ { 0x000041bc, 0x00000193 },
+ { 0x000041c0, 0x00000197 },
+ { 0x000041c4, 0x0000019b },
+ { 0x000041c8, 0x000001a0 },
+ { 0x000041cc, 0x000001a4 },
+ { 0x000041d0, 0x000001a8 },
+ { 0x000041d4, 0x000001ad },
+ { 0x000041d8, 0x000001b1 },
+ { 0x000041dc, 0x000001b5 },
+ { 0x000041e0, 0x000001ba },
+ { 0x000041e4, 0x000001be },
+ { 0x000041e8, 0x000001c3 },
+ { 0x000041ec, 0x000001c7 },
+ { 0x000041f0, 0x000001cc },
+ { 0x000041f4, 0x000001d0 },
+ { 0x000041f8, 0x000001d5 },
+ { 0x000041fc, 0x000001d9 },
+ { 0x00004200, 0x000001de },
+ { 0x00004204, 0x000001e3 },
+ { 0x00004208, 0x000001e7 },
+ { 0x0000420c, 0x000001ec },
+ { 0x00004210, 0x000001f1 },
+ { 0x00004214, 0x000001f6 },
+ { 0x00004218, 0x000001fa },
+ { 0x0000421c, 0x000001ff },
+ { 0x00004220, 0x00000204 },
+ { 0x00004224, 0x00000209 },
+ { 0x00004228, 0x0000020e },
+ { 0x0000422c, 0x00000213 },
+ { 0x00004230, 0x00000217 },
+ { 0x00004234, 0x0000021c },
+ { 0x00004238, 0x00000221 },
+ { 0x0000423c, 0x00000226 },
+ { 0x00004240, 0x0000022b },
+ { 0x00004244, 0x00000230 },
+ { 0x00004248, 0x00000236 },
+ { 0x0000424c, 0x0000023b },
+ { 0x00004250, 0x00000240 },
+ { 0x00004254, 0x00000245 },
+ { 0x00004258, 0x0000024a },
+ { 0x0000425c, 0x0000024f },
+ { 0x00004260, 0x00000255 },
+ { 0x00004264, 0x0000025a },
+ { 0x00004268, 0x0000025f },
+ { 0x0000426c, 0x00000264 },
+ { 0x00004270, 0x0000026a },
+ { 0x00004274, 0x0000026f },
+ { 0x00004278, 0x00000274 },
+ { 0x0000427c, 0x0000027a },
+ { 0x00004280, 0x0000027f },
+ { 0x00004284, 0x00000285 },
+ { 0x00004288, 0x0000028a },
+ { 0x0000428c, 0x00000290 },
+ { 0x00004290, 0x00000295 },
+ { 0x00004294, 0x0000029b },
+ { 0x00004298, 0x000002a0 },
+ { 0x0000429c, 0x000002a6 },
+ { 0x000042a0, 0x000002ac },
+ { 0x000042a4, 0x000002b1 },
+ { 0x000042a8, 0x000002b7 },
+ { 0x000042ac, 0x000002bd },
+ { 0x000042b0, 0x000002c2 },
+ { 0x000042b4, 0x000002c8 },
+ { 0x000042b8, 0x000002ce },
+ { 0x000042bc, 0x000002d4 },
+ { 0x000042c0, 0x000002da },
+ { 0x000042c4, 0x000002df },
+ { 0x000042c8, 0x000002e5 },
+ { 0x000042cc, 0x000002eb },
+ { 0x000042d0, 0x000002f1 },
+ { 0x000042d4, 0x000002f7 },
+ { 0x000042d8, 0x000002fd },
+ { 0x000042dc, 0x00000303 },
+ { 0x000042e0, 0x00000309 },
+ { 0x000042e4, 0x0000030f },
+ { 0x000042e8, 0x00000315 },
+ { 0x000042ec, 0x0000031c },
+ { 0x000042f0, 0x00000322 },
+ { 0x000042f4, 0x00000328 },
+ { 0x000042f8, 0x0000032e },
+ { 0x000042fc, 0x00000334 },
+ { 0x00004300, 0x0000033b },
+ { 0x00004304, 0x00000341 },
+ { 0x00004308, 0x00000347 },
+ { 0x0000430c, 0x0000034d },
+ { 0x00004310, 0x00000354 },
+ { 0x00004314, 0x0000035a },
+ { 0x00004318, 0x00000361 },
+ { 0x0000431c, 0x00000367 },
+ { 0x00004320, 0x0000036d },
+ { 0x00004324, 0x00000374 },
+ { 0x00004328, 0x0000037a },
+ { 0x0000432c, 0x00000381 },
+ { 0x00004330, 0x00000388 },
+ { 0x00004334, 0x0000038e },
+ { 0x00004338, 0x00000395 },
+ { 0x0000433c, 0x0000039b },
+ { 0x00004340, 0x000003a2 },
+ { 0x00004344, 0x000003a9 },
+ { 0x00004348, 0x000003b0 },
+ { 0x0000434c, 0x000003b6 },
+ { 0x00004350, 0x000003bd },
+ { 0x00004354, 0x000003c4 },
+ { 0x00004358, 0x000003cb },
+ { 0x0000435c, 0x000003d2 },
+ { 0x00004360, 0x000003d8 },
+ { 0x00004364, 0x000003df },
+ { 0x00004368, 0x000003e6 },
+ { 0x0000436c, 0x000003ed },
+ { 0x00004370, 0x000003f4 },
+ { 0x00004374, 0x000003fb },
+ { 0x00004378, 0x00000402 },
+ { 0x0000437c, 0x00000409 },
+ { 0x00004380, 0x00000411 },
+ { 0x00004384, 0x00000418 },
+ { 0x00004388, 0x0000041f },
+ { 0x0000438c, 0x00000426 },
+ { 0x00004390, 0x0000042d },
+ { 0x00004394, 0x00000434 },
+ { 0x00004398, 0x0000043c },
+ { 0x0000439c, 0x00000443 },
+ { 0x000043a0, 0x0000044a },
+ { 0x000043a4, 0x00000452 },
+ { 0x000043a8, 0x00000459 },
+ { 0x000043ac, 0x00000460 },
+ { 0x000043b0, 0x00000468 },
+ { 0x000043b4, 0x0000046f },
+ { 0x000043b8, 0x00000477 },
+ { 0x000043bc, 0x0000047e },
+ { 0x000043c0, 0x00000486 },
+ { 0x000043c4, 0x0000048d },
+ { 0x000043c8, 0x00000495 },
+ { 0x000043cc, 0x0000049c },
+ { 0x000043d0, 0x000004a4 },
+ { 0x000043d4, 0x000004ac },
+ { 0x000043d8, 0x000004b3 },
+ { 0x000043dc, 0x000004bb },
+ { 0x000043e0, 0x000004c3 },
+ { 0x000043e4, 0x000004cb },
+ { 0x000043e8, 0x000004d3 },
+ { 0x000043ec, 0x000004da },
+ { 0x000043f0, 0x000004e2 },
+ { 0x000043f4, 0x000004ea },
+ { 0x000043f8, 0x000004f2 },
+ { 0x000043fc, 0x000004fa },
+ { 0x00004400, 0x00000502 },
+ { 0x00004404, 0x0000050a },
+ { 0x00004408, 0x00000512 },
+ { 0x0000440c, 0x0000051a },
+ { 0x00004410, 0x00000522 },
+ { 0x00004414, 0x0000052a },
+ { 0x00004418, 0x00000532 },
+ { 0x0000441c, 0x0000053a },
+ { 0x00004420, 0x00000543 },
+ { 0x00004424, 0x0000054b },
+ { 0x00004428, 0x00000553 },
+ { 0x0000442c, 0x0000055b },
+ { 0x00004430, 0x00000564 },
+ { 0x00004434, 0x0000056c },
+ { 0x00004438, 0x00000574 },
+ { 0x0000443c, 0x0000057d },
+ { 0x00004440, 0x00000585 },
+ { 0x00004444, 0x0000058d },
+ { 0x00004448, 0x00000596 },
+ { 0x0000444c, 0x0000059e },
+ { 0x00004450, 0x000005a7 },
+ { 0x00004454, 0x000005af },
+ { 0x00004458, 0x000005b8 },
+ { 0x0000445c, 0x000005c1 },
+ { 0x00004460, 0x000005c9 },
+ { 0x00004464, 0x000005d2 },
+ { 0x00004468, 0x000005db },
+ { 0x0000446c, 0x000005e3 },
+ { 0x00004470, 0x000005ec },
+ { 0x00004474, 0x000005f5 },
+ { 0x00004478, 0x000005fe },
+ { 0x0000447c, 0x00000606 },
+ { 0x00004480, 0x0000060f },
+ { 0x00004484, 0x00000618 },
+ { 0x00004488, 0x00000621 },
+ { 0x0000448c, 0x0000062a },
+ { 0x00004490, 0x00000633 },
+ { 0x00004494, 0x0000063c },
+ { 0x00004498, 0x00000645 },
+ { 0x0000449c, 0x0000064e },
+ { 0x000044a0, 0x00000657 },
+ { 0x000044a4, 0x00000660 },
+ { 0x000044a8, 0x00000669 },
+ { 0x000044ac, 0x00000672 },
+ { 0x000044b0, 0x0000067b },
+ { 0x000044b4, 0x00000685 },
+ { 0x000044b8, 0x0000068e },
+ { 0x000044bc, 0x00000697 },
+ { 0x000044c0, 0x000006a0 },
+ { 0x000044c4, 0x000006aa },
+ { 0x000044c8, 0x000006b3 },
+ { 0x000044cc, 0x000006bd },
+ { 0x000044d0, 0x000006c6 },
+ { 0x000044d4, 0x000006cf },
+ { 0x000044d8, 0x000006d9 },
+ { 0x000044dc, 0x000006e2 },
+ { 0x000044e0, 0x000006ec },
+ { 0x000044e4, 0x000006f5 },
+ { 0x000044e8, 0x000006ff },
+ { 0x000044ec, 0x00000709 },
+ { 0x000044f0, 0x00000712 },
+ { 0x000044f4, 0x0000071c },
+ { 0x000044f8, 0x00000726 },
+ { 0x000044fc, 0x0000072f },
+ { 0x00004500, 0x00000739 },
+ { 0x00004504, 0x00000743 },
+ { 0x00004508, 0x0000074d },
+ { 0x0000450c, 0x00000756 },
+ { 0x00004510, 0x00000760 },
+ { 0x00004514, 0x0000076a },
+ { 0x00004518, 0x00000774 },
+ { 0x0000451c, 0x0000077e },
+ { 0x00004520, 0x00000788 },
+ { 0x00004524, 0x00000792 },
+ { 0x00004528, 0x0000079c },
+ { 0x0000452c, 0x000007a6 },
+ { 0x00004530, 0x000007b0 },
+ { 0x00004534, 0x000007ba },
+ { 0x00004538, 0x000007c4 },
+ { 0x0000453c, 0x000007cf },
+ { 0x00004540, 0x000007d9 },
+ { 0x00004544, 0x000007e3 },
+ { 0x00004548, 0x000007ed },
+ { 0x0000454c, 0x000007f7 },
+ { 0x00004550, 0x00000802 },
+ { 0x00004554, 0x0000080c },
+ { 0x00004558, 0x00000816 },
+ { 0x0000455c, 0x00000821 },
+ { 0x00004560, 0x0000082b },
+ { 0x00004564, 0x00000836 },
+ { 0x00004568, 0x00000840 },
+ { 0x0000456c, 0x0000084b },
+ { 0x00004570, 0x00000855 },
+ { 0x00004574, 0x00000860 },
+ { 0x00004578, 0x0000086a },
+ { 0x0000457c, 0x00000875 },
+ { 0x00004580, 0x00000880 },
+ { 0x00004584, 0x0000088a },
+ { 0x00004588, 0x00000895 },
+ { 0x0000458c, 0x000008a0 },
+ { 0x00004590, 0x000008ab },
+ { 0x00004594, 0x000008b5 },
+ { 0x00004598, 0x000008c0 },
+ { 0x0000459c, 0x000008cb },
+ { 0x000045a0, 0x000008d6 },
+ { 0x000045a4, 0x000008e1 },
+ { 0x000045a8, 0x000008ec },
+ { 0x000045ac, 0x000008f7 },
+ { 0x000045b0, 0x00000902 },
+ { 0x000045b4, 0x0000090d },
+ { 0x000045b8, 0x00000918 },
+ { 0x000045bc, 0x00000923 },
+ { 0x000045c0, 0x0000092e },
+ { 0x000045c4, 0x00000939 },
+ { 0x000045c8, 0x00000944 },
+ { 0x000045cc, 0x00000950 },
+ { 0x000045d0, 0x0000095b },
+ { 0x000045d4, 0x00000966 },
+ { 0x000045d8, 0x00000971 },
+ { 0x000045dc, 0x0000097d },
+ { 0x000045e0, 0x00000988 },
+ { 0x000045e4, 0x00000993 },
+ { 0x000045e8, 0x0000099f },
+ { 0x000045ec, 0x000009aa },
+ { 0x000045f0, 0x000009b6 },
+ { 0x000045f4, 0x000009c1 },
+ { 0x000045f8, 0x000009cd },
+ { 0x000045fc, 0x000009d8 },
+ { 0x00004600, 0x000009e4 },
+ { 0x00004604, 0x000009f0 },
+ { 0x00004608, 0x000009fb },
+ { 0x0000460c, 0x00000a07 },
+ { 0x00004610, 0x00000a13 },
+ { 0x00004614, 0x00000a1e },
+ { 0x00004618, 0x00000a2a },
+ { 0x0000461c, 0x00000a36 },
+ { 0x00004620, 0x00000a42 },
+ { 0x00004624, 0x00000a4e },
+ { 0x00004628, 0x00000a59 },
+ { 0x0000462c, 0x00000a65 },
+ { 0x00004630, 0x00000a71 },
+ { 0x00004634, 0x00000a7d },
+ { 0x00004638, 0x00000a89 },
+ { 0x0000463c, 0x00000a95 },
+ { 0x00004640, 0x00000aa1 },
+ { 0x00004644, 0x00000aad },
+ { 0x00004648, 0x00000ab9 },
+ { 0x0000464c, 0x00000ac6 },
+ { 0x00004650, 0x00000ad2 },
+ { 0x00004654, 0x00000ade },
+ { 0x00004658, 0x00000aea },
+ { 0x0000465c, 0x00000af6 },
+ { 0x00004660, 0x00000b03 },
+ { 0x00004664, 0x00000b0f },
+ { 0x00004668, 0x00000b1b },
+ { 0x0000466c, 0x00000b28 },
+ { 0x00004670, 0x00000b34 },
+ { 0x00004674, 0x00000b41 },
+ { 0x00004678, 0x00000b4d },
+ { 0x0000467c, 0x00000b5a },
+ { 0x00004680, 0x00000b66 },
+ { 0x00004684, 0x00000b73 },
+ { 0x00004688, 0x00000b7f },
+ { 0x0000468c, 0x00000b8c },
+ { 0x00004690, 0x00000b98 },
+ { 0x00004694, 0x00000ba5 },
+ { 0x00004698, 0x00000bb2 },
+ { 0x0000469c, 0x00000bbf },
+ { 0x000046a0, 0x00000bcb },
+ { 0x000046a4, 0x00000bd8 },
+ { 0x000046a8, 0x00000be5 },
+ { 0x000046ac, 0x00000bf2 },
+ { 0x000046b0, 0x00000bff },
+ { 0x000046b4, 0x00000c0c },
+ { 0x000046b8, 0x00000c19 },
+ { 0x000046bc, 0x00000c25 },
+ { 0x000046c0, 0x00000c32 },
+ { 0x000046c4, 0x00000c40 },
+ { 0x000046c8, 0x00000c4d },
+ { 0x000046cc, 0x00000c5a },
+ { 0x000046d0, 0x00000c67 },
+ { 0x000046d4, 0x00000c74 },
+ { 0x000046d8, 0x00000c81 },
+ { 0x000046dc, 0x00000c8e },
+ { 0x000046e0, 0x00000c9c },
+ { 0x000046e4, 0x00000ca9 },
+ { 0x000046e8, 0x00000cb6 },
+ { 0x000046ec, 0x00000cc3 },
+ { 0x000046f0, 0x00000cd1 },
+ { 0x000046f4, 0x00000cde },
+ { 0x000046f8, 0x00000cec },
+ { 0x000046fc, 0x00000cf9 },
+ { 0x00004700, 0x00000d07 },
+ { 0x00004704, 0x00000d14 },
+ { 0x00004708, 0x00000d22 },
+ { 0x0000470c, 0x00000d2f },
+ { 0x00004710, 0x00000d3d },
+ { 0x00004714, 0x00000d4a },
+ { 0x00004718, 0x00000d58 },
+ { 0x0000471c, 0x00000d66 },
+ { 0x00004720, 0x00000d73 },
+ { 0x00004724, 0x00000d81 },
+ { 0x00004728, 0x00000d8f },
+ { 0x0000472c, 0x00000d9d },
+ { 0x00004730, 0x00000dab },
+ { 0x00004734, 0x00000db8 },
+ { 0x00004738, 0x00000dc6 },
+ { 0x0000473c, 0x00000dd4 },
+ { 0x00004740, 0x00000de2 },
+ { 0x00004744, 0x00000df0 },
+ { 0x00004748, 0x00000dfe },
+ { 0x0000474c, 0x00000e0c },
+ { 0x00004750, 0x00000e1a },
+ { 0x00004754, 0x00000e29 },
+ { 0x00004758, 0x00000e37 },
+ { 0x0000475c, 0x00000e45 },
+ { 0x00004760, 0x00000e53 },
+ { 0x00004764, 0x00000e61 },
+ { 0x00004768, 0x00000e70 },
+ { 0x0000476c, 0x00000e7e },
+ { 0x00004770, 0x00000e8c },
+ { 0x00004774, 0x00000e9a },
+ { 0x00004778, 0x00000ea9 },
+ { 0x0000477c, 0x00000eb7 },
+ { 0x00004780, 0x00000ec6 },
+ { 0x00004784, 0x00000ed4 },
+ { 0x00004788, 0x00000ee3 },
+ { 0x0000478c, 0x00000ef1 },
+ { 0x00004790, 0x00000f00 },
+ { 0x00004794, 0x00000f0e },
+ { 0x00004798, 0x00000f1d },
+ { 0x0000479c, 0x00000f2c },
+ { 0x000047a0, 0x00000f3a },
+ { 0x000047a4, 0x00000f49 },
+ { 0x000047a8, 0x00000f58 },
+ { 0x000047ac, 0x00000f67 },
+ { 0x000047b0, 0x00000f75 },
+ { 0x000047b4, 0x00000f84 },
+ { 0x000047b8, 0x00000f93 },
+ { 0x000047bc, 0x00000fa2 },
+ { 0x000047c0, 0x00000fb1 },
+ { 0x000047c4, 0x00000fc0 },
+ { 0x000047c8, 0x00000fcf },
+ { 0x000047cc, 0x00000fde },
+ { 0x000047d0, 0x00000fed },
+ { 0x000047d4, 0x00000ffc },
+ { 0x000047d8, 0x0000100b },
+ { 0x000047dc, 0x0000101a },
+ { 0x000047e0, 0x0000102a },
+ { 0x000047e4, 0x00001039 },
+ { 0x000047e8, 0x00001048 },
+ { 0x000047ec, 0x00001057 },
+ { 0x000047f0, 0x00001067 },
+ { 0x000047f4, 0x00001076 },
+ { 0x000047f8, 0x00001085 },
+ { 0x000047fc, 0x00001095 },
+ { 0x00004800, 0x000010a4 },
+ { 0x00004804, 0x000010b4 },
+ { 0x00004808, 0x000010c3 },
+ { 0x0000480c, 0x000010d3 },
+ { 0x00004810, 0x000010e2 },
+ { 0x00004814, 0x000010f2 },
+ { 0x00004818, 0x00001101 },
+ { 0x0000481c, 0x00001111 },
+ { 0x00004820, 0x00001121 },
+ { 0x00004824, 0x00001130 },
+ { 0x00004828, 0x00001140 },
+ { 0x0000482c, 0x00001150 },
+ { 0x00004830, 0x00001160 },
+ { 0x00004834, 0x0000116f },
+ { 0x00004838, 0x0000117f },
+ { 0x0000483c, 0x0000118f },
+ { 0x00004840, 0x0000119f },
+ { 0x00004844, 0x000011af },
+ { 0x00004848, 0x000011bf },
+ { 0x0000484c, 0x000011cf },
+ { 0x00004850, 0x000011df },
+ { 0x00004854, 0x000011ef },
+ { 0x00004858, 0x000011ff },
+ { 0x0000485c, 0x0000120f },
+ { 0x00004860, 0x0000121f },
+ { 0x00004864, 0x00001230 },
+ { 0x00004868, 0x00001240 },
+ { 0x0000486c, 0x00001250 },
+ { 0x00004870, 0x00001260 },
+ { 0x00004874, 0x00001271 },
+ { 0x00004878, 0x00001281 },
+ { 0x0000487c, 0x00001291 },
+ { 0x00004880, 0x000012a2 },
+ { 0x00004884, 0x000012b2 },
+ { 0x00004888, 0x000012c3 },
+ { 0x0000488c, 0x000012d3 },
+ { 0x00004890, 0x000012e4 },
+ { 0x00004894, 0x000012f4 },
+ { 0x00004898, 0x00001305 },
+ { 0x0000489c, 0x00001316 },
+ { 0x000048a0, 0x00001326 },
+ { 0x000048a4, 0x00001337 },
+ { 0x000048a8, 0x00001348 },
+ { 0x000048ac, 0x00001359 },
+ { 0x000048b0, 0x00001369 },
+ { 0x000048b4, 0x0000137a },
+ { 0x000048b8, 0x0000138b },
+ { 0x000048bc, 0x0000139c },
+ { 0x000048c0, 0x000013ad },
+ { 0x000048c4, 0x000013be },
+ { 0x000048c8, 0x000013cf },
+ { 0x000048cc, 0x000013e0 },
+ { 0x000048d0, 0x000013f1 },
+ { 0x000048d4, 0x00001402 },
+ { 0x000048d8, 0x00001413 },
+ { 0x000048dc, 0x00001424 },
+ { 0x000048e0, 0x00001435 },
+ { 0x000048e4, 0x00001446 },
+ { 0x000048e8, 0x00001458 },
+ { 0x000048ec, 0x00001469 },
+ { 0x000048f0, 0x0000147a },
+ { 0x000048f4, 0x0000148b },
+ { 0x000048f8, 0x0000149d },
+ { 0x000048fc, 0x000014ae },
+ { 0x00004900, 0x000014c0 },
+ { 0x00004904, 0x000014d1 },
+ { 0x00004908, 0x000014e3 },
+ { 0x0000490c, 0x000014f4 },
+ { 0x00004910, 0x00001506 },
+ { 0x00004914, 0x00001517 },
+ { 0x00004918, 0x00001529 },
+ { 0x0000491c, 0x0000153a },
+ { 0x00004920, 0x0000154c },
+ { 0x00004924, 0x0000155e },
+ { 0x00004928, 0x0000156f },
+ { 0x0000492c, 0x00001581 },
+ { 0x00004930, 0x00001593 },
+ { 0x00004934, 0x000015a5 },
+ { 0x00004938, 0x000015b7 },
+ { 0x0000493c, 0x000015c9 },
+ { 0x00004940, 0x000015db },
+ { 0x00004944, 0x000015ec },
+ { 0x00004948, 0x000015fe },
+ { 0x0000494c, 0x00001610 },
+ { 0x00004950, 0x00001623 },
+ { 0x00004954, 0x00001635 },
+ { 0x00004958, 0x00001647 },
+ { 0x0000495c, 0x00001659 },
+ { 0x00004960, 0x0000166b },
+ { 0x00004964, 0x0000167d },
+ { 0x00004968, 0x0000168f },
+ { 0x0000496c, 0x000016a2 },
+ { 0x00004970, 0x000016b4 },
+ { 0x00004974, 0x000016c6 },
+ { 0x00004978, 0x000016d9 },
+ { 0x0000497c, 0x000016eb },
+ { 0x00004980, 0x000016fe },
+ { 0x00004984, 0x00001710 },
+ { 0x00004988, 0x00001722 },
+ { 0x0000498c, 0x00001735 },
+ { 0x00004990, 0x00001748 },
+ { 0x00004994, 0x0000175a },
+ { 0x00004998, 0x0000176d },
+ { 0x0000499c, 0x0000177f },
+ { 0x000049a0, 0x00001792 },
+ { 0x000049a4, 0x000017a5 },
+ { 0x000049a8, 0x000017b8 },
+ { 0x000049ac, 0x000017ca },
+ { 0x000049b0, 0x000017dd },
+ { 0x000049b4, 0x000017f0 },
+ { 0x000049b8, 0x00001803 },
+ { 0x000049bc, 0x00001816 },
+ { 0x000049c0, 0x00001829 },
+ { 0x000049c4, 0x0000183c },
+ { 0x000049c8, 0x0000184f },
+ { 0x000049cc, 0x00001862 },
+ { 0x000049d0, 0x00001875 },
+ { 0x000049d4, 0x00001888 },
+ { 0x000049d8, 0x0000189b },
+ { 0x000049dc, 0x000018ae },
+ { 0x000049e0, 0x000018c1 },
+ { 0x000049e4, 0x000018d5 },
+ { 0x000049e8, 0x000018e8 },
+ { 0x000049ec, 0x000018fb },
+ { 0x000049f0, 0x0000190e },
+ { 0x000049f4, 0x00001922 },
+ { 0x000049f8, 0x00001935 },
+ { 0x000049fc, 0x00001949 },
+ { 0x00004a00, 0x0000195c },
+ { 0x00004a04, 0x0000196f },
+ { 0x00004a08, 0x00001983 },
+ { 0x00004a0c, 0x00001996 },
+ { 0x00004a10, 0x000019aa },
+ { 0x00004a14, 0x000019be },
+ { 0x00004a18, 0x000019d1 },
+ { 0x00004a1c, 0x000019e5 },
+ { 0x00004a20, 0x000019f9 },
+ { 0x00004a24, 0x00001a0c },
+ { 0x00004a28, 0x00001a20 },
+ { 0x00004a2c, 0x00001a34 },
+ { 0x00004a30, 0x00001a48 },
+ { 0x00004a34, 0x00001a5c },
+ { 0x00004a38, 0x00001a70 },
+ { 0x00004a3c, 0x00001a84 },
+ { 0x00004a40, 0x00001a97 },
+ { 0x00004a44, 0x00001aab },
+ { 0x00004a48, 0x00001ac0 },
+ { 0x00004a4c, 0x00001ad4 },
+ { 0x00004a50, 0x00001ae8 },
+ { 0x00004a54, 0x00001afc },
+ { 0x00004a58, 0x00001b10 },
+ { 0x00004a5c, 0x00001b24 },
+ { 0x00004a60, 0x00001b38 },
+ { 0x00004a64, 0x00001b4d },
+ { 0x00004a68, 0x00001b61 },
+ { 0x00004a6c, 0x00001b75 },
+ { 0x00004a70, 0x00001b8a },
+ { 0x00004a74, 0x00001b9e },
+ { 0x00004a78, 0x00001bb2 },
+ { 0x00004a7c, 0x00001bc7 },
+ { 0x00004a80, 0x00001bdb },
+ { 0x00004a84, 0x00001bf0 },
+ { 0x00004a88, 0x00001c04 },
+ { 0x00004a8c, 0x00001c19 },
+ { 0x00004a90, 0x00001c2e },
+ { 0x00004a94, 0x00001c42 },
+ { 0x00004a98, 0x00001c57 },
+ { 0x00004a9c, 0x00001c6c },
+ { 0x00004aa0, 0x00001c80 },
+ { 0x00004aa4, 0x00001c95 },
+ { 0x00004aa8, 0x00001caa },
+ { 0x00004aac, 0x00001cbf },
+ { 0x00004ab0, 0x00001cd4 },
+ { 0x00004ab4, 0x00001ce8 },
+ { 0x00004ab8, 0x00001cfd },
+ { 0x00004abc, 0x00001d12 },
+ { 0x00004ac0, 0x00001d27 },
+ { 0x00004ac4, 0x00001d3c },
+ { 0x00004ac8, 0x00001d51 },
+ { 0x00004acc, 0x00001d67 },
+ { 0x00004ad0, 0x00001d7c },
+ { 0x00004ad4, 0x00001d91 },
+ { 0x00004ad8, 0x00001da6 },
+ { 0x00004adc, 0x00001dbb },
+ { 0x00004ae0, 0x00001dd1 },
+ { 0x00004ae4, 0x00001de6 },
+ { 0x00004ae8, 0x00001dfb },
+ { 0x00004aec, 0x00001e10 },
+ { 0x00004af0, 0x00001e26 },
+ { 0x00004af4, 0x00001e3b },
+ { 0x00004af8, 0x00001e51 },
+ { 0x00004afc, 0x00001e66 },
+ { 0x00004b00, 0x00001e7c },
+ { 0x00004b04, 0x00001e91 },
+ { 0x00004b08, 0x00001ea7 },
+ { 0x00004b0c, 0x00001ebd },
+ { 0x00004b10, 0x00001ed2 },
+ { 0x00004b14, 0x00001ee8 },
+ { 0x00004b18, 0x00001efe },
+ { 0x00004b1c, 0x00001f13 },
+ { 0x00004b20, 0x00001f29 },
+ { 0x00004b24, 0x00001f3f },
+ { 0x00004b28, 0x00001f55 },
+ { 0x00004b2c, 0x00001f6b },
+ { 0x00004b30, 0x00001f81 },
+ { 0x00004b34, 0x00001f96 },
+ { 0x00004b38, 0x00001fac },
+ { 0x00004b3c, 0x00001fc2 },
+ { 0x00004b40, 0x00001fd9 },
+ { 0x00004b44, 0x00001fef },
+ { 0x00004b48, 0x00002005 },
+ { 0x00004b4c, 0x0000201b },
+ { 0x00004b50, 0x00002031 },
+ { 0x00004b54, 0x00002047 },
+ { 0x00004b58, 0x0000205d },
+ { 0x00004b5c, 0x00002074 },
+ { 0x00004b60, 0x0000208a },
+ { 0x00004b64, 0x000020a0 },
+ { 0x00004b68, 0x000020b7 },
+ { 0x00004b6c, 0x000020cd },
+ { 0x00004b70, 0x000020e4 },
+ { 0x00004b74, 0x000020fa },
+ { 0x00004b78, 0x00002111 },
+ { 0x00004b7c, 0x00002127 },
+ { 0x00004b80, 0x0000213e },
+ { 0x00004b84, 0x00002154 },
+ { 0x00004b88, 0x0000216b },
+ { 0x00004b8c, 0x00002182 },
+ { 0x00004b90, 0x00002198 },
+ { 0x00004b94, 0x000021af },
+ { 0x00004b98, 0x000021c6 },
+ { 0x00004b9c, 0x000021dd },
+ { 0x00004ba0, 0x000021f3 },
+ { 0x00004ba4, 0x0000220a },
+ { 0x00004ba8, 0x00002221 },
+ { 0x00004bac, 0x00002238 },
+ { 0x00004bb0, 0x0000224f },
+ { 0x00004bb4, 0x00002266 },
+ { 0x00004bb8, 0x0000227d },
+ { 0x00004bbc, 0x00002294 },
+ { 0x00004bc0, 0x000022ab },
+ { 0x00004bc4, 0x000022c2 },
+ { 0x00004bc8, 0x000022da },
+ { 0x00004bcc, 0x000022f1 },
+ { 0x00004bd0, 0x00002308 },
+ { 0x00004bd4, 0x0000231f },
+ { 0x00004bd8, 0x00002337 },
+ { 0x00004bdc, 0x0000234e },
+ { 0x00004be0, 0x00002365 },
+ { 0x00004be4, 0x0000237d },
+ { 0x00004be8, 0x00002394 },
+ { 0x00004bec, 0x000023ac },
+ { 0x00004bf0, 0x000023c3 },
+ { 0x00004bf4, 0x000023db },
+ { 0x00004bf8, 0x000023f2 },
+ { 0x00004bfc, 0x0000240a },
+ { 0x00004c00, 0x00002421 },
+ { 0x00004c04, 0x00002439 },
+ { 0x00004c08, 0x00002451 },
+ { 0x00004c0c, 0x00002469 },
+ { 0x00004c10, 0x00002480 },
+ { 0x00004c14, 0x00002498 },
+ { 0x00004c18, 0x000024b0 },
+ { 0x00004c1c, 0x000024c8 },
+ { 0x00004c20, 0x000024e0 },
+ { 0x00004c24, 0x000024f8 },
+ { 0x00004c28, 0x00002510 },
+ { 0x00004c2c, 0x00002528 },
+ { 0x00004c30, 0x00002540 },
+ { 0x00004c34, 0x00002558 },
+ { 0x00004c38, 0x00002570 },
+ { 0x00004c3c, 0x00002588 },
+ { 0x00004c40, 0x000025a0 },
+ { 0x00004c44, 0x000025b8 },
+ { 0x00004c48, 0x000025d0 },
+ { 0x00004c4c, 0x000025e9 },
+ { 0x00004c50, 0x00002601 },
+ { 0x00004c54, 0x00002619 },
+ { 0x00004c58, 0x00002632 },
+ { 0x00004c5c, 0x0000264a },
+ { 0x00004c60, 0x00002663 },
+ { 0x00004c64, 0x0000267b },
+ { 0x00004c68, 0x00002693 },
+ { 0x00004c6c, 0x000026ac },
+ { 0x00004c70, 0x000026c5 },
+ { 0x00004c74, 0x000026dd },
+ { 0x00004c78, 0x000026f6 },
+ { 0x00004c7c, 0x0000270e },
+ { 0x00004c80, 0x00002727 },
+ { 0x00004c84, 0x00002740 },
+ { 0x00004c88, 0x00002759 },
+ { 0x00004c8c, 0x00002771 },
+ { 0x00004c90, 0x0000278a },
+ { 0x00004c94, 0x000027a3 },
+ { 0x00004c98, 0x000027bc },
+ { 0x00004c9c, 0x000027d5 },
+ { 0x00004ca0, 0x000027ee },
+ { 0x00004ca4, 0x00002807 },
+ { 0x00004ca8, 0x00002820 },
+ { 0x00004cac, 0x00002839 },
+ { 0x00004cb0, 0x00002852 },
+ { 0x00004cb4, 0x0000286b },
+ { 0x00004cb8, 0x00002884 },
+ { 0x00004cbc, 0x0000289e },
+ { 0x00004cc0, 0x000028b7 },
+ { 0x00004cc4, 0x000028d0 },
+ { 0x00004cc8, 0x000028e9 },
+ { 0x00004ccc, 0x00002903 },
+ { 0x00004cd0, 0x0000291c },
+ { 0x00004cd4, 0x00002936 },
+ { 0x00004cd8, 0x0000294f },
+ { 0x00004cdc, 0x00002968 },
+ { 0x00004ce0, 0x00002982 },
+ { 0x00004ce4, 0x0000299c },
+ { 0x00004ce8, 0x000029b5 },
+ { 0x00004cec, 0x000029cf },
+ { 0x00004cf0, 0x000029e8 },
+ { 0x00004cf4, 0x00002a02 },
+ { 0x00004cf8, 0x00002a1c },
+ { 0x00004cfc, 0x00002a35 },
+ { 0x00004d00, 0x00002a4f },
+ { 0x00004d04, 0x00002a69 },
+ { 0x00004d08, 0x00002a83 },
+ { 0x00004d0c, 0x00002a9d },
+ { 0x00004d10, 0x00002ab7 },
+ { 0x00004d14, 0x00002ad1 },
+ { 0x00004d18, 0x00002aeb },
+ { 0x00004d1c, 0x00002b05 },
+ { 0x00004d20, 0x00002b1f },
+ { 0x00004d24, 0x00002b39 },
+ { 0x00004d28, 0x00002b53 },
+ { 0x00004d2c, 0x00002b6d },
+ { 0x00004d30, 0x00002b87 },
+ { 0x00004d34, 0x00002ba1 },
+ { 0x00004d38, 0x00002bbc },
+ { 0x00004d3c, 0x00002bd6 },
+ { 0x00004d40, 0x00002bf0 },
+ { 0x00004d44, 0x00002c0b },
+ { 0x00004d48, 0x00002c25 },
+ { 0x00004d4c, 0x00002c3f },
+ { 0x00004d50, 0x00002c5a },
+ { 0x00004d54, 0x00002c74 },
+ { 0x00004d58, 0x00002c8f },
+ { 0x00004d5c, 0x00002ca9 },
+ { 0x00004d60, 0x00002cc4 },
+ { 0x00004d64, 0x00002cdf },
+ { 0x00004d68, 0x00002cf9 },
+ { 0x00004d6c, 0x00002d14 },
+ { 0x00004d70, 0x00002d2f },
+ { 0x00004d74, 0x00002d49 },
+ { 0x00004d78, 0x00002d64 },
+ { 0x00004d7c, 0x00002d7f },
+ { 0x00004d80, 0x00002d9a },
+ { 0x00004d84, 0x00002db5 },
+ { 0x00004d88, 0x00002dd0 },
+ { 0x00004d8c, 0x00002deb },
+ { 0x00004d90, 0x00002e06 },
+ { 0x00004d94, 0x00002e21 },
+ { 0x00004d98, 0x00002e3c },
+ { 0x00004d9c, 0x00002e57 },
+ { 0x00004da0, 0x00002e72 },
+ { 0x00004da4, 0x00002e8d },
+ { 0x00004da8, 0x00002ea8 },
+ { 0x00004dac, 0x00002ec4 },
+ { 0x00004db0, 0x00002edf },
+ { 0x00004db4, 0x00002efa },
+ { 0x00004db8, 0x00002f16 },
+ { 0x00004dbc, 0x00002f31 },
+ { 0x00004dc0, 0x00002f4c },
+ { 0x00004dc4, 0x00002f68 },
+ { 0x00004dc8, 0x00002f83 },
+ { 0x00004dcc, 0x00002f9f },
+ { 0x00004dd0, 0x00002fba },
+ { 0x00004dd4, 0x00002fd6 },
+ { 0x00004dd8, 0x00002ff1 },
+ { 0x00004ddc, 0x0000300d },
+ { 0x00004de0, 0x00003029 },
+ { 0x00004de4, 0x00003044 },
+ { 0x00004de8, 0x00003060 },
+ { 0x00004dec, 0x0000307c },
+ { 0x00004df0, 0x00003098 },
+ { 0x00004df4, 0x000030b4 },
+ { 0x00004df8, 0x000030d0 },
+ { 0x00004dfc, 0x000030eb },
+ { 0x00004e00, 0x00003107 },
+ { 0x00004e04, 0x00003123 },
+ { 0x00004e08, 0x0000313f },
+ { 0x00004e0c, 0x0000315b },
+ { 0x00004e10, 0x00003178 },
+ { 0x00004e14, 0x00003194 },
+ { 0x00004e18, 0x000031b0 },
+ { 0x00004e1c, 0x000031cc },
+ { 0x00004e20, 0x000031e8 },
+ { 0x00004e24, 0x00003205 },
+ { 0x00004e28, 0x00003221 },
+ { 0x00004e2c, 0x0000323d },
+ { 0x00004e30, 0x0000325a },
+ { 0x00004e34, 0x00003276 },
+ { 0x00004e38, 0x00003292 },
+ { 0x00004e3c, 0x000032af },
+ { 0x00004e40, 0x000032cb },
+ { 0x00004e44, 0x000032e8 },
+ { 0x00004e48, 0x00003304 },
+ { 0x00004e4c, 0x00003321 },
+ { 0x00004e50, 0x0000333e },
+ { 0x00004e54, 0x0000335a },
+ { 0x00004e58, 0x00003377 },
+ { 0x00004e5c, 0x00003394 },
+ { 0x00004e60, 0x000033b1 },
+ { 0x00004e64, 0x000033cd },
+ { 0x00004e68, 0x000033ea },
+ { 0x00004e6c, 0x00003407 },
+ { 0x00004e70, 0x00003424 },
+ { 0x00004e74, 0x00003441 },
+ { 0x00004e78, 0x0000345e },
+ { 0x00004e7c, 0x0000347b },
+ { 0x00004e80, 0x00003498 },
+ { 0x00004e84, 0x000034b5 },
+ { 0x00004e88, 0x000034d2 },
+ { 0x00004e8c, 0x000034ef },
+ { 0x00004e90, 0x0000350d },
+ { 0x00004e94, 0x0000352a },
+ { 0x00004e98, 0x00003547 },
+ { 0x00004e9c, 0x00003564 },
+ { 0x00004ea0, 0x00003582 },
+ { 0x00004ea4, 0x0000359f },
+ { 0x00004ea8, 0x000035bc },
+ { 0x00004eac, 0x000035da },
+ { 0x00004eb0, 0x000035f7 },
+ { 0x00004eb4, 0x00003615 },
+ { 0x00004eb8, 0x00003632 },
+ { 0x00004ebc, 0x00003650 },
+ { 0x00004ec0, 0x0000366e },
+ { 0x00004ec4, 0x0000368b },
+ { 0x00004ec8, 0x000036a9 },
+ { 0x00004ecc, 0x000036c7 },
+ { 0x00004ed0, 0x000036e4 },
+ { 0x00004ed4, 0x00003702 },
+ { 0x00004ed8, 0x00003720 },
+ { 0x00004edc, 0x0000373e },
+ { 0x00004ee0, 0x0000375c },
+ { 0x00004ee4, 0x0000377a },
+ { 0x00004ee8, 0x00003798 },
+ { 0x00004eec, 0x000037b6 },
+ { 0x00004ef0, 0x000037d4 },
+ { 0x00004ef4, 0x000037f2 },
+ { 0x00004ef8, 0x00003810 },
+ { 0x00004efc, 0x0000382e },
+ { 0x00004f00, 0x0000384c },
+ { 0x00004f04, 0x0000386a },
+ { 0x00004f08, 0x00003888 },
+ { 0x00004f0c, 0x000038a7 },
+ { 0x00004f10, 0x000038c5 },
+ { 0x00004f14, 0x000038e3 },
+ { 0x00004f18, 0x00003902 },
+ { 0x00004f1c, 0x00003920 },
+ { 0x00004f20, 0x0000393f },
+ { 0x00004f24, 0x0000395d },
+ { 0x00004f28, 0x0000397c },
+ { 0x00004f2c, 0x0000399a },
+ { 0x00004f30, 0x000039b9 },
+ { 0x00004f34, 0x000039d7 },
+ { 0x00004f38, 0x000039f6 },
+ { 0x00004f3c, 0x00003a15 },
+ { 0x00004f40, 0x00003a33 },
+ { 0x00004f44, 0x00003a52 },
+ { 0x00004f48, 0x00003a71 },
+ { 0x00004f4c, 0x00003a90 },
+ { 0x00004f50, 0x00003aaf },
+ { 0x00004f54, 0x00003acd },
+ { 0x00004f58, 0x00003aec },
+ { 0x00004f5c, 0x00003b0b },
+ { 0x00004f60, 0x00003b2a },
+ { 0x00004f64, 0x00003b49 },
+ { 0x00004f68, 0x00003b68 },
+ { 0x00004f6c, 0x00003b87 },
+ { 0x00004f70, 0x00003ba7 },
+ { 0x00004f74, 0x00003bc6 },
+ { 0x00004f78, 0x00003be5 },
+ { 0x00004f7c, 0x00003c04 },
+ { 0x00004f80, 0x00003c24 },
+ { 0x00004f84, 0x00003c43 },
+ { 0x00004f88, 0x00003c62 },
+ { 0x00004f8c, 0x00003c82 },
+ { 0x00004f90, 0x00003ca1 },
+ { 0x00004f94, 0x00003cc0 },
+ { 0x00004f98, 0x00003ce0 },
+ { 0x00004f9c, 0x00003cff },
+ { 0x00004fa0, 0x00003d1f },
+ { 0x00004fa4, 0x00003d3f },
+ { 0x00004fa8, 0x00003d5e },
+ { 0x00004fac, 0x00003d7e },
+ { 0x00004fb0, 0x00003d9e },
+ { 0x00004fb4, 0x00003dbd },
+ { 0x00004fb8, 0x00003ddd },
+ { 0x00004fbc, 0x00003dfd },
+ { 0x00004fc0, 0x00003e1d },
+ { 0x00004fc4, 0x00003e3d },
+ { 0x00004fc8, 0x00003e5d },
+ { 0x00004fcc, 0x00003e7c },
+ { 0x00004fd0, 0x00003e9c },
+ { 0x00004fd4, 0x00003ebc },
+ { 0x00004fd8, 0x00003edc },
+ { 0x00004fdc, 0x00003efd },
+ { 0x00004fe0, 0x00003f1d },
+ { 0x00004fe4, 0x00003f3d },
+ { 0x00004fe8, 0x00003f5d },
+ { 0x00004fec, 0x00003f7d },
+ { 0x00004ff0, 0x00003f9e },
+ { 0x00004ff4, 0x00003fbe },
+ { 0x00004ff8, 0x00003fde },
+ { 0x00004ffc, 0x00003fff },
+};
+
+struct data_unit hdr10_pipe2_lut_a1[] = {
+ { 0x00005000, 0x00000000 },
+ { 0x00005004, 0x00000003 },
+ { 0x00005008, 0x00000007 },
+ { 0x0000500c, 0x0000000a },
+ { 0x00005010, 0x0000000e },
+ { 0x00005014, 0x00000011 },
+ { 0x00005018, 0x00000015 },
+ { 0x0000501c, 0x00000018 },
+ { 0x00005020, 0x0000001c },
+ { 0x00005024, 0x00000020 },
+ { 0x00005028, 0x00000023 },
+ { 0x0000502c, 0x00000027 },
+ { 0x00005030, 0x0000002a },
+ { 0x00005034, 0x0000002e },
+ { 0x00005038, 0x00000031 },
+ { 0x0000503c, 0x00000035 },
+ { 0x00005040, 0x00000038 },
+ { 0x00005044, 0x0000003c },
+ { 0x00005048, 0x00000040 },
+ { 0x0000504c, 0x00000043 },
+ { 0x00005050, 0x00000047 },
+ { 0x00005054, 0x0000004a },
+ { 0x00005058, 0x0000004e },
+ { 0x0000505c, 0x00000051 },
+ { 0x00005060, 0x00000055 },
+ { 0x00005064, 0x00000058 },
+ { 0x00005068, 0x0000005c },
+ { 0x0000506c, 0x00000060 },
+ { 0x00005070, 0x00000063 },
+ { 0x00005074, 0x00000067 },
+ { 0x00005078, 0x0000006a },
+ { 0x0000507c, 0x0000006e },
+ { 0x00005080, 0x00000071 },
+ { 0x00005084, 0x00000075 },
+ { 0x00005088, 0x00000078 },
+ { 0x0000508c, 0x0000007c },
+ { 0x00005090, 0x00000080 },
+ { 0x00005094, 0x00000083 },
+ { 0x00005098, 0x00000087 },
+ { 0x0000509c, 0x0000008a },
+ { 0x000050a0, 0x0000008e },
+ { 0x000050a4, 0x00000091 },
+ { 0x000050a8, 0x00000095 },
+ { 0x000050ac, 0x00000099 },
+ { 0x000050b0, 0x0000009c },
+ { 0x000050b4, 0x000000a0 },
+ { 0x000050b8, 0x000000a3 },
+ { 0x000050bc, 0x000000a7 },
+ { 0x000050c0, 0x000000aa },
+ { 0x000050c4, 0x000000ae },
+ { 0x000050c8, 0x000000b1 },
+ { 0x000050cc, 0x000000b5 },
+ { 0x000050d0, 0x000000b9 },
+ { 0x000050d4, 0x000000bc },
+ { 0x000050d8, 0x000000c0 },
+ { 0x000050dc, 0x000000c3 },
+ { 0x000050e0, 0x000000c7 },
+ { 0x000050e4, 0x000000ca },
+ { 0x000050e8, 0x000000ce },
+ { 0x000050ec, 0x000000d1 },
+ { 0x000050f0, 0x000000d5 },
+ { 0x000050f4, 0x000000d9 },
+ { 0x000050f8, 0x000000dc },
+ { 0x000050fc, 0x000000e0 },
+ { 0x00005100, 0x000000e3 },
+ { 0x00005104, 0x000000e7 },
+ { 0x00005108, 0x000000ea },
+ { 0x0000510c, 0x000000ee },
+ { 0x00005110, 0x000000f1 },
+ { 0x00005114, 0x000000f5 },
+ { 0x00005118, 0x000000f9 },
+ { 0x0000511c, 0x000000fc },
+ { 0x00005120, 0x00000100 },
+ { 0x00005124, 0x00000103 },
+ { 0x00005128, 0x00000107 },
+ { 0x0000512c, 0x0000010a },
+ { 0x00005130, 0x0000010e },
+ { 0x00005134, 0x00000112 },
+ { 0x00005138, 0x00000115 },
+ { 0x0000513c, 0x00000119 },
+ { 0x00005140, 0x0000011c },
+ { 0x00005144, 0x00000120 },
+ { 0x00005148, 0x00000123 },
+ { 0x0000514c, 0x00000126 },
+ { 0x00005150, 0x0000012a },
+ { 0x00005154, 0x0000012d },
+ { 0x00005158, 0x00000131 },
+ { 0x0000515c, 0x00000134 },
+ { 0x00005160, 0x00000138 },
+ { 0x00005164, 0x0000013c },
+ { 0x00005168, 0x0000013f },
+ { 0x0000516c, 0x00000143 },
+ { 0x00005170, 0x00000147 },
+ { 0x00005174, 0x0000014b },
+ { 0x00005178, 0x0000014e },
+ { 0x0000517c, 0x00000152 },
+ { 0x00005180, 0x00000156 },
+ { 0x00005184, 0x0000015a },
+ { 0x00005188, 0x0000015e },
+ { 0x0000518c, 0x00000162 },
+ { 0x00005190, 0x00000166 },
+ { 0x00005194, 0x0000016a },
+ { 0x00005198, 0x0000016e },
+ { 0x0000519c, 0x00000172 },
+ { 0x000051a0, 0x00000176 },
+ { 0x000051a4, 0x0000017a },
+ { 0x000051a8, 0x0000017e },
+ { 0x000051ac, 0x00000182 },
+ { 0x000051b0, 0x00000186 },
+ { 0x000051b4, 0x0000018a },
+ { 0x000051b8, 0x0000018f },
+ { 0x000051bc, 0x00000193 },
+ { 0x000051c0, 0x00000197 },
+ { 0x000051c4, 0x0000019b },
+ { 0x000051c8, 0x000001a0 },
+ { 0x000051cc, 0x000001a4 },
+ { 0x000051d0, 0x000001a8 },
+ { 0x000051d4, 0x000001ad },
+ { 0x000051d8, 0x000001b1 },
+ { 0x000051dc, 0x000001b5 },
+ { 0x000051e0, 0x000001ba },
+ { 0x000051e4, 0x000001be },
+ { 0x000051e8, 0x000001c3 },
+ { 0x000051ec, 0x000001c7 },
+ { 0x000051f0, 0x000001cc },
+ { 0x000051f4, 0x000001d0 },
+ { 0x000051f8, 0x000001d5 },
+ { 0x000051fc, 0x000001d9 },
+ { 0x00005200, 0x000001de },
+ { 0x00005204, 0x000001e3 },
+ { 0x00005208, 0x000001e7 },
+ { 0x0000520c, 0x000001ec },
+ { 0x00005210, 0x000001f1 },
+ { 0x00005214, 0x000001f6 },
+ { 0x00005218, 0x000001fa },
+ { 0x0000521c, 0x000001ff },
+ { 0x00005220, 0x00000204 },
+ { 0x00005224, 0x00000209 },
+ { 0x00005228, 0x0000020e },
+ { 0x0000522c, 0x00000213 },
+ { 0x00005230, 0x00000217 },
+ { 0x00005234, 0x0000021c },
+ { 0x00005238, 0x00000221 },
+ { 0x0000523c, 0x00000226 },
+ { 0x00005240, 0x0000022b },
+ { 0x00005244, 0x00000230 },
+ { 0x00005248, 0x00000236 },
+ { 0x0000524c, 0x0000023b },
+ { 0x00005250, 0x00000240 },
+ { 0x00005254, 0x00000245 },
+ { 0x00005258, 0x0000024a },
+ { 0x0000525c, 0x0000024f },
+ { 0x00005260, 0x00000255 },
+ { 0x00005264, 0x0000025a },
+ { 0x00005268, 0x0000025f },
+ { 0x0000526c, 0x00000264 },
+ { 0x00005270, 0x0000026a },
+ { 0x00005274, 0x0000026f },
+ { 0x00005278, 0x00000274 },
+ { 0x0000527c, 0x0000027a },
+ { 0x00005280, 0x0000027f },
+ { 0x00005284, 0x00000285 },
+ { 0x00005288, 0x0000028a },
+ { 0x0000528c, 0x00000290 },
+ { 0x00005290, 0x00000295 },
+ { 0x00005294, 0x0000029b },
+ { 0x00005298, 0x000002a0 },
+ { 0x0000529c, 0x000002a6 },
+ { 0x000052a0, 0x000002ac },
+ { 0x000052a4, 0x000002b1 },
+ { 0x000052a8, 0x000002b7 },
+ { 0x000052ac, 0x000002bd },
+ { 0x000052b0, 0x000002c2 },
+ { 0x000052b4, 0x000002c8 },
+ { 0x000052b8, 0x000002ce },
+ { 0x000052bc, 0x000002d4 },
+ { 0x000052c0, 0x000002da },
+ { 0x000052c4, 0x000002df },
+ { 0x000052c8, 0x000002e5 },
+ { 0x000052cc, 0x000002eb },
+ { 0x000052d0, 0x000002f1 },
+ { 0x000052d4, 0x000002f7 },
+ { 0x000052d8, 0x000002fd },
+ { 0x000052dc, 0x00000303 },
+ { 0x000052e0, 0x00000309 },
+ { 0x000052e4, 0x0000030f },
+ { 0x000052e8, 0x00000315 },
+ { 0x000052ec, 0x0000031c },
+ { 0x000052f0, 0x00000322 },
+ { 0x000052f4, 0x00000328 },
+ { 0x000052f8, 0x0000032e },
+ { 0x000052fc, 0x00000334 },
+ { 0x00005300, 0x0000033b },
+ { 0x00005304, 0x00000341 },
+ { 0x00005308, 0x00000347 },
+ { 0x0000530c, 0x0000034d },
+ { 0x00005310, 0x00000354 },
+ { 0x00005314, 0x0000035a },
+ { 0x00005318, 0x00000361 },
+ { 0x0000531c, 0x00000367 },
+ { 0x00005320, 0x0000036d },
+ { 0x00005324, 0x00000374 },
+ { 0x00005328, 0x0000037a },
+ { 0x0000532c, 0x00000381 },
+ { 0x00005330, 0x00000388 },
+ { 0x00005334, 0x0000038e },
+ { 0x00005338, 0x00000395 },
+ { 0x0000533c, 0x0000039b },
+ { 0x00005340, 0x000003a2 },
+ { 0x00005344, 0x000003a9 },
+ { 0x00005348, 0x000003b0 },
+ { 0x0000534c, 0x000003b6 },
+ { 0x00005350, 0x000003bd },
+ { 0x00005354, 0x000003c4 },
+ { 0x00005358, 0x000003cb },
+ { 0x0000535c, 0x000003d2 },
+ { 0x00005360, 0x000003d8 },
+ { 0x00005364, 0x000003df },
+ { 0x00005368, 0x000003e6 },
+ { 0x0000536c, 0x000003ed },
+ { 0x00005370, 0x000003f4 },
+ { 0x00005374, 0x000003fb },
+ { 0x00005378, 0x00000402 },
+ { 0x0000537c, 0x00000409 },
+ { 0x00005380, 0x00000411 },
+ { 0x00005384, 0x00000418 },
+ { 0x00005388, 0x0000041f },
+ { 0x0000538c, 0x00000426 },
+ { 0x00005390, 0x0000042d },
+ { 0x00005394, 0x00000434 },
+ { 0x00005398, 0x0000043c },
+ { 0x0000539c, 0x00000443 },
+ { 0x000053a0, 0x0000044a },
+ { 0x000053a4, 0x00000452 },
+ { 0x000053a8, 0x00000459 },
+ { 0x000053ac, 0x00000460 },
+ { 0x000053b0, 0x00000468 },
+ { 0x000053b4, 0x0000046f },
+ { 0x000053b8, 0x00000477 },
+ { 0x000053bc, 0x0000047e },
+ { 0x000053c0, 0x00000486 },
+ { 0x000053c4, 0x0000048d },
+ { 0x000053c8, 0x00000495 },
+ { 0x000053cc, 0x0000049c },
+ { 0x000053d0, 0x000004a4 },
+ { 0x000053d4, 0x000004ac },
+ { 0x000053d8, 0x000004b3 },
+ { 0x000053dc, 0x000004bb },
+ { 0x000053e0, 0x000004c3 },
+ { 0x000053e4, 0x000004cb },
+ { 0x000053e8, 0x000004d3 },
+ { 0x000053ec, 0x000004da },
+ { 0x000053f0, 0x000004e2 },
+ { 0x000053f4, 0x000004ea },
+ { 0x000053f8, 0x000004f2 },
+ { 0x000053fc, 0x000004fa },
+ { 0x00005400, 0x00000502 },
+ { 0x00005404, 0x0000050a },
+ { 0x00005408, 0x00000512 },
+ { 0x0000540c, 0x0000051a },
+ { 0x00005410, 0x00000522 },
+ { 0x00005414, 0x0000052a },
+ { 0x00005418, 0x00000532 },
+ { 0x0000541c, 0x0000053a },
+ { 0x00005420, 0x00000543 },
+ { 0x00005424, 0x0000054b },
+ { 0x00005428, 0x00000553 },
+ { 0x0000542c, 0x0000055b },
+ { 0x00005430, 0x00000564 },
+ { 0x00005434, 0x0000056c },
+ { 0x00005438, 0x00000574 },
+ { 0x0000543c, 0x0000057d },
+ { 0x00005440, 0x00000585 },
+ { 0x00005444, 0x0000058d },
+ { 0x00005448, 0x00000596 },
+ { 0x0000544c, 0x0000059e },
+ { 0x00005450, 0x000005a7 },
+ { 0x00005454, 0x000005af },
+ { 0x00005458, 0x000005b8 },
+ { 0x0000545c, 0x000005c1 },
+ { 0x00005460, 0x000005c9 },
+ { 0x00005464, 0x000005d2 },
+ { 0x00005468, 0x000005db },
+ { 0x0000546c, 0x000005e3 },
+ { 0x00005470, 0x000005ec },
+ { 0x00005474, 0x000005f5 },
+ { 0x00005478, 0x000005fe },
+ { 0x0000547c, 0x00000606 },
+ { 0x00005480, 0x0000060f },
+ { 0x00005484, 0x00000618 },
+ { 0x00005488, 0x00000621 },
+ { 0x0000548c, 0x0000062a },
+ { 0x00005490, 0x00000633 },
+ { 0x00005494, 0x0000063c },
+ { 0x00005498, 0x00000645 },
+ { 0x0000549c, 0x0000064e },
+ { 0x000054a0, 0x00000657 },
+ { 0x000054a4, 0x00000660 },
+ { 0x000054a8, 0x00000669 },
+ { 0x000054ac, 0x00000672 },
+ { 0x000054b0, 0x0000067b },
+ { 0x000054b4, 0x00000685 },
+ { 0x000054b8, 0x0000068e },
+ { 0x000054bc, 0x00000697 },
+ { 0x000054c0, 0x000006a0 },
+ { 0x000054c4, 0x000006aa },
+ { 0x000054c8, 0x000006b3 },
+ { 0x000054cc, 0x000006bd },
+ { 0x000054d0, 0x000006c6 },
+ { 0x000054d4, 0x000006cf },
+ { 0x000054d8, 0x000006d9 },
+ { 0x000054dc, 0x000006e2 },
+ { 0x000054e0, 0x000006ec },
+ { 0x000054e4, 0x000006f5 },
+ { 0x000054e8, 0x000006ff },
+ { 0x000054ec, 0x00000709 },
+ { 0x000054f0, 0x00000712 },
+ { 0x000054f4, 0x0000071c },
+ { 0x000054f8, 0x00000726 },
+ { 0x000054fc, 0x0000072f },
+ { 0x00005500, 0x00000739 },
+ { 0x00005504, 0x00000743 },
+ { 0x00005508, 0x0000074d },
+ { 0x0000550c, 0x00000756 },
+ { 0x00005510, 0x00000760 },
+ { 0x00005514, 0x0000076a },
+ { 0x00005518, 0x00000774 },
+ { 0x0000551c, 0x0000077e },
+ { 0x00005520, 0x00000788 },
+ { 0x00005524, 0x00000792 },
+ { 0x00005528, 0x0000079c },
+ { 0x0000552c, 0x000007a6 },
+ { 0x00005530, 0x000007b0 },
+ { 0x00005534, 0x000007ba },
+ { 0x00005538, 0x000007c4 },
+ { 0x0000553c, 0x000007cf },
+ { 0x00005540, 0x000007d9 },
+ { 0x00005544, 0x000007e3 },
+ { 0x00005548, 0x000007ed },
+ { 0x0000554c, 0x000007f7 },
+ { 0x00005550, 0x00000802 },
+ { 0x00005554, 0x0000080c },
+ { 0x00005558, 0x00000816 },
+ { 0x0000555c, 0x00000821 },
+ { 0x00005560, 0x0000082b },
+ { 0x00005564, 0x00000836 },
+ { 0x00005568, 0x00000840 },
+ { 0x0000556c, 0x0000084b },
+ { 0x00005570, 0x00000855 },
+ { 0x00005574, 0x00000860 },
+ { 0x00005578, 0x0000086a },
+ { 0x0000557c, 0x00000875 },
+ { 0x00005580, 0x00000880 },
+ { 0x00005584, 0x0000088a },
+ { 0x00005588, 0x00000895 },
+ { 0x0000558c, 0x000008a0 },
+ { 0x00005590, 0x000008ab },
+ { 0x00005594, 0x000008b5 },
+ { 0x00005598, 0x000008c0 },
+ { 0x0000559c, 0x000008cb },
+ { 0x000055a0, 0x000008d6 },
+ { 0x000055a4, 0x000008e1 },
+ { 0x000055a8, 0x000008ec },
+ { 0x000055ac, 0x000008f7 },
+ { 0x000055b0, 0x00000902 },
+ { 0x000055b4, 0x0000090d },
+ { 0x000055b8, 0x00000918 },
+ { 0x000055bc, 0x00000923 },
+ { 0x000055c0, 0x0000092e },
+ { 0x000055c4, 0x00000939 },
+ { 0x000055c8, 0x00000944 },
+ { 0x000055cc, 0x00000950 },
+ { 0x000055d0, 0x0000095b },
+ { 0x000055d4, 0x00000966 },
+ { 0x000055d8, 0x00000971 },
+ { 0x000055dc, 0x0000097d },
+ { 0x000055e0, 0x00000988 },
+ { 0x000055e4, 0x00000993 },
+ { 0x000055e8, 0x0000099f },
+ { 0x000055ec, 0x000009aa },
+ { 0x000055f0, 0x000009b6 },
+ { 0x000055f4, 0x000009c1 },
+ { 0x000055f8, 0x000009cd },
+ { 0x000055fc, 0x000009d8 },
+ { 0x00005600, 0x000009e4 },
+ { 0x00005604, 0x000009f0 },
+ { 0x00005608, 0x000009fb },
+ { 0x0000560c, 0x00000a07 },
+ { 0x00005610, 0x00000a13 },
+ { 0x00005614, 0x00000a1e },
+ { 0x00005618, 0x00000a2a },
+ { 0x0000561c, 0x00000a36 },
+ { 0x00005620, 0x00000a42 },
+ { 0x00005624, 0x00000a4e },
+ { 0x00005628, 0x00000a59 },
+ { 0x0000562c, 0x00000a65 },
+ { 0x00005630, 0x00000a71 },
+ { 0x00005634, 0x00000a7d },
+ { 0x00005638, 0x00000a89 },
+ { 0x0000563c, 0x00000a95 },
+ { 0x00005640, 0x00000aa1 },
+ { 0x00005644, 0x00000aad },
+ { 0x00005648, 0x00000ab9 },
+ { 0x0000564c, 0x00000ac6 },
+ { 0x00005650, 0x00000ad2 },
+ { 0x00005654, 0x00000ade },
+ { 0x00005658, 0x00000aea },
+ { 0x0000565c, 0x00000af6 },
+ { 0x00005660, 0x00000b03 },
+ { 0x00005664, 0x00000b0f },
+ { 0x00005668, 0x00000b1b },
+ { 0x0000566c, 0x00000b28 },
+ { 0x00005670, 0x00000b34 },
+ { 0x00005674, 0x00000b41 },
+ { 0x00005678, 0x00000b4d },
+ { 0x0000567c, 0x00000b5a },
+ { 0x00005680, 0x00000b66 },
+ { 0x00005684, 0x00000b73 },
+ { 0x00005688, 0x00000b7f },
+ { 0x0000568c, 0x00000b8c },
+ { 0x00005690, 0x00000b98 },
+ { 0x00005694, 0x00000ba5 },
+ { 0x00005698, 0x00000bb2 },
+ { 0x0000569c, 0x00000bbf },
+ { 0x000056a0, 0x00000bcb },
+ { 0x000056a4, 0x00000bd8 },
+ { 0x000056a8, 0x00000be5 },
+ { 0x000056ac, 0x00000bf2 },
+ { 0x000056b0, 0x00000bff },
+ { 0x000056b4, 0x00000c0c },
+ { 0x000056b8, 0x00000c19 },
+ { 0x000056bc, 0x00000c25 },
+ { 0x000056c0, 0x00000c32 },
+ { 0x000056c4, 0x00000c40 },
+ { 0x000056c8, 0x00000c4d },
+ { 0x000056cc, 0x00000c5a },
+ { 0x000056d0, 0x00000c67 },
+ { 0x000056d4, 0x00000c74 },
+ { 0x000056d8, 0x00000c81 },
+ { 0x000056dc, 0x00000c8e },
+ { 0x000056e0, 0x00000c9c },
+ { 0x000056e4, 0x00000ca9 },
+ { 0x000056e8, 0x00000cb6 },
+ { 0x000056ec, 0x00000cc3 },
+ { 0x000056f0, 0x00000cd1 },
+ { 0x000056f4, 0x00000cde },
+ { 0x000056f8, 0x00000cec },
+ { 0x000056fc, 0x00000cf9 },
+ { 0x00005700, 0x00000d07 },
+ { 0x00005704, 0x00000d14 },
+ { 0x00005708, 0x00000d22 },
+ { 0x0000570c, 0x00000d2f },
+ { 0x00005710, 0x00000d3d },
+ { 0x00005714, 0x00000d4a },
+ { 0x00005718, 0x00000d58 },
+ { 0x0000571c, 0x00000d66 },
+ { 0x00005720, 0x00000d73 },
+ { 0x00005724, 0x00000d81 },
+ { 0x00005728, 0x00000d8f },
+ { 0x0000572c, 0x00000d9d },
+ { 0x00005730, 0x00000dab },
+ { 0x00005734, 0x00000db8 },
+ { 0x00005738, 0x00000dc6 },
+ { 0x0000573c, 0x00000dd4 },
+ { 0x00005740, 0x00000de2 },
+ { 0x00005744, 0x00000df0 },
+ { 0x00005748, 0x00000dfe },
+ { 0x0000574c, 0x00000e0c },
+ { 0x00005750, 0x00000e1a },
+ { 0x00005754, 0x00000e29 },
+ { 0x00005758, 0x00000e37 },
+ { 0x0000575c, 0x00000e45 },
+ { 0x00005760, 0x00000e53 },
+ { 0x00005764, 0x00000e61 },
+ { 0x00005768, 0x00000e70 },
+ { 0x0000576c, 0x00000e7e },
+ { 0x00005770, 0x00000e8c },
+ { 0x00005774, 0x00000e9a },
+ { 0x00005778, 0x00000ea9 },
+ { 0x0000577c, 0x00000eb7 },
+ { 0x00005780, 0x00000ec6 },
+ { 0x00005784, 0x00000ed4 },
+ { 0x00005788, 0x00000ee3 },
+ { 0x0000578c, 0x00000ef1 },
+ { 0x00005790, 0x00000f00 },
+ { 0x00005794, 0x00000f0e },
+ { 0x00005798, 0x00000f1d },
+ { 0x0000579c, 0x00000f2c },
+ { 0x000057a0, 0x00000f3a },
+ { 0x000057a4, 0x00000f49 },
+ { 0x000057a8, 0x00000f58 },
+ { 0x000057ac, 0x00000f67 },
+ { 0x000057b0, 0x00000f75 },
+ { 0x000057b4, 0x00000f84 },
+ { 0x000057b8, 0x00000f93 },
+ { 0x000057bc, 0x00000fa2 },
+ { 0x000057c0, 0x00000fb1 },
+ { 0x000057c4, 0x00000fc0 },
+ { 0x000057c8, 0x00000fcf },
+ { 0x000057cc, 0x00000fde },
+ { 0x000057d0, 0x00000fed },
+ { 0x000057d4, 0x00000ffc },
+ { 0x000057d8, 0x0000100b },
+ { 0x000057dc, 0x0000101a },
+ { 0x000057e0, 0x0000102a },
+ { 0x000057e4, 0x00001039 },
+ { 0x000057e8, 0x00001048 },
+ { 0x000057ec, 0x00001057 },
+ { 0x000057f0, 0x00001067 },
+ { 0x000057f4, 0x00001076 },
+ { 0x000057f8, 0x00001085 },
+ { 0x000057fc, 0x00001095 },
+ { 0x00005800, 0x000010a4 },
+ { 0x00005804, 0x000010b4 },
+ { 0x00005808, 0x000010c3 },
+ { 0x0000580c, 0x000010d3 },
+ { 0x00005810, 0x000010e2 },
+ { 0x00005814, 0x000010f2 },
+ { 0x00005818, 0x00001101 },
+ { 0x0000581c, 0x00001111 },
+ { 0x00005820, 0x00001121 },
+ { 0x00005824, 0x00001130 },
+ { 0x00005828, 0x00001140 },
+ { 0x0000582c, 0x00001150 },
+ { 0x00005830, 0x00001160 },
+ { 0x00005834, 0x0000116f },
+ { 0x00005838, 0x0000117f },
+ { 0x0000583c, 0x0000118f },
+ { 0x00005840, 0x0000119f },
+ { 0x00005844, 0x000011af },
+ { 0x00005848, 0x000011bf },
+ { 0x0000584c, 0x000011cf },
+ { 0x00005850, 0x000011df },
+ { 0x00005854, 0x000011ef },
+ { 0x00005858, 0x000011ff },
+ { 0x0000585c, 0x0000120f },
+ { 0x00005860, 0x0000121f },
+ { 0x00005864, 0x00001230 },
+ { 0x00005868, 0x00001240 },
+ { 0x0000586c, 0x00001250 },
+ { 0x00005870, 0x00001260 },
+ { 0x00005874, 0x00001271 },
+ { 0x00005878, 0x00001281 },
+ { 0x0000587c, 0x00001291 },
+ { 0x00005880, 0x000012a2 },
+ { 0x00005884, 0x000012b2 },
+ { 0x00005888, 0x000012c3 },
+ { 0x0000588c, 0x000012d3 },
+ { 0x00005890, 0x000012e4 },
+ { 0x00005894, 0x000012f4 },
+ { 0x00005898, 0x00001305 },
+ { 0x0000589c, 0x00001316 },
+ { 0x000058a0, 0x00001326 },
+ { 0x000058a4, 0x00001337 },
+ { 0x000058a8, 0x00001348 },
+ { 0x000058ac, 0x00001359 },
+ { 0x000058b0, 0x00001369 },
+ { 0x000058b4, 0x0000137a },
+ { 0x000058b8, 0x0000138b },
+ { 0x000058bc, 0x0000139c },
+ { 0x000058c0, 0x000013ad },
+ { 0x000058c4, 0x000013be },
+ { 0x000058c8, 0x000013cf },
+ { 0x000058cc, 0x000013e0 },
+ { 0x000058d0, 0x000013f1 },
+ { 0x000058d4, 0x00001402 },
+ { 0x000058d8, 0x00001413 },
+ { 0x000058dc, 0x00001424 },
+ { 0x000058e0, 0x00001435 },
+ { 0x000058e4, 0x00001446 },
+ { 0x000058e8, 0x00001458 },
+ { 0x000058ec, 0x00001469 },
+ { 0x000058f0, 0x0000147a },
+ { 0x000058f4, 0x0000148b },
+ { 0x000058f8, 0x0000149d },
+ { 0x000058fc, 0x000014ae },
+ { 0x00005900, 0x000014c0 },
+ { 0x00005904, 0x000014d1 },
+ { 0x00005908, 0x000014e3 },
+ { 0x0000590c, 0x000014f4 },
+ { 0x00005910, 0x00001506 },
+ { 0x00005914, 0x00001517 },
+ { 0x00005918, 0x00001529 },
+ { 0x0000591c, 0x0000153a },
+ { 0x00005920, 0x0000154c },
+ { 0x00005924, 0x0000155e },
+ { 0x00005928, 0x0000156f },
+ { 0x0000592c, 0x00001581 },
+ { 0x00005930, 0x00001593 },
+ { 0x00005934, 0x000015a5 },
+ { 0x00005938, 0x000015b7 },
+ { 0x0000593c, 0x000015c9 },
+ { 0x00005940, 0x000015db },
+ { 0x00005944, 0x000015ec },
+ { 0x00005948, 0x000015fe },
+ { 0x0000594c, 0x00001610 },
+ { 0x00005950, 0x00001623 },
+ { 0x00005954, 0x00001635 },
+ { 0x00005958, 0x00001647 },
+ { 0x0000595c, 0x00001659 },
+ { 0x00005960, 0x0000166b },
+ { 0x00005964, 0x0000167d },
+ { 0x00005968, 0x0000168f },
+ { 0x0000596c, 0x000016a2 },
+ { 0x00005970, 0x000016b4 },
+ { 0x00005974, 0x000016c6 },
+ { 0x00005978, 0x000016d9 },
+ { 0x0000597c, 0x000016eb },
+ { 0x00005980, 0x000016fe },
+ { 0x00005984, 0x00001710 },
+ { 0x00005988, 0x00001722 },
+ { 0x0000598c, 0x00001735 },
+ { 0x00005990, 0x00001748 },
+ { 0x00005994, 0x0000175a },
+ { 0x00005998, 0x0000176d },
+ { 0x0000599c, 0x0000177f },
+ { 0x000059a0, 0x00001792 },
+ { 0x000059a4, 0x000017a5 },
+ { 0x000059a8, 0x000017b8 },
+ { 0x000059ac, 0x000017ca },
+ { 0x000059b0, 0x000017dd },
+ { 0x000059b4, 0x000017f0 },
+ { 0x000059b8, 0x00001803 },
+ { 0x000059bc, 0x00001816 },
+ { 0x000059c0, 0x00001829 },
+ { 0x000059c4, 0x0000183c },
+ { 0x000059c8, 0x0000184f },
+ { 0x000059cc, 0x00001862 },
+ { 0x000059d0, 0x00001875 },
+ { 0x000059d4, 0x00001888 },
+ { 0x000059d8, 0x0000189b },
+ { 0x000059dc, 0x000018ae },
+ { 0x000059e0, 0x000018c1 },
+ { 0x000059e4, 0x000018d5 },
+ { 0x000059e8, 0x000018e8 },
+ { 0x000059ec, 0x000018fb },
+ { 0x000059f0, 0x0000190e },
+ { 0x000059f4, 0x00001922 },
+ { 0x000059f8, 0x00001935 },
+ { 0x000059fc, 0x00001949 },
+ { 0x00005a00, 0x0000195c },
+ { 0x00005a04, 0x0000196f },
+ { 0x00005a08, 0x00001983 },
+ { 0x00005a0c, 0x00001996 },
+ { 0x00005a10, 0x000019aa },
+ { 0x00005a14, 0x000019be },
+ { 0x00005a18, 0x000019d1 },
+ { 0x00005a1c, 0x000019e5 },
+ { 0x00005a20, 0x000019f9 },
+ { 0x00005a24, 0x00001a0c },
+ { 0x00005a28, 0x00001a20 },
+ { 0x00005a2c, 0x00001a34 },
+ { 0x00005a30, 0x00001a48 },
+ { 0x00005a34, 0x00001a5c },
+ { 0x00005a38, 0x00001a70 },
+ { 0x00005a3c, 0x00001a84 },
+ { 0x00005a40, 0x00001a97 },
+ { 0x00005a44, 0x00001aab },
+ { 0x00005a48, 0x00001ac0 },
+ { 0x00005a4c, 0x00001ad4 },
+ { 0x00005a50, 0x00001ae8 },
+ { 0x00005a54, 0x00001afc },
+ { 0x00005a58, 0x00001b10 },
+ { 0x00005a5c, 0x00001b24 },
+ { 0x00005a60, 0x00001b38 },
+ { 0x00005a64, 0x00001b4d },
+ { 0x00005a68, 0x00001b61 },
+ { 0x00005a6c, 0x00001b75 },
+ { 0x00005a70, 0x00001b8a },
+ { 0x00005a74, 0x00001b9e },
+ { 0x00005a78, 0x00001bb2 },
+ { 0x00005a7c, 0x00001bc7 },
+ { 0x00005a80, 0x00001bdb },
+ { 0x00005a84, 0x00001bf0 },
+ { 0x00005a88, 0x00001c04 },
+ { 0x00005a8c, 0x00001c19 },
+ { 0x00005a90, 0x00001c2e },
+ { 0x00005a94, 0x00001c42 },
+ { 0x00005a98, 0x00001c57 },
+ { 0x00005a9c, 0x00001c6c },
+ { 0x00005aa0, 0x00001c80 },
+ { 0x00005aa4, 0x00001c95 },
+ { 0x00005aa8, 0x00001caa },
+ { 0x00005aac, 0x00001cbf },
+ { 0x00005ab0, 0x00001cd4 },
+ { 0x00005ab4, 0x00001ce8 },
+ { 0x00005ab8, 0x00001cfd },
+ { 0x00005abc, 0x00001d12 },
+ { 0x00005ac0, 0x00001d27 },
+ { 0x00005ac4, 0x00001d3c },
+ { 0x00005ac8, 0x00001d51 },
+ { 0x00005acc, 0x00001d67 },
+ { 0x00005ad0, 0x00001d7c },
+ { 0x00005ad4, 0x00001d91 },
+ { 0x00005ad8, 0x00001da6 },
+ { 0x00005adc, 0x00001dbb },
+ { 0x00005ae0, 0x00001dd1 },
+ { 0x00005ae4, 0x00001de6 },
+ { 0x00005ae8, 0x00001dfb },
+ { 0x00005aec, 0x00001e10 },
+ { 0x00005af0, 0x00001e26 },
+ { 0x00005af4, 0x00001e3b },
+ { 0x00005af8, 0x00001e51 },
+ { 0x00005afc, 0x00001e66 },
+ { 0x00005b00, 0x00001e7c },
+ { 0x00005b04, 0x00001e91 },
+ { 0x00005b08, 0x00001ea7 },
+ { 0x00005b0c, 0x00001ebd },
+ { 0x00005b10, 0x00001ed2 },
+ { 0x00005b14, 0x00001ee8 },
+ { 0x00005b18, 0x00001efe },
+ { 0x00005b1c, 0x00001f13 },
+ { 0x00005b20, 0x00001f29 },
+ { 0x00005b24, 0x00001f3f },
+ { 0x00005b28, 0x00001f55 },
+ { 0x00005b2c, 0x00001f6b },
+ { 0x00005b30, 0x00001f81 },
+ { 0x00005b34, 0x00001f96 },
+ { 0x00005b38, 0x00001fac },
+ { 0x00005b3c, 0x00001fc2 },
+ { 0x00005b40, 0x00001fd9 },
+ { 0x00005b44, 0x00001fef },
+ { 0x00005b48, 0x00002005 },
+ { 0x00005b4c, 0x0000201b },
+ { 0x00005b50, 0x00002031 },
+ { 0x00005b54, 0x00002047 },
+ { 0x00005b58, 0x0000205d },
+ { 0x00005b5c, 0x00002074 },
+ { 0x00005b60, 0x0000208a },
+ { 0x00005b64, 0x000020a0 },
+ { 0x00005b68, 0x000020b7 },
+ { 0x00005b6c, 0x000020cd },
+ { 0x00005b70, 0x000020e4 },
+ { 0x00005b74, 0x000020fa },
+ { 0x00005b78, 0x00002111 },
+ { 0x00005b7c, 0x00002127 },
+ { 0x00005b80, 0x0000213e },
+ { 0x00005b84, 0x00002154 },
+ { 0x00005b88, 0x0000216b },
+ { 0x00005b8c, 0x00002182 },
+ { 0x00005b90, 0x00002198 },
+ { 0x00005b94, 0x000021af },
+ { 0x00005b98, 0x000021c6 },
+ { 0x00005b9c, 0x000021dd },
+ { 0x00005ba0, 0x000021f3 },
+ { 0x00005ba4, 0x0000220a },
+ { 0x00005ba8, 0x00002221 },
+ { 0x00005bac, 0x00002238 },
+ { 0x00005bb0, 0x0000224f },
+ { 0x00005bb4, 0x00002266 },
+ { 0x00005bb8, 0x0000227d },
+ { 0x00005bbc, 0x00002294 },
+ { 0x00005bc0, 0x000022ab },
+ { 0x00005bc4, 0x000022c2 },
+ { 0x00005bc8, 0x000022da },
+ { 0x00005bcc, 0x000022f1 },
+ { 0x00005bd0, 0x00002308 },
+ { 0x00005bd4, 0x0000231f },
+ { 0x00005bd8, 0x00002337 },
+ { 0x00005bdc, 0x0000234e },
+ { 0x00005be0, 0x00002365 },
+ { 0x00005be4, 0x0000237d },
+ { 0x00005be8, 0x00002394 },
+ { 0x00005bec, 0x000023ac },
+ { 0x00005bf0, 0x000023c3 },
+ { 0x00005bf4, 0x000023db },
+ { 0x00005bf8, 0x000023f2 },
+ { 0x00005bfc, 0x0000240a },
+ { 0x00005c00, 0x00002421 },
+ { 0x00005c04, 0x00002439 },
+ { 0x00005c08, 0x00002451 },
+ { 0x00005c0c, 0x00002469 },
+ { 0x00005c10, 0x00002480 },
+ { 0x00005c14, 0x00002498 },
+ { 0x00005c18, 0x000024b0 },
+ { 0x00005c1c, 0x000024c8 },
+ { 0x00005c20, 0x000024e0 },
+ { 0x00005c24, 0x000024f8 },
+ { 0x00005c28, 0x00002510 },
+ { 0x00005c2c, 0x00002528 },
+ { 0x00005c30, 0x00002540 },
+ { 0x00005c34, 0x00002558 },
+ { 0x00005c38, 0x00002570 },
+ { 0x00005c3c, 0x00002588 },
+ { 0x00005c40, 0x000025a0 },
+ { 0x00005c44, 0x000025b8 },
+ { 0x00005c48, 0x000025d0 },
+ { 0x00005c4c, 0x000025e9 },
+ { 0x00005c50, 0x00002601 },
+ { 0x00005c54, 0x00002619 },
+ { 0x00005c58, 0x00002632 },
+ { 0x00005c5c, 0x0000264a },
+ { 0x00005c60, 0x00002663 },
+ { 0x00005c64, 0x0000267b },
+ { 0x00005c68, 0x00002693 },
+ { 0x00005c6c, 0x000026ac },
+ { 0x00005c70, 0x000026c5 },
+ { 0x00005c74, 0x000026dd },
+ { 0x00005c78, 0x000026f6 },
+ { 0x00005c7c, 0x0000270e },
+ { 0x00005c80, 0x00002727 },
+ { 0x00005c84, 0x00002740 },
+ { 0x00005c88, 0x00002759 },
+ { 0x00005c8c, 0x00002771 },
+ { 0x00005c90, 0x0000278a },
+ { 0x00005c94, 0x000027a3 },
+ { 0x00005c98, 0x000027bc },
+ { 0x00005c9c, 0x000027d5 },
+ { 0x00005ca0, 0x000027ee },
+ { 0x00005ca4, 0x00002807 },
+ { 0x00005ca8, 0x00002820 },
+ { 0x00005cac, 0x00002839 },
+ { 0x00005cb0, 0x00002852 },
+ { 0x00005cb4, 0x0000286b },
+ { 0x00005cb8, 0x00002884 },
+ { 0x00005cbc, 0x0000289e },
+ { 0x00005cc0, 0x000028b7 },
+ { 0x00005cc4, 0x000028d0 },
+ { 0x00005cc8, 0x000028e9 },
+ { 0x00005ccc, 0x00002903 },
+ { 0x00005cd0, 0x0000291c },
+ { 0x00005cd4, 0x00002936 },
+ { 0x00005cd8, 0x0000294f },
+ { 0x00005cdc, 0x00002968 },
+ { 0x00005ce0, 0x00002982 },
+ { 0x00005ce4, 0x0000299c },
+ { 0x00005ce8, 0x000029b5 },
+ { 0x00005cec, 0x000029cf },
+ { 0x00005cf0, 0x000029e8 },
+ { 0x00005cf4, 0x00002a02 },
+ { 0x00005cf8, 0x00002a1c },
+ { 0x00005cfc, 0x00002a35 },
+ { 0x00005d00, 0x00002a4f },
+ { 0x00005d04, 0x00002a69 },
+ { 0x00005d08, 0x00002a83 },
+ { 0x00005d0c, 0x00002a9d },
+ { 0x00005d10, 0x00002ab7 },
+ { 0x00005d14, 0x00002ad1 },
+ { 0x00005d18, 0x00002aeb },
+ { 0x00005d1c, 0x00002b05 },
+ { 0x00005d20, 0x00002b1f },
+ { 0x00005d24, 0x00002b39 },
+ { 0x00005d28, 0x00002b53 },
+ { 0x00005d2c, 0x00002b6d },
+ { 0x00005d30, 0x00002b87 },
+ { 0x00005d34, 0x00002ba1 },
+ { 0x00005d38, 0x00002bbc },
+ { 0x00005d3c, 0x00002bd6 },
+ { 0x00005d40, 0x00002bf0 },
+ { 0x00005d44, 0x00002c0b },
+ { 0x00005d48, 0x00002c25 },
+ { 0x00005d4c, 0x00002c3f },
+ { 0x00005d50, 0x00002c5a },
+ { 0x00005d54, 0x00002c74 },
+ { 0x00005d58, 0x00002c8f },
+ { 0x00005d5c, 0x00002ca9 },
+ { 0x00005d60, 0x00002cc4 },
+ { 0x00005d64, 0x00002cdf },
+ { 0x00005d68, 0x00002cf9 },
+ { 0x00005d6c, 0x00002d14 },
+ { 0x00005d70, 0x00002d2f },
+ { 0x00005d74, 0x00002d49 },
+ { 0x00005d78, 0x00002d64 },
+ { 0x00005d7c, 0x00002d7f },
+ { 0x00005d80, 0x00002d9a },
+ { 0x00005d84, 0x00002db5 },
+ { 0x00005d88, 0x00002dd0 },
+ { 0x00005d8c, 0x00002deb },
+ { 0x00005d90, 0x00002e06 },
+ { 0x00005d94, 0x00002e21 },
+ { 0x00005d98, 0x00002e3c },
+ { 0x00005d9c, 0x00002e57 },
+ { 0x00005da0, 0x00002e72 },
+ { 0x00005da4, 0x00002e8d },
+ { 0x00005da8, 0x00002ea8 },
+ { 0x00005dac, 0x00002ec4 },
+ { 0x00005db0, 0x00002edf },
+ { 0x00005db4, 0x00002efa },
+ { 0x00005db8, 0x00002f16 },
+ { 0x00005dbc, 0x00002f31 },
+ { 0x00005dc0, 0x00002f4c },
+ { 0x00005dc4, 0x00002f68 },
+ { 0x00005dc8, 0x00002f83 },
+ { 0x00005dcc, 0x00002f9f },
+ { 0x00005dd0, 0x00002fba },
+ { 0x00005dd4, 0x00002fd6 },
+ { 0x00005dd8, 0x00002ff1 },
+ { 0x00005ddc, 0x0000300d },
+ { 0x00005de0, 0x00003029 },
+ { 0x00005de4, 0x00003044 },
+ { 0x00005de8, 0x00003060 },
+ { 0x00005dec, 0x0000307c },
+ { 0x00005df0, 0x00003098 },
+ { 0x00005df4, 0x000030b4 },
+ { 0x00005df8, 0x000030d0 },
+ { 0x00005dfc, 0x000030eb },
+ { 0x00005e00, 0x00003107 },
+ { 0x00005e04, 0x00003123 },
+ { 0x00005e08, 0x0000313f },
+ { 0x00005e0c, 0x0000315b },
+ { 0x00005e10, 0x00003178 },
+ { 0x00005e14, 0x00003194 },
+ { 0x00005e18, 0x000031b0 },
+ { 0x00005e1c, 0x000031cc },
+ { 0x00005e20, 0x000031e8 },
+ { 0x00005e24, 0x00003205 },
+ { 0x00005e28, 0x00003221 },
+ { 0x00005e2c, 0x0000323d },
+ { 0x00005e30, 0x0000325a },
+ { 0x00005e34, 0x00003276 },
+ { 0x00005e38, 0x00003292 },
+ { 0x00005e3c, 0x000032af },
+ { 0x00005e40, 0x000032cb },
+ { 0x00005e44, 0x000032e8 },
+ { 0x00005e48, 0x00003304 },
+ { 0x00005e4c, 0x00003321 },
+ { 0x00005e50, 0x0000333e },
+ { 0x00005e54, 0x0000335a },
+ { 0x00005e58, 0x00003377 },
+ { 0x00005e5c, 0x00003394 },
+ { 0x00005e60, 0x000033b1 },
+ { 0x00005e64, 0x000033cd },
+ { 0x00005e68, 0x000033ea },
+ { 0x00005e6c, 0x00003407 },
+ { 0x00005e70, 0x00003424 },
+ { 0x00005e74, 0x00003441 },
+ { 0x00005e78, 0x0000345e },
+ { 0x00005e7c, 0x0000347b },
+ { 0x00005e80, 0x00003498 },
+ { 0x00005e84, 0x000034b5 },
+ { 0x00005e88, 0x000034d2 },
+ { 0x00005e8c, 0x000034ef },
+ { 0x00005e90, 0x0000350d },
+ { 0x00005e94, 0x0000352a },
+ { 0x00005e98, 0x00003547 },
+ { 0x00005e9c, 0x00003564 },
+ { 0x00005ea0, 0x00003582 },
+ { 0x00005ea4, 0x0000359f },
+ { 0x00005ea8, 0x000035bc },
+ { 0x00005eac, 0x000035da },
+ { 0x00005eb0, 0x000035f7 },
+ { 0x00005eb4, 0x00003615 },
+ { 0x00005eb8, 0x00003632 },
+ { 0x00005ebc, 0x00003650 },
+ { 0x00005ec0, 0x0000366e },
+ { 0x00005ec4, 0x0000368b },
+ { 0x00005ec8, 0x000036a9 },
+ { 0x00005ecc, 0x000036c7 },
+ { 0x00005ed0, 0x000036e4 },
+ { 0x00005ed4, 0x00003702 },
+ { 0x00005ed8, 0x00003720 },
+ { 0x00005edc, 0x0000373e },
+ { 0x00005ee0, 0x0000375c },
+ { 0x00005ee4, 0x0000377a },
+ { 0x00005ee8, 0x00003798 },
+ { 0x00005eec, 0x000037b6 },
+ { 0x00005ef0, 0x000037d4 },
+ { 0x00005ef4, 0x000037f2 },
+ { 0x00005ef8, 0x00003810 },
+ { 0x00005efc, 0x0000382e },
+ { 0x00005f00, 0x0000384c },
+ { 0x00005f04, 0x0000386a },
+ { 0x00005f08, 0x00003888 },
+ { 0x00005f0c, 0x000038a7 },
+ { 0x00005f10, 0x000038c5 },
+ { 0x00005f14, 0x000038e3 },
+ { 0x00005f18, 0x00003902 },
+ { 0x00005f1c, 0x00003920 },
+ { 0x00005f20, 0x0000393f },
+ { 0x00005f24, 0x0000395d },
+ { 0x00005f28, 0x0000397c },
+ { 0x00005f2c, 0x0000399a },
+ { 0x00005f30, 0x000039b9 },
+ { 0x00005f34, 0x000039d7 },
+ { 0x00005f38, 0x000039f6 },
+ { 0x00005f3c, 0x00003a15 },
+ { 0x00005f40, 0x00003a33 },
+ { 0x00005f44, 0x00003a52 },
+ { 0x00005f48, 0x00003a71 },
+ { 0x00005f4c, 0x00003a90 },
+ { 0x00005f50, 0x00003aaf },
+ { 0x00005f54, 0x00003acd },
+ { 0x00005f58, 0x00003aec },
+ { 0x00005f5c, 0x00003b0b },
+ { 0x00005f60, 0x00003b2a },
+ { 0x00005f64, 0x00003b49 },
+ { 0x00005f68, 0x00003b68 },
+ { 0x00005f6c, 0x00003b87 },
+ { 0x00005f70, 0x00003ba7 },
+ { 0x00005f74, 0x00003bc6 },
+ { 0x00005f78, 0x00003be5 },
+ { 0x00005f7c, 0x00003c04 },
+ { 0x00005f80, 0x00003c24 },
+ { 0x00005f84, 0x00003c43 },
+ { 0x00005f88, 0x00003c62 },
+ { 0x00005f8c, 0x00003c82 },
+ { 0x00005f90, 0x00003ca1 },
+ { 0x00005f94, 0x00003cc0 },
+ { 0x00005f98, 0x00003ce0 },
+ { 0x00005f9c, 0x00003cff },
+ { 0x00005fa0, 0x00003d1f },
+ { 0x00005fa4, 0x00003d3f },
+ { 0x00005fa8, 0x00003d5e },
+ { 0x00005fac, 0x00003d7e },
+ { 0x00005fb0, 0x00003d9e },
+ { 0x00005fb4, 0x00003dbd },
+ { 0x00005fb8, 0x00003ddd },
+ { 0x00005fbc, 0x00003dfd },
+ { 0x00005fc0, 0x00003e1d },
+ { 0x00005fc4, 0x00003e3d },
+ { 0x00005fc8, 0x00003e5d },
+ { 0x00005fcc, 0x00003e7c },
+ { 0x00005fd0, 0x00003e9c },
+ { 0x00005fd4, 0x00003ebc },
+ { 0x00005fd8, 0x00003edc },
+ { 0x00005fdc, 0x00003efd },
+ { 0x00005fe0, 0x00003f1d },
+ { 0x00005fe4, 0x00003f3d },
+ { 0x00005fe8, 0x00003f5d },
+ { 0x00005fec, 0x00003f7d },
+ { 0x00005ff0, 0x00003f9e },
+ { 0x00005ff4, 0x00003fbe },
+ { 0x00005ff8, 0x00003fde },
+ { 0x00005ffc, 0x00003fff },
+};
+
+struct data_unit hdr10_pipe2_lut_a2[] = {
+ { 0x00006000, 0x00000000 },
+ { 0x00006004, 0x00000003 },
+ { 0x00006008, 0x00000007 },
+ { 0x0000600c, 0x0000000a },
+ { 0x00006010, 0x0000000e },
+ { 0x00006014, 0x00000011 },
+ { 0x00006018, 0x00000015 },
+ { 0x0000601c, 0x00000018 },
+ { 0x00006020, 0x0000001c },
+ { 0x00006024, 0x00000020 },
+ { 0x00006028, 0x00000023 },
+ { 0x0000602c, 0x00000027 },
+ { 0x00006030, 0x0000002a },
+ { 0x00006034, 0x0000002e },
+ { 0x00006038, 0x00000031 },
+ { 0x0000603c, 0x00000035 },
+ { 0x00006040, 0x00000038 },
+ { 0x00006044, 0x0000003c },
+ { 0x00006048, 0x00000040 },
+ { 0x0000604c, 0x00000043 },
+ { 0x00006050, 0x00000047 },
+ { 0x00006054, 0x0000004a },
+ { 0x00006058, 0x0000004e },
+ { 0x0000605c, 0x00000051 },
+ { 0x00006060, 0x00000055 },
+ { 0x00006064, 0x00000058 },
+ { 0x00006068, 0x0000005c },
+ { 0x0000606c, 0x00000060 },
+ { 0x00006070, 0x00000063 },
+ { 0x00006074, 0x00000067 },
+ { 0x00006078, 0x0000006a },
+ { 0x0000607c, 0x0000006e },
+ { 0x00006080, 0x00000071 },
+ { 0x00006084, 0x00000075 },
+ { 0x00006088, 0x00000078 },
+ { 0x0000608c, 0x0000007c },
+ { 0x00006090, 0x00000080 },
+ { 0x00006094, 0x00000083 },
+ { 0x00006098, 0x00000087 },
+ { 0x0000609c, 0x0000008a },
+ { 0x000060a0, 0x0000008e },
+ { 0x000060a4, 0x00000091 },
+ { 0x000060a8, 0x00000095 },
+ { 0x000060ac, 0x00000099 },
+ { 0x000060b0, 0x0000009c },
+ { 0x000060b4, 0x000000a0 },
+ { 0x000060b8, 0x000000a3 },
+ { 0x000060bc, 0x000000a7 },
+ { 0x000060c0, 0x000000aa },
+ { 0x000060c4, 0x000000ae },
+ { 0x000060c8, 0x000000b1 },
+ { 0x000060cc, 0x000000b5 },
+ { 0x000060d0, 0x000000b9 },
+ { 0x000060d4, 0x000000bc },
+ { 0x000060d8, 0x000000c0 },
+ { 0x000060dc, 0x000000c3 },
+ { 0x000060e0, 0x000000c7 },
+ { 0x000060e4, 0x000000ca },
+ { 0x000060e8, 0x000000ce },
+ { 0x000060ec, 0x000000d1 },
+ { 0x000060f0, 0x000000d5 },
+ { 0x000060f4, 0x000000d9 },
+ { 0x000060f8, 0x000000dc },
+ { 0x000060fc, 0x000000e0 },
+ { 0x00006100, 0x000000e3 },
+ { 0x00006104, 0x000000e7 },
+ { 0x00006108, 0x000000ea },
+ { 0x0000610c, 0x000000ee },
+ { 0x00006110, 0x000000f1 },
+ { 0x00006114, 0x000000f5 },
+ { 0x00006118, 0x000000f9 },
+ { 0x0000611c, 0x000000fc },
+ { 0x00006120, 0x00000100 },
+ { 0x00006124, 0x00000103 },
+ { 0x00006128, 0x00000107 },
+ { 0x0000612c, 0x0000010a },
+ { 0x00006130, 0x0000010e },
+ { 0x00006134, 0x00000112 },
+ { 0x00006138, 0x00000115 },
+ { 0x0000613c, 0x00000119 },
+ { 0x00006140, 0x0000011c },
+ { 0x00006144, 0x00000120 },
+ { 0x00006148, 0x00000123 },
+ { 0x0000614c, 0x00000126 },
+ { 0x00006150, 0x0000012a },
+ { 0x00006154, 0x0000012d },
+ { 0x00006158, 0x00000131 },
+ { 0x0000615c, 0x00000134 },
+ { 0x00006160, 0x00000138 },
+ { 0x00006164, 0x0000013c },
+ { 0x00006168, 0x0000013f },
+ { 0x0000616c, 0x00000143 },
+ { 0x00006170, 0x00000147 },
+ { 0x00006174, 0x0000014b },
+ { 0x00006178, 0x0000014e },
+ { 0x0000617c, 0x00000152 },
+ { 0x00006180, 0x00000156 },
+ { 0x00006184, 0x0000015a },
+ { 0x00006188, 0x0000015e },
+ { 0x0000618c, 0x00000162 },
+ { 0x00006190, 0x00000166 },
+ { 0x00006194, 0x0000016a },
+ { 0x00006198, 0x0000016e },
+ { 0x0000619c, 0x00000172 },
+ { 0x000061a0, 0x00000176 },
+ { 0x000061a4, 0x0000017a },
+ { 0x000061a8, 0x0000017e },
+ { 0x000061ac, 0x00000182 },
+ { 0x000061b0, 0x00000186 },
+ { 0x000061b4, 0x0000018a },
+ { 0x000061b8, 0x0000018f },
+ { 0x000061bc, 0x00000193 },
+ { 0x000061c0, 0x00000197 },
+ { 0x000061c4, 0x0000019b },
+ { 0x000061c8, 0x000001a0 },
+ { 0x000061cc, 0x000001a4 },
+ { 0x000061d0, 0x000001a8 },
+ { 0x000061d4, 0x000001ad },
+ { 0x000061d8, 0x000001b1 },
+ { 0x000061dc, 0x000001b5 },
+ { 0x000061e0, 0x000001ba },
+ { 0x000061e4, 0x000001be },
+ { 0x000061e8, 0x000001c3 },
+ { 0x000061ec, 0x000001c7 },
+ { 0x000061f0, 0x000001cc },
+ { 0x000061f4, 0x000001d0 },
+ { 0x000061f8, 0x000001d5 },
+ { 0x000061fc, 0x000001d9 },
+ { 0x00006200, 0x000001de },
+ { 0x00006204, 0x000001e3 },
+ { 0x00006208, 0x000001e7 },
+ { 0x0000620c, 0x000001ec },
+ { 0x00006210, 0x000001f1 },
+ { 0x00006214, 0x000001f6 },
+ { 0x00006218, 0x000001fa },
+ { 0x0000621c, 0x000001ff },
+ { 0x00006220, 0x00000204 },
+ { 0x00006224, 0x00000209 },
+ { 0x00006228, 0x0000020e },
+ { 0x0000622c, 0x00000213 },
+ { 0x00006230, 0x00000217 },
+ { 0x00006234, 0x0000021c },
+ { 0x00006238, 0x00000221 },
+ { 0x0000623c, 0x00000226 },
+ { 0x00006240, 0x0000022b },
+ { 0x00006244, 0x00000230 },
+ { 0x00006248, 0x00000236 },
+ { 0x0000624c, 0x0000023b },
+ { 0x00006250, 0x00000240 },
+ { 0x00006254, 0x00000245 },
+ { 0x00006258, 0x0000024a },
+ { 0x0000625c, 0x0000024f },
+ { 0x00006260, 0x00000255 },
+ { 0x00006264, 0x0000025a },
+ { 0x00006268, 0x0000025f },
+ { 0x0000626c, 0x00000264 },
+ { 0x00006270, 0x0000026a },
+ { 0x00006274, 0x0000026f },
+ { 0x00006278, 0x00000274 },
+ { 0x0000627c, 0x0000027a },
+ { 0x00006280, 0x0000027f },
+ { 0x00006284, 0x00000285 },
+ { 0x00006288, 0x0000028a },
+ { 0x0000628c, 0x00000290 },
+ { 0x00006290, 0x00000295 },
+ { 0x00006294, 0x0000029b },
+ { 0x00006298, 0x000002a0 },
+ { 0x0000629c, 0x000002a6 },
+ { 0x000062a0, 0x000002ac },
+ { 0x000062a4, 0x000002b1 },
+ { 0x000062a8, 0x000002b7 },
+ { 0x000062ac, 0x000002bd },
+ { 0x000062b0, 0x000002c2 },
+ { 0x000062b4, 0x000002c8 },
+ { 0x000062b8, 0x000002ce },
+ { 0x000062bc, 0x000002d4 },
+ { 0x000062c0, 0x000002da },
+ { 0x000062c4, 0x000002df },
+ { 0x000062c8, 0x000002e5 },
+ { 0x000062cc, 0x000002eb },
+ { 0x000062d0, 0x000002f1 },
+ { 0x000062d4, 0x000002f7 },
+ { 0x000062d8, 0x000002fd },
+ { 0x000062dc, 0x00000303 },
+ { 0x000062e0, 0x00000309 },
+ { 0x000062e4, 0x0000030f },
+ { 0x000062e8, 0x00000315 },
+ { 0x000062ec, 0x0000031c },
+ { 0x000062f0, 0x00000322 },
+ { 0x000062f4, 0x00000328 },
+ { 0x000062f8, 0x0000032e },
+ { 0x000062fc, 0x00000334 },
+ { 0x00006300, 0x0000033b },
+ { 0x00006304, 0x00000341 },
+ { 0x00006308, 0x00000347 },
+ { 0x0000630c, 0x0000034d },
+ { 0x00006310, 0x00000354 },
+ { 0x00006314, 0x0000035a },
+ { 0x00006318, 0x00000361 },
+ { 0x0000631c, 0x00000367 },
+ { 0x00006320, 0x0000036d },
+ { 0x00006324, 0x00000374 },
+ { 0x00006328, 0x0000037a },
+ { 0x0000632c, 0x00000381 },
+ { 0x00006330, 0x00000388 },
+ { 0x00006334, 0x0000038e },
+ { 0x00006338, 0x00000395 },
+ { 0x0000633c, 0x0000039b },
+ { 0x00006340, 0x000003a2 },
+ { 0x00006344, 0x000003a9 },
+ { 0x00006348, 0x000003b0 },
+ { 0x0000634c, 0x000003b6 },
+ { 0x00006350, 0x000003bd },
+ { 0x00006354, 0x000003c4 },
+ { 0x00006358, 0x000003cb },
+ { 0x0000635c, 0x000003d2 },
+ { 0x00006360, 0x000003d8 },
+ { 0x00006364, 0x000003df },
+ { 0x00006368, 0x000003e6 },
+ { 0x0000636c, 0x000003ed },
+ { 0x00006370, 0x000003f4 },
+ { 0x00006374, 0x000003fb },
+ { 0x00006378, 0x00000402 },
+ { 0x0000637c, 0x00000409 },
+ { 0x00006380, 0x00000411 },
+ { 0x00006384, 0x00000418 },
+ { 0x00006388, 0x0000041f },
+ { 0x0000638c, 0x00000426 },
+ { 0x00006390, 0x0000042d },
+ { 0x00006394, 0x00000434 },
+ { 0x00006398, 0x0000043c },
+ { 0x0000639c, 0x00000443 },
+ { 0x000063a0, 0x0000044a },
+ { 0x000063a4, 0x00000452 },
+ { 0x000063a8, 0x00000459 },
+ { 0x000063ac, 0x00000460 },
+ { 0x000063b0, 0x00000468 },
+ { 0x000063b4, 0x0000046f },
+ { 0x000063b8, 0x00000477 },
+ { 0x000063bc, 0x0000047e },
+ { 0x000063c0, 0x00000486 },
+ { 0x000063c4, 0x0000048d },
+ { 0x000063c8, 0x00000495 },
+ { 0x000063cc, 0x0000049c },
+ { 0x000063d0, 0x000004a4 },
+ { 0x000063d4, 0x000004ac },
+ { 0x000063d8, 0x000004b3 },
+ { 0x000063dc, 0x000004bb },
+ { 0x000063e0, 0x000004c3 },
+ { 0x000063e4, 0x000004cb },
+ { 0x000063e8, 0x000004d3 },
+ { 0x000063ec, 0x000004da },
+ { 0x000063f0, 0x000004e2 },
+ { 0x000063f4, 0x000004ea },
+ { 0x000063f8, 0x000004f2 },
+ { 0x000063fc, 0x000004fa },
+ { 0x00006400, 0x00000502 },
+ { 0x00006404, 0x0000050a },
+ { 0x00006408, 0x00000512 },
+ { 0x0000640c, 0x0000051a },
+ { 0x00006410, 0x00000522 },
+ { 0x00006414, 0x0000052a },
+ { 0x00006418, 0x00000532 },
+ { 0x0000641c, 0x0000053a },
+ { 0x00006420, 0x00000543 },
+ { 0x00006424, 0x0000054b },
+ { 0x00006428, 0x00000553 },
+ { 0x0000642c, 0x0000055b },
+ { 0x00006430, 0x00000564 },
+ { 0x00006434, 0x0000056c },
+ { 0x00006438, 0x00000574 },
+ { 0x0000643c, 0x0000057d },
+ { 0x00006440, 0x00000585 },
+ { 0x00006444, 0x0000058d },
+ { 0x00006448, 0x00000596 },
+ { 0x0000644c, 0x0000059e },
+ { 0x00006450, 0x000005a7 },
+ { 0x00006454, 0x000005af },
+ { 0x00006458, 0x000005b8 },
+ { 0x0000645c, 0x000005c1 },
+ { 0x00006460, 0x000005c9 },
+ { 0x00006464, 0x000005d2 },
+ { 0x00006468, 0x000005db },
+ { 0x0000646c, 0x000005e3 },
+ { 0x00006470, 0x000005ec },
+ { 0x00006474, 0x000005f5 },
+ { 0x00006478, 0x000005fe },
+ { 0x0000647c, 0x00000606 },
+ { 0x00006480, 0x0000060f },
+ { 0x00006484, 0x00000618 },
+ { 0x00006488, 0x00000621 },
+ { 0x0000648c, 0x0000062a },
+ { 0x00006490, 0x00000633 },
+ { 0x00006494, 0x0000063c },
+ { 0x00006498, 0x00000645 },
+ { 0x0000649c, 0x0000064e },
+ { 0x000064a0, 0x00000657 },
+ { 0x000064a4, 0x00000660 },
+ { 0x000064a8, 0x00000669 },
+ { 0x000064ac, 0x00000672 },
+ { 0x000064b0, 0x0000067b },
+ { 0x000064b4, 0x00000685 },
+ { 0x000064b8, 0x0000068e },
+ { 0x000064bc, 0x00000697 },
+ { 0x000064c0, 0x000006a0 },
+ { 0x000064c4, 0x000006aa },
+ { 0x000064c8, 0x000006b3 },
+ { 0x000064cc, 0x000006bd },
+ { 0x000064d0, 0x000006c6 },
+ { 0x000064d4, 0x000006cf },
+ { 0x000064d8, 0x000006d9 },
+ { 0x000064dc, 0x000006e2 },
+ { 0x000064e0, 0x000006ec },
+ { 0x000064e4, 0x000006f5 },
+ { 0x000064e8, 0x000006ff },
+ { 0x000064ec, 0x00000709 },
+ { 0x000064f0, 0x00000712 },
+ { 0x000064f4, 0x0000071c },
+ { 0x000064f8, 0x00000726 },
+ { 0x000064fc, 0x0000072f },
+ { 0x00006500, 0x00000739 },
+ { 0x00006504, 0x00000743 },
+ { 0x00006508, 0x0000074d },
+ { 0x0000650c, 0x00000756 },
+ { 0x00006510, 0x00000760 },
+ { 0x00006514, 0x0000076a },
+ { 0x00006518, 0x00000774 },
+ { 0x0000651c, 0x0000077e },
+ { 0x00006520, 0x00000788 },
+ { 0x00006524, 0x00000792 },
+ { 0x00006528, 0x0000079c },
+ { 0x0000652c, 0x000007a6 },
+ { 0x00006530, 0x000007b0 },
+ { 0x00006534, 0x000007ba },
+ { 0x00006538, 0x000007c4 },
+ { 0x0000653c, 0x000007cf },
+ { 0x00006540, 0x000007d9 },
+ { 0x00006544, 0x000007e3 },
+ { 0x00006548, 0x000007ed },
+ { 0x0000654c, 0x000007f7 },
+ { 0x00006550, 0x00000802 },
+ { 0x00006554, 0x0000080c },
+ { 0x00006558, 0x00000816 },
+ { 0x0000655c, 0x00000821 },
+ { 0x00006560, 0x0000082b },
+ { 0x00006564, 0x00000836 },
+ { 0x00006568, 0x00000840 },
+ { 0x0000656c, 0x0000084b },
+ { 0x00006570, 0x00000855 },
+ { 0x00006574, 0x00000860 },
+ { 0x00006578, 0x0000086a },
+ { 0x0000657c, 0x00000875 },
+ { 0x00006580, 0x00000880 },
+ { 0x00006584, 0x0000088a },
+ { 0x00006588, 0x00000895 },
+ { 0x0000658c, 0x000008a0 },
+ { 0x00006590, 0x000008ab },
+ { 0x00006594, 0x000008b5 },
+ { 0x00006598, 0x000008c0 },
+ { 0x0000659c, 0x000008cb },
+ { 0x000065a0, 0x000008d6 },
+ { 0x000065a4, 0x000008e1 },
+ { 0x000065a8, 0x000008ec },
+ { 0x000065ac, 0x000008f7 },
+ { 0x000065b0, 0x00000902 },
+ { 0x000065b4, 0x0000090d },
+ { 0x000065b8, 0x00000918 },
+ { 0x000065bc, 0x00000923 },
+ { 0x000065c0, 0x0000092e },
+ { 0x000065c4, 0x00000939 },
+ { 0x000065c8, 0x00000944 },
+ { 0x000065cc, 0x00000950 },
+ { 0x000065d0, 0x0000095b },
+ { 0x000065d4, 0x00000966 },
+ { 0x000065d8, 0x00000971 },
+ { 0x000065dc, 0x0000097d },
+ { 0x000065e0, 0x00000988 },
+ { 0x000065e4, 0x00000993 },
+ { 0x000065e8, 0x0000099f },
+ { 0x000065ec, 0x000009aa },
+ { 0x000065f0, 0x000009b6 },
+ { 0x000065f4, 0x000009c1 },
+ { 0x000065f8, 0x000009cd },
+ { 0x000065fc, 0x000009d8 },
+ { 0x00006600, 0x000009e4 },
+ { 0x00006604, 0x000009f0 },
+ { 0x00006608, 0x000009fb },
+ { 0x0000660c, 0x00000a07 },
+ { 0x00006610, 0x00000a13 },
+ { 0x00006614, 0x00000a1e },
+ { 0x00006618, 0x00000a2a },
+ { 0x0000661c, 0x00000a36 },
+ { 0x00006620, 0x00000a42 },
+ { 0x00006624, 0x00000a4e },
+ { 0x00006628, 0x00000a59 },
+ { 0x0000662c, 0x00000a65 },
+ { 0x00006630, 0x00000a71 },
+ { 0x00006634, 0x00000a7d },
+ { 0x00006638, 0x00000a89 },
+ { 0x0000663c, 0x00000a95 },
+ { 0x00006640, 0x00000aa1 },
+ { 0x00006644, 0x00000aad },
+ { 0x00006648, 0x00000ab9 },
+ { 0x0000664c, 0x00000ac6 },
+ { 0x00006650, 0x00000ad2 },
+ { 0x00006654, 0x00000ade },
+ { 0x00006658, 0x00000aea },
+ { 0x0000665c, 0x00000af6 },
+ { 0x00006660, 0x00000b03 },
+ { 0x00006664, 0x00000b0f },
+ { 0x00006668, 0x00000b1b },
+ { 0x0000666c, 0x00000b28 },
+ { 0x00006670, 0x00000b34 },
+ { 0x00006674, 0x00000b41 },
+ { 0x00006678, 0x00000b4d },
+ { 0x0000667c, 0x00000b5a },
+ { 0x00006680, 0x00000b66 },
+ { 0x00006684, 0x00000b73 },
+ { 0x00006688, 0x00000b7f },
+ { 0x0000668c, 0x00000b8c },
+ { 0x00006690, 0x00000b98 },
+ { 0x00006694, 0x00000ba5 },
+ { 0x00006698, 0x00000bb2 },
+ { 0x0000669c, 0x00000bbf },
+ { 0x000066a0, 0x00000bcb },
+ { 0x000066a4, 0x00000bd8 },
+ { 0x000066a8, 0x00000be5 },
+ { 0x000066ac, 0x00000bf2 },
+ { 0x000066b0, 0x00000bff },
+ { 0x000066b4, 0x00000c0c },
+ { 0x000066b8, 0x00000c19 },
+ { 0x000066bc, 0x00000c25 },
+ { 0x000066c0, 0x00000c32 },
+ { 0x000066c4, 0x00000c40 },
+ { 0x000066c8, 0x00000c4d },
+ { 0x000066cc, 0x00000c5a },
+ { 0x000066d0, 0x00000c67 },
+ { 0x000066d4, 0x00000c74 },
+ { 0x000066d8, 0x00000c81 },
+ { 0x000066dc, 0x00000c8e },
+ { 0x000066e0, 0x00000c9c },
+ { 0x000066e4, 0x00000ca9 },
+ { 0x000066e8, 0x00000cb6 },
+ { 0x000066ec, 0x00000cc3 },
+ { 0x000066f0, 0x00000cd1 },
+ { 0x000066f4, 0x00000cde },
+ { 0x000066f8, 0x00000cec },
+ { 0x000066fc, 0x00000cf9 },
+ { 0x00006700, 0x00000d07 },
+ { 0x00006704, 0x00000d14 },
+ { 0x00006708, 0x00000d22 },
+ { 0x0000670c, 0x00000d2f },
+ { 0x00006710, 0x00000d3d },
+ { 0x00006714, 0x00000d4a },
+ { 0x00006718, 0x00000d58 },
+ { 0x0000671c, 0x00000d66 },
+ { 0x00006720, 0x00000d73 },
+ { 0x00006724, 0x00000d81 },
+ { 0x00006728, 0x00000d8f },
+ { 0x0000672c, 0x00000d9d },
+ { 0x00006730, 0x00000dab },
+ { 0x00006734, 0x00000db8 },
+ { 0x00006738, 0x00000dc6 },
+ { 0x0000673c, 0x00000dd4 },
+ { 0x00006740, 0x00000de2 },
+ { 0x00006744, 0x00000df0 },
+ { 0x00006748, 0x00000dfe },
+ { 0x0000674c, 0x00000e0c },
+ { 0x00006750, 0x00000e1a },
+ { 0x00006754, 0x00000e29 },
+ { 0x00006758, 0x00000e37 },
+ { 0x0000675c, 0x00000e45 },
+ { 0x00006760, 0x00000e53 },
+ { 0x00006764, 0x00000e61 },
+ { 0x00006768, 0x00000e70 },
+ { 0x0000676c, 0x00000e7e },
+ { 0x00006770, 0x00000e8c },
+ { 0x00006774, 0x00000e9a },
+ { 0x00006778, 0x00000ea9 },
+ { 0x0000677c, 0x00000eb7 },
+ { 0x00006780, 0x00000ec6 },
+ { 0x00006784, 0x00000ed4 },
+ { 0x00006788, 0x00000ee3 },
+ { 0x0000678c, 0x00000ef1 },
+ { 0x00006790, 0x00000f00 },
+ { 0x00006794, 0x00000f0e },
+ { 0x00006798, 0x00000f1d },
+ { 0x0000679c, 0x00000f2c },
+ { 0x000067a0, 0x00000f3a },
+ { 0x000067a4, 0x00000f49 },
+ { 0x000067a8, 0x00000f58 },
+ { 0x000067ac, 0x00000f67 },
+ { 0x000067b0, 0x00000f75 },
+ { 0x000067b4, 0x00000f84 },
+ { 0x000067b8, 0x00000f93 },
+ { 0x000067bc, 0x00000fa2 },
+ { 0x000067c0, 0x00000fb1 },
+ { 0x000067c4, 0x00000fc0 },
+ { 0x000067c8, 0x00000fcf },
+ { 0x000067cc, 0x00000fde },
+ { 0x000067d0, 0x00000fed },
+ { 0x000067d4, 0x00000ffc },
+ { 0x000067d8, 0x0000100b },
+ { 0x000067dc, 0x0000101a },
+ { 0x000067e0, 0x0000102a },
+ { 0x000067e4, 0x00001039 },
+ { 0x000067e8, 0x00001048 },
+ { 0x000067ec, 0x00001057 },
+ { 0x000067f0, 0x00001067 },
+ { 0x000067f4, 0x00001076 },
+ { 0x000067f8, 0x00001085 },
+ { 0x000067fc, 0x00001095 },
+ { 0x00006800, 0x000010a4 },
+ { 0x00006804, 0x000010b4 },
+ { 0x00006808, 0x000010c3 },
+ { 0x0000680c, 0x000010d3 },
+ { 0x00006810, 0x000010e2 },
+ { 0x00006814, 0x000010f2 },
+ { 0x00006818, 0x00001101 },
+ { 0x0000681c, 0x00001111 },
+ { 0x00006820, 0x00001121 },
+ { 0x00006824, 0x00001130 },
+ { 0x00006828, 0x00001140 },
+ { 0x0000682c, 0x00001150 },
+ { 0x00006830, 0x00001160 },
+ { 0x00006834, 0x0000116f },
+ { 0x00006838, 0x0000117f },
+ { 0x0000683c, 0x0000118f },
+ { 0x00006840, 0x0000119f },
+ { 0x00006844, 0x000011af },
+ { 0x00006848, 0x000011bf },
+ { 0x0000684c, 0x000011cf },
+ { 0x00006850, 0x000011df },
+ { 0x00006854, 0x000011ef },
+ { 0x00006858, 0x000011ff },
+ { 0x0000685c, 0x0000120f },
+ { 0x00006860, 0x0000121f },
+ { 0x00006864, 0x00001230 },
+ { 0x00006868, 0x00001240 },
+ { 0x0000686c, 0x00001250 },
+ { 0x00006870, 0x00001260 },
+ { 0x00006874, 0x00001271 },
+ { 0x00006878, 0x00001281 },
+ { 0x0000687c, 0x00001291 },
+ { 0x00006880, 0x000012a2 },
+ { 0x00006884, 0x000012b2 },
+ { 0x00006888, 0x000012c3 },
+ { 0x0000688c, 0x000012d3 },
+ { 0x00006890, 0x000012e4 },
+ { 0x00006894, 0x000012f4 },
+ { 0x00006898, 0x00001305 },
+ { 0x0000689c, 0x00001316 },
+ { 0x000068a0, 0x00001326 },
+ { 0x000068a4, 0x00001337 },
+ { 0x000068a8, 0x00001348 },
+ { 0x000068ac, 0x00001359 },
+ { 0x000068b0, 0x00001369 },
+ { 0x000068b4, 0x0000137a },
+ { 0x000068b8, 0x0000138b },
+ { 0x000068bc, 0x0000139c },
+ { 0x000068c0, 0x000013ad },
+ { 0x000068c4, 0x000013be },
+ { 0x000068c8, 0x000013cf },
+ { 0x000068cc, 0x000013e0 },
+ { 0x000068d0, 0x000013f1 },
+ { 0x000068d4, 0x00001402 },
+ { 0x000068d8, 0x00001413 },
+ { 0x000068dc, 0x00001424 },
+ { 0x000068e0, 0x00001435 },
+ { 0x000068e4, 0x00001446 },
+ { 0x000068e8, 0x00001458 },
+ { 0x000068ec, 0x00001469 },
+ { 0x000068f0, 0x0000147a },
+ { 0x000068f4, 0x0000148b },
+ { 0x000068f8, 0x0000149d },
+ { 0x000068fc, 0x000014ae },
+ { 0x00006900, 0x000014c0 },
+ { 0x00006904, 0x000014d1 },
+ { 0x00006908, 0x000014e3 },
+ { 0x0000690c, 0x000014f4 },
+ { 0x00006910, 0x00001506 },
+ { 0x00006914, 0x00001517 },
+ { 0x00006918, 0x00001529 },
+ { 0x0000691c, 0x0000153a },
+ { 0x00006920, 0x0000154c },
+ { 0x00006924, 0x0000155e },
+ { 0x00006928, 0x0000156f },
+ { 0x0000692c, 0x00001581 },
+ { 0x00006930, 0x00001593 },
+ { 0x00006934, 0x000015a5 },
+ { 0x00006938, 0x000015b7 },
+ { 0x0000693c, 0x000015c9 },
+ { 0x00006940, 0x000015db },
+ { 0x00006944, 0x000015ec },
+ { 0x00006948, 0x000015fe },
+ { 0x0000694c, 0x00001610 },
+ { 0x00006950, 0x00001623 },
+ { 0x00006954, 0x00001635 },
+ { 0x00006958, 0x00001647 },
+ { 0x0000695c, 0x00001659 },
+ { 0x00006960, 0x0000166b },
+ { 0x00006964, 0x0000167d },
+ { 0x00006968, 0x0000168f },
+ { 0x0000696c, 0x000016a2 },
+ { 0x00006970, 0x000016b4 },
+ { 0x00006974, 0x000016c6 },
+ { 0x00006978, 0x000016d9 },
+ { 0x0000697c, 0x000016eb },
+ { 0x00006980, 0x000016fe },
+ { 0x00006984, 0x00001710 },
+ { 0x00006988, 0x00001722 },
+ { 0x0000698c, 0x00001735 },
+ { 0x00006990, 0x00001748 },
+ { 0x00006994, 0x0000175a },
+ { 0x00006998, 0x0000176d },
+ { 0x0000699c, 0x0000177f },
+ { 0x000069a0, 0x00001792 },
+ { 0x000069a4, 0x000017a5 },
+ { 0x000069a8, 0x000017b8 },
+ { 0x000069ac, 0x000017ca },
+ { 0x000069b0, 0x000017dd },
+ { 0x000069b4, 0x000017f0 },
+ { 0x000069b8, 0x00001803 },
+ { 0x000069bc, 0x00001816 },
+ { 0x000069c0, 0x00001829 },
+ { 0x000069c4, 0x0000183c },
+ { 0x000069c8, 0x0000184f },
+ { 0x000069cc, 0x00001862 },
+ { 0x000069d0, 0x00001875 },
+ { 0x000069d4, 0x00001888 },
+ { 0x000069d8, 0x0000189b },
+ { 0x000069dc, 0x000018ae },
+ { 0x000069e0, 0x000018c1 },
+ { 0x000069e4, 0x000018d5 },
+ { 0x000069e8, 0x000018e8 },
+ { 0x000069ec, 0x000018fb },
+ { 0x000069f0, 0x0000190e },
+ { 0x000069f4, 0x00001922 },
+ { 0x000069f8, 0x00001935 },
+ { 0x000069fc, 0x00001949 },
+ { 0x00006a00, 0x0000195c },
+ { 0x00006a04, 0x0000196f },
+ { 0x00006a08, 0x00001983 },
+ { 0x00006a0c, 0x00001996 },
+ { 0x00006a10, 0x000019aa },
+ { 0x00006a14, 0x000019be },
+ { 0x00006a18, 0x000019d1 },
+ { 0x00006a1c, 0x000019e5 },
+ { 0x00006a20, 0x000019f9 },
+ { 0x00006a24, 0x00001a0c },
+ { 0x00006a28, 0x00001a20 },
+ { 0x00006a2c, 0x00001a34 },
+ { 0x00006a30, 0x00001a48 },
+ { 0x00006a34, 0x00001a5c },
+ { 0x00006a38, 0x00001a70 },
+ { 0x00006a3c, 0x00001a84 },
+ { 0x00006a40, 0x00001a97 },
+ { 0x00006a44, 0x00001aab },
+ { 0x00006a48, 0x00001ac0 },
+ { 0x00006a4c, 0x00001ad4 },
+ { 0x00006a50, 0x00001ae8 },
+ { 0x00006a54, 0x00001afc },
+ { 0x00006a58, 0x00001b10 },
+ { 0x00006a5c, 0x00001b24 },
+ { 0x00006a60, 0x00001b38 },
+ { 0x00006a64, 0x00001b4d },
+ { 0x00006a68, 0x00001b61 },
+ { 0x00006a6c, 0x00001b75 },
+ { 0x00006a70, 0x00001b8a },
+ { 0x00006a74, 0x00001b9e },
+ { 0x00006a78, 0x00001bb2 },
+ { 0x00006a7c, 0x00001bc7 },
+ { 0x00006a80, 0x00001bdb },
+ { 0x00006a84, 0x00001bf0 },
+ { 0x00006a88, 0x00001c04 },
+ { 0x00006a8c, 0x00001c19 },
+ { 0x00006a90, 0x00001c2e },
+ { 0x00006a94, 0x00001c42 },
+ { 0x00006a98, 0x00001c57 },
+ { 0x00006a9c, 0x00001c6c },
+ { 0x00006aa0, 0x00001c80 },
+ { 0x00006aa4, 0x00001c95 },
+ { 0x00006aa8, 0x00001caa },
+ { 0x00006aac, 0x00001cbf },
+ { 0x00006ab0, 0x00001cd4 },
+ { 0x00006ab4, 0x00001ce8 },
+ { 0x00006ab8, 0x00001cfd },
+ { 0x00006abc, 0x00001d12 },
+ { 0x00006ac0, 0x00001d27 },
+ { 0x00006ac4, 0x00001d3c },
+ { 0x00006ac8, 0x00001d51 },
+ { 0x00006acc, 0x00001d67 },
+ { 0x00006ad0, 0x00001d7c },
+ { 0x00006ad4, 0x00001d91 },
+ { 0x00006ad8, 0x00001da6 },
+ { 0x00006adc, 0x00001dbb },
+ { 0x00006ae0, 0x00001dd1 },
+ { 0x00006ae4, 0x00001de6 },
+ { 0x00006ae8, 0x00001dfb },
+ { 0x00006aec, 0x00001e10 },
+ { 0x00006af0, 0x00001e26 },
+ { 0x00006af4, 0x00001e3b },
+ { 0x00006af8, 0x00001e51 },
+ { 0x00006afc, 0x00001e66 },
+ { 0x00006b00, 0x00001e7c },
+ { 0x00006b04, 0x00001e91 },
+ { 0x00006b08, 0x00001ea7 },
+ { 0x00006b0c, 0x00001ebd },
+ { 0x00006b10, 0x00001ed2 },
+ { 0x00006b14, 0x00001ee8 },
+ { 0x00006b18, 0x00001efe },
+ { 0x00006b1c, 0x00001f13 },
+ { 0x00006b20, 0x00001f29 },
+ { 0x00006b24, 0x00001f3f },
+ { 0x00006b28, 0x00001f55 },
+ { 0x00006b2c, 0x00001f6b },
+ { 0x00006b30, 0x00001f81 },
+ { 0x00006b34, 0x00001f96 },
+ { 0x00006b38, 0x00001fac },
+ { 0x00006b3c, 0x00001fc2 },
+ { 0x00006b40, 0x00001fd9 },
+ { 0x00006b44, 0x00001fef },
+ { 0x00006b48, 0x00002005 },
+ { 0x00006b4c, 0x0000201b },
+ { 0x00006b50, 0x00002031 },
+ { 0x00006b54, 0x00002047 },
+ { 0x00006b58, 0x0000205d },
+ { 0x00006b5c, 0x00002074 },
+ { 0x00006b60, 0x0000208a },
+ { 0x00006b64, 0x000020a0 },
+ { 0x00006b68, 0x000020b7 },
+ { 0x00006b6c, 0x000020cd },
+ { 0x00006b70, 0x000020e4 },
+ { 0x00006b74, 0x000020fa },
+ { 0x00006b78, 0x00002111 },
+ { 0x00006b7c, 0x00002127 },
+ { 0x00006b80, 0x0000213e },
+ { 0x00006b84, 0x00002154 },
+ { 0x00006b88, 0x0000216b },
+ { 0x00006b8c, 0x00002182 },
+ { 0x00006b90, 0x00002198 },
+ { 0x00006b94, 0x000021af },
+ { 0x00006b98, 0x000021c6 },
+ { 0x00006b9c, 0x000021dd },
+ { 0x00006ba0, 0x000021f3 },
+ { 0x00006ba4, 0x0000220a },
+ { 0x00006ba8, 0x00002221 },
+ { 0x00006bac, 0x00002238 },
+ { 0x00006bb0, 0x0000224f },
+ { 0x00006bb4, 0x00002266 },
+ { 0x00006bb8, 0x0000227d },
+ { 0x00006bbc, 0x00002294 },
+ { 0x00006bc0, 0x000022ab },
+ { 0x00006bc4, 0x000022c2 },
+ { 0x00006bc8, 0x000022da },
+ { 0x00006bcc, 0x000022f1 },
+ { 0x00006bd0, 0x00002308 },
+ { 0x00006bd4, 0x0000231f },
+ { 0x00006bd8, 0x00002337 },
+ { 0x00006bdc, 0x0000234e },
+ { 0x00006be0, 0x00002365 },
+ { 0x00006be4, 0x0000237d },
+ { 0x00006be8, 0x00002394 },
+ { 0x00006bec, 0x000023ac },
+ { 0x00006bf0, 0x000023c3 },
+ { 0x00006bf4, 0x000023db },
+ { 0x00006bf8, 0x000023f2 },
+ { 0x00006bfc, 0x0000240a },
+ { 0x00006c00, 0x00002421 },
+ { 0x00006c04, 0x00002439 },
+ { 0x00006c08, 0x00002451 },
+ { 0x00006c0c, 0x00002469 },
+ { 0x00006c10, 0x00002480 },
+ { 0x00006c14, 0x00002498 },
+ { 0x00006c18, 0x000024b0 },
+ { 0x00006c1c, 0x000024c8 },
+ { 0x00006c20, 0x000024e0 },
+ { 0x00006c24, 0x000024f8 },
+ { 0x00006c28, 0x00002510 },
+ { 0x00006c2c, 0x00002528 },
+ { 0x00006c30, 0x00002540 },
+ { 0x00006c34, 0x00002558 },
+ { 0x00006c38, 0x00002570 },
+ { 0x00006c3c, 0x00002588 },
+ { 0x00006c40, 0x000025a0 },
+ { 0x00006c44, 0x000025b8 },
+ { 0x00006c48, 0x000025d0 },
+ { 0x00006c4c, 0x000025e9 },
+ { 0x00006c50, 0x00002601 },
+ { 0x00006c54, 0x00002619 },
+ { 0x00006c58, 0x00002632 },
+ { 0x00006c5c, 0x0000264a },
+ { 0x00006c60, 0x00002663 },
+ { 0x00006c64, 0x0000267b },
+ { 0x00006c68, 0x00002693 },
+ { 0x00006c6c, 0x000026ac },
+ { 0x00006c70, 0x000026c5 },
+ { 0x00006c74, 0x000026dd },
+ { 0x00006c78, 0x000026f6 },
+ { 0x00006c7c, 0x0000270e },
+ { 0x00006c80, 0x00002727 },
+ { 0x00006c84, 0x00002740 },
+ { 0x00006c88, 0x00002759 },
+ { 0x00006c8c, 0x00002771 },
+ { 0x00006c90, 0x0000278a },
+ { 0x00006c94, 0x000027a3 },
+ { 0x00006c98, 0x000027bc },
+ { 0x00006c9c, 0x000027d5 },
+ { 0x00006ca0, 0x000027ee },
+ { 0x00006ca4, 0x00002807 },
+ { 0x00006ca8, 0x00002820 },
+ { 0x00006cac, 0x00002839 },
+ { 0x00006cb0, 0x00002852 },
+ { 0x00006cb4, 0x0000286b },
+ { 0x00006cb8, 0x00002884 },
+ { 0x00006cbc, 0x0000289e },
+ { 0x00006cc0, 0x000028b7 },
+ { 0x00006cc4, 0x000028d0 },
+ { 0x00006cc8, 0x000028e9 },
+ { 0x00006ccc, 0x00002903 },
+ { 0x00006cd0, 0x0000291c },
+ { 0x00006cd4, 0x00002936 },
+ { 0x00006cd8, 0x0000294f },
+ { 0x00006cdc, 0x00002968 },
+ { 0x00006ce0, 0x00002982 },
+ { 0x00006ce4, 0x0000299c },
+ { 0x00006ce8, 0x000029b5 },
+ { 0x00006cec, 0x000029cf },
+ { 0x00006cf0, 0x000029e8 },
+ { 0x00006cf4, 0x00002a02 },
+ { 0x00006cf8, 0x00002a1c },
+ { 0x00006cfc, 0x00002a35 },
+ { 0x00006d00, 0x00002a4f },
+ { 0x00006d04, 0x00002a69 },
+ { 0x00006d08, 0x00002a83 },
+ { 0x00006d0c, 0x00002a9d },
+ { 0x00006d10, 0x00002ab7 },
+ { 0x00006d14, 0x00002ad1 },
+ { 0x00006d18, 0x00002aeb },
+ { 0x00006d1c, 0x00002b05 },
+ { 0x00006d20, 0x00002b1f },
+ { 0x00006d24, 0x00002b39 },
+ { 0x00006d28, 0x00002b53 },
+ { 0x00006d2c, 0x00002b6d },
+ { 0x00006d30, 0x00002b87 },
+ { 0x00006d34, 0x00002ba1 },
+ { 0x00006d38, 0x00002bbc },
+ { 0x00006d3c, 0x00002bd6 },
+ { 0x00006d40, 0x00002bf0 },
+ { 0x00006d44, 0x00002c0b },
+ { 0x00006d48, 0x00002c25 },
+ { 0x00006d4c, 0x00002c3f },
+ { 0x00006d50, 0x00002c5a },
+ { 0x00006d54, 0x00002c74 },
+ { 0x00006d58, 0x00002c8f },
+ { 0x00006d5c, 0x00002ca9 },
+ { 0x00006d60, 0x00002cc4 },
+ { 0x00006d64, 0x00002cdf },
+ { 0x00006d68, 0x00002cf9 },
+ { 0x00006d6c, 0x00002d14 },
+ { 0x00006d70, 0x00002d2f },
+ { 0x00006d74, 0x00002d49 },
+ { 0x00006d78, 0x00002d64 },
+ { 0x00006d7c, 0x00002d7f },
+ { 0x00006d80, 0x00002d9a },
+ { 0x00006d84, 0x00002db5 },
+ { 0x00006d88, 0x00002dd0 },
+ { 0x00006d8c, 0x00002deb },
+ { 0x00006d90, 0x00002e06 },
+ { 0x00006d94, 0x00002e21 },
+ { 0x00006d98, 0x00002e3c },
+ { 0x00006d9c, 0x00002e57 },
+ { 0x00006da0, 0x00002e72 },
+ { 0x00006da4, 0x00002e8d },
+ { 0x00006da8, 0x00002ea8 },
+ { 0x00006dac, 0x00002ec4 },
+ { 0x00006db0, 0x00002edf },
+ { 0x00006db4, 0x00002efa },
+ { 0x00006db8, 0x00002f16 },
+ { 0x00006dbc, 0x00002f31 },
+ { 0x00006dc0, 0x00002f4c },
+ { 0x00006dc4, 0x00002f68 },
+ { 0x00006dc8, 0x00002f83 },
+ { 0x00006dcc, 0x00002f9f },
+ { 0x00006dd0, 0x00002fba },
+ { 0x00006dd4, 0x00002fd6 },
+ { 0x00006dd8, 0x00002ff1 },
+ { 0x00006ddc, 0x0000300d },
+ { 0x00006de0, 0x00003029 },
+ { 0x00006de4, 0x00003044 },
+ { 0x00006de8, 0x00003060 },
+ { 0x00006dec, 0x0000307c },
+ { 0x00006df0, 0x00003098 },
+ { 0x00006df4, 0x000030b4 },
+ { 0x00006df8, 0x000030d0 },
+ { 0x00006dfc, 0x000030eb },
+ { 0x00006e00, 0x00003107 },
+ { 0x00006e04, 0x00003123 },
+ { 0x00006e08, 0x0000313f },
+ { 0x00006e0c, 0x0000315b },
+ { 0x00006e10, 0x00003178 },
+ { 0x00006e14, 0x00003194 },
+ { 0x00006e18, 0x000031b0 },
+ { 0x00006e1c, 0x000031cc },
+ { 0x00006e20, 0x000031e8 },
+ { 0x00006e24, 0x00003205 },
+ { 0x00006e28, 0x00003221 },
+ { 0x00006e2c, 0x0000323d },
+ { 0x00006e30, 0x0000325a },
+ { 0x00006e34, 0x00003276 },
+ { 0x00006e38, 0x00003292 },
+ { 0x00006e3c, 0x000032af },
+ { 0x00006e40, 0x000032cb },
+ { 0x00006e44, 0x000032e8 },
+ { 0x00006e48, 0x00003304 },
+ { 0x00006e4c, 0x00003321 },
+ { 0x00006e50, 0x0000333e },
+ { 0x00006e54, 0x0000335a },
+ { 0x00006e58, 0x00003377 },
+ { 0x00006e5c, 0x00003394 },
+ { 0x00006e60, 0x000033b1 },
+ { 0x00006e64, 0x000033cd },
+ { 0x00006e68, 0x000033ea },
+ { 0x00006e6c, 0x00003407 },
+ { 0x00006e70, 0x00003424 },
+ { 0x00006e74, 0x00003441 },
+ { 0x00006e78, 0x0000345e },
+ { 0x00006e7c, 0x0000347b },
+ { 0x00006e80, 0x00003498 },
+ { 0x00006e84, 0x000034b5 },
+ { 0x00006e88, 0x000034d2 },
+ { 0x00006e8c, 0x000034ef },
+ { 0x00006e90, 0x0000350d },
+ { 0x00006e94, 0x0000352a },
+ { 0x00006e98, 0x00003547 },
+ { 0x00006e9c, 0x00003564 },
+ { 0x00006ea0, 0x00003582 },
+ { 0x00006ea4, 0x0000359f },
+ { 0x00006ea8, 0x000035bc },
+ { 0x00006eac, 0x000035da },
+ { 0x00006eb0, 0x000035f7 },
+ { 0x00006eb4, 0x00003615 },
+ { 0x00006eb8, 0x00003632 },
+ { 0x00006ebc, 0x00003650 },
+ { 0x00006ec0, 0x0000366e },
+ { 0x00006ec4, 0x0000368b },
+ { 0x00006ec8, 0x000036a9 },
+ { 0x00006ecc, 0x000036c7 },
+ { 0x00006ed0, 0x000036e4 },
+ { 0x00006ed4, 0x00003702 },
+ { 0x00006ed8, 0x00003720 },
+ { 0x00006edc, 0x0000373e },
+ { 0x00006ee0, 0x0000375c },
+ { 0x00006ee4, 0x0000377a },
+ { 0x00006ee8, 0x00003798 },
+ { 0x00006eec, 0x000037b6 },
+ { 0x00006ef0, 0x000037d4 },
+ { 0x00006ef4, 0x000037f2 },
+ { 0x00006ef8, 0x00003810 },
+ { 0x00006efc, 0x0000382e },
+ { 0x00006f00, 0x0000384c },
+ { 0x00006f04, 0x0000386a },
+ { 0x00006f08, 0x00003888 },
+ { 0x00006f0c, 0x000038a7 },
+ { 0x00006f10, 0x000038c5 },
+ { 0x00006f14, 0x000038e3 },
+ { 0x00006f18, 0x00003902 },
+ { 0x00006f1c, 0x00003920 },
+ { 0x00006f20, 0x0000393f },
+ { 0x00006f24, 0x0000395d },
+ { 0x00006f28, 0x0000397c },
+ { 0x00006f2c, 0x0000399a },
+ { 0x00006f30, 0x000039b9 },
+ { 0x00006f34, 0x000039d7 },
+ { 0x00006f38, 0x000039f6 },
+ { 0x00006f3c, 0x00003a15 },
+ { 0x00006f40, 0x00003a33 },
+ { 0x00006f44, 0x00003a52 },
+ { 0x00006f48, 0x00003a71 },
+ { 0x00006f4c, 0x00003a90 },
+ { 0x00006f50, 0x00003aaf },
+ { 0x00006f54, 0x00003acd },
+ { 0x00006f58, 0x00003aec },
+ { 0x00006f5c, 0x00003b0b },
+ { 0x00006f60, 0x00003b2a },
+ { 0x00006f64, 0x00003b49 },
+ { 0x00006f68, 0x00003b68 },
+ { 0x00006f6c, 0x00003b87 },
+ { 0x00006f70, 0x00003ba7 },
+ { 0x00006f74, 0x00003bc6 },
+ { 0x00006f78, 0x00003be5 },
+ { 0x00006f7c, 0x00003c04 },
+ { 0x00006f80, 0x00003c24 },
+ { 0x00006f84, 0x00003c43 },
+ { 0x00006f88, 0x00003c62 },
+ { 0x00006f8c, 0x00003c82 },
+ { 0x00006f90, 0x00003ca1 },
+ { 0x00006f94, 0x00003cc0 },
+ { 0x00006f98, 0x00003ce0 },
+ { 0x00006f9c, 0x00003cff },
+ { 0x00006fa0, 0x00003d1f },
+ { 0x00006fa4, 0x00003d3f },
+ { 0x00006fa8, 0x00003d5e },
+ { 0x00006fac, 0x00003d7e },
+ { 0x00006fb0, 0x00003d9e },
+ { 0x00006fb4, 0x00003dbd },
+ { 0x00006fb8, 0x00003ddd },
+ { 0x00006fbc, 0x00003dfd },
+ { 0x00006fc0, 0x00003e1d },
+ { 0x00006fc4, 0x00003e3d },
+ { 0x00006fc8, 0x00003e5d },
+ { 0x00006fcc, 0x00003e7c },
+ { 0x00006fd0, 0x00003e9c },
+ { 0x00006fd4, 0x00003ebc },
+ { 0x00006fd8, 0x00003edc },
+ { 0x00006fdc, 0x00003efd },
+ { 0x00006fe0, 0x00003f1d },
+ { 0x00006fe4, 0x00003f3d },
+ { 0x00006fe8, 0x00003f5d },
+ { 0x00006fec, 0x00003f7d },
+ { 0x00006ff0, 0x00003f9e },
+ { 0x00006ff4, 0x00003fbe },
+ { 0x00006ff8, 0x00003fde },
+ { 0x00006ffc, 0x00003fff },
+};
+
+struct data_unit hdr10_pipe2_csca[] = {
+ { 0x00007004, 0x0000255f },
+ { 0x0000700c, 0x00003989 },
+ { 0x00007010, 0x0000255f },
+ { 0x00007014, 0x0000f928 },
+ { 0x00007018, 0x0000eee6 },
+ { 0x0000701c, 0x0000255f },
+ { 0x00007020, 0x000043cc },
+ { 0x00007028, 0x000003c0 },
+ { 0x0000702c, 0x00000200 },
+ { 0x00007030, 0x00000200 },
+ { 0x00007038, 0x00000240 },
+ { 0x0000703c, 0x00000240 },
+ { 0x00007040, 0x0000036c },
+ { 0x00007044, 0x000001c0 },
+ { 0x00007048, 0x000001c0 },
+ { 0x0000704c, 0x0000000d },
+ { 0x00007068, 0x000003ff },
+ { 0x0000706c, 0x000003ff },
+ { 0x00007070, 0x000003ff },
+ { 0x00007080, 0x00000003 },
+ { 0x00007000, 0x00000003 },
+};
+
+struct data_unit hdr10_pipe2_cscb[] = {
+ { 0x00007804, 0x00007fe2 },
+ { 0x00007814, 0x00007fe2 },
+ { 0x00007824, 0x00007fe2 },
+ { 0x00007840, 0x00003fff },
+ { 0x00007844, 0x00003fff },
+ { 0x00007848, 0x00003fff },
+ { 0x0000784c, 0x00000001 },
+ { 0x00007868, 0x0ffc0000 },
+ { 0x0000786c, 0x0ffc0000 },
+ { 0x00007870, 0x0ffc0000 },
+ { 0x00007874, 0x00000000 },
+ { 0x00007800, 0x00000003 },
+};
+
+/* Linear to Non-Linear Conversion Tables */
+struct data_unit hdr10_opipe_a0[] = {
+ { 0x0000c000, 0x00003612 },
+ { 0x0000c004, 0x00003612 },
+ { 0x0000c008, 0x0000327c },
+ { 0x0000c00c, 0x00003840 },
+ { 0x0000c010, 0x00002fb2 },
+ { 0x0000c014, 0x00003475 },
+ { 0x0000c018, 0x00003728 },
+ { 0x0000c01c, 0x0000390e },
+ { 0x0000c020, 0x00002d7f },
+ { 0x0000c024, 0x00003134 },
+ { 0x0000c028, 0x00003397 },
+ { 0x0000c02c, 0x0000353d },
+ { 0x0000c030, 0x00003695 },
+ { 0x0000c034, 0x000037cb },
+ { 0x0000c038, 0x000038a2 },
+ { 0x0000c03c, 0x00003982 },
+ { 0x0000c040, 0x00002b71 },
+ { 0x0000c044, 0x00002ea4 },
+ { 0x0000c048, 0x00003079 },
+ { 0x0000c04c, 0x00003204 },
+ { 0x0000c050, 0x00003302 },
+ { 0x0000c054, 0x0000341c },
+ { 0x0000c058, 0x000034d5 },
+ { 0x0000c05c, 0x000035ad },
+ { 0x0000c060, 0x00003651 },
+ { 0x0000c064, 0x000036dc },
+ { 0x0000c068, 0x00003778 },
+ { 0x0000c06c, 0x00003811 },
+ { 0x0000c070, 0x00003870 },
+ { 0x0000c074, 0x000038d7 },
+ { 0x0000c078, 0x00003946 },
+ { 0x0000c07c, 0x000039bf },
+ { 0x0000c080, 0x00002955 },
+ { 0x0000c084, 0x00002c9c },
+ { 0x0000c088, 0x00002e31 },
+ { 0x0000c08c, 0x00002f25 },
+ { 0x0000c090, 0x00003026 },
+ { 0x0000c094, 0x000030d3 },
+ { 0x0000c098, 0x0000319b },
+ { 0x0000c09c, 0x0000323e },
+ { 0x0000c0a0, 0x000032bd },
+ { 0x0000c0a4, 0x0000334b },
+ { 0x0000c0a8, 0x000033e6 },
+ { 0x0000c0ac, 0x00003448 },
+ { 0x0000c0b0, 0x000034a4 },
+ { 0x0000c0b4, 0x00003508 },
+ { 0x0000c0b8, 0x00003574 },
+ { 0x0000c0bc, 0x000035e7 },
+ { 0x0000c0c0, 0x00003631 },
+ { 0x0000c0c4, 0x00003672 },
+ { 0x0000c0c8, 0x000036b8 },
+ { 0x0000c0cc, 0x00003702 },
+ { 0x0000c0d0, 0x0000374f },
+ { 0x0000c0d4, 0x000037a1 },
+ { 0x0000c0d8, 0x000037f7 },
+ { 0x0000c0dc, 0x00003828 },
+ { 0x0000c0e0, 0x00003857 },
+ { 0x0000c0e4, 0x00003889 },
+ { 0x0000c0e8, 0x000038bc },
+ { 0x0000c0ec, 0x000038f2 },
+ { 0x0000c0f0, 0x0000392a },
+ { 0x0000c0f4, 0x00003964 },
+ { 0x0000c0f8, 0x000039a0 },
+ { 0x0000c0fc, 0x000039de },
+ { 0x0000c100, 0x0000271c },
+ { 0x0000c104, 0x00002a8e },
+ { 0x0000c108, 0x00002c2a },
+ { 0x0000c10c, 0x00002d0e },
+ { 0x0000c110, 0x00002df1 },
+ { 0x0000c114, 0x00002e69 },
+ { 0x0000c118, 0x00002ee3 },
+ { 0x0000c11c, 0x00002f6a },
+ { 0x0000c120, 0x00002ffe },
+ { 0x0000c124, 0x0000304f },
+ { 0x0000c128, 0x000030a5 },
+ { 0x0000c12c, 0x00003102 },
+ { 0x0000c130, 0x00003166 },
+ { 0x0000c134, 0x000031d1 },
+ { 0x0000c138, 0x00003221 },
+ { 0x0000c13c, 0x0000325d },
+ { 0x0000c140, 0x0000329c },
+ { 0x0000c144, 0x000032df },
+ { 0x0000c148, 0x00003326 },
+ { 0x0000c14c, 0x00003370 },
+ { 0x0000c150, 0x000033be },
+ { 0x0000c154, 0x00003407 },
+ { 0x0000c158, 0x00003432 },
+ { 0x0000c15c, 0x0000345e },
+ { 0x0000c160, 0x0000348c },
+ { 0x0000c164, 0x000034bd },
+ { 0x0000c168, 0x000034ef },
+ { 0x0000c16c, 0x00003522 },
+ { 0x0000c170, 0x00003558 },
+ { 0x0000c174, 0x00003590 },
+ { 0x0000c178, 0x000035ca },
+ { 0x0000c17c, 0x00003602 },
+ { 0x0000c180, 0x00003621 },
+ { 0x0000c184, 0x00003641 },
+ { 0x0000c188, 0x00003662 },
+ { 0x0000c18c, 0x00003683 },
+ { 0x0000c190, 0x000036a6 },
+ { 0x0000c194, 0x000036ca },
+ { 0x0000c198, 0x000036ef },
+ { 0x0000c19c, 0x00003715 },
+ { 0x0000c1a0, 0x0000373b },
+ { 0x0000c1a4, 0x00003763 },
+ { 0x0000c1a8, 0x0000378c },
+ { 0x0000c1ac, 0x000037b6 },
+ { 0x0000c1b0, 0x000037e1 },
+ { 0x0000c1b4, 0x00003806 },
+ { 0x0000c1b8, 0x0000381d },
+ { 0x0000c1bc, 0x00003834 },
+ { 0x0000c1c0, 0x0000384b },
+ { 0x0000c1c4, 0x00003864 },
+ { 0x0000c1c8, 0x0000387c },
+ { 0x0000c1cc, 0x00003895 },
+ { 0x0000c1d0, 0x000038af },
+ { 0x0000c1d4, 0x000038c9 },
+ { 0x0000c1d8, 0x000038e4 },
+ { 0x0000c1dc, 0x00003900 },
+ { 0x0000c1e0, 0x0000391c },
+ { 0x0000c1e4, 0x00003938 },
+ { 0x0000c1e8, 0x00003955 },
+ { 0x0000c1ec, 0x00003973 },
+ { 0x0000c1f0, 0x00003991 },
+ { 0x0000c1f4, 0x000039af },
+ { 0x0000c1f8, 0x000039cf },
+ { 0x0000c1fc, 0x000039ee },
+ { 0x0000c200, 0x000024aa },
+ { 0x0000c204, 0x00002871 },
+ { 0x0000c208, 0x00002a1c },
+ { 0x0000c20c, 0x00002aff },
+ { 0x0000c210, 0x00002be3 },
+ { 0x0000c214, 0x00002c63 },
+ { 0x0000c218, 0x00002cd5 },
+ { 0x0000c21c, 0x00002d47 },
+ { 0x0000c220, 0x00002db8 },
+ { 0x0000c224, 0x00002e15 },
+ { 0x0000c228, 0x00002e4c },
+ { 0x0000c22c, 0x00002e86 },
+ { 0x0000c230, 0x00002ec4 },
+ { 0x0000c234, 0x00002f04 },
+ { 0x0000c238, 0x00002f47 },
+ { 0x0000c23c, 0x00002f8e },
+ { 0x0000c240, 0x00002fd8 },
+ { 0x0000c244, 0x00003012 },
+ { 0x0000c248, 0x0000303a },
+ { 0x0000c24c, 0x00003064 },
+ { 0x0000c250, 0x0000308f },
+ { 0x0000c254, 0x000030bc },
+ { 0x0000c258, 0x000030eb },
+ { 0x0000c25c, 0x0000311b },
+ { 0x0000c260, 0x0000314d },
+ { 0x0000c264, 0x00003180 },
+ { 0x0000c268, 0x000031b5 },
+ { 0x0000c26c, 0x000031ec },
+ { 0x0000c270, 0x00003212 },
+ { 0x0000c274, 0x0000322f },
+ { 0x0000c278, 0x0000324d },
+ { 0x0000c27c, 0x0000326c },
+ { 0x0000c280, 0x0000328c },
+ { 0x0000c284, 0x000032ad },
+ { 0x0000c288, 0x000032ce },
+ { 0x0000c28c, 0x000032f1 },
+ { 0x0000c290, 0x00003314 },
+ { 0x0000c294, 0x00003338 },
+ { 0x0000c298, 0x0000335d },
+ { 0x0000c29c, 0x00003383 },
+ { 0x0000c2a0, 0x000033aa },
+ { 0x0000c2a4, 0x000033d2 },
+ { 0x0000c2a8, 0x000033fb },
+ { 0x0000c2ac, 0x00003412 },
+ { 0x0000c2b0, 0x00003427 },
+ { 0x0000c2b4, 0x0000343d },
+ { 0x0000c2b8, 0x00003453 },
+ { 0x0000c2bc, 0x0000346a },
+ { 0x0000c2c0, 0x00003481 },
+ { 0x0000c2c4, 0x00003498 },
+ { 0x0000c2c8, 0x000034b0 },
+ { 0x0000c2cc, 0x000034c9 },
+ { 0x0000c2d0, 0x000034e2 },
+ { 0x0000c2d4, 0x000034fb },
+ { 0x0000c2d8, 0x00003515 },
+ { 0x0000c2dc, 0x00003530 },
+ { 0x0000c2e0, 0x0000354b },
+ { 0x0000c2e4, 0x00003566 },
+ { 0x0000c2e8, 0x00003582 },
+ { 0x0000c2ec, 0x0000359e },
+ { 0x0000c2f0, 0x000035bb },
+ { 0x0000c2f4, 0x000035d8 },
+ { 0x0000c2f8, 0x000035f6 },
+ { 0x0000c2fc, 0x0000360a },
+ { 0x0000c300, 0x00003619 },
+ { 0x0000c304, 0x00003629 },
+ { 0x0000c308, 0x00003639 },
+ { 0x0000c30c, 0x00003649 },
+ { 0x0000c310, 0x00003659 },
+ { 0x0000c314, 0x0000366a },
+ { 0x0000c318, 0x0000367b },
+ { 0x0000c31c, 0x0000368c },
+ { 0x0000c320, 0x0000369d },
+ { 0x0000c324, 0x000036af },
+ { 0x0000c328, 0x000036c1 },
+ { 0x0000c32c, 0x000036d3 },
+ { 0x0000c330, 0x000036e6 },
+ { 0x0000c334, 0x000036f8 },
+ { 0x0000c338, 0x0000370b },
+ { 0x0000c33c, 0x0000371e },
+ { 0x0000c340, 0x00003732 },
+ { 0x0000c344, 0x00003745 },
+ { 0x0000c348, 0x00003759 },
+ { 0x0000c34c, 0x0000376d },
+ { 0x0000c350, 0x00003782 },
+ { 0x0000c354, 0x00003797 },
+ { 0x0000c358, 0x000037ac },
+ { 0x0000c35c, 0x000037c1 },
+ { 0x0000c360, 0x000037d6 },
+ { 0x0000c364, 0x000037ec },
+ { 0x0000c368, 0x00003801 },
+ { 0x0000c36c, 0x0000380c },
+ { 0x0000c370, 0x00003817 },
+ { 0x0000c374, 0x00003823 },
+ { 0x0000c378, 0x0000382e },
+ { 0x0000c37c, 0x0000383a },
+ { 0x0000c380, 0x00003846 },
+ { 0x0000c384, 0x00003851 },
+ { 0x0000c388, 0x0000385e },
+ { 0x0000c38c, 0x0000386a },
+ { 0x0000c390, 0x00003876 },
+ { 0x0000c394, 0x00003883 },
+ { 0x0000c398, 0x0000388f },
+ { 0x0000c39c, 0x0000389c },
+ { 0x0000c3a0, 0x000038a9 },
+ { 0x0000c3a4, 0x000038b6 },
+ { 0x0000c3a8, 0x000038c3 },
+ { 0x0000c3ac, 0x000038d0 },
+ { 0x0000c3b0, 0x000038de },
+ { 0x0000c3b4, 0x000038eb },
+ { 0x0000c3b8, 0x000038f9 },
+ { 0x0000c3bc, 0x00003907 },
+ { 0x0000c3c0, 0x00003915 },
+ { 0x0000c3c4, 0x00003923 },
+ { 0x0000c3c8, 0x00003931 },
+ { 0x0000c3cc, 0x0000393f },
+ { 0x0000c3d0, 0x0000394e },
+ { 0x0000c3d4, 0x0000395c },
+ { 0x0000c3d8, 0x0000396b },
+ { 0x0000c3dc, 0x0000397a },
+ { 0x0000c3e0, 0x00003989 },
+ { 0x0000c3e4, 0x00003998 },
+ { 0x0000c3e8, 0x000039a8 },
+ { 0x0000c3ec, 0x000039b7 },
+ { 0x0000c3f0, 0x000039c7 },
+ { 0x0000c3f4, 0x000039d6 },
+ { 0x0000c3f8, 0x000039e6 },
+ { 0x0000c3fc, 0x000039f6 },
+ { 0x0000c400, 0x0000218e },
+ { 0x0000c404, 0x00002638 },
+ { 0x0000c408, 0x000027ff },
+ { 0x0000c40c, 0x000028e3 },
+ { 0x0000c410, 0x000029c7 },
+ { 0x0000c414, 0x00002a55 },
+ { 0x0000c418, 0x00002ac7 },
+ { 0x0000c41c, 0x00002b38 },
+ { 0x0000c420, 0x00002baa },
+ { 0x0000c424, 0x00002c0e },
+ { 0x0000c428, 0x00002c47 },
+ { 0x0000c42c, 0x00002c7f },
+ { 0x0000c430, 0x00002cb8 },
+ { 0x0000c434, 0x00002cf1 },
+ { 0x0000c438, 0x00002d2a },
+ { 0x0000c43c, 0x00002d63 },
+ { 0x0000c440, 0x00002d9c },
+ { 0x0000c444, 0x00002dd5 },
+ { 0x0000c448, 0x00002e07 },
+ { 0x0000c44c, 0x00002e23 },
+ { 0x0000c450, 0x00002e3f },
+ { 0x0000c454, 0x00002e5a },
+ { 0x0000c458, 0x00002e77 },
+ { 0x0000c45c, 0x00002e95 },
+ { 0x0000c460, 0x00002eb4 },
+ { 0x0000c464, 0x00002ed3 },
+ { 0x0000c468, 0x00002ef4 },
+ { 0x0000c46c, 0x00002f14 },
+ { 0x0000c470, 0x00002f36 },
+ { 0x0000c474, 0x00002f59 },
+ { 0x0000c478, 0x00002f7c },
+ { 0x0000c47c, 0x00002fa0 },
+ { 0x0000c480, 0x00002fc5 },
+ { 0x0000c484, 0x00002feb },
+ { 0x0000c488, 0x00003008 },
+ { 0x0000c48c, 0x0000301c },
+ { 0x0000c490, 0x00003030 },
+ { 0x0000c494, 0x00003044 },
+ { 0x0000c498, 0x00003059 },
+ { 0x0000c49c, 0x0000306e },
+ { 0x0000c4a0, 0x00003084 },
+ { 0x0000c4a4, 0x0000309a },
+ { 0x0000c4a8, 0x000030b1 },
+ { 0x0000c4ac, 0x000030c7 },
+ { 0x0000c4b0, 0x000030df },
+ { 0x0000c4b4, 0x000030f6 },
+ { 0x0000c4b8, 0x0000310f },
+ { 0x0000c4bc, 0x00003127 },
+ { 0x0000c4c0, 0x00003140 },
+ { 0x0000c4c4, 0x00003159 },
+ { 0x0000c4c8, 0x00003173 },
+ { 0x0000c4cc, 0x0000318d },
+ { 0x0000c4d0, 0x000031a8 },
+ { 0x0000c4d4, 0x000031c3 },
+ { 0x0000c4d8, 0x000031de },
+ { 0x0000c4dc, 0x000031fa },
+ { 0x0000c4e0, 0x0000320b },
+ { 0x0000c4e4, 0x00003219 },
+ { 0x0000c4e8, 0x00003228 },
+ { 0x0000c4ec, 0x00003237 },
+ { 0x0000c4f0, 0x00003246 },
+ { 0x0000c4f4, 0x00003255 },
+ { 0x0000c4f8, 0x00003265 },
+ { 0x0000c4fc, 0x00003274 },
+ { 0x0000c500, 0x00003284 },
+ { 0x0000c504, 0x00003294 },
+ { 0x0000c508, 0x000032a5 },
+ { 0x0000c50c, 0x000032b5 },
+ { 0x0000c510, 0x000032c6 },
+ { 0x0000c514, 0x000032d7 },
+ { 0x0000c518, 0x000032e8 },
+ { 0x0000c51c, 0x000032f9 },
+ { 0x0000c520, 0x0000330b },
+ { 0x0000c524, 0x0000331d },
+ { 0x0000c528, 0x0000332f },
+ { 0x0000c52c, 0x00003341 },
+ { 0x0000c530, 0x00003354 },
+ { 0x0000c534, 0x00003367 },
+ { 0x0000c538, 0x0000337a },
+ { 0x0000c53c, 0x0000338d },
+ { 0x0000c540, 0x000033a0 },
+ { 0x0000c544, 0x000033b4 },
+ { 0x0000c548, 0x000033c8 },
+ { 0x0000c54c, 0x000033dc },
+ { 0x0000c550, 0x000033f0 },
+ { 0x0000c554, 0x00003402 },
+ { 0x0000c558, 0x0000340d },
+ { 0x0000c55c, 0x00003417 },
+ { 0x0000c560, 0x00003422 },
+ { 0x0000c564, 0x0000342c },
+ { 0x0000c568, 0x00003437 },
+ { 0x0000c56c, 0x00003442 },
+ { 0x0000c570, 0x0000344d },
+ { 0x0000c574, 0x00003459 },
+ { 0x0000c578, 0x00003464 },
+ { 0x0000c57c, 0x0000346f },
+ { 0x0000c580, 0x0000347b },
+ { 0x0000c584, 0x00003487 },
+ { 0x0000c588, 0x00003492 },
+ { 0x0000c58c, 0x0000349e },
+ { 0x0000c590, 0x000034aa },
+ { 0x0000c594, 0x000034b6 },
+ { 0x0000c598, 0x000034c3 },
+ { 0x0000c59c, 0x000034cf },
+ { 0x0000c5a0, 0x000034dc },
+ { 0x0000c5a4, 0x000034e8 },
+ { 0x0000c5a8, 0x000034f5 },
+ { 0x0000c5ac, 0x00003502 },
+ { 0x0000c5b0, 0x0000350f },
+ { 0x0000c5b4, 0x0000351c },
+ { 0x0000c5b8, 0x00003529 },
+ { 0x0000c5bc, 0x00003536 },
+ { 0x0000c5c0, 0x00003544 },
+ { 0x0000c5c4, 0x00003551 },
+ { 0x0000c5c8, 0x0000355f },
+ { 0x0000c5cc, 0x0000356d },
+ { 0x0000c5d0, 0x0000357b },
+ { 0x0000c5d4, 0x00003589 },
+ { 0x0000c5d8, 0x00003597 },
+ { 0x0000c5dc, 0x000035a5 },
+ { 0x0000c5e0, 0x000035b4 },
+ { 0x0000c5e4, 0x000035c2 },
+ { 0x0000c5e8, 0x000035d1 },
+ { 0x0000c5ec, 0x000035e0 },
+ { 0x0000c5f0, 0x000035ef },
+ { 0x0000c5f4, 0x000035fe },
+ { 0x0000c5f8, 0x00003606 },
+ { 0x0000c5fc, 0x0000360e },
+ { 0x0000c600, 0x00003616 },
+ { 0x0000c604, 0x0000361d },
+ { 0x0000c608, 0x00003625 },
+ { 0x0000c60c, 0x0000362d },
+ { 0x0000c610, 0x00003635 },
+ { 0x0000c614, 0x0000363d },
+ { 0x0000c618, 0x00003645 },
+ { 0x0000c61c, 0x0000364d },
+ { 0x0000c620, 0x00003655 },
+ { 0x0000c624, 0x0000365e },
+ { 0x0000c628, 0x00003666 },
+ { 0x0000c62c, 0x0000366e },
+ { 0x0000c630, 0x00003677 },
+ { 0x0000c634, 0x0000367f },
+ { 0x0000c638, 0x00003688 },
+ { 0x0000c63c, 0x00003690 },
+ { 0x0000c640, 0x00003699 },
+ { 0x0000c644, 0x000036a2 },
+ { 0x0000c648, 0x000036ab },
+ { 0x0000c64c, 0x000036b4 },
+ { 0x0000c650, 0x000036bc },
+ { 0x0000c654, 0x000036c5 },
+ { 0x0000c658, 0x000036cf },
+ { 0x0000c65c, 0x000036d8 },
+ { 0x0000c660, 0x000036e1 },
+ { 0x0000c664, 0x000036ea },
+ { 0x0000c668, 0x000036f3 },
+ { 0x0000c66c, 0x000036fd },
+ { 0x0000c670, 0x00003706 },
+ { 0x0000c674, 0x00003710 },
+ { 0x0000c678, 0x00003719 },
+ { 0x0000c67c, 0x00003723 },
+ { 0x0000c680, 0x0000372d },
+ { 0x0000c684, 0x00003737 },
+ { 0x0000c688, 0x00003740 },
+ { 0x0000c68c, 0x0000374a },
+ { 0x0000c690, 0x00003754 },
+ { 0x0000c694, 0x0000375e },
+ { 0x0000c698, 0x00003768 },
+ { 0x0000c69c, 0x00003772 },
+ { 0x0000c6a0, 0x0000377d },
+ { 0x0000c6a4, 0x00003787 },
+ { 0x0000c6a8, 0x00003791 },
+ { 0x0000c6ac, 0x0000379c },
+ { 0x0000c6b0, 0x000037a6 },
+ { 0x0000c6b4, 0x000037b1 },
+ { 0x0000c6b8, 0x000037bb },
+ { 0x0000c6bc, 0x000037c6 },
+ { 0x0000c6c0, 0x000037d1 },
+ { 0x0000c6c4, 0x000037dc },
+ { 0x0000c6c8, 0x000037e7 },
+ { 0x0000c6cc, 0x000037f1 },
+ { 0x0000c6d0, 0x000037fc },
+ { 0x0000c6d4, 0x00003804 },
+ { 0x0000c6d8, 0x00003809 },
+ { 0x0000c6dc, 0x0000380f },
+ { 0x0000c6e0, 0x00003814 },
+ { 0x0000c6e4, 0x0000381a },
+ { 0x0000c6e8, 0x00003820 },
+ { 0x0000c6ec, 0x00003825 },
+ { 0x0000c6f0, 0x0000382b },
+ { 0x0000c6f4, 0x00003831 },
+ { 0x0000c6f8, 0x00003837 },
+ { 0x0000c6fc, 0x0000383d },
+ { 0x0000c700, 0x00003843 },
+ { 0x0000c704, 0x00003848 },
+ { 0x0000c708, 0x0000384e },
+ { 0x0000c70c, 0x00003854 },
+ { 0x0000c710, 0x0000385a },
+ { 0x0000c714, 0x00003861 },
+ { 0x0000c718, 0x00003867 },
+ { 0x0000c71c, 0x0000386d },
+ { 0x0000c720, 0x00003873 },
+ { 0x0000c724, 0x00003879 },
+ { 0x0000c728, 0x0000387f },
+ { 0x0000c72c, 0x00003886 },
+ { 0x0000c730, 0x0000388c },
+ { 0x0000c734, 0x00003892 },
+ { 0x0000c738, 0x00003899 },
+ { 0x0000c73c, 0x0000389f },
+ { 0x0000c740, 0x000038a5 },
+ { 0x0000c744, 0x000038ac },
+ { 0x0000c748, 0x000038b2 },
+ { 0x0000c74c, 0x000038b9 },
+ { 0x0000c750, 0x000038c0 },
+ { 0x0000c754, 0x000038c6 },
+ { 0x0000c758, 0x000038cd },
+ { 0x0000c75c, 0x000038d3 },
+ { 0x0000c760, 0x000038da },
+ { 0x0000c764, 0x000038e1 },
+ { 0x0000c768, 0x000038e8 },
+ { 0x0000c76c, 0x000038ee },
+ { 0x0000c770, 0x000038f5 },
+ { 0x0000c774, 0x000038fc },
+ { 0x0000c778, 0x00003903 },
+ { 0x0000c77c, 0x0000390a },
+ { 0x0000c780, 0x00003911 },
+ { 0x0000c784, 0x00003918 },
+ { 0x0000c788, 0x0000391f },
+ { 0x0000c78c, 0x00003926 },
+ { 0x0000c790, 0x0000392d },
+ { 0x0000c794, 0x00003934 },
+ { 0x0000c798, 0x0000393c },
+ { 0x0000c79c, 0x00003943 },
+ { 0x0000c7a0, 0x0000394a },
+ { 0x0000c7a4, 0x00003951 },
+ { 0x0000c7a8, 0x00003959 },
+ { 0x0000c7ac, 0x00003960 },
+ { 0x0000c7b0, 0x00003967 },
+ { 0x0000c7b4, 0x0000396f },
+ { 0x0000c7b8, 0x00003976 },
+ { 0x0000c7bc, 0x0000397e },
+ { 0x0000c7c0, 0x00003985 },
+ { 0x0000c7c4, 0x0000398d },
+ { 0x0000c7c8, 0x00003995 },
+ { 0x0000c7cc, 0x0000399c },
+ { 0x0000c7d0, 0x000039a4 },
+ { 0x0000c7d4, 0x000039ac },
+ { 0x0000c7d8, 0x000039b3 },
+ { 0x0000c7dc, 0x000039bb },
+ { 0x0000c7e0, 0x000039c3 },
+ { 0x0000c7e4, 0x000039cb },
+ { 0x0000c7e8, 0x000039d3 },
+ { 0x0000c7ec, 0x000039da },
+ { 0x0000c7f0, 0x000039e2 },
+ { 0x0000c7f4, 0x000039ea },
+ { 0x0000c7f8, 0x000039f2 },
+ { 0x0000c7fc, 0x000039fa },
+ { 0x0000c800, 0x00000000 },
+ { 0x0000c804, 0x0000238e },
+ { 0x0000c808, 0x0000258e },
+ { 0x0000c80c, 0x000026aa },
+ { 0x0000c810, 0x0000278e },
+ { 0x0000c814, 0x00002838 },
+ { 0x0000c818, 0x000028aa },
+ { 0x0000c81c, 0x0000291c },
+ { 0x0000c820, 0x0000298e },
+ { 0x0000c824, 0x000029ff },
+ { 0x0000c828, 0x00002a38 },
+ { 0x0000c82c, 0x00002a71 },
+ { 0x0000c830, 0x00002aaa },
+ { 0x0000c834, 0x00002ae3 },
+ { 0x0000c838, 0x00002b1c },
+ { 0x0000c83c, 0x00002b55 },
+ { 0x0000c840, 0x00002b8e },
+ { 0x0000c844, 0x00002bc7 },
+ { 0x0000c848, 0x00002bff },
+ { 0x0000c84c, 0x00002c1c },
+ { 0x0000c850, 0x00002c38 },
+ { 0x0000c854, 0x00002c55 },
+ { 0x0000c858, 0x00002c71 },
+ { 0x0000c85c, 0x00002c8e },
+ { 0x0000c860, 0x00002caa },
+ { 0x0000c864, 0x00002cc7 },
+ { 0x0000c868, 0x00002ce3 },
+ { 0x0000c86c, 0x00002cff },
+ { 0x0000c870, 0x00002d1c },
+ { 0x0000c874, 0x00002d38 },
+ { 0x0000c878, 0x00002d55 },
+ { 0x0000c87c, 0x00002d71 },
+ { 0x0000c880, 0x00002d8e },
+ { 0x0000c884, 0x00002daa },
+ { 0x0000c888, 0x00002dc7 },
+ { 0x0000c88c, 0x00002de3 },
+ { 0x0000c890, 0x00002dff },
+ { 0x0000c894, 0x00002e0e },
+ { 0x0000c898, 0x00002e1c },
+ { 0x0000c89c, 0x00002e2a },
+ { 0x0000c8a0, 0x00002e38 },
+ { 0x0000c8a4, 0x00002e47 },
+ { 0x0000c8a8, 0x00002e53 },
+ { 0x0000c8ac, 0x00002e61 },
+ { 0x0000c8b0, 0x00002e70 },
+ { 0x0000c8b4, 0x00002e7f },
+ { 0x0000c8b8, 0x00002e8e },
+ { 0x0000c8bc, 0x00002e9d },
+ { 0x0000c8c0, 0x00002eac },
+ { 0x0000c8c4, 0x00002ebc },
+ { 0x0000c8c8, 0x00002ecb },
+ { 0x0000c8cc, 0x00002edb },
+ { 0x0000c8d0, 0x00002eeb },
+ { 0x0000c8d4, 0x00002efc },
+ { 0x0000c8d8, 0x00002f0c },
+ { 0x0000c8dc, 0x00002f1d },
+ { 0x0000c8e0, 0x00002f2e },
+ { 0x0000c8e4, 0x00002f3f },
+ { 0x0000c8e8, 0x00002f50 },
+ { 0x0000c8ec, 0x00002f61 },
+ { 0x0000c8f0, 0x00002f73 },
+ { 0x0000c8f4, 0x00002f85 },
+ { 0x0000c8f8, 0x00002f97 },
+ { 0x0000c8fc, 0x00002fa9 },
+ { 0x0000c900, 0x00002fbc },
+ { 0x0000c904, 0x00002fce },
+ { 0x0000c908, 0x00002fe1 },
+ { 0x0000c90c, 0x00002ff4 },
+ { 0x0000c910, 0x00003003 },
+ { 0x0000c914, 0x0000300d },
+ { 0x0000c918, 0x00003017 },
+ { 0x0000c91c, 0x00003021 },
+ { 0x0000c920, 0x0000302b },
+ { 0x0000c924, 0x00003035 },
+ { 0x0000c928, 0x0000303f },
+ { 0x0000c92c, 0x0000304a },
+ { 0x0000c930, 0x00003054 },
+ { 0x0000c934, 0x0000305f },
+ { 0x0000c938, 0x00003069 },
+ { 0x0000c93c, 0x00003074 },
+ { 0x0000c940, 0x0000307f },
+ { 0x0000c944, 0x0000308a },
+ { 0x0000c948, 0x00003095 },
+ { 0x0000c94c, 0x000030a0 },
+ { 0x0000c950, 0x000030ab },
+ { 0x0000c954, 0x000030b6 },
+ { 0x0000c958, 0x000030c2 },
+ { 0x0000c95c, 0x000030cd },
+ { 0x0000c960, 0x000030d9 },
+ { 0x0000c964, 0x000030e5 },
+ { 0x0000c968, 0x000030f1 },
+ { 0x0000c96c, 0x000030fc },
+ { 0x0000c970, 0x00003109 },
+ { 0x0000c974, 0x00003115 },
+ { 0x0000c978, 0x00003121 },
+ { 0x0000c97c, 0x0000312d },
+ { 0x0000c980, 0x0000313a },
+ { 0x0000c984, 0x00003146 },
+ { 0x0000c988, 0x00003153 },
+ { 0x0000c98c, 0x00003160 },
+ { 0x0000c990, 0x0000316d },
+ { 0x0000c994, 0x0000317a },
+ { 0x0000c998, 0x00003187 },
+ { 0x0000c99c, 0x00003194 },
+ { 0x0000c9a0, 0x000031a1 },
+ { 0x0000c9a4, 0x000031af },
+ { 0x0000c9a8, 0x000031bc },
+ { 0x0000c9ac, 0x000031ca },
+ { 0x0000c9b0, 0x000031d8 },
+ { 0x0000c9b4, 0x000031e5 },
+ { 0x0000c9b8, 0x000031f3 },
+ { 0x0000c9bc, 0x00003200 },
+ { 0x0000c9c0, 0x00003208 },
+ { 0x0000c9c4, 0x0000320f },
+ { 0x0000c9c8, 0x00003216 },
+ { 0x0000c9cc, 0x0000321d },
+ { 0x0000c9d0, 0x00003224 },
+ { 0x0000c9d4, 0x0000322c },
+ { 0x0000c9d8, 0x00003233 },
+ { 0x0000c9dc, 0x0000323b },
+ { 0x0000c9e0, 0x00003242 },
+ { 0x0000c9e4, 0x0000324a },
+ { 0x0000c9e8, 0x00003251 },
+ { 0x0000c9ec, 0x00003259 },
+ { 0x0000c9f0, 0x00003261 },
+ { 0x0000c9f4, 0x00003268 },
+ { 0x0000c9f8, 0x00003270 },
+ { 0x0000c9fc, 0x00003278 },
+ { 0x0000ca00, 0x00003280 },
+ { 0x0000ca04, 0x00003288 },
+ { 0x0000ca08, 0x00003290 },
+ { 0x0000ca0c, 0x00003298 },
+ { 0x0000ca10, 0x000032a0 },
+ { 0x0000ca14, 0x000032a9 },
+ { 0x0000ca18, 0x000032b1 },
+ { 0x0000ca1c, 0x000032b9 },
+ { 0x0000ca20, 0x000032c2 },
+ { 0x0000ca24, 0x000032ca },
+ { 0x0000ca28, 0x000032d3 },
+ { 0x0000ca2c, 0x000032db },
+ { 0x0000ca30, 0x000032e4 },
+ { 0x0000ca34, 0x000032ec },
+ { 0x0000ca38, 0x000032f5 },
+ { 0x0000ca3c, 0x000032fe },
+ { 0x0000ca40, 0x00003307 },
+ { 0x0000ca44, 0x00003310 },
+ { 0x0000ca48, 0x00003318 },
+ { 0x0000ca4c, 0x00003321 },
+ { 0x0000ca50, 0x0000332a },
+ { 0x0000ca54, 0x00003334 },
+ { 0x0000ca58, 0x0000333d },
+ { 0x0000ca5c, 0x00003346 },
+ { 0x0000ca60, 0x0000334f },
+ { 0x0000ca64, 0x00003359 },
+ { 0x0000ca68, 0x00003362 },
+ { 0x0000ca6c, 0x0000336b },
+ { 0x0000ca70, 0x00003375 },
+ { 0x0000ca74, 0x0000337e },
+ { 0x0000ca78, 0x00003388 },
+ { 0x0000ca7c, 0x00003392 },
+ { 0x0000ca80, 0x0000339b },
+ { 0x0000ca84, 0x000033a5 },
+ { 0x0000ca88, 0x000033af },
+ { 0x0000ca8c, 0x000033b9 },
+ { 0x0000ca90, 0x000033c3 },
+ { 0x0000ca94, 0x000033cd },
+ { 0x0000ca98, 0x000033d7 },
+ { 0x0000ca9c, 0x000033e1 },
+ { 0x0000caa0, 0x000033eb },
+ { 0x0000caa4, 0x000033f5 },
+ { 0x0000caa8, 0x00003400 },
+ { 0x0000caac, 0x00003405 },
+ { 0x0000cab0, 0x0000340a },
+ { 0x0000cab4, 0x0000340f },
+ { 0x0000cab8, 0x00003414 },
+ { 0x0000cabc, 0x0000341a },
+ { 0x0000cac0, 0x0000341f },
+ { 0x0000cac4, 0x00003424 },
+ { 0x0000cac8, 0x0000342a },
+ { 0x0000cacc, 0x0000342f },
+ { 0x0000cad0, 0x00003435 },
+ { 0x0000cad4, 0x0000343a },
+ { 0x0000cad8, 0x00003440 },
+ { 0x0000cadc, 0x00003445 },
+ { 0x0000cae0, 0x0000344b },
+ { 0x0000cae4, 0x00003450 },
+ { 0x0000cae8, 0x00003456 },
+ { 0x0000caec, 0x0000345b },
+ { 0x0000caf0, 0x00003461 },
+ { 0x0000caf4, 0x00003467 },
+ { 0x0000caf8, 0x0000346d },
+ { 0x0000cafc, 0x00003472 },
+ { 0x0000cb00, 0x00003478 },
+ { 0x0000cb04, 0x0000347e },
+ { 0x0000cb08, 0x00003484 },
+ { 0x0000cb0c, 0x0000348a },
+ { 0x0000cb10, 0x0000348f },
+ { 0x0000cb14, 0x00003495 },
+ { 0x0000cb18, 0x0000349b },
+ { 0x0000cb1c, 0x000034a1 },
+ { 0x0000cb20, 0x000034a7 },
+ { 0x0000cb24, 0x000034ad },
+ { 0x0000cb28, 0x000034b3 },
+ { 0x0000cb2c, 0x000034ba },
+ { 0x0000cb30, 0x000034c0 },
+ { 0x0000cb34, 0x000034c6 },
+ { 0x0000cb38, 0x000034cc },
+ { 0x0000cb3c, 0x000034d2 },
+ { 0x0000cb40, 0x000034d8 },
+ { 0x0000cb44, 0x000034df },
+ { 0x0000cb48, 0x000034e5 },
+ { 0x0000cb4c, 0x000034eb },
+ { 0x0000cb50, 0x000034f2 },
+ { 0x0000cb54, 0x000034f8 },
+ { 0x0000cb58, 0x000034ff },
+ { 0x0000cb5c, 0x00003505 },
+ { 0x0000cb60, 0x0000350c },
+ { 0x0000cb64, 0x00003512 },
+ { 0x0000cb68, 0x00003519 },
+ { 0x0000cb6c, 0x0000351f },
+ { 0x0000cb70, 0x00003526 },
+ { 0x0000cb74, 0x0000352c },
+ { 0x0000cb78, 0x00003533 },
+ { 0x0000cb7c, 0x0000353a },
+ { 0x0000cb80, 0x00003540 },
+ { 0x0000cb84, 0x00003547 },
+ { 0x0000cb88, 0x0000354e },
+ { 0x0000cb8c, 0x00003555 },
+ { 0x0000cb90, 0x0000355c },
+ { 0x0000cb94, 0x00003563 },
+ { 0x0000cb98, 0x00003569 },
+ { 0x0000cb9c, 0x00003570 },
+ { 0x0000cba0, 0x00003577 },
+ { 0x0000cba4, 0x0000357e },
+ { 0x0000cba8, 0x00003585 },
+ { 0x0000cbac, 0x0000358c },
+ { 0x0000cbb0, 0x00003594 },
+ { 0x0000cbb4, 0x0000359b },
+ { 0x0000cbb8, 0x000035a2 },
+ { 0x0000cbbc, 0x000035a9 },
+ { 0x0000cbc0, 0x000035b0 },
+ { 0x0000cbc4, 0x000035b7 },
+ { 0x0000cbc8, 0x000035bf },
+ { 0x0000cbcc, 0x000035c6 },
+ { 0x0000cbd0, 0x000035cd },
+ { 0x0000cbd4, 0x000035d5 },
+ { 0x0000cbd8, 0x000035dc },
+ { 0x0000cbdc, 0x000035e4 },
+ { 0x0000cbe0, 0x000035eb },
+ { 0x0000cbe4, 0x000035f2 },
+ { 0x0000cbe8, 0x000035fa },
+ { 0x0000cbec, 0x00003600 },
+ { 0x0000cbf0, 0x00003604 },
+ { 0x0000cbf4, 0x00003608 },
+ { 0x0000cbf8, 0x0000360c },
+ { 0x0000cbfc, 0x00003610 },
+ { 0x0000cc00, 0x00003614 },
+ { 0x0000cc04, 0x00003617 },
+ { 0x0000cc08, 0x0000361b },
+ { 0x0000cc0c, 0x0000361f },
+ { 0x0000cc10, 0x00003623 },
+ { 0x0000cc14, 0x00003627 },
+ { 0x0000cc18, 0x0000362b },
+ { 0x0000cc1c, 0x0000362f },
+ { 0x0000cc20, 0x00003633 },
+ { 0x0000cc24, 0x00003637 },
+ { 0x0000cc28, 0x0000363b },
+ { 0x0000cc2c, 0x0000363f },
+ { 0x0000cc30, 0x00003643 },
+ { 0x0000cc34, 0x00003647 },
+ { 0x0000cc38, 0x0000364b },
+ { 0x0000cc3c, 0x0000364f },
+ { 0x0000cc40, 0x00003653 },
+ { 0x0000cc44, 0x00003657 },
+ { 0x0000cc48, 0x0000365b },
+ { 0x0000cc4c, 0x00003660 },
+ { 0x0000cc50, 0x00003664 },
+ { 0x0000cc54, 0x00003668 },
+ { 0x0000cc58, 0x0000366c },
+ { 0x0000cc5c, 0x00003670 },
+ { 0x0000cc60, 0x00003675 },
+ { 0x0000cc64, 0x00003679 },
+ { 0x0000cc68, 0x0000367d },
+ { 0x0000cc6c, 0x00003681 },
+ { 0x0000cc70, 0x00003686 },
+ { 0x0000cc74, 0x0000368a },
+ { 0x0000cc78, 0x0000368e },
+ { 0x0000cc7c, 0x00003693 },
+ { 0x0000cc80, 0x00003697 },
+ { 0x0000cc84, 0x0000369b },
+ { 0x0000cc88, 0x000036a0 },
+ { 0x0000cc8c, 0x000036a4 },
+ { 0x0000cc90, 0x000036a8 },
+ { 0x0000cc94, 0x000036ad },
+ { 0x0000cc98, 0x000036b1 },
+ { 0x0000cc9c, 0x000036b6 },
+ { 0x0000cca0, 0x000036ba },
+ { 0x0000cca4, 0x000036bf },
+ { 0x0000cca8, 0x000036c3 },
+ { 0x0000ccac, 0x000036c8 },
+ { 0x0000ccb0, 0x000036cc },
+ { 0x0000ccb4, 0x000036d1 },
+ { 0x0000ccb8, 0x000036d5 },
+ { 0x0000ccbc, 0x000036da },
+ { 0x0000ccc0, 0x000036df },
+ { 0x0000ccc4, 0x000036e3 },
+ { 0x0000ccc8, 0x000036e8 },
+ { 0x0000cccc, 0x000036ec },
+ { 0x0000ccd0, 0x000036f1 },
+ { 0x0000ccd4, 0x000036f6 },
+ { 0x0000ccd8, 0x000036fb },
+ { 0x0000ccdc, 0x000036ff },
+ { 0x0000cce0, 0x00003704 },
+ { 0x0000cce4, 0x00003709 },
+ { 0x0000cce8, 0x0000370d },
+ { 0x0000ccec, 0x00003712 },
+ { 0x0000ccf0, 0x00003717 },
+ { 0x0000ccf4, 0x0000371c },
+ { 0x0000ccf8, 0x00003721 },
+ { 0x0000ccfc, 0x00003725 },
+ { 0x0000cd00, 0x0000372a },
+ { 0x0000cd04, 0x0000372f },
+ { 0x0000cd08, 0x00003734 },
+ { 0x0000cd0c, 0x00003739 },
+ { 0x0000cd10, 0x0000373e },
+ { 0x0000cd14, 0x00003743 },
+ { 0x0000cd18, 0x00003748 },
+ { 0x0000cd1c, 0x0000374d },
+ { 0x0000cd20, 0x00003752 },
+ { 0x0000cd24, 0x00003757 },
+ { 0x0000cd28, 0x0000375c },
+ { 0x0000cd2c, 0x00003761 },
+ { 0x0000cd30, 0x00003766 },
+ { 0x0000cd34, 0x0000376b },
+ { 0x0000cd38, 0x00003770 },
+ { 0x0000cd3c, 0x00003775 },
+ { 0x0000cd40, 0x0000377a },
+ { 0x0000cd44, 0x0000377f },
+ { 0x0000cd48, 0x00003784 },
+ { 0x0000cd4c, 0x0000378a },
+ { 0x0000cd50, 0x0000378f },
+ { 0x0000cd54, 0x00003794 },
+ { 0x0000cd58, 0x00003799 },
+ { 0x0000cd5c, 0x0000379e },
+ { 0x0000cd60, 0x000037a4 },
+ { 0x0000cd64, 0x000037a9 },
+ { 0x0000cd68, 0x000037ae },
+ { 0x0000cd6c, 0x000037b3 },
+ { 0x0000cd70, 0x000037b9 },
+ { 0x0000cd74, 0x000037be },
+ { 0x0000cd78, 0x000037c3 },
+ { 0x0000cd7c, 0x000037c9 },
+ { 0x0000cd80, 0x000037ce },
+ { 0x0000cd84, 0x000037d4 },
+ { 0x0000cd88, 0x000037d9 },
+ { 0x0000cd8c, 0x000037de },
+ { 0x0000cd90, 0x000037e4 },
+ { 0x0000cd94, 0x000037e9 },
+ { 0x0000cd98, 0x000037ef },
+ { 0x0000cd9c, 0x000037f4 },
+ { 0x0000cda0, 0x000037fa },
+ { 0x0000cda4, 0x000037ff },
+ { 0x0000cda8, 0x00003802 },
+ { 0x0000cdac, 0x00003805 },
+ { 0x0000cdb0, 0x00003808 },
+ { 0x0000cdb4, 0x0000380a },
+ { 0x0000cdb8, 0x0000380d },
+ { 0x0000cdbc, 0x00003810 },
+ { 0x0000cdc0, 0x00003813 },
+ { 0x0000cdc4, 0x00003816 },
+ { 0x0000cdc8, 0x00003819 },
+ { 0x0000cdcc, 0x0000381b },
+ { 0x0000cdd0, 0x0000381e },
+ { 0x0000cdd4, 0x00003821 },
+ { 0x0000cdd8, 0x00003824 },
+ { 0x0000cddc, 0x00003827 },
+ { 0x0000cde0, 0x0000382a },
+ { 0x0000cde4, 0x0000382d },
+ { 0x0000cde8, 0x00003830 },
+ { 0x0000cdec, 0x00003832 },
+ { 0x0000cdf0, 0x00003835 },
+ { 0x0000cdf4, 0x00003838 },
+ { 0x0000cdf8, 0x0000383b },
+ { 0x0000cdfc, 0x0000383e },
+ { 0x0000ce00, 0x00003841 },
+ { 0x0000ce04, 0x00003844 },
+ { 0x0000ce08, 0x00003847 },
+ { 0x0000ce0c, 0x0000384a },
+ { 0x0000ce10, 0x0000384d },
+ { 0x0000ce14, 0x00003850 },
+ { 0x0000ce18, 0x00003853 },
+ { 0x0000ce1c, 0x00003856 },
+ { 0x0000ce20, 0x00003859 },
+ { 0x0000ce24, 0x0000385c },
+ { 0x0000ce28, 0x0000385f },
+ { 0x0000ce2c, 0x00003862 },
+ { 0x0000ce30, 0x00003865 },
+ { 0x0000ce34, 0x00003868 },
+ { 0x0000ce38, 0x0000386b },
+ { 0x0000ce3c, 0x0000386e },
+ { 0x0000ce40, 0x00003871 },
+ { 0x0000ce44, 0x00003874 },
+ { 0x0000ce48, 0x00003878 },
+ { 0x0000ce4c, 0x0000387b },
+ { 0x0000ce50, 0x0000387e },
+ { 0x0000ce54, 0x00003881 },
+ { 0x0000ce58, 0x00003884 },
+ { 0x0000ce5c, 0x00003887 },
+ { 0x0000ce60, 0x0000388a },
+ { 0x0000ce64, 0x0000388e },
+ { 0x0000ce68, 0x00003891 },
+ { 0x0000ce6c, 0x00003894 },
+ { 0x0000ce70, 0x00003897 },
+ { 0x0000ce74, 0x0000389a },
+ { 0x0000ce78, 0x0000389d },
+ { 0x0000ce7c, 0x000038a1 },
+ { 0x0000ce80, 0x000038a4 },
+ { 0x0000ce84, 0x000038a7 },
+ { 0x0000ce88, 0x000038aa },
+ { 0x0000ce8c, 0x000038ae },
+ { 0x0000ce90, 0x000038b1 },
+ { 0x0000ce94, 0x000038b4 },
+ { 0x0000ce98, 0x000038b7 },
+ { 0x0000ce9c, 0x000038bb },
+ { 0x0000cea0, 0x000038be },
+ { 0x0000cea4, 0x000038c1 },
+ { 0x0000cea8, 0x000038c4 },
+ { 0x0000ceac, 0x000038c8 },
+ { 0x0000ceb0, 0x000038cb },
+ { 0x0000ceb4, 0x000038ce },
+ { 0x0000ceb8, 0x000038d2 },
+ { 0x0000cebc, 0x000038d5 },
+ { 0x0000cec0, 0x000038d8 },
+ { 0x0000cec4, 0x000038dc },
+ { 0x0000cec8, 0x000038df },
+ { 0x0000cecc, 0x000038e3 },
+ { 0x0000ced0, 0x000038e6 },
+ { 0x0000ced4, 0x000038e9 },
+ { 0x0000ced8, 0x000038ed },
+ { 0x0000cedc, 0x000038f0 },
+ { 0x0000cee0, 0x000038f4 },
+ { 0x0000cee4, 0x000038f7 },
+ { 0x0000cee8, 0x000038fa },
+ { 0x0000ceec, 0x000038fe },
+ { 0x0000cef0, 0x00003901 },
+ { 0x0000cef4, 0x00003905 },
+ { 0x0000cef8, 0x00003908 },
+ { 0x0000cefc, 0x0000390c },
+ { 0x0000cf00, 0x0000390f },
+ { 0x0000cf04, 0x00003913 },
+ { 0x0000cf08, 0x00003916 },
+ { 0x0000cf0c, 0x0000391a },
+ { 0x0000cf10, 0x0000391d },
+ { 0x0000cf14, 0x00003921 },
+ { 0x0000cf18, 0x00003924 },
+ { 0x0000cf1c, 0x00003928 },
+ { 0x0000cf20, 0x0000392b },
+ { 0x0000cf24, 0x0000392f },
+ { 0x0000cf28, 0x00003933 },
+ { 0x0000cf2c, 0x00003936 },
+ { 0x0000cf30, 0x0000393a },
+ { 0x0000cf34, 0x0000393d },
+ { 0x0000cf38, 0x00003941 },
+ { 0x0000cf3c, 0x00003945 },
+ { 0x0000cf40, 0x00003948 },
+ { 0x0000cf44, 0x0000394c },
+ { 0x0000cf48, 0x00003950 },
+ { 0x0000cf4c, 0x00003953 },
+ { 0x0000cf50, 0x00003957 },
+ { 0x0000cf54, 0x0000395b },
+ { 0x0000cf58, 0x0000395e },
+ { 0x0000cf5c, 0x00003962 },
+ { 0x0000cf60, 0x00003966 },
+ { 0x0000cf64, 0x00003969 },
+ { 0x0000cf68, 0x0000396d },
+ { 0x0000cf6c, 0x00003971 },
+ { 0x0000cf70, 0x00003974 },
+ { 0x0000cf74, 0x00003978 },
+ { 0x0000cf78, 0x0000397c },
+ { 0x0000cf7c, 0x00003980 },
+ { 0x0000cf80, 0x00003983 },
+ { 0x0000cf84, 0x00003987 },
+ { 0x0000cf88, 0x0000398b },
+ { 0x0000cf8c, 0x0000398f },
+ { 0x0000cf90, 0x00003993 },
+ { 0x0000cf94, 0x00003996 },
+ { 0x0000cf98, 0x0000399a },
+ { 0x0000cf9c, 0x0000399e },
+ { 0x0000cfa0, 0x000039a2 },
+ { 0x0000cfa4, 0x000039a6 },
+ { 0x0000cfa8, 0x000039aa },
+ { 0x0000cfac, 0x000039ad },
+ { 0x0000cfb0, 0x000039b1 },
+ { 0x0000cfb4, 0x000039b5 },
+ { 0x0000cfb8, 0x000039b9 },
+ { 0x0000cfbc, 0x000039bd },
+ { 0x0000cfc0, 0x000039c1 },
+ { 0x0000cfc4, 0x000039c5 },
+ { 0x0000cfc8, 0x000039c9 },
+ { 0x0000cfcc, 0x000039cd },
+ { 0x0000cfd0, 0x000039d1 },
+ { 0x0000cfd4, 0x000039d5 },
+ { 0x0000cfd8, 0x000039d8 },
+ { 0x0000cfdc, 0x000039dc },
+ { 0x0000cfe0, 0x000039e0 },
+ { 0x0000cfe4, 0x000039e4 },
+ { 0x0000cfe8, 0x000039e8 },
+ { 0x0000cfec, 0x000039ec },
+ { 0x0000cff0, 0x000039f0 },
+ { 0x0000cff4, 0x000039f4 },
+ { 0x0000cff8, 0x000039f8 },
+ { 0x0000cffc, 0x000039fc },
+};
+
+struct data_unit hdr10_opipe_a1[] = {
+ { 0x0000d000, 0x00003612 },
+ { 0x0000d004, 0x00003612 },
+ { 0x0000d008, 0x0000327c },
+ { 0x0000d00c, 0x00003840 },
+ { 0x0000d010, 0x00002fb2 },
+ { 0x0000d014, 0x00003475 },
+ { 0x0000d018, 0x00003728 },
+ { 0x0000d01c, 0x0000390e },
+ { 0x0000d020, 0x00002d7f },
+ { 0x0000d024, 0x00003134 },
+ { 0x0000d028, 0x00003397 },
+ { 0x0000d02c, 0x0000353d },
+ { 0x0000d030, 0x00003695 },
+ { 0x0000d034, 0x000037cb },
+ { 0x0000d038, 0x000038a2 },
+ { 0x0000d03c, 0x00003982 },
+ { 0x0000d040, 0x00002b71 },
+ { 0x0000d044, 0x00002ea4 },
+ { 0x0000d048, 0x00003079 },
+ { 0x0000d04c, 0x00003204 },
+ { 0x0000d050, 0x00003302 },
+ { 0x0000d054, 0x0000341c },
+ { 0x0000d058, 0x000034d5 },
+ { 0x0000d05c, 0x000035ad },
+ { 0x0000d060, 0x00003651 },
+ { 0x0000d064, 0x000036dc },
+ { 0x0000d068, 0x00003778 },
+ { 0x0000d06c, 0x00003811 },
+ { 0x0000d070, 0x00003870 },
+ { 0x0000d074, 0x000038d7 },
+ { 0x0000d078, 0x00003946 },
+ { 0x0000d07c, 0x000039bf },
+ { 0x0000d080, 0x00002955 },
+ { 0x0000d084, 0x00002c9c },
+ { 0x0000d088, 0x00002e31 },
+ { 0x0000d08c, 0x00002f25 },
+ { 0x0000d090, 0x00003026 },
+ { 0x0000d094, 0x000030d3 },
+ { 0x0000d098, 0x0000319b },
+ { 0x0000d09c, 0x0000323e },
+ { 0x0000d0a0, 0x000032bd },
+ { 0x0000d0a4, 0x0000334b },
+ { 0x0000d0a8, 0x000033e6 },
+ { 0x0000d0ac, 0x00003448 },
+ { 0x0000d0b0, 0x000034a4 },
+ { 0x0000d0b4, 0x00003508 },
+ { 0x0000d0b8, 0x00003574 },
+ { 0x0000d0bc, 0x000035e7 },
+ { 0x0000d0c0, 0x00003631 },
+ { 0x0000d0c4, 0x00003672 },
+ { 0x0000d0c8, 0x000036b8 },
+ { 0x0000d0cc, 0x00003702 },
+ { 0x0000d0d0, 0x0000374f },
+ { 0x0000d0d4, 0x000037a1 },
+ { 0x0000d0d8, 0x000037f7 },
+ { 0x0000d0dc, 0x00003828 },
+ { 0x0000d0e0, 0x00003857 },
+ { 0x0000d0e4, 0x00003889 },
+ { 0x0000d0e8, 0x000038bc },
+ { 0x0000d0ec, 0x000038f2 },
+ { 0x0000d0f0, 0x0000392a },
+ { 0x0000d0f4, 0x00003964 },
+ { 0x0000d0f8, 0x000039a0 },
+ { 0x0000d0fc, 0x000039de },
+ { 0x0000d100, 0x0000271c },
+ { 0x0000d104, 0x00002a8e },
+ { 0x0000d108, 0x00002c2a },
+ { 0x0000d10c, 0x00002d0e },
+ { 0x0000d110, 0x00002df1 },
+ { 0x0000d114, 0x00002e69 },
+ { 0x0000d118, 0x00002ee3 },
+ { 0x0000d11c, 0x00002f6a },
+ { 0x0000d120, 0x00002ffe },
+ { 0x0000d124, 0x0000304f },
+ { 0x0000d128, 0x000030a5 },
+ { 0x0000d12c, 0x00003102 },
+ { 0x0000d130, 0x00003166 },
+ { 0x0000d134, 0x000031d1 },
+ { 0x0000d138, 0x00003221 },
+ { 0x0000d13c, 0x0000325d },
+ { 0x0000d140, 0x0000329c },
+ { 0x0000d144, 0x000032df },
+ { 0x0000d148, 0x00003326 },
+ { 0x0000d14c, 0x00003370 },
+ { 0x0000d150, 0x000033be },
+ { 0x0000d154, 0x00003407 },
+ { 0x0000d158, 0x00003432 },
+ { 0x0000d15c, 0x0000345e },
+ { 0x0000d160, 0x0000348c },
+ { 0x0000d164, 0x000034bd },
+ { 0x0000d168, 0x000034ef },
+ { 0x0000d16c, 0x00003522 },
+ { 0x0000d170, 0x00003558 },
+ { 0x0000d174, 0x00003590 },
+ { 0x0000d178, 0x000035ca },
+ { 0x0000d17c, 0x00003602 },
+ { 0x0000d180, 0x00003621 },
+ { 0x0000d184, 0x00003641 },
+ { 0x0000d188, 0x00003662 },
+ { 0x0000d18c, 0x00003683 },
+ { 0x0000d190, 0x000036a6 },
+ { 0x0000d194, 0x000036ca },
+ { 0x0000d198, 0x000036ef },
+ { 0x0000d19c, 0x00003715 },
+ { 0x0000d1a0, 0x0000373b },
+ { 0x0000d1a4, 0x00003763 },
+ { 0x0000d1a8, 0x0000378c },
+ { 0x0000d1ac, 0x000037b6 },
+ { 0x0000d1b0, 0x000037e1 },
+ { 0x0000d1b4, 0x00003806 },
+ { 0x0000d1b8, 0x0000381d },
+ { 0x0000d1bc, 0x00003834 },
+ { 0x0000d1c0, 0x0000384b },
+ { 0x0000d1c4, 0x00003864 },
+ { 0x0000d1c8, 0x0000387c },
+ { 0x0000d1cc, 0x00003895 },
+ { 0x0000d1d0, 0x000038af },
+ { 0x0000d1d4, 0x000038c9 },
+ { 0x0000d1d8, 0x000038e4 },
+ { 0x0000d1dc, 0x00003900 },
+ { 0x0000d1e0, 0x0000391c },
+ { 0x0000d1e4, 0x00003938 },
+ { 0x0000d1e8, 0x00003955 },
+ { 0x0000d1ec, 0x00003973 },
+ { 0x0000d1f0, 0x00003991 },
+ { 0x0000d1f4, 0x000039af },
+ { 0x0000d1f8, 0x000039cf },
+ { 0x0000d1fc, 0x000039ee },
+ { 0x0000d200, 0x000024aa },
+ { 0x0000d204, 0x00002871 },
+ { 0x0000d208, 0x00002a1c },
+ { 0x0000d20c, 0x00002aff },
+ { 0x0000d210, 0x00002be3 },
+ { 0x0000d214, 0x00002c63 },
+ { 0x0000d218, 0x00002cd5 },
+ { 0x0000d21c, 0x00002d47 },
+ { 0x0000d220, 0x00002db8 },
+ { 0x0000d224, 0x00002e15 },
+ { 0x0000d228, 0x00002e4c },
+ { 0x0000d22c, 0x00002e86 },
+ { 0x0000d230, 0x00002ec4 },
+ { 0x0000d234, 0x00002f04 },
+ { 0x0000d238, 0x00002f47 },
+ { 0x0000d23c, 0x00002f8e },
+ { 0x0000d240, 0x00002fd8 },
+ { 0x0000d244, 0x00003012 },
+ { 0x0000d248, 0x0000303a },
+ { 0x0000d24c, 0x00003064 },
+ { 0x0000d250, 0x0000308f },
+ { 0x0000d254, 0x000030bc },
+ { 0x0000d258, 0x000030eb },
+ { 0x0000d25c, 0x0000311b },
+ { 0x0000d260, 0x0000314d },
+ { 0x0000d264, 0x00003180 },
+ { 0x0000d268, 0x000031b5 },
+ { 0x0000d26c, 0x000031ec },
+ { 0x0000d270, 0x00003212 },
+ { 0x0000d274, 0x0000322f },
+ { 0x0000d278, 0x0000324d },
+ { 0x0000d27c, 0x0000326c },
+ { 0x0000d280, 0x0000328c },
+ { 0x0000d284, 0x000032ad },
+ { 0x0000d288, 0x000032ce },
+ { 0x0000d28c, 0x000032f1 },
+ { 0x0000d290, 0x00003314 },
+ { 0x0000d294, 0x00003338 },
+ { 0x0000d298, 0x0000335d },
+ { 0x0000d29c, 0x00003383 },
+ { 0x0000d2a0, 0x000033aa },
+ { 0x0000d2a4, 0x000033d2 },
+ { 0x0000d2a8, 0x000033fb },
+ { 0x0000d2ac, 0x00003412 },
+ { 0x0000d2b0, 0x00003427 },
+ { 0x0000d2b4, 0x0000343d },
+ { 0x0000d2b8, 0x00003453 },
+ { 0x0000d2bc, 0x0000346a },
+ { 0x0000d2c0, 0x00003481 },
+ { 0x0000d2c4, 0x00003498 },
+ { 0x0000d2c8, 0x000034b0 },
+ { 0x0000d2cc, 0x000034c9 },
+ { 0x0000d2d0, 0x000034e2 },
+ { 0x0000d2d4, 0x000034fb },
+ { 0x0000d2d8, 0x00003515 },
+ { 0x0000d2dc, 0x00003530 },
+ { 0x0000d2e0, 0x0000354b },
+ { 0x0000d2e4, 0x00003566 },
+ { 0x0000d2e8, 0x00003582 },
+ { 0x0000d2ec, 0x0000359e },
+ { 0x0000d2f0, 0x000035bb },
+ { 0x0000d2f4, 0x000035d8 },
+ { 0x0000d2f8, 0x000035f6 },
+ { 0x0000d2fc, 0x0000360a },
+ { 0x0000d300, 0x00003619 },
+ { 0x0000d304, 0x00003629 },
+ { 0x0000d308, 0x00003639 },
+ { 0x0000d30c, 0x00003649 },
+ { 0x0000d310, 0x00003659 },
+ { 0x0000d314, 0x0000366a },
+ { 0x0000d318, 0x0000367b },
+ { 0x0000d31c, 0x0000368c },
+ { 0x0000d320, 0x0000369d },
+ { 0x0000d324, 0x000036af },
+ { 0x0000d328, 0x000036c1 },
+ { 0x0000d32c, 0x000036d3 },
+ { 0x0000d330, 0x000036e6 },
+ { 0x0000d334, 0x000036f8 },
+ { 0x0000d338, 0x0000370b },
+ { 0x0000d33c, 0x0000371e },
+ { 0x0000d340, 0x00003732 },
+ { 0x0000d344, 0x00003745 },
+ { 0x0000d348, 0x00003759 },
+ { 0x0000d34c, 0x0000376d },
+ { 0x0000d350, 0x00003782 },
+ { 0x0000d354, 0x00003797 },
+ { 0x0000d358, 0x000037ac },
+ { 0x0000d35c, 0x000037c1 },
+ { 0x0000d360, 0x000037d6 },
+ { 0x0000d364, 0x000037ec },
+ { 0x0000d368, 0x00003801 },
+ { 0x0000d36c, 0x0000380c },
+ { 0x0000d370, 0x00003817 },
+ { 0x0000d374, 0x00003823 },
+ { 0x0000d378, 0x0000382e },
+ { 0x0000d37c, 0x0000383a },
+ { 0x0000d380, 0x00003846 },
+ { 0x0000d384, 0x00003851 },
+ { 0x0000d388, 0x0000385e },
+ { 0x0000d38c, 0x0000386a },
+ { 0x0000d390, 0x00003876 },
+ { 0x0000d394, 0x00003883 },
+ { 0x0000d398, 0x0000388f },
+ { 0x0000d39c, 0x0000389c },
+ { 0x0000d3a0, 0x000038a9 },
+ { 0x0000d3a4, 0x000038b6 },
+ { 0x0000d3a8, 0x000038c3 },
+ { 0x0000d3ac, 0x000038d0 },
+ { 0x0000d3b0, 0x000038de },
+ { 0x0000d3b4, 0x000038eb },
+ { 0x0000d3b8, 0x000038f9 },
+ { 0x0000d3bc, 0x00003907 },
+ { 0x0000d3c0, 0x00003915 },
+ { 0x0000d3c4, 0x00003923 },
+ { 0x0000d3c8, 0x00003931 },
+ { 0x0000d3cc, 0x0000393f },
+ { 0x0000d3d0, 0x0000394e },
+ { 0x0000d3d4, 0x0000395c },
+ { 0x0000d3d8, 0x0000396b },
+ { 0x0000d3dc, 0x0000397a },
+ { 0x0000d3e0, 0x00003989 },
+ { 0x0000d3e4, 0x00003998 },
+ { 0x0000d3e8, 0x000039a8 },
+ { 0x0000d3ec, 0x000039b7 },
+ { 0x0000d3f0, 0x000039c7 },
+ { 0x0000d3f4, 0x000039d6 },
+ { 0x0000d3f8, 0x000039e6 },
+ { 0x0000d3fc, 0x000039f6 },
+ { 0x0000d400, 0x0000218e },
+ { 0x0000d404, 0x00002638 },
+ { 0x0000d408, 0x000027ff },
+ { 0x0000d40c, 0x000028e3 },
+ { 0x0000d410, 0x000029c7 },
+ { 0x0000d414, 0x00002a55 },
+ { 0x0000d418, 0x00002ac7 },
+ { 0x0000d41c, 0x00002b38 },
+ { 0x0000d420, 0x00002baa },
+ { 0x0000d424, 0x00002c0e },
+ { 0x0000d428, 0x00002c47 },
+ { 0x0000d42c, 0x00002c7f },
+ { 0x0000d430, 0x00002cb8 },
+ { 0x0000d434, 0x00002cf1 },
+ { 0x0000d438, 0x00002d2a },
+ { 0x0000d43c, 0x00002d63 },
+ { 0x0000d440, 0x00002d9c },
+ { 0x0000d444, 0x00002dd5 },
+ { 0x0000d448, 0x00002e07 },
+ { 0x0000d44c, 0x00002e23 },
+ { 0x0000d450, 0x00002e3f },
+ { 0x0000d454, 0x00002e5a },
+ { 0x0000d458, 0x00002e77 },
+ { 0x0000d45c, 0x00002e95 },
+ { 0x0000d460, 0x00002eb4 },
+ { 0x0000d464, 0x00002ed3 },
+ { 0x0000d468, 0x00002ef4 },
+ { 0x0000d46c, 0x00002f14 },
+ { 0x0000d470, 0x00002f36 },
+ { 0x0000d474, 0x00002f59 },
+ { 0x0000d478, 0x00002f7c },
+ { 0x0000d47c, 0x00002fa0 },
+ { 0x0000d480, 0x00002fc5 },
+ { 0x0000d484, 0x00002feb },
+ { 0x0000d488, 0x00003008 },
+ { 0x0000d48c, 0x0000301c },
+ { 0x0000d490, 0x00003030 },
+ { 0x0000d494, 0x00003044 },
+ { 0x0000d498, 0x00003059 },
+ { 0x0000d49c, 0x0000306e },
+ { 0x0000d4a0, 0x00003084 },
+ { 0x0000d4a4, 0x0000309a },
+ { 0x0000d4a8, 0x000030b1 },
+ { 0x0000d4ac, 0x000030c7 },
+ { 0x0000d4b0, 0x000030df },
+ { 0x0000d4b4, 0x000030f6 },
+ { 0x0000d4b8, 0x0000310f },
+ { 0x0000d4bc, 0x00003127 },
+ { 0x0000d4c0, 0x00003140 },
+ { 0x0000d4c4, 0x00003159 },
+ { 0x0000d4c8, 0x00003173 },
+ { 0x0000d4cc, 0x0000318d },
+ { 0x0000d4d0, 0x000031a8 },
+ { 0x0000d4d4, 0x000031c3 },
+ { 0x0000d4d8, 0x000031de },
+ { 0x0000d4dc, 0x000031fa },
+ { 0x0000d4e0, 0x0000320b },
+ { 0x0000d4e4, 0x00003219 },
+ { 0x0000d4e8, 0x00003228 },
+ { 0x0000d4ec, 0x00003237 },
+ { 0x0000d4f0, 0x00003246 },
+ { 0x0000d4f4, 0x00003255 },
+ { 0x0000d4f8, 0x00003265 },
+ { 0x0000d4fc, 0x00003274 },
+ { 0x0000d500, 0x00003284 },
+ { 0x0000d504, 0x00003294 },
+ { 0x0000d508, 0x000032a5 },
+ { 0x0000d50c, 0x000032b5 },
+ { 0x0000d510, 0x000032c6 },
+ { 0x0000d514, 0x000032d7 },
+ { 0x0000d518, 0x000032e8 },
+ { 0x0000d51c, 0x000032f9 },
+ { 0x0000d520, 0x0000330b },
+ { 0x0000d524, 0x0000331d },
+ { 0x0000d528, 0x0000332f },
+ { 0x0000d52c, 0x00003341 },
+ { 0x0000d530, 0x00003354 },
+ { 0x0000d534, 0x00003367 },
+ { 0x0000d538, 0x0000337a },
+ { 0x0000d53c, 0x0000338d },
+ { 0x0000d540, 0x000033a0 },
+ { 0x0000d544, 0x000033b4 },
+ { 0x0000d548, 0x000033c8 },
+ { 0x0000d54c, 0x000033dc },
+ { 0x0000d550, 0x000033f0 },
+ { 0x0000d554, 0x00003402 },
+ { 0x0000d558, 0x0000340d },
+ { 0x0000d55c, 0x00003417 },
+ { 0x0000d560, 0x00003422 },
+ { 0x0000d564, 0x0000342c },
+ { 0x0000d568, 0x00003437 },
+ { 0x0000d56c, 0x00003442 },
+ { 0x0000d570, 0x0000344d },
+ { 0x0000d574, 0x00003459 },
+ { 0x0000d578, 0x00003464 },
+ { 0x0000d57c, 0x0000346f },
+ { 0x0000d580, 0x0000347b },
+ { 0x0000d584, 0x00003487 },
+ { 0x0000d588, 0x00003492 },
+ { 0x0000d58c, 0x0000349e },
+ { 0x0000d590, 0x000034aa },
+ { 0x0000d594, 0x000034b6 },
+ { 0x0000d598, 0x000034c3 },
+ { 0x0000d59c, 0x000034cf },
+ { 0x0000d5a0, 0x000034dc },
+ { 0x0000d5a4, 0x000034e8 },
+ { 0x0000d5a8, 0x000034f5 },
+ { 0x0000d5ac, 0x00003502 },
+ { 0x0000d5b0, 0x0000350f },
+ { 0x0000d5b4, 0x0000351c },
+ { 0x0000d5b8, 0x00003529 },
+ { 0x0000d5bc, 0x00003536 },
+ { 0x0000d5c0, 0x00003544 },
+ { 0x0000d5c4, 0x00003551 },
+ { 0x0000d5c8, 0x0000355f },
+ { 0x0000d5cc, 0x0000356d },
+ { 0x0000d5d0, 0x0000357b },
+ { 0x0000d5d4, 0x00003589 },
+ { 0x0000d5d8, 0x00003597 },
+ { 0x0000d5dc, 0x000035a5 },
+ { 0x0000d5e0, 0x000035b4 },
+ { 0x0000d5e4, 0x000035c2 },
+ { 0x0000d5e8, 0x000035d1 },
+ { 0x0000d5ec, 0x000035e0 },
+ { 0x0000d5f0, 0x000035ef },
+ { 0x0000d5f4, 0x000035fe },
+ { 0x0000d5f8, 0x00003606 },
+ { 0x0000d5fc, 0x0000360e },
+ { 0x0000d600, 0x00003616 },
+ { 0x0000d604, 0x0000361d },
+ { 0x0000d608, 0x00003625 },
+ { 0x0000d60c, 0x0000362d },
+ { 0x0000d610, 0x00003635 },
+ { 0x0000d614, 0x0000363d },
+ { 0x0000d618, 0x00003645 },
+ { 0x0000d61c, 0x0000364d },
+ { 0x0000d620, 0x00003655 },
+ { 0x0000d624, 0x0000365e },
+ { 0x0000d628, 0x00003666 },
+ { 0x0000d62c, 0x0000366e },
+ { 0x0000d630, 0x00003677 },
+ { 0x0000d634, 0x0000367f },
+ { 0x0000d638, 0x00003688 },
+ { 0x0000d63c, 0x00003690 },
+ { 0x0000d640, 0x00003699 },
+ { 0x0000d644, 0x000036a2 },
+ { 0x0000d648, 0x000036ab },
+ { 0x0000d64c, 0x000036b4 },
+ { 0x0000d650, 0x000036bc },
+ { 0x0000d654, 0x000036c5 },
+ { 0x0000d658, 0x000036cf },
+ { 0x0000d65c, 0x000036d8 },
+ { 0x0000d660, 0x000036e1 },
+ { 0x0000d664, 0x000036ea },
+ { 0x0000d668, 0x000036f3 },
+ { 0x0000d66c, 0x000036fd },
+ { 0x0000d670, 0x00003706 },
+ { 0x0000d674, 0x00003710 },
+ { 0x0000d678, 0x00003719 },
+ { 0x0000d67c, 0x00003723 },
+ { 0x0000d680, 0x0000372d },
+ { 0x0000d684, 0x00003737 },
+ { 0x0000d688, 0x00003740 },
+ { 0x0000d68c, 0x0000374a },
+ { 0x0000d690, 0x00003754 },
+ { 0x0000d694, 0x0000375e },
+ { 0x0000d698, 0x00003768 },
+ { 0x0000d69c, 0x00003772 },
+ { 0x0000d6a0, 0x0000377d },
+ { 0x0000d6a4, 0x00003787 },
+ { 0x0000d6a8, 0x00003791 },
+ { 0x0000d6ac, 0x0000379c },
+ { 0x0000d6b0, 0x000037a6 },
+ { 0x0000d6b4, 0x000037b1 },
+ { 0x0000d6b8, 0x000037bb },
+ { 0x0000d6bc, 0x000037c6 },
+ { 0x0000d6c0, 0x000037d1 },
+ { 0x0000d6c4, 0x000037dc },
+ { 0x0000d6c8, 0x000037e7 },
+ { 0x0000d6cc, 0x000037f1 },
+ { 0x0000d6d0, 0x000037fc },
+ { 0x0000d6d4, 0x00003804 },
+ { 0x0000d6d8, 0x00003809 },
+ { 0x0000d6dc, 0x0000380f },
+ { 0x0000d6e0, 0x00003814 },
+ { 0x0000d6e4, 0x0000381a },
+ { 0x0000d6e8, 0x00003820 },
+ { 0x0000d6ec, 0x00003825 },
+ { 0x0000d6f0, 0x0000382b },
+ { 0x0000d6f4, 0x00003831 },
+ { 0x0000d6f8, 0x00003837 },
+ { 0x0000d6fc, 0x0000383d },
+ { 0x0000d700, 0x00003843 },
+ { 0x0000d704, 0x00003848 },
+ { 0x0000d708, 0x0000384e },
+ { 0x0000d70c, 0x00003854 },
+ { 0x0000d710, 0x0000385a },
+ { 0x0000d714, 0x00003861 },
+ { 0x0000d718, 0x00003867 },
+ { 0x0000d71c, 0x0000386d },
+ { 0x0000d720, 0x00003873 },
+ { 0x0000d724, 0x00003879 },
+ { 0x0000d728, 0x0000387f },
+ { 0x0000d72c, 0x00003886 },
+ { 0x0000d730, 0x0000388c },
+ { 0x0000d734, 0x00003892 },
+ { 0x0000d738, 0x00003899 },
+ { 0x0000d73c, 0x0000389f },
+ { 0x0000d740, 0x000038a5 },
+ { 0x0000d744, 0x000038ac },
+ { 0x0000d748, 0x000038b2 },
+ { 0x0000d74c, 0x000038b9 },
+ { 0x0000d750, 0x000038c0 },
+ { 0x0000d754, 0x000038c6 },
+ { 0x0000d758, 0x000038cd },
+ { 0x0000d75c, 0x000038d3 },
+ { 0x0000d760, 0x000038da },
+ { 0x0000d764, 0x000038e1 },
+ { 0x0000d768, 0x000038e8 },
+ { 0x0000d76c, 0x000038ee },
+ { 0x0000d770, 0x000038f5 },
+ { 0x0000d774, 0x000038fc },
+ { 0x0000d778, 0x00003903 },
+ { 0x0000d77c, 0x0000390a },
+ { 0x0000d780, 0x00003911 },
+ { 0x0000d784, 0x00003918 },
+ { 0x0000d788, 0x0000391f },
+ { 0x0000d78c, 0x00003926 },
+ { 0x0000d790, 0x0000392d },
+ { 0x0000d794, 0x00003934 },
+ { 0x0000d798, 0x0000393c },
+ { 0x0000d79c, 0x00003943 },
+ { 0x0000d7a0, 0x0000394a },
+ { 0x0000d7a4, 0x00003951 },
+ { 0x0000d7a8, 0x00003959 },
+ { 0x0000d7ac, 0x00003960 },
+ { 0x0000d7b0, 0x00003967 },
+ { 0x0000d7b4, 0x0000396f },
+ { 0x0000d7b8, 0x00003976 },
+ { 0x0000d7bc, 0x0000397e },
+ { 0x0000d7c0, 0x00003985 },
+ { 0x0000d7c4, 0x0000398d },
+ { 0x0000d7c8, 0x00003995 },
+ { 0x0000d7cc, 0x0000399c },
+ { 0x0000d7d0, 0x000039a4 },
+ { 0x0000d7d4, 0x000039ac },
+ { 0x0000d7d8, 0x000039b3 },
+ { 0x0000d7dc, 0x000039bb },
+ { 0x0000d7e0, 0x000039c3 },
+ { 0x0000d7e4, 0x000039cb },
+ { 0x0000d7e8, 0x000039d3 },
+ { 0x0000d7ec, 0x000039da },
+ { 0x0000d7f0, 0x000039e2 },
+ { 0x0000d7f4, 0x000039ea },
+ { 0x0000d7f8, 0x000039f2 },
+ { 0x0000d7fc, 0x000039fa },
+ { 0x0000d800, 0x00000000 },
+ { 0x0000d804, 0x0000238e },
+ { 0x0000d808, 0x0000258e },
+ { 0x0000d80c, 0x000026aa },
+ { 0x0000d810, 0x0000278e },
+ { 0x0000d814, 0x00002838 },
+ { 0x0000d818, 0x000028aa },
+ { 0x0000d81c, 0x0000291c },
+ { 0x0000d820, 0x0000298e },
+ { 0x0000d824, 0x000029ff },
+ { 0x0000d828, 0x00002a38 },
+ { 0x0000d82c, 0x00002a71 },
+ { 0x0000d830, 0x00002aaa },
+ { 0x0000d834, 0x00002ae3 },
+ { 0x0000d838, 0x00002b1c },
+ { 0x0000d83c, 0x00002b55 },
+ { 0x0000d840, 0x00002b8e },
+ { 0x0000d844, 0x00002bc7 },
+ { 0x0000d848, 0x00002bff },
+ { 0x0000d84c, 0x00002c1c },
+ { 0x0000d850, 0x00002c38 },
+ { 0x0000d854, 0x00002c55 },
+ { 0x0000d858, 0x00002c71 },
+ { 0x0000d85c, 0x00002c8e },
+ { 0x0000d860, 0x00002caa },
+ { 0x0000d864, 0x00002cc7 },
+ { 0x0000d868, 0x00002ce3 },
+ { 0x0000d86c, 0x00002cff },
+ { 0x0000d870, 0x00002d1c },
+ { 0x0000d874, 0x00002d38 },
+ { 0x0000d878, 0x00002d55 },
+ { 0x0000d87c, 0x00002d71 },
+ { 0x0000d880, 0x00002d8e },
+ { 0x0000d884, 0x00002daa },
+ { 0x0000d888, 0x00002dc7 },
+ { 0x0000d88c, 0x00002de3 },
+ { 0x0000d890, 0x00002dff },
+ { 0x0000d894, 0x00002e0e },
+ { 0x0000d898, 0x00002e1c },
+ { 0x0000d89c, 0x00002e2a },
+ { 0x0000d8a0, 0x00002e38 },
+ { 0x0000d8a4, 0x00002e47 },
+ { 0x0000d8a8, 0x00002e53 },
+ { 0x0000d8ac, 0x00002e61 },
+ { 0x0000d8b0, 0x00002e70 },
+ { 0x0000d8b4, 0x00002e7f },
+ { 0x0000d8b8, 0x00002e8e },
+ { 0x0000d8bc, 0x00002e9d },
+ { 0x0000d8c0, 0x00002eac },
+ { 0x0000d8c4, 0x00002ebc },
+ { 0x0000d8c8, 0x00002ecb },
+ { 0x0000d8cc, 0x00002edb },
+ { 0x0000d8d0, 0x00002eeb },
+ { 0x0000d8d4, 0x00002efc },
+ { 0x0000d8d8, 0x00002f0c },
+ { 0x0000d8dc, 0x00002f1d },
+ { 0x0000d8e0, 0x00002f2e },
+ { 0x0000d8e4, 0x00002f3f },
+ { 0x0000d8e8, 0x00002f50 },
+ { 0x0000d8ec, 0x00002f61 },
+ { 0x0000d8f0, 0x00002f73 },
+ { 0x0000d8f4, 0x00002f85 },
+ { 0x0000d8f8, 0x00002f97 },
+ { 0x0000d8fc, 0x00002fa9 },
+ { 0x0000d900, 0x00002fbc },
+ { 0x0000d904, 0x00002fce },
+ { 0x0000d908, 0x00002fe1 },
+ { 0x0000d90c, 0x00002ff4 },
+ { 0x0000d910, 0x00003003 },
+ { 0x0000d914, 0x0000300d },
+ { 0x0000d918, 0x00003017 },
+ { 0x0000d91c, 0x00003021 },
+ { 0x0000d920, 0x0000302b },
+ { 0x0000d924, 0x00003035 },
+ { 0x0000d928, 0x0000303f },
+ { 0x0000d92c, 0x0000304a },
+ { 0x0000d930, 0x00003054 },
+ { 0x0000d934, 0x0000305f },
+ { 0x0000d938, 0x00003069 },
+ { 0x0000d93c, 0x00003074 },
+ { 0x0000d940, 0x0000307f },
+ { 0x0000d944, 0x0000308a },
+ { 0x0000d948, 0x00003095 },
+ { 0x0000d94c, 0x000030a0 },
+ { 0x0000d950, 0x000030ab },
+ { 0x0000d954, 0x000030b6 },
+ { 0x0000d958, 0x000030c2 },
+ { 0x0000d95c, 0x000030cd },
+ { 0x0000d960, 0x000030d9 },
+ { 0x0000d964, 0x000030e5 },
+ { 0x0000d968, 0x000030f1 },
+ { 0x0000d96c, 0x000030fc },
+ { 0x0000d970, 0x00003109 },
+ { 0x0000d974, 0x00003115 },
+ { 0x0000d978, 0x00003121 },
+ { 0x0000d97c, 0x0000312d },
+ { 0x0000d980, 0x0000313a },
+ { 0x0000d984, 0x00003146 },
+ { 0x0000d988, 0x00003153 },
+ { 0x0000d98c, 0x00003160 },
+ { 0x0000d990, 0x0000316d },
+ { 0x0000d994, 0x0000317a },
+ { 0x0000d998, 0x00003187 },
+ { 0x0000d99c, 0x00003194 },
+ { 0x0000d9a0, 0x000031a1 },
+ { 0x0000d9a4, 0x000031af },
+ { 0x0000d9a8, 0x000031bc },
+ { 0x0000d9ac, 0x000031ca },
+ { 0x0000d9b0, 0x000031d8 },
+ { 0x0000d9b4, 0x000031e5 },
+ { 0x0000d9b8, 0x000031f3 },
+ { 0x0000d9bc, 0x00003200 },
+ { 0x0000d9c0, 0x00003208 },
+ { 0x0000d9c4, 0x0000320f },
+ { 0x0000d9c8, 0x00003216 },
+ { 0x0000d9cc, 0x0000321d },
+ { 0x0000d9d0, 0x00003224 },
+ { 0x0000d9d4, 0x0000322c },
+ { 0x0000d9d8, 0x00003233 },
+ { 0x0000d9dc, 0x0000323b },
+ { 0x0000d9e0, 0x00003242 },
+ { 0x0000d9e4, 0x0000324a },
+ { 0x0000d9e8, 0x00003251 },
+ { 0x0000d9ec, 0x00003259 },
+ { 0x0000d9f0, 0x00003261 },
+ { 0x0000d9f4, 0x00003268 },
+ { 0x0000d9f8, 0x00003270 },
+ { 0x0000d9fc, 0x00003278 },
+ { 0x0000da00, 0x00003280 },
+ { 0x0000da04, 0x00003288 },
+ { 0x0000da08, 0x00003290 },
+ { 0x0000da0c, 0x00003298 },
+ { 0x0000da10, 0x000032a0 },
+ { 0x0000da14, 0x000032a9 },
+ { 0x0000da18, 0x000032b1 },
+ { 0x0000da1c, 0x000032b9 },
+ { 0x0000da20, 0x000032c2 },
+ { 0x0000da24, 0x000032ca },
+ { 0x0000da28, 0x000032d3 },
+ { 0x0000da2c, 0x000032db },
+ { 0x0000da30, 0x000032e4 },
+ { 0x0000da34, 0x000032ec },
+ { 0x0000da38, 0x000032f5 },
+ { 0x0000da3c, 0x000032fe },
+ { 0x0000da40, 0x00003307 },
+ { 0x0000da44, 0x00003310 },
+ { 0x0000da48, 0x00003318 },
+ { 0x0000da4c, 0x00003321 },
+ { 0x0000da50, 0x0000332a },
+ { 0x0000da54, 0x00003334 },
+ { 0x0000da58, 0x0000333d },
+ { 0x0000da5c, 0x00003346 },
+ { 0x0000da60, 0x0000334f },
+ { 0x0000da64, 0x00003359 },
+ { 0x0000da68, 0x00003362 },
+ { 0x0000da6c, 0x0000336b },
+ { 0x0000da70, 0x00003375 },
+ { 0x0000da74, 0x0000337e },
+ { 0x0000da78, 0x00003388 },
+ { 0x0000da7c, 0x00003392 },
+ { 0x0000da80, 0x0000339b },
+ { 0x0000da84, 0x000033a5 },
+ { 0x0000da88, 0x000033af },
+ { 0x0000da8c, 0x000033b9 },
+ { 0x0000da90, 0x000033c3 },
+ { 0x0000da94, 0x000033cd },
+ { 0x0000da98, 0x000033d7 },
+ { 0x0000da9c, 0x000033e1 },
+ { 0x0000daa0, 0x000033eb },
+ { 0x0000daa4, 0x000033f5 },
+ { 0x0000daa8, 0x00003400 },
+ { 0x0000daac, 0x00003405 },
+ { 0x0000dab0, 0x0000340a },
+ { 0x0000dab4, 0x0000340f },
+ { 0x0000dab8, 0x00003414 },
+ { 0x0000dabc, 0x0000341a },
+ { 0x0000dac0, 0x0000341f },
+ { 0x0000dac4, 0x00003424 },
+ { 0x0000dac8, 0x0000342a },
+ { 0x0000dacc, 0x0000342f },
+ { 0x0000dad0, 0x00003435 },
+ { 0x0000dad4, 0x0000343a },
+ { 0x0000dad8, 0x00003440 },
+ { 0x0000dadc, 0x00003445 },
+ { 0x0000dae0, 0x0000344b },
+ { 0x0000dae4, 0x00003450 },
+ { 0x0000dae8, 0x00003456 },
+ { 0x0000daec, 0x0000345b },
+ { 0x0000daf0, 0x00003461 },
+ { 0x0000daf4, 0x00003467 },
+ { 0x0000daf8, 0x0000346d },
+ { 0x0000dafc, 0x00003472 },
+ { 0x0000db00, 0x00003478 },
+ { 0x0000db04, 0x0000347e },
+ { 0x0000db08, 0x00003484 },
+ { 0x0000db0c, 0x0000348a },
+ { 0x0000db10, 0x0000348f },
+ { 0x0000db14, 0x00003495 },
+ { 0x0000db18, 0x0000349b },
+ { 0x0000db1c, 0x000034a1 },
+ { 0x0000db20, 0x000034a7 },
+ { 0x0000db24, 0x000034ad },
+ { 0x0000db28, 0x000034b3 },
+ { 0x0000db2c, 0x000034ba },
+ { 0x0000db30, 0x000034c0 },
+ { 0x0000db34, 0x000034c6 },
+ { 0x0000db38, 0x000034cc },
+ { 0x0000db3c, 0x000034d2 },
+ { 0x0000db40, 0x000034d8 },
+ { 0x0000db44, 0x000034df },
+ { 0x0000db48, 0x000034e5 },
+ { 0x0000db4c, 0x000034eb },
+ { 0x0000db50, 0x000034f2 },
+ { 0x0000db54, 0x000034f8 },
+ { 0x0000db58, 0x000034ff },
+ { 0x0000db5c, 0x00003505 },
+ { 0x0000db60, 0x0000350c },
+ { 0x0000db64, 0x00003512 },
+ { 0x0000db68, 0x00003519 },
+ { 0x0000db6c, 0x0000351f },
+ { 0x0000db70, 0x00003526 },
+ { 0x0000db74, 0x0000352c },
+ { 0x0000db78, 0x00003533 },
+ { 0x0000db7c, 0x0000353a },
+ { 0x0000db80, 0x00003540 },
+ { 0x0000db84, 0x00003547 },
+ { 0x0000db88, 0x0000354e },
+ { 0x0000db8c, 0x00003555 },
+ { 0x0000db90, 0x0000355c },
+ { 0x0000db94, 0x00003563 },
+ { 0x0000db98, 0x00003569 },
+ { 0x0000db9c, 0x00003570 },
+ { 0x0000dba0, 0x00003577 },
+ { 0x0000dba4, 0x0000357e },
+ { 0x0000dba8, 0x00003585 },
+ { 0x0000dbac, 0x0000358c },
+ { 0x0000dbb0, 0x00003594 },
+ { 0x0000dbb4, 0x0000359b },
+ { 0x0000dbb8, 0x000035a2 },
+ { 0x0000dbbc, 0x000035a9 },
+ { 0x0000dbc0, 0x000035b0 },
+ { 0x0000dbc4, 0x000035b7 },
+ { 0x0000dbc8, 0x000035bf },
+ { 0x0000dbcc, 0x000035c6 },
+ { 0x0000dbd0, 0x000035cd },
+ { 0x0000dbd4, 0x000035d5 },
+ { 0x0000dbd8, 0x000035dc },
+ { 0x0000dbdc, 0x000035e4 },
+ { 0x0000dbe0, 0x000035eb },
+ { 0x0000dbe4, 0x000035f2 },
+ { 0x0000dbe8, 0x000035fa },
+ { 0x0000dbec, 0x00003600 },
+ { 0x0000dbf0, 0x00003604 },
+ { 0x0000dbf4, 0x00003608 },
+ { 0x0000dbf8, 0x0000360c },
+ { 0x0000dbfc, 0x00003610 },
+ { 0x0000dc00, 0x00003614 },
+ { 0x0000dc04, 0x00003617 },
+ { 0x0000dc08, 0x0000361b },
+ { 0x0000dc0c, 0x0000361f },
+ { 0x0000dc10, 0x00003623 },
+ { 0x0000dc14, 0x00003627 },
+ { 0x0000dc18, 0x0000362b },
+ { 0x0000dc1c, 0x0000362f },
+ { 0x0000dc20, 0x00003633 },
+ { 0x0000dc24, 0x00003637 },
+ { 0x0000dc28, 0x0000363b },
+ { 0x0000dc2c, 0x0000363f },
+ { 0x0000dc30, 0x00003643 },
+ { 0x0000dc34, 0x00003647 },
+ { 0x0000dc38, 0x0000364b },
+ { 0x0000dc3c, 0x0000364f },
+ { 0x0000dc40, 0x00003653 },
+ { 0x0000dc44, 0x00003657 },
+ { 0x0000dc48, 0x0000365b },
+ { 0x0000dc4c, 0x00003660 },
+ { 0x0000dc50, 0x00003664 },
+ { 0x0000dc54, 0x00003668 },
+ { 0x0000dc58, 0x0000366c },
+ { 0x0000dc5c, 0x00003670 },
+ { 0x0000dc60, 0x00003675 },
+ { 0x0000dc64, 0x00003679 },
+ { 0x0000dc68, 0x0000367d },
+ { 0x0000dc6c, 0x00003681 },
+ { 0x0000dc70, 0x00003686 },
+ { 0x0000dc74, 0x0000368a },
+ { 0x0000dc78, 0x0000368e },
+ { 0x0000dc7c, 0x00003693 },
+ { 0x0000dc80, 0x00003697 },
+ { 0x0000dc84, 0x0000369b },
+ { 0x0000dc88, 0x000036a0 },
+ { 0x0000dc8c, 0x000036a4 },
+ { 0x0000dc90, 0x000036a8 },
+ { 0x0000dc94, 0x000036ad },
+ { 0x0000dc98, 0x000036b1 },
+ { 0x0000dc9c, 0x000036b6 },
+ { 0x0000dca0, 0x000036ba },
+ { 0x0000dca4, 0x000036bf },
+ { 0x0000dca8, 0x000036c3 },
+ { 0x0000dcac, 0x000036c8 },
+ { 0x0000dcb0, 0x000036cc },
+ { 0x0000dcb4, 0x000036d1 },
+ { 0x0000dcb8, 0x000036d5 },
+ { 0x0000dcbc, 0x000036da },
+ { 0x0000dcc0, 0x000036df },
+ { 0x0000dcc4, 0x000036e3 },
+ { 0x0000dcc8, 0x000036e8 },
+ { 0x0000dccc, 0x000036ec },
+ { 0x0000dcd0, 0x000036f1 },
+ { 0x0000dcd4, 0x000036f6 },
+ { 0x0000dcd8, 0x000036fb },
+ { 0x0000dcdc, 0x000036ff },
+ { 0x0000dce0, 0x00003704 },
+ { 0x0000dce4, 0x00003709 },
+ { 0x0000dce8, 0x0000370d },
+ { 0x0000dcec, 0x00003712 },
+ { 0x0000dcf0, 0x00003717 },
+ { 0x0000dcf4, 0x0000371c },
+ { 0x0000dcf8, 0x00003721 },
+ { 0x0000dcfc, 0x00003725 },
+ { 0x0000dd00, 0x0000372a },
+ { 0x0000dd04, 0x0000372f },
+ { 0x0000dd08, 0x00003734 },
+ { 0x0000dd0c, 0x00003739 },
+ { 0x0000dd10, 0x0000373e },
+ { 0x0000dd14, 0x00003743 },
+ { 0x0000dd18, 0x00003748 },
+ { 0x0000dd1c, 0x0000374d },
+ { 0x0000dd20, 0x00003752 },
+ { 0x0000dd24, 0x00003757 },
+ { 0x0000dd28, 0x0000375c },
+ { 0x0000dd2c, 0x00003761 },
+ { 0x0000dd30, 0x00003766 },
+ { 0x0000dd34, 0x0000376b },
+ { 0x0000dd38, 0x00003770 },
+ { 0x0000dd3c, 0x00003775 },
+ { 0x0000dd40, 0x0000377a },
+ { 0x0000dd44, 0x0000377f },
+ { 0x0000dd48, 0x00003784 },
+ { 0x0000dd4c, 0x0000378a },
+ { 0x0000dd50, 0x0000378f },
+ { 0x0000dd54, 0x00003794 },
+ { 0x0000dd58, 0x00003799 },
+ { 0x0000dd5c, 0x0000379e },
+ { 0x0000dd60, 0x000037a4 },
+ { 0x0000dd64, 0x000037a9 },
+ { 0x0000dd68, 0x000037ae },
+ { 0x0000dd6c, 0x000037b3 },
+ { 0x0000dd70, 0x000037b9 },
+ { 0x0000dd74, 0x000037be },
+ { 0x0000dd78, 0x000037c3 },
+ { 0x0000dd7c, 0x000037c9 },
+ { 0x0000dd80, 0x000037ce },
+ { 0x0000dd84, 0x000037d4 },
+ { 0x0000dd88, 0x000037d9 },
+ { 0x0000dd8c, 0x000037de },
+ { 0x0000dd90, 0x000037e4 },
+ { 0x0000dd94, 0x000037e9 },
+ { 0x0000dd98, 0x000037ef },
+ { 0x0000dd9c, 0x000037f4 },
+ { 0x0000dda0, 0x000037fa },
+ { 0x0000dda4, 0x000037ff },
+ { 0x0000dda8, 0x00003802 },
+ { 0x0000ddac, 0x00003805 },
+ { 0x0000ddb0, 0x00003808 },
+ { 0x0000ddb4, 0x0000380a },
+ { 0x0000ddb8, 0x0000380d },
+ { 0x0000ddbc, 0x00003810 },
+ { 0x0000ddc0, 0x00003813 },
+ { 0x0000ddc4, 0x00003816 },
+ { 0x0000ddc8, 0x00003819 },
+ { 0x0000ddcc, 0x0000381b },
+ { 0x0000ddd0, 0x0000381e },
+ { 0x0000ddd4, 0x00003821 },
+ { 0x0000ddd8, 0x00003824 },
+ { 0x0000dddc, 0x00003827 },
+ { 0x0000dde0, 0x0000382a },
+ { 0x0000dde4, 0x0000382d },
+ { 0x0000dde8, 0x00003830 },
+ { 0x0000ddec, 0x00003832 },
+ { 0x0000ddf0, 0x00003835 },
+ { 0x0000ddf4, 0x00003838 },
+ { 0x0000ddf8, 0x0000383b },
+ { 0x0000ddfc, 0x0000383e },
+ { 0x0000de00, 0x00003841 },
+ { 0x0000de04, 0x00003844 },
+ { 0x0000de08, 0x00003847 },
+ { 0x0000de0c, 0x0000384a },
+ { 0x0000de10, 0x0000384d },
+ { 0x0000de14, 0x00003850 },
+ { 0x0000de18, 0x00003853 },
+ { 0x0000de1c, 0x00003856 },
+ { 0x0000de20, 0x00003859 },
+ { 0x0000de24, 0x0000385c },
+ { 0x0000de28, 0x0000385f },
+ { 0x0000de2c, 0x00003862 },
+ { 0x0000de30, 0x00003865 },
+ { 0x0000de34, 0x00003868 },
+ { 0x0000de38, 0x0000386b },
+ { 0x0000de3c, 0x0000386e },
+ { 0x0000de40, 0x00003871 },
+ { 0x0000de44, 0x00003874 },
+ { 0x0000de48, 0x00003878 },
+ { 0x0000de4c, 0x0000387b },
+ { 0x0000de50, 0x0000387e },
+ { 0x0000de54, 0x00003881 },
+ { 0x0000de58, 0x00003884 },
+ { 0x0000de5c, 0x00003887 },
+ { 0x0000de60, 0x0000388a },
+ { 0x0000de64, 0x0000388e },
+ { 0x0000de68, 0x00003891 },
+ { 0x0000de6c, 0x00003894 },
+ { 0x0000de70, 0x00003897 },
+ { 0x0000de74, 0x0000389a },
+ { 0x0000de78, 0x0000389d },
+ { 0x0000de7c, 0x000038a1 },
+ { 0x0000de80, 0x000038a4 },
+ { 0x0000de84, 0x000038a7 },
+ { 0x0000de88, 0x000038aa },
+ { 0x0000de8c, 0x000038ae },
+ { 0x0000de90, 0x000038b1 },
+ { 0x0000de94, 0x000038b4 },
+ { 0x0000de98, 0x000038b7 },
+ { 0x0000de9c, 0x000038bb },
+ { 0x0000dea0, 0x000038be },
+ { 0x0000dea4, 0x000038c1 },
+ { 0x0000dea8, 0x000038c4 },
+ { 0x0000deac, 0x000038c8 },
+ { 0x0000deb0, 0x000038cb },
+ { 0x0000deb4, 0x000038ce },
+ { 0x0000deb8, 0x000038d2 },
+ { 0x0000debc, 0x000038d5 },
+ { 0x0000dec0, 0x000038d8 },
+ { 0x0000dec4, 0x000038dc },
+ { 0x0000dec8, 0x000038df },
+ { 0x0000decc, 0x000038e3 },
+ { 0x0000ded0, 0x000038e6 },
+ { 0x0000ded4, 0x000038e9 },
+ { 0x0000ded8, 0x000038ed },
+ { 0x0000dedc, 0x000038f0 },
+ { 0x0000dee0, 0x000038f4 },
+ { 0x0000dee4, 0x000038f7 },
+ { 0x0000dee8, 0x000038fa },
+ { 0x0000deec, 0x000038fe },
+ { 0x0000def0, 0x00003901 },
+ { 0x0000def4, 0x00003905 },
+ { 0x0000def8, 0x00003908 },
+ { 0x0000defc, 0x0000390c },
+ { 0x0000df00, 0x0000390f },
+ { 0x0000df04, 0x00003913 },
+ { 0x0000df08, 0x00003916 },
+ { 0x0000df0c, 0x0000391a },
+ { 0x0000df10, 0x0000391d },
+ { 0x0000df14, 0x00003921 },
+ { 0x0000df18, 0x00003924 },
+ { 0x0000df1c, 0x00003928 },
+ { 0x0000df20, 0x0000392b },
+ { 0x0000df24, 0x0000392f },
+ { 0x0000df28, 0x00003933 },
+ { 0x0000df2c, 0x00003936 },
+ { 0x0000df30, 0x0000393a },
+ { 0x0000df34, 0x0000393d },
+ { 0x0000df38, 0x00003941 },
+ { 0x0000df3c, 0x00003945 },
+ { 0x0000df40, 0x00003948 },
+ { 0x0000df44, 0x0000394c },
+ { 0x0000df48, 0x00003950 },
+ { 0x0000df4c, 0x00003953 },
+ { 0x0000df50, 0x00003957 },
+ { 0x0000df54, 0x0000395b },
+ { 0x0000df58, 0x0000395e },
+ { 0x0000df5c, 0x00003962 },
+ { 0x0000df60, 0x00003966 },
+ { 0x0000df64, 0x00003969 },
+ { 0x0000df68, 0x0000396d },
+ { 0x0000df6c, 0x00003971 },
+ { 0x0000df70, 0x00003974 },
+ { 0x0000df74, 0x00003978 },
+ { 0x0000df78, 0x0000397c },
+ { 0x0000df7c, 0x00003980 },
+ { 0x0000df80, 0x00003983 },
+ { 0x0000df84, 0x00003987 },
+ { 0x0000df88, 0x0000398b },
+ { 0x0000df8c, 0x0000398f },
+ { 0x0000df90, 0x00003993 },
+ { 0x0000df94, 0x00003996 },
+ { 0x0000df98, 0x0000399a },
+ { 0x0000df9c, 0x0000399e },
+ { 0x0000dfa0, 0x000039a2 },
+ { 0x0000dfa4, 0x000039a6 },
+ { 0x0000dfa8, 0x000039aa },
+ { 0x0000dfac, 0x000039ad },
+ { 0x0000dfb0, 0x000039b1 },
+ { 0x0000dfb4, 0x000039b5 },
+ { 0x0000dfb8, 0x000039b9 },
+ { 0x0000dfbc, 0x000039bd },
+ { 0x0000dfc0, 0x000039c1 },
+ { 0x0000dfc4, 0x000039c5 },
+ { 0x0000dfc8, 0x000039c9 },
+ { 0x0000dfcc, 0x000039cd },
+ { 0x0000dfd0, 0x000039d1 },
+ { 0x0000dfd4, 0x000039d5 },
+ { 0x0000dfd8, 0x000039d8 },
+ { 0x0000dfdc, 0x000039dc },
+ { 0x0000dfe0, 0x000039e0 },
+ { 0x0000dfe4, 0x000039e4 },
+ { 0x0000dfe8, 0x000039e8 },
+ { 0x0000dfec, 0x000039ec },
+ { 0x0000dff0, 0x000039f0 },
+ { 0x0000dff4, 0x000039f4 },
+ { 0x0000dff8, 0x000039f8 },
+ { 0x0000dffc, 0x000039fc },
+};
+
+struct data_unit hdr10_opipe_a2[] = {
+ { 0x0000e000, 0x00003612 },
+ { 0x0000e004, 0x00003612 },
+ { 0x0000e008, 0x0000327c },
+ { 0x0000e00c, 0x00003840 },
+ { 0x0000e010, 0x00002fb2 },
+ { 0x0000e014, 0x00003475 },
+ { 0x0000e018, 0x00003728 },
+ { 0x0000e01c, 0x0000390e },
+ { 0x0000e020, 0x00002d7f },
+ { 0x0000e024, 0x00003134 },
+ { 0x0000e028, 0x00003397 },
+ { 0x0000e02c, 0x0000353d },
+ { 0x0000e030, 0x00003695 },
+ { 0x0000e034, 0x000037cb },
+ { 0x0000e038, 0x000038a2 },
+ { 0x0000e03c, 0x00003982 },
+ { 0x0000e040, 0x00002b71 },
+ { 0x0000e044, 0x00002ea4 },
+ { 0x0000e048, 0x00003079 },
+ { 0x0000e04c, 0x00003204 },
+ { 0x0000e050, 0x00003302 },
+ { 0x0000e054, 0x0000341c },
+ { 0x0000e058, 0x000034d5 },
+ { 0x0000e05c, 0x000035ad },
+ { 0x0000e060, 0x00003651 },
+ { 0x0000e064, 0x000036dc },
+ { 0x0000e068, 0x00003778 },
+ { 0x0000e06c, 0x00003811 },
+ { 0x0000e070, 0x00003870 },
+ { 0x0000e074, 0x000038d7 },
+ { 0x0000e078, 0x00003946 },
+ { 0x0000e07c, 0x000039bf },
+ { 0x0000e080, 0x00002955 },
+ { 0x0000e084, 0x00002c9c },
+ { 0x0000e088, 0x00002e31 },
+ { 0x0000e08c, 0x00002f25 },
+ { 0x0000e090, 0x00003026 },
+ { 0x0000e094, 0x000030d3 },
+ { 0x0000e098, 0x0000319b },
+ { 0x0000e09c, 0x0000323e },
+ { 0x0000e0a0, 0x000032bd },
+ { 0x0000e0a4, 0x0000334b },
+ { 0x0000e0a8, 0x000033e6 },
+ { 0x0000e0ac, 0x00003448 },
+ { 0x0000e0b0, 0x000034a4 },
+ { 0x0000e0b4, 0x00003508 },
+ { 0x0000e0b8, 0x00003574 },
+ { 0x0000e0bc, 0x000035e7 },
+ { 0x0000e0c0, 0x00003631 },
+ { 0x0000e0c4, 0x00003672 },
+ { 0x0000e0c8, 0x000036b8 },
+ { 0x0000e0cc, 0x00003702 },
+ { 0x0000e0d0, 0x0000374f },
+ { 0x0000e0d4, 0x000037a1 },
+ { 0x0000e0d8, 0x000037f7 },
+ { 0x0000e0dc, 0x00003828 },
+ { 0x0000e0e0, 0x00003857 },
+ { 0x0000e0e4, 0x00003889 },
+ { 0x0000e0e8, 0x000038bc },
+ { 0x0000e0ec, 0x000038f2 },
+ { 0x0000e0f0, 0x0000392a },
+ { 0x0000e0f4, 0x00003964 },
+ { 0x0000e0f8, 0x000039a0 },
+ { 0x0000e0fc, 0x000039de },
+ { 0x0000e100, 0x0000271c },
+ { 0x0000e104, 0x00002a8e },
+ { 0x0000e108, 0x00002c2a },
+ { 0x0000e10c, 0x00002d0e },
+ { 0x0000e110, 0x00002df1 },
+ { 0x0000e114, 0x00002e69 },
+ { 0x0000e118, 0x00002ee3 },
+ { 0x0000e11c, 0x00002f6a },
+ { 0x0000e120, 0x00002ffe },
+ { 0x0000e124, 0x0000304f },
+ { 0x0000e128, 0x000030a5 },
+ { 0x0000e12c, 0x00003102 },
+ { 0x0000e130, 0x00003166 },
+ { 0x0000e134, 0x000031d1 },
+ { 0x0000e138, 0x00003221 },
+ { 0x0000e13c, 0x0000325d },
+ { 0x0000e140, 0x0000329c },
+ { 0x0000e144, 0x000032df },
+ { 0x0000e148, 0x00003326 },
+ { 0x0000e14c, 0x00003370 },
+ { 0x0000e150, 0x000033be },
+ { 0x0000e154, 0x00003407 },
+ { 0x0000e158, 0x00003432 },
+ { 0x0000e15c, 0x0000345e },
+ { 0x0000e160, 0x0000348c },
+ { 0x0000e164, 0x000034bd },
+ { 0x0000e168, 0x000034ef },
+ { 0x0000e16c, 0x00003522 },
+ { 0x0000e170, 0x00003558 },
+ { 0x0000e174, 0x00003590 },
+ { 0x0000e178, 0x000035ca },
+ { 0x0000e17c, 0x00003602 },
+ { 0x0000e180, 0x00003621 },
+ { 0x0000e184, 0x00003641 },
+ { 0x0000e188, 0x00003662 },
+ { 0x0000e18c, 0x00003683 },
+ { 0x0000e190, 0x000036a6 },
+ { 0x0000e194, 0x000036ca },
+ { 0x0000e198, 0x000036ef },
+ { 0x0000e19c, 0x00003715 },
+ { 0x0000e1a0, 0x0000373b },
+ { 0x0000e1a4, 0x00003763 },
+ { 0x0000e1a8, 0x0000378c },
+ { 0x0000e1ac, 0x000037b6 },
+ { 0x0000e1b0, 0x000037e1 },
+ { 0x0000e1b4, 0x00003806 },
+ { 0x0000e1b8, 0x0000381d },
+ { 0x0000e1bc, 0x00003834 },
+ { 0x0000e1c0, 0x0000384b },
+ { 0x0000e1c4, 0x00003864 },
+ { 0x0000e1c8, 0x0000387c },
+ { 0x0000e1cc, 0x00003895 },
+ { 0x0000e1d0, 0x000038af },
+ { 0x0000e1d4, 0x000038c9 },
+ { 0x0000e1d8, 0x000038e4 },
+ { 0x0000e1dc, 0x00003900 },
+ { 0x0000e1e0, 0x0000391c },
+ { 0x0000e1e4, 0x00003938 },
+ { 0x0000e1e8, 0x00003955 },
+ { 0x0000e1ec, 0x00003973 },
+ { 0x0000e1f0, 0x00003991 },
+ { 0x0000e1f4, 0x000039af },
+ { 0x0000e1f8, 0x000039cf },
+ { 0x0000e1fc, 0x000039ee },
+ { 0x0000e200, 0x000024aa },
+ { 0x0000e204, 0x00002871 },
+ { 0x0000e208, 0x00002a1c },
+ { 0x0000e20c, 0x00002aff },
+ { 0x0000e210, 0x00002be3 },
+ { 0x0000e214, 0x00002c63 },
+ { 0x0000e218, 0x00002cd5 },
+ { 0x0000e21c, 0x00002d47 },
+ { 0x0000e220, 0x00002db8 },
+ { 0x0000e224, 0x00002e15 },
+ { 0x0000e228, 0x00002e4c },
+ { 0x0000e22c, 0x00002e86 },
+ { 0x0000e230, 0x00002ec4 },
+ { 0x0000e234, 0x00002f04 },
+ { 0x0000e238, 0x00002f47 },
+ { 0x0000e23c, 0x00002f8e },
+ { 0x0000e240, 0x00002fd8 },
+ { 0x0000e244, 0x00003012 },
+ { 0x0000e248, 0x0000303a },
+ { 0x0000e24c, 0x00003064 },
+ { 0x0000e250, 0x0000308f },
+ { 0x0000e254, 0x000030bc },
+ { 0x0000e258, 0x000030eb },
+ { 0x0000e25c, 0x0000311b },
+ { 0x0000e260, 0x0000314d },
+ { 0x0000e264, 0x00003180 },
+ { 0x0000e268, 0x000031b5 },
+ { 0x0000e26c, 0x000031ec },
+ { 0x0000e270, 0x00003212 },
+ { 0x0000e274, 0x0000322f },
+ { 0x0000e278, 0x0000324d },
+ { 0x0000e27c, 0x0000326c },
+ { 0x0000e280, 0x0000328c },
+ { 0x0000e284, 0x000032ad },
+ { 0x0000e288, 0x000032ce },
+ { 0x0000e28c, 0x000032f1 },
+ { 0x0000e290, 0x00003314 },
+ { 0x0000e294, 0x00003338 },
+ { 0x0000e298, 0x0000335d },
+ { 0x0000e29c, 0x00003383 },
+ { 0x0000e2a0, 0x000033aa },
+ { 0x0000e2a4, 0x000033d2 },
+ { 0x0000e2a8, 0x000033fb },
+ { 0x0000e2ac, 0x00003412 },
+ { 0x0000e2b0, 0x00003427 },
+ { 0x0000e2b4, 0x0000343d },
+ { 0x0000e2b8, 0x00003453 },
+ { 0x0000e2bc, 0x0000346a },
+ { 0x0000e2c0, 0x00003481 },
+ { 0x0000e2c4, 0x00003498 },
+ { 0x0000e2c8, 0x000034b0 },
+ { 0x0000e2cc, 0x000034c9 },
+ { 0x0000e2d0, 0x000034e2 },
+ { 0x0000e2d4, 0x000034fb },
+ { 0x0000e2d8, 0x00003515 },
+ { 0x0000e2dc, 0x00003530 },
+ { 0x0000e2e0, 0x0000354b },
+ { 0x0000e2e4, 0x00003566 },
+ { 0x0000e2e8, 0x00003582 },
+ { 0x0000e2ec, 0x0000359e },
+ { 0x0000e2f0, 0x000035bb },
+ { 0x0000e2f4, 0x000035d8 },
+ { 0x0000e2f8, 0x000035f6 },
+ { 0x0000e2fc, 0x0000360a },
+ { 0x0000e300, 0x00003619 },
+ { 0x0000e304, 0x00003629 },
+ { 0x0000e308, 0x00003639 },
+ { 0x0000e30c, 0x00003649 },
+ { 0x0000e310, 0x00003659 },
+ { 0x0000e314, 0x0000366a },
+ { 0x0000e318, 0x0000367b },
+ { 0x0000e31c, 0x0000368c },
+ { 0x0000e320, 0x0000369d },
+ { 0x0000e324, 0x000036af },
+ { 0x0000e328, 0x000036c1 },
+ { 0x0000e32c, 0x000036d3 },
+ { 0x0000e330, 0x000036e6 },
+ { 0x0000e334, 0x000036f8 },
+ { 0x0000e338, 0x0000370b },
+ { 0x0000e33c, 0x0000371e },
+ { 0x0000e340, 0x00003732 },
+ { 0x0000e344, 0x00003745 },
+ { 0x0000e348, 0x00003759 },
+ { 0x0000e34c, 0x0000376d },
+ { 0x0000e350, 0x00003782 },
+ { 0x0000e354, 0x00003797 },
+ { 0x0000e358, 0x000037ac },
+ { 0x0000e35c, 0x000037c1 },
+ { 0x0000e360, 0x000037d6 },
+ { 0x0000e364, 0x000037ec },
+ { 0x0000e368, 0x00003801 },
+ { 0x0000e36c, 0x0000380c },
+ { 0x0000e370, 0x00003817 },
+ { 0x0000e374, 0x00003823 },
+ { 0x0000e378, 0x0000382e },
+ { 0x0000e37c, 0x0000383a },
+ { 0x0000e380, 0x00003846 },
+ { 0x0000e384, 0x00003851 },
+ { 0x0000e388, 0x0000385e },
+ { 0x0000e38c, 0x0000386a },
+ { 0x0000e390, 0x00003876 },
+ { 0x0000e394, 0x00003883 },
+ { 0x0000e398, 0x0000388f },
+ { 0x0000e39c, 0x0000389c },
+ { 0x0000e3a0, 0x000038a9 },
+ { 0x0000e3a4, 0x000038b6 },
+ { 0x0000e3a8, 0x000038c3 },
+ { 0x0000e3ac, 0x000038d0 },
+ { 0x0000e3b0, 0x000038de },
+ { 0x0000e3b4, 0x000038eb },
+ { 0x0000e3b8, 0x000038f9 },
+ { 0x0000e3bc, 0x00003907 },
+ { 0x0000e3c0, 0x00003915 },
+ { 0x0000e3c4, 0x00003923 },
+ { 0x0000e3c8, 0x00003931 },
+ { 0x0000e3cc, 0x0000393f },
+ { 0x0000e3d0, 0x0000394e },
+ { 0x0000e3d4, 0x0000395c },
+ { 0x0000e3d8, 0x0000396b },
+ { 0x0000e3dc, 0x0000397a },
+ { 0x0000e3e0, 0x00003989 },
+ { 0x0000e3e4, 0x00003998 },
+ { 0x0000e3e8, 0x000039a8 },
+ { 0x0000e3ec, 0x000039b7 },
+ { 0x0000e3f0, 0x000039c7 },
+ { 0x0000e3f4, 0x000039d6 },
+ { 0x0000e3f8, 0x000039e6 },
+ { 0x0000e3fc, 0x000039f6 },
+ { 0x0000e400, 0x0000218e },
+ { 0x0000e404, 0x00002638 },
+ { 0x0000e408, 0x000027ff },
+ { 0x0000e40c, 0x000028e3 },
+ { 0x0000e410, 0x000029c7 },
+ { 0x0000e414, 0x00002a55 },
+ { 0x0000e418, 0x00002ac7 },
+ { 0x0000e41c, 0x00002b38 },
+ { 0x0000e420, 0x00002baa },
+ { 0x0000e424, 0x00002c0e },
+ { 0x0000e428, 0x00002c47 },
+ { 0x0000e42c, 0x00002c7f },
+ { 0x0000e430, 0x00002cb8 },
+ { 0x0000e434, 0x00002cf1 },
+ { 0x0000e438, 0x00002d2a },
+ { 0x0000e43c, 0x00002d63 },
+ { 0x0000e440, 0x00002d9c },
+ { 0x0000e444, 0x00002dd5 },
+ { 0x0000e448, 0x00002e07 },
+ { 0x0000e44c, 0x00002e23 },
+ { 0x0000e450, 0x00002e3f },
+ { 0x0000e454, 0x00002e5a },
+ { 0x0000e458, 0x00002e77 },
+ { 0x0000e45c, 0x00002e95 },
+ { 0x0000e460, 0x00002eb4 },
+ { 0x0000e464, 0x00002ed3 },
+ { 0x0000e468, 0x00002ef4 },
+ { 0x0000e46c, 0x00002f14 },
+ { 0x0000e470, 0x00002f36 },
+ { 0x0000e474, 0x00002f59 },
+ { 0x0000e478, 0x00002f7c },
+ { 0x0000e47c, 0x00002fa0 },
+ { 0x0000e480, 0x00002fc5 },
+ { 0x0000e484, 0x00002feb },
+ { 0x0000e488, 0x00003008 },
+ { 0x0000e48c, 0x0000301c },
+ { 0x0000e490, 0x00003030 },
+ { 0x0000e494, 0x00003044 },
+ { 0x0000e498, 0x00003059 },
+ { 0x0000e49c, 0x0000306e },
+ { 0x0000e4a0, 0x00003084 },
+ { 0x0000e4a4, 0x0000309a },
+ { 0x0000e4a8, 0x000030b1 },
+ { 0x0000e4ac, 0x000030c7 },
+ { 0x0000e4b0, 0x000030df },
+ { 0x0000e4b4, 0x000030f6 },
+ { 0x0000e4b8, 0x0000310f },
+ { 0x0000e4bc, 0x00003127 },
+ { 0x0000e4c0, 0x00003140 },
+ { 0x0000e4c4, 0x00003159 },
+ { 0x0000e4c8, 0x00003173 },
+ { 0x0000e4cc, 0x0000318d },
+ { 0x0000e4d0, 0x000031a8 },
+ { 0x0000e4d4, 0x000031c3 },
+ { 0x0000e4d8, 0x000031de },
+ { 0x0000e4dc, 0x000031fa },
+ { 0x0000e4e0, 0x0000320b },
+ { 0x0000e4e4, 0x00003219 },
+ { 0x0000e4e8, 0x00003228 },
+ { 0x0000e4ec, 0x00003237 },
+ { 0x0000e4f0, 0x00003246 },
+ { 0x0000e4f4, 0x00003255 },
+ { 0x0000e4f8, 0x00003265 },
+ { 0x0000e4fc, 0x00003274 },
+ { 0x0000e500, 0x00003284 },
+ { 0x0000e504, 0x00003294 },
+ { 0x0000e508, 0x000032a5 },
+ { 0x0000e50c, 0x000032b5 },
+ { 0x0000e510, 0x000032c6 },
+ { 0x0000e514, 0x000032d7 },
+ { 0x0000e518, 0x000032e8 },
+ { 0x0000e51c, 0x000032f9 },
+ { 0x0000e520, 0x0000330b },
+ { 0x0000e524, 0x0000331d },
+ { 0x0000e528, 0x0000332f },
+ { 0x0000e52c, 0x00003341 },
+ { 0x0000e530, 0x00003354 },
+ { 0x0000e534, 0x00003367 },
+ { 0x0000e538, 0x0000337a },
+ { 0x0000e53c, 0x0000338d },
+ { 0x0000e540, 0x000033a0 },
+ { 0x0000e544, 0x000033b4 },
+ { 0x0000e548, 0x000033c8 },
+ { 0x0000e54c, 0x000033dc },
+ { 0x0000e550, 0x000033f0 },
+ { 0x0000e554, 0x00003402 },
+ { 0x0000e558, 0x0000340d },
+ { 0x0000e55c, 0x00003417 },
+ { 0x0000e560, 0x00003422 },
+ { 0x0000e564, 0x0000342c },
+ { 0x0000e568, 0x00003437 },
+ { 0x0000e56c, 0x00003442 },
+ { 0x0000e570, 0x0000344d },
+ { 0x0000e574, 0x00003459 },
+ { 0x0000e578, 0x00003464 },
+ { 0x0000e57c, 0x0000346f },
+ { 0x0000e580, 0x0000347b },
+ { 0x0000e584, 0x00003487 },
+ { 0x0000e588, 0x00003492 },
+ { 0x0000e58c, 0x0000349e },
+ { 0x0000e590, 0x000034aa },
+ { 0x0000e594, 0x000034b6 },
+ { 0x0000e598, 0x000034c3 },
+ { 0x0000e59c, 0x000034cf },
+ { 0x0000e5a0, 0x000034dc },
+ { 0x0000e5a4, 0x000034e8 },
+ { 0x0000e5a8, 0x000034f5 },
+ { 0x0000e5ac, 0x00003502 },
+ { 0x0000e5b0, 0x0000350f },
+ { 0x0000e5b4, 0x0000351c },
+ { 0x0000e5b8, 0x00003529 },
+ { 0x0000e5bc, 0x00003536 },
+ { 0x0000e5c0, 0x00003544 },
+ { 0x0000e5c4, 0x00003551 },
+ { 0x0000e5c8, 0x0000355f },
+ { 0x0000e5cc, 0x0000356d },
+ { 0x0000e5d0, 0x0000357b },
+ { 0x0000e5d4, 0x00003589 },
+ { 0x0000e5d8, 0x00003597 },
+ { 0x0000e5dc, 0x000035a5 },
+ { 0x0000e5e0, 0x000035b4 },
+ { 0x0000e5e4, 0x000035c2 },
+ { 0x0000e5e8, 0x000035d1 },
+ { 0x0000e5ec, 0x000035e0 },
+ { 0x0000e5f0, 0x000035ef },
+ { 0x0000e5f4, 0x000035fe },
+ { 0x0000e5f8, 0x00003606 },
+ { 0x0000e5fc, 0x0000360e },
+ { 0x0000e600, 0x00003616 },
+ { 0x0000e604, 0x0000361d },
+ { 0x0000e608, 0x00003625 },
+ { 0x0000e60c, 0x0000362d },
+ { 0x0000e610, 0x00003635 },
+ { 0x0000e614, 0x0000363d },
+ { 0x0000e618, 0x00003645 },
+ { 0x0000e61c, 0x0000364d },
+ { 0x0000e620, 0x00003655 },
+ { 0x0000e624, 0x0000365e },
+ { 0x0000e628, 0x00003666 },
+ { 0x0000e62c, 0x0000366e },
+ { 0x0000e630, 0x00003677 },
+ { 0x0000e634, 0x0000367f },
+ { 0x0000e638, 0x00003688 },
+ { 0x0000e63c, 0x00003690 },
+ { 0x0000e640, 0x00003699 },
+ { 0x0000e644, 0x000036a2 },
+ { 0x0000e648, 0x000036ab },
+ { 0x0000e64c, 0x000036b4 },
+ { 0x0000e650, 0x000036bc },
+ { 0x0000e654, 0x000036c5 },
+ { 0x0000e658, 0x000036cf },
+ { 0x0000e65c, 0x000036d8 },
+ { 0x0000e660, 0x000036e1 },
+ { 0x0000e664, 0x000036ea },
+ { 0x0000e668, 0x000036f3 },
+ { 0x0000e66c, 0x000036fd },
+ { 0x0000e670, 0x00003706 },
+ { 0x0000e674, 0x00003710 },
+ { 0x0000e678, 0x00003719 },
+ { 0x0000e67c, 0x00003723 },
+ { 0x0000e680, 0x0000372d },
+ { 0x0000e684, 0x00003737 },
+ { 0x0000e688, 0x00003740 },
+ { 0x0000e68c, 0x0000374a },
+ { 0x0000e690, 0x00003754 },
+ { 0x0000e694, 0x0000375e },
+ { 0x0000e698, 0x00003768 },
+ { 0x0000e69c, 0x00003772 },
+ { 0x0000e6a0, 0x0000377d },
+ { 0x0000e6a4, 0x00003787 },
+ { 0x0000e6a8, 0x00003791 },
+ { 0x0000e6ac, 0x0000379c },
+ { 0x0000e6b0, 0x000037a6 },
+ { 0x0000e6b4, 0x000037b1 },
+ { 0x0000e6b8, 0x000037bb },
+ { 0x0000e6bc, 0x000037c6 },
+ { 0x0000e6c0, 0x000037d1 },
+ { 0x0000e6c4, 0x000037dc },
+ { 0x0000e6c8, 0x000037e7 },
+ { 0x0000e6cc, 0x000037f1 },
+ { 0x0000e6d0, 0x000037fc },
+ { 0x0000e6d4, 0x00003804 },
+ { 0x0000e6d8, 0x00003809 },
+ { 0x0000e6dc, 0x0000380f },
+ { 0x0000e6e0, 0x00003814 },
+ { 0x0000e6e4, 0x0000381a },
+ { 0x0000e6e8, 0x00003820 },
+ { 0x0000e6ec, 0x00003825 },
+ { 0x0000e6f0, 0x0000382b },
+ { 0x0000e6f4, 0x00003831 },
+ { 0x0000e6f8, 0x00003837 },
+ { 0x0000e6fc, 0x0000383d },
+ { 0x0000e700, 0x00003843 },
+ { 0x0000e704, 0x00003848 },
+ { 0x0000e708, 0x0000384e },
+ { 0x0000e70c, 0x00003854 },
+ { 0x0000e710, 0x0000385a },
+ { 0x0000e714, 0x00003861 },
+ { 0x0000e718, 0x00003867 },
+ { 0x0000e71c, 0x0000386d },
+ { 0x0000e720, 0x00003873 },
+ { 0x0000e724, 0x00003879 },
+ { 0x0000e728, 0x0000387f },
+ { 0x0000e72c, 0x00003886 },
+ { 0x0000e730, 0x0000388c },
+ { 0x0000e734, 0x00003892 },
+ { 0x0000e738, 0x00003899 },
+ { 0x0000e73c, 0x0000389f },
+ { 0x0000e740, 0x000038a5 },
+ { 0x0000e744, 0x000038ac },
+ { 0x0000e748, 0x000038b2 },
+ { 0x0000e74c, 0x000038b9 },
+ { 0x0000e750, 0x000038c0 },
+ { 0x0000e754, 0x000038c6 },
+ { 0x0000e758, 0x000038cd },
+ { 0x0000e75c, 0x000038d3 },
+ { 0x0000e760, 0x000038da },
+ { 0x0000e764, 0x000038e1 },
+ { 0x0000e768, 0x000038e8 },
+ { 0x0000e76c, 0x000038ee },
+ { 0x0000e770, 0x000038f5 },
+ { 0x0000e774, 0x000038fc },
+ { 0x0000e778, 0x00003903 },
+ { 0x0000e77c, 0x0000390a },
+ { 0x0000e780, 0x00003911 },
+ { 0x0000e784, 0x00003918 },
+ { 0x0000e788, 0x0000391f },
+ { 0x0000e78c, 0x00003926 },
+ { 0x0000e790, 0x0000392d },
+ { 0x0000e794, 0x00003934 },
+ { 0x0000e798, 0x0000393c },
+ { 0x0000e79c, 0x00003943 },
+ { 0x0000e7a0, 0x0000394a },
+ { 0x0000e7a4, 0x00003951 },
+ { 0x0000e7a8, 0x00003959 },
+ { 0x0000e7ac, 0x00003960 },
+ { 0x0000e7b0, 0x00003967 },
+ { 0x0000e7b4, 0x0000396f },
+ { 0x0000e7b8, 0x00003976 },
+ { 0x0000e7bc, 0x0000397e },
+ { 0x0000e7c0, 0x00003985 },
+ { 0x0000e7c4, 0x0000398d },
+ { 0x0000e7c8, 0x00003995 },
+ { 0x0000e7cc, 0x0000399c },
+ { 0x0000e7d0, 0x000039a4 },
+ { 0x0000e7d4, 0x000039ac },
+ { 0x0000e7d8, 0x000039b3 },
+ { 0x0000e7dc, 0x000039bb },
+ { 0x0000e7e0, 0x000039c3 },
+ { 0x0000e7e4, 0x000039cb },
+ { 0x0000e7e8, 0x000039d3 },
+ { 0x0000e7ec, 0x000039da },
+ { 0x0000e7f0, 0x000039e2 },
+ { 0x0000e7f4, 0x000039ea },
+ { 0x0000e7f8, 0x000039f2 },
+ { 0x0000e7fc, 0x000039fa },
+ { 0x0000e800, 0x00000000 },
+ { 0x0000e804, 0x0000238e },
+ { 0x0000e808, 0x0000258e },
+ { 0x0000e80c, 0x000026aa },
+ { 0x0000e810, 0x0000278e },
+ { 0x0000e814, 0x00002838 },
+ { 0x0000e818, 0x000028aa },
+ { 0x0000e81c, 0x0000291c },
+ { 0x0000e820, 0x0000298e },
+ { 0x0000e824, 0x000029ff },
+ { 0x0000e828, 0x00002a38 },
+ { 0x0000e82c, 0x00002a71 },
+ { 0x0000e830, 0x00002aaa },
+ { 0x0000e834, 0x00002ae3 },
+ { 0x0000e838, 0x00002b1c },
+ { 0x0000e83c, 0x00002b55 },
+ { 0x0000e840, 0x00002b8e },
+ { 0x0000e844, 0x00002bc7 },
+ { 0x0000e848, 0x00002bff },
+ { 0x0000e84c, 0x00002c1c },
+ { 0x0000e850, 0x00002c38 },
+ { 0x0000e854, 0x00002c55 },
+ { 0x0000e858, 0x00002c71 },
+ { 0x0000e85c, 0x00002c8e },
+ { 0x0000e860, 0x00002caa },
+ { 0x0000e864, 0x00002cc7 },
+ { 0x0000e868, 0x00002ce3 },
+ { 0x0000e86c, 0x00002cff },
+ { 0x0000e870, 0x00002d1c },
+ { 0x0000e874, 0x00002d38 },
+ { 0x0000e878, 0x00002d55 },
+ { 0x0000e87c, 0x00002d71 },
+ { 0x0000e880, 0x00002d8e },
+ { 0x0000e884, 0x00002daa },
+ { 0x0000e888, 0x00002dc7 },
+ { 0x0000e88c, 0x00002de3 },
+ { 0x0000e890, 0x00002dff },
+ { 0x0000e894, 0x00002e0e },
+ { 0x0000e898, 0x00002e1c },
+ { 0x0000e89c, 0x00002e2a },
+ { 0x0000e8a0, 0x00002e38 },
+ { 0x0000e8a4, 0x00002e47 },
+ { 0x0000e8a8, 0x00002e53 },
+ { 0x0000e8ac, 0x00002e61 },
+ { 0x0000e8b0, 0x00002e70 },
+ { 0x0000e8b4, 0x00002e7f },
+ { 0x0000e8b8, 0x00002e8e },
+ { 0x0000e8bc, 0x00002e9d },
+ { 0x0000e8c0, 0x00002eac },
+ { 0x0000e8c4, 0x00002ebc },
+ { 0x0000e8c8, 0x00002ecb },
+ { 0x0000e8cc, 0x00002edb },
+ { 0x0000e8d0, 0x00002eeb },
+ { 0x0000e8d4, 0x00002efc },
+ { 0x0000e8d8, 0x00002f0c },
+ { 0x0000e8dc, 0x00002f1d },
+ { 0x0000e8e0, 0x00002f2e },
+ { 0x0000e8e4, 0x00002f3f },
+ { 0x0000e8e8, 0x00002f50 },
+ { 0x0000e8ec, 0x00002f61 },
+ { 0x0000e8f0, 0x00002f73 },
+ { 0x0000e8f4, 0x00002f85 },
+ { 0x0000e8f8, 0x00002f97 },
+ { 0x0000e8fc, 0x00002fa9 },
+ { 0x0000e900, 0x00002fbc },
+ { 0x0000e904, 0x00002fce },
+ { 0x0000e908, 0x00002fe1 },
+ { 0x0000e90c, 0x00002ff4 },
+ { 0x0000e910, 0x00003003 },
+ { 0x0000e914, 0x0000300d },
+ { 0x0000e918, 0x00003017 },
+ { 0x0000e91c, 0x00003021 },
+ { 0x0000e920, 0x0000302b },
+ { 0x0000e924, 0x00003035 },
+ { 0x0000e928, 0x0000303f },
+ { 0x0000e92c, 0x0000304a },
+ { 0x0000e930, 0x00003054 },
+ { 0x0000e934, 0x0000305f },
+ { 0x0000e938, 0x00003069 },
+ { 0x0000e93c, 0x00003074 },
+ { 0x0000e940, 0x0000307f },
+ { 0x0000e944, 0x0000308a },
+ { 0x0000e948, 0x00003095 },
+ { 0x0000e94c, 0x000030a0 },
+ { 0x0000e950, 0x000030ab },
+ { 0x0000e954, 0x000030b6 },
+ { 0x0000e958, 0x000030c2 },
+ { 0x0000e95c, 0x000030cd },
+ { 0x0000e960, 0x000030d9 },
+ { 0x0000e964, 0x000030e5 },
+ { 0x0000e968, 0x000030f1 },
+ { 0x0000e96c, 0x000030fc },
+ { 0x0000e970, 0x00003109 },
+ { 0x0000e974, 0x00003115 },
+ { 0x0000e978, 0x00003121 },
+ { 0x0000e97c, 0x0000312d },
+ { 0x0000e980, 0x0000313a },
+ { 0x0000e984, 0x00003146 },
+ { 0x0000e988, 0x00003153 },
+ { 0x0000e98c, 0x00003160 },
+ { 0x0000e990, 0x0000316d },
+ { 0x0000e994, 0x0000317a },
+ { 0x0000e998, 0x00003187 },
+ { 0x0000e99c, 0x00003194 },
+ { 0x0000e9a0, 0x000031a1 },
+ { 0x0000e9a4, 0x000031af },
+ { 0x0000e9a8, 0x000031bc },
+ { 0x0000e9ac, 0x000031ca },
+ { 0x0000e9b0, 0x000031d8 },
+ { 0x0000e9b4, 0x000031e5 },
+ { 0x0000e9b8, 0x000031f3 },
+ { 0x0000e9bc, 0x00003200 },
+ { 0x0000e9c0, 0x00003208 },
+ { 0x0000e9c4, 0x0000320f },
+ { 0x0000e9c8, 0x00003216 },
+ { 0x0000e9cc, 0x0000321d },
+ { 0x0000e9d0, 0x00003224 },
+ { 0x0000e9d4, 0x0000322c },
+ { 0x0000e9d8, 0x00003233 },
+ { 0x0000e9dc, 0x0000323b },
+ { 0x0000e9e0, 0x00003242 },
+ { 0x0000e9e4, 0x0000324a },
+ { 0x0000e9e8, 0x00003251 },
+ { 0x0000e9ec, 0x00003259 },
+ { 0x0000e9f0, 0x00003261 },
+ { 0x0000e9f4, 0x00003268 },
+ { 0x0000e9f8, 0x00003270 },
+ { 0x0000e9fc, 0x00003278 },
+ { 0x0000ea00, 0x00003280 },
+ { 0x0000ea04, 0x00003288 },
+ { 0x0000ea08, 0x00003290 },
+ { 0x0000ea0c, 0x00003298 },
+ { 0x0000ea10, 0x000032a0 },
+ { 0x0000ea14, 0x000032a9 },
+ { 0x0000ea18, 0x000032b1 },
+ { 0x0000ea1c, 0x000032b9 },
+ { 0x0000ea20, 0x000032c2 },
+ { 0x0000ea24, 0x000032ca },
+ { 0x0000ea28, 0x000032d3 },
+ { 0x0000ea2c, 0x000032db },
+ { 0x0000ea30, 0x000032e4 },
+ { 0x0000ea34, 0x000032ec },
+ { 0x0000ea38, 0x000032f5 },
+ { 0x0000ea3c, 0x000032fe },
+ { 0x0000ea40, 0x00003307 },
+ { 0x0000ea44, 0x00003310 },
+ { 0x0000ea48, 0x00003318 },
+ { 0x0000ea4c, 0x00003321 },
+ { 0x0000ea50, 0x0000332a },
+ { 0x0000ea54, 0x00003334 },
+ { 0x0000ea58, 0x0000333d },
+ { 0x0000ea5c, 0x00003346 },
+ { 0x0000ea60, 0x0000334f },
+ { 0x0000ea64, 0x00003359 },
+ { 0x0000ea68, 0x00003362 },
+ { 0x0000ea6c, 0x0000336b },
+ { 0x0000ea70, 0x00003375 },
+ { 0x0000ea74, 0x0000337e },
+ { 0x0000ea78, 0x00003388 },
+ { 0x0000ea7c, 0x00003392 },
+ { 0x0000ea80, 0x0000339b },
+ { 0x0000ea84, 0x000033a5 },
+ { 0x0000ea88, 0x000033af },
+ { 0x0000ea8c, 0x000033b9 },
+ { 0x0000ea90, 0x000033c3 },
+ { 0x0000ea94, 0x000033cd },
+ { 0x0000ea98, 0x000033d7 },
+ { 0x0000ea9c, 0x000033e1 },
+ { 0x0000eaa0, 0x000033eb },
+ { 0x0000eaa4, 0x000033f5 },
+ { 0x0000eaa8, 0x00003400 },
+ { 0x0000eaac, 0x00003405 },
+ { 0x0000eab0, 0x0000340a },
+ { 0x0000eab4, 0x0000340f },
+ { 0x0000eab8, 0x00003414 },
+ { 0x0000eabc, 0x0000341a },
+ { 0x0000eac0, 0x0000341f },
+ { 0x0000eac4, 0x00003424 },
+ { 0x0000eac8, 0x0000342a },
+ { 0x0000eacc, 0x0000342f },
+ { 0x0000ead0, 0x00003435 },
+ { 0x0000ead4, 0x0000343a },
+ { 0x0000ead8, 0x00003440 },
+ { 0x0000eadc, 0x00003445 },
+ { 0x0000eae0, 0x0000344b },
+ { 0x0000eae4, 0x00003450 },
+ { 0x0000eae8, 0x00003456 },
+ { 0x0000eaec, 0x0000345b },
+ { 0x0000eaf0, 0x00003461 },
+ { 0x0000eaf4, 0x00003467 },
+ { 0x0000eaf8, 0x0000346d },
+ { 0x0000eafc, 0x00003472 },
+ { 0x0000eb00, 0x00003478 },
+ { 0x0000eb04, 0x0000347e },
+ { 0x0000eb08, 0x00003484 },
+ { 0x0000eb0c, 0x0000348a },
+ { 0x0000eb10, 0x0000348f },
+ { 0x0000eb14, 0x00003495 },
+ { 0x0000eb18, 0x0000349b },
+ { 0x0000eb1c, 0x000034a1 },
+ { 0x0000eb20, 0x000034a7 },
+ { 0x0000eb24, 0x000034ad },
+ { 0x0000eb28, 0x000034b3 },
+ { 0x0000eb2c, 0x000034ba },
+ { 0x0000eb30, 0x000034c0 },
+ { 0x0000eb34, 0x000034c6 },
+ { 0x0000eb38, 0x000034cc },
+ { 0x0000eb3c, 0x000034d2 },
+ { 0x0000eb40, 0x000034d8 },
+ { 0x0000eb44, 0x000034df },
+ { 0x0000eb48, 0x000034e5 },
+ { 0x0000eb4c, 0x000034eb },
+ { 0x0000eb50, 0x000034f2 },
+ { 0x0000eb54, 0x000034f8 },
+ { 0x0000eb58, 0x000034ff },
+ { 0x0000eb5c, 0x00003505 },
+ { 0x0000eb60, 0x0000350c },
+ { 0x0000eb64, 0x00003512 },
+ { 0x0000eb68, 0x00003519 },
+ { 0x0000eb6c, 0x0000351f },
+ { 0x0000eb70, 0x00003526 },
+ { 0x0000eb74, 0x0000352c },
+ { 0x0000eb78, 0x00003533 },
+ { 0x0000eb7c, 0x0000353a },
+ { 0x0000eb80, 0x00003540 },
+ { 0x0000eb84, 0x00003547 },
+ { 0x0000eb88, 0x0000354e },
+ { 0x0000eb8c, 0x00003555 },
+ { 0x0000eb90, 0x0000355c },
+ { 0x0000eb94, 0x00003563 },
+ { 0x0000eb98, 0x00003569 },
+ { 0x0000eb9c, 0x00003570 },
+ { 0x0000eba0, 0x00003577 },
+ { 0x0000eba4, 0x0000357e },
+ { 0x0000eba8, 0x00003585 },
+ { 0x0000ebac, 0x0000358c },
+ { 0x0000ebb0, 0x00003594 },
+ { 0x0000ebb4, 0x0000359b },
+ { 0x0000ebb8, 0x000035a2 },
+ { 0x0000ebbc, 0x000035a9 },
+ { 0x0000ebc0, 0x000035b0 },
+ { 0x0000ebc4, 0x000035b7 },
+ { 0x0000ebc8, 0x000035bf },
+ { 0x0000ebcc, 0x000035c6 },
+ { 0x0000ebd0, 0x000035cd },
+ { 0x0000ebd4, 0x000035d5 },
+ { 0x0000ebd8, 0x000035dc },
+ { 0x0000ebdc, 0x000035e4 },
+ { 0x0000ebe0, 0x000035eb },
+ { 0x0000ebe4, 0x000035f2 },
+ { 0x0000ebe8, 0x000035fa },
+ { 0x0000ebec, 0x00003600 },
+ { 0x0000ebf0, 0x00003604 },
+ { 0x0000ebf4, 0x00003608 },
+ { 0x0000ebf8, 0x0000360c },
+ { 0x0000ebfc, 0x00003610 },
+ { 0x0000ec00, 0x00003614 },
+ { 0x0000ec04, 0x00003617 },
+ { 0x0000ec08, 0x0000361b },
+ { 0x0000ec0c, 0x0000361f },
+ { 0x0000ec10, 0x00003623 },
+ { 0x0000ec14, 0x00003627 },
+ { 0x0000ec18, 0x0000362b },
+ { 0x0000ec1c, 0x0000362f },
+ { 0x0000ec20, 0x00003633 },
+ { 0x0000ec24, 0x00003637 },
+ { 0x0000ec28, 0x0000363b },
+ { 0x0000ec2c, 0x0000363f },
+ { 0x0000ec30, 0x00003643 },
+ { 0x0000ec34, 0x00003647 },
+ { 0x0000ec38, 0x0000364b },
+ { 0x0000ec3c, 0x0000364f },
+ { 0x0000ec40, 0x00003653 },
+ { 0x0000ec44, 0x00003657 },
+ { 0x0000ec48, 0x0000365b },
+ { 0x0000ec4c, 0x00003660 },
+ { 0x0000ec50, 0x00003664 },
+ { 0x0000ec54, 0x00003668 },
+ { 0x0000ec58, 0x0000366c },
+ { 0x0000ec5c, 0x00003670 },
+ { 0x0000ec60, 0x00003675 },
+ { 0x0000ec64, 0x00003679 },
+ { 0x0000ec68, 0x0000367d },
+ { 0x0000ec6c, 0x00003681 },
+ { 0x0000ec70, 0x00003686 },
+ { 0x0000ec74, 0x0000368a },
+ { 0x0000ec78, 0x0000368e },
+ { 0x0000ec7c, 0x00003693 },
+ { 0x0000ec80, 0x00003697 },
+ { 0x0000ec84, 0x0000369b },
+ { 0x0000ec88, 0x000036a0 },
+ { 0x0000ec8c, 0x000036a4 },
+ { 0x0000ec90, 0x000036a8 },
+ { 0x0000ec94, 0x000036ad },
+ { 0x0000ec98, 0x000036b1 },
+ { 0x0000ec9c, 0x000036b6 },
+ { 0x0000eca0, 0x000036ba },
+ { 0x0000eca4, 0x000036bf },
+ { 0x0000eca8, 0x000036c3 },
+ { 0x0000ecac, 0x000036c8 },
+ { 0x0000ecb0, 0x000036cc },
+ { 0x0000ecb4, 0x000036d1 },
+ { 0x0000ecb8, 0x000036d5 },
+ { 0x0000ecbc, 0x000036da },
+ { 0x0000ecc0, 0x000036df },
+ { 0x0000ecc4, 0x000036e3 },
+ { 0x0000ecc8, 0x000036e8 },
+ { 0x0000eccc, 0x000036ec },
+ { 0x0000ecd0, 0x000036f1 },
+ { 0x0000ecd4, 0x000036f6 },
+ { 0x0000ecd8, 0x000036fb },
+ { 0x0000ecdc, 0x000036ff },
+ { 0x0000ece0, 0x00003704 },
+ { 0x0000ece4, 0x00003709 },
+ { 0x0000ece8, 0x0000370d },
+ { 0x0000ecec, 0x00003712 },
+ { 0x0000ecf0, 0x00003717 },
+ { 0x0000ecf4, 0x0000371c },
+ { 0x0000ecf8, 0x00003721 },
+ { 0x0000ecfc, 0x00003725 },
+ { 0x0000ed00, 0x0000372a },
+ { 0x0000ed04, 0x0000372f },
+ { 0x0000ed08, 0x00003734 },
+ { 0x0000ed0c, 0x00003739 },
+ { 0x0000ed10, 0x0000373e },
+ { 0x0000ed14, 0x00003743 },
+ { 0x0000ed18, 0x00003748 },
+ { 0x0000ed1c, 0x0000374d },
+ { 0x0000ed20, 0x00003752 },
+ { 0x0000ed24, 0x00003757 },
+ { 0x0000ed28, 0x0000375c },
+ { 0x0000ed2c, 0x00003761 },
+ { 0x0000ed30, 0x00003766 },
+ { 0x0000ed34, 0x0000376b },
+ { 0x0000ed38, 0x00003770 },
+ { 0x0000ed3c, 0x00003775 },
+ { 0x0000ed40, 0x0000377a },
+ { 0x0000ed44, 0x0000377f },
+ { 0x0000ed48, 0x00003784 },
+ { 0x0000ed4c, 0x0000378a },
+ { 0x0000ed50, 0x0000378f },
+ { 0x0000ed54, 0x00003794 },
+ { 0x0000ed58, 0x00003799 },
+ { 0x0000ed5c, 0x0000379e },
+ { 0x0000ed60, 0x000037a4 },
+ { 0x0000ed64, 0x000037a9 },
+ { 0x0000ed68, 0x000037ae },
+ { 0x0000ed6c, 0x000037b3 },
+ { 0x0000ed70, 0x000037b9 },
+ { 0x0000ed74, 0x000037be },
+ { 0x0000ed78, 0x000037c3 },
+ { 0x0000ed7c, 0x000037c9 },
+ { 0x0000ed80, 0x000037ce },
+ { 0x0000ed84, 0x000037d4 },
+ { 0x0000ed88, 0x000037d9 },
+ { 0x0000ed8c, 0x000037de },
+ { 0x0000ed90, 0x000037e4 },
+ { 0x0000ed94, 0x000037e9 },
+ { 0x0000ed98, 0x000037ef },
+ { 0x0000ed9c, 0x000037f4 },
+ { 0x0000eda0, 0x000037fa },
+ { 0x0000eda4, 0x000037ff },
+ { 0x0000eda8, 0x00003802 },
+ { 0x0000edac, 0x00003805 },
+ { 0x0000edb0, 0x00003808 },
+ { 0x0000edb4, 0x0000380a },
+ { 0x0000edb8, 0x0000380d },
+ { 0x0000edbc, 0x00003810 },
+ { 0x0000edc0, 0x00003813 },
+ { 0x0000edc4, 0x00003816 },
+ { 0x0000edc8, 0x00003819 },
+ { 0x0000edcc, 0x0000381b },
+ { 0x0000edd0, 0x0000381e },
+ { 0x0000edd4, 0x00003821 },
+ { 0x0000edd8, 0x00003824 },
+ { 0x0000eddc, 0x00003827 },
+ { 0x0000ede0, 0x0000382a },
+ { 0x0000ede4, 0x0000382d },
+ { 0x0000ede8, 0x00003830 },
+ { 0x0000edec, 0x00003832 },
+ { 0x0000edf0, 0x00003835 },
+ { 0x0000edf4, 0x00003838 },
+ { 0x0000edf8, 0x0000383b },
+ { 0x0000edfc, 0x0000383e },
+ { 0x0000ee00, 0x00003841 },
+ { 0x0000ee04, 0x00003844 },
+ { 0x0000ee08, 0x00003847 },
+ { 0x0000ee0c, 0x0000384a },
+ { 0x0000ee10, 0x0000384d },
+ { 0x0000ee14, 0x00003850 },
+ { 0x0000ee18, 0x00003853 },
+ { 0x0000ee1c, 0x00003856 },
+ { 0x0000ee20, 0x00003859 },
+ { 0x0000ee24, 0x0000385c },
+ { 0x0000ee28, 0x0000385f },
+ { 0x0000ee2c, 0x00003862 },
+ { 0x0000ee30, 0x00003865 },
+ { 0x0000ee34, 0x00003868 },
+ { 0x0000ee38, 0x0000386b },
+ { 0x0000ee3c, 0x0000386e },
+ { 0x0000ee40, 0x00003871 },
+ { 0x0000ee44, 0x00003874 },
+ { 0x0000ee48, 0x00003878 },
+ { 0x0000ee4c, 0x0000387b },
+ { 0x0000ee50, 0x0000387e },
+ { 0x0000ee54, 0x00003881 },
+ { 0x0000ee58, 0x00003884 },
+ { 0x0000ee5c, 0x00003887 },
+ { 0x0000ee60, 0x0000388a },
+ { 0x0000ee64, 0x0000388e },
+ { 0x0000ee68, 0x00003891 },
+ { 0x0000ee6c, 0x00003894 },
+ { 0x0000ee70, 0x00003897 },
+ { 0x0000ee74, 0x0000389a },
+ { 0x0000ee78, 0x0000389d },
+ { 0x0000ee7c, 0x000038a1 },
+ { 0x0000ee80, 0x000038a4 },
+ { 0x0000ee84, 0x000038a7 },
+ { 0x0000ee88, 0x000038aa },
+ { 0x0000ee8c, 0x000038ae },
+ { 0x0000ee90, 0x000038b1 },
+ { 0x0000ee94, 0x000038b4 },
+ { 0x0000ee98, 0x000038b7 },
+ { 0x0000ee9c, 0x000038bb },
+ { 0x0000eea0, 0x000038be },
+ { 0x0000eea4, 0x000038c1 },
+ { 0x0000eea8, 0x000038c4 },
+ { 0x0000eeac, 0x000038c8 },
+ { 0x0000eeb0, 0x000038cb },
+ { 0x0000eeb4, 0x000038ce },
+ { 0x0000eeb8, 0x000038d2 },
+ { 0x0000eebc, 0x000038d5 },
+ { 0x0000eec0, 0x000038d8 },
+ { 0x0000eec4, 0x000038dc },
+ { 0x0000eec8, 0x000038df },
+ { 0x0000eecc, 0x000038e3 },
+ { 0x0000eed0, 0x000038e6 },
+ { 0x0000eed4, 0x000038e9 },
+ { 0x0000eed8, 0x000038ed },
+ { 0x0000eedc, 0x000038f0 },
+ { 0x0000eee0, 0x000038f4 },
+ { 0x0000eee4, 0x000038f7 },
+ { 0x0000eee8, 0x000038fa },
+ { 0x0000eeec, 0x000038fe },
+ { 0x0000eef0, 0x00003901 },
+ { 0x0000eef4, 0x00003905 },
+ { 0x0000eef8, 0x00003908 },
+ { 0x0000eefc, 0x0000390c },
+ { 0x0000ef00, 0x0000390f },
+ { 0x0000ef04, 0x00003913 },
+ { 0x0000ef08, 0x00003916 },
+ { 0x0000ef0c, 0x0000391a },
+ { 0x0000ef10, 0x0000391d },
+ { 0x0000ef14, 0x00003921 },
+ { 0x0000ef18, 0x00003924 },
+ { 0x0000ef1c, 0x00003928 },
+ { 0x0000ef20, 0x0000392b },
+ { 0x0000ef24, 0x0000392f },
+ { 0x0000ef28, 0x00003933 },
+ { 0x0000ef2c, 0x00003936 },
+ { 0x0000ef30, 0x0000393a },
+ { 0x0000ef34, 0x0000393d },
+ { 0x0000ef38, 0x00003941 },
+ { 0x0000ef3c, 0x00003945 },
+ { 0x0000ef40, 0x00003948 },
+ { 0x0000ef44, 0x0000394c },
+ { 0x0000ef48, 0x00003950 },
+ { 0x0000ef4c, 0x00003953 },
+ { 0x0000ef50, 0x00003957 },
+ { 0x0000ef54, 0x0000395b },
+ { 0x0000ef58, 0x0000395e },
+ { 0x0000ef5c, 0x00003962 },
+ { 0x0000ef60, 0x00003966 },
+ { 0x0000ef64, 0x00003969 },
+ { 0x0000ef68, 0x0000396d },
+ { 0x0000ef6c, 0x00003971 },
+ { 0x0000ef70, 0x00003974 },
+ { 0x0000ef74, 0x00003978 },
+ { 0x0000ef78, 0x0000397c },
+ { 0x0000ef7c, 0x00003980 },
+ { 0x0000ef80, 0x00003983 },
+ { 0x0000ef84, 0x00003987 },
+ { 0x0000ef88, 0x0000398b },
+ { 0x0000ef8c, 0x0000398f },
+ { 0x0000ef90, 0x00003993 },
+ { 0x0000ef94, 0x00003996 },
+ { 0x0000ef98, 0x0000399a },
+ { 0x0000ef9c, 0x0000399e },
+ { 0x0000efa0, 0x000039a2 },
+ { 0x0000efa4, 0x000039a6 },
+ { 0x0000efa8, 0x000039aa },
+ { 0x0000efac, 0x000039ad },
+ { 0x0000efb0, 0x000039b1 },
+ { 0x0000efb4, 0x000039b5 },
+ { 0x0000efb8, 0x000039b9 },
+ { 0x0000efbc, 0x000039bd },
+ { 0x0000efc0, 0x000039c1 },
+ { 0x0000efc4, 0x000039c5 },
+ { 0x0000efc8, 0x000039c9 },
+ { 0x0000efcc, 0x000039cd },
+ { 0x0000efd0, 0x000039d1 },
+ { 0x0000efd4, 0x000039d5 },
+ { 0x0000efd8, 0x000039d8 },
+ { 0x0000efdc, 0x000039dc },
+ { 0x0000efe0, 0x000039e0 },
+ { 0x0000efe4, 0x000039e4 },
+ { 0x0000efe8, 0x000039e8 },
+ { 0x0000efec, 0x000039ec },
+ { 0x0000eff0, 0x000039f0 },
+ { 0x0000eff4, 0x000039f4 },
+ { 0x0000eff8, 0x000039f8 },
+ { 0x0000effc, 0x000039fc },
+};
+
+struct data_unit hdr10_opipe_csco[] = {
+ { 0x0000f074, 0x0000000c },
+ { 0x0000f000, 0x00000004 },
+};
diff --git a/drivers/video/fbdev/mxc/ldb.c b/drivers/video/fbdev/mxc/ldb.c
new file mode 100644
index 000000000000..1d6c9e08590c
--- /dev/null
+++ b/drivers/video/fbdev/mxc/ldb.c
@@ -0,0 +1,910 @@
+/*
+ * Copyright (C) 2012-2015 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+/*
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/mfd/syscon.h>
+#include <linux/mfd/syscon/imx6q-iomuxc-gpr.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/types.h>
+#include <video/of_videomode.h>
+#include <video/videomode.h>
+#include "mxc_dispdrv.h"
+
+#define DRIVER_NAME "ldb"
+
+#define LDB_BGREF_RMODE_INT (0x1 << 15)
+
+#define LDB_DI1_VS_POL_ACT_LOW (0x1 << 10)
+#define LDB_DI0_VS_POL_ACT_LOW (0x1 << 9)
+
+#define LDB_BIT_MAP_CH1_JEIDA (0x1 << 8)
+#define LDB_BIT_MAP_CH0_JEIDA (0x1 << 6)
+
+#define LDB_DATA_WIDTH_CH1_24 (0x1 << 7)
+#define LDB_DATA_WIDTH_CH0_24 (0x1 << 5)
+
+#define LDB_CH1_MODE_MASK (0x3 << 2)
+#define LDB_CH1_MODE_EN_TO_DI1 (0x3 << 2)
+#define LDB_CH1_MODE_EN_TO_DI0 (0x1 << 2)
+#define LDB_CH0_MODE_MASK (0x3 << 0)
+#define LDB_CH0_MODE_EN_TO_DI1 (0x3 << 0)
+#define LDB_CH0_MODE_EN_TO_DI0 (0x1 << 0)
+
+#define LDB_SPLIT_MODE_EN (0x1 << 4)
+
+#define INVALID_BUS_REG (~0UL)
+
+struct crtc_mux {
+ enum crtc crtc;
+ u32 val;
+};
+
+struct bus_mux {
+ int reg;
+ int shift;
+ int mask;
+ int crtc_mux_num;
+ const struct crtc_mux *crtcs;
+};
+
+struct ldb_info {
+ bool split_cap;
+ bool dual_cap;
+ bool ext_bgref_cap;
+ bool clk_fixup;
+ int ctrl_reg;
+ int bus_mux_num;
+ const struct bus_mux *buses;
+};
+
+struct ldb_data;
+
+struct ldb_chan {
+ struct ldb_data *ldb;
+ struct fb_info *fbi;
+ struct videomode vm;
+ enum crtc crtc;
+ int chno;
+ bool is_used;
+ bool online;
+};
+
+struct ldb_data {
+ struct regmap *regmap;
+ struct device *dev;
+ struct mxc_dispdrv_handle *mddh;
+ struct ldb_chan chan[2];
+ int bus_mux_num;
+ const struct bus_mux *buses;
+ int primary_chno;
+ int ctrl_reg;
+ u32 ctrl;
+ bool spl_mode;
+ bool dual_mode;
+ bool clk_fixup;
+ struct clk *di_clk[4];
+ struct clk *ldb_di_clk[2];
+ struct clk *div_3_5_clk[2];
+ struct clk *div_7_clk[2];
+ struct clk *div_sel_clk[2];
+};
+
+static const struct crtc_mux imx6q_lvds0_crtc_mux[] = {
+ {
+ .crtc = CRTC_IPU1_DI0,
+ .val = IMX6Q_GPR3_LVDS0_MUX_CTL_IPU1_DI0,
+ }, {
+ .crtc = CRTC_IPU1_DI1,
+ .val = IMX6Q_GPR3_LVDS0_MUX_CTL_IPU1_DI1,
+ }, {
+ .crtc = CRTC_IPU2_DI0,
+ .val = IMX6Q_GPR3_LVDS0_MUX_CTL_IPU2_DI0,
+ }, {
+ .crtc = CRTC_IPU2_DI1,
+ .val = IMX6Q_GPR3_LVDS0_MUX_CTL_IPU2_DI1,
+ }
+};
+
+static const struct crtc_mux imx6q_lvds1_crtc_mux[] = {
+ {
+ .crtc = CRTC_IPU1_DI0,
+ .val = IMX6Q_GPR3_LVDS1_MUX_CTL_IPU1_DI0,
+ }, {
+ .crtc = CRTC_IPU1_DI1,
+ .val = IMX6Q_GPR3_LVDS1_MUX_CTL_IPU1_DI1,
+ }, {
+ .crtc = CRTC_IPU2_DI0,
+ .val = IMX6Q_GPR3_LVDS1_MUX_CTL_IPU2_DI0,
+ }, {
+ .crtc = CRTC_IPU2_DI1,
+ .val = IMX6Q_GPR3_LVDS1_MUX_CTL_IPU2_DI1,
+ }
+};
+
+static const struct bus_mux imx6q_ldb_buses[] = {
+ {
+ .reg = IOMUXC_GPR3,
+ .shift = 6,
+ .mask = IMX6Q_GPR3_LVDS0_MUX_CTL_MASK,
+ .crtc_mux_num = ARRAY_SIZE(imx6q_lvds0_crtc_mux),
+ .crtcs = imx6q_lvds0_crtc_mux,
+ }, {
+ .reg = IOMUXC_GPR3,
+ .shift = 8,
+ .mask = IMX6Q_GPR3_LVDS1_MUX_CTL_MASK,
+ .crtc_mux_num = ARRAY_SIZE(imx6q_lvds1_crtc_mux),
+ .crtcs = imx6q_lvds1_crtc_mux,
+ }
+};
+
+static const struct ldb_info imx6q_ldb_info = {
+ .split_cap = true,
+ .dual_cap = true,
+ .ext_bgref_cap = false,
+ .clk_fixup = false,
+ .ctrl_reg = IOMUXC_GPR2,
+ .bus_mux_num = ARRAY_SIZE(imx6q_ldb_buses),
+ .buses = imx6q_ldb_buses,
+};
+
+static const struct ldb_info imx6qp_ldb_info = {
+ .split_cap = true,
+ .dual_cap = true,
+ .ext_bgref_cap = false,
+ .clk_fixup = true,
+ .ctrl_reg = IOMUXC_GPR2,
+ .bus_mux_num = ARRAY_SIZE(imx6q_ldb_buses),
+ .buses = imx6q_ldb_buses,
+};
+
+static const struct crtc_mux imx6dl_lvds0_crtc_mux[] = {
+ {
+ .crtc = CRTC_IPU1_DI0,
+ .val = IMX6DL_GPR3_LVDS0_MUX_CTL_IPU1_DI0,
+ }, {
+ .crtc = CRTC_IPU1_DI1,
+ .val = IMX6DL_GPR3_LVDS0_MUX_CTL_IPU1_DI1,
+ }, {
+ .crtc = CRTC_LCDIF1,
+ .val = IMX6DL_GPR3_LVDS0_MUX_CTL_LCDIF,
+ }
+};
+
+static const struct crtc_mux imx6dl_lvds1_crtc_mux[] = {
+ {
+ .crtc = CRTC_IPU1_DI0,
+ .val = IMX6DL_GPR3_LVDS1_MUX_CTL_IPU1_DI0,
+ }, {
+ .crtc = CRTC_IPU1_DI1,
+ .val = IMX6DL_GPR3_LVDS1_MUX_CTL_IPU1_DI1,
+ }, {
+ .crtc = CRTC_LCDIF1,
+ .val = IMX6DL_GPR3_LVDS1_MUX_CTL_LCDIF,
+ }
+};
+
+static const struct bus_mux imx6dl_ldb_buses[] = {
+ {
+ .reg = IOMUXC_GPR3,
+ .shift = 6,
+ .mask = IMX6DL_GPR3_LVDS0_MUX_CTL_MASK,
+ .crtc_mux_num = ARRAY_SIZE(imx6dl_lvds0_crtc_mux),
+ .crtcs = imx6dl_lvds0_crtc_mux,
+ }, {
+ .reg = IOMUXC_GPR3,
+ .shift = 8,
+ .mask = IMX6DL_GPR3_LVDS1_MUX_CTL_MASK,
+ .crtc_mux_num = ARRAY_SIZE(imx6dl_lvds1_crtc_mux),
+ .crtcs = imx6dl_lvds1_crtc_mux,
+ }
+};
+
+static const struct ldb_info imx6dl_ldb_info = {
+ .split_cap = true,
+ .dual_cap = true,
+ .ext_bgref_cap = false,
+ .clk_fixup = false,
+ .ctrl_reg = IOMUXC_GPR2,
+ .bus_mux_num = ARRAY_SIZE(imx6dl_ldb_buses),
+ .buses = imx6dl_ldb_buses,
+};
+
+static const struct crtc_mux imx6sx_lvds_crtc_mux[] = {
+ {
+ .crtc = CRTC_LCDIF1,
+ .val = IMX6SX_GPR5_DISP_MUX_LDB_CTRL_LCDIF1,
+ }, {
+ .crtc = CRTC_LCDIF2,
+ .val = IMX6SX_GPR5_DISP_MUX_LDB_CTRL_LCDIF2,
+ }
+};
+
+static const struct bus_mux imx6sx_ldb_buses[] = {
+ {
+ .reg = IOMUXC_GPR5,
+ .shift = 3,
+ .mask = IMX6SX_GPR5_DISP_MUX_LDB_CTRL_MASK,
+ .crtc_mux_num = ARRAY_SIZE(imx6sx_lvds_crtc_mux),
+ .crtcs = imx6sx_lvds_crtc_mux,
+ }
+};
+
+static const struct ldb_info imx6sx_ldb_info = {
+ .split_cap = false,
+ .dual_cap = false,
+ .ext_bgref_cap = false,
+ .clk_fixup = false,
+ .ctrl_reg = IOMUXC_GPR6,
+ .bus_mux_num = ARRAY_SIZE(imx6sx_ldb_buses),
+ .buses = imx6sx_ldb_buses,
+};
+
+static const struct crtc_mux imx53_lvds0_crtc_mux[] = {
+ { .crtc = CRTC_IPU1_DI0, },
+};
+
+static const struct crtc_mux imx53_lvds1_crtc_mux[] = {
+ { .crtc = CRTC_IPU1_DI1, }
+};
+
+static const struct bus_mux imx53_ldb_buses[] = {
+ {
+ .reg = INVALID_BUS_REG,
+ .crtc_mux_num = ARRAY_SIZE(imx53_lvds0_crtc_mux),
+ .crtcs = imx53_lvds0_crtc_mux,
+ }, {
+ .reg = INVALID_BUS_REG,
+ .crtc_mux_num = ARRAY_SIZE(imx53_lvds1_crtc_mux),
+ .crtcs = imx53_lvds1_crtc_mux,
+ }
+};
+
+static const struct ldb_info imx53_ldb_info = {
+ .split_cap = true,
+ .dual_cap = false,
+ .ext_bgref_cap = true,
+ .clk_fixup = false,
+ .ctrl_reg = IOMUXC_GPR2,
+ .bus_mux_num = ARRAY_SIZE(imx53_ldb_buses),
+ .buses = imx53_ldb_buses,
+};
+
+static const struct of_device_id ldb_dt_ids[] = {
+ { .compatible = "fsl,imx6qp-ldb", .data = &imx6qp_ldb_info, },
+ { .compatible = "fsl,imx6q-ldb", .data = &imx6q_ldb_info, },
+ { .compatible = "fsl,imx6dl-ldb", .data = &imx6dl_ldb_info, },
+ { .compatible = "fsl,imx6sx-ldb", .data = &imx6sx_ldb_info, },
+ { .compatible = "fsl,imx53-ldb", .data = &imx53_ldb_info, },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, ldb_dt_ids);
+
+static int ldb_init(struct mxc_dispdrv_handle *mddh,
+ struct mxc_dispdrv_setting *setting)
+{
+ struct ldb_data *ldb = mxc_dispdrv_getdata(mddh);
+ struct device *dev = ldb->dev;
+ struct fb_info *fbi = setting->fbi;
+ struct ldb_chan *chan;
+ struct fb_videomode fb_vm;
+ int chno;
+
+ chno = ldb->chan[ldb->primary_chno].is_used ?
+ !ldb->primary_chno : ldb->primary_chno;
+
+ chan = &ldb->chan[chno];
+
+ if (chan->is_used) {
+ dev_err(dev, "LVDS channel%d is already used\n", chno);
+ return -EBUSY;
+ }
+ if (!chan->online) {
+ dev_err(dev, "LVDS channel%d is not online\n", chno);
+ return -ENODEV;
+ }
+
+ chan->is_used = true;
+
+ chan->fbi = fbi;
+
+ fb_videomode_from_videomode(&chan->vm, &fb_vm);
+ fb_videomode_to_var(&fbi->var, &fb_vm);
+
+ setting->crtc = chan->crtc;
+
+ return 0;
+}
+
+static int get_di_clk_id(struct ldb_chan chan, int *id)
+{
+ struct ldb_data *ldb = chan.ldb;
+ int i = 0, chno = chan.chno, mask, shift;
+ enum crtc crtc;
+ u32 val;
+
+ /* no pre-muxing, such as mx53 */
+ if (ldb->buses[chno].reg == INVALID_BUS_REG) {
+ *id = chno;
+ return 0;
+ }
+
+ for (; i < ldb->buses[chno].crtc_mux_num; i++) {
+ crtc = ldb->buses[chno].crtcs[i].crtc;
+ val = ldb->buses[chno].crtcs[i].val;
+ mask = ldb->buses[chno].mask;
+ shift = ldb->buses[chno].shift;
+ if (chan.crtc == crtc) {
+ *id = (val & mask) >> shift;
+ return 0;
+ }
+ }
+
+ return -EINVAL;
+}
+
+static int get_mux_val(struct bus_mux bus_mux, enum crtc crtc,
+ u32 *mux_val)
+{
+ int i = 0;
+
+ for (; i < bus_mux.crtc_mux_num; i++)
+ if (bus_mux.crtcs[i].crtc == crtc) {
+ *mux_val = bus_mux.crtcs[i].val;
+ return 0;
+ }
+
+ return -EINVAL;
+}
+
+static int find_ldb_chno(struct ldb_data *ldb,
+ struct fb_info *fbi, int *chno)
+{
+ struct device *dev = ldb->dev;
+ int i = 0;
+
+ for (; i < 2; i++)
+ if (ldb->chan[i].fbi == fbi) {
+ *chno = ldb->chan[i].chno;
+ return 0;
+ }
+ dev_err(dev, "failed to find channel number\n");
+ return -EINVAL;
+}
+
+static void ldb_disable(struct mxc_dispdrv_handle *mddh,
+ struct fb_info *fbi);
+
+static int ldb_setup(struct mxc_dispdrv_handle *mddh,
+ struct fb_info *fbi)
+{
+ struct ldb_data *ldb = mxc_dispdrv_getdata(mddh);
+ struct ldb_chan chan;
+ struct device *dev = ldb->dev;
+ struct clk *ldb_di_parent, *ldb_di_sel, *ldb_di_sel_parent;
+ struct clk *other_ldb_di_sel = NULL;
+ struct bus_mux bus_mux;
+ int ret = 0, id = 0, chno, other_chno;
+ unsigned long serial_clk;
+ u32 mux_val;
+
+ ret = find_ldb_chno(ldb, fbi, &chno);
+ if (ret < 0)
+ return ret;
+
+ other_chno = chno ? 0 : 1;
+
+ chan = ldb->chan[chno];
+
+ bus_mux = ldb->buses[chno];
+
+ ret = get_di_clk_id(chan, &id);
+ if (ret < 0) {
+ dev_err(dev, "failed to get ch%d di clk id\n",
+ chan.chno);
+ return ret;
+ }
+
+ ret = get_mux_val(bus_mux, chan.crtc, &mux_val);
+ if (ret < 0) {
+ dev_err(dev, "failed to get ch%d mux val\n",
+ chan.chno);
+ return ret;
+ }
+
+
+ if (ldb->clk_fixup) {
+ /*
+ * ldb_di_sel_parent(plls) -> ldb_di_sel -> ldb_di[chno] ->
+ *
+ * -> div_3_5[chno] ->
+ * -> | |-> div_sel[chno] -> di[id]
+ * -> div_7[chno] ->
+ */
+ clk_set_parent(ldb->di_clk[id], ldb->div_sel_clk[chno]);
+ } else {
+ /*
+ * ldb_di_sel_parent(plls) -> ldb_di_sel ->
+ *
+ * -> div_3_5[chno] ->
+ * -> | |-> div_sel[chno] ->
+ * -> div_7[chno] ->
+ *
+ * -> ldb_di[chno] -> di[id]
+ */
+ clk_set_parent(ldb->di_clk[id], ldb->ldb_di_clk[chno]);
+ }
+ ldb_di_parent = ldb->spl_mode ? ldb->div_3_5_clk[chno] :
+ ldb->div_7_clk[chno];
+ clk_set_parent(ldb->div_sel_clk[chno], ldb_di_parent);
+ ldb_di_sel = clk_get_parent(ldb_di_parent);
+ ldb_di_sel_parent = clk_get_parent(ldb_di_sel);
+ serial_clk = ldb->spl_mode ? chan.vm.pixelclock * 7 / 2 :
+ chan.vm.pixelclock * 7;
+ clk_set_rate(ldb_di_sel_parent, serial_clk);
+
+ /*
+ * split mode or dual mode:
+ * clock tree for the other channel
+ */
+ if (ldb->spl_mode) {
+ clk_set_parent(ldb->div_sel_clk[other_chno],
+ ldb->div_3_5_clk[other_chno]);
+ other_ldb_di_sel =
+ clk_get_parent(ldb->div_3_5_clk[other_chno]);;
+ }
+
+ if (ldb->dual_mode) {
+ clk_set_parent(ldb->div_sel_clk[other_chno],
+ ldb->div_7_clk[other_chno]);
+ other_ldb_di_sel =
+ clk_get_parent(ldb->div_7_clk[other_chno]);;
+ }
+
+ if (ldb->spl_mode || ldb->dual_mode)
+ clk_set_parent(other_ldb_di_sel, ldb_di_sel_parent);
+
+ if (!(chan.fbi->var.sync & FB_SYNC_VERT_HIGH_ACT)) {
+ if (ldb->spl_mode && bus_mux.reg == INVALID_BUS_REG)
+ /* no pre-muxing, such as mx53 */
+ ldb->ctrl |= (id == 0 ? LDB_DI0_VS_POL_ACT_LOW :
+ LDB_DI1_VS_POL_ACT_LOW);
+ else
+ ldb->ctrl |= (chno == 0 ? LDB_DI0_VS_POL_ACT_LOW :
+ LDB_DI1_VS_POL_ACT_LOW);
+ }
+
+ if (bus_mux.reg != INVALID_BUS_REG)
+ regmap_update_bits(ldb->regmap, bus_mux.reg,
+ bus_mux.mask, mux_val);
+
+ regmap_write(ldb->regmap, ldb->ctrl_reg, ldb->ctrl);
+
+ /* disable channel for correct sequence */
+ ldb_disable(mddh, fbi);
+
+ return ret;
+}
+
+static int ldb_enable(struct mxc_dispdrv_handle *mddh,
+ struct fb_info *fbi)
+{
+ struct ldb_data *ldb = mxc_dispdrv_getdata(mddh);
+ struct ldb_chan chan;
+ struct device *dev = ldb->dev;
+ struct bus_mux bus_mux;
+ int ret = 0, id = 0, chno, other_chno;
+
+ ret = find_ldb_chno(ldb, fbi, &chno);
+ if (ret < 0)
+ return ret;
+
+ chan = ldb->chan[chno];
+
+ bus_mux = ldb->buses[chno];
+
+ if (ldb->spl_mode || ldb->dual_mode) {
+ other_chno = chno ? 0 : 1;
+ clk_prepare_enable(ldb->ldb_di_clk[other_chno]);
+ }
+
+ if ((ldb->spl_mode || ldb->dual_mode) &&
+ bus_mux.reg == INVALID_BUS_REG) {
+ /* no pre-muxing, such as mx53 */
+ ret = get_di_clk_id(chan, &id);
+ if (ret < 0) {
+ dev_err(dev, "failed to get ch%d di clk id\n",
+ chan.chno);
+ return ret;
+ }
+
+ ldb->ctrl |= id ?
+ (LDB_CH0_MODE_EN_TO_DI1 | LDB_CH1_MODE_EN_TO_DI1) :
+ (LDB_CH0_MODE_EN_TO_DI0 | LDB_CH1_MODE_EN_TO_DI0);
+ } else {
+ if (ldb->spl_mode || ldb->dual_mode)
+ ldb->ctrl |= LDB_CH0_MODE_EN_TO_DI0 |
+ LDB_CH1_MODE_EN_TO_DI0;
+ else
+ ldb->ctrl |= chno ? LDB_CH1_MODE_EN_TO_DI1 :
+ LDB_CH0_MODE_EN_TO_DI0;
+ }
+
+ regmap_write(ldb->regmap, ldb->ctrl_reg, ldb->ctrl);
+ return 0;
+}
+
+static void ldb_disable(struct mxc_dispdrv_handle *mddh,
+ struct fb_info *fbi)
+{
+ struct ldb_data *ldb = mxc_dispdrv_getdata(mddh);
+ int ret, chno, other_chno;
+
+ ret = find_ldb_chno(ldb, fbi, &chno);
+ if (ret < 0)
+ return;
+
+ if (ldb->spl_mode || ldb->dual_mode) {
+ ldb->ctrl &= ~(LDB_CH1_MODE_MASK | LDB_CH0_MODE_MASK);
+ other_chno = chno ? 0 : 1;
+ clk_disable_unprepare(ldb->ldb_di_clk[other_chno]);
+ } else {
+ ldb->ctrl &= ~(chno ? LDB_CH1_MODE_MASK :
+ LDB_CH0_MODE_MASK);
+ }
+
+ regmap_write(ldb->regmap, ldb->ctrl_reg, ldb->ctrl);
+ return;
+}
+
+static struct mxc_dispdrv_driver ldb_drv = {
+ .name = DRIVER_NAME,
+ .init = ldb_init,
+ .setup = ldb_setup,
+ .enable = ldb_enable,
+ .disable = ldb_disable
+};
+
+enum {
+ LVDS_BIT_MAP_SPWG,
+ LVDS_BIT_MAP_JEIDA,
+};
+
+static const char *ldb_bit_mappings[] = {
+ [LVDS_BIT_MAP_SPWG] = "spwg",
+ [LVDS_BIT_MAP_JEIDA] = "jeida",
+};
+
+static int of_get_data_mapping(struct device_node *np)
+{
+ const char *bm;
+ int ret, i;
+
+ ret = of_property_read_string(np, "fsl,data-mapping", &bm);
+ if (ret < 0)
+ return ret;
+
+ for (i = 0; i < ARRAY_SIZE(ldb_bit_mappings); i++)
+ if (!strcasecmp(bm, ldb_bit_mappings[i]))
+ return i;
+
+ return -EINVAL;
+}
+
+static const char *ldb_crtc_mappings[] = {
+ [CRTC_IPU_DI0] = "ipu-di0",
+ [CRTC_IPU_DI1] = "ipu-di1",
+ [CRTC_IPU1_DI0] = "ipu1-di0",
+ [CRTC_IPU1_DI1] = "ipu1-di1",
+ [CRTC_IPU2_DI0] = "ipu2-di0",
+ [CRTC_IPU2_DI1] = "ipu2-di1",
+ [CRTC_LCDIF] = "lcdif",
+ [CRTC_LCDIF1] = "lcdif1",
+ [CRTC_LCDIF2] = "lcdif2",
+};
+
+static enum crtc of_get_crtc_mapping(struct device_node *np)
+{
+ const char *cm;
+ enum crtc i;
+ int ret;
+
+ ret = of_property_read_string(np, "crtc", &cm);
+ if (ret < 0)
+ return ret;
+
+ for (i = 0; i < ARRAY_SIZE(ldb_crtc_mappings); i++)
+ if (!strcasecmp(cm, ldb_crtc_mappings[i])) {
+ switch (i) {
+ case CRTC_IPU_DI0:
+ i = CRTC_IPU1_DI0;
+ break;
+ case CRTC_IPU_DI1:
+ i = CRTC_IPU1_DI1;
+ break;
+ case CRTC_LCDIF:
+ i = CRTC_LCDIF1;
+ break;
+ default:
+ break;
+ }
+ return i;
+ }
+
+ return -EINVAL;
+}
+
+static int mux_count(struct ldb_data *ldb)
+{
+ int i, j, count = 0;
+ bool should_count[CRTC_MAX];
+ enum crtc crtc;
+
+ for (i = 0; i < CRTC_MAX; i++)
+ should_count[i] = true;
+
+ for (i = 0; i < ldb->bus_mux_num; i++) {
+ for (j = 0; j < ldb->buses[i].crtc_mux_num; j++) {
+ crtc = ldb->buses[i].crtcs[j].crtc;
+ if (should_count[crtc]) {
+ count++;
+ should_count[crtc] = false;
+ }
+ }
+ }
+
+ return count;
+}
+
+static bool is_valid_crtc(struct ldb_data *ldb, enum crtc crtc,
+ int chno)
+{
+ int i = 0;
+
+ if (chno > ldb->bus_mux_num - 1)
+ return false;
+
+ for (; i < ldb->buses[chno].crtc_mux_num; i++)
+ if (ldb->buses[chno].crtcs[i].crtc == crtc)
+ return true;
+
+ return false;
+}
+
+static int ldb_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ const struct of_device_id *of_id =
+ of_match_device(ldb_dt_ids, dev);
+ const struct ldb_info *ldb_info =
+ (const struct ldb_info *)of_id->data;
+ struct device_node *np = dev->of_node, *child;
+ struct ldb_data *ldb;
+ bool ext_ref;
+ int i, data_width, mapping, child_count = 0;
+ char clkname[16];
+
+ ldb = devm_kzalloc(dev, sizeof(*ldb), GFP_KERNEL);
+ if (!ldb)
+ return -ENOMEM;
+
+ ldb->regmap = syscon_regmap_lookup_by_phandle(np, "gpr");
+ if (IS_ERR(ldb->regmap)) {
+ dev_err(dev, "failed to get parent regmap\n");
+ return PTR_ERR(ldb->regmap);
+ }
+
+ ldb->dev = dev;
+ ldb->bus_mux_num = ldb_info->bus_mux_num;
+ ldb->buses = ldb_info->buses;
+ ldb->ctrl_reg = ldb_info->ctrl_reg;
+ ldb->clk_fixup = ldb_info->clk_fixup;
+ ldb->primary_chno = -1;
+
+ ext_ref = of_property_read_bool(np, "ext-ref");
+ if (!ext_ref && ldb_info->ext_bgref_cap)
+ ldb->ctrl |= LDB_BGREF_RMODE_INT;
+
+ ldb->spl_mode = of_property_read_bool(np, "split-mode");
+ if (ldb->spl_mode) {
+ if (ldb_info->split_cap) {
+ ldb->ctrl |= LDB_SPLIT_MODE_EN;
+ dev_info(dev, "split mode\n");
+ } else {
+ dev_err(dev, "cannot support split mode\n");
+ return -EINVAL;
+ }
+ }
+
+ ldb->dual_mode = of_property_read_bool(np, "dual-mode");
+ if (ldb->dual_mode) {
+ if (ldb_info->dual_cap) {
+ dev_info(dev, "dual mode\n");
+ } else {
+ dev_err(dev, "cannot support dual mode\n");
+ return -EINVAL;
+ }
+ }
+
+ if (ldb->dual_mode && ldb->spl_mode) {
+ dev_err(dev, "cannot support dual mode and split mode "
+ "simultaneously\n");
+ return -EINVAL;
+ }
+
+ for (i = 0; i < mux_count(ldb); i++) {
+ sprintf(clkname, "di%d_sel", i);
+ ldb->di_clk[i] = devm_clk_get(dev, clkname);
+ if (IS_ERR(ldb->di_clk[i])) {
+ dev_err(dev, "failed to get clk %s\n", clkname);
+ return PTR_ERR(ldb->di_clk[i]);
+ }
+ }
+
+ for_each_child_of_node(np, child) {
+ struct ldb_chan *chan;
+ enum crtc crtc;
+ bool is_primary;
+ int ret;
+
+ ret = of_property_read_u32(child, "reg", &i);
+ if (ret || i < 0 || i > 1 || i >= ldb->bus_mux_num) {
+ dev_err(dev, "wrong LVDS channel number\n");
+ return -EINVAL;
+ }
+
+ if ((ldb->spl_mode || ldb->dual_mode) && i > 0) {
+ dev_warn(dev, "split mode or dual mode, ignoring "
+ "second output\n");
+ continue;
+ }
+
+ if (!of_device_is_available(child))
+ continue;
+
+ if (++child_count > ldb->bus_mux_num) {
+ dev_err(dev, "too many LVDS channels\n");
+ return -EINVAL;
+ }
+
+ chan = &ldb->chan[i];
+ chan->chno = i;
+ chan->ldb = ldb;
+ chan->online = true;
+
+ is_primary = of_property_read_bool(child, "primary");
+
+ if (ldb->bus_mux_num == 1 || (ldb->primary_chno == -1 &&
+ (is_primary || ldb->spl_mode || ldb->dual_mode)))
+ ldb->primary_chno = chan->chno;
+
+ ret = of_property_read_u32(child, "fsl,data-width",
+ &data_width);
+ if (ret || (data_width != 18 && data_width != 24)) {
+ dev_err(dev, "data width not specified or invalid\n");
+ return -EINVAL;
+ }
+
+ mapping = of_get_data_mapping(child);
+ switch (mapping) {
+ case LVDS_BIT_MAP_SPWG:
+ if (data_width == 24) {
+ if (i == 0 || ldb->spl_mode || ldb->dual_mode)
+ ldb->ctrl |= LDB_DATA_WIDTH_CH0_24;
+ if (i == 1 || ldb->spl_mode || ldb->dual_mode)
+ ldb->ctrl |= LDB_DATA_WIDTH_CH1_24;
+ }
+ break;
+ case LVDS_BIT_MAP_JEIDA:
+ if (data_width == 18) {
+ dev_err(dev, "JEIDA only support 24bit\n");
+ return -EINVAL;
+ }
+ if (i == 0 || ldb->spl_mode || ldb->dual_mode)
+ ldb->ctrl |= LDB_DATA_WIDTH_CH0_24 |
+ LDB_BIT_MAP_CH0_JEIDA;
+ if (i == 1 || ldb->spl_mode || ldb->dual_mode)
+ ldb->ctrl |= LDB_DATA_WIDTH_CH1_24 |
+ LDB_BIT_MAP_CH1_JEIDA;
+ break;
+ default:
+ dev_err(dev, "data mapping not specified or invalid\n");
+ return -EINVAL;
+ }
+
+ crtc = of_get_crtc_mapping(child);
+ if (is_valid_crtc(ldb, crtc, chan->chno)) {
+ ldb->chan[i].crtc = crtc;
+ } else {
+ dev_err(dev, "crtc not specified or invalid\n");
+ return -EINVAL;
+ }
+
+ ret = of_get_videomode(child, &chan->vm, 0);
+ if (ret)
+ return -EINVAL;
+
+ sprintf(clkname, "ldb_di%d", i);
+ ldb->ldb_di_clk[i] = devm_clk_get(dev, clkname);
+ if (IS_ERR(ldb->ldb_di_clk[i])) {
+ dev_err(dev, "failed to get clk %s\n", clkname);
+ return PTR_ERR(ldb->ldb_di_clk[i]);
+ }
+
+ sprintf(clkname, "ldb_di%d_div_3_5", i);
+ ldb->div_3_5_clk[i] = devm_clk_get(dev, clkname);
+ if (IS_ERR(ldb->div_3_5_clk[i])) {
+ dev_err(dev, "failed to get clk %s\n", clkname);
+ return PTR_ERR(ldb->div_3_5_clk[i]);
+ }
+
+ sprintf(clkname, "ldb_di%d_div_7", i);
+ ldb->div_7_clk[i] = devm_clk_get(dev, clkname);
+ if (IS_ERR(ldb->div_7_clk[i])) {
+ dev_err(dev, "failed to get clk %s\n", clkname);
+ return PTR_ERR(ldb->div_7_clk[i]);
+ }
+
+ sprintf(clkname, "ldb_di%d_div_sel", i);
+ ldb->div_sel_clk[i] = devm_clk_get(dev, clkname);
+ if (IS_ERR(ldb->div_sel_clk[i])) {
+ dev_err(dev, "failed to get clk %s\n", clkname);
+ return PTR_ERR(ldb->div_sel_clk[i]);
+ }
+ }
+
+ if (child_count == 0) {
+ dev_err(dev, "failed to find valid LVDS channel\n");
+ return -EINVAL;
+ }
+
+ if (ldb->primary_chno == -1) {
+ dev_err(dev, "failed to know primary channel\n");
+ return -EINVAL;
+ }
+
+ ldb->mddh = mxc_dispdrv_register(&ldb_drv);
+ mxc_dispdrv_setdata(ldb->mddh, ldb);
+ dev_set_drvdata(&pdev->dev, ldb);
+
+ return 0;
+}
+
+static int ldb_remove(struct platform_device *pdev)
+{
+ struct ldb_data *ldb = dev_get_drvdata(&pdev->dev);
+
+ mxc_dispdrv_puthandle(ldb->mddh);
+ mxc_dispdrv_unregister(ldb->mddh);
+ return 0;
+}
+
+static struct platform_driver ldb_driver = {
+ .driver = {
+ .name = DRIVER_NAME,
+ .of_match_table = ldb_dt_ids,
+ },
+ .probe = ldb_probe,
+ .remove = ldb_remove,
+};
+
+module_platform_driver(ldb_driver);
+
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("LDB driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:" DRIVER_NAME);
diff --git a/drivers/video/fbdev/mxc/mipi_dsi.c b/drivers/video/fbdev/mxc/mipi_dsi.c
new file mode 100644
index 000000000000..68a9bfa2aa9f
--- /dev/null
+++ b/drivers/video/fbdev/mxc/mipi_dsi.c
@@ -0,0 +1,1039 @@
+/*
+ * Copyright (C) 2011-2015 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/console.h>
+#include <linux/io.h>
+#include <linux/bitops.h>
+#include <linux/ipu.h>
+#include <linux/mfd/syscon.h>
+#include <linux/mfd/syscon/imx6q-iomuxc-gpr.h>
+#include <linux/mipi_dsi.h>
+#include <linux/module.h>
+#include <linux/mxcfb.h>
+#include <linux/backlight.h>
+#include <linux/of_device.h>
+#include <linux/of_gpio.h>
+#include <linux/regulator/consumer.h>
+#include <linux/spinlock.h>
+#include <linux/delay.h>
+#include <video/mipi_display.h>
+
+#include "mipi_dsi.h"
+
+#define DISPDRV_MIPI "mipi_dsi"
+#define ROUND_UP(x) ((x)+1)
+#define NS2PS_RATIO (1000)
+#define NUMBER_OF_CHUNKS (0x8)
+#define NULL_PKT_SIZE (0x8)
+#define PHY_BTA_MAXTIME (0xd00)
+#define PHY_LP2HS_MAXTIME (0x40)
+#define PHY_HS2LP_MAXTIME (0x40)
+#define PHY_STOP_WAIT_TIME (0x20)
+#define DSI_CLKMGR_CFG_CLK_DIV (0x107)
+#define DSI_GEN_PLD_DATA_BUF_ENTRY (0x10)
+#define MIPI_MUX_CTRL(v) (((v) & 0x3) << 4)
+#define MIPI_LCD_SLEEP_MODE_DELAY (120)
+#define MIPI_DSI_REG_RW_TIMEOUT (20)
+#define MIPI_DSI_PHY_TIMEOUT (10)
+
+static struct mipi_dsi_match_lcd mipi_dsi_lcd_db[] = {
+#ifdef CONFIG_FB_MXC_TRULY_WVGA_SYNC_PANEL
+ {
+ "TRULY-WVGA",
+ {mipid_hx8369_get_lcd_videomode, mipid_hx8369_lcd_setup}
+ },
+#endif
+ {
+ "", {NULL, NULL}
+ }
+};
+
+struct _mipi_dsi_phy_pll_clk {
+ u32 max_phy_clk;
+ u32 config;
+};
+
+/* configure data for DPHY PLL 27M reference clk out */
+static const struct _mipi_dsi_phy_pll_clk mipi_dsi_phy_pll_clk_table[] = {
+ {1000, 0x74}, /* 950-1000MHz */
+ {950, 0x54}, /* 900-950Mhz */
+ {900, 0x34}, /* 850-900Mhz */
+ {850, 0x14}, /* 800-850MHz */
+ {800, 0x32}, /* 750-800MHz */
+ {750, 0x12}, /* 700-750Mhz */
+ {700, 0x30}, /* 650-700Mhz */
+ {650, 0x10}, /* 600-650MHz */
+ {600, 0x2e}, /* 550-600MHz */
+ {550, 0x0e}, /* 500-550Mhz */
+ {500, 0x2c}, /* 450-500Mhz */
+ {450, 0x0c}, /* 400-450MHz */
+ {400, 0x4a}, /* 360-400MHz */
+ {360, 0x2a}, /* 330-360Mhz */
+ {330, 0x48}, /* 300-330Mhz */
+ {300, 0x28}, /* 270-300MHz */
+ {270, 0x08}, /* 250-270MHz */
+ {250, 0x46}, /* 240-250Mhz */
+ {240, 0x26}, /* 210-240Mhz */
+ {210, 0x06}, /* 200-210MHz */
+ {200, 0x44}, /* 180-200MHz */
+ {180, 0x24}, /* 160-180MHz */
+ {160, 0x04}, /* 150-160MHz */
+};
+
+static int valid_mode(int pixel_fmt)
+{
+ return ((pixel_fmt == IPU_PIX_FMT_RGB24) ||
+ (pixel_fmt == IPU_PIX_FMT_BGR24) ||
+ (pixel_fmt == IPU_PIX_FMT_RGB666) ||
+ (pixel_fmt == IPU_PIX_FMT_RGB565) ||
+ (pixel_fmt == IPU_PIX_FMT_BGR666) ||
+ (pixel_fmt == IPU_PIX_FMT_RGB332));
+}
+
+static inline void mipi_dsi_read_register(struct mipi_dsi_info *mipi_dsi,
+ u32 reg, u32 *val)
+{
+ *val = ioread32(mipi_dsi->mmio_base + reg);
+ dev_dbg(&mipi_dsi->pdev->dev, "read_reg:0x%02x, val:0x%08x.\n",
+ reg, *val);
+}
+
+static inline void mipi_dsi_write_register(struct mipi_dsi_info *mipi_dsi,
+ u32 reg, u32 val)
+{
+ iowrite32(val, mipi_dsi->mmio_base + reg);
+ dev_dbg(&mipi_dsi->pdev->dev, "\t\twrite_reg:0x%02x, val:0x%08x.\n",
+ reg, val);
+}
+
+static int mipi_dsi_pkt_write(struct mipi_dsi_info *mipi_dsi,
+ u8 data_type, const u32 *buf, int len)
+{
+ u32 val;
+ u32 status = 0;
+ int write_len = len;
+ uint32_t timeout = 0;
+
+ if (len) {
+ /* generic long write command */
+ while (len / DSI_GEN_PLD_DATA_BUF_SIZE) {
+ mipi_dsi_write_register(mipi_dsi,
+ MIPI_DSI_GEN_PLD_DATA, *buf);
+ buf++;
+ len -= DSI_GEN_PLD_DATA_BUF_SIZE;
+ mipi_dsi_read_register(mipi_dsi,
+ MIPI_DSI_CMD_PKT_STATUS, &status);
+ while ((status & DSI_CMD_PKT_STATUS_GEN_PLD_W_FULL) ==
+ DSI_CMD_PKT_STATUS_GEN_PLD_W_FULL) {
+ msleep(1);
+ timeout++;
+ if (timeout == MIPI_DSI_REG_RW_TIMEOUT)
+ return -EIO;
+ mipi_dsi_read_register(mipi_dsi,
+ MIPI_DSI_CMD_PKT_STATUS, &status);
+ }
+ }
+ /* write the remainder bytes */
+ if (len > 0) {
+ while ((status & DSI_CMD_PKT_STATUS_GEN_PLD_W_FULL) ==
+ DSI_CMD_PKT_STATUS_GEN_PLD_W_FULL) {
+ msleep(1);
+ timeout++;
+ if (timeout == MIPI_DSI_REG_RW_TIMEOUT)
+ return -EIO;
+ mipi_dsi_read_register(mipi_dsi,
+ MIPI_DSI_CMD_PKT_STATUS, &status);
+ }
+ mipi_dsi_write_register(mipi_dsi,
+ MIPI_DSI_GEN_PLD_DATA, *buf);
+ }
+
+ val = data_type | ((write_len & DSI_GEN_HDR_DATA_MASK)
+ << DSI_GEN_HDR_DATA_SHIFT);
+ } else {
+ /* generic short write command */
+ val = data_type | ((*buf & DSI_GEN_HDR_DATA_MASK)
+ << DSI_GEN_HDR_DATA_SHIFT);
+ }
+
+ mipi_dsi_read_register(mipi_dsi, MIPI_DSI_CMD_PKT_STATUS, &status);
+ while ((status & DSI_CMD_PKT_STATUS_GEN_CMD_FULL) ==
+ DSI_CMD_PKT_STATUS_GEN_CMD_FULL) {
+ msleep(1);
+ timeout++;
+ if (timeout == MIPI_DSI_REG_RW_TIMEOUT)
+ return -EIO;
+ mipi_dsi_read_register(mipi_dsi, MIPI_DSI_CMD_PKT_STATUS,
+ &status);
+ }
+ mipi_dsi_write_register(mipi_dsi, MIPI_DSI_GEN_HDR, val);
+
+ mipi_dsi_read_register(mipi_dsi, MIPI_DSI_CMD_PKT_STATUS, &status);
+ while (!((status & DSI_CMD_PKT_STATUS_GEN_CMD_EMPTY) ==
+ DSI_CMD_PKT_STATUS_GEN_CMD_EMPTY) ||
+ !((status & DSI_CMD_PKT_STATUS_GEN_PLD_W_EMPTY) ==
+ DSI_CMD_PKT_STATUS_GEN_PLD_W_EMPTY)) {
+ msleep(1);
+ timeout++;
+ if (timeout == MIPI_DSI_REG_RW_TIMEOUT)
+ return -EIO;
+ mipi_dsi_read_register(mipi_dsi, MIPI_DSI_CMD_PKT_STATUS,
+ &status);
+ }
+
+ return 0;
+}
+
+static int mipi_dsi_pkt_read(struct mipi_dsi_info *mipi_dsi,
+ u8 data_type, u32 *buf, int len)
+{
+ u32 val;
+ int read_len = 0;
+ uint32_t timeout = 0;
+
+ if (!len) {
+ mipi_dbg("%s, len = 0 invalid error!\n", __func__);
+ return -EINVAL;
+ }
+
+ val = data_type | ((*buf & DSI_GEN_HDR_DATA_MASK)
+ << DSI_GEN_HDR_DATA_SHIFT);
+ memset(buf, 0, len);
+ mipi_dsi_write_register(mipi_dsi, MIPI_DSI_GEN_HDR, val);
+
+ /* wait for cmd to sent out */
+ mipi_dsi_read_register(mipi_dsi, MIPI_DSI_CMD_PKT_STATUS, &val);
+ while ((val & DSI_CMD_PKT_STATUS_GEN_RD_CMD_BUSY) !=
+ DSI_CMD_PKT_STATUS_GEN_RD_CMD_BUSY) {
+ msleep(1);
+ timeout++;
+ if (timeout == MIPI_DSI_REG_RW_TIMEOUT)
+ return -EIO;
+ mipi_dsi_read_register(mipi_dsi, MIPI_DSI_CMD_PKT_STATUS,
+ &val);
+ }
+ /* wait for entire response stroed in FIFO */
+ while ((val & DSI_CMD_PKT_STATUS_GEN_RD_CMD_BUSY) ==
+ DSI_CMD_PKT_STATUS_GEN_RD_CMD_BUSY) {
+ msleep(1);
+ timeout++;
+ if (timeout == MIPI_DSI_REG_RW_TIMEOUT)
+ return -EIO;
+ mipi_dsi_read_register(mipi_dsi, MIPI_DSI_CMD_PKT_STATUS,
+ &val);
+ }
+
+ mipi_dsi_read_register(mipi_dsi, MIPI_DSI_CMD_PKT_STATUS, &val);
+ while (!(val & DSI_CMD_PKT_STATUS_GEN_PLD_R_EMPTY)) {
+ mipi_dsi_read_register(mipi_dsi, MIPI_DSI_GEN_PLD_DATA, buf);
+ read_len += DSI_GEN_PLD_DATA_BUF_SIZE;
+ buf++;
+ mipi_dsi_read_register(mipi_dsi, MIPI_DSI_CMD_PKT_STATUS,
+ &val);
+ if (read_len == (DSI_GEN_PLD_DATA_BUF_ENTRY *
+ DSI_GEN_PLD_DATA_BUF_SIZE))
+ break;
+ }
+
+ if ((len <= read_len) &&
+ ((len + DSI_GEN_PLD_DATA_BUF_SIZE) >= read_len))
+ return 0;
+ else {
+ dev_err(&mipi_dsi->pdev->dev,
+ "actually read_len:%d != len:%d.\n", read_len, len);
+ return -ERANGE;
+ }
+}
+
+static int mipi_dsi_dcs_cmd(struct mipi_dsi_info *mipi_dsi,
+ u8 cmd, const u32 *param, int num)
+{
+ int err = 0;
+ u32 buf[DSI_CMD_BUF_MAXSIZE];
+
+ switch (cmd) {
+ case MIPI_DCS_EXIT_SLEEP_MODE:
+ case MIPI_DCS_ENTER_SLEEP_MODE:
+ case MIPI_DCS_SET_DISPLAY_ON:
+ case MIPI_DCS_SET_DISPLAY_OFF:
+ buf[0] = cmd;
+ err = mipi_dsi_pkt_write(mipi_dsi,
+ MIPI_DSI_DCS_SHORT_WRITE, buf, 0);
+ break;
+
+ default:
+ dev_err(&mipi_dsi->pdev->dev,
+ "MIPI DSI DCS Command:0x%x Not supported!\n", cmd);
+ break;
+ }
+
+ return err;
+}
+
+static void mipi_dsi_dphy_init(struct mipi_dsi_info *mipi_dsi,
+ u32 cmd, u32 data)
+{
+ u32 val;
+ u32 timeout = 0;
+
+ mipi_dsi_write_register(mipi_dsi, MIPI_DSI_PHY_IF_CTRL,
+ DSI_PHY_IF_CTRL_RESET);
+ mipi_dsi_write_register(mipi_dsi, MIPI_DSI_PWR_UP, DSI_PWRUP_POWERUP);
+
+ mipi_dsi_write_register(mipi_dsi, MIPI_DSI_PHY_TST_CTRL0, 0);
+ mipi_dsi_write_register(mipi_dsi, MIPI_DSI_PHY_TST_CTRL1,
+ (0x10000 | cmd));
+ mipi_dsi_write_register(mipi_dsi, MIPI_DSI_PHY_TST_CTRL0, 2);
+ mipi_dsi_write_register(mipi_dsi, MIPI_DSI_PHY_TST_CTRL0, 0);
+ mipi_dsi_write_register(mipi_dsi, MIPI_DSI_PHY_TST_CTRL1, (0 | data));
+ mipi_dsi_write_register(mipi_dsi, MIPI_DSI_PHY_TST_CTRL0, 2);
+ mipi_dsi_write_register(mipi_dsi, MIPI_DSI_PHY_TST_CTRL0, 0);
+ val = DSI_PHY_RSTZ_EN_CLK | DSI_PHY_RSTZ_DISABLE_RST |
+ DSI_PHY_RSTZ_DISABLE_SHUTDOWN;
+ mipi_dsi_write_register(mipi_dsi, MIPI_DSI_PHY_RSTZ, val);
+
+ mipi_dsi_read_register(mipi_dsi, MIPI_DSI_PHY_STATUS, &val);
+ while ((val & DSI_PHY_STATUS_LOCK) != DSI_PHY_STATUS_LOCK) {
+ msleep(1);
+ timeout++;
+ if (timeout == MIPI_DSI_PHY_TIMEOUT) {
+ dev_err(&mipi_dsi->pdev->dev,
+ "Error: phy lock timeout!\n");
+ break;
+ }
+ mipi_dsi_read_register(mipi_dsi, MIPI_DSI_PHY_STATUS, &val);
+ }
+ timeout = 0;
+ while ((val & DSI_PHY_STATUS_STOPSTATE_CLK_LANE) !=
+ DSI_PHY_STATUS_STOPSTATE_CLK_LANE) {
+ msleep(1);
+ timeout++;
+ if (timeout == MIPI_DSI_PHY_TIMEOUT) {
+ dev_err(&mipi_dsi->pdev->dev,
+ "Error: phy lock lane timeout!\n");
+ break;
+ }
+ mipi_dsi_read_register(mipi_dsi, MIPI_DSI_PHY_STATUS, &val);
+ }
+}
+
+static void mipi_dsi_enable_controller(struct mipi_dsi_info *mipi_dsi,
+ bool init)
+{
+ u32 val = 0;
+ u32 lane_byte_clk_period;
+ struct fb_videomode *mode = mipi_dsi->mode;
+ struct mipi_lcd_config *lcd_config = mipi_dsi->lcd_config;
+
+ if (init) {
+ mipi_dsi_write_register(mipi_dsi, MIPI_DSI_PWR_UP,
+ DSI_PWRUP_RESET);
+ mipi_dsi_write_register(mipi_dsi, MIPI_DSI_PHY_RSTZ,
+ DSI_PHY_RSTZ_RST);
+ mipi_dsi_write_register(mipi_dsi, MIPI_DSI_CLKMGR_CFG,
+ DSI_CLKMGR_CFG_CLK_DIV);
+
+ if (!(mode->sync & FB_SYNC_VERT_HIGH_ACT))
+ val = DSI_DPI_CFG_VSYNC_ACT_LOW;
+ if (!(mode->sync & FB_SYNC_HOR_HIGH_ACT))
+ val |= DSI_DPI_CFG_HSYNC_ACT_LOW;
+ if ((mode->sync & FB_SYNC_OE_LOW_ACT))
+ val |= DSI_DPI_CFG_DATAEN_ACT_LOW;
+ if (MIPI_RGB666_LOOSELY == lcd_config->dpi_fmt)
+ val |= DSI_DPI_CFG_EN18LOOSELY;
+ val |= (lcd_config->dpi_fmt & DSI_DPI_CFG_COLORCODE_MASK)
+ << DSI_DPI_CFG_COLORCODE_SHIFT;
+ val |= (lcd_config->virtual_ch & DSI_DPI_CFG_VID_MASK)
+ << DSI_DPI_CFG_VID_SHIFT;
+ mipi_dsi_write_register(mipi_dsi, MIPI_DSI_DPI_CFG, val);
+
+ val = DSI_PCKHDL_CFG_EN_BTA |
+ DSI_PCKHDL_CFG_EN_ECC_RX |
+ DSI_PCKHDL_CFG_EN_CRC_RX;
+
+ mipi_dsi_write_register(mipi_dsi, MIPI_DSI_PCKHDL_CFG, val);
+
+ val = (mode->xres & DSI_VID_PKT_CFG_VID_PKT_SZ_MASK)
+ << DSI_VID_PKT_CFG_VID_PKT_SZ_SHIFT;
+ val |= (NUMBER_OF_CHUNKS & DSI_VID_PKT_CFG_NUM_CHUNKS_MASK)
+ << DSI_VID_PKT_CFG_NUM_CHUNKS_SHIFT;
+ val |= (NULL_PKT_SIZE & DSI_VID_PKT_CFG_NULL_PKT_SZ_MASK)
+ << DSI_VID_PKT_CFG_NULL_PKT_SZ_SHIFT;
+ mipi_dsi_write_register(mipi_dsi, MIPI_DSI_VID_PKT_CFG, val);
+
+ /* enable LP mode when TX DCS cmd and enable DSI command mode */
+ mipi_dsi_write_register(mipi_dsi, MIPI_DSI_CMD_MODE_CFG,
+ MIPI_DSI_CMD_MODE_CFG_EN_LOWPOWER);
+
+ /* mipi lane byte clk period in ns unit */
+ lane_byte_clk_period = NS2PS_RATIO /
+ (lcd_config->max_phy_clk / BITS_PER_BYTE);
+ val = ROUND_UP(mode->hsync_len * mode->pixclock /
+ NS2PS_RATIO / lane_byte_clk_period)
+ << DSI_TME_LINE_CFG_HSA_TIME_SHIFT;
+ val |= ROUND_UP(mode->left_margin * mode->pixclock /
+ NS2PS_RATIO / lane_byte_clk_period)
+ << DSI_TME_LINE_CFG_HBP_TIME_SHIFT;
+ val |= ROUND_UP((mode->left_margin + mode->right_margin +
+ mode->hsync_len + mode->xres) * mode->pixclock
+ / NS2PS_RATIO / lane_byte_clk_period)
+ << DSI_TME_LINE_CFG_HLINE_TIME_SHIFT;
+ mipi_dsi_write_register(mipi_dsi, MIPI_DSI_TMR_LINE_CFG, val);
+
+ val = ((mode->vsync_len & DSI_VTIMING_CFG_VSA_LINES_MASK)
+ << DSI_VTIMING_CFG_VSA_LINES_SHIFT);
+ val |= ((mode->upper_margin & DSI_VTIMING_CFG_VBP_LINES_MASK)
+ << DSI_VTIMING_CFG_VBP_LINES_SHIFT);
+ val |= ((mode->lower_margin & DSI_VTIMING_CFG_VFP_LINES_MASK)
+ << DSI_VTIMING_CFG_VFP_LINES_SHIFT);
+ val |= ((mode->yres & DSI_VTIMING_CFG_V_ACT_LINES_MASK)
+ << DSI_VTIMING_CFG_V_ACT_LINES_SHIFT);
+ mipi_dsi_write_register(mipi_dsi, MIPI_DSI_VTIMING_CFG, val);
+
+ val = ((PHY_BTA_MAXTIME & DSI_PHY_TMR_CFG_BTA_TIME_MASK)
+ << DSI_PHY_TMR_CFG_BTA_TIME_SHIFT);
+ val |= ((PHY_LP2HS_MAXTIME & DSI_PHY_TMR_CFG_LP2HS_TIME_MASK)
+ << DSI_PHY_TMR_CFG_LP2HS_TIME_SHIFT);
+ val |= ((PHY_HS2LP_MAXTIME & DSI_PHY_TMR_CFG_HS2LP_TIME_MASK)
+ << DSI_PHY_TMR_CFG_HS2LP_TIME_SHIFT);
+ mipi_dsi_write_register(mipi_dsi, MIPI_DSI_PHY_TMR_CFG, val);
+
+ val = (((lcd_config->data_lane_num - 1) &
+ DSI_PHY_IF_CFG_N_LANES_MASK)
+ << DSI_PHY_IF_CFG_N_LANES_SHIFT);
+ val |= ((PHY_STOP_WAIT_TIME & DSI_PHY_IF_CFG_WAIT_TIME_MASK)
+ << DSI_PHY_IF_CFG_WAIT_TIME_SHIFT);
+ mipi_dsi_write_register(mipi_dsi, MIPI_DSI_PHY_IF_CFG, val);
+
+ mipi_dsi_read_register(mipi_dsi, MIPI_DSI_ERROR_ST0, &val);
+ mipi_dsi_read_register(mipi_dsi, MIPI_DSI_ERROR_ST1, &val);
+ mipi_dsi_write_register(mipi_dsi, MIPI_DSI_ERROR_MSK0, 0);
+ mipi_dsi_write_register(mipi_dsi, MIPI_DSI_ERROR_MSK1, 0);
+
+ mipi_dsi_dphy_init(mipi_dsi, DSI_PHY_CLK_INIT_COMMAND,
+ mipi_dsi->dphy_pll_config);
+ } else {
+ mipi_dsi_dphy_init(mipi_dsi, DSI_PHY_CLK_INIT_COMMAND,
+ mipi_dsi->dphy_pll_config);
+ }
+}
+
+static void mipi_dsi_disable_controller(struct mipi_dsi_info *mipi_dsi)
+{
+ mipi_dsi_write_register(mipi_dsi, MIPI_DSI_PHY_IF_CTRL,
+ DSI_PHY_IF_CTRL_RESET);
+ mipi_dsi_write_register(mipi_dsi, MIPI_DSI_PWR_UP, DSI_PWRUP_RESET);
+ mipi_dsi_write_register(mipi_dsi, MIPI_DSI_PHY_RSTZ, DSI_PHY_RSTZ_RST);
+}
+
+static irqreturn_t mipi_dsi_irq_handler(int irq, void *data)
+{
+ u32 mask0;
+ u32 mask1;
+ u32 status0;
+ u32 status1;
+ struct mipi_dsi_info *mipi_dsi;
+
+ mipi_dsi = (struct mipi_dsi_info *)data;
+ mipi_dsi_read_register(mipi_dsi, MIPI_DSI_ERROR_ST0, &status0);
+ mipi_dsi_read_register(mipi_dsi, MIPI_DSI_ERROR_ST1, &status1);
+ mipi_dsi_read_register(mipi_dsi, MIPI_DSI_ERROR_MSK0, &mask0);
+ mipi_dsi_read_register(mipi_dsi, MIPI_DSI_ERROR_MSK1, &mask1);
+
+ if ((status0 & (~mask0)) || (status1 & (~mask1))) {
+ dev_err(&mipi_dsi->pdev->dev,
+ "mipi_dsi IRQ status0:0x%x, status1:0x%x!\n",
+ status0, status1);
+ }
+
+ return IRQ_HANDLED;
+}
+
+static inline void mipi_dsi_set_mode(struct mipi_dsi_info *mipi_dsi,
+ bool cmd_mode)
+{
+ u32 val;
+
+ if (cmd_mode) {
+ mipi_dsi_write_register(mipi_dsi, MIPI_DSI_PWR_UP,
+ DSI_PWRUP_RESET);
+ mipi_dsi_read_register(mipi_dsi, MIPI_DSI_CMD_MODE_CFG, &val);
+ val |= MIPI_DSI_CMD_MODE_CFG_EN_CMD_MODE;
+ mipi_dsi_write_register(mipi_dsi, MIPI_DSI_CMD_MODE_CFG, val);
+ mipi_dsi_write_register(mipi_dsi, MIPI_DSI_VID_MODE_CFG, 0);
+ mipi_dsi_write_register(mipi_dsi, MIPI_DSI_PWR_UP,
+ DSI_PWRUP_POWERUP);
+ } else {
+ mipi_dsi_write_register(mipi_dsi, MIPI_DSI_PWR_UP,
+ DSI_PWRUP_RESET);
+ /* Disable Command mode when tranfering video data */
+ mipi_dsi_read_register(mipi_dsi, MIPI_DSI_CMD_MODE_CFG, &val);
+ val &= ~MIPI_DSI_CMD_MODE_CFG_EN_CMD_MODE;
+ mipi_dsi_write_register(mipi_dsi, MIPI_DSI_CMD_MODE_CFG, val);
+ val = DSI_VID_MODE_CFG_EN | DSI_VID_MODE_CFG_EN_BURSTMODE |
+ DSI_VID_MODE_CFG_EN_LP_MODE;
+ mipi_dsi_write_register(mipi_dsi, MIPI_DSI_VID_MODE_CFG, val);
+ mipi_dsi_write_register(mipi_dsi, MIPI_DSI_PWR_UP,
+ DSI_PWRUP_POWERUP);
+ mipi_dsi_write_register(mipi_dsi, MIPI_DSI_PHY_IF_CTRL,
+ DSI_PHY_IF_CTRL_TX_REQ_CLK_HS);
+ }
+}
+
+static int mipi_dsi_power_on(struct mxc_dispdrv_handle *disp)
+{
+ int err;
+ struct mipi_dsi_info *mipi_dsi = mxc_dispdrv_getdata(disp);
+
+ if (!mipi_dsi->dsi_power_on) {
+ clk_prepare_enable(mipi_dsi->dphy_clk);
+ clk_prepare_enable(mipi_dsi->cfg_clk);
+ mipi_dsi_enable_controller(mipi_dsi, false);
+ mipi_dsi_set_mode(mipi_dsi, false);
+ /* host send pclk/hsync/vsync for two frames before sleep-out */
+ msleep((1000/mipi_dsi->mode->refresh + 1) << 1);
+ mipi_dsi_set_mode(mipi_dsi, true);
+ err = mipi_dsi_dcs_cmd(mipi_dsi, MIPI_DCS_EXIT_SLEEP_MODE,
+ NULL, 0);
+ if (err) {
+ dev_err(&mipi_dsi->pdev->dev,
+ "MIPI DSI DCS Command sleep-in error!\n");
+ }
+ msleep(MIPI_LCD_SLEEP_MODE_DELAY);
+ mipi_dsi_set_mode(mipi_dsi, false);
+ mipi_dsi->dsi_power_on = 1;
+ }
+
+ return 0;
+}
+
+void mipi_dsi_power_off(struct mxc_dispdrv_handle *disp)
+{
+ int err;
+ struct mipi_dsi_info *mipi_dsi = mxc_dispdrv_getdata(disp);
+
+ if (mipi_dsi->dsi_power_on) {
+ mipi_dsi_set_mode(mipi_dsi, true);
+ err = mipi_dsi_dcs_cmd(mipi_dsi, MIPI_DCS_ENTER_SLEEP_MODE,
+ NULL, 0);
+ if (err) {
+ dev_err(&mipi_dsi->pdev->dev,
+ "MIPI DSI DCS Command display on error!\n");
+ }
+ /* To allow time for the supply voltages
+ * and clock circuits to stabilize.
+ */
+ msleep(5);
+ /* video stream timing on */
+ mipi_dsi_set_mode(mipi_dsi, false);
+ msleep(MIPI_LCD_SLEEP_MODE_DELAY);
+
+ mipi_dsi_set_mode(mipi_dsi, true);
+ mipi_dsi_disable_controller(mipi_dsi);
+ mipi_dsi->dsi_power_on = 0;
+ clk_disable_unprepare(mipi_dsi->dphy_clk);
+ clk_disable_unprepare(mipi_dsi->cfg_clk);
+ }
+}
+
+static int mipi_dsi_lcd_init(struct mipi_dsi_info *mipi_dsi,
+ struct mxc_dispdrv_setting *setting)
+{
+ int err;
+ int size;
+ int i;
+ struct fb_videomode *mipi_lcd_modedb;
+ struct fb_videomode mode;
+ struct device *dev = &mipi_dsi->pdev->dev;
+
+ for (i = 0; i < ARRAY_SIZE(mipi_dsi_lcd_db); i++) {
+ if (!strcmp(mipi_dsi->lcd_panel,
+ mipi_dsi_lcd_db[i].lcd_panel)) {
+ mipi_dsi->lcd_callback =
+ &mipi_dsi_lcd_db[i].lcd_callback;
+ break;
+ }
+ }
+ if (i == ARRAY_SIZE(mipi_dsi_lcd_db)) {
+ dev_err(dev, "failed to find supported lcd panel.\n");
+ return -EINVAL;
+ }
+ /* get the videomode in the order: cmdline->platform data->driver */
+ mipi_dsi->lcd_callback->get_mipi_lcd_videomode(&mipi_lcd_modedb, &size,
+ &mipi_dsi->lcd_config);
+ err = fb_find_mode(&setting->fbi->var, setting->fbi,
+ setting->dft_mode_str,
+ mipi_lcd_modedb, size, NULL,
+ setting->default_bpp);
+ if (err != 1)
+ fb_videomode_to_var(&setting->fbi->var, mipi_lcd_modedb);
+
+ INIT_LIST_HEAD(&setting->fbi->modelist);
+ for (i = 0; i < size; i++) {
+ fb_var_to_videomode(&mode, &setting->fbi->var);
+ if (fb_mode_is_equal(&mode, mipi_lcd_modedb + i)) {
+ err = fb_add_videomode(mipi_lcd_modedb + i,
+ &setting->fbi->modelist);
+ /* Note: only support fb mode from driver */
+ mipi_dsi->mode = mipi_lcd_modedb + i;
+ break;
+ }
+ }
+ if ((err < 0) || (size == i)) {
+ dev_err(dev, "failed to add videomode.\n");
+ return err;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(mipi_dsi_phy_pll_clk_table); i++) {
+ if (mipi_dsi_phy_pll_clk_table[i].max_phy_clk <
+ mipi_dsi->lcd_config->max_phy_clk)
+ break;
+ }
+ if ((i == ARRAY_SIZE(mipi_dsi_phy_pll_clk_table)) ||
+ (mipi_dsi->lcd_config->max_phy_clk >
+ mipi_dsi_phy_pll_clk_table[0].max_phy_clk)) {
+ dev_err(dev, "failed to find data in"
+ "mipi_dsi_phy_pll_clk_table.\n");
+ return -EINVAL;
+ }
+ mipi_dsi->dphy_pll_config = mipi_dsi_phy_pll_clk_table[--i].config;
+ dev_dbg(dev, "dphy_pll_config:0x%x.\n", mipi_dsi->dphy_pll_config);
+
+ return 0;
+}
+
+static int mipi_dsi_enable(struct mxc_dispdrv_handle *disp,
+ struct fb_info *fbi)
+{
+ int err;
+ struct mipi_dsi_info *mipi_dsi = mxc_dispdrv_getdata(disp);
+
+ if (!mipi_dsi->lcd_inited) {
+ err = clk_prepare_enable(mipi_dsi->dphy_clk);
+ err |= clk_prepare_enable(mipi_dsi->cfg_clk);
+ if (err)
+ dev_err(&mipi_dsi->pdev->dev,
+ "clk enable error:%d!\n", err);
+ mipi_dsi_enable_controller(mipi_dsi, true);
+ err = mipi_dsi->lcd_callback->mipi_lcd_setup(
+ mipi_dsi);
+ if (err < 0) {
+ dev_err(&mipi_dsi->pdev->dev,
+ "failed to init mipi lcd.");
+ clk_disable_unprepare(mipi_dsi->dphy_clk);
+ clk_disable_unprepare(mipi_dsi->cfg_clk);
+ return err;
+ }
+ mipi_dsi_set_mode(mipi_dsi, false);
+ mipi_dsi->dsi_power_on = 1;
+ mipi_dsi->lcd_inited = 1;
+ }
+ mipi_dsi_power_on(mipi_dsi->disp_mipi);
+
+ return 0;
+}
+
+static void mipi_dsi_disable(struct mxc_dispdrv_handle *disp,
+ struct fb_info *fbi)
+{
+ struct mipi_dsi_info *mipi_dsi = mxc_dispdrv_getdata(disp);
+
+ mipi_dsi_power_off(mipi_dsi->disp_mipi);
+}
+
+static int mipi_dsi_disp_init(struct mxc_dispdrv_handle *disp,
+ struct mxc_dispdrv_setting *setting)
+{
+ struct mipi_dsi_info *mipi_dsi = mxc_dispdrv_getdata(disp);
+ struct device *dev = &mipi_dsi->pdev->dev;
+ int ret = 0;
+
+ if (!valid_mode(setting->if_fmt)) {
+ dev_warn(dev, "Input pixel format not valid"
+ "use default RGB24\n");
+ setting->if_fmt = IPU_PIX_FMT_RGB24;
+ }
+
+ ret = ipu_di_to_crtc(dev, mipi_dsi->dev_id,
+ mipi_dsi->disp_id, &setting->crtc);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_lcd_init(mipi_dsi, setting);
+ if (ret) {
+ dev_err(dev, "failed to init mipi dsi lcd\n");
+ return ret;
+ }
+
+ dev_dbg(dev, "MIPI DSI dispdrv inited!\n");
+ return ret;
+}
+
+static void mipi_dsi_disp_deinit(struct mxc_dispdrv_handle *disp)
+{
+ struct mipi_dsi_info *mipi_dsi;
+
+ mipi_dsi = mxc_dispdrv_getdata(disp);
+
+ mipi_dsi_power_off(mipi_dsi->disp_mipi);
+ if (mipi_dsi->bl)
+ backlight_device_unregister(mipi_dsi->bl);
+}
+
+static int mipi_dsi_setup(struct mxc_dispdrv_handle *disp,
+ struct fb_info *fbi)
+{
+ struct mipi_dsi_info *mipi_dsi = mxc_dispdrv_getdata(disp);
+ int xres_virtual = fbi->var.xres_virtual;
+ int yres_virtual = fbi->var.yres_virtual;
+ int xoffset = fbi->var.xoffset;
+ int yoffset = fbi->var.yoffset;
+ int pixclock = fbi->var.pixclock;
+
+ if (!mipi_dsi->mode)
+ return 0;
+
+ /* set the mode back to var in case userspace changes it */
+ fb_videomode_to_var(&fbi->var, mipi_dsi->mode);
+
+ /* restore some var entries cached */
+ fbi->var.xres_virtual = xres_virtual;
+ fbi->var.yres_virtual = yres_virtual;
+ fbi->var.xoffset = xoffset;
+ fbi->var.yoffset = yoffset;
+ fbi->var.pixclock = pixclock;
+ return 0;
+}
+
+static struct mxc_dispdrv_driver mipi_dsi_drv = {
+ .name = DISPDRV_MIPI,
+ .init = mipi_dsi_disp_init,
+ .deinit = mipi_dsi_disp_deinit,
+ .enable = mipi_dsi_enable,
+ .disable = mipi_dsi_disable,
+ .setup = mipi_dsi_setup,
+};
+
+static int device_reset(struct device *dev)
+{
+ struct device_node *np = dev->of_node;
+ enum of_gpio_flags flags;
+ unsigned long gpio_flags;
+ unsigned int gpio;
+ bool initially_in_reset;
+ bool active_low;
+ s32 delay_us;
+ int ret;
+
+ gpio = of_get_named_gpio_flags(np, "reset-gpios", 0, &flags);
+ if (gpio == -EPROBE_DEFER) {
+ return gpio;
+ } else if (!gpio_is_valid(gpio)) {
+ dev_err(dev, "invalid reset gpio: %d\n", gpio);
+ return gpio;
+ }
+
+ active_low = flags & OF_GPIO_ACTIVE_LOW;
+
+ ret = of_property_read_u32(np, "reset-delay-us", &delay_us);
+ if (ret < 0 || delay_us < 0) {
+ dev_err(dev, "invalid reset delay\n");
+ return -EINVAL;
+ }
+
+ initially_in_reset = of_property_read_bool(np, "initially-in-reset");
+ if (active_low ^ initially_in_reset)
+ gpio_flags = GPIOF_OUT_INIT_HIGH;
+ else
+ gpio_flags = GPIOF_OUT_INIT_LOW;
+
+ ret = devm_gpio_request_one(dev, gpio, gpio_flags, NULL);
+ if (ret < 0) {
+ dev_err(dev, "failed to request gpio %d: %d\n", gpio, ret);
+ return ret;
+ }
+
+ gpio_set_value_cansleep(gpio, active_low ? 0 : 1);
+ udelay(delay_us);
+ gpio_set_value_cansleep(gpio, active_low ? 1 : 0);
+
+ return 0;
+}
+
+static int imx6q_mipi_dsi_get_mux(int dev_id, int disp_id)
+{
+ if (dev_id > 1 || disp_id > 1)
+ return -EINVAL;
+
+ return (dev_id << 5) | (disp_id << 4);
+}
+
+static struct mipi_dsi_bus_mux imx6q_mipi_dsi_mux[] = {
+ {
+ .reg = IOMUXC_GPR3,
+ .mask = IMX6Q_GPR3_MIPI_MUX_CTL_MASK,
+ .get_mux = imx6q_mipi_dsi_get_mux,
+ },
+};
+
+static int imx6dl_mipi_dsi_get_mux(int dev_id, int disp_id)
+{
+ if (dev_id > 1 || disp_id > 1)
+ return -EINVAL;
+
+ /* MIPI DSI source is LCDIF */
+ if (dev_id)
+ disp_id = 0;
+
+ return (dev_id << 5) | (disp_id << 4);
+}
+
+static struct mipi_dsi_bus_mux imx6dl_mipi_dsi_mux[] = {
+ {
+ .reg = IOMUXC_GPR3,
+ .mask = IMX6Q_GPR3_MIPI_MUX_CTL_MASK,
+ .get_mux = imx6dl_mipi_dsi_get_mux,
+ },
+};
+
+static const struct of_device_id imx_mipi_dsi_dt_ids[] = {
+ { .compatible = "fsl,imx6q-mipi-dsi", .data = imx6q_mipi_dsi_mux, },
+ { .compatible = "fsl,imx6dl-mipi-dsi", .data = imx6dl_mipi_dsi_mux, },
+ { }
+};
+MODULE_DEVICE_TABLE(of, imx_mipi_dsi_dt_ids);
+
+/**
+ * This function is called by the driver framework to initialize the MIPI DSI
+ * device.
+ *
+ * @param pdev The device structure for the MIPI DSI passed in by the
+ * driver framework.
+ *
+ * @return Returns 0 on success or negative error code on error
+ */
+static int mipi_dsi_probe(struct platform_device *pdev)
+{
+ struct device_node *np = pdev->dev.of_node;
+ const struct of_device_id *of_id =
+ of_match_device(of_match_ptr(imx_mipi_dsi_dt_ids),
+ &pdev->dev);
+ struct mipi_dsi_info *mipi_dsi;
+ struct resource *res;
+ u32 dev_id, disp_id;
+ const char *lcd_panel;
+ int mux;
+ int ret = 0;
+
+ if (!np) {
+ dev_err(&pdev->dev, "failed to find device tree node\n");
+ return -ENODEV;
+ }
+
+ mipi_dsi = devm_kzalloc(&pdev->dev, sizeof(*mipi_dsi), GFP_KERNEL);
+ if (!mipi_dsi)
+ return -ENOMEM;
+
+ ret = of_property_read_string(np, "lcd_panel", &lcd_panel);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to read of property lcd_panel\n");
+ return ret;
+ }
+
+ ret = of_property_read_u32(np, "dev_id", &dev_id);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to read of property dev_id\n");
+ return ret;
+ }
+ ret = of_property_read_u32(np, "disp_id", &disp_id);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to read of property disp_id\n");
+ return ret;
+ }
+ mipi_dsi->dev_id = dev_id;
+ mipi_dsi->disp_id = disp_id;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ dev_err(&pdev->dev, "failed to get platform resource 0\n");
+ return -ENODEV;
+ }
+
+ if (!devm_request_mem_region(&pdev->dev, res->start,
+ resource_size(res), pdev->name))
+ return -EBUSY;
+
+ mipi_dsi->mmio_base = devm_ioremap(&pdev->dev, res->start,
+ resource_size(res));
+ if (!mipi_dsi->mmio_base)
+ return -EBUSY;
+
+ mipi_dsi->irq = platform_get_irq(pdev, 0);
+ if (mipi_dsi->irq < 0) {
+ dev_err(&pdev->dev, "failed get device irq\n");
+ return -ENODEV;
+ }
+
+ ret = devm_request_irq(&pdev->dev, mipi_dsi->irq,
+ mipi_dsi_irq_handler,
+ 0, "mipi_dsi", mipi_dsi);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to request irq\n");
+ return ret;
+ }
+
+ mipi_dsi->dphy_clk = devm_clk_get(&pdev->dev, "mipi_pllref_clk");
+ if (IS_ERR(mipi_dsi->dphy_clk)) {
+ dev_err(&pdev->dev, "failed to get dphy pll_ref_clk\n");
+ return PTR_ERR(mipi_dsi->dphy_clk);
+ }
+
+ mipi_dsi->cfg_clk = devm_clk_get(&pdev->dev, "mipi_cfg_clk");
+ if (IS_ERR(mipi_dsi->cfg_clk)) {
+ dev_err(&pdev->dev, "failed to get cfg_clk\n");
+ return PTR_ERR(mipi_dsi->cfg_clk);
+ }
+
+ mipi_dsi->disp_power_on = devm_regulator_get(&pdev->dev,
+ "disp-power-on");
+ if (!IS_ERR(mipi_dsi->disp_power_on)) {
+ ret = regulator_enable(mipi_dsi->disp_power_on);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to enable display "
+ "power regulator, err=%d\n", ret);
+ return ret;
+ }
+ } else {
+ mipi_dsi->disp_power_on = NULL;
+ }
+
+ ret = device_reset(&pdev->dev);
+ if (ret) {
+ if (ret != -EPROBE_DEFER)
+ dev_err(&pdev->dev, "failed to reset: %d\n", ret);
+ goto dev_reset_fail;
+ }
+
+ if (of_id)
+ mipi_dsi->bus_mux = of_id->data;
+
+ mipi_dsi->regmap = syscon_regmap_lookup_by_phandle(np, "gpr");
+ if (IS_ERR(mipi_dsi->regmap)) {
+ dev_err(&pdev->dev, "failed to get parent regmap\n");
+ ret = PTR_ERR(mipi_dsi->regmap);
+ goto get_parent_regmap_fail;
+ }
+
+ mux = mipi_dsi->bus_mux->get_mux(dev_id, disp_id);
+ if (mux >= 0)
+ regmap_update_bits(mipi_dsi->regmap, mipi_dsi->bus_mux->reg,
+ mipi_dsi->bus_mux->mask, (unsigned int)mux);
+ else
+ dev_warn(&pdev->dev, "invalid dev_id or disp_id muxing\n");
+
+ mipi_dsi->lcd_panel = kstrdup(lcd_panel, GFP_KERNEL);
+ if (!mipi_dsi->lcd_panel) {
+ dev_err(&pdev->dev, "failed to allocate lcd panel name\n");
+ ret = -ENOMEM;
+ goto kstrdup_fail;
+ }
+
+ mipi_dsi->pdev = pdev;
+ mipi_dsi->disp_mipi = mxc_dispdrv_register(&mipi_dsi_drv);
+ if (IS_ERR(mipi_dsi->disp_mipi)) {
+ dev_err(&pdev->dev, "mxc_dispdrv_register error\n");
+ ret = PTR_ERR(mipi_dsi->disp_mipi);
+ goto dispdrv_reg_fail;
+ }
+
+ mipi_dsi->mipi_dsi_pkt_read = mipi_dsi_pkt_read;
+ mipi_dsi->mipi_dsi_pkt_write = mipi_dsi_pkt_write;
+ mipi_dsi->mipi_dsi_dcs_cmd = mipi_dsi_dcs_cmd;
+
+ mxc_dispdrv_setdata(mipi_dsi->disp_mipi, mipi_dsi);
+ dev_set_drvdata(&pdev->dev, mipi_dsi);
+
+ dev_info(&pdev->dev, "i.MX MIPI DSI driver probed\n");
+ return ret;
+
+dispdrv_reg_fail:
+ kfree(mipi_dsi->lcd_panel);
+kstrdup_fail:
+get_parent_regmap_fail:
+dev_reset_fail:
+ if (mipi_dsi->disp_power_on)
+ regulator_disable(mipi_dsi->disp_power_on);
+ return ret;
+}
+
+static void mipi_dsi_shutdown(struct platform_device *pdev)
+{
+ struct mipi_dsi_info *mipi_dsi = dev_get_drvdata(&pdev->dev);
+
+ mipi_dsi_power_off(mipi_dsi->disp_mipi);
+}
+
+static int mipi_dsi_remove(struct platform_device *pdev)
+{
+ struct mipi_dsi_info *mipi_dsi = dev_get_drvdata(&pdev->dev);
+
+ mxc_dispdrv_puthandle(mipi_dsi->disp_mipi);
+ mxc_dispdrv_unregister(mipi_dsi->disp_mipi);
+
+ if (mipi_dsi->disp_power_on)
+ regulator_disable(mipi_dsi->disp_power_on);
+
+ kfree(mipi_dsi->lcd_panel);
+ dev_set_drvdata(&pdev->dev, NULL);
+
+ return 0;
+}
+
+static struct platform_driver mipi_dsi_driver = {
+ .driver = {
+ .of_match_table = imx_mipi_dsi_dt_ids,
+ .name = "mxc_mipi_dsi",
+ },
+ .probe = mipi_dsi_probe,
+ .remove = mipi_dsi_remove,
+ .shutdown = mipi_dsi_shutdown,
+};
+
+static int __init mipi_dsi_init(void)
+{
+ int err;
+
+ err = platform_driver_register(&mipi_dsi_driver);
+ if (err) {
+ pr_err("mipi_dsi_driver register failed\n");
+ return -ENODEV;
+ }
+ pr_debug("MIPI DSI driver module loaded: %s\n", mipi_dsi_driver.driver.name);
+ return 0;
+}
+
+static void __exit mipi_dsi_cleanup(void)
+{
+ platform_driver_unregister(&mipi_dsi_driver);
+}
+
+module_init(mipi_dsi_init);
+module_exit(mipi_dsi_cleanup);
+
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("i.MX MIPI DSI driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/video/fbdev/mxc/mipi_dsi.h b/drivers/video/fbdev/mxc/mipi_dsi.h
new file mode 100644
index 000000000000..ae9b0428ca1e
--- /dev/null
+++ b/drivers/video/fbdev/mxc/mipi_dsi.h
@@ -0,0 +1,151 @@
+/*
+ * Copyright (C) 2011-2016 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2017 NXP.
+ */
+
+/*
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+#ifndef __MIPI_DSI_H__
+#define __MIPI_DSI_H__
+
+#include <linux/regmap.h>
+#include "mxc_dispdrv.h"
+
+#ifdef DEBUG
+#define mipi_dbg(fmt, ...) printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__)
+#else
+#define mipi_dbg(fmt, ...)
+#endif
+
+#define DSI_CMD_BUF_MAXSIZE (128)
+
+#define DSI_NON_BURST_WITH_SYNC_PULSE 0
+#define DSI_NON_BURST_WITH_SYNC_EVENT 1
+#define DSI_BURST_MODE 2
+
+#define DSI_HSA_PKT_OVERHEAD 10
+#define DSI_HFP_PKT_OVERHEAD 8
+#define DSI_HBP_PKT_OVERHEAD 14
+
+/* DPI interface pixel color coding map */
+enum mipi_dsi_dpi_fmt {
+ MIPI_RGB565_PACKED = 0,
+ MIPI_RGB565_LOOSELY,
+ MIPI_RGB565_CONFIG3,
+ MIPI_RGB666_PACKED,
+ MIPI_RGB666_LOOSELY,
+ MIPI_RGB888,
+};
+
+struct mipi_lcd_config {
+ u32 virtual_ch;
+ u32 data_lane_num;
+ /* device max DPHY clock in MHz unit */
+ u32 max_phy_clk;
+ enum mipi_dsi_dpi_fmt dpi_fmt;
+};
+
+struct mipi_dsi_info;
+struct mipi_dsi_lcd_callback {
+ /* callback for lcd panel operation */
+ void (*get_mipi_lcd_videomode)(struct fb_videomode **, int *,
+ struct mipi_lcd_config **);
+ int (*mipi_lcd_setup)(struct mipi_dsi_info *);
+
+};
+
+struct mipi_dsi_match_lcd {
+ char *lcd_panel;
+ struct mipi_dsi_lcd_callback lcd_callback;
+};
+
+struct mipi_dsi_bus_mux {
+ int reg;
+ int mask;
+ int (*get_mux) (int dev_id, int disp_id);
+};
+
+/* driver private data */
+struct mipi_dsi_info {
+ struct platform_device *pdev;
+ void __iomem *mmio_base;
+ void __iomem *phy_base;
+ struct regmap *regmap;
+ struct regmap *mux_sel;
+ const struct mipi_dsi_bus_mux *bus_mux;
+ int dsi_power_on;
+ int lcd_inited;
+ int encoder;
+ int traffic_mode;
+ u32 dphy_pll_config;
+ int dev_id;
+ int disp_id;
+ char *lcd_panel;
+ int irq;
+ uint32_t phy_ref_clkfreq;
+#ifdef CONFIG_FB_IMX64
+ struct clk *core_clk;
+ struct clk *phy_ref_clk;
+ struct clk *dbi_clk;
+ struct clk *rxesc_clk;
+ struct clk *txesc_clk;
+#else
+ struct clk *dphy_clk;
+ struct clk *cfg_clk;
+ struct clk *esc_clk;
+#endif
+ struct mxc_dispdrv_handle *disp_mipi;
+ int vmode_index;
+ struct fb_videomode *mode;
+ struct regulator *disp_power_on;
+ struct mipi_lcd_config *lcd_config;
+ /* board related power control */
+ struct backlight_device *bl;
+ /* callback for lcd panel operation */
+ struct mipi_dsi_lcd_callback *lcd_callback;
+
+ int (*mipi_dsi_pkt_read)(struct mipi_dsi_info *mipi,
+ u8 data_type, u32 *buf, int len);
+ int (*mipi_dsi_pkt_write)(struct mipi_dsi_info *mipi_dsi,
+ u8 data_type, const u32 *buf, int len);
+ int (*mipi_dsi_dcs_cmd)(struct mipi_dsi_info *mipi,
+ u8 cmd, const u32 *param, int num);
+};
+
+#ifdef CONFIG_FB_MXC_TRULY_WVGA_SYNC_PANEL
+void mipid_hx8369_get_lcd_videomode(struct fb_videomode **mode, int *size,
+ struct mipi_lcd_config **data);
+int mipid_hx8369_lcd_setup(struct mipi_dsi_info *);
+#endif
+#ifdef CONFIG_FB_MXC_TRULY_PANEL_TFT3P5079E
+void mipid_otm8018b_get_lcd_videomode(struct fb_videomode **mode, int *size,
+ struct mipi_lcd_config **data);
+int mipid_otm8018b_lcd_setup(struct mipi_dsi_info *);
+#endif
+#ifdef CONFIG_FB_MXC_TRULY_PANEL_TFT3P5581E
+void mipid_hx8363_get_lcd_videomode(struct fb_videomode **mode, int *size,
+ struct mipi_lcd_config **data);
+int mipid_hx8363_lcd_setup(struct mipi_dsi_info *);
+#endif
+#ifdef CONFIG_FB_MXC_RK_PANEL_RK055AHD042
+void mipid_rm68200_get_lcd_videomode(struct fb_videomode **mode, int *size,
+ struct mipi_lcd_config **data);
+int mipid_rm68200_lcd_setup(struct mipi_dsi_info *mipi_dsi);
+#endif
+#ifdef CONFIG_FB_MXC_RK_PANEL_RK055IQH042
+void mipid_rm68191_get_lcd_videomode(struct fb_videomode **mode, int *size,
+ struct mipi_lcd_config **data);
+int mipid_rm68191_lcd_setup(struct mipi_dsi_info *mipi_dsi);
+#endif
+
+#ifndef CONFIG_FB_MXC_TRULY_WVGA_SYNC_PANEL
+#error "Please configure MIPI LCD panel, we cannot find one!"
+#endif
+
+#endif
diff --git a/drivers/video/fbdev/mxc/mipi_dsi_northwest.c b/drivers/video/fbdev/mxc/mipi_dsi_northwest.c
new file mode 100644
index 000000000000..9df6c9cdb191
--- /dev/null
+++ b/drivers/video/fbdev/mxc/mipi_dsi_northwest.c
@@ -0,0 +1,1555 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2017 NXP.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/console.h>
+#include <linux/io.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/bitops.h>
+#include <linux/gcd.h>
+#include <linux/mipi_dsi_northwest.h>
+#include <linux/module.h>
+#include <linux/mxcfb.h>
+#include <linux/pm_runtime.h>
+#include <linux/busfreq-imx.h>
+#include <linux/backlight.h>
+#include <linux/of_device.h>
+#include <linux/of_address.h>
+#include <linux/of_graph.h>
+#include <linux/regulator/consumer.h>
+#include <linux/reset.h>
+#include <linux/spinlock.h>
+#include <linux/delay.h>
+#include <video/mipi_display.h>
+#include <video/mxc_edid.h>
+#include <linux/mfd/syscon.h>
+
+#include "mipi_dsi.h"
+
+#define DISPDRV_MIPI "mipi_dsi_northwest"
+#define ROUND_UP(x) ((x)+1)
+#define NS2PS_RATIO (1000)
+#define MIPI_LCD_SLEEP_MODE_DELAY (120)
+#define MIPI_FIFO_TIMEOUT msecs_to_jiffies(250)
+#define PICOS_PER_SEC (1000000000ULL)
+#define PICOS2KHZ2(a, bpp) \
+ DIV_ROUND_CLOSEST_ULL(PICOS_PER_SEC * (bpp), (a))
+
+static struct mipi_dsi_match_lcd mipi_dsi_lcd_db[] = {
+#ifdef CONFIG_FB_MXC_TRULY_WVGA_SYNC_PANEL
+ {
+ "TRULY-WVGA",
+ {mipid_hx8369_get_lcd_videomode, mipid_hx8369_lcd_setup}
+ },
+#endif
+#ifdef CONFIG_FB_MXC_TRULY_PANEL_TFT3P5079E
+ {
+ "TRULY-WVGA-TFT3P5079E",
+ {mipid_otm8018b_get_lcd_videomode, mipid_otm8018b_lcd_setup}
+ },
+#endif
+#ifdef CONFIG_FB_MXC_TRULY_PANEL_TFT3P5581E
+ {
+ "TRULY-WVGA-TFT3P5581E",
+ {mipid_hx8363_get_lcd_videomode, mipid_hx8363_lcd_setup}
+ },
+#endif
+#ifdef CONFIG_FB_MXC_RK_PANEL_RK055AHD042
+ {
+ "ROCKTECH-WXGA-RK055AHD042",
+ {mipid_rm68200_get_lcd_videomode, mipid_rm68200_lcd_setup}
+ },
+#endif
+#ifdef CONFIG_FB_MXC_RK_PANEL_RK055IQH042
+ {
+ "ROCKTECH-QHD-RK055IQH042",
+ {mipid_rm68191_get_lcd_videomode, mipid_rm68191_lcd_setup}
+ },
+#endif
+ {
+ "", {NULL, NULL}
+ }
+};
+
+enum mipi_dsi_mode {
+ DSI_COMMAND_MODE,
+ DSI_VIDEO_MODE
+};
+
+#define DSI_LP_MODE 0
+#define DSI_HS_MODE 1
+
+enum mipi_dsi_payload {
+ DSI_PAYLOAD_CMD,
+ DSI_PAYLOAD_VIDEO,
+};
+
+struct pll_divider {
+ unsigned int cm; /* multiplier */
+ unsigned int cn; /* predivider */
+ unsigned int co; /* outdivider */
+};
+
+/**
+ * 'CM' value to 'CM' reigister config value map
+ * 'CM' = [16, 255];
+ */
+static unsigned int cm_map_table[240] = {
+ 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, /* 16 ~ 23 */
+ 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, /* 24 ~ 31 */
+
+ 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, /* 32 ~ 39 */
+ 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, /* 40 ~ 47 */
+
+ 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, /* 48 ~ 55 */
+ 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, /* 56 ~ 63 */
+
+ 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, /* 64 ~ 71 */
+ 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, /* 72 ~ 79 */
+
+ 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, /* 80 ~ 87 */
+ 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, /* 88 ~ 95 */
+
+ 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, /* 96 ~ 103 */
+ 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, /* 104 ~ 111 */
+
+ 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, /* 112 ~ 119 */
+ 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, /* 120 ~ 127 */
+
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 128 ~ 135 */
+ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 136 ~ 143 */
+
+ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 144 ~ 151 */
+ 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, /* 152 ~ 159 */
+
+ 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 160 ~ 167 */
+ 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, /* 168 ~ 175 */
+
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 176 ~ 183 */
+ 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, /* 184 ~ 191 */
+
+ 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 192 ~ 199 */
+ 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, /* 200 ~ 207 */
+
+ 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 208 ~ 215 */
+ 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, /* 216 ~ 223 */
+
+ 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* 224 ~ 231 */
+ 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, /* 232 ~ 239 */
+
+ 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, /* 240 ~ 247 */
+ 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f /* 248 ~ 255 */
+};
+
+/**
+ * map 'CN' value to 'CN' reigister config value
+ * 'CN' = [1, 32];
+ */
+static unsigned int cn_map_table[32] = {
+ 0x1f, 0x00, 0x10, 0x18, 0x1c, 0x0e, 0x07, 0x13, /* 1 ~ 8 */
+ 0x09, 0x04, 0x02, 0x11, 0x08, 0x14, 0x0a, 0x15, /* 9 ~ 16 */
+ 0x1a, 0x1d, 0x1e, 0x0f, 0x17, 0x1b, 0x0d, 0x16, /* 17 ~ 24 */
+ 0x0b, 0x05, 0x12, 0x19, 0x0c, 0x06, 0x03, 0x01 /* 25 ~ 32 */
+};
+
+/**
+ * map 'CO' value to 'CO' reigister config value
+ * 'CO' = { 1, 2, 4, 8 };
+ */
+static unsigned int co_map_table[4] = {
+ 0x0, 0x1, 0x2, 0x3
+};
+
+static DECLARE_COMPLETION(dsi_rx_done);
+static DECLARE_COMPLETION(dsi_tx_done);
+
+static void mipi_dsi_set_mode(struct mipi_dsi_info *mipi_dsi,
+ uint8_t mode);
+static int mipi_dsi_dcs_cmd(struct mipi_dsi_info *mipi_dsi,
+ u8 cmd, const u32 *param, int num);
+
+static int mipi_dsi_lcd_init(struct mipi_dsi_info *mipi_dsi,
+ struct mxc_dispdrv_setting *setting)
+{
+ u32 data_lane_num, max_data_rate;
+ int i, size, err = 0;
+ struct fb_videomode *mipi_lcd_modedb;
+ struct fb_videomode mode;
+ struct device *dev = &mipi_dsi->pdev->dev;
+
+ err = of_property_read_u32(dev->of_node,
+ "data-lanes-num", &data_lane_num);
+ if (err) {
+ dev_err(dev, "failed to get data lane num\n");
+ goto err0;
+ } else if (data_lane_num > 4) {
+ dev_err(dev, "invalid data lane number\n");
+ err = -EINVAL;
+ goto err0;
+ }
+
+ err = of_property_read_u32(dev->of_node,
+ "max-data-rate", &max_data_rate);
+ if (err) {
+ dev_err(dev, "failed to get max data rate\n");
+ goto err0;
+ }
+
+ if (mipi_dsi->encoder) {
+ mipi_dsi->lcd_config->virtual_ch = 0;
+ mipi_dsi->lcd_config->data_lane_num = data_lane_num;
+ mipi_dsi->lcd_config->max_phy_clk = max_data_rate;
+ mipi_dsi->lcd_config->dpi_fmt = MIPI_RGB888;
+ setting->fbi->var.bits_per_pixel = 32;
+
+ /* TODO Add bandwidth check */
+
+ if (setting->fbi->fbops->fb_check_var)
+ err = setting->fbi->fbops->fb_check_var(&setting->fbi->var,
+ setting->fbi);
+ if (err)
+ goto err0;
+
+ err = fb_add_videomode(mipi_dsi->mode,
+ &setting->fbi->modelist);
+ if (err)
+ goto err0;
+
+ fb_videomode_to_var(&setting->fbi->var, mipi_dsi->mode);
+ setting->fbi->mode = mipi_dsi->mode;
+err0:
+ return err;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(mipi_dsi_lcd_db); i++) {
+ if (!strcmp(mipi_dsi->lcd_panel,
+ mipi_dsi_lcd_db[i].lcd_panel)) {
+ mipi_dsi->lcd_callback =
+ &mipi_dsi_lcd_db[i].lcd_callback;
+ break;
+ }
+ }
+ if (i == ARRAY_SIZE(mipi_dsi_lcd_db)) {
+ dev_err(dev, "failed to find supported lcd panel.\n");
+ return -EINVAL;
+ }
+
+ /* set default bpp to 32 if not set*/
+ if (!setting->default_bpp)
+ setting->default_bpp = 32;
+
+ mipi_dsi->lcd_callback->get_mipi_lcd_videomode(&mipi_lcd_modedb, &size,
+ &mipi_dsi->lcd_config);
+
+ err = fb_find_mode(&setting->fbi->var, setting->fbi,
+ setting->dft_mode_str,
+ mipi_lcd_modedb, size, NULL,
+ setting->default_bpp);
+ if (err != 1)
+ fb_videomode_to_var(&setting->fbi->var, mipi_lcd_modedb);
+
+ INIT_LIST_HEAD(&setting->fbi->modelist);
+ for (i = 0; i < size; i++) {
+ fb_var_to_videomode(&mode, &setting->fbi->var);
+ if (fb_mode_is_equal(&mode, mipi_lcd_modedb + i)) {
+ err = fb_add_videomode(mipi_lcd_modedb + i,
+ &setting->fbi->modelist);
+ mipi_dsi->mode = mipi_lcd_modedb + i;
+ break;
+ }
+ }
+
+ if ((err < 0) || (size == i)) {
+ dev_err(dev, "failed to add videomode.\n");
+ return err;
+ }
+
+ setting->fbi->mode = mipi_dsi->mode;
+
+ return 0;
+}
+
+static int mipi_dsi_disp_init(struct mxc_dispdrv_handle *disp,
+ struct mxc_dispdrv_setting *setting)
+{
+ struct mipi_dsi_info *mipi_dsi = mxc_dispdrv_getdata(disp);
+ struct device *dev = &mipi_dsi->pdev->dev;
+ struct device_node *np = dev->of_node;
+ struct reset_control *reset = NULL;
+ int ret = 0;
+
+ if (!mipi_dsi->encoder) {
+ reset = of_reset_control_get(np, NULL);
+ if (IS_ERR(reset))
+ return PTR_ERR(reset);
+ }
+
+ ret = mipi_dsi_lcd_init(mipi_dsi, setting);
+ if (ret) {
+ dev_err(dev, "failed to init mipi dsi lcd\n");
+ goto out;
+ }
+
+ dev_info(dev, "MIPI DSI dispdv inited\n");
+
+out:
+ if (!mipi_dsi->encoder)
+ reset_control_put(reset);
+
+ return ret;
+}
+
+static void mipi_dsi_disp_deinit(struct mxc_dispdrv_handle *disp)
+{
+ struct mipi_dsi_info *mipi_dsi;
+
+ mipi_dsi = mxc_dispdrv_getdata(disp);
+
+ if (mipi_dsi->bl)
+ backlight_device_unregister(mipi_dsi->bl);
+}
+
+static void mipi_dsi_set_mode(struct mipi_dsi_info *mipi_dsi,
+ uint8_t mode)
+{
+ uint32_t pkt_control;
+
+ pkt_control = readl(mipi_dsi->mmio_base + HOST_PKT_CONTROL);
+
+ switch (mode) {
+ case DSI_LP_MODE:
+ writel(0x1, mipi_dsi->mmio_base + HOST_CFG_NONCONTINUOUS_CLK);
+ break;
+ case DSI_HS_MODE:
+ writel(0x0, mipi_dsi->mmio_base + HOST_CFG_NONCONTINUOUS_CLK);
+ break;
+ default:
+ dev_err(&mipi_dsi->pdev->dev,
+ "invalid dsi mode\n");
+ return;
+ }
+
+ mdelay(1);
+}
+
+static uint32_t fmt_to_bpp(enum mipi_dsi_dpi_fmt dpi_fmt)
+{
+ switch (dpi_fmt) {
+ case MIPI_RGB888:
+ return 24;
+ case MIPI_RGB565_PACKED:
+ return 16;
+ default:
+ return 0;
+ }
+}
+
+/*
+static void dphy_calc_dividers(int *cm, int *cn, int *co)
+{
+}
+*/
+
+static int mipi_dsi_dphy_init(struct mipi_dsi_info *mipi_dsi)
+{
+ int i, best_div = -1;
+ int64_t delta;
+ uint64_t least_delta = ~0U;
+ uint32_t bpp, time_out = 100;
+ uint32_t lock;
+ uint32_t req_bit_clk;
+ uint64_t limit, div_result;
+ uint64_t denominator, numerator, divisor;
+ uint64_t norm_denom, norm_num, split_denom;
+ struct pll_divider div = { 0 };
+ struct fb_videomode *mode = mipi_dsi->mode;
+ struct mipi_lcd_config *lcd_config = mipi_dsi->lcd_config;
+
+#ifndef CONFIG_FB_IMX64
+ regmap_update_bits(mipi_dsi->regmap, SIM_SOPT1,
+ MIPI_ISO_DISABLE, MIPI_ISO_DISABLE);
+#endif
+
+ bpp = fmt_to_bpp(lcd_config->dpi_fmt);
+ req_bit_clk = PICOS2KHZ2(mode->pixclock, bpp) * 1000U;
+
+ switch (lcd_config->data_lane_num) {
+ case 1:
+ break;
+ case 2:
+ req_bit_clk = req_bit_clk >> 1;
+ break;
+ case 4:
+ req_bit_clk = req_bit_clk >> 2;
+ break;
+ default:
+ dev_err(&mipi_dsi->pdev->dev,
+ "requested data lane num is invalid\n");
+ return -EINVAL;
+ }
+
+ if (mipi_dsi->encoder) {
+ if (req_bit_clk > lcd_config->max_phy_clk)
+ return -EINVAL;
+ }
+
+ /* calc CM, CN and CO according to PHY PLL formula:
+ *
+ * 'PLL out bitclk = refclk * CM / (CN * CO);'
+ *
+ * Let:
+ * 'numerator = bitclk / divisor';
+ * 'denominator = refclk / divisor';
+ * Then:
+ * 'numerator / denominator = CM / (CN * CO)';
+ *
+ * CM is in [16, 255]
+ * CN is in [1, 32]
+ * CO is in { 1, 2, 4, 8 };
+ */
+ divisor = gcd(mipi_dsi->phy_ref_clkfreq, req_bit_clk);
+ WARN_ON(divisor == 1);
+
+ div_result = req_bit_clk;
+ do_div(div_result, divisor);
+ numerator = div_result;
+
+ div_result = mipi_dsi->phy_ref_clkfreq;
+ do_div(div_result, divisor);
+ denominator = div_result;
+
+ /* denominator & numerator out of range check */
+ if (DIV_ROUND_CLOSEST_ULL(numerator, denominator) > 255 ||
+ DIV_ROUND_CLOSEST_ULL(denominator, numerator) > 32 * 8)
+ return -EINVAL;
+
+ /* Normalization: reduce or increase
+ * numerator to [16, 255]
+ * denominator to [1, 32 * 8]
+ * Reduce normalization result is 'approximiate'
+ * Increase nomralization result is 'precise'
+ */
+ if (numerator > 255 || denominator > 32 * 8) {
+ /* approximate */
+ if (likely(numerator > denominator)) {
+ /* 'numerator > 255';
+ * 'limit' should meet below conditions:
+ * a. '(numerator / limit) >= 16'
+ * b. '(denominator / limit) >= 1'
+ */
+ limit = min(denominator,
+ DIV_ROUND_CLOSEST_ULL(numerator, 16));
+
+ /* Let:
+ * norm_num = numerator / i;
+ * norm_denom = denominator / i;
+ *
+ * So:
+ * delta = numerator * norm_denom -
+ * denominator * norm_num
+ */
+ for (i = 2; i <= limit; i++) {
+ norm_num = DIV_ROUND_CLOSEST_ULL(numerator, i);
+ if (norm_num > 255)
+ continue;
+
+ norm_denom = DIV_ROUND_CLOSEST_ULL(denominator, i);
+
+ /* 'norm_num <= 255' && 'norm_num > norm_denom'
+ * so, 'norm_denom < 256'
+ */
+ delta = numerator * norm_denom -
+ denominator * norm_num;
+ delta = abs(delta);
+ if (delta < least_delta) {
+ least_delta = delta;
+ best_div = i;
+ } else if (delta == least_delta) {
+ /* choose better one IF:
+ * 'norm_denom' derived from last 'best_div'
+ * needs later split, i.e, 'norm_denom > 32'.
+ */
+ if (DIV_ROUND_CLOSEST_ULL(denominator, best_div) > 32) {
+ least_delta = delta;
+ best_div = i;
+ }
+ }
+ }
+ } else {
+ /* 'denominator > 32 * 8';
+ * 'limit' should meet below conditions:
+ * a. '(numerator / limit >= 16'
+ * b. '(denominator / limit >= 1': obviously.
+ */
+ limit = DIV_ROUND_CLOSEST_ULL(numerator, 16);
+ if (!limit ||
+ DIV_ROUND_CLOSEST_ULL(denominator, limit) > 32 * 8)
+ return -EINVAL;
+
+ for (i = 2; i <= limit; i++) {
+ norm_denom = DIV_ROUND_CLOSEST_ULL(denominator, i);
+ if (norm_denom > 32 * 8)
+ continue;
+
+ norm_num = DIV_ROUND_CLOSEST_ULL(numerator, i);
+
+ /* 'norm_denom <= 256' && 'norm_num < norm_denom'
+ * so, 'norm_num <= 255'
+ */
+ delta = numerator * norm_denom -
+ denominator * norm_num;
+ delta = abs(delta);
+ if (delta < least_delta) {
+ least_delta = delta;
+ best_div = i;
+ } else if (delta == least_delta) {
+ if (DIV_ROUND_CLOSEST_ULL(denominator, best_div) > 32) {
+ least_delta = delta;
+ best_div = i;
+ }
+ }
+ }
+ }
+
+ numerator = DIV_ROUND_CLOSEST_ULL(numerator, best_div);
+ denominator = DIV_ROUND_CLOSEST_ULL(denominator, best_div);
+ } else if (numerator < 16) {
+ /* precise */
+
+ /* 'limit' should meet below conditions:
+ * a. 'denominator * limit <= 32 * 8'
+ * b. '16 <= numerator * limit <= 255'
+ * Choose 'limit' to be the least value
+ * which makes 'numerator * limit' to be
+ * in [16, 255].
+ */
+ limit = min(256 / (uint32_t)denominator,
+ 255 / (uint32_t)numerator);
+ if (limit == 1 || limit < DIV_ROUND_UP_ULL(16, numerator))
+ return -EINVAL;
+
+ /* choose the least available value for 'limit' */
+ limit = DIV_ROUND_UP_ULL(16, numerator);
+ numerator = numerator * limit;
+ denominator = denominator * limit;
+
+ WARN_ON(numerator < 16 || denominator > 32 * 8);
+ }
+
+ div.cm = cm_map_table[numerator - 16];
+
+ /* split 'denominator' to 'CN' and 'CO' */
+ if (denominator > 32) {
+ /* traverse four possible values of 'CO'
+ * there must be some value of 'CO' can be used
+ */
+ least_delta = ~0U;
+ for (i = 0; i < 4; i++) {
+ split_denom = DIV_ROUND_CLOSEST_ULL(denominator, 1 << i);
+ if (split_denom > 32)
+ continue;
+
+ /* calc deviation to choose the best one */
+ delta = denominator - split_denom * (1 << i);
+ delta = abs(delta);
+ if (delta < least_delta) {
+ least_delta = delta;
+ div.co = co_map_table[i];
+ div.cn = cn_map_table[split_denom - 1];
+ }
+ }
+ } else {
+ div.co = co_map_table[1 >> 1];
+ div.cn = cn_map_table[denominator - 1];
+ }
+
+ writel(div.cn, mipi_dsi->mmio_base + DPHY_CN);
+ writel(div.cm, mipi_dsi->mmio_base + DPHY_CM);
+ writel(div.co, mipi_dsi->mmio_base + DPHY_CO);
+
+ writel(0x25, mipi_dsi->mmio_base + DPHY_TST);
+ writel(0x0, mipi_dsi->mmio_base + DPHY_PD_PLL);
+
+ while(!(lock = readl(mipi_dsi->mmio_base + DPHY_LOCK))) {
+ udelay(10);
+ time_out--;
+ if (time_out == 0) {
+ dev_err(&mipi_dsi->pdev->dev, "cannot get the dphy lock = 0x%x\n", lock);
+ return -EINVAL;
+ }
+ }
+
+ dev_dbg(&mipi_dsi->pdev->dev, "%s: dphy lock = 0x%x\n", __func__, lock);
+
+ writel(0x0, mipi_dsi->mmio_base + DPHY_LOCK_BYP);
+ writel(0x1, mipi_dsi->mmio_base + DPHY_RTERM_SEL);
+ writel(0x0, mipi_dsi->mmio_base + DPHY_AUTO_PD_EN);
+ writel(0x1, mipi_dsi->mmio_base + DPHY_RXLPRP);
+ writel(0x1, mipi_dsi->mmio_base + DPHY_RXCDRP);
+ writel(0x0, mipi_dsi->mmio_base + DPHY_M_PRG_HS_PREPARE);
+ writel(0x0, mipi_dsi->mmio_base + DPHY_MC_PRG_HS_PREPARE);
+ writel(0x9, mipi_dsi->mmio_base + DPHY_M_PRG_HS_ZERO);
+ writel(0x20, mipi_dsi->mmio_base + DPHY_MC_PRG_HS_ZERO);
+ writel(0x5, mipi_dsi->mmio_base + DPHY_M_PRG_HS_TRAIL);
+ writel(0x5, mipi_dsi->mmio_base + DPHY_MC_PRG_HS_TRAIL);
+ writel(0x0, mipi_dsi->mmio_base + DPHY_PD_DPHY);
+
+#ifndef CONFIG_FB_IMX64
+ regmap_update_bits(mipi_dsi->regmap, SIM_SOPT1CFG,
+ DSI_PLL_EN, DSI_PLL_EN);
+#endif
+
+ return 0;
+}
+
+static int mipi_dsi_host_init(struct mipi_dsi_info *mipi_dsi)
+{
+ uint32_t lane_num;
+ struct mipi_lcd_config *lcd_config = mipi_dsi->lcd_config;
+
+ switch (lcd_config->data_lane_num) {
+ case 1:
+ lane_num = 0x0;
+ break;
+ case 2:
+ lane_num = 0x1;
+ break;
+ case 4:
+ lane_num = 0x3;
+ break;
+ default:
+ /* Invalid lane num */
+ return -EINVAL;
+ }
+
+#ifdef CONFIG_FB_IMX64_DEBUG
+ printk("%s: data_lane_num = %d\n", __func__, lcd_config->data_lane_num);
+#endif
+
+ writel(lane_num, mipi_dsi->mmio_base + HOST_CFG_NUM_LANES);
+ writel(mipi_dsi->encoder ? 0x0 : 0x1,
+ mipi_dsi->mmio_base + HOST_CFG_NONCONTINUOUS_CLK);
+ writel(0x1, mipi_dsi->mmio_base + HOST_CFG_T_PRE);
+ writel(52, mipi_dsi->mmio_base + HOST_CFG_T_POST);
+ writel(13, mipi_dsi->mmio_base + HOST_CFG_TX_GAP);
+ writel(mipi_dsi->encoder ? 0x0 : 0x1,
+ mipi_dsi->mmio_base + HOST_CFG_AUTOINSERT_EOTP);
+ writel(0x0, mipi_dsi->mmio_base + HOST_CFG_EXTRA_CMDS_AFTER_EOTP);
+ writel(0x0, mipi_dsi->mmio_base + HOST_CFG_HTX_TO_COUNT);
+ writel(0x0, mipi_dsi->mmio_base + HOST_CFG_LRX_H_TO_COUNT);
+ writel(0x0, mipi_dsi->mmio_base + HOST_CFG_BTA_H_TO_COUNT);
+ writel(0x3A98, mipi_dsi->mmio_base + HOST_CFG_TWAKEUP);
+
+ return 0;
+}
+
+static int mipi_dsi_dpi_init(struct mipi_dsi_info *mipi_dsi)
+{
+ uint32_t bpp, color_coding, pixel_fmt;
+ uint32_t pixel_fifo_level, hfp_period, hbp_period, hsa_period;
+ struct fb_videomode *mode = mipi_dsi->mode;
+ struct mipi_lcd_config *lcd_config = mipi_dsi->lcd_config;
+
+ bpp = fmt_to_bpp(lcd_config->dpi_fmt);
+
+ writel(mode->xres, mipi_dsi->mmio_base + DPI_PIXEL_PAYLOAD_SIZE);
+
+ switch (mipi_dsi->traffic_mode) {
+ case DSI_NON_BURST_WITH_SYNC_PULSE:
+#ifdef CONFIG_FB_IMX64
+ pixel_fifo_level = 8;
+ hfp_period = mode->right_margin - DSI_HFP_PKT_OVERHEAD;
+ hbp_period = mode->left_margin - DSI_HBP_PKT_OVERHEAD;
+ hsa_period = mode->hsync_len - DSI_HSA_PKT_OVERHEAD;
+#else
+ pixel_fifo_level = mode->xres;
+ hfp_period = 0x10;
+ hbp_period = 0x60;
+ hsa_period = 0xf0;
+#endif
+ break;
+ case DSI_BURST_MODE:
+ pixel_fifo_level = mode->xres;
+#ifdef CONFIG_FB_IMX64
+ hfp_period = mode->right_margin;
+ hbp_period = mode->left_margin;
+ hsa_period = mode->hsync_len;
+#else
+ hfp_period = mode->right_margin * (bpp >> 3);
+ hbp_period = mode->left_margin * (bpp >> 3);
+ hsa_period = mode->hsync_len * (bpp >> 3);
+#endif
+ break;
+ default:
+ pr_debug("unsupport traffic mode: %d\n",
+ mipi_dsi->traffic_mode);
+ return -EINVAL;
+ }
+ writel(pixel_fifo_level, mipi_dsi->mmio_base + DPI_PIXEL_FIFO_SEND_LEVEL);
+
+ switch (bpp) {
+ case 24:
+ color_coding = 5;
+ pixel_fmt = 3;
+ break;
+ case 16:
+ case 18:
+ default:
+ break;
+ }
+ writel(color_coding, mipi_dsi->mmio_base + DPI_INTERFACE_COLOR_CODING);
+ writel(pixel_fmt, mipi_dsi->mmio_base + DPI_PIXEL_FORMAT);
+#ifdef CONFIG_FB_IMX64
+ writel(0x1, mipi_dsi->mmio_base + DPI_VSYNC_POLARITY);
+ writel(0x1, mipi_dsi->mmio_base + DPI_HSYNC_POLARITY);
+#else
+ writel(0x0, mipi_dsi->mmio_base + DPI_VSYNC_POLARITY);
+ writel(0x0, mipi_dsi->mmio_base + DPI_HSYNC_POLARITY);
+#endif
+ writel(mipi_dsi->traffic_mode,
+ mipi_dsi->mmio_base + DPI_VIDEO_MODE);
+
+ writel(hfp_period, mipi_dsi->mmio_base + DPI_HFP);
+ writel(hbp_period, mipi_dsi->mmio_base + DPI_HBP);
+ writel(hsa_period, mipi_dsi->mmio_base + DPI_HSA);
+
+ writel(0x0, mipi_dsi->mmio_base + DPI_ENABLE_MULT_PKTS);
+
+ writel(mode->upper_margin, mipi_dsi->mmio_base + DPI_VBP);
+ writel(mode->lower_margin, mipi_dsi->mmio_base + DPI_VFP);
+ writel(0x1, mipi_dsi->mmio_base + DPI_BLLP_MODE);
+ writel(0x0, mipi_dsi->mmio_base + DPI_USE_NULL_PKT_BLLP);
+
+ writel(mode->yres - 1, mipi_dsi->mmio_base + DPI_VACTIVE);
+
+ writel(0x0, mipi_dsi->mmio_base + DPI_VC);
+
+ return 0;
+}
+
+static void mipi_dsi_init_interrupt(struct mipi_dsi_info *mipi_dsi)
+{
+ uint32_t irqs_enable;
+
+ /* disable all the irqs */
+ writel(0xffffffff, mipi_dsi->mmio_base + HOST_IRQ_MASK);
+ writel(0x7, mipi_dsi->mmio_base + HOST_IRQ_MASK2);
+
+ irqs_enable = ~(HOST_IRQ_MASK_TX_PKT_DONE_MASK |
+ HOST_IRQ_MASK_RX_PKT_HDR_RCVD_MASK);
+
+ writel(irqs_enable, mipi_dsi->mmio_base + HOST_IRQ_MASK);
+}
+
+static int mipi_display_enter_sleep(struct mxc_dispdrv_handle *disp)
+{
+ int err;
+ struct mipi_dsi_info *mipi_dsi = mxc_dispdrv_getdata(disp);
+
+ err = mipi_dsi_dcs_cmd(mipi_dsi, MIPI_DCS_SET_DISPLAY_OFF,
+ NULL, 0);
+ if (err)
+ return -EINVAL;
+ msleep(50);
+
+ err = mipi_dsi_dcs_cmd(mipi_dsi, MIPI_DCS_ENTER_SLEEP_MODE,
+ NULL, 0);
+ if (err) {
+ dev_err(&mipi_dsi->pdev->dev,
+ "MIPI DSI DCS Command sleep in error!\n");
+ }
+ msleep(MIPI_LCD_SLEEP_MODE_DELAY);
+
+ return err;
+}
+
+static int mipi_display_exit_sleep(struct mxc_dispdrv_handle *disp)
+{
+ int err;
+ struct mipi_dsi_info *mipi_dsi = mxc_dispdrv_getdata(disp);
+
+ err = mipi_dsi_dcs_cmd(mipi_dsi, MIPI_DCS_EXIT_SLEEP_MODE,
+ NULL, 0);
+ if (err) {
+ dev_err(&mipi_dsi->pdev->dev,
+ "MIPI DSI DCS Command sleep-out error!\n");
+ return err;
+ }
+ msleep(MIPI_LCD_SLEEP_MODE_DELAY);
+
+ err = mipi_dsi_dcs_cmd(mipi_dsi, MIPI_DCS_SET_DISPLAY_ON,
+ NULL, 0);
+ msleep(20);
+
+ return err;
+}
+
+static void reset_dsi_domains(struct mipi_dsi_info *mipi_dsi, bool reset)
+{
+#ifdef CONFIG_FB_IMX64
+ /* pclk domain */
+ regmap_update_bits(mipi_dsi->regmap, SRC_MIPIPHY_RCR,
+ MIPI_DSI_PCLK_RESET_N, (reset ? 0 : MIPI_DSI_PCLK_RESET_N));
+ /* escape domain */
+ regmap_update_bits(mipi_dsi->regmap, SRC_MIPIPHY_RCR,
+ MIPI_DSI_ESC_RESET_N, (reset ? 0 : MIPI_DSI_ESC_RESET_N));
+ /* byte domain */
+ regmap_update_bits(mipi_dsi->regmap, SRC_MIPIPHY_RCR,
+ MIPI_DSI_RESET_BYTE_N, (reset ? 0 : MIPI_DSI_RESET_BYTE_N));
+ /* dpi domain */
+ regmap_update_bits(mipi_dsi->regmap, SRC_MIPIPHY_RCR,
+ MIPI_DSI_DPI_RESET_N, (reset ? 0 : MIPI_DSI_DPI_RESET_N));
+#else
+ /* escape domain */
+ regmap_update_bits(mipi_dsi->regmap, SIM_SOPT1CFG,
+ DSI_RST_ESC_N, (reset ? 0 : DSI_RST_ESC_N));
+ /* byte domain */
+ regmap_update_bits(mipi_dsi->regmap, SIM_SOPT1CFG,
+ DSI_RST_BYTE_N, (reset ? 0 : DSI_RST_BYTE_N));
+
+ /* dpi domain */
+ regmap_update_bits(mipi_dsi->regmap, SIM_SOPT1CFG,
+ DSI_RST_DPI_N, (reset ? 0 : DSI_RST_DPI_N));
+#endif
+}
+
+static int mipi_dsi_enable(struct mxc_dispdrv_handle *disp,
+ struct fb_info *fbi)
+{
+ int ret;
+ struct mipi_dsi_info *mipi_dsi = mxc_dispdrv_getdata(disp);
+
+#ifndef CONFIG_FB_IMX64
+ if (!mipi_dsi->dsi_power_on)
+ pm_runtime_get_sync(&mipi_dsi->pdev->dev);
+#endif
+
+ if (!mipi_dsi->lcd_inited) {
+#ifdef CONFIG_FB_IMX64
+ reset_dsi_domains(mipi_dsi, 0);
+#else
+ ret = clk_set_rate(mipi_dsi->esc_clk, 80000000);
+ if (ret) {
+ dev_err(&mipi_dsi->pdev->dev,
+ "clk enable error: %d!\n", ret);
+ return ret;
+ }
+
+ ret = clk_prepare_enable(mipi_dsi->esc_clk);
+ if (ret) {
+ dev_err(&mipi_dsi->pdev->dev,
+ "clk enable error: %d!\n", ret);
+ return -EINVAL;
+ }
+#endif
+
+ if ((ret = mipi_dsi_dphy_init(mipi_dsi)) < 0)
+ return ret;
+
+ if ((ret = mipi_dsi_host_init(mipi_dsi)) < 0)
+ return ret;
+
+ mipi_dsi_dpi_init(mipi_dsi);
+
+#ifndef CONFIG_FB_IMX64
+ reset_dsi_domains(mipi_dsi, 0);
+
+ /* display_en */
+ regmap_update_bits(mipi_dsi->regmap, SIM_SOPT1CFG,
+ DSI_SD, 0x0);
+ /* normal cm */
+ regmap_update_bits(mipi_dsi->regmap, SIM_SOPT1CFG,
+ DSI_CM, 0x0);
+#endif
+ msleep(20);
+
+ if (!mipi_dsi->encoder) {
+ ret = device_reset(&mipi_dsi->pdev->dev);
+ if (ret) {
+ dev_err(&mipi_dsi->pdev->dev,
+ "failed to reset device: %d\n", ret);
+ return -EINVAL;
+ }
+ msleep(60);
+
+ mipi_dsi_init_interrupt(mipi_dsi);
+
+ ret = mipi_dsi->lcd_callback->mipi_lcd_setup(mipi_dsi);
+ if (ret < 0) {
+ dev_err(&mipi_dsi->pdev->dev,
+ "failed to init mipi lcd.\n");
+ return ret;
+ }
+ mipi_dsi_set_mode(mipi_dsi, DSI_HS_MODE);
+ }
+
+ mipi_dsi->lcd_inited = 1;
+ } else {
+#ifndef CONFIG_FB_IMX64
+ ret = clk_prepare_enable(mipi_dsi->esc_clk);
+ if (ret) {
+ dev_err(&mipi_dsi->pdev->dev,
+ "clk enable error: %d!\n", ret);
+ return -EINVAL;
+ }
+#endif
+
+ reset_dsi_domains(mipi_dsi, 0);
+
+ if (!mipi_dsi->encoder) {
+ ret = mipi_display_exit_sleep(mipi_dsi->disp_mipi);
+ if (ret) {
+ dev_err(&mipi_dsi->pdev->dev, "exit sleep failed\n");
+ return -EINVAL;
+ }
+ }
+ }
+
+ return 0;
+}
+
+static void mipi_dsi_wr_tx_header(struct mipi_dsi_info *mipi_dsi,
+ u8 di, u8 data0, u8 data1, u8 mode, u8 need_bta)
+{
+ uint32_t pkt_control = 0;
+ uint16_t word_count = 0;
+
+ word_count = data0 | (data1 << 8);
+ pkt_control = HOST_PKT_CONTROL_WC(word_count) |
+ HOST_PKT_CONTROL_VC(0) |
+ HOST_PKT_CONTROL_DT(di) |
+ HOST_PKT_CONTROL_HS_SEL(mode) |
+ HOST_PKT_CONTROL_BTA_TX(need_bta);
+
+ dev_dbg(&mipi_dsi->pdev->dev, "pkt_control = %x\n", pkt_control);
+ writel(pkt_control, mipi_dsi->mmio_base + HOST_PKT_CONTROL);
+}
+
+static void mipi_dsi_wr_tx_data(struct mipi_dsi_info *mipi_dsi,
+ uint32_t tx_data)
+{
+ writel(tx_data, mipi_dsi->mmio_base + HOST_TX_PAYLOAD);
+}
+
+static void mipi_dsi_long_data_wr(struct mipi_dsi_info *mipi_dsi,
+ const uint8_t *data0, uint32_t data_size)
+{
+ uint32_t data_cnt = 0, payload = 0;
+
+ /* in case that data count is more than 4 */
+ for (data_cnt = 0; data_cnt < data_size; data_cnt += 4) {
+ /*
+ * after sending 4bytes per one time,
+ * send remainder data less then 4.
+ */
+ if ((data_size - data_cnt) < 4) {
+ if ((data_size - data_cnt) == 3) {
+ payload = data0[data_cnt] |
+ (data0[data_cnt + 1] << 8) |
+ (data0[data_cnt + 2] << 16);
+ dev_dbg(&mipi_dsi->pdev->dev, "count = 3 payload = %x, %x %x %x\n",
+ payload, data0[data_cnt], data0[data_cnt + 1], data0[data_cnt + 2]);
+ } else if ((data_size - data_cnt) == 2) {
+ payload = data0[data_cnt] |
+ (data0[data_cnt + 1] << 8);
+ dev_dbg(&mipi_dsi->pdev->dev, "count = 2 payload = %x, %x %x\n",
+ payload, data0[data_cnt], data0[data_cnt + 1]);
+ } else if ((data_size - data_cnt) == 1) {
+ payload = data0[data_cnt];
+ dev_dbg(&mipi_dsi->pdev->dev, "count = 1 payload = %x, %x\n",
+ payload, data0[data_cnt]);
+ }
+
+ mipi_dsi_wr_tx_data(mipi_dsi, payload);
+ } else {
+ payload = data0[data_cnt] |
+ (data0[data_cnt + 1] << 8) |
+ (data0[data_cnt + 2] << 16) |
+ (data0[data_cnt + 3] << 24);
+
+ dev_dbg(&mipi_dsi->pdev->dev,
+ "count = 4 payload = %x, %x %x %x %x\n",
+ payload, *(u8 *)(data0 + data_cnt),
+ data0[data_cnt + 1],
+ data0[data_cnt + 2],
+ data0[data_cnt + 3]);
+
+ mipi_dsi_wr_tx_data(mipi_dsi, payload);
+ }
+ }
+}
+
+static int mipi_dsi_pkt_write(struct mipi_dsi_info *mipi_dsi,
+ u8 data_type, const u32 *buf, int len)
+{
+ int ret = 0;
+ struct platform_device *pdev = mipi_dsi->pdev;
+ const uint8_t *data = (const uint8_t *)buf;
+
+ if (len == 0)
+ /* handle generic long write command */
+ mipi_dsi_wr_tx_header(mipi_dsi, data_type, data[0], data[1], DSI_LP_MODE, 0);
+ else {
+ reinit_completion(&dsi_tx_done);
+
+ /* handle generic long write command */
+ mipi_dsi_long_data_wr(mipi_dsi, data, len);
+ mipi_dsi_wr_tx_header(mipi_dsi, data_type, len & 0xff,
+ (len & 0xff00) >> 8, DSI_LP_MODE, 0);
+ }
+
+ /* send packet */
+ writel(0x1, mipi_dsi->mmio_base + HOST_SEND_PACKET);
+ ret = wait_for_completion_timeout(&dsi_tx_done, MIPI_FIFO_TIMEOUT);
+
+ if (!ret) {
+ dev_err(&pdev->dev, "wait tx done timeout!\n");
+ return -ETIMEDOUT;
+ }
+ mdelay(10);
+
+ return 0;
+}
+
+static uint32_t mipi_dsi_rd_rx_header(struct mipi_dsi_info *mipi_dsi)
+{
+ return readl(mipi_dsi->mmio_base + HOST_PKT_RX_PKT_HEADER);
+}
+
+static int mipi_dsi_pkt_read(struct mipi_dsi_info *mipi_dsi,
+ uint8_t data_type, uint32_t *buf, int len)
+{
+ int ret;
+ uint32_t rx_hdr;
+ struct platform_device *pdev = mipi_dsi->pdev;
+ const uint8_t *data = (const uint8_t *)buf;
+
+ if (len <= 4) {
+ reinit_completion(&dsi_rx_done);
+
+ mipi_dsi_wr_tx_header(mipi_dsi, data_type, data[0], data[1], DSI_LP_MODE, 1);
+ writel(0x1, mipi_dsi->mmio_base + HOST_SEND_PACKET);
+
+ ret = wait_for_completion_timeout(&dsi_rx_done, MIPI_FIFO_TIMEOUT);
+ if (!ret) {
+ dev_err(&pdev->dev, "wait rx done timeout!\n");
+ return -ETIMEDOUT;
+ }
+
+ rx_hdr = mipi_dsi_rd_rx_header(mipi_dsi);
+ dev_dbg(&pdev->dev, "rx: rx_hdr = 0x%x, data type = 0x%x, word_count = 0x%x\n",
+ rx_hdr, (rx_hdr >> 16) & 0x3f, rx_hdr & 0xffff);
+
+ buf[0] = rx_hdr & 0xff;
+ } else {
+ /* TODO: add support later */
+ }
+
+ return 0;
+}
+
+static int mipi_dsi_dcs_cmd(struct mipi_dsi_info *mipi_dsi,
+ u8 cmd, const u32 *param, int num)
+{
+ int err = 0;
+ u32 buf[DSI_CMD_BUF_MAXSIZE];
+
+ switch (cmd) {
+ case MIPI_DCS_EXIT_SLEEP_MODE:
+ case MIPI_DCS_ENTER_SLEEP_MODE:
+ case MIPI_DCS_SET_DISPLAY_ON:
+ case MIPI_DCS_SET_DISPLAY_OFF:
+ buf[0] = cmd;
+ buf[1] = 0x0;
+ err = mipi_dsi_pkt_write(mipi_dsi,
+ MIPI_DSI_DCS_SHORT_WRITE, buf, 0);
+ break;
+
+ default:
+ dev_err(&mipi_dsi->pdev->dev,
+ "MIPI DSI DCS Command:0x%x Not supported!\n", cmd);
+ break;
+ }
+
+ return err;
+}
+
+static void mipi_dsi_disable(struct mxc_dispdrv_handle *disp,
+ struct fb_info *fbi)
+{
+ struct mipi_dsi_info *mipi_dsi = mxc_dispdrv_getdata(disp);
+
+ if (!mipi_dsi->encoder)
+ mipi_display_enter_sleep(mipi_dsi->disp_mipi);
+
+#ifndef CONFIG_FB_IMX64
+ clk_disable_unprepare(mipi_dsi->esc_clk);
+#endif
+ reset_dsi_domains(mipi_dsi, 1);
+#ifdef CONFIG_FB_IMX64
+ regmap_update_bits(mipi_dsi->regmap, SRC_MIPIPHY_RCR,
+ MIPI_DSI_PCLK_RESET_N, 0x0);
+#else
+ regmap_update_bits(mipi_dsi->regmap, SIM_SOPT1CFG,
+ DSI_PLL_EN, 0x0);
+#endif
+}
+
+static int mipi_dsi_setup(struct mxc_dispdrv_handle *disp,
+ struct fb_info *fbi)
+{
+ struct mipi_dsi_info *mipi_dsi = mxc_dispdrv_getdata(disp);
+ int xres_virtual = fbi->var.xres_virtual;
+ int yres_virtual = fbi->var.yres_virtual;
+ int xoffset = fbi->var.xoffset;
+ int yoffset = fbi->var.yoffset;
+ int pixclock = fbi->var.pixclock;
+
+ if (!mipi_dsi->mode)
+ return 0;
+
+ /* set the mode back to var in case userspace changes it */
+ fb_videomode_to_var(&fbi->var, mipi_dsi->mode);
+
+ /* restore some var entries cached */
+ fbi->var.xres_virtual = xres_virtual;
+ fbi->var.yres_virtual = yres_virtual;
+ fbi->var.xoffset = xoffset;
+ fbi->var.yoffset = yoffset;
+ fbi->var.pixclock = pixclock;
+
+ return 0;
+}
+
+static struct mxc_dispdrv_driver mipi_dsi_drv = {
+ .name = DISPDRV_MIPI,
+ .init = mipi_dsi_disp_init,
+ .deinit = mipi_dsi_disp_deinit,
+ .enable = mipi_dsi_enable,
+ .disable = mipi_dsi_disable,
+ .setup = mipi_dsi_setup,
+};
+
+static irqreturn_t mipi_dsi_irq_handler(int irq, void *data)
+{
+ uint32_t irq_status;
+ struct mipi_dsi_info *mipi_dsi = data;
+ struct platform_device *pdev = mipi_dsi->pdev;
+
+ irq_status = readl(mipi_dsi->mmio_base + HOST_IRQ_STATUS);
+
+ dev_dbg(&pdev->dev, "irq_status = 0x%x\n", irq_status);
+
+ if (irq_status & HOST_IRQ_STATUS_TX_PKT_DONE) {
+ dev_dbg(&pdev->dev, "payload tx finished\n");
+ complete(&dsi_tx_done);
+ }
+
+ if (irq_status & HOST_IRQ_STATUS_RX_PKT_HDR_RCVD) {
+ dev_dbg(&pdev->dev, "rx data finished\n");
+ complete(&dsi_rx_done);
+ }
+
+ return IRQ_HANDLED;
+}
+
+#ifdef CONFIG_FB_IMX64
+static int dsi_clks_init(struct mipi_dsi_info *minfo)
+{
+ int ret = 0;
+ struct platform_device *pdev = minfo->pdev;
+ struct device_node *np = pdev->dev.of_node;
+
+ minfo->core_clk = devm_clk_get(&pdev->dev, "core");
+ BUG_ON(IS_ERR(minfo->core_clk));
+
+ minfo->phy_ref_clk = devm_clk_get(&pdev->dev, "phy_ref");
+ BUG_ON(IS_ERR(minfo->phy_ref_clk));
+
+ minfo->rxesc_clk = devm_clk_get(&pdev->dev, "rxesc");
+ BUG_ON(IS_ERR(minfo->rxesc_clk));
+
+ minfo->txesc_clk = devm_clk_get(&pdev->dev, "txesc");
+ BUG_ON(IS_ERR(minfo->txesc_clk));
+
+ minfo->dbi_clk = devm_clk_get(&pdev->dev, "dbi");
+ BUG_ON(IS_ERR(minfo->dbi_clk));
+
+
+ ret = clk_set_rate(minfo->phy_ref_clk, minfo->phy_ref_clkfreq);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "set phy_ref clock rate failed\n");
+ goto out;
+ }
+
+ ret = clk_set_rate(minfo->rxesc_clk, 80000000);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "set rxesc clock rate failed\n");
+ goto out;
+ }
+
+ ret = clk_set_rate(minfo->txesc_clk, 20000000);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "set txesc clock rate failed\n");
+ goto out;
+ }
+
+ clk_prepare_enable(minfo->core_clk);
+ clk_prepare_enable(minfo->phy_ref_clk);
+ clk_prepare_enable(minfo->rxesc_clk);
+ clk_prepare_enable(minfo->txesc_clk);
+ /* TODO: dbi clk is not used yet */
+
+out:
+ return ret;
+}
+#endif
+
+/**
+ * This function is called by the driver framework to initialize the MIPI DSI
+ * device.
+ *
+ * @param pdev The device structure for the MIPI DSI passed in by the
+ * driver framework.
+ *
+ * @return Returns 0 on success or negative error code on error
+ */
+static int mipi_dsi_probe(struct platform_device *pdev)
+{
+ struct device_node *np = pdev->dev.of_node;
+ struct mipi_dsi_info *mipi_dsi;
+ struct device_node *endpoint = NULL, *remote;
+ struct resource *res;
+ const char *lcd_panel;
+ int ret = 0;
+ u32 vmode_index;
+ uint32_t phy_ref_clkfreq;
+
+ mipi_dsi = devm_kzalloc(&pdev->dev, sizeof(*mipi_dsi), GFP_KERNEL);
+ if (!mipi_dsi)
+ return -ENOMEM;
+ mipi_dsi->pdev = pdev;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ dev_err(&pdev->dev, "failed to get platform mem resource\n");
+ return -ENOMEM;
+ }
+
+ mipi_dsi->mmio_base = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(mipi_dsi->mmio_base))
+ return -ENODEV;
+
+ mipi_dsi->irq = platform_get_irq(pdev, 0);
+ if (mipi_dsi->irq < 0) {
+ dev_err(&pdev->dev, "failed to get device irq\n");
+ return -EINVAL;
+ }
+
+ ret = devm_request_irq(&pdev->dev, mipi_dsi->irq,
+ mipi_dsi_irq_handler,
+ 0, "mipi_dsi_northwest", mipi_dsi);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to request mipi dsi irq\n");
+ return ret;
+ }
+
+ ret = of_property_read_u32(np, "phy-ref-clkfreq",
+ &phy_ref_clkfreq);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "failed to get phy reference clock rate\n");
+ return -EINVAL;
+ }
+
+ if (phy_ref_clkfreq < 24000000 || phy_ref_clkfreq > 200000000) {
+ dev_err(&pdev->dev, "invalid phy reference clock rate\n");
+ return -EINVAL;
+ }
+ mipi_dsi->phy_ref_clkfreq = phy_ref_clkfreq;
+
+#ifdef CONFIG_FB_IMX64
+ dsi_clks_init(mipi_dsi);
+
+ mipi_dsi->regmap = syscon_regmap_lookup_by_phandle(np, "reset");
+ if (IS_ERR(mipi_dsi->regmap)) {
+ dev_err(&pdev->dev, "failed to get reset regmap\n");
+ return -EINVAL;
+ }
+
+ mipi_dsi->mux_sel = syscon_regmap_lookup_by_phandle(np, "mux-sel");
+ if (IS_ERR(mipi_dsi->mux_sel)) {
+ dev_err(&pdev->dev, "failed to get mux_sel regmap\n");
+ return -EINVAL;
+ }
+
+ /* TODO: use lcdif for source */
+ regmap_update_bits(mipi_dsi->mux_sel, IOMUXC_GPR_GPR13,
+ GPR_MIPI_MUX_SEL, 0x0);
+
+#else
+ mipi_dsi->esc_clk = devm_clk_get(&pdev->dev, "mipi_dsi_clk");
+ if (IS_ERR(mipi_dsi->esc_clk)) {
+ dev_err(&pdev->dev, "failed to get esc clk\n");
+ return PTR_ERR(mipi_dsi->esc_clk);
+ }
+
+ mipi_dsi->regmap = syscon_regmap_lookup_by_phandle(np, "sim");
+ if (IS_ERR(mipi_dsi->regmap)) {
+ dev_err(&pdev->dev, "failed to get parent regmap\n");
+ return -EINVAL;
+ }
+#endif
+ /* check whether an encoder exists */
+ endpoint = of_graph_get_next_endpoint(np, NULL);
+ if (endpoint) {
+ remote = of_graph_get_remote_port_parent(endpoint);
+ if (!remote)
+ return -EINVAL;
+
+ ret = of_property_read_u32(remote, "video-mode", &vmode_index);
+ if ((ret < 0) || (vmode_index >= ARRAY_SIZE(mxc_cea_mode)))
+ return -EINVAL;
+ mipi_dsi->vmode_index = vmode_index;
+
+ mipi_dsi->mode = devm_kzalloc(&pdev->dev,
+ sizeof(struct fb_videomode),
+ GFP_KERNEL);
+ if (!mipi_dsi->mode)
+ return -ENOMEM;
+
+ memcpy(mipi_dsi->mode, &mxc_cea_mode[vmode_index],
+ sizeof(struct fb_videomode));
+
+ ret = of_property_read_u32(remote, "dsi-traffic-mode",
+ &mipi_dsi->traffic_mode);
+ if (ret < 0 || mipi_dsi->traffic_mode > 2) {
+ devm_kfree(&pdev->dev, mipi_dsi->mode);
+ return -EINVAL;
+ }
+
+ mipi_dsi->lcd_config = devm_kzalloc(&pdev->dev,
+ sizeof(struct mipi_lcd_config),
+ GFP_KERNEL);
+ if (!mipi_dsi->lcd_config) {
+ kfree(mipi_dsi->mode);
+ return -ENOMEM;
+ }
+
+ mipi_dsi->encoder = 1;
+ } else {
+ /* Default, using 'BURST-MODE' for mipi panel */
+ mipi_dsi->traffic_mode = 2;
+
+ ret = of_property_read_string(np, "lcd_panel", &lcd_panel);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to read lcd_panel property\n");
+ return ret;
+ }
+
+ /* mipi VDDA is sw1 in PMIC which is always on */
+
+ mipi_dsi->lcd_panel = kstrdup(lcd_panel, GFP_KERNEL);
+ if (!mipi_dsi->lcd_panel) {
+ dev_err(&pdev->dev, "failed to allocate lcd panel\n");
+ ret = -ENOMEM;
+ }
+ }
+
+ mipi_dsi->disp_mipi = mxc_dispdrv_register(&mipi_dsi_drv);
+ if (IS_ERR(mipi_dsi->disp_mipi)) {
+ dev_err(&pdev->dev, "mxc_dispdrv_register error\n");
+ ret = PTR_ERR(mipi_dsi->disp_mipi);
+ goto dispdrv_reg_fail;
+ }
+
+ mipi_dsi->mipi_dsi_pkt_read = mipi_dsi_pkt_read;
+ mipi_dsi->mipi_dsi_pkt_write = mipi_dsi_pkt_write;
+ mipi_dsi->mipi_dsi_dcs_cmd = mipi_dsi_dcs_cmd;
+
+#ifndef CONFIG_FB_IMX64
+ pm_runtime_enable(&pdev->dev);
+#endif
+ mxc_dispdrv_setdata(mipi_dsi->disp_mipi, mipi_dsi);
+ dev_set_drvdata(&pdev->dev, mipi_dsi);
+
+ dev_info(&pdev->dev, "i.MX MIPI DSI driver probed\n");
+ return ret;
+
+dispdrv_reg_fail:
+ if (mipi_dsi->lcd_panel)
+ kfree(mipi_dsi->lcd_panel);
+ return ret;
+}
+
+static int mipi_dsi_remove(struct platform_device *pdev)
+{
+ struct mipi_dsi_info *mipi_dsi = dev_get_drvdata(&pdev->dev);
+
+ mxc_dispdrv_puthandle(mipi_dsi->disp_mipi);
+ mxc_dispdrv_unregister(mipi_dsi->disp_mipi);
+
+ kfree(mipi_dsi->lcd_panel);
+ dev_set_drvdata(&pdev->dev, NULL);
+
+ return 0;
+}
+
+static void mipi_dsi_shutdown(struct platform_device *pdev)
+{
+ struct mipi_dsi_info *mipi_dsi = dev_get_drvdata(&pdev->dev);
+
+ if (mipi_dsi->lcd_inited) {
+#ifndef CONFIG_FB_IMX64
+ clk_prepare_enable(mipi_dsi->esc_clk);
+#endif
+ if (!mipi_dsi->encoder)
+ mipi_display_enter_sleep(mipi_dsi->disp_mipi);
+
+ writel(0x1, mipi_dsi->mmio_base + DPHY_PD_PLL);
+ writel(0x1, mipi_dsi->mmio_base + DPHY_PD_DPHY);
+#ifndef CONFIG_FB_IMX64
+ clk_disable_unprepare(mipi_dsi->esc_clk);
+#endif
+ mipi_dsi->lcd_inited = 0;
+ }
+
+ reset_dsi_domains(mipi_dsi, 1);
+
+#ifdef CONFIG_FB_IMX64
+ regmap_update_bits(mipi_dsi->regmap, SRC_MIPIPHY_RCR,
+ MIPI_DSI_PCLK_RESET_N, 0x0);
+#else
+ regmap_update_bits(mipi_dsi->regmap, SIM_SOPT1CFG,
+ DSI_PLL_EN, 0x0);
+#endif
+}
+
+static const struct of_device_id imx_mipi_dsi_dt_ids[] = {
+ { .compatible = "fsl,imx7ulp-mipi-dsi", .data = NULL, },
+ { .compatible = "fsl,imx8mq-mipi-dsi", .data = NULL, },
+ { }
+};
+MODULE_DEVICE_TABLE(of, imx_mipi_dsi_dt_ids);
+
+static int mipi_dsi_runtime_suspend(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct mipi_dsi_info *mipi_dsi = dev_get_drvdata(&pdev->dev);
+
+ mipi_dsi->dsi_power_on = 0;
+
+ return 0;
+}
+
+static int mipi_dsi_runtime_resume(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct mipi_dsi_info *mipi_dsi = dev_get_drvdata(&pdev->dev);
+
+ if (!mipi_dsi->dsi_power_on) {
+ request_bus_freq(BUS_FREQ_HIGH);
+ dev_dbg(dev, "mipi dsi busfreq high request.\n");
+
+ mipi_dsi->dsi_power_on = 1;
+ }
+
+ return 0;
+}
+
+static int mipi_dsi_suspend(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct mipi_dsi_info *mipi_dsi = dev_get_drvdata(&pdev->dev);
+
+ if (unlikely(mipi_dsi->lcd_inited)) {
+#ifndef CONFIG_FB_IMX64
+ clk_prepare_enable(mipi_dsi->esc_clk);
+#endif
+
+ writel(0x1, mipi_dsi->mmio_base + DPHY_PD_PLL);
+ writel(0x1, mipi_dsi->mmio_base + DPHY_PD_DPHY);
+
+#ifndef CONFIG_FB_IMX64
+ clk_disable_unprepare(mipi_dsi->esc_clk);
+#endif
+ mipi_dsi->lcd_inited = 0;
+ }
+
+ pinctrl_pm_select_sleep_state(dev);
+
+ return 0;
+}
+
+static int mipi_dsi_resume(struct device *dev)
+{
+ pinctrl_pm_select_default_state(dev);
+
+ return 0;
+}
+
+static const struct dev_pm_ops mipi_dsi_pm_ops = {
+ .suspend = mipi_dsi_suspend,
+ .resume = mipi_dsi_resume,
+ .runtime_suspend = mipi_dsi_runtime_suspend,
+ .runtime_resume = mipi_dsi_runtime_resume,
+ .runtime_idle = NULL,
+};
+
+static struct platform_driver mipi_dsi_driver = {
+ .driver = {
+ .of_match_table = imx_mipi_dsi_dt_ids,
+ .name = "mipi_dsi_northwest",
+ .pm = &mipi_dsi_pm_ops,
+ },
+ .probe = mipi_dsi_probe,
+ .remove = mipi_dsi_remove,
+ .shutdown = mipi_dsi_shutdown,
+};
+
+static int __init mipi_dsi_init(void)
+{
+ int err;
+
+ err = platform_driver_register(&mipi_dsi_driver);
+ if (err) {
+ pr_err("mipi_dsi_driver register failed\n");
+ return err;
+ }
+
+ pr_debug("MIPI DSI driver module loaded: %s\n", mipi_dsi_driver.driver.name);
+
+ return 0;
+}
+
+static void __exit mipi_dsi_exit(void)
+{
+ platform_driver_unregister(&mipi_dsi_driver);
+}
+
+module_init(mipi_dsi_init);
+module_exit(mipi_dsi_exit);
+
+MODULE_AUTHOR("NXP Semiconductor, Inc.");
+MODULE_DESCRIPTION("i.MX MIPI DSI driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/video/fbdev/mxc/mipi_dsi_samsung.c b/drivers/video/fbdev/mxc/mipi_dsi_samsung.c
new file mode 100644
index 000000000000..d6bcf2a3de9f
--- /dev/null
+++ b/drivers/video/fbdev/mxc/mipi_dsi_samsung.c
@@ -0,0 +1,952 @@
+/*
+ * Copyright (C) 2015 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2017 NXP.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/console.h>
+#include <linux/io.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/bitops.h>
+#include <linux/mipi_dsi_samsung.h>
+#include <linux/module.h>
+#include <linux/mxcfb.h>
+#include <linux/pm_runtime.h>
+#include <linux/busfreq-imx.h>
+#include <linux/backlight.h>
+#include <linux/of_device.h>
+#include <linux/of_address.h>
+#include <linux/regulator/consumer.h>
+#include <linux/reset.h>
+#include <linux/spinlock.h>
+#include <linux/delay.h>
+#include <video/mipi_display.h>
+#include <linux/mfd/syscon.h>
+
+#include "mipi_dsi.h"
+
+#define DISPDRV_MIPI "mipi_dsi_samsung"
+#define ROUND_UP(x) ((x)+1)
+#define NS2PS_RATIO (1000)
+#define MIPI_LCD_SLEEP_MODE_DELAY (120)
+#define MIPI_FIFO_TIMEOUT msecs_to_jiffies(250)
+
+static struct mipi_dsi_match_lcd mipi_dsi_lcd_db[] = {
+#ifdef CONFIG_FB_MXC_TRULY_WVGA_SYNC_PANEL
+ {
+ "TRULY-WVGA",
+ {mipid_hx8369_get_lcd_videomode, mipid_hx8369_lcd_setup}
+ },
+#endif
+#ifdef CONFIG_FB_MXC_TRULY_PANEL_TFT3P5079E
+ {
+ "TRULY-WVGA-TFT3P5079E",
+ {mipid_otm8018b_get_lcd_videomode, mipid_otm8018b_lcd_setup}
+ },
+#endif
+#ifdef CONFIG_FB_MXC_TRULY_PANEL_TFT3P5581E
+ {
+ "TRULY-WVGA-TFT3P5581E",
+ {mipid_hx8363_get_lcd_videomode, mipid_hx8363_lcd_setup}
+ },
+#endif
+ {
+ "", {NULL, NULL}
+ }
+};
+
+enum mipi_dsi_mode {
+ DSI_COMMAND_MODE,
+ DSI_VIDEO_MODE
+};
+
+enum mipi_dsi_trans_mode {
+ DSI_LP_MODE,
+ DSI_HS_MODE
+};
+
+static struct regulator *mipi_phy_reg;
+static DECLARE_COMPLETION(dsi_rx_done);
+static DECLARE_COMPLETION(dsi_tx_done);
+
+static void mipi_dsi_dphy_power_down(void);
+static void mipi_dsi_set_mode(struct mipi_dsi_info *mipi_dsi,
+ enum mipi_dsi_trans_mode mode);
+
+static int mipi_dsi_lcd_init(struct mipi_dsi_info *mipi_dsi,
+ struct mxc_dispdrv_setting *setting)
+{
+ int i, size, err;
+ struct fb_videomode *mipi_lcd_modedb;
+ struct fb_videomode mode;
+ struct device *dev = &mipi_dsi->pdev->dev;
+
+ for (i = 0; i < ARRAY_SIZE(mipi_dsi_lcd_db); i++) {
+ if (!strcmp(mipi_dsi->lcd_panel,
+ mipi_dsi_lcd_db[i].lcd_panel)) {
+ mipi_dsi->lcd_callback =
+ &mipi_dsi_lcd_db[i].lcd_callback;
+ break;
+ }
+ }
+ if (i == ARRAY_SIZE(mipi_dsi_lcd_db)) {
+ dev_err(dev, "failed to find supported lcd panel.\n");
+ return -EINVAL;
+ }
+
+ /* set default bpp to 32 if not set*/
+ if (!setting->default_bpp)
+ setting->default_bpp = 32;
+
+ mipi_dsi->lcd_callback->get_mipi_lcd_videomode(&mipi_lcd_modedb, &size,
+ &mipi_dsi->lcd_config);
+
+ err = fb_find_mode(&setting->fbi->var, setting->fbi,
+ setting->dft_mode_str,
+ mipi_lcd_modedb, size, NULL,
+ setting->default_bpp);
+ if (err != 1)
+ fb_videomode_to_var(&setting->fbi->var, mipi_lcd_modedb);
+
+ INIT_LIST_HEAD(&setting->fbi->modelist);
+ for (i = 0; i < size; i++) {
+ fb_var_to_videomode(&mode, &setting->fbi->var);
+ if (fb_mode_is_equal(&mode, mipi_lcd_modedb + i)) {
+ err = fb_add_videomode(mipi_lcd_modedb + i,
+ &setting->fbi->modelist);
+ mipi_dsi->mode = mipi_lcd_modedb + i;
+ break;
+ }
+ }
+
+ if ((err < 0) || (size == i)) {
+ dev_err(dev, "failed to add videomode.\n");
+ return err;
+ }
+
+ return 0;
+}
+
+static void mipi_dsi_wr_tx_header(struct mipi_dsi_info *mipi_dsi,
+ u8 di, u8 data0, u8 data1)
+{
+ unsigned int reg;
+
+ reg = (data1 << 16) | (data0 << 8) | ((di & 0x3f) << 0);
+
+ writel(reg, mipi_dsi->mmio_base + MIPI_DSI_PKTHDR);
+}
+
+static void mipi_dsi_wr_tx_data(struct mipi_dsi_info *mipi_dsi,
+ unsigned int tx_data)
+{
+ writel(tx_data, mipi_dsi->mmio_base + MIPI_DSI_PAYLOAD);
+}
+
+static void mipi_dsi_long_data_wr(struct mipi_dsi_info *mipi_dsi,
+ const unsigned char *data0, unsigned int data_size)
+{
+ unsigned int data_cnt = 0, payload = 0;
+
+ /* in case that data count is more then 4 */
+ for (data_cnt = 0; data_cnt < data_size; data_cnt += 4) {
+ /*
+ * after sending 4bytes per one time,
+ * send remainder data less then 4.
+ */
+ if ((data_size - data_cnt) < 4) {
+ if ((data_size - data_cnt) == 3) {
+ payload = data0[data_cnt] |
+ data0[data_cnt + 1] << 8 |
+ data0[data_cnt + 2] << 16;
+ dev_dbg(&mipi_dsi->pdev->dev, "count = 3 payload = %x, %x %x %x\n",
+ payload, data0[data_cnt],
+ data0[data_cnt + 1],
+ data0[data_cnt + 2]);
+ } else if ((data_size - data_cnt) == 2) {
+ payload = data0[data_cnt] |
+ data0[data_cnt + 1] << 8;
+ dev_dbg(&mipi_dsi->pdev->dev,
+ "count = 2 payload = %x, %x %x\n", payload,
+ data0[data_cnt],
+ data0[data_cnt + 1]);
+ } else if ((data_size - data_cnt) == 1) {
+ payload = data0[data_cnt];
+ }
+
+ mipi_dsi_wr_tx_data(mipi_dsi, payload);
+ /* send 4bytes per one time. */
+ } else {
+ payload = data0[data_cnt] |
+ data0[data_cnt + 1] << 8 |
+ data0[data_cnt + 2] << 16 |
+ data0[data_cnt + 3] << 24;
+
+ dev_dbg(&mipi_dsi->pdev->dev,
+ "count = 4 payload = %x, %x %x %x %x\n",
+ payload, *(u8 *)(data0 + data_cnt),
+ data0[data_cnt + 1],
+ data0[data_cnt + 2],
+ data0[data_cnt + 3]);
+
+ mipi_dsi_wr_tx_data(mipi_dsi, payload);
+ }
+ }
+}
+
+static int mipi_dsi_pkt_write(struct mipi_dsi_info *mipi_dsi,
+ u8 data_type, const u32 *buf, int len)
+{
+ int ret = 0;
+ struct platform_device *pdev = mipi_dsi->pdev;
+ const unsigned char *data = (const unsigned char*)buf;
+
+ if (len == 0)
+ /* handle generic short write command */
+ mipi_dsi_wr_tx_header(mipi_dsi, data_type, data[0], data[1]);
+ else {
+ reinit_completion(&dsi_tx_done);
+
+ /* handle generic long write command */
+ mipi_dsi_long_data_wr(mipi_dsi, data, len);
+ mipi_dsi_wr_tx_header(mipi_dsi, data_type, len & 0xff, (len & 0xff00) >> 8);
+
+ ret = wait_for_completion_timeout(&dsi_tx_done, MIPI_FIFO_TIMEOUT);
+ if (!ret) {
+ dev_err(&pdev->dev, "wait tx done timeout!\n");
+ return -ETIMEDOUT;
+ }
+ }
+ mdelay(10);
+
+ return 0;
+}
+
+static void mipi_dsi_rd_tx_header(struct mipi_dsi_info *mipi_dsi,
+ u8 data_type, u8 data0)
+{
+ unsigned int reg = (data_type << 0) | (data0 << 8);
+
+ writel(reg, mipi_dsi->mmio_base + MIPI_DSI_PKTHDR);
+}
+
+static unsigned int mipi_dsi_rd_rx_fifo(struct mipi_dsi_info *mipi_dsi)
+{
+ return readl(mipi_dsi->mmio_base + MIPI_DSI_RXFIFO);
+}
+
+static int mipi_dsi_pkt_read(struct mipi_dsi_info *mipi_dsi,
+ u8 data_type, u32 *buf, int len)
+{
+ int ret;
+ struct platform_device *pdev = mipi_dsi->pdev;
+
+ if (len <= 4) {
+ reinit_completion(&dsi_rx_done);
+
+ mipi_dsi_rd_tx_header(mipi_dsi, data_type, buf[0]);
+
+ ret = wait_for_completion_timeout(&dsi_rx_done, MIPI_FIFO_TIMEOUT);
+ if (!ret) {
+ dev_err(&pdev->dev, "wait rx done timeout!\n");
+ return -ETIMEDOUT;
+ }
+
+ buf[0] = mipi_dsi_rd_rx_fifo(mipi_dsi);
+ buf[0] = buf[0] >> 8;
+ }
+ else {
+ /* TODO: add support later */
+ }
+
+ return 0;
+}
+
+int mipi_dsi_dcs_cmd(struct mipi_dsi_info *mipi_dsi,
+ u8 cmd, const u32 *param, int num)
+{
+ int err = 0;
+ u32 buf[DSI_CMD_BUF_MAXSIZE];
+
+ switch (cmd) {
+ case MIPI_DCS_EXIT_SLEEP_MODE:
+ case MIPI_DCS_ENTER_SLEEP_MODE:
+ case MIPI_DCS_SET_DISPLAY_ON:
+ case MIPI_DCS_SET_DISPLAY_OFF:
+ buf[0] = cmd;
+ err = mipi_dsi_pkt_write(mipi_dsi,
+ MIPI_DSI_DCS_SHORT_WRITE, buf, 0);
+ break;
+
+ default:
+ dev_err(&mipi_dsi->pdev->dev,
+ "MIPI DSI DCS Command:0x%x Not supported!\n", cmd);
+ break;
+ }
+
+ return err;
+}
+
+static void mipi_dsi_set_main_standby(struct mipi_dsi_info *mipi_dsi,
+ unsigned int enable)
+{
+ unsigned int reg;
+
+ reg = readl(mipi_dsi->mmio_base + MIPI_DSI_MDRESOL);
+
+ reg &= ~MIPI_DSI_MAIN_STANDBY(1);
+
+ if (enable)
+ reg |= MIPI_DSI_MAIN_STANDBY(1);
+
+ writel(reg, mipi_dsi->mmio_base + MIPI_DSI_MDRESOL);
+}
+
+static void mipi_dsi_power_off(struct mxc_dispdrv_handle *disp)
+{
+ int err;
+ struct mipi_dsi_info *mipi_dsi = mxc_dispdrv_getdata(disp);
+
+ err = mipi_dsi_dcs_cmd(mipi_dsi, MIPI_DCS_ENTER_SLEEP_MODE,
+ NULL, 0);
+ if (err) {
+ dev_err(&mipi_dsi->pdev->dev,
+ "MIPI DSI DCS Command display on error!\n");
+ }
+ msleep(MIPI_LCD_SLEEP_MODE_DELAY);
+
+ mipi_dsi_set_main_standby(mipi_dsi, 0);
+
+ clk_disable_unprepare(mipi_dsi->dphy_clk);
+ clk_disable_unprepare(mipi_dsi->cfg_clk);
+}
+
+static void mipi_dsi_dphy_power_on(struct platform_device *pdev)
+{
+ int ret;
+
+ regulator_set_voltage(mipi_phy_reg, 1000000, 1000000);
+
+ ret = regulator_enable(mipi_phy_reg);
+ if (ret){
+ dev_err(&pdev->dev, "failed to enable mipi phy regulatore\n");
+ BUG_ON(1);
+ }
+}
+
+static void mipi_dsi_dphy_power_down(void)
+{
+ regulator_disable(mipi_phy_reg);
+}
+
+static int mipi_dsi_lane_stop_state(struct mipi_dsi_info *mipi_dsi)
+{
+ unsigned int reg;
+
+ reg = readl(mipi_dsi->mmio_base + MIPI_DSI_STATUS);
+
+ if (((reg & MIPI_DSI_STOP_STATE_DAT(0x3)) == 0x3) &&
+ ((reg & MIPI_DSI_STOP_STATE_CLK(0x1)) ||
+ (reg & MIPI_DSI_TX_READY_HS_CLK(0x1))))
+ return 1;
+
+ return 0;
+}
+
+static void mipi_dsi_init_interrupt(struct mipi_dsi_info *mipi_dsi)
+{
+ unsigned int intsrc, intmsk;
+
+ intsrc = (INTSRC_SFR_PL_FIFO_EMPTY | INTSRC_RX_DATA_DONE);
+ writel(intsrc, mipi_dsi->mmio_base + MIPI_DSI_INTSRC);
+
+ intmsk = ~(INTMSK_SFR_PL_FIFO_EMPTY | INTMSK_RX_DATA_DONE);
+ writel(intmsk, mipi_dsi->mmio_base + MIPI_DSI_INTMSK);
+}
+
+static int mipi_dsi_master_init(struct mipi_dsi_info *mipi_dsi,
+ bool init)
+{
+ unsigned int time_out = 100;
+ unsigned int reg, byte_clk, esc_div;
+ struct fb_videomode *mode = mipi_dsi->mode;
+ struct device *dev = &mipi_dsi->pdev->dev;
+
+ /* configure DPHY PLL clock */
+ writel(MIPI_DSI_TX_REQUEST_HSCLK(0) |
+ MIPI_DSI_DPHY_SEL(0) |
+ MIPI_DSI_PLL_BYPASS(0) |
+ MIPI_DSI_BYTE_CLK_SRC(0),
+ mipi_dsi->mmio_base + MIPI_DSI_CLKCTRL);
+ if (!strcmp(mipi_dsi->lcd_panel, "TRULY-WVGA-TFT3P5581E"))
+ writel(MIPI_DSI_PLL_EN(1) | MIPI_DSI_PMS(0x3141),
+ mipi_dsi->mmio_base + MIPI_DSI_PLLCTRL);
+ else
+ writel(MIPI_DSI_PLL_EN(1) | MIPI_DSI_PMS(0x4190),
+ mipi_dsi->mmio_base + MIPI_DSI_PLLCTRL);
+
+ /* set PLLTMR: stable time */
+ writel(33024, mipi_dsi->mmio_base + MIPI_DSI_PLLTMR);
+ udelay(300);
+
+ /* configure byte clock */
+ reg = readl(mipi_dsi->mmio_base + MIPI_DSI_CLKCTRL);
+ reg |= MIPI_DSI_BYTE_CLK_EN(1);
+ byte_clk = 1500000000 / 8;
+ esc_div = DIV_ROUND_UP(byte_clk, 20 * 1000000);
+ reg |= (esc_div & 0xffff);
+ /* enable escape clock for clock lane and data lane0 and lane1 */
+ reg |= MIPI_DSI_LANE_ESC_CLK_EN(0x7);
+ reg |= MIPI_DSI_ESC_CLK_EN(1);
+ writel(reg, mipi_dsi->mmio_base + MIPI_DSI_CLKCTRL);
+
+ /* set main display resolution */
+ writel(MIPI_DSI_MAIN_HRESOL(mode->xres) |
+ MIPI_DSI_MAIN_VRESOL(mode->yres) |
+ MIPI_DSI_MAIN_STANDBY(0),
+ mipi_dsi->mmio_base + MIPI_DSI_MDRESOL);
+
+ /* set config register */
+ writel(MIPI_DSI_MFLUSH_VS(1) |
+ MIPI_DSI_SYNC_IN_FORM(0) |
+ MIPI_DSI_BURST_MODE(1) |
+ MIPI_DSI_VIDEO_MODE(1) |
+ MIPI_DSI_AUTO_MODE(0) |
+ MIPI_DSI_HSE_DISABLE_MODE(0) |
+ MIPI_DSI_HFP_DISABLE_MODE(0) |
+ MIPI_DSI_HBP_DISABLE_MODE(0) |
+ MIPI_DSI_HSA_DISABLE_MODE(0) |
+ MIPI_DSI_MAIN_VC(0) |
+ MIPI_DSI_SUB_VC(1) |
+ MIPI_DSI_MAIN_PIX_FORMAT(0x7) |
+ MIPI_DSI_SUB_PIX_FORMAT(0x7) |
+ MIPI_DSI_NUM_OF_DATALANE(0x1) |
+ MIPI_DSI_LANE_EN(0x7), /* enable data lane 0 and 1 */
+ mipi_dsi->mmio_base + MIPI_DSI_CONFIG);
+
+ /* set main display vporch */
+ writel(MIPI_DSI_CMDALLOW(0xf) |
+ MIPI_DSI_STABLE_VFP(mode->lower_margin) |
+ MIPI_DSI_MAIN_VBP(mode->upper_margin),
+ mipi_dsi->mmio_base + MIPI_DSI_MVPORCH);
+ /* set main display hporch */
+ writel(MIPI_DSI_MAIN_HFP(mode->right_margin) |
+ MIPI_DSI_MAIN_HBP(mode->left_margin),
+ mipi_dsi->mmio_base + MIPI_DSI_MHPORCH);
+ /* set main display sync */
+ writel(MIPI_DSI_MAIN_VSA(mode->vsync_len) |
+ MIPI_DSI_MAIN_HSA(mode->hsync_len),
+ mipi_dsi->mmio_base + MIPI_DSI_MSYNC);
+
+ /* configure d-phy timings */
+ if (!strcmp(mipi_dsi->lcd_panel, "TRULY-WVGA-TFT3P5581E")) {
+ writel(MIPI_DSI_M_TLPXCTL(2) | MIPI_DSI_M_THSEXITCTL(4),
+ mipi_dsi->mmio_base + MIPI_DSI_PHYTIMING);
+ writel(MIPI_DSI_M_TCLKPRPRCTL(5) |
+ MIPI_DSI_M_TCLKZEROCTL(14) |
+ MIPI_DSI_M_TCLKPOSTCTL(8) |
+ MIPI_DSI_M_TCLKTRAILCTL(3),
+ mipi_dsi->mmio_base + MIPI_DSI_PHYTIMING1);
+ writel(MIPI_DSI_M_THSPRPRCTL(3) |
+ MIPI_DSI_M_THSZEROCTL(3) |
+ MIPI_DSI_M_THSTRAILCTL(3),
+ mipi_dsi->mmio_base + MIPI_DSI_PHYTIMING2);
+ } else {
+ writel(MIPI_DSI_M_TLPXCTL(11) | MIPI_DSI_M_THSEXITCTL(18),
+ mipi_dsi->mmio_base + MIPI_DSI_PHYTIMING);
+ writel(MIPI_DSI_M_TCLKPRPRCTL(13) |
+ MIPI_DSI_M_TCLKZEROCTL(65) |
+ MIPI_DSI_M_TCLKPOSTCTL(17) |
+ MIPI_DSI_M_TCLKTRAILCTL(13),
+ mipi_dsi->mmio_base + MIPI_DSI_PHYTIMING1);
+ writel(MIPI_DSI_M_THSPRPRCTL(16) |
+ MIPI_DSI_M_THSZEROCTL(24) |
+ MIPI_DSI_M_THSTRAILCTL(16),
+ mipi_dsi->mmio_base + MIPI_DSI_PHYTIMING2);
+ }
+
+ writel(0xf000f, mipi_dsi->mmio_base + MIPI_DSI_TIMEOUT);
+
+ /* Init FIFO */
+ writel(0x0, mipi_dsi->mmio_base + MIPI_DSI_FIFOCTRL);
+ udelay(300);
+ writel(0x1f, mipi_dsi->mmio_base + MIPI_DSI_FIFOCTRL);
+
+ /* check clock and data lanes are in stop state
+ * which means dphy is in low power mode
+ */
+ while (!mipi_dsi_lane_stop_state(mipi_dsi)) {
+ time_out--;
+ if (time_out == 0) {
+ dev_err(dev, "MIPI DSI is not stop state.\n");
+ return -EINVAL;
+ }
+ }
+
+ /* transfer commands always in lp mode */
+ writel(MIPI_DSI_CMD_LPDT, mipi_dsi->mmio_base + MIPI_DSI_ESCMODE);
+
+ mipi_dsi_init_interrupt(mipi_dsi);
+
+ return 0;
+}
+
+static int mipi_dsi_disp_init(struct mxc_dispdrv_handle *disp,
+ struct mxc_dispdrv_setting *setting)
+{
+ struct mipi_dsi_info *mipi_dsi = mxc_dispdrv_getdata(disp);
+ struct device *dev = &mipi_dsi->pdev->dev;
+ struct device_node *np = dev->of_node;
+ struct reset_control *reset = NULL;
+ int ret = 0;
+
+ reset = of_reset_control_get(np, NULL);
+ if (IS_ERR(reset))
+ return PTR_ERR(reset);
+
+ ret = mipi_dsi_lcd_init(mipi_dsi, setting);
+ if (ret) {
+ dev_err(dev, "failed to init mipi dsi lcd\n");
+ goto out;
+ }
+
+ dev_info(dev, "MIPI DSI dispdrv inited!\n");
+
+out:
+ reset_control_put(reset);
+ return ret;
+}
+
+static void mipi_dsi_disp_deinit(struct mxc_dispdrv_handle *disp)
+{
+ struct mipi_dsi_info *mipi_dsi;
+
+ mipi_dsi = mxc_dispdrv_getdata(disp);
+
+ mipi_dsi_power_off(mipi_dsi->disp_mipi);
+ if (mipi_dsi->bl)
+ backlight_device_unregister(mipi_dsi->bl);
+}
+
+static void mipi_dsi_set_mode(struct mipi_dsi_info *mipi_dsi,
+ enum mipi_dsi_trans_mode mode)
+{
+ unsigned int dsi_clkctrl;
+
+ dsi_clkctrl = readl(mipi_dsi->mmio_base + MIPI_DSI_CLKCTRL);
+
+ switch (mode) {
+ case DSI_LP_MODE:
+ dsi_clkctrl &= ~MIPI_DSI_TX_REQUEST_HSCLK(1);
+ break;
+ case DSI_HS_MODE:
+ dsi_clkctrl |= MIPI_DSI_TX_REQUEST_HSCLK(1);
+ break;
+ default:
+ dev_err(&mipi_dsi->pdev->dev,
+ "invalid dsi mode\n");
+ return;
+ }
+
+ writel(dsi_clkctrl, mipi_dsi->mmio_base + MIPI_DSI_CLKCTRL);
+ mdelay(1);
+}
+
+static int mipi_dsi_enable(struct mxc_dispdrv_handle *disp,
+ struct fb_info *fbi)
+{
+ int ret;
+ struct mipi_dsi_info *mipi_dsi = mxc_dispdrv_getdata(disp);
+
+ if (fbi->state == FBINFO_STATE_SUSPENDED) {
+ if (mipi_dsi->disp_power_on) {
+ ret = regulator_enable(mipi_dsi->disp_power_on);
+ if (ret) {
+ dev_err(&mipi_dsi->pdev->dev, "failed to enable display "
+ "power regulator, err = %d\n", ret);
+ return ret;
+ }
+ }
+ }
+
+ if (!mipi_dsi->dsi_power_on)
+ pm_runtime_get_sync(&mipi_dsi->pdev->dev);
+
+ ret = clk_prepare_enable(mipi_dsi->dphy_clk);
+ ret |= clk_prepare_enable(mipi_dsi->cfg_clk);
+ if (ret) {
+ dev_err(&mipi_dsi->pdev->dev,
+ "clk enable error:%d!\n", ret);
+ return -EINVAL;
+ }
+
+ if (!mipi_dsi->lcd_inited) {
+ ret = mipi_dsi_master_init(mipi_dsi, true);
+ if (ret)
+ return -EINVAL;
+
+ msleep(20);
+ ret = device_reset(&mipi_dsi->pdev->dev);
+ if (ret) {
+ dev_err(&mipi_dsi->pdev->dev, "failed to reset device: %d\n", ret);
+ return -EINVAL;
+ }
+ msleep(120);
+
+ /* the panel should be config under LP mode */
+ ret = mipi_dsi->lcd_callback->mipi_lcd_setup(mipi_dsi);
+ if (ret < 0) {
+ dev_err(&mipi_dsi->pdev->dev,
+ "failed to init mipi lcd.\n");
+ return ret ;
+ }
+ mipi_dsi->lcd_inited = 1;
+
+ /* change to HS mode for panel display */
+ mipi_dsi_set_mode(mipi_dsi, DSI_HS_MODE);
+ } else {
+ ret = mipi_dsi_dcs_cmd(mipi_dsi, MIPI_DCS_EXIT_SLEEP_MODE,
+ NULL, 0);
+ if (ret) {
+ dev_err(&mipi_dsi->pdev->dev,
+ "MIPI DSI DCS Command sleep-in error!\n");
+ }
+ msleep(MIPI_LCD_SLEEP_MODE_DELAY);
+ }
+
+ mipi_dsi_set_main_standby(mipi_dsi, 1);
+
+ return 0;
+}
+
+static void mipi_dsi_disable(struct mxc_dispdrv_handle *disp,
+ struct fb_info *fbi)
+{
+ struct mipi_dsi_info *mipi_dsi = mxc_dispdrv_getdata(disp);
+
+ mipi_dsi_power_off(mipi_dsi->disp_mipi);
+
+ if (fbi->state == FBINFO_STATE_SUSPENDED) {
+ if (mipi_dsi->dsi_power_on) {
+ pm_runtime_put_noidle(&mipi_dsi->pdev->dev);
+ pm_runtime_put_sync_suspend(&mipi_dsi->pdev->dev);
+ pm_runtime_get_noresume(&mipi_dsi->pdev->dev);
+ }
+
+ if (mipi_dsi->disp_power_on)
+ regulator_disable(mipi_dsi->disp_power_on);
+
+ mipi_dsi->lcd_inited = 0;
+ }
+}
+
+static int mipi_dsi_setup(struct mxc_dispdrv_handle *disp,
+ struct fb_info *fbi)
+{
+ struct mipi_dsi_info *mipi_dsi = mxc_dispdrv_getdata(disp);
+ int xres_virtual = fbi->var.xres_virtual;
+ int yres_virtual = fbi->var.yres_virtual;
+ int xoffset = fbi->var.xoffset;
+ int yoffset = fbi->var.yoffset;
+ int pixclock = fbi->var.pixclock;
+
+ if (!mipi_dsi->mode)
+ return 0;
+
+ /* set the mode back to var in case userspace changes it */
+ fb_videomode_to_var(&fbi->var, mipi_dsi->mode);
+
+ /* restore some var entries cached */
+ fbi->var.xres_virtual = xres_virtual;
+ fbi->var.yres_virtual = yres_virtual;
+ fbi->var.xoffset = xoffset;
+ fbi->var.yoffset = yoffset;
+ fbi->var.pixclock = pixclock;
+
+ return 0;
+}
+
+static struct mxc_dispdrv_driver mipi_dsi_drv = {
+ .name = DISPDRV_MIPI,
+ .init = mipi_dsi_disp_init,
+ .deinit = mipi_dsi_disp_deinit,
+ .enable = mipi_dsi_enable,
+ .disable = mipi_dsi_disable,
+ .setup = mipi_dsi_setup,
+};
+
+static const struct of_device_id imx_mipi_dsi_dt_ids[] = {
+ { .compatible = "fsl,imx7d-mipi-dsi", .data = NULL, },
+ { }
+};
+MODULE_DEVICE_TABLE(of, imx_mipi_dsi_dt_ids);
+
+static irqreturn_t mipi_dsi_irq_handler(int irq, void *data)
+{
+ unsigned int intsrc, intclr;
+ struct mipi_dsi_info *mipi_dsi = data;
+ struct platform_device *pdev = mipi_dsi->pdev;
+
+ intclr = 0;
+ intsrc = readl(mipi_dsi->mmio_base + MIPI_DSI_INTSRC);
+
+ dev_dbg(&pdev->dev, "intsrc = 0x%x\n", intsrc);
+
+ if (intsrc & INTSRC_SFR_PL_FIFO_EMPTY) {
+ dev_dbg(&pdev->dev, "playload tx finished\n");
+ intclr |= INTSRC_SFR_PL_FIFO_EMPTY;
+ complete(&dsi_tx_done);
+ }
+
+ if(intsrc & INTSRC_RX_DATA_DONE) {
+ dev_dbg(&pdev->dev, "rx data finished\n");
+ intclr |= INTSRC_RX_DATA_DONE;
+ complete(&dsi_rx_done);
+ }
+
+ /* clear the interrupts */
+ if (intclr)
+ writel(intclr, mipi_dsi->mmio_base + MIPI_DSI_INTSRC);
+
+ return IRQ_HANDLED;
+}
+
+/**
+ * This function is called by the driver framework to initialize the MIPI DSI
+ * device.
+ *
+ * @param pdev The device structure for the MIPI DSI passed in by the
+ * driver framework.
+ *
+ * @return Returns 0 on success or negative error code on error
+ */
+static int mipi_dsi_probe(struct platform_device *pdev)
+{
+ struct device_node *np = pdev->dev.of_node;
+ struct mipi_dsi_info *mipi_dsi;
+ struct resource *res;
+ const char *lcd_panel;
+ int ret = 0;
+
+ mipi_dsi = devm_kzalloc(&pdev->dev, sizeof(*mipi_dsi), GFP_KERNEL);
+ if (!mipi_dsi)
+ return -ENOMEM;
+ mipi_dsi->pdev = pdev;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ dev_err(&pdev->dev, "failed to get platform resource mem\n");
+ return -ENODEV;
+ }
+
+ if (!devm_request_mem_region(&pdev->dev, res->start,
+ resource_size(res), pdev->name))
+ return -EBUSY;
+
+ mipi_dsi->mmio_base = devm_ioremap(&pdev->dev, res->start,
+ resource_size(res));
+ if (!mipi_dsi->mmio_base)
+ return -ENOMEM;
+
+ mipi_dsi->irq = platform_get_irq(pdev, 0);
+ if (mipi_dsi->irq < 0) {
+ dev_err(&pdev->dev, "failed to get device irq\n");
+ return -EINVAL;
+ }
+
+ ret = devm_request_irq(&pdev->dev, mipi_dsi->irq,
+ mipi_dsi_irq_handler,
+ 0, "mipi_dsi_samsung", mipi_dsi);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to request mipi dsi irq\n");
+ return ret;
+ }
+
+ mipi_dsi->dphy_clk = devm_clk_get(&pdev->dev, "mipi_pllref_clk");
+ if (IS_ERR(mipi_dsi->dphy_clk)) {
+ dev_err(&pdev->dev, "failed to get dphy pll_ref_clk\n");
+ return PTR_ERR(mipi_dsi->dphy_clk);
+ }
+
+ mipi_dsi->cfg_clk = devm_clk_get(&pdev->dev, "mipi_cfg_clk");
+ if (IS_ERR(mipi_dsi->cfg_clk)) {
+ dev_err(&pdev->dev, "failed to get cfg_clk\n");
+ return PTR_ERR(mipi_dsi->cfg_clk);
+ }
+
+ ret = of_property_read_string(np, "lcd_panel", &lcd_panel);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to read lcd_panel property\n");
+ return ret;
+ }
+
+ mipi_phy_reg = devm_regulator_get(&pdev->dev, "mipi-phy");
+ if (IS_ERR(mipi_phy_reg)) {
+ dev_err(&pdev->dev, "mipi phy power supply not found\n");
+ return ret;
+ }
+
+ mipi_dsi->disp_power_on = devm_regulator_get(&pdev->dev,
+ "disp-power-on");
+ if (!IS_ERR(mipi_dsi->disp_power_on)) {
+ ret = regulator_enable(mipi_dsi->disp_power_on);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to enable display "
+ "power regulator, err = %d\n", ret);
+ return ret;
+ }
+ }
+
+ mipi_dsi->lcd_panel = kstrdup(lcd_panel, GFP_KERNEL);
+ if (!mipi_dsi->lcd_panel) {
+ dev_err(&pdev->dev, "failed to allocate lcd panel name\n");
+ ret = -ENOMEM;
+ goto kstrdup_fail;
+ }
+
+ mipi_dsi->disp_mipi = mxc_dispdrv_register(&mipi_dsi_drv);
+ if (IS_ERR(mipi_dsi->disp_mipi)) {
+ dev_err(&pdev->dev, "mxc_dispdrv_register error\n");
+ ret = PTR_ERR(mipi_dsi->disp_mipi);
+ goto dispdrv_reg_fail;
+ }
+
+ mipi_dsi->mipi_dsi_pkt_read = mipi_dsi_pkt_read;
+ mipi_dsi->mipi_dsi_pkt_write = mipi_dsi_pkt_write;
+ mipi_dsi->mipi_dsi_dcs_cmd = mipi_dsi_dcs_cmd;
+
+ pm_runtime_enable(&pdev->dev);
+
+ mxc_dispdrv_setdata(mipi_dsi->disp_mipi, mipi_dsi);
+ dev_set_drvdata(&pdev->dev, mipi_dsi);
+
+ dev_info(&pdev->dev, "i.MX MIPI DSI driver probed\n");
+ return ret;
+
+dispdrv_reg_fail:
+ kfree(mipi_dsi->lcd_panel);
+kstrdup_fail:
+ if (mipi_dsi->disp_power_on)
+ regulator_disable(mipi_dsi->disp_power_on);
+
+ return ret;
+}
+
+static void mipi_dsi_shutdown(struct platform_device *pdev)
+{
+ struct mipi_dsi_info *mipi_dsi = dev_get_drvdata(&pdev->dev);
+
+ mipi_dsi_power_off(mipi_dsi->disp_mipi);
+ mipi_dsi_dphy_power_down();
+}
+
+static int mipi_dsi_remove(struct platform_device *pdev)
+{
+ struct mipi_dsi_info *mipi_dsi = dev_get_drvdata(&pdev->dev);
+
+ mxc_dispdrv_puthandle(mipi_dsi->disp_mipi);
+ mxc_dispdrv_unregister(mipi_dsi->disp_mipi);
+
+ if (mipi_dsi->disp_power_on)
+ regulator_disable(mipi_dsi->disp_power_on);
+
+ kfree(mipi_dsi->lcd_panel);
+ dev_set_drvdata(&pdev->dev, NULL);
+
+ return 0;
+}
+
+static int mipi_dsi_runtime_suspend(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct mipi_dsi_info *mipi_dsi = dev_get_drvdata(&pdev->dev);
+
+ if (mipi_dsi->dsi_power_on) {
+ release_bus_freq(BUS_FREQ_HIGH);
+ dev_dbg(dev, "mipi dsi busfreq high release.\n");
+
+ mipi_dsi_dphy_power_down();
+ mipi_dsi->dsi_power_on = 0;
+ }
+
+ return 0;
+}
+
+static int mipi_dsi_runtime_resume(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct mipi_dsi_info *mipi_dsi = dev_get_drvdata(&pdev->dev);
+
+ if (!mipi_dsi->dsi_power_on) {
+ request_bus_freq(BUS_FREQ_HIGH);
+ dev_dbg(dev, "mipi dsi busfreq high request.\n");
+
+ mipi_dsi_dphy_power_on(pdev);
+ mipi_dsi->dsi_power_on = 1;
+ }
+
+ return 0;
+}
+
+static const struct dev_pm_ops mipi_dsi_pm_ops = {
+ .runtime_suspend = mipi_dsi_runtime_suspend,
+ .runtime_resume = mipi_dsi_runtime_resume,
+ .runtime_idle = NULL,
+};
+
+static struct platform_driver mipi_dsi_driver = {
+ .driver = {
+ .of_match_table = imx_mipi_dsi_dt_ids,
+ .name = "mxc_mipi_dsi_samsung",
+ .pm = &mipi_dsi_pm_ops,
+ },
+ .probe = mipi_dsi_probe,
+ .remove = mipi_dsi_remove,
+ .shutdown = mipi_dsi_shutdown,
+};
+
+static int __init mipi_dsi_init(void)
+{
+ int err;
+
+ err = platform_driver_register(&mipi_dsi_driver);
+ if (err) {
+ pr_err("mipi_dsi_driver register failed\n");
+ return err;
+ }
+
+ pr_debug("MIPI DSI driver module loaded: %s\n", mipi_dsi_driver.driver.name);
+
+ return 0;
+}
+
+static void __exit mipi_dsi_cleanup(void)
+{
+ platform_driver_unregister(&mipi_dsi_driver);
+}
+
+module_init(mipi_dsi_init);
+module_exit(mipi_dsi_cleanup);
+
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("i.MX MIPI DSI driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/video/fbdev/mxc/mxc_dcic.c b/drivers/video/fbdev/mxc/mxc_dcic.c
new file mode 100644
index 000000000000..3e6824a00fb6
--- /dev/null
+++ b/drivers/video/fbdev/mxc/mxc_dcic.c
@@ -0,0 +1,593 @@
+/*
+ * Copyright (C) 2014-2015 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+#include <linux/clk.h>
+#include <linux/cdev.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/fs.h>
+#include <linux/fb.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/ioctl.h>
+#include <linux/interrupt.h>
+#include <linux/mfd/syscon.h>
+#include <linux/mfd/syscon/imx6q-iomuxc-gpr.h>
+#include <linux/module.h>
+#include <linux/mxc_dcic.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/types.h>
+#include <linux/uaccess.h>
+#include <video/videomode.h>
+#include <video/of_videomode.h>
+
+#define DRIVER_NAME "mxc_dcic"
+
+#define DCIC_IPU1_DI0 "dcic-ipu1-di0"
+#define DCIC_IPU1_DI1 "dcic-ipu1-di1"
+#define DCIC_IPU2_DI0 "dcic-ipu2-di0"
+#define DCIC_IPU2_DI1 "dcic-ipu2-di1"
+#define DCIC_LCDIF "dcic-lcdif"
+#define DCIC_LCDIF1 "dcic-lcdif1"
+#define DCIC_LCDIF2 "dcic-lcdif2"
+#define DCIC_LVDS "dcic-lvds"
+#define DCIC_LVDS0 "dcic-lvds0"
+#define DCIC_LVDS1 "dcic-lvds1"
+#define DCIC_HDMI "dcic-hdmi"
+
+#define DCIC0_DEV_NAME "mxc_dcic0"
+#define DCIC1_DEV_NAME "mxc_dcic1"
+
+#define FB_SYNC_OE_LOW_ACT 0x80000000
+#define FB_SYNC_CLK_LAT_FALL 0x40000000
+
+static const struct dcic_mux imx6q_dcic0_mux[] = {
+ {
+ .dcic = DCIC_IPU1_DI0,
+ .val = IMX6Q_GPR10_DCIC1_MUX_CTL_IPU1_DI0,
+ }, {
+ .dcic = DCIC_LVDS0,
+ .val = IMX6Q_GPR10_DCIC1_MUX_CTL_LVDS0,
+ }, {
+ .dcic = DCIC_LVDS1,
+ .val = IMX6Q_GPR10_DCIC1_MUX_CTL_LVDS1,
+ }, {
+ .dcic = DCIC_HDMI,
+ .val = IMX6Q_GPR10_DCIC1_MUX_CTL_HDMI,
+ }
+};
+
+static const struct dcic_mux imx6q_dcic1_mux[] = {
+ {
+ .dcic = DCIC_IPU1_DI1,
+ .val = IMX6Q_GPR10_DCIC2_MUX_CTL_IPU1_DI1,
+ }, {
+ .dcic = DCIC_LVDS0,
+ .val = IMX6Q_GPR10_DCIC2_MUX_CTL_LVDS0,
+ }, {
+ .dcic = DCIC_LVDS1,
+ .val = IMX6Q_GPR10_DCIC2_MUX_CTL_LVDS1,
+ }, {
+ .dcic = DCIC_HDMI,
+ .val = IMX6Q_GPR10_DCIC2_MUX_CTL_MIPI,
+ }
+};
+
+static const struct bus_mux imx6q_dcic_buses[] = {
+ {
+ .name = DCIC0_DEV_NAME,
+ .reg = IOMUXC_GPR10,
+ .shift = 0,
+ .mask = IMX6Q_GPR10_DCIC1_MUX_CTL_MASK,
+ .dcic_mux_num = ARRAY_SIZE(imx6q_dcic0_mux),
+ .dcics = imx6q_dcic0_mux,
+ }, {
+ .name = DCIC1_DEV_NAME,
+ .reg = IOMUXC_GPR10,
+ .shift = 2,
+ .mask = IMX6Q_GPR10_DCIC2_MUX_CTL_MASK,
+ .dcic_mux_num = ARRAY_SIZE(imx6q_dcic1_mux),
+ .dcics = imx6q_dcic1_mux,
+ }
+};
+
+static const struct dcic_info imx6q_dcic_info = {
+ .bus_mux_num = ARRAY_SIZE(imx6q_dcic_buses),
+ .buses = imx6q_dcic_buses,
+};
+
+static const struct dcic_mux imx6sx_dcic0_mux[] = {
+ {
+ .dcic = DCIC_LCDIF1,
+ .val = IMX6SX_GPR5_DISP_MUX_DCIC1_LCDIF1,
+ }, {
+ .dcic = DCIC_LVDS,
+ .val = IMX6SX_GPR5_DISP_MUX_DCIC1_LVDS,
+ }
+};
+
+static const struct dcic_mux imx6sx_dcic1_mux[] = {
+ {
+ .dcic = DCIC_LCDIF2,
+ .val = IMX6SX_GPR5_DISP_MUX_DCIC2_LCDIF2,
+ }, {
+ .dcic = DCIC_LVDS,
+ .val = IMX6SX_GPR5_DISP_MUX_DCIC2_LVDS,
+ }
+};
+
+static const struct bus_mux imx6sx_dcic_buses[] = {
+ {
+ .name = DCIC0_DEV_NAME,
+ .reg = IOMUXC_GPR5,
+ .shift = 1,
+ .mask = IMX6SX_GPR5_DISP_MUX_DCIC1_MASK,
+ .dcic_mux_num = ARRAY_SIZE(imx6sx_dcic0_mux),
+ .dcics = imx6sx_dcic0_mux,
+ }, {
+ .name = DCIC1_DEV_NAME,
+ .reg = IOMUXC_GPR5,
+ .shift = 2,
+ .mask = IMX6SX_GPR5_DISP_MUX_DCIC2_MASK,
+ .dcic_mux_num = ARRAY_SIZE(imx6sx_dcic1_mux),
+ .dcics = imx6sx_dcic1_mux,
+ }
+};
+
+static const struct dcic_info imx6sx_dcic_info = {
+ .bus_mux_num = ARRAY_SIZE(imx6sx_dcic_buses),
+ .buses = imx6sx_dcic_buses,
+};
+
+static const struct of_device_id dcic_dt_ids[] = {
+ { .compatible = "fsl,imx6q-dcic", .data = &imx6q_dcic_info, },
+ { .compatible = "fsl,imx6sx-dcic", .data = &imx6sx_dcic_info, },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, dcic_dt_ids);
+
+static int of_get_dcic_val(struct device_node *np, struct dcic_data *dcic)
+{
+ const char *mux;
+ int ret;
+ u32 i, dcic_id;
+
+ ret = of_property_read_string(np, "dcic_mux", &mux);
+ if (ret < 0) {
+ dev_err(dcic->dev, "Can not get dcic_mux\n");
+ return ret;
+ }
+ ret = of_property_read_u32(np, "dcic_id", &dcic_id);
+ if (ret < 0) {
+ dev_err(dcic->dev, "Can not get dcic_id\n");
+ return ret;
+ }
+
+ dcic->bus_n = dcic_id;
+
+ for (i = 0; i < dcic->buses[dcic_id].dcic_mux_num; i++)
+ if (!strcmp(mux, dcic->buses[dcic_id].dcics[i].dcic)) {
+ dcic->mux_n = i;
+ return dcic->buses[dcic_id].dcics[i].val;
+ }
+
+ return -EINVAL;
+}
+
+static void dcic_enable(struct dcic_data *dcic)
+{
+ u32 val;
+
+ val = readl(&dcic->regs->dcicc);
+ val |= DCICC_IC_ENABLE;
+ writel(val, &dcic->regs->dcicc);
+}
+
+void dcic_disable(struct dcic_data *dcic)
+{
+ u32 val;
+
+ val = readl(&dcic->regs->dcicc);
+ val &= ~DCICC_IC_MASK;
+ val |= DCICC_IC_DISABLE;
+ writel(val, &dcic->regs->dcicc);
+}
+
+static void roi_enable(struct dcic_data *dcic, struct roi_params *roi_param)
+{
+ u32 val;
+ u32 roi_n = roi_param->roi_n;
+
+ val = readl(&dcic->regs->ROI[roi_n].dcicrc);
+ val |= DCICRC_ROI_ENABLE;
+ if (roi_param->freeze)
+ val |= DCICRC_ROI_FROZEN;
+ writel(val, &dcic->regs->ROI[roi_n].dcicrc);
+}
+
+static void roi_disable(struct dcic_data *dcic, u32 roi_n)
+{
+ u32 val;
+
+ val = readl(&dcic->regs->ROI[roi_n].dcicrc);
+ val &= ~DCICRC_ROI_ENABLE;
+ writel(val, &dcic->regs->ROI[roi_n].dcicrc);
+}
+
+static bool roi_configure(struct dcic_data *dcic, struct roi_params *roi_param)
+{
+ struct roi_regs *roi_reg;
+ u32 val;
+
+ if (roi_param->roi_n >= 16) {
+ printk(KERN_ERR "Error, Wrong ROI number %d\n", roi_param->roi_n);
+ return false;
+ }
+
+ if (roi_param->end_x <= roi_param->start_x ||
+ roi_param->end_y <= roi_param->start_y) {
+ printk(KERN_ERR "Error, Wrong ROI\n");
+ return false;
+ }
+
+ roi_reg = (struct roi_regs *) &dcic->regs->ROI[roi_param->roi_n];
+
+ /* init roi block size */
+ val = roi_param->start_y << 16 | roi_param->start_x;
+ writel(val, &roi_reg->dcicrc);
+
+ val = roi_param->end_y << 16 | roi_param->end_x;
+ writel(val, &roi_reg->dcicrs);
+
+ writel(roi_param->ref_sig, &roi_reg->dcicrrs);
+
+ roi_enable(dcic, roi_param);
+ return true;
+}
+
+static void dcic_int_enable(struct dcic_data *dcic)
+{
+ u32 val;
+
+ /* Clean pending interrupt before enable int */
+ writel(DCICS_FI_STAT_PENDING, &dcic->regs->dcics);
+ writel(0xffffffff, &dcic->regs->dcics);
+
+ /* Enable function interrupt */
+ val = readl(&dcic->regs->dcicic);
+ val &= ~DCICIC_FUN_INT_MASK;
+ val |= DCICIC_FUN_INT_ENABLE;
+ writel(val, &dcic->regs->dcicic);
+}
+
+static void dcic_int_disable(struct dcic_data *dcic)
+{
+ u32 val;
+
+ /* Disable both function and error interrupt */
+ val = readl(&dcic->regs->dcicic);
+ val = DCICIC_ERROR_INT_DISABLE | DCICIC_FUN_INT_DISABLE;
+ writel(val, &dcic->regs->dcicic);
+}
+
+static irqreturn_t dcic_irq_handler(int irq, void *data)
+{
+ u32 i;
+
+ struct dcic_data *dcic = data;
+ u32 dcics = readl(&dcic->regs->dcics);
+
+ dcic->result = dcics & 0xffff;
+
+ dcic_int_disable(dcic);
+
+ /* clean dcic interrupt state */
+ writel(DCICS_FI_STAT_PENDING, &dcic->regs->dcics);
+ writel(dcics, &dcic->regs->dcics);
+
+ for (i = 0; i < 16; i++) {
+ printk(KERN_INFO "ROI=%d,crcRS=0x%x, crcCS=0x%x\n", i,
+ readl(&dcic->regs->ROI[i].dcicrrs),
+ readl(&dcic->regs->ROI[i].dcicrcs));
+ }
+ complete(&dcic->roi_crc_comp);
+
+ return 0;
+}
+
+static int dcic_configure(struct dcic_data *dcic, unsigned int sync)
+{
+ u32 val;
+ val = 0;
+
+ /* vsync, hsync, DE, clk_pol */
+ if (!(sync & FB_SYNC_HOR_HIGH_ACT))
+ val |= DCICC_HSYNC_POL_ACTIVE_LOW;
+ if (!(sync & FB_SYNC_VERT_HIGH_ACT))
+ val |= DCICC_VSYNC_POL_ACTIVE_LOW;
+ if (sync & FB_SYNC_OE_LOW_ACT)
+ val |= DCICC_DE_ACTIVE_LOW;
+ if (sync & FB_SYNC_CLK_LAT_FALL)
+ val |= DCICC_CLK_POL_INVERTED;
+
+ writel(val, &dcic->regs->dcicc);
+ return 0;
+}
+
+static int dcic_open(struct inode *inode, struct file *file)
+{
+ struct dcic_data *dcic;
+
+ dcic = container_of(inode->i_cdev, struct dcic_data, cdev);
+
+ mutex_lock(&dcic->lock);
+
+ clk_prepare_enable(dcic->disp_axi_clk);
+ clk_prepare_enable(dcic->dcic_clk);
+
+ file->private_data = dcic;
+ mutex_unlock(&dcic->lock);
+ return 0;
+}
+
+static int dcic_release(struct inode *inode, struct file *file)
+{
+ struct dcic_data *dcic = file->private_data;
+ u32 i;
+
+ mutex_lock(&dcic->lock);
+
+ for (i = 0; i < 16; i++)
+ roi_disable(dcic, i);
+
+ clk_disable_unprepare(dcic->dcic_clk);
+ clk_disable_unprepare(dcic->disp_axi_clk);
+
+ mutex_unlock(&dcic->lock);
+ return 0;
+}
+
+static int dcic_init(struct device_node *np, struct dcic_data *dcic)
+{
+ int val;
+ u32 bus;
+
+ val = of_get_dcic_val(np, dcic);
+ if (val < 0) {
+ printk(KERN_ERR "Error incorrect\n");
+ return -1;
+ }
+
+ bus = dcic->bus_n;
+
+ regmap_update_bits(dcic->regmap, dcic->buses[bus].reg ,
+ dcic->buses[bus].mask, val);
+
+ return 0;
+}
+
+static long dcic_ioctl(struct file *file,
+ unsigned int cmd, unsigned long arg)
+{
+ int __user *argp = (void __user *)arg;
+ struct dcic_data *dcic = file->private_data;
+ struct roi_params roi_param;
+ unsigned int sync;
+ int ret = 0;
+
+ switch (cmd) {
+ case DCIC_IOC_CONFIG_DCIC:
+ if (!copy_from_user(&sync, argp, sizeof(unsigned int)))
+ dcic_configure(dcic, sync);
+ break;
+ case DCIC_IOC_CONFIG_ROI:
+ if (copy_from_user(&roi_param, argp, sizeof(roi_param)))
+ return -EFAULT;
+ else
+ if (!roi_configure(dcic, &roi_param))
+ return -EINVAL;
+ break;
+ case DCIC_IOC_GET_RESULT:
+ init_completion(&dcic->roi_crc_comp);
+
+ dcic_enable(dcic);
+
+ dcic->result = 0;
+ msleep(25);
+
+ dcic_int_enable(dcic);
+
+ ret = wait_for_completion_interruptible_timeout(
+ &dcic->roi_crc_comp, 1 * HZ);
+ if (ret == 0) {
+ dev_err(dcic->dev,
+ "dcic wait for roi crc cal timeout\n");
+ ret = -ETIME;
+ } else if (ret > 0) {
+ if (copy_to_user(argp, &dcic->result, sizeof(dcic->result)))
+ return -EFAULT;
+ ret = 0;
+ }
+ dcic_disable(dcic);
+ break;
+ default:
+ printk(KERN_ERR "%s, Unsupport cmd %d\n", __func__, cmd);
+ break;
+ }
+ return ret;
+}
+
+
+static const struct file_operations mxc_dcic_fops = {
+ .owner = THIS_MODULE,
+ .open = dcic_open,
+ .release = dcic_release,
+ .unlocked_ioctl = dcic_ioctl,
+};
+
+static int dcic_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ const struct of_device_id *of_id =
+ of_match_device(dcic_dt_ids, dev);
+ const struct dcic_info *dcic_info =
+ (const struct dcic_info *)of_id->data;
+ struct device_node *np = dev->of_node;
+ struct dcic_data *dcic;
+ struct resource *res;
+ const char *name;
+ dev_t devt;
+ int ret = 0;
+ int irq;
+
+ dcic = devm_kzalloc(&pdev->dev,
+ sizeof(struct dcic_data),
+ GFP_KERNEL);
+ if (!dcic) {
+ dev_err(&pdev->dev, "Cannot allocate device data\n");
+ ret = -ENOMEM;
+ goto ealloc;
+ }
+
+ platform_set_drvdata(pdev, dcic);
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ dev_err(&pdev->dev, "No dcic base address found.\n");
+ ret = -ENODEV;
+ goto ealloc;
+ }
+
+ dcic->regs = (struct dcic_regs *) devm_ioremap(&pdev->dev, res->start, resource_size(res));
+ if (!dcic->regs) {
+ dev_err(&pdev->dev, "ioremap failed with dcic base\n");
+ ret = -ENOMEM;
+ goto ealloc;
+ }
+
+ dcic->dev = dev;
+ dcic->buses = dcic_info->buses;
+
+ dcic->regmap = syscon_regmap_lookup_by_phandle(np, "gpr");
+ if (IS_ERR(dcic->regmap)) {
+ dev_err(dev, "failed to get parent regmap\n");
+ ret = PTR_ERR(dcic->regmap);
+ goto ealloc;
+ }
+
+ /* clock */
+ dcic->disp_axi_clk = devm_clk_get(&pdev->dev, "disp-axi");
+ if (IS_ERR(dcic->disp_axi_clk)) {
+ dev_err(&pdev->dev, "get disp-axi clock failed\n");
+ ret = PTR_ERR(dcic->disp_axi_clk);
+ goto ealloc;
+ }
+
+ dcic->dcic_clk = devm_clk_get(&pdev->dev, "dcic");
+ if (IS_ERR(dcic->dcic_clk)) {
+ dev_err(&pdev->dev, "get dcic clk failed\n");
+ ret = PTR_ERR(dcic->dcic_clk);
+ goto ealloc;
+ }
+
+ mutex_init(&dcic->lock);
+ ret = dcic_init(np, dcic);
+ if (ret < 0) {
+ printk(KERN_ERR "Failed init dcic\n");
+ goto ealloc;
+ }
+
+ /* register device */
+ name = dcic->buses[dcic->bus_n].name;
+ dcic->major = register_chrdev(0, name, &mxc_dcic_fops);
+ if (dcic->major < 0) {
+ printk(KERN_ERR "DCIC: unable to get a major for dcic\n");
+ ret = -EBUSY;
+ goto ealloc;
+ }
+
+ dcic->class = class_create(THIS_MODULE, name);
+ if (IS_ERR(dcic->class)) {
+ ret = PTR_ERR(dcic->class);
+ goto err_out_chrdev;
+ }
+
+ /* create char device */
+ devt = MKDEV(dcic->major, 0);
+ dcic->devt = devt;
+
+ cdev_init(&dcic->cdev, &mxc_dcic_fops);
+ dcic->cdev.owner = THIS_MODULE;
+ ret = cdev_add(&dcic->cdev, devt, 1);
+ if (ret)
+ goto err_out_class;
+
+ device_create(dcic->class, NULL, devt,
+ NULL, name);
+
+ /* IRQ */
+ irq = platform_get_irq(pdev, 0);
+
+ ret = devm_request_irq(&pdev->dev, irq, dcic_irq_handler, 0,
+ dev_name(&pdev->dev), dcic);
+ if (ret) {
+ dev_err(&pdev->dev, "request_irq (%d) failed with error %d\n",
+ irq, ret);
+ goto err_out_cdev;
+ }
+
+ return 0;
+
+err_out_cdev:
+ cdev_del(&dcic->cdev);
+err_out_class:
+ device_destroy(dcic->class, devt);
+ class_destroy(dcic->class);
+err_out_chrdev:
+ unregister_chrdev(dcic->major, name);
+ealloc:
+ return ret;
+}
+
+static int dcic_remove(struct platform_device *pdev)
+{
+ struct dcic_data *dcic = platform_get_drvdata(pdev);
+ const char *name;
+
+ name = dcic->buses[dcic->bus_n].name;
+
+ device_destroy(dcic->class, dcic->devt);
+ cdev_del(&dcic->cdev);
+ class_destroy(dcic->class);
+ unregister_chrdev(dcic->major, name);
+ mutex_destroy(&dcic->lock);
+
+ return 0;
+}
+
+static struct platform_driver dcic_driver = {
+ .driver = {
+ .name = DRIVER_NAME,
+ .of_match_table = dcic_dt_ids,
+ },
+ .probe = dcic_probe,
+ .remove = dcic_remove,
+};
+
+module_platform_driver(dcic_driver);
+
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("MXC DCIC driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:" DRIVER_NAME);
diff --git a/drivers/video/fbdev/mxc/mxc_dispdrv.c b/drivers/video/fbdev/mxc/mxc_dispdrv.c
new file mode 100644
index 000000000000..77c0d50babea
--- /dev/null
+++ b/drivers/video/fbdev/mxc/mxc_dispdrv.c
@@ -0,0 +1,148 @@
+/*
+ * Copyright (C) 2011-2015 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/*!
+ * @file mxc_dispdrv.c
+ * @brief mxc display driver framework.
+ *
+ * A display device driver could call mxc_dispdrv_register(drv) in its dev_probe() function.
+ * Move all dev_probe() things into mxc_dispdrv_driver->init(), init() function should init
+ * and feedback setting;
+ * Move all dev_remove() things into mxc_dispdrv_driver->deinit();
+ * Move all dev_suspend() things into fb_notifier for SUSPEND, if there is;
+ * Move all dev_resume() things into fb_notifier for RESUME, if there is;
+ *
+ * mxc fb driver could call mxc_dispdrv_gethandle(name, setting) before a fb
+ * need be added, with fbi param passing by setting, after
+ * mxc_dispdrv_gethandle() return, FB driver should get the basic setting
+ * about fbi info and crtc.
+ *
+ * @ingroup Framebuffer
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/list.h>
+#include <linux/mutex.h>
+#include <linux/slab.h>
+#include <linux/err.h>
+#include <linux/string.h>
+#include "mxc_dispdrv.h"
+
+static LIST_HEAD(dispdrv_list);
+static DEFINE_MUTEX(dispdrv_lock);
+
+struct mxc_dispdrv_entry {
+ /* Note: drv always the first element */
+ struct mxc_dispdrv_driver *drv;
+ bool active;
+ void *priv;
+ struct list_head list;
+};
+
+struct mxc_dispdrv_handle *mxc_dispdrv_register(struct mxc_dispdrv_driver *drv)
+{
+ struct mxc_dispdrv_entry *new;
+
+ mutex_lock(&dispdrv_lock);
+
+ new = kzalloc(sizeof(struct mxc_dispdrv_entry), GFP_KERNEL);
+ if (!new) {
+ mutex_unlock(&dispdrv_lock);
+ return ERR_PTR(-ENOMEM);
+ }
+
+ new->drv = drv;
+ list_add_tail(&new->list, &dispdrv_list);
+
+ mutex_unlock(&dispdrv_lock);
+
+ return (struct mxc_dispdrv_handle *)new;
+}
+EXPORT_SYMBOL_GPL(mxc_dispdrv_register);
+
+int mxc_dispdrv_unregister(struct mxc_dispdrv_handle *handle)
+{
+ struct mxc_dispdrv_entry *entry = (struct mxc_dispdrv_entry *)handle;
+
+ if (entry) {
+ mutex_lock(&dispdrv_lock);
+ list_del(&entry->list);
+ mutex_unlock(&dispdrv_lock);
+ kfree(entry);
+ return 0;
+ } else
+ return -EINVAL;
+}
+EXPORT_SYMBOL_GPL(mxc_dispdrv_unregister);
+
+struct mxc_dispdrv_handle *mxc_dispdrv_gethandle(char *name,
+ struct mxc_dispdrv_setting *setting)
+{
+ int ret = -ENODEV, found = 0;
+ struct mxc_dispdrv_entry *entry;
+
+ mutex_lock(&dispdrv_lock);
+ list_for_each_entry(entry, &dispdrv_list, list) {
+ if (!strcmp(entry->drv->name, name) && (entry->drv->init)) {
+ ret = entry->drv->init((struct mxc_dispdrv_handle *)
+ entry, setting);
+ if (ret >= 0) {
+ entry->active = true;
+ found = 1;
+ break;
+ }
+ }
+ }
+ mutex_unlock(&dispdrv_lock);
+
+ return found ? (struct mxc_dispdrv_handle *)entry:ERR_PTR(ret);
+}
+EXPORT_SYMBOL_GPL(mxc_dispdrv_gethandle);
+
+void mxc_dispdrv_puthandle(struct mxc_dispdrv_handle *handle)
+{
+ struct mxc_dispdrv_entry *entry = (struct mxc_dispdrv_entry *)handle;
+
+ mutex_lock(&dispdrv_lock);
+ if (entry && entry->active && entry->drv->deinit) {
+ entry->drv->deinit(handle);
+ entry->active = false;
+ }
+ mutex_unlock(&dispdrv_lock);
+
+}
+EXPORT_SYMBOL_GPL(mxc_dispdrv_puthandle);
+
+int mxc_dispdrv_setdata(struct mxc_dispdrv_handle *handle, void *data)
+{
+ struct mxc_dispdrv_entry *entry = (struct mxc_dispdrv_entry *)handle;
+
+ if (entry) {
+ entry->priv = data;
+ return 0;
+ } else
+ return -EINVAL;
+}
+EXPORT_SYMBOL_GPL(mxc_dispdrv_setdata);
+
+void *mxc_dispdrv_getdata(struct mxc_dispdrv_handle *handle)
+{
+ struct mxc_dispdrv_entry *entry = (struct mxc_dispdrv_entry *)handle;
+
+ if (entry) {
+ return entry->priv;
+ } else
+ return ERR_PTR(-EINVAL);
+}
+EXPORT_SYMBOL_GPL(mxc_dispdrv_getdata);
diff --git a/drivers/video/fbdev/mxc/mxc_dispdrv.h b/drivers/video/fbdev/mxc/mxc_dispdrv.h
new file mode 100644
index 000000000000..58d8a07d3380
--- /dev/null
+++ b/drivers/video/fbdev/mxc/mxc_dispdrv.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2011-2014 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+#ifndef __MXC_DISPDRV_H__
+#define __MXC_DISPDRV_H__
+#include <linux/fb.h>
+#include "crtc.h"
+
+struct mxc_dispdrv_handle {
+ struct mxc_dispdrv_driver *drv;
+};
+
+struct mxc_dispdrv_setting {
+ /*input-feedback parameter*/
+ struct fb_info *fbi;
+ int if_fmt;
+ int default_bpp;
+ char *dft_mode_str;
+
+ /* feedback parameter */
+ enum crtc crtc;
+};
+
+struct mxc_dispdrv_driver {
+ const char *name;
+ int (*init) (struct mxc_dispdrv_handle *, struct mxc_dispdrv_setting *);
+ void (*deinit) (struct mxc_dispdrv_handle *);
+ /* display driver enable function for extension */
+ int (*enable) (struct mxc_dispdrv_handle *, struct fb_info *);
+ /* display driver disable function, called at early part of fb_blank */
+ void (*disable) (struct mxc_dispdrv_handle *, struct fb_info *);
+ /* display driver setup function, called at early part of fb_set_par */
+ int (*setup) (struct mxc_dispdrv_handle *, struct fb_info *fbi);
+};
+
+struct mxc_dispdrv_handle *mxc_dispdrv_register(struct mxc_dispdrv_driver *drv);
+int mxc_dispdrv_unregister(struct mxc_dispdrv_handle *handle);
+struct mxc_dispdrv_handle *mxc_dispdrv_gethandle(char *name,
+ struct mxc_dispdrv_setting *setting);
+void mxc_dispdrv_puthandle(struct mxc_dispdrv_handle *handle);
+int mxc_dispdrv_setdata(struct mxc_dispdrv_handle *handle, void *data);
+void *mxc_dispdrv_getdata(struct mxc_dispdrv_handle *handle);
+#endif
diff --git a/drivers/video/fbdev/mxc/mxc_edid.c b/drivers/video/fbdev/mxc/mxc_edid.c
new file mode 100644
index 000000000000..02563d8781cc
--- /dev/null
+++ b/drivers/video/fbdev/mxc/mxc_edid.c
@@ -0,0 +1,771 @@
+/*
+ * Copyright 2009-2015 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/*!
+ * @defgroup Framebuffer Framebuffer Driver for SDC and ADC.
+ */
+
+/*!
+ * @file mxc_edid.c
+ *
+ * @brief MXC EDID driver
+ *
+ * @ingroup Framebuffer
+ */
+
+/*!
+ * Include files
+ */
+#include <linux/i2c.h>
+#include <linux/fb.h>
+#include <video/mxc_edid.h>
+#include "../edid.h"
+
+#undef DEBUG /* define this for verbose EDID parsing output */
+#ifdef DEBUG
+#define DPRINTK(fmt, args...) printk(fmt, ## args)
+#else
+#define DPRINTK(fmt, args...)
+#endif
+
+const struct fb_videomode mxc_cea_mode[64] = {
+ /* #1: 640x480p@59.94/60Hz 4:3 */
+ [1] = {
+ NULL, 60, 640, 480, 39683, 48, 16, 33, 10, 96, 2, 0,
+ FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_4_3, 0,
+ },
+ /* #2: 720x480p@59.94/60Hz 4:3 */
+ [2] = {
+ NULL, 60, 720, 480, 37037, 60, 16, 30, 9, 62, 6, 0,
+ FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_4_3, 0,
+ },
+ /* #3: 720x480p@59.94/60Hz 16:9 */
+ [3] = {
+ NULL, 60, 720, 480, 37037, 60, 16, 30, 9, 62, 6, 0,
+ FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_16_9, 0,
+ },
+ /* #4: 1280x720p@59.94/60Hz 16:9 */
+ [4] = {
+ NULL, 60, 1280, 720, 13468, 220, 110, 20, 5, 40, 5,
+ FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+ FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_16_9, 0
+ },
+ /* #5: 1920x1080i@59.94/60Hz 16:9 */
+ [5] = {
+ NULL, 60, 1920, 1080, 13763, 148, 88, 15, 2, 44, 5,
+ FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+ FB_VMODE_INTERLACED | FB_VMODE_ASPECT_16_9, 0,
+ },
+ /* #6: 720(1440)x480iH@59.94/60Hz 4:3 */
+ [6] = {
+ NULL, 60, 1440, 480, 18554/*37108*/, 114, 38, 15, 4, 124, 3, 0,
+ FB_VMODE_INTERLACED | FB_VMODE_ASPECT_4_3, 0,
+ },
+ /* #7: 720(1440)x480iH@59.94/60Hz 16:9 */
+ [7] = {
+ NULL, 60, 1440, 480, 18554/*37108*/, 114, 38, 15, 4, 124, 3, 0,
+ FB_VMODE_INTERLACED | FB_VMODE_ASPECT_16_9, 0,
+ },
+ /* #8: 720(1440)x240pH@59.94/60Hz 4:3 */
+ [8] = {
+ NULL, 60, 1440, 240, 37108, 114, 38, 15, 4, 124, 3, 0,
+ FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_4_3, 0,
+ },
+ /* #9: 720(1440)x240pH@59.94/60Hz 16:9 */
+ [9] = {
+ NULL, 60, 1440, 240, 37108, 114, 38, 15, 4, 124, 3, 0,
+ FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_16_9, 0,
+ },
+ /* #14: 1440x480p@59.94/60Hz 4:3 */
+ [14] = {
+ NULL, 60, 1440, 480, 18500, 120, 32, 30, 9, 124, 6, 0,
+ FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_4_3, 0,
+ },
+ /* #15: 1440x480p@59.94/60Hz 16:9 */
+ [15] = {
+ NULL, 60, 1440, 480, 18500, 120, 32, 30, 9, 124, 6, 0,
+ FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_16_9, 0,
+ },
+ /* #16: 1920x1080p@60Hz 16:9 */
+ [16] = {
+ NULL, 60, 1920, 1080, 6734, 148, 88, 36, 4, 44, 5,
+ FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+ FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_16_9, 0,
+ },
+ /* #17: 720x576pH@50Hz 4:3 */
+ [17] = {
+ NULL, 50, 720, 576, 37037, 68, 12, 39, 5, 64, 5, 0,
+ FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_4_3, 0,
+ },
+ /* #18: 720x576pH@50Hz 16:9 */
+ [18] = {
+ NULL, 50, 720, 576, 37037, 68, 12, 39, 5, 64, 5, 0,
+ FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_16_9, 0,
+ },
+ /* #19: 1280x720p@50Hz */
+ [19] = {
+ NULL, 50, 1280, 720, 13468, 220, 440, 20, 5, 40, 5,
+ FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+ FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_16_9, 0,
+ },
+ /* #20: 1920x1080i@50Hz */
+ [20] = {
+ NULL, 50, 1920, 1080, 13480, 148, 528, 15, 5, 528, 5,
+ FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+ FB_VMODE_INTERLACED | FB_VMODE_ASPECT_16_9, 0,
+ },
+ /* #23: 720(1440)x288pH@50Hz 4:3 */
+ [23] = {
+ NULL, 50, 1440, 288, 37037, 138, 24, 19, 2, 126, 3, 0,
+ FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_4_3, 0,
+ },
+ /* #24: 720(1440)x288pH@50Hz 16:9 */
+ [24] = {
+ NULL, 50, 1440, 288, 37037, 138, 24, 19, 2, 126, 3, 0,
+ FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_16_9, 0,
+ },
+ /* #29: 720(1440)x576pH@50Hz 4:3 */
+ [29] = {
+ NULL, 50, 1440, 576, 18518, 136, 24, 39, 5, 128, 5, 0,
+ FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_4_3, 0,
+ },
+ /* #30: 720(1440)x576pH@50Hz 16:9 */
+ [30] = {
+ NULL, 50, 1440, 576, 18518, 136, 24, 39, 5, 128, 5, 0,
+ FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_16_9, 0,
+ },
+ /* #31: 1920x1080p@50Hz */
+ [31] = {
+ NULL, 50, 1920, 1080, 6734, 148, 528, 36, 4, 44, 5,
+ FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+ FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_16_9, 0,
+ },
+ /* #32: 1920x1080p@23.98/24Hz */
+ [32] = {
+ NULL, 24, 1920, 1080, 13468, 148, 638, 36, 4, 44, 5,
+ FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+ FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_16_9, 0,
+ },
+ /* #33: 1920x1080p@25Hz */
+ [33] = {
+ NULL, 25, 1920, 1080, 13468, 148, 528, 36, 4, 44, 5,
+ FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+ FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_16_9, 0,
+ },
+ /* #34: 1920x1080p@30Hz */
+ [34] = {
+ NULL, 30, 1920, 1080, 13468, 148, 88, 36, 4, 44, 5,
+ FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+ FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_16_9, 0,
+ },
+ /* #41: 1280x720p@100Hz 16:9 */
+ [41] = {
+ NULL, 100, 1280, 720, 6734, 220, 440, 20, 5, 40, 5,
+ FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+ FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_16_9, 0
+ },
+ /* #47: 1280x720p@119.88/120Hz 16:9 */
+ [47] = {
+ NULL, 120, 1280, 720, 6734, 220, 110, 20, 5, 40, 5,
+ FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+ FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_16_9, 0
+ },
+};
+
+/*
+ * We have a special version of fb_mode_is_equal that ignores
+ * pixclock, since for many CEA modes, 2 frequencies are supported
+ * e.g. 640x480 @ 60Hz or 59.94Hz
+ */
+int mxc_edid_fb_mode_is_equal(bool use_aspect,
+ const struct fb_videomode *mode1,
+ const struct fb_videomode *mode2)
+{
+ u32 mask;
+
+ if (use_aspect)
+ mask = ~0;
+ else
+ mask = ~FB_VMODE_ASPECT_MASK;
+
+ return (mode1->xres == mode2->xres &&
+ mode1->yres == mode2->yres &&
+ mode1->hsync_len == mode2->hsync_len &&
+ mode1->vsync_len == mode2->vsync_len &&
+ mode1->left_margin == mode2->left_margin &&
+ mode1->right_margin == mode2->right_margin &&
+ mode1->upper_margin == mode2->upper_margin &&
+ mode1->lower_margin == mode2->lower_margin &&
+ mode1->sync == mode2->sync &&
+ /* refresh check, 59.94Hz and 60Hz have the same parameter
+ * in struct of mxc_cea_mode */
+ abs(mode1->refresh - mode2->refresh) <= 1 &&
+ (mode1->vmode & mask) == (mode2->vmode & mask));
+}
+
+static void get_detailed_timing(unsigned char *block,
+ struct fb_videomode *mode)
+{
+ mode->xres = H_ACTIVE;
+ mode->yres = V_ACTIVE;
+ mode->pixclock = PIXEL_CLOCK;
+ mode->pixclock /= 1000;
+ mode->pixclock = KHZ2PICOS(mode->pixclock);
+ mode->right_margin = H_SYNC_OFFSET;
+ mode->left_margin = (H_ACTIVE + H_BLANKING) -
+ (H_ACTIVE + H_SYNC_OFFSET + H_SYNC_WIDTH);
+ mode->upper_margin = V_BLANKING - V_SYNC_OFFSET -
+ V_SYNC_WIDTH;
+ mode->lower_margin = V_SYNC_OFFSET;
+ mode->hsync_len = H_SYNC_WIDTH;
+ mode->vsync_len = V_SYNC_WIDTH;
+ if (HSYNC_POSITIVE)
+ mode->sync |= FB_SYNC_HOR_HIGH_ACT;
+ if (VSYNC_POSITIVE)
+ mode->sync |= FB_SYNC_VERT_HIGH_ACT;
+ mode->refresh = PIXEL_CLOCK/((H_ACTIVE + H_BLANKING) *
+ (V_ACTIVE + V_BLANKING));
+ if (INTERLACED) {
+ mode->yres *= 2;
+ mode->upper_margin *= 2;
+ mode->lower_margin *= 2;
+ mode->vsync_len *= 2;
+ mode->vmode |= FB_VMODE_INTERLACED;
+ }
+ mode->flag = FB_MODE_IS_DETAILED;
+
+ if ((H_SIZE / 16) == (V_SIZE / 9))
+ mode->vmode |= FB_VMODE_ASPECT_16_9;
+ else if ((H_SIZE / 4) == (V_SIZE / 3))
+ mode->vmode |= FB_VMODE_ASPECT_4_3;
+ else if ((mode->xres / 16) == (mode->yres / 9))
+ mode->vmode |= FB_VMODE_ASPECT_16_9;
+ else if ((mode->xres / 4) == (mode->yres / 3))
+ mode->vmode |= FB_VMODE_ASPECT_4_3;
+
+ if (mode->vmode & FB_VMODE_ASPECT_16_9)
+ DPRINTK("Aspect ratio: 16:9\n");
+ if (mode->vmode & FB_VMODE_ASPECT_4_3)
+ DPRINTK("Aspect ratio: 4:3\n");
+ DPRINTK(" %d MHz ", PIXEL_CLOCK/1000000);
+ DPRINTK("%d %d %d %d ", H_ACTIVE, H_ACTIVE + H_SYNC_OFFSET,
+ H_ACTIVE + H_SYNC_OFFSET + H_SYNC_WIDTH, H_ACTIVE + H_BLANKING);
+ DPRINTK("%d %d %d %d ", V_ACTIVE, V_ACTIVE + V_SYNC_OFFSET,
+ V_ACTIVE + V_SYNC_OFFSET + V_SYNC_WIDTH, V_ACTIVE + V_BLANKING);
+ DPRINTK("%sHSync %sVSync\n\n", (HSYNC_POSITIVE) ? "+" : "-",
+ (VSYNC_POSITIVE) ? "+" : "-");
+}
+
+int mxc_edid_parse_ext_blk(unsigned char *edid,
+ struct mxc_edid_cfg *cfg,
+ struct fb_monspecs *specs)
+{
+ char detail_timing_desc_offset;
+ struct fb_videomode *mode, *m;
+ unsigned char index = 0x0;
+ unsigned char *block;
+ int i, num = 0, revision;
+
+ if (edid[index++] != 0x2) /* only support cea ext block now */
+ return 0;
+ revision = edid[index++];
+ DPRINTK("cea extent revision %d\n", revision);
+ mode = kzalloc(50 * sizeof(struct fb_videomode), GFP_KERNEL);
+ if (mode == NULL)
+ return -1;
+
+ detail_timing_desc_offset = edid[index++];
+
+ if (revision >= 2) {
+ cfg->cea_underscan = (edid[index] >> 7) & 0x1;
+ cfg->cea_basicaudio = (edid[index] >> 6) & 0x1;
+ cfg->cea_ycbcr444 = (edid[index] >> 5) & 0x1;
+ cfg->cea_ycbcr422 = (edid[index] >> 4) & 0x1;
+
+ DPRINTK("CEA underscan %d\n", cfg->cea_underscan);
+ DPRINTK("CEA basicaudio %d\n", cfg->cea_basicaudio);
+ DPRINTK("CEA ycbcr444 %d\n", cfg->cea_ycbcr444);
+ DPRINTK("CEA ycbcr422 %d\n", cfg->cea_ycbcr422);
+ }
+
+ if (revision >= 3) {
+ /* short desc */
+ DPRINTK("CEA Short desc timmings\n");
+ index++;
+ while (index < detail_timing_desc_offset) {
+ unsigned char tagcode, blklen;
+
+ tagcode = (edid[index] >> 5) & 0x7;
+ blklen = (edid[index]) & 0x1f;
+
+ DPRINTK("Tagcode %x Len %d\n", tagcode, blklen);
+
+ switch (tagcode) {
+ case 0x2: /*Video data block*/
+ {
+ int cea_idx;
+ i = 0;
+ while (i < blklen) {
+ index++;
+ cea_idx = edid[index] & 0x7f;
+ if (cea_idx < ARRAY_SIZE(mxc_cea_mode) &&
+ (mxc_cea_mode[cea_idx].xres)) {
+ DPRINTK("Support CEA Format #%d\n", cea_idx);
+ mode[num] = mxc_cea_mode[cea_idx];
+ mode[num].flag |= FB_MODE_IS_STANDARD;
+ num++;
+ }
+ i++;
+ }
+ break;
+ }
+ case 0x3: /*Vendor specific data*/
+ {
+ unsigned char IEEE_reg_iden[3];
+ unsigned char deep_color;
+ unsigned char latency_present;
+ unsigned char I_latency_present;
+ unsigned char hdmi_video_present;
+ unsigned char hdmi_3d_present;
+ unsigned char hdmi_3d_multi_present;
+ unsigned char hdmi_vic_len;
+ unsigned char hdmi_3d_len;
+ unsigned char index_inc = 0;
+ unsigned char vsd_end;
+
+ vsd_end = index + blklen;
+
+ IEEE_reg_iden[0] = edid[index+1];
+ IEEE_reg_iden[1] = edid[index+2];
+ IEEE_reg_iden[2] = edid[index+3];
+ cfg->physical_address[0] = (edid[index+4] & 0xf0) >> 4;
+ cfg->physical_address[1] = (edid[index+4] & 0x0f);
+ cfg->physical_address[2] = (edid[index+5] & 0xf0) >> 4;
+ cfg->physical_address[3] = (edid[index+5] & 0x0f);
+
+ if ((IEEE_reg_iden[0] == 0x03) &&
+ (IEEE_reg_iden[1] == 0x0c) &&
+ (IEEE_reg_iden[2] == 0x00))
+ cfg->hdmi_cap = 1;
+
+ if (blklen > 5) {
+ deep_color = edid[index+6];
+ if (deep_color & 0x80)
+ cfg->vsd_support_ai = true;
+ if (deep_color & 0x40)
+ cfg->vsd_dc_48bit = true;
+ if (deep_color & 0x20)
+ cfg->vsd_dc_36bit = true;
+ if (deep_color & 0x10)
+ cfg->vsd_dc_30bit = true;
+ if (deep_color & 0x08)
+ cfg->vsd_dc_y444 = true;
+ if (deep_color & 0x01)
+ cfg->vsd_dvi_dual = true;
+ }
+
+ DPRINTK("VSD hdmi capability %d\n", cfg->hdmi_cap);
+ DPRINTK("VSD support ai %d\n", cfg->vsd_support_ai);
+ DPRINTK("VSD support deep color 48bit %d\n", cfg->vsd_dc_48bit);
+ DPRINTK("VSD support deep color 36bit %d\n", cfg->vsd_dc_36bit);
+ DPRINTK("VSD support deep color 30bit %d\n", cfg->vsd_dc_30bit);
+ DPRINTK("VSD support deep color y444 %d\n", cfg->vsd_dc_y444);
+ DPRINTK("VSD support dvi dual %d\n", cfg->vsd_dvi_dual);
+
+ if (blklen > 6)
+ cfg->vsd_max_tmdsclk_rate = edid[index+7] * 5;
+ DPRINTK("VSD MAX TMDS CLOCK RATE %d\n", cfg->vsd_max_tmdsclk_rate);
+
+ if (blklen > 7) {
+ latency_present = edid[index+8] >> 7;
+ I_latency_present = (edid[index+8] & 0x40) >> 6;
+ hdmi_video_present = (edid[index+8] & 0x20) >> 5;
+ cfg->vsd_cnc3 = (edid[index+8] & 0x8) >> 3;
+ cfg->vsd_cnc2 = (edid[index+8] & 0x4) >> 2;
+ cfg->vsd_cnc1 = (edid[index+8] & 0x2) >> 1;
+ cfg->vsd_cnc0 = edid[index+8] & 0x1;
+
+ DPRINTK("VSD cnc0 %d\n", cfg->vsd_cnc0);
+ DPRINTK("VSD cnc1 %d\n", cfg->vsd_cnc1);
+ DPRINTK("VSD cnc2 %d\n", cfg->vsd_cnc2);
+ DPRINTK("VSD cnc3 %d\n", cfg->vsd_cnc3);
+ DPRINTK("latency_present %d\n", latency_present);
+ DPRINTK("I_latency_present %d\n", I_latency_present);
+ DPRINTK("hdmi_video_present %d\n", hdmi_video_present);
+
+ } else {
+ index += blklen;
+ break;
+ }
+
+ index += 9;
+
+ /*latency present */
+ if (latency_present) {
+ cfg->vsd_video_latency = edid[index++];
+ cfg->vsd_audio_latency = edid[index++];
+
+ if (I_latency_present) {
+ cfg->vsd_I_video_latency = edid[index++];
+ cfg->vsd_I_audio_latency = edid[index++];
+ } else {
+ cfg->vsd_I_video_latency = cfg->vsd_video_latency;
+ cfg->vsd_I_audio_latency = cfg->vsd_audio_latency;
+ }
+
+ DPRINTK("VSD latency video_latency %d\n", cfg->vsd_video_latency);
+ DPRINTK("VSD latency audio_latency %d\n", cfg->vsd_audio_latency);
+ DPRINTK("VSD latency I_video_latency %d\n", cfg->vsd_I_video_latency);
+ DPRINTK("VSD latency I_audio_latency %d\n", cfg->vsd_I_audio_latency);
+ }
+
+ if (hdmi_video_present) {
+ hdmi_3d_present = edid[index] >> 7;
+ hdmi_3d_multi_present = (edid[index] & 0x60) >> 5;
+ index++;
+ hdmi_vic_len = (edid[index] & 0xe0) >> 5;
+ hdmi_3d_len = edid[index] & 0x1f;
+ index++;
+
+ DPRINTK("hdmi_3d_present %d\n", hdmi_3d_present);
+ DPRINTK("hdmi_3d_multi_present %d\n", hdmi_3d_multi_present);
+ DPRINTK("hdmi_vic_len %d\n", hdmi_vic_len);
+ DPRINTK("hdmi_3d_len %d\n", hdmi_3d_len);
+
+ if (hdmi_vic_len > 0) {
+ for (i = 0; i < hdmi_vic_len; i++) {
+ cfg->hdmi_vic[i] = edid[index++];
+ DPRINTK("HDMI_vic=%d\n", cfg->hdmi_vic[i]);
+ }
+ }
+
+ if (hdmi_3d_len > 0) {
+ if (hdmi_3d_present) {
+ if (hdmi_3d_multi_present == 0x1) {
+ cfg->hdmi_3d_struct_all = (edid[index] << 8) | edid[index+1];
+ index_inc = 2;
+ } else if (hdmi_3d_multi_present == 0x2) {
+ cfg->hdmi_3d_struct_all = (edid[index] << 8) | edid[index+1];
+ cfg->hdmi_3d_mask_all = (edid[index+2] << 8) | edid[index+3];
+ index_inc = 4;
+ } else
+ index_inc = 0;
+ }
+
+ DPRINTK("HDMI 3d struct all =0x%x\n", cfg->hdmi_3d_struct_all);
+ DPRINTK("HDMI 3d mask all =0x%x\n", cfg->hdmi_3d_mask_all);
+
+ /* Read 2D vic 3D_struct */
+ if ((hdmi_3d_len - index_inc) > 0) {
+ DPRINTK("Support 3D video format\n");
+ i = 0;
+ while ((hdmi_3d_len - index_inc) > 0) {
+
+ cfg->hdmi_3d_format[i].vic_order_2d = edid[index+index_inc] >> 4;
+ cfg->hdmi_3d_format[i].struct_3d = edid[index+index_inc] & 0x0f;
+ index_inc++;
+
+ if (cfg->hdmi_3d_format[i].struct_3d == 8) {
+ cfg->hdmi_3d_format[i].detail_3d = edid[index+index_inc] >> 4;
+ index_inc++;
+ } else if (cfg->hdmi_3d_format[i].struct_3d > 8) {
+ cfg->hdmi_3d_format[i].detail_3d = 0;
+ index_inc++;
+ }
+
+ DPRINTK("vic_order_2d=%d, 3d_struct=%d, 3d_detail=0x%x\n",
+ cfg->hdmi_3d_format[i].vic_order_2d,
+ cfg->hdmi_3d_format[i].struct_3d,
+ cfg->hdmi_3d_format[i].detail_3d);
+ i++;
+ }
+ }
+ index += index_inc;
+ }
+ }
+
+ index = vsd_end;
+
+ break;
+ }
+ case 0x1: /*Audio data block*/
+ {
+ u8 audio_format, max_ch, byte1, byte2, byte3;
+
+ i = 0;
+ cfg->max_channels = 0;
+ cfg->sample_rates = 0;
+ cfg->sample_sizes = 0;
+
+ while (i < blklen) {
+ byte1 = edid[index + 1];
+ byte2 = edid[index + 2];
+ byte3 = edid[index + 3];
+ index += 3;
+ i += 3;
+
+ audio_format = byte1 >> 3;
+ max_ch = (byte1 & 0x07) + 1;
+
+ DPRINTK("Audio Format Descriptor : %2d\n", audio_format);
+ DPRINTK("Max Number of Channels : %2d\n", max_ch);
+ DPRINTK("Sample Rates : %02x\n", byte2);
+
+ /* ALSA can't specify specific compressed
+ * formats, so only care about PCM for now. */
+ if (audio_format == AUDIO_CODING_TYPE_LPCM) {
+ if (max_ch > cfg->max_channels)
+ cfg->max_channels = max_ch;
+
+ cfg->sample_rates |= byte2;
+ cfg->sample_sizes |= byte3 & 0x7;
+ DPRINTK("Sample Sizes : %02x\n",
+ byte3 & 0x7);
+ }
+ }
+ break;
+ }
+ case 0x4: /*Speaker allocation block*/
+ {
+ i = 0;
+ while (i < blklen) {
+ cfg->speaker_alloc = edid[index + 1];
+ index += 3;
+ i += 3;
+ DPRINTK("Speaker Alloc : %02x\n", cfg->speaker_alloc);
+ }
+ break;
+ }
+ case 0x7: /*User extended block*/
+ default:
+ /* skip */
+ DPRINTK("Not handle block, tagcode = 0x%x\n", tagcode);
+ index += blklen;
+ break;
+ }
+
+ index++;
+ }
+ }
+
+ /* long desc */
+ DPRINTK("CEA long desc timmings\n");
+ index = detail_timing_desc_offset;
+ block = edid + index;
+ while (index < (EDID_LENGTH - DETAILED_TIMING_DESCRIPTION_SIZE)) {
+ if (!(block[0] == 0x00 && block[1] == 0x00)) {
+ get_detailed_timing(block, &mode[num]);
+ num++;
+ }
+ block += DETAILED_TIMING_DESCRIPTION_SIZE;
+ index += DETAILED_TIMING_DESCRIPTION_SIZE;
+ }
+
+ if (!num) {
+ kfree(mode);
+ return 0;
+ }
+
+ m = kmalloc((num + specs->modedb_len) *
+ sizeof(struct fb_videomode), GFP_KERNEL);
+ if (!m) {
+ kfree(mode);
+ return 0;
+ }
+
+ if (specs->modedb_len) {
+ memmove(m, specs->modedb,
+ specs->modedb_len * sizeof(struct fb_videomode));
+ kfree(specs->modedb);
+ }
+ memmove(m+specs->modedb_len, mode,
+ num * sizeof(struct fb_videomode));
+ kfree(mode);
+
+ specs->modedb_len += num;
+ specs->modedb = m;
+
+ return 0;
+}
+EXPORT_SYMBOL(mxc_edid_parse_ext_blk);
+
+static int mxc_edid_readblk(struct i2c_adapter *adp,
+ unsigned short addr, unsigned char *edid)
+{
+ int ret = 0, extblknum = 0;
+ unsigned char regaddr = 0x0;
+ struct i2c_msg msg[2] = {
+ {
+ .addr = addr,
+ .flags = 0,
+ .len = 1,
+ .buf = &regaddr,
+ }, {
+ .addr = addr,
+ .flags = I2C_M_RD,
+ .len = EDID_LENGTH,
+ .buf = edid,
+ },
+ };
+
+ ret = i2c_transfer(adp, msg, ARRAY_SIZE(msg));
+ if (ret != ARRAY_SIZE(msg)) {
+ DPRINTK("unable to read EDID block\n");
+ return -EIO;
+ }
+
+ if (edid[1] == 0x00)
+ return -ENOENT;
+
+ extblknum = edid[0x7E];
+
+ if (extblknum) {
+ regaddr = 128;
+ msg[1].buf = edid + EDID_LENGTH;
+
+ ret = i2c_transfer(adp, msg, ARRAY_SIZE(msg));
+ if (ret != ARRAY_SIZE(msg)) {
+ DPRINTK("unable to read EDID ext block\n");
+ return -EIO;
+ }
+ }
+
+ return extblknum;
+}
+
+static int mxc_edid_readsegblk(struct i2c_adapter *adp, unsigned short addr,
+ unsigned char *edid, int seg_num)
+{
+ int ret = 0;
+ unsigned char segment = 0x1, regaddr = 0;
+ struct i2c_msg msg[3] = {
+ {
+ .addr = 0x30,
+ .flags = 0,
+ .len = 1,
+ .buf = &segment,
+ }, {
+ .addr = addr,
+ .flags = 0,
+ .len = 1,
+ .buf = &regaddr,
+ }, {
+ .addr = addr,
+ .flags = I2C_M_RD,
+ .len = EDID_LENGTH,
+ .buf = edid,
+ },
+ };
+
+ ret = i2c_transfer(adp, msg, ARRAY_SIZE(msg));
+ if (ret != ARRAY_SIZE(msg)) {
+ DPRINTK("unable to read EDID block\n");
+ return -EIO;
+ }
+
+ if (seg_num == 2) {
+ regaddr = 128;
+ msg[2].buf = edid + EDID_LENGTH;
+
+ ret = i2c_transfer(adp, msg, ARRAY_SIZE(msg));
+ if (ret != ARRAY_SIZE(msg)) {
+ DPRINTK("unable to read EDID block\n");
+ return -EIO;
+ }
+ }
+
+ return ret;
+}
+
+int mxc_edid_var_to_vic(struct fb_var_screeninfo *var)
+{
+ int i;
+ struct fb_videomode m;
+
+ for (i = 0; i < ARRAY_SIZE(mxc_cea_mode); i++) {
+ fb_var_to_videomode(&m, var);
+ if (mxc_edid_fb_mode_is_equal(false, &m, &mxc_cea_mode[i]))
+ break;
+ }
+
+ if (i == ARRAY_SIZE(mxc_cea_mode))
+ return 0;
+
+ return i;
+}
+EXPORT_SYMBOL(mxc_edid_var_to_vic);
+
+int mxc_edid_mode_to_vic(const struct fb_videomode *mode)
+{
+ int i;
+ bool use_aspect = (mode->vmode & FB_VMODE_ASPECT_MASK);
+
+ for (i = 0; i < ARRAY_SIZE(mxc_cea_mode); i++) {
+ if (mxc_edid_fb_mode_is_equal(use_aspect, mode, &mxc_cea_mode[i]))
+ break;
+ }
+
+ if (i == ARRAY_SIZE(mxc_cea_mode))
+ return 0;
+
+ return i;
+}
+EXPORT_SYMBOL(mxc_edid_mode_to_vic);
+
+/* make sure edid has 512 bytes*/
+int mxc_edid_read(struct i2c_adapter *adp, unsigned short addr,
+ unsigned char *edid, struct mxc_edid_cfg *cfg, struct fb_info *fbi)
+{
+ int ret = 0, extblknum;
+ if (!adp || !edid || !cfg || !fbi)
+ return -EINVAL;
+
+ memset(edid, 0, EDID_LENGTH*4);
+ memset(cfg, 0, sizeof(struct mxc_edid_cfg));
+
+ extblknum = mxc_edid_readblk(adp, addr, edid);
+ if (extblknum < 0)
+ return extblknum;
+
+ /* edid first block parsing */
+ memset(&fbi->monspecs, 0, sizeof(fbi->monspecs));
+ fb_edid_to_monspecs(edid, &fbi->monspecs);
+
+ if (extblknum) {
+ int i;
+
+ /* FIXME: mxc_edid_readsegblk() won't read more than 2 blocks
+ * and the for-loop will read past the end of the buffer! :-( */
+ if (extblknum > 3) {
+ WARN_ON(true);
+ return -EINVAL;
+ }
+
+ /* need read segment block? */
+ if (extblknum > 1) {
+ ret = mxc_edid_readsegblk(adp, addr,
+ edid + EDID_LENGTH*2, extblknum - 1);
+ if (ret < 0)
+ return ret;
+ }
+
+ for (i = 1; i <= extblknum; i++)
+ /* edid ext block parsing */
+ mxc_edid_parse_ext_blk(edid + i*EDID_LENGTH,
+ cfg, &fbi->monspecs);
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL(mxc_edid_read);
+
diff --git a/drivers/video/fbdev/mxc/mxc_epdc_fb.c b/drivers/video/fbdev/mxc/mxc_epdc_fb.c
new file mode 100644
index 000000000000..0109b0371b76
--- /dev/null
+++ b/drivers/video/fbdev/mxc/mxc_epdc_fb.c
@@ -0,0 +1,5601 @@
+/*
+ * Copyright (C) 2010-2016 Freescale Semiconductor, Inc.
+ * Copyright 2017 NXP
+ *
+ * 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
+ *
+ */
+/*
+ * Based on STMP378X LCDIF
+ * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved.
+ */
+
+#include <linux/busfreq-imx.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/input.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/fb.h>
+#include <linux/init.h>
+#include <linux/list.h>
+#include <linux/mutex.h>
+#include <linux/delay.h>
+#include <linux/dma-mapping.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/uaccess.h>
+#include <linux/cpufreq.h>
+#include <linux/firmware.h>
+#include <linux/kthread.h>
+#include <linux/dmaengine.h>
+#include <linux/pxp_dma.h>
+#include <linux/pm_runtime.h>
+#include <linux/mxcfb.h>
+#include <linux/mxcfb_epdc.h>
+#include <linux/gpio.h>
+#include <linux/regulator/driver.h>
+#include <linux/fsl_devices.h>
+#include <linux/bitops.h>
+#include <linux/pinctrl/consumer.h>
+#include <linux/platform_data/dma-imx.h>
+#include <asm/cacheflush.h>
+
+#include "epdc_regs.h"
+
+/*
+ * Enable this define to have a default panel
+ * loaded during driver initialization
+ */
+/*#define DEFAULT_PANEL_HW_INIT*/
+
+#define NUM_SCREENS_MIN 2
+
+#define EPDC_V1_NUM_LUTS 16
+#define EPDC_V1_MAX_NUM_UPDATES 20
+#define EPDC_V2_NUM_LUTS 64
+#define EPDC_V2_MAX_NUM_UPDATES 64
+#define EPDC_MAX_NUM_BUFFERS 2
+#define INVALID_LUT (-1)
+#define DRY_RUN_NO_LUT 100
+
+/* Maximum update buffer image width due to v2.0 and v2.1 errata ERR005313. */
+#define EPDC_V2_MAX_UPDATE_WIDTH 2047
+#define EPDC_V2_ROTATION_ALIGNMENT 8
+
+#define DEFAULT_TEMP_INDEX 0
+#define DEFAULT_TEMP 20 /* room temp in deg Celsius */
+
+#define INIT_UPDATE_MARKER 0x12345678
+#define PAN_UPDATE_MARKER 0x12345679
+
+#define POWER_STATE_OFF 0
+#define POWER_STATE_ON 1
+
+#define MERGE_OK 0
+#define MERGE_FAIL 1
+#define MERGE_BLOCK 2
+
+static unsigned long default_bpp = 16;
+static DEFINE_MUTEX(hard_lock);
+
+struct update_marker_data {
+ struct list_head full_list;
+ struct list_head upd_list;
+ u32 update_marker;
+ struct completion update_completion;
+ int lut_num;
+ bool collision_test;
+ bool waiting;
+};
+
+struct update_desc_list {
+ struct list_head list;
+ struct mxcfb_update_data upd_data;/* Update parameters */
+ u32 epdc_offs; /* Added to buffer ptr to resolve alignment */
+ u32 epdc_stride; /* Depends on rotation & whether we skip PxP */
+ struct list_head upd_marker_list; /* List of markers for this update */
+ u32 update_order; /* Numeric ordering value for update */
+};
+
+/* This structure represents a list node containing both
+ * a memory region allocated as an output buffer for the PxP
+ * update processing task, and the update description (mode, region, etc.) */
+struct update_data_list {
+ struct list_head list;
+ dma_addr_t phys_addr; /* Pointer to phys address of processed Y buf */
+ void *virt_addr;
+ struct update_desc_list *update_desc;
+ int lut_num; /* Assigned before update is processed into working buffer */
+ u64 collision_mask; /* Set when update creates collision */
+ /* Mask of the LUTs the update collides with */
+};
+
+struct mxc_epdc_fb_data {
+ struct fb_info info;
+ struct fb_var_screeninfo epdc_fb_var; /* Internal copy of screeninfo
+ so we can sync changes to it */
+ u32 pseudo_palette[16];
+ char fw_str[24];
+ struct list_head list;
+ struct imx_epdc_fb_mode *cur_mode;
+ struct imx_epdc_fb_platform_data *pdata;
+ int blank;
+ u32 max_pix_size;
+ ssize_t map_size;
+ dma_addr_t phys_start;
+ u32 fb_offset;
+ int default_bpp;
+ int native_width;
+ int native_height;
+ int num_screens;
+ int epdc_irq;
+ struct device *dev;
+ int power_state;
+ int wait_for_powerdown;
+ struct completion powerdown_compl;
+ struct clk *epdc_clk_axi;
+ struct clk *epdc_clk_pix;
+ struct regulator *display_regulator;
+ struct regulator *vcom_regulator;
+ struct regulator *v3p3_regulator;
+ bool fw_default_load;
+ int rev;
+
+ /* FB elements related to EPDC updates */
+ int num_luts;
+ int max_num_updates;
+ bool in_init;
+ bool hw_ready;
+ bool hw_initializing;
+ bool waiting_for_idle;
+ u32 auto_mode;
+ u32 upd_scheme;
+ struct list_head upd_pending_list;
+ struct list_head upd_buf_queue;
+ struct list_head upd_buf_free_list;
+ struct list_head upd_buf_collision_list;
+ struct update_data_list *cur_update;
+ struct mutex queue_mutex;
+ int trt_entries;
+ int temp_index;
+ u8 *temp_range_bounds;
+ struct mxcfb_waveform_modes wv_modes;
+ bool wv_modes_update;
+ u32 *waveform_buffer_virt;
+ u32 waveform_buffer_phys;
+ u32 waveform_buffer_size;
+ u32 *working_buffer_virt;
+ u32 working_buffer_phys;
+ u32 working_buffer_size;
+ dma_addr_t *phys_addr_updbuf;
+ void **virt_addr_updbuf;
+ u32 upd_buffer_num;
+ u32 max_num_buffers;
+ dma_addr_t phys_addr_copybuf; /* Phys address of copied update data */
+ void *virt_addr_copybuf; /* Used for PxP SW workaround */
+ u32 order_cnt;
+ struct list_head full_marker_list;
+ u32 *lut_update_order; /* Array size = number of luts */
+ u64 epdc_colliding_luts;
+ u64 luts_complete_wb;
+ struct completion updates_done;
+ struct delayed_work epdc_done_work;
+ struct workqueue_struct *epdc_submit_workqueue;
+ struct work_struct epdc_submit_work;
+ struct workqueue_struct *epdc_intr_workqueue;
+ struct work_struct epdc_intr_work;
+ bool waiting_for_wb;
+ bool waiting_for_lut;
+ bool waiting_for_lut15;
+ struct completion update_res_free;
+ struct completion lut15_free;
+ struct completion eof_event;
+ int eof_sync_period;
+ struct mutex power_mutex;
+ bool powering_down;
+ bool updates_active;
+ int pwrdown_delay;
+ unsigned long tce_prevent;
+ bool restrict_width; /* work around rev >=2.0 width and
+ stride restriction */
+
+ /* FB elements related to PxP DMA */
+ struct completion pxp_tx_cmpl;
+ struct pxp_channel *pxp_chan;
+ struct pxp_config_data pxp_conf;
+ struct dma_async_tx_descriptor *txd;
+ dma_cookie_t cookie;
+ struct scatterlist sg[2];
+ struct mutex pxp_mutex; /* protects access to PxP */
+};
+
+struct waveform_data_header {
+ unsigned int wi0;
+ unsigned int wi1;
+ unsigned int wi2;
+ unsigned int wi3;
+ unsigned int wi4;
+ unsigned int wi5;
+ unsigned int wi6;
+ unsigned int xwia:24;
+ unsigned int cs1:8;
+ unsigned int wmta:24;
+ unsigned int fvsn:8;
+ unsigned int luts:8;
+ unsigned int mc:8;
+ unsigned int trc:8;
+ unsigned int reserved0_0:8;
+ unsigned int eb:8;
+ unsigned int sb:8;
+ unsigned int reserved0_1:8;
+ unsigned int reserved0_2:8;
+ unsigned int reserved0_3:8;
+ unsigned int reserved0_4:8;
+ unsigned int reserved0_5:8;
+ unsigned int cs2:8;
+};
+
+struct mxcfb_waveform_data_file {
+ struct waveform_data_header wdh;
+ u32 *data; /* Temperature Range Table + Waveform Data */
+};
+
+static struct fb_videomode e60_v110_mode = {
+ .name = "E60_V110",
+ .refresh = 50,
+ .xres = 800,
+ .yres = 600,
+ .pixclock = 18604700,
+ .left_margin = 8,
+ .right_margin = 178,
+ .upper_margin = 4,
+ .lower_margin = 10,
+ .hsync_len = 20,
+ .vsync_len = 4,
+ .sync = 0,
+ .vmode = FB_VMODE_NONINTERLACED,
+ .flag = 0,
+};
+
+static struct fb_videomode e60_v220_mode = {
+ .name = "E60_V220",
+ .refresh = 85,
+ .xres = 800,
+ .yres = 600,
+ .pixclock = 30000000,
+ .left_margin = 8,
+ .right_margin = 164,
+ .upper_margin = 4,
+ .lower_margin = 8,
+ .hsync_len = 4,
+ .vsync_len = 1,
+ .sync = 0,
+ .vmode = FB_VMODE_NONINTERLACED,
+ .flag = 0,
+};
+
+static struct fb_videomode e060scm_mode = {
+ .name = "E060SCM",
+ .refresh = 85,
+ .xres = 800,
+ .yres = 600,
+ .pixclock = 26666667,
+ .left_margin = 8,
+ .right_margin = 100,
+ .upper_margin = 4,
+ .lower_margin = 8,
+ .hsync_len = 4,
+ .vsync_len = 1,
+ .sync = 0,
+ .vmode = FB_VMODE_NONINTERLACED,
+ .flag = 0,
+};
+
+static struct fb_videomode e97_v110_mode = {
+ .name = "E97_V110",
+ .refresh = 50,
+ .xres = 1200,
+ .yres = 825,
+ .pixclock = 32000000,
+ .left_margin = 12,
+ .right_margin = 128,
+ .upper_margin = 4,
+ .lower_margin = 10,
+ .hsync_len = 20,
+ .vsync_len = 4,
+ .sync = 0,
+ .vmode = FB_VMODE_NONINTERLACED,
+ .flag = 0,
+};
+
+static struct imx_epdc_fb_mode panel_modes[] = {
+ {
+ &e60_v110_mode,
+ 4, /* vscan_holdoff */
+ 10, /* sdoed_width */
+ 20, /* sdoed_delay */
+ 10, /* sdoez_width */
+ 20, /* sdoez_delay */
+ 428, /* gdclk_hp_offs */
+ 20, /* gdsp_offs */
+ 0, /* gdoe_offs */
+ 1, /* gdclk_offs */
+ 1, /* num_ce */
+ },
+ {
+ &e60_v220_mode,
+ 4, /* vscan_holdoff */
+ 10, /* sdoed_width */
+ 20, /* sdoed_delay */
+ 10, /* sdoez_width */
+ 20, /* sdoez_delay */
+ 465, /* gdclk_hp_offs */
+ 20, /* gdsp_offs */
+ 0, /* gdoe_offs */
+ 9, /* gdclk_offs */
+ 1, /* num_ce */
+ },
+ {
+ &e060scm_mode,
+ 4, /* vscan_holdoff */
+ 10, /* sdoed_width */
+ 20, /* sdoed_delay */
+ 10, /* sdoez_width */
+ 20, /* sdoez_delay */
+ 419, /* gdclk_hp_offs */
+ 20, /* gdsp_offs */
+ 0, /* gdoe_offs */
+ 5, /* gdclk_offs */
+ 1, /* num_ce */
+ },
+ {
+ &e97_v110_mode,
+ 8, /* vscan_holdoff */
+ 10, /* sdoed_width */
+ 20, /* sdoed_delay */
+ 10, /* sdoez_width */
+ 20, /* sdoez_delay */
+ 632, /* gdclk_hp_offs */
+ 20, /* gdsp_offs */
+ 0, /* gdoe_offs */
+ 1, /* gdclk_offs */
+ 3, /* num_ce */
+ }
+};
+
+static struct imx_epdc_fb_platform_data epdc_data = {
+ .epdc_mode = panel_modes,
+ .num_modes = ARRAY_SIZE(panel_modes),
+};
+
+void __iomem *epdc_base;
+
+struct mxc_epdc_fb_data *g_fb_data;
+
+/* forward declaration */
+static int mxc_epdc_fb_get_temp_index(struct mxc_epdc_fb_data *fb_data,
+ int temp);
+static void mxc_epdc_fb_flush_updates(struct mxc_epdc_fb_data *fb_data);
+static int mxc_epdc_fb_blank(int blank, struct fb_info *info);
+static int mxc_epdc_fb_init_hw(struct fb_info *info);
+static int pxp_process_update(struct mxc_epdc_fb_data *fb_data,
+ u32 src_width, u32 src_height,
+ struct mxcfb_rect *update_region);
+static int pxp_complete_update(struct mxc_epdc_fb_data *fb_data, u32 *hist_stat);
+
+static void draw_mode0(struct mxc_epdc_fb_data *fb_data);
+static bool is_free_list_full(struct mxc_epdc_fb_data *fb_data);
+
+static void do_dithering_processing_Y1_v1_0(
+ unsigned char *update_region_virt_ptr,
+ dma_addr_t update_region_phys_ptr,
+ struct mxcfb_rect *update_region,
+ unsigned long update_region_stride,
+ int *err_dist);
+static void do_dithering_processing_Y4_v1_0(
+ unsigned char *update_region_virt_ptr,
+ dma_addr_t update_region_phys_ptr,
+ struct mxcfb_rect *update_region,
+ unsigned long update_region_stride,
+ int *err_dist);
+
+#ifdef DEBUG
+static void dump_pxp_config(struct mxc_epdc_fb_data *fb_data,
+ struct pxp_config_data *pxp_conf)
+{
+ dev_info(fb_data->dev, "S0 fmt 0x%x",
+ pxp_conf->s0_param.pixel_fmt);
+ dev_info(fb_data->dev, "S0 width 0x%x",
+ pxp_conf->s0_param.width);
+ dev_info(fb_data->dev, "S0 height 0x%x",
+ pxp_conf->s0_param.height);
+ dev_info(fb_data->dev, "S0 ckey 0x%x",
+ pxp_conf->s0_param.color_key);
+ dev_info(fb_data->dev, "S0 ckey en 0x%x",
+ pxp_conf->s0_param.color_key_enable);
+
+ dev_info(fb_data->dev, "OL0 combine en 0x%x",
+ pxp_conf->ol_param[0].combine_enable);
+ dev_info(fb_data->dev, "OL0 fmt 0x%x",
+ pxp_conf->ol_param[0].pixel_fmt);
+ dev_info(fb_data->dev, "OL0 width 0x%x",
+ pxp_conf->ol_param[0].width);
+ dev_info(fb_data->dev, "OL0 height 0x%x",
+ pxp_conf->ol_param[0].height);
+ dev_info(fb_data->dev, "OL0 ckey 0x%x",
+ pxp_conf->ol_param[0].color_key);
+ dev_info(fb_data->dev, "OL0 ckey en 0x%x",
+ pxp_conf->ol_param[0].color_key_enable);
+ dev_info(fb_data->dev, "OL0 alpha 0x%x",
+ pxp_conf->ol_param[0].global_alpha);
+ dev_info(fb_data->dev, "OL0 alpha en 0x%x",
+ pxp_conf->ol_param[0].global_alpha_enable);
+ dev_info(fb_data->dev, "OL0 local alpha en 0x%x",
+ pxp_conf->ol_param[0].local_alpha_enable);
+
+ dev_info(fb_data->dev, "Out fmt 0x%x",
+ pxp_conf->out_param.pixel_fmt);
+ dev_info(fb_data->dev, "Out width 0x%x",
+ pxp_conf->out_param.width);
+ dev_info(fb_data->dev, "Out height 0x%x",
+ pxp_conf->out_param.height);
+
+ dev_info(fb_data->dev,
+ "drect left 0x%x right 0x%x width 0x%x height 0x%x",
+ pxp_conf->proc_data.drect.left, pxp_conf->proc_data.drect.top,
+ pxp_conf->proc_data.drect.width,
+ pxp_conf->proc_data.drect.height);
+ dev_info(fb_data->dev,
+ "srect left 0x%x right 0x%x width 0x%x height 0x%x",
+ pxp_conf->proc_data.srect.left, pxp_conf->proc_data.srect.top,
+ pxp_conf->proc_data.srect.width,
+ pxp_conf->proc_data.srect.height);
+ dev_info(fb_data->dev, "Scaling en 0x%x", pxp_conf->proc_data.scaling);
+ dev_info(fb_data->dev, "HFlip en 0x%x", pxp_conf->proc_data.hflip);
+ dev_info(fb_data->dev, "VFlip en 0x%x", pxp_conf->proc_data.vflip);
+ dev_info(fb_data->dev, "Rotation 0x%x", pxp_conf->proc_data.rotate);
+ dev_info(fb_data->dev, "BG Color 0x%x", pxp_conf->proc_data.bgcolor);
+}
+
+static void dump_epdc_reg(void)
+{
+ printk(KERN_DEBUG "\n\n");
+ printk(KERN_DEBUG "EPDC_CTRL 0x%x\n", __raw_readl(EPDC_CTRL));
+ printk(KERN_DEBUG "EPDC_WVADDR 0x%x\n", __raw_readl(EPDC_WVADDR));
+ printk(KERN_DEBUG "EPDC_WB_ADDR 0x%x\n", __raw_readl(EPDC_WB_ADDR));
+ printk(KERN_DEBUG "EPDC_RES 0x%x\n", __raw_readl(EPDC_RES));
+ printk(KERN_DEBUG "EPDC_FORMAT 0x%x\n", __raw_readl(EPDC_FORMAT));
+ printk(KERN_DEBUG "EPDC_FIFOCTRL 0x%x\n", __raw_readl(EPDC_FIFOCTRL));
+ printk(KERN_DEBUG "EPDC_UPD_ADDR 0x%x\n", __raw_readl(EPDC_UPD_ADDR));
+ printk(KERN_DEBUG "EPDC_UPD_STRIDE 0x%x\n", __raw_readl(EPDC_UPD_STRIDE));
+ printk(KERN_DEBUG "EPDC_UPD_FIXED 0x%x\n", __raw_readl(EPDC_UPD_FIXED));
+ printk(KERN_DEBUG "EPDC_UPD_CORD 0x%x\n", __raw_readl(EPDC_UPD_CORD));
+ printk(KERN_DEBUG "EPDC_UPD_SIZE 0x%x\n", __raw_readl(EPDC_UPD_SIZE));
+ printk(KERN_DEBUG "EPDC_UPD_CTRL 0x%x\n", __raw_readl(EPDC_UPD_CTRL));
+ printk(KERN_DEBUG "EPDC_TEMP 0x%x\n", __raw_readl(EPDC_TEMP));
+ printk(KERN_DEBUG "EPDC_AUTOWV_LUT 0x%x\n", __raw_readl(EPDC_AUTOWV_LUT));
+ printk(KERN_DEBUG "EPDC_TCE_CTRL 0x%x\n", __raw_readl(EPDC_TCE_CTRL));
+ printk(KERN_DEBUG "EPDC_TCE_SDCFG 0x%x\n", __raw_readl(EPDC_TCE_SDCFG));
+ printk(KERN_DEBUG "EPDC_TCE_GDCFG 0x%x\n", __raw_readl(EPDC_TCE_GDCFG));
+ printk(KERN_DEBUG "EPDC_TCE_HSCAN1 0x%x\n", __raw_readl(EPDC_TCE_HSCAN1));
+ printk(KERN_DEBUG "EPDC_TCE_HSCAN2 0x%x\n", __raw_readl(EPDC_TCE_HSCAN2));
+ printk(KERN_DEBUG "EPDC_TCE_VSCAN 0x%x\n", __raw_readl(EPDC_TCE_VSCAN));
+ printk(KERN_DEBUG "EPDC_TCE_OE 0x%x\n", __raw_readl(EPDC_TCE_OE));
+ printk(KERN_DEBUG "EPDC_TCE_POLARITY 0x%x\n", __raw_readl(EPDC_TCE_POLARITY));
+ printk(KERN_DEBUG "EPDC_TCE_TIMING1 0x%x\n", __raw_readl(EPDC_TCE_TIMING1));
+ printk(KERN_DEBUG "EPDC_TCE_TIMING2 0x%x\n", __raw_readl(EPDC_TCE_TIMING2));
+ printk(KERN_DEBUG "EPDC_TCE_TIMING3 0x%x\n", __raw_readl(EPDC_TCE_TIMING3));
+ printk(KERN_DEBUG "EPDC_PIGEON_CTRL0 0x%x\n", __raw_readl(EPDC_PIGEON_CTRL0));
+ printk(KERN_DEBUG "EPDC_PIGEON_CTRL1 0x%x\n", __raw_readl(EPDC_PIGEON_CTRL1));
+ printk(KERN_DEBUG "EPDC_IRQ_MASK1 0x%x\n", __raw_readl(EPDC_IRQ_MASK1));
+ printk(KERN_DEBUG "EPDC_IRQ_MASK2 0x%x\n", __raw_readl(EPDC_IRQ_MASK2));
+ printk(KERN_DEBUG "EPDC_IRQ1 0x%x\n", __raw_readl(EPDC_IRQ1));
+ printk(KERN_DEBUG "EPDC_IRQ2 0x%x\n", __raw_readl(EPDC_IRQ2));
+ printk(KERN_DEBUG "EPDC_IRQ_MASK 0x%x\n", __raw_readl(EPDC_IRQ_MASK));
+ printk(KERN_DEBUG "EPDC_IRQ 0x%x\n", __raw_readl(EPDC_IRQ));
+ printk(KERN_DEBUG "EPDC_STATUS_LUTS 0x%x\n", __raw_readl(EPDC_STATUS_LUTS));
+ printk(KERN_DEBUG "EPDC_STATUS_LUTS2 0x%x\n", __raw_readl(EPDC_STATUS_LUTS2));
+ printk(KERN_DEBUG "EPDC_STATUS_NEXTLUT 0x%x\n", __raw_readl(EPDC_STATUS_NEXTLUT));
+ printk(KERN_DEBUG "EPDC_STATUS_COL1 0x%x\n", __raw_readl(EPDC_STATUS_COL));
+ printk(KERN_DEBUG "EPDC_STATUS_COL2 0x%x\n", __raw_readl(EPDC_STATUS_COL2));
+ printk(KERN_DEBUG "EPDC_STATUS 0x%x\n", __raw_readl(EPDC_STATUS));
+ printk(KERN_DEBUG "EPDC_UPD_COL_CORD 0x%x\n", __raw_readl(EPDC_UPD_COL_CORD));
+ printk(KERN_DEBUG "EPDC_UPD_COL_SIZE 0x%x\n", __raw_readl(EPDC_UPD_COL_SIZE));
+ printk(KERN_DEBUG "EPDC_DEBUG 0x%x\n", __raw_readl(EPDC_DEBUG));
+ printk(KERN_DEBUG "EPDC_DEBUG_LUT 0x%x\n", __raw_readl(EPDC_DEBUG_LUT));
+ printk(KERN_DEBUG "EPDC_HIST1_PARAM 0x%x\n", __raw_readl(EPDC_HIST1_PARAM));
+ printk(KERN_DEBUG "EPDC_HIST2_PARAM 0x%x\n", __raw_readl(EPDC_HIST2_PARAM));
+ printk(KERN_DEBUG "EPDC_HIST4_PARAM 0x%x\n", __raw_readl(EPDC_HIST4_PARAM));
+ printk(KERN_DEBUG "EPDC_HIST8_PARAM0 0x%x\n", __raw_readl(EPDC_HIST8_PARAM0));
+ printk(KERN_DEBUG "EPDC_HIST8_PARAM1 0x%x\n", __raw_readl(EPDC_HIST8_PARAM1));
+ printk(KERN_DEBUG "EPDC_HIST16_PARAM0 0x%x\n", __raw_readl(EPDC_HIST16_PARAM0));
+ printk(KERN_DEBUG "EPDC_HIST16_PARAM1 0x%x\n", __raw_readl(EPDC_HIST16_PARAM1));
+ printk(KERN_DEBUG "EPDC_HIST16_PARAM2 0x%x\n", __raw_readl(EPDC_HIST16_PARAM2));
+ printk(KERN_DEBUG "EPDC_HIST16_PARAM3 0x%x\n", __raw_readl(EPDC_HIST16_PARAM3));
+ printk(KERN_DEBUG "EPDC_GPIO 0x%x\n", __raw_readl(EPDC_GPIO));
+ printk(KERN_DEBUG "EPDC_VERSION 0x%x\n", __raw_readl(EPDC_VERSION));
+ printk(KERN_DEBUG "\n\n");
+}
+
+static void dump_update_data(struct device *dev,
+ struct update_data_list *upd_data_list)
+{
+ dev_info(dev,
+ "X = %d, Y = %d, Width = %d, Height = %d, WaveMode = %d, "
+ "LUT = %d, Coll Mask = 0x%llx, order = %d\n",
+ upd_data_list->update_desc->upd_data.update_region.left,
+ upd_data_list->update_desc->upd_data.update_region.top,
+ upd_data_list->update_desc->upd_data.update_region.width,
+ upd_data_list->update_desc->upd_data.update_region.height,
+ upd_data_list->update_desc->upd_data.waveform_mode,
+ upd_data_list->lut_num,
+ upd_data_list->collision_mask,
+ upd_data_list->update_desc->update_order);
+}
+
+static void dump_collision_list(struct mxc_epdc_fb_data *fb_data)
+{
+ struct update_data_list *plist;
+
+ dev_info(fb_data->dev, "Collision List:\n");
+ if (list_empty(&fb_data->upd_buf_collision_list))
+ dev_info(fb_data->dev, "Empty");
+ list_for_each_entry(plist, &fb_data->upd_buf_collision_list, list) {
+ dev_info(fb_data->dev, "Virt Addr = 0x%x, Phys Addr = 0x%x ",
+ (u32)plist->virt_addr, plist->phys_addr);
+ dump_update_data(fb_data->dev, plist);
+ }
+}
+
+static void dump_free_list(struct mxc_epdc_fb_data *fb_data)
+{
+ struct update_data_list *plist;
+
+ dev_info(fb_data->dev, "Free List:\n");
+ if (list_empty(&fb_data->upd_buf_free_list))
+ dev_info(fb_data->dev, "Empty");
+ list_for_each_entry(plist, &fb_data->upd_buf_free_list, list)
+ dev_info(fb_data->dev, "Virt Addr = 0x%x, Phys Addr = 0x%x ",
+ (u32)plist->virt_addr, plist->phys_addr);
+}
+
+static void dump_queue(struct mxc_epdc_fb_data *fb_data)
+{
+ struct update_data_list *plist;
+
+ dev_info(fb_data->dev, "Queue:\n");
+ if (list_empty(&fb_data->upd_buf_queue))
+ dev_info(fb_data->dev, "Empty");
+ list_for_each_entry(plist, &fb_data->upd_buf_queue, list) {
+ dev_info(fb_data->dev, "Virt Addr = 0x%x, Phys Addr = 0x%x ",
+ (u32)plist->virt_addr, plist->phys_addr);
+ dump_update_data(fb_data->dev, plist);
+ }
+}
+
+static void dump_desc_data(struct device *dev,
+ struct update_desc_list *upd_desc_list)
+{
+ dev_info(dev,
+ "X = %d, Y = %d, Width = %d, Height = %d, WaveMode = %d, "
+ "order = %d\n",
+ upd_desc_list->upd_data.update_region.left,
+ upd_desc_list->upd_data.update_region.top,
+ upd_desc_list->upd_data.update_region.width,
+ upd_desc_list->upd_data.update_region.height,
+ upd_desc_list->upd_data.waveform_mode,
+ upd_desc_list->update_order);
+}
+
+static void dump_pending_list(struct mxc_epdc_fb_data *fb_data)
+{
+ struct update_desc_list *plist;
+
+ dev_info(fb_data->dev, "Queue:\n");
+ if (list_empty(&fb_data->upd_pending_list))
+ dev_info(fb_data->dev, "Empty");
+ list_for_each_entry(plist, &fb_data->upd_pending_list, list)
+ dump_desc_data(fb_data->dev, plist);
+}
+
+static void dump_all_updates(struct mxc_epdc_fb_data *fb_data)
+{
+ dump_free_list(fb_data);
+ dump_queue(fb_data);
+ dump_collision_list(fb_data);
+ dev_info(fb_data->dev, "Current update being processed:\n");
+ if (fb_data->cur_update == NULL)
+ dev_info(fb_data->dev, "No current update\n");
+ else
+ dump_update_data(fb_data->dev, fb_data->cur_update);
+}
+#else
+static inline void dump_pxp_config(struct mxc_epdc_fb_data *fb_data,
+ struct pxp_config_data *pxp_conf) {}
+static inline void dump_epdc_reg(void) {}
+static inline void dump_update_data(struct device *dev,
+ struct update_data_list *upd_data_list) {}
+static inline void dump_collision_list(struct mxc_epdc_fb_data *fb_data) {}
+static inline void dump_free_list(struct mxc_epdc_fb_data *fb_data) {}
+static inline void dump_queue(struct mxc_epdc_fb_data *fb_data) {}
+static inline void dump_all_updates(struct mxc_epdc_fb_data *fb_data) {}
+
+#endif
+
+
+/********************************************************
+ * Start Low-Level EPDC Functions
+ ********************************************************/
+
+static inline void epdc_lut_complete_intr(int rev, u32 lut_num, bool enable)
+{
+ if (rev < 20) {
+ if (enable)
+ __raw_writel(1 << lut_num, EPDC_IRQ_MASK_SET);
+ else
+ __raw_writel(1 << lut_num, EPDC_IRQ_MASK_CLEAR);
+ } else {
+ if (enable) {
+ if (lut_num < 32)
+ __raw_writel(1 << lut_num, EPDC_IRQ_MASK1_SET);
+ else
+ __raw_writel(1 << (lut_num - 32),
+ EPDC_IRQ_MASK2_SET);
+ } else {
+ if (lut_num < 32)
+ __raw_writel(1 << lut_num,
+ EPDC_IRQ_MASK1_CLEAR);
+ else
+ __raw_writel(1 << (lut_num - 32),
+ EPDC_IRQ_MASK2_CLEAR);
+ }
+ }
+}
+
+static inline void epdc_working_buf_intr(bool enable)
+{
+ if (enable)
+ __raw_writel(EPDC_IRQ_WB_CMPLT_IRQ, EPDC_IRQ_MASK_SET);
+ else
+ __raw_writel(EPDC_IRQ_WB_CMPLT_IRQ, EPDC_IRQ_MASK_CLEAR);
+}
+
+static inline void epdc_clear_working_buf_irq(void)
+{
+ __raw_writel(EPDC_IRQ_WB_CMPLT_IRQ | EPDC_IRQ_LUT_COL_IRQ,
+ EPDC_IRQ_CLEAR);
+}
+
+static inline void epdc_eof_intr(bool enable)
+{
+ if (enable)
+ __raw_writel(EPDC_IRQ_FRAME_END_IRQ, EPDC_IRQ_MASK_SET);
+ else
+ __raw_writel(EPDC_IRQ_FRAME_END_IRQ, EPDC_IRQ_MASK_CLEAR);
+}
+
+static inline void epdc_clear_eof_irq(void)
+{
+ __raw_writel(EPDC_IRQ_FRAME_END_IRQ, EPDC_IRQ_CLEAR);
+}
+
+static inline bool epdc_signal_eof(void)
+{
+ return (__raw_readl(EPDC_IRQ_MASK) & __raw_readl(EPDC_IRQ)
+ & EPDC_IRQ_FRAME_END_IRQ) ? true : false;
+}
+
+static inline void epdc_set_temp(u32 temp)
+{
+ __raw_writel(temp, EPDC_TEMP);
+}
+
+static inline void epdc_set_screen_res(u32 width, u32 height)
+{
+ u32 val = (height << EPDC_RES_VERTICAL_OFFSET) | width;
+ __raw_writel(val, EPDC_RES);
+}
+
+static inline void epdc_set_update_addr(u32 addr)
+{
+ __raw_writel(addr, EPDC_UPD_ADDR);
+}
+
+static inline void epdc_set_update_coord(u32 x, u32 y)
+{
+ u32 val = (y << EPDC_UPD_CORD_YCORD_OFFSET) | x;
+ __raw_writel(val, EPDC_UPD_CORD);
+}
+
+static inline void epdc_set_update_dimensions(u32 width, u32 height)
+{
+ u32 val = (height << EPDC_UPD_SIZE_HEIGHT_OFFSET) | width;
+ __raw_writel(val, EPDC_UPD_SIZE);
+}
+
+static void epdc_set_update_waveform(struct mxcfb_waveform_modes *wv_modes)
+{
+ u32 val;
+
+ /* Configure the auto-waveform look-up table based on waveform modes */
+
+ /* Entry 1 = DU, 2 = GC4, 3 = GC8, etc. */
+ val = (wv_modes->mode_du << EPDC_AUTOWV_LUT_DATA_OFFSET) |
+ (0 << EPDC_AUTOWV_LUT_ADDR_OFFSET);
+ __raw_writel(val, EPDC_AUTOWV_LUT);
+ val = (wv_modes->mode_du << EPDC_AUTOWV_LUT_DATA_OFFSET) |
+ (1 << EPDC_AUTOWV_LUT_ADDR_OFFSET);
+ __raw_writel(val, EPDC_AUTOWV_LUT);
+ val = (wv_modes->mode_gc4 << EPDC_AUTOWV_LUT_DATA_OFFSET) |
+ (2 << EPDC_AUTOWV_LUT_ADDR_OFFSET);
+ __raw_writel(val, EPDC_AUTOWV_LUT);
+ val = (wv_modes->mode_gc8 << EPDC_AUTOWV_LUT_DATA_OFFSET) |
+ (3 << EPDC_AUTOWV_LUT_ADDR_OFFSET);
+ __raw_writel(val, EPDC_AUTOWV_LUT);
+ val = (wv_modes->mode_gc16 << EPDC_AUTOWV_LUT_DATA_OFFSET) |
+ (4 << EPDC_AUTOWV_LUT_ADDR_OFFSET);
+ __raw_writel(val, EPDC_AUTOWV_LUT);
+ val = (wv_modes->mode_gc32 << EPDC_AUTOWV_LUT_DATA_OFFSET) |
+ (5 << EPDC_AUTOWV_LUT_ADDR_OFFSET);
+ __raw_writel(val, EPDC_AUTOWV_LUT);
+}
+
+static void epdc_set_update_stride(u32 stride)
+{
+ __raw_writel(stride, EPDC_UPD_STRIDE);
+}
+
+static void epdc_submit_update(u32 lut_num, u32 waveform_mode, u32 update_mode,
+ bool use_dry_run, bool use_test_mode, u32 np_val)
+{
+ u32 reg_val = 0;
+
+ if (use_test_mode) {
+ reg_val |=
+ ((np_val << EPDC_UPD_FIXED_FIXNP_OFFSET) &
+ EPDC_UPD_FIXED_FIXNP_MASK) | EPDC_UPD_FIXED_FIXNP_EN;
+
+ __raw_writel(reg_val, EPDC_UPD_FIXED);
+
+ reg_val = EPDC_UPD_CTRL_USE_FIXED;
+ } else {
+ __raw_writel(reg_val, EPDC_UPD_FIXED);
+ }
+
+ if (waveform_mode == WAVEFORM_MODE_AUTO)
+ reg_val |= EPDC_UPD_CTRL_AUTOWV;
+ else
+ reg_val |= ((waveform_mode <<
+ EPDC_UPD_CTRL_WAVEFORM_MODE_OFFSET) &
+ EPDC_UPD_CTRL_WAVEFORM_MODE_MASK);
+
+ reg_val |= (use_dry_run ? EPDC_UPD_CTRL_DRY_RUN : 0) |
+ ((lut_num << EPDC_UPD_CTRL_LUT_SEL_OFFSET) &
+ EPDC_UPD_CTRL_LUT_SEL_MASK) |
+ update_mode;
+
+ __raw_writel(reg_val, EPDC_UPD_CTRL);
+}
+
+static inline bool epdc_is_lut_complete(int rev, u32 lut_num)
+{
+ u32 val;
+ bool is_compl;
+ if (rev < 20) {
+ val = __raw_readl(EPDC_IRQ);
+ is_compl = val & (1 << lut_num) ? true : false;
+ } else if (lut_num < 32) {
+ val = __raw_readl(EPDC_IRQ1);
+ is_compl = val & (1 << lut_num) ? true : false;
+ } else {
+ val = __raw_readl(EPDC_IRQ2);
+ is_compl = val & (1 << (lut_num - 32)) ? true : false;
+ }
+
+ return is_compl;
+}
+
+static inline void epdc_clear_lut_complete_irq(int rev, u32 lut_num)
+{
+ if (rev < 20)
+ __raw_writel(1 << lut_num, EPDC_IRQ_CLEAR);
+ else if (lut_num < 32)
+ __raw_writel(1 << lut_num, EPDC_IRQ1_CLEAR);
+ else
+ __raw_writel(1 << (lut_num - 32), EPDC_IRQ2_CLEAR);
+}
+
+static inline bool epdc_is_lut_active(u32 lut_num)
+{
+ u32 val;
+ bool is_active;
+
+ if (lut_num < 32) {
+ val = __raw_readl(EPDC_STATUS_LUTS);
+ is_active = val & (1 << lut_num) ? true : false;
+ } else {
+ val = __raw_readl(EPDC_STATUS_LUTS2);
+ is_active = val & (1 << (lut_num - 32)) ? true : false;
+ }
+
+ return is_active;
+}
+
+static inline bool epdc_any_luts_active(int rev)
+{
+ bool any_active;
+
+ if (rev < 20)
+ any_active = __raw_readl(EPDC_STATUS_LUTS) ? true : false;
+ else
+ any_active = (__raw_readl(EPDC_STATUS_LUTS) |
+ __raw_readl(EPDC_STATUS_LUTS2)) ? true : false;
+
+ return any_active;
+}
+
+static inline bool epdc_any_luts_available(void)
+{
+ bool luts_available =
+ (__raw_readl(EPDC_STATUS_NEXTLUT) &
+ EPDC_STATUS_NEXTLUT_NEXT_LUT_VALID) ? true : false;
+ return luts_available;
+}
+
+static inline int epdc_get_next_lut(void)
+{
+ u32 val =
+ __raw_readl(EPDC_STATUS_NEXTLUT) &
+ EPDC_STATUS_NEXTLUT_NEXT_LUT_MASK;
+ return val;
+}
+
+static int epdc_choose_next_lut(int rev, int *next_lut)
+{
+ u64 luts_status, unprocessed_luts, used_luts;
+ /* Available LUTs are reduced to 16 in 5-bit waveform mode */
+ bool format_p5n = ((__raw_readl(EPDC_FORMAT) &
+ EPDC_FORMAT_BUF_PIXEL_FORMAT_MASK) ==
+ EPDC_FORMAT_BUF_PIXEL_FORMAT_P5N);
+
+ luts_status = __raw_readl(EPDC_STATUS_LUTS);
+ if ((rev < 20) || format_p5n)
+ luts_status &= 0xFFFF;
+ else
+ luts_status |= ((u64)__raw_readl(EPDC_STATUS_LUTS2) << 32);
+
+ if (rev < 20) {
+ unprocessed_luts = __raw_readl(EPDC_IRQ) & 0xFFFF;
+ } else {
+ unprocessed_luts = __raw_readl(EPDC_IRQ1) |
+ ((u64)__raw_readl(EPDC_IRQ2) << 32);
+ if (format_p5n)
+ unprocessed_luts &= 0xFFFF;
+ }
+
+ /*
+ * Note on unprocessed_luts: There is a race condition
+ * where a LUT completes, but has not been processed by
+ * IRQ handler workqueue, and then a new update request
+ * attempts to use that LUT. We prevent that here by
+ * ensuring that the LUT we choose doesn't have its IRQ
+ * bit set (indicating it has completed but not yet been
+ * processed).
+ */
+ used_luts = luts_status | unprocessed_luts;
+
+ /*
+ * Selecting a LUT to minimize incidence of TCE Underrun Error
+ * --------------------------------------------------------
+ * We want to find the lowest order LUT that is of greater
+ * order than all other active LUTs. If highest order LUT
+ * is active, then we want to choose the lowest order
+ * available LUT.
+ *
+ * NOTE: For EPDC version 2.0 and later, TCE Underrun error
+ * bug is fixed, so it doesn't matter which LUT is used.
+ */
+
+ if ((rev < 20) || format_p5n) {
+ *next_lut = fls64(used_luts);
+ if (*next_lut > 15)
+ *next_lut = ffz(used_luts);
+ } else {
+ if ((u32)used_luts != ~0UL)
+ *next_lut = ffz((u32)used_luts);
+ else if ((u32)(used_luts >> 32) != ~0UL)
+ *next_lut = ffz((u32)(used_luts >> 32)) + 32;
+ else
+ *next_lut = INVALID_LUT;
+ }
+
+ if (used_luts & 0x8000)
+ return 1;
+ else
+ return 0;
+}
+
+static inline bool epdc_is_working_buffer_busy(void)
+{
+ u32 val = __raw_readl(EPDC_STATUS);
+ bool is_busy = (val & EPDC_STATUS_WB_BUSY) ? true : false;
+
+ return is_busy;
+}
+
+static inline bool epdc_is_working_buffer_complete(void)
+{
+ u32 val = __raw_readl(EPDC_IRQ);
+ bool is_compl = (val & EPDC_IRQ_WB_CMPLT_IRQ) ? true : false;
+
+ return is_compl;
+}
+
+static inline bool epdc_is_lut_cancelled(void)
+{
+ u32 val = __raw_readl(EPDC_STATUS);
+ bool is_void = (val & EPDC_STATUS_UPD_VOID) ? true : false;
+
+ return is_void;
+}
+
+static inline bool epdc_is_collision(void)
+{
+ u32 val = __raw_readl(EPDC_IRQ);
+ return (val & EPDC_IRQ_LUT_COL_IRQ) ? true : false;
+}
+
+static inline u64 epdc_get_colliding_luts(int rev)
+{
+ u32 val = __raw_readl(EPDC_STATUS_COL);
+ if (rev >= 20)
+ val |= (u64)__raw_readl(EPDC_STATUS_COL2) << 32;
+ return val;
+}
+
+static void epdc_set_horizontal_timing(u32 horiz_start, u32 horiz_end,
+ u32 hsync_width, u32 hsync_line_length)
+{
+ u32 reg_val =
+ ((hsync_width << EPDC_TCE_HSCAN1_LINE_SYNC_WIDTH_OFFSET) &
+ EPDC_TCE_HSCAN1_LINE_SYNC_WIDTH_MASK)
+ | ((hsync_line_length << EPDC_TCE_HSCAN1_LINE_SYNC_OFFSET) &
+ EPDC_TCE_HSCAN1_LINE_SYNC_MASK);
+ __raw_writel(reg_val, EPDC_TCE_HSCAN1);
+
+ reg_val =
+ ((horiz_start << EPDC_TCE_HSCAN2_LINE_BEGIN_OFFSET) &
+ EPDC_TCE_HSCAN2_LINE_BEGIN_MASK)
+ | ((horiz_end << EPDC_TCE_HSCAN2_LINE_END_OFFSET) &
+ EPDC_TCE_HSCAN2_LINE_END_MASK);
+ __raw_writel(reg_val, EPDC_TCE_HSCAN2);
+}
+
+static void epdc_set_vertical_timing(u32 vert_start, u32 vert_end,
+ u32 vsync_width)
+{
+ u32 reg_val =
+ ((vert_start << EPDC_TCE_VSCAN_FRAME_BEGIN_OFFSET) &
+ EPDC_TCE_VSCAN_FRAME_BEGIN_MASK)
+ | ((vert_end << EPDC_TCE_VSCAN_FRAME_END_OFFSET) &
+ EPDC_TCE_VSCAN_FRAME_END_MASK)
+ | ((vsync_width << EPDC_TCE_VSCAN_FRAME_SYNC_OFFSET) &
+ EPDC_TCE_VSCAN_FRAME_SYNC_MASK);
+ __raw_writel(reg_val, EPDC_TCE_VSCAN);
+}
+
+static void epdc_init_settings(struct mxc_epdc_fb_data *fb_data)
+{
+ struct imx_epdc_fb_mode *epdc_mode = fb_data->cur_mode;
+ struct fb_var_screeninfo *screeninfo = &fb_data->epdc_fb_var;
+ u32 reg_val;
+ int num_ce;
+ int i;
+
+ /* Enable clocks to access EPDC regs */
+ clk_prepare_enable(fb_data->epdc_clk_axi);
+ clk_prepare_enable(fb_data->epdc_clk_pix);
+
+ /* Reset */
+ __raw_writel(EPDC_CTRL_SFTRST, EPDC_CTRL_SET);
+ while (!(__raw_readl(EPDC_CTRL) & EPDC_CTRL_CLKGATE))
+ ;
+ __raw_writel(EPDC_CTRL_SFTRST, EPDC_CTRL_CLEAR);
+
+ /* Enable clock gating (clear to enable) */
+ __raw_writel(EPDC_CTRL_CLKGATE, EPDC_CTRL_CLEAR);
+ while (__raw_readl(EPDC_CTRL) & (EPDC_CTRL_SFTRST | EPDC_CTRL_CLKGATE))
+ ;
+
+ /* EPDC_CTRL */
+ reg_val = __raw_readl(EPDC_CTRL);
+ reg_val &= ~EPDC_CTRL_UPD_DATA_SWIZZLE_MASK;
+ reg_val |= EPDC_CTRL_UPD_DATA_SWIZZLE_NO_SWAP;
+ reg_val &= ~EPDC_CTRL_LUT_DATA_SWIZZLE_MASK;
+ reg_val |= EPDC_CTRL_LUT_DATA_SWIZZLE_NO_SWAP;
+ __raw_writel(reg_val, EPDC_CTRL_SET);
+
+ /* EPDC_FORMAT - 2bit TFT and 4bit Buf pixel format */
+ reg_val = EPDC_FORMAT_TFT_PIXEL_FORMAT_2BIT
+ | EPDC_FORMAT_BUF_PIXEL_FORMAT_P4N
+ | ((0x0 << EPDC_FORMAT_DEFAULT_TFT_PIXEL_OFFSET) &
+ EPDC_FORMAT_DEFAULT_TFT_PIXEL_MASK);
+ __raw_writel(reg_val, EPDC_FORMAT);
+
+ /* EPDC_FIFOCTRL (disabled) */
+ reg_val =
+ ((100 << EPDC_FIFOCTRL_FIFO_INIT_LEVEL_OFFSET) &
+ EPDC_FIFOCTRL_FIFO_INIT_LEVEL_MASK)
+ | ((200 << EPDC_FIFOCTRL_FIFO_H_LEVEL_OFFSET) &
+ EPDC_FIFOCTRL_FIFO_H_LEVEL_MASK)
+ | ((100 << EPDC_FIFOCTRL_FIFO_L_LEVEL_OFFSET) &
+ EPDC_FIFOCTRL_FIFO_L_LEVEL_MASK);
+ __raw_writel(reg_val, EPDC_FIFOCTRL);
+
+ /* EPDC_TEMP - Use default temp to get index */
+ epdc_set_temp(mxc_epdc_fb_get_temp_index(fb_data, DEFAULT_TEMP));
+
+ /* EPDC_RES */
+ epdc_set_screen_res(epdc_mode->vmode->xres, epdc_mode->vmode->yres);
+
+ /* EPDC_AUTOWV_LUT */
+ /* Initialize all auto-wavefrom look-up values to 2 - GC16 */
+ for (i = 0; i < 8; i++)
+ __raw_writel((2 << EPDC_AUTOWV_LUT_DATA_OFFSET) |
+ (i << EPDC_AUTOWV_LUT_ADDR_OFFSET), EPDC_AUTOWV_LUT);
+
+ /*
+ * EPDC_TCE_CTRL
+ * VSCAN_HOLDOFF = 4
+ * VCOM_MODE = MANUAL
+ * VCOM_VAL = 0
+ * DDR_MODE = DISABLED
+ * LVDS_MODE_CE = DISABLED
+ * LVDS_MODE = DISABLED
+ * DUAL_SCAN = DISABLED
+ * SDDO_WIDTH = 8bit
+ * PIXELS_PER_SDCLK = 4
+ */
+ reg_val =
+ ((epdc_mode->vscan_holdoff << EPDC_TCE_CTRL_VSCAN_HOLDOFF_OFFSET) &
+ EPDC_TCE_CTRL_VSCAN_HOLDOFF_MASK)
+ | EPDC_TCE_CTRL_PIXELS_PER_SDCLK_4;
+ __raw_writel(reg_val, EPDC_TCE_CTRL);
+
+ /* EPDC_TCE_HSCAN */
+ epdc_set_horizontal_timing(screeninfo->left_margin,
+ screeninfo->right_margin,
+ screeninfo->hsync_len,
+ screeninfo->hsync_len);
+
+ /* EPDC_TCE_VSCAN */
+ epdc_set_vertical_timing(screeninfo->upper_margin,
+ screeninfo->lower_margin,
+ screeninfo->vsync_len);
+
+ /* EPDC_TCE_OE */
+ reg_val =
+ ((epdc_mode->sdoed_width << EPDC_TCE_OE_SDOED_WIDTH_OFFSET) &
+ EPDC_TCE_OE_SDOED_WIDTH_MASK)
+ | ((epdc_mode->sdoed_delay << EPDC_TCE_OE_SDOED_DLY_OFFSET) &
+ EPDC_TCE_OE_SDOED_DLY_MASK)
+ | ((epdc_mode->sdoez_width << EPDC_TCE_OE_SDOEZ_WIDTH_OFFSET) &
+ EPDC_TCE_OE_SDOEZ_WIDTH_MASK)
+ | ((epdc_mode->sdoez_delay << EPDC_TCE_OE_SDOEZ_DLY_OFFSET) &
+ EPDC_TCE_OE_SDOEZ_DLY_MASK);
+ __raw_writel(reg_val, EPDC_TCE_OE);
+
+ /* EPDC_TCE_TIMING1 */
+ __raw_writel(0x0, EPDC_TCE_TIMING1);
+
+ /* EPDC_TCE_TIMING2 */
+ reg_val =
+ ((epdc_mode->gdclk_hp_offs << EPDC_TCE_TIMING2_GDCLK_HP_OFFSET) &
+ EPDC_TCE_TIMING2_GDCLK_HP_MASK)
+ | ((epdc_mode->gdsp_offs << EPDC_TCE_TIMING2_GDSP_OFFSET_OFFSET) &
+ EPDC_TCE_TIMING2_GDSP_OFFSET_MASK);
+ __raw_writel(reg_val, EPDC_TCE_TIMING2);
+
+ /* EPDC_TCE_TIMING3 */
+ reg_val =
+ ((epdc_mode->gdoe_offs << EPDC_TCE_TIMING3_GDOE_OFFSET_OFFSET) &
+ EPDC_TCE_TIMING3_GDOE_OFFSET_MASK)
+ | ((epdc_mode->gdclk_offs << EPDC_TCE_TIMING3_GDCLK_OFFSET_OFFSET) &
+ EPDC_TCE_TIMING3_GDCLK_OFFSET_MASK);
+ __raw_writel(reg_val, EPDC_TCE_TIMING3);
+
+ /*
+ * EPDC_TCE_SDCFG
+ * SDCLK_HOLD = 1
+ * SDSHR = 1
+ * NUM_CE = 1
+ * SDDO_REFORMAT = FLIP_PIXELS
+ * SDDO_INVERT = DISABLED
+ * PIXELS_PER_CE = display horizontal resolution
+ */
+ num_ce = epdc_mode->num_ce;
+ if (num_ce == 0)
+ num_ce = 1;
+ reg_val = EPDC_TCE_SDCFG_SDCLK_HOLD | EPDC_TCE_SDCFG_SDSHR
+ | ((num_ce << EPDC_TCE_SDCFG_NUM_CE_OFFSET) &
+ EPDC_TCE_SDCFG_NUM_CE_MASK)
+ | EPDC_TCE_SDCFG_SDDO_REFORMAT_FLIP_PIXELS
+ | ((epdc_mode->vmode->xres/num_ce << EPDC_TCE_SDCFG_PIXELS_PER_CE_OFFSET) &
+ EPDC_TCE_SDCFG_PIXELS_PER_CE_MASK);
+ __raw_writel(reg_val, EPDC_TCE_SDCFG);
+
+ /*
+ * EPDC_TCE_GDCFG
+ * GDRL = 1
+ * GDOE_MODE = 0;
+ * GDSP_MODE = 0;
+ */
+ reg_val = EPDC_TCE_SDCFG_GDRL;
+ __raw_writel(reg_val, EPDC_TCE_GDCFG);
+
+ /*
+ * EPDC_TCE_POLARITY
+ * SDCE_POL = ACTIVE LOW
+ * SDLE_POL = ACTIVE HIGH
+ * SDOE_POL = ACTIVE HIGH
+ * GDOE_POL = ACTIVE HIGH
+ * GDSP_POL = ACTIVE LOW
+ */
+ reg_val = EPDC_TCE_POLARITY_SDLE_POL_ACTIVE_HIGH
+ | EPDC_TCE_POLARITY_SDOE_POL_ACTIVE_HIGH
+ | EPDC_TCE_POLARITY_GDOE_POL_ACTIVE_HIGH;
+ __raw_writel(reg_val, EPDC_TCE_POLARITY);
+
+ /* EPDC_IRQ_MASK */
+ __raw_writel(EPDC_IRQ_TCE_UNDERRUN_IRQ, EPDC_IRQ_MASK);
+
+ /*
+ * EPDC_GPIO
+ * PWRCOM = ?
+ * PWRCTRL = ?
+ * BDR = ?
+ */
+ reg_val = ((0 << EPDC_GPIO_PWRCTRL_OFFSET) & EPDC_GPIO_PWRCTRL_MASK)
+ | ((0 << EPDC_GPIO_BDR_OFFSET) & EPDC_GPIO_BDR_MASK);
+ __raw_writel(reg_val, EPDC_GPIO);
+
+ __raw_writel(fb_data->waveform_buffer_phys, EPDC_WVADDR);
+ __raw_writel(fb_data->working_buffer_phys, EPDC_WB_ADDR);
+ __raw_writel(fb_data->working_buffer_phys, EPDC_WB_ADDR_TCE);
+
+ /* Disable clock */
+ clk_disable_unprepare(fb_data->epdc_clk_axi);
+ clk_disable_unprepare(fb_data->epdc_clk_pix);
+}
+
+static void epdc_powerup(struct mxc_epdc_fb_data *fb_data)
+{
+ int ret = 0;
+ mutex_lock(&fb_data->power_mutex);
+
+ /*
+ * If power down request is pending, clear
+ * powering_down to cancel the request.
+ */
+ if (fb_data->powering_down)
+ fb_data->powering_down = false;
+
+ if (fb_data->power_state == POWER_STATE_ON) {
+ mutex_unlock(&fb_data->power_mutex);
+ return;
+ }
+
+ dev_dbg(fb_data->dev, "EPDC Powerup\n");
+
+ fb_data->updates_active = true;
+
+ /* Enable the v3p3 regulator */
+ ret = regulator_enable(fb_data->v3p3_regulator);
+ if (IS_ERR((void *)ret)) {
+ dev_err(fb_data->dev, "Unable to enable V3P3 regulator."
+ "err = 0x%x\n", ret);
+ mutex_unlock(&fb_data->power_mutex);
+ return;
+ }
+
+ msleep(1);
+
+ pm_runtime_get_sync(fb_data->dev);
+
+ /* Enable clocks to EPDC */
+ clk_prepare_enable(fb_data->epdc_clk_axi);
+ clk_prepare_enable(fb_data->epdc_clk_pix);
+
+ __raw_writel(EPDC_CTRL_CLKGATE, EPDC_CTRL_CLEAR);
+
+ /* Enable power to the EPD panel */
+ ret = regulator_enable(fb_data->display_regulator);
+ if (IS_ERR((void *)ret)) {
+ dev_err(fb_data->dev, "Unable to enable DISPLAY regulator."
+ "err = 0x%x\n", ret);
+ mutex_unlock(&fb_data->power_mutex);
+ return;
+ }
+ ret = regulator_enable(fb_data->vcom_regulator);
+ if (IS_ERR((void *)ret)) {
+ dev_err(fb_data->dev, "Unable to enable VCOM regulator."
+ "err = 0x%x\n", ret);
+ mutex_unlock(&fb_data->power_mutex);
+ return;
+ }
+
+ fb_data->power_state = POWER_STATE_ON;
+
+ mutex_unlock(&fb_data->power_mutex);
+}
+
+static void epdc_powerdown(struct mxc_epdc_fb_data *fb_data)
+{
+ mutex_lock(&fb_data->power_mutex);
+
+ /* If powering_down has been cleared, a powerup
+ * request is pre-empting this powerdown request.
+ */
+ if (!fb_data->powering_down
+ || (fb_data->power_state == POWER_STATE_OFF)) {
+ mutex_unlock(&fb_data->power_mutex);
+ return;
+ }
+
+ dev_dbg(fb_data->dev, "EPDC Powerdown\n");
+
+ /* Disable power to the EPD panel */
+ regulator_disable(fb_data->vcom_regulator);
+ regulator_disable(fb_data->display_regulator);
+
+ /* Disable clocks to EPDC */
+ __raw_writel(EPDC_CTRL_CLKGATE, EPDC_CTRL_SET);
+ clk_disable_unprepare(fb_data->epdc_clk_pix);
+ clk_disable_unprepare(fb_data->epdc_clk_axi);
+
+ pm_runtime_put_sync_suspend(fb_data->dev);
+
+ /* turn off the V3p3 */
+ regulator_disable(fb_data->v3p3_regulator);
+
+ fb_data->power_state = POWER_STATE_OFF;
+ fb_data->powering_down = false;
+
+ if (fb_data->wait_for_powerdown) {
+ fb_data->wait_for_powerdown = false;
+ complete(&fb_data->powerdown_compl);
+ }
+
+ mutex_unlock(&fb_data->power_mutex);
+}
+
+static void epdc_init_sequence(struct mxc_epdc_fb_data *fb_data)
+{
+ /* Initialize EPDC, passing pointer to EPDC registers */
+ epdc_init_settings(fb_data);
+ fb_data->in_init = true;
+ epdc_powerup(fb_data);
+ draw_mode0(fb_data);
+ /* Force power down event */
+ fb_data->powering_down = true;
+ epdc_powerdown(fb_data);
+ fb_data->updates_active = false;
+}
+
+static int mxc_epdc_fb_mmap(struct fb_info *info, struct vm_area_struct *vma)
+{
+ u32 len;
+ unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
+
+ if (offset < info->fix.smem_len) {
+ /* mapping framebuffer memory */
+ len = info->fix.smem_len - offset;
+ vma->vm_pgoff = (info->fix.smem_start + offset) >> PAGE_SHIFT;
+ } else
+ return -EINVAL;
+
+ len = PAGE_ALIGN(len);
+ if (vma->vm_end - vma->vm_start > len)
+ return -EINVAL;
+
+ /* make buffers bufferable */
+ vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
+
+ if (remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
+ vma->vm_end - vma->vm_start, vma->vm_page_prot)) {
+ dev_dbg(info->device, "mmap remap_pfn_range failed\n");
+ return -ENOBUFS;
+ }
+
+ return 0;
+}
+
+static inline u_int _chan_to_field(u_int chan, struct fb_bitfield *bf)
+{
+ chan &= 0xffff;
+ chan >>= 16 - bf->length;
+ return chan << bf->offset;
+}
+
+static int mxc_epdc_fb_setcolreg(u_int regno, u_int red, u_int green,
+ u_int blue, u_int transp, struct fb_info *info)
+{
+ unsigned int val;
+ int ret = 1;
+
+ /*
+ * If greyscale is true, then we convert the RGB value
+ * to greyscale no matter what visual we are using.
+ */
+ if (info->var.grayscale)
+ red = green = blue = (19595 * red + 38470 * green +
+ 7471 * blue) >> 16;
+ switch (info->fix.visual) {
+ case FB_VISUAL_TRUECOLOR:
+ /*
+ * 16-bit True Colour. We encode the RGB value
+ * according to the RGB bitfield information.
+ */
+ if (regno < 16) {
+ u32 *pal = info->pseudo_palette;
+
+ val = _chan_to_field(red, &info->var.red);
+ val |= _chan_to_field(green, &info->var.green);
+ val |= _chan_to_field(blue, &info->var.blue);
+
+ pal[regno] = val;
+ ret = 0;
+ }
+ break;
+
+ case FB_VISUAL_STATIC_PSEUDOCOLOR:
+ case FB_VISUAL_PSEUDOCOLOR:
+ break;
+ }
+
+ return ret;
+}
+
+static int mxc_epdc_fb_setcmap(struct fb_cmap *cmap, struct fb_info *info)
+{
+ int count, index, r;
+ u16 *red, *green, *blue, *transp;
+ u16 trans = 0xffff;
+ struct mxc_epdc_fb_data *fb_data = (struct mxc_epdc_fb_data *)info;
+ int i;
+
+ dev_dbg(fb_data->dev, "setcmap\n");
+
+ if (info->fix.visual == FB_VISUAL_STATIC_PSEUDOCOLOR) {
+ /* Only support an 8-bit, 256 entry lookup */
+ if (cmap->len != 256)
+ return 1;
+
+ mxc_epdc_fb_flush_updates(fb_data);
+
+ mutex_lock(&fb_data->pxp_mutex);
+ /*
+ * Store colormap in pxp_conf structure for later transmit
+ * to PxP during update process to convert gray pixels.
+ *
+ * Since red=blue=green for pseudocolor visuals, we can
+ * just use red values.
+ */
+ for (i = 0; i < 256; i++)
+ fb_data->pxp_conf.proc_data.lut_map[i] = cmap->red[i] & 0xFF;
+
+ fb_data->pxp_conf.proc_data.lut_map_updated = true;
+
+ mutex_unlock(&fb_data->pxp_mutex);
+ } else {
+ red = cmap->red;
+ green = cmap->green;
+ blue = cmap->blue;
+ transp = cmap->transp;
+ index = cmap->start;
+
+ for (count = 0; count < cmap->len; count++) {
+ if (transp)
+ trans = *transp++;
+ r = mxc_epdc_fb_setcolreg(index++, *red++, *green++, *blue++,
+ trans, info);
+ if (r != 0)
+ return r;
+ }
+ }
+
+ return 0;
+}
+
+static void adjust_coordinates(u32 xres, u32 yres, u32 rotation,
+ struct mxcfb_rect *update_region, struct mxcfb_rect *adj_update_region)
+{
+ u32 temp;
+
+ /* If adj_update_region == NULL, pass result back in update_region */
+ /* If adj_update_region == valid, use it to pass back result */
+ if (adj_update_region)
+ switch (rotation) {
+ case FB_ROTATE_UR:
+ adj_update_region->top = update_region->top;
+ adj_update_region->left = update_region->left;
+ adj_update_region->width = update_region->width;
+ adj_update_region->height = update_region->height;
+ break;
+ case FB_ROTATE_CW:
+ adj_update_region->top = update_region->left;
+ adj_update_region->left = yres -
+ (update_region->top + update_region->height);
+ adj_update_region->width = update_region->height;
+ adj_update_region->height = update_region->width;
+ break;
+ case FB_ROTATE_UD:
+ adj_update_region->width = update_region->width;
+ adj_update_region->height = update_region->height;
+ adj_update_region->top = yres -
+ (update_region->top + update_region->height);
+ adj_update_region->left = xres -
+ (update_region->left + update_region->width);
+ break;
+ case FB_ROTATE_CCW:
+ adj_update_region->left = update_region->top;
+ adj_update_region->top = xres -
+ (update_region->left + update_region->width);
+ adj_update_region->width = update_region->height;
+ adj_update_region->height = update_region->width;
+ break;
+ }
+ else
+ switch (rotation) {
+ case FB_ROTATE_UR:
+ /* No adjustment needed */
+ break;
+ case FB_ROTATE_CW:
+ temp = update_region->top;
+ update_region->top = update_region->left;
+ update_region->left = yres -
+ (temp + update_region->height);
+ temp = update_region->width;
+ update_region->width = update_region->height;
+ update_region->height = temp;
+ break;
+ case FB_ROTATE_UD:
+ update_region->top = yres -
+ (update_region->top + update_region->height);
+ update_region->left = xres -
+ (update_region->left + update_region->width);
+ break;
+ case FB_ROTATE_CCW:
+ temp = update_region->left;
+ update_region->left = update_region->top;
+ update_region->top = xres -
+ (temp + update_region->width);
+ temp = update_region->width;
+ update_region->width = update_region->height;
+ update_region->height = temp;
+ break;
+ }
+}
+
+/*
+ * Set fixed framebuffer parameters based on variable settings.
+ *
+ * @param info framebuffer information pointer
+ */
+static int mxc_epdc_fb_set_fix(struct fb_info *info)
+{
+ struct fb_fix_screeninfo *fix = &info->fix;
+ struct fb_var_screeninfo *var = &info->var;
+
+ fix->line_length = var->xres_virtual * var->bits_per_pixel / 8;
+
+ fix->type = FB_TYPE_PACKED_PIXELS;
+ fix->accel = FB_ACCEL_NONE;
+ if (var->grayscale)
+ fix->visual = FB_VISUAL_STATIC_PSEUDOCOLOR;
+ else
+ fix->visual = FB_VISUAL_TRUECOLOR;
+ fix->xpanstep = 1;
+ fix->ypanstep = 1;
+
+ return 0;
+}
+
+/*
+ * This routine actually sets the video mode. It's in here where we
+ * the hardware state info->par and fix which can be affected by the
+ * change in par. For this driver it doesn't do much.
+ *
+ */
+static int mxc_epdc_fb_set_par(struct fb_info *info)
+{
+ struct mxc_epdc_fb_data *fb_data = (struct mxc_epdc_fb_data *)info;
+ struct pxp_config_data *pxp_conf = &fb_data->pxp_conf;
+ struct pxp_proc_data *proc_data = &pxp_conf->proc_data;
+ struct fb_var_screeninfo *screeninfo = &fb_data->info.var;
+ struct imx_epdc_fb_mode *epdc_modes = fb_data->pdata->epdc_mode;
+ int i;
+ int ret;
+ __u32 xoffset_old, yoffset_old;
+
+ /*
+ * Can't change the FB parameters until current updates have completed.
+ * This function returns when all active updates are done.
+ */
+ mxc_epdc_fb_flush_updates(fb_data);
+
+ mutex_lock(&fb_data->queue_mutex);
+ /*
+ * Set all screeninfo except for xoffset/yoffset
+ * Subsequent call to pan_display will handle those.
+ */
+ xoffset_old = fb_data->epdc_fb_var.xoffset;
+ yoffset_old = fb_data->epdc_fb_var.yoffset;
+ fb_data->epdc_fb_var = *screeninfo;
+ fb_data->epdc_fb_var.xoffset = xoffset_old;
+ fb_data->epdc_fb_var.yoffset = yoffset_old;
+ mutex_unlock(&fb_data->queue_mutex);
+
+ mutex_lock(&fb_data->pxp_mutex);
+
+ /*
+ * Update PxP config data (used to process FB regions for updates)
+ * based on FB info and processing tasks required
+ */
+
+ /* Initialize non-channel-specific PxP parameters */
+ proc_data->drect.left = proc_data->srect.left = 0;
+ proc_data->drect.top = proc_data->srect.top = 0;
+ proc_data->drect.width = proc_data->srect.width = screeninfo->xres;
+ proc_data->drect.height = proc_data->srect.height = screeninfo->yres;
+ proc_data->scaling = 0;
+ proc_data->hflip = 0;
+ proc_data->vflip = 0;
+ proc_data->rotate = screeninfo->rotate;
+ proc_data->bgcolor = 0;
+ proc_data->overlay_state = 0;
+ proc_data->lut_transform = PXP_LUT_NONE;
+
+ /*
+ * configure S0 channel parameters
+ * Parameters should match FB format/width/height
+ */
+ if (screeninfo->grayscale)
+ pxp_conf->s0_param.pixel_fmt = PXP_PIX_FMT_GREY;
+ else {
+ switch (screeninfo->bits_per_pixel) {
+ case 16:
+ pxp_conf->s0_param.pixel_fmt = PXP_PIX_FMT_RGB565;
+ break;
+ case 24:
+ pxp_conf->s0_param.pixel_fmt = PXP_PIX_FMT_RGB24;
+ break;
+ case 32:
+ pxp_conf->s0_param.pixel_fmt = PXP_PIX_FMT_XRGB32;
+ break;
+ default:
+ pxp_conf->s0_param.pixel_fmt = PXP_PIX_FMT_RGB565;
+ break;
+ }
+ }
+ pxp_conf->s0_param.width = screeninfo->xres_virtual;
+ pxp_conf->s0_param.height = screeninfo->yres;
+ pxp_conf->s0_param.color_key = -1;
+ pxp_conf->s0_param.color_key_enable = false;
+
+ /*
+ * Initialize Output channel parameters
+ * Output is Y-only greyscale
+ * Output width/height will vary based on update region size
+ */
+ pxp_conf->out_param.width = screeninfo->xres;
+ pxp_conf->out_param.height = screeninfo->yres;
+ pxp_conf->out_param.pixel_fmt = PXP_PIX_FMT_GREY;
+
+ mutex_unlock(&fb_data->pxp_mutex);
+
+ /*
+ * If HW not yet initialized, check to see if we are being sent
+ * an initialization request.
+ */
+ if (!fb_data->hw_ready) {
+ struct fb_videomode mode;
+ u32 xres_temp;
+
+ fb_var_to_videomode(&mode, screeninfo);
+
+ /* When comparing requested fb mode,
+ we need to use unrotated dimensions */
+ if ((screeninfo->rotate == FB_ROTATE_CW) ||
+ (screeninfo->rotate == FB_ROTATE_CCW)) {
+ xres_temp = mode.xres;
+ mode.xres = mode.yres;
+ mode.yres = xres_temp;
+ }
+
+ /*
+ * If requested video mode does not match current video
+ * mode, search for a matching panel.
+ */
+ if (fb_data->cur_mode &&
+ !fb_mode_is_equal(fb_data->cur_mode->vmode,
+ &mode)) {
+ bool found_match = false;
+
+ /* Match videomode against epdc modes */
+ for (i = 0; i < fb_data->pdata->num_modes; i++) {
+ if (!fb_mode_is_equal(epdc_modes[i].vmode,
+ &mode))
+ continue;
+ fb_data->cur_mode = &epdc_modes[i];
+ found_match = true;
+ break;
+ }
+
+ if (!found_match) {
+ dev_err(fb_data->dev,
+ "Failed to match requested "
+ "video mode\n");
+ return EINVAL;
+ }
+ }
+
+ /* Found a match - Grab timing params */
+ screeninfo->left_margin = mode.left_margin;
+ screeninfo->right_margin = mode.right_margin;
+ screeninfo->upper_margin = mode.upper_margin;
+ screeninfo->lower_margin = mode.lower_margin;
+ screeninfo->hsync_len = mode.hsync_len;
+ screeninfo->vsync_len = mode.vsync_len;
+
+ fb_data->hw_initializing = true;
+
+ /* Initialize EPDC settings and init panel */
+ ret =
+ mxc_epdc_fb_init_hw((struct fb_info *)fb_data);
+ if (ret) {
+ dev_err(fb_data->dev,
+ "Failed to load panel waveform data\n");
+ return ret;
+ }
+ }
+
+ /*
+ * EOF sync delay (in us) should be equal to the vscan holdoff time
+ * VSCAN_HOLDOFF time = (VSCAN_HOLDOFF value + 1) * Vertical lines
+ * Add 25us for additional margin
+ */
+ fb_data->eof_sync_period = (fb_data->cur_mode->vscan_holdoff + 1) *
+ 1000000/(fb_data->cur_mode->vmode->refresh *
+ (fb_data->cur_mode->vmode->upper_margin +
+ fb_data->cur_mode->vmode->yres +
+ fb_data->cur_mode->vmode->lower_margin +
+ fb_data->cur_mode->vmode->vsync_len)) + 25;
+
+ mxc_epdc_fb_set_fix(info);
+
+ return 0;
+}
+
+static int mxc_epdc_fb_check_var(struct fb_var_screeninfo *var,
+ struct fb_info *info)
+{
+ struct mxc_epdc_fb_data *fb_data = (struct mxc_epdc_fb_data *)info;
+
+ if (!var->xres)
+ var->xres = 1;
+ if (!var->yres)
+ var->yres = 1;
+
+ if (var->xres_virtual < var->xoffset + var->xres)
+ var->xres_virtual = var->xoffset + var->xres;
+ if (var->yres_virtual < var->yoffset + var->yres)
+ var->yres_virtual = var->yoffset + var->yres;
+
+ if ((var->bits_per_pixel != 32) && (var->bits_per_pixel != 24) &&
+ (var->bits_per_pixel != 16) && (var->bits_per_pixel != 8))
+ var->bits_per_pixel = default_bpp;
+
+ switch (var->bits_per_pixel) {
+ case 8:
+ if (var->grayscale != 0) {
+ /*
+ * For 8-bit grayscale, R, G, and B offset are equal.
+ *
+ */
+ var->red.length = 8;
+ var->red.offset = 0;
+ var->red.msb_right = 0;
+
+ var->green.length = 8;
+ var->green.offset = 0;
+ var->green.msb_right = 0;
+
+ var->blue.length = 8;
+ var->blue.offset = 0;
+ var->blue.msb_right = 0;
+
+ var->transp.length = 0;
+ var->transp.offset = 0;
+ var->transp.msb_right = 0;
+ } else {
+ var->red.length = 3;
+ var->red.offset = 5;
+ var->red.msb_right = 0;
+
+ var->green.length = 3;
+ var->green.offset = 2;
+ var->green.msb_right = 0;
+
+ var->blue.length = 2;
+ var->blue.offset = 0;
+ var->blue.msb_right = 0;
+
+ var->transp.length = 0;
+ var->transp.offset = 0;
+ var->transp.msb_right = 0;
+ }
+ break;
+ case 16:
+ var->red.length = 5;
+ var->red.offset = 11;
+ var->red.msb_right = 0;
+
+ var->green.length = 6;
+ var->green.offset = 5;
+ var->green.msb_right = 0;
+
+ var->blue.length = 5;
+ var->blue.offset = 0;
+ var->blue.msb_right = 0;
+
+ var->transp.length = 0;
+ var->transp.offset = 0;
+ var->transp.msb_right = 0;
+ break;
+ case 24:
+ var->red.length = 8;
+ var->red.offset = 16;
+ var->red.msb_right = 0;
+
+ var->green.length = 8;
+ var->green.offset = 8;
+ var->green.msb_right = 0;
+
+ var->blue.length = 8;
+ var->blue.offset = 0;
+ var->blue.msb_right = 0;
+
+ var->transp.length = 0;
+ var->transp.offset = 0;
+ var->transp.msb_right = 0;
+ break;
+ case 32:
+ var->red.length = 8;
+ var->red.offset = 16;
+ var->red.msb_right = 0;
+
+ var->green.length = 8;
+ var->green.offset = 8;
+ var->green.msb_right = 0;
+
+ var->blue.length = 8;
+ var->blue.offset = 0;
+ var->blue.msb_right = 0;
+
+ var->transp.length = 8;
+ var->transp.offset = 24;
+ var->transp.msb_right = 0;
+ break;
+ }
+
+ switch (var->rotate) {
+ case FB_ROTATE_UR:
+ case FB_ROTATE_UD:
+ var->xres = fb_data->native_width;
+ var->yres = fb_data->native_height;
+ break;
+ case FB_ROTATE_CW:
+ case FB_ROTATE_CCW:
+ var->xres = fb_data->native_height;
+ var->yres = fb_data->native_width;
+ break;
+ default:
+ /* Invalid rotation value */
+ var->rotate = 0;
+ dev_dbg(fb_data->dev, "Invalid rotation request\n");
+ return -EINVAL;
+ }
+
+ var->xres_virtual = ALIGN(var->xres, 32);
+ var->yres_virtual = ALIGN(var->yres, 128) * fb_data->num_screens;
+
+ var->height = -1;
+ var->width = -1;
+
+ return 0;
+}
+
+void mxc_epdc_fb_set_waveform_modes(struct mxcfb_waveform_modes *modes,
+ struct fb_info *info)
+{
+ struct mxc_epdc_fb_data *fb_data = info ?
+ (struct mxc_epdc_fb_data *)info:g_fb_data;
+
+ mutex_lock(&fb_data->queue_mutex);
+
+ memcpy(&fb_data->wv_modes, modes, sizeof(struct mxcfb_waveform_modes));
+
+ /* Set flag to ensure that new waveform modes
+ * are programmed into EPDC before next update */
+ fb_data->wv_modes_update = true;
+
+ mutex_unlock(&fb_data->queue_mutex);
+}
+EXPORT_SYMBOL(mxc_epdc_fb_set_waveform_modes);
+
+static int mxc_epdc_fb_get_temp_index(struct mxc_epdc_fb_data *fb_data, int temp)
+{
+ int i;
+ int index = -1;
+
+ if (fb_data->trt_entries == 0) {
+ dev_err(fb_data->dev,
+ "No TRT exists...using default temp index\n");
+ return DEFAULT_TEMP_INDEX;
+ }
+
+ /* Search temperature ranges for a match */
+ for (i = 0; i < fb_data->trt_entries - 1; i++) {
+ if ((temp >= fb_data->temp_range_bounds[i])
+ && (temp < fb_data->temp_range_bounds[i+1])) {
+ index = i;
+ break;
+ }
+ }
+
+ if (index < 0) {
+ dev_err(fb_data->dev,
+ "No TRT index match...using default temp index\n");
+ return DEFAULT_TEMP_INDEX;
+ }
+
+ dev_dbg(fb_data->dev, "Using temperature index %d\n", index);
+
+ return index;
+}
+
+int mxc_epdc_fb_set_temperature(int temperature, struct fb_info *info)
+{
+ struct mxc_epdc_fb_data *fb_data = info ?
+ (struct mxc_epdc_fb_data *)info:g_fb_data;
+
+ /* Store temp index. Used later when configuring updates. */
+ mutex_lock(&fb_data->queue_mutex);
+ fb_data->temp_index = mxc_epdc_fb_get_temp_index(fb_data, temperature);
+ mutex_unlock(&fb_data->queue_mutex);
+
+ return 0;
+}
+EXPORT_SYMBOL(mxc_epdc_fb_set_temperature);
+
+int mxc_epdc_fb_set_auto_update(u32 auto_mode, struct fb_info *info)
+{
+ struct mxc_epdc_fb_data *fb_data = info ?
+ (struct mxc_epdc_fb_data *)info:g_fb_data;
+
+ dev_dbg(fb_data->dev, "Setting auto update mode to %d\n", auto_mode);
+
+ if ((auto_mode == AUTO_UPDATE_MODE_AUTOMATIC_MODE)
+ || (auto_mode == AUTO_UPDATE_MODE_REGION_MODE))
+ fb_data->auto_mode = auto_mode;
+ else {
+ dev_err(fb_data->dev, "Invalid auto update mode parameter.\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL(mxc_epdc_fb_set_auto_update);
+
+int mxc_epdc_fb_set_upd_scheme(u32 upd_scheme, struct fb_info *info)
+{
+ struct mxc_epdc_fb_data *fb_data = info ?
+ (struct mxc_epdc_fb_data *)info:g_fb_data;
+
+ dev_dbg(fb_data->dev, "Setting optimization level to %d\n", upd_scheme);
+
+ /*
+ * Can't change the scheme until current updates have completed.
+ * This function returns when all active updates are done.
+ */
+ mxc_epdc_fb_flush_updates(fb_data);
+
+ if ((upd_scheme == UPDATE_SCHEME_SNAPSHOT)
+ || (upd_scheme == UPDATE_SCHEME_QUEUE)
+ || (upd_scheme == UPDATE_SCHEME_QUEUE_AND_MERGE))
+ fb_data->upd_scheme = upd_scheme;
+ else {
+ dev_err(fb_data->dev, "Invalid update scheme specified.\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL(mxc_epdc_fb_set_upd_scheme);
+
+static void copy_before_process(struct mxc_epdc_fb_data *fb_data,
+ struct update_data_list *upd_data_list)
+{
+ struct mxcfb_update_data *upd_data =
+ &upd_data_list->update_desc->upd_data;
+ int i;
+ unsigned char *temp_buf_ptr = fb_data->virt_addr_copybuf;
+ unsigned char *src_ptr;
+ struct mxcfb_rect *src_upd_region;
+ int temp_buf_stride;
+ int src_stride;
+ int bpp = fb_data->epdc_fb_var.bits_per_pixel;
+ int left_offs, right_offs;
+ int x_trailing_bytes, y_trailing_bytes;
+ int alt_buf_offset;
+
+ /* Set source buf pointer based on input source, panning, etc. */
+ if (upd_data->flags & EPDC_FLAG_USE_ALT_BUFFER) {
+ src_upd_region = &upd_data->alt_buffer_data.alt_update_region;
+ src_stride =
+ upd_data->alt_buffer_data.width * bpp/8;
+ alt_buf_offset = upd_data->alt_buffer_data.phys_addr -
+ fb_data->info.fix.smem_start;
+ src_ptr = fb_data->info.screen_base + alt_buf_offset
+ + src_upd_region->top * src_stride;
+ } else {
+ src_upd_region = &upd_data->update_region;
+ src_stride = fb_data->epdc_fb_var.xres_virtual * bpp/8;
+ src_ptr = fb_data->info.screen_base + fb_data->fb_offset
+ + src_upd_region->top * src_stride;
+ }
+
+ temp_buf_stride = ALIGN(src_upd_region->width, 8) * bpp/8;
+ left_offs = src_upd_region->left * bpp/8;
+ right_offs = src_upd_region->width * bpp/8;
+ x_trailing_bytes = (ALIGN(src_upd_region->width, 8)
+ - src_upd_region->width) * bpp/8;
+
+ for (i = 0; i < src_upd_region->height; i++) {
+ /* Copy the full line */
+ memcpy(temp_buf_ptr, src_ptr + left_offs,
+ src_upd_region->width * bpp/8);
+
+ /* Clear any unwanted pixels at the end of each line */
+ if (src_upd_region->width & 0x7) {
+ memset(temp_buf_ptr + right_offs, 0x0,
+ x_trailing_bytes);
+ }
+
+ temp_buf_ptr += temp_buf_stride;
+ src_ptr += src_stride;
+ }
+
+ /* Clear any unwanted pixels at the bottom of the end of each line */
+ if (src_upd_region->height & 0x7) {
+ y_trailing_bytes = (ALIGN(src_upd_region->height, 8)
+ - src_upd_region->height) *
+ ALIGN(src_upd_region->width, 8) * bpp/8;
+ memset(temp_buf_ptr, 0x0, y_trailing_bytes);
+ }
+}
+
+static int epdc_process_update(struct update_data_list *upd_data_list,
+ struct mxc_epdc_fb_data *fb_data)
+{
+ struct mxcfb_rect *src_upd_region; /* Region of src buffer for update */
+ struct mxcfb_rect pxp_upd_region;
+ u32 src_width, src_height;
+ u32 offset_from_4, bytes_per_pixel;
+ u32 post_rotation_xcoord, post_rotation_ycoord, width_pxp_blocks;
+ u32 pxp_input_offs, pxp_output_offs, pxp_output_shift;
+ u32 hist_stat = 0;
+ int width_unaligned, height_unaligned;
+ bool input_unaligned = false;
+ bool line_overflow = false;
+ int pix_per_line_added;
+ bool use_temp_buf = false;
+ struct mxcfb_rect temp_buf_upd_region;
+ struct update_desc_list *upd_desc_list = upd_data_list->update_desc;
+
+ int ret;
+
+ /*
+ * Gotta do a whole bunch of buffer ptr manipulation to
+ * work around HW restrictions for PxP & EPDC
+ * Note: Applies to pre-2.0 versions of EPDC/PxP
+ */
+
+ /*
+ * Are we using FB or an alternate (overlay)
+ * buffer for source of update?
+ */
+ if (upd_desc_list->upd_data.flags & EPDC_FLAG_USE_ALT_BUFFER) {
+ src_width = upd_desc_list->upd_data.alt_buffer_data.width;
+ src_height = upd_desc_list->upd_data.alt_buffer_data.height;
+ src_upd_region = &upd_desc_list->upd_data.alt_buffer_data.alt_update_region;
+ } else {
+ src_width = fb_data->epdc_fb_var.xres_virtual;
+ src_height = fb_data->epdc_fb_var.yres;
+ src_upd_region = &upd_desc_list->upd_data.update_region;
+ }
+
+ bytes_per_pixel = fb_data->epdc_fb_var.bits_per_pixel/8;
+
+ /*
+ * SW workaround for PxP limitation (for pre-v2.0 HW)
+ *
+ * There are 3 cases where we cannot process the update data
+ * directly from the input buffer:
+ *
+ * 1) PxP must process 8x8 pixel blocks, and all pixels in each block
+ * are considered for auto-waveform mode selection. If the
+ * update region is not 8x8 aligned, additional unwanted pixels
+ * will be considered in auto-waveform mode selection.
+ *
+ * 2) PxP input must be 32-bit aligned, so any update
+ * address not 32-bit aligned must be shifted to meet the
+ * 32-bit alignment. The PxP will thus end up processing pixels
+ * outside of the update region to satisfy this alignment restriction,
+ * which can affect auto-waveform mode selection.
+ *
+ * 3) If input fails 32-bit alignment, and the resulting expansion
+ * of the processed region would add at least 8 pixels more per
+ * line than the original update line width, the EPDC would
+ * cause screen artifacts by incorrectly handling the 8+ pixels
+ * at the end of each line.
+ *
+ * Workaround is to copy from source buffer into a temporary
+ * buffer, which we pad with zeros to match the 8x8 alignment
+ * requirement. This temp buffer becomes the input to the PxP.
+ */
+ width_unaligned = src_upd_region->width & 0x7;
+ height_unaligned = src_upd_region->height & 0x7;
+
+ offset_from_4 = src_upd_region->left & 0x3;
+ input_unaligned = ((offset_from_4 * bytes_per_pixel % 4) != 0) ?
+ true : false;
+
+ pix_per_line_added = (offset_from_4 * bytes_per_pixel % 4)
+ / bytes_per_pixel;
+ if ((((fb_data->epdc_fb_var.rotate == FB_ROTATE_UR) ||
+ fb_data->epdc_fb_var.rotate == FB_ROTATE_UD)) &&
+ (ALIGN(src_upd_region->width, 8) <
+ ALIGN(src_upd_region->width + pix_per_line_added, 8)))
+ line_overflow = true;
+
+ /* Grab pxp_mutex here so that we protect access
+ * to copybuf in addition to the PxP structures */
+ mutex_lock(&fb_data->pxp_mutex);
+
+ if (((((width_unaligned || height_unaligned || input_unaligned) &&
+ (upd_desc_list->upd_data.waveform_mode == WAVEFORM_MODE_AUTO))
+ || line_overflow) && (fb_data->rev < 20)) ||
+ fb_data->restrict_width) {
+ dev_dbg(fb_data->dev, "Copying update before processing.\n");
+
+ /* Update to reflect what the new source buffer will be */
+ src_width = ALIGN(src_upd_region->width, 8);
+ src_height = ALIGN(src_upd_region->height, 8);
+
+ copy_before_process(fb_data, upd_data_list);
+
+ /*
+ * src_upd_region should now describe
+ * the new update buffer attributes.
+ */
+ temp_buf_upd_region.left = 0;
+ temp_buf_upd_region.top = 0;
+ temp_buf_upd_region.width = src_upd_region->width;
+ temp_buf_upd_region.height = src_upd_region->height;
+ src_upd_region = &temp_buf_upd_region;
+
+ use_temp_buf = true;
+ }
+
+ /*
+ * For pre-2.0 HW, input address must be 32-bit aligned
+ * Compute buffer offset to account for this PxP limitation
+ */
+ offset_from_4 = src_upd_region->left & 0x3;
+ input_unaligned = ((offset_from_4 * bytes_per_pixel % 4) != 0) ?
+ true : false;
+ if ((fb_data->rev < 20) && input_unaligned) {
+ /* Leave a gap between PxP input addr and update region pixels */
+ pxp_input_offs =
+ (src_upd_region->top * src_width + src_upd_region->left)
+ * bytes_per_pixel & 0xFFFFFFFC;
+ /* Update region left changes to reflect relative position to input ptr */
+ pxp_upd_region.left = (offset_from_4 * bytes_per_pixel % 4)
+ / bytes_per_pixel;
+ } else {
+ pxp_input_offs =
+ (src_upd_region->top * src_width + src_upd_region->left)
+ * bytes_per_pixel;
+ pxp_upd_region.left = 0;
+ }
+
+ pxp_upd_region.top = 0;
+
+ /*
+ * For version 2.0 and later of EPDC & PxP, if no rotation, we don't
+ * need to align width & height (rotation always requires 8-pixel
+ * width & height alignment, per PxP limitations)
+ */
+ if ((fb_data->epdc_fb_var.rotate == 0) && (fb_data->rev >= 20)) {
+ pxp_upd_region.width = src_upd_region->width;
+ pxp_upd_region.height = src_upd_region->height;
+ } else {
+ /* Update region dimensions to meet 8x8 pixel requirement */
+ pxp_upd_region.width = ALIGN(src_upd_region->width + pxp_upd_region.left, 8);
+ pxp_upd_region.height = ALIGN(src_upd_region->height, 8);
+ }
+
+ switch (fb_data->epdc_fb_var.rotate) {
+ case FB_ROTATE_UR:
+ default:
+ post_rotation_xcoord = pxp_upd_region.left;
+ post_rotation_ycoord = pxp_upd_region.top;
+ width_pxp_blocks = pxp_upd_region.width;
+ break;
+ case FB_ROTATE_CW:
+ width_pxp_blocks = pxp_upd_region.height;
+ post_rotation_xcoord = width_pxp_blocks - src_upd_region->height;
+ post_rotation_ycoord = pxp_upd_region.left;
+ break;
+ case FB_ROTATE_UD:
+ width_pxp_blocks = pxp_upd_region.width;
+ post_rotation_xcoord = width_pxp_blocks - src_upd_region->width - pxp_upd_region.left;
+ post_rotation_ycoord = pxp_upd_region.height - src_upd_region->height - pxp_upd_region.top;
+ break;
+ case FB_ROTATE_CCW:
+ width_pxp_blocks = pxp_upd_region.height;
+ post_rotation_xcoord = pxp_upd_region.top;
+ post_rotation_ycoord = pxp_upd_region.width - src_upd_region->width - pxp_upd_region.left;
+ break;
+ }
+
+ /* Update region start coord to force PxP to process full 8x8 regions */
+ pxp_upd_region.top &= ~0x7;
+ pxp_upd_region.left &= ~0x7;
+
+ if (fb_data->rev < 20) {
+ pxp_output_shift = ALIGN(post_rotation_xcoord, 8)
+ - post_rotation_xcoord;
+
+ pxp_output_offs = post_rotation_ycoord * width_pxp_blocks
+ + pxp_output_shift;
+
+ upd_desc_list->epdc_offs = ALIGN(pxp_output_offs, 8);
+ } else {
+ pxp_output_shift = 0;
+ pxp_output_offs = post_rotation_ycoord * width_pxp_blocks
+ + post_rotation_xcoord;
+
+ upd_desc_list->epdc_offs = pxp_output_offs;
+ }
+
+ upd_desc_list->epdc_stride = width_pxp_blocks;
+
+ /* Source address either comes from alternate buffer
+ provided in update data, or from the framebuffer. */
+ if (use_temp_buf)
+ sg_dma_address(&fb_data->sg[0]) =
+ fb_data->phys_addr_copybuf;
+ else if (upd_desc_list->upd_data.flags & EPDC_FLAG_USE_ALT_BUFFER)
+ sg_dma_address(&fb_data->sg[0]) =
+ upd_desc_list->upd_data.alt_buffer_data.phys_addr
+ + pxp_input_offs;
+ else {
+ sg_dma_address(&fb_data->sg[0]) =
+ fb_data->info.fix.smem_start + fb_data->fb_offset
+ + pxp_input_offs;
+ sg_set_page(&fb_data->sg[0],
+ virt_to_page(fb_data->info.screen_base),
+ fb_data->info.fix.smem_len,
+ offset_in_page(fb_data->info.screen_base));
+ }
+
+ /* Update sg[1] to point to output of PxP proc task */
+ sg_dma_address(&fb_data->sg[1]) = upd_data_list->phys_addr
+ + pxp_output_shift;
+ sg_set_page(&fb_data->sg[1], virt_to_page(upd_data_list->virt_addr),
+ fb_data->max_pix_size,
+ offset_in_page(upd_data_list->virt_addr));
+
+ /*
+ * Set PxP LUT transform type based on update flags.
+ */
+ fb_data->pxp_conf.proc_data.lut_transform = 0;
+ if (upd_desc_list->upd_data.flags & EPDC_FLAG_ENABLE_INVERSION)
+ fb_data->pxp_conf.proc_data.lut_transform |= PXP_LUT_INVERT;
+ if (upd_desc_list->upd_data.flags & EPDC_FLAG_FORCE_MONOCHROME)
+ fb_data->pxp_conf.proc_data.lut_transform |=
+ PXP_LUT_BLACK_WHITE;
+ if (upd_desc_list->upd_data.flags & EPDC_FLAG_USE_CMAP)
+ fb_data->pxp_conf.proc_data.lut_transform |=
+ PXP_LUT_USE_CMAP;
+
+ /*
+ * Toggle inversion processing if 8-bit
+ * inverted is the current pixel format.
+ */
+ if (fb_data->epdc_fb_var.grayscale == GRAYSCALE_8BIT_INVERTED)
+ fb_data->pxp_conf.proc_data.lut_transform ^= PXP_LUT_INVERT;
+
+ /* This is a blocking call, so upon return PxP tx should be done */
+ ret = pxp_process_update(fb_data, src_width, src_height,
+ &pxp_upd_region);
+ if (ret) {
+ dev_err(fb_data->dev, "Unable to submit PxP update task.\n");
+ mutex_unlock(&fb_data->pxp_mutex);
+ return ret;
+ }
+
+ /* If needed, enable EPDC HW while ePxP is processing */
+ if ((fb_data->power_state == POWER_STATE_OFF)
+ || fb_data->powering_down) {
+ epdc_powerup(fb_data);
+ }
+
+ /* This is a blocking call, so upon return PxP tx should be done */
+ ret = pxp_complete_update(fb_data, &hist_stat);
+ if (ret) {
+ dev_err(fb_data->dev, "Unable to complete PxP update task.\n");
+ mutex_unlock(&fb_data->pxp_mutex);
+ return ret;
+ }
+
+ mutex_unlock(&fb_data->pxp_mutex);
+
+ /* Update waveform mode from PxP histogram results */
+ if ((fb_data->rev <= 20) &&
+ (upd_desc_list->upd_data.waveform_mode == WAVEFORM_MODE_AUTO)) {
+ if (hist_stat & 0x1)
+ upd_desc_list->upd_data.waveform_mode =
+ fb_data->wv_modes.mode_du;
+ else if (hist_stat & 0x2)
+ upd_desc_list->upd_data.waveform_mode =
+ fb_data->wv_modes.mode_gc4;
+ else if (hist_stat & 0x4)
+ upd_desc_list->upd_data.waveform_mode =
+ fb_data->wv_modes.mode_gc8;
+ else if (hist_stat & 0x8)
+ upd_desc_list->upd_data.waveform_mode =
+ fb_data->wv_modes.mode_gc16;
+ else
+ upd_desc_list->upd_data.waveform_mode =
+ fb_data->wv_modes.mode_gc32;
+
+ dev_dbg(fb_data->dev, "hist_stat = 0x%x, new waveform = 0x%x\n",
+ hist_stat, upd_desc_list->upd_data.waveform_mode);
+ }
+
+ return 0;
+}
+
+static int epdc_submit_merge(struct update_desc_list *upd_desc_list,
+ struct update_desc_list *update_to_merge,
+ struct mxc_epdc_fb_data *fb_data)
+{
+ struct mxcfb_update_data *a, *b;
+ struct mxcfb_rect *arect, *brect;
+ struct mxcfb_rect combine;
+ bool use_flags = false;
+
+ a = &upd_desc_list->upd_data;
+ b = &update_to_merge->upd_data;
+ arect = &upd_desc_list->upd_data.update_region;
+ brect = &update_to_merge->upd_data.update_region;
+
+ /* Do not merge a dry-run collision test update */
+ if ((a->flags & EPDC_FLAG_TEST_COLLISION) ||
+ (b->flags & EPDC_FLAG_TEST_COLLISION))
+ return MERGE_BLOCK;
+
+ /*
+ * Updates with different flags must be executed sequentially.
+ * Halt the merge process to ensure this.
+ */
+ if (a->flags != b->flags) {
+ /*
+ * Special exception: if update regions are identical,
+ * we may be able to merge them.
+ */
+ if ((arect->left != brect->left) ||
+ (arect->top != brect->top) ||
+ (arect->width != brect->width) ||
+ (arect->height != brect->height))
+ return MERGE_BLOCK;
+
+ use_flags = true;
+ }
+
+ if (a->update_mode != b->update_mode)
+ a->update_mode = UPDATE_MODE_FULL;
+
+ if (a->waveform_mode != b->waveform_mode)
+ a->waveform_mode = WAVEFORM_MODE_AUTO;
+
+ if (arect->left > (brect->left + brect->width) ||
+ brect->left > (arect->left + arect->width) ||
+ arect->top > (brect->top + brect->height) ||
+ brect->top > (arect->top + arect->height))
+ return MERGE_FAIL;
+
+ combine.left = arect->left < brect->left ? arect->left : brect->left;
+ combine.top = arect->top < brect->top ? arect->top : brect->top;
+ combine.width = (arect->left + arect->width) >
+ (brect->left + brect->width) ?
+ (arect->left + arect->width - combine.left) :
+ (brect->left + brect->width - combine.left);
+ combine.height = (arect->top + arect->height) >
+ (brect->top + brect->height) ?
+ (arect->top + arect->height - combine.top) :
+ (brect->top + brect->height - combine.top);
+
+ /* Don't merge if combined width exceeds max width */
+ if (fb_data->restrict_width) {
+ u32 max_width = EPDC_V2_MAX_UPDATE_WIDTH;
+ u32 combined_width = combine.width;
+ if (fb_data->epdc_fb_var.rotate != FB_ROTATE_UR)
+ max_width -= EPDC_V2_ROTATION_ALIGNMENT;
+ if ((fb_data->epdc_fb_var.rotate == FB_ROTATE_CW) ||
+ (fb_data->epdc_fb_var.rotate == FB_ROTATE_CCW))
+ combined_width = combine.height;
+ if (combined_width > max_width)
+ return MERGE_FAIL;
+ }
+
+ *arect = combine;
+
+ /* Use flags of the later update */
+ if (use_flags)
+ a->flags = b->flags;
+
+ /* Merge markers */
+ list_splice_tail(&update_to_merge->upd_marker_list,
+ &upd_desc_list->upd_marker_list);
+
+ /* Merged update should take on the earliest order */
+ upd_desc_list->update_order =
+ (upd_desc_list->update_order > update_to_merge->update_order) ?
+ upd_desc_list->update_order : update_to_merge->update_order;
+
+ return MERGE_OK;
+}
+
+static void epdc_submit_work_func(struct work_struct *work)
+{
+ int temp_index;
+ struct update_data_list *next_update, *temp_update;
+ struct update_desc_list *next_desc, *temp_desc;
+ struct update_marker_data *next_marker, *temp_marker;
+ struct mxc_epdc_fb_data *fb_data =
+ container_of(work, struct mxc_epdc_fb_data, epdc_submit_work);
+ struct update_data_list *upd_data_list = NULL;
+ struct mxcfb_rect adj_update_region, *upd_region;
+ bool end_merge = false;
+ bool is_transform;
+ u32 update_addr;
+ int *err_dist;
+ int ret;
+
+ /* Protect access to buffer queues and to update HW */
+ mutex_lock(&fb_data->queue_mutex);
+
+ /*
+ * Are any of our collision updates able to go now?
+ * Go through all updates in the collision list and check to see
+ * if the collision mask has been fully cleared
+ */
+ list_for_each_entry_safe(next_update, temp_update,
+ &fb_data->upd_buf_collision_list, list) {
+
+ if (next_update->collision_mask != 0)
+ continue;
+
+ dev_dbg(fb_data->dev, "A collision update is ready to go!\n");
+
+ /* Force waveform mode to auto for resubmitted collisions */
+ next_update->update_desc->upd_data.waveform_mode =
+ WAVEFORM_MODE_AUTO;
+
+ /*
+ * We have a collision cleared, so select it for resubmission.
+ * If an update is already selected, attempt to merge.
+ */
+ if (!upd_data_list) {
+ upd_data_list = next_update;
+ list_del_init(&next_update->list);
+ if (fb_data->upd_scheme == UPDATE_SCHEME_QUEUE)
+ /* If not merging, we have our update */
+ break;
+ } else {
+ switch (epdc_submit_merge(upd_data_list->update_desc,
+ next_update->update_desc,
+ fb_data)) {
+ case MERGE_OK:
+ dev_dbg(fb_data->dev,
+ "Update merged [collision]\n");
+ list_del_init(&next_update->update_desc->list);
+ kfree(next_update->update_desc);
+ next_update->update_desc = NULL;
+ list_del_init(&next_update->list);
+ /* Add to free buffer list */
+ list_add_tail(&next_update->list,
+ &fb_data->upd_buf_free_list);
+ break;
+ case MERGE_FAIL:
+ dev_dbg(fb_data->dev,
+ "Update not merged [collision]\n");
+ break;
+ case MERGE_BLOCK:
+ dev_dbg(fb_data->dev,
+ "Merge blocked [collision]\n");
+ end_merge = true;
+ break;
+ }
+
+ if (end_merge) {
+ end_merge = false;
+ break;
+ }
+ }
+ }
+
+ /*
+ * Skip pending update list only if we found a collision
+ * update and we are not merging
+ */
+ if (!((fb_data->upd_scheme == UPDATE_SCHEME_QUEUE) &&
+ upd_data_list)) {
+ /*
+ * If we didn't find a collision update ready to go, we
+ * need to get a free buffer and match it to a pending update.
+ */
+
+ /*
+ * Can't proceed if there are no free buffers (and we don't
+ * already have a collision update selected)
+ */
+ if (!upd_data_list &&
+ list_empty(&fb_data->upd_buf_free_list)) {
+ mutex_unlock(&fb_data->queue_mutex);
+ return;
+ }
+
+ list_for_each_entry_safe(next_desc, temp_desc,
+ &fb_data->upd_pending_list, list) {
+
+ dev_dbg(fb_data->dev, "Found a pending update!\n");
+
+ if (!upd_data_list) {
+ if (list_empty(&fb_data->upd_buf_free_list))
+ break;
+ upd_data_list =
+ list_entry(fb_data->upd_buf_free_list.next,
+ struct update_data_list, list);
+ list_del_init(&upd_data_list->list);
+ upd_data_list->update_desc = next_desc;
+ list_del_init(&next_desc->list);
+ if (fb_data->upd_scheme == UPDATE_SCHEME_QUEUE)
+ /* If not merging, we have an update */
+ break;
+ } else {
+ switch (epdc_submit_merge(upd_data_list->update_desc,
+ next_desc, fb_data)) {
+ case MERGE_OK:
+ dev_dbg(fb_data->dev,
+ "Update merged [queue]\n");
+ list_del_init(&next_desc->list);
+ kfree(next_desc);
+ break;
+ case MERGE_FAIL:
+ dev_dbg(fb_data->dev,
+ "Update not merged [queue]\n");
+ break;
+ case MERGE_BLOCK:
+ dev_dbg(fb_data->dev,
+ "Merge blocked [collision]\n");
+ end_merge = true;
+ break;
+ }
+
+ if (end_merge)
+ break;
+ }
+ }
+ }
+
+ /* Is update list empty? */
+ if (!upd_data_list) {
+ mutex_unlock(&fb_data->queue_mutex);
+ return;
+ }
+
+ /*
+ * If no processing required, skip update processing
+ * No processing means:
+ * - FB unrotated
+ * - FB pixel format = 8-bit grayscale
+ * - No look-up transformations (inversion, posterization, etc.)
+ *
+ * Note: A bug with EPDC stride prevents us from skipping
+ * PxP in versions 2.0 and earlier of EPDC.
+ */
+ is_transform = upd_data_list->update_desc->upd_data.flags &
+ (EPDC_FLAG_ENABLE_INVERSION | EPDC_FLAG_USE_DITHERING_Y1 |
+ EPDC_FLAG_USE_DITHERING_Y4 | EPDC_FLAG_FORCE_MONOCHROME |
+ EPDC_FLAG_USE_CMAP) ? true : false;
+
+ if ((fb_data->epdc_fb_var.rotate == FB_ROTATE_UR) &&
+ (fb_data->epdc_fb_var.grayscale == GRAYSCALE_8BIT) &&
+ !is_transform && (fb_data->rev > 20) &&
+ !fb_data->restrict_width) {
+
+ /* If needed, enable EPDC HW while ePxP is processing */
+ if ((fb_data->power_state == POWER_STATE_OFF)
+ || fb_data->powering_down)
+ epdc_powerup(fb_data);
+
+ /*
+ * Set update buffer pointer to the start of
+ * the update region in the frame buffer.
+ */
+ upd_region = &upd_data_list->update_desc->upd_data.update_region;
+ update_addr = fb_data->info.fix.smem_start +
+ ((upd_region->top * fb_data->info.var.xres_virtual) +
+ upd_region->left) * fb_data->info.var.bits_per_pixel/8;
+ upd_data_list->update_desc->epdc_stride =
+ fb_data->info.var.xres_virtual *
+ fb_data->info.var.bits_per_pixel/8;
+ } else {
+ /* Select from PxP output buffers */
+ upd_data_list->phys_addr =
+ fb_data->phys_addr_updbuf[fb_data->upd_buffer_num];
+ upd_data_list->virt_addr =
+ fb_data->virt_addr_updbuf[fb_data->upd_buffer_num];
+ fb_data->upd_buffer_num++;
+ if (fb_data->upd_buffer_num > fb_data->max_num_buffers-1)
+ fb_data->upd_buffer_num = 0;
+
+ /* Release buffer queues */
+ mutex_unlock(&fb_data->queue_mutex);
+
+ /* Perform PXP processing - EPDC power will also be enabled */
+ if (epdc_process_update(upd_data_list, fb_data)) {
+ dev_dbg(fb_data->dev, "PXP processing error.\n");
+ /* Protect access to buffer queues and to update HW */
+ mutex_lock(&fb_data->queue_mutex);
+ list_del_init(&upd_data_list->update_desc->list);
+ kfree(upd_data_list->update_desc);
+ upd_data_list->update_desc = NULL;
+ /* Add to free buffer list */
+ list_add_tail(&upd_data_list->list,
+ &fb_data->upd_buf_free_list);
+ /* Release buffer queues */
+ mutex_unlock(&fb_data->queue_mutex);
+ return;
+ }
+
+ /* Protect access to buffer queues and to update HW */
+ mutex_lock(&fb_data->queue_mutex);
+
+ update_addr = upd_data_list->phys_addr
+ + upd_data_list->update_desc->epdc_offs;
+ }
+
+ /* Get rotation-adjusted coordinates */
+ adjust_coordinates(fb_data->epdc_fb_var.xres,
+ fb_data->epdc_fb_var.yres, fb_data->epdc_fb_var.rotate,
+ &upd_data_list->update_desc->upd_data.update_region,
+ &adj_update_region);
+
+ /*
+ * Is the working buffer idle?
+ * If the working buffer is busy, we must wait for the resource
+ * to become free. The IST will signal this event.
+ */
+ if (fb_data->cur_update != NULL) {
+ dev_dbg(fb_data->dev, "working buf busy!\n");
+
+ /* Initialize event signalling an update resource is free */
+ init_completion(&fb_data->update_res_free);
+
+ fb_data->waiting_for_wb = true;
+
+ /* Leave spinlock while waiting for WB to complete */
+ mutex_unlock(&fb_data->queue_mutex);
+ wait_for_completion(&fb_data->update_res_free);
+ mutex_lock(&fb_data->queue_mutex);
+ }
+
+ /*
+ * Dithering Processing (Version 1.0 - for i.MX508 and i.MX6SL)
+ */
+ if (upd_data_list->update_desc->upd_data.flags &
+ EPDC_FLAG_USE_DITHERING_Y1) {
+
+ err_dist = kzalloc((fb_data->info.var.xres_virtual + 3) * 3
+ * sizeof(int), GFP_KERNEL);
+
+ /* Dithering Y8 -> Y1 */
+ do_dithering_processing_Y1_v1_0(
+ (uint8_t *)(upd_data_list->virt_addr +
+ upd_data_list->update_desc->epdc_offs),
+ upd_data_list->phys_addr +
+ upd_data_list->update_desc->epdc_offs,
+ &adj_update_region,
+ (fb_data->rev < 20) ?
+ ALIGN(adj_update_region.width, 8) :
+ adj_update_region.width,
+ err_dist);
+
+ kfree(err_dist);
+ } else if (upd_data_list->update_desc->upd_data.flags &
+ EPDC_FLAG_USE_DITHERING_Y4) {
+
+ err_dist = kzalloc((fb_data->info.var.xres_virtual + 3) * 3
+ * sizeof(int), GFP_KERNEL);
+
+ /* Dithering Y8 -> Y1 */
+ do_dithering_processing_Y4_v1_0(
+ (uint8_t *)(upd_data_list->virt_addr +
+ upd_data_list->update_desc->epdc_offs),
+ upd_data_list->phys_addr +
+ upd_data_list->update_desc->epdc_offs,
+ &adj_update_region,
+ (fb_data->rev < 20) ?
+ ALIGN(adj_update_region.width, 8) :
+ adj_update_region.width,
+ err_dist);
+
+ kfree(err_dist);
+ }
+
+ /*
+ * If there are no LUTs available,
+ * then we must wait for the resource to become free.
+ * The IST will signal this event.
+ */
+ if (!epdc_any_luts_available()) {
+ dev_dbg(fb_data->dev, "no luts available!\n");
+
+ /* Initialize event signalling an update resource is free */
+ init_completion(&fb_data->update_res_free);
+
+ fb_data->waiting_for_lut = true;
+
+ /* Leave spinlock while waiting for LUT to free up */
+ mutex_unlock(&fb_data->queue_mutex);
+ wait_for_completion(&fb_data->update_res_free);
+ mutex_lock(&fb_data->queue_mutex);
+ }
+
+ ret = epdc_choose_next_lut(fb_data->rev, &upd_data_list->lut_num);
+ /*
+ * If LUT15 is in use (for pre-EPDC v2.0 hardware):
+ * - Wait for LUT15 to complete is if TCE underrun prevent is enabled
+ * - If we go ahead with update, sync update submission with EOF
+ */
+ if (ret && fb_data->tce_prevent && (fb_data->rev < 20)) {
+ dev_dbg(fb_data->dev, "Waiting for LUT15\n");
+
+ /* Initialize event signalling that lut15 is free */
+ init_completion(&fb_data->lut15_free);
+
+ fb_data->waiting_for_lut15 = true;
+
+ /* Leave spinlock while waiting for LUT to free up */
+ mutex_unlock(&fb_data->queue_mutex);
+ wait_for_completion(&fb_data->lut15_free);
+ mutex_lock(&fb_data->queue_mutex);
+
+ epdc_choose_next_lut(fb_data->rev, &upd_data_list->lut_num);
+ } else if (ret && (fb_data->rev < 20)) {
+ /* Synchronize update submission time to reduce
+ chances of TCE underrun */
+ init_completion(&fb_data->eof_event);
+
+ epdc_eof_intr(true);
+
+ /* Leave spinlock while waiting for EOF event */
+ mutex_unlock(&fb_data->queue_mutex);
+ ret = wait_for_completion_timeout(&fb_data->eof_event,
+ msecs_to_jiffies(1000));
+ if (!ret) {
+ dev_err(fb_data->dev, "Missed EOF event!\n");
+ epdc_eof_intr(false);
+ }
+ udelay(fb_data->eof_sync_period);
+ mutex_lock(&fb_data->queue_mutex);
+
+ }
+
+ /* LUTs are available, so we get one here */
+ fb_data->cur_update = upd_data_list;
+
+ /* Reset mask for LUTS that have completed during WB processing */
+ fb_data->luts_complete_wb = 0;
+
+ /* If we are just testing for collision, we don't assign a LUT,
+ * so we don't need to update LUT-related resources. */
+ if (!(upd_data_list->update_desc->upd_data.flags
+ & EPDC_FLAG_TEST_COLLISION)) {
+ /* Associate LUT with update marker */
+ list_for_each_entry_safe(next_marker, temp_marker,
+ &upd_data_list->update_desc->upd_marker_list, upd_list)
+ next_marker->lut_num = fb_data->cur_update->lut_num;
+
+ /* Mark LUT with order */
+ fb_data->lut_update_order[upd_data_list->lut_num] =
+ upd_data_list->update_desc->update_order;
+
+ epdc_lut_complete_intr(fb_data->rev, upd_data_list->lut_num,
+ true);
+ }
+
+ /* Enable Collision and WB complete IRQs */
+ epdc_working_buf_intr(true);
+
+ /* Program EPDC update to process buffer */
+ if (upd_data_list->update_desc->upd_data.temp != TEMP_USE_AMBIENT) {
+ temp_index = mxc_epdc_fb_get_temp_index(fb_data,
+ upd_data_list->update_desc->upd_data.temp);
+ epdc_set_temp(temp_index);
+ } else
+ epdc_set_temp(fb_data->temp_index);
+ epdc_set_update_addr(update_addr);
+ epdc_set_update_coord(adj_update_region.left, adj_update_region.top);
+ epdc_set_update_dimensions(adj_update_region.width,
+ adj_update_region.height);
+ if (fb_data->rev > 20)
+ epdc_set_update_stride(upd_data_list->update_desc->epdc_stride);
+ if (fb_data->wv_modes_update &&
+ (upd_data_list->update_desc->upd_data.waveform_mode
+ == WAVEFORM_MODE_AUTO)) {
+ epdc_set_update_waveform(&fb_data->wv_modes);
+ fb_data->wv_modes_update = false;
+ }
+
+ epdc_submit_update(upd_data_list->lut_num,
+ upd_data_list->update_desc->upd_data.waveform_mode,
+ upd_data_list->update_desc->upd_data.update_mode,
+ (upd_data_list->update_desc->upd_data.flags
+ & EPDC_FLAG_TEST_COLLISION) ? true : false,
+ false, 0);
+
+ /* Release buffer queues */
+ mutex_unlock(&fb_data->queue_mutex);
+}
+
+static int mxc_epdc_fb_send_single_update(struct mxcfb_update_data *upd_data,
+ struct fb_info *info)
+{
+ struct mxc_epdc_fb_data *fb_data = info ?
+ (struct mxc_epdc_fb_data *)info:g_fb_data;
+ struct update_data_list *upd_data_list = NULL;
+ struct mxcfb_rect *screen_upd_region; /* Region on screen to update */
+ int temp_index;
+ int ret;
+ struct update_desc_list *upd_desc;
+ struct update_marker_data *marker_data, *next_marker, *temp_marker;
+
+ /* Has EPDC HW been initialized? */
+ if (!fb_data->hw_ready) {
+ /* Throw message if we are not mid-initialization */
+ if (!fb_data->hw_initializing)
+ dev_err(fb_data->dev, "Display HW not properly"
+ "initialized. Aborting update.\n");
+ return -EPERM;
+ }
+
+ /* Check validity of update params */
+ if ((upd_data->update_mode != UPDATE_MODE_PARTIAL) &&
+ (upd_data->update_mode != UPDATE_MODE_FULL)) {
+ dev_err(fb_data->dev,
+ "Update mode 0x%x is invalid. Aborting update.\n",
+ upd_data->update_mode);
+ return -EINVAL;
+ }
+ if ((upd_data->waveform_mode > 255) &&
+ (upd_data->waveform_mode != WAVEFORM_MODE_AUTO)) {
+ dev_err(fb_data->dev,
+ "Update waveform mode 0x%x is invalid."
+ " Aborting update.\n",
+ upd_data->waveform_mode);
+ return -EINVAL;
+ }
+
+ mutex_lock(&fb_data->queue_mutex);
+ if ((upd_data->update_region.left + upd_data->update_region.width > fb_data->epdc_fb_var.xres) ||
+ (upd_data->update_region.top + upd_data->update_region.height > fb_data->epdc_fb_var.yres)) {
+ mutex_unlock(&fb_data->queue_mutex);
+ dev_err(fb_data->dev,
+ "Update region is outside bounds of framebuffer."
+ "Aborting update.\n");
+ return -EINVAL;
+ }
+ mutex_unlock(&fb_data->queue_mutex);
+
+ if (upd_data->flags & EPDC_FLAG_USE_ALT_BUFFER) {
+ if ((upd_data->update_region.width !=
+ upd_data->alt_buffer_data.alt_update_region.width) ||
+ (upd_data->update_region.height !=
+ upd_data->alt_buffer_data.alt_update_region.height)) {
+ dev_err(fb_data->dev,
+ "Alternate update region dimensions must "
+ "match screen update region dimensions.\n");
+ return -EINVAL;
+ }
+ /* Validate physical address parameter */
+ if ((upd_data->alt_buffer_data.phys_addr <
+ fb_data->info.fix.smem_start) ||
+ (upd_data->alt_buffer_data.phys_addr >
+ fb_data->info.fix.smem_start + fb_data->map_size)) {
+ dev_err(fb_data->dev,
+ "Invalid physical address for alternate "
+ "buffer. Aborting update...\n");
+ return -EINVAL;
+ }
+ }
+
+ mutex_lock(&fb_data->queue_mutex);
+
+ /*
+ * If we are waiting to go into suspend, or the FB is blanked,
+ * we do not accept new updates
+ */
+ if ((fb_data->waiting_for_idle) ||
+ (fb_data->blank != FB_BLANK_UNBLANK)) {
+ dev_dbg(fb_data->dev, "EPDC not active."
+ "Update request abort.\n");
+ mutex_unlock(&fb_data->queue_mutex);
+ return -EPERM;
+ }
+
+ if (fb_data->upd_scheme == UPDATE_SCHEME_SNAPSHOT) {
+ int count = 0;
+ struct update_data_list *plist;
+
+ /*
+ * If next update is a FULL mode update, then we must
+ * ensure that all pending & active updates are complete
+ * before submitting the update. Otherwise, the FULL
+ * mode update may cause an endless collision loop with
+ * other updates. Block here until updates are flushed.
+ */
+ if (upd_data->update_mode == UPDATE_MODE_FULL) {
+ mutex_unlock(&fb_data->queue_mutex);
+ mxc_epdc_fb_flush_updates(fb_data);
+ mutex_lock(&fb_data->queue_mutex);
+ }
+
+ /* Count buffers in free buffer list */
+ list_for_each_entry(plist, &fb_data->upd_buf_free_list, list)
+ count++;
+
+ /* Use count to determine if we have enough
+ * free buffers to handle this update request */
+ if (count + fb_data->max_num_buffers
+ <= fb_data->max_num_updates) {
+ dev_err(fb_data->dev,
+ "No free intermediate buffers available.\n");
+ mutex_unlock(&fb_data->queue_mutex);
+ return -ENOMEM;
+ }
+
+ /* Grab first available buffer and delete from the free list */
+ upd_data_list =
+ list_entry(fb_data->upd_buf_free_list.next,
+ struct update_data_list, list);
+
+ list_del_init(&upd_data_list->list);
+ }
+
+ /*
+ * Create new update data structure, fill it with new update
+ * data and add it to the list of pending updates
+ */
+ upd_desc = kzalloc(sizeof(struct update_desc_list), GFP_KERNEL);
+ if (!upd_desc) {
+ dev_err(fb_data->dev,
+ "Insufficient system memory for update! Aborting.\n");
+ if (fb_data->upd_scheme == UPDATE_SCHEME_SNAPSHOT) {
+ list_add(&upd_data_list->list,
+ &fb_data->upd_buf_free_list);
+ }
+ mutex_unlock(&fb_data->queue_mutex);
+ return -EPERM;
+ }
+ /* Initialize per-update marker list */
+ INIT_LIST_HEAD(&upd_desc->upd_marker_list);
+ upd_desc->upd_data = *upd_data;
+ upd_desc->update_order = fb_data->order_cnt++;
+ list_add_tail(&upd_desc->list, &fb_data->upd_pending_list);
+
+ /* If marker specified, associate it with a completion */
+ if (upd_data->update_marker != 0) {
+ /* Allocate new update marker and set it up */
+ marker_data = kzalloc(sizeof(struct update_marker_data),
+ GFP_KERNEL);
+ if (!marker_data) {
+ dev_err(fb_data->dev, "No memory for marker!\n");
+ mutex_unlock(&fb_data->queue_mutex);
+ return -ENOMEM;
+ }
+ list_add_tail(&marker_data->upd_list,
+ &upd_desc->upd_marker_list);
+ marker_data->update_marker = upd_data->update_marker;
+ if (upd_desc->upd_data.flags & EPDC_FLAG_TEST_COLLISION)
+ marker_data->lut_num = DRY_RUN_NO_LUT;
+ else
+ marker_data->lut_num = INVALID_LUT;
+ init_completion(&marker_data->update_completion);
+ /* Add marker to master marker list */
+ list_add_tail(&marker_data->full_list,
+ &fb_data->full_marker_list);
+ }
+
+ if (fb_data->upd_scheme != UPDATE_SCHEME_SNAPSHOT) {
+ /* Queued update scheme processing */
+
+ mutex_unlock(&fb_data->queue_mutex);
+
+ /* Signal workqueue to handle new update */
+ queue_work(fb_data->epdc_submit_workqueue,
+ &fb_data->epdc_submit_work);
+
+ return 0;
+ }
+
+ /* Snapshot update scheme processing */
+
+ /* Set descriptor for current update, delete from pending list */
+ upd_data_list->update_desc = upd_desc;
+ list_del_init(&upd_desc->list);
+
+ mutex_unlock(&fb_data->queue_mutex);
+
+ /*
+ * Hold on to original screen update region, which we
+ * will ultimately use when telling EPDC where to update on panel
+ */
+ screen_upd_region = &upd_desc->upd_data.update_region;
+
+ /* Select from PxP output buffers */
+ upd_data_list->phys_addr =
+ fb_data->phys_addr_updbuf[fb_data->upd_buffer_num];
+ upd_data_list->virt_addr =
+ fb_data->virt_addr_updbuf[fb_data->upd_buffer_num];
+ fb_data->upd_buffer_num++;
+ if (fb_data->upd_buffer_num > fb_data->max_num_buffers-1)
+ fb_data->upd_buffer_num = 0;
+
+ ret = epdc_process_update(upd_data_list, fb_data);
+ if (ret) {
+ mutex_unlock(&fb_data->pxp_mutex);
+ return ret;
+ }
+
+ /* Pass selected waveform mode back to user */
+ upd_data->waveform_mode = upd_desc->upd_data.waveform_mode;
+
+ /* Get rotation-adjusted coordinates */
+ adjust_coordinates(fb_data->epdc_fb_var.xres,
+ fb_data->epdc_fb_var.yres, fb_data->epdc_fb_var.rotate,
+ &upd_desc->upd_data.update_region, NULL);
+
+ /* Grab lock for queue manipulation and update submission */
+ mutex_lock(&fb_data->queue_mutex);
+
+ /*
+ * Is the working buffer idle?
+ * If either the working buffer is busy, or there are no LUTs available,
+ * then we return and let the ISR handle the update later
+ */
+ if ((fb_data->cur_update != NULL) || !epdc_any_luts_available()) {
+ /* Add processed Y buffer to update list */
+ list_add_tail(&upd_data_list->list, &fb_data->upd_buf_queue);
+
+ /* Return and allow the update to be submitted by the ISR. */
+ mutex_unlock(&fb_data->queue_mutex);
+ return 0;
+ }
+
+ /* LUTs are available, so we get one here */
+ ret = epdc_choose_next_lut(fb_data->rev, &upd_data_list->lut_num);
+ if (ret && fb_data->tce_prevent && (fb_data->rev < 20)) {
+ dev_dbg(fb_data->dev, "Must wait for LUT15\n");
+ /* Add processed Y buffer to update list */
+ list_add_tail(&upd_data_list->list, &fb_data->upd_buf_queue);
+
+ /* Return and allow the update to be submitted by the ISR. */
+ mutex_unlock(&fb_data->queue_mutex);
+ return 0;
+ }
+
+ if (!(upd_data_list->update_desc->upd_data.flags
+ & EPDC_FLAG_TEST_COLLISION)) {
+
+ /* Save current update */
+ fb_data->cur_update = upd_data_list;
+
+ /* Reset mask for LUTS that have completed during WB processing */
+ fb_data->luts_complete_wb = 0;
+
+ /* Associate LUT with update marker */
+ list_for_each_entry_safe(next_marker, temp_marker,
+ &upd_data_list->update_desc->upd_marker_list, upd_list)
+ next_marker->lut_num = upd_data_list->lut_num;
+
+ /* Mark LUT as containing new update */
+ fb_data->lut_update_order[upd_data_list->lut_num] =
+ upd_desc->update_order;
+
+ epdc_lut_complete_intr(fb_data->rev, upd_data_list->lut_num,
+ true);
+ }
+
+ /* Clear status and Enable LUT complete and WB complete IRQs */
+ epdc_working_buf_intr(true);
+
+ /* Program EPDC update to process buffer */
+ epdc_set_update_addr(upd_data_list->phys_addr + upd_desc->epdc_offs);
+ epdc_set_update_coord(screen_upd_region->left, screen_upd_region->top);
+ epdc_set_update_dimensions(screen_upd_region->width,
+ screen_upd_region->height);
+ if (fb_data->rev > 20)
+ epdc_set_update_stride(upd_desc->epdc_stride);
+ if (upd_desc->upd_data.temp != TEMP_USE_AMBIENT) {
+ temp_index = mxc_epdc_fb_get_temp_index(fb_data,
+ upd_desc->upd_data.temp);
+ epdc_set_temp(temp_index);
+ } else
+ epdc_set_temp(fb_data->temp_index);
+ if (fb_data->wv_modes_update &&
+ (upd_desc->upd_data.waveform_mode == WAVEFORM_MODE_AUTO)) {
+ epdc_set_update_waveform(&fb_data->wv_modes);
+ fb_data->wv_modes_update = false;
+ }
+
+ epdc_submit_update(upd_data_list->lut_num,
+ upd_desc->upd_data.waveform_mode,
+ upd_desc->upd_data.update_mode,
+ (upd_desc->upd_data.flags
+ & EPDC_FLAG_TEST_COLLISION) ? true : false,
+ false, 0);
+
+ mutex_unlock(&fb_data->queue_mutex);
+ return 0;
+}
+
+int mxc_epdc_fb_send_update(struct mxcfb_update_data *upd_data,
+ struct fb_info *info)
+{
+ struct mxc_epdc_fb_data *fb_data = info ?
+ (struct mxc_epdc_fb_data *)info:g_fb_data;
+
+ if (!fb_data->restrict_width) {
+ /* No width restriction, send entire update region */
+ return mxc_epdc_fb_send_single_update(upd_data, info);
+ } else {
+ int ret;
+ __u32 width, left;
+ __u32 marker;
+ __u32 *region_width, *region_left;
+ u32 max_upd_width = EPDC_V2_MAX_UPDATE_WIDTH;
+
+ /* Further restrict max width due to pxp rotation
+ * alignment requirement
+ */
+ if (fb_data->epdc_fb_var.rotate != FB_ROTATE_UR)
+ max_upd_width -= EPDC_V2_ROTATION_ALIGNMENT;
+
+ /* Select split of width or height based on rotation */
+ if ((fb_data->epdc_fb_var.rotate == FB_ROTATE_UR) ||
+ (fb_data->epdc_fb_var.rotate == FB_ROTATE_UD)) {
+ region_width = &upd_data->update_region.width;
+ region_left = &upd_data->update_region.left;
+ } else {
+ region_width = &upd_data->update_region.height;
+ region_left = &upd_data->update_region.top;
+ }
+
+ if (*region_width <= max_upd_width)
+ return mxc_epdc_fb_send_single_update(upd_data, info);
+
+ width = *region_width;
+ left = *region_left;
+ marker = upd_data->update_marker;
+ upd_data->update_marker = 0;
+
+ do {
+ *region_width = max_upd_width;
+ *region_left = left;
+ ret = mxc_epdc_fb_send_single_update(upd_data, info);
+ if (ret)
+ return ret;
+ width -= max_upd_width;
+ left += max_upd_width;
+ } while (width > max_upd_width);
+
+ *region_width = width;
+ *region_left = left;
+ upd_data->update_marker = marker;
+ return mxc_epdc_fb_send_single_update(upd_data, info);
+ }
+}
+EXPORT_SYMBOL(mxc_epdc_fb_send_update);
+
+int mxc_epdc_fb_wait_update_complete(struct mxcfb_update_marker_data *marker_data,
+ struct fb_info *info)
+{
+ struct mxc_epdc_fb_data *fb_data = info ?
+ (struct mxc_epdc_fb_data *)info:g_fb_data;
+ struct update_marker_data *next_marker;
+ struct update_marker_data *temp;
+ bool marker_found = false;
+ int ret = 0;
+
+ /* 0 is an invalid update_marker value */
+ if (marker_data->update_marker == 0)
+ return -EINVAL;
+
+ /*
+ * Find completion associated with update_marker requested.
+ * Note: If update completed already, marker will have been
+ * cleared, it won't be found, and function will just return.
+ */
+
+ /* Grab queue lock to protect access to marker list */
+ mutex_lock(&fb_data->queue_mutex);
+
+ list_for_each_entry_safe(next_marker, temp,
+ &fb_data->full_marker_list, full_list) {
+ if (next_marker->update_marker == marker_data->update_marker) {
+ dev_dbg(fb_data->dev, "Waiting for marker %d\n",
+ marker_data->update_marker);
+ next_marker->waiting = true;
+ marker_found = true;
+ break;
+ }
+ }
+
+ mutex_unlock(&fb_data->queue_mutex);
+
+ /*
+ * If marker not found, it has either been signalled already
+ * or the update request failed. In either case, just return.
+ */
+ if (!marker_found)
+ return ret;
+
+ ret = wait_for_completion_timeout(&next_marker->update_completion,
+ msecs_to_jiffies(5000));
+ if (!ret) {
+ dev_err(fb_data->dev,
+ "Timed out waiting for update completion\n");
+ return -ETIMEDOUT;
+ }
+
+ marker_data->collision_test = next_marker->collision_test;
+
+ /* Free update marker object */
+ kfree(next_marker);
+
+ return ret;
+}
+EXPORT_SYMBOL(mxc_epdc_fb_wait_update_complete);
+
+int mxc_epdc_fb_set_pwrdown_delay(u32 pwrdown_delay,
+ struct fb_info *info)
+{
+ struct mxc_epdc_fb_data *fb_data = info ?
+ (struct mxc_epdc_fb_data *)info:g_fb_data;
+
+ fb_data->pwrdown_delay = pwrdown_delay;
+
+ return 0;
+}
+EXPORT_SYMBOL(mxc_epdc_fb_set_pwrdown_delay);
+
+int mxc_epdc_get_pwrdown_delay(struct fb_info *info)
+{
+ struct mxc_epdc_fb_data *fb_data = info ?
+ (struct mxc_epdc_fb_data *)info:g_fb_data;
+
+ return fb_data->pwrdown_delay;
+}
+EXPORT_SYMBOL(mxc_epdc_get_pwrdown_delay);
+
+static int mxc_epdc_fb_ioctl(struct fb_info *info, unsigned int cmd,
+ unsigned long arg)
+{
+ void __user *argp = (void __user *)arg;
+ int ret = -EINVAL;
+
+ switch (cmd) {
+ case MXCFB_SET_WAVEFORM_MODES:
+ {
+ struct mxcfb_waveform_modes modes;
+ if (!copy_from_user(&modes, argp, sizeof(modes))) {
+ mxc_epdc_fb_set_waveform_modes(&modes, info);
+ ret = 0;
+ }
+ break;
+ }
+ case MXCFB_SET_TEMPERATURE:
+ {
+ int temperature;
+ if (!get_user(temperature, (int32_t __user *) arg))
+ ret = mxc_epdc_fb_set_temperature(temperature,
+ info);
+ break;
+ }
+ case MXCFB_SET_AUTO_UPDATE_MODE:
+ {
+ u32 auto_mode = 0;
+ if (!get_user(auto_mode, (__u32 __user *) arg))
+ ret = mxc_epdc_fb_set_auto_update(auto_mode,
+ info);
+ break;
+ }
+ case MXCFB_SET_UPDATE_SCHEME:
+ {
+ u32 upd_scheme = 0;
+ if (!get_user(upd_scheme, (__u32 __user *) arg))
+ ret = mxc_epdc_fb_set_upd_scheme(upd_scheme,
+ info);
+ break;
+ }
+ case MXCFB_SEND_UPDATE:
+ {
+ struct mxcfb_update_data upd_data;
+
+ if (mutex_lock_interruptible(&hard_lock) < 0)
+ return -ERESTARTSYS;
+
+ if (!copy_from_user(&upd_data, argp,
+ sizeof(upd_data))) {
+ ret = mxc_epdc_fb_send_update(&upd_data, info);
+ if (ret == 0 && copy_to_user(argp, &upd_data,
+ sizeof(upd_data)))
+ ret = -EFAULT;
+ } else {
+ ret = -EFAULT;
+ }
+
+ mutex_unlock(&hard_lock);
+
+ break;
+ }
+ case MXCFB_WAIT_FOR_UPDATE_COMPLETE:
+ {
+ struct mxcfb_update_marker_data upd_marker_data;
+ if (!copy_from_user(&upd_marker_data, argp,
+ sizeof(upd_marker_data))) {
+ ret = mxc_epdc_fb_wait_update_complete(
+ &upd_marker_data, info);
+ if (copy_to_user(argp, &upd_marker_data,
+ sizeof(upd_marker_data)))
+ ret = -EFAULT;
+ } else {
+ ret = -EFAULT;
+ }
+
+ break;
+ }
+
+ case MXCFB_SET_PWRDOWN_DELAY:
+ {
+ int delay = 0;
+ if (!get_user(delay, (__u32 __user *) arg))
+ ret =
+ mxc_epdc_fb_set_pwrdown_delay(delay, info);
+ break;
+ }
+
+ case MXCFB_GET_PWRDOWN_DELAY:
+ {
+ int pwrdown_delay = mxc_epdc_get_pwrdown_delay(info);
+ if (put_user(pwrdown_delay,
+ (int __user *)argp))
+ ret = -EFAULT;
+ ret = 0;
+ break;
+ }
+
+ case MXCFB_GET_WORK_BUFFER:
+ {
+ /* copy the epdc working buffer to the user space */
+ struct mxc_epdc_fb_data *fb_data = info ?
+ (struct mxc_epdc_fb_data *)info:g_fb_data;
+ flush_cache_all();
+ outer_flush_range(fb_data->working_buffer_phys,
+ fb_data->working_buffer_phys +
+ fb_data->working_buffer_size);
+ if (copy_to_user((void __user *)arg,
+ (const void *) fb_data->working_buffer_virt,
+ fb_data->working_buffer_size))
+ ret = -EFAULT;
+ else
+ ret = 0;
+ flush_cache_all();
+ outer_flush_range(fb_data->working_buffer_phys,
+ fb_data->working_buffer_phys +
+ fb_data->working_buffer_size);
+ break;
+ }
+
+ case MXCFB_DISABLE_EPDC_ACCESS:
+ {
+ struct mxc_epdc_fb_data *fb_data = info ?
+ (struct mxc_epdc_fb_data *)info:g_fb_data;
+ mxc_epdc_fb_flush_updates(fb_data);
+ /* disable handling any user update request */
+ mutex_lock(&hard_lock);
+ ret = 0;
+ break;
+ }
+
+ case MXCFB_ENABLE_EPDC_ACCESS:
+ {
+ /* enable user update handling again */
+ mutex_unlock(&hard_lock);
+ ret = 0;
+ break;
+ }
+
+ default:
+ break;
+ }
+ return ret;
+}
+
+static void mxc_epdc_fb_update_pages(struct mxc_epdc_fb_data *fb_data,
+ u16 y1, u16 y2)
+{
+ struct mxcfb_update_data update;
+
+ /* Do partial screen update, Update full horizontal lines */
+ update.update_region.left = 0;
+ update.update_region.width = fb_data->epdc_fb_var.xres;
+ update.update_region.top = y1;
+ update.update_region.height = y2 - y1;
+ update.waveform_mode = WAVEFORM_MODE_AUTO;
+ update.update_mode = UPDATE_MODE_FULL;
+ update.update_marker = 0;
+ update.temp = TEMP_USE_AMBIENT;
+ update.flags = 0;
+
+ mxc_epdc_fb_send_update(&update, &fb_data->info);
+}
+
+/* this is called back from the deferred io workqueue */
+static void mxc_epdc_fb_deferred_io(struct fb_info *info,
+ struct list_head *pagelist)
+{
+ struct mxc_epdc_fb_data *fb_data = (struct mxc_epdc_fb_data *)info;
+ struct page *page;
+ unsigned long beg, end;
+ int y1, y2, miny, maxy;
+
+ if (fb_data->auto_mode != AUTO_UPDATE_MODE_AUTOMATIC_MODE)
+ return;
+
+ miny = INT_MAX;
+ maxy = 0;
+ list_for_each_entry(page, pagelist, lru) {
+ beg = page->index << PAGE_SHIFT;
+ end = beg + PAGE_SIZE - 1;
+ y1 = beg / info->fix.line_length;
+ y2 = end / info->fix.line_length;
+ if (y2 >= fb_data->epdc_fb_var.yres)
+ y2 = fb_data->epdc_fb_var.yres - 1;
+ if (miny > y1)
+ miny = y1;
+ if (maxy < y2)
+ maxy = y2;
+ }
+
+ mxc_epdc_fb_update_pages(fb_data, miny, maxy);
+}
+
+void mxc_epdc_fb_flush_updates(struct mxc_epdc_fb_data *fb_data)
+{
+ int ret;
+
+ if (fb_data->in_init)
+ return;
+
+ /* Grab queue lock to prevent any new updates from being submitted */
+ mutex_lock(&fb_data->queue_mutex);
+
+ /*
+ * 3 places to check for updates that are active or pending:
+ * 1) Updates in the pending list
+ * 2) Update buffers in use (e.g., PxP processing)
+ * 3) Active updates to panel - We can key off of EPDC
+ * power state to know if we have active updates.
+ */
+ if (!list_empty(&fb_data->upd_pending_list) ||
+ !is_free_list_full(fb_data) ||
+ (fb_data->updates_active == true)) {
+ /* Initialize event signalling updates are done */
+ init_completion(&fb_data->updates_done);
+ fb_data->waiting_for_idle = true;
+
+ mutex_unlock(&fb_data->queue_mutex);
+ /* Wait for any currently active updates to complete */
+ ret = wait_for_completion_timeout(&fb_data->updates_done,
+ msecs_to_jiffies(8000));
+ if (!ret)
+ dev_err(fb_data->dev,
+ "Flush updates timeout! ret = 0x%x\n", ret);
+
+ mutex_lock(&fb_data->queue_mutex);
+ fb_data->waiting_for_idle = false;
+ }
+
+ mutex_unlock(&fb_data->queue_mutex);
+}
+
+static int mxc_epdc_fb_blank(int blank, struct fb_info *info)
+{
+ struct mxc_epdc_fb_data *fb_data = (struct mxc_epdc_fb_data *)info;
+ int ret;
+
+ dev_dbg(fb_data->dev, "blank = %d\n", blank);
+
+ if (fb_data->blank == blank)
+ return 0;
+
+ fb_data->blank = blank;
+
+ switch (blank) {
+ case FB_BLANK_POWERDOWN:
+ mxc_epdc_fb_flush_updates(fb_data);
+ /* Wait for powerdown */
+ mutex_lock(&fb_data->power_mutex);
+ if ((fb_data->power_state == POWER_STATE_ON) &&
+ (fb_data->pwrdown_delay == FB_POWERDOWN_DISABLE)) {
+
+ /* Powerdown disabled, so we disable EPDC manually */
+ int count = 0;
+ int sleep_ms = 10;
+
+ mutex_unlock(&fb_data->power_mutex);
+
+ /* If any active updates, wait for them to complete */
+ while (fb_data->updates_active) {
+ /* Timeout after 1 sec */
+ if ((count * sleep_ms) > 1000)
+ break;
+ msleep(sleep_ms);
+ count++;
+ }
+
+ fb_data->powering_down = true;
+ epdc_powerdown(fb_data);
+ } else if (fb_data->power_state != POWER_STATE_OFF) {
+ fb_data->wait_for_powerdown = true;
+ init_completion(&fb_data->powerdown_compl);
+ mutex_unlock(&fb_data->power_mutex);
+ ret = wait_for_completion_timeout(&fb_data->powerdown_compl,
+ msecs_to_jiffies(5000));
+ if (!ret) {
+ dev_err(fb_data->dev,
+ "No powerdown received!\n");
+ return -ETIMEDOUT;
+ }
+ } else
+ mutex_unlock(&fb_data->power_mutex);
+ break;
+ case FB_BLANK_VSYNC_SUSPEND:
+ case FB_BLANK_HSYNC_SUSPEND:
+ case FB_BLANK_NORMAL:
+ mxc_epdc_fb_flush_updates(fb_data);
+ break;
+ }
+ return 0;
+}
+
+static int mxc_epdc_fb_pan_display(struct fb_var_screeninfo *var,
+ struct fb_info *info)
+{
+ struct mxc_epdc_fb_data *fb_data = (struct mxc_epdc_fb_data *)info;
+ u_int y_bottom;
+
+ dev_dbg(info->device, "%s: var->yoffset %d, info->var.yoffset %d\n",
+ __func__, var->yoffset, info->var.yoffset);
+ /* check if var is valid; also, xpan is not supported */
+ if (!var || (var->xoffset != info->var.xoffset) ||
+ (var->yoffset + var->yres > var->yres_virtual)) {
+ dev_dbg(info->device, "x panning not supported\n");
+ return -EINVAL;
+ }
+
+ if ((fb_data->epdc_fb_var.xoffset == var->xoffset) &&
+ (fb_data->epdc_fb_var.yoffset == var->yoffset))
+ return 0; /* No change, do nothing */
+
+ y_bottom = var->yoffset;
+
+ if (!(var->vmode & FB_VMODE_YWRAP))
+ y_bottom += var->yres;
+
+ if (y_bottom > info->var.yres_virtual)
+ return -EINVAL;
+
+ mutex_lock(&fb_data->queue_mutex);
+
+ fb_data->fb_offset = (var->yoffset * var->xres_virtual + var->xoffset)
+ * (var->bits_per_pixel) / 8;
+
+ fb_data->epdc_fb_var.xoffset = var->xoffset;
+ fb_data->epdc_fb_var.yoffset = var->yoffset;
+
+ if (var->vmode & FB_VMODE_YWRAP)
+ info->var.vmode |= FB_VMODE_YWRAP;
+ else
+ info->var.vmode &= ~FB_VMODE_YWRAP;
+
+ mutex_unlock(&fb_data->queue_mutex);
+
+ return 0;
+}
+
+static struct fb_ops mxc_epdc_fb_ops = {
+ .owner = THIS_MODULE,
+ .fb_check_var = mxc_epdc_fb_check_var,
+ .fb_set_par = mxc_epdc_fb_set_par,
+ .fb_setcmap = mxc_epdc_fb_setcmap,
+ .fb_setcolreg = mxc_epdc_fb_setcolreg,
+ .fb_pan_display = mxc_epdc_fb_pan_display,
+ .fb_ioctl = mxc_epdc_fb_ioctl,
+ .fb_mmap = mxc_epdc_fb_mmap,
+ .fb_blank = mxc_epdc_fb_blank,
+ .fb_fillrect = cfb_fillrect,
+ .fb_copyarea = cfb_copyarea,
+ .fb_imageblit = cfb_imageblit,
+};
+
+static struct fb_deferred_io mxc_epdc_fb_defio = {
+ .delay = HZ,
+ .deferred_io = mxc_epdc_fb_deferred_io,
+};
+
+static void epdc_done_work_func(struct work_struct *work)
+{
+ struct mxc_epdc_fb_data *fb_data =
+ container_of(work, struct mxc_epdc_fb_data,
+ epdc_done_work.work);
+ epdc_powerdown(fb_data);
+}
+
+static bool is_free_list_full(struct mxc_epdc_fb_data *fb_data)
+{
+ int count = 0;
+ struct update_data_list *plist;
+
+ /* Count buffers in free buffer list */
+ list_for_each_entry(plist, &fb_data->upd_buf_free_list, list)
+ count++;
+
+ /* Check to see if all buffers are in this list */
+ if (count == fb_data->max_num_updates)
+ return true;
+ else
+ return false;
+}
+
+static irqreturn_t mxc_epdc_irq_handler(int irq, void *dev_id)
+{
+ struct mxc_epdc_fb_data *fb_data = dev_id;
+ u32 ints_fired, luts1_ints_fired, luts2_ints_fired;
+
+ /*
+ * If we just completed one-time panel init, bypass
+ * queue handling, clear interrupt and return
+ */
+ if (fb_data->in_init) {
+ if (epdc_is_working_buffer_complete()) {
+ epdc_working_buf_intr(false);
+ epdc_clear_working_buf_irq();
+ dev_dbg(fb_data->dev, "Cleared WB for init update\n");
+ }
+
+ if (epdc_is_lut_complete(fb_data->rev, 0)) {
+ epdc_lut_complete_intr(fb_data->rev, 0, false);
+ epdc_clear_lut_complete_irq(fb_data->rev, 0);
+ fb_data->in_init = false;
+ dev_dbg(fb_data->dev, "Cleared LUT complete for init update\n");
+ }
+
+ return IRQ_HANDLED;
+ }
+
+ ints_fired = __raw_readl(EPDC_IRQ_MASK) & __raw_readl(EPDC_IRQ);
+ if (fb_data->rev < 20) {
+ luts1_ints_fired = 0;
+ luts2_ints_fired = 0;
+ } else {
+ luts1_ints_fired = __raw_readl(EPDC_IRQ_MASK1) & __raw_readl(EPDC_IRQ1);
+ luts2_ints_fired = __raw_readl(EPDC_IRQ_MASK2) & __raw_readl(EPDC_IRQ2);
+ }
+
+ if (!(ints_fired || luts1_ints_fired || luts2_ints_fired))
+ return IRQ_HANDLED;
+
+ if (__raw_readl(EPDC_IRQ) & EPDC_IRQ_TCE_UNDERRUN_IRQ) {
+ dev_err(fb_data->dev,
+ "TCE underrun! Will continue to update panel\n");
+ /* Clear TCE underrun IRQ */
+ __raw_writel(EPDC_IRQ_TCE_UNDERRUN_IRQ, EPDC_IRQ_CLEAR);
+ }
+
+ /* Check if we are waiting on EOF to sync a new update submission */
+ if (epdc_signal_eof()) {
+ epdc_eof_intr(false);
+ epdc_clear_eof_irq();
+ complete(&fb_data->eof_event);
+ }
+
+ /*
+ * Workaround for EPDC v2.0/v2.1 errata: Must read collision status
+ * before clearing IRQ, or else collision status for bits 16:63
+ * will be automatically cleared. So we read it here, and there is
+ * no conflict with using it in epdc_intr_work_func since the
+ * working buffer processing flow is strictly sequential (i.e.,
+ * only one WB processing done at a time, so the data grabbed
+ * here should be up-to-date and accurate when the WB processing
+ * completes. Also, note that there is no impact to other versions
+ * of EPDC by reading LUT status here.
+ */
+ if (fb_data->cur_update != NULL)
+ fb_data->epdc_colliding_luts = epdc_get_colliding_luts(fb_data->rev);
+
+ /* Clear the interrupt mask for any interrupts signalled */
+ __raw_writel(ints_fired, EPDC_IRQ_MASK_CLEAR);
+ __raw_writel(luts1_ints_fired, EPDC_IRQ_MASK1_CLEAR);
+ __raw_writel(luts2_ints_fired, EPDC_IRQ_MASK2_CLEAR);
+
+ dev_dbg(fb_data->dev, "EPDC interrupts fired = 0x%x, "
+ "LUTS1 fired = 0x%x, LUTS2 fired = 0x%x\n",
+ ints_fired, luts1_ints_fired, luts2_ints_fired);
+
+ queue_work(fb_data->epdc_intr_workqueue,
+ &fb_data->epdc_intr_work);
+
+ return IRQ_HANDLED;
+}
+
+static void epdc_intr_work_func(struct work_struct *work)
+{
+ struct mxc_epdc_fb_data *fb_data =
+ container_of(work, struct mxc_epdc_fb_data, epdc_intr_work);
+ struct update_data_list *collision_update;
+ struct mxcfb_rect *next_upd_region;
+ struct update_marker_data *next_marker;
+ struct update_marker_data *temp;
+ int temp_index;
+ u64 temp_mask;
+ u32 lut;
+ bool ignore_collision = false;
+ int i;
+ bool wb_lut_done = false;
+ bool free_update = true;
+ int next_lut, epdc_next_lut_15;
+ u32 epdc_luts_active, epdc_wb_busy, epdc_luts_avail, epdc_lut_cancelled;
+ u32 epdc_collision;
+ u64 epdc_irq_stat;
+ bool epdc_waiting_on_wb;
+ u32 coll_coord, coll_size;
+ struct mxcfb_rect coll_region;
+
+ /* Protect access to buffer queues and to update HW */
+ mutex_lock(&fb_data->queue_mutex);
+
+ /* Capture EPDC status one time to limit exposure to race conditions */
+ epdc_luts_active = epdc_any_luts_active(fb_data->rev);
+ epdc_wb_busy = epdc_is_working_buffer_busy();
+ epdc_lut_cancelled = epdc_is_lut_cancelled();
+ epdc_luts_avail = epdc_any_luts_available();
+ epdc_collision = epdc_is_collision();
+ if (fb_data->rev < 20)
+ epdc_irq_stat = __raw_readl(EPDC_IRQ);
+ else
+ epdc_irq_stat = (u64)__raw_readl(EPDC_IRQ1) |
+ ((u64)__raw_readl(EPDC_IRQ2) << 32);
+ epdc_waiting_on_wb = (fb_data->cur_update != NULL) ? true : false;
+
+ /* Free any LUTs that have completed */
+ for (i = 0; i < fb_data->num_luts; i++) {
+ if ((epdc_irq_stat & (1ULL << i)) == 0)
+ continue;
+
+ dev_dbg(fb_data->dev, "LUT %d completed\n", i);
+
+ /* Disable IRQ for completed LUT */
+ epdc_lut_complete_intr(fb_data->rev, i, false);
+
+ /*
+ * Go through all updates in the collision list and
+ * unmask any updates that were colliding with
+ * the completed LUT.
+ */
+ list_for_each_entry(collision_update,
+ &fb_data->upd_buf_collision_list, list) {
+ collision_update->collision_mask =
+ collision_update->collision_mask & ~(1 << i);
+ }
+
+ epdc_clear_lut_complete_irq(fb_data->rev, i);
+
+ fb_data->luts_complete_wb |= 1ULL << i;
+
+ fb_data->lut_update_order[i] = 0;
+
+ /* Signal completion if submit workqueue needs a LUT */
+ if (fb_data->waiting_for_lut) {
+ complete(&fb_data->update_res_free);
+ fb_data->waiting_for_lut = false;
+ }
+
+ /* Signal completion if LUT15 free and is needed */
+ if (fb_data->waiting_for_lut15 && (i == 15)) {
+ complete(&fb_data->lut15_free);
+ fb_data->waiting_for_lut15 = false;
+ }
+
+ /* Detect race condition where WB and its LUT complete
+ (i.e. full update completes) in one swoop */
+ if (epdc_waiting_on_wb &&
+ (i == fb_data->cur_update->lut_num))
+ wb_lut_done = true;
+
+ /* Signal completion if anyone waiting on this LUT */
+ if (!wb_lut_done)
+ list_for_each_entry_safe(next_marker, temp,
+ &fb_data->full_marker_list,
+ full_list) {
+ if (next_marker->lut_num != i)
+ continue;
+
+ /* Found marker to signal - remove from list */
+ list_del_init(&next_marker->full_list);
+
+ /* Signal completion of update */
+ dev_dbg(fb_data->dev, "Signaling marker %d\n",
+ next_marker->update_marker);
+ if (next_marker->waiting)
+ complete(&next_marker->update_completion);
+ else
+ kfree(next_marker);
+ }
+ }
+
+ /* Check to see if all updates have completed */
+ if (list_empty(&fb_data->upd_pending_list) &&
+ is_free_list_full(fb_data) &&
+ !epdc_waiting_on_wb &&
+ !epdc_luts_active) {
+
+ fb_data->updates_active = false;
+
+ if (fb_data->pwrdown_delay != FB_POWERDOWN_DISABLE) {
+ /*
+ * Set variable to prevent overlapping
+ * enable/disable requests
+ */
+ fb_data->powering_down = true;
+
+ /* Schedule task to disable EPDC HW until next update */
+ schedule_delayed_work(&fb_data->epdc_done_work,
+ msecs_to_jiffies(fb_data->pwrdown_delay));
+
+ /* Reset counter to reduce chance of overflow */
+ fb_data->order_cnt = 0;
+ }
+
+ if (fb_data->waiting_for_idle)
+ complete(&fb_data->updates_done);
+ }
+
+ /* Is Working Buffer busy? */
+ if (epdc_wb_busy) {
+ /* Can't submit another update until WB is done */
+ mutex_unlock(&fb_data->queue_mutex);
+ return;
+ }
+
+ /*
+ * Were we waiting on working buffer?
+ * If so, update queues and check for collisions
+ */
+ if (epdc_waiting_on_wb) {
+ dev_dbg(fb_data->dev, "\nWorking buffer completed\n");
+
+ /* Signal completion if submit workqueue was waiting on WB */
+ if (fb_data->waiting_for_wb) {
+ complete(&fb_data->update_res_free);
+ fb_data->waiting_for_wb = false;
+ }
+
+ if (fb_data->cur_update->update_desc->upd_data.flags
+ & EPDC_FLAG_TEST_COLLISION) {
+ /* This was a dry run to test for collision */
+
+ /* Signal marker */
+ list_for_each_entry_safe(next_marker, temp,
+ &fb_data->full_marker_list,
+ full_list) {
+ if (next_marker->lut_num != DRY_RUN_NO_LUT)
+ continue;
+
+ if (epdc_collision)
+ next_marker->collision_test = true;
+ else
+ next_marker->collision_test = false;
+
+ dev_dbg(fb_data->dev,
+ "In IRQ, collision_test = %d\n",
+ next_marker->collision_test);
+
+ /* Found marker to signal - remove from list */
+ list_del_init(&next_marker->full_list);
+
+ /* Signal completion of update */
+ dev_dbg(fb_data->dev, "Signaling marker "
+ "for dry-run - %d\n",
+ next_marker->update_marker);
+ complete(&next_marker->update_completion);
+ }
+ } else if (epdc_lut_cancelled && !epdc_collision) {
+ /*
+ * Note: The update may be cancelled (void) if all
+ * pixels collided. In that case we handle it as a
+ * collision, not a cancel.
+ */
+
+ /* Clear LUT status (might be set if no AUTOWV used) */
+
+ /*
+ * Disable and clear IRQ for the LUT used.
+ * Even though LUT is cancelled in HW, the LUT
+ * complete bit may be set if AUTOWV not used.
+ */
+ epdc_lut_complete_intr(fb_data->rev,
+ fb_data->cur_update->lut_num, false);
+ epdc_clear_lut_complete_irq(fb_data->rev,
+ fb_data->cur_update->lut_num);
+
+ fb_data->lut_update_order[fb_data->cur_update->lut_num] = 0;
+
+ /* Signal completion if submit workqueue needs a LUT */
+ if (fb_data->waiting_for_lut) {
+ complete(&fb_data->update_res_free);
+ fb_data->waiting_for_lut = false;
+ }
+
+ list_for_each_entry_safe(next_marker, temp,
+ &fb_data->cur_update->update_desc->upd_marker_list,
+ upd_list) {
+
+ /* Del from per-update & full list */
+ list_del_init(&next_marker->upd_list);
+ list_del_init(&next_marker->full_list);
+
+ /* Signal completion of update */
+ dev_dbg(fb_data->dev,
+ "Signaling marker (cancelled) %d\n",
+ next_marker->update_marker);
+ if (next_marker->waiting)
+ complete(&next_marker->update_completion);
+ else
+ kfree(next_marker);
+ }
+ } else if (epdc_collision) {
+ /* Real update (no dry-run), collision occurred */
+
+ /* Check list of colliding LUTs, and add to our collision mask */
+ fb_data->cur_update->collision_mask =
+ fb_data->epdc_colliding_luts;
+
+ /* Clear collisions that completed since WB began */
+ fb_data->cur_update->collision_mask &=
+ ~fb_data->luts_complete_wb;
+
+ dev_dbg(fb_data->dev, "Collision mask = 0x%llx\n",
+ fb_data->epdc_colliding_luts);
+
+ /* For EPDC 2.0 and later, minimum collision bounds
+ are provided by HW. Recompute new bounds here. */
+ if ((fb_data->upd_scheme != UPDATE_SCHEME_SNAPSHOT)
+ && (fb_data->rev >= 20)) {
+ u32 xres, yres, rotate;
+ struct mxcfb_rect *cur_upd_rect =
+ &fb_data->cur_update->update_desc->upd_data.update_region;
+
+ /* Get collision region coords from EPDC */
+ coll_coord = __raw_readl(EPDC_UPD_COL_CORD);
+ coll_size = __raw_readl(EPDC_UPD_COL_SIZE);
+ coll_region.left =
+ (coll_coord & EPDC_UPD_COL_CORD_XCORD_MASK)
+ >> EPDC_UPD_COL_CORD_XCORD_OFFSET;
+ coll_region.top =
+ (coll_coord & EPDC_UPD_COL_CORD_YCORD_MASK)
+ >> EPDC_UPD_COL_CORD_YCORD_OFFSET;
+ coll_region.width =
+ (coll_size & EPDC_UPD_COL_SIZE_WIDTH_MASK)
+ >> EPDC_UPD_COL_SIZE_WIDTH_OFFSET;
+ coll_region.height =
+ (coll_size & EPDC_UPD_COL_SIZE_HEIGHT_MASK)
+ >> EPDC_UPD_COL_SIZE_HEIGHT_OFFSET;
+ dev_dbg(fb_data->dev, "Coll region: l = %d, "
+ "t = %d, w = %d, h = %d\n",
+ coll_region.left, coll_region.top,
+ coll_region.width, coll_region.height);
+
+ /* Convert coords back to orig orientation */
+ switch (fb_data->epdc_fb_var.rotate) {
+ case FB_ROTATE_CW:
+ xres = fb_data->epdc_fb_var.yres;
+ yres = fb_data->epdc_fb_var.xres;
+ rotate = FB_ROTATE_CCW;
+ break;
+ case FB_ROTATE_UD:
+ xres = fb_data->epdc_fb_var.xres;
+ yres = fb_data->epdc_fb_var.yres;
+ rotate = FB_ROTATE_UD;
+ break;
+ case FB_ROTATE_CCW:
+ xres = fb_data->epdc_fb_var.yres;
+ yres = fb_data->epdc_fb_var.xres;
+ rotate = FB_ROTATE_CW;
+ break;
+ default:
+ xres = fb_data->epdc_fb_var.xres;
+ yres = fb_data->epdc_fb_var.yres;
+ rotate = FB_ROTATE_UR;
+ break;
+ }
+ adjust_coordinates(xres, yres, rotate,
+ &coll_region, cur_upd_rect);
+
+ dev_dbg(fb_data->dev, "Adj coll region: l = %d, "
+ "t = %d, w = %d, h = %d\n",
+ cur_upd_rect->left, cur_upd_rect->top,
+ cur_upd_rect->width,
+ cur_upd_rect->height);
+ }
+
+ /*
+ * If we collide with newer updates, then
+ * we don't need to re-submit the update. The
+ * idea is that the newer updates should take
+ * precedence anyways, so we don't want to
+ * overwrite them.
+ */
+ for (temp_mask = fb_data->cur_update->collision_mask, lut = 0;
+ temp_mask != 0;
+ lut++, temp_mask = temp_mask >> 1) {
+ if (!(temp_mask & 0x1))
+ continue;
+
+ if (fb_data->lut_update_order[lut] >=
+ fb_data->cur_update->update_desc->update_order) {
+ dev_dbg(fb_data->dev,
+ "Ignoring collision with"
+ "newer update.\n");
+ ignore_collision = true;
+ break;
+ }
+ }
+
+ if (!ignore_collision) {
+ free_update = false;
+ /*
+ * If update has markers, clear the LUTs to
+ * avoid signalling that they have completed.
+ */
+ list_for_each_entry_safe(next_marker, temp,
+ &fb_data->cur_update->update_desc->upd_marker_list,
+ upd_list)
+ next_marker->lut_num = INVALID_LUT;
+
+ /* Move to collision list */
+ list_add_tail(&fb_data->cur_update->list,
+ &fb_data->upd_buf_collision_list);
+ }
+ }
+
+ /* Do we need to free the current update descriptor? */
+ if (free_update) {
+ /* Handle condition where WB & LUT are both complete */
+ if (wb_lut_done)
+ list_for_each_entry_safe(next_marker, temp,
+ &fb_data->cur_update->update_desc->upd_marker_list,
+ upd_list) {
+
+ /* Del from per-update & full list */
+ list_del_init(&next_marker->upd_list);
+ list_del_init(&next_marker->full_list);
+
+ /* Signal completion of update */
+ dev_dbg(fb_data->dev,
+ "Signaling marker (wb) %d\n",
+ next_marker->update_marker);
+ if (next_marker->waiting)
+ complete(&next_marker->update_completion);
+ else
+ kfree(next_marker);
+ }
+
+ /* Free marker list and update descriptor */
+ kfree(fb_data->cur_update->update_desc);
+
+ /* Add to free buffer list */
+ list_add_tail(&fb_data->cur_update->list,
+ &fb_data->upd_buf_free_list);
+
+ /* Check to see if all updates have completed */
+ if (list_empty(&fb_data->upd_pending_list) &&
+ is_free_list_full(fb_data) &&
+ !epdc_luts_active) {
+
+ fb_data->updates_active = false;
+
+ if (fb_data->pwrdown_delay !=
+ FB_POWERDOWN_DISABLE) {
+ /*
+ * Set variable to prevent overlapping
+ * enable/disable requests
+ */
+ fb_data->powering_down = true;
+
+ /* Schedule EPDC disable */
+ schedule_delayed_work(&fb_data->epdc_done_work,
+ msecs_to_jiffies(fb_data->pwrdown_delay));
+
+ /* Reset counter to reduce chance of overflow */
+ fb_data->order_cnt = 0;
+ }
+
+ if (fb_data->waiting_for_idle)
+ complete(&fb_data->updates_done);
+ }
+ }
+
+ /* Clear current update */
+ fb_data->cur_update = NULL;
+
+ /* Clear IRQ for working buffer */
+ epdc_working_buf_intr(false);
+ epdc_clear_working_buf_irq();
+ }
+
+ if (fb_data->upd_scheme != UPDATE_SCHEME_SNAPSHOT) {
+ /* Queued update scheme processing */
+
+ /* Schedule task to submit collision and pending update */
+ if (!fb_data->powering_down)
+ queue_work(fb_data->epdc_submit_workqueue,
+ &fb_data->epdc_submit_work);
+
+ /* Release buffer queues */
+ mutex_unlock(&fb_data->queue_mutex);
+
+ return;
+ }
+
+ /* Snapshot update scheme processing */
+
+ /* Check to see if any LUTs are free */
+ if (!epdc_luts_avail) {
+ dev_dbg(fb_data->dev, "No luts available.\n");
+ mutex_unlock(&fb_data->queue_mutex);
+ return;
+ }
+
+ epdc_next_lut_15 = epdc_choose_next_lut(fb_data->rev, &next_lut);
+ /* Check to see if there is a valid LUT to use */
+ if (epdc_next_lut_15 && fb_data->tce_prevent && (fb_data->rev < 20)) {
+ dev_dbg(fb_data->dev, "Must wait for LUT15\n");
+ mutex_unlock(&fb_data->queue_mutex);
+ return;
+ }
+
+ /*
+ * Are any of our collision updates able to go now?
+ * Go through all updates in the collision list and check to see
+ * if the collision mask has been fully cleared
+ */
+ list_for_each_entry(collision_update,
+ &fb_data->upd_buf_collision_list, list) {
+
+ if (collision_update->collision_mask != 0)
+ continue;
+
+ dev_dbg(fb_data->dev, "A collision update is ready to go!\n");
+ /*
+ * We have a collision cleared, so select it
+ * and we will retry the update
+ */
+ fb_data->cur_update = collision_update;
+ list_del_init(&fb_data->cur_update->list);
+ break;
+ }
+
+ /*
+ * If we didn't find a collision update ready to go,
+ * we try to grab one from the update queue
+ */
+ if (fb_data->cur_update == NULL) {
+ /* Is update list empty? */
+ if (list_empty(&fb_data->upd_buf_queue)) {
+ dev_dbg(fb_data->dev, "No pending updates.\n");
+
+ /* No updates pending, so we are done */
+ mutex_unlock(&fb_data->queue_mutex);
+ return;
+ } else {
+ dev_dbg(fb_data->dev, "Found a pending update!\n");
+
+ /* Process next item in update list */
+ fb_data->cur_update =
+ list_entry(fb_data->upd_buf_queue.next,
+ struct update_data_list, list);
+ list_del_init(&fb_data->cur_update->list);
+ }
+ }
+
+ /* Use LUT selected above */
+ fb_data->cur_update->lut_num = next_lut;
+
+ /* Associate LUT with update markers */
+ list_for_each_entry_safe(next_marker, temp,
+ &fb_data->cur_update->update_desc->upd_marker_list, upd_list)
+ next_marker->lut_num = fb_data->cur_update->lut_num;
+
+ /* Mark LUT as containing new update */
+ fb_data->lut_update_order[fb_data->cur_update->lut_num] =
+ fb_data->cur_update->update_desc->update_order;
+
+ /* Enable Collision and WB complete IRQs */
+ epdc_working_buf_intr(true);
+ epdc_lut_complete_intr(fb_data->rev, fb_data->cur_update->lut_num, true);
+
+ /* Program EPDC update to process buffer */
+ next_upd_region =
+ &fb_data->cur_update->update_desc->upd_data.update_region;
+ if (fb_data->cur_update->update_desc->upd_data.temp
+ != TEMP_USE_AMBIENT) {
+ temp_index = mxc_epdc_fb_get_temp_index(fb_data,
+ fb_data->cur_update->update_desc->upd_data.temp);
+ epdc_set_temp(temp_index);
+ } else
+ epdc_set_temp(fb_data->temp_index);
+ epdc_set_update_addr(fb_data->cur_update->phys_addr +
+ fb_data->cur_update->update_desc->epdc_offs);
+ epdc_set_update_coord(next_upd_region->left, next_upd_region->top);
+ epdc_set_update_dimensions(next_upd_region->width,
+ next_upd_region->height);
+ if (fb_data->rev > 20)
+ epdc_set_update_stride(fb_data->cur_update->update_desc->epdc_stride);
+ if (fb_data->wv_modes_update &&
+ (fb_data->cur_update->update_desc->upd_data.waveform_mode
+ == WAVEFORM_MODE_AUTO)) {
+ epdc_set_update_waveform(&fb_data->wv_modes);
+ fb_data->wv_modes_update = false;
+ }
+
+ epdc_submit_update(fb_data->cur_update->lut_num,
+ fb_data->cur_update->update_desc->upd_data.waveform_mode,
+ fb_data->cur_update->update_desc->upd_data.update_mode,
+ false, false, 0);
+
+ /* Release buffer queues */
+ mutex_unlock(&fb_data->queue_mutex);
+
+ return;
+}
+
+static void draw_mode0(struct mxc_epdc_fb_data *fb_data)
+{
+ u32 *upd_buf_ptr;
+ int i;
+ struct fb_var_screeninfo *screeninfo = &fb_data->epdc_fb_var;
+ u32 xres, yres;
+
+ upd_buf_ptr = (u32 *)fb_data->info.screen_base;
+
+ epdc_working_buf_intr(true);
+ epdc_lut_complete_intr(fb_data->rev, 0, true);
+
+ /* Use unrotated (native) width/height */
+ if ((screeninfo->rotate == FB_ROTATE_CW) ||
+ (screeninfo->rotate == FB_ROTATE_CCW)) {
+ xres = screeninfo->yres;
+ yres = screeninfo->xres;
+ } else {
+ xres = screeninfo->xres;
+ yres = screeninfo->yres;
+ }
+
+ /* Program EPDC update to process buffer */
+ epdc_set_update_addr(fb_data->phys_start);
+ epdc_set_update_coord(0, 0);
+ epdc_set_update_dimensions(xres, yres);
+ if (fb_data->rev > 20)
+ epdc_set_update_stride(0);
+ epdc_submit_update(0, fb_data->wv_modes.mode_init, UPDATE_MODE_FULL,
+ false, true, 0xFF);
+
+ dev_dbg(fb_data->dev, "Mode0 update - Waiting for LUT to complete...\n");
+
+ /* Will timeout after ~4-5 seconds */
+
+ for (i = 0; i < 40; i++) {
+ if (!epdc_is_lut_active(0)) {
+ dev_dbg(fb_data->dev, "Mode0 init complete\n");
+ return;
+ }
+ msleep(100);
+ }
+
+ dev_err(fb_data->dev, "Mode0 init failed!\n");
+
+ return;
+}
+
+
+static void mxc_epdc_fb_fw_handler(const struct firmware *fw,
+ void *context)
+{
+ struct mxc_epdc_fb_data *fb_data = context;
+ int ret;
+ struct mxcfb_waveform_data_file *wv_file;
+ int wv_data_offs;
+ int i;
+ struct mxcfb_update_data update;
+ struct mxcfb_update_marker_data upd_marker_data;
+ struct fb_var_screeninfo *screeninfo = &fb_data->epdc_fb_var;
+ u32 xres, yres;
+ struct clk *epdc_parent;
+ unsigned long rounded_parent_rate, epdc_pix_rate,
+ rounded_pix_clk, target_pix_clk;
+
+ if (fw == NULL) {
+ /* If default FW file load failed, we give up */
+ if (fb_data->fw_default_load)
+ return;
+
+ /* Try to load default waveform */
+ dev_dbg(fb_data->dev,
+ "Can't find firmware. Trying fallback fw\n");
+ fb_data->fw_default_load = true;
+ ret = request_firmware_nowait(THIS_MODULE, FW_ACTION_HOTPLUG,
+ "imx/epdc/epdc.fw", fb_data->dev, GFP_KERNEL, fb_data,
+ mxc_epdc_fb_fw_handler);
+ if (ret)
+ dev_err(fb_data->dev,
+ "Failed request_firmware_nowait err %d\n", ret);
+
+ return;
+ }
+
+ wv_file = (struct mxcfb_waveform_data_file *)fw->data;
+
+ /* Get size and allocate temperature range table */
+ fb_data->trt_entries = wv_file->wdh.trc + 1;
+ fb_data->temp_range_bounds = kzalloc(fb_data->trt_entries, GFP_KERNEL);
+
+ for (i = 0; i < fb_data->trt_entries; i++)
+ dev_dbg(fb_data->dev, "trt entry #%d = 0x%x\n", i, *((u8 *)&wv_file->data + i));
+
+ /* Copy TRT data */
+ memcpy(fb_data->temp_range_bounds, &wv_file->data, fb_data->trt_entries);
+
+ /* Set default temperature index using TRT and room temp */
+ fb_data->temp_index = mxc_epdc_fb_get_temp_index(fb_data, DEFAULT_TEMP);
+
+ /* Get offset and size for waveform data */
+ wv_data_offs = sizeof(wv_file->wdh) + fb_data->trt_entries + 1;
+ fb_data->waveform_buffer_size = fw->size - wv_data_offs;
+
+ /* Allocate memory for waveform data */
+ fb_data->waveform_buffer_virt = dma_alloc_coherent(fb_data->dev,
+ fb_data->waveform_buffer_size,
+ &fb_data->waveform_buffer_phys,
+ GFP_DMA | GFP_KERNEL);
+ if (fb_data->waveform_buffer_virt == NULL) {
+ dev_err(fb_data->dev, "Can't allocate mem for waveform!\n");
+ return;
+ }
+
+ memcpy(fb_data->waveform_buffer_virt, (u8 *)(fw->data) + wv_data_offs,
+ fb_data->waveform_buffer_size);
+
+ release_firmware(fw);
+
+ /* Enable clocks to access EPDC regs */
+ clk_prepare_enable(fb_data->epdc_clk_axi);
+
+ target_pix_clk = fb_data->cur_mode->vmode->pixclock;
+ /* Enable pix clk for EPDC */
+ rounded_pix_clk = clk_round_rate(fb_data->epdc_clk_pix, target_pix_clk);
+
+ if (((rounded_pix_clk >= target_pix_clk + target_pix_clk/100) ||
+ (rounded_pix_clk <= target_pix_clk - target_pix_clk/100))) {
+ /* Can't get close enough without changing parent clk */
+ epdc_parent = clk_get_parent(fb_data->epdc_clk_pix);
+ rounded_parent_rate = clk_round_rate(epdc_parent, target_pix_clk);
+
+ epdc_pix_rate = target_pix_clk;
+ while (epdc_pix_rate < rounded_parent_rate)
+ epdc_pix_rate *= 2;
+ clk_set_rate(epdc_parent, epdc_pix_rate);
+
+ rounded_pix_clk = clk_round_rate(fb_data->epdc_clk_pix, target_pix_clk);
+ if (((rounded_pix_clk >= target_pix_clk + target_pix_clk/100) ||
+ (rounded_pix_clk <= target_pix_clk - target_pix_clk/100)))
+ /* Still can't get a good clock, provide warning */
+ dev_err(fb_data->dev, "Unable to get an accurate EPDC pix clk"
+ "desired = %lu, actual = %lu\n", target_pix_clk,
+ rounded_pix_clk);
+ }
+
+ clk_set_rate(fb_data->epdc_clk_pix, rounded_pix_clk);
+ clk_prepare_enable(fb_data->epdc_clk_pix);
+
+ epdc_init_sequence(fb_data);
+
+ /* Disable clocks */
+ clk_disable_unprepare(fb_data->epdc_clk_axi);
+ clk_disable_unprepare(fb_data->epdc_clk_pix);
+
+ fb_data->hw_ready = true;
+ fb_data->hw_initializing = false;
+
+ /* Use unrotated (native) width/height */
+ if ((screeninfo->rotate == FB_ROTATE_CW) ||
+ (screeninfo->rotate == FB_ROTATE_CCW)) {
+ xres = screeninfo->yres;
+ yres = screeninfo->xres;
+ } else {
+ xres = screeninfo->xres;
+ yres = screeninfo->yres;
+ }
+
+ update.update_region.left = 0;
+ update.update_region.width = xres;
+ update.update_region.top = 0;
+ update.update_region.height = yres;
+ update.update_mode = UPDATE_MODE_FULL;
+ update.waveform_mode = WAVEFORM_MODE_AUTO;
+ update.update_marker = INIT_UPDATE_MARKER;
+ update.temp = TEMP_USE_AMBIENT;
+ update.flags = 0;
+
+ upd_marker_data.update_marker = update.update_marker;
+
+ mxc_epdc_fb_send_update(&update, &fb_data->info);
+
+ /* Block on initial update */
+ ret = mxc_epdc_fb_wait_update_complete(&upd_marker_data,
+ &fb_data->info);
+ if (ret < 0)
+ dev_err(fb_data->dev,
+ "Wait for initial update complete failed."
+ " Error = 0x%x", ret);
+}
+
+static int mxc_epdc_fb_init_hw(struct fb_info *info)
+{
+ struct mxc_epdc_fb_data *fb_data = (struct mxc_epdc_fb_data *)info;
+ int ret;
+
+ /*
+ * Create fw search string based on ID string in selected videomode.
+ * Format is "imx/epdc_[panel string].fw"
+ */
+ if (fb_data->cur_mode) {
+ strcat(fb_data->fw_str, "imx/epdc/epdc_");
+ strcat(fb_data->fw_str, fb_data->cur_mode->vmode->name);
+ strcat(fb_data->fw_str, ".fw");
+ }
+
+ fb_data->fw_default_load = false;
+
+ ret = request_firmware_nowait(THIS_MODULE, FW_ACTION_HOTPLUG,
+ fb_data->fw_str, fb_data->dev, GFP_KERNEL,
+ fb_data, mxc_epdc_fb_fw_handler);
+ if (ret)
+ dev_dbg(fb_data->dev,
+ "Failed request_firmware_nowait err %d\n", ret);
+
+ return ret;
+}
+
+static ssize_t store_update(struct device *device,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct mxcfb_update_data update;
+ struct fb_info *info = dev_get_drvdata(device);
+ struct mxc_epdc_fb_data *fb_data = (struct mxc_epdc_fb_data *)info;
+
+ if (strncmp(buf, "direct", 6) == 0)
+ update.waveform_mode = fb_data->wv_modes.mode_du;
+ else if (strncmp(buf, "gc16", 4) == 0)
+ update.waveform_mode = fb_data->wv_modes.mode_gc16;
+ else if (strncmp(buf, "gc4", 3) == 0)
+ update.waveform_mode = fb_data->wv_modes.mode_gc4;
+
+ /* Now, request full screen update */
+ update.update_region.left = 0;
+ update.update_region.width = fb_data->epdc_fb_var.xres;
+ update.update_region.top = 0;
+ update.update_region.height = fb_data->epdc_fb_var.yres;
+ update.update_mode = UPDATE_MODE_FULL;
+ update.temp = TEMP_USE_AMBIENT;
+ update.update_marker = 0;
+ update.flags = 0;
+
+ mxc_epdc_fb_send_update(&update, info);
+
+ return count;
+}
+
+static struct device_attribute fb_attrs[] = {
+ __ATTR(update, S_IRUGO|S_IWUSR, NULL, store_update),
+};
+
+static const struct of_device_id imx_epdc_dt_ids[] = {
+ { .compatible = "fsl,imx6dl-epdc", },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, imx_epdc_dt_ids);
+
+int mxc_epdc_fb_probe(struct platform_device *pdev)
+{
+ int ret = 0;
+ struct pinctrl *pinctrl;
+ struct mxc_epdc_fb_data *fb_data;
+ struct resource *res;
+ struct fb_info *info;
+ char *options, *opt;
+ char *panel_str = NULL;
+ char name[] = "mxcepdcfb";
+ struct fb_videomode *vmode;
+ int xres_virt, yres_virt, buf_size;
+ int xres_virt_rot, yres_virt_rot, pix_size_rot;
+ struct fb_var_screeninfo *var_info;
+ struct fb_fix_screeninfo *fix_info;
+ struct pxp_config_data *pxp_conf;
+ struct pxp_proc_data *proc_data;
+ struct scatterlist *sg;
+ struct update_data_list *upd_list;
+ struct update_data_list *plist, *temp_list;
+ int i;
+ unsigned long x_mem_size = 0;
+ u32 val;
+ int irq;
+
+ fb_data = (struct mxc_epdc_fb_data *)framebuffer_alloc(
+ sizeof(struct mxc_epdc_fb_data), &pdev->dev);
+ if (fb_data == NULL) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ /* Get platform data and check validity */
+ fb_data->pdata = &epdc_data;
+ if ((fb_data->pdata == NULL) || (fb_data->pdata->num_modes < 1)
+ || (fb_data->pdata->epdc_mode == NULL)
+ || (fb_data->pdata->epdc_mode->vmode == NULL)) {
+ ret = -EINVAL;
+ goto out_fbdata;
+ }
+
+ if (fb_get_options(name, &options)) {
+ ret = -ENODEV;
+ goto out_fbdata;
+ }
+
+ fb_data->tce_prevent = 0;
+
+ if (options)
+ while ((opt = strsep(&options, ",")) != NULL) {
+ if (!*opt)
+ continue;
+
+ if (!strncmp(opt, "bpp=", 4))
+ fb_data->default_bpp =
+ simple_strtoul(opt + 4, NULL, 0);
+ else if (!strncmp(opt, "x_mem=", 6))
+ x_mem_size = memparse(opt + 6, NULL);
+ else if (!strncmp(opt, "tce_prevent", 11))
+ fb_data->tce_prevent = 1;
+ else
+ panel_str = opt;
+ }
+
+ fb_data->dev = &pdev->dev;
+
+ if (!fb_data->default_bpp)
+ fb_data->default_bpp = 16;
+
+ /* Set default (first defined mode) before searching for a match */
+ fb_data->cur_mode = &fb_data->pdata->epdc_mode[0];
+
+ if (panel_str)
+ for (i = 0; i < fb_data->pdata->num_modes; i++)
+ if (!strcmp(fb_data->pdata->epdc_mode[i].vmode->name,
+ panel_str)) {
+ fb_data->cur_mode =
+ &fb_data->pdata->epdc_mode[i];
+ break;
+ }
+
+ vmode = fb_data->cur_mode->vmode;
+
+ platform_set_drvdata(pdev, fb_data);
+ info = &fb_data->info;
+
+ /* Allocate color map for the FB */
+ ret = fb_alloc_cmap(&info->cmap, 256, 0);
+ if (ret)
+ goto out_fbdata;
+
+ dev_dbg(&pdev->dev, "resolution %dx%d, bpp %d\n",
+ vmode->xres, vmode->yres, fb_data->default_bpp);
+
+ /*
+ * GPU alignment restrictions dictate framebuffer parameters:
+ * - 32-byte alignment for buffer width
+ * - 128-byte alignment for buffer height
+ * => 4K buffer alignment for buffer start
+ */
+ xres_virt = ALIGN(vmode->xres, 32);
+ yres_virt = ALIGN(vmode->yres, 128);
+ fb_data->max_pix_size = PAGE_ALIGN(xres_virt * yres_virt);
+
+ /*
+ * Have to check to see if aligned buffer size when rotated
+ * is bigger than when not rotated, and use the max
+ */
+ xres_virt_rot = ALIGN(vmode->yres, 32);
+ yres_virt_rot = ALIGN(vmode->xres, 128);
+ pix_size_rot = PAGE_ALIGN(xres_virt_rot * yres_virt_rot);
+ fb_data->max_pix_size = (fb_data->max_pix_size > pix_size_rot) ?
+ fb_data->max_pix_size : pix_size_rot;
+
+ buf_size = fb_data->max_pix_size * fb_data->default_bpp/8;
+
+ /* Compute the number of screens needed based on X memory requested */
+ if (x_mem_size > 0) {
+ fb_data->num_screens = DIV_ROUND_UP(x_mem_size, buf_size);
+ if (fb_data->num_screens < NUM_SCREENS_MIN)
+ fb_data->num_screens = NUM_SCREENS_MIN;
+ else if (buf_size * fb_data->num_screens > SZ_16M)
+ fb_data->num_screens = SZ_16M / buf_size;
+ } else
+ fb_data->num_screens = NUM_SCREENS_MIN;
+
+ fb_data->map_size = buf_size * fb_data->num_screens;
+ dev_dbg(&pdev->dev, "memory to allocate: %d\n", fb_data->map_size);
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (res == NULL) {
+ ret = -ENODEV;
+ goto out_cmap;
+ }
+
+ epdc_base = devm_ioremap_resource(&pdev->dev, res);
+ if (epdc_base == NULL) {
+ ret = -ENOMEM;
+ goto out_cmap;
+ }
+
+ /* Allocate FB memory */
+ info->screen_base = dma_alloc_writecombine(&pdev->dev,
+ fb_data->map_size,
+ &fb_data->phys_start,
+ GFP_DMA | GFP_KERNEL);
+
+ if (info->screen_base == NULL) {
+ ret = -ENOMEM;
+ goto out_cmap;
+ }
+ dev_dbg(&pdev->dev, "allocated at %p:0x%x\n", info->screen_base,
+ fb_data->phys_start);
+
+ var_info = &info->var;
+ var_info->activate = FB_ACTIVATE_TEST;
+ var_info->bits_per_pixel = fb_data->default_bpp;
+ var_info->xres = vmode->xres;
+ var_info->yres = vmode->yres;
+ var_info->xres_virtual = xres_virt;
+ /* Additional screens allow for panning and buffer flipping */
+ var_info->yres_virtual = yres_virt * fb_data->num_screens;
+
+ var_info->pixclock = vmode->pixclock;
+ var_info->left_margin = vmode->left_margin;
+ var_info->right_margin = vmode->right_margin;
+ var_info->upper_margin = vmode->upper_margin;
+ var_info->lower_margin = vmode->lower_margin;
+ var_info->hsync_len = vmode->hsync_len;
+ var_info->vsync_len = vmode->vsync_len;
+ var_info->vmode = FB_VMODE_NONINTERLACED;
+
+ switch (fb_data->default_bpp) {
+ case 32:
+ case 24:
+ var_info->red.offset = 16;
+ var_info->red.length = 8;
+ var_info->green.offset = 8;
+ var_info->green.length = 8;
+ var_info->blue.offset = 0;
+ var_info->blue.length = 8;
+ break;
+
+ case 16:
+ var_info->red.offset = 11;
+ var_info->red.length = 5;
+ var_info->green.offset = 5;
+ var_info->green.length = 6;
+ var_info->blue.offset = 0;
+ var_info->blue.length = 5;
+ break;
+
+ case 8:
+ /*
+ * For 8-bit grayscale, R, G, and B offset are equal.
+ *
+ */
+ var_info->grayscale = GRAYSCALE_8BIT;
+
+ var_info->red.length = 8;
+ var_info->red.offset = 0;
+ var_info->red.msb_right = 0;
+ var_info->green.length = 8;
+ var_info->green.offset = 0;
+ var_info->green.msb_right = 0;
+ var_info->blue.length = 8;
+ var_info->blue.offset = 0;
+ var_info->blue.msb_right = 0;
+ break;
+
+ default:
+ dev_err(&pdev->dev, "unsupported bitwidth %d\n",
+ fb_data->default_bpp);
+ ret = -EINVAL;
+ goto out_dma_fb;
+ }
+
+ fix_info = &info->fix;
+
+ strcpy(fix_info->id, "mxc_epdc_fb");
+ fix_info->type = FB_TYPE_PACKED_PIXELS;
+ fix_info->visual = FB_VISUAL_TRUECOLOR;
+ fix_info->xpanstep = 0;
+ fix_info->ypanstep = 0;
+ fix_info->ywrapstep = 0;
+ fix_info->accel = FB_ACCEL_NONE;
+ fix_info->smem_start = fb_data->phys_start;
+ fix_info->smem_len = fb_data->map_size;
+ fix_info->ypanstep = 0;
+
+ fb_data->native_width = vmode->xres;
+ fb_data->native_height = vmode->yres;
+
+ info->fbops = &mxc_epdc_fb_ops;
+ info->var.activate = FB_ACTIVATE_NOW;
+ info->pseudo_palette = fb_data->pseudo_palette;
+ info->screen_size = info->fix.smem_len;
+ info->flags = FBINFO_FLAG_DEFAULT;
+
+ mxc_epdc_fb_set_fix(info);
+
+ fb_data->auto_mode = AUTO_UPDATE_MODE_REGION_MODE;
+ fb_data->upd_scheme = UPDATE_SCHEME_QUEUE_AND_MERGE;
+
+ /* Initialize our internal copy of the screeninfo */
+ fb_data->epdc_fb_var = *var_info;
+ fb_data->fb_offset = 0;
+ fb_data->eof_sync_period = 0;
+
+ fb_data->epdc_clk_axi = clk_get(fb_data->dev, "epdc_axi");
+ if (IS_ERR(fb_data->epdc_clk_axi)) {
+ dev_err(&pdev->dev, "Unable to get EPDC AXI clk."
+ "err = %d\n", (int)fb_data->epdc_clk_axi);
+ ret = -ENODEV;
+ goto out_dma_fb;
+ }
+ fb_data->epdc_clk_pix = clk_get(fb_data->dev, "epdc_pix");
+ if (IS_ERR(fb_data->epdc_clk_pix)) {
+ dev_err(&pdev->dev, "Unable to get EPDC pix clk."
+ "err = %d\n", (int)fb_data->epdc_clk_pix);
+ ret = -ENODEV;
+ goto out_dma_fb;
+ }
+
+ clk_prepare_enable(fb_data->epdc_clk_axi);
+ val = __raw_readl(EPDC_VERSION);
+ clk_disable_unprepare(fb_data->epdc_clk_axi);
+ fb_data->rev = ((val & EPDC_VERSION_MAJOR_MASK) >>
+ EPDC_VERSION_MAJOR_OFFSET) * 10
+ + ((val & EPDC_VERSION_MINOR_MASK) >>
+ EPDC_VERSION_MINOR_OFFSET);
+ dev_dbg(&pdev->dev, "EPDC version = %d\n", fb_data->rev);
+
+ if (fb_data->rev < 20) {
+ fb_data->num_luts = EPDC_V1_NUM_LUTS;
+ fb_data->max_num_updates = EPDC_V1_MAX_NUM_UPDATES;
+ } else {
+ fb_data->num_luts = EPDC_V2_NUM_LUTS;
+ fb_data->max_num_updates = EPDC_V2_MAX_NUM_UPDATES;
+ if (vmode->xres > EPDC_V2_MAX_UPDATE_WIDTH)
+ fb_data->restrict_width = true;
+ }
+ fb_data->max_num_buffers = EPDC_MAX_NUM_BUFFERS;
+
+ /*
+ * Initialize lists for pending updates,
+ * active update requests, update collisions,
+ * and freely available updates.
+ */
+ INIT_LIST_HEAD(&fb_data->upd_pending_list);
+ INIT_LIST_HEAD(&fb_data->upd_buf_queue);
+ INIT_LIST_HEAD(&fb_data->upd_buf_free_list);
+ INIT_LIST_HEAD(&fb_data->upd_buf_collision_list);
+
+ /* Allocate update buffers and add them to the list */
+ for (i = 0; i < fb_data->max_num_updates; i++) {
+ upd_list = kzalloc(sizeof(*upd_list), GFP_KERNEL);
+ if (upd_list == NULL) {
+ ret = -ENOMEM;
+ goto out_upd_lists;
+ }
+
+ /* Add newly allocated buffer to free list */
+ list_add(&upd_list->list, &fb_data->upd_buf_free_list);
+ }
+
+ fb_data->virt_addr_updbuf =
+ kzalloc(sizeof(void *) * fb_data->max_num_buffers, GFP_KERNEL);
+ fb_data->phys_addr_updbuf =
+ kzalloc(sizeof(dma_addr_t) * fb_data->max_num_buffers,
+ GFP_KERNEL);
+ for (i = 0; i < fb_data->max_num_buffers; i++) {
+ /*
+ * Allocate memory for PxP output buffer.
+ * Each update buffer is 1 byte per pixel, and can
+ * be as big as the full-screen frame buffer
+ */
+ fb_data->virt_addr_updbuf[i] =
+ kmalloc(fb_data->max_pix_size, GFP_KERNEL);
+ fb_data->phys_addr_updbuf[i] =
+ virt_to_phys(fb_data->virt_addr_updbuf[i]);
+ if (fb_data->virt_addr_updbuf[i] == NULL) {
+ ret = -ENOMEM;
+ goto out_upd_buffers;
+ }
+
+ dev_dbg(fb_data->info.device, "allocated %d bytes @ 0x%08X\n",
+ fb_data->max_pix_size, fb_data->phys_addr_updbuf[i]);
+ }
+
+ /* Counter indicating which update buffer should be used next. */
+ fb_data->upd_buffer_num = 0;
+
+ /*
+ * Allocate memory for PxP SW workaround buffer
+ * These buffers are used to hold copy of the update region,
+ * before sending it to PxP for processing.
+ */
+ fb_data->virt_addr_copybuf =
+ dma_alloc_coherent(fb_data->info.device, fb_data->max_pix_size*2,
+ &fb_data->phys_addr_copybuf,
+ GFP_DMA | GFP_KERNEL);
+ if (fb_data->virt_addr_copybuf == NULL) {
+ ret = -ENOMEM;
+ goto out_upd_buffers;
+ }
+
+ fb_data->working_buffer_size = vmode->yres * vmode->xres * 2;
+ /* Allocate memory for EPDC working buffer */
+ fb_data->working_buffer_virt =
+ dma_alloc_coherent(&pdev->dev, fb_data->working_buffer_size,
+ &fb_data->working_buffer_phys,
+ GFP_DMA | GFP_KERNEL);
+ if (fb_data->working_buffer_virt == NULL) {
+ dev_err(&pdev->dev, "Can't allocate mem for working buf!\n");
+ ret = -ENOMEM;
+ goto out_copybuffer;
+ }
+
+ /* Initialize EPDC pins */
+ pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
+ if (IS_ERR(pinctrl)) {
+ dev_err(&pdev->dev, "can't get/select pinctrl\n");
+ ret = PTR_ERR(pinctrl);
+ goto out_copybuffer;
+ }
+
+ fb_data->in_init = false;
+
+ fb_data->hw_ready = false;
+ fb_data->hw_initializing = false;
+
+ /*
+ * Set default waveform mode values.
+ * Should be overwritten via ioctl.
+ */
+ fb_data->wv_modes.mode_init = 0;
+ fb_data->wv_modes.mode_du = 1;
+ fb_data->wv_modes.mode_gc4 = 3;
+ fb_data->wv_modes.mode_gc8 = 2;
+ fb_data->wv_modes.mode_gc16 = 2;
+ fb_data->wv_modes.mode_gc32 = 2;
+ fb_data->wv_modes_update = true;
+
+ /* Initialize marker list */
+ INIT_LIST_HEAD(&fb_data->full_marker_list);
+
+ /* Initialize all LUTs to inactive */
+ fb_data->lut_update_order =
+ kzalloc(fb_data->num_luts * sizeof(u32 *), GFP_KERNEL);
+ for (i = 0; i < fb_data->num_luts; i++)
+ fb_data->lut_update_order[i] = 0;
+
+ INIT_DELAYED_WORK(&fb_data->epdc_done_work, epdc_done_work_func);
+ fb_data->epdc_submit_workqueue = alloc_workqueue("EPDC Submit",
+ WQ_MEM_RECLAIM | WQ_HIGHPRI |
+ WQ_CPU_INTENSIVE | WQ_UNBOUND, 1);
+ INIT_WORK(&fb_data->epdc_submit_work, epdc_submit_work_func);
+ fb_data->epdc_intr_workqueue = alloc_workqueue("EPDC Interrupt",
+ WQ_MEM_RECLAIM | WQ_HIGHPRI |
+ WQ_CPU_INTENSIVE | WQ_UNBOUND, 1);
+ INIT_WORK(&fb_data->epdc_intr_work, epdc_intr_work_func);
+
+ /* Retrieve EPDC IRQ num */
+ irq = platform_get_irq(pdev, 0);
+ if (irq < 0) {
+ dev_err(&pdev->dev, "cannot get IRQ resource\n");
+ ret = -ENODEV;
+ goto out_dma_work_buf;
+ }
+ fb_data->epdc_irq = irq;
+
+ /* Register IRQ handler */
+ ret = devm_request_irq(&pdev->dev, fb_data->epdc_irq,
+ mxc_epdc_irq_handler, 0, "epdc", fb_data);
+ if (ret) {
+ dev_err(&pdev->dev, "request_irq (%d) failed with error %d\n",
+ fb_data->epdc_irq, ret);
+ ret = -ENODEV;
+ goto out_dma_work_buf;
+ }
+
+ info->fbdefio = &mxc_epdc_fb_defio;
+#ifdef CONFIG_FB_MXC_EINK_AUTO_UPDATE_MODE
+ fb_deferred_io_init(info);
+#endif
+
+ /* get pmic regulators */
+ fb_data->display_regulator = devm_regulator_get(&pdev->dev, "DISPLAY");
+ if (IS_ERR(fb_data->display_regulator)) {
+ dev_err(&pdev->dev, "Unable to get display PMIC regulator."
+ "err = 0x%x\n", (int)fb_data->display_regulator);
+ ret = -ENODEV;
+ goto out_dma_work_buf;
+ }
+ fb_data->vcom_regulator = devm_regulator_get(&pdev->dev, "VCOM");
+ if (IS_ERR(fb_data->vcom_regulator)) {
+ dev_err(&pdev->dev, "Unable to get VCOM regulator."
+ "err = 0x%x\n", (int)fb_data->vcom_regulator);
+ ret = -ENODEV;
+ goto out_dma_work_buf;
+ }
+ fb_data->v3p3_regulator = devm_regulator_get(&pdev->dev, "V3P3");
+ if (IS_ERR(fb_data->v3p3_regulator)) {
+ dev_err(&pdev->dev, "Unable to get V3P3 regulator."
+ "err = 0x%x\n", (int)fb_data->vcom_regulator);
+ ret = -ENODEV;
+ goto out_dma_work_buf;
+ }
+
+ if (device_create_file(info->dev, &fb_attrs[0]))
+ dev_err(&pdev->dev, "Unable to create file from fb_attrs\n");
+
+ fb_data->cur_update = NULL;
+
+ mutex_init(&fb_data->queue_mutex);
+ mutex_init(&fb_data->pxp_mutex);
+ mutex_init(&fb_data->power_mutex);
+
+ /*
+ * Fill out PxP config data structure based on FB info and
+ * processing tasks required
+ */
+ pxp_conf = &fb_data->pxp_conf;
+ proc_data = &pxp_conf->proc_data;
+
+ /* Initialize non-channel-specific PxP parameters */
+ proc_data->drect.left = proc_data->srect.left = 0;
+ proc_data->drect.top = proc_data->srect.top = 0;
+ proc_data->drect.width = proc_data->srect.width = fb_data->info.var.xres;
+ proc_data->drect.height = proc_data->srect.height = fb_data->info.var.yres;
+ proc_data->scaling = 0;
+ proc_data->hflip = 0;
+ proc_data->vflip = 0;
+ proc_data->rotate = 0;
+ proc_data->bgcolor = 0;
+ proc_data->overlay_state = 0;
+ proc_data->lut_transform = PXP_LUT_NONE;
+ proc_data->lut_map = NULL;
+
+ /*
+ * We initially configure PxP for RGB->YUV conversion,
+ * and only write out Y component of the result.
+ */
+
+ /*
+ * Initialize S0 channel parameters
+ * Parameters should match FB format/width/height
+ */
+ pxp_conf->s0_param.pixel_fmt = PXP_PIX_FMT_RGB565;
+ pxp_conf->s0_param.width = fb_data->info.var.xres_virtual;
+ pxp_conf->s0_param.height = fb_data->info.var.yres;
+ pxp_conf->s0_param.color_key = -1;
+ pxp_conf->s0_param.color_key_enable = false;
+
+ /*
+ * Initialize OL0 channel parameters
+ * No overlay will be used for PxP operation
+ */
+ pxp_conf->ol_param[0].combine_enable = false;
+ pxp_conf->ol_param[0].width = 0;
+ pxp_conf->ol_param[0].height = 0;
+ pxp_conf->ol_param[0].pixel_fmt = PXP_PIX_FMT_RGB565;
+ pxp_conf->ol_param[0].color_key_enable = false;
+ pxp_conf->ol_param[0].color_key = -1;
+ pxp_conf->ol_param[0].global_alpha_enable = false;
+ pxp_conf->ol_param[0].global_alpha = 0;
+ pxp_conf->ol_param[0].local_alpha_enable = false;
+
+ /*
+ * Initialize Output channel parameters
+ * Output is Y-only greyscale
+ * Output width/height will vary based on update region size
+ */
+ pxp_conf->out_param.width = fb_data->info.var.xres;
+ pxp_conf->out_param.height = fb_data->info.var.yres;
+ pxp_conf->out_param.stride = pxp_conf->out_param.width;
+ pxp_conf->out_param.pixel_fmt = PXP_PIX_FMT_GREY;
+
+ /* Initialize color map for conversion of 8-bit gray pixels */
+ fb_data->pxp_conf.proc_data.lut_map = kmalloc(256, GFP_KERNEL);
+ if (fb_data->pxp_conf.proc_data.lut_map == NULL) {
+ dev_err(&pdev->dev, "Can't allocate mem for lut map!\n");
+ ret = -ENOMEM;
+ goto out_dma_work_buf;
+ }
+ for (i = 0; i < 256; i++)
+ fb_data->pxp_conf.proc_data.lut_map[i] = i;
+
+ fb_data->pxp_conf.proc_data.lut_map_updated = true;
+
+ /*
+ * Ensure this is set to NULL here...we will initialize pxp_chan
+ * later in our thread.
+ */
+ fb_data->pxp_chan = NULL;
+
+ /* Initialize Scatter-gather list containing 2 buffer addresses. */
+ sg = fb_data->sg;
+ sg_init_table(sg, 2);
+
+ /*
+ * For use in PxP transfers:
+ * sg[0] holds the FB buffer pointer
+ * sg[1] holds the Output buffer pointer (configured before TX request)
+ */
+ sg_dma_address(&sg[0]) = info->fix.smem_start;
+ sg_set_page(&sg[0], virt_to_page(info->screen_base),
+ info->fix.smem_len, offset_in_page(info->screen_base));
+
+ fb_data->order_cnt = 0;
+ fb_data->waiting_for_wb = false;
+ fb_data->waiting_for_lut = false;
+ fb_data->waiting_for_lut15 = false;
+ fb_data->waiting_for_idle = false;
+ fb_data->blank = FB_BLANK_UNBLANK;
+ fb_data->power_state = POWER_STATE_OFF;
+ fb_data->powering_down = false;
+ fb_data->wait_for_powerdown = false;
+ fb_data->updates_active = false;
+ fb_data->pwrdown_delay = 0;
+
+ /* Register FB */
+ ret = register_framebuffer(info);
+ if (ret) {
+ dev_err(&pdev->dev,
+ "register_framebuffer failed with error %d\n", ret);
+ goto out_lutmap;
+ }
+
+ g_fb_data = fb_data;
+
+ pm_runtime_enable(fb_data->dev);
+
+#ifdef DEFAULT_PANEL_HW_INIT
+ ret = mxc_epdc_fb_init_hw((struct fb_info *)fb_data);
+ if (ret) {
+ dev_err(&pdev->dev, "Failed to initialize HW!\n");
+ }
+#endif
+
+ goto out;
+
+out_lutmap:
+ kfree(fb_data->pxp_conf.proc_data.lut_map);
+out_dma_work_buf:
+ dma_free_writecombine(&pdev->dev, fb_data->working_buffer_size,
+ fb_data->working_buffer_virt, fb_data->working_buffer_phys);
+out_copybuffer:
+ dma_free_writecombine(&pdev->dev, fb_data->max_pix_size*2,
+ fb_data->virt_addr_copybuf,
+ fb_data->phys_addr_copybuf);
+out_upd_buffers:
+ for (i = 0; i < fb_data->max_num_buffers; i++)
+ if (fb_data->virt_addr_updbuf[i] != NULL)
+ kfree(fb_data->virt_addr_updbuf[i]);
+ if (fb_data->virt_addr_updbuf != NULL)
+ kfree(fb_data->virt_addr_updbuf);
+ if (fb_data->phys_addr_updbuf != NULL)
+ kfree(fb_data->phys_addr_updbuf);
+out_upd_lists:
+ list_for_each_entry_safe(plist, temp_list, &fb_data->upd_buf_free_list,
+ list) {
+ list_del(&plist->list);
+ kfree(plist);
+ }
+out_dma_fb:
+ dma_free_writecombine(&pdev->dev, fb_data->map_size, info->screen_base,
+ fb_data->phys_start);
+
+out_cmap:
+ fb_dealloc_cmap(&info->cmap);
+out_fbdata:
+ kfree(fb_data);
+out:
+ return ret;
+}
+
+static int mxc_epdc_fb_remove(struct platform_device *pdev)
+{
+ struct update_data_list *plist, *temp_list;
+ struct mxc_epdc_fb_data *fb_data = platform_get_drvdata(pdev);
+ int i;
+
+ mxc_epdc_fb_blank(FB_BLANK_POWERDOWN, &fb_data->info);
+
+ flush_workqueue(fb_data->epdc_submit_workqueue);
+ destroy_workqueue(fb_data->epdc_submit_workqueue);
+
+ unregister_framebuffer(&fb_data->info);
+
+ for (i = 0; i < fb_data->max_num_buffers; i++)
+ if (fb_data->virt_addr_updbuf[i] != NULL)
+ kfree(fb_data->virt_addr_updbuf[i]);
+ if (fb_data->virt_addr_updbuf != NULL)
+ kfree(fb_data->virt_addr_updbuf);
+ if (fb_data->phys_addr_updbuf != NULL)
+ kfree(fb_data->phys_addr_updbuf);
+
+ dma_free_writecombine(&pdev->dev, fb_data->working_buffer_size,
+ fb_data->working_buffer_virt,
+ fb_data->working_buffer_phys);
+ if (fb_data->waveform_buffer_virt != NULL)
+ dma_free_writecombine(&pdev->dev, fb_data->waveform_buffer_size,
+ fb_data->waveform_buffer_virt,
+ fb_data->waveform_buffer_phys);
+ if (fb_data->virt_addr_copybuf != NULL)
+ dma_free_writecombine(&pdev->dev, fb_data->max_pix_size*2,
+ fb_data->virt_addr_copybuf,
+ fb_data->phys_addr_copybuf);
+ list_for_each_entry_safe(plist, temp_list, &fb_data->upd_buf_free_list,
+ list) {
+ list_del(&plist->list);
+ kfree(plist);
+ }
+#ifdef CONFIG_FB_MXC_EINK_AUTO_UPDATE_MODE
+ fb_deferred_io_cleanup(&fb_data->info);
+#endif
+
+ dma_free_writecombine(&pdev->dev, fb_data->map_size, fb_data->info.screen_base,
+ fb_data->phys_start);
+
+ /* Release PxP-related resources */
+ if (fb_data->pxp_chan != NULL)
+ dma_release_channel(&fb_data->pxp_chan->dma_chan);
+
+ fb_dealloc_cmap(&fb_data->info.cmap);
+
+ framebuffer_release(&fb_data->info);
+ platform_set_drvdata(pdev, NULL);
+
+ return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int mxc_epdc_fb_suspend(struct device *dev)
+{
+ struct mxc_epdc_fb_data *data = dev_get_drvdata(dev);
+ int ret;
+
+ data->pwrdown_delay = FB_POWERDOWN_DISABLE;
+ ret = mxc_epdc_fb_blank(FB_BLANK_POWERDOWN, &data->info);
+ if (ret)
+ goto out;
+
+out:
+ return ret;
+}
+
+static int mxc_epdc_fb_resume(struct device *dev)
+{
+ struct mxc_epdc_fb_data *data = dev_get_drvdata(dev);
+
+ mxc_epdc_fb_blank(FB_BLANK_UNBLANK, &data->info);
+ epdc_init_settings(data);
+ data->updates_active = false;
+
+ return 0;
+}
+#else
+#define mxc_epdc_fb_suspend NULL
+#define mxc_epdc_fb_resume NULL
+#endif
+
+#ifdef CONFIG_PM
+static int mxc_epdc_fb_runtime_suspend(struct device *dev)
+{
+ release_bus_freq(BUS_FREQ_HIGH);
+ dev_dbg(dev, "epdc busfreq high release.\n");
+
+ return 0;
+}
+
+static int mxc_epdc_fb_runtime_resume(struct device *dev)
+{
+ request_bus_freq(BUS_FREQ_HIGH);
+ dev_dbg(dev, "epdc busfreq high request.\n");
+
+ return 0;
+}
+#else
+#define mxc_epdc_fb_runtime_suspend NULL
+#define mxc_epdc_fb_runtime_resume NULL
+#endif
+
+static const struct dev_pm_ops mxc_epdc_fb_pm_ops = {
+ SET_RUNTIME_PM_OPS(mxc_epdc_fb_runtime_suspend,
+ mxc_epdc_fb_runtime_resume, NULL)
+ SET_SYSTEM_SLEEP_PM_OPS(mxc_epdc_fb_suspend, mxc_epdc_fb_resume)
+};
+
+static void mxc_epdc_fb_shutdown(struct platform_device *pdev)
+{
+ struct mxc_epdc_fb_data *fb_data = platform_get_drvdata(pdev);
+
+ /* Disable power to the EPD panel */
+ if (regulator_is_enabled(fb_data->vcom_regulator))
+ regulator_disable(fb_data->vcom_regulator);
+ if (regulator_is_enabled(fb_data->display_regulator))
+ regulator_disable(fb_data->display_regulator);
+
+ /* Disable clocks to EPDC */
+ clk_prepare_enable(fb_data->epdc_clk_axi);
+ clk_prepare_enable(fb_data->epdc_clk_pix);
+ __raw_writel(EPDC_CTRL_CLKGATE, EPDC_CTRL_SET);
+ clk_disable_unprepare(fb_data->epdc_clk_pix);
+ clk_disable_unprepare(fb_data->epdc_clk_axi);
+
+ /* turn off the V3p3 */
+ if (regulator_is_enabled(fb_data->v3p3_regulator))
+ regulator_disable(fb_data->v3p3_regulator);
+}
+
+static struct platform_driver mxc_epdc_fb_driver = {
+ .probe = mxc_epdc_fb_probe,
+ .remove = mxc_epdc_fb_remove,
+ .shutdown = mxc_epdc_fb_shutdown,
+ .driver = {
+ .name = "imx_epdc_fb",
+ .owner = THIS_MODULE,
+ .of_match_table = of_match_ptr(imx_epdc_dt_ids),
+ .pm = &mxc_epdc_fb_pm_ops,
+ },
+};
+
+/* Callback function triggered after PxP receives an EOF interrupt */
+static void pxp_dma_done(void *arg)
+{
+ struct pxp_tx_desc *tx_desc = to_tx_desc(arg);
+ struct dma_chan *chan = tx_desc->txd.chan;
+ struct pxp_channel *pxp_chan = to_pxp_channel(chan);
+ struct mxc_epdc_fb_data *fb_data = pxp_chan->client;
+
+ /* This call will signal wait_for_completion_timeout() in send_buffer_to_pxp */
+ complete(&fb_data->pxp_tx_cmpl);
+}
+
+static bool chan_filter(struct dma_chan *chan, void *arg)
+{
+ if (imx_dma_is_pxp(chan))
+ return true;
+ else
+ return false;
+}
+
+/* Function to request PXP DMA channel */
+static int pxp_chan_init(struct mxc_epdc_fb_data *fb_data)
+{
+ dma_cap_mask_t mask;
+ struct dma_chan *chan;
+
+ /*
+ * Request a free channel
+ */
+ dma_cap_zero(mask);
+ dma_cap_set(DMA_SLAVE, mask);
+ dma_cap_set(DMA_PRIVATE, mask);
+ chan = dma_request_channel(mask, chan_filter, NULL);
+ if (!chan) {
+ dev_err(fb_data->dev, "Unsuccessfully received channel!!!!\n");
+ return -EBUSY;
+ }
+
+ fb_data->pxp_chan = to_pxp_channel(chan);
+ fb_data->pxp_chan->client = fb_data;
+
+ init_completion(&fb_data->pxp_tx_cmpl);
+
+ return 0;
+}
+
+/*
+ * Function to call PxP DMA driver and send our latest FB update region
+ * through the PxP and out to an intermediate buffer.
+ * Note: This is a blocking call, so upon return the PxP tx should be complete.
+ */
+static int pxp_process_update(struct mxc_epdc_fb_data *fb_data,
+ u32 src_width, u32 src_height,
+ struct mxcfb_rect *update_region)
+{
+ dma_cookie_t cookie;
+ struct scatterlist *sg = fb_data->sg;
+ struct dma_chan *dma_chan;
+ struct pxp_tx_desc *desc;
+ struct dma_async_tx_descriptor *txd;
+ struct pxp_config_data *pxp_conf = &fb_data->pxp_conf;
+ struct pxp_proc_data *proc_data = &fb_data->pxp_conf.proc_data;
+ int i, ret;
+ int length;
+
+ dev_dbg(fb_data->dev, "Starting PxP Send Buffer\n");
+
+ /* First, check to see that we have acquired a PxP Channel object */
+ if (fb_data->pxp_chan == NULL) {
+ /*
+ * PxP Channel has not yet been created and initialized,
+ * so let's go ahead and try
+ */
+ ret = pxp_chan_init(fb_data);
+ if (ret) {
+ /*
+ * PxP channel init failed, and we can't use the
+ * PxP until the PxP DMA driver has loaded, so we abort
+ */
+ dev_err(fb_data->dev, "PxP chan init failed\n");
+ return -ENODEV;
+ }
+ }
+
+ /*
+ * Init completion, so that we
+ * can be properly informed of the completion
+ * of the PxP task when it is done.
+ */
+ init_completion(&fb_data->pxp_tx_cmpl);
+
+ dma_chan = &fb_data->pxp_chan->dma_chan;
+
+ txd = dma_chan->device->device_prep_slave_sg(dma_chan, sg, 2,
+ DMA_TO_DEVICE,
+ DMA_PREP_INTERRUPT,
+ NULL);
+ if (!txd) {
+ dev_err(fb_data->info.device,
+ "Error preparing a DMA transaction descriptor.\n");
+ return -EIO;
+ }
+
+ txd->callback_param = txd;
+ txd->callback = pxp_dma_done;
+
+ /*
+ * Configure PxP for processing of new update region
+ * The rest of our config params were set up in
+ * probe() and should not need to be changed.
+ */
+ pxp_conf->s0_param.width = src_width;
+ pxp_conf->s0_param.height = src_height;
+ proc_data->srect.top = update_region->top;
+ proc_data->srect.left = update_region->left;
+ proc_data->srect.width = update_region->width;
+ proc_data->srect.height = update_region->height;
+
+ /*
+ * Because only YUV/YCbCr image can be scaled, configure
+ * drect equivalent to srect, as such do not perform scaling.
+ */
+ proc_data->drect.top = 0;
+ proc_data->drect.left = 0;
+
+ /* PXP expects rotation in terms of degrees */
+ proc_data->rotate = fb_data->epdc_fb_var.rotate * 90;
+ if (proc_data->rotate > 270)
+ proc_data->rotate = 0;
+
+ /* Just as V4L2 PXP, we should pass the rotated values to PXP */
+ if ((proc_data->rotate == 90) || (proc_data->rotate == 270)) {
+ proc_data->drect.width = proc_data->srect.height;
+ proc_data->drect.height = proc_data->srect.width;
+ pxp_conf->out_param.width = update_region->height;
+ pxp_conf->out_param.height = update_region->width;
+ pxp_conf->out_param.stride = update_region->height;
+ } else {
+ proc_data->drect.width = proc_data->srect.width;
+ proc_data->drect.height = proc_data->srect.height;
+ pxp_conf->out_param.width = update_region->width;
+ pxp_conf->out_param.height = update_region->height;
+ pxp_conf->out_param.stride = update_region->width;
+ }
+
+ /* For EPDC v2.0, we need output to be 64-bit
+ * aligned since EPDC stride does not work. */
+ if (fb_data->rev <= 20)
+ pxp_conf->out_param.stride = ALIGN(pxp_conf->out_param.stride, 8);
+
+
+ desc = to_tx_desc(txd);
+ length = desc->len;
+ for (i = 0; i < length; i++) {
+ if (i == 0) {/* S0 */
+ memcpy(&desc->proc_data, proc_data, sizeof(struct pxp_proc_data));
+ pxp_conf->s0_param.paddr = sg_dma_address(&sg[0]);
+ memcpy(&desc->layer_param.s0_param, &pxp_conf->s0_param,
+ sizeof(struct pxp_layer_param));
+ } else if (i == 1) {
+ pxp_conf->out_param.paddr = sg_dma_address(&sg[1]);
+ memcpy(&desc->layer_param.out_param, &pxp_conf->out_param,
+ sizeof(struct pxp_layer_param));
+ }
+ /* TODO: OverLay */
+
+ desc = desc->next;
+ }
+
+ /* Submitting our TX starts the PxP processing task */
+ cookie = txd->tx_submit(txd);
+ if (cookie < 0) {
+ dev_err(fb_data->info.device, "Error sending FB through PxP\n");
+ return -EIO;
+ }
+
+ fb_data->txd = txd;
+
+ /* trigger ePxP */
+ dma_async_issue_pending(dma_chan);
+
+ return 0;
+}
+
+static int pxp_complete_update(struct mxc_epdc_fb_data *fb_data, u32 *hist_stat)
+{
+ int ret;
+ /*
+ * Wait for completion event, which will be set
+ * through our TX callback function.
+ */
+ ret = wait_for_completion_timeout(&fb_data->pxp_tx_cmpl, HZ / 10);
+ if (ret <= 0) {
+ dev_info(fb_data->info.device,
+ "PxP operation failed due to %s\n",
+ ret < 0 ? "user interrupt" : "timeout");
+ dma_release_channel(&fb_data->pxp_chan->dma_chan);
+ fb_data->pxp_chan = NULL;
+ return ret ? : -ETIMEDOUT;
+ }
+
+ if ((fb_data->pxp_conf.proc_data.lut_transform & EPDC_FLAG_USE_CMAP) &&
+ fb_data->pxp_conf.proc_data.lut_map_updated)
+ fb_data->pxp_conf.proc_data.lut_map_updated = false;
+
+ *hist_stat = to_tx_desc(fb_data->txd)->hist_status;
+ dma_release_channel(&fb_data->pxp_chan->dma_chan);
+ fb_data->pxp_chan = NULL;
+
+ dev_dbg(fb_data->dev, "TX completed\n");
+
+ return 0;
+}
+
+/*
+ * Different dithering algorithm can be used. We chose
+ * to implement Bill Atkinson's algorithm as an example
+ * Thanks Bill Atkinson for his dithering algorithm.
+ */
+
+/*
+ * Dithering algorithm implementation - Y8->Y1 version 1.0 for i.MX
+ */
+static void do_dithering_processing_Y1_v1_0(
+ unsigned char *update_region_virt_ptr,
+ dma_addr_t update_region_phys_ptr,
+ struct mxcfb_rect *update_region,
+ unsigned long update_region_stride,
+ int *err_dist)
+{
+
+ /* create a temp error distribution array */
+ int bwPix;
+ int y;
+ int col;
+ int *err_dist_l0, *err_dist_l1, *err_dist_l2, distrib_error;
+ int width_3 = update_region->width + 3;
+ char *y8buf;
+ int x_offset = 0;
+
+ /* prime a few elements the error distribution array */
+ for (y = 0; y < update_region->height; y++) {
+ /* Dithering the Y8 in sbuf to BW suitable for A2 waveform */
+ err_dist_l0 = err_dist + (width_3) * (y % 3);
+ err_dist_l1 = err_dist + (width_3) * ((y + 1) % 3);
+ err_dist_l2 = err_dist + (width_3) * ((y + 2) % 3);
+
+ y8buf = update_region_virt_ptr + x_offset;
+
+ /* scan the line and convert the Y8 to BW */
+ for (col = 1; col <= update_region->width; col++) {
+ bwPix = *(err_dist_l0 + col) + *y8buf;
+
+ if (bwPix >= 128) {
+ *y8buf++ = 0xff;
+ distrib_error = (bwPix - 255) >> 3;
+ } else {
+ *y8buf++ = 0;
+ distrib_error = bwPix >> 3;
+ }
+
+ /* modify the error distribution buffer */
+ *(err_dist_l0 + col + 2) += distrib_error;
+ *(err_dist_l1 + col + 1) += distrib_error;
+ *(err_dist_l0 + col + 1) += distrib_error;
+ *(err_dist_l1 + col - 1) += distrib_error;
+ *(err_dist_l1 + col) += distrib_error;
+ *(err_dist_l2 + col) = distrib_error;
+ }
+ x_offset += update_region_stride;
+ }
+
+ flush_cache_all();
+ outer_flush_range(update_region_phys_ptr, update_region_phys_ptr +
+ update_region->height * update_region->width);
+}
+
+/*
+ * Dithering algorithm implementation - Y8->Y4 version 1.0 for i.MX
+ */
+
+static void do_dithering_processing_Y4_v1_0(
+ unsigned char *update_region_virt_ptr,
+ dma_addr_t update_region_phys_ptr,
+ struct mxcfb_rect *update_region,
+ unsigned long update_region_stride,
+ int *err_dist)
+{
+
+ /* create a temp error distribution array */
+ int gcPix;
+ int y;
+ int col;
+ int *err_dist_l0, *err_dist_l1, *err_dist_l2, distrib_error;
+ int width_3 = update_region->width + 3;
+ char *y8buf;
+ int x_offset = 0;
+
+ /* prime a few elements the error distribution array */
+ for (y = 0; y < update_region->height; y++) {
+ /* Dithering the Y8 in sbuf to Y4 */
+ err_dist_l0 = err_dist + (width_3) * (y % 3);
+ err_dist_l1 = err_dist + (width_3) * ((y + 1) % 3);
+ err_dist_l2 = err_dist + (width_3) * ((y + 2) % 3);
+
+ y8buf = update_region_virt_ptr + x_offset;
+
+ /* scan the line and convert the Y8 to Y4 */
+ for (col = 1; col <= update_region->width; col++) {
+ gcPix = *(err_dist_l0 + col) + *y8buf;
+
+ if (gcPix > 255)
+ gcPix = 255;
+ else if (gcPix < 0)
+ gcPix = 0;
+
+ distrib_error = (*y8buf - (gcPix & 0xf0)) >> 3;
+
+ *y8buf++ = gcPix & 0xf0;
+
+ /* modify the error distribution buffer */
+ *(err_dist_l0 + col + 2) += distrib_error;
+ *(err_dist_l1 + col + 1) += distrib_error;
+ *(err_dist_l0 + col + 1) += distrib_error;
+ *(err_dist_l1 + col - 1) += distrib_error;
+ *(err_dist_l1 + col) += distrib_error;
+ *(err_dist_l2 + col) = distrib_error;
+ }
+ x_offset += update_region_stride;
+ }
+
+ flush_cache_all();
+ outer_flush_range(update_region_phys_ptr, update_region_phys_ptr +
+ update_region->height * update_region->width);
+}
+
+static int __init mxc_epdc_fb_init(void)
+{
+ return platform_driver_register(&mxc_epdc_fb_driver);
+}
+late_initcall(mxc_epdc_fb_init);
+
+static void __exit mxc_epdc_fb_exit(void)
+{
+ platform_driver_unregister(&mxc_epdc_fb_driver);
+}
+module_exit(mxc_epdc_fb_exit);
+
+
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("MXC EPDC framebuffer driver");
+MODULE_LICENSE("GPL");
+MODULE_SUPPORTED_DEVICE("fb");
diff --git a/drivers/video/fbdev/mxc/mxc_epdc_v2_fb.c b/drivers/video/fbdev/mxc/mxc_epdc_v2_fb.c
new file mode 100644
index 000000000000..cd8d49adbf14
--- /dev/null
+++ b/drivers/video/fbdev/mxc/mxc_epdc_v2_fb.c
@@ -0,0 +1,6879 @@
+/*
+ * Copyright (C) 2014-2016 Freescale Semiconductor, Inc.
+ * Copyright 2017 NXP
+ *
+ * Copyright 2017 NXP
+ *
+ * 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
+ *
+ */
+/*
+ * Based on STMP378X LCDIF
+ * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved.
+ */
+
+#include <linux/busfreq-imx.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/input.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/fb.h>
+#include <linux/init.h>
+#include <linux/list.h>
+#include <linux/mutex.h>
+#include <linux/delay.h>
+#include <linux/dma-mapping.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/uaccess.h>
+#include <linux/cpufreq.h>
+#include <linux/firmware.h>
+#include <linux/kthread.h>
+#include <linux/dmaengine.h>
+#include <linux/pxp_dma.h>
+#include <linux/pm_runtime.h>
+#include <linux/mxcfb.h>
+#include <linux/mxcfb_epdc.h>
+#include <linux/gpio.h>
+#include <linux/of_gpio.h>
+#include <linux/mfd/syscon.h>
+#include <linux/regmap.h>
+#include <linux/regulator/driver.h>
+#include <linux/mfd/max17135.h>
+#include <linux/fsl_devices.h>
+#include <linux/bitops.h>
+#include <linux/pinctrl/consumer.h>
+#include <linux/platform_data/dma-imx.h>
+#include <asm/cacheflush.h>
+
+#include "epdc_v2_regs.h"
+
+#define EPDC_STANDARD_MODE
+
+#define USE_PS_AS_OUTPUT
+
+/*
+ * Enable this define to have a default panel
+ * loaded during driver initialization
+ */
+/*#define DEFAULT_PANEL_HW_INIT*/
+
+#define SG_NUM 14 /* 2+4+4+4 */
+#define NUM_SCREENS_MIN 2
+
+#define EPDC_V1_NUM_LUTS 16
+#define EPDC_V1_MAX_NUM_UPDATES 20
+#define EPDC_V2_NUM_LUTS 64
+#define EPDC_V2_MAX_NUM_UPDATES 64
+#define EPDC_MAX_NUM_BUFFERS 2
+#define INVALID_LUT (-1)
+#define DRY_RUN_NO_LUT 100
+
+/* Maximum update buffer image width due to v2.0 and v2.1 errata ERR005313. */
+#define EPDC_V2_MAX_UPDATE_WIDTH 2047
+#define EPDC_V2_ROTATION_ALIGNMENT 8
+
+#define DEFAULT_TEMP_INDEX 0
+#define DEFAULT_TEMP 20 /* room temp in deg Celsius */
+
+#define INIT_UPDATE_MARKER 0x12345678
+#define PAN_UPDATE_MARKER 0x12345679
+
+#define POWER_STATE_OFF 0
+#define POWER_STATE_ON 1
+
+#define MERGE_OK 0
+#define MERGE_FAIL 1
+#define MERGE_BLOCK 2
+
+static u64 used_luts = 0x1; /* do not use LUT0 */
+static unsigned long default_bpp = 16;
+
+struct update_marker_data {
+ struct list_head full_list;
+ struct list_head upd_list;
+ u32 update_marker;
+ struct completion update_completion;
+ int lut_num;
+ bool collision_test;
+ bool waiting;
+};
+
+struct update_desc_list {
+ struct list_head list;
+ struct mxcfb_update_data upd_data;/* Update parameters */
+ u32 epdc_offs; /* Added to buffer ptr to resolve alignment */
+ u32 epdc_stride; /* Depends on rotation & whether we skip PxP */
+ struct list_head upd_marker_list; /* List of markers for this update */
+ u32 update_order; /* Numeric ordering value for update */
+};
+
+/* This structure represents a list node containing both
+ * a memory region allocated as an output buffer for the PxP
+ * update processing task, and the update description (mode, region, etc.) */
+struct update_data_list {
+ struct list_head list;
+ dma_addr_t phys_addr; /* Pointer to phys address of processed Y buf */
+ void *virt_addr;
+ struct update_desc_list *update_desc;
+ int lut_num; /* Assigned before update is processed into working buffer */
+ u64 collision_mask; /* Set when update creates collision */
+ /* Mask of the LUTs the update collides with */
+};
+
+struct mxc_epdc_fb_data {
+ struct fb_info info;
+ struct fb_var_screeninfo epdc_fb_var; /* Internal copy of screeninfo
+ so we can sync changes to it */
+ u32 pseudo_palette[16];
+ char fw_str[24];
+ struct list_head list;
+ struct imx_epdc_fb_mode *cur_mode;
+ struct imx_epdc_fb_platform_data *pdata;
+ int blank;
+ u32 max_pix_size;
+ ssize_t map_size;
+ dma_addr_t phys_start;
+ void *virt_start;
+ u32 fb_offset;
+ int default_bpp;
+ int native_width;
+ int native_height;
+ int num_screens;
+ int epdc_irq;
+ struct device *dev;
+ int power_state;
+ int wait_for_powerdown;
+ struct completion powerdown_compl;
+ struct clk *epdc_clk_axi;
+ struct clk *epdc_clk_pix;
+ struct regulator *display_regulator;
+ struct regulator *vcom_regulator;
+ struct regulator *v3p3_regulator;
+ bool fw_default_load;
+ int rev;
+
+ /* FB elements related to EPDC updates */
+ int num_luts;
+ int max_num_updates;
+ bool in_init;
+ bool hw_ready;
+ bool hw_initializing;
+ bool waiting_for_idle;
+ u32 auto_mode;
+ u32 upd_scheme;
+ struct list_head upd_pending_list;
+ struct list_head upd_buf_queue;
+ struct list_head upd_buf_free_list;
+ struct list_head upd_buf_collision_list;
+ struct update_data_list *cur_update;
+ struct mutex queue_mutex;
+ int trt_entries;
+ int temp_index;
+ u8 *temp_range_bounds;
+ struct mxcfb_waveform_modes wv_modes;
+ bool wv_modes_update;
+ bool waveform_is_advanced;
+ u32 *waveform_buffer_virt;
+ u32 waveform_buffer_phys;
+ u32 waveform_buffer_size;
+ u32 *working_buffer_virt;
+ u32 working_buffer_phys;
+ u32 working_buffer_size;
+ u32 *tmp_working_buffer_virt;
+ u32 tmp_working_buffer_phys;
+ dma_addr_t *phys_addr_updbuf;
+ void **virt_addr_updbuf;
+ u32 upd_buffer_num;
+ u32 max_num_buffers;
+ dma_addr_t phys_addr_copybuf; /* Phys address of copied update data */
+ void *virt_addr_copybuf; /* Used for PxP SW workaround */
+ dma_addr_t phys_addr_y4;
+ void *virt_addr_y4;
+ dma_addr_t phys_addr_y4c;
+ void *virt_addr_y4c;
+ dma_addr_t phys_addr_black;
+ void *virt_addr_black;
+ u32 order_cnt;
+ struct list_head full_marker_list;
+ u32 *lut_update_order; /* Array size = number of luts */
+ u64 epdc_colliding_luts;
+ u64 luts_complete_wb;
+ u64 luts_complete;
+ struct completion updates_done;
+ struct delayed_work epdc_done_work;
+ struct workqueue_struct *epdc_submit_workqueue;
+ struct work_struct epdc_submit_work;
+ struct workqueue_struct *epdc_intr_workqueue;
+ struct work_struct epdc_intr_work;
+ bool waiting_for_wb;
+ bool waiting_for_lut;
+ bool waiting_for_lut15;
+ struct completion update_res_free;
+ struct completion lut15_free;
+ struct completion eof_event;
+ int eof_sync_period;
+ struct mutex power_mutex;
+ bool powering_down;
+ bool updates_active;
+ int pwrdown_delay;
+ unsigned long tce_prevent;
+ bool restrict_width; /* work around rev >=2.0 width and
+ stride restriction */
+
+ /* FB elements related to PxP DMA */
+ struct completion pxp_tx_cmpl;
+ struct pxp_channel *pxp_chan;
+ struct pxp_config_data pxp_conf;
+ struct dma_async_tx_descriptor *txd;
+ dma_cookie_t cookie;
+ struct scatterlist sg[SG_NUM];
+ struct mutex pxp_mutex; /* protects access to PxP */
+
+ /* external mode or internal mode */
+ int epdc_wb_mode;
+ struct pxp_collision_info col_info;
+ u32 hist_status;
+
+ struct regmap *gpr;
+ u8 req_gpr;
+ u8 req_bit;
+
+ /* qos */
+ struct regmap *qos_regmap;
+};
+
+struct waveform_data_header {
+ unsigned int wi0;
+ unsigned int wi1;
+ unsigned int wi2;
+ unsigned int wi3;
+ unsigned int wi4;
+ unsigned int wi5;
+ unsigned int wi6;
+ unsigned int xwia:24;
+ unsigned int cs1:8;
+ unsigned int wmta:24;
+ unsigned int fvsn:8;
+ unsigned int luts:8;
+ unsigned int mc:8;
+ unsigned int trc:8;
+ unsigned int reserved0_0:8;
+ unsigned int eb:8;
+ unsigned int sb:8;
+ unsigned int reserved0_1:8;
+ unsigned int reserved0_2:8;
+ unsigned int reserved0_3:8;
+ unsigned int reserved0_4:8;
+ unsigned int reserved0_5:8;
+ unsigned int cs2:8;
+};
+
+struct mxcfb_waveform_data_file {
+ struct waveform_data_header wdh;
+ u32 *data; /* Temperature Range Table + Waveform Data */
+};
+
+#define WAVEFORM_HDR_LUT_ADVANCED_ALGO_MASK 0xc
+
+static struct fb_videomode ed060xh2c1mode = {
+ .name = "ED060XH2C1",
+ .refresh = 85,
+ .xres = 1024,
+ .yres = 758,
+ .pixclock = 40000000,
+ .left_margin = 12,
+ .right_margin = 76,
+ .upper_margin = 4,
+ .lower_margin = 5,
+ .hsync_len = 12,
+ .vsync_len = 2,
+ .sync = 0,
+ .vmode = FB_VMODE_NONINTERLACED,
+ .flag = 0,
+};
+
+static struct fb_videomode e60_v110_mode = {
+ .name = "E60_V110",
+ .refresh = 50,
+ .xres = 800,
+ .yres = 600,
+ .pixclock = 18604700,
+ .left_margin = 8,
+ .right_margin = 178,
+ .upper_margin = 4,
+ .lower_margin = 10,
+ .hsync_len = 20,
+ .vsync_len = 4,
+ .sync = 0,
+ .vmode = FB_VMODE_NONINTERLACED,
+ .flag = 0,
+};
+
+static struct fb_videomode e60_v220_mode = {
+ .name = "E60_V220",
+ .refresh = 85,
+ .xres = 800,
+ .yres = 600,
+ .pixclock = 30000000,
+ .left_margin = 8,
+ .right_margin = 164,
+ .upper_margin = 4,
+ .lower_margin = 8,
+ .hsync_len = 4,
+ .vsync_len = 1,
+ .sync = 0,
+ .vmode = FB_VMODE_NONINTERLACED,
+ .flag = 0,
+};
+
+static struct fb_videomode e060scm_mode = {
+ .name = "E060SCM",
+ .refresh = 85,
+ .xres = 800,
+ .yres = 600,
+ .pixclock = 26666667,
+ .left_margin = 8,
+ .right_margin = 100,
+ .upper_margin = 4,
+ .lower_margin = 8,
+ .hsync_len = 4,
+ .vsync_len = 1,
+ .sync = 0,
+ .vmode = FB_VMODE_NONINTERLACED,
+ .flag = 0,
+};
+
+static struct fb_videomode e97_v110_mode = {
+ .name = "E97_V110",
+ .refresh = 50,
+ .xres = 1200,
+ .yres = 825,
+ .pixclock = 32000000,
+ .left_margin = 12,
+ .right_margin = 128,
+ .upper_margin = 4,
+ .lower_margin = 10,
+ .hsync_len = 20,
+ .vsync_len = 4,
+ .sync = 0,
+ .vmode = FB_VMODE_NONINTERLACED,
+ .flag = 0,
+};
+
+static struct imx_epdc_fb_mode panel_modes[] = {
+ {
+ &ed060xh2c1mode, /* struct fb_videomode *mode */
+ 4, /* vscan_holdoff */
+ 10, /* sdoed_width */
+ 20, /* sdoed_delay */
+ 10, /* sdoez_width */
+ 20, /* sdoez_delay */
+ 524, /* GDCLK_HP */
+ 327, /* GDSP_OFF */
+ 0, /* GDOE_OFF */
+ 19, /* gdclk_offs */
+ 1, /* num_ce */
+ },
+ {
+ &e60_v110_mode,
+ 4, /* vscan_holdoff */
+ 10, /* sdoed_width */
+ 20, /* sdoed_delay */
+ 10, /* sdoez_width */
+ 20, /* sdoez_delay */
+ 428, /* gdclk_hp_offs */
+ 20, /* gdsp_offs */
+ 0, /* gdoe_offs */
+ 1, /* gdclk_offs */
+ 1, /* num_ce */
+ },
+ {
+ &e60_v220_mode,
+ 4, /* vscan_holdoff */
+ 10, /* sdoed_width */
+ 20, /* sdoed_delay */
+ 10, /* sdoez_width */
+ 20, /* sdoez_delay */
+ 465, /* gdclk_hp_offs */
+ 20, /* gdsp_offs */
+ 0, /* gdoe_offs */
+ 9, /* gdclk_offs */
+ 1, /* num_ce */
+ },
+ {
+ &e060scm_mode,
+ 4, /* vscan_holdoff */
+ 10, /* sdoed_width */
+ 20, /* sdoed_delay */
+ 10, /* sdoez_width */
+ 20, /* sdoez_delay */
+ 419, /* gdclk_hp_offs */
+ 263, /* gdsp_offs */
+ 0, /* gdoe_offs */
+ 5, /* gdclk_offs */
+ 1, /* num_ce */
+ },
+ {
+ &e97_v110_mode,
+ 8, /* vscan_holdoff */
+ 10, /* sdoed_width */
+ 20, /* sdoed_delay */
+ 10, /* sdoez_width */
+ 20, /* sdoez_delay */
+ 632, /* gdclk_hp_offs */
+ 20, /* gdsp_offs */
+ 0, /* gdoe_offs */
+ 1, /* gdclk_offs */
+ 3, /* num_ce */
+ }
+};
+
+static struct imx_epdc_fb_platform_data epdc_data = {
+ .epdc_mode = panel_modes,
+ .num_modes = ARRAY_SIZE(panel_modes),
+};
+
+void __iomem *epdc_v2_base;
+
+static struct mxc_epdc_fb_data *g_fb_data;
+
+/* forward declaration */
+static int mxc_epdc_fb_get_temp_index(struct mxc_epdc_fb_data *fb_data,
+ int temp);
+static void mxc_epdc_fb_flush_updates(struct mxc_epdc_fb_data *fb_data);
+static int mxc_epdc_fb_blank(int blank, struct fb_info *info);
+static int mxc_epdc_fb_init_hw(struct fb_info *info);
+static int pxp_legacy_process(struct mxc_epdc_fb_data *fb_data,
+ u32 src_width, u32 src_height,
+ struct mxcfb_rect *update_region);
+static int pxp_process_dithering(struct mxc_epdc_fb_data *fb_data,
+ struct mxcfb_rect *update_region);
+static int pxp_wfe_a_process(struct mxc_epdc_fb_data *fb_data,
+ struct mxcfb_rect *update_region,
+ struct update_data_list *upd_data_list);
+static int pxp_wfe_b_process_update(struct mxc_epdc_fb_data *fb_data,
+ struct mxcfb_rect *update_region);
+static int pxp_wfe_a_process_clear_workingbuffer(struct mxc_epdc_fb_data *fb_data,
+ u32 src_width, u32 src_height);
+static int pxp_complete_update(struct mxc_epdc_fb_data *fb_data, u32 *hist_stat);
+
+static void draw_mode0(struct mxc_epdc_fb_data *fb_data);
+static bool is_free_list_full(struct mxc_epdc_fb_data *fb_data);
+
+static void do_dithering_processing_Y1_v1_0(
+ unsigned char *update_region_virt_ptr,
+ dma_addr_t update_region_phys_ptr,
+ struct mxcfb_rect *update_region,
+ unsigned long update_region_stride,
+ int *err_dist);
+static void do_dithering_processing_Y4_v1_0(
+ unsigned char *update_region_virt_ptr,
+ dma_addr_t update_region_phys_ptr,
+ struct mxcfb_rect *update_region,
+ unsigned long update_region_stride,
+ int *err_dist);
+static inline void epdc_set_used_lut(u64 used_bit);
+static inline void epdc_reset_used_lut(void);
+static int pxp_clear_wb_work_func(struct mxc_epdc_fb_data *fb_data);
+static int epdc_working_buffer_update(struct mxc_epdc_fb_data *fb_data,
+ struct update_data_list *upd_data_list,
+ struct mxcfb_rect *update_region);
+extern void pxp_get_collision_info(struct pxp_collision_info *info);
+
+#ifdef DEBUG
+static void dump_pxp_config(struct mxc_epdc_fb_data *fb_data,
+ struct pxp_config_data *pxp_conf)
+{
+ dev_info(fb_data->dev, "S0 fmt 0x%x",
+ pxp_conf->s0_param.pixel_fmt);
+ dev_info(fb_data->dev, "S0 width 0x%x",
+ pxp_conf->s0_param.width);
+ dev_info(fb_data->dev, "S0 height 0x%x",
+ pxp_conf->s0_param.height);
+ dev_info(fb_data->dev, "S0 ckey 0x%x",
+ pxp_conf->s0_param.color_key);
+ dev_info(fb_data->dev, "S0 ckey en 0x%x",
+ pxp_conf->s0_param.color_key_enable);
+
+ dev_info(fb_data->dev, "OL0 combine en 0x%x",
+ pxp_conf->ol_param[0].combine_enable);
+ dev_info(fb_data->dev, "OL0 fmt 0x%x",
+ pxp_conf->ol_param[0].pixel_fmt);
+ dev_info(fb_data->dev, "OL0 width 0x%x",
+ pxp_conf->ol_param[0].width);
+ dev_info(fb_data->dev, "OL0 height 0x%x",
+ pxp_conf->ol_param[0].height);
+ dev_info(fb_data->dev, "OL0 ckey 0x%x",
+ pxp_conf->ol_param[0].color_key);
+ dev_info(fb_data->dev, "OL0 ckey en 0x%x",
+ pxp_conf->ol_param[0].color_key_enable);
+ dev_info(fb_data->dev, "OL0 alpha 0x%x",
+ pxp_conf->ol_param[0].global_alpha);
+ dev_info(fb_data->dev, "OL0 alpha en 0x%x",
+ pxp_conf->ol_param[0].global_alpha_enable);
+ dev_info(fb_data->dev, "OL0 local alpha en 0x%x",
+ pxp_conf->ol_param[0].local_alpha_enable);
+
+ dev_info(fb_data->dev, "Out fmt 0x%x",
+ pxp_conf->out_param.pixel_fmt);
+ dev_info(fb_data->dev, "Out width 0x%x",
+ pxp_conf->out_param.width);
+ dev_info(fb_data->dev, "Out height 0x%x",
+ pxp_conf->out_param.height);
+
+ dev_info(fb_data->dev,
+ "drect left 0x%x right 0x%x width 0x%x height 0x%x",
+ pxp_conf->proc_data.drect.left, pxp_conf->proc_data.drect.top,
+ pxp_conf->proc_data.drect.width,
+ pxp_conf->proc_data.drect.height);
+ dev_info(fb_data->dev,
+ "srect left 0x%x right 0x%x width 0x%x height 0x%x",
+ pxp_conf->proc_data.srect.left, pxp_conf->proc_data.srect.top,
+ pxp_conf->proc_data.srect.width,
+ pxp_conf->proc_data.srect.height);
+ dev_info(fb_data->dev, "Scaling en 0x%x", pxp_conf->proc_data.scaling);
+ dev_info(fb_data->dev, "HFlip en 0x%x", pxp_conf->proc_data.hflip);
+ dev_info(fb_data->dev, "VFlip en 0x%x", pxp_conf->proc_data.vflip);
+ dev_info(fb_data->dev, "Rotation 0x%x", pxp_conf->proc_data.rotate);
+ dev_info(fb_data->dev, "BG Color 0x%x", pxp_conf->proc_data.bgcolor);
+}
+
+static void dump_epdc_reg(void)
+{
+ printk(KERN_DEBUG "\n\n");
+ printk(KERN_DEBUG "EPDC_CTRL 0x%x\n", __raw_readl(EPDC_CTRL));
+ printk(KERN_DEBUG "EPDC_WVADDR 0x%x\n", __raw_readl(EPDC_WVADDR));
+ printk(KERN_DEBUG "EPDC_WB_ADDR 0x%x\n", __raw_readl(EPDC_WB_ADDR));
+ printk(KERN_DEBUG "EPDC_RES 0x%x\n", __raw_readl(EPDC_RES));
+ printk(KERN_DEBUG "EPDC_FORMAT 0x%x\n", __raw_readl(EPDC_FORMAT));
+ printk(KERN_DEBUG "EPDC_FIFOCTRL 0x%x\n", __raw_readl(EPDC_FIFOCTRL));
+ printk(KERN_DEBUG "EPDC_UPD_ADDR 0x%x\n", __raw_readl(EPDC_UPD_ADDR));
+ printk(KERN_DEBUG "EPDC_UPD_STRIDE 0x%x\n", __raw_readl(EPDC_UPD_STRIDE));
+ printk(KERN_DEBUG "EPDC_UPD_FIXED 0x%x\n", __raw_readl(EPDC_UPD_FIXED));
+ printk(KERN_DEBUG "EPDC_UPD_CORD 0x%x\n", __raw_readl(EPDC_UPD_CORD));
+ printk(KERN_DEBUG "EPDC_UPD_SIZE 0x%x\n", __raw_readl(EPDC_UPD_SIZE));
+ printk(KERN_DEBUG "EPDC_UPD_CTRL 0x%x\n", __raw_readl(EPDC_UPD_CTRL));
+ printk(KERN_DEBUG "EPDC_TEMP 0x%x\n", __raw_readl(EPDC_TEMP));
+ printk(KERN_DEBUG "EPDC_AUTOWV_LUT 0x%x\n", __raw_readl(EPDC_AUTOWV_LUT));
+ printk(KERN_DEBUG "EPDC_TCE_CTRL 0x%x\n", __raw_readl(EPDC_TCE_CTRL));
+ printk(KERN_DEBUG "EPDC_TCE_SDCFG 0x%x\n", __raw_readl(EPDC_TCE_SDCFG));
+ printk(KERN_DEBUG "EPDC_TCE_GDCFG 0x%x\n", __raw_readl(EPDC_TCE_GDCFG));
+ printk(KERN_DEBUG "EPDC_TCE_HSCAN1 0x%x\n", __raw_readl(EPDC_TCE_HSCAN1));
+ printk(KERN_DEBUG "EPDC_TCE_HSCAN2 0x%x\n", __raw_readl(EPDC_TCE_HSCAN2));
+ printk(KERN_DEBUG "EPDC_TCE_VSCAN 0x%x\n", __raw_readl(EPDC_TCE_VSCAN));
+ printk(KERN_DEBUG "EPDC_TCE_OE 0x%x\n", __raw_readl(EPDC_TCE_OE));
+ printk(KERN_DEBUG "EPDC_TCE_POLARITY 0x%x\n", __raw_readl(EPDC_TCE_POLARITY));
+ printk(KERN_DEBUG "EPDC_TCE_TIMING1 0x%x\n", __raw_readl(EPDC_TCE_TIMING1));
+ printk(KERN_DEBUG "EPDC_TCE_TIMING2 0x%x\n", __raw_readl(EPDC_TCE_TIMING2));
+ printk(KERN_DEBUG "EPDC_TCE_TIMING3 0x%x\n", __raw_readl(EPDC_TCE_TIMING3));
+ printk(KERN_DEBUG "EPDC_PIGEON_CTRL0 0x%x\n", __raw_readl(EPDC_PIGEON_CTRL0));
+ printk(KERN_DEBUG "EPDC_PIGEON_CTRL1 0x%x\n", __raw_readl(EPDC_PIGEON_CTRL1));
+ printk(KERN_DEBUG "EPDC_IRQ_MASK1 0x%x\n", __raw_readl(EPDC_IRQ_MASK1));
+ printk(KERN_DEBUG "EPDC_IRQ_MASK2 0x%x\n", __raw_readl(EPDC_IRQ_MASK2));
+ printk(KERN_DEBUG "EPDC_IRQ1 0x%x\n", __raw_readl(EPDC_IRQ1));
+ printk(KERN_DEBUG "EPDC_IRQ2 0x%x\n", __raw_readl(EPDC_IRQ2));
+ printk(KERN_DEBUG "EPDC_IRQ_MASK 0x%x\n", __raw_readl(EPDC_IRQ_MASK));
+ printk(KERN_DEBUG "EPDC_IRQ 0x%x\n", __raw_readl(EPDC_IRQ));
+ printk(KERN_DEBUG "EPDC_STATUS_LUTS 0x%x\n", __raw_readl(EPDC_STATUS_LUTS));
+ printk(KERN_DEBUG "EPDC_STATUS_LUTS2 0x%x\n", __raw_readl(EPDC_STATUS_LUTS2));
+ printk(KERN_DEBUG "EPDC_STATUS_NEXTLUT 0x%x\n", __raw_readl(EPDC_STATUS_NEXTLUT));
+ printk(KERN_DEBUG "EPDC_STATUS_COL1 0x%x\n", __raw_readl(EPDC_STATUS_COL));
+ printk(KERN_DEBUG "EPDC_STATUS_COL2 0x%x\n", __raw_readl(EPDC_STATUS_COL2));
+ printk(KERN_DEBUG "EPDC_STATUS 0x%x\n", __raw_readl(EPDC_STATUS));
+ printk(KERN_DEBUG "EPDC_UPD_COL_CORD 0x%x\n", __raw_readl(EPDC_UPD_COL_CORD));
+ printk(KERN_DEBUG "EPDC_UPD_COL_SIZE 0x%x\n", __raw_readl(EPDC_UPD_COL_SIZE));
+ printk(KERN_DEBUG "EPDC_DEBUG 0x%x\n", __raw_readl(EPDC_DEBUG));
+ printk(KERN_DEBUG "EPDC_DEBUG_LUT 0x%x\n", __raw_readl(EPDC_DEBUG_LUT));
+ printk(KERN_DEBUG "EPDC_HIST1_PARAM 0x%x\n", __raw_readl(EPDC_HIST1_PARAM));
+ printk(KERN_DEBUG "EPDC_HIST2_PARAM 0x%x\n", __raw_readl(EPDC_HIST2_PARAM));
+ printk(KERN_DEBUG "EPDC_HIST4_PARAM 0x%x\n", __raw_readl(EPDC_HIST4_PARAM));
+ printk(KERN_DEBUG "EPDC_HIST8_PARAM0 0x%x\n", __raw_readl(EPDC_HIST8_PARAM0));
+ printk(KERN_DEBUG "EPDC_HIST8_PARAM1 0x%x\n", __raw_readl(EPDC_HIST8_PARAM1));
+ printk(KERN_DEBUG "EPDC_HIST16_PARAM0 0x%x\n", __raw_readl(EPDC_HIST16_PARAM0));
+ printk(KERN_DEBUG "EPDC_HIST16_PARAM1 0x%x\n", __raw_readl(EPDC_HIST16_PARAM1));
+ printk(KERN_DEBUG "EPDC_HIST16_PARAM2 0x%x\n", __raw_readl(EPDC_HIST16_PARAM2));
+ printk(KERN_DEBUG "EPDC_HIST16_PARAM3 0x%x\n", __raw_readl(EPDC_HIST16_PARAM3));
+ printk(KERN_DEBUG "EPDC_GPIO 0x%x\n", __raw_readl(EPDC_GPIO));
+ printk(KERN_DEBUG "EPDC_VERSION 0x%x\n", __raw_readl(EPDC_VERSION));
+ printk(KERN_DEBUG "\n\n");
+}
+
+static void dump_update_data(struct device *dev,
+ struct update_data_list *upd_data_list)
+{
+ dev_info(dev,
+ "X = %d, Y = %d, Width = %d, Height = %d, WaveMode = %d, "
+ "LUT = %d, Coll Mask = 0x%llx, order = %d\n",
+ upd_data_list->update_desc->upd_data.update_region.left,
+ upd_data_list->update_desc->upd_data.update_region.top,
+ upd_data_list->update_desc->upd_data.update_region.width,
+ upd_data_list->update_desc->upd_data.update_region.height,
+ upd_data_list->update_desc->upd_data.waveform_mode,
+ upd_data_list->lut_num,
+ upd_data_list->collision_mask,
+ upd_data_list->update_desc->update_order);
+}
+
+static void dump_collision_list(struct mxc_epdc_fb_data *fb_data)
+{
+ struct update_data_list *plist;
+
+ dev_info(fb_data->dev, "Collision List:\n");
+ if (list_empty(&fb_data->upd_buf_collision_list))
+ dev_info(fb_data->dev, "Empty");
+ list_for_each_entry(plist, &fb_data->upd_buf_collision_list, list) {
+ dev_info(fb_data->dev, "Virt Addr = 0x%x, Phys Addr = 0x%x ",
+ (u32)plist->virt_addr, plist->phys_addr);
+ dump_update_data(fb_data->dev, plist);
+ }
+}
+
+static void dump_free_list(struct mxc_epdc_fb_data *fb_data)
+{
+ struct update_data_list *plist;
+
+ dev_info(fb_data->dev, "Free List:\n");
+ if (list_empty(&fb_data->upd_buf_free_list))
+ dev_info(fb_data->dev, "Empty");
+ list_for_each_entry(plist, &fb_data->upd_buf_free_list, list)
+ dev_info(fb_data->dev, "Virt Addr = 0x%x, Phys Addr = 0x%x ",
+ (u32)plist->virt_addr, plist->phys_addr);
+}
+
+static void dump_queue(struct mxc_epdc_fb_data *fb_data)
+{
+ struct update_data_list *plist;
+
+ dev_info(fb_data->dev, "Queue:\n");
+ if (list_empty(&fb_data->upd_buf_queue))
+ dev_info(fb_data->dev, "Empty");
+ list_for_each_entry(plist, &fb_data->upd_buf_queue, list) {
+ dev_info(fb_data->dev, "Virt Addr = 0x%x, Phys Addr = 0x%x ",
+ (u32)plist->virt_addr, plist->phys_addr);
+ dump_update_data(fb_data->dev, plist);
+ }
+}
+
+static void dump_desc_data(struct device *dev,
+ struct update_desc_list *upd_desc_list)
+{
+ dev_info(dev,
+ "X = %d, Y = %d, Width = %d, Height = %d, WaveMode = %d, "
+ "order = %d\n",
+ upd_desc_list->upd_data.update_region.left,
+ upd_desc_list->upd_data.update_region.top,
+ upd_desc_list->upd_data.update_region.width,
+ upd_desc_list->upd_data.update_region.height,
+ upd_desc_list->upd_data.waveform_mode,
+ upd_desc_list->update_order);
+}
+
+static void dump_pending_list(struct mxc_epdc_fb_data *fb_data)
+{
+ struct update_desc_list *plist;
+
+ dev_info(fb_data->dev, "Queue:\n");
+ if (list_empty(&fb_data->upd_pending_list))
+ dev_info(fb_data->dev, "Empty");
+ list_for_each_entry(plist, &fb_data->upd_pending_list, list)
+ dump_desc_data(fb_data->dev, plist);
+}
+
+static void dump_all_updates(struct mxc_epdc_fb_data *fb_data)
+{
+ dump_free_list(fb_data);
+ dump_queue(fb_data);
+ dump_collision_list(fb_data);
+ dev_info(fb_data->dev, "Current update being processed:\n");
+ if (fb_data->cur_update == NULL)
+ dev_info(fb_data->dev, "No current update\n");
+ else
+ dump_update_data(fb_data->dev, fb_data->cur_update);
+}
+
+static void dump_fw_header(struct device *dev,
+ struct mxcfb_waveform_data_file *fw)
+{
+ dev_dbg(dev, "Firmware Header:\n");
+ dev_dbg(dev, "wi0 0x%08x\n", fw->wdh.wi0);
+ dev_dbg(dev, "wi1 0x%08x\n", fw->wdh.wi1);
+ dev_dbg(dev, "wi2 0x%08x\n", fw->wdh.wi2);
+ dev_dbg(dev, "wi3 0x%08x\n", fw->wdh.wi3);
+ dev_dbg(dev, "wi4 0x%08x\n", fw->wdh.wi4);
+ dev_dbg(dev, "wi5 0x%08x\n", fw->wdh.wi5);
+ dev_dbg(dev, "wi6 0x%08x\n", fw->wdh.wi6);
+ dev_dbg(dev, "xwia:24 0x%06x\n", fw->wdh.xwia);
+ dev_dbg(dev, "cs1:8 0x%02x\n", fw->wdh.cs1);
+ dev_dbg(dev, "wmta:24 0x%06x\n", fw->wdh.wmta);
+ dev_dbg(dev, "fvsn:8 0x%02x\n", fw->wdh.fvsn);
+ dev_dbg(dev, "luts:8 0x%02x\n", fw->wdh.luts);
+ dev_dbg(dev, "mc:8 0x%02x\n", fw->wdh.mc);
+ dev_dbg(dev, "trc:8 0x%02x\n", fw->wdh.trc);
+ dev_dbg(dev, "reserved0_0 0x%02x\n", fw->wdh.reserved0_0);
+ dev_dbg(dev, "eb:8 0x%02x\n", fw->wdh.eb);
+ dev_dbg(dev, "sb:8 0x%02x\n", fw->wdh.sb);
+ dev_dbg(dev, "reserved0_1 0x%02x\n", fw->wdh.reserved0_1);
+ dev_dbg(dev, "reserved0_2 0x%02x\n", fw->wdh.reserved0_2);
+ dev_dbg(dev, "reserved0_3 0x%02x\n", fw->wdh.reserved0_3);
+ dev_dbg(dev, "reserved0_4 0x%02x\n", fw->wdh.reserved0_4);
+ dev_dbg(dev, "reserved0_5 0x%02x\n", fw->wdh.reserved0_5);
+ dev_dbg(dev, "cs2:8 0x%02x\n", fw->wdh.cs2);
+}
+
+#else
+static inline void dump_pxp_config(struct mxc_epdc_fb_data *fb_data,
+ struct pxp_config_data *pxp_conf) {}
+static inline void dump_epdc_reg(void) {}
+static inline void dump_update_data(struct device *dev,
+ struct update_data_list *upd_data_list) {}
+static inline void dump_collision_list(struct mxc_epdc_fb_data *fb_data) {}
+static inline void dump_free_list(struct mxc_epdc_fb_data *fb_data) {}
+static inline void dump_queue(struct mxc_epdc_fb_data *fb_data) {}
+static inline void dump_all_updates(struct mxc_epdc_fb_data *fb_data) {}
+static void dump_fw_header(struct device *dev,
+ struct mxcfb_waveform_data_file *fw) {}
+
+#endif
+
+
+/********************************************************
+ * Start Low-Level EPDC Functions
+ ********************************************************/
+
+static inline void epdc_lut_complete_intr(int rev, u32 lut_num, bool enable)
+{
+ if (rev < 20) {
+ if (enable)
+ __raw_writel(1 << lut_num, EPDC_IRQ_MASK_SET);
+ else
+ __raw_writel(1 << lut_num, EPDC_IRQ_MASK_CLEAR);
+ } else {
+ if (enable) {
+ if (lut_num < 32)
+ __raw_writel(1 << lut_num, EPDC_IRQ_MASK1_SET);
+ else
+ __raw_writel(1 << (lut_num - 32),
+ EPDC_IRQ_MASK2_SET);
+ } else {
+ if (lut_num < 32)
+ __raw_writel(1 << lut_num,
+ EPDC_IRQ_MASK1_CLEAR);
+ else
+ __raw_writel(1 << (lut_num - 32),
+ EPDC_IRQ_MASK2_CLEAR);
+ }
+ }
+}
+
+static inline void epdc_working_buf_intr(bool enable)
+{
+ if (enable)
+ __raw_writel(EPDC_IRQ_WB_CMPLT_IRQ, EPDC_IRQ_MASK_SET);
+ else
+ __raw_writel(EPDC_IRQ_WB_CMPLT_IRQ, EPDC_IRQ_MASK_CLEAR);
+}
+
+static inline void epdc_clear_working_buf_irq(void)
+{
+ __raw_writel(EPDC_IRQ_WB_CMPLT_IRQ | EPDC_IRQ_LUT_COL_IRQ,
+ EPDC_IRQ_CLEAR);
+}
+
+static inline void epdc_eof_intr(bool enable)
+{
+ if (enable)
+ __raw_writel(EPDC_IRQ_FRAME_END_IRQ, EPDC_IRQ_MASK_SET);
+ else
+ __raw_writel(EPDC_IRQ_FRAME_END_IRQ, EPDC_IRQ_MASK_CLEAR);
+}
+
+static inline void epdc_clear_eof_irq(void)
+{
+ __raw_writel(EPDC_IRQ_FRAME_END_IRQ, EPDC_IRQ_CLEAR);
+}
+
+static inline bool epdc_signal_eof(void)
+{
+ return (__raw_readl(EPDC_IRQ_MASK) & __raw_readl(EPDC_IRQ)
+ & EPDC_IRQ_FRAME_END_IRQ) ? true : false;
+}
+
+static inline void epdc_set_temp(u32 temp)
+{
+ int ret = 0;
+ /* used to store external panel temperature value */
+ unsigned int ext_temp, ext_temp_index = temp;
+
+ if (temp == DEFAULT_TEMP_INDEX) {
+ ret = max17135_reg_read(REG_MAX17135_EXT_TEMP, &ext_temp);
+ if (ret == 0) {
+ ext_temp = ext_temp >> 8;
+ dev_dbg(g_fb_data->dev, "the current external temperature is %d\n",
+ ext_temp);
+ ext_temp_index = mxc_epdc_fb_get_temp_index(g_fb_data, ext_temp);
+ }
+ }
+
+ __raw_writel(ext_temp_index, EPDC_TEMP);
+}
+
+static inline void epdc_set_screen_res(u32 width, u32 height)
+{
+ u32 val = (height << EPDC_RES_VERTICAL_OFFSET) | width;
+ __raw_writel(val, EPDC_RES);
+}
+
+static inline void epdc_set_update_addr(u32 addr)
+{
+#ifdef EPDC_STANDARD_MODE
+ __raw_writel(0, EPDC_UPD_ADDR);
+#else
+ __raw_writel(addr, EPDC_UPD_ADDR);
+#endif
+}
+
+static inline void epdc_set_update_coord(u32 x, u32 y)
+{
+ u32 val = (y << EPDC_UPD_CORD_YCORD_OFFSET) | x;
+ __raw_writel(val, EPDC_UPD_CORD);
+}
+
+static inline void epdc_set_update_dimensions(u32 width, u32 height)
+{
+ u32 val = (height << EPDC_UPD_SIZE_HEIGHT_OFFSET) | width;
+ __raw_writel(val, EPDC_UPD_SIZE);
+}
+
+static void epdc_set_update_waveform(struct mxcfb_waveform_modes *wv_modes)
+{
+ u32 val;
+
+#ifdef EPDC_STANDARD_MODE
+ return;
+#endif
+
+ /* Configure the auto-waveform look-up table based on waveform modes */
+
+ /* Entry 1 = DU, 2 = GC4, 3 = GC8, etc. */
+ val = (wv_modes->mode_du << EPDC_AUTOWV_LUT_DATA_OFFSET) |
+ (0 << EPDC_AUTOWV_LUT_ADDR_OFFSET);
+ __raw_writel(val, EPDC_AUTOWV_LUT);
+ val = (wv_modes->mode_du << EPDC_AUTOWV_LUT_DATA_OFFSET) |
+ (1 << EPDC_AUTOWV_LUT_ADDR_OFFSET);
+ __raw_writel(val, EPDC_AUTOWV_LUT);
+ val = (wv_modes->mode_gc4 << EPDC_AUTOWV_LUT_DATA_OFFSET) |
+ (2 << EPDC_AUTOWV_LUT_ADDR_OFFSET);
+ __raw_writel(val, EPDC_AUTOWV_LUT);
+ val = (wv_modes->mode_gc8 << EPDC_AUTOWV_LUT_DATA_OFFSET) |
+ (3 << EPDC_AUTOWV_LUT_ADDR_OFFSET);
+ __raw_writel(val, EPDC_AUTOWV_LUT);
+ val = (wv_modes->mode_gc16 << EPDC_AUTOWV_LUT_DATA_OFFSET) |
+ (4 << EPDC_AUTOWV_LUT_ADDR_OFFSET);
+ __raw_writel(val, EPDC_AUTOWV_LUT);
+ val = (wv_modes->mode_gc32 << EPDC_AUTOWV_LUT_DATA_OFFSET) |
+ (5 << EPDC_AUTOWV_LUT_ADDR_OFFSET);
+ __raw_writel(val, EPDC_AUTOWV_LUT);
+}
+
+static void epdc_set_update_stride(u32 stride)
+{
+#ifdef EPDC_STANDARD_MODE
+ __raw_writel(0, EPDC_UPD_STRIDE);
+#else
+ __raw_writel(stride, EPDC_UPD_STRIDE);
+#endif
+}
+
+static void epdc_submit_update(u32 lut_num, u32 waveform_mode, u32 update_mode,
+ bool use_dry_run, bool use_test_mode, u32 np_val)
+{
+ u32 reg_val = 0;
+
+ if (use_test_mode) {
+ reg_val |=
+ ((np_val << EPDC_UPD_FIXED_FIXNP_OFFSET) &
+ EPDC_UPD_FIXED_FIXNP_MASK) | EPDC_UPD_FIXED_FIXNP_EN;
+ reg_val |=
+ ((np_val << EPDC_UPD_FIXED_FIXCP_OFFSET) &
+ EPDC_UPD_FIXED_FIXCP_MASK) | EPDC_UPD_FIXED_FIXCP_EN;
+
+ __raw_writel(reg_val, EPDC_UPD_FIXED);
+
+ reg_val = EPDC_UPD_CTRL_USE_FIXED;
+ } else {
+ __raw_writel(reg_val, EPDC_UPD_FIXED);
+ }
+
+ if (waveform_mode == WAVEFORM_MODE_AUTO)
+ reg_val |= EPDC_UPD_CTRL_AUTOWV;
+ else
+ reg_val |= ((waveform_mode <<
+ EPDC_UPD_CTRL_WAVEFORM_MODE_OFFSET) &
+ EPDC_UPD_CTRL_WAVEFORM_MODE_MASK);
+
+ reg_val |= (use_dry_run ? EPDC_UPD_CTRL_DRY_RUN : 0) |
+ ((lut_num << EPDC_UPD_CTRL_LUT_SEL_OFFSET) &
+ EPDC_UPD_CTRL_LUT_SEL_MASK) |
+ update_mode;
+
+#ifdef EPDC_STANDARD_MODE
+ reg_val |= 0x80000000;
+
+ epdc_set_used_lut(lut_num);
+#endif
+ dump_epdc_reg();
+ __raw_writel(reg_val, EPDC_UPD_CTRL);
+}
+
+static inline bool epdc_is_lut_complete(int rev, u32 lut_num)
+{
+ u32 val;
+ bool is_compl;
+ if (rev < 20) {
+ val = __raw_readl(EPDC_IRQ);
+ is_compl = val & (1 << lut_num) ? true : false;
+ } else if (lut_num < 32) {
+ val = __raw_readl(EPDC_IRQ1);
+ is_compl = val & (1 << lut_num) ? true : false;
+ } else {
+ val = __raw_readl(EPDC_IRQ2);
+ is_compl = val & (1 << (lut_num - 32)) ? true : false;
+ }
+
+ return is_compl;
+}
+
+static inline void epdc_clear_lut_complete_irq(int rev, u32 lut_num)
+{
+ if (rev < 20)
+ __raw_writel(1 << lut_num, EPDC_IRQ_CLEAR);
+ else if (lut_num < 32)
+ __raw_writel(1 << lut_num, EPDC_IRQ1_CLEAR);
+ else
+ __raw_writel(1 << (lut_num - 32), EPDC_IRQ2_CLEAR);
+}
+
+static inline bool epdc_is_lut_active(u32 lut_num)
+{
+ u32 val;
+ bool is_active;
+
+ if (lut_num < 32) {
+ val = __raw_readl(EPDC_STATUS_LUTS);
+ is_active = val & (1 << lut_num) ? true : false;
+ } else {
+ val = __raw_readl(EPDC_STATUS_LUTS2);
+ is_active = val & (1 << (lut_num - 32)) ? true : false;
+ }
+
+ return is_active;
+}
+
+static inline bool epdc_any_luts_active(int rev)
+{
+ bool any_active;
+
+ if (rev < 20)
+ any_active = __raw_readl(EPDC_STATUS_LUTS) ? true : false;
+ else
+ any_active = (__raw_readl(EPDC_STATUS_LUTS) |
+ __raw_readl(EPDC_STATUS_LUTS2)) ? true : false;
+
+ return any_active;
+}
+
+static inline bool epdc_any_luts_real_available(void)
+{
+ if ((__raw_readl(EPDC_STATUS_LUTS) != 0xfffffffe) ||
+ (__raw_readl(EPDC_STATUS_LUTS2) != ~0UL))
+ return true;
+ else
+ return false;
+}
+
+static inline bool epdc_any_luts_available(void)
+{
+#ifdef EPDC_STANDARD_MODE
+ if (((u32)used_luts != ~0UL) || ((u32)(used_luts >> 32) != ~0UL))
+ return 1;
+ else
+ return 0;
+#else
+ bool luts_available =
+ (__raw_readl(EPDC_STATUS_NEXTLUT) &
+ EPDC_STATUS_NEXTLUT_NEXT_LUT_VALID) ? true : false;
+ return luts_available;
+#endif
+}
+
+static inline int epdc_get_next_lut(void)
+{
+ u32 val =
+ __raw_readl(EPDC_STATUS_NEXTLUT) &
+ EPDC_STATUS_NEXTLUT_NEXT_LUT_MASK;
+ return val;
+}
+
+static inline void epdc_set_used_lut(u64 used_bit)
+{
+ used_luts |= (u64)1 << used_bit;
+}
+
+static inline void epdc_reset_used_lut(void)
+{
+ used_luts = 0x1;
+}
+
+#ifdef EPDC_STANDARD_MODE
+/*
+ * in previous flow, when all LUTs are used, the LUT cleanup operation
+ * need to wait for all the LUT to finish, it will not happen util last LUT
+ * is done. while in new flow, the cleanup operation does not need to wait
+ * for all LUTs to finish, instead it can start when there's LUT's done.
+ * The saved time is multiple LUT operation time.
+ */
+static int epdc_choose_next_lut(struct mxc_epdc_fb_data *fb_data, int *next_lut)
+{
+ while (!epdc_any_luts_available()) {
+ u64 luts_complete = fb_data->luts_complete;
+ pxp_clear_wb_work_func(fb_data);
+ used_luts &= ~luts_complete;
+ fb_data->luts_complete &= ~luts_complete;
+ mutex_unlock(&fb_data->queue_mutex);
+ msleep(10);
+ mutex_lock(&fb_data->queue_mutex);
+ }
+
+ used_luts |= 0x1;
+
+ if ((u32)used_luts != ~0UL)
+ *next_lut = ffz((u32)used_luts);
+ else if ((u32)(used_luts >> 32) != ~0UL)
+ *next_lut = ffz((u32)(used_luts >> 32)) + 32;
+
+ return 0;
+}
+#else
+static int epdc_choose_next_lut(struct mxc_epdc_fb_data *fb_data, int *next_lut)
+{
+ u64 luts_status, unprocessed_luts, used_luts;
+ /* Available LUTs are reduced to 16 in 5-bit waveform mode */
+ bool format_p5n = ((__raw_readl(EPDC_FORMAT) &
+ EPDC_FORMAT_BUF_PIXEL_FORMAT_MASK) ==
+ EPDC_FORMAT_BUF_PIXEL_FORMAT_P5N);
+
+ luts_status = __raw_readl(EPDC_STATUS_LUTS);
+ if ((fb_data->rev < 20) || format_p5n)
+ luts_status &= 0xFFFF;
+ else
+ luts_status |= ((u64)__raw_readl(EPDC_STATUS_LUTS2) << 32);
+
+ if (fb_data->rev < 20) {
+ unprocessed_luts = __raw_readl(EPDC_IRQ) & 0xFFFF;
+ } else {
+ unprocessed_luts = __raw_readl(EPDC_IRQ1) |
+ ((u64)__raw_readl(EPDC_IRQ2) << 32);
+ if (format_p5n)
+ unprocessed_luts &= 0xFFFF;
+ }
+
+ /*
+ * Note on unprocessed_luts: There is a race condition
+ * where a LUT completes, but has not been processed by
+ * IRQ handler workqueue, and then a new update request
+ * attempts to use that LUT. We prevent that here by
+ * ensuring that the LUT we choose doesn't have its IRQ
+ * bit set (indicating it has completed but not yet been
+ * processed).
+ */
+ used_luts = luts_status | unprocessed_luts;
+
+ /*
+ * Selecting a LUT to minimize incidence of TCE Underrun Error
+ * --------------------------------------------------------
+ * We want to find the lowest order LUT that is of greater
+ * order than all other active LUTs. If highest order LUT
+ * is active, then we want to choose the lowest order
+ * available LUT.
+ *
+ * NOTE: For EPDC version 2.0 and later, TCE Underrun error
+ * bug is fixed, so it doesn't matter which LUT is used.
+ */
+
+ if ((fb_data->rev < 20) || format_p5n) {
+ *next_lut = fls64(used_luts);
+ if (*next_lut > 15)
+ *next_lut = ffz(used_luts);
+ } else {
+ if ((u32)used_luts != ~0UL)
+ *next_lut = ffz((u32)used_luts);
+ else if ((u32)(used_luts >> 32) != ~0UL)
+ *next_lut = ffz((u32)(used_luts >> 32)) + 32;
+ else
+ *next_lut = INVALID_LUT;
+ }
+
+ if (used_luts & 0x8000)
+ return 1;
+ else
+ return 0;
+}
+#endif
+
+static inline bool epdc_is_working_buffer_busy(void)
+{
+ u32 val = __raw_readl(EPDC_STATUS);
+ bool is_busy = (val & EPDC_STATUS_WB_BUSY) ? true : false;
+
+ return is_busy;
+}
+
+static inline bool epdc_is_working_buffer_complete(void)
+{
+ u32 val = __raw_readl(EPDC_IRQ);
+ bool is_compl = (val & EPDC_IRQ_WB_CMPLT_IRQ) ? true : false;
+
+ return is_compl;
+}
+
+static inline bool epdc_is_lut_cancelled(void)
+{
+ u32 val = __raw_readl(EPDC_STATUS);
+ bool is_void = (val & EPDC_STATUS_UPD_VOID) ? true : false;
+
+ return is_void;
+}
+
+static inline bool epdc_is_collision(void)
+{
+ u32 val = __raw_readl(EPDC_IRQ);
+ return (val & EPDC_IRQ_LUT_COL_IRQ) ? true : false;
+}
+
+static inline u64 epdc_get_colliding_luts(int rev)
+{
+ u32 val = __raw_readl(EPDC_STATUS_COL);
+ if (rev >= 20)
+ val |= (u64)__raw_readl(EPDC_STATUS_COL2) << 32;
+ return val;
+}
+
+static void epdc_set_horizontal_timing(u32 horiz_start, u32 horiz_end,
+ u32 hsync_width, u32 hsync_line_length)
+{
+ u32 reg_val =
+ ((hsync_width << EPDC_TCE_HSCAN1_LINE_SYNC_WIDTH_OFFSET) &
+ EPDC_TCE_HSCAN1_LINE_SYNC_WIDTH_MASK)
+ | ((hsync_line_length << EPDC_TCE_HSCAN1_LINE_SYNC_OFFSET) &
+ EPDC_TCE_HSCAN1_LINE_SYNC_MASK);
+ __raw_writel(reg_val, EPDC_TCE_HSCAN1);
+
+ reg_val =
+ ((horiz_start << EPDC_TCE_HSCAN2_LINE_BEGIN_OFFSET) &
+ EPDC_TCE_HSCAN2_LINE_BEGIN_MASK)
+ | ((horiz_end << EPDC_TCE_HSCAN2_LINE_END_OFFSET) &
+ EPDC_TCE_HSCAN2_LINE_END_MASK);
+ __raw_writel(reg_val, EPDC_TCE_HSCAN2);
+}
+
+static void epdc_set_vertical_timing(u32 vert_start, u32 vert_end,
+ u32 vsync_width)
+{
+ u32 reg_val =
+ ((vert_start << EPDC_TCE_VSCAN_FRAME_BEGIN_OFFSET) &
+ EPDC_TCE_VSCAN_FRAME_BEGIN_MASK)
+ | ((vert_end << EPDC_TCE_VSCAN_FRAME_END_OFFSET) &
+ EPDC_TCE_VSCAN_FRAME_END_MASK)
+ | ((vsync_width << EPDC_TCE_VSCAN_FRAME_SYNC_OFFSET) &
+ EPDC_TCE_VSCAN_FRAME_SYNC_MASK);
+ __raw_writel(reg_val, EPDC_TCE_VSCAN);
+}
+
+static void epdc_init_settings(struct mxc_epdc_fb_data *fb_data)
+{
+ struct imx_epdc_fb_mode *epdc_mode = fb_data->cur_mode;
+ struct fb_var_screeninfo *screeninfo = &fb_data->epdc_fb_var;
+ u32 reg_val;
+ int num_ce;
+#ifndef EPDC_STANDARD_MODE
+ int i;
+#endif
+ int j;
+ unsigned char *bb_p;
+
+ /* Enable clocks to access EPDC regs */
+ clk_prepare_enable(fb_data->epdc_clk_axi);
+ clk_prepare_enable(fb_data->epdc_clk_pix);
+
+ /* Reset */
+ __raw_writel(EPDC_CTRL_SFTRST, EPDC_CTRL_SET);
+ while (!(__raw_readl(EPDC_CTRL) & EPDC_CTRL_CLKGATE))
+ ;
+ __raw_writel(EPDC_CTRL_SFTRST, EPDC_CTRL_CLEAR);
+
+ /* Enable clock gating (clear to enable) */
+ __raw_writel(EPDC_CTRL_CLKGATE, EPDC_CTRL_CLEAR);
+ while (__raw_readl(EPDC_CTRL) & (EPDC_CTRL_SFTRST | EPDC_CTRL_CLKGATE))
+ ;
+
+ /* EPDC_CTRL */
+ reg_val = __raw_readl(EPDC_CTRL);
+ reg_val &= ~EPDC_CTRL_UPD_DATA_SWIZZLE_MASK;
+#ifdef EPDC_STANDARD_MODE
+ reg_val |= EPDC_CTRL_UPD_DATA_SWIZZLE_ALL_BYTES_SWAP;
+#else
+ reg_val |= EPDC_CTRL_UPD_DATA_SWIZZLE_NO_SWAP;
+#endif
+ reg_val &= ~EPDC_CTRL_LUT_DATA_SWIZZLE_MASK;
+ reg_val |= EPDC_CTRL_LUT_DATA_SWIZZLE_NO_SWAP;
+ __raw_writel(reg_val, EPDC_CTRL_SET);
+
+ /* EPDC_FORMAT - 2bit TFT and 4bit Buf pixel format */
+ reg_val = EPDC_FORMAT_TFT_PIXEL_FORMAT_2BIT
+#ifdef EPDC_STANDARD_MODE
+ | EPDC_FORMAT_WB_TYPE_WB_EXTERNAL16
+#endif
+ | EPDC_FORMAT_BUF_PIXEL_FORMAT_P4N
+ | ((0x0 << EPDC_FORMAT_DEFAULT_TFT_PIXEL_OFFSET) &
+ EPDC_FORMAT_DEFAULT_TFT_PIXEL_MASK);
+ __raw_writel(reg_val, EPDC_FORMAT);
+
+#ifdef EPDC_STANDARD_MODE
+ reg_val = 0;
+ if (fb_data->waveform_is_advanced) {
+ reg_val =
+ ((EPDC_WB_FIELD_USAGE_PTS << EPDC_WB_FIELD_USAGE_OFFSET) &
+ EPDC_WB_FIELD_USAGE_MASK)
+ | ((0x8 << EPDC_WB_FIELD_FROM_OFFSET) &
+ EPDC_WB_FIELD_FROM_MASK)
+ | ((0x8 << EPDC_WB_FIELD_TO_OFFSET) &
+ EPDC_WB_FIELD_TO_MASK)
+ | ((0x1 << EPDC_WB_FIELD_LEN_OFFSET) &
+ EPDC_WB_FIELD_LEN_MASK);
+ }
+ __raw_writel(reg_val, EPDC_WB_FIELD3);
+#endif
+
+ /* EPDC_FIFOCTRL (disabled) */
+ reg_val =
+ ((100 << EPDC_FIFOCTRL_FIFO_INIT_LEVEL_OFFSET) &
+ EPDC_FIFOCTRL_FIFO_INIT_LEVEL_MASK)
+ | ((200 << EPDC_FIFOCTRL_FIFO_H_LEVEL_OFFSET) &
+ EPDC_FIFOCTRL_FIFO_H_LEVEL_MASK)
+ | ((100 << EPDC_FIFOCTRL_FIFO_L_LEVEL_OFFSET) &
+ EPDC_FIFOCTRL_FIFO_L_LEVEL_MASK);
+ __raw_writel(reg_val, EPDC_FIFOCTRL);
+
+ /* EPDC_TEMP - Use default temp to get index */
+ epdc_set_temp(mxc_epdc_fb_get_temp_index(fb_data, DEFAULT_TEMP));
+
+ /* EPDC_RES */
+ epdc_set_screen_res(epdc_mode->vmode->xres, epdc_mode->vmode->yres);
+
+#ifndef EPDC_STANDARD_MODE
+ /* EPDC_AUTOWV_LUT */
+ /* Initialize all auto-wavefrom look-up values to 2 - GC16 */
+ for (i = 0; i < 8; i++)
+ __raw_writel((2 << EPDC_AUTOWV_LUT_DATA_OFFSET) |
+ (i << EPDC_AUTOWV_LUT_ADDR_OFFSET), EPDC_AUTOWV_LUT);
+#endif
+
+ /*
+ * EPDC_TCE_CTRL
+ * VSCAN_HOLDOFF = 4
+ * VCOM_MODE = MANUAL
+ * VCOM_VAL = 0
+ * DDR_MODE = DISABLED
+ * LVDS_MODE_CE = DISABLED
+ * LVDS_MODE = DISABLED
+ * DUAL_SCAN = DISABLED
+ * SDDO_WIDTH = 8bit
+ * PIXELS_PER_SDCLK = 4
+ */
+ reg_val =
+ ((epdc_mode->vscan_holdoff << EPDC_TCE_CTRL_VSCAN_HOLDOFF_OFFSET) &
+ EPDC_TCE_CTRL_VSCAN_HOLDOFF_MASK)
+ | EPDC_TCE_CTRL_PIXELS_PER_SDCLK_4;
+ __raw_writel(reg_val, EPDC_TCE_CTRL);
+
+ /* EPDC_TCE_HSCAN */
+ epdc_set_horizontal_timing(screeninfo->left_margin,
+ screeninfo->right_margin,
+ screeninfo->hsync_len,
+ screeninfo->hsync_len);
+
+ /* EPDC_TCE_VSCAN */
+ epdc_set_vertical_timing(screeninfo->upper_margin,
+ screeninfo->lower_margin,
+ screeninfo->vsync_len);
+
+ /* EPDC_TCE_OE */
+ reg_val =
+ ((epdc_mode->sdoed_width << EPDC_TCE_OE_SDOED_WIDTH_OFFSET) &
+ EPDC_TCE_OE_SDOED_WIDTH_MASK)
+ | ((epdc_mode->sdoed_delay << EPDC_TCE_OE_SDOED_DLY_OFFSET) &
+ EPDC_TCE_OE_SDOED_DLY_MASK)
+ | ((epdc_mode->sdoez_width << EPDC_TCE_OE_SDOEZ_WIDTH_OFFSET) &
+ EPDC_TCE_OE_SDOEZ_WIDTH_MASK)
+ | ((epdc_mode->sdoez_delay << EPDC_TCE_OE_SDOEZ_DLY_OFFSET) &
+ EPDC_TCE_OE_SDOEZ_DLY_MASK);
+ __raw_writel(reg_val, EPDC_TCE_OE);
+
+ /* EPDC_TCE_TIMING1 */
+ __raw_writel(0x0, EPDC_TCE_TIMING1);
+
+ /* EPDC_TCE_TIMING2 */
+ reg_val =
+ ((epdc_mode->gdclk_hp_offs << EPDC_TCE_TIMING2_GDCLK_HP_OFFSET) &
+ EPDC_TCE_TIMING2_GDCLK_HP_MASK)
+ | ((epdc_mode->gdsp_offs << EPDC_TCE_TIMING2_GDSP_OFFSET_OFFSET) &
+ EPDC_TCE_TIMING2_GDSP_OFFSET_MASK);
+ __raw_writel(reg_val, EPDC_TCE_TIMING2);
+
+ /* EPDC_TCE_TIMING3 */
+ reg_val =
+ ((epdc_mode->gdoe_offs << EPDC_TCE_TIMING3_GDOE_OFFSET_OFFSET) &
+ EPDC_TCE_TIMING3_GDOE_OFFSET_MASK)
+ | ((epdc_mode->gdclk_offs << EPDC_TCE_TIMING3_GDCLK_OFFSET_OFFSET) &
+ EPDC_TCE_TIMING3_GDCLK_OFFSET_MASK);
+ __raw_writel(reg_val, EPDC_TCE_TIMING3);
+
+ /*
+ * EPDC_TCE_SDCFG
+ * SDCLK_HOLD = 1
+ * SDSHR = 1
+ * NUM_CE = 1
+ * SDDO_REFORMAT = FLIP_PIXELS
+ * SDDO_INVERT = DISABLED
+ * PIXELS_PER_CE = display horizontal resolution
+ */
+ num_ce = epdc_mode->num_ce;
+ if (num_ce == 0)
+ num_ce = 1;
+ reg_val = EPDC_TCE_SDCFG_SDCLK_HOLD | EPDC_TCE_SDCFG_SDSHR
+ | ((num_ce << EPDC_TCE_SDCFG_NUM_CE_OFFSET) &
+ EPDC_TCE_SDCFG_NUM_CE_MASK)
+ | EPDC_TCE_SDCFG_SDDO_REFORMAT_FLIP_PIXELS
+ | ((epdc_mode->vmode->xres/num_ce << EPDC_TCE_SDCFG_PIXELS_PER_CE_OFFSET) &
+ EPDC_TCE_SDCFG_PIXELS_PER_CE_MASK);
+ __raw_writel(reg_val, EPDC_TCE_SDCFG);
+
+ /*
+ * EPDC_TCE_GDCFG
+ * GDRL = 1
+ * GDOE_MODE = 0;
+ * GDSP_MODE = 0;
+ */
+ reg_val = EPDC_TCE_SDCFG_GDRL;
+ __raw_writel(reg_val, EPDC_TCE_GDCFG);
+
+ /*
+ * EPDC_TCE_POLARITY
+ * SDCE_POL = ACTIVE LOW
+ * SDLE_POL = ACTIVE HIGH
+ * SDOE_POL = ACTIVE HIGH
+ * GDOE_POL = ACTIVE HIGH
+ * GDSP_POL = ACTIVE LOW
+ */
+ reg_val = EPDC_TCE_POLARITY_SDLE_POL_ACTIVE_HIGH
+ | EPDC_TCE_POLARITY_SDOE_POL_ACTIVE_HIGH
+ | EPDC_TCE_POLARITY_GDOE_POL_ACTIVE_HIGH;
+ __raw_writel(reg_val, EPDC_TCE_POLARITY);
+
+ /* EPDC_IRQ_MASK */
+ __raw_writel(EPDC_IRQ_TCE_UNDERRUN_IRQ, EPDC_IRQ_MASK);
+
+ /*
+ * EPDC_GPIO
+ * PWRCOM = ?
+ * PWRCTRL = ?
+ * BDR = ?
+ */
+ reg_val = ((0 << EPDC_GPIO_PWRCTRL_OFFSET) & EPDC_GPIO_PWRCTRL_MASK)
+ | ((0 << EPDC_GPIO_BDR_OFFSET) & EPDC_GPIO_BDR_MASK);
+ __raw_writel(reg_val, EPDC_GPIO);
+
+ __raw_writel(fb_data->waveform_buffer_phys, EPDC_WVADDR);
+ __raw_writel(fb_data->working_buffer_phys, EPDC_WB_ADDR);
+ __raw_writel(fb_data->working_buffer_phys, EPDC_WB_ADDR_TCE);
+
+ bb_p = (unsigned char *)fb_data->virt_addr_black;
+ for (j = 0; j < fb_data->cur_mode->vmode->xres * fb_data->cur_mode->vmode->yres; j++) {
+ *bb_p = 0x0;
+ bb_p++;
+ }
+
+ /* Disable clock */
+ clk_disable_unprepare(fb_data->epdc_clk_axi);
+ clk_disable_unprepare(fb_data->epdc_clk_pix);
+}
+
+static void epdc_powerup(struct mxc_epdc_fb_data *fb_data)
+{
+ int ret = 0;
+ mutex_lock(&fb_data->power_mutex);
+
+ /*
+ * If power down request is pending, clear
+ * powering_down to cancel the request.
+ */
+ if (fb_data->powering_down)
+ fb_data->powering_down = false;
+
+ if (fb_data->power_state == POWER_STATE_ON) {
+ mutex_unlock(&fb_data->power_mutex);
+ return;
+ }
+
+ dev_dbg(fb_data->dev, "EPDC Powerup\n");
+
+ fb_data->updates_active = true;
+
+ /* Enable the v3p3 regulator */
+ ret = regulator_enable(fb_data->v3p3_regulator);
+ if (IS_ERR((void *)ret)) {
+ dev_err(fb_data->dev, "Unable to enable V3P3 regulator."
+ "err = 0x%x\n", ret);
+ mutex_unlock(&fb_data->power_mutex);
+ return;
+ }
+
+ msleep(1);
+
+ pm_runtime_get_sync(fb_data->dev);
+
+ /* Enable clocks to EPDC */
+ clk_prepare_enable(fb_data->epdc_clk_axi);
+ clk_prepare_enable(fb_data->epdc_clk_pix);
+
+ __raw_writel(EPDC_CTRL_CLKGATE, EPDC_CTRL_CLEAR);
+
+ /* Enable power to the EPD panel */
+ ret = regulator_enable(fb_data->display_regulator);
+ if (IS_ERR((void *)ret)) {
+ dev_err(fb_data->dev, "Unable to enable DISPLAY regulator."
+ "err = 0x%x\n", ret);
+ mutex_unlock(&fb_data->power_mutex);
+ return;
+ }
+ ret = regulator_enable(fb_data->vcom_regulator);
+ if (IS_ERR((void *)ret)) {
+ dev_err(fb_data->dev, "Unable to enable VCOM regulator."
+ "err = 0x%x\n", ret);
+ mutex_unlock(&fb_data->power_mutex);
+ return;
+ }
+
+ fb_data->power_state = POWER_STATE_ON;
+
+ mutex_unlock(&fb_data->power_mutex);
+}
+
+static void epdc_powerdown(struct mxc_epdc_fb_data *fb_data)
+{
+ mutex_lock(&fb_data->power_mutex);
+
+ /* If powering_down has been cleared, a powerup
+ * request is pre-empting this powerdown request.
+ */
+ if (!fb_data->powering_down
+ || (fb_data->power_state == POWER_STATE_OFF)) {
+ mutex_unlock(&fb_data->power_mutex);
+ return;
+ }
+
+ dev_dbg(fb_data->dev, "EPDC Powerdown\n");
+
+ /* Disable power to the EPD panel */
+ regulator_disable(fb_data->vcom_regulator);
+ regulator_disable(fb_data->display_regulator);
+
+ /* Disable clocks to EPDC */
+ __raw_writel(EPDC_CTRL_CLKGATE, EPDC_CTRL_SET);
+ clk_disable_unprepare(fb_data->epdc_clk_pix);
+ clk_disable_unprepare(fb_data->epdc_clk_axi);
+
+ pm_runtime_put_sync_suspend(fb_data->dev);
+
+ /* turn off the V3p3 */
+ regulator_disable(fb_data->v3p3_regulator);
+
+ fb_data->power_state = POWER_STATE_OFF;
+ fb_data->powering_down = false;
+
+ if (fb_data->wait_for_powerdown) {
+ fb_data->wait_for_powerdown = false;
+ complete(&fb_data->powerdown_compl);
+ }
+
+ mutex_unlock(&fb_data->power_mutex);
+}
+
+static void epdc_init_sequence(struct mxc_epdc_fb_data *fb_data)
+{
+ /* Initialize EPDC, passing pointer to EPDC registers */
+ epdc_init_settings(fb_data);
+
+ fb_data->in_init = true;
+ epdc_powerup(fb_data);
+ draw_mode0(fb_data);
+ /* Force power down event */
+ fb_data->powering_down = true;
+ epdc_powerdown(fb_data);
+ fb_data->updates_active = false;
+}
+
+static int mxc_epdc_fb_mmap(struct fb_info *info, struct vm_area_struct *vma)
+{
+ u32 len;
+ unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
+
+ if (offset < info->fix.smem_len) {
+ /* mapping framebuffer memory */
+ len = info->fix.smem_len - offset;
+ vma->vm_pgoff = (info->fix.smem_start + offset) >> PAGE_SHIFT;
+ } else
+ return -EINVAL;
+
+ len = PAGE_ALIGN(len);
+ if (vma->vm_end - vma->vm_start > len)
+ return -EINVAL;
+
+ /* make buffers bufferable */
+ vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
+
+ if (remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
+ vma->vm_end - vma->vm_start, vma->vm_page_prot)) {
+ dev_dbg(info->device, "mmap remap_pfn_range failed\n");
+ return -ENOBUFS;
+ }
+
+ return 0;
+}
+
+static inline u_int _chan_to_field(u_int chan, struct fb_bitfield *bf)
+{
+ chan &= 0xffff;
+ chan >>= 16 - bf->length;
+ return chan << bf->offset;
+}
+
+static int mxc_epdc_fb_setcolreg(u_int regno, u_int red, u_int green,
+ u_int blue, u_int transp, struct fb_info *info)
+{
+ unsigned int val;
+ int ret = 1;
+
+ /*
+ * If greyscale is true, then we convert the RGB value
+ * to greyscale no matter what visual we are using.
+ */
+ if (info->var.grayscale)
+ red = green = blue = (19595 * red + 38470 * green +
+ 7471 * blue) >> 16;
+ switch (info->fix.visual) {
+ case FB_VISUAL_TRUECOLOR:
+ /*
+ * 16-bit True Colour. We encode the RGB value
+ * according to the RGB bitfield information.
+ */
+ if (regno < 16) {
+ u32 *pal = info->pseudo_palette;
+
+ val = _chan_to_field(red, &info->var.red);
+ val |= _chan_to_field(green, &info->var.green);
+ val |= _chan_to_field(blue, &info->var.blue);
+
+ pal[regno] = val;
+ ret = 0;
+ }
+ break;
+
+ case FB_VISUAL_STATIC_PSEUDOCOLOR:
+ case FB_VISUAL_PSEUDOCOLOR:
+ break;
+ }
+
+ return ret;
+}
+
+static int mxc_epdc_fb_setcmap(struct fb_cmap *cmap, struct fb_info *info)
+{
+ int count, index, r;
+ u16 *red, *green, *blue, *transp;
+ u16 trans = 0xffff;
+ struct mxc_epdc_fb_data *fb_data = (struct mxc_epdc_fb_data *)info;
+ int i;
+
+ dev_dbg(fb_data->dev, "setcmap\n");
+
+ if (info->fix.visual == FB_VISUAL_STATIC_PSEUDOCOLOR) {
+ /* Only support an 8-bit, 256 entry lookup */
+ if (cmap->len != 256)
+ return 1;
+
+ mxc_epdc_fb_flush_updates(fb_data);
+
+ mutex_lock(&fb_data->pxp_mutex);
+ /*
+ * Store colormap in pxp_conf structure for later transmit
+ * to PxP during update process to convert gray pixels.
+ *
+ * Since red=blue=green for pseudocolor visuals, we can
+ * just use red values.
+ */
+ for (i = 0; i < 256; i++)
+ fb_data->pxp_conf.proc_data.lut_map[i] = cmap->red[i] & 0xFF;
+
+ fb_data->pxp_conf.proc_data.lut_map_updated = true;
+
+ mutex_unlock(&fb_data->pxp_mutex);
+ } else {
+ red = cmap->red;
+ green = cmap->green;
+ blue = cmap->blue;
+ transp = cmap->transp;
+ index = cmap->start;
+
+ for (count = 0; count < cmap->len; count++) {
+ if (transp)
+ trans = *transp++;
+ r = mxc_epdc_fb_setcolreg(index++, *red++, *green++, *blue++,
+ trans, info);
+ if (r != 0)
+ return r;
+ }
+ }
+
+ return 0;
+}
+
+static void adjust_coordinates(u32 xres, u32 yres, u32 rotation,
+ struct mxcfb_rect *update_region, struct mxcfb_rect *adj_update_region)
+{
+ u32 temp;
+
+ /* If adj_update_region == NULL, pass result back in update_region */
+ /* If adj_update_region == valid, use it to pass back result */
+ if (adj_update_region)
+ switch (rotation) {
+ case FB_ROTATE_UR:
+ adj_update_region->top = update_region->top;
+ adj_update_region->left = update_region->left;
+ adj_update_region->width = update_region->width;
+ adj_update_region->height = update_region->height;
+ break;
+ case FB_ROTATE_CW:
+ adj_update_region->top = update_region->left;
+ adj_update_region->left = yres -
+ (update_region->top + update_region->height);
+ adj_update_region->width = update_region->height;
+ adj_update_region->height = update_region->width;
+ break;
+ case FB_ROTATE_UD:
+ adj_update_region->width = update_region->width;
+ adj_update_region->height = update_region->height;
+ adj_update_region->top = yres -
+ (update_region->top + update_region->height);
+ adj_update_region->left = xres -
+ (update_region->left + update_region->width);
+ break;
+ case FB_ROTATE_CCW:
+ adj_update_region->left = update_region->top;
+ adj_update_region->top = xres -
+ (update_region->left + update_region->width);
+ adj_update_region->width = update_region->height;
+ adj_update_region->height = update_region->width;
+ break;
+ }
+ else
+ switch (rotation) {
+ case FB_ROTATE_UR:
+ /* No adjustment needed */
+ break;
+ case FB_ROTATE_CW:
+ temp = update_region->top;
+ update_region->top = update_region->left;
+ update_region->left = yres -
+ (temp + update_region->height);
+ temp = update_region->width;
+ update_region->width = update_region->height;
+ update_region->height = temp;
+ break;
+ case FB_ROTATE_UD:
+ update_region->top = yres -
+ (update_region->top + update_region->height);
+ update_region->left = xres -
+ (update_region->left + update_region->width);
+ break;
+ case FB_ROTATE_CCW:
+ temp = update_region->left;
+ update_region->left = update_region->top;
+ update_region->top = xres -
+ (temp + update_region->width);
+ temp = update_region->width;
+ update_region->width = update_region->height;
+ update_region->height = temp;
+ break;
+ }
+}
+
+/*
+ * Set fixed framebuffer parameters based on variable settings.
+ *
+ * @param info framebuffer information pointer
+ */
+static int mxc_epdc_fb_set_fix(struct fb_info *info)
+{
+ struct fb_fix_screeninfo *fix = &info->fix;
+ struct fb_var_screeninfo *var = &info->var;
+
+ fix->line_length = var->xres_virtual * var->bits_per_pixel / 8;
+
+ fix->type = FB_TYPE_PACKED_PIXELS;
+ fix->accel = FB_ACCEL_NONE;
+ if (var->grayscale)
+ fix->visual = FB_VISUAL_STATIC_PSEUDOCOLOR;
+ else
+ fix->visual = FB_VISUAL_TRUECOLOR;
+ fix->xpanstep = 1;
+ fix->ypanstep = 1;
+
+ return 0;
+}
+
+/*
+ * This routine actually sets the video mode. It's in here where we
+ * the hardware state info->par and fix which can be affected by the
+ * change in par. For this driver it doesn't do much.
+ *
+ */
+static int mxc_epdc_fb_set_par(struct fb_info *info)
+{
+ struct mxc_epdc_fb_data *fb_data = (struct mxc_epdc_fb_data *)info;
+ struct pxp_config_data *pxp_conf = &fb_data->pxp_conf;
+ struct pxp_proc_data *proc_data = &pxp_conf->proc_data;
+ struct fb_var_screeninfo *screeninfo = &fb_data->info.var;
+ struct imx_epdc_fb_mode *epdc_modes = fb_data->pdata->epdc_mode;
+ int i;
+ int ret;
+ __u32 xoffset_old, yoffset_old;
+
+ /*
+ * Can't change the FB parameters until current updates have completed.
+ * This function returns when all active updates are done.
+ */
+ mxc_epdc_fb_flush_updates(fb_data);
+
+ mutex_lock(&fb_data->queue_mutex);
+ /*
+ * Set all screeninfo except for xoffset/yoffset
+ * Subsequent call to pan_display will handle those.
+ */
+ xoffset_old = fb_data->epdc_fb_var.xoffset;
+ yoffset_old = fb_data->epdc_fb_var.yoffset;
+ fb_data->epdc_fb_var = *screeninfo;
+ fb_data->epdc_fb_var.xoffset = xoffset_old;
+ fb_data->epdc_fb_var.yoffset = yoffset_old;
+ mutex_unlock(&fb_data->queue_mutex);
+
+ mutex_lock(&fb_data->pxp_mutex);
+
+ /*
+ * Update PxP config data (used to process FB regions for updates)
+ * based on FB info and processing tasks required
+ */
+
+ /* Initialize non-channel-specific PxP parameters */
+ proc_data->drect.left = proc_data->srect.left = 0;
+ proc_data->drect.top = proc_data->srect.top = 0;
+ proc_data->drect.width = proc_data->srect.width = screeninfo->xres;
+ proc_data->drect.height = proc_data->srect.height = screeninfo->yres;
+ proc_data->scaling = 0;
+ proc_data->hflip = 0;
+ proc_data->vflip = 0;
+ proc_data->rotate = screeninfo->rotate;
+ proc_data->bgcolor = 0;
+ proc_data->overlay_state = 0;
+ proc_data->lut_transform = PXP_LUT_NONE;
+
+ /*
+ * configure S0 channel parameters
+ * Parameters should match FB format/width/height
+ */
+ if (screeninfo->grayscale)
+ pxp_conf->s0_param.pixel_fmt = PXP_PIX_FMT_GREY;
+ else {
+ switch (screeninfo->bits_per_pixel) {
+ case 16:
+ pxp_conf->s0_param.pixel_fmt = PXP_PIX_FMT_RGB565;
+ break;
+ case 24:
+ pxp_conf->s0_param.pixel_fmt = PXP_PIX_FMT_RGB24;
+ break;
+ case 32:
+ pxp_conf->s0_param.pixel_fmt = PXP_PIX_FMT_XRGB32;
+ break;
+ default:
+ pxp_conf->s0_param.pixel_fmt = PXP_PIX_FMT_RGB565;
+ break;
+ }
+ }
+ pxp_conf->s0_param.width = screeninfo->xres_virtual;
+ pxp_conf->s0_param.stride = (screeninfo->bits_per_pixel * pxp_conf->s0_param.width) >> 3;
+ pxp_conf->s0_param.height = screeninfo->yres;
+ pxp_conf->s0_param.color_key = -1;
+ pxp_conf->s0_param.color_key_enable = false;
+
+ /*
+ * Initialize Output channel parameters
+ * Output is Y-only greyscale
+ * Output width/height will vary based on update region size
+ */
+ pxp_conf->out_param.width = screeninfo->xres;
+ pxp_conf->out_param.height = screeninfo->yres;
+ pxp_conf->out_param.pixel_fmt = PXP_PIX_FMT_GREY;
+
+ mutex_unlock(&fb_data->pxp_mutex);
+
+ /*
+ * If HW not yet initialized, check to see if we are being sent
+ * an initialization request.
+ */
+ if (!fb_data->hw_ready) {
+ struct fb_videomode mode;
+ u32 xres_temp;
+
+ fb_var_to_videomode(&mode, screeninfo);
+
+ /* When comparing requested fb mode,
+ we need to use unrotated dimensions */
+ if ((screeninfo->rotate == FB_ROTATE_CW) ||
+ (screeninfo->rotate == FB_ROTATE_CCW)) {
+ xres_temp = mode.xres;
+ mode.xres = mode.yres;
+ mode.yres = xres_temp;
+ }
+
+ /*
+ * If requested video mode does not match current video
+ * mode, search for a matching panel.
+ */
+ if (fb_data->cur_mode &&
+ !fb_mode_is_equal(fb_data->cur_mode->vmode,
+ &mode)) {
+ bool found_match = false;
+
+ /* Match videomode against epdc modes */
+ for (i = 0; i < fb_data->pdata->num_modes; i++) {
+ if (!fb_mode_is_equal(epdc_modes[i].vmode,
+ &mode))
+ continue;
+ fb_data->cur_mode = &epdc_modes[i];
+ found_match = true;
+ break;
+ }
+
+ if (!found_match) {
+ dev_err(fb_data->dev,
+ "Failed to match requested "
+ "video mode\n");
+ return EINVAL;
+ }
+ }
+
+ /* Found a match - Grab timing params */
+ screeninfo->left_margin = mode.left_margin;
+ screeninfo->right_margin = mode.right_margin;
+ screeninfo->upper_margin = mode.upper_margin;
+ screeninfo->lower_margin = mode.lower_margin;
+ screeninfo->hsync_len = mode.hsync_len;
+ screeninfo->vsync_len = mode.vsync_len;
+
+ fb_data->hw_initializing = true;
+
+ /* Initialize EPDC settings and init panel */
+ ret =
+ mxc_epdc_fb_init_hw((struct fb_info *)fb_data);
+ if (ret) {
+ dev_err(fb_data->dev,
+ "Failed to load panel waveform data\n");
+ return ret;
+ }
+ }
+
+ /*
+ * EOF sync delay (in us) should be equal to the vscan holdoff time
+ * VSCAN_HOLDOFF time = (VSCAN_HOLDOFF value + 1) * Vertical lines
+ * Add 25us for additional margin
+ */
+ fb_data->eof_sync_period = (fb_data->cur_mode->vscan_holdoff + 1) *
+ 1000000/(fb_data->cur_mode->vmode->refresh *
+ (fb_data->cur_mode->vmode->upper_margin +
+ fb_data->cur_mode->vmode->yres +
+ fb_data->cur_mode->vmode->lower_margin +
+ fb_data->cur_mode->vmode->vsync_len)) + 25;
+
+ mxc_epdc_fb_set_fix(info);
+
+ return 0;
+}
+
+static int mxc_epdc_fb_check_var(struct fb_var_screeninfo *var,
+ struct fb_info *info)
+{
+ struct mxc_epdc_fb_data *fb_data = (struct mxc_epdc_fb_data *)info;
+
+ if (!var->xres)
+ var->xres = 1;
+ if (!var->yres)
+ var->yres = 1;
+
+ if (var->xres_virtual < var->xoffset + var->xres)
+ var->xres_virtual = var->xoffset + var->xres;
+ if (var->yres_virtual < var->yoffset + var->yres)
+ var->yres_virtual = var->yoffset + var->yres;
+
+ if ((var->bits_per_pixel != 32) && (var->bits_per_pixel != 24) &&
+ (var->bits_per_pixel != 16) && (var->bits_per_pixel != 8))
+ var->bits_per_pixel = default_bpp;
+
+ switch (var->bits_per_pixel) {
+ case 8:
+ if (var->grayscale != 0) {
+ /*
+ * For 8-bit grayscale, R, G, and B offset are equal.
+ *
+ */
+ var->red.length = 8;
+ var->red.offset = 0;
+ var->red.msb_right = 0;
+
+ var->green.length = 8;
+ var->green.offset = 0;
+ var->green.msb_right = 0;
+
+ var->blue.length = 8;
+ var->blue.offset = 0;
+ var->blue.msb_right = 0;
+
+ var->transp.length = 0;
+ var->transp.offset = 0;
+ var->transp.msb_right = 0;
+ } else {
+ var->red.length = 3;
+ var->red.offset = 5;
+ var->red.msb_right = 0;
+
+ var->green.length = 3;
+ var->green.offset = 2;
+ var->green.msb_right = 0;
+
+ var->blue.length = 2;
+ var->blue.offset = 0;
+ var->blue.msb_right = 0;
+
+ var->transp.length = 0;
+ var->transp.offset = 0;
+ var->transp.msb_right = 0;
+ }
+ break;
+ case 16:
+ var->red.length = 5;
+ var->red.offset = 11;
+ var->red.msb_right = 0;
+
+ var->green.length = 6;
+ var->green.offset = 5;
+ var->green.msb_right = 0;
+
+ var->blue.length = 5;
+ var->blue.offset = 0;
+ var->blue.msb_right = 0;
+
+ var->transp.length = 0;
+ var->transp.offset = 0;
+ var->transp.msb_right = 0;
+ break;
+ case 24:
+ var->red.length = 8;
+ var->red.offset = 16;
+ var->red.msb_right = 0;
+
+ var->green.length = 8;
+ var->green.offset = 8;
+ var->green.msb_right = 0;
+
+ var->blue.length = 8;
+ var->blue.offset = 0;
+ var->blue.msb_right = 0;
+
+ var->transp.length = 0;
+ var->transp.offset = 0;
+ var->transp.msb_right = 0;
+ break;
+ case 32:
+ var->red.length = 8;
+ var->red.offset = 16;
+ var->red.msb_right = 0;
+
+ var->green.length = 8;
+ var->green.offset = 8;
+ var->green.msb_right = 0;
+
+ var->blue.length = 8;
+ var->blue.offset = 0;
+ var->blue.msb_right = 0;
+
+ var->transp.length = 8;
+ var->transp.offset = 24;
+ var->transp.msb_right = 0;
+ break;
+ }
+
+ switch (var->rotate) {
+ case FB_ROTATE_UR:
+ case FB_ROTATE_UD:
+ var->xres = fb_data->native_width;
+ var->yres = fb_data->native_height;
+ break;
+ case FB_ROTATE_CW:
+ case FB_ROTATE_CCW:
+ var->xres = fb_data->native_height;
+ var->yres = fb_data->native_width;
+ break;
+ default:
+ /* Invalid rotation value */
+ var->rotate = 0;
+ dev_dbg(fb_data->dev, "Invalid rotation request\n");
+ return -EINVAL;
+ }
+
+ var->xres_virtual = ALIGN(var->xres, 32);
+ var->yres_virtual = ALIGN(var->yres, 128) * fb_data->num_screens;
+
+ var->height = -1;
+ var->width = -1;
+
+ return 0;
+}
+
+static void mxc_epdc_fb_set_waveform_modes(struct mxcfb_waveform_modes *modes,
+ struct fb_info *info)
+{
+ struct mxc_epdc_fb_data *fb_data = info ?
+ (struct mxc_epdc_fb_data *)info:g_fb_data;
+
+ mutex_lock(&fb_data->queue_mutex);
+
+ memcpy(&fb_data->wv_modes, modes, sizeof(struct mxcfb_waveform_modes));
+
+ /* Set flag to ensure that new waveform modes
+ * are programmed into EPDC before next update */
+ fb_data->wv_modes_update = true;
+
+ mutex_unlock(&fb_data->queue_mutex);
+}
+
+static int mxc_epdc_fb_get_temp_index(struct mxc_epdc_fb_data *fb_data, int temp)
+{
+ int i;
+ int index = -1;
+
+ if (fb_data->trt_entries == 0) {
+ dev_err(fb_data->dev,
+ "No TRT exists...using default temp index\n");
+ return DEFAULT_TEMP_INDEX;
+ }
+
+ /* Search temperature ranges for a match */
+ for (i = 0; i < fb_data->trt_entries - 1; i++) {
+ if ((temp >= fb_data->temp_range_bounds[i])
+ && (temp < fb_data->temp_range_bounds[i+1])) {
+ index = i;
+ break;
+ }
+ }
+
+ if (index < 0) {
+ dev_err(fb_data->dev,
+ "No TRT index match...using default temp index\n");
+ return DEFAULT_TEMP_INDEX;
+ }
+
+ dev_dbg(fb_data->dev, "Using temperature index %d\n", index);
+
+ return index;
+}
+
+static int mxc_epdc_fb_set_temperature(int temperature, struct fb_info *info)
+{
+ struct mxc_epdc_fb_data *fb_data = info ?
+ (struct mxc_epdc_fb_data *)info:g_fb_data;
+
+ /* Store temp index. Used later when configuring updates. */
+ mutex_lock(&fb_data->queue_mutex);
+ fb_data->temp_index = mxc_epdc_fb_get_temp_index(fb_data, temperature);
+ mutex_unlock(&fb_data->queue_mutex);
+
+ return 0;
+}
+
+static int mxc_epdc_fb_set_auto_update(u32 auto_mode, struct fb_info *info)
+{
+ struct mxc_epdc_fb_data *fb_data = info ?
+ (struct mxc_epdc_fb_data *)info:g_fb_data;
+
+ dev_dbg(fb_data->dev, "Setting auto update mode to %d\n", auto_mode);
+
+ if ((auto_mode == AUTO_UPDATE_MODE_AUTOMATIC_MODE)
+ || (auto_mode == AUTO_UPDATE_MODE_REGION_MODE))
+ fb_data->auto_mode = auto_mode;
+ else {
+ dev_err(fb_data->dev, "Invalid auto update mode parameter.\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int mxc_epdc_fb_set_upd_scheme(u32 upd_scheme, struct fb_info *info)
+{
+ struct mxc_epdc_fb_data *fb_data = info ?
+ (struct mxc_epdc_fb_data *)info:g_fb_data;
+
+ dev_dbg(fb_data->dev, "Setting optimization level to %d\n", upd_scheme);
+
+ /*
+ * Can't change the scheme until current updates have completed.
+ * This function returns when all active updates are done.
+ */
+ mxc_epdc_fb_flush_updates(fb_data);
+
+ if ((upd_scheme == UPDATE_SCHEME_SNAPSHOT)
+ || (upd_scheme == UPDATE_SCHEME_QUEUE)
+ || (upd_scheme == UPDATE_SCHEME_QUEUE_AND_MERGE))
+ fb_data->upd_scheme = upd_scheme;
+ else {
+ dev_err(fb_data->dev, "Invalid update scheme specified.\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static void copy_before_process(struct mxc_epdc_fb_data *fb_data,
+ struct update_data_list *upd_data_list)
+{
+ struct mxcfb_update_data *upd_data =
+ &upd_data_list->update_desc->upd_data;
+ int i;
+ unsigned char *temp_buf_ptr = fb_data->virt_addr_copybuf;
+ unsigned char *src_ptr;
+ struct mxcfb_rect *src_upd_region;
+ int temp_buf_stride;
+ int src_stride;
+ int bpp = fb_data->epdc_fb_var.bits_per_pixel;
+ int left_offs, right_offs;
+ int x_trailing_bytes, y_trailing_bytes;
+ int alt_buf_offset;
+
+ /* Set source buf pointer based on input source, panning, etc. */
+ if (upd_data->flags & EPDC_FLAG_USE_ALT_BUFFER) {
+ src_upd_region = &upd_data->alt_buffer_data.alt_update_region;
+ src_stride =
+ upd_data->alt_buffer_data.width * bpp/8;
+ alt_buf_offset = upd_data->alt_buffer_data.phys_addr -
+ fb_data->info.fix.smem_start;
+ src_ptr = fb_data->info.screen_base + alt_buf_offset
+ + src_upd_region->top * src_stride;
+ } else {
+ src_upd_region = &upd_data->update_region;
+ src_stride = fb_data->epdc_fb_var.xres_virtual * bpp/8;
+ src_ptr = fb_data->info.screen_base + fb_data->fb_offset
+ + src_upd_region->top * src_stride;
+ }
+
+ temp_buf_stride = ALIGN(src_upd_region->width, 8) * bpp/8;
+ left_offs = src_upd_region->left * bpp/8;
+ right_offs = src_upd_region->width * bpp/8;
+ x_trailing_bytes = (ALIGN(src_upd_region->width, 8)
+ - src_upd_region->width) * bpp/8;
+
+ for (i = 0; i < src_upd_region->height; i++) {
+ /* Copy the full line */
+ memcpy(temp_buf_ptr, src_ptr + left_offs,
+ src_upd_region->width * bpp/8);
+
+ /* Clear any unwanted pixels at the end of each line */
+ if (src_upd_region->width & 0x7) {
+ memset(temp_buf_ptr + right_offs, 0x0,
+ x_trailing_bytes);
+ }
+
+ temp_buf_ptr += temp_buf_stride;
+ src_ptr += src_stride;
+ }
+
+ /* Clear any unwanted pixels at the bottom of the end of each line */
+ if (src_upd_region->height & 0x7) {
+ y_trailing_bytes = (ALIGN(src_upd_region->height, 8)
+ - src_upd_region->height) *
+ ALIGN(src_upd_region->width, 8) * bpp/8;
+ memset(temp_buf_ptr, 0x0, y_trailing_bytes);
+ }
+}
+
+/* Before every update to panel, we should call this
+ * function to update the working buffer first.
+ */
+static int epdc_working_buffer_update(struct mxc_epdc_fb_data *fb_data,
+ struct update_data_list *upd_data_list,
+ struct mxcfb_rect *update_region)
+{
+ struct pxp_proc_data *proc_data = &fb_data->pxp_conf.proc_data;
+ u32 wv_mode = upd_data_list->update_desc->upd_data.waveform_mode;
+ int ret = 0;
+ u32 hist_stat;
+ struct update_desc_list *upd_desc_list;
+
+ ret = pxp_wfe_a_process(fb_data, update_region, upd_data_list);
+ if (ret) {
+ dev_err(fb_data->dev, "Unable to submit PxP update task.\n");
+ mutex_unlock(&fb_data->pxp_mutex);
+ return ret;
+ }
+
+ /* If needed, enable EPDC HW while ePxP is processing */
+ if ((fb_data->power_state == POWER_STATE_OFF)
+ || fb_data->powering_down) {
+ epdc_powerup(fb_data);
+ }
+
+ /* This is a blocking call, so upon return PxP tx should be done */
+ ret = pxp_complete_update(fb_data, &fb_data->hist_status);
+ if (ret) {
+ dev_err(fb_data->dev, "Unable to complete PxP update task: main process\n");
+ return ret;
+ }
+
+ upd_desc_list = upd_data_list->update_desc;
+ if (fb_data->epdc_wb_mode &&
+ (upd_desc_list->upd_data.waveform_mode == WAVEFORM_MODE_AUTO)) {
+ hist_stat = fb_data->hist_status;
+
+ if (hist_stat & 0x1)
+ upd_desc_list->upd_data.waveform_mode =
+ fb_data->wv_modes.mode_du;
+ else if (hist_stat & 0x2)
+ upd_desc_list->upd_data.waveform_mode =
+ fb_data->wv_modes.mode_gc4;
+ else if (hist_stat & 0x4)
+ upd_desc_list->upd_data.waveform_mode =
+ fb_data->wv_modes.mode_gc8;
+ else if (hist_stat & 0x8)
+ upd_desc_list->upd_data.waveform_mode =
+ fb_data->wv_modes.mode_gc16;
+ else
+ upd_desc_list->upd_data.waveform_mode =
+ fb_data->wv_modes.mode_gc32;
+
+ dev_dbg(fb_data->dev, "hist_stat = 0x%x, new waveform = 0x%x\n",
+ hist_stat, upd_desc_list->upd_data.waveform_mode);
+ }
+
+ if (proc_data->detection_only == 1) {
+ dev_dbg(fb_data->dev, "collision detection only, no real update\n");
+ return 0;
+ }
+
+ if (fb_data->col_info.pixel_cnt) {
+ dev_dbg(fb_data->dev, "collision detected, can not do REAGl/-D\n");
+ return 0;
+ }
+
+ /* for REAGL/-D Processing */
+ if (wv_mode == WAVEFORM_MODE_GLR16
+ || wv_mode == WAVEFORM_MODE_GLD16) {
+ /* This is a blocking call, so upon return PxP tx should be done */
+ ret = pxp_wfe_b_process_update(fb_data, update_region);
+ if (ret) {
+ dev_err(fb_data->dev, "Unable to submit PxP update task.\n");
+ mutex_unlock(&fb_data->pxp_mutex);
+ return ret;
+ }
+
+ /* If needed, enable EPDC HW while ePxP is processing */
+ if ((fb_data->power_state == POWER_STATE_OFF)
+ || fb_data->powering_down) {
+ epdc_powerup(fb_data);
+ }
+
+ /* This is a blocking call, so upon return PxP tx should be done */
+ ret = pxp_complete_update(fb_data, &hist_stat);
+ if (ret) {
+ dev_err(fb_data->dev, "Unable to complete PxP update task: reagl/-d process\n");
+ mutex_unlock(&fb_data->pxp_mutex);
+ return ret;
+ }
+
+ }
+
+ return 0;
+}
+
+static int epdc_process_update(struct update_data_list *upd_data_list,
+ struct mxc_epdc_fb_data *fb_data)
+{
+ struct mxcfb_rect *src_upd_region; /* Region of src buffer for update */
+ struct mxcfb_rect pxp_upd_region;
+ u32 src_width, src_height;
+ u32 offset_from_4, bytes_per_pixel;
+ u32 post_rotation_xcoord, post_rotation_ycoord, width_pxp_blocks;
+ u32 pxp_input_offs, pxp_output_offs, pxp_output_shift;
+ u32 hist_stat = 0;
+ int width_unaligned, height_unaligned;
+ bool input_unaligned = false;
+ bool line_overflow = false;
+ int pix_per_line_added;
+ bool use_temp_buf = false;
+ struct mxcfb_rect temp_buf_upd_region;
+ struct update_desc_list *upd_desc_list = upd_data_list->update_desc;
+
+ int ret;
+
+ /*
+ * Gotta do a whole bunch of buffer ptr manipulation to
+ * work around HW restrictions for PxP & EPDC
+ * Note: Applies to pre-2.0 versions of EPDC/PxP
+ */
+
+ /*
+ * Are we using FB or an alternate (overlay)
+ * buffer for source of update?
+ */
+ if (upd_desc_list->upd_data.flags & EPDC_FLAG_USE_ALT_BUFFER) {
+ src_width = upd_desc_list->upd_data.alt_buffer_data.width;
+ src_height = upd_desc_list->upd_data.alt_buffer_data.height;
+ src_upd_region = &upd_desc_list->upd_data.alt_buffer_data.alt_update_region;
+ } else {
+ src_width = fb_data->epdc_fb_var.xres_virtual;
+ src_height = fb_data->epdc_fb_var.yres;
+ src_upd_region = &upd_desc_list->upd_data.update_region;
+ }
+
+ bytes_per_pixel = fb_data->epdc_fb_var.bits_per_pixel/8;
+
+ /*
+ * SW workaround for PxP limitation (for pre-v2.0 HW)
+ *
+ * There are 3 cases where we cannot process the update data
+ * directly from the input buffer:
+ *
+ * 1) PxP must process 8x8 pixel blocks, and all pixels in each block
+ * are considered for auto-waveform mode selection. If the
+ * update region is not 8x8 aligned, additional unwanted pixels
+ * will be considered in auto-waveform mode selection.
+ *
+ * 2) PxP input must be 32-bit aligned, so any update
+ * address not 32-bit aligned must be shifted to meet the
+ * 32-bit alignment. The PxP will thus end up processing pixels
+ * outside of the update region to satisfy this alignment restriction,
+ * which can affect auto-waveform mode selection.
+ *
+ * 3) If input fails 32-bit alignment, and the resulting expansion
+ * of the processed region would add at least 8 pixels more per
+ * line than the original update line width, the EPDC would
+ * cause screen artifacts by incorrectly handling the 8+ pixels
+ * at the end of each line.
+ *
+ * Workaround is to copy from source buffer into a temporary
+ * buffer, which we pad with zeros to match the 8x8 alignment
+ * requirement. This temp buffer becomes the input to the PxP.
+ */
+ width_unaligned = src_upd_region->width & 0x7;
+ height_unaligned = src_upd_region->height & 0x7;
+
+ offset_from_4 = src_upd_region->left & 0x3;
+ input_unaligned = ((offset_from_4 * bytes_per_pixel % 4) != 0) ?
+ true : false;
+
+ pix_per_line_added = (offset_from_4 * bytes_per_pixel % 4)
+ / bytes_per_pixel;
+ if ((((fb_data->epdc_fb_var.rotate == FB_ROTATE_UR) ||
+ fb_data->epdc_fb_var.rotate == FB_ROTATE_UD)) &&
+ (ALIGN(src_upd_region->width, 8) <
+ ALIGN(src_upd_region->width + pix_per_line_added, 8)))
+ line_overflow = true;
+
+ /* Grab pxp_mutex here so that we protect access
+ * to copybuf in addition to the PxP structures */
+ mutex_lock(&fb_data->pxp_mutex);
+
+ if (((((width_unaligned || height_unaligned || input_unaligned) &&
+ (upd_desc_list->upd_data.waveform_mode == WAVEFORM_MODE_AUTO))
+ || line_overflow) && (fb_data->rev < 20)) ||
+ fb_data->restrict_width) {
+ dev_dbg(fb_data->dev, "Copying update before processing.\n");
+
+ /* Update to reflect what the new source buffer will be */
+ src_width = ALIGN(src_upd_region->width, 8);
+ src_height = ALIGN(src_upd_region->height, 8);
+
+ copy_before_process(fb_data, upd_data_list);
+
+ /*
+ * src_upd_region should now describe
+ * the new update buffer attributes.
+ */
+ temp_buf_upd_region.left = 0;
+ temp_buf_upd_region.top = 0;
+ temp_buf_upd_region.width = src_upd_region->width;
+ temp_buf_upd_region.height = src_upd_region->height;
+ src_upd_region = &temp_buf_upd_region;
+
+ use_temp_buf = true;
+ }
+
+ /*
+ * For pre-2.0 HW, input address must be 32-bit aligned
+ * Compute buffer offset to account for this PxP limitation
+ */
+ offset_from_4 = src_upd_region->left & 0x3;
+ input_unaligned = ((offset_from_4 * bytes_per_pixel % 4) != 0) ?
+ true : false;
+ if ((fb_data->rev < 20) && input_unaligned) {
+ /* Leave a gap between PxP input addr and update region pixels */
+ pxp_input_offs =
+ (src_upd_region->top * src_width + src_upd_region->left)
+ * bytes_per_pixel & 0xFFFFFFFC;
+ /* Update region left changes to reflect relative position to input ptr */
+ pxp_upd_region.left = (offset_from_4 * bytes_per_pixel % 4)
+ / bytes_per_pixel;
+ } else {
+ pxp_input_offs =
+ (src_upd_region->top * src_width + src_upd_region->left)
+ * bytes_per_pixel;
+ pxp_upd_region.left = 0;
+ }
+
+ pxp_upd_region.top = 0;
+
+ /*
+ * For version 2.0 and later of EPDC & PxP, if no rotation, we don't
+ * need to align width & height (rotation always requires 8-pixel
+ * width & height alignment, per PxP limitations)
+ */
+ if ((fb_data->epdc_fb_var.rotate == 0) && (fb_data->rev >= 20)) {
+ pxp_upd_region.width = src_upd_region->width;
+ pxp_upd_region.height = src_upd_region->height;
+ } else {
+ /* Update region dimensions to meet 8x8 pixel requirement */
+ pxp_upd_region.width = ALIGN(src_upd_region->width + pxp_upd_region.left, 8);
+ pxp_upd_region.height = ALIGN(src_upd_region->height, 8);
+ }
+
+ switch (fb_data->epdc_fb_var.rotate) {
+ case FB_ROTATE_UR:
+ default:
+ post_rotation_xcoord = pxp_upd_region.left;
+ post_rotation_ycoord = pxp_upd_region.top;
+ width_pxp_blocks = pxp_upd_region.width;
+ break;
+ case FB_ROTATE_CW:
+ width_pxp_blocks = pxp_upd_region.height;
+ post_rotation_xcoord = width_pxp_blocks - src_upd_region->height;
+ post_rotation_ycoord = pxp_upd_region.left;
+ break;
+ case FB_ROTATE_UD:
+ width_pxp_blocks = pxp_upd_region.width;
+ post_rotation_xcoord = width_pxp_blocks - src_upd_region->width - pxp_upd_region.left;
+ post_rotation_ycoord = pxp_upd_region.height - src_upd_region->height - pxp_upd_region.top;
+ break;
+ case FB_ROTATE_CCW:
+ width_pxp_blocks = pxp_upd_region.height;
+ post_rotation_xcoord = pxp_upd_region.top;
+ post_rotation_ycoord = pxp_upd_region.width - src_upd_region->width - pxp_upd_region.left;
+ break;
+ }
+
+ /* Update region start coord to force PxP to process full 8x8 regions */
+ pxp_upd_region.top &= ~0x7;
+ pxp_upd_region.left &= ~0x7;
+
+ if (fb_data->rev < 20) {
+ pxp_output_shift = ALIGN(post_rotation_xcoord, 8)
+ - post_rotation_xcoord;
+
+ pxp_output_offs = post_rotation_ycoord * width_pxp_blocks
+ + pxp_output_shift;
+
+ upd_desc_list->epdc_offs = ALIGN(pxp_output_offs, 8);
+ } else {
+ pxp_output_shift = 0;
+ pxp_output_offs = post_rotation_ycoord * width_pxp_blocks
+ + post_rotation_xcoord;
+
+ upd_desc_list->epdc_offs = pxp_output_offs;
+ }
+
+ upd_desc_list->epdc_stride = width_pxp_blocks;
+
+ /* Source address either comes from alternate buffer
+ provided in update data, or from the framebuffer. */
+ if (use_temp_buf)
+ sg_dma_address(&fb_data->sg[0]) =
+ fb_data->phys_addr_copybuf;
+ else if (upd_desc_list->upd_data.flags & EPDC_FLAG_USE_ALT_BUFFER)
+ sg_dma_address(&fb_data->sg[0]) =
+ upd_desc_list->upd_data.alt_buffer_data.phys_addr
+ + pxp_input_offs;
+ else {
+ sg_dma_address(&fb_data->sg[0]) =
+ fb_data->info.fix.smem_start + fb_data->fb_offset
+ + pxp_input_offs;
+ sg_set_page(&fb_data->sg[0],
+ virt_to_page(fb_data->info.screen_base),
+ fb_data->info.fix.smem_len,
+ offset_in_page(fb_data->info.screen_base));
+ }
+
+ /* Update sg[1] to point to output of PxP proc task */
+ sg_dma_address(&fb_data->sg[1]) = upd_data_list->phys_addr
+ + pxp_output_shift;
+ sg_set_page(&fb_data->sg[1], virt_to_page(upd_data_list->virt_addr),
+ fb_data->max_pix_size,
+ offset_in_page(upd_data_list->virt_addr));
+
+ /*
+ * Set PxP LUT transform type based on update flags.
+ */
+ fb_data->pxp_conf.proc_data.lut_transform = 0;
+ if (upd_desc_list->upd_data.flags & EPDC_FLAG_ENABLE_INVERSION)
+ fb_data->pxp_conf.proc_data.lut_transform |= PXP_LUT_INVERT;
+ if (upd_desc_list->upd_data.flags & EPDC_FLAG_FORCE_MONOCHROME)
+ fb_data->pxp_conf.proc_data.lut_transform |=
+ PXP_LUT_BLACK_WHITE;
+ if (upd_desc_list->upd_data.flags & EPDC_FLAG_USE_CMAP)
+ fb_data->pxp_conf.proc_data.lut_transform |=
+ PXP_LUT_USE_CMAP;
+
+ /*
+ * Toggle inversion processing if 8-bit
+ * inverted is the current pixel format.
+ */
+ if (fb_data->epdc_fb_var.grayscale == GRAYSCALE_8BIT_INVERTED)
+ fb_data->pxp_conf.proc_data.lut_transform ^= PXP_LUT_INVERT;
+
+#ifdef USE_PS_AS_OUTPUT
+ /* This is a blocking call, so upon return PxP tx should be done */
+ ret = pxp_legacy_process(fb_data, src_width, src_height,
+ &pxp_upd_region);
+ if (ret) {
+ dev_err(fb_data->dev, "Unable to submit PxP update task.\n");
+ mutex_unlock(&fb_data->pxp_mutex);
+ return ret;
+ }
+
+ /* If needed, enable EPDC HW while ePxP is processing */
+ if ((fb_data->power_state == POWER_STATE_OFF)
+ || fb_data->powering_down) {
+ epdc_powerup(fb_data);
+ }
+
+ /* This is a blocking call, so upon return PxP tx should be done */
+ ret = pxp_complete_update(fb_data, &hist_stat);
+ if (ret) {
+ dev_err(fb_data->dev, "Unable to complete PxP update task: pre_prcoess.\n");
+ mutex_unlock(&fb_data->pxp_mutex);
+ return ret;
+ }
+#endif
+ pr_debug(" upd_data.dither_mode %d \n", upd_desc_list->upd_data.dither_mode);
+ fb_data->pxp_conf.proc_data.dither_mode = 0;
+
+ /* Dithering */
+ if ((EPDC_FLAG_USE_DITHERING_PASSTHROUGH < upd_desc_list->upd_data.dither_mode) &&
+ (upd_desc_list->upd_data.dither_mode < EPDC_FLAG_USE_DITHERING_MAX)) {
+
+ fb_data->pxp_conf.proc_data.dither_mode = upd_desc_list->upd_data.dither_mode;
+ fb_data->pxp_conf.proc_data.quant_bit = upd_desc_list->upd_data.quant_bit;
+
+ /* This is a blocking call, so upon return PxP tx should be done */
+ ret = pxp_process_dithering(fb_data, &pxp_upd_region);
+ if (ret) {
+ dev_err(fb_data->dev, "Unable to submit PxP update task.\n");
+ mutex_unlock(&fb_data->pxp_mutex);
+ return ret;
+ }
+
+ /* If needed, enable EPDC HW while ePxP is processing */
+ if ((fb_data->power_state == POWER_STATE_OFF)
+ || fb_data->powering_down) {
+ epdc_powerup(fb_data);
+ }
+
+ /* This is a blocking call, so upon return PxP tx should be done */
+ ret = pxp_complete_update(fb_data, &hist_stat);
+ if (ret) {
+ dev_err(fb_data->dev, "Unable to complete PxP update task: dithering process\n");
+ mutex_unlock(&fb_data->pxp_mutex);
+ return ret;
+ }
+
+ }
+
+ /* Regal D Processing */
+ fb_data->pxp_conf.proc_data.reagl_d_en =
+ (upd_desc_list->upd_data.waveform_mode == WAVEFORM_MODE_GLD16);
+
+ mutex_unlock(&fb_data->pxp_mutex);
+
+ /* Update waveform mode from PxP histogram results */
+ if ((fb_data->rev <= 20) &&
+ (upd_desc_list->upd_data.waveform_mode == WAVEFORM_MODE_AUTO)) {
+ if (hist_stat & 0x1)
+ upd_desc_list->upd_data.waveform_mode =
+ fb_data->wv_modes.mode_du;
+ else if (hist_stat & 0x2)
+ upd_desc_list->upd_data.waveform_mode =
+ fb_data->wv_modes.mode_gc4;
+ else if (hist_stat & 0x4)
+ upd_desc_list->upd_data.waveform_mode =
+ fb_data->wv_modes.mode_gc8;
+ else if (hist_stat & 0x8)
+ upd_desc_list->upd_data.waveform_mode =
+ fb_data->wv_modes.mode_gc16;
+ else
+ upd_desc_list->upd_data.waveform_mode =
+ fb_data->wv_modes.mode_gc32;
+
+ dev_dbg(fb_data->dev, "hist_stat = 0x%x, new waveform = 0x%x\n",
+ hist_stat, upd_desc_list->upd_data.waveform_mode);
+ }
+
+ return 0;
+}
+
+static int epdc_submit_merge(struct update_desc_list *upd_desc_list,
+ struct update_desc_list *update_to_merge,
+ struct mxc_epdc_fb_data *fb_data)
+{
+ struct mxcfb_update_data *a, *b;
+ struct mxcfb_rect *arect, *brect;
+ struct mxcfb_rect combine;
+ bool use_flags = false;
+
+ a = &upd_desc_list->upd_data;
+ b = &update_to_merge->upd_data;
+ arect = &upd_desc_list->upd_data.update_region;
+ brect = &update_to_merge->upd_data.update_region;
+
+ /* Do not merge a dry-run collision test update */
+ if ((a->flags & EPDC_FLAG_TEST_COLLISION) ||
+ (b->flags & EPDC_FLAG_TEST_COLLISION))
+ return MERGE_BLOCK;
+
+ /*
+ * Updates with different flags must be executed sequentially.
+ * Halt the merge process to ensure this.
+ */
+ if (a->flags != b->flags) {
+ /*
+ * Special exception: if update regions are identical,
+ * we may be able to merge them.
+ */
+ if ((arect->left != brect->left) ||
+ (arect->top != brect->top) ||
+ (arect->width != brect->width) ||
+ (arect->height != brect->height))
+ return MERGE_BLOCK;
+
+ use_flags = true;
+ }
+
+ if (a->update_mode != b->update_mode)
+ a->update_mode = UPDATE_MODE_FULL;
+
+ if (a->waveform_mode != b->waveform_mode)
+ a->waveform_mode = WAVEFORM_MODE_AUTO;
+
+ if (arect->left > (brect->left + brect->width) ||
+ brect->left > (arect->left + arect->width) ||
+ arect->top > (brect->top + brect->height) ||
+ brect->top > (arect->top + arect->height))
+ return MERGE_FAIL;
+
+ combine.left = arect->left < brect->left ? arect->left : brect->left;
+ combine.top = arect->top < brect->top ? arect->top : brect->top;
+ combine.width = (arect->left + arect->width) >
+ (brect->left + brect->width) ?
+ (arect->left + arect->width - combine.left) :
+ (brect->left + brect->width - combine.left);
+ combine.height = (arect->top + arect->height) >
+ (brect->top + brect->height) ?
+ (arect->top + arect->height - combine.top) :
+ (brect->top + brect->height - combine.top);
+
+ /* Don't merge if combined width exceeds max width */
+ if (fb_data->restrict_width) {
+ u32 max_width = EPDC_V2_MAX_UPDATE_WIDTH;
+ u32 combined_width = combine.width;
+ if (fb_data->epdc_fb_var.rotate != FB_ROTATE_UR)
+ max_width -= EPDC_V2_ROTATION_ALIGNMENT;
+ if ((fb_data->epdc_fb_var.rotate == FB_ROTATE_CW) ||
+ (fb_data->epdc_fb_var.rotate == FB_ROTATE_CCW))
+ combined_width = combine.height;
+ if (combined_width > max_width)
+ return MERGE_FAIL;
+ }
+
+ *arect = combine;
+
+ /* Use flags of the later update */
+ if (use_flags)
+ a->flags = b->flags;
+
+ /* Merge markers */
+ list_splice_tail(&update_to_merge->upd_marker_list,
+ &upd_desc_list->upd_marker_list);
+
+ /* Merged update should take on the earliest order */
+ upd_desc_list->update_order =
+ (upd_desc_list->update_order > update_to_merge->update_order) ?
+ upd_desc_list->update_order : update_to_merge->update_order;
+
+ return MERGE_OK;
+}
+
+static void epdc_submit_work_func(struct work_struct *work)
+{
+ int temp_index;
+ struct update_data_list *next_update, *temp_update;
+ struct update_desc_list *next_desc, *temp_desc;
+ struct update_marker_data *next_marker, *temp_marker;
+ struct mxc_epdc_fb_data *fb_data =
+ container_of(work, struct mxc_epdc_fb_data, epdc_submit_work);
+ struct pxp_config_data *pxp_conf = &fb_data->pxp_conf;
+ struct pxp_proc_data *proc_data = &pxp_conf->proc_data;
+ struct update_data_list *upd_data_list = NULL;
+ struct mxcfb_rect adj_update_region, *upd_region;
+ bool end_merge = false;
+ bool is_transform;
+ u32 update_addr;
+ int *err_dist;
+ int ret;
+
+ /* Protect access to buffer queues and to update HW */
+ mutex_lock(&fb_data->queue_mutex);
+
+ /*
+ * Are any of our collision updates able to go now?
+ * Go through all updates in the collision list and check to see
+ * if the collision mask has been fully cleared
+ */
+ list_for_each_entry_safe(next_update, temp_update,
+ &fb_data->upd_buf_collision_list, list) {
+
+ if (next_update->collision_mask != 0)
+ continue;
+
+ dev_dbg(fb_data->dev, "A collision update is ready to go!\n");
+
+ /* Force waveform mode to auto for resubmitted collisions */
+ next_update->update_desc->upd_data.waveform_mode =
+ WAVEFORM_MODE_AUTO;
+
+ /*
+ * We have a collision cleared, so select it for resubmission.
+ * If an update is already selected, attempt to merge.
+ */
+ if (!upd_data_list) {
+ upd_data_list = next_update;
+ list_del_init(&next_update->list);
+ if (fb_data->upd_scheme == UPDATE_SCHEME_QUEUE)
+ /* If not merging, we have our update */
+ break;
+ } else {
+ switch (epdc_submit_merge(upd_data_list->update_desc,
+ next_update->update_desc,
+ fb_data)) {
+ case MERGE_OK:
+ dev_dbg(fb_data->dev,
+ "Update merged [collision]\n");
+ list_del_init(&next_update->update_desc->list);
+ kfree(next_update->update_desc);
+ next_update->update_desc = NULL;
+ list_del_init(&next_update->list);
+ /* Add to free buffer list */
+ list_add_tail(&next_update->list,
+ &fb_data->upd_buf_free_list);
+ break;
+ case MERGE_FAIL:
+ dev_dbg(fb_data->dev,
+ "Update not merged [collision]\n");
+ break;
+ case MERGE_BLOCK:
+ dev_dbg(fb_data->dev,
+ "Merge blocked [collision]\n");
+ end_merge = true;
+ break;
+ }
+
+ if (end_merge) {
+ end_merge = false;
+ break;
+ }
+ }
+ }
+
+ /*
+ * Skip pending update list only if we found a collision
+ * update and we are not merging
+ */
+ if (!((fb_data->upd_scheme == UPDATE_SCHEME_QUEUE) &&
+ upd_data_list)) {
+ /*
+ * If we didn't find a collision update ready to go, we
+ * need to get a free buffer and match it to a pending update.
+ */
+
+ /*
+ * Can't proceed if there are no free buffers (and we don't
+ * already have a collision update selected)
+ */
+ if (!upd_data_list &&
+ list_empty(&fb_data->upd_buf_free_list)) {
+ mutex_unlock(&fb_data->queue_mutex);
+ return;
+ }
+
+ list_for_each_entry_safe(next_desc, temp_desc,
+ &fb_data->upd_pending_list, list) {
+
+ dev_dbg(fb_data->dev, "Found a pending update!\n");
+
+ if (!upd_data_list) {
+ if (list_empty(&fb_data->upd_buf_free_list))
+ break;
+ upd_data_list =
+ list_entry(fb_data->upd_buf_free_list.next,
+ struct update_data_list, list);
+ list_del_init(&upd_data_list->list);
+ upd_data_list->update_desc = next_desc;
+ list_del_init(&next_desc->list);
+ if (fb_data->upd_scheme == UPDATE_SCHEME_QUEUE)
+ /* If not merging, we have an update */
+ break;
+ } else {
+ switch (epdc_submit_merge(upd_data_list->update_desc,
+ next_desc, fb_data)) {
+ case MERGE_OK:
+ dev_dbg(fb_data->dev,
+ "Update merged [queue]\n");
+ list_del_init(&next_desc->list);
+ kfree(next_desc);
+ break;
+ case MERGE_FAIL:
+ dev_dbg(fb_data->dev,
+ "Update not merged [queue]\n");
+ break;
+ case MERGE_BLOCK:
+ dev_dbg(fb_data->dev,
+ "Merge blocked [collision]\n");
+ end_merge = true;
+ break;
+ }
+
+ if (end_merge)
+ break;
+ }
+ }
+ }
+
+ /* Is update list empty? */
+ if (!upd_data_list) {
+ mutex_unlock(&fb_data->queue_mutex);
+ return;
+ }
+
+ /*
+ * If no processing required, skip update processing
+ * No processing means:
+ * - FB unrotated
+ * - FB pixel format = 8-bit grayscale
+ * - No look-up transformations (inversion, posterization, etc.)
+ * - No scaling/flip
+ */
+ is_transform = ((upd_data_list->update_desc->upd_data.flags &
+ (EPDC_FLAG_ENABLE_INVERSION | EPDC_FLAG_USE_DITHERING_Y1 |
+ EPDC_FLAG_USE_DITHERING_Y4 | EPDC_FLAG_FORCE_MONOCHROME |
+ EPDC_FLAG_USE_CMAP)) && (proc_data->scaling == 0) &&
+ (proc_data->hflip == 0) && (proc_data->vflip == 0)) ?
+ true : false;
+
+ /*XXX if we use external mode, we should first use pxp
+ * to update upd buffer data to working buffer first.
+ */
+ if ((fb_data->epdc_fb_var.rotate == FB_ROTATE_UR) &&
+ (fb_data->epdc_fb_var.grayscale == GRAYSCALE_8BIT) &&
+ !is_transform && (proc_data->dither_mode == 0) &&
+ !fb_data->restrict_width) {
+
+ /* If needed, enable EPDC HW while ePxP is processing */
+ if ((fb_data->power_state == POWER_STATE_OFF)
+ || fb_data->powering_down)
+ epdc_powerup(fb_data);
+
+ /*
+ * Set update buffer pointer to the start of
+ * the update region in the frame buffer.
+ */
+ upd_region = &upd_data_list->update_desc->upd_data.update_region;
+ update_addr = fb_data->info.fix.smem_start +
+ ((upd_region->top * fb_data->info.var.xres_virtual) +
+ upd_region->left) * fb_data->info.var.bits_per_pixel/8;
+ upd_data_list->update_desc->epdc_stride =
+ fb_data->info.var.xres_virtual *
+ fb_data->info.var.bits_per_pixel/8;
+ } else {
+ /* Select from PxP output buffers */
+ upd_data_list->phys_addr =
+ fb_data->phys_addr_updbuf[fb_data->upd_buffer_num];
+ upd_data_list->virt_addr =
+ fb_data->virt_addr_updbuf[fb_data->upd_buffer_num];
+ fb_data->upd_buffer_num++;
+ if (fb_data->upd_buffer_num > fb_data->max_num_buffers-1)
+ fb_data->upd_buffer_num = 0;
+
+ /* Release buffer queues */
+ mutex_unlock(&fb_data->queue_mutex);
+
+ /* Perform PXP processing - EPDC power will also be enabled */
+ if (epdc_process_update(upd_data_list, fb_data)) {
+ dev_dbg(fb_data->dev, "PXP processing error.\n");
+ /* Protect access to buffer queues and to update HW */
+ mutex_lock(&fb_data->queue_mutex);
+ list_del_init(&upd_data_list->update_desc->list);
+ kfree(upd_data_list->update_desc);
+ upd_data_list->update_desc = NULL;
+ /* Add to free buffer list */
+ list_add_tail(&upd_data_list->list,
+ &fb_data->upd_buf_free_list);
+ /* Release buffer queues */
+ mutex_unlock(&fb_data->queue_mutex);
+ return;
+ }
+
+ /* Protect access to buffer queues and to update HW */
+ mutex_lock(&fb_data->queue_mutex);
+
+ update_addr = upd_data_list->phys_addr
+ + upd_data_list->update_desc->epdc_offs;
+ }
+
+ /* Get rotation-adjusted coordinates */
+ adjust_coordinates(fb_data->epdc_fb_var.xres,
+ fb_data->epdc_fb_var.yres, fb_data->epdc_fb_var.rotate,
+ &upd_data_list->update_desc->upd_data.update_region,
+ &adj_update_region);
+
+ /*
+ * Is the working buffer idle?
+ * If the working buffer is busy, we must wait for the resource
+ * to become free. The IST will signal this event.
+ */
+ if (fb_data->cur_update != NULL) {
+ dev_dbg(fb_data->dev, "working buf busy!\n");
+
+ /* Initialize event signalling an update resource is free */
+ init_completion(&fb_data->update_res_free);
+
+ fb_data->waiting_for_wb = true;
+
+ /* Leave spinlock while waiting for WB to complete */
+ mutex_unlock(&fb_data->queue_mutex);
+ wait_for_completion(&fb_data->update_res_free);
+ mutex_lock(&fb_data->queue_mutex);
+ }
+
+ /*
+ * Dithering Processing (Version 1.0 - for i.MX508 and i.MX6SL)
+ */
+ if (upd_data_list->update_desc->upd_data.flags &
+ EPDC_FLAG_USE_DITHERING_Y1) {
+
+ err_dist = kzalloc((fb_data->info.var.xres_virtual + 3) * 3
+ * sizeof(int), GFP_KERNEL);
+
+ /* Dithering Y8 -> Y1 */
+ do_dithering_processing_Y1_v1_0(
+ (uint8_t *)(upd_data_list->virt_addr +
+ upd_data_list->update_desc->epdc_offs),
+ upd_data_list->phys_addr +
+ upd_data_list->update_desc->epdc_offs,
+ &adj_update_region,
+ (fb_data->rev < 20) ?
+ ALIGN(adj_update_region.width, 8) :
+ adj_update_region.width,
+ err_dist);
+
+ kfree(err_dist);
+ } else if (upd_data_list->update_desc->upd_data.flags &
+ EPDC_FLAG_USE_DITHERING_Y4) {
+
+ err_dist = kzalloc((fb_data->info.var.xres_virtual + 3) * 3
+ * sizeof(int), GFP_KERNEL);
+
+ /* Dithering Y8 -> Y1 */
+ do_dithering_processing_Y4_v1_0(
+ (uint8_t *)(upd_data_list->virt_addr +
+ upd_data_list->update_desc->epdc_offs),
+ upd_data_list->phys_addr +
+ upd_data_list->update_desc->epdc_offs,
+ &adj_update_region,
+ (fb_data->rev < 20) ?
+ ALIGN(adj_update_region.width, 8) :
+ adj_update_region.width,
+ err_dist);
+
+ kfree(err_dist);
+ }
+
+ /*
+ * If there are no LUTs available,
+ * then we must wait for the resource to become free.
+ * The IST will signal this event.
+ */
+ {
+ bool luts_available;
+
+ luts_available = fb_data->epdc_wb_mode ? epdc_any_luts_real_available() :
+ epdc_any_luts_available();
+ if (!luts_available) {
+ dev_dbg(fb_data->dev, "no luts available!\n");
+
+ /* Initialize event signalling an update resource is free */
+ init_completion(&fb_data->update_res_free);
+
+ fb_data->waiting_for_lut = true;
+
+ /* Leave spinlock while waiting for LUT to free up */
+ mutex_unlock(&fb_data->queue_mutex);
+ wait_for_completion(&fb_data->update_res_free);
+ mutex_lock(&fb_data->queue_mutex);
+ }
+ }
+
+ ret = epdc_choose_next_lut(fb_data, &upd_data_list->lut_num);
+ /*
+ * If LUT15 is in use (for pre-EPDC v2.0 hardware):
+ * - Wait for LUT15 to complete is if TCE underrun prevent is enabled
+ * - If we go ahead with update, sync update submission with EOF
+ */
+ if (ret && fb_data->tce_prevent && (fb_data->rev < 20)) {
+ dev_dbg(fb_data->dev, "Waiting for LUT15\n");
+
+ /* Initialize event signalling that lut15 is free */
+ init_completion(&fb_data->lut15_free);
+
+ fb_data->waiting_for_lut15 = true;
+
+ /* Leave spinlock while waiting for LUT to free up */
+ mutex_unlock(&fb_data->queue_mutex);
+ wait_for_completion(&fb_data->lut15_free);
+ mutex_lock(&fb_data->queue_mutex);
+
+ epdc_choose_next_lut(fb_data, &upd_data_list->lut_num);
+ } else if (ret && (fb_data->rev < 20)) {
+ /* Synchronize update submission time to reduce
+ chances of TCE underrun */
+ init_completion(&fb_data->eof_event);
+
+ epdc_eof_intr(true);
+
+ /* Leave spinlock while waiting for EOF event */
+ mutex_unlock(&fb_data->queue_mutex);
+ ret = wait_for_completion_timeout(&fb_data->eof_event,
+ msecs_to_jiffies(1000));
+ if (!ret) {
+ dev_err(fb_data->dev, "Missed EOF event!\n");
+ epdc_eof_intr(false);
+ }
+ udelay(fb_data->eof_sync_period);
+ mutex_lock(&fb_data->queue_mutex);
+
+ }
+
+ /* LUTs are available, so we get one here */
+ fb_data->cur_update = upd_data_list;
+
+ /* Reset mask for LUTS that have completed during WB processing */
+ fb_data->luts_complete_wb = 0;
+
+ /* If we are just testing for collision, we don't assign a LUT,
+ * so we don't need to update LUT-related resources. */
+ if (!(upd_data_list->update_desc->upd_data.flags
+ & EPDC_FLAG_TEST_COLLISION)) {
+ /* Associate LUT with update marker */
+ list_for_each_entry_safe(next_marker, temp_marker,
+ &upd_data_list->update_desc->upd_marker_list, upd_list)
+ next_marker->lut_num = fb_data->cur_update->lut_num;
+
+ /* Mark LUT with order */
+ fb_data->lut_update_order[upd_data_list->lut_num] =
+ upd_data_list->update_desc->update_order;
+
+ epdc_lut_complete_intr(fb_data->rev, upd_data_list->lut_num,
+ true);
+ }
+
+ /* Enable Collision and WB complete IRQs */
+ epdc_working_buf_intr(true);
+
+ /* add working buffer update here for external mode */
+ if (fb_data->epdc_wb_mode)
+ ret = epdc_working_buffer_update(fb_data, upd_data_list,
+ &adj_update_region);
+
+ /* Program EPDC update to process buffer */
+ if (upd_data_list->update_desc->upd_data.temp != TEMP_USE_AMBIENT) {
+ temp_index = mxc_epdc_fb_get_temp_index(fb_data,
+ upd_data_list->update_desc->upd_data.temp);
+ epdc_set_temp(temp_index);
+ } else
+ epdc_set_temp(fb_data->temp_index);
+
+ epdc_set_update_addr(update_addr);
+ epdc_set_update_coord(adj_update_region.left, adj_update_region.top);
+ epdc_set_update_dimensions(adj_update_region.width,
+ adj_update_region.height);
+ if (fb_data->rev > 20)
+ epdc_set_update_stride(upd_data_list->update_desc->epdc_stride);
+ if (fb_data->wv_modes_update &&
+ (upd_data_list->update_desc->upd_data.waveform_mode
+ == WAVEFORM_MODE_AUTO)) {
+ epdc_set_update_waveform(&fb_data->wv_modes);
+ fb_data->wv_modes_update = false;
+ }
+
+ epdc_submit_update(upd_data_list->lut_num,
+ upd_data_list->update_desc->upd_data.waveform_mode,
+ upd_data_list->update_desc->upd_data.update_mode,
+ (upd_data_list->update_desc->upd_data.flags
+ & EPDC_FLAG_TEST_COLLISION) ? true : false,
+ false, 0);
+
+ /* Release buffer queues */
+ mutex_unlock(&fb_data->queue_mutex);
+}
+
+static int mxc_epdc_fb_send_single_update(struct mxcfb_update_data *upd_data,
+ struct fb_info *info)
+{
+ struct mxc_epdc_fb_data *fb_data = info ?
+ (struct mxc_epdc_fb_data *)info:g_fb_data;
+ struct update_data_list *upd_data_list = NULL;
+ struct mxcfb_rect *screen_upd_region; /* Region on screen to update */
+ int temp_index;
+ int ret;
+ struct update_desc_list *upd_desc;
+ struct update_marker_data *marker_data, *next_marker, *temp_marker;
+
+ /* Has EPDC HW been initialized? */
+ if (!fb_data->hw_ready) {
+ /* Throw message if we are not mid-initialization */
+ if (!fb_data->hw_initializing)
+ dev_err(fb_data->dev, "Display HW not properly"
+ "initialized. Aborting update.\n");
+ return -EPERM;
+ }
+
+ /* Check validity of update params */
+ if ((upd_data->update_mode != UPDATE_MODE_PARTIAL) &&
+ (upd_data->update_mode != UPDATE_MODE_FULL)) {
+ dev_err(fb_data->dev,
+ "Update mode 0x%x is invalid. Aborting update.\n",
+ upd_data->update_mode);
+ return -EINVAL;
+ }
+ if ((upd_data->waveform_mode > 255) &&
+ (upd_data->waveform_mode != WAVEFORM_MODE_AUTO)) {
+ dev_err(fb_data->dev,
+ "Update waveform mode 0x%x is invalid."
+ " Aborting update.\n",
+ upd_data->waveform_mode);
+ return -EINVAL;
+ }
+ if ((upd_data->update_region.left >= fb_data->epdc_fb_var.xres) ||
+ (upd_data->update_region.top >= fb_data->epdc_fb_var.yres) ||
+ (upd_data->update_region.width > fb_data->epdc_fb_var.xres) ||
+ (upd_data->update_region.height > fb_data->epdc_fb_var.yres) ||
+ (upd_data->update_region.left + upd_data->update_region.width > fb_data->epdc_fb_var.xres) ||
+ (upd_data->update_region.top + upd_data->update_region.height > fb_data->epdc_fb_var.yres)) {
+ dev_err(fb_data->dev,
+ "Update region is outside bounds of framebuffer."
+ "Aborting update.\n");
+ return -EINVAL;
+ }
+ if (upd_data->flags & EPDC_FLAG_USE_ALT_BUFFER) {
+ if ((upd_data->update_region.width !=
+ upd_data->alt_buffer_data.alt_update_region.width) ||
+ (upd_data->update_region.height !=
+ upd_data->alt_buffer_data.alt_update_region.height)) {
+ dev_err(fb_data->dev,
+ "Alternate update region dimensions must "
+ "match screen update region dimensions.\n");
+ return -EINVAL;
+ }
+ /* Validate physical address parameter */
+ if ((upd_data->alt_buffer_data.phys_addr <
+ fb_data->info.fix.smem_start) ||
+ (upd_data->alt_buffer_data.phys_addr >
+ fb_data->info.fix.smem_start + fb_data->map_size)) {
+ dev_err(fb_data->dev,
+ "Invalid physical address for alternate "
+ "buffer. Aborting update...\n");
+ return -EINVAL;
+ }
+ }
+
+ mutex_lock(&fb_data->queue_mutex);
+
+ /*
+ * If we are waiting to go into suspend, or the FB is blanked,
+ * we do not accept new updates
+ */
+ if ((fb_data->waiting_for_idle) ||
+ (fb_data->blank != FB_BLANK_UNBLANK)) {
+ dev_dbg(fb_data->dev, "EPDC not active."
+ "Update request abort.\n");
+ mutex_unlock(&fb_data->queue_mutex);
+ return -EPERM;
+ }
+
+ if (fb_data->upd_scheme == UPDATE_SCHEME_SNAPSHOT) {
+ int count = 0;
+ struct update_data_list *plist;
+
+ /*
+ * If next update is a FULL mode update, then we must
+ * ensure that all pending & active updates are complete
+ * before submitting the update. Otherwise, the FULL
+ * mode update may cause an endless collision loop with
+ * other updates. Block here until updates are flushed.
+ */
+ if (upd_data->update_mode == UPDATE_MODE_FULL) {
+ mutex_unlock(&fb_data->queue_mutex);
+ mxc_epdc_fb_flush_updates(fb_data);
+ mutex_lock(&fb_data->queue_mutex);
+ }
+
+ /* Count buffers in free buffer list */
+ list_for_each_entry(plist, &fb_data->upd_buf_free_list, list)
+ count++;
+
+ /* Use count to determine if we have enough
+ * free buffers to handle this update request */
+ if (count + fb_data->max_num_buffers
+ <= fb_data->max_num_updates) {
+ dev_err(fb_data->dev,
+ "No free intermediate buffers available.\n");
+ mutex_unlock(&fb_data->queue_mutex);
+ return -ENOMEM;
+ }
+
+ /* Grab first available buffer and delete from the free list */
+ upd_data_list =
+ list_entry(fb_data->upd_buf_free_list.next,
+ struct update_data_list, list);
+
+ list_del_init(&upd_data_list->list);
+ }
+
+ /*
+ * Create new update data structure, fill it with new update
+ * data and add it to the list of pending updates
+ */
+ upd_desc = kzalloc(sizeof(struct update_desc_list), GFP_KERNEL);
+ if (!upd_desc) {
+ dev_err(fb_data->dev,
+ "Insufficient system memory for update! Aborting.\n");
+ if (fb_data->upd_scheme == UPDATE_SCHEME_SNAPSHOT) {
+ list_add(&upd_data_list->list,
+ &fb_data->upd_buf_free_list);
+ }
+ mutex_unlock(&fb_data->queue_mutex);
+ return -EPERM;
+ }
+ /* Initialize per-update marker list */
+ INIT_LIST_HEAD(&upd_desc->upd_marker_list);
+ upd_desc->upd_data = *upd_data;
+ upd_desc->update_order = fb_data->order_cnt++;
+ list_add_tail(&upd_desc->list, &fb_data->upd_pending_list);
+
+ /* If marker specified, associate it with a completion */
+ if (upd_data->update_marker != 0) {
+ /* Allocate new update marker and set it up */
+ marker_data = kzalloc(sizeof(struct update_marker_data),
+ GFP_KERNEL);
+ if (!marker_data) {
+ dev_err(fb_data->dev, "No memory for marker!\n");
+ mutex_unlock(&fb_data->queue_mutex);
+ return -ENOMEM;
+ }
+ list_add_tail(&marker_data->upd_list,
+ &upd_desc->upd_marker_list);
+ marker_data->update_marker = upd_data->update_marker;
+ if (upd_desc->upd_data.flags & EPDC_FLAG_TEST_COLLISION)
+ marker_data->lut_num = DRY_RUN_NO_LUT;
+ else
+ marker_data->lut_num = INVALID_LUT;
+ init_completion(&marker_data->update_completion);
+ /* Add marker to master marker list */
+ list_add_tail(&marker_data->full_list,
+ &fb_data->full_marker_list);
+ }
+
+ if (fb_data->upd_scheme != UPDATE_SCHEME_SNAPSHOT) {
+ /* Queued update scheme processing */
+
+ mutex_unlock(&fb_data->queue_mutex);
+
+ /* Signal workqueue to handle new update */
+ queue_work(fb_data->epdc_submit_workqueue,
+ &fb_data->epdc_submit_work);
+
+ return 0;
+ }
+
+ /* Snapshot update scheme processing */
+
+ /* Set descriptor for current update, delete from pending list */
+ upd_data_list->update_desc = upd_desc;
+ list_del_init(&upd_desc->list);
+
+ mutex_unlock(&fb_data->queue_mutex);
+
+ /*
+ * Hold on to original screen update region, which we
+ * will ultimately use when telling EPDC where to update on panel
+ */
+ screen_upd_region = &upd_desc->upd_data.update_region;
+
+ /* Select from PxP output buffers */
+ upd_data_list->phys_addr =
+ fb_data->phys_addr_updbuf[fb_data->upd_buffer_num];
+ upd_data_list->virt_addr =
+ fb_data->virt_addr_updbuf[fb_data->upd_buffer_num];
+ fb_data->upd_buffer_num++;
+ if (fb_data->upd_buffer_num > fb_data->max_num_buffers-1)
+ fb_data->upd_buffer_num = 0;
+
+ ret = epdc_process_update(upd_data_list, fb_data);
+ if (ret) {
+ mutex_unlock(&fb_data->pxp_mutex);
+ return ret;
+ }
+
+ /* Pass selected waveform mode back to user */
+ upd_data->waveform_mode = upd_desc->upd_data.waveform_mode;
+
+ /* Get rotation-adjusted coordinates */
+ adjust_coordinates(fb_data->epdc_fb_var.xres,
+ fb_data->epdc_fb_var.yres, fb_data->epdc_fb_var.rotate,
+ &upd_desc->upd_data.update_region, NULL);
+
+ /* Grab lock for queue manipulation and update submission */
+ mutex_lock(&fb_data->queue_mutex);
+
+ /*
+ * Is the working buffer idle?
+ * If either the working buffer is busy, or there are no LUTs available,
+ * then we return and let the ISR handle the update later
+ */
+ {
+ bool luts_available;
+
+ luts_available = fb_data->epdc_wb_mode ? epdc_any_luts_real_available() :
+ epdc_any_luts_available();
+ if ((fb_data->cur_update != NULL) || !luts_available) {
+ /* Add processed Y buffer to update list */
+ list_add_tail(&upd_data_list->list, &fb_data->upd_buf_queue);
+
+ /* Return and allow the update to be submitted by the ISR. */
+ mutex_unlock(&fb_data->queue_mutex);
+ return 0;
+ }
+ }
+
+ /* LUTs are available, so we get one here */
+ ret = epdc_choose_next_lut(fb_data, &upd_data_list->lut_num);
+ if (ret && fb_data->tce_prevent && (fb_data->rev < 20)) {
+ dev_dbg(fb_data->dev, "Must wait for LUT15\n");
+ /* Add processed Y buffer to update list */
+ list_add_tail(&upd_data_list->list, &fb_data->upd_buf_queue);
+
+ /* Return and allow the update to be submitted by the ISR. */
+ mutex_unlock(&fb_data->queue_mutex);
+ return 0;
+ }
+
+ if (!(upd_data_list->update_desc->upd_data.flags
+ & EPDC_FLAG_TEST_COLLISION)) {
+
+ /* Save current update */
+ fb_data->cur_update = upd_data_list;
+
+ /* Reset mask for LUTS that have completed during WB processing */
+ fb_data->luts_complete_wb = 0;
+
+ /* Associate LUT with update marker */
+ list_for_each_entry_safe(next_marker, temp_marker,
+ &upd_data_list->update_desc->upd_marker_list, upd_list)
+ next_marker->lut_num = upd_data_list->lut_num;
+
+ /* Mark LUT as containing new update */
+ fb_data->lut_update_order[upd_data_list->lut_num] =
+ upd_desc->update_order;
+
+ epdc_lut_complete_intr(fb_data->rev, upd_data_list->lut_num,
+ true);
+ }
+
+ /* Clear status and Enable LUT complete and WB complete IRQs */
+ epdc_working_buf_intr(true);
+
+ /* add working buffer update before display for external mode */
+ if (fb_data->epdc_wb_mode)
+ ret = epdc_working_buffer_update(fb_data, upd_data_list,
+ screen_upd_region);
+
+ /* Program EPDC update to process buffer */
+ epdc_set_update_addr(upd_data_list->phys_addr + upd_desc->epdc_offs);
+ epdc_set_update_coord(screen_upd_region->left, screen_upd_region->top);
+ epdc_set_update_dimensions(screen_upd_region->width,
+ screen_upd_region->height);
+ if (fb_data->rev > 20)
+ epdc_set_update_stride(upd_desc->epdc_stride);
+ if (upd_desc->upd_data.temp != TEMP_USE_AMBIENT) {
+ temp_index = mxc_epdc_fb_get_temp_index(fb_data,
+ upd_desc->upd_data.temp);
+ epdc_set_temp(temp_index);
+ } else
+ epdc_set_temp(fb_data->temp_index);
+ if (fb_data->wv_modes_update &&
+ (upd_desc->upd_data.waveform_mode == WAVEFORM_MODE_AUTO)) {
+ epdc_set_update_waveform(&fb_data->wv_modes);
+ fb_data->wv_modes_update = false;
+ }
+
+ epdc_submit_update(upd_data_list->lut_num,
+ upd_desc->upd_data.waveform_mode,
+ upd_desc->upd_data.update_mode,
+ (upd_desc->upd_data.flags
+ & EPDC_FLAG_TEST_COLLISION) ? true : false,
+ false, 0);
+
+ mutex_unlock(&fb_data->queue_mutex);
+ return 0;
+}
+
+static int mxc_epdc_fb_send_update(struct mxcfb_update_data *upd_data,
+ struct fb_info *info)
+{
+ struct mxc_epdc_fb_data *fb_data = info ?
+ (struct mxc_epdc_fb_data *)info:g_fb_data;
+
+ if (!fb_data->restrict_width) {
+ /* No width restriction, send entire update region */
+ return mxc_epdc_fb_send_single_update(upd_data, info);
+ } else {
+ int ret;
+ __u32 width, left;
+ __u32 marker;
+ __u32 *region_width, *region_left;
+ u32 max_upd_width = EPDC_V2_MAX_UPDATE_WIDTH;
+
+ /* Further restrict max width due to pxp rotation
+ * alignment requirement
+ */
+ if (fb_data->epdc_fb_var.rotate != FB_ROTATE_UR)
+ max_upd_width -= EPDC_V2_ROTATION_ALIGNMENT;
+
+ /* Select split of width or height based on rotation */
+ if ((fb_data->epdc_fb_var.rotate == FB_ROTATE_UR) ||
+ (fb_data->epdc_fb_var.rotate == FB_ROTATE_UD)) {
+ region_width = &upd_data->update_region.width;
+ region_left = &upd_data->update_region.left;
+ } else {
+ region_width = &upd_data->update_region.height;
+ region_left = &upd_data->update_region.top;
+ }
+
+ if (*region_width <= max_upd_width)
+ return mxc_epdc_fb_send_single_update(upd_data, info);
+
+ width = *region_width;
+ left = *region_left;
+ marker = upd_data->update_marker;
+ upd_data->update_marker = 0;
+
+ do {
+ *region_width = max_upd_width;
+ *region_left = left;
+ ret = mxc_epdc_fb_send_single_update(upd_data, info);
+ if (ret)
+ return ret;
+ width -= max_upd_width;
+ left += max_upd_width;
+ } while (width > max_upd_width);
+
+ *region_width = width;
+ *region_left = left;
+ upd_data->update_marker = marker;
+ return mxc_epdc_fb_send_single_update(upd_data, info);
+ }
+}
+
+static int mxc_epdc_fb_wait_update_complete(struct mxcfb_update_marker_data *marker_data,
+ struct fb_info *info)
+{
+ struct mxc_epdc_fb_data *fb_data = info ?
+ (struct mxc_epdc_fb_data *)info:g_fb_data;
+ struct update_marker_data *next_marker;
+ struct update_marker_data *temp;
+ bool marker_found = false;
+ int ret = 0;
+
+ /* 0 is an invalid update_marker value */
+ if (marker_data->update_marker == 0)
+ return -EINVAL;
+
+ /*
+ * Find completion associated with update_marker requested.
+ * Note: If update completed already, marker will have been
+ * cleared, it won't be found, and function will just return.
+ */
+
+ /* Grab queue lock to protect access to marker list */
+ mutex_lock(&fb_data->queue_mutex);
+
+ list_for_each_entry_safe(next_marker, temp,
+ &fb_data->full_marker_list, full_list) {
+ if (next_marker->update_marker == marker_data->update_marker) {
+ dev_dbg(fb_data->dev, "Waiting for marker %d\n",
+ marker_data->update_marker);
+ next_marker->waiting = true;
+ marker_found = true;
+ break;
+ }
+ }
+
+ mutex_unlock(&fb_data->queue_mutex);
+
+ /*
+ * If marker not found, it has either been signalled already
+ * or the update request failed. In either case, just return.
+ */
+ if (!marker_found)
+ return ret;
+
+ ret = wait_for_completion_timeout(&next_marker->update_completion,
+ msecs_to_jiffies(5000));
+ if (!ret) {
+ dev_err(fb_data->dev,
+ "Timed out waiting for update completion\n");
+ return -ETIMEDOUT;
+ }
+
+ marker_data->collision_test = next_marker->collision_test;
+
+ /* Free update marker object */
+ kfree(next_marker);
+
+ return ret;
+}
+
+static int mxc_epdc_fb_set_pwrdown_delay(u32 pwrdown_delay,
+ struct fb_info *info)
+{
+ struct mxc_epdc_fb_data *fb_data = info ?
+ (struct mxc_epdc_fb_data *)info:g_fb_data;
+
+ fb_data->pwrdown_delay = pwrdown_delay;
+
+ return 0;
+}
+
+static int mxc_epdc_get_pwrdown_delay(struct fb_info *info)
+{
+ struct mxc_epdc_fb_data *fb_data = info ?
+ (struct mxc_epdc_fb_data *)info:g_fb_data;
+
+ return fb_data->pwrdown_delay;
+}
+
+static int mxc_epdc_fb_ioctl(struct fb_info *info, unsigned int cmd,
+ unsigned long arg)
+{
+ void __user *argp = (void __user *)arg;
+ int ret = -EINVAL;
+
+ switch (cmd) {
+ case MXCFB_SET_WAVEFORM_MODES:
+ {
+ struct mxcfb_waveform_modes modes;
+ if (!copy_from_user(&modes, argp, sizeof(modes))) {
+ mxc_epdc_fb_set_waveform_modes(&modes, info);
+ ret = 0;
+ }
+ break;
+ }
+ case MXCFB_SET_TEMPERATURE:
+ {
+ int temperature;
+ if (!get_user(temperature, (int32_t __user *) arg))
+ ret = mxc_epdc_fb_set_temperature(temperature,
+ info);
+ break;
+ }
+ case MXCFB_SET_AUTO_UPDATE_MODE:
+ {
+ u32 auto_mode = 0;
+ if (!get_user(auto_mode, (__u32 __user *) arg))
+ ret = mxc_epdc_fb_set_auto_update(auto_mode,
+ info);
+ break;
+ }
+ case MXCFB_SET_UPDATE_SCHEME:
+ {
+ u32 upd_scheme = 0;
+ if (!get_user(upd_scheme, (__u32 __user *) arg))
+ ret = mxc_epdc_fb_set_upd_scheme(upd_scheme,
+ info);
+ break;
+ }
+ case MXCFB_SEND_UPDATE:
+ {
+ struct mxcfb_update_data upd_data;
+ if (!copy_from_user(&upd_data, argp,
+ sizeof(upd_data))) {
+ ret = mxc_epdc_fb_send_update(&upd_data, info);
+ if (ret == 0 && copy_to_user(argp, &upd_data,
+ sizeof(upd_data)))
+ ret = -EFAULT;
+ } else {
+ ret = -EFAULT;
+ }
+
+ break;
+ }
+ case MXCFB_WAIT_FOR_UPDATE_COMPLETE:
+ {
+ struct mxcfb_update_marker_data upd_marker_data;
+ if (!copy_from_user(&upd_marker_data, argp,
+ sizeof(upd_marker_data))) {
+ ret = mxc_epdc_fb_wait_update_complete(
+ &upd_marker_data, info);
+ if (copy_to_user(argp, &upd_marker_data,
+ sizeof(upd_marker_data)))
+ ret = -EFAULT;
+ } else {
+ ret = -EFAULT;
+ }
+
+ break;
+ }
+
+ case MXCFB_SET_PWRDOWN_DELAY:
+ {
+ int delay = 0;
+ if (!get_user(delay, (__u32 __user *) arg))
+ ret =
+ mxc_epdc_fb_set_pwrdown_delay(delay, info);
+ break;
+ }
+
+ case MXCFB_GET_PWRDOWN_DELAY:
+ {
+ int pwrdown_delay = mxc_epdc_get_pwrdown_delay(info);
+ if (put_user(pwrdown_delay,
+ (int __user *)argp))
+ ret = -EFAULT;
+ ret = 0;
+ break;
+ }
+
+ case MXCFB_GET_WORK_BUFFER:
+ {
+ /* copy the epdc working buffer to the user space */
+ struct mxc_epdc_fb_data *fb_data = info ?
+ (struct mxc_epdc_fb_data *)info:g_fb_data;
+ flush_cache_all();
+ outer_flush_range(fb_data->working_buffer_phys,
+ fb_data->working_buffer_phys +
+ fb_data->working_buffer_size);
+ if (copy_to_user((void __user *)arg,
+ (const void *) fb_data->working_buffer_virt,
+ fb_data->working_buffer_size))
+ ret = -EFAULT;
+ else
+ ret = 0;
+ flush_cache_all();
+ outer_flush_range(fb_data->working_buffer_phys,
+ fb_data->working_buffer_phys +
+ fb_data->working_buffer_size);
+ break;
+ }
+
+ default:
+ break;
+ }
+ return ret;
+}
+
+static void mxc_epdc_fb_update_pages(struct mxc_epdc_fb_data *fb_data,
+ u16 y1, u16 y2)
+{
+ struct mxcfb_update_data update;
+
+ /* Do partial screen update, Update full horizontal lines */
+ update.update_region.left = 0;
+ update.update_region.width = fb_data->epdc_fb_var.xres;
+ update.update_region.top = y1;
+ update.update_region.height = y2 - y1;
+ update.waveform_mode = WAVEFORM_MODE_AUTO;
+ update.update_mode = UPDATE_MODE_FULL;
+ update.update_marker = 0;
+ update.temp = TEMP_USE_AMBIENT;
+ update.flags = 0;
+
+ mxc_epdc_fb_send_update(&update, &fb_data->info);
+}
+
+/* this is called back from the deferred io workqueue */
+static void mxc_epdc_fb_deferred_io(struct fb_info *info,
+ struct list_head *pagelist)
+{
+ struct mxc_epdc_fb_data *fb_data = (struct mxc_epdc_fb_data *)info;
+ struct page *page;
+ unsigned long beg, end;
+ int y1, y2, miny, maxy;
+
+ if (fb_data->auto_mode != AUTO_UPDATE_MODE_AUTOMATIC_MODE)
+ return;
+
+ miny = INT_MAX;
+ maxy = 0;
+ list_for_each_entry(page, pagelist, lru) {
+ beg = page->index << PAGE_SHIFT;
+ end = beg + PAGE_SIZE - 1;
+ y1 = beg / info->fix.line_length;
+ y2 = end / info->fix.line_length;
+ if (y2 >= fb_data->epdc_fb_var.yres)
+ y2 = fb_data->epdc_fb_var.yres - 1;
+ if (miny > y1)
+ miny = y1;
+ if (maxy < y2)
+ maxy = y2;
+ }
+
+ mxc_epdc_fb_update_pages(fb_data, miny, maxy);
+}
+
+void mxc_epdc_fb_flush_updates(struct mxc_epdc_fb_data *fb_data)
+{
+ int ret;
+
+ if (fb_data->in_init)
+ return;
+
+ /* Grab queue lock to prevent any new updates from being submitted */
+ mutex_lock(&fb_data->queue_mutex);
+
+ /*
+ * 3 places to check for updates that are active or pending:
+ * 1) Updates in the pending list
+ * 2) Update buffers in use (e.g., PxP processing)
+ * 3) Active updates to panel - We can key off of EPDC
+ * power state to know if we have active updates.
+ */
+ if (!list_empty(&fb_data->upd_pending_list) ||
+ !is_free_list_full(fb_data) ||
+ (fb_data->updates_active == true)) {
+ /* Initialize event signalling updates are done */
+ init_completion(&fb_data->updates_done);
+ fb_data->waiting_for_idle = true;
+
+ mutex_unlock(&fb_data->queue_mutex);
+ /* Wait for any currently active updates to complete */
+ ret = wait_for_completion_timeout(&fb_data->updates_done,
+ msecs_to_jiffies(8000));
+ if (!ret)
+ dev_err(fb_data->dev,
+ "Flush updates timeout! ret = 0x%x\n", ret);
+
+ mutex_lock(&fb_data->queue_mutex);
+ fb_data->waiting_for_idle = false;
+ }
+
+ mutex_unlock(&fb_data->queue_mutex);
+}
+
+static int mxc_epdc_fb_blank(int blank, struct fb_info *info)
+{
+ struct mxc_epdc_fb_data *fb_data = (struct mxc_epdc_fb_data *)info;
+ int ret;
+
+ dev_dbg(fb_data->dev, "blank = %d\n", blank);
+
+ if (fb_data->blank == blank)
+ return 0;
+
+ fb_data->blank = blank;
+
+ switch (blank) {
+ case FB_BLANK_POWERDOWN:
+ mxc_epdc_fb_flush_updates(fb_data);
+ /* Wait for powerdown */
+ mutex_lock(&fb_data->power_mutex);
+ if ((fb_data->power_state == POWER_STATE_ON) &&
+ (fb_data->pwrdown_delay == FB_POWERDOWN_DISABLE)) {
+
+ /* Powerdown disabled, so we disable EPDC manually */
+ int count = 0;
+ int sleep_ms = 10;
+
+ mutex_unlock(&fb_data->power_mutex);
+
+ /* If any active updates, wait for them to complete */
+ while (fb_data->updates_active) {
+ /* Timeout after 1 sec */
+ if ((count * sleep_ms) > 1000)
+ break;
+ msleep(sleep_ms);
+ count++;
+ }
+
+ fb_data->powering_down = true;
+ epdc_powerdown(fb_data);
+ } else if (fb_data->power_state != POWER_STATE_OFF) {
+ fb_data->wait_for_powerdown = true;
+ init_completion(&fb_data->powerdown_compl);
+ mutex_unlock(&fb_data->power_mutex);
+ ret = wait_for_completion_timeout(&fb_data->powerdown_compl,
+ msecs_to_jiffies(5000));
+ if (!ret) {
+ dev_err(fb_data->dev,
+ "No powerdown received!\n");
+ return -ETIMEDOUT;
+ }
+ } else
+ mutex_unlock(&fb_data->power_mutex);
+ break;
+ case FB_BLANK_VSYNC_SUSPEND:
+ case FB_BLANK_HSYNC_SUSPEND:
+ case FB_BLANK_NORMAL:
+ mxc_epdc_fb_flush_updates(fb_data);
+ break;
+ }
+ return 0;
+}
+
+static int mxc_epdc_fb_pan_display(struct fb_var_screeninfo *var,
+ struct fb_info *info)
+{
+ struct mxc_epdc_fb_data *fb_data = (struct mxc_epdc_fb_data *)info;
+ u_int y_bottom;
+
+ dev_dbg(info->device, "%s: var->yoffset %d, info->var.yoffset %d\n",
+ __func__, var->yoffset, info->var.yoffset);
+ /* check if var is valid; also, xpan is not supported */
+ if (!var || (var->xoffset != info->var.xoffset) ||
+ (var->yoffset + var->yres > var->yres_virtual)) {
+ dev_dbg(info->device, "x panning not supported\n");
+ return -EINVAL;
+ }
+
+ if ((fb_data->epdc_fb_var.xoffset == var->xoffset) &&
+ (fb_data->epdc_fb_var.yoffset == var->yoffset))
+ return 0; /* No change, do nothing */
+
+ y_bottom = var->yoffset;
+
+ if (!(var->vmode & FB_VMODE_YWRAP))
+ y_bottom += var->yres;
+
+ if (y_bottom > info->var.yres_virtual)
+ return -EINVAL;
+
+ mutex_lock(&fb_data->queue_mutex);
+
+ fb_data->fb_offset = (var->yoffset * var->xres_virtual + var->xoffset)
+ * (var->bits_per_pixel) / 8;
+
+ fb_data->epdc_fb_var.xoffset = var->xoffset;
+ fb_data->epdc_fb_var.yoffset = var->yoffset;
+
+ if (var->vmode & FB_VMODE_YWRAP)
+ info->var.vmode |= FB_VMODE_YWRAP;
+ else
+ info->var.vmode &= ~FB_VMODE_YWRAP;
+
+ mutex_unlock(&fb_data->queue_mutex);
+
+ return 0;
+}
+
+static struct fb_ops mxc_epdc_fb_ops = {
+ .owner = THIS_MODULE,
+ .fb_check_var = mxc_epdc_fb_check_var,
+ .fb_set_par = mxc_epdc_fb_set_par,
+ .fb_setcmap = mxc_epdc_fb_setcmap,
+ .fb_setcolreg = mxc_epdc_fb_setcolreg,
+ .fb_pan_display = mxc_epdc_fb_pan_display,
+ .fb_ioctl = mxc_epdc_fb_ioctl,
+ .fb_mmap = mxc_epdc_fb_mmap,
+ .fb_blank = mxc_epdc_fb_blank,
+ .fb_fillrect = cfb_fillrect,
+ .fb_copyarea = cfb_copyarea,
+ .fb_imageblit = cfb_imageblit,
+};
+
+static struct fb_deferred_io mxc_epdc_fb_defio = {
+ .delay = HZ,
+ .deferred_io = mxc_epdc_fb_deferred_io,
+};
+
+static void epdc_done_work_func(struct work_struct *work)
+{
+ struct mxc_epdc_fb_data *fb_data =
+ container_of(work, struct mxc_epdc_fb_data,
+ epdc_done_work.work);
+ epdc_powerdown(fb_data);
+}
+
+static bool is_free_list_full(struct mxc_epdc_fb_data *fb_data)
+{
+ int count = 0;
+ struct update_data_list *plist;
+
+ /* Count buffers in free buffer list */
+ list_for_each_entry(plist, &fb_data->upd_buf_free_list, list)
+ count++;
+
+ /* Check to see if all buffers are in this list */
+ if (count == fb_data->max_num_updates)
+ return true;
+ else
+ return false;
+}
+
+static irqreturn_t mxc_epdc_irq_handler(int irq, void *dev_id)
+{
+ struct mxc_epdc_fb_data *fb_data = dev_id;
+ u32 ints_fired, luts1_ints_fired, luts2_ints_fired;
+
+ /*
+ * If we just completed one-time panel init, bypass
+ * queue handling, clear interrupt and return
+ */
+ if (fb_data->in_init) {
+ if (epdc_is_working_buffer_complete()) {
+ epdc_working_buf_intr(false);
+ epdc_clear_working_buf_irq();
+ dev_dbg(fb_data->dev, "Cleared WB for init update\n");
+ }
+
+ if (epdc_is_lut_complete(fb_data->rev, 0)) {
+ epdc_lut_complete_intr(fb_data->rev, 0, false);
+ epdc_clear_lut_complete_irq(fb_data->rev, 0);
+ fb_data->in_init = false;
+ dev_dbg(fb_data->dev, "Cleared LUT complete for init update\n");
+ }
+
+ return IRQ_HANDLED;
+ }
+
+ ints_fired = __raw_readl(EPDC_IRQ_MASK) & __raw_readl(EPDC_IRQ);
+ if (fb_data->rev < 20) {
+ luts1_ints_fired = 0;
+ luts2_ints_fired = 0;
+ } else {
+ luts1_ints_fired = __raw_readl(EPDC_IRQ_MASK1) & __raw_readl(EPDC_IRQ1);
+ luts2_ints_fired = __raw_readl(EPDC_IRQ_MASK2) & __raw_readl(EPDC_IRQ2);
+ }
+
+ if (!(ints_fired || luts1_ints_fired || luts2_ints_fired))
+ return IRQ_HANDLED;
+
+ if (__raw_readl(EPDC_IRQ) & EPDC_IRQ_TCE_UNDERRUN_IRQ) {
+ dev_err(fb_data->dev,
+ "TCE underrun! Will continue to update panel\n");
+ /* Clear TCE underrun IRQ */
+ __raw_writel(EPDC_IRQ_TCE_UNDERRUN_IRQ, EPDC_IRQ_CLEAR);
+ }
+
+ /* Check if we are waiting on EOF to sync a new update submission */
+ if (epdc_signal_eof()) {
+ epdc_eof_intr(false);
+ epdc_clear_eof_irq();
+ complete(&fb_data->eof_event);
+ }
+
+ /*
+ * Workaround for EPDC v2.0/v2.1 errata: Must read collision status
+ * before clearing IRQ, or else collision status for bits 16:63
+ * will be automatically cleared. So we read it here, and there is
+ * no conflict with using it in epdc_intr_work_func since the
+ * working buffer processing flow is strictly sequential (i.e.,
+ * only one WB processing done at a time, so the data grabbed
+ * here should be up-to-date and accurate when the WB processing
+ * completes. Also, note that there is no impact to other versions
+ * of EPDC by reading LUT status here.
+ */
+ if (fb_data->cur_update != NULL)
+ fb_data->epdc_colliding_luts = epdc_get_colliding_luts(fb_data->rev);
+
+ /* Clear the interrupt mask for any interrupts signalled */
+ __raw_writel(ints_fired, EPDC_IRQ_MASK_CLEAR);
+ __raw_writel(luts1_ints_fired, EPDC_IRQ_MASK1_CLEAR);
+ __raw_writel(luts2_ints_fired, EPDC_IRQ_MASK2_CLEAR);
+
+ dev_dbg(fb_data->dev, "EPDC interrupts fired = 0x%x, "
+ "LUTS1 fired = 0x%x, LUTS2 fired = 0x%x\n",
+ ints_fired, luts1_ints_fired, luts2_ints_fired);
+
+ queue_work(fb_data->epdc_intr_workqueue,
+ &fb_data->epdc_intr_work);
+
+ return IRQ_HANDLED;
+}
+
+static void epdc_intr_work_func(struct work_struct *work)
+{
+ struct mxc_epdc_fb_data *fb_data =
+ container_of(work, struct mxc_epdc_fb_data, epdc_intr_work);
+ struct update_data_list *collision_update;
+ struct mxcfb_rect *next_upd_region;
+ struct update_marker_data *next_marker;
+ struct update_marker_data *temp;
+ int temp_index;
+ u64 temp_mask;
+ u32 lut;
+ bool ignore_collision = false;
+ int i;
+ bool wb_lut_done = false;
+ bool free_update = true;
+ int next_lut, epdc_next_lut_15;
+ u32 epdc_luts_active, epdc_wb_busy, epdc_luts_avail, epdc_lut_cancelled;
+ u32 epdc_collision;
+ u64 epdc_irq_stat;
+ bool epdc_waiting_on_wb;
+ u32 coll_coord, coll_size;
+ struct mxcfb_rect coll_region;
+
+ /* Protect access to buffer queues and to update HW */
+ mutex_lock(&fb_data->queue_mutex);
+
+ /* Capture EPDC status one time to limit exposure to race conditions */
+ epdc_luts_active = epdc_any_luts_active(fb_data->rev);
+ epdc_wb_busy = epdc_is_working_buffer_busy();
+
+ /*XXX unsupport update cancelled in external mode temporarily */
+ if (fb_data->epdc_wb_mode)
+ epdc_lut_cancelled = 0;
+ else
+ epdc_lut_cancelled = epdc_is_lut_cancelled();
+
+ if (fb_data->epdc_wb_mode)
+ epdc_luts_avail = epdc_any_luts_real_available();
+ else
+ epdc_luts_avail = epdc_any_luts_available();
+
+ if (fb_data->epdc_wb_mode)
+ epdc_collision = fb_data->col_info.pixel_cnt ? 1 : 0;
+ else
+ epdc_collision = epdc_is_collision();
+
+ if (fb_data->rev < 20)
+ epdc_irq_stat = __raw_readl(EPDC_IRQ);
+ else
+ epdc_irq_stat = (u64)__raw_readl(EPDC_IRQ1) |
+ ((u64)__raw_readl(EPDC_IRQ2) << 32);
+ epdc_waiting_on_wb = (fb_data->cur_update != NULL) ? true : false;
+
+ /* Free any LUTs that have completed */
+ for (i = 0; i < fb_data->num_luts; i++) {
+ if ((epdc_irq_stat & (1ULL << i)) == 0)
+ continue;
+
+ dev_dbg(fb_data->dev, "LUT %d completed\n", i);
+
+ /* Disable IRQ for completed LUT */
+ epdc_lut_complete_intr(fb_data->rev, i, false);
+
+ /*
+ * Go through all updates in the collision list and
+ * unmask any updates that were colliding with
+ * the completed LUT.
+ */
+ list_for_each_entry(collision_update,
+ &fb_data->upd_buf_collision_list, list) {
+ collision_update->collision_mask =
+ collision_update->collision_mask & ~(1ULL << i);
+ }
+
+ epdc_clear_lut_complete_irq(fb_data->rev, i);
+
+ fb_data->luts_complete_wb |= 1ULL << i;
+ if (i != 0)
+ fb_data->luts_complete |= 1ULL << i;
+
+ fb_data->lut_update_order[i] = 0;
+
+ /* Signal completion if submit workqueue needs a LUT */
+ if (fb_data->waiting_for_lut) {
+ complete(&fb_data->update_res_free);
+ fb_data->waiting_for_lut = false;
+ }
+
+ /* Signal completion if LUT15 free and is needed */
+ if (fb_data->waiting_for_lut15 && (i == 15)) {
+ complete(&fb_data->lut15_free);
+ fb_data->waiting_for_lut15 = false;
+ }
+
+ /* Detect race condition where WB and its LUT complete
+ (i.e. full update completes) in one swoop */
+ if (epdc_waiting_on_wb &&
+ (i == fb_data->cur_update->lut_num))
+ wb_lut_done = true;
+
+ /* Signal completion if anyone waiting on this LUT */
+ if (!wb_lut_done)
+ list_for_each_entry_safe(next_marker, temp,
+ &fb_data->full_marker_list,
+ full_list) {
+ if (next_marker->lut_num != i)
+ continue;
+
+ /* Found marker to signal - remove from list */
+ list_del_init(&next_marker->full_list);
+
+ /* Signal completion of update */
+ dev_dbg(fb_data->dev, "Signaling marker %d\n",
+ next_marker->update_marker);
+ if (next_marker->waiting)
+ complete(&next_marker->update_completion);
+ else
+ kfree(next_marker);
+ }
+ }
+
+ /* Check to see if all updates have completed */
+ if (list_empty(&fb_data->upd_pending_list) &&
+ is_free_list_full(fb_data) &&
+ !epdc_waiting_on_wb &&
+ !epdc_luts_active) {
+
+ fb_data->updates_active = false;
+
+ if (fb_data->pwrdown_delay != FB_POWERDOWN_DISABLE) {
+ /*
+ * Set variable to prevent overlapping
+ * enable/disable requests
+ */
+ fb_data->powering_down = true;
+
+ /* Schedule task to disable EPDC HW until next update */
+ schedule_delayed_work(&fb_data->epdc_done_work,
+ msecs_to_jiffies(fb_data->pwrdown_delay));
+
+ /* Reset counter to reduce chance of overflow */
+ fb_data->order_cnt = 0;
+ }
+
+ if (fb_data->waiting_for_idle)
+ complete(&fb_data->updates_done);
+ }
+
+ /* Is Working Buffer busy? */
+ if (epdc_wb_busy) {
+ /* Can't submit another update until WB is done */
+ mutex_unlock(&fb_data->queue_mutex);
+ return;
+ }
+
+ /*
+ * Were we waiting on working buffer?
+ * If so, update queues and check for collisions
+ */
+ if (epdc_waiting_on_wb) {
+ dev_dbg(fb_data->dev, "\nWorking buffer completed\n");
+
+ /* Signal completion if submit workqueue was waiting on WB */
+ if (fb_data->waiting_for_wb) {
+ complete(&fb_data->update_res_free);
+ fb_data->waiting_for_wb = false;
+ }
+
+ if (fb_data->cur_update->update_desc->upd_data.flags
+ & EPDC_FLAG_TEST_COLLISION) {
+ /* This was a dry run to test for collision */
+
+ /* Signal marker */
+ list_for_each_entry_safe(next_marker, temp,
+ &fb_data->full_marker_list,
+ full_list) {
+ if (next_marker->lut_num != DRY_RUN_NO_LUT)
+ continue;
+
+ if (epdc_collision)
+ next_marker->collision_test = true;
+ else
+ next_marker->collision_test = false;
+
+ dev_dbg(fb_data->dev,
+ "In IRQ, collision_test = %d\n",
+ next_marker->collision_test);
+
+ /* Found marker to signal - remove from list */
+ list_del_init(&next_marker->full_list);
+
+ /* Signal completion of update */
+ dev_dbg(fb_data->dev, "Signaling marker "
+ "for dry-run - %d\n",
+ next_marker->update_marker);
+ complete(&next_marker->update_completion);
+ }
+ memset(&fb_data->col_info, 0x0, sizeof(struct pxp_collision_info));
+ } else if (epdc_lut_cancelled && !epdc_collision) {
+ /*
+ * Note: The update may be cancelled (void) if all
+ * pixels collided. In that case we handle it as a
+ * collision, not a cancel.
+ */
+
+ /* Clear LUT status (might be set if no AUTOWV used) */
+
+ /*
+ * Disable and clear IRQ for the LUT used.
+ * Even though LUT is cancelled in HW, the LUT
+ * complete bit may be set if AUTOWV not used.
+ */
+ epdc_lut_complete_intr(fb_data->rev,
+ fb_data->cur_update->lut_num, false);
+ epdc_clear_lut_complete_irq(fb_data->rev,
+ fb_data->cur_update->lut_num);
+
+ fb_data->lut_update_order[fb_data->cur_update->lut_num] = 0;
+
+ /* Signal completion if submit workqueue needs a LUT */
+ if (fb_data->waiting_for_lut) {
+ complete(&fb_data->update_res_free);
+ fb_data->waiting_for_lut = false;
+ }
+
+ list_for_each_entry_safe(next_marker, temp,
+ &fb_data->cur_update->update_desc->upd_marker_list,
+ upd_list) {
+
+ /* Del from per-update & full list */
+ list_del_init(&next_marker->upd_list);
+ list_del_init(&next_marker->full_list);
+
+ /* Signal completion of update */
+ dev_dbg(fb_data->dev,
+ "Signaling marker (cancelled) %d\n",
+ next_marker->update_marker);
+ if (next_marker->waiting)
+ complete(&next_marker->update_completion);
+ else
+ kfree(next_marker);
+ }
+ } else if (epdc_collision) {
+ /* Real update (no dry-run), collision occurred */
+
+ /* Check list of colliding LUTs, and add to our collision mask */
+ if (fb_data->epdc_wb_mode)
+ fb_data->epdc_colliding_luts = (u64)fb_data->col_info.victim_luts[0] |
+ (((u64)fb_data->col_info.victim_luts[1]) << 32);
+
+ fb_data->cur_update->collision_mask =
+ fb_data->epdc_colliding_luts;
+
+ /* Clear collisions that completed since WB began */
+ fb_data->cur_update->collision_mask &=
+ ~fb_data->luts_complete_wb;
+
+ dev_dbg(fb_data->dev, "Collision mask = 0x%llx\n",
+ fb_data->epdc_colliding_luts);
+
+ /* For EPDC 2.0 and later, minimum collision bounds
+ are provided by HW. Recompute new bounds here. */
+ if ((fb_data->upd_scheme != UPDATE_SCHEME_SNAPSHOT)
+ && (fb_data->rev >= 20)) {
+ u32 xres, yres, rotate;
+ struct mxcfb_rect adj_update_region;
+ struct mxcfb_rect *cur_upd_rect =
+ &fb_data->cur_update->update_desc->upd_data.update_region;
+
+ if (fb_data->epdc_wb_mode) {
+ adjust_coordinates(fb_data->epdc_fb_var.xres,
+ fb_data->epdc_fb_var.yres, fb_data->epdc_fb_var.rotate,
+ cur_upd_rect, &adj_update_region);
+
+ coll_region.left = fb_data->col_info.rect_min_x + adj_update_region.left;
+ coll_region.top = fb_data->col_info.rect_min_y + adj_update_region.top;
+ coll_region.width = fb_data->col_info.rect_max_x - fb_data->col_info.rect_min_x + 1;
+ coll_region.height = fb_data->col_info.rect_max_y - fb_data->col_info.rect_min_y + 1;
+ memset(&fb_data->col_info, 0x0, sizeof(struct pxp_collision_info));
+ } else {
+ /* Get collision region coords from EPDC */
+ coll_coord = __raw_readl(EPDC_UPD_COL_CORD);
+ coll_size = __raw_readl(EPDC_UPD_COL_SIZE);
+ coll_region.left =
+ (coll_coord & EPDC_UPD_COL_CORD_XCORD_MASK)
+ >> EPDC_UPD_COL_CORD_XCORD_OFFSET;
+ coll_region.top =
+ (coll_coord & EPDC_UPD_COL_CORD_YCORD_MASK)
+ >> EPDC_UPD_COL_CORD_YCORD_OFFSET;
+ coll_region.width =
+ (coll_size & EPDC_UPD_COL_SIZE_WIDTH_MASK)
+ >> EPDC_UPD_COL_SIZE_WIDTH_OFFSET;
+ coll_region.height =
+ (coll_size & EPDC_UPD_COL_SIZE_HEIGHT_MASK)
+ >> EPDC_UPD_COL_SIZE_HEIGHT_OFFSET;
+ }
+ dev_dbg(fb_data->dev, "Coll region: l = %d, "
+ "t = %d, w = %d, h = %d\n",
+ coll_region.left, coll_region.top,
+ coll_region.width, coll_region.height);
+
+ /* Convert coords back to orig orientation */
+ switch (fb_data->epdc_fb_var.rotate) {
+ case FB_ROTATE_CW:
+ xres = fb_data->epdc_fb_var.yres;
+ yres = fb_data->epdc_fb_var.xres;
+ rotate = FB_ROTATE_CCW;
+ break;
+ case FB_ROTATE_UD:
+ xres = fb_data->epdc_fb_var.xres;
+ yres = fb_data->epdc_fb_var.yres;
+ rotate = FB_ROTATE_UD;
+ break;
+ case FB_ROTATE_CCW:
+ xres = fb_data->epdc_fb_var.yres;
+ yres = fb_data->epdc_fb_var.xres;
+ rotate = FB_ROTATE_CW;
+ break;
+ default:
+ xres = fb_data->epdc_fb_var.xres;
+ yres = fb_data->epdc_fb_var.yres;
+ rotate = FB_ROTATE_UR;
+ break;
+ }
+ adjust_coordinates(xres, yres, rotate,
+ &coll_region, cur_upd_rect);
+
+ dev_dbg(fb_data->dev, "Adj coll region: l = %d, "
+ "t = %d, w = %d, h = %d\n",
+ cur_upd_rect->left, cur_upd_rect->top,
+ cur_upd_rect->width,
+ cur_upd_rect->height);
+ }
+
+ /*
+ * If we collide with newer updates, then
+ * we don't need to re-submit the update. The
+ * idea is that the newer updates should take
+ * precedence anyways, so we don't want to
+ * overwrite them.
+ */
+ for (temp_mask = fb_data->cur_update->collision_mask, lut = 0;
+ temp_mask != 0;
+ lut++, temp_mask = temp_mask >> 1) {
+ if (!(temp_mask & 0x1))
+ continue;
+
+ if (fb_data->lut_update_order[lut] >=
+ fb_data->cur_update->update_desc->update_order) {
+ dev_dbg(fb_data->dev,
+ "Ignoring collision with"
+ "newer update.\n");
+ ignore_collision = true;
+ break;
+ }
+ }
+
+ if (!ignore_collision) {
+ free_update = false;
+ /*
+ * If update has markers, clear the LUTs to
+ * avoid signalling that they have completed.
+ */
+ list_for_each_entry_safe(next_marker, temp,
+ &fb_data->cur_update->update_desc->upd_marker_list,
+ upd_list)
+ next_marker->lut_num = INVALID_LUT;
+
+ /* Move to collision list */
+ list_add_tail(&fb_data->cur_update->list,
+ &fb_data->upd_buf_collision_list);
+ }
+ }
+
+ /* Do we need to free the current update descriptor? */
+ if (free_update) {
+ /* Handle condition where WB & LUT are both complete */
+ if (wb_lut_done)
+ list_for_each_entry_safe(next_marker, temp,
+ &fb_data->cur_update->update_desc->upd_marker_list,
+ upd_list) {
+
+ /* Del from per-update & full list */
+ list_del_init(&next_marker->upd_list);
+ list_del_init(&next_marker->full_list);
+
+ /* Signal completion of update */
+ dev_dbg(fb_data->dev,
+ "Signaling marker (wb) %d\n",
+ next_marker->update_marker);
+ if (next_marker->waiting)
+ complete(&next_marker->update_completion);
+ else
+ kfree(next_marker);
+ }
+
+ /* Free marker list and update descriptor */
+ kfree(fb_data->cur_update->update_desc);
+
+ /* Add to free buffer list */
+ list_add_tail(&fb_data->cur_update->list,
+ &fb_data->upd_buf_free_list);
+
+ /* Check to see if all updates have completed */
+ if (list_empty(&fb_data->upd_pending_list) &&
+ is_free_list_full(fb_data) &&
+ !epdc_luts_active) {
+
+ fb_data->updates_active = false;
+
+ if (fb_data->pwrdown_delay !=
+ FB_POWERDOWN_DISABLE) {
+ /*
+ * Set variable to prevent overlapping
+ * enable/disable requests
+ */
+ fb_data->powering_down = true;
+
+ /* Schedule EPDC disable */
+ schedule_delayed_work(&fb_data->epdc_done_work,
+ msecs_to_jiffies(fb_data->pwrdown_delay));
+
+ /* Reset counter to reduce chance of overflow */
+ fb_data->order_cnt = 0;
+ }
+
+ if (fb_data->waiting_for_idle)
+ complete(&fb_data->updates_done);
+ }
+ }
+
+ /* Clear current update */
+ fb_data->cur_update = NULL;
+
+ /* Clear IRQ for working buffer */
+ epdc_working_buf_intr(false);
+ epdc_clear_working_buf_irq();
+ }
+
+ if (fb_data->upd_scheme != UPDATE_SCHEME_SNAPSHOT) {
+ /* Queued update scheme processing */
+
+ /* Schedule task to submit collision and pending update */
+ if (!fb_data->powering_down)
+ queue_work(fb_data->epdc_submit_workqueue,
+ &fb_data->epdc_submit_work);
+
+ /* Release buffer queues */
+ mutex_unlock(&fb_data->queue_mutex);
+
+ return;
+ }
+
+ /* Snapshot update scheme processing */
+
+ /* Check to see if any LUTs are free */
+ if (!epdc_luts_avail) {
+ dev_dbg(fb_data->dev, "No luts available.\n");
+ mutex_unlock(&fb_data->queue_mutex);
+ return;
+ }
+
+ epdc_next_lut_15 = epdc_choose_next_lut(fb_data, &next_lut);
+ /* Check to see if there is a valid LUT to use */
+ if (epdc_next_lut_15 && fb_data->tce_prevent && (fb_data->rev < 20)) {
+ dev_dbg(fb_data->dev, "Must wait for LUT15\n");
+ mutex_unlock(&fb_data->queue_mutex);
+ return;
+ }
+
+ /*
+ * Are any of our collision updates able to go now?
+ * Go through all updates in the collision list and check to see
+ * if the collision mask has been fully cleared
+ */
+ list_for_each_entry(collision_update,
+ &fb_data->upd_buf_collision_list, list) {
+
+ if (collision_update->collision_mask != 0)
+ continue;
+
+ dev_dbg(fb_data->dev, "A collision update is ready to go!\n");
+ /*
+ * We have a collision cleared, so select it
+ * and we will retry the update
+ */
+ fb_data->cur_update = collision_update;
+ list_del_init(&fb_data->cur_update->list);
+ break;
+ }
+
+ /*
+ * If we didn't find a collision update ready to go,
+ * we try to grab one from the update queue
+ */
+ if (fb_data->cur_update == NULL) {
+ /* Is update list empty? */
+ if (list_empty(&fb_data->upd_buf_queue)) {
+ dev_dbg(fb_data->dev, "No pending updates.\n");
+
+ /* No updates pending, so we are done */
+ mutex_unlock(&fb_data->queue_mutex);
+ return;
+ } else {
+ dev_dbg(fb_data->dev, "Found a pending update!\n");
+
+ /* Process next item in update list */
+ fb_data->cur_update =
+ list_entry(fb_data->upd_buf_queue.next,
+ struct update_data_list, list);
+ list_del_init(&fb_data->cur_update->list);
+ }
+ }
+
+ /* Use LUT selected above */
+ fb_data->cur_update->lut_num = next_lut;
+
+ /* Associate LUT with update markers */
+ list_for_each_entry_safe(next_marker, temp,
+ &fb_data->cur_update->update_desc->upd_marker_list, upd_list)
+ next_marker->lut_num = fb_data->cur_update->lut_num;
+
+ /* Mark LUT as containing new update */
+ fb_data->lut_update_order[fb_data->cur_update->lut_num] =
+ fb_data->cur_update->update_desc->update_order;
+
+ /* Enable Collision and WB complete IRQs */
+ epdc_working_buf_intr(true);
+ epdc_lut_complete_intr(fb_data->rev, fb_data->cur_update->lut_num, true);
+
+ /* Program EPDC update to process buffer */
+ next_upd_region =
+ &fb_data->cur_update->update_desc->upd_data.update_region;
+
+ /* add working buffer update here for external mode */
+ if (fb_data->epdc_wb_mode)
+ epdc_working_buffer_update(fb_data, fb_data->cur_update,
+ next_upd_region);
+
+ if (fb_data->cur_update->update_desc->upd_data.temp
+ != TEMP_USE_AMBIENT) {
+ temp_index = mxc_epdc_fb_get_temp_index(fb_data,
+ fb_data->cur_update->update_desc->upd_data.temp);
+ epdc_set_temp(temp_index);
+ } else
+ epdc_set_temp(fb_data->temp_index);
+ epdc_set_update_addr(fb_data->cur_update->phys_addr +
+ fb_data->cur_update->update_desc->epdc_offs);
+ epdc_set_update_coord(next_upd_region->left, next_upd_region->top);
+ epdc_set_update_dimensions(next_upd_region->width,
+ next_upd_region->height);
+ if (fb_data->rev > 20)
+ epdc_set_update_stride(fb_data->cur_update->update_desc->epdc_stride);
+ if (fb_data->wv_modes_update &&
+ (fb_data->cur_update->update_desc->upd_data.waveform_mode
+ == WAVEFORM_MODE_AUTO)) {
+ epdc_set_update_waveform(&fb_data->wv_modes);
+ fb_data->wv_modes_update = false;
+ }
+
+ epdc_submit_update(fb_data->cur_update->lut_num,
+ fb_data->cur_update->update_desc->upd_data.waveform_mode,
+ fb_data->cur_update->update_desc->upd_data.update_mode,
+ false, false, 0);
+
+ /* Release buffer queues */
+ mutex_unlock(&fb_data->queue_mutex);
+
+ return;
+}
+
+static void draw_mode0(struct mxc_epdc_fb_data *fb_data)
+{
+ u32 *upd_buf_ptr;
+ int i;
+ struct fb_var_screeninfo *screeninfo = &fb_data->epdc_fb_var;
+ u32 xres, yres;
+
+ upd_buf_ptr = (u32 *)fb_data->info.screen_base;
+
+ epdc_working_buf_intr(true);
+ epdc_lut_complete_intr(fb_data->rev, 0, true);
+
+ /* Use unrotated (native) width/height */
+ if ((screeninfo->rotate == FB_ROTATE_CW) ||
+ (screeninfo->rotate == FB_ROTATE_CCW)) {
+ xres = screeninfo->yres;
+ yres = screeninfo->xres;
+ } else {
+ xres = screeninfo->xres;
+ yres = screeninfo->yres;
+ }
+
+ /* Program EPDC update to process buffer */
+ epdc_set_update_addr(fb_data->phys_start);
+ epdc_set_update_coord(0, 0);
+ epdc_set_update_dimensions(xres, yres);
+ if (fb_data->rev > 20)
+ epdc_set_update_stride(0);
+ epdc_submit_update(0, fb_data->wv_modes.mode_init, UPDATE_MODE_FULL,
+ false, true, 0xFF);
+
+ dev_dbg(fb_data->dev, "Mode0 update - Waiting for LUT to complete...\n");
+
+ /* Will timeout after ~4-5 seconds */
+
+ for (i = 0; i < 40; i++) {
+ if (!epdc_is_lut_active(0)) {
+ dev_dbg(fb_data->dev, "Mode0 init complete\n");
+ return;
+ }
+ msleep(100);
+ }
+
+ dev_err(fb_data->dev, "Mode0 init failed!\n");
+
+ return;
+}
+
+
+static void mxc_epdc_fb_fw_handler(const struct firmware *fw,
+ void *context)
+{
+ struct mxc_epdc_fb_data *fb_data = context;
+ int ret;
+ struct mxcfb_waveform_data_file *wv_file;
+ int wv_data_offs;
+ int i;
+ struct mxcfb_update_data update;
+ struct mxcfb_update_marker_data upd_marker_data;
+ struct fb_var_screeninfo *screeninfo = &fb_data->epdc_fb_var;
+ u32 xres, yres;
+ struct clk *epdc_parent;
+ unsigned long rounded_parent_rate, epdc_pix_rate,
+ rounded_pix_clk, target_pix_clk;
+
+ if (fw == NULL) {
+ /* If default FW file load failed, we give up */
+ if (fb_data->fw_default_load)
+ return;
+
+ /* Try to load default waveform */
+ dev_dbg(fb_data->dev,
+ "Can't find firmware. Trying fallback fw\n");
+ fb_data->fw_default_load = true;
+ ret = request_firmware_nowait(THIS_MODULE, FW_ACTION_HOTPLUG,
+ "imx/epdc/epdc.fw", fb_data->dev, GFP_KERNEL, fb_data,
+ mxc_epdc_fb_fw_handler);
+ if (ret)
+ dev_err(fb_data->dev,
+ "Failed request_firmware_nowait err %d\n", ret);
+
+ return;
+ }
+
+ wv_file = (struct mxcfb_waveform_data_file *)fw->data;
+
+ dump_fw_header(fb_data->dev, wv_file);
+
+ /* Get size and allocate temperature range table */
+ fb_data->trt_entries = wv_file->wdh.trc + 1;
+ fb_data->temp_range_bounds = kzalloc(fb_data->trt_entries, GFP_KERNEL);
+
+ for (i = 0; i < fb_data->trt_entries; i++)
+ dev_dbg(fb_data->dev, "trt entry #%d = 0x%x\n", i, *((u8 *)&wv_file->data + i));
+
+ /* Copy TRT data */
+ memcpy(fb_data->temp_range_bounds, &wv_file->data, fb_data->trt_entries);
+
+ /* Set default temperature index using TRT and room temp */
+ fb_data->temp_index = mxc_epdc_fb_get_temp_index(fb_data, DEFAULT_TEMP);
+
+ /* Get offset and size for waveform data */
+ wv_data_offs = sizeof(wv_file->wdh) + fb_data->trt_entries + 1;
+ fb_data->waveform_buffer_size = fw->size - wv_data_offs;
+
+ /* Allocate memory for waveform data */
+ fb_data->waveform_buffer_virt = dma_alloc_coherent(fb_data->dev,
+ fb_data->waveform_buffer_size,
+ &fb_data->waveform_buffer_phys,
+ GFP_DMA | GFP_KERNEL);
+ if (fb_data->waveform_buffer_virt == NULL) {
+ dev_err(fb_data->dev, "Can't allocate mem for waveform!\n");
+ return;
+ }
+
+ memcpy(fb_data->waveform_buffer_virt, (u8 *)(fw->data) + wv_data_offs,
+ fb_data->waveform_buffer_size);
+
+ /* Check for advanced algorithms */
+ if ((wv_file->wdh.luts & WAVEFORM_HDR_LUT_ADVANCED_ALGO_MASK) != 0) {
+ dev_dbg(fb_data->dev,
+ "Waveform file supports advanced algorithms\n");
+ fb_data->waveform_is_advanced = true;
+ } else {
+ dev_dbg(fb_data->dev,
+ "Waveform file does not support advanced algorithms\n");
+ fb_data->waveform_is_advanced = false;
+ }
+
+ release_firmware(fw);
+
+ /* Enable clocks to access EPDC regs */
+ clk_prepare_enable(fb_data->epdc_clk_axi);
+
+ target_pix_clk = fb_data->cur_mode->vmode->pixclock;
+
+ rounded_pix_clk = clk_round_rate(fb_data->epdc_clk_pix, target_pix_clk);
+
+ if (((rounded_pix_clk >= target_pix_clk + target_pix_clk/100) ||
+ (rounded_pix_clk <= target_pix_clk - target_pix_clk/100))) {
+ /* Can't get close enough without changing parent clk */
+ epdc_parent = clk_get_parent(fb_data->epdc_clk_pix);
+ rounded_parent_rate = clk_round_rate(epdc_parent, target_pix_clk);
+
+ epdc_pix_rate = target_pix_clk;
+ while (epdc_pix_rate < rounded_parent_rate)
+ epdc_pix_rate *= 2;
+ clk_set_rate(epdc_parent, epdc_pix_rate);
+
+ rounded_pix_clk = clk_round_rate(fb_data->epdc_clk_pix, target_pix_clk);
+ if (((rounded_pix_clk >= target_pix_clk + target_pix_clk/100) ||
+ (rounded_pix_clk <= target_pix_clk - target_pix_clk/100)))
+ /* Still can't get a good clock, provide warning */
+ dev_err(fb_data->dev, "Unable to get an accurate EPDC pix clk"
+ "desired = %lu, actual = %lu\n", target_pix_clk,
+ rounded_pix_clk);
+ }
+
+ clk_set_rate(fb_data->epdc_clk_pix, rounded_pix_clk);
+
+ /* Enable pix clk for EPDC */
+ clk_prepare_enable(fb_data->epdc_clk_pix);
+
+ epdc_init_sequence(fb_data);
+
+ /* Disable clocks */
+ clk_disable_unprepare(fb_data->epdc_clk_axi);
+ clk_disable_unprepare(fb_data->epdc_clk_pix);
+
+ fb_data->hw_ready = true;
+ fb_data->hw_initializing = false;
+
+ /* Use unrotated (native) width/height */
+ if ((screeninfo->rotate == FB_ROTATE_CW) ||
+ (screeninfo->rotate == FB_ROTATE_CCW)) {
+ xres = screeninfo->yres;
+ yres = screeninfo->xres;
+ } else {
+ xres = screeninfo->xres;
+ yres = screeninfo->yres;
+ }
+
+ update.update_region.left = 0;
+ update.update_region.width = xres;
+ update.update_region.top = 0;
+ update.update_region.height = yres;
+ update.update_mode = UPDATE_MODE_FULL;
+ update.waveform_mode = WAVEFORM_MODE_AUTO;
+ update.update_marker = INIT_UPDATE_MARKER;
+ update.temp = TEMP_USE_AMBIENT;
+ update.flags = 0;
+ update.dither_mode = 0;
+
+ upd_marker_data.update_marker = update.update_marker;
+
+ mxc_epdc_fb_send_update(&update, &fb_data->info);
+
+ /* Block on initial update */
+ ret = mxc_epdc_fb_wait_update_complete(&upd_marker_data,
+ &fb_data->info);
+ if (ret < 0)
+ dev_err(fb_data->dev,
+ "Wait for initial update complete failed."
+ " Error = 0x%x", ret);
+}
+
+static int mxc_epdc_fb_init_hw(struct fb_info *info)
+{
+ struct mxc_epdc_fb_data *fb_data = (struct mxc_epdc_fb_data *)info;
+ int ret;
+
+ /*
+ * Create fw search string based on ID string in selected videomode.
+ * Format is "imx/epdc/epdc_[panel string].fw"
+ */
+ if (fb_data->cur_mode) {
+ strcat(fb_data->fw_str, "imx/epdc/epdc_");
+ strcat(fb_data->fw_str, fb_data->cur_mode->vmode->name);
+ strcat(fb_data->fw_str, ".fw");
+ }
+
+ fb_data->fw_default_load = false;
+
+ ret = request_firmware_nowait(THIS_MODULE, FW_ACTION_HOTPLUG,
+ fb_data->fw_str, fb_data->dev, GFP_KERNEL,
+ fb_data, mxc_epdc_fb_fw_handler);
+ if (ret)
+ dev_dbg(fb_data->dev,
+ "Failed request_firmware_nowait err %d\n", ret);
+
+ return ret;
+}
+
+static ssize_t store_update(struct device *device,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct mxcfb_update_data update;
+ struct fb_info *info = dev_get_drvdata(device);
+ struct mxc_epdc_fb_data *fb_data = (struct mxc_epdc_fb_data *)info;
+
+ if (strncmp(buf, "direct", 6) == 0)
+ update.waveform_mode = fb_data->wv_modes.mode_du;
+ else if (strncmp(buf, "gc16", 4) == 0)
+ update.waveform_mode = fb_data->wv_modes.mode_gc16;
+ else if (strncmp(buf, "gc4", 3) == 0)
+ update.waveform_mode = fb_data->wv_modes.mode_gc4;
+
+ /* Now, request full screen update */
+ update.update_region.left = 0;
+ update.update_region.width = fb_data->epdc_fb_var.xres;
+ update.update_region.top = 0;
+ update.update_region.height = fb_data->epdc_fb_var.yres;
+ update.update_mode = UPDATE_MODE_FULL;
+ update.temp = TEMP_USE_AMBIENT;
+ update.update_marker = 0;
+ update.flags = 0;
+
+ mxc_epdc_fb_send_update(&update, info);
+
+ return count;
+}
+
+static struct device_attribute fb_attrs[] = {
+ __ATTR(update, S_IRUGO|S_IWUSR, NULL, store_update),
+};
+
+static const struct of_device_id imx_epdc_dt_ids[] = {
+ { .compatible = "fsl,imx7d-epdc", },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, imx_epdc_dt_ids);
+
+static int mxc_epdc_fb_probe(struct platform_device *pdev)
+{
+ int ret = 0;
+ struct pinctrl *pinctrl;
+ struct mxc_epdc_fb_data *fb_data;
+ struct resource *res;
+ struct fb_info *info;
+ char *options, *opt;
+ char *panel_str = NULL;
+ char name[] = "mxcepdcfb";
+ struct fb_videomode *vmode;
+ int xres_virt, yres_virt, buf_size;
+ int xres_virt_rot, yres_virt_rot, pix_size_rot;
+ struct fb_var_screeninfo *var_info;
+ struct fb_fix_screeninfo *fix_info;
+ struct pxp_config_data *pxp_conf;
+ struct pxp_proc_data *proc_data;
+ struct scatterlist *sg;
+ struct update_data_list *upd_list;
+ struct update_data_list *plist, *temp_list;
+ int i;
+ unsigned long x_mem_size = 0;
+ u32 val;
+ int irq;
+ struct device_node *np = pdev->dev.of_node;
+ struct device_node *node;
+ phandle phandle;
+ u32 out_val[3];
+ int enable_gpio;
+ enum of_gpio_flags flag;
+ unsigned short *wk_p;
+
+ if (!np)
+ return -EINVAL;
+
+ fb_data = (struct mxc_epdc_fb_data *)framebuffer_alloc(
+ sizeof(struct mxc_epdc_fb_data), &pdev->dev);
+ if (fb_data == NULL) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ ret = of_property_read_u32_array(np, "epdc-ram", out_val, 3);
+ if (ret) {
+ dev_dbg(&pdev->dev, "no epdc-ram property found\n");
+ } else {
+ phandle = *out_val;
+
+ node = of_find_node_by_phandle(phandle);
+ if (!node) {
+ dev_dbg(&pdev->dev, "not find gpr node by phandle\n");
+ ret = PTR_ERR(node);
+ goto out_fbdata;
+ }
+ fb_data->gpr = syscon_node_to_regmap(node);
+ if (IS_ERR(fb_data->gpr)) {
+ dev_err(&pdev->dev, "failed to get gpr regmap\n");
+ ret = PTR_ERR(fb_data->gpr);
+ goto out_fbdata;
+ }
+ of_node_put(node);
+ fb_data->req_gpr = out_val[1];
+ fb_data->req_bit = out_val[2];
+
+ regmap_update_bits(fb_data->gpr, fb_data->req_gpr,
+ 1 << fb_data->req_bit, 0);
+ }
+
+ if (of_find_property(np, "en-gpios", NULL)) {
+ enable_gpio = of_get_named_gpio_flags(np, "en-gpios", 0, &flag);
+ if (enable_gpio == -EPROBE_DEFER) {
+ dev_info(&pdev->dev, "GPIO requested is not"
+ "here yet, deferring the probe\n");
+ return -EPROBE_DEFER;
+ }
+ if (!gpio_is_valid(enable_gpio)) {
+ dev_warn(&pdev->dev, "No dt property: en-gpios\n");
+ } else {
+
+ ret = devm_gpio_request_one(&pdev->dev,
+ enable_gpio,
+ (flag & OF_GPIO_ACTIVE_LOW)
+ ? GPIOF_OUT_INIT_LOW :
+ GPIOF_OUT_INIT_HIGH,
+ "en_pins");
+ if (ret) {
+ dev_err(&pdev->dev, "failed to request gpio"
+ " %d: %d\n", enable_gpio, ret);
+ return -EINVAL;
+ }
+ }
+ }
+
+ fb_data->qos_regmap = syscon_regmap_lookup_by_phandle(np, "qos");
+ if (IS_ERR(fb_data->qos_regmap)) {
+ dev_warn(&pdev->dev, "No qos phandle specified. Ignored.\n");
+ }
+
+ /* Get platform data and check validity */
+ fb_data->pdata = &epdc_data;
+ if ((fb_data->pdata == NULL) || (fb_data->pdata->num_modes < 1)
+ || (fb_data->pdata->epdc_mode == NULL)
+ || (fb_data->pdata->epdc_mode->vmode == NULL)) {
+ ret = -EINVAL;
+ goto out_fbdata;
+ }
+
+ if (fb_get_options(name, &options)) {
+ ret = -ENODEV;
+ goto out_fbdata;
+ }
+
+ fb_data->epdc_wb_mode = 1;
+ fb_data->tce_prevent = 0;
+
+ if (options)
+ while ((opt = strsep(&options, ",")) != NULL) {
+ if (!*opt)
+ continue;
+
+ if (!strncmp(opt, "bpp=", 4))
+ fb_data->default_bpp =
+ simple_strtoul(opt + 4, NULL, 0);
+ else if (!strncmp(opt, "x_mem=", 6))
+ x_mem_size = memparse(opt + 6, NULL);
+ else if (!strncmp(opt, "tce_prevent", 11))
+ fb_data->tce_prevent = 1;
+ else
+ panel_str = opt;
+ }
+
+ fb_data->dev = &pdev->dev;
+
+ if (!fb_data->default_bpp)
+ fb_data->default_bpp = 16;
+
+ /* Set default (first defined mode) before searching for a match */
+ fb_data->cur_mode = &fb_data->pdata->epdc_mode[0];
+
+ if (panel_str)
+ for (i = 0; i < fb_data->pdata->num_modes; i++)
+ if (!strcmp(fb_data->pdata->epdc_mode[i].vmode->name,
+ panel_str)) {
+ fb_data->cur_mode =
+ &fb_data->pdata->epdc_mode[i];
+ break;
+ }
+
+ vmode = fb_data->cur_mode->vmode;
+
+ platform_set_drvdata(pdev, fb_data);
+ info = &fb_data->info;
+
+ /* Allocate color map for the FB */
+ ret = fb_alloc_cmap(&info->cmap, 256, 0);
+ if (ret)
+ goto out_fbdata;
+
+ dev_dbg(&pdev->dev, "resolution %dx%d, bpp %d\n",
+ vmode->xres, vmode->yres, fb_data->default_bpp);
+
+ /*
+ * GPU alignment restrictions dictate framebuffer parameters:
+ * - 32-byte alignment for buffer width
+ * - 128-byte alignment for buffer height
+ * => 4K buffer alignment for buffer start
+ */
+ xres_virt = ALIGN(vmode->xres, 32);
+ yres_virt = ALIGN(vmode->yres, 128);
+ fb_data->max_pix_size = PAGE_ALIGN(xres_virt * yres_virt);
+
+ /*
+ * Have to check to see if aligned buffer size when rotated
+ * is bigger than when not rotated, and use the max
+ */
+ xres_virt_rot = ALIGN(vmode->yres, 32);
+ yres_virt_rot = ALIGN(vmode->xres, 128);
+ pix_size_rot = PAGE_ALIGN(xres_virt_rot * yres_virt_rot);
+ fb_data->max_pix_size = (fb_data->max_pix_size > pix_size_rot) ?
+ fb_data->max_pix_size : pix_size_rot;
+
+ buf_size = fb_data->max_pix_size * fb_data->default_bpp/8;
+
+ /* Compute the number of screens needed based on X memory requested */
+ if (x_mem_size > 0) {
+ fb_data->num_screens = DIV_ROUND_UP(x_mem_size, buf_size);
+ if (fb_data->num_screens < NUM_SCREENS_MIN)
+ fb_data->num_screens = NUM_SCREENS_MIN;
+ else if (buf_size * fb_data->num_screens > SZ_16M)
+ fb_data->num_screens = SZ_16M / buf_size;
+ } else
+ fb_data->num_screens = NUM_SCREENS_MIN;
+
+ fb_data->map_size = buf_size * fb_data->num_screens;
+ dev_dbg(&pdev->dev, "memory to allocate: %d\n", fb_data->map_size);
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (res == NULL) {
+ ret = -ENODEV;
+ goto out_cmap;
+ }
+
+ epdc_v2_base = devm_ioremap_resource(&pdev->dev, res);
+ if (epdc_v2_base == NULL) {
+ ret = -ENOMEM;
+ goto out_cmap;
+ }
+
+ /* Allocate FB memory */
+ info->screen_base = dma_alloc_writecombine(&pdev->dev,
+ fb_data->map_size,
+ &fb_data->phys_start,
+ GFP_DMA | GFP_KERNEL);
+
+ if (info->screen_base == NULL) {
+ ret = -ENOMEM;
+ goto out_cmap;
+ }
+ dev_dbg(&pdev->dev, "allocated at %p:0x%x\n", info->screen_base,
+ fb_data->phys_start);
+
+ var_info = &info->var;
+ var_info->activate = FB_ACTIVATE_TEST;
+ var_info->bits_per_pixel = fb_data->default_bpp;
+ var_info->xres = vmode->xres;
+ var_info->yres = vmode->yres;
+ var_info->xres_virtual = xres_virt;
+ /* Additional screens allow for panning and buffer flipping */
+ var_info->yres_virtual = yres_virt * fb_data->num_screens;
+
+ var_info->pixclock = vmode->pixclock;
+ var_info->left_margin = vmode->left_margin;
+ var_info->right_margin = vmode->right_margin;
+ var_info->upper_margin = vmode->upper_margin;
+ var_info->lower_margin = vmode->lower_margin;
+ var_info->hsync_len = vmode->hsync_len;
+ var_info->vsync_len = vmode->vsync_len;
+ var_info->vmode = FB_VMODE_NONINTERLACED;
+
+ switch (fb_data->default_bpp) {
+ case 32:
+ case 24:
+ var_info->red.offset = 16;
+ var_info->red.length = 8;
+ var_info->green.offset = 8;
+ var_info->green.length = 8;
+ var_info->blue.offset = 0;
+ var_info->blue.length = 8;
+ break;
+
+ case 16:
+ var_info->red.offset = 11;
+ var_info->red.length = 5;
+ var_info->green.offset = 5;
+ var_info->green.length = 6;
+ var_info->blue.offset = 0;
+ var_info->blue.length = 5;
+ break;
+
+ case 8:
+ /*
+ * For 8-bit grayscale, R, G, and B offset are equal.
+ *
+ */
+ var_info->grayscale = GRAYSCALE_8BIT;
+
+ var_info->red.length = 8;
+ var_info->red.offset = 0;
+ var_info->red.msb_right = 0;
+ var_info->green.length = 8;
+ var_info->green.offset = 0;
+ var_info->green.msb_right = 0;
+ var_info->blue.length = 8;
+ var_info->blue.offset = 0;
+ var_info->blue.msb_right = 0;
+ break;
+
+ default:
+ dev_err(&pdev->dev, "unsupported bitwidth %d\n",
+ fb_data->default_bpp);
+ ret = -EINVAL;
+ goto out_dma_fb;
+ }
+
+ fix_info = &info->fix;
+
+ strcpy(fix_info->id, "mxc_epdc_fb");
+ fix_info->type = FB_TYPE_PACKED_PIXELS;
+ fix_info->visual = FB_VISUAL_TRUECOLOR;
+ fix_info->xpanstep = 0;
+ fix_info->ypanstep = 0;
+ fix_info->ywrapstep = 0;
+ fix_info->accel = FB_ACCEL_NONE;
+ fix_info->smem_start = fb_data->phys_start;
+ fix_info->smem_len = fb_data->map_size;
+ fix_info->ypanstep = 0;
+
+ fb_data->native_width = vmode->xres;
+ fb_data->native_height = vmode->yres;
+
+ info->fbops = &mxc_epdc_fb_ops;
+ info->var.activate = FB_ACTIVATE_NOW;
+ info->pseudo_palette = fb_data->pseudo_palette;
+ info->screen_size = info->fix.smem_len;
+ info->flags = FBINFO_FLAG_DEFAULT;
+
+ mxc_epdc_fb_set_fix(info);
+
+ fb_data->auto_mode = AUTO_UPDATE_MODE_REGION_MODE;
+ fb_data->upd_scheme = UPDATE_SCHEME_QUEUE_AND_MERGE;
+
+ /* Initialize our internal copy of the screeninfo */
+ fb_data->epdc_fb_var = *var_info;
+ fb_data->fb_offset = 0;
+ fb_data->eof_sync_period = 0;
+
+ fb_data->epdc_clk_axi = clk_get(fb_data->dev, "epdc_axi");
+ if (IS_ERR(fb_data->epdc_clk_axi)) {
+ dev_err(&pdev->dev, "Unable to get EPDC AXI clk."
+ "err = %d\n", (int)fb_data->epdc_clk_axi);
+ ret = -ENODEV;
+ goto out_dma_fb;
+ }
+ fb_data->epdc_clk_pix = clk_get(fb_data->dev, "epdc_pix");
+ if (IS_ERR(fb_data->epdc_clk_pix)) {
+ dev_err(&pdev->dev, "Unable to get EPDC pix clk."
+ "err = %d\n", (int)fb_data->epdc_clk_pix);
+ ret = -ENODEV;
+ goto out_dma_fb;
+ }
+
+ clk_prepare_enable(fb_data->epdc_clk_axi);
+ clk_prepare_enable(fb_data->epdc_clk_pix);
+ val = __raw_readl(EPDC_VERSION);
+ clk_disable_unprepare(fb_data->epdc_clk_pix);
+ clk_disable_unprepare(fb_data->epdc_clk_axi);
+ fb_data->rev = ((val & EPDC_VERSION_MAJOR_MASK) >>
+ EPDC_VERSION_MAJOR_OFFSET) * 10
+ + ((val & EPDC_VERSION_MINOR_MASK) >>
+ EPDC_VERSION_MINOR_OFFSET);
+ dev_dbg(&pdev->dev, "EPDC version = %d\n", fb_data->rev);
+
+ if (fb_data->rev < 20) {
+ fb_data->num_luts = EPDC_V1_NUM_LUTS;
+ fb_data->max_num_updates = EPDC_V1_MAX_NUM_UPDATES;
+ } else {
+ fb_data->num_luts = EPDC_V2_NUM_LUTS;
+ fb_data->max_num_updates = EPDC_V2_MAX_NUM_UPDATES;
+ if (vmode->xres > EPDC_V2_MAX_UPDATE_WIDTH)
+ fb_data->restrict_width = true;
+ }
+ fb_data->max_num_buffers = EPDC_MAX_NUM_BUFFERS;
+
+ /*
+ * Initialize lists for pending updates,
+ * active update requests, update collisions,
+ * and freely available updates.
+ */
+ INIT_LIST_HEAD(&fb_data->upd_pending_list);
+ INIT_LIST_HEAD(&fb_data->upd_buf_queue);
+ INIT_LIST_HEAD(&fb_data->upd_buf_free_list);
+ INIT_LIST_HEAD(&fb_data->upd_buf_collision_list);
+
+ /* Allocate update buffers and add them to the list */
+ for (i = 0; i < fb_data->max_num_updates; i++) {
+ upd_list = kzalloc(sizeof(*upd_list), GFP_KERNEL);
+ if (upd_list == NULL) {
+ ret = -ENOMEM;
+ goto out_upd_lists;
+ }
+
+ /* Add newly allocated buffer to free list */
+ list_add(&upd_list->list, &fb_data->upd_buf_free_list);
+ }
+
+ fb_data->virt_addr_updbuf =
+ kzalloc(sizeof(void *) * fb_data->max_num_buffers, GFP_KERNEL);
+ fb_data->phys_addr_updbuf =
+ kzalloc(sizeof(dma_addr_t) * fb_data->max_num_buffers,
+ GFP_KERNEL);
+ for (i = 0; i < fb_data->max_num_buffers; i++) {
+ /*
+ * Allocate memory for PxP output buffer.
+ * Each update buffer is 1 byte per pixel, and can
+ * be as big as the full-screen frame buffer
+ */
+ fb_data->virt_addr_updbuf[i] =
+ kmalloc(fb_data->max_pix_size, GFP_KERNEL);
+ fb_data->phys_addr_updbuf[i] =
+ virt_to_phys(fb_data->virt_addr_updbuf[i]);
+ if (fb_data->virt_addr_updbuf[i] == NULL) {
+ ret = -ENOMEM;
+ goto out_upd_buffers;
+ }
+
+ dev_dbg(fb_data->info.device, "allocated %d bytes @ 0x%08X\n",
+ fb_data->max_pix_size, fb_data->phys_addr_updbuf[i]);
+ }
+
+ /* Counter indicating which update buffer should be used next. */
+ fb_data->upd_buffer_num = 0;
+
+ /*
+ * Allocate memory for PxP SW workaround buffer
+ * These buffers are used to hold copy of the update region,
+ * before sending it to PxP for processing.
+ */
+ fb_data->virt_addr_copybuf =
+ dma_alloc_coherent(fb_data->info.device, fb_data->max_pix_size*2,
+ &fb_data->phys_addr_copybuf,
+ GFP_DMA | GFP_KERNEL);
+ if (fb_data->virt_addr_copybuf == NULL) {
+ ret = -ENOMEM;
+ goto out_upd_buffers;
+ }
+
+ fb_data->virt_addr_y4 =
+ dma_alloc_coherent(fb_data->info.device, fb_data->max_pix_size*2,
+ &fb_data->phys_addr_y4,
+ GFP_DMA | GFP_KERNEL);
+ if (fb_data->virt_addr_y4 == NULL) {
+ ret = -ENOMEM;
+ goto out_upd_buffers;
+ }
+
+ fb_data->virt_addr_y4c =
+ dma_alloc_coherent(fb_data->info.device, fb_data->max_pix_size*2,
+ &fb_data->phys_addr_y4c,
+ GFP_DMA | GFP_KERNEL);
+ if (fb_data->virt_addr_y4c == NULL) {
+ ret = -ENOMEM;
+ goto out_upd_buffers;
+ }
+
+ fb_data->virt_addr_black =
+ dma_alloc_coherent(fb_data->info.device, fb_data->max_pix_size*2,
+ &fb_data->phys_addr_black,
+ GFP_DMA | GFP_KERNEL);
+ if (fb_data->virt_addr_black == NULL) {
+ ret = -ENOMEM;
+ goto out_upd_buffers;
+ }
+
+ fb_data->working_buffer_size = vmode->yres * vmode->xres * 2;
+
+ /* Allocate memory for EPDC working buffer */
+ fb_data->working_buffer_virt =
+ dma_alloc_coherent(&pdev->dev, fb_data->working_buffer_size,
+ &fb_data->working_buffer_phys,
+ GFP_DMA | GFP_KERNEL);
+ if (fb_data->working_buffer_virt == NULL) {
+ dev_err(&pdev->dev, "Can't allocate mem for working buf!\n");
+ ret = -ENOMEM;
+ goto out_copybuffer;
+ }
+
+ /* initialize the working buffer */
+ wk_p = (unsigned short *)fb_data->working_buffer_virt;
+ for (i = 0; i < fb_data->cur_mode->vmode->xres *
+ fb_data->cur_mode->vmode->yres; i++) {
+ *wk_p = 0x00F0;
+ wk_p++;
+ }
+
+ fb_data->tmp_working_buffer_virt =
+ dma_alloc_coherent(&pdev->dev, fb_data->working_buffer_size,
+ &fb_data->tmp_working_buffer_phys,
+ GFP_DMA | GFP_KERNEL);
+ if (fb_data->tmp_working_buffer_virt == NULL) {
+ dev_err(&pdev->dev, "Can't allocate mem for tmp working buf!\n");
+ ret = -ENOMEM;
+ goto out_copybuffer;
+ }
+
+ /* Initialize EPDC pins */
+ pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
+ if (IS_ERR(pinctrl)) {
+ dev_err(&pdev->dev, "can't get/select pinctrl\n");
+ ret = PTR_ERR(pinctrl);
+ goto out_copybuffer;
+ }
+
+ fb_data->in_init = false;
+
+ fb_data->hw_ready = false;
+ fb_data->hw_initializing = false;
+
+ /*
+ * Set default waveform mode values.
+ * Should be overwritten via ioctl.
+ */
+ fb_data->wv_modes.mode_init = 0;
+ fb_data->wv_modes.mode_du = 1;
+ fb_data->wv_modes.mode_gc4 = 3;
+ fb_data->wv_modes.mode_gc8 = 2;
+ fb_data->wv_modes.mode_gc16 = 2;
+ fb_data->wv_modes.mode_gc32 = 2;
+ fb_data->wv_modes_update = true;
+
+ /* Initialize marker list */
+ INIT_LIST_HEAD(&fb_data->full_marker_list);
+
+ /* Initialize all LUTs to inactive */
+ fb_data->lut_update_order =
+ kzalloc(fb_data->num_luts * sizeof(u32 *), GFP_KERNEL);
+ for (i = 0; i < fb_data->num_luts; i++)
+ fb_data->lut_update_order[i] = 0;
+
+ INIT_DELAYED_WORK(&fb_data->epdc_done_work, epdc_done_work_func);
+ fb_data->epdc_submit_workqueue = alloc_workqueue("EPDC Submit",
+ WQ_MEM_RECLAIM | WQ_HIGHPRI |
+ WQ_CPU_INTENSIVE | WQ_UNBOUND, 1);
+ INIT_WORK(&fb_data->epdc_submit_work, epdc_submit_work_func);
+ fb_data->epdc_intr_workqueue = alloc_workqueue("EPDC Interrupt",
+ WQ_MEM_RECLAIM | WQ_HIGHPRI |
+ WQ_CPU_INTENSIVE | WQ_UNBOUND, 1);
+ INIT_WORK(&fb_data->epdc_intr_work, epdc_intr_work_func);
+
+ /* Retrieve EPDC IRQ num */
+ irq = platform_get_irq(pdev, 0);
+ if (irq < 0) {
+ dev_err(&pdev->dev, "cannot get IRQ resource\n");
+ ret = -ENODEV;
+ goto out_dma_work_buf;
+ }
+ fb_data->epdc_irq = irq;
+
+ /* Register IRQ handler */
+ ret = devm_request_irq(&pdev->dev, fb_data->epdc_irq,
+ mxc_epdc_irq_handler, 0, "epdc", fb_data);
+ if (ret) {
+ dev_err(&pdev->dev, "request_irq (%d) failed with error %d\n",
+ fb_data->epdc_irq, ret);
+ ret = -ENODEV;
+ goto out_dma_work_buf;
+ }
+
+ info->fbdefio = &mxc_epdc_fb_defio;
+#ifdef CONFIG_FB_MXC_EINK_AUTO_UPDATE_MODE
+ fb_deferred_io_init(info);
+#endif
+
+ /* get pmic regulators */
+ fb_data->display_regulator = devm_regulator_get(&pdev->dev, "DISPLAY");
+ if (IS_ERR(fb_data->display_regulator)) {
+ dev_err(&pdev->dev, "Unable to get display PMIC regulator."
+ "err = 0x%x\n", (int)fb_data->display_regulator);
+ ret = -ENODEV;
+ goto out_dma_work_buf;
+ }
+ fb_data->vcom_regulator = devm_regulator_get(&pdev->dev, "VCOM");
+ if (IS_ERR(fb_data->vcom_regulator)) {
+ dev_err(&pdev->dev, "Unable to get VCOM regulator."
+ "err = 0x%x\n", (int)fb_data->vcom_regulator);
+ ret = -ENODEV;
+ goto out_dma_work_buf;
+ }
+ fb_data->v3p3_regulator = devm_regulator_get(&pdev->dev, "V3P3");
+ if (IS_ERR(fb_data->v3p3_regulator)) {
+ dev_err(&pdev->dev, "Unable to get V3P3 regulator."
+ "err = 0x%x\n", (int)fb_data->vcom_regulator);
+ ret = -ENODEV;
+ goto out_dma_work_buf;
+ }
+
+ if (device_create_file(info->dev, &fb_attrs[0]))
+ dev_err(&pdev->dev, "Unable to create file from fb_attrs\n");
+
+ fb_data->cur_update = NULL;
+
+ mutex_init(&fb_data->queue_mutex);
+ mutex_init(&fb_data->pxp_mutex);
+ mutex_init(&fb_data->power_mutex);
+
+ /*
+ * Fill out PxP config data structure based on FB info and
+ * processing tasks required
+ */
+ pxp_conf = &fb_data->pxp_conf;
+ proc_data = &pxp_conf->proc_data;
+
+ /* Initialize non-channel-specific PxP parameters */
+ proc_data->drect.left = proc_data->srect.left = 0;
+ proc_data->drect.top = proc_data->srect.top = 0;
+ proc_data->drect.width = proc_data->srect.width = fb_data->info.var.xres;
+ proc_data->drect.height = proc_data->srect.height = fb_data->info.var.yres;
+ proc_data->scaling = 0;
+ proc_data->hflip = 0;
+ proc_data->vflip = 0;
+ proc_data->rotate = 0;
+ proc_data->bgcolor = 0;
+ proc_data->overlay_state = 0;
+ proc_data->lut_transform = PXP_LUT_NONE;
+ proc_data->lut_map = NULL;
+
+ /*
+ * We initially configure PxP for RGB->YUV conversion,
+ * and only write out Y component of the result.
+ */
+
+ /*
+ * Initialize S0 channel parameters
+ * Parameters should match FB format/width/height
+ */
+ pxp_conf->s0_param.pixel_fmt = PXP_PIX_FMT_RGB565;
+ pxp_conf->s0_param.width = fb_data->info.var.xres_virtual;
+ pxp_conf->s0_param.stride = (var_info->bits_per_pixel * pxp_conf->s0_param.width) >> 3;
+ pxp_conf->s0_param.height = fb_data->info.var.yres;
+ pxp_conf->s0_param.color_key = -1;
+ pxp_conf->s0_param.color_key_enable = false;
+
+ /*
+ * Initialize OL0 channel parameters
+ * No overlay will be used for PxP operation
+ */
+ pxp_conf->ol_param[0].combine_enable = false;
+ pxp_conf->ol_param[0].width = 0;
+ pxp_conf->ol_param[0].height = 0;
+ pxp_conf->ol_param[0].pixel_fmt = PXP_PIX_FMT_RGB565;
+ pxp_conf->ol_param[0].color_key_enable = false;
+ pxp_conf->ol_param[0].color_key = -1;
+ pxp_conf->ol_param[0].global_alpha_enable = false;
+ pxp_conf->ol_param[0].global_alpha = 0;
+ pxp_conf->ol_param[0].local_alpha_enable = false;
+
+ /*
+ * Initialize Output channel parameters
+ * Output is Y-only greyscale
+ * Output width/height will vary based on update region size
+ */
+ pxp_conf->out_param.width = fb_data->info.var.xres;
+ pxp_conf->out_param.height = fb_data->info.var.yres;
+ pxp_conf->out_param.stride = pxp_conf->out_param.width;
+ pxp_conf->out_param.pixel_fmt = PXP_PIX_FMT_GREY;
+
+ /* Initialize color map for conversion of 8-bit gray pixels */
+ fb_data->pxp_conf.proc_data.lut_map = kmalloc(256, GFP_KERNEL);
+ if (fb_data->pxp_conf.proc_data.lut_map == NULL) {
+ dev_err(&pdev->dev, "Can't allocate mem for lut map!\n");
+ ret = -ENOMEM;
+ goto out_dma_work_buf;
+ }
+ for (i = 0; i < 256; i++)
+ fb_data->pxp_conf.proc_data.lut_map[i] = i;
+
+ fb_data->pxp_conf.proc_data.lut_map_updated = true;
+
+ /*
+ * Ensure this is set to NULL here...we will initialize pxp_chan
+ * later in our thread.
+ */
+ fb_data->pxp_chan = NULL;
+
+ /* Initialize Scatter-gather list containing 2 buffer addresses. */
+ sg = fb_data->sg;
+ sg_init_table(sg, SG_NUM);
+
+ /*
+ * For use in PxP transfers:
+ * sg[0] holds the FB buffer pointer
+ * sg[1] holds the Output buffer pointer (configured before TX request)
+ */
+ sg_dma_address(&sg[0]) = info->fix.smem_start;
+ sg_set_page(&sg[0], virt_to_page(info->screen_base),
+ info->fix.smem_len, offset_in_page(info->screen_base));
+
+ fb_data->order_cnt = 0;
+ fb_data->waiting_for_wb = false;
+ fb_data->waiting_for_lut = false;
+ fb_data->waiting_for_lut15 = false;
+ fb_data->waiting_for_idle = false;
+ fb_data->blank = FB_BLANK_UNBLANK;
+ fb_data->power_state = POWER_STATE_OFF;
+ fb_data->powering_down = false;
+ fb_data->wait_for_powerdown = false;
+ fb_data->updates_active = false;
+ fb_data->pwrdown_delay = 0;
+
+ /* Register FB */
+ ret = register_framebuffer(info);
+ if (ret) {
+ dev_err(&pdev->dev,
+ "register_framebuffer failed with error %d\n", ret);
+ goto out_lutmap;
+ }
+
+ g_fb_data = fb_data;
+
+ pm_runtime_enable(fb_data->dev);
+
+#ifdef DEFAULT_PANEL_HW_INIT
+ ret = mxc_epdc_fb_init_hw((struct fb_info *)fb_data);
+ if (ret) {
+ dev_err(&pdev->dev, "Failed to initialize HW!\n");
+ }
+#endif
+
+ goto out;
+
+out_lutmap:
+ kfree(fb_data->pxp_conf.proc_data.lut_map);
+out_dma_work_buf:
+ dma_free_writecombine(&pdev->dev, fb_data->working_buffer_size,
+ fb_data->working_buffer_virt, fb_data->working_buffer_phys);
+out_copybuffer:
+ dma_free_writecombine(&pdev->dev, fb_data->max_pix_size*2,
+ fb_data->virt_addr_copybuf,
+ fb_data->phys_addr_copybuf);
+out_upd_buffers:
+ for (i = 0; i < fb_data->max_num_buffers; i++)
+ if (fb_data->virt_addr_updbuf[i] != NULL)
+ kfree(fb_data->virt_addr_updbuf[i]);
+ if (fb_data->virt_addr_updbuf != NULL)
+ kfree(fb_data->virt_addr_updbuf);
+ if (fb_data->phys_addr_updbuf != NULL)
+ kfree(fb_data->phys_addr_updbuf);
+out_upd_lists:
+ list_for_each_entry_safe(plist, temp_list, &fb_data->upd_buf_free_list,
+ list) {
+ list_del(&plist->list);
+ kfree(plist);
+ }
+out_dma_fb:
+ dma_free_writecombine(&pdev->dev, fb_data->map_size, info->screen_base,
+ fb_data->phys_start);
+
+out_cmap:
+ fb_dealloc_cmap(&info->cmap);
+out_fbdata:
+ kfree(fb_data);
+out:
+ return ret;
+}
+
+static int mxc_epdc_fb_remove(struct platform_device *pdev)
+{
+ struct update_data_list *plist, *temp_list;
+ struct mxc_epdc_fb_data *fb_data = platform_get_drvdata(pdev);
+ int i;
+
+ mxc_epdc_fb_blank(FB_BLANK_POWERDOWN, &fb_data->info);
+
+ flush_workqueue(fb_data->epdc_submit_workqueue);
+ destroy_workqueue(fb_data->epdc_submit_workqueue);
+
+ unregister_framebuffer(&fb_data->info);
+
+ for (i = 0; i < fb_data->max_num_buffers; i++)
+ if (fb_data->virt_addr_updbuf[i] != NULL)
+ kfree(fb_data->virt_addr_updbuf[i]);
+ if (fb_data->virt_addr_updbuf != NULL)
+ kfree(fb_data->virt_addr_updbuf);
+ if (fb_data->phys_addr_updbuf != NULL)
+ kfree(fb_data->phys_addr_updbuf);
+
+ dma_free_writecombine(&pdev->dev, fb_data->working_buffer_size,
+ fb_data->working_buffer_virt,
+ fb_data->working_buffer_phys);
+ if (fb_data->waveform_buffer_virt != NULL)
+ dma_free_writecombine(&pdev->dev, fb_data->waveform_buffer_size,
+ fb_data->waveform_buffer_virt,
+ fb_data->waveform_buffer_phys);
+ if (fb_data->virt_addr_copybuf != NULL)
+ dma_free_writecombine(&pdev->dev, fb_data->max_pix_size*2,
+ fb_data->virt_addr_copybuf,
+ fb_data->phys_addr_copybuf);
+ list_for_each_entry_safe(plist, temp_list, &fb_data->upd_buf_free_list,
+ list) {
+ list_del(&plist->list);
+ kfree(plist);
+ }
+#ifdef CONFIG_FB_MXC_EINK_AUTO_UPDATE_MODE
+ fb_deferred_io_cleanup(&fb_data->info);
+#endif
+
+ dma_free_writecombine(&pdev->dev, fb_data->map_size, fb_data->info.screen_base,
+ fb_data->phys_start);
+
+ /* Release PxP-related resources */
+ if (fb_data->pxp_chan != NULL)
+ dma_release_channel(&fb_data->pxp_chan->dma_chan);
+
+ fb_dealloc_cmap(&fb_data->info.cmap);
+
+ framebuffer_release(&fb_data->info);
+ if (!IS_ERR_OR_NULL(fb_data->gpr))
+ regmap_update_bits(fb_data->gpr, fb_data->req_gpr,
+ 1 << fb_data->req_bit, 1 << fb_data->req_bit);
+ platform_set_drvdata(pdev, NULL);
+
+ return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int mxc_epdc_fb_suspend(struct device *dev)
+{
+ struct mxc_epdc_fb_data *data = dev_get_drvdata(dev);
+ int ret;
+
+ data->pwrdown_delay = FB_POWERDOWN_DISABLE;
+ ret = mxc_epdc_fb_blank(FB_BLANK_POWERDOWN, &data->info);
+
+ if (ret)
+ goto out;
+
+out:
+ pinctrl_pm_select_sleep_state(dev);
+
+ return ret;
+}
+
+static void mxc_epdc_restore_qos(struct mxc_epdc_fb_data *data)
+{
+ if (IS_ERR_OR_NULL(data->qos_regmap)) {
+ dev_dbg(data->dev, "no QoS setting found.\n");
+ return;
+ }
+
+#define QOS_EPDC_OFFSET 0x3400
+#define QOS_PXP0_OFFSET 0x2C00
+#define QOS_PXP1_OFFSET 0x3C00
+ regmap_write(data->qos_regmap, 0, 0);
+ regmap_write(data->qos_regmap, 0x60, 0);
+ regmap_write(data->qos_regmap, QOS_EPDC_OFFSET, 0);
+ regmap_write(data->qos_regmap, QOS_PXP0_OFFSET, 0);
+ regmap_write(data->qos_regmap, QOS_PXP1_OFFSET, 0);
+
+ regmap_write(data->qos_regmap, QOS_EPDC_OFFSET + 0xd0, 0x0f020722);
+ regmap_write(data->qos_regmap, QOS_EPDC_OFFSET + 0xe0, 0x0f020722);
+
+ regmap_write(data->qos_regmap, QOS_PXP0_OFFSET, 1);
+ regmap_write(data->qos_regmap, QOS_PXP1_OFFSET, 1);
+
+ regmap_write(data->qos_regmap, QOS_PXP0_OFFSET + 0x50, 0x0f020222);
+ regmap_write(data->qos_regmap, QOS_PXP1_OFFSET + 0x50, 0x0f020222);
+ regmap_write(data->qos_regmap, QOS_PXP0_OFFSET + 0x60, 0x0f020222);
+ regmap_write(data->qos_regmap, QOS_PXP1_OFFSET + 0x60, 0x0f020222);
+ regmap_write(data->qos_regmap, QOS_PXP0_OFFSET + 0x70, 0x0f020422);
+ regmap_write(data->qos_regmap, QOS_PXP1_OFFSET + 0x70, 0x0f020422);
+
+ if (!IS_ERR_OR_NULL(data->gpr))
+ regmap_update_bits(data->gpr, 0x34, 0xe080, 0xe080);
+}
+
+static int mxc_epdc_fb_resume(struct device *dev)
+{
+ struct mxc_epdc_fb_data *data = dev_get_drvdata(dev);
+
+ pinctrl_pm_select_default_state(dev);
+
+ mxc_epdc_restore_qos(data);
+
+ mxc_epdc_fb_blank(FB_BLANK_UNBLANK, &data->info);
+ epdc_init_settings(data);
+ data->updates_active = false;
+
+ return 0;
+}
+#else
+#define mxc_epdc_fb_suspend NULL
+#define mxc_epdc_fb_resume NULL
+#endif
+
+#ifdef CONFIG_PM
+static int mxc_epdc_fb_runtime_suspend(struct device *dev)
+{
+ release_bus_freq(BUS_FREQ_HIGH);
+ dev_dbg(dev, "epdc busfreq high release.\n");
+
+ return 0;
+}
+
+static int mxc_epdc_fb_runtime_resume(struct device *dev)
+{
+ request_bus_freq(BUS_FREQ_HIGH);
+ dev_dbg(dev, "epdc busfreq high request.\n");
+
+ return 0;
+}
+#else
+#define mxc_epdc_fb_runtime_suspend NULL
+#define mxc_epdc_fb_runtime_resume NULL
+#endif
+
+static const struct dev_pm_ops mxc_epdc_fb_pm_ops = {
+ SET_RUNTIME_PM_OPS(mxc_epdc_fb_runtime_suspend,
+ mxc_epdc_fb_runtime_resume, NULL)
+ SET_SYSTEM_SLEEP_PM_OPS(mxc_epdc_fb_suspend, mxc_epdc_fb_resume)
+};
+
+static void mxc_epdc_fb_shutdown(struct platform_device *pdev)
+{
+ struct mxc_epdc_fb_data *fb_data = platform_get_drvdata(pdev);
+
+ /* Disable power to the EPD panel */
+ if (regulator_is_enabled(fb_data->vcom_regulator))
+ regulator_disable(fb_data->vcom_regulator);
+ if (regulator_is_enabled(fb_data->display_regulator))
+ regulator_disable(fb_data->display_regulator);
+
+ /* Disable clocks to EPDC */
+ clk_prepare_enable(fb_data->epdc_clk_axi);
+ clk_prepare_enable(fb_data->epdc_clk_pix);
+ __raw_writel(EPDC_CTRL_CLKGATE, EPDC_CTRL_SET);
+ clk_disable_unprepare(fb_data->epdc_clk_pix);
+ clk_disable_unprepare(fb_data->epdc_clk_axi);
+
+ /* turn off the V3p3 */
+ if (regulator_is_enabled(fb_data->v3p3_regulator))
+ regulator_disable(fb_data->v3p3_regulator);
+}
+
+static struct platform_driver mxc_epdc_fb_driver = {
+ .probe = mxc_epdc_fb_probe,
+ .remove = mxc_epdc_fb_remove,
+ .shutdown = mxc_epdc_fb_shutdown,
+ .driver = {
+ .name = "imx_epdc_v2_fb",
+ .owner = THIS_MODULE,
+ .of_match_table = of_match_ptr(imx_epdc_dt_ids),
+ .pm = &mxc_epdc_fb_pm_ops,
+ },
+};
+
+/* Callback function triggered after PxP receives an EOF interrupt */
+static void pxp_dma_done(void *arg)
+{
+ struct pxp_tx_desc *tx_desc = to_tx_desc(arg);
+ struct dma_chan *chan = tx_desc->txd.chan;
+ struct pxp_channel *pxp_chan = to_pxp_channel(chan);
+ struct mxc_epdc_fb_data *fb_data = pxp_chan->client;
+
+ /*
+ * if epd works in external mode, we should queue epdc_intr_workqueue
+ * after a wfe_a process finishes.
+ */
+ if (fb_data->epdc_wb_mode && (tx_desc->proc_data.engine_enable & PXP_ENABLE_WFE_A)) {
+ pxp_get_collision_info(&fb_data->col_info);
+ queue_work(fb_data->epdc_intr_workqueue,
+ &fb_data->epdc_intr_work);
+ }
+
+ /* This call will signal wait_for_completion_timeout() in send_buffer_to_pxp */
+ complete(&fb_data->pxp_tx_cmpl);
+}
+
+static bool chan_filter(struct dma_chan *chan, void *arg)
+{
+ if (imx_dma_is_pxp(chan))
+ return true;
+ else
+ return false;
+}
+
+/* Function to request PXP DMA channel */
+static int pxp_chan_init(struct mxc_epdc_fb_data *fb_data)
+{
+ dma_cap_mask_t mask;
+ struct dma_chan *chan;
+
+ /*
+ * Request a free channel
+ */
+ dma_cap_zero(mask);
+ dma_cap_set(DMA_SLAVE, mask);
+ dma_cap_set(DMA_PRIVATE, mask);
+ chan = dma_request_channel(mask, chan_filter, NULL);
+ if (!chan) {
+ dev_err(fb_data->dev, "Unsuccessfully received channel!!!!\n");
+ return -EBUSY;
+ }
+
+ fb_data->pxp_chan = to_pxp_channel(chan);
+ fb_data->pxp_chan->client = fb_data;
+
+ init_completion(&fb_data->pxp_tx_cmpl);
+
+ return 0;
+}
+
+static int pxp_wfe_a_process_clear_workingbuffer(struct mxc_epdc_fb_data *fb_data,
+ u32 panel_width, u32 panel_height)
+{
+ dma_cookie_t cookie;
+ struct scatterlist *sg = fb_data->sg;
+ struct dma_chan *dma_chan;
+ struct pxp_tx_desc *desc;
+ struct dma_async_tx_descriptor *txd;
+ struct pxp_config_data *pxp_conf = &fb_data->pxp_conf;
+ struct pxp_proc_data *proc_data = &fb_data->pxp_conf.proc_data;
+ int i, j = 0, ret;
+ int length;
+
+ dev_dbg(fb_data->dev, "Starting PxP WFE_A process for clearing WB.\n");
+
+ /* First, check to see that we have acquired a PxP Channel object */
+ if (fb_data->pxp_chan == NULL) {
+ /*
+ * PxP Channel has not yet been created and initialized,
+ * so let's go ahead and try
+ */
+ ret = pxp_chan_init(fb_data);
+ if (ret) {
+ /*
+ * PxP channel init failed, and we can't use the
+ * PxP until the PxP DMA driver has loaded, so we abort
+ */
+ dev_err(fb_data->dev, "PxP chan init failed\n");
+ return -ENODEV;
+ }
+ }
+
+ /*
+ * Init completion, so that we
+ * can be properly informed of the completion
+ * of the PxP task when it is done.
+ */
+ init_completion(&fb_data->pxp_tx_cmpl);
+
+ dma_chan = &fb_data->pxp_chan->dma_chan;
+
+ txd = dma_chan->device->device_prep_slave_sg(dma_chan, sg, 2 + 4,
+ DMA_TO_DEVICE,
+ DMA_PREP_INTERRUPT,
+ NULL);
+ if (!txd) {
+ dev_err(fb_data->info.device,
+ "Error preparing a DMA transaction descriptor.\n");
+ return -EIO;
+ }
+
+ txd->callback_param = txd;
+ txd->callback = pxp_dma_done;
+
+ proc_data->working_mode = PXP_MODE_STANDARD;
+ proc_data->engine_enable = PXP_ENABLE_WFE_A;
+ proc_data->lut = 0;
+ proc_data->detection_only = 0;
+ proc_data->reagl_en = 0;
+ proc_data->partial_update = 0;
+ proc_data->alpha_en = 1;
+ proc_data->lut_sels = fb_data->luts_complete;
+ proc_data->lut_cleanup = 1;
+
+ pxp_conf->wfe_a_fetch_param[0].stride = panel_width;
+ pxp_conf->wfe_a_fetch_param[0].width = panel_width;
+ pxp_conf->wfe_a_fetch_param[0].height = panel_height;
+ pxp_conf->wfe_a_fetch_param[0].paddr = fb_data->phys_addr_black;
+ pxp_conf->wfe_a_fetch_param[1].stride = panel_width;
+ pxp_conf->wfe_a_fetch_param[1].width = panel_width;
+ pxp_conf->wfe_a_fetch_param[1].height = panel_height;
+ pxp_conf->wfe_a_fetch_param[1].paddr = fb_data->working_buffer_phys;
+ pxp_conf->wfe_a_fetch_param[0].left = 0;
+ pxp_conf->wfe_a_fetch_param[0].top = 0;
+ pxp_conf->wfe_a_fetch_param[1].left = 0;
+ pxp_conf->wfe_a_fetch_param[1].top = 0;
+
+ pxp_conf->wfe_a_store_param[0].stride = panel_width;
+ pxp_conf->wfe_a_store_param[0].width = panel_width;
+ pxp_conf->wfe_a_store_param[0].height = panel_height;
+ pxp_conf->wfe_a_store_param[0].paddr = fb_data->phys_addr_y4c;
+ pxp_conf->wfe_a_store_param[1].stride = panel_width;
+ pxp_conf->wfe_a_store_param[1].width = panel_width;
+ pxp_conf->wfe_a_store_param[1].height = panel_height;
+ pxp_conf->wfe_a_store_param[1].paddr = fb_data->working_buffer_phys;
+ pxp_conf->wfe_a_store_param[0].left = 0;
+ pxp_conf->wfe_a_store_param[0].top = 0;
+ pxp_conf->wfe_a_store_param[1].left = 0;
+ pxp_conf->wfe_a_store_param[1].top = 0;
+
+ desc = to_tx_desc(txd);
+ length = desc->len;
+
+ memcpy(&desc->proc_data, proc_data, sizeof(struct pxp_proc_data));
+ for (i = 0; i < length; i++) {
+ if (i == 0 || i == 1) {/* wfe_a won't use s0 or output at all */
+ desc = desc->next;
+
+ } else if ((pxp_conf->proc_data.engine_enable & PXP_ENABLE_WFE_A) && (j < 4)) {
+ for (j = 0; j < 4; j++) {
+ if (j == 0) {
+ memcpy(&desc->layer_param.processing_param,
+ &pxp_conf->wfe_a_fetch_param[0],
+ sizeof(struct pxp_layer_param));
+ desc->layer_param.processing_param.flag = PXP_BUF_FLAG_WFE_A_FETCH0;
+ } else if (j == 1) {
+ memcpy(&desc->layer_param.processing_param,
+ &pxp_conf->wfe_a_fetch_param[1],
+ sizeof(struct pxp_layer_param));
+ desc->layer_param.processing_param.flag = PXP_BUF_FLAG_WFE_A_FETCH1;
+ } else if (j == 2) {
+ memcpy(&desc->layer_param.processing_param,
+ &pxp_conf->wfe_a_store_param[0],
+ sizeof(struct pxp_layer_param));
+ desc->layer_param.processing_param.flag = PXP_BUF_FLAG_WFE_A_STORE0;
+ } else if (j == 3) {
+ memcpy(&desc->layer_param.processing_param,
+ &pxp_conf->wfe_a_store_param[1],
+ sizeof(struct pxp_layer_param));
+ desc->layer_param.processing_param.flag = PXP_BUF_FLAG_WFE_A_STORE1;
+ }
+
+ desc = desc->next;
+ }
+
+ i += 4;
+ }
+ }
+
+ /* Submitting our TX starts the PxP processing task */
+ cookie = txd->tx_submit(txd);
+ if (cookie < 0) {
+ dev_err(fb_data->info.device, "Error sending FB through PxP\n");
+ return -EIO;
+ }
+
+ fb_data->txd = txd;
+
+ /* trigger ePxP */
+ dma_async_issue_pending(dma_chan);
+
+ return 0;
+}
+
+static int pxp_clear_wb_work_func(struct mxc_epdc_fb_data *fb_data)
+{
+ unsigned int hist_stat;
+ int ret;
+
+ dev_dbg(fb_data->dev, "PxP WFE to clear working buffer.\n");
+
+ mutex_lock(&fb_data->pxp_mutex);
+ ret = pxp_wfe_a_process_clear_workingbuffer(fb_data, fb_data->cur_mode->vmode->xres, fb_data->cur_mode->vmode->yres);
+ if (ret) {
+ dev_err(fb_data->dev, "Unable to submit PxP update task.\n");
+ mutex_unlock(&fb_data->pxp_mutex);
+ return ret;
+ }
+ mutex_unlock(&fb_data->pxp_mutex);
+
+ /* If needed, enable EPDC HW while ePxP is processing */
+ if ((fb_data->power_state == POWER_STATE_OFF)
+ || fb_data->powering_down) {
+ epdc_powerup(fb_data);
+ }
+
+ /* This is a blocking call, so upon return PxP tx should be done */
+ ret = pxp_complete_update(fb_data, &hist_stat);
+ if (ret) {
+ dev_err(fb_data->dev, "Unable to complete PxP update task: clear wb process\n");
+ mutex_unlock(&fb_data->pxp_mutex);
+ return ret;
+ }
+
+ return 0;
+}
+
+
+/* PS_AS_OUT */
+static int pxp_legacy_process(struct mxc_epdc_fb_data *fb_data,
+ u32 src_width, u32 src_height,
+ struct mxcfb_rect *update_region)
+{
+ dma_cookie_t cookie;
+ struct scatterlist *sg = fb_data->sg;
+ struct dma_chan *dma_chan;
+ struct pxp_tx_desc *desc;
+ struct dma_async_tx_descriptor *txd;
+ struct pxp_config_data *pxp_conf = &fb_data->pxp_conf;
+ struct pxp_proc_data *proc_data = &fb_data->pxp_conf.proc_data;
+ struct fb_var_screeninfo *screeninfo = &fb_data->info.var;
+ int i, ret;
+ int length;
+
+ dev_dbg(fb_data->dev, "Starting PxP legacy process.\n");
+
+ /* First, check to see that we have acquired a PxP Channel object */
+ if (fb_data->pxp_chan == NULL) {
+ /*
+ * PxP Channel has not yet been created and initialized,
+ * so let's go ahead and try
+ */
+ ret = pxp_chan_init(fb_data);
+ if (ret) {
+ /*
+ * PxP channel init failed, and we can't use the
+ * PxP until the PxP DMA driver has loaded, so we abort
+ */
+ dev_err(fb_data->dev, "PxP chan init failed\n");
+ return -ENODEV;
+ }
+ }
+
+ /*
+ * Init completion, so that we
+ * can be properly informed of the completion
+ * of the PxP task when it is done.
+ */
+ init_completion(&fb_data->pxp_tx_cmpl);
+
+ dma_chan = &fb_data->pxp_chan->dma_chan;
+
+ txd = dma_chan->device->device_prep_slave_sg(dma_chan, sg, 2,
+ DMA_TO_DEVICE,
+ DMA_PREP_INTERRUPT,
+ NULL);
+ if (!txd) {
+ dev_err(fb_data->info.device,
+ "Error preparing a DMA transaction descriptor.\n");
+ return -EIO;
+ }
+
+ txd->callback_param = txd;
+ txd->callback = pxp_dma_done;
+
+ proc_data->working_mode = PXP_MODE_LEGACY;
+ proc_data->engine_enable = PXP_ENABLE_PS_AS_OUT;
+
+ /*
+ * Configure PxP for processing of new update region
+ * The rest of our config params were set up in
+ * probe() and should not need to be changed.
+ */
+ pxp_conf->s0_param.width = src_width;
+ pxp_conf->s0_param.stride = (screeninfo->bits_per_pixel * src_width) >> 3;
+ pxp_conf->s0_param.height = src_height;
+ proc_data->srect.top = update_region->top;
+ proc_data->srect.left = update_region->left;
+ proc_data->srect.width = update_region->width;
+ proc_data->srect.height = update_region->height;
+ proc_data->lut_cleanup = 0;
+
+ /*
+ * Because only YUV/YCbCr image can be scaled, configure
+ * drect equivalent to srect, as such do not perform scaling.
+ */
+ proc_data->drect.top = 0;
+ proc_data->drect.left = 0;
+
+ /* PXP expects rotation in terms of degrees */
+ proc_data->rotate = fb_data->epdc_fb_var.rotate * 90;
+ if (proc_data->rotate > 270)
+ proc_data->rotate = 0;
+
+ /* we should pass the rotated values to PXP */
+ if ((proc_data->rotate == 90) || (proc_data->rotate == 270)) {
+ proc_data->drect.width = proc_data->srect.height;
+ proc_data->drect.height = proc_data->srect.width;
+ pxp_conf->out_param.width = update_region->height;
+ pxp_conf->out_param.height = update_region->width;
+ pxp_conf->out_param.stride = update_region->height;
+ } else {
+ proc_data->drect.width = proc_data->srect.width;
+ proc_data->drect.height = proc_data->srect.height;
+ pxp_conf->out_param.width = update_region->width;
+ pxp_conf->out_param.height = update_region->height;
+ pxp_conf->out_param.stride = update_region->width;
+ }
+
+ /* For EPDC v2.0, we need output to be 64-bit
+ * aligned since EPDC stride does not work. */
+ if (fb_data->rev <= 20)
+ pxp_conf->out_param.stride = ALIGN(pxp_conf->out_param.stride, 8);
+
+ desc = to_tx_desc(txd);
+ length = desc->len;
+
+ for (i = 0; i < length; i++) {
+ if (i == 0) {/* S0 */
+ memcpy(&desc->proc_data, proc_data, sizeof(struct pxp_proc_data));
+ pxp_conf->s0_param.paddr = sg_dma_address(&sg[0]);
+ memcpy(&desc->layer_param.s0_param, &pxp_conf->s0_param,
+ sizeof(struct pxp_layer_param));
+ desc = desc->next;
+
+ } else if (i == 1) {
+ pxp_conf->out_param.paddr = sg_dma_address(&sg[1]);
+ memcpy(&desc->layer_param.out_param, &pxp_conf->out_param,
+ sizeof(struct pxp_layer_param));
+ desc = desc->next;
+ }
+ }
+
+ /* Submitting our TX starts the PxP processing task */
+ cookie = txd->tx_submit(txd);
+ if (cookie < 0) {
+ dev_err(fb_data->info.device, "Error sending FB through PxP\n");
+ return -EIO;
+ }
+
+ fb_data->txd = txd;
+
+ /* trigger ePxP */
+ dma_async_issue_pending(dma_chan);
+
+ return 0;
+}
+
+static int pxp_process_dithering(struct mxc_epdc_fb_data *fb_data,
+ struct mxcfb_rect *update_region)
+{
+ dma_cookie_t cookie;
+ struct scatterlist *sg = fb_data->sg;
+ struct dma_chan *dma_chan;
+ struct pxp_tx_desc *desc;
+ struct dma_async_tx_descriptor *txd;
+ struct pxp_config_data *pxp_conf = &fb_data->pxp_conf;
+ struct pxp_proc_data *proc_data = &fb_data->pxp_conf.proc_data;
+ int i, j = 0, ret;
+ int length;
+
+ dev_dbg(fb_data->dev, "Starting PxP Dithering process.\n");
+
+ /* First, check to see that we have acquired a PxP Channel object */
+ if (fb_data->pxp_chan == NULL) {
+ /*
+ * PxP Channel has not yet been created and initialized,
+ * so let's go ahead and try
+ */
+ ret = pxp_chan_init(fb_data);
+ if (ret) {
+ /*
+ * PxP channel init failed, and we can't use the
+ * PxP until the PxP DMA driver has loaded, so we abort
+ */
+ dev_err(fb_data->dev, "PxP chan init failed\n");
+ return -ENODEV;
+ }
+ }
+
+ /*
+ * Init completion, so that we
+ * can be properly informed of the completion
+ * of the PxP task when it is done.
+ */
+ init_completion(&fb_data->pxp_tx_cmpl);
+
+ dma_chan = &fb_data->pxp_chan->dma_chan;
+
+ txd = dma_chan->device->device_prep_slave_sg(dma_chan, sg, 2 + 4,
+ DMA_TO_DEVICE,
+ DMA_PREP_INTERRUPT,
+ NULL);
+ if (!txd) {
+ dev_err(fb_data->info.device,
+ "Error preparing a DMA transaction descriptor.\n");
+ return -EIO;
+ }
+
+ txd->callback_param = txd;
+ txd->callback = pxp_dma_done;
+
+ proc_data->working_mode = PXP_MODE_STANDARD;
+ proc_data->engine_enable = PXP_ENABLE_DITHER;
+
+ pxp_conf->dither_fetch_param[0].stride = update_region->width;
+ pxp_conf->dither_fetch_param[0].width = update_region->width;
+ pxp_conf->dither_fetch_param[0].height = update_region->height;
+#ifdef USE_PS_AS_OUTPUT
+ pxp_conf->dither_fetch_param[0].paddr = sg_dma_address(&sg[1]);
+#else
+ pxp_conf->dither_fetch_param[0].paddr = sg_dma_address(&sg[0]);
+#endif
+ pxp_conf->dither_fetch_param[1].stride = update_region->width;
+ pxp_conf->dither_fetch_param[1].width = update_region->width;
+ pxp_conf->dither_fetch_param[1].height = update_region->height;
+ pxp_conf->dither_fetch_param[1].paddr = pxp_conf->dither_fetch_param[0].paddr;
+
+ pxp_conf->dither_store_param[0].stride = update_region->width;
+ pxp_conf->dither_store_param[0].width = update_region->width;
+ pxp_conf->dither_store_param[0].height = update_region->height;
+ pxp_conf->dither_store_param[0].paddr = fb_data->phys_addr_y4;
+ pxp_conf->dither_store_param[1].stride = update_region->width;
+ pxp_conf->dither_store_param[1].width = update_region->width;
+ pxp_conf->dither_store_param[1].height = update_region->height;
+ pxp_conf->dither_store_param[1].paddr = pxp_conf->dither_store_param[0].paddr;
+
+ desc = to_tx_desc(txd);
+ length = desc->len;
+
+ for (i = 0; i < length; i++) {
+ if (i == 0) {/* S0 */
+ memcpy(&desc->proc_data, proc_data, sizeof(struct pxp_proc_data));
+ pxp_conf->s0_param.paddr = sg_dma_address(&sg[0]);
+ memcpy(&desc->layer_param.s0_param, &pxp_conf->s0_param,
+ sizeof(struct pxp_layer_param));
+ desc = desc->next;
+ } else if (i == 1) {
+ pxp_conf->out_param.paddr = sg_dma_address(&sg[1]);
+ memcpy(&desc->layer_param.out_param, &pxp_conf->out_param,
+ sizeof(struct pxp_layer_param));
+ desc = desc->next;
+ } else if ((pxp_conf->proc_data.engine_enable & PXP_ENABLE_DITHER) && (j < 4)) {
+ for (j = 0; j < 4; j++) {
+ if (j == 0) {
+ memcpy(&desc->layer_param.processing_param,
+ &pxp_conf->dither_fetch_param[0],
+ sizeof(struct pxp_layer_param));
+ desc->layer_param.processing_param.flag = PXP_BUF_FLAG_DITHER_FETCH0;
+ } else if (j == 1) {
+ memcpy(&desc->layer_param.processing_param,
+ &pxp_conf->dither_fetch_param[1],
+ sizeof(struct pxp_layer_param));
+ desc->layer_param.processing_param.flag = PXP_BUF_FLAG_DITHER_FETCH1;
+ } else if (j == 2) {
+ memcpy(&desc->layer_param.processing_param,
+ &pxp_conf->dither_store_param[0],
+ sizeof(struct pxp_layer_param));
+ desc->layer_param.processing_param.flag = PXP_BUF_FLAG_DITHER_STORE0;
+ } else if (j == 3) {
+ memcpy(&desc->layer_param.processing_param,
+ &pxp_conf->dither_store_param[1],
+ sizeof(struct pxp_layer_param));
+ desc->layer_param.processing_param.flag = PXP_BUF_FLAG_DITHER_STORE1;
+ }
+
+ desc = desc->next;
+ }
+
+ i += 4;
+ }
+ }
+
+ /* Submitting our TX starts the PxP processing task */
+ cookie = txd->tx_submit(txd);
+ if (cookie < 0) {
+ dev_err(fb_data->info.device, "Error sending FB through PxP\n");
+ return -EIO;
+ }
+
+ fb_data->txd = txd;
+
+ /* trigger ePxP */
+ dma_async_issue_pending(dma_chan);
+
+ return 0;
+}
+
+/*
+ * Function to call PxP DMA driver and send our latest FB update region
+ * through the PxP and out to an intermediate buffer.
+ * Note: This is a blocking call, so upon return the PxP tx should be complete.
+ */
+static int pxp_wfe_a_process(struct mxc_epdc_fb_data *fb_data,
+ struct mxcfb_rect *update_region,
+ struct update_data_list *upd_data_list)
+{
+ dma_cookie_t cookie;
+ struct scatterlist *sg = fb_data->sg;
+ struct dma_chan *dma_chan;
+ struct pxp_tx_desc *desc;
+ struct dma_async_tx_descriptor *txd;
+ struct pxp_config_data *pxp_conf = &fb_data->pxp_conf;
+ struct pxp_proc_data *proc_data = &fb_data->pxp_conf.proc_data;
+ u32 wv_mode = upd_data_list->update_desc->upd_data.waveform_mode;
+ int i, j = 0, ret;
+ int length;
+ bool is_transform;
+
+ dev_dbg(fb_data->dev, "Starting PxP WFE_A process.\n");
+
+ /* First, check to see that we have acquired a PxP Channel object */
+ if (fb_data->pxp_chan == NULL) {
+ /*
+ * PxP Channel has not yet been created and initialized,
+ * so let's go ahead and try
+ */
+ ret = pxp_chan_init(fb_data);
+ if (ret) {
+ /*
+ * PxP channel init failed, and we can't use the
+ * PxP until the PxP DMA driver has loaded, so we abort
+ */
+ dev_err(fb_data->dev, "PxP chan init failed\n");
+ return -ENODEV;
+ }
+ }
+
+ /*
+ * Init completion, so that we
+ * can be properly informed of the completion
+ * of the PxP task when it is done.
+ */
+ init_completion(&fb_data->pxp_tx_cmpl);
+
+ dma_chan = &fb_data->pxp_chan->dma_chan;
+
+ txd = dma_chan->device->device_prep_slave_sg(dma_chan, sg, 2 + 4,
+ DMA_TO_DEVICE,
+ DMA_PREP_INTERRUPT,
+ NULL);
+ if (!txd) {
+ dev_err(fb_data->info.device,
+ "Error preparing a DMA transaction descriptor.\n");
+ return -EIO;
+ }
+
+ txd->callback_param = txd;
+ txd->callback = pxp_dma_done;
+
+ proc_data->working_mode = PXP_MODE_STANDARD;
+ proc_data->engine_enable = PXP_ENABLE_WFE_A;
+ proc_data->lut = upd_data_list->lut_num;
+ proc_data->alpha_en = 0;
+ proc_data->lut_sels = fb_data->luts_complete;
+ proc_data->lut_status_1 = __raw_readl(EPDC_STATUS_LUTS);
+ proc_data->lut_status_2 = __raw_readl(EPDC_STATUS_LUTS2);
+ proc_data->lut_cleanup = 0;
+
+ if (upd_data_list->update_desc->upd_data.flags & EPDC_FLAG_TEST_COLLISION) {
+ proc_data->detection_only = 1;
+ dev_dbg(fb_data->info.device,
+ "collision test_only send to pxp\n");
+ } else
+ proc_data->detection_only = 0;
+
+ if (wv_mode == WAVEFORM_MODE_GLR16
+ || wv_mode == WAVEFORM_MODE_GLD16)
+ proc_data->reagl_en = 1;
+
+ if (upd_data_list->update_desc->upd_data.update_mode == UPDATE_MODE_PARTIAL)
+ proc_data->partial_update = 1;
+ else
+ proc_data->partial_update = 0;
+
+ /* fetch0 is upd buffer */
+ pxp_conf->wfe_a_fetch_param[0].stride = upd_data_list->update_desc->epdc_stride;
+ pxp_conf->wfe_a_fetch_param[0].width = update_region->width;
+ pxp_conf->wfe_a_fetch_param[0].height = update_region->height;
+ /* upd buffer left and top should be always 0 */
+ pxp_conf->wfe_a_fetch_param[0].left = 0;
+ pxp_conf->wfe_a_fetch_param[0].top = 0;
+ if (proc_data->dither_mode) {
+ pxp_conf->wfe_a_fetch_param[0].paddr = fb_data->phys_addr_y4;
+ } else {
+ is_transform = ((upd_data_list->update_desc->upd_data.flags &
+ (EPDC_FLAG_ENABLE_INVERSION | EPDC_FLAG_USE_DITHERING_Y1 |
+ EPDC_FLAG_USE_DITHERING_Y4 | EPDC_FLAG_FORCE_MONOCHROME |
+ EPDC_FLAG_USE_CMAP)) && (proc_data->scaling == 0) &&
+ (proc_data->hflip == 0) && (proc_data->vflip == 0)) ?
+ true : false;
+
+ if ((fb_data->epdc_fb_var.rotate == FB_ROTATE_UR) &&
+ (fb_data->epdc_fb_var.grayscale == GRAYSCALE_8BIT) &&
+ !is_transform && (proc_data->dither_mode == 0) &&
+ !(upd_data_list->update_desc->upd_data.flags &
+ EPDC_FLAG_USE_ALT_BUFFER) &&
+ !fb_data->restrict_width) {
+ sg_dma_address(&sg[0]) = fb_data->info.fix.smem_start;
+ sg_set_page(&sg[0],
+ virt_to_page(fb_data->info.screen_base),
+ fb_data->info.fix.smem_len,
+ offset_in_page(fb_data->info.screen_base));
+ pxp_conf->wfe_a_fetch_param[0].paddr =
+ sg_dma_address(&sg[0]);
+
+ pxp_conf->wfe_a_fetch_param[0].left = update_region->left;
+ pxp_conf->wfe_a_fetch_param[0].top = update_region->top;
+ } else
+ pxp_conf->wfe_a_fetch_param[0].paddr =
+ upd_data_list->phys_addr + upd_data_list->update_desc->epdc_offs;
+ }
+
+ /* fetch1 is working buffer */
+ pxp_conf->wfe_a_fetch_param[1].stride = fb_data->cur_mode->vmode->xres;
+ pxp_conf->wfe_a_fetch_param[1].width = update_region->width;
+ pxp_conf->wfe_a_fetch_param[1].height = update_region->height;
+ pxp_conf->wfe_a_fetch_param[1].paddr = fb_data->working_buffer_phys;
+ pxp_conf->wfe_a_fetch_param[1].left = update_region->left;
+ pxp_conf->wfe_a_fetch_param[1].top = update_region->top;
+
+ /* store0 is y4c buffer */
+ pxp_conf->wfe_a_store_param[0].stride = fb_data->cur_mode->vmode->xres;
+ pxp_conf->wfe_a_store_param[0].width = update_region->width;
+ pxp_conf->wfe_a_store_param[0].height = update_region->height;
+ pxp_conf->wfe_a_store_param[0].paddr = fb_data->phys_addr_y4c;
+
+ /* store1 is (temp) working buffer */
+ pxp_conf->wfe_a_store_param[1].stride = fb_data->cur_mode->vmode->xres;
+ pxp_conf->wfe_a_store_param[1].width = update_region->width;
+ pxp_conf->wfe_a_store_param[1].height = update_region->height;
+ if (wv_mode == WAVEFORM_MODE_GLR16
+ || wv_mode == WAVEFORM_MODE_GLD16)
+ pxp_conf->wfe_a_store_param[1].paddr = fb_data->tmp_working_buffer_phys;
+ else
+ pxp_conf->wfe_a_store_param[1].paddr = fb_data->working_buffer_phys;
+ pxp_conf->wfe_a_store_param[1].left = update_region->left;
+ pxp_conf->wfe_a_store_param[1].top = update_region->top;
+
+ desc = to_tx_desc(txd);
+ length = desc->len;
+
+ memcpy(&desc->proc_data, proc_data, sizeof(struct pxp_proc_data));
+ for (i = 0; i < length; i++) {
+ if (i == 0 || i == 1) {/* wfe_a won't use s0 or output at all */
+ desc = desc->next;
+ } else if ((pxp_conf->proc_data.engine_enable & PXP_ENABLE_WFE_A) && (j < 4)) {
+ for (j = 0; j < 4; j++) {
+ if (j == 0) {
+ memcpy(&desc->layer_param.processing_param,
+ &pxp_conf->wfe_a_fetch_param[0],
+ sizeof(struct pxp_layer_param));
+ desc->layer_param.processing_param.flag = PXP_BUF_FLAG_WFE_A_FETCH0;
+ } else if (j == 1) {
+ memcpy(&desc->layer_param.processing_param,
+ &pxp_conf->wfe_a_fetch_param[1],
+ sizeof(struct pxp_layer_param));
+ desc->layer_param.processing_param.flag = PXP_BUF_FLAG_WFE_A_FETCH1;
+ } else if (j == 2) {
+ memcpy(&desc->layer_param.processing_param,
+ &pxp_conf->wfe_a_store_param[0],
+ sizeof(struct pxp_layer_param));
+ desc->layer_param.processing_param.flag = PXP_BUF_FLAG_WFE_A_STORE0;
+ } else if (j == 3) {
+ memcpy(&desc->layer_param.processing_param,
+ &pxp_conf->wfe_a_store_param[1],
+ sizeof(struct pxp_layer_param));
+ desc->layer_param.processing_param.flag = PXP_BUF_FLAG_WFE_A_STORE1;
+ }
+
+ desc = desc->next;
+ }
+
+ i += 4;
+ }
+ }
+
+ /* Submitting our TX starts the PxP processing task */
+ cookie = txd->tx_submit(txd);
+ if (cookie < 0) {
+ dev_err(fb_data->info.device, "Error sending FB through PxP\n");
+ return -EIO;
+ }
+
+ fb_data->txd = txd;
+
+ /* trigger ePxP */
+ dma_async_issue_pending(dma_chan);
+
+ return 0;
+}
+
+/* For REAGL/-D processing */
+static int pxp_wfe_b_process_update(struct mxc_epdc_fb_data *fb_data,
+ struct mxcfb_rect *update_region)
+{
+ dma_cookie_t cookie;
+ struct scatterlist *sg = fb_data->sg;
+ struct dma_chan *dma_chan;
+ struct pxp_tx_desc *desc;
+ struct dma_async_tx_descriptor *txd;
+ struct pxp_config_data *pxp_conf = &fb_data->pxp_conf;
+ struct pxp_proc_data *proc_data = &fb_data->pxp_conf.proc_data;
+ int i, j = 0, ret;
+ int length;
+
+ dev_dbg(fb_data->dev, "Starting PxP WFE_B process.\n");
+
+ /* First, check to see that we have acquired a PxP Channel object */
+ if (fb_data->pxp_chan == NULL) {
+ /*
+ * PxP Channel has not yet been created and initialized,
+ * so let's go ahead and try
+ */
+ ret = pxp_chan_init(fb_data);
+ if (ret) {
+ /*
+ * PxP channel init failed, and we can't use the
+ * PxP until the PxP DMA driver has loaded, so we abort
+ */
+ dev_err(fb_data->dev, "PxP chan init failed\n");
+ return -ENODEV;
+ }
+ }
+
+ /*
+ * Init completion, so that we
+ * can be properly informed of the completion
+ * of the PxP task when it is done.
+ */
+ init_completion(&fb_data->pxp_tx_cmpl);
+
+ dma_chan = &fb_data->pxp_chan->dma_chan;
+
+ txd = dma_chan->device->device_prep_slave_sg(dma_chan, sg, 2 + 4,
+ DMA_TO_DEVICE,
+ DMA_PREP_INTERRUPT,
+ NULL);
+ if (!txd) {
+ dev_err(fb_data->info.device,
+ "Error preparing a DMA transaction descriptor.\n");
+ return -EIO;
+ }
+
+ txd->callback_param = txd;
+ txd->callback = pxp_dma_done;
+
+ proc_data->working_mode = PXP_MODE_STANDARD;
+ proc_data->engine_enable = PXP_ENABLE_WFE_B;
+ proc_data->lut_update = false;
+ proc_data->lut_cleanup = 0;
+
+ pxp_conf->wfe_b_fetch_param[0].stride = fb_data->cur_mode->vmode->xres;
+ pxp_conf->wfe_b_fetch_param[0].width = fb_data->cur_mode->vmode->xres;
+ pxp_conf->wfe_b_fetch_param[0].height = fb_data->cur_mode->vmode->yres;
+ pxp_conf->wfe_b_fetch_param[0].paddr = fb_data->phys_addr_black;
+ pxp_conf->wfe_b_fetch_param[1].stride = fb_data->cur_mode->vmode->xres;
+ pxp_conf->wfe_b_fetch_param[1].width = update_region->width;
+ pxp_conf->wfe_b_fetch_param[1].height = update_region->height;
+ pxp_conf->wfe_b_fetch_param[1].top = update_region->top;
+ pxp_conf->wfe_b_fetch_param[1].left = update_region->left;
+ pxp_conf->wfe_b_fetch_param[1].paddr = fb_data->tmp_working_buffer_phys;
+
+ pxp_conf->wfe_b_store_param[0].stride = fb_data->cur_mode->vmode->xres;
+ pxp_conf->wfe_b_store_param[0].width = update_region->width;
+ pxp_conf->wfe_b_store_param[0].height = update_region->height;
+ pxp_conf->wfe_b_store_param[0].top = update_region->top;
+ pxp_conf->wfe_b_store_param[0].left = update_region->left;
+ pxp_conf->wfe_b_store_param[0].paddr = fb_data->working_buffer_phys;
+ pxp_conf->wfe_b_store_param[1].stride = fb_data->cur_mode->vmode->xres;
+ pxp_conf->wfe_b_store_param[1].width = update_region->width;
+ pxp_conf->wfe_b_store_param[1].height = update_region->height;
+ pxp_conf->wfe_b_store_param[1].paddr = 0;
+
+ desc = to_tx_desc(txd);
+ length = desc->len;
+
+ for (i = 0; i < length; i++) {
+ if (i == 0) { /* S0 */
+ memcpy(&desc->proc_data, proc_data,
+ sizeof(struct pxp_proc_data));
+ pxp_conf->s0_param.paddr = sg_dma_address(&sg[0]);
+ memcpy(&desc->layer_param.s0_param, &pxp_conf->s0_param,
+ sizeof(struct pxp_layer_param));
+ desc = desc->next;
+ } else if (i == 1) {
+ pxp_conf->out_param.paddr = sg_dma_address(&sg[1]);
+ memcpy(&desc->layer_param.out_param,
+ &pxp_conf->out_param,
+ sizeof(struct pxp_layer_param));
+ desc = desc->next;
+ } else
+ if ((pxp_conf->proc_data.engine_enable & PXP_ENABLE_WFE_B)
+ && (j < 4)) {
+ for (j = 0; j < 4; j++) {
+ if (j == 0) {
+ memcpy(&desc->layer_param.
+ processing_param,
+ &pxp_conf->wfe_b_fetch_param[0],
+ sizeof(struct pxp_layer_param));
+ desc->layer_param.processing_param.
+ flag = PXP_BUF_FLAG_WFE_B_FETCH0;
+ } else if (j == 1) {
+ memcpy(&desc->layer_param.
+ processing_param,
+ &pxp_conf->wfe_b_fetch_param[1],
+ sizeof(struct pxp_layer_param));
+ desc->layer_param.processing_param.
+ flag = PXP_BUF_FLAG_WFE_B_FETCH1;
+ } else if (j == 2) {
+ memcpy(&desc->layer_param.
+ processing_param,
+ &pxp_conf->wfe_b_store_param[0],
+ sizeof(struct pxp_layer_param));
+ desc->layer_param.processing_param.
+ flag = PXP_BUF_FLAG_WFE_B_STORE0;
+ } else if (j == 3) {
+ memcpy(&desc->layer_param.
+ processing_param,
+ &pxp_conf->wfe_b_store_param[1],
+ sizeof(struct pxp_layer_param));
+ desc->layer_param.processing_param.
+ flag = PXP_BUF_FLAG_WFE_B_STORE1;
+ }
+
+ desc = desc->next;
+ }
+
+ i += 4;
+ }
+ }
+
+ /* Submitting our TX starts the PxP processing task */
+ cookie = txd->tx_submit(txd);
+ if (cookie < 0) {
+ dev_err(fb_data->info.device, "Error sending FB through PxP\n");
+ return -EIO;
+ }
+
+ fb_data->txd = txd;
+
+ /* trigger ePxP */
+ dma_async_issue_pending(dma_chan);
+
+ return 0;
+}
+
+static int pxp_complete_update(struct mxc_epdc_fb_data *fb_data, u32 *hist_stat)
+{
+ int ret;
+ /*
+ * Wait for completion event, which will be set
+ * through our TX callback function.
+ */
+ ret = wait_for_completion_timeout(&fb_data->pxp_tx_cmpl, HZ * 2);
+ if (ret <= 0) {
+ dev_info(fb_data->info.device,
+ "PxP operation failed due to %s\n",
+ ret < 0 ? "user interrupt" : "timeout");
+ dma_release_channel(&fb_data->pxp_chan->dma_chan);
+ fb_data->pxp_chan = NULL;
+ return ret ? : -ETIMEDOUT;
+ }
+
+ if ((fb_data->pxp_conf.proc_data.lut_transform & EPDC_FLAG_USE_CMAP) &&
+ fb_data->pxp_conf.proc_data.lut_map_updated)
+ fb_data->pxp_conf.proc_data.lut_map_updated = false;
+
+ *hist_stat = to_tx_desc(fb_data->txd)->hist_status;
+ dma_release_channel(&fb_data->pxp_chan->dma_chan);
+ fb_data->pxp_chan = NULL;
+
+ dev_dbg(fb_data->dev, "TX completed\n");
+
+ return 0;
+}
+
+/*
+ * Different dithering algorithm can be used. We chose
+ * to implement Bill Atkinson's algorithm as an example
+ * Thanks Bill Atkinson for his dithering algorithm.
+ */
+
+/*
+ * Dithering algorithm implementation - Y8->Y1 version 1.0 for i.MX
+ */
+static void do_dithering_processing_Y1_v1_0(
+ unsigned char *update_region_virt_ptr,
+ dma_addr_t update_region_phys_ptr,
+ struct mxcfb_rect *update_region,
+ unsigned long update_region_stride,
+ int *err_dist)
+{
+
+ /* create a temp error distribution array */
+ int bwPix;
+ int y;
+ int col;
+ int *err_dist_l0, *err_dist_l1, *err_dist_l2, distrib_error;
+ int width_3 = update_region->width + 3;
+ char *y8buf;
+ int x_offset = 0;
+
+ /* prime a few elements the error distribution array */
+ for (y = 0; y < update_region->height; y++) {
+ /* Dithering the Y8 in sbuf to BW suitable for A2 waveform */
+ err_dist_l0 = err_dist + (width_3) * (y % 3);
+ err_dist_l1 = err_dist + (width_3) * ((y + 1) % 3);
+ err_dist_l2 = err_dist + (width_3) * ((y + 2) % 3);
+
+ y8buf = update_region_virt_ptr + x_offset;
+
+ /* scan the line and convert the Y8 to BW */
+ for (col = 1; col <= update_region->width; col++) {
+ bwPix = *(err_dist_l0 + col) + *y8buf;
+
+ if (bwPix >= 128) {
+ *y8buf++ = 0xff;
+ distrib_error = (bwPix - 255) >> 3;
+ } else {
+ *y8buf++ = 0;
+ distrib_error = bwPix >> 3;
+ }
+
+ /* modify the error distribution buffer */
+ *(err_dist_l0 + col + 2) += distrib_error;
+ *(err_dist_l1 + col + 1) += distrib_error;
+ *(err_dist_l0 + col + 1) += distrib_error;
+ *(err_dist_l1 + col - 1) += distrib_error;
+ *(err_dist_l1 + col) += distrib_error;
+ *(err_dist_l2 + col) = distrib_error;
+ }
+ x_offset += update_region_stride;
+ }
+
+ flush_cache_all();
+ outer_flush_range(update_region_phys_ptr, update_region_phys_ptr +
+ update_region->height * update_region->width);
+}
+
+/*
+ * Dithering algorithm implementation - Y8->Y4 version 1.0 for i.MX
+ */
+
+static void do_dithering_processing_Y4_v1_0(
+ unsigned char *update_region_virt_ptr,
+ dma_addr_t update_region_phys_ptr,
+ struct mxcfb_rect *update_region,
+ unsigned long update_region_stride,
+ int *err_dist)
+{
+
+ /* create a temp error distribution array */
+ int gcPix;
+ int y;
+ int col;
+ int *err_dist_l0, *err_dist_l1, *err_dist_l2, distrib_error;
+ int width_3 = update_region->width + 3;
+ char *y8buf;
+ int x_offset = 0;
+
+ /* prime a few elements the error distribution array */
+ for (y = 0; y < update_region->height; y++) {
+ /* Dithering the Y8 in sbuf to Y4 */
+ err_dist_l0 = err_dist + (width_3) * (y % 3);
+ err_dist_l1 = err_dist + (width_3) * ((y + 1) % 3);
+ err_dist_l2 = err_dist + (width_3) * ((y + 2) % 3);
+
+ y8buf = update_region_virt_ptr + x_offset;
+
+ /* scan the line and convert the Y8 to Y4 */
+ for (col = 1; col <= update_region->width; col++) {
+ gcPix = *(err_dist_l0 + col) + *y8buf;
+
+ if (gcPix > 255)
+ gcPix = 255;
+ else if (gcPix < 0)
+ gcPix = 0;
+
+ distrib_error = (*y8buf - (gcPix & 0xf0)) >> 3;
+
+ *y8buf++ = gcPix & 0xf0;
+
+ /* modify the error distribution buffer */
+ *(err_dist_l0 + col + 2) += distrib_error;
+ *(err_dist_l1 + col + 1) += distrib_error;
+ *(err_dist_l0 + col + 1) += distrib_error;
+ *(err_dist_l1 + col - 1) += distrib_error;
+ *(err_dist_l1 + col) += distrib_error;
+ *(err_dist_l2 + col) = distrib_error;
+ }
+ x_offset += update_region_stride;
+ }
+
+ flush_cache_all();
+ outer_flush_range(update_region_phys_ptr, update_region_phys_ptr +
+ update_region->height * update_region->width);
+}
+
+static int __init mxc_epdc_fb_init(void)
+{
+ return platform_driver_register(&mxc_epdc_fb_driver);
+}
+late_initcall(mxc_epdc_fb_init);
+
+static void __exit mxc_epdc_fb_exit(void)
+{
+ platform_driver_unregister(&mxc_epdc_fb_driver);
+}
+module_exit(mxc_epdc_fb_exit);
+
+
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("MXC EPDC V2 framebuffer driver");
+MODULE_LICENSE("GPL");
+MODULE_SUPPORTED_DEVICE("fb");
diff --git a/drivers/video/fbdev/mxc/mxc_hdmi.c b/drivers/video/fbdev/mxc/mxc_hdmi.c
new file mode 100644
index 000000000000..6bb39f9795d1
--- /dev/null
+++ b/drivers/video/fbdev/mxc/mxc_hdmi.c
@@ -0,0 +1,2983 @@
+/*
+ * Copyright (C) 2011-2016 Freescale Semiconductor, Inc.
+ *
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+/*
+ * SH-Mobile High-Definition Multimedia Interface (HDMI) driver
+ * for SLISHDMI13T and SLIPHDMIT IP cores
+ *
+ * Copyright (C) 2010, Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/input.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <linux/fb.h>
+#include <linux/init.h>
+#include <linux/list.h>
+#include <linux/delay.h>
+#include <linux/dma-mapping.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/uaccess.h>
+#include <linux/cpufreq.h>
+#include <linux/firmware.h>
+#include <linux/kthread.h>
+#include <linux/regulator/driver.h>
+#include <linux/fsl_devices.h>
+#include <linux/ipu.h>
+#include <linux/regmap.h>
+#include <linux/pinctrl/consumer.h>
+#include <linux/of_device.h>
+
+#include <linux/console.h>
+#include <linux/types.h>
+
+#include "../edid.h"
+#include <video/mxc_edid.h>
+#include <video/mxc_hdmi.h>
+#include "mxc_dispdrv.h"
+
+#include <linux/mfd/mxc-hdmi-core.h>
+
+#define DISPDRV_HDMI "hdmi"
+#define HDMI_EDID_LEN 512
+
+/* status codes for reading edid */
+#define HDMI_EDID_SUCCESS 0
+#define HDMI_EDID_FAIL -1
+#define HDMI_EDID_SAME -2
+#define HDMI_EDID_NO_MODES -3
+
+#define NUM_CEA_VIDEO_MODES 64
+#define DEFAULT_VIDEO_MODE 16 /* 1080P */
+
+#define RGB 0
+#define YCBCR444 1
+#define YCBCR422_16BITS 2
+#define YCBCR422_8BITS 3
+#define XVYCC444 4
+
+/*
+ * We follow a flowchart which is in the "Synopsys DesignWare Courses
+ * HDMI Transmitter Controller User Guide, 1.30a", section 3.1
+ * (dwc_hdmi_tx_user.pdf)
+ *
+ * Below are notes that say "HDMI Initialization Step X"
+ * These correspond to the flowchart.
+ */
+
+/*
+ * We are required to configure VGA mode before reading edid
+ * in HDMI Initialization Step B
+ */
+static const struct fb_videomode vga_mode = {
+ /* 640x480 @ 60 Hz, 31.5 kHz hsync */
+ NULL, 60, 640, 480, 39721, 48, 16, 33, 10, 96, 2, 0,
+ FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_4_3, FB_MODE_IS_VESA,
+};
+
+enum hdmi_datamap {
+ RGB444_8B = 0x01,
+ RGB444_10B = 0x03,
+ RGB444_12B = 0x05,
+ RGB444_16B = 0x07,
+ YCbCr444_8B = 0x09,
+ YCbCr444_10B = 0x0B,
+ YCbCr444_12B = 0x0D,
+ YCbCr444_16B = 0x0F,
+ YCbCr422_8B = 0x16,
+ YCbCr422_10B = 0x14,
+ YCbCr422_12B = 0x12,
+};
+
+enum hdmi_colorimetry {
+ eITU601,
+ eITU709,
+};
+
+struct hdmi_vmode {
+ bool mDVI;
+ bool mHSyncPolarity;
+ bool mVSyncPolarity;
+ bool mInterlaced;
+ bool mDataEnablePolarity;
+
+ unsigned int mPixelClock;
+ unsigned int mPixelRepetitionInput;
+ unsigned int mPixelRepetitionOutput;
+};
+
+struct hdmi_data_info {
+ unsigned int enc_in_format;
+ unsigned int enc_out_format;
+ unsigned int enc_color_depth;
+ unsigned int colorimetry;
+ unsigned int pix_repet_factor;
+ unsigned int hdcp_enable;
+ unsigned int rgb_out_enable;
+ struct hdmi_vmode video_mode;
+};
+
+struct hdmi_phy_reg_config {
+ /* HDMI PHY register config for pass HCT */
+ u16 reg_vlev;
+ u16 reg_cksymtx;
+};
+
+struct mxc_hdmi {
+ struct platform_device *pdev;
+ struct platform_device *core_pdev;
+ struct mxc_dispdrv_handle *disp_mxc_hdmi;
+ struct fb_info *fbi;
+ struct clk *hdmi_isfr_clk;
+ struct clk *hdmi_iahb_clk;
+ struct clk *mipi_core_clk;
+ struct delayed_work hotplug_work;
+ struct delayed_work hdcp_hdp_work;
+
+ struct notifier_block nb;
+
+ struct hdmi_data_info hdmi_data;
+ int vic;
+ struct mxc_edid_cfg edid_cfg;
+ u8 edid[HDMI_EDID_LEN];
+ bool fb_reg;
+ bool cable_plugin;
+ u8 blank;
+ bool dft_mode_set;
+ char *dft_mode_str;
+ int default_bpp;
+ u8 latest_intr_stat;
+ bool irq_enabled;
+ spinlock_t irq_lock;
+ bool phy_enabled;
+ struct fb_videomode default_mode;
+ struct fb_videomode previous_non_vga_mode;
+ bool requesting_vga_for_initialization;
+
+ int *gpr_base;
+ int *gpr_hdmi_base;
+ int *gpr_sdma_base;
+ int cpu_type;
+ int cpu_version;
+ struct hdmi_phy_reg_config phy_config;
+
+ struct pinctrl *pinctrl;
+};
+
+static int hdmi_major;
+static struct class *hdmi_class;
+
+struct i2c_client *hdmi_i2c;
+struct mxc_hdmi *g_hdmi;
+
+static bool hdmi_inited;
+static bool hdcp_init;
+static struct regulator *hdmi_regulator;
+
+extern const struct fb_videomode mxc_cea_mode[64];
+extern void mxc_hdmi_cec_handle(u16 cec_stat);
+
+static void mxc_hdmi_setup(struct mxc_hdmi *hdmi, unsigned long event);
+static void mxc_hdmi_phy_disable(struct mxc_hdmi *hdmi);
+static void hdmi_enable_overflow_interrupts(void);
+static void hdmi_disable_overflow_interrupts(void);
+
+static struct platform_device_id imx_hdmi_devtype[] = {
+ {
+ .name = "hdmi-imx6DL",
+ .driver_data = IMX6DL_HDMI,
+ }, {
+ .name = "hdmi-imx6Q",
+ .driver_data = IMX6Q_HDMI,
+ }, {
+ /* sentinel */
+ }
+};
+MODULE_DEVICE_TABLE(platform, imx_hdmi_devtype);
+
+static const struct of_device_id imx_hdmi_dt_ids[] = {
+ { .compatible = "fsl,imx6dl-hdmi-video", .data = &imx_hdmi_devtype[IMX6DL_HDMI], },
+ { .compatible = "fsl,imx6q-hdmi-video", .data = &imx_hdmi_devtype[IMX6Q_HDMI], },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, imx_hdmi_dt_ids);
+
+static inline int cpu_is_imx6dl(struct mxc_hdmi *hdmi)
+{
+ return hdmi->cpu_type == IMX6DL_HDMI;
+}
+#ifdef DEBUG
+static void dump_fb_videomode(const struct fb_videomode *m)
+{
+ pr_debug("fb_videomode = %d %d %d %d %d %d %d %d %d %d %d %d %d\n",
+ m->refresh, m->xres, m->yres, m->pixclock, m->left_margin,
+ m->right_margin, m->upper_margin, m->lower_margin,
+ m->hsync_len, m->vsync_len, m->sync, m->vmode, m->flag);
+}
+#else
+static void dump_fb_videomode(const struct fb_videomode *m)
+{}
+#endif
+
+static ssize_t mxc_hdmi_show_name(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct mxc_hdmi *hdmi = dev_get_drvdata(dev);
+
+ strcpy(buf, hdmi->fbi->fix.id);
+ sprintf(buf+strlen(buf), "\n");
+
+ return strlen(buf);
+}
+
+static DEVICE_ATTR(fb_name, S_IRUGO, mxc_hdmi_show_name, NULL);
+
+static ssize_t mxc_hdmi_show_state(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct mxc_hdmi *hdmi = dev_get_drvdata(dev);
+
+ if (hdmi->cable_plugin == false)
+ strcpy(buf, "plugout\n");
+ else
+ strcpy(buf, "plugin\n");
+
+ return strlen(buf);
+}
+
+static DEVICE_ATTR(cable_state, S_IRUGO, mxc_hdmi_show_state, NULL);
+
+static ssize_t mxc_hdmi_show_edid(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct mxc_hdmi *hdmi = dev_get_drvdata(dev);
+ int i, j, len = 0;
+
+ for (j = 0; j < HDMI_EDID_LEN/16; j++) {
+ for (i = 0; i < 16; i++)
+ len += sprintf(buf+len, "0x%02X ",
+ hdmi->edid[j*16 + i]);
+ len += sprintf(buf+len, "\n");
+ }
+
+ return len;
+}
+
+static DEVICE_ATTR(edid, S_IRUGO, mxc_hdmi_show_edid, NULL);
+
+static ssize_t mxc_hdmi_show_rgb_out_enable(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct mxc_hdmi *hdmi = dev_get_drvdata(dev);
+
+ if (hdmi->hdmi_data.rgb_out_enable == true)
+ strcpy(buf, "RGB out\n");
+ else
+ strcpy(buf, "YCbCr out\n");
+
+ return strlen(buf);
+}
+
+static ssize_t mxc_hdmi_store_rgb_out_enable(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ struct mxc_hdmi *hdmi = dev_get_drvdata(dev);
+ unsigned long value;
+ int ret;
+
+ ret = kstrtoul(buf, 10, &value);
+ if (ret)
+ return ret;
+
+ hdmi->hdmi_data.rgb_out_enable = value;
+
+ /* Reconfig HDMI for output color space change */
+ mxc_hdmi_setup(hdmi, 0);
+
+ return count;
+}
+
+static DEVICE_ATTR(rgb_out_enable, S_IRUGO | S_IWUSR,
+ mxc_hdmi_show_rgb_out_enable,
+ mxc_hdmi_store_rgb_out_enable);
+
+static ssize_t mxc_hdmi_show_hdcp_enable(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct mxc_hdmi *hdmi = dev_get_drvdata(dev);
+
+ if (hdmi->hdmi_data.hdcp_enable == false)
+ strcpy(buf, "hdcp disable\n");
+ else
+ strcpy(buf, "hdcp enable\n");
+
+ return strlen(buf);
+
+}
+
+static ssize_t mxc_hdmi_store_hdcp_enable(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ struct mxc_hdmi *hdmi = dev_get_drvdata(dev);
+ char event_string[32];
+ char *envp[] = { event_string, NULL };
+ unsigned long value;
+ u8 clkdis;
+ int ret;
+
+ ret = kstrtoul(buf, 10, &value);
+ if (ret)
+ return ret;
+
+ hdmi->hdmi_data.hdcp_enable = value;
+
+ /* Disable All HDMI clock and HDMI PHY */
+ clkdis = hdmi_readb(HDMI_MC_CLKDIS);
+ clkdis |= 0x5f;
+ hdmi_writeb(clkdis, HDMI_MC_CLKDIS);
+ mxc_hdmi_phy_disable(hdmi);
+ hdmi_disable_overflow_interrupts();
+
+ /* Reconfig HDMI for HDCP */
+ mxc_hdmi_setup(hdmi, 0);
+
+ if (hdmi->hdmi_data.hdcp_enable == false) {
+ sprintf(event_string, "EVENT=hdcpdisable");
+ kobject_uevent_env(&hdmi->pdev->dev.kobj, KOBJ_CHANGE, envp);
+ } else {
+ sprintf(event_string, "EVENT=hdcpenable");
+ kobject_uevent_env(&hdmi->pdev->dev.kobj, KOBJ_CHANGE, envp);
+ }
+
+ return count;
+
+}
+
+static DEVICE_ATTR(hdcp_enable, S_IRUGO | S_IWUSR,
+ mxc_hdmi_show_hdcp_enable, mxc_hdmi_store_hdcp_enable);
+
+/*!
+ * this submodule is responsible for the video data synchronization.
+ * for example, for RGB 4:4:4 input, the data map is defined as
+ * pin{47~40} <==> R[7:0]
+ * pin{31~24} <==> G[7:0]
+ * pin{15~8} <==> B[7:0]
+ */
+static void hdmi_video_sample(struct mxc_hdmi *hdmi)
+{
+ int color_format = 0;
+ u8 val;
+
+ if (hdmi->hdmi_data.enc_in_format == RGB) {
+ if (hdmi->hdmi_data.enc_color_depth == 8)
+ color_format = 0x01;
+ else if (hdmi->hdmi_data.enc_color_depth == 10)
+ color_format = 0x03;
+ else if (hdmi->hdmi_data.enc_color_depth == 12)
+ color_format = 0x05;
+ else if (hdmi->hdmi_data.enc_color_depth == 16)
+ color_format = 0x07;
+ else
+ return;
+ } else if (hdmi->hdmi_data.enc_in_format == YCBCR444) {
+ if (hdmi->hdmi_data.enc_color_depth == 8)
+ color_format = 0x09;
+ else if (hdmi->hdmi_data.enc_color_depth == 10)
+ color_format = 0x0B;
+ else if (hdmi->hdmi_data.enc_color_depth == 12)
+ color_format = 0x0D;
+ else if (hdmi->hdmi_data.enc_color_depth == 16)
+ color_format = 0x0F;
+ else
+ return;
+ } else if (hdmi->hdmi_data.enc_in_format == YCBCR422_8BITS) {
+ if (hdmi->hdmi_data.enc_color_depth == 8)
+ color_format = 0x16;
+ else if (hdmi->hdmi_data.enc_color_depth == 10)
+ color_format = 0x14;
+ else if (hdmi->hdmi_data.enc_color_depth == 12)
+ color_format = 0x12;
+ else
+ return;
+ }
+
+ val = HDMI_TX_INVID0_INTERNAL_DE_GENERATOR_DISABLE |
+ ((color_format << HDMI_TX_INVID0_VIDEO_MAPPING_OFFSET) &
+ HDMI_TX_INVID0_VIDEO_MAPPING_MASK);
+ hdmi_writeb(val, HDMI_TX_INVID0);
+
+ /* Enable TX stuffing: When DE is inactive, fix the output data to 0 */
+ val = HDMI_TX_INSTUFFING_BDBDATA_STUFFING_ENABLE |
+ HDMI_TX_INSTUFFING_RCRDATA_STUFFING_ENABLE |
+ HDMI_TX_INSTUFFING_GYDATA_STUFFING_ENABLE;
+ hdmi_writeb(val, HDMI_TX_INSTUFFING);
+ hdmi_writeb(0x0, HDMI_TX_GYDATA0);
+ hdmi_writeb(0x0, HDMI_TX_GYDATA1);
+ hdmi_writeb(0x0, HDMI_TX_RCRDATA0);
+ hdmi_writeb(0x0, HDMI_TX_RCRDATA1);
+ hdmi_writeb(0x0, HDMI_TX_BCBDATA0);
+ hdmi_writeb(0x0, HDMI_TX_BCBDATA1);
+}
+
+static int isColorSpaceConversion(struct mxc_hdmi *hdmi)
+{
+ return (hdmi->hdmi_data.enc_in_format !=
+ hdmi->hdmi_data.enc_out_format);
+}
+
+static int isColorSpaceDecimation(struct mxc_hdmi *hdmi)
+{
+ return ((hdmi->hdmi_data.enc_out_format == YCBCR422_8BITS) &&
+ (hdmi->hdmi_data.enc_in_format == RGB ||
+ hdmi->hdmi_data.enc_in_format == YCBCR444));
+}
+
+static int isColorSpaceInterpolation(struct mxc_hdmi *hdmi)
+{
+ return ((hdmi->hdmi_data.enc_in_format == YCBCR422_8BITS) &&
+ (hdmi->hdmi_data.enc_out_format == RGB
+ || hdmi->hdmi_data.enc_out_format == YCBCR444));
+}
+
+/*!
+ * update the color space conversion coefficients.
+ */
+static void update_csc_coeffs(struct mxc_hdmi *hdmi)
+{
+ unsigned short csc_coeff[3][4];
+ unsigned int csc_scale = 1;
+ u8 val;
+ bool coeff_selected = false;
+
+ if (isColorSpaceConversion(hdmi)) { /* csc needed */
+ if (hdmi->hdmi_data.enc_out_format == RGB) {
+ if (hdmi->hdmi_data.colorimetry == eITU601) {
+ csc_coeff[0][0] = 0x2000;
+ csc_coeff[0][1] = 0x6926;
+ csc_coeff[0][2] = 0x74fd;
+ csc_coeff[0][3] = 0x010e;
+
+ csc_coeff[1][0] = 0x2000;
+ csc_coeff[1][1] = 0x2cdd;
+ csc_coeff[1][2] = 0x0000;
+ csc_coeff[1][3] = 0x7e9a;
+
+ csc_coeff[2][0] = 0x2000;
+ csc_coeff[2][1] = 0x0000;
+ csc_coeff[2][2] = 0x38b4;
+ csc_coeff[2][3] = 0x7e3b;
+
+ csc_scale = 1;
+ coeff_selected = true;
+ } else if (hdmi->hdmi_data.colorimetry == eITU709) {
+ csc_coeff[0][0] = 0x2000;
+ csc_coeff[0][1] = 0x7106;
+ csc_coeff[0][2] = 0x7a02;
+ csc_coeff[0][3] = 0x00a7;
+
+ csc_coeff[1][0] = 0x2000;
+ csc_coeff[1][1] = 0x3264;
+ csc_coeff[1][2] = 0x0000;
+ csc_coeff[1][3] = 0x7e6d;
+
+ csc_coeff[2][0] = 0x2000;
+ csc_coeff[2][1] = 0x0000;
+ csc_coeff[2][2] = 0x3b61;
+ csc_coeff[2][3] = 0x7e25;
+
+ csc_scale = 1;
+ coeff_selected = true;
+ }
+ } else if (hdmi->hdmi_data.enc_in_format == RGB) {
+ if (hdmi->hdmi_data.colorimetry == eITU601) {
+ csc_coeff[0][0] = 0x2591;
+ csc_coeff[0][1] = 0x1322;
+ csc_coeff[0][2] = 0x074b;
+ csc_coeff[0][3] = 0x0000;
+
+ csc_coeff[1][0] = 0x6535;
+ csc_coeff[1][1] = 0x2000;
+ csc_coeff[1][2] = 0x7acc;
+ csc_coeff[1][3] = 0x0200;
+
+ csc_coeff[2][0] = 0x6acd;
+ csc_coeff[2][1] = 0x7534;
+ csc_coeff[2][2] = 0x2000;
+ csc_coeff[2][3] = 0x0200;
+
+ csc_scale = 0;
+ coeff_selected = true;
+ } else if (hdmi->hdmi_data.colorimetry == eITU709) {
+ csc_coeff[0][0] = 0x2dc5;
+ csc_coeff[0][1] = 0x0d9b;
+ csc_coeff[0][2] = 0x049e;
+ csc_coeff[0][3] = 0x0000;
+
+ csc_coeff[1][0] = 0x62f0;
+ csc_coeff[1][1] = 0x2000;
+ csc_coeff[1][2] = 0x7d11;
+ csc_coeff[1][3] = 0x0200;
+
+ csc_coeff[2][0] = 0x6756;
+ csc_coeff[2][1] = 0x78ab;
+ csc_coeff[2][2] = 0x2000;
+ csc_coeff[2][3] = 0x0200;
+
+ csc_scale = 0;
+ coeff_selected = true;
+ }
+ }
+ }
+
+ if (!coeff_selected) {
+ csc_coeff[0][0] = 0x2000;
+ csc_coeff[0][1] = 0x0000;
+ csc_coeff[0][2] = 0x0000;
+ csc_coeff[0][3] = 0x0000;
+
+ csc_coeff[1][0] = 0x0000;
+ csc_coeff[1][1] = 0x2000;
+ csc_coeff[1][2] = 0x0000;
+ csc_coeff[1][3] = 0x0000;
+
+ csc_coeff[2][0] = 0x0000;
+ csc_coeff[2][1] = 0x0000;
+ csc_coeff[2][2] = 0x2000;
+ csc_coeff[2][3] = 0x0000;
+
+ csc_scale = 1;
+ }
+
+ /* Update CSC parameters in HDMI CSC registers */
+ hdmi_writeb((unsigned char)(csc_coeff[0][0] & 0xFF),
+ HDMI_CSC_COEF_A1_LSB);
+ hdmi_writeb((unsigned char)(csc_coeff[0][0] >> 8),
+ HDMI_CSC_COEF_A1_MSB);
+ hdmi_writeb((unsigned char)(csc_coeff[0][1] & 0xFF),
+ HDMI_CSC_COEF_A2_LSB);
+ hdmi_writeb((unsigned char)(csc_coeff[0][1] >> 8),
+ HDMI_CSC_COEF_A2_MSB);
+ hdmi_writeb((unsigned char)(csc_coeff[0][2] & 0xFF),
+ HDMI_CSC_COEF_A3_LSB);
+ hdmi_writeb((unsigned char)(csc_coeff[0][2] >> 8),
+ HDMI_CSC_COEF_A3_MSB);
+ hdmi_writeb((unsigned char)(csc_coeff[0][3] & 0xFF),
+ HDMI_CSC_COEF_A4_LSB);
+ hdmi_writeb((unsigned char)(csc_coeff[0][3] >> 8),
+ HDMI_CSC_COEF_A4_MSB);
+
+ hdmi_writeb((unsigned char)(csc_coeff[1][0] & 0xFF),
+ HDMI_CSC_COEF_B1_LSB);
+ hdmi_writeb((unsigned char)(csc_coeff[1][0] >> 8),
+ HDMI_CSC_COEF_B1_MSB);
+ hdmi_writeb((unsigned char)(csc_coeff[1][1] & 0xFF),
+ HDMI_CSC_COEF_B2_LSB);
+ hdmi_writeb((unsigned char)(csc_coeff[1][1] >> 8),
+ HDMI_CSC_COEF_B2_MSB);
+ hdmi_writeb((unsigned char)(csc_coeff[1][2] & 0xFF),
+ HDMI_CSC_COEF_B3_LSB);
+ hdmi_writeb((unsigned char)(csc_coeff[1][2] >> 8),
+ HDMI_CSC_COEF_B3_MSB);
+ hdmi_writeb((unsigned char)(csc_coeff[1][3] & 0xFF),
+ HDMI_CSC_COEF_B4_LSB);
+ hdmi_writeb((unsigned char)(csc_coeff[1][3] >> 8),
+ HDMI_CSC_COEF_B4_MSB);
+
+ hdmi_writeb((unsigned char)(csc_coeff[2][0] & 0xFF),
+ HDMI_CSC_COEF_C1_LSB);
+ hdmi_writeb((unsigned char)(csc_coeff[2][0] >> 8),
+ HDMI_CSC_COEF_C1_MSB);
+ hdmi_writeb((unsigned char)(csc_coeff[2][1] & 0xFF),
+ HDMI_CSC_COEF_C2_LSB);
+ hdmi_writeb((unsigned char)(csc_coeff[2][1] >> 8),
+ HDMI_CSC_COEF_C2_MSB);
+ hdmi_writeb((unsigned char)(csc_coeff[2][2] & 0xFF),
+ HDMI_CSC_COEF_C3_LSB);
+ hdmi_writeb((unsigned char)(csc_coeff[2][2] >> 8),
+ HDMI_CSC_COEF_C3_MSB);
+ hdmi_writeb((unsigned char)(csc_coeff[2][3] & 0xFF),
+ HDMI_CSC_COEF_C4_LSB);
+ hdmi_writeb((unsigned char)(csc_coeff[2][3] >> 8),
+ HDMI_CSC_COEF_C4_MSB);
+
+ val = hdmi_readb(HDMI_CSC_SCALE);
+ val &= ~HDMI_CSC_SCALE_CSCSCALE_MASK;
+ val |= csc_scale & HDMI_CSC_SCALE_CSCSCALE_MASK;
+ hdmi_writeb(val, HDMI_CSC_SCALE);
+}
+
+static void hdmi_video_csc(struct mxc_hdmi *hdmi)
+{
+ int color_depth = 0;
+ int interpolation = HDMI_CSC_CFG_INTMODE_DISABLE;
+ int decimation = 0;
+ u8 val;
+
+ /* YCC422 interpolation to 444 mode */
+ if (isColorSpaceInterpolation(hdmi))
+ interpolation = HDMI_CSC_CFG_INTMODE_CHROMA_INT_FORMULA1;
+ else if (isColorSpaceDecimation(hdmi))
+ decimation = HDMI_CSC_CFG_DECMODE_CHROMA_INT_FORMULA3;
+
+ if (hdmi->hdmi_data.enc_color_depth == 8)
+ color_depth = HDMI_CSC_SCALE_CSC_COLORDE_PTH_24BPP;
+ else if (hdmi->hdmi_data.enc_color_depth == 10)
+ color_depth = HDMI_CSC_SCALE_CSC_COLORDE_PTH_30BPP;
+ else if (hdmi->hdmi_data.enc_color_depth == 12)
+ color_depth = HDMI_CSC_SCALE_CSC_COLORDE_PTH_36BPP;
+ else if (hdmi->hdmi_data.enc_color_depth == 16)
+ color_depth = HDMI_CSC_SCALE_CSC_COLORDE_PTH_48BPP;
+ else
+ return;
+
+ /*configure the CSC registers */
+ hdmi_writeb(interpolation | decimation, HDMI_CSC_CFG);
+ val = hdmi_readb(HDMI_CSC_SCALE);
+ val &= ~HDMI_CSC_SCALE_CSC_COLORDE_PTH_MASK;
+ val |= color_depth;
+ hdmi_writeb(val, HDMI_CSC_SCALE);
+
+ update_csc_coeffs(hdmi);
+}
+
+/*!
+ * HDMI video packetizer is used to packetize the data.
+ * 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 mxc_hdmi *hdmi)
+{
+ unsigned int color_depth = 0;
+ unsigned int remap_size = HDMI_VP_REMAP_YCC422_16bit;
+ unsigned int output_select = HDMI_VP_CONF_OUTPUT_SELECTOR_PP;
+ struct hdmi_data_info *hdmi_data = &hdmi->hdmi_data;
+ u8 val;
+
+ if (hdmi_data->enc_out_format == RGB
+ || hdmi_data->enc_out_format == YCBCR444) {
+ if (hdmi_data->enc_color_depth == 0)
+ output_select = HDMI_VP_CONF_OUTPUT_SELECTOR_BYPASS;
+ 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)
+ color_depth = 5;
+ else if (hdmi_data->enc_color_depth == 12)
+ color_depth = 6;
+ else if (hdmi_data->enc_color_depth == 16)
+ color_depth = 7;
+ else
+ return;
+ } else if (hdmi_data->enc_out_format == YCBCR422_8BITS) {
+ if (hdmi_data->enc_color_depth == 0 ||
+ hdmi_data->enc_color_depth == 8)
+ remap_size = HDMI_VP_REMAP_YCC422_16bit;
+ else if (hdmi_data->enc_color_depth == 10)
+ remap_size = HDMI_VP_REMAP_YCC422_20bit;
+ else if (hdmi_data->enc_color_depth == 12)
+ remap_size = HDMI_VP_REMAP_YCC422_24bit;
+ else
+ return;
+ output_select = HDMI_VP_CONF_OUTPUT_SELECTOR_YCC422;
+ } else
+ return;
+
+ /* HDMI not support deep color,
+ * because IPU MAX support color depth is 24bit */
+ color_depth = 0;
+
+ /* set the packetizer registers */
+ val = ((color_depth << HDMI_VP_PR_CD_COLOR_DEPTH_OFFSET) &
+ HDMI_VP_PR_CD_COLOR_DEPTH_MASK) |
+ ((hdmi_data->pix_repet_factor <<
+ HDMI_VP_PR_CD_DESIRED_PR_FACTOR_OFFSET) &
+ HDMI_VP_PR_CD_DESIRED_PR_FACTOR_MASK);
+ hdmi_writeb(val, HDMI_VP_PR_CD);
+
+ val = hdmi_readb(HDMI_VP_STUFF);
+ val &= ~HDMI_VP_STUFF_PR_STUFFING_MASK;
+ val |= HDMI_VP_STUFF_PR_STUFFING_STUFFING_MODE;
+ hdmi_writeb(val, HDMI_VP_STUFF);
+
+ /* Data from pixel repeater block */
+ if (hdmi_data->pix_repet_factor > 1) {
+ val = hdmi_readb(HDMI_VP_CONF);
+ val &= ~(HDMI_VP_CONF_PR_EN_MASK |
+ HDMI_VP_CONF_BYPASS_SELECT_MASK);
+ val |= HDMI_VP_CONF_PR_EN_ENABLE |
+ HDMI_VP_CONF_BYPASS_SELECT_PIX_REPEATER;
+ hdmi_writeb(val, HDMI_VP_CONF);
+ } else { /* data from packetizer block */
+ val = hdmi_readb(HDMI_VP_CONF);
+ val &= ~(HDMI_VP_CONF_PR_EN_MASK |
+ HDMI_VP_CONF_BYPASS_SELECT_MASK);
+ val |= HDMI_VP_CONF_PR_EN_DISABLE |
+ HDMI_VP_CONF_BYPASS_SELECT_VID_PACKETIZER;
+ hdmi_writeb(val, HDMI_VP_CONF);
+ }
+
+ val = hdmi_readb(HDMI_VP_STUFF);
+ val &= ~HDMI_VP_STUFF_IDEFAULT_PHASE_MASK;
+ val |= 1 << HDMI_VP_STUFF_IDEFAULT_PHASE_OFFSET;
+ hdmi_writeb(val, HDMI_VP_STUFF);
+
+ hdmi_writeb(remap_size, HDMI_VP_REMAP);
+
+ if (output_select == HDMI_VP_CONF_OUTPUT_SELECTOR_PP) {
+ val = hdmi_readb(HDMI_VP_CONF);
+ val &= ~(HDMI_VP_CONF_BYPASS_EN_MASK |
+ HDMI_VP_CONF_PP_EN_ENMASK |
+ HDMI_VP_CONF_YCC422_EN_MASK);
+ val |= HDMI_VP_CONF_BYPASS_EN_DISABLE |
+ HDMI_VP_CONF_PP_EN_ENABLE |
+ HDMI_VP_CONF_YCC422_EN_DISABLE;
+ hdmi_writeb(val, HDMI_VP_CONF);
+ } else if (output_select == HDMI_VP_CONF_OUTPUT_SELECTOR_YCC422) {
+ val = hdmi_readb(HDMI_VP_CONF);
+ val &= ~(HDMI_VP_CONF_BYPASS_EN_MASK |
+ HDMI_VP_CONF_PP_EN_ENMASK |
+ HDMI_VP_CONF_YCC422_EN_MASK);
+ val |= HDMI_VP_CONF_BYPASS_EN_DISABLE |
+ HDMI_VP_CONF_PP_EN_DISABLE |
+ HDMI_VP_CONF_YCC422_EN_ENABLE;
+ hdmi_writeb(val, HDMI_VP_CONF);
+ } else if (output_select == HDMI_VP_CONF_OUTPUT_SELECTOR_BYPASS) {
+ val = hdmi_readb(HDMI_VP_CONF);
+ val &= ~(HDMI_VP_CONF_BYPASS_EN_MASK |
+ HDMI_VP_CONF_PP_EN_ENMASK |
+ HDMI_VP_CONF_YCC422_EN_MASK);
+ val |= HDMI_VP_CONF_BYPASS_EN_ENABLE |
+ HDMI_VP_CONF_PP_EN_DISABLE |
+ HDMI_VP_CONF_YCC422_EN_DISABLE;
+ hdmi_writeb(val, HDMI_VP_CONF);
+ } else {
+ return;
+ }
+
+ val = hdmi_readb(HDMI_VP_STUFF);
+ val &= ~(HDMI_VP_STUFF_PP_STUFFING_MASK |
+ HDMI_VP_STUFF_YCC422_STUFFING_MASK);
+ val |= HDMI_VP_STUFF_PP_STUFFING_STUFFING_MODE |
+ HDMI_VP_STUFF_YCC422_STUFFING_STUFFING_MODE;
+ hdmi_writeb(val, HDMI_VP_STUFF);
+
+ val = hdmi_readb(HDMI_VP_CONF);
+ val &= ~HDMI_VP_CONF_OUTPUT_SELECTOR_MASK;
+ val |= output_select;
+ hdmi_writeb(val, HDMI_VP_CONF);
+}
+
+#if 0
+/* Force a fixed color screen */
+static void hdmi_video_force_output(struct mxc_hdmi *hdmi, unsigned char force)
+{
+ u8 val;
+
+ dev_dbg(&hdmi->pdev->dev, "%s\n", __func__);
+
+ if (force) {
+ hdmi_writeb(0x00, HDMI_FC_DBGTMDS2); /* R */
+ hdmi_writeb(0x00, HDMI_FC_DBGTMDS1); /* G */
+ hdmi_writeb(0xFF, HDMI_FC_DBGTMDS0); /* B */
+ val = hdmi_readb(HDMI_FC_DBGFORCE);
+ val |= HDMI_FC_DBGFORCE_FORCEVIDEO;
+ hdmi_writeb(val, HDMI_FC_DBGFORCE);
+ } else {
+ val = hdmi_readb(HDMI_FC_DBGFORCE);
+ val &= ~HDMI_FC_DBGFORCE_FORCEVIDEO;
+ hdmi_writeb(val, HDMI_FC_DBGFORCE);
+ hdmi_writeb(0x00, HDMI_FC_DBGTMDS2); /* R */
+ hdmi_writeb(0x00, HDMI_FC_DBGTMDS1); /* G */
+ hdmi_writeb(0x00, HDMI_FC_DBGTMDS0); /* B */
+ }
+}
+#endif
+
+static inline void hdmi_phy_test_clear(struct mxc_hdmi *hdmi,
+ unsigned char bit)
+{
+ u8 val = hdmi_readb(HDMI_PHY_TST0);
+ val &= ~HDMI_PHY_TST0_TSTCLR_MASK;
+ val |= (bit << HDMI_PHY_TST0_TSTCLR_OFFSET) &
+ HDMI_PHY_TST0_TSTCLR_MASK;
+ hdmi_writeb(val, HDMI_PHY_TST0);
+}
+
+static inline void hdmi_phy_test_enable(struct mxc_hdmi *hdmi,
+ unsigned char bit)
+{
+ u8 val = hdmi_readb(HDMI_PHY_TST0);
+ val &= ~HDMI_PHY_TST0_TSTEN_MASK;
+ val |= (bit << HDMI_PHY_TST0_TSTEN_OFFSET) &
+ HDMI_PHY_TST0_TSTEN_MASK;
+ hdmi_writeb(val, HDMI_PHY_TST0);
+}
+
+static inline void hdmi_phy_test_clock(struct mxc_hdmi *hdmi,
+ unsigned char bit)
+{
+ u8 val = hdmi_readb(HDMI_PHY_TST0);
+ val &= ~HDMI_PHY_TST0_TSTCLK_MASK;
+ val |= (bit << HDMI_PHY_TST0_TSTCLK_OFFSET) &
+ HDMI_PHY_TST0_TSTCLK_MASK;
+ hdmi_writeb(val, HDMI_PHY_TST0);
+}
+
+static inline void hdmi_phy_test_din(struct mxc_hdmi *hdmi,
+ unsigned char bit)
+{
+ hdmi_writeb(bit, HDMI_PHY_TST1);
+}
+
+static inline void hdmi_phy_test_dout(struct mxc_hdmi *hdmi,
+ unsigned char bit)
+{
+ hdmi_writeb(bit, HDMI_PHY_TST2);
+}
+
+static bool hdmi_phy_wait_i2c_done(struct mxc_hdmi *hdmi, int msec)
+{
+ unsigned char val = 0;
+ val = hdmi_readb(HDMI_IH_I2CMPHY_STAT0) & 0x3;
+ while (val == 0) {
+ udelay(1000);
+ if (msec-- == 0)
+ return false;
+ val = hdmi_readb(HDMI_IH_I2CMPHY_STAT0) & 0x3;
+ }
+ return true;
+}
+
+static void hdmi_phy_i2c_write(struct mxc_hdmi *hdmi, unsigned short data,
+ unsigned char addr)
+{
+ hdmi_writeb(0xFF, HDMI_IH_I2CMPHY_STAT0);
+ hdmi_writeb(addr, HDMI_PHY_I2CM_ADDRESS_ADDR);
+ hdmi_writeb((unsigned char)(data >> 8),
+ HDMI_PHY_I2CM_DATAO_1_ADDR);
+ hdmi_writeb((unsigned char)(data >> 0),
+ HDMI_PHY_I2CM_DATAO_0_ADDR);
+ hdmi_writeb(HDMI_PHY_I2CM_OPERATION_ADDR_WRITE,
+ HDMI_PHY_I2CM_OPERATION_ADDR);
+ hdmi_phy_wait_i2c_done(hdmi, 1000);
+}
+
+#if 0
+static unsigned short hdmi_phy_i2c_read(struct mxc_hdmi *hdmi,
+ unsigned char addr)
+{
+ unsigned short data;
+ unsigned char msb = 0, lsb = 0;
+ hdmi_writeb(0xFF, HDMI_IH_I2CMPHY_STAT0);
+ hdmi_writeb(addr, HDMI_PHY_I2CM_ADDRESS_ADDR);
+ hdmi_writeb(HDMI_PHY_I2CM_OPERATION_ADDR_READ,
+ HDMI_PHY_I2CM_OPERATION_ADDR);
+ hdmi_phy_wait_i2c_done(hdmi, 1000);
+ msb = hdmi_readb(HDMI_PHY_I2CM_DATAI_1_ADDR);
+ lsb = hdmi_readb(HDMI_PHY_I2CM_DATAI_0_ADDR);
+ data = (msb << 8) | lsb;
+ return data;
+}
+
+static int hdmi_phy_i2c_write_verify(struct mxc_hdmi *hdmi, unsigned short data,
+ unsigned char addr)
+{
+ unsigned short val = 0;
+ hdmi_phy_i2c_write(hdmi, data, addr);
+ val = hdmi_phy_i2c_read(hdmi, addr);
+ return (val == data);
+}
+#endif
+
+static bool hdmi_edid_wait_i2c_done(struct mxc_hdmi *hdmi, int msec)
+{
+ unsigned char val = 0;
+ val = hdmi_readb(HDMI_IH_I2CM_STAT0) & 0x2;
+ while (val == 0) {
+
+ udelay(1000);
+ if (msec-- == 0) {
+ dev_dbg(&hdmi->pdev->dev,
+ "HDMI EDID i2c operation time out!!\n");
+ return false;
+ }
+ val = hdmi_readb(HDMI_IH_I2CM_STAT0) & 0x2;
+ }
+ return true;
+}
+
+static u8 hdmi_edid_i2c_read(struct mxc_hdmi *hdmi,
+ u8 addr, u8 blockno)
+{
+ u8 spointer = blockno / 2;
+ u8 edidaddress = ((blockno % 2) * 0x80) + addr;
+ u8 data;
+
+ hdmi_writeb(0xFF, HDMI_IH_I2CM_STAT0);
+ hdmi_writeb(edidaddress, HDMI_I2CM_ADDRESS);
+ hdmi_writeb(spointer, HDMI_I2CM_SEGADDR);
+ if (spointer == 0)
+ hdmi_writeb(HDMI_I2CM_OPERATION_READ,
+ HDMI_I2CM_OPERATION);
+ else
+ hdmi_writeb(HDMI_I2CM_OPERATION_READ_EXT,
+ HDMI_I2CM_OPERATION);
+
+ hdmi_edid_wait_i2c_done(hdmi, 30);
+ data = hdmi_readb(HDMI_I2CM_DATAI);
+ hdmi_writeb(0xFF, HDMI_IH_I2CM_STAT0);
+ return data;
+}
+
+
+/* "Power-down enable (active low)"
+ * That mean that power up == 1! */
+static void mxc_hdmi_phy_enable_power(u8 enable)
+{
+ hdmi_mask_writeb(enable, HDMI_PHY_CONF0,
+ HDMI_PHY_CONF0_PDZ_OFFSET,
+ HDMI_PHY_CONF0_PDZ_MASK);
+}
+
+static void mxc_hdmi_phy_enable_tmds(u8 enable)
+{
+ hdmi_mask_writeb(enable, HDMI_PHY_CONF0,
+ HDMI_PHY_CONF0_ENTMDS_OFFSET,
+ HDMI_PHY_CONF0_ENTMDS_MASK);
+}
+
+static void mxc_hdmi_phy_gen2_pddq(u8 enable)
+{
+ hdmi_mask_writeb(enable, HDMI_PHY_CONF0,
+ HDMI_PHY_CONF0_GEN2_PDDQ_OFFSET,
+ HDMI_PHY_CONF0_GEN2_PDDQ_MASK);
+}
+
+static void mxc_hdmi_phy_gen2_txpwron(u8 enable)
+{
+ hdmi_mask_writeb(enable, HDMI_PHY_CONF0,
+ HDMI_PHY_CONF0_GEN2_TXPWRON_OFFSET,
+ HDMI_PHY_CONF0_GEN2_TXPWRON_MASK);
+}
+
+#if 0
+static void mxc_hdmi_phy_gen2_enhpdrxsense(u8 enable)
+{
+ hdmi_mask_writeb(enable, HDMI_PHY_CONF0,
+ HDMI_PHY_CONF0_GEN2_ENHPDRXSENSE_OFFSET,
+ HDMI_PHY_CONF0_GEN2_ENHPDRXSENSE_MASK);
+}
+#endif
+
+static void mxc_hdmi_phy_sel_data_en_pol(u8 enable)
+{
+ hdmi_mask_writeb(enable, HDMI_PHY_CONF0,
+ HDMI_PHY_CONF0_SELDATAENPOL_OFFSET,
+ HDMI_PHY_CONF0_SELDATAENPOL_MASK);
+}
+
+static void mxc_hdmi_phy_sel_interface_control(u8 enable)
+{
+ hdmi_mask_writeb(enable, HDMI_PHY_CONF0,
+ HDMI_PHY_CONF0_SELDIPIF_OFFSET,
+ HDMI_PHY_CONF0_SELDIPIF_MASK);
+}
+
+static int hdmi_phy_configure(struct mxc_hdmi *hdmi, unsigned char pRep,
+ unsigned char cRes, int cscOn)
+{
+ u8 val;
+ u8 msec;
+
+ dev_dbg(&hdmi->pdev->dev, "%s\n", __func__);
+
+ /* color resolution 0 is 8 bit colour depth */
+ if (cRes == 0)
+ cRes = 8;
+
+ if (pRep != 0)
+ return false;
+ else if (cRes != 8 && cRes != 12)
+ return false;
+
+ /* Enable csc path */
+ if (cscOn)
+ val = HDMI_MC_FLOWCTRL_FEED_THROUGH_OFF_CSC_IN_PATH;
+ else
+ val = HDMI_MC_FLOWCTRL_FEED_THROUGH_OFF_CSC_BYPASS;
+
+ hdmi_writeb(val, HDMI_MC_FLOWCTRL);
+
+ /* gen2 tx power off */
+ mxc_hdmi_phy_gen2_txpwron(0);
+
+ /* gen2 pddq */
+ mxc_hdmi_phy_gen2_pddq(1);
+
+ /* PHY reset */
+ hdmi_writeb(HDMI_MC_PHYRSTZ_DEASSERT, HDMI_MC_PHYRSTZ);
+ hdmi_writeb(HDMI_MC_PHYRSTZ_ASSERT, HDMI_MC_PHYRSTZ);
+
+ hdmi_writeb(HDMI_MC_HEACPHY_RST_ASSERT, HDMI_MC_HEACPHY_RST);
+
+ hdmi_phy_test_clear(hdmi, 1);
+ hdmi_writeb(HDMI_PHY_I2CM_SLAVE_ADDR_PHY_GEN2,
+ HDMI_PHY_I2CM_SLAVE_ADDR);
+ hdmi_phy_test_clear(hdmi, 0);
+
+ if (hdmi->hdmi_data.video_mode.mPixelClock <= 45250000) {
+ switch (cRes) {
+ case 8:
+ /* PLL/MPLL Cfg */
+ hdmi_phy_i2c_write(hdmi, 0x01e0, 0x06);
+ hdmi_phy_i2c_write(hdmi, 0x0000, 0x15); /* GMPCTRL */
+ break;
+ case 10:
+ hdmi_phy_i2c_write(hdmi, 0x21e1, 0x06);
+ hdmi_phy_i2c_write(hdmi, 0x0000, 0x15);
+ break;
+ case 12:
+ hdmi_phy_i2c_write(hdmi, 0x41e2, 0x06);
+ hdmi_phy_i2c_write(hdmi, 0x0000, 0x15);
+ break;
+ default:
+ return false;
+ }
+ } else if (hdmi->hdmi_data.video_mode.mPixelClock <= 92500000) {
+ switch (cRes) {
+ case 8:
+ hdmi_phy_i2c_write(hdmi, 0x0140, 0x06);
+ hdmi_phy_i2c_write(hdmi, 0x0005, 0x15);
+ break;
+ case 10:
+ hdmi_phy_i2c_write(hdmi, 0x2141, 0x06);
+ hdmi_phy_i2c_write(hdmi, 0x0005, 0x15);
+ break;
+ case 12:
+ hdmi_phy_i2c_write(hdmi, 0x4142, 0x06);
+ hdmi_phy_i2c_write(hdmi, 0x0005, 0x15);
+ default:
+ return false;
+ }
+ } else if (hdmi->hdmi_data.video_mode.mPixelClock <= 148500000) {
+ switch (cRes) {
+ case 8:
+ hdmi_phy_i2c_write(hdmi, 0x00a0, 0x06);
+ hdmi_phy_i2c_write(hdmi, 0x000a, 0x15);
+ break;
+ case 10:
+ hdmi_phy_i2c_write(hdmi, 0x20a1, 0x06);
+ hdmi_phy_i2c_write(hdmi, 0x000a, 0x15);
+ break;
+ case 12:
+ hdmi_phy_i2c_write(hdmi, 0x40a2, 0x06);
+ hdmi_phy_i2c_write(hdmi, 0x000a, 0x15);
+ default:
+ return false;
+ }
+ } else {
+ switch (cRes) {
+ case 8:
+ hdmi_phy_i2c_write(hdmi, 0x00a0, 0x06);
+ hdmi_phy_i2c_write(hdmi, 0x000a, 0x15);
+ break;
+ case 10:
+ hdmi_phy_i2c_write(hdmi, 0x2001, 0x06);
+ hdmi_phy_i2c_write(hdmi, 0x000f, 0x15);
+ break;
+ case 12:
+ hdmi_phy_i2c_write(hdmi, 0x4002, 0x06);
+ hdmi_phy_i2c_write(hdmi, 0x000f, 0x15);
+ default:
+ return false;
+ }
+ }
+
+ if (hdmi->hdmi_data.video_mode.mPixelClock <= 54000000) {
+ switch (cRes) {
+ case 8:
+ hdmi_phy_i2c_write(hdmi, 0x091c, 0x10); /* CURRCTRL */
+ break;
+ case 10:
+ hdmi_phy_i2c_write(hdmi, 0x091c, 0x10);
+ break;
+ case 12:
+ hdmi_phy_i2c_write(hdmi, 0x06dc, 0x10);
+ break;
+ default:
+ return false;
+ }
+ } else if (hdmi->hdmi_data.video_mode.mPixelClock <= 58400000) {
+ switch (cRes) {
+ case 8:
+ hdmi_phy_i2c_write(hdmi, 0x091c, 0x10);
+ break;
+ case 10:
+ hdmi_phy_i2c_write(hdmi, 0x06dc, 0x10);
+ break;
+ case 12:
+ hdmi_phy_i2c_write(hdmi, 0x06dc, 0x10);
+ break;
+ default:
+ return false;
+ }
+ } else if (hdmi->hdmi_data.video_mode.mPixelClock <= 72000000) {
+ switch (cRes) {
+ case 8:
+ hdmi_phy_i2c_write(hdmi, 0x06dc, 0x10);
+ break;
+ case 10:
+ hdmi_phy_i2c_write(hdmi, 0x06dc, 0x10);
+ break;
+ case 12:
+ hdmi_phy_i2c_write(hdmi, 0x091c, 0x10);
+ break;
+ default:
+ return false;
+ }
+ } else if (hdmi->hdmi_data.video_mode.mPixelClock <= 74250000) {
+ switch (cRes) {
+ case 8:
+ hdmi_phy_i2c_write(hdmi, 0x06dc, 0x10);
+ break;
+ case 10:
+ hdmi_phy_i2c_write(hdmi, 0x0b5c, 0x10);
+ break;
+ case 12:
+ hdmi_phy_i2c_write(hdmi, 0x091c, 0x10);
+ break;
+ default:
+ return false;
+ }
+ } else if (hdmi->hdmi_data.video_mode.mPixelClock <= 118800000) {
+ switch (cRes) {
+ case 8:
+ hdmi_phy_i2c_write(hdmi, 0x091c, 0x10);
+ break;
+ case 10:
+ hdmi_phy_i2c_write(hdmi, 0x091c, 0x10);
+ break;
+ case 12:
+ hdmi_phy_i2c_write(hdmi, 0x06dc, 0x10);
+ break;
+ default:
+ return false;
+ }
+ } else if (hdmi->hdmi_data.video_mode.mPixelClock <= 216000000) {
+ switch (cRes) {
+ case 8:
+ hdmi_phy_i2c_write(hdmi, 0x06dc, 0x10);
+ break;
+ case 10:
+ hdmi_phy_i2c_write(hdmi, 0x0b5c, 0x10);
+ break;
+ case 12:
+ hdmi_phy_i2c_write(hdmi, 0x091c, 0x10);
+ break;
+ default:
+ return false;
+ }
+ } else {
+ dev_err(&hdmi->pdev->dev,
+ "Pixel clock %d - unsupported by HDMI\n",
+ hdmi->hdmi_data.video_mode.mPixelClock);
+ return false;
+ }
+
+ hdmi_phy_i2c_write(hdmi, 0x0000, 0x13); /* PLLPHBYCTRL */
+ hdmi_phy_i2c_write(hdmi, 0x0006, 0x17);
+ /* RESISTANCE TERM 133Ohm Cfg */
+ hdmi_phy_i2c_write(hdmi, 0x0005, 0x19); /* TXTERM */
+ /* PREEMP Cgf 0.00 */
+ hdmi_phy_i2c_write(hdmi, 0x800d, 0x09); /* CKSYMTXCTRL */
+ /* TX/CK LVL 10 */
+ hdmi_phy_i2c_write(hdmi, 0x01ad, 0x0E); /* VLEVCTRL */
+
+ /* Board specific setting for PHY register 0x09, 0x0e to pass HCT */
+ if (hdmi->phy_config.reg_cksymtx != 0)
+ hdmi_phy_i2c_write(hdmi, hdmi->phy_config.reg_cksymtx, 0x09);
+
+ if (hdmi->phy_config.reg_vlev != 0)
+ hdmi_phy_i2c_write(hdmi, hdmi->phy_config.reg_vlev, 0x0E);
+
+ /* REMOVE CLK TERM */
+ hdmi_phy_i2c_write(hdmi, 0x8000, 0x05); /* CKCALCTRL */
+
+ if (hdmi->hdmi_data.video_mode.mPixelClock > 148500000) {
+ hdmi_phy_i2c_write(hdmi, 0x800b, 0x09);
+ hdmi_phy_i2c_write(hdmi, 0x0129, 0x0E);
+ }
+
+ mxc_hdmi_phy_enable_power(1);
+
+ /* toggle TMDS enable */
+ mxc_hdmi_phy_enable_tmds(0);
+ mxc_hdmi_phy_enable_tmds(1);
+
+ /* gen2 tx power on */
+ mxc_hdmi_phy_gen2_txpwron(1);
+ mxc_hdmi_phy_gen2_pddq(0);
+
+ /*Wait for PHY PLL lock */
+ msec = 4;
+ val = hdmi_readb(HDMI_PHY_STAT0) & HDMI_PHY_TX_PHY_LOCK;
+ while (val == 0) {
+ udelay(1000);
+ if (msec-- == 0) {
+ dev_dbg(&hdmi->pdev->dev, "PHY PLL not locked\n");
+ return false;
+ }
+ val = hdmi_readb(HDMI_PHY_STAT0) & HDMI_PHY_TX_PHY_LOCK;
+ }
+
+ return true;
+}
+
+static void mxc_hdmi_phy_init(struct mxc_hdmi *hdmi)
+{
+ int i;
+ bool cscon = false;
+
+ dev_dbg(&hdmi->pdev->dev, "%s\n", __func__);
+
+ /* Never do phy init if pixel clock is gated.
+ * Otherwise HDMI PHY will get messed up and generate an overflow
+ * interrupt that can't be cleared or detected by accessing the
+ * status register. */
+ if (!hdmi->fb_reg || !hdmi->cable_plugin
+ || (hdmi->blank != FB_BLANK_UNBLANK))
+ return;
+
+ if (!hdmi->hdmi_data.video_mode.mDVI)
+ hdmi_enable_overflow_interrupts();
+
+ /*check csc whether needed activated in HDMI mode */
+ cscon = (isColorSpaceConversion(hdmi) &&
+ !hdmi->hdmi_data.video_mode.mDVI);
+
+ /* HDMI Phy spec says to do the phy initialization sequence twice */
+ for (i = 0 ; i < 2 ; i++) {
+ mxc_hdmi_phy_sel_data_en_pol(1);
+ mxc_hdmi_phy_sel_interface_control(0);
+ mxc_hdmi_phy_enable_tmds(0);
+ mxc_hdmi_phy_enable_power(0);
+
+ /* Enable CSC */
+ hdmi_phy_configure(hdmi, 0, 8, cscon);
+ }
+
+ hdmi->phy_enabled = true;
+}
+
+static void hdmi_config_AVI(struct mxc_hdmi *hdmi)
+{
+ u8 val;
+ u8 pix_fmt;
+ u8 under_scan;
+ u8 act_ratio, coded_ratio, colorimetry, ext_colorimetry;
+ struct fb_videomode mode;
+ const struct fb_videomode *edid_mode;
+ bool aspect_16_9;
+
+ dev_dbg(&hdmi->pdev->dev, "set up AVI frame\n");
+
+ fb_var_to_videomode(&mode, &hdmi->fbi->var);
+ /* Use mode from list extracted from EDID to get aspect ratio */
+ if (!list_empty(&hdmi->fbi->modelist)) {
+ edid_mode = fb_find_nearest_mode(&mode, &hdmi->fbi->modelist);
+ if (edid_mode->vmode & FB_VMODE_ASPECT_16_9)
+ aspect_16_9 = true;
+ else
+ aspect_16_9 = false;
+ } else
+ aspect_16_9 = false;
+
+ /********************************************
+ * AVI Data Byte 1
+ ********************************************/
+ if (hdmi->hdmi_data.enc_out_format == YCBCR444)
+ pix_fmt = HDMI_FC_AVICONF0_PIX_FMT_YCBCR444;
+ else if (hdmi->hdmi_data.enc_out_format == YCBCR422_8BITS)
+ pix_fmt = HDMI_FC_AVICONF0_PIX_FMT_YCBCR422;
+ else
+ pix_fmt = HDMI_FC_AVICONF0_PIX_FMT_RGB;
+
+ if (hdmi->edid_cfg.cea_underscan)
+ under_scan = HDMI_FC_AVICONF0_SCAN_INFO_UNDERSCAN;
+ else
+ under_scan = HDMI_FC_AVICONF0_SCAN_INFO_NODATA;
+
+ /*
+ * Active format identification data is present in the AVI InfoFrame.
+ * Under scan info, no bar data
+ */
+ val = pix_fmt | under_scan |
+ HDMI_FC_AVICONF0_ACTIVE_FMT_INFO_PRESENT |
+ HDMI_FC_AVICONF0_BAR_DATA_NO_DATA;
+
+ hdmi_writeb(val, HDMI_FC_AVICONF0);
+
+ /********************************************
+ * AVI Data Byte 2
+ ********************************************/
+
+ /* Set the Aspect Ratio */
+ if (aspect_16_9) {
+ act_ratio = HDMI_FC_AVICONF1_ACTIVE_ASPECT_RATIO_16_9;
+ coded_ratio = HDMI_FC_AVICONF1_CODED_ASPECT_RATIO_16_9;
+ } else {
+ act_ratio = HDMI_FC_AVICONF1_ACTIVE_ASPECT_RATIO_4_3;
+ coded_ratio = HDMI_FC_AVICONF1_CODED_ASPECT_RATIO_4_3;
+ }
+
+ /* Set up colorimetry */
+ if (hdmi->hdmi_data.enc_out_format == XVYCC444) {
+ colorimetry = HDMI_FC_AVICONF1_COLORIMETRY_EXTENDED_INFO;
+ if (hdmi->hdmi_data.colorimetry == eITU601)
+ ext_colorimetry =
+ HDMI_FC_AVICONF2_EXT_COLORIMETRY_XVYCC601;
+ else /* hdmi->hdmi_data.colorimetry == eITU709 */
+ ext_colorimetry =
+ HDMI_FC_AVICONF2_EXT_COLORIMETRY_XVYCC709;
+ } else if (hdmi->hdmi_data.enc_out_format != RGB) {
+ if (hdmi->hdmi_data.colorimetry == eITU601)
+ colorimetry = HDMI_FC_AVICONF1_COLORIMETRY_SMPTE;
+ else /* hdmi->hdmi_data.colorimetry == eITU709 */
+ colorimetry = HDMI_FC_AVICONF1_COLORIMETRY_ITUR;
+ ext_colorimetry = HDMI_FC_AVICONF2_EXT_COLORIMETRY_XVYCC601;
+ } else { /* Carries no data */
+ colorimetry = HDMI_FC_AVICONF1_COLORIMETRY_NO_DATA;
+ ext_colorimetry = HDMI_FC_AVICONF2_EXT_COLORIMETRY_XVYCC601;
+ }
+
+ val = colorimetry | coded_ratio | act_ratio;
+ hdmi_writeb(val, HDMI_FC_AVICONF1);
+
+ /********************************************
+ * AVI Data Byte 3
+ ********************************************/
+
+ val = HDMI_FC_AVICONF2_IT_CONTENT_NO_DATA | ext_colorimetry |
+ HDMI_FC_AVICONF2_RGB_QUANT_DEFAULT |
+ HDMI_FC_AVICONF2_SCALING_NONE;
+ hdmi_writeb(val, HDMI_FC_AVICONF2);
+
+ /********************************************
+ * AVI Data Byte 4
+ ********************************************/
+ hdmi_writeb(hdmi->vic, HDMI_FC_AVIVID);
+
+ /********************************************
+ * AVI Data Byte 5
+ ********************************************/
+
+ /* Set up input and output pixel repetition */
+ val = (((hdmi->hdmi_data.video_mode.mPixelRepetitionInput + 1) <<
+ HDMI_FC_PRCONF_INCOMING_PR_FACTOR_OFFSET) &
+ HDMI_FC_PRCONF_INCOMING_PR_FACTOR_MASK) |
+ ((hdmi->hdmi_data.video_mode.mPixelRepetitionOutput <<
+ HDMI_FC_PRCONF_OUTPUT_PR_FACTOR_OFFSET) &
+ HDMI_FC_PRCONF_OUTPUT_PR_FACTOR_MASK);
+ hdmi_writeb(val, HDMI_FC_PRCONF);
+
+ /* IT Content and quantization range = don't care */
+ val = HDMI_FC_AVICONF3_IT_CONTENT_TYPE_GRAPHICS |
+ HDMI_FC_AVICONF3_QUANT_RANGE_LIMITED;
+ hdmi_writeb(val, HDMI_FC_AVICONF3);
+
+ /********************************************
+ * AVI Data Bytes 6-13
+ ********************************************/
+ hdmi_writeb(0, HDMI_FC_AVIETB0);
+ hdmi_writeb(0, HDMI_FC_AVIETB1);
+ hdmi_writeb(0, HDMI_FC_AVISBB0);
+ hdmi_writeb(0, HDMI_FC_AVISBB1);
+ hdmi_writeb(0, HDMI_FC_AVIELB0);
+ hdmi_writeb(0, HDMI_FC_AVIELB1);
+ hdmi_writeb(0, HDMI_FC_AVISRB0);
+ hdmi_writeb(0, HDMI_FC_AVISRB1);
+}
+
+/*!
+ * this submodule is responsible for the video/audio data composition.
+ */
+static void hdmi_av_composer(struct mxc_hdmi *hdmi)
+{
+ u8 inv_val;
+ struct fb_info *fbi = hdmi->fbi;
+ struct fb_videomode fb_mode;
+ struct hdmi_vmode *vmode = &hdmi->hdmi_data.video_mode;
+ int hblank, vblank;
+
+ dev_dbg(&hdmi->pdev->dev, "%s\n", __func__);
+
+ fb_var_to_videomode(&fb_mode, &fbi->var);
+
+ vmode->mHSyncPolarity = ((fb_mode.sync & FB_SYNC_HOR_HIGH_ACT) != 0);
+ vmode->mVSyncPolarity = ((fb_mode.sync & FB_SYNC_VERT_HIGH_ACT) != 0);
+ vmode->mInterlaced = ((fb_mode.vmode & FB_VMODE_INTERLACED) != 0);
+ vmode->mPixelClock = (fb_mode.xres + fb_mode.left_margin +
+ fb_mode.right_margin + fb_mode.hsync_len) * (fb_mode.yres +
+ fb_mode.upper_margin + fb_mode.lower_margin +
+ fb_mode.vsync_len) * fb_mode.refresh;
+
+ dev_dbg(&hdmi->pdev->dev, "final pixclk = %d\n", vmode->mPixelClock);
+
+ /* Set up HDMI_FC_INVIDCONF */
+ inv_val = (hdmi->hdmi_data.hdcp_enable ?
+ HDMI_FC_INVIDCONF_HDCP_KEEPOUT_ACTIVE :
+ HDMI_FC_INVIDCONF_HDCP_KEEPOUT_INACTIVE);
+
+ inv_val |= (vmode->mVSyncPolarity ?
+ HDMI_FC_INVIDCONF_VSYNC_IN_POLARITY_ACTIVE_HIGH :
+ HDMI_FC_INVIDCONF_VSYNC_IN_POLARITY_ACTIVE_LOW);
+
+ inv_val |= (vmode->mHSyncPolarity ?
+ HDMI_FC_INVIDCONF_HSYNC_IN_POLARITY_ACTIVE_HIGH :
+ HDMI_FC_INVIDCONF_HSYNC_IN_POLARITY_ACTIVE_LOW);
+
+ inv_val |= (vmode->mDataEnablePolarity ?
+ HDMI_FC_INVIDCONF_DE_IN_POLARITY_ACTIVE_HIGH :
+ HDMI_FC_INVIDCONF_DE_IN_POLARITY_ACTIVE_LOW);
+
+ if (hdmi->vic == 39)
+ inv_val |= HDMI_FC_INVIDCONF_R_V_BLANK_IN_OSC_ACTIVE_HIGH;
+ else
+ inv_val |= (vmode->mInterlaced ?
+ HDMI_FC_INVIDCONF_R_V_BLANK_IN_OSC_ACTIVE_HIGH :
+ HDMI_FC_INVIDCONF_R_V_BLANK_IN_OSC_ACTIVE_LOW);
+
+ inv_val |= (vmode->mInterlaced ?
+ HDMI_FC_INVIDCONF_IN_I_P_INTERLACED :
+ HDMI_FC_INVIDCONF_IN_I_P_PROGRESSIVE);
+
+ inv_val |= (vmode->mDVI ?
+ HDMI_FC_INVIDCONF_DVI_MODEZ_DVI_MODE :
+ HDMI_FC_INVIDCONF_DVI_MODEZ_HDMI_MODE);
+
+ hdmi_writeb(inv_val, HDMI_FC_INVIDCONF);
+
+ /* Set up horizontal active pixel region width */
+ hdmi_writeb(fb_mode.xres >> 8, HDMI_FC_INHACTV1);
+ hdmi_writeb(fb_mode.xres, HDMI_FC_INHACTV0);
+
+ /* Set up vertical blanking pixel region width */
+ hdmi_writeb(fb_mode.yres >> 8, HDMI_FC_INVACTV1);
+ hdmi_writeb(fb_mode.yres, HDMI_FC_INVACTV0);
+
+ /* Set up horizontal blanking pixel region width */
+ hblank = fb_mode.left_margin + fb_mode.right_margin +
+ fb_mode.hsync_len;
+ hdmi_writeb(hblank >> 8, HDMI_FC_INHBLANK1);
+ hdmi_writeb(hblank, HDMI_FC_INHBLANK0);
+
+ /* Set up vertical blanking pixel region width */
+ vblank = fb_mode.upper_margin + fb_mode.lower_margin +
+ fb_mode.vsync_len;
+ hdmi_writeb(vblank, HDMI_FC_INVBLANK);
+
+ /* Set up HSYNC active edge delay width (in pixel clks) */
+ hdmi_writeb(fb_mode.right_margin >> 8, HDMI_FC_HSYNCINDELAY1);
+ hdmi_writeb(fb_mode.right_margin, HDMI_FC_HSYNCINDELAY0);
+
+ /* Set up VSYNC active edge delay (in pixel clks) */
+ hdmi_writeb(fb_mode.lower_margin, HDMI_FC_VSYNCINDELAY);
+
+ /* Set up HSYNC active pulse width (in pixel clks) */
+ hdmi_writeb(fb_mode.hsync_len >> 8, HDMI_FC_HSYNCINWIDTH1);
+ hdmi_writeb(fb_mode.hsync_len, HDMI_FC_HSYNCINWIDTH0);
+
+ /* Set up VSYNC active edge delay (in pixel clks) */
+ hdmi_writeb(fb_mode.vsync_len, HDMI_FC_VSYNCINWIDTH);
+
+ dev_dbg(&hdmi->pdev->dev, "%s exit\n", __func__);
+}
+
+static int mxc_edid_read_internal(struct mxc_hdmi *hdmi, unsigned char *edid,
+ struct mxc_edid_cfg *cfg, struct fb_info *fbi)
+{
+ int extblknum;
+ int i, j, ret;
+ unsigned char *ediddata = edid;
+ unsigned char tmpedid[EDID_LENGTH];
+
+ dev_info(&hdmi->pdev->dev, "%s\n", __func__);
+
+ if (!edid || !cfg || !fbi)
+ return -EINVAL;
+
+ /* init HDMI I2CM for read edid*/
+ hdmi_writeb(0x0, HDMI_I2CM_DIV);
+ hdmi_writeb(0x00, HDMI_I2CM_SS_SCL_HCNT_1_ADDR);
+ hdmi_writeb(0x79, HDMI_I2CM_SS_SCL_HCNT_0_ADDR);
+ hdmi_writeb(0x00, HDMI_I2CM_SS_SCL_LCNT_1_ADDR);
+ hdmi_writeb(0x91, HDMI_I2CM_SS_SCL_LCNT_0_ADDR);
+
+ hdmi_writeb(0x00, HDMI_I2CM_FS_SCL_HCNT_1_ADDR);
+ hdmi_writeb(0x0F, HDMI_I2CM_FS_SCL_HCNT_0_ADDR);
+ hdmi_writeb(0x00, HDMI_I2CM_FS_SCL_LCNT_1_ADDR);
+ hdmi_writeb(0x21, HDMI_I2CM_FS_SCL_LCNT_0_ADDR);
+
+ hdmi_writeb(0x50, HDMI_I2CM_SLAVE);
+ hdmi_writeb(0x30, HDMI_I2CM_SEGADDR);
+
+ /* Umask edid interrupt */
+ hdmi_writeb(HDMI_I2CM_INT_DONE_POL,
+ HDMI_I2CM_INT);
+
+ hdmi_writeb(HDMI_I2CM_CTLINT_NAC_POL |
+ HDMI_I2CM_CTLINT_ARBITRATION_POL,
+ HDMI_I2CM_CTLINT);
+
+ /* reset edid data zero */
+ memset(edid, 0, EDID_LENGTH*4);
+ memset(cfg, 0, sizeof(struct mxc_edid_cfg));
+
+ /* Check first three byte of EDID head */
+ if (!(hdmi_edid_i2c_read(hdmi, 0, 0) == 0x00) ||
+ !(hdmi_edid_i2c_read(hdmi, 1, 0) == 0xFF) ||
+ !(hdmi_edid_i2c_read(hdmi, 2, 0) == 0xFF)) {
+ dev_info(&hdmi->pdev->dev, "EDID head check failed!");
+ return -ENOENT;
+ }
+
+ for (i = 0; i < 128; i++) {
+ *ediddata = hdmi_edid_i2c_read(hdmi, i, 0);
+ ediddata++;
+ }
+
+ extblknum = edid[0x7E];
+ if (extblknum == 255)
+ extblknum = 0;
+
+ if (extblknum) {
+ ediddata = edid + EDID_LENGTH;
+ for (i = 0; i < 128; i++) {
+ *ediddata = hdmi_edid_i2c_read(hdmi, i, 1);
+ ediddata++;
+ }
+ }
+
+ /* edid first block parsing */
+ memset(&fbi->monspecs, 0, sizeof(fbi->monspecs));
+ fb_edid_to_monspecs(edid, &fbi->monspecs);
+
+ if (extblknum) {
+ ret = mxc_edid_parse_ext_blk(edid + EDID_LENGTH,
+ cfg, &fbi->monspecs);
+ if (ret < 0)
+ return -ENOENT;
+ }
+
+ /* need read segment block? */
+ if (extblknum > 1) {
+ for (j = 2; j <= extblknum; j++) {
+ for (i = 0; i < 128; i++)
+ tmpedid[i] = hdmi_edid_i2c_read(hdmi, i, j);
+
+ /* edid ext block parsing */
+ ret = mxc_edid_parse_ext_blk(tmpedid,
+ cfg, &fbi->monspecs);
+ if (ret < 0)
+ return -ENOENT;
+ }
+ }
+
+ return 0;
+}
+
+static int mxc_hdmi_read_edid(struct mxc_hdmi *hdmi)
+{
+ int ret;
+ u8 edid_old[HDMI_EDID_LEN];
+ u8 clkdis;
+
+ dev_dbg(&hdmi->pdev->dev, "%s\n", __func__);
+
+ /* save old edid */
+ memcpy(edid_old, hdmi->edid, HDMI_EDID_LEN);
+
+ /* Read EDID via HDMI DDC when HDCP Enable */
+ if (!hdcp_init)
+ ret = mxc_edid_read(hdmi_i2c->adapter, hdmi_i2c->addr,
+ hdmi->edid, &hdmi->edid_cfg, hdmi->fbi);
+ else {
+
+ /* Disable HDCP clk */
+ if (hdmi->hdmi_data.hdcp_enable) {
+ clkdis = hdmi_readb(HDMI_MC_CLKDIS);
+ clkdis |= HDMI_MC_CLKDIS_HDCPCLK_DISABLE;
+ hdmi_writeb(clkdis, HDMI_MC_CLKDIS);
+ }
+
+ ret = mxc_edid_read_internal(hdmi, hdmi->edid,
+ &hdmi->edid_cfg, hdmi->fbi);
+
+ /* Enable HDCP clk */
+ if (hdmi->hdmi_data.hdcp_enable) {
+ clkdis = hdmi_readb(HDMI_MC_CLKDIS);
+ clkdis &= ~HDMI_MC_CLKDIS_HDCPCLK_DISABLE;
+ hdmi_writeb(clkdis, HDMI_MC_CLKDIS);
+ }
+
+ }
+ if (ret < 0) {
+ dev_dbg(&hdmi->pdev->dev, "read failed\n");
+ return HDMI_EDID_FAIL;
+ }
+
+ /* Save edid cfg for audio driver */
+ hdmi_set_edid_cfg(&hdmi->edid_cfg);
+
+ if (!memcmp(edid_old, hdmi->edid, HDMI_EDID_LEN)) {
+ dev_info(&hdmi->pdev->dev, "same edid\n");
+ return HDMI_EDID_SAME;
+ }
+
+ if (hdmi->fbi->monspecs.modedb_len == 0) {
+ dev_info(&hdmi->pdev->dev, "No modes read from edid\n");
+ return HDMI_EDID_NO_MODES;
+ }
+
+ return HDMI_EDID_SUCCESS;
+}
+
+static void mxc_hdmi_phy_disable(struct mxc_hdmi *hdmi)
+{
+ dev_dbg(&hdmi->pdev->dev, "%s\n", __func__);
+
+ if (!hdmi->phy_enabled)
+ return;
+
+ hdmi_disable_overflow_interrupts();
+
+ /* Setting PHY to reset status */
+ hdmi_writeb(HDMI_MC_PHYRSTZ_DEASSERT, HDMI_MC_PHYRSTZ);
+
+ /* Power down PHY */
+ mxc_hdmi_phy_enable_tmds(0);
+ mxc_hdmi_phy_enable_power(0);
+ mxc_hdmi_phy_gen2_txpwron(0);
+ mxc_hdmi_phy_gen2_pddq(1);
+
+ hdmi->phy_enabled = false;
+ dev_dbg(&hdmi->pdev->dev, "%s - exit\n", __func__);
+}
+
+/* HDMI Initialization Step B.4 */
+static void mxc_hdmi_enable_video_path(struct mxc_hdmi *hdmi)
+{
+ u8 clkdis;
+
+ dev_dbg(&hdmi->pdev->dev, "%s\n", __func__);
+
+ /* control period minimum duration */
+ hdmi_writeb(12, HDMI_FC_CTRLDUR);
+ hdmi_writeb(32, HDMI_FC_EXCTRLDUR);
+ hdmi_writeb(1, HDMI_FC_EXCTRLSPAC);
+
+ /* Set to fill TMDS data channels */
+ hdmi_writeb(0x0B, HDMI_FC_CH0PREAM);
+ hdmi_writeb(0x16, HDMI_FC_CH1PREAM);
+ hdmi_writeb(0x21, HDMI_FC_CH2PREAM);
+
+ clkdis = hdmi_readb(HDMI_MC_CLKDIS);
+ /* Enable pixel clock and tmds data path */
+ clkdis &= ~HDMI_MC_CLKDIS_PIXELCLK_DISABLE;
+ hdmi_writeb(clkdis, HDMI_MC_CLKDIS);
+
+ clkdis &= ~HDMI_MC_CLKDIS_TMDSCLK_DISABLE;
+ hdmi_writeb(clkdis, HDMI_MC_CLKDIS);
+
+ /* Enable csc path */
+ if (isColorSpaceConversion(hdmi)) {
+ clkdis &= ~HDMI_MC_CLKDIS_CSCCLK_DISABLE;
+ hdmi_writeb(clkdis, HDMI_MC_CLKDIS);
+ }
+}
+
+static void hdmi_enable_audio_clk(struct mxc_hdmi *hdmi)
+{
+ u8 clkdis;
+
+ dev_dbg(&hdmi->pdev->dev, "%s\n", __func__);
+
+ clkdis = hdmi_readb(HDMI_MC_CLKDIS);
+ clkdis &= ~HDMI_MC_CLKDIS_AUDCLK_DISABLE;
+ hdmi_writeb(clkdis, HDMI_MC_CLKDIS);
+}
+
+/* Workaround to clear the overflow condition */
+static void mxc_hdmi_clear_overflow(struct mxc_hdmi *hdmi)
+{
+ int count;
+ u8 val;
+
+ /* TMDS software reset */
+ hdmi_writeb((u8)~HDMI_MC_SWRSTZ_TMDSSWRST_REQ, HDMI_MC_SWRSTZ);
+
+ val = hdmi_readb(HDMI_FC_INVIDCONF);
+
+ if (cpu_is_imx6dl(hdmi)) {
+ hdmi_writeb(val, HDMI_FC_INVIDCONF);
+ return;
+ }
+
+ for (count = 0 ; count < 5 ; count++)
+ hdmi_writeb(val, HDMI_FC_INVIDCONF);
+}
+
+static void hdmi_enable_overflow_interrupts(void)
+{
+ pr_debug("%s\n", __func__);
+ hdmi_writeb(0, HDMI_FC_MASK2);
+ hdmi_writeb(0, HDMI_IH_MUTE_FC_STAT2);
+}
+
+static void hdmi_disable_overflow_interrupts(void)
+{
+ pr_debug("%s\n", __func__);
+ hdmi_writeb(HDMI_IH_MUTE_FC_STAT2_OVERFLOW_MASK,
+ HDMI_IH_MUTE_FC_STAT2);
+ hdmi_writeb(0xff, HDMI_FC_MASK2);
+}
+
+static void mxc_hdmi_notify_fb(struct mxc_hdmi *hdmi)
+{
+ dev_dbg(&hdmi->pdev->dev, "%s\n", __func__);
+
+ /* Don't notify if we aren't registered yet */
+ WARN_ON(!hdmi->fb_reg);
+
+ /* disable the phy before ipu changes mode */
+ mxc_hdmi_phy_disable(hdmi);
+
+ /*
+ * Note that fb_set_var will block. During this time,
+ * FB_EVENT_MODE_CHANGE callback will happen.
+ * So by the end of this function, mxc_hdmi_setup()
+ * will be done.
+ */
+ hdmi->fbi->var.activate |= FB_ACTIVATE_FORCE;
+ console_lock();
+ hdmi->fbi->flags |= FBINFO_MISC_USEREVENT;
+ fb_set_var(hdmi->fbi, &hdmi->fbi->var);
+ hdmi->fbi->flags &= ~FBINFO_MISC_USEREVENT;
+ console_unlock();
+
+ dev_dbg(&hdmi->pdev->dev, "%s exit\n", __func__);
+}
+
+static void mxc_hdmi_edid_rebuild_modelist(struct mxc_hdmi *hdmi)
+{
+ int i;
+ struct fb_videomode *mode;
+
+ dev_dbg(&hdmi->pdev->dev, "%s\n", __func__);
+
+ console_lock();
+
+ fb_destroy_modelist(&hdmi->fbi->modelist);
+ fb_add_videomode(&vga_mode, &hdmi->fbi->modelist);
+
+ for (i = 0; i < hdmi->fbi->monspecs.modedb_len; i++) {
+ /*
+ * We might check here if mode is supported by HDMI.
+ * We do not currently support interlaced modes.
+ * And add CEA modes in the modelist.
+ */
+ mode = &hdmi->fbi->monspecs.modedb[i];
+
+ if (!(mode->vmode & FB_VMODE_INTERLACED) &&
+ (mxc_edid_mode_to_vic(mode) != 0)) {
+
+ dev_dbg(&hdmi->pdev->dev, "Added mode %d:", i);
+ dev_dbg(&hdmi->pdev->dev,
+ "xres = %d, yres = %d, freq = %d, vmode = %d, flag = %d\n",
+ hdmi->fbi->monspecs.modedb[i].xres,
+ hdmi->fbi->monspecs.modedb[i].yres,
+ hdmi->fbi->monspecs.modedb[i].refresh,
+ hdmi->fbi->monspecs.modedb[i].vmode,
+ hdmi->fbi->monspecs.modedb[i].flag);
+
+ fb_add_videomode(mode, &hdmi->fbi->modelist);
+ }
+ }
+
+ fb_new_modelist(hdmi->fbi);
+
+ console_unlock();
+}
+
+static void mxc_hdmi_default_edid_cfg(struct mxc_hdmi *hdmi)
+{
+ /* Default setting HDMI working in HDMI mode */
+ hdmi->edid_cfg.hdmi_cap = true;
+}
+
+static void mxc_hdmi_default_modelist(struct mxc_hdmi *hdmi)
+{
+ struct fb_modelist *modelist;
+ struct fb_videomode *m;
+
+ dev_dbg(&hdmi->pdev->dev, "%s\n", __func__);
+
+ /* If no EDID data read, set up default modelist; since we don't know
+ * the supported modes of the current sink, we will use only one mode in
+ * this modelist:
+ * the default_mode set up at init (usually got from cmdline)
+ */
+ dev_info(&hdmi->pdev->dev, "create default modelist\n");
+
+ /* If the current modelist is already default, don't re-create it*/
+ if (list_is_singular(&hdmi->fbi->modelist)) {
+ modelist = list_entry((&hdmi->fbi->modelist)->next,
+ struct fb_modelist, list);
+ m = &modelist->mode;
+ if (fb_mode_is_equal(m, &hdmi->default_mode)) {
+ dev_info(&hdmi->pdev->dev,
+ "Modelist is already default, no need to re-create!\n");
+ return;
+ }
+
+ }
+
+ console_lock();
+ fb_destroy_modelist(&hdmi->fbi->modelist);
+ fb_add_videomode(&hdmi->default_mode, &hdmi->fbi->modelist);
+ fb_new_modelist(hdmi->fbi);
+ console_unlock();
+}
+
+static void mxc_hdmi_set_mode_to_vga_dvi(struct mxc_hdmi *hdmi)
+{
+ dev_dbg(&hdmi->pdev->dev, "%s\n", __func__);
+
+ hdmi_disable_overflow_interrupts();
+
+ fb_videomode_to_var(&hdmi->fbi->var, &vga_mode);
+
+ hdmi->requesting_vga_for_initialization = true;
+ mxc_hdmi_notify_fb(hdmi);
+ hdmi->requesting_vga_for_initialization = false;
+}
+
+static void mxc_hdmi_set_mode(struct mxc_hdmi *hdmi)
+{
+ const struct fb_videomode *mode;
+ struct fb_videomode m;
+ struct fb_var_screeninfo var;
+
+ dev_dbg(&hdmi->pdev->dev, "%s\n", __func__);
+
+ /* Set the default mode only once. */
+ if (!hdmi->dft_mode_set) {
+ fb_videomode_to_var(&var, &hdmi->default_mode);
+ hdmi->dft_mode_set = true;
+ } else
+ fb_videomode_to_var(&var, &hdmi->previous_non_vga_mode);
+
+ fb_var_to_videomode(&m, &var);
+ dump_fb_videomode(&m);
+
+ mode = fb_find_nearest_mode(&m, &hdmi->fbi->modelist);
+ if (!mode) {
+ pr_err("%s: could not find mode in modelist\n", __func__);
+ return;
+ }
+
+ /* If both video mode and work mode same as previous,
+ * init HDMI again */
+ if (fb_mode_is_equal(&hdmi->previous_non_vga_mode, mode) &&
+ (hdmi->edid_cfg.hdmi_cap != hdmi->hdmi_data.video_mode.mDVI)) {
+ dev_dbg(&hdmi->pdev->dev,
+ "%s: Video mode same as previous\n", __func__);
+ /* update fbi mode in case modelist is updated */
+ hdmi->fbi->mode = (struct fb_videomode *)mode;
+ fb_videomode_to_var(&hdmi->fbi->var, mode);
+ /* update hdmi setting in case EDID data updated */
+ mxc_hdmi_setup(hdmi, 0);
+ } else {
+ dev_dbg(&hdmi->pdev->dev, "%s: New video mode\n", __func__);
+ mxc_hdmi_set_mode_to_vga_dvi(hdmi);
+ fb_videomode_to_var(&hdmi->fbi->var, mode);
+ dump_fb_videomode((struct fb_videomode *)mode);
+ mxc_hdmi_notify_fb(hdmi);
+ }
+
+}
+
+static void mxc_hdmi_cable_connected(struct mxc_hdmi *hdmi)
+{
+ int edid_status;
+
+ dev_dbg(&hdmi->pdev->dev, "%s\n", __func__);
+
+ hdmi->cable_plugin = true;
+
+ /* HDMI Initialization Step C */
+ edid_status = mxc_hdmi_read_edid(hdmi);
+
+ /* Read EDID again if first EDID read failed */
+ if (edid_status == HDMI_EDID_NO_MODES ||
+ edid_status == HDMI_EDID_FAIL) {
+ int retry_status;
+ dev_info(&hdmi->pdev->dev, "Read EDID again\n");
+ msleep(200);
+ retry_status = mxc_hdmi_read_edid(hdmi);
+ /* If we get NO_MODES on the 1st and SAME on the 2nd attempt we
+ * want NO_MODES as final result. */
+ if (retry_status != HDMI_EDID_SAME)
+ edid_status = retry_status;
+ }
+
+ /* HDMI Initialization Steps D, E, F */
+ switch (edid_status) {
+ case HDMI_EDID_SUCCESS:
+ mxc_hdmi_edid_rebuild_modelist(hdmi);
+ break;
+
+ /* Nothing to do if EDID same */
+ case HDMI_EDID_SAME:
+ break;
+
+ case HDMI_EDID_FAIL:
+ mxc_hdmi_default_edid_cfg(hdmi);
+ /* No break here */
+ case HDMI_EDID_NO_MODES:
+ default:
+ mxc_hdmi_default_modelist(hdmi);
+ break;
+ }
+
+ /* Setting video mode */
+ mxc_hdmi_set_mode(hdmi);
+
+ dev_dbg(&hdmi->pdev->dev, "%s exit\n", __func__);
+}
+
+static int mxc_hdmi_power_on(struct mxc_dispdrv_handle *disp,
+ struct fb_info *fbi)
+{
+ struct mxc_hdmi *hdmi = mxc_dispdrv_getdata(disp);
+ mxc_hdmi_phy_init(hdmi);
+ return 0;
+}
+
+static void mxc_hdmi_power_off(struct mxc_dispdrv_handle *disp,
+ struct fb_info *fbi)
+{
+ struct mxc_hdmi *hdmi = mxc_dispdrv_getdata(disp);
+ mxc_hdmi_phy_disable(hdmi);
+}
+
+static void mxc_hdmi_cable_disconnected(struct mxc_hdmi *hdmi)
+{
+ u8 clkdis;
+
+ dev_dbg(&hdmi->pdev->dev, "%s\n", __func__);
+ /* Disable All HDMI clock and bypass cec */
+ clkdis = hdmi_readb(HDMI_MC_CLKDIS);
+ clkdis |= 0x5f;
+ hdmi_writeb(clkdis, HDMI_MC_CLKDIS);
+
+ mxc_hdmi_phy_disable(hdmi);
+
+ hdmi_disable_overflow_interrupts();
+
+ hdmi->cable_plugin = false;
+}
+
+static void hotplug_worker(struct work_struct *work)
+{
+ struct delayed_work *delay_work = to_delayed_work(work);
+ struct mxc_hdmi *hdmi =
+ container_of(delay_work, struct mxc_hdmi, hotplug_work);
+ u32 phy_int_stat, phy_int_pol, phy_int_mask;
+ u8 val;
+ unsigned long flags;
+ char event_string[32];
+ char *envp[] = { event_string, NULL };
+
+ phy_int_stat = hdmi->latest_intr_stat;
+ phy_int_pol = hdmi_readb(HDMI_PHY_POL0);
+
+ dev_dbg(&hdmi->pdev->dev, "phy_int_stat=0x%x, phy_int_pol=0x%x\n",
+ phy_int_stat, phy_int_pol);
+
+ /* check cable status */
+ if (phy_int_stat & HDMI_IH_PHY_STAT0_HPD) {
+ /* cable connection changes */
+ if (phy_int_pol & HDMI_PHY_HPD) {
+ /* Plugin event */
+ dev_dbg(&hdmi->pdev->dev, "EVENT=plugin\n");
+ mxc_hdmi_cable_connected(hdmi);
+
+ /* Make HPD intr active low to capture unplug event */
+ val = hdmi_readb(HDMI_PHY_POL0);
+ val &= ~HDMI_PHY_HPD;
+ hdmi_writeb(val, HDMI_PHY_POL0);
+
+ hdmi_set_cable_state(1);
+
+ sprintf(event_string, "EVENT=plugin");
+ kobject_uevent_env(&hdmi->pdev->dev.kobj, KOBJ_CHANGE, envp);
+#ifdef CONFIG_MXC_HDMI_CEC
+ mxc_hdmi_cec_handle(0x80);
+#endif
+ } else if (!(phy_int_pol & HDMI_PHY_HPD)) {
+ /* Plugout event */
+ dev_dbg(&hdmi->pdev->dev, "EVENT=plugout\n");
+ hdmi_set_cable_state(0);
+ mxc_hdmi_abort_stream();
+ mxc_hdmi_cable_disconnected(hdmi);
+
+ /* Make HPD intr active high to capture plugin event */
+ val = hdmi_readb(HDMI_PHY_POL0);
+ val |= HDMI_PHY_HPD;
+ hdmi_writeb(val, HDMI_PHY_POL0);
+
+ sprintf(event_string, "EVENT=plugout");
+ kobject_uevent_env(&hdmi->pdev->dev.kobj, KOBJ_CHANGE, envp);
+#ifdef CONFIG_MXC_HDMI_CEC
+ mxc_hdmi_cec_handle(0x100);
+#endif
+
+ } else
+ dev_dbg(&hdmi->pdev->dev, "EVENT=none?\n");
+ }
+
+ /* Lock here to ensure full powerdown sequence
+ * completed before next interrupt processed */
+ spin_lock_irqsave(&hdmi->irq_lock, flags);
+
+ /* Re-enable HPD interrupts */
+ phy_int_mask = hdmi_readb(HDMI_PHY_MASK0);
+ phy_int_mask &= ~HDMI_PHY_HPD;
+ hdmi_writeb(phy_int_mask, HDMI_PHY_MASK0);
+
+ /* Unmute interrupts */
+ hdmi_writeb(~HDMI_IH_MUTE_PHY_STAT0_HPD, HDMI_IH_MUTE_PHY_STAT0);
+
+ if (hdmi_readb(HDMI_IH_FC_STAT2) & HDMI_IH_FC_STAT2_OVERFLOW_MASK)
+ mxc_hdmi_clear_overflow(hdmi);
+
+ spin_unlock_irqrestore(&hdmi->irq_lock, flags);
+}
+
+static void hdcp_hdp_worker(struct work_struct *work)
+{
+ struct delayed_work *delay_work = to_delayed_work(work);
+ struct mxc_hdmi *hdmi =
+ container_of(delay_work, struct mxc_hdmi, hdcp_hdp_work);
+ char event_string[32];
+ char *envp[] = { event_string, NULL };
+
+ /* HDCP interrupt */
+ sprintf(event_string, "EVENT=hdcpint");
+ kobject_uevent_env(&hdmi->pdev->dev.kobj, KOBJ_CHANGE, envp);
+
+ /* Unmute interrupts in HDCP application*/
+}
+
+static irqreturn_t mxc_hdmi_hotplug(int irq, void *data)
+{
+ struct mxc_hdmi *hdmi = data;
+ u8 val, intr_stat;
+ unsigned long flags;
+
+ spin_lock_irqsave(&hdmi->irq_lock, flags);
+
+ /* Check and clean packet overflow interrupt.*/
+ if (hdmi_readb(HDMI_IH_FC_STAT2) &
+ HDMI_IH_FC_STAT2_OVERFLOW_MASK) {
+ mxc_hdmi_clear_overflow(hdmi);
+
+ dev_dbg(&hdmi->pdev->dev, "Overflow interrupt received\n");
+ /* clear irq status */
+ hdmi_writeb(HDMI_IH_FC_STAT2_OVERFLOW_MASK,
+ HDMI_IH_FC_STAT2);
+ }
+
+ /*
+ * We could not disable the irq. Probably the audio driver
+ * has enabled it. Masking off the HDMI interrupts using
+ * HDMI registers.
+ */
+ /* Capture status - used in hotplug_worker ISR */
+ intr_stat = hdmi_readb(HDMI_IH_PHY_STAT0);
+
+ if (intr_stat & HDMI_IH_PHY_STAT0_HPD) {
+
+ dev_dbg(&hdmi->pdev->dev, "Hotplug interrupt received\n");
+ hdmi->latest_intr_stat = intr_stat;
+
+ /* Mute interrupts until handled */
+
+ val = hdmi_readb(HDMI_IH_MUTE_PHY_STAT0);
+ val |= HDMI_IH_MUTE_PHY_STAT0_HPD;
+ hdmi_writeb(val, HDMI_IH_MUTE_PHY_STAT0);
+
+ val = hdmi_readb(HDMI_PHY_MASK0);
+ val |= HDMI_PHY_HPD;
+ hdmi_writeb(val, HDMI_PHY_MASK0);
+
+ /* Clear Hotplug interrupts */
+ hdmi_writeb(HDMI_IH_PHY_STAT0_HPD, HDMI_IH_PHY_STAT0);
+
+ schedule_delayed_work(&(hdmi->hotplug_work), msecs_to_jiffies(20));
+ }
+
+ /* Check HDCP interrupt state */
+ if (hdmi->hdmi_data.hdcp_enable) {
+ val = hdmi_readb(HDMI_A_APIINTSTAT);
+ if (val != 0) {
+ /* Mute interrupts until interrupt handled */
+ val = 0xFF;
+ hdmi_writeb(val, HDMI_A_APIINTMSK);
+ schedule_delayed_work(&(hdmi->hdcp_hdp_work), msecs_to_jiffies(50));
+ }
+ }
+
+ spin_unlock_irqrestore(&hdmi->irq_lock, flags);
+ return IRQ_HANDLED;
+}
+
+static void mxc_hdmi_setup(struct mxc_hdmi *hdmi, unsigned long event)
+{
+ struct fb_videomode m;
+ const struct fb_videomode *edid_mode;
+
+ dev_dbg(&hdmi->pdev->dev, "%s\n", __func__);
+
+ fb_var_to_videomode(&m, &hdmi->fbi->var);
+ dump_fb_videomode(&m);
+
+ dev_dbg(&hdmi->pdev->dev, "%s - video mode changed\n", __func__);
+
+ hdmi->vic = 0;
+ if (!hdmi->requesting_vga_for_initialization) {
+ /* Save mode if this isn't the result of requesting
+ * vga default. */
+ memcpy(&hdmi->previous_non_vga_mode, &m,
+ sizeof(struct fb_videomode));
+ if (!list_empty(&hdmi->fbi->modelist)) {
+ edid_mode = fb_find_nearest_mode(&m, &hdmi->fbi->modelist);
+ pr_debug("edid mode ");
+ dump_fb_videomode((struct fb_videomode *)edid_mode);
+ /* update fbi mode */
+ hdmi->fbi->mode = (struct fb_videomode *)edid_mode;
+ hdmi->vic = mxc_edid_mode_to_vic(edid_mode);
+ }
+ }
+
+ hdmi_disable_overflow_interrupts();
+
+ dev_dbg(&hdmi->pdev->dev, "CEA mode used vic=%d\n", hdmi->vic);
+ if (hdmi->edid_cfg.hdmi_cap)
+ hdmi->hdmi_data.video_mode.mDVI = false;
+ else {
+ dev_dbg(&hdmi->pdev->dev, "CEA mode vic=%d work in DVI\n", hdmi->vic);
+ hdmi->hdmi_data.video_mode.mDVI = true;
+ }
+
+ 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->hdmi_data.colorimetry = eITU601;
+ else
+ hdmi->hdmi_data.colorimetry = eITU709;
+
+ 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->hdmi_data.video_mode.mPixelRepetitionOutput = 1;
+ else
+ hdmi->hdmi_data.video_mode.mPixelRepetitionOutput = 0;
+
+ hdmi->hdmi_data.video_mode.mPixelRepetitionInput = 0;
+
+ /* TODO: Get input format from IPU (via FB driver iface) */
+ hdmi->hdmi_data.enc_in_format = RGB;
+
+ hdmi->hdmi_data.enc_out_format = RGB;
+
+ /* YCbCr only enabled in HDMI mode */
+ if (!hdmi->hdmi_data.video_mode.mDVI &&
+ !hdmi->hdmi_data.rgb_out_enable) {
+ if (hdmi->edid_cfg.cea_ycbcr444)
+ hdmi->hdmi_data.enc_out_format = YCBCR444;
+ else if (hdmi->edid_cfg.cea_ycbcr422)
+ hdmi->hdmi_data.enc_out_format = YCBCR422_8BITS;
+ }
+
+ /* IPU not support depth color output */
+ hdmi->hdmi_data.enc_color_depth = 8;
+ hdmi->hdmi_data.pix_repet_factor = 0;
+ hdmi->hdmi_data.video_mode.mDataEnablePolarity = true;
+
+ /* HDMI Initialization Step B.1 */
+ hdmi_av_composer(hdmi);
+
+ /* HDMI Initializateion Step B.2 */
+ mxc_hdmi_phy_init(hdmi);
+
+ /* HDMI Initialization Step B.3 */
+ mxc_hdmi_enable_video_path(hdmi);
+
+ /* not for DVI mode */
+ if (hdmi->hdmi_data.video_mode.mDVI)
+ dev_dbg(&hdmi->pdev->dev, "%s DVI mode\n", __func__);
+ else {
+ dev_dbg(&hdmi->pdev->dev, "%s CEA mode\n", __func__);
+
+ /* HDMI Initialization Step E - Configure audio */
+ hdmi_clk_regenerator_update_pixel_clock(hdmi->fbi->var.pixclock);
+ hdmi_enable_audio_clk(hdmi);
+
+ /* HDMI Initialization Step F - Configure AVI InfoFrame */
+ hdmi_config_AVI(hdmi);
+ }
+
+ hdmi_video_packetize(hdmi);
+ hdmi_video_csc(hdmi);
+ hdmi_video_sample(hdmi);
+
+ mxc_hdmi_clear_overflow(hdmi);
+
+ dev_dbg(&hdmi->pdev->dev, "%s exit\n\n", __func__);
+
+}
+
+/* Wait until we are registered to enable interrupts */
+static void mxc_hdmi_fb_registered(struct mxc_hdmi *hdmi)
+{
+ unsigned long flags;
+
+ if (hdmi->fb_reg)
+ return;
+
+ spin_lock_irqsave(&hdmi->irq_lock, flags);
+
+ dev_dbg(&hdmi->pdev->dev, "%s\n", __func__);
+
+ hdmi_writeb(HDMI_PHY_I2CM_INT_ADDR_DONE_POL,
+ HDMI_PHY_I2CM_INT_ADDR);
+
+ hdmi_writeb(HDMI_PHY_I2CM_CTLINT_ADDR_NAC_POL |
+ HDMI_PHY_I2CM_CTLINT_ADDR_ARBITRATION_POL,
+ HDMI_PHY_I2CM_CTLINT_ADDR);
+
+ /* enable cable hot plug irq */
+ hdmi_writeb((u8)~HDMI_PHY_HPD, HDMI_PHY_MASK0);
+
+ /* Clear Hotplug interrupts */
+ hdmi_writeb(HDMI_IH_PHY_STAT0_HPD, HDMI_IH_PHY_STAT0);
+
+ /* Unmute interrupts */
+ hdmi_writeb(~HDMI_IH_MUTE_PHY_STAT0_HPD, HDMI_IH_MUTE_PHY_STAT0);
+
+ hdmi->fb_reg = true;
+
+ spin_unlock_irqrestore(&hdmi->irq_lock, flags);
+
+}
+
+static int mxc_hdmi_fb_event(struct notifier_block *nb,
+ unsigned long val, void *v)
+{
+ struct fb_event *event = v;
+ struct mxc_hdmi *hdmi = container_of(nb, struct mxc_hdmi, nb);
+
+ if (strcmp(event->info->fix.id, hdmi->fbi->fix.id))
+ return 0;
+
+ switch (val) {
+ case FB_EVENT_FB_REGISTERED:
+ dev_dbg(&hdmi->pdev->dev, "event=FB_EVENT_FB_REGISTERED\n");
+ mxc_hdmi_fb_registered(hdmi);
+ hdmi_set_registered(1);
+ break;
+
+ case FB_EVENT_FB_UNREGISTERED:
+ dev_dbg(&hdmi->pdev->dev, "event=FB_EVENT_FB_UNREGISTERED\n");
+ hdmi->fb_reg = false;
+ hdmi_set_registered(0);
+ break;
+
+ case FB_EVENT_MODE_CHANGE:
+ dev_dbg(&hdmi->pdev->dev, "event=FB_EVENT_MODE_CHANGE\n");
+ if (hdmi->fb_reg)
+ mxc_hdmi_setup(hdmi, val);
+ break;
+
+ case FB_EVENT_BLANK:
+ if ((*((int *)event->data) == FB_BLANK_UNBLANK) &&
+ (*((int *)event->data) != hdmi->blank)) {
+ dev_dbg(&hdmi->pdev->dev,
+ "event=FB_EVENT_BLANK - UNBLANK\n");
+
+ hdmi->blank = *((int *)event->data);
+
+ if (hdmi->fb_reg && hdmi->cable_plugin)
+ mxc_hdmi_setup(hdmi, val);
+ hdmi_set_blank_state(1);
+
+ } else if (*((int *)event->data) != hdmi->blank) {
+ dev_dbg(&hdmi->pdev->dev,
+ "event=FB_EVENT_BLANK - BLANK\n");
+ hdmi_set_blank_state(0);
+ mxc_hdmi_abort_stream();
+
+ mxc_hdmi_phy_disable(hdmi);
+
+ hdmi->blank = *((int *)event->data);
+ } else
+ dev_dbg(&hdmi->pdev->dev,
+ "FB BLANK state no changed!\n");
+
+ break;
+
+ case FB_EVENT_SUSPEND:
+ dev_dbg(&hdmi->pdev->dev,
+ "event=FB_EVENT_SUSPEND\n");
+
+ if (hdmi->blank == FB_BLANK_UNBLANK) {
+ mxc_hdmi_phy_disable(hdmi);
+ clk_disable(hdmi->hdmi_iahb_clk);
+ clk_disable(hdmi->hdmi_isfr_clk);
+ clk_disable(hdmi->mipi_core_clk);
+ }
+ break;
+
+ case FB_EVENT_RESUME:
+ dev_dbg(&hdmi->pdev->dev,
+ "event=FB_EVENT_RESUME\n");
+
+ if (hdmi->blank == FB_BLANK_UNBLANK) {
+ clk_enable(hdmi->mipi_core_clk);
+ clk_enable(hdmi->hdmi_iahb_clk);
+ clk_enable(hdmi->hdmi_isfr_clk);
+ mxc_hdmi_phy_init(hdmi);
+ }
+ break;
+
+ }
+ return 0;
+}
+
+static void hdmi_init_route(struct mxc_hdmi *hdmi)
+{
+ uint32_t hdmi_mux_setting, reg;
+ int ipu_id, disp_id;
+
+ ipu_id = mxc_hdmi_ipu_id;
+ disp_id = mxc_hdmi_disp_id;
+
+ if ((ipu_id > 1) || (ipu_id < 0)) {
+ pr_err("Invalid IPU select for HDMI: %d. Set to 0\n", ipu_id);
+ ipu_id = 0;
+ }
+
+ if ((disp_id > 1) || (disp_id < 0)) {
+ pr_err("Invalid DI select for HDMI: %d. Set to 0\n", disp_id);
+ disp_id = 0;
+ }
+
+ reg = readl(hdmi->gpr_hdmi_base);
+
+ /* Configure the connection between IPU1/2 and HDMI */
+ hdmi_mux_setting = 2*ipu_id + disp_id;
+
+ /* GPR3, bits 2-3 = HDMI_MUX_CTL */
+ reg &= ~0xd;
+ reg |= hdmi_mux_setting << 2;
+
+ writel(reg, hdmi->gpr_hdmi_base);
+
+ /* Set HDMI event as SDMA event2 for HDMI audio */
+ reg = readl(hdmi->gpr_sdma_base);
+ reg |= 0x1;
+ writel(reg, hdmi->gpr_sdma_base);
+}
+
+static void hdmi_hdcp_get_property(struct platform_device *pdev)
+{
+ struct device_node *np = pdev->dev.of_node;
+
+ /* Check hdcp enable by dts.*/
+ hdcp_init = of_property_read_bool(np, "fsl,hdcp");
+ if (hdcp_init)
+ dev_dbg(&pdev->dev, "hdcp enable\n");
+ else
+ dev_dbg(&pdev->dev, "hdcp disable\n");
+}
+
+static void hdmi_get_of_property(struct mxc_hdmi *hdmi)
+{
+ struct platform_device *pdev = hdmi->pdev;
+ struct device_node *np = pdev->dev.of_node;
+ const struct of_device_id *of_id =
+ of_match_device(imx_hdmi_dt_ids, &pdev->dev);
+ int ret;
+ u32 phy_reg_vlev = 0, phy_reg_cksymtx = 0;
+
+ if (of_id) {
+ pdev->id_entry = of_id->data;
+ hdmi->cpu_type = pdev->id_entry->driver_data;
+ }
+
+ /* HDMI PHY register vlev and cksymtx preperty is optional.
+ * It is for specific board to pass HCT electrical part.
+ * Default value will been setting in HDMI PHY config function
+ * if it is not define in device tree.
+ */
+ ret = of_property_read_u32(np, "fsl,phy_reg_vlev", &phy_reg_vlev);
+ if (ret)
+ dev_dbg(&pdev->dev, "No board specific HDMI PHY vlev\n");
+
+ ret = of_property_read_u32(np, "fsl,phy_reg_cksymtx", &phy_reg_cksymtx);
+ if (ret)
+ dev_dbg(&pdev->dev, "No board specific HDMI PHY cksymtx\n");
+
+ /* Specific phy config */
+ hdmi->phy_config.reg_cksymtx = phy_reg_cksymtx;
+ hdmi->phy_config.reg_vlev = phy_reg_vlev;
+
+}
+
+/* HDMI Initialization Step A */
+static int mxc_hdmi_disp_init(struct mxc_dispdrv_handle *disp,
+ struct mxc_dispdrv_setting *setting)
+{
+ int ret = 0;
+ u32 i;
+ const struct fb_videomode *mode;
+ struct fb_videomode m;
+ struct mxc_hdmi *hdmi = mxc_dispdrv_getdata(disp);
+ int irq = platform_get_irq(hdmi->pdev, 0);
+
+ dev_dbg(&hdmi->pdev->dev, "%s\n", __func__);
+
+ /* Check hdmi disp init once */
+ if (hdmi_inited) {
+ dev_err(&hdmi->pdev->dev,
+ "Error only one HDMI output support now!\n");
+ return -1;
+ }
+
+ hdmi_get_of_property(hdmi);
+
+ if (irq < 0)
+ return -ENODEV;
+
+ /* Setting HDMI default to blank state */
+ hdmi->blank = FB_BLANK_POWERDOWN;
+
+ ret = ipu_di_to_crtc(&hdmi->pdev->dev, mxc_hdmi_ipu_id,
+ mxc_hdmi_disp_id, &setting->crtc);
+ if (ret < 0)
+ return ret;
+
+ setting->if_fmt = IPU_PIX_FMT_RGB24;
+
+ hdmi->dft_mode_str = setting->dft_mode_str;
+ hdmi->default_bpp = setting->default_bpp;
+ dev_dbg(&hdmi->pdev->dev, "%s - default mode %s bpp=%d\n",
+ __func__, hdmi->dft_mode_str, hdmi->default_bpp);
+
+ hdmi->fbi = setting->fbi;
+
+ hdmi_init_route(hdmi);
+
+ hdmi->mipi_core_clk = clk_get(&hdmi->pdev->dev, "mipi_core");
+ if (IS_ERR(hdmi->mipi_core_clk)) {
+ ret = PTR_ERR(hdmi->mipi_core_clk);
+ dev_err(&hdmi->pdev->dev,
+ "Unable to get mipi core clk: %d\n", ret);
+ goto egetclk;
+ }
+
+ ret = clk_prepare_enable(hdmi->mipi_core_clk);
+ if (ret < 0) {
+ dev_err(&hdmi->pdev->dev,
+ "Cannot enable mipi core clock: %d\n", ret);
+ goto erate;
+ }
+
+ hdmi->hdmi_isfr_clk = clk_get(&hdmi->pdev->dev, "hdmi_isfr");
+ if (IS_ERR(hdmi->hdmi_isfr_clk)) {
+ ret = PTR_ERR(hdmi->hdmi_isfr_clk);
+ dev_err(&hdmi->pdev->dev,
+ "Unable to get HDMI clk: %d\n", ret);
+ goto egetclk1;
+ }
+
+ ret = clk_prepare_enable(hdmi->hdmi_isfr_clk);
+ if (ret < 0) {
+ dev_err(&hdmi->pdev->dev,
+ "Cannot enable HDMI isfr clock: %d\n", ret);
+ goto erate1;
+ }
+
+ hdmi->hdmi_iahb_clk = clk_get(&hdmi->pdev->dev, "hdmi_iahb");
+ if (IS_ERR(hdmi->hdmi_iahb_clk)) {
+ ret = PTR_ERR(hdmi->hdmi_iahb_clk);
+ dev_err(&hdmi->pdev->dev,
+ "Unable to get HDMI clk: %d\n", ret);
+ goto egetclk2;
+ }
+
+ ret = clk_prepare_enable(hdmi->hdmi_iahb_clk);
+ if (ret < 0) {
+ dev_err(&hdmi->pdev->dev,
+ "Cannot enable HDMI iahb clock: %d\n", ret);
+ goto erate2;
+ }
+
+ dev_dbg(&hdmi->pdev->dev, "Enabled HDMI clocks\n");
+
+ /* Init DDC pins for HDCP */
+ if (hdcp_init) {
+ hdmi->pinctrl = devm_pinctrl_get_select_default(&hdmi->pdev->dev);
+ if (IS_ERR(hdmi->pinctrl)) {
+ dev_err(&hdmi->pdev->dev, "can't get/select DDC pinctrl\n");
+ goto erate2;
+ }
+ }
+
+ /* Product and revision IDs */
+ dev_info(&hdmi->pdev->dev,
+ "Detected HDMI controller 0x%x:0x%x:0x%x:0x%x\n",
+ hdmi_readb(HDMI_DESIGN_ID),
+ hdmi_readb(HDMI_REVISION_ID),
+ hdmi_readb(HDMI_PRODUCT_ID0),
+ hdmi_readb(HDMI_PRODUCT_ID1));
+
+ /* To prevent overflows in HDMI_IH_FC_STAT2, set the clk regenerator
+ * N and cts values before enabling phy */
+ hdmi_init_clk_regenerator();
+
+ INIT_LIST_HEAD(&hdmi->fbi->modelist);
+
+ spin_lock_init(&hdmi->irq_lock);
+
+ /* Set the default mode and modelist when disp init. */
+ fb_find_mode(&hdmi->fbi->var, hdmi->fbi,
+ hdmi->dft_mode_str, NULL, 0, NULL,
+ hdmi->default_bpp);
+
+ console_lock();
+
+ fb_destroy_modelist(&hdmi->fbi->modelist);
+
+ /*Add all no interlaced CEA mode to default modelist */
+ for (i = 0; i < ARRAY_SIZE(mxc_cea_mode); i++) {
+ mode = &mxc_cea_mode[i];
+ if (!(mode->vmode & FB_VMODE_INTERLACED) && (mode->xres != 0))
+ fb_add_videomode(mode, &hdmi->fbi->modelist);
+ }
+
+ console_unlock();
+
+ /* Find a nearest mode in default modelist */
+ fb_var_to_videomode(&m, &hdmi->fbi->var);
+
+ hdmi->dft_mode_set = false;
+ mode = fb_find_nearest_mode(&m, &hdmi->fbi->modelist);
+ if (!mode) {
+ pr_err("%s: could not find mode in modelist\n", __func__);
+ return -1;
+ }
+ dump_fb_videomode(mode);
+ /* Save default video mode */
+ memcpy(&hdmi->default_mode, mode, sizeof(struct fb_videomode));
+
+ fb_videomode_to_var(&hdmi->fbi->var, mode);
+
+ /* update fbi mode */
+ hdmi->fbi->mode = (struct fb_videomode *)mode;
+
+ /* Default setting HDMI working in HDMI mode*/
+ hdmi->edid_cfg.hdmi_cap = true;
+
+ INIT_DELAYED_WORK(&hdmi->hotplug_work, hotplug_worker);
+ INIT_DELAYED_WORK(&hdmi->hdcp_hdp_work, hdcp_hdp_worker);
+
+ /* Configure registers related to HDMI interrupt
+ * generation before registering IRQ. */
+ hdmi_writeb(HDMI_PHY_HPD, HDMI_PHY_POL0);
+
+ /* Clear Hotplug interrupts */
+ hdmi_writeb(HDMI_IH_PHY_STAT0_HPD, HDMI_IH_PHY_STAT0);
+
+ hdmi->nb.notifier_call = mxc_hdmi_fb_event;
+ ret = fb_register_client(&hdmi->nb);
+ if (ret < 0)
+ goto efbclient;
+
+ memset(&hdmi->hdmi_data, 0, sizeof(struct hdmi_data_info));
+
+ /* Default HDMI working in RGB mode */
+ hdmi->hdmi_data.rgb_out_enable = true;
+
+ ret = devm_request_irq(&hdmi->pdev->dev, irq, mxc_hdmi_hotplug, IRQF_SHARED,
+ dev_name(&hdmi->pdev->dev), hdmi);
+ if (ret < 0) {
+ dev_err(&hdmi->pdev->dev,
+ "Unable to request irq: %d\n", ret);
+ goto ereqirq;
+ }
+
+ ret = device_create_file(&hdmi->pdev->dev, &dev_attr_fb_name);
+ if (ret < 0)
+ dev_warn(&hdmi->pdev->dev,
+ "cound not create sys node for fb name\n");
+ ret = device_create_file(&hdmi->pdev->dev, &dev_attr_cable_state);
+ if (ret < 0)
+ dev_warn(&hdmi->pdev->dev,
+ "cound not create sys node for cable state\n");
+ ret = device_create_file(&hdmi->pdev->dev, &dev_attr_edid);
+ if (ret < 0)
+ dev_warn(&hdmi->pdev->dev,
+ "cound not create sys node for edid\n");
+
+ ret = device_create_file(&hdmi->pdev->dev, &dev_attr_rgb_out_enable);
+ if (ret < 0)
+ dev_warn(&hdmi->pdev->dev,
+ "cound not create sys node for rgb out enable\n");
+
+ ret = device_create_file(&hdmi->pdev->dev, &dev_attr_hdcp_enable);
+ if (ret < 0)
+ dev_warn(&hdmi->pdev->dev,
+ "cound not create sys node for hdcp enable\n");
+
+ dev_dbg(&hdmi->pdev->dev, "%s exit\n", __func__);
+
+ hdmi_inited = true;
+
+ return ret;
+
+efbclient:
+ free_irq(irq, hdmi);
+ereqirq:
+ clk_disable_unprepare(hdmi->hdmi_iahb_clk);
+erate2:
+ clk_put(hdmi->hdmi_iahb_clk);
+egetclk2:
+ clk_disable_unprepare(hdmi->hdmi_isfr_clk);
+erate1:
+ clk_put(hdmi->hdmi_isfr_clk);
+egetclk1:
+ clk_disable_unprepare(hdmi->mipi_core_clk);
+erate:
+ clk_put(hdmi->mipi_core_clk);
+egetclk:
+ dev_dbg(&hdmi->pdev->dev, "%s error exit\n", __func__);
+
+ return ret;
+}
+
+static void mxc_hdmi_disp_deinit(struct mxc_dispdrv_handle *disp)
+{
+ struct mxc_hdmi *hdmi = mxc_dispdrv_getdata(disp);
+
+ dev_dbg(&hdmi->pdev->dev, "%s\n", __func__);
+
+ fb_unregister_client(&hdmi->nb);
+
+ clk_disable_unprepare(hdmi->hdmi_isfr_clk);
+ clk_put(hdmi->hdmi_isfr_clk);
+ clk_disable_unprepare(hdmi->hdmi_iahb_clk);
+ clk_put(hdmi->hdmi_iahb_clk);
+ clk_disable_unprepare(hdmi->mipi_core_clk);
+ clk_put(hdmi->mipi_core_clk);
+
+ platform_device_unregister(hdmi->pdev);
+
+ hdmi_inited = false;
+}
+
+static struct mxc_dispdrv_driver mxc_hdmi_drv = {
+ .name = DISPDRV_HDMI,
+ .init = mxc_hdmi_disp_init,
+ .deinit = mxc_hdmi_disp_deinit,
+ .enable = mxc_hdmi_power_on,
+ .disable = mxc_hdmi_power_off,
+};
+
+
+static int mxc_hdmi_open(struct inode *inode, struct file *file)
+{
+ return 0;
+}
+
+static long mxc_hdmi_ioctl(struct file *file,
+ unsigned int cmd, unsigned long arg)
+{
+ int __user *argp = (void __user *)arg;
+ int ret = 0;
+
+ switch (cmd) {
+ case HDMI_IOC_GET_RESOURCE:
+ ret = copy_to_user(argp, &g_hdmi->hdmi_data,
+ sizeof(g_hdmi->hdmi_data)) ? -EFAULT : 0;
+ break;
+ case HDMI_IOC_GET_CPU_TYPE:
+ ret = put_user(g_hdmi->cpu_type, argp);
+ break;
+ default:
+ pr_debug("Unsupport cmd %d\n", cmd);
+ break;
+ }
+
+ return ret;
+}
+
+static int mxc_hdmi_release(struct inode *inode, struct file *file)
+{
+ return 0;
+}
+
+static const struct file_operations mxc_hdmi_fops = {
+ .owner = THIS_MODULE,
+ .open = mxc_hdmi_open,
+ .release = mxc_hdmi_release,
+ .unlocked_ioctl = mxc_hdmi_ioctl,
+};
+
+
+static int mxc_hdmi_probe(struct platform_device *pdev)
+{
+ struct mxc_hdmi *hdmi;
+ struct device *temp_class;
+ struct resource *res;
+ int ret = 0;
+
+ /* Check I2C driver is loaded and available
+ * check hdcp function is enable by dts */
+ hdmi_hdcp_get_property(pdev);
+ if (!hdmi_i2c && !hdcp_init)
+ return -ENODEV;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res)
+ return -ENOENT;
+
+ hdmi = devm_kzalloc(&pdev->dev,
+ sizeof(struct mxc_hdmi),
+ GFP_KERNEL);
+ if (!hdmi) {
+ dev_err(&pdev->dev, "Cannot allocate device data\n");
+ ret = -ENOMEM;
+ goto ealloc;
+ }
+ g_hdmi = hdmi;
+
+ hdmi_major = register_chrdev(hdmi_major, "mxc_hdmi", &mxc_hdmi_fops);
+ if (hdmi_major < 0) {
+ printk(KERN_ERR "HDMI: unable to get a major for HDMI\n");
+ ret = -EBUSY;
+ goto ealloc;
+ }
+
+ hdmi_class = class_create(THIS_MODULE, "mxc_hdmi");
+ if (IS_ERR(hdmi_class)) {
+ ret = PTR_ERR(hdmi_class);
+ goto err_out_chrdev;
+ }
+
+ temp_class = device_create(hdmi_class, NULL, MKDEV(hdmi_major, 0),
+ NULL, "mxc_hdmi");
+ if (IS_ERR(temp_class)) {
+ ret = PTR_ERR(temp_class);
+ goto err_out_class;
+ }
+
+ hdmi->pdev = pdev;
+
+ hdmi->core_pdev = platform_device_alloc("mxc_hdmi_core", -1);
+ if (!hdmi->core_pdev) {
+ pr_err("%s failed platform_device_alloc for hdmi core\n",
+ __func__);
+ ret = -ENOMEM;
+ goto ecore;
+ }
+
+ hdmi->gpr_base = ioremap(res->start, resource_size(res));
+ if (!hdmi->gpr_base) {
+ dev_err(&pdev->dev, "ioremap failed\n");
+ ret = -ENOMEM;
+ goto eiomap;
+ }
+
+ hdmi->gpr_hdmi_base = hdmi->gpr_base + 3;
+ hdmi->gpr_sdma_base = hdmi->gpr_base;
+
+ hdmi_inited = false;
+
+ hdmi->disp_mxc_hdmi = mxc_dispdrv_register(&mxc_hdmi_drv);
+ if (IS_ERR(hdmi->disp_mxc_hdmi)) {
+ dev_err(&pdev->dev, "Failed to register dispdrv - 0x%x\n",
+ (int)hdmi->disp_mxc_hdmi);
+ ret = (int)hdmi->disp_mxc_hdmi;
+ goto edispdrv;
+ }
+ mxc_dispdrv_setdata(hdmi->disp_mxc_hdmi, hdmi);
+
+ platform_set_drvdata(pdev, hdmi);
+
+ hdmi_regulator = devm_regulator_get(&pdev->dev, "HDMI");
+ if (!IS_ERR(hdmi_regulator)) {
+ ret = regulator_enable(hdmi_regulator);
+ if (ret) {
+ dev_err(&pdev->dev, "enable 5v hdmi regulator failed\n");
+ goto edispdrv;
+ }
+ } else {
+ hdmi_regulator = NULL;
+ dev_warn(&pdev->dev, "No hdmi 5v supply\n");
+ }
+
+ return 0;
+edispdrv:
+ iounmap(hdmi->gpr_base);
+eiomap:
+ platform_device_put(hdmi->core_pdev);
+ecore:
+ kfree(hdmi);
+err_out_class:
+ device_destroy(hdmi_class, MKDEV(hdmi_major, 0));
+ class_destroy(hdmi_class);
+err_out_chrdev:
+ unregister_chrdev(hdmi_major, "mxc_hdmi");
+ealloc:
+ return ret;
+}
+
+static int mxc_hdmi_remove(struct platform_device *pdev)
+{
+ struct mxc_hdmi *hdmi = platform_get_drvdata(pdev);
+ int irq = platform_get_irq(pdev, 0);
+
+ fb_unregister_client(&hdmi->nb);
+
+ mxc_dispdrv_puthandle(hdmi->disp_mxc_hdmi);
+ mxc_dispdrv_unregister(hdmi->disp_mxc_hdmi);
+ iounmap(hdmi->gpr_base);
+ /* No new work will be scheduled, wait for running ISR */
+ free_irq(irq, hdmi);
+ kfree(hdmi);
+
+ if (hdmi_regulator)
+ regulator_disable(hdmi_regulator);
+
+ g_hdmi = NULL;
+
+ return 0;
+}
+
+static struct platform_driver mxc_hdmi_driver = {
+ .probe = mxc_hdmi_probe,
+ .remove = mxc_hdmi_remove,
+ .driver = {
+ .name = "mxc_hdmi",
+ .of_match_table = imx_hdmi_dt_ids,
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init mxc_hdmi_init(void)
+{
+ return platform_driver_register(&mxc_hdmi_driver);
+}
+module_init(mxc_hdmi_init);
+
+static void __exit mxc_hdmi_exit(void)
+{
+ if (hdmi_major > 0) {
+ device_destroy(hdmi_class, MKDEV(hdmi_major, 0));
+ class_destroy(hdmi_class);
+ unregister_chrdev(hdmi_major, "mxc_hdmi");
+ hdmi_major = 0;
+ }
+
+ platform_driver_unregister(&mxc_hdmi_driver);
+}
+module_exit(mxc_hdmi_exit);
+
+static int mxc_hdmi_i2c_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ if (!i2c_check_functionality(client->adapter,
+ I2C_FUNC_SMBUS_BYTE | I2C_FUNC_I2C))
+ return -ENODEV;
+
+ hdmi_i2c = client;
+
+ return 0;
+}
+
+static int mxc_hdmi_i2c_remove(struct i2c_client *client)
+{
+ hdmi_i2c = NULL;
+ return 0;
+}
+
+static const struct of_device_id imx_hdmi_i2c_match[] = {
+ { .compatible = "fsl,imx6-hdmi-i2c", },
+ { /* sentinel */ }
+};
+
+static const struct i2c_device_id mxc_hdmi_i2c_id[] = {
+ { "mxc_hdmi_i2c", 0 },
+ {},
+};
+MODULE_DEVICE_TABLE(i2c, mxc_hdmi_i2c_id);
+
+static struct i2c_driver mxc_hdmi_i2c_driver = {
+ .driver = {
+ .name = "mxc_hdmi_i2c",
+ .of_match_table = imx_hdmi_i2c_match,
+ },
+ .probe = mxc_hdmi_i2c_probe,
+ .remove = mxc_hdmi_i2c_remove,
+ .id_table = mxc_hdmi_i2c_id,
+};
+
+static int __init mxc_hdmi_i2c_init(void)
+{
+ return i2c_add_driver(&mxc_hdmi_i2c_driver);
+}
+
+static void __exit mxc_hdmi_i2c_exit(void)
+{
+ i2c_del_driver(&mxc_hdmi_i2c_driver);
+}
+
+module_init(mxc_hdmi_i2c_init);
+module_exit(mxc_hdmi_i2c_exit);
+
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
diff --git a/drivers/video/fbdev/mxc/mxc_ipuv3_fb.c b/drivers/video/fbdev/mxc/mxc_ipuv3_fb.c
new file mode 100644
index 000000000000..c6001b6a73d2
--- /dev/null
+++ b/drivers/video/fbdev/mxc/mxc_ipuv3_fb.c
@@ -0,0 +1,3673 @@
+/*
+ * Copyright 2004-2016 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/*!
+ * @defgroup Framebuffer Framebuffer Driver for SDC and ADC.
+ */
+
+/*!
+ * @file mxcfb.c
+ *
+ * @brief MXC Frame buffer driver for SDC
+ *
+ * @ingroup Framebuffer
+ */
+
+/*!
+ * Include files
+ */
+#include <linux/clk.h>
+#include <linux/console.h>
+#include <linux/delay.h>
+#include <linux/dma-mapping.h>
+#include <linux/errno.h>
+#include <linux/fb.h>
+#include <linux/fsl_devices.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/ioport.h>
+#include <linux/ipu.h>
+#include <linux/ipu-v3.h>
+#include <linux/ipu-v3-pre.h>
+#include <linux/ipu-v3-prg.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/mxcfb.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/time.h>
+#include <linux/uaccess.h>
+
+#include "mxc_dispdrv.h"
+
+/*
+ * Driver name
+ */
+#define MXCFB_NAME "mxc_sdc_fb"
+
+/* Display port number */
+#define MXCFB_PORT_NUM 2
+/*!
+ * Structure containing the MXC specific framebuffer information.
+ */
+struct mxcfb_info {
+ int default_bpp;
+ int cur_blank;
+ int next_blank;
+ ipu_channel_t ipu_ch;
+ int ipu_id;
+ int ipu_di;
+ int pre_num;
+ u32 ipu_di_pix_fmt;
+ bool ipu_int_clk;
+ bool overlay;
+ bool alpha_chan_en;
+ bool late_init;
+ bool first_set_par;
+ bool resolve;
+ bool prefetch;
+ bool on_the_fly;
+ uint32_t final_pfmt;
+ unsigned long gpu_sec_buf_off;
+ unsigned long base;
+ uint32_t x_crop;
+ uint32_t y_crop;
+ unsigned int sec_buf_off;
+ unsigned int trd_buf_off;
+ dma_addr_t store_addr;
+ dma_addr_t alpha_phy_addr0;
+ dma_addr_t alpha_phy_addr1;
+ void *alpha_virt_addr0;
+ void *alpha_virt_addr1;
+ uint32_t alpha_mem_len;
+ uint32_t ipu_ch_irq;
+ uint32_t ipu_ch_nf_irq;
+ uint32_t ipu_alp_ch_irq;
+ uint32_t cur_ipu_buf;
+ uint32_t cur_ipu_alpha_buf;
+
+ u32 pseudo_palette[16];
+
+ bool mode_found;
+ struct completion flip_complete;
+ struct completion alpha_flip_complete;
+ struct completion vsync_complete;
+ struct completion otf_complete; /* on the fly */
+
+ void *ipu;
+ struct fb_info *ovfbi;
+
+ struct mxc_dispdrv_handle *dispdrv;
+
+ struct fb_var_screeninfo cur_var;
+ uint32_t cur_ipu_pfmt;
+ uint32_t cur_fb_pfmt;
+ bool cur_prefetch;
+ spinlock_t spin_lock; /* for PRE small yres cases */
+ struct ipu_pre_context *pre_config;
+};
+
+struct mxcfb_pfmt {
+ u32 fb_pix_fmt;
+ int bpp;
+ struct fb_bitfield red;
+ struct fb_bitfield green;
+ struct fb_bitfield blue;
+ struct fb_bitfield transp;
+};
+
+struct mxcfb_tile_block {
+ u32 fb_pix_fmt;
+ int bw; /* in pixel */
+ int bh; /* in pixel */
+};
+
+#define NA (~0x0UL)
+static const struct mxcfb_pfmt mxcfb_pfmts[] = {
+ /* pixel bpp red green blue transp */
+ {IPU_PIX_FMT_RGB565, 16, {11, 5, 0}, { 5, 6, 0}, { 0, 5, 0}, { 0, 0, 0} },
+ {IPU_PIX_FMT_BGRA4444, 16, { 8, 4, 0}, { 4, 4, 0}, { 0, 4, 0}, { 12, 4, 0} },
+ {IPU_PIX_FMT_BGRA5551, 16, {10, 5, 0}, { 5, 5, 0}, { 0, 5, 0}, { 15, 1, 0} },
+ {IPU_PIX_FMT_RGB24, 24, { 0, 8, 0}, { 8, 8, 0}, {16, 8, 0}, { 0, 0, 0} },
+ {IPU_PIX_FMT_BGR24, 24, {16, 8, 0}, { 8, 8, 0}, { 0, 8, 0}, { 0, 0, 0} },
+ {IPU_PIX_FMT_RGB32, 32, { 0, 8, 0}, { 8, 8, 0}, {16, 8, 0}, {24, 8, 0} },
+ {IPU_PIX_FMT_BGR32, 32, {16, 8, 0}, { 8, 8, 0}, { 0, 8, 0}, {24, 8, 0} },
+ {IPU_PIX_FMT_ABGR32, 32, {24, 8, 0}, {16, 8, 0}, { 8, 8, 0}, { 0, 8, 0} },
+ /* pixel bpp red green blue transp */
+ {IPU_PIX_FMT_YUV420P2, 12, {NA, NA, NA}, {NA, NA, NA}, {NA, NA, NA}, {NA, NA, NA} },
+ {IPU_PIX_FMT_YUV420P, 12, {NA, NA, NA}, {NA, NA, NA}, {NA, NA, NA}, {NA, NA, NA} },
+ {IPU_PIX_FMT_YVU420P, 12, {NA, NA, NA}, {NA, NA, NA}, {NA, NA, NA}, {NA, NA, NA} },
+ {IPU_PIX_FMT_NV12, 12, {NA, NA, NA}, {NA, NA, NA}, {NA, NA, NA}, {NA, NA, NA} },
+ {PRE_PIX_FMT_NV21, 12, {NA, NA, NA}, {NA, NA, NA}, {NA, NA, NA}, {NA, NA, NA} },
+ {IPU_PIX_FMT_NV16, 16, {NA, NA, NA}, {NA, NA, NA}, {NA, NA, NA}, {NA, NA, NA} },
+ {PRE_PIX_FMT_NV61, 16, {NA, NA, NA}, {NA, NA, NA}, {NA, NA, NA}, {NA, NA, NA} },
+ {IPU_PIX_FMT_YUV422P, 16, {NA, NA, NA}, {NA, NA, NA}, {NA, NA, NA}, {NA, NA, NA} },
+ {IPU_PIX_FMT_YVU422P, 16, {NA, NA, NA}, {NA, NA, NA}, {NA, NA, NA}, {NA, NA, NA} },
+ {IPU_PIX_FMT_UYVY, 16, {NA, NA, NA}, {NA, NA, NA}, {NA, NA, NA}, {NA, NA, NA} },
+ {IPU_PIX_FMT_YUYV, 16, {NA, NA, NA}, {NA, NA, NA}, {NA, NA, NA}, {NA, NA, NA} },
+ {IPU_PIX_FMT_YUV444, 24, {NA, NA, NA}, {NA, NA, NA}, {NA, NA, NA}, {NA, NA, NA} },
+ {IPU_PIX_FMT_YUV444P, 24, {NA, NA, NA}, {NA, NA, NA}, {NA, NA, NA}, {NA, NA, NA} },
+ {IPU_PIX_FMT_AYUV, 32, {NA, NA, NA}, {NA, NA, NA}, {NA, NA, NA}, {NA, NA, NA} },
+ /* pixel bpp red green blue transp */
+ {IPU_PIX_FMT_GPU32_SB_ST, 32, {NA, NA, NA}, {NA, NA, NA}, {NA, NA, NA}, {NA, NA, NA} },
+ {IPU_PIX_FMT_GPU32_SB_SRT, 32, {NA, NA, NA}, {NA, NA, NA}, {NA, NA, NA}, {NA, NA, NA} },
+ {IPU_PIX_FMT_GPU32_ST, 32, {NA, NA, NA}, {NA, NA, NA}, {NA, NA, NA}, {NA, NA, NA} },
+ {IPU_PIX_FMT_GPU32_SRT, 32, {NA, NA, NA}, {NA, NA, NA}, {NA, NA, NA}, {NA, NA, NA} },
+ {IPU_PIX_FMT_GPU16_SB_ST, 16, {NA, NA, NA}, {NA, NA, NA}, {NA, NA, NA}, {NA, NA, NA} },
+ {IPU_PIX_FMT_GPU16_SB_SRT, 16, {NA, NA, NA}, {NA, NA, NA}, {NA, NA, NA}, {NA, NA, NA} },
+ {IPU_PIX_FMT_GPU16_ST, 16, {NA, NA, NA}, {NA, NA, NA}, {NA, NA, NA}, {NA, NA, NA} },
+ {IPU_PIX_FMT_GPU16_SRT, 16, {NA, NA, NA}, {NA, NA, NA}, {NA, NA, NA}, {NA, NA, NA} },
+};
+
+/* Tile fb alignment */
+static const struct mxcfb_tile_block tas[] = {
+ {IPU_PIX_FMT_GPU32_SB_ST, 16, 8},
+ {IPU_PIX_FMT_GPU32_SB_SRT, 64, 128},
+ {IPU_PIX_FMT_GPU32_ST, 16, 4},
+ {IPU_PIX_FMT_GPU32_SRT, 64, 64},
+ {IPU_PIX_FMT_GPU16_SB_ST, 16, 8},
+ {IPU_PIX_FMT_GPU16_SB_SRT, 64, 128},
+ {IPU_PIX_FMT_GPU16_ST, 16, 4},
+ {IPU_PIX_FMT_GPU16_SRT, 64, 64},
+};
+
+/* The block can be resolved */
+static const struct mxcfb_tile_block trs[] = {
+ /* pixel w h */
+ {IPU_PIX_FMT_GPU32_SB_ST, 16, 4},
+ {IPU_PIX_FMT_GPU32_SB_SRT, 16, 4},
+ {IPU_PIX_FMT_GPU32_ST, 16, 4},
+ {IPU_PIX_FMT_GPU32_SRT, 16, 4},
+ {IPU_PIX_FMT_GPU16_SB_ST, 16, 4},
+ {IPU_PIX_FMT_GPU16_SB_SRT, 16, 4},
+ {IPU_PIX_FMT_GPU16_ST, 16, 4},
+ {IPU_PIX_FMT_GPU16_SRT, 16, 4},
+};
+
+struct mxcfb_alloc_list {
+ struct list_head list;
+ dma_addr_t phy_addr;
+ void *cpu_addr;
+ u32 size;
+};
+
+enum {
+ BOTH_ON,
+ SRC_ON,
+ TGT_ON,
+ BOTH_OFF
+};
+
+static bool g_dp_in_use[2];
+LIST_HEAD(fb_alloc_list);
+
+/* Return default standard(RGB) pixel format */
+static uint32_t bpp_to_pixfmt(int bpp)
+{
+ uint32_t pixfmt = 0;
+
+ switch (bpp) {
+ case 24:
+ pixfmt = IPU_PIX_FMT_BGR24;
+ break;
+ case 32:
+ pixfmt = IPU_PIX_FMT_BGR32;
+ break;
+ case 16:
+ pixfmt = IPU_PIX_FMT_RGB565;
+ break;
+ }
+ return pixfmt;
+}
+
+static inline int bitfield_is_equal(struct fb_bitfield f1,
+ struct fb_bitfield f2)
+{
+ return !memcmp(&f1, &f2, sizeof(f1));
+}
+
+static int pixfmt_to_var(uint32_t pixfmt, struct fb_var_screeninfo *var)
+{
+ int i, ret = -1;
+
+ for (i = 0; i < ARRAY_SIZE(mxcfb_pfmts); i++) {
+ if (pixfmt == mxcfb_pfmts[i].fb_pix_fmt) {
+ var->red = mxcfb_pfmts[i].red;
+ var->green = mxcfb_pfmts[i].green;
+ var->blue = mxcfb_pfmts[i].blue;
+ var->transp = mxcfb_pfmts[i].transp;
+ var->bits_per_pixel = mxcfb_pfmts[i].bpp;
+ ret = 0;
+ break;
+ }
+ }
+ return ret;
+}
+
+static int bpp_to_var(int bpp, struct fb_var_screeninfo *var)
+{
+ uint32_t pixfmt = 0;
+
+ if (var->nonstd)
+ return -1;
+
+ pixfmt = bpp_to_pixfmt(bpp);
+ if (pixfmt)
+ return pixfmt_to_var(pixfmt, var);
+ else
+ return -1;
+}
+
+static int check_var_pixfmt(struct fb_var_screeninfo *var)
+{
+ int i, ret = -1;
+
+ if (var->nonstd) {
+ for (i = 0; i < ARRAY_SIZE(mxcfb_pfmts); i++) {
+ if (mxcfb_pfmts[i].fb_pix_fmt == var->nonstd) {
+ var->bits_per_pixel = mxcfb_pfmts[i].bpp;
+ ret = 0;
+ break;
+ }
+ }
+ return ret;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(mxcfb_pfmts); i++) {
+ if (bitfield_is_equal(var->red, mxcfb_pfmts[i].red) &&
+ bitfield_is_equal(var->green, mxcfb_pfmts[i].green) &&
+ bitfield_is_equal(var->blue, mxcfb_pfmts[i].blue) &&
+ bitfield_is_equal(var->transp, mxcfb_pfmts[i].transp) &&
+ var->bits_per_pixel == mxcfb_pfmts[i].bpp) {
+ ret = 0;
+ break;
+ }
+ }
+ return ret;
+}
+
+static uint32_t fb_to_store_pixfmt(uint32_t fb_pixfmt)
+{
+ switch (fb_pixfmt) {
+ case IPU_PIX_FMT_RGB32:
+ case IPU_PIX_FMT_BGR32:
+ case IPU_PIX_FMT_ABGR32:
+ case IPU_PIX_FMT_RGB24:
+ case IPU_PIX_FMT_BGR24:
+ case IPU_PIX_FMT_RGB565:
+ case IPU_PIX_FMT_BGRA4444:
+ case IPU_PIX_FMT_BGRA5551:
+ case IPU_PIX_FMT_UYVY:
+ case IPU_PIX_FMT_YUYV:
+ case IPU_PIX_FMT_YUV444:
+ case IPU_PIX_FMT_AYUV:
+ return fb_pixfmt;
+ case IPU_PIX_FMT_YUV422P:
+ case IPU_PIX_FMT_YVU422P:
+ case IPU_PIX_FMT_YUV420P2:
+ case IPU_PIX_FMT_YVU420P:
+ case IPU_PIX_FMT_NV12:
+ case PRE_PIX_FMT_NV21:
+ case IPU_PIX_FMT_NV16:
+ case PRE_PIX_FMT_NV61:
+ case IPU_PIX_FMT_YUV420P:
+ return IPU_PIX_FMT_UYVY;
+ case IPU_PIX_FMT_YUV444P:
+ return IPU_PIX_FMT_AYUV;
+ default:
+ return 0;
+ }
+}
+
+static uint32_t fbi_to_pixfmt(struct fb_info *fbi, bool original_fb)
+{
+ struct mxcfb_info *mxc_fbi = (struct mxcfb_info *)fbi->par;
+ int i;
+ uint32_t pixfmt = 0;
+
+ if (fbi->var.nonstd) {
+ if (mxc_fbi->prefetch && !original_fb) {
+ if (ipu_pixel_format_is_gpu_tile(fbi->var.nonstd))
+ goto next;
+
+ return fb_to_store_pixfmt(fbi->var.nonstd);
+ } else {
+ return fbi->var.nonstd;
+ }
+ }
+
+next:
+ for (i = 0; i < ARRAY_SIZE(mxcfb_pfmts); i++) {
+ if (bitfield_is_equal(fbi->var.red, mxcfb_pfmts[i].red) &&
+ bitfield_is_equal(fbi->var.green, mxcfb_pfmts[i].green) &&
+ bitfield_is_equal(fbi->var.blue, mxcfb_pfmts[i].blue) &&
+ bitfield_is_equal(fbi->var.transp, mxcfb_pfmts[i].transp)) {
+ pixfmt = mxcfb_pfmts[i].fb_pix_fmt;
+ break;
+ }
+ }
+
+ if (pixfmt == 0)
+ dev_err(fbi->device, "cannot get pixel format\n");
+
+ return pixfmt;
+}
+
+static void fmt_to_tile_alignment(uint32_t fmt, int *bw, int *bh)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(tas); i++) {
+ if (tas[i].fb_pix_fmt == fmt) {
+ *bw = tas[i].bw;
+ *bh = tas[i].bh;
+ }
+ }
+
+ BUG_ON(!(*bw) || !(*bh));
+}
+
+static void fmt_to_tile_block(uint32_t fmt, int *bw, int *bh)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(trs); i++) {
+ if (trs[i].fb_pix_fmt == fmt) {
+ *bw = trs[i].bw;
+ *bh = trs[i].bh;
+ }
+ }
+
+ BUG_ON(!(*bw) || !(*bh));
+}
+
+static struct fb_info *found_registered_fb(ipu_channel_t ipu_ch, int ipu_id)
+{
+ int i;
+ struct mxcfb_info *mxc_fbi;
+ struct fb_info *fbi = NULL;
+
+ for (i = 0; i < num_registered_fb; i++) {
+ mxc_fbi =
+ ((struct mxcfb_info *)(registered_fb[i]->par));
+
+ if ((mxc_fbi->ipu_ch == ipu_ch) &&
+ (mxc_fbi->ipu_id == ipu_id)) {
+ fbi = registered_fb[i];
+ break;
+ }
+ }
+ return fbi;
+}
+
+static irqreturn_t mxcfb_irq_handler(int irq, void *dev_id);
+static irqreturn_t mxcfb_nf_irq_handler(int irq, void *dev_id);
+static int mxcfb_blank(int blank, struct fb_info *info);
+static int mxcfb_map_video_memory(struct fb_info *fbi);
+static int mxcfb_unmap_video_memory(struct fb_info *fbi);
+static int mxcfb_ioctl(struct fb_info *fbi, unsigned int cmd,
+ unsigned long arg);
+
+/*
+ * Set fixed framebuffer parameters based on variable settings.
+ *
+ * @param info framebuffer information pointer
+ */
+static int mxcfb_set_fix(struct fb_info *info)
+{
+ struct fb_fix_screeninfo *fix = &info->fix;
+ struct fb_var_screeninfo *var = &info->var;
+
+ fix->line_length = var->xres_virtual * var->bits_per_pixel / 8;
+
+ fix->type = FB_TYPE_PACKED_PIXELS;
+ fix->accel = FB_ACCEL_NONE;
+ fix->visual = FB_VISUAL_TRUECOLOR;
+ fix->xpanstep = 1;
+ fix->ywrapstep = 1;
+ fix->ypanstep = 1;
+
+ return 0;
+}
+
+static int _setup_disp_channel1(struct fb_info *fbi)
+{
+ ipu_channel_params_t params;
+ struct mxcfb_info *mxc_fbi = (struct mxcfb_info *)fbi->par;
+
+ memset(&params, 0, sizeof(params));
+
+ if (mxc_fbi->ipu_ch == MEM_DC_SYNC) {
+ params.mem_dc_sync.di = mxc_fbi->ipu_di;
+ if (fbi->var.vmode & FB_VMODE_INTERLACED)
+ params.mem_dc_sync.interlaced = true;
+ params.mem_dc_sync.out_pixel_fmt = mxc_fbi->ipu_di_pix_fmt;
+ params.mem_dc_sync.in_pixel_fmt = mxc_fbi->on_the_fly ?
+ mxc_fbi->final_pfmt :
+ fbi_to_pixfmt(fbi, false);
+ } else {
+ params.mem_dp_bg_sync.di = mxc_fbi->ipu_di;
+ if (fbi->var.vmode & FB_VMODE_INTERLACED)
+ params.mem_dp_bg_sync.interlaced = true;
+ params.mem_dp_bg_sync.out_pixel_fmt = mxc_fbi->ipu_di_pix_fmt;
+ params.mem_dp_bg_sync.in_pixel_fmt = mxc_fbi->on_the_fly ?
+ mxc_fbi->final_pfmt :
+ fbi_to_pixfmt(fbi, false);
+ if (mxc_fbi->alpha_chan_en)
+ params.mem_dp_bg_sync.alpha_chan_en = true;
+ }
+ if (ipu_init_channel(mxc_fbi->ipu, mxc_fbi->ipu_ch, &params) < 0) {
+ dev_err(fbi->device, "init ipu channel fail\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int _setup_disp_channel2(struct fb_info *fbi)
+{
+ int retval = 0;
+ struct mxcfb_info *mxc_fbi = (struct mxcfb_info *)fbi->par;
+ int fb_stride, ipu_stride, bw = 0, bh = 0;
+ unsigned long base, ipu_base;
+ unsigned int fr_xoff, fr_yoff, fr_w, fr_h;
+ unsigned int prg_width;
+ struct ipu_pre_context pre;
+ bool post_pre_disable = false;
+
+ switch (fbi_to_pixfmt(fbi, true)) {
+ case IPU_PIX_FMT_YUV420P2:
+ case IPU_PIX_FMT_YVU420P:
+ case IPU_PIX_FMT_NV12:
+ case PRE_PIX_FMT_NV21:
+ case IPU_PIX_FMT_NV16:
+ case PRE_PIX_FMT_NV61:
+ case IPU_PIX_FMT_YUV422P:
+ case IPU_PIX_FMT_YVU422P:
+ case IPU_PIX_FMT_YUV420P:
+ case IPU_PIX_FMT_YUV444P:
+ fb_stride = fbi->var.xres_virtual;
+ break;
+ default:
+ fb_stride = fbi->fix.line_length;
+ }
+
+ base = fbi->fix.smem_start;
+ fr_xoff = fbi->var.xoffset;
+ fr_w = fbi->var.xres_virtual;
+ if (!(fbi->var.vmode & FB_VMODE_YWRAP)) {
+ dev_dbg(fbi->device, "Y wrap disabled\n");
+ fr_yoff = fbi->var.yoffset % fbi->var.yres;
+ fr_h = fbi->var.yres;
+ base += fbi->fix.line_length * fbi->var.yres *
+ (fbi->var.yoffset / fbi->var.yres);
+ if (ipu_pixel_format_is_split_gpu_tile(fbi->var.nonstd))
+ base += (mxc_fbi->gpu_sec_buf_off -
+ fbi->fix.line_length * fbi->var.yres / 2) *
+ (fbi->var.yoffset / fbi->var.yres);
+ } else {
+ dev_dbg(fbi->device, "Y wrap enabled\n");
+ fr_yoff = fbi->var.yoffset;
+ fr_h = fbi->var.yres_virtual;
+ }
+
+ /* pixel block alignment for resolving cases */
+ if (mxc_fbi->resolve) {
+ fmt_to_tile_block(fbi->var.nonstd, &bw, &bh);
+ } else {
+ base += fr_yoff * fb_stride + fr_xoff *
+ bytes_per_pixel(fbi_to_pixfmt(fbi, true));
+ }
+
+ if (!mxc_fbi->on_the_fly)
+ mxc_fbi->cur_ipu_buf = 2;
+ init_completion(&mxc_fbi->flip_complete);
+ /*
+ * We don't need to wait for vsync at the first time
+ * we do pan display after fb is initialized, as IPU will
+ * switch to the newly selected buffer automatically,
+ * so we call complete() for both mxc_fbi->flip_complete
+ * and mxc_fbi->alpha_flip_complete.
+ */
+ if (!mxc_fbi->prefetch ||
+ (mxc_fbi->prefetch && !ipu_pre_yres_is_small(fbi->var.yres)))
+ complete(&mxc_fbi->flip_complete);
+ if (mxc_fbi->alpha_chan_en) {
+ mxc_fbi->cur_ipu_alpha_buf = 1;
+ init_completion(&mxc_fbi->alpha_flip_complete);
+ complete(&mxc_fbi->alpha_flip_complete);
+ }
+
+ if (mxc_fbi->prefetch) {
+ struct ipu_prg_config prg;
+ struct fb_var_screeninfo from_var, to_var;
+
+ if (mxc_fbi->pre_num < 0) {
+ mxc_fbi->pre_num = ipu_pre_alloc(mxc_fbi->ipu_id,
+ mxc_fbi->ipu_ch);
+ if (mxc_fbi->pre_num < 0) {
+ dev_dbg(fbi->device, "failed to alloc PRE\n");
+ mxc_fbi->prefetch = mxc_fbi->cur_prefetch;
+ mxc_fbi->resolve = false;
+ if (!mxc_fbi->on_the_fly)
+ mxc_fbi->cur_blank = FB_BLANK_POWERDOWN;
+ return mxc_fbi->pre_num;
+ }
+ }
+ pre.repeat = true;
+ pre.vflip = fbi->var.rotate ? true : false;
+ pre.handshake_en = true;
+ pre.hsk_abort_en = true;
+ pre.hsk_line_num = 0;
+ pre.sdw_update = true;
+ pre.cur_buf = base;
+ pre.next_buf = pre.cur_buf;
+ if (fbi->var.vmode & FB_VMODE_INTERLACED) {
+ pre.interlaced = 2;
+ if (mxc_fbi->resolve) {
+ pre.field_inverse = fbi->var.rotate;
+ pre.interlace_offset = 0;
+ } else {
+ pre.field_inverse = 0;
+ if (fbi->var.rotate) {
+ pre.interlace_offset = ~(fbi->var.xres_virtual *
+ bytes_per_pixel(fbi_to_pixfmt(fbi, true))) + 1;
+ pre.cur_buf += fbi->var.xres_virtual * bytes_per_pixel(fbi_to_pixfmt(fbi, true));
+ pre.next_buf = pre.cur_buf;
+ } else {
+ pre.interlace_offset = fbi->var.xres_virtual *
+ bytes_per_pixel(fbi_to_pixfmt(fbi, true));
+ }
+ }
+ } else {
+ pre.interlaced = 0;
+ pre.interlace_offset = 0;
+ }
+ pre.prefetch_mode = mxc_fbi->resolve ? 1 : 0;
+ pre.tile_fmt = mxc_fbi->resolve ? fbi->var.nonstd : 0;
+ pre.read_burst = mxc_fbi->resolve ? 0x4 : 0x3;
+ if (fbi_to_pixfmt(fbi, true) == IPU_PIX_FMT_RGB24 ||
+ fbi_to_pixfmt(fbi, true) == IPU_PIX_FMT_BGR24 ||
+ fbi_to_pixfmt(fbi, true) == IPU_PIX_FMT_YUV444) {
+ if ((fbi->var.xres * 3) % 8 == 0 &&
+ (fbi->var.xres_virtual * 3) % 8 == 0)
+ pre.prefetch_input_bpp = 64;
+ else if ((fbi->var.xres * 3) % 4 == 0 &&
+ (fbi->var.xres_virtual * 3) % 4 == 0)
+ pre.prefetch_input_bpp = 32;
+ else if ((fbi->var.xres * 3) % 2 == 0 &&
+ (fbi->var.xres_virtual * 3) % 2 == 0)
+ pre.prefetch_input_bpp = 16;
+ else
+ pre.prefetch_input_bpp = 8;
+ } else {
+ pre.prefetch_input_bpp =
+ 8 * bytes_per_pixel(fbi_to_pixfmt(fbi, true));
+ }
+ pre.prefetch_input_pixel_fmt = mxc_fbi->resolve ?
+ 0x1 : (fbi->var.nonstd ? fbi->var.nonstd : 0);
+ pre.shift_bypass = (mxc_fbi->on_the_fly &&
+ mxc_fbi->final_pfmt != fbi_to_pixfmt(fbi, false)) ?
+ false : true;
+ pixfmt_to_var(fbi_to_pixfmt(fbi, false), &from_var);
+ pixfmt_to_var(mxc_fbi->final_pfmt, &to_var);
+ if (mxc_fbi->on_the_fly &&
+ (format_to_colorspace(fbi_to_pixfmt(fbi, true)) == RGB) &&
+ (bytes_per_pixel(fbi_to_pixfmt(fbi, true)) == 4)) {
+ pre.prefetch_shift_offset = (from_var.red.offset << to_var.red.offset) |
+ (from_var.green.offset << to_var.green.offset) |
+ (from_var.blue.offset << to_var.blue.offset) |
+ (from_var.transp.offset << to_var.transp.offset);
+ pre.prefetch_shift_width = (to_var.red.length << (to_var.red.offset/2)) |
+ (to_var.green.length << (to_var.green.offset/2)) |
+ (to_var.blue.length << (to_var.blue.offset/2)) |
+ (to_var.transp.length << (to_var.transp.offset/2));
+ } else {
+ pre.prefetch_shift_offset = 0;
+ pre.prefetch_shift_width = 0;
+ }
+ pre.tpr_coor_offset_en = mxc_fbi->resolve ? true : false;
+ pre.prefetch_output_size.left = mxc_fbi->resolve ? (fr_xoff & ~(bw - 1)) : 0;
+ pre.prefetch_output_size.top = mxc_fbi->resolve ? (fr_yoff & ~(bh - 1)) : 0;
+ if (fbi_to_pixfmt(fbi, true) == IPU_PIX_FMT_RGB24 ||
+ fbi_to_pixfmt(fbi, true) == IPU_PIX_FMT_BGR24 ||
+ fbi_to_pixfmt(fbi, true) == IPU_PIX_FMT_YUV444) {
+ pre.prefetch_output_size.width = (fbi->var.xres * 3) /
+ (pre.prefetch_input_bpp / 8);
+ pre.store_output_bpp = pre.prefetch_input_bpp;
+ } else {
+ pre.prefetch_output_size.width = fbi->var.xres;
+ pre.store_output_bpp = 8 *
+ bytes_per_pixel(fbi_to_pixfmt(fbi, false));
+ }
+ pre.prefetch_output_size.height = fbi->var.yres;
+ pre.prefetch_input_active_width = pre.prefetch_output_size.width;
+ if (fbi_to_pixfmt(fbi, true) == IPU_PIX_FMT_RGB24 ||
+ fbi_to_pixfmt(fbi, true) == IPU_PIX_FMT_BGR24 ||
+ fbi_to_pixfmt(fbi, true) == IPU_PIX_FMT_YUV444)
+ pre.prefetch_input_width = (fbi->var.xres_virtual * 3) /
+ (pre.prefetch_input_bpp / 8);
+ else
+ pre.prefetch_input_width = fbi->var.xres_virtual;
+ pre.prefetch_input_height = fbi->var.yres;
+ prg_width = pre.prefetch_output_size.width;
+ if (!(pre.prefetch_input_active_width % 32))
+ pre.block_size = 0;
+ else if (!(pre.prefetch_input_active_width % 16))
+ pre.block_size = 1;
+ else
+ pre.block_size = 0;
+ if (mxc_fbi->resolve) {
+ int bs = pre.block_size ? 16 : 32;
+ pre.prefetch_input_active_width += fr_xoff % bw;
+ if (((fr_xoff % bw) + pre.prefetch_input_active_width) % bs)
+ pre.prefetch_input_active_width =
+ ALIGN(pre.prefetch_input_active_width, bs);
+ pre.prefetch_output_size.width =
+ pre.prefetch_input_active_width;
+ prg_width = pre.prefetch_output_size.width;
+ pre.prefetch_input_height += fr_yoff % bh;
+ if (((fr_yoff % bh) + fbi->var.yres) % 4) {
+ pre.prefetch_input_height =
+ (fbi->var.vmode & FB_VMODE_INTERLACED) ?
+ ALIGN(pre.prefetch_input_height, 8) :
+ ALIGN(pre.prefetch_input_height, 4);
+ } else {
+ if (fbi->var.vmode & FB_VMODE_INTERLACED)
+ pre.prefetch_input_height =
+ ALIGN(pre.prefetch_input_height, 8);
+ }
+ pre.prefetch_output_size.height = pre.prefetch_input_height;
+ }
+
+ /* store output pitch 8-byte aligned */
+ while ((pre.store_output_bpp * prg_width) % 64)
+ prg_width++;
+
+ pre.store_pitch = (pre.store_output_bpp * prg_width) / 8;
+
+ pre.store_en = true;
+ pre.write_burst = 0x3;
+ ipu_get_channel_offset(fbi_to_pixfmt(fbi, true),
+ fbi->var.xres,
+ fr_h,
+ fr_w,
+ 0, 0,
+ fr_yoff,
+ fr_xoff,
+ &pre.sec_buf_off,
+ &pre.trd_buf_off);
+ if (mxc_fbi->resolve)
+ pre.sec_buf_off = mxc_fbi->gpu_sec_buf_off;
+
+ ipu_pre_config(mxc_fbi->pre_num, &pre);
+ ipu_stride = pre.store_pitch;
+ ipu_base = pre.store_addr;
+ mxc_fbi->store_addr = ipu_base;
+
+ if (mxc_fbi->cur_prefetch && mxc_fbi->on_the_fly) {
+ /*
+ * Make sure any pending interrupt is handled so that
+ * the buffer panned can start to be scanned out.
+ */
+ if (!ipu_pre_yres_is_small(fbi->var.yres)) {
+ mxcfb_ioctl(fbi, MXCFB_WAIT_FOR_VSYNC,
+ (unsigned long)fbi->par);
+ mxcfb_ioctl(fbi, MXCFB_WAIT_FOR_VSYNC,
+ (unsigned long)fbi->par);
+ }
+
+ mxc_fbi->pre_config = &pre;
+
+ /*
+ * Write the PRE control register in the flip interrupt
+ * handler in this on-the-fly case to workaround the
+ * SoC design bug recorded by errata ERR009624.
+ */
+ init_completion(&mxc_fbi->otf_complete);
+ ipu_clear_irq(mxc_fbi->ipu, mxc_fbi->ipu_ch_irq);
+ ipu_enable_irq(mxc_fbi->ipu, mxc_fbi->ipu_ch_irq);
+ retval = wait_for_completion_timeout(
+ &mxc_fbi->otf_complete, HZ/2);
+ if (retval == 0) {
+ dev_err(fbi->device, "timeout when waiting "
+ "for on the fly config irq\n");
+ return -ETIMEDOUT;
+ } else {
+ retval = 0;
+ }
+ } else {
+ retval = ipu_pre_set_ctrl(mxc_fbi->pre_num, &pre);
+ if (retval < 0)
+ return retval;
+ }
+
+ if (!mxc_fbi->on_the_fly || !mxc_fbi->cur_prefetch) {
+ prg.id = mxc_fbi->ipu_id;
+ prg.pre_num = mxc_fbi->pre_num;
+ prg.ipu_ch = mxc_fbi->ipu_ch;
+ prg.so = (fbi->var.vmode & FB_VMODE_INTERLACED) ?
+ PRG_SO_INTERLACE : PRG_SO_PROGRESSIVE;
+ prg.vflip = fbi->var.rotate ? true : false;
+ prg.block_mode = mxc_fbi->resolve ? PRG_BLOCK_MODE : PRG_SCAN_MODE;
+ prg.stride = (fbi->var.vmode & FB_VMODE_INTERLACED) ?
+ ipu_stride * 2 : ipu_stride;
+ prg.ilo = (fbi->var.vmode & FB_VMODE_INTERLACED) ?
+ ipu_stride : 0;
+ prg.height = mxc_fbi->resolve ?
+ pre.prefetch_output_size.height : fbi->var.yres;
+ prg.ipu_height = fbi->var.yres;
+ prg.crop_line = mxc_fbi->resolve ?
+ ((fbi->var.vmode & FB_VMODE_INTERLACED) ? (fr_yoff % bh) / 2 : fr_yoff % bh) : 0;
+ prg.baddr = pre.store_addr;
+ prg.offset = mxc_fbi->resolve ? (prg.crop_line * prg.stride +
+ (fr_xoff % bw) *
+ bytes_per_pixel(fbi_to_pixfmt(fbi, false))) : 0;
+ ipu_base += prg.offset;
+ if (ipu_base % 8) {
+ dev_err(fbi->device,
+ "IPU base address is not 8byte aligned\n");
+ return -EINVAL;
+ }
+ mxc_fbi->store_addr = ipu_base;
+
+ if (!mxc_fbi->on_the_fly) {
+ retval = ipu_init_channel_buffer(mxc_fbi->ipu,
+ mxc_fbi->ipu_ch, IPU_INPUT_BUFFER,
+ fbi_to_pixfmt(fbi, false),
+ fbi->var.xres, fbi->var.yres,
+ ipu_stride,
+ fbi->var.rotate,
+ ipu_base,
+ ipu_base,
+ fbi->var.accel_flags &
+ FB_ACCEL_DOUBLE_FLAG ? 0 : ipu_base,
+ 0, 0);
+ if (retval) {
+ dev_err(fbi->device,
+ "ipu_init_channel_buffer error %d\n", retval);
+ return retval;
+ }
+ }
+
+ retval = ipu_prg_config(&prg);
+ if (retval < 0) {
+ dev_err(fbi->device,
+ "failed to configure PRG %d\n", retval);
+ return retval;
+ }
+
+ retval = ipu_pre_enable(mxc_fbi->pre_num);
+ if (retval < 0) {
+ ipu_prg_disable(mxc_fbi->ipu_id, mxc_fbi->pre_num);
+ dev_err(fbi->device,
+ "failed to enable PRE %d\n", retval);
+ return retval;
+ }
+
+ retval = ipu_prg_wait_buf_ready(mxc_fbi->ipu_id,
+ mxc_fbi->pre_num,
+ pre.hsk_line_num,
+ pre.prefetch_output_size.height);
+ if (retval < 0) {
+ ipu_prg_disable(mxc_fbi->ipu_id, mxc_fbi->pre_num);
+ ipu_pre_disable(mxc_fbi->pre_num);
+ ipu_pre_free(&mxc_fbi->pre_num);
+ dev_err(fbi->device, "failed to wait PRG ready %d\n", retval);
+ return retval;
+ }
+ }
+ } else {
+ ipu_stride = fb_stride;
+ ipu_base = base;
+ if (mxc_fbi->on_the_fly)
+ post_pre_disable = true;
+ }
+
+ if (mxc_fbi->on_the_fly && ((mxc_fbi->cur_prefetch && !mxc_fbi->prefetch) ||
+ (!mxc_fbi->cur_prefetch && mxc_fbi->prefetch))) {
+ int htotal = fbi->var.xres + fbi->var.right_margin +
+ fbi->var.hsync_len + fbi->var.left_margin;
+ int vtotal = fbi->var.yres + fbi->var.lower_margin +
+ fbi->var.vsync_len + fbi->var.upper_margin;
+ int timeout = ((htotal * vtotal) / PICOS2KHZ(fbi->var.pixclock)) * 2 ;
+ int cur_buf = 0;
+
+ BUG_ON(timeout <= 0);
+
+ ++mxc_fbi->cur_ipu_buf;
+ mxc_fbi->cur_ipu_buf %= 3;
+ if (ipu_update_channel_buffer(mxc_fbi->ipu, mxc_fbi->ipu_ch,
+ IPU_INPUT_BUFFER,
+ mxc_fbi->cur_ipu_buf,
+ ipu_base) == 0) {
+ if (!mxc_fbi->prefetch)
+ ipu_update_channel_offset(mxc_fbi->ipu,
+ mxc_fbi->ipu_ch,
+ IPU_INPUT_BUFFER,
+ fbi_to_pixfmt(fbi, true),
+ fr_w,
+ fr_h,
+ fr_w,
+ 0, 0,
+ fr_yoff,
+ fr_xoff);
+ ipu_select_buffer(mxc_fbi->ipu, mxc_fbi->ipu_ch,
+ IPU_INPUT_BUFFER, mxc_fbi->cur_ipu_buf);
+ for (; timeout > 0; timeout--) {
+ cur_buf = ipu_get_cur_buffer_idx(mxc_fbi->ipu,
+ mxc_fbi->ipu_ch,
+ IPU_INPUT_BUFFER);
+ if (cur_buf == mxc_fbi->cur_ipu_buf)
+ break;
+
+ udelay(1000);
+ }
+ if (!timeout)
+ dev_err(fbi->device, "Timeout for switch to buf %d "
+ "to address=0x%08lX, current buf %d, "
+ "buf0 ready %d, buf1 ready %d, buf2 ready "
+ "%d\n", mxc_fbi->cur_ipu_buf, ipu_base,
+ ipu_get_cur_buffer_idx(mxc_fbi->ipu,
+ mxc_fbi->ipu_ch,
+ IPU_INPUT_BUFFER),
+ ipu_check_buffer_ready(mxc_fbi->ipu,
+ mxc_fbi->ipu_ch,
+ IPU_INPUT_BUFFER, 0),
+ ipu_check_buffer_ready(mxc_fbi->ipu,
+ mxc_fbi->ipu_ch,
+ IPU_INPUT_BUFFER, 1),
+ ipu_check_buffer_ready(mxc_fbi->ipu,
+ mxc_fbi->ipu_ch,
+ IPU_INPUT_BUFFER, 2));
+ }
+ } else if (!mxc_fbi->on_the_fly && !mxc_fbi->prefetch) {
+ retval = ipu_init_channel_buffer(mxc_fbi->ipu,
+ mxc_fbi->ipu_ch, IPU_INPUT_BUFFER,
+ mxc_fbi->on_the_fly ? mxc_fbi->final_pfmt :
+ fbi_to_pixfmt(fbi, false),
+ fbi->var.xres, fbi->var.yres,
+ ipu_stride,
+ fbi->var.rotate,
+ ipu_base,
+ ipu_base,
+ fbi->var.accel_flags &
+ FB_ACCEL_DOUBLE_FLAG ? 0 : ipu_base,
+ 0, 0);
+ if (retval) {
+ dev_err(fbi->device,
+ "ipu_init_channel_buffer error %d\n", retval);
+ return retval;
+ }
+ /* update u/v offset */
+ if (!mxc_fbi->prefetch)
+ ipu_update_channel_offset(mxc_fbi->ipu, mxc_fbi->ipu_ch,
+ IPU_INPUT_BUFFER,
+ fbi_to_pixfmt(fbi, true),
+ fr_w,
+ fr_h,
+ fr_w,
+ 0, 0,
+ fr_yoff,
+ fr_xoff);
+ }
+
+ if (post_pre_disable) {
+ ipu_prg_disable(mxc_fbi->ipu_id, mxc_fbi->pre_num);
+ ipu_pre_disable(mxc_fbi->pre_num);
+ ipu_pre_free(&mxc_fbi->pre_num);
+ }
+
+ if (mxc_fbi->alpha_chan_en) {
+ retval = ipu_init_channel_buffer(mxc_fbi->ipu,
+ mxc_fbi->ipu_ch,
+ IPU_ALPHA_IN_BUFFER,
+ IPU_PIX_FMT_GENERIC,
+ fbi->var.xres, fbi->var.yres,
+ fbi->var.xres,
+ fbi->var.rotate,
+ mxc_fbi->alpha_phy_addr1,
+ mxc_fbi->alpha_phy_addr0,
+ 0,
+ 0, 0);
+ if (retval) {
+ dev_err(fbi->device,
+ "ipu_init_channel_buffer error %d\n", retval);
+ return retval;
+ }
+ }
+
+ return retval;
+}
+
+static bool mxcfb_need_to_set_par(struct fb_info *fbi)
+{
+ struct mxcfb_info *mxc_fbi = fbi->par;
+
+ if ((fbi->var.activate & FB_ACTIVATE_FORCE) &&
+ (fbi->var.activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW)
+ return true;
+
+ /*
+ * Ignore xoffset and yoffset update,
+ * because pan display handles this case.
+ */
+ mxc_fbi->cur_var.xoffset = fbi->var.xoffset;
+ mxc_fbi->cur_var.yoffset = fbi->var.yoffset;
+
+ return !!memcmp(&mxc_fbi->cur_var, &fbi->var,
+ sizeof(struct fb_var_screeninfo));
+}
+
+static bool mxcfb_can_set_par_on_the_fly(struct fb_info *fbi,
+ uint32_t *final_pfmt)
+{
+ struct mxcfb_info *mxc_fbi = fbi->par;
+ struct fb_var_screeninfo cur_var = mxc_fbi->cur_var;
+ uint32_t cur_pfmt = mxc_fbi->cur_ipu_pfmt;
+ uint32_t new_pfmt = fbi_to_pixfmt(fbi, false);
+ uint32_t new_fb_pfmt = fbi_to_pixfmt(fbi, true);
+ int cur_bpp, new_bpp, cur_bw, cur_bh, new_bw, new_bh;
+ unsigned int mem_len;
+ ipu_color_space_t cur_space, new_space;
+
+ cur_space = format_to_colorspace(cur_pfmt);
+ new_space = format_to_colorspace(new_pfmt);
+
+ cur_bpp = bytes_per_pixel(cur_pfmt);
+ new_bpp = bytes_per_pixel(new_pfmt);
+
+ if (mxc_fbi->first_set_par || mxc_fbi->cur_blank != FB_BLANK_UNBLANK)
+ return false;
+
+ if (!mxc_fbi->prefetch && !mxc_fbi->cur_prefetch)
+ return false;
+
+ if (!mxc_fbi->prefetch && cur_pfmt != new_pfmt)
+ return false;
+
+ if (cur_space == RGB && (cur_bpp == 2 || cur_bpp == 3) &&
+ cur_pfmt != new_pfmt)
+ return false;
+
+ if (!(mxc_fbi->cur_prefetch && mxc_fbi->prefetch) &&
+ ((cur_var.xres_virtual != fbi->var.xres_virtual) ||
+ (cur_var.xres != cur_var.xres_virtual) ||
+ (fbi->var.xres != fbi->var.xres_virtual)))
+ return false;
+
+ if (cur_space != new_space ||
+ (new_space == RGB && cur_bpp != new_bpp))
+ return false;
+
+ if (new_space == YCbCr)
+ return false;
+
+ mem_len = fbi->var.yres_virtual * fbi->fix.line_length;
+ if (mxc_fbi->resolve && mxc_fbi->gpu_sec_buf_off) {
+ if (fbi->var.vmode & FB_VMODE_YWRAP)
+ mem_len = mxc_fbi->gpu_sec_buf_off + mem_len / 2;
+ else
+ mem_len = mxc_fbi->gpu_sec_buf_off *
+ (fbi->var.yres_virtual / fbi->var.yres) + mem_len / 2;
+ }
+ if (mem_len > fbi->fix.smem_len)
+ return false;
+
+ if (mxc_fbi->resolve && ipu_pixel_format_is_gpu_tile(mxc_fbi->cur_fb_pfmt)) {
+ fmt_to_tile_block(mxc_fbi->cur_fb_pfmt, &cur_bw, &cur_bh);
+ fmt_to_tile_block(new_fb_pfmt, &new_bw, &new_bh);
+
+ if (cur_bw != new_bw || cur_bh != new_bh ||
+ cur_var.xoffset % cur_bw != fbi->var.xoffset % new_bw ||
+ cur_var.yoffset % cur_bh != fbi->var.yoffset % new_bh)
+ return false;
+ } else if (mxc_fbi->resolve && mxc_fbi->cur_prefetch) {
+ fmt_to_tile_block(new_fb_pfmt, &new_bw, &new_bh);
+ if (fbi->var.xoffset % new_bw || fbi->var.yoffset % new_bh ||
+ fbi->var.xres % 16 || fbi->var.yres %
+ (fbi->var.vmode & FB_VMODE_INTERLACED ? 8 : 4))
+ return false;
+ } else if (mxc_fbi->prefetch && ipu_pixel_format_is_gpu_tile(mxc_fbi->cur_fb_pfmt)) {
+ fmt_to_tile_block(mxc_fbi->cur_fb_pfmt, &cur_bw, &cur_bh);
+ if (cur_var.xoffset % cur_bw || cur_var.yoffset % cur_bh ||
+ cur_var.xres % 16 || cur_var.yres %
+ (cur_var.vmode & FB_VMODE_INTERLACED ? 8 : 4))
+ return false;
+ }
+
+ cur_var.xres_virtual = fbi->var.xres_virtual;
+ cur_var.yres_virtual = fbi->var.yres_virtual;
+ cur_var.xoffset = fbi->var.xoffset;
+ cur_var.yoffset = fbi->var.yoffset;
+ cur_var.red = fbi->var.red;
+ cur_var.green = fbi->var.green;
+ cur_var.blue = fbi->var.blue;
+ cur_var.transp = fbi->var.transp;
+ cur_var.nonstd = fbi->var.nonstd;
+ if (memcmp(&cur_var, &fbi->var,
+ sizeof(struct fb_var_screeninfo)))
+ return false;
+
+ *final_pfmt = cur_pfmt;
+
+ return true;
+}
+
+static void mxcfb_check_resolve(struct fb_info *fbi)
+{
+ struct mxcfb_info *mxc_fbi = fbi->par;
+
+ switch (fbi->var.nonstd) {
+ case IPU_PIX_FMT_GPU32_ST:
+ case IPU_PIX_FMT_GPU32_SRT:
+ case IPU_PIX_FMT_GPU16_ST:
+ case IPU_PIX_FMT_GPU16_SRT:
+ mxc_fbi->gpu_sec_buf_off = 0;
+ case IPU_PIX_FMT_GPU32_SB_ST:
+ case IPU_PIX_FMT_GPU32_SB_SRT:
+ case IPU_PIX_FMT_GPU16_SB_ST:
+ case IPU_PIX_FMT_GPU16_SB_SRT:
+ mxc_fbi->prefetch = true;
+ mxc_fbi->resolve = true;
+ break;
+ default:
+ mxc_fbi->resolve = false;
+ }
+}
+
+static void mxcfb_check_yuv(struct fb_info *fbi)
+{
+ struct mxcfb_info *mxc_fbi = fbi->par;
+
+ if (fbi->var.vmode & FB_VMODE_INTERLACED) {
+ if (ipu_pixel_format_is_multiplanar_yuv(fbi_to_pixfmt(fbi, true)))
+ mxc_fbi->prefetch = false;
+ } else {
+ if (fbi->var.nonstd == PRE_PIX_FMT_NV21 ||
+ fbi->var.nonstd == PRE_PIX_FMT_NV61)
+ mxc_fbi->prefetch = true;
+ }
+}
+
+/*
+ * Set framebuffer parameters and change the operating mode.
+ *
+ * @param info framebuffer information pointer
+ */
+static int mxcfb_set_par(struct fb_info *fbi)
+{
+ int retval = 0;
+ u32 mem_len, alpha_mem_len;
+ ipu_di_signal_cfg_t sig_cfg;
+ struct mxcfb_info *mxc_fbi = (struct mxcfb_info *)fbi->par;
+ uint32_t final_pfmt = 0;
+ int16_t ov_pos_x = 0, ov_pos_y = 0;
+ int ov_pos_ret = 0;
+ struct mxcfb_info *mxc_fbi_fg = NULL;
+ bool ovfbi_enable = false, on_the_fly;
+
+ if (ipu_ch_param_bad_alpha_pos(fbi_to_pixfmt(fbi, true)) &&
+ mxc_fbi->alpha_chan_en) {
+ dev_err(fbi->device, "Bad pixel format for "
+ "graphics plane fb\n");
+ return -EINVAL;
+ }
+
+ if (mxc_fbi->ovfbi)
+ mxc_fbi_fg = (struct mxcfb_info *)mxc_fbi->ovfbi->par;
+
+ if (mxc_fbi->ovfbi && mxc_fbi_fg)
+ if (mxc_fbi_fg->next_blank == FB_BLANK_UNBLANK)
+ ovfbi_enable = true;
+
+ if (!mxcfb_need_to_set_par(fbi))
+ return 0;
+
+ dev_dbg(fbi->device, "Reconfiguring framebuffer\n");
+
+ if (fbi->var.xres == 0 || fbi->var.yres == 0)
+ return 0;
+
+ mxcfb_set_fix(fbi);
+
+ mxcfb_check_resolve(fbi);
+
+ mxcfb_check_yuv(fbi);
+
+ on_the_fly = mxcfb_can_set_par_on_the_fly(fbi, &final_pfmt);
+ mxc_fbi->on_the_fly = on_the_fly;
+ mxc_fbi->final_pfmt = final_pfmt;
+
+ if (on_the_fly)
+ dev_dbg(fbi->device, "Reconfiguring framebuffer on the fly\n");
+
+ if (ovfbi_enable) {
+ ov_pos_ret = ipu_disp_get_window_pos(
+ mxc_fbi_fg->ipu, mxc_fbi_fg->ipu_ch,
+ &ov_pos_x, &ov_pos_y);
+ if (ov_pos_ret < 0)
+ dev_err(fbi->device, "Get overlay pos failed, dispdrv:%s.\n",
+ mxc_fbi->dispdrv->drv->name);
+
+ if (!on_the_fly) {
+ ipu_clear_irq(mxc_fbi_fg->ipu, mxc_fbi_fg->ipu_ch_irq);
+ ipu_disable_irq(mxc_fbi_fg->ipu, mxc_fbi_fg->ipu_ch_irq);
+ ipu_clear_irq(mxc_fbi_fg->ipu, mxc_fbi_fg->ipu_ch_nf_irq);
+ ipu_disable_irq(mxc_fbi_fg->ipu, mxc_fbi_fg->ipu_ch_nf_irq);
+ ipu_disable_channel(mxc_fbi_fg->ipu, mxc_fbi_fg->ipu_ch, true);
+ ipu_uninit_channel(mxc_fbi_fg->ipu, mxc_fbi_fg->ipu_ch);
+ if (mxc_fbi_fg->cur_prefetch) {
+ ipu_prg_disable(mxc_fbi_fg->ipu_id, mxc_fbi_fg->pre_num);
+ ipu_pre_disable(mxc_fbi_fg->pre_num);
+ ipu_pre_free(&mxc_fbi_fg->pre_num);
+ }
+ }
+ }
+
+ if (!on_the_fly) {
+ ipu_clear_irq(mxc_fbi->ipu, mxc_fbi->ipu_ch_irq);
+ ipu_disable_irq(mxc_fbi->ipu, mxc_fbi->ipu_ch_irq);
+ ipu_clear_irq(mxc_fbi->ipu, mxc_fbi->ipu_ch_nf_irq);
+ ipu_disable_irq(mxc_fbi->ipu, mxc_fbi->ipu_ch_nf_irq);
+ ipu_disable_channel(mxc_fbi->ipu, mxc_fbi->ipu_ch, true);
+ ipu_uninit_channel(mxc_fbi->ipu, mxc_fbi->ipu_ch);
+ if (mxc_fbi->cur_prefetch) {
+ ipu_prg_disable(mxc_fbi->ipu_id, mxc_fbi->pre_num);
+ ipu_pre_disable(mxc_fbi->pre_num);
+ ipu_pre_free(&mxc_fbi->pre_num);
+ }
+ }
+
+ /*
+ * Disable IPU hsp clock if it is enabled for an
+ * additional time in ipu common driver.
+ */
+ if (mxc_fbi->first_set_par && mxc_fbi->late_init)
+ ipu_disable_hsp_clk(mxc_fbi->ipu);
+
+ mem_len = fbi->var.yres_virtual * fbi->fix.line_length;
+ if (mxc_fbi->resolve && mxc_fbi->gpu_sec_buf_off) {
+ if (fbi->var.vmode & FB_VMODE_YWRAP)
+ mem_len = mxc_fbi->gpu_sec_buf_off + mem_len / 2;
+ else
+ mem_len = mxc_fbi->gpu_sec_buf_off *
+ (fbi->var.yres_virtual / fbi->var.yres) + mem_len / 2;
+ }
+ if (!fbi->fix.smem_start || (mem_len > fbi->fix.smem_len)) {
+ if (fbi->fix.smem_start)
+ mxcfb_unmap_video_memory(fbi);
+
+ if (mxcfb_map_video_memory(fbi) < 0)
+ return -ENOMEM;
+ }
+
+ if (mxc_fbi->first_set_par) {
+ /*
+ * Clear the screen in case uboot fb pixel format is not
+ * the same to kernel fb pixel format.
+ */
+ if (mxc_fbi->late_init)
+ memset((char *)fbi->screen_base, 0, fbi->fix.smem_len);
+
+ mxc_fbi->first_set_par = false;
+ }
+
+ if (mxc_fbi->alpha_chan_en) {
+ alpha_mem_len = fbi->var.xres * fbi->var.yres;
+ if ((!mxc_fbi->alpha_phy_addr0 && !mxc_fbi->alpha_phy_addr1) ||
+ (alpha_mem_len > mxc_fbi->alpha_mem_len)) {
+ if (mxc_fbi->alpha_phy_addr0)
+ dma_free_coherent(fbi->device,
+ mxc_fbi->alpha_mem_len,
+ mxc_fbi->alpha_virt_addr0,
+ mxc_fbi->alpha_phy_addr0);
+ if (mxc_fbi->alpha_phy_addr1)
+ dma_free_coherent(fbi->device,
+ mxc_fbi->alpha_mem_len,
+ mxc_fbi->alpha_virt_addr1,
+ mxc_fbi->alpha_phy_addr1);
+
+ mxc_fbi->alpha_virt_addr0 =
+ dma_alloc_coherent(fbi->device,
+ alpha_mem_len,
+ &mxc_fbi->alpha_phy_addr0,
+ GFP_DMA | GFP_KERNEL);
+
+ mxc_fbi->alpha_virt_addr1 =
+ dma_alloc_coherent(fbi->device,
+ alpha_mem_len,
+ &mxc_fbi->alpha_phy_addr1,
+ GFP_DMA | GFP_KERNEL);
+ if (mxc_fbi->alpha_virt_addr0 == NULL ||
+ mxc_fbi->alpha_virt_addr1 == NULL) {
+ dev_err(fbi->device, "mxcfb: dma alloc for"
+ " alpha buffer failed.\n");
+ if (mxc_fbi->alpha_virt_addr0)
+ dma_free_coherent(fbi->device,
+ mxc_fbi->alpha_mem_len,
+ mxc_fbi->alpha_virt_addr0,
+ mxc_fbi->alpha_phy_addr0);
+ if (mxc_fbi->alpha_virt_addr1)
+ dma_free_coherent(fbi->device,
+ mxc_fbi->alpha_mem_len,
+ mxc_fbi->alpha_virt_addr1,
+ mxc_fbi->alpha_phy_addr1);
+ return -ENOMEM;
+ }
+ mxc_fbi->alpha_mem_len = alpha_mem_len;
+ }
+ }
+
+ if (mxc_fbi->next_blank != FB_BLANK_UNBLANK)
+ return retval;
+
+ if (!on_the_fly && mxc_fbi->dispdrv && mxc_fbi->dispdrv->drv->setup) {
+ retval = mxc_fbi->dispdrv->drv->setup(mxc_fbi->dispdrv, fbi);
+ if (retval < 0) {
+ dev_err(fbi->device, "setup error, dispdrv:%s.\n",
+ mxc_fbi->dispdrv->drv->name);
+ return -EINVAL;
+ }
+ }
+
+ if (!on_the_fly) {
+ _setup_disp_channel1(fbi);
+ if (ovfbi_enable)
+ _setup_disp_channel1(mxc_fbi->ovfbi);
+ }
+
+ if (!mxc_fbi->overlay && !on_the_fly) {
+ uint32_t out_pixel_fmt;
+
+ memset(&sig_cfg, 0, sizeof(sig_cfg));
+ if (fbi->var.vmode & FB_VMODE_INTERLACED)
+ sig_cfg.interlaced = true;
+ out_pixel_fmt = mxc_fbi->ipu_di_pix_fmt;
+ if (fbi->var.vmode & FB_VMODE_ODD_FLD_FIRST) /* PAL */
+ sig_cfg.odd_field_first = true;
+ if (mxc_fbi->ipu_int_clk)
+ sig_cfg.int_clk = true;
+ if (fbi->var.sync & FB_SYNC_HOR_HIGH_ACT)
+ sig_cfg.Hsync_pol = true;
+ if (fbi->var.sync & FB_SYNC_VERT_HIGH_ACT)
+ sig_cfg.Vsync_pol = true;
+ if (!(fbi->var.sync & FB_SYNC_CLK_LAT_FALL))
+ sig_cfg.clk_pol = true;
+ if (fbi->var.sync & FB_SYNC_DATA_INVERT)
+ sig_cfg.data_pol = true;
+ if (!(fbi->var.sync & FB_SYNC_OE_LOW_ACT))
+ sig_cfg.enable_pol = true;
+ if (fbi->var.sync & FB_SYNC_CLK_IDLE_EN)
+ sig_cfg.clkidle_en = true;
+
+ dev_dbg(fbi->device, "pixclock = %ul Hz\n",
+ (u32) (PICOS2KHZ(fbi->var.pixclock) * 1000UL));
+
+ if (ipu_init_sync_panel(mxc_fbi->ipu, mxc_fbi->ipu_di,
+ (PICOS2KHZ(fbi->var.pixclock)) * 1000UL,
+ fbi->var.xres, fbi->var.yres,
+ out_pixel_fmt,
+ fbi->var.left_margin,
+ fbi->var.hsync_len,
+ fbi->var.right_margin,
+ fbi->var.upper_margin,
+ fbi->var.vsync_len,
+ fbi->var.lower_margin,
+ 0, sig_cfg) != 0) {
+ dev_err(fbi->device,
+ "mxcfb: Error initializing panel.\n");
+ return -EINVAL;
+ }
+
+ fbi->mode =
+ (struct fb_videomode *)fb_match_mode(&fbi->var,
+ &fbi->modelist);
+
+ ipu_disp_set_window_pos(mxc_fbi->ipu, mxc_fbi->ipu_ch, 0, 0);
+ }
+
+ retval = _setup_disp_channel2(fbi);
+ if (retval) {
+ if (!on_the_fly)
+ ipu_uninit_channel(mxc_fbi->ipu, mxc_fbi->ipu_ch);
+ return retval;
+ }
+
+ if (ovfbi_enable && !on_the_fly) {
+ if (ov_pos_ret >= 0)
+ ipu_disp_set_window_pos(
+ mxc_fbi_fg->ipu, mxc_fbi_fg->ipu_ch,
+ ov_pos_x, ov_pos_y);
+ retval = _setup_disp_channel2(mxc_fbi->ovfbi);
+ if (retval) {
+ ipu_uninit_channel(mxc_fbi_fg->ipu, mxc_fbi_fg->ipu_ch);
+ ipu_uninit_channel(mxc_fbi->ipu, mxc_fbi->ipu_ch);
+ return retval;
+ }
+ }
+
+ if (!on_the_fly) {
+ ipu_enable_channel(mxc_fbi->ipu, mxc_fbi->ipu_ch);
+ if (ovfbi_enable)
+ ipu_enable_channel(mxc_fbi_fg->ipu, mxc_fbi_fg->ipu_ch);
+ }
+
+ if (!on_the_fly && mxc_fbi->dispdrv && mxc_fbi->dispdrv->drv->enable) {
+ retval = mxc_fbi->dispdrv->drv->enable(mxc_fbi->dispdrv, fbi);
+ if (retval < 0) {
+ dev_err(fbi->device, "enable error, dispdrv:%s.\n",
+ mxc_fbi->dispdrv->drv->name);
+ return -EINVAL;
+ }
+ }
+
+ mxc_fbi->cur_var = fbi->var;
+ mxc_fbi->cur_ipu_pfmt = on_the_fly ? mxc_fbi->final_pfmt :
+ fbi_to_pixfmt(fbi, false);
+ mxc_fbi->cur_fb_pfmt = fbi_to_pixfmt(fbi, true);
+ mxc_fbi->cur_prefetch = mxc_fbi->prefetch;
+
+ return retval;
+}
+
+static int _swap_channels(struct fb_info *fbi_from,
+ struct fb_info *fbi_to, bool both_on)
+{
+ int retval, tmp;
+ ipu_channel_t old_ch;
+ struct fb_info *ovfbi;
+ struct mxcfb_info *mxc_fbi_from = (struct mxcfb_info *)fbi_from->par;
+ struct mxcfb_info *mxc_fbi_to = (struct mxcfb_info *)fbi_to->par;
+
+ if (both_on) {
+ ipu_disable_channel(mxc_fbi_to->ipu, mxc_fbi_to->ipu_ch, true);
+ ipu_uninit_channel(mxc_fbi_to->ipu, mxc_fbi_to->ipu_ch);
+ }
+
+ /* switch the mxc fbi parameters */
+ old_ch = mxc_fbi_from->ipu_ch;
+ mxc_fbi_from->ipu_ch = mxc_fbi_to->ipu_ch;
+ mxc_fbi_to->ipu_ch = old_ch;
+ tmp = mxc_fbi_from->ipu_ch_irq;
+ mxc_fbi_from->ipu_ch_irq = mxc_fbi_to->ipu_ch_irq;
+ mxc_fbi_to->ipu_ch_irq = tmp;
+ tmp = mxc_fbi_from->ipu_ch_nf_irq;
+ mxc_fbi_from->ipu_ch_nf_irq = mxc_fbi_to->ipu_ch_nf_irq;
+ mxc_fbi_to->ipu_ch_nf_irq = tmp;
+ ovfbi = mxc_fbi_from->ovfbi;
+ mxc_fbi_from->ovfbi = mxc_fbi_to->ovfbi;
+ mxc_fbi_to->ovfbi = ovfbi;
+
+ _setup_disp_channel1(fbi_from);
+ retval = _setup_disp_channel2(fbi_from);
+ if (retval)
+ return retval;
+
+ /* switch between dp and dc, disable old idmac, enable new idmac */
+ retval = ipu_swap_channel(mxc_fbi_from->ipu, old_ch, mxc_fbi_from->ipu_ch);
+ ipu_uninit_channel(mxc_fbi_from->ipu, old_ch);
+
+ if (both_on) {
+ _setup_disp_channel1(fbi_to);
+ retval = _setup_disp_channel2(fbi_to);
+ if (retval)
+ return retval;
+ ipu_enable_channel(mxc_fbi_to->ipu, mxc_fbi_to->ipu_ch);
+ }
+
+ return retval;
+}
+
+static int swap_channels(struct fb_info *fbi_from)
+{
+ int i;
+ int swap_mode;
+ ipu_channel_t ch_to;
+ struct mxcfb_info *mxc_fbi_from = (struct mxcfb_info *)fbi_from->par;
+ struct fb_info *fbi_to = NULL;
+ struct mxcfb_info *mxc_fbi_to;
+
+ /* what's the target channel? */
+ if (mxc_fbi_from->ipu_ch == MEM_BG_SYNC)
+ ch_to = MEM_DC_SYNC;
+ else
+ ch_to = MEM_BG_SYNC;
+
+ fbi_to = found_registered_fb(ch_to, mxc_fbi_from->ipu_id);
+ if (!fbi_to)
+ return -1;
+ mxc_fbi_to = (struct mxcfb_info *)fbi_to->par;
+
+ ipu_clear_irq(mxc_fbi_from->ipu, mxc_fbi_from->ipu_ch_irq);
+ ipu_clear_irq(mxc_fbi_to->ipu, mxc_fbi_to->ipu_ch_irq);
+ ipu_free_irq(mxc_fbi_from->ipu, mxc_fbi_from->ipu_ch_irq, fbi_from);
+ ipu_free_irq(mxc_fbi_to->ipu, mxc_fbi_to->ipu_ch_irq, fbi_to);
+ ipu_clear_irq(mxc_fbi_from->ipu, mxc_fbi_from->ipu_ch_nf_irq);
+ ipu_clear_irq(mxc_fbi_to->ipu, mxc_fbi_to->ipu_ch_nf_irq);
+ ipu_free_irq(mxc_fbi_from->ipu, mxc_fbi_from->ipu_ch_nf_irq, fbi_from);
+ ipu_free_irq(mxc_fbi_to->ipu, mxc_fbi_to->ipu_ch_nf_irq, fbi_to);
+
+ if (mxc_fbi_from->cur_blank == FB_BLANK_UNBLANK) {
+ if (mxc_fbi_to->cur_blank == FB_BLANK_UNBLANK)
+ swap_mode = BOTH_ON;
+ else
+ swap_mode = SRC_ON;
+ } else {
+ if (mxc_fbi_to->cur_blank == FB_BLANK_UNBLANK)
+ swap_mode = TGT_ON;
+ else
+ swap_mode = BOTH_OFF;
+ }
+
+ switch (swap_mode) {
+ case BOTH_ON:
+ /* disable target->switch src->enable target */
+ _swap_channels(fbi_from, fbi_to, true);
+ break;
+ case SRC_ON:
+ /* just switch src */
+ _swap_channels(fbi_from, fbi_to, false);
+ break;
+ case TGT_ON:
+ /* just switch target */
+ _swap_channels(fbi_to, fbi_from, false);
+ break;
+ case BOTH_OFF:
+ /* switch directly, no more need to do */
+ mxc_fbi_to->ipu_ch = mxc_fbi_from->ipu_ch;
+ mxc_fbi_from->ipu_ch = ch_to;
+ i = mxc_fbi_from->ipu_ch_irq;
+ mxc_fbi_from->ipu_ch_irq = mxc_fbi_to->ipu_ch_irq;
+ mxc_fbi_to->ipu_ch_irq = i;
+ i = mxc_fbi_from->ipu_ch_nf_irq;
+ mxc_fbi_from->ipu_ch_nf_irq = mxc_fbi_to->ipu_ch_nf_irq;
+ mxc_fbi_to->ipu_ch_nf_irq = i;
+ break;
+ default:
+ break;
+ }
+
+ if (ipu_request_irq(mxc_fbi_from->ipu, mxc_fbi_from->ipu_ch_irq,
+ mxcfb_irq_handler, IPU_IRQF_ONESHOT,
+ MXCFB_NAME, fbi_from) != 0) {
+ dev_err(fbi_from->device, "Error registering irq %d\n",
+ mxc_fbi_from->ipu_ch_irq);
+ return -EBUSY;
+ }
+ ipu_disable_irq(mxc_fbi_from->ipu, mxc_fbi_from->ipu_ch_irq);
+ if (ipu_request_irq(mxc_fbi_to->ipu, mxc_fbi_to->ipu_ch_irq,
+ mxcfb_irq_handler, IPU_IRQF_ONESHOT,
+ MXCFB_NAME, fbi_to) != 0) {
+ dev_err(fbi_to->device, "Error registering irq %d\n",
+ mxc_fbi_to->ipu_ch_irq);
+ return -EBUSY;
+ }
+ ipu_disable_irq(mxc_fbi_to->ipu, mxc_fbi_to->ipu_ch_irq);
+ if (ipu_request_irq(mxc_fbi_from->ipu, mxc_fbi_from->ipu_ch_nf_irq,
+ mxcfb_nf_irq_handler, IPU_IRQF_ONESHOT,
+ MXCFB_NAME, fbi_from) != 0) {
+ dev_err(fbi_from->device, "Error registering irq %d\n",
+ mxc_fbi_from->ipu_ch_nf_irq);
+ return -EBUSY;
+ }
+ ipu_disable_irq(mxc_fbi_from->ipu, mxc_fbi_from->ipu_ch_nf_irq);
+ if (ipu_request_irq(mxc_fbi_to->ipu, mxc_fbi_to->ipu_ch_nf_irq,
+ mxcfb_nf_irq_handler, IPU_IRQF_ONESHOT,
+ MXCFB_NAME, fbi_to) != 0) {
+ dev_err(fbi_to->device, "Error registering irq %d\n",
+ mxc_fbi_to->ipu_ch_nf_irq);
+ return -EBUSY;
+ }
+ ipu_disable_irq(mxc_fbi_to->ipu, mxc_fbi_to->ipu_ch_nf_irq);
+
+ return 0;
+}
+
+/*
+ * Check framebuffer variable parameters and adjust to valid values.
+ *
+ * @param var framebuffer variable parameters
+ *
+ * @param info framebuffer information pointer
+ */
+static int mxcfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
+{
+ u32 vtotal;
+ u32 htotal;
+ struct mxcfb_info *mxc_fbi = (struct mxcfb_info *)info->par;
+ struct fb_info tmp_fbi;
+ unsigned int fr_xoff, fr_yoff, fr_w, fr_h, line_length;
+ unsigned long base = 0;
+ int ret, bw = 0, bh = 0;
+ bool triple_buffer = false;
+
+ if (var->xres == 0 || var->yres == 0)
+ return 0;
+
+ /* fg should not bigger than bg */
+ if (mxc_fbi->ipu_ch == MEM_FG_SYNC) {
+ struct fb_info *fbi_tmp;
+ int bg_xres = 0, bg_yres = 0;
+ int16_t pos_x, pos_y;
+
+ bg_xres = var->xres;
+ bg_yres = var->yres;
+
+ fbi_tmp = found_registered_fb(MEM_BG_SYNC, mxc_fbi->ipu_id);
+ if (!fbi_tmp) {
+ dev_err(info->device,
+ "cannot find background fb for overlay fb\n");
+ return -EINVAL;
+ }
+
+ bg_xres = fbi_tmp->var.xres;
+ bg_yres = fbi_tmp->var.yres;
+
+ ipu_disp_get_window_pos(mxc_fbi->ipu, mxc_fbi->ipu_ch, &pos_x, &pos_y);
+
+ if ((var->xres + pos_x) > bg_xres)
+ var->xres = bg_xres - pos_x;
+ if ((var->yres + pos_y) > bg_yres)
+ var->yres = bg_yres - pos_y;
+
+ if (fbi_tmp->var.vmode & FB_VMODE_INTERLACED)
+ var->vmode |= FB_VMODE_INTERLACED;
+ else
+ var->vmode &= ~FB_VMODE_INTERLACED;
+
+ var->pixclock = fbi_tmp->var.pixclock;
+ var->right_margin = fbi_tmp->var.right_margin;
+ var->hsync_len = fbi_tmp->var.hsync_len;
+ var->left_margin = fbi_tmp->var.left_margin +
+ fbi_tmp->var.xres - var->xres;
+ var->upper_margin = fbi_tmp->var.upper_margin;
+ var->vsync_len = fbi_tmp->var.vsync_len;
+ var->lower_margin = fbi_tmp->var.lower_margin +
+ fbi_tmp->var.yres - var->yres;
+ }
+
+ if (var->rotate > IPU_ROTATE_VERT_FLIP)
+ var->rotate = IPU_ROTATE_NONE;
+
+ if (var->xres_virtual < var->xres)
+ var->xres_virtual = var->xres;
+
+ if (var->yres_virtual < var->yres) {
+ var->yres_virtual = var->yres * 3;
+ triple_buffer = true;
+ }
+
+ if ((var->bits_per_pixel != 32) && (var->bits_per_pixel != 24) &&
+ (var->bits_per_pixel != 16) && (var->bits_per_pixel != 12) &&
+ (var->bits_per_pixel != 8))
+ var->bits_per_pixel = 16;
+
+ if (check_var_pixfmt(var)) {
+ /* Fall back to default */
+ ret = bpp_to_var(var->bits_per_pixel, var);
+ if (ret < 0)
+ return ret;
+ }
+
+ if (ipu_pixel_format_is_gpu_tile(var->nonstd)) {
+ fmt_to_tile_alignment(var->nonstd, &bw, &bh);
+ var->xres_virtual = ALIGN(var->xres_virtual, bw);
+ if (triple_buffer)
+ var->yres_virtual = 3 * ALIGN(var->yres, bh);
+ else
+ var->yres_virtual = ALIGN(var->yres_virtual, bh);
+ }
+
+ line_length = var->xres_virtual * var->bits_per_pixel / 8;
+ fr_xoff = var->xoffset;
+ fr_w = var->xres_virtual;
+ if (!(var->vmode & FB_VMODE_YWRAP)) {
+ fr_yoff = var->yoffset % var->yres;
+ fr_h = var->yres;
+ base = line_length * var->yres *
+ (var->yoffset / var->yres);
+ if (ipu_pixel_format_is_split_gpu_tile(var->nonstd))
+ base += (mxc_fbi->gpu_sec_buf_off -
+ line_length * var->yres / 2) *
+ (var->yoffset / var->yres);
+ } else {
+ fr_yoff = var->yoffset;
+ fr_h = var->yres_virtual;
+ }
+
+ tmp_fbi.device = info->device;
+ tmp_fbi.var = *var;
+ tmp_fbi.par = mxc_fbi;
+ if (ipu_pixel_format_is_gpu_tile(var->nonstd)) {
+ unsigned int crop_line, prg_width = var->xres, offset;
+ int ipu_stride, prg_stride, bs;
+ bool tmp_prefetch = mxc_fbi->prefetch;
+
+ if (!(var->xres % 32))
+ bs = 32;
+ else if (!(var->xres % 16))
+ bs = 16;
+ else
+ bs = 32;
+
+ prg_width += fr_xoff % bw;
+ if (((fr_xoff % bw) + prg_width) % bs)
+ prg_width = ALIGN(prg_width, bs);
+
+ mxc_fbi->prefetch = true;
+ ipu_stride = prg_width *
+ bytes_per_pixel(fbi_to_pixfmt(&tmp_fbi, false));
+
+ if (var->vmode & FB_VMODE_INTERLACED) {
+ if ((fr_yoff % bh) % 2) {
+ dev_err(info->device,
+ "wrong crop value in interlaced mode\n");
+ return -EINVAL;
+ }
+ crop_line = (fr_yoff % bh) / 2;
+ prg_stride = ipu_stride * 2;
+ } else {
+ crop_line = fr_yoff % bh;
+ prg_stride = ipu_stride;
+ }
+
+ offset = crop_line * prg_stride +
+ (fr_xoff % bw) *
+ bytes_per_pixel(fbi_to_pixfmt(&tmp_fbi, false));
+ mxc_fbi->prefetch = tmp_prefetch;
+ if (offset % 8) {
+ dev_err(info->device,
+ "IPU base address is not 8byte aligned\n");
+ return -EINVAL;
+ }
+ } else {
+ unsigned int uoff = 0, voff = 0;
+ int fb_stride;
+
+ switch (fbi_to_pixfmt(&tmp_fbi, true)) {
+ case IPU_PIX_FMT_YUV420P2:
+ case IPU_PIX_FMT_YVU420P:
+ case IPU_PIX_FMT_NV12:
+ case PRE_PIX_FMT_NV21:
+ case IPU_PIX_FMT_NV16:
+ case PRE_PIX_FMT_NV61:
+ case IPU_PIX_FMT_YUV422P:
+ case IPU_PIX_FMT_YVU422P:
+ case IPU_PIX_FMT_YUV420P:
+ case IPU_PIX_FMT_YUV444P:
+ fb_stride = var->xres_virtual;
+ break;
+ default:
+ fb_stride = line_length;
+ }
+ base += fr_yoff * fb_stride +
+ fr_xoff * var->bits_per_pixel / 8;
+
+ ipu_get_channel_offset(fbi_to_pixfmt(&tmp_fbi, true),
+ var->xres,
+ fr_h,
+ fr_w,
+ 0, 0,
+ fr_yoff,
+ fr_xoff,
+ &uoff,
+ &voff);
+ if (base % 8 || uoff % 8 || voff % 8) {
+ dev_err(info->device,
+ "IPU base address is not 8byte aligned\n");
+ return -EINVAL;
+ }
+ }
+
+ if (var->pixclock < 1000) {
+ htotal = var->xres + var->right_margin + var->hsync_len +
+ var->left_margin;
+ vtotal = var->yres + var->lower_margin + var->vsync_len +
+ var->upper_margin;
+ var->pixclock = (vtotal * htotal * 6UL) / 100UL;
+ var->pixclock = KHZ2PICOS(var->pixclock);
+ dev_dbg(info->device,
+ "pixclock set for 60Hz refresh = %u ps\n",
+ var->pixclock);
+ }
+
+ var->height = -1;
+ var->width = -1;
+ var->grayscale = 0;
+
+ return 0;
+}
+
+static inline u_int _chan_to_field(u_int chan, struct fb_bitfield *bf)
+{
+ chan &= 0xffff;
+ chan >>= 16 - bf->length;
+ return chan << bf->offset;
+}
+
+static int mxcfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
+ u_int trans, struct fb_info *fbi)
+{
+ unsigned int val;
+ int ret = 1;
+
+ /*
+ * If greyscale is true, then we convert the RGB value
+ * to greyscale no matter what visual we are using.
+ */
+ if (fbi->var.grayscale)
+ red = green = blue = (19595 * red + 38470 * green +
+ 7471 * blue) >> 16;
+ switch (fbi->fix.visual) {
+ case FB_VISUAL_TRUECOLOR:
+ /*
+ * 16-bit True Colour. We encode the RGB value
+ * according to the RGB bitfield information.
+ */
+ if (regno < 16) {
+ u32 *pal = fbi->pseudo_palette;
+
+ val = _chan_to_field(red, &fbi->var.red);
+ val |= _chan_to_field(green, &fbi->var.green);
+ val |= _chan_to_field(blue, &fbi->var.blue);
+
+ pal[regno] = val;
+ ret = 0;
+ }
+ break;
+
+ case FB_VISUAL_STATIC_PSEUDOCOLOR:
+ case FB_VISUAL_PSEUDOCOLOR:
+ break;
+ }
+
+ return ret;
+}
+
+/*
+ * Function to handle custom ioctls for MXC framebuffer.
+ *
+ * @param inode inode struct
+ *
+ * @param file file struct
+ *
+ * @param cmd Ioctl command to handle
+ *
+ * @param arg User pointer to command arguments
+ *
+ * @param fbi framebuffer information pointer
+ */
+static int mxcfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg)
+{
+ int retval = 0;
+ int __user *argp = (void __user *)arg;
+ struct mxcfb_info *mxc_fbi = (struct mxcfb_info *)fbi->par;
+
+ switch (cmd) {
+ case MXCFB_SET_GBL_ALPHA:
+ {
+ struct mxcfb_gbl_alpha ga;
+
+ if (copy_from_user(&ga, (void *)arg, sizeof(ga))) {
+ retval = -EFAULT;
+ break;
+ }
+
+ if (ipu_disp_set_global_alpha(mxc_fbi->ipu,
+ mxc_fbi->ipu_ch,
+ (bool)ga.enable,
+ ga.alpha)) {
+ retval = -EINVAL;
+ break;
+ }
+
+ if (ga.enable)
+ mxc_fbi->alpha_chan_en = false;
+
+ if (ga.enable)
+ dev_dbg(fbi->device,
+ "Set global alpha of %s to %d\n",
+ fbi->fix.id, ga.alpha);
+ break;
+ }
+ case MXCFB_SET_LOC_ALPHA:
+ {
+ struct mxcfb_loc_alpha la;
+ bool bad_pixfmt =
+ ipu_ch_param_bad_alpha_pos(fbi_to_pixfmt(fbi, true));
+
+ if (copy_from_user(&la, (void *)arg, sizeof(la))) {
+ retval = -EFAULT;
+ break;
+ }
+
+ if (la.enable && !la.alpha_in_pixel) {
+ struct fb_info *fbi_tmp;
+ ipu_channel_t ipu_ch;
+
+ if (bad_pixfmt) {
+ dev_err(fbi->device, "Bad pixel format "
+ "for graphics plane fb\n");
+ retval = -EINVAL;
+ break;
+ }
+
+ mxc_fbi->alpha_chan_en = true;
+
+ if (mxc_fbi->ipu_ch == MEM_FG_SYNC)
+ ipu_ch = MEM_BG_SYNC;
+ else if (mxc_fbi->ipu_ch == MEM_BG_SYNC)
+ ipu_ch = MEM_FG_SYNC;
+ else {
+ retval = -EINVAL;
+ break;
+ }
+
+ fbi_tmp = found_registered_fb(ipu_ch, mxc_fbi->ipu_id);
+ if (fbi_tmp)
+ ((struct mxcfb_info *)(fbi_tmp->par))->alpha_chan_en = false;
+ } else
+ mxc_fbi->alpha_chan_en = false;
+
+ if (ipu_disp_set_global_alpha(mxc_fbi->ipu,
+ mxc_fbi->ipu_ch,
+ !(bool)la.enable, 0)) {
+ retval = -EINVAL;
+ break;
+ }
+
+ fbi->var.activate = (fbi->var.activate & ~FB_ACTIVATE_MASK) |
+ FB_ACTIVATE_NOW | FB_ACTIVATE_FORCE;
+ mxcfb_set_par(fbi);
+
+ la.alpha_phy_addr0 = mxc_fbi->alpha_phy_addr0;
+ la.alpha_phy_addr1 = mxc_fbi->alpha_phy_addr1;
+ if (copy_to_user((void *)arg, &la, sizeof(la))) {
+ retval = -EFAULT;
+ break;
+ }
+
+ if (la.enable)
+ dev_dbg(fbi->device,
+ "Enable DP local alpha for %s\n",
+ fbi->fix.id);
+ break;
+ }
+ case MXCFB_SET_LOC_ALP_BUF:
+ {
+ unsigned long base;
+ uint32_t ipu_alp_ch_irq;
+
+ if (!(((mxc_fbi->ipu_ch == MEM_FG_SYNC) ||
+ (mxc_fbi->ipu_ch == MEM_BG_SYNC)) &&
+ (mxc_fbi->alpha_chan_en))) {
+ dev_err(fbi->device,
+ "Should use background or overlay "
+ "framebuffer to set the alpha buffer "
+ "number\n");
+ return -EINVAL;
+ }
+
+ if (get_user(base, argp))
+ return -EFAULT;
+
+ if (base != mxc_fbi->alpha_phy_addr0 &&
+ base != mxc_fbi->alpha_phy_addr1) {
+ dev_err(fbi->device,
+ "Wrong alpha buffer physical address "
+ "%lu\n", base);
+ return -EINVAL;
+ }
+
+ if (mxc_fbi->ipu_ch == MEM_FG_SYNC)
+ ipu_alp_ch_irq = IPU_IRQ_FG_ALPHA_SYNC_EOF;
+ else
+ ipu_alp_ch_irq = IPU_IRQ_BG_ALPHA_SYNC_EOF;
+
+ retval = wait_for_completion_timeout(
+ &mxc_fbi->alpha_flip_complete, HZ/2);
+ if (retval == 0) {
+ dev_err(fbi->device, "timeout when waiting for alpha flip irq\n");
+ retval = -ETIMEDOUT;
+ break;
+ }
+
+ mxc_fbi->cur_ipu_alpha_buf =
+ !mxc_fbi->cur_ipu_alpha_buf;
+ if (ipu_update_channel_buffer(mxc_fbi->ipu, mxc_fbi->ipu_ch,
+ IPU_ALPHA_IN_BUFFER,
+ mxc_fbi->
+ cur_ipu_alpha_buf,
+ base) == 0) {
+ ipu_select_buffer(mxc_fbi->ipu, mxc_fbi->ipu_ch,
+ IPU_ALPHA_IN_BUFFER,
+ mxc_fbi->cur_ipu_alpha_buf);
+ ipu_clear_irq(mxc_fbi->ipu, ipu_alp_ch_irq);
+ ipu_enable_irq(mxc_fbi->ipu, ipu_alp_ch_irq);
+ } else {
+ dev_err(fbi->device,
+ "Error updating %s SDC alpha buf %d "
+ "to address=0x%08lX\n",
+ fbi->fix.id,
+ mxc_fbi->cur_ipu_alpha_buf, base);
+ }
+ break;
+ }
+ case MXCFB_SET_CLR_KEY:
+ {
+ struct mxcfb_color_key key;
+ if (copy_from_user(&key, (void *)arg, sizeof(key))) {
+ retval = -EFAULT;
+ break;
+ }
+ retval = ipu_disp_set_color_key(mxc_fbi->ipu, mxc_fbi->ipu_ch,
+ key.enable,
+ key.color_key);
+ dev_dbg(fbi->device, "Set color key to 0x%08X\n",
+ key.color_key);
+ break;
+ }
+ case MXCFB_SET_GAMMA:
+ {
+ struct mxcfb_gamma gamma;
+ if (copy_from_user(&gamma, (void *)arg, sizeof(gamma))) {
+ retval = -EFAULT;
+ break;
+ }
+ retval = ipu_disp_set_gamma_correction(mxc_fbi->ipu,
+ mxc_fbi->ipu_ch,
+ gamma.enable,
+ gamma.constk,
+ gamma.slopek);
+ break;
+ }
+ case MXCFB_SET_GPU_SPLIT_FMT:
+ {
+ struct mxcfb_gpu_split_fmt fmt;
+
+ if (copy_from_user(&fmt, (void *)arg, sizeof(fmt))) {
+ retval = -EFAULT;
+ break;
+ }
+
+ if (fmt.var.nonstd != IPU_PIX_FMT_GPU32_SB_ST &&
+ fmt.var.nonstd != IPU_PIX_FMT_GPU32_SB_SRT &&
+ fmt.var.nonstd != IPU_PIX_FMT_GPU16_SB_ST &&
+ fmt.var.nonstd != IPU_PIX_FMT_GPU16_SB_SRT) {
+ retval = -EINVAL;
+ break;
+ }
+
+ mxc_fbi->gpu_sec_buf_off = fmt.offset;
+ fmt.var.activate = (fbi->var.activate & ~FB_ACTIVATE_MASK) |
+ FB_ACTIVATE_NOW | FB_ACTIVATE_FORCE;
+ console_lock();
+ fbi->flags |= FBINFO_MISC_USEREVENT;
+ retval = fb_set_var(fbi, &fmt.var);
+ fbi->flags &= ~FBINFO_MISC_USEREVENT;
+ console_unlock();
+ break;
+ }
+ case MXCFB_SET_PREFETCH:
+ {
+ int enable;
+
+ if (copy_from_user(&enable, (void *)arg, sizeof(enable))) {
+ retval = -EFAULT;
+ break;
+ }
+
+ if (!enable) {
+ if (ipu_pixel_format_is_gpu_tile(fbi_to_pixfmt(fbi, true))) {
+ dev_err(fbi->device, "Cannot disable prefetch in "
+ "resolving mode\n");
+ retval = -EINVAL;
+ break;
+ }
+ if (ipu_pixel_format_is_pre_yuv(fbi_to_pixfmt(fbi, true))) {
+ dev_err(fbi->device, "Cannot disable prefetch when "
+ "PRE gets NV61 or NV21\n");
+ retval = -EINVAL;
+ break;
+ }
+ } else {
+ if ((fbi->var.vmode & FB_VMODE_INTERLACED) &&
+ ipu_pixel_format_is_multiplanar_yuv(fbi_to_pixfmt(fbi, true))) {
+ dev_err(fbi->device, "Cannot enable prefetch when "
+ "PRE gets multiplanar YUV frames\n");
+ retval = -EINVAL;
+ break;
+ }
+ }
+
+ retval = mxcfb_check_var(&fbi->var, fbi);
+ if (retval)
+ break;
+
+ mxc_fbi->prefetch = !!enable;
+
+ if (mxc_fbi->cur_prefetch == mxc_fbi->prefetch)
+ break;
+
+ fbi->var.activate = (fbi->var.activate & ~FB_ACTIVATE_MASK) |
+ FB_ACTIVATE_NOW | FB_ACTIVATE_FORCE;
+ retval = mxcfb_set_par(fbi);
+ break;
+ }
+ case MXCFB_GET_PREFETCH:
+ {
+ struct mxcfb_info *mxc_fbi =
+ (struct mxcfb_info *)fbi->par;
+
+ if (put_user(mxc_fbi->cur_prefetch, argp))
+ return -EFAULT;
+ break;
+ }
+ case MXCFB_WAIT_FOR_VSYNC:
+ {
+ if (mxc_fbi->ipu_ch == MEM_FG_SYNC) {
+ /* BG should poweron */
+ struct mxcfb_info *bg_mxcfbi = NULL;
+ struct fb_info *fbi_tmp;
+
+ fbi_tmp = found_registered_fb(MEM_BG_SYNC, mxc_fbi->ipu_id);
+ if (fbi_tmp)
+ bg_mxcfbi = ((struct mxcfb_info *)(fbi_tmp->par));
+
+ if (!bg_mxcfbi) {
+ retval = -EINVAL;
+ break;
+ }
+ if (bg_mxcfbi->cur_blank != FB_BLANK_UNBLANK) {
+ retval = -EINVAL;
+ break;
+ }
+ }
+ if (mxc_fbi->cur_blank != FB_BLANK_UNBLANK) {
+ retval = -EINVAL;
+ break;
+ }
+
+ init_completion(&mxc_fbi->vsync_complete);
+ ipu_clear_irq(mxc_fbi->ipu, mxc_fbi->ipu_ch_nf_irq);
+ ipu_enable_irq(mxc_fbi->ipu, mxc_fbi->ipu_ch_nf_irq);
+ retval = wait_for_completion_interruptible_timeout(
+ &mxc_fbi->vsync_complete, 1 * HZ);
+ if (retval == 0) {
+ dev_err(fbi->device,
+ "MXCFB_WAIT_FOR_VSYNC: timeout %d\n",
+ retval);
+ retval = -ETIME;
+ } else if (retval > 0) {
+ retval = 0;
+ }
+ break;
+ }
+ case FBIO_ALLOC:
+ {
+ int size;
+ struct mxcfb_alloc_list *mem;
+
+ mem = kzalloc(sizeof(*mem), GFP_KERNEL);
+ if (mem == NULL)
+ return -ENOMEM;
+
+ if (get_user(size, argp)) {
+ kfree(mem);
+ return -EFAULT;
+ }
+
+ mem->size = PAGE_ALIGN(size);
+
+ mem->cpu_addr = dma_alloc_coherent(fbi->device, size,
+ &mem->phy_addr,
+ GFP_KERNEL);
+ if (mem->cpu_addr == NULL) {
+ kfree(mem);
+ return -ENOMEM;
+ }
+
+ list_add(&mem->list, &fb_alloc_list);
+
+ if (put_user(mem->phy_addr, argp)) {
+ list_del(&mem->list);
+ dma_free_coherent(fbi->device,
+ mem->size,
+ mem->cpu_addr,
+ mem->phy_addr);
+ kfree(mem);
+ return -EFAULT;
+ }
+
+ dev_dbg(fbi->device, "allocated %d bytes @ 0x%08X\n",
+ mem->size, mem->phy_addr);
+
+ break;
+ }
+ case FBIO_FREE:
+ {
+ unsigned long offset;
+ struct mxcfb_alloc_list *mem;
+
+ if (get_user(offset, argp))
+ return -EFAULT;
+
+ retval = -EINVAL;
+ list_for_each_entry(mem, &fb_alloc_list, list) {
+ if (mem->phy_addr == offset) {
+ list_del(&mem->list);
+ dma_free_coherent(fbi->device,
+ mem->size,
+ mem->cpu_addr,
+ mem->phy_addr);
+ kfree(mem);
+ retval = 0;
+ break;
+ }
+ }
+
+ break;
+ }
+ case MXCFB_SET_OVERLAY_POS:
+ {
+ struct mxcfb_pos pos;
+ struct fb_info *bg_fbi = NULL;
+ struct mxcfb_info *bg_mxcfbi = NULL;
+
+ if (mxc_fbi->ipu_ch != MEM_FG_SYNC) {
+ dev_err(fbi->device, "Should use the overlay "
+ "framebuffer to set the position of "
+ "the overlay window\n");
+ retval = -EINVAL;
+ break;
+ }
+
+ if (copy_from_user(&pos, (void *)arg, sizeof(pos))) {
+ retval = -EFAULT;
+ break;
+ }
+
+ bg_fbi = found_registered_fb(MEM_BG_SYNC, mxc_fbi->ipu_id);
+ if (bg_fbi)
+ bg_mxcfbi = ((struct mxcfb_info *)(bg_fbi->par));
+
+ if (bg_fbi == NULL) {
+ dev_err(fbi->device, "Cannot find the "
+ "background framebuffer\n");
+ retval = -ENOENT;
+ break;
+ }
+
+ /* if fb is unblank, check if the pos fit the display */
+ if (mxc_fbi->cur_blank == FB_BLANK_UNBLANK) {
+ if (fbi->var.xres + pos.x > bg_fbi->var.xres) {
+ if (bg_fbi->var.xres < fbi->var.xres)
+ pos.x = 0;
+ else
+ pos.x = bg_fbi->var.xres - fbi->var.xres;
+ }
+ if (fbi->var.yres + pos.y > bg_fbi->var.yres) {
+ if (bg_fbi->var.yres < fbi->var.yres)
+ pos.y = 0;
+ else
+ pos.y = bg_fbi->var.yres - fbi->var.yres;
+ }
+ }
+
+ retval = ipu_disp_set_window_pos(mxc_fbi->ipu, mxc_fbi->ipu_ch,
+ pos.x, pos.y);
+
+ if (copy_to_user((void *)arg, &pos, sizeof(pos))) {
+ retval = -EFAULT;
+ break;
+ }
+ break;
+ }
+ case MXCFB_GET_FB_IPU_CHAN:
+ {
+ struct mxcfb_info *mxc_fbi =
+ (struct mxcfb_info *)fbi->par;
+
+ if (put_user(mxc_fbi->ipu_ch, argp))
+ return -EFAULT;
+ break;
+ }
+ case MXCFB_GET_DIFMT:
+ {
+ struct mxcfb_info *mxc_fbi =
+ (struct mxcfb_info *)fbi->par;
+
+ if (put_user(mxc_fbi->ipu_di_pix_fmt, argp))
+ return -EFAULT;
+ break;
+ }
+ case MXCFB_GET_FB_IPU_DI:
+ {
+ struct mxcfb_info *mxc_fbi =
+ (struct mxcfb_info *)fbi->par;
+
+ if (put_user(mxc_fbi->ipu_di, argp))
+ return -EFAULT;
+ break;
+ }
+ case MXCFB_GET_FB_BLANK:
+ {
+ struct mxcfb_info *mxc_fbi =
+ (struct mxcfb_info *)fbi->par;
+
+ if (put_user(mxc_fbi->cur_blank, argp))
+ return -EFAULT;
+ break;
+ }
+ case MXCFB_SET_DIFMT:
+ {
+ struct mxcfb_info *mxc_fbi =
+ (struct mxcfb_info *)fbi->par;
+
+ if (get_user(mxc_fbi->ipu_di_pix_fmt, argp))
+ return -EFAULT;
+
+ break;
+ }
+ case MXCFB_CSC_UPDATE:
+ {
+ struct mxcfb_csc_matrix csc;
+
+ if (copy_from_user(&csc, (void *) arg, sizeof(csc)))
+ return -EFAULT;
+
+ if ((mxc_fbi->ipu_ch != MEM_FG_SYNC) &&
+ (mxc_fbi->ipu_ch != MEM_BG_SYNC) &&
+ (mxc_fbi->ipu_ch != MEM_BG_ASYNC0))
+ return -EFAULT;
+ ipu_set_csc_coefficients(mxc_fbi->ipu, mxc_fbi->ipu_ch,
+ csc.param);
+ break;
+ }
+ default:
+ retval = -EINVAL;
+ }
+ return retval;
+}
+
+/*
+ * mxcfb_blank():
+ * Blank the display.
+ */
+static int mxcfb_blank(int blank, struct fb_info *info)
+{
+ struct mxcfb_info *mxc_fbi = (struct mxcfb_info *)info->par;
+ int ret = 0;
+
+ dev_dbg(info->device, "blank = %d\n", blank);
+
+ if (blank)
+ blank = FB_BLANK_POWERDOWN;
+
+ if (mxc_fbi->cur_blank == blank)
+ return 0;
+
+ mxc_fbi->next_blank = blank;
+
+ if (blank == FB_BLANK_UNBLANK) {
+ info->var.activate = (info->var.activate & ~FB_ACTIVATE_MASK) |
+ FB_ACTIVATE_NOW | FB_ACTIVATE_FORCE;
+ ret = fb_set_var(info, &info->var);
+ } else {
+ if (mxc_fbi->dispdrv && mxc_fbi->dispdrv->drv->disable)
+ mxc_fbi->dispdrv->drv->disable(mxc_fbi->dispdrv, info);
+ ipu_disable_channel(mxc_fbi->ipu, mxc_fbi->ipu_ch, true);
+ if (mxc_fbi->ipu_di >= 0)
+ ipu_uninit_sync_panel(mxc_fbi->ipu, mxc_fbi->ipu_di);
+ ipu_uninit_channel(mxc_fbi->ipu, mxc_fbi->ipu_ch);
+ if (mxc_fbi->cur_prefetch) {
+ ipu_prg_disable(mxc_fbi->ipu_id, mxc_fbi->pre_num);
+ ipu_pre_disable(mxc_fbi->pre_num);
+ ipu_pre_free(&mxc_fbi->pre_num);
+ }
+ }
+ if (!ret)
+ mxc_fbi->cur_blank = blank;
+ return ret;
+}
+
+/*
+ * Pan or Wrap the Display
+ *
+ * This call looks only at xoffset, yoffset and the FB_VMODE_YWRAP flag
+ *
+ * @param var Variable screen buffer information
+ * @param info Framebuffer information pointer
+ */
+static int
+mxcfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
+{
+ struct mxcfb_info *mxc_fbi = (struct mxcfb_info *)info->par,
+ *mxc_graphic_fbi = NULL;
+ u_int y_bottom;
+ unsigned int fr_xoff, fr_yoff, fr_w, fr_h;
+ unsigned long base, ipu_base = 0, active_alpha_phy_addr = 0;
+ bool loc_alpha_en = false;
+ int fb_stride;
+ int bw = 0, bh = 0;
+ int i;
+ int ret;
+
+ /* no pan display during fb blank */
+ if (mxc_fbi->ipu_ch == MEM_FG_SYNC) {
+ struct mxcfb_info *bg_mxcfbi = NULL;
+ struct fb_info *fbi_tmp;
+
+ fbi_tmp = found_registered_fb(MEM_BG_SYNC, mxc_fbi->ipu_id);
+ if (fbi_tmp)
+ bg_mxcfbi = ((struct mxcfb_info *)(fbi_tmp->par));
+ if (!bg_mxcfbi)
+ return -EINVAL;
+ if (bg_mxcfbi->cur_blank != FB_BLANK_UNBLANK)
+ return -EINVAL;
+ }
+ if (mxc_fbi->cur_blank != FB_BLANK_UNBLANK)
+ return -EINVAL;
+
+ if (mxc_fbi->resolve) {
+ fmt_to_tile_block(info->var.nonstd, &bw, &bh);
+
+ if (mxc_fbi->cur_var.xoffset % bw != var->xoffset % bw ||
+ mxc_fbi->cur_var.yoffset % bh != var->yoffset % bh) {
+ dev_err(info->device, "do not support panning "
+ "with tile crop settings changed\n");
+ return -EINVAL;
+ }
+ }
+
+ y_bottom = var->yoffset;
+
+ if (y_bottom > info->var.yres_virtual)
+ return -EINVAL;
+
+ switch (fbi_to_pixfmt(info, true)) {
+ case IPU_PIX_FMT_YUV420P2:
+ case IPU_PIX_FMT_YVU420P:
+ case IPU_PIX_FMT_NV12:
+ case PRE_PIX_FMT_NV21:
+ case IPU_PIX_FMT_NV16:
+ case PRE_PIX_FMT_NV61:
+ case IPU_PIX_FMT_YUV422P:
+ case IPU_PIX_FMT_YVU422P:
+ case IPU_PIX_FMT_YUV420P:
+ case IPU_PIX_FMT_YUV444P:
+ fb_stride = info->var.xres_virtual;
+ break;
+ default:
+ fb_stride = info->fix.line_length;
+ }
+
+ base = info->fix.smem_start;
+ fr_xoff = var->xoffset;
+ fr_w = info->var.xres_virtual;
+ if (!(var->vmode & FB_VMODE_YWRAP)) {
+ dev_dbg(info->device, "Y wrap disabled\n");
+ fr_yoff = var->yoffset % info->var.yres;
+ fr_h = info->var.yres;
+ base += info->fix.line_length * info->var.yres *
+ (var->yoffset / info->var.yres);
+ if (ipu_pixel_format_is_split_gpu_tile(var->nonstd))
+ base += (mxc_fbi->gpu_sec_buf_off -
+ info->fix.line_length * info->var.yres / 2) *
+ (var->yoffset / info->var.yres);
+ } else {
+ dev_dbg(info->device, "Y wrap enabled\n");
+ fr_yoff = var->yoffset;
+ fr_h = info->var.yres_virtual;
+ }
+ if (!mxc_fbi->resolve) {
+ base += fr_yoff * fb_stride + fr_xoff *
+ bytes_per_pixel(fbi_to_pixfmt(info, true));
+
+ if (mxc_fbi->cur_prefetch && (info->var.vmode & FB_VMODE_INTERLACED))
+ base += info->var.rotate ?
+ fr_w * bytes_per_pixel(fbi_to_pixfmt(info, true)) : 0;
+ }
+
+ if (mxc_fbi->cur_prefetch) {
+ unsigned long lock_flags = 0;
+
+ if (ipu_pre_yres_is_small(info->var.yres))
+ /*
+ * Update the PRE buffer address in the flip interrupt
+ * handler in this case to workaround the SoC design
+ * bug recorded by errata ERR009624.
+ */
+ spin_lock_irqsave(&mxc_fbi->spin_lock, lock_flags);
+
+ if (mxc_fbi->resolve) {
+ mxc_fbi->x_crop = fr_xoff & ~(bw - 1);
+ mxc_fbi->y_crop = fr_yoff & ~(bh - 1);
+ } else {
+ mxc_fbi->x_crop = 0;
+ mxc_fbi->y_crop = 0;
+ }
+
+ ipu_get_channel_offset(fbi_to_pixfmt(info, true),
+ info->var.xres,
+ fr_h,
+ fr_w,
+ 0, 0,
+ fr_yoff,
+ fr_xoff,
+ &mxc_fbi->sec_buf_off,
+ &mxc_fbi->trd_buf_off);
+ if (mxc_fbi->resolve)
+ mxc_fbi->sec_buf_off = mxc_fbi->gpu_sec_buf_off;
+
+ if (ipu_pre_yres_is_small(info->var.yres)) {
+ mxc_fbi->base = base;
+ spin_unlock_irqrestore(&mxc_fbi->spin_lock, lock_flags);
+ }
+ } else {
+ ipu_base = base;
+ }
+
+ /* Check if DP local alpha is enabled and find the graphic fb */
+ if (mxc_fbi->ipu_ch == MEM_BG_SYNC || mxc_fbi->ipu_ch == MEM_FG_SYNC) {
+ for (i = 0; i < num_registered_fb; i++) {
+ char bg_id[] = "DISP3 BG";
+ char fg_id[] = "DISP3 FG";
+ char *idstr = registered_fb[i]->fix.id;
+ bg_id[4] += mxc_fbi->ipu_id;
+ fg_id[4] += mxc_fbi->ipu_id;
+ if ((strcmp(idstr, bg_id) == 0 ||
+ strcmp(idstr, fg_id) == 0) &&
+ ((struct mxcfb_info *)
+ (registered_fb[i]->par))->alpha_chan_en) {
+ loc_alpha_en = true;
+ mxc_graphic_fbi = (struct mxcfb_info *)
+ (registered_fb[i]->par);
+ active_alpha_phy_addr =
+ mxc_fbi->cur_ipu_alpha_buf ?
+ mxc_graphic_fbi->alpha_phy_addr1 :
+ mxc_graphic_fbi->alpha_phy_addr0;
+ dev_dbg(info->device, "Updating SDC alpha "
+ "buf %d address=0x%08lX\n",
+ !mxc_fbi->cur_ipu_alpha_buf,
+ active_alpha_phy_addr);
+ break;
+ }
+ }
+ }
+
+ if (!mxc_fbi->cur_prefetch ||
+ (mxc_fbi->cur_prefetch && !ipu_pre_yres_is_small(info->var.yres))) {
+ ret = wait_for_completion_timeout(&mxc_fbi->flip_complete,
+ HZ/2);
+ if (ret == 0) {
+ dev_err(info->device, "timeout when waiting for flip "
+ "irq\n");
+ return -ETIMEDOUT;
+ }
+ }
+
+ if (!mxc_fbi->cur_prefetch) {
+ ++mxc_fbi->cur_ipu_buf;
+ mxc_fbi->cur_ipu_buf %= 3;
+ dev_dbg(info->device, "Updating SDC %s buf %d address=0x%08lX\n",
+ info->fix.id, mxc_fbi->cur_ipu_buf, base);
+ }
+ mxc_fbi->cur_ipu_alpha_buf = !mxc_fbi->cur_ipu_alpha_buf;
+
+ if (mxc_fbi->cur_prefetch)
+ goto next;
+
+ if (ipu_update_channel_buffer(mxc_fbi->ipu, mxc_fbi->ipu_ch, IPU_INPUT_BUFFER,
+ mxc_fbi->cur_ipu_buf, ipu_base) == 0) {
+next:
+ /* Update the DP local alpha buffer only for graphic plane */
+ if (loc_alpha_en && mxc_graphic_fbi == mxc_fbi &&
+ ipu_update_channel_buffer(mxc_graphic_fbi->ipu, mxc_graphic_fbi->ipu_ch,
+ IPU_ALPHA_IN_BUFFER,
+ mxc_fbi->cur_ipu_alpha_buf,
+ active_alpha_phy_addr) == 0) {
+ ipu_select_buffer(mxc_graphic_fbi->ipu, mxc_graphic_fbi->ipu_ch,
+ IPU_ALPHA_IN_BUFFER,
+ mxc_fbi->cur_ipu_alpha_buf);
+ }
+
+ /* update u/v offset */
+ if (!mxc_fbi->cur_prefetch) {
+ ipu_update_channel_offset(mxc_fbi->ipu, mxc_fbi->ipu_ch,
+ IPU_INPUT_BUFFER,
+ fbi_to_pixfmt(info, true),
+ fr_w,
+ fr_h,
+ fr_w,
+ 0, 0,
+ fr_yoff,
+ fr_xoff);
+
+ ipu_select_buffer(mxc_fbi->ipu, mxc_fbi->ipu_ch,
+ IPU_INPUT_BUFFER, mxc_fbi->cur_ipu_buf);
+ } else if (!ipu_pre_yres_is_small(info->var.yres)) {
+ ipu_pre_set_fb_buffer(mxc_fbi->pre_num,
+ mxc_fbi->resolve,
+ base, info->var.yres,
+ mxc_fbi->x_crop,
+ mxc_fbi->y_crop,
+ mxc_fbi->sec_buf_off,
+ mxc_fbi->trd_buf_off);
+ }
+ ipu_clear_irq(mxc_fbi->ipu, mxc_fbi->ipu_ch_irq);
+ ipu_enable_irq(mxc_fbi->ipu, mxc_fbi->ipu_ch_irq);
+ } else {
+ dev_err(info->device,
+ "Error updating SDC buf %d to address=0x%08lX, "
+ "current buf %d, buf0 ready %d, buf1 ready %d, "
+ "buf2 ready %d\n", mxc_fbi->cur_ipu_buf, base,
+ ipu_get_cur_buffer_idx(mxc_fbi->ipu, mxc_fbi->ipu_ch,
+ IPU_INPUT_BUFFER),
+ ipu_check_buffer_ready(mxc_fbi->ipu, mxc_fbi->ipu_ch,
+ IPU_INPUT_BUFFER, 0),
+ ipu_check_buffer_ready(mxc_fbi->ipu, mxc_fbi->ipu_ch,
+ IPU_INPUT_BUFFER, 1),
+ ipu_check_buffer_ready(mxc_fbi->ipu, mxc_fbi->ipu_ch,
+ IPU_INPUT_BUFFER, 2));
+ if (!mxc_fbi->cur_prefetch) {
+ ++mxc_fbi->cur_ipu_buf;
+ mxc_fbi->cur_ipu_buf %= 3;
+ ++mxc_fbi->cur_ipu_buf;
+ mxc_fbi->cur_ipu_buf %= 3;
+ }
+ mxc_fbi->cur_ipu_alpha_buf = !mxc_fbi->cur_ipu_alpha_buf;
+ ipu_clear_irq(mxc_fbi->ipu, mxc_fbi->ipu_ch_irq);
+ ipu_enable_irq(mxc_fbi->ipu, mxc_fbi->ipu_ch_irq);
+ return -EBUSY;
+ }
+
+ if (mxc_fbi->cur_prefetch && ipu_pre_yres_is_small(info->var.yres)) {
+ ret = wait_for_completion_timeout(&mxc_fbi->flip_complete,
+ HZ/2);
+ if (ret == 0) {
+ dev_err(info->device, "timeout when waiting for flip "
+ "irq\n");
+ return -ETIMEDOUT;
+ }
+ }
+
+ dev_dbg(info->device, "Update complete\n");
+
+ info->var.yoffset = var->yoffset;
+ mxc_fbi->cur_var.xoffset = var->xoffset;
+ mxc_fbi->cur_var.yoffset = var->yoffset;
+
+ return 0;
+}
+
+/*
+ * Function to handle custom mmap for MXC framebuffer.
+ *
+ * @param fbi framebuffer information pointer
+ *
+ * @param vma Pointer to vm_area_struct
+ */
+static int mxcfb_mmap(struct fb_info *fbi, struct vm_area_struct *vma)
+{
+ bool found = false;
+ u32 len;
+ unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
+ struct mxcfb_alloc_list *mem;
+ struct mxcfb_info *mxc_fbi = (struct mxcfb_info *)fbi->par;
+
+ if (offset < fbi->fix.smem_len) {
+ /* mapping framebuffer memory */
+ len = fbi->fix.smem_len - offset;
+ vma->vm_pgoff = (fbi->fix.smem_start + offset) >> PAGE_SHIFT;
+ } else if ((vma->vm_pgoff ==
+ (mxc_fbi->alpha_phy_addr0 >> PAGE_SHIFT)) ||
+ (vma->vm_pgoff ==
+ (mxc_fbi->alpha_phy_addr1 >> PAGE_SHIFT))) {
+ len = mxc_fbi->alpha_mem_len;
+ } else {
+ list_for_each_entry(mem, &fb_alloc_list, list) {
+ if (offset == mem->phy_addr) {
+ found = true;
+ len = mem->size;
+ break;
+ }
+ }
+ if (!found)
+ return -EINVAL;
+ }
+
+ len = PAGE_ALIGN(len);
+ if (vma->vm_end - vma->vm_start > len)
+ return -EINVAL;
+
+ /* make buffers bufferable */
+ vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
+
+ vma->vm_flags |= VM_IO;
+
+ if (remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
+ vma->vm_end - vma->vm_start, vma->vm_page_prot)) {
+ dev_dbg(fbi->device, "mmap remap_pfn_range failed\n");
+ return -ENOBUFS;
+ }
+
+ return 0;
+}
+
+/*!
+ * This structure contains the pointers to the control functions that are
+ * invoked by the core framebuffer driver to perform operations like
+ * blitting, rectangle filling, copy regions and cursor definition.
+ */
+static struct fb_ops mxcfb_ops = {
+ .owner = THIS_MODULE,
+ .fb_set_par = mxcfb_set_par,
+ .fb_check_var = mxcfb_check_var,
+ .fb_setcolreg = mxcfb_setcolreg,
+ .fb_pan_display = mxcfb_pan_display,
+ .fb_ioctl = mxcfb_ioctl,
+ .fb_mmap = mxcfb_mmap,
+ .fb_fillrect = cfb_fillrect,
+ .fb_copyarea = cfb_copyarea,
+ .fb_imageblit = cfb_imageblit,
+ .fb_blank = mxcfb_blank,
+};
+
+static irqreturn_t mxcfb_irq_handler(int irq, void *dev_id)
+{
+ struct fb_info *fbi = dev_id;
+ struct mxcfb_info *mxc_fbi = fbi->par;
+
+ if (mxc_fbi->pre_config) {
+ ipu_pre_set_ctrl(mxc_fbi->pre_num, mxc_fbi->pre_config);
+ mxc_fbi->pre_config = NULL;
+ complete(&mxc_fbi->otf_complete);
+ return IRQ_HANDLED;
+ }
+
+ if (mxc_fbi->cur_prefetch && ipu_pre_yres_is_small(fbi->var.yres)) {
+ spin_lock(&mxc_fbi->spin_lock);
+ ipu_pre_set_fb_buffer(mxc_fbi->pre_num,
+ mxc_fbi->resolve,
+ mxc_fbi->base, fbi->var.yres,
+ mxc_fbi->x_crop, mxc_fbi->y_crop,
+ mxc_fbi->sec_buf_off,
+ mxc_fbi->trd_buf_off);
+ spin_unlock(&mxc_fbi->spin_lock);
+ }
+
+ complete(&mxc_fbi->flip_complete);
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t mxcfb_nf_irq_handler(int irq, void *dev_id)
+{
+ struct fb_info *fbi = dev_id;
+ struct mxcfb_info *mxc_fbi = fbi->par;
+
+ complete(&mxc_fbi->vsync_complete);
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t mxcfb_alpha_irq_handler(int irq, void *dev_id)
+{
+ struct fb_info *fbi = dev_id;
+ struct mxcfb_info *mxc_fbi = fbi->par;
+
+ complete(&mxc_fbi->alpha_flip_complete);
+ return IRQ_HANDLED;
+}
+
+/*
+ * Suspends the framebuffer and blanks the screen. Power management support
+ */
+static int mxcfb_suspend(struct platform_device *pdev, pm_message_t state)
+{
+ struct fb_info *fbi = platform_get_drvdata(pdev);
+ struct mxcfb_info *mxc_fbi = (struct mxcfb_info *)fbi->par;
+ int saved_blank;
+#ifdef CONFIG_FB_MXC_LOW_PWR_DISPLAY
+ void *fbmem;
+#endif
+
+ if (mxc_fbi->ovfbi) {
+ struct mxcfb_info *mxc_fbi_fg =
+ (struct mxcfb_info *)mxc_fbi->ovfbi->par;
+
+ console_lock();
+ fb_set_suspend(mxc_fbi->ovfbi, 1);
+ saved_blank = mxc_fbi_fg->cur_blank;
+ mxcfb_blank(FB_BLANK_POWERDOWN, mxc_fbi->ovfbi);
+ mxc_fbi_fg->next_blank = saved_blank;
+ console_unlock();
+ }
+
+ console_lock();
+ fb_set_suspend(fbi, 1);
+ saved_blank = mxc_fbi->cur_blank;
+ mxcfb_blank(FB_BLANK_POWERDOWN, fbi);
+ mxc_fbi->next_blank = saved_blank;
+ console_unlock();
+
+ return 0;
+}
+
+/*
+ * Resumes the framebuffer and unblanks the screen. Power management support
+ */
+static int mxcfb_resume(struct platform_device *pdev)
+{
+ struct fb_info *fbi = platform_get_drvdata(pdev);
+ struct mxcfb_info *mxc_fbi = (struct mxcfb_info *)fbi->par;
+
+ console_lock();
+ mxcfb_blank(mxc_fbi->next_blank, fbi);
+ fb_set_suspend(fbi, 0);
+ console_unlock();
+
+ if (mxc_fbi->ovfbi) {
+ struct mxcfb_info *mxc_fbi_fg =
+ (struct mxcfb_info *)mxc_fbi->ovfbi->par;
+ console_lock();
+ mxcfb_blank(mxc_fbi_fg->next_blank, mxc_fbi->ovfbi);
+ fb_set_suspend(mxc_fbi->ovfbi, 0);
+ console_unlock();
+ }
+
+ return 0;
+}
+
+/*
+ * Main framebuffer functions
+ */
+
+/*!
+ * Allocates the DRAM memory for the frame buffer. This buffer is remapped
+ * into a non-cached, non-buffered, memory region to allow palette and pixel
+ * writes to occur without flushing the cache. Once this area is remapped,
+ * all virtual memory access to the video memory should occur at the new region.
+ *
+ * @param fbi framebuffer information pointer
+ *
+ * @return Error code indicating success or failure
+ */
+static int mxcfb_map_video_memory(struct fb_info *fbi)
+{
+ struct mxcfb_info *mxc_fbi = (struct mxcfb_info *)fbi->par;
+
+ if (fbi->fix.smem_len < fbi->var.yres_virtual * fbi->fix.line_length)
+ fbi->fix.smem_len = fbi->var.yres_virtual *
+ fbi->fix.line_length;
+
+ if (mxc_fbi->resolve && mxc_fbi->gpu_sec_buf_off) {
+ if (fbi->var.vmode & FB_VMODE_YWRAP)
+ fbi->fix.smem_len = mxc_fbi->gpu_sec_buf_off +
+ fbi->fix.smem_len / 2;
+ else
+ fbi->fix.smem_len = mxc_fbi->gpu_sec_buf_off *
+ (fbi->var.yres_virtual / fbi->var.yres) +
+ fbi->fix.smem_len / 2;
+ }
+
+ fbi->screen_base = dma_alloc_writecombine(fbi->device,
+ fbi->fix.smem_len,
+ (dma_addr_t *)&fbi->fix.smem_start,
+ GFP_DMA | GFP_KERNEL);
+ if (fbi->screen_base == 0) {
+ dev_err(fbi->device, "Unable to allocate framebuffer memory\n");
+ fbi->fix.smem_len = 0;
+ fbi->fix.smem_start = 0;
+ return -EBUSY;
+ }
+
+ dev_dbg(fbi->device, "allocated fb @ paddr=0x%08X, size=%d.\n",
+ (uint32_t) fbi->fix.smem_start, fbi->fix.smem_len);
+
+ fbi->screen_size = fbi->fix.smem_len;
+
+ /* Clear the screen */
+ memset((char *)fbi->screen_base, 0, fbi->fix.smem_len);
+
+ return 0;
+}
+
+/*!
+ * De-allocates the DRAM memory for the frame buffer.
+ *
+ * @param fbi framebuffer information pointer
+ *
+ * @return Error code indicating success or failure
+ */
+static int mxcfb_unmap_video_memory(struct fb_info *fbi)
+{
+ dma_free_writecombine(fbi->device, fbi->fix.smem_len,
+ fbi->screen_base, fbi->fix.smem_start);
+ fbi->screen_base = 0;
+ fbi->fix.smem_start = 0;
+ fbi->fix.smem_len = 0;
+ return 0;
+}
+
+/*!
+ * Initializes the framebuffer information pointer. After allocating
+ * sufficient memory for the framebuffer structure, the fields are
+ * filled with custom information passed in from the configurable
+ * structures. This includes information such as bits per pixel,
+ * color maps, screen width/height and RGBA offsets.
+ *
+ * @return Framebuffer structure initialized with our information
+ */
+static struct fb_info *mxcfb_init_fbinfo(struct device *dev, struct fb_ops *ops)
+{
+ struct fb_info *fbi;
+ struct mxcfb_info *mxcfbi;
+ struct ipuv3_fb_platform_data *plat_data = dev->platform_data;
+
+ /*
+ * Allocate sufficient memory for the fb structure
+ */
+ fbi = framebuffer_alloc(sizeof(struct mxcfb_info), dev);
+ if (!fbi)
+ return NULL;
+
+ mxcfbi = (struct mxcfb_info *)fbi->par;
+
+ fbi->var.activate = FB_ACTIVATE_NOW;
+
+ bpp_to_var(plat_data->default_bpp, &fbi->var);
+
+ fbi->fbops = ops;
+ fbi->flags = FBINFO_FLAG_DEFAULT;
+ fbi->pseudo_palette = mxcfbi->pseudo_palette;
+
+ /*
+ * Allocate colormap
+ */
+ fb_alloc_cmap(&fbi->cmap, 16, 0);
+
+ return fbi;
+}
+
+static ssize_t show_disp_chan(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct fb_info *info = dev_get_drvdata(dev);
+ struct mxcfb_info *mxcfbi = (struct mxcfb_info *)info->par;
+
+ if (mxcfbi->ipu_ch == MEM_BG_SYNC)
+ return sprintf(buf, "2-layer-fb-bg\n");
+ else if (mxcfbi->ipu_ch == MEM_FG_SYNC)
+ return sprintf(buf, "2-layer-fb-fg\n");
+ else if (mxcfbi->ipu_ch == MEM_DC_SYNC)
+ return sprintf(buf, "1-layer-fb\n");
+ else
+ return sprintf(buf, "err: no display chan\n");
+}
+
+static ssize_t swap_disp_chan(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct fb_info *info = dev_get_drvdata(dev);
+ struct mxcfb_info *mxcfbi = (struct mxcfb_info *)info->par;
+ struct mxcfb_info *fg_mxcfbi = NULL;
+
+ console_lock();
+ /* swap only happen between DP-BG and DC, while DP-FG disable */
+ if (((mxcfbi->ipu_ch == MEM_BG_SYNC) &&
+ (strstr(buf, "1-layer-fb") != NULL)) ||
+ ((mxcfbi->ipu_ch == MEM_DC_SYNC) &&
+ (strstr(buf, "2-layer-fb-bg") != NULL))) {
+ struct fb_info *fbi_fg;
+
+ fbi_fg = found_registered_fb(MEM_FG_SYNC, mxcfbi->ipu_id);
+ if (fbi_fg)
+ fg_mxcfbi = (struct mxcfb_info *)fbi_fg->par;
+
+ if (!fg_mxcfbi ||
+ fg_mxcfbi->cur_blank == FB_BLANK_UNBLANK) {
+ dev_err(dev,
+ "Can not switch while fb2(fb-fg) is on.\n");
+ console_unlock();
+ return count;
+ }
+
+ if (swap_channels(info) < 0)
+ dev_err(dev, "Swap display channel failed.\n");
+ }
+
+ console_unlock();
+ return count;
+}
+static DEVICE_ATTR(fsl_disp_property, S_IWUSR | S_IRUGO,
+ show_disp_chan, swap_disp_chan);
+
+static ssize_t show_disp_dev(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct fb_info *info = dev_get_drvdata(dev);
+ struct mxcfb_info *mxcfbi = (struct mxcfb_info *)info->par;
+
+ if (mxcfbi->ipu_ch == MEM_FG_SYNC)
+ return sprintf(buf, "overlay\n");
+ else
+ return sprintf(buf, "%s\n", mxcfbi->dispdrv->drv->name);
+}
+static DEVICE_ATTR(fsl_disp_dev_property, S_IRUGO, show_disp_dev, NULL);
+
+static int mxcfb_get_crtc(struct device *dev, struct mxcfb_info *mxcfbi,
+ enum crtc crtc)
+{
+ int i = 0;
+
+ for (; i < ARRAY_SIZE(ipu_di_crtc_maps); i++)
+ if (ipu_di_crtc_maps[i].crtc == crtc) {
+ mxcfbi->ipu_id = ipu_di_crtc_maps[i].ipu_id;
+ mxcfbi->ipu_di = ipu_di_crtc_maps[i].ipu_di;
+ return 0;
+ }
+
+ dev_err(dev, "failed to get valid crtc\n");
+ return -EINVAL;
+}
+
+static int mxcfb_dispdrv_init(struct platform_device *pdev,
+ struct fb_info *fbi)
+{
+ struct ipuv3_fb_platform_data *plat_data = pdev->dev.platform_data;
+ struct mxcfb_info *mxcfbi = (struct mxcfb_info *)fbi->par;
+ struct mxc_dispdrv_setting setting;
+ char disp_dev[32], *default_dev = "lcd";
+ int ret = 0;
+
+ setting.if_fmt = plat_data->interface_pix_fmt;
+ setting.dft_mode_str = plat_data->mode_str;
+ setting.default_bpp = plat_data->default_bpp;
+ if (!setting.default_bpp)
+ setting.default_bpp = 16;
+ setting.fbi = fbi;
+ if (!strlen(plat_data->disp_dev)) {
+ memcpy(disp_dev, default_dev, strlen(default_dev));
+ disp_dev[strlen(default_dev)] = '\0';
+ } else {
+ memcpy(disp_dev, plat_data->disp_dev,
+ strlen(plat_data->disp_dev));
+ disp_dev[strlen(plat_data->disp_dev)] = '\0';
+ }
+
+ mxcfbi->dispdrv = mxc_dispdrv_gethandle(disp_dev, &setting);
+ if (IS_ERR(mxcfbi->dispdrv)) {
+ ret = PTR_ERR(mxcfbi->dispdrv);
+ dev_err(&pdev->dev, "NO mxc display driver found!\n");
+ return ret;
+ } else {
+ /* fix-up */
+ mxcfbi->ipu_di_pix_fmt = setting.if_fmt;
+ mxcfbi->default_bpp = setting.default_bpp;
+
+ ret = mxcfb_get_crtc(&pdev->dev, mxcfbi, setting.crtc);
+ if (ret)
+ return ret;
+
+ dev_dbg(&pdev->dev, "di_pixfmt:0x%x, bpp:0x%x, di:%d, ipu:%d\n",
+ setting.if_fmt, setting.default_bpp,
+ mxcfbi->ipu_di, mxcfbi->ipu_id);
+ }
+
+ dev_info(&pdev->dev, "registered mxc display driver %s\n", disp_dev);
+
+ return ret;
+}
+
+/*
+ * Parse user specified options (`video=trident:')
+ * example:
+ * video=mxcfb0:dev=lcd,800x480M-16@55,if=RGB565,bpp=16,noaccel
+ * video=mxcfb0:dev=lcd,800x480M-16@55,if=RGB565,fbpix=RGB565
+ */
+static int mxcfb_option_setup(struct platform_device *pdev, struct fb_info *fbi)
+{
+ struct ipuv3_fb_platform_data *pdata = pdev->dev.platform_data;
+ char *options, *opt, *fb_mode_str = NULL;
+ char name[] = "mxcfb0";
+ uint32_t fb_pix_fmt = 0;
+
+ name[5] += pdev->id;
+ if (fb_get_options(name, &options)) {
+ dev_err(&pdev->dev, "Can't get fb option for %s!\n", name);
+ return -ENODEV;
+ }
+
+ if (!options || !*options)
+ return 0;
+
+ while ((opt = strsep(&options, ",")) != NULL) {
+ if (!*opt)
+ continue;
+
+ if (!strncmp(opt, "dev=", 4)) {
+ memcpy(pdata->disp_dev, opt + 4, strlen(opt) - 4);
+ pdata->disp_dev[strlen(opt) - 4] = '\0';
+ } else if (!strncmp(opt, "if=", 3)) {
+ if (!strncmp(opt+3, "RGB24", 5))
+ pdata->interface_pix_fmt = IPU_PIX_FMT_RGB24;
+ else if (!strncmp(opt+3, "BGR24", 5))
+ pdata->interface_pix_fmt = IPU_PIX_FMT_BGR24;
+ else if (!strncmp(opt+3, "GBR24", 5))
+ pdata->interface_pix_fmt = IPU_PIX_FMT_GBR24;
+ else if (!strncmp(opt+3, "RGB565", 6))
+ pdata->interface_pix_fmt = IPU_PIX_FMT_RGB565;
+ else if (!strncmp(opt+3, "RGB666", 6))
+ pdata->interface_pix_fmt = IPU_PIX_FMT_RGB666;
+ else if (!strncmp(opt+3, "YUV444", 6))
+ pdata->interface_pix_fmt = IPU_PIX_FMT_YUV444;
+ else if (!strncmp(opt+3, "LVDS666", 7))
+ pdata->interface_pix_fmt = IPU_PIX_FMT_LVDS666;
+ else if (!strncmp(opt+3, "YUYV16", 6))
+ pdata->interface_pix_fmt = IPU_PIX_FMT_YUYV;
+ else if (!strncmp(opt+3, "UYVY16", 6))
+ pdata->interface_pix_fmt = IPU_PIX_FMT_UYVY;
+ else if (!strncmp(opt+3, "YVYU16", 6))
+ pdata->interface_pix_fmt = IPU_PIX_FMT_YVYU;
+ else if (!strncmp(opt+3, "VYUY16", 6))
+ pdata->interface_pix_fmt = IPU_PIX_FMT_VYUY;
+ } else if (!strncmp(opt, "fbpix=", 6)) {
+ if (!strncmp(opt+6, "RGB24", 5))
+ fb_pix_fmt = IPU_PIX_FMT_RGB24;
+ else if (!strncmp(opt+6, "BGR24", 5))
+ fb_pix_fmt = IPU_PIX_FMT_BGR24;
+ else if (!strncmp(opt+6, "RGB32", 5))
+ fb_pix_fmt = IPU_PIX_FMT_RGB32;
+ else if (!strncmp(opt+6, "BGR32", 5))
+ fb_pix_fmt = IPU_PIX_FMT_BGR32;
+ else if (!strncmp(opt+6, "ABGR32", 6))
+ fb_pix_fmt = IPU_PIX_FMT_ABGR32;
+ else if (!strncmp(opt+6, "RGB565", 6))
+ fb_pix_fmt = IPU_PIX_FMT_RGB565;
+ else if (!strncmp(opt+6, "BGRA4444", 8))
+ fb_pix_fmt = IPU_PIX_FMT_BGRA4444;
+ else if (!strncmp(opt+6, "BGRA5551", 8))
+ fb_pix_fmt = IPU_PIX_FMT_BGRA5551;
+
+ if (fb_pix_fmt) {
+ pixfmt_to_var(fb_pix_fmt, &fbi->var);
+ pdata->default_bpp =
+ fbi->var.bits_per_pixel;
+ }
+ } else if (!strncmp(opt, "int_clk", 7)) {
+ pdata->int_clk = true;
+ continue;
+ } else if (!strncmp(opt, "bpp=", 4)) {
+ /* bpp setting cannot overwirte fbpix setting */
+ if (fb_pix_fmt)
+ continue;
+
+ pdata->default_bpp =
+ simple_strtoul(opt + 4, NULL, 0);
+
+ fb_pix_fmt = bpp_to_pixfmt(pdata->default_bpp);
+ if (fb_pix_fmt)
+ pixfmt_to_var(fb_pix_fmt, &fbi->var);
+ } else
+ fb_mode_str = opt;
+ }
+
+ if (fb_mode_str)
+ pdata->mode_str = fb_mode_str;
+
+ return 0;
+}
+
+static int mxcfb_register(struct fb_info *fbi)
+{
+ struct mxcfb_info *mxcfbi = (struct mxcfb_info *)fbi->par;
+ struct fb_videomode m;
+ int ret = 0;
+ char bg0_id[] = "DISP3 BG";
+ char bg1_id[] = "DISP3 BG - DI1";
+ char fg_id[] = "DISP3 FG";
+
+ if (mxcfbi->ipu_di == 0) {
+ bg0_id[4] += mxcfbi->ipu_id;
+ strcpy(fbi->fix.id, bg0_id);
+ } else if (mxcfbi->ipu_di == 1) {
+ bg1_id[4] += mxcfbi->ipu_id;
+ strcpy(fbi->fix.id, bg1_id);
+ } else { /* Overlay */
+ fg_id[4] += mxcfbi->ipu_id;
+ strcpy(fbi->fix.id, fg_id);
+ }
+
+ mxcfb_check_var(&fbi->var, fbi);
+
+ mxcfb_set_fix(fbi);
+
+ /* Added first mode to fbi modelist. */
+ if (!fbi->modelist.next || !fbi->modelist.prev)
+ INIT_LIST_HEAD(&fbi->modelist);
+ fb_var_to_videomode(&m, &fbi->var);
+ fb_add_videomode(&m, &fbi->modelist);
+
+ if (ipu_request_irq(mxcfbi->ipu, mxcfbi->ipu_ch_irq,
+ mxcfb_irq_handler, IPU_IRQF_ONESHOT, MXCFB_NAME, fbi) != 0) {
+ dev_err(fbi->device, "Error registering EOF irq handler.\n");
+ ret = -EBUSY;
+ goto err0;
+ }
+ ipu_disable_irq(mxcfbi->ipu, mxcfbi->ipu_ch_irq);
+ if (ipu_request_irq(mxcfbi->ipu, mxcfbi->ipu_ch_nf_irq,
+ mxcfb_nf_irq_handler, IPU_IRQF_ONESHOT, MXCFB_NAME, fbi) != 0) {
+ dev_err(fbi->device, "Error registering NFACK irq handler.\n");
+ ret = -EBUSY;
+ goto err1;
+ }
+ ipu_disable_irq(mxcfbi->ipu, mxcfbi->ipu_ch_nf_irq);
+
+ if (mxcfbi->ipu_alp_ch_irq != -1)
+ if (ipu_request_irq(mxcfbi->ipu, mxcfbi->ipu_alp_ch_irq,
+ mxcfb_alpha_irq_handler, IPU_IRQF_ONESHOT,
+ MXCFB_NAME, fbi) != 0) {
+ dev_err(fbi->device, "Error registering alpha irq "
+ "handler.\n");
+ ret = -EBUSY;
+ goto err2;
+ }
+
+ if (!mxcfbi->late_init) {
+ fbi->var.activate |= FB_ACTIVATE_FORCE;
+ console_lock();
+ fbi->flags |= FBINFO_MISC_USEREVENT;
+ ret = fb_set_var(fbi, &fbi->var);
+ fbi->flags &= ~FBINFO_MISC_USEREVENT;
+ console_unlock();
+ if (ret < 0) {
+ dev_err(fbi->device, "Error fb_set_var ret:%d\n", ret);
+ goto err3;
+ }
+
+ if (mxcfbi->next_blank == FB_BLANK_UNBLANK) {
+ console_lock();
+ ret = fb_blank(fbi, FB_BLANK_UNBLANK);
+ console_unlock();
+ if (ret < 0) {
+ dev_err(fbi->device,
+ "Error fb_blank ret:%d\n", ret);
+ goto err4;
+ }
+ }
+ } else {
+ /*
+ * Setup the channel again though bootloader
+ * has done this, then set_par() can stop the
+ * channel neatly and re-initialize it .
+ */
+ if (mxcfbi->next_blank == FB_BLANK_UNBLANK) {
+ console_lock();
+ _setup_disp_channel1(fbi);
+ ipu_enable_channel(mxcfbi->ipu, mxcfbi->ipu_ch);
+ console_unlock();
+ }
+ }
+
+
+ ret = register_framebuffer(fbi);
+ if (ret < 0)
+ goto err5;
+
+ return ret;
+err5:
+ if (mxcfbi->next_blank == FB_BLANK_UNBLANK) {
+ console_lock();
+ if (!mxcfbi->late_init)
+ fb_blank(fbi, FB_BLANK_POWERDOWN);
+ else {
+ ipu_disable_channel(mxcfbi->ipu, mxcfbi->ipu_ch,
+ true);
+ ipu_uninit_channel(mxcfbi->ipu, mxcfbi->ipu_ch);
+ }
+ console_unlock();
+ }
+err4:
+err3:
+ if (mxcfbi->ipu_alp_ch_irq != -1)
+ ipu_free_irq(mxcfbi->ipu, mxcfbi->ipu_alp_ch_irq, fbi);
+err2:
+ ipu_free_irq(mxcfbi->ipu, mxcfbi->ipu_ch_nf_irq, fbi);
+err1:
+ ipu_free_irq(mxcfbi->ipu, mxcfbi->ipu_ch_irq, fbi);
+err0:
+ return ret;
+}
+
+static void mxcfb_unregister(struct fb_info *fbi)
+{
+ struct mxcfb_info *mxcfbi = (struct mxcfb_info *)fbi->par;
+
+ if (mxcfbi->ipu_alp_ch_irq != -1)
+ ipu_free_irq(mxcfbi->ipu, mxcfbi->ipu_alp_ch_irq, fbi);
+ if (mxcfbi->ipu_ch_irq)
+ ipu_free_irq(mxcfbi->ipu, mxcfbi->ipu_ch_irq, fbi);
+ if (mxcfbi->ipu_ch_nf_irq)
+ ipu_free_irq(mxcfbi->ipu, mxcfbi->ipu_ch_nf_irq, fbi);
+
+ unregister_framebuffer(fbi);
+}
+
+static int mxcfb_setup_overlay(struct platform_device *pdev,
+ struct fb_info *fbi_bg, struct resource *res)
+{
+ struct fb_info *ovfbi;
+ struct mxcfb_info *mxcfbi_bg = (struct mxcfb_info *)fbi_bg->par;
+ struct mxcfb_info *mxcfbi_fg;
+ int ret = 0;
+
+ ovfbi = mxcfb_init_fbinfo(&pdev->dev, &mxcfb_ops);
+ if (!ovfbi) {
+ ret = -ENOMEM;
+ goto init_ovfbinfo_failed;
+ }
+ mxcfbi_fg = (struct mxcfb_info *)ovfbi->par;
+
+ mxcfbi_fg->ipu = ipu_get_soc(mxcfbi_bg->ipu_id);
+ if (IS_ERR(mxcfbi_fg->ipu)) {
+ ret = -ENODEV;
+ goto get_ipu_failed;
+ }
+ mxcfbi_fg->ipu_id = mxcfbi_bg->ipu_id;
+ mxcfbi_fg->ipu_ch_irq = IPU_IRQ_FG_SYNC_EOF;
+ mxcfbi_fg->ipu_ch_nf_irq = IPU_IRQ_FG_SYNC_NFACK;
+ mxcfbi_fg->ipu_alp_ch_irq = IPU_IRQ_FG_ALPHA_SYNC_EOF;
+ mxcfbi_fg->ipu_ch = MEM_FG_SYNC;
+ mxcfbi_fg->ipu_di = -1;
+ mxcfbi_fg->ipu_di_pix_fmt = mxcfbi_bg->ipu_di_pix_fmt;
+ mxcfbi_fg->overlay = true;
+ mxcfbi_fg->cur_blank = mxcfbi_fg->next_blank = FB_BLANK_POWERDOWN;
+ mxcfbi_fg->prefetch = false;
+ mxcfbi_fg->resolve = false;
+ mxcfbi_fg->pre_num = -1;
+
+ /* Need dummy values until real panel is configured */
+ ovfbi->var.xres = 240;
+ ovfbi->var.yres = 320;
+
+ if (res && res->start && res->end) {
+ ovfbi->fix.smem_len = res->end - res->start + 1;
+ ovfbi->fix.smem_start = res->start;
+ ovfbi->screen_base = ioremap(
+ ovfbi->fix.smem_start,
+ ovfbi->fix.smem_len);
+ }
+
+ ret = mxcfb_register(ovfbi);
+ if (ret < 0)
+ goto register_ov_failed;
+
+ mxcfbi_bg->ovfbi = ovfbi;
+
+ return ret;
+
+register_ov_failed:
+get_ipu_failed:
+ fb_dealloc_cmap(&ovfbi->cmap);
+ framebuffer_release(ovfbi);
+init_ovfbinfo_failed:
+ return ret;
+}
+
+static void mxcfb_unsetup_overlay(struct fb_info *fbi_bg)
+{
+ struct mxcfb_info *mxcfbi_bg = (struct mxcfb_info *)fbi_bg->par;
+ struct fb_info *ovfbi = mxcfbi_bg->ovfbi;
+
+ mxcfb_unregister(ovfbi);
+
+ if (&ovfbi->cmap)
+ fb_dealloc_cmap(&ovfbi->cmap);
+ framebuffer_release(ovfbi);
+}
+
+static bool ipu_usage[2][2];
+static int ipu_test_set_usage(int ipu, int di)
+{
+ if (ipu_usage[ipu][di])
+ return -EBUSY;
+ else
+ ipu_usage[ipu][di] = true;
+ return 0;
+}
+
+static void ipu_clear_usage(int ipu, int di)
+{
+ ipu_usage[ipu][di] = false;
+}
+
+static int mxcfb_get_of_property(struct platform_device *pdev,
+ struct ipuv3_fb_platform_data *plat_data)
+{
+ struct device_node *np = pdev->dev.of_node;
+ const char *disp_dev;
+ const char *mode_str = NULL;
+ const char *pixfmt;
+ int err;
+ int len;
+ u32 bpp, int_clk;
+ u32 late_init;
+
+ err = of_property_read_string(np, "disp_dev", &disp_dev);
+ if (err < 0) {
+ dev_dbg(&pdev->dev, "get of property disp_dev fail\n");
+ return err;
+ }
+ err = of_property_read_string(np, "mode_str", &mode_str);
+ if (err < 0)
+ dev_dbg(&pdev->dev, "get of property mode_str fail\n");
+ err = of_property_read_string(np, "interface_pix_fmt", &pixfmt);
+ if (err) {
+ dev_dbg(&pdev->dev, "get of property pix fmt fail\n");
+ return err;
+ }
+ err = of_property_read_u32(np, "default_bpp", &bpp);
+ if (err) {
+ dev_dbg(&pdev->dev, "get of property bpp fail\n");
+ return err;
+ }
+ err = of_property_read_u32(np, "int_clk", &int_clk);
+ if (err) {
+ dev_dbg(&pdev->dev, "get of property int_clk fail\n");
+ return err;
+ }
+ err = of_property_read_u32(np, "late_init", &late_init);
+ if (err) {
+ dev_dbg(&pdev->dev, "get of property late_init fail\n");
+ return err;
+ }
+
+ plat_data->prefetch = of_property_read_bool(np, "prefetch");
+
+ if (!strncmp(pixfmt, "RGB24", 5))
+ plat_data->interface_pix_fmt = IPU_PIX_FMT_RGB24;
+ else if (!strncmp(pixfmt, "BGR24", 5))
+ plat_data->interface_pix_fmt = IPU_PIX_FMT_BGR24;
+ else if (!strncmp(pixfmt, "GBR24", 5))
+ plat_data->interface_pix_fmt = IPU_PIX_FMT_GBR24;
+ else if (!strncmp(pixfmt, "RGB565", 6))
+ plat_data->interface_pix_fmt = IPU_PIX_FMT_RGB565;
+ else if (!strncmp(pixfmt, "RGB666", 6))
+ plat_data->interface_pix_fmt = IPU_PIX_FMT_RGB666;
+ else if (!strncmp(pixfmt, "YUV444", 6))
+ plat_data->interface_pix_fmt = IPU_PIX_FMT_YUV444;
+ else if (!strncmp(pixfmt, "LVDS666", 7))
+ plat_data->interface_pix_fmt = IPU_PIX_FMT_LVDS666;
+ else if (!strncmp(pixfmt, "YUYV16", 6))
+ plat_data->interface_pix_fmt = IPU_PIX_FMT_YUYV;
+ else if (!strncmp(pixfmt, "UYVY16", 6))
+ plat_data->interface_pix_fmt = IPU_PIX_FMT_UYVY;
+ else if (!strncmp(pixfmt, "YVYU16", 6))
+ plat_data->interface_pix_fmt = IPU_PIX_FMT_YVYU;
+ else if (!strncmp(pixfmt, "VYUY16", 6))
+ plat_data->interface_pix_fmt = IPU_PIX_FMT_VYUY;
+ else {
+ dev_err(&pdev->dev, "err interface_pix_fmt!\n");
+ return -ENOENT;
+ }
+
+ len = min(sizeof(plat_data->disp_dev) - 1, strlen(disp_dev));
+ memcpy(plat_data->disp_dev, disp_dev, len);
+ plat_data->disp_dev[len] = '\0';
+ plat_data->mode_str = (char *)mode_str;
+ plat_data->default_bpp = bpp;
+ plat_data->int_clk = (bool)int_clk;
+ plat_data->late_init = (bool)late_init;
+ return err;
+}
+
+/*!
+ * Probe routine for the framebuffer driver. It is called during the
+ * driver binding process. The following functions are performed in
+ * this routine: Framebuffer initialization, Memory allocation and
+ * mapping, Framebuffer registration, IPU initialization.
+ *
+ * @return Appropriate error code to the kernel common code
+ */
+static int mxcfb_probe(struct platform_device *pdev)
+{
+ struct ipuv3_fb_platform_data *plat_data;
+ struct fb_info *fbi;
+ struct mxcfb_info *mxcfbi;
+ struct resource *res;
+ int ret = 0;
+
+ dev_dbg(&pdev->dev, "%s enter\n", __func__);
+ pdev->id = of_alias_get_id(pdev->dev.of_node, "mxcfb");
+ if (pdev->id < 0) {
+ dev_err(&pdev->dev, "can not get alias id\n");
+ return pdev->id;
+ }
+
+ plat_data = devm_kzalloc(&pdev->dev, sizeof(struct
+ ipuv3_fb_platform_data), GFP_KERNEL);
+ if (!plat_data)
+ return -ENOMEM;
+ pdev->dev.platform_data = plat_data;
+
+ ret = mxcfb_get_of_property(pdev, plat_data);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "get mxcfb of property fail\n");
+ return ret;
+ }
+
+ /* Initialize FB structures */
+ fbi = mxcfb_init_fbinfo(&pdev->dev, &mxcfb_ops);
+ if (!fbi) {
+ ret = -ENOMEM;
+ goto init_fbinfo_failed;
+ }
+
+ ret = mxcfb_option_setup(pdev, fbi);
+ if (ret)
+ goto get_fb_option_failed;
+
+ mxcfbi = (struct mxcfb_info *)fbi->par;
+ mxcfbi->ipu_int_clk = plat_data->int_clk;
+ mxcfbi->late_init = plat_data->late_init;
+ mxcfbi->first_set_par = true;
+ mxcfbi->prefetch = plat_data->prefetch;
+ mxcfbi->pre_num = -1;
+ spin_lock_init(&mxcfbi->spin_lock);
+
+ ret = mxcfb_dispdrv_init(pdev, fbi);
+ if (ret < 0)
+ goto init_dispdrv_failed;
+
+ ret = ipu_test_set_usage(mxcfbi->ipu_id, mxcfbi->ipu_di);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "ipu%d-di%d already in use\n",
+ mxcfbi->ipu_id, mxcfbi->ipu_di);
+ goto ipu_in_busy;
+ }
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (res && res->start && res->end) {
+ fbi->fix.smem_len = res->end - res->start + 1;
+ fbi->fix.smem_start = res->start;
+ fbi->screen_base = ioremap(fbi->fix.smem_start, fbi->fix.smem_len);
+ /* Do not clear the fb content drawn in bootloader. */
+ if (!mxcfbi->late_init)
+ memset(fbi->screen_base, 0, fbi->fix.smem_len);
+ }
+
+ mxcfbi->ipu = ipu_get_soc(mxcfbi->ipu_id);
+ if (IS_ERR(mxcfbi->ipu)) {
+ ret = -ENODEV;
+ goto get_ipu_failed;
+ }
+
+ /* first user uses DP with alpha feature */
+ if (!g_dp_in_use[mxcfbi->ipu_id]) {
+ mxcfbi->ipu_ch_irq = IPU_IRQ_BG_SYNC_EOF;
+ mxcfbi->ipu_ch_nf_irq = IPU_IRQ_BG_SYNC_NFACK;
+ mxcfbi->ipu_alp_ch_irq = IPU_IRQ_BG_ALPHA_SYNC_EOF;
+ mxcfbi->ipu_ch = MEM_BG_SYNC;
+ /* Unblank the primary fb only by default */
+ if (pdev->id == 0)
+ mxcfbi->cur_blank = mxcfbi->next_blank = FB_BLANK_UNBLANK;
+ else
+ mxcfbi->cur_blank = mxcfbi->next_blank = FB_BLANK_POWERDOWN;
+
+ ret = mxcfb_register(fbi);
+ if (ret < 0)
+ goto mxcfb_register_failed;
+
+ ipu_disp_set_global_alpha(mxcfbi->ipu, mxcfbi->ipu_ch,
+ true, 0x80);
+ ipu_disp_set_color_key(mxcfbi->ipu, mxcfbi->ipu_ch, false, 0);
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+ ret = mxcfb_setup_overlay(pdev, fbi, res);
+
+ if (ret < 0) {
+ mxcfb_unregister(fbi);
+ goto mxcfb_setupoverlay_failed;
+ }
+
+ g_dp_in_use[mxcfbi->ipu_id] = true;
+
+ ret = device_create_file(mxcfbi->ovfbi->dev,
+ &dev_attr_fsl_disp_property);
+ if (ret)
+ dev_err(mxcfbi->ovfbi->dev, "Error %d on creating "
+ "file for disp property\n",
+ ret);
+
+ ret = device_create_file(mxcfbi->ovfbi->dev,
+ &dev_attr_fsl_disp_dev_property);
+ if (ret)
+ dev_err(mxcfbi->ovfbi->dev, "Error %d on creating "
+ "file for disp device "
+ "propety\n", ret);
+ } else {
+ mxcfbi->ipu_ch_irq = IPU_IRQ_DC_SYNC_EOF;
+ mxcfbi->ipu_ch_nf_irq = IPU_IRQ_DC_SYNC_NFACK;
+ mxcfbi->ipu_alp_ch_irq = -1;
+ mxcfbi->ipu_ch = MEM_DC_SYNC;
+ mxcfbi->cur_blank = mxcfbi->next_blank = FB_BLANK_POWERDOWN;
+
+ ret = mxcfb_register(fbi);
+ if (ret < 0)
+ goto mxcfb_register_failed;
+ }
+
+ platform_set_drvdata(pdev, fbi);
+
+ ret = device_create_file(fbi->dev, &dev_attr_fsl_disp_property);
+ if (ret)
+ dev_err(&pdev->dev, "Error %d on creating file for disp "
+ "property\n", ret);
+
+ ret = device_create_file(fbi->dev, &dev_attr_fsl_disp_dev_property);
+ if (ret)
+ dev_err(&pdev->dev, "Error %d on creating file for disp "
+ " device propety\n", ret);
+
+ return 0;
+
+mxcfb_setupoverlay_failed:
+mxcfb_register_failed:
+get_ipu_failed:
+ ipu_clear_usage(mxcfbi->ipu_id, mxcfbi->ipu_di);
+ipu_in_busy:
+init_dispdrv_failed:
+ fb_dealloc_cmap(&fbi->cmap);
+ framebuffer_release(fbi);
+get_fb_option_failed:
+init_fbinfo_failed:
+ return ret;
+}
+
+static int mxcfb_remove(struct platform_device *pdev)
+{
+ struct fb_info *fbi = platform_get_drvdata(pdev);
+ struct mxcfb_info *mxc_fbi = fbi->par;
+
+ device_remove_file(fbi->dev, &dev_attr_fsl_disp_dev_property);
+ device_remove_file(fbi->dev, &dev_attr_fsl_disp_property);
+ mxcfb_blank(FB_BLANK_POWERDOWN, fbi);
+ mxcfb_unregister(fbi);
+ mxcfb_unmap_video_memory(fbi);
+
+ if (mxc_fbi->ovfbi) {
+ device_remove_file(mxc_fbi->ovfbi->dev,
+ &dev_attr_fsl_disp_dev_property);
+ device_remove_file(mxc_fbi->ovfbi->dev,
+ &dev_attr_fsl_disp_property);
+ mxcfb_blank(FB_BLANK_POWERDOWN, mxc_fbi->ovfbi);
+ mxcfb_unsetup_overlay(fbi);
+ mxcfb_unmap_video_memory(mxc_fbi->ovfbi);
+ }
+
+ ipu_clear_usage(mxc_fbi->ipu_id, mxc_fbi->ipu_di);
+ if (&fbi->cmap)
+ fb_dealloc_cmap(&fbi->cmap);
+ framebuffer_release(fbi);
+ return 0;
+}
+
+static const struct of_device_id imx_mxcfb_dt_ids[] = {
+ { .compatible = "fsl,mxc_sdc_fb"},
+ { /* sentinel */ }
+};
+
+/*!
+ * This structure contains pointers to the power management callback functions.
+ */
+static struct platform_driver mxcfb_driver = {
+ .driver = {
+ .name = MXCFB_NAME,
+ .of_match_table = imx_mxcfb_dt_ids,
+ },
+ .probe = mxcfb_probe,
+ .remove = mxcfb_remove,
+ .suspend = mxcfb_suspend,
+ .resume = mxcfb_resume,
+};
+
+/*!
+ * Main entry function for the framebuffer. The function registers the power
+ * management callback functions with the kernel and also registers the MXCFB
+ * callback functions with the core Linux framebuffer driver \b fbmem.c
+ *
+ * @return Error code indicating success or failure
+ */
+int __init mxcfb_init(void)
+{
+ return platform_driver_register(&mxcfb_driver);
+}
+
+void mxcfb_exit(void)
+{
+ platform_driver_unregister(&mxcfb_driver);
+}
+
+module_init(mxcfb_init);
+module_exit(mxcfb_exit);
+
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("MXC framebuffer driver");
+MODULE_LICENSE("GPL");
+MODULE_SUPPORTED_DEVICE("fb");
diff --git a/drivers/video/fbdev/mxc/mxc_lcdif.c b/drivers/video/fbdev/mxc/mxc_lcdif.c
new file mode 100644
index 000000000000..59d429c82017
--- /dev/null
+++ b/drivers/video/fbdev/mxc/mxc_lcdif.c
@@ -0,0 +1,237 @@
+/*
+ * Copyright (C) 2011-2015 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/init.h>
+#include <linux/ipu.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/mxcfb.h>
+#include <linux/of_device.h>
+#include <linux/pinctrl/consumer.h>
+#include <linux/platform_device.h>
+
+#include "mxc_dispdrv.h"
+
+struct mxc_lcd_platform_data {
+ u32 default_ifmt;
+ u32 ipu_id;
+ u32 disp_id;
+};
+
+struct mxc_lcdif_data {
+ struct platform_device *pdev;
+ struct mxc_dispdrv_handle *disp_lcdif;
+};
+
+#define DISPDRV_LCD "lcd"
+
+static struct fb_videomode lcdif_modedb[] = {
+ {
+ /* 800x480 @ 57 Hz , pixel clk @ 27MHz */
+ "CLAA-WVGA", 57, 800, 480, 37037, 40, 60, 10, 10, 20, 10,
+ FB_SYNC_CLK_LAT_FALL,
+ FB_VMODE_NONINTERLACED,
+ 0,},
+ {
+ /* 800x480 @ 60 Hz , pixel clk @ 32MHz */
+ "SEIKO-WVGA", 60, 800, 480, 29850, 89, 164, 23, 10, 10, 10,
+ FB_SYNC_CLK_LAT_FALL,
+ FB_VMODE_NONINTERLACED,
+ 0,},
+};
+static int lcdif_modedb_sz = ARRAY_SIZE(lcdif_modedb);
+
+static int lcdif_init(struct mxc_dispdrv_handle *disp,
+ struct mxc_dispdrv_setting *setting)
+{
+ int ret, i;
+ struct mxc_lcdif_data *lcdif = mxc_dispdrv_getdata(disp);
+ struct device *dev = &lcdif->pdev->dev;
+ struct mxc_lcd_platform_data *plat_data = dev->platform_data;
+ struct fb_videomode *modedb = lcdif_modedb;
+ int modedb_sz = lcdif_modedb_sz;
+
+ /* use platform defined ipu/di */
+ ret = ipu_di_to_crtc(dev, plat_data->ipu_id,
+ plat_data->disp_id, &setting->crtc);
+ if (ret < 0)
+ return ret;
+
+ ret = fb_find_mode(&setting->fbi->var, setting->fbi, setting->dft_mode_str,
+ modedb, modedb_sz, NULL, setting->default_bpp);
+ if (!ret) {
+ fb_videomode_to_var(&setting->fbi->var, &modedb[0]);
+ setting->if_fmt = plat_data->default_ifmt;
+ }
+
+ INIT_LIST_HEAD(&setting->fbi->modelist);
+ for (i = 0; i < modedb_sz; i++) {
+ struct fb_videomode m;
+ fb_var_to_videomode(&m, &setting->fbi->var);
+ if (fb_mode_is_equal(&m, &modedb[i])) {
+ fb_add_videomode(&modedb[i],
+ &setting->fbi->modelist);
+ break;
+ }
+ }
+
+ return ret;
+}
+
+void lcdif_deinit(struct mxc_dispdrv_handle *disp)
+{
+ /*TODO*/
+}
+
+static struct mxc_dispdrv_driver lcdif_drv = {
+ .name = DISPDRV_LCD,
+ .init = lcdif_init,
+ .deinit = lcdif_deinit,
+};
+
+static int lcd_get_of_property(struct platform_device *pdev,
+ struct mxc_lcd_platform_data *plat_data)
+{
+ struct device_node *np = pdev->dev.of_node;
+ int err;
+ u32 ipu_id, disp_id;
+ const char *default_ifmt;
+
+ err = of_property_read_string(np, "default_ifmt", &default_ifmt);
+ if (err) {
+ dev_dbg(&pdev->dev, "get of property default_ifmt fail\n");
+ return err;
+ }
+ err = of_property_read_u32(np, "ipu_id", &ipu_id);
+ if (err) {
+ dev_dbg(&pdev->dev, "get of property ipu_id fail\n");
+ return err;
+ }
+ err = of_property_read_u32(np, "disp_id", &disp_id);
+ if (err) {
+ dev_dbg(&pdev->dev, "get of property disp_id fail\n");
+ return err;
+ }
+
+ plat_data->ipu_id = ipu_id;
+ plat_data->disp_id = disp_id;
+ if (!strncmp(default_ifmt, "RGB24", 5))
+ plat_data->default_ifmt = IPU_PIX_FMT_RGB24;
+ else if (!strncmp(default_ifmt, "BGR24", 5))
+ plat_data->default_ifmt = IPU_PIX_FMT_BGR24;
+ else if (!strncmp(default_ifmt, "GBR24", 5))
+ plat_data->default_ifmt = IPU_PIX_FMT_GBR24;
+ else if (!strncmp(default_ifmt, "RGB565", 6))
+ plat_data->default_ifmt = IPU_PIX_FMT_RGB565;
+ else if (!strncmp(default_ifmt, "RGB666", 6))
+ plat_data->default_ifmt = IPU_PIX_FMT_RGB666;
+ else if (!strncmp(default_ifmt, "YUV444", 6))
+ plat_data->default_ifmt = IPU_PIX_FMT_YUV444;
+ else if (!strncmp(default_ifmt, "LVDS666", 7))
+ plat_data->default_ifmt = IPU_PIX_FMT_LVDS666;
+ else if (!strncmp(default_ifmt, "YUYV16", 6))
+ plat_data->default_ifmt = IPU_PIX_FMT_YUYV;
+ else if (!strncmp(default_ifmt, "UYVY16", 6))
+ plat_data->default_ifmt = IPU_PIX_FMT_UYVY;
+ else if (!strncmp(default_ifmt, "YVYU16", 6))
+ plat_data->default_ifmt = IPU_PIX_FMT_YVYU;
+ else if (!strncmp(default_ifmt, "VYUY16", 6))
+ plat_data->default_ifmt = IPU_PIX_FMT_VYUY;
+ else {
+ dev_err(&pdev->dev, "err default_ifmt!\n");
+ return -ENOENT;
+ }
+
+ return err;
+}
+
+static int mxc_lcdif_probe(struct platform_device *pdev)
+{
+ int ret;
+ struct pinctrl *pinctrl;
+ struct mxc_lcdif_data *lcdif;
+ struct mxc_lcd_platform_data *plat_data;
+
+ dev_dbg(&pdev->dev, "%s enter\n", __func__);
+ lcdif = devm_kzalloc(&pdev->dev, sizeof(struct mxc_lcdif_data),
+ GFP_KERNEL);
+ if (!lcdif)
+ return -ENOMEM;
+ plat_data = devm_kzalloc(&pdev->dev,
+ sizeof(struct mxc_lcd_platform_data),
+ GFP_KERNEL);
+ if (!plat_data)
+ return -ENOMEM;
+ pdev->dev.platform_data = plat_data;
+
+ ret = lcd_get_of_property(pdev, plat_data);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "get lcd of property fail\n");
+ return ret;
+ }
+
+ pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
+ if (IS_ERR(pinctrl)) {
+ dev_err(&pdev->dev, "can't get/select pinctrl\n");
+ return PTR_ERR(pinctrl);
+ }
+
+ lcdif->pdev = pdev;
+ lcdif->disp_lcdif = mxc_dispdrv_register(&lcdif_drv);
+ mxc_dispdrv_setdata(lcdif->disp_lcdif, lcdif);
+
+ dev_set_drvdata(&pdev->dev, lcdif);
+ dev_dbg(&pdev->dev, "%s exit\n", __func__);
+
+ return ret;
+}
+
+static int mxc_lcdif_remove(struct platform_device *pdev)
+{
+ struct mxc_lcdif_data *lcdif = dev_get_drvdata(&pdev->dev);
+
+ mxc_dispdrv_puthandle(lcdif->disp_lcdif);
+ mxc_dispdrv_unregister(lcdif->disp_lcdif);
+ kfree(lcdif);
+ return 0;
+}
+
+static const struct of_device_id imx_lcd_dt_ids[] = {
+ { .compatible = "fsl,lcd"},
+ { /* sentinel */ }
+};
+static struct platform_driver mxc_lcdif_driver = {
+ .driver = {
+ .name = "mxc_lcdif",
+ .of_match_table = imx_lcd_dt_ids,
+ },
+ .probe = mxc_lcdif_probe,
+ .remove = mxc_lcdif_remove,
+};
+
+static int __init mxc_lcdif_init(void)
+{
+ return platform_driver_register(&mxc_lcdif_driver);
+}
+
+static void __exit mxc_lcdif_exit(void)
+{
+ platform_driver_unregister(&mxc_lcdif_driver);
+}
+
+module_init(mxc_lcdif_init);
+module_exit(mxc_lcdif_exit);
+
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("i.MX ipuv3 LCD extern port driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/video/fbdev/mxc/mxcfb_hx8363_wvga.c b/drivers/video/fbdev/mxc/mxcfb_hx8363_wvga.c
new file mode 100644
index 000000000000..155e8491d765
--- /dev/null
+++ b/drivers/video/fbdev/mxc/mxcfb_hx8363_wvga.c
@@ -0,0 +1,220 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/console.h>
+#include <linux/io.h>
+#include <linux/bitops.h>
+#include <linux/spinlock.h>
+#include <linux/mipi_dsi.h>
+#include <linux/mxcfb.h>
+#include <linux/backlight.h>
+#include <video/mipi_display.h>
+
+#include "mipi_dsi.h"
+
+#define HX8363_TWO_DATA_LANE (0x2)
+#define HX8363_MAX_DPHY_CLK (800)
+#define HX8363_CMD_GETHXID (0xF4)
+#define HX8363_CMD_GETHXID_LEN (0x4)
+#define HX8363_ID (0x84)
+#define HX8363_ID_MASK (0xFF)
+
+
+#define CHECK_RETCODE(ret) \
+do { \
+ if (ret < 0) { \
+ dev_err(&mipi_dsi->pdev->dev, \
+ "%s ERR: ret:%d, line:%d.\n", \
+ __func__, ret, __LINE__); \
+ return ret; \
+ } \
+} while (0)
+
+static void parse_variadic(int n, u8 *buf, ...)
+{
+ int i = 0;
+ va_list args;
+
+ if (unlikely(!n)) return;
+
+ va_start(args, buf);
+
+ for (i = 0; i < n; i++)
+ buf[i + 1] = (u8)va_arg(args, int);
+
+ va_end(args);
+}
+
+#define TC358763_DCS_write_1A_nP(n, addr, ...) { \
+ int err; \
+ \
+ buf[0] = addr; \
+ parse_variadic(n, buf, ##__VA_ARGS__); \
+ \
+ if (n >= 2) \
+ err = mipi_dsi->mipi_dsi_pkt_write(mipi_dsi, \
+ MIPI_DSI_DCS_LONG_WRITE, (u32*)buf, n + 1); \
+ else if (n == 1) \
+ err = mipi_dsi->mipi_dsi_pkt_write(mipi_dsi, \
+ MIPI_DSI_DCS_SHORT_WRITE_PARAM, (u32*)buf, 0); \
+ else if (n == 0) \
+ { \
+ buf[1] = 0; \
+ err = mipi_dsi->mipi_dsi_pkt_write(mipi_dsi, \
+ MIPI_DSI_DCS_SHORT_WRITE, (u32*)buf, 0); \
+ } \
+ CHECK_RETCODE(err); \
+}
+
+#define TC358763_DCS_write_1A_0P(addr) \
+ TC358763_DCS_write_1A_nP(0, addr)
+
+#define TC358763_DCS_write_1A_1P(addr, ...) \
+ TC358763_DCS_write_1A_nP(1, addr, __VA_ARGS__)
+
+#define TC358763_DCS_write_1A_2P(addr, ...) \
+ TC358763_DCS_write_1A_nP(2, addr, __VA_ARGS__)
+
+#define TC358763_DCS_write_1A_3P(addr, ...) \
+ TC358763_DCS_write_1A_nP(3, addr, __VA_ARGS__)
+
+#define TC358763_DCS_write_1A_5P(addr, ...) \
+ TC358763_DCS_write_1A_nP(5, addr, __VA_ARGS__)
+
+#define TC358763_DCS_write_1A_6P(addr, ...) \
+ TC358763_DCS_write_1A_nP(6, addr, __VA_ARGS__)
+
+#define TC358763_DCS_write_1A_7P(addr, ...) \
+ TC358763_DCS_write_1A_nP(7, addr, __VA_ARGS__)
+
+#define TC358763_DCS_write_1A_12P(addr, ...) \
+ TC358763_DCS_write_1A_nP(12, addr, __VA_ARGS__)
+
+#define TC358763_DCS_write_1A_13P(addr, ...) \
+ TC358763_DCS_write_1A_nP(13, addr, __VA_ARGS__)
+
+#define TC358763_DCS_write_1A_14P(addr, ...) \
+ TC358763_DCS_write_1A_nP(14, addr, __VA_ARGS__)
+
+#define TC358763_DCS_write_1A_19P(addr, ...) \
+ TC358763_DCS_write_1A_nP(19, addr, __VA_ARGS__)
+
+#define TC358763_DCS_write_1A_34P(addr, ...) \
+ TC358763_DCS_write_1A_nP(34, addr, __VA_ARGS__)
+
+#define TC358763_DCS_write_1A_127P(addr, ...) \
+ TC358763_DCS_write_1A_nP(127, addr, __VA_ARGS__)
+
+static int hx8363bl_brightness;
+
+#define ACTIVE_HIGH_NAME "TRUULY-WVGA-SYNC-HIGH"
+#define ACTIVE_LOW_NAME "TRUULY-WVGA-SYNC-LOW"
+
+static struct fb_videomode truly_lcd_modedb[] = {
+ {
+ ACTIVE_HIGH_NAME, 50, 480, 854, 41042,
+ 40, 60,
+ 3, 3,
+ 8, 4,
+ 0x0,
+ FB_VMODE_NONINTERLACED,
+ 0,
+ }, {
+ ACTIVE_LOW_NAME, 50, 480, 854, 41042,
+ 40, 60,
+ 3, 3,
+ 8, 4,
+ FB_SYNC_OE_LOW_ACT,
+ FB_VMODE_NONINTERLACED,
+ 0,
+ },
+};
+
+static struct mipi_lcd_config lcd_config = {
+ .virtual_ch = 0x0,
+ .data_lane_num = HX8363_TWO_DATA_LANE,
+ .max_phy_clk = HX8363_MAX_DPHY_CLK,
+ .dpi_fmt = MIPI_RGB888,
+};
+
+void mipid_hx8363_get_lcd_videomode(struct fb_videomode **mode, int *size,
+ struct mipi_lcd_config **data)
+{
+ *mode = &truly_lcd_modedb[0];
+ *size = ARRAY_SIZE(truly_lcd_modedb);
+ *data = &lcd_config;
+}
+
+int mipid_hx8363_lcd_setup(struct mipi_dsi_info *mipi_dsi)
+{
+ u8 buf[DSI_CMD_BUF_MAXSIZE];
+
+ dev_dbg(&mipi_dsi->pdev->dev, "MIPI DSI LCD HX8363 setup.\n");
+
+ TC358763_DCS_write_1A_3P(0xB9,0xFF,0x83,0x63);/* SET password */
+
+ TC358763_DCS_write_1A_19P(0xB1,0x01,0x00,0x44,0x08,0x01,0x10,0x10,0x36,
+ 0x3E,0x1A,0x1A,0x40,0x12,0x00,0xE6,0xE6,0xE6,0xE6,0xE6);/* Set Power */
+ TC358763_DCS_write_1A_2P(0xB2,0x08,0x03);/* Set DISP */
+ TC358763_DCS_write_1A_7P(0xB4,0x02,0x18,0x9C,0x08,0x18,0x04,0x6C);
+ TC358763_DCS_write_1A_1P(0xB6,0x00);/* Set VCOM */
+ TC358763_DCS_write_1A_1P(0xCC,0x0B);/* Set Panel */
+ TC358763_DCS_write_1A_34P(0xE0,0x0E,0x15,0x19,0x30,0x31,0x3F,0x27,0x3C,0x88,0x8F,0xD1,0xD5,0xD7,0x16,0x16,
+ 0x0C,0x1E,0x0E,0x15,0x19,0x30,0x31,0x3F,0x27,0x3C,0x88,0x8F,
+ 0xD1,0xD5,0xD7,0x16,0x16,0x0C,0x1E);
+ mdelay(5);
+
+ TC358763_DCS_write_1A_1P(0x3A,0x77);/* 24bit */
+ TC358763_DCS_write_1A_14P(0xBA,0x11,0x00,0x56,0xC6,0x10,0x89,0xFF,0x0F,0x32,0x6E,0x04,0x07,0x9A,0x92);
+ TC358763_DCS_write_1A_0P(0x21);
+
+ TC358763_DCS_write_1A_0P(0x11);
+ msleep(10);
+
+ TC358763_DCS_write_1A_0P(0x29);
+ msleep(120);
+
+ return 0;
+}
+
+static int mipid_bl_update_status(struct backlight_device *bl)
+{
+ return 0;
+}
+
+static int mipid_bl_get_brightness(struct backlight_device *bl)
+{
+ return hx8363bl_brightness;
+}
+
+static int mipi_bl_check_fb(struct backlight_device *bl, struct fb_info *fbi)
+{
+ return 0;
+}
+
+static const struct backlight_ops mipid_lcd_bl_ops = {
+ .update_status = mipid_bl_update_status,
+ .get_brightness = mipid_bl_get_brightness,
+ .check_fb = mipi_bl_check_fb,
+};
diff --git a/drivers/video/fbdev/mxc/mxcfb_hx8369_wvga.c b/drivers/video/fbdev/mxc/mxcfb_hx8369_wvga.c
new file mode 100644
index 000000000000..d461662bf4de
--- /dev/null
+++ b/drivers/video/fbdev/mxc/mxcfb_hx8369_wvga.c
@@ -0,0 +1,453 @@
+/*
+ * Copyright (C) 2011-2015 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/console.h>
+#include <linux/io.h>
+#include <linux/bitops.h>
+#include <linux/spinlock.h>
+#include <linux/mipi_dsi.h>
+#include <linux/mxcfb.h>
+#include <linux/backlight.h>
+#include <video/mipi_display.h>
+
+#include "mipi_dsi.h"
+
+#define MIPI_DSI_MAX_RET_PACK_SIZE (0x4)
+
+#define HX8369BL_MAX_BRIGHT (255)
+#define HX8369BL_DEF_BRIGHT (255)
+
+#define HX8369_MAX_DPHY_CLK (800)
+#define HX8369_ONE_DATA_LANE (0x1)
+#define HX8369_TWO_DATA_LANE (0x2)
+
+#define HX8369_CMD_SETEXTC (0xB9)
+#define HX8369_CMD_SETEXTC_LEN (0x4)
+#define HX8369_CMD_SETEXTC_PARAM_1 (0x6983ff)
+
+#define HX8369_CMD_GETHXID (0xF4)
+#define HX8369_CMD_GETHXID_LEN (0x4)
+#define HX8369_ID (0x69)
+#define HX8369_ID_MASK (0xFF)
+
+#define HX8369_CMD_SETDISP (0xB2)
+#define HX8369_CMD_SETDISP_LEN (16)
+#define HX8369_CMD_SETDISP_1_HALT (0x00)
+#define HX8369_CMD_SETDISP_2_RES_MODE (0x23)
+#define HX8369_CMD_SETDISP_3_BP (0x03)
+#define HX8369_CMD_SETDISP_4_FP (0x03)
+#define HX8369_CMD_SETDISP_5_SAP (0x70)
+#define HX8369_CMD_SETDISP_6_GENON (0x00)
+#define HX8369_CMD_SETDISP_7_GENOFF (0xff)
+#define HX8369_CMD_SETDISP_8_RTN (0x00)
+#define HX8369_CMD_SETDISP_9_TEI (0x00)
+#define HX8369_CMD_SETDISP_10_TEP_UP (0x00)
+#define HX8369_CMD_SETDISP_11_TEP_LOW (0x00)
+#define HX8369_CMD_SETDISP_12_BP_PE (0x03)
+#define HX8369_CMD_SETDISP_13_FP_PE (0x03)
+#define HX8369_CMD_SETDISP_14_RTN_PE (0x00)
+#define HX8369_CMD_SETDISP_15_GON (0x01)
+
+#define HX8369_CMD_SETCYC (0xB4)
+#define HX8369_CMD_SETCYC_LEN (6)
+#define HX8369_CMD_SETCYC_PARAM_1 (0x5f1d00)
+#define HX8369_CMD_SETCYC_PARAM_2 (0x060e)
+
+#define HX8369_CMD_SETGIP (0xD5)
+#define HX8369_CMD_SETGIP_LEN (27)
+#define HX8369_CMD_SETGIP_PARAM_1 (0x030400)
+#define HX8369_CMD_SETGIP_PARAM_2 (0x1c050100)
+#define HX8369_CMD_SETGIP_PARAM_3 (0x00030170)
+#define HX8369_CMD_SETGIP_PARAM_4 (0x51064000)
+#define HX8369_CMD_SETGIP_PARAM_5 (0x41000007)
+#define HX8369_CMD_SETGIP_PARAM_6 (0x07075006)
+#define HX8369_CMD_SETGIP_PARAM_7 (0x040f)
+
+#define HX8369_CMD_SETPOWER (0xB1)
+#define HX8369_CMD_SETPOWER_LEN (20)
+#define HX8369_CMD_SETPOWER_PARAM_1 (0x340001)
+#define HX8369_CMD_SETPOWER_PARAM_2 (0x0f0f0006)
+#define HX8369_CMD_SETPOWER_PARAM_3 (0x3f3f322a)
+#define HX8369_CMD_SETPOWER_PARAM_4 (0xe6013a07)
+#define HX8369_CMD_SETPOWER_PARAM_5 (0xe6e6e6e6)
+
+#define HX8369_CMD_SETVCOM (0xB6)
+#define HX8369_CMD_SETVCOM_LEN (3)
+#define HX8369_CMD_SETVCOM_PARAM_1 (0x5656)
+
+#define HX8369_CMD_SETPANEL (0xCC)
+#define HX8369_CMD_SETPANEL_PARAM_1 (0x02)
+
+#define HX8369_CMD_SETGAMMA (0xE0)
+#define HX8369_CMD_SETGAMMA_LEN (35)
+#define HX8369_CMD_SETGAMMA_PARAM_1 (0x221d00)
+#define HX8369_CMD_SETGAMMA_PARAM_2 (0x2e3f3d38)
+#define HX8369_CMD_SETGAMMA_PARAM_3 (0x0f0d064a)
+#define HX8369_CMD_SETGAMMA_PARAM_4 (0x16131513)
+#define HX8369_CMD_SETGAMMA_PARAM_5 (0x1d001910)
+#define HX8369_CMD_SETGAMMA_PARAM_6 (0x3f3d3822)
+#define HX8369_CMD_SETGAMMA_PARAM_7 (0x0d064a2e)
+#define HX8369_CMD_SETGAMMA_PARAM_8 (0x1315130f)
+#define HX8369_CMD_SETGAMMA_PARAM_9 (0x191016)
+
+#define HX8369_CMD_SETMIPI (0xBA)
+#define HX8369_CMD_SETMIPI_LEN (14)
+#define HX8369_CMD_SETMIPI_PARAM_1 (0xc6a000)
+#define HX8369_CMD_SETMIPI_PARAM_2 (0x10000a00)
+#define HX8369_CMD_SETMIPI_ONELANE (0x10 << 24)
+#define HX8369_CMD_SETMIPI_TWOLANE (0x11 << 24)
+#define HX8369_CMD_SETMIPI_PARAM_3 (0x00026f30)
+#define HX8369_CMD_SETMIPI_PARAM_4 (0x4018)
+
+#define HX8369_CMD_SETPIXEL_FMT (0x3A)
+#define HX8369_CMD_SETPIXEL_FMT_24BPP (0x77)
+#define HX8369_CMD_SETPIXEL_FMT_18BPP (0x66)
+#define HX8369_CMD_SETPIXEL_FMT_16BPP (0x55)
+
+#define HX8369_CMD_SETCLUMN_ADDR (0x2A)
+#define HX8369_CMD_SETCLUMN_ADDR_LEN (5)
+#define HX8369_CMD_SETCLUMN_ADDR_PARAM_1 (0xdf0000)
+#define HX8369_CMD_SETCLUMN_ADDR_PARAM_2 (0x01)
+
+#define HX8369_CMD_SETPAGE_ADDR (0x2B)
+#define HX8369_CMD_SETPAGE_ADDR_LEN (5)
+#define HX8369_CMD_SETPAGE_ADDR_PARAM_1 (0x1f0000)
+#define HX8369_CMD_SETPAGE_ADDR_PARAM_2 (0x03)
+
+#define HX8369_CMD_WRT_DISP_BRIGHT (0x51)
+#define HX8369_CMD_WRT_DISP_BRIGHT_PARAM_1 (0xFF)
+
+#define HX8369_CMD_WRT_CABC_MIN_BRIGHT (0x5E)
+#define HX8369_CMD_WRT_CABC_MIN_BRIGHT_PARAM_1 (0x20)
+
+#define HX8369_CMD_WRT_CABC_CTRL (0x55)
+#define HX8369_CMD_WRT_CABC_CTRL_PARAM_1 (0x1)
+
+#define HX8369_CMD_WRT_CTRL_DISP (0x53)
+#define HX8369_CMD_WRT_CTRL_DISP_PARAM_1 (0x24)
+
+#define CHECK_RETCODE(ret) \
+do { \
+ if (ret < 0) { \
+ dev_err(&mipi_dsi->pdev->dev, \
+ "%s ERR: ret:%d, line:%d.\n", \
+ __func__, ret, __LINE__); \
+ return ret; \
+ } \
+} while (0)
+
+static int hx8369bl_brightness;
+static int mipid_init_backlight(struct mipi_dsi_info *mipi_dsi);
+
+static struct fb_videomode truly_lcd_modedb[] = {
+ {
+ "TRULY-WVGA", 64, 480, 800, 37880,
+ 8, 8,
+ 6, 6,
+ 8, 6,
+ FB_SYNC_OE_LOW_ACT,
+ FB_VMODE_NONINTERLACED,
+ 0,
+ },
+};
+
+static struct mipi_lcd_config lcd_config = {
+ .virtual_ch = 0x0,
+ .data_lane_num = HX8369_TWO_DATA_LANE,
+ .max_phy_clk = HX8369_MAX_DPHY_CLK,
+ .dpi_fmt = MIPI_RGB888,
+};
+void mipid_hx8369_get_lcd_videomode(struct fb_videomode **mode, int *size,
+ struct mipi_lcd_config **data)
+{
+ *mode = &truly_lcd_modedb[0];
+ *size = ARRAY_SIZE(truly_lcd_modedb);
+ *data = &lcd_config;
+}
+EXPORT_SYMBOL(mipid_hx8369_get_lcd_videomode);
+
+int mipid_hx8369_lcd_setup(struct mipi_dsi_info *mipi_dsi)
+{
+ u32 buf[DSI_CMD_BUF_MAXSIZE];
+ int err;
+
+ dev_dbg(&mipi_dsi->pdev->dev, "MIPI DSI LCD setup.\n");
+ buf[0] = HX8369_CMD_SETEXTC | (HX8369_CMD_SETEXTC_PARAM_1 << 8);
+ err = mipi_dsi->mipi_dsi_pkt_write(mipi_dsi, MIPI_DSI_GENERIC_LONG_WRITE,
+ buf, HX8369_CMD_SETEXTC_LEN);
+ CHECK_RETCODE(err);
+ buf[0] = MIPI_DSI_MAX_RET_PACK_SIZE;
+ err = mipi_dsi->mipi_dsi_pkt_write(mipi_dsi,
+ MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE,
+ buf, 0);
+ CHECK_RETCODE(err);
+ buf[0] = HX8369_CMD_GETHXID;
+ err = mipi_dsi->mipi_dsi_pkt_read(mipi_dsi,
+ MIPI_DSI_GENERIC_READ_REQUEST_2_PARAM,
+ buf, HX8369_CMD_GETHXID_LEN);
+ if (!err && ((buf[0] & HX8369_ID_MASK) == HX8369_ID)) {
+ dev_info(&mipi_dsi->pdev->dev,
+ "MIPI DSI LCD ID:0x%x.\n", buf[0]);
+ } else {
+ dev_err(&mipi_dsi->pdev->dev,
+ "mipi_dsi_pkt_read err:%d, data:0x%x.\n",
+ err, buf[0]);
+ dev_info(&mipi_dsi->pdev->dev,
+ "MIPI DSI LCD not detected!\n");
+ return err;
+ }
+
+ /* set LCD resolution as 480RGBx800, DPI interface,
+ * display operation mode: RGB data bypass GRAM mode.
+ */
+ buf[0] = HX8369_CMD_SETDISP | (HX8369_CMD_SETDISP_1_HALT << 8) |
+ (HX8369_CMD_SETDISP_2_RES_MODE << 16) |
+ (HX8369_CMD_SETDISP_3_BP << 24);
+ buf[1] = HX8369_CMD_SETDISP_4_FP | (HX8369_CMD_SETDISP_5_SAP << 8) |
+ (HX8369_CMD_SETDISP_6_GENON << 16) |
+ (HX8369_CMD_SETDISP_7_GENOFF << 24);
+ buf[2] = HX8369_CMD_SETDISP_8_RTN | (HX8369_CMD_SETDISP_9_TEI << 8) |
+ (HX8369_CMD_SETDISP_10_TEP_UP << 16) |
+ (HX8369_CMD_SETDISP_11_TEP_LOW << 24);
+ buf[3] = HX8369_CMD_SETDISP_12_BP_PE |
+ (HX8369_CMD_SETDISP_13_FP_PE << 8) |
+ (HX8369_CMD_SETDISP_14_RTN_PE << 16) |
+ (HX8369_CMD_SETDISP_15_GON << 24);
+ err = mipi_dsi->mipi_dsi_pkt_write(mipi_dsi, MIPI_DSI_GENERIC_LONG_WRITE,
+ buf, HX8369_CMD_SETDISP_LEN);
+ CHECK_RETCODE(err);
+
+ /* Set display waveform cycle */
+ buf[0] = HX8369_CMD_SETCYC | (HX8369_CMD_SETCYC_PARAM_1 << 8);
+ buf[1] = HX8369_CMD_SETCYC_PARAM_2;
+ err = mipi_dsi->mipi_dsi_pkt_write(mipi_dsi, MIPI_DSI_GENERIC_LONG_WRITE,
+ buf, HX8369_CMD_SETCYC_LEN);
+ CHECK_RETCODE(err);
+
+ /* Set GIP timing output control */
+ buf[0] = HX8369_CMD_SETGIP | (HX8369_CMD_SETGIP_PARAM_1 << 8);
+ buf[1] = HX8369_CMD_SETGIP_PARAM_2;
+ buf[2] = HX8369_CMD_SETGIP_PARAM_3;
+ buf[3] = HX8369_CMD_SETGIP_PARAM_4;
+ buf[4] = HX8369_CMD_SETGIP_PARAM_5;
+ buf[5] = HX8369_CMD_SETGIP_PARAM_6;
+ buf[6] = HX8369_CMD_SETGIP_PARAM_7;
+ err = mipi_dsi->mipi_dsi_pkt_write(mipi_dsi, MIPI_DSI_GENERIC_LONG_WRITE, buf,
+ HX8369_CMD_SETGIP_LEN);
+ CHECK_RETCODE(err);
+
+ /* Set power: standby, DC etc. */
+ buf[0] = HX8369_CMD_SETPOWER | (HX8369_CMD_SETPOWER_PARAM_1 << 8);
+ buf[1] = HX8369_CMD_SETPOWER_PARAM_2;
+ buf[2] = HX8369_CMD_SETPOWER_PARAM_3;
+ buf[3] = HX8369_CMD_SETPOWER_PARAM_4;
+ buf[4] = HX8369_CMD_SETPOWER_PARAM_5;
+ err = mipi_dsi->mipi_dsi_pkt_write(mipi_dsi, MIPI_DSI_GENERIC_LONG_WRITE, buf,
+ HX8369_CMD_SETPOWER_LEN);
+ CHECK_RETCODE(err);
+
+ /* Set VCOM voltage. */
+ buf[0] = HX8369_CMD_SETVCOM | (HX8369_CMD_SETVCOM_PARAM_1 << 8);
+ err = mipi_dsi->mipi_dsi_pkt_write(mipi_dsi, MIPI_DSI_GENERIC_LONG_WRITE, buf,
+ HX8369_CMD_SETVCOM_LEN);
+ CHECK_RETCODE(err);
+
+ /* Set Panel: BGR/RGB or Inversion. */
+ buf[0] = HX8369_CMD_SETPANEL | (HX8369_CMD_SETPANEL_PARAM_1 << 8);
+ err = mipi_dsi->mipi_dsi_pkt_write(mipi_dsi,
+ MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM, buf, 0);
+ CHECK_RETCODE(err);
+
+ /* Set gamma curve related setting */
+ buf[0] = HX8369_CMD_SETGAMMA | (HX8369_CMD_SETGAMMA_PARAM_1 << 8);
+ buf[1] = HX8369_CMD_SETGAMMA_PARAM_2;
+ buf[2] = HX8369_CMD_SETGAMMA_PARAM_3;
+ buf[3] = HX8369_CMD_SETGAMMA_PARAM_4;
+ buf[4] = HX8369_CMD_SETGAMMA_PARAM_5;
+ buf[5] = HX8369_CMD_SETGAMMA_PARAM_6;
+ buf[6] = HX8369_CMD_SETGAMMA_PARAM_7;
+ buf[7] = HX8369_CMD_SETGAMMA_PARAM_8;
+ buf[8] = HX8369_CMD_SETGAMMA_PARAM_9;
+ err = mipi_dsi->mipi_dsi_pkt_write(mipi_dsi, MIPI_DSI_GENERIC_LONG_WRITE, buf,
+ HX8369_CMD_SETGAMMA_LEN);
+ CHECK_RETCODE(err);
+
+ /* Set MIPI: DPHYCMD & DSICMD, data lane number */
+ buf[0] = HX8369_CMD_SETMIPI | (HX8369_CMD_SETMIPI_PARAM_1 << 8);
+ buf[1] = HX8369_CMD_SETMIPI_PARAM_2;
+ buf[2] = HX8369_CMD_SETMIPI_PARAM_3;
+ if (lcd_config.data_lane_num == HX8369_ONE_DATA_LANE)
+ buf[2] |= HX8369_CMD_SETMIPI_ONELANE;
+ else
+ buf[2] |= HX8369_CMD_SETMIPI_TWOLANE;
+ buf[3] = HX8369_CMD_SETMIPI_PARAM_4;
+ err = mipi_dsi->mipi_dsi_pkt_write(mipi_dsi, MIPI_DSI_GENERIC_LONG_WRITE, buf,
+ HX8369_CMD_SETMIPI_LEN);
+ CHECK_RETCODE(err);
+
+ /* Set pixel format:24bpp */
+ buf[0] = HX8369_CMD_SETPIXEL_FMT;
+ switch (lcd_config.dpi_fmt) {
+ case MIPI_RGB565_PACKED:
+ case MIPI_RGB565_LOOSELY:
+ case MIPI_RGB565_CONFIG3:
+ buf[0] |= (HX8369_CMD_SETPIXEL_FMT_16BPP << 8);
+ break;
+
+ case MIPI_RGB666_LOOSELY:
+ case MIPI_RGB666_PACKED:
+ buf[0] |= (HX8369_CMD_SETPIXEL_FMT_18BPP << 8);
+ break;
+
+ case MIPI_RGB888:
+ buf[0] |= (HX8369_CMD_SETPIXEL_FMT_24BPP << 8);
+ break;
+
+ default:
+ buf[0] |= (HX8369_CMD_SETPIXEL_FMT_24BPP << 8);
+ break;
+ }
+ err = mipi_dsi->mipi_dsi_pkt_write(mipi_dsi, MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM,
+ buf, 0);
+ CHECK_RETCODE(err);
+
+ /* Set column address: 0~479 */
+ buf[0] = HX8369_CMD_SETCLUMN_ADDR |
+ (HX8369_CMD_SETCLUMN_ADDR_PARAM_1 << 8);
+ buf[1] = HX8369_CMD_SETCLUMN_ADDR_PARAM_2;
+ err = mipi_dsi->mipi_dsi_pkt_write(mipi_dsi, MIPI_DSI_GENERIC_LONG_WRITE,
+ buf, HX8369_CMD_SETCLUMN_ADDR_LEN);
+ CHECK_RETCODE(err);
+
+ /* Set page address: 0~799 */
+ buf[0] = HX8369_CMD_SETPAGE_ADDR |
+ (HX8369_CMD_SETPAGE_ADDR_PARAM_1 << 8);
+ buf[1] = HX8369_CMD_SETPAGE_ADDR_PARAM_2;
+ err = mipi_dsi->mipi_dsi_pkt_write(mipi_dsi, MIPI_DSI_GENERIC_LONG_WRITE,
+ buf, HX8369_CMD_SETPAGE_ADDR_LEN);
+ CHECK_RETCODE(err);
+
+ /* Set display brightness related */
+ buf[0] = HX8369_CMD_WRT_DISP_BRIGHT |
+ (HX8369_CMD_WRT_DISP_BRIGHT_PARAM_1 << 8);
+ err = mipi_dsi->mipi_dsi_pkt_write(mipi_dsi, MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM,
+ buf, 0);
+ CHECK_RETCODE(err);
+
+ buf[0] = HX8369_CMD_WRT_CABC_CTRL |
+ (HX8369_CMD_WRT_CABC_CTRL_PARAM_1 << 8);
+ err = mipi_dsi->mipi_dsi_pkt_write(mipi_dsi, MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM,
+ buf, 0);
+ CHECK_RETCODE(err);
+
+ buf[0] = HX8369_CMD_WRT_CTRL_DISP |
+ (HX8369_CMD_WRT_CTRL_DISP_PARAM_1 << 8);
+ err = mipi_dsi->mipi_dsi_pkt_write(mipi_dsi, MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM,
+ buf, 0);
+ CHECK_RETCODE(err);
+
+ /* exit sleep mode and set display on */
+ buf[0] = MIPI_DCS_EXIT_SLEEP_MODE;
+ err = mipi_dsi->mipi_dsi_pkt_write(mipi_dsi, MIPI_DSI_GENERIC_SHORT_WRITE_1_PARAM,
+ buf, 0);
+ CHECK_RETCODE(err);
+ /* To allow time for the supply voltages
+ * and clock circuits to stabilize.
+ */
+ msleep(5);
+ buf[0] = MIPI_DCS_SET_DISPLAY_ON;
+ err = mipi_dsi->mipi_dsi_pkt_write(mipi_dsi, MIPI_DSI_GENERIC_SHORT_WRITE_1_PARAM,
+ buf, 0);
+ CHECK_RETCODE(err);
+
+ err = mipid_init_backlight(mipi_dsi);
+ return err;
+}
+EXPORT_SYMBOL(mipid_hx8369_lcd_setup);
+
+static int mipid_bl_update_status(struct backlight_device *bl)
+{
+ int err;
+ u32 buf;
+ int brightness = bl->props.brightness;
+ struct mipi_dsi_info *mipi_dsi = bl_get_data(bl);
+
+ if (bl->props.power != FB_BLANK_UNBLANK ||
+ bl->props.fb_blank != FB_BLANK_UNBLANK)
+ brightness = 0;
+
+ buf = HX8369_CMD_WRT_DISP_BRIGHT |
+ ((brightness & HX8369BL_MAX_BRIGHT) << 8);
+ err = mipi_dsi->mipi_dsi_pkt_write(mipi_dsi, MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM,
+ &buf, 0);
+ CHECK_RETCODE(err);
+
+ hx8369bl_brightness = brightness & HX8369BL_MAX_BRIGHT;
+
+ dev_dbg(&bl->dev, "mipid backlight bringtness:%d.\n", brightness);
+ return 0;
+}
+
+static int mipid_bl_get_brightness(struct backlight_device *bl)
+{
+ return hx8369bl_brightness;
+}
+
+static int mipi_bl_check_fb(struct backlight_device *bl, struct fb_info *fbi)
+{
+ return 0;
+}
+
+static const struct backlight_ops mipid_lcd_bl_ops = {
+ .update_status = mipid_bl_update_status,
+ .get_brightness = mipid_bl_get_brightness,
+ .check_fb = mipi_bl_check_fb,
+};
+
+static int mipid_init_backlight(struct mipi_dsi_info *mipi_dsi)
+{
+ struct backlight_properties props;
+ struct backlight_device *bl;
+
+ if (mipi_dsi->bl) {
+ pr_debug("mipid backlight already init!\n");
+ return 0;
+ }
+ memset(&props, 0, sizeof(struct backlight_properties));
+ props.max_brightness = HX8369BL_MAX_BRIGHT;
+ props.type = BACKLIGHT_RAW;
+ bl = backlight_device_register("mipid-bl", &mipi_dsi->pdev->dev,
+ mipi_dsi, &mipid_lcd_bl_ops, &props);
+ if (IS_ERR(bl)) {
+ pr_err("error %ld on backlight register\n", PTR_ERR(bl));
+ return PTR_ERR(bl);
+ }
+ mipi_dsi->bl = bl;
+ bl->props.power = FB_BLANK_UNBLANK;
+ bl->props.fb_blank = FB_BLANK_UNBLANK;
+ bl->props.brightness = HX8369BL_DEF_BRIGHT;
+
+ mipid_bl_update_status(bl);
+ return 0;
+}
diff --git a/drivers/video/fbdev/mxc/mxcfb_otm8018b_wvga.c b/drivers/video/fbdev/mxc/mxcfb_otm8018b_wvga.c
new file mode 100644
index 000000000000..fa7db02f37f6
--- /dev/null
+++ b/drivers/video/fbdev/mxc/mxcfb_otm8018b_wvga.c
@@ -0,0 +1,266 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/console.h>
+#include <linux/io.h>
+#include <linux/bitops.h>
+#include <linux/spinlock.h>
+#include <linux/mipi_dsi.h>
+#include <linux/mxcfb.h>
+#include <linux/backlight.h>
+#include <video/mipi_display.h>
+
+#include "mipi_dsi.h"
+
+#define OTM8018B_TWO_DATA_LANE (0x2)
+#define OTM8018B_MAX_DPHY_CLK (800)
+
+#define CHECK_RETCODE(ret) \
+do { \
+ if (ret < 0) { \
+ dev_err(&mipi_dsi->pdev->dev, \
+ "%s ERR: ret:%d, line:%d.\n", \
+ __func__, ret, __LINE__); \
+ return ret; \
+ } \
+} while (0)
+
+static void parse_variadic(int n, u8 *buf, ...)
+{
+ int i = 0;
+ va_list args;
+
+ if (unlikely(!n)) return;
+
+ va_start(args, buf);
+
+ for (i = 0; i < n; i++)
+ buf[i + 1] = (u8)va_arg(args, int);
+
+ va_end(args);
+}
+
+#define TC358763_DCS_write_1A_nP(n, addr, ...) { \
+ int err; \
+ \
+ buf[0] = addr; \
+ parse_variadic(n, buf, ##__VA_ARGS__); \
+ \
+ err = mipi_dsi->mipi_dsi_pkt_write(mipi_dsi, \
+ MIPI_DSI_GENERIC_LONG_WRITE, (u32*)buf, n + 1); \
+ CHECK_RETCODE(err); \
+}
+
+#define TC358763_DCS_write_1A_0P(addr) \
+ TC358763_DCS_write_1A_nP(0, addr)
+
+#define TC358763_DCS_write_1A_1P(addr, ...) \
+ TC358763_DCS_write_1A_nP(1, addr, __VA_ARGS__)
+
+#define TC358763_DCS_write_1A_2P(addr, ...) \
+ TC358763_DCS_write_1A_nP(2, addr, __VA_ARGS__)
+
+#define TC358763_DCS_write_1A_3P(addr, ...) \
+ TC358763_DCS_write_1A_nP(3, addr, __VA_ARGS__)
+
+#define TC358763_DCS_write_1A_5P(addr, ...) \
+ TC358763_DCS_write_1A_nP(5, addr, __VA_ARGS__)
+
+#define TC358763_DCS_write_1A_6P(addr, ...) \
+ TC358763_DCS_write_1A_nP(6, addr, __VA_ARGS__)
+
+#define TC358763_DCS_write_1A_12P(addr, ...) \
+ TC358763_DCS_write_1A_nP(12, addr, __VA_ARGS__)
+
+#define TC358763_DCS_write_1A_14P(addr, ...) \
+ TC358763_DCS_write_1A_nP(14, addr, __VA_ARGS__)
+
+static int otm8018bbl_brightness;
+
+static struct fb_videomode truly_lcd_modedb[] = {
+ {
+ "TRULY-WVGA", 64, 480, 800, 37880,
+ 8, 8,
+ 6, 6,
+ 8, 6,
+ FB_SYNC_OE_LOW_ACT,
+ FB_VMODE_NONINTERLACED,
+ 0,
+ },
+};
+
+static struct mipi_lcd_config lcd_config = {
+ .virtual_ch = 0x0,
+ .data_lane_num = OTM8018B_TWO_DATA_LANE,
+ .max_phy_clk = OTM8018B_MAX_DPHY_CLK,
+ .dpi_fmt = MIPI_RGB888,
+};
+
+void mipid_otm8018b_get_lcd_videomode(struct fb_videomode **mode, int *size,
+ struct mipi_lcd_config **data)
+{
+ *mode = &truly_lcd_modedb[0];
+ *size = ARRAY_SIZE(truly_lcd_modedb);
+ *data = &lcd_config;
+}
+
+int mipid_otm8018b_lcd_setup(struct mipi_dsi_info *mipi_dsi)
+{
+ u8 buf[DSI_CMD_BUF_MAXSIZE];
+
+ dev_dbg(&mipi_dsi->pdev->dev, "MIPI DSI LCD setup.\n");
+
+ TC358763_DCS_write_1A_3P(0xFF,0x80,0x09,0x01);
+ TC358763_DCS_write_1A_1P(0x00,0x80);
+ TC358763_DCS_write_1A_2P(0xFF,0x80,0x09);
+
+ TC358763_DCS_write_1A_1P(0x00,0x03);
+ TC358763_DCS_write_1A_1P(0xff,0x01);
+
+ TC358763_DCS_write_1A_1P(0x00,0xb4);
+ TC358763_DCS_write_1A_1P(0xc0,0x10);
+
+ TC358763_DCS_write_1A_1P(0x00,0x82);
+ TC358763_DCS_write_1A_1P(0xC5,0xa3);
+
+ TC358763_DCS_write_1A_1P(0x00,0x90);
+ TC358763_DCS_write_1A_2P(0xC5,0x96,0x76);
+
+ TC358763_DCS_write_1A_1P(0x00,0x00);
+ TC358763_DCS_write_1A_2P(0xD8,0x75,0x73);
+
+ TC358763_DCS_write_1A_1P(0x00,0x00);
+ TC358763_DCS_write_1A_1P(0xD9,0x5e);
+
+ TC358763_DCS_write_1A_1P(0x00,0x81);
+ TC358763_DCS_write_1A_1P(0xC1,0x66);
+
+ TC358763_DCS_write_1A_1P(0x00,0xA1);
+ TC358763_DCS_write_1A_1P(0xC1,0x08);
+
+ TC358763_DCS_write_1A_1P(0x00,0x89);
+ TC358763_DCS_write_1A_1P(0xC4,0x08);
+
+ TC358763_DCS_write_1A_1P(0x00,0xA2);
+ TC358763_DCS_write_1A_3P(0xC0,0x1B,0x00,0x02);
+
+ TC358763_DCS_write_1A_1P(0x00,0x81);
+ TC358763_DCS_write_1A_1P(0xC4,0x83);
+
+ TC358763_DCS_write_1A_1P(0x00,0x92);
+ TC358763_DCS_write_1A_1P(0xC5,0x01);
+
+ TC358763_DCS_write_1A_1P(0x00,0xb1);
+ TC358763_DCS_write_1A_1P(0xC5,0xa9);
+
+ TC358763_DCS_write_1A_1P(0x00,0x90);
+ TC358763_DCS_write_1A_6P(0xC0,0x00,0x44,0x00,0x00,0x00,0x03);
+
+ TC358763_DCS_write_1A_1P(0x00,0xA6);
+ TC358763_DCS_write_1A_3P(0xC1,0x00,0x00,0x00);
+
+ TC358763_DCS_write_1A_1P(0x00,0x80);
+ TC358763_DCS_write_1A_12P(0xCE,0x87,0x03,0x00,0x85,0x03,0x00,
+ 0x86,0x03,0x00,0x84,0x03,0x00);
+
+ TC358763_DCS_write_1A_1P(0x00,0xA0);
+ TC358763_DCS_write_1A_14P(0xCE,0x38,0x03,0x03,0x58,0x00,0x00,
+ 0x00,0x38,0x02,0x03,0x59,0x00,0x00,0x00);
+
+ TC358763_DCS_write_1A_1P(0x00,0xB0);
+ TC358763_DCS_write_1A_14P(0xCE,0x38,0x01,0x03,0x5a,0x00,0x00,
+ 0x00,0x38,0x00,0x03,0x5b,0x00,0x00,0x00);
+
+ TC358763_DCS_write_1A_1P(0x00,0xC0);
+ TC358763_DCS_write_1A_14P(0xCE,0x30,0x00,0x03,0x5c,0x00,0x00,
+ 0x00,0x30,0x01,0x03,0x5d,0x00,0x00,0x00);
+
+ TC358763_DCS_write_1A_1P(0x00,0xD0);
+ TC358763_DCS_write_1A_14P(0xCE,0x30,0x02,0x03,0x5e,0x00,0x00,
+ 0x00,0x30,0x03,0x03,0x5f,0x00,0x00,0x00);
+
+ TC358763_DCS_write_1A_1P(0x00,0xC7);
+ TC358763_DCS_write_1A_1P(0xCF,0x00);
+
+ TC358763_DCS_write_1A_1P(0x00,0xC9);
+ TC358763_DCS_write_1A_1P(0xCF,0x00);
+
+ TC358763_DCS_write_1A_1P(0x00,0xC4);
+ TC358763_DCS_write_1A_6P(0xCB,0x04,0x04,0x04,0x04,0x04,0x04);
+
+ TC358763_DCS_write_1A_1P(0x00,0xd9);
+ TC358763_DCS_write_1A_6P(0xCB,0x04,0x04,0x04,0x04,0x04,0x04);
+
+ TC358763_DCS_write_1A_1P(0x00,0x84);
+ TC358763_DCS_write_1A_6P(0xCc,0x0c,0x0a,0x10,0x0e,0x03,0x04);
+
+ TC358763_DCS_write_1A_1P(0x00,0x9e);
+ TC358763_DCS_write_1A_1P(0xCc,0x0b);
+
+ TC358763_DCS_write_1A_1P(0x00,0xA0);
+ TC358763_DCS_write_1A_5P(0xCC,0x09,0x0f,0x0d,0x01,0x02);
+
+ TC358763_DCS_write_1A_1P(0x00,0xb4);
+ TC358763_DCS_write_1A_5P(0xCC,0x0d,0x09,0x0b,0x02,0x01);
+
+ TC358763_DCS_write_1A_1P(0x00,0xce);
+ TC358763_DCS_write_1A_1P(0xCc,0x0e);
+
+ TC358763_DCS_write_1A_1P(0x00,0xD0);
+ TC358763_DCS_write_1A_5P(0xCC,0x10,0x0a,0x0c,0x04,0x03);
+
+ TC358763_DCS_write_1A_1P(0x00,0x00);
+ TC358763_DCS_write_1A_1P(0x3a,0x77);
+
+ TC358763_DCS_write_1A_0P(0x11);
+
+ msleep(200);
+
+ TC358763_DCS_write_1A_0P(0x29);
+
+ TC358763_DCS_write_1A_0P(0x2C);
+
+ return 0;
+}
+
+static int mipid_bl_update_status(struct backlight_device *bl)
+{
+ return 0;
+}
+
+static int mipid_bl_get_brightness(struct backlight_device *bl)
+{
+ return otm8018bbl_brightness;
+}
+
+static int mipi_bl_check_fb(struct backlight_device *bl, struct fb_info *fbi)
+{
+ return 0;
+}
+
+static const struct backlight_ops mipid_lcd_bl_ops = {
+ .update_status = mipid_bl_update_status,
+ .get_brightness = mipid_bl_get_brightness,
+ .check_fb = mipi_bl_check_fb,
+};
diff --git a/drivers/video/fbdev/mxc/mxcfb_rm68191_qhd.c b/drivers/video/fbdev/mxc/mxcfb_rm68191_qhd.c
new file mode 100644
index 000000000000..4faa9b6c6509
--- /dev/null
+++ b/drivers/video/fbdev/mxc/mxcfb_rm68191_qhd.c
@@ -0,0 +1,264 @@
+/*
+ * Copyright 2018 NXP
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/console.h>
+#include <linux/io.h>
+#include <linux/bitops.h>
+#include <linux/spinlock.h>
+#include <linux/mipi_dsi.h>
+#include <linux/mxcfb.h>
+#include <linux/backlight.h>
+#include <video/mipi_display.h>
+
+#include "mipi_dsi.h"
+
+#define RM68191_MAX_DPHY_CLK (850)
+
+#define CHECK_RETCODE(ret) \
+do { \
+ if (ret < 0) { \
+ dev_err(&mipi_dsi->pdev->dev, \
+ "%s ERR: ret:%d, line:%d.\n", \
+ __func__, ret, __LINE__); \
+ return ret; \
+ } \
+} while (0)
+
+static void parse_variadic(int n, u8 *buf, ...)
+{
+ int i = 0;
+ va_list args;
+
+ if (unlikely(!n)) return;
+
+ va_start(args, buf);
+
+ for (i = 0; i < n; i++)
+ buf[i + 1] = (u8)va_arg(args, int);
+
+ va_end(args);
+}
+
+#define RM68191_DCS_write_1A_nP(n, addr, ...) { \
+ int err; \
+ \
+ buf[0] = addr; \
+ parse_variadic(n, buf, ##__VA_ARGS__); \
+ \
+ if (n >= 2) \
+ err = mipi_dsi->mipi_dsi_pkt_write(mipi_dsi, \
+ MIPI_DSI_DCS_LONG_WRITE, (u32*)buf, n + 1); \
+ else if (n == 1) \
+ err = mipi_dsi->mipi_dsi_pkt_write(mipi_dsi, \
+ MIPI_DSI_DCS_SHORT_WRITE_PARAM, (u32*)buf, 0); \
+ else if (n == 0) \
+ { \
+ buf[1] = 0; \
+ err = mipi_dsi->mipi_dsi_pkt_write(mipi_dsi, \
+ MIPI_DSI_DCS_SHORT_WRITE, (u32*)buf, 0); \
+ } \
+ CHECK_RETCODE(err); \
+}
+
+#define RM68191_DCS_write_1A_0P(addr) \
+ RM68191_DCS_write_1A_nP(0, addr)
+
+#define RM68191_DCS_write_1A_1P(addr, ...) \
+ RM68191_DCS_write_1A_nP(1, addr, __VA_ARGS__)
+
+#define RM68191_DCS_write_1A_2P(addr, ...) \
+ RM68191_DCS_write_1A_nP(2, addr, __VA_ARGS__)
+
+#define RM68191_DCS_write_1A_3P(addr, ...) \
+ RM68191_DCS_write_1A_nP(3, addr, __VA_ARGS__)
+
+#define RM68191_DCS_write_1A_4P(addr, ...) \
+ RM68191_DCS_write_1A_nP(4, addr, __VA_ARGS__)
+
+#define RM68191_DCS_write_1A_5P(addr, ...) \
+ RM68191_DCS_write_1A_nP(5, addr, __VA_ARGS__)
+
+#define RM68191_DCS_write_1A_6P(addr, ...) \
+ RM68191_DCS_write_1A_nP(6, addr, __VA_ARGS__)
+
+#define RM68191_DCS_write_1A_7P(addr, ...) \
+ RM68191_DCS_write_1A_nP(7, addr, __VA_ARGS__)
+
+#define RM68191_DCS_write_1A_8P(addr, ...) \
+ RM68191_DCS_write_1A_nP(8, addr, __VA_ARGS__)
+
+#define RM68191_DCS_write_1A_9P(addr, ...) \
+ RM68191_DCS_write_1A_nP(9, addr, __VA_ARGS__)
+
+#define RM68191_DCS_write_1A_10P(addr, ...) \
+ RM68191_DCS_write_1A_nP(10, addr, __VA_ARGS__)
+
+#define RM68191_DCS_write_1A_11P(addr, ...) \
+ RM68191_DCS_write_1A_nP(11, addr, __VA_ARGS__)
+
+#define RM68191_DCS_write_1A_16P(addr, ...) \
+ RM68191_DCS_write_1A_nP(16, addr, __VA_ARGS__)
+
+#define ACTIVE_HIGH_NAME "RK-QHD-SYNC-HIGH"
+#define ACTIVE_LOW_NAME "RK-QHD-SYNC-LOW"
+
+static struct fb_videomode rk_lcd_modedb[] = {
+ /* 540 x 960 */
+ {
+ ACTIVE_HIGH_NAME, 60, 540, 960, 27396,
+ 30, 32,
+ 14, 16,
+ 2, 2,
+ 0x0,
+ FB_VMODE_NONINTERLACED,
+ 0,
+ }, {
+ ACTIVE_LOW_NAME, 60, 540, 960, 27396,
+ 30, 32,
+ 14, 16,
+ 2, 2,
+ FB_SYNC_OE_LOW_ACT,
+ FB_VMODE_NONINTERLACED,
+ 0,
+ },
+};
+
+static struct mipi_lcd_config lcd_config = {
+ .virtual_ch = 0x0,
+ .data_lane_num = 2,
+ .max_phy_clk = RM68191_MAX_DPHY_CLK,
+ .dpi_fmt = MIPI_RGB888,
+};
+
+void mipid_rm68191_get_lcd_videomode(struct fb_videomode **mode, int *size,
+ struct mipi_lcd_config **data)
+{
+ *mode = &rk_lcd_modedb[0];
+ *size = ARRAY_SIZE(rk_lcd_modedb);
+ *data = &lcd_config;
+}
+
+int mipid_rm68191_lcd_setup(struct mipi_dsi_info *mipi_dsi)
+{
+ u8 buf[DSI_CMD_BUF_MAXSIZE];
+
+ dev_dbg(&mipi_dsi->pdev->dev, "MIPI DSI LCD RM68191 setup.\n");
+
+ RM68191_DCS_write_1A_5P(0xF0, 0x55, 0xAA, 0x52, 0x08, 0x03);
+ RM68191_DCS_write_1A_9P(0x90, 0x05, 0x16, 0x09, 0x03, 0xCD, 0x00, 0x00, 0x00, 0x00);
+ RM68191_DCS_write_1A_9P(0x91, 0x05, 0x16, 0x0B, 0x03, 0xCF, 0x00, 0x00, 0x00, 0x00);
+ RM68191_DCS_write_1A_11P(0x92, 0x40, 0x0C, 0x0D, 0x0E, 0x0F, 0x00, 0x8F, 0x00, 0x00, 0x04, 0x08);
+ RM68191_DCS_write_1A_8P(0x94, 0x00, 0x08, 0x0C, 0x03, 0xD1, 0x03, 0xD2, 0x0C);
+ RM68191_DCS_write_1A_16P(0x95, 0x40, 0x10, 0x00, 0x11, 0x00, 0x12, 0x00, 0x13, 0x00, 0x8F, 0x00, 0x00, 0x00, 0x04, 0x00, 0x08);
+ RM68191_DCS_write_1A_2P(0x99, 0x00, 0x00);
+ RM68191_DCS_write_1A_11P(0x9A, 0x80, 0x10, 0x03, 0xD5, 0x03, 0xD7, 0x00, 0x00, 0x00, 0x00, 0x50);
+ RM68191_DCS_write_1A_6P(0x9B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
+ RM68191_DCS_write_1A_2P(0x9C, 0x00, 0x00);
+ RM68191_DCS_write_1A_8P(0x9D, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00);
+ RM68191_DCS_write_1A_2P(0x9E, 0x00, 0x00);
+ RM68191_DCS_write_1A_10P(0xA0, 0x84, 0x00, 0x1F, 0x1F, 0x1F, 0x1F, 0x08, 0x1F, 0x0A, 0x1F);
+ RM68191_DCS_write_1A_10P(0xA1, 0x1F, 0x1F, 0x1F, 0x1F, 0x0C, 0x1F, 0x0E, 0x1F, 0x1F, 0x1F);
+ RM68191_DCS_write_1A_10P(0xA2, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x02, 0x1F, 0x06, 0x1F);
+ RM68191_DCS_write_1A_10P(0xA3, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F);
+ RM68191_DCS_write_1A_10P(0xA4, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x07, 0x1F, 0x03, 0x1F, 0x0F);
+ RM68191_DCS_write_1A_10P(0xA5, 0x1F, 0x0D, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x0B, 0x1F, 0x09);
+ RM68191_DCS_write_1A_10P(0xA6, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x01, 0x05);
+ RM68191_DCS_write_1A_10P(0xA7, 0x03, 0x07, 0x1F, 0x1F, 0x1F, 0x1F, 0x0B, 0x1F, 0x09, 0x1F);
+ RM68191_DCS_write_1A_10P(0xA8, 0x1F, 0x1F, 0x1F, 0x1F, 0x0F, 0x1F, 0x0D, 0x1F, 0x1F, 0x1F);
+ RM68191_DCS_write_1A_10P(0xA9, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x05, 0x1F, 0x01, 0x1F);
+ RM68191_DCS_write_1A_10P(0xAA, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F);
+ RM68191_DCS_write_1A_10P(0xAB, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x00, 0x1F, 0x04, 0x1F, 0x0C);
+ RM68191_DCS_write_1A_10P(0xAC, 0x1F, 0x0E, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x08, 0x1F, 0x0A);
+ RM68191_DCS_write_1A_10P(0xAD, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x06, 0x02);
+ RM68191_DCS_write_1A_5P(0xF0, 0x55, 0xAA, 0x52, 0x08, 0x02);
+ RM68191_DCS_write_1A_1P(0xEA, 0x7D);
+ RM68191_DCS_write_1A_5P(0xF0, 0x55, 0xAA, 0x52, 0x08, 0x00);
+ RM68191_DCS_write_1A_3P(0xBC, 0x00, 0x00, 0x00);
+ RM68191_DCS_write_1A_4P(0xB8, 0x01, 0xAF, 0x8F, 0x8F);
+ RM68191_DCS_write_1A_5P(0xF0, 0x55, 0xAA, 0x52, 0x08, 0x01);
+ RM68191_DCS_write_1A_16P(0xD1, 0x00, 0x00, 0x00, 0x26, 0x00, 0x5E, 0x00, 0x88, 0x00, 0xA8, 0x00, 0xDB, 0x01, 0x02, 0x01, 0x3D);
+ RM68191_DCS_write_1A_16P(0xD2, 0x01, 0x67, 0x01, 0xA6, 0x01, 0xD3, 0x02, 0x16, 0x02, 0x49, 0x02, 0x4B, 0x02, 0x7B, 0x02, 0xB3);
+ RM68191_DCS_write_1A_16P(0xD3, 0x02, 0xD9, 0x03, 0x0E, 0x03, 0x31, 0x03, 0x61, 0x03, 0x80, 0x03, 0xA5, 0x03, 0xBD, 0x03, 0xD2);
+ RM68191_DCS_write_1A_4P(0xD4, 0x03, 0xE5, 0x03, 0xFF);
+ RM68191_DCS_write_1A_16P(0xD5, 0x00, 0x00, 0x00, 0x26, 0x00, 0x5E, 0x00, 0x88, 0x00, 0xA8, 0x00, 0xDB, 0x01, 0x02, 0x01, 0x3D);
+ RM68191_DCS_write_1A_16P(0xD6, 0x01, 0x67, 0x01, 0xA6, 0x01, 0xD3, 0x02, 0x16, 0x02, 0x49, 0x02, 0x4B, 0x02, 0x7B, 0x02, 0xB3);
+ RM68191_DCS_write_1A_16P(0xD7, 0x02, 0xD9, 0x03, 0x0E, 0x03, 0x31, 0x03, 0x61, 0x03, 0x80, 0x03, 0xA5, 0x03, 0xBD, 0x03, 0xD2);
+ RM68191_DCS_write_1A_4P(0xD8, 0x03, 0xE5, 0x03, 0xFF);
+ RM68191_DCS_write_1A_16P(0xD9, 0x00, 0x00, 0x00, 0x26, 0x00, 0x5E, 0x00, 0x88, 0x00, 0xA8, 0x00, 0xDB, 0x01, 0x02, 0x01, 0x3D);
+ RM68191_DCS_write_1A_16P(0xDD, 0x01, 0x67, 0x01, 0xA6, 0x01, 0xD3, 0x02, 0x16, 0x02, 0x49, 0x02, 0x4B, 0x02, 0x7B, 0x02, 0xB3);
+ RM68191_DCS_write_1A_16P(0xDE, 0x02, 0xD9, 0x03, 0x0E, 0x03, 0x31, 0x03, 0x61, 0x03, 0x80, 0x03, 0xA5, 0x03, 0xBD, 0x03, 0xD2);
+ RM68191_DCS_write_1A_4P(0xDF, 0x03, 0xE5, 0x03, 0xFF);
+ RM68191_DCS_write_1A_16P(0xE0, 0x00, 0x00, 0x00, 0x26, 0x00, 0x5E, 0x00, 0x88, 0x00, 0xA8, 0x00, 0xDB, 0x01, 0x02, 0x01, 0x3D);
+ RM68191_DCS_write_1A_16P(0xE1, 0x01, 0x67, 0x01, 0xA6, 0x01, 0xD3, 0x02, 0x16, 0x02, 0x49, 0x02, 0x4B, 0x02, 0x7B, 0x02, 0xB3);
+ RM68191_DCS_write_1A_16P(0xE2, 0x02, 0xD9, 0x03, 0x0E, 0x03, 0x31, 0x03, 0x61, 0x03, 0x80, 0x03, 0xA5, 0x03, 0xBD, 0x03, 0xD2);
+ RM68191_DCS_write_1A_4P(0xE3, 0x03, 0xE5, 0x03, 0xFF);
+ RM68191_DCS_write_1A_16P(0xE4, 0x00, 0x00, 0x00, 0x26, 0x00, 0x5E, 0x00, 0x88, 0x00, 0xA8, 0x00, 0xDB, 0x01, 0x02, 0x01, 0x3D);
+ RM68191_DCS_write_1A_16P(0xE5, 0x01, 0x67, 0x01, 0xA6, 0x01, 0xD3, 0x02, 0x16, 0x02, 0x49, 0x02, 0x4B, 0x02, 0x7B, 0x02, 0xB3);
+ RM68191_DCS_write_1A_16P(0xE6, 0x02, 0xD9, 0x03, 0x0E, 0x03, 0x31, 0x03, 0x61, 0x03, 0x80, 0x03, 0xA5, 0x03, 0xBD, 0x03, 0xD2);
+ RM68191_DCS_write_1A_4P(0xE7, 0x03, 0xE5, 0x03, 0xFF);
+ RM68191_DCS_write_1A_16P(0xE8, 0x00, 0x00, 0x00, 0x26, 0x00, 0x5E, 0x00, 0x88, 0x00, 0xA8, 0x00, 0xDB, 0x01, 0x02, 0x01, 0x3D);
+ RM68191_DCS_write_1A_16P(0xE9, 0x01, 0x67, 0x01, 0xA6, 0x01, 0xD3, 0x02, 0x16, 0x02, 0x49, 0x02, 0x4B, 0x02, 0x7B, 0x02, 0xB3);
+ RM68191_DCS_write_1A_16P(0xEA, 0x02, 0xD9, 0x03, 0x0E, 0x03, 0x31, 0x03, 0x61, 0x03, 0x80, 0x03, 0xA5, 0x03, 0xBD, 0x03, 0xD2);
+ RM68191_DCS_write_1A_4P(0xEB, 0x03, 0xE5, 0x03, 0xFF);
+ RM68191_DCS_write_1A_3P(0xB0, 0x07, 0x07, 0x07);
+ RM68191_DCS_write_1A_3P(0xB1, 0x07, 0x07, 0x07);
+ RM68191_DCS_write_1A_3P(0xB3, 0x11, 0x11, 0x11);
+ RM68191_DCS_write_1A_3P(0xB4, 0x09, 0x09, 0x09);
+ RM68191_DCS_write_1A_3P(0xB6, 0x44, 0x44, 0x44);
+ RM68191_DCS_write_1A_3P(0xB7, 0x34, 0x34, 0x34);
+ RM68191_DCS_write_1A_3P(0xB9, 0x34, 0x34, 0x34);
+ RM68191_DCS_write_1A_3P(0xBA, 0x14, 0x14, 0x14);
+ RM68191_DCS_write_1A_3P(0xBC, 0x00, 0x98, 0x00);
+ RM68191_DCS_write_1A_3P(0xBD, 0x00, 0x98, 0x00);
+ RM68191_DCS_write_1A_1P(0xBE, 0x1D);
+ RM68191_DCS_write_1A_1P(0x35, 0x00);
+
+ RM68191_DCS_write_1A_0P(0x11);
+ mdelay(200);
+ RM68191_DCS_write_1A_0P(0x29);
+ mdelay(200);
+
+ return 0;
+}
+
+static int mipid_bl_update_status(struct backlight_device *bl)
+{
+ return 0;
+}
+
+static int mipid_bl_get_brightness(struct backlight_device *bl)
+{
+ return 255;
+}
+
+static int mipi_bl_check_fb(struct backlight_device *bl, struct fb_info *fbi)
+{
+ return 0;
+}
+
+static const struct backlight_ops mipid_lcd_bl_ops = {
+ .update_status = mipid_bl_update_status,
+ .get_brightness = mipid_bl_get_brightness,
+ .check_fb = mipi_bl_check_fb,
+};
diff --git a/drivers/video/fbdev/mxc/mxcfb_rm68200_wxga.c b/drivers/video/fbdev/mxc/mxcfb_rm68200_wxga.c
new file mode 100644
index 000000000000..9c6ef8e2dbfb
--- /dev/null
+++ b/drivers/video/fbdev/mxc/mxcfb_rm68200_wxga.c
@@ -0,0 +1,438 @@
+/*
+ * Copyright 2018 NXP
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/console.h>
+#include <linux/io.h>
+#include <linux/bitops.h>
+#include <linux/spinlock.h>
+#include <linux/mipi_dsi.h>
+#include <linux/mxcfb.h>
+#include <linux/backlight.h>
+#include <video/mipi_display.h>
+
+#include "mipi_dsi.h"
+
+#define RM68200_MAX_DPHY_CLK (850)
+
+#define CHECK_RETCODE(ret) \
+do { \
+ if (ret < 0) { \
+ dev_err(&mipi_dsi->pdev->dev, \
+ "%s ERR: ret:%d, line:%d.\n", \
+ __func__, ret, __LINE__); \
+ return ret; \
+ } \
+} while (0)
+
+static void parse_variadic(int n, u8 *buf, ...)
+{
+ int i = 0;
+ va_list args;
+
+ if (unlikely(!n)) return;
+
+ va_start(args, buf);
+
+ for (i = 0; i < n; i++)
+ buf[i + 1] = (u8)va_arg(args, int);
+
+ va_end(args);
+}
+
+#define RM68200_DCS_write_1A_nP(n, addr, ...) { \
+ int err; \
+ \
+ buf[0] = addr; \
+ parse_variadic(n, buf, ##__VA_ARGS__); \
+ \
+ if (n >= 2) \
+ err = mipi_dsi->mipi_dsi_pkt_write(mipi_dsi, \
+ MIPI_DSI_DCS_LONG_WRITE, (u32*)buf, n + 1); \
+ else if (n == 1) \
+ err = mipi_dsi->mipi_dsi_pkt_write(mipi_dsi, \
+ MIPI_DSI_DCS_SHORT_WRITE_PARAM, (u32*)buf, 0); \
+ else if (n == 0) \
+ { \
+ buf[1] = 0; \
+ err = mipi_dsi->mipi_dsi_pkt_write(mipi_dsi, \
+ MIPI_DSI_DCS_SHORT_WRITE, (u32*)buf, 0); \
+ } \
+ CHECK_RETCODE(err); \
+}
+
+#define RM68200_DCS_write_1A_0P(addr) \
+ RM68200_DCS_write_1A_nP(0, addr)
+
+#define RM68200_DCS_write_1A_1P(addr, ...) \
+ RM68200_DCS_write_1A_nP(1, addr, __VA_ARGS__)
+
+#define ACTIVE_HIGH_NAME "RK-WXGA-SYNC-HIGH"
+#define ACTIVE_LOW_NAME "RK-WXGA-SYNC-LOW"
+
+static struct fb_videomode rk_lcd_modedb[] = {
+ /* 720 x 1280 */
+ {
+ ACTIVE_HIGH_NAME, 60, 720, 1280, 16040,
+ 32, 32,
+ 14, 16,
+ 8, 2,
+ 0x0,
+ FB_VMODE_NONINTERLACED,
+ 0,
+ }, {
+ ACTIVE_LOW_NAME, 60, 720, 1280, 16040,
+ 32, 32,
+ 14, 16,
+ 8, 2,
+ FB_SYNC_OE_LOW_ACT,
+ FB_VMODE_NONINTERLACED,
+ 0,
+ },
+};
+
+static struct mipi_lcd_config lcd_config = {
+ .virtual_ch = 0x0,
+ .data_lane_num = 2,
+ .max_phy_clk = RM68200_MAX_DPHY_CLK,
+ .dpi_fmt = MIPI_RGB888,
+};
+
+void mipid_rm68200_get_lcd_videomode(struct fb_videomode **mode, int *size,
+ struct mipi_lcd_config **data)
+{
+ *mode = &rk_lcd_modedb[0];
+ *size = ARRAY_SIZE(rk_lcd_modedb);
+ *data = &lcd_config;
+}
+
+int mipid_rm68200_lcd_setup(struct mipi_dsi_info *mipi_dsi)
+{
+ u8 buf[DSI_CMD_BUF_MAXSIZE];
+
+ dev_dbg(&mipi_dsi->pdev->dev, "MIPI DSI LCD RM68200 setup.\n");
+
+ /* change to MCS Page 0 */
+ RM68200_DCS_write_1A_1P(0xFE, 0x01);
+ RM68200_DCS_write_1A_1P(0x24, 0xc0); /* External PWR IC Control */
+ RM68200_DCS_write_1A_1P(0x25, 0x53);
+ RM68200_DCS_write_1A_1P(0x26, 0x00);
+ RM68200_DCS_write_1A_1P(0x2B, 0xE5);
+ RM68200_DCS_write_1A_1P(0x27, 0x0A);
+ RM68200_DCS_write_1A_1P(0x29, 0x0A);
+ RM68200_DCS_write_1A_1P(0x16, 0x52);
+ RM68200_DCS_write_1A_1P(0x2F, 0x53);
+ RM68200_DCS_write_1A_1P(0x34, 0x5A);
+ RM68200_DCS_write_1A_1P(0x1B, 0x00);
+ RM68200_DCS_write_1A_1P(0x12, 0x0A);
+ RM68200_DCS_write_1A_1P(0x1A, 0x06);
+ RM68200_DCS_write_1A_1P(0x46, 0x56);
+ RM68200_DCS_write_1A_1P(0x52, 0xA0);
+ RM68200_DCS_write_1A_1P(0x53, 0x00);
+ RM68200_DCS_write_1A_1P(0x54, 0xA0);
+ RM68200_DCS_write_1A_1P(0x55, 0x00);
+ RM68200_DCS_write_1A_1P(0x5F, 0x11); /* 2 data lanes */
+
+ /* change to MCS Page 2 */
+ RM68200_DCS_write_1A_1P(0xFE, 0x03);
+ RM68200_DCS_write_1A_1P(0x00, 0x05);
+ RM68200_DCS_write_1A_1P(0x02, 0x0B);
+ RM68200_DCS_write_1A_1P(0x03, 0x0F);
+ RM68200_DCS_write_1A_1P(0x04, 0x7D);
+ RM68200_DCS_write_1A_1P(0x05, 0x00);
+ RM68200_DCS_write_1A_1P(0x06, 0x50);
+ RM68200_DCS_write_1A_1P(0x07, 0x05);
+ RM68200_DCS_write_1A_1P(0x08, 0x16);
+ RM68200_DCS_write_1A_1P(0x09, 0x0D);
+ RM68200_DCS_write_1A_1P(0x0A, 0x11);
+ RM68200_DCS_write_1A_1P(0x0B, 0x7D);
+ RM68200_DCS_write_1A_1P(0x0C, 0x00);
+ RM68200_DCS_write_1A_1P(0x0D, 0x50);
+ RM68200_DCS_write_1A_1P(0x0E, 0x07);
+ RM68200_DCS_write_1A_1P(0x0F, 0x08);
+ RM68200_DCS_write_1A_1P(0x10, 0x01);
+ RM68200_DCS_write_1A_1P(0x11, 0x02);
+ RM68200_DCS_write_1A_1P(0x12, 0x00);
+ RM68200_DCS_write_1A_1P(0x13, 0x7D);
+ RM68200_DCS_write_1A_1P(0x14, 0x00);
+ RM68200_DCS_write_1A_1P(0x15, 0x85);
+ RM68200_DCS_write_1A_1P(0x16, 0x08);
+ RM68200_DCS_write_1A_1P(0x17, 0x03);
+ RM68200_DCS_write_1A_1P(0x18, 0x04);
+ RM68200_DCS_write_1A_1P(0x19, 0x05);
+ RM68200_DCS_write_1A_1P(0x1A, 0x06);
+ RM68200_DCS_write_1A_1P(0x1B, 0x00);
+ RM68200_DCS_write_1A_1P(0x1C, 0x7D);
+ RM68200_DCS_write_1A_1P(0x1D, 0x00);
+ RM68200_DCS_write_1A_1P(0x1E, 0x85);
+ RM68200_DCS_write_1A_1P(0x1F, 0x08);
+ RM68200_DCS_write_1A_1P(0x20, 0x00);
+ RM68200_DCS_write_1A_1P(0x21, 0x00);
+ RM68200_DCS_write_1A_1P(0x22, 0x00);
+ RM68200_DCS_write_1A_1P(0x23, 0x00);
+ RM68200_DCS_write_1A_1P(0x24, 0x00);
+ RM68200_DCS_write_1A_1P(0x25, 0x00);
+ RM68200_DCS_write_1A_1P(0x26, 0x00);
+ RM68200_DCS_write_1A_1P(0x27, 0x00);
+ RM68200_DCS_write_1A_1P(0x28, 0x00);
+ RM68200_DCS_write_1A_1P(0x29, 0x00);
+ RM68200_DCS_write_1A_1P(0x2A, 0x07);
+ RM68200_DCS_write_1A_1P(0x2B, 0x08);
+ RM68200_DCS_write_1A_1P(0x2D, 0x01);
+ RM68200_DCS_write_1A_1P(0x2F, 0x02);
+ RM68200_DCS_write_1A_1P(0x30, 0x00);
+ RM68200_DCS_write_1A_1P(0x31, 0x40);
+ RM68200_DCS_write_1A_1P(0x32, 0x05);
+ RM68200_DCS_write_1A_1P(0x33, 0x08);
+ RM68200_DCS_write_1A_1P(0x34, 0x54);
+ RM68200_DCS_write_1A_1P(0x35, 0x7D);
+ RM68200_DCS_write_1A_1P(0x36, 0x00);
+ RM68200_DCS_write_1A_1P(0x37, 0x03);
+ RM68200_DCS_write_1A_1P(0x38, 0x04);
+ RM68200_DCS_write_1A_1P(0x39, 0x05);
+ RM68200_DCS_write_1A_1P(0x3A, 0x06);
+ RM68200_DCS_write_1A_1P(0x3B, 0x00);
+ RM68200_DCS_write_1A_1P(0x3D, 0x40);
+ RM68200_DCS_write_1A_1P(0x3F, 0x05);
+ RM68200_DCS_write_1A_1P(0x40, 0x08);
+ RM68200_DCS_write_1A_1P(0x41, 0x54);
+ RM68200_DCS_write_1A_1P(0x42, 0x7D);
+ RM68200_DCS_write_1A_1P(0x43, 0x00);
+ RM68200_DCS_write_1A_1P(0x44, 0x00);
+ RM68200_DCS_write_1A_1P(0x45, 0x00);
+ RM68200_DCS_write_1A_1P(0x46, 0x00);
+ RM68200_DCS_write_1A_1P(0x47, 0x00);
+ RM68200_DCS_write_1A_1P(0x48, 0x00);
+ RM68200_DCS_write_1A_1P(0x49, 0x00);
+ RM68200_DCS_write_1A_1P(0x4A, 0x00);
+ RM68200_DCS_write_1A_1P(0x4B, 0x00);
+ RM68200_DCS_write_1A_1P(0x4C, 0x00);
+ RM68200_DCS_write_1A_1P(0x4D, 0x00);
+ RM68200_DCS_write_1A_1P(0x4E, 0x00);
+ RM68200_DCS_write_1A_1P(0x4F, 0x00);
+ RM68200_DCS_write_1A_1P(0x50, 0x00);
+ RM68200_DCS_write_1A_1P(0x51, 0x00);
+ RM68200_DCS_write_1A_1P(0x52, 0x00);
+ RM68200_DCS_write_1A_1P(0x53, 0x00);
+ RM68200_DCS_write_1A_1P(0x54, 0x00);
+ RM68200_DCS_write_1A_1P(0x55, 0x00);
+ RM68200_DCS_write_1A_1P(0x56, 0x00);
+ RM68200_DCS_write_1A_1P(0x58, 0x00);
+ RM68200_DCS_write_1A_1P(0x59, 0x00);
+ RM68200_DCS_write_1A_1P(0x5A, 0x00);
+ RM68200_DCS_write_1A_1P(0x5B, 0x00);
+ RM68200_DCS_write_1A_1P(0x5C, 0x00);
+ RM68200_DCS_write_1A_1P(0x5D, 0x00);
+ RM68200_DCS_write_1A_1P(0x5E, 0x00);
+ RM68200_DCS_write_1A_1P(0x5F, 0x00);
+ RM68200_DCS_write_1A_1P(0x60, 0x00);
+ RM68200_DCS_write_1A_1P(0x61, 0x00);
+ RM68200_DCS_write_1A_1P(0x62, 0x00);
+ RM68200_DCS_write_1A_1P(0x63, 0x00);
+ RM68200_DCS_write_1A_1P(0x64, 0x00);
+ RM68200_DCS_write_1A_1P(0x65, 0x00);
+ RM68200_DCS_write_1A_1P(0x66, 0x00);
+ RM68200_DCS_write_1A_1P(0x67, 0x00);
+ RM68200_DCS_write_1A_1P(0x68, 0x00);
+ RM68200_DCS_write_1A_1P(0x69, 0x00);
+ RM68200_DCS_write_1A_1P(0x6A, 0x00);
+ RM68200_DCS_write_1A_1P(0x6B, 0x00);
+ RM68200_DCS_write_1A_1P(0x6C, 0x00);
+ RM68200_DCS_write_1A_1P(0x6D, 0x00);
+ RM68200_DCS_write_1A_1P(0x6E, 0x00);
+ RM68200_DCS_write_1A_1P(0x6F, 0x00);
+ RM68200_DCS_write_1A_1P(0x70, 0x00);
+ RM68200_DCS_write_1A_1P(0x71, 0x00);
+ RM68200_DCS_write_1A_1P(0x72, 0x20);
+ RM68200_DCS_write_1A_1P(0x73, 0x00);
+ RM68200_DCS_write_1A_1P(0x74, 0x08);
+ RM68200_DCS_write_1A_1P(0x75, 0x08);
+ RM68200_DCS_write_1A_1P(0x76, 0x08);
+ RM68200_DCS_write_1A_1P(0x77, 0x08);
+ RM68200_DCS_write_1A_1P(0x78, 0x08);
+ RM68200_DCS_write_1A_1P(0x79, 0x08);
+ RM68200_DCS_write_1A_1P(0x7A, 0x00);
+ RM68200_DCS_write_1A_1P(0x7B, 0x00);
+ RM68200_DCS_write_1A_1P(0x7C, 0x00);
+ RM68200_DCS_write_1A_1P(0x7D, 0x00);
+ RM68200_DCS_write_1A_1P(0x7E, 0xBF);
+ RM68200_DCS_write_1A_1P(0x7F, 0x02);
+ RM68200_DCS_write_1A_1P(0x80, 0x06);
+ RM68200_DCS_write_1A_1P(0x81, 0x14);
+ RM68200_DCS_write_1A_1P(0x82, 0x10);
+ RM68200_DCS_write_1A_1P(0x83, 0x16);
+ RM68200_DCS_write_1A_1P(0x84, 0x12);
+ RM68200_DCS_write_1A_1P(0x85, 0x08);
+ RM68200_DCS_write_1A_1P(0x86, 0x3F);
+ RM68200_DCS_write_1A_1P(0x87, 0x3F);
+ RM68200_DCS_write_1A_1P(0x88, 0x3F);
+ RM68200_DCS_write_1A_1P(0x89, 0x3F);
+ RM68200_DCS_write_1A_1P(0x8A, 0x3F);
+ RM68200_DCS_write_1A_1P(0x8B, 0x0C);
+ RM68200_DCS_write_1A_1P(0x8C, 0x0A);
+ RM68200_DCS_write_1A_1P(0x8D, 0x0E);
+ RM68200_DCS_write_1A_1P(0x8E, 0x3F);
+ RM68200_DCS_write_1A_1P(0x8F, 0x3F);
+ RM68200_DCS_write_1A_1P(0x90, 0x00);
+ RM68200_DCS_write_1A_1P(0x91, 0x04);
+ RM68200_DCS_write_1A_1P(0x92, 0x3F);
+ RM68200_DCS_write_1A_1P(0x93, 0x3F);
+ RM68200_DCS_write_1A_1P(0x94, 0x3F);
+ RM68200_DCS_write_1A_1P(0x95, 0x3F);
+ RM68200_DCS_write_1A_1P(0x96, 0x05);
+ RM68200_DCS_write_1A_1P(0x97, 0x01);
+ RM68200_DCS_write_1A_1P(0x98, 0x3F);
+ RM68200_DCS_write_1A_1P(0x99, 0x3F);
+ RM68200_DCS_write_1A_1P(0x9A, 0x0F);
+ RM68200_DCS_write_1A_1P(0x9B, 0x0B);
+ RM68200_DCS_write_1A_1P(0x9C, 0x0D);
+ RM68200_DCS_write_1A_1P(0x9D, 0x3F);
+ RM68200_DCS_write_1A_1P(0x9E, 0x3F);
+ RM68200_DCS_write_1A_1P(0x9F, 0x3F);
+ RM68200_DCS_write_1A_1P(0xA0, 0x3F);
+ RM68200_DCS_write_1A_1P(0xA2, 0x3F);
+ RM68200_DCS_write_1A_1P(0xA3, 0x09);
+ RM68200_DCS_write_1A_1P(0xA4, 0x13);
+ RM68200_DCS_write_1A_1P(0xA5, 0x17);
+ RM68200_DCS_write_1A_1P(0xA6, 0x11);
+ RM68200_DCS_write_1A_1P(0xA7, 0x15);
+ RM68200_DCS_write_1A_1P(0xA9, 0x07);
+ RM68200_DCS_write_1A_1P(0xAA, 0x03);
+ RM68200_DCS_write_1A_1P(0xAB, 0x3F);
+ RM68200_DCS_write_1A_1P(0xAC, 0x3F);
+ RM68200_DCS_write_1A_1P(0xAD, 0x05);
+ RM68200_DCS_write_1A_1P(0xAE, 0x01);
+ RM68200_DCS_write_1A_1P(0xAF, 0x17);
+ RM68200_DCS_write_1A_1P(0xB0, 0x13);
+ RM68200_DCS_write_1A_1P(0xB1, 0x15);
+ RM68200_DCS_write_1A_1P(0xB2, 0x11);
+ RM68200_DCS_write_1A_1P(0xB3, 0x0F);
+ RM68200_DCS_write_1A_1P(0xB4, 0x3F);
+ RM68200_DCS_write_1A_1P(0xB5, 0x3F);
+ RM68200_DCS_write_1A_1P(0xB6, 0x3F);
+ RM68200_DCS_write_1A_1P(0xB7, 0x3F);
+ RM68200_DCS_write_1A_1P(0xB8, 0x3F);
+ RM68200_DCS_write_1A_1P(0xB9, 0x0B);
+ RM68200_DCS_write_1A_1P(0xBA, 0x0D);
+ RM68200_DCS_write_1A_1P(0xBB, 0x09);
+ RM68200_DCS_write_1A_1P(0xBC, 0x3F);
+ RM68200_DCS_write_1A_1P(0xBD, 0x3F);
+ RM68200_DCS_write_1A_1P(0xBE, 0x07);
+ RM68200_DCS_write_1A_1P(0xBF, 0x03);
+ RM68200_DCS_write_1A_1P(0xC0, 0x3F);
+ RM68200_DCS_write_1A_1P(0xC1, 0x3F);
+ RM68200_DCS_write_1A_1P(0xC2, 0x3F);
+ RM68200_DCS_write_1A_1P(0xC3, 0x3F);
+ RM68200_DCS_write_1A_1P(0xC4, 0x02);
+ RM68200_DCS_write_1A_1P(0xC5, 0x06);
+ RM68200_DCS_write_1A_1P(0xC6, 0x3F);
+ RM68200_DCS_write_1A_1P(0xC7, 0x3F);
+ RM68200_DCS_write_1A_1P(0xC8, 0x08);
+ RM68200_DCS_write_1A_1P(0xC9, 0x0C);
+ RM68200_DCS_write_1A_1P(0xCA, 0x0A);
+ RM68200_DCS_write_1A_1P(0xCB, 0x3F);
+ RM68200_DCS_write_1A_1P(0xCC, 0x3F);
+ RM68200_DCS_write_1A_1P(0xCD, 0x3F);
+ RM68200_DCS_write_1A_1P(0xCE, 0x3F);
+ RM68200_DCS_write_1A_1P(0xCF, 0x3F);
+ RM68200_DCS_write_1A_1P(0xD0, 0x0E);
+ RM68200_DCS_write_1A_1P(0xD1, 0x10);
+ RM68200_DCS_write_1A_1P(0xD2, 0x14);
+ RM68200_DCS_write_1A_1P(0xD3, 0x12);
+ RM68200_DCS_write_1A_1P(0xD4, 0x16);
+ RM68200_DCS_write_1A_1P(0xD5, 0x00);
+ RM68200_DCS_write_1A_1P(0xD6, 0x04);
+ RM68200_DCS_write_1A_1P(0xD7, 0x3F);
+ RM68200_DCS_write_1A_1P(0xDC, 0x02);
+ RM68200_DCS_write_1A_1P(0xDE, 0x12);
+ RM68200_DCS_write_1A_1P(0xFE, 0x0E);
+ RM68200_DCS_write_1A_1P(0x01, 0x75);
+
+ /* change to MCS Page 3: Gamma Settings */
+ RM68200_DCS_write_1A_1P(0xFE, 0x04);
+ RM68200_DCS_write_1A_1P(0x60, 0x00);
+ RM68200_DCS_write_1A_1P(0x61, 0x0C);
+ RM68200_DCS_write_1A_1P(0x62, 0x12);
+ RM68200_DCS_write_1A_1P(0x63, 0x0E);
+ RM68200_DCS_write_1A_1P(0x64, 0x06);
+ RM68200_DCS_write_1A_1P(0x65, 0x12);
+ RM68200_DCS_write_1A_1P(0x66, 0x0E);
+ RM68200_DCS_write_1A_1P(0x67, 0x0B);
+ RM68200_DCS_write_1A_1P(0x68, 0x15);
+ RM68200_DCS_write_1A_1P(0x69, 0x0B);
+ RM68200_DCS_write_1A_1P(0x6A, 0x10);
+ RM68200_DCS_write_1A_1P(0x6B, 0x07);
+ RM68200_DCS_write_1A_1P(0x6C, 0x0F);
+ RM68200_DCS_write_1A_1P(0x6D, 0x12);
+ RM68200_DCS_write_1A_1P(0x6E, 0x0C);
+ RM68200_DCS_write_1A_1P(0x6F, 0x00);
+ RM68200_DCS_write_1A_1P(0x70, 0x00);
+ RM68200_DCS_write_1A_1P(0x71, 0x0C);
+ RM68200_DCS_write_1A_1P(0x72, 0x12);
+ RM68200_DCS_write_1A_1P(0x73, 0x0E);
+ RM68200_DCS_write_1A_1P(0x74, 0x06);
+ RM68200_DCS_write_1A_1P(0x75, 0x12);
+ RM68200_DCS_write_1A_1P(0x76, 0x0E);
+ RM68200_DCS_write_1A_1P(0x77, 0x0B);
+ RM68200_DCS_write_1A_1P(0x78, 0x15);
+ RM68200_DCS_write_1A_1P(0x79, 0x0B);
+ RM68200_DCS_write_1A_1P(0x7A, 0x10);
+ RM68200_DCS_write_1A_1P(0x7B, 0x07);
+ RM68200_DCS_write_1A_1P(0x7C, 0x0F);
+ RM68200_DCS_write_1A_1P(0x7D, 0x12);
+ RM68200_DCS_write_1A_1P(0x7E, 0x0C);
+ RM68200_DCS_write_1A_1P(0x7F, 0x00);
+
+ /* change to MCS Page 0 */
+ RM68200_DCS_write_1A_1P(0xFE, 0x00);
+ RM68200_DCS_write_1A_1P(0x11, 0x00);
+ mdelay(200);
+ RM68200_DCS_write_1A_1P(0x29, 0x00);
+ mdelay(100);
+ RM68200_DCS_write_1A_0P(0x2C);
+ RM68200_DCS_write_1A_1P(0x35, 0x00);
+ mdelay(200);
+
+ return 0;
+}
+
+static int mipid_bl_update_status(struct backlight_device *bl)
+{
+ return 0;
+}
+
+static int mipid_bl_get_brightness(struct backlight_device *bl)
+{
+ return 255;
+}
+
+static int mipi_bl_check_fb(struct backlight_device *bl, struct fb_info *fbi)
+{
+ return 0;
+}
+
+static const struct backlight_ops mipid_lcd_bl_ops = {
+ .update_status = mipid_bl_update_status,
+ .get_brightness = mipid_bl_get_brightness,
+ .check_fb = mipi_bl_check_fb,
+};
diff --git a/drivers/video/fbdev/mxc/mxsfb_sii902x.c b/drivers/video/fbdev/mxc/mxsfb_sii902x.c
new file mode 100644
index 000000000000..1a6a2ee992be
--- /dev/null
+++ b/drivers/video/fbdev/mxc/mxsfb_sii902x.c
@@ -0,0 +1,563 @@
+/*
+ * Copyright (C) 2010-2015 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/*!
+ * @defgroup Framebuffer Framebuffer Driver for Sii902x.
+ */
+
+/*!
+ * @file mxsfb_sii902x.c
+ *
+ * @brief Frame buffer driver for SII902x
+ *
+ * @ingroup Framebuffer
+ */
+
+/*!
+ * Include files
+ */
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/console.h>
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <linux/fb.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/consumer.h>
+#include <linux/i2c.h>
+#include <linux/fsl_devices.h>
+#include <linux/interrupt.h>
+#include <linux/reset.h>
+#include <asm/mach-types.h>
+#include <video/mxc_edid.h>
+
+#define SII_EDID_LEN 512
+#define DRV_NAME "sii902x"
+
+struct sii902x_data {
+ struct i2c_client *client;
+ struct delayed_work det_work;
+ struct fb_info *fbi;
+ struct mxc_edid_cfg edid_cfg;
+ u8 cable_plugin;
+ u8 edid[SII_EDID_LEN];
+ bool dft_mode_set;
+ const char *mode_str;
+ int bits_per_pixel;
+} sii902x;
+
+static void sii902x_poweron(void);
+static void sii902x_poweroff(void);
+
+static int sii902x_in_init_state;
+
+#ifdef DEBUG
+static void dump_fb_videomode(struct fb_videomode *m)
+{
+ pr_debug("fb_videomode = %d %d %d %d %d %d %d %d %d %d %d %d %d\n",
+ m->refresh, m->xres, m->yres, m->pixclock, m->left_margin,
+ m->right_margin, m->upper_margin, m->lower_margin,
+ m->hsync_len, m->vsync_len, m->sync, m->vmode, m->flag);
+}
+#else
+static void dump_fb_videomode(struct fb_videomode *m)
+{}
+#endif
+
+static __attribute__ ((unused)) void dump_regs(u8 reg, int len)
+{
+ u8 buf[50];
+ int i;
+
+ i2c_smbus_read_i2c_block_data(sii902x.client, reg, len, buf);
+ for (i = 0; i < len; i++)
+ dev_dbg(&sii902x.client->dev, "reg[0x%02X]: 0x%02X\n",
+ i+reg, buf[i]);
+}
+
+static ssize_t sii902x_show_name(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ strcpy(buf, sii902x.fbi->fix.id);
+ sprintf(buf+strlen(buf), "\n");
+
+ return strlen(buf);
+}
+
+static DEVICE_ATTR(fb_name, S_IRUGO, sii902x_show_name, NULL);
+
+static ssize_t sii902x_show_state(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ if (sii902x.cable_plugin == 0)
+ strcpy(buf, "plugout\n");
+ else
+ strcpy(buf, "plugin\n");
+
+ return strlen(buf);
+}
+
+static DEVICE_ATTR(cable_state, S_IRUGO, sii902x_show_state, NULL);
+
+static ssize_t sii902x_show_edid(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int i, j, len = 0;
+
+ for (j = 0; j < SII_EDID_LEN/16; j++) {
+ for (i = 0; i < 16; i++)
+ len += sprintf(buf+len, "0x%02X ",
+ sii902x.edid[j*16 + i]);
+ len += sprintf(buf+len, "\n");
+ }
+
+ return len;
+}
+
+static DEVICE_ATTR(edid, S_IRUGO, sii902x_show_edid, NULL);
+
+static void sii902x_setup(struct fb_info *fbi)
+{
+ u16 data[4];
+ u32 refresh;
+ u8 *tmp;
+ int i;
+
+ dev_dbg(&sii902x.client->dev, "Sii902x: setup..\n");
+
+ /* Power up */
+ i2c_smbus_write_byte_data(sii902x.client, 0x1E, 0x00);
+
+ /* set TPI video mode */
+ data[0] = PICOS2KHZ(fbi->var.pixclock) / 10;
+ data[2] = fbi->var.hsync_len + fbi->var.left_margin +
+ fbi->var.xres + fbi->var.right_margin;
+ data[3] = fbi->var.vsync_len + fbi->var.upper_margin +
+ fbi->var.yres + fbi->var.lower_margin;
+ refresh = data[2] * data[3];
+ refresh = (PICOS2KHZ(fbi->var.pixclock) * 1000) / refresh;
+ data[1] = refresh * 100;
+ tmp = (u8 *)data;
+ for (i = 0; i < 8; i++)
+ i2c_smbus_write_byte_data(sii902x.client, i, tmp[i]);
+
+ /* input bus/pixel: full pixel wide (24bit), rising edge */
+ i2c_smbus_write_byte_data(sii902x.client, 0x08, 0x70);
+ /* Set input format to RGB */
+ i2c_smbus_write_byte_data(sii902x.client, 0x09, 0x00);
+ /* set output format to RGB */
+ i2c_smbus_write_byte_data(sii902x.client, 0x0A, 0x00);
+}
+
+static void sii902x_audio_setup(void)
+{
+ /* audio setup */
+ i2c_smbus_write_byte_data(sii902x.client, 0x25, 0x00);
+ i2c_smbus_write_byte_data(sii902x.client, 0x26, 0x40);
+ i2c_smbus_write_byte_data(sii902x.client, 0x27, 0x00);
+}
+
+#ifdef CONFIG_FB_MODE_HELPERS
+static int sii902x_read_edid(struct fb_info *fbi)
+{
+ int old, dat, ret, cnt = 100;
+ unsigned short addr = 0x50;
+
+ dev_dbg(&sii902x.client->dev, "%s\n", __func__);
+
+ old = i2c_smbus_read_byte_data(sii902x.client, 0x1A);
+
+ i2c_smbus_write_byte_data(sii902x.client, 0x1A, old | 0x4);
+ do {
+ cnt--;
+ msleep(10);
+ dat = i2c_smbus_read_byte_data(sii902x.client, 0x1A);
+ } while ((!(dat & 0x2)) && cnt);
+
+ if (!cnt) {
+ ret = -1;
+ goto done;
+ }
+
+ i2c_smbus_write_byte_data(sii902x.client, 0x1A, old | 0x06);
+
+ /* edid reading */
+ ret = mxc_edid_read(sii902x.client->adapter, addr,
+ sii902x.edid, &sii902x.edid_cfg, fbi);
+
+ cnt = 100;
+ do {
+ cnt--;
+ i2c_smbus_write_byte_data(sii902x.client, 0x1A, old & ~0x6);
+ msleep(10);
+ dat = i2c_smbus_read_byte_data(sii902x.client, 0x1A);
+ } while ((dat & 0x6) && cnt);
+
+ if (!cnt)
+ ret = -1;
+
+done:
+
+ i2c_smbus_write_byte_data(sii902x.client, 0x1A, old);
+ return ret;
+}
+#else
+static int sii902x_read_edid(struct fb_info *fbi)
+{
+ return -1;
+}
+#endif
+
+static void sii902x_cable_connected(void)
+{
+ int i;
+ const struct fb_videomode *mode;
+ struct fb_videomode m;
+
+ if (sii902x_read_edid(sii902x.fbi) < 0)
+ dev_err(&sii902x.client->dev,
+ "Sii902x: read edid fail\n");
+ else {
+ if (sii902x.fbi->monspecs.modedb_len > 0) {
+
+ fb_destroy_modelist(&sii902x.fbi->modelist);
+
+ for (i = 0; i < sii902x.fbi->monspecs.modedb_len; i++) {
+
+ mode = &sii902x.fbi->monspecs.modedb[i];
+
+ if (!(mode->vmode & FB_VMODE_INTERLACED)) {
+ dev_dbg(&sii902x.client->dev, "Added mode %d:", i);
+ dev_dbg(&sii902x.client->dev,
+ "xres = %d, yres = %d, freq = %d, vmode = %d, flag = %d\n",
+ mode->xres, mode->yres, mode->refresh,
+ mode->vmode, mode->flag);
+
+ fb_add_videomode(mode, &sii902x.fbi->modelist);
+ }
+ }
+
+ /* Set the default mode only once. */
+ if (!sii902x.dft_mode_set &&
+ sii902x.mode_str && sii902x.bits_per_pixel) {
+
+ dev_dbg(&sii902x.client->dev, "%s: setting to default=%s bpp=%d\n",
+ __func__, sii902x.mode_str, sii902x.bits_per_pixel);
+
+ fb_find_mode(&sii902x.fbi->var, sii902x.fbi,
+ sii902x.mode_str, NULL, 0, NULL,
+ sii902x.bits_per_pixel);
+
+ sii902x.dft_mode_set = true;
+ }
+
+ fb_var_to_videomode(&m, &sii902x.fbi->var);
+ dump_fb_videomode(&m);
+
+ mode = fb_find_nearest_mode(&m,
+ &sii902x.fbi->modelist);
+
+ /* update fbi mode */
+ sii902x.fbi->mode = (struct fb_videomode *)mode;
+
+ fb_videomode_to_var(&sii902x.fbi->var, mode);
+
+ sii902x.fbi->var.activate |= FB_ACTIVATE_FORCE;
+ console_lock();
+ sii902x.fbi->flags |= FBINFO_MISC_USEREVENT;
+ fb_set_var(sii902x.fbi, &sii902x.fbi->var);
+ sii902x.fbi->flags &= ~FBINFO_MISC_USEREVENT;
+ console_unlock();
+ }
+ /* Power on sii902x */
+ sii902x_poweron();
+ }
+}
+
+static void det_worker(struct work_struct *work)
+{
+ int dat;
+ char event_string[16];
+ char *envp[] = { event_string, NULL };
+
+ dev_dbg(&sii902x.client->dev, "%s\n", __func__);
+
+ dat = i2c_smbus_read_byte_data(sii902x.client, 0x3D);
+
+ /* cable connection state */
+ if (dat & 0x4) {
+ sii902x.cable_plugin = 1;
+ dev_dbg(&sii902x.client->dev, "EVENT=plugin\n");
+ sprintf(event_string, "EVENT=plugin");
+ sii902x_cable_connected();
+ } else {
+ sii902x.cable_plugin = 0;
+ dev_dbg(&sii902x.client->dev, "EVENT=plugout\n");
+ sprintf(event_string, "EVENT=plugout");
+ /* Power off sii902x */
+ sii902x_poweroff();
+ }
+ kobject_uevent_env(&sii902x.client->dev.kobj, KOBJ_CHANGE, envp);
+
+ i2c_smbus_write_byte_data(sii902x.client, 0x3D, dat);
+
+ dev_dbg(&sii902x.client->dev, "exit %s\n", __func__);
+
+}
+
+static irqreturn_t sii902x_detect_handler(int irq, void *data)
+{
+ if (sii902x.fbi)
+ schedule_delayed_work(&(sii902x.det_work), msecs_to_jiffies(50));
+
+ return IRQ_HANDLED;
+}
+
+static int sii902x_fb_event(struct notifier_block *nb, unsigned long val, void *v)
+{
+ struct fb_event *event = v;
+ struct fb_info *fbi = event->info;
+
+ /* Check if our FB just registered */
+ if (!sii902x.fbi && val == FB_EVENT_FB_REGISTERED &&
+ !strncmp(fbi->fix.id, "mxs-lcdif", 9)) {
+ pr_info("sii902x bound to %s from %s\n",
+ fbi->fix.id, dev_name(fbi->device));
+ sii902x.fbi = fbi;
+ }
+
+ /* Ignore if not our FB */
+ if (fbi != sii902x.fbi)
+ return 0;
+
+ /* Ignore if driver did not probe yet */
+ if (sii902x_in_init_state)
+ return 0;
+
+ switch (val) {
+ case FB_EVENT_FB_REGISTERED:
+ /* Manually trigger a plugin/plugout interrupter to check cable state */
+ schedule_delayed_work(&(sii902x.det_work), msecs_to_jiffies(50));
+
+ fb_show_logo(fbi, 0);
+
+ break;
+ case FB_EVENT_MODE_CHANGE:
+ sii902x_setup(fbi);
+ break;
+ case FB_EVENT_BLANK:
+ if (*((int *)event->data) == FB_BLANK_UNBLANK) {
+ dev_dbg(&sii902x.client->dev, "FB_BLANK_UNBLANK\n");
+ sii902x_poweron();
+ } else {
+ dev_dbg(&sii902x.client->dev, "FB_BLANK_BLANK\n");
+ sii902x_poweroff();
+ }
+ break;
+ }
+ return 0;
+}
+
+static struct notifier_block nb = {
+ .notifier_call = sii902x_fb_event,
+};
+
+static int mxsfb_get_of_property(void)
+{
+ struct device_node *np = sii902x.client->dev.of_node;
+ const char *mode_str;
+ int bits_per_pixel, ret;
+
+ ret = of_property_read_string(np, "mode_str", &mode_str);
+ if (ret < 0) {
+ dev_warn(&sii902x.client->dev, "get of property mode_str fail\n");
+ return ret;
+ }
+ ret = of_property_read_u32(np, "bits-per-pixel", &bits_per_pixel);
+ if (ret) {
+ dev_warn(&sii902x.client->dev, "get of property bpp fail\n");
+ return ret;
+ }
+
+ sii902x.mode_str = mode_str;
+ sii902x.bits_per_pixel = bits_per_pixel;
+
+ return ret;
+}
+
+static int sii902x_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ int i, dat, ret;
+ struct fb_info edid_fbi;
+ struct fb_info *init_fbi = sii902x.fbi;
+
+ memset(&sii902x, 0, sizeof(sii902x));
+
+ sii902x.client = client;
+
+ dev_dbg(&sii902x.client->dev, "%s\n", __func__);;
+
+ /* Reset sii902x */
+ ret = device_reset(&sii902x.client->dev);
+ if (ret)
+ dev_warn(&sii902x.client->dev, "No reset pin found\n");
+ if (ret == -EPROBE_DEFER)
+ return ret;
+
+ /* Set 902x in hardware TPI mode on and jump out of D3 state */
+ if (i2c_smbus_write_byte_data(sii902x.client, 0xc7, 0x00) < 0) {
+ dev_err(&sii902x.client->dev,
+ "Sii902x: cound not find device\n");
+ return -ENODEV;
+ }
+
+ /* read device ID */
+ for (i = 10; i > 0; i--) {
+ dat = i2c_smbus_read_byte_data(sii902x.client, 0x1B);
+ dev_dbg(&sii902x.client->dev, "Sii902x: read id = 0x%02X", dat);
+ if (dat == 0xb0) {
+ dat = i2c_smbus_read_byte_data(sii902x.client, 0x1C);
+ dev_dbg(&sii902x.client->dev, "-0x%02X", dat);
+ dat = i2c_smbus_read_byte_data(sii902x.client, 0x1D);
+ dev_dbg(&sii902x.client->dev, "-0x%02X", dat);
+ dat = i2c_smbus_read_byte_data(sii902x.client, 0x30);
+ dev_dbg(&sii902x.client->dev, "-0x%02X\n", dat);
+ break;
+ }
+ }
+ if (i == 0) {
+ dev_err(&sii902x.client->dev,
+ "Sii902x: cound not find device\n");
+ return -ENODEV;
+ }
+
+ /* enable hmdi audio */
+ sii902x_audio_setup();
+
+ /* try to read edid, only if cable is plugged in */
+ dat = i2c_smbus_read_byte_data(sii902x.client, 0x3D);
+ if (dat & 0x04) {
+ ret = sii902x_read_edid(&edid_fbi);
+ if (ret < 0)
+ dev_warn(&sii902x.client->dev, "Can not read edid\n");
+ }
+
+ if (sii902x.client->irq) {
+ ret = request_irq(sii902x.client->irq, sii902x_detect_handler,
+ IRQF_TRIGGER_FALLING,
+ "SII902x_det", &sii902x);
+ if (ret < 0)
+ dev_warn(&sii902x.client->dev,
+ "Sii902x: cound not request det irq %d\n",
+ sii902x.client->irq);
+ else {
+ /*enable cable hot plug irq*/
+ i2c_smbus_write_byte_data(sii902x.client, 0x3c, 0x01);
+ INIT_DELAYED_WORK(&(sii902x.det_work), det_worker);
+ }
+ ret = device_create_file(&sii902x.client->dev, &dev_attr_fb_name);
+ if (ret < 0)
+ dev_warn(&sii902x.client->dev,
+ "Sii902x: cound not create sys node for fb name\n");
+ ret = device_create_file(&sii902x.client->dev, &dev_attr_cable_state);
+ if (ret < 0)
+ dev_warn(&sii902x.client->dev,
+ "Sii902x: cound not create sys node for cable state\n");
+ ret = device_create_file(&sii902x.client->dev, &dev_attr_edid);
+ if (ret < 0)
+ dev_warn(&sii902x.client->dev,
+ "Sii902x: cound not create sys node for edid\n");
+
+ }
+
+ mxsfb_get_of_property();
+
+ if (init_fbi) {
+ sii902x.fbi = init_fbi;
+
+ /* Manually trigger a plugin/plugout interrupter to check cable state */
+ schedule_delayed_work(&(sii902x.det_work), msecs_to_jiffies(50));
+ }
+
+ sii902x_in_init_state = 0;
+
+ return 0;
+}
+
+static int sii902x_remove(struct i2c_client *client)
+{
+ fb_unregister_client(&nb);
+ sii902x_poweroff();
+
+ return 0;
+}
+
+static void sii902x_poweron(void)
+{
+ /* Turn on DVI or HDMI */
+ if (sii902x.edid_cfg.hdmi_cap)
+ i2c_smbus_write_byte_data(sii902x.client, 0x1A, 0x01);
+ else
+ i2c_smbus_write_byte_data(sii902x.client, 0x1A, 0x00);
+ return;
+}
+
+static void sii902x_poweroff(void)
+{
+ /* disable tmds before changing resolution */
+ if (sii902x.edid_cfg.hdmi_cap)
+ i2c_smbus_write_byte_data(sii902x.client, 0x1A, 0x11);
+ else
+ i2c_smbus_write_byte_data(sii902x.client, 0x1A, 0x10);
+
+ return;
+}
+
+static int __init sii902x_init(void)
+{
+ sii902x_in_init_state = 1;
+
+ return fb_register_client(&nb);
+}
+fs_initcall_sync(sii902x_init);
+
+static const struct i2c_device_id sii902x_id[] = {
+ { DRV_NAME, 0},
+ { },
+};
+MODULE_DEVICE_TABLE(i2c, sii902x_id);
+
+static const struct of_device_id sii902x_dt_ids[] = {
+ { .compatible = "SiI,sii902x", },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, sii902x_dt_ids);
+
+static struct i2c_driver sii902x_driver = {
+ .driver = {
+ .name = DRV_NAME,
+ .owner = THIS_MODULE,
+ .of_match_table = sii902x_dt_ids,
+ },
+ .probe = sii902x_probe,
+ .remove = sii902x_remove,
+ .id_table = sii902x_id,
+};
+
+module_i2c_driver(sii902x_driver);
+
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("SII902x DVI/HDMI driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/video/fbdev/mxsfb.c b/drivers/video/fbdev/mxsfb.c
index 7846f0e8bbbb..f4294b355d21 100644
--- a/drivers/video/fbdev/mxsfb.c
+++ b/drivers/video/fbdev/mxsfb.c
@@ -4,7 +4,8 @@
* This code is based on:
* Author: Vitaly Wool <vital@embeddedalley.com>
*
- * Copyright 2008-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2017-2019 NXP
+ * Copyright 2008-2015 Freescale Semiconductor, Inc. All Rights Reserved.
* Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved.
*
* This program is free software; you can redistribute it and/or
@@ -39,18 +40,30 @@
* the required value in the imx_fb_videomode structure.
*/
+#include <linux/busfreq-imx.h>
+#include <linux/console.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/of_device.h>
+#include <linux/of_gpio.h>
+#include <linux/pm_qos.h>
#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/interrupt.h>
#include <linux/clk.h>
#include <linux/dma-mapping.h>
#include <linux/io.h>
+#include <linux/pinctrl/consumer.h>
#include <linux/fb.h>
+#include <linux/mxcfb.h>
#include <linux/regulator/consumer.h>
+#include <linux/types.h>
+#include <linux/videodev2.h>
#include <video/of_display_timing.h>
-#include <video/of_videomode.h>
#include <video/videomode.h>
+#include <linux/uaccess.h>
+
+#include "mxc/mxc_dispdrv.h"
#define REG_SET 4
#define REG_CLR 8
@@ -79,6 +92,9 @@
#define LCDC_V3_DATA 0x1b0
#define LCDC_V4_DEBUG0 0x1d0
#define LCDC_V3_DEBUG0 0x1f0
+#define LCDC_AS_CTRL 0x210
+#define LCDC_AS_BUF 0x220
+#define LCDC_AS_NEXT_BUF 0x230
#define CTRL_SFTRST (1 << 31)
#define CTRL_CLKGATE (1 << 30)
@@ -96,9 +112,30 @@
#define CTRL_DF24 (1 << 1)
#define CTRL_RUN (1 << 0)
-#define CTRL1_FIFO_CLEAR (1 << 21)
-#define CTRL1_SET_BYTE_PACKAGING(x) (((x) & 0xf) << 16)
-#define CTRL1_GET_BYTE_PACKAGING(x) (((x) >> 16) & 0xf)
+#define CTRL1_RECOVERY_ON_UNDERFLOW (1 << 24)
+#define CTRL1_FIFO_CLEAR (1 << 21)
+#define CTRL1_SET_BYTE_PACKAGING(x) (((x) & 0xf) << 16)
+#define CTRL1_GET_BYTE_PACKAGING(x) (((x) >> 16) & 0xf)
+#define CTRL1_OVERFLOW_IRQ_EN (1 << 15)
+#define CTRL1_UNDERFLOW_IRQ_EN (1 << 14)
+#define CTRL1_CUR_FRAME_DONE_IRQ_EN (1 << 13)
+#define CTRL1_VSYNC_EDGE_IRQ_EN (1 << 12)
+#define CTRL1_OVERFLOW_IRQ (1 << 11)
+#define CTRL1_UNDERFLOW_IRQ (1 << 10)
+#define CTRL1_CUR_FRAME_DONE_IRQ (1 << 9)
+#define CTRL1_VSYNC_EDGE_IRQ (1 << 8)
+#define CTRL1_IRQ_ENABLE_MASK (CTRL1_OVERFLOW_IRQ_EN | \
+ CTRL1_UNDERFLOW_IRQ_EN | \
+ CTRL1_CUR_FRAME_DONE_IRQ_EN | \
+ CTRL1_VSYNC_EDGE_IRQ_EN)
+#define CTRL1_IRQ_ENABLE_SHIFT 12
+#define CTRL1_IRQ_STATUS_MASK (CTRL1_OVERFLOW_IRQ | \
+ CTRL1_UNDERFLOW_IRQ | \
+ CTRL1_CUR_FRAME_DONE_IRQ | \
+ CTRL1_VSYNC_EDGE_IRQ)
+#define CTRL1_IRQ_STATUS_SHIFT 8
+
+#define CTRL2_OUTSTANDING_REQS__REQ_16 (4 << 21)
#define TRANSFER_COUNT_SET_VCOUNT(x) (((x) & 0xffff) << 16)
#define TRANSFER_COUNT_GET_VCOUNT(x) (((x) >> 16) & 0xffff)
@@ -149,12 +186,13 @@
#define STMLCDIF_18BIT 2 /** pixel data bus to the display is of 18 bit width */
#define STMLCDIF_24BIT 3 /** pixel data bus to the display is of 24 bit width */
-#define MXSFB_SYNC_DATA_ENABLE_HIGH_ACT (1 << 6)
-#define MXSFB_SYNC_DOTCLK_FALLING_ACT (1 << 7) /* negtive edge sampling */
+#define FB_SYNC_OE_LOW_ACT 0x80000000
+#define FB_SYNC_CLK_LAT_FALL 0x40000000
enum mxsfb_devtype {
MXSFB_V3,
MXSFB_V4,
+ MXSFB_V5,
};
/* CPU dependent register offsets */
@@ -166,26 +204,79 @@ struct mxsfb_devdata {
unsigned hs_wdth_mask;
unsigned hs_wdth_shift;
unsigned ipversion;
+ u32 flags;
+};
+
+struct mxsfb_layer;
+
+struct mxsfb_layer_ops {
+ void (*enable)(struct mxsfb_layer *ofb);
+ void (*disable)(struct mxsfb_layer *ofb);
+ void (*setup)(struct mxsfb_layer *ofb);
+};
+
+struct mxsfb_layer {
+ struct fb_info *ol_fb;
+ int id;
+ int registered;
+ atomic_t usage;
+ int blank_state;
+ uint32_t global_alpha;
+
+ struct mxsfb_layer_ops *ops;
+
+ struct device *dev;
+ void __iomem *video_mem;
+ unsigned long video_mem_phys;
+ size_t video_mem_size;
+
+ struct mxsfb_info *fbi;
};
+#define NAME_LEN 32
+
struct mxsfb_info {
- struct fb_info fb_info;
+ struct fb_info *fb_info;
struct platform_device *pdev;
- struct clk *clk;
+ struct clk *clk_pix;
struct clk *clk_axi;
struct clk *clk_disp_axi;
+ bool clk_pix_enabled;
+ bool clk_axi_enabled;
+ bool clk_disp_axi_enabled;
void __iomem *base; /* registers */
+ u32 sync; /* record display timing polarities */
unsigned allocated_size;
int enabled;
unsigned ld_intf_width;
unsigned dotclk_delay;
const struct mxsfb_devdata *devdata;
- u32 sync;
struct regulator *reg_lcd;
+ bool wait4vsync;
+ struct completion vsync_complete;
+ struct completion flip_complete;
+ int cur_blank;
+ int restore_blank;
+ char disp_dev[NAME_LEN];
+ struct mxc_dispdrv_handle *dispdrv;
+ int id;
+ struct fb_var_screeninfo var;
+ struct pm_qos_request pm_qos_req;
+
+ char disp_videomode[NAME_LEN];
+
+#ifdef CONFIG_FB_MXC_OVERLAY
+ struct mxsfb_layer overlay;
+#endif
};
#define mxsfb_is_v3(host) (host->devdata->ipversion == 3)
#define mxsfb_is_v4(host) (host->devdata->ipversion == 4)
+#define mxsfb_is_v5(host) (host->devdata->ipversion == 5)
+
+#define MXSFB_FLAG_NULL 0x0
+#define MXSFB_FLAG_BUSFREQ 0x1
+#define MXSFB_FLAG_PMQOS 0x2
static const struct mxsfb_devdata mxsfb_devdata[] = {
[MXSFB_V3] = {
@@ -196,6 +287,7 @@ static const struct mxsfb_devdata mxsfb_devdata[] = {
.hs_wdth_mask = 0xff,
.hs_wdth_shift = 24,
.ipversion = 3,
+ .flags = MXSFB_FLAG_NULL,
},
[MXSFB_V4] = {
.transfer_count = LCDC_V4_TRANSFER_COUNT,
@@ -205,10 +297,77 @@ static const struct mxsfb_devdata mxsfb_devdata[] = {
.hs_wdth_mask = 0x3fff,
.hs_wdth_shift = 18,
.ipversion = 4,
+ .flags = MXSFB_FLAG_BUSFREQ,
+ },
+ [MXSFB_V5] = {
+ .transfer_count = LCDC_V4_TRANSFER_COUNT,
+ .cur_buf = LCDC_V4_CUR_BUF,
+ .next_buf = LCDC_V4_NEXT_BUF,
+ .debug0 = LCDC_V4_DEBUG0,
+ .hs_wdth_mask = 0x3fff,
+ .hs_wdth_shift = 18,
+ .ipversion = 4,
+ .flags = MXSFB_FLAG_PMQOS,
},
};
-#define to_imxfb_host(x) (container_of(x, struct mxsfb_info, fb_info))
+static int mxsfb_map_videomem(struct fb_info *info);
+static int mxsfb_unmap_videomem(struct fb_info *info);
+static int mxsfb_set_par(struct fb_info *fb_info);
+
+/* enable lcdif pix clock */
+static inline void clk_enable_pix(struct mxsfb_info *host)
+{
+ if (!host->clk_pix_enabled && (host->clk_pix != NULL)) {
+ clk_prepare_enable(host->clk_pix);
+ host->clk_pix_enabled = true;
+ }
+}
+
+/* disable lcdif pix clock */
+static inline void clk_disable_pix(struct mxsfb_info *host)
+{
+ if (host->clk_pix_enabled && (host->clk_pix != NULL)) {
+ clk_disable_unprepare(host->clk_pix);
+ host->clk_pix_enabled = false;
+ }
+}
+
+/* enable lcdif axi clock */
+static inline void clk_enable_axi(struct mxsfb_info *host)
+{
+ if (!host->clk_axi_enabled && (host->clk_axi != NULL)) {
+ clk_prepare_enable(host->clk_axi);
+ host->clk_axi_enabled = true;
+ }
+}
+
+/* disable lcdif axi clock */
+static inline void clk_disable_axi(struct mxsfb_info *host)
+{
+ if (host->clk_axi_enabled && (host->clk_axi != NULL)) {
+ clk_disable_unprepare(host->clk_axi);
+ host->clk_axi_enabled = false;
+ }
+}
+
+/* enable DISP axi clock */
+static inline void clk_enable_disp_axi(struct mxsfb_info *host)
+{
+ if (!host->clk_disp_axi_enabled && (host->clk_disp_axi != NULL)) {
+ clk_prepare_enable(host->clk_disp_axi);
+ host->clk_disp_axi_enabled = true;
+ }
+}
+
+/* disable DISP axi clock */
+static inline void clk_disable_disp_axi(struct mxsfb_info *host)
+{
+ if (host->clk_disp_axi_enabled && (host->clk_disp_axi != NULL)) {
+ clk_disable_unprepare(host->clk_disp_axi);
+ host->clk_disp_axi_enabled = false;
+ }
+}
/* mask and shift depends on architecture */
static inline u32 set_hsync_pulse_width(struct mxsfb_info *host, unsigned val)
@@ -241,6 +400,105 @@ static const struct fb_bitfield def_rgb565[] = {
}
};
+#ifdef CONFIG_FB_MXC_OVERLAY
+static u32 saved_as_ctrl;
+static u32 saved_as_next_buf;
+
+static const struct fb_bitfield def_argb555[] = {
+ [RED] = {
+ .offset = 10,
+ .length = 5,
+ },
+ [GREEN] = {
+ .offset = 5,
+ .length = 5,
+ },
+ [BLUE] = {
+ .offset = 0,
+ .length = 5,
+ },
+ [TRANSP] = {
+ .offset = 15,
+ .length = 0,
+ }
+};
+
+static const struct fb_bitfield def_rgb555[] = {
+ [RED] = {
+ .offset = 10,
+ .length = 5,
+ },
+ [GREEN] = {
+ .offset = 5,
+ .length = 5,
+ },
+ [BLUE] = {
+ .offset = 0,
+ .length = 5,
+ },
+ [TRANSP] = {
+ .offset = 0,
+ .length = 0,
+ }
+};
+
+static const struct fb_bitfield def_argb444[] = {
+ [RED] = {
+ .offset = 8,
+ .length = 4,
+ },
+ [GREEN] = {
+ .offset = 4,
+ .length = 4,
+ },
+ [BLUE] = {
+ .offset = 0,
+ .length = 4,
+ },
+ [TRANSP] = {
+ .offset = 12,
+ .length = 4,
+ }
+};
+
+static const struct fb_bitfield def_rgb444[] = {
+ [RED] = {
+ .offset = 8,
+ .length = 4,
+ },
+ [GREEN] = {
+ .offset = 4,
+ .length = 4,
+ },
+ [BLUE] = {
+ .offset = 0,
+ .length = 4,
+ },
+ [TRANSP] = {
+ .offset = 0,
+ .length = 0,
+ }
+};
+#endif
+
+static const struct fb_bitfield def_rgb666[] = {
+ [RED] = {
+ .offset = 16,
+ .length = 6,
+ },
+ [GREEN] = {
+ .offset = 8,
+ .length = 6,
+ },
+ [BLUE] = {
+ .offset = 0,
+ .length = 6,
+ },
+ [TRANSP] = { /* no support for transparency */
+ .length = 0,
+ }
+};
+
static const struct fb_bitfield def_rgb888[] = {
[RED] = {
.offset = 16,
@@ -259,6 +517,38 @@ static const struct fb_bitfield def_rgb888[] = {
}
};
+static const struct fb_bitfield def_argb32[] = {
+ [RED] = {
+ .offset = 16,
+ .length = 8,
+ },
+ [GREEN] = {
+ .offset = 8,
+ .length = 8,
+ },
+ [BLUE] = {
+ .offset = 0,
+ .length = 8,
+ },
+ [TRANSP] = {
+ .offset = 24,
+ .length = 8,
+ }
+};
+
+#define bitfield_is_equal(f1, f2) (!memcmp(&(f1), &(f2), sizeof(f1)))
+
+static inline bool pixfmt_is_equal(struct fb_var_screeninfo *var,
+ const struct fb_bitfield *f)
+{
+ if (bitfield_is_equal(var->red, f[RED]) &&
+ bitfield_is_equal(var->green, f[GREEN]) &&
+ bitfield_is_equal(var->blue, f[BLUE]))
+ return true;
+
+ return false;
+}
+
static inline unsigned chan_to_field(unsigned chan, struct fb_bitfield *bf)
{
chan &= 0xffff;
@@ -266,10 +556,46 @@ static inline unsigned chan_to_field(unsigned chan, struct fb_bitfield *bf)
return chan << bf->offset;
}
+static irqreturn_t mxsfb_irq_handler(int irq, void *dev_id)
+{
+ struct mxsfb_info *host = dev_id;
+ u32 ctrl1, enable, status, acked_status;
+
+ ctrl1 = readl(host->base + LCDC_CTRL1);
+ enable = (ctrl1 & CTRL1_IRQ_ENABLE_MASK) >> CTRL1_IRQ_ENABLE_SHIFT;
+ status = (ctrl1 & CTRL1_IRQ_STATUS_MASK) >> CTRL1_IRQ_STATUS_SHIFT;
+ acked_status = (enable & status) << CTRL1_IRQ_STATUS_SHIFT;
+
+ if ((acked_status & CTRL1_VSYNC_EDGE_IRQ) && host->wait4vsync) {
+ writel(CTRL1_VSYNC_EDGE_IRQ,
+ host->base + LCDC_CTRL1 + REG_CLR);
+ writel(CTRL1_VSYNC_EDGE_IRQ_EN,
+ host->base + LCDC_CTRL1 + REG_CLR);
+ host->wait4vsync = 0;
+ complete(&host->vsync_complete);
+ }
+
+ if (acked_status & CTRL1_CUR_FRAME_DONE_IRQ) {
+ writel(CTRL1_CUR_FRAME_DONE_IRQ,
+ host->base + LCDC_CTRL1 + REG_CLR);
+ writel(CTRL1_CUR_FRAME_DONE_IRQ_EN,
+ host->base + LCDC_CTRL1 + REG_CLR);
+ complete(&host->flip_complete);
+ }
+
+ if (acked_status & CTRL1_UNDERFLOW_IRQ)
+ writel(CTRL1_UNDERFLOW_IRQ, host->base + LCDC_CTRL1 + REG_CLR);
+
+ if (acked_status & CTRL1_OVERFLOW_IRQ)
+ writel(CTRL1_OVERFLOW_IRQ, host->base + LCDC_CTRL1 + REG_CLR);
+
+ return IRQ_HANDLED;
+}
+
static int mxsfb_check_var(struct fb_var_screeninfo *var,
struct fb_info *fb_info)
{
- struct mxsfb_info *host = to_imxfb_host(fb_info);
+ struct mxsfb_info *host = fb_info->par;
const struct fb_bitfield *rgb = NULL;
if (var->xres < MIN_XRES)
@@ -277,9 +603,18 @@ static int mxsfb_check_var(struct fb_var_screeninfo *var,
if (var->yres < MIN_YRES)
var->yres = MIN_YRES;
- var->xres_virtual = var->xres;
+ if (var->xres_virtual > var->xres) {
+ dev_dbg(fb_info->device, "stride not supported\n");
+ return -EINVAL;
+ }
- var->yres_virtual = var->yres;
+ if (var->xres_virtual < var->xres)
+ var->xres_virtual = var->xres;
+ if (var->yres_virtual < var->yres)
+ var->yres_virtual = var->yres;
+
+ if ((var->bits_per_pixel != 32) && (var->bits_per_pixel != 16))
+ var->bits_per_pixel = 32;
switch (var->bits_per_pixel) {
case 16:
@@ -290,17 +625,35 @@ static int mxsfb_check_var(struct fb_var_screeninfo *var,
switch (host->ld_intf_width) {
case STMLCDIF_8BIT:
pr_debug("Unsupported LCD bus width mapping\n");
- break;
+ return -EINVAL;
case STMLCDIF_16BIT:
+ /* 24 bit to 18 bit mapping */
+ rgb = def_rgb666;
+ break;
case STMLCDIF_18BIT:
+ if (pixfmt_is_equal(var, def_rgb666))
+ /* 24 bit to 18 bit mapping */
+ rgb = def_rgb666;
+ else
+ rgb = def_rgb888;
+ break;
case STMLCDIF_24BIT:
/* real 24 bit */
rgb = def_rgb888;
break;
+ default:
+ /*
+ * 32-bit output is possible through I/O muxing, if this
+ * option is available on chip. Currently not
+ * implemented.
+ */
+ pr_debug("Currently unsupported output colour depth: %u\n",
+ host->ld_intf_width);
+ return -EINVAL;
}
break;
default:
- pr_err("Unsupported colour depth: %u\n", var->bits_per_pixel);
+ pr_debug("Unsupported colour depth: %u\n", var->bits_per_pixel);
return -EINVAL;
}
@@ -316,26 +669,27 @@ static int mxsfb_check_var(struct fb_var_screeninfo *var,
return 0;
}
-static inline void mxsfb_enable_axi_clk(struct mxsfb_info *host)
-{
- if (host->clk_axi)
- clk_prepare_enable(host->clk_axi);
-}
-
-static inline void mxsfb_disable_axi_clk(struct mxsfb_info *host)
-{
- if (host->clk_axi)
- clk_disable_unprepare(host->clk_axi);
-}
-
static void mxsfb_enable_controller(struct fb_info *fb_info)
{
- struct mxsfb_info *host = to_imxfb_host(fb_info);
+ struct mxsfb_info *host = fb_info->par;
u32 reg;
int ret;
+#ifdef CONFIG_FB_IMX64_DEBUG
+ static int pix_enable;
+#endif
dev_dbg(&host->pdev->dev, "%s\n", __func__);
+ if (host->dispdrv && host->dispdrv->drv->setup) {
+ ret = host->dispdrv->drv->setup(host->dispdrv, fb_info);
+ if (ret < 0) {
+ dev_err(&host->pdev->dev, "failed to setup"
+ "dispdrv:%s\n", host->dispdrv->drv->name);
+ return;
+ }
+ host->sync = fb_info->var.sync;
+ }
+
if (host->reg_lcd) {
ret = regulator_enable(host->reg_lcd);
if (ret) {
@@ -345,12 +699,44 @@ static void mxsfb_enable_controller(struct fb_info *fb_info)
}
}
- if (host->clk_disp_axi)
- clk_prepare_enable(host->clk_disp_axi);
- clk_prepare_enable(host->clk);
- clk_set_rate(host->clk, PICOS2KHZ(fb_info->var.pixclock) * 1000U);
+ if (host->dispdrv && host->dispdrv->drv->enable) {
+ ret = host->dispdrv->drv->enable(host->dispdrv, fb_info);
+ if (ret < 0)
+ dev_err(&host->pdev->dev, "failed to enable "
+ "dispdrv:%s\n", host->dispdrv->drv->name);
+ }
+
+#ifdef CONFIG_FB_IMX64_DEBUG
+ if (unlikely(!pix_enable)) {
+ /* the pixel clock should be disabled before
+ * trying to set its clock rate successfully.
+ */
+#else
+ clk_disable_pix(host);
+#endif
+ ret = clk_set_rate(host->clk_pix,
+ PICOS2KHZ(fb_info->var.pixclock) * 1000U);
+ if (ret) {
+ dev_err(&host->pdev->dev,
+ "lcd pixel rate set failed: %d\n", ret);
+
+ if (host->reg_lcd) {
+ ret = regulator_disable(host->reg_lcd);
+ if (ret)
+ dev_err(&host->pdev->dev,
+ "lcd regulator disable failed: %d\n",
+ ret);
+ }
+ return;
+ }
+ clk_enable_pix(host);
+#ifdef CONFIG_FB_IMX64_DEBUG
+ pix_enable++;
+ }
+#endif
- mxsfb_enable_axi_clk(host);
+ writel(CTRL2_OUTSTANDING_REQS__REQ_16,
+ host->base + LCDC_V4_CTRL2 + REG_SET);
/* if it was disabled, re-enable the mode again */
writel(CTRL_DOTCLK_MODE, host->base + LCDC_CTRL + REG_SET);
@@ -360,20 +746,30 @@ static void mxsfb_enable_controller(struct fb_info *fb_info)
reg |= VDCTRL4_SYNC_SIGNALS_ON;
writel(reg, host->base + LCDC_VDCTRL4);
+ writel(CTRL_MASTER, host->base + LCDC_CTRL + REG_SET);
writel(CTRL_RUN, host->base + LCDC_CTRL + REG_SET);
+ /* Recovery on underflow */
+ writel(CTRL1_RECOVERY_ON_UNDERFLOW, host->base + LCDC_CTRL1 + REG_SET);
+
host->enabled = 1;
+
}
static void mxsfb_disable_controller(struct fb_info *fb_info)
{
- struct mxsfb_info *host = to_imxfb_host(fb_info);
+ struct mxsfb_info *host = fb_info->par;
unsigned loop;
u32 reg;
int ret;
dev_dbg(&host->pdev->dev, "%s\n", __func__);
+ writel(CTRL_RUN, host->base + LCDC_CTRL + REG_CLR);
+
+ if (host->dispdrv && host->dispdrv->drv->disable)
+ host->dispdrv->drv->disable(host->dispdrv, fb_info);
+
/*
* Even if we disable the controller here, it will still continue
* until its FIFOs are running out of data
@@ -388,15 +784,11 @@ static void mxsfb_disable_controller(struct fb_info *fb_info)
loop--;
}
+ writel(CTRL_MASTER, host->base + LCDC_CTRL + REG_CLR);
+
reg = readl(host->base + LCDC_VDCTRL4);
writel(reg & ~VDCTRL4_SYNC_SIGNALS_ON, host->base + LCDC_VDCTRL4);
- mxsfb_disable_axi_clk(host);
-
- clk_disable_unprepare(host->clk);
- if (host->clk_disp_axi)
- clk_disable_unprepare(host->clk_disp_axi);
-
host->enabled = 0;
if (host->reg_lcd) {
@@ -407,20 +799,67 @@ static void mxsfb_disable_controller(struct fb_info *fb_info)
}
}
+/**
+ This function compare the fb parameter see whether it was different
+ parameter for hardware, if it was different parameter, the hardware
+ will reinitialize. All will compared except x/y offset.
+ */
+static bool mxsfb_par_equal(struct fb_info *fbi, struct mxsfb_info *host)
+{
+ /* Here we set the xoffset, yoffset to zero, and compare two
+ * var see have different or not. */
+ struct fb_var_screeninfo oldvar = host->var;
+ struct fb_var_screeninfo newvar = fbi->var;
+
+ if ((fbi->var.activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW &&
+ fbi->var.activate & FB_ACTIVATE_FORCE)
+ return false;
+
+ oldvar.xoffset = newvar.xoffset = 0;
+ oldvar.yoffset = newvar.yoffset = 0;
+
+ return memcmp(&oldvar, &newvar, sizeof(struct fb_var_screeninfo)) == 0;
+}
+
static int mxsfb_set_par(struct fb_info *fb_info)
{
- struct mxsfb_info *host = to_imxfb_host(fb_info);
+ struct mxsfb_info *host = fb_info->par;
u32 ctrl, vdctrl0, vdctrl4;
int line_size, fb_size;
int reenable = 0;
+ static u32 equal_bypass = 0;
+#ifdef CONFIG_FB_IMX64_DEBUG
+ static int time;
+
+ if (time == 1)
+ return 0;
+ time++;
+#endif
+
+ if (likely(equal_bypass > 1)) {
+ /* If parameter no change, don't reconfigure. */
+ if (mxsfb_par_equal(fb_info, host))
+ return 0;
+ } else
+ equal_bypass++;
+
+ dev_dbg(&host->pdev->dev, "%s\n", __func__);
+
+ /* If fb is in blank mode, it is
+ * unnecessary to really set par here.
+ * It can be delayed when unblank fb
+ */
+ if (host->cur_blank != FB_BLANK_UNBLANK)
+ return 0;
line_size = fb_info->var.xres * (fb_info->var.bits_per_pixel >> 3);
+ fb_info->fix.line_length = line_size;
fb_size = fb_info->var.yres_virtual * line_size;
- if (fb_size > fb_info->fix.smem_len)
+ if (fb_size > fb_info->fix.smem_len) {
+ dev_err(&host->pdev->dev, "exceeds the fb buffer size limit!\n");
return -ENOMEM;
-
- fb_info->fix.line_length = line_size;
+ }
/*
* It seems, you can't re-program the controller if it is still running.
@@ -432,8 +871,6 @@ static int mxsfb_set_par(struct fb_info *fb_info)
mxsfb_disable_controller(fb_info);
}
- mxsfb_enable_axi_clk(host);
-
/* clear the FIFOs */
writel(CTRL1_FIFO_CLEAR, host->base + LCDC_CTRL1 + REG_SET);
@@ -451,12 +888,22 @@ static int mxsfb_set_par(struct fb_info *fb_info)
ctrl |= CTRL_SET_WORD_LENGTH(3);
switch (host->ld_intf_width) {
case STMLCDIF_8BIT:
- mxsfb_disable_axi_clk(host);
- dev_err(&host->pdev->dev,
+ dev_dbg(&host->pdev->dev,
"Unsupported LCD bus width mapping\n");
return -EINVAL;
case STMLCDIF_16BIT:
+ /* 24 bit to 18 bit mapping */
+ ctrl |= CTRL_DF24; /* ignore the upper 2 bits in
+ * each colour component
+ */
+ break;
case STMLCDIF_18BIT:
+ if (pixfmt_is_equal(&fb_info->var, def_rgb666))
+ /* 24 bit to 18 bit mapping */
+ ctrl |= CTRL_DF24; /* ignore the upper 2 bits in
+ * each colour component
+ */
+ break;
case STMLCDIF_24BIT:
/* real 24 bit */
break;
@@ -465,8 +912,7 @@ static int mxsfb_set_par(struct fb_info *fb_info)
writel(CTRL1_SET_BYTE_PACKAGING(0x7), host->base + LCDC_CTRL1);
break;
default:
- mxsfb_disable_axi_clk(host);
- dev_err(&host->pdev->dev, "Unhandled color depth of %u\n",
+ dev_dbg(&host->pdev->dev, "Unhandled color depth of %u\n",
fb_info->var.bits_per_pixel);
return -EINVAL;
}
@@ -481,13 +927,16 @@ static int mxsfb_set_par(struct fb_info *fb_info)
VDCTRL0_VSYNC_PERIOD_UNIT |
VDCTRL0_VSYNC_PULSE_WIDTH_UNIT |
VDCTRL0_SET_VSYNC_PULSE_WIDTH(fb_info->var.vsync_len);
- if (fb_info->var.sync & FB_SYNC_HOR_HIGH_ACT)
+ /* use the saved sync to avoid wrong sync information */
+ if (host->sync & FB_SYNC_HOR_HIGH_ACT)
vdctrl0 |= VDCTRL0_HSYNC_ACT_HIGH;
- if (fb_info->var.sync & FB_SYNC_VERT_HIGH_ACT)
+ if (host->sync & FB_SYNC_VERT_HIGH_ACT)
vdctrl0 |= VDCTRL0_VSYNC_ACT_HIGH;
- if (host->sync & MXSFB_SYNC_DATA_ENABLE_HIGH_ACT)
+#ifndef CONFIG_FB_IMX64_DEBUG
+ if (!(host->sync & FB_SYNC_OE_LOW_ACT))
vdctrl0 |= VDCTRL0_ENABLE_ACT_HIGH;
- if (host->sync & MXSFB_SYNC_DOTCLK_FALLING_ACT)
+#endif
+ if (host->sync & FB_SYNC_CLK_LAT_FALL)
vdctrl0 |= VDCTRL0_DOTCLK_ACT_FALLING;
writel(vdctrl0, host->base + LCDC_VDCTRL0);
@@ -519,11 +968,15 @@ static int mxsfb_set_par(struct fb_info *fb_info)
fb_info->fix.line_length * fb_info->var.yoffset,
host->base + host->devdata->next_buf);
- mxsfb_disable_axi_clk(host);
-
if (reenable)
mxsfb_enable_controller(fb_info);
+ /* Clear activate as not Reconfiguring framebuffer again */
+ if ((fb_info->var.activate & FB_ACTIVATE_FORCE) &&
+ (fb_info->var.activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW)
+ fb_info->var.activate = FB_ACTIVATE_NOW;
+
+ host->var = fb_info->var;
return 0;
}
@@ -567,22 +1020,90 @@ static int mxsfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
return ret;
}
+static int mxsfb_wait_for_vsync(struct fb_info *fb_info)
+{
+ struct mxsfb_info *host = fb_info->par;
+ int ret = 0;
+
+ if (host->cur_blank != FB_BLANK_UNBLANK) {
+ dev_err(fb_info->device, "can't wait for VSYNC when fb "
+ "is blank\n");
+ return -EINVAL;
+ }
+
+ init_completion(&host->vsync_complete);
+
+ host->wait4vsync = 1;
+ writel(CTRL1_VSYNC_EDGE_IRQ_EN,
+ host->base + LCDC_CTRL1 + REG_SET);
+ ret = wait_for_completion_interruptible_timeout(
+ &host->vsync_complete, 1 * HZ);
+ if (ret == 0) {
+ dev_err(fb_info->device,
+ "mxs wait for vsync timeout\n");
+ host->wait4vsync = 0;
+ ret = -ETIME;
+ } else if (ret > 0) {
+ ret = 0;
+ }
+ return ret;
+}
+
+static int mxsfb_ioctl(struct fb_info *fb_info, unsigned int cmd,
+ unsigned long arg)
+{
+ int ret = -EINVAL;
+
+ switch (cmd) {
+ case MXCFB_WAIT_FOR_VSYNC:
+ ret = mxsfb_wait_for_vsync(fb_info);
+ break;
+ default:
+ break;
+ }
+ return ret;
+}
+
static int mxsfb_blank(int blank, struct fb_info *fb_info)
{
- struct mxsfb_info *host = to_imxfb_host(fb_info);
+ struct mxsfb_info *host = fb_info->par;
+
+#ifdef CONFIG_FB_IMX64_DEBUG
+ return 0;
+#endif
+
+ host->cur_blank = blank;
switch (blank) {
case FB_BLANK_POWERDOWN:
case FB_BLANK_VSYNC_SUSPEND:
case FB_BLANK_HSYNC_SUSPEND:
case FB_BLANK_NORMAL:
- if (host->enabled)
+ if (host->enabled) {
mxsfb_disable_controller(fb_info);
+ pm_runtime_put_sync_suspend(&host->pdev->dev);
+ }
+
+ clk_disable_disp_axi(host);
+ clk_disable_axi(host);
+ clk_disable_pix(host);
break;
case FB_BLANK_UNBLANK:
- if (!host->enabled)
+ fb_info->var.activate = (fb_info->var.activate & ~FB_ACTIVATE_MASK) |
+ FB_ACTIVATE_NOW | FB_ACTIVATE_FORCE;
+
+ clk_enable_pix(host);
+ clk_enable_axi(host);
+ clk_enable_disp_axi(host);
+
+ if (!host->enabled) {
+ pm_runtime_get_sync(&host->pdev->dev);
+
+ writel(0, host->base + LCDC_CTRL);
+ mxsfb_set_par(host->fb_info);
mxsfb_enable_controller(fb_info);
+ }
break;
}
return 0;
@@ -591,21 +1112,71 @@ static int mxsfb_blank(int blank, struct fb_info *fb_info)
static int mxsfb_pan_display(struct fb_var_screeninfo *var,
struct fb_info *fb_info)
{
- struct mxsfb_info *host = to_imxfb_host(fb_info);
+ int ret = 0;
+ struct mxsfb_info *host = fb_info->par;
unsigned offset;
- if (var->xoffset != 0)
+ if (host->cur_blank != FB_BLANK_UNBLANK) {
+ dev_dbg(fb_info->device, "can't do pan display when fb "
+ "is blank\n");
return -EINVAL;
+ }
- offset = fb_info->fix.line_length * var->yoffset;
+ if (var->xoffset > 0) {
+ dev_dbg(fb_info->device, "x panning not supported\n");
+ return -EINVAL;
+ }
- mxsfb_enable_axi_clk(host);
+ if ((var->yoffset + var->yres > var->yres_virtual)) {
+ dev_err(fb_info->device, "y panning exceeds\n");
+ return -EINVAL;
+ }
+
+ init_completion(&host->flip_complete);
+
+ offset = fb_info->fix.line_length * var->yoffset;
/* update on next VSYNC */
writel(fb_info->fix.smem_start + offset,
host->base + host->devdata->next_buf);
- mxsfb_disable_axi_clk(host);
+ writel(CTRL1_CUR_FRAME_DONE_IRQ_EN,
+ host->base + LCDC_CTRL1 + REG_SET);
+
+ ret = wait_for_completion_timeout(&host->flip_complete, HZ / 2);
+ if (!ret) {
+ dev_err(fb_info->device,
+ "mxs wait for pan flip timeout\n");
+ return -ETIMEDOUT;
+ }
+
+ return 0;
+}
+
+static int mxsfb_mmap(struct fb_info *info, struct vm_area_struct *vma)
+{
+ u32 len;
+ unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
+
+ if (offset < info->fix.smem_len) {
+ /* mapping framebuffer memory */
+ len = info->fix.smem_len - offset;
+ vma->vm_pgoff = (info->fix.smem_start + offset) >> PAGE_SHIFT;
+ } else
+ return -EINVAL;
+
+ len = PAGE_ALIGN(len);
+ if (vma->vm_end - vma->vm_start > len)
+ return -EINVAL;
+
+ /* make buffers bufferable */
+ vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
+
+ if (remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
+ vma->vm_end - vma->vm_start, vma->vm_page_prot)) {
+ dev_dbg(info->device, "mmap remap_pfn_range failed\n");
+ return -ENOBUFS;
+ }
return 0;
}
@@ -615,31 +1186,43 @@ static struct fb_ops mxsfb_ops = {
.fb_check_var = mxsfb_check_var,
.fb_set_par = mxsfb_set_par,
.fb_setcolreg = mxsfb_setcolreg,
+ .fb_ioctl = mxsfb_ioctl,
.fb_blank = mxsfb_blank,
.fb_pan_display = mxsfb_pan_display,
+ .fb_mmap = mxsfb_mmap,
.fb_fillrect = cfb_fillrect,
.fb_copyarea = cfb_copyarea,
.fb_imageblit = cfb_imageblit,
};
-static int mxsfb_restore_mode(struct mxsfb_info *host,
- struct fb_videomode *vmode)
+static int mxsfb_restore_mode(struct mxsfb_info *host)
{
- struct fb_info *fb_info = &host->fb_info;
+ struct fb_info *fb_info = host->fb_info;
unsigned line_count;
unsigned period;
unsigned long pa, fbsize;
- int bits_per_pixel, ofs, ret = 0;
+ int bits_per_pixel, ofs;
u32 transfer_count, vdctrl0, vdctrl2, vdctrl3, vdctrl4, ctrl;
+ struct fb_videomode vmode;
- mxsfb_enable_axi_clk(host);
+ clk_enable_axi(host);
+ clk_enable_disp_axi(host);
+
+#ifndef CONFIG_FB_IMX64_DEBUG
+ /* Enable pixel clock earlier since in 7D
+ * the lcdif registers should be accessed
+ * when the pixel clock is enabled, otherwise
+ * the bus will be hang.
+ */
+ clk_enable_pix(host);
+#endif
/* Only restore the mode when the controller is running */
ctrl = readl(host->base + LCDC_CTRL);
- if (!(ctrl & CTRL_RUN)) {
- ret = -EINVAL;
- goto err;
- }
+ if (!(ctrl & CTRL_RUN))
+ return -EINVAL;
+
+ memset(&vmode, 0, sizeof(vmode));
vdctrl0 = readl(host->base + LCDC_VDCTRL0);
vdctrl2 = readl(host->base + LCDC_VDCTRL2);
@@ -648,8 +1231,8 @@ static int mxsfb_restore_mode(struct mxsfb_info *host,
transfer_count = readl(host->base + host->devdata->transfer_count);
- vmode->xres = TRANSFER_COUNT_GET_HCOUNT(transfer_count);
- vmode->yres = TRANSFER_COUNT_GET_VCOUNT(transfer_count);
+ vmode.xres = TRANSFER_COUNT_GET_HCOUNT(transfer_count);
+ vmode.yres = TRANSFER_COUNT_GET_VCOUNT(transfer_count);
switch (CTRL_GET_WORD_LENGTH(ctrl)) {
case 0:
@@ -660,53 +1243,51 @@ static int mxsfb_restore_mode(struct mxsfb_info *host,
break;
case 1:
default:
- ret = -EINVAL;
- goto err;
+ return -EINVAL;
}
fb_info->var.bits_per_pixel = bits_per_pixel;
- vmode->pixclock = KHZ2PICOS(clk_get_rate(host->clk) / 1000U);
- vmode->hsync_len = get_hsync_pulse_width(host, vdctrl2);
- vmode->left_margin = GET_HOR_WAIT_CNT(vdctrl3) - vmode->hsync_len;
- vmode->right_margin = VDCTRL2_GET_HSYNC_PERIOD(vdctrl2) -
- vmode->hsync_len - vmode->left_margin - vmode->xres;
- vmode->vsync_len = VDCTRL0_GET_VSYNC_PULSE_WIDTH(vdctrl0);
+ vmode.pixclock = clk_get_rate(host->clk_pix) / 1000U;
+ if (vmode.pixclock)
+ vmode.pixclock = KHZ2PICOS(vmode.pixclock);
+ vmode.hsync_len = get_hsync_pulse_width(host, vdctrl2);
+ vmode.left_margin = GET_HOR_WAIT_CNT(vdctrl3) - vmode.hsync_len;
+ vmode.right_margin = VDCTRL2_GET_HSYNC_PERIOD(vdctrl2) - vmode.hsync_len -
+ vmode.left_margin - vmode.xres;
+ vmode.vsync_len = VDCTRL0_GET_VSYNC_PULSE_WIDTH(vdctrl0);
period = readl(host->base + LCDC_VDCTRL1);
- vmode->upper_margin = GET_VERT_WAIT_CNT(vdctrl3) - vmode->vsync_len;
- vmode->lower_margin = period - vmode->vsync_len -
- vmode->upper_margin - vmode->yres;
+ vmode.upper_margin = GET_VERT_WAIT_CNT(vdctrl3) - vmode.vsync_len;
+ vmode.lower_margin = period - vmode.vsync_len - vmode.upper_margin - vmode.yres;
- vmode->vmode = FB_VMODE_NONINTERLACED;
+ vmode.vmode = FB_VMODE_NONINTERLACED;
- vmode->sync = 0;
+ vmode.sync = 0;
if (vdctrl0 & VDCTRL0_HSYNC_ACT_HIGH)
- vmode->sync |= FB_SYNC_HOR_HIGH_ACT;
+ vmode.sync |= FB_SYNC_HOR_HIGH_ACT;
if (vdctrl0 & VDCTRL0_VSYNC_ACT_HIGH)
- vmode->sync |= FB_SYNC_VERT_HIGH_ACT;
+ vmode.sync |= FB_SYNC_VERT_HIGH_ACT;
pr_debug("Reconstructed video mode:\n");
pr_debug("%dx%d, hsync: %u left: %u, right: %u, vsync: %u, upper: %u, lower: %u\n",
- vmode->xres, vmode->yres, vmode->hsync_len, vmode->left_margin,
- vmode->right_margin, vmode->vsync_len, vmode->upper_margin,
- vmode->lower_margin);
- pr_debug("pixclk: %ldkHz\n", PICOS2KHZ(vmode->pixclock));
+ vmode.xres, vmode.yres,
+ vmode.hsync_len, vmode.left_margin, vmode.right_margin,
+ vmode.vsync_len, vmode.upper_margin, vmode.lower_margin);
+ pr_debug("pixclk: %ldkHz\n", PICOS2KHZ(vmode.pixclock));
+
+ fb_add_videomode(&vmode, &fb_info->modelist);
host->ld_intf_width = CTRL_GET_BUS_WIDTH(ctrl);
host->dotclk_delay = VDCTRL4_GET_DOTCLK_DLY(vdctrl4);
- fb_info->fix.line_length = vmode->xres * (bits_per_pixel >> 3);
+ fb_info->fix.line_length = vmode.xres * (bits_per_pixel >> 3);
pa = readl(host->base + host->devdata->cur_buf);
- fbsize = fb_info->fix.line_length * vmode->yres;
- if (pa < fb_info->fix.smem_start) {
- ret = -EINVAL;
- goto err;
- }
- if (pa + fbsize > fb_info->fix.smem_start + fb_info->fix.smem_len) {
- ret = -EINVAL;
- goto err;
- }
+ fbsize = fb_info->fix.line_length * vmode.yres;
+ if (pa < fb_info->fix.smem_start)
+ return -EINVAL;
+ if (pa + fbsize > fb_info->fix.smem_start + fb_info->fix.smem_len)
+ return -EINVAL;
ofs = pa - fb_info->fix.smem_start;
if (ofs) {
memmove(fb_info->screen_base, fb_info->screen_base + ofs, fbsize);
@@ -715,28 +1296,28 @@ static int mxsfb_restore_mode(struct mxsfb_info *host,
line_count = fb_info->fix.smem_len / fb_info->fix.line_length;
fb_info->fix.ypanstep = 1;
+ fb_info->fix.ywrapstep = 1;
- clk_prepare_enable(host->clk);
host->enabled = 1;
-err:
- if (ret)
- mxsfb_disable_axi_clk(host);
-
- return ret;
+ return 0;
}
-static int mxsfb_init_fbinfo_dt(struct mxsfb_info *host,
- struct fb_videomode *vmode)
+static int mxsfb_init_fbinfo_dt(struct mxsfb_info *host)
{
- struct fb_info *fb_info = &host->fb_info;
+ struct fb_info *fb_info = host->fb_info;
struct fb_var_screeninfo *var = &fb_info->var;
struct device *dev = &host->pdev->dev;
struct device_node *np = host->pdev->dev.of_node;
struct device_node *display_np;
- struct videomode vm;
+ struct device_node *timings_np;
+ struct display_timings *timings = NULL;
+ const char *disp_dev, *disp_videomode;
u32 width;
- int ret;
+ int i;
+ int ret = 0;
+
+ host->id = of_alias_get_id(np, "lcdif");
display_np = of_parse_phandle(np, "display", 0);
if (!display_np) {
@@ -776,77 +1357,216 @@ static int mxsfb_init_fbinfo_dt(struct mxsfb_info *host,
goto put_display_node;
}
- ret = of_get_videomode(display_np, &vm, OF_USE_NATIVE_MODE);
- if (ret) {
- dev_err(dev, "failed to get videomode from DT\n");
+ ret = of_property_read_string(np, "disp-dev", &disp_dev);
+ if (!ret) {
+ memcpy(host->disp_dev, disp_dev, strlen(disp_dev));
+
+ if (!of_property_read_string(np, "disp-videomode",
+ &disp_videomode)) {
+ memcpy(host->disp_videomode, disp_videomode,
+ strlen(disp_videomode));
+ }
+
+ /* Timing is from encoder driver */
+ goto put_display_node;
+ }
+
+ timings = of_get_display_timings(display_np);
+ if (!timings) {
+ dev_err(dev, "failed to get display timings\n");
+ ret = -ENOENT;
goto put_display_node;
}
- ret = fb_videomode_from_videomode(&vm, vmode);
- if (ret < 0)
+ timings_np = of_find_node_by_name(display_np,
+ "display-timings");
+ if (!timings_np) {
+ dev_err(dev, "failed to find display-timings node\n");
+ ret = -ENOENT;
goto put_display_node;
+ }
- if (vm.flags & DISPLAY_FLAGS_DE_HIGH)
- host->sync |= MXSFB_SYNC_DATA_ENABLE_HIGH_ACT;
- if (vm.flags & DISPLAY_FLAGS_PIXDATA_NEGEDGE)
- host->sync |= MXSFB_SYNC_DOTCLK_FALLING_ACT;
+ for (i = 0; i < of_get_child_count(timings_np); i++) {
+ struct videomode vm;
+ struct fb_videomode fb_vm;
+
+ ret = videomode_from_timings(timings, &vm, i);
+ if (ret < 0)
+ goto put_timings_node;
+ ret = fb_videomode_from_videomode(&vm, &fb_vm);
+ if (ret < 0)
+ goto put_timings_node;
+
+ if (!(vm.flags & DISPLAY_FLAGS_DE_HIGH))
+ fb_vm.sync |= FB_SYNC_OE_LOW_ACT;
+ if (vm.flags & DISPLAY_FLAGS_PIXDATA_NEGEDGE)
+ fb_vm.sync |= FB_SYNC_CLK_LAT_FALL;
+ fb_add_videomode(&fb_vm, &fb_info->modelist);
+ }
+put_timings_node:
+ of_node_put(timings_np);
put_display_node:
+ if (timings)
+ kfree(timings);
of_node_put(display_np);
return ret;
}
-static int mxsfb_init_fbinfo(struct mxsfb_info *host,
- struct fb_videomode *vmode)
+static int mxsfb_init_fbinfo(struct mxsfb_info *host)
{
int ret;
- struct device *dev = &host->pdev->dev;
- struct fb_info *fb_info = &host->fb_info;
+ struct fb_info *fb_info = host->fb_info;
struct fb_var_screeninfo *var = &fb_info->var;
- dma_addr_t fb_phys;
- void *fb_virt;
- unsigned fb_size;
+ struct fb_modelist *modelist;
fb_info->fbops = &mxsfb_ops;
fb_info->flags = FBINFO_FLAG_DEFAULT | FBINFO_READS_FAST;
- strlcpy(fb_info->fix.id, "mxs", sizeof(fb_info->fix.id));
fb_info->fix.type = FB_TYPE_PACKED_PIXELS;
fb_info->fix.ypanstep = 1;
+ fb_info->fix.ywrapstep = 1;
fb_info->fix.visual = FB_VISUAL_TRUECOLOR,
fb_info->fix.accel = FB_ACCEL_NONE;
- ret = mxsfb_init_fbinfo_dt(host, vmode);
+ ret = mxsfb_init_fbinfo_dt(host);
if (ret)
return ret;
+ if (host->id < 0)
+ sprintf(fb_info->fix.id, "mxs-lcdif");
+ else
+ sprintf(fb_info->fix.id, "mxs-lcdif%d", host->id);
+
+ if (!list_empty(&fb_info->modelist)) {
+ /* first video mode in the modelist as default video mode */
+ modelist = list_first_entry(&fb_info->modelist,
+ struct fb_modelist, list);
+ fb_videomode_to_var(var, &modelist->mode);
+ }
+ /* save the sync value getting from dtb */
+ host->sync = fb_info->var.sync;
+
var->nonstd = 0;
var->activate = FB_ACTIVATE_NOW;
var->accel_flags = 0;
var->vmode = FB_VMODE_NONINTERLACED;
+ /* init the color fields */
+ mxsfb_check_var(var, fb_info);
+
+ fb_info->fix.line_length =
+ fb_info->var.xres * (fb_info->var.bits_per_pixel >> 3);
+ fb_info->fix.smem_len = SZ_32M;
+
/* Memory allocation for framebuffer */
- fb_size = SZ_2M;
- fb_virt = dma_alloc_wc(dev, PAGE_ALIGN(fb_size), &fb_phys, GFP_KERNEL);
- if (!fb_virt)
+ if (mxsfb_map_videomem(fb_info) < 0)
return -ENOMEM;
- fb_info->fix.smem_start = fb_phys;
- fb_info->screen_base = fb_virt;
- fb_info->screen_size = fb_info->fix.smem_len = fb_size;
+ if (mxsfb_restore_mode(host))
+ memset((char *)fb_info->screen_base, 0, fb_info->fix.smem_len);
- if (mxsfb_restore_mode(host, vmode))
- memset(fb_virt, 0, fb_size);
+ return 0;
+}
+
+static int mxsfb_dispdrv_init(struct platform_device *pdev,
+ struct fb_info *fbi)
+{
+ struct mxsfb_info *host = fbi->par;
+ struct mxc_dispdrv_setting setting;
+ struct device *dev = &pdev->dev;
+ char disp_dev[32];
+
+ if (!strlen(host->disp_dev))
+ return 0;
+
+ memset(&setting, 0x0, sizeof(setting));
+ setting.fbi = fbi;
+ memcpy(disp_dev, host->disp_dev, strlen(host->disp_dev));
+ disp_dev[strlen(host->disp_dev)] = '\0';
+
+ /* Use videomode name from dtb, if any given */
+ if (host->disp_videomode[0]) {
+ setting.dft_mode_str = kmalloc(NAME_LEN, GFP_KERNEL);
+ if (setting.dft_mode_str) {
+ memset(setting.dft_mode_str, 0x0, NAME_LEN);
+ memcpy(setting.dft_mode_str, host->disp_videomode,
+ strlen(host->disp_videomode));
+ }
+ }
+
+ host->dispdrv = mxc_dispdrv_gethandle(disp_dev, &setting);
+
+ kfree(setting.dft_mode_str);
+
+ if (IS_ERR(host->dispdrv))
+ return -EPROBE_DEFER;
+ else
+ dev_info(dev, "registered mxc display driver %s\n",
+ disp_dev);
return 0;
}
static void mxsfb_free_videomem(struct mxsfb_info *host)
{
- struct device *dev = &host->pdev->dev;
- struct fb_info *fb_info = &host->fb_info;
+ struct fb_info *fb_info = host->fb_info;
+
+ mxsfb_unmap_videomem(fb_info);
+}
+
+/*!
+ * Allocates the DRAM memory for the frame buffer. This buffer is remapped
+ * into a non-cached, non-buffered, memory region to allow palette and pixel
+ * writes to occur without flushing the cache. Once this area is remapped,
+ * all virtual memory access to the video memory should occur at the new region.
+ *
+ * @param fbi framebuffer information pointer
+ *
+ * @return Error code indicating success or failure
+ */
+static int mxsfb_map_videomem(struct fb_info *fbi)
+{
+ if (fbi->fix.smem_len < fbi->var.yres_virtual * fbi->fix.line_length)
+ fbi->fix.smem_len = fbi->var.yres_virtual *
+ fbi->fix.line_length;
+
+ fbi->screen_base = dma_alloc_writecombine(fbi->device,
+ fbi->fix.smem_len,
+ (dma_addr_t *)&fbi->fix.smem_start,
+ GFP_DMA | GFP_KERNEL);
+ if (fbi->screen_base == 0) {
+ dev_err(fbi->device, "Unable to allocate framebuffer memory\n");
+ fbi->fix.smem_len = 0;
+ fbi->fix.smem_start = 0;
+ return -EBUSY;
+ }
+
+ dev_dbg(fbi->device, "allocated fb @ paddr=0x%08X, size=%d.\n",
+ (uint32_t) fbi->fix.smem_start, fbi->fix.smem_len);
- dma_free_wc(dev, fb_info->screen_size, fb_info->screen_base,
- fb_info->fix.smem_start);
+ fbi->screen_size = fbi->fix.smem_len;
+
+ /* Clear the screen */
+ memset((char *)fbi->screen_base, 0, fbi->fix.smem_len);
+
+ return 0;
+}
+
+/*!
+ * De-allocates the DRAM memory for the frame buffer.
+ *
+ * @param fbi framebuffer information pointer
+ *
+ * @return Error code indicating success or failure
+ */
+static int mxsfb_unmap_videomem(struct fb_info *fbi)
+{
+ dma_free_writecombine(fbi->device, fbi->fix.smem_len,
+ fbi->screen_base, fbi->fix.smem_start);
+ fbi->screen_base = 0;
+ fbi->fix.smem_start = 0;
+ fbi->fix.smem_len = 0;
+ return 0;
}
static const struct platform_device_id mxsfb_devtype[] = {
@@ -857,6 +1577,9 @@ static const struct platform_device_id mxsfb_devtype[] = {
.name = "imx28-fb",
.driver_data = MXSFB_V4,
}, {
+ .name = "imx7ulp-fb",
+ .driver_data = MXSFB_V5,
+ }, {
/* sentinel */
}
};
@@ -865,10 +1588,605 @@ MODULE_DEVICE_TABLE(platform, mxsfb_devtype);
static const struct of_device_id mxsfb_dt_ids[] = {
{ .compatible = "fsl,imx23-lcdif", .data = &mxsfb_devtype[0], },
{ .compatible = "fsl,imx28-lcdif", .data = &mxsfb_devtype[1], },
+ { .compatible = "fsl,imx7ulp-lcdif", .data = &mxsfb_devtype[2], },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, mxsfb_dt_ids);
+#ifdef CONFIG_FB_MXC_OVERLAY
+static int overlay_fmt_support(uint32_t fmt)
+{
+ switch (fmt) {
+ case V4L2_PIX_FMT_ARGB32:
+ case V4L2_PIX_FMT_XRGB32:
+ return 32;
+ case V4L2_PIX_FMT_ARGB555:
+ case V4L2_PIX_FMT_ARGB444:
+ case V4L2_PIX_FMT_XRGB555:
+ case V4L2_PIX_FMT_RGB444:
+ case V4L2_PIX_FMT_RGB565:
+ return 16;
+ default:
+ return -EINVAL;
+ }
+}
+
+/* alpha mode */
+#define ALPHA_CTRL_EMBEDDED 0x0
+#define ALPHA_CTRL_OVERRIDE 0x1
+#define ALPHA_CTRL_MULTIPLY 0x2
+#define ALPHA_CTRL_ROPS 0x3
+
+static void overlayfb_enable(struct mxsfb_layer *ofb)
+{
+ struct mxsfb_info *fbi = ofb->fbi;
+
+ if (!lock_fb_info(fbi->fb_info))
+ return;
+
+ if (fbi->cur_blank == FB_BLANK_UNBLANK) {
+ mxsfb_disable_controller(fbi->fb_info);
+ writel(CTRL1_FIFO_CLEAR, fbi->base + LCDC_CTRL1 + REG_SET);
+ }
+
+ writel(0x1, fbi->base + LCDC_AS_CTRL + REG_SET);
+
+ if (fbi->cur_blank == FB_BLANK_UNBLANK) {
+ writel(CTRL1_FIFO_CLEAR, fbi->base + LCDC_CTRL1 + REG_CLR);
+ mxsfb_enable_controller(fbi->fb_info);
+ }
+ unlock_fb_info(fbi->fb_info);
+}
+
+static void overlayfb_disable(struct mxsfb_layer *ofb)
+{
+ struct mxsfb_info *fbi = ofb->fbi;
+
+ writel(0x1, fbi->base + LCDC_AS_CTRL + REG_CLR);
+}
+
+static void overlayfb_setup(struct mxsfb_layer *ofb)
+{
+ uint32_t as_next_buf, as_ctrl = 0;
+ uint8_t format, alpha_ctrl, global_alpha_en = 0;
+ struct mxsfb_info *fbi = ofb->fbi;
+ struct fb_var_screeninfo *var = &ofb->ol_fb->var;
+
+ /* set fb1 framebuffer address */
+ as_next_buf = ofb->video_mem_phys;
+ writel(as_next_buf, fbi->base + LCDC_AS_NEXT_BUF);
+
+ /* clear the LCDC_AS_CTRL */
+ writel(0x0, fbi->base + LCDC_AS_CTRL);
+
+ switch (var->grayscale) {
+ case 0: /* color */
+ switch (var->bits_per_pixel) {
+ case 16: /* RGB565 */
+ format = 0xE;
+ global_alpha_en = 1;
+ break;
+ case 32: /* ARGB8888 */
+ format = 0x0;
+ global_alpha_en = 1;
+ break;
+ default:
+ return;
+ }
+ break;
+ case 1: /* grayscale */
+ return;
+ default:
+ switch (var->grayscale) {
+ case V4L2_PIX_FMT_ARGB32:
+ format = 0x0;
+ break;
+ case V4L2_PIX_FMT_XRGB32:
+ format = 0x4;
+ global_alpha_en = 1;
+ break;
+ case V4L2_PIX_FMT_ARGB555:
+ format = 0x8;
+ break;
+ case V4L2_PIX_FMT_ARGB444:
+ format = 0x9;
+ break;
+ case V4L2_PIX_FMT_RGB555:
+ format = 0xC;
+ global_alpha_en = 1;
+ break;
+ case V4L2_PIX_FMT_RGB444:
+ format = 0xD;
+ global_alpha_en = 1;
+ break;
+ case V4L2_PIX_FMT_RGB565:
+ format = 0xE;
+ global_alpha_en = 1;
+ break;
+ default:
+ return;
+ }
+ break;
+ }
+ as_ctrl |= ((format & 0xf) << 4);
+
+ alpha_ctrl = global_alpha_en ? ALPHA_CTRL_OVERRIDE :
+ ALPHA_CTRL_EMBEDDED;
+ as_ctrl |= ((alpha_ctrl & 0x3) << 1);
+ if (global_alpha_en)
+ as_ctrl |= ((ofb->global_alpha & 0xff) << 8);
+
+ writel(as_ctrl, fbi->base + LCDC_AS_CTRL);
+}
+
+static struct mxsfb_layer_ops ofb_ops = {
+ .enable = overlayfb_enable,
+ .disable = overlayfb_disable,
+ .setup = overlayfb_setup,
+};
+
+static int overlayfb_open(struct fb_info *info, int user)
+{
+ struct mxsfb_layer *ofb = (struct mxsfb_layer*)info->par;
+ struct mxsfb_info *fbi = ofb->fbi;
+
+ if (atomic_inc_return(&ofb->usage) == 1) {
+ ofb->ol_fb->var.xres = fbi->fb_info->var.xres;
+ ofb->ol_fb->var.yres = fbi->fb_info->var.yres;
+ ofb->ol_fb->var.xres_virtual = fbi->fb_info->var.xres_virtual;
+ ofb->ol_fb->var.yres_virtual = fbi->fb_info->var.yres;
+ ofb->ol_fb->var.bits_per_pixel = fbi->fb_info->var.bits_per_pixel;
+ ofb->ol_fb->var.vmode = FB_VMODE_NONINTERLACED;
+ }
+
+ return 0;
+}
+
+static int overlayfb_release(struct fb_info *info, int user)
+{
+ struct mxsfb_layer *ofb = (struct mxsfb_layer*)info->par;
+
+ BUG_ON(!atomic_read(&ofb->usage));
+
+ if (atomic_dec_return(&ofb->usage) == 0) {
+ if (ofb->blank_state == FB_BLANK_UNBLANK)
+ ofb->ops->disable(ofb);
+
+ ofb->blank_state = -1;
+ }
+
+ return 0;
+}
+
+static void fill_fmt_bitfields(struct fb_var_screeninfo *var,
+ const struct fb_bitfield *color)
+{
+ var->red = color[RED];
+ var->green = color[GREEN];
+ var->blue = color[BLUE];
+ var->transp = color[TRANSP];
+}
+
+static int overlayfb_check_var(struct fb_var_screeninfo *var,
+ struct fb_info *info)
+{
+ int bpp;
+ struct mxsfb_layer *ofb = (struct mxsfb_layer*)info->par;
+ struct mxsfb_info *fbi = ofb->fbi;
+ const struct fb_bitfield *rgb = NULL;
+
+ /* lcdif doesn't support different bpp of AS and PS */
+ if (var->bits_per_pixel != fbi->fb_info->var.bits_per_pixel)
+ return -EINVAL;
+
+ /* overlay width & should be equal to fb0 */
+ if ((var->xres != fbi->fb_info->var.xres) ||
+ (var->yres != fbi->fb_info->var.yres))
+ return -EINVAL;
+
+ if ((var->xres > 2048) || (var->yres > 2048))
+ return -EINVAL;
+
+ if (var->xres_virtual > var->xres)
+ return -EINVAL;
+
+ if (var->xres_virtual < var->xres)
+ var->xres_virtual = var->xres;
+ if (var->yres_virtual < var->yres)
+ var->yres_virtual = var->yres;
+
+ switch (var->grayscale) {
+ case 0: /* color */
+ switch (var->bits_per_pixel) {
+ case 16:/* RGB565 */
+ rgb = def_rgb565;
+ break;
+ case 32:/* ARGB8888 */
+ rgb = def_argb32;
+ break;
+ default:
+ return -EINVAL;
+ }
+ break;
+ case 1: /* grayscale */
+ return -EINVAL;
+ default: /* fourcc */
+ if ((bpp = overlay_fmt_support(var->grayscale)) < 0) {
+ dev_err(info->dev, "unsupport pixel format for overlay\n");
+ return -EINVAL;
+ }
+
+ var->bits_per_pixel = bpp;
+ if (var->bits_per_pixel < 16)
+ return -EINVAL;
+
+ switch (var->grayscale) {
+ case V4L2_PIX_FMT_ARGB32:
+ rgb = def_argb32;
+ break;
+ case V4L2_PIX_FMT_XRGB32:
+ rgb = def_rgb888;
+ break;
+ case V4L2_PIX_FMT_ARGB555:
+ rgb = def_argb555;
+ break;
+ case V4L2_PIX_FMT_ARGB444:
+ rgb = def_argb444;
+ break;
+ case V4L2_PIX_FMT_RGB555:
+ rgb = def_rgb555;
+ break;
+ case V4L2_PIX_FMT_RGB444:
+ rgb = def_rgb444;
+ break;
+ case V4L2_PIX_FMT_RGB565:
+ rgb = def_rgb565;
+ break;
+ default:
+ /*
+ * This should never be reached since the verification
+ * is done in overlay_fmt_support(), but handle this in
+ * case there will be a sync error between formats
+ * supported in fmt_support and this function.
+ */
+ return -EINVAL;
+ }
+ break;
+ }
+
+ if (var->xres_virtual * var->yres_virtual * var->bits_per_pixel / 8 >
+ info->fix.smem_len)
+ return -EINVAL;
+
+ fill_fmt_bitfields(var, rgb);
+
+ return 0;
+}
+
+static int overlayfb_set_par(struct fb_info *info)
+{
+ int size, bpp;
+ struct mxsfb_layer *ofb = (struct mxsfb_layer*)info->par;
+ struct mxsfb_info *fbi = ofb->fbi;
+ struct fb_var_screeninfo *var = &ofb->ol_fb->var;
+
+ bpp = var->bits_per_pixel;
+ ofb->ol_fb->fix.line_length = var->xres_virtual * bpp / 8;
+
+ size = PAGE_ALIGN(ofb->ol_fb->fix.line_length * var->yres_virtual);
+ if (ofb->video_mem_size < size)
+ return -EINVAL;
+
+ if (!lock_fb_info(fbi->fb_info))
+ return -EINVAL;
+
+ if (fbi->cur_blank != FB_BLANK_UNBLANK) {
+ clk_enable_pix(fbi);
+ clk_enable_axi(fbi);
+ clk_enable_disp_axi(fbi);
+ }
+ unlock_fb_info(fbi->fb_info);
+
+ if (ofb->blank_state == FB_BLANK_UNBLANK)
+ ofb->ops->disable(ofb);
+
+ ofb->ops->setup(ofb);
+
+ if (ofb->blank_state == FB_BLANK_UNBLANK)
+ ofb->ops->enable(ofb);
+
+ if (!lock_fb_info(fbi->fb_info))
+ return -EINVAL;
+
+ if (fbi->cur_blank != FB_BLANK_UNBLANK) {
+ clk_disable_disp_axi(fbi);
+ clk_disable_axi(fbi);
+ clk_disable_pix(fbi);
+ }
+ unlock_fb_info(fbi->fb_info);
+
+ if ((var->activate & FB_ACTIVATE_FORCE) &&
+ (var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW)
+ var->activate = FB_ACTIVATE_NOW;
+
+ return 0;
+}
+
+static int overlayfb_blank(int blank, struct fb_info *info)
+{
+ struct mxsfb_layer *ofb = (struct mxsfb_layer*)info->par;
+ struct mxsfb_info *fbi = ofb->fbi;
+
+ if (ofb->blank_state == blank)
+ return 0;
+
+ if (!lock_fb_info(fbi->fb_info))
+ return -EINVAL;
+
+ if (fbi->cur_blank != FB_BLANK_UNBLANK) {
+ clk_enable_pix(fbi);
+ clk_enable_axi(fbi);
+ clk_enable_disp_axi(fbi);
+ }
+ unlock_fb_info(fbi->fb_info);
+
+ switch (blank) {
+ case FB_BLANK_POWERDOWN:
+ case FB_BLANK_VSYNC_SUSPEND:
+ case FB_BLANK_HSYNC_SUSPEND:
+ case FB_BLANK_NORMAL:
+ ofb->ops->disable(ofb);
+ break;
+ case FB_BLANK_UNBLANK:
+ ofb->ops->enable(ofb);
+ break;
+ }
+
+ if (!lock_fb_info(fbi->fb_info))
+ return -EINVAL;
+
+ if (fbi->cur_blank != FB_BLANK_UNBLANK) {
+ clk_disable_disp_axi(fbi);
+ clk_disable_axi(fbi);
+ clk_disable_pix(fbi);
+ }
+ unlock_fb_info(fbi->fb_info);
+
+ ofb->blank_state = blank;
+
+ return 0;
+}
+
+static int overlayfb_pan_display(struct fb_var_screeninfo *var,
+ struct fb_info *info)
+{
+ int ret = 0;
+ unsigned int bytes_offset;
+ struct mxsfb_layer *ofb = (struct mxsfb_layer *)info->par;
+ struct mxsfb_info *fbi = ofb->fbi;
+
+ init_completion(&fbi->flip_complete);
+
+ if (!lock_fb_info(fbi->fb_info))
+ return -EINVAL;
+
+ if (fbi->cur_blank != FB_BLANK_UNBLANK) {
+ unlock_fb_info(fbi->fb_info);
+ return -EINVAL;
+ }
+
+ unlock_fb_info(fbi->fb_info);
+
+ bytes_offset = info->fix.line_length * var->yoffset;
+ writel(info->fix.smem_start + bytes_offset,
+ fbi->base + LCDC_AS_NEXT_BUF);
+
+ /* update on next VSYNC */
+ writel(CTRL1_CUR_FRAME_DONE_IRQ_EN,
+ fbi->base + LCDC_CTRL1 + REG_SET);
+
+ ret = wait_for_completion_timeout(&fbi->flip_complete, HZ / 2);
+ if (!ret) {
+ dev_err(info->device,
+ "overlay wait for pane flip timeout\n");
+ return -ETIMEDOUT;
+ }
+
+ return 0;
+}
+
+static struct fb_ops overlay_fb_ops = {
+ .owner = THIS_MODULE,
+ .fb_open = overlayfb_open,
+ .fb_release = overlayfb_release,
+ .fb_check_var = overlayfb_check_var,
+ .fb_set_par = overlayfb_set_par,
+ .fb_blank = overlayfb_blank,
+ .fb_pan_display = overlayfb_pan_display,
+ .fb_mmap = mxsfb_mmap,
+};
+
+static void init_mxsfb_overlay(struct mxsfb_info *fbi,
+ struct mxsfb_layer *ofb)
+{
+ dev_dbg(&fbi->pdev->dev, "AS overlay init\n");
+
+ ofb->ol_fb->fix.type = FB_TYPE_PACKED_PIXELS;
+ ofb->ol_fb->fix.xpanstep = 0;
+ ofb->ol_fb->fix.ypanstep = 1;
+ ofb->ol_fb->fix.ywrapstep = 1;
+ ofb->ol_fb->fix.visual = FB_VISUAL_TRUECOLOR;
+ ofb->ol_fb->fix.accel = FB_ACCEL_NONE;
+
+ ofb->ol_fb->var.activate = FB_ACTIVATE_NXTOPEN;
+ ofb->ol_fb->var.xres = fbi->fb_info->var.xres;
+ ofb->ol_fb->var.yres = fbi->fb_info->var.yres;
+ ofb->ol_fb->var.xres_virtual = fbi->fb_info->var.xres_virtual;
+ ofb->ol_fb->var.yres_virtual = fbi->fb_info->var.yres;
+ ofb->ol_fb->var.bits_per_pixel = fbi->fb_info->var.bits_per_pixel;
+ ofb->ol_fb->var.vmode = FB_VMODE_NONINTERLACED;
+ ofb->ol_fb->var.nonstd = 0;
+
+ /* Copy timings of primary fb */
+ ofb->ol_fb->var.pixclock = fbi->fb_info->var.pixclock;
+ ofb->ol_fb->var.left_margin = fbi->fb_info->var.left_margin;
+ ofb->ol_fb->var.right_margin = fbi->fb_info->var.right_margin;
+ ofb->ol_fb->var.upper_margin = fbi->fb_info->var.upper_margin;
+ ofb->ol_fb->var.lower_margin = fbi->fb_info->var.lower_margin;
+ ofb->ol_fb->var.hsync_len = fbi->fb_info->var.hsync_len;
+ ofb->ol_fb->var.vsync_len = fbi->fb_info->var.vsync_len;
+
+ ofb->ol_fb->fbops = &overlay_fb_ops;
+ ofb->ol_fb->node = -1;
+ ofb->ol_fb->par = ofb;
+ INIT_LIST_HEAD(&ofb->ol_fb->modelist);
+
+ ofb->id = 0;
+ ofb->ops = &ofb_ops;
+ atomic_set(&ofb->usage, 0);
+ ofb->blank_state = -1;
+ ofb->global_alpha = 255;
+ ofb->fbi = fbi;
+
+ sprintf(ofb->ol_fb->fix.id, "FG");
+}
+
+static int mxsfb_overlay_map_video_memory(struct mxsfb_info *fbi,
+ struct mxsfb_layer *ofb)
+{
+ struct fb_info *fb = fbi->fb_info;
+ BUG_ON(!fb->fix.smem_len);
+
+ ofb->video_mem_size = fb->fix.smem_len;
+ ofb->video_mem = dma_alloc_writecombine(ofb->dev,
+ ofb->video_mem_size,
+ (dma_addr_t *)&ofb->video_mem_phys,
+ GFP_DMA | GFP_KERNEL);
+
+ if (ofb->video_mem == NULL) {
+ dev_err(ofb->dev, "Unable to allocate overlay fb memory\n");
+ return -ENOMEM;
+ }
+
+ /* clear overlay fb memory buffer */
+ memset(ofb->video_mem, 0x0, ofb->video_mem_size);
+
+ ofb->ol_fb->fix.smem_start = ofb->video_mem_phys;
+ ofb->ol_fb->fix.smem_len = ofb->video_mem_size;
+ ofb->ol_fb->screen_base = ofb->video_mem;
+
+ return 0;
+}
+
+static void mxsfb_overlay_init(struct mxsfb_info *fbi)
+{
+ int ret;
+ struct mxsfb_layer *ofb = &fbi->overlay;
+ struct fb_videomode ofb_vm;
+
+ ofb->dev = &fbi->pdev->dev;
+ ofb->ol_fb = framebuffer_alloc(0, ofb->dev);
+ if (!ofb->ol_fb) {
+ dev_err(ofb->dev, "Faild to allocate overlay fbinfo\n");
+ return;
+ }
+
+ init_mxsfb_overlay(fbi, ofb);
+
+ /* add videomode to overlay fb */
+ fb_var_to_videomode(&ofb_vm, &fbi->fb_info->var);
+ ret = fb_add_videomode(&ofb_vm, &ofb->ol_fb->modelist);
+ if (ret) {
+ dev_err(ofb->dev, "add vm to ofb failed\n");
+ goto fb_release;
+ }
+
+ ret = register_framebuffer(ofb->ol_fb);
+ if (ret) {
+ dev_err(ofb->dev, "failed to register overlay\n");
+ goto fb_release;
+ }
+
+ ret = mxsfb_overlay_map_video_memory(fbi, ofb);
+ if (ret) {
+ dev_err(ofb->dev, "failed to map video mem for overlay\n");
+ goto fb_unregister;
+ }
+
+ /* setup the initial params for overlay fb */
+ overlayfb_check_var(&ofb->ol_fb->var, ofb->ol_fb);
+ overlayfb_set_par(ofb->ol_fb);
+
+ ofb->registered = 1;
+
+ return;
+
+fb_unregister:
+ unregister_framebuffer(ofb->ol_fb);
+fb_release:
+ framebuffer_release(ofb->ol_fb);
+}
+
+static void mxsfb_overlay_exit(struct mxsfb_info *fbi)
+{
+ struct mxsfb_layer *ofb = &fbi->overlay;
+
+ if (ofb->registered) {
+ if (ofb->video_mem)
+ dma_free_writecombine(ofb->dev, ofb->video_mem_size,
+ ofb->video_mem, ofb->video_mem_phys);
+
+ unregister_framebuffer(ofb->ol_fb);
+ framebuffer_release(ofb->ol_fb);
+ }
+}
+
+static void mxsfb_overlay_resume(struct mxsfb_info *fbi)
+{
+ if (fbi->cur_blank != FB_BLANK_UNBLANK) {
+ clk_enable_pix(fbi);
+ clk_enable_axi(fbi);
+ clk_enable_disp_axi(fbi);
+ }
+
+ /* Pull LCDIF out of reset */
+ writel(0xc0000000, fbi->base + LCDC_CTRL + REG_CLR);
+
+ writel(saved_as_ctrl, fbi->base + LCDC_AS_CTRL);
+ writel(saved_as_next_buf, fbi->base + LCDC_AS_NEXT_BUF);
+
+ if (fbi->cur_blank != FB_BLANK_UNBLANK) {
+ clk_disable_disp_axi(fbi);
+ clk_disable_axi(fbi);
+ clk_disable_pix(fbi);
+ }
+
+}
+
+static void mxsfb_overlay_suspend(struct mxsfb_info *fbi)
+{
+ if (fbi->cur_blank != FB_BLANK_UNBLANK) {
+ clk_enable_pix(fbi);
+ clk_enable_axi(fbi);
+ clk_enable_disp_axi(fbi);
+ }
+
+ saved_as_ctrl = readl(fbi->base + LCDC_AS_CTRL);
+ saved_as_next_buf = readl(fbi->base + LCDC_AS_NEXT_BUF);
+
+ if (fbi->cur_blank != FB_BLANK_UNBLANK) {
+ clk_disable_disp_axi(fbi);
+ clk_disable_axi(fbi);
+ clk_disable_pix(fbi);
+ }
+}
+#else
+static void mxsfb_overlay_init(struct mxsfb_info *fbi) {}
+static void mxsfb_overlay_exit(struct mxsfb_info *fbi) {}
+static void mxsfb_overlay_resume(struct mxsfb_info *fbi) {}
+static void mxsfb_overlay_suspend(struct mxsfb_info *fbi) {}
+#endif
+
static int mxsfb_probe(struct platform_device *pdev)
{
const struct of_device_id *of_id =
@@ -876,28 +2194,58 @@ static int mxsfb_probe(struct platform_device *pdev)
struct resource *res;
struct mxsfb_info *host;
struct fb_info *fb_info;
- struct fb_videomode *mode;
- int ret;
+ struct pinctrl *pinctrl;
+ int irq = platform_get_irq(pdev, 0);
+ int gpio, ret;
if (of_id)
pdev->id_entry = of_id->data;
- fb_info = framebuffer_alloc(sizeof(struct mxsfb_info), &pdev->dev);
- if (!fb_info) {
- dev_err(&pdev->dev, "Failed to allocate fbdev\n");
+ gpio = of_get_named_gpio(pdev->dev.of_node, "enable-gpio", 0);
+ if (gpio == -EPROBE_DEFER)
+ return -EPROBE_DEFER;
+
+ if (gpio_is_valid(gpio)) {
+ ret = devm_gpio_request_one(&pdev->dev, gpio, GPIOF_OUT_INIT_LOW, "lcd_pwr_en");
+ if (ret) {
+ dev_err(&pdev->dev, "faild to request gpio %d, ret = %d\n", gpio, ret);
+ return ret;
+ }
+ }
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ dev_err(&pdev->dev, "Cannot get memory IO resource\n");
+ return -ENODEV;
+ }
+
+ host = devm_kzalloc(&pdev->dev, sizeof(struct mxsfb_info), GFP_KERNEL);
+ if (!host) {
+ dev_err(&pdev->dev, "Failed to allocate IO resource\n");
return -ENOMEM;
}
- mode = devm_kzalloc(&pdev->dev, sizeof(struct fb_videomode),
- GFP_KERNEL);
- if (mode == NULL)
+ fb_info = framebuffer_alloc(0, &pdev->dev);
+ if (!fb_info) {
+ dev_err(&pdev->dev, "Failed to allocate fbdev\n");
+ devm_kfree(&pdev->dev, host);
return -ENOMEM;
+ }
+ host->fb_info = fb_info;
+ fb_info->par = host;
- host = to_imxfb_host(fb_info);
+ ret = devm_request_irq(&pdev->dev, irq, mxsfb_irq_handler, 0,
+ dev_name(&pdev->dev), host);
+ if (ret) {
+ dev_err(&pdev->dev, "request_irq (%d) failed with error %d\n",
+ irq, ret);
+ ret = -ENODEV;
+ goto fb_release;
+ }
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
host->base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(host->base)) {
+ dev_err(&pdev->dev, "ioremap failed\n");
ret = PTR_ERR(host->base);
goto fb_release;
}
@@ -907,19 +2255,28 @@ static int mxsfb_probe(struct platform_device *pdev)
host->devdata = &mxsfb_devdata[pdev->id_entry->driver_data];
- host->clk = devm_clk_get(&host->pdev->dev, NULL);
- if (IS_ERR(host->clk)) {
- ret = PTR_ERR(host->clk);
+ host->clk_pix = devm_clk_get(&host->pdev->dev, "pix");
+ if (IS_ERR(host->clk_pix)) {
+ host->clk_pix = NULL;
+ ret = PTR_ERR(host->clk_pix);
goto fb_release;
}
host->clk_axi = devm_clk_get(&host->pdev->dev, "axi");
- if (IS_ERR(host->clk_axi))
+ if (IS_ERR(host->clk_axi)) {
host->clk_axi = NULL;
+ ret = PTR_ERR(host->clk_axi);
+ dev_err(&pdev->dev, "Failed to get axi clock: %d\n", ret);
+ goto fb_release;
+ }
host->clk_disp_axi = devm_clk_get(&host->pdev->dev, "disp_axi");
- if (IS_ERR(host->clk_disp_axi))
+ if (IS_ERR(host->clk_disp_axi)) {
host->clk_disp_axi = NULL;
+ ret = PTR_ERR(host->clk_disp_axi);
+ dev_err(&pdev->dev, "Failed to get disp_axi clock: %d\n", ret);
+ goto fb_release;
+ }
host->reg_lcd = devm_regulator_get(&pdev->dev, "lcd");
if (IS_ERR(host->reg_lcd))
@@ -929,79 +2286,205 @@ static int mxsfb_probe(struct platform_device *pdev)
GFP_KERNEL);
if (!fb_info->pseudo_palette) {
ret = -ENOMEM;
+ dev_err(&pdev->dev, "Failed to allocate pseudo_palette memory\n");
goto fb_release;
}
- ret = mxsfb_init_fbinfo(host, mode);
- if (ret != 0)
- goto fb_release;
-
- fb_videomode_to_var(&fb_info->var, mode);
+ INIT_LIST_HEAD(&fb_info->modelist);
- /* init the color fields */
- mxsfb_check_var(&fb_info->var, fb_info);
+ pm_runtime_enable(&host->pdev->dev);
- platform_set_drvdata(pdev, fb_info);
+ ret = mxsfb_init_fbinfo(host);
+ if (ret != 0) {
+ dev_err(&pdev->dev, "Failed to initialize fbinfo: %d\n", ret);
+ goto fb_pm_runtime_disable;
+ }
- ret = register_framebuffer(fb_info);
+ ret = mxsfb_dispdrv_init(pdev, fb_info);
if (ret != 0) {
- dev_err(&pdev->dev,"Failed to register framebuffer\n");
- goto fb_destroy;
+ if (ret == -EPROBE_DEFER)
+ dev_info(&pdev->dev,
+ "Defer fb probe due to dispdrv not ready\n");
+ goto fb_free_videomem;
+ }
+
+ if (!host->dispdrv) {
+ pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
+ if (IS_ERR(pinctrl)) {
+ ret = PTR_ERR(pinctrl);
+ goto fb_pm_runtime_disable;
+ }
}
if (!host->enabled) {
- mxsfb_enable_axi_clk(host);
writel(0, host->base + LCDC_CTRL);
- mxsfb_disable_axi_clk(host);
mxsfb_set_par(fb_info);
mxsfb_enable_controller(fb_info);
+ pm_runtime_get_sync(&host->pdev->dev);
+ }
+
+ ret = register_framebuffer(fb_info);
+ if (ret != 0) {
+ dev_err(&pdev->dev, "Failed to register framebuffer\n");
+ goto fb_destroy;
+ }
+
+ mxsfb_overlay_init(host);
+
+#ifndef CONFIG_FB_IMX64_DEBUG
+ console_lock();
+ ret = fb_blank(fb_info, FB_BLANK_UNBLANK);
+ console_unlock();
+ if (ret < 0) {
+ dev_err(&pdev->dev, "Failed to unblank framebuffer\n");
+ goto fb_unregister;
}
+#endif
dev_info(&pdev->dev, "initialized\n");
return 0;
+#ifndef CONFIG_FB_IMX64_DEBUG
+fb_unregister:
+ unregister_framebuffer(fb_info);
+#endif
fb_destroy:
- if (host->enabled)
- clk_disable_unprepare(host->clk);
+ fb_destroy_modelist(&fb_info->modelist);
+fb_free_videomem:
+ mxsfb_free_videomem(host);
+fb_pm_runtime_disable:
+ clk_disable_pix(host);
+ clk_disable_axi(host);
+ clk_disable_disp_axi(host);
+
+ pm_runtime_disable(&host->pdev->dev);
+ devm_kfree(&pdev->dev, fb_info->pseudo_palette);
fb_release:
framebuffer_release(fb_info);
+ devm_kfree(&pdev->dev, host);
return ret;
}
static int mxsfb_remove(struct platform_device *pdev)
{
- struct fb_info *fb_info = platform_get_drvdata(pdev);
- struct mxsfb_info *host = to_imxfb_host(fb_info);
+ struct mxsfb_info *host = platform_get_drvdata(pdev);
+ struct fb_info *fb_info = host->fb_info;
if (host->enabled)
mxsfb_disable_controller(fb_info);
+ if (host->devdata->flags & MXSFB_FLAG_PMQOS)
+ pm_qos_remove_request(&host->pm_qos_req);
+
+ pm_runtime_disable(&host->pdev->dev);
+ mxsfb_overlay_exit(host);
unregister_framebuffer(fb_info);
mxsfb_free_videomem(host);
+ platform_set_drvdata(pdev, NULL);
+
+ devm_kfree(&pdev->dev, fb_info->pseudo_palette);
framebuffer_release(fb_info);
+ devm_kfree(&pdev->dev, host);
return 0;
}
static void mxsfb_shutdown(struct platform_device *pdev)
{
- struct fb_info *fb_info = platform_get_drvdata(pdev);
- struct mxsfb_info *host = to_imxfb_host(fb_info);
-
- mxsfb_enable_axi_clk(host);
+ struct mxsfb_info *host = platform_get_drvdata(pdev);
/*
* Force stop the LCD controller as keeping it running during reboot
* might interfere with the BootROM's boot mode pads sampling.
*/
- writel(CTRL_RUN, host->base + LCDC_CTRL + REG_CLR);
+ if (host->cur_blank == FB_BLANK_UNBLANK) {
+ writel(CTRL_RUN, host->base + LCDC_CTRL + REG_CLR);
+ writel(CTRL_MASTER, host->base + LCDC_CTRL + REG_CLR);
+ }
+}
+
+#ifdef CONFIG_PM
+static int mxsfb_runtime_suspend(struct device *dev)
+{
+ struct mxsfb_info *host = dev_get_drvdata(dev);
- mxsfb_disable_axi_clk(host);
+ if (host->devdata->flags & MXSFB_FLAG_BUSFREQ)
+ release_bus_freq(BUS_FREQ_HIGH);
+
+ if (host->devdata->flags & MXSFB_FLAG_PMQOS)
+ pm_qos_remove_request(&host->pm_qos_req);
+
+ dev_dbg(dev, "mxsfb busfreq high release.\n");
+
+ return 0;
}
+static int mxsfb_runtime_resume(struct device *dev)
+{
+ struct mxsfb_info *host = dev_get_drvdata(dev);
+
+ if (host->devdata->flags & MXSFB_FLAG_BUSFREQ)
+ request_bus_freq(BUS_FREQ_HIGH);
+
+ if (host->devdata->flags & MXSFB_FLAG_PMQOS)
+ pm_qos_add_request(&host->pm_qos_req,
+ PM_QOS_CPU_DMA_LATENCY, 0);
+
+ dev_dbg(dev, "mxsfb busfreq high request.\n");
+
+ return 0;
+}
+
+static int mxsfb_suspend(struct device *pdev)
+{
+ struct mxsfb_info *host = dev_get_drvdata(pdev);
+ struct fb_info *fb_info = host->fb_info;
+ int saved_blank;
+
+ console_lock();
+ mxsfb_overlay_suspend(host);
+ fb_set_suspend(fb_info, 1);
+ saved_blank = host->cur_blank;
+ mxsfb_blank(FB_BLANK_POWERDOWN, fb_info);
+ host->restore_blank = saved_blank;
+ console_unlock();
+
+ pinctrl_pm_select_sleep_state(pdev);
+
+ return 0;
+}
+
+static int mxsfb_resume(struct device *pdev)
+{
+ struct mxsfb_info *host = dev_get_drvdata(pdev);
+ struct fb_info *fb_info = host->fb_info;
+
+ pinctrl_pm_select_default_state(pdev);
+
+ console_lock();
+ mxsfb_overlay_resume(host);
+ mxsfb_blank(host->restore_blank, fb_info);
+ fb_set_suspend(fb_info, 0);
+ console_unlock();
+
+ return 0;
+}
+#else
+#define mxsfb_runtime_suspend NULL
+#define mxsfb_runtime_resume NULL
+
+#define mxsfb_suspend NULL
+#define mxsfb_resume NULL
+#endif
+
+static const struct dev_pm_ops mxsfb_pm_ops = {
+ SET_RUNTIME_PM_OPS(mxsfb_runtime_suspend, mxsfb_runtime_resume, NULL)
+ SET_SYSTEM_SLEEP_PM_OPS(mxsfb_suspend, mxsfb_resume)
+};
+
static struct platform_driver mxsfb_driver = {
.probe = mxsfb_probe,
.remove = mxsfb_remove,
@@ -1010,6 +2493,7 @@ static struct platform_driver mxsfb_driver = {
.driver = {
.name = DRIVER_NAME,
.of_match_table = mxsfb_dt_ids,
+ .pm = &mxsfb_pm_ops,
},
};
diff --git a/drivers/video/hdmi.c b/drivers/video/hdmi.c
index ce7c4a269f77..4fe0cf16f0dc 100644
--- a/drivers/video/hdmi.c
+++ b/drivers/video/hdmi.c
@@ -393,6 +393,103 @@ ssize_t hdmi_vendor_infoframe_pack(struct hdmi_vendor_infoframe *frame,
}
EXPORT_SYMBOL(hdmi_vendor_infoframe_pack);
+/**
+ * hdmi_drm_infoframe_init() - initialize an HDMI Dynaminc Range and
+ * mastering infoframe
+ * @frame: HDMI DRM infoframe
+ *
+ * Returns 0 on success or a negative error code on failure.
+ */
+int hdmi_drm_infoframe_init(struct hdmi_drm_infoframe *frame)
+{
+ memset(frame, 0, sizeof(*frame));
+
+ frame->type = HDMI_INFOFRAME_TYPE_DRM;
+ frame->version = 1;
+
+ return 0;
+}
+EXPORT_SYMBOL(hdmi_drm_infoframe_init);
+
+/**
+ * hdmi_drm_infoframe_pack() - write HDMI DRM infoframe to binary buffer
+ * @frame: HDMI DRM infoframe
+ * @buffer: destination buffer
+ * @size: size of buffer
+ *
+ * Packs the information contained in the @frame structure into a binary
+ * representation that can be written into the corresponding controller
+ * registers. Also computes the checksum as required by section 5.3.5 of
+ * the HDMI 1.4 specification.
+ *
+ * Returns the number of bytes packed into the binary buffer or a negative
+ * error code on failure.
+ */
+ssize_t hdmi_drm_infoframe_pack(struct hdmi_drm_infoframe *frame, void *buffer,
+ size_t size)
+{
+ u8 *ptr = buffer;
+ size_t length;
+
+ length = HDMI_INFOFRAME_HEADER_SIZE + frame->length;
+
+ if (size < length)
+ return -ENOSPC;
+
+ memset(buffer, 0, size);
+
+ ptr[0] = frame->type;
+ ptr[1] = frame->version;
+ ptr[2] = frame->length;
+ ptr[3] = 0; /* checksum */
+
+ /* start infoframe payload */
+ ptr += HDMI_INFOFRAME_HEADER_SIZE;
+
+ ptr[0] = frame->eotf;
+ ptr[1] = frame->metadata_type;
+
+ ptr[2] = frame->display_primaries_x[0] & 0xff;
+ ptr[3] = frame->display_primaries_x[0] >> 8;
+
+ ptr[4] = frame->display_primaries_y[0] & 0xff;
+ ptr[5] = frame->display_primaries_y[0] >> 8;
+
+ ptr[6] = frame->display_primaries_x[1] & 0xff;
+ ptr[7] = frame->display_primaries_x[1] >> 8;
+
+ ptr[8] = frame->display_primaries_y[1] & 0xff;
+ ptr[9] = frame->display_primaries_y[1] >> 8;
+
+ ptr[10] = frame->display_primaries_x[2] & 0xff;
+ ptr[11] = frame->display_primaries_x[2] >> 8;
+
+ ptr[12] = frame->display_primaries_y[2] & 0xff;
+ ptr[13] = frame->display_primaries_y[2] >> 8;
+
+ ptr[14] = frame->white_point_x & 0xff;
+ ptr[15] = frame->white_point_x >> 8;
+
+ ptr[16] = frame->white_point_y & 0xff;
+ ptr[17] = frame->white_point_y >> 8;
+
+ ptr[18] = frame->max_mastering_display_luminance & 0xff;
+ ptr[19] = frame->max_mastering_display_luminance >> 8;
+
+ ptr[20] = frame->min_mastering_display_luminance & 0xff;
+ ptr[21] = frame->min_mastering_display_luminance >> 8;
+
+ ptr[22] = frame->max_cll & 0xff;
+ ptr[23] = frame->max_cll >> 8;
+
+ ptr[24] = frame->max_fall & 0xff;
+ ptr[25] = frame->max_fall >> 8;
+
+ hdmi_infoframe_set_checksum(buffer, length);
+
+ return length;
+}
+
/*
* hdmi_vendor_any_infoframe_pack() - write a vendor infoframe to binary buffer
*/
@@ -430,6 +527,9 @@ hdmi_infoframe_pack(union hdmi_infoframe *frame, void *buffer, size_t size)
case HDMI_INFOFRAME_TYPE_AVI:
length = hdmi_avi_infoframe_pack(&frame->avi, buffer, size);
break;
+ case HDMI_INFOFRAME_TYPE_DRM:
+ length = hdmi_drm_infoframe_pack(&frame->drm, buffer, size);
+ break;
case HDMI_INFOFRAME_TYPE_SPD:
length = hdmi_spd_infoframe_pack(&frame->spd, buffer, size);
break;
@@ -462,6 +562,8 @@ static const char *hdmi_infoframe_type_get_name(enum hdmi_infoframe_type type)
return "Source Product Description (SPD)";
case HDMI_INFOFRAME_TYPE_AUDIO:
return "Audio";
+ case HDMI_INFOFRAME_TYPE_DRM:
+ return "Dynamic Range and Mastering";
}
return "Reserved";
}
@@ -908,6 +1010,39 @@ static void hdmi_audio_infoframe_log(const char *level,
frame->downmix_inhibit ? "Yes" : "No");
}
+/**
+ * hdmi_drm_infoframe_log() - log info of HDMI DRM infoframe
+ * @level: logging level
+ * @dev: device
+ * @frame: HDMI DRM infoframe
+ */
+static void hdmi_drm_infoframe_log(const char *level,
+ struct device *dev,
+ struct hdmi_drm_infoframe *frame)
+{
+ int i;
+
+ hdmi_infoframe_log_header(level, dev,
+ (struct hdmi_any_infoframe *)frame);
+ hdmi_log("length: %d\n", frame->length);
+ hdmi_log("eotf: %d\n", frame->eotf);
+ for (i = 0; i <= 2; i++) {
+ hdmi_log("x[%d]: %d\n", i, frame->display_primaries_x[i]);
+ hdmi_log("y[%d]: %d\n", i, frame->display_primaries_y[i]);
+ }
+
+ hdmi_log("white point x: %d\n", frame->white_point_x);
+ hdmi_log("white point y: %d\n", frame->white_point_y);
+
+ hdmi_log("max_mastering_display_luminance: %d\n",
+ frame->max_mastering_display_luminance);
+ hdmi_log("min_mastering_display_luminance: %d\n",
+ frame->min_mastering_display_luminance);
+
+ hdmi_log("max_cll: %d\n", frame->max_cll);
+ hdmi_log("max_fall: %d\n", frame->max_fall);
+}
+
static const char *
hdmi_3d_structure_get_name(enum hdmi_3d_structure s3d_struct)
{
@@ -996,6 +1131,9 @@ void hdmi_infoframe_log(const char *level,
case HDMI_INFOFRAME_TYPE_VENDOR:
hdmi_vendor_any_infoframe_log(level, dev, &frame->vendor);
break;
+ case HDMI_INFOFRAME_TYPE_DRM:
+ hdmi_drm_infoframe_log(level, dev, &frame->drm);
+ break;
}
}
EXPORT_SYMBOL(hdmi_infoframe_log);
diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c
index b82bb0b08161..f83474abc405 100644
--- a/drivers/virtio/virtio_ring.c
+++ b/drivers/virtio/virtio_ring.c
@@ -144,6 +144,8 @@ struct vring_virtqueue {
static bool vring_use_dma_api(struct virtio_device *vdev)
{
+ struct device *dma_dev = vdev->dev.parent;
+
if (!virtio_has_iommu_quirk(vdev))
return true;
@@ -156,7 +158,7 @@ static bool vring_use_dma_api(struct virtio_device *vdev)
* the DMA API if we're a Xen guest, which at least allows
* all of the sensible Xen configurations to work correctly.
*/
- if (xen_domain())
+ if (xen_domain() && !dma_dev->dma_mem)
return true;
return false;
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index f55328a31629..3f849a3d02ad 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -571,7 +571,7 @@ config MAX77620_WATCHDOG
config IMX2_WDT
tristate "IMX2+ Watchdog"
- depends on ARCH_MXC || ARCH_LAYERSCAPE || COMPILE_TEST
+ depends on ARCH_MXC || ARCH_LAYERSCAPE || ARCH_MXC_ARM64 || COMPILE_TEST
select REGMAP_MMIO
select WATCHDOG_CORE
help
@@ -583,6 +583,30 @@ config IMX2_WDT
To compile this driver as a module, choose M here: the
module will be called imx2_wdt.
+config IMX7ULP_WDT
+ tristate "IMX7ULP Watchdog"
+ depends on ARCH_MXC
+ select WATCHDOG_CORE
+ help
+ This is the driver for the hardware watchdog
+ on the Freescale IMX7ULP and later processors.
+ If you have one of these processors and wish to have
+ watchdog support enabled, say Y, otherwise say N.
+
+ To compile this driver as a module, choose M here: the
+ module will be called imx7ulp_wdt.
+
+config IMX8_WDT
+ tristate "IMX8 Watchdog"
+ depends on OF
+ select WATCHDOG_CORE
+ help
+ This is the driver for the watchdog on i.mx8QM/QXP
+ and later processors, this virtual watch dog call
+ the interfaces which provided by SCFW.
+ If you have one of these processors and wish to have
+ watchdog support enabled, say Y, otherwise say N.
+
config UX500_WATCHDOG
tristate "ST-Ericsson Ux500 watchdog"
depends on MFD_DB8500_PRCMU
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
index 715a21078e0c..428cd57f9ffb 100644
--- a/drivers/watchdog/Makefile
+++ b/drivers/watchdog/Makefile
@@ -66,6 +66,8 @@ obj-$(CONFIG_NUC900_WATCHDOG) += nuc900_wdt.o
obj-$(CONFIG_TS4800_WATCHDOG) += ts4800_wdt.o
obj-$(CONFIG_TS72XX_WATCHDOG) += ts72xx_wdt.o
obj-$(CONFIG_IMX2_WDT) += imx2_wdt.o
+obj-$(CONFIG_IMX7ULP_WDT) += imx7ulp_wdt.o
+obj-$(CONFIG_IMX8_WDT) += imx8_wdt.o
obj-$(CONFIG_UX500_WATCHDOG) += ux500_wdt.o
obj-$(CONFIG_RETU_WATCHDOG) += retu_wdt.o
obj-$(CONFIG_BCM2835_WDT) += bcm2835_wdt.o
diff --git a/drivers/watchdog/imx2_wdt.c b/drivers/watchdog/imx2_wdt.c
index e5c162b05376..ca744aeb874e 100644
--- a/drivers/watchdog/imx2_wdt.c
+++ b/drivers/watchdog/imx2_wdt.c
@@ -92,6 +92,9 @@ static const struct watchdog_info imx2_wdt_pretimeout_info = {
WDIOF_PRETIMEOUT,
};
+static int imx2_wdt_ping(struct watchdog_device *wdog);
+static inline bool imx2_wdt_is_running(struct imx2_wdt_device *wdev);
+
static int imx2_wdt_restart(struct watchdog_device *wdog, unsigned long action,
void *data)
{
@@ -106,6 +109,10 @@ static int imx2_wdt_restart(struct watchdog_device *wdog, unsigned long action,
/* Assert SRS signal */
regmap_write(wdev->regmap, IMX2_WDT_WCR, wcr_enable);
+
+ if (imx2_wdt_is_running(wdev))
+ imx2_wdt_ping(wdog);
+
/*
* Due to imx6q errata ERR004346 (WDOG: WDOG SRS bit requires to be
* written twice), we add another two writes to ensure there must be at
@@ -117,7 +124,9 @@ static int imx2_wdt_restart(struct watchdog_device *wdog, unsigned long action,
regmap_write(wdev->regmap, IMX2_WDT_WCR, wcr_enable);
/* wait for reset to assert... */
- mdelay(500);
+ mdelay(100);
+ dev_err(wdog->parent, "failed to assert %s reset, trying with timeout\n",
+ wdev->ext_reset ? "external" : "internal");
return 0;
}
diff --git a/drivers/watchdog/imx7ulp_wdt.c b/drivers/watchdog/imx7ulp_wdt.c
new file mode 100644
index 000000000000..b54268849ce6
--- /dev/null
+++ b/drivers/watchdog/imx7ulp_wdt.c
@@ -0,0 +1,291 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+#include <linux/io.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/reboot.h>
+#include <linux/watchdog.h>
+
+#define WDOG_CS 0x0
+#define WDOG_CS_CMD32EN (1 << 13)
+#define WDOG_CS_ULK (1 << 11)
+#define WDOG_CS_RCS (1 << 10)
+#define WDOG_CS_EN (1 << 7)
+#define WDOG_CS_UPDATE (1 << 5)
+
+#define WDOG_CNT 0x4
+#define WDOG_TOVAL 0x8
+
+#define REFRESH_SEQ0 0xA602
+#define REFRESH_SEQ1 0xB480
+#define REFRESH ((REFRESH_SEQ1 << 16) | (REFRESH_SEQ0))
+
+#define UNLOCK_SEQ0 0xC520
+#define UNLOCK_SEQ1 0xD928
+#define UNLOCK ((UNLOCK_SEQ1 << 16) | (UNLOCK_SEQ0))
+
+struct imx7ulp_wdt {
+ void __iomem *base;
+ int rate;
+ struct watchdog_device wdd;
+ struct notifier_block restart_handler;
+};
+
+static inline void imx7ulp_wdt_enable(void __iomem *base, bool enable)
+{
+ u32 val = readl(base + WDOG_CS);
+
+ local_irq_disable();
+
+ writel(UNLOCK, base + WDOG_CNT);
+ if (enable)
+ writel(val | WDOG_CS_EN, base + WDOG_CS);
+ else
+ writel(val & ~WDOG_CS_EN, base + WDOG_CS);
+
+ local_irq_enable();
+}
+
+static inline bool imx7ulp_wdt_is_enabled(void __iomem *base)
+{
+ u32 val = readl(base + WDOG_CS);
+
+ return val & WDOG_CS_EN;
+}
+
+static int imx7ulp_wdt_ping(struct watchdog_device *wdog)
+{
+ /* refresh the wdt counter to keepalive */
+ struct imx7ulp_wdt *wdt = watchdog_get_drvdata(wdog);
+ local_irq_disable();
+ writel(REFRESH, wdt->base + WDOG_CNT);
+ local_irq_enable();
+ return 0;
+}
+
+static int imx7ulp_wdt_start(struct watchdog_device *wdog)
+{
+ struct imx7ulp_wdt *wdt = watchdog_get_drvdata(wdog);
+ imx7ulp_wdt_enable(wdt->base, true);
+
+ return 0;
+}
+
+static int imx7ulp_wdt_stop(struct watchdog_device *wdog)
+{
+ struct imx7ulp_wdt *wdt = watchdog_get_drvdata(wdog);
+ imx7ulp_wdt_enable(wdt->base, false);
+
+ return 0;
+}
+
+static int imx7ulp_wdt_set_timeout(struct watchdog_device *wdog, unsigned int timeout)
+{
+ struct imx7ulp_wdt *wdt = watchdog_get_drvdata(wdog);
+ u32 val = wdt->rate * timeout;
+
+ local_irq_disable();
+
+ writel(UNLOCK, wdt->base + WDOG_CNT);
+ writel(val, wdt->base + WDOG_TOVAL);
+
+ local_irq_enable();
+
+ wdog->timeout = timeout;
+
+ imx7ulp_wdt_ping(wdog);
+
+ return 0;
+}
+
+static const struct watchdog_ops imx7ulp_wdt_ops = {
+ .owner = THIS_MODULE,
+ .start = imx7ulp_wdt_start,
+ .stop = imx7ulp_wdt_stop,
+ .ping = imx7ulp_wdt_ping,
+ .set_timeout = imx7ulp_wdt_set_timeout,
+};
+
+static const struct watchdog_info imx7ulp_wdt_info = {
+ .identity = "i.MX7ULP watchdog timer",
+ .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING
+ | WDIOF_MAGICCLOSE,
+};
+
+static int imx7ulp_wdt_restart_handler(struct notifier_block *this,
+ unsigned long action, void *data)
+{
+ struct imx7ulp_wdt *wdt = container_of(this, struct imx7ulp_wdt, restart_handler);
+
+ local_irq_disable();
+
+ imx7ulp_wdt_enable(wdt->base, true);
+ imx7ulp_wdt_set_timeout(&wdt->wdd, 1);
+
+ local_irq_enable();
+
+ /* wait for wdog to fire */
+ while(true)
+ ;
+
+ return NOTIFY_DONE;
+}
+
+static inline void imx7ulp_wdt_init(void __iomem *base, unsigned int timeout)
+{
+ u32 val;
+
+ local_irq_disable();
+
+ /* unlock the wdog for reconfiguration */
+ writel_relaxed(UNLOCK_SEQ0, base + WDOG_CNT);
+ writel_relaxed(UNLOCK_SEQ1, base + WDOG_CNT);
+
+ /*set an initial timeout value in TOVAL */
+ writel(timeout, base + WDOG_TOVAL);
+ /* enable 32bit command sequence and reconfigure */
+ val = (1 << 13) | (1 << 8) | (1 << 5);
+ writel(val, base + WDOG_CS);
+
+ local_irq_enable();
+}
+
+static int imx7ulp_wdt_probe(struct platform_device *pdev)
+{
+ struct imx7ulp_wdt *wdt;
+ struct resource *res;
+ int err;
+ u32 timeout;
+
+ wdt = devm_kzalloc(&pdev->dev, sizeof(*wdt), GFP_KERNEL);
+ if (!wdt)
+ return -ENOMEM;
+
+ platform_set_drvdata(pdev, wdt);
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ wdt->base = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(wdt->base))
+ return PTR_ERR(wdt->base);
+
+ /* use the 1KHz LPO as the counter clock */
+ wdt->rate = 1000;
+
+ /* init the wdd */
+ wdt->wdd.info = &imx7ulp_wdt_info;
+ wdt->wdd.ops = &imx7ulp_wdt_ops;
+ wdt->wdd.min_timeout = 1;
+ wdt->wdd.max_timeout = 60;
+ wdt->wdd.parent = &pdev->dev;
+ watchdog_set_drvdata(&wdt->wdd, wdt);
+ /*
+ * set the timeout_parm to 0 to get the timeout
+ * from 'timeout-sec' property in dtb.
+ */
+ err = watchdog_init_timeout(&wdt->wdd, 0, &pdev->dev);
+ if (err) {
+ dev_err(&pdev->dev, "Failed to init the wdog timeout\n");
+ return err;
+ }
+
+ timeout = wdt->wdd.timeout * wdt->rate;
+ /* reconfigure the watchdog timer.*/
+ imx7ulp_wdt_init(wdt->base, timeout);
+
+ err = watchdog_register_device(&wdt->wdd);
+ if (err) {
+ dev_err(&pdev->dev, "Failed to register watchdog device\n");
+ return err;
+ }
+
+ wdt->restart_handler.notifier_call = imx7ulp_wdt_restart_handler;
+ wdt->restart_handler.priority = 128;
+ err = register_restart_handler(&wdt->restart_handler);
+ if (err) {
+ dev_err(&pdev->dev, "cannot register restart handler\n");
+ watchdog_unregister_device(&wdt->wdd);
+ return err;
+ }
+
+ return 0;
+}
+
+static int imx7ulp_wdt_remove(struct platform_device *pdev)
+{
+ struct imx7ulp_wdt *wdt = platform_get_drvdata(pdev);
+
+ imx7ulp_wdt_stop(&wdt->wdd);
+
+ watchdog_unregister_device(&wdt->wdd);
+
+ return 0;
+}
+
+static void imx7ulp_wdt_shutdown(struct platform_device *pdev)
+{
+ struct imx7ulp_wdt *wdt = platform_get_drvdata(pdev);
+
+ if (watchdog_active(&wdt->wdd))
+ imx7ulp_wdt_stop(&wdt->wdd);
+}
+
+#ifdef CONFIG_PM_SLEEP
+/* Disable watchdog before suspend */
+static int imx7ulp_wdt_suspend(struct device *dev)
+{
+ struct imx7ulp_wdt *wdt = dev_get_drvdata(dev);
+
+ imx7ulp_wdt_enable(wdt->base, false);
+
+ return 0;
+}
+
+static int imx7ulp_wdt_resume(struct device *dev)
+{
+ struct imx7ulp_wdt *wdt = dev_get_drvdata(dev);
+ u32 timeout = wdt->wdd.timeout * wdt->rate;
+
+ if (imx7ulp_wdt_is_enabled(wdt->base))
+ imx7ulp_wdt_init(wdt->base, timeout);
+
+ if (watchdog_active(&wdt->wdd))
+ imx7ulp_wdt_enable(wdt->base, true);
+
+ return 0;
+}
+#endif
+
+static SIMPLE_DEV_PM_OPS(imx7ulp_wdt_pm_ops, imx7ulp_wdt_suspend,
+ imx7ulp_wdt_resume);
+
+static const struct of_device_id imx7ulp_wdt_dt_ids[] = {
+ { .compatible = "fsl,imx7ulp-wdt", },
+ { /*sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, imx7ulp_wdt_dt_ids);
+
+static struct platform_driver imx7ulp_wdt_driver = {
+ .probe = imx7ulp_wdt_probe,
+ .remove = imx7ulp_wdt_remove,
+ .shutdown = imx7ulp_wdt_shutdown,
+ .driver = {
+ .name = "imx7ulp-wdt",
+ .pm = &imx7ulp_wdt_pm_ops,
+ .of_match_table = imx7ulp_wdt_dt_ids,
+ },
+};
+
+module_platform_driver(imx7ulp_wdt_driver);
+
+MODULE_AUTHOR("Bai Ping <ping.bai@nxp.com>");
+MODULE_DESCRIPTION("Freescale i.MX7ULP watchdog driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/watchdog/imx8_wdt.c b/drivers/watchdog/imx8_wdt.c
new file mode 100644
index 000000000000..7a855012366a
--- /dev/null
+++ b/drivers/watchdog/imx8_wdt.c
@@ -0,0 +1,233 @@
+/*
+ * Copyright (C) 2017 NXP.
+ *
+ * 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/arm-smccc.h>
+#include <linux/io.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/platform_device.h>
+#include <linux/reboot.h>
+#include <linux/watchdog.h>
+#include <soc/imx/fsl_sip.h>
+#include <soc/imx8/sc/sci.h>
+#include <soc/imx8/sc/svc/irq/api.h>
+
+#define DEFAULT_TIMEOUT 60
+/*
+ * Software timer tick implemented in scfw side, support 10ms to 0xffffffff ms
+ * in theory, but for normal case, 1s~128s is enough, you can change this max
+ * value in case it's not enough.
+ */
+#define MAX_TIMEOUT 128
+
+static bool nowayout = WATCHDOG_NOWAYOUT;
+module_param(nowayout, bool, 0000);
+MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default="
+ __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
+
+static unsigned int timeout = DEFAULT_TIMEOUT;
+module_param(timeout, uint, 0000);
+MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds (default="
+ __MODULE_STRING(DEFAULT_TIMEOUT) ")");
+
+static struct watchdog_device imx8_wdd;
+
+static int imx8_wdt_notify(struct notifier_block *nb,
+ unsigned long event, void *group)
+{
+ /* ignore other irqs */
+ if (!(event & SC_IRQ_WDOG &&
+ (*(sc_irq_group_t *)group == SC_IRQ_GROUP_WDOG)))
+ return 0;
+
+ watchdog_notify_pretimeout(&imx8_wdd);
+
+ return 0;
+}
+
+static int imx8_wdt_ping(struct watchdog_device *wdog)
+{
+ struct arm_smccc_res res;
+
+ arm_smccc_smc(FSL_SIP_SRTC, FSL_SIP_SRTC_PING_WDOG, 0, 0, 0, 0, 0, 0,
+ &res);
+
+ return res.a0;
+}
+
+static int imx8_wdt_start(struct watchdog_device *wdog)
+{
+ struct arm_smccc_res res;
+
+ /* no block */
+ arm_smccc_smc(FSL_SIP_SRTC, FSL_SIP_SRTC_START_WDOG, 0, 0, 0, 0, 0, 0,
+ &res);
+ if (res.a0)
+ return res.a0;
+
+ return 0;
+}
+
+static int imx8_wdt_stop(struct watchdog_device *wdog)
+{
+ struct arm_smccc_res res;
+
+ arm_smccc_smc(FSL_SIP_SRTC, FSL_SIP_SRTC_STOP_WDOG, 0, 0, 0, 0, 0, 0,
+ &res);
+
+ return res.a0;
+}
+
+static int imx8_wdt_set_timeout(struct watchdog_device *wdog,
+ unsigned int timeout)
+{
+ struct arm_smccc_res res;
+
+ wdog->timeout = timeout;
+
+ arm_smccc_smc(FSL_SIP_SRTC, FSL_SIP_SRTC_SET_TIMEOUT_WDOG,
+ timeout * 1000, 0, 0, 0, 0, 0, &res);
+
+ return res.a0;
+}
+
+static int imx8_wdt_set_pretimeout(struct watchdog_device *wdog,
+ unsigned int new_pretimeout)
+{
+ struct arm_smccc_res res;
+
+ arm_smccc_smc(FSL_SIP_SRTC, FSL_SIP_SRTC_SET_PRETIME_WDOG,
+ new_pretimeout * 1000, 0, 0, 0, 0, 0,
+ &res);
+
+ return res.a0;
+}
+
+static const struct watchdog_ops imx8_wdt_ops = {
+ .owner = THIS_MODULE,
+ .start = imx8_wdt_start,
+ .stop = imx8_wdt_stop,
+ .ping = imx8_wdt_ping,
+ .set_timeout = imx8_wdt_set_timeout,
+ .set_pretimeout = imx8_wdt_set_pretimeout,
+};
+
+static const struct watchdog_info imx8_wdt_info = {
+ .identity = "i.MX8 watchdog timer",
+ .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING |
+ WDIOF_MAGICCLOSE | WDIOF_PRETIMEOUT,
+};
+
+static struct notifier_block imx8_wdt_notifier = {
+ .notifier_call = imx8_wdt_notify,
+};
+
+#ifdef CONFIG_PM_SLEEP
+static int imx8_wdt_suspend(struct device *dev)
+{
+ if (test_bit(WDOG_ACTIVE, &imx8_wdd.status))
+ imx8_wdt_stop(&imx8_wdd);
+
+ return 0;
+}
+
+static int imx8_wdt_resume(struct device *dev)
+{
+ if (test_bit(WDOG_ACTIVE, &imx8_wdd.status))
+ imx8_wdt_start(&imx8_wdd);
+
+ return 0;
+}
+
+static const struct dev_pm_ops imx8_wdt_pm_ops = {
+ .suspend = imx8_wdt_suspend,
+ .resume = imx8_wdt_resume,
+};
+
+#define IMX8_WDT_PM_OPS (&imx8_wdt_pm_ops)
+
+#else
+
+#define IMX8_WDT_PM_OPS NULL
+
+#endif
+
+static int imx8_wdt_probe(struct platform_device *pdev)
+{
+ struct watchdog_device *wdt = &imx8_wdd;
+ int err;
+
+ platform_set_drvdata(pdev, wdt);
+ /* init the wdd */
+ wdt->info = &imx8_wdt_info;
+ wdt->ops = &imx8_wdt_ops;
+ wdt->min_timeout = 1;
+ wdt->max_timeout = MAX_TIMEOUT;
+ wdt->parent = &pdev->dev;
+ watchdog_set_drvdata(wdt, NULL);
+
+ err = watchdog_init_timeout(wdt, DEFAULT_TIMEOUT, &pdev->dev);
+ if (err) {
+ dev_err(&pdev->dev, "Failed to init the wdog timeout:%d\n",
+ err);
+ return err;
+ }
+
+ err = watchdog_register_device(wdt);
+ if (err) {
+ dev_err(&pdev->dev, "Failed to register watchdog device\n");
+ return err;
+ }
+
+ return register_scu_notifier(&imx8_wdt_notifier);
+}
+
+static int imx8_wdt_remove(struct platform_device *pdev)
+{
+ struct watchdog_device *wdt = platform_get_drvdata(pdev);
+
+ imx8_wdt_stop(wdt);
+
+ watchdog_unregister_device(wdt);
+
+ return 0;
+}
+
+static void imx8_wdt_shutdown(struct platform_device *pdev)
+{
+ struct watchdog_device *wdt = platform_get_drvdata(pdev);
+
+ if (watchdog_active(wdt))
+ imx8_wdt_stop(wdt);
+}
+
+static const struct of_device_id imx8_wdt_dt_ids[] = {
+ { .compatible = "fsl,imx8-wdt", },
+ { /*sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, imx8_wdt_dt_ids);
+
+static struct platform_driver imx8_wdt_driver = {
+ .probe = imx8_wdt_probe,
+ .remove = imx8_wdt_remove,
+ .shutdown = imx8_wdt_shutdown,
+ .driver = {
+ .name = "imx8-wdt",
+ .of_match_table = imx8_wdt_dt_ids,
+ .pm = IMX8_WDT_PM_OPS,
+ },
+};
+
+module_platform_driver(imx8_wdt_driver);
+
+MODULE_AUTHOR("Robin Gong <yibin.gong@nxp.com>");
+MODULE_DESCRIPTION("NXP i.MX8 watchdog driver");
+MODULE_LICENSE("GPL v2");
diff --git a/fs/block_dev.c b/fs/block_dev.c
index 61949e3446e5..b4b462d289f3 100644
--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -263,7 +263,7 @@ __blkdev_direct_IO_simple(struct kiocb *iocb, struct iov_iter *iter,
if (!READ_ONCE(bio.bi_private))
break;
if (!(iocb->ki_flags & IOCB_HIPRI) ||
- !blk_mq_poll(bdev_get_queue(bdev), qc))
+ !blk_poll(bdev_get_queue(bdev), qc))
io_schedule();
}
__set_current_state(TASK_RUNNING);
@@ -429,7 +429,7 @@ __blkdev_direct_IO(struct kiocb *iocb, struct iov_iter *iter, int nr_pages)
break;
if (!(iocb->ki_flags & IOCB_HIPRI) ||
- !blk_mq_poll(bdev_get_queue(bdev), qc))
+ !blk_poll(bdev_get_queue(bdev), qc))
io_schedule();
}
__set_current_state(TASK_RUNNING);
diff --git a/fs/btrfs/check-integrity.c b/fs/btrfs/check-integrity.c
index 7d5a9b51f0d7..0e7efa9a76d8 100644
--- a/fs/btrfs/check-integrity.c
+++ b/fs/btrfs/check-integrity.c
@@ -2803,7 +2803,7 @@ static void __btrfsic_submit_bio(struct bio *bio)
mutex_lock(&btrfsic_mutex);
/* since btrfsic_submit_bio() is also called before
* btrfsic_mount(), this might return NULL */
- dev_state = btrfsic_dev_state_lookup(bio_dev(bio));
+ dev_state = btrfsic_dev_state_lookup(bio_dev(bio) + bio->bi_partno);
if (NULL != dev_state &&
(bio_op(bio) == REQ_OP_WRITE) && bio_has_data(bio)) {
unsigned int i = 0;
diff --git a/fs/direct-io.c b/fs/direct-io.c
index 30bf22c989de..2cd493494c3b 100644
--- a/fs/direct-io.c
+++ b/fs/direct-io.c
@@ -519,7 +519,7 @@ static struct bio *dio_await_one(struct dio *dio)
dio->waiter = current;
spin_unlock_irqrestore(&dio->bio_lock, flags);
if (!(dio->iocb->ki_flags & IOCB_HIPRI) ||
- !blk_mq_poll(dio->bio_disk->queue, dio->bio_cookie))
+ !blk_poll(dio->bio_disk->queue, dio->bio_cookie))
io_schedule();
/* wake up sets us TASK_RUNNING */
spin_lock_irqsave(&dio->bio_lock, flags);
diff --git a/fs/iomap.c b/fs/iomap.c
index 3f5b1655cfce..64e07534ded3 100644
--- a/fs/iomap.c
+++ b/fs/iomap.c
@@ -1079,7 +1079,7 @@ iomap_dio_rw(struct kiocb *iocb, struct iov_iter *iter,
if (!(iocb->ki_flags & IOCB_HIPRI) ||
!dio->submit.last_queue ||
- !blk_mq_poll(dio->submit.last_queue,
+ !blk_poll(dio->submit.last_queue,
dio->submit.cookie))
io_schedule();
}
diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
index 309d24118f9a..755149cfcf23 100644
--- a/fs/proc/task_mmu.c
+++ b/fs/proc/task_mmu.c
@@ -758,7 +758,7 @@ static int show_smap(struct seq_file *m, void *v, int is_pid)
};
int ret = 0;
bool rollup_mode;
- bool last_vma;
+ bool last_vma = true;
if (priv->rollup) {
rollup_mode = true;
diff --git a/include/drm/bridge/nwl_dsi.h b/include/drm/bridge/nwl_dsi.h
new file mode 100644
index 000000000000..df5f25b18fdb
--- /dev/null
+++ b/include/drm/bridge/nwl_dsi.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2017 NXP
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __NWL_DSI__
+#define __NWL_DSI__
+
+#include <drm/drmP.h>
+#include <drm/drm_mipi_dsi.h>
+#include <linux/phy/phy.h>
+
+/*
+ * RGB bit distribution within the 24-bit data bus,
+ * as specified by the DPI specification
+ */
+enum dpi_interface_color_coding {
+ DPI_16_BIT_565_PACKED, /* 0x0 cfg1 */
+ DPI_16_BIT_565_ALIGNED, /* 0x1 cfg 2 */
+ DPI_16_BIT_565_SHIFTED, /* 0x2 cfg 3 */
+ DPI_18_BIT_PACKED, /* 0x3 cfg1 */
+ DPI_18_BIT_ALIGNED, /* 0x4* cfg2 */
+ DPI_24_BIT /* 0x5 */
+};
+
+/* DSI packet type of pixels, as specified by the DPI specification */
+enum dpi_pixel_format {
+ DPI_FMT_16_BIT, /* 0x0 */
+ DPI_FMT_18_BIT, /* 0x1 */
+ DPI_FMT_18_BIT_LOOSELY_PACKED, /* 0x2 */
+ DPI_FMT_24_BIT /* 0x3 */
+};
+
+#endif /* __NWL_DSI_H__ */
diff --git a/include/drm/bridge/sec_mipi_dsim.h b/include/drm/bridge/sec_mipi_dsim.h
new file mode 100644
index 000000000000..2f9233563ee6
--- /dev/null
+++ b/include/drm/bridge/sec_mipi_dsim.h
@@ -0,0 +1,112 @@
+/*
+ * Copyright 2018-2019 NXP
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __SEC_MIPI_DSIM_H__
+#define __SEC_MIPI_DSIM_H__
+
+#include <drm/drmP.h>
+#include <linux/bsearch.h>
+
+struct sec_mipi_dsim_dphy_timing;
+struct sec_mipi_dsim_pll;
+
+struct sec_mipi_dsim_plat_data {
+ uint32_t version;
+ uint32_t max_data_lanes;
+ uint64_t max_data_rate;
+ const struct sec_mipi_dsim_dphy_timing *dphy_timing;
+ uint32_t num_dphy_timing;
+ const struct sec_mipi_dsim_pll *dphy_pll;
+ int (*dphy_timing_cmp)(const void *key, const void *elt);
+ enum drm_mode_status (*mode_valid)(struct drm_connector *connector,
+ struct drm_display_mode *mode);
+};
+
+/* DPHY PLL structure */
+struct sec_mipi_dsim_range {
+ uint32_t min;
+ uint32_t max;
+};
+
+struct sec_mipi_dsim_pll {
+ struct sec_mipi_dsim_range p;
+ struct sec_mipi_dsim_range m;
+ struct sec_mipi_dsim_range s;
+ struct sec_mipi_dsim_range k;
+ struct sec_mipi_dsim_range fin;
+ struct sec_mipi_dsim_range fpref;
+ struct sec_mipi_dsim_range fvco;
+};
+
+/* DPHY timings structure */
+struct sec_mipi_dsim_dphy_timing {
+ uint32_t bit_clk; /* MHz */
+
+ uint32_t clk_prepare;
+ uint32_t clk_zero;
+ uint32_t clk_post;
+ uint32_t clk_trail;
+
+ uint32_t hs_prepare;
+ uint32_t hs_zero;
+ uint32_t hs_trail;
+
+ uint32_t lpx;
+ uint32_t hs_exit;
+};
+
+#define DSIM_DPHY_TIMING(bclk, cpre, czero, cpost, ctrail, \
+ hpre, hzero, htrail, lp, hexit) \
+ .bit_clk = bclk, \
+ .clk_prepare = cpre, \
+ .clk_zero = czero, \
+ .clk_post = cpost, \
+ .clk_trail = ctrail, \
+ .hs_prepare = hpre, \
+ .hs_zero = hzero, \
+ .hs_trail = htrail, \
+ .lpx = lp, \
+ .hs_exit = hexit
+
+static inline int dphy_timing_default_cmp(const void *key, const void *elt)
+{
+ const struct sec_mipi_dsim_dphy_timing *_key = key;
+ const struct sec_mipi_dsim_dphy_timing *_elt = elt;
+
+ /* find an element whose 'bit_clk' is equal to the
+ * the key's 'bit_clk' value or, the difference
+ * between them is less than 5.
+ */
+ if (abs((int)(_elt->bit_clk - _key->bit_clk)) <= 5)
+ return 0;
+
+ if (_key->bit_clk < _elt->bit_clk)
+ /* search bottom half */
+ return 1;
+ else
+ /* search top half */
+ return -1;
+}
+
+int sec_mipi_dsim_check_pll_out(void *driver_private,
+ const struct drm_display_mode *mode);
+int sec_mipi_dsim_bind(struct device *dev, struct device *master, void *data,
+ struct drm_encoder *encoder, struct resource *res,
+ int irq, const struct sec_mipi_dsim_plat_data *pdata);
+void sec_mipi_dsim_unbind(struct device *dev, struct device *master, void *data);
+
+void sec_mipi_dsim_suspend(struct device *dev);
+void sec_mipi_dsim_resume(struct device *dev);
+
+#endif
diff --git a/include/drm/drmP.h b/include/drm/drmP.h
index 7277783a4ff0..59be1232d005 100644
--- a/include/drm/drmP.h
+++ b/include/drm/drmP.h
@@ -136,6 +136,7 @@ struct pci_controller;
#define DRM_UT_ATOMIC 0x10
#define DRM_UT_VBL 0x20
#define DRM_UT_STATE 0x40
+#define DRM_UT_LEASE 0x80
/***********************************************************************/
/** \name DRM template customization defaults */
@@ -250,6 +251,9 @@ struct pci_controller;
#define DRM_DEBUG_VBL(fmt, ...) \
drm_printk(KERN_DEBUG, DRM_UT_VBL, fmt, ##__VA_ARGS__)
+#define DRM_DEBUG_LEASE(fmt, ...) \
+ drm_printk(KERN_DEBUG, DRM_UT_LEASE, fmt, ##__VA_ARGS__)
+
#define _DRM_DEV_DEFINE_DEBUG_RATELIMITED(dev, level, fmt, args...) \
({ \
static DEFINE_RATELIMIT_STATE(_rs, \
diff --git a/include/drm/drm_auth.h b/include/drm/drm_auth.h
index 81a40c2a9a3e..86bff9841b54 100644
--- a/include/drm/drm_auth.h
+++ b/include/drm/drm_auth.h
@@ -52,6 +52,12 @@ struct drm_lock_data {
* @dev: Link back to the DRM device
* @lock: DRI1 lock information.
* @driver_priv: Pointer to driver-private information.
+ * @lessor: Lease holder
+ * @lessee_id: id for lessees. Owners always have id 0
+ * @lessee_list: other lessees of the same master
+ * @lessees: drm_masters leasing from this one
+ * @leases: Objects leased to this drm_master.
+ * @lessee_idr: All lessees under this owner (only used where lessor == NULL)
*
* Note that master structures are only relevant for the legacy/primary device
* nodes, hence there can only be one per device, not one per drm_minor.
@@ -76,10 +82,25 @@ struct drm_master {
struct idr magic_map;
struct drm_lock_data lock;
void *driver_priv;
+
+ /* Tree of display resource leases, each of which is a drm_master struct
+ * All of these get activated simultaneously, so drm_device master points
+ * at the top of the tree (for which lessor is NULL). Protected by
+ * &drm_device.mode_config.idr_mutex.
+ */
+
+ struct drm_master *lessor;
+ int lessee_id;
+ struct list_head lessee_list;
+ struct list_head lessees;
+ struct idr leases;
+ struct idr lessee_idr;
};
struct drm_master *drm_master_get(struct drm_master *master);
void drm_master_put(struct drm_master **master);
bool drm_is_current_master(struct drm_file *fpriv);
+struct drm_master *drm_master_create(struct drm_device *dev);
+
#endif
diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
index ea8da401c93c..e9e6fb0ba56d 100644
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -157,6 +157,11 @@ struct drm_hdmi_info {
/** @y420_dc_modes: bitmap of deep color support index */
u8 y420_dc_modes;
+
+ /* Colorimerty info from EDID */
+ u32 colorimetry;
+ /* Panel HDR capabilities */
+ struct hdr_static_metadata hdr_panel_metadata;
};
/**
@@ -281,6 +286,11 @@ struct drm_display_info {
u8 cea_rev;
/**
+ * @non_desktop: Non desktop display (HMD)
+ */
+ bool non_desktop;
+
+ /**
* @hdmi: advance features of a HDMI sink.
*/
struct drm_hdmi_info hdmi;
@@ -359,10 +369,30 @@ struct drm_connector_state {
enum hdmi_picture_aspect picture_aspect_ratio;
/**
+ * @content_type: Connector property to control the
+ * HDMI infoframe content type setting.
+ * The %DRM_MODE_CONTENT_TYPE_\* values much
+ * match the values.
+ */
+ unsigned int content_type;
+
+ /**
* @scaling_mode: Connector property to control the
* upscaling, mostly used for built-in panels.
*/
unsigned int scaling_mode;
+
+ /**
+ * @metadata_blob_ptr:
+ * DRM blob property for HDR metadata
+ */
+ struct drm_property_blob *hdr_source_metadata_blob_ptr;
+ bool hdr_metadata_changed : 1;
+ /**
+ * @content_protection: Connector property to request content
+ * protection. This is most commonly used for HDCP.
+ */
+ unsigned int content_protection;
};
/**
@@ -711,6 +741,7 @@ struct drm_cmdline_mode {
* @tile_h_size: horizontal size of this tile.
* @tile_v_size: vertical size of this tile.
* @scaling_mode_property: Optional atomic property to control the upscaling.
+ * @content_protection_property: Optional property to control content protection
*
* Each connector may be connected to one or more CRTCs, or may be clonable by
* another connector if they can share a CRTC. Each connector also has a specific
@@ -802,6 +833,12 @@ struct drm_connector {
struct drm_property *scaling_mode_property;
/**
+ * @content_protection_property: DRM ENUM property for content
+ * protection
+ */
+ struct drm_property *content_protection_property;
+
+ /**
* @path_blob_ptr:
*
* DRM blob property data for the DP MST path property.
@@ -905,6 +942,9 @@ struct drm_connector {
uint8_t num_h_tile, num_v_tile;
uint8_t tile_h_loc, tile_v_loc;
uint16_t tile_h_size, tile_v_size;
+
+ /* HDR metdata */
+ struct hdr_static_metadata *hdr_source_metadata;
};
#define obj_to_connector(x) container_of(x, struct drm_connector, base)
@@ -933,10 +973,11 @@ static inline unsigned drm_connector_index(struct drm_connector *connector)
* add takes a reference to it.
*/
static inline struct drm_connector *drm_connector_lookup(struct drm_device *dev,
+ struct drm_file *file_priv,
uint32_t id)
{
struct drm_mode_object *mo;
- mo = drm_mode_object_find(dev, id, DRM_MODE_OBJECT_CONNECTOR);
+ mo = drm_mode_object_find(dev, file_priv, id, DRM_MODE_OBJECT_CONNECTOR);
return mo ? obj_to_connector(mo) : NULL;
}
@@ -994,15 +1035,23 @@ const char *drm_get_dvi_i_subconnector_name(int val);
const char *drm_get_dvi_i_select_name(int val);
const char *drm_get_tv_subconnector_name(int val);
const char *drm_get_tv_select_name(int val);
+const char *drm_get_content_protection_name(int val);
int drm_mode_create_dvi_i_properties(struct drm_device *dev);
int drm_mode_create_tv_properties(struct drm_device *dev,
unsigned int num_modes,
const char * const modes[]);
int drm_mode_create_scaling_mode_property(struct drm_device *dev);
+int drm_connector_attach_content_type_property(struct drm_connector *dev);
int drm_connector_attach_scaling_mode_property(struct drm_connector *connector,
u32 scaling_mode_mask);
+int drm_connector_attach_content_protection_property(
+ struct drm_connector *connector);
int drm_mode_create_aspect_ratio_property(struct drm_device *dev);
+int drm_mode_create_content_type_property(struct drm_device *dev);
+void drm_hdmi_avi_infoframe_content_type(struct hdmi_avi_infoframe *frame,
+ const struct drm_connector_state *conn_state);
+
int drm_mode_create_suggested_offset_properties(struct drm_device *dev);
int drm_mode_connector_set_path_property(struct drm_connector *connector,
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index 1a642020e306..1577e32da695 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -944,10 +944,11 @@ struct drm_crtc *drm_crtc_from_index(struct drm_device *dev, int idx);
* userspace interface should be done using &drm_property.
*/
static inline struct drm_crtc *drm_crtc_find(struct drm_device *dev,
- uint32_t id)
+ struct drm_file *file_priv,
+ uint32_t id)
{
struct drm_mode_object *mo;
- mo = drm_mode_object_find(dev, id, DRM_MODE_OBJECT_CRTC);
+ mo = drm_mode_object_find(dev, file_priv, id, DRM_MODE_OBJECT_CRTC);
return mo ? obj_to_crtc(mo) : NULL;
}
diff --git a/include/drm/drm_device.h b/include/drm/drm_device.h
index e21af87a2f3c..7c4fa32f3fc6 100644
--- a/include/drm/drm_device.h
+++ b/include/drm/drm_device.h
@@ -17,6 +17,7 @@ struct drm_vblank_crtc;
struct drm_sg_mem;
struct drm_local_map;
struct drm_vma_offset_manager;
+struct drm_fb_helper;
struct inode;
@@ -185,6 +186,14 @@ struct drm_device {
struct drm_vma_offset_manager *vma_offset_manager;
/*@} */
int switch_power_state;
+
+ /**
+ * @fb_helper:
+ *
+ * Pointer to the fbdev emulation structure.
+ * Set by drm_fb_helper_init() and cleared by drm_fb_helper_fini().
+ */
+ struct drm_fb_helper *fb_helper;
};
#endif
diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h
index 8fd7cb5297ab..8508b8dbf9aa 100644
--- a/include/drm/drm_dp_helper.h
+++ b/include/drm/drm_dp_helper.h
@@ -805,6 +805,74 @@
#define DP_CEC_TX_MESSAGE_BUFFER 0x3020
#define DP_CEC_MESSAGE_BUFFER_LENGTH 0x10
+#define DP_AUX_HDCP_BKSV 0x68000
+#define DP_AUX_HDCP_RI_PRIME 0x68005
+#define DP_AUX_HDCP_AKSV 0x68007
+#define DP_AUX_HDCP_AN 0x6800C
+#define DP_AUX_HDCP_V_PRIME(h) (0x68014 + h * 4)
+#define DP_AUX_HDCP_BCAPS 0x68028
+# define DP_BCAPS_REPEATER_PRESENT BIT(1)
+# define DP_BCAPS_HDCP_CAPABLE BIT(0)
+#define DP_AUX_HDCP_BSTATUS 0x68029
+# define DP_BSTATUS_REAUTH_REQ BIT(3)
+# define DP_BSTATUS_LINK_FAILURE BIT(2)
+# define DP_BSTATUS_R0_PRIME_READY BIT(1)
+# define DP_BSTATUS_READY BIT(0)
+#define DP_AUX_HDCP_BINFO 0x6802A
+#define DP_AUX_HDCP_KSV_FIFO 0x6802C
+#define DP_AUX_HDCP_AINFO 0x6803B
+
+/* DP HDCP2.2 parameter offsets in DPCD address space */
+#define DP_HDCP_2_2_REG_RTX_OFFSET 0x69000
+#define DP_HDCP_2_2_REG_TXCAPS_OFFSET 0x69008
+#define DP_HDCP_2_2_REG_CERT_RX_OFFSET 0x6900B
+#define DP_HDCP_2_2_REG_RRX_OFFSET 0x69215
+#define DP_HDCP_2_2_REG_RX_CAPS_OFFSET 0x6921D
+#define DP_HDCP_2_2_REG_EKPUB_KM_OFFSET 0x69220
+#define DP_HDCP_2_2_REG_EKH_KM_WR_OFFSET 0x692A0
+#define DP_HDCP_2_2_REG_M_OFFSET 0x692B0
+#define DP_HDCP_2_2_REG_HPRIME_OFFSET 0x692C0
+#define DP_HDCP_2_2_REG_EKH_KM_RD_OFFSET 0x692E0
+#define DP_HDCP_2_2_REG_RN_OFFSET 0x692F0
+#define DP_HDCP_2_2_REG_LPRIME_OFFSET 0x692F8
+#define DP_HDCP_2_2_REG_EDKEY_KS_OFFSET 0x69318
+#define DP_HDCP_2_2_REG_RIV_OFFSET 0x69328
+#define DP_HDCP_2_2_REG_RXINFO_OFFSET 0x69330
+#define DP_HDCP_2_2_REG_SEQ_NUM_V_OFFSET 0x69332
+#define DP_HDCP_2_2_REG_VPRIME_OFFSET 0x69335
+#define DP_HDCP_2_2_REG_RECV_ID_LIST_OFFSET 0x69345
+#define DP_HDCP_2_2_REG_V_OFFSET 0x693E0
+#define DP_HDCP_2_2_REG_SEQ_NUM_M_OFFSET 0x693F0
+#define DP_HDCP_2_2_REG_K_OFFSET 0x693F3
+#define DP_HDCP_2_2_REG_STREAM_ID_TYPE_OFFSET 0x693F5
+#define DP_HDCP_2_2_REG_MPRIME_OFFSET 0x69473
+#define DP_HDCP_2_2_REG_RXSTATUS_OFFSET 0x69493
+#define DP_HDCP_2_2_REG_STREAM_TYPE_OFFSET 0x69494
+#define DP_HDCP_2_2_REG_DBG_OFFSET 0x69518
+
+/* DP HDCP message start offsets in DPCD address space */
+#define DP_HDCP_2_2_AKE_INIT_OFFSET DP_HDCP_2_2_REG_RTX_OFFSET
+#define DP_HDCP_2_2_AKE_SEND_CERT_OFFSET DP_HDCP_2_2_REG_CERT_RX_OFFSET
+#define DP_HDCP_2_2_AKE_NO_STORED_KM_OFFSET DP_HDCP_2_2_REG_EKPUB_KM_OFFSET
+#define DP_HDCP_2_2_AKE_STORED_KM_OFFSET DP_HDCP_2_2_REG_EKH_KM_WR_OFFSET
+#define DP_HDCP_2_2_AKE_SEND_HPRIME_OFFSET DP_HDCP_2_2_REG_HPRIME_OFFSET
+#define DP_HDCP_2_2_AKE_SEND_PAIRING_INFO_OFFSET \
+ DP_HDCP_2_2_REG_EKH_KM_RD_OFFSET
+#define DP_HDCP_2_2_LC_INIT_OFFSET DP_HDCP_2_2_REG_RN_OFFSET
+#define DP_HDCP_2_2_LC_SEND_LPRIME_OFFSET DP_HDCP_2_2_REG_LPRIME_OFFSET
+#define DP_HDCP_2_2_SKE_SEND_EKS_OFFSET DP_HDCP_2_2_REG_EDKEY_KS_OFFSET
+#define DP_HDCP_2_2_REP_SEND_RECVID_LIST_OFFSET DP_HDCP_2_2_REG_RXINFO_OFFSET
+#define DP_HDCP_2_2_REP_SEND_ACK_OFFSET DP_HDCP_2_2_REG_V_OFFSET
+#define DP_HDCP_2_2_REP_STREAM_MANAGE_OFFSET DP_HDCP_2_2_REG_SEQ_NUM_M_OFFSET
+#define DP_HDCP_2_2_REP_STREAM_READY_OFFSET DP_HDCP_2_2_REG_MPRIME_OFFSET
+
+#define HDCP_2_2_DP_RXSTATUS_LEN 1
+#define HDCP_2_2_DP_RXSTATUS_READY(x) ((x) & BIT(0))
+#define HDCP_2_2_DP_RXSTATUS_H_PRIME(x) ((x) & BIT(1))
+#define HDCP_2_2_DP_RXSTATUS_PAIRING(x) ((x) & BIT(2))
+#define HDCP_2_2_DP_RXSTATUS_REAUTH_REQ(x) ((x) & BIT(3))
+#define HDCP_2_2_DP_RXSTATUS_LINK_FAILED(x) ((x) & BIT(4))
+
/* DP 1.2 Sideband message defines */
/* peer device type - DP 1.2a Table 2-92 */
#define DP_PEER_DEVICE_NONE 0x0
diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h
index 267e0426c479..6f1410b113fc 100644
--- a/include/drm/drm_edid.h
+++ b/include/drm/drm_edid.h
@@ -372,6 +372,10 @@ static inline int drm_eld_mnl(const uint8_t *eld)
return (eld[DRM_ELD_CEA_EDID_VER_MNL] & DRM_ELD_MNL_MASK) >> DRM_ELD_MNL_SHIFT;
}
+int
+drm_hdmi_infoframe_set_hdr_metadata(struct hdmi_drm_infoframe *frame,
+ void *hdr_source_metadata);
+
/**
* drm_eld_sad - Get ELD SAD structures.
* @eld: pointer to an eld memory structure with sad_count set
diff --git a/include/drm/drm_encoder.h b/include/drm/drm_encoder.h
index 8d8245ec0181..86db0da8bdcb 100644
--- a/include/drm/drm_encoder.h
+++ b/include/drm/drm_encoder.h
@@ -214,11 +214,12 @@ static inline bool drm_encoder_crtc_ok(struct drm_encoder *encoder,
* drm_mode_object_find().
*/
static inline struct drm_encoder *drm_encoder_find(struct drm_device *dev,
+ struct drm_file *file_priv,
uint32_t id)
{
struct drm_mode_object *mo;
- mo = drm_mode_object_find(dev, id, DRM_MODE_OBJECT_ENCODER);
+ mo = drm_mode_object_find(dev, file_priv, id, DRM_MODE_OBJECT_ENCODER);
return mo ? obj_to_encoder(mo) : NULL;
}
diff --git a/include/drm/drm_framebuffer.h b/include/drm/drm_framebuffer.h
index b6996ddb19d6..4c5ee4ae54df 100644
--- a/include/drm/drm_framebuffer.h
+++ b/include/drm/drm_framebuffer.h
@@ -205,6 +205,7 @@ int drm_framebuffer_init(struct drm_device *dev,
struct drm_framebuffer *fb,
const struct drm_framebuffer_funcs *funcs);
struct drm_framebuffer *drm_framebuffer_lookup(struct drm_device *dev,
+ struct drm_file *file_priv,
uint32_t id);
void drm_framebuffer_remove(struct drm_framebuffer *fb);
void drm_framebuffer_cleanup(struct drm_framebuffer *fb);
diff --git a/include/drm/drm_hdcp.h b/include/drm/drm_hdcp.h
new file mode 100644
index 000000000000..a6de09c5e47f
--- /dev/null
+++ b/include/drm/drm_hdcp.h
@@ -0,0 +1,253 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright (C) 2017 Google, Inc.
+ *
+ * Authors:
+ * Sean Paul <seanpaul@chromium.org>
+ */
+
+#ifndef _DRM_HDCP_H_INCLUDED_
+#define _DRM_HDCP_H_INCLUDED_
+
+/* Period of hdcp checks (to ensure we're still authenticated) */
+#define DRM_HDCP_CHECK_PERIOD_MS (128 * 16)
+
+/* Shared lengths/masks between HDMI/DVI/DisplayPort */
+#define DRM_HDCP_AN_LEN 8
+#define DRM_HDCP_BSTATUS_LEN 2
+#define DRM_HDCP_KSV_LEN 5
+#define DRM_HDCP_RI_LEN 2
+#define DRM_HDCP_V_PRIME_PART_LEN 4
+#define DRM_HDCP_V_PRIME_NUM_PARTS 5
+#define DRM_HDCP_NUM_DOWNSTREAM(x) (x & 0x7f)
+#define DRM_HDCP_MAX_CASCADE_EXCEEDED(x) (x & BIT(3))
+#define DRM_HDCP_MAX_DEVICE_EXCEEDED(x) (x & BIT(7))
+
+/* Slave address for the HDCP registers in the receiver */
+#define DRM_HDCP_DDC_ADDR 0x3A
+
+/* HDCP register offsets for HDMI/DVI devices */
+#define DRM_HDCP_DDC_BKSV 0x00
+#define DRM_HDCP_DDC_RI_PRIME 0x08
+#define DRM_HDCP_DDC_AKSV 0x10
+#define DRM_HDCP_DDC_AN 0x18
+#define DRM_HDCP_DDC_V_PRIME(h) (0x20 + h * 4)
+#define DRM_HDCP_DDC_BCAPS 0x40
+#define DRM_HDCP_DDC_BCAPS_REPEATER_PRESENT BIT(6)
+#define DRM_HDCP_DDC_BCAPS_KSV_FIFO_READY BIT(5)
+#define DRM_HDCP_DDC_BSTATUS 0x41
+#define DRM_HDCP_DDC_KSV_FIFO 0x43
+
+#define DRM_HDCP_1_4_SRM_ID 0x8
+#define DRM_HDCP_1_4_VRL_LENGTH_SIZE 3
+#define DRM_HDCP_1_4_DCP_SIG_SIZE 40
+
+/* Protocol message definition for HDCP2.2 specification */
+/*
+ * Protected content streams are classified into 2 types:
+ * - Type0: Can be transmitted with HDCP 1.4+
+ * - Type1: Can be transmitted with HDCP 2.2+
+ */
+#define HDCP_STREAM_TYPE0 0x00
+#define HDCP_STREAM_TYPE1 0x01
+
+/* HDCP2.2 Msg IDs */
+#define HDCP_2_2_NULL_MSG 1
+#define HDCP_2_2_AKE_INIT 2
+#define HDCP_2_2_AKE_SEND_CERT 3
+#define HDCP_2_2_AKE_NO_STORED_KM 4
+#define HDCP_2_2_AKE_STORED_KM 5
+#define HDCP_2_2_AKE_SEND_HPRIME 7
+#define HDCP_2_2_AKE_SEND_PAIRING_INFO 8
+#define HDCP_2_2_LC_INIT 9
+#define HDCP_2_2_LC_SEND_LPRIME 10
+#define HDCP_2_2_SKE_SEND_EKS 11
+#define HDCP_2_2_REP_SEND_RECVID_LIST 12
+#define HDCP_2_2_REP_SEND_ACK 15
+#define HDCP_2_2_REP_STREAM_MANAGE 16
+#define HDCP_2_2_REP_STREAM_READY 17
+#define HDCP_2_2_ERRATA_DP_STREAM_TYPE 50
+
+#define HDCP_2_2_RTX_LEN 8
+#define HDCP_2_2_RRX_LEN 8
+
+#define HDCP_2_2_K_PUB_RX_MOD_N_LEN 128
+#define HDCP_2_2_K_PUB_RX_EXP_E_LEN 3
+#define HDCP_2_2_K_PUB_RX_LEN (HDCP_2_2_K_PUB_RX_MOD_N_LEN + \
+ HDCP_2_2_K_PUB_RX_EXP_E_LEN)
+
+#define HDCP_2_2_DCP_LLC_SIG_LEN 384
+
+#define HDCP_2_2_E_KPUB_KM_LEN 128
+#define HDCP_2_2_E_KH_KM_M_LEN (16 + 16)
+#define HDCP_2_2_H_PRIME_LEN 32
+#define HDCP_2_2_E_KH_KM_LEN 16
+#define HDCP_2_2_RN_LEN 8
+#define HDCP_2_2_L_PRIME_LEN 32
+#define HDCP_2_2_E_DKEY_KS_LEN 16
+#define HDCP_2_2_RIV_LEN 8
+#define HDCP_2_2_SEQ_NUM_LEN 3
+#define HDCP_2_2_V_PRIME_HALF_LEN (HDCP_2_2_L_PRIME_LEN / 2)
+#define HDCP_2_2_RECEIVER_ID_LEN DRM_HDCP_KSV_LEN
+#define HDCP_2_2_MAX_DEVICE_COUNT 31
+#define HDCP_2_2_RECEIVER_IDS_MAX_LEN (HDCP_2_2_RECEIVER_ID_LEN * \
+ HDCP_2_2_MAX_DEVICE_COUNT)
+#define HDCP_2_2_MPRIME_LEN 32
+
+/* Following Macros take a byte at a time for bit(s) masking */
+/*
+ * TODO: This has to be changed for DP MST, as multiple stream on
+ * same port is possible.
+ * For HDCP2.2 on HDMI and DP SST this value is always 1.
+ */
+#define HDCP_2_2_MAX_CONTENT_STREAMS_CNT 1
+#define HDCP_2_2_TXCAP_MASK_LEN 2
+#define HDCP_2_2_RXCAPS_LEN 3
+#define HDCP_2_2_RX_REPEATER(x) ((x) & BIT(0))
+#define HDCP_2_2_DP_HDCP_CAPABLE(x) ((x) & BIT(1))
+#define HDCP_2_2_RXINFO_LEN 2
+
+/* HDCP1.x compliant device in downstream */
+#define HDCP_2_2_HDCP1_DEVICE_CONNECTED(x) ((x) & BIT(0))
+
+/* HDCP2.0 Compliant repeater in downstream */
+#define HDCP_2_2_HDCP_2_0_REP_CONNECTED(x) ((x) & BIT(1))
+#define HDCP_2_2_MAX_CASCADE_EXCEEDED(x) ((x) & BIT(2))
+#define HDCP_2_2_MAX_DEVS_EXCEEDED(x) ((x) & BIT(3))
+#define HDCP_2_2_DEV_COUNT_LO(x) (((x) & (0xF << 4)) >> 4)
+#define HDCP_2_2_DEV_COUNT_HI(x) ((x) & BIT(0))
+#define HDCP_2_2_DEPTH(x) (((x) & (0x7 << 1)) >> 1)
+
+struct hdcp2_cert_rx {
+ u8 receiver_id[HDCP_2_2_RECEIVER_ID_LEN];
+ u8 kpub_rx[HDCP_2_2_K_PUB_RX_LEN];
+ u8 reserved[2];
+ u8 dcp_signature[HDCP_2_2_DCP_LLC_SIG_LEN];
+} __packed;
+
+struct hdcp2_streamid_type {
+ u8 stream_id;
+ u8 stream_type;
+} __packed;
+
+/*
+ * The TxCaps field specified in the HDCP HDMI, DP specs
+ * This field is big endian as specified in the errata.
+ */
+struct hdcp2_tx_caps {
+ /* Transmitter must set this to 0x2 */
+ u8 version;
+
+ /* Reserved for HDCP and DP Spec. Read as Zero */
+ u8 tx_cap_mask[HDCP_2_2_TXCAP_MASK_LEN];
+} __packed;
+
+/* Main structures for HDCP2.2 protocol communication */
+struct hdcp2_ake_init {
+ u8 msg_id;
+ u8 r_tx[HDCP_2_2_RTX_LEN];
+ struct hdcp2_tx_caps tx_caps;
+} __packed;
+
+struct hdcp2_ake_send_cert {
+ u8 msg_id;
+ struct hdcp2_cert_rx cert_rx;
+ u8 r_rx[HDCP_2_2_RRX_LEN];
+ u8 rx_caps[HDCP_2_2_RXCAPS_LEN];
+} __packed;
+
+struct hdcp2_ake_no_stored_km {
+ u8 msg_id;
+ u8 e_kpub_km[HDCP_2_2_E_KPUB_KM_LEN];
+} __packed;
+
+struct hdcp2_ake_stored_km {
+ u8 msg_id;
+ u8 e_kh_km_m[HDCP_2_2_E_KH_KM_M_LEN];
+} __packed;
+
+struct hdcp2_ake_send_hprime {
+ u8 msg_id;
+ u8 h_prime[HDCP_2_2_H_PRIME_LEN];
+} __packed;
+
+struct hdcp2_ake_send_pairing_info {
+ u8 msg_id;
+ u8 e_kh_km[HDCP_2_2_E_KH_KM_LEN];
+} __packed;
+
+struct hdcp2_lc_init {
+ u8 msg_id;
+ u8 r_n[HDCP_2_2_RN_LEN];
+} __packed;
+
+struct hdcp2_lc_send_lprime {
+ u8 msg_id;
+ u8 l_prime[HDCP_2_2_L_PRIME_LEN];
+} __packed;
+
+struct hdcp2_ske_send_eks {
+ u8 msg_id;
+ u8 e_dkey_ks[HDCP_2_2_E_DKEY_KS_LEN];
+ u8 riv[HDCP_2_2_RIV_LEN];
+} __packed;
+
+struct hdcp2_rep_send_receiverid_list {
+ u8 msg_id;
+ u8 rx_info[HDCP_2_2_RXINFO_LEN];
+ u8 seq_num_v[HDCP_2_2_SEQ_NUM_LEN];
+ u8 v_prime[HDCP_2_2_V_PRIME_HALF_LEN];
+ u8 receiver_ids[HDCP_2_2_RECEIVER_IDS_MAX_LEN];
+} __packed;
+
+struct hdcp2_rep_send_ack {
+ u8 msg_id;
+ u8 v[HDCP_2_2_V_PRIME_HALF_LEN];
+} __packed;
+
+struct hdcp2_rep_stream_manage {
+ u8 msg_id;
+ u8 seq_num_m[HDCP_2_2_SEQ_NUM_LEN];
+ __be16 k;
+ struct hdcp2_streamid_type streams[HDCP_2_2_MAX_CONTENT_STREAMS_CNT];
+} __packed;
+
+struct hdcp2_rep_stream_ready {
+ u8 msg_id;
+ u8 m_prime[HDCP_2_2_MPRIME_LEN];
+} __packed;
+
+struct hdcp2_dp_errata_stream_type {
+ u8 msg_id;
+ u8 stream_type;
+} __packed;
+
+/* HDCP2.2 TIMEOUTs in mSec */
+#define HDCP_2_2_CERT_TIMEOUT_MS 100
+#define HDCP_2_2_HPRIME_NO_PAIRED_TIMEOUT_MS 1000
+#define HDCP_2_2_HPRIME_PAIRED_TIMEOUT_MS 200
+#define HDCP_2_2_PAIRING_TIMEOUT_MS 200
+#define HDCP_2_2_HDMI_LPRIME_TIMEOUT_MS 20
+#define HDCP_2_2_DP_LPRIME_TIMEOUT_MS 7
+#define HDCP_2_2_RECVID_LIST_TIMEOUT_MS 3000
+#define HDCP_2_2_STREAM_READY_TIMEOUT_MS 100
+
+/* HDMI HDCP2.2 Register Offsets */
+#define HDCP_2_2_HDMI_REG_VER_OFFSET 0x50
+#define HDCP_2_2_HDMI_REG_WR_MSG_OFFSET 0x60
+#define HDCP_2_2_HDMI_REG_RXSTATUS_OFFSET 0x70
+#define HDCP_2_2_HDMI_REG_RD_MSG_OFFSET 0x80
+#define HDCP_2_2_HDMI_REG_DBG_OFFSET 0xC0
+
+#define HDCP_2_2_HDMI_SUPPORT_MASK BIT(2)
+#define HDCP_2_2_RX_CAPS_VERSION_VAL 0x02
+#define HDCP_2_2_SEQ_NUM_MAX 0xFFFFFF
+#define HDCP_2_2_DELAY_BEFORE_ENCRYPTION_EN 200
+
+/* Below macros take a byte at a time and mask the bit(s) */
+#define HDCP_2_2_HDMI_RXSTATUS_LEN 2
+#define HDCP_2_2_HDMI_RXSTATUS_MSG_SZ_HI(x) ((x) & 0x3)
+#define HDCP_2_2_HDMI_RXSTATUS_READY(x) ((x) & BIT(2))
+#define HDCP_2_2_HDMI_RXSTATUS_REAUTH_REQ(x) ((x) & BIT(3))
+
+#endif
diff --git a/include/drm/drm_lease.h b/include/drm/drm_lease.h
new file mode 100644
index 000000000000..fbc0ab54855b
--- /dev/null
+++ b/include/drm/drm_lease.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright © 2017 Keith Packard <keithp@keithp.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.
+ */
+
+#ifndef _DRM_LEASE_H_
+#define _DRM_LEASE_H_
+
+struct drm_file;
+struct drm_device;
+struct drm_master;
+
+struct drm_master *drm_lease_owner(struct drm_master *master);
+
+void drm_lease_destroy(struct drm_master *lessee);
+
+bool drm_lease_held(struct drm_file *file_priv, int id);
+
+bool _drm_lease_held(struct drm_file *file_priv, int id);
+
+void drm_lease_revoke(struct drm_master *master);
+
+uint32_t drm_lease_filter_crtcs(struct drm_file *file_priv, uint32_t crtcs);
+
+int drm_mode_create_lease_ioctl(struct drm_device *dev,
+ void *data, struct drm_file *file_priv);
+
+int drm_mode_list_lessees_ioctl(struct drm_device *dev,
+ void *data, struct drm_file *file_priv);
+
+int drm_mode_get_lease_ioctl(struct drm_device *dev,
+ void *data, struct drm_file *file_priv);
+
+int drm_mode_revoke_lease_ioctl(struct drm_device *dev,
+ void *data, struct drm_file *file_priv);
+
+#endif /* _DRM_LEASE_H_ */
diff --git a/include/drm/drm_mode_config.h b/include/drm/drm_mode_config.h
index 1b37368416c8..bb037f6bee60 100644
--- a/include/drm/drm_mode_config.h
+++ b/include/drm/drm_mode_config.h
@@ -703,6 +703,11 @@ struct drm_mode_config {
*/
struct drm_property *aspect_ratio_property;
/**
+ * @content_type_property: Optional connector property to control the
+ * HDMI infoframe content type setting.
+ */
+ struct drm_property *content_type_property;
+ /**
* @degamma_lut_property: Optional CRTC property to set the LUT used to
* convert the framebuffer's colors to linear gamma.
*/
@@ -735,12 +740,26 @@ struct drm_mode_config {
* the position of the output on the host's screen.
*/
struct drm_property *suggested_x_property;
+
+ /**
+ * @non_desktop_property: Optional connector property with a hint
+ * that device isn't a standard display, and the console/desktop
+ * should not be displayed on it.
+ */
+ struct drm_property *non_desktop_property;
+
/**
* @suggested_y_property: Optional connector property with a hint for
* the position of the output on the host's screen.
*/
struct drm_property *suggested_y_property;
+ /**
+ * hdr_metadata_property: Connector property containing hdr metatda
+ * This will be provided by userspace compositors based on HDR content
+ */
+ struct drm_property *hdr_source_metadata_property;
+
/* dumb ioctl parameters */
uint32_t preferred_depth, prefer_shadow;
@@ -766,6 +785,15 @@ struct drm_mode_config {
/* cursor size */
uint32_t cursor_width, cursor_height;
+ /**
+ * @suspend_state:
+ *
+ * Atomic state when suspended.
+ * Set by drm_mode_config_helper_suspend() and cleared by
+ * drm_mode_config_helper_resume().
+ */
+ struct drm_atomic_state *suspend_state;
+
const struct drm_mode_config_helper_funcs *helper_private;
};
diff --git a/include/drm/drm_mode_object.h b/include/drm/drm_mode_object.h
index a767b4a30a6d..7ba3913f30b5 100644
--- a/include/drm/drm_mode_object.h
+++ b/include/drm/drm_mode_object.h
@@ -24,9 +24,11 @@
#define __DRM_MODESET_H__
#include <linux/kref.h>
+#include <drm/drm_lease.h>
struct drm_object_properties;
struct drm_property;
struct drm_device;
+struct drm_file;
/**
* struct drm_mode_object - base structure for modeset objects
@@ -113,6 +115,7 @@ struct drm_object_properties {
}
struct drm_mode_object *drm_mode_object_find(struct drm_device *dev,
+ struct drm_file *file_priv,
uint32_t id, uint32_t type);
void drm_mode_object_get(struct drm_mode_object *obj);
void drm_mode_object_put(struct drm_mode_object *obj);
@@ -151,4 +154,6 @@ int drm_object_property_get_value(struct drm_mode_object *obj,
void drm_object_attach_property(struct drm_mode_object *obj,
struct drm_property *property,
uint64_t init_val);
+
+bool drm_mode_object_lease_required(uint32_t type);
#endif
diff --git a/include/drm/drm_modeset_helper.h b/include/drm/drm_modeset_helper.h
index cb0ec92e11e6..efa337f03129 100644
--- a/include/drm/drm_modeset_helper.h
+++ b/include/drm/drm_modeset_helper.h
@@ -34,4 +34,7 @@ void drm_helper_mode_fill_fb_struct(struct drm_device *dev,
int drm_crtc_init(struct drm_device *dev, struct drm_crtc *crtc,
const struct drm_crtc_funcs *funcs);
+int drm_mode_config_helper_suspend(struct drm_device *dev);
+int drm_mode_config_helper_resume(struct drm_device *dev);
+
#endif
diff --git a/include/drm/drm_of.h b/include/drm/drm_of.h
index 4f835490d77a..c0bd3dff0191 100644
--- a/include/drm/drm_of.h
+++ b/include/drm/drm_of.h
@@ -4,6 +4,7 @@
#include <linux/of_graph.h>
+struct component_match;
struct component_master_ops;
struct component_match;
struct device;
@@ -20,6 +21,10 @@ void drm_of_component_match_add(struct device *master,
struct component_match **matchptr,
int (*compare)(struct device *, void *),
struct device_node *node);
+extern int drm_of_component_probe_with_match(struct device *dev,
+ struct component_match *match,
+ int (*compare_of)(struct device *, void *),
+ const struct component_master_ops *m_ops);
int drm_of_component_probe(struct device *dev,
int (*compare_of)(struct device *, void *),
const struct component_master_ops *m_ops);
@@ -45,6 +50,14 @@ drm_of_component_match_add(struct device *master,
{
}
+static int drm_of_component_probe_with_match(struct device *dev,
+ struct component_match *match,
+ int (*compare_of)(struct device *, void *),
+ const struct component_master_ops *m_ops)
+{
+ return -EINVAL;
+}
+
static inline int
drm_of_component_probe(struct device *dev,
int (*compare_of)(struct device *, void *),
diff --git a/include/drm/drm_plane.h b/include/drm/drm_plane.h
index 73f90f9d057f..4ccf52f1c12a 100644
--- a/include/drm/drm_plane.h
+++ b/include/drm/drm_plane.h
@@ -515,6 +515,9 @@ struct drm_plane {
enum drm_plane_type type;
+ /* Value of true:1 means HDR is supported */
+ bool hdr_supported;
+
/**
* @index: Position inside the mode_config.list, can be used as an array
* index. It is invariant over the lifetime of the plane.
@@ -589,10 +592,11 @@ int drm_mode_plane_set_obj_prop(struct drm_plane *plane,
* drm_mode_object_find().
*/
static inline struct drm_plane *drm_plane_find(struct drm_device *dev,
+ struct drm_file *file_priv,
uint32_t id)
{
struct drm_mode_object *mo;
- mo = drm_mode_object_find(dev, id, DRM_MODE_OBJECT_PLANE);
+ mo = drm_mode_object_find(dev, file_priv, id, DRM_MODE_OBJECT_PLANE);
return mo ? obj_to_plane(mo) : NULL;
}
diff --git a/include/drm/drm_property.h b/include/drm/drm_property.h
index 37355c623e6c..429d8218f740 100644
--- a/include/drm/drm_property.h
+++ b/include/drm/drm_property.h
@@ -312,10 +312,11 @@ drm_property_unreference_blob(struct drm_property_blob *blob)
* This function looks up the property object specified by id and returns it.
*/
static inline struct drm_property *drm_property_find(struct drm_device *dev,
+ struct drm_file *file_priv,
uint32_t id)
{
struct drm_mode_object *mo;
- mo = drm_mode_object_find(dev, id, DRM_MODE_OBJECT_PROPERTY);
+ mo = drm_mode_object_find(dev, file_priv, id, DRM_MODE_OBJECT_PROPERTY);
return mo ? obj_to_property(mo) : NULL;
}
diff --git a/include/drm/drm_simple_kms_helper.h b/include/drm/drm_simple_kms_helper.h
index 6d9adbb46293..d9e4c3c3f009 100644
--- a/include/drm/drm_simple_kms_helper.h
+++ b/include/drm/drm_simple_kms_helper.h
@@ -22,6 +22,20 @@ struct drm_simple_display_pipe;
*/
struct drm_simple_display_pipe_funcs {
/**
+ * @mode_valid:
+ *
+ * This function is called to filter out valid modes from the
+ * suggestions suggested by the bridge or display. This optional
+ * hook is passed in when initializing the pipeline.
+ *
+ * RETURNS:
+ *
+ * drm_mode_status Enum
+ */
+ enum drm_mode_status (*mode_valid)(struct drm_crtc *crtc,
+ const struct drm_display_mode *mode);
+
+ /**
* @enable:
*
* This function should be used to enable the pipeline.
diff --git a/include/dt-bindings/clock/imx6qdl-clock.h b/include/dt-bindings/clock/imx6qdl-clock.h
index da59fd9cdb5e..2a25fdb2d9b8 100644
--- a/include/dt-bindings/clock/imx6qdl-clock.h
+++ b/include/dt-bindings/clock/imx6qdl-clock.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2014 Freescale Semiconductor, Inc.
+ * Copyright (C) 2015 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
@@ -271,6 +271,13 @@
#define IMX6QDL_CLK_PRE_AXI 258
#define IMX6QDL_CLK_MLB_SEL 259
#define IMX6QDL_CLK_MLB_PODF 260
-#define IMX6QDL_CLK_END 261
+#define IMX6QDL_CLK_AXI_ALT_SEL 261
+#define IMX6QDL_CLK_LDB_DI0_DIV_7 262
+#define IMX6QDL_CLK_LDB_DI1_DIV_7 263
+#define IMX6QDL_CLK_LDB_DI0_DIV_SEL 264
+#define IMX6QDL_CLK_LDB_DI1_DIV_SEL 265
+#define IMX6QDL_CLK_DCIC1 266
+#define IMX6QDL_CLK_DCIC2 267
+#define IMX6QDL_CLK_END 268
#endif /* __DT_BINDINGS_CLOCK_IMX6QDL_H */
diff --git a/include/dt-bindings/clock/imx6sl-clock.h b/include/dt-bindings/clock/imx6sl-clock.h
index e14573e293c5..6bc731e00a89 100644
--- a/include/dt-bindings/clock/imx6sl-clock.h
+++ b/include/dt-bindings/clock/imx6sl-clock.h
@@ -175,6 +175,7 @@
#define IMX6SL_CLK_SSI2_IPG 162
#define IMX6SL_CLK_SSI3_IPG 163
#define IMX6SL_CLK_SPDIF_GCLK 164
-#define IMX6SL_CLK_END 165
+#define IMX6SL_CLK_UART_OSC_4M 165
+#define IMX6SL_CLK_END 166
#endif /* __DT_BINDINGS_CLOCK_IMX6SL_H */
diff --git a/include/dt-bindings/clock/imx6sll-clock.h b/include/dt-bindings/clock/imx6sll-clock.h
new file mode 100644
index 000000000000..b68a89ee82cd
--- /dev/null
+++ b/include/dt-bindings/clock/imx6sll-clock.h
@@ -0,0 +1,206 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017 NXP.
+ *
+ * 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 __DT_BINDINGS_CLOCK_IMX6SLL_H
+#define __DT_BINDINGS_CLOCK_IMX6SLL_H
+
+#define IMX6SLL_CLK_DUMMY 0
+#define IMX6SLL_CLK_CKIL 1
+#define IMX6SLL_CLK_OSC 2
+#define IMX6SLL_PLL1_BYPASS_SRC 3
+#define IMX6SLL_PLL2_BYPASS_SRC 4
+#define IMX6SLL_PLL3_BYPASS_SRC 5
+#define IMX6SLL_PLL4_BYPASS_SRC 6
+#define IMX6SLL_PLL5_BYPASS_SRC 7
+#define IMX6SLL_PLL6_BYPASS_SRC 8
+#define IMX6SLL_PLL7_BYPASS_SRC 9
+#define IMX6SLL_CLK_PLL1 10
+#define IMX6SLL_CLK_PLL2 11
+#define IMX6SLL_CLK_PLL3 12
+#define IMX6SLL_CLK_PLL4 13
+#define IMX6SLL_CLK_PLL5 14
+#define IMX6SLL_CLK_PLL6 15
+#define IMX6SLL_CLK_PLL7 16
+#define IMX6SLL_PLL1_BYPASS 17
+#define IMX6SLL_PLL2_BYPASS 18
+#define IMX6SLL_PLL3_BYPASS 19
+#define IMX6SLL_PLL4_BYPASS 20
+#define IMX6SLL_PLL5_BYPASS 21
+#define IMX6SLL_PLL6_BYPASS 22
+#define IMX6SLL_PLL7_BYPASS 23
+#define IMX6SLL_CLK_PLL1_SYS 24
+#define IMX6SLL_CLK_PLL2_BUS 25
+#define IMX6SLL_CLK_PLL3_USB_OTG 26
+#define IMX6SLL_CLK_PLL4_AUDIO 27
+#define IMX6SLL_CLK_PLL5_VIDEO 28
+#define IMX6SLL_CLK_PLL6_ENET 29
+#define IMX6SLL_CLK_PLL7_USB_HOST 30
+#define IMX6SLL_CLK_USBPHY1 31
+#define IMX6SLL_CLK_USBPHY2 32
+#define IMX6SLL_CLK_USBPHY1_GATE 33
+#define IMX6SLL_CLK_USBPHY2_GATE 34
+#define IMX6SLL_CLK_PLL2_PFD0 35
+#define IMX6SLL_CLK_PLL2_PFD1 36
+#define IMX6SLL_CLK_PLL2_PFD2 37
+#define IMX6SLL_CLK_PLL2_PFD3 38
+#define IMX6SLL_CLK_PLL3_PFD0 39
+#define IMX6SLL_CLK_PLL3_PFD1 40
+#define IMX6SLL_CLK_PLL3_PFD2 41
+#define IMX6SLL_CLK_PLL3_PFD3 42
+#define IMX6SLL_CLK_PLL4_POST_DIV 43
+#define IMX6SLL_CLK_PLL4_AUDIO_DIV 44
+#define IMX6SLL_CLK_PLL5_POST_DIV 45
+#define IMX6SLL_CLK_PLL5_VIDEO_DIV 46
+#define IMX6SLL_CLK_PLL2_198M 47
+#define IMX6SLL_CLK_PLL3_120M 48
+#define IMX6SLL_CLK_PLL3_80M 49
+#define IMX6SLL_CLK_PLL3_60M 50
+#define IMX6SLL_CLK_STEP 51
+#define IMX6SLL_CLK_PLL1_SW 52
+#define IMX6SLL_CLK_AXI_ALT_SEL 53
+#define IMX6SLL_CLK_AXI_SEL 54
+#define IMX6SLL_CLK_PERIPH_PRE 55
+#define IMX6SLL_CLK_PERIPH2_PRE 56
+#define IMX6SLL_CLK_PERIPH_CLK2_SEL 57
+#define IMX6SLL_CLK_PERIPH2_CLK2_SEL 58
+#define IMX6SLL_CLK_PERCLK_SEL 59
+#define IMX6SLL_CLK_USDHC1_SEL 60
+#define IMX6SLL_CLK_USDHC2_SEL 61
+#define IMX6SLL_CLK_USDHC3_SEL 62
+#define IMX6SLL_CLK_SSI1_SEL 63
+#define IMX6SLL_CLK_SSI2_SEL 64
+#define IMX6SLL_CLK_SSI3_SEL 65
+#define IMX6SLL_CLK_PXP_SEL 66
+#define IMX6SLL_CLK_LCDIF_PRE_SEL 67
+#define IMX6SLL_CLK_LCDIF_SEL 68
+#define IMX6SLL_CLK_EPDC_PRE_SEL 69
+#define IMX6SLL_CLK_SPDIF_SEL 70
+#define IMX6SLL_CLK_ECSPI_SEL 71
+#define IMX6SLL_CLK_UART_SEL 72
+#define IMX6SLL_CLK_ARM 73
+#define IMX6SLL_CLK_PERIPH 74
+#define IMX6SLL_CLK_PERIPH2 75
+#define IMX6SLL_CLK_PERIPH2_CLK2 76
+#define IMX6SLL_CLK_PERIPH_CLK2 77
+#define IMX6SLL_CLK_MMDC_PODF 78
+#define IMX6SLL_CLK_AXI_PODF 79
+#define IMX6SLL_CLK_AHB 80
+#define IMX6SLL_CLK_IPG 81
+#define IMX6SLL_CLK_PERCLK 82
+#define IMX6SLL_CLK_USDHC1_PODF 83
+#define IMX6SLL_CLK_USDHC2_PODF 84
+#define IMX6SLL_CLK_USDHC3_PODF 85
+#define IMX6SLL_CLK_SSI1_PRED 86
+#define IMX6SLL_CLK_SSI2_PRED 87
+#define IMX6SLL_CLK_SSI3_PRED 88
+#define IMX6SLL_CLK_SSI1_PODF 89
+#define IMX6SLL_CLK_SSI2_PODF 90
+#define IMX6SLL_CLK_SSI3_PODF 91
+#define IMX6SLL_CLK_PXP_PODF 92
+#define IMX6SLL_CLK_LCDIF_PRED 93
+#define IMX6SLL_CLK_LCDIF_PODF 94
+#define IMX6SLL_CLK_EPDC_SEL 95
+#define IMX6SLL_CLK_EPDC_PODF 96
+#define IMX6SLL_CLK_SPDIF_PRED 97
+#define IMX6SLL_CLK_SPDIF_PODF 98
+#define IMX6SLL_CLK_ECSPI_PODF 99
+#define IMX6SLL_CLK_UART_PODF 100
+
+/* CCGR 0 */
+#define IMX6SLL_CLK_AIPSTZ1 101
+#define IMX6SLL_CLK_AIPSTZ2 102
+#define IMX6SLL_CLK_DCP 103
+#define IMX6SLL_CLK_UART2_IPG 104
+#define IMX6SLL_CLK_UART2_SERIAL 105
+
+/* CCGR 1 */
+#define IMX6SLL_CLK_ECSPI1 106
+#define IMX6SLL_CLK_ECSPI2 107
+#define IMX6SLL_CLK_ECSPI3 108
+#define IMX6SLL_CLK_ECSPI4 109
+#define IMX6SLL_CLK_UART3_IPG 110
+#define IMX6SLL_CLK_UART3_SERIAL 111
+#define IMX6SLL_CLK_UART4_IPG 112
+#define IMX6SLL_CLK_UART4_SERIAL 113
+#define IMX6SLL_CLK_EPIT1 114
+#define IMX6SLL_CLK_EPIT2 115
+#define IMX6SLL_CLK_GPT_BUS 116
+#define IMX6SLL_CLK_GPT_SERIAL 117
+
+/* CCGR2 */
+#define IMX6SLL_CLK_CSI 118
+#define IMX6SLL_CLK_I2C1 119
+#define IMX6SLL_CLK_I2C2 120
+#define IMX6SLL_CLK_I2C3 121
+#define IMX6SLL_CLK_OCOTP 122
+#define IMX6SLL_CLK_LCDIF_APB 123
+#define IMX6SLL_CLK_PXP 124
+
+/* CCGR3 */
+#define IMX6SLL_CLK_UART5_IPG 125
+#define IMX6SLL_CLK_UART5_SERIAL 126
+#define IMX6SLL_CLK_EPDC_AXI 127
+#define IMX6SLL_CLK_EPDC_PIX 128
+#define IMX6SLL_CLK_LCDIF_PIX 129
+#define IMX6SLL_CLK_WDOG1 130
+#define IMX6SLL_CLK_MMDC_P0_FAST 131
+#define IMX6SLL_CLK_MMDC_P0_IPG 132
+#define IMX6SLL_CLK_OCRAM 133
+
+/* CCGR4 */
+#define IMX6SLL_CLK_PWM1 134
+#define IMX6SLL_CLK_PWM2 135
+#define IMX6SLL_CLK_PWM3 136
+#define IMX6SLL_CLK_PWM4 137
+
+/* CCGR 5 */
+#define IMX6SLL_CLK_ROM 138
+#define IMX6SLL_CLK_SDMA 139
+#define IMX6SLL_CLK_KPP 140
+#define IMX6SLL_CLK_WDOG2 141
+#define IMX6SLL_CLK_SPBA 142
+#define IMX6SLL_CLK_SPDIF 143
+#define IMX6SLL_CLK_SPDIF_GCLK 144
+#define IMX6SLL_CLK_SSI1 145
+#define IMX6SLL_CLK_SSI1_IPG 146
+#define IMX6SLL_CLK_SSI2 147
+#define IMX6SLL_CLK_SSI2_IPG 148
+#define IMX6SLL_CLK_SSI3 149
+#define IMX6SLL_CLK_SSI3_IPG 150
+#define IMX6SLL_CLK_UART1_IPG 151
+#define IMX6SLL_CLK_UART1_SERIAL 152
+
+/* CCGR 6 */
+#define IMX6SLL_CLK_USBOH3 153
+#define IMX6SLL_CLK_USDHC1 154
+#define IMX6SLL_CLK_USDHC2 155
+#define IMX6SLL_CLK_USDHC3 156
+
+#define IMX6SLL_CLK_IPP_DI0 157
+#define IMX6SLL_CLK_IPP_DI1 158
+#define IMX6SLL_CLK_LDB_DI0_SEL 159
+#define IMX6SLL_CLK_LDB_DI0_DIV_3_5 160
+#define IMX6SLL_CLK_LDB_DI0_DIV_7 161
+#define IMX6SLL_CLK_LDB_DI0_DIV_SEL 162
+#define IMX6SLL_CLK_LDB_DI0 163
+#define IMX6SLL_CLK_LDB_DI1_SEL 164
+#define IMX6SLL_CLK_LDB_DI1_DIV_3_5 165
+#define IMX6SLL_CLK_LDB_DI1_DIV_7 166
+#define IMX6SLL_CLK_LDB_DI1_DIV_SEL 167
+#define IMX6SLL_CLK_LDB_DI1 168
+#define IMX6SLL_CLK_EXTERN_AUDIO_SEL 169
+#define IMX6SLL_CLK_EXTERN_AUDIO_PRED 170
+#define IMX6SLL_CLK_EXTERN_AUDIO_PODF 171
+#define IMX6SLL_CLK_EXTERN_AUDIO 172
+#define IMX6SLL_CLK_GPT_3M 173
+
+#define IMX6SLL_CLK_END 174
+
+#endif /* __DT_BINDINGS_CLOCK_IMX6SLL_H */
diff --git a/include/dt-bindings/clock/imx6sx-clock.h b/include/dt-bindings/clock/imx6sx-clock.h
index 36f0324902a5..a248f928a30a 100644
--- a/include/dt-bindings/clock/imx6sx-clock.h
+++ b/include/dt-bindings/clock/imx6sx-clock.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2014 Freescale Semiconductor, Inc.
+ * Copyright (C) 2014-2015 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
@@ -275,6 +275,10 @@
#define IMX6SX_PLL6_BYPASS 262
#define IMX6SX_PLL7_BYPASS 263
#define IMX6SX_CLK_SPDIF_GCLK 264
-#define IMX6SX_CLK_CLK_END 265
+#define IMX6SX_CLK_LVDS2_SEL 265
+#define IMX6SX_CLK_LVDS2_OUT 266
+#define IMX6SX_CLK_LVDS2_IN 267
+#define IMX6SX_CLK_ANACLK2 268
+#define IMX6SX_CLK_CLK_END 269
#endif /* __DT_BINDINGS_CLOCK_IMX6SX_H */
diff --git a/include/dt-bindings/clock/imx7d-clock.h b/include/dt-bindings/clock/imx7d-clock.h
index de62a83b6c80..6b5d908d303e 100644
--- a/include/dt-bindings/clock/imx7d-clock.h
+++ b/include/dt-bindings/clock/imx7d-clock.h
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2014-2015 Freescale Semiconductor, Inc.
+ * Copyright 2017 NXP.
*
* 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
@@ -80,10 +81,10 @@
#define IMX7D_ARM_M4_ROOT_SRC 67
#define IMX7D_ARM_M4_ROOT_CG 68
#define IMX7D_ARM_M4_ROOT_DIV 69
-#define IMX7D_ARM_M0_ROOT_CLK 70
-#define IMX7D_ARM_M0_ROOT_SRC 71
-#define IMX7D_ARM_M0_ROOT_CG 72
-#define IMX7D_ARM_M0_ROOT_DIV 73
+#define IMX7D_ARM_M0_ROOT_CLK 70 /* unused */
+#define IMX7D_ARM_M0_ROOT_SRC 71 /* unused */
+#define IMX7D_ARM_M0_ROOT_CG 72 /* unused */
+#define IMX7D_ARM_M0_ROOT_DIV 73 /* unused */
#define IMX7D_MAIN_AXI_ROOT_CLK 74
#define IMX7D_MAIN_AXI_ROOT_SRC 75
#define IMX7D_MAIN_AXI_ROOT_CG 76
@@ -452,5 +453,11 @@
#define IMX7D_OCOTP_CLK 439
#define IMX7D_NAND_RAWNAND_CLK 440
#define IMX7D_NAND_USDHC_BUS_RAWNAND_CLK 441
-#define IMX7D_CLK_END 442
+#define IMX7D_CAAM_CLK 442
+#define IMX7D_PXP_IPG_CLK 443
+#define IMX7D_PXP_AXI_CLK 444
+#define IMX7D_ENET1_IPG_ROOT_CLK 445
+#define IMX7D_ENET2_IPG_ROOT_CLK 446
+#define IMX7D_CLK_END 447
+
#endif /* __DT_BINDINGS_CLOCK_IMX7D_H */
diff --git a/include/dt-bindings/clock/imx7ulp-clock.h b/include/dt-bindings/clock/imx7ulp-clock.h
new file mode 100644
index 000000000000..28413e25bc67
--- /dev/null
+++ b/include/dt-bindings/clock/imx7ulp-clock.h
@@ -0,0 +1,169 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017 NXP.
+ *
+ * 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 __DT_BINDINGS_CLOCK_IMX7ULP_H
+#define __DT_BINDINGS_CLOCK_IMX7ULP_H
+
+#define IMX7ULP_CLK_DUMMY 0
+#define IMX7ULP_CLK_ROSC 1
+#define IMX7ULP_CLK_SOSC 2
+#define IMX7ULP_CLK_FIRC 3
+
+/* SCG1 */
+#define IMX7ULP_CLK_SPLL_PRE_SEL 4
+#define IMX7ULP_CLK_SPLL_PRE_DIV 5
+#define IMX7ULP_CLK_SPLL 6
+#define IMX7ULP_CLK_SPLL_POST_DIV1 7
+#define IMX7ULP_CLK_SPLL_POST_DIV2 8
+#define IMX7ULP_CLK_SPLL_PFD0 9
+#define IMX7ULP_CLK_SPLL_PFD1 10
+#define IMX7ULP_CLK_SPLL_PFD2 11
+#define IMX7ULP_CLK_SPLL_PFD3 12
+#define IMX7ULP_CLK_SPLL_PFD_SEL 13
+#define IMX7ULP_CLK_SPLL_SEL 14
+#define IMX7ULP_CLK_APLL_PRE_SEL 15
+#define IMX7ULP_CLK_APLL_PRE_DIV 16
+#define IMX7ULP_CLK_APLL 17
+#define IMX7ULP_CLK_APLL_POST_DIV1 18
+#define IMX7ULP_CLK_APLL_POST_DIV2 19
+#define IMX7ULP_CLK_APLL_PFD0 20
+#define IMX7ULP_CLK_APLL_PFD1 21
+#define IMX7ULP_CLK_APLL_PFD2 22
+#define IMX7ULP_CLK_APLL_PFD3 23
+#define IMX7ULP_CLK_APLL_PFD_SEL 24
+#define IMX7ULP_CLK_APLL_SEL 25
+#define IMX7ULP_CLK_UPLL 26
+#define IMX7ULP_CLK_SYS_SEL 27
+#define IMX7ULP_CLK_CORE_DIV 28
+#define IMX7ULP_CLK_BUS_DIV 29
+#define IMX7ULP_CLK_PLAT_DIV 30
+#define IMX7ULP_CLK_DDR_SEL 31
+#define IMX7ULP_CLK_DDR_DIV 32
+#define IMX7ULP_CLK_NIC_SEL 33
+#define IMX7ULP_CLK_NIC0_DIV 34
+#define IMX7ULP_CLK_GPU_DIV 35
+#define IMX7ULP_CLK_NIC1_DIV 36
+#define IMX7ULP_CLK_NIC1_BUS_DIV 37
+#define IMX7ULP_CLK_NIC1_EXT_DIV 38
+
+/* PCG2 */
+#define IMX7ULP_CLK_DMA1 39
+#define IMX7ULP_CLK_RGPIO2P1 40
+#define IMX7ULP_CLK_FLEXBUS 41
+#define IMX7ULP_CLK_SEMA42_1 42
+#define IMX7ULP_CLK_DMA_MUX1 43
+#define IMX7ULP_CLK_SNVS 44
+#define IMX7ULP_CLK_CAAM 45
+#define IMX7ULP_CLK_LPTPM4 46
+#define IMX7ULP_CLK_LPTPM5 47
+#define IMX7ULP_CLK_LPIT1 48
+#define IMX7ULP_CLK_LPSPI2 49
+#define IMX7ULP_CLK_LPSPI3 50
+#define IMX7ULP_CLK_LPI2C4 51
+#define IMX7ULP_CLK_LPI2C5 52
+#define IMX7ULP_CLK_LPUART4 53
+#define IMX7ULP_CLK_LPUART5 54
+#define IMX7ULP_CLK_FLEXIO1 55
+#define IMX7ULP_CLK_USB0 56
+#define IMX7ULP_CLK_USB1 57
+#define IMX7ULP_CLK_USB_PHY 58
+#define IMX7ULP_CLK_USB_PL301 59
+#define IMX7ULP_CLK_USDHC0 60
+#define IMX7ULP_CLK_USDHC1 61
+#define IMX7ULP_CLK_WDG1 62
+#define IMX7ULP_CLK_WDG2 63
+
+/* PCG3 */
+#define IMX7ULP_CLK_LPTPM6 64
+#define IMX7ULP_CLK_LPTPM7 65
+#define IMX7ULP_CLK_LPI2C6 66
+#define IMX7ULP_CLK_LPI2C7 67
+#define IMX7ULP_CLK_LPUART6 68
+#define IMX7ULP_CLK_LPUART7 69
+#define IMX7ULP_CLK_VIU 70
+#define IMX7ULP_CLK_DSI 71
+#define IMX7ULP_CLK_LCDIF 72
+#define IMX7ULP_CLK_MMDC 73
+#define IMX7ULP_CLK_PCTLC 74
+#define IMX7ULP_CLK_PCTLD 75
+#define IMX7ULP_CLK_PCTLE 76
+#define IMX7ULP_CLK_PCTLF 77
+#define IMX7ULP_CLK_GPU3D 78
+#define IMX7ULP_CLK_GPU2D 79
+
+#define IMX7ULP_CLK_MIPI_PLL 80
+#define IMX7ULP_CLK_SIRC 81
+
+#define IMX7ULP_CLK_SCG1_CLKOUT 82
+#define IMX7ULP_CLK_HSRUN_SYS_SEL 83
+#define IMX7ULP_CLK_HSRUN_CORE 84
+#define IMX7ULP_CLK_ARM 85
+
+#define IMX7ULP_CLK_SOSC_BUS_CLK 86
+#define IMX7ULP_CLK_FIRC_BUS_CLK 87
+#define IMX7ULP_CLK_SPLL_BUS_CLK 88
+
+#define IMX7ULP_CLK_END 89
+
+/*cm4 clocks*/
+#define IMX7ULP_CM4_CLK_DUMMY 0
+#define IMX7ULP_CM4_CLK_ROSC 1
+#define IMX7ULP_CM4_CLK_SOSC 2
+#define IMX7ULP_CM4_CLK_FIRC 3
+#define IMX7ULP_CM4_CLK_SIRC 4
+
+/* SCG0 */
+#define IMX7ULP_CM4_CLK_SPLL_VCO_PRE_SEL 5
+#define IMX7ULP_CM4_CLK_SPLL_VCO_PRE_DIV 6
+#define IMX7ULP_CM4_CLK_SPLL 7
+#define IMX7ULP_CM4_CLK_SPLL_VCO 8
+#define IMX7ULP_CM4_CLK_SPLL_VCO_POST_DIV1 9
+#define IMX7ULP_CM4_CLK_SPLL_VCO_POST_DIV2 10
+#define IMX7ULP_CM4_CLK_SPLL_PFD0 11
+#define IMX7ULP_CM4_CLK_SPLL_PFD1 12
+#define IMX7ULP_CM4_CLK_SPLL_PFD2 13
+#define IMX7ULP_CM4_CLK_SPLL_PFD3 14
+#define IMX7ULP_CM4_CLK_SPLL_PFD_SEL 15
+#define IMX7ULP_CM4_CLK_SPLL_PFD 16
+#define IMX7ULP_CM4_CLK_SPLL_SEL 17
+#define IMX7ULP_CM4_CLK_APLL_VCO_PRE_SEL 18
+#define IMX7ULP_CM4_CLK_APLL_VCO_PRE_DIV 19
+#define IMX7ULP_CM4_CLK_APLL 20
+#define IMX7ULP_CM4_CLK_APLL_VCO 21
+#define IMX7ULP_CM4_CLK_APLL_VCO_POST_DIV1 22
+#define IMX7ULP_CM4_CLK_APLL_VCO_POST_DIV2 23
+#define IMX7ULP_CM4_CLK_APLL_PFD0 24
+#define IMX7ULP_CM4_CLK_APLL_PFD1 25
+#define IMX7ULP_CM4_CLK_APLL_PFD2 26
+#define IMX7ULP_CM4_CLK_APLL_PFD3 27
+#define IMX7ULP_CM4_CLK_APLL_PFD_SEL 28
+#define IMX7ULP_CM4_CLK_APLL_PFD 29
+#define IMX7ULP_CM4_CLK_APLL_SEL 30
+#define IMX7ULP_CM4_CLK_APLL_PFD0_PRE_DIV 31
+#define IMX7ULP_CM4_CLK_SYS_SEL 32
+#define IMX7ULP_CM4_CLK_CORE_DIV 33
+#define IMX7ULP_CM4_CLK_BUS_DIV 34
+#define IMX7ULP_CM4_CLK_PLAT_DIV 35
+#define IMX7ULP_CM4_CLK_SLOW_DIV 36
+
+#define IMX7ULP_CM4_CLK_SAI0_SEL 37
+#define IMX7ULP_CM4_CLK_SAI0_DIV 38
+#define IMX7ULP_CM4_CLK_SAI0_ROOT 39
+#define IMX7ULP_CM4_CLK_SAI0_IPG 40
+#define IMX7ULP_CM4_CLK_SAI1_SEL 41
+#define IMX7ULP_CM4_CLK_SAI1_DIV 42
+#define IMX7ULP_CM4_CLK_SAI1_ROOT 43
+#define IMX7ULP_CM4_CLK_SAI1_IPG 44
+
+#define IMX7ULP_CLK_SCG0_CLKOUT 45
+
+#define IMX7ULP_CM4_CLK_END 46
+
+#endif /* __DT_BINDINGS_CLOCK_IMX7ULP_H */
diff --git a/include/dt-bindings/clock/imx8mm-clock.h b/include/dt-bindings/clock/imx8mm-clock.h
new file mode 100644
index 000000000000..083dd6d0116d
--- /dev/null
+++ b/include/dt-bindings/clock/imx8mm-clock.h
@@ -0,0 +1,473 @@
+/*
+ * Copyright 2017-2018 NXP
+ *
+ * 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 __DT_BINDINGS_CLOCK_IMX8MM_H
+#define __DT_BINDINGS_CLOCK_IMX8MM_H
+
+#define IMX8MM_CLK_DUMMY 0
+#define IMX8MM_CLK_32K 1
+#define IMX8MM_CLK_24M 2
+#define IMX8MM_OSC_HDMI_CLK 3
+#define IMX8MM_CLK_EXT1 4
+#define IMX8MM_CLK_EXT2 5
+#define IMX8MM_CLK_EXT3 6
+#define IMX8MM_CLK_EXT4 7
+#define IMX8MM_AUDIO_PLL1_REF_SEL 8
+#define IMX8MM_AUDIO_PLL2_REF_SEL 9
+#define IMX8MM_VIDEO_PLL1_REF_SEL 10
+#define IMX8MM_DRAM_PLL_REF_SEL 11
+#define IMX8MM_GPU_PLL_REF_SEL 12
+#define IMX8MM_VPU_PLL_REF_SEL 13
+#define IMX8MM_ARM_PLL_REF_SEL 14
+#define IMX8MM_SYS_PLL1_REF_SEL 15
+#define IMX8MM_SYS_PLL2_REF_SEL 16
+#define IMX8MM_SYS_PLL3_REF_SEL 17
+#define IMX8MM_AUDIO_PLL1 18
+#define IMX8MM_AUDIO_PLL2 19
+#define IMX8MM_VIDEO_PLL1 20
+#define IMX8MM_DRAM_PLL 21
+#define IMX8MM_GPU_PLL 22
+#define IMX8MM_VPU_PLL 23
+#define IMX8MM_ARM_PLL 24
+#define IMX8MM_SYS_PLL1 25
+#define IMX8MM_SYS_PLL2 26
+#define IMX8MM_SYS_PLL3 27
+#define IMX8MM_AUDIO_PLL1_BYPASS 28
+#define IMX8MM_AUDIO_PLL2_BYPASS 29
+#define IMX8MM_VIDEO_PLL1_BYPASS 30
+#define IMX8MM_DRAM_PLL_BYPASS 31
+#define IMX8MM_GPU_PLL_BYPASS 32
+#define IMX8MM_VPU_PLL_BYPASS 33
+#define IMX8MM_ARM_PLL_BYPASS 34
+#define IMX8MM_SYS_PLL1_BYPASS 35
+#define IMX8MM_SYS_PLL2_BYPASS 36
+#define IMX8MM_SYS_PLL3_BYPASS 37
+#define IMX8MM_AUDIO_PLL1_OUT 38
+#define IMX8MM_AUDIO_PLL2_OUT 39
+#define IMX8MM_VIDEO_PLL1_OUT 40
+#define IMX8MM_DRAM_PLL_OUT 41
+#define IMX8MM_GPU_PLL_OUT 42
+#define IMX8MM_VPU_PLL_OUT 43
+#define IMX8MM_ARM_PLL_OUT 44
+#define IMX8MM_SYS_PLL1_OUT 45
+#define IMX8MM_SYS_PLL2_OUT 46
+#define IMX8MM_SYS_PLL3_OUT 47
+#define IMX8MM_SYS_PLL1_40M 48
+#define IMX8MM_SYS_PLL1_80M 49
+#define IMX8MM_SYS_PLL1_100M 50
+#define IMX8MM_SYS_PLL1_133M 51
+#define IMX8MM_SYS_PLL1_160M 52
+#define IMX8MM_SYS_PLL1_200M 53
+#define IMX8MM_SYS_PLL1_266M 54
+#define IMX8MM_SYS_PLL1_400M 55
+#define IMX8MM_SYS_PLL1_800M 56
+#define IMX8MM_SYS_PLL2_50M 57
+#define IMX8MM_SYS_PLL2_100M 58
+#define IMX8MM_SYS_PLL2_125M 59
+#define IMX8MM_SYS_PLL2_166M 60
+#define IMX8MM_SYS_PLL2_200M 61
+#define IMX8MM_SYS_PLL2_250M 62
+#define IMX8MM_SYS_PLL2_333M 63
+#define IMX8MM_SYS_PLL2_500M 64
+#define IMX8MM_SYS_PLL2_1000M 65
+#define IMX8MM_CLK_A53_SRC 66
+#define IMX8MM_CLK_M4_SRC 67
+#define IMX8MM_CLK_VPU_SRC 68
+#define IMX8MM_CLK_GPU3D_SRC 69
+#define IMX8MM_CLK_GPU2D_SRC 70
+#define IMX8MM_CLK_A53_CG 71
+#define IMX8MM_CLK_M4_CG 72
+#define IMX8MM_CLK_VPU_CG 73
+#define IMX8MM_CLK_GPU3D_CG 74
+#define IMX8MM_CLK_GPU2D_CG 75
+#define IMX8MM_CLK_A53_DIV 76
+#define IMX8MM_CLK_M4_DIV 77
+#define IMX8MM_CLK_VPU_DIV 78
+#define IMX8MM_CLK_GPU3D_DIV 79
+#define IMX8MM_CLK_GPU2D_DIV 80
+#define IMX8MM_CLK_MAIN_AXI_SRC 81
+#define IMX8MM_CLK_ENET_AXI_SRC 82
+#define IMX8MM_CLK_NAND_USDHC_BUS_SRC 83
+#define IMX8MM_CLK_VPU_BUS_SRC 84
+#define IMX8MM_CLK_DISP_AXI_SRC 85
+#define IMX8MM_CLK_DISP_APB_SRC 86
+#define IMX8MM_CLK_DISP_RTRM_SRC 87
+#define IMX8MM_CLK_USB_BUS_SRC 88
+#define IMX8MM_CLK_GPU_AXI_SRC 89
+#define IMX8MM_CLK_GPU_AHB_SRC 90
+#define IMX8MM_CLK_NOC_SRC 91
+#define IMX8MM_CLK_NOC_APB_SRC 92
+#define IMX8MM_CLK_MAIN_AXI_CG 93
+#define IMX8MM_CLK_ENET_AXI_CG 94
+#define IMX8MM_CLK_NAND_USDHC_BUS_CG 95
+#define IMX8MM_CLK_VPU_BUS_CG 96
+#define IMX8MM_CLK_DISP_AXI_CG 97
+#define IMX8MM_CLK_DISP_APB_CG 98
+#define IMX8MM_CLK_DISP_RTRM_CG 99
+#define IMX8MM_CLK_USB_BUS_CG 100
+#define IMX8MM_CLK_GPU_AXI_CG 101
+#define IMX8MM_CLK_GPU_AHB_CG 102
+#define IMX8MM_CLK_NOC_CG 103
+#define IMX8MM_CLK_NOC_APB_CG 104
+#define IMX8MM_CLK_MAIN_AXI_PRE_DIV 105
+#define IMX8MM_CLK_ENET_AXI_PRE_DIV 106
+#define IMX8MM_CLK_NAND_USDHC_BUS_PRE_DIV 107
+#define IMX8MM_CLK_VPU_BUS_PRE_DIV 108
+#define IMX8MM_CLK_DISP_AXI_PRE_DIV 109
+#define IMX8MM_CLK_DISP_APB_PRE_DIV 110
+#define IMX8MM_CLK_DISP_RTRM_PRE_DIV 111
+#define IMX8MM_CLK_USB_BUS_PRE_DIV 112
+#define IMX8MM_CLK_GPU_AXI_PRE_DIV 113
+#define IMX8MM_CLK_GPU_AHB_PRE_DIV 114
+#define IMX8MM_CLK_NOC_PRE_DIV 115
+#define IMX8MM_CLK_NOC_APB_PRE_DIV 116
+#define IMX8MM_CLK_MAIN_AXI_DIV 117
+#define IMX8MM_CLK_ENET_AXI_DIV 118
+#define IMX8MM_CLK_NAND_USDHC_BUS_DIV 119
+#define IMX8MM_CLK_VPU_BUS_DIV 120
+#define IMX8MM_CLK_DISP_AXI_DIV 121
+#define IMX8MM_CLK_DISP_APB_DIV 122
+#define IMX8MM_CLK_DISP_RTRM_DIV 123
+#define IMX8MM_CLK_USB_BUS_DIV 124
+#define IMX8MM_CLK_GPU_AXI_DIV 125
+#define IMX8MM_CLK_GPU_AHB_DIV 126
+#define IMX8MM_CLK_NOC_DIV 127
+#define IMX8MM_CLK_NOC_APB_DIV 128
+#define IMX8MM_CLK_AHB_SRC 129
+#define IMX8MM_CLK_AUDIO_AHB_SRC 130
+#define IMX8MM_CLK_DSI_ESC_RX_SRC 131
+#define IMX8MM_CLK_AHB_CG 132
+#define IMX8MM_CLK_AUDIO_AHB_CG 133
+#define IMX8MM_CLK_DSI_ESC_RX_CG 134
+#define IMX8MM_CLK_AHB_PRE_DIV 135
+#define IMX8MM_CLK_AUDIO_AHB_PRE_DIV 136
+#define IMX8MM_CLK_DSI_ESC_RX_PRE_DIV 137
+#define IMX8MM_CLK_AHB_DIV 138
+#define IMX8MM_CLK_AUDIO_AHB_DIV 139
+#define IMX8MM_CLK_DSI_ESC_RX_DIV 140
+#define IMX8MM_CLK_IPG_ROOT 141
+#define IMX8MM_CLK_IPG_AUDIO_ROOT 142
+#define IMX8MM_CLK_IPG_DSI_ESC_RX_ROOT 143
+#define IMX8MM_CLK_DRAM_ALT_SRC 144
+#define IMX8MM_CLK_DRAM_APB_SRC 145
+#define IMX8MM_CLK_VPU_G1_SRC 146
+#define IMX8MM_CLK_VPU_G2_SRC 147
+#define IMX8MM_CLK_DISP_DTRC_SRC 148
+#define IMX8MM_CLK_DISP_DC8000_SRC 149
+#define IMX8MM_CLK_PCIE1_CTRL_SRC 150
+#define IMX8MM_CLK_PCIE1_PHY_SRC 151
+#define IMX8MM_CLK_PCIE1_AUX_SRC 152
+#define IMX8MM_CLK_DC_PIXEL_SRC 153
+#define IMX8MM_CLK_LCDIF_PIXEL_SRC 154
+#define IMX8MM_CLK_SAI1_SRC 155
+#define IMX8MM_CLK_SAI2_SRC 156
+#define IMX8MM_CLK_SAI3_SRC 157
+#define IMX8MM_CLK_SAI4_SRC 158
+#define IMX8MM_CLK_SAI5_SRC 159
+#define IMX8MM_CLK_SAI6_SRC 160
+#define IMX8MM_CLK_SPDIF1_SRC 161
+#define IMX8MM_CLK_SPDIF2_SRC 162
+#define IMX8MM_CLK_ENET_REF_SRC 163
+#define IMX8MM_CLK_ENET_TIMER_SRC 164
+#define IMX8MM_CLK_ENET_PHY_REF_SRC 165
+#define IMX8MM_CLK_NAND_SRC 166
+#define IMX8MM_CLK_QSPI_SRC 167
+#define IMX8MM_CLK_USDHC1_SRC 168
+#define IMX8MM_CLK_USDHC2_SRC 169
+#define IMX8MM_CLK_I2C1_SRC 170
+#define IMX8MM_CLK_I2C2_SRC 171
+#define IMX8MM_CLK_I2C3_SRC 172
+#define IMX8MM_CLK_I2C4_SRC 173
+#define IMX8MM_CLK_UART1_SRC 174
+#define IMX8MM_CLK_UART2_SRC 175
+#define IMX8MM_CLK_UART3_SRC 176
+#define IMX8MM_CLK_UART4_SRC 177
+#define IMX8MM_CLK_USB_CORE_REF_SRC 178
+#define IMX8MM_CLK_USB_PHY_REF_SRC 179
+#define IMX8MM_CLK_ECSPI1_SRC 180
+#define IMX8MM_CLK_ECSPI2_SRC 181
+#define IMX8MM_CLK_PWM1_SRC 182
+#define IMX8MM_CLK_PWM2_SRC 183
+#define IMX8MM_CLK_PWM3_SRC 184
+#define IMX8MM_CLK_PWM4_SRC 185
+#define IMX8MM_CLK_GPT1_SRC 186
+#define IMX8MM_CLK_WDOG_SRC 187
+#define IMX8MM_CLK_WRCLK_SRC 188
+#define IMX8MM_CLK_DSI_CORE_SRC 189
+#define IMX8MM_CLK_DSI_PHY_REF_SRC 190
+#define IMX8MM_CLK_DSI_DBI_SRC 191
+#define IMX8MM_CLK_USDHC3_SRC 192
+#define IMX8MM_CLK_CSI1_CORE_SRC 193
+#define IMX8MM_CLK_CSI1_PHY_REF_SRC 194
+#define IMX8MM_CLK_CSI1_ESC_SRC 195
+#define IMX8MM_CLK_CSI2_CORE_SRC 196
+#define IMX8MM_CLK_CSI2_PHY_REF_SRC 197
+#define IMX8MM_CLK_CSI2_ESC_SRC 198
+#define IMX8MM_CLK_PCIE2_CTRL_SRC 199
+#define IMX8MM_CLK_PCIE2_PHY_SRC 200
+#define IMX8MM_CLK_PCIE2_AUX_SRC 201
+#define IMX8MM_CLK_ECSPI3_SRC 202
+#define IMX8MM_CLK_PDM_SRC 203
+#define IMX8MM_CLK_VPU_H1_SRC 204
+#define IMX8MM_CLK_DRAM_ALT_CG 205
+#define IMX8MM_CLK_DRAM_APB_CG 206
+#define IMX8MM_CLK_VPU_G1_CG 207
+#define IMX8MM_CLK_VPU_G2_CG 208
+#define IMX8MM_CLK_DISP_DTRC_CG 209
+#define IMX8MM_CLK_DISP_DC8000_CG 210
+#define IMX8MM_CLK_PCIE1_CTRL_CG 211
+#define IMX8MM_CLK_PCIE1_PHY_CG 212
+#define IMX8MM_CLK_PCIE1_AUX_CG 213
+#define IMX8MM_CLK_DC_PIXEL_CG 214
+#define IMX8MM_CLK_LCDIF_PIXEL_CG 215
+#define IMX8MM_CLK_SAI1_CG 216
+#define IMX8MM_CLK_SAI2_CG 217
+#define IMX8MM_CLK_SAI3_CG 218
+#define IMX8MM_CLK_SAI4_CG 219
+#define IMX8MM_CLK_SAI5_CG 220
+#define IMX8MM_CLK_SAI6_CG 221
+#define IMX8MM_CLK_SPDIF1_CG 222
+#define IMX8MM_CLK_SPDIF2_CG 223
+#define IMX8MM_CLK_ENET_REF_CG 224
+#define IMX8MM_CLK_ENET_TIMER_CG 225
+#define IMX8MM_CLK_ENET_PHY_REF_CG 226
+#define IMX8MM_CLK_NAND_CG 227
+#define IMX8MM_CLK_QSPI_CG 228
+#define IMX8MM_CLK_USDHC1_CG 229
+#define IMX8MM_CLK_USDHC2_CG 230
+#define IMX8MM_CLK_I2C1_CG 231
+#define IMX8MM_CLK_I2C2_CG 232
+#define IMX8MM_CLK_I2C3_CG 233
+#define IMX8MM_CLK_I2C4_CG 234
+#define IMX8MM_CLK_UART1_CG 235
+#define IMX8MM_CLK_UART2_CG 236
+#define IMX8MM_CLK_UART3_CG 237
+#define IMX8MM_CLK_UART4_CG 238
+#define IMX8MM_CLK_USB_CORE_REF_CG 239
+#define IMX8MM_CLK_USB_PHY_REF_CG 240
+#define IMX8MM_CLK_ECSPI1_CG 241
+#define IMX8MM_CLK_ECSPI2_CG 242
+#define IMX8MM_CLK_PWM1_CG 243
+#define IMX8MM_CLK_PWM2_CG 244
+#define IMX8MM_CLK_PWM3_CG 245
+#define IMX8MM_CLK_PWM4_CG 246
+#define IMX8MM_CLK_GPT1_CG 247
+#define IMX8MM_CLK_WDOG_CG 248
+#define IMX8MM_CLK_WRCLK_CG 249
+#define IMX8MM_CLK_DSI_CORE_CG 250
+#define IMX8MM_CLK_DSI_PHY_REF_CG 251
+#define IMX8MM_CLK_DSI_DBI_CG 252
+#define IMX8MM_CLK_USDHC3_CG 253
+#define IMX8MM_CLK_CSI1_CORE_CG 254
+#define IMX8MM_CLK_CSI1_PHY_REF_CG 255
+#define IMX8MM_CLK_CSI1_ESC_CG 256
+#define IMX8MM_CLK_CSI2_CORE_CG 257
+#define IMX8MM_CLK_CSI2_PHY_REF_CG 258
+#define IMX8MM_CLK_CSI2_ESC_CG 259
+#define IMX8MM_CLK_PCIE2_CTRL_CG 260
+#define IMX8MM_CLK_PCIE2_PHY_CG 261
+#define IMX8MM_CLK_PCIE2_AUX_CG 262
+#define IMX8MM_CLK_ECSPI3_CG 263
+#define IMX8MM_CLK_PDM_CG 264
+#define IMX8MM_CLK_VPU_H1_CG 265
+#define IMX8MM_CLK_DRAM_ALT_PRE_DIV 266
+#define IMX8MM_CLK_DRAM_APB_PRE_DIV 267
+#define IMX8MM_CLK_VPU_G1_PRE_DIV 268
+#define IMX8MM_CLK_VPU_G2_PRE_DIV 269
+#define IMX8MM_CLK_DISP_DTRC_PRE_DIV 270
+#define IMX8MM_CLK_DISP_DC8000_PRE_DIV 271
+#define IMX8MM_CLK_PCIE1_CTRL_PRE_DIV 272
+#define IMX8MM_CLK_PCIE1_PHY_PRE_DIV 273
+#define IMX8MM_CLK_PCIE1_AUX_PRE_DIV 274
+#define IMX8MM_CLK_DC_PIXEL_PRE_DIV 275
+#define IMX8MM_CLK_LCDIF_PIXEL_PRE_DIV 276
+#define IMX8MM_CLK_SAI1_PRE_DIV 277
+#define IMX8MM_CLK_SAI2_PRE_DIV 278
+#define IMX8MM_CLK_SAI3_PRE_DIV 279
+#define IMX8MM_CLK_SAI4_PRE_DIV 280
+#define IMX8MM_CLK_SAI5_PRE_DIV 281
+#define IMX8MM_CLK_SAI6_PRE_DIV 282
+#define IMX8MM_CLK_SPDIF1_PRE_DIV 283
+#define IMX8MM_CLK_SPDIF2_PRE_DIV 284
+#define IMX8MM_CLK_ENET_REF_PRE_DIV 285
+#define IMX8MM_CLK_ENET_TIMER_PRE_DIV 286
+#define IMX8MM_CLK_ENET_PHY_REF_PRE_DIV 287
+#define IMX8MM_CLK_NAND_PRE_DIV 288
+#define IMX8MM_CLK_QSPI_PRE_DIV 289
+#define IMX8MM_CLK_USDHC1_PRE_DIV 290
+#define IMX8MM_CLK_USDHC2_PRE_DIV 291
+#define IMX8MM_CLK_I2C1_PRE_DIV 292
+#define IMX8MM_CLK_I2C2_PRE_DIV 293
+#define IMX8MM_CLK_I2C3_PRE_DIV 294
+#define IMX8MM_CLK_I2C4_PRE_DIV 295
+#define IMX8MM_CLK_UART1_PRE_DIV 296
+#define IMX8MM_CLK_UART2_PRE_DIV 297
+#define IMX8MM_CLK_UART3_PRE_DIV 298
+#define IMX8MM_CLK_UART4_PRE_DIV 299
+#define IMX8MM_CLK_USB_CORE_REF_PRE_DIV 300
+#define IMX8MM_CLK_USB_PHY_REF_PRE_DIV 301
+#define IMX8MM_CLK_ECSPI1_PRE_DIV 302
+#define IMX8MM_CLK_ECSPI2_PRE_DIV 303
+#define IMX8MM_CLK_PWM1_PRE_DIV 304
+#define IMX8MM_CLK_PWM2_PRE_DIV 305
+#define IMX8MM_CLK_PWM3_PRE_DIV 306
+#define IMX8MM_CLK_PWM4_PRE_DIV 307
+#define IMX8MM_CLK_GPT1_PRE_DIV 308
+#define IMX8MM_CLK_WDOG_PRE_DIV 309
+#define IMX8MM_CLK_WRCLK_PRE_DIV 310
+#define IMX8MM_CLK_DSI_CORE_PRE_DIV 311
+#define IMX8MM_CLK_DSI_PHY_REF_PRE_DIV 312
+#define IMX8MM_CLK_DSI_DBI_PRE_DIV 313
+#define IMX8MM_CLK_USDHC3_PRE_DIV 314
+#define IMX8MM_CLK_CSI1_CORE_PRE_DIV 315
+#define IMX8MM_CLK_CSI1_PHY_REF_PRE_DIV 316
+#define IMX8MM_CLK_CSI1_ESC_PRE_DIV 317
+#define IMX8MM_CLK_CSI2_CORE_PRE_DIV 318
+#define IMX8MM_CLK_CSI2_PHY_REF_PRE_DIV 319
+#define IMX8MM_CLK_CSI2_ESC_PRE_DIV 320
+#define IMX8MM_CLK_PCIE2_CTRL_PRE_DIV 321
+#define IMX8MM_CLK_PCIE2_PHY_PRE_DIV 322
+#define IMX8MM_CLK_PCIE2_AUX_PRE_DIV 323
+#define IMX8MM_CLK_ECSPI3_PRE_DIV 324
+#define IMX8MM_CLK_PDM_PRE_DIV 325
+#define IMX8MM_CLK_VPU_H1_PRE_DIV 326
+#define IMX8MM_CLK_DRAM_ALT_DIV 327
+#define IMX8MM_CLK_DRAM_APB_DIV 328
+#define IMX8MM_CLK_VPU_G1_DIV 329
+#define IMX8MM_CLK_VPU_G2_DIV 330
+#define IMX8MM_CLK_DISP_DTRC_DIV 331
+#define IMX8MM_CLK_DISP_DC8000_DIV 332
+#define IMX8MM_CLK_PCIE1_CTRL_DIV 333
+#define IMX8MM_CLK_PCIE1_PHY_DIV 334
+#define IMX8MM_CLK_PCIE1_AUX_DIV 335
+#define IMX8MM_CLK_DC_PIXEL_DIV 336
+#define IMX8MM_CLK_LCDIF_PIXEL_DIV 337
+#define IMX8MM_CLK_SAI1_DIV 338
+#define IMX8MM_CLK_SAI2_DIV 339
+#define IMX8MM_CLK_SAI3_DIV 340
+#define IMX8MM_CLK_SAI4_DIV 341
+#define IMX8MM_CLK_SAI5_DIV 342
+#define IMX8MM_CLK_SAI6_DIV 343
+#define IMX8MM_CLK_SPDIF1_DIV 344
+#define IMX8MM_CLK_SPDIF2_DIV 345
+#define IMX8MM_CLK_ENET_REF_DIV 346
+#define IMX8MM_CLK_ENET_TIMER_DIV 347
+#define IMX8MM_CLK_ENET_PHY_REF_DIV 348
+#define IMX8MM_CLK_NAND_DIV 349
+#define IMX8MM_CLK_QSPI_DIV 350
+#define IMX8MM_CLK_USDHC1_DIV 351
+#define IMX8MM_CLK_USDHC2_DIV 352
+#define IMX8MM_CLK_I2C1_DIV 353
+#define IMX8MM_CLK_I2C2_DIV 354
+#define IMX8MM_CLK_I2C3_DIV 355
+#define IMX8MM_CLK_I2C4_DIV 356
+#define IMX8MM_CLK_UART1_DIV 357
+#define IMX8MM_CLK_UART2_DIV 358
+#define IMX8MM_CLK_UART3_DIV 359
+#define IMX8MM_CLK_UART4_DIV 360
+#define IMX8MM_CLK_USB_CORE_REF_DIV 361
+#define IMX8MM_CLK_USB_PHY_REF_DIV 362
+#define IMX8MM_CLK_ECSPI1_DIV 363
+#define IMX8MM_CLK_ECSPI2_DIV 364
+#define IMX8MM_CLK_PWM1_DIV 365
+#define IMX8MM_CLK_PWM2_DIV 366
+#define IMX8MM_CLK_PWM3_DIV 367
+#define IMX8MM_CLK_PWM4_DIV 368
+#define IMX8MM_CLK_GPT1_DIV 369
+#define IMX8MM_CLK_WDOG_DIV 370
+#define IMX8MM_CLK_WRCLK_DIV 371
+#define IMX8MM_CLK_DSI_CORE_DIV 372
+#define IMX8MM_CLK_DSI_PHY_REF_DIV 373
+#define IMX8MM_CLK_DSI_DBI_DIV 374
+#define IMX8MM_CLK_USDHC3_DIV 375
+#define IMX8MM_CLK_CSI1_CORE_DIV 376
+#define IMX8MM_CLK_CSI1_PHY_REF_DIV 377
+#define IMX8MM_CLK_CSI1_ESC_DIV 378
+#define IMX8MM_CLK_CSI2_CORE_DIV 379
+#define IMX8MM_CLK_CSI2_PHY_REF_DIV 380
+#define IMX8MM_CLK_CSI2_ESC_DIV 381
+#define IMX8MM_CLK_PCIE2_CTRL_DIV 382
+#define IMX8MM_CLK_PCIE2_PHY_DIV 383
+#define IMX8MM_CLK_PCIE2_AUX_DIV 384
+#define IMX8MM_CLK_ECSPI3_DIV 385
+#define IMX8MM_CLK_PDM_DIV 386
+#define IMX8MM_CLK_VPU_H1_DIV 387
+#define IMX8MM_CLK_ECSPI1_ROOT 388
+#define IMX8MM_CLK_ECSPI2_ROOT 389
+#define IMX8MM_CLK_ECSPI3_ROOT 390
+#define IMX8MM_CLK_ENET1_ROOT 391
+#define IMX8MM_CLK_GPT1_ROOT 392
+#define IMX8MM_CLK_I2C1_ROOT 393
+#define IMX8MM_CLK_I2C2_ROOT 394
+#define IMX8MM_CLK_I2C3_ROOT 395
+#define IMX8MM_CLK_I2C4_ROOT 396
+#define IMX8MM_CLK_OCOTP_ROOT 397
+#define IMX8MM_CLK_PCIE1_ROOT 398
+#define IMX8MM_CLK_PWM1_ROOT 399
+#define IMX8MM_CLK_PWM2_ROOT 400
+#define IMX8MM_CLK_PWM3_ROOT 401
+#define IMX8MM_CLK_PWM4_ROOT 402
+#define IMX8MM_CLK_QSPI_ROOT 403
+#define IMX8MM_CLK_NAND_ROOT 404
+#define IMX8MM_CLK_SAI1_ROOT 405
+#define IMX8MM_CLK_SAI1_IPG 406
+#define IMX8MM_CLK_SAI2_ROOT 407
+#define IMX8MM_CLK_SAI2_IPG 408
+#define IMX8MM_CLK_SAI3_ROOT 409
+#define IMX8MM_CLK_SAI3_IPG 410
+#define IMX8MM_CLK_SAI4_ROOT 411
+#define IMX8MM_CLK_SAI4_IPG 412
+#define IMX8MM_CLK_SAI5_ROOT 413
+#define IMX8MM_CLK_SAI5_IPG 414
+#define IMX8MM_CLK_SAI6_ROOT 415
+#define IMX8MM_CLK_SAI6_IPG 416
+#define IMX8MM_CLK_UART1_ROOT 417
+#define IMX8MM_CLK_UART2_ROOT 418
+#define IMX8MM_CLK_UART3_ROOT 419
+#define IMX8MM_CLK_UART4_ROOT 420
+#define IMX8MM_CLK_USB1_CTRL_ROOT 421
+#define IMX8MM_CLK_GPU3D_ROOT 422
+#define IMX8MM_CLK_USDHC1_ROOT 423
+#define IMX8MM_CLK_USDHC2_ROOT 424
+#define IMX8MM_CLK_WDOG1_ROOT 425
+#define IMX8MM_CLK_WDOG2_ROOT 426
+#define IMX8MM_CLK_WDOG3_ROOT 427
+#define IMX8MM_CLK_VPU_G1_ROOT 428
+#define IMX8MM_CLK_GPU_BUS_ROOT 429
+#define IMX8MM_CLK_VPU_H1_ROOT 430
+#define IMX8MM_CLK_VPU_G2_ROOT 431
+#define IMX8MM_CLK_PDM_ROOT 432
+#define IMX8MM_CLK_DISP_ROOT 433
+#define IMX8MM_CLK_DISP_AXI_ROOT 434
+#define IMX8MM_CLK_DISP_APB_ROOT 435
+#define IMX8MM_CLK_DISP_RTRM_ROOT 436
+#define IMX8MM_CLK_USDHC3_ROOT 437
+#define IMX8MM_CLK_TMU_ROOT 438
+#define IMX8MM_CLK_VPU_DEC_ROOT 439
+#define IMX8MM_CLK_SDMA1_ROOT 440
+#define IMX8MM_CLK_SDMA2_ROOT 441
+#define IMX8MM_CLK_SDMA3_ROOT 442
+#define IMX8MM_CLK_GPT_3M 443
+#define IMX8MM_CLK_ARM 444
+#define IMX8MM_CLK_PDM_IPG 445
+#define IMX8MM_CLK_GPU2D_ROOT 446
+#define IMX8MM_CLK_MU_ROOT 447
+#define IMX8MM_CLK_CSI1_ROOT 448
+#define IMX8MM_CLK_CLKO1_SRC 449
+#define IMX8MM_CLK_CLKO1_CG 450
+#define IMX8MM_CLK_CLKO1_PRE_DIV 451
+#define IMX8MM_CLK_CLKO1_DIV 452
+
+#define IMX8MM_CLK_DRAM_CORE 453
+#define IMX8MM_CLK_DRAM_ALT_ROOT 454
+
+#define IMX8MM_CLK_NAND_USDHC_BUS_RAWNAND_CLK 455
+#define IMX8MM_CLK_SIM_HSIO 456
+
+#define IMX8MM_CLK_END 457
+#endif
diff --git a/include/dt-bindings/clock/imx8mq-clock.h b/include/dt-bindings/clock/imx8mq-clock.h
new file mode 100644
index 000000000000..e05eea7ce1e7
--- /dev/null
+++ b/include/dt-bindings/clock/imx8mq-clock.h
@@ -0,0 +1,410 @@
+/*
+ * Copyright 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017 NXP
+ *
+ * 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 __DT_BINDINGS_CLOCK_IMX8MQ_H
+#define __DT_BINDINGS_CLOCK_IMX8MQ_H
+
+#define IMX8MQ_CLK_DUMMY 0
+#define IMX8MQ_CLK_32K 1
+#define IMX8MQ_CLK_25M 2
+#define IMX8MQ_CLK_27M 3
+#define IMX8MQ_CLK_EXT1 4
+#define IMX8MQ_CLK_EXT2 5
+#define IMX8MQ_CLK_EXT3 6
+#define IMX8MQ_CLK_EXT4 7
+
+/* ANAMIX PLL clocks */
+/* FRAC PLLs */
+/* ARM PLL */
+#define IMX8MQ_ARM_PLL_REF_SEL 8
+#define IMX8MQ_ARM_PLL_REF_DIV 9
+#define IMX8MQ_ARM_PLL 10
+#define IMX8MQ_ARM_PLL_BYPASS 11
+#define IMX8MQ_ARM_PLL_OUT 12
+
+/* GPU PLL */
+#define IMX8MQ_GPU_PLL_REF_SEL 13
+#define IMX8MQ_GPU_PLL_REF_DIV 14
+#define IMX8MQ_GPU_PLL 15
+#define IMX8MQ_GPU_PLL_BYPASS 16
+#define IMX8MQ_GPU_PLL_OUT 17
+
+/* VPU PLL */
+#define IMX8MQ_VPU_PLL_REF_SEL 18
+#define IMX8MQ_VPU_PLL_REF_DIV 19
+#define IMX8MQ_VPU_PLL 20
+#define IMX8MQ_VPU_PLL_BYPASS 21
+#define IMX8MQ_VPU_PLL_OUT 22
+
+/* AUDIO PLL1 */
+#define IMX8MQ_AUDIO_PLL1_REF_SEL 23
+#define IMX8MQ_AUDIO_PLL1_REF_DIV 24
+#define IMX8MQ_AUDIO_PLL1 25
+#define IMX8MQ_AUDIO_PLL1_BYPASS 26
+#define IMX8MQ_AUDIO_PLL1_OUT 27
+
+/* AUDIO PLL2 */
+#define IMX8MQ_AUDIO_PLL2_REF_SEL 28
+#define IMX8MQ_AUDIO_PLL2_REF_DIV 29
+#define IMX8MQ_AUDIO_PLL2 30
+#define IMX8MQ_AUDIO_PLL2_BYPASS 31
+#define IMX8MQ_AUDIO_PLL2_OUT 32
+
+/* VIDEO PLL1 */
+#define IMX8MQ_VIDEO_PLL1_REF_SEL 33
+#define IMX8MQ_VIDEO_PLL1_REF_DIV 34
+#define IMX8MQ_VIDEO_PLL1 35
+#define IMX8MQ_VIDEO_PLL1_BYPASS 36
+#define IMX8MQ_VIDEO_PLL1_OUT 37
+
+/* SYS1 PLL */
+#define IMX8MQ_SYS1_PLL1_REF_SEL 38
+#define IMX8MQ_SYS1_PLL1_REF_DIV 39
+#define IMX8MQ_SYS1_PLL1 40
+#define IMX8MQ_SYS1_PLL1_OUT 41
+#define IMX8MQ_SYS1_PLL1_OUT_DIV 42
+#define IMX8MQ_SYS1_PLL2 43
+#define IMX8MQ_SYS1_PLL2_DIV 44
+#define IMX8MQ_SYS1_PLL2_OUT 45
+
+/* SYS2 PLL */
+#define IMX8MQ_SYS2_PLL1_REF_SEL 46
+#define IMX8MQ_SYS2_PLL1_REF_DIV 47
+#define IMX8MQ_SYS2_PLL1 48
+#define IMX8MQ_SYS2_PLL1_OUT 49
+#define IMX8MQ_SYS2_PLL1_OUT_DIV 50
+#define IMX8MQ_SYS2_PLL2 51
+#define IMX8MQ_SYS2_PLL2_DIV 52
+#define IMX8MQ_SYS2_PLL2_OUT 53
+
+/* SYS3 PLL */
+#define IMX8MQ_SYS3_PLL1_REF_SEL 54
+#define IMX8MQ_SYS3_PLL1_REF_DIV 55
+#define IMX8MQ_SYS3_PLL1 56
+#define IMX8MQ_SYS3_PLL1_OUT 57
+#define IMX8MQ_SYS3_PLL1_OUT_DIV 58
+#define IMX8MQ_SYS3_PLL2 59
+#define IMX8MQ_SYS3_PLL2_DIV 60
+#define IMX8MQ_SYS3_PLL2_OUT 61
+
+/* DRAM PLL */
+#define IMX8MQ_DRAM_PLL1_REF_SEL 62
+#define IMX8MQ_DRAM_PLL1_REF_DIV 63
+#define IMX8MQ_DRAM_PLL1 64
+#define IMX8MQ_DRAM_PLL1_OUT 65
+#define IMX8MQ_DRAM_PLL1_OUT_DIV 66
+#define IMX8MQ_DRAM_PLL2 67
+#define IMX8MQ_DRAM_PLL2_DIV 68
+#define IMX8MQ_DRAM_PLL2_OUT 69
+
+/* SYS PLL DIV */
+#define IMX8MQ_SYS1_PLL_40M 70
+#define IMX8MQ_SYS1_PLL_80M 71
+#define IMX8MQ_SYS1_PLL_100M 72
+#define IMX8MQ_SYS1_PLL_133M 73
+#define IMX8MQ_SYS1_PLL_160M 74
+#define IMX8MQ_SYS1_PLL_200M 75
+#define IMX8MQ_SYS1_PLL_266M 76
+#define IMX8MQ_SYS1_PLL_400M 77
+#define IMX8MQ_SYS1_PLL_800M 78
+
+#define IMX8MQ_SYS2_PLL_50M 79
+#define IMX8MQ_SYS2_PLL_100M 80
+#define IMX8MQ_SYS2_PLL_125M 81
+#define IMX8MQ_SYS2_PLL_166M 82
+#define IMX8MQ_SYS2_PLL_200M 83
+#define IMX8MQ_SYS2_PLL_250M 84
+#define IMX8MQ_SYS2_PLL_333M 85
+#define IMX8MQ_SYS2_PLL_500M 86
+#define IMX8MQ_SYS2_PLL_1000M 87
+
+/* CCM ROOT clocks */
+/* A53 */
+#define IMX8MQ_CLK_A53_SRC 88
+#define IMX8MQ_CLK_A53_CG 89
+#define IMX8MQ_CLK_A53_DIV 90
+/* M4 */
+#define IMX8MQ_CLK_M4_SRC 91
+#define IMX8MQ_CLK_M4_CG 92
+#define IMX8MQ_CLK_M4_DIV 93
+/* VPU */
+#define IMX8MQ_CLK_VPU_SRC 94
+#define IMX8MQ_CLK_VPU_CG 95
+#define IMX8MQ_CLK_VPU_DIV 96
+/* GPU CORE */
+#define IMX8MQ_CLK_GPU_CORE_SRC 97
+#define IMX8MQ_CLK_GPU_CORE_CG 98
+#define IMX8MQ_CLK_GPU_CORE_DIV 99
+/* GPU SHADER */
+#define IMX8MQ_CLK_GPU_SHADER_SRC 100
+#define IMX8MQ_CLK_GPU_SHADER_CG 101
+#define IMX8MQ_CLK_GPU_SHADER_DIV 102
+
+/* BUS TYPE */
+/* MAIN AXI */
+#define IMX8MQ_CLK_MAIN_AXI 103
+/* ENET AXI */
+#define IMX8MQ_CLK_ENET_AXI 104
+/* NAND_USDHC_BUS */
+#define IMX8MQ_CLK_NAND_USDHC_BUS 105
+/* VPU BUS */
+#define IMX8MQ_CLK_VPU_BUS 106
+/* DISP_AXI */
+#define IMX8MQ_CLK_DISP_AXI 107
+/* DISP APB */
+#define IMX8MQ_CLK_DISP_APB 108
+/* DISP RTRM */
+#define IMX8MQ_CLK_DISP_RTRM 109
+/* USB_BUS */
+#define IMX8MQ_CLK_USB_BUS 110
+/* GPU_AXI */
+#define IMX8MQ_CLK_GPU_AXI 111
+/* GPU_AHB */
+#define IMX8MQ_CLK_GPU_AHB 112
+/* NOC */
+#define IMX8MQ_CLK_NOC 113
+/* NOC_APB */
+#define IMX8MQ_CLK_NOC_APB 114
+
+/* AHB */
+#define IMX8MQ_CLK_AHB 115
+/* AUDIO AHB */
+#define IMX8MQ_CLK_AUDIO_AHB 116
+
+/* DRAM_ALT */
+#define IMX8MQ_CLK_DRAM_ALT 117
+/* DRAM APB */
+#define IMX8MQ_CLK_DRAM_APB 118
+/* VPU_G1 */
+#define IMX8MQ_CLK_VPU_G1 119
+/* VPU_G2 */
+#define IMX8MQ_CLK_VPU_G2 120
+/* DISP_DTRC */
+#define IMX8MQ_CLK_DISP_DTRC 121
+/* DISP_DC8000 */
+#define IMX8MQ_CLK_DISP_DC8000 122
+/* PCIE_CTRL */
+#define IMX8MQ_CLK_PCIE1_CTRL 123
+/* PCIE_PHY */
+#define IMX8MQ_CLK_PCIE1_PHY 124
+/* PCIE_AUX */
+#define IMX8MQ_CLK_PCIE1_AUX 125
+/* DC_PIXEL */
+#define IMX8MQ_CLK_DC_PIXEL 126
+/* LCDIF_PIXEL */
+#define IMX8MQ_CLK_LCDIF_PIXEL 127
+/* SAI1~6 */
+#define IMX8MQ_CLK_SAI1 128
+
+#define IMX8MQ_CLK_SAI2 129
+
+#define IMX8MQ_CLK_SAI3 130
+
+#define IMX8MQ_CLK_SAI4 131
+
+#define IMX8MQ_CLK_SAI5 132
+
+#define IMX8MQ_CLK_SAI6 133
+/* SPDIF1 */
+#define IMX8MQ_CLK_SPDIF1 134
+/* SPDIF2 */
+#define IMX8MQ_CLK_SPDIF2 135
+/* ENET_REF */
+#define IMX8MQ_CLK_ENET_REF 136
+/* ENET_TIMER */
+#define IMX8MQ_CLK_ENET_TIMER 137
+/* ENET_PHY */
+#define IMX8MQ_CLK_ENET_PHY_REF 138
+/* NAND */
+#define IMX8MQ_CLK_NAND 139
+/* QSPI */
+#define IMX8MQ_CLK_QSPI 140
+/* USDHC1 */
+#define IMX8MQ_CLK_USDHC1 141
+/* USDHC2 */
+#define IMX8MQ_CLK_USDHC2 142
+/* I2C1 */
+#define IMX8MQ_CLK_I2C1 143
+/* I2C2 */
+#define IMX8MQ_CLK_I2C2 144
+/* I2C3 */
+#define IMX8MQ_CLK_I2C3 145
+/* I2C4 */
+#define IMX8MQ_CLK_I2C4 146
+/* UART1 */
+#define IMX8MQ_CLK_UART1 148
+/* UART2 */
+#define IMX8MQ_CLK_UART2 149
+/* UART3 */
+#define IMX8MQ_CLK_UART3 150
+/* UART4 */
+#define IMX8MQ_CLK_UART4 151
+/* USB_CORE_REF */
+#define IMX8MQ_CLK_USB_CORE_REF 152
+/* USB_PHY_REF */
+#define IMX8MQ_CLK_USB_PHY_REF 153
+/* ECSPI1 */
+#define IMX8MQ_CLK_ECSPI1 154
+/* ECSPI2 */
+#define IMX8MQ_CLK_ECSPI2 155
+/* PWM1 */
+#define IMX8MQ_CLK_PWM1 156
+/* PWM2 */
+#define IMX8MQ_CLK_PWM2 157
+/* PWM3 */
+#define IMX8MQ_CLK_PWM3 158
+/* PWM4 */
+#define IMX8MQ_CLK_PWM4 159
+/* GPT1 */
+#define IMX8MQ_CLK_GPT1 160
+/* WDOG */
+#define IMX8MQ_CLK_WDOG 161
+/* WRCLK */
+#define IMX8MQ_CLK_WRCLK 162
+/* DSI_CORE */
+#define IMX8MQ_CLK_DSI_CORE 163
+/* DSI_PHY */
+#define IMX8MQ_CLK_DSI_PHY_REF 164
+/* DSI_DBI */
+#define IMX8MQ_CLK_DSI_DBI 165
+/*DSI_ESC */
+#define IMX8MQ_CLK_DSI_ESC 166
+/* CSI1_CORE */
+#define IMX8MQ_CLK_CSI1_CORE 167
+/* CSI1_PHY */
+#define IMX8MQ_CLK_CSI1_PHY_REF 168
+/* CSI_ESC */
+#define IMX8MQ_CLK_CSI1_ESC 169
+/* CSI2_CORE */
+#define IMX8MQ_CLK_CSI2_CORE 170
+/* CSI2_PHY */
+#define IMX8MQ_CLK_CSI2_PHY_REF 171
+/* CSI2_ESC */
+#define IMX8MQ_CLK_CSI2_ESC 172
+/* PCIE2_CTRL */
+#define IMX8MQ_CLK_PCIE2_CTRL 173
+/* PCIE2_PHY */
+#define IMX8MQ_CLK_PCIE2_PHY 174
+/* PCIE2_AUX */
+#define IMX8MQ_CLK_PCIE2_AUX 175
+/* ECSPI3 */
+#define IMX8MQ_CLK_ECSPI3 176
+
+/* CCGR clocks */
+#define IMX8MQ_CLK_A53_ROOT 191
+#define IMX8MQ_CLK_DRAM_ROOT 192
+#define IMX8MQ_CLK_ECSPI1_ROOT 193
+#define IMX8MQ_CLK_ECSPI2_ROOT 194
+#define IMX8MQ_CLK_ECSPI3_ROOT 195
+#define IMX8MQ_CLK_ENET1_ROOT 196
+#define IMX8MQ_CLK_GPT1_ROOT 197
+#define IMX8MQ_CLK_I2C1_ROOT 198
+#define IMX8MQ_CLK_I2C2_ROOT 199
+#define IMX8MQ_CLK_I2C3_ROOT 200
+#define IMX8MQ_CLK_I2C4_ROOT 201
+#define IMX8MQ_CLK_M4_ROOT 202
+#define IMX8MQ_CLK_PCIE1_ROOT 203
+#define IMX8MQ_CLK_PCIE2_ROOT 204
+#define IMX8MQ_CLK_PWM1_ROOT 205
+#define IMX8MQ_CLK_PWM2_ROOT 206
+#define IMX8MQ_CLK_PWM3_ROOT 207
+#define IMX8MQ_CLK_PWM4_ROOT 208
+#define IMX8MQ_CLK_QSPI_ROOT 209
+#define IMX8MQ_CLK_SAI1_ROOT 210
+#define IMX8MQ_CLK_SAI2_ROOT 211
+#define IMX8MQ_CLK_SAI3_ROOT 212
+#define IMX8MQ_CLK_SAI4_ROOT 213
+#define IMX8MQ_CLK_SAI5_ROOT 214
+#define IMX8MQ_CLK_SAI6_ROOT 215
+#define IMX8MQ_CLK_UART1_ROOT 216
+#define IMX8MQ_CLK_UART2_ROOT 217
+#define IMX8MQ_CLK_UART3_ROOT 218
+#define IMX8MQ_CLK_UART4_ROOT 219
+#define IMX8MQ_CLK_USB1_CTRL_ROOT 220
+#define IMX8MQ_CLK_USB2_CTRL_ROOT 221
+#define IMX8MQ_CLK_USB1_PHY_ROOT 222
+#define IMX8MQ_CLK_USB2_PHY_ROOT 223
+#define IMX8MQ_CLK_USDHC1_ROOT 224
+#define IMX8MQ_CLK_USDHC2_ROOT 225
+#define IMX8MQ_CLK_WDOG1_ROOT 226
+#define IMX8MQ_CLK_WDOG2_ROOT 227
+#define IMX8MQ_CLK_WDOG3_ROOT 228
+#define IMX8MQ_CLK_GPU_ROOT 229
+#define IMX8MQ_CLK_HEVC_ROOT 230
+#define IMX8MQ_CLK_AVC_ROOT 231
+#define IMX8MQ_CLK_VP9_ROOT 232
+#define IMX8MQ_CLK_HEVC_INTER_ROOT 233
+#define IMX8MQ_CLK_DISP_ROOT 234
+#define IMX8MQ_CLK_HDMI_ROOT 235
+#define IMX8MQ_CLK_HDMI_PHY_ROOT 236
+#define IMX8MQ_CLK_VPU_DEC_ROOT 237
+#define IMX8MQ_CLK_CSI1_ROOT 238
+#define IMX8MQ_CLK_CSI2_ROOT 239
+#define IMX8MQ_CLK_RAWNAND_ROOT 240
+#define IMX8MQ_CLK_SDMA1_ROOT 241
+#define IMX8MQ_CLK_SDMA2_ROOT 242
+#define IMX8MQ_CLK_VPU_G1_ROOT 243
+#define IMX8MQ_CLK_VPU_G2_ROOT 244
+
+/* SCCG PLL GATE */
+#define IMX8MQ_SYS1_PLL_OUT 245
+#define IMX8MQ_SYS2_PLL_OUT 246
+#define IMX8MQ_SYS3_PLL_OUT 247
+#define IMX8MQ_DRAM_PLL_OUT 248
+
+#define IMX8MQ_GPT_3M_CLK 249
+
+#define IMX8MQ_CLK_IPG_ROOT 250
+#define IMX8MQ_CLK_IPG_AUDIO_ROOT 251
+#define IMX8MQ_CLK_SAI1_IPG 252
+#define IMX8MQ_CLK_SAI2_IPG 253
+#define IMX8MQ_CLK_SAI3_IPG 254
+#define IMX8MQ_CLK_SAI4_IPG 255
+#define IMX8MQ_CLK_SAI5_IPG 256
+#define IMX8MQ_CLK_SAI6_IPG 257
+
+/* DSI AHB/IPG clocks */
+/* rxesc clock */
+#define IMX8MQ_CLK_DSI_AHB 258
+/* txesc clock */
+#define IMX8MQ_CLK_DSI_IPG_DIV 259
+
+/* VIDEO2 PLL */
+#define IMX8MQ_VIDEO2_PLL1_REF_SEL 260
+#define IMX8MQ_VIDEO2_PLL1_REF_DIV 261
+#define IMX8MQ_VIDEO2_PLL1 262
+#define IMX8MQ_VIDEO2_PLL1_OUT 263
+#define IMX8MQ_VIDEO2_PLL1_OUT_DIV 264
+#define IMX8MQ_VIDEO2_PLL2 265
+#define IMX8MQ_VIDEO2_PLL2_DIV 266
+#define IMX8MQ_VIDEO2_PLL2_OUT 267
+#define IMX8MQ_CLK_TMU_ROOT 268
+
+/* Display root clocks */
+#define IMX8MQ_CLK_DISP_AXI_ROOT 269
+#define IMX8MQ_CLK_DISP_APB_ROOT 270
+#define IMX8MQ_CLK_DISP_RTRM_ROOT 271
+
+#define IMX8MQ_CLK_OCOTP_ROOT 272
+
+#define IMX8MQ_CLK_DRAM_ALT_ROOT 273
+#define IMX8MQ_CLK_DRAM_CORE 274
+
+#define IMX8MQ_CLK_MU_ROOT 275
+#define IMX8MQ_VIDEO2_PLL_OUT 276
+
+#define IMX8MQ_CLK_CLKO2 277
+
+#define IMX8MQ_CLK_NAND_USDHC_BUS_RAWNAND_CLK 278
+
+#define IMX8MQ_CLK_PHY_27MHZ 279
+
+#define IMX8MQ_CLK_END 280
+
+#endif /* __DT_BINDINGS_CLOCK_IMX8MQ_H */
diff --git a/include/dt-bindings/clock/imx8qm-clock.h b/include/dt-bindings/clock/imx8qm-clock.h
new file mode 100644
index 000000000000..820ea0dcc3d5
--- /dev/null
+++ b/include/dt-bindings/clock/imx8qm-clock.h
@@ -0,0 +1,866 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017 NXP
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __DT_BINDINGS_CLOCK_IMX8QM_H
+#define __DT_BINDINGS_CLOCK_IMX8QM_H
+
+#define IMX8QM_CLK_DUMMY 0
+
+#define IMX8QM_A53_DIV 1
+#define IMX8QM_A53_CLK 2
+#define IMX8QM_A72_DIV 3
+#define IMX8QM_A72_CLK 4
+
+/* SC Clocks. */
+#define IMX8QM_SC_I2C_DIV 5
+#define IMX8QM_SC_I2C_CLK 6
+#define IMX8QM_SC_PID0_DIV 7
+#define IMX8QM_SC_PID0_CLK 8
+#define IMX8QM_SC_PIT_DIV 9
+#define IMX8QM_SC_PIT_CLK 10
+#define IMX8QM_SC_TPM_DIV 11
+#define IMX8QM_SC_TPM_CLK 12
+#define IMX8QM_SC_UART_DIV 13
+#define IMX8QM_SC_UART_CLK 14
+
+/* LSIO */
+#define IMX8QM_PWM0_DIV 15
+#define IMX8QM_PWM0_CLK 16
+#define IMX8QM_PWM1_DIV 17
+#define IMX8QM_PWM1_CLK 18
+#define IMX8QM_PWM2_DIV 19
+#define IMX8QM_PWM2_CLK 20
+#define IMX8QM_PWM3_DIV 21
+#define IMX8QM_PWM3_CLK 22
+#define IMX8QM_PWM4_DIV 23
+#define IMX8QM_PWM4_CLK 24
+#define IMX8QM_PWM5_DIV 26
+#define IMX8QM_PWM5_CLK 27
+#define IMX8QM_PWM6_DIV 28
+#define IMX8QM_PWM6_CLK 29
+#define IMX8QM_PWM7_DIV 30
+#define IMX8QM_PWM7_CLK 31
+#define IMX8QM_FSPI0_DIV 32
+#define IMX8QM_FSPI0_CLK 33
+#define IMX8QM_FSPI1_DIV 34
+#define IMX8QM_FSPI1_CLK 35
+#define IMX8QM_GPT0_DIV 36
+#define IMX8QM_GPT0_CLK 37
+#define IMX8QM_GPT1_DIV 38
+#define IMX8QM_GPT1_CLK 39
+#define IMX8QM_GPT2_DIV 40
+#define IMX8QM_GPT2_CLK 41
+#define IMX8QM_GPT3_DIV 42
+#define IMX8QM_GPT3_CLK 43
+#define IMX8QM_GPT4_DIV 44
+#define IMX8QM_GPT4_CLK 45
+
+/* Connectivity */
+#define IMX8QM_APBHDMA_CLK 46
+#define IMX8QM_GPMI_APB_CLK 47
+#define IMX8QM_GPMI_APB_BCH_CLK 48
+#define IMX8QM_GPMI_BCH_IO_DIV 49
+#define IMX8QM_GPMI_BCH_IO_CLK 50
+#define IMX8QM_GPMI_BCH_DIV 51
+#define IMX8QM_GPMI_BCH_CLK 52
+#define IMX8QM_SDHC0_IPG_CLK 53
+#define IMX8QM_SDHC0_DIV 54
+#define IMX8QM_SDHC0_CLK 55
+#define IMX8QM_SDHC1_IPG_CLK 56
+#define IMX8QM_SDHC1_DIV 57
+#define IMX8QM_SDHC1_CLK 58
+#define IMX8QM_SDHC2_IPG_CLK 59
+#define IMX8QM_SDHC2_DIV 60
+#define IMX8QM_SDHC2_CLK 61
+#define IMX8QM_USB2_OH_AHB_CLK 62
+#define IMX8QM_USB2_OH_IPG_S_CLK 63
+#define IMX8QM_USB2_OH_IPG_S_PL301_CLK 64
+#define IMX8QM_USB2_PHY_IPG_CLK 65
+#define IMX8QM_USB3_IPG_CLK 66
+#define IMX8QM_USB3_CORE_PCLK 67
+#define IMX8QM_USB3_PHY_CLK 68
+#define IMX8QM_USB3_ACLK_DIV 69
+#define IMX8QM_USB3_ACLK 70
+#define IMX8QM_USB3_BUS_DIV 71
+#define IMX8QM_USB3_BUS_CLK 72
+#define IMX8QM_USB3_LPM_DIV 73
+#define IMX8QM_USB3_LPM_CLK 74
+#define IMX8QM_ENET0_AHB_CLK 75
+#define IMX8QM_ENET0_IPG_S_CLK 76
+#define IMX8QM_ENET0_IPG_CLK 77
+#define IMX8QM_ENET0_RGMII_DIV 78
+#define IMX8QM_ENET0_RGMII_TX_CLK 79
+#define IMX8QM_ENET0_ROOT_DIV 80
+#define IMX8QM_ENET0_TX_CLK 81
+#define IMX8QM_ENET0_ROOT_CLK 82
+#define IMX8QM_ENET0_PTP_CLK 83
+#define IMX8QM_ENET0_BYPASS_DIV 84
+#define IMX8QM_ENET1_AHB_CLK 85
+#define IMX8QM_ENET1_IPG_S_CLK 86
+#define IMX8QM_ENET1_IPG_CLK 87
+#define IMX8QM_ENET1_RGMII_DIV 88
+#define IMX8QM_ENET1_RGMII_TX_CLK 89
+#define IMX8QM_ENET1_ROOT_DIV 90
+#define IMX8QM_ENET1_TX_CLK 91
+#define IMX8QM_ENET1_ROOT_CLK 92
+#define IMX8QM_ENET1_PTP_CLK 93
+#define IMX8QM_ENET1_BYPASS_DIV 94
+#define IMX8QM_MLB_CLK 95
+#define IMX8QM_MLB_HCLK 96
+#define IMX8QM_MLB_IPG_CLK 97
+#define IMX8QM_EDMA_CLK 98
+#define IMX8QM_EDMA_IPG_CLK 99
+
+/* DMA */
+#define IMX8QM_SPI0_IPG_CLK 100
+#define IMX8QM_SPI0_DIV 101
+#define IMX8QM_SPI0_CLK 102
+#define IMX8QM_SPI1_IPG_CLK 103
+#define IMX8QM_SPI1_DIV 104
+#define IMX8QM_SPI1_CLK 105
+#define IMX8QM_SPI2_IPG_CLK 106
+#define IMX8QM_SPI2_DIV 107
+#define IMX8QM_SPI2_CLK 108
+#define IMX8QM_SPI3_IPG_CLK 109
+#define IMX8QM_SPI3_DIV 110
+#define IMX8QM_SPI3_CLK 111
+#define IMX8QM_UART0_IPG_CLK 112
+#define IMX8QM_UART0_DIV 113
+#define IMX8QM_UART0_CLK 114
+#define IMX8QM_UART1_IPG_CLK 115
+#define IMX8QM_UART1_DIV 116
+#define IMX8QM_UART1_CLK 117
+#define IMX8QM_UART2_IPG_CLK 118
+#define IMX8QM_UART2_DIV 119
+#define IMX8QM_UART2_CLK 120
+#define IMX8QM_UART3_IPG_CLK 121
+#define IMX8QM_UART3_DIV 122
+#define IMX8QM_UART3_CLK 123
+#define IMX8QM_UART4_IPG_CLK 124
+#define IMX8QM_UART4_DIV 125
+#define IMX8QM_EMVSIM0_IPG_CLK 126
+#define IMX8QM_UART4_CLK 127
+#define IMX8QM_EMVSIM0_DIV 128
+#define IMX8QM_EMVSIM0_CLK 129
+#define IMX8QM_EMVSIM1_IPG_CLK 130
+#define IMX8QM_EMVSIM1_DIV 131
+#define IMX8QM_EMVSIM1_CLK 132
+#define IMX8QM_CAN0_IPG_CHI_CLK 133
+#define IMX8QM_CAN0_IPG_CLK 134
+#define IMX8QM_CAN0_DIV 135
+#define IMX8QM_CAN0_CLK 136
+#define IMX8QM_CAN1_IPG_CHI_CLK 137
+#define IMX8QM_CAN1_IPG_CLK 138
+#define IMX8QM_CAN1_DIV 139
+#define IMX8QM_CAN1_CLK 140
+#define IMX8QM_CAN2_IPG_CHI_CLK 141
+#define IMX8QM_CAN2_IPG_CLK 142
+#define IMX8QM_CAN2_DIV 143
+#define IMX8QM_CAN2_CLK 144
+#define IMX8QM_I2C0_IPG_CLK 145
+#define IMX8QM_I2C0_DIV 146
+#define IMX8QM_I2C0_CLK 147
+#define IMX8QM_I2C1_IPG_CLK 148
+#define IMX8QM_I2C1_DIV 149
+#define IMX8QM_I2C1_CLK 150
+#define IMX8QM_I2C2_IPG_CLK 151
+#define IMX8QM_I2C2_DIV 152
+#define IMX8QM_I2C2_CLK 153
+#define IMX8QM_I2C3_IPG_CLK 154
+#define IMX8QM_I2C3_DIV 155
+#define IMX8QM_I2C3_CLK 156
+#define IMX8QM_I2C4_IPG_CLK 157
+#define IMX8QM_I2C4_DIV 158
+#define IMX8QM_I2C4_CLK 159
+#define IMX8QM_FTM0_IPG_CLK 160
+#define IMX8QM_FTM0_DIV 161
+#define IMX8QM_FTM0_CLK 162
+#define IMX8QM_FTM1_IPG_CLK 163
+#define IMX8QM_FTM1_DIV 164
+#define IMX8QM_FTM1_CLK 165
+#define IMX8QM_ADC0_IPG_CLK 166
+#define IMX8QM_ADC0_DIV 167
+#define IMX8QM_ADC0_CLK 168
+#define IMX8QM_ADC1_IPG_CLK 169
+#define IMX8QM_ADC1_DIV 170
+#define IMX8QM_ADC1_CLK 171
+
+/* Audio */
+#define IMX8QM_AUD_PLL0_DIV 172
+#define IMX8QM_AUD_PLL0 173
+#define IMX8QM_AUD_PLL1_DIV 174
+#define IMX8QM_AUD_PLL1 175
+#define IMX8QM_AUD_AMIX_IPG 182
+#define IMX8QM_AUD_ESAI_0_IPG 183
+#define IMX8QM_AUD_ESAI_1_IPG 184
+#define IMX8QM_AUD_ESAI_0_EXTAL_IPG 185
+#define IMX8QM_AUD_ESAI_1_EXTAL_IPG 186
+#define IMX8QM_AUD_SAI_0_IPG 187
+#define IMX8QM_AUD_SAI_0_IPG_S 188
+#define IMX8QM_AUD_SAI_0_MCLK 189
+#define IMX8QM_AUD_SAI_1_IPG 190
+#define IMX8QM_AUD_SAI_1_IPG_S 191
+#define IMX8QM_AUD_SAI_1_MCLK 192
+#define IMX8QM_AUD_SAI_2_IPG 193
+#define IMX8QM_AUD_SAI_2_IPG_S 194
+#define IMX8QM_AUD_SAI_2_MCLK 195
+#define IMX8QM_AUD_SAI_3_IPG 196
+#define IMX8QM_AUD_SAI_3_IPG_S 197
+#define IMX8QM_AUD_SAI_3_MCLK 198
+#define IMX8QM_AUD_SAI_6_IPG 199
+#define IMX8QM_AUD_SAI_6_IPG_S 200
+#define IMX8QM_AUD_SAI_6_MCLK 201
+#define IMX8QM_AUD_SAI_7_IPG 202
+#define IMX8QM_AUD_SAI_7_IPG_S 203
+#define IMX8QM_AUD_SAI_7_MCLK 204
+#define IMX8QM_AUD_SAI_HDMIRX0_IPG 205
+#define IMX8QM_AUD_SAI_HDMIRX0_IPG_S 206
+#define IMX8QM_AUD_SAI_HDMIRX0_MCLK 207
+#define IMX8QM_AUD_SAI_HDMITX0_IPG 208
+#define IMX8QM_AUD_SAI_HDMITX0_IPG_S 209
+#define IMX8QM_AUD_SAI_HDMITX0_MCLK 210
+#define IMX8QM_AUD_MQS_IPG 211
+#define IMX8QM_AUD_MQS_HMCLK 212
+#define IMX8QM_AUD_GPT5_IPG_S 213
+#define IMX8QM_AUD_GPT5_CLKIN 214
+#define IMX8QM_AUD_GPT5_24M_CLK 215
+#define IMX8QM_AUD_GPT6_IPG_S 216
+#define IMX8QM_AUD_GPT6_CLKIN 217
+#define IMX8QM_AUD_GPT6_24M_CLK 218
+#define IMX8QM_AUD_GPT7_IPG_S 219
+#define IMX8QM_AUD_GPT7_CLKIN 220
+#define IMX8QM_AUD_GPT7_24M_CLK 221
+#define IMX8QM_AUD_GPT8_IPG_S 222
+#define IMX8QM_AUD_GPT8_CLKIN 223
+#define IMX8QM_AUD_GPT8_24M_CLK 224
+#define IMX8QM_AUD_GPT9_IPG_S 225
+#define IMX8QM_AUD_GPT9_CLKIN 226
+#define IMX8QM_AUD_GPT9_24M_CLK 227
+#define IMX8QM_AUD_GPT10_IPG_S 228
+#define IMX8QM_AUD_GPT10_CLKIN 229
+#define IMX8QM_AUD_GPT10_24M_CLK 230
+#define IMX8QM_AUD_ACM_AUD_PLL_CLK0_DIV 232
+#define IMX8QM_AUD_ACM_AUD_PLL_CLK0_CLK 233
+#define IMX8QM_AUD_ACM_AUD_PLL_CLK1_DIV 234
+#define IMX8QM_AUD_ACM_AUD_PLL_CLK1_CLK 235
+#define IMX8QM_AUD_ACM_AUD_REC_CLK0_DIV 236
+#define IMX8QM_AUD_ACM_AUD_REC_CLK0_CLK 237
+#define IMX8QM_AUD_ACM_AUD_REC_CLK1_DIV 238
+#define IMX8QM_AUD_ACM_AUD_REC_CLK1_CLK 239
+#define IMX8QM_AUD_MCLKOUT0 240
+#define IMX8QM_AUD_MCLKOUT1 241
+#define IMX8QM_AUD_SPDIF_0_TX_CLK 242
+#define IMX8QM_AUD_SPDIF_0_GCLKW 243
+#define IMX8QM_AUD_SPDIF_0_IPG_S 244
+#define IMX8QM_AUD_SPDIF_1_TX_CLK 245
+#define IMX8QM_AUD_SPDIF_1_GCLKW 246
+#define IMX8QM_AUD_SPDIF_1_IPG_S 247
+#define IMX8QM_AUD_ASRC_0_IPG 248
+#define IMX8QM_AUD_ASRC_0_MEM 249
+#define IMX8QM_AUD_ASRC_1_IPG 250
+#define IMX8QM_AUD_ASRC_1_MEM 251
+
+
+/* VPU */
+#define IMX8QM_VPU_CORE_DIV 252
+#define IMX8QM_VPU_CORE_CLK 253
+#define IMX8QM_VPU_UART_DIV 254
+#define IMX8QM_VPU_UART_CLK 255
+#define IMX8QM_VPU_DDR_DIV 256
+#define IMX8QM_VPU_DDR_CLK 257
+#define IMX8QM_VPU_SYS_DIV 258
+#define IMX8QM_VPU_SYS_CLK 259
+#define IMX8QM_VPU_XUVI_DIV 260
+#define IMX8QM_VPU_XUVI_CLK 261
+
+/* GPU Clocks. */
+#define IMX8QM_GPU0_CORE_DIV 262
+#define IMX8QM_GPU0_CORE_CLK 263
+#define IMX8QM_GPU0_SHADER_DIV 264
+#define IMX8QM_GPU0_SHADER_CLK 265
+#define IMX8QM_GPU1_CORE_DIV 266
+#define IMX8QM_GPU1_CORE_CLK 267
+#define IMX8QM_GPU1_SHADER_DIV 268
+#define IMX8QM_GPU1_SHADER_CLK 269
+
+
+/* MIPI CSI */
+#define IMX8QM_CSI0_IPG_CLK_S 270
+#define IMX8QM_CSI0_LIS_IPG_CLK 271
+#define IMX8QM_CSI0_APB_CLK 272
+#define IMX8QM_CSI0_I2C0_DIV 273
+#define IMX8QM_CSI0_I2C0_CLK 274
+#define IMX8QM_CSI0_PWM0_DIV 275
+#define IMX8QM_CSI0_PWM0_CLK 276
+#define IMX8QM_CSI0_CORE_DIV 277
+#define IMX8QM_CSI0_CORE_CLK 278
+#define IMX8QM_CSI0_ESC_DIV 279
+#define IMX8QM_CSI0_ESC_CLK 280
+#define IMX8QM_CSI1_IPG_CLK_S 281
+#define IMX8QM_CSI1_LIS_IPG_CLK 282
+#define IMX8QM_CSI1_APB_CLK 283
+#define IMX8QM_CSI1_I2C0_DIV 284
+#define IMX8QM_CSI1_I2C0_CLK 285
+#define IMX8QM_CSI1_PWM0_DIV 286
+#define IMX8QM_CSI1_PWM0_CLK 287
+#define IMX8QM_CSI1_CORE_DIV 288
+#define IMX8QM_CSI1_CORE_CLK 289
+#define IMX8QM_CSI1_ESC_DIV 290
+#define IMX8QM_CSI1_ESC_CLK 291
+
+
+/* Display */
+#define IMX8QM_DC0_PLL0_DIV 292
+#define IMX8QM_DC0_PLL0_CLK 293
+#define IMX8QM_DC0_PLL1_DIV 294
+#define IMX8QM_DC0_PLL1_CLK 295
+#define IMX8QM_DC0_DISP0_DIV 296
+#define IMX8QM_DC0_DISP0_CLK 297
+#define IMX8QM_DC0_DISP1_DIV 298
+#define IMX8QM_DC0_DISP1_CLK 299
+#define IMX8QM_DC0_BYPASS_0_DIV 300
+#define IMX8QM_DC0_BYPASS_1_DIV 301
+#define IMX8QM_DC0_IRIS_AXI_CLK 302
+#define IMX8AM_DC0_IRIS_MVPL_CLK 303
+#define IMX8QM_DC0_DISP0_MSI_CLK 304
+#define IMX8QM_DC0_LIS_IPG_CLK 305
+#define IMX8QM_DC0_PXL_CMB_APB_CLK 306
+#define IMX8QM_DC0_PRG0_RTRAM_CLK 307
+#define IMX8QM_DC0_PRG1_RTRAM_CLK 308
+#define IMX8QM_DC0_PRG2_RTRAM_CLK 309
+#define IMX8QM_DC0_PRG3_RTRAM_CLK 310
+#define IMX8QM_DC0_PRG4_RTRAM_CLK 311
+#define IMX8QM_DC0_PRG5_RTRAM_CLK 312
+#define IMX8QM_DC0_PRG6_RTRAM_CLK 313
+#define IMX8QM_DC0_PRG7_RTRAM_CLK 314
+#define IMX8QM_DC0_PRG8_RTRAM_CLK 315
+#define IMX8QM_DC0_PRG0_APB_CLK 316
+#define IMX8QM_DC0_PRG1_APB_CLK 317
+#define IMX8QM_DC0_PRG2_APB_CLK 318
+#define IMX8QM_DC0_PRG3_APB_CLK 319
+#define IMX8QM_DC0_PRG4_APB_CLK 320
+#define IMX8QM_DC0_PRG5_APB_CLK 321
+#define IMX8QM_DC0_PRG6_APB_CLK 322
+#define IMX8QM_DC0_PRG7_APB_CLK 323
+#define IMX8QM_DC0_PRG8_APB_CLK 324
+#define IMX8QM_DC0_DPR0_APB_CLK 325
+#define IMX8QM_DC0_DPR1_APB_CLK 326
+#define IMX8QM_DC0_RTRAM0_CLK 327
+#define IMX8QM_DC0_RTRAM1_CLK 328
+#define IMX8QM_DC1_PLL0_DIV 329
+#define IMX8QM_DC1_PLL0_CLK 330
+#define IMX8QM_DC1_PLL1_DIV 331
+#define IMX8QM_DC1_PLL1_CLK 332
+#define IMX8QM_DC1_DISP0_DIV 333
+#define IMX8QM_DC1_DISP0_CLK 334
+#define IMX8QM_DC1_BYPASS_0_DIV 335
+#define IMX8QM_DC1_BYPASS_1_DIV 336
+#define IMX8QM_DC1_DISP1_DIV 337
+#define IMX8QM_DC1_DISP1_CLK 338
+#define IMX8QM_DC1_IRIS_AXI_CLK 339
+#define IMX8AM_DC1_IRIS_MVPL_CLK 340
+#define IMX8QM_DC1_DISP0_MSI_CLK 341
+#define IMX8QM_DC1_LIS_IPG_CLK 342
+#define IMX8QM_DC1_PXL_CMB_APB_CLK 343
+#define IMX8QM_DC1_PRG0_RTRAM_CLK 344
+#define IMX8QM_DC1_PRG1_RTRAM_CLK 345
+#define IMX8QM_DC1_PRG2_RTRAM_CLK 346
+#define IMX8QM_DC1_PRG3_RTRAM_CLK 347
+#define IMX8QM_DC1_PRG4_RTRAM_CLK 348
+#define IMX8QM_DC1_PRG5_RTRAM_CLK 349
+#define IMX8QM_DC1_PRG6_RTRAM_CLK 350
+#define IMX8QM_DC1_PRG7_RTRAM_CLK 351
+#define IMX8QM_DC1_PRG8_RTRAM_CLK 352
+#define IMX8QM_DC1_PRG0_APB_CLK 353
+#define IMX8QM_DC1_PRG1_APB_CLK 354
+#define IMX8QM_DC1_PRG2_APB_CLK 355
+#define IMX8QM_DC1_PRG3_APB_CLK 356
+#define IMX8QM_DC1_PRG4_APB_CLK 357
+#define IMX8QM_DC1_PRG5_APB_CLK 358
+#define IMX8QM_DC1_PRG6_APB_CLK 359
+#define IMX8QM_DC1_PRG7_APB_CLK 360
+#define IMX8QM_DC1_PRG8_APB_CLK 361
+#define IMX8QM_DC1_DPR0_APB_CLK 362
+#define IMX8QM_DC1_DPR1_APB_CLK 363
+#define IMX8QM_DC1_RTRAM0_CLK 364
+#define IMX8QM_DC1_RTRAM1_CLK 365
+
+/* DRC */
+#define IMX8QM_DRC0_PLL0_DIV 366
+#define IMX8QM_DRC0_PLL0_CLK 367
+#define IMX8QM_DRC0_DIV 368
+#define IMX8QM_DRC0_CLK 369
+#define IMX8QM_DRC1_PLL0_DIV 370
+#define IMX8QM_DRC1_PLL0_CLK 371
+#define IMX8QM_DRC1_DIV 372
+#define IMX8QM_DRC1_CLK 373
+
+/* HDMI */
+#define IMX8QM_HDMI_AV_PLL_DIV 374
+#define IMX8QM_HDMI_AV_PLL_CLK 375
+#define IMX8QM_HDMI_I2S_BYPASS_CLK 376
+#define IMX8QM_HDMI_I2C0_DIV 377
+#define IMX8QM_HDMI_I2C0_CLK 378
+#define IMX8QM_HDMI_PXL_DIV 379
+#define IMX8QM_HDMI_PXL_CLK 380
+#define IMX8QM_HDMI_PXL_LINK_DIV 381
+#define IMX8QM_HDMI_PXL_LINK_CLK 382
+#define IMX8QM_HDMI_PXL_MUX_DIV 383
+#define IMX8QM_HDMI_PXL_MUX_CLK 384
+#define IMX8QM_HDMI_I2S_DIV 385
+#define IMX8QM_HDMI_I2S_CLK 386
+#define IMX8QM_HDMI_HDP_CORE_DIV 387
+#define IMX8QM_HDMI_HDP_CORE_CLK 388
+#define IMX8QM_HDMI_I2C_IPG_S_CLK 389
+#define IMX8QM_HDMI_I2C_IPG_CLK 390
+#define IMX8QM_HDMI_PWM_IPG_S_CLK 391
+#define IMX8QM_HDMI_PWM_IPG_CLK 392
+#define IMX8QM_HDMI_PWM_32K_CLK 393
+#define IMX8QM_HDMI_GPIO_IPG_CLK 394
+#define IMX8QM_HDMI_PXL_LINK_SLV_ODD_CLK 395
+#define IMX8QM_HDMI_PXL_LINK_SLV_EVEN_CLK 396
+#define IMX8QM_HDMI_LIS_IPG_CLK 397
+#define IMX8QM_HDMI_MSI_HCLK 398
+#define IMX8QM_HDMI_PXL_EVEN_CLK 399
+#define IMX8QM_HDMI_HDP_CLK 400
+#define IMX8QM_HDMI_PXL_DBL_CLK 401
+#define IMX8QM_HDMI_APB_CLK 402
+#define IMX8QM_HDMI_PXL_LPCG_CLK 403
+#define IMX8QM_HDMI_HDP_PHY_CLK 404
+#define IMX8QM_HDMI_IPG_DIV 405
+#define IMX8QM_HDMI_VIF_CLK 406
+#define IMX8QM_HDMI_DIG_PLL_DIV 407
+#define IMX8QM_HDMI_DIG_PLL_CLK 408
+#define IMX8QM_HDMI_APB_MUX_CSR_CLK 409
+#define IMX8QM_HDMI_APB_MUX_CTRL_CLK 410
+
+/* RX-HDMI */
+#define IMX8QM_HDMI_RX_I2S_BYPASS_CLK 411
+#define IMX8QM_HDMI_RX_BYPASS_CLK 412
+#define IMX8QM_HDMI_RX_SPDIF_BYPASS_CLK 413
+#define IMX8QM_HDMI_RX_I2C0_DIV 414
+#define IMX8QM_HDMI_RX_I2C0_CLK 415
+#define IMX8QM_HDMI_RX_SPDIF_DIV 416
+#define IMX8QM_HDMI_RX_SPDIF_CLK 417
+#define IMX8QM_HDMI_RX_HD_REF_DIV 418
+#define IMX8QM_HDMI_RX_HD_REF_CLK 419
+#define IMX8QM_HDMI_RX_HD_CORE_DIV 420
+#define IMX8QM_HDMI_RX_HD_CORE_CLK 421
+#define IMX8QM_HDMI_RX_PXL_DIV 422
+#define IMX8QM_HDMI_RX_PXL_CLK 423
+#define IMX8QM_HDMI_RX_I2S_DIV 424
+#define IMX8QM_HDMI_RX_I2S_CLK 425
+#define IMX8QM_HDMI_RX_PWM_DIV 426
+#define IMX8QM_HDMI_RX_PWM_CLK 427
+
+/* LVDS */
+#define IMX8QM_LVDS0_BYPASS_CLK 428
+#define IMX8QM_LVDS0_PIXEL_DIV 429
+#define IMX8QM_LVDS0_PIXEL_CLK 430
+#define IMX8QM_LVDS0_PHY_DIV 431
+#define IMX8QM_LVDS0_PHY_CLK 432
+#define IMX8QM_LVDS0_I2C0_IPG_CLK 433
+#define IMX8QM_LVDS0_I2C0_DIV 434
+#define IMX8QM_LVDS0_I2C0_CLK 435
+#define IMX8QM_LVDS0_I2C1_IPG_CLK 436
+#define IMX8QM_LVDS0_I2C1_DIV 437
+#define IMX8QM_LVDS0_I2C1_CLK 438
+#define IMX8QM_LVDS0_PWM0_IPG_CLK 439
+#define IMX8QM_LVDS0_PWM0_DIV 440
+#define IMX8QM_LVDS0_PWM0_CLK 441
+#define IMX8QM_LVDS0_GPIO_IPG_CLK 444
+#define IMX8QM_LVDS1_BYPASS_DIV 445
+#define IMX8QM_LVDS1_BYPASS_CLK 446
+#define IMX8QM_LVDS1_PIXEL_DIV 447
+#define IMX8QM_LVDS1_PIXEL_CLK 448
+#define IMX8QM_LVDS1_PHY_DIV 449
+#define IMX8QM_LVDS1_PHY_CLK 450
+#define IMX8QM_LVDS1_I2C0_IPG_CLK 451
+#define IMX8QM_LVDS1_I2C0_DIV 452
+#define IMX8QM_LVDS1_I2C0_CLK 453
+#define IMX8QM_LVDS1_I2C1_IPG_CLK 454
+#define IMX8QM_LVDS1_I2C1_DIV 455
+#define IMX8QM_LVDS1_I2C1_CLK 456
+#define IMX8QM_LVDS1_PWM0_IPG_CLK 457
+#define IMX8QM_LVDS1_PWM0_DIV 458
+#define IMX8QM_LVDS1_PWM0_CLK 459
+#define IMX8QM_LVDS1_GPIO_IPG_CLK 462
+
+/* MIPI */
+#define IMX8QM_MIPI0_BYPASS_CLK 465
+#define IMX8QM_MIPI0_I2C0_DIV 466
+#define IMX8QM_MIPI0_I2C0_CLK 467
+#define IMX8QM_MIPI0_I2C1_DIV 468
+#define IMX8QM_MIPI0_I2C1_CLK 469
+#define IMX8QM_MIPI0_PWM0_DIV 470
+#define IMX8QM_MIPI0_PWM0_CLK 471
+#define IMX8QM_MIPI0_DSI_TX_ESC_DIV 472
+#define IMX8QM_MIPI0_DSI_TX_ESC_CLK 473
+#define IMX8QM_MIPI0_DSI_RX_ESC_DIV 474
+#define IMX8QM_MIPI0_DSI_RX_ESC_CLK 475
+#define IMX8QM_MIPI0_PXL_DIV 476
+#define IMX8QM_MIPI0_PXL_CLK 477
+#define IMX8QM_MIPI1_BYPASS_CLK 479
+#define IMX8QM_MIPI1_I2C0_DIV 480
+#define IMX8QM_MIPI1_I2C0_CLK 481
+#define IMX8QM_MIPI1_I2C1_DIV 482
+#define IMX8QM_MIPI1_I2C1_CLK 483
+#define IMX8QM_MIPI1_PWM0_DIV 484
+#define IMX8QM_MIPI1_PWM0_CLK 485
+#define IMX8QM_MIPI1_DSI_TX_ESC_DIV 486
+#define IMX8QM_MIPI1_DSI_TX_ESC_CLK 487
+#define IMX8QM_MIPI1_DSI_RX_ESC_DIV 488
+#define IMX8QM_MIPI1_DSI_RX_ESC_CLK 489
+#define IMX8QM_MIPI1_PXL_DIV 490
+#define IMX8QM_MIPI1_PXL_CLK 491
+
+/* Imaging */
+#define IMX8QM_IMG_JPEG_ENC_IPG_CLK 492
+#define IMX8QM_IMG_JPEG_ENC_CLK 493
+#define IMX8QM_IMG_JPEG_DEC_IPG_CLK 494
+#define IMX8QM_IMG_JPEG_DEC_CLK 495
+#define IMX8QM_IMG_PXL_LINK_DC0_CLK 496
+#define IMX8QM_IMG_PXL_LINK_DC1_CLK 497
+#define IMX8QM_IMG_PXL_LINK_CSI0_CLK 498
+#define IMX8QM_IMG_PXL_LINK_CSI1_CLK 499
+#define IMX8QM_IMG_PXL_LINK_HDMI_IN_CLK 500
+#define IMX8QM_IMG_PDMA_0_CLK 501
+#define IMX8QM_IMG_PDMA_1_CLK 502
+#define IMX8QM_IMG_PDMA_2_CLK 503
+#define IMX8QM_IMG_PDMA_3_CLK 504
+#define IMX8QM_IMG_PDMA_4_CLK 505
+#define IMX8QM_IMG_PDMA_5_CLK 506
+#define IMX8QM_IMG_PDMA_6_CLK 507
+#define IMX8QM_IMG_PDMA_7_CLK 508
+
+/* HSIO */
+#define IMX8QM_HSIO_PCIE_A_MSTR_AXI_CLK 509
+#define IMX8QM_HSIO_PCIE_A_SLV_AXI_CLK 510
+#define IMX8QM_HSIO_PCIE_A_DBI_AXI_CLK 511
+#define IMX8QM_HSIO_PCIE_B_MSTR_AXI_CLK 512
+#define IMX8QM_HSIO_PCIE_B_SLV_AXI_CLK 513
+#define IMX8QM_HSIO_PCIE_B_DBI_AXI_CLK 514
+#define IMX8QM_HSIO_PCIE_X1_PER_CLK 515
+#define IMX8QM_HSIO_PCIE_X2_PER_CLK 516
+#define IMX8QM_HSIO_SATA_PER_CLK 517
+#define IMX8QM_HSIO_PHY_X1_PER_CLK 518
+#define IMX8QM_HSIO_PHY_X2_PER_CLK 519
+#define IMX8QM_HSIO_MISC_PER_CLK 520
+#define IMX8QM_HSIO_PHY_X1_APB_CLK 521
+#define IMX8QM_HSIO_PHY_X2_APB_0_CLK 522
+#define IMX8QM_HSIO_PHY_X2_APB_1_CLK 523
+#define IMX8QM_HSIO_SATA_CLK 524
+#define IMX8QM_HSIO_GPIO_CLK 525
+#define IMX8QM_HSIO_PHY_X1_PCLK 526
+#define IMX8QM_HSIO_PHY_X2_PCLK_0 527
+#define IMX8QM_HSIO_PHY_X2_PCLK_1 528
+#define IMX8QM_HSIO_SATA_EPCS_RX_CLK 529
+#define IMX8QM_HSIO_SATA_EPCS_TX_CLK 530
+
+
+/* M4 */
+#define IMX8QM_M4_0_CORE_DIV 531
+#define IMX8QM_M4_0_CORE_CLK 532
+#define IMX8QM_M4_0_I2C_DIV 533
+#define IMX8QM_M4_0_I2C_CLK 534
+#define IMX8QM_M4_0_PIT_DIV 535
+#define IMX8QM_M4_0_PIT_CLK 536
+#define IMX8QM_M4_0_TPM_DIV 537
+#define IMX8QM_M4_0_TPM_CLK 538
+#define IMX8QM_M4_0_UART_DIV 539
+#define IMX8QM_M4_0_UART_CLK 540
+#define IMX8QM_M4_0_WDOG_DIV 541
+#define IMX8QM_M4_0_WDOG_CLK 542
+#define IMX8QM_M4_1_CORE_DIV 543
+#define IMX8QM_M4_1_CORE_CLK 544
+#define IMX8QM_M4_1_I2C_DIV 545
+#define IMX8QM_M4_1_I2C_CLK 546
+#define IMX8QM_M4_1_PIT_DIV 547
+#define IMX8QM_M4_1_PIT_CLK 548
+#define IMX8QM_M4_1_TPM_DIV 549
+#define IMX8QM_M4_1_TPM_CLK 550
+#define IMX8QM_M4_1_UART_DIV 551
+#define IMX8QM_M4_1_UART_CLK 552
+#define IMX8QM_M4_1_WDOG_DIV 553
+#define IMX8QM_M4_1_WDOG_CLK 554
+
+/* IPG clocks */
+#define IMX8QM_24MHZ 555
+#define IMX8QM_GPT_3M 556
+#define IMX8QM_IPG_DMA_CLK_ROOT 557
+#define IMX8QM_IPG_AUD_CLK_ROOT 558
+#define IMX8QM_IPG_CONN_CLK_ROOT 559
+#define IMX8QM_AHB_CONN_CLK_ROOT 560
+#define IMX8QM_AXI_CONN_CLK_ROOT 561
+#define IMX8QM_IPG_MIPI_CSI_CLK_ROOT 562
+#define IMX8QM_DC_AXI_EXT_CLK 563
+#define IMX8QM_DC_AXI_INT_CLK 564
+#define IMX8QM_DC_CFG_CLK 565
+#define IMX8QM_HDMI_IPG_CLK 566
+#define IMX8QM_LVDS_IPG_CLK 567
+#define IMX8QM_IMG_AXI_CLK 568
+#define IMX8QM_IMG_IPG_CLK 569
+#define IMX8QM_IMG_PXL_CLK 570
+#define IMX8QM_CSI0_I2C0_IPG_CLK 571
+#define IMX8QM_CSI0_PWM0_IPG_CLK 572
+#define IMX8QM_CSI1_I2C0_IPG_CLK 573
+#define IMX8QM_CSI1_PWM0_IPG_CLK 574
+#define IMX8QM_DC0_DPR0_B_CLK 575
+#define IMX8QM_DC0_DPR1_B_CLK 576
+#define IMX8QM_DC1_DPR0_B_CLK 577
+#define IMX8QM_DC1_DPR1_B_CLK 578
+#define IMX8QM_32KHZ 579
+#define IMX8QM_HSIO_AXI_CLK 580
+#define IMX8QM_HSIO_PER_CLK 581
+#define IMX8QM_HDMI_RX_GPIO_IPG_S_CLK 582
+#define IMX8QM_HDMI_RX_PWM_IPG_S_CLK 583
+#define IMX8QM_HDMI_RX_PWM_IPG_CLK 584
+#define IMX8QM_HDMI_RX_I2C_DIV_CLK 585
+#define IMX8QM_HDMI_RX_I2C_IPG_S_CLK 586
+#define IMX8QM_HDMI_RX_I2C_IPG_CLK 587
+#define IMX8QM_HDMI_RX_SINK_PCLK 588
+#define IMX8QM_HDMI_RX_SINK_SCLK 589
+#define IMX8QM_HDMI_RX_PXL_ENC_CLK 590
+#define IMX8QM_HDMI_RX_IPG_CLK 591
+
+/* ACM */
+#define IMX8QM_HDMI_RX_MCLK 592
+#define IMX8QM_EXT_AUD_MCLK0 593
+#define IMX8QM_EXT_AUD_MCLK1 594
+#define IMX8QM_ESAI0_RX_CLK 595
+#define IMX8QM_ESAI0_RX_HF_CLK 596
+#define IMX8QM_ESAI0_TX_CLK 597
+#define IMX8QM_ESAI0_TX_HF_CLK 598
+#define IMX8QM_ESAI1_RX_CLK 599
+#define IMX8QM_ESAI1_RX_HF_CLK 600
+#define IMX8QM_ESAI1_TX_CLK 601
+#define IMX8QM_ESAI1_TX_HF_CLK 602
+#define IMX8QM_SPDIF0_RX 603
+#define IMX8QM_SPDIF1_RX 604
+#define IMX8QM_SAI0_RX_BCLK 605
+#define IMX8QM_SAI0_TX_BCLK 606
+#define IMX8QM_SAI1_RX_BCLK 607
+#define IMX8QM_SAI1_TX_BCLK 608
+#define IMX8QM_SAI2_RX_BCLK 609
+#define IMX8QM_SAI3_RX_BCLK 610
+#define IMX8QM_HDMI_RX_SAI0_RX_BCLK 611
+#define IMX8QM_SAI6_RX_BCLK 612
+#define IMX8QM_HDMI_TX_SAI0_TX_BCLK 613
+
+#define IMX8QM_ACM_AUD_CLK0_SEL 614
+#define IMX8QM_ACM_AUD_CLK0_CLK 615
+#define IMX8QM_ACM_AUD_CLK1_SEL 616
+#define IMX8QM_ACM_AUD_CLK1_CLK 617
+#define IMX8QM_ACM_MCLKOUT0_SEL 618
+#define IMX8QM_ACM_MCLKOUT0_CLK 619
+#define IMX8QM_ACM_MCLKOUT1_SEL 620
+#define IMX8QM_ACM_MCLKOUT1_CLK 621
+#define IMX8QM_ACM_ASRC0_MUX_CLK_SEL 622
+#define IMX8QM_ACM_ASRC0_MUX_CLK_CLK 623
+#define IMX8QM_ACM_ASRC1_MUX_CLK_SEL 624
+#define IMX8QM_ACM_ASRC1_MUX_CLK_CLK 625
+#define IMX8QM_ACM_ESAI0_MCLK_SEL 626
+#define IMX8QM_ACM_ESAI0_MCLK_CLK 627
+#define IMX8QM_ACM_ESAI1_MCLK_SEL 628
+#define IMX8QM_ACM_ESAI1_MCLK_CLK 629
+#define IMX8QM_ACM_GPT0_MUX_CLK_SEL 630
+#define IMX8QM_ACM_GPT0_MUX_CLK_CLK 631
+#define IMX8QM_ACM_GPT1_MUX_CLK_SEL 632
+#define IMX8QM_ACM_GPT1_MUX_CLK_CLK 633
+#define IMX8QM_ACM_GPT2_MUX_CLK_SEL 634
+#define IMX8QM_ACM_GPT2_MUX_CLK_CLK 635
+#define IMX8QM_ACM_GPT3_MUX_CLK_SEL 636
+#define IMX8QM_ACM_GPT3_MUX_CLK_CLK 637
+#define IMX8QM_ACM_GPT4_MUX_CLK_SEL 638
+#define IMX8QM_ACM_GPT4_MUX_CLK_CLK 639
+#define IMX8QM_ACM_GPT5_MUX_CLK_SEL 640
+#define IMX8QM_ACM_GPT5_MUX_CLK_CLK 641
+#define IMX8QM_ACM_SAI0_MCLK_SEL 642
+#define IMX8QM_ACM_SAI0_MCLK_CLK 643
+#define IMX8QM_ACM_SAI1_MCLK_SEL 644
+#define IMX8QM_ACM_SAI1_MCLK_CLK 645
+#define IMX8QM_ACM_SAI2_MCLK_SEL 646
+#define IMX8QM_ACM_SAI2_MCLK_CLK 647
+#define IMX8QM_ACM_SAI3_MCLK_SEL 648
+#define IMX8QM_ACM_SAI3_MCLK_CLK 649
+#define IMX8QM_ACM_HDMI_RX_SAI0_MCLK_SEL 650
+#define IMX8QM_ACM_HDMI_RX_SAI0_MCLK_CLK 651
+#define IMX8QM_ACM_HDMI_TX_SAI0_MCLK_SEL 652
+#define IMX8QM_ACM_HDMI_TX_SAI0_MCLK_CLK 653
+#define IMX8QM_ACM_SAI6_MCLK_SEL 654
+#define IMX8QM_ACM_SAI6_MCLK_CLK 655
+#define IMX8QM_ACM_SAI7_MCLK_SEL 656
+#define IMX8QM_ACM_SAI7_MCLK_CLK 657
+#define IMX8QM_ACM_SPDIF0_TX_CLK_SEL 658
+#define IMX8QM_ACM_SPDIF0_TX_CLK_CLK 659
+#define IMX8QM_ACM_SPDIF1_TX_CLK_SEL 660
+#define IMX8QM_ACM_SPDIF1_TX_CLK_CLK 661
+#define IMX8QM_ACM_MQS_TX_CLK_SEL 662
+#define IMX8QM_ACM_MQS_TX_CLK_CLK 663
+
+#define IMX8QM_ENET0_REF_25MHZ_125MHZ_SEL 664
+#define IMX8QM_ENET0_REF_25MHZ_125MHZ_CLK 665
+#define IMX8QM_ENET1_REF_25MHZ_125MHZ_SEL 666
+#define IMX8QM_ENET1_REF_25MHZ_125MHZ_CLK 667
+#define IMX8QM_ENET0_REF_50MHZ_CLK 668
+#define IMX8QM_ENET1_REF_50MHZ_CLK 669
+#define IMX8QM_ENET_25MHZ_CLK 670
+#define IMX8QM_ENET_125MHZ_CLK 671
+#define IMX8QM_ENET0_REF_DIV 672
+#define IMX8QM_ENET0_REF_CLK 673
+#define IMX8QM_ENET1_REF_DIV 674
+#define IMX8QM_ENET1_REF_CLK 675
+#define IMX8QM_ENET0_RMII_TX_CLK 676
+#define IMX8QM_ENET1_RMII_TX_CLK 677
+#define IMX8QM_ENET0_RMII_TX_SEL 678
+#define IMX8QM_ENET1_RMII_TX_SEL 679
+#define IMX8QM_ENET0_RMII_RX_CLK 680
+#define IMX8QM_ENET1_RMII_RX_CLK 681
+
+#define IMX8QM_KPP_CLK 683
+#define IMX8QM_GPT0_HF_CLK 684
+#define IMX8QM_GPT0_IPG_S_CLK 685
+#define IMX8QM_GPT0_IPG_SLV_CLK 686
+#define IMX8QM_GPT0_IPG_MSTR_CLK 687
+#define IMX8QM_GPT1_HF_CLK 688
+#define IMX8QM_GPT1_IPG_S_CLK 689
+#define IMX8QM_GPT1_IPG_SLV_CLK 690
+#define IMX8QM_GPT1_IPG_MSTR_CLK 691
+#define IMX8QM_GPT2_HF_CLK 692
+#define IMX8QM_GPT2_IPG_S_CLK 693
+#define IMX8QM_GPT2_IPG_SLV_CLK 694
+#define IMX8QM_GPT2_IPG_MSTR_CLK 695
+#define IMX8QM_GPT3_HF_CLK 696
+#define IMX8QM_GPT3_IPG_S_CLK 697
+#define IMX8QM_GPT3_IPG_SLV_CLK 698
+#define IMX8QM_GPT3_IPG_MSTR_CLK 699
+#define IMX8QM_GPT4_HF_CLK 700
+#define IMX8QM_GPT4_IPG_S_CLK 701
+#define IMX8QM_GPT4_IPG_SLV_CLK 702
+#define IMX8QM_GPT4_IPG_MSTR_CLK 703
+#define IMX8QM_PWM0_HF_CLK 704
+#define IMX8QM_PWM0_IPG_S_CLK 705
+#define IMX8QM_PWM0_IPG_SLV_CLK 706
+#define IMX8QM_PWM0_IPG_MSTR_CLK 707
+#define IMX8QM_PWM1_HF_CLK 708
+#define IMX8QM_PWM1_IPG_S_CLK 709
+#define IMX8QM_PWM1_IPG_SLV_CLK 710
+#define IMX8QM_PWM1_IPG_MSTR_CLK 711
+#define IMX8QM_PWM2_HF_CLK 712
+#define IMX8QM_PWM2_IPG_S_CLK 713
+#define IMX8QM_PWM2_IPG_SLV_CLK 714
+#define IMX8QM_PWM2_IPG_MSTR_CLK 715
+#define IMX8QM_PWM3_HF_CLK 716
+#define IMX8QM_PWM3_IPG_S_CLK 717
+#define IMX8QM_PWM3_IPG_SLV_CLK 718
+#define IMX8QM_PWM3_IPG_MSTR_CLK 719
+#define IMX8QM_PWM4_HF_CLK 720
+#define IMX8QM_PWM4_IPG_S_CLK 721
+#define IMX8QM_PWM4_IPG_SLV_CLK 722
+#define IMX8QM_PWM4_IPG_MSTR_CLK 723
+#define IMX8QM_PWM5_HF_CLK 724
+#define IMX8QM_PWM5_IPG_S_CLK 725
+#define IMX8QM_PWM5_IPG_SLV_CLK 726
+#define IMX8QM_PWM5_IPG_MSTR_CLK 727
+#define IMX8QM_PWM6_HF_CLK 728
+#define IMX8QM_PWM6_IPG_S_CLK 729
+#define IMX8QM_PWM6_IPG_SLV_CLK 730
+#define IMX8QM_PWM6_IPG_MSTR_CLK 731
+#define IMX8QM_PWM7_HF_CLK 732
+#define IMX8QM_PWM7_IPG_S_CLK 733
+#define IMX8QM_PWM7_IPG_SLV_CLK 734
+#define IMX8QM_PWM7_IPG_MSTR_CLK 735
+#define IMX8QM_FSPI0_HCLK 736
+#define IMX8QM_FSPI0_IPG_CLK 737
+#define IMX8QM_FSPI0_IPG_S_CLK 738
+#define IMX8QM_FSPI1_HCLK 736
+#define IMX8QM_FSPI1_IPG_CLK 737
+#define IMX8QM_FSPI1_IPG_S_CLK 738
+#define IMX8QM_GPIO0_IPG_S_CLK 739
+#define IMX8QM_GPIO1_IPG_S_CLK 740
+#define IMX8QM_GPIO2_IPG_S_CLK 741
+#define IMX8QM_GPIO3_IPG_S_CLK 742
+#define IMX8QM_GPIO4_IPG_S_CLK 743
+#define IMX8QM_GPIO5_IPG_S_CLK 744
+#define IMX8QM_GPIO6_IPG_S_CLK 745
+#define IMX8QM_GPIO7_IPG_S_CLK 746
+#define IMX8QM_ROMCP_CLK 747
+#define IMX8QM_ROMCP_REG_CLK 748
+#define IMX8QM_96KROM_CLK 749
+#define IMX8QM_OCRAM_MEM_CLK 750
+#define IMX8QM_OCRAM_CTRL_CLK 751
+#define IMX8QM_LSIO_BUS_CLK 752
+#define IMX8QM_LSIO_MEM_CLK 753
+#define IMX8QM_LVDS0_LIS_IPG_CLK 754
+#define IMX8QM_LVDS1_LIS_IPG_CLK 755
+#define IMX8QM_MIPI0_LIS_IPG_CLK 756
+#define IMX8QM_MIPI0_I2C0_IPG_S_CLK 757
+#define IMX8QM_MIPI0_I2C0_IPG_CLK 758
+#define IMX8QM_MIPI0_I2C1_IPG_S_CLK 759
+#define IMX8QM_MIPI0_I2C1_IPG_CLK 760
+#define IMX8QM_MIPI0_CLK_ROOT 761
+#define IMX8QM_MIPI1_LIS_IPG_CLK 762
+#define IMX8QM_MIPI1_I2C0_IPG_S_CLK 763
+#define IMX8QM_MIPI1_I2C0_IPG_CLK 764
+#define IMX8QM_MIPI1_I2C1_IPG_S_CLK 765
+#define IMX8QM_MIPI1_I2C1_IPG_CLK 766
+#define IMX8QM_MIPI1_CLK_ROOT 767
+#define IMX8QM_DC0_DISP0_SEL 768
+#define IMX8QM_DC0_DISP1_SEL 769
+#define IMX8QM_DC1_DISP0_SEL 770
+#define IMX8QM_DC1_DISP1_SEL 771
+
+/* CM40 */
+#define IMX8QM_CM40_IPG_CLK 772
+#define IMX8QM_CM40_I2C_DIV 773
+#define IMX8QM_CM40_I2C_CLK 774
+#define IMX8QM_CM40_I2C_IPG_CLK 775
+
+/* CM41 */
+#define IMX8QM_CM41_IPG_CLK 776
+#define IMX8QM_CM41_I2C_DIV 777
+#define IMX8QM_CM41_I2C_CLK 778
+#define IMX8QM_CM41_I2C_IPG_CLK 779
+
+#define IMX8QM_HDMI_PXL_SEL 780
+#define IMX8QM_HDMI_PXL_LINK_SEL 781
+#define IMX8QM_HDMI_PXL_MUX_SEL 782
+#define IMX8QM_HDMI_AV_PLL_BYPASS_CLK 783
+
+#define IMX8QM_HDMI_RX_PXL_SEL 784
+#define IMX8QM_HDMI_RX_HD_REF_SEL 785
+#define IMX8QM_HDMI_RX_HD_CORE_SEL 786
+#define IMX8QM_HDMI_RX_DIG_PLL_CLK 787
+
+#define IMX8QM_LSIO_MU5A_IPG_S_CLK 788
+#define IMX8QM_LSIO_MU5A_IPG_CLK 789
+#define IMX8QM_LSIO_MU6A_IPG_S_CLK 790
+#define IMX8QM_LSIO_MU6A_IPG_CLK 791
+
+/* DSP */
+#define IMX8QM_AUD_DSP_ADB_ACLK 792
+#define IMX8QM_AUD_DSP_IPG 793
+#define IMX8QM_AUD_DSP_CORE_CLK 794
+#define IMX8QM_AUD_OCRAM_IPG 795
+
+/* MIPI DSI */
+#define IMX8QM_MIPI0_DSI_PHY_DIV 796
+#define IMX8QM_MIPI0_DSI_PHY_CLK 797
+#define IMX8QM_MIPI1_DSI_PHY_DIV 798
+#define IMX8QM_MIPI1_DSI_PHY_CLK 799
+
+#define IMX8QM_CLK_END 800
+
+#endif /* __DT_BINDINGS_CLOCK_IMX8QM_H */
diff --git a/include/dt-bindings/clock/imx8qxp-clock.h b/include/dt-bindings/clock/imx8qxp-clock.h
new file mode 100644
index 000000000000..6316d5a71780
--- /dev/null
+++ b/include/dt-bindings/clock/imx8qxp-clock.h
@@ -0,0 +1,597 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017-2018 NXP
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __DT_BINDINGS_CLOCK_IMX8QXP_H
+#define __DT_BINDINGS_CLOCK_IMX8QXP_H
+
+#define IMX8QXP_CLK_DUMMY 0
+
+#define IMX8QXP_UART0_IPG_CLK 1
+#define IMX8QXP_UART0_DIV 2
+#define IMX8QXP_UART0_CLK 3
+
+#define IMX8QXP_IPG_DMA_CLK_ROOT 4
+
+/* GPU Clocks. */
+#define IMX8QXP_GPU0_CORE_DIV 5
+#define IMX8QXP_GPU0_CORE_CLK 6
+#define IMX8QXP_GPU0_SHADER_DIV 7
+#define IMX8QXP_GPU0_SHADER_CLK 8
+
+#define IMX8QXP_24MHZ 9
+#define IMX8QXP_GPT_3M 10
+#define IMX8QXP_32KHZ 11
+
+/* LSIO SS */
+#define IMX8QXP_LSIO_MEM_CLK 12
+#define IMX8QXP_LSIO_BUS_CLK 13
+#define IMX8QXP_LSIO_PWM0_DIV 14
+#define IMX8QXP_LSIO_PWM0_IPG_S_CLK 15
+#define IMX8QXP_LSIO_PWM0_IPG_SLV_CLK 16
+#define IMX8QXP_LSIO_PWM0_IPG_MSTR_CLK 17
+#define IMX8QXP_LSIO_PWM0_HF_CLK 18
+#define IMX8QXP_LSIO_PWM0_CLK 19
+#define IMX8QXP_LSIO_PWM1_DIV 20
+#define IMX8QXP_LSIO_PWM1_IPG_S_CLK 21
+#define IMX8QXP_LSIO_PWM1_IPG_SLV_CLK 22
+#define IMX8QXP_LSIO_PWM1_IPG_MSTR_CLK 23
+#define IMX8QXP_LSIO_PWM1_HF_CLK 24
+#define IMX8QXP_LSIO_PWM1_CLK 25
+#define IMX8QXP_LSIO_PWM2_DIV 26
+#define IMX8QXP_LSIO_PWM2_IPG_S_CLK 27
+#define IMX8QXP_LSIO_PWM2_IPG_SLV_CLK 28
+#define IMX8QXP_LSIO_PWM2_IPG_MSTR_CLK 29
+#define IMX8QXP_LSIO_PWM2_HF_CLK 30
+#define IMX8QXP_LSIO_PWM2_CLK 31
+#define IMX8QXP_LSIO_PWM3_DIV 32
+#define IMX8QXP_LSIO_PWM3_IPG_S_CLK 33
+#define IMX8QXP_LSIO_PWM3_IPG_SLV_CLK 34
+#define IMX8QXP_LSIO_PWM3_IPG_MSTR_CLK 35
+#define IMX8QXP_LSIO_PWM3_HF_CLK 36
+#define IMX8QXP_LSIO_PWM3_CLK 37
+#define IMX8QXP_LSIO_PWM4_DIV 38
+#define IMX8QXP_LSIO_PWM4_IPG_S_CLK 39
+#define IMX8QXP_LSIO_PWM4_IPG_SLV_CLK 40
+#define IMX8QXP_LSIO_PWM4_IPG_MSTR_CLK 42
+#define IMX8QXP_LSIO_PWM4_HF_CLK 43
+#define IMX8QXP_LSIO_PWM4_CLK 44
+#define IMX8QXP_LSIO_PWM5_DIV 45
+#define IMX8QXP_LSIO_PWM5_IPG_S_CLK 46
+#define IMX8QXP_LSIO_PWM5_IPG_SLV_CLK 47
+#define IMX8QXP_LSIO_PWM5_IPG_MSTR_CLK 48
+#define IMX8QXP_LSIO_PWM5_HF_CLK 49
+#define IMX8QXP_LSIO_PWM5_CLK 50
+#define IMX8QXP_LSIO_PWM6_DIV 51
+#define IMX8QXP_LSIO_PWM6_IPG_S_CLK 52
+#define IMX8QXP_LSIO_PWM6_IPG_SLV_CLK 53
+#define IMX8QXP_LSIO_PWM6_IPG_MSTR_CLK 54
+#define IMX8QXP_LSIO_PWM6_HF_CLK 55
+#define IMX8QXP_LSIO_PWM6_CLK 56
+#define IMX8QXP_LSIO_PWM7_DIV 57
+#define IMX8QXP_LSIO_PWM7_IPG_S_CLK 58
+#define IMX8QXP_LSIO_PWM7_IPG_SLV_CLK 59
+#define IMX8QXP_LSIO_PWM7_IPG_MSTR_CLK 60
+#define IMX8QXP_LSIO_PWM7_HF_CLK 61
+#define IMX8QXP_LSIO_PWM7_CLK 62
+#define IMX8QXP_LSIO_GPT0_DIV 63
+#define IMX8QXP_LSIO_GPT0_IPG_S_CLK 64
+#define IMX8QXP_LSIO_GPT0_IPG_SLV_CLK 65
+#define IMX8QXP_LSIO_GPT0_IPG_MSTR_CLK 66
+#define IMX8QXP_LSIO_GPT0_HF_CLK 67
+#define IMX8QXP_LSIO_GPT0_CLK 68
+#define IMX8QXP_LSIO_GPT1_DIV 69
+#define IMX8QXP_LSIO_GPT1_IPG_S_CLK 70
+#define IMX8QXP_LSIO_GPT1_IPG_SLV_CLK 71
+#define IMX8QXP_LSIO_GPT1_IPG_MSTR_CLK 72
+#define IMX8QXP_LSIO_GPT1_HF_CLK 73
+#define IMX8QXP_LSIO_GPT1_CLK 74
+#define IMX8QXP_LSIO_GPT2_DIV 75
+#define IMX8QXP_LSIO_GPT2_IPG_S_CLK 76
+#define IMX8QXP_LSIO_GPT2_IPG_SLV_CLK 77
+#define IMX8QXP_LSIO_GPT2_IPG_MSTR_CLK 78
+#define IMX8QXP_LSIO_GPT2_HF_CLK 79
+#define IMX8QXP_LSIO_GPT2_CLK 80
+#define IMX8QXP_LSIO_GPT3_DIV 81
+#define IMX8QXP_LSIO_GPT3_IPG_S_CLK 82
+#define IMX8QXP_LSIO_GPT3_IPG_SLV_CLK 83
+#define IMX8QXP_LSIO_GPT3_IPG_MSTR_CLK 84
+#define IMX8QXP_LSIO_GPT3_HF_CLK 85
+#define IMX8QXP_LSIO_GPT3_CLK 86
+#define IMX8QXP_LSIO_GPT4_DIV 87
+#define IMX8QXP_LSIO_GPT4_IPG_S_CLK 88
+#define IMX8QXP_LSIO_GPT4_IPG_SLV_CLK 89
+#define IMX8QXP_LSIO_GPT4_IPG_MSTR_CLK 90
+#define IMX8QXP_LSIO_GPT4_HF_CLK 91
+#define IMX8QXP_LSIO_GPT4_CLK 92
+#define IMX8QXP_LSIO_FSPI0_DIV 93
+#define IMX8QXP_LSIO_FSPI0_HCLK 94
+#define IMX8QXP_LSIO_FSPI0_IPG_S_CLK 95
+#define IMX8QXP_LSIO_FSPI0_IPG_CLK 96
+#define IMX8QXP_LSIO_FSPI0_CLK 97
+#define IMX8QXP_LSIO_FSPI1_DIV 98
+#define IMX8QXP_LSIO_FSPI1_HCLK 99
+#define IMX8QXP_LSIO_FSPI1_IPG_S_CLK 100
+#define IMX8QXP_LSIO_FSPI1_IPG_CLK 101
+#define IMX8QXP_LSIO_FSPI1_CLK 102
+#define IMX8QXP_LSIO_GPIO0_IPG_S_CLK 103
+#define IMX8QXP_LSIO_GPIO1_IPG_S_CLK 104
+#define IMX8QXP_LSIO_GPIO2_IPG_S_CLK 105
+#define IMX8QXP_LSIO_GPIO3_IPG_S_CLK 106
+#define IMX8QXP_LSIO_GPIO4_IPG_S_CLK 107
+#define IMX8QXP_LSIO_GPIO5_IPG_S_CLK 108
+#define IMX8QXP_LSIO_GPIO6_IPG_S_CLK 109
+#define IMX8QXP_LSIO_GPIO7_IPG_S_CLK 110
+#define IMX8QXP_LSIO_ROMCP_REG_CLK 111
+#define IMX8QXP_LSIO_ROMCP_CLK 112
+#define IMX8QXP_LSIO_96KROM_CLK 113
+#define IMX8QXP_LSIO_OCRAM_MEM_CLK 114
+#define IMX8QXP_LSIO_OCRAM_CTRL_CLK 115
+
+/* ADMA SS */
+#define IMX8QXP_UART1_IPG_CLK 116
+#define IMX8QXP_UART2_IPG_CLK 117
+#define IMX8QXP_UART3_IPG_CLK 118
+#define IMX8QXP_UART1_DIV 119
+#define IMX8QXP_UART2_DIV 120
+#define IMX8QXP_UART3_DIV 121
+#define IMX8QXP_UART1_CLK 122
+#define IMX8QXP_UART2_CLK 123
+#define IMX8QXP_UART3_CLK 124
+#define IMX8QXP_SPI0_IPG_CLK 125
+#define IMX8QXP_SPI1_IPG_CLK 126
+#define IMX8QXP_SPI2_IPG_CLK 127
+#define IMX8QXP_SPI3_IPG_CLK 128
+#define IMX8QXP_SPI0_DIV 129
+#define IMX8QXP_SPI1_DIV 130
+#define IMX8QXP_SPI2_DIV 131
+#define IMX8QXP_SPI3_DIV 132
+#define IMX8QXP_SPI0_CLK 133
+#define IMX8QXP_SPI1_CLK 134
+#define IMX8QXP_SPI2_CLK 135
+#define IMX8QXP_SPI3_CLK 136
+#define IMX8QXP_CAN0_IPG_CHI_CLK 137
+#define IMX8QXP_CAN1_IPG_CHI_CLK 138
+#define IMX8QXP_CAN2_IPG_CHI_CLK 139
+#define IMX8QXP_CAN0_IPG_CLK 140
+#define IMX8QXP_CAN1_IPG_CLK 141
+#define IMX8QXP_CAN2_IPG_CLK 142
+#define IMX8QXP_CAN0_DIV 143
+#define IMX8QXP_CAN1_DIV 144
+#define IMX8QXP_CAN2_DIV 145
+#define IMX8QXP_CAN0_CLK 146
+#define IMX8QXP_CAN1_CLK 147
+#define IMX8QXP_CAN2_CLK 148
+#define IMX8QXP_I2C0_IPG_CLK 149
+#define IMX8QXP_I2C1_IPG_CLK 150
+#define IMX8QXP_I2C2_IPG_CLK 151
+#define IMX8QXP_I2C3_IPG_CLK 152
+#define IMX8QXP_I2C0_DIV 153
+#define IMX8QXP_I2C1_DIV 154
+#define IMX8QXP_I2C2_DIV 155
+#define IMX8QXP_I2C3_DIV 156
+#define IMX8QXP_I2C0_CLK 157
+#define IMX8QXP_I2C1_CLK 158
+#define IMX8QXP_I2C2_CLK 159
+#define IMX8QXP_I2C3_CLK 160
+#define IMX8QXP_FTM0_IPG_CLK 161
+#define IMX8QXP_FTM1_IPG_CLK 162
+#define IMX8QXP_FTM0_DIV 163
+#define IMX8QXP_FTM1_DIV 164
+#define IMX8QXP_FTM0_CLK 165
+#define IMX8QXP_FTM1_CLK 166
+#define IMX8QXP_ADC0_IPG_CLK 167
+#define IMX8QXP_ADC0_DIV 168
+#define IMX8QXP_ADC0_CLK 169
+#define IMX8QXP_PWM_IPG_CLK 170
+#define IMX8QXP_PWM_DIV 171
+#define IMX8QXP_PWM_CLK 172
+#define IMX8QXP_LCD_IPG_CLK 173
+#define IMX8QXP_LCD_DIV 174
+#define IMX8QXP_LCD_CLK 175
+
+/* Connectivity SS */
+#define IMX8QXP_AXI_CONN_CLK_ROOT 176
+#define IMX8QXP_AHB_CONN_CLK_ROOT 177
+#define IMX8QXP_IPG_CONN_CLK_ROOT 178
+#define IMX8QXP_SDHC0_IPG_CLK 179
+#define IMX8QXP_SDHC1_IPG_CLK 180
+#define IMX8QXP_SDHC2_IPG_CLK 181
+#define IMX8QXP_SDHC0_DIV 182
+#define IMX8QXP_SDHC1_DIV 183
+#define IMX8QXP_SDHC2_DIV 184
+#define IMX8QXP_SDHC0_CLK 185
+#define IMX8QXP_SDHC1_CLK 186
+#define IMX8QXP_SDHC2_CLK 187
+#define IMX8QXP_ENET0_ROOT_DIV 188
+#define IMX8QXP_ENET0_REF_DIV 189
+#define IMX8QXP_ENET1_REF_DIV 190
+#define IMX8QXP_ENET0_BYPASS_DIV 191
+#define IMX8QXP_ENET0_RGMII_DIV 192
+#define IMX8QXP_ENET1_ROOT_DIV 193
+#define IMX8QXP_ENET1_BYPASS_DIV 194
+#define IMX8QXP_ENET1_RGMII_DIV 195
+#define IMX8QXP_ENET0_AHB_CLK 196
+#define IMX8QXP_ENET0_IPG_S_CLK 197
+#define IMX8QXP_ENET0_IPG_CLK 198
+#define IMX8QXP_ENET1_AHB_CLK 199
+#define IMX8QXP_ENET1_IPG_S_CLK 200
+#define IMX8QXP_ENET1_IPG_CLK 201
+#define IMX8QXP_ENET0_ROOT_CLK 202
+#define IMX8QXP_ENET1_ROOT_CLK 203
+#define IMX8QXP_ENET0_TX_CLK 204
+#define IMX8QXP_ENET1_TX_CLK 205
+#define IMX8QXP_ENET0_PTP_CLK 206
+#define IMX8QXP_ENET1_PTP_CLK 207
+#define IMX8QXP_ENET0_REF_25MHZ_125MHZ_SEL 208
+#define IMX8QXP_ENET1_REF_25MHZ_125MHZ_SEL 209
+#define IMX8QXP_ENET0_RMII_TX_SEL 210
+#define IMX8QXP_ENET1_RMII_TX_SEL 211
+#define IMX8QXP_ENET0_RGMII_TX_CLK 212
+#define IMX8QXP_ENET1_RGMII_TX_CLK 213
+#define IMX8QXP_ENET0_RMII_RX_CLK 214
+#define IMX8QXP_ENET1_RMII_RX_CLK 215
+#define IMX8QXP_ENET0_REF_25MHZ_125MHZ_CLK 216
+#define IMX8QXP_ENET1_REF_25MHZ_125MHZ_CLK 217
+#define IMX8QXP_ENET0_REF_50MHZ_CLK 218
+#define IMX8QXP_ENET1_REF_50MHZ_CLK 219
+#define IMX8QXP_GPMI_BCH_IO_DIV 220
+#define IMX8QXP_GPMI_BCH_DIV 221
+#define IMX8QXP_GPMI_APB_CLK 222
+#define IMX8QXP_GPMI_APB_BCH_CLK 223
+#define IMX8QXP_GPMI_BCH_IO_CLK 224
+#define IMX8QXP_GPMI_BCH_CLK 225
+#define IMX8QXP_APBHDMA_CLK 226
+#define IMX8QXP_USB3_ACLK_DIV 227
+#define IMX8QXP_USB3_BUS_DIV 228
+#define IMX8QXP_USB3_LPM_DIV 229
+#define IMX8QXP_USB3_IPG_CLK 230
+#define IMX8QXP_USB3_CORE_PCLK 231
+#define IMX8QXP_USB3_PHY_CLK 232
+#define IMX8QXP_USB3_ACLK 233
+#define IMX8QXP_USB3_BUS_CLK 234
+#define IMX8QXP_USB3_LPM_CLK 235
+#define IMX8QXP_USB2_OH_AHB_CLK 236
+#define IMX8QXP_USB2_OH_IPG_S_CLK 237
+#define IMX8QXP_USB2_OH_IPG_S_PL301_CLK 238
+#define IMX8QXP_USB2_PHY_IPG_CLK 239
+#define IMX8QXP_EDMA_CLK 240
+#define IMX8QXP_EDMA_IPG_CLK 241
+#define IMX8QXP_MLB_HCLK 242
+#define IMX8QXP_MLB_CLK 243
+#define IMX8QXP_MLB_IPG_CLK 244
+
+/* Display controller SS */
+/* DC part1 */
+#define IMX8QXP_DC_AXI_EXT_CLK 245
+#define IMX8QXP_DC_AXI_INT_CLK 246
+#define IMX8QXP_DC_CFG_CLK 247
+#define IMX8QXP_DC0_DISP0_CLK 248
+#define IMX8QXP_DC0_DISP1_CLK 249
+#define IMX8QXP_DC0_PRG0_RTRAM_CLK 250
+#define IMX8QXP_DC0_PRG0_APB_CLK 251
+#define IMX8QXP_DC0_PRG1_RTRAM_CLK 252
+#define IMX8QXP_DC0_PRG1_APB_CLK 253
+#define IMX8QXP_DC0_PRG2_RTRAM_CLK 254
+#define IMX8QXP_DC0_PRG2_APB_CLK 255
+#define IMX8QXP_DC0_PRG3_RTRAM_CLK 256
+#define IMX8QXP_DC0_PRG3_APB_CLK 257
+#define IMX8QXP_DC0_PRG4_RTRAM_CLK 258
+#define IMX8QXP_DC0_PRG4_APB_CLK 259
+#define IMX8QXP_DC0_PRG5_RTRAM_CLK 260
+#define IMX8QXP_DC0_PRG5_APB_CLK 261
+#define IMX8QXP_DC0_PRG6_RTRAM_CLK 262
+#define IMX8QXP_DC0_PRG6_APB_CLK 263
+#define IMX8QXP_DC0_PRG7_RTRAM_CLK 264
+#define IMX8QXP_DC0_PRG7_APB_CLK 265
+#define IMX8QXP_DC0_PRG8_RTRAM_CLK 266
+#define IMX8QXP_DC0_PRG8_APB_CLK 267
+#define IMX8QXP_DC0_DPR0_APB_CLK 268
+#define IMX8QXP_DC0_DPR0_B_CLK 269
+#define IMX8QXP_DC0_RTRAM0_CLK 270
+#define IMX8QXP_DC0_RTRAM1_CLK 271
+
+/* MIPI-LVDS part1 */
+#define IMX8QXP_MIPI_IPG_CLK 272
+#define IMX8QXP_MIPI0_I2C0_DIV 273
+#define IMX8QXP_MIPI0_I2C1_DIV 274
+#define IMX8QXP_MIPI0_I2C0_CLK 275
+#define IMX8QXP_MIPI0_I2C1_CLK 276
+#define IMX8QXP_MIPI0_I2C0_IPG_CLK 278
+#define IMX8QXP_MIPI0_I2C1_IPG_CLK 280
+#define IMX8QXP_MIPI0_PWM_IPG_CLK 282
+#define IMX8QXP_MIPI0_PWM_32K_CLK 283
+#define IMX8QXP_MIPI0_GPIO_IPG_CLK 284
+
+#define IMX8QXP_IMG_JPEG_ENC_IPG_CLK 285
+#define IMX8QXP_IMG_JPEG_ENC_CLK 286
+#define IMX8QXP_IMG_JPEG_DEC_IPG_CLK 287
+#define IMX8QXP_IMG_JPEG_DEC_CLK 288
+#define IMX8QXP_IMG_PXL_LINK_DC0_CLK 289
+#define IMX8QXP_IMG_PXL_LINK_DC1_CLK 290
+#define IMX8QXP_IMG_PXL_LINK_CSI0_CLK 291
+#define IMX8QXP_IMG_PXL_LINK_CSI1_CLK 292
+#define IMX8QXP_IMG_PXL_LINK_HDMI_IN_CLK 293
+#define IMX8QXP_IMG_PDMA_0_CLK 294
+#define IMX8QXP_IMG_PDMA_1_CLK 295
+#define IMX8QXP_IMG_PDMA_2_CLK 296
+#define IMX8QXP_IMG_PDMA_3_CLK 297
+#define IMX8QXP_IMG_PDMA_4_CLK 298
+#define IMX8QXP_IMG_PDMA_5_CLK 299
+#define IMX8QXP_IMG_PDMA_6_CLK 300
+#define IMX8QXP_IMG_PDMA_7_CLK 301
+#define IMX8QXP_IMG_AXI_CLK 302
+#define IMX8QXP_IMG_IPG_CLK 303
+#define IMX8QXP_IMG_PXL_CLK 304
+
+#define IMX8QXP_CSI0_I2C0_DIV 305
+#define IMX8QXP_CSI0_PWM0_DIV 306
+#define IMX8QXP_CSI0_CORE_DIV 307
+#define IMX8QXP_CSI0_ESC_DIV 308
+#define IMX8QXP_CSI0_IPG_CLK_S 309
+#define IMX8QXP_CSI0_IPG_CLK 310
+#define IMX8QXP_CSI0_APB_CLK 311
+#define IMX8QXP_CSI0_I2C0_IPG_CLK 312
+#define IMX8QXP_CSI0_I2C0_CLK 313
+#define IMX8QXP_CSI0_PWM0_IPG_CLK 314
+#define IMX8QXP_CSI0_PWM0_CLK 315
+#define IMX8QXP_CSI0_CORE_CLK 316
+#define IMX8QXP_CSI0_ESC_CLK 317
+
+#define IMX8QXP_HSIO_AXI_CLK 318
+#define IMX8QXP_HSIO_PER_CLK 319
+#define IMX8QXP_HSIO_PCIE_MSTR_AXI_CLK 320
+#define IMX8QXP_HSIO_PCIE_SLV_AXI_CLK 321
+#define IMX8QXP_HSIO_PCIE_DBI_AXI_CLK 322
+#define IMX8QXP_HSIO_PCIE_X1_PER_CLK 323
+#define IMX8QXP_HSIO_PHY_X1_PER_CLK 324
+#define IMX8QXP_HSIO_MISC_PER_CLK 325
+#define IMX8QXP_HSIO_PHY_X1_APB_CLK 326
+#define IMX8QXP_HSIO_GPIO_CLK 327
+#define IMX8QXP_HSIO_PHY_X1_PCLK 328
+
+#define IMX8QXP_A35_DIV 329
+
+/* ACM */
+#define IMX8QXP_EXT_AUD_MCLK0 330
+#define IMX8QXP_EXT_AUD_MCLK1 331
+#define IMX8QXP_ESAI0_RX_CLK 332
+#define IMX8QXP_ESAI0_RX_HF_CLK 333
+#define IMX8QXP_ESAI0_TX_CLK 334
+#define IMX8QXP_ESAI0_TX_HF_CLK 335
+#define IMX8QXP_SPDIF0_RX 336
+#define IMX8QXP_SAI0_RX_BCLK 337
+#define IMX8QXP_SAI0_TX_BCLK 338
+#define IMX8QXP_SAI1_RX_BCLK 339
+#define IMX8QXP_SAI1_TX_BCLK 340
+#define IMX8QXP_SAI2_RX_BCLK 341
+#define IMX8QXP_SAI3_RX_BCLK 342
+#define IMX8QXP_SAI4_RX_BCLK 343
+
+#define IMX8QXP_ACM_AUD_CLK0_SEL 344
+#define IMX8QXP_ACM_AUD_CLK0_CLK 345
+#define IMX8QXP_ACM_AUD_CLK1_SEL 346
+#define IMX8QXP_ACM_AUD_CLK1_CLK 347
+#define IMX8QXP_ACM_MCLKOUT0_SEL 348
+#define IMX8QXP_ACM_MCLKOUT0_CLK 349
+#define IMX8QXP_ACM_MCLKOUT1_SEL 350
+#define IMX8QXP_ACM_MCLKOUT1_CLK 351
+#define IMX8QXP_ACM_ESAI0_MCLK_SEL 352
+#define IMX8QXP_ACM_ESAI0_MCLK_CLK 353
+#define IMX8QXP_ACM_GPT0_MUX_CLK_SEL 354
+#define IMX8QXP_ACM_GPT0_MUX_CLK_CLK 355
+#define IMX8QXP_ACM_GPT1_MUX_CLK_SEL 356
+#define IMX8QXP_ACM_GPT1_MUX_CLK_CLK 357
+#define IMX8QXP_ACM_GPT2_MUX_CLK_SEL 358
+#define IMX8QXP_ACM_GPT2_MUX_CLK_CLK 359
+#define IMX8QXP_ACM_GPT3_MUX_CLK_SEL 360
+#define IMX8QXP_ACM_GPT3_MUX_CLK_CLK 361
+#define IMX8QXP_ACM_GPT4_MUX_CLK_SEL 362
+#define IMX8QXP_ACM_GPT4_MUX_CLK_CLK 363
+#define IMX8QXP_ACM_GPT5_MUX_CLK_SEL 364
+#define IMX8QXP_ACM_GPT5_MUX_CLK_CLK 365
+#define IMX8QXP_ACM_SAI0_MCLK_SEL 366
+#define IMX8QXP_ACM_SAI0_MCLK_CLK 367
+#define IMX8QXP_ACM_SAI1_MCLK_SEL 368
+#define IMX8QXP_ACM_SAI1_MCLK_CLK 369
+#define IMX8QXP_ACM_SAI2_MCLK_SEL 370
+#define IMX8QXP_ACM_SAI2_MCLK_CLK 371
+#define IMX8QXP_ACM_SAI3_MCLK_SEL 372
+#define IMX8QXP_ACM_SAI3_MCLK_CLK 373
+#define IMX8QXP_ACM_SAI4_MCLK_SEL 374
+#define IMX8QXP_ACM_SAI4_MCLK_CLK 375
+#define IMX8QXP_ACM_SAI5_MCLK_SEL 376
+#define IMX8QXP_ACM_SAI5_MCLK_CLK 377
+#define IMX8QXP_ACM_SPDIF0_TX_CLK_SEL 378
+#define IMX8QXP_ACM_SPDIF0_TX_CLK_CLK 379
+#define IMX8QXP_ACM_MQS_TX_CLK_SEL 380
+#define IMX8QXP_ACM_MQS_TX_CLK_CLK 381
+#define IMX8QXP_ACM_ASRC0_MUX_CLK_SEL 382
+#define IMX8QXP_ACM_ASRC1_MUX_CLK_SEL 383
+#define IMX8QXP_ACM_ASRC0_MUX_CLK_CLK 384
+#define IMX8QXP_ACM_ASRC1_MUX_CLK_CLK 385
+
+#define IMX8QXP_IPG_AUD_CLK_ROOT 386
+
+/* Audio */
+#define IMX8QXP_AUD_PLL0_DIV 387
+#define IMX8QXP_AUD_PLL0 388
+#define IMX8QXP_AUD_PLL1_DIV 389
+#define IMX8QXP_AUD_PLL1 390
+#define IMX8QXP_AUD_AMIX_IPG 391
+#define IMX8QXP_AUD_ESAI_0_IPG 392
+#define IMX8QXP_AUD_ESAI_0_EXTAL_IPG 393
+#define IMX8QXP_AUD_SAI_0_IPG 394
+#define IMX8QXP_AUD_SAI_0_MCLK 395
+#define IMX8QXP_AUD_SAI_1_IPG 396
+#define IMX8QXP_AUD_SAI_1_MCLK 397
+#define IMX8QXP_AUD_SAI_2_IPG 398
+#define IMX8QXP_AUD_SAI_2_MCLK 399
+#define IMX8QXP_AUD_SAI_3_IPG 400
+#define IMX8QXP_AUD_SAI_3_MCLK 401
+#define IMX8QXP_AUD_SAI_4_IPG 402
+#define IMX8QXP_AUD_SAI_4_MCLK 403
+#define IMX8QXP_AUD_SAI_5_IPG 404
+#define IMX8QXP_AUD_SAI_5_MCLK 405
+#define IMX8QXP_AUD_MQS_IPG 406
+#define IMX8QXP_AUD_MQS_HMCLK 407
+#define IMX8QXP_AUD_GPT5_IPG 408
+#define IMX8QXP_AUD_GPT5_CLKIN 409
+#define IMX8QXP_AUD_GPT6_IPG 410
+#define IMX8QXP_AUD_GPT6_CLKIN 411
+#define IMX8QXP_AUD_GPT7_IPG 412
+#define IMX8QXP_AUD_GPT7_CLKIN 413
+#define IMX8QXP_AUD_GPT8_IPG 414
+#define IMX8QXP_AUD_GPT8_CLKIN 415
+#define IMX8QXP_AUD_GPT9_IPG 416
+#define IMX8QXP_AUD_GPT9_CLKIN 417
+#define IMX8QXP_AUD_GPT10_IPG 418
+#define IMX8QXP_AUD_GPT10_CLKIN 419
+#define IMX8QXP_AUD_ACM_AUD_PLL_CLK0_DIV 420
+#define IMX8QXP_AUD_ACM_AUD_PLL_CLK0_CLK 421
+#define IMX8QXP_AUD_ACM_AUD_PLL_CLK1_DIV 422
+#define IMX8QXP_AUD_ACM_AUD_PLL_CLK1_CLK 423
+#define IMX8QXP_AUD_ACM_AUD_REC_CLK0_DIV 424
+#define IMX8QXP_AUD_ACM_AUD_REC_CLK0_CLK 425
+#define IMX8QXP_AUD_ACM_AUD_REC_CLK1_DIV 426
+#define IMX8QXP_AUD_ACM_AUD_REC_CLK1_CLK 427
+#define IMX8QXP_AUD_MCLKOUT0 428
+#define IMX8QXP_AUD_MCLKOUT1 429
+#define IMX8QXP_AUD_SPDIF_0_TX_CLK 430
+#define IMX8QXP_AUD_SPDIF_0_GCLKW 431
+#define IMX8QXP_AUD_SPDIF_0_IPG 432
+#define IMX8QXP_AUD_ASRC_0_IPG 433
+#define IMX8QXP_AUD_ASRC_1_IPG 434
+#define IMX8QXP_AUD_DSP_ADB_ACLK 435
+#define IMX8QXP_AUD_DSP_IPG 436
+#define IMX8QXP_AUD_DSP_CORE_CLK 437
+#define IMX8QXP_AUD_OCRAM_IPG 438
+
+/* DC part2 */
+#define IMX8QXP_DC0_DISP0_DIV 439
+#define IMX8QXP_DC0_DISP1_DIV 440
+#define IMX8QXP_DC0_BYPASS_0_DIV 441
+#define IMX8QXP_DC0_BYPASS_1_DIV 442
+#define IMX8QXP_DC0_PLL0_DIV 443
+#define IMX8QXP_DC0_PLL1_DIV 444
+#define IMX8QXP_DC0_PLL0_CLK 445
+#define IMX8QXP_DC0_PLL1_CLK 446
+
+/* MIPI-LVDS part2 */
+#define IMX8QXP_MIPI0_BYPASS_CLK 447
+#define IMX8QXP_MIPI0_PIXEL_DIV 448
+#define IMX8QXP_MIPI0_PIXEL_CLK 449
+#define IMX8QXP_MIPI0_LVDS_PIXEL_DIV 450
+#define IMX8QXP_MIPI0_LVDS_PIXEL_CLK 451
+#define IMX8QXP_MIPI0_LVDS_BYPASS_CLK 452
+#define IMX8QXP_MIPI0_LVDS_PHY_DIV 453
+#define IMX8QXP_MIPI0_LVDS_PHY_CLK 454
+#define IMX8QXP_MIPI0_DSI_TX_ESC_DIV 455
+#define IMX8QXP_MIPI0_DSI_RX_ESC_DIV 456
+#define IMX8QXP_MIPI0_DSI_TX_ESC_CLK 457
+#define IMX8QXP_MIPI0_DSI_RX_ESC_CLK 458
+#define IMX8QXP_MIPI0_LIS_IPG_CLK 459
+#define IMX8QXP_MIPI1_I2C0_DIV 460
+#define IMX8QXP_MIPI1_I2C1_DIV 461
+#define IMX8QXP_MIPI1_I2C0_CLK 462
+#define IMX8QXP_MIPI1_I2C1_CLK 463
+#define IMX8QXP_MIPI1_I2C0_IPG_CLK 465
+#define IMX8QXP_MIPI1_I2C1_IPG_CLK 467
+#define IMX8QXP_MIPI1_PWM_IPG_CLK 469
+#define IMX8QXP_MIPI1_PWM_32K_CLK 470
+#define IMX8QXP_MIPI1_GPIO_IPG_CLK 471
+#define IMX8QXP_MIPI1_BYPASS_CLK 472
+#define IMX8QXP_MIPI1_PIXEL_DIV 473
+#define IMX8QXP_MIPI1_PIXEL_CLK 474
+#define IMX8QXP_MIPI1_LVDS_PIXEL_DIV 475
+#define IMX8QXP_MIPI1_LVDS_PIXEL_CLK 476
+#define IMX8QXP_MIPI1_LVDS_BYPASS_CLK 477
+#define IMX8QXP_MIPI1_LVDS_PHY_DIV 478
+#define IMX8QXP_MIPI1_LVDS_PHY_CLK 479
+#define IMX8QXP_MIPI1_DSI_TX_ESC_DIV 480
+#define IMX8QXP_MIPI1_DSI_RX_ESC_DIV 481
+#define IMX8QXP_MIPI1_DSI_TX_ESC_CLK 482
+#define IMX8QXP_MIPI1_DSI_RX_ESC_CLK 483
+
+#define IMX8QXP_MIPI1_LIS_IPG_CLK 484
+
+/* CM40 */
+#define IMX8QXP_CM40_IPG_CLK 485
+#define IMX8QXP_CM40_I2C_DIV 486
+#define IMX8QXP_CM40_I2C_CLK 487
+#define IMX8QXP_CM40_I2C_IPG_CLK 488
+
+/* VPU clocks. */
+#define IMX8QXP_VPU_ENC_CLK 489
+#define IMX8QXP_VPU_DEC_CLK 490
+
+/* MIPI-LVDS part3 */
+#define IMX8QXP_MIPI0_DSI_PLL_CLK 491
+#define IMX8QXP_MIPI0_DSI_PLL_DIV2_CLK 492
+#define IMX8QXP_MIPI0_LVDS_PIXEL_SEL 493
+#define IMX8QXP_MIPI0_LVDS_PHY_SEL 494
+#define IMX8QXP_MIPI0_DSI_TX_ESC_SEL 495
+#define IMX8QXP_MIPI0_DSI_RX_ESC_SEL 496
+#define IMX8QXP_MIPI0_DSI_PHY_SEL 498
+#define IMX8QXP_MIPI0_DSI_PHY_DIV 499
+#define IMX8QXP_MIPI0_DSI_PHY_CLK 500
+#define IMX8QXP_MIPI1_DSI_PLL_CLK 501
+#define IMX8QXP_MIPI1_DSI_PLL_DIV2_CLK 502
+#define IMX8QXP_MIPI1_LVDS_PIXEL_SEL 503
+#define IMX8QXP_MIPI1_LVDS_PHY_SEL 504
+#define IMX8QXP_MIPI1_DSI_TX_ESC_SEL 505
+#define IMX8QXP_MIPI1_DSI_RX_ESC_SEL 506
+#define IMX8QXP_MIPI1_DSI_PHY_SEL 507
+#define IMX8QXP_MIPI1_DSI_PHY_DIV 508
+#define IMX8QXP_MIPI1_DSI_PHY_CLK 509
+
+/* DC part3 */
+#define IMX8QXP_DC0_DPR1_APB_CLK 510
+#define IMX8QXP_DC0_DPR1_B_CLK 511
+
+#define IMX8QXP_CONN_PLL0_CLK 512
+#define IMX8QXP_CONN_PLL1_CLK 513
+#define IMX8QXP_SDHC0_SEL 514
+#define IMX8QXP_SDHC1_SEL 515
+#define IMX8QXP_SDHC2_SEL 516
+
+/* PARALLER CSI */
+#define IMX8QXP_PARALLEL_CSI_CLK_DPLL 517
+#define IMX8QXP_PARALLEL_CSI_CLK_SEL 518
+#define IMX8QXP_PARALLEL_CSI_PER_CLK_DIV 519
+#define IMX8QXP_PARALLEL_CSI_PIXEL_CLK 520
+#define IMX8QXP_PARALLEL_CSI_IPG_CLK 521
+#define IMX8QXP_PARALLEL_CSI_MCLK_DIV 522
+#define IMX8QXP_PARALLEL_CSI_MISC0_CLK 523
+
+#define IMX8QXP_MIPI0_PWM_DIV 524
+#define IMX8QXP_MIPI1_PWM_DIV 525
+#define IMX8QXP_MIPI0_PWM_CLK 526
+#define IMX8QXP_MIPI1_PWM_CLK 527
+
+#define IMX8QXP_LSIO_MU5A_IPG_S_CLK 528
+#define IMX8QXP_LSIO_MU5A_IPG_CLK 529
+
+
+/* LCD part2 */
+#define IMX8QXP_LCD_PXL_BYPASS_DIV 530
+#define IMX8QXP_LCD_PXL_SEL 531
+#define IMX8QXP_LCD_PXL_DIV 532
+#define IMX8QXP_LCD_PXL_CLK 533
+#define IMX8QXP_ELCDIF_PLL_DIV 534
+#define IMX8QXP_ELCDIF_PLL 535
+#define IMX8QXP_LCD_SEL 536
+
+#define IMX8QXP_CLK_END 537
+#endif /* __DT_BINDINGS_CLOCK_IMX8QXP_H */
diff --git a/include/dt-bindings/input/input.h b/include/dt-bindings/input/input.h
index bcf0ae100f21..daa418607e8c 100644
--- a/include/dt-bindings/input/input.h
+++ b/include/dt-bindings/input/input.h
@@ -15,4 +15,7 @@
#define MATRIX_KEY(row, col, code) \
((((row) & 0xFF) << 24) | (((col) & 0xFF) << 16) | ((code) & 0xFFFF))
+#define FT5416 0x54160002
+#define FT5426 0x54260002
+
#endif /* _DT_BINDINGS_INPUT_INPUT_H */
diff --git a/include/dt-bindings/pinctrl/pads-imx8qm.h b/include/dt-bindings/pinctrl/pads-imx8qm.h
new file mode 100644
index 000000000000..1115b3ec10d5
--- /dev/null
+++ b/include/dt-bindings/pinctrl/pads-imx8qm.h
@@ -0,0 +1,1002 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017-2019 NXP
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+/*!
+ * Header file used to configure SoC pad list.
+ */
+
+#ifndef SC_PADS_H
+#define SC_PADS_H
+
+/* Includes */
+
+/* Defines */
+
+/*!
+ * @name Pad Definitions
+ */
+/*@{*/
+#define SC_P_SIM0_CLK 0 /* DMA.SIM0.CLK, LSIO.GPIO0.IO00 */
+#define SC_P_SIM0_RST 1 /* DMA.SIM0.RST, LSIO.GPIO0.IO01 */
+#define SC_P_SIM0_IO 2 /* DMA.SIM0.IO, LSIO.GPIO0.IO02 */
+#define SC_P_SIM0_PD 3 /* DMA.SIM0.PD, DMA.I2C3.SCL, LSIO.GPIO0.IO03 */
+#define SC_P_SIM0_POWER_EN 4 /* DMA.SIM0.POWER_EN, DMA.I2C3.SDA, LSIO.GPIO0.IO04 */
+#define SC_P_SIM0_GPIO0_00 5 /* DMA.SIM0.POWER_EN, LSIO.GPIO0.IO05 */
+#define SC_P_COMP_CTL_GPIO_1V8_3V3_SIM 6 /* */
+#define SC_P_M40_I2C0_SCL 7 /* M40.I2C0.SCL, M40.UART0.RX, M40.GPIO0.IO02, LSIO.GPIO0.IO06 */
+#define SC_P_M40_I2C0_SDA 8 /* M40.I2C0.SDA, M40.UART0.TX, M40.GPIO0.IO03, LSIO.GPIO0.IO07 */
+#define SC_P_M40_GPIO0_00 9 /* M40.GPIO0.IO00, M40.TPM0.CH0, DMA.UART4.RX, LSIO.GPIO0.IO08 */
+#define SC_P_M40_GPIO0_01 10 /* M40.GPIO0.IO01, M40.TPM0.CH1, DMA.UART4.TX, LSIO.GPIO0.IO09 */
+#define SC_P_M41_I2C0_SCL 11 /* M41.I2C0.SCL, M41.UART0.RX, M41.GPIO0.IO02, LSIO.GPIO0.IO10 */
+#define SC_P_M41_I2C0_SDA 12 /* M41.I2C0.SDA, M41.UART0.TX, M41.GPIO0.IO03, LSIO.GPIO0.IO11 */
+#define SC_P_M41_GPIO0_00 13 /* M41.GPIO0.IO00, M41.TPM0.CH0, DMA.UART3.RX, LSIO.GPIO0.IO12 */
+#define SC_P_M41_GPIO0_01 14 /* M41.GPIO0.IO01, M41.TPM0.CH1, DMA.UART3.TX, LSIO.GPIO0.IO13 */
+#define SC_P_GPT0_CLK 15 /* LSIO.GPT0.CLK, DMA.I2C1.SCL, LSIO.KPP0.COL4, LSIO.GPIO0.IO14 */
+#define SC_P_GPT0_CAPTURE 16 /* LSIO.GPT0.CAPTURE, DMA.I2C1.SDA, LSIO.KPP0.COL5, LSIO.GPIO0.IO15 */
+#define SC_P_GPT0_COMPARE 17 /* LSIO.GPT0.COMPARE, LSIO.PWM3.OUT, LSIO.KPP0.COL6, LSIO.GPIO0.IO16 */
+#define SC_P_GPT1_CLK 18 /* LSIO.GPT1.CLK, DMA.I2C2.SCL, LSIO.KPP0.COL7, LSIO.GPIO0.IO17 */
+#define SC_P_GPT1_CAPTURE 19 /* LSIO.GPT1.CAPTURE, DMA.I2C2.SDA, LSIO.KPP0.ROW4, LSIO.GPIO0.IO18 */
+#define SC_P_GPT1_COMPARE 20 /* LSIO.GPT1.COMPARE, LSIO.PWM2.OUT, LSIO.KPP0.ROW5, LSIO.GPIO0.IO19 */
+#define SC_P_UART0_RX 21 /* DMA.UART0.RX, SCU.UART0.RX, LSIO.GPIO0.IO20 */
+#define SC_P_UART0_TX 22 /* DMA.UART0.TX, SCU.UART0.TX, LSIO.GPIO0.IO21 */
+#define SC_P_UART0_RTS_B 23 /* DMA.UART0.RTS_B, LSIO.PWM0.OUT, DMA.UART2.RX, LSIO.GPIO0.IO22 */
+#define SC_P_UART0_CTS_B 24 /* DMA.UART0.CTS_B, LSIO.PWM1.OUT, DMA.UART2.TX, LSIO.GPIO0.IO23 */
+#define SC_P_UART1_TX 25 /* DMA.UART1.TX, DMA.SPI3.SCK, LSIO.GPIO0.IO24 */
+#define SC_P_UART1_RX 26 /* DMA.UART1.RX, DMA.SPI3.SDO, LSIO.GPIO0.IO25 */
+#define SC_P_UART1_RTS_B 27 /* DMA.UART1.RTS_B, DMA.SPI3.SDI, DMA.UART1.CTS_B, LSIO.GPIO0.IO26 */
+#define SC_P_UART1_CTS_B 28 /* DMA.UART1.CTS_B, DMA.SPI3.CS0, DMA.UART1.RTS_B, LSIO.GPIO0.IO27 */
+#define SC_P_COMP_CTL_GPIO_1V8_3V3_GPIOLH 29 /* */
+#define SC_P_SCU_PMIC_MEMC_ON 30 /* SCU.GPIO0.IOXX_PMIC_MEMC_ON */
+#define SC_P_SCU_WDOG_OUT 31 /* SCU.WDOG0.WDOG_OUT */
+#define SC_P_PMIC_I2C_SDA 32 /* SCU.PMIC_I2C.SDA */
+#define SC_P_PMIC_I2C_SCL 33 /* SCU.PMIC_I2C.SCL */
+#define SC_P_PMIC_EARLY_WARNING 34 /* SCU.PMIC_EARLY_WARNING */
+#define SC_P_PMIC_INT_B 35 /* SCU.DSC.PMIC_INT_B */
+#define SC_P_SCU_GPIO0_00 36 /* SCU.GPIO0.IO00, SCU.UART0.RX, LSIO.GPIO0.IO28 */
+#define SC_P_SCU_GPIO0_01 37 /* SCU.GPIO0.IO01, SCU.UART0.TX, LSIO.GPIO0.IO29 */
+#define SC_P_SCU_GPIO0_02 38 /* SCU.GPIO0.IO02, SCU.GPIO0.IOXX_PMIC_GPU0_ON, LSIO.GPIO0.IO30 */
+#define SC_P_SCU_GPIO0_03 39 /* SCU.GPIO0.IO03, SCU.GPIO0.IOXX_PMIC_GPU1_ON, LSIO.GPIO0.IO31 */
+#define SC_P_SCU_GPIO0_04 40 /* SCU.GPIO0.IO04, SCU.GPIO0.IOXX_PMIC_A72_ON, LSIO.GPIO1.IO00 */
+#define SC_P_SCU_GPIO0_05 41 /* SCU.GPIO0.IO05, SCU.GPIO0.IOXX_PMIC_A53_ON, LSIO.GPIO1.IO01 */
+#define SC_P_SCU_GPIO0_06 42 /* SCU.GPIO0.IO06, SCU.TPM0.CH0, LSIO.GPIO1.IO02 */
+#define SC_P_SCU_GPIO0_07 43 /* SCU.GPIO0.IO07, SCU.TPM0.CH1, SCU.DSC.RTC_CLOCK_OUTPUT_32K, LSIO.GPIO1.IO03 */
+#define SC_P_SCU_BOOT_MODE0 44 /* SCU.DSC.BOOT_MODE0 */
+#define SC_P_SCU_BOOT_MODE1 45 /* SCU.DSC.BOOT_MODE1 */
+#define SC_P_SCU_BOOT_MODE2 46 /* SCU.DSC.BOOT_MODE2 */
+#define SC_P_SCU_BOOT_MODE3 47 /* SCU.DSC.BOOT_MODE3 */
+#define SC_P_SCU_BOOT_MODE4 48 /* SCU.DSC.BOOT_MODE4, SCU.PMIC_I2C.SCL */
+#define SC_P_SCU_BOOT_MODE5 49 /* SCU.DSC.BOOT_MODE5, SCU.PMIC_I2C.SDA */
+#define SC_P_LVDS0_GPIO00 50 /* LVDS0.GPIO0.IO00, LVDS0.PWM0.OUT, LSIO.GPIO1.IO04 */
+#define SC_P_LVDS0_GPIO01 51 /* LVDS0.GPIO0.IO01, LSIO.GPIO1.IO05 */
+#define SC_P_LVDS0_I2C0_SCL 52 /* LVDS0.I2C0.SCL, LVDS0.GPIO0.IO02, LSIO.GPIO1.IO06 */
+#define SC_P_LVDS0_I2C0_SDA 53 /* LVDS0.I2C0.SDA, LVDS0.GPIO0.IO03, LSIO.GPIO1.IO07 */
+#define SC_P_LVDS0_I2C1_SCL 54 /* LVDS0.I2C1.SCL, DMA.UART2.TX, LSIO.GPIO1.IO08 */
+#define SC_P_LVDS0_I2C1_SDA 55 /* LVDS0.I2C1.SDA, DMA.UART2.RX, LSIO.GPIO1.IO09 */
+#define SC_P_LVDS1_GPIO00 56 /* LVDS1.GPIO0.IO00, LVDS1.PWM0.OUT, LSIO.GPIO1.IO10 */
+#define SC_P_LVDS1_GPIO01 57 /* LVDS1.GPIO0.IO01, LSIO.GPIO1.IO11 */
+#define SC_P_LVDS1_I2C0_SCL 58 /* LVDS1.I2C0.SCL, LVDS1.GPIO0.IO02, LSIO.GPIO1.IO12 */
+#define SC_P_LVDS1_I2C0_SDA 59 /* LVDS1.I2C0.SDA, LVDS1.GPIO0.IO03, LSIO.GPIO1.IO13 */
+#define SC_P_LVDS1_I2C1_SCL 60 /* LVDS1.I2C1.SCL, DMA.UART3.TX, LSIO.GPIO1.IO14 */
+#define SC_P_LVDS1_I2C1_SDA 61 /* LVDS1.I2C1.SDA, DMA.UART3.RX, LSIO.GPIO1.IO15 */
+#define SC_P_COMP_CTL_GPIO_1V8_3V3_LVDSGPIO 62 /* */
+#define SC_P_MIPI_DSI0_I2C0_SCL 63 /* MIPI_DSI0.I2C0.SCL, LSIO.GPIO1.IO16 */
+#define SC_P_MIPI_DSI0_I2C0_SDA 64 /* MIPI_DSI0.I2C0.SDA, LSIO.GPIO1.IO17 */
+#define SC_P_MIPI_DSI0_GPIO0_00 65 /* MIPI_DSI0.GPIO0.IO00, MIPI_DSI0.PWM0.OUT, LSIO.GPIO1.IO18 */
+#define SC_P_MIPI_DSI0_GPIO0_01 66 /* MIPI_DSI0.GPIO0.IO01, LSIO.GPIO1.IO19 */
+#define SC_P_MIPI_DSI1_I2C0_SCL 67 /* MIPI_DSI1.I2C0.SCL, LSIO.GPIO1.IO20 */
+#define SC_P_MIPI_DSI1_I2C0_SDA 68 /* MIPI_DSI1.I2C0.SDA, LSIO.GPIO1.IO21 */
+#define SC_P_MIPI_DSI1_GPIO0_00 69 /* MIPI_DSI1.GPIO0.IO00, MIPI_DSI1.PWM0.OUT, LSIO.GPIO1.IO22 */
+#define SC_P_MIPI_DSI1_GPIO0_01 70 /* MIPI_DSI1.GPIO0.IO01, LSIO.GPIO1.IO23 */
+#define SC_P_COMP_CTL_GPIO_1V8_3V3_MIPIDSIGPIO 71 /* */
+#define SC_P_MIPI_CSI0_MCLK_OUT 72 /* MIPI_CSI0.ACM.MCLK_OUT, LSIO.GPIO1.IO24 */
+#define SC_P_MIPI_CSI0_I2C0_SCL 73 /* MIPI_CSI0.I2C0.SCL, LSIO.GPIO1.IO25 */
+#define SC_P_MIPI_CSI0_I2C0_SDA 74 /* MIPI_CSI0.I2C0.SDA, LSIO.GPIO1.IO26 */
+#define SC_P_MIPI_CSI0_GPIO0_00 75 /* MIPI_CSI0.GPIO0.IO00, DMA.I2C0.SCL, MIPI_CSI1.I2C0.SCL, LSIO.GPIO1.IO27 */
+#define SC_P_MIPI_CSI0_GPIO0_01 76 /* MIPI_CSI0.GPIO0.IO01, DMA.I2C0.SDA, MIPI_CSI1.I2C0.SDA, LSIO.GPIO1.IO28 */
+#define SC_P_MIPI_CSI1_MCLK_OUT 77 /* MIPI_CSI1.ACM.MCLK_OUT, LSIO.GPIO1.IO29 */
+#define SC_P_MIPI_CSI1_GPIO0_00 78 /* MIPI_CSI1.GPIO0.IO00, DMA.UART4.RX, LSIO.GPIO1.IO30 */
+#define SC_P_MIPI_CSI1_GPIO0_01 79 /* MIPI_CSI1.GPIO0.IO01, DMA.UART4.TX, LSIO.GPIO1.IO31 */
+#define SC_P_MIPI_CSI1_I2C0_SCL 80 /* MIPI_CSI1.I2C0.SCL, LSIO.GPIO2.IO00 */
+#define SC_P_MIPI_CSI1_I2C0_SDA 81 /* MIPI_CSI1.I2C0.SDA, LSIO.GPIO2.IO01 */
+#define SC_P_HDMI_TX0_TS_SCL 82 /* HDMI_TX0.I2C0.SCL, DMA.I2C0.SCL, LSIO.GPIO2.IO02 */
+#define SC_P_HDMI_TX0_TS_SDA 83 /* HDMI_TX0.I2C0.SDA, DMA.I2C0.SDA, LSIO.GPIO2.IO03 */
+#define SC_P_COMP_CTL_GPIO_3V3_HDMIGPIO 84 /* */
+#define SC_P_ESAI1_FSR 85 /* AUD.ESAI1.FSR, LSIO.GPIO2.IO04 */
+#define SC_P_ESAI1_FST 86 /* AUD.ESAI1.FST, AUD.SPDIF0.EXT_CLK, LSIO.GPIO2.IO05 */
+#define SC_P_ESAI1_SCKR 87 /* AUD.ESAI1.SCKR, LSIO.GPIO2.IO06 */
+#define SC_P_ESAI1_SCKT 88 /* AUD.ESAI1.SCKT, AUD.SAI2.RXC, AUD.SPDIF0.EXT_CLK, LSIO.GPIO2.IO07 */
+#define SC_P_ESAI1_TX0 89 /* AUD.ESAI1.TX0, AUD.SAI2.RXD, AUD.SPDIF0.RX, LSIO.GPIO2.IO08 */
+#define SC_P_ESAI1_TX1 90 /* AUD.ESAI1.TX1, AUD.SAI2.RXFS, AUD.SPDIF0.TX, LSIO.GPIO2.IO09 */
+#define SC_P_ESAI1_TX2_RX3 91 /* AUD.ESAI1.TX2_RX3, AUD.SPDIF0.RX, LSIO.GPIO2.IO10 */
+#define SC_P_ESAI1_TX3_RX2 92 /* AUD.ESAI1.TX3_RX2, AUD.SPDIF0.TX, LSIO.GPIO2.IO11 */
+#define SC_P_ESAI1_TX4_RX1 93 /* AUD.ESAI1.TX4_RX1, LSIO.GPIO2.IO12 */
+#define SC_P_ESAI1_TX5_RX0 94 /* AUD.ESAI1.TX5_RX0, LSIO.GPIO2.IO13 */
+#define SC_P_SPDIF0_RX 95 /* AUD.SPDIF0.RX, AUD.MQS.R, AUD.ACM.MCLK_IN1, LSIO.GPIO2.IO14 */
+#define SC_P_SPDIF0_TX 96 /* AUD.SPDIF0.TX, AUD.MQS.L, AUD.ACM.MCLK_OUT1, LSIO.GPIO2.IO15 */
+#define SC_P_SPDIF0_EXT_CLK 97 /* AUD.SPDIF0.EXT_CLK, DMA.DMA0.REQ_IN0, LSIO.GPIO2.IO16 */
+#define SC_P_SPI3_SCK 98 /* DMA.SPI3.SCK, LSIO.GPIO2.IO17 */
+#define SC_P_SPI3_SDO 99 /* DMA.SPI3.SDO, DMA.FTM.CH0, LSIO.GPIO2.IO18 */
+#define SC_P_SPI3_SDI 100 /* DMA.SPI3.SDI, DMA.FTM.CH1, LSIO.GPIO2.IO19 */
+#define SC_P_SPI3_CS0 101 /* DMA.SPI3.CS0, DMA.FTM.CH2, LSIO.GPIO2.IO20 */
+#define SC_P_SPI3_CS1 102 /* DMA.SPI3.CS1, LSIO.GPIO2.IO21 */
+#define SC_P_COMP_CTL_GPIO_1V8_3V3_GPIORHB 103 /* */
+#define SC_P_ESAI0_FSR 104 /* AUD.ESAI0.FSR, LSIO.GPIO2.IO22 */
+#define SC_P_ESAI0_FST 105 /* AUD.ESAI0.FST, LSIO.GPIO2.IO23 */
+#define SC_P_ESAI0_SCKR 106 /* AUD.ESAI0.SCKR, LSIO.GPIO2.IO24 */
+#define SC_P_ESAI0_SCKT 107 /* AUD.ESAI0.SCKT, LSIO.GPIO2.IO25 */
+#define SC_P_ESAI0_TX0 108 /* AUD.ESAI0.TX0, LSIO.GPIO2.IO26 */
+#define SC_P_ESAI0_TX1 109 /* AUD.ESAI0.TX1, LSIO.GPIO2.IO27 */
+#define SC_P_ESAI0_TX2_RX3 110 /* AUD.ESAI0.TX2_RX3, LSIO.GPIO2.IO28 */
+#define SC_P_ESAI0_TX3_RX2 111 /* AUD.ESAI0.TX3_RX2, LSIO.GPIO2.IO29 */
+#define SC_P_ESAI0_TX4_RX1 112 /* AUD.ESAI0.TX4_RX1, LSIO.GPIO2.IO30 */
+#define SC_P_ESAI0_TX5_RX0 113 /* AUD.ESAI0.TX5_RX0, LSIO.GPIO2.IO31 */
+#define SC_P_MCLK_IN0 114 /* AUD.ACM.MCLK_IN0, AUD.ESAI0.RX_HF_CLK, AUD.ESAI1.RX_HF_CLK, LSIO.GPIO3.IO00 */
+#define SC_P_MCLK_OUT0 115 /* AUD.ACM.MCLK_OUT0, AUD.ESAI0.TX_HF_CLK, AUD.ESAI1.TX_HF_CLK, LSIO.GPIO3.IO01 */
+#define SC_P_COMP_CTL_GPIO_1V8_3V3_GPIORHC 116 /* */
+#define SC_P_SPI0_SCK 117 /* DMA.SPI0.SCK, AUD.SAI0.RXC, LSIO.GPIO3.IO02 */
+#define SC_P_SPI0_SDO 118 /* DMA.SPI0.SDO, AUD.SAI0.TXD, LSIO.GPIO3.IO03 */
+#define SC_P_SPI0_SDI 119 /* DMA.SPI0.SDI, AUD.SAI0.RXD, LSIO.GPIO3.IO04 */
+#define SC_P_SPI0_CS0 120 /* DMA.SPI0.CS0, AUD.SAI0.RXFS, LSIO.GPIO3.IO05 */
+#define SC_P_SPI0_CS1 121 /* DMA.SPI0.CS1, AUD.SAI0.TXC, LSIO.GPIO3.IO06 */
+#define SC_P_SPI2_SCK 122 /* DMA.SPI2.SCK, LSIO.GPIO3.IO07 */
+#define SC_P_SPI2_SDO 123 /* DMA.SPI2.SDO, LSIO.GPIO3.IO08 */
+#define SC_P_SPI2_SDI 124 /* DMA.SPI2.SDI, LSIO.GPIO3.IO09 */
+#define SC_P_SPI2_CS0 125 /* DMA.SPI2.CS0, LSIO.GPIO3.IO10 */
+#define SC_P_SPI2_CS1 126 /* DMA.SPI2.CS1, AUD.SAI0.TXFS, LSIO.GPIO3.IO11 */
+#define SC_P_SAI1_RXC 127 /* AUD.SAI1.RXC, AUD.SAI0.TXD, LSIO.GPIO3.IO12 */
+#define SC_P_SAI1_RXD 128 /* AUD.SAI1.RXD, AUD.SAI0.TXFS, LSIO.GPIO3.IO13 */
+#define SC_P_SAI1_RXFS 129 /* AUD.SAI1.RXFS, AUD.SAI0.RXD, LSIO.GPIO3.IO14 */
+#define SC_P_SAI1_TXC 130 /* AUD.SAI1.TXC, AUD.SAI0.TXC, LSIO.GPIO3.IO15 */
+#define SC_P_SAI1_TXD 131 /* AUD.SAI1.TXD, AUD.SAI1.RXC, LSIO.GPIO3.IO16 */
+#define SC_P_SAI1_TXFS 132 /* AUD.SAI1.TXFS, AUD.SAI1.RXFS, LSIO.GPIO3.IO17 */
+#define SC_P_COMP_CTL_GPIO_1V8_3V3_GPIORHT 133 /* */
+#define SC_P_ADC_IN7 134 /* DMA.ADC1.IN3, DMA.SPI1.CS1, LSIO.KPP0.ROW3, LSIO.GPIO3.IO25 */
+#define SC_P_ADC_IN6 135 /* DMA.ADC1.IN2, DMA.SPI1.CS0, LSIO.KPP0.ROW2, LSIO.GPIO3.IO24 */
+#define SC_P_ADC_IN5 136 /* DMA.ADC1.IN1, DMA.SPI1.SDI, LSIO.KPP0.ROW1, LSIO.GPIO3.IO23 */
+#define SC_P_ADC_IN4 137 /* DMA.ADC1.IN0, DMA.SPI1.SDO, LSIO.KPP0.ROW0, LSIO.GPIO3.IO22 */
+#define SC_P_ADC_IN3 138 /* DMA.ADC0.IN3, DMA.SPI1.SCK, LSIO.KPP0.COL3, LSIO.GPIO3.IO21 */
+#define SC_P_ADC_IN2 139 /* DMA.ADC0.IN2, LSIO.KPP0.COL2, LSIO.GPIO3.IO20 */
+#define SC_P_ADC_IN1 140 /* DMA.ADC0.IN1, LSIO.KPP0.COL1, LSIO.GPIO3.IO19 */
+#define SC_P_ADC_IN0 141 /* DMA.ADC0.IN0, LSIO.KPP0.COL0, LSIO.GPIO3.IO18 */
+#define SC_P_MLB_SIG 142 /* CONN.MLB.SIG, AUD.SAI3.RXC, LSIO.GPIO3.IO26 */
+#define SC_P_MLB_CLK 143 /* CONN.MLB.CLK, AUD.SAI3.RXFS, LSIO.GPIO3.IO27 */
+#define SC_P_MLB_DATA 144 /* CONN.MLB.DATA, AUD.SAI3.RXD, LSIO.GPIO3.IO28 */
+#define SC_P_COMP_CTL_GPIO_1V8_3V3_GPIOLHT 145 /* */
+#define SC_P_FLEXCAN0_RX 146 /* DMA.FLEXCAN0.RX, LSIO.GPIO3.IO29 */
+#define SC_P_FLEXCAN0_TX 147 /* DMA.FLEXCAN0.TX, LSIO.GPIO3.IO30 */
+#define SC_P_FLEXCAN1_RX 148 /* DMA.FLEXCAN1.RX, LSIO.GPIO3.IO31 */
+#define SC_P_FLEXCAN1_TX 149 /* DMA.FLEXCAN1.TX, LSIO.GPIO4.IO00 */
+#define SC_P_FLEXCAN2_RX 150 /* DMA.FLEXCAN2.RX, LSIO.GPIO4.IO01 */
+#define SC_P_FLEXCAN2_TX 151 /* DMA.FLEXCAN2.TX, LSIO.GPIO4.IO02 */
+#define SC_P_COMP_CTL_GPIO_1V8_3V3_GPIOTHR 152 /* */
+#define SC_P_USB_SS3_TC0 153 /* DMA.I2C1.SCL, CONN.USB_OTG1.PWR, LSIO.GPIO4.IO03 */
+#define SC_P_USB_SS3_TC1 154 /* DMA.I2C1.SCL, CONN.USB_OTG2.PWR, LSIO.GPIO4.IO04 */
+#define SC_P_USB_SS3_TC2 155 /* DMA.I2C1.SDA, CONN.USB_OTG1.OC, LSIO.GPIO4.IO05 */
+#define SC_P_USB_SS3_TC3 156 /* DMA.I2C1.SDA, CONN.USB_OTG2.OC, LSIO.GPIO4.IO06 */
+#define SC_P_COMP_CTL_GPIO_3V3_USB3IO 157 /* */
+#define SC_P_USDHC1_RESET_B 158 /* CONN.USDHC1.RESET_B, LSIO.GPIO4.IO07 */
+#define SC_P_USDHC1_VSELECT 159 /* CONN.USDHC1.VSELECT, LSIO.GPIO4.IO08 */
+#define SC_P_USDHC2_RESET_B 160 /* CONN.USDHC2.RESET_B, LSIO.GPIO4.IO09 */
+#define SC_P_USDHC2_VSELECT 161 /* CONN.USDHC2.VSELECT, LSIO.GPIO4.IO10 */
+#define SC_P_USDHC2_WP 162 /* CONN.USDHC2.WP, LSIO.GPIO4.IO11 */
+#define SC_P_USDHC2_CD_B 163 /* CONN.USDHC2.CD_B, LSIO.GPIO4.IO12 */
+#define SC_P_COMP_CTL_GPIO_1V8_3V3_VSELSEP 164 /* */
+#define SC_P_ENET0_MDIO 165 /* CONN.ENET0.MDIO, DMA.I2C4.SDA, LSIO.GPIO4.IO13 */
+#define SC_P_ENET0_MDC 166 /* CONN.ENET0.MDC, DMA.I2C4.SCL, LSIO.GPIO4.IO14 */
+#define SC_P_ENET0_REFCLK_125M_25M 167 /* CONN.ENET0.REFCLK_125M_25M, CONN.ENET0.PPS, LSIO.GPIO4.IO15 */
+#define SC_P_ENET1_REFCLK_125M_25M 168 /* CONN.ENET1.REFCLK_125M_25M, CONN.ENET1.PPS, LSIO.GPIO4.IO16 */
+#define SC_P_ENET1_MDIO 169 /* CONN.ENET1.MDIO, DMA.I2C4.SDA, LSIO.GPIO4.IO17 */
+#define SC_P_ENET1_MDC 170 /* CONN.ENET1.MDC, DMA.I2C4.SCL, LSIO.GPIO4.IO18 */
+#define SC_P_COMP_CTL_GPIO_1V8_3V3_GPIOCT 171 /* */
+#define SC_P_QSPI1A_SS0_B 172 /* LSIO.QSPI1A.SS0_B, LSIO.GPIO4.IO19 */
+#define SC_P_QSPI1A_SS1_B 173 /* LSIO.QSPI1A.SS1_B, LSIO.QSPI1A.SCLK2, LSIO.GPIO4.IO20 */
+#define SC_P_QSPI1A_SCLK 174 /* LSIO.QSPI1A.SCLK, LSIO.GPIO4.IO21 */
+#define SC_P_QSPI1A_DQS 175 /* LSIO.QSPI1A.DQS, LSIO.GPIO4.IO22 */
+#define SC_P_QSPI1A_DATA3 176 /* LSIO.QSPI1A.DATA3, DMA.I2C1.SDA, CONN.USB_OTG1.OC, LSIO.GPIO4.IO23 */
+#define SC_P_QSPI1A_DATA2 177 /* LSIO.QSPI1A.DATA2, DMA.I2C1.SCL, CONN.USB_OTG2.PWR, LSIO.GPIO4.IO24 */
+#define SC_P_QSPI1A_DATA1 178 /* LSIO.QSPI1A.DATA1, DMA.I2C1.SDA, CONN.USB_OTG2.OC, LSIO.GPIO4.IO25 */
+#define SC_P_QSPI1A_DATA0 179 /* LSIO.QSPI1A.DATA0, LSIO.GPIO4.IO26 */
+#define SC_P_COMP_CTL_GPIO_1V8_3V3_QSPI1 180 /* */
+#define SC_P_QSPI0A_DATA0 181 /* LSIO.QSPI0A.DATA0 */
+#define SC_P_QSPI0A_DATA1 182 /* LSIO.QSPI0A.DATA1 */
+#define SC_P_QSPI0A_DATA2 183 /* LSIO.QSPI0A.DATA2 */
+#define SC_P_QSPI0A_DATA3 184 /* LSIO.QSPI0A.DATA3 */
+#define SC_P_QSPI0A_DQS 185 /* LSIO.QSPI0A.DQS */
+#define SC_P_QSPI0A_SS0_B 186 /* LSIO.QSPI0A.SS0_B */
+#define SC_P_QSPI0A_SS1_B 187 /* LSIO.QSPI0A.SS1_B, LSIO.QSPI0A.SCLK2 */
+#define SC_P_QSPI0A_SCLK 188 /* LSIO.QSPI0A.SCLK */
+#define SC_P_QSPI0B_SCLK 189 /* LSIO.QSPI0B.SCLK */
+#define SC_P_QSPI0B_DATA0 190 /* LSIO.QSPI0B.DATA0 */
+#define SC_P_QSPI0B_DATA1 191 /* LSIO.QSPI0B.DATA1 */
+#define SC_P_QSPI0B_DATA2 192 /* LSIO.QSPI0B.DATA2 */
+#define SC_P_QSPI0B_DATA3 193 /* LSIO.QSPI0B.DATA3 */
+#define SC_P_QSPI0B_DQS 194 /* LSIO.QSPI0B.DQS */
+#define SC_P_QSPI0B_SS0_B 195 /* LSIO.QSPI0B.SS0_B */
+#define SC_P_QSPI0B_SS1_B 196 /* LSIO.QSPI0B.SS1_B, LSIO.QSPI0B.SCLK2 */
+#define SC_P_COMP_CTL_GPIO_1V8_3V3_QSPI0 197 /* */
+#define SC_P_PCIE_CTRL0_CLKREQ_B 198 /* HSIO.PCIE0.CLKREQ_B, LSIO.GPIO4.IO27 */
+#define SC_P_PCIE_CTRL0_WAKE_B 199 /* HSIO.PCIE0.WAKE_B, LSIO.GPIO4.IO28 */
+#define SC_P_PCIE_CTRL0_PERST_B 200 /* HSIO.PCIE0.PERST_B, LSIO.GPIO4.IO29 */
+#define SC_P_PCIE_CTRL1_CLKREQ_B 201 /* HSIO.PCIE1.CLKREQ_B, DMA.I2C1.SDA, CONN.USB_OTG2.OC, LSIO.GPIO4.IO30 */
+#define SC_P_PCIE_CTRL1_WAKE_B 202 /* HSIO.PCIE1.WAKE_B, DMA.I2C1.SCL, CONN.USB_OTG2.PWR, LSIO.GPIO4.IO31 */
+#define SC_P_PCIE_CTRL1_PERST_B 203 /* HSIO.PCIE1.PERST_B, DMA.I2C1.SCL, CONN.USB_OTG1.PWR, LSIO.GPIO5.IO00 */
+#define SC_P_COMP_CTL_GPIO_1V8_3V3_PCIESEP 204 /* */
+#define SC_P_USB_HSIC0_DATA 205 /* CONN.USB_HSIC0.DATA, DMA.I2C1.SDA, LSIO.GPIO5.IO01 */
+#define SC_P_USB_HSIC0_STROBE 206 /* CONN.USB_HSIC0.STROBE, DMA.I2C1.SCL, LSIO.GPIO5.IO02 */
+#define SC_P_CALIBRATION_0_HSIC 207 /* */
+#define SC_P_CALIBRATION_1_HSIC 208 /* */
+#define SC_P_EMMC0_CLK 209 /* CONN.EMMC0.CLK, CONN.NAND.READY_B */
+#define SC_P_EMMC0_CMD 210 /* CONN.EMMC0.CMD, CONN.NAND.DQS, AUD.MQS.R, LSIO.GPIO5.IO03 */
+#define SC_P_EMMC0_DATA0 211 /* CONN.EMMC0.DATA0, CONN.NAND.DATA00, LSIO.GPIO5.IO04 */
+#define SC_P_EMMC0_DATA1 212 /* CONN.EMMC0.DATA1, CONN.NAND.DATA01, LSIO.GPIO5.IO05 */
+#define SC_P_EMMC0_DATA2 213 /* CONN.EMMC0.DATA2, CONN.NAND.DATA02, LSIO.GPIO5.IO06 */
+#define SC_P_EMMC0_DATA3 214 /* CONN.EMMC0.DATA3, CONN.NAND.DATA03, LSIO.GPIO5.IO07 */
+#define SC_P_EMMC0_DATA4 215 /* CONN.EMMC0.DATA4, CONN.NAND.DATA04, LSIO.GPIO5.IO08 */
+#define SC_P_EMMC0_DATA5 216 /* CONN.EMMC0.DATA5, CONN.NAND.DATA05, LSIO.GPIO5.IO09 */
+#define SC_P_EMMC0_DATA6 217 /* CONN.EMMC0.DATA6, CONN.NAND.DATA06, LSIO.GPIO5.IO10 */
+#define SC_P_EMMC0_DATA7 218 /* CONN.EMMC0.DATA7, CONN.NAND.DATA07, LSIO.GPIO5.IO11 */
+#define SC_P_EMMC0_STROBE 219 /* CONN.EMMC0.STROBE, CONN.NAND.CLE, LSIO.GPIO5.IO12 */
+#define SC_P_EMMC0_RESET_B 220 /* CONN.EMMC0.RESET_B, CONN.NAND.WP_B, CONN.USDHC1.VSELECT, LSIO.GPIO5.IO13 */
+#define SC_P_COMP_CTL_GPIO_1V8_3V3_SD1FIX 221 /* */
+#define SC_P_USDHC1_CLK 222 /* CONN.USDHC1.CLK, AUD.MQS.R */
+#define SC_P_USDHC1_CMD 223 /* CONN.USDHC1.CMD, AUD.MQS.L, LSIO.GPIO5.IO14 */
+#define SC_P_USDHC1_DATA0 224 /* CONN.USDHC1.DATA0, CONN.NAND.RE_N, LSIO.GPIO5.IO15 */
+#define SC_P_USDHC1_DATA1 225 /* CONN.USDHC1.DATA1, CONN.NAND.RE_P, LSIO.GPIO5.IO16 */
+#define SC_P_CTL_NAND_RE_P_N 226 /* */
+#define SC_P_USDHC1_DATA2 227 /* CONN.USDHC1.DATA2, CONN.NAND.DQS_N, LSIO.GPIO5.IO17 */
+#define SC_P_USDHC1_DATA3 228 /* CONN.USDHC1.DATA3, CONN.NAND.DQS_P, LSIO.GPIO5.IO18 */
+#define SC_P_CTL_NAND_DQS_P_N 229 /* */
+#define SC_P_USDHC1_DATA4 230 /* CONN.USDHC1.DATA4, CONN.NAND.CE0_B, AUD.MQS.R, LSIO.GPIO5.IO19 */
+#define SC_P_USDHC1_DATA5 231 /* CONN.USDHC1.DATA5, CONN.NAND.RE_B, AUD.MQS.L, LSIO.GPIO5.IO20 */
+#define SC_P_USDHC1_DATA6 232 /* CONN.USDHC1.DATA6, CONN.NAND.WE_B, CONN.USDHC1.WP, LSIO.GPIO5.IO21 */
+#define SC_P_USDHC1_DATA7 233 /* CONN.USDHC1.DATA7, CONN.NAND.ALE, CONN.USDHC1.CD_B, LSIO.GPIO5.IO22 */
+#define SC_P_USDHC1_STROBE 234 /* CONN.USDHC1.STROBE, CONN.NAND.CE1_B, CONN.USDHC1.RESET_B, LSIO.GPIO5.IO23 */
+#define SC_P_COMP_CTL_GPIO_1V8_3V3_VSEL2 235 /* */
+#define SC_P_USDHC2_CLK 236 /* CONN.USDHC2.CLK, AUD.MQS.R, LSIO.GPIO5.IO24 */
+#define SC_P_USDHC2_CMD 237 /* CONN.USDHC2.CMD, AUD.MQS.L, LSIO.GPIO5.IO25 */
+#define SC_P_USDHC2_DATA0 238 /* CONN.USDHC2.DATA0, DMA.UART4.RX, LSIO.GPIO5.IO26 */
+#define SC_P_USDHC2_DATA1 239 /* CONN.USDHC2.DATA1, DMA.UART4.TX, LSIO.GPIO5.IO27 */
+#define SC_P_USDHC2_DATA2 240 /* CONN.USDHC2.DATA2, DMA.UART4.CTS_B, LSIO.GPIO5.IO28 */
+#define SC_P_USDHC2_DATA3 241 /* CONN.USDHC2.DATA3, DMA.UART4.RTS_B, LSIO.GPIO5.IO29 */
+#define SC_P_COMP_CTL_GPIO_1V8_3V3_VSEL3 242 /* */
+#define SC_P_ENET0_RGMII_TXC 243 /* CONN.ENET0.RGMII_TXC, CONN.ENET0.RCLK50M_OUT, CONN.ENET0.RCLK50M_IN, LSIO.GPIO5.IO30 */
+#define SC_P_ENET0_RGMII_TX_CTL 244 /* CONN.ENET0.RGMII_TX_CTL, LSIO.GPIO5.IO31 */
+#define SC_P_ENET0_RGMII_TXD0 245 /* CONN.ENET0.RGMII_TXD0, LSIO.GPIO6.IO00 */
+#define SC_P_ENET0_RGMII_TXD1 246 /* CONN.ENET0.RGMII_TXD1, LSIO.GPIO6.IO01 */
+#define SC_P_ENET0_RGMII_TXD2 247 /* CONN.ENET0.RGMII_TXD2, DMA.UART3.TX, VPU.TSI_S1.VID, LSIO.GPIO6.IO02 */
+#define SC_P_ENET0_RGMII_TXD3 248 /* CONN.ENET0.RGMII_TXD3, DMA.UART3.RTS_B, VPU.TSI_S1.SYNC, LSIO.GPIO6.IO03 */
+#define SC_P_ENET0_RGMII_RXC 249 /* CONN.ENET0.RGMII_RXC, DMA.UART3.CTS_B, VPU.TSI_S1.DATA, LSIO.GPIO6.IO04 */
+#define SC_P_ENET0_RGMII_RX_CTL 250 /* CONN.ENET0.RGMII_RX_CTL, VPU.TSI_S0.VID, LSIO.GPIO6.IO05 */
+#define SC_P_ENET0_RGMII_RXD0 251 /* CONN.ENET0.RGMII_RXD0, VPU.TSI_S0.SYNC, LSIO.GPIO6.IO06 */
+#define SC_P_ENET0_RGMII_RXD1 252 /* CONN.ENET0.RGMII_RXD1, VPU.TSI_S0.DATA, LSIO.GPIO6.IO07 */
+#define SC_P_ENET0_RGMII_RXD2 253 /* CONN.ENET0.RGMII_RXD2, CONN.ENET0.RMII_RX_ER, VPU.TSI_S0.CLK, LSIO.GPIO6.IO08 */
+#define SC_P_ENET0_RGMII_RXD3 254 /* CONN.ENET0.RGMII_RXD3, DMA.UART3.RX, VPU.TSI_S1.CLK, LSIO.GPIO6.IO09 */
+#define SC_P_COMP_CTL_GPIO_1V8_3V3_ENET_ENETB 255 /* */
+#define SC_P_ENET1_RGMII_TXC 256 /* CONN.ENET1.RGMII_TXC, CONN.ENET1.RCLK50M_OUT, CONN.ENET1.RCLK50M_IN, LSIO.GPIO6.IO10 */
+#define SC_P_ENET1_RGMII_TX_CTL 257 /* CONN.ENET1.RGMII_TX_CTL, LSIO.GPIO6.IO11 */
+#define SC_P_ENET1_RGMII_TXD0 258 /* CONN.ENET1.RGMII_TXD0, LSIO.GPIO6.IO12 */
+#define SC_P_ENET1_RGMII_TXD1 259 /* CONN.ENET1.RGMII_TXD1, LSIO.GPIO6.IO13 */
+#define SC_P_ENET1_RGMII_TXD2 260 /* CONN.ENET1.RGMII_TXD2, DMA.UART3.TX, VPU.TSI_S1.VID, LSIO.GPIO6.IO14 */
+#define SC_P_ENET1_RGMII_TXD3 261 /* CONN.ENET1.RGMII_TXD3, DMA.UART3.RTS_B, VPU.TSI_S1.SYNC, LSIO.GPIO6.IO15 */
+#define SC_P_ENET1_RGMII_RXC 262 /* CONN.ENET1.RGMII_RXC, DMA.UART3.CTS_B, VPU.TSI_S1.DATA, LSIO.GPIO6.IO16 */
+#define SC_P_ENET1_RGMII_RX_CTL 263 /* CONN.ENET1.RGMII_RX_CTL, VPU.TSI_S0.VID, LSIO.GPIO6.IO17 */
+#define SC_P_ENET1_RGMII_RXD0 264 /* CONN.ENET1.RGMII_RXD0, VPU.TSI_S0.SYNC, LSIO.GPIO6.IO18 */
+#define SC_P_ENET1_RGMII_RXD1 265 /* CONN.ENET1.RGMII_RXD1, VPU.TSI_S0.DATA, LSIO.GPIO6.IO19 */
+#define SC_P_ENET1_RGMII_RXD2 266 /* CONN.ENET1.RGMII_RXD2, CONN.ENET1.RMII_RX_ER, VPU.TSI_S0.CLK, LSIO.GPIO6.IO20 */
+#define SC_P_ENET1_RGMII_RXD3 267 /* CONN.ENET1.RGMII_RXD3, DMA.UART3.RX, VPU.TSI_S1.CLK, LSIO.GPIO6.IO21 */
+#define SC_P_COMP_CTL_GPIO_1V8_3V3_ENET_ENETA 268 /* */
+/*@}*/
+
+/*!
+ * @name Pad Mux Definitions
+ * format: name padid padmux
+ */
+/*@{*/
+#define SC_P_SIM0_CLK_DMA_SIM0_CLK SC_P_SIM0_CLK 0
+#define SC_P_SIM0_CLK_LSIO_GPIO0_IO00 SC_P_SIM0_CLK 3
+#define SC_P_SIM0_RST_DMA_SIM0_RST SC_P_SIM0_RST 0
+#define SC_P_SIM0_RST_LSIO_GPIO0_IO01 SC_P_SIM0_RST 3
+#define SC_P_SIM0_IO_DMA_SIM0_IO SC_P_SIM0_IO 0
+#define SC_P_SIM0_IO_LSIO_GPIO0_IO02 SC_P_SIM0_IO 3
+#define SC_P_SIM0_PD_DMA_SIM0_PD SC_P_SIM0_PD 0
+#define SC_P_SIM0_PD_DMA_I2C3_SCL SC_P_SIM0_PD 1
+#define SC_P_SIM0_PD_LSIO_GPIO0_IO03 SC_P_SIM0_PD 3
+#define SC_P_SIM0_POWER_EN_DMA_SIM0_POWER_EN SC_P_SIM0_POWER_EN 0
+#define SC_P_SIM0_POWER_EN_DMA_I2C3_SDA SC_P_SIM0_POWER_EN 1
+#define SC_P_SIM0_POWER_EN_LSIO_GPIO0_IO04 SC_P_SIM0_POWER_EN 3
+#define SC_P_SIM0_GPIO0_00_DMA_SIM0_POWER_EN SC_P_SIM0_GPIO0_00 0
+#define SC_P_SIM0_GPIO0_00_LSIO_GPIO0_IO05 SC_P_SIM0_GPIO0_00 3
+#define SC_P_M40_I2C0_SCL_M40_I2C0_SCL SC_P_M40_I2C0_SCL 0
+#define SC_P_M40_I2C0_SCL_M40_UART0_RX SC_P_M40_I2C0_SCL 1
+#define SC_P_M40_I2C0_SCL_M40_GPIO0_IO02 SC_P_M40_I2C0_SCL 2
+#define SC_P_M40_I2C0_SCL_LSIO_GPIO0_IO06 SC_P_M40_I2C0_SCL 3
+#define SC_P_M40_I2C0_SDA_M40_I2C0_SDA SC_P_M40_I2C0_SDA 0
+#define SC_P_M40_I2C0_SDA_M40_UART0_TX SC_P_M40_I2C0_SDA 1
+#define SC_P_M40_I2C0_SDA_M40_GPIO0_IO03 SC_P_M40_I2C0_SDA 2
+#define SC_P_M40_I2C0_SDA_LSIO_GPIO0_IO07 SC_P_M40_I2C0_SDA 3
+#define SC_P_M40_GPIO0_00_M40_GPIO0_IO00 SC_P_M40_GPIO0_00 0
+#define SC_P_M40_GPIO0_00_M40_TPM0_CH0 SC_P_M40_GPIO0_00 1
+#define SC_P_M40_GPIO0_00_DMA_UART4_RX SC_P_M40_GPIO0_00 2
+#define SC_P_M40_GPIO0_00_LSIO_GPIO0_IO08 SC_P_M40_GPIO0_00 3
+#define SC_P_M40_GPIO0_01_M40_GPIO0_IO01 SC_P_M40_GPIO0_01 0
+#define SC_P_M40_GPIO0_01_M40_TPM0_CH1 SC_P_M40_GPIO0_01 1
+#define SC_P_M40_GPIO0_01_DMA_UART4_TX SC_P_M40_GPIO0_01 2
+#define SC_P_M40_GPIO0_01_LSIO_GPIO0_IO09 SC_P_M40_GPIO0_01 3
+#define SC_P_M41_I2C0_SCL_M41_I2C0_SCL SC_P_M41_I2C0_SCL 0
+#define SC_P_M41_I2C0_SCL_M41_UART0_RX SC_P_M41_I2C0_SCL 1
+#define SC_P_M41_I2C0_SCL_M41_GPIO0_IO02 SC_P_M41_I2C0_SCL 2
+#define SC_P_M41_I2C0_SCL_LSIO_GPIO0_IO10 SC_P_M41_I2C0_SCL 3
+#define SC_P_M41_I2C0_SDA_M41_I2C0_SDA SC_P_M41_I2C0_SDA 0
+#define SC_P_M41_I2C0_SDA_M41_UART0_TX SC_P_M41_I2C0_SDA 1
+#define SC_P_M41_I2C0_SDA_M41_GPIO0_IO03 SC_P_M41_I2C0_SDA 2
+#define SC_P_M41_I2C0_SDA_LSIO_GPIO0_IO11 SC_P_M41_I2C0_SDA 3
+#define SC_P_M41_GPIO0_00_M41_GPIO0_IO00 SC_P_M41_GPIO0_00 0
+#define SC_P_M41_GPIO0_00_M41_TPM0_CH0 SC_P_M41_GPIO0_00 1
+#define SC_P_M41_GPIO0_00_DMA_UART3_RX SC_P_M41_GPIO0_00 2
+#define SC_P_M41_GPIO0_00_LSIO_GPIO0_IO12 SC_P_M41_GPIO0_00 3
+#define SC_P_M41_GPIO0_01_M41_GPIO0_IO01 SC_P_M41_GPIO0_01 0
+#define SC_P_M41_GPIO0_01_M41_TPM0_CH1 SC_P_M41_GPIO0_01 1
+#define SC_P_M41_GPIO0_01_DMA_UART3_TX SC_P_M41_GPIO0_01 2
+#define SC_P_M41_GPIO0_01_LSIO_GPIO0_IO13 SC_P_M41_GPIO0_01 3
+#define SC_P_GPT0_CLK_LSIO_GPT0_CLK SC_P_GPT0_CLK 0
+#define SC_P_GPT0_CLK_DMA_I2C1_SCL SC_P_GPT0_CLK 1
+#define SC_P_GPT0_CLK_LSIO_KPP0_COL4 SC_P_GPT0_CLK 2
+#define SC_P_GPT0_CLK_LSIO_GPIO0_IO14 SC_P_GPT0_CLK 3
+#define SC_P_GPT0_CAPTURE_LSIO_GPT0_CAPTURE SC_P_GPT0_CAPTURE 0
+#define SC_P_GPT0_CAPTURE_DMA_I2C1_SDA SC_P_GPT0_CAPTURE 1
+#define SC_P_GPT0_CAPTURE_LSIO_KPP0_COL5 SC_P_GPT0_CAPTURE 2
+#define SC_P_GPT0_CAPTURE_LSIO_GPIO0_IO15 SC_P_GPT0_CAPTURE 3
+#define SC_P_GPT0_COMPARE_LSIO_GPT0_COMPARE SC_P_GPT0_COMPARE 0
+#define SC_P_GPT0_COMPARE_LSIO_PWM3_OUT SC_P_GPT0_COMPARE 1
+#define SC_P_GPT0_COMPARE_LSIO_KPP0_COL6 SC_P_GPT0_COMPARE 2
+#define SC_P_GPT0_COMPARE_LSIO_GPIO0_IO16 SC_P_GPT0_COMPARE 3
+#define SC_P_GPT1_CLK_LSIO_GPT1_CLK SC_P_GPT1_CLK 0
+#define SC_P_GPT1_CLK_DMA_I2C2_SCL SC_P_GPT1_CLK 1
+#define SC_P_GPT1_CLK_LSIO_KPP0_COL7 SC_P_GPT1_CLK 2
+#define SC_P_GPT1_CLK_LSIO_GPIO0_IO17 SC_P_GPT1_CLK 3
+#define SC_P_GPT1_CAPTURE_LSIO_GPT1_CAPTURE SC_P_GPT1_CAPTURE 0
+#define SC_P_GPT1_CAPTURE_DMA_I2C2_SDA SC_P_GPT1_CAPTURE 1
+#define SC_P_GPT1_CAPTURE_LSIO_KPP0_ROW4 SC_P_GPT1_CAPTURE 2
+#define SC_P_GPT1_CAPTURE_LSIO_GPIO0_IO18 SC_P_GPT1_CAPTURE 3
+#define SC_P_GPT1_COMPARE_LSIO_GPT1_COMPARE SC_P_GPT1_COMPARE 0
+#define SC_P_GPT1_COMPARE_LSIO_PWM2_OUT SC_P_GPT1_COMPARE 1
+#define SC_P_GPT1_COMPARE_LSIO_KPP0_ROW5 SC_P_GPT1_COMPARE 2
+#define SC_P_GPT1_COMPARE_LSIO_GPIO0_IO19 SC_P_GPT1_COMPARE 3
+#define SC_P_UART0_RX_DMA_UART0_RX SC_P_UART0_RX 0
+#define SC_P_UART0_RX_SCU_UART0_RX SC_P_UART0_RX 1
+#define SC_P_UART0_RX_LSIO_GPIO0_IO20 SC_P_UART0_RX 3
+#define SC_P_UART0_TX_DMA_UART0_TX SC_P_UART0_TX 0
+#define SC_P_UART0_TX_SCU_UART0_TX SC_P_UART0_TX 1
+#define SC_P_UART0_TX_LSIO_GPIO0_IO21 SC_P_UART0_TX 3
+#define SC_P_UART0_RTS_B_DMA_UART0_RTS_B SC_P_UART0_RTS_B 0
+#define SC_P_UART0_RTS_B_LSIO_PWM0_OUT SC_P_UART0_RTS_B 1
+#define SC_P_UART0_RTS_B_DMA_UART2_RX SC_P_UART0_RTS_B 2
+#define SC_P_UART0_RTS_B_LSIO_GPIO0_IO22 SC_P_UART0_RTS_B 3
+#define SC_P_UART0_CTS_B_DMA_UART0_CTS_B SC_P_UART0_CTS_B 0
+#define SC_P_UART0_CTS_B_LSIO_PWM1_OUT SC_P_UART0_CTS_B 1
+#define SC_P_UART0_CTS_B_DMA_UART2_TX SC_P_UART0_CTS_B 2
+#define SC_P_UART0_CTS_B_LSIO_GPIO0_IO23 SC_P_UART0_CTS_B 3
+#define SC_P_UART1_TX_DMA_UART1_TX SC_P_UART1_TX 0
+#define SC_P_UART1_TX_DMA_SPI3_SCK SC_P_UART1_TX 1
+#define SC_P_UART1_TX_LSIO_GPIO0_IO24 SC_P_UART1_TX 3
+#define SC_P_UART1_RX_DMA_UART1_RX SC_P_UART1_RX 0
+#define SC_P_UART1_RX_DMA_SPI3_SDO SC_P_UART1_RX 1
+#define SC_P_UART1_RX_LSIO_GPIO0_IO25 SC_P_UART1_RX 3
+#define SC_P_UART1_RTS_B_DMA_UART1_RTS_B SC_P_UART1_RTS_B 0
+#define SC_P_UART1_RTS_B_DMA_SPI3_SDI SC_P_UART1_RTS_B 1
+#define SC_P_UART1_RTS_B_DMA_UART1_CTS_B SC_P_UART1_RTS_B 2
+#define SC_P_UART1_RTS_B_LSIO_GPIO0_IO26 SC_P_UART1_RTS_B 3
+#define SC_P_UART1_CTS_B_DMA_UART1_CTS_B SC_P_UART1_CTS_B 0
+#define SC_P_UART1_CTS_B_DMA_SPI3_CS0 SC_P_UART1_CTS_B 1
+#define SC_P_UART1_CTS_B_DMA_UART1_RTS_B SC_P_UART1_CTS_B 2
+#define SC_P_UART1_CTS_B_LSIO_GPIO0_IO27 SC_P_UART1_CTS_B 3
+#define SC_P_SCU_PMIC_MEMC_ON_SCU_GPIO0_IOXX_PMIC_MEMC_ON SC_P_SCU_PMIC_MEMC_ON 0
+#define SC_P_SCU_WDOG_OUT_SCU_WDOG0_WDOG_OUT SC_P_SCU_WDOG_OUT 0
+#define SC_P_PMIC_I2C_SDA_SCU_PMIC_I2C_SDA SC_P_PMIC_I2C_SDA 0
+#define SC_P_PMIC_I2C_SCL_SCU_PMIC_I2C_SCL SC_P_PMIC_I2C_SCL 0
+#define SC_P_PMIC_EARLY_WARNING_SCU_PMIC_EARLY_WARNING SC_P_PMIC_EARLY_WARNING 0
+#define SC_P_PMIC_INT_B_SCU_DSC_PMIC_INT_B SC_P_PMIC_INT_B 0
+#define SC_P_SCU_GPIO0_00_SCU_GPIO0_IO00 SC_P_SCU_GPIO0_00 0
+#define SC_P_SCU_GPIO0_00_SCU_UART0_RX SC_P_SCU_GPIO0_00 1
+#define SC_P_SCU_GPIO0_00_LSIO_GPIO0_IO28 SC_P_SCU_GPIO0_00 3
+#define SC_P_SCU_GPIO0_01_SCU_GPIO0_IO01 SC_P_SCU_GPIO0_01 0
+#define SC_P_SCU_GPIO0_01_SCU_UART0_TX SC_P_SCU_GPIO0_01 1
+#define SC_P_SCU_GPIO0_01_LSIO_GPIO0_IO29 SC_P_SCU_GPIO0_01 3
+#define SC_P_SCU_GPIO0_02_SCU_GPIO0_IO02 SC_P_SCU_GPIO0_02 0
+#define SC_P_SCU_GPIO0_02_SCU_GPIO0_IOXX_PMIC_GPU0_ON SC_P_SCU_GPIO0_02 1
+#define SC_P_SCU_GPIO0_02_LSIO_GPIO0_IO30 SC_P_SCU_GPIO0_02 3
+#define SC_P_SCU_GPIO0_03_SCU_GPIO0_IO03 SC_P_SCU_GPIO0_03 0
+#define SC_P_SCU_GPIO0_03_SCU_GPIO0_IOXX_PMIC_GPU1_ON SC_P_SCU_GPIO0_03 1
+#define SC_P_SCU_GPIO0_03_LSIO_GPIO0_IO31 SC_P_SCU_GPIO0_03 3
+#define SC_P_SCU_GPIO0_04_SCU_GPIO0_IO04 SC_P_SCU_GPIO0_04 0
+#define SC_P_SCU_GPIO0_04_SCU_GPIO0_IOXX_PMIC_A72_ON SC_P_SCU_GPIO0_04 1
+#define SC_P_SCU_GPIO0_04_LSIO_GPIO1_IO00 SC_P_SCU_GPIO0_04 3
+#define SC_P_SCU_GPIO0_05_SCU_GPIO0_IO05 SC_P_SCU_GPIO0_05 0
+#define SC_P_SCU_GPIO0_05_SCU_GPIO0_IOXX_PMIC_A53_ON SC_P_SCU_GPIO0_05 1
+#define SC_P_SCU_GPIO0_05_LSIO_GPIO1_IO01 SC_P_SCU_GPIO0_05 3
+#define SC_P_SCU_GPIO0_06_SCU_GPIO0_IO06 SC_P_SCU_GPIO0_06 0
+#define SC_P_SCU_GPIO0_06_SCU_TPM0_CH0 SC_P_SCU_GPIO0_06 1
+#define SC_P_SCU_GPIO0_06_LSIO_GPIO1_IO02 SC_P_SCU_GPIO0_06 3
+#define SC_P_SCU_GPIO0_07_SCU_GPIO0_IO07 SC_P_SCU_GPIO0_07 0
+#define SC_P_SCU_GPIO0_07_SCU_TPM0_CH1 SC_P_SCU_GPIO0_07 1
+#define SC_P_SCU_GPIO0_07_SCU_DSC_RTC_CLOCK_OUTPUT_32K SC_P_SCU_GPIO0_07 2
+#define SC_P_SCU_GPIO0_07_LSIO_GPIO1_IO03 SC_P_SCU_GPIO0_07 3
+#define SC_P_SCU_BOOT_MODE0_SCU_DSC_BOOT_MODE0 SC_P_SCU_BOOT_MODE0 0
+#define SC_P_SCU_BOOT_MODE1_SCU_DSC_BOOT_MODE1 SC_P_SCU_BOOT_MODE1 0
+#define SC_P_SCU_BOOT_MODE2_SCU_DSC_BOOT_MODE2 SC_P_SCU_BOOT_MODE2 0
+#define SC_P_SCU_BOOT_MODE3_SCU_DSC_BOOT_MODE3 SC_P_SCU_BOOT_MODE3 0
+#define SC_P_SCU_BOOT_MODE4_SCU_DSC_BOOT_MODE4 SC_P_SCU_BOOT_MODE4 0
+#define SC_P_SCU_BOOT_MODE4_SCU_PMIC_I2C_SCL SC_P_SCU_BOOT_MODE4 1
+#define SC_P_SCU_BOOT_MODE5_SCU_DSC_BOOT_MODE5 SC_P_SCU_BOOT_MODE5 0
+#define SC_P_SCU_BOOT_MODE5_SCU_PMIC_I2C_SDA SC_P_SCU_BOOT_MODE5 1
+#define SC_P_LVDS0_GPIO00_LVDS0_GPIO0_IO00 SC_P_LVDS0_GPIO00 0
+#define SC_P_LVDS0_GPIO00_LVDS0_PWM0_OUT SC_P_LVDS0_GPIO00 1
+#define SC_P_LVDS0_GPIO00_LSIO_GPIO1_IO04 SC_P_LVDS0_GPIO00 3
+#define SC_P_LVDS0_GPIO01_LVDS0_GPIO0_IO01 SC_P_LVDS0_GPIO01 0
+#define SC_P_LVDS0_GPIO01_LSIO_GPIO1_IO05 SC_P_LVDS0_GPIO01 3
+#define SC_P_LVDS0_I2C0_SCL_LVDS0_I2C0_SCL SC_P_LVDS0_I2C0_SCL 0
+#define SC_P_LVDS0_I2C0_SCL_LVDS0_GPIO0_IO02 SC_P_LVDS0_I2C0_SCL 1
+#define SC_P_LVDS0_I2C0_SCL_LSIO_GPIO1_IO06 SC_P_LVDS0_I2C0_SCL 3
+#define SC_P_LVDS0_I2C0_SDA_LVDS0_I2C0_SDA SC_P_LVDS0_I2C0_SDA 0
+#define SC_P_LVDS0_I2C0_SDA_LVDS0_GPIO0_IO03 SC_P_LVDS0_I2C0_SDA 1
+#define SC_P_LVDS0_I2C0_SDA_LSIO_GPIO1_IO07 SC_P_LVDS0_I2C0_SDA 3
+#define SC_P_LVDS0_I2C1_SCL_LVDS0_I2C1_SCL SC_P_LVDS0_I2C1_SCL 0
+#define SC_P_LVDS0_I2C1_SCL_DMA_UART2_TX SC_P_LVDS0_I2C1_SCL 1
+#define SC_P_LVDS0_I2C1_SCL_LSIO_GPIO1_IO08 SC_P_LVDS0_I2C1_SCL 3
+#define SC_P_LVDS0_I2C1_SDA_LVDS0_I2C1_SDA SC_P_LVDS0_I2C1_SDA 0
+#define SC_P_LVDS0_I2C1_SDA_DMA_UART2_RX SC_P_LVDS0_I2C1_SDA 1
+#define SC_P_LVDS0_I2C1_SDA_LSIO_GPIO1_IO09 SC_P_LVDS0_I2C1_SDA 3
+#define SC_P_LVDS1_GPIO00_LVDS1_GPIO0_IO00 SC_P_LVDS1_GPIO00 0
+#define SC_P_LVDS1_GPIO00_LVDS1_PWM0_OUT SC_P_LVDS1_GPIO00 1
+#define SC_P_LVDS1_GPIO00_LSIO_GPIO1_IO10 SC_P_LVDS1_GPIO00 3
+#define SC_P_LVDS1_GPIO01_LVDS1_GPIO0_IO01 SC_P_LVDS1_GPIO01 0
+#define SC_P_LVDS1_GPIO01_LSIO_GPIO1_IO11 SC_P_LVDS1_GPIO01 3
+#define SC_P_LVDS1_I2C0_SCL_LVDS1_I2C0_SCL SC_P_LVDS1_I2C0_SCL 0
+#define SC_P_LVDS1_I2C0_SCL_LVDS1_GPIO0_IO02 SC_P_LVDS1_I2C0_SCL 1
+#define SC_P_LVDS1_I2C0_SCL_LSIO_GPIO1_IO12 SC_P_LVDS1_I2C0_SCL 3
+#define SC_P_LVDS1_I2C0_SDA_LVDS1_I2C0_SDA SC_P_LVDS1_I2C0_SDA 0
+#define SC_P_LVDS1_I2C0_SDA_LVDS1_GPIO0_IO03 SC_P_LVDS1_I2C0_SDA 1
+#define SC_P_LVDS1_I2C0_SDA_LSIO_GPIO1_IO13 SC_P_LVDS1_I2C0_SDA 3
+#define SC_P_LVDS1_I2C1_SCL_LVDS1_I2C1_SCL SC_P_LVDS1_I2C1_SCL 0
+#define SC_P_LVDS1_I2C1_SCL_DMA_UART3_TX SC_P_LVDS1_I2C1_SCL 1
+#define SC_P_LVDS1_I2C1_SCL_LSIO_GPIO1_IO14 SC_P_LVDS1_I2C1_SCL 3
+#define SC_P_LVDS1_I2C1_SDA_LVDS1_I2C1_SDA SC_P_LVDS1_I2C1_SDA 0
+#define SC_P_LVDS1_I2C1_SDA_DMA_UART3_RX SC_P_LVDS1_I2C1_SDA 1
+#define SC_P_LVDS1_I2C1_SDA_LSIO_GPIO1_IO15 SC_P_LVDS1_I2C1_SDA 3
+#define SC_P_MIPI_DSI0_I2C0_SCL_MIPI_DSI0_I2C0_SCL SC_P_MIPI_DSI0_I2C0_SCL 0
+#define SC_P_MIPI_DSI0_I2C0_SCL_LSIO_GPIO1_IO16 SC_P_MIPI_DSI0_I2C0_SCL 3
+#define SC_P_MIPI_DSI0_I2C0_SDA_MIPI_DSI0_I2C0_SDA SC_P_MIPI_DSI0_I2C0_SDA 0
+#define SC_P_MIPI_DSI0_I2C0_SDA_LSIO_GPIO1_IO17 SC_P_MIPI_DSI0_I2C0_SDA 3
+#define SC_P_MIPI_DSI0_GPIO0_00_MIPI_DSI0_GPIO0_IO00 SC_P_MIPI_DSI0_GPIO0_00 0
+#define SC_P_MIPI_DSI0_GPIO0_00_MIPI_DSI0_PWM0_OUT SC_P_MIPI_DSI0_GPIO0_00 1
+#define SC_P_MIPI_DSI0_GPIO0_00_LSIO_GPIO1_IO18 SC_P_MIPI_DSI0_GPIO0_00 3
+#define SC_P_MIPI_DSI0_GPIO0_01_MIPI_DSI0_GPIO0_IO01 SC_P_MIPI_DSI0_GPIO0_01 0
+#define SC_P_MIPI_DSI0_GPIO0_01_LSIO_GPIO1_IO19 SC_P_MIPI_DSI0_GPIO0_01 3
+#define SC_P_MIPI_DSI1_I2C0_SCL_MIPI_DSI1_I2C0_SCL SC_P_MIPI_DSI1_I2C0_SCL 0
+#define SC_P_MIPI_DSI1_I2C0_SCL_LSIO_GPIO1_IO20 SC_P_MIPI_DSI1_I2C0_SCL 3
+#define SC_P_MIPI_DSI1_I2C0_SDA_MIPI_DSI1_I2C0_SDA SC_P_MIPI_DSI1_I2C0_SDA 0
+#define SC_P_MIPI_DSI1_I2C0_SDA_LSIO_GPIO1_IO21 SC_P_MIPI_DSI1_I2C0_SDA 3
+#define SC_P_MIPI_DSI1_GPIO0_00_MIPI_DSI1_GPIO0_IO00 SC_P_MIPI_DSI1_GPIO0_00 0
+#define SC_P_MIPI_DSI1_GPIO0_00_MIPI_DSI1_PWM0_OUT SC_P_MIPI_DSI1_GPIO0_00 1
+#define SC_P_MIPI_DSI1_GPIO0_00_LSIO_GPIO1_IO22 SC_P_MIPI_DSI1_GPIO0_00 3
+#define SC_P_MIPI_DSI1_GPIO0_01_MIPI_DSI1_GPIO0_IO01 SC_P_MIPI_DSI1_GPIO0_01 0
+#define SC_P_MIPI_DSI1_GPIO0_01_LSIO_GPIO1_IO23 SC_P_MIPI_DSI1_GPIO0_01 3
+#define SC_P_MIPI_CSI0_MCLK_OUT_MIPI_CSI0_ACM_MCLK_OUT SC_P_MIPI_CSI0_MCLK_OUT 0
+#define SC_P_MIPI_CSI0_MCLK_OUT_LSIO_GPIO1_IO24 SC_P_MIPI_CSI0_MCLK_OUT 3
+#define SC_P_MIPI_CSI0_I2C0_SCL_MIPI_CSI0_I2C0_SCL SC_P_MIPI_CSI0_I2C0_SCL 0
+#define SC_P_MIPI_CSI0_I2C0_SCL_LSIO_GPIO1_IO25 SC_P_MIPI_CSI0_I2C0_SCL 3
+#define SC_P_MIPI_CSI0_I2C0_SDA_MIPI_CSI0_I2C0_SDA SC_P_MIPI_CSI0_I2C0_SDA 0
+#define SC_P_MIPI_CSI0_I2C0_SDA_LSIO_GPIO1_IO26 SC_P_MIPI_CSI0_I2C0_SDA 3
+#define SC_P_MIPI_CSI0_GPIO0_00_MIPI_CSI0_GPIO0_IO00 SC_P_MIPI_CSI0_GPIO0_00 0
+#define SC_P_MIPI_CSI0_GPIO0_00_DMA_I2C0_SCL SC_P_MIPI_CSI0_GPIO0_00 1
+#define SC_P_MIPI_CSI0_GPIO0_00_MIPI_CSI1_I2C0_SCL SC_P_MIPI_CSI0_GPIO0_00 2
+#define SC_P_MIPI_CSI0_GPIO0_00_LSIO_GPIO1_IO27 SC_P_MIPI_CSI0_GPIO0_00 3
+#define SC_P_MIPI_CSI0_GPIO0_01_MIPI_CSI0_GPIO0_IO01 SC_P_MIPI_CSI0_GPIO0_01 0
+#define SC_P_MIPI_CSI0_GPIO0_01_DMA_I2C0_SDA SC_P_MIPI_CSI0_GPIO0_01 1
+#define SC_P_MIPI_CSI0_GPIO0_01_MIPI_CSI1_I2C0_SDA SC_P_MIPI_CSI0_GPIO0_01 2
+#define SC_P_MIPI_CSI0_GPIO0_01_LSIO_GPIO1_IO28 SC_P_MIPI_CSI0_GPIO0_01 3
+#define SC_P_MIPI_CSI1_MCLK_OUT_MIPI_CSI1_ACM_MCLK_OUT SC_P_MIPI_CSI1_MCLK_OUT 0
+#define SC_P_MIPI_CSI1_MCLK_OUT_LSIO_GPIO1_IO29 SC_P_MIPI_CSI1_MCLK_OUT 3
+#define SC_P_MIPI_CSI1_GPIO0_00_MIPI_CSI1_GPIO0_IO00 SC_P_MIPI_CSI1_GPIO0_00 0
+#define SC_P_MIPI_CSI1_GPIO0_00_DMA_UART4_RX SC_P_MIPI_CSI1_GPIO0_00 1
+#define SC_P_MIPI_CSI1_GPIO0_00_LSIO_GPIO1_IO30 SC_P_MIPI_CSI1_GPIO0_00 3
+#define SC_P_MIPI_CSI1_GPIO0_01_MIPI_CSI1_GPIO0_IO01 SC_P_MIPI_CSI1_GPIO0_01 0
+#define SC_P_MIPI_CSI1_GPIO0_01_DMA_UART4_TX SC_P_MIPI_CSI1_GPIO0_01 1
+#define SC_P_MIPI_CSI1_GPIO0_01_LSIO_GPIO1_IO31 SC_P_MIPI_CSI1_GPIO0_01 3
+#define SC_P_MIPI_CSI1_I2C0_SCL_MIPI_CSI1_I2C0_SCL SC_P_MIPI_CSI1_I2C0_SCL 0
+#define SC_P_MIPI_CSI1_I2C0_SCL_LSIO_GPIO2_IO00 SC_P_MIPI_CSI1_I2C0_SCL 3
+#define SC_P_MIPI_CSI1_I2C0_SDA_MIPI_CSI1_I2C0_SDA SC_P_MIPI_CSI1_I2C0_SDA 0
+#define SC_P_MIPI_CSI1_I2C0_SDA_LSIO_GPIO2_IO01 SC_P_MIPI_CSI1_I2C0_SDA 3
+#define SC_P_HDMI_TX0_TS_SCL_HDMI_TX0_I2C0_SCL SC_P_HDMI_TX0_TS_SCL 0
+#define SC_P_HDMI_TX0_TS_SCL_DMA_I2C0_SCL SC_P_HDMI_TX0_TS_SCL 1
+#define SC_P_HDMI_TX0_TS_SCL_LSIO_GPIO2_IO02 SC_P_HDMI_TX0_TS_SCL 3
+#define SC_P_HDMI_TX0_TS_SDA_HDMI_TX0_I2C0_SDA SC_P_HDMI_TX0_TS_SDA 0
+#define SC_P_HDMI_TX0_TS_SDA_DMA_I2C0_SDA SC_P_HDMI_TX0_TS_SDA 1
+#define SC_P_HDMI_TX0_TS_SDA_LSIO_GPIO2_IO03 SC_P_HDMI_TX0_TS_SDA 3
+#define SC_P_ESAI1_FSR_AUD_ESAI1_FSR SC_P_ESAI1_FSR 0
+#define SC_P_ESAI1_FSR_LSIO_GPIO2_IO04 SC_P_ESAI1_FSR 3
+#define SC_P_ESAI1_FST_AUD_ESAI1_FST SC_P_ESAI1_FST 0
+#define SC_P_ESAI1_FST_AUD_SPDIF0_EXT_CLK SC_P_ESAI1_FST 1
+#define SC_P_ESAI1_FST_LSIO_GPIO2_IO05 SC_P_ESAI1_FST 3
+#define SC_P_ESAI1_SCKR_AUD_ESAI1_SCKR SC_P_ESAI1_SCKR 0
+#define SC_P_ESAI1_SCKR_LSIO_GPIO2_IO06 SC_P_ESAI1_SCKR 3
+#define SC_P_ESAI1_SCKT_AUD_ESAI1_SCKT SC_P_ESAI1_SCKT 0
+#define SC_P_ESAI1_SCKT_AUD_SAI2_RXC SC_P_ESAI1_SCKT 1
+#define SC_P_ESAI1_SCKT_AUD_SPDIF0_EXT_CLK SC_P_ESAI1_SCKT 2
+#define SC_P_ESAI1_SCKT_LSIO_GPIO2_IO07 SC_P_ESAI1_SCKT 3
+#define SC_P_ESAI1_TX0_AUD_ESAI1_TX0 SC_P_ESAI1_TX0 0
+#define SC_P_ESAI1_TX0_AUD_SAI2_RXD SC_P_ESAI1_TX0 1
+#define SC_P_ESAI1_TX0_AUD_SPDIF0_RX SC_P_ESAI1_TX0 2
+#define SC_P_ESAI1_TX0_LSIO_GPIO2_IO08 SC_P_ESAI1_TX0 3
+#define SC_P_ESAI1_TX1_AUD_ESAI1_TX1 SC_P_ESAI1_TX1 0
+#define SC_P_ESAI1_TX1_AUD_SAI2_RXFS SC_P_ESAI1_TX1 1
+#define SC_P_ESAI1_TX1_AUD_SPDIF0_TX SC_P_ESAI1_TX1 2
+#define SC_P_ESAI1_TX1_LSIO_GPIO2_IO09 SC_P_ESAI1_TX1 3
+#define SC_P_ESAI1_TX2_RX3_AUD_ESAI1_TX2_RX3 SC_P_ESAI1_TX2_RX3 0
+#define SC_P_ESAI1_TX2_RX3_AUD_SPDIF0_RX SC_P_ESAI1_TX2_RX3 1
+#define SC_P_ESAI1_TX2_RX3_LSIO_GPIO2_IO10 SC_P_ESAI1_TX2_RX3 3
+#define SC_P_ESAI1_TX3_RX2_AUD_ESAI1_TX3_RX2 SC_P_ESAI1_TX3_RX2 0
+#define SC_P_ESAI1_TX3_RX2_AUD_SPDIF0_TX SC_P_ESAI1_TX3_RX2 1
+#define SC_P_ESAI1_TX3_RX2_LSIO_GPIO2_IO11 SC_P_ESAI1_TX3_RX2 3
+#define SC_P_ESAI1_TX4_RX1_AUD_ESAI1_TX4_RX1 SC_P_ESAI1_TX4_RX1 0
+#define SC_P_ESAI1_TX4_RX1_LSIO_GPIO2_IO12 SC_P_ESAI1_TX4_RX1 3
+#define SC_P_ESAI1_TX5_RX0_AUD_ESAI1_TX5_RX0 SC_P_ESAI1_TX5_RX0 0
+#define SC_P_ESAI1_TX5_RX0_LSIO_GPIO2_IO13 SC_P_ESAI1_TX5_RX0 3
+#define SC_P_SPDIF0_RX_AUD_SPDIF0_RX SC_P_SPDIF0_RX 0
+#define SC_P_SPDIF0_RX_AUD_MQS_R SC_P_SPDIF0_RX 1
+#define SC_P_SPDIF0_RX_AUD_ACM_MCLK_IN1 SC_P_SPDIF0_RX 2
+#define SC_P_SPDIF0_RX_LSIO_GPIO2_IO14 SC_P_SPDIF0_RX 3
+#define SC_P_SPDIF0_TX_AUD_SPDIF0_TX SC_P_SPDIF0_TX 0
+#define SC_P_SPDIF0_TX_AUD_MQS_L SC_P_SPDIF0_TX 1
+#define SC_P_SPDIF0_TX_AUD_ACM_MCLK_OUT1 SC_P_SPDIF0_TX 2
+#define SC_P_SPDIF0_TX_LSIO_GPIO2_IO15 SC_P_SPDIF0_TX 3
+#define SC_P_SPDIF0_EXT_CLK_AUD_SPDIF0_EXT_CLK SC_P_SPDIF0_EXT_CLK 0
+#define SC_P_SPDIF0_EXT_CLK_DMA_DMA0_REQ_IN0 SC_P_SPDIF0_EXT_CLK 1
+#define SC_P_SPDIF0_EXT_CLK_LSIO_GPIO2_IO16 SC_P_SPDIF0_EXT_CLK 3
+#define SC_P_SPI3_SCK_DMA_SPI3_SCK SC_P_SPI3_SCK 0
+#define SC_P_SPI3_SCK_LSIO_GPIO2_IO17 SC_P_SPI3_SCK 3
+#define SC_P_SPI3_SDO_DMA_SPI3_SDO SC_P_SPI3_SDO 0
+#define SC_P_SPI3_SDO_DMA_FTM_CH0 SC_P_SPI3_SDO 1
+#define SC_P_SPI3_SDO_LSIO_GPIO2_IO18 SC_P_SPI3_SDO 3
+#define SC_P_SPI3_SDI_DMA_SPI3_SDI SC_P_SPI3_SDI 0
+#define SC_P_SPI3_SDI_DMA_FTM_CH1 SC_P_SPI3_SDI 1
+#define SC_P_SPI3_SDI_LSIO_GPIO2_IO19 SC_P_SPI3_SDI 3
+#define SC_P_SPI3_CS0_DMA_SPI3_CS0 SC_P_SPI3_CS0 0
+#define SC_P_SPI3_CS0_DMA_FTM_CH2 SC_P_SPI3_CS0 1
+#define SC_P_SPI3_CS0_LSIO_GPIO2_IO20 SC_P_SPI3_CS0 3
+#define SC_P_SPI3_CS1_DMA_SPI3_CS1 SC_P_SPI3_CS1 0
+#define SC_P_SPI3_CS1_LSIO_GPIO2_IO21 SC_P_SPI3_CS1 3
+#define SC_P_ESAI0_FSR_AUD_ESAI0_FSR SC_P_ESAI0_FSR 0
+#define SC_P_ESAI0_FSR_LSIO_GPIO2_IO22 SC_P_ESAI0_FSR 3
+#define SC_P_ESAI0_FST_AUD_ESAI0_FST SC_P_ESAI0_FST 0
+#define SC_P_ESAI0_FST_LSIO_GPIO2_IO23 SC_P_ESAI0_FST 3
+#define SC_P_ESAI0_SCKR_AUD_ESAI0_SCKR SC_P_ESAI0_SCKR 0
+#define SC_P_ESAI0_SCKR_LSIO_GPIO2_IO24 SC_P_ESAI0_SCKR 3
+#define SC_P_ESAI0_SCKT_AUD_ESAI0_SCKT SC_P_ESAI0_SCKT 0
+#define SC_P_ESAI0_SCKT_LSIO_GPIO2_IO25 SC_P_ESAI0_SCKT 3
+#define SC_P_ESAI0_TX0_AUD_ESAI0_TX0 SC_P_ESAI0_TX0 0
+#define SC_P_ESAI0_TX0_LSIO_GPIO2_IO26 SC_P_ESAI0_TX0 3
+#define SC_P_ESAI0_TX1_AUD_ESAI0_TX1 SC_P_ESAI0_TX1 0
+#define SC_P_ESAI0_TX1_LSIO_GPIO2_IO27 SC_P_ESAI0_TX1 3
+#define SC_P_ESAI0_TX2_RX3_AUD_ESAI0_TX2_RX3 SC_P_ESAI0_TX2_RX3 0
+#define SC_P_ESAI0_TX2_RX3_LSIO_GPIO2_IO28 SC_P_ESAI0_TX2_RX3 3
+#define SC_P_ESAI0_TX3_RX2_AUD_ESAI0_TX3_RX2 SC_P_ESAI0_TX3_RX2 0
+#define SC_P_ESAI0_TX3_RX2_LSIO_GPIO2_IO29 SC_P_ESAI0_TX3_RX2 3
+#define SC_P_ESAI0_TX4_RX1_AUD_ESAI0_TX4_RX1 SC_P_ESAI0_TX4_RX1 0
+#define SC_P_ESAI0_TX4_RX1_LSIO_GPIO2_IO30 SC_P_ESAI0_TX4_RX1 3
+#define SC_P_ESAI0_TX5_RX0_AUD_ESAI0_TX5_RX0 SC_P_ESAI0_TX5_RX0 0
+#define SC_P_ESAI0_TX5_RX0_LSIO_GPIO2_IO31 SC_P_ESAI0_TX5_RX0 3
+#define SC_P_MCLK_IN0_AUD_ACM_MCLK_IN0 SC_P_MCLK_IN0 0
+#define SC_P_MCLK_IN0_AUD_ESAI0_RX_HF_CLK SC_P_MCLK_IN0 1
+#define SC_P_MCLK_IN0_AUD_ESAI1_RX_HF_CLK SC_P_MCLK_IN0 2
+#define SC_P_MCLK_IN0_LSIO_GPIO3_IO00 SC_P_MCLK_IN0 3
+#define SC_P_MCLK_OUT0_AUD_ACM_MCLK_OUT0 SC_P_MCLK_OUT0 0
+#define SC_P_MCLK_OUT0_AUD_ESAI0_TX_HF_CLK SC_P_MCLK_OUT0 1
+#define SC_P_MCLK_OUT0_AUD_ESAI1_TX_HF_CLK SC_P_MCLK_OUT0 2
+#define SC_P_MCLK_OUT0_LSIO_GPIO3_IO01 SC_P_MCLK_OUT0 3
+#define SC_P_SPI0_SCK_DMA_SPI0_SCK SC_P_SPI0_SCK 0
+#define SC_P_SPI0_SCK_AUD_SAI0_RXC SC_P_SPI0_SCK 1
+#define SC_P_SPI0_SCK_LSIO_GPIO3_IO02 SC_P_SPI0_SCK 3
+#define SC_P_SPI0_SDO_DMA_SPI0_SDO SC_P_SPI0_SDO 0
+#define SC_P_SPI0_SDO_AUD_SAI0_TXD SC_P_SPI0_SDO 1
+#define SC_P_SPI0_SDO_LSIO_GPIO3_IO03 SC_P_SPI0_SDO 3
+#define SC_P_SPI0_SDI_DMA_SPI0_SDI SC_P_SPI0_SDI 0
+#define SC_P_SPI0_SDI_AUD_SAI0_RXD SC_P_SPI0_SDI 1
+#define SC_P_SPI0_SDI_LSIO_GPIO3_IO04 SC_P_SPI0_SDI 3
+#define SC_P_SPI0_CS0_DMA_SPI0_CS0 SC_P_SPI0_CS0 0
+#define SC_P_SPI0_CS0_AUD_SAI0_RXFS SC_P_SPI0_CS0 1
+#define SC_P_SPI0_CS0_LSIO_GPIO3_IO05 SC_P_SPI0_CS0 3
+#define SC_P_SPI0_CS1_DMA_SPI0_CS1 SC_P_SPI0_CS1 0
+#define SC_P_SPI0_CS1_AUD_SAI0_TXC SC_P_SPI0_CS1 1
+#define SC_P_SPI0_CS1_LSIO_GPIO3_IO06 SC_P_SPI0_CS1 3
+#define SC_P_SPI2_SCK_DMA_SPI2_SCK SC_P_SPI2_SCK 0
+#define SC_P_SPI2_SCK_LSIO_GPIO3_IO07 SC_P_SPI2_SCK 3
+#define SC_P_SPI2_SDO_DMA_SPI2_SDO SC_P_SPI2_SDO 0
+#define SC_P_SPI2_SDO_LSIO_GPIO3_IO08 SC_P_SPI2_SDO 3
+#define SC_P_SPI2_SDI_DMA_SPI2_SDI SC_P_SPI2_SDI 0
+#define SC_P_SPI2_SDI_LSIO_GPIO3_IO09 SC_P_SPI2_SDI 3
+#define SC_P_SPI2_CS0_DMA_SPI2_CS0 SC_P_SPI2_CS0 0
+#define SC_P_SPI2_CS0_LSIO_GPIO3_IO10 SC_P_SPI2_CS0 3
+#define SC_P_SPI2_CS1_DMA_SPI2_CS1 SC_P_SPI2_CS1 0
+#define SC_P_SPI2_CS1_AUD_SAI0_TXFS SC_P_SPI2_CS1 1
+#define SC_P_SPI2_CS1_LSIO_GPIO3_IO11 SC_P_SPI2_CS1 3
+#define SC_P_SAI1_RXC_AUD_SAI1_RXC SC_P_SAI1_RXC 0
+#define SC_P_SAI1_RXC_AUD_SAI0_TXD SC_P_SAI1_RXC 1
+#define SC_P_SAI1_RXC_LSIO_GPIO3_IO12 SC_P_SAI1_RXC 3
+#define SC_P_SAI1_RXD_AUD_SAI1_RXD SC_P_SAI1_RXD 0
+#define SC_P_SAI1_RXD_AUD_SAI0_TXFS SC_P_SAI1_RXD 1
+#define SC_P_SAI1_RXD_LSIO_GPIO3_IO13 SC_P_SAI1_RXD 3
+#define SC_P_SAI1_RXFS_AUD_SAI1_RXFS SC_P_SAI1_RXFS 0
+#define SC_P_SAI1_RXFS_AUD_SAI0_RXD SC_P_SAI1_RXFS 1
+#define SC_P_SAI1_RXFS_LSIO_GPIO3_IO14 SC_P_SAI1_RXFS 3
+#define SC_P_SAI1_TXC_AUD_SAI1_TXC SC_P_SAI1_TXC 0
+#define SC_P_SAI1_TXC_AUD_SAI0_TXC SC_P_SAI1_TXC 1
+#define SC_P_SAI1_TXC_LSIO_GPIO3_IO15 SC_P_SAI1_TXC 3
+#define SC_P_SAI1_TXD_AUD_SAI1_TXD SC_P_SAI1_TXD 0
+#define SC_P_SAI1_TXD_AUD_SAI1_RXC SC_P_SAI1_TXD 1
+#define SC_P_SAI1_TXD_LSIO_GPIO3_IO16 SC_P_SAI1_TXD 3
+#define SC_P_SAI1_TXFS_AUD_SAI1_TXFS SC_P_SAI1_TXFS 0
+#define SC_P_SAI1_TXFS_AUD_SAI1_RXFS SC_P_SAI1_TXFS 1
+#define SC_P_SAI1_TXFS_LSIO_GPIO3_IO17 SC_P_SAI1_TXFS 3
+#define SC_P_ADC_IN7_DMA_ADC1_IN3 SC_P_ADC_IN7 0
+#define SC_P_ADC_IN7_DMA_SPI1_CS1 SC_P_ADC_IN7 1
+#define SC_P_ADC_IN7_LSIO_KPP0_ROW3 SC_P_ADC_IN7 2
+#define SC_P_ADC_IN7_LSIO_GPIO3_IO25 SC_P_ADC_IN7 3
+#define SC_P_ADC_IN6_DMA_ADC1_IN2 SC_P_ADC_IN6 0
+#define SC_P_ADC_IN6_DMA_SPI1_CS0 SC_P_ADC_IN6 1
+#define SC_P_ADC_IN6_LSIO_KPP0_ROW2 SC_P_ADC_IN6 2
+#define SC_P_ADC_IN6_LSIO_GPIO3_IO24 SC_P_ADC_IN6 3
+#define SC_P_ADC_IN5_DMA_ADC1_IN1 SC_P_ADC_IN5 0
+#define SC_P_ADC_IN5_DMA_SPI1_SDI SC_P_ADC_IN5 1
+#define SC_P_ADC_IN5_LSIO_KPP0_ROW1 SC_P_ADC_IN5 2
+#define SC_P_ADC_IN5_LSIO_GPIO3_IO23 SC_P_ADC_IN5 3
+#define SC_P_ADC_IN4_DMA_ADC1_IN0 SC_P_ADC_IN4 0
+#define SC_P_ADC_IN4_DMA_SPI1_SDO SC_P_ADC_IN4 1
+#define SC_P_ADC_IN4_LSIO_KPP0_ROW0 SC_P_ADC_IN4 2
+#define SC_P_ADC_IN4_LSIO_GPIO3_IO22 SC_P_ADC_IN4 3
+#define SC_P_ADC_IN3_DMA_ADC0_IN3 SC_P_ADC_IN3 0
+#define SC_P_ADC_IN3_DMA_SPI1_SCK SC_P_ADC_IN3 1
+#define SC_P_ADC_IN3_LSIO_KPP0_COL3 SC_P_ADC_IN3 2
+#define SC_P_ADC_IN3_LSIO_GPIO3_IO21 SC_P_ADC_IN3 3
+#define SC_P_ADC_IN2_DMA_ADC0_IN2 SC_P_ADC_IN2 0
+#define SC_P_ADC_IN2_LSIO_KPP0_COL2 SC_P_ADC_IN2 2
+#define SC_P_ADC_IN2_LSIO_GPIO3_IO20 SC_P_ADC_IN2 3
+#define SC_P_ADC_IN1_DMA_ADC0_IN1 SC_P_ADC_IN1 0
+#define SC_P_ADC_IN1_LSIO_KPP0_COL1 SC_P_ADC_IN1 2
+#define SC_P_ADC_IN1_LSIO_GPIO3_IO19 SC_P_ADC_IN1 3
+#define SC_P_ADC_IN0_DMA_ADC0_IN0 SC_P_ADC_IN0 0
+#define SC_P_ADC_IN0_LSIO_KPP0_COL0 SC_P_ADC_IN0 2
+#define SC_P_ADC_IN0_LSIO_GPIO3_IO18 SC_P_ADC_IN0 3
+#define SC_P_MLB_SIG_CONN_MLB_SIG SC_P_MLB_SIG 0
+#define SC_P_MLB_SIG_AUD_SAI3_RXC SC_P_MLB_SIG 1
+#define SC_P_MLB_SIG_LSIO_GPIO3_IO26 SC_P_MLB_SIG 3
+#define SC_P_MLB_CLK_CONN_MLB_CLK SC_P_MLB_CLK 0
+#define SC_P_MLB_CLK_AUD_SAI3_RXFS SC_P_MLB_CLK 1
+#define SC_P_MLB_CLK_LSIO_GPIO3_IO27 SC_P_MLB_CLK 3
+#define SC_P_MLB_DATA_CONN_MLB_DATA SC_P_MLB_DATA 0
+#define SC_P_MLB_DATA_AUD_SAI3_RXD SC_P_MLB_DATA 1
+#define SC_P_MLB_DATA_LSIO_GPIO3_IO28 SC_P_MLB_DATA 3
+#define SC_P_FLEXCAN0_RX_DMA_FLEXCAN0_RX SC_P_FLEXCAN0_RX 0
+#define SC_P_FLEXCAN0_RX_LSIO_GPIO3_IO29 SC_P_FLEXCAN0_RX 3
+#define SC_P_FLEXCAN0_TX_DMA_FLEXCAN0_TX SC_P_FLEXCAN0_TX 0
+#define SC_P_FLEXCAN0_TX_LSIO_GPIO3_IO30 SC_P_FLEXCAN0_TX 3
+#define SC_P_FLEXCAN1_RX_DMA_FLEXCAN1_RX SC_P_FLEXCAN1_RX 0
+#define SC_P_FLEXCAN1_RX_LSIO_GPIO3_IO31 SC_P_FLEXCAN1_RX 3
+#define SC_P_FLEXCAN1_TX_DMA_FLEXCAN1_TX SC_P_FLEXCAN1_TX 0
+#define SC_P_FLEXCAN1_TX_LSIO_GPIO4_IO00 SC_P_FLEXCAN1_TX 3
+#define SC_P_FLEXCAN2_RX_DMA_FLEXCAN2_RX SC_P_FLEXCAN2_RX 0
+#define SC_P_FLEXCAN2_RX_LSIO_GPIO4_IO01 SC_P_FLEXCAN2_RX 3
+#define SC_P_FLEXCAN2_TX_DMA_FLEXCAN2_TX SC_P_FLEXCAN2_TX 0
+#define SC_P_FLEXCAN2_TX_LSIO_GPIO4_IO02 SC_P_FLEXCAN2_TX 3
+#define SC_P_USB_SS3_TC0_DMA_I2C1_SCL SC_P_USB_SS3_TC0 0
+#define SC_P_USB_SS3_TC0_CONN_USB_OTG1_PWR SC_P_USB_SS3_TC0 1
+#define SC_P_USB_SS3_TC0_LSIO_GPIO4_IO03 SC_P_USB_SS3_TC0 3
+#define SC_P_USB_SS3_TC1_DMA_I2C1_SCL SC_P_USB_SS3_TC1 0
+#define SC_P_USB_SS3_TC1_CONN_USB_OTG2_PWR SC_P_USB_SS3_TC1 1
+#define SC_P_USB_SS3_TC1_LSIO_GPIO4_IO04 SC_P_USB_SS3_TC1 3
+#define SC_P_USB_SS3_TC2_DMA_I2C1_SDA SC_P_USB_SS3_TC2 0
+#define SC_P_USB_SS3_TC2_CONN_USB_OTG1_OC SC_P_USB_SS3_TC2 1
+#define SC_P_USB_SS3_TC2_LSIO_GPIO4_IO05 SC_P_USB_SS3_TC2 3
+#define SC_P_USB_SS3_TC3_DMA_I2C1_SDA SC_P_USB_SS3_TC3 0
+#define SC_P_USB_SS3_TC3_CONN_USB_OTG2_OC SC_P_USB_SS3_TC3 1
+#define SC_P_USB_SS3_TC3_LSIO_GPIO4_IO06 SC_P_USB_SS3_TC3 3
+#define SC_P_USDHC1_RESET_B_CONN_USDHC1_RESET_B SC_P_USDHC1_RESET_B 0
+#define SC_P_USDHC1_RESET_B_LSIO_GPIO4_IO07 SC_P_USDHC1_RESET_B 3
+#define SC_P_USDHC1_VSELECT_CONN_USDHC1_VSELECT SC_P_USDHC1_VSELECT 0
+#define SC_P_USDHC1_VSELECT_LSIO_GPIO4_IO08 SC_P_USDHC1_VSELECT 3
+#define SC_P_USDHC2_RESET_B_CONN_USDHC2_RESET_B SC_P_USDHC2_RESET_B 0
+#define SC_P_USDHC2_RESET_B_LSIO_GPIO4_IO09 SC_P_USDHC2_RESET_B 3
+#define SC_P_USDHC2_VSELECT_CONN_USDHC2_VSELECT SC_P_USDHC2_VSELECT 0
+#define SC_P_USDHC2_VSELECT_LSIO_GPIO4_IO10 SC_P_USDHC2_VSELECT 3
+#define SC_P_USDHC2_WP_CONN_USDHC2_WP SC_P_USDHC2_WP 0
+#define SC_P_USDHC2_WP_LSIO_GPIO4_IO11 SC_P_USDHC2_WP 3
+#define SC_P_USDHC2_CD_B_CONN_USDHC2_CD_B SC_P_USDHC2_CD_B 0
+#define SC_P_USDHC2_CD_B_LSIO_GPIO4_IO12 SC_P_USDHC2_CD_B 3
+#define SC_P_ENET0_MDIO_CONN_ENET0_MDIO SC_P_ENET0_MDIO 0
+#define SC_P_ENET0_MDIO_DMA_I2C4_SDA SC_P_ENET0_MDIO 1
+#define SC_P_ENET0_MDIO_LSIO_GPIO4_IO13 SC_P_ENET0_MDIO 3
+#define SC_P_ENET0_MDC_CONN_ENET0_MDC SC_P_ENET0_MDC 0
+#define SC_P_ENET0_MDC_DMA_I2C4_SCL SC_P_ENET0_MDC 1
+#define SC_P_ENET0_MDC_LSIO_GPIO4_IO14 SC_P_ENET0_MDC 3
+#define SC_P_ENET0_REFCLK_125M_25M_CONN_ENET0_REFCLK_125M_25M SC_P_ENET0_REFCLK_125M_25M 0
+#define SC_P_ENET0_REFCLK_125M_25M_CONN_ENET0_PPS SC_P_ENET0_REFCLK_125M_25M 1
+#define SC_P_ENET0_REFCLK_125M_25M_LSIO_GPIO4_IO15 SC_P_ENET0_REFCLK_125M_25M 3
+#define SC_P_ENET1_REFCLK_125M_25M_CONN_ENET1_REFCLK_125M_25M SC_P_ENET1_REFCLK_125M_25M 0
+#define SC_P_ENET1_REFCLK_125M_25M_CONN_ENET1_PPS SC_P_ENET1_REFCLK_125M_25M 1
+#define SC_P_ENET1_REFCLK_125M_25M_LSIO_GPIO4_IO16 SC_P_ENET1_REFCLK_125M_25M 3
+#define SC_P_ENET1_MDIO_CONN_ENET1_MDIO SC_P_ENET1_MDIO 0
+#define SC_P_ENET1_MDIO_DMA_I2C4_SDA SC_P_ENET1_MDIO 1
+#define SC_P_ENET1_MDIO_LSIO_GPIO4_IO17 SC_P_ENET1_MDIO 3
+#define SC_P_ENET1_MDC_CONN_ENET1_MDC SC_P_ENET1_MDC 0
+#define SC_P_ENET1_MDC_DMA_I2C4_SCL SC_P_ENET1_MDC 1
+#define SC_P_ENET1_MDC_LSIO_GPIO4_IO18 SC_P_ENET1_MDC 3
+#define SC_P_QSPI1A_SS0_B_LSIO_QSPI1A_SS0_B SC_P_QSPI1A_SS0_B 0
+#define SC_P_QSPI1A_SS0_B_LSIO_GPIO4_IO19 SC_P_QSPI1A_SS0_B 3
+#define SC_P_QSPI1A_SS1_B_LSIO_QSPI1A_SS1_B SC_P_QSPI1A_SS1_B 0
+#define SC_P_QSPI1A_SS1_B_LSIO_QSPI1A_SCLK2 SC_P_QSPI1A_SS1_B 1
+#define SC_P_QSPI1A_SS1_B_LSIO_GPIO4_IO20 SC_P_QSPI1A_SS1_B 3
+#define SC_P_QSPI1A_SCLK_LSIO_QSPI1A_SCLK SC_P_QSPI1A_SCLK 0
+#define SC_P_QSPI1A_SCLK_LSIO_GPIO4_IO21 SC_P_QSPI1A_SCLK 3
+#define SC_P_QSPI1A_DQS_LSIO_QSPI1A_DQS SC_P_QSPI1A_DQS 0
+#define SC_P_QSPI1A_DQS_LSIO_GPIO4_IO22 SC_P_QSPI1A_DQS 3
+#define SC_P_QSPI1A_DATA3_LSIO_QSPI1A_DATA3 SC_P_QSPI1A_DATA3 0
+#define SC_P_QSPI1A_DATA3_DMA_I2C1_SDA SC_P_QSPI1A_DATA3 1
+#define SC_P_QSPI1A_DATA3_CONN_USB_OTG1_OC SC_P_QSPI1A_DATA3 2
+#define SC_P_QSPI1A_DATA3_LSIO_GPIO4_IO23 SC_P_QSPI1A_DATA3 3
+#define SC_P_QSPI1A_DATA2_LSIO_QSPI1A_DATA2 SC_P_QSPI1A_DATA2 0
+#define SC_P_QSPI1A_DATA2_DMA_I2C1_SCL SC_P_QSPI1A_DATA2 1
+#define SC_P_QSPI1A_DATA2_CONN_USB_OTG2_PWR SC_P_QSPI1A_DATA2 2
+#define SC_P_QSPI1A_DATA2_LSIO_GPIO4_IO24 SC_P_QSPI1A_DATA2 3
+#define SC_P_QSPI1A_DATA1_LSIO_QSPI1A_DATA1 SC_P_QSPI1A_DATA1 0
+#define SC_P_QSPI1A_DATA1_DMA_I2C1_SDA SC_P_QSPI1A_DATA1 1
+#define SC_P_QSPI1A_DATA1_CONN_USB_OTG2_OC SC_P_QSPI1A_DATA1 2
+#define SC_P_QSPI1A_DATA1_LSIO_GPIO4_IO25 SC_P_QSPI1A_DATA1 3
+#define SC_P_QSPI1A_DATA0_LSIO_QSPI1A_DATA0 SC_P_QSPI1A_DATA0 0
+#define SC_P_QSPI1A_DATA0_LSIO_GPIO4_IO26 SC_P_QSPI1A_DATA0 3
+#define SC_P_QSPI0A_DATA0_LSIO_QSPI0A_DATA0 SC_P_QSPI0A_DATA0 0
+#define SC_P_QSPI0A_DATA1_LSIO_QSPI0A_DATA1 SC_P_QSPI0A_DATA1 0
+#define SC_P_QSPI0A_DATA2_LSIO_QSPI0A_DATA2 SC_P_QSPI0A_DATA2 0
+#define SC_P_QSPI0A_DATA3_LSIO_QSPI0A_DATA3 SC_P_QSPI0A_DATA3 0
+#define SC_P_QSPI0A_DQS_LSIO_QSPI0A_DQS SC_P_QSPI0A_DQS 0
+#define SC_P_QSPI0A_SS0_B_LSIO_QSPI0A_SS0_B SC_P_QSPI0A_SS0_B 0
+#define SC_P_QSPI0A_SS1_B_LSIO_QSPI0A_SS1_B SC_P_QSPI0A_SS1_B 0
+#define SC_P_QSPI0A_SS1_B_LSIO_QSPI0A_SCLK2 SC_P_QSPI0A_SS1_B 1
+#define SC_P_QSPI0A_SCLK_LSIO_QSPI0A_SCLK SC_P_QSPI0A_SCLK 0
+#define SC_P_QSPI0B_SCLK_LSIO_QSPI0B_SCLK SC_P_QSPI0B_SCLK 0
+#define SC_P_QSPI0B_DATA0_LSIO_QSPI0B_DATA0 SC_P_QSPI0B_DATA0 0
+#define SC_P_QSPI0B_DATA1_LSIO_QSPI0B_DATA1 SC_P_QSPI0B_DATA1 0
+#define SC_P_QSPI0B_DATA2_LSIO_QSPI0B_DATA2 SC_P_QSPI0B_DATA2 0
+#define SC_P_QSPI0B_DATA3_LSIO_QSPI0B_DATA3 SC_P_QSPI0B_DATA3 0
+#define SC_P_QSPI0B_DQS_LSIO_QSPI0B_DQS SC_P_QSPI0B_DQS 0
+#define SC_P_QSPI0B_SS0_B_LSIO_QSPI0B_SS0_B SC_P_QSPI0B_SS0_B 0
+#define SC_P_QSPI0B_SS1_B_LSIO_QSPI0B_SS1_B SC_P_QSPI0B_SS1_B 0
+#define SC_P_QSPI0B_SS1_B_LSIO_QSPI0B_SCLK2 SC_P_QSPI0B_SS1_B 1
+#define SC_P_PCIE_CTRL0_CLKREQ_B_HSIO_PCIE0_CLKREQ_B SC_P_PCIE_CTRL0_CLKREQ_B 0
+#define SC_P_PCIE_CTRL0_CLKREQ_B_LSIO_GPIO4_IO27 SC_P_PCIE_CTRL0_CLKREQ_B 3
+#define SC_P_PCIE_CTRL0_WAKE_B_HSIO_PCIE0_WAKE_B SC_P_PCIE_CTRL0_WAKE_B 0
+#define SC_P_PCIE_CTRL0_WAKE_B_LSIO_GPIO4_IO28 SC_P_PCIE_CTRL0_WAKE_B 3
+#define SC_P_PCIE_CTRL0_PERST_B_HSIO_PCIE0_PERST_B SC_P_PCIE_CTRL0_PERST_B 0
+#define SC_P_PCIE_CTRL0_PERST_B_LSIO_GPIO4_IO29 SC_P_PCIE_CTRL0_PERST_B 3
+#define SC_P_PCIE_CTRL1_CLKREQ_B_HSIO_PCIE1_CLKREQ_B SC_P_PCIE_CTRL1_CLKREQ_B 0
+#define SC_P_PCIE_CTRL1_CLKREQ_B_DMA_I2C1_SDA SC_P_PCIE_CTRL1_CLKREQ_B 1
+#define SC_P_PCIE_CTRL1_CLKREQ_B_CONN_USB_OTG2_OC SC_P_PCIE_CTRL1_CLKREQ_B 2
+#define SC_P_PCIE_CTRL1_CLKREQ_B_LSIO_GPIO4_IO30 SC_P_PCIE_CTRL1_CLKREQ_B 3
+#define SC_P_PCIE_CTRL1_WAKE_B_HSIO_PCIE1_WAKE_B SC_P_PCIE_CTRL1_WAKE_B 0
+#define SC_P_PCIE_CTRL1_WAKE_B_DMA_I2C1_SCL SC_P_PCIE_CTRL1_WAKE_B 1
+#define SC_P_PCIE_CTRL1_WAKE_B_CONN_USB_OTG2_PWR SC_P_PCIE_CTRL1_WAKE_B 2
+#define SC_P_PCIE_CTRL1_WAKE_B_LSIO_GPIO4_IO31 SC_P_PCIE_CTRL1_WAKE_B 3
+#define SC_P_PCIE_CTRL1_PERST_B_HSIO_PCIE1_PERST_B SC_P_PCIE_CTRL1_PERST_B 0
+#define SC_P_PCIE_CTRL1_PERST_B_DMA_I2C1_SCL SC_P_PCIE_CTRL1_PERST_B 1
+#define SC_P_PCIE_CTRL1_PERST_B_CONN_USB_OTG1_PWR SC_P_PCIE_CTRL1_PERST_B 2
+#define SC_P_PCIE_CTRL1_PERST_B_LSIO_GPIO5_IO00 SC_P_PCIE_CTRL1_PERST_B 3
+#define SC_P_USB_HSIC0_DATA_CONN_USB_HSIC0_DATA SC_P_USB_HSIC0_DATA 0
+#define SC_P_USB_HSIC0_DATA_DMA_I2C1_SDA SC_P_USB_HSIC0_DATA 1
+#define SC_P_USB_HSIC0_DATA_LSIO_GPIO5_IO01 SC_P_USB_HSIC0_DATA 3
+#define SC_P_USB_HSIC0_STROBE_CONN_USB_HSIC0_STROBE SC_P_USB_HSIC0_STROBE 0
+#define SC_P_USB_HSIC0_STROBE_DMA_I2C1_SCL SC_P_USB_HSIC0_STROBE 1
+#define SC_P_USB_HSIC0_STROBE_LSIO_GPIO5_IO02 SC_P_USB_HSIC0_STROBE 3
+#define SC_P_EMMC0_CLK_CONN_EMMC0_CLK SC_P_EMMC0_CLK 0
+#define SC_P_EMMC0_CLK_CONN_NAND_READY_B SC_P_EMMC0_CLK 1
+#define SC_P_EMMC0_CMD_CONN_EMMC0_CMD SC_P_EMMC0_CMD 0
+#define SC_P_EMMC0_CMD_CONN_NAND_DQS SC_P_EMMC0_CMD 1
+#define SC_P_EMMC0_CMD_AUD_MQS_R SC_P_EMMC0_CMD 2
+#define SC_P_EMMC0_CMD_LSIO_GPIO5_IO03 SC_P_EMMC0_CMD 3
+#define SC_P_EMMC0_DATA0_CONN_EMMC0_DATA0 SC_P_EMMC0_DATA0 0
+#define SC_P_EMMC0_DATA0_CONN_NAND_DATA00 SC_P_EMMC0_DATA0 1
+#define SC_P_EMMC0_DATA0_LSIO_GPIO5_IO04 SC_P_EMMC0_DATA0 3
+#define SC_P_EMMC0_DATA1_CONN_EMMC0_DATA1 SC_P_EMMC0_DATA1 0
+#define SC_P_EMMC0_DATA1_CONN_NAND_DATA01 SC_P_EMMC0_DATA1 1
+#define SC_P_EMMC0_DATA1_LSIO_GPIO5_IO05 SC_P_EMMC0_DATA1 3
+#define SC_P_EMMC0_DATA2_CONN_EMMC0_DATA2 SC_P_EMMC0_DATA2 0
+#define SC_P_EMMC0_DATA2_CONN_NAND_DATA02 SC_P_EMMC0_DATA2 1
+#define SC_P_EMMC0_DATA2_LSIO_GPIO5_IO06 SC_P_EMMC0_DATA2 3
+#define SC_P_EMMC0_DATA3_CONN_EMMC0_DATA3 SC_P_EMMC0_DATA3 0
+#define SC_P_EMMC0_DATA3_CONN_NAND_DATA03 SC_P_EMMC0_DATA3 1
+#define SC_P_EMMC0_DATA3_LSIO_GPIO5_IO07 SC_P_EMMC0_DATA3 3
+#define SC_P_EMMC0_DATA4_CONN_EMMC0_DATA4 SC_P_EMMC0_DATA4 0
+#define SC_P_EMMC0_DATA4_CONN_NAND_DATA04 SC_P_EMMC0_DATA4 1
+#define SC_P_EMMC0_DATA4_LSIO_GPIO5_IO08 SC_P_EMMC0_DATA4 3
+#define SC_P_EMMC0_DATA5_CONN_EMMC0_DATA5 SC_P_EMMC0_DATA5 0
+#define SC_P_EMMC0_DATA5_CONN_NAND_DATA05 SC_P_EMMC0_DATA5 1
+#define SC_P_EMMC0_DATA5_LSIO_GPIO5_IO09 SC_P_EMMC0_DATA5 3
+#define SC_P_EMMC0_DATA6_CONN_EMMC0_DATA6 SC_P_EMMC0_DATA6 0
+#define SC_P_EMMC0_DATA6_CONN_NAND_DATA06 SC_P_EMMC0_DATA6 1
+#define SC_P_EMMC0_DATA6_LSIO_GPIO5_IO10 SC_P_EMMC0_DATA6 3
+#define SC_P_EMMC0_DATA7_CONN_EMMC0_DATA7 SC_P_EMMC0_DATA7 0
+#define SC_P_EMMC0_DATA7_CONN_NAND_DATA07 SC_P_EMMC0_DATA7 1
+#define SC_P_EMMC0_DATA7_LSIO_GPIO5_IO11 SC_P_EMMC0_DATA7 3
+#define SC_P_EMMC0_STROBE_CONN_EMMC0_STROBE SC_P_EMMC0_STROBE 0
+#define SC_P_EMMC0_STROBE_CONN_NAND_CLE SC_P_EMMC0_STROBE 1
+#define SC_P_EMMC0_STROBE_LSIO_GPIO5_IO12 SC_P_EMMC0_STROBE 3
+#define SC_P_EMMC0_RESET_B_CONN_EMMC0_RESET_B SC_P_EMMC0_RESET_B 0
+#define SC_P_EMMC0_RESET_B_CONN_NAND_WP_B SC_P_EMMC0_RESET_B 1
+#define SC_P_EMMC0_RESET_B_CONN_USDHC1_VSELECT SC_P_EMMC0_RESET_B 2
+#define SC_P_EMMC0_RESET_B_LSIO_GPIO5_IO13 SC_P_EMMC0_RESET_B 3
+#define SC_P_USDHC1_CLK_CONN_USDHC1_CLK SC_P_USDHC1_CLK 0
+#define SC_P_USDHC1_CLK_AUD_MQS_R SC_P_USDHC1_CLK 1
+#define SC_P_USDHC1_CMD_CONN_USDHC1_CMD SC_P_USDHC1_CMD 0
+#define SC_P_USDHC1_CMD_AUD_MQS_L SC_P_USDHC1_CMD 1
+#define SC_P_USDHC1_CMD_LSIO_GPIO5_IO14 SC_P_USDHC1_CMD 3
+#define SC_P_USDHC1_DATA0_CONN_USDHC1_DATA0 SC_P_USDHC1_DATA0 0
+#define SC_P_USDHC1_DATA0_CONN_NAND_RE_N SC_P_USDHC1_DATA0 1
+#define SC_P_USDHC1_DATA0_LSIO_GPIO5_IO15 SC_P_USDHC1_DATA0 3
+#define SC_P_USDHC1_DATA1_CONN_USDHC1_DATA1 SC_P_USDHC1_DATA1 0
+#define SC_P_USDHC1_DATA1_CONN_NAND_RE_P SC_P_USDHC1_DATA1 1
+#define SC_P_USDHC1_DATA1_LSIO_GPIO5_IO16 SC_P_USDHC1_DATA1 3
+#define SC_P_USDHC1_DATA2_CONN_USDHC1_DATA2 SC_P_USDHC1_DATA2 0
+#define SC_P_USDHC1_DATA2_CONN_NAND_DQS_N SC_P_USDHC1_DATA2 1
+#define SC_P_USDHC1_DATA2_LSIO_GPIO5_IO17 SC_P_USDHC1_DATA2 3
+#define SC_P_USDHC1_DATA3_CONN_USDHC1_DATA3 SC_P_USDHC1_DATA3 0
+#define SC_P_USDHC1_DATA3_CONN_NAND_DQS_P SC_P_USDHC1_DATA3 1
+#define SC_P_USDHC1_DATA3_LSIO_GPIO5_IO18 SC_P_USDHC1_DATA3 3
+#define SC_P_USDHC1_DATA4_CONN_USDHC1_DATA4 SC_P_USDHC1_DATA4 0
+#define SC_P_USDHC1_DATA4_CONN_NAND_CE0_B SC_P_USDHC1_DATA4 1
+#define SC_P_USDHC1_DATA4_AUD_MQS_R SC_P_USDHC1_DATA4 2
+#define SC_P_USDHC1_DATA4_LSIO_GPIO5_IO19 SC_P_USDHC1_DATA4 3
+#define SC_P_USDHC1_DATA5_CONN_USDHC1_DATA5 SC_P_USDHC1_DATA5 0
+#define SC_P_USDHC1_DATA5_CONN_NAND_RE_B SC_P_USDHC1_DATA5 1
+#define SC_P_USDHC1_DATA5_AUD_MQS_L SC_P_USDHC1_DATA5 2
+#define SC_P_USDHC1_DATA5_LSIO_GPIO5_IO20 SC_P_USDHC1_DATA5 3
+#define SC_P_USDHC1_DATA6_CONN_USDHC1_DATA6 SC_P_USDHC1_DATA6 0
+#define SC_P_USDHC1_DATA6_CONN_NAND_WE_B SC_P_USDHC1_DATA6 1
+#define SC_P_USDHC1_DATA6_CONN_USDHC1_WP SC_P_USDHC1_DATA6 2
+#define SC_P_USDHC1_DATA6_LSIO_GPIO5_IO21 SC_P_USDHC1_DATA6 3
+#define SC_P_USDHC1_DATA7_CONN_USDHC1_DATA7 SC_P_USDHC1_DATA7 0
+#define SC_P_USDHC1_DATA7_CONN_NAND_ALE SC_P_USDHC1_DATA7 1
+#define SC_P_USDHC1_DATA7_CONN_USDHC1_CD_B SC_P_USDHC1_DATA7 2
+#define SC_P_USDHC1_DATA7_LSIO_GPIO5_IO22 SC_P_USDHC1_DATA7 3
+#define SC_P_USDHC1_STROBE_CONN_USDHC1_STROBE SC_P_USDHC1_STROBE 0
+#define SC_P_USDHC1_STROBE_CONN_NAND_CE1_B SC_P_USDHC1_STROBE 1
+#define SC_P_USDHC1_STROBE_CONN_USDHC1_RESET_B SC_P_USDHC1_STROBE 2
+#define SC_P_USDHC1_STROBE_LSIO_GPIO5_IO23 SC_P_USDHC1_STROBE 3
+#define SC_P_USDHC2_CLK_CONN_USDHC2_CLK SC_P_USDHC2_CLK 0
+#define SC_P_USDHC2_CLK_AUD_MQS_R SC_P_USDHC2_CLK 1
+#define SC_P_USDHC2_CLK_LSIO_GPIO5_IO24 SC_P_USDHC2_CLK 3
+#define SC_P_USDHC2_CMD_CONN_USDHC2_CMD SC_P_USDHC2_CMD 0
+#define SC_P_USDHC2_CMD_AUD_MQS_L SC_P_USDHC2_CMD 1
+#define SC_P_USDHC2_CMD_LSIO_GPIO5_IO25 SC_P_USDHC2_CMD 3
+#define SC_P_USDHC2_DATA0_CONN_USDHC2_DATA0 SC_P_USDHC2_DATA0 0
+#define SC_P_USDHC2_DATA0_DMA_UART4_RX SC_P_USDHC2_DATA0 1
+#define SC_P_USDHC2_DATA0_LSIO_GPIO5_IO26 SC_P_USDHC2_DATA0 3
+#define SC_P_USDHC2_DATA1_CONN_USDHC2_DATA1 SC_P_USDHC2_DATA1 0
+#define SC_P_USDHC2_DATA1_DMA_UART4_TX SC_P_USDHC2_DATA1 1
+#define SC_P_USDHC2_DATA1_LSIO_GPIO5_IO27 SC_P_USDHC2_DATA1 3
+#define SC_P_USDHC2_DATA2_CONN_USDHC2_DATA2 SC_P_USDHC2_DATA2 0
+#define SC_P_USDHC2_DATA2_DMA_UART4_CTS_B SC_P_USDHC2_DATA2 1
+#define SC_P_USDHC2_DATA2_LSIO_GPIO5_IO28 SC_P_USDHC2_DATA2 3
+#define SC_P_USDHC2_DATA3_CONN_USDHC2_DATA3 SC_P_USDHC2_DATA3 0
+#define SC_P_USDHC2_DATA3_DMA_UART4_RTS_B SC_P_USDHC2_DATA3 1
+#define SC_P_USDHC2_DATA3_LSIO_GPIO5_IO29 SC_P_USDHC2_DATA3 3
+#define SC_P_ENET0_RGMII_TXC_CONN_ENET0_RGMII_TXC SC_P_ENET0_RGMII_TXC 0
+#define SC_P_ENET0_RGMII_TXC_CONN_ENET0_RCLK50M_OUT SC_P_ENET0_RGMII_TXC 1
+#define SC_P_ENET0_RGMII_TXC_CONN_ENET0_RCLK50M_IN SC_P_ENET0_RGMII_TXC 2
+#define SC_P_ENET0_RGMII_TXC_LSIO_GPIO5_IO30 SC_P_ENET0_RGMII_TXC 3
+#define SC_P_ENET0_RGMII_TX_CTL_CONN_ENET0_RGMII_TX_CTL SC_P_ENET0_RGMII_TX_CTL 0
+#define SC_P_ENET0_RGMII_TX_CTL_LSIO_GPIO5_IO31 SC_P_ENET0_RGMII_TX_CTL 3
+#define SC_P_ENET0_RGMII_TXD0_CONN_ENET0_RGMII_TXD0 SC_P_ENET0_RGMII_TXD0 0
+#define SC_P_ENET0_RGMII_TXD0_LSIO_GPIO6_IO00 SC_P_ENET0_RGMII_TXD0 3
+#define SC_P_ENET0_RGMII_TXD1_CONN_ENET0_RGMII_TXD1 SC_P_ENET0_RGMII_TXD1 0
+#define SC_P_ENET0_RGMII_TXD1_LSIO_GPIO6_IO01 SC_P_ENET0_RGMII_TXD1 3
+#define SC_P_ENET0_RGMII_TXD2_CONN_ENET0_RGMII_TXD2 SC_P_ENET0_RGMII_TXD2 0
+#define SC_P_ENET0_RGMII_TXD2_DMA_UART3_TX SC_P_ENET0_RGMII_TXD2 1
+#define SC_P_ENET0_RGMII_TXD2_VPU_TSI_S1_VID SC_P_ENET0_RGMII_TXD2 2
+#define SC_P_ENET0_RGMII_TXD2_LSIO_GPIO6_IO02 SC_P_ENET0_RGMII_TXD2 3
+#define SC_P_ENET0_RGMII_TXD3_CONN_ENET0_RGMII_TXD3 SC_P_ENET0_RGMII_TXD3 0
+#define SC_P_ENET0_RGMII_TXD3_DMA_UART3_RTS_B SC_P_ENET0_RGMII_TXD3 1
+#define SC_P_ENET0_RGMII_TXD3_VPU_TSI_S1_SYNC SC_P_ENET0_RGMII_TXD3 2
+#define SC_P_ENET0_RGMII_TXD3_LSIO_GPIO6_IO03 SC_P_ENET0_RGMII_TXD3 3
+#define SC_P_ENET0_RGMII_RXC_CONN_ENET0_RGMII_RXC SC_P_ENET0_RGMII_RXC 0
+#define SC_P_ENET0_RGMII_RXC_DMA_UART3_CTS_B SC_P_ENET0_RGMII_RXC 1
+#define SC_P_ENET0_RGMII_RXC_VPU_TSI_S1_DATA SC_P_ENET0_RGMII_RXC 2
+#define SC_P_ENET0_RGMII_RXC_LSIO_GPIO6_IO04 SC_P_ENET0_RGMII_RXC 3
+#define SC_P_ENET0_RGMII_RX_CTL_CONN_ENET0_RGMII_RX_CTL SC_P_ENET0_RGMII_RX_CTL 0
+#define SC_P_ENET0_RGMII_RX_CTL_VPU_TSI_S0_VID SC_P_ENET0_RGMII_RX_CTL 2
+#define SC_P_ENET0_RGMII_RX_CTL_LSIO_GPIO6_IO05 SC_P_ENET0_RGMII_RX_CTL 3
+#define SC_P_ENET0_RGMII_RXD0_CONN_ENET0_RGMII_RXD0 SC_P_ENET0_RGMII_RXD0 0
+#define SC_P_ENET0_RGMII_RXD0_VPU_TSI_S0_SYNC SC_P_ENET0_RGMII_RXD0 2
+#define SC_P_ENET0_RGMII_RXD0_LSIO_GPIO6_IO06 SC_P_ENET0_RGMII_RXD0 3
+#define SC_P_ENET0_RGMII_RXD1_CONN_ENET0_RGMII_RXD1 SC_P_ENET0_RGMII_RXD1 0
+#define SC_P_ENET0_RGMII_RXD1_VPU_TSI_S0_DATA SC_P_ENET0_RGMII_RXD1 2
+#define SC_P_ENET0_RGMII_RXD1_LSIO_GPIO6_IO07 SC_P_ENET0_RGMII_RXD1 3
+#define SC_P_ENET0_RGMII_RXD2_CONN_ENET0_RGMII_RXD2 SC_P_ENET0_RGMII_RXD2 0
+#define SC_P_ENET0_RGMII_RXD2_CONN_ENET0_RMII_RX_ER SC_P_ENET0_RGMII_RXD2 1
+#define SC_P_ENET0_RGMII_RXD2_VPU_TSI_S0_CLK SC_P_ENET0_RGMII_RXD2 2
+#define SC_P_ENET0_RGMII_RXD2_LSIO_GPIO6_IO08 SC_P_ENET0_RGMII_RXD2 3
+#define SC_P_ENET0_RGMII_RXD3_CONN_ENET0_RGMII_RXD3 SC_P_ENET0_RGMII_RXD3 0
+#define SC_P_ENET0_RGMII_RXD3_DMA_UART3_RX SC_P_ENET0_RGMII_RXD3 1
+#define SC_P_ENET0_RGMII_RXD3_VPU_TSI_S1_CLK SC_P_ENET0_RGMII_RXD3 2
+#define SC_P_ENET0_RGMII_RXD3_LSIO_GPIO6_IO09 SC_P_ENET0_RGMII_RXD3 3
+#define SC_P_ENET1_RGMII_TXC_CONN_ENET1_RGMII_TXC SC_P_ENET1_RGMII_TXC 0
+#define SC_P_ENET1_RGMII_TXC_CONN_ENET1_RCLK50M_OUT SC_P_ENET1_RGMII_TXC 1
+#define SC_P_ENET1_RGMII_TXC_CONN_ENET1_RCLK50M_IN SC_P_ENET1_RGMII_TXC 2
+#define SC_P_ENET1_RGMII_TXC_LSIO_GPIO6_IO10 SC_P_ENET1_RGMII_TXC 3
+#define SC_P_ENET1_RGMII_TX_CTL_CONN_ENET1_RGMII_TX_CTL SC_P_ENET1_RGMII_TX_CTL 0
+#define SC_P_ENET1_RGMII_TX_CTL_LSIO_GPIO6_IO11 SC_P_ENET1_RGMII_TX_CTL 3
+#define SC_P_ENET1_RGMII_TXD0_CONN_ENET1_RGMII_TXD0 SC_P_ENET1_RGMII_TXD0 0
+#define SC_P_ENET1_RGMII_TXD0_LSIO_GPIO6_IO12 SC_P_ENET1_RGMII_TXD0 3
+#define SC_P_ENET1_RGMII_TXD1_CONN_ENET1_RGMII_TXD1 SC_P_ENET1_RGMII_TXD1 0
+#define SC_P_ENET1_RGMII_TXD1_LSIO_GPIO6_IO13 SC_P_ENET1_RGMII_TXD1 3
+#define SC_P_ENET1_RGMII_TXD2_CONN_ENET1_RGMII_TXD2 SC_P_ENET1_RGMII_TXD2 0
+#define SC_P_ENET1_RGMII_TXD2_DMA_UART3_TX SC_P_ENET1_RGMII_TXD2 1
+#define SC_P_ENET1_RGMII_TXD2_VPU_TSI_S1_VID SC_P_ENET1_RGMII_TXD2 2
+#define SC_P_ENET1_RGMII_TXD2_LSIO_GPIO6_IO14 SC_P_ENET1_RGMII_TXD2 3
+#define SC_P_ENET1_RGMII_TXD3_CONN_ENET1_RGMII_TXD3 SC_P_ENET1_RGMII_TXD3 0
+#define SC_P_ENET1_RGMII_TXD3_DMA_UART3_RTS_B SC_P_ENET1_RGMII_TXD3 1
+#define SC_P_ENET1_RGMII_TXD3_VPU_TSI_S1_SYNC SC_P_ENET1_RGMII_TXD3 2
+#define SC_P_ENET1_RGMII_TXD3_LSIO_GPIO6_IO15 SC_P_ENET1_RGMII_TXD3 3
+#define SC_P_ENET1_RGMII_RXC_CONN_ENET1_RGMII_RXC SC_P_ENET1_RGMII_RXC 0
+#define SC_P_ENET1_RGMII_RXC_DMA_UART3_CTS_B SC_P_ENET1_RGMII_RXC 1
+#define SC_P_ENET1_RGMII_RXC_VPU_TSI_S1_DATA SC_P_ENET1_RGMII_RXC 2
+#define SC_P_ENET1_RGMII_RXC_LSIO_GPIO6_IO16 SC_P_ENET1_RGMII_RXC 3
+#define SC_P_ENET1_RGMII_RX_CTL_CONN_ENET1_RGMII_RX_CTL SC_P_ENET1_RGMII_RX_CTL 0
+#define SC_P_ENET1_RGMII_RX_CTL_VPU_TSI_S0_VID SC_P_ENET1_RGMII_RX_CTL 2
+#define SC_P_ENET1_RGMII_RX_CTL_LSIO_GPIO6_IO17 SC_P_ENET1_RGMII_RX_CTL 3
+#define SC_P_ENET1_RGMII_RXD0_CONN_ENET1_RGMII_RXD0 SC_P_ENET1_RGMII_RXD0 0
+#define SC_P_ENET1_RGMII_RXD0_VPU_TSI_S0_SYNC SC_P_ENET1_RGMII_RXD0 2
+#define SC_P_ENET1_RGMII_RXD0_LSIO_GPIO6_IO18 SC_P_ENET1_RGMII_RXD0 3
+#define SC_P_ENET1_RGMII_RXD1_CONN_ENET1_RGMII_RXD1 SC_P_ENET1_RGMII_RXD1 0
+#define SC_P_ENET1_RGMII_RXD1_VPU_TSI_S0_DATA SC_P_ENET1_RGMII_RXD1 2
+#define SC_P_ENET1_RGMII_RXD1_LSIO_GPIO6_IO19 SC_P_ENET1_RGMII_RXD1 3
+#define SC_P_ENET1_RGMII_RXD2_CONN_ENET1_RGMII_RXD2 SC_P_ENET1_RGMII_RXD2 0
+#define SC_P_ENET1_RGMII_RXD2_CONN_ENET1_RMII_RX_ER SC_P_ENET1_RGMII_RXD2 1
+#define SC_P_ENET1_RGMII_RXD2_VPU_TSI_S0_CLK SC_P_ENET1_RGMII_RXD2 2
+#define SC_P_ENET1_RGMII_RXD2_LSIO_GPIO6_IO20 SC_P_ENET1_RGMII_RXD2 3
+#define SC_P_ENET1_RGMII_RXD3_CONN_ENET1_RGMII_RXD3 SC_P_ENET1_RGMII_RXD3 0
+#define SC_P_ENET1_RGMII_RXD3_DMA_UART3_RX SC_P_ENET1_RGMII_RXD3 1
+#define SC_P_ENET1_RGMII_RXD3_VPU_TSI_S1_CLK SC_P_ENET1_RGMII_RXD3 2
+#define SC_P_ENET1_RGMII_RXD3_LSIO_GPIO6_IO21 SC_P_ENET1_RGMII_RXD3 3
+/*@}*/
+
+/*!
+ * @name Fake Pad Mux Definitions
+ * format: name padid 0
+ */
+/*@{*/
+#define SC_P_COMP_CTL_GPIO_1V8_3V3_SIM_PAD SC_P_COMP_CTL_GPIO_1V8_3V3_SIM 0
+#define SC_P_COMP_CTL_GPIO_1V8_3V3_GPIOLH_PAD SC_P_COMP_CTL_GPIO_1V8_3V3_GPIOLH 0
+#define SC_P_COMP_CTL_GPIO_1V8_3V3_LVDSGPIO_PAD SC_P_COMP_CTL_GPIO_1V8_3V3_LVDSGPIO 0
+#define SC_P_COMP_CTL_GPIO_1V8_3V3_MIPIDSIGPIO_PAD SC_P_COMP_CTL_GPIO_1V8_3V3_MIPIDSIGPIO 0
+#define SC_P_COMP_CTL_GPIO_3V3_HDMIGPIO_PAD SC_P_COMP_CTL_GPIO_3V3_HDMIGPIO 0
+#define SC_P_COMP_CTL_GPIO_1V8_3V3_GPIORHB_PAD SC_P_COMP_CTL_GPIO_1V8_3V3_GPIORHB 0
+#define SC_P_COMP_CTL_GPIO_1V8_3V3_GPIORHC_PAD SC_P_COMP_CTL_GPIO_1V8_3V3_GPIORHC 0
+#define SC_P_COMP_CTL_GPIO_1V8_3V3_GPIORHT_PAD SC_P_COMP_CTL_GPIO_1V8_3V3_GPIORHT 0
+#define SC_P_COMP_CTL_GPIO_1V8_3V3_GPIOLHT_PAD SC_P_COMP_CTL_GPIO_1V8_3V3_GPIOLHT 0
+#define SC_P_COMP_CTL_GPIO_1V8_3V3_GPIOTHR_PAD SC_P_COMP_CTL_GPIO_1V8_3V3_GPIOTHR 0
+#define SC_P_COMP_CTL_GPIO_3V3_USB3IO_PAD SC_P_COMP_CTL_GPIO_3V3_USB3IO 0
+#define SC_P_COMP_CTL_GPIO_1V8_3V3_VSELSEP_PAD SC_P_COMP_CTL_GPIO_1V8_3V3_VSELSEP 0
+#define SC_P_COMP_CTL_GPIO_1V8_3V3_GPIOCT_PAD SC_P_COMP_CTL_GPIO_1V8_3V3_GPIOCT 0
+#define SC_P_COMP_CTL_GPIO_1V8_3V3_QSPI1_PAD SC_P_COMP_CTL_GPIO_1V8_3V3_QSPI1 0
+#define SC_P_COMP_CTL_GPIO_1V8_3V3_QSPI0_PAD SC_P_COMP_CTL_GPIO_1V8_3V3_QSPI0 0
+#define SC_P_COMP_CTL_GPIO_1V8_3V3_PCIESEP_PAD SC_P_COMP_CTL_GPIO_1V8_3V3_PCIESEP 0
+#define SC_P_COMP_CTL_GPIO_1V8_3V3_SD1FIX_PAD SC_P_COMP_CTL_GPIO_1V8_3V3_SD1FIX 0
+#define SC_P_COMP_CTL_GPIO_1V8_3V3_VSEL2_PAD SC_P_COMP_CTL_GPIO_1V8_3V3_VSEL2 0
+#define SC_P_COMP_CTL_GPIO_1V8_3V3_VSEL3_PAD SC_P_COMP_CTL_GPIO_1V8_3V3_VSEL3 0
+#define SC_P_COMP_CTL_GPIO_1V8_3V3_ENET_ENETB_PAD SC_P_COMP_CTL_GPIO_1V8_3V3_ENET_ENETB 0
+#define SC_P_COMP_CTL_GPIO_1V8_3V3_ENET_ENETA_PAD SC_P_COMP_CTL_GPIO_1V8_3V3_ENET_ENETA 0
+/*@}*/
+
+#endif /* SC_PADS_H */
diff --git a/include/dt-bindings/pinctrl/pads-imx8qxp.h b/include/dt-bindings/pinctrl/pads-imx8qxp.h
new file mode 100644
index 000000000000..5fc77a03c21c
--- /dev/null
+++ b/include/dt-bindings/pinctrl/pads-imx8qxp.h
@@ -0,0 +1,793 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017-2019 NXP
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+/*!
+ * Header file used to configure SoC pad list.
+ */
+
+#ifndef SC_PADS_H
+#define SC_PADS_H
+
+/* Includes */
+
+/* Defines */
+
+/*!
+ * @name Pad Definitions
+ */
+/*@{*/
+#define SC_P_PCIE_CTRL0_PERST_B 0 /* HSIO.PCIE0.PERST_B, LSIO.GPIO4.IO00 */
+#define SC_P_PCIE_CTRL0_CLKREQ_B 1 /* HSIO.PCIE0.CLKREQ_B, LSIO.GPIO4.IO01 */
+#define SC_P_PCIE_CTRL0_WAKE_B 2 /* HSIO.PCIE0.WAKE_B, LSIO.GPIO4.IO02 */
+#define SC_P_COMP_CTL_GPIO_1V8_3V3_PCIESEP 3 /* */
+#define SC_P_USB_SS3_TC0 4 /* ADMA.I2C1.SCL, CONN.USB_OTG1.PWR, CONN.USB_OTG2.PWR, LSIO.GPIO4.IO03 */
+#define SC_P_USB_SS3_TC1 5 /* ADMA.I2C1.SCL, CONN.USB_OTG2.PWR, LSIO.GPIO4.IO04 */
+#define SC_P_USB_SS3_TC2 6 /* ADMA.I2C1.SDA, CONN.USB_OTG1.OC, CONN.USB_OTG2.OC, LSIO.GPIO4.IO05 */
+#define SC_P_USB_SS3_TC3 7 /* ADMA.I2C1.SDA, CONN.USB_OTG2.OC, LSIO.GPIO4.IO06 */
+#define SC_P_COMP_CTL_GPIO_3V3_USB3IO 8 /* */
+#define SC_P_EMMC0_CLK 9 /* CONN.EMMC0.CLK, CONN.NAND.READY_B, LSIO.GPIO4.IO07 */
+#define SC_P_EMMC0_CMD 10 /* CONN.EMMC0.CMD, CONN.NAND.DQS, LSIO.GPIO4.IO08 */
+#define SC_P_EMMC0_DATA0 11 /* CONN.EMMC0.DATA0, CONN.NAND.DATA00, LSIO.GPIO4.IO09 */
+#define SC_P_EMMC0_DATA1 12 /* CONN.EMMC0.DATA1, CONN.NAND.DATA01, LSIO.GPIO4.IO10 */
+#define SC_P_EMMC0_DATA2 13 /* CONN.EMMC0.DATA2, CONN.NAND.DATA02, LSIO.GPIO4.IO11 */
+#define SC_P_EMMC0_DATA3 14 /* CONN.EMMC0.DATA3, CONN.NAND.DATA03, LSIO.GPIO4.IO12 */
+#define SC_P_COMP_CTL_GPIO_1V8_3V3_SD1FIX0 15 /* */
+#define SC_P_EMMC0_DATA4 16 /* CONN.EMMC0.DATA4, CONN.NAND.DATA04, CONN.EMMC0.WP, LSIO.GPIO4.IO13 */
+#define SC_P_EMMC0_DATA5 17 /* CONN.EMMC0.DATA5, CONN.NAND.DATA05, CONN.EMMC0.VSELECT, LSIO.GPIO4.IO14 */
+#define SC_P_EMMC0_DATA6 18 /* CONN.EMMC0.DATA6, CONN.NAND.DATA06, CONN.MLB.CLK, LSIO.GPIO4.IO15 */
+#define SC_P_EMMC0_DATA7 19 /* CONN.EMMC0.DATA7, CONN.NAND.DATA07, CONN.MLB.SIG, LSIO.GPIO4.IO16 */
+#define SC_P_EMMC0_STROBE 20 /* CONN.EMMC0.STROBE, CONN.NAND.CLE, CONN.MLB.DATA, LSIO.GPIO4.IO17 */
+#define SC_P_EMMC0_RESET_B 21 /* CONN.EMMC0.RESET_B, CONN.NAND.WP_B, LSIO.GPIO4.IO18 */
+#define SC_P_COMP_CTL_GPIO_1V8_3V3_SD1FIX1 22 /* */
+#define SC_P_USDHC1_RESET_B 23 /* CONN.USDHC1.RESET_B, CONN.NAND.RE_N, ADMA.SPI2.SCK, LSIO.GPIO4.IO19 */
+#define SC_P_USDHC1_VSELECT 24 /* CONN.USDHC1.VSELECT, CONN.NAND.RE_P, ADMA.SPI2.SDO, CONN.NAND.RE_B, LSIO.GPIO4.IO20 */
+#define SC_P_CTL_NAND_RE_P_N 25 /* */
+#define SC_P_USDHC1_WP 26 /* CONN.USDHC1.WP, CONN.NAND.DQS_N, ADMA.SPI2.SDI, LSIO.GPIO4.IO21 */
+#define SC_P_USDHC1_CD_B 27 /* CONN.USDHC1.CD_B, CONN.NAND.DQS_P, ADMA.SPI2.CS0, CONN.NAND.DQS, LSIO.GPIO4.IO22 */
+#define SC_P_CTL_NAND_DQS_P_N 28 /* */
+#define SC_P_COMP_CTL_GPIO_1V8_3V3_VSELSEP 29 /* */
+#define SC_P_USDHC1_CLK 30 /* CONN.USDHC1.CLK, ADMA.UART3.RX, LSIO.GPIO4.IO23 */
+#define SC_P_USDHC1_CMD 31 /* CONN.USDHC1.CMD, CONN.NAND.CE0_B, ADMA.MQS.R, LSIO.GPIO4.IO24 */
+#define SC_P_USDHC1_DATA0 32 /* CONN.USDHC1.DATA0, CONN.NAND.CE1_B, ADMA.MQS.L, LSIO.GPIO4.IO25 */
+#define SC_P_USDHC1_DATA1 33 /* CONN.USDHC1.DATA1, CONN.NAND.RE_B, ADMA.UART3.TX, LSIO.GPIO4.IO26 */
+#define SC_P_USDHC1_DATA2 34 /* CONN.USDHC1.DATA2, CONN.NAND.WE_B, ADMA.UART3.CTS_B, LSIO.GPIO4.IO27 */
+#define SC_P_USDHC1_DATA3 35 /* CONN.USDHC1.DATA3, CONN.NAND.ALE, ADMA.UART3.RTS_B, LSIO.GPIO4.IO28 */
+#define SC_P_COMP_CTL_GPIO_1V8_3V3_VSEL3 36 /* */
+#define SC_P_ENET0_RGMII_TXC 37 /* CONN.ENET0.RGMII_TXC, CONN.ENET0.RCLK50M_OUT, CONN.ENET0.RCLK50M_IN, CONN.NAND.CE1_B, LSIO.GPIO4.IO29 */
+#define SC_P_ENET0_RGMII_TX_CTL 38 /* CONN.ENET0.RGMII_TX_CTL, CONN.USDHC1.RESET_B, LSIO.GPIO4.IO30 */
+#define SC_P_ENET0_RGMII_TXD0 39 /* CONN.ENET0.RGMII_TXD0, CONN.USDHC1.VSELECT, LSIO.GPIO4.IO31 */
+#define SC_P_ENET0_RGMII_TXD1 40 /* CONN.ENET0.RGMII_TXD1, CONN.USDHC1.WP, LSIO.GPIO5.IO00 */
+#define SC_P_ENET0_RGMII_TXD2 41 /* CONN.ENET0.RGMII_TXD2, CONN.MLB.CLK, CONN.NAND.CE0_B, CONN.USDHC1.CD_B, LSIO.GPIO5.IO01 */
+#define SC_P_ENET0_RGMII_TXD3 42 /* CONN.ENET0.RGMII_TXD3, CONN.MLB.SIG, CONN.NAND.RE_B, LSIO.GPIO5.IO02 */
+#define SC_P_COMP_CTL_GPIO_1V8_3V3_ENET_ENETB0 43 /* */
+#define SC_P_ENET0_RGMII_RXC 44 /* CONN.ENET0.RGMII_RXC, CONN.MLB.DATA, CONN.NAND.WE_B, CONN.USDHC1.CLK, LSIO.GPIO5.IO03 */
+#define SC_P_ENET0_RGMII_RX_CTL 45 /* CONN.ENET0.RGMII_RX_CTL, CONN.USDHC1.CMD, LSIO.GPIO5.IO04 */
+#define SC_P_ENET0_RGMII_RXD0 46 /* CONN.ENET0.RGMII_RXD0, CONN.USDHC1.DATA0, LSIO.GPIO5.IO05 */
+#define SC_P_ENET0_RGMII_RXD1 47 /* CONN.ENET0.RGMII_RXD1, CONN.USDHC1.DATA1, LSIO.GPIO5.IO06 */
+#define SC_P_ENET0_RGMII_RXD2 48 /* CONN.ENET0.RGMII_RXD2, CONN.ENET0.RMII_RX_ER, CONN.USDHC1.DATA2, LSIO.GPIO5.IO07 */
+#define SC_P_ENET0_RGMII_RXD3 49 /* CONN.ENET0.RGMII_RXD3, CONN.NAND.ALE, CONN.USDHC1.DATA3, LSIO.GPIO5.IO08 */
+#define SC_P_COMP_CTL_GPIO_1V8_3V3_ENET_ENETB1 50 /* */
+#define SC_P_ENET0_REFCLK_125M_25M 51 /* CONN.ENET0.REFCLK_125M_25M, CONN.ENET0.PPS, CONN.ENET1.PPS, LSIO.GPIO5.IO09 */
+#define SC_P_ENET0_MDIO 52 /* CONN.ENET0.MDIO, ADMA.I2C3.SDA, CONN.ENET1.MDIO, LSIO.GPIO5.IO10 */
+#define SC_P_ENET0_MDC 53 /* CONN.ENET0.MDC, ADMA.I2C3.SCL, CONN.ENET1.MDC, LSIO.GPIO5.IO11 */
+#define SC_P_COMP_CTL_GPIO_1V8_3V3_GPIOCT 54 /* */
+#define SC_P_ESAI0_FSR 55 /* ADMA.ESAI0.FSR, CONN.ENET1.RCLK50M_OUT, ADMA.LCDIF.D00, CONN.ENET1.RGMII_TXC, CONN.ENET1.RCLK50M_IN */
+#define SC_P_ESAI0_FST 56 /* ADMA.ESAI0.FST, CONN.MLB.CLK, ADMA.LCDIF.D01, CONN.ENET1.RGMII_TXD2, LSIO.GPIO0.IO01 */
+#define SC_P_ESAI0_SCKR 57 /* ADMA.ESAI0.SCKR, ADMA.LCDIF.D02, CONN.ENET1.RGMII_TX_CTL, LSIO.GPIO0.IO02 */
+#define SC_P_ESAI0_SCKT 58 /* ADMA.ESAI0.SCKT, CONN.MLB.SIG, ADMA.LCDIF.D03, CONN.ENET1.RGMII_TXD3, LSIO.GPIO0.IO03 */
+#define SC_P_ESAI0_TX0 59 /* ADMA.ESAI0.TX0, CONN.MLB.DATA, ADMA.LCDIF.D04, CONN.ENET1.RGMII_RXC, LSIO.GPIO0.IO04 */
+#define SC_P_ESAI0_TX1 60 /* ADMA.ESAI0.TX1, ADMA.LCDIF.D05, CONN.ENET1.RGMII_RXD3, LSIO.GPIO0.IO05 */
+#define SC_P_ESAI0_TX2_RX3 61 /* ADMA.ESAI0.TX2_RX3, CONN.ENET1.RMII_RX_ER, ADMA.LCDIF.D06, CONN.ENET1.RGMII_RXD2, LSIO.GPIO0.IO06 */
+#define SC_P_ESAI0_TX3_RX2 62 /* ADMA.ESAI0.TX3_RX2, ADMA.LCDIF.D07, CONN.ENET1.RGMII_RXD1, LSIO.GPIO0.IO07 */
+#define SC_P_ESAI0_TX4_RX1 63 /* ADMA.ESAI0.TX4_RX1, ADMA.LCDIF.D08, CONN.ENET1.RGMII_TXD0, LSIO.GPIO0.IO08 */
+#define SC_P_ESAI0_TX5_RX0 64 /* ADMA.ESAI0.TX5_RX0, ADMA.LCDIF.D09, CONN.ENET1.RGMII_TXD1, LSIO.GPIO0.IO09 */
+#define SC_P_SPDIF0_RX 65 /* ADMA.SPDIF0.RX, ADMA.MQS.R, ADMA.LCDIF.D10, CONN.ENET1.RGMII_RXD0, LSIO.GPIO0.IO10 */
+#define SC_P_SPDIF0_TX 66 /* ADMA.SPDIF0.TX, ADMA.MQS.L, ADMA.LCDIF.D11, CONN.ENET1.RGMII_RX_CTL, LSIO.GPIO0.IO11 */
+#define SC_P_SPDIF0_EXT_CLK 67 /* ADMA.SPDIF0.EXT_CLK, ADMA.LCDIF.D12, CONN.ENET1.REFCLK_125M_25M, LSIO.GPIO0.IO12 */
+#define SC_P_COMP_CTL_GPIO_1V8_3V3_GPIORHB 68 /* */
+#define SC_P_SPI3_SCK 69 /* ADMA.SPI3.SCK, ADMA.LCDIF.D13, LSIO.GPIO0.IO13 */
+#define SC_P_SPI3_SDO 70 /* ADMA.SPI3.SDO, ADMA.LCDIF.D14, LSIO.GPIO0.IO14 */
+#define SC_P_SPI3_SDI 71 /* ADMA.SPI3.SDI, ADMA.LCDIF.D15, LSIO.GPIO0.IO15 */
+#define SC_P_SPI3_CS0 72 /* ADMA.SPI3.CS0, ADMA.ACM.MCLK_OUT1, ADMA.LCDIF.HSYNC, LSIO.GPIO0.IO16 */
+#define SC_P_SPI3_CS1 73 /* ADMA.SPI3.CS1, ADMA.I2C3.SCL, ADMA.LCDIF.RESET, ADMA.SPI2.CS0, ADMA.LCDIF.D16 */
+#define SC_P_MCLK_IN1 74 /* ADMA.ACM.MCLK_IN1, ADMA.I2C3.SDA, ADMA.LCDIF.EN, ADMA.SPI2.SCK, ADMA.LCDIF.D17 */
+#define SC_P_MCLK_IN0 75 /* ADMA.ACM.MCLK_IN0, ADMA.ESAI0.RX_HF_CLK, ADMA.LCDIF.VSYNC, ADMA.SPI2.SDI, LSIO.GPIO0.IO19 */
+#define SC_P_MCLK_OUT0 76 /* ADMA.ACM.MCLK_OUT0, ADMA.ESAI0.TX_HF_CLK, ADMA.LCDIF.CLK, ADMA.SPI2.SDO, LSIO.GPIO0.IO20 */
+#define SC_P_UART1_TX 77 /* ADMA.UART1.TX, LSIO.PWM0.OUT, LSIO.GPT0.CAPTURE, LSIO.GPIO0.IO21 */
+#define SC_P_UART1_RX 78 /* ADMA.UART1.RX, LSIO.PWM1.OUT, LSIO.GPT0.COMPARE, LSIO.GPT1.CLK, LSIO.GPIO0.IO22 */
+#define SC_P_UART1_RTS_B 79 /* ADMA.UART1.RTS_B, LSIO.PWM2.OUT, ADMA.LCDIF.D16, LSIO.GPT1.CAPTURE, LSIO.GPT0.CLK */
+#define SC_P_UART1_CTS_B 80 /* ADMA.UART1.CTS_B, LSIO.PWM3.OUT, ADMA.LCDIF.D17, LSIO.GPT1.COMPARE, LSIO.GPIO0.IO24 */
+#define SC_P_COMP_CTL_GPIO_1V8_3V3_GPIORHK 81 /* */
+#define SC_P_SAI0_TXD 82 /* ADMA.SAI0.TXD, ADMA.SAI1.RXC, ADMA.SPI1.SDO, ADMA.LCDIF.D18, LSIO.GPIO0.IO25 */
+#define SC_P_SAI0_TXC 83 /* ADMA.SAI0.TXC, ADMA.SAI1.TXD, ADMA.SPI1.SDI, ADMA.LCDIF.D19, LSIO.GPIO0.IO26 */
+#define SC_P_SAI0_RXD 84 /* ADMA.SAI0.RXD, ADMA.SAI1.RXFS, ADMA.SPI1.CS0, ADMA.LCDIF.D20, LSIO.GPIO0.IO27 */
+#define SC_P_SAI0_TXFS 85 /* ADMA.SAI0.TXFS, ADMA.SPI2.CS1, ADMA.SPI1.SCK, LSIO.GPIO0.IO28 */
+#define SC_P_SAI1_RXD 86 /* ADMA.SAI1.RXD, ADMA.SAI0.RXFS, ADMA.SPI1.CS1, ADMA.LCDIF.D21, LSIO.GPIO0.IO29 */
+#define SC_P_SAI1_RXC 87 /* ADMA.SAI1.RXC, ADMA.SAI1.TXC, ADMA.LCDIF.D22, LSIO.GPIO0.IO30 */
+#define SC_P_SAI1_RXFS 88 /* ADMA.SAI1.RXFS, ADMA.SAI1.TXFS, ADMA.LCDIF.D23, LSIO.GPIO0.IO31 */
+#define SC_P_SPI2_CS0 89 /* ADMA.SPI2.CS0, LSIO.GPIO1.IO00 */
+#define SC_P_SPI2_SDO 90 /* ADMA.SPI2.SDO, LSIO.GPIO1.IO01 */
+#define SC_P_SPI2_SDI 91 /* ADMA.SPI2.SDI, LSIO.GPIO1.IO02 */
+#define SC_P_SPI2_SCK 92 /* ADMA.SPI2.SCK, LSIO.GPIO1.IO03 */
+#define SC_P_SPI0_SCK 93 /* ADMA.SPI0.SCK, ADMA.SAI0.TXC, M40.I2C0.SCL, M40.GPIO0.IO00, LSIO.GPIO1.IO04 */
+#define SC_P_SPI0_SDI 94 /* ADMA.SPI0.SDI, ADMA.SAI0.TXD, M40.TPM0.CH0, M40.GPIO0.IO02, LSIO.GPIO1.IO05 */
+#define SC_P_SPI0_SDO 95 /* ADMA.SPI0.SDO, ADMA.SAI0.TXFS, M40.I2C0.SDA, M40.GPIO0.IO01, LSIO.GPIO1.IO06 */
+#define SC_P_SPI0_CS1 96 /* ADMA.SPI0.CS1, ADMA.SAI0.RXC, ADMA.SAI1.TXD, ADMA.LCD_PWM0.OUT, LSIO.GPIO1.IO07 */
+#define SC_P_SPI0_CS0 97 /* ADMA.SPI0.CS0, ADMA.SAI0.RXD, M40.TPM0.CH1, M40.GPIO0.IO03, LSIO.GPIO1.IO08 */
+#define SC_P_COMP_CTL_GPIO_1V8_3V3_GPIORHT 98 /* */
+#define SC_P_ADC_IN1 99 /* ADMA.ADC.IN1, M40.I2C0.SDA, M40.GPIO0.IO01, LSIO.GPIO1.IO09 */
+#define SC_P_ADC_IN0 100 /* ADMA.ADC.IN0, M40.I2C0.SCL, M40.GPIO0.IO00, LSIO.GPIO1.IO10 */
+#define SC_P_ADC_IN3 101 /* ADMA.ADC.IN3, M40.UART0.TX, M40.GPIO0.IO03, ADMA.ACM.MCLK_OUT0, LSIO.GPIO1.IO11 */
+#define SC_P_ADC_IN2 102 /* ADMA.ADC.IN2, M40.UART0.RX, M40.GPIO0.IO02, ADMA.ACM.MCLK_IN0, LSIO.GPIO1.IO12 */
+#define SC_P_ADC_IN5 103 /* ADMA.ADC.IN5, M40.TPM0.CH1, M40.GPIO0.IO05, LSIO.GPIO1.IO13 */
+#define SC_P_ADC_IN4 104 /* ADMA.ADC.IN4, M40.TPM0.CH0, M40.GPIO0.IO04, LSIO.GPIO1.IO14 */
+#define SC_P_FLEXCAN0_RX 105 /* ADMA.FLEXCAN0.RX, ADMA.SAI2.RXC, ADMA.UART0.RTS_B, ADMA.SAI1.TXC, LSIO.GPIO1.IO15 */
+#define SC_P_FLEXCAN0_TX 106 /* ADMA.FLEXCAN0.TX, ADMA.SAI2.RXD, ADMA.UART0.CTS_B, ADMA.SAI1.TXFS, LSIO.GPIO1.IO16 */
+#define SC_P_FLEXCAN1_RX 107 /* ADMA.FLEXCAN1.RX, ADMA.SAI2.RXFS, ADMA.FTM.CH2, ADMA.SAI1.TXD, LSIO.GPIO1.IO17 */
+#define SC_P_FLEXCAN1_TX 108 /* ADMA.FLEXCAN1.TX, ADMA.SAI3.RXC, ADMA.DMA0.REQ_IN0, ADMA.SAI1.RXD, LSIO.GPIO1.IO18 */
+#define SC_P_FLEXCAN2_RX 109 /* ADMA.FLEXCAN2.RX, ADMA.SAI3.RXD, ADMA.UART3.RX, ADMA.SAI1.RXFS, LSIO.GPIO1.IO19 */
+#define SC_P_FLEXCAN2_TX 110 /* ADMA.FLEXCAN2.TX, ADMA.SAI3.RXFS, ADMA.UART3.TX, ADMA.SAI1.RXC, LSIO.GPIO1.IO20 */
+#define SC_P_UART0_RX 111 /* ADMA.UART0.RX, ADMA.MQS.R, ADMA.FLEXCAN0.RX, SCU.UART0.RX, LSIO.GPIO1.IO21 */
+#define SC_P_UART0_TX 112 /* ADMA.UART0.TX, ADMA.MQS.L, ADMA.FLEXCAN0.TX, SCU.UART0.TX, LSIO.GPIO1.IO22 */
+#define SC_P_UART2_TX 113 /* ADMA.UART2.TX, ADMA.FTM.CH1, ADMA.FLEXCAN1.TX, LSIO.GPIO1.IO23 */
+#define SC_P_UART2_RX 114 /* ADMA.UART2.RX, ADMA.FTM.CH0, ADMA.FLEXCAN1.RX, LSIO.GPIO1.IO24 */
+#define SC_P_COMP_CTL_GPIO_1V8_3V3_GPIOLH 115 /* */
+#define SC_P_MIPI_DSI0_I2C0_SCL 116 /* MIPI_DSI0.I2C0.SCL, MIPI_DSI1.GPIO0.IO02, LSIO.GPIO1.IO25 */
+#define SC_P_MIPI_DSI0_I2C0_SDA 117 /* MIPI_DSI0.I2C0.SDA, MIPI_DSI1.GPIO0.IO03, LSIO.GPIO1.IO26 */
+#define SC_P_MIPI_DSI0_GPIO0_00 118 /* MIPI_DSI0.GPIO0.IO00, ADMA.I2C1.SCL, MIPI_DSI0.PWM0.OUT, LSIO.GPIO1.IO27 */
+#define SC_P_MIPI_DSI0_GPIO0_01 119 /* MIPI_DSI0.GPIO0.IO01, ADMA.I2C1.SDA, LSIO.GPIO1.IO28 */
+#define SC_P_MIPI_DSI1_I2C0_SCL 120 /* MIPI_DSI1.I2C0.SCL, MIPI_DSI0.GPIO0.IO02, LSIO.GPIO1.IO29 */
+#define SC_P_MIPI_DSI1_I2C0_SDA 121 /* MIPI_DSI1.I2C0.SDA, MIPI_DSI0.GPIO0.IO03, LSIO.GPIO1.IO30 */
+#define SC_P_MIPI_DSI1_GPIO0_00 122 /* MIPI_DSI1.GPIO0.IO00, ADMA.I2C2.SCL, MIPI_DSI1.PWM0.OUT, LSIO.GPIO1.IO31 */
+#define SC_P_MIPI_DSI1_GPIO0_01 123 /* MIPI_DSI1.GPIO0.IO01, ADMA.I2C2.SDA, LSIO.GPIO2.IO00 */
+#define SC_P_COMP_CTL_GPIO_1V8_3V3_MIPIDSIGPIO 124 /* */
+#define SC_P_JTAG_TRST_B 125 /* SCU.JTAG.TRST_B, SCU.WDOG0.WDOG_OUT */
+#define SC_P_PMIC_I2C_SCL 126 /* SCU.PMIC_I2C.SCL, SCU.GPIO0.IOXX_PMIC_A35_ON, LSIO.GPIO2.IO01 */
+#define SC_P_PMIC_I2C_SDA 127 /* SCU.PMIC_I2C.SDA, SCU.GPIO0.IOXX_PMIC_GPU_ON, LSIO.GPIO2.IO02 */
+#define SC_P_PMIC_INT_B 128 /* SCU.DSC.PMIC_INT_B */
+#define SC_P_SCU_GPIO0_00 129 /* SCU.GPIO0.IO00, SCU.UART0.RX, M40.UART0.RX, ADMA.UART3.RX, LSIO.GPIO2.IO03 */
+#define SC_P_SCU_GPIO0_01 130 /* SCU.GPIO0.IO01, SCU.UART0.TX, M40.UART0.TX, ADMA.UART3.TX, SCU.WDOG0.WDOG_OUT */
+#define SC_P_SCU_PMIC_STANDBY 131 /* SCU.DSC.PMIC_STANDBY */
+#define SC_P_SCU_BOOT_MODE0 132 /* SCU.DSC.BOOT_MODE0 */
+#define SC_P_SCU_BOOT_MODE1 133 /* SCU.DSC.BOOT_MODE1 */
+#define SC_P_SCU_BOOT_MODE2 134 /* SCU.DSC.BOOT_MODE2, SCU.PMIC_I2C.SDA */
+#define SC_P_SCU_BOOT_MODE3 135 /* SCU.DSC.BOOT_MODE3, SCU.PMIC_I2C.SCL, SCU.DSC.RTC_CLOCK_OUTPUT_32K */
+#define SC_P_CSI_D00 136 /* CI_PI.D02, ADMA.SAI0.RXC */
+#define SC_P_CSI_D01 137 /* CI_PI.D03, ADMA.SAI0.RXD */
+#define SC_P_CSI_D02 138 /* CI_PI.D04, ADMA.SAI0.RXFS */
+#define SC_P_CSI_D03 139 /* CI_PI.D05, ADMA.SAI2.RXC */
+#define SC_P_CSI_D04 140 /* CI_PI.D06, ADMA.SAI2.RXD */
+#define SC_P_CSI_D05 141 /* CI_PI.D07, ADMA.SAI2.RXFS */
+#define SC_P_CSI_D06 142 /* CI_PI.D08, ADMA.SAI3.RXC */
+#define SC_P_CSI_D07 143 /* CI_PI.D09, ADMA.SAI3.RXD */
+#define SC_P_CSI_HSYNC 144 /* CI_PI.HSYNC, CI_PI.D00, ADMA.SAI3.RXFS */
+#define SC_P_CSI_VSYNC 145 /* CI_PI.VSYNC, CI_PI.D01 */
+#define SC_P_CSI_PCLK 146 /* CI_PI.PCLK, MIPI_CSI0.I2C0.SCL, ADMA.SPI1.SCK, LSIO.GPIO3.IO00 */
+#define SC_P_CSI_MCLK 147 /* CI_PI.MCLK, MIPI_CSI0.I2C0.SDA, ADMA.SPI1.SDO, LSIO.GPIO3.IO01 */
+#define SC_P_CSI_EN 148 /* CI_PI.EN, CI_PI.I2C.SCL, ADMA.I2C3.SCL, ADMA.SPI1.SDI, LSIO.GPIO3.IO02 */
+#define SC_P_CSI_RESET 149 /* CI_PI.RESET, CI_PI.I2C.SDA, ADMA.I2C3.SDA, ADMA.SPI1.CS0, LSIO.GPIO3.IO03 */
+#define SC_P_COMP_CTL_GPIO_1V8_3V3_GPIORHD 150 /* */
+#define SC_P_MIPI_CSI0_MCLK_OUT 151 /* MIPI_CSI0.ACM.MCLK_OUT, LSIO.GPIO3.IO04 */
+#define SC_P_MIPI_CSI0_I2C0_SCL 152 /* MIPI_CSI0.I2C0.SCL, MIPI_CSI0.GPIO0.IO02, LSIO.GPIO3.IO05 */
+#define SC_P_MIPI_CSI0_I2C0_SDA 153 /* MIPI_CSI0.I2C0.SDA, MIPI_CSI0.GPIO0.IO03, LSIO.GPIO3.IO06 */
+#define SC_P_MIPI_CSI0_GPIO0_01 154 /* MIPI_CSI0.GPIO0.IO01, ADMA.I2C0.SDA, LSIO.GPIO3.IO07 */
+#define SC_P_MIPI_CSI0_GPIO0_00 155 /* MIPI_CSI0.GPIO0.IO00, ADMA.I2C0.SCL, LSIO.GPIO3.IO08 */
+#define SC_P_QSPI0A_DATA0 156 /* LSIO.QSPI0A.DATA0, LSIO.GPIO3.IO09 */
+#define SC_P_QSPI0A_DATA1 157 /* LSIO.QSPI0A.DATA1, LSIO.GPIO3.IO10 */
+#define SC_P_QSPI0A_DATA2 158 /* LSIO.QSPI0A.DATA2, LSIO.GPIO3.IO11 */
+#define SC_P_QSPI0A_DATA3 159 /* LSIO.QSPI0A.DATA3, LSIO.GPIO3.IO12 */
+#define SC_P_QSPI0A_DQS 160 /* LSIO.QSPI0A.DQS, LSIO.GPIO3.IO13 */
+#define SC_P_QSPI0A_SS0_B 161 /* LSIO.QSPI0A.SS0_B, LSIO.GPIO3.IO14 */
+#define SC_P_QSPI0A_SS1_B 162 /* LSIO.QSPI0A.SS1_B, LSIO.GPIO3.IO15 */
+#define SC_P_QSPI0A_SCLK 163 /* LSIO.QSPI0A.SCLK, LSIO.GPIO3.IO16 */
+#define SC_P_COMP_CTL_GPIO_1V8_3V3_QSPI0A 164 /* */
+#define SC_P_QSPI0B_SCLK 165 /* LSIO.QSPI0B.SCLK, LSIO.QSPI1A.SCLK, LSIO.KPP0.COL0, LSIO.GPIO3.IO17 */
+#define SC_P_QSPI0B_DATA0 166 /* LSIO.QSPI0B.DATA0, LSIO.QSPI1A.DATA0, LSIO.KPP0.COL1, LSIO.GPIO3.IO18 */
+#define SC_P_QSPI0B_DATA1 167 /* LSIO.QSPI0B.DATA1, LSIO.QSPI1A.DATA1, LSIO.KPP0.COL2, LSIO.GPIO3.IO19 */
+#define SC_P_QSPI0B_DATA2 168 /* LSIO.QSPI0B.DATA2, LSIO.QSPI1A.DATA2, LSIO.KPP0.COL3, LSIO.GPIO3.IO20 */
+#define SC_P_QSPI0B_DATA3 169 /* LSIO.QSPI0B.DATA3, LSIO.QSPI1A.DATA3, LSIO.KPP0.ROW0, LSIO.GPIO3.IO21 */
+#define SC_P_QSPI0B_DQS 170 /* LSIO.QSPI0B.DQS, LSIO.QSPI1A.DQS, LSIO.KPP0.ROW1, LSIO.GPIO3.IO22 */
+#define SC_P_QSPI0B_SS0_B 171 /* LSIO.QSPI0B.SS0_B, LSIO.QSPI1A.SS0_B, LSIO.KPP0.ROW2, LSIO.GPIO3.IO23 */
+#define SC_P_QSPI0B_SS1_B 172 /* LSIO.QSPI0B.SS1_B, LSIO.QSPI1A.SS1_B, LSIO.KPP0.ROW3, LSIO.GPIO3.IO24 */
+#define SC_P_COMP_CTL_GPIO_1V8_3V3_QSPI0B 173 /* */
+/*@}*/
+
+/*!
+ * @name Pad Mux Definitions
+ * format: name padid padmux
+ */
+/*@{*/
+#define SC_P_PCIE_CTRL0_PERST_B_HSIO_PCIE0_PERST_B SC_P_PCIE_CTRL0_PERST_B 0
+#define SC_P_PCIE_CTRL0_PERST_B_LSIO_GPIO4_IO00 SC_P_PCIE_CTRL0_PERST_B 4
+#define SC_P_PCIE_CTRL0_CLKREQ_B_HSIO_PCIE0_CLKREQ_B SC_P_PCIE_CTRL0_CLKREQ_B 0
+#define SC_P_PCIE_CTRL0_CLKREQ_B_LSIO_GPIO4_IO01 SC_P_PCIE_CTRL0_CLKREQ_B 4
+#define SC_P_PCIE_CTRL0_WAKE_B_HSIO_PCIE0_WAKE_B SC_P_PCIE_CTRL0_WAKE_B 0
+#define SC_P_PCIE_CTRL0_WAKE_B_LSIO_GPIO4_IO02 SC_P_PCIE_CTRL0_WAKE_B 4
+#define SC_P_USB_SS3_TC0_ADMA_I2C1_SCL SC_P_USB_SS3_TC0 0
+#define SC_P_USB_SS3_TC0_CONN_USB_OTG1_PWR SC_P_USB_SS3_TC0 1
+#define SC_P_USB_SS3_TC0_CONN_USB_OTG2_PWR SC_P_USB_SS3_TC0 2
+#define SC_P_USB_SS3_TC0_LSIO_GPIO4_IO03 SC_P_USB_SS3_TC0 4
+#define SC_P_USB_SS3_TC1_ADMA_I2C1_SCL SC_P_USB_SS3_TC1 0
+#define SC_P_USB_SS3_TC1_CONN_USB_OTG2_PWR SC_P_USB_SS3_TC1 1
+#define SC_P_USB_SS3_TC1_LSIO_GPIO4_IO04 SC_P_USB_SS3_TC1 4
+#define SC_P_USB_SS3_TC2_ADMA_I2C1_SDA SC_P_USB_SS3_TC2 0
+#define SC_P_USB_SS3_TC2_CONN_USB_OTG1_OC SC_P_USB_SS3_TC2 1
+#define SC_P_USB_SS3_TC2_CONN_USB_OTG2_OC SC_P_USB_SS3_TC2 2
+#define SC_P_USB_SS3_TC2_LSIO_GPIO4_IO05 SC_P_USB_SS3_TC2 4
+#define SC_P_USB_SS3_TC3_ADMA_I2C1_SDA SC_P_USB_SS3_TC3 0
+#define SC_P_USB_SS3_TC3_CONN_USB_OTG2_OC SC_P_USB_SS3_TC3 1
+#define SC_P_USB_SS3_TC3_LSIO_GPIO4_IO06 SC_P_USB_SS3_TC3 4
+#define SC_P_EMMC0_CLK_CONN_EMMC0_CLK SC_P_EMMC0_CLK 0
+#define SC_P_EMMC0_CLK_CONN_NAND_READY_B SC_P_EMMC0_CLK 1
+#define SC_P_EMMC0_CLK_LSIO_GPIO4_IO07 SC_P_EMMC0_CLK 4
+#define SC_P_EMMC0_CMD_CONN_EMMC0_CMD SC_P_EMMC0_CMD 0
+#define SC_P_EMMC0_CMD_CONN_NAND_DQS SC_P_EMMC0_CMD 1
+#define SC_P_EMMC0_CMD_LSIO_GPIO4_IO08 SC_P_EMMC0_CMD 4
+#define SC_P_EMMC0_DATA0_CONN_EMMC0_DATA0 SC_P_EMMC0_DATA0 0
+#define SC_P_EMMC0_DATA0_CONN_NAND_DATA00 SC_P_EMMC0_DATA0 1
+#define SC_P_EMMC0_DATA0_LSIO_GPIO4_IO09 SC_P_EMMC0_DATA0 4
+#define SC_P_EMMC0_DATA1_CONN_EMMC0_DATA1 SC_P_EMMC0_DATA1 0
+#define SC_P_EMMC0_DATA1_CONN_NAND_DATA01 SC_P_EMMC0_DATA1 1
+#define SC_P_EMMC0_DATA1_LSIO_GPIO4_IO10 SC_P_EMMC0_DATA1 4
+#define SC_P_EMMC0_DATA2_CONN_EMMC0_DATA2 SC_P_EMMC0_DATA2 0
+#define SC_P_EMMC0_DATA2_CONN_NAND_DATA02 SC_P_EMMC0_DATA2 1
+#define SC_P_EMMC0_DATA2_LSIO_GPIO4_IO11 SC_P_EMMC0_DATA2 4
+#define SC_P_EMMC0_DATA3_CONN_EMMC0_DATA3 SC_P_EMMC0_DATA3 0
+#define SC_P_EMMC0_DATA3_CONN_NAND_DATA03 SC_P_EMMC0_DATA3 1
+#define SC_P_EMMC0_DATA3_LSIO_GPIO4_IO12 SC_P_EMMC0_DATA3 4
+#define SC_P_EMMC0_DATA4_CONN_EMMC0_DATA4 SC_P_EMMC0_DATA4 0
+#define SC_P_EMMC0_DATA4_CONN_NAND_DATA04 SC_P_EMMC0_DATA4 1
+#define SC_P_EMMC0_DATA4_CONN_EMMC0_WP SC_P_EMMC0_DATA4 3
+#define SC_P_EMMC0_DATA4_LSIO_GPIO4_IO13 SC_P_EMMC0_DATA4 4
+#define SC_P_EMMC0_DATA5_CONN_EMMC0_DATA5 SC_P_EMMC0_DATA5 0
+#define SC_P_EMMC0_DATA5_CONN_NAND_DATA05 SC_P_EMMC0_DATA5 1
+#define SC_P_EMMC0_DATA5_CONN_EMMC0_VSELECT SC_P_EMMC0_DATA5 3
+#define SC_P_EMMC0_DATA5_LSIO_GPIO4_IO14 SC_P_EMMC0_DATA5 4
+#define SC_P_EMMC0_DATA6_CONN_EMMC0_DATA6 SC_P_EMMC0_DATA6 0
+#define SC_P_EMMC0_DATA6_CONN_NAND_DATA06 SC_P_EMMC0_DATA6 1
+#define SC_P_EMMC0_DATA6_CONN_MLB_CLK SC_P_EMMC0_DATA6 3
+#define SC_P_EMMC0_DATA6_LSIO_GPIO4_IO15 SC_P_EMMC0_DATA6 4
+#define SC_P_EMMC0_DATA7_CONN_EMMC0_DATA7 SC_P_EMMC0_DATA7 0
+#define SC_P_EMMC0_DATA7_CONN_NAND_DATA07 SC_P_EMMC0_DATA7 1
+#define SC_P_EMMC0_DATA7_CONN_MLB_SIG SC_P_EMMC0_DATA7 3
+#define SC_P_EMMC0_DATA7_LSIO_GPIO4_IO16 SC_P_EMMC0_DATA7 4
+#define SC_P_EMMC0_STROBE_CONN_EMMC0_STROBE SC_P_EMMC0_STROBE 0
+#define SC_P_EMMC0_STROBE_CONN_NAND_CLE SC_P_EMMC0_STROBE 1
+#define SC_P_EMMC0_STROBE_CONN_MLB_DATA SC_P_EMMC0_STROBE 3
+#define SC_P_EMMC0_STROBE_LSIO_GPIO4_IO17 SC_P_EMMC0_STROBE 4
+#define SC_P_EMMC0_RESET_B_CONN_EMMC0_RESET_B SC_P_EMMC0_RESET_B 0
+#define SC_P_EMMC0_RESET_B_CONN_NAND_WP_B SC_P_EMMC0_RESET_B 1
+#define SC_P_EMMC0_RESET_B_LSIO_GPIO4_IO18 SC_P_EMMC0_RESET_B 4
+#define SC_P_USDHC1_RESET_B_CONN_USDHC1_RESET_B SC_P_USDHC1_RESET_B 0
+#define SC_P_USDHC1_RESET_B_CONN_NAND_RE_N SC_P_USDHC1_RESET_B 1
+#define SC_P_USDHC1_RESET_B_ADMA_SPI2_SCK SC_P_USDHC1_RESET_B 2
+#define SC_P_USDHC1_RESET_B_LSIO_GPIO4_IO19 SC_P_USDHC1_RESET_B 4
+#define SC_P_USDHC1_VSELECT_CONN_USDHC1_VSELECT SC_P_USDHC1_VSELECT 0
+#define SC_P_USDHC1_VSELECT_CONN_NAND_RE_P SC_P_USDHC1_VSELECT 1
+#define SC_P_USDHC1_VSELECT_ADMA_SPI2_SDO SC_P_USDHC1_VSELECT 2
+#define SC_P_USDHC1_VSELECT_CONN_NAND_RE_B SC_P_USDHC1_VSELECT 3
+#define SC_P_USDHC1_VSELECT_LSIO_GPIO4_IO20 SC_P_USDHC1_VSELECT 4
+#define SC_P_USDHC1_WP_CONN_USDHC1_WP SC_P_USDHC1_WP 0
+#define SC_P_USDHC1_WP_CONN_NAND_DQS_N SC_P_USDHC1_WP 1
+#define SC_P_USDHC1_WP_ADMA_SPI2_SDI SC_P_USDHC1_WP 2
+#define SC_P_USDHC1_WP_LSIO_GPIO4_IO21 SC_P_USDHC1_WP 4
+#define SC_P_USDHC1_CD_B_CONN_USDHC1_CD_B SC_P_USDHC1_CD_B 0
+#define SC_P_USDHC1_CD_B_CONN_NAND_DQS_P SC_P_USDHC1_CD_B 1
+#define SC_P_USDHC1_CD_B_ADMA_SPI2_CS0 SC_P_USDHC1_CD_B 2
+#define SC_P_USDHC1_CD_B_CONN_NAND_DQS SC_P_USDHC1_CD_B 3
+#define SC_P_USDHC1_CD_B_LSIO_GPIO4_IO22 SC_P_USDHC1_CD_B 4
+#define SC_P_USDHC1_CLK_CONN_USDHC1_CLK SC_P_USDHC1_CLK 0
+#define SC_P_USDHC1_CLK_ADMA_UART3_RX SC_P_USDHC1_CLK 2
+#define SC_P_USDHC1_CLK_LSIO_GPIO4_IO23 SC_P_USDHC1_CLK 4
+#define SC_P_USDHC1_CMD_CONN_USDHC1_CMD SC_P_USDHC1_CMD 0
+#define SC_P_USDHC1_CMD_CONN_NAND_CE0_B SC_P_USDHC1_CMD 1
+#define SC_P_USDHC1_CMD_ADMA_MQS_R SC_P_USDHC1_CMD 2
+#define SC_P_USDHC1_CMD_LSIO_GPIO4_IO24 SC_P_USDHC1_CMD 4
+#define SC_P_USDHC1_DATA0_CONN_USDHC1_DATA0 SC_P_USDHC1_DATA0 0
+#define SC_P_USDHC1_DATA0_CONN_NAND_CE1_B SC_P_USDHC1_DATA0 1
+#define SC_P_USDHC1_DATA0_ADMA_MQS_L SC_P_USDHC1_DATA0 2
+#define SC_P_USDHC1_DATA0_LSIO_GPIO4_IO25 SC_P_USDHC1_DATA0 4
+#define SC_P_USDHC1_DATA1_CONN_USDHC1_DATA1 SC_P_USDHC1_DATA1 0
+#define SC_P_USDHC1_DATA1_CONN_NAND_RE_B SC_P_USDHC1_DATA1 1
+#define SC_P_USDHC1_DATA1_ADMA_UART3_TX SC_P_USDHC1_DATA1 2
+#define SC_P_USDHC1_DATA1_LSIO_GPIO4_IO26 SC_P_USDHC1_DATA1 4
+#define SC_P_USDHC1_DATA2_CONN_USDHC1_DATA2 SC_P_USDHC1_DATA2 0
+#define SC_P_USDHC1_DATA2_CONN_NAND_WE_B SC_P_USDHC1_DATA2 1
+#define SC_P_USDHC1_DATA2_ADMA_UART3_CTS_B SC_P_USDHC1_DATA2 2
+#define SC_P_USDHC1_DATA2_LSIO_GPIO4_IO27 SC_P_USDHC1_DATA2 4
+#define SC_P_USDHC1_DATA3_CONN_USDHC1_DATA3 SC_P_USDHC1_DATA3 0
+#define SC_P_USDHC1_DATA3_CONN_NAND_ALE SC_P_USDHC1_DATA3 1
+#define SC_P_USDHC1_DATA3_ADMA_UART3_RTS_B SC_P_USDHC1_DATA3 2
+#define SC_P_USDHC1_DATA3_LSIO_GPIO4_IO28 SC_P_USDHC1_DATA3 4
+#define SC_P_ENET0_RGMII_TXC_CONN_ENET0_RGMII_TXC SC_P_ENET0_RGMII_TXC 0
+#define SC_P_ENET0_RGMII_TXC_CONN_ENET0_RCLK50M_OUT SC_P_ENET0_RGMII_TXC 1
+#define SC_P_ENET0_RGMII_TXC_CONN_ENET0_RCLK50M_IN SC_P_ENET0_RGMII_TXC 2
+#define SC_P_ENET0_RGMII_TXC_CONN_NAND_CE1_B SC_P_ENET0_RGMII_TXC 3
+#define SC_P_ENET0_RGMII_TXC_LSIO_GPIO4_IO29 SC_P_ENET0_RGMII_TXC 4
+#define SC_P_ENET0_RGMII_TX_CTL_CONN_ENET0_RGMII_TX_CTL SC_P_ENET0_RGMII_TX_CTL 0
+#define SC_P_ENET0_RGMII_TX_CTL_CONN_USDHC1_RESET_B SC_P_ENET0_RGMII_TX_CTL 3
+#define SC_P_ENET0_RGMII_TX_CTL_LSIO_GPIO4_IO30 SC_P_ENET0_RGMII_TX_CTL 4
+#define SC_P_ENET0_RGMII_TXD0_CONN_ENET0_RGMII_TXD0 SC_P_ENET0_RGMII_TXD0 0
+#define SC_P_ENET0_RGMII_TXD0_CONN_USDHC1_VSELECT SC_P_ENET0_RGMII_TXD0 3
+#define SC_P_ENET0_RGMII_TXD0_LSIO_GPIO4_IO31 SC_P_ENET0_RGMII_TXD0 4
+#define SC_P_ENET0_RGMII_TXD1_CONN_ENET0_RGMII_TXD1 SC_P_ENET0_RGMII_TXD1 0
+#define SC_P_ENET0_RGMII_TXD1_CONN_USDHC1_WP SC_P_ENET0_RGMII_TXD1 3
+#define SC_P_ENET0_RGMII_TXD1_LSIO_GPIO5_IO00 SC_P_ENET0_RGMII_TXD1 4
+#define SC_P_ENET0_RGMII_TXD2_CONN_ENET0_RGMII_TXD2 SC_P_ENET0_RGMII_TXD2 0
+#define SC_P_ENET0_RGMII_TXD2_CONN_MLB_CLK SC_P_ENET0_RGMII_TXD2 1
+#define SC_P_ENET0_RGMII_TXD2_CONN_NAND_CE0_B SC_P_ENET0_RGMII_TXD2 2
+#define SC_P_ENET0_RGMII_TXD2_CONN_USDHC1_CD_B SC_P_ENET0_RGMII_TXD2 3
+#define SC_P_ENET0_RGMII_TXD2_LSIO_GPIO5_IO01 SC_P_ENET0_RGMII_TXD2 4
+#define SC_P_ENET0_RGMII_TXD3_CONN_ENET0_RGMII_TXD3 SC_P_ENET0_RGMII_TXD3 0
+#define SC_P_ENET0_RGMII_TXD3_CONN_MLB_SIG SC_P_ENET0_RGMII_TXD3 1
+#define SC_P_ENET0_RGMII_TXD3_CONN_NAND_RE_B SC_P_ENET0_RGMII_TXD3 2
+#define SC_P_ENET0_RGMII_TXD3_LSIO_GPIO5_IO02 SC_P_ENET0_RGMII_TXD3 4
+#define SC_P_ENET0_RGMII_RXC_CONN_ENET0_RGMII_RXC SC_P_ENET0_RGMII_RXC 0
+#define SC_P_ENET0_RGMII_RXC_CONN_MLB_DATA SC_P_ENET0_RGMII_RXC 1
+#define SC_P_ENET0_RGMII_RXC_CONN_NAND_WE_B SC_P_ENET0_RGMII_RXC 2
+#define SC_P_ENET0_RGMII_RXC_CONN_USDHC1_CLK SC_P_ENET0_RGMII_RXC 3
+#define SC_P_ENET0_RGMII_RXC_LSIO_GPIO5_IO03 SC_P_ENET0_RGMII_RXC 4
+#define SC_P_ENET0_RGMII_RX_CTL_CONN_ENET0_RGMII_RX_CTL SC_P_ENET0_RGMII_RX_CTL 0
+#define SC_P_ENET0_RGMII_RX_CTL_CONN_USDHC1_CMD SC_P_ENET0_RGMII_RX_CTL 3
+#define SC_P_ENET0_RGMII_RX_CTL_LSIO_GPIO5_IO04 SC_P_ENET0_RGMII_RX_CTL 4
+#define SC_P_ENET0_RGMII_RXD0_CONN_ENET0_RGMII_RXD0 SC_P_ENET0_RGMII_RXD0 0
+#define SC_P_ENET0_RGMII_RXD0_CONN_USDHC1_DATA0 SC_P_ENET0_RGMII_RXD0 3
+#define SC_P_ENET0_RGMII_RXD0_LSIO_GPIO5_IO05 SC_P_ENET0_RGMII_RXD0 4
+#define SC_P_ENET0_RGMII_RXD1_CONN_ENET0_RGMII_RXD1 SC_P_ENET0_RGMII_RXD1 0
+#define SC_P_ENET0_RGMII_RXD1_CONN_USDHC1_DATA1 SC_P_ENET0_RGMII_RXD1 3
+#define SC_P_ENET0_RGMII_RXD1_LSIO_GPIO5_IO06 SC_P_ENET0_RGMII_RXD1 4
+#define SC_P_ENET0_RGMII_RXD2_CONN_ENET0_RGMII_RXD2 SC_P_ENET0_RGMII_RXD2 0
+#define SC_P_ENET0_RGMII_RXD2_CONN_ENET0_RMII_RX_ER SC_P_ENET0_RGMII_RXD2 1
+#define SC_P_ENET0_RGMII_RXD2_CONN_USDHC1_DATA2 SC_P_ENET0_RGMII_RXD2 3
+#define SC_P_ENET0_RGMII_RXD2_LSIO_GPIO5_IO07 SC_P_ENET0_RGMII_RXD2 4
+#define SC_P_ENET0_RGMII_RXD3_CONN_ENET0_RGMII_RXD3 SC_P_ENET0_RGMII_RXD3 0
+#define SC_P_ENET0_RGMII_RXD3_CONN_NAND_ALE SC_P_ENET0_RGMII_RXD3 2
+#define SC_P_ENET0_RGMII_RXD3_CONN_USDHC1_DATA3 SC_P_ENET0_RGMII_RXD3 3
+#define SC_P_ENET0_RGMII_RXD3_LSIO_GPIO5_IO08 SC_P_ENET0_RGMII_RXD3 4
+#define SC_P_ENET0_REFCLK_125M_25M_CONN_ENET0_REFCLK_125M_25M SC_P_ENET0_REFCLK_125M_25M 0
+#define SC_P_ENET0_REFCLK_125M_25M_CONN_ENET0_PPS SC_P_ENET0_REFCLK_125M_25M 1
+#define SC_P_ENET0_REFCLK_125M_25M_CONN_ENET1_PPS SC_P_ENET0_REFCLK_125M_25M 2
+#define SC_P_ENET0_REFCLK_125M_25M_LSIO_GPIO5_IO09 SC_P_ENET0_REFCLK_125M_25M 4
+#define SC_P_ENET0_MDIO_CONN_ENET0_MDIO SC_P_ENET0_MDIO 0
+#define SC_P_ENET0_MDIO_ADMA_I2C3_SDA SC_P_ENET0_MDIO 1
+#define SC_P_ENET0_MDIO_CONN_ENET1_MDIO SC_P_ENET0_MDIO 2
+#define SC_P_ENET0_MDIO_LSIO_GPIO5_IO10 SC_P_ENET0_MDIO 4
+#define SC_P_ENET0_MDC_CONN_ENET0_MDC SC_P_ENET0_MDC 0
+#define SC_P_ENET0_MDC_ADMA_I2C3_SCL SC_P_ENET0_MDC 1
+#define SC_P_ENET0_MDC_CONN_ENET1_MDC SC_P_ENET0_MDC 2
+#define SC_P_ENET0_MDC_LSIO_GPIO5_IO11 SC_P_ENET0_MDC 4
+#define SC_P_ESAI0_FSR_ADMA_ESAI0_FSR SC_P_ESAI0_FSR 0
+#define SC_P_ESAI0_FSR_CONN_ENET1_RCLK50M_OUT SC_P_ESAI0_FSR 1
+#define SC_P_ESAI0_FSR_ADMA_LCDIF_D00 SC_P_ESAI0_FSR 2
+#define SC_P_ESAI0_FSR_CONN_ENET1_RGMII_TXC SC_P_ESAI0_FSR 3
+#define SC_P_ESAI0_FSR_CONN_ENET1_RCLK50M_IN SC_P_ESAI0_FSR 4
+#define SC_P_ESAI0_FST_ADMA_ESAI0_FST SC_P_ESAI0_FST 0
+#define SC_P_ESAI0_FST_CONN_MLB_CLK SC_P_ESAI0_FST 1
+#define SC_P_ESAI0_FST_ADMA_LCDIF_D01 SC_P_ESAI0_FST 2
+#define SC_P_ESAI0_FST_CONN_ENET1_RGMII_TXD2 SC_P_ESAI0_FST 3
+#define SC_P_ESAI0_FST_LSIO_GPIO0_IO01 SC_P_ESAI0_FST 4
+#define SC_P_ESAI0_SCKR_ADMA_ESAI0_SCKR SC_P_ESAI0_SCKR 0
+#define SC_P_ESAI0_SCKR_ADMA_LCDIF_D02 SC_P_ESAI0_SCKR 2
+#define SC_P_ESAI0_SCKR_CONN_ENET1_RGMII_TX_CTL SC_P_ESAI0_SCKR 3
+#define SC_P_ESAI0_SCKR_LSIO_GPIO0_IO02 SC_P_ESAI0_SCKR 4
+#define SC_P_ESAI0_SCKT_ADMA_ESAI0_SCKT SC_P_ESAI0_SCKT 0
+#define SC_P_ESAI0_SCKT_CONN_MLB_SIG SC_P_ESAI0_SCKT 1
+#define SC_P_ESAI0_SCKT_ADMA_LCDIF_D03 SC_P_ESAI0_SCKT 2
+#define SC_P_ESAI0_SCKT_CONN_ENET1_RGMII_TXD3 SC_P_ESAI0_SCKT 3
+#define SC_P_ESAI0_SCKT_LSIO_GPIO0_IO03 SC_P_ESAI0_SCKT 4
+#define SC_P_ESAI0_TX0_ADMA_ESAI0_TX0 SC_P_ESAI0_TX0 0
+#define SC_P_ESAI0_TX0_CONN_MLB_DATA SC_P_ESAI0_TX0 1
+#define SC_P_ESAI0_TX0_ADMA_LCDIF_D04 SC_P_ESAI0_TX0 2
+#define SC_P_ESAI0_TX0_CONN_ENET1_RGMII_RXC SC_P_ESAI0_TX0 3
+#define SC_P_ESAI0_TX0_LSIO_GPIO0_IO04 SC_P_ESAI0_TX0 4
+#define SC_P_ESAI0_TX1_ADMA_ESAI0_TX1 SC_P_ESAI0_TX1 0
+#define SC_P_ESAI0_TX1_ADMA_LCDIF_D05 SC_P_ESAI0_TX1 2
+#define SC_P_ESAI0_TX1_CONN_ENET1_RGMII_RXD3 SC_P_ESAI0_TX1 3
+#define SC_P_ESAI0_TX1_LSIO_GPIO0_IO05 SC_P_ESAI0_TX1 4
+#define SC_P_ESAI0_TX2_RX3_ADMA_ESAI0_TX2_RX3 SC_P_ESAI0_TX2_RX3 0
+#define SC_P_ESAI0_TX2_RX3_CONN_ENET1_RMII_RX_ER SC_P_ESAI0_TX2_RX3 1
+#define SC_P_ESAI0_TX2_RX3_ADMA_LCDIF_D06 SC_P_ESAI0_TX2_RX3 2
+#define SC_P_ESAI0_TX2_RX3_CONN_ENET1_RGMII_RXD2 SC_P_ESAI0_TX2_RX3 3
+#define SC_P_ESAI0_TX2_RX3_LSIO_GPIO0_IO06 SC_P_ESAI0_TX2_RX3 4
+#define SC_P_ESAI0_TX3_RX2_ADMA_ESAI0_TX3_RX2 SC_P_ESAI0_TX3_RX2 0
+#define SC_P_ESAI0_TX3_RX2_ADMA_LCDIF_D07 SC_P_ESAI0_TX3_RX2 2
+#define SC_P_ESAI0_TX3_RX2_CONN_ENET1_RGMII_RXD1 SC_P_ESAI0_TX3_RX2 3
+#define SC_P_ESAI0_TX3_RX2_LSIO_GPIO0_IO07 SC_P_ESAI0_TX3_RX2 4
+#define SC_P_ESAI0_TX4_RX1_ADMA_ESAI0_TX4_RX1 SC_P_ESAI0_TX4_RX1 0
+#define SC_P_ESAI0_TX4_RX1_ADMA_LCDIF_D08 SC_P_ESAI0_TX4_RX1 2
+#define SC_P_ESAI0_TX4_RX1_CONN_ENET1_RGMII_TXD0 SC_P_ESAI0_TX4_RX1 3
+#define SC_P_ESAI0_TX4_RX1_LSIO_GPIO0_IO08 SC_P_ESAI0_TX4_RX1 4
+#define SC_P_ESAI0_TX5_RX0_ADMA_ESAI0_TX5_RX0 SC_P_ESAI0_TX5_RX0 0
+#define SC_P_ESAI0_TX5_RX0_ADMA_LCDIF_D09 SC_P_ESAI0_TX5_RX0 2
+#define SC_P_ESAI0_TX5_RX0_CONN_ENET1_RGMII_TXD1 SC_P_ESAI0_TX5_RX0 3
+#define SC_P_ESAI0_TX5_RX0_LSIO_GPIO0_IO09 SC_P_ESAI0_TX5_RX0 4
+#define SC_P_SPDIF0_RX_ADMA_SPDIF0_RX SC_P_SPDIF0_RX 0
+#define SC_P_SPDIF0_RX_ADMA_MQS_R SC_P_SPDIF0_RX 1
+#define SC_P_SPDIF0_RX_ADMA_LCDIF_D10 SC_P_SPDIF0_RX 2
+#define SC_P_SPDIF0_RX_CONN_ENET1_RGMII_RXD0 SC_P_SPDIF0_RX 3
+#define SC_P_SPDIF0_RX_LSIO_GPIO0_IO10 SC_P_SPDIF0_RX 4
+#define SC_P_SPDIF0_TX_ADMA_SPDIF0_TX SC_P_SPDIF0_TX 0
+#define SC_P_SPDIF0_TX_ADMA_MQS_L SC_P_SPDIF0_TX 1
+#define SC_P_SPDIF0_TX_ADMA_LCDIF_D11 SC_P_SPDIF0_TX 2
+#define SC_P_SPDIF0_TX_CONN_ENET1_RGMII_RX_CTL SC_P_SPDIF0_TX 3
+#define SC_P_SPDIF0_TX_LSIO_GPIO0_IO11 SC_P_SPDIF0_TX 4
+#define SC_P_SPDIF0_EXT_CLK_ADMA_SPDIF0_EXT_CLK SC_P_SPDIF0_EXT_CLK 0
+#define SC_P_SPDIF0_EXT_CLK_ADMA_LCDIF_D12 SC_P_SPDIF0_EXT_CLK 2
+#define SC_P_SPDIF0_EXT_CLK_CONN_ENET1_REFCLK_125M_25M SC_P_SPDIF0_EXT_CLK 3
+#define SC_P_SPDIF0_EXT_CLK_LSIO_GPIO0_IO12 SC_P_SPDIF0_EXT_CLK 4
+#define SC_P_SPI3_SCK_ADMA_SPI3_SCK SC_P_SPI3_SCK 0
+#define SC_P_SPI3_SCK_ADMA_LCDIF_D13 SC_P_SPI3_SCK 2
+#define SC_P_SPI3_SCK_LSIO_GPIO0_IO13 SC_P_SPI3_SCK 4
+#define SC_P_SPI3_SDO_ADMA_SPI3_SDO SC_P_SPI3_SDO 0
+#define SC_P_SPI3_SDO_ADMA_LCDIF_D14 SC_P_SPI3_SDO 2
+#define SC_P_SPI3_SDO_LSIO_GPIO0_IO14 SC_P_SPI3_SDO 4
+#define SC_P_SPI3_SDI_ADMA_SPI3_SDI SC_P_SPI3_SDI 0
+#define SC_P_SPI3_SDI_ADMA_LCDIF_D15 SC_P_SPI3_SDI 2
+#define SC_P_SPI3_SDI_LSIO_GPIO0_IO15 SC_P_SPI3_SDI 4
+#define SC_P_SPI3_CS0_ADMA_SPI3_CS0 SC_P_SPI3_CS0 0
+#define SC_P_SPI3_CS0_ADMA_ACM_MCLK_OUT1 SC_P_SPI3_CS0 1
+#define SC_P_SPI3_CS0_ADMA_LCDIF_HSYNC SC_P_SPI3_CS0 2
+#define SC_P_SPI3_CS0_LSIO_GPIO0_IO16 SC_P_SPI3_CS0 4
+#define SC_P_SPI3_CS1_ADMA_SPI3_CS1 SC_P_SPI3_CS1 0
+#define SC_P_SPI3_CS1_ADMA_I2C3_SCL SC_P_SPI3_CS1 1
+#define SC_P_SPI3_CS1_ADMA_LCDIF_RESET SC_P_SPI3_CS1 2
+#define SC_P_SPI3_CS1_ADMA_SPI2_CS0 SC_P_SPI3_CS1 3
+#define SC_P_SPI3_CS1_ADMA_LCDIF_D16 SC_P_SPI3_CS1 4
+#define SC_P_MCLK_IN1_ADMA_ACM_MCLK_IN1 SC_P_MCLK_IN1 0
+#define SC_P_MCLK_IN1_ADMA_I2C3_SDA SC_P_MCLK_IN1 1
+#define SC_P_MCLK_IN1_ADMA_LCDIF_EN SC_P_MCLK_IN1 2
+#define SC_P_MCLK_IN1_ADMA_SPI2_SCK SC_P_MCLK_IN1 3
+#define SC_P_MCLK_IN1_ADMA_LCDIF_D17 SC_P_MCLK_IN1 4
+#define SC_P_MCLK_IN0_ADMA_ACM_MCLK_IN0 SC_P_MCLK_IN0 0
+#define SC_P_MCLK_IN0_ADMA_ESAI0_RX_HF_CLK SC_P_MCLK_IN0 1
+#define SC_P_MCLK_IN0_ADMA_LCDIF_VSYNC SC_P_MCLK_IN0 2
+#define SC_P_MCLK_IN0_ADMA_SPI2_SDI SC_P_MCLK_IN0 3
+#define SC_P_MCLK_IN0_LSIO_GPIO0_IO19 SC_P_MCLK_IN0 4
+#define SC_P_MCLK_OUT0_ADMA_ACM_MCLK_OUT0 SC_P_MCLK_OUT0 0
+#define SC_P_MCLK_OUT0_ADMA_ESAI0_TX_HF_CLK SC_P_MCLK_OUT0 1
+#define SC_P_MCLK_OUT0_ADMA_LCDIF_CLK SC_P_MCLK_OUT0 2
+#define SC_P_MCLK_OUT0_ADMA_SPI2_SDO SC_P_MCLK_OUT0 3
+#define SC_P_MCLK_OUT0_LSIO_GPIO0_IO20 SC_P_MCLK_OUT0 4
+#define SC_P_UART1_TX_ADMA_UART1_TX SC_P_UART1_TX 0
+#define SC_P_UART1_TX_LSIO_PWM0_OUT SC_P_UART1_TX 1
+#define SC_P_UART1_TX_LSIO_GPT0_CAPTURE SC_P_UART1_TX 2
+#define SC_P_UART1_TX_LSIO_GPIO0_IO21 SC_P_UART1_TX 4
+#define SC_P_UART1_RX_ADMA_UART1_RX SC_P_UART1_RX 0
+#define SC_P_UART1_RX_LSIO_PWM1_OUT SC_P_UART1_RX 1
+#define SC_P_UART1_RX_LSIO_GPT0_COMPARE SC_P_UART1_RX 2
+#define SC_P_UART1_RX_LSIO_GPT1_CLK SC_P_UART1_RX 3
+#define SC_P_UART1_RX_LSIO_GPIO0_IO22 SC_P_UART1_RX 4
+#define SC_P_UART1_RTS_B_ADMA_UART1_RTS_B SC_P_UART1_RTS_B 0
+#define SC_P_UART1_RTS_B_LSIO_PWM2_OUT SC_P_UART1_RTS_B 1
+#define SC_P_UART1_RTS_B_ADMA_LCDIF_D16 SC_P_UART1_RTS_B 2
+#define SC_P_UART1_RTS_B_LSIO_GPT1_CAPTURE SC_P_UART1_RTS_B 3
+#define SC_P_UART1_RTS_B_LSIO_GPT0_CLK SC_P_UART1_RTS_B 4
+#define SC_P_UART1_CTS_B_ADMA_UART1_CTS_B SC_P_UART1_CTS_B 0
+#define SC_P_UART1_CTS_B_LSIO_PWM3_OUT SC_P_UART1_CTS_B 1
+#define SC_P_UART1_CTS_B_ADMA_LCDIF_D17 SC_P_UART1_CTS_B 2
+#define SC_P_UART1_CTS_B_LSIO_GPT1_COMPARE SC_P_UART1_CTS_B 3
+#define SC_P_UART1_CTS_B_LSIO_GPIO0_IO24 SC_P_UART1_CTS_B 4
+#define SC_P_SAI0_TXD_ADMA_SAI0_TXD SC_P_SAI0_TXD 0
+#define SC_P_SAI0_TXD_ADMA_SAI1_RXC SC_P_SAI0_TXD 1
+#define SC_P_SAI0_TXD_ADMA_SPI1_SDO SC_P_SAI0_TXD 2
+#define SC_P_SAI0_TXD_ADMA_LCDIF_D18 SC_P_SAI0_TXD 3
+#define SC_P_SAI0_TXD_LSIO_GPIO0_IO25 SC_P_SAI0_TXD 4
+#define SC_P_SAI0_TXC_ADMA_SAI0_TXC SC_P_SAI0_TXC 0
+#define SC_P_SAI0_TXC_ADMA_SAI1_TXD SC_P_SAI0_TXC 1
+#define SC_P_SAI0_TXC_ADMA_SPI1_SDI SC_P_SAI0_TXC 2
+#define SC_P_SAI0_TXC_ADMA_LCDIF_D19 SC_P_SAI0_TXC 3
+#define SC_P_SAI0_TXC_LSIO_GPIO0_IO26 SC_P_SAI0_TXC 4
+#define SC_P_SAI0_RXD_ADMA_SAI0_RXD SC_P_SAI0_RXD 0
+#define SC_P_SAI0_RXD_ADMA_SAI1_RXFS SC_P_SAI0_RXD 1
+#define SC_P_SAI0_RXD_ADMA_SPI1_CS0 SC_P_SAI0_RXD 2
+#define SC_P_SAI0_RXD_ADMA_LCDIF_D20 SC_P_SAI0_RXD 3
+#define SC_P_SAI0_RXD_LSIO_GPIO0_IO27 SC_P_SAI0_RXD 4
+#define SC_P_SAI0_TXFS_ADMA_SAI0_TXFS SC_P_SAI0_TXFS 0
+#define SC_P_SAI0_TXFS_ADMA_SPI2_CS1 SC_P_SAI0_TXFS 1
+#define SC_P_SAI0_TXFS_ADMA_SPI1_SCK SC_P_SAI0_TXFS 2
+#define SC_P_SAI0_TXFS_LSIO_GPIO0_IO28 SC_P_SAI0_TXFS 4
+#define SC_P_SAI1_RXD_ADMA_SAI1_RXD SC_P_SAI1_RXD 0
+#define SC_P_SAI1_RXD_ADMA_SAI0_RXFS SC_P_SAI1_RXD 1
+#define SC_P_SAI1_RXD_ADMA_SPI1_CS1 SC_P_SAI1_RXD 2
+#define SC_P_SAI1_RXD_ADMA_LCDIF_D21 SC_P_SAI1_RXD 3
+#define SC_P_SAI1_RXD_LSIO_GPIO0_IO29 SC_P_SAI1_RXD 4
+#define SC_P_SAI1_RXC_ADMA_SAI1_RXC SC_P_SAI1_RXC 0
+#define SC_P_SAI1_RXC_ADMA_SAI1_TXC SC_P_SAI1_RXC 1
+#define SC_P_SAI1_RXC_ADMA_LCDIF_D22 SC_P_SAI1_RXC 3
+#define SC_P_SAI1_RXC_LSIO_GPIO0_IO30 SC_P_SAI1_RXC 4
+#define SC_P_SAI1_RXFS_ADMA_SAI1_RXFS SC_P_SAI1_RXFS 0
+#define SC_P_SAI1_RXFS_ADMA_SAI1_TXFS SC_P_SAI1_RXFS 1
+#define SC_P_SAI1_RXFS_ADMA_LCDIF_D23 SC_P_SAI1_RXFS 3
+#define SC_P_SAI1_RXFS_LSIO_GPIO0_IO31 SC_P_SAI1_RXFS 4
+#define SC_P_SPI2_CS0_ADMA_SPI2_CS0 SC_P_SPI2_CS0 0
+#define SC_P_SPI2_CS0_LSIO_GPIO1_IO00 SC_P_SPI2_CS0 4
+#define SC_P_SPI2_SDO_ADMA_SPI2_SDO SC_P_SPI2_SDO 0
+#define SC_P_SPI2_SDO_LSIO_GPIO1_IO01 SC_P_SPI2_SDO 4
+#define SC_P_SPI2_SDI_ADMA_SPI2_SDI SC_P_SPI2_SDI 0
+#define SC_P_SPI2_SDI_LSIO_GPIO1_IO02 SC_P_SPI2_SDI 4
+#define SC_P_SPI2_SCK_ADMA_SPI2_SCK SC_P_SPI2_SCK 0
+#define SC_P_SPI2_SCK_LSIO_GPIO1_IO03 SC_P_SPI2_SCK 4
+#define SC_P_SPI0_SCK_ADMA_SPI0_SCK SC_P_SPI0_SCK 0
+#define SC_P_SPI0_SCK_ADMA_SAI0_TXC SC_P_SPI0_SCK 1
+#define SC_P_SPI0_SCK_M40_I2C0_SCL SC_P_SPI0_SCK 2
+#define SC_P_SPI0_SCK_M40_GPIO0_IO00 SC_P_SPI0_SCK 3
+#define SC_P_SPI0_SCK_LSIO_GPIO1_IO04 SC_P_SPI0_SCK 4
+#define SC_P_SPI0_SDI_ADMA_SPI0_SDI SC_P_SPI0_SDI 0
+#define SC_P_SPI0_SDI_ADMA_SAI0_TXD SC_P_SPI0_SDI 1
+#define SC_P_SPI0_SDI_M40_TPM0_CH0 SC_P_SPI0_SDI 2
+#define SC_P_SPI0_SDI_M40_GPIO0_IO02 SC_P_SPI0_SDI 3
+#define SC_P_SPI0_SDI_LSIO_GPIO1_IO05 SC_P_SPI0_SDI 4
+#define SC_P_SPI0_SDO_ADMA_SPI0_SDO SC_P_SPI0_SDO 0
+#define SC_P_SPI0_SDO_ADMA_SAI0_TXFS SC_P_SPI0_SDO 1
+#define SC_P_SPI0_SDO_M40_I2C0_SDA SC_P_SPI0_SDO 2
+#define SC_P_SPI0_SDO_M40_GPIO0_IO01 SC_P_SPI0_SDO 3
+#define SC_P_SPI0_SDO_LSIO_GPIO1_IO06 SC_P_SPI0_SDO 4
+#define SC_P_SPI0_CS1_ADMA_SPI0_CS1 SC_P_SPI0_CS1 0
+#define SC_P_SPI0_CS1_ADMA_SAI0_RXC SC_P_SPI0_CS1 1
+#define SC_P_SPI0_CS1_ADMA_SAI1_TXD SC_P_SPI0_CS1 2
+#define SC_P_SPI0_CS1_ADMA_LCD_PWM0_OUT SC_P_SPI0_CS1 3
+#define SC_P_SPI0_CS1_LSIO_GPIO1_IO07 SC_P_SPI0_CS1 4
+#define SC_P_SPI0_CS0_ADMA_SPI0_CS0 SC_P_SPI0_CS0 0
+#define SC_P_SPI0_CS0_ADMA_SAI0_RXD SC_P_SPI0_CS0 1
+#define SC_P_SPI0_CS0_M40_TPM0_CH1 SC_P_SPI0_CS0 2
+#define SC_P_SPI0_CS0_M40_GPIO0_IO03 SC_P_SPI0_CS0 3
+#define SC_P_SPI0_CS0_LSIO_GPIO1_IO08 SC_P_SPI0_CS0 4
+#define SC_P_ADC_IN1_ADMA_ADC_IN1 SC_P_ADC_IN1 0
+#define SC_P_ADC_IN1_M40_I2C0_SDA SC_P_ADC_IN1 1
+#define SC_P_ADC_IN1_M40_GPIO0_IO01 SC_P_ADC_IN1 2
+#define SC_P_ADC_IN1_LSIO_GPIO1_IO09 SC_P_ADC_IN1 4
+#define SC_P_ADC_IN0_ADMA_ADC_IN0 SC_P_ADC_IN0 0
+#define SC_P_ADC_IN0_M40_I2C0_SCL SC_P_ADC_IN0 1
+#define SC_P_ADC_IN0_M40_GPIO0_IO00 SC_P_ADC_IN0 2
+#define SC_P_ADC_IN0_LSIO_GPIO1_IO10 SC_P_ADC_IN0 4
+#define SC_P_ADC_IN3_ADMA_ADC_IN3 SC_P_ADC_IN3 0
+#define SC_P_ADC_IN3_M40_UART0_TX SC_P_ADC_IN3 1
+#define SC_P_ADC_IN3_M40_GPIO0_IO03 SC_P_ADC_IN3 2
+#define SC_P_ADC_IN3_ADMA_ACM_MCLK_OUT0 SC_P_ADC_IN3 3
+#define SC_P_ADC_IN3_LSIO_GPIO1_IO11 SC_P_ADC_IN3 4
+#define SC_P_ADC_IN2_ADMA_ADC_IN2 SC_P_ADC_IN2 0
+#define SC_P_ADC_IN2_M40_UART0_RX SC_P_ADC_IN2 1
+#define SC_P_ADC_IN2_M40_GPIO0_IO02 SC_P_ADC_IN2 2
+#define SC_P_ADC_IN2_ADMA_ACM_MCLK_IN0 SC_P_ADC_IN2 3
+#define SC_P_ADC_IN2_LSIO_GPIO1_IO12 SC_P_ADC_IN2 4
+#define SC_P_ADC_IN5_ADMA_ADC_IN5 SC_P_ADC_IN5 0
+#define SC_P_ADC_IN5_M40_TPM0_CH1 SC_P_ADC_IN5 1
+#define SC_P_ADC_IN5_M40_GPIO0_IO05 SC_P_ADC_IN5 2
+#define SC_P_ADC_IN5_LSIO_GPIO1_IO13 SC_P_ADC_IN5 4
+#define SC_P_ADC_IN4_ADMA_ADC_IN4 SC_P_ADC_IN4 0
+#define SC_P_ADC_IN4_M40_TPM0_CH0 SC_P_ADC_IN4 1
+#define SC_P_ADC_IN4_M40_GPIO0_IO04 SC_P_ADC_IN4 2
+#define SC_P_ADC_IN4_LSIO_GPIO1_IO14 SC_P_ADC_IN4 4
+#define SC_P_FLEXCAN0_RX_ADMA_FLEXCAN0_RX SC_P_FLEXCAN0_RX 0
+#define SC_P_FLEXCAN0_RX_ADMA_SAI2_RXC SC_P_FLEXCAN0_RX 1
+#define SC_P_FLEXCAN0_RX_ADMA_UART0_RTS_B SC_P_FLEXCAN0_RX 2
+#define SC_P_FLEXCAN0_RX_ADMA_SAI1_TXC SC_P_FLEXCAN0_RX 3
+#define SC_P_FLEXCAN0_RX_LSIO_GPIO1_IO15 SC_P_FLEXCAN0_RX 4
+#define SC_P_FLEXCAN0_TX_ADMA_FLEXCAN0_TX SC_P_FLEXCAN0_TX 0
+#define SC_P_FLEXCAN0_TX_ADMA_SAI2_RXD SC_P_FLEXCAN0_TX 1
+#define SC_P_FLEXCAN0_TX_ADMA_UART0_CTS_B SC_P_FLEXCAN0_TX 2
+#define SC_P_FLEXCAN0_TX_ADMA_SAI1_TXFS SC_P_FLEXCAN0_TX 3
+#define SC_P_FLEXCAN0_TX_LSIO_GPIO1_IO16 SC_P_FLEXCAN0_TX 4
+#define SC_P_FLEXCAN1_RX_ADMA_FLEXCAN1_RX SC_P_FLEXCAN1_RX 0
+#define SC_P_FLEXCAN1_RX_ADMA_SAI2_RXFS SC_P_FLEXCAN1_RX 1
+#define SC_P_FLEXCAN1_RX_ADMA_FTM_CH2 SC_P_FLEXCAN1_RX 2
+#define SC_P_FLEXCAN1_RX_ADMA_SAI1_TXD SC_P_FLEXCAN1_RX 3
+#define SC_P_FLEXCAN1_RX_LSIO_GPIO1_IO17 SC_P_FLEXCAN1_RX 4
+#define SC_P_FLEXCAN1_TX_ADMA_FLEXCAN1_TX SC_P_FLEXCAN1_TX 0
+#define SC_P_FLEXCAN1_TX_ADMA_SAI3_RXC SC_P_FLEXCAN1_TX 1
+#define SC_P_FLEXCAN1_TX_ADMA_DMA0_REQ_IN0 SC_P_FLEXCAN1_TX 2
+#define SC_P_FLEXCAN1_TX_ADMA_SAI1_RXD SC_P_FLEXCAN1_TX 3
+#define SC_P_FLEXCAN1_TX_LSIO_GPIO1_IO18 SC_P_FLEXCAN1_TX 4
+#define SC_P_FLEXCAN2_RX_ADMA_FLEXCAN2_RX SC_P_FLEXCAN2_RX 0
+#define SC_P_FLEXCAN2_RX_ADMA_SAI3_RXD SC_P_FLEXCAN2_RX 1
+#define SC_P_FLEXCAN2_RX_ADMA_UART3_RX SC_P_FLEXCAN2_RX 2
+#define SC_P_FLEXCAN2_RX_ADMA_SAI1_RXFS SC_P_FLEXCAN2_RX 3
+#define SC_P_FLEXCAN2_RX_LSIO_GPIO1_IO19 SC_P_FLEXCAN2_RX 4
+#define SC_P_FLEXCAN2_TX_ADMA_FLEXCAN2_TX SC_P_FLEXCAN2_TX 0
+#define SC_P_FLEXCAN2_TX_ADMA_SAI3_RXFS SC_P_FLEXCAN2_TX 1
+#define SC_P_FLEXCAN2_TX_ADMA_UART3_TX SC_P_FLEXCAN2_TX 2
+#define SC_P_FLEXCAN2_TX_ADMA_SAI1_RXC SC_P_FLEXCAN2_TX 3
+#define SC_P_FLEXCAN2_TX_LSIO_GPIO1_IO20 SC_P_FLEXCAN2_TX 4
+#define SC_P_UART0_RX_ADMA_UART0_RX SC_P_UART0_RX 0
+#define SC_P_UART0_RX_ADMA_MQS_R SC_P_UART0_RX 1
+#define SC_P_UART0_RX_ADMA_FLEXCAN0_RX SC_P_UART0_RX 2
+#define SC_P_UART0_RX_SCU_UART0_RX SC_P_UART0_RX 3
+#define SC_P_UART0_RX_LSIO_GPIO1_IO21 SC_P_UART0_RX 4
+#define SC_P_UART0_TX_ADMA_UART0_TX SC_P_UART0_TX 0
+#define SC_P_UART0_TX_ADMA_MQS_L SC_P_UART0_TX 1
+#define SC_P_UART0_TX_ADMA_FLEXCAN0_TX SC_P_UART0_TX 2
+#define SC_P_UART0_TX_SCU_UART0_TX SC_P_UART0_TX 3
+#define SC_P_UART0_TX_LSIO_GPIO1_IO22 SC_P_UART0_TX 4
+#define SC_P_UART2_TX_ADMA_UART2_TX SC_P_UART2_TX 0
+#define SC_P_UART2_TX_ADMA_FTM_CH1 SC_P_UART2_TX 1
+#define SC_P_UART2_TX_ADMA_FLEXCAN1_TX SC_P_UART2_TX 2
+#define SC_P_UART2_TX_LSIO_GPIO1_IO23 SC_P_UART2_TX 4
+#define SC_P_UART2_RX_ADMA_UART2_RX SC_P_UART2_RX 0
+#define SC_P_UART2_RX_ADMA_FTM_CH0 SC_P_UART2_RX 1
+#define SC_P_UART2_RX_ADMA_FLEXCAN1_RX SC_P_UART2_RX 2
+#define SC_P_UART2_RX_LSIO_GPIO1_IO24 SC_P_UART2_RX 4
+#define SC_P_MIPI_DSI0_I2C0_SCL_MIPI_DSI0_I2C0_SCL SC_P_MIPI_DSI0_I2C0_SCL 0
+#define SC_P_MIPI_DSI0_I2C0_SCL_MIPI_DSI1_GPIO0_IO02 SC_P_MIPI_DSI0_I2C0_SCL 1
+#define SC_P_MIPI_DSI0_I2C0_SCL_LSIO_GPIO1_IO25 SC_P_MIPI_DSI0_I2C0_SCL 4
+#define SC_P_MIPI_DSI0_I2C0_SDA_MIPI_DSI0_I2C0_SDA SC_P_MIPI_DSI0_I2C0_SDA 0
+#define SC_P_MIPI_DSI0_I2C0_SDA_MIPI_DSI1_GPIO0_IO03 SC_P_MIPI_DSI0_I2C0_SDA 1
+#define SC_P_MIPI_DSI0_I2C0_SDA_LSIO_GPIO1_IO26 SC_P_MIPI_DSI0_I2C0_SDA 4
+#define SC_P_MIPI_DSI0_GPIO0_00_MIPI_DSI0_GPIO0_IO00 SC_P_MIPI_DSI0_GPIO0_00 0
+#define SC_P_MIPI_DSI0_GPIO0_00_ADMA_I2C1_SCL SC_P_MIPI_DSI0_GPIO0_00 1
+#define SC_P_MIPI_DSI0_GPIO0_00_MIPI_DSI0_PWM0_OUT SC_P_MIPI_DSI0_GPIO0_00 2
+#define SC_P_MIPI_DSI0_GPIO0_00_LSIO_GPIO1_IO27 SC_P_MIPI_DSI0_GPIO0_00 4
+#define SC_P_MIPI_DSI0_GPIO0_01_MIPI_DSI0_GPIO0_IO01 SC_P_MIPI_DSI0_GPIO0_01 0
+#define SC_P_MIPI_DSI0_GPIO0_01_ADMA_I2C1_SDA SC_P_MIPI_DSI0_GPIO0_01 1
+#define SC_P_MIPI_DSI0_GPIO0_01_LSIO_GPIO1_IO28 SC_P_MIPI_DSI0_GPIO0_01 4
+#define SC_P_MIPI_DSI1_I2C0_SCL_MIPI_DSI1_I2C0_SCL SC_P_MIPI_DSI1_I2C0_SCL 0
+#define SC_P_MIPI_DSI1_I2C0_SCL_MIPI_DSI0_GPIO0_IO02 SC_P_MIPI_DSI1_I2C0_SCL 1
+#define SC_P_MIPI_DSI1_I2C0_SCL_LSIO_GPIO1_IO29 SC_P_MIPI_DSI1_I2C0_SCL 4
+#define SC_P_MIPI_DSI1_I2C0_SDA_MIPI_DSI1_I2C0_SDA SC_P_MIPI_DSI1_I2C0_SDA 0
+#define SC_P_MIPI_DSI1_I2C0_SDA_MIPI_DSI0_GPIO0_IO03 SC_P_MIPI_DSI1_I2C0_SDA 1
+#define SC_P_MIPI_DSI1_I2C0_SDA_LSIO_GPIO1_IO30 SC_P_MIPI_DSI1_I2C0_SDA 4
+#define SC_P_MIPI_DSI1_GPIO0_00_MIPI_DSI1_GPIO0_IO00 SC_P_MIPI_DSI1_GPIO0_00 0
+#define SC_P_MIPI_DSI1_GPIO0_00_ADMA_I2C2_SCL SC_P_MIPI_DSI1_GPIO0_00 1
+#define SC_P_MIPI_DSI1_GPIO0_00_MIPI_DSI1_PWM0_OUT SC_P_MIPI_DSI1_GPIO0_00 2
+#define SC_P_MIPI_DSI1_GPIO0_00_LSIO_GPIO1_IO31 SC_P_MIPI_DSI1_GPIO0_00 4
+#define SC_P_MIPI_DSI1_GPIO0_01_MIPI_DSI1_GPIO0_IO01 SC_P_MIPI_DSI1_GPIO0_01 0
+#define SC_P_MIPI_DSI1_GPIO0_01_ADMA_I2C2_SDA SC_P_MIPI_DSI1_GPIO0_01 1
+#define SC_P_MIPI_DSI1_GPIO0_01_LSIO_GPIO2_IO00 SC_P_MIPI_DSI1_GPIO0_01 4
+#define SC_P_JTAG_TRST_B_SCU_JTAG_TRST_B SC_P_JTAG_TRST_B 0
+#define SC_P_JTAG_TRST_B_SCU_WDOG0_WDOG_OUT SC_P_JTAG_TRST_B 1
+#define SC_P_PMIC_I2C_SCL_SCU_PMIC_I2C_SCL SC_P_PMIC_I2C_SCL 0
+#define SC_P_PMIC_I2C_SCL_SCU_GPIO0_IOXX_PMIC_A35_ON SC_P_PMIC_I2C_SCL 1
+#define SC_P_PMIC_I2C_SCL_LSIO_GPIO2_IO01 SC_P_PMIC_I2C_SCL 4
+#define SC_P_PMIC_I2C_SDA_SCU_PMIC_I2C_SDA SC_P_PMIC_I2C_SDA 0
+#define SC_P_PMIC_I2C_SDA_SCU_GPIO0_IOXX_PMIC_GPU_ON SC_P_PMIC_I2C_SDA 1
+#define SC_P_PMIC_I2C_SDA_LSIO_GPIO2_IO02 SC_P_PMIC_I2C_SDA 4
+#define SC_P_PMIC_INT_B_SCU_DSC_PMIC_INT_B SC_P_PMIC_INT_B 0
+#define SC_P_SCU_GPIO0_00_SCU_GPIO0_IO00 SC_P_SCU_GPIO0_00 0
+#define SC_P_SCU_GPIO0_00_SCU_UART0_RX SC_P_SCU_GPIO0_00 1
+#define SC_P_SCU_GPIO0_00_M40_UART0_RX SC_P_SCU_GPIO0_00 2
+#define SC_P_SCU_GPIO0_00_ADMA_UART3_RX SC_P_SCU_GPIO0_00 3
+#define SC_P_SCU_GPIO0_00_LSIO_GPIO2_IO03 SC_P_SCU_GPIO0_00 4
+#define SC_P_SCU_GPIO0_01_SCU_GPIO0_IO01 SC_P_SCU_GPIO0_01 0
+#define SC_P_SCU_GPIO0_01_SCU_UART0_TX SC_P_SCU_GPIO0_01 1
+#define SC_P_SCU_GPIO0_01_M40_UART0_TX SC_P_SCU_GPIO0_01 2
+#define SC_P_SCU_GPIO0_01_ADMA_UART3_TX SC_P_SCU_GPIO0_01 3
+#define SC_P_SCU_GPIO0_01_SCU_WDOG0_WDOG_OUT SC_P_SCU_GPIO0_01 4
+#define SC_P_SCU_PMIC_STANDBY_SCU_DSC_PMIC_STANDBY SC_P_SCU_PMIC_STANDBY 0
+#define SC_P_SCU_BOOT_MODE0_SCU_DSC_BOOT_MODE0 SC_P_SCU_BOOT_MODE0 0
+#define SC_P_SCU_BOOT_MODE1_SCU_DSC_BOOT_MODE1 SC_P_SCU_BOOT_MODE1 0
+#define SC_P_SCU_BOOT_MODE2_SCU_DSC_BOOT_MODE2 SC_P_SCU_BOOT_MODE2 0
+#define SC_P_SCU_BOOT_MODE2_SCU_PMIC_I2C_SDA SC_P_SCU_BOOT_MODE2 1
+#define SC_P_SCU_BOOT_MODE3_SCU_DSC_BOOT_MODE3 SC_P_SCU_BOOT_MODE3 0
+#define SC_P_SCU_BOOT_MODE3_SCU_PMIC_I2C_SCL SC_P_SCU_BOOT_MODE3 1
+#define SC_P_SCU_BOOT_MODE3_SCU_DSC_RTC_CLOCK_OUTPUT_32K SC_P_SCU_BOOT_MODE3 3
+#define SC_P_CSI_D00_CI_PI_D02 SC_P_CSI_D00 0
+#define SC_P_CSI_D00_ADMA_SAI0_RXC SC_P_CSI_D00 2
+#define SC_P_CSI_D01_CI_PI_D03 SC_P_CSI_D01 0
+#define SC_P_CSI_D01_ADMA_SAI0_RXD SC_P_CSI_D01 2
+#define SC_P_CSI_D02_CI_PI_D04 SC_P_CSI_D02 0
+#define SC_P_CSI_D02_ADMA_SAI0_RXFS SC_P_CSI_D02 2
+#define SC_P_CSI_D03_CI_PI_D05 SC_P_CSI_D03 0
+#define SC_P_CSI_D03_ADMA_SAI2_RXC SC_P_CSI_D03 2
+#define SC_P_CSI_D04_CI_PI_D06 SC_P_CSI_D04 0
+#define SC_P_CSI_D04_ADMA_SAI2_RXD SC_P_CSI_D04 2
+#define SC_P_CSI_D05_CI_PI_D07 SC_P_CSI_D05 0
+#define SC_P_CSI_D05_ADMA_SAI2_RXFS SC_P_CSI_D05 2
+#define SC_P_CSI_D06_CI_PI_D08 SC_P_CSI_D06 0
+#define SC_P_CSI_D06_ADMA_SAI3_RXC SC_P_CSI_D06 2
+#define SC_P_CSI_D07_CI_PI_D09 SC_P_CSI_D07 0
+#define SC_P_CSI_D07_ADMA_SAI3_RXD SC_P_CSI_D07 2
+#define SC_P_CSI_HSYNC_CI_PI_HSYNC SC_P_CSI_HSYNC 0
+#define SC_P_CSI_HSYNC_CI_PI_D00 SC_P_CSI_HSYNC 1
+#define SC_P_CSI_HSYNC_ADMA_SAI3_RXFS SC_P_CSI_HSYNC 2
+#define SC_P_CSI_VSYNC_CI_PI_VSYNC SC_P_CSI_VSYNC 0
+#define SC_P_CSI_VSYNC_CI_PI_D01 SC_P_CSI_VSYNC 1
+#define SC_P_CSI_PCLK_CI_PI_PCLK SC_P_CSI_PCLK 0
+#define SC_P_CSI_PCLK_MIPI_CSI0_I2C0_SCL SC_P_CSI_PCLK 1
+#define SC_P_CSI_PCLK_ADMA_SPI1_SCK SC_P_CSI_PCLK 3
+#define SC_P_CSI_PCLK_LSIO_GPIO3_IO00 SC_P_CSI_PCLK 4
+#define SC_P_CSI_MCLK_CI_PI_MCLK SC_P_CSI_MCLK 0
+#define SC_P_CSI_MCLK_MIPI_CSI0_I2C0_SDA SC_P_CSI_MCLK 1
+#define SC_P_CSI_MCLK_ADMA_SPI1_SDO SC_P_CSI_MCLK 3
+#define SC_P_CSI_MCLK_LSIO_GPIO3_IO01 SC_P_CSI_MCLK 4
+#define SC_P_CSI_EN_CI_PI_EN SC_P_CSI_EN 0
+#define SC_P_CSI_EN_CI_PI_I2C_SCL SC_P_CSI_EN 1
+#define SC_P_CSI_EN_ADMA_I2C3_SCL SC_P_CSI_EN 2
+#define SC_P_CSI_EN_ADMA_SPI1_SDI SC_P_CSI_EN 3
+#define SC_P_CSI_EN_LSIO_GPIO3_IO02 SC_P_CSI_EN 4
+#define SC_P_CSI_RESET_CI_PI_RESET SC_P_CSI_RESET 0
+#define SC_P_CSI_RESET_CI_PI_I2C_SDA SC_P_CSI_RESET 1
+#define SC_P_CSI_RESET_ADMA_I2C3_SDA SC_P_CSI_RESET 2
+#define SC_P_CSI_RESET_ADMA_SPI1_CS0 SC_P_CSI_RESET 3
+#define SC_P_CSI_RESET_LSIO_GPIO3_IO03 SC_P_CSI_RESET 4
+#define SC_P_MIPI_CSI0_MCLK_OUT_MIPI_CSI0_ACM_MCLK_OUT SC_P_MIPI_CSI0_MCLK_OUT 0
+#define SC_P_MIPI_CSI0_MCLK_OUT_LSIO_GPIO3_IO04 SC_P_MIPI_CSI0_MCLK_OUT 4
+#define SC_P_MIPI_CSI0_I2C0_SCL_MIPI_CSI0_I2C0_SCL SC_P_MIPI_CSI0_I2C0_SCL 0
+#define SC_P_MIPI_CSI0_I2C0_SCL_MIPI_CSI0_GPIO0_IO02 SC_P_MIPI_CSI0_I2C0_SCL 1
+#define SC_P_MIPI_CSI0_I2C0_SCL_LSIO_GPIO3_IO05 SC_P_MIPI_CSI0_I2C0_SCL 4
+#define SC_P_MIPI_CSI0_I2C0_SDA_MIPI_CSI0_I2C0_SDA SC_P_MIPI_CSI0_I2C0_SDA 0
+#define SC_P_MIPI_CSI0_I2C0_SDA_MIPI_CSI0_GPIO0_IO03 SC_P_MIPI_CSI0_I2C0_SDA 1
+#define SC_P_MIPI_CSI0_I2C0_SDA_LSIO_GPIO3_IO06 SC_P_MIPI_CSI0_I2C0_SDA 4
+#define SC_P_MIPI_CSI0_GPIO0_01_MIPI_CSI0_GPIO0_IO01 SC_P_MIPI_CSI0_GPIO0_01 0
+#define SC_P_MIPI_CSI0_GPIO0_01_ADMA_I2C0_SDA SC_P_MIPI_CSI0_GPIO0_01 1
+#define SC_P_MIPI_CSI0_GPIO0_01_LSIO_GPIO3_IO07 SC_P_MIPI_CSI0_GPIO0_01 4
+#define SC_P_MIPI_CSI0_GPIO0_00_MIPI_CSI0_GPIO0_IO00 SC_P_MIPI_CSI0_GPIO0_00 0
+#define SC_P_MIPI_CSI0_GPIO0_00_ADMA_I2C0_SCL SC_P_MIPI_CSI0_GPIO0_00 1
+#define SC_P_MIPI_CSI0_GPIO0_00_LSIO_GPIO3_IO08 SC_P_MIPI_CSI0_GPIO0_00 4
+#define SC_P_QSPI0A_DATA0_LSIO_QSPI0A_DATA0 SC_P_QSPI0A_DATA0 0
+#define SC_P_QSPI0A_DATA0_LSIO_GPIO3_IO09 SC_P_QSPI0A_DATA0 4
+#define SC_P_QSPI0A_DATA1_LSIO_QSPI0A_DATA1 SC_P_QSPI0A_DATA1 0
+#define SC_P_QSPI0A_DATA1_LSIO_GPIO3_IO10 SC_P_QSPI0A_DATA1 4
+#define SC_P_QSPI0A_DATA2_LSIO_QSPI0A_DATA2 SC_P_QSPI0A_DATA2 0
+#define SC_P_QSPI0A_DATA2_LSIO_GPIO3_IO11 SC_P_QSPI0A_DATA2 4
+#define SC_P_QSPI0A_DATA3_LSIO_QSPI0A_DATA3 SC_P_QSPI0A_DATA3 0
+#define SC_P_QSPI0A_DATA3_LSIO_GPIO3_IO12 SC_P_QSPI0A_DATA3 4
+#define SC_P_QSPI0A_DQS_LSIO_QSPI0A_DQS SC_P_QSPI0A_DQS 0
+#define SC_P_QSPI0A_DQS_LSIO_GPIO3_IO13 SC_P_QSPI0A_DQS 4
+#define SC_P_QSPI0A_SS0_B_LSIO_QSPI0A_SS0_B SC_P_QSPI0A_SS0_B 0
+#define SC_P_QSPI0A_SS0_B_LSIO_GPIO3_IO14 SC_P_QSPI0A_SS0_B 4
+#define SC_P_QSPI0A_SS1_B_LSIO_QSPI0A_SS1_B SC_P_QSPI0A_SS1_B 0
+#define SC_P_QSPI0A_SS1_B_LSIO_GPIO3_IO15 SC_P_QSPI0A_SS1_B 4
+#define SC_P_QSPI0A_SCLK_LSIO_QSPI0A_SCLK SC_P_QSPI0A_SCLK 0
+#define SC_P_QSPI0A_SCLK_LSIO_GPIO3_IO16 SC_P_QSPI0A_SCLK 4
+#define SC_P_QSPI0B_SCLK_LSIO_QSPI0B_SCLK SC_P_QSPI0B_SCLK 0
+#define SC_P_QSPI0B_SCLK_LSIO_QSPI1A_SCLK SC_P_QSPI0B_SCLK 1
+#define SC_P_QSPI0B_SCLK_LSIO_KPP0_COL0 SC_P_QSPI0B_SCLK 2
+#define SC_P_QSPI0B_SCLK_LSIO_GPIO3_IO17 SC_P_QSPI0B_SCLK 4
+#define SC_P_QSPI0B_DATA0_LSIO_QSPI0B_DATA0 SC_P_QSPI0B_DATA0 0
+#define SC_P_QSPI0B_DATA0_LSIO_QSPI1A_DATA0 SC_P_QSPI0B_DATA0 1
+#define SC_P_QSPI0B_DATA0_LSIO_KPP0_COL1 SC_P_QSPI0B_DATA0 2
+#define SC_P_QSPI0B_DATA0_LSIO_GPIO3_IO18 SC_P_QSPI0B_DATA0 4
+#define SC_P_QSPI0B_DATA1_LSIO_QSPI0B_DATA1 SC_P_QSPI0B_DATA1 0
+#define SC_P_QSPI0B_DATA1_LSIO_QSPI1A_DATA1 SC_P_QSPI0B_DATA1 1
+#define SC_P_QSPI0B_DATA1_LSIO_KPP0_COL2 SC_P_QSPI0B_DATA1 2
+#define SC_P_QSPI0B_DATA1_LSIO_GPIO3_IO19 SC_P_QSPI0B_DATA1 4
+#define SC_P_QSPI0B_DATA2_LSIO_QSPI0B_DATA2 SC_P_QSPI0B_DATA2 0
+#define SC_P_QSPI0B_DATA2_LSIO_QSPI1A_DATA2 SC_P_QSPI0B_DATA2 1
+#define SC_P_QSPI0B_DATA2_LSIO_KPP0_COL3 SC_P_QSPI0B_DATA2 2
+#define SC_P_QSPI0B_DATA2_LSIO_GPIO3_IO20 SC_P_QSPI0B_DATA2 4
+#define SC_P_QSPI0B_DATA3_LSIO_QSPI0B_DATA3 SC_P_QSPI0B_DATA3 0
+#define SC_P_QSPI0B_DATA3_LSIO_QSPI1A_DATA3 SC_P_QSPI0B_DATA3 1
+#define SC_P_QSPI0B_DATA3_LSIO_KPP0_ROW0 SC_P_QSPI0B_DATA3 2
+#define SC_P_QSPI0B_DATA3_LSIO_GPIO3_IO21 SC_P_QSPI0B_DATA3 4
+#define SC_P_QSPI0B_DQS_LSIO_QSPI0B_DQS SC_P_QSPI0B_DQS 0
+#define SC_P_QSPI0B_DQS_LSIO_QSPI1A_DQS SC_P_QSPI0B_DQS 1
+#define SC_P_QSPI0B_DQS_LSIO_KPP0_ROW1 SC_P_QSPI0B_DQS 2
+#define SC_P_QSPI0B_DQS_LSIO_GPIO3_IO22 SC_P_QSPI0B_DQS 4
+#define SC_P_QSPI0B_SS0_B_LSIO_QSPI0B_SS0_B SC_P_QSPI0B_SS0_B 0
+#define SC_P_QSPI0B_SS0_B_LSIO_QSPI1A_SS0_B SC_P_QSPI0B_SS0_B 1
+#define SC_P_QSPI0B_SS0_B_LSIO_KPP0_ROW2 SC_P_QSPI0B_SS0_B 2
+#define SC_P_QSPI0B_SS0_B_LSIO_GPIO3_IO23 SC_P_QSPI0B_SS0_B 4
+#define SC_P_QSPI0B_SS1_B_LSIO_QSPI0B_SS1_B SC_P_QSPI0B_SS1_B 0
+#define SC_P_QSPI0B_SS1_B_LSIO_QSPI1A_SS1_B SC_P_QSPI0B_SS1_B 1
+#define SC_P_QSPI0B_SS1_B_LSIO_KPP0_ROW3 SC_P_QSPI0B_SS1_B 2
+#define SC_P_QSPI0B_SS1_B_LSIO_GPIO3_IO24 SC_P_QSPI0B_SS1_B 4
+/*@}*/
+
+/*!
+ * @name Fake Pad Mux Definitions
+ * format: name padid 0
+ */
+/*@{*/
+#define SC_P_COMP_CTL_GPIO_1V8_3V3_PCIESEP_PAD SC_P_COMP_CTL_GPIO_1V8_3V3_PCIESEP 0
+#define SC_P_COMP_CTL_GPIO_3V3_USB3IO_PAD SC_P_COMP_CTL_GPIO_3V3_USB3IO 0
+#define SC_P_COMP_CTL_GPIO_1V8_3V3_SD1FIX0_PAD SC_P_COMP_CTL_GPIO_1V8_3V3_SD1FIX0 0
+#define SC_P_COMP_CTL_GPIO_1V8_3V3_SD1FIX1_PAD SC_P_COMP_CTL_GPIO_1V8_3V3_SD1FIX1 0
+#define SC_P_COMP_CTL_GPIO_1V8_3V3_VSELSEP_PAD SC_P_COMP_CTL_GPIO_1V8_3V3_VSELSEP 0
+#define SC_P_COMP_CTL_GPIO_1V8_3V3_VSEL3_PAD SC_P_COMP_CTL_GPIO_1V8_3V3_VSEL3 0
+#define SC_P_COMP_CTL_GPIO_1V8_3V3_ENET_ENETB0_PAD SC_P_COMP_CTL_GPIO_1V8_3V3_ENET_ENETB0 0
+#define SC_P_COMP_CTL_GPIO_1V8_3V3_ENET_ENETB1_PAD SC_P_COMP_CTL_GPIO_1V8_3V3_ENET_ENETB1 0
+#define SC_P_COMP_CTL_GPIO_1V8_3V3_GPIOCT_PAD SC_P_COMP_CTL_GPIO_1V8_3V3_GPIOCT 0
+#define SC_P_COMP_CTL_GPIO_1V8_3V3_GPIORHB_PAD SC_P_COMP_CTL_GPIO_1V8_3V3_GPIORHB 0
+#define SC_P_COMP_CTL_GPIO_1V8_3V3_GPIORHK_PAD SC_P_COMP_CTL_GPIO_1V8_3V3_GPIORHK 0
+#define SC_P_COMP_CTL_GPIO_1V8_3V3_GPIORHT_PAD SC_P_COMP_CTL_GPIO_1V8_3V3_GPIORHT 0
+#define SC_P_COMP_CTL_GPIO_1V8_3V3_GPIOLH_PAD SC_P_COMP_CTL_GPIO_1V8_3V3_GPIOLH 0
+#define SC_P_COMP_CTL_GPIO_1V8_3V3_MIPIDSIGPIO_PAD SC_P_COMP_CTL_GPIO_1V8_3V3_MIPIDSIGPIO 0
+#define SC_P_COMP_CTL_GPIO_1V8_3V3_GPIORHD_PAD SC_P_COMP_CTL_GPIO_1V8_3V3_GPIORHD 0
+#define SC_P_COMP_CTL_GPIO_1V8_3V3_QSPI0A_PAD SC_P_COMP_CTL_GPIO_1V8_3V3_QSPI0A 0
+#define SC_P_COMP_CTL_GPIO_1V8_3V3_QSPI0B_PAD SC_P_COMP_CTL_GPIO_1V8_3V3_QSPI0B 0
+/*@}*/
+
+#endif /* SC_PADS_H */
diff --git a/include/dt-bindings/pinctrl/pins-imx8mm.h b/include/dt-bindings/pinctrl/pins-imx8mm.h
new file mode 100644
index 000000000000..b2db829ef96e
--- /dev/null
+++ b/include/dt-bindings/pinctrl/pins-imx8mm.h
@@ -0,0 +1,638 @@
+/*
+ * Copyright 2017-2018 NXP
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __DTS_IMX8MM_PINFUNC_H
+#define __DTS_IMX8MM_PINFUNC_H
+
+/*
+ * The pin function ID is a tuple of
+ * <mux_reg conf_reg input_reg mux_mode input_val>
+ */
+
+#define MX8MM_IOMUXC_GPIO1_IO00_GPIO1_IO0 0x028 0x290 0x000 0x0 0x0
+#define MX8MM_IOMUXC_GPIO1_IO00_CCMSRCGPCMIX_ENET_PHY_REF_CLK_ROOT 0x028 0x290 0x4C0 0x1 0x0
+#define MX8MM_IOMUXC_GPIO1_IO00_ANAMIX_REF_CLK_32K 0x028 0x290 0x000 0x5 0x0
+#define MX8MM_IOMUXC_GPIO1_IO00_CCMSRCGPCMIX_EXT_CLK1 0x028 0x290 0x000 0x6 0x0
+#define MX8MM_IOMUXC_GPIO1_IO00_SJC_FAIL 0x028 0x290 0x000 0x7 0x0
+#define MX8MM_IOMUXC_GPIO1_IO01_GPIO1_IO1 0x02C 0x294 0x000 0x0 0x0
+#define MX8MM_IOMUXC_GPIO1_IO01_PWM1_OUT 0x02C 0x294 0x000 0x1 0x0
+#define MX8MM_IOMUXC_GPIO1_IO01_ANAMIX_REF_CLK_24M 0x02C 0x294 0x4BC 0x5 0x0
+#define MX8MM_IOMUXC_GPIO1_IO01_CCMSRCGPCMIX_EXT_CLK2 0x02C 0x294 0x000 0x6 0x0
+#define MX8MM_IOMUXC_GPIO1_IO01_SJC_ACTIVE 0x02C 0x294 0x000 0x7 0x0
+#define MX8MM_IOMUXC_GPIO1_IO02_GPIO1_IO2 0x030 0x298 0x000 0x0 0x0
+#define MX8MM_IOMUXC_GPIO1_IO02_WDOG1_WDOG_B 0x030 0x298 0x000 0x1 0x0
+#define MX8MM_IOMUXC_GPIO1_IO02_WDOG1_WDOG_ANY 0x030 0x298 0x000 0x5 0x0
+#define MX8MM_IOMUXC_GPIO1_IO02_SJC_DE_B 0x030 0x298 0x000 0x7 0x0
+#define MX8MM_IOMUXC_GPIO1_IO03_GPIO1_IO3 0x034 0x29C 0x000 0x0 0x0
+#define MX8MM_IOMUXC_GPIO1_IO03_USDHC1_VSELECT 0x034 0x29C 0x000 0x1 0x0
+#define MX8MM_IOMUXC_GPIO1_IO03_SDMA1_EXT_EVENT0 0x034 0x29C 0x000 0x5 0x0
+#define MX8MM_IOMUXC_GPIO1_IO03_ANAMIX_XTAL_OK 0x034 0x29C 0x000 0x6 0x0
+#define MX8MM_IOMUXC_GPIO1_IO03_SJC_DONE 0x034 0x29C 0x000 0x7 0x0
+#define MX8MM_IOMUXC_GPIO1_IO04_GPIO1_IO4 0x038 0x2A0 0x000 0x0 0x0
+#define MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0x038 0x2A0 0x000 0x1 0x0
+#define MX8MM_IOMUXC_GPIO1_IO04_SDMA1_EXT_EVENT1 0x038 0x2A0 0x000 0x5 0x0
+#define MX8MM_IOMUXC_GPIO1_IO04_ANAMIX_XTAL_OK_LV 0x038 0x2A0 0x000 0x6 0x0
+#define MX8MM_IOMUXC_GPIO1_IO04_USDHC1_TEST_TRIG 0x038 0x2A0 0x000 0x7 0x0
+#define MX8MM_IOMUXC_GPIO1_IO05_GPIO1_IO5 0x03C 0x2A4 0x000 0x0 0x0
+#define MX8MM_IOMUXC_GPIO1_IO05_M4_NMI 0x03C 0x2A4 0x000 0x1 0x0
+#define MX8MM_IOMUXC_GPIO1_IO05_CCMSRCGPCMIX_PMIC_READY 0x03C 0x2A4 0x000 0x5 0x0
+#define MX8MM_IOMUXC_GPIO1_IO05_CCMSRCGPCMIX_INT_BOOT 0x03C 0x2A4 0x000 0x6 0x0
+#define MX8MM_IOMUXC_GPIO1_IO05_USDHC2_TEST_TRIG 0x03C 0x2A4 0x000 0x7 0x0
+#define MX8MM_IOMUXC_GPIO1_IO06_GPIO1_IO6 0x040 0x2A8 0x000 0x0 0x0
+#define MX8MM_IOMUXC_GPIO1_IO06_ENET1_MDC 0x040 0x2A8 0x000 0x1 0x0
+#define MX8MM_IOMUXC_GPIO1_IO06_USDHC1_CD_B 0x040 0x2A8 0x000 0x5 0x0
+#define MX8MM_IOMUXC_GPIO1_IO06_CCMSRCGPCMIX_EXT_CLK3 0x040 0x2A8 0x000 0x6 0x0
+#define MX8MM_IOMUXC_GPIO1_IO06_ECSPI1_TEST_TRIG 0x040 0x2A8 0x000 0x7 0x0
+#define MX8MM_IOMUXC_GPIO1_IO07_GPIO1_IO7 0x044 0x2AC 0x000 0x0 0x0
+#define MX8MM_IOMUXC_GPIO1_IO07_ENET1_MDIO 0x044 0x2AC 0x000 0x1 0x0
+#define MX8MM_IOMUXC_GPIO1_IO07_USDHC1_WP 0x044 0x2AC 0x000 0x5 0x0
+#define MX8MM_IOMUXC_GPIO1_IO07_CCMSRCGPCMIX_EXT_CLK4 0x044 0x2AC 0x000 0x6 0x0
+#define MX8MM_IOMUXC_GPIO1_IO07_ECSPI2_TEST_TRIG 0x044 0x2AC 0x000 0x7 0x0
+#define MX8MM_IOMUXC_GPIO1_IO08_GPIO1_IO8 0x048 0x2B0 0x000 0x0 0x0
+#define MX8MM_IOMUXC_GPIO1_IO08_ENET1_1588_EVENT0_IN 0x048 0x2B0 0x000 0x1 0x0
+#define MX8MM_IOMUXC_GPIO1_IO08_USDHC2_RESET_B 0x048 0x2B0 0x000 0x5 0x0
+#define MX8MM_IOMUXC_GPIO1_IO08_CCMSRCGPCMIX_WAIT 0x048 0x2B0 0x000 0x6 0x0
+#define MX8MM_IOMUXC_GPIO1_IO08_QSPI_TEST_TRIG 0x048 0x2B0 0x000 0x7 0x0
+#define MX8MM_IOMUXC_GPIO1_IO09_GPIO1_IO9 0x04C 0x2B4 0x000 0x0 0x0
+#define MX8MM_IOMUXC_GPIO1_IO09_ENET1_1588_EVENT0_OUT 0x04C 0x2B4 0x000 0x1 0x0
+#define MX8MM_IOMUXC_GPIO1_IO09_SDMA2_EXT_EVENT0 0x04C 0x2B4 0x000 0x5 0x0
+#define MX8MM_IOMUXC_GPIO1_IO09_CCMSRCGPCMIX_STOP 0x04C 0x2B4 0x000 0x6 0x0
+#define MX8MM_IOMUXC_GPIO1_IO09_RAWNAND_TEST_TRIG 0x04C 0x2B4 0x000 0x7 0x0
+#define MX8MM_IOMUXC_GPIO1_IO10_GPIO1_IO10 0x050 0x2B8 0x000 0x0 0x0
+#define MX8MM_IOMUXC_GPIO1_IO10_USB1_OTG_ID 0x050 0x2B8 0x000 0x1 0x0
+#define MX8MM_IOMUXC_GPIO1_IO10_OCOTP_CTRL_WRAPPER_FUSE_LATCHED 0x050 0x2B8 0x000 0x7 0x0
+#define MX8MM_IOMUXC_GPIO1_IO11_GPIO1_IO11 0x054 0x2BC 0x000 0x0 0x0
+#define MX8MM_IOMUXC_GPIO1_IO11_USB2_OTG_ID 0x054 0x2BC 0x000 0x1 0x0
+#define MX8MM_IOMUXC_GPIO1_IO11_CCMSRCGPCMIX_PMIC_READY 0x054 0x2BC 0x4BC 0x5 0x1
+#define MX8MM_IOMUXC_GPIO1_IO11_CCMSRCGPCMIX_OUT0 0x054 0x2BC 0x000 0x6 0x0
+#define MX8MM_IOMUXC_GPIO1_IO11_CAAM_WRAPPER_RNG_OSC_OBS 0x054 0x2BC 0x000 0x7 0x0
+#define MX8MM_IOMUXC_GPIO1_IO12_GPIO1_IO12 0x058 0x2C0 0x000 0x0 0x0
+#define MX8MM_IOMUXC_GPIO1_IO12_USB1_OTG_PWR 0x058 0x2C0 0x000 0x1 0x0
+#define MX8MM_IOMUXC_GPIO1_IO12_SDMA2_EXT_EVENT1 0x058 0x2C0 0x000 0x5 0x0
+#define MX8MM_IOMUXC_GPIO1_IO12_CCMSRCGPCMIX_OUT1 0x058 0x2C0 0x000 0x6 0x0
+#define MX8MM_IOMUXC_GPIO1_IO12_CSU_CSU_ALARM_AUT0 0x058 0x2C0 0x000 0x7 0x0
+#define MX8MM_IOMUXC_GPIO1_IO13_GPIO1_IO13 0x05C 0x2C4 0x000 0x0 0x0
+#define MX8MM_IOMUXC_GPIO1_IO13_USB1_OTG_OC 0x05C 0x2C4 0x000 0x1 0x0
+#define MX8MM_IOMUXC_GPIO1_IO13_PWM2_OUT 0x05C 0x2C4 0x000 0x5 0x0
+#define MX8MM_IOMUXC_GPIO1_IO13_CCMSRCGPCMIX_OUT2 0x05C 0x2C4 0x000 0x6 0x0
+#define MX8MM_IOMUXC_GPIO1_IO13_CSU_CSU_ALARM_AUT1 0x05C 0x2C4 0x000 0x7 0x0
+#define MX8MM_IOMUXC_GPIO1_IO14_GPIO1_IO14 0x060 0x2C8 0x000 0x0 0x0
+#define MX8MM_IOMUXC_GPIO1_IO14_USB2_OTG_PWR 0x060 0x2C8 0x000 0x1 0x0
+#define MX8MM_IOMUXC_GPIO1_IO14_PWM3_OUT 0x060 0x2C8 0x000 0x5 0x0
+#define MX8MM_IOMUXC_GPIO1_IO14_CCMSRCGPCMIX_CLKO1 0x060 0x2C8 0x000 0x6 0x0
+#define MX8MM_IOMUXC_GPIO1_IO14_CSU_CSU_ALARM_AUT2 0x060 0x2C8 0x000 0x7 0x0
+#define MX8MM_IOMUXC_GPIO1_IO15_GPIO1_IO15 0x064 0x2CC 0x000 0x0 0x0
+#define MX8MM_IOMUXC_GPIO1_IO15_USB2_OTG_OC 0x064 0x2CC 0x000 0x1 0x0
+#define MX8MM_IOMUXC_GPIO1_IO15_PWM4_OUT 0x064 0x2CC 0x000 0x5 0x0
+#define MX8MM_IOMUXC_GPIO1_IO15_CCMSRCGPCMIX_CLKO2 0x064 0x2CC 0x000 0x6 0x0
+#define MX8MM_IOMUXC_GPIO1_IO15_CSU_CSU_INT_DEB 0x064 0x2CC 0x000 0x7 0x0
+#define MX8MM_IOMUXC_ENET_MDC_ENET1_MDC 0x068 0x2D0 0x000 0x0 0x0
+#define MX8MM_IOMUXC_ENET_MDC_GPIO1_IO16 0x068 0x2D0 0x000 0x5 0x0
+#define MX8MM_IOMUXC_ENET_MDIO_ENET1_MDIO 0x06C 0x2D4 0x4C0 0x0 0x1
+#define MX8MM_IOMUXC_ENET_MDIO_GPIO1_IO17 0x06C 0x2D4 0x000 0x5 0x0
+#define MX8MM_IOMUXC_ENET_TD3_ENET1_RGMII_TD3 0x070 0x2D8 0x000 0x0 0x0
+#define MX8MM_IOMUXC_ENET_TD3_GPIO1_IO18 0x070 0x2D8 0x000 0x5 0x0
+#define MX8MM_IOMUXC_ENET_TD2_ENET1_RGMII_TD2 0x074 0x2DC 0x000 0x0 0x0
+#define MX8MM_IOMUXC_ENET_TD2_ENET1_TX_CLK 0x074 0x2DC 0x000 0x1 0x0
+#define MX8MM_IOMUXC_ENET_TD2_GPIO1_IO19 0x074 0x2DC 0x000 0x5 0x0
+#define MX8MM_IOMUXC_ENET_TD1_ENET1_RGMII_TD1 0x078 0x2E0 0x000 0x0 0x0
+#define MX8MM_IOMUXC_ENET_TD1_GPIO1_IO20 0x078 0x2E0 0x000 0x5 0x0
+#define MX8MM_IOMUXC_ENET_TD0_ENET1_RGMII_TD0 0x07C 0x2E4 0x000 0x0 0x0
+#define MX8MM_IOMUXC_ENET_TD0_GPIO1_IO21 0x07C 0x2E4 0x000 0x5 0x0
+#define MX8MM_IOMUXC_ENET_TX_CTL_ENET1_RGMII_TX_CTL 0x080 0x2E8 0x000 0x0 0x0
+#define MX8MM_IOMUXC_ENET_TX_CTL_GPIO1_IO22 0x080 0x2E8 0x000 0x5 0x0
+#define MX8MM_IOMUXC_ENET_TXC_ENET1_RGMII_TXC 0x084 0x2EC 0x000 0x0 0x0
+#define MX8MM_IOMUXC_ENET_TXC_ENET1_TX_ER 0x084 0x2EC 0x000 0x1 0x0
+#define MX8MM_IOMUXC_ENET_TXC_GPIO1_IO23 0x084 0x2EC 0x000 0x5 0x0
+#define MX8MM_IOMUXC_ENET_RX_CTL_ENET1_RGMII_RX_CTL 0x088 0x2F0 0x000 0x0 0x0
+#define MX8MM_IOMUXC_ENET_RX_CTL_GPIO1_IO24 0x088 0x2F0 0x000 0x5 0x0
+#define MX8MM_IOMUXC_ENET_RXC_ENET1_RGMII_RXC 0x08C 0x2F4 0x000 0x0 0x0
+#define MX8MM_IOMUXC_ENET_RXC_ENET1_RX_ER 0x08C 0x2F4 0x000 0x1 0x0
+#define MX8MM_IOMUXC_ENET_RXC_GPIO1_IO25 0x08C 0x2F4 0x000 0x5 0x0
+#define MX8MM_IOMUXC_ENET_RD0_ENET1_RGMII_RD0 0x090 0x2F8 0x000 0x0 0x0
+#define MX8MM_IOMUXC_ENET_RD0_GPIO1_IO26 0x090 0x2F8 0x000 0x5 0x0
+#define MX8MM_IOMUXC_ENET_RD1_ENET1_RGMII_RD1 0x094 0x2FC 0x000 0x0 0x0
+#define MX8MM_IOMUXC_ENET_RD1_GPIO1_IO27 0x094 0x2FC 0x000 0x5 0x0
+#define MX8MM_IOMUXC_ENET_RD2_ENET1_RGMII_RD2 0x098 0x300 0x000 0x0 0x0
+#define MX8MM_IOMUXC_ENET_RD2_GPIO1_IO28 0x098 0x300 0x000 0x5 0x0
+#define MX8MM_IOMUXC_ENET_RD3_ENET1_RGMII_RD3 0x09C 0x304 0x000 0x0 0x0
+#define MX8MM_IOMUXC_ENET_RD3_GPIO1_IO29 0x09C 0x304 0x000 0x5 0x0
+#define MX8MM_IOMUXC_SD1_CLK_USDHC1_CLK 0x0A0 0x308 0x000 0x0 0x0
+#define MX8MM_IOMUXC_SD1_CLK_GPIO2_IO0 0x0A0 0x308 0x000 0x5 0x0
+#define MX8MM_IOMUXC_SD1_CMD_USDHC1_CMD 0x0A4 0x30C 0x000 0x0 0x0
+#define MX8MM_IOMUXC_SD1_CMD_GPIO2_IO1 0x0A4 0x30C 0x000 0x5 0x0
+#define MX8MM_IOMUXC_SD1_DATA0_USDHC1_DATA0 0x0A8 0x310 0x000 0x0 0x0
+#define MX8MM_IOMUXC_SD1_DATA0_GPIO2_IO2 0x0A8 0x31 0x000 0x5 0x0
+#define MX8MM_IOMUXC_SD1_DATA1_USDHC1_DATA1 0x0AC 0x314 0x000 0x0 0x0
+#define MX8MM_IOMUXC_SD1_DATA1_GPIO2_IO3 0x0AC 0x314 0x000 0x5 0x0
+#define MX8MM_IOMUXC_SD1_DATA2_USDHC1_DATA2 0x0B0 0x318 0x000 0x0 0x0
+#define MX8MM_IOMUXC_SD1_DATA2_GPIO2_IO4 0x0B0 0x318 0x000 0x5 0x0
+#define MX8MM_IOMUXC_SD1_DATA3_USDHC1_DATA3 0x0B4 0x31C 0x000 0x0 0x0
+#define MX8MM_IOMUXC_SD1_DATA3_GPIO2_IO5 0x0B4 0x31C 0x000 0x5 0x0
+#define MX8MM_IOMUXC_SD1_DATA4_USDHC1_DATA4 0x0B8 0x320 0x000 0x0 0x0
+#define MX8MM_IOMUXC_SD1_DATA4_GPIO2_IO6 0x0B8 0x320 0x000 0x5 0x0
+#define MX8MM_IOMUXC_SD1_DATA5_USDHC1_DATA5 0x0BC 0x324 0x000 0x0 0x0
+#define MX8MM_IOMUXC_SD1_DATA5_GPIO2_IO7 0x0BC 0x324 0x000 0x5 0x0
+#define MX8MM_IOMUXC_SD1_DATA6_USDHC1_DATA6 0x0C0 0x328 0x000 0x0 0x0
+#define MX8MM_IOMUXC_SD1_DATA6_GPIO2_IO8 0x0C0 0x328 0x000 0x5 0x0
+#define MX8MM_IOMUXC_SD1_DATA7_USDHC1_DATA7 0x0C4 0x32C 0x000 0x0 0x0
+#define MX8MM_IOMUXC_SD1_DATA7_GPIO2_IO9 0x0C4 0x32C 0x000 0x5 0x0
+#define MX8MM_IOMUXC_SD1_RESET_B_USDHC1_RESET_B 0x0C8 0x330 0x000 0x0 0x0
+#define MX8MM_IOMUXC_SD1_RESET_B_GPIO2_IO10 0x0C8 0x330 0x000 0x5 0x0
+#define MX8MM_IOMUXC_SD1_STROBE_USDHC1_STROBE 0x0CC 0x334 0x000 0x0 0x0
+#define MX8MM_IOMUXC_SD1_STROBE_GPIO2_IO11 0x0CC 0x334 0x000 0x5 0x0
+#define MX8MM_IOMUXC_SD2_CD_B_USDHC2_CD_B 0x0D0 0x338 0x000 0x0 0x0
+#define MX8MM_IOMUXC_SD2_CD_B_GPIO2_IO12 0x0D0 0x338 0x000 0x5 0x0
+#define MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK 0x0D4 0x33C 0x000 0x0 0x0
+#define MX8MM_IOMUXC_SD2_CLK_GPIO2_IO13 0x0D4 0x33C 0x000 0x5 0x0
+#define MX8MM_IOMUXC_SD2_CLK_CCMSRCGPCMIX_OBSERVE0 0x0D4 0x33C 0x000 0x6 0x0
+#define MX8MM_IOMUXC_SD2_CLK_OBSERVE_MUX_OUT0 0x0D4 0x33C 0x000 0x7 0x0
+#define MX8MM_IOMUXC_SD2_CMD_USDHC2_CMD 0x0D8 0x340 0x000 0x0 0x0
+#define MX8MM_IOMUXC_SD2_CMD_GPIO2_IO14 0x0D8 0x340 0x000 0x5 0x0
+#define MX8MM_IOMUXC_SD2_CMD_CCMSRCGPCMIX_OBSERVE1 0x0D8 0x340 0x000 0x6 0x0
+#define MX8MM_IOMUXC_SD2_CMD_OBSERVE_MUX_OUT1 0x0D8 0x340 0x000 0x7 0x0
+#define MX8MM_IOMUXC_SD2_DATA0_USDHC2_DATA0 0x0DC 0x344 0x000 0x0 0x0
+#define MX8MM_IOMUXC_SD2_DATA0_GPIO2_IO15 0x0DC 0x344 0x000 0x5 0x0
+#define MX8MM_IOMUXC_SD2_DATA0_CCMSRCGPCMIX_OBSERVE2 0x0DC 0x344 0x000 0x6 0x0
+#define MX8MM_IOMUXC_SD2_DATA0_OBSERVE_MUX_OUT2 0x0DC 0x344 0x000 0x7 0x0
+#define MX8MM_IOMUXC_SD2_DATA1_USDHC2_DATA1 0x0E0 0x348 0x000 0x0 0x0
+#define MX8MM_IOMUXC_SD2_DATA1_GPIO2_IO16 0x0E0 0x348 0x000 0x5 0x0
+#define MX8MM_IOMUXC_SD2_DATA1_CCMSRCGPCMIX_WAIT 0x0E0 0x348 0x000 0x6 0x0
+#define MX8MM_IOMUXC_SD2_DATA1_OBSERVE_MUX_OUT3 0x0E0 0x348 0x000 0x7 0x0
+#define MX8MM_IOMUXC_SD2_DATA2_USDHC2_DATA2 0x0E4 0x34C 0x000 0x0 0x0
+#define MX8MM_IOMUXC_SD2_DATA2_GPIO2_IO17 0x0E4 0x34C 0x000 0x5 0x0
+#define MX8MM_IOMUXC_SD2_DATA2_CCMSRCGPCMIX_STOP 0x0E4 0x34C 0x000 0x6 0x0
+#define MX8MM_IOMUXC_SD2_DATA2_OBSERVE_MUX_OUT4 0x0E4 0x34C 0x000 0x7 0x0
+#define MX8MM_IOMUXC_SD2_DATA3_USDHC2_DATA3 0x0E8 0x350 0x000 0x0 0x0
+#define MX8MM_IOMUXC_SD2_DATA3_GPIO2_IO18 0x0E8 0x350 0x000 0x5 0x0
+#define MX8MM_IOMUXC_SD2_DATA3_CCMSRCGPCMIX_EARLY_RESET 0x0E8 0x350 0x000 0x6 0x0
+#define MX8MM_IOMUXC_SD2_RESET_B_USDHC2_RESET_B 0x0EC 0x354 0x000 0x0 0x0
+#define MX8MM_IOMUXC_SD2_RESET_B_GPIO2_IO19 0x0EC 0x354 0x000 0x5 0x0
+#define MX8MM_IOMUXC_SD2_RESET_B_CCMSRCGPCMIX_SYSTEM_RESET 0x0EC 0x354 0x000 0x6 0x0
+#define MX8MM_IOMUXC_SD2_WP_USDHC2_WP 0x0F0 0x358 0x000 0x0 0x0
+#define MX8MM_IOMUXC_SD2_WP_GPIO2_IO20 0x0F0 0x358 0x000 0x5 0x0
+#define MX8MM_IOMUXC_SD2_WP_SIM_M_HMASTLOCK 0x0F0 0x358 0x000 0x7 0x0
+#define MX8MM_IOMUXC_NAND_ALE_RAWNAND_ALE 0x0F4 0x35C 0x000 0x0 0x0
+#define MX8MM_IOMUXC_NAND_ALE_QSPI_A_SCLK 0x0F4 0x35C 0x000 0x1 0x0
+#define MX8MM_IOMUXC_NAND_ALE_GPIO3_IO0 0x0F4 0x35C 0x000 0x5 0x0
+#define MX8MM_IOMUXC_NAND_ALE_SIM_M_HPROT0 0x0F4 0x35C 0x000 0x7 0x0
+#define MX8MM_IOMUXC_NAND_CE0_B_RAWNAND_CE0_B 0x0F8 0x360 0x000 0x0 0x0
+#define MX8MM_IOMUXC_NAND_CE0_B_QSPI_A_SS0_B 0x0F8 0x360 0x000 0x1 0x0
+#define MX8MM_IOMUXC_NAND_CE0_B_GPIO3_IO1 0x0F8 0x360 0x000 0x5 0x0
+#define MX8MM_IOMUXC_NAND_CE0_B_SIM_M_HPROT1 0x0F8 0x360 0x000 0x7 0x0
+#define MX8MM_IOMUXC_NAND_CE1_B_RAWNAND_CE1_B 0x0FC 0x364 0x000 0x0 0x0
+#define MX8MM_IOMUXC_NAND_CE1_B_QSPI_A_SS1_B 0x0FC 0x364 0x000 0x1 0x0
+#define MX8MM_IOMUXC_NAND_CE1_B_USDHC3_STROBE 0x0FC 0x364 0x000 0x2 0x0
+#define MX8MM_IOMUXC_NAND_CE1_B_GPIO3_IO2 0x0FC 0x364 0x000 0x5 0x0
+#define MX8MM_IOMUXC_NAND_CE1_B_SIM_M_HPROT2 0x0FC 0x364 0x000 0x7 0x0
+#define MX8MM_IOMUXC_NAND_CE2_B_RAWNAND_CE2_B 0x100 0x368 0x000 0x0 0x0
+#define MX8MM_IOMUXC_NAND_CE2_B_QSPI_B_SS0_B 0x100 0x368 0x000 0x1 0x0
+#define MX8MM_IOMUXC_NAND_CE2_B_USDHC3_DATA5 0x100 0x368 0x000 0x2 0x0
+#define MX8MM_IOMUXC_NAND_CE2_B_GPIO3_IO3 0x100 0x368 0x000 0x5 0x0
+#define MX8MM_IOMUXC_NAND_CE2_B_SIM_M_HPROT3 0x100 0x368 0x000 0x7 0x0
+#define MX8MM_IOMUXC_NAND_CE3_B_RAWNAND_CE3_B 0x104 0x36C 0x000 0x0 0x0
+#define MX8MM_IOMUXC_NAND_CE3_B_QSPI_B_SS1_B 0x104 0x36C 0x000 0x1 0x0
+#define MX8MM_IOMUXC_NAND_CE3_B_USDHC3_DATA6 0x104 0x36C 0x000 0x2 0x0
+#define MX8MM_IOMUXC_NAND_CE3_B_GPIO3_IO4 0x104 0x36C 0x000 0x5 0x0
+#define MX8MM_IOMUXC_NAND_CE3_B_SIM_M_HADDR0 0x104 0x36C 0x000 0x7 0x0
+#define MX8MM_IOMUXC_NAND_CLE_RAWNAND_CLE 0x108 0x370 0x000 0x0 0x0
+#define MX8MM_IOMUXC_NAND_CLE_QSPI_B_SCLK 0x108 0x370 0x000 0x1 0x0
+#define MX8MM_IOMUXC_NAND_CLE_USDHC3_DATA7 0x108 0x370 0x000 0x2 0x0
+#define MX8MM_IOMUXC_NAND_CLE_GPIO3_IO5 0x108 0x370 0x000 0x5 0x0
+#define MX8MM_IOMUXC_NAND_CLE_SIM_M_HADDR1 0x108 0x370 0x000 0x7 0x0
+#define MX8MM_IOMUXC_NAND_DATA00_RAWNAND_DATA00 0x10C 0x374 0x000 0x0 0x0
+#define MX8MM_IOMUXC_NAND_DATA00_QSPI_A_DATA0 0x10C 0x374 0x000 0x1 0x0
+#define MX8MM_IOMUXC_NAND_DATA00_GPIO3_IO6 0x10C 0x374 0x000 0x5 0x0
+#define MX8MM_IOMUXC_NAND_DATA00_SIM_M_HADDR2 0x10C 0x374 0x000 0x7 0x0
+#define MX8MM_IOMUXC_NAND_DATA01_RAWNAND_DATA01 0x110 0x378 0x000 0x0 0x0
+#define MX8MM_IOMUXC_NAND_DATA01_QSPI_A_DATA1 0x110 0x378 0x000 0x1 0x0
+#define MX8MM_IOMUXC_NAND_DATA01_GPIO3_IO7 0x110 0x378 0x000 0x5 0x0
+#define MX8MM_IOMUXC_NAND_DATA01_SIM_M_HADDR3 0x110 0x378 0x000 0x7 0x0
+#define MX8MM_IOMUXC_NAND_DATA02_RAWNAND_DATA02 0x114 0x37C 0x000 0x0 0x0
+#define MX8MM_IOMUXC_NAND_DATA02_QSPI_A_DATA2 0x114 0x37C 0x000 0x1 0x0
+#define MX8MM_IOMUXC_NAND_DATA02_GPIO3_IO8 0x114 0x37C 0x000 0x5 0x0
+#define MX8MM_IOMUXC_NAND_DATA02_SIM_M_HADDR4 0x114 0x37C 0x000 0x7 0x0
+#define MX8MM_IOMUXC_NAND_DATA03_RAWNAND_DATA03 0x118 0x380 0x000 0x0 0x0
+#define MX8MM_IOMUXC_NAND_DATA03_QSPI_A_DATA3 0x118 0x380 0x000 0x1 0x0
+#define MX8MM_IOMUXC_NAND_DATA03_GPIO3_IO9 0x118 0x380 0x000 0x5 0x0
+#define MX8MM_IOMUXC_NAND_DATA03_SIM_M_HADDR5 0x118 0x380 0x000 0x7 0x0
+#define MX8MM_IOMUXC_NAND_DATA04_RAWNAND_DATA04 0x11C 0x384 0x000 0x0 0x0
+#define MX8MM_IOMUXC_NAND_DATA04_QSPI_B_DATA0 0x11C 0x384 0x000 0x1 0x0
+#define MX8MM_IOMUXC_NAND_DATA04_USDHC3_DATA0 0x11C 0x384 0x000 0x2 0x0
+#define MX8MM_IOMUXC_NAND_DATA04_GPIO3_IO10 0x11C 0x384 0x000 0x5 0x0
+#define MX8MM_IOMUXC_NAND_DATA04_SIM_M_HADDR6 0x11C 0x384 0x000 0x7 0x0
+#define MX8MM_IOMUXC_NAND_DATA05_RAWNAND_DATA05 0x120 0x388 0x000 0x0 0x0
+#define MX8MM_IOMUXC_NAND_DATA05_QSPI_B_DATA1 0x120 0x388 0x000 0x1 0x0
+#define MX8MM_IOMUXC_NAND_DATA05_USDHC3_DATA1 0x120 0x388 0x000 0x2 0x0
+#define MX8MM_IOMUXC_NAND_DATA05_GPIO3_IO11 0x120 0x388 0x000 0x5 0x0
+#define MX8MM_IOMUXC_NAND_DATA05_SIM_M_HADDR7 0x120 0x388 0x000 0x7 0x0
+#define MX8MM_IOMUXC_NAND_DATA06_RAWNAND_DATA06 0x124 0x38C 0x000 0x0 0x0
+#define MX8MM_IOMUXC_NAND_DATA06_QSPI_B_DATA2 0x124 0x38C 0x000 0x1 0x0
+#define MX8MM_IOMUXC_NAND_DATA06_USDHC3_DATA2 0x124 0x38C 0x000 0x2 0x0
+#define MX8MM_IOMUXC_NAND_DATA06_GPIO3_IO12 0x124 0x38C 0x000 0x5 0x0
+#define MX8MM_IOMUXC_NAND_DATA06_SIM_M_HADDR8 0x124 0x38C 0x000 0x7 0x0
+#define MX8MM_IOMUXC_NAND_DATA07_RAWNAND_DATA07 0x128 0x390 0x000 0x0 0x0
+#define MX8MM_IOMUXC_NAND_DATA07_QSPI_B_DATA3 0x128 0x390 0x000 0x1 0x0
+#define MX8MM_IOMUXC_NAND_DATA07_USDHC3_DATA3 0x128 0x390 0x000 0x2 0x0
+#define MX8MM_IOMUXC_NAND_DATA07_GPIO3_IO13 0x128 0x390 0x000 0x5 0x0
+#define MX8MM_IOMUXC_NAND_DATA07_SIM_M_HADDR9 0x128 0x390 0x000 0x7 0x0
+#define MX8MM_IOMUXC_NAND_DQS_RAWNAND_DQS 0x12C 0x394 0x000 0x0 0x0
+#define MX8MM_IOMUXC_NAND_DQS_QSPI_A_DQS 0x12C 0x394 0x000 0x1 0x0
+#define MX8MM_IOMUXC_NAND_DQS_GPIO3_IO14 0x12C 0x394 0x000 0x5 0x0
+#define MX8MM_IOMUXC_NAND_DQS_SIM_M_HADDR10 0x12C 0x394 0x000 0x7 0x0
+#define MX8MM_IOMUXC_NAND_RE_B_RAWNAND_RE_B 0x130 0x398 0x000 0x0 0x0
+#define MX8MM_IOMUXC_NAND_RE_B_QSPI_B_DQS 0x130 0x398 0x000 0x1 0x0
+#define MX8MM_IOMUXC_NAND_RE_B_USDHC3_DATA4 0x130 0x398 0x000 0x2 0x0
+#define MX8MM_IOMUXC_NAND_RE_B_GPIO3_IO15 0x130 0x398 0x000 0x5 0x0
+#define MX8MM_IOMUXC_NAND_RE_B_SIM_M_HADDR11 0x130 0x398 0x000 0x7 0x0
+#define MX8MM_IOMUXC_NAND_READY_B_RAWNAND_READY_B 0x134 0x39C 0x000 0x0 0x0
+#define MX8MM_IOMUXC_NAND_READY_B_GPIO3_IO16 0x134 0x39C 0x000 0x5 0x0
+#define MX8MM_IOMUXC_NAND_READY_B_SIM_M_HADDR12 0x134 0x39C 0x000 0x7 0x0
+#define MX8MM_IOMUXC_NAND_WE_B_RAWNAND_WE_B 0x138 0x3A0 0x000 0x0 0x0
+#define MX8MM_IOMUXC_NAND_WE_B_USDHC3_CLK 0x138 0x3A0 0x000 0x12 0x0
+#define MX8MM_IOMUXC_NAND_WE_B_GPIO3_IO17 0x138 0x3A0 0x000 0x5 0x0
+#define MX8MM_IOMUXC_NAND_WE_B_SIM_M_HADDR13 0x138 0x3A0 0x000 0x7 0x0
+#define MX8MM_IOMUXC_NAND_WP_B_RAWNAND_WP_B 0x13C 0x3A4 0x000 0x0 0x0
+#define MX8MM_IOMUXC_NAND_WP_B_USDHC3_CMD 0x13C 0x3A4 0x000 0x2 0x0
+#define MX8MM_IOMUXC_NAND_WP_B_GPIO3_IO18 0x13C 0x3A4 0x000 0x5 0x0
+#define MX8MM_IOMUXC_NAND_WP_B_SIM_M_HADDR14 0x13C 0x3A4 0x000 0x7 0x0
+#define MX8MM_IOMUXC_SAI5_RXFS_SAI5_RX_SYNC 0x140 0x3A8 0x4E4 0x0 0x0
+#define MX8MM_IOMUXC_SAI5_RXFS_SAI1_TX_DATA0 0x140 0x3A8 0x000 0x1 0x0
+#define MX8MM_IOMUXC_SAI5_RXFS_GPIO3_IO19 0x140 0x3A8 0x000 0x5 0x0
+#define MX8MM_IOMUXC_SAI5_RXC_SAI5_RX_BCLK 0x144 0x3AC 0x4D0 0x0 0x0
+#define MX8MM_IOMUXC_SAI5_RXC_SAI1_TX_DATA1 0x144 0x3AC 0x000 0x1 0x0
+#define MX8MM_IOMUXC_SAI5_RXC_PDM_CLK 0x144 0x3AC 0x000 0x4 0x0
+#define MX8MM_IOMUXC_SAI5_RXC_GPIO3_IO20 0x144 0x3AC 0x000 0x5 0x0
+#define MX8MM_IOMUXC_SAI5_RXD0_SAI5_RX_DATA0 0x148 0x3B0 0x4D4 0x0 0x0
+#define MX8MM_IOMUXC_SAI5_RXD0_SAI1_TX_DATA2 0x148 0x3B0 0x000 0x1 0x0
+#define MX8MM_IOMUXC_SAI5_RXD0_PDM_DATA0 0x148 0x3B0 0x534 0x4 0x0
+#define MX8MM_IOMUXC_SAI5_RXD0_GPIO3_IO21 0x148 0x3B0 0x000 0x5 0x0
+#define MX8MM_IOMUXC_SAI5_RXD1_SAI5_RX_DATA1 0x14C 0x3B4 0x4D8 0x0 0x0
+#define MX8MM_IOMUXC_SAI5_RXD1_SAI1_TX_DATA3 0x14C 0x3B4 0x000 0x1 0x0
+#define MX8MM_IOMUXC_SAI5_RXD1_SAI1_TX_SYNC 0x14C 0x3B4 0x4CC 0x2 0x0
+#define MX8MM_IOMUXC_SAI5_RXD1_SAI5_TX_SYNC 0x14C 0x3B4 0x4EC 0x3 0x0
+#define MX8MM_IOMUXC_SAI5_RXD1_PDM_DATA1 0x14C 0x3B4 0x538 0x4 0x0
+#define MX8MM_IOMUXC_SAI5_RXD1_GPIO3_IO22 0x14C 0x3B4 0x000 0x5 0x0
+#define MX8MM_IOMUXC_SAI5_RXD2_SAI5_RX_DATA2 0x150 0x3B8 0x4DC 0x0 0x0
+#define MX8MM_IOMUXC_SAI5_RXD2_SAI1_TX_DATA4 0x150 0x3B8 0x000 0x1 0x0
+#define MX8MM_IOMUXC_SAI5_RXD2_SAI1_TX_SYNC 0x150 0x3B8 0x4CC 0x2 0x1
+#define MX8MM_IOMUXC_SAI5_RXD2_SAI5_TX_BCLK 0x150 0x3B8 0x4E8 0x3 0x0
+#define MX8MM_IOMUXC_SAI5_RXD2_PDM_DATA2 0x150 0x3B8 0x53c 0x4 0x0
+#define MX8MM_IOMUXC_SAI5_RXD2_GPIO3_IO23 0x150 0x3B8 0x000 0x5 0x0
+#define MX8MM_IOMUXC_SAI5_RXD3_SAI5_RX_DATA3 0x154 0x3BC 0x4E0 0x0 0x0
+#define MX8MM_IOMUXC_SAI5_RXD3_SAI1_TX_DATA5 0x154 0x3BC 0x000 0x1 0x0
+#define MX8MM_IOMUXC_SAI5_RXD3_SAI1_TX_SYNC 0x154 0x3BC 0x4CC 0x2 0x2
+#define MX8MM_IOMUXC_SAI5_RXD3_SAI5_TX_DATA0 0x154 0x3BC 0x000 0x3 0x0
+#define MX8MM_IOMUXC_SAI5_RXD3_PDM_DATA3 0x154 0x3BC 0x540 0x4 0x0
+#define MX8MM_IOMUXC_SAI5_RXD3_GPIO3_IO24 0x154 0x3BC 0x000 0x5 0x0
+#define MX8MM_IOMUXC_SAI5_MCLK_SAI5_MCLK 0x158 0x3C0 0x52C 0x0 0x0
+#define MX8MM_IOMUXC_SAI5_MCLK_SAI1_TX_BCLK 0x158 0x3C0 0x4C8 0x1 0x0
+#define MX8MM_IOMUXC_SAI5_MCLK_SAI4_MCLK 0x158 0x3C0 0x000 0x2 0x0
+#define MX8MM_IOMUXC_SAI5_MCLK_GPIO3_IO25 0x158 0x3C0 0x000 0x5 0x0
+#define MX8MM_IOMUXC_SAI5_MCLK_CCMSRCGPCMIX_TESTER_ACK 0x158 0x3C0 0x000 0x6 0x0
+#define MX8MM_IOMUXC_SAI1_RXFS_SAI1_RX_SYNC 0x15C 0x3C4 0x4C4 0x0 0x0
+#define MX8MM_IOMUXC_SAI1_RXFS_SAI5_RX_SYNC 0x15C 0x3C4 0x4E4 0x1 0x1
+#define MX8MM_IOMUXC_SAI1_RXFS_CORESIGHT_TRACE_CLK 0x15C 0x3C4 0x000 0x4 0x0
+#define MX8MM_IOMUXC_SAI1_RXFS_GPIO4_IO0 0x15C 0x3C4 0x000 0x5 0x0
+#define MX8MM_IOMUXC_SAI1_RXFS_SIM_M_HADDR15 0x15C 0x3C4 0x000 0x7 0x0
+#define MX8MM_IOMUXC_SAI1_RXC_SAI1_RX_BCLK 0x160 0x3C8 0x000 0x0 0x0
+#define MX8MM_IOMUXC_SAI1_RXC_SAI5_RX_BCLK 0x160 0x3C8 0x4D0 0x1 0x1
+#define MX8MM_IOMUXC_SAI1_RXC_CORESIGHT_TRACE_CTL 0x160 0x3C8 0x000 0x4 0x0
+#define MX8MM_IOMUXC_SAI1_RXC_GPIO4_IO1 0x160 0x3C8 0x000 0x5 0x0
+#define MX8MM_IOMUXC_SAI1_RXC_SIM_M_HADDR16 0x160 0x3C8 0x000 0x7 0x0
+#define MX8MM_IOMUXC_SAI1_RXD0_SAI1_RX_DATA0 0x164 0x3CC 0x000 0x0 0x0
+#define MX8MM_IOMUXC_SAI1_RXD0_SAI5_RX_DATA0 0x164 0x3CC 0x4D4 0x1 0x1
+#define MX8MM_IOMUXC_SAI1_RXD0_PDM_DATA0 0x164 0x3CC 0x534 0x3 0x1
+#define MX8MM_IOMUXC_SAI1_RXD0_CORESIGHT_TRACE0 0x164 0x3CC 0x000 0x4 0x0
+#define MX8MM_IOMUXC_SAI1_RXD0_GPIO4_IO2 0x164 0x3CC 0x000 0x5 0x0
+#define MX8MM_IOMUXC_SAI1_RXD0_CCMSRCGPCMIX_BOOT_CFG0 0x164 0x3CC 0x000 0x6 0x0
+#define MX8MM_IOMUXC_SAI1_RXD0_SIM_M_HADDR17 0x164 0x3CC 0x000 0x7 0x0
+#define MX8MM_IOMUXC_SAI1_RXD1_SAI1_RX_DATA1 0x168 0x3D0 0x000 0x0 0x0
+#define MX8MM_IOMUXC_SAI1_RXD1_SAI5_RX_DATA1 0x168 0x3D0 0x4D8 0x1 0x1
+#define MX8MM_IOMUXC_SAI1_RXD1_PDM_DATA1 0x168 0x3D0 0x538 0x3 0x1
+#define MX8MM_IOMUXC_SAI1_RXD1_CORESIGHT_TRACE1 0x168 0x3D0 0x000 0x4 0x0
+#define MX8MM_IOMUXC_SAI1_RXD1_GPIO4_IO3 0x168 0x3D0 0x000 0x5 0x0
+#define MX8MM_IOMUXC_SAI1_RXD1_CCMSRCGPCMIX_BOOT_CFG1 0x168 0x3D0 0x000 0x6 0x0
+#define MX8MM_IOMUXC_SAI1_RXD1_SIM_M_HADDR18 0x168 0x3D0 0x000 0x7 0x0
+#define MX8MM_IOMUXC_SAI1_RXD2_SAI1_RX_DATA2 0x16C 0x3D4 0x000 0x0 0x0
+#define MX8MM_IOMUXC_SAI1_RXD2_SAI5_RX_DATA2 0x16C 0x3D4 0x4DC 0x1 0x1
+#define MX8MM_IOMUXC_SAI1_RXD2_PDM_DATA2 0x16C 0x3D4 0x53C 0x3 0x1
+#define MX8MM_IOMUXC_SAI1_RXD2_CORESIGHT_TRACE2 0x16C 0x3D4 0x000 0x4 0x0
+#define MX8MM_IOMUXC_SAI1_RXD2_GPIO4_IO4 0x16C 0x3D4 0x000 0x5 0x0
+#define MX8MM_IOMUXC_SAI1_RXD2_CCMSRCGPCMIX_BOOT_CFG2 0x16C 0x3D4 0x000 0x6 0x0
+#define MX8MM_IOMUXC_SAI1_RXD2_SIM_M_HADDR19 0x16C 0x3D4 0x000 0x7 0x0
+#define MX8MM_IOMUXC_SAI1_RXD3_SAI1_RX_DATA3 0x170 0x3D8 0x4E0 0x0 0x1
+#define MX8MM_IOMUXC_SAI1_RXD3_SAI5_RX_DATA3 0x170 0x3D8 0x000 0x1 0x0
+#define MX8MM_IOMUXC_SAI1_RXD3_PDM_DATA3 0x170 0x3D8 0x540 0x3 0x1
+#define MX8MM_IOMUXC_SAI1_RXD3_CORESIGHT_TRACE3 0x170 0x3D8 0x000 0x4 0x0
+#define MX8MM_IOMUXC_SAI1_RXD3_GPIO4_IO5 0x170 0x3D8 0x000 0x5 0x0
+#define MX8MM_IOMUXC_SAI1_RXD3_CCMSRCGPCMIX_BOOT_CFG3 0x170 0x3D8 0x000 0x6 0x0
+#define MX8MM_IOMUXC_SAI1_RXD3_SIM_M_HADDR20 0x170 0x3D8 0x000 0x7 0x0
+#define MX8MM_IOMUXC_SAI1_RXD4_SAI1_RX_DATA4 0x174 0x3DC 0x000 0x0 0x0
+#define MX8MM_IOMUXC_SAI1_RXD4_SAI6_TX_BCLK 0x174 0x3DC 0x51C 0x1 0x0
+#define MX8MM_IOMUXC_SAI1_RXD4_SAI6_RX_BCLK 0x174 0x3DC 0x510 0x2 0x0
+#define MX8MM_IOMUXC_SAI1_RXD4_CORESIGHT_TRACE4 0x174 0x3DC 0x000 0x4 0x0
+#define MX8MM_IOMUXC_SAI1_RXD4_GPIO4_IO6 0x174 0x3DC 0x000 0x5 0x0
+#define MX8MM_IOMUXC_SAI1_RXD4_CCMSRCGPCMIX_BOOT_CFG4 0x174 0x3DC 0x000 0x6 0x0
+#define MX8MM_IOMUXC_SAI1_RXD4_SIM_M_HADDR21 0x174 0x3DC 0x000 0x7 0x0
+#define MX8MM_IOMUXC_SAI1_RXD5_SAI1_RX_DATA5 0x178 0x3E0 0x000 0x0 0x0
+#define MX8MM_IOMUXC_SAI1_RXD5_SAI6_TX_DATA0 0x178 0x3E0 0x000 0x1 0x0
+#define MX8MM_IOMUXC_SAI1_RXD5_SAI6_RX_DATA0 0x178 0x3E0 0x514 0x2 0x0
+#define MX8MM_IOMUXC_SAI1_RXD5_SAI1_RX_SYNC 0x178 0x3E0 0x4C4 0x3 0x1
+#define MX8MM_IOMUXC_SAI1_RXD5_CORESIGHT_TRACE5 0x178 0x3E0 0x000 0x4 0x0
+#define MX8MM_IOMUXC_SAI1_RXD5_GPIO4_IO7 0x178 0x3E0 0x000 0x5 0x0
+#define MX8MM_IOMUXC_SAI1_RXD5_CCMSRCGPCMIX_BOOT_CFG5 0x178 0x3E0 0x000 0x6 0x0
+#define MX8MM_IOMUXC_SAI1_RXD5_SIM_M_HADDR22 0x178 0x3E0 0x000 0x7 0x0
+#define MX8MM_IOMUXC_SAI1_RXD6_SAI1_RX_DATA6 0x17C 0x3E4 0x520 0x0 0x0
+#define MX8MM_IOMUXC_SAI1_RXD6_SAI6_TX_SYNC 0x17C 0x3E4 0x000 0x1 0x0
+#define MX8MM_IOMUXC_SAI1_RXD6_SAI6_RX_SYNC 0x17C 0x3E4 0x518 0x2 0x0
+#define MX8MM_IOMUXC_SAI1_RXD6_CORESIGHT_TRACE6 0x17C 0x3E4 0x000 0x4 0x0
+#define MX8MM_IOMUXC_SAI1_RXD6_GPIO4_IO8 0x17C 0x3E4 0x000 0x5 0x0
+#define MX8MM_IOMUXC_SAI1_RXD6_CCMSRCGPCMIX_BOOT_CFG6 0x17C 0x3E4 0x000 0x6 0x0
+#define MX8MM_IOMUXC_SAI1_RXD6_SIM_M_HADDR23 0x17C 0x3E4 0x000 0x7 0x0
+#define MX8MM_IOMUXC_SAI1_RXD7_SAI1_RX_DATA7 0x180 0x3E8 0x000 0x0 0x0
+#define MX8MM_IOMUXC_SAI1_RXD7_SAI6_MCLK 0x180 0x3E8 0x530 0x1 0x0
+#define MX8MM_IOMUXC_SAI1_RXD7_SAI1_TX_SYNC 0x180 0x3E8 0x4CC 0x2 0x4
+#define MX8MM_IOMUXC_SAI1_RXD7_SAI1_TX_DATA4 0x180 0x3E8 0x000 0x3 0x0
+#define MX8MM_IOMUXC_SAI1_RXD7_CORESIGHT_TRACE7 0x180 0x3E8 0x000 0x4 0x0
+#define MX8MM_IOMUXC_SAI1_RXD7_GPIO4_IO9 0x180 0x3E8 0x000 0x5 0x0
+#define MX8MM_IOMUXC_SAI1_RXD7_CCMSRCGPCMIX_BOOT_CFG7 0x180 0x3E8 0x000 0x6 0x0
+#define MX8MM_IOMUXC_SAI1_RXD7_SIM_M_HADDR24 0x180 0x3E8 0x000 0x7 0x0
+#define MX8MM_IOMUXC_SAI1_TXFS_SAI1_TX_SYNC 0x184 0x3EC 0x4CC 0x0 0x3
+#define MX8MM_IOMUXC_SAI1_TXFS_SAI5_TX_SYNC 0x184 0x3EC 0x4EC 0x1 0x1
+#define MX8MM_IOMUXC_SAI1_TXFS_CORESIGHT_EVENTO 0x184 0x3EC 0x000 0x4 0x0
+#define MX8MM_IOMUXC_SAI1_TXFS_GPIO4_IO10 0x184 0x3EC 0x000 0x5 0x0
+#define MX8MM_IOMUXC_SAI1_TXFS_SIM_M_HADDR25 0x184 0x3EC 0x000 0x7 0x0
+#define MX8MM_IOMUXC_SAI1_TXC_SAI1_TX_BCLK 0x188 0x3F0 0x4C8 0x0 0x1
+#define MX8MM_IOMUXC_SAI1_TXC_SAI5_TX_BCLK 0x188 0x3F0 0x4E8 0x1 0x1
+#define MX8MM_IOMUXC_SAI1_TXC_CORESIGHT_EVENTI 0x188 0x3F0 0x000 0x4 0x0
+#define MX8MM_IOMUXC_SAI1_TXC_GPIO4_IO11 0x188 0x3F0 0x000 0x5 0x0
+#define MX8MM_IOMUXC_SAI1_TXC_SIM_M_HADDR26 0x188 0x3F0 0x000 0x7 0x0
+#define MX8MM_IOMUXC_SAI1_TXD0_SAI1_TX_DATA0 0x18C 0x3F4 0x000 0x0 0x0
+#define MX8MM_IOMUXC_SAI1_TXD0_SAI5_TX_DATA0 0x18C 0x3F4 0x000 0x1 0x0
+#define MX8MM_IOMUXC_SAI1_TXD0_CORESIGHT_TRACE8 0x18C 0x3F4 0x000 0x4 0x0
+#define MX8MM_IOMUXC_SAI1_TXD0_GPIO4_IO12 0x18C 0x3F4 0x000 0x5 0x0
+#define MX8MM_IOMUXC_SAI1_TXD0_CCMSRCGPCMIX_BOOT_CFG8 0x18C 0x3F4 0x000 0x6 0x0
+#define MX8MM_IOMUXC_SAI1_TXD0_SIM_M_HADDR27 0x18C 0x3F4 0x000 0x7 0x0
+#define MX8MM_IOMUXC_SAI1_TXD1_SAI1_TX_DATA1 0x190 0x3F8 0x000 0x0 0x0
+#define MX8MM_IOMUXC_SAI1_TXD1_SAI5_TX_DATA1 0x190 0x3F8 0x000 0x1 0x0
+#define MX8MM_IOMUXC_SAI1_TXD1_CORESIGHT_TRACE9 0x190 0x3F8 0x000 0x4 0x0
+#define MX8MM_IOMUXC_SAI1_TXD1_GPIO4_IO13 0x190 0x3F8 0x000 0x5 0x0
+#define MX8MM_IOMUXC_SAI1_TXD1_CCMSRCGPCMIX_BOOT_CFG9 0x190 0x3F8 0x000 0x6 0x0
+#define MX8MM_IOMUXC_SAI1_TXD1_SIM_M_HADDR28 0x190 0x3F8 0x000 0x7 0x0
+#define MX8MM_IOMUXC_SAI1_TXD2_SAI1_TX_DATA2 0x194 0x3FC 0x000 0x0 0x0
+#define MX8MM_IOMUXC_SAI1_TXD2_SAI5_TX_DATA2 0x194 0x3FC 0x000 0x1 0x0
+#define MX8MM_IOMUXC_SAI1_TXD2_CORESIGHT_TRACE10 0x194 0x3FC 0x000 0x4 0x0
+#define MX8MM_IOMUXC_SAI1_TXD2_GPIO4_IO14 0x194 0x3FC 0x000 0x5 0x0
+#define MX8MM_IOMUXC_SAI1_TXD2_CCMSRCGPCMIX_BOOT_CFG10 0x194 0x3FC 0x000 0x6 0x0
+#define MX8MM_IOMUXC_SAI1_TXD2_SIM_M_HADDR29 0x194 0x3FC 0x000 0x7 0x0
+#define MX8MM_IOMUXC_SAI1_TXD3_SAI1_TX_DATA3 0x198 0x400 0x000 0x0 0x0
+#define MX8MM_IOMUXC_SAI1_TXD3_SAI5_TX_DATA3 0x198 0x400 0x000 0x1 0x0
+#define MX8MM_IOMUXC_SAI1_TXD3_CORESIGHT_TRACE11 0x198 0x400 0x000 0x4 0x0
+#define MX8MM_IOMUXC_SAI1_TXD3_GPIO4_IO15 0x198 0x400 0x000 0x5 0x0
+#define MX8MM_IOMUXC_SAI1_TXD3_CCMSRCGPCMIX_BOOT_CFG11 0x198 0x400 0x000 0x6 0x0
+#define MX8MM_IOMUXC_SAI1_TXD3_SIM_M_HADDR30 0x198 0x400 0x000 0x7 0x0
+#define MX8MM_IOMUXC_SAI1_TXD4_SAI1_TX_DATA4 0x19C 0x404 0x000 0x0 0x0
+#define MX8MM_IOMUXC_SAI1_TXD4_SAI6_RX_BCLK 0x19C 0x404 0x510 0x1 0x1
+#define MX8MM_IOMUXC_SAI1_TXD4_SAI6_TX_BCLK 0x19C 0x404 0x51C 0x2 0x1
+#define MX8MM_IOMUXC_SAI1_TXD4_CORESIGHT_TRACE12 0x19C 0x404 0x000 0x4 0x0
+#define MX8MM_IOMUXC_SAI1_TXD4_GPIO4_IO16 0x19C 0x404 0x000 0x5 0x0
+#define MX8MM_IOMUXC_SAI1_TXD4_CCMSRCGPCMIX_BOOT_CFG12 0x19C 0x404 0x000 0x6 0x0
+#define MX8MM_IOMUXC_SAI1_TXD4_SIM_M_HADDR31 0x19C 0x404 0x000 0x7 0x0
+#define MX8MM_IOMUXC_SAI1_TXD5_SAI1_TX_DATA5 0x1A0 0x408 0x000 0x0 0x0
+#define MX8MM_IOMUXC_SAI1_TXD5_SAI6_RX_DATA0 0x1A0 0x408 0x514 0x1 0x1
+#define MX8MM_IOMUXC_SAI1_TXD5_SAI6_TX_DATA0 0x1A0 0x408 0x000 0x2 0x0
+#define MX8MM_IOMUXC_SAI1_TXD5_CORESIGHT_TRACE13 0x1A0 0x408 0x000 0x4 0x0
+#define MX8MM_IOMUXC_SAI1_TXD5_GPIO4_IO17 0x1A0 0x408 0x000 0x5 0x0
+#define MX8MM_IOMUXC_SAI1_TXD5_CCMSRCGPCMIX_BOOT_CFG13 0x1A0 0x408 0x000 0x6 0x0
+#define MX8MM_IOMUXC_SAI1_TXD5_SIM_M_HBURST0 0x1A0 0x408 0x000 0x7 0x0
+#define MX8MM_IOMUXC_SAI1_TXD6_SAI1_TX_DATA6 0x1A4 0x40C 0x000 0x0 0x0
+#define MX8MM_IOMUXC_SAI1_TXD6_SAI6_RX_SYNC 0x1A4 0x40C 0x518 0x1 0x1
+#define MX8MM_IOMUXC_SAI1_TXD6_SAI6_TX_SYNC 0x1A4 0x40C 0x520 0x2 0x1
+#define MX8MM_IOMUXC_SAI1_TXD6_CORESIGHT_TRACE14 0x1A4 0x40C 0x000 0x4 0x0
+#define MX8MM_IOMUXC_SAI1_TXD6_GPIO4_IO18 0x1A4 0x40C 0x000 0x5 0x0
+#define MX8MM_IOMUXC_SAI1_TXD6_CCMSRCGPCMIX_BOOT_CFG14 0x1A4 0x40C 0x000 0x6 0x0
+#define MX8MM_IOMUXC_SAI1_TXD6_SIM_M_HBURST1 0x1A4 0x40C 0x000 0x7 0x0
+#define MX8MM_IOMUXC_SAI1_TXD7_SAI1_TX_DATA7 0x1A8 0x410 0x000 0x0 0x0
+#define MX8MM_IOMUXC_SAI1_TXD7_SAI6_MCLK 0x1A8 0x410 0x530 0x1 0x1
+#define MX8MM_IOMUXC_SAI1_TXD7_PDM_CLK 0x1A8 0x410 0x000 0x3 0x0
+#define MX8MM_IOMUXC_SAI1_TXD7_CORESIGHT_TRACE15 0x1A8 0x410 0x000 0x4 0x0
+#define MX8MM_IOMUXC_SAI1_TXD7_GPIO4_IO19 0x1A8 0x410 0x000 0x5 0x0
+#define MX8MM_IOMUXC_SAI1_TXD7_CCMSRCGPCMIX_BOOT_CFG15 0x1A8 0x410 0x000 0x6 0x0
+#define MX8MM_IOMUXC_SAI1_TXD7_SIM_M_HBURST2 0x1A8 0x410 0x000 0x7 0x0
+#define MX8MM_IOMUXC_SAI1_MCLK_SAI1_MCLK 0x1AC 0x414 0x000 0x0 0x0
+#define MX8MM_IOMUXC_SAI1_MCLK_SAI5_MCLK 0x1AC 0x414 0x52C 0x1 0x1
+#define MX8MM_IOMUXC_SAI1_MCLK_SAI1_TX_BCLK 0x1AC 0x414 0x4C8 0x2 0x2
+#define MX8MM_IOMUXC_SAI1_MCLK_PDM_CLK 0x1AC 0x414 0x000 0x3 0x0
+#define MX8MM_IOMUXC_SAI1_MCLK_GPIO4_IO20 0x1AC 0x414 0x000 0x5 0x0
+#define MX8MM_IOMUXC_SAI1_MCLK_SIM_M_HRESP 0x1AC 0x414 0x000 0x7 0x0
+#define MX8MM_IOMUXC_SAI2_RXFS_SAI2_RX_SYNC 0x1B0 0x418 0x000 0x0 0x0
+#define MX8MM_IOMUXC_SAI2_RXFS_SAI5_TX_SYNC 0x1B0 0x418 0x4EC 0x1 0x2
+#define MX8MM_IOMUXC_SAI2_RXFS_GPIO4_IO21 0x1B0 0x418 0x000 0x5 0x0
+#define MX8MM_IOMUXC_SAI2_RXFS_SIM_M_HSIZE0 0x1B0 0x418 0x000 0x7 0x0
+#define MX8MM_IOMUXC_SAI2_RXC_SAI2_RX_BCLK 0x1B4 0x41C 0x000 0x0 0x0
+#define MX8MM_IOMUXC_SAI2_RXC_SAI5_TX_BCLK 0x1B4 0x41C 0x4E8 0x1 0x2
+#define MX8MM_IOMUXC_SAI2_RXC_GPIO4_IO22 0x1B4 0x41C 0x000 0x5 0x0
+#define MX8MM_IOMUXC_SAI2_RXC_SIM_M_HSIZE1 0x1B4 0x41C 0x000 0x7 0x0
+#define MX8MM_IOMUXC_SAI2_RXD0_SAI2_RX_DATA0 0x1B8 0x420 0x000 0x0 0x0
+#define MX8MM_IOMUXC_SAI2_RXD0_SAI5_TX_DATA0 0x1B8 0x420 0x000 0x1 0x0
+#define MX8MM_IOMUXC_SAI2_RXD0_GPIO4_IO23 0x1B8 0x420 0x000 0x5 0x0
+#define MX8MM_IOMUXC_SAI2_RXD0_SIM_M_HSIZE2 0x1B8 0x420 0x000 0x7 0x0
+#define MX8MM_IOMUXC_SAI2_TXFS_SAI2_TX_SYNC 0x1BC 0x424 0x000 0x0 0x0
+#define MX8MM_IOMUXC_SAI2_TXFS_SAI5_TX_DATA1 0x1BC 0x424 0x000 0x1 0x0
+#define MX8MM_IOMUXC_SAI2_TXFS_GPIO4_IO24 0x1BC 0x424 0x000 0x5 0x0
+#define MX8MM_IOMUXC_SAI2_TXFS_SIM_M_HWRITE 0x1BC 0x424 0x000 0x7 0x0
+#define MX8MM_IOMUXC_SAI2_TXC_SAI2_TX_BCLK 0x1C0 0x428 0x000 0x0 0x0
+#define MX8MM_IOMUXC_SAI2_TXC_SAI5_TX_DATA2 0x1C0 0x428 0x000 0x1 0x0
+#define MX8MM_IOMUXC_SAI2_TXC_GPIO4_IO25 0x1C0 0x428 0x000 0x5 0x0
+#define MX8MM_IOMUXC_SAI2_TXC_SIM_M_HREADYOUT 0x1C0 0x428 0x000 0x7 0x0
+#define MX8MM_IOMUXC_SAI2_TXD0_SAI2_TX_DATA0 0x1C4 0x42C 0x000 0x0 0x0
+#define MX8MM_IOMUXC_SAI2_TXD0_SAI5_TX_DATA3 0x1C4 0x42C 0x000 0x1 0x0
+#define MX8MM_IOMUXC_SAI2_TXD0_GPIO4_IO26 0x1C4 0x42C 0x000 0x5 0x0
+#define MX8MM_IOMUXC_SAI2_TXD0_TPSMP_CLK 0x1C4 0x42C 0x000 0x7 0x0
+#define MX8MM_IOMUXC_SAI2_MCLK_SAI2_MCLK 0x1C8 0x430 0x000 0x0 0x0
+#define MX8MM_IOMUXC_SAI2_MCLK_SAI5_MCLK 0x1C8 0x430 0x52C 0x1 0x2
+#define MX8MM_IOMUXC_SAI2_MCLK_GPIO4_IO27 0x1C8 0x430 0x000 0x5 0x0
+#define MX8MM_IOMUXC_SAI2_MCLK_TPSMP_HDATA_DIR 0x1C8 0x430 0x000 0x7 0x0
+#define MX8MM_IOMUXC_SAI3_RXFS_SAI3_RX_SYNC 0x1CC 0x434 0x000 0x0 0x0
+#define MX8MM_IOMUXC_SAI3_RXFS_GPT1_CAPTURE1 0x1CC 0x434 0x000 0x1 0x0
+#define MX8MM_IOMUXC_SAI3_RXFS_SAI5_RX_SYNC 0x1CC 0x434 0x4E4 0x2 0x2
+#define MX8MM_IOMUXC_SAI3_RXFS_GPIO4_IO28 0x1CC 0x434 0x000 0x5 0x0
+#define MX8MM_IOMUXC_SAI3_RXFS_TPSMP_HTRANS0 0x1CC 0x434 0x000 0x7 0x0
+#define MX8MM_IOMUXC_SAI3_RXC_SAI3_RX_BCLK 0x1D0 0x438 0x000 0x0 0x0
+#define MX8MM_IOMUXC_SAI3_RXC_GPT1_CAPTURE2 0x1D0 0x438 0x000 0x1 0x0
+#define MX8MM_IOMUXC_SAI3_RXC_SAI5_RX_BCLK 0x1D0 0x438 0x4D0 0x2 0x2
+#define MX8MM_IOMUXC_SAI3_RXC_GPIO4_IO29 0x1D0 0x438 0x000 0x5 0x0
+#define MX8MM_IOMUXC_SAI3_RXC_TPSMP_HTRANS1 0x1D0 0x438 0x000 0x7 0x0
+#define MX8MM_IOMUXC_SAI3_RXD_SAI3_RX_DATA0 0x1D4 0x43C 0x000 0x0 0x0
+#define MX8MM_IOMUXC_SAI3_RXD_GPT1_COMPARE1 0x1D4 0x43C 0x000 0x1 0x0
+#define MX8MM_IOMUXC_SAI3_RXD_SAI5_RX_DATA0 0x1D4 0x43C 0x4D4 0x2 0x2
+#define MX8MM_IOMUXC_SAI3_RXD_GPIO4_IO30 0x1D4 0x43C 0x000 0x5 0x0
+#define MX8MM_IOMUXC_SAI3_RXD_TPSMP_HDATA0 0x1D4 0x43C 0x000 0x7 0x0
+#define MX8MM_IOMUXC_SAI3_TXFS_SAI3_TX_SYNC 0x1D8 0x440 0x000 0x0 0x0
+#define MX8MM_IOMUXC_SAI3_TXFS_GPT1_CLK 0x1D8 0x440 0x000 0x1 0x0
+#define MX8MM_IOMUXC_SAI3_TXFS_SAI5_RX_DATA1 0x1D8 0x440 0x4D8 0x2 0x2
+#define MX8MM_IOMUXC_SAI3_TXFS_GPIO4_IO31 0x1D8 0x440 0x000 0x5 0x0
+#define MX8MM_IOMUXC_SAI3_TXFS_TPSMP_HDATA1 0x1D8 0x440 0x000 0x7 0x0
+#define MX8MM_IOMUXC_SAI3_TXC_SAI3_TX_BCLK 0x1DC 0x444 0x000 0x0 0x0
+#define MX8MM_IOMUXC_SAI3_TXC_GPT1_COMPARE2 0x1DC 0x444 0x000 0x1 0x0
+#define MX8MM_IOMUXC_SAI3_TXC_SAI5_RX_DATA2 0x1DC 0x444 0x4DC 0x2 0x2
+#define MX8MM_IOMUXC_SAI3_TXC_GPIO5_IO0 0x1DC 0x444 0x000 0x5 0x0
+#define MX8MM_IOMUXC_SAI3_TXC_TPSMP_HDATA2 0x1DC 0x444 0x000 0x7 0x0
+#define MX8MM_IOMUXC_SAI3_TXD_SAI3_TX_DATA0 0x1E0 0x448 0x000 0x0 0x0
+#define MX8MM_IOMUXC_SAI3_TXD_GPT1_COMPARE3 0x1E0 0x448 0x000 0x1 0x0
+#define MX8MM_IOMUXC_SAI3_TXD_SAI5_RX_DATA3 0x1E0 0x448 0x4E0 0x2 0x2
+#define MX8MM_IOMUXC_SAI3_TXD_GPIO5_IO1 0x1E0 0x448 0x000 0x5 0x0
+#define MX8MM_IOMUXC_SAI3_TXD_TPSMP_HDATA3 0x1E0 0x448 0x000 0x7 0x0
+#define MX8MM_IOMUXC_SAI3_MCLK_SAI3_MCLK 0x1E4 0x44C 0x000 0x0 0x0
+#define MX8MM_IOMUXC_SAI3_MCLK_PWM4_OUT 0x1E4 0x44C 0x000 0x1 0x0
+#define MX8MM_IOMUXC_SAI3_MCLK_SAI5_MCLK 0x1E4 0x44C 0x52C 0x2 0x3
+#define MX8MM_IOMUXC_SAI3_MCLK_GPIO5_IO2 0x1E4 0x44C 0x000 0x5 0x0
+#define MX8MM_IOMUXC_SAI3_MCLK_TPSMP_HDATA4 0x1E4 0x44C 0x000 0x7 0x0
+#define MX8MM_IOMUXC_SPDIF_TX_SPDIF1_OUT 0x1E8 0x450 0x000 0x0 0x0
+#define MX8MM_IOMUXC_SPDIF_TX_PWM3_OUT 0x1E8 0x450 0x000 0x1 0x0
+#define MX8MM_IOMUXC_SPDIF_TX_GPIO5_IO3 0x1E8 0x450 0x000 0x5 0x0
+#define MX8MM_IOMUXC_SPDIF_TX_TPSMP_HDATA5 0x1E8 0x450 0x000 0x7 0x0
+#define MX8MM_IOMUXC_SPDIF_RX_SPDIF1_IN 0x1EC 0x454 0x000 0x0 0x0
+#define MX8MM_IOMUXC_SPDIF_RX_PWM2_OUT 0x1EC 0x454 0x000 0x1 0x0
+#define MX8MM_IOMUXC_SPDIF_RX_GPIO5_IO4 0x1EC 0x454 0x000 0x5 0x0
+#define MX8MM_IOMUXC_SPDIF_RX_TPSMP_HDATA6 0x1EC 0x454 0x000 0x7 0x0
+#define MX8MM_IOMUXC_SPDIF_EXT_CLK_SPDIF1_EXT_CLK 0x1F0 0x458 0x000 0x0 0x0
+#define MX8MM_IOMUXC_SPDIF_EXT_CLK_PWM1_OUT 0x1F0 0x458 0x000 0x1 0x0
+#define MX8MM_IOMUXC_SPDIF_EXT_CLK_GPIO5_IO5 0x1F0 0x458 0x000 0x5 0x0
+#define MX8MM_IOMUXC_SPDIF_EXT_CLK_TPSMP_HDATA7 0x1F0 0x458 0x000 0x7 0x0
+#define MX8MM_IOMUXC_ECSPI1_SCLK_ECSPI1_SCLK 0x1F4 0x45C 0x000 0x0 0x0
+#define MX8MM_IOMUXC_ECSPI1_SCLK_UART3_DCE_RX 0x1F4 0x45C 0x504 0x1 0x0
+#define MX8MM_IOMUXC_ECSPI1_SCLK_UART3_DTE_TX 0x1F4 0x45C 0x000 0x1 0x0
+#define MX8MM_IOMUXC_ECSPI1_SCLK_GPIO5_IO6 0x1F4 0x45C 0x000 0x5 0x0
+#define MX8MM_IOMUXC_ECSPI1_SCLK_TPSMP_HDATA8 0x1F4 0x45C 0x000 0x7 0x0
+#define MX8MM_IOMUXC_ECSPI1_MOSI_ECSPI1_MOSI 0x1F8 0x460 0x000 0x0 0x0
+#define MX8MM_IOMUXC_ECSPI1_MOSI_UART3_DCE_TX 0x1F8 0x460 0x000 0x1 0x0
+#define MX8MM_IOMUXC_ECSPI1_MOSI_UART3_DTE_RX 0x1F8 0x460 0x504 0x1 0x1
+#define MX8MM_IOMUXC_ECSPI1_MOSI_GPIO5_IO7 0x1F8 0x460 0x000 0x5 0x0
+#define MX8MM_IOMUXC_ECSPI1_MOSI_TPSMP_HDATA9 0x1F8 0x460 0x000 0x7 0x0
+#define MX8MM_IOMUXC_ECSPI1_MISO_ECSPI1_MISO 0x1FC 0x464 0x000 0x0 0x0
+#define MX8MM_IOMUXC_ECSPI1_MISO_UART3_DCE_CTS_B 0x1FC 0x464 0x000 0x1 0x0
+#define MX8MM_IOMUXC_ECSPI1_MISO_UART3_DTE_RTS_B 0x1FC 0x464 0x500 0x1 0x0
+#define MX8MM_IOMUXC_ECSPI1_MISO_GPIO5_IO8 0x1FC 0x464 0x000 0x5 0x0
+#define MX8MM_IOMUXC_ECSPI1_MISO_TPSMP_HDATA10 0x1FC 0x464 0x000 0x7 0x0
+#define MX8MM_IOMUXC_ECSPI1_SS0_ECSPI1_SS0 0x200 0x468 0x000 0x0 0x0
+#define MX8MM_IOMUXC_ECSPI1_SS0_UART3_DCE_RTS_B 0x200 0x468 0x500 0x1 0x1
+#define MX8MM_IOMUXC_ECSPI1_SS0_UART3_DTE_CTS_B 0x200 0x468 0x000 0x1 0x0
+#define MX8MM_IOMUXC_ECSPI1_SS0_GPIO5_IO9 0x200 0x468 0x000 0x5 0x0
+#define MX8MM_IOMUXC_ECSPI1_SS0_TPSMP_HDATA11 0x200 0x468 0x000 0x7 0x0
+#define MX8MM_IOMUXC_ECSPI2_SCLK_ECSPI2_SCLK 0x204 0x46C 0x000 0x0 0x0
+#define MX8MM_IOMUXC_ECSPI2_SCLK_UART4_DCE_RX 0x204 0x46C 0x50C 0x1 0x0
+#define MX8MM_IOMUXC_ECSPI2_SCLK_UART4_DTE_TX 0x204 0x46C 0x000 0x1 0x0
+#define MX8MM_IOMUXC_ECSPI2_SCLK_GPIO5_IO10 0x204 0x46C 0x000 0x5 0x0
+#define MX8MM_IOMUXC_ECSPI2_SCLK_TPSMP_HDATA12 0x204 0x46C 0x000 0x7 0x0
+#define MX8MM_IOMUXC_ECSPI2_MOSI_ECSPI2_MOSI 0x208 0x470 0x000 0x0 0x0
+#define MX8MM_IOMUXC_ECSPI2_MOSI_UART4_DCE_TX 0x208 0x470 0x000 0x1 0x0
+#define MX8MM_IOMUXC_ECSPI2_MOSI_UART4_DTE_RX 0x208 0x470 0x50C 0x1 0x1
+#define MX8MM_IOMUXC_ECSPI2_MOSI_GPIO5_IO11 0x208 0x470 0x000 0x5 0x0
+#define MX8MM_IOMUXC_ECSPI2_MOSI_TPSMP_HDATA13 0x208 0x470 0x000 0x7 0x0
+#define MX8MM_IOMUXC_ECSPI2_MISO_ECSPI2_MISO 0x20C 0x474 0x000 0x0 0x0
+#define MX8MM_IOMUXC_ECSPI2_MISO_UART4_DCE_CTS_B 0x20C 0x474 0x000 0x1 0x0
+#define MX8MM_IOMUXC_ECSPI2_MISO_UART4_DTE_RTS_B 0x20C 0x474 0x508 0x1 0x0
+#define MX8MM_IOMUXC_ECSPI2_MISO_GPIO5_IO12 0x20C 0x474 0x000 0x5 0x0
+#define MX8MM_IOMUXC_ECSPI2_MISO_TPSMP_HDATA14 0x20C 0x474 0x000 0x7 0x0
+#define MX8MM_IOMUXC_ECSPI2_SS0_ECSPI2_SS0 0x210 0x478 0x000 0x0 0x0
+#define MX8MM_IOMUXC_ECSPI2_SS0_UART4_DCE_RTS_B 0x210 0x478 0x508 0x1 0x1
+#define MX8MM_IOMUXC_ECSPI2_SS0_UART4_DTE_CTS_B 0x210 0x478 0x000 0x1 0x0
+#define MX8MM_IOMUXC_ECSPI2_SS0_GPIO5_IO13 0x210 0x478 0x000 0x5 0x0
+#define MX8MM_IOMUXC_ECSPI2_SS0_TPSMP_HDATA15 0x210 0x478 0x000 0x7 0x0
+#define MX8MM_IOMUXC_I2C1_SCL_I2C1_SCL 0x214 0x47C 0x000 0x0 0x0
+#define MX8MM_IOMUXC_I2C1_SCL_ENET1_MDC 0x214 0x47C 0x000 0x1 0x0
+#define MX8MM_IOMUXC_I2C1_SCL_GPIO5_IO14 0x214 0x47C 0x000 0x5 0x0
+#define MX8MM_IOMUXC_I2C1_SCL_TPSMP_HDATA16 0x214 0x47C 0x000 0x7 0x0
+#define MX8MM_IOMUXC_I2C1_SDA_I2C1_SDA 0x218 0x480 0x000 0x0 0x0
+#define MX8MM_IOMUXC_I2C1_SDA_ENET1_MDIO 0x218 0x480 0x4C0 0x1 0x2
+#define MX8MM_IOMUXC_I2C1_SDA_GPIO5_IO15 0x218 0x480 0x000 0x5 0x0
+#define MX8MM_IOMUXC_I2C1_SDA_TPSMP_HDATA17 0x218 0x480 0x000 0x7 0x0
+#define MX8MM_IOMUXC_I2C2_SCL_I2C2_SCL 0x21C 0x484 0x000 0x0 0x0
+#define MX8MM_IOMUXC_I2C2_SCL_ENET1_1588_EVENT1_IN 0x21C 0x484 0x000 0x1 0x0
+#define MX8MM_IOMUXC_I2C2_SCL_GPIO5_IO16 0x21C 0x484 0x000 0x5 0x0
+#define MX8MM_IOMUXC_I2C2_SCL_TPSMP_HDATA18 0x21C 0x484 0x000 0x7 0x0
+#define MX8MM_IOMUXC_I2C2_SDA_I2C2_SDA 0x220 0x488 0x000 0x0 0x0
+#define MX8MM_IOMUXC_I2C2_SDA_ENET1_1588_EVENT1_OUT 0x220 0x488 0x000 0x1 0x0
+#define MX8MM_IOMUXC_I2C2_SDA_GPIO5_IO17 0x220 0x488 0x000 0x5 0x0
+#define MX8MM_IOMUXC_I2C2_SDA_TPSMP_HDATA19 0x220 0x488 0x000 0x7 0x0
+#define MX8MM_IOMUXC_I2C3_SCL_I2C3_SCL 0x224 0x48C 0x000 0x0 0x0
+#define MX8MM_IOMUXC_I2C3_SCL_PWM4_OUT 0x224 0x48C 0x000 0x1 0x0
+#define MX8MM_IOMUXC_I2C3_SCL_GPT2_CLK 0x224 0x48C 0x000 0x2 0x0
+#define MX8MM_IOMUXC_I2C3_SCL_GPIO5_IO18 0x224 0x48C 0x000 0x5 0x0
+#define MX8MM_IOMUXC_I2C3_SCL_TPSMP_HDATA20 0x224 0x48C 0x000 0x7 0x0
+#define MX8MM_IOMUXC_I2C3_SDA_I2C3_SDA 0x228 0x490 0x000 0x0 0x0
+#define MX8MM_IOMUXC_I2C3_SDA_PWM3_OUT 0x228 0x490 0x000 0x1 0x0
+#define MX8MM_IOMUXC_I2C3_SDA_GPT3_CLK 0x228 0x490 0x000 0x2 0x0
+#define MX8MM_IOMUXC_I2C3_SDA_GPIO5_IO19 0x228 0x490 0x000 0x5 0x0
+#define MX8MM_IOMUXC_I2C3_SDA_TPSMP_HDATA21 0x228 0x490 0x000 0x7 0x0
+#define MX8MM_IOMUXC_I2C4_SCL_I2C4_SCL 0x22C 0x494 0x000 0x0 0x0
+#define MX8MM_IOMUXC_I2C4_SCL_PWM2_OUT 0x22C 0x494 0x000 0x1 0x0
+#define MX8MM_IOMUXC_I2C4_SCL_PCIE1_CLKREQ_B 0x22C 0x494 0x524 0x12 0x0
+#define MX8MM_IOMUXC_I2C4_SCL_GPIO5_IO20 0x22C 0x494 0x000 0x5 0x0
+#define MX8MM_IOMUXC_I2C4_SCL_TPSMP_HDATA22 0x22C 0x494 0x000 0x7 0x0
+#define MX8MM_IOMUXC_I2C4_SDA_I2C4_SDA 0x230 0x498 0x000 0x0 0x0
+#define MX8MM_IOMUXC_I2C4_SDA_PWM1_OUT 0x230 0x498 0x000 0x1 0x0
+#define MX8MM_IOMUXC_I2C4_SDA_PCIE2_CLKREQ_B 0x230 0x498 0x528 0x2 0x0
+#define MX8MM_IOMUXC_I2C4_SDA_GPIO5_IO21 0x230 0x498 0x000 0x5 0x0
+#define MX8MM_IOMUXC_I2C4_SDA_TPSMP_HDATA23 0x230 0x498 0x000 0x7 0x0
+#define MX8MM_IOMUXC_UART1_RXD_UART1_DCE_RX 0x234 0x49C 0x4F4 0x0 0x0
+#define MX8MM_IOMUXC_UART1_RXD_UART1_DTE_TX 0x234 0x49C 0x000 0x0 0x0
+#define MX8MM_IOMUXC_UART1_RXD_ECSPI3_SCLK 0x234 0x49C 0x000 0x1 0x0
+#define MX8MM_IOMUXC_UART1_RXD_GPIO5_IO22 0x234 0x49C 0x000 0x5 0x0
+#define MX8MM_IOMUXC_UART1_RXD_TPSMP_HDATA24 0x234 0x49C 0x000 0x7 0x0
+#define MX8MM_IOMUXC_UART1_TXD_UART1_DCE_TX 0x238 0x4A0 0x000 0x0 0x0
+#define MX8MM_IOMUXC_UART1_TXD_UART1_DTE_RX 0x238 0x4A0 0x4F4 0x0 0x0
+#define MX8MM_IOMUXC_UART1_TXD_ECSPI3_MOSI 0x238 0x4A0 0x000 0x1 0x0
+#define MX8MM_IOMUXC_UART1_TXD_GPIO5_IO23 0x238 0x4A0 0x000 0x5 0x0
+#define MX8MM_IOMUXC_UART1_TXD_TPSMP_HDATA25 0x238 0x4A0 0x000 0x7 0x0
+#define MX8MM_IOMUXC_UART2_RXD_UART2_DCE_RX 0x23C 0x4A4 0x4FC 0x0 0x0
+#define MX8MM_IOMUXC_UART2_RXD_UART2_DTE_TX 0x23C 0x4A4 0x000 0x0 0x0
+#define MX8MM_IOMUXC_UART2_RXD_ECSPI3_MISO 0x23C 0x4A4 0x000 0x1 0x0
+#define MX8MM_IOMUXC_UART2_RXD_GPIO5_IO24 0x23C 0x4A4 0x000 0x5 0x0
+#define MX8MM_IOMUXC_UART2_RXD_TPSMP_HDATA26 0x23C 0x4A4 0x000 0x7 0x0
+#define MX8MM_IOMUXC_UART2_TXD_UART2_DCE_TX 0x240 0x4A8 0x000 0x0 0x0
+#define MX8MM_IOMUXC_UART2_TXD_UART2_DTE_RX 0x240 0x4A8 0x4FC 0x0 0x1
+#define MX8MM_IOMUXC_UART2_TXD_ECSPI3_SS0 0x240 0x4A8 0x000 0x1 0x0
+#define MX8MM_IOMUXC_UART2_TXD_GPIO5_IO25 0x240 0x4A8 0x000 0x5 0x0
+#define MX8MM_IOMUXC_UART2_TXD_TPSMP_HDATA27 0x240 0x4A8 0x000 0x7 0x0
+#define MX8MM_IOMUXC_UART3_RXD_UART3_DCE_RX 0x244 0x4AC 0x504 0x0 0x2
+#define MX8MM_IOMUXC_UART3_RXD_UART3_DTE_TX 0x244 0x4AC 0x000 0x0 0x0
+#define MX8MM_IOMUXC_UART3_RXD_UART1_DCE_CTS_B 0x244 0x4AC 0x000 0x1 0x0
+#define MX8MM_IOMUXC_UART3_RXD_UART1_DTE_RTS_B 0x244 0x4AC 0x4F0 0x1 0x0
+#define MX8MM_IOMUXC_UART3_RXD_GPIO5_IO26 0x244 0x4AC 0x000 0x5 0x0
+#define MX8MM_IOMUXC_UART3_RXD_TPSMP_HDATA28 0x244 0x4AC 0x000 0x7 0x0
+#define MX8MM_IOMUXC_UART3_TXD_UART3_DCE_TX 0x248 0x4B0 0x000 0x0 0x0
+#define MX8MM_IOMUXC_UART3_TXD_UART3_DTE_RX 0x248 0x4B0 0x504 0x0 0x3
+#define MX8MM_IOMUXC_UART3_TXD_UART1_DCE_RTS_B 0x248 0x4B0 0x4F0 0x1 0x1
+#define MX8MM_IOMUXC_UART3_TXD_UART1_DTE_CTS_B 0x248 0x4B0 0x000 0x1 0x0
+#define MX8MM_IOMUXC_UART3_TXD_GPIO5_IO27 0x248 0x4B0 0x000 0x5 0x0
+#define MX8MM_IOMUXC_UART3_TXD_TPSMP_HDATA29 0x248 0x4B0 0x000 0x7 0x0
+#define MX8MM_IOMUXC_UART4_RXD_UART4_DCE_RX 0x24C 0x4B4 0x50C 0x0 0x2
+#define MX8MM_IOMUXC_UART4_RXD_UART4_DTE_TX 0x24C 0x4B4 0x000 0x0 0x0
+#define MX8MM_IOMUXC_UART4_RXD_UART2_DCE_CTS_B 0x24C 0x4B4 0x000 0x1 0x0
+#define MX8MM_IOMUXC_UART4_RXD_UART2_DTE_RTS_B 0x24C 0x4B4 0x4F8 0x1 0x0
+#define MX8MM_IOMUXC_UART4_RXD_PCIE1_CLKREQ_B 0x24C 0x4B4 0x524 0x2 0x1
+#define MX8MM_IOMUXC_UART4_RXD_GPIO5_IO28 0x24C 0x4B4 0x000 0x5 0x0
+#define MX8MM_IOMUXC_UART4_RXD_TPSMP_HDATA30 0x24C 0x4B4 0x000 0x7 0x0
+#define MX8MM_IOMUXC_UART4_TXD_UART4_DCE_TX 0x250 0x4B8 0x000 0x0 0x0
+#define MX8MM_IOMUXC_UART4_TXD_UART4_DTE_RX 0x250 0x4B8 0x50C 0x0 0x3
+#define MX8MM_IOMUXC_UART4_TXD_UART2_DCE_RTS_B 0x250 0x4B8 0x4F8 0x1 0x1
+#define MX8MM_IOMUXC_UART4_TXD_UART2_DTE_CTS_B 0x250 0x4B8 0x000 0x1 0x0
+#define MX8MM_IOMUXC_UART4_TXD_PCIE2_CLKREQ_B 0x250 0x4B8 0x528 0x2 0x1
+#define MX8MM_IOMUXC_UART4_TXD_GPIO5_IO29 0x250 0x4B8 0x000 0x5 0x0
+#define MX8MM_IOMUXC_UART4_TXD_TPSMP_HDATA31 0x250 0x4B8 0x000 0x7 0x0
+
+#endif /* __DTS_IMX8MM_PINFUNC_H */
diff --git a/include/dt-bindings/pinctrl/pins-imx8mq.h b/include/dt-bindings/pinctrl/pins-imx8mq.h
new file mode 100644
index 000000000000..498b76f11989
--- /dev/null
+++ b/include/dt-bindings/pinctrl/pins-imx8mq.h
@@ -0,0 +1,632 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017 NXP
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __DTS_IMX8MQ_PINFUNC_H
+#define __DTS_IMX8MQ_PINFUNC_H
+
+/*
+ * The pin function ID is a tuple of
+ * <mux_reg conf_reg input_reg mux_mode input_val>
+ */
+
+#define MX8MQ_IOMUXC_PMIC_STBY_REQ_CCMSRCGPCMIX_PMIC_STBY_REQ 0x014 0x27C 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_PMIC_ON_REQ_SNVSMIX_PMIC_ON_REQ 0x018 0x280 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_ONOFF_SNVSMIX_ONOFF 0x01C 0x284 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_POR_B_SNVSMIX_POR_B 0x020 0x288 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_RTC_RESET_B_SNVSMIX_RTC_RESET_B 0x024 0x28C 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO00_GPIO1_IO0 0x028 0x290 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO00_CCMSRCGPCMIX_ENET_PHY_REF_CLK_ROOT 0x028 0x290 0x4C0 0x1 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO00_ANAMIX_REF_CLK_32K 0x028 0x290 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO00_CCMSRCGPCMIX_EXT_CLK1 0x028 0x290 0x000 0x6 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO00_SJC_FAIL 0x028 0x290 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO01_GPIO1_IO1 0x02C 0x294 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO01_PWM1_OUT 0x02C 0x294 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO01_ANAMIX_REF_CLK_24M 0x02C 0x294 0x4BC 0x5 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO01_CCMSRCGPCMIX_EXT_CLK2 0x02C 0x294 0x000 0x6 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO01_SJC_ACTIVE 0x02C 0x294 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO02_GPIO1_IO2 0x030 0x298 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO02_WDOG1_WDOG_B 0x030 0x298 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO02_WDOG1_WDOG_ANY 0x030 0x298 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO02_SJC_DE_B 0x030 0x298 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO03_GPIO1_IO3 0x034 0x29C 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO03_USDHC1_VSELECT 0x034 0x29C 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO03_SDMA1_EXT_EVENT0 0x034 0x29C 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO03_ANAMIX_XTAL_OK 0x034 0x29C 0x000 0x6 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO03_SJC_DONE 0x034 0x29C 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO04_GPIO1_IO4 0x038 0x2A0 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0x038 0x2A0 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO04_SDMA1_EXT_EVENT1 0x038 0x2A0 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO04_ANAMIX_XTAL_OK_LV 0x038 0x2A0 0x000 0x6 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO04_USDHC1_TEST_TRIG 0x038 0x2A0 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO05_GPIO1_IO5 0x03C 0x2A4 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO05_M4_NMI 0x03C 0x2A4 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO05_CCMSRCGPCMIX_PMIC_READY 0x03C 0x2A4 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO05_CCMSRCGPCMIX_INT_BOOT 0x03C 0x2A4 0x000 0x6 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO05_USDHC2_TEST_TRIG 0x03C 0x2A4 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO06_GPIO1_IO6 0x040 0x2A8 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO06_ENET1_MDC 0x040 0x2A8 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO06_USDHC1_CD_B 0x040 0x2A8 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO06_CCMSRCGPCMIX_EXT_CLK3 0x040 0x2A8 0x000 0x6 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO06_ECSPI1_TEST_TRIG 0x040 0x2A8 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO07_GPIO1_IO7 0x044 0x2AC 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO07_ENET1_MDIO 0x044 0x2AC 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO07_USDHC1_WP 0x044 0x2AC 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO07_CCMSRCGPCMIX_EXT_CLK4 0x044 0x2AC 0x000 0x6 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO07_ECSPI2_TEST_TRIG 0x044 0x2AC 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO08_GPIO1_IO8 0x048 0x2B0 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO08_ENET1_1588_EVENT0_IN 0x048 0x2B0 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO08_USDHC2_RESET_B 0x048 0x2B0 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO08_CCMSRCGPCMIX_WAIT 0x048 0x2B0 0x000 0x6 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO08_QSPI_TEST_TRIG 0x048 0x2B0 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO09_GPIO1_IO9 0x04C 0x2B4 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO09_ENET1_1588_EVENT0_OUT 0x04C 0x2B4 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO09_SDMA2_EXT_EVENT0 0x04C 0x2B4 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO09_CCMSRCGPCMIX_STOP 0x04C 0x2B4 0x000 0x6 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO09_RAWNAND_TEST_TRIG 0x04C 0x2B4 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO10_GPIO1_IO10 0x050 0x2B8 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO10_USB1_OTG_ID 0x050 0x2B8 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO10_OCOTP_CTRL_WRAPPER_FUSE_LATCHED 0x050 0x2B8 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO11_GPIO1_IO11 0x054 0x2BC 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO11_USB2_OTG_ID 0x054 0x2BC 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO11_CCMSRCGPCMIX_PMIC_READY 0x054 0x2BC 0x4BC 0x5 0x1
+#define MX8MQ_IOMUXC_GPIO1_IO11_CCMSRCGPCMIX_OUT0 0x054 0x2BC 0x000 0x6 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO11_CAAM_WRAPPER_RNG_OSC_OBS 0x054 0x2BC 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO12_GPIO1_IO12 0x058 0x2C0 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO12_USB1_OTG_PWR 0x058 0x2C0 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO12_SDMA2_EXT_EVENT1 0x058 0x2C0 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO12_CCMSRCGPCMIX_OUT1 0x058 0x2C0 0x000 0x6 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO12_CSU_CSU_ALARM_AUT0 0x058 0x2C0 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO13_GPIO1_IO13 0x05C 0x2C4 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO13_USB1_OTG_OC 0x05C 0x2C4 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO13_PWM2_OUT 0x05C 0x2C4 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO13_CCMSRCGPCMIX_OUT2 0x05C 0x2C4 0x000 0x6 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO13_CSU_CSU_ALARM_AUT1 0x05C 0x2C4 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO14_GPIO1_IO14 0x060 0x2C8 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO14_USB2_OTG_PWR 0x060 0x2C8 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO14_PWM3_OUT 0x060 0x2C8 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO14_CCMSRCGPCMIX_CLKO1 0x060 0x2C8 0x000 0x6 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO14_CSU_CSU_ALARM_AUT2 0x060 0x2C8 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO15_GPIO1_IO15 0x064 0x2CC 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO15_USB2_OTG_OC 0x064 0x2CC 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO15_PWM4_OUT 0x064 0x2CC 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO15_CCMSRCGPCMIX_CLKO2 0x064 0x2CC 0x000 0x6 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO15_CSU_CSU_INT_DEB 0x064 0x2CC 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_ENET_MDC_ENET1_MDC 0x068 0x2D0 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_ENET_MDC_GPIO1_IO16 0x068 0x2D0 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_ENET_MDIO_ENET1_MDIO 0x06C 0x2D4 0x4C0 0x0 0x1
+#define MX8MQ_IOMUXC_ENET_MDIO_GPIO1_IO17 0x06C 0x2D4 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_ENET_TD3_ENET1_RGMII_TD3 0x070 0x2D8 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_ENET_TD3_GPIO1_IO18 0x070 0x2D8 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_ENET_TD2_ENET1_RGMII_TD2 0x074 0x2DC 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_ENET_TD2_ENET1_TX_CLK 0x074 0x2DC 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_ENET_TD2_GPIO1_IO19 0x074 0x2DC 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_ENET_TD1_ENET1_RGMII_TD1 0x078 0x2E0 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_ENET_TD1_GPIO1_IO20 0x078 0x2E0 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_ENET_TD0_ENET1_RGMII_TD0 0x07C 0x2E4 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_ENET_TD0_GPIO1_IO21 0x07C 0x2E4 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_ENET_TX_CTL_ENET1_RGMII_TX_CTL 0x080 0x2E8 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_ENET_TX_CTL_GPIO1_IO22 0x080 0x2E8 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_ENET_TXC_ENET1_RGMII_TXC 0x084 0x2EC 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_ENET_TXC_ENET1_TX_ER 0x084 0x2EC 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_ENET_TXC_GPIO1_IO23 0x084 0x2EC 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_ENET_RX_CTL_ENET1_RGMII_RX_CTL 0x088 0x2F0 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_ENET_RX_CTL_GPIO1_IO24 0x088 0x2F0 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_ENET_RXC_ENET1_RGMII_RXC 0x08C 0x2F4 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_ENET_RXC_ENET1_RX_ER 0x08C 0x2F4 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_ENET_RXC_GPIO1_IO25 0x08C 0x2F4 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_ENET_RD0_ENET1_RGMII_RD0 0x090 0x2F8 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_ENET_RD0_GPIO1_IO26 0x090 0x2F8 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_ENET_RD1_ENET1_RGMII_RD1 0x094 0x2FC 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_ENET_RD1_GPIO1_IO27 0x094 0x2FC 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_ENET_RD2_ENET1_RGMII_RD2 0x098 0x300 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_ENET_RD2_GPIO1_IO28 0x098 0x300 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_ENET_RD3_ENET1_RGMII_RD3 0x09C 0x304 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_ENET_RD3_GPIO1_IO29 0x09C 0x304 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SD1_CLK_USDHC1_CLK 0x0A0 0x308 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SD1_CLK_GPIO2_IO0 0x0A0 0x308 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SD1_CMD_USDHC1_CMD 0x0A4 0x30C 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SD1_CMD_GPIO2_IO1 0x0A4 0x30C 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SD1_DATA0_USDHC1_DATA0 0x0A8 0x310 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SD1_DATA0_GPIO2_IO2 0x0A8 0x31 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SD1_DATA1_USDHC1_DATA1 0x0AC 0x314 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SD1_DATA1_GPIO2_IO3 0x0AC 0x314 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SD1_DATA2_USDHC1_DATA2 0x0B0 0x318 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SD1_DATA2_GPIO2_IO4 0x0B0 0x318 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SD1_DATA3_USDHC1_DATA3 0x0B4 0x31C 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SD1_DATA3_GPIO2_IO5 0x0B4 0x31C 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SD1_DATA4_USDHC1_DATA4 0x0B8 0x320 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SD1_DATA4_GPIO2_IO6 0x0B8 0x320 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SD1_DATA5_USDHC1_DATA5 0x0BC 0x324 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SD1_DATA5_GPIO2_IO7 0x0BC 0x324 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SD1_DATA6_USDHC1_DATA6 0x0C0 0x328 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SD1_DATA6_GPIO2_IO8 0x0C0 0x328 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SD1_DATA7_USDHC1_DATA7 0x0C4 0x32C 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SD1_DATA7_GPIO2_IO9 0x0C4 0x32C 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SD1_RESET_B_USDHC1_RESET_B 0x0C8 0x330 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SD1_RESET_B_GPIO2_IO10 0x0C8 0x330 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SD1_STROBE_USDHC1_STROBE 0x0CC 0x334 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SD1_STROBE_GPIO2_IO11 0x0CC 0x334 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SD2_CD_B_USDHC2_CD_B 0x0D0 0x338 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SD2_CD_B_GPIO2_IO12 0x0D0 0x338 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SD2_CLK_USDHC2_CLK 0x0D4 0x33C 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SD2_CLK_GPIO2_IO13 0x0D4 0x33C 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SD2_CLK_CCMSRCGPCMIX_OBSERVE0 0x0D4 0x33C 0x000 0x6 0x0
+#define MX8MQ_IOMUXC_SD2_CLK_OBSERVE_MUX_OUT0 0x0D4 0x33C 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_SD2_CMD_USDHC2_CMD 0x0D8 0x340 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SD2_CMD_GPIO2_IO14 0x0D8 0x340 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SD2_CMD_CCMSRCGPCMIX_OBSERVE1 0x0D8 0x340 0x000 0x6 0x0
+#define MX8MQ_IOMUXC_SD2_CMD_OBSERVE_MUX_OUT1 0x0D8 0x340 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_SD2_DATA0_USDHC2_DATA0 0x0DC 0x344 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SD2_DATA0_GPIO2_IO15 0x0DC 0x344 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SD2_DATA0_CCMSRCGPCMIX_OBSERVE2 0x0DC 0x344 0x000 0x6 0x0
+#define MX8MQ_IOMUXC_SD2_DATA0_OBSERVE_MUX_OUT2 0x0DC 0x344 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_SD2_DATA1_USDHC2_DATA1 0x0E0 0x348 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SD2_DATA1_GPIO2_IO16 0x0E0 0x348 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SD2_DATA1_CCMSRCGPCMIX_WAIT 0x0E0 0x348 0x000 0x6 0x0
+#define MX8MQ_IOMUXC_SD2_DATA1_OBSERVE_MUX_OUT3 0x0E0 0x348 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_SD2_DATA2_USDHC2_DATA2 0x0E4 0x34C 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SD2_DATA2_GPIO2_IO17 0x0E4 0x34C 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SD2_DATA2_CCMSRCGPCMIX_STOP 0x0E4 0x34C 0x000 0x6 0x0
+#define MX8MQ_IOMUXC_SD2_DATA2_OBSERVE_MUX_OUT4 0x0E4 0x34C 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_SD2_DATA3_USDHC2_DATA3 0x0E8 0x350 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SD2_DATA3_GPIO2_IO18 0x0E8 0x350 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SD2_DATA3_CCMSRCGPCMIX_EARLY_RESET 0x0E8 0x350 0x000 0x6 0x0
+#define MX8MQ_IOMUXC_SD2_RESET_B_USDHC2_RESET_B 0x0EC 0x354 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SD2_RESET_B_GPIO2_IO19 0x0EC 0x354 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SD2_RESET_B_CCMSRCGPCMIX_SYSTEM_RESET 0x0EC 0x354 0x000 0x6 0x0
+#define MX8MQ_IOMUXC_SD2_WP_USDHC2_WP 0x0F0 0x358 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SD2_WP_GPIO2_IO20 0x0F0 0x358 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SD2_WP_SIM_M_HMASTLOCK 0x0F0 0x358 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_NAND_ALE_RAWNAND_ALE 0x0F4 0x35C 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_NAND_ALE_QSPI_A_SCLK 0x0F4 0x35C 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_NAND_ALE_GPIO3_IO0 0x0F4 0x35C 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_NAND_ALE_SIM_M_HPROT0 0x0F4 0x35C 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_NAND_CE0_B_RAWNAND_CE0_B 0x0F8 0x360 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_NAND_CE0_B_QSPI_A_SS0_B 0x0F8 0x360 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_NAND_CE0_B_GPIO3_IO1 0x0F8 0x360 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_NAND_CE0_B_SIM_M_HPROT1 0x0F8 0x360 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_NAND_CE1_B_RAWNAND_CE1_B 0x0FC 0x364 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_NAND_CE1_B_QSPI_A_SS1_B 0x0FC 0x364 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_NAND_CE1_B_GPIO3_IO2 0x0FC 0x364 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_NAND_CE1_B_SIM_M_HPROT2 0x0FC 0x364 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_NAND_CE2_B_RAWNAND_CE2_B 0x100 0x368 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_NAND_CE2_B_QSPI_B_SS0_B 0x100 0x368 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_NAND_CE2_B_GPIO3_IO3 0x100 0x368 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_NAND_CE2_B_SIM_M_HPROT3 0x100 0x368 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_NAND_CE3_B_RAWNAND_CE3_B 0x104 0x36C 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_NAND_CE3_B_QSPI_B_SS1_B 0x104 0x36C 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_NAND_CE3_B_GPIO3_IO4 0x104 0x36C 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_NAND_CE3_B_SIM_M_HADDR0 0x104 0x36C 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_NAND_CLE_RAWNAND_CLE 0x108 0x370 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_NAND_CLE_QSPI_B_SCLK 0x108 0x370 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_NAND_CLE_GPIO3_IO5 0x108 0x370 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_NAND_CLE_SIM_M_HADDR1 0x108 0x370 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_NAND_DATA00_RAWNAND_DATA00 0x10C 0x374 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_NAND_DATA00_QSPI_A_DATA0 0x10C 0x374 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_NAND_DATA00_GPIO3_IO6 0x10C 0x374 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_NAND_DATA00_SIM_M_HADDR2 0x10C 0x374 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_NAND_DATA01_RAWNAND_DATA01 0x110 0x378 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_NAND_DATA01_QSPI_A_DATA1 0x110 0x378 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_NAND_DATA01_GPIO3_IO7 0x110 0x378 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_NAND_DATA01_SIM_M_HADDR3 0x110 0x378 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_NAND_DATA02_RAWNAND_DATA02 0x114 0x37C 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_NAND_DATA02_QSPI_A_DATA2 0x114 0x37C 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_NAND_DATA02_GPIO3_IO8 0x114 0x37C 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_NAND_DATA02_SIM_M_HADDR4 0x114 0x37C 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_NAND_DATA03_RAWNAND_DATA03 0x118 0x380 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_NAND_DATA03_QSPI_A_DATA3 0x118 0x380 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_NAND_DATA03_GPIO3_IO9 0x118 0x380 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_NAND_DATA03_SIM_M_HADDR5 0x118 0x380 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_NAND_DATA04_RAWNAND_DATA04 0x11C 0x384 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_NAND_DATA04_QSPI_B_DATA0 0x11C 0x384 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_NAND_DATA04_GPIO3_IO10 0x11C 0x384 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_NAND_DATA04_SIM_M_HADDR6 0x11C 0x384 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_NAND_DATA05_RAWNAND_DATA05 0x120 0x388 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_NAND_DATA05_QSPI_B_DATA1 0x120 0x388 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_NAND_DATA05_GPIO3_IO11 0x120 0x388 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_NAND_DATA05_SIM_M_HADDR7 0x120 0x388 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_NAND_DATA06_RAWNAND_DATA06 0x124 0x38C 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_NAND_DATA06_QSPI_B_DATA2 0x124 0x38C 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_NAND_DATA06_GPIO3_IO12 0x124 0x38C 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_NAND_DATA06_SIM_M_HADDR8 0x124 0x38C 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_NAND_DATA07_RAWNAND_DATA07 0x128 0x390 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_NAND_DATA07_QSPI_B_DATA3 0x128 0x390 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_NAND_DATA07_GPIO3_IO13 0x128 0x390 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_NAND_DATA07_SIM_M_HADDR9 0x128 0x390 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_NAND_DQS_RAWNAND_DQS 0x12C 0x394 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_NAND_DQS_QSPI_A_DQS 0x12C 0x394 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_NAND_DQS_GPIO3_IO14 0x12C 0x394 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_NAND_DQS_SIM_M_HADDR10 0x12C 0x394 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_NAND_RE_B_RAWNAND_RE_B 0x130 0x398 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_NAND_RE_B_QSPI_B_DQS 0x130 0x398 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_NAND_RE_B_GPIO3_IO15 0x130 0x398 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_NAND_RE_B_SIM_M_HADDR11 0x130 0x398 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_NAND_READY_B_RAWNAND_READY_B 0x134 0x39C 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_NAND_READY_B_GPIO3_IO16 0x134 0x39C 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_NAND_READY_B_SIM_M_HADDR12 0x134 0x39C 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_NAND_WE_B_RAWNAND_WE_B 0x138 0x3A0 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_NAND_WE_B_GPIO3_IO17 0x138 0x3A0 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_NAND_WE_B_SIM_M_HADDR13 0x138 0x3A0 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_NAND_WP_B_RAWNAND_WP_B 0x13C 0x3A4 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_NAND_WP_B_GPIO3_IO18 0x13C 0x3A4 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_NAND_WP_B_SIM_M_HADDR14 0x13C 0x3A4 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_SAI5_RXFS_SAI5_RX_SYNC 0x140 0x3A8 0x4E4 0x0 0x0
+#define MX8MQ_IOMUXC_SAI5_RXFS_SAI1_TX_DATA0 0x140 0x3A8 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_SAI5_RXFS_GPIO3_IO19 0x140 0x3A8 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SAI5_RXC_SAI5_RX_BCLK 0x144 0x3AC 0x4D0 0x0 0x0
+#define MX8MQ_IOMUXC_SAI5_RXC_SAI1_TX_DATA1 0x144 0x3AC 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_SAI5_RXC_GPIO3_IO20 0x144 0x3AC 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SAI5_RXD0_SAI5_RX_DATA0 0x148 0x3B0 0x4D4 0x0 0x0
+#define MX8MQ_IOMUXC_SAI5_RXD0_SAI1_TX_DATA2 0x148 0x3B0 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_SAI5_RXD0_GPIO3_IO21 0x148 0x3B0 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SAI5_RXD1_SAI5_RX_DATA1 0x14C 0x3B4 0x4D8 0x0 0x0
+#define MX8MQ_IOMUXC_SAI5_RXD1_SAI1_TX_DATA3 0x14C 0x3B4 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_SAI5_RXD1_SAI1_TX_SYNC 0x14C 0x3B4 0x4CC 0x2 0x0
+#define MX8MQ_IOMUXC_SAI5_RXD1_SAI5_TX_SYNC 0x14C 0x3B4 0x4EC 0x3 0x0
+#define MX8MQ_IOMUXC_SAI5_RXD1_GPIO3_IO22 0x14C 0x3B4 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SAI5_RXD2_SAI5_RX_DATA2 0x150 0x3B8 0x4DC 0x0 0x0
+#define MX8MQ_IOMUXC_SAI5_RXD2_SAI1_TX_DATA4 0x150 0x3B8 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_SAI5_RXD2_SAI1_TX_SYNC 0x150 0x3B8 0x4CC 0x2 0x1
+#define MX8MQ_IOMUXC_SAI5_RXD2_SAI5_TX_BCLK 0x150 0x3B8 0x4E8 0x3 0x0
+#define MX8MQ_IOMUXC_SAI5_RXD2_GPIO3_IO23 0x150 0x3B8 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SAI5_RXD3_SAI5_RX_DATA3 0x154 0x3BC 0x4E0 0x0 0x0
+#define MX8MQ_IOMUXC_SAI5_RXD3_SAI1_TX_DATA5 0x154 0x3BC 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_SAI5_RXD3_SAI1_TX_SYNC 0x154 0x3BC 0x4CC 0x2 0x2
+#define MX8MQ_IOMUXC_SAI5_RXD3_SAI5_TX_DATA0 0x154 0x3BC 0x000 0x3 0x0
+#define MX8MQ_IOMUXC_SAI5_RXD3_GPIO3_IO24 0x154 0x3BC 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SAI5_MCLK_SAI5_MCLK 0x158 0x3C0 0x52C 0x0 0x0
+#define MX8MQ_IOMUXC_SAI5_MCLK_SAI1_TX_BCLK 0x158 0x3C0 0x4C8 0x1 0x0
+#define MX8MQ_IOMUXC_SAI5_MCLK_SAI4_MCLK 0x158 0x3C0 0x000 0x2 0x0
+#define MX8MQ_IOMUXC_SAI5_MCLK_GPIO3_IO25 0x158 0x3C0 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SAI5_MCLK_CCMSRCGPCMIX_TESTER_ACK 0x158 0x3C0 0x000 0x6 0x0
+#define MX8MQ_IOMUXC_SAI1_RXFS_SAI1_RX_SYNC 0x15C 0x3C4 0x4C4 0x0 0x0
+#define MX8MQ_IOMUXC_SAI1_RXFS_SAI5_RX_SYNC 0x15C 0x3C4 0x4E4 0x1 0x1
+#define MX8MQ_IOMUXC_SAI1_RXFS_CORESIGHT_TRACE_CLK 0x15C 0x3C4 0x000 0x4 0x0
+#define MX8MQ_IOMUXC_SAI1_RXFS_GPIO4_IO0 0x15C 0x3C4 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SAI1_RXFS_SIM_M_HADDR15 0x15C 0x3C4 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_SAI1_RXC_SAI1_RX_BCLK 0x160 0x3C8 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SAI1_RXC_SAI5_RX_BCLK 0x160 0x3C8 0x4D0 0x1 0x1
+#define MX8MQ_IOMUXC_SAI1_RXC_CORESIGHT_TRACE_CTL 0x160 0x3C8 0x000 0x4 0x0
+#define MX8MQ_IOMUXC_SAI1_RXC_GPIO4_IO1 0x160 0x3C8 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SAI1_RXC_SIM_M_HADDR16 0x160 0x3C8 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD0_SAI1_RX_DATA0 0x164 0x3CC 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD0_SAI5_RX_DATA0 0x164 0x3CC 0x4D4 0x1 0x1
+#define MX8MQ_IOMUXC_SAI1_RXD0_CORESIGHT_TRACE0 0x164 0x3CC 0x000 0x4 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD0_GPIO4_IO2 0x164 0x3CC 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD0_CCMSRCGPCMIX_BOOT_CFG0 0x164 0x3CC 0x000 0x6 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD0_SIM_M_HADDR17 0x164 0x3CC 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD1_SAI1_RX_DATA1 0x168 0x3D0 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD1_SAI5_RX_DATA1 0x168 0x3D0 0x4D8 0x1 0x1
+#define MX8MQ_IOMUXC_SAI1_RXD1_CORESIGHT_TRACE1 0x168 0x3D0 0x000 0x4 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD1_GPIO4_IO3 0x168 0x3D0 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD1_CCMSRCGPCMIX_BOOT_CFG1 0x168 0x3D0 0x000 0x6 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD1_SIM_M_HADDR18 0x168 0x3D0 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD2_SAI1_RX_DATA2 0x16C 0x3D4 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD2_SAI5_RX_DATA2 0x16C 0x3D4 0x4DC 0x1 0x1
+#define MX8MQ_IOMUXC_SAI1_RXD2_CORESIGHT_TRACE2 0x16C 0x3D4 0x000 0x4 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD2_GPIO4_IO4 0x16C 0x3D4 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD2_CCMSRCGPCMIX_BOOT_CFG2 0x16C 0x3D4 0x000 0x6 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD2_SIM_M_HADDR19 0x16C 0x3D4 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD3_SAI1_RX_DATA3 0x170 0x3D8 0x4E0 0x0 0x1
+#define MX8MQ_IOMUXC_SAI1_RXD3_SAI5_RX_DATA3 0x170 0x3D8 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD3_CORESIGHT_TRACE3 0x170 0x3D8 0x000 0x4 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD3_GPIO4_IO5 0x170 0x3D8 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD3_CCMSRCGPCMIX_BOOT_CFG3 0x170 0x3D8 0x000 0x6 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD3_SIM_M_HADDR20 0x170 0x3D8 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD4_SAI1_RX_DATA4 0x174 0x3DC 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD4_SAI6_TX_BCLK 0x174 0x3DC 0x51C 0x1 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD4_SAI6_RX_BCLK 0x174 0x3DC 0x510 0x2 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD4_CORESIGHT_TRACE4 0x174 0x3DC 0x000 0x4 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD4_GPIO4_IO6 0x174 0x3DC 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD4_CCMSRCGPCMIX_BOOT_CFG4 0x174 0x3DC 0x000 0x6 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD4_SIM_M_HADDR21 0x174 0x3DC 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD5_SAI1_RX_DATA5 0x178 0x3E0 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD5_SAI6_TX_DATA0 0x178 0x3E0 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD5_SAI6_RX_DATA0 0x178 0x3E0 0x514 0x2 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD5_SAI1_RX_SYNC 0x178 0x3E0 0x4C4 0x3 0x1
+#define MX8MQ_IOMUXC_SAI1_RXD5_CORESIGHT_TRACE5 0x178 0x3E0 0x000 0x4 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD5_GPIO4_IO7 0x178 0x3E0 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD5_CCMSRCGPCMIX_BOOT_CFG5 0x178 0x3E0 0x000 0x6 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD5_SIM_M_HADDR22 0x178 0x3E0 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD6_SAI1_RX_DATA6 0x17C 0x3E4 0x520 0x0 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD6_SAI6_TX_SYNC 0x17C 0x3E4 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD6_SAI6_RX_SYNC 0x17C 0x3E4 0x518 0x2 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD6_CORESIGHT_TRACE6 0x17C 0x3E4 0x000 0x4 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD6_GPIO4_IO8 0x17C 0x3E4 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD6_CCMSRCGPCMIX_BOOT_CFG6 0x17C 0x3E4 0x000 0x6 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD6_SIM_M_HADDR23 0x17C 0x3E4 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD7_SAI1_RX_DATA7 0x180 0x3E8 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD7_SAI6_MCLK 0x180 0x3E8 0x530 0x1 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD7_SAI1_TX_SYNC 0x180 0x3E8 0x4CC 0x2 0x4
+#define MX8MQ_IOMUXC_SAI1_RXD7_SAI1_TX_DATA4 0x180 0x3E8 0x000 0x3 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD7_CORESIGHT_TRACE7 0x180 0x3E8 0x000 0x4 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD7_GPIO4_IO9 0x180 0x3E8 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD7_CCMSRCGPCMIX_BOOT_CFG7 0x180 0x3E8 0x000 0x6 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD7_SIM_M_HADDR24 0x180 0x3E8 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_SAI1_TXFS_SAI1_TX_SYNC 0x184 0x3EC 0x4CC 0x0 0x3
+#define MX8MQ_IOMUXC_SAI1_TXFS_SAI5_TX_SYNC 0x184 0x3EC 0x4EC 0x1 0x1
+#define MX8MQ_IOMUXC_SAI1_TXFS_CORESIGHT_EVENTO 0x184 0x3EC 0x000 0x4 0x0
+#define MX8MQ_IOMUXC_SAI1_TXFS_GPIO4_IO10 0x184 0x3EC 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SAI1_TXFS_SIM_M_HADDR25 0x184 0x3EC 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_SAI1_TXC_SAI1_TX_BCLK 0x188 0x3F0 0x4C8 0x0 0x1
+#define MX8MQ_IOMUXC_SAI1_TXC_SAI5_TX_BCLK 0x188 0x3F0 0x4E8 0x1 0x1
+#define MX8MQ_IOMUXC_SAI1_TXC_CORESIGHT_EVENTI 0x188 0x3F0 0x000 0x4 0x0
+#define MX8MQ_IOMUXC_SAI1_TXC_GPIO4_IO11 0x188 0x3F0 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SAI1_TXC_SIM_M_HADDR26 0x188 0x3F0 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD0_SAI1_TX_DATA0 0x18C 0x3F4 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD0_SAI5_TX_DATA0 0x18C 0x3F4 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD0_CORESIGHT_TRACE8 0x18C 0x3F4 0x000 0x4 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD0_GPIO4_IO12 0x18C 0x3F4 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD0_CCMSRCGPCMIX_BOOT_CFG8 0x18C 0x3F4 0x000 0x6 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD0_SIM_M_HADDR27 0x18C 0x3F4 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD1_SAI1_TX_DATA1 0x190 0x3F8 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD1_SAI5_TX_DATA1 0x190 0x3F8 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD1_CORESIGHT_TRACE9 0x190 0x3F8 0x000 0x4 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD1_GPIO4_IO13 0x190 0x3F8 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD1_CCMSRCGPCMIX_BOOT_CFG9 0x190 0x3F8 0x000 0x6 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD1_SIM_M_HADDR28 0x190 0x3F8 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD2_SAI1_TX_DATA2 0x194 0x3FC 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD2_SAI5_TX_DATA2 0x194 0x3FC 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD2_CORESIGHT_TRACE10 0x194 0x3FC 0x000 0x4 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD2_GPIO4_IO14 0x194 0x3FC 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD2_CCMSRCGPCMIX_BOOT_CFG10 0x194 0x3FC 0x000 0x6 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD2_SIM_M_HADDR29 0x194 0x3FC 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD3_SAI1_TX_DATA3 0x198 0x400 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD3_SAI5_TX_DATA3 0x198 0x400 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD3_CORESIGHT_TRACE11 0x198 0x400 0x000 0x4 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD3_GPIO4_IO15 0x198 0x400 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD3_CCMSRCGPCMIX_BOOT_CFG11 0x198 0x400 0x000 0x6 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD3_SIM_M_HADDR30 0x198 0x400 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD4_SAI1_TX_DATA4 0x19C 0x404 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD4_SAI6_RX_BCLK 0x19C 0x404 0x510 0x1 0x1
+#define MX8MQ_IOMUXC_SAI1_TXD4_SAI6_TX_BCLK 0x19C 0x404 0x51C 0x2 0x1
+#define MX8MQ_IOMUXC_SAI1_TXD4_CORESIGHT_TRACE12 0x19C 0x404 0x000 0x4 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD4_GPIO4_IO16 0x19C 0x404 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD4_CCMSRCGPCMIX_BOOT_CFG12 0x19C 0x404 0x000 0x6 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD4_SIM_M_HADDR31 0x19C 0x404 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD5_SAI1_TX_DATA5 0x1A0 0x408 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD5_SAI6_RX_DATA0 0x1A0 0x408 0x514 0x1 0x1
+#define MX8MQ_IOMUXC_SAI1_TXD5_SAI6_TX_DATA0 0x1A0 0x408 0x000 0x2 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD5_CORESIGHT_TRACE13 0x1A0 0x408 0x000 0x4 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD5_GPIO4_IO17 0x1A0 0x408 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD5_CCMSRCGPCMIX_BOOT_CFG13 0x1A0 0x408 0x000 0x6 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD5_SIM_M_HBURST0 0x1A0 0x408 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD6_SAI1_TX_DATA6 0x1A4 0x40C 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD6_SAI6_RX_SYNC 0x1A4 0x40C 0x518 0x1 0x1
+#define MX8MQ_IOMUXC_SAI1_TXD6_SAI6_TX_SYNC 0x1A4 0x40C 0x520 0x2 0x1
+#define MX8MQ_IOMUXC_SAI1_TXD6_CORESIGHT_TRACE14 0x1A4 0x40C 0x000 0x4 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD6_GPIO4_IO18 0x1A4 0x40C 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD6_CCMSRCGPCMIX_BOOT_CFG14 0x1A4 0x40C 0x000 0x6 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD6_SIM_M_HBURST1 0x1A4 0x40C 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD7_SAI1_TX_DATA7 0x1A8 0x410 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD7_SAI6_MCLK 0x1A8 0x410 0x530 0x1 0x1
+#define MX8MQ_IOMUXC_SAI1_TXD7_CORESIGHT_TRACE15 0x1A8 0x410 0x000 0x4 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD7_GPIO4_IO19 0x1A8 0x410 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD7_CCMSRCGPCMIX_BOOT_CFG15 0x1A8 0x410 0x000 0x6 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD7_SIM_M_HBURST2 0x1A8 0x410 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_SAI1_MCLK_SAI1_MCLK 0x1AC 0x414 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SAI1_MCLK_SAI5_MCLK 0x1AC 0x414 0x52C 0x1 0x1
+#define MX8MQ_IOMUXC_SAI1_MCLK_SAI1_TX_BCLK 0x1AC 0x414 0x4C8 0x2 0x2
+#define MX8MQ_IOMUXC_SAI1_MCLK_GPIO4_IO20 0x1AC 0x414 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SAI1_MCLK_SIM_M_HRESP 0x1AC 0x414 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_SAI2_RXFS_SAI2_RX_SYNC 0x1B0 0x418 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SAI2_RXFS_SAI5_TX_SYNC 0x1B0 0x418 0x4EC 0x1 0x2
+#define MX8MQ_IOMUXC_SAI2_RXFS_GPIO4_IO21 0x1B0 0x418 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SAI2_RXFS_SIM_M_HSIZE0 0x1B0 0x418 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_SAI2_RXC_SAI2_RX_BCLK 0x1B4 0x41C 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SAI2_RXC_SAI5_TX_BCLK 0x1B4 0x41C 0x4E8 0x1 0x2
+#define MX8MQ_IOMUXC_SAI2_RXC_GPIO4_IO22 0x1B4 0x41C 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SAI2_RXC_SIM_M_HSIZE1 0x1B4 0x41C 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_SAI2_RXD0_SAI2_RX_DATA0 0x1B8 0x420 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SAI2_RXD0_SAI5_TX_DATA0 0x1B8 0x420 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_SAI2_RXD0_GPIO4_IO23 0x1B8 0x420 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SAI2_RXD0_SIM_M_HSIZE2 0x1B8 0x420 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_SAI2_TXFS_SAI2_TX_SYNC 0x1BC 0x424 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SAI2_TXFS_SAI5_TX_DATA1 0x1BC 0x424 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_SAI2_TXFS_GPIO4_IO24 0x1BC 0x424 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SAI2_TXFS_SIM_M_HWRITE 0x1BC 0x424 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_SAI2_TXC_SAI2_TX_BCLK 0x1C0 0x428 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SAI2_TXC_SAI5_TX_DATA2 0x1C0 0x428 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_SAI2_TXC_GPIO4_IO25 0x1C0 0x428 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SAI2_TXC_SIM_M_HREADYOUT 0x1C0 0x428 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_SAI2_TXD0_SAI2_TX_DATA0 0x1C4 0x42C 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SAI2_TXD0_SAI5_TX_DATA3 0x1C4 0x42C 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_SAI2_TXD0_GPIO4_IO26 0x1C4 0x42C 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SAI2_TXD0_TPSMP_CLK 0x1C4 0x42C 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_SAI2_MCLK_SAI2_MCLK 0x1C8 0x430 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SAI2_MCLK_SAI5_MCLK 0x1C8 0x430 0x52C 0x1 0x2
+#define MX8MQ_IOMUXC_SAI2_MCLK_GPIO4_IO27 0x1C8 0x430 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SAI2_MCLK_TPSMP_HDATA_DIR 0x1C8 0x430 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_SAI3_RXFS_SAI3_RX_SYNC 0x1CC 0x434 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SAI3_RXFS_GPT1_CAPTURE1 0x1CC 0x434 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_SAI3_RXFS_SAI5_RX_SYNC 0x1CC 0x434 0x4E4 0x2 0x2
+#define MX8MQ_IOMUXC_SAI3_RXFS_GPIO4_IO28 0x1CC 0x434 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SAI3_RXFS_TPSMP_HTRANS0 0x1CC 0x434 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_SAI3_RXC_SAI3_RX_BCLK 0x1D0 0x438 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SAI3_RXC_GPT1_CAPTURE2 0x1D0 0x438 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_SAI3_RXC_SAI5_RX_BCLK 0x1D0 0x438 0x4D0 0x2 0x2
+#define MX8MQ_IOMUXC_SAI3_RXC_GPIO4_IO29 0x1D0 0x438 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SAI3_RXC_TPSMP_HTRANS1 0x1D0 0x438 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_SAI3_RXD_SAI3_RX_DATA0 0x1D4 0x43C 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SAI3_RXD_GPT1_COMPARE1 0x1D4 0x43C 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_SAI3_RXD_SAI5_RX_DATA0 0x1D4 0x43C 0x4D4 0x2 0x2
+#define MX8MQ_IOMUXC_SAI3_RXD_GPIO4_IO30 0x1D4 0x43C 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SAI3_RXD_TPSMP_HDATA0 0x1D4 0x43C 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_SAI3_TXFS_SAI3_TX_SYNC 0x1D8 0x440 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SAI3_TXFS_GPT1_CLK 0x1D8 0x440 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_SAI3_TXFS_SAI5_RX_DATA1 0x1D8 0x440 0x4D8 0x2 0x2
+#define MX8MQ_IOMUXC_SAI3_TXFS_GPIO4_IO31 0x1D8 0x440 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SAI3_TXFS_TPSMP_HDATA1 0x1D8 0x440 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_SAI3_TXC_SAI3_TX_BCLK 0x1DC 0x444 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SAI3_TXC_GPT1_COMPARE2 0x1DC 0x444 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_SAI3_TXC_SAI5_RX_DATA2 0x1DC 0x444 0x4DC 0x2 0x2
+#define MX8MQ_IOMUXC_SAI3_TXC_GPIO5_IO0 0x1DC 0x444 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SAI3_TXC_TPSMP_HDATA2 0x1DC 0x444 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_SAI3_TXD_SAI3_TX_DATA0 0x1E0 0x448 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SAI3_TXD_GPT1_COMPARE3 0x1E0 0x448 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_SAI3_TXD_SAI5_RX_DATA3 0x1E0 0x448 0x4E0 0x2 0x2
+#define MX8MQ_IOMUXC_SAI3_TXD_GPIO5_IO1 0x1E0 0x448 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SAI3_TXD_TPSMP_HDATA3 0x1E0 0x448 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_SAI3_MCLK_SAI3_MCLK 0x1E4 0x44C 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SAI3_MCLK_PWM4_OUT 0x1E4 0x44C 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_SAI3_MCLK_SAI5_MCLK 0x1E4 0x44C 0x52C 0x2 0x3
+#define MX8MQ_IOMUXC_SAI3_MCLK_GPIO5_IO2 0x1E4 0x44C 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SAI3_MCLK_TPSMP_HDATA4 0x1E4 0x44C 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_SPDIF_TX_SPDIF1_OUT 0x1E8 0x450 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SPDIF_TX_PWM3_OUT 0x1E8 0x450 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_SPDIF_TX_GPIO5_IO3 0x1E8 0x450 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SPDIF_TX_TPSMP_HDATA5 0x1E8 0x450 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_SPDIF_RX_SPDIF1_IN 0x1EC 0x454 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SPDIF_RX_PWM2_OUT 0x1EC 0x454 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_SPDIF_RX_GPIO5_IO4 0x1EC 0x454 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SPDIF_RX_TPSMP_HDATA6 0x1EC 0x454 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_SPDIF_EXT_CLK_SPDIF1_EXT_CLK 0x1F0 0x458 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SPDIF_EXT_CLK_PWM1_OUT 0x1F0 0x458 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_SPDIF_EXT_CLK_GPIO5_IO5 0x1F0 0x458 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SPDIF_EXT_CLK_TPSMP_HDATA7 0x1F0 0x458 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_ECSPI1_SCLK_ECSPI1_SCLK 0x1F4 0x45C 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_ECSPI1_SCLK_UART3_DCE_RX 0x1F4 0x45C 0x504 0x1 0x0
+#define MX8MQ_IOMUXC_ECSPI1_SCLK_UART3_DTE_TX 0x1F4 0x45C 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_ECSPI1_SCLK_GPIO5_IO6 0x1F4 0x45C 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_ECSPI1_SCLK_TPSMP_HDATA8 0x1F4 0x45C 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_ECSPI1_MOSI_ECSPI1_MOSI 0x1F8 0x460 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_ECSPI1_MOSI_UART3_DCE_TX 0x1F8 0x460 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_ECSPI1_MOSI_UART3_DTE_RX 0x1F8 0x460 0x504 0x1 0x1
+#define MX8MQ_IOMUXC_ECSPI1_MOSI_GPIO5_IO7 0x1F8 0x460 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_ECSPI1_MOSI_TPSMP_HDATA9 0x1F8 0x460 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_ECSPI1_MISO_ECSPI1_MISO 0x1FC 0x464 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_ECSPI1_MISO_UART3_DCE_CTS_B 0x1FC 0x464 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_ECSPI1_MISO_UART3_DTE_RTS_B 0x1FC 0x464 0x500 0x1 0x0
+#define MX8MQ_IOMUXC_ECSPI1_MISO_GPIO5_IO8 0x1FC 0x464 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_ECSPI1_MISO_TPSMP_HDATA10 0x1FC 0x464 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_ECSPI1_SS0_ECSPI1_SS0 0x200 0x468 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_ECSPI1_SS0_UART3_DCE_RTS_B 0x200 0x468 0x500 0x1 0x1
+#define MX8MQ_IOMUXC_ECSPI1_SS0_UART3_DTE_CTS_B 0x200 0x468 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_ECSPI1_SS0_GPIO5_IO9 0x200 0x468 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_ECSPI1_SS0_TPSMP_HDATA11 0x200 0x468 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_ECSPI2_SCLK_ECSPI2_SCLK 0x204 0x46C 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_ECSPI2_SCLK_UART4_DCE_RX 0x204 0x46C 0x50C 0x1 0x0
+#define MX8MQ_IOMUXC_ECSPI2_SCLK_UART4_DTE_TX 0x204 0x46C 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_ECSPI2_SCLK_GPIO5_IO10 0x204 0x46C 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_ECSPI2_SCLK_TPSMP_HDATA12 0x204 0x46C 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_ECSPI2_MOSI_ECSPI2_MOSI 0x208 0x470 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_ECSPI2_MOSI_UART4_DCE_TX 0x208 0x470 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_ECSPI2_MOSI_UART4_DTE_RX 0x208 0x470 0x50C 0x1 0x1
+#define MX8MQ_IOMUXC_ECSPI2_MOSI_GPIO5_IO11 0x208 0x470 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_ECSPI2_MOSI_TPSMP_HDATA13 0x208 0x470 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_ECSPI2_MISO_ECSPI2_MISO 0x20C 0x474 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_ECSPI2_MISO_UART4_DCE_CTS_B 0x20C 0x474 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_ECSPI2_MISO_UART4_DTE_RTS_B 0x20C 0x474 0x508 0x1 0x0
+#define MX8MQ_IOMUXC_ECSPI2_MISO_GPIO5_IO12 0x20C 0x474 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_ECSPI2_MISO_TPSMP_HDATA14 0x20C 0x474 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_ECSPI2_SS0_ECSPI2_SS0 0x210 0x478 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_ECSPI2_SS0_UART4_DCE_RTS_B 0x210 0x478 0x508 0x1 0x1
+#define MX8MQ_IOMUXC_ECSPI2_SS0_UART4_DTE_CTS_B 0x210 0x478 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_ECSPI2_SS0_GPIO5_IO13 0x210 0x478 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_ECSPI2_SS0_TPSMP_HDATA15 0x210 0x478 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_I2C1_SCL_I2C1_SCL 0x214 0x47C 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_I2C1_SCL_ENET1_MDC 0x214 0x47C 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_I2C1_SCL_GPIO5_IO14 0x214 0x47C 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_I2C1_SCL_TPSMP_HDATA16 0x214 0x47C 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_I2C1_SDA_I2C1_SDA 0x218 0x480 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_I2C1_SDA_ENET1_MDIO 0x218 0x480 0x4C0 0x1 0x2
+#define MX8MQ_IOMUXC_I2C1_SDA_GPIO5_IO15 0x218 0x480 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_I2C1_SDA_TPSMP_HDATA17 0x218 0x480 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_I2C2_SCL_I2C2_SCL 0x21C 0x484 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_I2C2_SCL_ENET1_1588_EVENT1_IN 0x21C 0x484 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_I2C2_SCL_GPIO5_IO16 0x21C 0x484 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_I2C2_SCL_TPSMP_HDATA18 0x21C 0x484 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_I2C2_SDA_I2C2_SDA 0x220 0x488 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_I2C2_SDA_ENET1_1588_EVENT1_OUT 0x220 0x488 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_I2C2_SDA_GPIO5_IO17 0x220 0x488 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_I2C2_SDA_TPSMP_HDATA19 0x220 0x488 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_I2C3_SCL_I2C3_SCL 0x224 0x48C 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_I2C3_SCL_PWM4_OUT 0x224 0x48C 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_I2C3_SCL_GPT2_CLK 0x224 0x48C 0x000 0x2 0x0
+#define MX8MQ_IOMUXC_I2C3_SCL_GPIO5_IO18 0x224 0x48C 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_I2C3_SCL_TPSMP_HDATA20 0x224 0x48C 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_I2C3_SDA_I2C3_SDA 0x228 0x490 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_I2C3_SDA_PWM3_OUT 0x228 0x490 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_I2C3_SDA_GPT3_CLK 0x228 0x490 0x000 0x2 0x0
+#define MX8MQ_IOMUXC_I2C3_SDA_GPIO5_IO19 0x228 0x490 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_I2C3_SDA_TPSMP_HDATA21 0x228 0x490 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_I2C4_SCL_I2C4_SCL 0x22C 0x494 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_I2C4_SCL_PWM2_OUT 0x22C 0x494 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_I2C4_SCL_PCIE1_CLKREQ_B 0x22C 0x494 0x524 0x12 0x0
+#define MX8MQ_IOMUXC_I2C4_SCL_GPIO5_IO20 0x22C 0x494 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_I2C4_SCL_TPSMP_HDATA22 0x22C 0x494 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_I2C4_SDA_I2C4_SDA 0x230 0x498 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_I2C4_SDA_PWM1_OUT 0x230 0x498 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_I2C4_SDA_PCIE2_CLKREQ_B 0x230 0x498 0x528 0x12 0x0
+#define MX8MQ_IOMUXC_I2C4_SDA_GPIO5_IO21 0x230 0x498 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_I2C4_SDA_TPSMP_HDATA23 0x230 0x498 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_UART1_RXD_UART1_DCE_RX 0x234 0x49C 0x4F4 0x0 0x0
+#define MX8MQ_IOMUXC_UART1_RXD_UART1_DTE_TX 0x234 0x49C 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_UART1_RXD_ECSPI3_SCLK 0x234 0x49C 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_UART1_RXD_GPIO5_IO22 0x234 0x49C 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_UART1_RXD_TPSMP_HDATA24 0x234 0x49C 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_UART1_TXD_UART1_DCE_TX 0x238 0x4A0 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_UART1_TXD_UART1_DTE_RX 0x238 0x4A0 0x4F4 0x0 0x0
+#define MX8MQ_IOMUXC_UART1_TXD_ECSPI3_MOSI 0x238 0x4A0 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_UART1_TXD_GPIO5_IO23 0x238 0x4A0 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_UART1_TXD_TPSMP_HDATA25 0x238 0x4A0 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_UART2_RXD_UART2_DCE_RX 0x23C 0x4A4 0x4FC 0x0 0x0
+#define MX8MQ_IOMUXC_UART2_RXD_UART2_DTE_TX 0x23C 0x4A4 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_UART2_RXD_ECSPI3_MISO 0x23C 0x4A4 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_UART2_RXD_GPIO5_IO24 0x23C 0x4A4 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_UART2_RXD_TPSMP_HDATA26 0x23C 0x4A4 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_UART2_TXD_UART2_DCE_TX 0x240 0x4A8 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_UART2_TXD_UART2_DTE_RX 0x240 0x4A8 0x4FC 0x0 0x1
+#define MX8MQ_IOMUXC_UART2_TXD_ECSPI3_SS0 0x240 0x4A8 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_UART2_TXD_GPIO5_IO25 0x240 0x4A8 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_UART2_TXD_TPSMP_HDATA27 0x240 0x4A8 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_UART3_RXD_UART3_DCE_RX 0x244 0x4AC 0x504 0x0 0x2
+#define MX8MQ_IOMUXC_UART3_RXD_UART3_DTE_TX 0x244 0x4AC 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_UART3_RXD_UART1_DCE_CTS_B 0x244 0x4AC 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_UART3_RXD_UART1_DTE_RTS_B 0x244 0x4AC 0x4F0 0x1 0x0
+#define MX8MQ_IOMUXC_UART3_RXD_GPIO5_IO26 0x244 0x4AC 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_UART3_RXD_TPSMP_HDATA28 0x244 0x4AC 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_UART3_TXD_UART3_DCE_TX 0x248 0x4B0 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_UART3_TXD_UART3_DTE_RX 0x248 0x4B0 0x504 0x0 0x3
+#define MX8MQ_IOMUXC_UART3_TXD_UART1_DCE_RTS_B 0x248 0x4B0 0x4F0 0x1 0x1
+#define MX8MQ_IOMUXC_UART3_TXD_UART1_DTE_CTS_B 0x248 0x4B0 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_UART3_TXD_GPIO5_IO27 0x248 0x4B0 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_UART3_TXD_TPSMP_HDATA29 0x248 0x4B0 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_UART4_RXD_UART4_DCE_RX 0x24C 0x4B4 0x50C 0x0 0x2
+#define MX8MQ_IOMUXC_UART4_RXD_UART4_DTE_TX 0x24C 0x4B4 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_UART4_RXD_UART2_DCE_CTS_B 0x24C 0x4B4 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_UART4_RXD_UART2_DTE_RTS_B 0x24C 0x4B4 0x4F8 0x1 0x0
+#define MX8MQ_IOMUXC_UART4_RXD_PCIE1_CLKREQ_B 0x24C 0x4B4 0x524 0x2 0x1
+#define MX8MQ_IOMUXC_UART4_RXD_GPIO5_IO28 0x24C 0x4B4 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_UART4_RXD_TPSMP_HDATA30 0x24C 0x4B4 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_UART4_TXD_UART4_DCE_TX 0x250 0x4B8 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_UART4_TXD_UART4_DTE_RX 0x250 0x4B8 0x50C 0x0 0x3
+#define MX8MQ_IOMUXC_UART4_TXD_UART2_DCE_RTS_B 0x250 0x4B8 0x4F8 0x1 0x1
+#define MX8MQ_IOMUXC_UART4_TXD_UART2_DTE_CTS_B 0x250 0x4B8 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_UART4_TXD_PCIE2_CLKREQ_B 0x250 0x4B8 0x528 0x2 0x1
+#define MX8MQ_IOMUXC_UART4_TXD_GPIO5_IO29 0x250 0x4B8 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_UART4_TXD_TPSMP_HDATA31 0x250 0x4B8 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_TEST_MODE 0x000 0x254 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_BOOT_MODE0 0x000 0x258 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_BOOT_MODE1 0x000 0x25C 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_JTAG_MOD 0x000 0x260 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_JTAG_TRST_B 0x000 0x264 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_JTAG_TDI 0x000 0x268 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_JTAG_TMS 0x000 0x26C 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_JTAG_TCK 0x000 0x270 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_JTAG_TDO 0x000 0x274 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_RTC 0x000 0x278 0x000 0x0 0x0
+
+#endif /* __DTS_IMX8MQ_PINFUNC_H */
diff --git a/include/dt-bindings/soc/imx8_hsio.h b/include/dt-bindings/soc/imx8_hsio.h
new file mode 100644
index 000000000000..a237ceb82620
--- /dev/null
+++ b/include/dt-bindings/soc/imx8_hsio.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2017 NXP
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __DT_BINDINGS_IMX8_HSIO_H
+#define __DT_BINDINGS_IMX8_HSIO_H
+
+/*
+ * imx8qm hsio has pciea, pcieb and sata modules, and hsio
+ * can be configured to the following different work modes.
+ * 1 - pciea 2 lanes and one sata ahci port.
+ * 2 - pciea 1 lane, pcieb 1 lane and one sata ahci port.
+ * 3 - pciea 2 lanes, pcieb 1 lane.
+ * Choose one mode, refer to the exact hardware board design.
+ */
+#define PCIEAX2SATA 1
+#define PCIEAX1PCIEBX1SATA 2
+#define PCIEAX2PCIEBX1 3
+
+#endif /* __DT_BINDINGS_IMX8_HSIO_H */
+
diff --git a/include/dt-bindings/soc/imx8_pd.h b/include/dt-bindings/soc/imx8_pd.h
new file mode 100644
index 000000000000..d955bcf94914
--- /dev/null
+++ b/include/dt-bindings/soc/imx8_pd.h
@@ -0,0 +1,219 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017-2018 NXP
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __DT_BINDINGS_IMX8_PD_H
+#define __DT_BINDINGS_IMX8_PD_H
+
+/*!
+ * These defines are used to indicate a resource. Resources include peripherals
+ * and bus masters (but not memory regions). Note items from list should
+ * never be changed or removed (only added to at the end of the list).
+ */
+#define PD_DC_0 dc0_power_domain
+#define PD_DC_0_PLL_0 dc0_pll0
+#define PD_DC_0_PLL_1 dc0_pll1
+#define PD_LVDS0 lvds0_power_domain
+#define PD_LVDS0_I2C0 lvds0_i2c0
+#define PD_LVDS0_I2C1 lvds0_i2c1
+#define PD_LVDS0_PWM lvds0_pwm
+#define PD_LVDS0_PWM lvds0_pwm
+#define PD_LVDS0_GPIO lvds0_gpio
+#define PD_DC_1 dc1_power_domain
+#define PD_DC_1_PLL_0 dc1_pll0
+#define PD_DC_1_PLL_1 dc1_pll1
+#define PD_LVDS1 lvds1_power_domain
+#define PD_LVDS1_I2C0 lvds1_i2c0
+#define PD_LVDS1_I2C1 lvds1_i2c1
+#define PD_LVDS1_PWM lvds1_pwm
+#define PD_LVDS1_GPIO lvds1_gpio
+
+#define PD_DMA dma_power_domain
+#define PD_DMA_SPI_0 dma_spi0
+#define PD_DMA_SPI_1 dma_spi1
+#define PD_DMA_SPI_2 dma_spi2
+#define PD_DMA_SPI_3 dma_spi3
+#define PD_DMA_UART0 dma_lpuart0
+#define PD_DMA_UART1 dma_lpuart1
+#define PD_DMA_UART2 dma_lpuart2
+#define PD_DMA_UART3 dma_lpuart3
+#define PD_DMA_UART4 dma_lpuart4
+#define PD_DMA_EMVSIM_0 dma_emvsim0
+#define PD_DMA_EMVSIM_1 dma_emvsim1
+#define PD_DMA_I2C_0 dma_lpi2c0
+#define PD_DMA_I2C_1 dma_lpi2c1
+#define PD_DMA_I2C_2 dma_lpi2c2
+#define PD_DMA_I2C_3 dma_lpi2c3
+#define PD_DMA_I2C_4 dma_lpi2c4
+#define PD_DMA_ADC_0 dma_adc0
+#define PD_DMA_ADC_1 dma_adc1
+#define PD_DMA_FTM_0 dma_ftm0
+#define PD_DMA_FTM_1 dma_ftm1
+#define PD_DMA_CAN_0 dma_flexcan0
+#define PD_DMA_CAN_1 dma_flexcan1
+#define PD_DMA_CAN_2 dma_flexcan2
+#define PD_DMA_PWM_0 dma_pwm0
+#define PD_DMA_LCD_0 dma_lcd0
+#define PD_DMA_ELCDIF_PLL dma_elcdif_pll
+
+#define PD_HSIO hsio_power_domain
+#define PD_HSIO_PCIE_A hsio_pcie0
+#define PD_HSIO_PCIE_B hsio_pcie1
+#define PD_HSIO_SATA_0 hsio_sata0
+#define PD_HSIO_GPIO hsio_gpio
+
+#define PD_LCD_0 lcd0_power_domain
+#define PD_LCD_0_I2C_0 lcd0_i2c0
+#define PD_LCD_0_I2C_1 lcd0_i2c1
+#define PD_LCD_PWM_0 lcd0_pwm0
+
+#define PD_LSIO lsio_power_domain
+#define PD_LSIO_GPIO_0 lsio_gpio0
+#define PD_LSIO_GPIO_1 lsio_gpio1
+#define PD_LSIO_GPIO_2 lsio_gpio2
+#define PD_LSIO_GPIO_3 lsio_gpio3
+#define PD_LSIO_GPIO_4 lsio_gpio4
+#define PD_LSIO_GPIO_5 lsio_gpio5
+#define PD_LSIO_GPIO_6 lsio_gpio6
+#define PD_LSIO_GPIO_7 lsio_gpio7
+#define PD_LSIO_GPT_0 lsio_gpt0
+#define PD_LSIO_GPT_1 lsio_gpt1
+#define PD_LSIO_GPT_2 lsio_gpt2
+#define PD_LSIO_GPT_3 lsio_gpt3
+#define PD_LSIO_GPT_4 lsio_gpt4
+#define PD_LSIO_KPP lsio_kpp
+#define PD_LSIO_FSPI_0 lsio_fspi0
+#define PD_LSIO_FSPI_1 lsio_fspi1
+#define PD_LSIO_PWM_0 lsio_pwm0
+#define PD_LSIO_PWM_1 lsio_pwm1
+#define PD_LSIO_PWM_2 lsio_pwm2
+#define PD_LSIO_PWM_3 lsio_pwm3
+#define PD_LSIO_PWM_4 lsio_pwm4
+#define PD_LSIO_PWM_5 lsio_pwm5
+#define PD_LSIO_PWM_6 lsio_pwm6
+#define PD_LSIO_PWM_7 lsio_pwm7
+#define PD_LSIO_MU5A lsio_mu5a
+#define PD_LSIO_MU6A lsio_mu6a
+
+#define PD_CONN connectivity_power_domain
+#define PD_CONN_SDHC_0 conn_sdhc0
+#define PD_CONN_SDHC_1 conn_sdhc1
+#define PD_CONN_SDHC_2 conn_sdhc2
+#define PD_CONN_ENET_0 conn_enet0
+#define PD_CONN_ENET_1 conn_enet1
+#define PD_CONN_MLB_0 conn_mlb0
+#define PD_CONN_DMA_4_CH0 conn_dma4_ch0
+#define PD_CONN_DMA_4_CH1 conn_dma4_ch1
+#define PD_CONN_DMA_4_CH2 conn_dma4_ch2
+#define PD_CONN_DMA_4_CH3 conn_dma4_ch3
+#define PD_CONN_DMA_4_CH4 conn_dma4_ch4
+#define PD_CONN_USB_0 conn_usb0
+#define PD_CONN_USB_1 conn_usb1
+#define PD_CONN_USB_0_PHY conn_usb0_phy
+#define PD_CONN_USB_2 conn_usb2
+#define PD_CONN_USB_2_PHY conn_usb2_phy
+#define PD_CONN_NAND conn_nand
+
+#define PD_AUDIO audio_power_domain
+#define PD_AUD_SAI_0 audio_sai0
+#define PD_AUD_SAI_1 audio_sai1
+#define PD_AUD_SAI_2 audio_sai2
+#define PD_AUD_ASRC_0 audio_asrc0
+#define PD_AUD_ASRC_1 audio_asrc1
+#define PD_AUD_ESAI_0 audio_esai0
+#define PD_AUD_ESAI_1 audio_esai1
+#define PD_AUD_SPDIF_0 audio_spdif0
+#define PD_AUD_SPDIF_1 audio_spdif1
+#define PD_AUD_SAI_3 audio_sai3
+#define PD_AUD_SAI_4 audio_sai4
+#define PD_AUD_SAI_5 audio_sai5
+#define PD_AUD_SAI_6 audio_sai6
+#define PD_AUD_SAI_7 audio_sai7
+#define PD_AUD_GPT_5 audio_gpt5
+#define PD_AUD_GPT_6 audio_gpt6
+#define PD_AUD_GPT_7 audio_gpt7
+#define PD_AUD_GPT_8 audio_gpt8
+#define PD_AUD_GPT_9 audio_gpt9
+#define PD_AUD_GPT_10 audio_gpt10
+#define PD_AUD_AMIX audio_amix
+#define PD_AUD_MQS_0 audio_mqs0
+#define PD_AUD_DSP audio_dsp
+#define PD_AUD_OCRAM audio_ocram
+#define PD_AUD_MCLK_OUT_0 audio_mclkout0
+#define PD_AUD_MCLK_OUT_1 audio_mclkout1
+#define PD_AUD_AUDIO_PLL_0 audio_audiopll0
+#define PD_AUD_AUDIO_PLL_1 audio_audiopll1
+#define PD_AUD_AUDIO_CLK_0 audio_audioclk0
+#define PD_AUD_AUDIO_CLK_1 audio_audioclk1
+
+#define PD_IMAGING imaging_power_domain
+#define PD_IMAGING_JPEG_DEC imaging_jpeg_dec
+#define PD_IMAGING_JPEG_ENC imaging_jpeg_enc
+#define PD_IMAGING_PDMA0 PD_IMAGING
+#define PD_IMAGING_PDMA1 imaging_pdma1
+#define PD_IMAGING_PDMA2 imaging_pdma2
+#define PD_IMAGING_PDMA3 imaging_pdma3
+#define PD_IMAGING_PDMA4 imaging_pdma4
+#define PD_IMAGING_PDMA5 imaging_pdma5
+#define PD_IMAGING_PDMA6 imaging_pdma6
+#define PD_IMAGING_PDMA7 imaging_pdma7
+
+#define PD_MIPI_0_DSI mipi0_dsi_power_domain
+#define PD_MIPI_0_DSI_I2C0 mipi0_dsi_i2c0
+#define PD_MIPI_0_DSI_I2C1 mipi0_dsi_i2c1
+#define PD_MIPI_0_DSI_PWM0 mipi0_dsi_pwm0
+#define PD_MIPI_1_DSI mipi1_dsi_power_domain
+#define PD_MIPI_1_DSI_I2C0 mipi1_dsi_i2c0
+#define PD_MIPI_1_DSI_I2C1 mipi1_dsi_i2c1
+#define PD_MIPI_1_DSI_PWM0 mipi1_dsi_pwm0
+
+#define PD_MIPI_CSI0 mipi_csi0_power_domain
+#define PD_MIPI_CSI0_PWM mipi_csi0_pwm
+#define PD_MIPI_CSI0_I2C0 mipi_csi0_i2c0
+#define PD_MIPI_CSI1 mipi_csi1_power_domain
+#define PD_MIPI_CSI1_PWM_0 mipi_csi1_pwm
+#define PD_MIPI_CSI1_I2C0 mipi_csi1_i2c0
+
+#define PD_PARALLEL_CSI parallel_csi_power_domain
+#define PD_PARALLEL_CSI_I2C parallel_csi_i2c
+#define PD_PARALLEL_CSI_PWM parallel_csi_pwm
+#define PD_PARALLEL_CSI_PLL parallel_csi_pll
+
+#define PD_HDMI hdmi_power_domain
+#define PD_HDMI_PLL_0 hdmi_pll0
+#define PD_HDMI_PLL_1 hdmi_pll1
+#define PD_HDMI_I2C_0 hdmi_i2c
+#define PD_HDMI_I2S_0 hdmi_i2s
+#define PD_HDMI_PWM_0 hdmi_pwm
+#define PD_HDMI_GPIO_0 hdmi_gpio
+
+#define PD_HDMI_RX hdmi_rx_power_domain
+#define PD_HDMI_RX_BYPASS hdmi_rx_bypass
+#define PD_HDMI_RX_I2C hdmi_rx_i2c
+#define PD_HDMI_RX_PWM hdmi_rx_pwm
+
+#define PD_CM40 cm40_power_domain
+#define PD_CM40_I2C cm40_i2c
+#define PD_CM40_INTMUX cm40_intmux
+#define PD_CM41 cm41_power_domain
+#define PD_CM41_I2C cm41_i2c
+#define PD_CM41_INTMUX cm41_intmux
+
+#define PD_CAAM caam_power_domain
+#define PD_CAAM_JR1 caam_job_ring1
+#define PD_CAAM_JR2 caam_job_ring2
+#define PD_CAAM_JR3 caam_job_ring3
+
+#endif /* __DT_BINDINGS_IMX8_PD_H */
+
diff --git a/include/dt-bindings/soc/imx_rsrc.h b/include/dt-bindings/soc/imx_rsrc.h
new file mode 100644
index 000000000000..24a1401907b1
--- /dev/null
+++ b/include/dt-bindings/soc/imx_rsrc.h
@@ -0,0 +1,566 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017-2019 NXP
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef DT_BINDINGS_RSCRC_IMX_H
+#define DT_BINDINGS_RSCRC_IMX_H
+
+/*!
+ * These defines are used to indicate a resource. Resources include peripherals
+ * and bus masters (but not memory regions). Note items from list should
+ * never be changed or removed (only added to at the end of the list).
+ */
+#define SC_R_A53 0
+#define SC_R_A53_0 1
+#define SC_R_A53_1 2
+#define SC_R_A53_2 3
+#define SC_R_A53_3 4
+#define SC_R_A72 5
+#define SC_R_A72_0 6
+#define SC_R_A72_1 7
+#define SC_R_A72_2 8
+#define SC_R_A72_3 9
+#define SC_R_CCI 10
+#define SC_R_DB 11
+#define SC_R_DRC_0 12
+#define SC_R_DRC_1 13
+#define SC_R_GIC_SMMU 14
+#define SC_R_IRQSTR_M4_0 15
+#define SC_R_IRQSTR_M4_1 16
+#define SC_R_SMMU 17
+#define SC_R_GIC 18
+#define SC_R_DC_0_BLIT0 19
+#define SC_R_DC_0_BLIT1 20
+#define SC_R_DC_0_BLIT2 21
+#define SC_R_DC_0_BLIT_OUT 22
+#define SC_R_PERF 23
+#define SC_R_UNUSED5 24
+#define SC_R_DC_0_WARP 25
+#define SC_R_UNUSED7 26
+#define SC_R_UNUSED8 27
+#define SC_R_DC_0_VIDEO0 28
+#define SC_R_DC_0_VIDEO1 29
+#define SC_R_DC_0_FRAC0 30
+#define SC_R_UNUSED6 31
+#define SC_R_DC_0 32
+#define SC_R_GPU_2_PID0 33
+#define SC_R_DC_0_PLL_0 34
+#define SC_R_DC_0_PLL_1 35
+#define SC_R_DC_1_BLIT0 36
+#define SC_R_DC_1_BLIT1 37
+#define SC_R_DC_1_BLIT2 38
+#define SC_R_DC_1_BLIT_OUT 39
+#define SC_R_UNUSED9 40
+#define SC_R_UNUSED10 41
+#define SC_R_DC_1_WARP 42
+#define SC_R_UNUSED11 43
+#define SC_R_UNUSED12 44
+#define SC_R_DC_1_VIDEO0 45
+#define SC_R_DC_1_VIDEO1 46
+#define SC_R_DC_1_FRAC0 47
+#define SC_R_UNUSED13 48
+#define SC_R_DC_1 49
+#define SC_R_UNUSED14 50
+#define SC_R_DC_1_PLL_0 51
+#define SC_R_DC_1_PLL_1 52
+#define SC_R_SPI_0 53
+#define SC_R_SPI_1 54
+#define SC_R_SPI_2 55
+#define SC_R_SPI_3 56
+#define SC_R_UART_0 57
+#define SC_R_UART_1 58
+#define SC_R_UART_2 59
+#define SC_R_UART_3 60
+#define SC_R_UART_4 61
+#define SC_R_EMVSIM_0 62
+#define SC_R_EMVSIM_1 63
+#define SC_R_DMA_0_CH0 64
+#define SC_R_DMA_0_CH1 65
+#define SC_R_DMA_0_CH2 66
+#define SC_R_DMA_0_CH3 67
+#define SC_R_DMA_0_CH4 68
+#define SC_R_DMA_0_CH5 69
+#define SC_R_DMA_0_CH6 70
+#define SC_R_DMA_0_CH7 71
+#define SC_R_DMA_0_CH8 72
+#define SC_R_DMA_0_CH9 73
+#define SC_R_DMA_0_CH10 74
+#define SC_R_DMA_0_CH11 75
+#define SC_R_DMA_0_CH12 76
+#define SC_R_DMA_0_CH13 77
+#define SC_R_DMA_0_CH14 78
+#define SC_R_DMA_0_CH15 79
+#define SC_R_DMA_0_CH16 80
+#define SC_R_DMA_0_CH17 81
+#define SC_R_DMA_0_CH18 82
+#define SC_R_DMA_0_CH19 83
+#define SC_R_DMA_0_CH20 84
+#define SC_R_DMA_0_CH21 85
+#define SC_R_DMA_0_CH22 86
+#define SC_R_DMA_0_CH23 87
+#define SC_R_DMA_0_CH24 88
+#define SC_R_DMA_0_CH25 89
+#define SC_R_DMA_0_CH26 90
+#define SC_R_DMA_0_CH27 91
+#define SC_R_DMA_0_CH28 92
+#define SC_R_DMA_0_CH29 93
+#define SC_R_DMA_0_CH30 94
+#define SC_R_DMA_0_CH31 95
+#define SC_R_I2C_0 96
+#define SC_R_I2C_1 97
+#define SC_R_I2C_2 98
+#define SC_R_I2C_3 99
+#define SC_R_I2C_4 100
+#define SC_R_ADC_0 101
+#define SC_R_ADC_1 102
+#define SC_R_FTM_0 103
+#define SC_R_FTM_1 104
+#define SC_R_CAN_0 105
+#define SC_R_CAN_1 106
+#define SC_R_CAN_2 107
+#define SC_R_DMA_1_CH0 108
+#define SC_R_DMA_1_CH1 109
+#define SC_R_DMA_1_CH2 110
+#define SC_R_DMA_1_CH3 111
+#define SC_R_DMA_1_CH4 112
+#define SC_R_DMA_1_CH5 113
+#define SC_R_DMA_1_CH6 114
+#define SC_R_DMA_1_CH7 115
+#define SC_R_DMA_1_CH8 116
+#define SC_R_DMA_1_CH9 117
+#define SC_R_DMA_1_CH10 118
+#define SC_R_DMA_1_CH11 119
+#define SC_R_DMA_1_CH12 120
+#define SC_R_DMA_1_CH13 121
+#define SC_R_DMA_1_CH14 122
+#define SC_R_DMA_1_CH15 123
+#define SC_R_DMA_1_CH16 124
+#define SC_R_DMA_1_CH17 125
+#define SC_R_DMA_1_CH18 126
+#define SC_R_DMA_1_CH19 127
+#define SC_R_DMA_1_CH20 128
+#define SC_R_DMA_1_CH21 129
+#define SC_R_DMA_1_CH22 130
+#define SC_R_DMA_1_CH23 131
+#define SC_R_DMA_1_CH24 132
+#define SC_R_DMA_1_CH25 133
+#define SC_R_DMA_1_CH26 134
+#define SC_R_DMA_1_CH27 135
+#define SC_R_DMA_1_CH28 136
+#define SC_R_DMA_1_CH29 137
+#define SC_R_DMA_1_CH30 138
+#define SC_R_DMA_1_CH31 139
+#define SC_R_UNUSED1 140
+#define SC_R_UNUSED2 141
+#define SC_R_UNUSED3 142
+#define SC_R_UNUSED4 143
+#define SC_R_GPU_0_PID0 144
+#define SC_R_GPU_0_PID1 145
+#define SC_R_GPU_0_PID2 146
+#define SC_R_GPU_0_PID3 147
+#define SC_R_GPU_1_PID0 148
+#define SC_R_GPU_1_PID1 149
+#define SC_R_GPU_1_PID2 150
+#define SC_R_GPU_1_PID3 151
+#define SC_R_PCIE_A 152
+#define SC_R_SERDES_0 153
+#define SC_R_MATCH_0 154
+#define SC_R_MATCH_1 155
+#define SC_R_MATCH_2 156
+#define SC_R_MATCH_3 157
+#define SC_R_MATCH_4 158
+#define SC_R_MATCH_5 159
+#define SC_R_MATCH_6 160
+#define SC_R_MATCH_7 161
+#define SC_R_MATCH_8 162
+#define SC_R_MATCH_9 163
+#define SC_R_MATCH_10 164
+#define SC_R_MATCH_11 165
+#define SC_R_MATCH_12 166
+#define SC_R_MATCH_13 167
+#define SC_R_MATCH_14 168
+#define SC_R_PCIE_B 169
+#define SC_R_SATA_0 170
+#define SC_R_SERDES_1 171
+#define SC_R_HSIO_GPIO 172
+#define SC_R_MATCH_15 173
+#define SC_R_MATCH_16 174
+#define SC_R_MATCH_17 175
+#define SC_R_MATCH_18 176
+#define SC_R_MATCH_19 177
+#define SC_R_MATCH_20 178
+#define SC_R_MATCH_21 179
+#define SC_R_MATCH_22 180
+#define SC_R_MATCH_23 181
+#define SC_R_MATCH_24 182
+#define SC_R_MATCH_25 183
+#define SC_R_MATCH_26 184
+#define SC_R_MATCH_27 185
+#define SC_R_MATCH_28 186
+#define SC_R_LCD_0 187
+#define SC_R_LCD_0_PWM_0 188
+#define SC_R_LCD_0_I2C_0 189
+#define SC_R_LCD_0_I2C_1 190
+#define SC_R_PWM_0 191
+#define SC_R_PWM_1 192
+#define SC_R_PWM_2 193
+#define SC_R_PWM_3 194
+#define SC_R_PWM_4 195
+#define SC_R_PWM_5 196
+#define SC_R_PWM_6 197
+#define SC_R_PWM_7 198
+#define SC_R_GPIO_0 199
+#define SC_R_GPIO_1 200
+#define SC_R_GPIO_2 201
+#define SC_R_GPIO_3 202
+#define SC_R_GPIO_4 203
+#define SC_R_GPIO_5 204
+#define SC_R_GPIO_6 205
+#define SC_R_GPIO_7 206
+#define SC_R_GPT_0 207
+#define SC_R_GPT_1 208
+#define SC_R_GPT_2 209
+#define SC_R_GPT_3 210
+#define SC_R_GPT_4 211
+#define SC_R_KPP 212
+#define SC_R_MU_0A 213
+#define SC_R_MU_1A 214
+#define SC_R_MU_2A 215
+#define SC_R_MU_3A 216
+#define SC_R_MU_4A 217
+#define SC_R_MU_5A 218
+#define SC_R_MU_6A 219
+#define SC_R_MU_7A 220
+#define SC_R_MU_8A 221
+#define SC_R_MU_9A 222
+#define SC_R_MU_10A 223
+#define SC_R_MU_11A 224
+#define SC_R_MU_12A 225
+#define SC_R_MU_13A 226
+#define SC_R_MU_5B 227
+#define SC_R_MU_6B 228
+#define SC_R_MU_7B 229
+#define SC_R_MU_8B 230
+#define SC_R_MU_9B 231
+#define SC_R_MU_10B 232
+#define SC_R_MU_11B 233
+#define SC_R_MU_12B 234
+#define SC_R_MU_13B 235
+#define SC_R_ROM_0 236
+#define SC_R_FSPI_0 237
+#define SC_R_FSPI_1 238
+#define SC_R_IEE 239
+#define SC_R_IEE_R0 240
+#define SC_R_IEE_R1 241
+#define SC_R_IEE_R2 242
+#define SC_R_IEE_R3 243
+#define SC_R_IEE_R4 244
+#define SC_R_IEE_R5 245
+#define SC_R_IEE_R6 246
+#define SC_R_IEE_R7 247
+#define SC_R_SDHC_0 248
+#define SC_R_SDHC_1 249
+#define SC_R_SDHC_2 250
+#define SC_R_ENET_0 251
+#define SC_R_ENET_1 252
+#define SC_R_MLB_0 253
+#define SC_R_DMA_2_CH0 254
+#define SC_R_DMA_2_CH1 255
+#define SC_R_DMA_2_CH2 256
+#define SC_R_DMA_2_CH3 257
+#define SC_R_DMA_2_CH4 258
+#define SC_R_USB_0 259
+#define SC_R_USB_1 260
+#define SC_R_USB_0_PHY 261
+#define SC_R_USB_2 262
+#define SC_R_USB_2_PHY 263
+#define SC_R_DTCP 264
+#define SC_R_NAND 265
+#define SC_R_LVDS_0 266
+#define SC_R_LVDS_0_PWM_0 267
+#define SC_R_LVDS_0_I2C_0 268
+#define SC_R_LVDS_0_I2C_1 269
+#define SC_R_LVDS_1 270
+#define SC_R_LVDS_1_PWM_0 271
+#define SC_R_LVDS_1_I2C_0 272
+#define SC_R_LVDS_1_I2C_1 273
+#define SC_R_LVDS_2 274
+#define SC_R_LVDS_2_PWM_0 275
+#define SC_R_LVDS_2_I2C_0 276
+#define SC_R_LVDS_2_I2C_1 277
+#define SC_R_M4_0_PID0 278
+#define SC_R_M4_0_PID1 279
+#define SC_R_M4_0_PID2 280
+#define SC_R_M4_0_PID3 281
+#define SC_R_M4_0_PID4 282
+#define SC_R_M4_0_RGPIO 283
+#define SC_R_M4_0_SEMA42 284
+#define SC_R_M4_0_TPM 285
+#define SC_R_M4_0_PIT 286
+#define SC_R_M4_0_UART 287
+#define SC_R_M4_0_I2C 288
+#define SC_R_M4_0_INTMUX 289
+#define SC_R_UNUSED15 290
+#define SC_R_UNUSED16 291
+#define SC_R_M4_0_MU_0B 292
+#define SC_R_M4_0_MU_0A0 293
+#define SC_R_M4_0_MU_0A1 294
+#define SC_R_M4_0_MU_0A2 295
+#define SC_R_M4_0_MU_0A3 296
+#define SC_R_M4_0_MU_1A 297
+#define SC_R_M4_1_PID0 298
+#define SC_R_M4_1_PID1 299
+#define SC_R_M4_1_PID2 300
+#define SC_R_M4_1_PID3 301
+#define SC_R_M4_1_PID4 302
+#define SC_R_M4_1_RGPIO 303
+#define SC_R_M4_1_SEMA42 304
+#define SC_R_M4_1_TPM 305
+#define SC_R_M4_1_PIT 306
+#define SC_R_M4_1_UART 307
+#define SC_R_M4_1_I2C 308
+#define SC_R_M4_1_INTMUX 309
+#define SC_R_UNUSED17 310
+#define SC_R_UNUSED18 311
+#define SC_R_M4_1_MU_0B 312
+#define SC_R_M4_1_MU_0A0 313
+#define SC_R_M4_1_MU_0A1 314
+#define SC_R_M4_1_MU_0A2 315
+#define SC_R_M4_1_MU_0A3 316
+#define SC_R_M4_1_MU_1A 317
+#define SC_R_SAI_0 318
+#define SC_R_SAI_1 319
+#define SC_R_SAI_2 320
+#define SC_R_IRQSTR_SCU2 321
+#define SC_R_IRQSTR_DSP 322
+#define SC_R_ELCDIF_PLL 323
+#define SC_R_OCRAM 324
+#define SC_R_AUDIO_PLL_0 325
+#define SC_R_PI_0 326
+#define SC_R_PI_0_PWM_0 327
+#define SC_R_PI_0_PWM_1 328
+#define SC_R_PI_0_I2C_0 329
+#define SC_R_PI_0_PLL 330
+#define SC_R_PI_1 331
+#define SC_R_PI_1_PWM_0 332
+#define SC_R_PI_1_PWM_1 333
+#define SC_R_PI_1_I2C_0 334
+#define SC_R_PI_1_PLL 335
+#define SC_R_SC_PID0 336
+#define SC_R_SC_PID1 337
+#define SC_R_SC_PID2 338
+#define SC_R_SC_PID3 339
+#define SC_R_SC_PID4 340
+#define SC_R_SC_SEMA42 341
+#define SC_R_SC_TPM 342
+#define SC_R_SC_PIT 343
+#define SC_R_SC_UART 344
+#define SC_R_SC_I2C 345
+#define SC_R_SC_MU_0B 346
+#define SC_R_SC_MU_0A0 347
+#define SC_R_SC_MU_0A1 348
+#define SC_R_SC_MU_0A2 349
+#define SC_R_SC_MU_0A3 350
+#define SC_R_SC_MU_1A 351
+#define SC_R_SYSCNT_RD 352
+#define SC_R_SYSCNT_CMP 353
+#define SC_R_DEBUG 354
+#define SC_R_SYSTEM 355
+#define SC_R_SNVS 356
+#define SC_R_OTP 357
+#define SC_R_VPU_PID0 358
+#define SC_R_VPU_PID1 359
+#define SC_R_VPU_PID2 360
+#define SC_R_VPU_PID3 361
+#define SC_R_VPU_PID4 362
+#define SC_R_VPU_PID5 363
+#define SC_R_VPU_PID6 364
+#define SC_R_VPU_PID7 365
+#define SC_R_VPU_UART 366
+#define SC_R_VPUCORE 367
+#define SC_R_VPUCORE_0 368
+#define SC_R_VPUCORE_1 369
+#define SC_R_VPUCORE_2 370
+#define SC_R_VPUCORE_3 371
+#define SC_R_DMA_4_CH0 372
+#define SC_R_DMA_4_CH1 373
+#define SC_R_DMA_4_CH2 374
+#define SC_R_DMA_4_CH3 375
+#define SC_R_DMA_4_CH4 376
+#define SC_R_ISI_CH0 377
+#define SC_R_ISI_CH1 378
+#define SC_R_ISI_CH2 379
+#define SC_R_ISI_CH3 380
+#define SC_R_ISI_CH4 381
+#define SC_R_ISI_CH5 382
+#define SC_R_ISI_CH6 383
+#define SC_R_ISI_CH7 384
+#define SC_R_MJPEG_DEC_S0 385
+#define SC_R_MJPEG_DEC_S1 386
+#define SC_R_MJPEG_DEC_S2 387
+#define SC_R_MJPEG_DEC_S3 388
+#define SC_R_MJPEG_ENC_S0 389
+#define SC_R_MJPEG_ENC_S1 390
+#define SC_R_MJPEG_ENC_S2 391
+#define SC_R_MJPEG_ENC_S3 392
+#define SC_R_MIPI_0 393
+#define SC_R_MIPI_0_PWM_0 394
+#define SC_R_MIPI_0_I2C_0 395
+#define SC_R_MIPI_0_I2C_1 396
+#define SC_R_MIPI_1 397
+#define SC_R_MIPI_1_PWM_0 398
+#define SC_R_MIPI_1_I2C_0 399
+#define SC_R_MIPI_1_I2C_1 400
+#define SC_R_CSI_0 401
+#define SC_R_CSI_0_PWM_0 402
+#define SC_R_CSI_0_I2C_0 403
+#define SC_R_CSI_1 404
+#define SC_R_CSI_1_PWM_0 405
+#define SC_R_CSI_1_I2C_0 406
+#define SC_R_HDMI 407
+#define SC_R_HDMI_I2S 408
+#define SC_R_HDMI_I2C_0 409
+#define SC_R_HDMI_PLL_0 410
+#define SC_R_HDMI_RX 411
+#define SC_R_HDMI_RX_BYPASS 412
+#define SC_R_HDMI_RX_I2C_0 413
+#define SC_R_ASRC_0 414
+#define SC_R_ESAI_0 415
+#define SC_R_SPDIF_0 416
+#define SC_R_SPDIF_1 417
+#define SC_R_SAI_3 418
+#define SC_R_SAI_4 419
+#define SC_R_SAI_5 420
+#define SC_R_GPT_5 421
+#define SC_R_GPT_6 422
+#define SC_R_GPT_7 423
+#define SC_R_GPT_8 424
+#define SC_R_GPT_9 425
+#define SC_R_GPT_10 426
+#define SC_R_DMA_2_CH5 427
+#define SC_R_DMA_2_CH6 428
+#define SC_R_DMA_2_CH7 429
+#define SC_R_DMA_2_CH8 430
+#define SC_R_DMA_2_CH9 431
+#define SC_R_DMA_2_CH10 432
+#define SC_R_DMA_2_CH11 433
+#define SC_R_DMA_2_CH12 434
+#define SC_R_DMA_2_CH13 435
+#define SC_R_DMA_2_CH14 436
+#define SC_R_DMA_2_CH15 437
+#define SC_R_DMA_2_CH16 438
+#define SC_R_DMA_2_CH17 439
+#define SC_R_DMA_2_CH18 440
+#define SC_R_DMA_2_CH19 441
+#define SC_R_DMA_2_CH20 442
+#define SC_R_DMA_2_CH21 443
+#define SC_R_DMA_2_CH22 444
+#define SC_R_DMA_2_CH23 445
+#define SC_R_DMA_2_CH24 446
+#define SC_R_DMA_2_CH25 447
+#define SC_R_DMA_2_CH26 448
+#define SC_R_DMA_2_CH27 449
+#define SC_R_DMA_2_CH28 450
+#define SC_R_DMA_2_CH29 451
+#define SC_R_DMA_2_CH30 452
+#define SC_R_DMA_2_CH31 453
+#define SC_R_ASRC_1 454
+#define SC_R_ESAI_1 455
+#define SC_R_SAI_6 456
+#define SC_R_SAI_7 457
+#define SC_R_AMIX 458
+#define SC_R_MQS_0 459
+#define SC_R_DMA_3_CH0 460
+#define SC_R_DMA_3_CH1 461
+#define SC_R_DMA_3_CH2 462
+#define SC_R_DMA_3_CH3 463
+#define SC_R_DMA_3_CH4 464
+#define SC_R_DMA_3_CH5 465
+#define SC_R_DMA_3_CH6 466
+#define SC_R_DMA_3_CH7 467
+#define SC_R_DMA_3_CH8 468
+#define SC_R_DMA_3_CH9 469
+#define SC_R_DMA_3_CH10 470
+#define SC_R_DMA_3_CH11 471
+#define SC_R_DMA_3_CH12 472
+#define SC_R_DMA_3_CH13 473
+#define SC_R_DMA_3_CH14 474
+#define SC_R_DMA_3_CH15 475
+#define SC_R_DMA_3_CH16 476
+#define SC_R_DMA_3_CH17 477
+#define SC_R_DMA_3_CH18 478
+#define SC_R_DMA_3_CH19 479
+#define SC_R_DMA_3_CH20 480
+#define SC_R_DMA_3_CH21 481
+#define SC_R_DMA_3_CH22 482
+#define SC_R_DMA_3_CH23 483
+#define SC_R_DMA_3_CH24 484
+#define SC_R_DMA_3_CH25 485
+#define SC_R_DMA_3_CH26 486
+#define SC_R_DMA_3_CH27 487
+#define SC_R_DMA_3_CH28 488
+#define SC_R_DMA_3_CH29 489
+#define SC_R_DMA_3_CH30 490
+#define SC_R_DMA_3_CH31 491
+#define SC_R_AUDIO_PLL_1 492
+#define SC_R_AUDIO_CLK_0 493
+#define SC_R_AUDIO_CLK_1 494
+#define SC_R_MCLK_OUT_0 495
+#define SC_R_MCLK_OUT_1 496
+#define SC_R_PMIC_0 497
+#define SC_R_PMIC_1 498
+#define SC_R_SECO 499
+#define SC_R_CAAM_JR1 500
+#define SC_R_CAAM_JR2 501
+#define SC_R_CAAM_JR3 502
+#define SC_R_SECO_MU_2 503
+#define SC_R_SECO_MU_3 504
+#define SC_R_SECO_MU_4 505
+#define SC_R_HDMI_RX_PWM_0 506
+#define SC_R_A35 507
+#define SC_R_A35_0 508
+#define SC_R_A35_1 509
+#define SC_R_A35_2 510
+#define SC_R_A35_3 511
+#define SC_R_DSP 512
+#define SC_R_DSP_RAM 513
+#define SC_R_CAAM_JR1_OUT 514
+#define SC_R_CAAM_JR2_OUT 515
+#define SC_R_CAAM_JR3_OUT 516
+#define SC_R_VPU_DEC_0 517
+#define SC_R_VPU_ENC_0 518
+#define SC_R_CAAM_JR0 519
+#define SC_R_CAAM_JR0_OUT 520
+#define SC_R_PMIC_2 521
+#define SC_R_DBLOGIC 522
+#define SC_R_HDMI_PLL_1 523
+#define SC_R_BOARD_R0 524
+#define SC_R_BOARD_R1 525
+#define SC_R_BOARD_R2 526
+#define SC_R_BOARD_R3 527
+#define SC_R_BOARD_R4 528
+#define SC_R_BOARD_R5 529
+#define SC_R_BOARD_R6 530
+#define SC_R_BOARD_R7 531
+#define SC_R_MJPEG_DEC_MP 532
+#define SC_R_MJPEG_ENC_MP 533
+#define SC_R_VPU_TS_0 534
+#define SC_R_VPU_MU_0 535
+#define SC_R_VPU_MU_1 536
+#define SC_R_VPU_MU_2 537
+#define SC_R_VPU_MU_3 538
+#define SC_R_VPU_ENC_1 539
+#define SC_R_VPU 540
+#define SC_R_DMA_5_CH0 541
+#define SC_R_DMA_5_CH1 542
+#define SC_R_DMA_5_CH2 543
+#define SC_R_DMA_5_CH3 544
+#define SC_R_ATTESTATION 545
+#define SC_R_LAST 546
+#define SC_R_NONE 0xFFF0
+
+#endif /* DT_BINDINGS_RSCRC_IMX_H */
+
diff --git a/include/linux/backlight.h b/include/linux/backlight.h
index af7003548593..ace825e2ca2d 100644
--- a/include/linux/backlight.h
+++ b/include/linux/backlight.h
@@ -130,6 +130,38 @@ static inline int backlight_update_status(struct backlight_device *bd)
return ret;
}
+/**
+ * backlight_enable - Enable backlight
+ * @bd: the backlight device to enable
+ */
+static inline int backlight_enable(struct backlight_device *bd)
+{
+ if (!bd)
+ return 0;
+
+ bd->props.power = FB_BLANK_UNBLANK;
+ bd->props.fb_blank = FB_BLANK_UNBLANK;
+ bd->props.state &= ~BL_CORE_FBBLANK;
+
+ return backlight_update_status(bd);
+}
+
+/**
+ * backlight_disable - Disable backlight
+ * @bd: the backlight device to disable
+ */
+static inline int backlight_disable(struct backlight_device *bd)
+{
+ if (!bd)
+ return 0;
+
+ bd->props.power = FB_BLANK_POWERDOWN;
+ bd->props.fb_blank = FB_BLANK_POWERDOWN;
+ bd->props.state |= BL_CORE_FBBLANK;
+
+ return backlight_update_status(bd);
+}
+
extern struct backlight_device *backlight_device_register(const char *name,
struct device *dev, void *devdata, const struct backlight_ops *ops,
const struct backlight_properties *props);
diff --git a/include/linux/blk_types.h b/include/linux/blk_types.h
index 91072b68dc38..86173bafcd39 100644
--- a/include/linux/blk_types.h
+++ b/include/linux/blk_types.h
@@ -229,11 +229,14 @@ enum req_flag_bits {
__REQ_PREFLUSH, /* request for cache flush */
__REQ_RAHEAD, /* read ahead, can fail anytime */
__REQ_BACKGROUND, /* background IO */
+ __REQ_NOWAIT, /* Don't wait if request will block */
/* command specific flags for REQ_OP_WRITE_ZEROES: */
__REQ_NOUNMAP, /* do not free blocks when zeroing */
- __REQ_NOWAIT, /* Don't wait if request will block */
+ /* for driver use */
+ __REQ_DRV,
+
__REQ_NR_BITS, /* stops here */
};
@@ -250,9 +253,11 @@ enum req_flag_bits {
#define REQ_PREFLUSH (1ULL << __REQ_PREFLUSH)
#define REQ_RAHEAD (1ULL << __REQ_RAHEAD)
#define REQ_BACKGROUND (1ULL << __REQ_BACKGROUND)
+#define REQ_NOWAIT (1ULL << __REQ_NOWAIT)
#define REQ_NOUNMAP (1ULL << __REQ_NOUNMAP)
-#define REQ_NOWAIT (1ULL << __REQ_NOWAIT)
+
+#define REQ_DRV (1ULL << __REQ_DRV)
#define REQ_FAILFAST_MASK \
(REQ_FAILFAST_DEV | REQ_FAILFAST_TRANSPORT | REQ_FAILFAST_DRIVER)
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index 4d4af0e94059..1b671119e2ae 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -284,6 +284,7 @@ struct blk_queue_ctx;
typedef void (request_fn_proc) (struct request_queue *q);
typedef blk_qc_t (make_request_fn) (struct request_queue *q, struct bio *bio);
+typedef bool (poll_q_fn) (struct request_queue *q, blk_qc_t);
typedef int (prep_rq_fn) (struct request_queue *, struct request *);
typedef void (unprep_rq_fn) (struct request_queue *, struct request *);
@@ -426,6 +427,7 @@ struct request_queue {
request_fn_proc *request_fn;
make_request_fn *make_request_fn;
+ poll_q_fn *poll_fn;
prep_rq_fn *prep_rq_fn;
unprep_rq_fn *unprep_rq_fn;
softirq_done_fn *softirq_done_fn;
@@ -954,6 +956,7 @@ do { \
extern int blk_register_queue(struct gendisk *disk);
extern void blk_unregister_queue(struct gendisk *disk);
extern blk_qc_t generic_make_request(struct bio *bio);
+extern blk_qc_t direct_make_request(struct bio *bio);
extern void blk_rq_init(struct request_queue *q, struct request *rq);
extern void blk_init_request_from_bio(struct request *req, struct bio *bio);
extern void blk_put_request(struct request *);
@@ -1008,7 +1011,7 @@ extern void blk_execute_rq_nowait(struct request_queue *, struct gendisk *,
int blk_status_to_errno(blk_status_t status);
blk_status_t errno_to_blk_status(int errno);
-bool blk_mq_poll(struct request_queue *q, blk_qc_t cookie);
+bool blk_poll(struct request_queue *q, blk_qc_t cookie);
static inline struct request_queue *bdev_get_queue(struct block_device *bdev)
{
@@ -1127,6 +1130,8 @@ extern struct request *blk_peek_request(struct request_queue *q);
extern void blk_start_request(struct request *rq);
extern struct request *blk_fetch_request(struct request_queue *q);
+void blk_steal_bios(struct bio_list *list, struct request *rq);
+
/*
* Request completion related functions.
*
diff --git a/include/linux/busfreq-imx.h b/include/linux/busfreq-imx.h
new file mode 100644
index 000000000000..17b8991d69bd
--- /dev/null
+++ b/include/linux/busfreq-imx.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2012-2016 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ASM_ARCH_MXC_BUSFREQ_H__
+#define __ASM_ARCH_MXC_BUSFREQ_H__
+
+#include <linux/notifier.h>
+#include <linux/regulator/consumer.h>
+
+/*
+ * This enumerates busfreq low power mode entry and exit.
+ */
+enum busfreq_event {
+ LOW_BUSFREQ_ENTER,
+ LOW_BUSFREQ_EXIT,
+};
+
+/*
+ * This enumerates the system bus and ddr frequencies in various modes.
+ * BUS_FREQ_HIGH - DDR @ 528MHz, AHB @ 132MHz.
+ * BUS_FREQ_MED - DDR @ 400MHz, AHB @ 132MHz
+ * BUS_FREQ_AUDIO - DDR @ 50MHz/100MHz, AHB @ 24MHz.
+ * BUS_FREQ_LOW - DDR @ 24MHz, AHB @ 24MHz.
+ * BUS_FREQ_ULTRA_LOW - DDR @ 1MHz, AHB - 3MHz.
+ *
+ * Drivers need to request/release the bus/ddr frequencies based on
+ * their performance requirements. Drivers cannot request/release
+ * BUS_FREQ_ULTRA_LOW mode as this mode is automatically entered from
+ * either BUS_FREQ_AUDIO or BUS_FREQ_LOW
+ * modes.
+ */
+enum bus_freq_mode {
+ BUS_FREQ_HIGH,
+ BUS_FREQ_MED,
+ BUS_FREQ_AUDIO,
+ BUS_FREQ_LOW,
+ BUS_FREQ_ULTRA_LOW,
+};
+
+#if defined(CONFIG_CPU_FREQ) && !defined(CONFIG_ARM64)
+extern struct regulator *arm_reg;
+extern struct regulator *soc_reg;
+void request_bus_freq(enum bus_freq_mode mode);
+void release_bus_freq(enum bus_freq_mode mode);
+int register_busfreq_notifier(struct notifier_block *nb);
+int unregister_busfreq_notifier(struct notifier_block *nb);
+int get_bus_freq_mode(void);
+#elif defined(CONFIG_ARCH_FSL_IMX8MQ)
+void request_bus_freq(enum bus_freq_mode mode);
+void release_bus_freq(enum bus_freq_mode mode);
+int get_bus_freq_mode(void);
+#else
+static inline void request_bus_freq(enum bus_freq_mode mode)
+{
+}
+static inline void release_bus_freq(enum bus_freq_mode mode)
+{
+}
+static inline int register_busfreq_notifier(struct notifier_block *nb)
+{
+ return 0;
+}
+static inline int unregister_busfreq_notifier(struct notifier_block *nb)
+{
+ return 0;
+}
+static inline int get_bus_freq_mode(void)
+{
+ return BUS_FREQ_HIGH;
+}
+#endif
+#endif
diff --git a/include/linux/can/platform/flexcan.h b/include/linux/can/platform/flexcan.h
new file mode 100644
index 000000000000..fdfe76f16ea7
--- /dev/null
+++ b/include/linux/can/platform/flexcan.h
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2014 Freescale Semiconductor, Inc.
+ *
+ * This file is released under the GPLv2
+ *
+ */
+
+#ifndef __CAN_PLATFORM_FLEXCAN_H
+#define __CAN_PLATFORM_FLEXCAN_H
+
+/**
+ * struct flexcan_platform_data - flex CAN controller platform data
+ * @transceiver_enable: - called to power on/off the transceiver
+ *
+ */
+struct flexcan_platform_data {
+ void (*transceiver_switch)(int enable);
+};
+
+#endif /* __CAN_PLATFORM_FLEXCAN_H */
diff --git a/include/linux/can/rx-offload.h b/include/linux/can/rx-offload.h
index 8268811a697e..6448e7dfc170 100644
--- a/include/linux/can/rx-offload.h
+++ b/include/linux/can/rx-offload.h
@@ -23,7 +23,7 @@
struct can_rx_offload {
struct net_device *dev;
- unsigned int (*mailbox_read)(struct can_rx_offload *offload, struct can_frame *cf,
+ unsigned int (*mailbox_read)(struct can_rx_offload *offload, struct canfd_frame *cf,
u32 *timestamp, unsigned int mb);
struct sk_buff_head skb_queue;
@@ -35,6 +35,8 @@ struct can_rx_offload {
struct napi_struct napi;
bool inc;
+
+ bool is_canfd;
};
int can_rx_offload_add_timestamp(struct net_device *dev, struct can_rx_offload *offload);
diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h
index 3eb3376f1cc8..9ae6613db10c 100644
--- a/include/linux/clk-provider.h
+++ b/include/linux/clk-provider.h
@@ -35,6 +35,7 @@
#define CLK_IS_CRITICAL BIT(11) /* do not gate, ever */
/* parents need enable during gate/ungate, set rate and re-parent */
#define CLK_OPS_PARENT_ENABLE BIT(12)
+#define CLK_SET_PARENT_NOCACHE BIT(13) /* do not use the cached clk parent */
struct clk;
struct clk_hw;
@@ -358,6 +359,7 @@ struct clk_div_table {
* @shift: shift to the divider bit field
* @width: width of the divider bit field
* @table: array of value/divider pairs, last entry should have div = 0
+ * @cached_val: cached div hw value used for CLK_DIVIDER_ZERO_GATE
* @lock: register lock
*
* Clock with an adjustable divider affecting its output frequency. Implements
@@ -386,6 +388,12 @@ struct clk_div_table {
* CLK_DIVIDER_MAX_AT_ZERO - For dividers which are like CLK_DIVIDER_ONE_BASED
* except when the value read from the register is zero, the divisor is
* 2^width of the field.
+ * CLK_DIVIDER_ZERO_GATE - For dividers when the value read from the register
+ * is zero, it means the divisor is gated. For this case, the cached_val
+ * will be used to store the intermediate div for the normal rate
+ * operation, like set_rate/get_rate/recalc_rate. When the divider is
+ * ungated, the driver will actually program the hardware to have the
+ * requested divider value.
*/
struct clk_divider {
struct clk_hw hw;
@@ -394,6 +402,7 @@ struct clk_divider {
u8 width;
u8 flags;
const struct clk_div_table *table;
+ u32 cached_val;
spinlock_t *lock;
};
@@ -406,6 +415,7 @@ struct clk_divider {
#define CLK_DIVIDER_ROUND_CLOSEST BIT(4)
#define CLK_DIVIDER_READ_ONLY BIT(5)
#define CLK_DIVIDER_MAX_AT_ZERO BIT(6)
+#define CLK_DIVIDER_ZERO_GATE BIT(7)
extern const struct clk_ops clk_divider_ops;
extern const struct clk_ops clk_divider_ro_ops;
@@ -555,6 +565,12 @@ void clk_hw_unregister_fixed_factor(struct clk_hw *hw);
* @lock: register lock
*
* Clock with adjustable fractional divider affecting its output frequency.
+ *
+ * Flags:
+ * CLK_FRAC_DIVIDER_ZERO_BASED - by default the numerator and denominator
+ * is the value read from the register. If CLK_FRAC_DIVIDER_ZERO_BASED
+ * is set then the numerator and denominator are both the value read
+ * plus one.
*/
struct clk_fractional_divider {
struct clk_hw hw;
@@ -574,6 +590,8 @@ struct clk_fractional_divider {
#define to_clk_fd(_hw) container_of(_hw, struct clk_fractional_divider, hw)
+#define CLK_FRAC_DIVIDER_ZERO_BASED BIT(0)
+
extern const struct clk_ops clk_fractional_divider_ops;
struct clk *clk_register_fractional_divider(struct device *dev,
const char *name, const char *parent_name, unsigned long flags,
diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h
index cad1eb50d668..b9c6fff3cc9f 100644
--- a/include/linux/cpufreq.h
+++ b/include/linux/cpufreq.h
@@ -548,6 +548,18 @@ struct gov_attr_set {
int usage_count;
};
+#define gov_attr_ro(_name) \
+static struct governor_attr _name = \
+__ATTR(_name, 0444, show_##_name, NULL)
+
+#define gov_attr_wo(_name) \
+static struct governor_attr _name = \
+__ATTR(_name, 0200, NULL, store_##_name)
+
+#define gov_attr_rw(_name) \
+static struct governor_attr _name = \
+__ATTR(_name, 0644, show_##_name, store_##_name)
+
/* sysfs ops for cpufreq governors */
extern const struct sysfs_ops governor_sysfs_ops;
diff --git a/include/linux/device_cooling.h b/include/linux/device_cooling.h
new file mode 100644
index 000000000000..18d9e3b90ed9
--- /dev/null
+++ b/include/linux/device_cooling.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2013-2015 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.
+ *
+ */
+
+#ifndef __DEVICE_THERMAL_H__
+#define __DEVICE_THERMAL_H__
+
+#include <linux/thermal.h>
+
+#ifdef CONFIG_DEVICE_THERMAL
+int register_devfreq_cooling_notifier(struct notifier_block *nb);
+int unregister_devfreq_cooling_notifier(struct notifier_block *nb);
+struct thermal_cooling_device *devfreq_cooling_register(void);
+void devfreq_cooling_unregister(struct thermal_cooling_device *cdev);
+#else
+static inline
+int register_devfreq_cooling_notifier(struct notifier_block *nb)
+{
+ return 0;
+}
+
+static inline
+int unregister_devfreq_cooling_notifier(struct notifier_block *nb)
+{
+ return 0;
+}
+
+static inline
+struct thermal_cooling_device *devfreq_cooling_register(void)
+{
+ return NULL;
+}
+
+static inline
+void devfreq_cooling_unregister(struct thermal_cooling_device *cdev)
+{
+ return;
+}
+#endif
+#endif /* __DEVICE_THERMAL_H__ */
diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h
index 8319101170fc..8dc150f27dcf 100644
--- a/include/linux/dmaengine.h
+++ b/include/linux/dmaengine.h
@@ -345,6 +345,8 @@ enum dma_slave_buswidth {
* loops in this area in order to transfer the data.
* @dst_port_window_size: same as src_port_window_size but for the destination
* port.
+ * @src_fifo_num: bit 0-7 is the fifo number, bit:8-11 is the fifo offset;
+ * @dst_fifo_num: same as src_fifo_num
* @device_fc: Flow Controller Settings. Only valid for slave channels. Fill
* with 'true' if peripheral should be flow controller. Direction will be
* selected at Runtime.
@@ -374,6 +376,8 @@ struct dma_slave_config {
u32 dst_maxburst;
u32 src_port_window_size;
u32 dst_port_window_size;
+ u32 src_fifo_num;
+ u32 dst_fifo_num;
bool device_fc;
unsigned int slave_id;
};
diff --git a/include/linux/elevator.h b/include/linux/elevator.h
index ddb7632d73b9..b974133b3b99 100644
--- a/include/linux/elevator.h
+++ b/include/linux/elevator.h
@@ -197,8 +197,6 @@ extern bool elv_attempt_insert_merge(struct request_queue *, struct request *);
extern void elv_requeue_request(struct request_queue *, struct request *);
extern struct request *elv_former_request(struct request_queue *, struct request *);
extern struct request *elv_latter_request(struct request_queue *, struct request *);
-extern int elv_register_queue(struct request_queue *q);
-extern void elv_unregister_queue(struct request_queue *q);
extern int elv_may_queue(struct request_queue *, unsigned int);
extern void elv_completed_request(struct request_queue *, struct request *);
extern int elv_set_request(struct request_queue *q, struct request *rq,
diff --git a/include/linux/genhd.h b/include/linux/genhd.h
index 550fa358893a..4ed6f5256710 100644
--- a/include/linux/genhd.h
+++ b/include/linux/genhd.h
@@ -141,6 +141,7 @@ struct hd_struct {
#define GENHD_FL_NATIVE_CAPACITY 128
#define GENHD_FL_BLOCK_EVENTS_ON_EXCL_WRITE 256
#define GENHD_FL_NO_PART_SCAN 512
+#define GENHD_FL_HIDDEN 1024
enum {
DISK_EVENT_MEDIA_CHANGE = 1 << 0, /* media changed */
@@ -235,7 +236,7 @@ static inline bool disk_part_scan_enabled(struct gendisk *disk)
static inline dev_t disk_devt(struct gendisk *disk)
{
- return disk_to_dev(disk)->devt;
+ return MKDEV(disk->major, disk->first_minor);
}
static inline dev_t part_devt(struct hd_struct *part)
@@ -395,6 +396,11 @@ static inline void add_disk(struct gendisk *disk)
{
device_add_disk(NULL, disk);
}
+extern void device_add_disk_no_queue_reg(struct device *parent, struct gendisk *disk);
+static inline void add_disk_no_queue_reg(struct gendisk *disk)
+{
+ device_add_disk_no_queue_reg(NULL, disk);
+}
extern void del_gendisk(struct gendisk *gp);
extern struct gendisk *get_gendisk(dev_t dev, int *partno);
diff --git a/include/linux/hantrodec.h b/include/linux/hantrodec.h
new file mode 100755
index 000000000000..f423ea82a04e
--- /dev/null
+++ b/include/linux/hantrodec.h
@@ -0,0 +1,29 @@
+/*****************************************************************************
+*
+* The GPL License (GPL)
+*
+* Copyright (c) 2015-2017, VeriSilicon Inc.
+* Copyright (c) 2011-2014, Google 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.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+*****************************************************************************/
+
+#ifndef _HANTRODEC_H_
+#define _HANTRODEC_H_
+
+#include <uapi/linux/hantrodec.h>
+
+#endif /* !_HANTRODEC_H_ */
diff --git a/include/linux/hdmi.h b/include/linux/hdmi.h
index d271ff23984f..e367de96076b 100644
--- a/include/linux/hdmi.h
+++ b/include/linux/hdmi.h
@@ -32,6 +32,7 @@ enum hdmi_infoframe_type {
HDMI_INFOFRAME_TYPE_AVI = 0x82,
HDMI_INFOFRAME_TYPE_SPD = 0x83,
HDMI_INFOFRAME_TYPE_AUDIO = 0x84,
+ HDMI_INFOFRAME_TYPE_DRM = 0x87,
};
#define HDMI_IEEE_OUI 0x000c03
@@ -160,10 +161,28 @@ struct hdmi_avi_infoframe {
unsigned short right_bar;
};
+struct hdmi_drm_infoframe {
+ enum hdmi_infoframe_type type;
+ unsigned char version;
+ unsigned char length;
+ uint8_t eotf;
+ uint8_t metadata_type;
+ uint16_t display_primaries_x[3];
+ uint16_t display_primaries_y[3];
+ uint16_t white_point_x;
+ uint16_t white_point_y;
+ uint16_t max_mastering_display_luminance;
+ uint16_t min_mastering_display_luminance;
+ uint16_t max_fall;
+ uint16_t max_cll;
+};
+
int hdmi_avi_infoframe_init(struct hdmi_avi_infoframe *frame);
ssize_t hdmi_avi_infoframe_pack(struct hdmi_avi_infoframe *frame, void *buffer,
size_t size);
+int hdmi_drm_infoframe_init(struct hdmi_drm_infoframe *frame);
+
enum hdmi_spd_sdi {
HDMI_SPD_SDI_UNKNOWN,
HDMI_SPD_SDI_DSTB,
@@ -328,6 +347,7 @@ union hdmi_infoframe {
struct hdmi_spd_infoframe spd;
union hdmi_vendor_any_infoframe vendor;
struct hdmi_audio_infoframe audio;
+ struct hdmi_drm_infoframe drm;
};
ssize_t
diff --git a/include/linux/hx280enc.h b/include/linux/hx280enc.h
new file mode 100755
index 000000000000..186a00e3446f
--- /dev/null
+++ b/include/linux/hx280enc.h
@@ -0,0 +1,31 @@
+/*****************************************************************************
+ * Encoder device driver (kernel module header)
+ *
+ * Copyright (C) 2012 Google Finland Oy.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+--------------------------------------------------------------------------------
+--
+-- Abstract : 6280/7280/8270/8290/H1 Encoder device driver (kernel module)
+--
+*****************************************************************************/
+
+#ifndef _HX280ENC_H_
+#define _HX280ENC_H_
+
+#include <uapi/linux/hx280enc.h>
+
+#endif /* !_HX280ENC_H_ */
diff --git a/include/linux/imx_gpc.h b/include/linux/imx_gpc.h
new file mode 100644
index 000000000000..0eb38224c438
--- /dev/null
+++ b/include/linux/imx_gpc.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2015 Freescale Semiconductor, Inc.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU Lesser General
+ * Public License. You may obtain a copy of the GNU Lesser General
+ * Public License Version 2.1 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/lgpl-license.html
+ * http://www.gnu.org/copyleft/lgpl.html
+ */
+
+/*
+ * @file linux/imx_gpc.h
+ *
+ * @brief Global header file for imx GPC
+ *
+ * @ingroup GPC
+ */
+#ifndef __LINUX_IMX_GPC_H__
+#define __LINUX_IMX_GPC_H__
+
+#ifdef CONFIG_HAVE_IMX_GPC
+int imx_gpc_mf_request_on(unsigned int irq, unsigned int on);
+#else
+static inline int imx_gpc_mf_request_on(unsigned int irq, unsigned int on) { return 0; }
+#endif
+
+#endif /* __LINUX_IMX_GPC_H__ */
diff --git a/include/linux/imx_rpmsg.h b/include/linux/imx_rpmsg.h
new file mode 100644
index 000000000000..cabb6d6e03ce
--- /dev/null
+++ b/include/linux/imx_rpmsg.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2015 Freescale Semiconductor, Inc.
+ * Copyright (C) 2017 NXP.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU Lesser General
+ * Public License. You may obtain a copy of the GNU Lesser General
+ * Public License Version 2.1 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/lgpl-license.html
+ * http://www.gnu.org/copyleft/lgpl.html
+ */
+
+/*
+ * @file linux/imx_rpmsg.h
+ *
+ * @brief Global header file for imx RPMSG
+ *
+ * @ingroup RPMSG
+ */
+#ifndef __LINUX_IMX_RPMSG_H__
+#define __LINUX_IMX_RPMSG_H__
+
+/* Category define */
+#define IMX_RMPSG_LIFECYCLE 1
+#define IMX_RPMSG_PMIC 2
+#define IMX_RPMSG_AUDIO 3
+#define IMX_RPMSG_KEY 4
+#define IMX_RPMSG_GPIO 5
+#define IMX_RPMSG_RTC 6
+#define IMX_RPMSG_SENSOR 7
+/* rpmsg version */
+#define IMX_RMPSG_MAJOR 1
+#define IMX_RMPSG_MINOR 0
+
+struct imx_rpmsg_head {
+ u8 cate;
+ u8 major;
+ u8 minor;
+ u8 type;
+ u8 cmd;
+ u8 reserved[5];
+} __attribute__ ((packed));
+
+#endif /* __LINUX_IMX_RPMSG_H__ */
diff --git a/include/linux/imx_sema4.h b/include/linux/imx_sema4.h
new file mode 100644
index 000000000000..19850ae7742b
--- /dev/null
+++ b/include/linux/imx_sema4.h
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2014-2015 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.
+ */
+
+#ifndef __LINUX_IMX_SEMA4_H__
+#define __LINUX_IMX_SEMA4_H__
+
+#define SEMA4_NUM_DEVICES 1
+#define SEMA4_NUM_GATES 16
+
+#define SEMA4_UNLOCK 0x00
+#define SEMA4_A9_LOCK 0x01
+#define SEMA4_GATE_MASK 0x03
+
+#define CORE_MUTEX_VALID (('c'<<24)|('m'<<24)|('t'<<24)|'x')
+
+/*
+ * The enumerates
+ */
+enum {
+ /* sema4 registers offset */
+ SEMA4_CP0INE = 0x40,
+ SEMA4_CP1INE = 0x48,
+ SEMA4_CP0NTF = 0x80,
+ SEMA4_CP1NTF = 0x88,
+};
+
+static const unsigned int idx_sema4[SEMA4_NUM_GATES] = {
+ 1 << 7, 1 << 6, 1 << 5, 1 << 4,
+ 1 << 3, 1 << 2, 1 << 1, 1 << 0,
+ 1 << 15, 1 << 14, 1 << 13, 1 << 12,
+ 1 << 11, 1 << 10, 1 << 9, 1 << 8,
+};
+
+struct imx_sema4_mutex {
+ u32 valid;
+ u32 gate_num;
+ unsigned char gate_val;
+ wait_queue_head_t wait_q;
+};
+
+struct imx_sema4_mutex_device {
+ struct device *dev;
+ u16 cpntf_val;
+ u16 cpine_val;
+ void __iomem *ioaddr; /* Mapped address */
+ spinlock_t lock; /* Mutex */
+ int irq;
+
+ u16 alloced;
+ struct imx_sema4_mutex *mutex_ptr[SEMA4_NUM_GATES];
+};
+
+struct imx_sema4_mutex *
+ imx_sema4_mutex_create(u32 dev_num, u32 mutex_num);
+#ifdef CONFIG_IMX_SEMA4
+int imx_sema4_mutex_destroy(struct imx_sema4_mutex *mutex_ptr);
+int imx_sema4_mutex_trylock(struct imx_sema4_mutex *mutex_ptr);
+int imx_sema4_mutex_lock(struct imx_sema4_mutex *mutex_ptr);
+int imx_sema4_mutex_unlock(struct imx_sema4_mutex *mutex_ptr);
+#else
+static inline int imx_sema4_mutex_destroy(struct imx_sema4_mutex *mutex_ptr)
+{
+ return 0;
+}
+static inline int imx_sema4_mutex_trylock(struct imx_sema4_mutex *mutex_ptr)
+{
+ return 0;
+}
+static inline int imx_sema4_mutex_lock(struct imx_sema4_mutex *mutex_ptr)
+{
+ return 0;
+}
+static inline int imx_sema4_mutex_unlock(struct imx_sema4_mutex *mutex_ptr)
+{
+ return 0;
+}
+#endif
+#endif /* __LINUX_IMX_SEMA4_H__ */
diff --git a/include/linux/ipu-v3-pre.h b/include/linux/ipu-v3-pre.h
new file mode 100644
index 000000000000..f5a26e5eadbf
--- /dev/null
+++ b/include/linux/ipu-v3-pre.h
@@ -0,0 +1,155 @@
+/*
+ * Copyright (C) 2014-2015 Freescale Semiconductor, Inc.
+ *
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+#ifndef __LINUX_IPU_V3_PRE_H_
+#define __LINUX_IPU_V3_PRE_H_
+
+#define IPU_PRE_MAX_WIDTH 1920
+#define IPU_PRE_MAX_BPP 4
+#define IPU_PRE_SMALL_LINE 9 /* to workaround errata ERR009624*/
+
+struct ipu_rect {
+ int left;
+ int top;
+ int width;
+ int height;
+};
+
+struct ipu_pre_context {
+ bool repeat;
+ bool vflip;
+ bool handshake_en;
+ bool hsk_abort_en;
+ unsigned int hsk_line_num;
+ bool sdw_update;
+ unsigned int block_size;
+ unsigned int interlaced;
+ unsigned int prefetch_mode;
+
+ unsigned long cur_buf;
+ unsigned long next_buf;
+
+ unsigned int tile_fmt;
+
+ unsigned int read_burst;
+ unsigned int prefetch_input_bpp;
+ unsigned int prefetch_input_pixel_fmt;
+ unsigned int prefetch_shift_offset;
+ unsigned int prefetch_shift_width;
+ bool shift_bypass;
+ bool field_inverse;
+ bool tpr_coor_offset_en;
+ /* the output of prefetch is
+ * also the input of store
+ */
+ struct ipu_rect prefetch_output_size;
+ unsigned int prefetch_input_active_width;
+ unsigned int prefetch_input_width;
+ unsigned int prefetch_input_height;
+ unsigned int store_pitch;
+ int interlace_offset;
+
+ bool store_en;
+ unsigned int write_burst;
+ unsigned int store_output_bpp;
+
+ unsigned int sec_buf_off;
+ unsigned int trd_buf_off;
+
+ /* return for IPU fb caller */
+ unsigned long store_addr;
+};
+
+/*
+ * In order to workaround the PRE SoC bug recorded by errata ERR009624,
+ * the software cannot write the PRE_CTRL register when the PRE writes
+ * the PRE_CTRL register automatically to set the ENABLE bit(bit0) to 1
+ * in the PRE repeat mode.
+ * The software mechanism to set the PRE_CTRL register is different for
+ * PRE Y resolution higher than 9 lines and lower or equal to 9 lines.
+ * Use this helper to check the Y resolution.
+ */
+static inline bool ipu_pre_yres_is_small(unsigned int yres)
+{
+ return yres <= IPU_PRE_SMALL_LINE;
+}
+
+#ifdef CONFIG_MXC_IPU_V3_PRE
+int ipu_pre_alloc(int ipu_id, ipu_channel_t ipu_ch);
+void ipu_pre_free(unsigned int *id);
+unsigned long ipu_pre_alloc_double_buffer(unsigned int id, unsigned int size);
+void ipu_pre_free_double_buffer(unsigned int id);
+int ipu_pre_config(int id, struct ipu_pre_context *config);
+int ipu_pre_set_ctrl(unsigned int id, struct ipu_pre_context *config);
+int ipu_pre_enable(int id);
+void ipu_pre_disable(int id);
+int ipu_pre_set_fb_buffer(int id, bool resolve,
+ unsigned long fb_paddr,
+ unsigned int y_res,
+ unsigned int x_crop,
+ unsigned int y_crop,
+ unsigned int sec_buf_off,
+ unsigned int trd_buf_off);
+int ipu_pre_sdw_update(int id);
+#else
+int ipu_pre_alloc(int ipu_id, ipu_channel_t channel)
+{
+ return -ENODEV;
+}
+
+void ipu_pre_free(unsigned int *id)
+{
+}
+
+unsigned long ipu_pre_alloc_double_buffer(unsigned int id, unsigned int size)
+{
+ return -ENODEV;
+}
+
+void ipu_pre_free_double_buffer(unsigned int id)
+{
+}
+
+int ipu_pre_config(int id, struct ipu_pre_context *config)
+{
+ return -ENODEV;
+}
+
+int ipu_pre_set_ctrl(unsigned int id, struct ipu_pre_context *config)
+{
+ return -ENODEV;
+}
+
+int ipu_pre_enable(int id)
+{
+ return -ENODEV;
+}
+
+void ipu_pre_disable(int id)
+{
+ return;
+}
+
+int ipu_pre_set_fb_buffer(int id, bool resolve,
+ unsigned long fb_paddr,
+ unsigned int y_res,
+ unsigned int x_crop,
+ unsigned int y_crop,
+ unsigned int sec_buf_off,
+ unsigned int trd_buf_off)
+{
+ return -ENODEV;
+}
+int ipu_pre_sdw_update(int id)
+{
+ return -ENODEV;
+}
+#endif
+#endif /* __LINUX_IPU_V3_PRE_H_ */
diff --git a/include/linux/ipu-v3-prg.h b/include/linux/ipu-v3-prg.h
new file mode 100644
index 000000000000..2ab803a6699f
--- /dev/null
+++ b/include/linux/ipu-v3-prg.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2014-2015 Freescale Semiconductor, Inc.
+ *
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+#ifndef __LINUX_IPU_V3_PRG_H_
+#define __LINUX_IPU_V3_PRG_H_
+
+#include <linux/ipu-v3.h>
+
+#define PRG_SO_INTERLACE 1
+#define PRG_SO_PROGRESSIVE 0
+#define PRG_BLOCK_MODE 1
+#define PRG_SCAN_MODE 0
+
+struct ipu_prg_config {
+ unsigned int id;
+ unsigned int pre_num;
+ ipu_channel_t ipu_ch;
+ unsigned int stride;
+ unsigned int height;
+ unsigned int ipu_height;
+ unsigned int crop_line;
+ unsigned int so;
+ unsigned int ilo;
+ unsigned int block_mode;
+ bool vflip;
+ u32 baddr;
+ u32 offset;
+};
+
+#ifdef CONFIG_MXC_IPU_V3_PRG
+int ipu_prg_config(struct ipu_prg_config *config);
+int ipu_prg_disable(unsigned int ipu_id, unsigned int pre_num);
+int ipu_prg_wait_buf_ready(unsigned int ipu_id, unsigned int pre_num,
+ unsigned int hsk_line_num,
+ int pre_store_out_height);
+#else
+int ipu_prg_config(struct ipu_prg_config *config)
+{
+ return -ENODEV;
+}
+
+int ipu_prg_disable(unsigned int ipu_id, unsigned int pre_num)
+{
+ return -ENODEV;
+}
+
+int ipu_prg_wait_buf_ready(unsigned int ipu_id, unsigned int pre_num,
+ unsigned int hsk_line_num,
+ int pre_store_out_height)
+{
+ return -ENODEV;
+}
+#endif
+#endif /* __LINUX_IPU_V3_PRG_H_ */
diff --git a/include/linux/ipu-v3.h b/include/linux/ipu-v3.h
new file mode 100644
index 000000000000..ae09614a2257
--- /dev/null
+++ b/include/linux/ipu-v3.h
@@ -0,0 +1,770 @@
+/*
+ * Copyright (c) 2010 Sascha Hauer <s.hauer@pengutronix.de>
+ * Copyright (C) 2011-2015 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.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#ifndef __LINUX_IPU_V3_H_
+#define __LINUX_IPU_V3_H_
+
+#include <linux/ipu.h>
+
+/* IPU Driver channels definitions. */
+/* Note these are different from IDMA channels */
+#define IPU_MAX_CH 32
+#define _MAKE_CHAN(num, v_in, g_in, a_in, out) \
+ ((num << 24) | (v_in << 18) | (g_in << 12) | (a_in << 6) | out)
+#define _MAKE_ALT_CHAN(ch) (ch | (IPU_MAX_CH << 24))
+#define IPU_CHAN_ID(ch) (ch >> 24)
+#define IPU_CHAN_ALT(ch) (ch & 0x02000000)
+#define IPU_CHAN_ALPHA_IN_DMA(ch) ((uint32_t) (ch >> 6) & 0x3F)
+#define IPU_CHAN_GRAPH_IN_DMA(ch) ((uint32_t) (ch >> 12) & 0x3F)
+#define IPU_CHAN_VIDEO_IN_DMA(ch) ((uint32_t) (ch >> 18) & 0x3F)
+#define IPU_CHAN_OUT_DMA(ch) ((uint32_t) (ch & 0x3F))
+#define NO_DMA 0x3F
+#define ALT 1
+/*!
+ * Enumeration of IPU logical channels. An IPU logical channel is defined as a
+ * combination of an input (memory to IPU), output (IPU to memory), and/or
+ * secondary input IDMA channels and in some cases an Image Converter task.
+ * Some channels consist of only an input or output.
+ */
+typedef enum {
+ CHAN_NONE = -1,
+ MEM_ROT_ENC_MEM = _MAKE_CHAN(1, 45, NO_DMA, NO_DMA, 48),
+ MEM_ROT_VF_MEM = _MAKE_CHAN(2, 46, NO_DMA, NO_DMA, 49),
+ MEM_ROT_PP_MEM = _MAKE_CHAN(3, 47, NO_DMA, NO_DMA, 50),
+
+ MEM_PRP_ENC_MEM = _MAKE_CHAN(4, 12, 14, 17, 20),
+ MEM_PRP_VF_MEM = _MAKE_CHAN(5, 12, 14, 17, 21),
+ MEM_PP_MEM = _MAKE_CHAN(6, 11, 15, 18, 22),
+
+ MEM_DC_SYNC = _MAKE_CHAN(7, 28, NO_DMA, NO_DMA, NO_DMA),
+ MEM_DC_ASYNC = _MAKE_CHAN(8, 41, NO_DMA, NO_DMA, NO_DMA),
+ MEM_BG_SYNC = _MAKE_CHAN(9, 23, NO_DMA, 51, NO_DMA),
+ MEM_FG_SYNC = _MAKE_CHAN(10, 27, NO_DMA, 31, NO_DMA),
+
+ MEM_BG_ASYNC0 = _MAKE_CHAN(11, 24, NO_DMA, 52, NO_DMA),
+ MEM_FG_ASYNC0 = _MAKE_CHAN(12, 29, NO_DMA, 33, NO_DMA),
+ MEM_BG_ASYNC1 = _MAKE_ALT_CHAN(MEM_BG_ASYNC0),
+ MEM_FG_ASYNC1 = _MAKE_ALT_CHAN(MEM_FG_ASYNC0),
+
+ DIRECT_ASYNC0 = _MAKE_CHAN(13, NO_DMA, NO_DMA, NO_DMA, NO_DMA),
+ DIRECT_ASYNC1 = _MAKE_CHAN(14, NO_DMA, NO_DMA, NO_DMA, NO_DMA),
+
+ CSI_MEM0 = _MAKE_CHAN(15, NO_DMA, NO_DMA, NO_DMA, 0),
+ CSI_MEM1 = _MAKE_CHAN(16, NO_DMA, NO_DMA, NO_DMA, 1),
+ CSI_MEM2 = _MAKE_CHAN(17, NO_DMA, NO_DMA, NO_DMA, 2),
+ CSI_MEM3 = _MAKE_CHAN(18, NO_DMA, NO_DMA, NO_DMA, 3),
+
+ CSI_MEM = CSI_MEM0,
+
+ CSI_PRP_ENC_MEM = _MAKE_CHAN(19, NO_DMA, NO_DMA, NO_DMA, 20),
+ CSI_PRP_VF_MEM = _MAKE_CHAN(20, NO_DMA, NO_DMA, NO_DMA, 21),
+
+ /* for vdi mem->vdi->ic->mem , add graphics plane and alpha*/
+ MEM_VDI_PRP_VF_MEM_P = _MAKE_CHAN(21, 8, 14, 17, 21),
+ MEM_VDI_PRP_VF_MEM = _MAKE_CHAN(22, 9, 14, 17, 21),
+ MEM_VDI_PRP_VF_MEM_N = _MAKE_CHAN(23, 10, 14, 17, 21),
+
+ /* for vdi mem->vdi->mem */
+ MEM_VDI_MEM_P = _MAKE_CHAN(24, 8, NO_DMA, NO_DMA, 5),
+ MEM_VDI_MEM = _MAKE_CHAN(25, 9, NO_DMA, NO_DMA, 5),
+ MEM_VDI_MEM_N = _MAKE_CHAN(26, 10, NO_DMA, NO_DMA, 5),
+
+ /* fake channel for vdoa to link with IPU */
+ MEM_VDOA_MEM = _MAKE_CHAN(27, NO_DMA, NO_DMA, NO_DMA, NO_DMA),
+
+ MEM_PP_ADC = CHAN_NONE,
+ ADC_SYS2 = CHAN_NONE,
+
+} ipu_channel_t;
+
+/*!
+ * Enumeration of types of buffers for a logical channel.
+ */
+typedef enum {
+ IPU_OUTPUT_BUFFER = 0, /*!< Buffer for output from IPU */
+ IPU_ALPHA_IN_BUFFER = 1, /*!< Buffer for input to IPU */
+ IPU_GRAPH_IN_BUFFER = 2, /*!< Buffer for input to IPU */
+ IPU_VIDEO_IN_BUFFER = 3, /*!< Buffer for input to IPU */
+ IPU_INPUT_BUFFER = IPU_VIDEO_IN_BUFFER,
+ IPU_SEC_INPUT_BUFFER = IPU_GRAPH_IN_BUFFER,
+} ipu_buffer_t;
+
+#define IPU_PANEL_SERIAL 1
+#define IPU_PANEL_PARALLEL 2
+
+/*!
+ * Enumeration of ADC channel operation mode.
+ */
+typedef enum {
+ Disable,
+ WriteTemplateNonSeq,
+ ReadTemplateNonSeq,
+ WriteTemplateUnCon,
+ ReadTemplateUnCon,
+ WriteDataWithRS,
+ WriteDataWoRS,
+ WriteCmd
+} mcu_mode_t;
+
+/*!
+ * Enumeration of ADC channel addressing mode.
+ */
+typedef enum {
+ FullWoBE,
+ FullWithBE,
+ XY
+} display_addressing_t;
+
+/*!
+ * Union of initialization parameters for a logical channel.
+ */
+typedef union {
+ struct {
+ uint32_t csi;
+ uint32_t mipi_id;
+ uint32_t mipi_vc;
+ bool mipi_en;
+ bool interlaced;
+ } csi_mem;
+ struct {
+ uint32_t in_width;
+ uint32_t in_height;
+ uint32_t in_pixel_fmt;
+ uint32_t out_width;
+ uint32_t out_height;
+ uint32_t out_pixel_fmt;
+ uint32_t outh_resize_ratio;
+ uint32_t outv_resize_ratio;
+ uint32_t csi;
+ uint32_t mipi_id;
+ uint32_t mipi_vc;
+ bool mipi_en;
+ } csi_prp_enc_mem;
+ struct {
+ uint32_t in_width;
+ uint32_t in_height;
+ uint32_t in_pixel_fmt;
+ uint32_t out_width;
+ uint32_t out_height;
+ uint32_t out_pixel_fmt;
+ uint32_t outh_resize_ratio;
+ uint32_t outv_resize_ratio;
+ } mem_prp_enc_mem;
+ struct {
+ uint32_t in_width;
+ uint32_t in_height;
+ uint32_t in_pixel_fmt;
+ uint32_t out_width;
+ uint32_t out_height;
+ uint32_t out_pixel_fmt;
+ } mem_rot_enc_mem;
+ struct {
+ uint32_t in_width;
+ uint32_t in_height;
+ uint32_t in_pixel_fmt;
+ uint32_t out_width;
+ uint32_t out_height;
+ uint32_t out_pixel_fmt;
+ uint32_t outh_resize_ratio;
+ uint32_t outv_resize_ratio;
+ bool graphics_combine_en;
+ bool global_alpha_en;
+ bool key_color_en;
+ uint32_t in_g_pixel_fmt;
+ uint8_t alpha;
+ uint32_t key_color;
+ bool alpha_chan_en;
+ ipu_motion_sel motion_sel;
+ enum v4l2_field field_fmt;
+ uint32_t csi;
+ uint32_t mipi_id;
+ uint32_t mipi_vc;
+ bool mipi_en;
+ } csi_prp_vf_mem;
+ struct {
+ uint32_t in_width;
+ uint32_t in_height;
+ uint32_t in_pixel_fmt;
+ uint32_t out_width;
+ uint32_t out_height;
+ uint32_t out_pixel_fmt;
+ bool graphics_combine_en;
+ bool global_alpha_en;
+ bool key_color_en;
+ display_port_t disp;
+ uint32_t out_left;
+ uint32_t out_top;
+ } csi_prp_vf_adc;
+ struct {
+ uint32_t in_width;
+ uint32_t in_height;
+ uint32_t in_pixel_fmt;
+ uint32_t out_width;
+ uint32_t out_height;
+ uint32_t out_pixel_fmt;
+ uint32_t outh_resize_ratio;
+ uint32_t outv_resize_ratio;
+ bool graphics_combine_en;
+ bool global_alpha_en;
+ bool key_color_en;
+ uint32_t in_g_pixel_fmt;
+ uint8_t alpha;
+ uint32_t key_color;
+ bool alpha_chan_en;
+ ipu_motion_sel motion_sel;
+ enum v4l2_field field_fmt;
+ } mem_prp_vf_mem;
+ struct {
+ uint32_t temp;
+ } mem_prp_vf_adc;
+ struct {
+ uint32_t temp;
+ } mem_rot_vf_mem;
+ struct {
+ uint32_t in_width;
+ uint32_t in_height;
+ uint32_t in_pixel_fmt;
+ uint32_t out_width;
+ uint32_t out_height;
+ uint32_t out_pixel_fmt;
+ uint32_t outh_resize_ratio;
+ uint32_t outv_resize_ratio;
+ bool graphics_combine_en;
+ bool global_alpha_en;
+ bool key_color_en;
+ uint32_t in_g_pixel_fmt;
+ uint8_t alpha;
+ uint32_t key_color;
+ bool alpha_chan_en;
+ } mem_pp_mem;
+ struct {
+ uint32_t temp;
+ } mem_rot_mem;
+ struct {
+ uint32_t in_width;
+ uint32_t in_height;
+ uint32_t in_pixel_fmt;
+ uint32_t out_width;
+ uint32_t out_height;
+ uint32_t out_pixel_fmt;
+ bool graphics_combine_en;
+ bool global_alpha_en;
+ bool key_color_en;
+ display_port_t disp;
+ uint32_t out_left;
+ uint32_t out_top;
+ } mem_pp_adc;
+ struct {
+ uint32_t di;
+ bool interlaced;
+ uint32_t in_pixel_fmt;
+ uint32_t out_pixel_fmt;
+ } mem_dc_sync;
+ struct {
+ uint32_t temp;
+ } mem_sdc_fg;
+ struct {
+ uint32_t di;
+ bool interlaced;
+ uint32_t in_pixel_fmt;
+ uint32_t out_pixel_fmt;
+ bool alpha_chan_en;
+ } mem_dp_bg_sync;
+ struct {
+ uint32_t temp;
+ } mem_sdc_bg;
+ struct {
+ uint32_t di;
+ bool interlaced;
+ uint32_t in_pixel_fmt;
+ uint32_t out_pixel_fmt;
+ bool alpha_chan_en;
+ } mem_dp_fg_sync;
+ struct {
+ uint32_t di;
+ } direct_async;
+ struct {
+ display_port_t disp;
+ mcu_mode_t ch_mode;
+ uint32_t out_left;
+ uint32_t out_top;
+ } adc_sys1;
+ struct {
+ display_port_t disp;
+ mcu_mode_t ch_mode;
+ uint32_t out_left;
+ uint32_t out_top;
+ } adc_sys2;
+} ipu_channel_params_t;
+
+/*
+ * IPU_IRQF_ONESHOT - Interrupt is not reenabled after the irq handler finished.
+ */
+#define IPU_IRQF_NONE 0x00000000
+#define IPU_IRQF_ONESHOT 0x00000001
+
+/*!
+ * Enumeration of IPU interrupt sources.
+ */
+enum ipu_irq_line {
+ IPU_IRQ_CSI0_OUT_EOF = 0,
+ IPU_IRQ_CSI1_OUT_EOF = 1,
+ IPU_IRQ_CSI2_OUT_EOF = 2,
+ IPU_IRQ_CSI3_OUT_EOF = 3,
+ IPU_IRQ_VDIC_OUT_EOF = 5,
+ IPU_IRQ_VDI_P_IN_EOF = 8,
+ IPU_IRQ_VDI_C_IN_EOF = 9,
+ IPU_IRQ_VDI_N_IN_EOF = 10,
+ IPU_IRQ_PP_IN_EOF = 11,
+ IPU_IRQ_PRP_IN_EOF = 12,
+ IPU_IRQ_PRP_GRAPH_IN_EOF = 14,
+ IPU_IRQ_PP_GRAPH_IN_EOF = 15,
+ IPU_IRQ_PRP_ALPHA_IN_EOF = 17,
+ IPU_IRQ_PP_ALPHA_IN_EOF = 18,
+ IPU_IRQ_PRP_ENC_OUT_EOF = 20,
+ IPU_IRQ_PRP_VF_OUT_EOF = 21,
+ IPU_IRQ_PP_OUT_EOF = 22,
+ IPU_IRQ_BG_SYNC_EOF = 23,
+ IPU_IRQ_BG_ASYNC_EOF = 24,
+ IPU_IRQ_FG_SYNC_EOF = 27,
+ IPU_IRQ_DC_SYNC_EOF = 28,
+ IPU_IRQ_FG_ASYNC_EOF = 29,
+ IPU_IRQ_FG_ALPHA_SYNC_EOF = 31,
+
+ IPU_IRQ_FG_ALPHA_ASYNC_EOF = 33,
+ IPU_IRQ_DC_READ_EOF = 40,
+ IPU_IRQ_DC_ASYNC_EOF = 41,
+ IPU_IRQ_DC_CMD1_EOF = 42,
+ IPU_IRQ_DC_CMD2_EOF = 43,
+ IPU_IRQ_DC_MASK_EOF = 44,
+ IPU_IRQ_PRP_ENC_ROT_IN_EOF = 45,
+ IPU_IRQ_PRP_VF_ROT_IN_EOF = 46,
+ IPU_IRQ_PP_ROT_IN_EOF = 47,
+ IPU_IRQ_PRP_ENC_ROT_OUT_EOF = 48,
+ IPU_IRQ_PRP_VF_ROT_OUT_EOF = 49,
+ IPU_IRQ_PP_ROT_OUT_EOF = 50,
+ IPU_IRQ_BG_ALPHA_SYNC_EOF = 51,
+ IPU_IRQ_BG_ALPHA_ASYNC_EOF = 52,
+
+ IPU_IRQ_BG_SYNC_NFACK = 64 + 23,
+ IPU_IRQ_FG_SYNC_NFACK = 64 + 27,
+ IPU_IRQ_DC_SYNC_NFACK = 64 + 28,
+
+ IPU_IRQ_DP_SF_START = 448 + 2,
+ IPU_IRQ_DP_SF_END = 448 + 3,
+ IPU_IRQ_BG_SF_END = IPU_IRQ_DP_SF_END,
+ IPU_IRQ_DC_FC_0 = 448 + 8,
+ IPU_IRQ_DC_FC_1 = 448 + 9,
+ IPU_IRQ_DC_FC_2 = 448 + 10,
+ IPU_IRQ_DC_FC_3 = 448 + 11,
+ IPU_IRQ_DC_FC_4 = 448 + 12,
+ IPU_IRQ_DC_FC_6 = 448 + 13,
+ IPU_IRQ_VSYNC_PRE_0 = 448 + 14,
+ IPU_IRQ_VSYNC_PRE_1 = 448 + 15,
+
+ IPU_IRQ_COUNT
+};
+
+/*!
+ * Bitfield of Display Interface signal polarities.
+ */
+typedef struct {
+ unsigned datamask_en:1;
+ unsigned int_clk: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;
+} ipu_di_signal_cfg_t;
+
+/*!
+ * Bitfield of CSI signal polarities and modes.
+ */
+
+typedef struct {
+ unsigned data_width:4;
+ unsigned clk_mode:3;
+ unsigned ext_vsync:1;
+ unsigned Vsync_pol:1;
+ unsigned Hsync_pol:1;
+ unsigned pixclk_pol:1;
+ unsigned data_pol:1;
+ unsigned sens_clksrc:1;
+ unsigned pack_tight:1;
+ unsigned force_eof:1;
+ unsigned data_en_pol:1;
+ unsigned data_fmt;
+ unsigned csi;
+ unsigned mclk;
+} ipu_csi_signal_cfg_t;
+
+/*!
+ * Enumeration of CSI data bus widths.
+ */
+enum {
+ IPU_CSI_DATA_WIDTH_4 = 0,
+ IPU_CSI_DATA_WIDTH_8 = 1,
+ IPU_CSI_DATA_WIDTH_10 = 3,
+ IPU_CSI_DATA_WIDTH_16 = 9,
+};
+
+/*!
+ * Enumeration of CSI clock modes.
+ */
+enum {
+ IPU_CSI_CLK_MODE_GATED_CLK,
+ IPU_CSI_CLK_MODE_NONGATED_CLK,
+ IPU_CSI_CLK_MODE_CCIR656_PROGRESSIVE,
+ IPU_CSI_CLK_MODE_CCIR656_INTERLACED,
+ IPU_CSI_CLK_MODE_CCIR1120_PROGRESSIVE_DDR,
+ IPU_CSI_CLK_MODE_CCIR1120_PROGRESSIVE_SDR,
+ IPU_CSI_CLK_MODE_CCIR1120_INTERLACED_DDR,
+ IPU_CSI_CLK_MODE_CCIR1120_INTERLACED_SDR,
+};
+
+enum {
+ IPU_CSI_MIPI_DI0,
+ IPU_CSI_MIPI_DI1,
+ IPU_CSI_MIPI_DI2,
+ IPU_CSI_MIPI_DI3,
+};
+
+typedef enum {
+ RGB,
+ YCbCr,
+ YUV
+} ipu_color_space_t;
+
+/*!
+ * Enumeration of ADC vertical sync mode.
+ */
+typedef enum {
+ VsyncNone,
+ VsyncInternal,
+ VsyncCSI,
+ VsyncExternal
+} vsync_t;
+
+typedef enum {
+ DAT,
+ CMD
+} cmddata_t;
+
+/*!
+ * Enumeration of ADC display update mode.
+ */
+typedef enum {
+ IPU_ADC_REFRESH_NONE,
+ IPU_ADC_AUTO_REFRESH,
+ IPU_ADC_AUTO_REFRESH_SNOOP,
+ IPU_ADC_SNOOPING,
+} ipu_adc_update_mode_t;
+
+/*!
+ * Enumeration of ADC display interface types (serial or parallel).
+ */
+enum {
+ IPU_ADC_IFC_MODE_SYS80_TYPE1,
+ IPU_ADC_IFC_MODE_SYS80_TYPE2,
+ IPU_ADC_IFC_MODE_SYS68K_TYPE1,
+ IPU_ADC_IFC_MODE_SYS68K_TYPE2,
+ IPU_ADC_IFC_MODE_3WIRE_SERIAL,
+ IPU_ADC_IFC_MODE_4WIRE_SERIAL,
+ IPU_ADC_IFC_MODE_5WIRE_SERIAL_CLK,
+ IPU_ADC_IFC_MODE_5WIRE_SERIAL_CS,
+};
+
+enum {
+ IPU_ADC_IFC_WIDTH_8,
+ IPU_ADC_IFC_WIDTH_16,
+};
+
+/*!
+ * Enumeration of ADC display interface burst mode.
+ */
+enum {
+ IPU_ADC_BURST_WCS,
+ IPU_ADC_BURST_WBLCK,
+ IPU_ADC_BURST_NONE,
+ IPU_ADC_BURST_SERIAL,
+};
+
+/*!
+ * Enumeration of ADC display interface RW signal timing modes.
+ */
+enum {
+ IPU_ADC_SER_NO_RW,
+ IPU_ADC_SER_RW_BEFORE_RS,
+ IPU_ADC_SER_RW_AFTER_RS,
+};
+
+/*!
+ * Bitfield of ADC signal polarities and modes.
+ */
+typedef struct {
+ unsigned data_pol:1;
+ unsigned clk_pol:1;
+ unsigned cs_pol:1;
+ unsigned rs_pol:1;
+ unsigned addr_pol:1;
+ unsigned read_pol:1;
+ unsigned write_pol:1;
+ unsigned Vsync_pol:1;
+ unsigned burst_pol:1;
+ unsigned burst_mode:2;
+ unsigned ifc_mode:3;
+ unsigned ifc_width:5;
+ unsigned ser_preamble_len:4;
+ unsigned ser_preamble:8;
+ unsigned ser_rw_mode:2;
+} ipu_adc_sig_cfg_t;
+
+/*!
+ * Enumeration of ADC template commands.
+ */
+enum {
+ RD_DATA,
+ RD_ACK,
+ RD_WAIT,
+ WR_XADDR,
+ WR_YADDR,
+ WR_ADDR,
+ WR_CMND,
+ WR_DATA,
+};
+
+/*!
+ * Enumeration of ADC template command flow control.
+ */
+enum {
+ SINGLE_STEP,
+ PAUSE,
+ STOP,
+};
+
+
+/*Define template constants*/
+#define ATM_ADDR_RANGE 0x20 /*offset address of DISP */
+#define TEMPLATE_BUF_SIZE 0x20 /*size of template */
+
+/*!
+ * Define to create ADC template command entry.
+ */
+#define ipu_adc_template_gen(oc, rs, fc, dat) (((rs) << 29) | ((fc) << 27) | \
+ ((oc) << 24) | (dat))
+
+typedef struct {
+ u32 reg;
+ u32 value;
+} ipu_lpmc_reg_t;
+
+#define IPU_LPMC_REG_READ 0x80000000L
+
+#define CSI_MCLK_VF 1
+#define CSI_MCLK_ENC 2
+#define CSI_MCLK_RAW 4
+#define CSI_MCLK_I2C 8
+
+struct ipu_soc;
+/* Common IPU API */
+struct ipu_soc *ipu_get_soc(int id);
+int32_t ipu_init_channel(struct ipu_soc *ipu, ipu_channel_t channel, ipu_channel_params_t *params);
+void ipu_uninit_channel(struct ipu_soc *ipu, ipu_channel_t channel);
+void ipu_disable_hsp_clk(struct ipu_soc *ipu);
+
+static inline bool ipu_can_rotate_in_place(ipu_rotate_mode_t rot)
+{
+#ifdef CONFIG_MXC_IPU_V3D
+ return (rot < IPU_ROTATE_HORIZ_FLIP);
+#else
+ return (rot < IPU_ROTATE_90_RIGHT);
+#endif
+}
+
+int32_t ipu_init_channel_buffer(struct ipu_soc *ipu, ipu_channel_t channel, ipu_buffer_t type,
+ uint32_t pixel_fmt,
+ uint16_t width, uint16_t height,
+ uint32_t stride,
+ ipu_rotate_mode_t rot_mode,
+ dma_addr_t phyaddr_0, dma_addr_t phyaddr_1,
+ dma_addr_t phyaddr_2,
+ uint32_t u_offset, uint32_t v_offset);
+
+int32_t ipu_update_channel_buffer(struct ipu_soc *ipu, ipu_channel_t channel, ipu_buffer_t type,
+ uint32_t bufNum, dma_addr_t phyaddr);
+
+int32_t ipu_update_channel_offset(struct ipu_soc *ipu, ipu_channel_t channel, ipu_buffer_t type,
+ uint32_t pixel_fmt,
+ uint16_t width, uint16_t height,
+ uint32_t stride,
+ uint32_t u, uint32_t v,
+ uint32_t vertical_offset, uint32_t horizontal_offset);
+
+int32_t ipu_get_channel_offset(uint32_t pixel_fmt,
+ uint16_t width, uint16_t height,
+ uint32_t stride,
+ uint32_t u, uint32_t v,
+ uint32_t vertical_offset, uint32_t horizontal_offset,
+ uint32_t *u_offset, uint32_t *v_offset);
+
+int32_t ipu_select_buffer(struct ipu_soc *ipu, ipu_channel_t channel,
+ ipu_buffer_t type, uint32_t bufNum);
+int32_t ipu_select_multi_vdi_buffer(struct ipu_soc *ipu, uint32_t bufNum);
+
+int32_t ipu_link_channels(struct ipu_soc *ipu, ipu_channel_t src_ch, ipu_channel_t dest_ch);
+int32_t ipu_unlink_channels(struct ipu_soc *ipu, ipu_channel_t src_ch, ipu_channel_t dest_ch);
+
+int32_t ipu_is_channel_busy(struct ipu_soc *ipu, ipu_channel_t channel);
+int32_t ipu_check_buffer_ready(struct ipu_soc *ipu, ipu_channel_t channel, ipu_buffer_t type,
+ uint32_t bufNum);
+void ipu_clear_buffer_ready(struct ipu_soc *ipu, ipu_channel_t channel, ipu_buffer_t type,
+ uint32_t bufNum);
+uint32_t ipu_get_cur_buffer_idx(struct ipu_soc *ipu, ipu_channel_t channel, ipu_buffer_t type);
+int32_t ipu_enable_channel(struct ipu_soc *ipu, ipu_channel_t channel);
+int32_t ipu_disable_channel(struct ipu_soc *ipu, ipu_channel_t channel, bool wait_for_stop);
+int32_t ipu_swap_channel(struct ipu_soc *ipu, ipu_channel_t from_ch, ipu_channel_t to_ch);
+uint32_t ipu_channel_status(struct ipu_soc *ipu, ipu_channel_t channel);
+
+int32_t ipu_enable_csi(struct ipu_soc *ipu, uint32_t csi);
+int32_t ipu_disable_csi(struct ipu_soc *ipu, uint32_t csi);
+
+int ipu_lowpwr_display_enable(void);
+int ipu_lowpwr_display_disable(void);
+
+int ipu_enable_irq(struct ipu_soc *ipu, uint32_t irq);
+void ipu_disable_irq(struct ipu_soc *ipu, uint32_t irq);
+void ipu_clear_irq(struct ipu_soc *ipu, uint32_t irq);
+int ipu_request_irq(struct ipu_soc *ipu, uint32_t irq,
+ irqreturn_t(*handler) (int, void *),
+ uint32_t irq_flags, const char *devname, void *dev_id);
+void ipu_free_irq(struct ipu_soc *ipu, uint32_t irq, void *dev_id);
+bool ipu_get_irq_status(struct ipu_soc *ipu, uint32_t irq);
+void ipu_set_csc_coefficients(struct ipu_soc *ipu, ipu_channel_t channel, int32_t param[][3]);
+int32_t ipu_set_channel_bandmode(struct ipu_soc *ipu, ipu_channel_t channel,
+ ipu_buffer_t type, uint32_t band_height);
+
+/* two stripe calculations */
+struct stripe_param{
+ unsigned int input_width; /* width of the input stripe */
+ unsigned int output_width; /* width of the output stripe */
+ unsigned int input_column; /* the first column on the input stripe */
+ unsigned int output_column; /* the first column on the output stripe */
+ unsigned int idr;
+ /* inverse downisizing ratio parameter; expressed as a power of 2 */
+ unsigned int irr;
+ /* inverse resizing ratio parameter; expressed as a multiple of 2^-13 */
+};
+int ipu_calc_stripes_sizes(const unsigned int input_frame_width,
+ unsigned int output_frame_width,
+ const unsigned int maximal_stripe_width,
+ const unsigned long long cirr,
+ const unsigned int equal_stripes,
+ u32 input_pixelformat,
+ u32 output_pixelformat,
+ struct stripe_param *left,
+ struct stripe_param *right);
+
+/* SDC API */
+int32_t ipu_init_sync_panel(struct ipu_soc *ipu, int disp,
+ uint32_t pixel_clk,
+ uint16_t width, uint16_t height,
+ uint32_t pixel_fmt,
+ uint16_t h_start_width, uint16_t h_sync_width,
+ uint16_t h_end_width, uint16_t v_start_width,
+ uint16_t v_sync_width, uint16_t v_end_width,
+ uint32_t v_to_h_sync, ipu_di_signal_cfg_t sig);
+
+void ipu_uninit_sync_panel(struct ipu_soc *ipu, int disp);
+
+int32_t ipu_disp_set_window_pos(struct ipu_soc *ipu, ipu_channel_t channel, int16_t x_pos,
+ int16_t y_pos);
+int32_t ipu_disp_get_window_pos(struct ipu_soc *ipu, ipu_channel_t channel, int16_t *x_pos,
+ int16_t *y_pos);
+int32_t ipu_disp_set_global_alpha(struct ipu_soc *ipu, ipu_channel_t channel, bool enable,
+ uint8_t alpha);
+int32_t ipu_disp_set_color_key(struct ipu_soc *ipu, ipu_channel_t channel, bool enable,
+ uint32_t colorKey);
+int32_t ipu_disp_set_gamma_correction(struct ipu_soc *ipu, ipu_channel_t channel, bool enable,
+ int constk[], int slopek[]);
+
+int ipu_init_async_panel(struct ipu_soc *ipu, int disp, int type, uint32_t cycle_time,
+ uint32_t pixel_fmt, ipu_adc_sig_cfg_t sig);
+void ipu_reset_disp_panel(struct ipu_soc *ipu);
+
+/* CMOS Sensor Interface API */
+int32_t ipu_csi_init_interface(struct ipu_soc *ipu, uint16_t width, uint16_t height,
+ uint32_t pixel_fmt, ipu_csi_signal_cfg_t sig);
+
+int32_t ipu_csi_get_sensor_protocol(struct ipu_soc *ipu, uint32_t csi);
+
+int32_t ipu_csi_enable_mclk(struct ipu_soc *ipu, int src, bool flag, bool wait);
+
+static inline int32_t ipu_csi_enable_mclk_if(struct ipu_soc *ipu, int src, uint32_t csi,
+ bool flag, bool wait)
+{
+ return ipu_csi_enable_mclk(ipu, csi, flag, wait);
+}
+
+int ipu_csi_read_mclk_flag(void);
+
+void ipu_csi_flash_strobe(bool flag);
+
+void ipu_csi_get_window_size(struct ipu_soc *ipu, uint32_t *width, uint32_t *height, uint32_t csi);
+
+void ipu_csi_set_window_size(struct ipu_soc *ipu, uint32_t width, uint32_t height, uint32_t csi);
+
+void ipu_csi_set_window_pos(struct ipu_soc *ipu, uint32_t left, uint32_t top, uint32_t csi);
+
+uint32_t bytes_per_pixel(uint32_t fmt);
+
+bool ipu_ch_param_bad_alpha_pos(uint32_t fmt);
+int ipu_ch_param_get_axi_id(struct ipu_soc *ipu, ipu_channel_t channel, ipu_buffer_t type);
+ipu_color_space_t format_to_colorspace(uint32_t fmt);
+bool ipu_pixel_format_is_gpu_tile(uint32_t fmt);
+bool ipu_pixel_format_is_split_gpu_tile(uint32_t fmt);
+bool ipu_pixel_format_is_pre_yuv(uint32_t fmt);
+bool ipu_pixel_format_is_multiplanar_yuv(uint32_t fmt);
+
+struct ipuv3_fb_platform_data {
+ char disp_dev[32];
+ u32 interface_pix_fmt;
+ char *mode_str;
+ int default_bpp;
+ bool int_clk;
+
+ /* reserved mem */
+ resource_size_t res_base[2];
+ resource_size_t res_size[2];
+
+ /*
+ * Late init to avoid display channel being
+ * re-initialized as we've probably setup the
+ * channel in bootloader.
+ */
+ bool late_init;
+
+ /* Enable prefetch engine or not? */
+ bool prefetch;
+
+ /* Enable the PRE resolve engine or not? */
+ bool resolve;
+};
+
+#endif /* __LINUX_IPU_V3_H_ */
diff --git a/include/linux/ipu.h b/include/linux/ipu.h
new file mode 100644
index 000000000000..1090ac65f24b
--- /dev/null
+++ b/include/linux/ipu.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2005-2015 Freescale Semiconductor, Inc.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU Lesser General
+ * Public License. You may obtain a copy of the GNU Lesser General
+ * Public License Version 2.1 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/lgpl-license.html
+ * http://www.gnu.org/copyleft/lgpl.html
+ */
+
+/*!
+ * @defgroup IPU MXC Image Processing Unit (IPU) Driver
+ */
+/*!
+ * @file linux/ipu.h
+ *
+ * @brief This file contains the IPU driver API declarations.
+ *
+ * @ingroup IPU
+ */
+
+#ifndef __LINUX_IPU_H__
+#define __LINUX_IPU_H__
+
+#include <linux/interrupt.h>
+#include <uapi/linux/ipu.h>
+
+unsigned int fmt_to_bpp(unsigned int pixelformat);
+cs_t colorspaceofpixel(int fmt);
+int need_csc(int ifmt, int ofmt);
+
+int ipu_queue_task(struct ipu_task *task);
+int ipu_check_task(struct ipu_task *task);
+
+#endif
diff --git a/include/linux/isl29023.h b/include/linux/isl29023.h
new file mode 100644
index 000000000000..5c84566b7b21
--- /dev/null
+++ b/include/linux/isl29023.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2011-2014 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __ISL29023_H__
+#define __ISL29023_H__
+
+#include <linux/types.h>
+
+#define ISL29023_PD_MODE 0x0
+#define ISL29023_ALS_ONCE_MODE 0x1
+#define ISL29023_IR_ONCE_MODE 0x2
+#define ISL29023_ALS_CONT_MODE 0x5
+#define ISL29023_IR_CONT_MODE 0x6
+
+#define ISL29023_INT_PERSISTS_1 0x0
+#define ISL29023_INT_PERSISTS_4 0x1
+#define ISL29023_INT_PERSISTS_8 0x2
+#define ISL29023_INT_PERSISTS_16 0x3
+
+#define ISL29023_RES_16 0x0
+#define ISL29023_RES_12 0x1
+#define ISL29023_RES_8 0x2
+#define ISL29023_RES_4 0x3
+
+#define ISL29023_RANGE_1K 0x0
+#define ISL29023_RANGE_4K 0x1
+#define ISL29023_RANGE_16K 0x2
+#define ISL29023_RANGE_64K 0x3
+
+#endif
diff --git a/include/linux/mfd/bd71837.h b/include/linux/mfd/bd71837.h
new file mode 100644
index 000000000000..3cd51f314b20
--- /dev/null
+++ b/include/linux/mfd/bd71837.h
@@ -0,0 +1,413 @@
+/**
+ * @file bd71837.h ROHM BD71837MWV header file
+ *
+ * Copyright 2017
+ *
+ * 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.
+ *
+ * @author cpham2403@gmail.com
+ */
+
+#ifndef __LINUX_MFD_BD71837_H
+#define __LINUX_MFD_BD71837_H
+
+#include <linux/regmap.h>
+
+enum {
+ BD71837_BUCK1 = 0,
+ BD71837_BUCK2,
+ BD71837_BUCK3,
+ BD71837_BUCK4,
+ BD71837_BUCK5,
+ BD71837_BUCK6,
+ BD71837_BUCK7,
+ BD71837_BUCK8,
+ // General Purpose
+ BD71837_LDO1,
+ BD71837_LDO2,
+ BD71837_LDO3,
+ BD71837_LDO4,
+ BD71837_LDO5,
+ BD71837_LDO6,
+ BD71837_LDO7,
+ BD71837_REGULATOR_CNT,
+};
+
+#define BD71837_SUPPLY_STATE_ENABLED 0x1
+
+#define BD71837_BUCK1_VOLTAGE_NUM 0x40
+#define BD71837_BUCK2_VOLTAGE_NUM 0x40
+#define BD71837_BUCK3_VOLTAGE_NUM 0x40
+#define BD71837_BUCK4_VOLTAGE_NUM 0x40
+
+#define BD71837_BUCK5_VOLTAGE_NUM 0x08
+#define BD71837_BUCK6_VOLTAGE_NUM 0x04
+#define BD71837_BUCK7_VOLTAGE_NUM 0x08
+#define BD71837_BUCK8_VOLTAGE_NUM 0x40
+
+#define BD71837_LDO1_VOLTAGE_NUM 0x04
+#define BD71837_LDO2_VOLTAGE_NUM 0x02
+#define BD71837_LDO3_VOLTAGE_NUM 0x10
+#define BD71837_LDO4_VOLTAGE_NUM 0x10
+#define BD71837_LDO5_VOLTAGE_NUM 0x10
+#define BD71837_LDO6_VOLTAGE_NUM 0x10
+#define BD71837_LDO7_VOLTAGE_NUM 0x10
+
+enum {
+ BD71837_REG_REV = 0x00,
+ BD71837_REG_SWRESET = 0x01,
+ BD71837_REG_I2C_DEV = 0x02,
+ BD71837_REG_PWRCTRL0 = 0x03,
+ BD71837_REG_PWRCTRL1 = 0x04,
+ BD71837_REG_BUCK1_CTRL = 0x05,
+ BD71837_REG_BUCK2_CTRL = 0x06,
+ BD71837_REG_BUCK3_CTRL = 0x07,
+ BD71837_REG_BUCK4_CTRL = 0x08,
+ BD71837_REG_BUCK5_CTRL = 0x09,
+ BD71837_REG_BUCK6_CTRL = 0x0A,
+ BD71837_REG_BUCK7_CTRL = 0x0B,
+ BD71837_REG_BUCK8_CTRL = 0x0C,
+ BD71837_REG_BUCK1_VOLT_RUN = 0x0D,
+ BD71837_REG_BUCK1_VOLT_IDLE = 0x0E,
+ BD71837_REG_BUCK1_VOLT_SUSP = 0x0F,
+ BD71837_REG_BUCK2_VOLT_RUN = 0x10,
+ BD71837_REG_BUCK2_VOLT_IDLE = 0x11,
+ BD71837_REG_BUCK3_VOLT_RUN = 0x12,
+ BD71837_REG_BUCK4_VOLT_RUN = 0x13,
+ BD71837_REG_BUCK5_VOLT = 0x14,
+ BD71837_REG_BUCK6_VOLT = 0x15,
+ BD71837_REG_BUCK7_VOLT = 0x16,
+ BD71837_REG_BUCK8_VOLT = 0x17,
+ BD71837_REG_LDO1_VOLT = 0x18,
+ BD71837_REG_LDO2_VOLT = 0x19,
+ BD71837_REG_LDO3_VOLT = 0x1A,
+ BD71837_REG_LDO4_VOLT = 0x1B,
+ BD71837_REG_LDO5_VOLT = 0x1C,
+ BD71837_REG_LDO6_VOLT = 0x1D,
+ BD71837_REG_LDO7_VOLT = 0x1E,
+ BD71837_REG_TRANS_COND0 = 0x1F,
+ BD71837_REG_TRANS_COND1 = 0x20,
+ BD71837_REG_VRFAULTEN = 0x21,
+ BD71837_REG_MVRFLTMASK0 = 0x22,
+ BD71837_REG_MVRFLTMASK1 = 0x23,
+ BD71837_REG_MVRFLTMASK2 = 0x24,
+ BD71837_REG_RCVCFG = 0x25,
+ BD71837_REG_RCVNUM = 0x26,
+ BD71837_REG_PWRONCONFIG0 = 0x27,
+ BD71837_REG_PWRONCONFIG1 = 0x28,
+ BD71837_REG_RESETSRC = 0x29,
+ BD71837_REG_MIRQ = 0x2A,
+ BD71837_REG_IRQ = 0x2B,
+ BD71837_REG_IN_MON = 0x2C,
+ BD71837_REG_POW_STATE = 0x2D,
+ BD71837_REG_OUT32K = 0x2E,
+ BD71837_REG_REGLOCK = 0x2F,
+ BD71837_REG_OTPVER = 0xFF,
+ BD71837_MAX_REGISTER = 0x100,
+};
+
+/* BD71837_REG_BUCK1_CTRL bits */
+#define BUCK1_RAMPRATE_MASK 0xC0
+#define BUCK1_RAMPRATE_10P00MV 0x0
+#define BUCK1_RAMPRATE_5P00MV 0x1
+#define BUCK1_RAMPRATE_2P50MV 0x2
+#define BUCK1_RAMPRATE_1P25MV 0x3
+#define BUCK1_SEL 0x02
+#define BUCK1_EN 0x01
+
+/* BD71837_REG_BUCK2_CTRL bits */
+#define BUCK2_RAMPRATE_MASK 0xC0
+#define BUCK2_RAMPRATE_10P00MV 0x0
+#define BUCK2_RAMPRATE_5P00MV 0x1
+#define BUCK2_RAMPRATE_2P50MV 0x2
+#define BUCK2_RAMPRATE_1P25MV 0x3
+#define BUCK2_SEL 0x02
+#define BUCK2_EN 0x01
+
+/* BD71837_REG_BUCK3_CTRL bits */
+#define BUCK3_RAMPRATE_MASK 0xC0
+#define BUCK3_RAMPRATE_10P00MV 0x0
+#define BUCK3_RAMPRATE_5P00MV 0x1
+#define BUCK3_RAMPRATE_2P50MV 0x2
+#define BUCK3_RAMPRATE_1P25MV 0x3
+#define BUCK3_SEL 0x02
+#define BUCK3_EN 0x01
+
+/* BD71837_REG_BUCK4_CTRL bits */
+#define BUCK4_RAMPRATE_MASK 0xC0
+#define BUCK4_RAMPRATE_10P00MV 0x0
+#define BUCK4_RAMPRATE_5P00MV 0x1
+#define BUCK4_RAMPRATE_2P50MV 0x2
+#define BUCK4_RAMPRATE_1P25MV 0x3
+#define BUCK4_SEL 0x02
+#define BUCK4_EN 0x01
+
+/* BD71837_REG_BUCK5_CTRL bits */
+#define BUCK5_SEL 0x02
+#define BUCK5_EN 0x01
+
+/* BD71837_REG_BUCK6_CTRL bits */
+#define BUCK6_SEL 0x02
+#define BUCK6_EN 0x01
+
+/* BD71837_REG_BUCK7_CTRL bits */
+#define BUCK7_SEL 0x02
+#define BUCK7_EN 0x01
+
+/* BD71837_REG_BUCK8_CTRL bits */
+#define BUCK8_SEL 0x02
+#define BUCK8_EN 0x01
+
+/* BD71837_REG_BUCK1_VOLT_RUN bits */
+#define BUCK1_RUN_MASK 0x3F
+#define BUCK1_RUN_DEFAULT 0x14
+
+/* BD71837_REG_BUCK1_VOLT_SUSP bits */
+#define BUCK1_SUSP_MASK 0x3F
+#define BUCK1_SUSP_DEFAULT 0x14
+
+/* BD71837_REG_BUCK1_VOLT_IDLE bits */
+#define BUCK1_IDLE_MASK 0x3F
+#define BUCK1_IDLE_DEFAULT 0x14
+
+/* BD71837_REG_BUCK2_VOLT_RUN bits */
+#define BUCK2_RUN_MASK 0x3F
+#define BUCK2_RUN_DEFAULT 0x1E
+
+/* BD71837_REG_BUCK2_VOLT_IDLE bits */
+#define BUCK2_IDLE_MASK 0x3F
+#define BUCK2_IDLE_DEFAULT 0x14
+
+/* BD71837_REG_BUCK3_VOLT_RUN bits */
+#define BUCK3_RUN_MASK 0x3F
+#define BUCK3_RUN_DEFAULT 0x1E
+
+/* BD71837_REG_BUCK4_VOLT_RUN bits */
+#define BUCK4_RUN_MASK 0x3F
+#define BUCK4_RUN_DEFAULT 0x1E
+
+/* BD71837_REG_BUCK5_VOLT bits */
+#define BUCK5_MASK 0x07
+#define BUCK5_DEFAULT 0x02
+
+/* BD71837_REG_BUCK6_VOLT bits */
+#define BUCK6_MASK 0x03
+#define BUCK6_DEFAULT 0x03
+
+/* BD71837_REG_BUCK7_VOLT bits */
+#define BUCK7_MASK 0x07
+#define BUCK7_DEFAULT 0x03
+
+/* BD71837_REG_BUCK8_VOLT bits */
+#define BUCK8_MASK 0x3F
+#define BUCK8_DEFAULT 0x1E
+
+/* BD71837_REG_IRQ bits */
+#define IRQ_SWRST 0x40
+#define IRQ_PWRON_S 0x20
+#define IRQ_PWRON_L 0x10
+#define IRQ_PWRON 0x08
+#define IRQ_WDOG 0x04
+#define IRQ_ON_REQ 0x02
+#define IRQ_STBY_REQ 0x01
+
+/* BD71837_REG_OUT32K bits */
+#define OUT32K_EN 0x01
+
+/* BD71837 interrupt masks */
+enum {
+ BD71837_INT_MASK = 0x7F,
+};
+/* BD71837 interrupt irqs */
+enum {
+ BD71837_IRQ = 0x0,
+};
+
+/* BD71837_REG_LDO1_VOLT bits */
+#define LDO1_SEL 0x80
+#define LDO1_EN 0x40
+#define LDO1_MASK 0x03
+
+/* BD71837_REG_LDO2_VOLT bits */
+#define LDO2_SEL 0x80
+#define LDO2_EN 0x40
+
+/* BD71837_REG_LDO3_VOLT bits */
+#define LDO3_SEL 0x80
+#define LDO3_EN 0x40
+#define LDO3_MASK 0x0F
+
+/* BD71837_REG_LDO4_VOLT bits */
+#define LDO4_SEL 0x80
+#define LDO4_EN 0x40
+#define LDO4_MASK 0x0F
+
+/* BD71837_REG_LDO5_VOLT bits */
+#define LDO5_EN 0x40
+#define LDO5_MASK 0x0F
+
+/* BD71837_REG_LDO6_VOLT bits */
+#define LDO6_EN 0x40
+#define LDO6_MASK 0x0F
+
+/* BD71837_REG_LDO7_VOLT bits */
+#define LDO7_EN 0x40
+#define LDO7_MASK 0x0F
+
+/** @brief charge state enumuration */
+enum CHG_STATE {
+ CHG_STATE_SUSPEND = 0x0, /**< suspend state */
+ CHG_STATE_TRICKLE_CHARGE, /**< trickle charge state */
+ CHG_STATE_PRE_CHARGE, /**< precharge state */
+ CHG_STATE_FAST_CHARGE, /**< fast charge state */
+ CHG_STATE_TOP_OFF, /**< top off state */
+ CHG_STATE_DONE, /**< charge complete */
+};
+
+struct bd71837;
+
+/**
+ * @brief Board platform data may be used to initialize regulators.
+ */
+
+struct bd71837_board {
+ struct regulator_init_data *init_data[BD71837_REGULATOR_CNT];
+ /**< regulator initialize data */
+ int gpio_intr; /**< gpio connected to bd71837 INTB */
+ int irq_base; /**< bd71837 sub irqs base # */
+};
+
+/**
+ * @brief bd71837 sub-driver chip access routines
+ */
+
+struct bd71837 {
+ struct device *dev;
+ struct i2c_client *i2c_client;
+ struct regmap *regmap;
+ struct mutex io_mutex;
+ unsigned int id;
+
+ /* IRQ Handling */
+ int chip_irq; /**< bd71837 irq to host cpu */
+ struct regmap_irq_chip_data *irq_data;
+
+ /* Client devices */
+ struct bd71837_pmic *pmic; /**< client device regulator */
+ struct bd71837_power *power; /**< client device battery */
+
+ struct bd71837_board *of_plat_data;
+ /**< Device node parsed board data */
+};
+
+static inline int bd71837_chip_id(struct bd71837 *bd71837)
+{
+ return bd71837->id;
+}
+
+
+/**
+ * @brief bd71837_reg_read
+ * read single register's value of bd71837
+ * @param bd71837 device to read
+ * @param reg register address
+ * @return register value if success
+ * error number if fail
+ */
+static inline int bd71837_reg_read(struct bd71837 *bd71837, u8 reg)
+{
+ int r, val;
+
+ r = regmap_read(bd71837->regmap, reg, &val);
+ if (r < 0) {
+ return r;
+ }
+ return val;
+}
+
+/**
+ * @brief bd71837_reg_write
+ * write single register of bd71837
+ * @param bd71837 device to write
+ * @param reg register address
+ * @param val value to write
+ * @retval 0 if success
+ * @retval negative error number if fail
+ */
+
+static inline int bd71837_reg_write(struct bd71837 *bd71837, u8 reg,
+ unsigned int val)
+{
+ return regmap_write(bd71837->regmap, reg, val);
+}
+
+/**
+ * @brief bd71837_set_bits
+ * set bits in one register of bd71837
+ * @param bd71837 device to read
+ * @param reg register address
+ * @param mask mask bits
+ * @retval 0 if success
+ * @retval negative error number if fail
+ */
+static inline int bd71837_set_bits(struct bd71837 *bd71837, u8 reg, u8 mask)
+{
+ return regmap_update_bits(bd71837->regmap, reg, mask, mask);
+}
+
+/**
+ * @brief bd71837_clear_bits
+ * clear bits in one register of bd71837
+ * @param bd71837 device to read
+ * @param reg register address
+ * @param mask mask bits
+ * @retval 0 if success
+ * @retval negative error number if fail
+ */
+
+static inline int bd71837_clear_bits(struct bd71837 *bd71837, u8 reg,
+ u8 mask)
+{
+ return regmap_update_bits(bd71837->regmap, reg, mask, 0);
+}
+
+/**
+ * @brief bd71837_update_bits
+ * update bits in one register of bd71837
+ * @param bd71837 device to read
+ * @param reg register address
+ * @param mask mask bits
+ * @param val value to update
+ * @retval 0 if success
+ * @retval negative error number if fail
+ */
+
+static inline int bd71837_update_bits(struct bd71837 *bd71837, u8 reg,
+ u8 mask, u8 val)
+{
+ return regmap_update_bits(bd71837->regmap, reg, mask, val);
+}
+
+/**
+ * @brief bd71837 platform data type
+ */
+struct bd71837_gpo_plat_data {
+ u32 drv; ///< gpo output drv
+ int gpio_base; ///< base gpio number in system
+};
+
+u8 ext_bd71837_reg_read8(u8 reg);
+int ext_bd71837_reg_write8(int reg, u8 val);
+
+#define BD71837_DBG0 0x0001
+#define BD71837_DBG1 0x0002
+#define BD71837_DBG2 0x0004
+#define BD71837_DBG3 0x0008
+
+extern unsigned int bd71837_debug_mask;
+#define bd71837_debug(debug, fmt, arg...) do { if (debug & bd71837_debug_mask) printk("BD71837:" fmt, ##arg); } while (0)
+
+#endif /* __LINUX_MFD_BD71837_H */
diff --git a/include/linux/mfd/max17135.h b/include/linux/mfd/max17135.h
new file mode 100644
index 000000000000..e3b8777c8630
--- /dev/null
+++ b/include/linux/mfd/max17135.h
@@ -0,0 +1,220 @@
+/*
+ * Copyright (C) 2010-2015 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+#ifndef __LINUX_REGULATOR_MAX17135_H_
+#define __LINUX_REGULATOR_MAX17135_H_
+
+/*
+ * PMIC Register Addresses
+ */
+enum {
+ REG_MAX17135_EXT_TEMP = 0x0,
+ REG_MAX17135_CONFIG,
+ REG_MAX17135_INT_TEMP = 0x4,
+ REG_MAX17135_STATUS,
+ REG_MAX17135_PRODUCT_REV,
+ REG_MAX17135_PRODUCT_ID,
+ REG_MAX17135_DVR,
+ REG_MAX17135_ENABLE,
+ REG_MAX17135_FAULT, /*0x0A*/
+ REG_MAX17135_HVINP,
+ REG_MAX17135_PRGM_CTRL,
+ REG_MAX17135_TIMING1 = 0x10, /* Timing regs base address is 0x10 */
+ REG_MAX17135_TIMING2,
+ REG_MAX17135_TIMING3,
+ REG_MAX17135_TIMING4,
+ REG_MAX17135_TIMING5,
+ REG_MAX17135_TIMING6,
+ REG_MAX17135_TIMING7,
+ REG_MAX17135_TIMING8,
+};
+#define MAX17135_REG_NUM 21
+#define MAX17135_MAX_REGISTER 0xFF
+
+/*
+ * Bitfield macros that use rely on bitfield width/shift information.
+ */
+#define BITFMASK(field) (((1U << (field ## _WID)) - 1) << (field ## _LSH))
+#define BITFVAL(field, val) ((val) << (field ## _LSH))
+#define BITFEXT(var, bit) ((var & BITFMASK(bit)) >> (bit ## _LSH))
+
+/*
+ * Shift and width values for each register bitfield
+ */
+#define EXT_TEMP_LSH 7
+#define EXT_TEMP_WID 9
+
+#define THERMAL_SHUTDOWN_LSH 0
+#define THERMAL_SHUTDOWN_WID 1
+
+#define INT_TEMP_LSH 7
+#define INT_TEMP_WID 9
+
+#define STAT_BUSY_LSH 0
+#define STAT_BUSY_WID 1
+#define STAT_OPEN_LSH 1
+#define STAT_OPEN_WID 1
+#define STAT_SHRT_LSH 2
+#define STAT_SHRT_WID 1
+
+#define PROD_REV_LSH 0
+#define PROD_REV_WID 8
+
+#define PROD_ID_LSH 0
+#define PROD_ID_WID 8
+
+#define DVR_LSH 0
+#define DVR_WID 8
+
+#define ENABLE_LSH 0
+#define ENABLE_WID 1
+#define VCOM_ENABLE_LSH 1
+#define VCOM_ENABLE_WID 1
+
+#define FAULT_FBPG_LSH 0
+#define FAULT_FBPG_WID 1
+#define FAULT_HVINP_LSH 1
+#define FAULT_HVINP_WID 1
+#define FAULT_HVINN_LSH 2
+#define FAULT_HVINN_WID 1
+#define FAULT_FBNG_LSH 3
+#define FAULT_FBNG_WID 1
+#define FAULT_HVINPSC_LSH 4
+#define FAULT_HVINPSC_WID 1
+#define FAULT_HVINNSC_LSH 5
+#define FAULT_HVINNSC_WID 1
+#define FAULT_OT_LSH 6
+#define FAULT_OT_WID 1
+#define FAULT_POK_LSH 7
+#define FAULT_POK_WID 1
+
+#define HVINP_LSH 0
+#define HVINP_WID 4
+
+#define CTRL_DVR_LSH 0
+#define CTRL_DVR_WID 1
+#define CTRL_TIMING_LSH 1
+#define CTRL_TIMING_WID 1
+
+#define TIMING1_LSH 0
+#define TIMING1_WID 8
+#define TIMING2_LSH 0
+#define TIMING2_WID 8
+#define TIMING3_LSH 0
+#define TIMING3_WID 8
+#define TIMING4_LSH 0
+#define TIMING4_WID 8
+#define TIMING5_LSH 0
+#define TIMING5_WID 8
+#define TIMING6_LSH 0
+#define TIMING6_WID 8
+#define TIMING7_LSH 0
+#define TIMING7_WID 8
+#define TIMING8_LSH 0
+#define TIMING8_WID 8
+
+struct max17135 {
+ /* chip revision */
+ int rev;
+
+ struct device *dev;
+ struct max17135_platform_data *pdata;
+
+ /* Platform connection */
+ struct i2c_client *i2c_client;
+
+ /* Timings */
+ unsigned int gvee_pwrup;
+ unsigned int vneg_pwrup;
+ unsigned int vpos_pwrup;
+ unsigned int gvdd_pwrup;
+ unsigned int gvdd_pwrdn;
+ unsigned int vpos_pwrdn;
+ unsigned int vneg_pwrdn;
+ unsigned int gvee_pwrdn;
+
+ /* GPIOs */
+ int gpio_pmic_pwrgood;
+ int gpio_pmic_vcom_ctrl;
+ int gpio_pmic_wakeup;
+ int gpio_pmic_v3p3;
+ int gpio_pmic_intr;
+
+ /* MAX17135 part variables */
+ int pass_num;
+ int vcom_uV;
+
+ /* One-time VCOM setup marker */
+ bool vcom_setup;
+
+ /* powerup/powerdown wait time */
+ int max_wait;
+};
+
+enum {
+ /* In alphabetical order */
+ MAX17135_DISPLAY, /* virtual master enable */
+ MAX17135_GVDD,
+ MAX17135_GVEE,
+ MAX17135_HVINN,
+ MAX17135_HVINP,
+ MAX17135_VCOM,
+ MAX17135_VNEG,
+ MAX17135_VPOS,
+ MAX17135_V3P3,
+ MAX17135_NUM_REGULATORS,
+};
+
+/*
+ * Declarations
+ */
+struct regulator_init_data;
+struct max17135_regulator_data;
+
+struct max17135_platform_data {
+ unsigned int gvee_pwrup;
+ unsigned int vneg_pwrup;
+ unsigned int vpos_pwrup;
+ unsigned int gvdd_pwrup;
+ unsigned int gvdd_pwrdn;
+ unsigned int vpos_pwrdn;
+ unsigned int vneg_pwrdn;
+ unsigned int gvee_pwrdn;
+ int gpio_pmic_pwrgood;
+ int gpio_pmic_vcom_ctrl;
+ int gpio_pmic_wakeup;
+ int gpio_pmic_v3p3;
+ int gpio_pmic_intr;
+ int pass_num;
+ int vcom_uV;
+
+ /* PMIC */
+ struct max17135_regulator_data *regulators;
+ int num_regulators;
+};
+
+struct max17135_regulator_data {
+ int id;
+ struct regulator_init_data *initdata;
+ struct device_node *reg_node;
+};
+
+int max17135_reg_read(int reg_num, unsigned int *reg_val);
+int max17135_reg_write(int reg_num, const unsigned int reg_val);
+
+#endif
diff --git a/include/linux/mfd/mxc-hdmi-core.h b/include/linux/mfd/mxc-hdmi-core.h
new file mode 100644
index 000000000000..b2696b951f43
--- /dev/null
+++ b/include/linux/mfd/mxc-hdmi-core.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2011-2015 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+#ifndef __LINUX_MXC_HDMI_CORE_H_
+#define __LINUX_MXC_HDMI_CORE_H_
+
+#include <video/mxc_edid.h>
+
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+
+#define IRQ_DISABLE_SUCCEED 0
+#define IRQ_DISABLE_FAIL 1
+
+bool hdmi_check_overflow(void);
+
+u8 hdmi_readb(unsigned int reg);
+void hdmi_writeb(u8 value, unsigned int reg);
+void hdmi_mask_writeb(u8 data, unsigned int addr, u8 shift, u8 mask);
+unsigned int hdmi_read4(unsigned int reg);
+void hdmi_write4(unsigned int value, unsigned int reg);
+
+void hdmi_irq_init(void);
+void hdmi_irq_enable(int irq);
+unsigned int hdmi_irq_disable(int irq);
+
+void hdmi_set_sample_rate(unsigned int rate);
+void hdmi_set_dma_mode(unsigned int dma_running);
+void hdmi_init_clk_regenerator(void);
+void hdmi_clk_regenerator_update_pixel_clock(u32 pixclock);
+
+void hdmi_set_edid_cfg(struct mxc_edid_cfg *cfg);
+void hdmi_get_edid_cfg(struct mxc_edid_cfg *cfg);
+
+extern int mxc_hdmi_ipu_id;
+extern int mxc_hdmi_disp_id;
+
+void hdmi_set_registered(int registered);
+int hdmi_get_registered(void);
+int mxc_hdmi_abort_stream(void);
+int mxc_hdmi_register_audio(struct snd_pcm_substream *substream);
+void mxc_hdmi_unregister_audio(struct snd_pcm_substream *substream);
+unsigned int hdmi_set_cable_state(unsigned int state);
+unsigned int hdmi_set_blank_state(unsigned int state);
+int check_hdmi_state(void);
+
+#endif
diff --git a/include/linux/mfd/pf1550.h b/include/linux/mfd/pf1550.h
new file mode 100644
index 000000000000..7d0a13e1144a
--- /dev/null
+++ b/include/linux/mfd/pf1550.h
@@ -0,0 +1,250 @@
+/*
+ * pf1550.h - mfd head file for PF1550
+ *
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Robin Gong <yibin.gong@freescale.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.
+ */
+
+#ifndef __LINUX_MFD_PF1550_H
+#define __LINUX_MFD_PF1550_H
+
+#include <linux/i2c.h>
+
+enum chips { PF1550 = 1, };
+
+enum pf1550_pmic_reg {
+ /* PMIC regulator part */
+ PF1550_PMIC_REG_DEVICE_ID = 0x00,
+ PF1550_PMIC_REG_OTP_FLAVOR = 0x01,
+ PF1550_PMIC_REG_SILICON_REV = 0x02,
+
+ PF1550_PMIC_REG_INT_CATEGORY = 0x06,
+ PF1550_PMIC_REG_SW_INT_STAT0 = 0x08,
+ PF1550_PMIC_REG_SW_INT_MASK0 = 0x09,
+ PF1550_PMIC_REG_SW_INT_SENSE0 = 0x0A,
+ PF1550_PMIC_REG_SW_INT_STAT1 = 0x0B,
+ PF1550_PMIC_REG_SW_INT_MASK1 = 0x0C,
+ PF1550_PMIC_REG_SW_INT_SENSE1 = 0x0D,
+ PF1550_PMIC_REG_SW_INT_STAT2 = 0x0E,
+ PF1550_PMIC_REG_SW_INT_MASK2 = 0x0F,
+ PF1550_PMIC_REG_SW_INT_SENSE2 = 0x10,
+ PF1550_PMIC_REG_LDO_INT_STAT0 = 0x18,
+ PF1550_PMIC_REG_LDO_INT_MASK0 = 0x19,
+ PF1550_PMIC_REG_LDO_INT_SENSE0 = 0x1A,
+ PF1550_PMIC_REG_TEMP_INT_STAT0 = 0x20,
+ PF1550_PMIC_REG_TEMP_INT_MASK0 = 0x21,
+ PF1550_PMIC_REG_TEMP_INT_SENSE0 = 0x22,
+ PF1550_PMIC_REG_ONKEY_INT_STAT0 = 0x24,
+ PF1550_PMIC_REG_ONKEY_INT_MASK0 = 0x25,
+ PF1550_PMIC_REG_ONKEY_INT_SENSE0 = 0x26,
+ PF1550_PMIC_REG_MISC_INT_STAT0 = 0x28,
+ PF1550_PMIC_REG_MISC_INT_MASK0 = 0x29,
+ PF1550_PMIC_REG_MISC_INT_SENSE0 = 0x2A,
+
+ PF1550_PMIC_REG_COINCELL_CONTROL = 0x30,
+
+ PF1550_PMIC_REG_SW1_VOLT = 0x32,
+ PF1550_PMIC_REG_SW1_STBY_VOLT = 0x33,
+ PF1550_PMIC_REG_SW1_SLP_VOLT = 0x34,
+ PF1550_PMIC_REG_SW1_CTRL = 0x35,
+ PF1550_PMIC_REG_SW1_CTRL1 = 0x36,
+ PF1550_PMIC_REG_SW2_VOLT = 0x38,
+ PF1550_PMIC_REG_SW2_STBY_VOLT = 0x39,
+ PF1550_PMIC_REG_SW2_SLP_VOLT = 0x3A,
+ PF1550_PMIC_REG_SW2_CTRL = 0x3B,
+ PF1550_PMIC_REG_SW2_CTRL1 = 0x3C,
+ PF1550_PMIC_REG_SW3_VOLT = 0x3E,
+ PF1550_PMIC_REG_SW3_STBY_VOLT = 0x3F,
+ PF1550_PMIC_REG_SW3_SLP_VOLT = 0x40,
+ PF1550_PMIC_REG_SW3_CTRL = 0x41,
+ PF1550_PMIC_REG_SW3_CTRL1 = 0x42,
+ PF1550_PMIC_REG_VSNVS_CTRL = 0x48,
+ PF1550_PMIC_REG_VREFDDR_CTRL = 0x4A,
+ PF1550_PMIC_REG_LDO1_VOLT = 0x4C,
+ PF1550_PMIC_REG_LDO1_CTRL = 0x4D,
+ PF1550_PMIC_REG_LDO2_VOLT = 0x4F,
+ PF1550_PMIC_REG_LDO2_CTRL = 0x50,
+ PF1550_PMIC_REG_LDO3_VOLT = 0x52,
+ PF1550_PMIC_REG_LDO3_CTRL = 0x53,
+ PF1550_PMIC_REG_PWRCTRL0 = 0x58,
+ PF1550_PMIC_REG_PWRCTRL1 = 0x59,
+ PF1550_PMIC_REG_PWRCTRL2 = 0x5A,
+ PF1550_PMIC_REG_PWRCTRL3 = 0x5B,
+ PF1550_PMIC_REG_SW1_PWRDN_SEQ = 0x5F,
+ PF1550_PMIC_REG_SW2_PWRDN_SEQ = 0x60,
+ PF1550_PMIC_REG_SW3_PWRDN_SEQ = 0x61,
+ PF1550_PMIC_REG_LDO1_PWRDN_SEQ = 0x62,
+ PF1550_PMIC_REG_LDO2_PWRDN_SEQ = 0x63,
+ PF1550_PMIC_REG_LDO3_PWRDN_SEQ = 0x64,
+ PF1550_PMIC_REG_VREFDDR_PWRDN_SEQ = 0x65,
+
+ PF1550_PMIC_REG_STATE_INFO = 0x67,
+ PF1550_PMIC_REG_I2C_ADDR = 0x68,
+ PF1550_PMIC_REG_IO_DRV0 = 0x69,
+ PF1550_PMIC_REG_IO_DRV1 = 0x6A,
+ PF1550_PMIC_REG_RC_16MHZ = 0x6B,
+ PF1550_PMIC_REG_KEY = 0x6F,
+
+ /* charger part */
+ PF1550_CHARG_REG_CHG_INT = 0x80,
+ PF1550_CHARG_REG_CHG_INT_MASK = 0x82,
+ PF1550_CHARG_REG_CHG_INT_OK = 0x84,
+ PF1550_CHARG_REG_VBUS_SNS = 0x86,
+ PF1550_CHARG_REG_CHG_SNS = 0x87,
+ PF1550_CHARG_REG_BATT_SNS = 0x88,
+ PF1550_CHARG_REG_CHG_OPER = 0x89,
+ PF1550_CHARG_REG_CHG_TMR = 0x8A,
+ PF1550_CHARG_REG_CHG_EOC_CNFG = 0x8D,
+ PF1550_CHARG_REG_CHG_CURR_CNFG = 0x8E,
+ PF1550_CHARG_REG_BATT_REG = 0x8F,
+ PF1550_CHARG_REG_BATFET_CNFG = 0x91,
+ PF1550_CHARG_REG_THM_REG_CNFG = 0x92,
+ PF1550_CHARG_REG_VBUS_INLIM_CNFG = 0x94,
+ PF1550_CHARG_REG_VBUS_LIN_DPM = 0x95,
+ PF1550_CHARG_REG_USB_PHY_LDO_CNFG = 0x96,
+ PF1550_CHARG_REG_DBNC_DELAY_TIME = 0x98,
+ PF1550_CHARG_REG_CHG_INT_CNFG = 0x99,
+ PF1550_CHARG_REG_THM_ADJ_SETTING = 0x9A,
+ PF1550_CHARG_REG_VBUS2SYS_CNFG = 0x9B,
+ PF1550_CHARG_REG_LED_PWM = 0x9C,
+ PF1550_CHARG_REG_FAULT_BATFET_CNFG = 0x9D,
+ PF1550_CHARG_REG_LED_CNFG = 0x9E,
+ PF1550_CHARG_REG_CHGR_KEY2 = 0x9F,
+
+ PF1550_TEST_REG_FMRADDR = 0xC4,
+ PF1550_TEST_REG_FMRDATA = 0xC5,
+ PF1550_TEST_REG_KEY3 = 0xDF,
+
+ PF1550_PMIC_REG_END = 0xff,
+};
+
+#define PF1550_CHG_PRECHARGE 0
+#define PF1550_CHG_CONSTANT_CURRENT 1
+#define PF1550_CHG_CONSTANT_VOL 2
+#define PF1550_CHG_EOC 3
+#define PF1550_CHG_DONE 4
+#define PF1550_CHG_TIMER_FAULT 6
+#define PF1550_CHG_SUSPEND 7
+#define PF1550_CHG_OFF_INV 8
+#define PF1550_CHG_BAT_OVER 9
+#define PF1550_CHG_OFF_TEMP 10
+#define PF1550_CHG_LINEAR_ONLY 12
+#define PF1550_CHG_SNS_MASK 0xf
+
+#define PF1550_BAT_NO_VBUS 0
+#define PF1550_BAT_LOW_THAN_PRECHARG 1
+#define PF1550_BAT_CHARG_FAIL 2
+#define PF1550_BAT_HIGH_THAN_PRECHARG 4
+#define PF1550_BAT_OVER_VOL 5
+#define PF1550_BAT_NO_DETECT 6
+#define PF1550_BAT_SNS_MASK 0x7
+
+#define PF1550_VBUS_UVLO BIT(2)
+#define PF1550_VBUS_IN2SYS BIT(3)
+#define PF1550_VBUS_OVLO BIT(4)
+#define PF1550_VBUS_VALID BIT(5)
+
+#define PF1550_CHARG_REG_BATT_REG_CHGCV_MASK 0x3f
+#define PF1550_CHARG_REG_BATT_REG_VMINSYS_SHIFT 6
+#define PF1550_CHARG_REG_BATT_REG_VMINSYS_MASK (0x3 << 6)
+#define PF1550_CHARG_REG_THM_REG_CNFG_REGTEMP_SHIFT 2
+#define PF1550_CHARG_REG_THM_REG_CNFG_REGTEMP_MASK (0x3 << 2)
+
+#define PMIC_IRQ_SW1_LS BIT(0)
+#define PMIC_IRQ_SW2_LS BIT(1)
+#define PMIC_IRQ_SW3_LS BIT(2)
+#define PMIC_IRQ_SW1_HS BIT(0)
+#define PMIC_IRQ_SW2_HS BIT(1)
+#define PMIC_IRQ_SW3_HS BIT(2)
+#define PMIC_IRQ_LDO1_FAULT BIT(0)
+#define PMIC_IRQ_LDO2_FAULT BIT(1)
+#define PMIC_IRQ_LDO3_FAULT BIT(2)
+#define PMIC_IRQ_TEMP_110 BIT(0)
+#define PMIC_IRQ_TEMP_125 BIT(1)
+
+#define ONKEY_IRQ_PUSHI BIT(0)
+#define ONKEY_IRQ_1SI BIT(1)
+#define ONKEY_IRQ_2SI BIT(2)
+#define ONKEY_IRQ_3SI BIT(3)
+#define ONKEY_IRQ_4SI BIT(4)
+#define ONKEY_IRQ_8SI BIT(5)
+
+#define CHARG_IRQ_BAT2SOCI BIT(1)
+#define CHARG_IRQ_BATI BIT(2)
+#define CHARG_IRQ_CHGI BIT(3)
+#define CHARG_IRQ_VBUSI BIT(5)
+#define CHARG_IRQ_DPMI BIT(6)
+#define CHARG_IRQ_THMI BIT(7)
+
+enum pf1550_pmic_irq {
+ PF1550_PMIC_IRQ_SW1_LS,
+ PF1550_PMIC_IRQ_SW2_LS,
+ PF1550_PMIC_IRQ_SW3_LS,
+ PF1550_PMIC_IRQ_SW1_HS,
+ PF1550_PMIC_IRQ_SW2_HS,
+ PF1550_PMIC_IRQ_SW3_HS,
+ PF1550_PMIC_IRQ_LDO1_FAULT,
+ PF1550_PMIC_IRQ_LDO2_FAULT,
+ PF1550_PMIC_IRQ_LDO3_FAULT,
+ PF1550_PMIC_IRQ_TEMP_110,
+ PF1550_PMIC_IRQ_TEMP_125,
+};
+
+enum pf1550_onkey_irq {
+ PF1550_ONKEY_IRQ_PUSHI,
+ PF1550_ONKEY_IRQ_1SI,
+ PF1550_ONKEY_IRQ_2SI,
+ PF1550_ONKEY_IRQ_3SI,
+ PF1550_ONKEY_IRQ_4SI,
+ PF1550_ONKEY_IRQ_8SI,
+};
+
+enum pf1550_charg_irq {
+ PF1550_CHARG_IRQ_BAT2SOCI,
+ PF1550_CHARG_IRQ_BATI,
+ PF1550_CHARG_IRQ_CHGI,
+ PF1550_CHARG_IRQ_VBUSI,
+ PF1550_CHARG_IRQ_THMI,
+};
+
+enum pf1550_regulators {
+ PF1550_SW1,
+ PF1550_SW2,
+ PF1550_SW3,
+ PF1550_VREFDDR,
+ PF1550_LDO1,
+ PF1550_LDO2,
+ PF1550_LDO3,
+};
+
+struct pf1550_irq_info {
+ unsigned int irq;
+ const char *name;
+ unsigned int virq;
+};
+
+struct pf1550_dev {
+ struct device *dev;
+ struct i2c_client *i2c;
+ int type;
+ struct regmap *regmap;
+ struct regmap_irq_chip_data *irq_data_regulator;
+ struct regmap_irq_chip_data *irq_data_onkey;
+ struct regmap_irq_chip_data *irq_data_charger;
+ int irq;
+};
+
+int pf1550_read_otp(struct pf1550_dev *pf1550, unsigned int index,
+ unsigned int *val);
+
+#endif /* __LINUX_MFD_PF1550_H */
diff --git a/include/linux/mfd/si476x-core.h b/include/linux/mfd/si476x-core.h
index 674b45d5a757..78a2b2c936f3 100644
--- a/include/linux/mfd/si476x-core.h
+++ b/include/linux/mfd/si476x-core.h
@@ -493,6 +493,8 @@ enum si476x_common_receiver_properties {
SI476X_PROP_DIGITAL_IO_OUTPUT_SAMPLE_RATE = 0x0202,
SI476X_PROP_DIGITAL_IO_OUTPUT_FORMAT = 0x0203,
+ SI476X_PROP_AUDIO_MUTE = 0x0301,
+
SI476X_PROP_SEEK_BAND_BOTTOM = 0x1100,
SI476X_PROP_SEEK_BAND_TOP = 0x1101,
SI476X_PROP_SEEK_FREQUENCY_SPACING = 0x1102,
diff --git a/include/linux/mfd/syscon/imx6q-iomuxc-gpr.h b/include/linux/mfd/syscon/imx6q-iomuxc-gpr.h
index c8e0164c5423..29f225235782 100644
--- a/include/linux/mfd/syscon/imx6q-iomuxc-gpr.h
+++ b/include/linux/mfd/syscon/imx6q-iomuxc-gpr.h
@@ -101,6 +101,7 @@
#define IMX6Q_GPR1_PCIE_ENTER_L1 BIT(26)
#define IMX6Q_GPR1_MIPI_COLOR_SW BIT(25)
#define IMX6Q_GPR1_DPI_OFF BIT(24)
+#define IMX6Q_GPR1_PCIE_SW_PERST BIT(23)
#define IMX6Q_GPR1_EXC_MON_MASK BIT(22)
#define IMX6Q_GPR1_EXC_MON_OKAY 0x0
#define IMX6Q_GPR1_EXC_MON_SLVE BIT(22)
@@ -243,6 +244,23 @@
#define IMX6Q_GPR4_IPU_RD_CACHE_CTL BIT(0)
#define IMX6Q_GPR5_L2_CLK_STOP BIT(8)
+#define IMX6Q_GPR5_ENET_TX_CLK_SEL BIT(9)
+#define IMX6Q_GPR5_PRE_PRG_SEL0_MASK (0x3 << 12)
+#define IMX6Q_GPR5_PRE_PRG_SEL0_SHIFT 12
+#define IMX6Q_GPR5_PRE_PRG_SEL0_MSB 13
+#define IMX6Q_GPR5_PRE_PRG_SEL0_LSB 12
+#define IMX6Q_GPR5_PRE_PRG_SEL0_PRE1_PRG0_CHAN1 (0x0 << 12)
+#define IMX6Q_GPR5_PRE_PRG_SEL0_PRE1_PRG0_CHAN2 (0x1 << 12)
+#define IMX6Q_GPR5_PRE_PRG_SEL0_PRE1_PRG1_CHAN1 (0x2 << 12)
+#define IMX6Q_GPR5_PRE_PRG_SEL0_PRE1_PRG1_CHAN2 (0x3 << 12)
+#define IMX6Q_GPR5_PRE_PRG_SEL1_MASK (0x3 << 14)
+#define IMX6Q_GPR5_PRE_PRG_SEL1_SHIFT 14
+#define IMX6Q_GPR5_PRE_PRG_SEL1_MSB 15
+#define IMX6Q_GPR5_PRE_PRG_SEL1_LSB 14
+#define IMX6Q_GPR5_PRE_PRG_SEL1_PRE2_PRG0_CHAN1 (0x0 << 14)
+#define IMX6Q_GPR5_PRE_PRG_SEL1_PRE2_PRG0_CHAN2 (0x1 << 14)
+#define IMX6Q_GPR5_PRE_PRG_SEL1_PRE2_PRG1_CHAN1 (0x2 << 14)
+#define IMX6Q_GPR5_PRE_PRG_SEL1_PRE2_PRG1_CHAN2 (0x3 << 14)
#define IMX6Q_GPR6_IPU1_ID00_WR_QOS_MASK (0xf << 0)
#define IMX6Q_GPR6_IPU1_ID01_WR_QOS_MASK (0xf << 4)
@@ -286,23 +304,25 @@
#define IMX6Q_GPR10_OCRAM_TZ_ADDR_MASK (0x3f << 5)
#define IMX6Q_GPR10_OCRAM_TZ_EN_MASK BIT(4)
#define IMX6Q_GPR10_DCIC2_MUX_CTL_MASK (0x3 << 2)
-#define IMX6Q_GPR10_DCIC2_MUX_CTL_IPU1_DI0 (0x0 << 2)
-#define IMX6Q_GPR10_DCIC2_MUX_CTL_IPU1_DI1 (0x1 << 2)
-#define IMX6Q_GPR10_DCIC2_MUX_CTL_IPU2_DI0 (0x2 << 2)
-#define IMX6Q_GPR10_DCIC2_MUX_CTL_IPU2_DI1 (0x3 << 2)
+#define IMX6Q_GPR10_DCIC2_MUX_CTL_IPU1_DI1 (0x0 << 2)
+#define IMX6Q_GPR10_DCIC2_MUX_CTL_LVDS0 (0x1 << 2)
+#define IMX6Q_GPR10_DCIC2_MUX_CTL_LVDS1 (0x2 << 2)
+#define IMX6Q_GPR10_DCIC2_MUX_CTL_MIPI (0x3 << 2)
#define IMX6Q_GPR10_DCIC1_MUX_CTL_MASK (0x3 << 0)
#define IMX6Q_GPR10_DCIC1_MUX_CTL_IPU1_DI0 (0x0 << 0)
-#define IMX6Q_GPR10_DCIC1_MUX_CTL_IPU1_DI1 (0x1 << 0)
-#define IMX6Q_GPR10_DCIC1_MUX_CTL_IPU2_DI0 (0x2 << 0)
-#define IMX6Q_GPR10_DCIC1_MUX_CTL_IPU2_DI1 (0x3 << 0)
+#define IMX6Q_GPR10_DCIC1_MUX_CTL_LVDS0 (0x1 << 0)
+#define IMX6Q_GPR10_DCIC1_MUX_CTL_LVDS1 (0x2 << 0)
+#define IMX6Q_GPR10_DCIC1_MUX_CTL_HDMI (0x3 << 0)
#define IMX6Q_GPR12_ARMP_IPG_CLK_EN BIT(27)
#define IMX6Q_GPR12_ARMP_AHB_CLK_EN BIT(26)
#define IMX6Q_GPR12_ARMP_ATB_CLK_EN BIT(25)
#define IMX6Q_GPR12_ARMP_APB_CLK_EN BIT(24)
+#define IMX6Q_GPR12_PCIE_PM_TURN_OFF BIT(16)
#define IMX6Q_GPR12_DEVICE_TYPE (0xf << 12)
#define IMX6Q_GPR12_PCIE_CTL_2 BIT(10)
#define IMX6Q_GPR12_LOS_LEVEL (0x1f << 4)
+#define IMX6Q_GPR12_LOS_LEVEL_9 (0x9 << 4)
#define IMX6Q_GPR13_SDMA_STOP_REQ BIT(30)
#define IMX6Q_GPR13_CAN2_STOP_REQ BIT(29)
@@ -411,6 +431,15 @@
#define IMX6SX_GPR4_FEC_ENET1_STOP_REQ (0x1 << 3)
#define IMX6SX_GPR4_FEC_ENET2_STOP_REQ (0x1 << 4)
+#define IMX6SX_GPR2_MQS_OVERSAMPLE_MASK (0x1 << 26)
+#define IMX6SX_GPR2_MQS_OVERSAMPLE_SHIFT (26)
+#define IMX6SX_GPR2_MQS_EN_MASK (0x1 << 25)
+#define IMX6SX_GPR2_MQS_EN_SHIFT (25)
+#define IMX6SX_GPR2_MQS_SW_RST_MASK (0x1 << 24)
+#define IMX6SX_GPR2_MQS_SW_RST_SHIFT (24)
+#define IMX6SX_GPR2_MQS_CLK_DIV_MASK (0xFF << 16)
+#define IMX6SX_GPR2_MQS_CLK_DIV_SHIFT (16)
+
#define IMX6SX_GPR5_DISP_MUX_LDB_CTRL_MASK (0x1 << 3)
#define IMX6SX_GPR5_DISP_MUX_LDB_CTRL_LCDIF1 (0x0 << 3)
#define IMX6SX_GPR5_DISP_MUX_LDB_CTRL_LCDIF2 (0x1 << 3)
@@ -423,6 +452,7 @@
#define IMX6SX_GPR5_VADC_TO_CSI_CAPTURE_EN_MASK (0x1 << 26)
#define IMX6SX_GPR5_VADC_TO_CSI_CAPTURE_EN_ENABLE (0x1 << 26)
#define IMX6SX_GPR5_VADC_TO_CSI_CAPTURE_EN_DISABLE (0x0 << 26)
+#define IMX6SX_GPR5_PCIE_PERST BIT(18)
#define IMX6SX_GPR5_PCIE_BTNRST_RESET BIT(19)
#define IMX6SX_GPR5_CSI1_MUX_CTRL_MASK (0x3 << 4)
#define IMX6SX_GPR5_CSI1_MUX_CTRL_EXT_PIN (0x0 << 4)
@@ -437,10 +467,21 @@
#define IMX6SX_GPR5_DISP_MUX_DCIC1_LVDS (0x1 << 1)
#define IMX6SX_GPR5_DISP_MUX_DCIC1_MASK (0x1 << 1)
+#define IMX6SX_GPR12_PCIE_PM_TURN_OFF BIT(16)
#define IMX6SX_GPR12_PCIE_TEST_POWERDOWN BIT(30)
#define IMX6SX_GPR12_PCIE_RX_EQ_MASK (0x7 << 0)
#define IMX6SX_GPR12_PCIE_RX_EQ_2 (0x2 << 0)
+/* For imx6dl iomux gpr register field definitions */
+#define IMX6DL_GPR3_LVDS1_MUX_CTL_MASK (0x3 << 8)
+#define IMX6DL_GPR3_LVDS1_MUX_CTL_IPU1_DI0 (0x0 << 8)
+#define IMX6DL_GPR3_LVDS1_MUX_CTL_IPU1_DI1 (0x1 << 8)
+#define IMX6DL_GPR3_LVDS1_MUX_CTL_LCDIF (0x2 << 8)
+#define IMX6DL_GPR3_LVDS0_MUX_CTL_MASK (0x3 << 6)
+#define IMX6DL_GPR3_LVDS0_MUX_CTL_IPU1_DI0 (0x0 << 6)
+#define IMX6DL_GPR3_LVDS0_MUX_CTL_IPU1_DI1 (0x1 << 6)
+#define IMX6DL_GPR3_LVDS0_MUX_CTL_LCDIF (0x2 << 6)
+
/* For imx6ul iomux gpr register field define */
#define IMX6UL_GPR1_ENET1_CLK_DIR (0x1 << 17)
#define IMX6UL_GPR1_ENET2_CLK_DIR (0x1 << 18)
diff --git a/include/linux/mfd/syscon/imx7-iomuxc-gpr.h b/include/linux/mfd/syscon/imx7-iomuxc-gpr.h
index abbd52466573..af33fcb13339 100644
--- a/include/linux/mfd/syscon/imx7-iomuxc-gpr.h
+++ b/include/linux/mfd/syscon/imx7-iomuxc-gpr.h
@@ -34,6 +34,8 @@
#define IOMUXC_GPR22 0x58
/* For imx7d iomux gpr register field define */
+#define IMX7D_GPR0_ENET_MDIO_OPEN_DRAIN_MASK (0x3 << 7)
+
#define IMX7D_GPR1_IRQ_MASK (0x1 << 12)
#define IMX7D_GPR1_ENET1_TX_CLK_SEL_MASK (0x1 << 13)
#define IMX7D_GPR1_ENET2_TX_CLK_SEL_MASK (0x1 << 14)
diff --git a/include/linux/mfd/syscon/imx8mq-iomuxc-gpr.h b/include/linux/mfd/syscon/imx8mq-iomuxc-gpr.h
new file mode 100644
index 000000000000..cfb857774cf5
--- /dev/null
+++ b/include/linux/mfd/syscon/imx8mq-iomuxc-gpr.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2017 NXP
+ *
+ * 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_IMX8MQ_IOMUXC_GPR_H
+#define __LINUX_IMX8MQ_IOMUXC_GPR_H
+
+#define IOMUXC_GPR0 0x00
+#define IOMUXC_GPR1 0x04
+#define IOMUXC_GPR2 0x08
+#define IOMUXC_GPR3 0x0c
+#define IOMUXC_GPR4 0x10
+#define IOMUXC_GPR5 0x14
+#define IOMUXC_GPR6 0x18
+#define IOMUXC_GPR7 0x1c
+#define IOMUXC_GPR8 0x20
+#define IOMUXC_GPR9 0x24
+#define IOMUXC_GPR10 0x28
+#define IOMUXC_GPR11 0x2c
+#define IOMUXC_GPR12 0x30
+#define IOMUXC_GPR13 0x34
+#define IOMUXC_GPR14 0x38
+#define IOMUXC_GPR15 0x3c
+#define IOMUXC_GPR16 0x40
+#define IOMUXC_GPR17 0x44
+#define IOMUXC_GPR18 0x48
+#define IOMUXC_GPR19 0x4c
+#define IOMUXC_GPR20 0x50
+#define IOMUXC_GPR21 0x54
+#define IOMUXC_GPR22 0x58
+#define IOMUXC_GPR23 0x5c
+#define IOMUXC_GPR24 0x60
+#define IOMUXC_GPR25 0x64
+#define IOMUXC_GPR26 0x68
+#define IOMUXC_GPR27 0x6c
+#define IOMUXC_GPR28 0x70
+#define IOMUXC_GPR29 0x74
+#define IOMUXC_GPR30 0x78
+#define IOMUXC_GPR31 0x7c
+#define IOMUXC_GPR32 0x80
+#define IOMUXC_GPR33 0x84
+#define IOMUXC_GPR34 0x88
+#define IOMUXC_GPR35 0x8c
+#define IOMUXC_GPR36 0x90
+#define IOMUXC_GPR37 0x94
+#define IOMUXC_GPR38 0x98
+#define IOMUXC_GPR39 0x9c
+#define IOMUXC_GPR40 0xa0
+#define IOMUXC_GPR41 0xa4
+#define IOMUXC_GPR42 0xa8
+#define IOMUXC_GPR43 0xac
+#define IOMUXC_GPR44 0xb0
+#define IOMUXC_GPR45 0xb4
+#define IOMUXC_GPR46 0xb8
+#define IOMUXC_GPR47 0xbc
+
+#define IMX8MQ_GPR13_MIPI_MUX_SEL BIT(2)
+
+#endif /* __LINUX_IMX8MQ_IOMUXC_GPR_H */
diff --git a/include/linux/mipi_csi2.h b/include/linux/mipi_csi2.h
new file mode 100644
index 000000000000..7dc76fd293f8
--- /dev/null
+++ b/include/linux/mipi_csi2.h
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2011-2013 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __INCLUDE_MIPI_CSI2_H
+#define __INCLUDE_MIPI_CSI2_H
+
+/* MIPI CSI2 registers */
+#define MIPI_CSI2_REG(offset) (offset)
+
+#define MIPI_CSI2_VERSION MIPI_CSI2_REG(0x000)
+#define MIPI_CSI2_N_LANES MIPI_CSI2_REG(0x004)
+#define MIPI_CSI2_PHY_SHUTDOWNZ MIPI_CSI2_REG(0x008)
+#define MIPI_CSI2_DPHY_RSTZ MIPI_CSI2_REG(0x00c)
+#define MIPI_CSI2_CSI2_RESETN MIPI_CSI2_REG(0x010)
+#define MIPI_CSI2_PHY_STATE MIPI_CSI2_REG(0x014)
+#define MIPI_CSI2_DATA_IDS_1 MIPI_CSI2_REG(0x018)
+#define MIPI_CSI2_DATA_IDS_2 MIPI_CSI2_REG(0x01c)
+#define MIPI_CSI2_ERR1 MIPI_CSI2_REG(0x020)
+#define MIPI_CSI2_ERR2 MIPI_CSI2_REG(0x024)
+#define MIPI_CSI2_MASK1 MIPI_CSI2_REG(0x028)
+#define MIPI_CSI2_MASK2 MIPI_CSI2_REG(0x02c)
+#define MIPI_CSI2_PHY_TST_CTRL0 MIPI_CSI2_REG(0x030)
+#define MIPI_CSI2_PHY_TST_CTRL1 MIPI_CSI2_REG(0x034)
+#define MIPI_CSI2_SFT_RESET MIPI_CSI2_REG(0xf00)
+
+/* mipi data type */
+#define MIPI_DT_YUV420 0x18 /* YYY.../UYVY.... */
+#define MIPI_DT_YUV420_LEGACY 0x1a /* UYY.../VYY... */
+#define MIPI_DT_YUV422 0x1e /* UYVY... */
+#define MIPI_DT_RGB444 0x20
+#define MIPI_DT_RGB555 0x21
+#define MIPI_DT_RGB565 0x22
+#define MIPI_DT_RGB666 0x23
+#define MIPI_DT_RGB888 0x24
+#define MIPI_DT_RAW6 0x28
+#define MIPI_DT_RAW7 0x29
+#define MIPI_DT_RAW8 0x2a
+#define MIPI_DT_RAW10 0x2b
+#define MIPI_DT_RAW12 0x2c
+#define MIPI_DT_RAW14 0x2d
+
+
+struct mipi_csi2_info;
+/* mipi csi2 API */
+struct mipi_csi2_info *mipi_csi2_get_info(void);
+
+bool mipi_csi2_enable(struct mipi_csi2_info *info);
+
+bool mipi_csi2_disable(struct mipi_csi2_info *info);
+
+bool mipi_csi2_get_status(struct mipi_csi2_info *info);
+
+int mipi_csi2_get_bind_ipu(struct mipi_csi2_info *info);
+
+unsigned int mipi_csi2_get_bind_csi(struct mipi_csi2_info *info);
+
+unsigned int mipi_csi2_get_virtual_channel(struct mipi_csi2_info *info);
+
+unsigned int mipi_csi2_set_lanes(struct mipi_csi2_info *info);
+
+unsigned int mipi_csi2_set_datatype(struct mipi_csi2_info *info,
+ unsigned int datatype);
+
+unsigned int mipi_csi2_get_datatype(struct mipi_csi2_info *info);
+
+unsigned int mipi_csi2_dphy_status(struct mipi_csi2_info *info);
+
+unsigned int mipi_csi2_get_error1(struct mipi_csi2_info *info);
+
+unsigned int mipi_csi2_get_error2(struct mipi_csi2_info *info);
+
+int mipi_csi2_pixelclk_enable(struct mipi_csi2_info *info);
+
+void mipi_csi2_pixelclk_disable(struct mipi_csi2_info *info);
+
+int mipi_csi2_reset(struct mipi_csi2_info *info);
+
+#endif
diff --git a/include/linux/mipi_dsi.h b/include/linux/mipi_dsi.h
new file mode 100644
index 000000000000..dbc249a38f68
--- /dev/null
+++ b/include/linux/mipi_dsi.h
@@ -0,0 +1,165 @@
+/*
+ * Copyright (C) 2011-2015 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+#ifndef __INCLUDE_MIPI_DSI_H
+#define __INCLUDE_MIPI_DSI_H
+
+#define MIPI_DSI_VERSION (0x000)
+#define MIPI_DSI_PWR_UP (0x004)
+#define MIPI_DSI_CLKMGR_CFG (0x008)
+#define MIPI_DSI_DPI_CFG (0x00c)
+#define MIPI_DSI_DBI_CFG (0x010)
+#define MIPI_DSI_DBIS_CMDSIZE (0x014)
+#define MIPI_DSI_PCKHDL_CFG (0x018)
+#define MIPI_DSI_VID_MODE_CFG (0x01c)
+#define MIPI_DSI_VID_PKT_CFG (0x020)
+#define MIPI_DSI_CMD_MODE_CFG (0x024)
+#define MIPI_DSI_TMR_LINE_CFG (0x028)
+#define MIPI_DSI_VTIMING_CFG (0x02c)
+#define MIPI_DSI_PHY_TMR_CFG (0x030)
+#define MIPI_DSI_GEN_HDR (0x034)
+#define MIPI_DSI_GEN_PLD_DATA (0x038)
+#define MIPI_DSI_CMD_PKT_STATUS (0x03c)
+#define MIPI_DSI_TO_CNT_CFG (0x040)
+#define MIPI_DSI_ERROR_ST0 (0x044)
+#define MIPI_DSI_ERROR_ST1 (0x048)
+#define MIPI_DSI_ERROR_MSK0 (0x04c)
+#define MIPI_DSI_ERROR_MSK1 (0x050)
+#define MIPI_DSI_PHY_RSTZ (0x054)
+#define MIPI_DSI_PHY_IF_CFG (0x058)
+#define MIPI_DSI_PHY_IF_CTRL (0x05c)
+#define MIPI_DSI_PHY_STATUS (0x060)
+#define MIPI_DSI_PHY_TST_CTRL0 (0x064)
+#define MIPI_DSI_PHY_TST_CTRL1 (0x068)
+
+#define DSI_PWRUP_RESET (0x0 << 0)
+#define DSI_PWRUP_POWERUP (0x1 << 0)
+
+#define DSI_DPI_CFG_VID_SHIFT (0)
+#define DSI_DPI_CFG_VID_MASK (0x3)
+#define DSI_DPI_CFG_COLORCODE_SHIFT (2)
+#define DSI_DPI_CFG_COLORCODE_MASK (0x7)
+#define DSI_DPI_CFG_DATAEN_ACT_LOW (0x1 << 5)
+#define DSI_DPI_CFG_DATAEN_ACT_HIGH (0x0 << 5)
+#define DSI_DPI_CFG_VSYNC_ACT_LOW (0x1 << 6)
+#define DSI_DPI_CFG_VSYNC_ACT_HIGH (0x0 << 6)
+#define DSI_DPI_CFG_HSYNC_ACT_LOW (0x1 << 7)
+#define DSI_DPI_CFG_HSYNC_ACT_HIGH (0x0 << 7)
+#define DSI_DPI_CFG_SHUTD_ACT_LOW (0x1 << 8)
+#define DSI_DPI_CFG_SHUTD_ACT_HIGH (0x0 << 8)
+#define DSI_DPI_CFG_COLORMODE_ACT_LOW (0x1 << 9)
+#define DSI_DPI_CFG_COLORMODE_ACT_HIGH (0x0 << 9)
+#define DSI_DPI_CFG_EN18LOOSELY (0x1 << 10)
+
+#define DSI_PCKHDL_CFG_EN_EOTP_TX (0x1 << 0)
+#define DSI_PCKHDL_CFG_EN_EOTP_RX (0x1 << 1)
+#define DSI_PCKHDL_CFG_EN_BTA (0x1 << 2)
+#define DSI_PCKHDL_CFG_EN_ECC_RX (0x1 << 3)
+#define DSI_PCKHDL_CFG_EN_CRC_RX (0x1 << 4)
+#define DSI_PCKHDL_CFG_GEN_VID_RX_MASK (0x3)
+#define DSI_PCKHDL_CFG_GEN_VID_RX_SHIFT (5)
+
+#define DSI_VID_MODE_CFG_EN (0x1 << 0)
+#define DSI_VID_MODE_CFG_EN_BURSTMODE (0x3 << 1)
+#define DSI_VID_MODE_CFG_TYPE_MASK (0x3)
+#define DSI_VID_MODE_CFG_TYPE_SHIFT (1)
+#define DSI_VID_MODE_CFG_EN_LP_VSA (0x1 << 3)
+#define DSI_VID_MODE_CFG_EN_LP_VBP (0x1 << 4)
+#define DSI_VID_MODE_CFG_EN_LP_VFP (0x1 << 5)
+#define DSI_VID_MODE_CFG_EN_LP_VACT (0x1 << 6)
+#define DSI_VID_MODE_CFG_EN_LP_HBP (0x1 << 7)
+#define DSI_VID_MODE_CFG_EN_LP_HFP (0x1 << 8)
+#define DSI_VID_MODE_CFG_EN_MULTI_PKT (0x1 << 9)
+#define DSI_VID_MODE_CFG_EN_NULL_PKT (0x1 << 10)
+#define DSI_VID_MODE_CFG_EN_FRAME_ACK (0x1 << 11)
+#define DSI_VID_MODE_CFG_EN_LP_MODE (DSI_VID_MODE_CFG_EN_LP_VSA | \
+ DSI_VID_MODE_CFG_EN_LP_VBP | \
+ DSI_VID_MODE_CFG_EN_LP_VFP | \
+ DSI_VID_MODE_CFG_EN_LP_HFP | \
+ DSI_VID_MODE_CFG_EN_LP_HBP | \
+ DSI_VID_MODE_CFG_EN_LP_VACT)
+
+
+
+#define DSI_VID_PKT_CFG_VID_PKT_SZ_MASK (0x7ff)
+#define DSI_VID_PKT_CFG_VID_PKT_SZ_SHIFT (0)
+#define DSI_VID_PKT_CFG_NUM_CHUNKS_MASK (0x3ff)
+#define DSI_VID_PKT_CFG_NUM_CHUNKS_SHIFT (11)
+#define DSI_VID_PKT_CFG_NULL_PKT_SZ_MASK (0x3ff)
+#define DSI_VID_PKT_CFG_NULL_PKT_SZ_SHIFT (21)
+
+#define MIPI_DSI_CMD_MODE_CFG_EN_LOWPOWER (0x1FFF)
+#define MIPI_DSI_CMD_MODE_CFG_EN_CMD_MODE (0x1 << 0)
+
+#define DSI_TME_LINE_CFG_HSA_TIME_MASK (0x1ff)
+#define DSI_TME_LINE_CFG_HSA_TIME_SHIFT (0)
+#define DSI_TME_LINE_CFG_HBP_TIME_MASK (0x1ff)
+#define DSI_TME_LINE_CFG_HBP_TIME_SHIFT (9)
+#define DSI_TME_LINE_CFG_HLINE_TIME_MASK (0x3fff)
+#define DSI_TME_LINE_CFG_HLINE_TIME_SHIFT (18)
+
+#define DSI_VTIMING_CFG_VSA_LINES_MASK (0xf)
+#define DSI_VTIMING_CFG_VSA_LINES_SHIFT (0)
+#define DSI_VTIMING_CFG_VBP_LINES_MASK (0x3f)
+#define DSI_VTIMING_CFG_VBP_LINES_SHIFT (4)
+#define DSI_VTIMING_CFG_VFP_LINES_MASK (0x3f)
+#define DSI_VTIMING_CFG_VFP_LINES_SHIFT (10)
+#define DSI_VTIMING_CFG_V_ACT_LINES_MASK (0x7ff)
+#define DSI_VTIMING_CFG_V_ACT_LINES_SHIFT (16)
+
+#define DSI_PHY_TMR_CFG_BTA_TIME_MASK (0xfff)
+#define DSI_PHY_TMR_CFG_BTA_TIME_SHIFT (0)
+#define DSI_PHY_TMR_CFG_LP2HS_TIME_MASK (0xff)
+#define DSI_PHY_TMR_CFG_LP2HS_TIME_SHIFT (12)
+#define DSI_PHY_TMR_CFG_HS2LP_TIME_MASK (0xff)
+#define DSI_PHY_TMR_CFG_HS2LP_TIME_SHIFT (20)
+
+#define DSI_PHY_IF_CFG_N_LANES_MASK (0x3)
+#define DSI_PHY_IF_CFG_N_LANES_SHIFT (0)
+#define DSI_PHY_IF_CFG_WAIT_TIME_MASK (0xff)
+#define DSI_PHY_IF_CFG_WAIT_TIME_SHIFT (2)
+
+#define DSI_PHY_RSTZ_EN_CLK (0x1 << 2)
+#define DSI_PHY_RSTZ_DISABLE_RST (0x1 << 1)
+#define DSI_PHY_RSTZ_DISABLE_SHUTDOWN (0x1 << 0)
+#define DSI_PHY_RSTZ_RST (0x0)
+
+#define DSI_PHY_STATUS_LOCK (0x1 << 0)
+#define DSI_PHY_STATUS_STOPSTATE_CLK_LANE (0x1 << 2)
+
+#define DSI_GEN_HDR_TYPE_MASK (0xff)
+#define DSI_GEN_HDR_TYPE_SHIFT (0)
+#define DSI_GEN_HDR_DATA_MASK (0xffff)
+#define DSI_GEN_HDR_DATA_SHIFT (8)
+
+#define DSI_CMD_PKT_STATUS_GEN_CMD_EMPTY (0x1 << 0)
+#define DSI_CMD_PKT_STATUS_GEN_CMD_FULL (0x1 << 1)
+#define DSI_CMD_PKT_STATUS_GEN_PLD_W_EMPTY (0x1 << 2)
+#define DSI_CMD_PKT_STATUS_GEN_PLD_W_FULL (0x1 << 3)
+#define DSI_CMD_PKT_STATUS_GEN_PLD_R_EMPTY (0x1 << 4)
+#define DSI_CMD_PKT_STATUS_GEN_RD_CMD_BUSY (0x1 << 6)
+
+#define DSI_ERROR_MSK0_ALL_MASK (0x1fffff)
+#define DSI_ERROR_MSK1_ALL_MASK (0x3ffff)
+
+#define DSI_PHY_IF_CTRL_RESET (0x0)
+#define DSI_PHY_IF_CTRL_TX_REQ_CLK_HS (0x1 << 0)
+#define DSI_PHY_IF_CTRL_TX_REQ_CLK_ULPS (0x1 << 1)
+#define DSI_PHY_IF_CTRL_TX_EXIT_CLK_ULPS (0x1 << 2)
+#define DSI_PHY_IF_CTRL_TX_REQ_DATA_ULPS (0x1 << 3)
+#define DSI_PHY_IF_CTRL_TX_EXIT_DATA_ULPS (0x1 << 4)
+#define DSI_PHY_IF_CTRL_TX_TRIG_MASK (0xF)
+#define DSI_PHY_IF_CTRL_TX_TRIG_SHIFT (5)
+
+#define DSI_PHY_CLK_INIT_COMMAND (0x44)
+#define DSI_GEN_PLD_DATA_BUF_SIZE (0x4)
+#endif
diff --git a/include/linux/mipi_dsi_northwest.h b/include/linux/mipi_dsi_northwest.h
new file mode 100644
index 000000000000..8cb379c85ef5
--- /dev/null
+++ b/include/linux/mipi_dsi_northwest.h
@@ -0,0 +1,164 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __INCLUDE_MIPI_DSI_NORTHWEST_H
+#define __INCLUDE_MIPI_DSI_NORTHWEST_H
+
+/* ---------------------------- register offsets --------------------------- */
+
+/* sim */
+#define SIM_SOPT1 0x0
+#define MIPI_ISO_DISABLE 0x8
+
+#define SIM_SOPT1CFG 0x4
+#define DSI_RST_DPI_N 0x80000000
+#define DSI_RST_ESC_N 0x40000000
+#define DSI_RST_BYTE_N 0x20000000
+#define DSI_SD 0x200
+#define DSI_CM 0x100
+#define DSI_PLL_EN 0x80
+
+/* SRC */
+#define SRC_MIPIPHY_RCR 0x28
+#define MIPI_DSI_RESET_BYTE_N 0x2
+#define MIPI_DSI_RESET_N 0x4
+#define MIPI_DSI_DPI_RESET_N 0x8
+#define MIPI_DSI_ESC_RESET_N 0x10
+#define MIPI_DSI_PCLK_RESET_N 0x20
+
+/* GPR */
+#define IOMUXC_GPR_GPR13 0x34
+#define GPR_MIPI_MUX_SEL 0x4
+
+/* dphy */
+#define DPHY_PD_DPHY 0x300
+#define DPHY_M_PRG_HS_PREPARE 0x304
+#define DPHY_MC_PRG_HS_PREPARE 0x308
+#define DPHY_M_PRG_HS_ZERO 0x30c
+#define DPHY_MC_PRG_HS_ZERO 0x310
+#define DPHY_M_PRG_HS_TRAIL 0x314
+#define DPHY_MC_PRG_HS_TRAIL 0x318
+#define DPHY_PD_PLL 0x31c
+#define DPHY_TST 0x320
+#define DPHY_CN 0x324
+#define DPHY_CM 0x328
+#define DPHY_CO 0x32c
+#define DPHY_LOCK 0x330
+#define DPHY_LOCK_BYP 0x334
+#define DPHY_RTERM_SEL 0x338
+#define DPHY_AUTO_PD_EN 0x33c
+#define DPHY_RXLPRP 0x340
+#define DPHY_RXCDRP 0x344
+
+/* host */
+#define HOST_CFG_NUM_LANES 0x0
+#define HOST_CFG_NONCONTINUOUS_CLK 0x4
+#define HOST_CFG_T_PRE 0x8
+#define HOST_CFG_T_POST 0xc
+#define HOST_CFG_TX_GAP 0x10
+#define HOST_CFG_AUTOINSERT_EOTP 0x14
+#define HOST_CFG_EXTRA_CMDS_AFTER_EOTP 0x18
+#define HOST_CFG_HTX_TO_COUNT 0x1c
+#define HOST_CFG_LRX_H_TO_COUNT 0x20
+#define HOST_CFG_BTA_H_TO_COUNT 0x24
+#define HOST_CFG_TWAKEUP 0x28
+#define HOST_CFG_STATUS_OUT 0x2c
+#define HOST_RX_ERROR_STATUS 0x30
+
+/* dpi */
+#define DPI_PIXEL_PAYLOAD_SIZE 0x200
+#define DPI_PIXEL_FIFO_SEND_LEVEL 0x204
+#define DPI_INTERFACE_COLOR_CODING 0x208
+#define DPI_PIXEL_FORMAT 0x20c
+#define DPI_VSYNC_POLARITY 0x210
+#define DPI_HSYNC_POLARITY 0x214
+#define DPI_VIDEO_MODE 0x218
+#define DPI_HFP 0x21c
+#define DPI_HBP 0x220
+#define DPI_HSA 0x224
+#define DPI_ENABLE_MULT_PKTS 0x228
+#define DPI_VBP 0x22c
+#define DPI_VFP 0x230
+#define DPI_BLLP_MODE 0x234
+#define DPI_USE_NULL_PKT_BLLP 0x238
+#define DPI_VACTIVE 0x23c
+#define DPI_VC 0x240
+
+/* apb pkt */
+#define HOST_TX_PAYLOAD 0x280
+
+#define HOST_PKT_CONTROL 0x284
+#define HOST_PKT_CONTROL_WC(x) (((x) & 0xffff) << 0)
+#define HOST_PKT_CONTROL_VC(x) (((x) & 0x3) << 16)
+#define HOST_PKT_CONTROL_DT(x) (((x) & 0x3f) << 18)
+#define HOST_PKT_CONTROL_HS_SEL(x) (((x) & 0x1) << 24)
+#define HOST_PKT_CONTROL_BTA_TX(x) (((x) & 0x1) << 25)
+#define HOST_PKT_CONTROL_BTA_NO_TX(x) (((x) & 0x1) << 26)
+
+#define HOST_SEND_PACKET 0x288
+#define HOST_PKT_STATUS 0x28c
+#define HOST_PKT_FIFO_WR_LEVEL 0x290
+#define HOST_PKT_FIFO_RD_LEVEL 0x294
+#define HOST_PKT_RX_PAYLOAD 0x298
+
+#define HOST_PKT_RX_PKT_HEADER 0x29c
+#define HOST_PKT_RX_PKT_HEADER_WC(x) (((x) & 0xffff) << 0)
+#define HOST_PKT_RX_PKT_HEADER_DT(x) (((x) & 0x3f) << 16)
+#define HOST_PKT_RX_PKT_HEADER_VC(x) (((x) & 0x3) << 22)
+
+#define HOST_IRQ_STATUS 0x2a0
+#define HOST_IRQ_STATUS_SM_NOT_IDLE (1 << 0)
+#define HOST_IRQ_STATUS_TX_PKT_DONE (1 << 1)
+#define HOST_IRQ_STATUS_DPHY_DIRECTION (1 << 2)
+#define HOST_IRQ_STATUS_TX_FIFO_OVFLW (1 << 3)
+#define HOST_IRQ_STATUS_TX_FIFO_UDFLW (1 << 4)
+#define HOST_IRQ_STATUS_RX_FIFO_OVFLW (1 << 5)
+#define HOST_IRQ_STATUS_RX_FIFO_UDFLW (1 << 6)
+#define HOST_IRQ_STATUS_RX_PKT_HDR_RCVD (1 << 7)
+#define HOST_IRQ_STATUS_RX_PKT_PAYLOAD_DATA_RCVD (1 << 8)
+#define HOST_IRQ_STATUS_HOST_BTA_TIMEOUT (1 << 29)
+#define HOST_IRQ_STATUS_LP_RX_TIMEOUT (1 << 30)
+#define HOST_IRQ_STATUS_HS_TX_TIMEOUT (1 << 31)
+
+#define HOST_IRQ_STATUS2 0x2a4
+#define HOST_IRQ_STATUS2_SINGLE_BIT_ECC_ERR (1 << 0)
+#define HOST_IRQ_STATUS2_MULTI_BIT_ECC_ERR (1 << 1)
+#define HOST_IRQ_STATUS2_CRC_ERR (1 << 2)
+
+#define HOST_IRQ_MASK 0x2a8
+#define HOST_IRQ_MASK_SM_NOT_IDLE_MASK (1 << 0)
+#define HOST_IRQ_MASK_TX_PKT_DONE_MASK (1 << 1)
+#define HOST_IRQ_MASK_DPHY_DIRECTION_MASK (1 << 2)
+#define HOST_IRQ_MASK_TX_FIFO_OVFLW_MASK (1 << 3)
+#define HOST_IRQ_MASK_TX_FIFO_UDFLW_MASK (1 << 4)
+#define HOST_IRQ_MASK_RX_FIFO_OVFLW_MASK (1 << 5)
+#define HOST_IRQ_MASK_RX_FIFO_UDFLW_MASK (1 << 6)
+#define HOST_IRQ_MASK_RX_PKT_HDR_RCVD_MASK (1 << 7)
+#define HOST_IRQ_MASK_RX_PKT_PAYLOAD_DATA_RCVD_MASK (1 << 8)
+#define HOST_IRQ_MASK_HOST_BTA_TIMEOUT_MASK (1 << 29)
+#define HOST_IRQ_MASK_LP_RX_TIMEOUT_MASK (1 << 30)
+#define HOST_IRQ_MASK_HS_TX_TIMEOUT_MASK (1 << 31)
+
+#define HOST_IRQ_MASK2 0x2ac
+#define HOST_IRQ_MASK2_SINGLE_BIT_ECC_ERR_MASK (1 << 0)
+#define HOST_IRQ_MASK2_MULTI_BIT_ECC_ERR_MASK (1 << 1)
+#define HOST_IRQ_MASK2_CRC_ERR_MASK (1 << 2)
+
+/* ------------------------------------- end -------------------------------- */
+
+#endif
diff --git a/include/linux/mipi_dsi_samsung.h b/include/linux/mipi_dsi_samsung.h
new file mode 100644
index 000000000000..e58da9541cfb
--- /dev/null
+++ b/include/linux/mipi_dsi_samsung.h
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2015 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __INCLUDE_MIPI_DSI_SAMSUNG_H
+#define __INCLUDE_MIPI_DSI_SAMSUNG_H
+
+#define MIPI_DSI_VERSION (0x000)
+#define MIPI_DSI_STATUS (0x004)
+#define MIPI_DSI_RGB_STATUS (0x008)
+#define MIPI_DSI_SWRST (0x00c)
+#define MIPI_DSI_CLKCTRL (0x010)
+#define MIPI_DSI_TIMEOUT (0x014)
+#define MIPI_DSI_CONFIG (0x018)
+#define MIPI_DSI_ESCMODE (0x01c)
+#define MIPI_DSI_MDRESOL (0x020)
+#define MIPI_DSI_MVPORCH (0x024)
+#define MIPI_DSI_MHPORCH (0x028)
+#define MIPI_DSI_MSYNC (0x02c)
+#define MIPI_DSI_SDRESOL (0x030)
+#define MIPI_DSI_INTSRC (0x034)
+#define MIPI_DSI_INTMSK (0x038)
+#define MIPI_DSI_PKTHDR (0x03c)
+#define MIPI_DSI_PAYLOAD (0x040)
+#define MIPI_DSI_RXFIFO (0x044)
+#define MIPI_DSI_FIFOTHLD (0x048)
+#define MIPI_DSI_FIFOCTRL (0x04c)
+#define MIPI_DSI_MEMACCHR (0x050)
+#define MIPI_DSI_MULTI_PKT (0x078)
+#define MIPI_DSI_PLLCTRL_1G (0x090)
+#define MIPI_DSI_PLLCTRL (0x094)
+#define MIPI_DSI_PLLCTRL1 (0x098)
+#define MIPI_DSI_PLLCTRL2 (0x09c)
+#define MIPI_DSI_PLLTMR (0x0a0)
+#define MIPI_DSI_PHYCTRL_B1 (0x0a4)
+#define MIPI_DSI_PHYCTRL_B2 (0x0a8)
+#define MIPI_DSI_PHYCTRL_M1 (0x0a8)
+#define MIPI_DSI_PHYCTRL_M2 (0x0ac)
+#define MIPI_DSI_PHYTIMING (0x0b4)
+#define MIPI_DSI_PHYTIMING1 (0x0b8)
+#define MIPI_DSI_PHYTIMING2 (0x0bc)
+
+#define MIPI_DSI_SWRST_SWRST (0x1 << 0)
+#define MIPI_DSI_SWRST_FUNCRST (0x1 << 16)
+#define MIPI_DSI_MAIN_HRESOL(x) (((x) & 0x7ff) << 0)
+#define MIPI_DSI_MAIN_VRESOL(x) (((x) & 0x7ff) << 16)
+#define MIPI_DSI_MAIN_STANDBY(x) (((x) & 0x1) << 31)
+#define MIPI_DSI_MAIN_VBP(x) (((x) & 0x7ff) << 0)
+#define MIPI_DSI_STABLE_VFP(x) (((x) & 0x7ff) << 16)
+#define MIPI_DSI_CMDALLOW(x) (((x) & 0xf) << 28)
+#define MIPI_DSI_MAIN_HBP(x) (((x) & 0xffff) << 0)
+#define MIPI_DSI_MAIN_HFP(x) (((x) & 0xffff) << 16)
+#define MIPI_DSI_MAIN_VSA(x) (((x) & 0x3ff) << 22)
+#define MIPI_DSI_MAIN_HSA(x) (((x) & 0xffff) << 0)
+
+#define MIPI_DSI_LANE_EN(x) (((x) & 0x1f) << 0)
+#define MIPI_DSI_NUM_OF_DATALANE(x) (((x) & 0x3) << 5)
+#define MIPI_DSI_SUB_PIX_FORMAT(x) (((x) & 0x7) << 8)
+#define MIPI_DSI_MAIN_PIX_FORMAT(x) (((x) & 0x7) << 12)
+#define MIPI_DSI_SUB_VC(x) (((x) & 0x3) << 16)
+#define MIPI_DSI_MAIN_VC(x) (((x) & 0x3) << 18)
+#define MIPI_DSI_HSA_DISABLE_MODE(x) (((x) & 0x1) << 20)
+#define MIPI_DSI_HBP_DISABLE_MODE(x) (((x) & 0x1) << 21)
+#define MIPI_DSI_HFP_DISABLE_MODE(x) (((x) & 0x1) << 22)
+#define MIPI_DSI_HSE_DISABLE_MODE(x) (((x) & 0x1) << 23)
+#define MIPI_DSI_AUTO_MODE(x) (((x) & 0x1) << 24)
+#define MIPI_DSI_VIDEO_MODE(x) (((x) & 0x1) << 25)
+#define MIPI_DSI_BURST_MODE(x) (((x) & 0x1) << 26)
+#define MIPI_DSI_SYNC_IN_FORM(x) (((x) & 0x1) << 27)
+#define MIPI_DSI_EOT_R03(x) (((x) & 0x1) << 28)
+#define MIPI_DSI_MFLUSH_VS(x) (((x) & 0x1) << 29)
+
+#define MIPI_DSI_DP_DN_SWAP_DATA (0x1 << 24)
+#define MIPI_DSI_PLL_EN(x) (((x) & 0x1) << 23)
+#define MIPI_DSI_PMS(x) (((x) & 0x7ffff) << 1)
+
+#define MIPI_DSI_TX_REQUEST_HSCLK(x) (((x) & 0x1) << 31)
+#define MIPI_DSI_DPHY_SEL(x) (((x) & 0x1) << 29)
+#define MIPI_DSI_ESC_CLK_EN(x) (((x) & 0x1) << 28)
+#define MIPI_DSI_PLL_BYPASS(x) (((x) & 0x1) << 27)
+#define MIPI_DSI_BYTE_CLK_SRC(x) (((x) & 0x3) << 25)
+#define MIPI_DSI_BYTE_CLK_EN(x) (((x) & 0x1) << 24)
+#define MIPI_DSI_LANE_ESC_CLK_EN(x) (((x) & 0x1f) << 19)
+
+#define MIPI_DSI_FORCE_STOP_STATE(x) (((x) & 0x1) << 20)
+
+#define MIPI_DSI_M_TLPXCTL(x) (((x) & 0xff) << 8)
+#define MIPI_DSI_M_THSEXITCTL(x) (((x) & 0xff) << 0)
+
+#define MIPI_DSI_M_TCLKPRPRCTL(x) (((x) & 0xff) << 24)
+#define MIPI_DSI_M_TCLKZEROCTL(x) (((x) & 0xff) << 16)
+#define MIPI_DSI_M_TCLKPOSTCTL(x) (((x) & 0xff) << 8)
+#define MIPI_DSI_M_TCLKTRAILCTL(x) (((x) & 0xff) << 0)
+
+#define MIPI_DSI_M_THSPRPRCTL(x) (((x) & 0xff) << 16)
+#define MIPI_DSI_M_THSZEROCTL(x) (((x) & 0xff) << 8)
+#define MIPI_DSI_M_THSTRAILCTL(x) (((x) & 0xff) << 0)
+
+#define MIPI_DSI_PLL_STABLE(x) (((x) & 0x1) << 31)
+#define MIPI_DSI_TX_READY_HS_CLK(x) (((x) & 0x1) << 10)
+#define MIPI_DSI_ULPS_CLK(x) (((x) & 0x1) << 9)
+#define MIPI_DSI_STOP_STATE_CLK(x) (((x) & 0x1) << 8)
+#define MIPI_DSI_ULPS_DAT(x) (((x) & 0xf) << 4)
+#define MIPI_DSI_STOP_STATE_DAT(x) (((x) & 0xf) << 0)
+
+#define INTSRC_SFR_PL_FIFO_EMPTY (0x1 << 29)
+#define INTSRC_SFR_PH_FIFO_EMPTY (0x1 << 28)
+#define INTSRC_RX_DATA_DONE (0x1 << 18)
+#define INTMSK_SFR_PL_FIFO_EMPTY (0x1 << 29)
+#define INTMSK_SFR_PH_FIFO_EMPTY (0x1 << 28)
+#define INTMSK_RX_DATA_DONE (0x1 << 18)
+
+#define MIPI_DSI_STOP_STATE_CNT(x) (((x) & 0x7ff) << 21)
+#define MIPI_DSI_CMD_LPDT (0x1 << 7)
+#define MIPI_DSI_TX_LPDT (0x1 << 6)
+
+#endif
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index 9a43763a68ad..e315691e1ce1 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -255,6 +255,10 @@ struct mmc_supply {
struct regulator *vqmmc; /* Optional Vccq supply */
};
+struct mmc_ctx {
+ struct task_struct *task;
+};
+
struct mmc_host {
struct device *parent;
struct device class_dev;
@@ -349,6 +353,8 @@ struct mmc_host {
#define MMC_CAP2_NO_MMC (1 << 22) /* Do not send (e)MMC commands during initialization */
#define MMC_CAP2_CQE (1 << 23) /* Has eMMC command queue engine */
#define MMC_CAP2_CQE_DCMD (1 << 24) /* CQE can issue a direct command */
+#define MMC_CAP2_CD_POST (1 << 25) /* post card rescan, let client driver to start */
+#define MMC_CAP2_DDR52_3_3V (1 << 26) /* Only supprot eMMC DDR52 at 3.3v */
mmc_pm_flag_t pm_caps; /* supported pm features */
@@ -374,6 +380,7 @@ struct mmc_host {
unsigned int doing_retune:1; /* re-tuning in progress */
unsigned int retune_now:1; /* do re-tuning at next req */
unsigned int retune_paused:1; /* re-tuning is temporarily disabled */
+ unsigned int use_blk_mq:1; /* use blk-mq */
int rescan_disable; /* disable card detection */
int rescan_entered; /* used with nonremovable devices */
@@ -388,8 +395,9 @@ struct mmc_host {
struct mmc_card *card; /* device attached to this host */
wait_queue_head_t wq;
- struct task_struct *claimer; /* task that has host claimed */
+ struct mmc_ctx *claimer; /* context that has host claimed */
int claim_cnt; /* "claim" nesting count */
+ struct mmc_ctx default_ctx; /* default context */
struct delayed_work detect;
int detect_change; /* card detect flag */
@@ -469,6 +477,8 @@ void mmc_detect_change(struct mmc_host *, unsigned long delay);
void mmc_request_done(struct mmc_host *, struct mmc_request *);
void mmc_command_done(struct mmc_host *host, struct mmc_request *mrq);
+void mmc_cqe_request_done(struct mmc_host *host, struct mmc_request *mrq);
+
static inline void mmc_signal_sdio_irq(struct mmc_host *host)
{
host->ops->enable_sdio_irq(host, 0);
diff --git a/include/linux/mmc/pm.h b/include/linux/mmc/pm.h
index 4a139204c20c..6e2d6a135c7e 100644
--- a/include/linux/mmc/pm.h
+++ b/include/linux/mmc/pm.h
@@ -26,5 +26,6 @@ typedef unsigned int mmc_pm_flag_t;
#define MMC_PM_KEEP_POWER (1 << 0) /* preserve card power during suspend */
#define MMC_PM_WAKE_SDIO_IRQ (1 << 1) /* wake up host system on SDIO IRQ assertion */
+#define MMC_PM_IGNORE_PM_NOTIFY (1 << 2) /* ignore mmc pm notify */
#endif /* LINUX_MMC_PM_H */
diff --git a/include/linux/mmc/sdio.h b/include/linux/mmc/sdio.h
index 17446d3c3602..bbb9c0010cce 100644
--- a/include/linux/mmc/sdio.h
+++ b/include/linux/mmc/sdio.h
@@ -12,6 +12,8 @@
#ifndef LINUX_MMC_SDIO_H
#define LINUX_MMC_SDIO_H
+#include <linux/mmc/host.h>
+
/* SDIO commands type argument response */
#define SD_IO_SEND_OP_COND 5 /* bcr [23:0] OCR R4 */
#define SD_IO_RW_DIRECT 52 /* ac [31:0] See below R5 */
@@ -190,4 +192,6 @@
#define SDIO_FBR_BLKSIZE 0x10 /* block size (2 bytes) */
+void mmc_sdio_force_remove(struct mmc_host *host);
+
#endif /* LINUX_MMC_SDIO_H */
diff --git a/include/linux/mmc/sdio_ids.h b/include/linux/mmc/sdio_ids.h
index 0a7abe8a407f..41cf7eae61de 100644
--- a/include/linux/mmc/sdio_ids.h
+++ b/include/linux/mmc/sdio_ids.h
@@ -36,12 +36,14 @@
#define SDIO_DEVICE_ID_BROADCOM_4339 0x4339
#define SDIO_DEVICE_ID_BROADCOM_43362 0xa962
#define SDIO_DEVICE_ID_BROADCOM_43364 0xa9a4
+#define SDIO_DEVICE_ID_BROADCOM_43428 0xa9a4
#define SDIO_DEVICE_ID_BROADCOM_43430 0xa9a6
#define SDIO_DEVICE_ID_BROADCOM_4345 0x4345
#define SDIO_DEVICE_ID_BROADCOM_43455 0xa9bf
#define SDIO_DEVICE_ID_BROADCOM_4354 0x4354
#define SDIO_DEVICE_ID_BROADCOM_4356 0x4356
#define SDIO_DEVICE_ID_CYPRESS_4373 0x4373
+#define SDIO_DEVICE_ID_CYPRESS_43012 43012
#define SDIO_VENDOR_ID_INTEL 0x0089
#define SDIO_DEVICE_ID_INTEL_IWMC3200WIMAX 0x1402
diff --git a/include/linux/mtd/cfi.h b/include/linux/mtd/cfi.h
index 9b57a9b1b081..f56b52e60f43 100644
--- a/include/linux/mtd/cfi.h
+++ b/include/linux/mtd/cfi.h
@@ -377,6 +377,7 @@ struct cfi_fixup {
#define CFI_MFR_SHARP 0x00B0
#define CFI_MFR_SST 0x00BF
#define CFI_MFR_ST 0x0020 /* STMicroelectronics */
+#define CFI_MFR_MICRON 0x002C
#define CFI_MFR_TOSHIBA 0x0098
#define CFI_MFR_WINBOND 0x00DA
diff --git a/include/linux/mtd/map.h b/include/linux/mtd/map.h
index 01b990e4b228..9a397595b68c 100644
--- a/include/linux/mtd/map.h
+++ b/include/linux/mtd/map.h
@@ -446,7 +446,7 @@ static inline void inline_map_copy_from(struct map_info *map, void *to, unsigned
if (map->cached)
memcpy(to, (char *)map->cached + from, len);
else
- memcpy_fromio(to, map->virt + from, len);
+ memcpy(to, map->virt + from, len);
}
static inline void inline_map_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h
index 1f0a7fc7772f..9c9401c7e1a5 100644
--- a/include/linux/mtd/spi-nor.h
+++ b/include/linux/mtd/spi-nor.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2014 Freescale Semiconductor, Inc.
+ * Copyright (C) 2014-2016 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
@@ -24,6 +24,7 @@
#define SNOR_MFR_GIGADEVICE 0xc8
#define SNOR_MFR_INTEL CFI_MFR_INTEL
#define SNOR_MFR_MICRON CFI_MFR_ST /* ST Micro <--> Micron */
+#define SNOR_MFR_MICRONO CFI_MFR_MICRON /* Original Micron */
#define SNOR_MFR_MACRONIX CFI_MFR_MACRONIX
#define SNOR_MFR_SPANSION CFI_MFR_AMD
#define SNOR_MFR_SST CFI_MFR_SST
@@ -69,6 +70,7 @@
#define SPINOR_OP_READ_1_2_2_4B 0xbc /* Read data bytes (Dual I/O SPI) */
#define SPINOR_OP_READ_1_1_4_4B 0x6c /* Read data bytes (Quad Output SPI) */
#define SPINOR_OP_READ_1_4_4_4B 0xec /* Read data bytes (Quad I/O SPI) */
+#define SPINOR_OP_READ_1_4_4_D_4B 0xee /* Read data bytes (DDR Quad SPI) */
#define SPINOR_OP_PP_4B 0x12 /* Page program (up to 256 bytes) */
#define SPINOR_OP_PP_1_1_4_4B 0x34 /* Quad page program */
#define SPINOR_OP_PP_1_4_4_4B 0x3e /* Quad page program */
@@ -79,11 +81,13 @@
/* Double Transfer Rate opcodes - defined in JEDEC JESD216B. */
#define SPINOR_OP_READ_1_1_1_DTR 0x0d
#define SPINOR_OP_READ_1_2_2_DTR 0xbd
+#define SPINOR_OP_READ_1_1_4_DTR 0x6d
#define SPINOR_OP_READ_1_4_4_DTR 0xed
#define SPINOR_OP_READ_1_1_1_DTR_4B 0x0e
#define SPINOR_OP_READ_1_2_2_DTR_4B 0xbe
#define SPINOR_OP_READ_1_4_4_DTR_4B 0xee
+#define SPINOR_OP_READ_1_8_8_DTR_4B 0x9d
/* Used for SST flashes only. */
#define SPINOR_OP_BP 0x02 /* Byte program */
@@ -110,6 +114,8 @@
/* Used for Micron flashes only. */
#define SPINOR_OP_RD_EVCR 0x65 /* Read EVCR register */
#define SPINOR_OP_WD_EVCR 0x61 /* Write EVCR register */
+#define SPINOR_OP_RD_VCR 0x85 /* Read VCR register */
+#define SPINOR_OP_WR_VCR 0x81 /* Write VCR register */
/* Status Register bits. */
#define SR_WIP BIT(0) /* Write in progress */
diff --git a/include/linux/mx8_mu.h b/include/linux/mx8_mu.h
new file mode 100644
index 000000000000..b31e52693db8
--- /dev/null
+++ b/include/linux/mx8_mu.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017 NXP
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#define MU_ATR0_OFFSET1 0x0
+#define MU_ARR0_OFFSET1 0x10
+#define MU_ASR_OFFSET1 0x20
+#define MU_ACR_OFFSET1 0x24
+
+/* Registers offsets of the MU Version 1.0 */
+#define MU_V10_VER_OFFSET1 0x0
+#define MU_V10_ATR0_OFFSET1 0x20
+#define MU_V10_ARR0_OFFSET1 0x40
+#define MU_V10_ASR_OFFSET1 0x60
+#define MU_V10_ACR_OFFSET1 0x64
+#define MU_VER_ID_V10 0x0100 /* Version 1.0 */
+
+#define MU_TR_COUNT1 4
+#define MU_RR_COUNT1 4
+
+#define MU_CR_GIEn_MASK1 (0xF << 28)
+#define MU_CR_RIEn_MASK1 (0xF << 24)
+#define MU_CR_TIEn_MASK1 (0xF << 20)
+#define MU_CR_GIRn_MASK1 (0xF << 16)
+#define MU_CR_NMI_MASK1 (1 << 3)
+#define MU_CR_Fn_MASK1 0x7
+
+#define MU_SR_TE0_MASK1 (1 << 23)
+#define MU_SR_RF0_MASK1 (1 << 27)
+#define MU_CR_RIE0_MASK1 (1 << 27)
+#define MU_CR_GIE0_MASK1 (1 << 31)
+
+#define MU_TR_COUNT 4
+#define MU_RR_COUNT 4
+
+
+void MU_Init(void __iomem *base);
+void MU_SendMessage(void __iomem *base, uint32_t regIndex, uint32_t msg);
+void MU_SendMessageTimeout(void __iomem *base, uint32_t regIndex, uint32_t msg, uint32_t t);
+void MU_ReceiveMsg(void __iomem *base, uint32_t regIndex, uint32_t *msg);
+void MU_EnableGeneralInt(void __iomem *base, uint32_t index);
+void MU_EnableRxFullInt(void __iomem *base, uint32_t index);
+uint32_t MU_ReadStatus(void __iomem *base);
+int32_t MU_SetFn(void __iomem *base, uint32_t Fn);
+
diff --git a/include/linux/mxc_dcic.h b/include/linux/mxc_dcic.h
new file mode 100644
index 000000000000..8e330bd466da
--- /dev/null
+++ b/include/linux/mxc_dcic.h
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2014-2015 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+/*!
+ * @file linux/mxc_dcic.h
+ *
+ * @brief Global header file for the MXC DCIC driver
+ *
+ * @ingroup MXC DCIC
+ */
+
+#ifndef __LINUX_DCIC_H__
+#define __LINUX_DCIC_H__
+
+#include <uapi/linux/mxc_dcic.h>
+
+#define DCICC_IC_ENABLE 0x1
+#define DCICC_IC_DISABLE 0x0
+#define DCICC_IC_MASK 0x1
+#define DCICC_DE_ACTIVE_HIGH 0
+#define DCICC_DE_ACTIVE_LOW (0x1 << 4)
+#define DCICC_DE_ACTIVE_MASK (0x1 << 4)
+#define DCICC_HSYNC_POL_ACTIVE_HIGH 0
+#define DCICC_HSYNC_POL_ACTIVE_LOW (0x1 << 5)
+#define DCICC_HSYNC_POL_ACTIVE_MASK (0x1 << 5)
+#define DCICC_VSYNC_POL_ACTIVE_HIGH 0
+#define DCICC_VSYNC_POL_ACTIVE_LOW (0x1 << 6)
+#define DCICC_VSYNC_POL_ACTIVE_MASK (0x1 << 6)
+#define DCICC_CLK_POL_NO_INVERTED 0
+#define DCICC_CLK_POL_INVERTED (0x1 << 7)
+#define DCICC_CLK_POL_INVERTED_MASK (0x1 << 7)
+
+#define DCICIC_ERROR_INT_DISABLE 1
+#define DCICIC_ERROR_INT_ENABLE 0
+#define DCICIC_ERROR_INT_MASK_MASK 1
+#define DCICIC_FUN_INT_DISABLE (0x1 << 1)
+#define DCICIC_FUN_INT_ENABLE 0
+#define DCICIC_FUN_INT_MASK (0x1 << 1)
+#define DCICIC_FREEZE_MASK_CHANGED 0
+#define DCICIC_FREEZE_MASK_FORZEN (0x1 << 3)
+#define DCICIC_FREEZE_MASK_MASK (0x1 << 3)
+#define DCICIC_EXT_SIG_EX_DISABLE 0
+#define DCICIC_EXT_SIG_EN_ENABLE (0x1 << 16)
+#define DCICIC_EXT_SIG_EN_MASK (0x1 << 16)
+
+#define DCICS_ROI_MATCH_STAT_MASK 0xFFFF
+#define DCICS_EI_STAT_PENDING (0x1 << 16)
+#define DCICS_EI_STAT_NO_PENDING 0
+#define DCICS_FI_STAT_PENDING (0x1 << 17)
+#define DCICS_FI_STAT_NO_PENDING 0
+
+#define DCICRC_ROI_START_OFFSET_X_MASK 0x1FFF
+#define DCICRC_ROI_START_OFFSET_X_SHIFT 0
+#define DCICRC_ROI_START_OFFSET_Y_MASK (0xFFF << 16)
+#define DCICRC_ROI_START_OFFSET_Y_SHIFT 16
+#define DCICRC_ROI_CHANGED 0
+#define DCICRC_ROI_FROZEN (0x1 << 30)
+#define DCICRC_ROI_ENABLE (0x1 << 31)
+#define DCICRC_ROI_DISABLE 0
+
+#define DCICRS_ROI_END_OFFSET_X_MASK 0x1FFF
+#define DCICRS_ROI_END_OFFSET_X_SHIFT 0
+#define DCICRS_ROI_END_OFFSET_Y_MASK (0xFFF << 16)
+#define DCICRS_ROI_END_OFFSET_Y_SHIFT 16
+
+struct roi_regs {
+ u32 dcicrc;
+ u32 dcicrs;
+ u32 dcicrrs;
+ u32 dcicrcs;
+};
+
+struct dcic_regs {
+ u32 dcicc;
+ u32 dcicic;
+ u32 dcics;
+ u32 dcic_reserved;
+ struct roi_regs ROI[16];
+};
+
+struct dcic_mux {
+ char dcic[16];
+ u32 val;
+};
+
+struct bus_mux {
+ char name[16];
+ int reg;
+ int shift;
+ int mask;
+ int dcic_mux_num;
+ const struct dcic_mux *dcics;
+};
+
+struct dcic_info {
+ int bus_mux_num;
+ const struct bus_mux *buses;
+};
+
+struct dcic_data {
+ struct regmap *regmap;
+ struct device *dev;
+ struct dcic_regs *regs;
+ const struct bus_mux *buses;
+ u32 bus_n;
+ u32 mux_n;
+ struct clk *disp_axi_clk;
+ struct clk *dcic_clk;
+ struct mutex lock;
+ struct completion roi_crc_comp;
+ struct class *class;
+ int major;
+ struct cdev cdev; /* Char device structure */
+ dev_t devt;
+ unsigned int result;
+};
+#endif
diff --git a/include/linux/mxc_mlb.h b/include/linux/mxc_mlb.h
new file mode 100644
index 000000000000..d7c792a2bee4
--- /dev/null
+++ b/include/linux/mxc_mlb.h
@@ -0,0 +1,55 @@
+/*
+ * mxc_mlb.h
+ *
+ * Copyright 2008-2013 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#ifndef _MXC_MLB_H
+#define _MXC_MLB_H
+
+/* define IOCTL command */
+#define MLB_DBG_RUNTIME _IO('S', 0x09)
+#define MLB_SET_FPS _IOW('S', 0x10, unsigned int)
+#define MLB_GET_VER _IOR('S', 0x11, unsigned long)
+#define MLB_SET_DEVADDR _IOR('S', 0x12, unsigned char)
+
+/*!
+ * set channel address for each logical channel
+ * the MSB 16bits is for tx channel, the left LSB is for rx channel
+ */
+#define MLB_CHAN_SETADDR _IOW('S', 0x13, unsigned int)
+#define MLB_CHAN_STARTUP _IO('S', 0x14)
+#define MLB_CHAN_SHUTDOWN _IO('S', 0x15)
+#define MLB_CHAN_GETEVENT _IOR('S', 0x16, unsigned long)
+
+#define MLB_SET_ISOC_BLKSIZE_188 _IO('S', 0x17)
+#define MLB_SET_ISOC_BLKSIZE_196 _IO('S', 0x18)
+#define MLB_SET_SYNC_QUAD _IOW('S', 0x19, unsigned int)
+#define MLB_IRQ_ENABLE _IO('S', 0x20)
+#define MLB_IRQ_DISABLE _IO('S', 0x21)
+
+/*!
+ * MLB event define
+ */
+enum {
+ MLB_EVT_TX_PROTO_ERR_CUR = 1 << 0,
+ MLB_EVT_TX_BRK_DETECT_CUR = 1 << 1,
+ MLB_EVT_TX_PROTO_ERR_PREV = 1 << 8,
+ MLB_EVT_TX_BRK_DETECT_PREV = 1 << 9,
+ MLB_EVT_RX_PROTO_ERR_CUR = 1 << 16,
+ MLB_EVT_RX_BRK_DETECT_CUR = 1 << 17,
+ MLB_EVT_RX_PROTO_ERR_PREV = 1 << 24,
+ MLB_EVT_RX_BRK_DETECT_PREV = 1 << 25,
+};
+
+
+#endif /* _MXC_MLB_H */
diff --git a/include/linux/mxc_sim_interface.h b/include/linux/mxc_sim_interface.h
new file mode 100644
index 000000000000..5eae53a59075
--- /dev/null
+++ b/include/linux/mxc_sim_interface.h
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 2015 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+#ifndef MXC_SIM_INTERFACE_H
+#define MXC_SIM_INTERFACE_H
+
+#define SIM_ATR_LENGTH_MAX 32
+
+/* Raw ATR SIM_IOCTL_GET_ATR */
+typedef struct {
+ unsigned int size;/* length of ATR received */
+ unsigned char *atr_buffer;/* raw ATR string received */
+ int errval;/* The error vale reported to user space after completing ATR*/
+} sim_atr_t;
+
+/* ISO7816-3 protocols */
+#define SIM_PROTOCOL_T0 1
+#define SIM_PROTOCOL_T1 2
+
+/* Transfer types for SIM_IOCTL_XFER */
+#define SIM_XFER_TYPE_TPDU 1
+#define SIM_XFER_TYPE_PTS 2
+
+typedef struct {
+ unsigned int wwt;
+ unsigned int cwt;
+ unsigned int bwt;
+ unsigned int bgt;
+ unsigned int cgt;
+} sim_timing_t;
+
+/* Transfer data for SIM_IOCTL_XFER */
+typedef struct {
+ unsigned char *xmt_buffer; /* transmit buffer pointer */
+ int xmt_length;/* transmit buffer length */
+ int timeout;/* transfer timeout in milliseconds */
+ int errval;/* The error vale reported to user space after completing transmitting*/
+} sim_xmt_t;
+
+typedef struct {
+ unsigned char *rcv_buffer; /* receive buffer pointer */
+ int rcv_length; /* receive buffer length */
+ int timeout;/* transfer timeout in milliseconds */
+ int errval;/* The error vale reported to user space after receiving*/
+} sim_rcv_t;
+
+typedef struct {
+ unsigned char di;
+ unsigned char fi;
+} sim_baud_t;
+
+/* Interface power states */
+#define SIM_POWER_OFF (0)
+#define SIM_POWER_ON (1)
+
+/* Return values for SIM_IOCTL_GET_PRESENSE */
+#define SIM_PRESENT_REMOVED (0)
+#define SIM_PRESENT_DETECTED (1)
+#define SIM_PRESENT_OPERATIONAL (2)
+
+/* The error value */
+#define SIM_OK (0)
+#define SIM_ERROR_CWT (1 << 0)
+#define SIM_ERROR_BWT (1 << 1)
+#define SIM_ERROR_PARITY (1 << 2)
+#define SIM_ERROR_INVALID_TS (1 << 3)
+#define SIM_ERROR_FRAME (1 << 4)
+#define SIM_ERROR_ATR_TIMEROUT (1 << 5)
+#define SIM_ERROR_NACK_THRESHOLD (1 << 6)
+#define SIM_ERROR_BGT (1 << 7)
+#define SIM_ERROR_ATR_DELAY (1 << 8)
+
+/* Return values for SIM_IOCTL_GET_ERROR */
+#define SIM_E_ACCESS (1)
+#define SIM_E_TPDUSHORT (2)
+#define SIM_E_PTSEMPTY (3)
+#define SIM_E_INVALIDXFERTYPE (4)
+#define SIM_E_INVALIDXMTLENGTH (5)
+#define SIM_E_INVALIDRCVLENGTH (6)
+#define SIM_E_NACK (7)
+#define SIM_E_TIMEOUT (8)
+#define SIM_E_NOCARD (9)
+#define SIM_E_PARAM_FI_INVALID (10)
+#define SIM_E_PARAM_DI_INVALID (11)
+#define SIM_E_PARAM_FBYD_WITHFRACTION (12)
+#define SIM_E_PARAM_FBYD_NOTDIVBY8OR12 (13)
+#define SIM_E_PARAM_DIVISOR_RANGE (14)
+#define SIM_E_MALLOC (15)
+#define SIM_E_IRQ (16)
+#define SIM_E_POWERED_ON (17)
+#define SIM_E_POWERED_OFF (18)
+
+/* ioctl encodings */
+#define SIM_IOCTL_BASE (0xc0)
+#define SIM_IOCTL_GET_PRESENSE _IOR(SIM_IOCTL_BASE, 1, int)
+#define SIM_IOCTL_GET_ATR _IOR(SIM_IOCTL_BASE, 2, sim_atr_t)
+#define SIM_IOCTL_XMT _IOR(SIM_IOCTL_BASE, 3, sim_xmt_t)
+#define SIM_IOCTL_RCV _IOR(SIM_IOCTL_BASE, 4, sim_rcv_t)
+#define SIM_IOCTL_ACTIVATE _IO(SIM_IOCTL_BASE, 5)
+#define SIM_IOCTL_DEACTIVATE _IO(SIM_IOCTL_BASE, 6)
+#define SIM_IOCTL_WARM_RESET _IO(SIM_IOCTL_BASE, 7)
+#define SIM_IOCTL_COLD_RESET _IO(SIM_IOCTL_BASE, 8)
+#define SIM_IOCTL_CARD_LOCK _IO(SIM_IOCTL_BASE, 9)
+#define SIM_IOCTL_CARD_EJECT _IO(SIM_IOCTL_BASE, 10)
+#define SIM_IOCTL_SET_PROTOCOL _IOR(SIM_IOCTL_BASE, 11, unsigned int)
+#define SIM_IOCTL_SET_TIMING _IOR(SIM_IOCTL_BASE, 12, sim_timing_t)
+#define SIM_IOCTL_SET_BAUD _IOR(SIM_IOCTL_BASE, 13, sim_baud_t)
+#define SIM_IOCTL_WAIT _IOR(SIM_IOCTL_BASE, 14, unsigned int)
+
+#endif
diff --git a/include/linux/mxc_v4l2.h b/include/linux/mxc_v4l2.h
new file mode 100644
index 000000000000..6d778e83ef53
--- /dev/null
+++ b/include/linux/mxc_v4l2.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2004-2015 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU Lesser General
+ * Public License. You may obtain a copy of the GNU Lesser General
+ * Public License Version 2.1 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/lgpl-license.html
+ * http://www.gnu.org/copyleft/lgpl.html
+ */
+
+/*!
+ * @file linux/mxc_v4l2.h
+ *
+ * @brief MXC V4L2 private header file
+ *
+ * @ingroup MXC V4L2
+ */
+
+#ifndef __LINUX_MXC_V4L2_H__
+#define __LINUX_MXC_V4L2_H__
+
+#include <uapi/linux/mxc_v4l2.h>
+
+#endif
diff --git a/include/linux/mxc_vpu-malone.h b/include/linux/mxc_vpu-malone.h
new file mode 100755
index 000000000000..4541c8733124
--- /dev/null
+++ b/include/linux/mxc_vpu-malone.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2017 NXP
+ */
+
+/*
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/*!
+ * @defgroup VPU Video Processor Unit Driver
+ */
+
+/*!
+ * @file linux/mxc_vpu-malone.h
+ *
+ * @brief VPU system initialization and file operation definition
+ *
+ * @ingroup VPU
+ */
+
+#ifndef __LINUX_MXC_VPU_MALONE_H__
+#define __LINUX_MXC_VPU_MALONE_H__
+
+#include <linux/fs.h>
+
+struct vpu_mem_desc {
+ u32 size;
+ dma_addr_t phy_addr;
+ void *cpu_addr; /* cpu address to free the dma mem */
+ u64 virt_uaddr; /* virtual user space address */
+};
+
+#define VPU_IOC_MAGIC 'V'
+
+#define VPU_IOC_PHYMEM_ALLOC _IO(VPU_IOC_MAGIC, 0)
+#define VPU_IOC_PHYMEM_FREE _IO(VPU_IOC_MAGIC, 1)
+#define VPU_IOC_WAIT4INT _IO(VPU_IOC_MAGIC, 2)
+#define VPU_IOC_CLKGATE_SETTING _IO(VPU_IOC_MAGIC, 3)
+#define VPU_IOC_REQ_VSHARE_MEM _IO(VPU_IOC_MAGIC, 4)
+#define VPU_IOC_SYS_SW_RESET _IO(VPU_IOC_MAGIC, 5)
+#define VPU_IOC_GET_SHARE_MEM _IO(VPU_IOC_MAGIC, 6)
+#define VPU_IOC_LOCK_DEV _IO(VPU_IOC_MAGIC, 7)
+
+#endif
diff --git a/include/linux/mxc_vpu.h b/include/linux/mxc_vpu.h
new file mode 100644
index 000000000000..df024698dee7
--- /dev/null
+++ b/include/linux/mxc_vpu.h
@@ -0,0 +1,118 @@
+/*
+ * Copyright 2004-2013, 2015 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU Lesser General
+ * Public License. You may obtain a copy of the GNU Lesser General
+ * Public License Version 2.1 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/lgpl-license.html
+ * http://www.gnu.org/copyleft/lgpl.html
+ */
+
+/*!
+ * @defgroup VPU Video Processor Unit Driver
+ */
+
+/*!
+ * @file linux/mxc_vpu.h
+ *
+ * @brief VPU system initialization and file operation definition
+ *
+ * @ingroup VPU
+ */
+
+#ifndef __LINUX_MXC_VPU_H__
+#define __LINUX_MXC_VPU_H__
+
+#include <linux/fs.h>
+
+struct mxc_vpu_platform_data {
+ bool iram_enable;
+ int iram_size;
+ void (*reset) (void);
+ void (*pg) (int);
+};
+
+struct vpu_mem_desc {
+ u32 size;
+ dma_addr_t phy_addr;
+ u32 cpu_addr; /* cpu address to free the dma mem */
+ u32 virt_uaddr; /* virtual user space address */
+};
+
+#define VPU_IOC_MAGIC 'V'
+
+#define VPU_IOC_PHYMEM_ALLOC _IO(VPU_IOC_MAGIC, 0)
+#define VPU_IOC_PHYMEM_FREE _IO(VPU_IOC_MAGIC, 1)
+#define VPU_IOC_WAIT4INT _IO(VPU_IOC_MAGIC, 2)
+#define VPU_IOC_PHYMEM_DUMP _IO(VPU_IOC_MAGIC, 3)
+#define VPU_IOC_REG_DUMP _IO(VPU_IOC_MAGIC, 4)
+#define VPU_IOC_IRAM_SETTING _IO(VPU_IOC_MAGIC, 6)
+#define VPU_IOC_CLKGATE_SETTING _IO(VPU_IOC_MAGIC, 7)
+#define VPU_IOC_GET_WORK_ADDR _IO(VPU_IOC_MAGIC, 8)
+#define VPU_IOC_REQ_VSHARE_MEM _IO(VPU_IOC_MAGIC, 9)
+#define VPU_IOC_SYS_SW_RESET _IO(VPU_IOC_MAGIC, 11)
+#define VPU_IOC_GET_SHARE_MEM _IO(VPU_IOC_MAGIC, 12)
+#define VPU_IOC_QUERY_BITWORK_MEM _IO(VPU_IOC_MAGIC, 13)
+#define VPU_IOC_SET_BITWORK_MEM _IO(VPU_IOC_MAGIC, 14)
+#define VPU_IOC_PHYMEM_CHECK _IO(VPU_IOC_MAGIC, 15)
+#define VPU_IOC_LOCK_DEV _IO(VPU_IOC_MAGIC, 16)
+
+#define BIT_CODE_RUN 0x000
+#define BIT_CODE_DOWN 0x004
+#define BIT_INT_CLEAR 0x00C
+#define BIT_INT_STATUS 0x010
+#define BIT_CUR_PC 0x018
+#define BIT_INT_REASON 0x174
+
+#define MJPEG_PIC_STATUS_REG 0x3004
+#define MBC_SET_SUBBLK_EN 0x4A0
+
+#define BIT_WORK_CTRL_BUF_BASE 0x100
+#define BIT_WORK_CTRL_BUF_REG(i) (BIT_WORK_CTRL_BUF_BASE + i * 4)
+#define BIT_CODE_BUF_ADDR BIT_WORK_CTRL_BUF_REG(0)
+#define BIT_WORK_BUF_ADDR BIT_WORK_CTRL_BUF_REG(1)
+#define BIT_PARA_BUF_ADDR BIT_WORK_CTRL_BUF_REG(2)
+#define BIT_BIT_STREAM_CTRL BIT_WORK_CTRL_BUF_REG(3)
+#define BIT_FRAME_MEM_CTRL BIT_WORK_CTRL_BUF_REG(4)
+#define BIT_BIT_STREAM_PARAM BIT_WORK_CTRL_BUF_REG(5)
+
+#ifndef CONFIG_SOC_IMX6Q
+#define BIT_RESET_CTRL 0x11C
+#else
+#define BIT_RESET_CTRL 0x128
+#endif
+
+/* i could be 0, 1, 2, 3 */
+#define BIT_RD_PTR_BASE 0x120
+#define BIT_RD_PTR_REG(i) (BIT_RD_PTR_BASE + i * 8)
+#define BIT_WR_PTR_REG(i) (BIT_RD_PTR_BASE + i * 8 + 4)
+
+/* i could be 0, 1, 2, 3 */
+#define BIT_FRM_DIS_FLG_BASE (cpu_is_mx51() ? 0x150 : 0x140)
+#define BIT_FRM_DIS_FLG_REG(i) (BIT_FRM_DIS_FLG_BASE + i * 4)
+
+#define BIT_BUSY_FLAG 0x160
+#define BIT_RUN_COMMAND 0x164
+#define BIT_INT_ENABLE 0x170
+
+#define BITVAL_PIC_RUN 8
+
+#define VPU_SLEEP_REG_VALUE 10
+#define VPU_WAKE_REG_VALUE 11
+
+int vl2cc_init(u32 vl2cc_hw_base);
+void vl2cc_enable(void);
+void vl2cc_flush(void);
+void vl2cc_disable(void);
+void vl2cc_cleanup(void);
+
+int vl2cc_init(u32 vl2cc_hw_base);
+void vl2cc_enable(void);
+void vl2cc_flush(void);
+void vl2cc_disable(void);
+void vl2cc_cleanup(void);
+
+#endif
diff --git a/include/linux/mxcfb.h b/include/linux/mxcfb.h
new file mode 100644
index 000000000000..67db5ee3fd11
--- /dev/null
+++ b/include/linux/mxcfb.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2004-2013 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU Lesser General
+ * Public License. You may obtain a copy of the GNU Lesser General
+ * Public License Version 2.1 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/lgpl-license.html
+ * http://www.gnu.org/copyleft/lgpl.html
+ */
+
+/*
+ * @file linux/mxcfb.h
+ *
+ * @brief Global header file for the MXC Frame buffer
+ *
+ * @ingroup Framebuffer
+ */
+#ifndef __LINUX_MXCFB_H__
+#define __LINUX_MXCFB_H__
+
+#include <uapi/linux/mxcfb.h>
+
+extern struct fb_videomode mxcfb_modedb[];
+extern int mxcfb_modedb_sz;
+
+enum {
+ MXC_DISP_SPEC_DEV = 0,
+ MXC_DISP_DDC_DEV = 1,
+};
+
+enum {
+ MXCFB_REFRESH_OFF,
+ MXCFB_REFRESH_AUTO,
+ MXCFB_REFRESH_PARTIAL,
+};
+
+int mxcfb_set_refresh_mode(struct fb_info *fbi, int mode,
+ struct mxcfb_rect *update_region);
+int mxc_elcdif_frame_addr_setup(dma_addr_t phys);
+void mxcfb_elcdif_register_mode(const struct fb_videomode *modedb,
+ int num_modes, int dev_mode);
+
+#endif
diff --git a/include/linux/mxcfb_epdc.h b/include/linux/mxcfb_epdc.h
new file mode 100644
index 000000000000..35a8b83b22d3
--- /dev/null
+++ b/include/linux/mxcfb_epdc.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2010-2013 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+#ifndef _MXCFB_EPDC_KERNEL
+#define _MXCFB_EPDC_KERNEL
+
+struct imx_epdc_fb_mode {
+ struct fb_videomode *vmode;
+ int vscan_holdoff;
+ int sdoed_width;
+ int sdoed_delay;
+ int sdoez_width;
+ int sdoez_delay;
+ int gdclk_hp_offs;
+ int gdsp_offs;
+ int gdoe_offs;
+ int gdclk_offs;
+ int num_ce;
+};
+
+struct imx_epdc_fb_platform_data {
+ struct imx_epdc_fb_mode *epdc_mode;
+ int num_modes;
+ int (*get_pins) (void);
+ void (*put_pins) (void);
+ void (*enable_pins) (void);
+ void (*disable_pins) (void);
+};
+
+#endif
diff --git a/include/linux/of.h b/include/linux/of.h
index 3c108f9be5e7..fd9b9d2c005f 100644
--- a/include/linux/of.h
+++ b/include/linux/of.h
@@ -384,6 +384,7 @@ extern int of_phandle_iterator_args(struct of_phandle_iterator *it,
extern void of_alias_scan(void * (*dt_alloc)(u64 size, u64 align));
extern int of_alias_get_id(struct device_node *np, const char *stem);
extern int of_alias_get_highest_id(const char *stem);
+extern int of_alias_max_index(const char *stem);
extern int of_machine_is_compatible(const char *compat);
@@ -826,6 +827,11 @@ static inline int of_alias_get_highest_id(const char *stem)
return -ENOSYS;
}
+static inline int of_alias_max_index(const char *stem)
+{
+ return -ENODEV;
+}
+
static inline int of_machine_is_compatible(const char *compat)
{
return 0;
diff --git a/include/linux/of_reserved_mem.h b/include/linux/of_reserved_mem.h
index bb4fda7317be..2a37f8490ea0 100644
--- a/include/linux/of_reserved_mem.h
+++ b/include/linux/of_reserved_mem.h
@@ -35,13 +35,13 @@ int of_reserved_mem_device_init_by_idx(struct device *dev,
struct device_node *np, int idx);
void of_reserved_mem_device_release(struct device *dev);
-int early_init_dt_alloc_reserved_memory_arch(phys_addr_t size,
+int early_init_dt_alloc_reserved_memory_arch(unsigned long node,
+ phys_addr_t size,
phys_addr_t align,
phys_addr_t start,
phys_addr_t end,
bool nomap,
phys_addr_t *res_base);
-
void fdt_init_reserved_mem(void);
void fdt_reserved_mem_save_node(unsigned long node, const char *uname,
phys_addr_t base, phys_addr_t size);
diff --git a/include/linux/pci-ecam.h b/include/linux/pci-ecam.h
index 809c2f1873ac..36c9ddbb6d30 100644
--- a/include/linux/pci-ecam.h
+++ b/include/linux/pci-ecam.h
@@ -73,5 +73,6 @@ extern struct pci_ecam_ops xgene_v2_pcie_ecam_ops; /* APM X-Gene PCIe v2.x */
/* for DT-based PCI controllers that support ECAM */
int pci_host_common_probe(struct platform_device *pdev,
struct pci_ecam_ops *ops);
+int pci_host_common_remove(struct platform_device *pdev);
#endif
#endif
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 59f4d10568c6..13f667f82e5a 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -1525,12 +1525,10 @@ void pci_cfg_access_unlock(struct pci_dev *dev);
*/
#ifdef CONFIG_PCI_DOMAINS
extern int pci_domains_supported;
-int pci_get_new_domain_nr(void);
#else
enum { pci_domains_supported = 0 };
static inline int pci_domain_nr(struct pci_bus *bus) { return 0; }
static inline int pci_proc_domain(struct pci_bus *bus) { return 0; }
-static inline int pci_get_new_domain_nr(void) { return -ENOSYS; }
#endif /* CONFIG_PCI_DOMAINS */
/*
@@ -1686,7 +1684,6 @@ static inline struct pci_dev *pci_get_bus_and_slot(unsigned int bus,
static inline int pci_domain_nr(struct pci_bus *bus) { return 0; }
static inline struct pci_dev *pci_dev_get(struct pci_dev *dev) { return NULL; }
-static inline int pci_get_new_domain_nr(void) { return -ENOSYS; }
#define dev_is_pci(d) (false)
#define dev_is_pf(d) (false)
diff --git a/include/linux/phy.h b/include/linux/phy.h
index efc04c2d92c9..16caed3a7f8a 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -867,6 +867,7 @@ void phy_attached_info(struct phy_device *phydev);
int genphy_config_init(struct phy_device *phydev);
int genphy_setup_forced(struct phy_device *phydev);
int genphy_restart_aneg(struct phy_device *phydev);
+int genphy_config_aneg_check(struct phy_device *phydev);
int genphy_config_aneg(struct phy_device *phydev);
int genphy_aneg_done(struct phy_device *phydev);
int genphy_update_link(struct phy_device *phydev);
diff --git a/include/linux/phy/phy-mixel-lvds-combo.h b/include/linux/phy/phy-mixel-lvds-combo.h
new file mode 100644
index 000000000000..9eac98c42829
--- /dev/null
+++ b/include/linux/phy/phy-mixel-lvds-combo.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2017 NXP
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#ifndef PHY_MIXEL_LVDS_COMBO_H_
+#define PHY_MIXEL_LVDS_COMBO_H_
+
+#include "phy.h"
+
+#if IS_ENABLED(CONFIG_PHY_MIXEL_LVDS_COMBO)
+void mixel_phy_combo_lvds_set_phy_speed(struct phy *phy,
+ unsigned long phy_clk_rate);
+void mixel_phy_combo_lvds_set_hsync_pol(struct phy *phy, bool active_high);
+void mixel_phy_combo_lvds_set_vsync_pol(struct phy *phy, bool active_high);
+#else
+void mixel_phy_combo_lvds_set_phy_speed(struct phy *phy,
+ unsigned long phy_clk_rate)
+{
+}
+void mixel_phy_combo_lvds_set_hsync_pol(struct phy *phy, bool active_high)
+{
+}
+void mixel_phy_combo_lvds_set_vsync_pol(struct phy *phy, bool active_high)
+{
+}
+#endif
+
+#endif /* PHY_MIXEL_LVDS_COMBO_H_ */
diff --git a/include/linux/phy/phy-mixel-lvds.h b/include/linux/phy/phy-mixel-lvds.h
new file mode 100644
index 000000000000..3540857b7a65
--- /dev/null
+++ b/include/linux/phy/phy-mixel-lvds.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2017 NXP
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#ifndef PHY_MIXEL_LVDS_H_
+#define PHY_MIXEL_LVDS_H_
+
+#include "phy.h"
+
+#if IS_ENABLED(CONFIG_PHY_MIXEL_LVDS)
+void mixel_phy_lvds_set_phy_speed(struct phy *phy, unsigned long phy_clk_rate);
+void mixel_phy_lvds_set_hsync_pol(struct phy *phy, bool active_high);
+void mixel_phy_lvds_set_vsync_pol(struct phy *phy, bool active_high);
+#else
+void mixel_phy_lvds_set_phy_speed(struct phy *phy, unsigned long phy_clk_rate)
+{
+}
+void mixel_phy_lvds_set_hsync_pol(struct phy *phy, bool active_high)
+{
+}
+void mixel_phy_lvds_set_vsync_pol(struct phy *phy, bool active_high)
+{
+}
+#endif
+
+#endif /* PHY_MIXEL_LVDS_H_ */
diff --git a/include/linux/phy/phy-mixel-mipi-dsi.h b/include/linux/phy/phy-mixel-mipi-dsi.h
new file mode 100644
index 000000000000..a76eea4d2704
--- /dev/null
+++ b/include/linux/phy/phy-mixel-mipi-dsi.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2017 NXP
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#ifndef PHY_MIXEL_MIPI_DSI_H_
+#define PHY_MIXEL_MIPI_DSI_H_
+
+#include "phy.h"
+
+#if IS_ENABLED(CONFIG_PHY_MIXEL_MIPI_DSI)
+int mixel_phy_mipi_set_phy_speed(struct phy *phy,
+ unsigned long bit_clk,
+ unsigned long ref_clk,
+ bool best_match);
+#else
+int mixel_phy_mipi_set_phy_speed(struct phy *phy,
+ unsigned long bit_clk,
+ unsigned long ref_clk,
+ bool best_match)
+{
+ return -ENODEV;
+}
+#endif
+
+#endif /* PHY_MIXEL_MIPI_DSI_H_ */
diff --git a/include/linux/platform_data/brcmfmac.h b/include/linux/platform_data/brcmfmac.h
index 1d30bf278231..b737c0a8e58d 100644
--- a/include/linux/platform_data/brcmfmac.h
+++ b/include/linux/platform_data/brcmfmac.h
@@ -178,6 +178,7 @@ struct brcmfmac_platform_data {
void (*power_off)(void);
char *fw_alternative_path;
int device_count;
+ struct device *dev;
struct brcmfmac_pd_device devices[0];
};
diff --git a/include/linux/platform_data/dma-imx-sdma.h b/include/linux/platform_data/dma-imx-sdma.h
index 6eaa53cef0bd..da06645bea80 100644
--- a/include/linux/platform_data/dma-imx-sdma.h
+++ b/include/linux/platform_data/dma-imx-sdma.h
@@ -51,7 +51,12 @@ struct sdma_script_start_addrs {
/* End of v2 array */
s32 zcanfd_2_mcu_addr;
s32 zqspi_2_mcu_addr;
+ s32 mcu_2_ecspi_addr;
+ s32 mcu_2_sai_addr;
+ s32 sai_2_mcu_addr;
/* End of v3 array */
+ s32 mcu_2_zqspi_addr;
+ /* End of v4 array */
};
/**
diff --git a/include/linux/platform_data/dma-imx.h b/include/linux/platform_data/dma-imx.h
index 7d964e787299..59e34a321da4 100644
--- a/include/linux/platform_data/dma-imx.h
+++ b/include/linux/platform_data/dma-imx.h
@@ -1,5 +1,6 @@
/*
- * Copyright 2004-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2004-2015 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2018 NXP.
*
* 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
@@ -42,6 +43,8 @@ enum sdma_peripheral_type {
IMX_DMATYPE_SSI_DUAL, /* SSI Dual FIFO */
IMX_DMATYPE_ASRC_SP, /* Shared ASRC */
IMX_DMATYPE_SAI, /* SAI */
+ IMX_DMATYPE_HDMI, /* HDMI Audio */
+ IMX_DMATYPE_MULTI_SAI, /* MULTI FIFOs For Audio */
};
enum imx_dma_prio {
@@ -55,6 +58,10 @@ struct imx_dma_data {
int dma_request2; /* secondary DMA request line */
enum sdma_peripheral_type peripheral_type;
int priority;
+ bool src_dualfifo;
+ bool dst_dualfifo;
+ int idx;
+ int done_sel;
};
static inline int imx_dma_is_ipu(struct dma_chan *chan)
@@ -62,6 +69,11 @@ static inline int imx_dma_is_ipu(struct dma_chan *chan)
return !strcmp(dev_name(chan->device->dev), "ipu-core");
}
+static inline int imx_dma_is_pxp(struct dma_chan *chan)
+{
+ return strstr(dev_name(chan->device->dev), "pxp") != NULL;
+}
+
static inline int imx_dma_is_general_purpose(struct dma_chan *chan)
{
return !strcmp(chan->device->dev->driver->name, "imx-sdma") ||
diff --git a/include/linux/platform_data/mmc-esdhc-imx.h b/include/linux/platform_data/mmc-esdhc-imx.h
index 7daa78a2f342..9888c868423b 100644
--- a/include/linux/platform_data/mmc-esdhc-imx.h
+++ b/include/linux/platform_data/mmc-esdhc-imx.h
@@ -34,7 +34,6 @@ enum cd_types {
* @cd_gpio: gpio for card_detect interrupt
* @wp_type: type of write_protect method (see wp_types enum above)
* @cd_type: type of card_detect method (see cd_types enum above)
- * @support_vsel: indicate it supports 1.8v switching
*/
struct esdhc_platform_data {
@@ -43,9 +42,9 @@ struct esdhc_platform_data {
enum wp_types wp_type;
enum cd_types cd_type;
int max_bus_width;
- bool support_vsel;
unsigned int delay_line;
unsigned int tuning_step; /* The delay cell steps in tuning procedure */
unsigned int tuning_start_tap; /* The start delay cell point in tuning procedure */
+ unsigned int strobe_dll_delay_target; /* The delay cell for strobe pad (read clock) */
};
#endif /* __ASM_ARCH_IMX_ESDHC_H */
diff --git a/include/linux/pm_domain.h b/include/linux/pm_domain.h
index 84f423d5633e..49e92073517c 100644
--- a/include/linux/pm_domain.h
+++ b/include/linux/pm_domain.h
@@ -90,6 +90,7 @@ struct generic_pm_domain {
};
};
+ unsigned int state_idx_saved; /* saved power state for recovery after system suspend/resume */
};
static inline struct generic_pm_domain *pd_to_genpd(struct dev_pm_domain *pd)
@@ -233,6 +234,8 @@ extern int of_genpd_parse_idle_states(struct device_node *dn,
struct genpd_power_state **states, int *n);
int genpd_dev_pm_attach(struct device *dev);
+struct generic_pm_domain *genpd_get_from_provider(
+ struct of_phandle_args *genpdspec);
#else /* !CONFIG_PM_GENERIC_DOMAINS_OF */
static inline int of_genpd_add_provider_simple(struct device_node *np,
struct generic_pm_domain *genpd)
@@ -276,6 +279,13 @@ struct generic_pm_domain *of_genpd_remove_last(struct device_node *np)
{
return ERR_PTR(-ENOTSUPP);
}
+
+static inline
+struct generic_pm_domain *genpd_get_from_provider(
+ struct of_phandle_args *genpdspec)
+{
+ return ERR_PTR(-ENOTSUPP);
+}
#endif /* CONFIG_PM_GENERIC_DOMAINS_OF */
#ifdef CONFIG_PM
diff --git a/include/linux/pmic_status.h b/include/linux/pmic_status.h
new file mode 100644
index 000000000000..a127c7117e13
--- /dev/null
+++ b/include/linux/pmic_status.h
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2004-2015 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU Lesser General
+ * Public License. You may obtain a copy of the GNU Lesser General
+ * Public License Version 2.1 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/lgpl-license.html
+ * http://www.gnu.org/copyleft/lgpl.html
+ */
+#ifndef __ASM_ARCH_MXC_PMIC_STATUS_H__
+#define __ASM_ARCH_MXC_PMIC_STATUS_H__
+#include <asm-generic/errno-base.h>
+#ifdef __KERNEL__
+#include <asm/uaccess.h> /* copy_{from,to}_user() */
+#endif
+/*!
+ * @file arch-mxc/pmic_status.h
+ * @brief PMIC APIs return code definition.
+ *
+ * @ingroup PMIC_CORE
+ */
+
+/*!
+ * @enum PMIC_STATUS
+ * @brief Define return values for all PMIC APIs.
+ *
+ * These return values are used by all of the PMIC APIs.
+ *
+ * @ingroup PMIC
+ */
+typedef enum {
+ PMIC_SUCCESS = 0, /*!< The requested operation was successfully
+ completed. */
+ PMIC_ERROR = -1, /*!< The requested operation could not be completed
+ due to an error. */
+ PMIC_PARAMETER_ERROR = -2, /*!< The requested operation failed because
+ one or more of the parameters was
+ invalid. */
+ PMIC_NOT_SUPPORTED = -3, /*!< The requested operation could not be
+ completed because the PMIC hardware
+ does not support it. */
+ PMIC_SYSTEM_ERROR_EINTR = -EINTR,
+
+ PMIC_MALLOC_ERROR = -5, /*!< Error in malloc function */
+ PMIC_UNSUBSCRIBE_ERROR = -6, /*!< Error in un-subscribe event */
+ PMIC_EVENT_NOT_SUBSCRIBED = -7, /*!< Event occur and not subscribed */
+ PMIC_EVENT_CALL_BACK = -8, /*!< Error - bad call back */
+ PMIC_CLIENT_NBOVERFLOW = -9, /*!< The requested operation could not be
+ completed because there are too many
+ PMIC client requests */
+} PMIC_STATUS;
+
+/*
+ * Bitfield macros that use rely on bitfield width/shift information.
+ */
+#define BITFMASK(field) (((1U << (field ## _WID)) - 1) << (field ## _LSH))
+#define BITFVAL(field, val) ((val) << (field ## _LSH))
+#define BITFEXT(var, bit) ((var & BITFMASK(bit)) >> (bit ## _LSH))
+
+/*
+ * Macros implementing error handling
+ */
+#define CHECK_ERROR(a) \
+do { \
+ int ret = (a); \
+ if (ret != PMIC_SUCCESS) \
+ return ret; \
+} while (0)
+
+#define CHECK_ERROR_KFREE(func, freeptrs) \
+do { \
+ int ret = (func); \
+ if (ret != PMIC_SUCCESS) { \
+ freeptrs; \
+ return ret; \
+ } \
+} while (0);
+
+#endif /* __ASM_ARCH_MXC_PMIC_STATUS_H__ */
diff --git a/include/linux/power/sabresd_battery.h b/include/linux/power/sabresd_battery.h
new file mode 100644
index 000000000000..10bfa4588864
--- /dev/null
+++ b/include/linux/power/sabresd_battery.h
@@ -0,0 +1,65 @@
+/*
+ * sabresd_battery.h - Maxim 8903 USB/Adapter Charger Driver
+ *
+ * Copyright (C) 2011 Samsung Electronics
+ * Copyright (C) 2011-2015 Freescale Semiconductor, Inc.
+ * Based on max8903_charger.h
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef __MAX8903_SABRESD_H__
+#define __MAX8903_SABRESD_H__
+
+struct max8903_pdata {
+ /*
+ * GPIOs
+ * cen, chg, flt, and usus are optional.
+ * dok, dcm, and uok are not optional depending on the status of
+ * dc_valid and usb_valid.
+ */
+ int cen; /* Charger Enable input */
+ int dok; /* DC(Adapter) Power OK output */
+ int uok; /* USB Power OK output */
+ int chg; /* Charger status output */
+ int flt; /* Fault output */
+ int dcm; /* Current-Limit Mode input (1: DC, 2: USB) */
+ int usus; /* USB Suspend Input (1: suspended) */
+ int feature_flag;/* battery capacity feature(0:enable, 1:disable) */
+
+ /*
+ * DCM wired to Logic High Set this true when DCM pin connect to
+ * Logic high.
+ */
+ bool dcm_always_high;
+
+ /*
+ * DC(Adapter/TA) is wired
+ * When dc_valid is true,
+ * dok and dcm should be valid.
+ *
+ * At least one of dc_valid or usb_valid should be true.
+ */
+ bool dc_valid;
+ /*
+ * USB is wired
+ * When usb_valid is true,
+ * uok should be valid.
+ */
+ bool usb_valid;
+};
+
+#endif /* __SABRESD_BATTERY_H__ */
diff --git a/include/linux/pwm_backlight.h b/include/linux/pwm_backlight.h
index e8afbd71a140..cac4d427cde4 100644
--- a/include/linux/pwm_backlight.h
+++ b/include/linux/pwm_backlight.h
@@ -21,6 +21,7 @@ struct platform_pwm_backlight_data {
void (*notify_after)(struct device *dev, int brightness);
void (*exit)(struct device *dev);
int (*check_fb)(struct device *dev, struct fb_info *info);
+ char fb_id[16];
};
#endif
diff --git a/include/linux/pxp_device.h b/include/linux/pxp_device.h
new file mode 100644
index 000000000000..df185c49d017
--- /dev/null
+++ b/include/linux/pxp_device.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2013-2014 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+#ifndef _PXP_DEVICE
+#define _PXP_DEVICE
+
+#include <linux/idr.h>
+#include <linux/hash.h>
+#include <uapi/linux/pxp_device.h>
+
+struct pxp_irq_info {
+ wait_queue_head_t waitq;
+ atomic_t irq_pending;
+ int hist_status;
+};
+
+struct pxp_buffer_hash {
+ struct hlist_head *hash_table;
+ u32 order;
+ spinlock_t hash_lock;
+};
+
+struct pxp_buf_obj {
+ uint32_t handle;
+
+ uint32_t size;
+ uint32_t mem_type;
+
+ unsigned long offset;
+ void *virtual;
+
+ struct hlist_node item;
+};
+
+struct pxp_chan_obj {
+ uint32_t handle;
+ struct dma_chan *chan;
+};
+
+/* File private data */
+struct pxp_file {
+ struct file *filp;
+
+ /* record allocated dma buffer */
+ struct idr buffer_idr;
+ spinlock_t buffer_lock;
+
+ /* record allocated dma channel */
+ struct idr channel_idr;
+ spinlock_t channel_lock;
+};
+
+#endif
diff --git a/include/linux/pxp_dma.h b/include/linux/pxp_dma.h
new file mode 100644
index 000000000000..a48871caebfc
--- /dev/null
+++ b/include/linux/pxp_dma.h
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2010-2015 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+#ifndef _PXP_DMA
+#define _PXP_DMA
+
+#include <uapi/linux/pxp_dma.h>
+
+struct pxp_tx_desc {
+ struct dma_async_tx_descriptor txd;
+ struct list_head tx_list;
+ struct list_head list;
+ int len;
+ union {
+ struct pxp_layer_param s0_param;
+ struct pxp_layer_param out_param;
+ struct pxp_layer_param ol_param;
+ struct pxp_layer_param processing_param;
+ } layer_param;
+ struct pxp_proc_data proc_data;
+
+ u32 hist_status; /* Histogram output status */
+
+ struct pxp_tx_desc *next;
+};
+
+struct pxp_channel {
+ struct dma_chan dma_chan;
+ dma_cookie_t completed; /* last completed cookie */
+ enum pxp_channel_status status;
+ void *client; /* Only one client per channel */
+ unsigned int n_tx_desc;
+ struct pxp_tx_desc *desc; /* allocated tx-descriptors */
+ struct list_head active_list; /* active tx-descriptors */
+ struct list_head free_list; /* free tx-descriptors */
+ struct list_head queue; /* queued tx-descriptors */
+ struct list_head list; /* track queued channel number */
+ spinlock_t lock; /* protects sg[0,1], queue */
+ struct mutex chan_mutex; /* protects status, cookie, free_list */
+ int active_buffer;
+ unsigned int eof_irq;
+ char eof_name[16]; /* EOF IRQ name for request_irq() */
+};
+
+#define to_tx_desc(tx) container_of(tx, struct pxp_tx_desc, txd)
+#define to_pxp_channel(d) container_of(d, struct pxp_channel, dma_chan)
+
+void pxp_txd_ack(struct dma_async_tx_descriptor *txd,
+ struct pxp_channel *pxp_chan);
+
+#ifdef CONFIG_MXC_PXP_CLIENT_DEVICE
+int register_pxp_device(void);
+void unregister_pxp_device(void);
+#else
+static int register_pxp_device(void) { return 0; }
+static void unregister_pxp_device(void) {}
+#endif
+void pxp_fill(
+ u32 bpp,
+ u32 value,
+ u32 width,
+ u32 height,
+ u32 output_buffer,
+ u32 output_pitch);
+
+void m4_process(void);
+#endif
diff --git a/include/linux/regulator/consumer.h b/include/linux/regulator/consumer.h
index f3f76051e8b0..82875120a9c4 100644
--- a/include/linux/regulator/consumer.h
+++ b/include/linux/regulator/consumer.h
@@ -121,6 +121,9 @@ struct regmap;
#define REGULATOR_EVENT_PRE_DISABLE 0x400
#define REGULATOR_EVENT_ABORT_DISABLE 0x800
#define REGULATOR_EVENT_ENABLE 0x1000
+#define REGULATOR_EVENT_PRE_DO_ENABLE 0x2000
+#define REGULATOR_EVENT_PRE_DO_DISABLE 0x4000
+#define REGULATOR_EVENT_AFT_DO_ENABLE 0x8000
/*
* Regulator errors that can be queried using regulator_get_error_flags
diff --git a/include/linux/regulator/fixed.h b/include/linux/regulator/fixed.h
index 48918be649d4..ba4ac009d832 100644
--- a/include/linux/regulator/fixed.h
+++ b/include/linux/regulator/fixed.h
@@ -51,6 +51,7 @@ struct fixed_voltage_config {
int microvolts;
int gpio;
unsigned startup_delay;
+ unsigned off_on_delay;
unsigned gpio_is_open_drain:1;
unsigned enable_high:1;
unsigned enabled_at_boot:1;
diff --git a/include/linux/rpmsg.h b/include/linux/rpmsg.h
index 10d6ae8bbb7d..df056ad6bf78 100644
--- a/include/linux/rpmsg.h
+++ b/include/linux/rpmsg.h
@@ -43,6 +43,8 @@
#include <linux/mutex.h>
#include <linux/poll.h>
+#define VIRTIO_RPMSG_F_NS 0
+
#define RPMSG_ADDR_ANY 0xFFFFFFFF
struct rpmsg_device;
diff --git a/include/linux/tee_drv.h b/include/linux/tee_drv.h
index cb889afe576b..07bd226cd5f9 100644
--- a/include/linux/tee_drv.h
+++ b/include/linux/tee_drv.h
@@ -25,8 +25,9 @@
* specific TEE driver.
*/
-#define TEE_SHM_MAPPED 0x1 /* Memory mapped by the kernel */
-#define TEE_SHM_DMA_BUF 0x2 /* Memory with dma-buf handle */
+#define TEE_SHM_MAPPED BIT(0) /* Memory mapped by the kernel */
+#define TEE_SHM_DMA_BUF BIT(1) /* Memory with dma-buf handle */
+#define TEE_SHM_EXT_DMA_BUF BIT(2) /* Memory with dma-buf handle */
struct device;
struct tee_device;
@@ -211,6 +212,16 @@ void *tee_get_drvdata(struct tee_device *teedev);
struct tee_shm *tee_shm_alloc(struct tee_context *ctx, size_t size, u32 flags);
/**
+ * tee_shm_register_fd() - Register shared memory from file descriptor
+ *
+ * @ctx: Context that allocates the shared memory
+ * @fd: shared memory file descriptor reference.
+ *
+ * @returns a pointer to 'struct tee_shm'
+ */
+struct tee_shm *tee_shm_register_fd(struct tee_context *ctx, int fd);
+
+/**
* tee_shm_free() - Free shared memory
* @shm: Handle to shared memory to free
*/
@@ -275,4 +286,36 @@ int tee_shm_get_id(struct tee_shm *shm);
*/
struct tee_shm *tee_shm_get_from_id(struct tee_context *ctx, int id);
+static inline bool tee_param_is_memref(struct tee_param *param)
+{
+ switch (param->attr & TEE_IOCTL_PARAM_ATTR_TYPE_MASK) {
+ case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT:
+ case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT:
+ case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT:
+ return true;
+ default:
+ return false;
+ }
+}
+
+struct tee_context *tee_client_open_context(struct tee_context *start,
+ int (*match)(struct tee_ioctl_version_data *,
+ const void *),
+ const void *data, struct tee_ioctl_version_data *vers);
+
+void tee_client_close_context(struct tee_context *ctx);
+
+void tee_client_get_version(struct tee_context *ctx,
+ struct tee_ioctl_version_data *vers);
+
+int tee_client_open_session(struct tee_context *ctx,
+ struct tee_ioctl_open_session_arg *arg,
+ struct tee_param *param);
+
+int tee_client_close_session(struct tee_context *ctx, u32 session);
+
+int tee_client_invoke_func(struct tee_context *ctx,
+ struct tee_ioctl_invoke_arg *arg,
+ struct tee_param *param);
+
#endif /*__TEE_DRV_H*/
diff --git a/include/linux/usb.h b/include/linux/usb.h
index a22a3e139e96..991b467012ac 100644
--- a/include/linux/usb.h
+++ b/include/linux/usb.h
@@ -431,6 +431,7 @@ struct usb_bus {
* Does the host controller use PIO
* for control transfers?
*/
+ struct otg_fsm *otg_fsm; /* usb otg finite state machine */
u8 otg_port; /* 0, or number of OTG/HNP port */
unsigned is_b_host:1; /* true during some HNP roleswitches */
unsigned b_hnp_enable:1; /* OTG: did A-Host enable HNP? */
diff --git a/include/linux/usb/chipidea.h b/include/linux/usb/chipidea.h
index 07f99362bc90..f572e1e01c63 100644
--- a/include/linux/usb/chipidea.h
+++ b/include/linux/usb/chipidea.h
@@ -60,9 +60,20 @@ struct ci_hdrc_platform_data {
#define CI_HDRC_OVERRIDE_RX_BURST BIT(11)
#define CI_HDRC_OVERRIDE_PHY_CONTROL BIT(12) /* Glue layer manages phy */
#define CI_HDRC_REQUIRES_ALIGNED_DMA BIT(13)
+#define CI_HDRC_IMX_EHCI_QUIRK BIT(14)
+#define CI_HDRC_IMX_IS_HSIC BIT(15)
+/* need request pmqos during low power */
+#define CI_HDRC_PMQOS BIT(16)
+/* Using PHY's charger detection */
+#define CI_HDRC_PHY_CHARGER_DETECTION BIT(17)
enum usb_dr_mode dr_mode;
#define CI_HDRC_CONTROLLER_RESET_EVENT 0
#define CI_HDRC_CONTROLLER_STOPPED_EVENT 1
+#define CI_HDRC_CONTROLLER_VBUS_EVENT 2
+#define CI_HDRC_IMX_HSIC_ACTIVE_EVENT 5
+#define CI_HDRC_IMX_HSIC_SUSPEND_EVENT 6
+#define CI_HDRC_IMX_TERM_SELECT_OVERRIDE_FS 7
+#define CI_HDRC_IMX_TERM_SELECT_OVERRIDE_OFF 8
int (*notify_event) (struct ci_hdrc *ci, unsigned event);
struct regulator *reg_vbus;
struct usb_otg_caps ci_otg_caps;
@@ -89,4 +100,6 @@ struct platform_device *ci_hdrc_add_device(struct device *dev,
/* Remove ci hdrc device */
void ci_hdrc_remove_device(struct platform_device *pdev);
+/* Get current available role */
+enum usb_dr_mode ci_hdrc_query_available_role(struct platform_device *pdev);
#endif
diff --git a/include/linux/usb/hcd.h b/include/linux/usb/hcd.h
index a1f03ebfde47..ea7fe49daa1d 100644
--- a/include/linux/usb/hcd.h
+++ b/include/linux/usb/hcd.h
@@ -398,7 +398,10 @@ struct hc_driver {
int (*find_raw_port_number)(struct usb_hcd *, int);
/* Call for power on/off the port if necessary */
int (*port_power)(struct usb_hcd *hcd, int portnum, bool enable);
-
+ /* Call for SINGLE_STEP_SET_FEATURE Test for USB2 EH certification */
+#define EHSET_TEST_SINGLE_STEP_SET_FEATURE 0x06
+ int (*submit_single_step_set_feature)(struct usb_hcd *,
+ struct urb *, int);
};
static inline int hcd_giveback_urb_in_bh(struct usb_hcd *hcd)
@@ -456,6 +459,14 @@ extern int usb_hcd_find_raw_port_number(struct usb_hcd *hcd, int port1);
struct platform_device;
extern void usb_hcd_platform_shutdown(struct platform_device *dev);
+#ifdef CONFIG_USB_HCD_TEST_MODE
+extern int ehset_single_step_set_feature(struct usb_hcd *hcd, int port);
+#else
+static inline int ehset_single_step_set_feature(struct usb_hcd *hcd, int port)
+{
+ return 0;
+}
+#endif /* CONFIG_USB_HCD_TEST_MODE */
#ifdef CONFIG_USB_PCI
struct pci_dev;
diff --git a/include/linux/usb/otg-fsm.h b/include/linux/usb/otg-fsm.h
index a0a8f878503c..afebc95703d0 100644
--- a/include/linux/usb/otg-fsm.h
+++ b/include/linux/usb/otg-fsm.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2007,2008 Freescale Semiconductor, Inc.
+/* Copyright (C) 2007-2015 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
@@ -53,6 +53,10 @@ enum otg_fsm_timer {
A_WAIT_ENUM,
B_DATA_PLS,
B_SSEND_SRP,
+ A_DP_END,
+ A_TST_MAINT,
+ B_SRP_REQD,
+ B_TST_SUSP,
NUM_OTG_FSM_TIMERS,
};
@@ -170,6 +174,13 @@ struct otg_fsm {
int b_srp_done;
int b_hnp_enable;
int a_clr_err;
+ int hnp_polling;
+
+ /* OTG test device */
+ int tst_maint;
+ int otg_vbus_off;
+ int otg_srp_reqd;
+ int otg_hnp_reqd;
/* Informative variables. All unused as of now */
int a_bus_drop_inf;
diff --git a/include/linux/usb/phy.h b/include/linux/usb/phy.h
index b7a2625947f5..ef89950cb68a 100644
--- a/include/linux/usb/phy.h
+++ b/include/linux/usb/phy.h
@@ -63,6 +63,13 @@ enum usb_otg_state {
OTG_STATE_A_VBUS_ERR,
};
+/* The usb role of phy to be working with */
+enum usb_current_mode {
+ USB_MODE_NONE,
+ USB_MODE_HOST,
+ USB_MODE_DEVICE,
+};
+
struct usb_phy;
struct usb_otg;
@@ -155,6 +162,15 @@ struct usb_phy {
* manually detect the charger type.
*/
enum usb_charger_type (*charger_detect)(struct usb_phy *x);
+
+ int (*notify_suspend)(struct usb_phy *x,
+ enum usb_device_speed speed);
+ int (*notify_resume)(struct usb_phy *x,
+ enum usb_device_speed speed);
+
+ int (*set_mode)(struct usb_phy *x,
+ enum usb_current_mode mode);
+
};
/**
@@ -229,6 +245,15 @@ usb_phy_vbus_off(struct usb_phy *x)
return x->set_vbus(x, false);
}
+static inline int
+usb_phy_set_mode(struct usb_phy *x, enum usb_current_mode mode)
+{
+ if (!x || !x->set_mode)
+ return 0;
+
+ return x->set_mode(x, mode);
+}
+
/* for usb host and peripheral controller drivers */
#if IS_ENABLED(CONFIG_USB_PHY)
extern struct usb_phy *usb_get_phy(enum usb_phy_type type);
@@ -370,6 +395,24 @@ usb_phy_notify_disconnect(struct usb_phy *x, enum usb_device_speed speed)
return 0;
}
+static inline int usb_phy_notify_suspend
+ (struct usb_phy *x, enum usb_device_speed speed)
+{
+ if (x && x->notify_suspend)
+ return x->notify_suspend(x, speed);
+ else
+ return 0;
+}
+
+static inline int usb_phy_notify_resume
+ (struct usb_phy *x, enum usb_device_speed speed)
+{
+ if (x && x->notify_resume)
+ return x->notify_resume(x, speed);
+ else
+ return 0;
+}
+
/* notifiers */
static inline int
usb_register_notifier(struct usb_phy *x, struct notifier_block *nb)
diff --git a/include/linux/usb/typec.h b/include/linux/usb/typec.h
index 0d44ce6af08f..41320b14d29c 100644
--- a/include/linux/usb/typec.h
+++ b/include/linux/usb/typec.h
@@ -25,6 +25,7 @@ enum typec_port_type {
TYPEC_PORT_DFP,
TYPEC_PORT_UFP,
TYPEC_PORT_DRP,
+ TYPEC_PORT_TYPE_UNKNOWN,
};
enum typec_plug_type {
@@ -43,6 +44,7 @@ enum typec_data_role {
enum typec_role {
TYPEC_SINK,
TYPEC_SOURCE,
+ TYPEC_ROLE_UNKNOWN,
};
enum typec_pwr_opmode {
@@ -244,5 +246,7 @@ void typec_set_data_role(struct typec_port *port, enum typec_data_role role);
void typec_set_pwr_role(struct typec_port *port, enum typec_role role);
void typec_set_vconn_role(struct typec_port *port, enum typec_role role);
void typec_set_pwr_opmode(struct typec_port *port, enum typec_pwr_opmode mode);
+enum typec_port_type typec_get_port_type(struct device *dev);
+enum typec_role typec_get_power_role(struct device *dev);
#endif /* __LINUX_USB_TYPEC_H */
diff --git a/include/linux/wakelock.h b/include/linux/wakelock.h
new file mode 100644
index 000000000000..f4a698a22880
--- /dev/null
+++ b/include/linux/wakelock.h
@@ -0,0 +1,67 @@
+/* include/linux/wakelock.h
+ *
+ * Copyright (C) 2007-2012 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef _LINUX_WAKELOCK_H
+#define _LINUX_WAKELOCK_H
+
+#include <linux/ktime.h>
+#include <linux/device.h>
+
+/* A wake_lock prevents the system from entering suspend or other low power
+ * states when active. If the type is set to WAKE_LOCK_SUSPEND, the wake_lock
+ * prevents a full system suspend.
+ */
+
+enum {
+ WAKE_LOCK_SUSPEND, /* Prevent suspend */
+ WAKE_LOCK_TYPE_COUNT
+};
+
+struct wake_lock {
+ struct wakeup_source ws;
+};
+
+static inline void wake_lock_init(struct wake_lock *lock, int type,
+ const char *name)
+{
+ wakeup_source_init(&lock->ws, name);
+}
+
+static inline void wake_lock_destroy(struct wake_lock *lock)
+{
+ wakeup_source_trash(&lock->ws);
+}
+
+static inline void wake_lock(struct wake_lock *lock)
+{
+ __pm_stay_awake(&lock->ws);
+}
+
+static inline void wake_lock_timeout(struct wake_lock *lock, long timeout)
+{
+ __pm_wakeup_event(&lock->ws, jiffies_to_msecs(timeout));
+}
+
+static inline void wake_unlock(struct wake_lock *lock)
+{
+ __pm_relax(&lock->ws);
+}
+
+static inline int wake_lock_active(struct wake_lock *lock)
+{
+ return lock->ws.active;
+}
+
+#endif
diff --git a/include/media/v4l2-chip-ident.h b/include/media/v4l2-chip-ident.h
new file mode 100644
index 000000000000..b4c8416c3d1f
--- /dev/null
+++ b/include/media/v4l2-chip-ident.h
@@ -0,0 +1,355 @@
+/*
+ v4l2 chip identifiers header
+
+ This header provides a list of chip identifiers that can be returned
+ through the VIDIOC_DBG_G_CHIP_IDENT ioctl.
+
+ Copyright (C) 2011-2014 Freescale Semiconductor, Inc.
+ Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef V4L2_CHIP_IDENT_H_
+#define V4L2_CHIP_IDENT_H_
+
+/* VIDIOC_DBG_G_CHIP_IDENT: identifies the actual chip installed on the board */
+
+/* KEEP THIS LIST ORDERED BY ID!
+ Otherwise it will be hard to see which ranges are already in use when
+ adding support to a new chip family. */
+enum {
+ /* general idents: reserved range 0-49 */
+ V4L2_IDENT_NONE = 0, /* No chip matched */
+ V4L2_IDENT_AMBIGUOUS = 1, /* Match too general, multiple chips matched */
+ V4L2_IDENT_UNKNOWN = 2, /* Chip found, but cannot identify */
+
+ /* module tvaudio: reserved range 50-99 */
+ V4L2_IDENT_TVAUDIO = 50, /* A tvaudio chip, unknown which it is exactly */
+
+ /* Sony IMX074 */
+ V4L2_IDENT_IMX074 = 74,
+
+ /* module saa7110: just ident 100 */
+ V4L2_IDENT_SAA7110 = 100,
+
+ /* module saa7115: reserved range 101-149 */
+ V4L2_IDENT_SAA7111 = 101,
+ V4L2_IDENT_SAA7111A = 102,
+ V4L2_IDENT_SAA7113 = 103,
+ V4L2_IDENT_SAA7114 = 104,
+ V4L2_IDENT_SAA7115 = 105,
+ V4L2_IDENT_SAA7118 = 108,
+
+ V4L2_IDENT_GM7113C = 140,
+
+ /* module saa7127: reserved range 150-199 */
+ V4L2_IDENT_SAA7127 = 157,
+ V4L2_IDENT_SAA7129 = 159,
+
+ /* module cx25840: reserved range 200-249 */
+ V4L2_IDENT_CX25836 = 236,
+ V4L2_IDENT_CX25837 = 237,
+ V4L2_IDENT_CX25840 = 240,
+ V4L2_IDENT_CX25841 = 241,
+ V4L2_IDENT_CX25842 = 242,
+ V4L2_IDENT_CX25843 = 243,
+
+ /* OmniVision sensors: reserved range 250-299 */
+ V4L2_IDENT_OV7670 = 250,
+ V4L2_IDENT_OV7720 = 251,
+ V4L2_IDENT_OV7725 = 252,
+ V4L2_IDENT_OV7660 = 253,
+ V4L2_IDENT_OV9650 = 254,
+ V4L2_IDENT_OV9655 = 255,
+ V4L2_IDENT_SOI968 = 256,
+ V4L2_IDENT_OV9640 = 257,
+ V4L2_IDENT_OV6650 = 258,
+ V4L2_IDENT_OV2640 = 259,
+ V4L2_IDENT_OV9740 = 260,
+ V4L2_IDENT_OV5642 = 261,
+
+ /* module saa7146: reserved range 300-309 */
+ V4L2_IDENT_SAA7146 = 300,
+
+ /* Conexant MPEG encoder/decoders: reserved range 400-420 */
+ V4L2_IDENT_CX23418_843 = 403, /* Integrated A/V Decoder on the '418 */
+ V4L2_IDENT_CX23415 = 415,
+ V4L2_IDENT_CX23416 = 416,
+ V4L2_IDENT_CX23417 = 417,
+ V4L2_IDENT_CX23418 = 418,
+
+ /* module bt819: reserved range 810-819 */
+ V4L2_IDENT_BT815A = 815,
+ V4L2_IDENT_BT817A = 817,
+ V4L2_IDENT_BT819A = 819,
+
+ /* module au0828 */
+ V4L2_IDENT_AU0828 = 828,
+
+ /* module bttv: ident 848 + 849 */
+ V4L2_IDENT_BT848 = 848,
+ V4L2_IDENT_BT849 = 849,
+
+ /* module bt856: just ident 856 */
+ V4L2_IDENT_BT856 = 856,
+
+ /* module bt866: just ident 866 */
+ V4L2_IDENT_BT866 = 866,
+
+ /* module bttv: ident 878 + 879 */
+ V4L2_IDENT_BT878 = 878,
+ V4L2_IDENT_BT879 = 879,
+
+ /* module ks0127: reserved range 1120-1129 */
+ V4L2_IDENT_KS0122S = 1122,
+ V4L2_IDENT_KS0127 = 1127,
+ V4L2_IDENT_KS0127B = 1128,
+
+ /* module indycam: just ident 2000 */
+ V4L2_IDENT_INDYCAM = 2000,
+
+ /* module vp27smpx: just ident 2700 */
+ V4L2_IDENT_VP27SMPX = 2700,
+
+ /* module vpx3220: reserved range: 3210-3229 */
+ V4L2_IDENT_VPX3214C = 3214,
+ V4L2_IDENT_VPX3216B = 3216,
+ V4L2_IDENT_VPX3220A = 3220,
+
+ /* VX855 just ident 3409 */
+ /* Other via devs could use 3314, 3324, 3327, 3336, 3364, 3353 */
+ V4L2_IDENT_VIA_VX855 = 3409,
+
+ /* module tvp5150 */
+ V4L2_IDENT_TVP5150 = 5150,
+
+ /* module saa5246a: just ident 5246 */
+ V4L2_IDENT_SAA5246A = 5246,
+
+ /* module saa5249: just ident 5249 */
+ V4L2_IDENT_SAA5249 = 5249,
+
+ /* module cs5345: just ident 5345 */
+ V4L2_IDENT_CS5345 = 5345,
+
+ /* module tea6415c: just ident 6415 */
+ V4L2_IDENT_TEA6415C = 6415,
+
+ /* module tea6420: just ident 6420 */
+ V4L2_IDENT_TEA6420 = 6420,
+
+ /* module saa6588: just ident 6588 */
+ V4L2_IDENT_SAA6588 = 6588,
+
+ /* module vs6624: just ident 6624 */
+ V4L2_IDENT_VS6624 = 6624,
+
+ /* module saa6752hs: reserved range 6750-6759 */
+ V4L2_IDENT_SAA6752HS = 6752,
+ V4L2_IDENT_SAA6752HS_AC3 = 6753,
+
+ /* modules tef6862: just ident 6862 */
+ V4L2_IDENT_TEF6862 = 6862,
+
+ /* module tvp7002: just ident 7002 */
+ V4L2_IDENT_TVP7002 = 7002,
+
+ /* module adv7170: just ident 7170 */
+ V4L2_IDENT_ADV7170 = 7170,
+
+ /* module adv7175: just ident 7175 */
+ V4L2_IDENT_ADV7175 = 7175,
+
+ /* module adv7180: just ident 7180 */
+ V4L2_IDENT_ADV7180 = 7180,
+
+ /* module adv7183: just ident 7183 */
+ V4L2_IDENT_ADV7183 = 7183,
+
+ /* module saa7185: just ident 7185 */
+ V4L2_IDENT_SAA7185 = 7185,
+
+ /* module saa7191: just ident 7191 */
+ V4L2_IDENT_SAA7191 = 7191,
+
+ /* module ths7303: just ident 7303 */
+ V4L2_IDENT_THS7303 = 7303,
+
+ /* module adv7343: just ident 7343 */
+ V4L2_IDENT_ADV7343 = 7343,
+
+ /* module ths7353: just ident 7353 */
+ V4L2_IDENT_THS7353 = 7353,
+
+ /* module adv7393: just ident 7393 */
+ V4L2_IDENT_ADV7393 = 7393,
+
+ /* module adv7604: just ident 7604 */
+ V4L2_IDENT_ADV7604 = 7604,
+
+ /* module saa7706h: just ident 7706 */
+ V4L2_IDENT_SAA7706H = 7706,
+
+ /* module mt9v011, just ident 8243 */
+ V4L2_IDENT_MT9V011 = 8243,
+
+ /* module wm8739: just ident 8739 */
+ V4L2_IDENT_WM8739 = 8739,
+
+ /* module wm8775: just ident 8775 */
+ V4L2_IDENT_WM8775 = 8775,
+
+ /* Marvell controllers starting at 8801 */
+ V4L2_IDENT_CAFE = 8801,
+ V4L2_IDENT_ARMADA610 = 8802,
+
+ /* AKM AK8813/AK8814 */
+ V4L2_IDENT_AK8813 = 8813,
+ V4L2_IDENT_AK8814 = 8814,
+
+ /* module cx23885 and cx25840 */
+ V4L2_IDENT_CX23885 = 8850,
+ V4L2_IDENT_CX23885_AV = 8851, /* Integrated A/V decoder */
+ V4L2_IDENT_CX23887 = 8870,
+ V4L2_IDENT_CX23887_AV = 8871, /* Integrated A/V decoder */
+ V4L2_IDENT_CX23888 = 8880,
+ V4L2_IDENT_CX23888_AV = 8881, /* Integrated A/V decoder */
+ V4L2_IDENT_CX23888_IR = 8882, /* Integrated infrared controller */
+
+ /* module ad9389b: just ident 9389 */
+ V4L2_IDENT_AD9389B = 9389,
+
+ /* module tda9840: just ident 9840 */
+ V4L2_IDENT_TDA9840 = 9840,
+
+ /* module tw9910: just ident 9910 */
+ V4L2_IDENT_TW9910 = 9910,
+
+ /* module sn9c20x: just ident 10000 */
+ V4L2_IDENT_SN9C20X = 10000,
+
+ /* module cx231xx and cx25840 */
+ V4L2_IDENT_CX2310X_AV = 23099, /* Integrated A/V decoder; not in '100 */
+ V4L2_IDENT_CX23100 = 23100,
+ V4L2_IDENT_CX23101 = 23101,
+ V4L2_IDENT_CX23102 = 23102,
+
+ /* module msp3400: reserved range 34000-34999 for msp34xx */
+ V4L2_IDENT_MSPX4XX = 34000, /* generic MSPX4XX identifier, only
+ use internally (tveeprom.c). */
+
+ V4L2_IDENT_MSP3400B = 34002,
+ V4L2_IDENT_MSP3400C = 34003,
+ V4L2_IDENT_MSP3400D = 34004,
+ V4L2_IDENT_MSP3400G = 34007,
+ V4L2_IDENT_MSP3401G = 34017,
+ V4L2_IDENT_MSP3402G = 34027,
+ V4L2_IDENT_MSP3405D = 34054,
+ V4L2_IDENT_MSP3405G = 34057,
+ V4L2_IDENT_MSP3407D = 34074,
+ V4L2_IDENT_MSP3407G = 34077,
+
+ V4L2_IDENT_MSP3410B = 34102,
+ V4L2_IDENT_MSP3410C = 34103,
+ V4L2_IDENT_MSP3410D = 34104,
+ V4L2_IDENT_MSP3410G = 34107,
+ V4L2_IDENT_MSP3411G = 34117,
+ V4L2_IDENT_MSP3412G = 34127,
+ V4L2_IDENT_MSP3415D = 34154,
+ V4L2_IDENT_MSP3415G = 34157,
+ V4L2_IDENT_MSP3417D = 34174,
+ V4L2_IDENT_MSP3417G = 34177,
+
+ V4L2_IDENT_MSP3420G = 34207,
+ V4L2_IDENT_MSP3421G = 34217,
+ V4L2_IDENT_MSP3422G = 34227,
+ V4L2_IDENT_MSP3425G = 34257,
+ V4L2_IDENT_MSP3427G = 34277,
+
+ V4L2_IDENT_MSP3430G = 34307,
+ V4L2_IDENT_MSP3431G = 34317,
+ V4L2_IDENT_MSP3435G = 34357,
+ V4L2_IDENT_MSP3437G = 34377,
+
+ V4L2_IDENT_MSP3440G = 34407,
+ V4L2_IDENT_MSP3441G = 34417,
+ V4L2_IDENT_MSP3442G = 34427,
+ V4L2_IDENT_MSP3445G = 34457,
+ V4L2_IDENT_MSP3447G = 34477,
+
+ V4L2_IDENT_MSP3450G = 34507,
+ V4L2_IDENT_MSP3451G = 34517,
+ V4L2_IDENT_MSP3452G = 34527,
+ V4L2_IDENT_MSP3455G = 34557,
+ V4L2_IDENT_MSP3457G = 34577,
+
+ V4L2_IDENT_MSP3460G = 34607,
+ V4L2_IDENT_MSP3461G = 34617,
+ V4L2_IDENT_MSP3465G = 34657,
+ V4L2_IDENT_MSP3467G = 34677,
+
+ /* module msp3400: reserved range 44000-44999 for msp44xx */
+ V4L2_IDENT_MSP4400G = 44007,
+ V4L2_IDENT_MSP4408G = 44087,
+ V4L2_IDENT_MSP4410G = 44107,
+ V4L2_IDENT_MSP4418G = 44187,
+ V4L2_IDENT_MSP4420G = 44207,
+ V4L2_IDENT_MSP4428G = 44287,
+ V4L2_IDENT_MSP4440G = 44407,
+ V4L2_IDENT_MSP4448G = 44487,
+ V4L2_IDENT_MSP4450G = 44507,
+ V4L2_IDENT_MSP4458G = 44587,
+
+ /* Micron CMOS sensor chips: 45000-45099 */
+ V4L2_IDENT_MT9M001C12ST = 45000,
+ V4L2_IDENT_MT9M001C12STM = 45005,
+ V4L2_IDENT_MT9M111 = 45007,
+ V4L2_IDENT_MT9M112 = 45008,
+ V4L2_IDENT_MT9V022IX7ATC = 45010, /* No way to detect "normal" I77ATx */
+ V4L2_IDENT_MT9V022IX7ATM = 45015, /* and "lead free" IA7ATx chips */
+ V4L2_IDENT_MT9T031 = 45020,
+ V4L2_IDENT_MT9T111 = 45021,
+ V4L2_IDENT_MT9T112 = 45022,
+ V4L2_IDENT_MT9V111 = 45031,
+ V4L2_IDENT_MT9V112 = 45032,
+
+ /* HV7131R CMOS sensor: just ident 46000 */
+ V4L2_IDENT_HV7131R = 46000,
+
+ /* Sharp RJ54N1CB0C, 0xCB0C = 51980 */
+ V4L2_IDENT_RJ54N1CB0C = 51980,
+
+ /* module m52790: just ident 52790 */
+ V4L2_IDENT_M52790 = 52790,
+
+ /* module cs53132a: just ident 53132 */
+ V4L2_IDENT_CS53l32A = 53132,
+
+ /* modules upd61151 MPEG2 encoder: just ident 54000 */
+ V4L2_IDENT_UPD61161 = 54000,
+ /* modules upd61152 MPEG2 encoder with AC3: just ident 54001 */
+ V4L2_IDENT_UPD61162 = 54001,
+
+ /* module upd64031a: just ident 64031 */
+ V4L2_IDENT_UPD64031A = 64031,
+
+ /* module upd64083: just ident 64083 */
+ V4L2_IDENT_UPD64083 = 64083,
+
+ /* Don't just add new IDs at the end: KEEP THIS LIST ORDERED BY ID! */
+};
+
+#endif
diff --git a/include/media/v4l2-dev.h b/include/media/v4l2-dev.h
index 28a686eb7d09..6cd753236213 100644
--- a/include/media/v4l2-dev.h
+++ b/include/media/v4l2-dev.h
@@ -153,6 +153,7 @@ struct v4l2_file_operations {
ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);
ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);
unsigned int (*poll) (struct file *, struct poll_table_struct *);
+ long (*ioctl) (struct file *, unsigned int, unsigned long);
long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);
#ifdef CONFIG_COMPAT
long (*compat_ioctl32) (struct file *, unsigned int, unsigned long);
diff --git a/include/media/v4l2-device.h b/include/media/v4l2-device.h
index 8ffa94009d1a..bb97f64e91c8 100644
--- a/include/media/v4l2-device.h
+++ b/include/media/v4l2-device.h
@@ -69,6 +69,8 @@ struct v4l2_device {
unsigned int notification, void *arg);
struct v4l2_ctrl_handler *ctrl_handler;
struct v4l2_prio_state prio;
+ /* BKL replacement mutex. Temporary solution only. */
+ struct mutex ioctl_lock;
struct kref ref;
void (*release)(struct v4l2_device *v4l2_dev);
};
diff --git a/include/media/v4l2-ioctl.h b/include/media/v4l2-ioctl.h
index a7b3f7c75d62..15563d874af1 100644
--- a/include/media/v4l2-ioctl.h
+++ b/include/media/v4l2-ioctl.h
@@ -555,6 +555,8 @@ struct v4l2_ioctl_ops {
int (*vidioc_g_chip_info)(struct file *file, void *fh,
struct v4l2_dbg_chip_info *chip);
#endif
+ int (*vidioc_g_chip_ident) (struct file *file, void *fh,
+ struct v4l2_dbg_chip_ident *chip);
int (*vidioc_enum_framesizes)(struct file *file, void *fh,
struct v4l2_frmsizeenum *fsize);
diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h
index e83872078376..fb143fd2ea43 100644
--- a/include/media/v4l2-subdev.h
+++ b/include/media/v4l2-subdev.h
@@ -97,6 +97,7 @@ struct v4l2_decode_vbi_line {
/*
* Core ops: it is highly recommended to implement at least these ops:
*
+ * g_chip_ident
* log_status
* g_register
* s_register
@@ -186,6 +187,7 @@ struct v4l2_subdev_io_pin_config {
* @unsubscribe_event: remove event subscription from the control framework.
*/
struct v4l2_subdev_core_ops {
+ int (*g_chip_ident)(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip);
int (*log_status)(struct v4l2_subdev *sd);
int (*s_io_pin_config)(struct v4l2_subdev *sd, size_t n,
struct v4l2_subdev_io_pin_config *pincfg);
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index ea0ed58db97e..61eb2ec3d79a 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -3277,6 +3277,7 @@ enum wiphy_flags {
WIPHY_FLAG_SUPPORTS_5_10_MHZ = BIT(22),
WIPHY_FLAG_HAS_CHANNEL_SWITCH = BIT(23),
WIPHY_FLAG_HAS_STATIC_WEP = BIT(24),
+ WIPHY_FLAG_DFS_OFFLOAD = BIT(25)
};
/**
@@ -4513,6 +4514,32 @@ const u8 *cfg80211_find_vendor_ie(unsigned int oui, int oui_type,
int regulatory_hint(struct wiphy *wiphy, const char *alpha2);
/**
+ * regulatory_hint_user - hint to the wireless core a regulatory domain
+ * which the driver has received from an application
+ * @alpha2: the ISO/IEC 3166 alpha2 the driver claims its regulatory domain
+ * should be in. If @rd is set this should be NULL. Note that if you
+ * set this to NULL you should still set rd->alpha2 to some accepted
+ * alpha2.
+ * @user_reg_hint_type: the type of user regulatory hint.
+ *
+ * Wireless drivers can use this function to hint to the wireless core
+ * the current regulatory domain as specified by trusted applications,
+ * it is the driver's responsibilty to estbalish which applications it
+ * trusts.
+ *
+ * The wiphy should be registered to cfg80211 prior to this call.
+ * For cfg80211 drivers this means you must first use wiphy_register(),
+ * for mac80211 drivers you must first use ieee80211_register_hw().
+ *
+ * Drivers should check the return value, its possible you can get
+ * an -ENOMEM or an -EINVAL.
+ *
+ * Return: 0 on success. -ENOMEM, -EINVAL.
+ */
+int regulatory_hint_user(const char *alpha2,
+ enum nl80211_user_reg_hint_type user_reg_hint_type);
+
+/**
* regulatory_set_wiphy_regd - set regdom info for self managed drivers
* @wiphy: the wireless device we want to process the regulatory domain on
* @rd: the regulatory domain informatoin to use for this wiphy
@@ -6188,6 +6215,16 @@ void cfg80211_nan_func_terminated(struct wireless_dev *wdev,
/* ethtool helper */
void cfg80211_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info);
+/**
+ * cfg80211_is_gratuitous_arp_unsolicited_na - packet is grat. ARP/unsol. NA
+ * @skb: the input packet, must be an ethernet frame already
+ *
+ * Return: %true if the packet is a gratuitous ARP or unsolicited NA packet.
+ * This is used to drop packets that shouldn't occur because the AP implements
+ * a proxy service.
+ */
+bool cfg80211_is_gratuitous_arp_unsolicited_na(struct sk_buff *skb);
+
/* Logging, debugging and troubleshooting/diagnostic helpers. */
/* wiphy_printk helpers, similar to dev_printk */
diff --git a/include/soc/imx/fsl_hvc.h b/include/soc/imx/fsl_hvc.h
new file mode 100644
index 000000000000..63e3cc5a3f2a
--- /dev/null
+++ b/include/soc/imx/fsl_hvc.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright 2018 NXP
+ *
+ * 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 __SOC_FSL_HVC_H
+#define __SOC_FSL_HVC_H
+
+/* VENDOR HVC 0xC6000000 - 0xC600FFFF */
+#define FSL_HVC_SC 0xC6000000
+
+#endif
diff --git a/include/soc/imx/fsl_sip.h b/include/soc/imx/fsl_sip.h
new file mode 100644
index 000000000000..0fbcbb5d1e68
--- /dev/null
+++ b/include/soc/imx/fsl_sip.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017 NXP
+ *
+ * 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 __SOC_FSL_SIP_H
+#define __SOC_FSL_SIP_H
+
+/* SIP 0xC2000000 - 0xC200FFFF */
+#define FSL_SIP_GPC 0xC2000000
+#define FSL_SIP_CONFIG_GPC_MASK 0x00
+#define FSL_SIP_CONFIG_GPC_UNMASK 0x01
+#define FSL_SIP_CONFIG_GPC_SET_WAKE 0x02
+#define FSL_SIP_CONFIG_GPC_PM_DOMAIN 0x03
+
+#define FSL_SIP_CPUFREQ 0xC2000001
+#define FSL_SIP_SET_CPUFREQ 0x00
+
+#define FSL_SIP_SRTC 0xC2000002
+#define FSL_SIP_SRTC_SET_TIME 0x00
+#define FSL_SIP_SRTC_START_WDOG 0x01
+#define FSL_SIP_SRTC_STOP_WDOG 0x02
+#define FSL_SIP_SRTC_SET_WDOG_ACT 0x03
+#define FSL_SIP_SRTC_PING_WDOG 0x04
+#define FSL_SIP_SRTC_SET_TIMEOUT_WDOG 0x05
+#define FSL_SIP_SRTC_GET_WDOG_STAT 0x06
+#define FSL_SIP_SRTC_SET_PRETIME_WDOG 0x07
+
+#define FSL_SIP_DDR_DVFS 0xc2000004
+
+#define IMX8MQ_PD_MIPI 0
+#define IMX8MQ_PD_PCIE1 1
+#define IMX8MQ_PD_OTG1 2
+#define IMX8MQ_PD_OTG2 3
+#define IMX8MQ_PD_GPU 4
+#define IMX8MQ_PD_VPU 5
+#define IMX8MQ_PD_HDMI 6
+#define IMX8MQ_PD_DISP 7
+#define IMX8MQ_PD_MIPI_CSI1 8
+#define IMX8MQ_PD_MIPI_CSI2 9
+#define IMX8MQ_PD_PCIE2 10
+
+#define FSL_SIP_DDR_DVFS 0xc2000004
+
+#define FSL_SIP_SRC 0xc2000005
+#define FSL_SIP_SRC_M4_START 0x00
+#define FSL_SIP_SRC_M4_STARTED 0x01
+
+#define FSL_SIP_GET_SOC_INFO 0xc2000006
+
+#define FSL_SIP_NOC 0xc2000008
+#define FSL_SIP_NOC_LCDIF 0x0
+#define FSL_SIP_NOC_PRIORITY 0x1
+#define NOC_GPU_PRIORITY 0x10
+#define NOC_DCSS_PRIORITY 0x11
+#define NOC_VPU_PRIORITY 0x12
+#define NOC_CPU_PRIORITY 0x13
+#define NOC_MIX_PRIORITY 0x14
+
+#define FSL_SIP_WAKEUP_SRC 0xc2000009
+#define FSL_SIP_WAKEUP_SRC_SCU 0x1
+#define FSL_SIP_WAKEUP_SRC_IRQSTEER 0x2
+
+#endif
diff --git a/include/soc/imx/gpc.h b/include/soc/imx/gpc.h
new file mode 100644
index 000000000000..6a976e6aa3fe
--- /dev/null
+++ b/include/soc/imx/gpc.h
@@ -0,0 +1,7 @@
+#ifndef __SOC_IMX_GPC_H
+#define __SOC_IMX_GPC_H
+
+void imx_gpc_hold_m4_in_sleep(void);
+void imx_gpc_release_m4_in_sleep(void);
+
+#endif /* __SOC_IMX_GPC_H */
diff --git a/include/soc/imx/src.h b/include/soc/imx/src.h
new file mode 100644
index 000000000000..c55c34cd2366
--- /dev/null
+++ b/include/soc/imx/src.h
@@ -0,0 +1,6 @@
+#ifndef __SOC_IMX_SRC_H
+#define __SOC_IMX_SRC_H
+
+bool imx_src_is_m4_enabled(void);
+
+#endif /* __SOC_IMX_SRC_H */
diff --git a/include/soc/imx8/fsl_bitaccess.h b/include/soc/imx8/fsl_bitaccess.h
new file mode 100644
index 000000000000..11e71eeb411b
--- /dev/null
+++ b/include/soc/imx8/fsl_bitaccess.h
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017 NXP
+ *
+ * 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.
+ */
+
+/*!
+ * @file devices/MX8/include/fsl_bitaccess.h
+ *
+ * Header file containing register access macros.
+ *
+ * \addtogroup Peripheral_access_layer (HAL) Device Peripheral Access Layer
+ *
+ * @{
+ */
+
+#ifndef _FSL_BITACCESS_H
+#define _FSL_BITACCESS_H 1
+
+/*!
+ * @addtogroup SCF Register Access Macros
+ * @{
+ */
+
+/*
+ * Macros for single instance registers
+ */
+
+#define BF_SET(reg, field) HW_##reg##_SET(BM_##reg##_##field)
+#define BF_CLR(reg, field) HW_##reg##_CLR(BM_##reg##_##field)
+#define BF_TOG(reg, field) HW_##reg##_TOG(BM_##reg##_##field)
+
+#define BF_SETV(reg, field, v) HW_##reg##_SET(BF_##reg##_##field(v))
+#define BF_CLRV(reg, field, v) HW_##reg##_CLR(BF_##reg##_##field(v))
+#define BF_TOGV(reg, field, v) HW_##reg##_TOG(BF_##reg##_##field(v))
+
+#define BV_FLD(reg, field, sym) BF_##reg##_##field(BV_##reg##_##field##__##sym)
+#define BV_VAL(reg, field, sym) BV_##reg##_##field##__##sym
+
+#define BF_RD(reg, field) HW_##reg.B.field
+#define BF_WR(reg, field, v) BW_##reg##_##field(v)
+
+
+/*******************************************************************************
+ * Macros to create bitfield mask, shift, and width from CMSIS definitions
+ ******************************************************************************/
+
+/* Bitfield Mask */
+#define SCF_BMSK(bit) (bit ## _MASK)
+
+/* Bitfield Left Shift */
+#define SCF_BLSH(bit) (bit ## _SHIFT)
+
+/* Bitfield Width */
+#define SCF_BWID(bit) (bit ## _WIDTH)
+
+/* Bitfield Value */
+#define SCF_BVAL(bit, val) ((val) << (SCF_BLSH(bit)))
+
+
+/*******************************************************************************
+ * Macros to set, clear, extact, and insert bitfields into register structures
+ * or local variables
+ ******************************************************************************/
+
+/* Bitfield Set */
+#define SCF_BSET(var, bit) (var |= (SCF_BMSK(bit)))
+
+/* Bitfield Clear */
+#define SCF_BCLR(var, bit) (var &= (~(SCF_BMSK(bit))))
+
+/* Bitfield Extract */
+#define SCF_BEXR(var, bit) ((var & (SCF_BMSK(bit))) >> (SCF_BLSH(bit)))
+
+/* Bitfield Insert */
+#define SCF_BINS(var, bit, val) (var = (var & (~(SCF_BMSK(bit)))) | SCF_BVAL(bit, val))
+
+
+/*******************************************************************************
+ * Macros to set, clear, extact, and insert bitfields into register structures
+ * that support SCT
+ ******************************************************************************/
+
+#ifdef EMUL
+/* Emulation does not have SCT hardware and must fallback to non-SCT definitions */
+
+/* SCT Bitfield Set */
+#define SCF_SCT_BSET(var, bit) (SCF_BSET(var, bit))
+
+/* SCT Bitfield Clear */
+#define SCF_SCT_BCLR(var, bit) (SCF_BCLR(var, bit))
+
+/* SCT Bitfield Insert */
+#define SCF_SCT_BINS(var, bit, val) (SCF_BINS(var, bit, val))
+
+#else
+/*! @todo Port macros leverage SCT register access hardware */
+
+/* SCT Bitfield Set */
+#define SCF_SCT_BSET(var, bit) (SCF_BSET(var, bit))
+
+/* SCT Bitfield Clear */
+#define SCF_SCT_BCLR(var, bit) (SCF_BCLR(var, bit))
+
+/* SCT Bitfield Insert */
+#define SCF_SCT_BINS(var, bit, val) (SCF_BINS(var, bit, val))
+
+#endif /* EMUL */
+
+/*!
+ * @}
+ */ /* end of group SCF */
+
+/*!
+ * @}
+ */ /* end of group Peripheral_access_layer */
+
+#endif /* _FSL_BITACCESS_H */
+
+/******************************************************************************/
diff --git a/include/soc/imx8/imx8qm/lpcg.h b/include/soc/imx8/imx8qm/lpcg.h
new file mode 100644
index 000000000000..220f23369326
--- /dev/null
+++ b/include/soc/imx8/imx8qm/lpcg.h
@@ -0,0 +1,201 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017 NXP
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef _SC_LPCG_H
+#define _SC_LPCG_H
+
+/*LSIO SS */
+#define PWM_0_LPCG 0x5D400000
+#define PWM_1_LPCG 0x5D410000
+#define PWM_2_LPCG 0x5D420000
+#define PWM_3_LPCG 0x5D430000
+#define PWM_4_LPCG 0x5D440000
+#define PWM_5_LPCG 0x5D450000
+#define PWM_6_LPCG 0x5D460000
+#define PWM_7_LPCG 0x5D470000
+#define GPIO_0_LPCG 0x5D480000
+#define GPIO_1_LPCG 0x5D490000
+#define GPIO_2_LPCG 0x5D4A0000
+#define GPIO_3_LPCG 0x5D4B0000
+#define GPIO_4_LPCG 0x5D4C0000
+#define GPIO_5_LPCG 0x5D4D0000
+#define GPIO_6_LPCG 0x5D4E0000
+#define GPIO_7_LPCG 0x5D4F0000
+#define FSPI_0_LPCG 0x5D520000
+#define FSPI_1_LPCG 0x5D530000
+#define GPT_0_LPCG 0x5D540000
+#define GPT_1_LPCG 0x5D550000
+#define GPT_2_LPCG 0x5D560000
+#define GPT_3_LPCG 0x5D570000
+#define GPT_4_LPCG 0x5D580000
+#define OCRAM_LPCG 0x5D590000
+#define KPP_LPCG 0x5D5A0000
+#define MU_5A_LPCG 0x5D600000
+#define MU_6A_LPCG 0x5D610000
+#define MU_7A_LPCG 0x5D620000
+#define MU_8A_LPCG 0x5D630000
+#define MU_9A_LPCG 0x5D640000
+#define MU_10A_LPCG 0x5D650000
+#define MU_11A_LPCG 0x5D660000
+#define MU_12A_LPCG 0x5D670000
+#define MU_13A_LPCG 0x5D680000
+
+/* HSIO SS */
+#define CRR_5_LPCG 0x5F0F0000
+#define CRR_4_LPCG 0x5F0E0000
+#define CRR_3_LPCG 0x5F0D0000
+#define CRR_2_LPCG 0x5F0C0000
+#define CRR_1_LPCG 0x5F0B0000
+#define CRR_0_LPCG 0x5F0A0000
+#define PHY_1_LPCG 0x5F090000
+#define PHY_2_LPCG 0x5F080000
+#define SATA_0_LPCG 0x5F070000
+#define PCIE_B_LPCG 0x5F060000
+#define PCIE_A_LPCG 0x5F050000
+
+/* DMA SS */
+#define FLEX_CAN_2_LPCG 0x5ACF0000
+#define FLEX_CAN_1_LPCG 0x5ACE0000
+#define FLEX_CAN_0_LPCG 0x5ACD0000
+#define FTM_1_LPCG 0x5ACB0000
+#define FTM_0_LPCG 0x5ACA0000
+#define ADC_1_LPCG 0x5AC90000
+#define ADC_0_LPCG 0x5AC80000
+#define LPI2C_4_LPCG 0x5AC40000
+#define LPI2C_3_LPCG 0x5AC30000
+#define LPI2C_2_LPCG 0x5AC20000
+#define LPI2C_1_LPCG 0x5AC10000
+#define LPI2C_0_LPCG 0x5AC00000
+#define EMVSIM_1_LPCG 0x5A4E0000
+#define EMVSIM_0_LPCG 0x5A4D0000
+#define LPUART_4_LPCG 0x5A4A0000
+#define LPUART_3_LPCG 0x5A490000
+#define LPUART_2_LPCG 0x5A480000
+#define LPUART_1_LPCG 0x5A470000
+#define LPUART_0_LPCG 0x5A460000
+#define LPSPI_3_LPCG 0x5A430000
+#define LPSPI_2_LPCG 0x5A420000
+#define LPSPI_1_LPCG 0x5A410000
+#define LPSPI_0_LPCG 0x5A400000
+
+/* Display SS */
+#define DC_0_LPCG 0x56010000
+#define DC_1_LPCG 0x57010000
+
+/* LVDS */
+#define DI_LVDS_0_LPCG 0x56243000
+#define DI_LVDS_1_LPCG 0x57243000
+
+/* DI HDMI */
+#define DI_HDMI_LPCG 0x56263000
+
+/* RX-HDMI */
+#define RX_HDMI_LPCG 0x58263000
+
+/* MIPI CSI SS */
+#define MIPI_CSI_0_LPCG 0x58223000
+#define MIPI_CSI_1_LPCG 0x58243000
+
+/* MIPI DSI SS */
+#define MIPI_DSI_0_LPCG 0x56223000
+#define MIPI_DSI_1_LPCG 0x57223000
+
+/* Imaging SS */
+#define IMG_JPEG_ENC_LPCG 0x585F0000
+#define IMG_JPEG_DEC_LPCG 0x585D0000
+#define IMG_PXL_LINK_DC1_LPCG 0x585C0000
+#define IMG_PXL_LINK_DC0_LPCG 0x585B0000
+#define IMG_PXL_LINK_HDMI_LPCG 0x585A0000
+#define IMG_PXL_LINK_CSI1_LPCG 0x58590000
+#define IMG_PXL_LINK_CSI0_LPCG 0x58580000
+#define IMG_PDMA_7_LPCG 0x58570000
+#define IMG_PDMA_6_LPCG 0x58560000
+#define IMG_PDMA_5_LPCG 0x58550000
+#define IMG_PDMA_4_LPCG 0x58540000
+#define IMG_PDMA_3_LPCG 0x58530000
+#define IMG_PDMA_2_LPCG 0x58520000
+#define IMG_PDMA_1_LPCG 0x58510000
+#define IMG_PDMA_0_LPCG 0x58500000
+
+/* HSIO SS */
+#define HSIO_GPIO_LPCG 0x5F100000
+#define HSIO_MISC_LPCG 0x5F0F0000
+#define HSIO_SATA_CRR4_LPCG 0x5F0E0000
+#define HSIO_PCIE_X1_CRR3_LPCG 0x5F0D0000
+#define HSIO_PCIE_X2_CRR2_LPCG 0x5F0C0000
+#define HSIO_PHY_X1_CRR1_LPCG 0x5F0B0000
+#define HSIO_PHY_X2_CRR0_LPCG 0x5F0A0000
+#define HSIO_PHY_X1_LPCG 0x5F090000
+#define HSIO_PHY_X2_LPCG 0x5F080000
+#define HSIO_SATA_LPCG 0x5F070000
+#define HSIO_PCIE_X1_LPCG 0x5F060000
+#define HSIO_PCIE_X2_LPCG 0x5F050000
+
+/* M4 SS */
+#define M4_0_I2C_LPCG 0x37630000
+#define M4_0_LPUART_LPCG 0x37620000
+#define M4_0_LPIT_LPCG 0x37610000
+#define M4_1_I2C_LPCG 0x3B630000
+#define M4_1_LPUART_LPCG 0x3B620000
+#define M4_1_LPIT_LPCG 0x3B610000
+
+/* Audio SS */
+#define AUD_ASRC_0_LPCG 0x59400000
+#define AUD_ESAI_0_LPCG 0x59410000
+#define AUD_SPDIF_0_LPCG 0x59420000
+#define AUD_SPDIF_1_LPCG 0x59430000
+#define AUD_SAI_0_LPCG 0x59440000
+#define AUD_SAI_1_LPCG 0x59450000
+#define AUD_SAI_2_LPCG 0x59460000
+#define AUD_SAI_3_LPCG 0x59470000
+#define AUD_HDMI_RX_SAI_0_LPCG 0x59480000
+#define AUD_HDMI_TX_SAI_0_LPCG 0x59490000
+#define AUD_GPT_5_LPCG 0x594B0000
+#define AUD_GPT_6_LPCG 0x594C0000
+#define AUD_GPT_7_LPCG 0x594D0000
+#define AUD_GPT_8_LPCG 0x594E0000
+#define AUD_GPT_9_LPCG 0x594F0000
+#define AUD_GPT_10_LPCG 0x59500000
+#define AUD_DSP_LPCG 0x59580000
+#define AUD_OCRAM_LPCG 0x59590000
+#define AUD_EDMA_0_LPCG 0x595f0000
+#define AUD_ASRC_1_LPCG 0x59c00000
+#define AUD_ESAI_1_LPCG 0x59c10000
+#define AUD_SAI_6_LPCG 0x59c20000
+#define AUD_SAI_7_LPCG 0x59c30000
+#define AUD_AMIX_LPCG 0x59c40000
+#define AUD_MQS_LPCG 0x59c50000
+#define AUD_ACM_LPCG 0x59c60000
+#define AUD_REC_CLK0_LPCG 0x59d00000
+#define AUD_REC_CLK1_LPCG 0x59d10000
+#define AUD_PLL_CLK0_LPCG 0x59d20000
+#define AUD_PLL_CLK1_LPCG 0x59d30000
+#define AUD_MCLKOUT0_LPCG 0x59d50000
+#define AUD_MCLKOUT1_LPCG 0x59d60000
+#define AUD_EDMA_1_LPCG 0x59df0000
+
+
+/* Connectivity SS */
+#define USDHC_0_LPCG 0x5B200000
+#define USDHC_1_LPCG 0x5B210000
+#define USDHC_2_LPCG 0x5B220000
+#define ENET_0_LPCG 0x5B230000
+#define ENET_1_LPCG 0x5B240000
+#define DTCP_LPCG 0x5B250000
+#define MLB_LPCG 0x5B260000
+#define USB_2_LPCG 0x5B270000
+#define USB_3_LPCG 0x5B280000
+#define NAND_LPCG 0x5B290000
+#define EDMA_LPCG 0x5B2A0000
+
+/* CM40 SS */
+#define CM40_I2C_LPCG 0x37630000
+
+/* CM41 SS */
+#define CM41_I2C_LPCG 0x3B630000
+
+#endif
diff --git a/include/soc/imx8/imx8qxp/lpcg.h b/include/soc/imx8/imx8qxp/lpcg.h
new file mode 100644
index 000000000000..79b774d825ba
--- /dev/null
+++ b/include/soc/imx8/imx8qxp/lpcg.h
@@ -0,0 +1,196 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017-2018 NXP
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef _SC_LPCG_H
+#define _SC_LPCG_H
+
+/*LSIO SS */
+#define PWM_0_LPCG 0x5D400000
+#define PWM_1_LPCG 0x5D410000
+#define PWM_2_LPCG 0x5D420000
+#define PWM_3_LPCG 0x5D430000
+#define PWM_4_LPCG 0x5D440000
+#define PWM_5_LPCG 0x5D450000
+#define PWM_6_LPCG 0x5D460000
+#define PWM_7_LPCG 0x5D470000
+#define GPIO_0_LPCG 0x5D480000
+#define GPIO_1_LPCG 0x5D490000
+#define GPIO_2_LPCG 0x5D4A0000
+#define GPIO_3_LPCG 0x5D4B0000
+#define GPIO_4_LPCG 0x5D4C0000
+#define GPIO_5_LPCG 0x5D4D0000
+#define GPIO_6_LPCG 0x5D4E0000
+#define GPIO_7_LPCG 0x5D4F0000
+#define FSPI_0_LPCG 0x5D520000
+#define FSPI_1_LPCG 0x5D530000
+#define GPT_0_LPCG 0x5D540000
+#define GPT_1_LPCG 0x5D550000
+#define GPT_2_LPCG 0x5D560000
+#define GPT_3_LPCG 0x5D570000
+#define GPT_4_LPCG 0x5D580000
+#define OCRAM_LPCG 0x5D590000
+#define KPP_LPCG 0x5D5A0000
+#define ROMCP_LPCG 0x5D500000
+#define MU_5A_LPCG 0x5D600000
+#define MU_6A_LPCG 0x5D610000
+#define MU_7A_LPCG 0x5D620000
+#define MU_8A_LPCG 0x5D630000
+#define MU_9A_LPCG 0x5D640000
+#define MU_10A_LPCG 0x5D650000
+#define MU_11A_LPCG 0x5D660000
+#define MU_12A_LPCG 0x5D670000
+#define MU_13A_LPCG 0x5D680000
+
+/* HSIO SS */
+#define CRR_5_LPCG 0x5F0F0000
+#define CRR_4_LPCG 0x5F0E0000
+#define CRR_3_LPCG 0x5F0D0000
+#define CRR_2_LPCG 0x5F0C0000
+#define CRR_1_LPCG 0x5F0B0000
+#define CRR_0_LPCG 0x5F0A0000
+#define PHY_1_LPCG 0x5F090000
+#define PHY_2_LPCG 0x5F080000
+#define SATA_0_LPCG 0x5F070000
+#define PCIE_B_LPCG 0x5F060000
+#define PCIE_A_LPCG 0x5F050000
+
+/* DMA SS */
+#define FLEX_CAN_2_LPCG 0x5ACF0000
+#define FLEX_CAN_1_LPCG 0x5ACE0000
+#define FLEX_CAN_0_LPCG 0x5ACD0000
+#define FTM_1_LPCG 0x5ACB0000
+#define FTM_0_LPCG 0x5ACA0000
+#define ADC_0_LPCG 0x5AC80000
+#define LPI2C_3_LPCG 0x5AC30000
+#define LPI2C_2_LPCG 0x5AC20000
+#define LPI2C_1_LPCG 0x5AC10000
+#define LPI2C_0_LPCG 0x5AC00000
+#define PWM_LPCG 0x5A590000
+#define LCD_LPCG 0x5A580000
+#define LPUART_3_LPCG 0x5A490000
+#define LPUART_2_LPCG 0x5A480000
+#define LPUART_1_LPCG 0x5A470000
+#define LPUART_0_LPCG 0x5A460000
+#define LPSPI_3_LPCG 0x5A430000
+#define LPSPI_2_LPCG 0x5A420000
+#define LPSPI_1_LPCG 0x5A410000
+#define LPSPI_0_LPCG 0x5A400000
+
+/* Display SS */
+#define DC_0_LPCG 0x56010000
+#define DC_1_LPCG 0x57010000
+
+/* LVDS */
+#define DI_LVDS_0_LPCG 0x56243000
+#define DI_LVDS_1_LPCG 0x57243000
+
+/* DI HDMI */
+#define DI_HDMI_LPCG 0x56263000
+
+/* RX-HDMI */
+#define RX_HDMI_LPCG 0x58263000
+
+/* MIPI CSI SS */
+#define MIPI_CSI_0_LPCG 0x58223000
+#define MIPI_CSI_1_LPCG 0x58243000
+
+/* PARALLEL CSI SS */
+#define PARALLEL_CSI_LPCG 0x58263000
+
+/* Display MIPI SS */
+#define DI_MIPI0_LPCG 0x56223000
+#define DI_MIPI1_LPCG 0x56243000
+
+/* Imaging SS */
+#define IMG_JPEG_ENC_LPCG 0x585F0000
+#define IMG_JPEG_DEC_LPCG 0x585D0000
+#define IMG_PXL_LINK_DC1_LPCG 0x585C0000
+#define IMG_PXL_LINK_DC0_LPCG 0x585B0000
+#define IMG_PXL_LINK_HDMI_LPCG 0x585A0000
+#define IMG_PXL_LINK_CSI1_LPCG 0x58590000
+#define IMG_PXL_LINK_CSI0_LPCG 0x58580000
+#define IMG_PDMA_7_LPCG 0x58570000
+#define IMG_PDMA_6_LPCG 0x58560000
+#define IMG_PDMA_5_LPCG 0x58550000
+#define IMG_PDMA_4_LPCG 0x58540000
+#define IMG_PDMA_3_LPCG 0x58530000
+#define IMG_PDMA_2_LPCG 0x58520000
+#define IMG_PDMA_1_LPCG 0x58510000
+#define IMG_PDMA_0_LPCG 0x58500000
+
+/* HSIO SS */
+#define HSIO_GPIO_LPCG 0x5F100000
+#define HSIO_MISC_LPCG 0x5F0F0000
+#define HSIO_SATA_CRR4_LPCG 0x5F0E0000
+#define HSIO_PCIE_X1_CRR3_LPCG 0x5F0D0000
+#define HSIO_PCIE_X2_CRR2_LPCG 0x5F0C0000
+#define HSIO_PHY_X1_CRR1_LPCG 0x5F0B0000
+#define HSIO_PHY_X2_CRR0_LPCG 0x5F0A0000
+#define HSIO_PHY_X1_LPCG 0x5F090000
+#define HSIO_PHY_X2_LPCG 0x5F080000
+#define HSIO_SATA_LPCG 0x5F070000
+#define HSIO_PCIE_X1_LPCG 0x5F060000
+#define HSIO_PCIE_X2_LPCG 0x5F050000
+
+/* M4 SS */
+#define M4_0_I2C_LPCG 0x37630000
+#define M4_0_LPUART_LPCG 0x37620000
+#define M4_0_LPIT_LPCG 0x37610000
+#define M4_1_I2C_LPCG 0x3B630000
+#define M4_1_LPUART_LPCG 0x3B620000
+#define M4_1_LPIT_LPCG 0x3B610000
+
+/* Audio SS */
+#define AUD_ASRC_0_LPCG 0x59400000
+#define AUD_ESAI_0_LPCG 0x59410000
+#define AUD_SPDIF_0_LPCG 0x59420000
+#define AUD_SAI_0_LPCG 0x59440000
+#define AUD_SAI_1_LPCG 0x59450000
+#define AUD_SAI_2_LPCG 0x59460000
+#define AUD_SAI_3_LPCG 0x59470000
+#define AUD_GPT_5_LPCG 0x594B0000
+#define AUD_GPT_6_LPCG 0x594C0000
+#define AUD_GPT_7_LPCG 0x594D0000
+#define AUD_GPT_8_LPCG 0x594E0000
+#define AUD_GPT_9_LPCG 0x594F0000
+#define AUD_GPT_10_LPCG 0x59500000
+#define AUD_DSP_LPCG 0x59580000
+#define AUD_OCRAM_LPCG 0x59590000
+#define AUD_EDMA_0_LPCG 0x595f0000
+#define AUD_ASRC_1_LPCG 0x59c00000
+#define AUD_SAI_4_LPCG 0x59c20000
+#define AUD_SAI_5_LPCG 0x59c30000
+#define AUD_AMIX_LPCG 0x59c40000
+#define AUD_MQS_LPCG 0x59c50000
+#define AUD_ACM_LPCG 0x59c60000
+#define AUD_REC_CLK0_LPCG 0x59d00000
+#define AUD_REC_CLK1_LPCG 0x59d10000
+#define AUD_PLL_CLK0_LPCG 0x59d20000
+#define AUD_PLL_CLK1_LPCG 0x59d30000
+#define AUD_MCLKOUT0_LPCG 0x59d50000
+#define AUD_MCLKOUT1_LPCG 0x59d60000
+#define AUD_EDMA_1_LPCG 0x59df0000
+
+
+/* Connectivity SS */
+#define USDHC_0_LPCG 0x5B200000
+#define USDHC_1_LPCG 0x5B210000
+#define USDHC_2_LPCG 0x5B220000
+#define ENET_0_LPCG 0x5B230000
+#define ENET_1_LPCG 0x5B240000
+#define DTCP_LPCG 0x5B250000
+#define MLB_LPCG 0x5B260000
+#define USB_2_LPCG 0x5B270000
+#define USB_3_LPCG 0x5B280000
+#define NAND_LPCG 0x5B290000
+#define EDMA_LPCG 0x5B2A0000
+
+/* CM40 SS */
+#define CM40_I2C_LPCG 0x37630000
+
+
+#endif
diff --git a/include/soc/imx8/sc/ipc.h b/include/soc/imx8/sc/ipc.h
new file mode 100644
index 000000000000..de55ce73fbeb
--- /dev/null
+++ b/include/soc/imx8/sc/ipc.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017-2019 NXP
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+/*!
+ * Header file for the IPC implementation.
+ */
+
+#ifndef SC_IPC_H
+#define SC_IPC_H
+
+/* Includes */
+
+#include <linux/thermal.h>
+#include <soc/imx8/sc/types.h>
+
+/* Defines */
+
+/* Types */
+
+/* Functions */
+
+/*!
+ * This function opens an IPC channel.
+ *
+ * @param[out] ipc return pointer for ipc handle
+ * @param[in] id id of channel to open
+ *
+ * @return Returns an error code (SC_ERR_NONE = success, SC_ERR_IPC
+ * otherwise).
+ *
+ * The \a id parameter is implementation specific. Could be an MU
+ * address, pointer to a driver path, channel index, etc.
+ */
+sc_err_t sc_ipc_open(sc_ipc_t *ipc, sc_ipc_id_t id);
+
+/*!
+ * This function closes an IPC channel.
+ *
+ * @param[in] ipc id of channel to close
+ */
+void sc_ipc_close(sc_ipc_t ipc);
+
+/*!
+ * This function reads a message from an IPC channel.
+ *
+ * @param[in] ipc id of channel read from
+ * @param[out] data pointer to message buffer to read
+ *
+ * This function will block if no message is available to be read.
+ */
+void sc_ipc_read(sc_ipc_t ipc, void *data);
+
+/*!
+ * This function writes a message to an IPC channel.
+ *
+ * @param[in] ipc id of channel to write to
+ * @param[in] data pointer to message buffer to write
+ *
+ * This function will block if the outgoing buffer is full.
+ */
+void sc_ipc_write(sc_ipc_t ipc, const void *data);
+
+int register_scu_notifier(struct notifier_block *nb);
+int unregister_scu_notifier(struct notifier_block *nb);
+
+#endif /* SC_IPC_H */
+
diff --git a/include/soc/imx8/sc/scfw.h b/include/soc/imx8/sc/scfw.h
new file mode 100644
index 000000000000..3c77c69f7f89
--- /dev/null
+++ b/include/soc/imx8/sc/scfw.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017 NXP
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef _SC_SCFW_H
+#define _SC_SCFW_H
+
+#include <linux/types.h>
+
+/*!
+ * This type is used to declare a handle for an IPC communication
+ * channel. Its meaning is specific to the IPC implementation.
+ */
+typedef uint32_t sc_ipc_t;
+
+/*!
+ * This type is used to declare an ID for an IPC communication
+ * channel. Its meaning is specific to the IPC implementation.
+ */
+typedef uint32_t sc_ipc_id_t;
+
+/*!
+ * This function returns the MU channel ID for this implementation
+ *
+ * @param[in] ipc pointer to Mu channel ID
+ * @return Returns an error code (SC_ERR_NONE = success, SC_ERR_IPC
+ * otherwise).
+ */
+int sc_ipc_getMuID(uint32_t *mu_id);
+
+#endif
diff --git a/include/soc/imx8/sc/sci.h b/include/soc/imx8/sc/sci.h
new file mode 100644
index 000000000000..004ad078091f
--- /dev/null
+++ b/include/soc/imx8/sc/sci.h
@@ -0,0 +1,42 @@
+/*==========================================================================*/
+/*!
+ * @file sci.h
+ *
+ * Header file containing the public System Controller Interface (SCI)
+ * definitions.
+ *
+ *
+ * @{
+ */
+/*==========================================================================*/
+
+#ifndef _SC_SCI_H
+#define _SC_SCI_H
+
+/* Defines */
+
+#define SC_NUM_IPC 5
+
+/* Includes */
+
+#include <soc/imx8/sc/ipc.h>
+#include <soc/imx8/sc/svc/misc/api.h>
+#include <soc/imx8/sc/svc/pad/api.h>
+#include <soc/imx8/sc/svc/pm/api.h>
+#include <soc/imx8/sc/svc/rm/api.h>
+#include <soc/imx8/sc/svc/timer/api.h>
+
+/* Types */
+
+/* Functions */
+/*!
+ * This function initializes the MU connection to SCU.
+ *
+ * @return Returns an error code.
+ */
+int imx8_mu_init(void);
+
+#endif /* _SC_SCI_H */
+
+/**@}*/
+
diff --git a/include/soc/imx8/sc/svc/irq/api.h b/include/soc/imx8/sc/svc/irq/api.h
new file mode 100644
index 000000000000..4df7b9c735ca
--- /dev/null
+++ b/include/soc/imx8/sc/svc/irq/api.h
@@ -0,0 +1,173 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017-2019 NXP
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+/*!
+ * Header file containing the public API for the System Controller (SC)
+ * Interrupt (IRQ) function.
+ *
+ * @addtogroup IRQ_SVC (SVC) Interrupt Service
+ *
+ * Module for the Interrupt (IRQ) service.
+ *
+ * @{
+ */
+
+#ifndef SC_IRQ_API_H
+#define SC_IRQ_API_H
+
+/* Includes */
+
+#include <soc/imx8/sc/types.h>
+
+/* Defines */
+
+#define SC_IRQ_NUM_GROUP 7U /* Number of groups */
+
+/*!
+ * @name Defines for sc_irq_group_t
+ */
+/*@{*/
+#define SC_IRQ_GROUP_TEMP 0U /* Temp interrupts */
+#define SC_IRQ_GROUP_WDOG 1U /* Watchdog interrupts */
+#define SC_IRQ_GROUP_RTC 2U /* RTC interrupts */
+#define SC_IRQ_GROUP_WAKE 3U /* Wakeup interrupts */
+#define SC_IRQ_GROUP_SYSCTR 4U /* System counter interrupts */
+#define SC_IRQ_GROUP_REBOOTED 5U /* Partition reboot complete */
+#define SC_IRQ_GROUP_REBOOT 6U /* Partition reboot starting */
+/*@}*/
+
+/*!
+ * @name Defines for sc_irq_temp_t
+ */
+/*@{*/
+#define SC_IRQ_TEMP_HIGH (1UL << 0U) /* Temp alarm interrupt */
+#define SC_IRQ_TEMP_CPU0_HIGH (1UL << 1U) /* CPU0 temp alarm interrupt */
+#define SC_IRQ_TEMP_CPU1_HIGH (1UL << 2U) /* CPU1 temp alarm interrupt */
+#define SC_IRQ_TEMP_GPU0_HIGH (1UL << 3U) /* GPU0 temp alarm interrupt */
+#define SC_IRQ_TEMP_GPU1_HIGH (1UL << 4U) /* GPU1 temp alarm interrupt */
+#define SC_IRQ_TEMP_DRC0_HIGH (1UL << 5U) /* DRC0 temp alarm interrupt */
+#define SC_IRQ_TEMP_DRC1_HIGH (1UL << 6U) /* DRC1 temp alarm interrupt */
+#define SC_IRQ_TEMP_VPU_HIGH (1UL << 7U) /* DRC1 temp alarm interrupt */
+#define SC_IRQ_TEMP_PMIC0_HIGH (1UL << 8U) /* PMIC0 temp alarm interrupt */
+#define SC_IRQ_TEMP_PMIC1_HIGH (1UL << 9U) /* PMIC1 temp alarm interrupt */
+#define SC_IRQ_TEMP_LOW (1UL << 10U) /* Temp alarm interrupt */
+#define SC_IRQ_TEMP_CPU0_LOW (1UL << 11U) /* CPU0 temp alarm interrupt */
+#define SC_IRQ_TEMP_CPU1_LOW (1UL << 12U) /* CPU1 temp alarm interrupt */
+#define SC_IRQ_TEMP_GPU0_LOW (1UL << 13U) /* GPU0 temp alarm interrupt */
+#define SC_IRQ_TEMP_GPU1_LOW (1UL << 14U) /* GPU1 temp alarm interrupt */
+#define SC_IRQ_TEMP_DRC0_LOW (1UL << 15U) /* DRC0 temp alarm interrupt */
+#define SC_IRQ_TEMP_DRC1_LOW (1UL << 16U) /* DRC1 temp alarm interrupt */
+#define SC_IRQ_TEMP_VPU_LOW (1UL << 17U) /* DRC1 temp alarm interrupt */
+#define SC_IRQ_TEMP_PMIC0_LOW (1UL << 18U) /* PMIC0 temp alarm interrupt */
+#define SC_IRQ_TEMP_PMIC1_LOW (1UL << 19U) /* PMIC1 temp alarm interrupt */
+#define SC_IRQ_TEMP_PMIC2_HIGH (1UL << 20U) /* PMIC2 temp alarm interrupt */
+#define SC_IRQ_TEMP_PMIC2_LOW (1UL << 21U) /* PMIC2 temp alarm interrupt */
+/*@}*/
+
+/*!
+ * @name Defines for sc_irq_wdog_t
+ */
+/*@{*/
+#define SC_IRQ_WDOG (1U << 0U) /* Watchdog interrupt */
+/*@}*/
+
+/*!
+ * @name Defines for sc_irq_rtc_t
+ */
+/*@{*/
+#define SC_IRQ_RTC (1U << 0U) /* RTC interrupt */
+/*@}*/
+
+/*!
+ * @name Defines for sc_irq_wake_t
+ */
+/*@{*/
+#define SC_IRQ_BUTTON (1U << 0U) /* Button interrupt */
+#define SC_IRQ_PAD (1U << 1U) /* Pad wakeup */
+#define SC_IRQ_USR1 (1U << 2U) /* User defined 1 */
+#define SC_IRQ_USR2 (1U << 3U) /* User defined 2 */
+#define SC_IRQ_BC_PAD (1U << 4U) /* Pad wakeup (broadcast to all partitions) */
+/*@}*/
+
+/*!
+ * @name Defines for sc_irq_sysctr_t
+ */
+/*@{*/
+#define SC_IRQ_SYSCTR (1U << 0U) /* SYSCTR interrupt */
+/*@}*/
+
+/* Types */
+
+/*!
+ * This type is used to declare an interrupt group.
+ */
+typedef uint8_t sc_irq_group_t;
+
+/*!
+ * This type is used to declare a bit mask of temp interrupts.
+ */
+typedef uint8_t sc_irq_temp_t;
+
+/*!
+ * This type is used to declare a bit mask of watchdog interrupts.
+ */
+typedef uint8_t sc_irq_wdog_t;
+
+/*!
+ * This type is used to declare a bit mask of RTC interrupts.
+ */
+typedef uint8_t sc_irq_rtc_t;
+
+/*!
+ * This type is used to declare a bit mask of wakeup interrupts.
+ */
+typedef uint8_t sc_irq_wake_t;
+
+/* Functions */
+
+/*!
+ * This function enables/disables interrupts. If pending interrupts
+ * are unmasked, an interrupt will be triggered.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] resource MU channel
+ * @param[in] group group the interrupts are in
+ * @param[in] mask mask of interrupts to affect
+ * @param[in] enable state to change interrupts to
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors:
+ * - SC_PARM if group invalid
+ */
+sc_err_t sc_irq_enable(sc_ipc_t ipc, sc_rsrc_t resource,
+ sc_irq_group_t group, uint32_t mask, sc_bool_t enable);
+
+/*!
+ * This function returns the current interrupt status (regardless if
+ * masked). Automatically clears pending interrupts.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] resource MU channel
+ * @param[in] group groups the interrupts are in
+ * @param[in] status status of interrupts
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors:
+ * - SC_PARM if group invalid
+ *
+ * The returned \a status may show interrupts pending that are
+ * currently masked.
+ */
+sc_err_t sc_irq_status(sc_ipc_t ipc, sc_rsrc_t resource,
+ sc_irq_group_t group, uint32_t *status);
+
+#endif /* SC_IRQ_API_H */
+
+/**@}*/
+
diff --git a/include/soc/imx8/sc/svc/misc/api.h b/include/soc/imx8/sc/svc/misc/api.h
new file mode 100644
index 000000000000..d5e9bfa35f26
--- /dev/null
+++ b/include/soc/imx8/sc/svc/misc/api.h
@@ -0,0 +1,547 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017-2019 NXP
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+/*!
+ * Header file containing the public API for the System Controller (SC)
+ * Miscellaneous (MISC) function.
+ *
+ * @addtogroup MISC_SVC (SVC) Miscellaneous Service
+ *
+ * Module for the Miscellaneous (MISC) service.
+ *
+ * @{
+ */
+
+#ifndef SC_MISC_API_H
+#define SC_MISC_API_H
+
+/* Includes */
+
+#include <soc/imx8/sc/types.h>
+#include <soc/imx8/sc/svc/rm/api.h>
+
+/* Defines */
+
+/*!
+ * @name Defines for type widths
+ */
+/*@{*/
+#define SC_MISC_DMA_GRP_W 5U /* Width of sc_misc_dma_group_t */
+/*@}*/
+
+/*! Max DMA channel priority group */
+#define SC_MISC_DMA_GRP_MAX 31U
+
+/*!
+ * @name Defines for sc_misc_boot_status_t
+ */
+/*@{*/
+#define SC_MISC_BOOT_STATUS_SUCCESS 0U /* Success */
+#define SC_MISC_BOOT_STATUS_SECURITY 1U /* Security violation */
+/*@}*/
+
+/*!
+ * @name Defines for sc_misc_temp_t
+ */
+/*@{*/
+#define SC_MISC_TEMP 0U /* Temp sensor */
+#define SC_MISC_TEMP_HIGH 1U /* Temp high alarm */
+#define SC_MISC_TEMP_LOW 2U /* Temp low alarm */
+/*@}*/
+
+/*!
+ * @name Defines for sc_misc_seco_auth_cmd_t
+ */
+/*@{*/
+#define SC_MISC_AUTH_CONTAINER 0U /* Authenticate container */
+#define SC_MISC_VERIFY_IMAGE 1U /* Verify image */
+#define SC_MISC_REL_CONTAINER 2U /* Release container */
+#define SC_MISC_SECO_AUTH_SECO_FW 3U /* SECO Firmware */
+#define SC_MISC_SECO_AUTH_HDMI_TX_FW 4U /* HDMI TX Firmware */
+#define SC_MISC_SECO_AUTH_HDMI_RX_FW 5U /* HDMI RX Firmware */
+/*@}*/
+
+/*!
+ * @name Defines for sc_misc_bt_t
+ */
+/*@{*/
+#define SC_MISC_BT_PRIMARY 0U /* Primary boot */
+#define SC_MISC_BT_SECONDARY 1U /* Secondary boot */
+#define SC_MISC_BT_RECOVERY 2U /* Recovery boot */
+#define SC_MISC_BT_MANUFACTURE 3U /* Manufacture boot */
+#define SC_MISC_BT_SERIAL 4U /* Serial boot */
+/*@}*/
+
+/* Types */
+
+/*!
+ * This type is used to store a DMA channel priority group.
+ */
+typedef uint8_t sc_misc_dma_group_t;
+
+/*!
+ * This type is used report boot status.
+ */
+typedef uint8_t sc_misc_boot_status_t;
+
+/*!
+ * This type is used to issue SECO authenticate commands.
+ */
+typedef uint8_t sc_misc_seco_auth_cmd_t;
+
+/*!
+ * This type is used report boot status.
+ */
+typedef uint8_t sc_misc_temp_t;
+
+/*!
+ * This type is used report the boot type.
+ */
+typedef uint8_t sc_misc_bt_t;
+
+/* Functions */
+
+/*!
+ * @name Control Functions
+ * @{
+ */
+
+/*!
+ * This function sets a miscellaneous control value.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] resource resource the control is associated with
+ * @param[in] ctrl control to change
+ * @param[in] val value to apply to the control
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors:
+ * - SC_PARM if arguments out of range or invalid,
+ * - SC_ERR_NOACCESS if caller's partition is not the resource owner or parent
+ * of the owner
+ *
+ * Refer to the [Control List](@ref CONTROLS) for valid control values.
+ */
+sc_err_t sc_misc_set_control(sc_ipc_t ipc, sc_rsrc_t resource,
+ sc_ctrl_t ctrl, uint32_t val);
+
+/*!
+ * This function gets a miscellaneous control value.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] resource resource the control is associated with
+ * @param[in] ctrl control to get
+ * @param[out] val pointer to return the control value
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors:
+ * - SC_PARM if arguments out of range or invalid,
+ * - SC_ERR_NOACCESS if caller's partition is not the resource owner or parent
+ * of the owner
+ *
+ * Refer to the [Control List](@ref CONTROLS) for valid control values.
+ */
+sc_err_t sc_misc_get_control(sc_ipc_t ipc, sc_rsrc_t resource,
+ sc_ctrl_t ctrl, uint32_t *val);
+
+/* @} */
+
+/*!
+ * @name DMA Functions
+ * @{
+ */
+
+/*!
+ * This function configures the max DMA channel priority group for a
+ * partition.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] pt handle of partition to assign \a max
+ * @param[in] max max priority group (0-31)
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors:
+ * - SC_PARM if arguments out of range or invalid,
+ * - SC_ERR_NOACCESS if caller's partition is not the parent
+ * of the affected partition
+ *
+ * Valid \a max range is 0-31 with 0 being the lowest and 31 the highest.
+ * Default is the max priority group for the parent partition of \a pt.
+ */
+sc_err_t sc_misc_set_max_dma_group(sc_ipc_t ipc, sc_rm_pt_t pt,
+ sc_misc_dma_group_t max);
+
+/*!
+ * This function configures the priority group for a DMA channel.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] resource DMA channel resource
+ * @param[in] group priority group (0-31)
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors:
+ * - SC_PARM if arguments out of range or invalid,
+ * - SC_ERR_NOACCESS if caller's partition is not the owner or parent
+ * of the owner of the DMA channel
+ *
+ * Valid \a group range is 0-31 with 0 being the lowest and 31 the highest.
+ * The max value of \a group is limited by the partition max set using
+ * sc_misc_set_max_dma_group().
+ */
+sc_err_t sc_misc_set_dma_group(sc_ipc_t ipc, sc_rsrc_t resource,
+ sc_misc_dma_group_t group);
+
+/* @} */
+
+/*!
+ * @name Security Functions
+ * @{
+ */
+
+/*!
+ * @deprecated Use sc_seco_image_load() instead.
+ */
+sc_err_t sc_misc_seco_image_load(sc_ipc_t ipc, sc_faddr_t addr_src,
+ sc_faddr_t addr_dst, uint32_t len, sc_bool_t fw);
+
+/*!
+ * @deprecated Use sc_seco_authenticate() instead.
+ */
+sc_err_t sc_misc_seco_authenticate(sc_ipc_t ipc,
+ sc_misc_seco_auth_cmd_t cmd, sc_faddr_t addr);
+
+/*!
+ * @deprecated Use sc_seco_fuse_write() instead.
+ */
+sc_err_t sc_misc_seco_fuse_write(sc_ipc_t ipc, sc_faddr_t addr);
+
+/*!
+ * @deprecated Use sc_seco_enable_debug() instead.
+ */
+sc_err_t sc_misc_seco_enable_debug(sc_ipc_t ipc, sc_faddr_t addr);
+
+/*!
+ * @deprecated Use sc_seco_forward_lifecycle() instead.
+ */
+sc_err_t sc_misc_seco_forward_lifecycle(sc_ipc_t ipc, uint32_t change);
+
+/*!
+ * @deprecated Use sc_seco_return_lifecycle() instead.
+ */
+sc_err_t sc_misc_seco_return_lifecycle(sc_ipc_t ipc, sc_faddr_t addr);
+
+/*!
+ * @deprecated Use sc_seco_build_info() instead.
+ */
+void sc_misc_seco_build_info(sc_ipc_t ipc, uint32_t *version,
+ uint32_t *commit);
+
+/*!
+ * @deprecated Use sc_seco_chip_info() instead.
+ */
+sc_err_t sc_misc_seco_chip_info(sc_ipc_t ipc, uint16_t *lc,
+ uint16_t *monotonic, uint32_t *uid_l, uint32_t *uid_h);
+
+/*!
+ * @deprecated Use sc_seco_attest_mode() instead.
+ */
+sc_err_t sc_misc_seco_attest_mode(sc_ipc_t ipc, uint32_t mode);
+
+/*!
+ * @deprecated Use sc_seco_attest() instead.
+ */
+sc_err_t sc_misc_seco_attest(sc_ipc_t ipc, uint64_t nonce);
+
+/*!
+ * @deprecated Use sc_seco_get_attest_pkey() instead.
+ */
+sc_err_t sc_misc_seco_get_attest_pkey(sc_ipc_t ipc, sc_faddr_t addr);
+
+/*!
+ * @deprecated Use sc_seco_get_attest_sign() instead.
+ */
+sc_err_t sc_misc_seco_get_attest_sign(sc_ipc_t ipc, sc_faddr_t addr);
+
+/*!
+ * @deprecated Use sc_seco_attest_verify() instead.
+ */
+sc_err_t sc_misc_seco_attest_verify(sc_ipc_t ipc, sc_faddr_t addr);
+
+/*!
+ * @deprecated Use sc_seco_commit() instead.
+ */
+sc_err_t sc_misc_seco_commit(sc_ipc_t ipc, uint32_t *info);
+
+/* @} */
+
+/*!
+ * @name Debug Functions
+ * @{
+ */
+
+/*!
+ * This function is used output a debug character from the SCU UART.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] ch character to output
+ */
+void sc_misc_debug_out(sc_ipc_t ipc, uint8_t ch);
+
+/*!
+ * This function starts/stops emulation waveform capture.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] enable flag to enable/disable capture
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors:
+ * - SC_ERR_UNAVAILABLE if not running on emulation
+ */
+sc_err_t sc_misc_waveform_capture(sc_ipc_t ipc, sc_bool_t enable);
+
+/*!
+ * This function is used to return the SCFW build info.
+ *
+ * @param[in] ipc IPC handle
+ * @param[out] build pointer to return build number
+ * @param[out] commit pointer to return commit ID (git SHA-1)
+ */
+void sc_misc_build_info(sc_ipc_t ipc, uint32_t *build,
+ uint32_t *commit);
+
+/*!
+ * This function is used to return the SCFW API versions.
+ *
+ * @param[in] ipc IPC handle
+ * @param[out] cl_maj pointer to return major part of client version
+ * @param[out] cl_min pointer to return minor part of client version
+ * @param[out] sv_maj pointer to return major part of SCFW version
+ * @param[out] sv_min pointer to return minor part of SCFW version
+ *
+ * Client verion is the version of the API ported to and used by the caller.
+ * SCFW version is the version of the SCFW binary running on the CPU.
+ *
+ * Note a major version difference indicates a break in compatibility.
+ */
+void sc_misc_api_ver(sc_ipc_t ipc, uint16_t *cl_maj,
+ uint16_t *cl_min, uint16_t *sv_maj, uint16_t *sv_min);
+
+/*!
+ * This function is used to return the device's unique ID.
+ *
+ * @param[in] ipc IPC handle
+ * @param[out] id_l pointer to return lower 32-bit of ID [31:0]
+ * @param[out] id_h pointer to return upper 32-bits of ID [63:32]
+ */
+void sc_misc_unique_id(sc_ipc_t ipc, uint32_t *id_l,
+ uint32_t *id_h);
+
+/* @} */
+
+/*!
+ * @name Other Functions
+ * @{
+ */
+
+/*!
+ * This function configures the ARI match value for PCIe/SATA resources.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] resource match resource
+ * @param[in] resource_mst PCIe/SATA master to match
+ * @param[in] ari ARI to match
+ * @param[in] enable enable match or not
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors:
+ * - SC_PARM if arguments out of range or invalid,
+ * - SC_ERR_NOACCESS if caller's partition is not the owner or parent
+ * of the owner of the resource and translation
+ *
+ * For PCIe, the ARI is the 16-bit value that includes the bus number,
+ * device number, and function number. For SATA, this value includes the
+ * FISType and PM_Port.
+ */
+sc_err_t sc_misc_set_ari(sc_ipc_t ipc, sc_rsrc_t resource,
+ sc_rsrc_t resource_mst, uint16_t ari, sc_bool_t enable);
+
+/*!
+ * This function reports boot status.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] status boot status
+ *
+ * This is used by SW partitions to report status of boot. This is
+ * normally used to report a boot failure.
+ */
+void sc_misc_boot_status(sc_ipc_t ipc, sc_misc_boot_status_t status);
+
+/*!
+ * This function tells the SCFW that a CPU is done booting.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] cpu CPU that is done booting
+ *
+ * This is called by early booting CPUs to report they are done with
+ * initialization. After starting early CPUs, the SCFW halts the
+ * booting process until they are done. During this time, early
+ * CPUs can call the SCFW with lower latency as the SCFW is idle.
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors:
+ * - SC_PARM if arguments out of range or invalid,
+ * - SC_ERR_NOACCESS if caller's partition is not the CPU owner
+ */
+sc_err_t sc_misc_boot_done(sc_ipc_t ipc, sc_rsrc_t cpu);
+
+/*!
+ * This function reads a given fuse word index.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] word fuse word index
+ * @param[out] val fuse read value
+ *
+ * @return Returns and error code (SC_ERR_NONE = success).
+ *
+ * Return errors codes:
+ * - SC_ERR_PARM if word fuse index param out of range or invalid
+ * - SC_ERR_NOACCESS if read operation failed
+ * - SC_ERR_LOCKED if read operation is locked
+ */
+sc_err_t sc_misc_otp_fuse_read(sc_ipc_t ipc, uint32_t word, uint32_t *val);
+
+/*!
+ * This function writes a given fuse word index. Only the owner of the
+ * SC_R_SYSTEM resource or a partition with access permissions to
+ * SC_R_SYSTEM can do this.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] word fuse word index
+ * @param[in] val fuse write value
+ *
+ * The command is passed as is to SECO. SECO uses part of the
+ * \a word parameter to indicate if the fuse should be locked
+ * after programming. See the "Write common fuse" section of
+ * the Security Reference Manual (SRM) for more info.
+ *
+ * @return Returns and error code (SC_ERR_NONE = success).
+ *
+ * Return errors codes:
+ * - SC_ERR_PARM if word fuse index param out of range or invalid
+ * - SC_ERR_NOACCESS if caller does not have SC_R_SYSTEM access
+ * - SC_ERR_NOACCESS if write operation failed
+ * - SC_ERR_LOCKED if write operation is locked
+ */
+sc_err_t sc_misc_otp_fuse_write(sc_ipc_t ipc, uint32_t word, uint32_t val);
+
+/*!
+ * This function sets a temp sensor alarm.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] resource resource with sensor
+ * @param[in] temp alarm to set
+ * @param[in] celsius whole part of temp to set
+ * @param[in] tenths fractional part of temp to set
+ *
+ * @return Returns and error code (SC_ERR_NONE = success).
+ *
+ * This function will enable the alarm interrupt if the temp requested is
+ * not the min/max temp. This enable automatically clears when the alarm
+ * occurs and this function has to be called again to re-enable.
+ *
+ * Return errors codes:
+ * - SC_ERR_PARM if parameters invalid
+ * - SC_ERR_NOACCESS if caller does not own the resource
+ * - SC_ERR_NOPOWER if power domain of resource not powered
+ */
+sc_err_t sc_misc_set_temp(sc_ipc_t ipc, sc_rsrc_t resource,
+ sc_misc_temp_t temp, int16_t celsius, int8_t tenths);
+
+/*!
+ * This function gets a temp sensor value.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] resource resource with sensor
+ * @param[in] temp value to get (sensor or alarm)
+ * @param[out] celsius whole part of temp to get
+ * @param[out] tenths fractional part of temp to get
+ *
+ * @return Returns and error code (SC_ERR_NONE = success).
+ *
+ * Return errors codes:
+ * - SC_ERR_PARM if parameters invalid
+ * - SC_ERR_BUSY if temp not ready yet (time delay after power on)
+ * - SC_ERR_NOPOWER if power domain of resource not powered
+ */
+sc_err_t sc_misc_get_temp(sc_ipc_t ipc, sc_rsrc_t resource,
+ sc_misc_temp_t temp, int16_t *celsius, int8_t *tenths);
+
+/*!
+ * This function returns the boot device.
+ *
+ * @param[in] ipc IPC handle
+ * @param[out] dev pointer to return boot device
+ */
+void sc_misc_get_boot_dev(sc_ipc_t ipc, sc_rsrc_t *dev);
+
+/*!
+ * This function returns the boot type.
+ *
+ * @param[in] ipc IPC handle
+ * @param[out] type pointer to return boot type
+ *
+ * @return Returns and error code (SC_ERR_NONE = success).
+ *
+ * Return errors code:
+ * - SC_ERR_UNAVAILABLE if type not passed by ROM
+ */
+sc_err_t sc_misc_get_boot_type(sc_ipc_t ipc, sc_misc_bt_t *type);
+
+/*!
+ * This function returns the current status of the ON/OFF button.
+ *
+ * @param[in] ipc IPC handle
+ * @param[out] status pointer to return button status
+ */
+void sc_misc_get_button_status(sc_ipc_t ipc, sc_bool_t *status);
+
+/*!
+ * This function returns the ROM patch checksum.
+ *
+ * @param[in] ipc IPC handle
+ * @param[out] checksum pointer to return checksum
+ *
+ * @return Returns and error code (SC_ERR_NONE = success).
+ */
+sc_err_t sc_misc_rompatch_checksum(sc_ipc_t ipc, uint32_t *checksum);
+
+/*!
+ * This function calls the board IOCTL function.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in,out] parm1 pointer to pass parameter 1
+ * @param[in,out] parm2 pointer to pass parameter 2
+ * @param[in,out] parm3 pointer to pass parameter 3
+ *
+ * @return Returns and error code (SC_ERR_NONE = success).
+ */
+sc_err_t sc_misc_board_ioctl(sc_ipc_t ipc, uint32_t *parm1,
+ uint32_t *parm2, uint32_t *parm3);
+
+/* @} */
+
+#endif /* SC_MISC_API_H */
+
+/**@}*/
+
diff --git a/include/soc/imx8/sc/svc/pad/api.h b/include/soc/imx8/sc/svc/pad/api.h
new file mode 100644
index 000000000000..2bcf109ea0a3
--- /dev/null
+++ b/include/soc/imx8/sc/svc/pad/api.h
@@ -0,0 +1,571 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017-2019 NXP
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+/*!
+ * Header file containing the public API for the System Controller (SC)
+ * Pad Control (PAD) function.
+ *
+ * @addtogroup PAD_SVC (SVC) Pad Service
+ *
+ * Module for the Pad Control (PAD) service.
+ *
+ * @details
+ *
+ * Pad configuration is managed by SC firmware. The pad configuration
+ * features supported by the SC firmware include:
+ *
+ * - Configuring the mux, input/output connection, and low-power isolation
+ mode.
+ * - Configuring the technology-specific pad setting such as drive strength,
+ * pullup/pulldown, etc.
+ * - Configuring compensation for pad groups with dual voltage capability.
+ *
+ * Pad functions fall into one of three categories. Generic functions are
+ * common to all SoCs and all process technologies. SoC functions are raw
+ * low-level functions. Technology-specific functions are specific to the
+ * process technology.
+ *
+ * The list of pads is SoC specific. Refer to the SoC [Pad List](@ref PADS)
+ * for valid pad values. Note that all pads exist on a die but may or
+ * may not be brought out by the specific package. Mapping of pads to
+ * package pins/balls is documented in the associated Data Sheet. Some pads
+ * may not be brought out because the part (die+package) is defeatured and
+ * some pads may connect to the substrate in the package.
+ *
+ * Some pads (SC_P_COMP_*) that can be specified are not individual pads
+ * but are in fact pad groups. These groups have additional configuration
+ * that can be done using the sc_pad_set_gp_28fdsoi_comp() function. More
+ * info on these can be found in the associated Reference Manual.
+ *
+ * Pads are managed as a resource by the Resource Manager (RM). They have
+ * assigned owners and only the owners can configure the pads. Some of the
+ * pads are reserved for use by the SCFW itself and this can be overriden
+ * with the implementation of board_config_sc(). Additionally, pads may
+ * be assigned to various other partitions via the implementation of
+ * board_system_config().
+ *
+ * Note muxing two input pads to the same IP functional signal will
+ * result in undefined behavior.
+ *
+ * @includedoc pad/details.dox
+ *
+ * @{
+ */
+
+#ifndef SC_PAD_API_H
+#define SC_PAD_API_H
+
+/* Includes */
+
+#include <soc/imx8/sc/types.h>
+#include <soc/imx8/sc/svc/rm/api.h>
+
+/* Defines */
+
+/*!
+ * @name Defines for type widths
+ */
+/*@{*/
+#define SC_PAD_MUX_W 3U /* Width of mux parameter */
+/*@}*/
+
+/*!
+ * @name Defines for sc_pad_config_t
+ */
+/*@{*/
+#define SC_PAD_CONFIG_NORMAL 0U /* Normal */
+#define SC_PAD_CONFIG_OD 1U /* Open Drain */
+#define SC_PAD_CONFIG_OD_IN 2U /* Open Drain and input */
+#define SC_PAD_CONFIG_OUT_IN 3U /* Output and input */
+/*@}*/
+
+/*!
+ * @name Defines for sc_pad_iso_t
+ */
+/*@{*/
+#define SC_PAD_ISO_OFF 0U /* ISO latch is transparent */
+#define SC_PAD_ISO_EARLY 1U /* Follow EARLY_ISO */
+#define SC_PAD_ISO_LATE 2U /* Follow LATE_ISO */
+#define SC_PAD_ISO_ON 3U /* ISO latched data is held */
+/*@}*/
+
+/*!
+ * @name Defines for sc_pad_28fdsoi_dse_t
+ */
+/*@{*/
+#define SC_PAD_28FDSOI_DSE_18V_1MA 0U /* Drive strength of 1mA for 1.8v */
+#define SC_PAD_28FDSOI_DSE_18V_2MA 1U /* Drive strength of 2mA for 1.8v */
+#define SC_PAD_28FDSOI_DSE_18V_4MA 2U /* Drive strength of 4mA for 1.8v */
+#define SC_PAD_28FDSOI_DSE_18V_6MA 3U /* Drive strength of 6mA for 1.8v */
+#define SC_PAD_28FDSOI_DSE_18V_8MA 4U /* Drive strength of 8mA for 1.8v */
+#define SC_PAD_28FDSOI_DSE_18V_10MA 5U /* Drive strength of 10mA for 1.8v */
+#define SC_PAD_28FDSOI_DSE_18V_12MA 6U /* Drive strength of 12mA for 1.8v */
+#define SC_PAD_28FDSOI_DSE_18V_HS 7U /* High-speed drive strength for 1.8v */
+#define SC_PAD_28FDSOI_DSE_33V_2MA 0U /* Drive strength of 2mA for 3.3v */
+#define SC_PAD_28FDSOI_DSE_33V_4MA 1U /* Drive strength of 4mA for 3.3v */
+#define SC_PAD_28FDSOI_DSE_33V_8MA 2U /* Drive strength of 8mA for 3.3v */
+#define SC_PAD_28FDSOI_DSE_33V_12MA 3U /* Drive strength of 12mA for 3.3v */
+#define SC_PAD_28FDSOI_DSE_DV_HIGH 0U /* High drive strength for dual volt */
+#define SC_PAD_28FDSOI_DSE_DV_LOW 1U /* Low drive strength for dual volt */
+/*@}*/
+
+/*!
+ * @name Defines for sc_pad_28fdsoi_ps_t
+ */
+/*@{*/
+#define SC_PAD_28FDSOI_PS_KEEPER 0U /* Bus-keeper (only valid for 1.8v) */
+#define SC_PAD_28FDSOI_PS_PU 1U /* Pull-up */
+#define SC_PAD_28FDSOI_PS_PD 2U /* Pull-down */
+#define SC_PAD_28FDSOI_PS_NONE 3U /* No pull (disabled) */
+/*@}*/
+
+/*!
+ * @name Defines for sc_pad_28fdsoi_pus_t
+ */
+/*@{*/
+#define SC_PAD_28FDSOI_PUS_30K_PD 0U /* 30K pull-down */
+#define SC_PAD_28FDSOI_PUS_100K_PU 1U /* 100K pull-up */
+#define SC_PAD_28FDSOI_PUS_3K_PU 2U /* 3K pull-up */
+#define SC_PAD_28FDSOI_PUS_30K_PU 3U /* 30K pull-up */
+/*@}*/
+
+/*!
+ * @name Defines for sc_pad_wakeup_t
+ */
+/*@{*/
+#define SC_PAD_WAKEUP_OFF 0U /* Off */
+#define SC_PAD_WAKEUP_CLEAR 1U /* Clears pending flag */
+#define SC_PAD_WAKEUP_LOW_LVL 4U /* Low level */
+#define SC_PAD_WAKEUP_FALL_EDGE 5U /* Falling edge */
+#define SC_PAD_WAKEUP_RISE_EDGE 6U /* Rising edge */
+#define SC_PAD_WAKEUP_HIGH_LVL 7U /* High-level */
+/*@}*/
+
+/* Types */
+
+/*!
+ * This type is used to declare a pad config. It determines how the
+ * output data is driven, pull-up is controlled, and input signal is
+ * connected. Normal and OD are typical and only connect the input
+ * when the output is not driven. The IN options are less common and
+ * force an input connection even when driving the output.
+ */
+typedef uint8_t sc_pad_config_t;
+
+/*!
+ * This type is used to declare a pad low-power isolation config.
+ * ISO_LATE is the most common setting. ISO_EARLY is only used when
+ * an output pad is directly determined by another input pad. The
+ * other two are only used when SW wants to directly contol isolation.
+ */
+typedef uint8_t sc_pad_iso_t;
+
+/*!
+ * This type is used to declare a drive strength. Note it is specific
+ * to 28FDSOI. Also note that valid values depend on the pad type.
+ */
+typedef uint8_t sc_pad_28fdsoi_dse_t;
+
+/*!
+ * This type is used to declare a pull select. Note it is specific
+ * to 28FDSOI.
+ */
+typedef uint8_t sc_pad_28fdsoi_ps_t;
+
+/*!
+ * This type is used to declare a pull-up select. Note it is specific
+ * to 28FDSOI HSIC pads.
+ */
+typedef uint8_t sc_pad_28fdsoi_pus_t;
+
+/*!
+ * This type is used to declare a wakeup mode of a pad.
+ */
+typedef uint8_t sc_pad_wakeup_t;
+
+/* Functions */
+
+/*!
+ * @name Generic Functions
+ * @{
+ */
+
+/*!
+ * This function configures the mux settings for a pad. This includes
+ * the signal mux, pad config, and low-power isolation mode.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] pad pad to configure
+ * @param[in] mux mux setting
+ * @param[in] config pad config
+ * @param[in] iso low-power isolation mode
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors:
+ * - SC_PARM if arguments out of range or invalid,
+ * - SC_ERR_NOACCESS if caller's partition is not the pad owner
+ *
+ * Note muxing two input pads to the same IP functional signal will
+ * result in undefined behavior.
+ *
+ * Refer to the SoC [Pad List](@ref PADS) for valid pad values.
+ */
+sc_err_t sc_pad_set_mux(sc_ipc_t ipc, sc_pad_t pad,
+ uint8_t mux, sc_pad_config_t config, sc_pad_iso_t iso);
+
+/*!
+ * This function gets the mux settings for a pad. This includes
+ * the signal mux, pad config, and low-power isolation mode.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] pad pad to query
+ * @param[out] mux pointer to return mux setting
+ * @param[out] config pointer to return pad config
+ * @param[out] iso pointer to return low-power isolation mode
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors:
+ * - SC_PARM if arguments out of range or invalid,
+ * - SC_ERR_NOACCESS if caller's partition is not the pad owner
+ *
+ * Refer to the SoC [Pad List](@ref PADS) for valid pad values.
+ */
+sc_err_t sc_pad_get_mux(sc_ipc_t ipc, sc_pad_t pad,
+ uint8_t *mux, sc_pad_config_t *config, sc_pad_iso_t *iso);
+
+/*!
+ * This function configures the general purpose pad control. This
+ * is technology dependent and includes things like drive strength,
+ * slew rate, pull up/down, etc. Refer to the SoC Reference Manual
+ * for bit field details.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] pad pad to configure
+ * @param[in] ctrl control value to set
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors:
+ * - SC_PARM if arguments out of range or invalid,
+ * - SC_ERR_NOACCESS if caller's partition is not the pad owner
+ *
+ * Refer to the SoC [Pad List](@ref PADS) for valid pad values.
+ */
+sc_err_t sc_pad_set_gp(sc_ipc_t ipc, sc_pad_t pad, uint32_t ctrl);
+
+/*!
+ * This function gets the general purpose pad control. This
+ * is technology dependent and includes things like drive strength,
+ * slew rate, pull up/down, etc. Refer to the SoC Reference Manual
+ * for bit field details.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] pad pad to query
+ * @param[out] ctrl pointer to return control value
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors:
+ * - SC_PARM if arguments out of range or invalid,
+ * - SC_ERR_NOACCESS if caller's partition is not the pad owner
+ *
+ * Refer to the SoC [Pad List](@ref PADS) for valid pad values.
+ */
+sc_err_t sc_pad_get_gp(sc_ipc_t ipc, sc_pad_t pad, uint32_t *ctrl);
+
+/*!
+ * This function configures the wakeup mode of the pad.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] pad pad to configure
+ * @param[in] wakeup wakeup to set
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors:
+ * - SC_PARM if arguments out of range or invalid,
+ * - SC_ERR_NOACCESS if caller's partition is not the pad owner
+ *
+ * Refer to the SoC [Pad List](@ref PADS) for valid pad values.
+ */
+sc_err_t sc_pad_set_wakeup(sc_ipc_t ipc, sc_pad_t pad,
+ sc_pad_wakeup_t wakeup);
+
+/*!
+ * This function gets the wakeup mode of a pad.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] pad pad to query
+ * @param[out] wakeup pointer to return wakeup
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors:
+ * - SC_PARM if arguments out of range or invalid,
+ * - SC_ERR_NOACCESS if caller's partition is not the pad owner
+ *
+ * Refer to the SoC [Pad List](@ref PADS) for valid pad values.
+ */
+sc_err_t sc_pad_get_wakeup(sc_ipc_t ipc, sc_pad_t pad,
+ sc_pad_wakeup_t *wakeup);
+
+/*!
+ * This function configures a pad.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] pad pad to configure
+ * @param[in] mux mux setting
+ * @param[in] config pad config
+ * @param[in] iso low-power isolation mode
+ * @param[in] ctrl control value
+ * @param[in] wakeup wakeup to set
+ *
+ * @see sc_pad_set_mux().
+ * @see sc_pad_set_gp().
+ *
+ * Return errors:
+ * - SC_PARM if arguments out of range or invalid,
+ * - SC_ERR_NOACCESS if caller's partition is not the pad owner
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Note muxing two input pads to the same IP functional signal will
+ * result in undefined behavior.
+ *
+ * Refer to the SoC [Pad List](@ref PADS) for valid pad values.
+ */
+sc_err_t sc_pad_set_all(sc_ipc_t ipc, sc_pad_t pad, uint8_t mux,
+ sc_pad_config_t config, sc_pad_iso_t iso, uint32_t ctrl,
+ sc_pad_wakeup_t wakeup);
+
+/*!
+ * This function gets a pad's config.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] pad pad to query
+ * @param[out] mux pointer to return mux setting
+ * @param[out] config pointer to return pad config
+ * @param[out] iso pointer to return low-power isolation mode
+ * @param[out] ctrl pointer to return control value
+ * @param[out] wakeup pointer to return wakeup to set
+ *
+ * @see sc_pad_set_mux().
+ * @see sc_pad_set_gp().
+ *
+ * Return errors:
+ * - SC_PARM if arguments out of range or invalid,
+ * - SC_ERR_NOACCESS if caller's partition is not the pad owner
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Refer to the SoC [Pad List](@ref PADS) for valid pad values.
+ */
+sc_err_t sc_pad_get_all(sc_ipc_t ipc, sc_pad_t pad, uint8_t *mux,
+ sc_pad_config_t *config, sc_pad_iso_t *iso, uint32_t *ctrl,
+ sc_pad_wakeup_t *wakeup);
+
+/* @} */
+
+/*!
+ * @name SoC Specific Functions
+ * @{
+ */
+
+/*!
+ * This function configures the settings for a pad. This setting is SoC
+ * specific.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] pad pad to configure
+ * @param[in] val value to set
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors:
+ * - SC_PARM if arguments out of range or invalid,
+ * - SC_ERR_NOACCESS if caller's partition is not the pad owner
+ *
+ * Refer to the SoC [Pad List](@ref PADS) for valid pad values.
+ */
+sc_err_t sc_pad_set(sc_ipc_t ipc, sc_pad_t pad, uint32_t val);
+
+/*!
+ * This function gets the settings for a pad. This setting is SoC
+ * specific.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] pad pad to query
+ * @param[out] val pointer to return setting
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors:
+ * - SC_PARM if arguments out of range or invalid,
+ * - SC_ERR_NOACCESS if caller's partition is not the pad owner
+ *
+ * Refer to the SoC [Pad List](@ref PADS) for valid pad values.
+ */
+sc_err_t sc_pad_get(sc_ipc_t ipc, sc_pad_t pad, uint32_t *val);
+
+/* @} */
+
+/*!
+ * @name Technology Specific Functions
+ * @{
+ */
+
+/*!
+ * This function configures the pad control specific to 28FDSOI.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] pad pad to configure
+ * @param[in] dse drive strength
+ * @param[in] ps pull select
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors:
+ * - SC_PARM if arguments out of range or invalid,
+ * - SC_ERR_NOACCESS if caller's partition is not the pad owner,
+ * - SC_ERR_UNAVAILABLE if process not applicable
+ *
+ * Refer to the SoC [Pad List](@ref PADS) for valid pad values.
+ */
+sc_err_t sc_pad_set_gp_28fdsoi(sc_ipc_t ipc, sc_pad_t pad,
+ sc_pad_28fdsoi_dse_t dse, sc_pad_28fdsoi_ps_t ps);
+
+/*!
+ * This function gets the pad control specific to 28FDSOI.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] pad pad to query
+ * @param[out] dse pointer to return drive strength
+ * @param[out] ps pointer to return pull select
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors:
+ * - SC_PARM if arguments out of range or invalid,
+ * - SC_ERR_NOACCESS if caller's partition is not the pad owner,
+ * - SC_ERR_UNAVAILABLE if process not applicable
+ *
+ * Refer to the SoC [Pad List](@ref PADS) for valid pad values.
+ */
+sc_err_t sc_pad_get_gp_28fdsoi(sc_ipc_t ipc, sc_pad_t pad,
+ sc_pad_28fdsoi_dse_t *dse, sc_pad_28fdsoi_ps_t *ps);
+
+/*!
+ * This function configures the pad control specific to 28FDSOI.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] pad pad to configure
+ * @param[in] dse drive strength
+ * @param[in] hys hysteresis
+ * @param[in] pus pull-up select
+ * @param[in] pke pull keeper enable
+ * @param[in] pue pull-up enable
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors:
+ * - SC_PARM if arguments out of range or invalid,
+ * - SC_ERR_NOACCESS if caller's partition is not the pad owner,
+ * - SC_ERR_UNAVAILABLE if process not applicable
+ *
+ * Refer to the SoC [Pad List](@ref PADS) for valid pad values.
+ */
+sc_err_t sc_pad_set_gp_28fdsoi_hsic(sc_ipc_t ipc, sc_pad_t pad,
+ sc_pad_28fdsoi_dse_t dse, sc_bool_t hys, sc_pad_28fdsoi_pus_t pus,
+ sc_bool_t pke, sc_bool_t pue);
+
+/*!
+ * This function gets the pad control specific to 28FDSOI.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] pad pad to query
+ * @param[out] dse pointer to return drive strength
+ * @param[out] hys pointer to return hysteresis
+ * @param[out] pus pointer to return pull-up select
+ * @param[out] pke pointer to return pull keeper enable
+ * @param[out] pue pointer to return pull-up enable
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors:
+ * - SC_PARM if arguments out of range or invalid,
+ * - SC_ERR_NOACCESS if caller's partition is not the pad owner,
+ * - SC_ERR_UNAVAILABLE if process not applicable
+ *
+ * Refer to the SoC [Pad List](@ref PADS) for valid pad values.
+ */
+sc_err_t sc_pad_get_gp_28fdsoi_hsic(sc_ipc_t ipc, sc_pad_t pad,
+ sc_pad_28fdsoi_dse_t *dse, sc_bool_t *hys, sc_pad_28fdsoi_pus_t *pus,
+ sc_bool_t *pke, sc_bool_t *pue);
+
+/*!
+ * This function configures the compensation control specific to 28FDSOI.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] pad pad to configure
+ * @param[in] compen compensation/freeze mode
+ * @param[in] fastfrz fast freeze
+ * @param[in] rasrcp compensation code for PMOS
+ * @param[in] rasrcn compensation code for NMOS
+ * @param[in] nasrc_sel NASRC read select
+ * @param[in] psw_ovr 2.5v override
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors:
+ * - SC_PARM if arguments out of range or invalid,
+ * - SC_ERR_NOACCESS if caller's partition is not the pad owner,
+ * - SC_ERR_UNAVAILABLE if process not applicable
+ *
+ * Refer to the SoC [Pad List](@ref PADS) for valid pad values.
+ *
+ * Note \a psw_ovr is only applicable to pads supporting 2.5 volt
+ * operation (e.g. some Ethernet pads).
+ */
+sc_err_t sc_pad_set_gp_28fdsoi_comp(sc_ipc_t ipc, sc_pad_t pad,
+ uint8_t compen, sc_bool_t fastfrz, uint8_t rasrcp, uint8_t rasrcn,
+ sc_bool_t nasrc_sel, sc_bool_t psw_ovr);
+
+/*!
+ * This function gets the compensation control specific to 28FDSOI.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] pad pad to query
+ * @param[out] compen pointer to return compensation/freeze mode
+ * @param[out] fastfrz pointer to return fast freeze
+ * @param[out] rasrcp pointer to return compensation code for PMOS
+ * @param[out] rasrcn pointer to return compensation code for NMOS
+ * @param[out] nasrc_sel pointer to return NASRC read select
+ * @param[out] compok pointer to return compensation status
+ * @param[out] nasrc pointer to return NASRCP/NASRCN
+ * @param[out] psw_ovr pointer to return the 2.5v override
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors:
+ * - SC_PARM if arguments out of range or invalid,
+ * - SC_ERR_NOACCESS if caller's partition is not the pad owner,
+ * - SC_ERR_UNAVAILABLE if process not applicable
+ *
+ * Refer to the SoC [Pad List](@ref PADS) for valid pad values.
+ */
+sc_err_t sc_pad_get_gp_28fdsoi_comp(sc_ipc_t ipc, sc_pad_t pad,
+ uint8_t *compen, sc_bool_t *fastfrz, uint8_t *rasrcp, uint8_t *rasrcn,
+ sc_bool_t *nasrc_sel, sc_bool_t *compok, uint8_t *nasrc, sc_bool_t *psw_ovr);
+
+/* @} */
+
+#endif /* SC_PAD_API_H */
+
+/**@}*/
+
diff --git a/include/soc/imx8/sc/svc/pm/api.h b/include/soc/imx8/sc/svc/pm/api.h
new file mode 100644
index 000000000000..608520eeb491
--- /dev/null
+++ b/include/soc/imx8/sc/svc/pm/api.h
@@ -0,0 +1,808 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017-2019 NXP
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+/*!
+ * Header file containing the public API for the System Controller (SC)
+ * Power Management (PM) function. This includes functions for power state
+ * control, clock control, reset control, and wake-up event control.
+ *
+ * @addtogroup PM_SVC (SVC) Power Management Service
+ *
+ * Module for the Power Management (PM) service.
+ *
+ * @includedoc pm/details.dox
+ *
+ * @{
+ */
+
+#ifndef SC_PM_API_H
+#define SC_PM_API_H
+
+/* Includes */
+
+#include <soc/imx8/sc/types.h>
+#include <soc/imx8/sc/svc/rm/api.h>
+
+/* Defines */
+
+/*!
+ * @name Defines for type widths
+ */
+/*@{*/
+#define SC_PM_POWER_MODE_W 2U /* Width of sc_pm_power_mode_t */
+#define SC_PM_CLOCK_MODE_W 3U /* Width of sc_pm_clock_mode_t */
+#define SC_PM_RESET_TYPE_W 2U /* Width of sc_pm_reset_type_t */
+#define SC_PM_RESET_REASON_W 4U /* Width of sc_pm_reset_reason_t */
+/*@}*/
+
+/*!
+ * @name Defines for clock indexes (sc_pm_clk_t)
+ */
+/*@{*/
+/*@}*/
+
+/*!
+ * @name Defines for ALL parameters
+ */
+/*@{*/
+#define SC_PM_CLK_ALL ((sc_pm_clk_t) UINT8_MAX) /* All clocks */
+/*@}*/
+
+/*!
+ * @name Defines for sc_pm_power_mode_t
+ */
+/*@{*/
+#define SC_PM_PW_MODE_OFF 0U /* Power off */
+#define SC_PM_PW_MODE_STBY 1U /* Power in standby */
+#define SC_PM_PW_MODE_LP 2U /* Power in low-power */
+#define SC_PM_PW_MODE_ON 3U /* Power on */
+/*@}*/
+
+/*!
+ * @name Defines for sc_pm_clk_t
+ */
+/*@{*/
+#define SC_PM_CLK_SLV_BUS 0U /* Slave bus clock */
+#define SC_PM_CLK_MST_BUS 1U /* Master bus clock */
+#define SC_PM_CLK_PER 2U /* Peripheral clock */
+#define SC_PM_CLK_PHY 3U /* Phy clock */
+#define SC_PM_CLK_MISC 4U /* Misc clock */
+#define SC_PM_CLK_MISC0 0U /* Misc 0 clock */
+#define SC_PM_CLK_MISC1 1U /* Misc 1 clock */
+#define SC_PM_CLK_MISC2 2U /* Misc 2 clock */
+#define SC_PM_CLK_MISC3 3U /* Misc 3 clock */
+#define SC_PM_CLK_MISC4 4U /* Misc 4 clock */
+#define SC_PM_CLK_CPU 2U /* CPU clock */
+#define SC_PM_CLK_PLL 4U /* PLL */
+#define SC_PM_CLK_BYPASS 4U /* Bypass clock */
+/*@}*/
+
+/*!
+ * @name Defines for sc_pm_clk_mode_t
+ */
+/*@{*/
+#define SC_PM_CLK_MODE_ROM_INIT 0U /* Clock is initialized by ROM. */
+#define SC_PM_CLK_MODE_OFF 1U /* Clock is disabled */
+#define SC_PM_CLK_MODE_ON 2U /* Clock is enabled. */
+#define SC_PM_CLK_MODE_AUTOGATE_SW 3U /* Clock is in SW autogate mode */
+#define SC_PM_CLK_MODE_AUTOGATE_HW 4U /* Clock is in HW autogate mode */
+#define SC_PM_CLK_MODE_AUTOGATE_SW_HW 5U /* Clock is in SW-HW autogate mode */
+/*@}*/
+
+/*!
+ * @name Defines for sc_pm_clk_parent_t
+ */
+/*@{*/
+#define SC_PM_PARENT_XTAL 0U /* Parent is XTAL. */
+#define SC_PM_PARENT_PLL0 1U /* Parent is PLL0 */
+#define SC_PM_PARENT_PLL1 2U /* Parent is PLL1 or PLL0/2 */
+#define SC_PM_PARENT_PLL2 3U /* Parent in PLL2 or PLL0/4 */
+#define SC_PM_PARENT_BYPS 4U /* Parent is a bypass clock. */
+/*@}*/
+
+/*!
+ * @name Defines for sc_pm_reset_type_t
+ */
+/*@{*/
+#define SC_PM_RESET_TYPE_COLD 0U /* Cold reset */
+#define SC_PM_RESET_TYPE_WARM 1U /* Warm reset */
+#define SC_PM_RESET_TYPE_BOARD 2U /* Board reset */
+/*@}*/
+
+/*!
+ * @name Defines for sc_pm_reset_reason_t
+ */
+/*@{*/
+#define SC_PM_RESET_REASON_POR 0U /* Power on reset */
+#define SC_PM_RESET_REASON_JTAG 1U /* JTAG reset */
+#define SC_PM_RESET_REASON_SW 2U /* Software reset */
+#define SC_PM_RESET_REASON_WDOG 3U /* Partition watchdog reset */
+#define SC_PM_RESET_REASON_LOCKUP 4U /* SCU lockup reset */
+#define SC_PM_RESET_REASON_SNVS 5U /* SNVS reset */
+#define SC_PM_RESET_REASON_TEMP 6U /* Temp panic reset */
+#define SC_PM_RESET_REASON_MSI 7U /* MSI reset */
+#define SC_PM_RESET_REASON_UECC 8U /* ECC reset */
+#define SC_PM_RESET_REASON_SCFW_WDOG 9U /* SCFW watchdog reset */
+#define SC_PM_RESET_REASON_ROM_WDOG 10U /* SCU ROM watchdog reset */
+#define SC_PM_RESET_REASON_SECO 11U /* SECO reset */
+#define SC_PM_RESET_REASON_SCFW_FAULT 12U /* SCFW fault reset */
+/*@}*/
+
+/*!
+ * @name Defines for sc_pm_sys_if_t
+ */
+/*@{*/
+#define SC_PM_SYS_IF_INTERCONNECT 0U /* System interconnect */
+#define SC_PM_SYS_IF_MU 1U /* AP -> SCU message units */
+#define SC_PM_SYS_IF_OCMEM 2U /* On-chip memory (ROM/OCRAM) */
+#define SC_PM_SYS_IF_DDR 3U /* DDR memory */
+/*@}*/
+
+/*!
+ * @name Defines for sc_pm_wake_src_t
+ */
+/*@{*/
+#define SC_PM_WAKE_SRC_NONE 0U /* No wake source, used for self-kill */
+#define SC_PM_WAKE_SRC_SCU 1U /* Wakeup from SCU to resume CPU (IRQSTEER & GIC powered down) */
+#define SC_PM_WAKE_SRC_IRQSTEER 2U /* Wakeup from IRQSTEER to resume CPU (GIC powered down) */
+#define SC_PM_WAKE_SRC_IRQSTEER_GIC 3U /* Wakeup from IRQSTEER+GIC to wake CPU (GIC clock gated) */
+#define SC_PM_WAKE_SRC_GIC 4U /* Wakeup from GIC to wake CPU */
+/*@}*/
+
+/* Types */
+
+/*!
+ * This type is used to declare a power mode. Note resources only use
+ * SC_PM_PW_MODE_OFF and SC_PM_PW_MODE_ON. The other modes are used only
+ * as system power modes.
+ */
+typedef uint8_t sc_pm_power_mode_t;
+
+/*!
+ * This type is used to declare a clock.
+ */
+typedef uint8_t sc_pm_clk_t;
+
+/*!
+ * This type is used to declare a clock mode.
+ */
+typedef uint8_t sc_pm_clk_mode_t;
+
+/*!
+ * This type is used to declare the clock parent.
+ */
+typedef uint8_t sc_pm_clk_parent_t;
+
+/*!
+ * This type is used to declare clock rates.
+ */
+typedef uint32_t sc_pm_clock_rate_t;
+
+/*!
+ * This type is used to declare a desired reset type.
+ */
+typedef uint8_t sc_pm_reset_type_t;
+
+/*!
+ * This type is used to declare a reason for a reset.
+ */
+typedef uint8_t sc_pm_reset_reason_t;
+
+/*!
+ * This type is used to specify a system-level interface to be power managed.
+ */
+typedef uint8_t sc_pm_sys_if_t;
+
+/*!
+ * This type is used to specify a wake source for CPU resources.
+ */
+typedef uint8_t sc_pm_wake_src_t;
+
+/* Functions */
+
+/*!
+ * @name Power Functions
+ * @{
+ */
+
+/*!
+ * This function sets the system power mode. Only the owner of the
+ * SC_R_SYSTEM resource or a partition with access permissions to
+ * SC_R_SYSTEM can do this.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] mode power mode to apply
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors:
+ * - SC_ERR_PARM if invalid mode,
+ * - SC_ERR_NOACCESS if caller does not have SC_R_SYSTEM access
+ *
+ * @see sc_pm_set_sys_power_mode().
+ */
+sc_err_t sc_pm_set_sys_power_mode(sc_ipc_t ipc, sc_pm_power_mode_t mode);
+
+/*!
+ * This function sets the power mode of a partition.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] pt handle of partition
+ * @param[in] mode power mode to apply
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors:
+ * - SC_ERR_PARM if invalid partition or mode,
+ * - SC_ERR_NOACCESS if caller's partition is not the owner or
+ * parent of \a pt
+ *
+ * The power mode of the partitions is a max power any resource will
+ * be set to. Calling this will result in all resources owned
+ * by \a pt to have their power changed to the lower of \a mode or the
+ * individual resource mode set using sc_pm_set_resource_power_mode().
+ */
+sc_err_t sc_pm_set_partition_power_mode(sc_ipc_t ipc, sc_rm_pt_t pt,
+ sc_pm_power_mode_t mode);
+
+/*!
+ * This function gets the power mode of a partition.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] pt handle of partition
+ * @param[out] mode pointer to return power mode
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors:
+ * - SC_ERR_PARM if invalid partition
+ */
+sc_err_t sc_pm_get_sys_power_mode(sc_ipc_t ipc, sc_rm_pt_t pt,
+ sc_pm_power_mode_t *mode);
+
+/*!
+ * This function sets the power mode of a resource.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] resource ID of the resource
+ * @param[in] mode power mode to apply
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors:
+ * - SC_ERR_PARM if invalid resource or mode,
+ * - SC_ERR_NOACCESS if caller's partition is not the resource owner
+ * or parent of the owner
+ *
+ * Resources must be at SC_PM_PW_MODE_LP mode or higher to access them,
+ * otherwise the master will get a bus error or hang.
+ *
+ * This function will record the individual resource power mode
+ * and change it if the requested mode is lower than or equal to the
+ * partition power mode set with sc_pm_set_partition_power_mode().
+ * In other words, the power mode of the resource will be the minimum
+ * of the resource power mode and the partition power mode.
+ *
+ * Note some resources are still not accessible even when powered up if bus
+ * transactions go through a fabric not powered up. Examples of this are
+ * resources in display and capture subsystems which require the display
+ * controller or the imaging subsytem to be powered up first.
+ *
+ * Not that resources are grouped into power domains by the underlying
+ * hardware. If any resource in the domain is on, the entire power domain
+ * will be on. Other power domains required to access the resource will
+ * also be turned on. Clocks required to access the peripheral will be
+ * turned on. Refer to the SoC RM for more info on power domains and access
+ * infrastructure (bus fabrics, clock domains, etc.).
+ */
+sc_err_t sc_pm_set_resource_power_mode(sc_ipc_t ipc, sc_rsrc_t resource,
+ sc_pm_power_mode_t mode);
+
+/*!
+* This function sets the power mode for all the resources owned
+* by a child partition.
+*
+* @param[in] ipc IPC handle
+* @param[in] pt handle of child partition
+* @param[in] mode power mode to apply
+* @param[in] exclude resource to exclude
+*
+* @return Returns an error code (SC_ERR_NONE = success).
+*
+* Return errors:
+* - SC_ERR_PARM if invalid partition or mode,
+* - SC_ERR_NOACCESS if caller's partition is not the parent
+* of \a pt
+*
+* This functions loops through all the resources owned by \a pt
+* and sets the power mode to \a mode. It will skip setting
+* \a exclude (SC_R_LAST to skip none).
+*
+* This function can only be called by the parent. It is used to
+* implement some aspects of virtualization.
+*/
+sc_err_t sc_pm_set_resource_power_mode_all(sc_ipc_t ipc,
+ sc_rm_pt_t pt, sc_pm_power_mode_t mode, sc_rsrc_t exclude);
+
+/*!
+ * This function gets the power mode of a resource.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] resource ID of the resource
+ * @param[out] mode pointer to return power mode
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Note only SC_PM_PW_MODE_OFF and SC_PM_PW_MODE_ON are valid. The value
+ * returned does not reflect the power mode of the partition..
+ */
+sc_err_t sc_pm_get_resource_power_mode(sc_ipc_t ipc, sc_rsrc_t resource,
+ sc_pm_power_mode_t *mode);
+
+/*!
+ * This function requests the low power mode some of the resources
+ * can enter based on their state. This API is only valid for the
+ * following resources : SC_R_A53, SC_R_A53_0, SC_R_A53_1, SC_A53_2,
+ * SC_A53_3, SC_R_A72, SC_R_A72_0, SC_R_A72_1, SC_R_CC1, SC_R_A35,
+ * SC_R_A35_0, SC_R_A35_1, SC_R_A35_2, SC_R_A35_3.
+ * For all other resources it will return SC_ERR_PARAM.
+ * This function will set the low power mode the cores, cluster
+ * and cluster associated resources will enter when all the cores
+ * in a given cluster execute WFI
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] resource ID of the resource
+ * @param[in] mode power mode to apply
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ */
+sc_err_t sc_pm_req_low_power_mode(sc_ipc_t ipc, sc_rsrc_t resource,
+ sc_pm_power_mode_t mode);
+
+/*!
+ * This function requests low-power mode entry for CPU/cluster
+ * resources. This API is only valid for the following resources:
+ * SC_R_A53, SC_R_A53_x, SC_R_A72, SC_R_A72_x, SC_R_A35, SC_R_A35_x,
+ * SC_R_CCI. For all other resources it will return SC_ERR_PARAM.
+ * For individual core resources, the specified power mode
+ * and wake source will be applied after the core has entered
+ * WFI. For cluster resources, the specified power mode is
+ * applied after all cores in the cluster have entered low-power mode.
+ * For multicluster resources, the specified power mode is applied
+ * after all clusters have reached low-power mode.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] resource ID of the resource
+ * @param[in] mode power mode to apply
+ * @param[in] wake_src wake source for low-power exit
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ */
+sc_err_t sc_pm_req_cpu_low_power_mode(sc_ipc_t ipc, sc_rsrc_t resource,
+ sc_pm_power_mode_t mode, sc_pm_wake_src_t wake_src);
+
+/*!
+ * This function is used to set the resume address of a CPU.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] resource ID of the CPU resource
+ * @param[in] address 64-bit resume address
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors:
+ * - SC_ERR_PARM if invalid resource or address,
+ * - SC_ERR_NOACCESS if caller's partition is not the parent of the
+ * resource (CPU) owner
+ */
+sc_err_t sc_pm_set_cpu_resume_addr(sc_ipc_t ipc, sc_rsrc_t resource,
+ sc_faddr_t address);
+
+/*!
+ * This function is used to set parameters for CPU resume from
+ * low-power mode.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] resource ID of the CPU resource
+ * @param[in] isPrimary set SC_TRUE if primary wake CPU
+ * @param[in] address 64-bit resume address
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors:
+ * - SC_ERR_PARM if invalid resource or address,
+ * - SC_ERR_NOACCESS if caller's partition is not the parent of the
+ * resource (CPU) owner
+ */
+sc_err_t sc_pm_set_cpu_resume(sc_ipc_t ipc, sc_rsrc_t resource,
+ sc_bool_t isPrimary, sc_faddr_t address);
+
+/*!
+ * This function requests the power mode configuration for system-level
+ * interfaces including messaging units, interconnect, and memories. This API
+ * is only valid for the following resources : SC_R_A53, SC_R_A72, and
+ * SC_R_M4_x_PID_y. For all other resources, it will return SC_ERR_PARAM.
+ * The requested power mode will be captured and applied to system-level
+ * resources as system conditions allow.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] resource ID of the resource
+ * @param[in] sys_if system-level interface to be configured
+ * @param[in] hpm high-power mode for the system interface
+ * @param[in] lpm low-power mode for the system interface
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ */
+sc_err_t sc_pm_req_sys_if_power_mode(sc_ipc_t ipc, sc_rsrc_t resource,
+ sc_pm_sys_if_t sys_if, sc_pm_power_mode_t hpm, sc_pm_power_mode_t lpm);
+
+/* @} */
+
+/*!
+ * @name Clock/PLL Functions
+ * @{
+ */
+
+/*!
+ * This function sets the rate of a resource's clock/PLL.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] resource ID of the resource
+ * @param[in] clk clock/PLL to affect
+ * @param[in,out] rate pointer to rate to set,
+ * return actual rate
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors:
+ * - SC_ERR_PARM if invalid resource or clock/PLL,
+ * - SC_ERR_NOACCESS if caller's partition is not the resource owner
+ * or parent of the owner,
+ * - SC_ERR_UNAVAILABLE if clock/PLL not applicable to this resource,
+ * - SC_ERR_LOCKED if rate locked (usually because shared clock/PLL)
+ *
+ * Refer to the [Clock List](@ref CLOCKS) for valid clock/PLL values.
+ */
+sc_err_t sc_pm_set_clock_rate(sc_ipc_t ipc, sc_rsrc_t resource,
+ sc_pm_clk_t clk, sc_pm_clock_rate_t *rate);
+
+/*!
+ * This function gets the rate of a resource's clock/PLL.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] resource ID of the resource
+ * @param[in] clk clock/PLL to affect
+ * @param[out] rate pointer to return rate
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors:
+ * - SC_ERR_PARM if invalid resource or clock/PLL,
+ * - SC_ERR_NOACCESS if caller's partition is not the resource owner
+ * or parent of the owner,
+ * - SC_ERR_UNAVAILABLE if clock/PLL not applicable to this resource
+ *
+ * Refer to the [Clock List](@ref CLOCKS) for valid clock/PLL values.
+ */
+sc_err_t sc_pm_get_clock_rate(sc_ipc_t ipc, sc_rsrc_t resource,
+ sc_pm_clk_t clk, sc_pm_clock_rate_t *rate);
+
+/*!
+ * This function enables/disables a resource's clock.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] resource ID of the resource
+ * @param[in] clk clock to affect
+ * @param[in] enable enable if SC_TRUE; otherwise disabled
+ * @param[in] autog HW auto clock gating
+ *
+ * If \a resource is SC_R_ALL then all resources owned will be affected.
+ * No error will be returned.
+ *
+ * If \a clk is SC_PM_CLK_ALL, then an error will be returned if any
+ * of the available clocks returns an error.
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors:
+ * - SC_ERR_PARM if invalid resource or clock,
+ * - SC_ERR_NOACCESS if caller's partition is not the resource owner
+ * or parent of the owner,
+ * - SC_ERR_UNAVAILABLE if clock not applicable to this resource
+ *
+ * Refer to the [Clock List](@ref CLOCKS) for valid clock values.
+ */
+sc_err_t sc_pm_clock_enable(sc_ipc_t ipc, sc_rsrc_t resource,
+ sc_pm_clk_t clk, sc_bool_t enable, sc_bool_t autog);
+
+/*!
+ * This function sets the parent of a resource's clock.
+ * This function should only be called when the clock is disabled.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] resource ID of the resource
+ * @param[in] clk clock to affect
+ * @param[in] parent New parent of the clock.
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors:
+ * - SC_ERR_PARM if invalid resource or clock,
+ * - SC_ERR_NOACCESS if caller's partition is not the resource owner
+ * or parent of the owner,
+ * - SC_ERR_UNAVAILABLE if clock not applicable to this resource
+ * - SC_ERR_BUSY if clock is currently enabled.
+ * - SC_ERR_NOPOWER if resource not powered
+ *
+ * Refer to the [Clock List](@ref CLOCKS) for valid clock values.
+ */
+sc_err_t sc_pm_set_clock_parent(sc_ipc_t ipc, sc_rsrc_t resource,
+ sc_pm_clk_t clk, sc_pm_clk_parent_t parent);
+
+/*!
+ * This function gets the parent of a resource's clock.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] resource ID of the resource
+ * @param[in] clk clock to affect
+ * @param[out] parent pointer to return parent of clock.
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors:
+ * - SC_ERR_PARM if invalid resource or clock,
+ * - SC_ERR_NOACCESS if caller's partition is not the resource owner
+ * or parent of the owner,
+ * - SC_ERR_UNAVAILABLE if clock not applicable to this resource
+ *
+ * Refer to the [Clock List](@ref CLOCKS) for valid clock values.
+ */
+sc_err_t sc_pm_get_clock_parent(sc_ipc_t ipc, sc_rsrc_t resource,
+ sc_pm_clk_t clk, sc_pm_clk_parent_t *parent);
+
+/* @} */
+
+/*!
+ * @name Reset Functions
+ * @{
+ */
+
+/*!
+ * This function is used to reset the system. Only the owner of the
+ * SC_R_SYSTEM resource or a partition with access permissions to
+ * SC_R_SYSTEM can do this.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] type reset type
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors:
+ * - SC_ERR_PARM if invalid type,
+ * - SC_ERR_NOACCESS if caller cannot access SC_R_SYSTEM
+ *
+ * If this function returns, then the reset did not occur due to an
+ * invalid parameter.
+ */
+sc_err_t sc_pm_reset(sc_ipc_t ipc, sc_pm_reset_type_t type);
+
+/*!
+ * This function gets a caller's reset reason.
+ *
+ * @param[in] ipc IPC handle
+ * @param[out] reason pointer to return the reset reason
+ *
+ * This function returns the reason a partition was reset. If the reason
+ * is POR, then the system reset reason will be returned.
+ *
+ * Note depending on the connection of the WDOG_OUT signal and the OTP
+ * programming of the PMIC, some resets may trigger a system POR
+ * and the original reason will be lost.
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ */
+sc_err_t sc_pm_reset_reason(sc_ipc_t ipc, sc_pm_reset_reason_t *reason);
+
+/*!
+ * This function gets the partition that caused a reset.
+ *
+ * @param[in] ipc IPC handle
+ * @param[out] pt pointer to return the resetting partition
+ *
+ * If the reset reason obtained via sc_pm_reset_reason() is POR then the
+ * result from this function will be 0. Some SECO causes of reset will
+ * also return 0.
+ *
+ * Note depending on the connection of the WDOG_OUT signal and the OTP
+ * programming of the PMIC, some resets may trigger a system POR
+ * and the partition info will be lost.
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ */
+sc_err_t sc_pm_get_reset_part(sc_ipc_t ipc, sc_rm_pt_t *pt);
+
+/*!
+ * This function is used to boot a partition.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] pt handle of partition to boot
+ * @param[in] resource_cpu ID of the CPU resource to start
+ * @param[in] boot_addr 64-bit boot address
+ * @param[in] resource_mu ID of the MU that must be powered
+ * @param[in] resource_dev ID of the boot device that must be powered
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors:
+ * - SC_ERR_PARM if invalid partition, resource, or addr,
+ * - SC_ERR_NOACCESS if caller's partition is not the parent of the
+ * partition to boot
+ *
+ * This must be used to boot a partition. Only a partition booted this
+ * way can be rebooted using the watchdog, sc_pm_boot() or
+ * sc_pm_reboot_partition().
+ */
+sc_err_t sc_pm_boot(sc_ipc_t ipc, sc_rm_pt_t pt,
+ sc_rsrc_t resource_cpu, sc_faddr_t boot_addr,
+ sc_rsrc_t resource_mu, sc_rsrc_t resource_dev);
+
+/*!
+ * This function is used to change the boot parameters for a partition.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] resource_cpu ID of the CPU resource to start
+ * @param[in] boot_addr 64-bit boot address
+ * @param[in] resource_mu ID of the MU that must be powered (0=none)
+ * @param[in] resource_dev ID of the boot device that must be powered (0=none)
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors:
+ * - SC_ERR_PARM if invalid resource, or addr
+ *
+ * This function can be used to change the boot parameters for a partition.
+ * This can be useful if a partitions reboots differently from the initial
+ * boot done via sc_pm_boot() or via ROM.
+ */
+sc_err_t sc_pm_set_boot_parm(sc_ipc_t ipc,
+ sc_rsrc_t resource_cpu, sc_faddr_t boot_addr,
+ sc_rsrc_t resource_mu, sc_rsrc_t resource_dev);
+
+/*!
+ * This function is used to reboot the caller's partition.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] type reset type
+ *
+ * If \a type is SC_PM_RESET_TYPE_COLD, then most peripherals owned by
+ * the calling partition will be reset if possible. SC state (partitions,
+ * power, clocks, etc.) is reset. The boot SW of the booting CPU must be
+ * able to handle peripherals that that are not reset.
+ *
+ * If \a type is SC_PM_RESET_TYPE_WARM or SC_PM_RESET_TYPE_BOARD, then
+ * returns SC_ERR_PARM as these are not supported.
+ *
+ * If this function returns, then the reset did not occur due to an
+ * invalid parameter.
+ */
+void sc_pm_reboot(sc_ipc_t ipc, sc_pm_reset_type_t type);
+
+/*!
+ * This function is used to reboot a partition.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] pt handle of partition to reboot
+ * @param[in] type reset type
+ *
+ * If \a type is SC_PM_RESET_TYPE_COLD, then most peripherals owned by
+ * the calling partition will be reset if possible. SC state (partitions,
+ * power, clocks, etc.) is reset. The boot SW of the booting CPU must be
+ * able to handle peripherals that that are not reset.
+ *
+ * If \a type is SC_PM_RESET_TYPE_WARM or SC_PM_RESET_TYPE_BOARD, then
+ * returns SC_ERR_PARM as these are not supported.
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors:
+ * - SC_ERR_PARM if invalid partition or type
+ * - SC_ERR_NOACCESS if caller's partition is not the parent of \a pt
+ * and the caller does not have access to SC_R_SYSTEM
+ *
+ * Most peripherals owned by the partition will be reset if
+ * possible. SC state (partitions, power, clocks, etc.) is reset. The
+ * boot SW of the booting CPU must be able to handle peripherals that
+ * that are not reset.
+ *
+ * If board_reboot_part() returns a non-0 mask, then the reboot will
+ * be delayed until all partitions indicated in the mask have called
+ * sc_pm_reboot_continue() to continue the boot.
+ */
+sc_err_t sc_pm_reboot_partition(sc_ipc_t ipc, sc_rm_pt_t pt,
+ sc_pm_reset_type_t type);
+
+/*!
+ * This function is used to continue the reboot a partition.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] pt handle of partition to continue
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors:
+ * - SC_ERR_PARM if invalid partition
+ */
+sc_err_t sc_pm_reboot_continue(sc_ipc_t ipc, sc_rm_pt_t pt);
+
+/*!
+ * This function is used to start/stop a CPU.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] resource ID of the CPU resource
+ * @param[in] enable start if SC_TRUE; otherwise stop
+ * @param[in] address 64-bit boot address
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors:
+ * - SC_ERR_PARM if invalid resource or address,
+ * - SC_ERR_NOACCESS if caller's partition is not the parent of the
+ * resource (CPU) owner
+ *
+ * This function is usually used to start a secondar CPU in the
+ * same partition as the caller. It is not used to start the first
+ * CPU in a dedicated partition. That would be started by calling
+ * sc_pm_boot().
+ *
+ * A CPU started with sc_pm_cpu_start() will not restart as a result
+ * of a watchdog event or calling sc_pm_reboot() or sc_pm_reboot_partition().
+ * Those will reboot that partition which will start the CPU started with
+ * sc_pm_boot().
+ */
+sc_err_t sc_pm_cpu_start(sc_ipc_t ipc, sc_rsrc_t resource, sc_bool_t enable,
+ sc_faddr_t address);
+
+/*!
+ * This function is used to reset a CPU.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] resource ID of the CPU resource
+ * @param[in] address 64-bit boot address
+ *
+ * This function does not return anything as the calling core may have been
+ * reset. It can still fail if the resource or address is invalid. It can also
+ * fail if the caller's partition is not the owner of the CPU, not the parent
+ * of the CPU resource owner, or has access to SC_R_SYSTEM. Will also fail if
+ * the resource is not powered on. No indication of failure is returned.
+ *
+ * Note this just resets the CPU. None of the peripherals or bus fabric used by
+ * the CPU is reset. State configured in the SCFW is not reset. The SW running
+ * on the core has to understand and deal with this.
+ */
+void sc_pm_cpu_reset(sc_ipc_t ipc, sc_rsrc_t resource, sc_faddr_t address);
+
+/*!
+ * This function returns a bool indicating if a partition was started.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] pt handle of partition to check
+ *
+ * @return Returns a bool (SC_TRUE = started).
+ *
+ * Note this indicates if a partition was started. It does not indicate if a
+ * partition is currently running or in a low power state.
+ */
+sc_bool_t sc_pm_is_partition_started(sc_ipc_t ipc, sc_rm_pt_t pt);
+
+/* @} */
+
+#endif /* SC_PM_API_H */
+
+/**@}*/
+
diff --git a/include/soc/imx8/sc/svc/rm/api.h b/include/soc/imx8/sc/svc/rm/api.h
new file mode 100644
index 000000000000..0491c8d8f844
--- /dev/null
+++ b/include/soc/imx8/sc/svc/rm/api.h
@@ -0,0 +1,803 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017-2019 NXP
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+/*!
+ * Header file containing the public API for the System Controller (SC)
+ * Resource Management (RM) function. This includes functions for
+ * partitioning resources, pads, and memory regions.
+ *
+ * @addtogroup RM_SVC (SVC) Resource Management Service
+ *
+ * Module for the Resource Management (RM) service.
+ *
+ * @includedoc rm/details.dox
+ *
+ * @{
+ */
+
+#ifndef SC_RM_API_H
+#define SC_RM_API_H
+
+/* Includes */
+
+#include <soc/imx8/sc/types.h>
+
+/* Defines */
+
+/*!
+ * @name Defines for type widths
+ */
+/*@{*/
+#define SC_RM_PARTITION_W 5U /* Width of sc_rm_pt_t */
+#define SC_RM_MEMREG_W 6U /* Width of sc_rm_mr_t */
+#define SC_RM_DID_W 4U /* Width of sc_rm_did_t */
+#define SC_RM_SID_W 6U /* Width of sc_rm_sid_t */
+#define SC_RM_SPA_W 2U /* Width of sc_rm_spa_t */
+#define SC_RM_PERM_W 3U /* Width of sc_rm_perm_t */
+/*@}*/
+
+/*!
+ * @name Defines for ALL parameters
+ */
+/*@{*/
+#define SC_RM_PT_ALL ((sc_rm_pt_t) UINT8_MAX) /* All partitions */
+#define SC_RM_MR_ALL ((sc_rm_mr_t) UINT8_MAX) /* All memory regions */
+/*@}*/
+
+/*!
+ * @name Defines for sc_rm_spa_t
+ */
+/*@{*/
+#define SC_RM_SPA_PASSTHRU 0U /* Pass through (attribute driven by master) */
+#define SC_RM_SPA_PASSSID 1U /* Pass through and output on SID */
+#define SC_RM_SPA_ASSERT 2U /* Assert (force to be secure/privileged) */
+#define SC_RM_SPA_NEGATE 3U /* Negate (force to be non-secure/user) */
+/*@}*/
+
+/*!
+ * @name Defines for sc_rm_perm_t
+ */
+/*@{*/
+#define SC_RM_PERM_NONE 0U /* No access */
+#define SC_RM_PERM_SEC_R 1U /* Secure RO */
+#define SC_RM_PERM_SECPRIV_RW 2U /* Secure privilege R/W */
+#define SC_RM_PERM_SEC_RW 3U /* Secure R/W */
+#define SC_RM_PERM_NSPRIV_R 4U /* Secure R/W, non-secure privilege RO */
+#define SC_RM_PERM_NS_R 5U /* Secure R/W, non-secure RO */
+#define SC_RM_PERM_NSPRIV_RW 6U /* Secure R/W, non-secure privilege R/W */
+#define SC_RM_PERM_FULL 7U /* Full access */
+/*@}*/
+
+/* Types */
+
+/*!
+ * This type is used to declare a resource partition.
+ */
+typedef uint8_t sc_rm_pt_t;
+
+/*!
+ * This type is used to declare a memory region.
+ */
+typedef uint8_t sc_rm_mr_t;
+
+/*!
+ * This type is used to declare a resource domain ID used by the
+ * isolation HW.
+ */
+typedef uint8_t sc_rm_did_t;
+
+/*!
+ * This type is used to declare an SMMU StreamID.
+ */
+typedef uint16_t sc_rm_sid_t;
+
+/*!
+ * This type is a used to declare master transaction attributes.
+ */
+typedef uint8_t sc_rm_spa_t;
+
+/*!
+ * This type is used to declare a resource/memory region access permission.
+ * Refer to the XRDC2 Block Guide for more information.
+ */
+typedef uint8_t sc_rm_perm_t;
+
+/* Functions */
+
+/*!
+ * @name Partition Functions
+ * @{
+ */
+
+/*!
+ * This function requests that the SC create a new resource partition.
+ *
+ * @param[in] ipc IPC handle
+ * @param[out] pt return handle for partition; used for subsequent function
+ * calls associated with this partition
+ * @param[in] secure boolean indicating if this partition should be secure; only
+ * valid if caller is secure
+ * @param[in] isolated boolean indicating if this partition should be HW isolated
+ * via XRDC; set SC_TRUE if new DID is desired
+ * @param[in] restricted boolean indicating if this partition should be restricted; set
+ * SC_TRUE if masters in this partition cannot create new partitions
+ * @param[in] grant boolean indicating if this partition should always grant
+ * access and control to the parent
+ * @param[in] coherent boolean indicating if this partition is coherent;
+ * set SC_TRUE if only this partition will contain both AP clusters
+ * and they will be coherent via the CCI
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors:
+ * - SC_ERR_NOACCESS if caller's partition is restricted,
+ * - SC_ERR_PARM if caller's partition is not secure but a new secure partition is requested,
+ * - SC_ERR_LOCKED if caller's partition is locked,
+ * - SC_ERR_UNAVAILABLE if partition table is full (no more allocation space)
+ *
+ * Marking as non-secure prevents subsequent functions from configuring masters in this
+ * partition to assert the secure signal. If restricted then the new partition is limited
+ * in what functions it can call, especially those associated with managing partitions.
+ *
+ * The grant option is usually used to isolate a bus master's traffic to specific
+ * memory without isolating the peripheral interface of the master or the API
+ * controls of that master.
+ */
+sc_err_t sc_rm_partition_alloc(sc_ipc_t ipc, sc_rm_pt_t *pt, sc_bool_t secure,
+ sc_bool_t isolated, sc_bool_t restricted, sc_bool_t grant, sc_bool_t coherent);
+
+/*!
+ * This function makes a partition confidential.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] pt handle of partition that is granting
+ * @param[in] retro retroactive
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors:
+ * - SC_PARM if \a pt out of range,
+ * - SC_ERR_NOACCESS if caller's not allowed to change \a pt
+ * - SC_ERR_LOCKED if partition \a pt is locked
+ *
+ * Call to make a partition confidential. Confidential means only this
+ * partition should be able to grant access permissions to this partition.
+ *
+ * If retroactive, then all resources owned by other partitions will have
+ * access rights for this partition removed, even if locked.
+ */
+sc_err_t sc_rm_set_confidential(sc_ipc_t ipc, sc_rm_pt_t pt, sc_bool_t retro);
+
+/*!
+ * This function frees a partition and assigns all resources to the caller.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] pt handle of partition to free
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors:
+ * - SC_ERR_NOACCESS if caller's partition is restricted,
+ * - SC_PARM if \a pt out of range or invalid,
+ * - SC_ERR_NOACCESS if \a pt is the SC partition,
+ * - SC_ERR_NOACCESS if caller's partition is not the parent of \a pt,
+ * - SC_ERR_LOCKED if \a pt or caller's partition is locked
+ *
+ * All resources, memory regions, and pads are assigned to the caller/parent.
+ * The partition watchdog is disabled (even if locked). DID is freed.
+ */
+sc_err_t sc_rm_partition_free(sc_ipc_t ipc, sc_rm_pt_t pt);
+
+/*!
+ * This function returns the DID of a partition.
+ *
+ * @param[in] ipc IPC handle
+ *
+ * @return Returns the domain ID (DID) of the caller's partition.
+ *
+ * The DID is a SoC-specific internal ID used by the HW resource
+ * protection mechanism. It is only required by clients when using the
+ * SEMA42 module as the DID is sometimes connected to the master ID.
+ */
+sc_rm_did_t sc_rm_get_did(sc_ipc_t ipc);
+
+/*!
+ * This function forces a partition to use a specific static DID.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] pt handle of partition to assign \a did
+ * @param[in] did static DID to assign
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors:
+ * - SC_ERR_NOACCESS if caller's partition is restricted,
+ * - SC_PARM if \a pt or \a did out of range,
+ * - SC_ERR_NOACCESS if caller's partition is not the parent of \a pt,
+ * - SC_ERR_LOCKED if \a pt is locked
+ *
+ * Assumes no assigned resources or memory regions yet! The number of static
+ * DID is fixed by the SC at boot.
+ */
+sc_err_t sc_rm_partition_static(sc_ipc_t ipc, sc_rm_pt_t pt,
+ sc_rm_did_t did);
+
+/*!
+ * This function locks a partition.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] pt handle of partition to lock
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors:
+ * - SC_PARM if \a pt out of range,
+ * - SC_ERR_NOACCESS if caller's partition is not the parent of \a pt
+ *
+ * If a partition is locked it cannot be freed, have resources/pads assigned
+ * to/from it, memory regions created/assigned, DID changed, or parent changed.
+ */
+sc_err_t sc_rm_partition_lock(sc_ipc_t ipc, sc_rm_pt_t pt);
+
+/*!
+ * This function gets the partition handle of the caller.
+ *
+ * @param[in] ipc IPC handle
+ * @param[out] pt return handle for caller's partition
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ */
+sc_err_t sc_rm_get_partition(sc_ipc_t ipc, sc_rm_pt_t *pt);
+
+/*!
+ * This function sets a new parent for a partition.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] pt handle of partition for which parent is to be
+ * changed
+ * @param[in] pt_parent handle of partition to set as parent
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors:
+ * - SC_ERR_NOACCESS if caller's partition is restricted,
+ * - SC_PARM if arguments out of range or invalid,
+ * - SC_ERR_NOACCESS if caller's partition is not the parent of \a pt,
+ * - SC_ERR_LOCKED if either partition is locked
+ */
+sc_err_t sc_rm_set_parent(sc_ipc_t ipc, sc_rm_pt_t pt,
+ sc_rm_pt_t pt_parent);
+
+/*!
+ * This function moves all movable resources/pads owned by a source partition
+ * to a destination partition. It can be used to more quickly set up a new
+ * partition if a majority of the caller's resources are to be moved to a
+ * new partition.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] pt_src handle of partition from which resources should
+ * be moved from
+ * @param[in] pt_dst handle of partition to which resources should be
+ * moved to
+ * @param[in] move_rsrc boolean to indicate if resources should be moved
+ * @param[in] move_pads boolean to indicate if pads should be moved
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * By default, all resources are movable. This can be changed using the
+ * sc_rm_set_resource_movable() function. Note all masters defaulted to SMMU
+ * bypass.
+ *
+ * Return errors:
+ * - SC_ERR_NOACCESS if caller's partition is restricted,
+ * - SC_PARM if arguments out of range or invalid,
+ * - SC_ERR_NOACCESS if caller's partition is not \a pt_src or the
+ * parent of \a pt_src,
+ * - SC_ERR_LOCKED if either partition is locked
+ */
+sc_err_t sc_rm_move_all(sc_ipc_t ipc, sc_rm_pt_t pt_src, sc_rm_pt_t pt_dst,
+ sc_bool_t move_rsrc, sc_bool_t move_pads);
+
+/* @} */
+
+/*!
+ * @name Resource Functions
+ * @{
+ */
+
+/*!
+ * This function assigns ownership of a resource to a partition.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] pt handle of partition to which resource should be
+ * assigned
+ * @param[in] resource resource to assign
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * This action resets the resource's master and peripheral attributes.
+ * Privilege attribute will be PASSTHRU, security attribute will be
+ * ASSERT if the partition si secure and NEGATE if it is not, and
+ * masters will defaulted to SMMU bypass. Access permissions will reset
+ * to SEC_RW for the owning partition only for secure partitions, FULL for
+ * non-secure. Default is no access by other partitions.
+ *
+ * Return errors:
+ * - SC_ERR_NOACCESS if caller's partition is restricted,
+ * - SC_PARM if arguments out of range or invalid,
+ * - SC_ERR_NOACCESS if caller's partition is not the resource owner or parent
+ * of the owner,
+ * - SC_ERR_LOCKED if the owning partition or \a pt is locked
+ */
+sc_err_t sc_rm_assign_resource(sc_ipc_t ipc, sc_rm_pt_t pt,
+ sc_rsrc_t resource);
+
+/*!
+ * This function flags resources as movable or not.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] resource_fst first resource for which flag should be set
+ * @param[in] resource_lst last resource for which flag should be set
+ * @param[in] movable movable flag (SC_TRUE is movable)
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors:
+ * - SC_PARM if resources are out of range,
+ * - SC_ERR_NOACCESS if caller's partition is not a parent of a resource owner,
+ * - SC_ERR_LOCKED if the owning partition is locked
+ *
+ * This function is used to determine the set of resources that will be
+ * moved using the sc_rm_move_all() function. All resources are movable
+ * by default so this function is normally used to prevent a set of
+ * resources from moving.
+ */
+sc_err_t sc_rm_set_resource_movable(sc_ipc_t ipc, sc_rsrc_t resource_fst,
+ sc_rsrc_t resource_lst, sc_bool_t movable);
+
+/*!
+ * This function flags all of a subsystem's resources as movable
+ * or not.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] resource resource to use to identify subsystem
+ * @param[in] movable movable flag (SC_TRUE is movable)
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors:
+ * - SC_ERR_PARM if a function argument is out of range
+ *
+ * Note \a resource is used to find the associated subsystem. Only
+ * resources owned by the caller are set.
+ */
+sc_err_t sc_rm_set_subsys_rsrc_movable(sc_ipc_t ipc, sc_rsrc_t resource,
+ sc_bool_t movable);
+
+/*!
+ * This function sets attributes for a resource which is a bus master (i.e.
+ * capable of DMA).
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] resource master resource for which attributes should apply
+ * @param[in] sa security attribute
+ * @param[in] pa privilege attribute
+ * @param[in] smmu_bypass SMMU bypass mode
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors:
+ * - SC_ERR_NOACCESS if caller's partition is restricted,
+ * - SC_PARM if arguments out of range or invalid,
+ * - SC_ERR_NOACCESS if caller's partition is not a parent of the resource owner,
+ * - SC_ERR_LOCKED if the owning partition is locked
+ *
+ * This function configures how the HW isolation will see bus transactions
+ * from the specified master. Note the security attribute will only be
+ * changed if the caller's partition is secure.
+ */
+sc_err_t sc_rm_set_master_attributes(sc_ipc_t ipc, sc_rsrc_t resource,
+ sc_rm_spa_t sa, sc_rm_spa_t pa, sc_bool_t smmu_bypass);
+
+/*!
+ * This function sets the StreamID for a resource which is a bus master (i.e.
+ * capable of DMA).
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] resource master resource for which attributes should apply
+ * @param[in] sid StreamID
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors:
+ * - SC_ERR_NOACCESS if caller's partition is restricted,
+ * - SC_PARM if arguments out of range or invalid,
+ * - SC_ERR_NOACCESS if caller's partition is not the resource owner or parent
+ * of the owner,
+ * - SC_ERR_LOCKED if the owning partition is locked
+ *
+ * This function configures the SID attribute associated with all bus transactions
+ * from this master. Note 0 is not a valid SID as it is reserved to indicate
+ * bypass.
+ */
+sc_err_t sc_rm_set_master_sid(sc_ipc_t ipc, sc_rsrc_t resource,
+ sc_rm_sid_t sid);
+
+/*!
+ * This function sets access permissions for a peripheral resource.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] resource peripheral resource for which permissions should apply
+ * @param[in] pt handle of partition \a perm should by applied for
+ * @param[in] perm permissions to apply to \a resource for \a pt
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors:
+ * - SC_PARM if arguments out of range or invalid,
+ * - SC_ERR_NOACCESS if caller's partition is not the resource owner or parent
+ * of the owner,
+ * - SC_ERR_LOCKED if the owning partition is locked
+ * - SC_ERR_LOCKED if the \a pt is confidential and the caller isn't \a pt
+ *
+ * This function configures how the HW isolation will restrict access to a
+ * peripheral based on the attributes of a transaction from bus master. It
+ * also allows the access permissions of SC_R_SYSTEM to be set.
+ */
+sc_err_t sc_rm_set_peripheral_permissions(sc_ipc_t ipc, sc_rsrc_t resource,
+ sc_rm_pt_t pt, sc_rm_perm_t perm);
+
+/*!
+ * This function gets ownership status of a resource.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] resource resource to check
+ *
+ * @return Returns a boolean (SC_TRUE if caller's partition owns the resource).
+ *
+ * If \a resource is out of range then SC_FALSE is returned.
+ */
+sc_bool_t sc_rm_is_resource_owned(sc_ipc_t ipc, sc_rsrc_t resource);
+
+/*!
+ * This function is used to get the owner of a resource.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] resource resource to check
+ * @param[out] pt pointer to return owning partition
+ *
+ * @return Returns a boolean (SC_TRUE if the resource is a bus master).
+ *
+ * Return errors:
+ * - SC_PARM if arguments out of range or invalid
+ *
+ * If \a resource is out of range then SC_ERR_PARM is returned.
+ */
+sc_err_t sc_rm_get_resource_owner(sc_ipc_t ipc, sc_rsrc_t resource,
+ sc_rm_pt_t *pt);
+
+/*!
+ * This function is used to test if a resource is a bus master.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] resource resource to check
+ *
+ * @return Returns a boolean (SC_TRUE if the resource is a bus master).
+ *
+ * If \a resource is out of range then SC_FALSE is returned.
+ */
+sc_bool_t sc_rm_is_resource_master(sc_ipc_t ipc, sc_rsrc_t resource);
+
+/*!
+ * This function is used to test if a resource is a peripheral.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] resource resource to check
+ *
+ * @return Returns a boolean (SC_TRUE if the resource is a peripheral).
+ *
+ * If \a resource is out of range then SC_FALSE is returned.
+ */
+sc_bool_t sc_rm_is_resource_peripheral(sc_ipc_t ipc, sc_rsrc_t resource);
+
+/*!
+ * This function is used to obtain info about a resource.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] resource resource to inquire about
+ * @param[out] sid pointer to return StreamID
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors:
+ * - SC_PARM if \a resource is out of range
+ */
+sc_err_t sc_rm_get_resource_info(sc_ipc_t ipc, sc_rsrc_t resource,
+ sc_rm_sid_t *sid);
+
+/* @} */
+
+/*!
+ * @name Memory Region Functions
+ * @{
+ */
+
+/*!
+ * This function requests that the SC create a new memory region.
+ *
+ * @param[in] ipc IPC handle
+ * @param[out] mr return handle for region; used for
+ * subsequent function calls
+ * associated with this region
+ * @param[in] addr_start start address of region (physical)
+ * @param[in] addr_end end address of region (physical)
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors:
+ * - SC_ERR_PARM if the new memory region is misaligned,
+ * - SC_ERR_LOCKED if caller's partition is locked,
+ * - SC_ERR_PARM if the new memory region spans multiple existing regions,
+ * - SC_ERR_NOACCESS if caller's partition does not own the memory containing
+ * the new region,
+ * - SC_ERR_UNAVAILABLE if memory region table is full (no more allocation
+ * space)
+ *
+ * The area covered by the memory region must currently be owned by the caller.
+ * By default, the new region will have access permission set to allow the
+ * caller to access.
+ */
+sc_err_t sc_rm_memreg_alloc(sc_ipc_t ipc, sc_rm_mr_t *mr,
+ sc_faddr_t addr_start, sc_faddr_t addr_end);
+
+/*!
+ * This function requests that the SC split a memory region.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] mr handle of memory region to split
+ * @param[out] mr_ret return handle for new region; used for
+ * subsequent function calls
+ * associated with this region
+ * @param[in] addr_start start address of region (physical)
+ * @param[in] addr_end end address of region (physical)
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors:
+ * - SC_ERR_PARM if the new memory region is not start/end part of mr,
+ * - SC_ERR_LOCKED if caller's partition is locked,
+ * - SC_ERR_PARM if the new memory region spans multiple existing regions,
+ * - SC_ERR_NOACCESS if caller's partition does not own the memory containing
+ * the new region,
+ * - SC_ERR_UNAVAILABLE if memory region table is full (no more allocation
+ * space)
+ *
+ * Note the new region must start or end on the split region.
+ */
+sc_err_t sc_rm_memreg_split(sc_ipc_t ipc, sc_rm_mr_t mr,
+ sc_rm_mr_t *mr_ret, sc_faddr_t addr_start, sc_faddr_t addr_end);
+
+/*!
+ * This function requests that the SC fragment a memory region.
+ *
+ * @param[in] ipc IPC handle
+ * @param[out] mr_ret return handle for new region; used for
+ * subsequent function calls
+ * associated with this region
+ * @param[in] addr_start start address of region (physical)
+ * @param[in] addr_end end address of region (physical)
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors:
+ * - SC_ERR_LOCKED if caller's partition is locked,
+ * - SC_ERR_PARM if the new memory region spans multiple existing regions,
+ * - SC_ERR_NOACCESS if caller's partition does not own the memory containing
+ * the new region,
+ * - SC_ERR_UNAVAILABLE if memory region table is full (no more allocation
+ * space)
+ *
+ * This function finds the memory region containing the address range.
+ * It then splits it as required and returns the extracted region.
+ */
+sc_err_t sc_rm_memreg_frag(sc_ipc_t ipc, sc_rm_mr_t *mr_ret,
+ sc_faddr_t addr_start, sc_faddr_t addr_end);
+
+/*!
+ * This function frees a memory region.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] mr handle of memory region to free
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors:
+ * - SC_PARM if \a mr out of range or invalid,
+ * - SC_ERR_NOACCESS if caller's partition is not a parent of \a mr,
+ * - SC_ERR_LOCKED if the owning partition of \a mr is locked
+ */
+sc_err_t sc_rm_memreg_free(sc_ipc_t ipc, sc_rm_mr_t mr);
+
+/*!
+ * Internal SC function to find a memory region.
+ *
+ * @see sc_rm_find_memreg().
+ */
+/*!
+ * This function finds a memory region.
+ *
+ * @param[in] ipc IPC handle
+ * @param[out] mr return handle for region; used for
+ * subsequent function calls
+ * associated with this region
+ * @param[in] addr_start start address of region to search for
+ * @param[in] addr_end end address of region to search for
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors:
+ * - SC_ERR_NOTFOUND if region not found,
+ *
+ * Searches only for regions owned by the caller. Finds first
+ * region containing the range specified.
+ */
+sc_err_t sc_rm_find_memreg(sc_ipc_t ipc, sc_rm_mr_t *mr,
+ sc_faddr_t addr_start, sc_faddr_t addr_end);
+
+/*!
+ * This function assigns ownership of a memory region.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] pt handle of partition to which memory region
+ * should be assigned
+ * @param[in] mr handle of memory region to assign
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors:
+ * - SC_PARM if arguments out of range or invalid,
+ * - SC_ERR_NOACCESS if caller's partition is not the \a mr owner or parent
+ * of the owner,
+ * - SC_ERR_LOCKED if the owning partition or \a pt is locked
+ */
+sc_err_t sc_rm_assign_memreg(sc_ipc_t ipc, sc_rm_pt_t pt, sc_rm_mr_t mr);
+
+/*!
+ * This function sets access permissions for a memory region.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] mr handle of memory region for which permissions
+ * should apply
+ * @param[in] pt handle of partition \a perm should by
+ * applied for
+ * @param[in] perm permissions to apply to \a mr for \a pt
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors:
+ * - SC_PARM if arguments out of range or invalid,
+ * - SC_ERR_NOACCESS if caller's partition is not the region owner or parent
+ * of the owner,
+ * - SC_ERR_LOCKED if the owning partition is locked
+ * - SC_ERR_LOCKED if the \a pt is confidential and the caller isn't \a pt
+ *
+ * This function configures how the HW isolation will restrict access to a
+ * memory region based on the attributes of a transaction from bus master.
+ */
+sc_err_t sc_rm_set_memreg_permissions(sc_ipc_t ipc, sc_rm_mr_t mr,
+ sc_rm_pt_t pt, sc_rm_perm_t perm);
+
+/*!
+ * This function gets ownership status of a memory region.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] mr handle of memory region to check
+ *
+ * @return Returns a boolean (SC_TRUE if caller's partition owns the
+ * memory region).
+ *
+ * If \a mr is out of range then SC_FALSE is returned.
+ */
+sc_bool_t sc_rm_is_memreg_owned(sc_ipc_t ipc, sc_rm_mr_t mr);
+
+/*!
+ * This function is used to obtain info about a memory region.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] mr handle of memory region to inquire about
+ * @param[out] addr_start pointer to return start address
+ * @param[out] addr_end pointer to return end address
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors:
+ * - SC_PARM if \a mr is out of range
+ */
+sc_err_t sc_rm_get_memreg_info(sc_ipc_t ipc, sc_rm_mr_t mr,
+ sc_faddr_t *addr_start, sc_faddr_t *addr_end);
+
+/* @} */
+
+/*!
+ * @name Pad Functions
+ * @{
+ */
+
+/*!
+ * This function assigns ownership of a pad to a partition.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] pt handle of partition to which pad should
+ * be assigned
+ * @param[in] pad pad to assign
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors:
+ * - SC_ERR_NOACCESS if caller's partition is restricted,
+ * - SC_PARM if arguments out of range or invalid,
+ * - SC_ERR_NOACCESS if caller's partition is not the pad owner or parent
+ * of the owner,
+ * - SC_ERR_LOCKED if the owning partition or \a pt is locked
+ */
+sc_err_t sc_rm_assign_pad(sc_ipc_t ipc, sc_rm_pt_t pt, sc_pad_t pad);
+
+/*!
+ * This function flags pads as movable or not.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] pad_fst first pad for which flag should be set
+ * @param[in] pad_lst last pad for which flag should be set
+ * @param[in] movable movable flag (SC_TRUE is movable)
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors:
+ * - SC_PARM if pads are out of range,
+ * - SC_ERR_NOACCESS if caller's partition is not a parent of a pad owner,
+ * - SC_ERR_LOCKED if the owning partition is locked
+ *
+ * This function is used to determine the set of pads that will be
+ * moved using the sc_rm_move_all() function. All pads are movable
+ * by default so this function is normally used to prevent a set of
+ * pads from moving.
+ */
+sc_err_t sc_rm_set_pad_movable(sc_ipc_t ipc, sc_pad_t pad_fst,
+ sc_pad_t pad_lst, sc_bool_t movable);
+
+/*!
+ * This function gets ownership status of a pad.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] pad pad to check
+ *
+ * @return Returns a boolean (SC_TRUE if caller's partition owns the pad).
+ *
+ * If \a pad is out of range then SC_FALSE is returned.
+ */
+sc_bool_t sc_rm_is_pad_owned(sc_ipc_t ipc, sc_pad_t pad);
+
+/* @} */
+
+/*!
+ * @name Debug Functions
+ * @{
+ */
+
+/*!
+ * This function dumps the RM state for debug.
+ *
+ * @param[in] ipc IPC handle
+ */
+void sc_rm_dump(sc_ipc_t ipc);
+
+/* @} */
+
+#endif /* SC_RM_API_H */
+
+/**@}*/
+
diff --git a/include/soc/imx8/sc/svc/seco/api.h b/include/soc/imx8/sc/svc/seco/api.h
new file mode 100644
index 000000000000..54c911a32ae9
--- /dev/null
+++ b/include/soc/imx8/sc/svc/seco/api.h
@@ -0,0 +1,512 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017-2019 NXP
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+/*!
+ * Header file containing the public API for the System Controller (SC)
+ * Security (SECO) function.
+ *
+ * @addtogroup SECO_SVC (SVC) Security Service
+ *
+ * Module for the Security (SECO) service.
+ *
+ * @{
+ */
+
+#ifndef SC_SECO_API_H
+#define SC_SECO_API_H
+
+/* Includes */
+
+#include <soc/imx8/sc/types.h>
+#include <soc/imx8/sc/svc/rm/api.h>
+
+/* Defines */
+
+/*!
+ * @name Defines for sc_seco_auth_cmd_t
+ */
+/*@{*/
+#define SC_SECO_AUTH_CONTAINER 0U /* Authenticate container */
+#define SC_SECO_VERIFY_IMAGE 1U /* Verify image */
+#define SC_SECO_REL_CONTAINER 2U /* Release container */
+#define SC_SECO_AUTH_SECO_FW 3U /* SECO Firmware */
+#define SC_SECO_AUTH_HDMI_TX_FW 4U /* HDMI TX Firmware */
+#define SC_SECO_AUTH_HDMI_RX_FW 5U /* HDMI RX Firmware */
+/*@}*/
+
+/* Types */
+
+/*!
+ * This type is used to issue SECO authenticate commands.
+ */
+typedef uint8_t sc_seco_auth_cmd_t;
+
+/* Functions */
+
+/*!
+ * @name Image Functions
+ * @{
+ */
+
+/*!
+ * This function loads a SECO image.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] addr_src address of image source
+ * @param[in] addr_dst address of image destination
+ * @param[in] len lenth of image to load
+ * @param[in] fw SC_TRUE = firmware load
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors codes:
+ * - SC_ERR_PARM if word fuse index param out of range or invalid
+ * - SC_ERR_UNAVAILABLE if SECO not available
+ *
+ * This is used to load images via the SECO. Examples include SECO
+ * Firmware and IVT/CSF data used for authentication. These are usually
+ * loaded into SECO TCM. \a addr_src is in secure memory.
+ *
+ * See the Security Reference Manual (SRM) for more info.
+ */
+sc_err_t sc_seco_image_load(sc_ipc_t ipc, sc_faddr_t addr_src,
+ sc_faddr_t addr_dst, uint32_t len, sc_bool_t fw);
+
+/*!
+ * This function is used to authenticate a SECO image or command.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] cmd authenticate command
+ * @param[in] addr address of/or metadata
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors codes:
+ * - SC_ERR_PARM if word fuse index param out of range or invalid
+ * - SC_ERR_UNAVAILABLE if SECO not available
+ *
+ * This is used to authenticate a SECO image or issue a security
+ * command. \a addr often points to an container. It is also
+ * just data (or even unused) for some commands.
+ *
+ * See the Security Reference Manual (SRM) for more info.
+ */
+sc_err_t sc_seco_authenticate(sc_ipc_t ipc,
+ sc_seco_auth_cmd_t cmd, sc_faddr_t addr);
+
+/* @} */
+
+/*!
+ * @name Lifecycle Functions
+ * @{
+ */
+
+/*!
+ * This function updates the lifecycle of the device.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] change desired lifecycle transistion
+ *
+ * @return Returns and error code (SC_ERR_NONE = success).
+ *
+ * Return errors codes:
+ * - SC_ERR_UNAVAILABLE if SECO not available
+ *
+ * This message is used for going from Open to NXP Closed to OEM Closed.
+ * Note \a change is NOT the new desired lifecycle. It is a lifecycle
+ * transition as documented in the Security Reference Manual (SRM).
+ *
+ * If any SECO request fails or only succeeds because the part is in an
+ * "OEM open" lifecycle, then a request to transition from "NXP closed"
+ * to "OEM closed" will also fail. For example, booting a signed container
+ * when the OEM SRK is not fused will succeed, but as it is an abnormal
+ * situation, a subsequent request to transition the lifecycle will return
+ * an error.
+ */
+sc_err_t sc_seco_forward_lifecycle(sc_ipc_t ipc, uint32_t change);
+
+/*!
+ * This function updates the lifecycle to one of the return lifecycles.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] addr address of message block
+ *
+ * @return Returns and error code (SC_ERR_NONE = success).
+ *
+ * Return errors codes:
+ * - SC_ERR_UNAVAILABLE if SECO not available
+ *
+ * Note \a addr must be a pointer to a signed message block.
+ *
+ * To switch back to NXP states (Full Field Return), message must be signed
+ * by NXP SRK. For OEM States (Partial Field Return), must be signed by OEM
+ * SRK.
+ *
+ * See the Security Reference Manual (SRM) for more info.
+ */
+sc_err_t sc_seco_return_lifecycle(sc_ipc_t ipc, sc_faddr_t addr);
+
+/*!
+ * This function is used to commit into the fuses any new SRK revocation
+ * and FW version information that have been found in the primary and
+ * secondary containers.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in,out] info pointer to information type to be committed
+ *
+ * The return \a info will contain what was actually committed.
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors codes:
+ * - SC_ERR_PARM if \a info is invalid
+ * - SC_ERR_UNAVAILABLE if SECO not available
+ */
+sc_err_t sc_seco_commit(sc_ipc_t ipc, uint32_t *info);
+
+/* @} */
+
+/*!
+ * @name Attestation Functions
+ * @{
+ */
+
+/*!
+ * This function is used to set the attestation mode. Only the owner of
+ * the SC_R_ATTESTATION resource may make this call.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] mode mode
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors codes:
+ * - SC_ERR_PARM if \a mode is invalid
+ * - SC_ERR_NOACCESS if SC_R_ATTESTATON not owned by caller
+ * - SC_ERR_UNAVAILABLE if SECO not available
+ *
+ * This is used to set the SECO attestation mode. This can be prover
+ * or verfier. See the Security Reference Manual (SRM) for more on the
+ * suported modes, mode values, and mode behavior.
+ */
+sc_err_t sc_seco_attest_mode(sc_ipc_t ipc, uint32_t mode);
+
+/*!
+ * This function is used to request atestation. Only the owner of
+ * the SC_R_ATTESTATION resource may make this call.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] nonce unique value
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors codes:
+ * - SC_ERR_NOACCESS if SC_R_ATTESTATON not owned by caller
+ * - SC_ERR_UNAVAILABLE if SECO not available
+ *
+ * This is used to ask SECO to perform an attestation. The result depends
+ * on the attestation mode. After this call, the signature can be
+ * requested or a verify can be requested.
+ *
+ * See the Security Reference Manual (SRM) for more info.
+ */
+sc_err_t sc_seco_attest(sc_ipc_t ipc, uint64_t nonce);
+
+/*!
+ * This function is used to retrieve the attestation public key.
+ * Mode must be verifier. Only the owner of the SC_R_ATTESTATION resource
+ * may make this call.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] addr address to write response
+ *
+ * Result will be written to \a addr. The \a addr parmater must point
+ * to an address SECO can access. It must be 64-bit aligned. There
+ * should be 96 bytes of space.
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors codes:
+ * - SC_ERR_PARM if \a addr bad or attestation has not been requested
+ * - SC_ERR_NOACCESS if SC_R_ATTESTATON not owned by caller
+ * - SC_ERR_UNAVAILABLE if SECO not available
+ *
+ * See the Security Reference Manual (SRM) for more info.
+ */
+sc_err_t sc_seco_get_attest_pkey(sc_ipc_t ipc, sc_faddr_t addr);
+
+/*!
+ * This function is used to retrieve attestation signature and parameters.
+ * Mode must be provider. Only the owner of the SC_R_ATTESTATION resource
+ * may make this call.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] addr address to write response
+ *
+ * Result will be written to \a addr. The \a addr parmater must point
+ * to an address SECO can access. It must be 64-bit aligned. There
+ * should be 120 bytes of space.
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors codes:
+ * - SC_ERR_PARM if \a addr bad or attestation has not been requested
+ * - SC_ERR_NOACCESS if SC_R_ATTESTATON not owned by caller
+ * - SC_ERR_UNAVAILABLE if SECO not available
+ *
+ * See the Security Reference Manual (SRM) for more info.
+ */
+sc_err_t sc_seco_get_attest_sign(sc_ipc_t ipc, sc_faddr_t addr);
+
+/*!
+ * This function is used to verify attestation. Mode must be verifier.
+ * Only the owner of the SC_R_ATTESTATION resource may make this call.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] addr address of signature
+ *
+ * The \a addr parmater must point to an address SECO can access. It must be
+ * 64-bit aligned.
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors codes:
+ * - SC_ERR_PARM if \a addr bad or attestation has not been requested
+ * - SC_ERR_NOACCESS if SC_R_ATTESTATON not owned by caller
+ * - SC_ERR_UNAVAILABLE if SECO not available
+ * - SC_ERR_FAIL if signature doesn't match
+ *
+ * See the Security Reference Manual (SRM) for more info.
+ */
+sc_err_t sc_seco_attest_verify(sc_ipc_t ipc, sc_faddr_t addr);
+
+/* @} */
+
+/*!
+ * @name Key Functions
+ * @{
+ */
+
+/*!
+ * This function is used to generate a SECO key blob.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] id key identifier
+ * @param[in] load_addr load address
+ * @param[in] export_addr export address
+ * @param[in] max_size max export size
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors codes:
+ * - SC_ERR_PARM if word fuse index param out of range or invalid
+ * - SC_ERR_UNAVAILABLE if SECO not available
+ *
+ * This function is used to encapsulate sensitive keys in a specific structure
+ * called a blob, which provides both confidentiality and integrity protection.
+ *
+ * See the Security Reference Manual (SRM) for more info.
+ */
+sc_err_t sc_seco_gen_key_blob(sc_ipc_t ipc, uint32_t id,
+ sc_faddr_t load_addr, sc_faddr_t export_addr, uint16_t max_size);
+
+/*!
+ * This function is used to load a SECO key.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] id key identifier
+ * @param[in] addr key address
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors codes:
+ * - SC_ERR_PARM if word fuse index param out of range or invalid
+ * - SC_ERR_UNAVAILABLE if SECO not available
+ *
+ * This function is used to install private cryptographic keys encapsulated
+ * in a blob previously generated by SECO. The controller can be either the
+ * IEE or the VPU. The blob header carries the controller type and the key
+ * size, as provided by the user when generating the key blob.
+ *
+ * See the Security Reference Manual (SRM) for more info.
+ */
+sc_err_t sc_seco_load_key(sc_ipc_t ipc, uint32_t id,
+ sc_faddr_t addr);
+
+/* @} */
+
+/*!
+ * @name Manufacturing Protection Functions
+ * @{
+ */
+
+/*!
+ * This function is used to get the manufacturing protection public key.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] dst_addr destination address
+ * @param[in] dst_size destination size
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors codes:
+ * - SC_ERR_PARM if word fuse index param out of range or invalid
+ * - SC_ERR_UNAVAILABLE if SECO not available
+ *
+ * This function is supported only in OEM-closed lifecycle. It generates
+ * the mfg public key and stores it in a specific location in the secure
+ * memory.
+ *
+ * See the Security Reference Manual (SRM) for more info.
+ */
+sc_err_t sc_seco_get_mp_key(sc_ipc_t ipc, sc_faddr_t dst_addr,
+ uint16_t dst_size);
+
+/*!
+ * This function is used to update the manufacturing protection message
+ * register.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] addr data address
+ * @param[in] size size
+ * @param[in] lock lock_reg
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors codes:
+ * - SC_ERR_PARM if word fuse index param out of range or invalid
+ * - SC_ERR_UNAVAILABLE if SECO not available
+ *
+ * This function is supported only in OEM-closed lifecycle. It updates the
+ * content of the MPMR (Manufacturing Protection Message register of 256
+ * bits). This register will be appended to the input-data message when
+ * generating the signature. Please refer to the CAAM block guide for details.
+ *
+ * See the Security Reference Manual (SRM) for more info.
+ */
+sc_err_t sc_seco_update_mpmr(sc_ipc_t ipc, sc_faddr_t addr,
+ uint8_t size, uint8_t lock);
+
+/*!
+ * This function is used to get the manufacturing protection signature.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] msg_addr message address
+ * @param[in] msg_size message size
+ * @param[in] dst_addr destination address
+ * @param[in] dst_size destination size
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors codes:
+ * - SC_ERR_PARM if word fuse index param out of range or invalid
+ * - SC_ERR_UNAVAILABLE if SECO not available
+ *
+ * This function is used to generate an ECDSA signature for an input-data
+ * message and to store it in a specific location in the secure memory. It
+ * is only supported in OEM-closed lifecycle. In order to get the ECDSA
+ * signature, the RNG must be initialized. In case it has not been started
+ * an error will be returned.
+ *
+ * See the Security Reference Manual (SRM) for more info.
+ */
+sc_err_t sc_seco_get_mp_sign(sc_ipc_t ipc, sc_faddr_t msg_addr,
+ uint16_t msg_size, sc_faddr_t dst_addr, uint16_t dst_size);
+
+/* @} */
+
+/*!
+ * @name Debug Functions
+ * @{
+ */
+
+/*!
+ * This function is used to return the SECO FW build info.
+ *
+ * @param[in] ipc IPC handle
+ * @param[out] version pointer to return build number
+ * @param[out] commit pointer to return commit ID (git SHA-1)
+ */
+void sc_seco_build_info(sc_ipc_t ipc, uint32_t *version,
+ uint32_t *commit);
+
+/*!
+ * This function is used to return SECO chip info.
+ *
+ * @param[in] ipc IPC handle
+ * @param[out] lc pointer to return lifecycle
+ * @param[out] monotonic pointer to return monotonic counter
+ * @param[out] uid_l pointer to return UID (lower 32 bits)
+ * @param[out] uid_h pointer to return UID (upper 32 bits)
+ *
+ * @return Returns and error code (SC_ERR_NONE = success).
+ */
+sc_err_t sc_seco_chip_info(sc_ipc_t ipc, uint16_t *lc,
+ uint16_t *monotonic, uint32_t *uid_l, uint32_t *uid_h);
+
+/*!
+ * This function securely enables debug.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] addr address of message block
+ *
+ * @return Returns and error code (SC_ERR_NONE = success).
+ *
+ * Return errors codes:
+ * - SC_ERR_UNAVAILABLE if SECO not available
+ *
+ * Note \a addr must be a pointer to a signed message block.
+ *
+ * See the Security Reference Manual (SRM) for more info.
+ */
+sc_err_t sc_seco_enable_debug(sc_ipc_t ipc, sc_faddr_t addr);
+
+/*!
+ * This function is used to return an event from the SECO error log.
+ *
+ * @param[in] ipc IPC handle
+ * @param[out] idx index of event to return
+ * @param[out] event pointer to return event
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Read of \a idx 0 captures events from SECO. Loop starting
+ * with 0 until an error is returned to dump all events.
+ */
+sc_err_t sc_seco_get_event(sc_ipc_t ipc, uint8_t idx,
+ uint32_t *event);
+
+/* @} */
+
+/*!
+ * @name Miscellaneous Functions
+ * @{
+ */
+
+/*!
+ * This function securely writes a group of fuse words.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] addr address of message block
+ *
+ * @return Returns and error code (SC_ERR_NONE = success).
+ *
+ * Return errors codes:
+ * - SC_ERR_UNAVAILABLE if SECO not available
+ *
+ * Note \a addr must be a pointer to a signed message block.
+ *
+ * See the Security Reference Manual (SRM) for more info.
+ */
+sc_err_t sc_seco_fuse_write(sc_ipc_t ipc, sc_faddr_t addr);
+
+/* @} */
+
+#endif /* SC_SECO_API_H */
+
+/**@}*/
+
diff --git a/include/soc/imx8/sc/svc/timer/api.h b/include/soc/imx8/sc/svc/timer/api.h
new file mode 100644
index 000000000000..6c80ceaf53f6
--- /dev/null
+++ b/include/soc/imx8/sc/svc/timer/api.h
@@ -0,0 +1,364 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017-2019 NXP
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+/*!
+ * Header file containing the public API for the System Controller (SC)
+ * Timer function.
+ *
+ * @addtogroup TIMER_SVC (SVC) Timer Service
+ *
+ * Module for the Timer service. This includes support for the watchdog, RTC,
+ * and system counter. Note every resource partition has a watchdog it can
+ * use.
+ *
+ * @{
+ */
+
+#ifndef SC_TIMER_API_H
+#define SC_TIMER_API_H
+
+/* Includes */
+
+#include <soc/imx8/sc/types.h>
+#include <soc/imx8/sc/svc/rm/api.h>
+
+/* Defines */
+
+/*!
+ * @name Defines for type widths
+ */
+/*@{*/
+#define SC_TIMER_ACTION_W 3U /* Width of sc_timer_wdog_action_t */
+/*@}*/
+
+/*!
+ * @name Defines for sc_timer_wdog_action_t
+ */
+/*@{*/
+#define SC_TIMER_WDOG_ACTION_PARTITION 0U /* Reset partition */
+#define SC_TIMER_WDOG_ACTION_WARM 1U /* Warm reset system */
+#define SC_TIMER_WDOG_ACTION_COLD 2U /* Cold reset system */
+#define SC_TIMER_WDOG_ACTION_BOARD 3U /* Reset board */
+#define SC_TIMER_WDOG_ACTION_IRQ 4U /* Only generate IRQs */
+/*@}*/
+
+/* Types */
+
+/*!
+ * This type is used to configure the watchdog action.
+ */
+typedef uint8_t sc_timer_wdog_action_t;
+
+/*!
+ * This type is used to declare a watchdog time value in milliseconds.
+ */
+typedef uint32_t sc_timer_wdog_time_t;
+
+/* Functions */
+
+/*!
+ * @name Wathdog Functions
+ * @{
+ */
+
+/*!
+ * This function sets the watchdog timeout in milliseconds. If not
+ * set then the timeout defaults to the max. Once locked this value
+ * cannot be changed.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] timeout timeout period for the watchdog
+ *
+ * @return Returns an error code (SC_ERR_NONE = success, SC_ERR_LOCKED
+ * = locked).
+ */
+sc_err_t sc_timer_set_wdog_timeout(sc_ipc_t ipc,
+ sc_timer_wdog_time_t timeout);
+
+/*!
+ * This function sets the watchdog pre-timeout in milliseconds. If not
+ * set then the pre-timeout defaults to the max. Once locked this value
+ * cannot be changed.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] pre_timeout pre-timeout period for the watchdog
+ *
+ * When the pre-timout expires an IRQ will be generated. Note this timeout
+ * clears when the IRQ is triggered. An IRQ is generated for the failing
+ * partition and all of its child partitions.
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ */
+sc_err_t sc_timer_set_wdog_pre_timeout(sc_ipc_t ipc,
+ sc_timer_wdog_time_t pre_timeout);
+
+/*!
+ * This function starts the watchdog.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] lock boolean indicating the lock status
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * If \a lock is set then the watchdog cannot be stopped or the timeout
+ * period changed.
+ */
+sc_err_t sc_timer_start_wdog(sc_ipc_t ipc, sc_bool_t lock);
+
+/*!
+ * This function stops the watchdog if it is not locked.
+ *
+ * @param[in] ipc IPC handle
+ *
+ * @return Returns an error code (SC_ERR_NONE = success, SC_ERR_LOCKED
+ * = locked).
+ */
+sc_err_t sc_timer_stop_wdog(sc_ipc_t ipc);
+
+/*!
+ * This function pings (services, kicks) the watchdog resetting the time
+ * before expiration back to the timeout.
+ *
+ * @param[in] ipc IPC handle
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ */
+sc_err_t sc_timer_ping_wdog(sc_ipc_t ipc);
+
+/*!
+ * This function gets the status of the watchdog. All arguments are
+ * in milliseconds.
+ *
+ * @param[in] ipc IPC handle
+ * @param[out] timeout pointer to return the timeout
+ * @param[out] max_timeout pointer to return the max timeout
+ * @param[out] remaining_time pointer to return the time remaining
+ * until trigger
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ */
+sc_err_t sc_timer_get_wdog_status(sc_ipc_t ipc,
+ sc_timer_wdog_time_t *timeout, sc_timer_wdog_time_t *max_timeout,
+ sc_timer_wdog_time_t *remaining_time);
+
+/*!
+ * This function gets the status of the watchdog of a partition. All
+ * arguments are in milliseconds.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] pt partition to query
+ * @param[out] enb pointer to return enable status
+ * @param[out] timeout pointer to return the timeout
+ * @param[out] remaining_time pointer to return the time remaining
+ * until trigger
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ */
+sc_err_t sc_timer_pt_get_wdog_status(sc_ipc_t ipc, sc_rm_pt_t pt, sc_bool_t *enb,
+ sc_timer_wdog_time_t *timeout, sc_timer_wdog_time_t *remaining_time);
+
+/*!
+ * This function configures the action to be taken when a watchdog
+ * expires.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] pt partition to affect
+ * @param[in] action action to take
+ *
+ * Default action is inherited from the parent.
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors:
+ * - SC_ERR_PARM if invalid parameters,
+ * - SC_ERR_NOACCESS if caller's partition is not the SYSTEM owner,
+ * - SC_ERR_LOCKED if the watchdog is locked
+ */
+sc_err_t sc_timer_set_wdog_action(sc_ipc_t ipc,
+ sc_rm_pt_t pt, sc_timer_wdog_action_t action);
+
+/* @} */
+
+/*!
+ * @name Real-Time Clock (RTC) Functions
+ * @{
+ */
+
+/*!
+ * This function sets the RTC time. Only the owner of the SC_R_SYSTEM
+ * resource or a partition with access permissions to SC_R_SYSTEM can
+ * set the time.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] year year (min 1970)
+ * @param[in] mon month (1-12)
+ * @param[in] day day of the month (1-31)
+ * @param[in] hour hour (0-23)
+ * @param[in] min minute (0-59)
+ * @param[in] sec second (0-59)
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors:
+ * - SC_ERR_PARM if invalid time/date parameters,
+ * - SC_ERR_NOACCESS if caller's partition cannot access SC_R_SYSTEM
+ */
+sc_err_t sc_timer_set_rtc_time(sc_ipc_t ipc, uint16_t year, uint8_t mon,
+ uint8_t day, uint8_t hour, uint8_t min, uint8_t sec);
+
+/*!
+ * This function gets the RTC time.
+ *
+ * @param[in] ipc IPC handle
+ * @param[out] year pointer to return year (min 1970)
+ * @param[out] mon pointer to return month (1-12)
+ * @param[out] day pointer to return day of the month (1-31)
+ * @param[out] hour pointer to return hour (0-23)
+ * @param[out] min pointer to return minute (0-59)
+ * @param[out] sec pointer to return second (0-59)
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ */
+sc_err_t sc_timer_get_rtc_time(sc_ipc_t ipc, uint16_t *year, uint8_t *mon,
+ uint8_t *day, uint8_t *hour, uint8_t *min, uint8_t *sec);
+
+/*!
+ * This function gets the RTC time in seconds since 1/1/1970.
+ *
+ * @param[in] ipc IPC handle
+ * @param[out] sec pointer to return second
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ */
+sc_err_t sc_timer_get_rtc_sec1970(sc_ipc_t ipc, uint32_t *sec);
+
+/*!
+ * This function sets the RTC alarm.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] year year (min 1970)
+ * @param[in] mon month (1-12)
+ * @param[in] day day of the month (1-31)
+ * @param[in] hour hour (0-23)
+ * @param[in] min minute (0-59)
+ * @param[in] sec second (0-59)
+ *
+ * Note this alarm setting clears when the alarm is triggered. This is an
+ * absolute time.
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors:
+ * - SC_ERR_PARM if invalid time/date parameters
+ */
+sc_err_t sc_timer_set_rtc_alarm(sc_ipc_t ipc, uint16_t year, uint8_t mon,
+ uint8_t day, uint8_t hour, uint8_t min, uint8_t sec);
+
+/*!
+ * This function sets the RTC alarm (periodic mode).
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] sec period in seconds
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Note this is a relative time.
+ *
+ * Return errors:
+ * - SC_ERR_PARM if invalid time/date parameters
+ */
+sc_err_t sc_timer_set_rtc_periodic_alarm(sc_ipc_t ipc, uint32_t sec);
+
+/*!
+ * This function cancels the RTC alarm.
+ *
+ * @param[in] ipc IPC handle
+ *
+ * Note this alarm setting clears when the alarm is triggered.
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors:
+ * - SC_ERR_PARM if invalid time/date parameters
+ */
+sc_err_t sc_timer_cancel_rtc_alarm(sc_ipc_t ipc);
+
+/*!
+ * This function sets the RTC calibration value. Only the owner of the SC_R_SYSTEM
+ * resource or a partition with access permissions to SC_R_SYSTEM can set the
+ * calibration.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] count calbration count (-16 to 15)
+ *
+ * The calibration value is a 5-bit value including the sign bit, which is
+ * implemented in 2's complement. It is added or subtracted from the RTC on
+ * a perdiodic basis, once per 32768 cycles of the RTC clock.
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ */
+sc_err_t sc_timer_set_rtc_calb(sc_ipc_t ipc, int8_t count);
+
+/* @} */
+
+/*!
+ * @name System Counter (SYSCTR) Functions
+ * @{
+ */
+
+/*!
+ * This function sets the SYSCTR alarm.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] ticks number of 8MHz cycles
+ *
+ * Note the \a ticks parameter is an absolute time. This alarm
+ * setting clears when the alarm is triggered.
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors:
+ * - SC_ERR_PARM if invalid time/date parameters
+ */
+sc_err_t sc_timer_set_sysctr_alarm(sc_ipc_t ipc, uint64_t ticks);
+
+/*!
+ * This function sets the SYSCTR alarm (periodic mode).
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] ticks number of 8MHz cycles
+ *
+ * Note the \a ticks parameter is a relative time.
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors:
+ * - SC_ERR_PARM if invalid time/date parameters
+ */
+sc_err_t sc_timer_set_sysctr_periodic_alarm(sc_ipc_t ipc,
+ uint64_t ticks);
+
+/*!
+ * This function cancels the SYSCTR alarm.
+ *
+ * @param[in] ipc IPC handle
+ *
+ * Note this alarm setting clears when the alarm is triggered.
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors:
+ * - SC_ERR_PARM if invalid time/date parameters
+ */
+sc_err_t sc_timer_cancel_sysctr_alarm(sc_ipc_t ipc);
+
+/* @} */
+
+#endif /* SC_TIMER_API_H */
+
+/**@}*/
+
diff --git a/include/soc/imx8/sc/types.h b/include/soc/imx8/sc/types.h
new file mode 100644
index 000000000000..4d287c0ba02c
--- /dev/null
+++ b/include/soc/imx8/sc/types.h
@@ -0,0 +1,886 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017-2019 NXP
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+/*!
+ * Header file containing types used across multiple service APIs.
+ */
+
+#ifndef SC_TYPES_H
+#define SC_TYPES_H
+
+/* Includes */
+
+#include <soc/imx8/sc/scfw.h>
+
+/* Defines */
+
+#define SCFW_API_VERSION 100U
+
+/*!
+ * @name Defines for common frequencies
+ */
+/*@{*/
+#define SC_32KHZ 32768U /* 32KHz */
+#define SC_10MHZ 10000000U /* 10MHz */
+#define SC_20MHZ 20000000U /* 20MHz */
+#define SC_25MHZ 25000000U /* 25MHz */
+#define SC_27MHZ 27000000U /* 27MHz */
+#define SC_40MHZ 40000000U /* 40MHz */
+#define SC_45MHZ 45000000U /* 45MHz */
+#define SC_50MHZ 50000000U /* 50MHz */
+#define SC_60MHZ 60000000U /* 60MHz */
+#define SC_66MHZ 66666666U /* 66MHz */
+#define SC_74MHZ 74250000U /* 74.25MHz */
+#define SC_80MHZ 80000000U /* 80MHz */
+#define SC_83MHZ 83333333U /* 83MHz */
+#define SC_84MHZ 84375000U /* 84.37MHz */
+#define SC_100MHZ 100000000U /* 100MHz */
+#define SC_125MHZ 125000000U /* 125MHz */
+#define SC_133MHZ 133333333U /* 133MHz */
+#define SC_135MHZ 135000000U /* 135MHz */
+#define SC_150MHZ 150000000U /* 150MHz */
+#define SC_160MHZ 160000000U /* 160MHz */
+#define SC_166MHZ 166666666U /* 166MHz */
+#define SC_175MHZ 175000000U /* 175MHz */
+#define SC_180MHZ 180000000U /* 180MHz */
+#define SC_200MHZ 200000000U /* 200MHz */
+#define SC_250MHZ 250000000U /* 250MHz */
+#define SC_266MHZ 266666666U /* 266MHz */
+#define SC_300MHZ 300000000U /* 300MHz */
+#define SC_312MHZ 312500000U /* 312.5MHZ */
+#define SC_320MHZ 320000000U /* 320MHz */
+#define SC_325MHZ 325000000U /* 325MHz */
+#define SC_333MHZ 333333333U /* 333MHz */
+#define SC_350MHZ 350000000U /* 350MHz */
+#define SC_372MHZ 372000000U /* 372MHz */
+#define SC_375MHZ 375000000U /* 375MHz */
+#define SC_400MHZ 400000000U /* 400MHz */
+#define SC_500MHZ 500000000U /* 500MHz */
+#define SC_594MHZ 594000000U /* 594MHz */
+#define SC_625MHZ 625000000U /* 625MHz */
+#define SC_640MHZ 640000000U /* 640MHz */
+#define SC_648MHZ 648000000U /* 648MHz */
+#define SC_650MHZ 650000000U /* 650MHz */
+#define SC_667MHZ 666666667U /* 667MHz */
+#define SC_675MHZ 675000000U /* 675MHz */
+#define SC_700MHZ 700000000U /* 700MHz */
+#define SC_720MHZ 720000000U /* 720MHz */
+#define SC_750MHZ 750000000U /* 750MHz */
+#define SC_753MHZ 753000000U /* 753MHz */
+#define SC_793MHZ 793000000U /* 793MHz */
+#define SC_800MHZ 800000000U /* 800MHz */
+#define SC_850MHZ 850000000U /* 850MHz */
+#define SC_858MHZ 858000000U /* 858MHz */
+#define SC_900MHZ 900000000U /* 900MHz */
+#define SC_953MHZ 953000000U /* 953MHz */
+#define SC_963MHZ 963000000U /* 963MHz */
+#define SC_1000MHZ 1000000000U /* 1GHz */
+#define SC_1060MHZ 1060000000U /* 1.06GHz */
+#define SC_1068MHZ 1068000000U /* 1.068GHz */
+#define SC_1121MHZ 1121000000U /* 1.121GHz */
+#define SC_1173MHZ 1173000000U /* 1.173GHz */
+#define SC_1188MHZ 1188000000U /* 1.188GHz */
+#define SC_1260MHZ 1260000000U /* 1.26GHz */
+#define SC_1278MHZ 1278000000U /* 1.278GHz */
+#define SC_1280MHZ 1280000000U /* 1.28GHz */
+#define SC_1300MHZ 1300000000U /* 1.3GHz */
+#define SC_1313MHZ 1313000000U /* 1.313GHz */
+#define SC_1345MHZ 1345000000U /* 1.345GHz */
+#define SC_1400MHZ 1400000000U /* 1.4GHz */
+#define SC_1500MHZ 1500000000U /* 1.5GHz */
+#define SC_1600MHZ 1600000000U /* 1.6GHz */
+#define SC_1800MHZ 1800000000U /* 1.8GHz */
+#define SC_2000MHZ 2000000000U /* 2.0GHz */
+#define SC_2112MHZ 2112000000U /* 2.12GHz */
+/*@}*/
+
+/*!
+ * @name Defines for 24M related frequencies
+ */
+/*@{*/
+#define SC_8MHZ 8000000U /* 8MHz */
+#define SC_12MHZ 12000000U /* 12MHz */
+#define SC_19MHZ 19800000U /* 19.8MHz */
+#define SC_24MHZ 24000000U /* 24MHz */
+#define SC_48MHZ 48000000U /* 48MHz */
+#define SC_120MHZ 120000000U /* 120MHz */
+#define SC_132MHZ 132000000U /* 132MHz */
+#define SC_144MHZ 144000000U /* 144MHz */
+#define SC_192MHZ 192000000U /* 192MHz */
+#define SC_211MHZ 211200000U /* 211.2MHz */
+#define SC_240MHZ 240000000U /* 240MHz */
+#define SC_264MHZ 264000000U /* 264MHz */
+#define SC_352MHZ 352000000U /* 352MHz */
+#define SC_360MHZ 360000000U /* 360MHz */
+#define SC_384MHZ 384000000U /* 384MHz */
+#define SC_396MHZ 396000000U /* 396MHz */
+#define SC_432MHZ 432000000U /* 432MHz */
+#define SC_480MHZ 480000000U /* 480MHz */
+#define SC_600MHZ 600000000U /* 600MHz */
+#define SC_744MHZ 744000000U /* 744MHz */
+#define SC_792MHZ 792000000U /* 792MHz */
+#define SC_864MHZ 864000000U /* 864MHz */
+#define SC_960MHZ 960000000U /* 960MHz */
+#define SC_1056MHZ 1056000000U /* 1056MHz */
+#define SC_1104MHZ 1104000000U /* 1104MHz */
+#define SC_1200MHZ 1200000000U /* 1.2GHz */
+#define SC_1464MHZ 1464000000U /* 1.464GHz */
+#define SC_2400MHZ 2400000000U /* 2.4GHz */
+/*@}*/
+
+/*!
+ * @name Defines for A/V related frequencies
+ */
+/*@{*/
+#define SC_62MHZ 62937500U /* 62.9375MHz */
+#define SC_755MHZ 755250000U /* 755.25MHz */
+/*@}*/
+
+/*!
+ * @name Defines for type widths
+ */
+/*@{*/
+#define SC_BOOL_W 1U /* Width of sc_bool_t */
+#define SC_ERR_W 4U /* Width of sc_err_t */
+#define SC_RSRC_W 10U /* Width of sc_rsrc_t */
+#define SC_CTRL_W 6U /* Width of sc_ctrl_t */
+/*@}*/
+
+/*!
+ * @name Defines for sc_bool_t
+ */
+/*@{*/
+#define SC_FALSE ((sc_bool_t) 0U) /* False */
+#define SC_TRUE ((sc_bool_t) 1U) /* True */
+/*@}*/
+
+/*!
+ * @name Defines for sc_err_t.
+ */
+/*@{*/
+#define SC_ERR_NONE 0U /* Success */
+#define SC_ERR_VERSION 1U /* Incompatible API version */
+#define SC_ERR_CONFIG 2U /* Configuration error */
+#define SC_ERR_PARM 3U /* Bad parameter */
+#define SC_ERR_NOACCESS 4U /* Permission error (no access) */
+#define SC_ERR_LOCKED 5U /* Permission error (locked) */
+#define SC_ERR_UNAVAILABLE 6U /* Unavailable (out of resources) */
+#define SC_ERR_NOTFOUND 7U /* Not found */
+#define SC_ERR_NOPOWER 8U /* No power */
+#define SC_ERR_IPC 9U /* Generic IPC error */
+#define SC_ERR_BUSY 10U /* Resource is currently busy/active */
+#define SC_ERR_FAIL 11U /* General I/O failure */
+#define SC_ERR_LAST 12U
+/*@}*/
+
+/*!
+ * @name Defines for sc_rsrc_t.
+ */
+/*@{*/
+#define SC_R_A53 0U
+#define SC_R_A53_0 1U
+#define SC_R_A53_1 2U
+#define SC_R_A53_2 3U
+#define SC_R_A53_3 4U
+#define SC_R_A72 5U
+#define SC_R_A72_0 6U
+#define SC_R_A72_1 7U
+#define SC_R_A72_2 8U
+#define SC_R_A72_3 9U
+#define SC_R_CCI 10U
+#define SC_R_DB 11U
+#define SC_R_DRC_0 12U
+#define SC_R_DRC_1 13U
+#define SC_R_GIC_SMMU 14U
+#define SC_R_IRQSTR_M4_0 15U
+#define SC_R_IRQSTR_M4_1 16U
+#define SC_R_SMMU 17U
+#define SC_R_GIC 18U
+#define SC_R_DC_0_BLIT0 19U
+#define SC_R_DC_0_BLIT1 20U
+#define SC_R_DC_0_BLIT2 21U
+#define SC_R_DC_0_BLIT_OUT 22U
+#define SC_R_PERF 23U
+#define SC_R_UNUSED5 24U
+#define SC_R_DC_0_WARP 25U
+#define SC_R_UNUSED7 26U
+#define SC_R_UNUSED8 27U
+#define SC_R_DC_0_VIDEO0 28U
+#define SC_R_DC_0_VIDEO1 29U
+#define SC_R_DC_0_FRAC0 30U
+#define SC_R_UNUSED6 31U
+#define SC_R_DC_0 32U
+#define SC_R_GPU_2_PID0 33U
+#define SC_R_DC_0_PLL_0 34U
+#define SC_R_DC_0_PLL_1 35U
+#define SC_R_DC_1_BLIT0 36U
+#define SC_R_DC_1_BLIT1 37U
+#define SC_R_DC_1_BLIT2 38U
+#define SC_R_DC_1_BLIT_OUT 39U
+#define SC_R_UNUSED9 40U
+#define SC_R_UNUSED10 41U
+#define SC_R_DC_1_WARP 42U
+#define SC_R_UNUSED11 43U
+#define SC_R_UNUSED12 44U
+#define SC_R_DC_1_VIDEO0 45U
+#define SC_R_DC_1_VIDEO1 46U
+#define SC_R_DC_1_FRAC0 47U
+#define SC_R_UNUSED13 48U
+#define SC_R_DC_1 49U
+#define SC_R_UNUSED14 50U
+#define SC_R_DC_1_PLL_0 51U
+#define SC_R_DC_1_PLL_1 52U
+#define SC_R_SPI_0 53U
+#define SC_R_SPI_1 54U
+#define SC_R_SPI_2 55U
+#define SC_R_SPI_3 56U
+#define SC_R_UART_0 57U
+#define SC_R_UART_1 58U
+#define SC_R_UART_2 59U
+#define SC_R_UART_3 60U
+#define SC_R_UART_4 61U
+#define SC_R_EMVSIM_0 62U
+#define SC_R_EMVSIM_1 63U
+#define SC_R_DMA_0_CH0 64U
+#define SC_R_DMA_0_CH1 65U
+#define SC_R_DMA_0_CH2 66U
+#define SC_R_DMA_0_CH3 67U
+#define SC_R_DMA_0_CH4 68U
+#define SC_R_DMA_0_CH5 69U
+#define SC_R_DMA_0_CH6 70U
+#define SC_R_DMA_0_CH7 71U
+#define SC_R_DMA_0_CH8 72U
+#define SC_R_DMA_0_CH9 73U
+#define SC_R_DMA_0_CH10 74U
+#define SC_R_DMA_0_CH11 75U
+#define SC_R_DMA_0_CH12 76U
+#define SC_R_DMA_0_CH13 77U
+#define SC_R_DMA_0_CH14 78U
+#define SC_R_DMA_0_CH15 79U
+#define SC_R_DMA_0_CH16 80U
+#define SC_R_DMA_0_CH17 81U
+#define SC_R_DMA_0_CH18 82U
+#define SC_R_DMA_0_CH19 83U
+#define SC_R_DMA_0_CH20 84U
+#define SC_R_DMA_0_CH21 85U
+#define SC_R_DMA_0_CH22 86U
+#define SC_R_DMA_0_CH23 87U
+#define SC_R_DMA_0_CH24 88U
+#define SC_R_DMA_0_CH25 89U
+#define SC_R_DMA_0_CH26 90U
+#define SC_R_DMA_0_CH27 91U
+#define SC_R_DMA_0_CH28 92U
+#define SC_R_DMA_0_CH29 93U
+#define SC_R_DMA_0_CH30 94U
+#define SC_R_DMA_0_CH31 95U
+#define SC_R_I2C_0 96U
+#define SC_R_I2C_1 97U
+#define SC_R_I2C_2 98U
+#define SC_R_I2C_3 99U
+#define SC_R_I2C_4 100U
+#define SC_R_ADC_0 101U
+#define SC_R_ADC_1 102U
+#define SC_R_FTM_0 103U
+#define SC_R_FTM_1 104U
+#define SC_R_CAN_0 105U
+#define SC_R_CAN_1 106U
+#define SC_R_CAN_2 107U
+#define SC_R_DMA_1_CH0 108U
+#define SC_R_DMA_1_CH1 109U
+#define SC_R_DMA_1_CH2 110U
+#define SC_R_DMA_1_CH3 111U
+#define SC_R_DMA_1_CH4 112U
+#define SC_R_DMA_1_CH5 113U
+#define SC_R_DMA_1_CH6 114U
+#define SC_R_DMA_1_CH7 115U
+#define SC_R_DMA_1_CH8 116U
+#define SC_R_DMA_1_CH9 117U
+#define SC_R_DMA_1_CH10 118U
+#define SC_R_DMA_1_CH11 119U
+#define SC_R_DMA_1_CH12 120U
+#define SC_R_DMA_1_CH13 121U
+#define SC_R_DMA_1_CH14 122U
+#define SC_R_DMA_1_CH15 123U
+#define SC_R_DMA_1_CH16 124U
+#define SC_R_DMA_1_CH17 125U
+#define SC_R_DMA_1_CH18 126U
+#define SC_R_DMA_1_CH19 127U
+#define SC_R_DMA_1_CH20 128U
+#define SC_R_DMA_1_CH21 129U
+#define SC_R_DMA_1_CH22 130U
+#define SC_R_DMA_1_CH23 131U
+#define SC_R_DMA_1_CH24 132U
+#define SC_R_DMA_1_CH25 133U
+#define SC_R_DMA_1_CH26 134U
+#define SC_R_DMA_1_CH27 135U
+#define SC_R_DMA_1_CH28 136U
+#define SC_R_DMA_1_CH29 137U
+#define SC_R_DMA_1_CH30 138U
+#define SC_R_DMA_1_CH31 139U
+#define SC_R_UNUSED1 140U
+#define SC_R_UNUSED2 141U
+#define SC_R_UNUSED3 142U
+#define SC_R_UNUSED4 143U
+#define SC_R_GPU_0_PID0 144U
+#define SC_R_GPU_0_PID1 145U
+#define SC_R_GPU_0_PID2 146U
+#define SC_R_GPU_0_PID3 147U
+#define SC_R_GPU_1_PID0 148U
+#define SC_R_GPU_1_PID1 149U
+#define SC_R_GPU_1_PID2 150U
+#define SC_R_GPU_1_PID3 151U
+#define SC_R_PCIE_A 152U
+#define SC_R_SERDES_0 153U
+#define SC_R_MATCH_0 154U
+#define SC_R_MATCH_1 155U
+#define SC_R_MATCH_2 156U
+#define SC_R_MATCH_3 157U
+#define SC_R_MATCH_4 158U
+#define SC_R_MATCH_5 159U
+#define SC_R_MATCH_6 160U
+#define SC_R_MATCH_7 161U
+#define SC_R_MATCH_8 162U
+#define SC_R_MATCH_9 163U
+#define SC_R_MATCH_10 164U
+#define SC_R_MATCH_11 165U
+#define SC_R_MATCH_12 166U
+#define SC_R_MATCH_13 167U
+#define SC_R_MATCH_14 168U
+#define SC_R_PCIE_B 169U
+#define SC_R_SATA_0 170U
+#define SC_R_SERDES_1 171U
+#define SC_R_HSIO_GPIO 172U
+#define SC_R_MATCH_15 173U
+#define SC_R_MATCH_16 174U
+#define SC_R_MATCH_17 175U
+#define SC_R_MATCH_18 176U
+#define SC_R_MATCH_19 177U
+#define SC_R_MATCH_20 178U
+#define SC_R_MATCH_21 179U
+#define SC_R_MATCH_22 180U
+#define SC_R_MATCH_23 181U
+#define SC_R_MATCH_24 182U
+#define SC_R_MATCH_25 183U
+#define SC_R_MATCH_26 184U
+#define SC_R_MATCH_27 185U
+#define SC_R_MATCH_28 186U
+#define SC_R_LCD_0 187U
+#define SC_R_LCD_0_PWM_0 188U
+#define SC_R_LCD_0_I2C_0 189U
+#define SC_R_LCD_0_I2C_1 190U
+#define SC_R_PWM_0 191U
+#define SC_R_PWM_1 192U
+#define SC_R_PWM_2 193U
+#define SC_R_PWM_3 194U
+#define SC_R_PWM_4 195U
+#define SC_R_PWM_5 196U
+#define SC_R_PWM_6 197U
+#define SC_R_PWM_7 198U
+#define SC_R_GPIO_0 199U
+#define SC_R_GPIO_1 200U
+#define SC_R_GPIO_2 201U
+#define SC_R_GPIO_3 202U
+#define SC_R_GPIO_4 203U
+#define SC_R_GPIO_5 204U
+#define SC_R_GPIO_6 205U
+#define SC_R_GPIO_7 206U
+#define SC_R_GPT_0 207U
+#define SC_R_GPT_1 208U
+#define SC_R_GPT_2 209U
+#define SC_R_GPT_3 210U
+#define SC_R_GPT_4 211U
+#define SC_R_KPP 212U
+#define SC_R_MU_0A 213U
+#define SC_R_MU_1A 214U
+#define SC_R_MU_2A 215U
+#define SC_R_MU_3A 216U
+#define SC_R_MU_4A 217U
+#define SC_R_MU_5A 218U
+#define SC_R_MU_6A 219U
+#define SC_R_MU_7A 220U
+#define SC_R_MU_8A 221U
+#define SC_R_MU_9A 222U
+#define SC_R_MU_10A 223U
+#define SC_R_MU_11A 224U
+#define SC_R_MU_12A 225U
+#define SC_R_MU_13A 226U
+#define SC_R_MU_5B 227U
+#define SC_R_MU_6B 228U
+#define SC_R_MU_7B 229U
+#define SC_R_MU_8B 230U
+#define SC_R_MU_9B 231U
+#define SC_R_MU_10B 232U
+#define SC_R_MU_11B 233U
+#define SC_R_MU_12B 234U
+#define SC_R_MU_13B 235U
+#define SC_R_ROM_0 236U
+#define SC_R_FSPI_0 237U
+#define SC_R_FSPI_1 238U
+#define SC_R_IEE 239U
+#define SC_R_IEE_R0 240U
+#define SC_R_IEE_R1 241U
+#define SC_R_IEE_R2 242U
+#define SC_R_IEE_R3 243U
+#define SC_R_IEE_R4 244U
+#define SC_R_IEE_R5 245U
+#define SC_R_IEE_R6 246U
+#define SC_R_IEE_R7 247U
+#define SC_R_SDHC_0 248U
+#define SC_R_SDHC_1 249U
+#define SC_R_SDHC_2 250U
+#define SC_R_ENET_0 251U
+#define SC_R_ENET_1 252U
+#define SC_R_MLB_0 253U
+#define SC_R_DMA_2_CH0 254U
+#define SC_R_DMA_2_CH1 255U
+#define SC_R_DMA_2_CH2 256U
+#define SC_R_DMA_2_CH3 257U
+#define SC_R_DMA_2_CH4 258U
+#define SC_R_USB_0 259U
+#define SC_R_USB_1 260U
+#define SC_R_USB_0_PHY 261U
+#define SC_R_USB_2 262U
+#define SC_R_USB_2_PHY 263U
+#define SC_R_DTCP 264U
+#define SC_R_NAND 265U
+#define SC_R_LVDS_0 266U
+#define SC_R_LVDS_0_PWM_0 267U
+#define SC_R_LVDS_0_I2C_0 268U
+#define SC_R_LVDS_0_I2C_1 269U
+#define SC_R_LVDS_1 270U
+#define SC_R_LVDS_1_PWM_0 271U
+#define SC_R_LVDS_1_I2C_0 272U
+#define SC_R_LVDS_1_I2C_1 273U
+#define SC_R_LVDS_2 274U
+#define SC_R_LVDS_2_PWM_0 275U
+#define SC_R_LVDS_2_I2C_0 276U
+#define SC_R_LVDS_2_I2C_1 277U
+#define SC_R_M4_0_PID0 278U
+#define SC_R_M4_0_PID1 279U
+#define SC_R_M4_0_PID2 280U
+#define SC_R_M4_0_PID3 281U
+#define SC_R_M4_0_PID4 282U
+#define SC_R_M4_0_RGPIO 283U
+#define SC_R_M4_0_SEMA42 284U
+#define SC_R_M4_0_TPM 285U
+#define SC_R_M4_0_PIT 286U
+#define SC_R_M4_0_UART 287U
+#define SC_R_M4_0_I2C 288U
+#define SC_R_M4_0_INTMUX 289U
+#define SC_R_UNUSED15 290U
+#define SC_R_UNUSED16 291U
+#define SC_R_M4_0_MU_0B 292U
+#define SC_R_M4_0_MU_0A0 293U
+#define SC_R_M4_0_MU_0A1 294U
+#define SC_R_M4_0_MU_0A2 295U
+#define SC_R_M4_0_MU_0A3 296U
+#define SC_R_M4_0_MU_1A 297U
+#define SC_R_M4_1_PID0 298U
+#define SC_R_M4_1_PID1 299U
+#define SC_R_M4_1_PID2 300U
+#define SC_R_M4_1_PID3 301U
+#define SC_R_M4_1_PID4 302U
+#define SC_R_M4_1_RGPIO 303U
+#define SC_R_M4_1_SEMA42 304U
+#define SC_R_M4_1_TPM 305U
+#define SC_R_M4_1_PIT 306U
+#define SC_R_M4_1_UART 307U
+#define SC_R_M4_1_I2C 308U
+#define SC_R_M4_1_INTMUX 309U
+#define SC_R_UNUSED17 310U
+#define SC_R_UNUSED18 311U
+#define SC_R_M4_1_MU_0B 312U
+#define SC_R_M4_1_MU_0A0 313U
+#define SC_R_M4_1_MU_0A1 314U
+#define SC_R_M4_1_MU_0A2 315U
+#define SC_R_M4_1_MU_0A3 316U
+#define SC_R_M4_1_MU_1A 317U
+#define SC_R_SAI_0 318U
+#define SC_R_SAI_1 319U
+#define SC_R_SAI_2 320U
+#define SC_R_IRQSTR_SCU2 321U
+#define SC_R_IRQSTR_DSP 322U
+#define SC_R_ELCDIF_PLL 323U
+#define SC_R_OCRAM 324U
+#define SC_R_AUDIO_PLL_0 325U
+#define SC_R_PI_0 326U
+#define SC_R_PI_0_PWM_0 327U
+#define SC_R_PI_0_PWM_1 328U
+#define SC_R_PI_0_I2C_0 329U
+#define SC_R_PI_0_PLL 330U
+#define SC_R_PI_1 331U
+#define SC_R_PI_1_PWM_0 332U
+#define SC_R_PI_1_PWM_1 333U
+#define SC_R_PI_1_I2C_0 334U
+#define SC_R_PI_1_PLL 335U
+#define SC_R_SC_PID0 336U
+#define SC_R_SC_PID1 337U
+#define SC_R_SC_PID2 338U
+#define SC_R_SC_PID3 339U
+#define SC_R_SC_PID4 340U
+#define SC_R_SC_SEMA42 341U
+#define SC_R_SC_TPM 342U
+#define SC_R_SC_PIT 343U
+#define SC_R_SC_UART 344U
+#define SC_R_SC_I2C 345U
+#define SC_R_SC_MU_0B 346U
+#define SC_R_SC_MU_0A0 347U
+#define SC_R_SC_MU_0A1 348U
+#define SC_R_SC_MU_0A2 349U
+#define SC_R_SC_MU_0A3 350U
+#define SC_R_SC_MU_1A 351U
+#define SC_R_SYSCNT_RD 352U
+#define SC_R_SYSCNT_CMP 353U
+#define SC_R_DEBUG 354U
+#define SC_R_SYSTEM 355U
+#define SC_R_SNVS 356U
+#define SC_R_OTP 357U
+#define SC_R_VPU_PID0 358U
+#define SC_R_VPU_PID1 359U
+#define SC_R_VPU_PID2 360U
+#define SC_R_VPU_PID3 361U
+#define SC_R_VPU_PID4 362U
+#define SC_R_VPU_PID5 363U
+#define SC_R_VPU_PID6 364U
+#define SC_R_VPU_PID7 365U
+#define SC_R_VPU_UART 366U
+#define SC_R_VPUCORE 367U
+#define SC_R_VPUCORE_0 368U
+#define SC_R_VPUCORE_1 369U
+#define SC_R_VPUCORE_2 370U
+#define SC_R_VPUCORE_3 371U
+#define SC_R_DMA_4_CH0 372U
+#define SC_R_DMA_4_CH1 373U
+#define SC_R_DMA_4_CH2 374U
+#define SC_R_DMA_4_CH3 375U
+#define SC_R_DMA_4_CH4 376U
+#define SC_R_ISI_CH0 377U
+#define SC_R_ISI_CH1 378U
+#define SC_R_ISI_CH2 379U
+#define SC_R_ISI_CH3 380U
+#define SC_R_ISI_CH4 381U
+#define SC_R_ISI_CH5 382U
+#define SC_R_ISI_CH6 383U
+#define SC_R_ISI_CH7 384U
+#define SC_R_MJPEG_DEC_S0 385U
+#define SC_R_MJPEG_DEC_S1 386U
+#define SC_R_MJPEG_DEC_S2 387U
+#define SC_R_MJPEG_DEC_S3 388U
+#define SC_R_MJPEG_ENC_S0 389U
+#define SC_R_MJPEG_ENC_S1 390U
+#define SC_R_MJPEG_ENC_S2 391U
+#define SC_R_MJPEG_ENC_S3 392U
+#define SC_R_MIPI_0 393U
+#define SC_R_MIPI_0_PWM_0 394U
+#define SC_R_MIPI_0_I2C_0 395U
+#define SC_R_MIPI_0_I2C_1 396U
+#define SC_R_MIPI_1 397U
+#define SC_R_MIPI_1_PWM_0 398U
+#define SC_R_MIPI_1_I2C_0 399U
+#define SC_R_MIPI_1_I2C_1 400U
+#define SC_R_CSI_0 401U
+#define SC_R_CSI_0_PWM_0 402U
+#define SC_R_CSI_0_I2C_0 403U
+#define SC_R_CSI_1 404U
+#define SC_R_CSI_1_PWM_0 405U
+#define SC_R_CSI_1_I2C_0 406U
+#define SC_R_HDMI 407U
+#define SC_R_HDMI_I2S 408U
+#define SC_R_HDMI_I2C_0 409U
+#define SC_R_HDMI_PLL_0 410U
+#define SC_R_HDMI_RX 411U
+#define SC_R_HDMI_RX_BYPASS 412U
+#define SC_R_HDMI_RX_I2C_0 413U
+#define SC_R_ASRC_0 414U
+#define SC_R_ESAI_0 415U
+#define SC_R_SPDIF_0 416U
+#define SC_R_SPDIF_1 417U
+#define SC_R_SAI_3 418U
+#define SC_R_SAI_4 419U
+#define SC_R_SAI_5 420U
+#define SC_R_GPT_5 421U
+#define SC_R_GPT_6 422U
+#define SC_R_GPT_7 423U
+#define SC_R_GPT_8 424U
+#define SC_R_GPT_9 425U
+#define SC_R_GPT_10 426U
+#define SC_R_DMA_2_CH5 427U
+#define SC_R_DMA_2_CH6 428U
+#define SC_R_DMA_2_CH7 429U
+#define SC_R_DMA_2_CH8 430U
+#define SC_R_DMA_2_CH9 431U
+#define SC_R_DMA_2_CH10 432U
+#define SC_R_DMA_2_CH11 433U
+#define SC_R_DMA_2_CH12 434U
+#define SC_R_DMA_2_CH13 435U
+#define SC_R_DMA_2_CH14 436U
+#define SC_R_DMA_2_CH15 437U
+#define SC_R_DMA_2_CH16 438U
+#define SC_R_DMA_2_CH17 439U
+#define SC_R_DMA_2_CH18 440U
+#define SC_R_DMA_2_CH19 441U
+#define SC_R_DMA_2_CH20 442U
+#define SC_R_DMA_2_CH21 443U
+#define SC_R_DMA_2_CH22 444U
+#define SC_R_DMA_2_CH23 445U
+#define SC_R_DMA_2_CH24 446U
+#define SC_R_DMA_2_CH25 447U
+#define SC_R_DMA_2_CH26 448U
+#define SC_R_DMA_2_CH27 449U
+#define SC_R_DMA_2_CH28 450U
+#define SC_R_DMA_2_CH29 451U
+#define SC_R_DMA_2_CH30 452U
+#define SC_R_DMA_2_CH31 453U
+#define SC_R_ASRC_1 454U
+#define SC_R_ESAI_1 455U
+#define SC_R_SAI_6 456U
+#define SC_R_SAI_7 457U
+#define SC_R_AMIX 458U
+#define SC_R_MQS_0 459U
+#define SC_R_DMA_3_CH0 460U
+#define SC_R_DMA_3_CH1 461U
+#define SC_R_DMA_3_CH2 462U
+#define SC_R_DMA_3_CH3 463U
+#define SC_R_DMA_3_CH4 464U
+#define SC_R_DMA_3_CH5 465U
+#define SC_R_DMA_3_CH6 466U
+#define SC_R_DMA_3_CH7 467U
+#define SC_R_DMA_3_CH8 468U
+#define SC_R_DMA_3_CH9 469U
+#define SC_R_DMA_3_CH10 470U
+#define SC_R_DMA_3_CH11 471U
+#define SC_R_DMA_3_CH12 472U
+#define SC_R_DMA_3_CH13 473U
+#define SC_R_DMA_3_CH14 474U
+#define SC_R_DMA_3_CH15 475U
+#define SC_R_DMA_3_CH16 476U
+#define SC_R_DMA_3_CH17 477U
+#define SC_R_DMA_3_CH18 478U
+#define SC_R_DMA_3_CH19 479U
+#define SC_R_DMA_3_CH20 480U
+#define SC_R_DMA_3_CH21 481U
+#define SC_R_DMA_3_CH22 482U
+#define SC_R_DMA_3_CH23 483U
+#define SC_R_DMA_3_CH24 484U
+#define SC_R_DMA_3_CH25 485U
+#define SC_R_DMA_3_CH26 486U
+#define SC_R_DMA_3_CH27 487U
+#define SC_R_DMA_3_CH28 488U
+#define SC_R_DMA_3_CH29 489U
+#define SC_R_DMA_3_CH30 490U
+#define SC_R_DMA_3_CH31 491U
+#define SC_R_AUDIO_PLL_1 492U
+#define SC_R_AUDIO_CLK_0 493U
+#define SC_R_AUDIO_CLK_1 494U
+#define SC_R_MCLK_OUT_0 495U
+#define SC_R_MCLK_OUT_1 496U
+#define SC_R_PMIC_0 497U
+#define SC_R_PMIC_1 498U
+#define SC_R_SECO 499U
+#define SC_R_CAAM_JR1 500U
+#define SC_R_CAAM_JR2 501U
+#define SC_R_CAAM_JR3 502U
+#define SC_R_SECO_MU_2 503U
+#define SC_R_SECO_MU_3 504U
+#define SC_R_SECO_MU_4 505U
+#define SC_R_HDMI_RX_PWM_0 506U
+#define SC_R_A35 507U
+#define SC_R_A35_0 508U
+#define SC_R_A35_1 509U
+#define SC_R_A35_2 510U
+#define SC_R_A35_3 511U
+#define SC_R_DSP 512U
+#define SC_R_DSP_RAM 513U
+#define SC_R_CAAM_JR1_OUT 514U
+#define SC_R_CAAM_JR2_OUT 515U
+#define SC_R_CAAM_JR3_OUT 516U
+#define SC_R_VPU_DEC_0 517U
+#define SC_R_VPU_ENC_0 518U
+#define SC_R_CAAM_JR0 519U
+#define SC_R_CAAM_JR0_OUT 520U
+#define SC_R_PMIC_2 521U
+#define SC_R_DBLOGIC 522U
+#define SC_R_HDMI_PLL_1 523U
+#define SC_R_BOARD_R0 524U
+#define SC_R_BOARD_R1 525U
+#define SC_R_BOARD_R2 526U
+#define SC_R_BOARD_R3 527U
+#define SC_R_BOARD_R4 528U
+#define SC_R_BOARD_R5 529U
+#define SC_R_BOARD_R6 530U
+#define SC_R_BOARD_R7 531U
+#define SC_R_MJPEG_DEC_MP 532U
+#define SC_R_MJPEG_ENC_MP 533U
+#define SC_R_VPU_TS_0 534U
+#define SC_R_VPU_MU_0 535U
+#define SC_R_VPU_MU_1 536U
+#define SC_R_VPU_MU_2 537U
+#define SC_R_VPU_MU_3 538U
+#define SC_R_VPU_ENC_1 539U
+#define SC_R_VPU 540U
+#define SC_R_DMA_5_CH0 541U
+#define SC_R_DMA_5_CH1 542U
+#define SC_R_DMA_5_CH2 543U
+#define SC_R_DMA_5_CH3 544U
+#define SC_R_ATTESTATION 545U
+#define SC_R_LAST 546U
+#define SC_R_ALL ((sc_rsrc_t) UINT16_MAX) /* All resources */
+/*@}*/
+
+/*!
+ * Define for ATF/Linux. Not used by SCFW. Not a valid parameter
+ * for any SCFW API calls!
+ */
+#define SC_R_NONE 0xFFF0U
+
+/* NOTE - please add by replacing some of the UNUSED from above! */
+
+/*!
+ * Defnes for sc_ctrl_t.
+ */
+#define SC_C_TEMP 0U
+#define SC_C_TEMP_HI 1U
+#define SC_C_TEMP_LOW 2U
+#define SC_C_PXL_LINK_MST1_ADDR 3U
+#define SC_C_PXL_LINK_MST2_ADDR 4U
+#define SC_C_PXL_LINK_MST_ENB 5U
+#define SC_C_PXL_LINK_MST1_ENB 6U
+#define SC_C_PXL_LINK_MST2_ENB 7U
+#define SC_C_PXL_LINK_SLV1_ADDR 8U
+#define SC_C_PXL_LINK_SLV2_ADDR 9U
+#define SC_C_PXL_LINK_MST_VLD 10U
+#define SC_C_PXL_LINK_MST1_VLD 11U
+#define SC_C_PXL_LINK_MST2_VLD 12U
+#define SC_C_SINGLE_MODE 13U
+#define SC_C_ID 14U
+#define SC_C_PXL_CLK_POLARITY 15U
+#define SC_C_LINESTATE 16U
+#define SC_C_PCIE_G_RST 17U
+#define SC_C_PCIE_BUTTON_RST 18U
+#define SC_C_PCIE_PERST 19U
+#define SC_C_PHY_RESET 20U
+#define SC_C_PXL_LINK_RATE_CORRECTION 21U
+#define SC_C_PANIC 22U
+#define SC_C_PRIORITY_GROUP 23U
+#define SC_C_TXCLK 24U
+#define SC_C_CLKDIV 25U
+#define SC_C_DISABLE_50 26U
+#define SC_C_DISABLE_125 27U
+#define SC_C_SEL_125 28U
+#define SC_C_MODE 29U
+#define SC_C_SYNC_CTRL0 30U
+#define SC_C_KACHUNK_CNT 31U
+#define SC_C_KACHUNK_SEL 32U
+#define SC_C_SYNC_CTRL1 33U
+#define SC_C_DPI_RESET 34U
+#define SC_C_MIPI_RESET 35U
+#define SC_C_DUAL_MODE 36U
+#define SC_C_VOLTAGE 37U
+#define SC_C_PXL_LINK_SEL 38U
+#define SC_C_OFS_SEL 39U
+#define SC_C_OFS_AUDIO 40U
+#define SC_C_OFS_PERIPH 41U
+#define SC_C_OFS_IRQ 42U
+#define SC_C_RST0 43U
+#define SC_C_RST1 44U
+#define SC_C_SEL0 45U
+#define SC_C_CALIB0 46U
+#define SC_C_CALIB1 47U
+#define SC_C_CALIB2 48U
+#define SC_C_IPG_DEBUG 49U
+#define SC_C_IPG_DOZE 50U
+#define SC_C_IPG_WAIT 51U
+#define SC_C_IPG_STOP 52U
+#define SC_C_IPG_STOP_MODE 53U
+#define SC_C_IPG_STOP_ACK 54U
+#define SC_C_SYNC_CTRL 55U
+#define SC_C_LAST 56U
+
+#define SC_P_ALL ((sc_pad_t) UINT16_MAX) /* All pads */
+
+/* Types */
+
+/*!
+ * This type is used to store a boolean
+ */
+typedef uint8_t sc_bool_t;
+
+/*!
+ * This type is used to store a system (full-size) address.
+ */
+typedef uint64_t sc_faddr_t;
+
+/*!
+ * This type is used to indicate error response for most functions.
+ */
+typedef uint8_t sc_err_t;
+
+/*!
+ * This type is used to indicate a resource. Resources include peripherals
+ * and bus masters (but not memory regions). Note items from list should
+ * never be changed or removed (only added to at the end of the list).
+ */
+typedef uint32_t sc_rsrc_t;
+
+/*!
+ * This type is used to indicate a control.
+ */
+typedef uint32_t sc_ctrl_t;
+
+/*!
+ * This type is used to indicate a pad. Valid values are SoC specific.
+ *
+ * Refer to the SoC [Pad List](@ref PADS) for valid pad values.
+ */
+typedef uint16_t sc_pad_t;
+
+/* Extra documentation of standard types */
+
+#ifdef DOXYGEN
+/*!
+ * Type used to declare an 8-bit integer.
+ */
+typedef __INT8_TYPE__ int8_t;
+
+/*!
+ * Type used to declare a 16-bit integer.
+ */
+typedef __INT16_TYPE__ int16_t;
+
+/*!
+ * Type used to declare a 32-bit integer.
+ */
+typedef __INT32_TYPE__ int32_t;
+
+/*!
+ * Type used to declare a 64-bit integer.
+ */
+typedef __INT64_TYPE__ int64_t;
+
+/*!
+ * Type used to declare an 8-bit unsigned integer.
+ */
+typedef __UINT8_TYPE__ uint8_t;
+
+/*!
+ * Type used to declare a 16-bit unsigned integer.
+ */
+typedef __UINT16_TYPE__ uint16_t;
+
+/*!
+ * Type used to declare a 32-bit unsigned integer.
+ */
+typedef __UINT32_TYPE__ uint32_t;
+
+/*!
+ * Type used to declare a 64-bit unsigned integer.
+ */
+typedef __UINT64_TYPE__ uint64_t;
+#endif
+
+#endif /* SC_TYPES_H */
+
diff --git a/include/soc/imx8/soc.h b/include/soc/imx8/soc.h
new file mode 100644
index 000000000000..376c58d2588a
--- /dev/null
+++ b/include/soc/imx8/soc.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2017 NXP
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+
+#ifndef __SOC_IMX8_SOC_H__
+#define __SOC_IMX8_SOC_H__
+
+#define IMX_SOC_IMX8QM 0x01
+#define IMX_SOC_IMX8QXP 0x02
+#define IMX_SOC_IMX8MQ 0x82
+
+bool cpu_is_imx8qm(void);
+bool cpu_is_imx8mq(void);
+bool cpu_is_imx8qxp(void);
+
+extern bool TKT340553_SW_WORKAROUND;
+unsigned int imx8_get_soc_revision(void);
+
+int check_m4_enabled(void);
+bool check_hdcp_enabled(void);
+
+#endif
diff --git a/include/sound/dmaengine_pcm.h b/include/sound/dmaengine_pcm.h
index 67be2445941a..267192c22e6a 100644
--- a/include/sound/dmaengine_pcm.h
+++ b/include/sound/dmaengine_pcm.h
@@ -74,6 +74,8 @@ struct dma_chan *snd_dmaengine_pcm_get_chan(struct snd_pcm_substream *substream)
* @chan_name: Custom channel name to use when requesting DMA channel.
* @fifo_size: FIFO size of the DAI controller in bytes
* @flags: PCM_DAI flags, only SND_DMAENGINE_PCM_DAI_FLAG_PACK for now
+ * @check_xrun: check if hardware xrun happen in the cpu dai.
+ * @device_reset: if xrun happened, then do cpu dai reset.
*/
struct snd_dmaengine_dai_dma_data {
dma_addr_t addr;
@@ -84,6 +86,17 @@ struct snd_dmaengine_dai_dma_data {
const char *chan_name;
unsigned int fifo_size;
unsigned int flags;
+ unsigned int fifo_num;
+ bool (*check_xrun)(struct snd_pcm_substream *substream);
+ void (*device_reset)(struct snd_pcm_substream *substream, bool stop);
+};
+
+struct dmaengine_pcm_runtime_data {
+ struct dma_chan *dma_chan;
+ dma_cookie_t cookie;
+
+ unsigned int pos;
+ dma_async_tx_callback callback;
};
void snd_dmaengine_pcm_set_config_from_dai_data(
diff --git a/include/sound/soc.h b/include/sound/soc.h
index d22de9712c45..d90b76e99bbf 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -1077,6 +1077,7 @@ struct snd_soc_dai_link {
/* DPCM used FE & BE merged format */
unsigned int dpcm_merged_format:1;
+ unsigned int dpcm_merged_chan:1;
/* pmdown_time is ignored at stop */
unsigned int ignore_pmdown_time:1;
diff --git a/include/trace/events/cpufreq_interactive.h b/include/trace/events/cpufreq_interactive.h
new file mode 100644
index 000000000000..faecc0bfdeff
--- /dev/null
+++ b/include/trace/events/cpufreq_interactive.h
@@ -0,0 +1,112 @@
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM cpufreq_interactive
+
+#if !defined(_TRACE_CPUFREQ_INTERACTIVE_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_CPUFREQ_INTERACTIVE_H
+
+#include <linux/tracepoint.h>
+
+DECLARE_EVENT_CLASS(set,
+ TP_PROTO(u32 cpu_id, unsigned long targfreq,
+ unsigned long actualfreq),
+ TP_ARGS(cpu_id, targfreq, actualfreq),
+
+ TP_STRUCT__entry(
+ __field(u32, cpu_id)
+ __field(unsigned long, targfreq)
+ __field(unsigned long, actualfreq)
+ ),
+
+ TP_fast_assign(
+ __entry->cpu_id = (u32)cpu_id;
+ __entry->targfreq = targfreq;
+ __entry->actualfreq = actualfreq;
+ ),
+
+ TP_printk("cpu=%u targ=%lu actual=%lu",
+ __entry->cpu_id, __entry->targfreq,
+ __entry->actualfreq)
+);
+
+DEFINE_EVENT(set, cpufreq_interactive_setspeed,
+ TP_PROTO(u32 cpu_id, unsigned long targfreq,
+ unsigned long actualfreq),
+ TP_ARGS(cpu_id, targfreq, actualfreq)
+);
+
+DECLARE_EVENT_CLASS(loadeval,
+ TP_PROTO(unsigned long cpu_id, unsigned long load,
+ unsigned long curtarg, unsigned long curactual,
+ unsigned long newtarg),
+ TP_ARGS(cpu_id, load, curtarg, curactual, newtarg),
+
+ TP_STRUCT__entry(
+ __field(unsigned long, cpu_id)
+ __field(unsigned long, load)
+ __field(unsigned long, curtarg)
+ __field(unsigned long, curactual)
+ __field(unsigned long, newtarg)
+ ),
+
+ TP_fast_assign(
+ __entry->cpu_id = cpu_id;
+ __entry->load = load;
+ __entry->curtarg = curtarg;
+ __entry->curactual = curactual;
+ __entry->newtarg = newtarg;
+ ),
+
+ TP_printk("cpu=%lu load=%lu cur=%lu actual=%lu targ=%lu",
+ __entry->cpu_id, __entry->load, __entry->curtarg,
+ __entry->curactual, __entry->newtarg)
+);
+
+DEFINE_EVENT(loadeval, cpufreq_interactive_target,
+ TP_PROTO(unsigned long cpu_id, unsigned long load,
+ unsigned long curtarg, unsigned long curactual,
+ unsigned long newtarg),
+ TP_ARGS(cpu_id, load, curtarg, curactual, newtarg)
+);
+
+DEFINE_EVENT(loadeval, cpufreq_interactive_already,
+ TP_PROTO(unsigned long cpu_id, unsigned long load,
+ unsigned long curtarg, unsigned long curactual,
+ unsigned long newtarg),
+ TP_ARGS(cpu_id, load, curtarg, curactual, newtarg)
+);
+
+DEFINE_EVENT(loadeval, cpufreq_interactive_notyet,
+ TP_PROTO(unsigned long cpu_id, unsigned long load,
+ unsigned long curtarg, unsigned long curactual,
+ unsigned long newtarg),
+ TP_ARGS(cpu_id, load, curtarg, curactual, newtarg)
+);
+
+TRACE_EVENT(cpufreq_interactive_boost,
+ TP_PROTO(const char *s),
+ TP_ARGS(s),
+ TP_STRUCT__entry(
+ __string(s, s)
+ ),
+ TP_fast_assign(
+ __assign_str(s, s);
+ ),
+ TP_printk("%s", __get_str(s))
+);
+
+TRACE_EVENT(cpufreq_interactive_unboost,
+ TP_PROTO(const char *s),
+ TP_ARGS(s),
+ TP_STRUCT__entry(
+ __string(s, s)
+ ),
+ TP_fast_assign(
+ __assign_str(s, s);
+ ),
+ TP_printk("%s", __get_str(s))
+);
+
+#endif /* _TRACE_CPUFREQ_INTERACTIVE_H */
+
+/* This part must be outside protection */
+#include <trace/define_trace.h>
diff --git a/include/uapi/drm/drm.h b/include/uapi/drm/drm.h
index 97677cd6964d..27eb278bb3f2 100644
--- a/include/uapi/drm/drm.h
+++ b/include/uapi/drm/drm.h
@@ -863,6 +863,11 @@ extern "C" {
#define DRM_IOCTL_SYNCOBJ_RESET DRM_IOWR(0xC4, struct drm_syncobj_array)
#define DRM_IOCTL_SYNCOBJ_SIGNAL DRM_IOWR(0xC5, struct drm_syncobj_array)
+#define DRM_IOCTL_MODE_CREATE_LEASE DRM_IOWR(0xC6, struct drm_mode_create_lease)
+#define DRM_IOCTL_MODE_LIST_LESSEES DRM_IOWR(0xC7, struct drm_mode_list_lessees)
+#define DRM_IOCTL_MODE_GET_LEASE DRM_IOWR(0xC8, struct drm_mode_get_lease)
+#define DRM_IOCTL_MODE_REVOKE_LEASE DRM_IOWR(0xC9, struct drm_mode_revoke_lease)
+
/**
* Device specific ioctls should only be in their respective headers
* The device specific ioctl range is from 0x40 to 0x9f.
diff --git a/include/uapi/drm/drm_fourcc.h b/include/uapi/drm/drm_fourcc.h
index 3ad838d3f93f..10e26af753f2 100644
--- a/include/uapi/drm/drm_fourcc.h
+++ b/include/uapi/drm/drm_fourcc.h
@@ -140,6 +140,7 @@ extern "C" {
#define DRM_FORMAT_NV61 fourcc_code('N', 'V', '6', '1') /* 2x1 subsampled Cb:Cr plane */
#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 */
+#define DRM_FORMAT_P010 fourcc_code('P', '0', '1', '0') /* 2x2 subsampled Cr:Cb plane, 10-bit per channel */
/*
* 3 plane YCbCr
@@ -183,6 +184,8 @@ extern "C" {
#define DRM_FORMAT_MOD_VENDOR_QCOM 0x05
#define DRM_FORMAT_MOD_VENDOR_VIVANTE 0x06
#define DRM_FORMAT_MOD_VENDOR_BROADCOM 0x07
+#define DRM_FORMAT_MOD_VENDOR_AMPHION 0x08
+#define DRM_FORMAT_MOD_VENDOR_VSI 0x09
/* add more to the end as needed */
#define DRM_FORMAT_RESERVED ((1ULL << 56) - 1)
@@ -338,6 +341,15 @@ extern "C" {
*/
#define DRM_FORMAT_MOD_VIVANTE_SPLIT_SUPER_TILED fourcc_mod_code(VIVANTE, 4)
+/*
+ * Vivante 64x64 super-tiling with compression layout
+ *
+ * This is a tiled layout using 64x64 pixel super-tiles, where each super-tile
+ * contains 8x4 groups of 2x4 tiles of 4x4 pixels each, all in row-major layout
+ * with compression.
+ */
+#define DRM_FORMAT_MOD_VIVANTE_SUPER_TILED_FC fourcc_mod_code(VIVANTE, 5)
+
/* NVIDIA Tegra frame buffer modifiers */
/*
@@ -403,6 +415,42 @@ extern "C" {
*/
#define DRM_FORMAT_MOD_BROADCOM_VC4_T_TILED fourcc_mod_code(BROADCOM, 1)
+/* Amphion tiled layout */
+
+/*
+ * Amphion 8x128 tiling layout
+ *
+ * This is a tiled layout using 8x128 pixel vertical strips, where each strip
+ * contains 1x16 groups of 8x8 pixels in a row-major layout.
+ */
+#define DRM_FORMAT_MOD_AMPHION_TILED fourcc_mod_code(AMPHION, 1)
+
+/* Verisilicon framebuffer modifiers */
+
+/*
+ * Verisilicon 8x4 tiling layout
+ *
+ * This is G1 VPU tiled layout using tiles of 8x4 pixels in a row-major
+ * layout.
+ */
+#define DRM_FORMAT_MOD_VSI_G1_TILED fourcc_mod_code(VSI, 1)
+
+/*
+ * Verisilicon 4x4 tiling layout
+ *
+ * This is G2 VPU tiled layout using tiles of 4x4 pixels in a row-major
+ * layout.
+ */
+#define DRM_FORMAT_MOD_VSI_G2_TILED fourcc_mod_code(VSI, 2)
+
+/*
+ * Verisilicon 4x4 tiling with compression layout
+ *
+ * This is G2 VPU tiled layout using tiles of 4x4 pixels in a row-major
+ * layout with compression.
+ */
+#define DRM_FORMAT_MOD_VSI_G2_TILED_COMPRESSED fourcc_mod_code(VSI, 3)
+
#if defined(__cplusplus)
}
#endif
diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h
index 54fc38c3c3f1..f0de943c7e22 100644
--- a/include/uapi/drm/drm_mode.h
+++ b/include/uapi/drm/drm_mode.h
@@ -90,6 +90,13 @@ extern "C" {
#define DRM_MODE_PICTURE_ASPECT_4_3 1
#define DRM_MODE_PICTURE_ASPECT_16_9 2
+/* Content type options */
+#define DRM_MODE_CONTENT_TYPE_NO_DATA 0
+#define DRM_MODE_CONTENT_TYPE_GRAPHICS 1
+#define DRM_MODE_CONTENT_TYPE_PHOTO 2
+#define DRM_MODE_CONTENT_TYPE_CINEMA 3
+#define DRM_MODE_CONTENT_TYPE_GAME 4
+
/* Aspect ratio flag bitmask (4 bits 22:19) */
#define DRM_MODE_FLAG_PIC_AR_MASK (0x0F<<19)
#define DRM_MODE_FLAG_PIC_AR_NONE \
@@ -173,6 +180,10 @@ extern "C" {
DRM_MODE_REFLECT_X | \
DRM_MODE_REFLECT_Y)
+/* Content Protection Flags */
+#define DRM_MODE_CONTENT_PROTECTION_UNDESIRED 0
+#define DRM_MODE_CONTENT_PROTECTION_DESIRED 1
+#define DRM_MODE_CONTENT_PROTECTION_ENABLED 2
struct drm_mode_modeinfo {
__u32 clock;
@@ -590,6 +601,27 @@ struct drm_color_lut {
__u16 reserved;
};
+enum supported_eotf_type {
+ TRADITIONAL_GAMMA_SDR = 0,
+ TRADITIONA_GAMMA_HDR,
+ SMPTE_ST2084,
+ FUTURE_EOTF
+};
+
+/* HDR Metadata */
+struct hdr_static_metadata {
+ uint8_t eotf;
+ uint8_t type;
+ uint16_t display_primaries_x[3];
+ uint16_t display_primaries_y[3];
+ uint16_t white_point_x;
+ uint16_t white_point_y;
+ uint16_t max_mastering_display_luminance;
+ uint16_t min_mastering_display_luminance;
+ uint16_t max_fall;
+ uint16_t max_cll;
+};
+
#define DRM_MODE_PAGE_FLIP_EVENT 0x01
#define DRM_MODE_PAGE_FLIP_ASYNC 0x02
#define DRM_MODE_PAGE_FLIP_TARGET_ABSOLUTE 0x4
@@ -782,6 +814,72 @@ struct drm_mode_destroy_blob {
__u32 blob_id;
};
+/**
+ * Lease mode resources, creating another drm_master.
+ */
+struct drm_mode_create_lease {
+ /** Pointer to array of object ids (__u32) */
+ __u64 object_ids;
+ /** Number of object ids */
+ __u32 object_count;
+ /** flags for new FD (O_CLOEXEC, etc) */
+ __u32 flags;
+
+ /** Return: unique identifier for lessee. */
+ __u32 lessee_id;
+ /** Return: file descriptor to new drm_master file */
+ __u32 fd;
+};
+
+/**
+ * List lesses from a drm_master
+ */
+struct drm_mode_list_lessees {
+ /** Number of lessees.
+ * On input, provides length of the array.
+ * On output, provides total number. No
+ * more than the input number will be written
+ * back, so two calls can be used to get
+ * the size and then the data.
+ */
+ __u32 count_lessees;
+ __u32 pad;
+
+ /** Pointer to lessees.
+ * pointer to __u64 array of lessee ids
+ */
+ __u64 lessees_ptr;
+};
+
+/**
+ * Get leased objects
+ */
+struct drm_mode_get_lease {
+ /** Number of leased objects.
+ * On input, provides length of the array.
+ * On output, provides total number. No
+ * more than the input number will be written
+ * back, so two calls can be used to get
+ * the size and then the data.
+ */
+ __u32 count_objects;
+ __u32 pad;
+
+ /** Pointer to objects.
+ * pointer to __u32 array of object ids
+ */
+ __u64 objects_ptr;
+};
+
+/**
+ * Revoke lease
+ */
+struct drm_mode_revoke_lease {
+ /** Unique ID of lessee
+ */
+ __u32 lessee_id;
+};
+
#if defined(__cplusplus)
}
#endif
diff --git a/include/uapi/drm/imx_drm.h b/include/uapi/drm/imx_drm.h
new file mode 100644
index 000000000000..e80cad4be8bd
--- /dev/null
+++ b/include/uapi/drm/imx_drm.h
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2017 NXP
+ *
+ * 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 _UAPI_IMX_DRM_H_
+#define _UAPI_IMX_DRM_H_
+
+#include "drm.h"
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+/**
+ * Dpu frame info.
+ *
+ */
+struct drm_imx_dpu_frame_info {
+ __u32 width;
+ __u32 height;
+ __u32 x_offset;
+ __u32 y_offset;
+ __u32 stride;
+ __u32 format;
+ __u64 modifier;
+ __u64 baddr;
+ __u64 uv_addr;
+};
+
+#define DRM_IMX_DPU_SET_CMDLIST 0x00
+#define DRM_IMX_DPU_WAIT 0x01
+#define DRM_IMX_DPU_GET_PARAM 0x02
+
+#define DRM_IOCTL_IMX_DPU_SET_CMDLIST DRM_IOWR(DRM_COMMAND_BASE + \
+ DRM_IMX_DPU_SET_CMDLIST, struct drm_imx_dpu_set_cmdlist)
+#define DRM_IOCTL_IMX_DPU_WAIT DRM_IOWR(DRM_COMMAND_BASE + \
+ DRM_IMX_DPU_WAIT, struct drm_imx_dpu_wait)
+#define DRM_IOCTL_IMX_DPU_GET_PARAM DRM_IOWR(DRM_COMMAND_BASE + \
+ DRM_IMX_DPU_GET_PARAM, enum drm_imx_dpu_param)
+
+/**
+ * struct drm_imx_dpu_set_cmdlist - ioctl argument for
+ * DRM_IMX_DPU_SET_CMDLIST.
+ */
+struct drm_imx_dpu_set_cmdlist {
+ __u64 cmd;
+ __u32 cmd_nr;
+
+ /* reserved */
+ __u64 user_data;
+};
+
+/**
+ * struct drm_imx_dpu_wait - ioctl argument for
+ * DRM_IMX_DPU_WAIT.
+ *
+ */
+struct drm_imx_dpu_wait {
+ /* reserved */
+ __u64 user_data;
+};
+
+/**
+ * enum drm_imx_dpu_param - ioctl argument for
+ * DRM_IMX_DPU_GET_PARAM.
+ *
+ */
+enum drm_imx_dpu_param {
+ DRM_IMX_MAX_DPUS,
+};
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* _UAPI_IMX_DRM_H_ */
diff --git a/include/uapi/linux/dma-buf.h b/include/uapi/linux/dma-buf.h
index d75df5210a4a..514beecd2d13 100644
--- a/include/uapi/linux/dma-buf.h
+++ b/include/uapi/linux/dma-buf.h
@@ -27,6 +27,10 @@ struct dma_buf_sync {
__u64 flags;
};
+struct dma_buf_phys {
+ unsigned long phys;
+};
+
#define DMA_BUF_SYNC_READ (1 << 0)
#define DMA_BUF_SYNC_WRITE (2 << 0)
#define DMA_BUF_SYNC_RW (DMA_BUF_SYNC_READ | DMA_BUF_SYNC_WRITE)
@@ -37,5 +41,6 @@ struct dma_buf_sync {
#define DMA_BUF_BASE 'b'
#define DMA_BUF_IOCTL_SYNC _IOW(DMA_BUF_BASE, 0, struct dma_buf_sync)
+#define DMA_BUF_IOCTL_PHYS _IOW(DMA_BUF_BASE, 1, struct dma_buf_phys)
#endif
diff --git a/include/uapi/linux/hantrodec.h b/include/uapi/linux/hantrodec.h
new file mode 100755
index 000000000000..4add50e85299
--- /dev/null
+++ b/include/uapi/linux/hantrodec.h
@@ -0,0 +1,93 @@
+/*****************************************************************************
+*
+* The GPL License (GPL)
+*
+* Copyright (c) 2015-2017, VeriSilicon Inc.
+* Copyright (c) 2011-2014, Google 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.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+*****************************************************************************/
+
+#ifndef _UAPI_HANTRODEC_H_
+#define _UAPI_HANTRODEC_H_
+#include <linux/ioctl.h>
+#include <linux/types.h>
+
+#undef PDEBUG
+#ifdef HANTRODEC_DEBUG
+# ifdef __KERNEL__
+# define PDEBUG(fmt, args...) pr_info("hantrodec: " fmt, ## args)
+# else
+# define PDEBUG(fmt, args...) fprintf(stderr, fmt, ## args)
+# endif
+#else
+# define PDEBUG(fmt, args...)
+#endif
+
+struct core_desc {
+ __u32 id; /* id of the Core */
+ __u32 *regs; /* pointer to user registers */
+ __u32 size; /* size of register space */
+};
+
+/* Use 'k' as magic number */
+#define HANTRODEC_IOC_MAGIC 'k'
+
+/*
+ * S means "Set" through a ptr,
+ * T means "Tell" directly with the argument value
+ * G means "Get": reply by setting through a pointer
+ * Q means "Query": response is on the return value
+ * X means "eXchange": G and S atomically
+ * H means "sHift": T and Q atomically
+ */
+
+#define HANTRODEC_PP_INSTANCE _IO(HANTRODEC_IOC_MAGIC, 1)
+#define HANTRODEC_HW_PERFORMANCE _IO(HANTRODEC_IOC_MAGIC, 2)
+#define HANTRODEC_IOCGHWOFFSET _IOR(HANTRODEC_IOC_MAGIC, 3, unsigned long *)
+#define HANTRODEC_IOCGHWIOSIZE _IOR(HANTRODEC_IOC_MAGIC, 4, unsigned int *)
+
+#define HANTRODEC_IOC_CLI _IO(HANTRODEC_IOC_MAGIC, 5)
+#define HANTRODEC_IOC_STI _IO(HANTRODEC_IOC_MAGIC, 6)
+#define HANTRODEC_IOC_MC_OFFSETS _IOR(HANTRODEC_IOC_MAGIC, 7, unsigned long *)
+#define HANTRODEC_IOC_MC_CORES _IOR(HANTRODEC_IOC_MAGIC, 8, unsigned int *)
+
+
+#define HANTRODEC_IOCS_DEC_PUSH_REG _IOW(HANTRODEC_IOC_MAGIC, 9, struct core_desc *)
+#define HANTRODEC_IOCS_PP_PUSH_REG _IOW(HANTRODEC_IOC_MAGIC, 10, struct core_desc *)
+
+#define HANTRODEC_IOCH_DEC_RESERVE _IO(HANTRODEC_IOC_MAGIC, 11)
+#define HANTRODEC_IOCT_DEC_RELEASE _IO(HANTRODEC_IOC_MAGIC, 12)
+#define HANTRODEC_IOCQ_PP_RESERVE _IO(HANTRODEC_IOC_MAGIC, 13)
+#define HANTRODEC_IOCT_PP_RELEASE _IO(HANTRODEC_IOC_MAGIC, 14)
+
+#define HANTRODEC_IOCX_DEC_WAIT _IOWR(HANTRODEC_IOC_MAGIC, 15, struct core_desc *)
+#define HANTRODEC_IOCX_PP_WAIT _IOWR(HANTRODEC_IOC_MAGIC, 16, struct core_desc *)
+
+#define HANTRODEC_IOCS_DEC_PULL_REG _IOWR(HANTRODEC_IOC_MAGIC, 17, struct core_desc *)
+#define HANTRODEC_IOCS_PP_PULL_REG _IOWR(HANTRODEC_IOC_MAGIC, 18, struct core_desc *)
+
+#define HANTRODEC_IOCG_CORE_WAIT _IOR(HANTRODEC_IOC_MAGIC, 19, int *)
+
+#define HANTRODEC_IOX_ASIC_ID _IOWR(HANTRODEC_IOC_MAGIC, 20, __u32 *)
+
+#define HANTRODEC_IOCG_CORE_ID _IO(HANTRODEC_IOC_MAGIC, 21)
+
+#define HANTRODEC_DEBUG_STATUS _IO(HANTRODEC_IOC_MAGIC, 29)
+
+#define HANTRODEC_IOC_MAXNR 29
+
+#endif /* !_UAPI_HANTRODEC_H_ */
diff --git a/include/uapi/linux/hx280enc.h b/include/uapi/linux/hx280enc.h
new file mode 100755
index 000000000000..d465c25f9f66
--- /dev/null
+++ b/include/uapi/linux/hx280enc.h
@@ -0,0 +1,79 @@
+ /*****************************************************************************
+ * Encoder device driver (kernel module header)
+ *
+ * Copyright (C) 2012 Google Finland Oy.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+--------------------------------------------------------------------------------
+--
+-- Abstract : 6280/7280/8270/8290/H1 Encoder device driver (kernel module)
+--
+*****************************************************************************/
+#ifndef _UAPI_HX280ENC_H_
+#define _UAPI_HX280ENC_H_
+#include <linux/ioctl.h> /* needed for the _IOW etc stuff used later */
+
+/*
+ * Macros to help debugging
+ */
+
+#undef PDEBUG /* undef it, just in case */
+#ifdef HX280ENC_DEBUG
+# ifdef __KERNEL__
+ /* This one if debugging is on, and kernel space */
+# define PDEBUG(fmt, args...) printk(KERN_INFO "hmp4e: " fmt, ## args)
+# else
+ /* This one for user space */
+# define PDEBUG(fmt, args...) printf(__FILE__ ":%d: " fmt, __LINE__, ## args)
+# endif
+#else
+# define PDEBUG(fmt, args...) /* not debugging: nothing */
+#endif
+
+/*
+ * Ioctl definitions
+ */
+
+/* Use 'k' as magic number */
+#define HX280ENC_IOC_MAGIC 'k'
+/*
+ * S means "Set" through a ptr,
+ * T means "Tell" directly with the argument value
+ * G means "Get": reply by setting through a pointer
+ * Q means "Query": response is on the return value
+ * X means "eXchange": G and S atomically
+ * H means "sHift": T and Q atomically
+ */
+ /*
+ * #define HX280ENC_IOCGBUFBUSADDRESS _IOR(HX280ENC_IOC_MAGIC, 1, unsigned long *)
+ * #define HX280ENC_IOCGBUFSIZE _IOR(HX280ENC_IOC_MAGIC, 2, unsigned int *)
+ */
+#define HX280ENC_IOCGHWOFFSET _IOR(HX280ENC_IOC_MAGIC, 3, unsigned long *)
+#define HX280ENC_IOCGHWIOSIZE _IOR(HX280ENC_IOC_MAGIC, 4, unsigned int *)
+#define HX280ENC_IOC_CLI _IO(HX280ENC_IOC_MAGIC, 5)
+#define HX280ENC_IOC_STI _IO(HX280ENC_IOC_MAGIC, 6)
+#define HX280ENC_IOCXVIRT2BUS _IOWR(HX280ENC_IOC_MAGIC, 7, unsigned long *)
+
+#define HX280ENC_IOCHARDRESET _IO(HX280ENC_IOC_MAGIC, 8) /* debugging tool */
+#define HX280ENC_IOCGSRAMOFFSET _IOR(HX280ENC_IOC_MAGIC, 9, unsigned long *)
+#define HX280ENC_IOCGSRAMEIOSIZE _IOR(HX280ENC_IOC_MAGIC, 10, unsigned int *)
+
+#define HX280ENC_IOCH_ENC_RESERVE _IOR(HX280ENC_IOC_MAGIC, 11, unsigned int *)
+#define HX280ENC_IOCH_ENC_RELEASE _IOR(HX280ENC_IOC_MAGIC, 12, unsigned int *)
+#define HX280ENC_IOCG_CORE_WAIT _IOR(HX280ENC_IOC_MAGIC, 13, unsigned int *)
+#define HX280ENC_IOC_MAXNR 30
+
+#endif /* !_UAPI_HX280ENC_H_ */
diff --git a/include/uapi/linux/ipu.h b/include/uapi/linux/ipu.h
new file mode 100644
index 000000000000..c92f292bcc9d
--- /dev/null
+++ b/include/uapi/linux/ipu.h
@@ -0,0 +1,293 @@
+/*
+ * Copyright (C) 2013-2015 Freescale Semiconductor, Inc. All Rights Reserved
+ */
+
+/*
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/*!
+ * @defgroup IPU MXC Image Processing Unit (IPU) Driver
+ */
+/*!
+ * @file uapi/linux/ipu.h
+ *
+ * @brief This file contains the IPU driver API declarations.
+ *
+ * @ingroup IPU
+ */
+
+#ifndef __ASM_ARCH_IPU_H__
+#define __ASM_ARCH_IPU_H__
+
+#include <linux/types.h>
+#include <linux/videodev2.h>
+
+#ifndef __KERNEL__
+#ifndef __cplusplus
+typedef unsigned char bool;
+#endif
+#define irqreturn_t int
+#define dma_addr_t int
+#define uint32_t unsigned int
+#define uint16_t unsigned short
+#define uint8_t unsigned char
+#define u32 unsigned int
+#define u8 unsigned char
+#define __u32 u32
+#endif
+
+/*!
+ * Enumeration of IPU rotation modes
+ */
+typedef enum {
+ /* Note the enum values correspond to BAM value */
+ IPU_ROTATE_NONE = 0,
+ IPU_ROTATE_VERT_FLIP = 1,
+ IPU_ROTATE_HORIZ_FLIP = 2,
+ IPU_ROTATE_180 = 3,
+ IPU_ROTATE_90_RIGHT = 4,
+ IPU_ROTATE_90_RIGHT_VFLIP = 5,
+ IPU_ROTATE_90_RIGHT_HFLIP = 6,
+ IPU_ROTATE_90_LEFT = 7,
+} ipu_rotate_mode_t;
+
+/*!
+ * Enumeration of VDI MOTION select
+ */
+typedef enum {
+ MED_MOTION = 0,
+ LOW_MOTION = 1,
+ HIGH_MOTION = 2,
+} ipu_motion_sel;
+
+/*!
+ * Enumeration of DI ports for ADC.
+ */
+typedef enum {
+ DISP0,
+ DISP1,
+ DISP2,
+ DISP3
+} display_port_t;
+
+/* IPU Pixel format definitions */
+/* Four-character-code (FOURCC) */
+#define fourcc(a, b, c, d)\
+ (((__u32)(a)<<0)|((__u32)(b)<<8)|((__u32)(c)<<16)|((__u32)(d)<<24))
+
+/*!
+ * @name IPU Pixel Formats
+ *
+ * Pixel formats are defined with ASCII FOURCC code. The pixel format codes are
+ * the same used by V4L2 API.
+ */
+
+/*! @{ */
+/*! @name GPU Tile Formats */
+/*! @{ */
+#define IPU_PIX_FMT_GPU32_SB_ST fourcc('5', 'P', '4', 'S') /*!< 32bit split buf 4x4 standard */
+#define IPU_PIX_FMT_GPU32_SB_SRT fourcc('5', 'P', '4', 'R') /*!< 32bit split buf 4x4 super */
+#define IPU_PIX_FMT_GPU32_ST fourcc('5', 'I', '4', 'S') /*!< 32bit single buf 4x4 standard */
+#define IPU_PIX_FMT_GPU32_SRT fourcc('5', 'I', '4', 'R') /*!< 32bit single buf 4x4 super */
+#define IPU_PIX_FMT_GPU16_SB_ST fourcc('4', 'P', '8', 'S') /*!< 16bit split buf 8x4 standard */
+#define IPU_PIX_FMT_GPU16_SB_SRT fourcc('4', 'P', '8', 'R') /*!< 16bit split buf 8x4 super */
+#define IPU_PIX_FMT_GPU16_ST fourcc('4', 'I', '8', 'S') /*!< 16bit single buf 8x4 standard */
+#define IPU_PIX_FMT_GPU16_SRT fourcc('4', 'I', '8', 'R') /*!< 16bit single buf 8x4 super */
+
+/*! @{ */
+/*! @name Generic or Raw Data Formats */
+/*! @{ */
+#define IPU_PIX_FMT_GENERIC fourcc('I', 'P', 'U', '0') /*!< IPU Generic Data */
+#define IPU_PIX_FMT_GENERIC_32 fourcc('I', 'P', 'U', '1') /*!< IPU Generic Data */
+#define IPU_PIX_FMT_GENERIC_16 fourcc('I', 'P', 'U', '2') /*!< IPU Generic Data */
+#define IPU_PIX_FMT_LVDS666 fourcc('L', 'V', 'D', '6') /*!< IPU Generic Data */
+#define IPU_PIX_FMT_LVDS888 fourcc('L', 'V', 'D', '8') /*!< IPU Generic Data */
+/*! @} */
+/*! @name RGB Formats */
+/*! @{ */
+#define IPU_PIX_FMT_RGB332 fourcc('R', 'G', 'B', '1') /*!< 8 RGB-3-3-2 */
+#define IPU_PIX_FMT_RGB555 fourcc('R', 'G', 'B', 'O') /*!< 16 RGB-5-5-5 */
+#define IPU_PIX_FMT_RGB565 fourcc('R', 'G', 'B', 'P') /*!< 1 6 RGB-5-6-5 */
+#define IPU_PIX_FMT_BGRA4444 fourcc('4', '4', '4', '4') /*!< 16 RGBA-4-4-4-4 */
+#define IPU_PIX_FMT_BGRA5551 fourcc('5', '5', '5', '1') /*!< 16 RGBA-5-5-5-1 */
+#define IPU_PIX_FMT_RGB666 fourcc('R', 'G', 'B', '6') /*!< 18 RGB-6-6-6 */
+#define IPU_PIX_FMT_BGR666 fourcc('B', 'G', 'R', '6') /*!< 18 BGR-6-6-6 */
+#define IPU_PIX_FMT_BGR24 fourcc('B', 'G', 'R', '3') /*!< 24 BGR-8-8-8 */
+#define IPU_PIX_FMT_RGB24 fourcc('R', 'G', 'B', '3') /*!< 24 RGB-8-8-8 */
+#define IPU_PIX_FMT_GBR24 fourcc('G', 'B', 'R', '3') /*!< 24 GBR-8-8-8 */
+#define IPU_PIX_FMT_BGR32 fourcc('B', 'G', 'R', '4') /*!< 32 BGR-8-8-8-8 */
+#define IPU_PIX_FMT_BGRA32 fourcc('B', 'G', 'R', 'A') /*!< 32 BGR-8-8-8-8 */
+#define IPU_PIX_FMT_RGB32 fourcc('R', 'G', 'B', '4') /*!< 32 RGB-8-8-8-8 */
+#define IPU_PIX_FMT_RGBA32 fourcc('R', 'G', 'B', 'A') /*!< 32 RGB-8-8-8-8 */
+#define IPU_PIX_FMT_ABGR32 fourcc('A', 'B', 'G', 'R') /*!< 32 ABGR-8-8-8-8 */
+/*! @} */
+/*! @name YUV Interleaved Formats */
+/*! @{ */
+#define IPU_PIX_FMT_YUYV fourcc('Y', 'U', 'Y', 'V') /*!< 16 YUV 4:2:2 */
+#define IPU_PIX_FMT_UYVY fourcc('U', 'Y', 'V', 'Y') /*!< 16 YUV 4:2:2 */
+#define IPU_PIX_FMT_YVYU fourcc('Y', 'V', 'Y', 'U') /*!< 16 YVYU 4:2:2 */
+#define IPU_PIX_FMT_VYUY fourcc('V', 'Y', 'U', 'Y') /*!< 16 VYYU 4:2:2 */
+#define IPU_PIX_FMT_Y41P fourcc('Y', '4', '1', 'P') /*!< 12 YUV 4:1:1 */
+#define IPU_PIX_FMT_YUV444 fourcc('Y', '4', '4', '4') /*!< 24 YUV 4:4:4 */
+#define IPU_PIX_FMT_VYU444 fourcc('V', '4', '4', '4') /*!< 24 VYU 4:4:4 */
+#define IPU_PIX_FMT_AYUV fourcc('A', 'Y', 'U', 'V') /*!< 32 AYUV 4:4:4:4 */
+/* two planes -- one Y, one Cb + Cr interleaved */
+#define IPU_PIX_FMT_NV12 fourcc('N', 'V', '1', '2') /* 12 Y/CbCr 4:2:0 */
+#define PRE_PIX_FMT_NV21 fourcc('N', 'V', '2', '1') /* 12 Y/CbCr 4:2:0 */
+#define IPU_PIX_FMT_NV16 fourcc('N', 'V', '1', '6') /* 16 Y/CbCr 4:2:2 */
+#define PRE_PIX_FMT_NV61 fourcc('N', 'V', '6', '1') /* 16 Y/CbCr 4:2:2 */
+/* two planes -- 12 tiled Y/CbCr 4:2:0 */
+#define IPU_PIX_FMT_TILED_NV12 fourcc('T', 'N', 'V', 'P')
+#define IPU_PIX_FMT_TILED_NV12F fourcc('T', 'N', 'V', 'F')
+
+/*! @} */
+/*! @name YUV Planar Formats */
+/*! @{ */
+#define IPU_PIX_FMT_GREY fourcc('G', 'R', 'E', 'Y') /*!< 8 Greyscale */
+#define IPU_PIX_FMT_YVU410P fourcc('Y', 'V', 'U', '9') /*!< 9 YVU 4:1:0 */
+#define IPU_PIX_FMT_YUV410P fourcc('Y', 'U', 'V', '9') /*!< 9 YUV 4:1:0 */
+#define IPU_PIX_FMT_YVU420P fourcc('Y', 'V', '1', '2') /*!< 12 YVU 4:2:0 */
+#define IPU_PIX_FMT_YUV420P fourcc('I', '4', '2', '0') /*!< 12 YUV 4:2:0 */
+#define IPU_PIX_FMT_YUV420P2 fourcc('Y', 'U', '1', '2') /*!< 12 YUV 4:2:0 */
+#define IPU_PIX_FMT_YVU422P fourcc('Y', 'V', '1', '6') /*!< 16 YVU 4:2:2 */
+#define IPU_PIX_FMT_YUV422P fourcc('4', '2', '2', 'P') /*!< 16 YUV 4:2:2 */
+/* non-interleaved 4:4:4 */
+#define IPU_PIX_FMT_YUV444P fourcc('4', '4', '4', 'P') /*!< 24 YUV 4:4:4 */
+/*! @} */
+#define IPU_PIX_FMT_TILED_NV12_MBALIGN (16)
+#define TILED_NV12_FRAME_SIZE(w, h) \
+ (ALIGN((w) * (h), SZ_4K) + ALIGN((w) * (h) / 2, SZ_4K))
+/* IPU device */
+typedef enum {
+ RGB_CS,
+ YUV_CS,
+ NULL_CS
+} cs_t;
+
+struct ipu_pos {
+ u32 x;
+ u32 y;
+};
+
+struct ipu_crop {
+ struct ipu_pos pos;
+ u32 w;
+ u32 h;
+};
+
+struct ipu_deinterlace {
+ bool enable;
+ u8 motion; /*see ipu_motion_sel*/
+#define IPU_DEINTERLACE_FIELD_TOP 0
+#define IPU_DEINTERLACE_FIELD_BOTTOM 1
+#define IPU_DEINTERLACE_FIELD_MASK \
+ (IPU_DEINTERLACE_FIELD_TOP | IPU_DEINTERLACE_FIELD_BOTTOM)
+ /* deinterlace frame rate double flags */
+#define IPU_DEINTERLACE_RATE_EN 0x80
+#define IPU_DEINTERLACE_RATE_FRAME1 0x40
+#define IPU_DEINTERLACE_RATE_MASK \
+ (IPU_DEINTERLACE_RATE_EN | IPU_DEINTERLACE_RATE_FRAME1)
+#define IPU_DEINTERLACE_MAX_FRAME 2
+ u8 field_fmt;
+};
+
+struct ipu_input {
+ u32 width;
+ u32 height;
+ u32 format;
+ struct ipu_crop crop;
+ dma_addr_t paddr;
+
+ struct ipu_deinterlace deinterlace;
+ dma_addr_t paddr_n; /*valid when deinterlace enable*/
+};
+
+struct ipu_alpha {
+#define IPU_ALPHA_MODE_GLOBAL 0
+#define IPU_ALPHA_MODE_LOCAL 1
+ u8 mode;
+ u8 gvalue; /* 0~255 */
+ dma_addr_t loc_alp_paddr;
+};
+
+struct ipu_colorkey {
+ bool enable;
+ u32 value; /* RGB 24bit */
+};
+
+struct ipu_overlay {
+ u32 width;
+ u32 height;
+ u32 format;
+ struct ipu_crop crop;
+ struct ipu_alpha alpha;
+ struct ipu_colorkey colorkey;
+ dma_addr_t paddr;
+};
+
+struct ipu_output {
+ u32 width;
+ u32 height;
+ u32 format;
+ u8 rotate;
+ struct ipu_crop crop;
+ dma_addr_t paddr;
+};
+
+struct ipu_task {
+ struct ipu_input input;
+ struct ipu_output output;
+
+ bool overlay_en;
+ struct ipu_overlay overlay;
+
+#define IPU_TASK_PRIORITY_NORMAL 0
+#define IPU_TASK_PRIORITY_HIGH 1
+ u8 priority;
+
+#define IPU_TASK_ID_ANY 0
+#define IPU_TASK_ID_VF 1
+#define IPU_TASK_ID_PP 2
+#define IPU_TASK_ID_MAX 3
+ u8 task_id;
+
+ int timeout;
+};
+
+enum {
+ IPU_CHECK_OK = 0,
+ IPU_CHECK_WARN_INPUT_OFFS_NOT8ALIGN = 0x1,
+ IPU_CHECK_WARN_OUTPUT_OFFS_NOT8ALIGN = 0x2,
+ IPU_CHECK_WARN_OVERLAY_OFFS_NOT8ALIGN = 0x4,
+ IPU_CHECK_ERR_MIN,
+ IPU_CHECK_ERR_INPUT_CROP,
+ IPU_CHECK_ERR_OUTPUT_CROP,
+ IPU_CHECK_ERR_OVERLAY_CROP,
+ IPU_CHECK_ERR_INPUT_OVER_LIMIT,
+ IPU_CHECK_ERR_OV_OUT_NO_FIT,
+ IPU_CHECK_ERR_OVERLAY_WITH_VDI,
+ IPU_CHECK_ERR_PROC_NO_NEED,
+ IPU_CHECK_ERR_SPLIT_INPUTW_OVER,
+ IPU_CHECK_ERR_SPLIT_INPUTH_OVER,
+ IPU_CHECK_ERR_SPLIT_OUTPUTW_OVER,
+ IPU_CHECK_ERR_SPLIT_OUTPUTH_OVER,
+ IPU_CHECK_ERR_SPLIT_WITH_ROT,
+ IPU_CHECK_ERR_NOT_SUPPORT,
+ IPU_CHECK_ERR_NOT16ALIGN,
+ IPU_CHECK_ERR_W_DOWNSIZE_OVER,
+ IPU_CHECK_ERR_H_DOWNSIZE_OVER,
+};
+
+/* IOCTL commands */
+#define IPU_CHECK_TASK _IOWR('I', 0x1, struct ipu_task)
+#define IPU_QUEUE_TASK _IOW('I', 0x2, struct ipu_task)
+#define IPU_ALLOC _IOWR('I', 0x3, int)
+#define IPU_FREE _IOW('I', 0x4, int)
+
+#endif
diff --git a/include/uapi/linux/isl29023.h b/include/uapi/linux/isl29023.h
new file mode 100644
index 000000000000..9fddf4282573
--- /dev/null
+++ b/include/uapi/linux/isl29023.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2011-2014 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __UAPI_LINUX_ISL29023_H__
+#define __UAPI_LINUX_ISL29023_H__
+
+#include <linux/types.h>
+
+#define ISL29023_PD_MODE 0x0
+#define ISL29023_ALS_ONCE_MODE 0x1
+#define ISL29023_IR_ONCE_MODE 0x2
+#define ISL29023_ALS_CONT_MODE 0x5
+#define ISL29023_IR_CONT_MODE 0x6
+
+#define ISL29023_INT_PERSISTS_1 0x0
+#define ISL29023_INT_PERSISTS_4 0x1
+#define ISL29023_INT_PERSISTS_8 0x2
+#define ISL29023_INT_PERSISTS_16 0x3
+
+#define ISL29023_RES_16 0x0
+#define ISL29023_RES_12 0x1
+#define ISL29023_RES_8 0x2
+#define ISL29023_RES_4 0x3
+
+#define ISL29023_RANGE_1K 0x0
+#define ISL29023_RANGE_4K 0x1
+#define ISL29023_RANGE_16K 0x2
+#define ISL29023_RANGE_64K 0x3
+
+#endif
diff --git a/include/uapi/linux/media-bus-format.h b/include/uapi/linux/media-bus-format.h
index 9e3511742fdc..3083f0734264 100644
--- a/include/uapi/linux/media-bus-format.h
+++ b/include/uapi/linux/media-bus-format.h
@@ -34,7 +34,7 @@
#define MEDIA_BUS_FMT_FIXED 0x0001
-/* RGB - next is 0x101b */
+/* RGB - next is 0x101f */
#define MEDIA_BUS_FMT_RGB444_1X12 0x1016
#define MEDIA_BUS_FMT_RGB444_2X8_PADHI_BE 0x1001
#define MEDIA_BUS_FMT_RGB444_2X8_PADHI_LE 0x1002
@@ -61,6 +61,10 @@
#define MEDIA_BUS_FMT_RGB101010_1X30 0x1018
#define MEDIA_BUS_FMT_RGB121212_1X36 0x1019
#define MEDIA_BUS_FMT_RGB161616_1X48 0x101a
+#define MEDIA_BUS_FMT_RGB888_1X30_PADLO 0x101b
+#define MEDIA_BUS_FMT_RGB666_1X30_PADLO 0x101c
+#define MEDIA_BUS_FMT_RGB101010_1X7X5_SPWG 0x101d
+#define MEDIA_BUS_FMT_RGB101010_1X7X5_JEIDA 0x101e
/* YUV (including grey) - next is 0x202c */
#define MEDIA_BUS_FMT_Y8_1X8 0x2001
diff --git a/include/uapi/linux/mxc_asrc.h b/include/uapi/linux/mxc_asrc.h
new file mode 100644
index 000000000000..837deea53f5b
--- /dev/null
+++ b/include/uapi/linux/mxc_asrc.h
@@ -0,0 +1,171 @@
+/*
+ * Copyright 2008-2014 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file mxc_asrc.h
+ *
+ * @brief i.MX Asynchronous Sample Rate Converter
+ *
+ * @ingroup Audio
+ */
+
+#ifndef __MXC_ASRC_UAPI_H__
+#define __MXC_ASRC_UAPI_H__
+
+#define ASRC_IOC_MAGIC 'C'
+
+#define ASRC_REQ_PAIR _IOWR(ASRC_IOC_MAGIC, 0, struct asrc_req)
+#define ASRC_CONFIG_PAIR _IOWR(ASRC_IOC_MAGIC, 1, struct asrc_config)
+#define ASRC_RELEASE_PAIR _IOW(ASRC_IOC_MAGIC, 2, enum asrc_pair_index)
+#define ASRC_CONVERT _IOW(ASRC_IOC_MAGIC, 3, struct asrc_convert_buffer)
+#define ASRC_START_CONV _IOW(ASRC_IOC_MAGIC, 4, enum asrc_pair_index)
+#define ASRC_STOP_CONV _IOW(ASRC_IOC_MAGIC, 5, enum asrc_pair_index)
+#define ASRC_STATUS _IOW(ASRC_IOC_MAGIC, 6, struct asrc_status_flags)
+#define ASRC_FLUSH _IOW(ASRC_IOC_MAGIC, 7, enum asrc_pair_index)
+
+enum asrc_pair_index {
+ ASRC_INVALID_PAIR = -1,
+ ASRC_PAIR_A = 0,
+ ASRC_PAIR_B = 1,
+ ASRC_PAIR_C = 2,
+};
+
+#define ASRC_PAIR_MAX_NUM (ASRC_PAIR_C + 1)
+
+enum asrc_inclk {
+ INCLK_NONE = 0x03,
+ INCLK_ESAI_RX = 0x00,
+ INCLK_SSI1_RX = 0x01,
+ INCLK_SSI2_RX = 0x02,
+ INCLK_SSI3_RX = 0x07,
+ INCLK_SPDIF_RX = 0x04,
+ INCLK_MLB_CLK = 0x05,
+ INCLK_PAD = 0x06,
+ INCLK_ESAI_TX = 0x08,
+ INCLK_SSI1_TX = 0x09,
+ INCLK_SSI2_TX = 0x0a,
+ INCLK_SSI3_TX = 0x0b,
+ INCLK_SPDIF_TX = 0x0c,
+ INCLK_ASRCK1_CLK = 0x0f,
+/* imx8 */
+ INCLK_AUD_PLL_DIV_CLK0 = 0x10,
+ INCLK_AUD_PLL_DIV_CLK1 = 0x11,
+ INCLK_AUD_CLK0 = 0x12,
+ INCLK_AUD_CLK1 = 0x13,
+ INCLK_ESAI0_RX_CLK = 0x14,
+ INCLK_ESAI0_TX_CLK = 0x15,
+ INCLK_SPDIF0_RX = 0x16,
+ INCLK_SPDIF1_RX = 0x17,
+ INCLK_SAI0_RX_BCLK = 0x18,
+ INCLK_SAI0_TX_BCLK = 0x19,
+ INCLK_SAI1_RX_BCLK = 0x1a,
+ INCLK_SAI1_TX_BCLK = 0x1b,
+ INCLK_SAI2_RX_BCLK = 0x1c,
+ INCLK_SAI3_RX_BCLK = 0x1d,
+ INCLK_ASRC0_MUX_CLK = 0x1e,
+
+ INCLK_ESAI1_RX_CLK = 0x20,
+ INCLK_ESAI1_TX_CLK = 0x21,
+ INCLK_SAI6_TX_BCLK = 0x22,
+ INCLK_HDMI_RX_SAI0_RX_BCLK = 0x24,
+ INCLK_HDMI_TX_SAI0_TX_BCLK = 0x25,
+};
+
+enum asrc_outclk {
+ OUTCLK_NONE = 0x03,
+ OUTCLK_ESAI_TX = 0x00,
+ OUTCLK_SSI1_TX = 0x01,
+ OUTCLK_SSI2_TX = 0x02,
+ OUTCLK_SSI3_TX = 0x07,
+ OUTCLK_SPDIF_TX = 0x04,
+ OUTCLK_MLB_CLK = 0x05,
+ OUTCLK_PAD = 0x06,
+ OUTCLK_ESAI_RX = 0x08,
+ OUTCLK_SSI1_RX = 0x09,
+ OUTCLK_SSI2_RX = 0x0a,
+ OUTCLK_SSI3_RX = 0x0b,
+ OUTCLK_SPDIF_RX = 0x0c,
+ OUTCLK_ASRCK1_CLK = 0x0f,
+
+/* imx8 */
+ OUTCLK_AUD_PLL_DIV_CLK0 = 0x10,
+ OUTCLK_AUD_PLL_DIV_CLK1 = 0x11,
+ OUTCLK_AUD_CLK0 = 0x12,
+ OUTCLK_AUD_CLK1 = 0x13,
+ OUTCLK_ESAI0_RX_CLK = 0x14,
+ OUTCLK_ESAI0_TX_CLK = 0x15,
+ OUTCLK_SPDIF0_RX = 0x16,
+ OUTCLK_SPDIF1_RX = 0x17,
+ OUTCLK_SAI0_RX_BCLK = 0x18,
+ OUTCLK_SAI0_TX_BCLK = 0x19,
+ OUTCLK_SAI1_RX_BCLK = 0x1a,
+ OUTCLK_SAI1_TX_BCLK = 0x1b,
+ OUTCLK_SAI2_RX_BCLK = 0x1c,
+ OUTCLK_SAI3_RX_BCLK = 0x1d,
+ OUTCLK_ASRCO_MUX_CLK = 0x1e,
+
+ OUTCLK_ESAI1_RX_CLK = 0x20,
+ OUTCLK_ESAI1_TX_CLK = 0x21,
+ OUTCLK_SAI6_TX_BCLK = 0x22,
+ OUTCLK_HDMI_RX_SAI0_RX_BCLK = 0x24,
+ OUTCLK_HDMI_TX_SAI0_TX_BCLK = 0x25,
+};
+
+enum asrc_word_width {
+ ASRC_WIDTH_24_BIT = 0,
+ ASRC_WIDTH_16_BIT = 1,
+ ASRC_WIDTH_8_BIT = 2,
+};
+
+struct asrc_config {
+ enum asrc_pair_index pair;
+ unsigned int channel_num;
+ unsigned int buffer_num;
+ unsigned int dma_buffer_size;
+ unsigned int input_sample_rate;
+ unsigned int output_sample_rate;
+ enum asrc_word_width input_word_width;
+ enum asrc_word_width output_word_width;
+ enum asrc_inclk inclk;
+ enum asrc_outclk outclk;
+};
+
+struct asrc_req {
+ unsigned int chn_num;
+ enum asrc_pair_index index;
+};
+
+struct asrc_querybuf {
+ unsigned int buffer_index;
+ unsigned int input_length;
+ unsigned int output_length;
+ unsigned long input_offset;
+ unsigned long output_offset;
+};
+
+struct asrc_convert_buffer {
+ void *input_buffer_vaddr;
+ void *output_buffer_vaddr;
+ unsigned int input_buffer_length;
+ unsigned int output_buffer_length;
+};
+
+struct asrc_status_flags {
+ enum asrc_pair_index index;
+ unsigned int overload_error;
+};
+
+enum asrc_error_status {
+ ASRC_TASK_Q_OVERLOAD = 0x01,
+ ASRC_OUTPUT_TASK_OVERLOAD = 0x02,
+ ASRC_INPUT_TASK_OVERLOAD = 0x04,
+ ASRC_OUTPUT_BUFFER_OVERFLOW = 0x08,
+ ASRC_INPUT_BUFFER_UNDERRUN = 0x10,
+};
+#endif/* __MXC_ASRC_UAPI_H__ */
diff --git a/include/uapi/linux/mxc_dcic.h b/include/uapi/linux/mxc_dcic.h
new file mode 100644
index 000000000000..83e3e2c68c02
--- /dev/null
+++ b/include/uapi/linux/mxc_dcic.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2014-2015 Freescale Semiconductor, Inc. All Rights Reserved
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+/*!
+ * @file uapi/linux/mxc_dcic.h
+ *
+ * @brief MXC DCIC private header file
+ *
+ * @ingroup MXC DCIC
+ */
+#ifndef __ASM_ARCH_MXC_DCIC_H__
+#define __ASM_ARCH_MXC_DCIC_H__
+
+#define DCIC_IOC_ALLOC_ROI_NUM _IO('D', 10)
+#define DCIC_IOC_FREE_ROI_NUM _IO('D', 11)
+#define DCIC_IOC_CONFIG_DCIC _IO('D', 12)
+#define DCIC_IOC_CONFIG_ROI _IO('D', 13)
+#define DCIC_IOC_GET_RESULT _IO('D', 14)
+
+struct roi_params {
+ unsigned int roi_n;
+ unsigned int ref_sig;
+ unsigned int start_y;
+ unsigned int start_x;
+ unsigned int end_y;
+ unsigned int end_x;
+ char freeze;
+};
+
+#endif
diff --git a/include/uapi/linux/mxc_dsp.h b/include/uapi/linux/mxc_dsp.h
new file mode 100644
index 000000000000..040681cc39c8
--- /dev/null
+++ b/include/uapi/linux/mxc_dsp.h
@@ -0,0 +1,152 @@
+/*
+ * Copyright 2018 NXP
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __MXC_DSP_UAPI_H__
+#define __MXC_DSP_UAPI_H__
+
+#define DSP_IOC_MAGIC 'H'
+#define DSP_CLIENT_REGISTER _IOW(DSP_IOC_MAGIC, 0, unsigned int)
+#define DSP_CLIENT_UNREGISTER _IOW(DSP_IOC_MAGIC, 1, unsigned int)
+#define DSP_IPC_MSG_SEND _IOW(DSP_IOC_MAGIC, 2, unsigned int)
+#define DSP_IPC_MSG_RECV _IOW(DSP_IOC_MAGIC, 3, unsigned int)
+#define DSP_GET_SHMEM_INFO _IOW(DSP_IOC_MAGIC, 4, unsigned int)
+#define DSP_LOAD_LIB _IOW(DSP_IOC_MAGIC, 5, unsigned int)
+#define DSP_UNLOAD_LIB _IOW(DSP_IOC_MAGIC, 6, unsigned int)
+
+
+#define CODEC_MP3_DEC 1
+#define CODEC_AAC_DEC 2
+#define CODEC_DAB_DEC 3
+#define CODEC_MP2_DEC 4
+#define CODEC_BSAC_DEC 5
+#define CODEC_DRM_DEC 6
+#define CODEC_SBC_DEC 7
+#define CODEC_SBC_ENC 8
+#define CODEC_DEMO_DEC 9
+
+#define RENDER_ESAI 0x10
+#define RENDER_SAI 0x11
+
+enum DSP_ERROR_TYPE {
+ XA_SUCCESS = 0,
+
+ XA_ERROR_STREAM,
+ XA_PARA_ERROR,
+ XA_INSUFFICIENT_MEM,
+ XA_ERR_UNKNOWN,
+ XA_PROFILE_NOT_SUPPORT,
+ XA_INIT_ERR,
+ XA_NO_OUTPUT,
+
+ XA_NOT_ENOUGH_DATA = 0x100,
+ XA_CAPIBILITY_CHANGE = 0x200,
+ XA_END_OF_STREAM = 0x300, /* no output */
+};
+
+/* Parameter type to Set /Get */
+enum DSP_ParaType {
+/* Set parmameters */
+/* common */
+ XA_SAMPLERATE = 0,
+ XA_CHANNEL,
+ XA_FRAMED, /* one whole frame input */
+ XA_DEPTH,
+ XA_CODEC_DATA,
+ XA_BITRATE,
+ XA_DOWNMIX_STEREO,
+ XA_STREAM_TYPE,
+ XA_CHAN_MAP_TABLE,
+ //UNIA_CHANNEL_MASK,
+ XA_TO_STEREO,
+
+/* dedicate for mp3 dec */
+ XA_MP3_DEC_CRC_CHECK = 0x120,
+ XA_MP3_DEC_MCH_ENABLE,
+ XA_MP3_DEC_NONSTD_STRM_SUPPORT,
+
+/* dedicate for bsac dec */
+ XA_BSAC_DEC_DECODELAYERS = 0x130,
+
+/* dedicate for aacplus dec */
+ XA_AACPLUS_DEC_BDOWNSAMPLE = 0x140,
+ XA_AACPLUS_DEC_BBITSTREAMDOWNMIX,
+ XA_AACPLUS_DEC_CHANROUTING,
+
+/* dedicate for dabplus dec */
+ XA_DABPLUS_DEC_BDOWNSAMPLE = 0x150,
+ XA_DABPLUS_DEC_BBITSTREAMDOWNMIX,
+ XA_DABPLUS_DEC_CHANROUTING,
+
+/* dedicate for sbc enc */
+ XA_SBC_ENC_SUBBANDS = 0x160,
+ XA_SBC_ENC_BLOCKS,
+ XA_SBC_ENC_SNR,
+ XA_SBC_ENC_BITPOOL,
+ XA_SBC_ENC_CHMODE,
+
+/* Get parmameters */
+ XA_CODEC_DESCRIPTION = 0x200,
+ XA_OUTPUT_PCM_FORMAT,
+ XA_CONSUMED_LENGTH,
+ XA_OUTBUF_ALLOC_SIZE,
+ XA_CONSUMED_CYCLES,
+
+};
+
+#define XA_STREAM_DABPLUS_BASE 0x30
+enum DSP_StreamType {
+ /* AAC/AACPLUS file format */
+ XA_STREAM_UNKNOWN = 0,
+ XA_STREAM_ADTS,
+ XA_STREAM_ADIF,
+ XA_STREAM_RAW,
+
+ XA_STREAM_LATM,
+ XA_STREAM_LATM_OUTOFBAND_CONFIG,
+ XA_STREAM_LOAS,
+
+ /* DABPLUS file format */
+ XA_STREAM_DABPLUS_RAW_SIDEINFO = XA_STREAM_DABPLUS_BASE,
+ XA_STREAM_DABPLUS,
+
+ /* BSAC file raw format */
+ XA_STREAM_BSAC_RAW,
+
+};
+
+/* sbc_enc-specific channel modes */
+enum DSP_SbcEncChmode {
+ XA_CHMODE_MONO = 0,
+ XA_CHMODE_DUAL = 1,
+ XA_CHMODE_STEREO = 2,
+ XA_CHMODE_JOINT = 3,
+};
+
+struct shmem_info {
+ unsigned int phys_addr;
+ unsigned int size;
+};
+
+#endif/* __MXC_DSP_UAPI_H__ */
diff --git a/include/uapi/linux/mxc_mlb.h b/include/uapi/linux/mxc_mlb.h
new file mode 100644
index 000000000000..20ba5240ea51
--- /dev/null
+++ b/include/uapi/linux/mxc_mlb.h
@@ -0,0 +1,55 @@
+/*
+ * mxc_mlb.h
+ *
+ * Copyright 2008-2013 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#ifndef _MXC_MLB_UAPI_H
+#define _MXC_MLB_UAPI_H
+
+/* define IOCTL command */
+#define MLB_DBG_RUNTIME _IO('S', 0x09)
+#define MLB_SET_FPS _IOW('S', 0x10, unsigned int)
+#define MLB_GET_VER _IOR('S', 0x11, unsigned long)
+#define MLB_SET_DEVADDR _IOR('S', 0x12, unsigned char)
+
+/*!
+ * set channel address for each logical channel
+ * the MSB 16bits is for tx channel, the left LSB is for rx channel
+ */
+#define MLB_CHAN_SETADDR _IOW('S', 0x13, unsigned int)
+#define MLB_CHAN_STARTUP _IO('S', 0x14)
+#define MLB_CHAN_SHUTDOWN _IO('S', 0x15)
+#define MLB_CHAN_GETEVENT _IOR('S', 0x16, unsigned long)
+
+#define MLB_SET_ISOC_BLKSIZE_188 _IO('S', 0x17)
+#define MLB_SET_ISOC_BLKSIZE_196 _IO('S', 0x18)
+#define MLB_SET_SYNC_QUAD _IOW('S', 0x19, unsigned int)
+#define MLB_IRQ_ENABLE _IO('S', 0x20)
+#define MLB_IRQ_DISABLE _IO('S', 0x21)
+
+/*!
+ * MLB event define
+ */
+enum {
+ MLB_EVT_TX_PROTO_ERR_CUR = 1 << 0,
+ MLB_EVT_TX_BRK_DETECT_CUR = 1 << 1,
+ MLB_EVT_TX_PROTO_ERR_PREV = 1 << 8,
+ MLB_EVT_TX_BRK_DETECT_PREV = 1 << 9,
+ MLB_EVT_RX_PROTO_ERR_CUR = 1 << 16,
+ MLB_EVT_RX_BRK_DETECT_CUR = 1 << 17,
+ MLB_EVT_RX_PROTO_ERR_PREV = 1 << 24,
+ MLB_EVT_RX_BRK_DETECT_PREV = 1 << 25,
+};
+
+
+#endif /* _MXC_MLB_H */
diff --git a/include/uapi/linux/mxc_sim_interface.h b/include/uapi/linux/mxc_sim_interface.h
new file mode 100644
index 000000000000..9ac3c029ab40
--- /dev/null
+++ b/include/uapi/linux/mxc_sim_interface.h
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 2015 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+#ifndef UAPI_MXC_SIM_INTERFACE_H
+#define UAPI_MXC_SIM_INTERFACE_H
+
+#define SIM_ATR_LENGTH_MAX 32
+
+/* Raw ATR SIM_IOCTL_GET_ATR */
+typedef struct {
+ unsigned int size;/* length of ATR received */
+ unsigned char *atr_buffer;/* raw ATR string received */
+ int errval;/* The error vale reported to user space after completing ATR*/
+} sim_atr_t;
+
+/* ISO7816-3 protocols */
+#define SIM_PROTOCOL_T0 1
+#define SIM_PROTOCOL_T1 2
+
+/* Transfer types for SIM_IOCTL_XFER */
+#define SIM_XFER_TYPE_TPDU 1
+#define SIM_XFER_TYPE_PTS 2
+
+typedef struct {
+ unsigned int wwt;
+ unsigned int cwt;
+ unsigned int bwt;
+ unsigned int bgt;
+ unsigned int cgt;
+} sim_timing_t;
+
+/* Transfer data for SIM_IOCTL_XFER */
+typedef struct {
+ unsigned char *xmt_buffer; /* transmit buffer pointer */
+ int xmt_length;/* transmit buffer length */
+ int timeout;/* transfer timeout in milliseconds */
+ int errval;/* The error vale reported to user space after completing transmitting*/
+} sim_xmt_t;
+
+typedef struct {
+ unsigned char *rcv_buffer; /* receive buffer pointer */
+ int rcv_length; /* receive buffer length */
+ int timeout;/* transfer timeout in milliseconds */
+ int errval;/* The error vale reported to user space after receiving*/
+} sim_rcv_t;
+
+typedef struct {
+ unsigned char di;
+ unsigned char fi;
+} sim_baud_t;
+
+/* Interface power states */
+#define SIM_POWER_OFF (0)
+#define SIM_POWER_ON (1)
+
+/* Return values for SIM_IOCTL_GET_PRESENSE */
+#define SIM_PRESENT_REMOVED (0)
+#define SIM_PRESENT_DETECTED (1)
+#define SIM_PRESENT_OPERATIONAL (2)
+
+/* The error value */
+#define SIM_OK (0)
+#define SIM_ERROR_CWT (1 << 0)
+#define SIM_ERROR_BWT (1 << 1)
+#define SIM_ERROR_PARITY (1 << 2)
+#define SIM_ERROR_INVALID_TS (1 << 3)
+#define SIM_ERROR_FRAME (1 << 4)
+#define SIM_ERROR_ATR_TIMEROUT (1 << 5)
+#define SIM_ERROR_NACK_THRESHOLD (1 << 6)
+#define SIM_ERROR_BGT (1 << 7)
+#define SIM_ERROR_ATR_DELAY (1 << 8)
+
+/* Return values for SIM_IOCTL_GET_ERROR */
+#define SIM_E_ACCESS (1)
+#define SIM_E_TPDUSHORT (2)
+#define SIM_E_PTSEMPTY (3)
+#define SIM_E_INVALIDXFERTYPE (4)
+#define SIM_E_INVALIDXMTLENGTH (5)
+#define SIM_E_INVALIDRCVLENGTH (6)
+#define SIM_E_NACK (7)
+#define SIM_E_TIMEOUT (8)
+#define SIM_E_NOCARD (9)
+#define SIM_E_PARAM_FI_INVALID (10)
+#define SIM_E_PARAM_DI_INVALID (11)
+#define SIM_E_PARAM_FBYD_WITHFRACTION (12)
+#define SIM_E_PARAM_FBYD_NOTDIVBY8OR12 (13)
+#define SIM_E_PARAM_DIVISOR_RANGE (14)
+#define SIM_E_MALLOC (15)
+#define SIM_E_IRQ (16)
+#define SIM_E_POWERED_ON (17)
+#define SIM_E_POWERED_OFF (18)
+
+/* ioctl encodings */
+#define SIM_IOCTL_BASE (0xc0)
+#define SIM_IOCTL_GET_PRESENSE _IOR(SIM_IOCTL_BASE, 1, int)
+#define SIM_IOCTL_GET_ATR _IOR(SIM_IOCTL_BASE, 2, sim_atr_t)
+#define SIM_IOCTL_XMT _IOR(SIM_IOCTL_BASE, 3, sim_xmt_t)
+#define SIM_IOCTL_RCV _IOR(SIM_IOCTL_BASE, 4, sim_rcv_t)
+#define SIM_IOCTL_ACTIVATE _IO(SIM_IOCTL_BASE, 5)
+#define SIM_IOCTL_DEACTIVATE _IO(SIM_IOCTL_BASE, 6)
+#define SIM_IOCTL_WARM_RESET _IO(SIM_IOCTL_BASE, 7)
+#define SIM_IOCTL_COLD_RESET _IO(SIM_IOCTL_BASE, 8)
+#define SIM_IOCTL_CARD_LOCK _IO(SIM_IOCTL_BASE, 9)
+#define SIM_IOCTL_CARD_EJECT _IO(SIM_IOCTL_BASE, 10)
+#define SIM_IOCTL_SET_PROTOCOL _IOR(SIM_IOCTL_BASE, 11, unsigned int)
+#define SIM_IOCTL_SET_TIMING _IOR(SIM_IOCTL_BASE, 12, sim_timing_t)
+#define SIM_IOCTL_SET_BAUD _IOR(SIM_IOCTL_BASE, 13, sim_baud_t)
+#define SIM_IOCTL_WAIT _IOR(SIM_IOCTL_BASE, 14, unsigned int)
+
+#endif
diff --git a/include/uapi/linux/mxc_v4l2.h b/include/uapi/linux/mxc_v4l2.h
new file mode 100644
index 000000000000..f261b925a7ed
--- /dev/null
+++ b/include/uapi/linux/mxc_v4l2.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2013-2015 Freescale Semiconductor, Inc. All Rights Reserved
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+/*!
+ * @file uapi/linux/mxc_v4l2.h
+ *
+ * @brief MXC V4L2 private header file
+ *
+ * @ingroup MXC V4L2
+ */
+
+#ifndef __ASM_ARCH_MXC_V4L2_H__
+#define __ASM_ARCH_MXC_V4L2_H__
+
+/*
+ * For IPUv1 and IPUv3, V4L2_CID_MXC_ROT means encoder ioctl ID.
+ * And V4L2_CID_MXC_VF_ROT is viewfinder ioctl ID only for IPUv1 and IPUv3.
+ */
+#define V4L2_CID_MXC_ROT (V4L2_CID_PRIVATE_BASE + 0)
+#define V4L2_CID_MXC_FLASH (V4L2_CID_PRIVATE_BASE + 1)
+#define V4L2_CID_MXC_VF_ROT (V4L2_CID_PRIVATE_BASE + 2)
+#define V4L2_CID_MXC_MOTION (V4L2_CID_PRIVATE_BASE + 3)
+#define V4L2_CID_MXC_SWITCH_CAM (V4L2_CID_PRIVATE_BASE + 6)
+
+#define V4L2_MXC_ROTATE_NONE 0
+#define V4L2_MXC_ROTATE_VERT_FLIP 1
+#define V4L2_MXC_ROTATE_HORIZ_FLIP 2
+#define V4L2_MXC_ROTATE_180 3
+#define V4L2_MXC_ROTATE_90_RIGHT 4
+#define V4L2_MXC_ROTATE_90_RIGHT_VFLIP 5
+#define V4L2_MXC_ROTATE_90_RIGHT_HFLIP 6
+#define V4L2_MXC_ROTATE_90_LEFT 7
+
+struct v4l2_mxc_offset {
+ uint32_t u_offset;
+ uint32_t v_offset;
+};
+
+struct v4l2_mxc_dest_crop {
+ __u32 type; /* enum v4l2_buf_type */
+ struct v4l2_mxc_offset offset;
+};
+
+/*
+ * Private IOCTLs
+ *
+ * VIDIOC_S_INOUT_CROP: Set input stream crop size
+ * VIDIOC_G_INOUT_CROP: Get input stream crop size
+ */
+#define VIDIOC_S_INPUT_CROP \
+ _IOWR('V', BASE_VIDIOC_PRIVATE + 1, struct v4l2_crop)
+#define VIDIOC_G_INPUT_CROP \
+ _IOWR('V', BASE_VIDIOC_PRIVATE + 2, struct v4l2_crop)
+#define VIDIOC_S_DEST_CROP \
+ _IOWR('V', BASE_VIDIOC_PRIVATE + 3, struct v4l2_mxc_dest_crop)
+#endif
diff --git a/include/uapi/linux/mxcfb.h b/include/uapi/linux/mxcfb.h
new file mode 100644
index 000000000000..3a984090769a
--- /dev/null
+++ b/include/uapi/linux/mxcfb.h
@@ -0,0 +1,198 @@
+/*
+ * Copyright (C) 2013-2015 Freescale Semiconductor, Inc. All Rights Reserved
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+/*
+ * @file uapi/linux/mxcfb.h
+ *
+ * @brief Global header file for the MXC frame buffer
+ *
+ * @ingroup Framebuffer
+ */
+#ifndef __ASM_ARCH_MXCFB_H__
+#define __ASM_ARCH_MXCFB_H__
+
+#include <linux/fb.h>
+
+#define FB_SYNC_OE_LOW_ACT 0x80000000
+#define FB_SYNC_CLK_LAT_FALL 0x40000000
+#define FB_SYNC_DATA_INVERT 0x20000000
+#define FB_SYNC_CLK_IDLE_EN 0x10000000
+#define FB_SYNC_SHARP_MODE 0x08000000
+#define FB_SYNC_SWAP_RGB 0x04000000
+#define FB_ACCEL_TRIPLE_FLAG 0x00000000
+#define FB_ACCEL_DOUBLE_FLAG 0x00000001
+
+struct mxcfb_gbl_alpha {
+ int enable;
+ int alpha;
+};
+
+struct mxcfb_loc_alpha {
+ int enable;
+ int alpha_in_pixel;
+ unsigned long alpha_phy_addr0;
+ unsigned long alpha_phy_addr1;
+};
+
+struct mxcfb_color_key {
+ int enable;
+ __u32 color_key;
+};
+
+struct mxcfb_pos {
+ __u16 x;
+ __u16 y;
+};
+
+struct mxcfb_gamma {
+ int enable;
+ int constk[16];
+ int slopek[16];
+};
+
+struct mxcfb_gpu_split_fmt {
+ struct fb_var_screeninfo var;
+ unsigned long offset;
+};
+
+struct mxcfb_rect {
+ __u32 top;
+ __u32 left;
+ __u32 width;
+ __u32 height;
+};
+
+#define GRAYSCALE_8BIT 0x1
+#define GRAYSCALE_8BIT_INVERTED 0x2
+#define GRAYSCALE_4BIT 0x3
+#define GRAYSCALE_4BIT_INVERTED 0x4
+
+#define AUTO_UPDATE_MODE_REGION_MODE 0
+#define AUTO_UPDATE_MODE_AUTOMATIC_MODE 1
+
+#define UPDATE_SCHEME_SNAPSHOT 0
+#define UPDATE_SCHEME_QUEUE 1
+#define UPDATE_SCHEME_QUEUE_AND_MERGE 2
+
+#define UPDATE_MODE_PARTIAL 0x0
+#define UPDATE_MODE_FULL 0x1
+
+#define WAVEFORM_MODE_GLR16 4
+#define WAVEFORM_MODE_GLD16 5
+#define WAVEFORM_MODE_AUTO 257
+
+#define TEMP_USE_AMBIENT 0x1000
+
+#define EPDC_FLAG_ENABLE_INVERSION 0x01
+#define EPDC_FLAG_FORCE_MONOCHROME 0x02
+#define EPDC_FLAG_USE_CMAP 0x04
+#define EPDC_FLAG_USE_ALT_BUFFER 0x100
+#define EPDC_FLAG_TEST_COLLISION 0x200
+#define EPDC_FLAG_GROUP_UPDATE 0x400
+#define EPDC_FLAG_USE_DITHERING_Y1 0x2000
+#define EPDC_FLAG_USE_DITHERING_Y4 0x4000
+#define EPDC_FLAG_USE_REGAL 0x8000
+
+enum mxcfb_dithering_mode {
+ EPDC_FLAG_USE_DITHERING_PASSTHROUGH = 0x0,
+ EPDC_FLAG_USE_DITHERING_FLOYD_STEINBERG,
+ EPDC_FLAG_USE_DITHERING_ATKINSON,
+ EPDC_FLAG_USE_DITHERING_ORDERED,
+ EPDC_FLAG_USE_DITHERING_QUANT_ONLY,
+ EPDC_FLAG_USE_DITHERING_MAX,
+};
+
+#define FB_POWERDOWN_DISABLE -1
+
+struct mxcfb_alt_buffer_data {
+ __u32 phys_addr;
+ __u32 width; /* width of entire buffer */
+ __u32 height; /* height of entire buffer */
+ struct mxcfb_rect alt_update_region; /* region within buffer to update */
+};
+
+struct mxcfb_update_data {
+ struct mxcfb_rect update_region;
+ __u32 waveform_mode;
+ __u32 update_mode;
+ __u32 update_marker;
+ int temp;
+ unsigned int flags;
+ int dither_mode;
+ int quant_bit;
+ struct mxcfb_alt_buffer_data alt_buffer_data;
+};
+
+struct mxcfb_update_marker_data {
+ __u32 update_marker;
+ __u32 collision_test;
+};
+
+/*
+ * Structure used to define waveform modes for driver
+ * Needed for driver to perform auto-waveform selection
+ */
+struct mxcfb_waveform_modes {
+ int mode_init;
+ int mode_du;
+ int mode_gc4;
+ int mode_gc8;
+ int mode_gc16;
+ int mode_gc32;
+};
+
+/*
+ * Structure used to define a 5*3 matrix of parameters for
+ * setting IPU DP CSC module related to this framebuffer.
+ */
+struct mxcfb_csc_matrix {
+ int param[5][3];
+};
+
+#define MXCFB_WAIT_FOR_VSYNC _IOW('F', 0x20, u_int32_t)
+#define MXCFB_SET_GBL_ALPHA _IOW('F', 0x21, struct mxcfb_gbl_alpha)
+#define MXCFB_SET_CLR_KEY _IOW('F', 0x22, struct mxcfb_color_key)
+#define MXCFB_SET_OVERLAY_POS _IOWR('F', 0x24, struct mxcfb_pos)
+#define MXCFB_GET_FB_IPU_CHAN _IOR('F', 0x25, u_int32_t)
+#define MXCFB_SET_LOC_ALPHA _IOWR('F', 0x26, struct mxcfb_loc_alpha)
+#define MXCFB_SET_LOC_ALP_BUF _IOW('F', 0x27, unsigned long)
+#define MXCFB_SET_GAMMA _IOW('F', 0x28, struct mxcfb_gamma)
+#define MXCFB_GET_FB_IPU_DI _IOR('F', 0x29, u_int32_t)
+#define MXCFB_GET_DIFMT _IOR('F', 0x2A, u_int32_t)
+#define MXCFB_GET_FB_BLANK _IOR('F', 0x2B, u_int32_t)
+#define MXCFB_SET_DIFMT _IOW('F', 0x2C, u_int32_t)
+#define MXCFB_CSC_UPDATE _IOW('F', 0x2D, struct mxcfb_csc_matrix)
+#define MXCFB_SET_GPU_SPLIT_FMT _IOW('F', 0x2F, struct mxcfb_gpu_split_fmt)
+#define MXCFB_SET_PREFETCH _IOW('F', 0x30, int)
+#define MXCFB_GET_PREFETCH _IOR('F', 0x31, int)
+
+/* IOCTLs for E-ink panel updates */
+#define MXCFB_SET_WAVEFORM_MODES _IOW('F', 0x2B, struct mxcfb_waveform_modes)
+#define MXCFB_SET_TEMPERATURE _IOW('F', 0x2C, int32_t)
+#define MXCFB_SET_AUTO_UPDATE_MODE _IOW('F', 0x2D, __u32)
+#define MXCFB_SEND_UPDATE _IOW('F', 0x2E, struct mxcfb_update_data)
+#define MXCFB_WAIT_FOR_UPDATE_COMPLETE _IOWR('F', 0x2F, struct mxcfb_update_marker_data)
+#define MXCFB_SET_PWRDOWN_DELAY _IOW('F', 0x30, int32_t)
+#define MXCFB_GET_PWRDOWN_DELAY _IOR('F', 0x31, int32_t)
+#define MXCFB_SET_UPDATE_SCHEME _IOW('F', 0x32, __u32)
+#define MXCFB_GET_WORK_BUFFER _IOWR('F', 0x34, unsigned long)
+#define MXCFB_DISABLE_EPDC_ACCESS _IO('F', 0x35)
+#define MXCFB_ENABLE_EPDC_ACCESS _IO('F', 0x36)
+#endif
diff --git a/include/uapi/linux/pxp_device.h b/include/uapi/linux/pxp_device.h
new file mode 100644
index 000000000000..fce89ce066bb
--- /dev/null
+++ b/include/uapi/linux/pxp_device.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2013-2014 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+#ifndef _UAPI_PXP_DEVICE
+#define _UAPI_PXP_DEVICE
+
+#include <linux/pxp_dma.h>
+
+struct pxp_chan_handle {
+ unsigned int handle;
+ int hist_status;
+};
+
+struct pxp_mem_desc {
+ unsigned int handle;
+ unsigned int size;
+ dma_addr_t phys_addr;
+ unsigned int virt_uaddr; /* virtual user space address */
+ unsigned int mtype;
+};
+
+struct pxp_mem_flush {
+ unsigned int handle;
+ unsigned int type;
+};
+
+#define PXP_IOC_MAGIC 'P'
+
+#define PXP_IOC_GET_CHAN _IOR(PXP_IOC_MAGIC, 0, struct pxp_mem_desc)
+#define PXP_IOC_PUT_CHAN _IOW(PXP_IOC_MAGIC, 1, struct pxp_mem_desc)
+#define PXP_IOC_CONFIG_CHAN _IOW(PXP_IOC_MAGIC, 2, struct pxp_mem_desc)
+#define PXP_IOC_START_CHAN _IOW(PXP_IOC_MAGIC, 3, struct pxp_mem_desc)
+#define PXP_IOC_GET_PHYMEM _IOWR(PXP_IOC_MAGIC, 4, struct pxp_mem_desc)
+#define PXP_IOC_PUT_PHYMEM _IOW(PXP_IOC_MAGIC, 5, struct pxp_mem_desc)
+#define PXP_IOC_WAIT4CMPLT _IOWR(PXP_IOC_MAGIC, 6, struct pxp_mem_desc)
+#define PXP_IOC_FLUSH_PHYMEM _IOR(PXP_IOC_MAGIC, 7, struct pxp_mem_flush)
+
+/* Memory types supported*/
+#define MEMORY_TYPE_UNCACHED 0x0
+#define MEMORY_TYPE_WC 0x1
+#define MEMORY_TYPE_CACHED 0x2
+
+/* Cache flush operations */
+#define CACHE_CLEAN 0x1
+#define CACHE_INVALIDATE 0x2
+#define CACHE_FLUSH 0x4
+
+#endif
diff --git a/include/uapi/linux/pxp_dma.h b/include/uapi/linux/pxp_dma.h
new file mode 100644
index 000000000000..76983abb4344
--- /dev/null
+++ b/include/uapi/linux/pxp_dma.h
@@ -0,0 +1,346 @@
+/*
+ * Copyright (C) 2013-2015 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2017 NXP
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+#ifndef _UAPI_PXP_DMA
+#define _UAPI_PXP_DMA
+
+#include <linux/posix_types.h>
+#include <linux/types.h>
+
+#ifndef __KERNEL__
+typedef unsigned long dma_addr_t;
+typedef unsigned char bool;
+#endif
+
+/* PXP Pixel format definitions */
+/* Four-character-code (FOURCC) */
+#define fourcc(a, b, c, d)\
+ (((__u32)(a)<<0)|((__u32)(b)<<8)|((__u32)(c)<<16)|((__u32)(d)<<24))
+
+/*!
+ * @name PXP Pixel Formats
+ *
+ * Pixel formats are defined with ASCII FOURCC code. The pixel format codes are
+ * the same used by V4L2 API.
+ */
+
+/*! @} */
+/*! @name RGB Formats */
+/*! @{ */
+#define PXP_PIX_FMT_RGB332 fourcc('R', 'G', 'B', '1') /*!< 8 RGB-3-3-2 */
+#define PXP_PIX_FMT_RGB444 fourcc('R', '4', '4', '4') /* 16 xxxxrrrr ggggbbbb */
+#define PXP_PIX_FMT_ARGB444 fourcc('A', 'R', '1', '2') /* 16 aaaarrrr ggggbbbb */
+#define PXP_PIX_FMT_RGBA444 fourcc('R', 'A', '1', '2') /* 16 rrrrgggg bbbbaaaa */
+#define PXP_PIX_FMT_XRGB444 fourcc('X', 'R', '1', '2') /* 16 xxxxrrrr ggggbbbb */
+#define PXP_PIX_FMT_RGB555 fourcc('R', 'G', 'B', 'O') /*!< 16 RGB-5-5-5 */
+#define PXP_PIX_FMT_ARGB555 fourcc('A', 'R', '1', '5') /*!< 16 ARGB-1-5-5-5 */
+#define PXP_PIX_FMT_RGBA555 fourcc('R', 'A', '1', '5') /*!< 16 RGBA-5-5-5-1 */
+#define PXP_PIX_FMT_XRGB555 fourcc('X', 'R', '1', '5') /*!< 16 XRGB-1-5-5-5 */
+#define PXP_PIX_FMT_RGB565 fourcc('R', 'G', 'B', 'P') /*!< 16 RGB-5-6-5 */
+#define PXP_PIX_FMT_BGR565 fourcc('B', 'G', 'R', 'P') /*!< 16 BGR-5-6-5 */
+#define PXP_PIX_FMT_RGB666 fourcc('R', 'G', 'B', '6') /*!< 18 RGB-6-6-6 */
+#define PXP_PIX_FMT_BGR666 fourcc('B', 'G', 'R', '6') /*!< 18 BGR-6-6-6 */
+#define PXP_PIX_FMT_BGR24 fourcc('B', 'G', 'R', '3') /*!< 24 BGR-8-8-8 */
+#define PXP_PIX_FMT_RGB24 fourcc('R', 'G', 'B', '3') /*!< 24 RGB-8-8-8 */
+#define PXP_PIX_FMT_XBGR32 fourcc('X', 'B', 'G', 'R') /*!< 32 XBGR-8-8-8-8 */
+#define PXP_PIX_FMT_BGRX32 fourcc('B', 'G', 'R', 'X') /*!< 32 BGRX-8-8-8-8 */
+#define PXP_PIX_FMT_BGRA32 fourcc('B', 'G', 'R', 'A') /*!< 32 BGRA-8-8-8-8 */
+#define PXP_PIX_FMT_XRGB32 fourcc('X', 'R', 'G', 'B') /*!< 32 XRGB-8-8-8-8 */
+#define PXP_PIX_FMT_RGBX32 fourcc('R', 'G', 'B', 'X') /*!< 32 RGBX-8-8-8-8 */
+#define PXP_PIX_FMT_ARGB32 fourcc('A', 'R', 'G', 'B') /*!< 32 ARGB-8-8-8-8 */
+#define PXP_PIX_FMT_RGBA32 fourcc('R', 'G', 'B', 'A') /*!< 32 RGBA-8-8-8-8 */
+#define PXP_PIX_FMT_ABGR32 fourcc('A', 'B', 'G', 'R') /*!< 32 ABGR-8-8-8-8 */
+#define PXP_PIX_FMT_RGB32 PXP_PIX_FMT_XRGB32
+/*! @} */
+/*! @name YUV Interleaved Formats */
+/*! @{ */
+#define PXP_PIX_FMT_YUYV fourcc('Y', 'U', 'Y', 'V') /*!< 16 YUV 4:2:2 */
+#define PXP_PIX_FMT_UYVY fourcc('U', 'Y', 'V', 'Y') /*!< 16 YUV 4:2:2 */
+#define PXP_PIX_FMT_VYUY fourcc('V', 'Y', 'U', 'Y') /*!< 16 YVU 4:2:2 */
+#define PXP_PIX_FMT_YVYU fourcc('Y', 'V', 'Y', 'U') /*!< 16 YVU 4:2:2 */
+#define PXP_PIX_FMT_Y41P fourcc('Y', '4', '1', 'P') /*!< 12 YUV 4:1:1 */
+#define PXP_PIX_FMT_VUY444 fourcc('V', 'U', 'Y', 'A') /*!< 32 VUYA 8:8:8 */
+#define PXP_PIX_FMT_YUV444 fourcc('A', 'Y', 'U', 'V') /*!< 32 AYUV 8:8:8 */
+#define PXP_PIX_FMT_YVU444 fourcc('A', 'Y', 'V', 'U') /*!< 32 AYUV 8:8:8 */
+/* two planes -- one Y, one Cb + Cr interleaved */
+#define PXP_PIX_FMT_NV12 fourcc('N', 'V', '1', '2') /* 12 Y/CbCr 4:2:0 */
+#define PXP_PIX_FMT_NV21 fourcc('N', 'V', '2', '1') /* 12 Y/CbCr 4:2:0 */
+#define PXP_PIX_FMT_NV16 fourcc('N', 'V', '1', '6') /* 12 Y/CbCr 4:2:2 */
+#define PXP_PIX_FMT_NV61 fourcc('N', 'V', '6', '1') /* 12 Y/CbCr 4:2:2 */
+/*! @} */
+/*! @name YUV Planar Formats */
+/*! @{ */
+#define PXP_PIX_FMT_GREY fourcc('G', 'R', 'E', 'Y') /*!< 8 Greyscale */
+#define PXP_PIX_FMT_GY04 fourcc('G', 'Y', '0', '4') /*!< 4 Greyscale */
+#define PXP_PIX_FMT_YVU410P fourcc('Y', 'V', 'U', '9') /*!< 9 YVU 4:1:0 */
+#define PXP_PIX_FMT_YUV410P fourcc('Y', 'U', 'V', '9') /*!< 9 YUV 4:1:0 */
+#define PXP_PIX_FMT_YVU420P fourcc('Y', 'V', '1', '2') /*!< 12 YVU 4:2:0 */
+#define PXP_PIX_FMT_YUV420P fourcc('I', '4', '2', '0') /*!< 12 YUV 4:2:0 */
+#define PXP_PIX_FMT_YUV420P2 fourcc('Y', 'U', '1', '2') /*!< 12 YUV 4:2:0 */
+#define PXP_PIX_FMT_YVU422P fourcc('Y', 'V', '1', '6') /*!< 16 YVU 4:2:2 */
+#define PXP_PIX_FMT_YUV422P fourcc('4', '2', '2', 'P') /*!< 16 YUV 4:2:2 */
+/*! @} */
+
+#define PXP_LUT_NONE 0x0
+#define PXP_LUT_INVERT 0x1
+#define PXP_LUT_BLACK_WHITE 0x2
+#define PXP_LUT_USE_CMAP 0x4
+
+/* dithering modes enum */
+#define PXP_DITHER_PASS_THROUGH 0
+#define PXP_DITHER_FLOYD 1
+#define PXP_DITHER_ATKINSON 2
+#define PXP_DITHER_ORDERED 3
+#define PXP_DITHER_QUANT_ONLY 4
+
+#define NR_PXP_VIRT_CHANNEL 16
+
+#define PXP_IOC_MAGIC 'P'
+
+#define PXP_IOC_GET_CHAN _IOR(PXP_IOC_MAGIC, 0, struct pxp_mem_desc)
+#define PXP_IOC_PUT_CHAN _IOW(PXP_IOC_MAGIC, 1, struct pxp_mem_desc)
+#define PXP_IOC_CONFIG_CHAN _IOW(PXP_IOC_MAGIC, 2, struct pxp_mem_desc)
+#define PXP_IOC_START_CHAN _IOW(PXP_IOC_MAGIC, 3, struct pxp_mem_desc)
+#define PXP_IOC_GET_PHYMEM _IOWR(PXP_IOC_MAGIC, 4, struct pxp_mem_desc)
+#define PXP_IOC_PUT_PHYMEM _IOW(PXP_IOC_MAGIC, 5, struct pxp_mem_desc)
+#define PXP_IOC_WAIT4CMPLT _IOWR(PXP_IOC_MAGIC, 6, struct pxp_mem_desc)
+
+#define PXP_IOC_FILL_DATA _IOWR(PXP_IOC_MAGIC, 7, struct pxp_mem_desc)
+
+#define ALPHA_MODE_ROP 0x1
+#define ALPHA_MODE_LEGACY 0x2
+#define ALPHA_MODE_PORTER_DUFF 0x3
+
+#define PXP_DEVICE_LEGACY
+
+/* Order significant! */
+enum pxp_channel_status {
+ PXP_CHANNEL_FREE,
+ PXP_CHANNEL_INITIALIZED,
+ PXP_CHANNEL_READY,
+};
+
+enum pxp_working_mode {
+ PXP_MODE_LEGACY = 0x1,
+ PXP_MODE_STANDARD = 0x2,
+ PXP_MODE_ADVANCED = 0x4,
+};
+
+enum pxp_buffer_flag {
+ PXP_BUF_FLAG_WFE_A_FETCH0 = 0x0001,
+ PXP_BUF_FLAG_WFE_A_FETCH1 = 0x0002,
+ PXP_BUF_FLAG_WFE_A_STORE0 = 0x0004,
+ PXP_BUF_FLAG_WFE_A_STORE1 = 0x0008,
+ PXP_BUF_FLAG_WFE_B_FETCH0 = 0x0010,
+ PXP_BUF_FLAG_WFE_B_FETCH1 = 0x0020,
+ PXP_BUF_FLAG_WFE_B_STORE0 = 0x0040,
+ PXP_BUF_FLAG_WFE_B_STORE1 = 0x0080,
+ PXP_BUF_FLAG_DITHER_FETCH0 = 0x0100,
+ PXP_BUF_FLAG_DITHER_FETCH1 = 0x0200,
+ PXP_BUF_FLAG_DITHER_STORE0 = 0x0400,
+ PXP_BUF_FLAG_DITHER_STORE1 = 0x0800,
+};
+
+enum pxp_engine_ctrl {
+ PXP_ENABLE_ROTATE0 = 0x001,
+ PXP_ENABLE_ROTATE1 = 0x002,
+ PXP_ENABLE_LUT = 0x004,
+ PXP_ENABLE_CSC2 = 0x008,
+ PXP_ENABLE_ALPHA_B = 0x010,
+ PXP_ENABLE_INPUT_FETCH_SOTRE = 0x020,
+ PXP_ENABLE_WFE_B = 0x040,
+ PXP_ENABLE_WFE_A = 0x080,
+ PXP_ENABLE_DITHER = 0x100,
+ PXP_ENABLE_PS_AS_OUT = 0x200,
+ PXP_ENABLE_COLLISION_DETECT = 0x400,
+ PXP_ENABLE_HANDSHAKE = 0x1000,
+ PXP_ENABLE_DITHER_BYPASS = 0x2000,
+};
+
+enum pxp_op_type {
+ PXP_OP_2D = 0x001,
+ PXP_OP_DITHER = 0x002,
+ PXP_OP_WFE_A = 0x004,
+ PXP_OP_WFE_B = 0x008,
+};
+
+struct rect {
+ int top; /* Upper left coordinate of rectangle */
+ int left;
+ int width;
+ int height;
+};
+
+#define ALPHA_MODE_STRAIGHT 0x0
+#define ALPHA_MODE_INVERSED 0x1
+
+#define GLOBAL_ALPHA_MODE_ON 0x0
+#define GLOBAL_ALPHA_MODE_OFF 0x1
+#define GLOBAL_ALPHA_MODE_SCALE 0x2
+
+#define FACTOR_MODE_ONE 0x0
+#define FACTOR_MODE_ZERO 0x1
+#define FACTOR_MODE_STRAIGHT 0x2
+#define FACTOR_MODE_INVERSED 0x3
+
+#define COLOR_MODE_STRAIGHT 0x0
+#define COLOR_MODE_MULTIPLY 0x1
+
+struct pxp_alpha {
+ unsigned int alpha_mode;
+ unsigned int global_alpha_mode;
+ unsigned int global_alpha_value;
+ unsigned int factor_mode;
+ unsigned int color_mode;
+};
+
+struct pxp_layer_param {
+ unsigned short left;
+ unsigned short top;
+ unsigned short width;
+ unsigned short height;
+ unsigned short stride; /* aka pitch */
+ unsigned int pixel_fmt;
+
+ unsigned int flag;
+ /* layers combining parameters
+ * (these are ignored for S0 and output
+ * layers, and only apply for OL layer)
+ */
+ bool combine_enable;
+ unsigned int color_key_enable;
+ unsigned int color_key;
+ bool global_alpha_enable;
+ /* global alpha is either override or multiply */
+ bool global_override;
+ unsigned char global_alpha;
+ bool alpha_invert;
+ bool local_alpha_enable;
+ int comp_mask;
+
+ struct pxp_alpha alpha;
+ struct rect crop;
+
+ dma_addr_t paddr;
+};
+
+struct pxp_collision_info {
+ unsigned int pixel_cnt;
+ unsigned int rect_min_x;
+ unsigned int rect_min_y;
+ unsigned int rect_max_x;
+ unsigned int rect_max_y;
+ unsigned int victim_luts[2];
+};
+
+struct pxp_proc_data {
+ /* S0 Transformation Info */
+ int scaling;
+ int hflip;
+ int vflip;
+ int rotate;
+ int rot_pos;
+ int yuv;
+ unsigned int alpha_mode;
+
+ /* Source rectangle (srect) defines the sub-rectangle
+ * within S0 to undergo processing.
+ */
+ struct rect srect;
+ /* Dest rect (drect) defines how to position the processed
+ * source rectangle (after resizing) within the output frame,
+ * whose dimensions are defined in pxp->pxp_conf_state.out_param
+ */
+ struct rect drect;
+
+ /* Current S0 configuration */
+ unsigned int bgcolor;
+ unsigned char fill_en;
+
+ /* Output overlay support */
+ int overlay_state;
+
+ /* LUT transformation on Y data */
+ int lut_transform;
+ unsigned char *lut_map; /* 256 entries */
+ bool lut_map_updated; /* Map recently changed */
+ bool combine_enable;
+
+ enum pxp_op_type op_type;
+
+ /* LUT cleanup */
+ __u64 lut_sels;
+
+ /* the mode pxp's working against */
+ enum pxp_working_mode working_mode;
+ enum pxp_engine_ctrl engine_enable;
+
+ /* wfe */
+/*
+ * partial:
+ * 0 - full update
+ * 1 - partial update
+ * alpha_en:
+ * 0 - upd is {Y4[3:0],4'b0000} format
+ * 1 - upd is {Y4[3:0],3'b000,alpha} format
+ * reagl_en:
+ * 0 - use normal waveform algorithm
+ * 1 - enable reagl/-d waveform algorithm
+ * detection_only:
+ * 0 - write working buffer
+ * 1 - do no write working buffer, detection only
+ * lut:
+ * valid value 0-63
+ * set to the lut used for next update
+ */
+ bool partial_update;
+ bool alpha_en;
+ bool lut_update;
+ bool reagl_en; /* enable reagl/-d */
+ bool reagl_d_en; /* enable reagl or reagl-d */
+ bool detection_only;
+ bool pxp_legacy;
+ int lut;
+ bool lut_cleanup;
+ unsigned int lut_status_1;
+ unsigned int lut_status_2;
+
+ /* Dithering specific data */
+ int dither_mode;
+ unsigned int quant_bit;
+};
+
+struct pxp_config_data {
+ struct pxp_layer_param s0_param;
+ struct pxp_layer_param ol_param[1];
+ struct pxp_layer_param out_param;
+ struct pxp_layer_param wfe_a_fetch_param[2];
+ struct pxp_layer_param wfe_a_store_param[2];
+ struct pxp_layer_param wfe_b_fetch_param[2];
+ struct pxp_layer_param wfe_b_store_param[2];
+ struct pxp_layer_param dither_fetch_param[2];
+ struct pxp_layer_param dither_store_param[2];
+ struct pxp_proc_data proc_data;
+ int layer_nr;
+
+ /* Users don't touch */
+ int handle;
+};
+
+#endif
diff --git a/include/uapi/linux/tee.h b/include/uapi/linux/tee.h
index 688782e90140..31f71276f413 100644
--- a/include/uapi/linux/tee.h
+++ b/include/uapi/linux/tee.h
@@ -117,6 +117,35 @@ struct tee_ioctl_shm_alloc_data {
struct tee_ioctl_shm_alloc_data)
/**
+ * struct tee_ioctl_shm_register_fd_data - Shared memory registering argument
+ * @fd: [in] file descriptor identifying the shared memory
+ * @size: [out] Size of shared memory to allocate
+ * @flags: [in] Flags to/from allocation.
+ * @id: [out] Identifier of the shared memory
+ *
+ * The flags field should currently be zero as input. Updated by the call
+ * with actual flags as defined by TEE_IOCTL_SHM_* above.
+ * This structure is used as argument for TEE_IOC_SHM_ALLOC below.
+ */
+struct tee_ioctl_shm_register_fd_data {
+ __s64 fd;
+ __u64 size;
+ __u32 flags;
+ __s32 id;
+} __aligned(8);
+
+/**
+ * TEE_IOC_SHM_REGISTER_FD - register a shared memory from a file descriptor
+ *
+ * Returns a file descriptor on success or < 0 on failure
+ *
+ * The returned file descriptor refers to the shared memory object in kernel
+ * land. The shared memory is freed when the descriptor is closed.
+ */
+#define TEE_IOC_SHM_REGISTER_FD _IOWR(TEE_IOC_MAGIC, TEE_IOC_BASE + 8, \
+ struct tee_ioctl_shm_register_fd_data)
+
+/**
* struct tee_ioctl_buf_data - Variable sized buffer
* @buf_ptr: [in] A __user pointer to a buffer
* @buf_len: [in] Length of the buffer above
@@ -154,6 +183,13 @@ struct tee_ioctl_buf_data {
*/
#define TEE_IOCTL_PARAM_ATTR_TYPE_MASK 0xff
+/* Meta parameter carrying extra information about the message. */
+#define TEE_IOCTL_PARAM_ATTR_META 0x100
+
+/* Mask of all known attr bits */
+#define TEE_IOCTL_PARAM_ATTR_MASK \
+ (TEE_IOCTL_PARAM_ATTR_TYPE_MASK | TEE_IOCTL_PARAM_ATTR_META)
+
/*
* Matches TEEC_LOGIN_* in GP TEE Client API
* Are only defined for GP compliant TEEs
diff --git a/include/uapi/linux/usb/ch9.h b/include/uapi/linux/usb/ch9.h
index 8512777889b0..2b158a736a6d 100644
--- a/include/uapi/linux/usb/ch9.h
+++ b/include/uapi/linux/usb/ch9.h
@@ -143,6 +143,8 @@
#define TEST_SE0_NAK 3
#define TEST_PACKET 4
#define TEST_FORCE_EN 5
+#define TEST_OTG_SRP_REQD 6
+#define TEST_OTG_HNP_REQD 7
/*
* New Feature Selectors as added by USB 3.0
diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h
index 1c095b5a99c5..cb78112e14b9 100644
--- a/include/uapi/linux/videodev2.h
+++ b/include/uapi/linux/videodev2.h
@@ -511,6 +511,8 @@ struct v4l2_pix_format {
#define V4L2_PIX_FMT_ARGB32 v4l2_fourcc('B', 'A', '2', '4') /* 32 ARGB-8-8-8-8 */
#define V4L2_PIX_FMT_XRGB32 v4l2_fourcc('B', 'X', '2', '4') /* 32 XRGB-8-8-8-8 */
+#define V4L2_PIX_FMT_RGBA v4l2_fourcc('R', 'G', 'B', 'A') /* 32 RGBA-8-8-8-8 */
+
/* Grey formats */
#define V4L2_PIX_FMT_GREY v4l2_fourcc('G', 'R', 'E', 'Y') /* 8 Greyscale */
#define V4L2_PIX_FMT_Y4 v4l2_fourcc('Y', '0', '4', ' ') /* 4 Greyscale */
@@ -2246,13 +2248,11 @@ struct v4l2_event_subscription {
/* VIDIOC_DBG_G_REGISTER and VIDIOC_DBG_S_REGISTER */
#define V4L2_CHIP_MATCH_BRIDGE 0 /* Match against chip ID on the bridge (0 for the bridge) */
-#define V4L2_CHIP_MATCH_SUBDEV 4 /* Match against subdev index */
-
-/* The following four defines are no longer in use */
#define V4L2_CHIP_MATCH_HOST V4L2_CHIP_MATCH_BRIDGE
#define V4L2_CHIP_MATCH_I2C_DRIVER 1 /* Match against I2C driver name */
#define V4L2_CHIP_MATCH_I2C_ADDR 2 /* Match against I2C 7-bit address */
#define V4L2_CHIP_MATCH_AC97 3 /* Match against ancillary AC97 chip */
+#define V4L2_CHIP_MATCH_SUBDEV 4 /* Match against subdev index */
struct v4l2_dbg_match {
__u32 type; /* Match type */
@@ -2269,6 +2269,13 @@ struct v4l2_dbg_register {
__u64 val;
} __attribute__ ((packed));
+/* VIDIOC_DBG_G_CHIP_IDENT */
+struct v4l2_dbg_chip_ident {
+ struct v4l2_dbg_match match;
+ __u32 ident; /* chip identifier as specified in <media/v4l2-chip-ident.h> */
+ __u32 revision; /* chip revision, chip specific */
+} __attribute__ ((packed));
+
#define V4L2_CHIP_FL_READABLE (1 << 0)
#define V4L2_CHIP_FL_WRITABLE (1 << 1)
@@ -2373,6 +2380,12 @@ struct v4l2_create_buffers {
#define VIDIOC_DBG_S_REGISTER _IOW('V', 79, struct v4l2_dbg_register)
#define VIDIOC_DBG_G_REGISTER _IOWR('V', 80, struct v4l2_dbg_register)
+/* Experimental, meant for debugging, testing and internal use.
+ Never use this ioctl in applications!
+ Note: this ioctl is deprecated in favor of VIDIOC_DBG_G_CHIP_INFO and
+ will go away in the future. */
+#define VIDIOC_DBG_G_CHIP_IDENT _IOWR('V', 81, struct v4l2_dbg_chip_ident)
+
#define VIDIOC_S_HW_FREQ_SEEK _IOW('V', 82, struct v4l2_hw_freq_seek)
#define VIDIOC_S_DV_TIMINGS _IOWR('V', 87, struct v4l2_dv_timings)
#define VIDIOC_G_DV_TIMINGS _IOWR('V', 88, struct v4l2_dv_timings)
diff --git a/include/video/dpu.h b/include/video/dpu.h
new file mode 100644
index 000000000000..ffa3e5a69d14
--- /dev/null
+++ b/include/video/dpu.h
@@ -0,0 +1,847 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017-2019 NXP
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#ifndef __DRM_DPU_H__
+#define __DRM_DPU_H__
+
+#include <drm/drm_crtc.h>
+#include <drm/drm_modes.h>
+#include <video/imx8-prefetch.h>
+#include <video/videomode.h>
+
+struct dpu_soc;
+
+enum dpu_irq {
+ IRQ_STORE9_SHDLOAD = 0,
+ IRQ_STORE9_FRAMECOMPLETE = 1,
+ IRQ_STORE9_SEQCOMPLETE = 2,
+ IRQ_EXTDST0_SHDLOAD = 3,
+ IRQ_EXTDST0_FRAMECOMPLETE = 4,
+ IRQ_EXTDST0_SEQCOMPLETE = 5,
+ IRQ_EXTDST4_SHDLOAD = 6,
+ IRQ_EXTDST4_FRAMECOMPLETE = 7,
+ IRQ_EXTDST4_SEQCOMPLETE = 8,
+ IRQ_EXTDST1_SHDLOAD = 9,
+ IRQ_EXTDST1_FRAMECOMPLETE = 10,
+ IRQ_EXTDST1_SEQCOMPLETE = 11,
+ IRQ_EXTDST5_SHDLOAD = 12,
+ IRQ_EXTDST5_FRAMECOMPLETE = 13,
+ IRQ_EXTDST5_SEQCOMPLETE = 14,
+ IRQ_STORE4_SHDLOAD = 15,
+ IRQ_STORE4_FRAMECOMPLETE = 16,
+ IRQ_STORE4_SEQCOMPLETE = 17,
+ IRQ_STORE5_SHDLOAD = 18,
+ IRQ_STORE5_FRAMECOMPLETE = 19,
+ IRQ_STORE5_SEQCOMPLETE = 20,
+ IRQ_RESERVED21 = 21,
+ IRQ_HISTOGRAM4_VALID = 22,
+ IRQ_RESERVED23 = 23,
+ IRQ_HISTOGRAM5_VALID = 24,
+ IRQ_FRAMEDUMP0_ERROR = 25,
+ IRQ_FRAMEDUMP1_ERROR = 26,
+ IRQ_DISENGCFG_SHDLOAD0 = 27,
+ IRQ_DISENGCFG_FRAMECOMPLETE0 = 28,
+ IRQ_DISENGCFG_SEQCOMPLETE0 = 29,
+ IRQ_FRAMEGEN0_INT0 = 30,
+ IRQ_FRAMEGEN0_INT1 = 31,
+ IRQ_FRAMEGEN0_INT2 = 32,
+ IRQ_FRAMEGEN0_INT3 = 33,
+ IRQ_SIG0_SHDLOAD = 34,
+ IRQ_SIG0_VALID = 35,
+ IRQ_SIG0_ERROR = 36,
+ IRQ_DISENGCFG_SHDLOAD1 = 37,
+ IRQ_DISENGCFG_FRAMECOMPLETE1 = 38,
+ IRQ_DISENGCFG_SEQCOMPLETE1 = 39,
+ IRQ_FRAMEGEN1_INT0 = 40,
+ IRQ_FRAMEGEN1_INT1 = 41,
+ IRQ_FRAMEGEN1_INT2 = 42,
+ IRQ_FRAMEGEN1_INT3 = 43,
+ IRQ_SIG1_SHDLOAD = 44,
+ IRQ_SIG1_VALID = 45,
+ IRQ_SIG1_ERROR = 46,
+ IRQ_ITUIFC4_ERROR = 47,
+ IRQ_ITUIFC5_ERROR = 48,
+ IRQ_RESERVED49 = 49,
+ IRQ_CMDSEQ_ERROR = 50,
+ IRQ_COMCTRL_SW0 = 51,
+ IRQ_COMCTRL_SW1 = 52,
+ IRQ_COMCTRL_SW2 = 53,
+ IRQ_COMCTRL_SW3 = 54,
+ IRQ_FRAMEGEN0_PRIMSYNC_ON = 55,
+ IRQ_FRAMEGEN0_PRIMSYNC_OFF = 56,
+ IRQ_FRAMEGEN0_SECSYNC_ON = 57,
+ IRQ_FRAMEGEN0_SECSYNC_OFF = 58,
+ IRQ_FRAMEGEN1_PRIMSYNC_ON = 59,
+ IRQ_FRAMEGEN1_PRIMSYNC_OFF = 60,
+ IRQ_FRAMEGEN1_SECSYNC_ON = 61,
+ IRQ_FRAMEGEN1_SECSYNC_OFF = 62,
+ IRQ_FRAMECAP4_SYNC_ON = 63,
+ IRQ_FRAMECAP4_SYNC_OFF = 64,
+ IRQ_CMD = 65,
+ IRQ_FRAMECAP5_SYNC_OFF = 66,
+};
+
+typedef enum {
+ ID_NONE = 0x00, /* 0 */
+ /* pixel engines */
+ ID_FETCHDECODE9 = 0x01, /* 1 */
+ ID_FETCHPERSP9 = 0x02, /* 2 */
+ ID_FETCHECO9 = 0x03, /* 3 */
+ ID_ROP9 = 0x04, /* 4 */
+ ID_CLUT9 = 0x05, /* 5 */
+ ID_MATRIX9 = 0x06, /* 6 */
+ ID_HSCALER9 = 0x07, /* 7 */
+ ID_VSCALER9 = 0x08, /* 8 */
+ ID_FILTER9 = 0x09, /* 9 */
+ ID_BLITBLEND9 = 0x0A, /* 10 */
+ ID_STORE9 = 0x0B, /* 11 */
+ ID_CONSTFRAME0 = 0x0C, /* 12 */
+ ID_EXTDST0 = 0x0D, /* 13 */
+ ID_CONSTFRAME4 = 0x0E, /* 14 */
+ ID_EXTDST4 = 0x0F, /* 15 */
+ ID_CONSTFRAME1 = 0x10, /* 16 */
+ ID_EXTDST1 = 0x11, /* 17 */
+ ID_CONSTFRAME5 = 0x12, /* 18 */
+ ID_EXTDST5 = 0x13, /* 19 */
+ ID_EXTSRC4 = 0x14, /* 20 */
+ ID_STORE4 = 0x15, /* 21 */
+ ID_EXTSRC5 = 0x16, /* 22 */
+ ID_STORE5 = 0x17, /* 23 */
+ ID_FETCHDECODE2 = 0x18, /* 24 */
+ ID_FETCHDECODE3 = 0x19, /* 25 */
+ ID_FETCHWARP2 = 0x1A, /* 26 */
+ ID_FETCHECO2 = 0x1B, /* 27 */
+ ID_FETCHDECODE0 = 0x1C, /* 28 */
+ ID_FETCHECO0 = 0x1D, /* 29 */
+ ID_FETCHDECODE1 = 0x1E, /* 30 */
+ ID_FETCHECO1 = 0x1F, /* 31 */
+ ID_FETCHLAYER0 = 0x20, /* 32 */
+ ID_FETCHLAYER1 = 0x21, /* 33 */
+ ID_GAMMACOR4 = 0x22, /* 34 */
+ ID_MATRIX4 = 0x23, /* 35 */
+ ID_HSCALER4 = 0x24, /* 36 */
+ ID_VSCALER4 = 0x25, /* 37 */
+ ID_HISTOGRAM4 = 0x26, /* 38 */
+ ID_GAMMACOR5 = 0x27, /* 39 */
+ ID_MATRIX5 = 0x28, /* 40 */
+ ID_HSCALER5 = 0x29, /* 41 */
+ ID_VSCALER5 = 0x2A, /* 42 */
+ ID_HISTOGRAM5 = 0x2B, /* 43 */
+ ID_LAYERBLEND0 = 0x2C, /* 44 */
+ ID_LAYERBLEND1 = 0x2D, /* 45 */
+ ID_LAYERBLEND2 = 0x2E, /* 46 */
+ ID_LAYERBLEND3 = 0x2F, /* 47 */
+ ID_LAYERBLEND4 = 0x30, /* 48 */
+ ID_LAYERBLEND5 = 0x31, /* 49 */
+ ID_LAYERBLEND6 = 0x32, /* 50 */
+ ID_EXTSRC0 = 0x33, /* 51 */
+ ID_EXTSRC1 = 0x34, /* 52 */
+ /* display engines */
+ ID_DISENGCFG = 0x35, /* 53 */
+ ID_FRAMEGEN0 = 0x36, /* 54 */
+ ID_MATRIX0 = 0x37, /* 55 */
+ ID_GAMMACOR0 = 0x38, /* 56 */
+ ID_DITHER0 = 0x39, /* 57 */
+ ID_TCON0 = 0x3A, /* 58 */
+ ID_SIG0 = 0x3B, /* 59 */
+ ID_FRAMEGEN1 = 0x3C, /* 60 */
+ ID_MATRIX1 = 0x3D, /* 61 */
+ ID_GAMMACOR1 = 0x3E, /* 62 */
+ ID_DITHER1 = 0x3F, /* 63 */
+ ID_TCON1 = 0x40, /* 64 */
+ ID_SIG1 = 0x41, /* 65 */
+ ID_FRAMECAP4 = 0x42, /* 66 */
+ ID_FRAMECAP5 = 0x43, /* 67 */
+} dpu_block_id_t;
+
+typedef enum {
+ ED_SRC_DISABLE = ID_NONE,
+ ED_SRC_BLITBLEND9 = ID_BLITBLEND9,
+ ED_SRC_CONSTFRAME0 = ID_CONSTFRAME0,
+ ED_SRC_CONSTFRAME1 = ID_CONSTFRAME1,
+ ED_SRC_CONSTFRAME4 = ID_CONSTFRAME4,
+ ED_SRC_CONSTFRAME5 = ID_CONSTFRAME5,
+ ED_SRC_MATRIX4 = ID_MATRIX4,
+ ED_SRC_HSCALER4 = ID_HSCALER4,
+ ED_SRC_VSCALER4 = ID_VSCALER4,
+ /* content stream(extdst 0/1) only */
+ ED_SRC_EXTSRC4 = ID_EXTSRC4,
+ ED_SRC_MATRIX5 = ID_MATRIX5,
+ ED_SRC_HSCALER5 = ID_HSCALER5,
+ ED_SRC_VSCALER5 = ID_VSCALER5,
+ /* content stream(extdst 0/1) only */
+ ED_SRC_EXTSRC5 = ID_EXTSRC5,
+ ED_SRC_LAYERBLEND6 = ID_LAYERBLEND6,
+ ED_SRC_LAYERBLEND5 = ID_LAYERBLEND5,
+ ED_SRC_LAYERBLEND4 = ID_LAYERBLEND4,
+ ED_SRC_LAYERBLEND3 = ID_LAYERBLEND3,
+ ED_SRC_LAYERBLEND2 = ID_LAYERBLEND2,
+ ED_SRC_LAYERBLEND1 = ID_LAYERBLEND1,
+ ED_SRC_LAYERBLEND0 = ID_LAYERBLEND0,
+} extdst_src_sel_t;
+
+typedef enum {
+ SINGLE, /* Reconfig pipeline after explicit trigger */
+ AUTO, /* Reconfig pipeline after every kick when idle */
+} ed_sync_mode_t;
+
+typedef enum {
+ PSTATUS_EMPTY,
+ PSTATUS_RUNNING,
+ PSTATUS_RUNNING_RETRIGGERED,
+ PSTATUS_RESERVED
+} ed_pipeline_status_t;
+
+typedef enum {
+ SOFTWARE = 0, /* kick generation by KICK field only */
+ EXTERNAL = BIT(8), /* kick signal from external allowed */
+} ed_kick_mode_t;
+
+typedef enum {
+ SHLDREQID_FETCHDECODE9 = BIT(1),
+ SHLDREQID_FETCHPERSP9 = BIT(2),
+ SHLDREQID_FETCHECO9 = BIT(3),
+ SHLDREQID_CONSTFRAME0 = BIT(4),
+ SHLDREQID_CONSTFRAME4 = BIT(5),
+ SHLDREQID_CONSTFRAME1 = BIT(6),
+ SHLDREQID_CONSTFRAME5 = BIT(7),
+ SHLDREQID_EXTSRC4 = BIT(8),
+ SHLDREQID_EXTSRC5 = BIT(9),
+ SHLDREQID_FETCHDECODE2 = BIT(10),
+ SHLDREQID_FETCHDECODE3 = BIT(11),
+ SHLDREQID_FETCHWARP2 = BIT(12),
+ SHLDREQID_FETCHECO2 = BIT(13),
+ SHLDREQID_FETCHDECODE0 = BIT(14),
+ SHLDREQID_FETCHECO0 = BIT(15),
+ SHLDREQID_FETCHDECODE1 = BIT(16),
+ SHLDREQID_FETCHECO1 = BIT(17),
+ SHLDREQID_FETCHLAYER0 = BIT(18),
+ SHLDREQID_FETCHLAYER1 = BIT(19),
+ SHLDREQID_EXTSRC0 = BIT(20),
+ SHLDREQID_EXTSRC1 = BIT(21),
+} shadow_load_req_t;
+
+typedef enum {
+ PIXENGCFG_STATUS_SEL_DISABLE,
+ PIXENGCFG_STATUS_SEL_STORE9,
+ PIXENGCFG_STATUS_SEL_EXTDST0,
+ PIXENGCFG_STATUS_SEL_EXTDST4,
+ PIXENGCFG_STATUS_SEL_EXTDST1,
+ PIXENGCFG_STATUS_SEL_EXTDST5,
+ PIXENGCFG_STATUS_SEL_STORE4,
+ PIXENGCFG_STATUS_SEL_STORE5,
+} pixengcfg_status_sel_t;
+
+typedef enum {
+ FD_SRC_DISABLE = ID_NONE,
+ FD_SRC_FETCHECO0 = ID_FETCHECO0,
+ FD_SRC_FETCHECO1 = ID_FETCHECO1,
+ FD_SRC_FETCHECO2 = ID_FETCHECO2,
+ FD_SRC_FETCHDECODE0 = ID_FETCHDECODE0,
+ FD_SRC_FETCHDECODE1 = ID_FETCHDECODE1,
+ FD_SRC_FETCHDECODE2 = ID_FETCHDECODE2,
+ FD_SRC_FETCHDECODE3 = ID_FETCHDECODE3,
+ FD_SRC_FETCHWARP2 = ID_FETCHWARP2,
+} fd_dynamic_src_sel_t;
+
+typedef enum {
+ /* RL and RLAD decoder */
+ FETCHTYPE__DECODE,
+ /* fractional plane(8 layers) */
+ FETCHTYPE__LAYER,
+ /* arbitrary warping and fractional plane(8 layers) */
+ FETCHTYPE__WARP,
+ /* minimum feature set for alpha, chroma and coordinate planes */
+ FETCHTYPE__ECO,
+ /* affine, perspective and arbitrary warping */
+ FETCHTYPE__PERSP,
+ /* affine and arbitrary warping */
+ FETCHTYPE__ROT,
+ /* RL and RLAD decoder, reduced feature set */
+ FETCHTYPE__DECODEL,
+ /* fractional plane(8 layers), reduced feature set */
+ FETCHTYPE__LAYERL,
+ /* affine and arbitrary warping, reduced feature set */
+ FETCHTYPE__ROTL,
+} fetchtype_t;
+
+typedef enum {
+ /* No side-by-side synchronization. */
+ FGSYNCMODE__OFF = 0,
+ /* Framegen is master. */
+ FGSYNCMODE__MASTER = 1 << 1,
+ /* Runs in cyclic synchronization mode. */
+ FGSYNCMODE__SLAVE_CYC = 2 << 1,
+ /* Runs in one time synchronization mode. */
+ FGSYNCMODE__SLAVE_ONCE = 3 << 1,
+} fgsyncmode_t;
+
+typedef enum {
+ FGDM__BLACK,
+ /* Constant Color Background is shown. */
+ FGDM__CONSTCOL,
+ FGDM__PRIM,
+ FGDM__SEC,
+ FGDM__PRIM_ON_TOP,
+ FGDM__SEC_ON_TOP,
+ /* White color background with test pattern is shown. */
+ FGDM__TEST,
+} fgdm_t;
+
+typedef enum {
+ HS_SRC_SEL__DISABLE = ID_NONE,
+ HS_SRC_SEL__MATRIX9 = ID_MATRIX9,
+ HS_SRC_SEL__VSCALER9 = ID_VSCALER9,
+ HS_SRC_SEL__FILTER9 = ID_FILTER9,
+ HS_SRC_SEL__EXTSRC4 = ID_EXTSRC4,
+ HS_SRC_SEL__EXTSRC5 = ID_EXTSRC5,
+ HS_SRC_SEL__FETCHDECODE2 = ID_FETCHDECODE2,
+ HS_SRC_SEL__FETCHDECODE3 = ID_FETCHDECODE3,
+ HS_SRC_SEL__FETCHDECODE0 = ID_FETCHDECODE0,
+ HS_SRC_SEL__FETCHDECODE1 = ID_FETCHDECODE1,
+ HS_SRC_SEL__MATRIX4 = ID_MATRIX4,
+ HS_SRC_SEL__VSCALER4 = ID_VSCALER4,
+ HS_SRC_SEL__MATRIX5 = ID_MATRIX5,
+ HS_SRC_SEL__VSCALER5 = ID_VSCALER5,
+} hs_src_sel_t;
+
+typedef enum {
+ /* common options */
+ LB_PRIM_SEL__DISABLE = ID_NONE,
+ LB_PRIM_SEL__BLITBLEND9 = ID_BLITBLEND9,
+ LB_PRIM_SEL__CONSTFRAME0 = ID_CONSTFRAME0,
+ LB_PRIM_SEL__CONSTFRAME1 = ID_CONSTFRAME1,
+ LB_PRIM_SEL__CONSTFRAME4 = ID_CONSTFRAME4,
+ LB_PRIM_SEL__CONSTFRAME5 = ID_CONSTFRAME5,
+ LB_PRIM_SEL__MATRIX4 = ID_MATRIX4,
+ LB_PRIM_SEL__HSCALER4 = ID_HSCALER4,
+ LB_PRIM_SEL__VSCALER4 = ID_VSCALER4,
+ LB_PRIM_SEL__EXTSRC4 = ID_EXTSRC4,
+ LB_PRIM_SEL__MATRIX5 = ID_MATRIX5,
+ LB_PRIM_SEL__HSCALER5 = ID_HSCALER5,
+ LB_PRIM_SEL__VSCALER5 = ID_VSCALER5,
+ LB_PRIM_SEL__EXTSRC5 = ID_EXTSRC5,
+ /*
+ * special options:
+ * layerblend(n) has n special options,
+ * from layerblend0 to layerblend(n - 1), e.g.,
+ * layerblend4 has 4 special options -
+ * layerblend0/1/2/3.
+ */
+ LB_PRIM_SEL__LAYERBLEND5 = ID_LAYERBLEND5,
+ LB_PRIM_SEL__LAYERBLEND4 = ID_LAYERBLEND4,
+ LB_PRIM_SEL__LAYERBLEND3 = ID_LAYERBLEND3,
+ LB_PRIM_SEL__LAYERBLEND2 = ID_LAYERBLEND2,
+ LB_PRIM_SEL__LAYERBLEND1 = ID_LAYERBLEND1,
+ LB_PRIM_SEL__LAYERBLEND0 = ID_LAYERBLEND0,
+} lb_prim_sel_t;
+
+typedef enum {
+ LB_SEC_SEL__DISABLE = ID_NONE,
+ LB_SEC_SEL__FETCHDECODE2 = ID_FETCHDECODE2,
+ LB_SEC_SEL__FETCHDECODE3 = ID_FETCHDECODE3,
+ LB_SEC_SEL__FETCHWARP2 = ID_FETCHWARP2,
+ LB_SEC_SEL__FETCHDECODE0 = ID_FETCHDECODE0,
+ LB_SEC_SEL__FETCHDECODE1 = ID_FETCHDECODE1,
+ LB_SEC_SEL__MATRIX4 = ID_MATRIX4,
+ LB_SEC_SEL__HSCALER4 = ID_HSCALER4,
+ LB_SEC_SEL__VSCALER4 = ID_VSCALER4,
+ LB_SEC_SEL__MATRIX5 = ID_MATRIX5,
+ LB_SEC_SEL__HSCALER5 = ID_HSCALER5,
+ LB_SEC_SEL__VSCALER5 = ID_VSCALER5,
+ LB_SEC_SEL__FETCHLAYER0 = ID_FETCHLAYER0,
+ LB_SEC_SEL__FETCHLAYER1 = ID_FETCHLAYER1,
+} lb_sec_sel_t;
+
+typedef enum {
+ PRIMARY, /* background plane */
+ SECONDARY, /* foreground plane */
+ BOTH,
+} lb_shadow_sel_t;
+
+typedef enum {
+ LB_NEUTRAL, /* Output is same as primary input. */
+ LB_BLEND,
+} lb_mode_t;
+
+typedef enum {
+ /* Constant 0 indicates frame or top field. */
+ SCALER_ALWAYS0 = 0x0,
+ /* Constant 1 indicates bottom field. */
+ SCALER_ALWAYS1 = 0x1 << 12,
+ /* Output field polarity is taken from input field polarity. */
+ SCALER_INPUT = 0x2 << 12,
+ /* Output field polarity toggles, starting with 0 after reset. */
+ SCALER_TOGGLE = 0x3 << 12,
+} scaler_field_mode_t;
+
+typedef enum {
+ /* pointer-sampling */
+ SCALER_NEAREST = 0x0,
+ /* box filter */
+ SCALER_LINEAR = 0x100,
+} scaler_filter_mode_t;
+
+typedef enum {
+ SCALER_DOWNSCALE = 0x0,
+ SCALER_UPSCALE = 0x10,
+} scaler_scale_mode_t;
+
+typedef enum {
+ /* Pixel by-pass the scaler, all other settings are ignored. */
+ SCALER_NEUTRAL = 0x0,
+ /* Scaler is active. */
+ SCALER_ACTIVE = 0x1,
+} scaler_mode_t;
+
+typedef enum {
+ VS_SRC_SEL__DISABLE = ID_NONE,
+ VS_SRC_SEL__MATRIX9 = ID_MATRIX9,
+ VS_SRC_SEL__HSCALER9 = ID_HSCALER9,
+ VS_SRC_SEL__EXTSRC4 = ID_EXTSRC4,
+ VS_SRC_SEL__EXTSRC5 = ID_EXTSRC5,
+ VS_SRC_SEL__FETCHDECODE2 = ID_FETCHDECODE2,
+ VS_SRC_SEL__FETCHDECODE3 = ID_FETCHDECODE3,
+ VS_SRC_SEL__FETCHDECODE0 = ID_FETCHDECODE0,
+ VS_SRC_SEL__FETCHDECODE1 = ID_FETCHDECODE1,
+ VS_SRC_SEL__MATRIX4 = ID_MATRIX4,
+ VS_SRC_SEL__HSCALER4 = ID_HSCALER4,
+ VS_SRC_SEL__MATRIX5 = ID_MATRIX5,
+ VS_SRC_SEL__HSCALER5 = ID_HSCALER5,
+} vs_src_sel_t;
+
+#define CLKEN_MASK (0x3 << 24)
+#define CLKEN_MASK_SHIFT 24
+typedef enum {
+ CLKEN__DISABLE = 0x0,
+ CLKEN__AUTOMATIC = 0x1,
+ CLKEN__FULL = 0x3,
+} pixengcfg_clken_t;
+
+/* fetch unit types */
+enum {
+ FU_T_NA,
+ FU_T_FD,
+ FU_T_FE,
+ FU_T_FL,
+ FU_T_FW,
+};
+
+struct dpu_fetchunit;
+
+struct dpu_fetchunit_ops {
+ void (*set_burstlength)(struct dpu_fetchunit *fu,
+ unsigned int x_offset, unsigned int mt_w,
+ int bpp, dma_addr_t baddr, bool use_prefetch);
+
+ void (*set_baseaddress)(struct dpu_fetchunit *fu, unsigned int width,
+ unsigned int x_offset, unsigned int y_offset,
+ unsigned int mt_w, unsigned int mt_h,
+ int bpp, dma_addr_t baddr);
+
+ void (*set_src_bpp)(struct dpu_fetchunit *fu, int bpp);
+
+ void (*set_src_stride)(struct dpu_fetchunit *fu,
+ unsigned int width, unsigned int x_offset,
+ unsigned int mt_w, int bpp, unsigned int stride,
+ dma_addr_t baddr, bool use_prefetch);
+
+ void (*set_src_buf_dimensions)(struct dpu_fetchunit *fu,
+ unsigned int w, unsigned int h, u32 fmt,
+ bool deinterlace);
+
+ void (*set_fmt)(struct dpu_fetchunit *fu, u32 fmt, bool deinterlace);
+
+ void (*enable_src_buf)(struct dpu_fetchunit *fu);
+ void (*disable_src_buf)(struct dpu_fetchunit *fu);
+ bool (*is_enabled)(struct dpu_fetchunit *fu);
+
+ void (*set_framedimensions)(struct dpu_fetchunit *fu,
+ unsigned int w, unsigned int h,
+ bool deinterlace);
+
+ void (*set_controltrigger)(struct dpu_fetchunit *fu);
+
+ unsigned int (*get_stream_id)(struct dpu_fetchunit *fu);
+ void (*set_stream_id)(struct dpu_fetchunit *fu, unsigned int id);
+
+ void (*pin_off)(struct dpu_fetchunit *fu);
+ void (*unpin_off)(struct dpu_fetchunit *fu);
+ bool (*is_pinned_off)(struct dpu_fetchunit *fu);
+};
+
+struct dpu_fetchunit {
+ void __iomem *pec_base;
+ void __iomem *base;
+ char *name;
+ struct mutex mutex;
+ int id;
+ int sub_id; /* for fractional fetch units */
+ int type;
+ bool inuse;
+ struct dpu_soc *dpu;
+ /* see DPU_PLANE_SRC_xxx */
+ unsigned int stream_id;
+ bool pin_off;
+ struct dprc *dprc;
+ const struct dpu_fetchunit_ops *ops;
+};
+
+int dpu_map_inner_irq(struct dpu_soc *dpu, int irq);
+
+/* Constant Frame Unit */
+struct dpu_constframe;
+void constframe_shden(struct dpu_constframe *cf, bool enable);
+void constframe_framedimensions(struct dpu_constframe *cf, unsigned int w,
+ unsigned int h);
+void constframe_framedimensions_copy_prim(struct dpu_constframe *cf);
+void constframe_constantcolor(struct dpu_constframe *cf, unsigned int r,
+ unsigned int g, unsigned int b, unsigned int a);
+void constframe_controltrigger(struct dpu_constframe *cf, bool trigger);
+shadow_load_req_t constframe_to_shdldreq_t(struct dpu_constframe *cf);
+struct dpu_constframe *dpu_cf_get(struct dpu_soc *dpu, int id);
+void dpu_cf_put(struct dpu_constframe *cf);
+struct dpu_constframe *dpu_aux_cf_peek(struct dpu_constframe *cf);
+
+/* Display Engine Configuration Unit */
+struct dpu_disengcfg;
+void disengcfg_polarity_ctrl(struct dpu_disengcfg *dec, unsigned int flags);
+struct dpu_disengcfg *dpu_dec_get(struct dpu_soc *dpu, int id);
+void dpu_dec_put(struct dpu_disengcfg *dec);
+struct dpu_disengcfg *dpu_aux_dec_peek(struct dpu_disengcfg *dec);
+
+/* External Destination Unit */
+struct dpu_extdst;
+void extdst_pixengcfg_shden(struct dpu_extdst *ed, bool enable);
+void extdst_pixengcfg_powerdown(struct dpu_extdst *ed, bool powerdown);
+void extdst_pixengcfg_sync_mode(struct dpu_extdst *ed, ed_sync_mode_t mode);
+void extdst_pixengcfg_reset(struct dpu_extdst *ed, bool reset);
+void extdst_pixengcfg_div(struct dpu_extdst *ed, u16 div);
+void extdst_pixengcfg_syncmode_master(struct dpu_extdst *ed, bool enable);
+int extdst_pixengcfg_src_sel(struct dpu_extdst *ed, extdst_src_sel_t src);
+void extdst_pixengcfg_sel_shdldreq(struct dpu_extdst *ed);
+void extdst_pixengcfg_shdldreq(struct dpu_extdst *ed, u32 req_mask);
+void extdst_pixengcfg_sync_trigger(struct dpu_extdst *ed);
+void extdst_pixengcfg_trigger_sequence_complete(struct dpu_extdst *ed);
+bool extdst_pixengcfg_is_sync_busy(struct dpu_extdst *ed);
+ed_pipeline_status_t extdst_pixengcfg_pipeline_status(struct dpu_extdst *ed);
+void extdst_shden(struct dpu_extdst *ed, bool enable);
+void extdst_kick_mode(struct dpu_extdst *ed, ed_kick_mode_t mode);
+void extdst_perfcountmode(struct dpu_extdst *ed, bool enable);
+void extdst_gamma_apply_enable(struct dpu_extdst *ed, bool enable);
+void extdst_kick(struct dpu_extdst *ed);
+void extdst_cnt_err_clear(struct dpu_extdst *ed);
+bool extdst_cnt_err_status(struct dpu_extdst *ed);
+u32 extdst_last_control_word(struct dpu_extdst *ed);
+void extdst_pixel_cnt(struct dpu_extdst *ed, u16 *x, u16 *y);
+void extdst_last_pixel_cnt(struct dpu_extdst *ed, u16 *x, u16 *y);
+u32 extdst_perfresult(struct dpu_extdst *ed);
+bool extdst_is_master(struct dpu_extdst *ed);
+struct dpu_extdst *dpu_ed_get(struct dpu_soc *dpu, int id);
+void dpu_ed_put(struct dpu_extdst *ed);
+struct dpu_extdst *dpu_aux_ed_peek(struct dpu_extdst *ed);
+
+/* Fetch Decode Unit */
+int fetchdecode_pixengcfg_dynamic_src_sel(struct dpu_fetchunit *fu,
+ fd_dynamic_src_sel_t src);
+void fetchdecode_layeroffset(struct dpu_fetchunit *fd, unsigned int x,
+ unsigned int y);
+void fetchdecode_clipoffset(struct dpu_fetchunit *fd, unsigned int x,
+ unsigned int y);
+void fetchdecode_clipdimensions(struct dpu_fetchunit *fd, unsigned int w,
+ unsigned int h);
+void fetchdecode_rgb_constantcolor(struct dpu_fetchunit *fd,
+ u8 r, u8 g, u8 b, u8 a);
+void fetchdecode_yuv_constantcolor(struct dpu_fetchunit *fd,
+ u8 y, u8 u, u8 v);
+int fetchdecode_fetchtype(struct dpu_fetchunit *fd, fetchtype_t *type);
+shadow_load_req_t fetchdecode_to_shdldreq_t(struct dpu_fetchunit *fd);
+u32 fetchdecode_get_vproc_mask(struct dpu_fetchunit *fd);
+bool fetchdecode_need_fetcheco(struct dpu_fetchunit *fd, u32 fmt);
+struct dpu_fetchunit *dpu_fd_get(struct dpu_soc *dpu, int id);
+void dpu_fd_put(struct dpu_fetchunit *fu);
+
+/* Fetch ECO Unit */
+void fetcheco_layeroffset(struct dpu_fetchunit *fu, unsigned int x,
+ unsigned int y);
+void fetcheco_clipoffset(struct dpu_fetchunit *fu, unsigned int x,
+ unsigned int y);
+void fetcheco_clipdimensions(struct dpu_fetchunit *fu, unsigned int w,
+ unsigned int h);
+void fetcheco_frameresampling(struct dpu_fetchunit *fu, unsigned int x,
+ unsigned int y);
+int fetcheco_fetchtype(struct dpu_fetchunit *fu, fetchtype_t *type);
+dpu_block_id_t fetcheco_get_block_id(struct dpu_fetchunit *fu);
+struct dpu_fetchunit *dpu_fe_get(struct dpu_soc *dpu, int id);
+void dpu_fe_put(struct dpu_fetchunit *fu);
+
+/* Fetch Layer Unit */
+void fetchlayer_rgb_constantcolor(struct dpu_fetchunit *fu,
+ u8 r, u8 g, u8 b, u8 a);
+void fetchlayer_yuv_constantcolor(struct dpu_fetchunit *fu, u8 y, u8 u, u8 v);
+int fetchlayer_fetchtype(struct dpu_fetchunit *fu, fetchtype_t *type);
+struct dpu_fetchunit *dpu_fl_get(struct dpu_soc *dpu, int id);
+void dpu_fl_put(struct dpu_fetchunit *fu);
+
+/* Fetch Warp Unit */
+void fetchwarp_rgb_constantcolor(struct dpu_fetchunit *fu,
+ u8 r, u8 g, u8 b, u8 a);
+void fetchwarp_yuv_constantcolor(struct dpu_fetchunit *fu, u8 y, u8 u, u8 v);
+int fetchwarp_fetchtype(struct dpu_fetchunit *fu, fetchtype_t *type);
+struct dpu_fetchunit *dpu_fw_get(struct dpu_soc *dpu, int id);
+void dpu_fw_put(struct dpu_fetchunit *fu);
+
+/* Frame Generator Unit */
+struct dpu_framegen;
+void framegen_enable(struct dpu_framegen *fg);
+void framegen_disable(struct dpu_framegen *fg);
+void framegen_shdtokgen(struct dpu_framegen *fg);
+void framegen_syncmode(struct dpu_framegen *fg, fgsyncmode_t mode);
+void
+framegen_cfg_videomode(struct dpu_framegen *fg,
+ struct drm_display_mode *m, bool side_by_side,
+ bool encoder_type_has_tmds, bool encoder_type_has_lvds);
+void framegen_pkickconfig(struct dpu_framegen *fg, bool enable);
+void framegen_syncmode_fixup(struct dpu_framegen *fg, bool enable);
+void framegen_sacfg(struct dpu_framegen *fg, unsigned int x, unsigned int y);
+void framegen_displaymode(struct dpu_framegen *fg, fgdm_t mode);
+void framegen_panic_displaymode(struct dpu_framegen *fg, fgdm_t mode);
+void framegen_wait_done(struct dpu_framegen *fg, struct drm_display_mode *m);
+void framegen_read_timestamp(struct dpu_framegen *fg,
+ u32 *frame_index, u32 *line_index);
+void framegen_wait_for_frame_counter_moving(struct dpu_framegen *fg);
+bool framegen_secondary_requests_to_read_empty_fifo(struct dpu_framegen *fg);
+void framegen_secondary_clear_channel_status(struct dpu_framegen *fg);
+bool framegen_secondary_is_syncup(struct dpu_framegen *fg);
+void framegen_wait_for_secondary_syncup(struct dpu_framegen *fg);
+void framegen_enable_clock(struct dpu_framegen *fg);
+void framegen_disable_clock(struct dpu_framegen *fg);
+bool framegen_is_master(struct dpu_framegen *fg);
+bool framegen_is_slave(struct dpu_framegen *fg);
+struct dpu_framegen *dpu_fg_get(struct dpu_soc *dpu, int id);
+void dpu_fg_put(struct dpu_framegen *fg);
+struct dpu_framegen *dpu_aux_fg_peek(struct dpu_framegen *fg);
+
+/* Horizontal Scaler Unit */
+struct dpu_hscaler;
+int hscaler_pixengcfg_dynamic_src_sel(struct dpu_hscaler *hs, hs_src_sel_t src);
+void hscaler_pixengcfg_clken(struct dpu_hscaler *hs, pixengcfg_clken_t clken);
+void hscaler_shden(struct dpu_hscaler *hs, bool enable);
+void hscaler_setup1(struct dpu_hscaler *hs, unsigned int src, unsigned int dst);
+void hscaler_setup2(struct dpu_hscaler *hs, u32 phase_offset);
+void hscaler_output_size(struct dpu_hscaler *hs, u32 line_num);
+void hscaler_filter_mode(struct dpu_hscaler *hs, scaler_filter_mode_t m);
+void hscaler_scale_mode(struct dpu_hscaler *hs, scaler_scale_mode_t m);
+void hscaler_mode(struct dpu_hscaler *hs, scaler_mode_t m);
+bool hscaler_is_enabled(struct dpu_hscaler *hs);
+dpu_block_id_t hscaler_get_block_id(struct dpu_hscaler *hs);
+unsigned int hscaler_get_stream_id(struct dpu_hscaler *hs);
+void hscaler_set_stream_id(struct dpu_hscaler *hs, unsigned int id);
+struct dpu_hscaler *dpu_hs_get(struct dpu_soc *dpu, int id);
+void dpu_hs_put(struct dpu_hscaler *hs);
+
+/* Layer Blend Unit */
+struct dpu_layerblend;
+int layerblend_pixengcfg_dynamic_prim_sel(struct dpu_layerblend *lb,
+ lb_prim_sel_t prim);
+void layerblend_pixengcfg_dynamic_sec_sel(struct dpu_layerblend *lb,
+ lb_sec_sel_t sec);
+void layerblend_pixengcfg_clken(struct dpu_layerblend *lb,
+ pixengcfg_clken_t clken);
+void layerblend_shden(struct dpu_layerblend *lb, bool enable);
+void layerblend_shdtoksel(struct dpu_layerblend *lb, lb_shadow_sel_t sel);
+void layerblend_shdldsel(struct dpu_layerblend *lb, lb_shadow_sel_t sel);
+void layerblend_control(struct dpu_layerblend *lb, lb_mode_t mode);
+void layerblend_blendcontrol(struct dpu_layerblend *lb, bool sec_from_scaler);
+void layerblend_position(struct dpu_layerblend *lb, int x, int y);
+struct dpu_layerblend *dpu_lb_get(struct dpu_soc *dpu, int id);
+void dpu_lb_put(struct dpu_layerblend *lb);
+
+/* Store Unit */
+struct dpu_store;
+void store_pixengcfg_syncmode_fixup(struct dpu_store *st, bool enable);
+struct dpu_store *dpu_st_get(struct dpu_soc *dpu, int id);
+void dpu_st_put(struct dpu_store *st);
+
+/* Timing Controller Unit */
+struct dpu_tcon;
+int tcon_set_fmt(struct dpu_tcon *tcon, u32 bus_format);
+void tcon_set_operation_mode(struct dpu_tcon *tcon);
+void tcon_cfg_videomode(struct dpu_tcon *tcon,
+ struct drm_display_mode *m, bool side_by_side);
+bool tcon_is_master(struct dpu_tcon *tcon);
+bool tcon_is_slave(struct dpu_tcon *tcon);
+void tcon_configure_pc(struct dpu_tcon *tcon, unsigned int di,
+ unsigned int frame_width, u32 mode, u32 format);
+void tcon_enable_pc(struct dpu_tcon *tcon);
+void tcon_disable_pc(struct dpu_tcon *tcon);
+struct dpu_tcon *dpu_tcon_get(struct dpu_soc *dpu, int id);
+void dpu_tcon_put(struct dpu_tcon *tcon);
+struct dpu_tcon *dpu_aux_tcon_peek(struct dpu_tcon *tcon);
+
+/* Vertical Scaler Unit */
+struct dpu_vscaler;
+int vscaler_pixengcfg_dynamic_src_sel(struct dpu_vscaler *vs, vs_src_sel_t src);
+void vscaler_pixengcfg_clken(struct dpu_vscaler *vs, pixengcfg_clken_t clken);
+void vscaler_shden(struct dpu_vscaler *vs, bool enable);
+void vscaler_setup1(struct dpu_vscaler *vs, u32 src, u32 dst, bool deinterlace);
+void vscaler_setup2(struct dpu_vscaler *vs, bool deinterlace);
+void vscaler_setup3(struct dpu_vscaler *vs, bool deinterlace);
+void vscaler_setup4(struct dpu_vscaler *vs, u32 phase_offset);
+void vscaler_setup5(struct dpu_vscaler *vs, u32 phase_offset);
+void vscaler_output_size(struct dpu_vscaler *vs, u32 line_num);
+void vscaler_field_mode(struct dpu_vscaler *vs, scaler_field_mode_t m);
+void vscaler_filter_mode(struct dpu_vscaler *vs, scaler_filter_mode_t m);
+void vscaler_scale_mode(struct dpu_vscaler *vs, scaler_scale_mode_t m);
+void vscaler_mode(struct dpu_vscaler *vs, scaler_mode_t m);
+bool vscaler_is_enabled(struct dpu_vscaler *vs);
+dpu_block_id_t vscaler_get_block_id(struct dpu_vscaler *vs);
+unsigned int vscaler_get_stream_id(struct dpu_vscaler *vs);
+void vscaler_set_stream_id(struct dpu_vscaler *vs, unsigned int id);
+struct dpu_vscaler *dpu_vs_get(struct dpu_soc *dpu, int id);
+void dpu_vs_put(struct dpu_vscaler *vs);
+
+struct dpu_fetchunit *fetchdecode_get_fetcheco(struct dpu_fetchunit *fu);
+struct dpu_hscaler *fetchdecode_get_hscaler(struct dpu_fetchunit *fu);
+struct dpu_vscaler *fetchdecode_get_vscaler(struct dpu_fetchunit *fu);
+
+bool dpu_has_pc(struct dpu_soc *dpu);
+unsigned int dpu_get_syncmode_min_prate(struct dpu_soc *dpu);
+unsigned int dpu_get_singlemode_max_width(struct dpu_soc *dpu);
+unsigned int dpu_get_master_stream_id(struct dpu_soc *dpu);
+
+bool dpu_vproc_has_fetcheco_cap(u32 cap_mask);
+bool dpu_vproc_has_hscale_cap(u32 cap_mask);
+bool dpu_vproc_has_vscale_cap(u32 cap_mask);
+
+u32 dpu_vproc_get_fetcheco_cap(u32 cap_mask);
+u32 dpu_vproc_get_hscale_cap(u32 cap_mask);
+u32 dpu_vproc_get_vscale_cap(u32 cap_mask);
+
+void fetchunit_get_dprc(struct dpu_fetchunit *fu, void *data);
+void fetchunit_shden(struct dpu_fetchunit *fu, bool enable);
+void fetchunit_baddr_autoupdate(struct dpu_fetchunit *fu, u8 layer_mask);
+void fetchunit_shdldreq_sticky(struct dpu_fetchunit *fu, u8 layer_mask);
+void fetchunit_set_burstlength(struct dpu_fetchunit *fu,
+ unsigned int x_offset, unsigned int mt_w,
+ int bpp, dma_addr_t baddr, bool use_prefetch);
+void fetchunit_set_baseaddress(struct dpu_fetchunit *fu, unsigned int width,
+ unsigned int x_offset, unsigned int y_offset,
+ unsigned int mt_w, unsigned int mt_h,
+ int bpp, dma_addr_t baddr);
+void fetchunit_set_src_bpp(struct dpu_fetchunit *fu, int bpp);
+void fetchunit_set_src_stride(struct dpu_fetchunit *fu,
+ unsigned int width, unsigned int x_offset,
+ unsigned int mt_w, int bpp, unsigned int stride,
+ dma_addr_t baddr, bool use_prefetch);
+void fetchunit_enable_src_buf(struct dpu_fetchunit *fu);
+void fetchunit_disable_src_buf(struct dpu_fetchunit *fu);
+bool fetchunit_is_enabled(struct dpu_fetchunit *fu);
+unsigned int fetchunit_get_stream_id(struct dpu_fetchunit *fu);
+void fetchunit_set_stream_id(struct dpu_fetchunit *fu, unsigned int id);
+void fetchunit_pin_off(struct dpu_fetchunit *fu);
+void fetchunit_unpin_off(struct dpu_fetchunit *fu);
+bool fetchunit_is_pinned_off(struct dpu_fetchunit *fu);
+bool fetchunit_is_fetchdecode(struct dpu_fetchunit *fu);
+bool fetchunit_is_fetcheco(struct dpu_fetchunit *fu);
+bool fetchunit_is_fetchlayer(struct dpu_fetchunit *fu);
+bool fetchunit_is_fetchwarp(struct dpu_fetchunit *fu);
+
+/* dpu blit engine */
+struct dpu_bliteng;
+int dpu_bliteng_init(struct dpu_bliteng *dpu_bliteng);
+void dpu_bliteng_fini(struct dpu_bliteng *dpu_bliteng);
+int dpu_be_get(struct dpu_bliteng *dpu_be);
+void dpu_be_put(struct dpu_bliteng *dpu_be);
+void dpu_be_wait(struct dpu_bliteng *dpu_be);
+int dpu_be_blit(struct dpu_bliteng *dpu_be, u32 *cmdlist,
+ u32 cmdnum);
+int dpu_bliteng_get_empty_instance(struct dpu_bliteng **dpu_be,
+ struct device *dev);
+u32 *dpu_bliteng_get_cmd_list(struct dpu_bliteng *dpu_be);
+s32 dpu_bliteng_get_id(struct dpu_bliteng *dpu_be);
+void dpu_bliteng_set_id(struct dpu_bliteng *dpu_be, int id);
+void dpu_bliteng_set_dev(struct dpu_bliteng *dpu_be, struct device *dev);
+
+void dpu_be_configure_prefetch(struct dpu_bliteng *dpu_be,
+ u32 width, u32 height,
+ u32 x_offset, u32 y_offset,
+ u32 stride, u32 format, u64 modifier,
+ u64 baddr, u64 uv_addr);
+
+/*
+ * to avoid on-the-fly/hot plane resource migration
+ * between two display interfaces
+ */
+#define DPU_PLANE_SRC_TO_DISP_STREAM0 BIT(0)
+#define DPU_PLANE_SRC_TO_DISP_STREAM1 BIT(1)
+#define DPU_PLANE_SRC_DISABLED 0
+
+#define MAX_FD_NUM 4
+#define MAX_FL_NUM 2
+#define MAX_FW_NUM 1
+#define MAX_LB_NUM 7
+struct dpu_plane_res {
+ struct dpu_constframe *cf[2];
+ struct dpu_extdst *ed[2];
+ struct dpu_fetchunit *fd[MAX_FD_NUM];
+ struct dpu_fetchunit *fe[2];
+ struct dpu_fetchunit *fl[MAX_FL_NUM];
+ struct dpu_fetchunit *fw[MAX_FW_NUM];
+ struct dpu_framegen *fg[2];
+ struct dpu_hscaler *hs[2];
+ struct dpu_layerblend *lb[MAX_LB_NUM];
+ struct dpu_vscaler *vs[2];
+};
+
+/*
+ * Each DPU plane can be a primary plane or an overlay plane
+ * of one of the DPU's two CRTCs.
+ */
+struct dpu_plane_grp {
+ struct dpu_plane_res res;
+ unsigned int hw_plane_num;
+ unsigned int hw_plane_fetcheco_num;
+ unsigned int hw_plane_hscaler_num;
+ unsigned int hw_plane_vscaler_num;
+ unsigned int id;
+ bool has_vproc;
+ /*
+ * used when assigning plane source
+ * index: 0 1 2 3 4 5 6
+ * source: fl0(sub0) fl1(sub0) fw2(sub0) fd0 fd1 fd2 fd3
+ */
+ struct mutex mutex;
+ u32 src_a_mask;
+ u32 src_na_mask;
+ u32 src_use_vproc_mask;
+};
+
+static inline struct dpu_plane_grp *plane_res_to_grp(struct dpu_plane_res *res)
+{
+ return container_of(res, struct dpu_plane_grp, res);
+}
+
+struct dpu_client_platformdata {
+ const unsigned int stream_id;
+ unsigned int di_grp_id;
+ struct dpu_plane_grp *plane_grp;
+
+ /* Store9 could be shared bewteen display engine and blit engine */
+ struct dpu_store *st9;
+
+ struct device_node *of_node;
+};
+#endif /* __DRM_DPU_H__ */
diff --git a/include/video/imx-dcss.h b/include/video/imx-dcss.h
new file mode 100644
index 000000000000..20b6daedd044
--- /dev/null
+++ b/include/video/imx-dcss.h
@@ -0,0 +1,190 @@
+/*
+ * Copyright 2017-2018 NXP
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#ifndef __IMX_DCSS_H__
+#define __IMX_DCSS_H__
+
+#include <linux/types.h>
+#include <video/videomode.h>
+#include <drm/drm_rect.h>
+
+struct dcss_soc;
+
+struct dcss_client_platformdata {
+ struct device_node *of_node;
+};
+
+/* COMMON */
+int dcss_vblank_irq_get(struct dcss_soc *dcss);
+void dcss_vblank_irq_enable(struct dcss_soc *dcss, bool en);
+void dcss_vblank_irq_clear(struct dcss_soc *dcss);
+enum dcss_color_space dcss_drm_fourcc_to_colorspace(u32 drm_fourcc);
+void dcss_trace_write(u64 tag);
+
+
+#define TAG(x) ((x) << 56)
+
+#define TRACE_COMMON TAG(0LL)
+#define TRACE_DTG TAG(1LL)
+#define TRACE_SS TAG(2LL)
+#define TRACE_DPR TAG(3LL)
+#define TRACE_SCALER TAG(4LL)
+#define TRACE_CTXLD TAG(5LL)
+#define TRACE_DEC400D TAG(6LL)
+#define TRACE_DTRC TAG(7LL)
+#define TRACE_HDR10 TAG(8LL)
+#define TRACE_RDSRC TAG(9LL)
+#define TRACE_WRSCL TAG(10LL)
+
+#define TRACE_DRM_CRTC TAG(11LL)
+#define TRACE_DRM_PLANE TAG(12LL)
+#define TRACE_DRM_KMS TAG(13LL)
+
+#define dcss_trace_module(mod_tag, val) dcss_trace_write((mod_tag) | (val));
+
+/* BLKCTL */
+void dcss_blkctl_hdmi_secure_src_en(struct dcss_soc *dcss);
+
+/* DPR */
+enum dcss_tile_type {
+ TILE_LINEAR = 0,
+ TILE_GPU_STANDARD,
+ TILE_GPU_SUPER,
+ TILE_VPU_YUV420,
+ TILE_VPU_VP9,
+};
+
+enum dcss_pix_size {
+ PIX_SIZE_8,
+ PIX_SIZE_16,
+ PIX_SIZE_32,
+};
+
+void dcss_dpr_set_res(struct dcss_soc *dcss, int ch_num, u32 xres, u32 yres,
+ u32 adj_w, u32 adj_h);
+void dcss_dpr_addr_set(struct dcss_soc *dcss, int ch_num, u32 luma_base_addr,
+ u32 chroma_base_addr, u16 pitch);
+void dcss_dpr_enable(struct dcss_soc *dcss, int ch_num, bool en);
+void dcss_dpr_format_set(struct dcss_soc *dcss, int ch_num, u32 pix_format,
+ bool modifiers_present);
+void dcss_dpr_tile_derive(struct dcss_soc *dcss,
+ int ch_num,
+ uint64_t modifier);
+void dcss_dpr_set_rotation(struct dcss_soc *dcss, int ch_num, u32 rotation);
+
+/* DTG */
+int dcss_dtg_mode_valid(struct dcss_soc *dcss, int clock, int crtc_clock);
+int dcss_dtg_mode_fixup(struct dcss_soc *dcss, int clock);
+void dcss_dtg_sync_set(struct dcss_soc *dcss, struct videomode *vm);
+void dcss_dtg_plane_pos_set(struct dcss_soc *dcss, int ch_num,
+ int px, int py, int pw, int ph);
+void dcss_dtg_enable(struct dcss_soc *dcss, bool en,
+ struct completion *dis_completion);
+bool dcss_dtg_is_enabled(struct dcss_soc *dcss);
+void dcss_dtg_ch_enable(struct dcss_soc *dcss, int ch_num, bool en);
+void dcss_dtg_plane_alpha_set(struct dcss_soc *dcss, int ch_num,
+ u32 pix_format, int alpha, bool use_global_alpha);
+bool dcss_dtg_global_alpha_changed(struct dcss_soc *dcss, int ch_num,
+ u32 pix_format, int alpha,
+ int use_global_alpha);
+void dcss_dtg_css_set(struct dcss_soc *dcss, u32 pix_format);
+void dcss_dtg_ctxld_kick_irq_enable(struct dcss_soc *dcss, bool en);
+bool dcss_dtg_vblank_irq_valid(struct dcss_soc *dcss);
+
+/* SUBSAM */
+void dcss_ss_sync_set(struct dcss_soc *dcss, struct videomode *vm,
+ bool phsync, bool pvsync);
+void dcss_ss_subsam_set(struct dcss_soc *dcss, u32 pix_format);
+void dcss_ss_enable(struct dcss_soc *dcss, bool en);
+
+/* SCALER */
+void dcss_scaler_enable(struct dcss_soc *dcss, int ch_num, bool en);
+void dcss_scaler_setup(struct dcss_soc *dcss, int ch_num, u32 pix_format,
+ int src_xres, int src_yres, int dst_xres, int dst_yres,
+ u32 vrefresh_hz);
+bool dcss_scaler_can_scale(struct dcss_soc *dcss, int ch_num,
+ int src_xres, int src_yres,
+ int dst_xres, int dst_yres);
+
+/* CTXLD */
+int dcss_ctxld_enable(struct dcss_soc *dcss);
+bool dcss_ctxld_is_flushed(struct dcss_soc *dcss);
+
+/* HDR10 */
+enum dcss_hdr10_nonlinearity {
+ NL_REC2084,
+ NL_REC709,
+ NL_BT1886,
+ NL_2100HLG,
+ NL_SRGB,
+};
+
+enum dcss_hdr10_pixel_range {
+ PR_LIMITED,
+ PR_FULL,
+};
+
+enum dcss_hdr10_gamut {
+ G_REC2020,
+ G_REC709,
+ G_REC601_NTSC,
+ G_REC601_PAL,
+ G_ADOBE_ARGB,
+};
+
+struct dcss_hdr10_pipe_cfg {
+ u32 pixel_format;
+ enum dcss_hdr10_nonlinearity nl;
+ enum dcss_hdr10_pixel_range pr;
+ enum dcss_hdr10_gamut g;
+};
+
+void dcss_hdr10_setup(struct dcss_soc *dcss, int ch_num,
+ struct dcss_hdr10_pipe_cfg *ipipe_cfg,
+ struct dcss_hdr10_pipe_cfg *opipe_cfg);
+
+/* DTRC */
+void dcss_dtrc_bypass(struct dcss_soc *dcss, int ch_num);
+void dcss_dtrc_set_res(struct dcss_soc *dcss, int ch_num, struct drm_rect *src,
+ struct drm_rect *old_src, u32 pixel_format);
+void dcss_dtrc_addr_set(struct dcss_soc *dcss, int ch_num, u32 p1_ba, u32 p2_ba,
+ uint64_t dec_table_ofs);
+void dcss_dtrc_enable(struct dcss_soc *dcss, int ch_num, bool enable);
+void dcss_dtrc_set_format_mod(struct dcss_soc *dcss, int ch_num, u64 modifier);
+
+enum dcss_color_space {
+ DCSS_COLORSPACE_RGB,
+ DCSS_COLORSPACE_YUV,
+ DCSS_COLORSPACE_UNKNOWN,
+};
+
+/* DEC400D */
+void dcss_dec400d_set_format_mod(struct dcss_soc *dcss,
+ uint32_t fourcc,
+ uint32_t mod_idx,
+ uint64_t modifier);
+void dcss_dec400d_bypass(struct dcss_soc *dcss);
+void dcss_dec400d_shadow_trig(struct dcss_soc *dcss);
+void dcss_dec400d_addr_set(struct dcss_soc *dcss,
+ uint32_t baddr,
+ uint32_t caddr);
+void dcss_dec400d_read_config(struct dcss_soc *dcss,
+ uint32_t read_id,
+ bool compress_en,
+ uint32_t compress_format);
+void dcss_dec400d_fast_clear_config(struct dcss_soc *dcss,
+ uint32_t fc_value,
+ bool enable);
+void dcss_dec400d_enable(struct dcss_soc *dcss);
+#endif /* __IMX_DCSS_H__ */
diff --git a/include/video/imx-lcdif.h b/include/video/imx-lcdif.h
new file mode 100644
index 000000000000..96b124852dd1
--- /dev/null
+++ b/include/video/imx-lcdif.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2018 NXP
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __IMX_LCDIF_H__
+#define __IMX_LCDIF_H__
+
+struct lcdif_soc;
+struct videomode;
+
+struct lcdif_client_platformdata {
+ struct device_node *of_node;
+};
+
+int lcdif_vblank_irq_get(struct lcdif_soc *lcdif);
+void lcdif_vblank_irq_enable(struct lcdif_soc *lcdif);
+void lcdif_vblank_irq_disable(struct lcdif_soc *lcdif);
+void lcdif_vblank_irq_clear(struct lcdif_soc *lcdif);
+
+int lcdif_get_bus_fmt_from_pix_fmt(struct lcdif_soc *lcdif,
+ uint32_t format);
+int lcdif_set_pix_fmt(struct lcdif_soc *lcdif, u32 format);
+void lcdif_set_bus_fmt(struct lcdif_soc *lcdif, u32 bus_format);
+void lcdif_set_fb_addr(struct lcdif_soc *lcdif, int id, u32 addr);
+void lcdif_set_mode(struct lcdif_soc *lcdif, struct videomode *vmode);
+void lcdif_set_fb_hcrop(struct lcdif_soc *lcdif, u32 src_w,
+ u32 fb_w, bool crop);
+void lcdif_enable_controller(struct lcdif_soc *lcdif);
+void lcdif_disable_controller(struct lcdif_soc *lcdif);
+void lcdif_dump_registers(struct lcdif_soc *lcdif);
+
+#endif
diff --git a/include/video/imx8-pc.h b/include/video/imx8-pc.h
new file mode 100644
index 000000000000..ab81d56a5f5f
--- /dev/null
+++ b/include/video/imx8-pc.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2018 NXP
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#ifndef _IMX8_PIXEL_COMBINER_H_
+#define _IMX8_PIXEL_COMBINER_H_
+
+enum {
+ PC_BYPASS,
+ PC_COMBINE,
+ PC_CONVERSION,
+ PC_SPLIT_RGB,
+};
+
+struct pc;
+
+void pc_enable(struct pc *pc);
+void pc_disable(struct pc *pc);
+void pc_configure(struct pc *pc, unsigned int di, unsigned int frame_width,
+ u32 mode, u32 format);
+struct pc *pc_lookup_by_phandle(struct device *dev, const char *name);
+
+#endif
diff --git a/include/video/imx8-prefetch.h b/include/video/imx8-prefetch.h
new file mode 100644
index 000000000000..edbbd17ef021
--- /dev/null
+++ b/include/video/imx8-prefetch.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2017-2018 NXP
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#ifndef _IMX8_PREFETCH_H_
+#define _IMX8_PREFETCH_H_
+
+#define PRG_HANDSHAKE_8LINES 8
+#define PRG_HANDSHAKE_4LINES 4
+#define AMPHION_STRIPE_WIDTH 8
+#define AMPHION_STRIPE_HEIGHT 128
+#define AMPHION_UV_STRIPE_HEIGHT AMPHION_STRIPE_HEIGHT
+#define AMPHION_Y_STRIPE_HEIGHT (2 * AMPHION_STRIPE_HEIGHT)
+#define VIVANTE_TILE_WIDTH 4
+#define VIVANTE_TILE_HEIGHT 4
+#define VIVANTE_SUPER_TILE_WIDTH 64
+#define VIVANTE_SUPER_TILE_HEIGHT 64
+
+struct prg;
+struct prg *
+prg_lookup_by_phandle(struct device *dev, const char *name, int index);
+void prg_enable(struct prg *prg);
+void prg_disable(struct prg *prg);
+void prg_configure(struct prg *prg, unsigned int width, unsigned int height,
+ unsigned int x_offset, unsigned int y_offset,
+ unsigned int stride, unsigned int bits_per_pixel,
+ unsigned long baddr, u32 format, u64 modifier,
+ bool start);
+void prg_reg_update(struct prg *prg);
+void prg_shadow_enable(struct prg *prg);
+bool prg_stride_supported(struct prg *prg, unsigned int stride);
+bool prg_stride_double_check(struct prg *prg,
+ unsigned int width, unsigned int x_offset,
+ unsigned int bits_per_pixel, u64 modifier,
+ unsigned int stride, dma_addr_t baddr);
+void prg_set_auxiliary(struct prg *prg);
+void prg_set_primary(struct prg *prg);
+void prg_set_blit(struct prg *prg);
+
+struct dprc;
+struct dprc *
+dprc_lookup_by_phandle(struct device *dev, const char *name, int index);
+void dprc_enable(struct dprc *dprc);
+void dprc_disable(struct dprc *dprc);
+void dprc_configure(struct dprc *dprc, unsigned int stream_id,
+ unsigned int width, unsigned int height,
+ unsigned int x_offset, unsigned int y_offset,
+ unsigned int stride, u32 format, u64 modifier,
+ unsigned long baddr, unsigned long uv_baddr,
+ bool start, bool aux_start, bool interlace_frame);
+void dprc_reg_update(struct dprc *dprc);
+void dprc_first_frame_handle(struct dprc *dprc);
+void dprc_irq_handle(struct dprc *dprc);
+void dprc_enable_ctrl_done_irq(struct dprc *dprc);
+bool dprc_format_supported(struct dprc *dprc, u32 format, u64 modifier);
+bool dprc_stride_supported(struct dprc *dprc,
+ unsigned int stride, unsigned int uv_stride,
+ unsigned int width, u32 format);
+bool dprc_stride_double_check(struct dprc *dprc,
+ unsigned int width, unsigned int x_offset,
+ u32 format, u64 modifier,
+ dma_addr_t baddr, dma_addr_t uv_baddr);
+
+#endif
diff --git a/include/video/mxc_edid.h b/include/video/mxc_edid.h
new file mode 100644
index 000000000000..ff7ddd92a3bc
--- /dev/null
+++ b/include/video/mxc_edid.h
@@ -0,0 +1,107 @@
+/*
+ * Copyright 2009-2015 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/*!
+ * @defgroup Framebuffer Framebuffer Driver for SDC and ADC.
+ */
+
+/*!
+ * @file mxc_edid.h
+ *
+ * @brief MXC EDID tools
+ *
+ * @ingroup Framebuffer
+ */
+
+#ifndef MXC_EDID_H
+#define MXC_EDID_H
+
+#include <linux/fb.h>
+
+#define FB_VMODE_ASPECT_4_3 0x10
+#define FB_VMODE_ASPECT_16_9 0x20
+#define FB_VMODE_ASPECT_MASK (FB_VMODE_ASPECT_4_3 | FB_VMODE_ASPECT_16_9)
+
+enum cea_audio_coding_types {
+ AUDIO_CODING_TYPE_REF_STREAM_HEADER = 0,
+ AUDIO_CODING_TYPE_LPCM = 1,
+ AUDIO_CODING_TYPE_AC3 = 2,
+ AUDIO_CODING_TYPE_MPEG1 = 3,
+ AUDIO_CODING_TYPE_MP3 = 4,
+ AUDIO_CODING_TYPE_MPEG2 = 5,
+ AUDIO_CODING_TYPE_AACLC = 6,
+ AUDIO_CODING_TYPE_DTS = 7,
+ AUDIO_CODING_TYPE_ATRAC = 8,
+ AUDIO_CODING_TYPE_SACD = 9,
+ AUDIO_CODING_TYPE_EAC3 = 10,
+ AUDIO_CODING_TYPE_DTS_HD = 11,
+ AUDIO_CODING_TYPE_MLP = 12,
+ AUDIO_CODING_TYPE_DST = 13,
+ AUDIO_CODING_TYPE_WMAPRO = 14,
+ AUDIO_CODING_TYPE_RESERVED = 15,
+};
+
+struct mxc_hdmi_3d_format {
+ unsigned char vic_order_2d;
+ unsigned char struct_3d;
+ unsigned char detail_3d;
+ unsigned char reserved;
+};
+
+struct mxc_edid_cfg {
+ bool cea_underscan;
+ bool cea_basicaudio;
+ bool cea_ycbcr444;
+ bool cea_ycbcr422;
+ bool hdmi_cap;
+
+ /*VSD*/
+ bool vsd_support_ai;
+ bool vsd_dc_48bit;
+ bool vsd_dc_36bit;
+ bool vsd_dc_30bit;
+ bool vsd_dc_y444;
+ bool vsd_dvi_dual;
+
+ bool vsd_cnc0;
+ bool vsd_cnc1;
+ bool vsd_cnc2;
+ bool vsd_cnc3;
+
+ u8 vsd_video_latency;
+ u8 vsd_audio_latency;
+ u8 vsd_I_video_latency;
+ u8 vsd_I_audio_latency;
+
+ u8 physical_address[4];
+ u8 hdmi_vic[64];
+ struct mxc_hdmi_3d_format hdmi_3d_format[64];
+ u16 hdmi_3d_mask_all;
+ u16 hdmi_3d_struct_all;
+ u32 vsd_max_tmdsclk_rate;
+
+ u8 max_channels;
+ u8 sample_sizes;
+ u8 sample_rates;
+ u8 speaker_alloc;
+};
+
+extern const struct fb_videomode mxc_cea_mode[64];
+
+int mxc_edid_var_to_vic(struct fb_var_screeninfo *var);
+int mxc_edid_mode_to_vic(const struct fb_videomode *mode);
+int mxc_edid_read(struct i2c_adapter *adp, unsigned short addr,
+ unsigned char *edid, struct mxc_edid_cfg *cfg, struct fb_info *fbi);
+int mxc_edid_parse_ext_blk(unsigned char *edid, struct mxc_edid_cfg *cfg,
+ struct fb_monspecs *specs);
+#endif
diff --git a/include/video/mxc_hdmi.h b/include/video/mxc_hdmi.h
new file mode 100644
index 000000000000..79eb3024f65c
--- /dev/null
+++ b/include/video/mxc_hdmi.h
@@ -0,0 +1,1015 @@
+/*
+ * Copyright (C) 2011-2015 Freescale Semiconductor, Inc.
+ */
+
+/*
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#ifndef __MXC_HDMI_H__
+#define __MXC_HDMI_H__
+
+/*
+ * Hdmi controller registers
+ */
+
+/* Identification Registers */
+#define HDMI_DESIGN_ID 0x0000
+#define HDMI_REVISION_ID 0x0001
+#define HDMI_PRODUCT_ID0 0x0002
+#define HDMI_PRODUCT_ID1 0x0003
+#define HDMI_CONFIG0_ID 0x0004
+#define HDMI_CONFIG1_ID 0x0005
+#define HDMI_CONFIG2_ID 0x0006
+#define HDMI_CONFIG3_ID 0x0007
+
+/* Interrupt Registers */
+#define HDMI_IH_FC_STAT0 0x0100
+#define HDMI_IH_FC_STAT1 0x0101
+#define HDMI_IH_FC_STAT2 0x0102
+#define HDMI_IH_AS_STAT0 0x0103
+#define HDMI_IH_PHY_STAT0 0x0104
+#define HDMI_IH_I2CM_STAT0 0x0105
+#define HDMI_IH_CEC_STAT0 0x0106
+#define HDMI_IH_VP_STAT0 0x0107
+#define HDMI_IH_I2CMPHY_STAT0 0x0108
+#define HDMI_IH_AHBDMAAUD_STAT0 0x0109
+
+#define HDMI_IH_MUTE_FC_STAT0 0x0180
+#define HDMI_IH_MUTE_FC_STAT1 0x0181
+#define HDMI_IH_MUTE_FC_STAT2 0x0182
+#define HDMI_IH_MUTE_AS_STAT0 0x0183
+#define HDMI_IH_MUTE_PHY_STAT0 0x0184
+#define HDMI_IH_MUTE_I2CM_STAT0 0x0185
+#define HDMI_IH_MUTE_CEC_STAT0 0x0186
+#define HDMI_IH_MUTE_VP_STAT0 0x0187
+#define HDMI_IH_MUTE_I2CMPHY_STAT0 0x0188
+#define HDMI_IH_MUTE_AHBDMAAUD_STAT0 0x0189
+#define HDMI_IH_MUTE 0x01FF
+
+/* Video Sample Registers */
+#define HDMI_TX_INVID0 0x0200
+#define HDMI_TX_INSTUFFING 0x0201
+#define HDMI_TX_GYDATA0 0x0202
+#define HDMI_TX_GYDATA1 0x0203
+#define HDMI_TX_RCRDATA0 0x0204
+#define HDMI_TX_RCRDATA1 0x0205
+#define HDMI_TX_BCBDATA0 0x0206
+#define HDMI_TX_BCBDATA1 0x0207
+
+/* Video Packetizer Registers */
+#define HDMI_VP_STATUS 0x0800
+#define HDMI_VP_PR_CD 0x0801
+#define HDMI_VP_STUFF 0x0802
+#define HDMI_VP_REMAP 0x0803
+#define HDMI_VP_CONF 0x0804
+#define HDMI_VP_STAT 0x0805
+#define HDMI_VP_INT 0x0806
+#define HDMI_VP_MASK 0x0807
+#define HDMI_VP_POL 0x0808
+
+/* Frame Composer Registers */
+#define HDMI_FC_INVIDCONF 0x1000
+#define HDMI_FC_INHACTV0 0x1001
+#define HDMI_FC_INHACTV1 0x1002
+#define HDMI_FC_INHBLANK0 0x1003
+#define HDMI_FC_INHBLANK1 0x1004
+#define HDMI_FC_INVACTV0 0x1005
+#define HDMI_FC_INVACTV1 0x1006
+#define HDMI_FC_INVBLANK 0x1007
+#define HDMI_FC_HSYNCINDELAY0 0x1008
+#define HDMI_FC_HSYNCINDELAY1 0x1009
+#define HDMI_FC_HSYNCINWIDTH0 0x100A
+#define HDMI_FC_HSYNCINWIDTH1 0x100B
+#define HDMI_FC_VSYNCINDELAY 0x100C
+#define HDMI_FC_VSYNCINWIDTH 0x100D
+#define HDMI_FC_INFREQ0 0x100E
+#define HDMI_FC_INFREQ1 0x100F
+#define HDMI_FC_INFREQ2 0x1010
+#define HDMI_FC_CTRLDUR 0x1011
+#define HDMI_FC_EXCTRLDUR 0x1012
+#define HDMI_FC_EXCTRLSPAC 0x1013
+#define HDMI_FC_CH0PREAM 0x1014
+#define HDMI_FC_CH1PREAM 0x1015
+#define HDMI_FC_CH2PREAM 0x1016
+#define HDMI_FC_AVICONF3 0x1017
+#define HDMI_FC_GCP 0x1018
+#define HDMI_FC_AVICONF0 0x1019
+#define HDMI_FC_AVICONF1 0x101A
+#define HDMI_FC_AVICONF2 0x101B
+#define HDMI_FC_AVIVID 0x101C
+#define HDMI_FC_AVIETB0 0x101D
+#define HDMI_FC_AVIETB1 0x101E
+#define HDMI_FC_AVISBB0 0x101F
+#define HDMI_FC_AVISBB1 0x1020
+#define HDMI_FC_AVIELB0 0x1021
+#define HDMI_FC_AVIELB1 0x1022
+#define HDMI_FC_AVISRB0 0x1023
+#define HDMI_FC_AVISRB1 0x1024
+#define HDMI_FC_AUDICONF0 0x1025
+#define HDMI_FC_AUDICONF1 0x1026
+#define HDMI_FC_AUDICONF2 0x1027
+#define HDMI_FC_AUDICONF3 0x1028
+#define HDMI_FC_VSDIEEEID0 0x1029
+#define HDMI_FC_VSDSIZE 0x102A
+#define HDMI_FC_VSDIEEEID1 0x1030
+#define HDMI_FC_VSDIEEEID2 0x1031
+#define HDMI_FC_VSDPAYLOAD0 0x1032
+#define HDMI_FC_VSDPAYLOAD1 0x1033
+#define HDMI_FC_VSDPAYLOAD2 0x1034
+#define HDMI_FC_VSDPAYLOAD3 0x1035
+#define HDMI_FC_VSDPAYLOAD4 0x1036
+#define HDMI_FC_VSDPAYLOAD5 0x1037
+#define HDMI_FC_VSDPAYLOAD6 0x1038
+#define HDMI_FC_VSDPAYLOAD7 0x1039
+#define HDMI_FC_VSDPAYLOAD8 0x103A
+#define HDMI_FC_VSDPAYLOAD9 0x103B
+#define HDMI_FC_VSDPAYLOAD10 0x103C
+#define HDMI_FC_VSDPAYLOAD11 0x103D
+#define HDMI_FC_VSDPAYLOAD12 0x103E
+#define HDMI_FC_VSDPAYLOAD13 0x103F
+#define HDMI_FC_VSDPAYLOAD14 0x1040
+#define HDMI_FC_VSDPAYLOAD15 0x1041
+#define HDMI_FC_VSDPAYLOAD16 0x1042
+#define HDMI_FC_VSDPAYLOAD17 0x1043
+#define HDMI_FC_VSDPAYLOAD18 0x1044
+#define HDMI_FC_VSDPAYLOAD19 0x1045
+#define HDMI_FC_VSDPAYLOAD20 0x1046
+#define HDMI_FC_VSDPAYLOAD21 0x1047
+#define HDMI_FC_VSDPAYLOAD22 0x1048
+#define HDMI_FC_VSDPAYLOAD23 0x1049
+#define HDMI_FC_SPDVENDORNAME0 0x104A
+#define HDMI_FC_SPDVENDORNAME1 0x104B
+#define HDMI_FC_SPDVENDORNAME2 0x104C
+#define HDMI_FC_SPDVENDORNAME3 0x104D
+#define HDMI_FC_SPDVENDORNAME4 0x104E
+#define HDMI_FC_SPDVENDORNAME5 0x104F
+#define HDMI_FC_SPDVENDORNAME6 0x1050
+#define HDMI_FC_SPDVENDORNAME7 0x1051
+#define HDMI_FC_SDPPRODUCTNAME0 0x1052
+#define HDMI_FC_SDPPRODUCTNAME1 0x1053
+#define HDMI_FC_SDPPRODUCTNAME2 0x1054
+#define HDMI_FC_SDPPRODUCTNAME3 0x1055
+#define HDMI_FC_SDPPRODUCTNAME4 0x1056
+#define HDMI_FC_SDPPRODUCTNAME5 0x1057
+#define HDMI_FC_SDPPRODUCTNAME6 0x1058
+#define HDMI_FC_SDPPRODUCTNAME7 0x1059
+#define HDMI_FC_SDPPRODUCTNAME8 0x105A
+#define HDMI_FC_SDPPRODUCTNAME9 0x105B
+#define HDMI_FC_SDPPRODUCTNAME10 0x105C
+#define HDMI_FC_SDPPRODUCTNAME11 0x105D
+#define HDMI_FC_SDPPRODUCTNAME12 0x105E
+#define HDMI_FC_SDPPRODUCTNAME13 0x105F
+#define HDMI_FC_SDPPRODUCTNAME14 0x1060
+#define HDMI_FC_SPDPRODUCTNAME15 0x1061
+#define HDMI_FC_SPDDEVICEINF 0x1062
+#define HDMI_FC_AUDSCONF 0x1063
+#define HDMI_FC_AUDSSTAT 0x1064
+#define HDMI_FC_DATACH0FILL 0x1070
+#define HDMI_FC_DATACH1FILL 0x1071
+#define HDMI_FC_DATACH2FILL 0x1072
+#define HDMI_FC_CTRLQHIGH 0x1073
+#define HDMI_FC_CTRLQLOW 0x1074
+#define HDMI_FC_ACP0 0x1075
+#define HDMI_FC_ACP28 0x1076
+#define HDMI_FC_ACP27 0x1077
+#define HDMI_FC_ACP26 0x1078
+#define HDMI_FC_ACP25 0x1079
+#define HDMI_FC_ACP24 0x107A
+#define HDMI_FC_ACP23 0x107B
+#define HDMI_FC_ACP22 0x107C
+#define HDMI_FC_ACP21 0x107D
+#define HDMI_FC_ACP20 0x107E
+#define HDMI_FC_ACP19 0x107F
+#define HDMI_FC_ACP18 0x1080
+#define HDMI_FC_ACP17 0x1081
+#define HDMI_FC_ACP16 0x1082
+#define HDMI_FC_ACP15 0x1083
+#define HDMI_FC_ACP14 0x1084
+#define HDMI_FC_ACP13 0x1085
+#define HDMI_FC_ACP12 0x1086
+#define HDMI_FC_ACP11 0x1087
+#define HDMI_FC_ACP10 0x1088
+#define HDMI_FC_ACP9 0x1089
+#define HDMI_FC_ACP8 0x108A
+#define HDMI_FC_ACP7 0x108B
+#define HDMI_FC_ACP6 0x108C
+#define HDMI_FC_ACP5 0x108D
+#define HDMI_FC_ACP4 0x108E
+#define HDMI_FC_ACP3 0x108F
+#define HDMI_FC_ACP2 0x1090
+#define HDMI_FC_ACP1 0x1091
+#define HDMI_FC_ISCR1_0 0x1092
+#define HDMI_FC_ISCR1_16 0x1093
+#define HDMI_FC_ISCR1_15 0x1094
+#define HDMI_FC_ISCR1_14 0x1095
+#define HDMI_FC_ISCR1_13 0x1096
+#define HDMI_FC_ISCR1_12 0x1097
+#define HDMI_FC_ISCR1_11 0x1098
+#define HDMI_FC_ISCR1_10 0x1099
+#define HDMI_FC_ISCR1_9 0x109A
+#define HDMI_FC_ISCR1_8 0x109B
+#define HDMI_FC_ISCR1_7 0x109C
+#define HDMI_FC_ISCR1_6 0x109D
+#define HDMI_FC_ISCR1_5 0x109E
+#define HDMI_FC_ISCR1_4 0x109F
+#define HDMI_FC_ISCR1_3 0x10A0
+#define HDMI_FC_ISCR1_2 0x10A1
+#define HDMI_FC_ISCR1_1 0x10A2
+#define HDMI_FC_ISCR2_15 0x10A3
+#define HDMI_FC_ISCR2_14 0x10A4
+#define HDMI_FC_ISCR2_13 0x10A5
+#define HDMI_FC_ISCR2_12 0x10A6
+#define HDMI_FC_ISCR2_11 0x10A7
+#define HDMI_FC_ISCR2_10 0x10A8
+#define HDMI_FC_ISCR2_9 0x10A9
+#define HDMI_FC_ISCR2_8 0x10AA
+#define HDMI_FC_ISCR2_7 0x10AB
+#define HDMI_FC_ISCR2_6 0x10AC
+#define HDMI_FC_ISCR2_5 0x10AD
+#define HDMI_FC_ISCR2_4 0x10AE
+#define HDMI_FC_ISCR2_3 0x10AF
+#define HDMI_FC_ISCR2_2 0x10B0
+#define HDMI_FC_ISCR2_1 0x10B1
+#define HDMI_FC_ISCR2_0 0x10B2
+#define HDMI_FC_DATAUTO0 0x10B3
+#define HDMI_FC_DATAUTO1 0x10B4
+#define HDMI_FC_DATAUTO2 0x10B5
+#define HDMI_FC_DATMAN 0x10B6
+#define HDMI_FC_DATAUTO3 0x10B7
+#define HDMI_FC_RDRB0 0x10B8
+#define HDMI_FC_RDRB1 0x10B9
+#define HDMI_FC_RDRB2 0x10BA
+#define HDMI_FC_RDRB3 0x10BB
+#define HDMI_FC_RDRB4 0x10BC
+#define HDMI_FC_RDRB5 0x10BD
+#define HDMI_FC_RDRB6 0x10BE
+#define HDMI_FC_RDRB7 0x10BF
+#define HDMI_FC_STAT0 0x10D0
+#define HDMI_FC_INT0 0x10D1
+#define HDMI_FC_MASK0 0x10D2
+#define HDMI_FC_POL0 0x10D3
+#define HDMI_FC_STAT1 0x10D4
+#define HDMI_FC_INT1 0x10D5
+#define HDMI_FC_MASK1 0x10D6
+#define HDMI_FC_POL1 0x10D7
+#define HDMI_FC_STAT2 0x10D8
+#define HDMI_FC_INT2 0x10D9
+#define HDMI_FC_MASK2 0x10DA
+#define HDMI_FC_POL2 0x10DB
+#define HDMI_FC_PRCONF 0x10E0
+
+#define HDMI_FC_GMD_STAT 0x1100
+#define HDMI_FC_GMD_EN 0x1101
+#define HDMI_FC_GMD_UP 0x1102
+#define HDMI_FC_GMD_CONF 0x1103
+#define HDMI_FC_GMD_HB 0x1104
+#define HDMI_FC_GMD_PB0 0x1105
+#define HDMI_FC_GMD_PB1 0x1106
+#define HDMI_FC_GMD_PB2 0x1107
+#define HDMI_FC_GMD_PB3 0x1108
+#define HDMI_FC_GMD_PB4 0x1109
+#define HDMI_FC_GMD_PB5 0x110A
+#define HDMI_FC_GMD_PB6 0x110B
+#define HDMI_FC_GMD_PB7 0x110C
+#define HDMI_FC_GMD_PB8 0x110D
+#define HDMI_FC_GMD_PB9 0x110E
+#define HDMI_FC_GMD_PB10 0x110F
+#define HDMI_FC_GMD_PB11 0x1110
+#define HDMI_FC_GMD_PB12 0x1111
+#define HDMI_FC_GMD_PB13 0x1112
+#define HDMI_FC_GMD_PB14 0x1113
+#define HDMI_FC_GMD_PB15 0x1114
+#define HDMI_FC_GMD_PB16 0x1115
+#define HDMI_FC_GMD_PB17 0x1116
+#define HDMI_FC_GMD_PB18 0x1117
+#define HDMI_FC_GMD_PB19 0x1118
+#define HDMI_FC_GMD_PB20 0x1119
+#define HDMI_FC_GMD_PB21 0x111A
+#define HDMI_FC_GMD_PB22 0x111B
+#define HDMI_FC_GMD_PB23 0x111C
+#define HDMI_FC_GMD_PB24 0x111D
+#define HDMI_FC_GMD_PB25 0x111E
+#define HDMI_FC_GMD_PB26 0x111F
+#define HDMI_FC_GMD_PB27 0x1120
+
+#define HDMI_FC_DBGFORCE 0x1200
+#define HDMI_FC_DBGAUD0CH0 0x1201
+#define HDMI_FC_DBGAUD1CH0 0x1202
+#define HDMI_FC_DBGAUD2CH0 0x1203
+#define HDMI_FC_DBGAUD0CH1 0x1204
+#define HDMI_FC_DBGAUD1CH1 0x1205
+#define HDMI_FC_DBGAUD2CH1 0x1206
+#define HDMI_FC_DBGAUD0CH2 0x1207
+#define HDMI_FC_DBGAUD1CH2 0x1208
+#define HDMI_FC_DBGAUD2CH2 0x1209
+#define HDMI_FC_DBGAUD0CH3 0x120A
+#define HDMI_FC_DBGAUD1CH3 0x120B
+#define HDMI_FC_DBGAUD2CH3 0x120C
+#define HDMI_FC_DBGAUD0CH4 0x120D
+#define HDMI_FC_DBGAUD1CH4 0x120E
+#define HDMI_FC_DBGAUD2CH4 0x120F
+#define HDMI_FC_DBGAUD0CH5 0x1210
+#define HDMI_FC_DBGAUD1CH5 0x1211
+#define HDMI_FC_DBGAUD2CH5 0x1212
+#define HDMI_FC_DBGAUD0CH6 0x1213
+#define HDMI_FC_DBGAUD1CH6 0x1214
+#define HDMI_FC_DBGAUD2CH6 0x1215
+#define HDMI_FC_DBGAUD0CH7 0x1216
+#define HDMI_FC_DBGAUD1CH7 0x1217
+#define HDMI_FC_DBGAUD2CH7 0x1218
+#define HDMI_FC_DBGTMDS0 0x1219
+#define HDMI_FC_DBGTMDS1 0x121A
+#define HDMI_FC_DBGTMDS2 0x121B
+
+/* HDMI Source PHY Registers */
+#define HDMI_PHY_CONF0 0x3000
+#define HDMI_PHY_TST0 0x3001
+#define HDMI_PHY_TST1 0x3002
+#define HDMI_PHY_TST2 0x3003
+#define HDMI_PHY_STAT0 0x3004
+#define HDMI_PHY_INT0 0x3005
+#define HDMI_PHY_MASK0 0x3006
+#define HDMI_PHY_POL0 0x3007
+
+/* HDMI Master PHY Registers */
+#define HDMI_PHY_I2CM_SLAVE_ADDR 0x3020
+#define HDMI_PHY_I2CM_ADDRESS_ADDR 0x3021
+#define HDMI_PHY_I2CM_DATAO_1_ADDR 0x3022
+#define HDMI_PHY_I2CM_DATAO_0_ADDR 0x3023
+#define HDMI_PHY_I2CM_DATAI_1_ADDR 0x3024
+#define HDMI_PHY_I2CM_DATAI_0_ADDR 0x3025
+#define HDMI_PHY_I2CM_OPERATION_ADDR 0x3026
+#define HDMI_PHY_I2CM_INT_ADDR 0x3027
+#define HDMI_PHY_I2CM_CTLINT_ADDR 0x3028
+#define HDMI_PHY_I2CM_DIV_ADDR 0x3029
+#define HDMI_PHY_I2CM_SOFTRSTZ_ADDR 0x302a
+#define HDMI_PHY_I2CM_SS_SCL_HCNT_1_ADDR 0x302b
+#define HDMI_PHY_I2CM_SS_SCL_HCNT_0_ADDR 0x302c
+#define HDMI_PHY_I2CM_SS_SCL_LCNT_1_ADDR 0x302d
+#define HDMI_PHY_I2CM_SS_SCL_LCNT_0_ADDR 0x302e
+#define HDMI_PHY_I2CM_FS_SCL_HCNT_1_ADDR 0x302f
+#define HDMI_PHY_I2CM_FS_SCL_HCNT_0_ADDR 0x3030
+#define HDMI_PHY_I2CM_FS_SCL_LCNT_1_ADDR 0x3031
+#define HDMI_PHY_I2CM_FS_SCL_LCNT_0_ADDR 0x3032
+
+/* Audio Sampler Registers */
+#define HDMI_AUD_CONF0 0x3100
+#define HDMI_AUD_CONF1 0x3101
+#define HDMI_AUD_INT 0x3102
+#define HDMI_AUD_CONF2 0x3103
+#define HDMI_AUD_N1 0x3200
+#define HDMI_AUD_N2 0x3201
+#define HDMI_AUD_N3 0x3202
+#define HDMI_AUD_CTS1 0x3203
+#define HDMI_AUD_CTS2 0x3204
+#define HDMI_AUD_CTS3 0x3205
+#define HDMI_AUD_INPUTCLKFS 0x3206
+#define HDMI_AUD_SPDIFINT 0x3302
+#define HDMI_AUD_CONF0_HBR 0x3400
+#define HDMI_AUD_HBR_STATUS 0x3401
+#define HDMI_AUD_HBR_INT 0x3402
+#define HDMI_AUD_HBR_POL 0x3403
+#define HDMI_AUD_HBR_MASK 0x3404
+
+/* Generic Parallel Audio Interface Registers */
+/* Not used as GPAUD interface is not enabled in hw */
+#define HDMI_GP_CONF0 0x3500
+#define HDMI_GP_CONF1 0x3501
+#define HDMI_GP_CONF2 0x3502
+#define HDMI_GP_STAT 0x3503
+#define HDMI_GP_INT 0x3504
+#define HDMI_GP_MASK 0x3505
+#define HDMI_GP_POL 0x3506
+
+/* Audio DMA Registers */
+#define HDMI_AHB_DMA_CONF0 0x3600
+#define HDMI_AHB_DMA_START 0x3601
+#define HDMI_AHB_DMA_STOP 0x3602
+#define HDMI_AHB_DMA_THRSLD 0x3603
+#define HDMI_AHB_DMA_STRADDR0 0x3604
+#define HDMI_AHB_DMA_STRADDR1 0x3605
+#define HDMI_AHB_DMA_STRADDR2 0x3606
+#define HDMI_AHB_DMA_STRADDR3 0x3607
+#define HDMI_AHB_DMA_STPADDR0 0x3608
+#define HDMI_AHB_DMA_STPADDR1 0x3609
+#define HDMI_AHB_DMA_STPADDR2 0x360a
+#define HDMI_AHB_DMA_STPADDR3 0x360b
+#define HDMI_AHB_DMA_BSTADDR0 0x360c
+#define HDMI_AHB_DMA_BSTADDR1 0x360d
+#define HDMI_AHB_DMA_BSTADDR2 0x360e
+#define HDMI_AHB_DMA_BSTADDR3 0x360f
+#define HDMI_AHB_DMA_MBLENGTH0 0x3610
+#define HDMI_AHB_DMA_MBLENGTH1 0x3611
+#define HDMI_AHB_DMA_STAT 0x3612
+#define HDMI_AHB_DMA_INT 0x3613
+#define HDMI_AHB_DMA_MASK 0x3614
+#define HDMI_AHB_DMA_POL 0x3615
+#define HDMI_AHB_DMA_CONF1 0x3616
+#define HDMI_AHB_DMA_BUFFSTAT 0x3617
+#define HDMI_AHB_DMA_BUFFINT 0x3618
+#define HDMI_AHB_DMA_BUFFMASK 0x3619
+#define HDMI_AHB_DMA_BUFFPOL 0x361a
+
+/* Main Controller Registers */
+#define HDMI_MC_SFRDIV 0x4000
+#define HDMI_MC_CLKDIS 0x4001
+#define HDMI_MC_SWRSTZ 0x4002
+#define HDMI_MC_OPCTRL 0x4003
+#define HDMI_MC_FLOWCTRL 0x4004
+#define HDMI_MC_PHYRSTZ 0x4005
+#define HDMI_MC_LOCKONCLOCK 0x4006
+#define HDMI_MC_HEACPHY_RST 0x4007
+
+/* Color Space Converter Registers */
+#define HDMI_CSC_CFG 0x4100
+#define HDMI_CSC_SCALE 0x4101
+#define HDMI_CSC_COEF_A1_MSB 0x4102
+#define HDMI_CSC_COEF_A1_LSB 0x4103
+#define HDMI_CSC_COEF_A2_MSB 0x4104
+#define HDMI_CSC_COEF_A2_LSB 0x4105
+#define HDMI_CSC_COEF_A3_MSB 0x4106
+#define HDMI_CSC_COEF_A3_LSB 0x4107
+#define HDMI_CSC_COEF_A4_MSB 0x4108
+#define HDMI_CSC_COEF_A4_LSB 0x4109
+#define HDMI_CSC_COEF_B1_MSB 0x410A
+#define HDMI_CSC_COEF_B1_LSB 0x410B
+#define HDMI_CSC_COEF_B2_MSB 0x410C
+#define HDMI_CSC_COEF_B2_LSB 0x410D
+#define HDMI_CSC_COEF_B3_MSB 0x410E
+#define HDMI_CSC_COEF_B3_LSB 0x410F
+#define HDMI_CSC_COEF_B4_MSB 0x4110
+#define HDMI_CSC_COEF_B4_LSB 0x4111
+#define HDMI_CSC_COEF_C1_MSB 0x4112
+#define HDMI_CSC_COEF_C1_LSB 0x4113
+#define HDMI_CSC_COEF_C2_MSB 0x4114
+#define HDMI_CSC_COEF_C2_LSB 0x4115
+#define HDMI_CSC_COEF_C3_MSB 0x4116
+#define HDMI_CSC_COEF_C3_LSB 0x4117
+#define HDMI_CSC_COEF_C4_MSB 0x4118
+#define HDMI_CSC_COEF_C4_LSB 0x4119
+
+/* HDCP Interrupt Registers */
+#define HDMI_A_APIINTCLR 0x5006
+#define HDMI_A_APIINTSTAT 0x5007
+#define HDMI_A_APIINTMSK 0x5008
+
+/* CEC Engine Registers */
+#define HDMI_CEC_CTRL 0x7D00
+#define HDMI_CEC_STAT 0x7D01
+#define HDMI_CEC_MASK 0x7D02
+#define HDMI_CEC_POLARITY 0x7D03
+#define HDMI_CEC_INT 0x7D04
+#define HDMI_CEC_ADDR_L 0x7D05
+#define HDMI_CEC_ADDR_H 0x7D06
+#define HDMI_CEC_TX_CNT 0x7D07
+#define HDMI_CEC_RX_CNT 0x7D08
+#define HDMI_CEC_TX_DATA0 0x7D10
+#define HDMI_CEC_TX_DATA1 0x7D11
+#define HDMI_CEC_TX_DATA2 0x7D12
+#define HDMI_CEC_TX_DATA3 0x7D13
+#define HDMI_CEC_TX_DATA4 0x7D14
+#define HDMI_CEC_TX_DATA5 0x7D15
+#define HDMI_CEC_TX_DATA6 0x7D16
+#define HDMI_CEC_TX_DATA7 0x7D17
+#define HDMI_CEC_TX_DATA8 0x7D18
+#define HDMI_CEC_TX_DATA9 0x7D19
+#define HDMI_CEC_TX_DATA10 0x7D1a
+#define HDMI_CEC_TX_DATA11 0x7D1b
+#define HDMI_CEC_TX_DATA12 0x7D1c
+#define HDMI_CEC_TX_DATA13 0x7D1d
+#define HDMI_CEC_TX_DATA14 0x7D1e
+#define HDMI_CEC_TX_DATA15 0x7D1f
+#define HDMI_CEC_RX_DATA0 0x7D20
+#define HDMI_CEC_RX_DATA1 0x7D21
+#define HDMI_CEC_RX_DATA2 0x7D22
+#define HDMI_CEC_RX_DATA3 0x7D23
+#define HDMI_CEC_RX_DATA4 0x7D24
+#define HDMI_CEC_RX_DATA5 0x7D25
+#define HDMI_CEC_RX_DATA6 0x7D26
+#define HDMI_CEC_RX_DATA7 0x7D27
+#define HDMI_CEC_RX_DATA8 0x7D28
+#define HDMI_CEC_RX_DATA9 0x7D29
+#define HDMI_CEC_RX_DATA10 0x7D2a
+#define HDMI_CEC_RX_DATA11 0x7D2b
+#define HDMI_CEC_RX_DATA12 0x7D2c
+#define HDMI_CEC_RX_DATA13 0x7D2d
+#define HDMI_CEC_RX_DATA14 0x7D2e
+#define HDMI_CEC_RX_DATA15 0x7D2f
+#define HDMI_CEC_LOCK 0x7D30
+#define HDMI_CEC_WKUPCTRL 0x7D31
+
+/* I2C Master Registers (E-DDC) */
+#define HDMI_I2CM_SLAVE 0x7E00
+#define HDMI_I2CM_ADDRESS 0x7E01
+#define HDMI_I2CM_DATAO 0x7E02
+#define HDMI_I2CM_DATAI 0x7E03
+#define HDMI_I2CM_OPERATION 0x7E04
+#define HDMI_I2CM_INT 0x7E05
+#define HDMI_I2CM_CTLINT 0x7E06
+#define HDMI_I2CM_DIV 0x7E07
+#define HDMI_I2CM_SEGADDR 0x7E08
+#define HDMI_I2CM_SOFTRSTZ 0x7E09
+#define HDMI_I2CM_SEGPTR 0x7E0A
+#define HDMI_I2CM_SS_SCL_HCNT_1_ADDR 0x7E0B
+#define HDMI_I2CM_SS_SCL_HCNT_0_ADDR 0x7E0C
+#define HDMI_I2CM_SS_SCL_LCNT_1_ADDR 0x7E0D
+#define HDMI_I2CM_SS_SCL_LCNT_0_ADDR 0x7E0E
+#define HDMI_I2CM_FS_SCL_HCNT_1_ADDR 0x7E0F
+#define HDMI_I2CM_FS_SCL_HCNT_0_ADDR 0x7E10
+#define HDMI_I2CM_FS_SCL_LCNT_1_ADDR 0x7E11
+#define HDMI_I2CM_FS_SCL_LCNT_0_ADDR 0x7E12
+
+/* Random Number Generator Registers (RNG) */
+#define HDMI_RNG_BASE 0x8000
+
+
+/*
+ * Register field definitions
+ */
+enum {
+/* IH_FC_INT2 field values */
+ HDMI_IH_FC_INT2_OVERFLOW_MASK = 0x03,
+ HDMI_IH_FC_INT2_LOW_PRIORITY_OVERFLOW = 0x02,
+ HDMI_IH_FC_INT2_HIGH_PRIORITY_OVERFLOW = 0x01,
+
+/* IH_FC_STAT2 field values */
+ HDMI_IH_FC_STAT2_OVERFLOW_MASK = 0x03,
+ HDMI_IH_FC_STAT2_LOW_PRIORITY_OVERFLOW = 0x02,
+ HDMI_IH_FC_STAT2_HIGH_PRIORITY_OVERFLOW = 0x01,
+
+/* IH_PHY_STAT0 field values */
+ HDMI_IH_PHY_STAT0_RX_SENSE3 = 0x20,
+ HDMI_IH_PHY_STAT0_RX_SENSE2 = 0x10,
+ HDMI_IH_PHY_STAT0_RX_SENSE1 = 0x8,
+ HDMI_IH_PHY_STAT0_RX_SENSE0 = 0x4,
+ HDMI_IH_PHY_STAT0_TX_PHY_LOCK = 0x2,
+ HDMI_IH_PHY_STAT0_HPD = 0x1,
+
+/* IH_CEC_STAT0 field values */
+ HDMI_IH_CEC_STAT0_WAKEUP = 0x40,
+ HDMI_IH_CEC_STAT0_ERROR_FOLL = 0x20,
+ HDMI_IH_CEC_STAT0_ERROR_INIT = 0x10,
+ HDMI_IH_CEC_STAT0_ARB_LOST = 0x8,
+ HDMI_IH_CEC_STAT0_NACK = 0x4,
+ HDMI_IH_CEC_STAT0_EOM = 0x2,
+ HDMI_IH_CEC_STAT0_DONE = 0x1,
+
+
+/* IH_MUTE_I2CMPHY_STAT0 field values */
+ HDMI_IH_MUTE_I2CMPHY_STAT0_I2CMPHYDONE = 0x2,
+ HDMI_IH_MUTE_I2CMPHY_STAT0_I2CMPHYERROR = 0x1,
+
+/* IH_PHY_STAT0 field values */
+ HDMI_IH_MUTE_PHY_STAT0_RX_SENSE3 = 0x20,
+ HDMI_IH_MUTE_PHY_STAT0_RX_SENSE2 = 0x10,
+ HDMI_IH_MUTE_PHY_STAT0_RX_SENSE1 = 0x8,
+ HDMI_IH_MUTE_PHY_STAT0_RX_SENSE0 = 0x4,
+ HDMI_IH_MUTE_PHY_STAT0_TX_PHY_LOCK = 0x2,
+ HDMI_IH_MUTE_PHY_STAT0_HPD = 0x1,
+
+/* IH_AHBDMAAUD_STAT0 field values */
+ HDMI_IH_AHBDMAAUD_STAT0_ERROR = 0x20,
+ HDMI_IH_AHBDMAAUD_STAT0_LOST = 0x10,
+ HDMI_IH_AHBDMAAUD_STAT0_RETRY = 0x08,
+ HDMI_IH_AHBDMAAUD_STAT0_DONE = 0x04,
+ HDMI_IH_AHBDMAAUD_STAT0_BUFFFULL = 0x02,
+ HDMI_IH_AHBDMAAUD_STAT0_BUFFEMPTY = 0x01,
+
+/* IH_MUTE_FC_STAT2 field values */
+ HDMI_IH_MUTE_FC_STAT2_OVERFLOW_MASK = 0x03,
+ HDMI_IH_MUTE_FC_STAT2_LOW_PRIORITY_OVERFLOW = 0x02,
+ HDMI_IH_MUTE_FC_STAT2_HIGH_PRIORITY_OVERFLOW = 0x01,
+
+/* IH_MUTE_AHBDMAAUD_STAT0 field values */
+ HDMI_IH_MUTE_AHBDMAAUD_STAT0_ERROR = 0x20,
+ HDMI_IH_MUTE_AHBDMAAUD_STAT0_LOST = 0x10,
+ HDMI_IH_MUTE_AHBDMAAUD_STAT0_RETRY = 0x08,
+ HDMI_IH_MUTE_AHBDMAAUD_STAT0_DONE = 0x04,
+ HDMI_IH_MUTE_AHBDMAAUD_STAT0_BUFFFULL = 0x02,
+ HDMI_IH_MUTE_AHBDMAAUD_STAT0_BUFFEMPTY = 0x01,
+
+/* IH_MUTE field values */
+ HDMI_IH_MUTE_MUTE_WAKEUP_INTERRUPT = 0x2,
+ HDMI_IH_MUTE_MUTE_ALL_INTERRUPT = 0x1,
+
+/* TX_INVID0 field values */
+ HDMI_TX_INVID0_INTERNAL_DE_GENERATOR_MASK = 0x80,
+ HDMI_TX_INVID0_INTERNAL_DE_GENERATOR_ENABLE = 0x80,
+ HDMI_TX_INVID0_INTERNAL_DE_GENERATOR_DISABLE = 0x00,
+ HDMI_TX_INVID0_VIDEO_MAPPING_MASK = 0x1F,
+ HDMI_TX_INVID0_VIDEO_MAPPING_OFFSET = 0,
+
+/* TX_INSTUFFING field values */
+ HDMI_TX_INSTUFFING_BDBDATA_STUFFING_MASK = 0x4,
+ HDMI_TX_INSTUFFING_BDBDATA_STUFFING_ENABLE = 0x4,
+ HDMI_TX_INSTUFFING_BDBDATA_STUFFING_DISABLE = 0x0,
+ HDMI_TX_INSTUFFING_RCRDATA_STUFFING_MASK = 0x2,
+ HDMI_TX_INSTUFFING_RCRDATA_STUFFING_ENABLE = 0x2,
+ HDMI_TX_INSTUFFING_RCRDATA_STUFFING_DISABLE = 0x0,
+ HDMI_TX_INSTUFFING_GYDATA_STUFFING_MASK = 0x1,
+ HDMI_TX_INSTUFFING_GYDATA_STUFFING_ENABLE = 0x1,
+ HDMI_TX_INSTUFFING_GYDATA_STUFFING_DISABLE = 0x0,
+
+/* VP_PR_CD field values */
+ HDMI_VP_PR_CD_COLOR_DEPTH_MASK = 0xF0,
+ HDMI_VP_PR_CD_COLOR_DEPTH_OFFSET = 4,
+ HDMI_VP_PR_CD_DESIRED_PR_FACTOR_MASK = 0x0F,
+ HDMI_VP_PR_CD_DESIRED_PR_FACTOR_OFFSET = 0,
+
+/* VP_STUFF field values */
+ HDMI_VP_STUFF_IDEFAULT_PHASE_MASK = 0x20,
+ HDMI_VP_STUFF_IDEFAULT_PHASE_OFFSET = 5,
+ HDMI_VP_STUFF_IFIX_PP_TO_LAST_MASK = 0x10,
+ HDMI_VP_STUFF_IFIX_PP_TO_LAST_OFFSET = 4,
+ HDMI_VP_STUFF_ICX_GOTO_P0_ST_MASK = 0x8,
+ HDMI_VP_STUFF_ICX_GOTO_P0_ST_OFFSET = 3,
+ HDMI_VP_STUFF_YCC422_STUFFING_MASK = 0x4,
+ HDMI_VP_STUFF_YCC422_STUFFING_STUFFING_MODE = 0x4,
+ HDMI_VP_STUFF_YCC422_STUFFING_DIRECT_MODE = 0x0,
+ HDMI_VP_STUFF_PP_STUFFING_MASK = 0x2,
+ HDMI_VP_STUFF_PP_STUFFING_STUFFING_MODE = 0x2,
+ HDMI_VP_STUFF_PP_STUFFING_DIRECT_MODE = 0x0,
+ HDMI_VP_STUFF_PR_STUFFING_MASK = 0x1,
+ HDMI_VP_STUFF_PR_STUFFING_STUFFING_MODE = 0x1,
+ HDMI_VP_STUFF_PR_STUFFING_DIRECT_MODE = 0x0,
+
+/* VP_CONF field values */
+ HDMI_VP_CONF_BYPASS_EN_MASK = 0x40,
+ HDMI_VP_CONF_BYPASS_EN_ENABLE = 0x40,
+ HDMI_VP_CONF_BYPASS_EN_DISABLE = 0x00,
+ HDMI_VP_CONF_PP_EN_ENMASK = 0x20,
+ HDMI_VP_CONF_PP_EN_ENABLE = 0x20,
+ HDMI_VP_CONF_PP_EN_DISABLE = 0x00,
+ HDMI_VP_CONF_PR_EN_MASK = 0x10,
+ HDMI_VP_CONF_PR_EN_ENABLE = 0x10,
+ HDMI_VP_CONF_PR_EN_DISABLE = 0x00,
+ HDMI_VP_CONF_YCC422_EN_MASK = 0x8,
+ HDMI_VP_CONF_YCC422_EN_ENABLE = 0x8,
+ HDMI_VP_CONF_YCC422_EN_DISABLE = 0x0,
+ HDMI_VP_CONF_BYPASS_SELECT_MASK = 0x4,
+ HDMI_VP_CONF_BYPASS_SELECT_VID_PACKETIZER = 0x4,
+ HDMI_VP_CONF_BYPASS_SELECT_PIX_REPEATER = 0x0,
+ HDMI_VP_CONF_OUTPUT_SELECTOR_MASK = 0x3,
+ HDMI_VP_CONF_OUTPUT_SELECTOR_BYPASS = 0x3,
+ HDMI_VP_CONF_OUTPUT_SELECTOR_YCC422 = 0x1,
+ HDMI_VP_CONF_OUTPUT_SELECTOR_PP = 0x0,
+
+/* VP_REMAP field values */
+ HDMI_VP_REMAP_MASK = 0x3,
+ HDMI_VP_REMAP_YCC422_24bit = 0x2,
+ HDMI_VP_REMAP_YCC422_20bit = 0x1,
+ HDMI_VP_REMAP_YCC422_16bit = 0x0,
+
+/* FC_INVIDCONF field values */
+ HDMI_FC_INVIDCONF_HDCP_KEEPOUT_MASK = 0x80,
+ HDMI_FC_INVIDCONF_HDCP_KEEPOUT_ACTIVE = 0x80,
+ HDMI_FC_INVIDCONF_HDCP_KEEPOUT_INACTIVE = 0x00,
+ HDMI_FC_INVIDCONF_VSYNC_IN_POLARITY_MASK = 0x40,
+ HDMI_FC_INVIDCONF_VSYNC_IN_POLARITY_ACTIVE_HIGH = 0x40,
+ HDMI_FC_INVIDCONF_VSYNC_IN_POLARITY_ACTIVE_LOW = 0x00,
+ HDMI_FC_INVIDCONF_HSYNC_IN_POLARITY_MASK = 0x20,
+ HDMI_FC_INVIDCONF_HSYNC_IN_POLARITY_ACTIVE_HIGH = 0x20,
+ HDMI_FC_INVIDCONF_HSYNC_IN_POLARITY_ACTIVE_LOW = 0x00,
+ HDMI_FC_INVIDCONF_DE_IN_POLARITY_MASK = 0x10,
+ HDMI_FC_INVIDCONF_DE_IN_POLARITY_ACTIVE_HIGH = 0x10,
+ HDMI_FC_INVIDCONF_DE_IN_POLARITY_ACTIVE_LOW = 0x00,
+ HDMI_FC_INVIDCONF_DVI_MODEZ_MASK = 0x8,
+ HDMI_FC_INVIDCONF_DVI_MODEZ_HDMI_MODE = 0x8,
+ HDMI_FC_INVIDCONF_DVI_MODEZ_DVI_MODE = 0x0,
+ HDMI_FC_INVIDCONF_R_V_BLANK_IN_OSC_MASK = 0x2,
+ HDMI_FC_INVIDCONF_R_V_BLANK_IN_OSC_ACTIVE_HIGH = 0x2,
+ HDMI_FC_INVIDCONF_R_V_BLANK_IN_OSC_ACTIVE_LOW = 0x0,
+ HDMI_FC_INVIDCONF_IN_I_P_MASK = 0x1,
+ HDMI_FC_INVIDCONF_IN_I_P_INTERLACED = 0x1,
+ HDMI_FC_INVIDCONF_IN_I_P_PROGRESSIVE = 0x0,
+
+/* FC_AUDICONF0 field values */
+ HDMI_FC_AUDICONF0_CC_OFFSET = 4,
+ HDMI_FC_AUDICONF0_CC_MASK = 0x70,
+ HDMI_FC_AUDICONF0_CT_OFFSET = 0,
+ HDMI_FC_AUDICONF0_CT_MASK = 0xF,
+
+/* FC_AUDICONF1 field values */
+ HDMI_FC_AUDICONF1_SS_OFFSET = 3,
+ HDMI_FC_AUDICONF1_SS_MASK = 0x18,
+ HDMI_FC_AUDICONF1_SF_OFFSET = 0,
+ HDMI_FC_AUDICONF1_SF_MASK = 0x7,
+
+/* FC_AUDICONF3 field values */
+ HDMI_FC_AUDICONF3_LFEPBL_OFFSET = 5,
+ HDMI_FC_AUDICONF3_LFEPBL_MASK = 0x60,
+ HDMI_FC_AUDICONF3_DM_INH_OFFSET = 4,
+ HDMI_FC_AUDICONF3_DM_INH_MASK = 0x10,
+ HDMI_FC_AUDICONF3_LSV_OFFSET = 0,
+ HDMI_FC_AUDICONF3_LSV_MASK = 0xF,
+
+/* FC_AUDSCHNLS0 field values */
+ HDMI_FC_AUDSCHNLS0_CGMSA_OFFSET = 4,
+ HDMI_FC_AUDSCHNLS0_CGMSA_MASK = 0x30,
+ HDMI_FC_AUDSCHNLS0_COPYRIGHT_OFFSET = 0,
+ HDMI_FC_AUDSCHNLS0_COPYRIGHT_MASK = 0x01,
+
+/* FC_AUDSCHNLS3-6 field values */
+ HDMI_FC_AUDSCHNLS3_OIEC_CH0_OFFSET = 0,
+ HDMI_FC_AUDSCHNLS3_OIEC_CH0_MASK = 0x0f,
+ HDMI_FC_AUDSCHNLS3_OIEC_CH1_OFFSET = 4,
+ HDMI_FC_AUDSCHNLS3_OIEC_CH1_MASK = 0xf0,
+ HDMI_FC_AUDSCHNLS4_OIEC_CH2_OFFSET = 0,
+ HDMI_FC_AUDSCHNLS4_OIEC_CH2_MASK = 0x0f,
+ HDMI_FC_AUDSCHNLS4_OIEC_CH3_OFFSET = 4,
+ HDMI_FC_AUDSCHNLS4_OIEC_CH3_MASK = 0xf0,
+
+ HDMI_FC_AUDSCHNLS5_OIEC_CH0_OFFSET = 0,
+ HDMI_FC_AUDSCHNLS5_OIEC_CH0_MASK = 0x0f,
+ HDMI_FC_AUDSCHNLS5_OIEC_CH1_OFFSET = 4,
+ HDMI_FC_AUDSCHNLS5_OIEC_CH1_MASK = 0xf0,
+ HDMI_FC_AUDSCHNLS6_OIEC_CH2_OFFSET = 0,
+ HDMI_FC_AUDSCHNLS6_OIEC_CH2_MASK = 0x0f,
+ HDMI_FC_AUDSCHNLS6_OIEC_CH3_OFFSET = 4,
+ HDMI_FC_AUDSCHNLS6_OIEC_CH3_MASK = 0xf0,
+
+/* HDMI_FC_AUDSCHNLS7 field values */
+ HDMI_FC_AUDSCHNLS7_ACCURACY_OFFSET = 4,
+ HDMI_FC_AUDSCHNLS7_ACCURACY_MASK = 0x30,
+
+/* HDMI_FC_AUDSCHNLS8 field values */
+ HDMI_FC_AUDSCHNLS8_ORIGSAMPFREQ_MASK = 0xf0,
+ HDMI_FC_AUDSCHNLS8_ORIGSAMPFREQ_OFFSET = 4,
+ HDMI_FC_AUDSCHNLS8_WORDLEGNTH_MASK = 0x0f,
+ HDMI_FC_AUDSCHNLS8_WORDLEGNTH_OFFSET = 0,
+
+/* FC_AUDSCONF field values */
+ HDMI_FC_AUDSCONF_AUD_PACKET_SAMPFIT_MASK = 0xF0,
+ HDMI_FC_AUDSCONF_AUD_PACKET_SAMPFIT_OFFSET = 4,
+ HDMI_FC_AUDSCONF_AUD_PACKET_LAYOUT_MASK = 0x1,
+ HDMI_FC_AUDSCONF_AUD_PACKET_LAYOUT_OFFSET = 0,
+ HDMI_FC_AUDSCONF_AUD_PACKET_LAYOUT_LAYOUT1 = 0x1,
+ HDMI_FC_AUDSCONF_AUD_PACKET_LAYOUT_LAYOUT0 = 0x0,
+
+/* FC_STAT2 field values */
+ HDMI_FC_STAT2_OVERFLOW_MASK = 0x03,
+ HDMI_FC_STAT2_LOW_PRIORITY_OVERFLOW = 0x02,
+ HDMI_FC_STAT2_HIGH_PRIORITY_OVERFLOW = 0x01,
+
+/* FC_INT2 field values */
+ HDMI_FC_INT2_OVERFLOW_MASK = 0x03,
+ HDMI_FC_INT2_LOW_PRIORITY_OVERFLOW = 0x02,
+ HDMI_FC_INT2_HIGH_PRIORITY_OVERFLOW = 0x01,
+
+/* FC_MASK2 field values */
+ HDMI_FC_MASK2_OVERFLOW_MASK = 0x03,
+ HDMI_FC_MASK2_LOW_PRIORITY_OVERFLOW = 0x02,
+ HDMI_FC_MASK2_HIGH_PRIORITY_OVERFLOW = 0x01,
+
+/* FC_PRCONF field values */
+ HDMI_FC_PRCONF_INCOMING_PR_FACTOR_MASK = 0xF0,
+ HDMI_FC_PRCONF_INCOMING_PR_FACTOR_OFFSET = 4,
+ HDMI_FC_PRCONF_OUTPUT_PR_FACTOR_MASK = 0x0F,
+ HDMI_FC_PRCONF_OUTPUT_PR_FACTOR_OFFSET = 0,
+
+/* FC_AVICONF0-FC_AVICONF3 field values */
+ HDMI_FC_AVICONF0_PIX_FMT_MASK = 0x03,
+ HDMI_FC_AVICONF0_PIX_FMT_RGB = 0x00,
+ HDMI_FC_AVICONF0_PIX_FMT_YCBCR422 = 0x01,
+ HDMI_FC_AVICONF0_PIX_FMT_YCBCR444 = 0x02,
+ HDMI_FC_AVICONF0_ACTIVE_FMT_MASK = 0x40,
+ HDMI_FC_AVICONF0_ACTIVE_FMT_INFO_PRESENT = 0x40,
+ HDMI_FC_AVICONF0_ACTIVE_FMT_NO_INFO = 0x00,
+ HDMI_FC_AVICONF0_BAR_DATA_MASK = 0x0C,
+ HDMI_FC_AVICONF0_BAR_DATA_NO_DATA = 0x00,
+ HDMI_FC_AVICONF0_BAR_DATA_VERT_BAR = 0x04,
+ HDMI_FC_AVICONF0_BAR_DATA_HORIZ_BAR = 0x08,
+ HDMI_FC_AVICONF0_BAR_DATA_VERT_HORIZ_BAR = 0x0C,
+ HDMI_FC_AVICONF0_SCAN_INFO_MASK = 0x30,
+ HDMI_FC_AVICONF0_SCAN_INFO_OVERSCAN = 0x10,
+ HDMI_FC_AVICONF0_SCAN_INFO_UNDERSCAN = 0x20,
+ HDMI_FC_AVICONF0_SCAN_INFO_NODATA = 0x00,
+
+ HDMI_FC_AVICONF1_ACTIVE_ASPECT_RATIO_MASK = 0x0F,
+ HDMI_FC_AVICONF1_ACTIVE_ASPECT_RATIO_USE_CODED = 0x08,
+ HDMI_FC_AVICONF1_ACTIVE_ASPECT_RATIO_4_3 = 0x09,
+ HDMI_FC_AVICONF1_ACTIVE_ASPECT_RATIO_16_9 = 0x0A,
+ HDMI_FC_AVICONF1_ACTIVE_ASPECT_RATIO_14_9 = 0x0B,
+ HDMI_FC_AVICONF1_CODED_ASPECT_RATIO_MASK = 0x30,
+ HDMI_FC_AVICONF1_CODED_ASPECT_RATIO_NO_DATA = 0x00,
+ HDMI_FC_AVICONF1_CODED_ASPECT_RATIO_4_3 = 0x10,
+ HDMI_FC_AVICONF1_CODED_ASPECT_RATIO_16_9 = 0x20,
+ HDMI_FC_AVICONF1_COLORIMETRY_MASK = 0xC0,
+ HDMI_FC_AVICONF1_COLORIMETRY_NO_DATA = 0x00,
+ HDMI_FC_AVICONF1_COLORIMETRY_SMPTE = 0x40,
+ HDMI_FC_AVICONF1_COLORIMETRY_ITUR = 0x80,
+ HDMI_FC_AVICONF1_COLORIMETRY_EXTENDED_INFO = 0xC0,
+
+ HDMI_FC_AVICONF2_SCALING_MASK = 0x03,
+ HDMI_FC_AVICONF2_SCALING_NONE = 0x00,
+ HDMI_FC_AVICONF2_SCALING_HORIZ = 0x01,
+ HDMI_FC_AVICONF2_SCALING_VERT = 0x02,
+ HDMI_FC_AVICONF2_SCALING_HORIZ_VERT = 0x03,
+ HDMI_FC_AVICONF2_RGB_QUANT_MASK = 0x0C,
+ HDMI_FC_AVICONF2_RGB_QUANT_DEFAULT = 0x00,
+ HDMI_FC_AVICONF2_RGB_QUANT_LIMITED_RANGE = 0x04,
+ HDMI_FC_AVICONF2_RGB_QUANT_FULL_RANGE = 0x08,
+ HDMI_FC_AVICONF2_EXT_COLORIMETRY_MASK = 0x70,
+ HDMI_FC_AVICONF2_EXT_COLORIMETRY_XVYCC601 = 0x00,
+ HDMI_FC_AVICONF2_EXT_COLORIMETRY_XVYCC709 = 0x10,
+ HDMI_FC_AVICONF2_EXT_COLORIMETRY_SYCC601 = 0x20,
+ HDMI_FC_AVICONF2_EXT_COLORIMETRY_ADOBE_YCC601 = 0x30,
+ HDMI_FC_AVICONF2_EXT_COLORIMETRY_ADOBE_RGB = 0x40,
+ HDMI_FC_AVICONF2_IT_CONTENT_MASK = 0x80,
+ HDMI_FC_AVICONF2_IT_CONTENT_NO_DATA = 0x00,
+ HDMI_FC_AVICONF2_IT_CONTENT_VALID = 0x80,
+
+ HDMI_FC_AVICONF3_IT_CONTENT_TYPE_MASK = 0x03,
+ HDMI_FC_AVICONF3_IT_CONTENT_TYPE_GRAPHICS = 0x00,
+ HDMI_FC_AVICONF3_IT_CONTENT_TYPE_PHOTO = 0x01,
+ HDMI_FC_AVICONF3_IT_CONTENT_TYPE_CINEMA = 0x02,
+ HDMI_FC_AVICONF3_IT_CONTENT_TYPE_GAME = 0x03,
+ HDMI_FC_AVICONF3_QUANT_RANGE_MASK = 0x0C,
+ HDMI_FC_AVICONF3_QUANT_RANGE_LIMITED = 0x00,
+ HDMI_FC_AVICONF3_QUANT_RANGE_FULL = 0x04,
+
+/* FC_DBGFORCE field values */
+ HDMI_FC_DBGFORCE_FORCEAUDIO = 0x10,
+ HDMI_FC_DBGFORCE_FORCEVIDEO = 0x1,
+
+/* PHY_CONF0 field values */
+ HDMI_PHY_CONF0_PDZ_MASK = 0x80,
+ 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_GEN2_PDDQ_MASK = 0x10,
+ HDMI_PHY_CONF0_GEN2_PDDQ_OFFSET = 4,
+ HDMI_PHY_CONF0_GEN2_TXPWRON_MASK = 0x8,
+ HDMI_PHY_CONF0_GEN2_TXPWRON_OFFSET = 3,
+ HDMI_PHY_CONF0_GEN2_ENHPDRXSENSE_MASK = 0x4,
+ HDMI_PHY_CONF0_GEN2_ENHPDRXSENSE_OFFSET = 2,
+ HDMI_PHY_CONF0_SELDATAENPOL_MASK = 0x2,
+ HDMI_PHY_CONF0_SELDATAENPOL_OFFSET = 1,
+ HDMI_PHY_CONF0_SELDIPIF_MASK = 0x1,
+ HDMI_PHY_CONF0_SELDIPIF_OFFSET = 0,
+
+/* PHY_TST0 field values */
+ HDMI_PHY_TST0_TSTCLR_MASK = 0x20,
+ HDMI_PHY_TST0_TSTCLR_OFFSET = 5,
+ HDMI_PHY_TST0_TSTEN_MASK = 0x10,
+ HDMI_PHY_TST0_TSTEN_OFFSET = 4,
+ HDMI_PHY_TST0_TSTCLK_MASK = 0x1,
+ HDMI_PHY_TST0_TSTCLK_OFFSET = 0,
+
+/* PHY_STAT0 field values */
+ HDMI_PHY_RX_SENSE3 = 0x80,
+ HDMI_PHY_RX_SENSE2 = 0x40,
+ HDMI_PHY_RX_SENSE1 = 0x20,
+ HDMI_PHY_RX_SENSE0 = 0x10,
+ HDMI_PHY_HPD = 0x02,
+ HDMI_PHY_TX_PHY_LOCK = 0x01,
+
+/* PHY_I2CM_SLAVE_ADDR field values */
+ HDMI_PHY_I2CM_SLAVE_ADDR_PHY_GEN2 = 0x69,
+ HDMI_PHY_I2CM_SLAVE_ADDR_HEAC_PHY = 0x49,
+
+/* PHY_I2CM_OPERATION_ADDR field values */
+ HDMI_PHY_I2CM_OPERATION_ADDR_WRITE = 0x10,
+ HDMI_PHY_I2CM_OPERATION_ADDR_READ = 0x1,
+
+/* HDMI_PHY_I2CM_INT_ADDR */
+ HDMI_PHY_I2CM_INT_ADDR_DONE_POL = 0x08,
+ HDMI_PHY_I2CM_INT_ADDR_DONE_MASK = 0x04,
+
+/* HDMI_PHY_I2CM_CTLINT_ADDR */
+ HDMI_PHY_I2CM_CTLINT_ADDR_NAC_POL = 0x80,
+ HDMI_PHY_I2CM_CTLINT_ADDR_NAC_MASK = 0x40,
+ HDMI_PHY_I2CM_CTLINT_ADDR_ARBITRATION_POL = 0x08,
+ HDMI_PHY_I2CM_CTLINT_ADDR_ARBITRATION_MASK = 0x04,
+
+/* AUD_CTS3 field values */
+ HDMI_AUD_CTS3_N_SHIFT_OFFSET = 5,
+ HDMI_AUD_CTS3_N_SHIFT_MASK = 0xe0,
+ HDMI_AUD_CTS3_N_SHIFT_1 = 0,
+ HDMI_AUD_CTS3_N_SHIFT_16 = 0x20,
+ HDMI_AUD_CTS3_N_SHIFT_32 = 0x40,
+ HDMI_AUD_CTS3_N_SHIFT_64 = 0x60,
+ HDMI_AUD_CTS3_N_SHIFT_128 = 0x80,
+ HDMI_AUD_CTS3_N_SHIFT_256 = 0xa0,
+ /* note that the CTS3 MANUAL bit has been removed
+ from our part. Can't set it, will read as 0. */
+ HDMI_AUD_CTS3_CTS_MANUAL = 0x10,
+ HDMI_AUD_CTS3_AUDCTS19_16_MASK = 0x0f,
+
+/* AHB_DMA_CONF0 field values */
+ HDMI_AHB_DMA_CONF0_SW_FIFO_RST_OFFSET = 7,
+ HDMI_AHB_DMA_CONF0_SW_FIFO_RST_MASK = 0x80,
+ HDMI_AHB_DMA_CONF0_HBR = 0x10,
+ HDMI_AHB_DMA_CONF0_EN_HLOCK_OFFSET = 3,
+ HDMI_AHB_DMA_CONF0_EN_HLOCK_MASK = 0x08,
+ HDMI_AHB_DMA_CONF0_INCR_TYPE_OFFSET = 1,
+ HDMI_AHB_DMA_CONF0_INCR_TYPE_MASK = 0x06,
+ HDMI_AHB_DMA_CONF0_INCR4 = 0x0,
+ HDMI_AHB_DMA_CONF0_INCR8 = 0x2,
+ HDMI_AHB_DMA_CONF0_INCR16 = 0x4,
+ HDMI_AHB_DMA_CONF0_BURST_MODE = 0x1,
+
+/* HDMI_AHB_DMA_START field values */
+ HDMI_AHB_DMA_START_START_OFFSET = 0,
+ HDMI_AHB_DMA_START_START_MASK = 0x01,
+
+/* HDMI_AHB_DMA_STOP field values */
+ HDMI_AHB_DMA_STOP_STOP_OFFSET = 0,
+ HDMI_AHB_DMA_STOP_STOP_MASK = 0x01,
+
+/* AHB_DMA_STAT, AHB_DMA_INT, AHB_DMA_MASK, AHB_DMA_POL field values */
+ HDMI_AHB_DMA_DONE = 0x80,
+ HDMI_AHB_DMA_RETRY_SPLIT = 0x40,
+ HDMI_AHB_DMA_LOSTOWNERSHIP = 0x20,
+ HDMI_AHB_DMA_ERROR = 0x10,
+ HDMI_AHB_DMA_FIFO_THREMPTY = 0x04,
+ HDMI_AHB_DMA_FIFO_FULL = 0x02,
+ HDMI_AHB_DMA_FIFO_EMPTY = 0x01,
+
+/* AHB_DMA_BUFFSTAT, AHB_DMA_BUFFINT, AHB_DMA_BUFFMASK, AHB_DMA_BUFFPOL field values */
+ HDMI_AHB_DMA_BUFFSTAT_FULL = 0x02,
+ HDMI_AHB_DMA_BUFFSTAT_EMPTY = 0x01,
+
+/* MC_CLKDIS field values */
+ HDMI_MC_CLKDIS_HDCPCLK_DISABLE = 0x40,
+ HDMI_MC_CLKDIS_CECCLK_DISABLE = 0x20,
+ HDMI_MC_CLKDIS_CSCCLK_DISABLE = 0x10,
+ HDMI_MC_CLKDIS_AUDCLK_DISABLE = 0x8,
+ HDMI_MC_CLKDIS_PREPCLK_DISABLE = 0x4,
+ HDMI_MC_CLKDIS_TMDSCLK_DISABLE = 0x2,
+ HDMI_MC_CLKDIS_PIXELCLK_DISABLE = 0x1,
+
+/* MC_SWRSTZ field values */
+ HDMI_MC_SWRSTZ_TMDSSWRST_REQ = 0x02,
+
+/* MC_FLOWCTRL field values */
+ HDMI_MC_FLOWCTRL_FEED_THROUGH_OFF_MASK = 0x1,
+ HDMI_MC_FLOWCTRL_FEED_THROUGH_OFF_CSC_IN_PATH = 0x1,
+ HDMI_MC_FLOWCTRL_FEED_THROUGH_OFF_CSC_BYPASS = 0x0,
+
+/* MC_PHYRSTZ field values */
+ HDMI_MC_PHYRSTZ_ASSERT = 0x0,
+ HDMI_MC_PHYRSTZ_DEASSERT = 0x1,
+
+/* MC_HEACPHY_RST field values */
+ HDMI_MC_HEACPHY_RST_ASSERT = 0x1,
+ HDMI_MC_HEACPHY_RST_DEASSERT = 0x0,
+
+/* CSC_CFG field values */
+ HDMI_CSC_CFG_INTMODE_MASK = 0x30,
+ HDMI_CSC_CFG_INTMODE_OFFSET = 4,
+ HDMI_CSC_CFG_INTMODE_DISABLE = 0x00,
+ HDMI_CSC_CFG_INTMODE_CHROMA_INT_FORMULA1 = 0x10,
+ HDMI_CSC_CFG_INTMODE_CHROMA_INT_FORMULA2 = 0x20,
+ HDMI_CSC_CFG_DECMODE_MASK = 0x3,
+ HDMI_CSC_CFG_DECMODE_OFFSET = 0,
+ HDMI_CSC_CFG_DECMODE_DISABLE = 0x0,
+ HDMI_CSC_CFG_DECMODE_CHROMA_INT_FORMULA1 = 0x1,
+ HDMI_CSC_CFG_DECMODE_CHROMA_INT_FORMULA2 = 0x2,
+ HDMI_CSC_CFG_DECMODE_CHROMA_INT_FORMULA3 = 0x3,
+
+/* CSC_SCALE field values */
+ HDMI_CSC_SCALE_CSC_COLORDE_PTH_MASK = 0xF0,
+ HDMI_CSC_SCALE_CSC_COLORDE_PTH_24BPP = 0x00,
+ HDMI_CSC_SCALE_CSC_COLORDE_PTH_30BPP = 0x50,
+ HDMI_CSC_SCALE_CSC_COLORDE_PTH_36BPP = 0x60,
+ HDMI_CSC_SCALE_CSC_COLORDE_PTH_48BPP = 0x70,
+ HDMI_CSC_SCALE_CSCSCALE_MASK = 0x03,
+
+/* I2CM_OPERATION field values */
+ HDMI_I2CM_OPERATION_WRITE = 0x10,
+ HDMI_I2CM_OPERATION_READ_EXT = 0x2,
+ HDMI_I2CM_OPERATION_READ = 0x1,
+
+/* HDMI_I2CM_INT */
+ HDMI_I2CM_INT_DONE_POL = 0x08,
+ HDMI_I2CM_INT_DONE_MASK = 0x04,
+
+/* HDMI_I2CM_CTLINT */
+ HDMI_I2CM_CTLINT_NAC_POL = 0x80,
+ HDMI_I2CM_CTLINT_NAC_MASK = 0x40,
+ HDMI_I2CM_CTLINT_ARBITRATION_POL = 0x08,
+ HDMI_I2CM_CTLINT_ARBITRATION_MASK = 0x04,
+
+};
+
+enum imx_hdmi_type {
+ IMX6DL_HDMI,
+ IMX6Q_HDMI,
+};
+
+/* IOCTL commands */
+#define HDMI_IOC_MAGIC 'H'
+
+#define HDMI_IOC_GET_RESOURCE _IO(HDMI_IOC_MAGIC, 0)
+#define HDMI_IOC_GET_CPU_TYPE _IO(HDMI_IOC_MAGIC, 1)
+
+
+#endif /* __MXC_HDMI_H__ */
diff --git a/include/video/viv-metadata.h b/include/video/viv-metadata.h
new file mode 100644
index 000000000000..d08680a4308e
--- /dev/null
+++ b/include/video/viv-metadata.h
@@ -0,0 +1,116 @@
+/****************************************************************************
+*
+* The MIT License (MIT)
+*
+* Copyright (c) 2014 - 2018 Vivante 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 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 GPL License (GPL)
+*
+* Copyright (C) 2014 - 2018 Vivante 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.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+*****************************************************************************
+*
+* Note: This software is released under dual MIT and GPL licenses. A
+* recipient may use this file under the terms of either the MIT license or
+* GPL License. If you wish to use only one license not the other, you can
+* indicate your decision by deleting one of the above license notices in your
+* version of this file.
+*
+*****************************************************************************/
+
+#ifndef __VIV_METADATA_H__
+#define __VIV_METADATA_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Macro to combine four characters into a Character Code. */
+#define __FOURCC(a, b, c, d) \
+ ((uint32_t)(a) | ((uint32_t)(b) << 8) | ((uint32_t)(c) << 16) | ((uint32_t)(d) << 24))
+
+#define VIV_VIDMEM_METADATA_MAGIC __FOURCC('v', 'i', 'v', 'm')
+
+/* Compressed format now was defined same as dec400d, should be general. */
+typedef enum _VIV_COMPRESS_FMT
+{
+ _VIV_CFMT_ARGB8 = 0,
+ _VIV_CFMT_XRGB8,
+ _VIV_CFMT_AYUV,
+ _VIV_CFMT_UYVY,
+ _VIV_CFMT_YUY2,
+ _VIV_CFMT_YUV_ONLY,
+ _VIV_CFMT_UV_MIX,
+ _VIV_CFMT_ARGB4,
+ _VIV_CFMT_XRGB4,
+ _VIV_CFMT_A1R5G5B5,
+ _VIV_CFMT_X1R5G5B5,
+ _VIV_CFMT_R5G6B5,
+ _VIV_CFMT_Z24S8,
+ _VIV_CFMT_Z24,
+ _VIV_CFMT_Z16,
+ _VIV_CFMT_A2R10G10B10,
+ _VIV_CFMT_BAYER,
+ _VIV_CFMT_SIGNED_BAYER,
+ _VIV_CFMT_VAA16,
+ _VIV_CFMT_S8,
+
+ _VIV_CFMT_MAX,
+} _VIV_COMPRESS_FMT;
+
+/* Metadata for cross-device fd share with additional (ts) info. */
+typedef struct _VIV_VIDMEM_METADATA
+{
+ uint32_t magic;
+
+ int32_t ts_fd;
+ void * ts_dma_buf;
+
+ uint32_t fc_enabled;
+ uint32_t fc_value;
+ uint32_t fc_value_upper;
+
+ uint32_t compressed;
+ uint32_t compress_format;
+} _VIV_VIDMEM_METADATA;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __VIV_METADATA_H__ */
+
diff --git a/include/xen/interface/io/i2cif.h b/include/xen/interface/io/i2cif.h
new file mode 100644
index 000000000000..36e9024a1b04
--- /dev/null
+++ b/include/xen/interface/io/i2cif.h
@@ -0,0 +1,95 @@
+/******************************************************************************
+ * i2cif.h
+ *
+ * I2C device I/O interface for Xen guest OSes.
+ *
+ * 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.
+ *
+ * Copyright 2018 NXP
+ *
+ * Authors: Peng Fan <peng.fan@nxp.com>
+ */
+
+#ifndef __XEN_PUBLIC_IO_I2CIF_H__
+#define __XEN_PUBLIC_IO_I2CIF_H__
+
+#include <xen/interface/io/ring.h>
+#include <xen/interface/grant_table.h>
+
+#define I2CIF_BUF_LEN I2C_SMBUS_BLOCK_MAX + 2
+#define I2CIF_MAX_MSG 2
+
+#define I2CIF_M_RD 0x0001 /* read data, from slave to master */
+ /* I2C_M_RD is guaranteed to be 0x0001! */
+#define I2CIF_M_TEN 0x0010 /* this is a ten bit chip address */
+#define I2CIF_M_RECV_LEN 0x0400 /* length will be first received byte */
+#define I2CIF_M_NO_RD_ACK 0x0800 /* if I2CIF_FUNC_PROTOCOL_MANGLING */
+#define I2CIF_M_IGNORE_NAK 0x1000 /* if I2CIF_FUNC_PROTOCOL_MANGLING */
+#define I2CIF_M_REV_DIR_ADDR 0x2000 /* if I2CIF_FUNC_PROTOCOL_MANGLING */
+#define I2CIF_M_NOSTART 0x4000 /* if I2CIF_FUNC_NOSTART */
+#define I2CIF_M_STOP 0x8000 /* if I2CIF_FUNC_PROTOCOL_MANGLING */
+
+#define I2CIF_FUNC_I2C 0x00000001
+#define I2CIF_FUNC_10BIT_ADDR 0x00000002
+#define I2CIF_FUNC_PROTOCOL_MANGLING 0x00000004 /* I2C_M_IGNORE_NAK etc. */
+#define I2CIF_FUNC_SMBUS_PEC 0x00000008
+#define I2CIF_FUNC_NOSTART 0x00000010 /* I2C_M_NOSTART */
+#define I2CIF_FUNC_SLAVE 0x00000020
+#define I2CIF_FUNC_SMBUS_BLOCK_PROC_CALL 0x00008000 /* SMBus 2.0 */
+#define I2CIF_FUNC_SMBUS_QUICK 0x00010000
+#define I2CIF_FUNC_SMBUS_READ_BYTE 0x00020000
+#define I2CIF_FUNC_SMBUS_WRITE_BYTE 0x00040000
+#define I2CIF_FUNC_SMBUS_READ_BYTE_DATA 0x00080000
+#define I2CIF_FUNC_SMBUS_WRITE_BYTE_DATA 0x00100000
+#define I2CIF_FUNC_SMBUS_READ_WORD_DATA 0x00200000
+#define I2CIF_FUNC_SMBUS_WRITE_WORD_DATA 0x00400000
+#define I2CIF_FUNC_SMBUS_PROC_CALL 0x00800000
+#define I2CIF_FUNC_SMBUS_READ_BLOCK_DATA 0x01000000
+#define I2CIF_FUNC_SMBUS_WRITE_BLOCK_DATA 0x02000000
+#define I2CIF_FUNC_SMBUS_READ_I2C_BLOCK 0x04000000 /* I2C-like block xfer */
+#define I2CIF_FUNC_SMBUS_WRITE_I2C_BLOCK 0x08000000 /* w/ 1-byte reg. addr. */
+#define I2CIF_FUNC_SMBUS_HOST_NOTIFY 0x10000000
+
+#define I2CIF_ADAPTER_NAME_LEN 32
+
+struct i2cif_request {
+ struct {
+ __u16 addr; /* slave address */
+ __u16 flags; /* msg flags */
+ __u16 len; /* msg length */
+ } msg[I2CIF_MAX_MSG];
+ int num_msg;
+ __u8 write_buf[I2CIF_BUF_LEN];
+
+ bool is_smbus;
+ __u16 addr;
+ __u16 flags;
+ __u8 read_write;
+ __u8 command;
+ int protocol;
+};
+
+struct i2cif_response {
+ int result;
+ __u8 read_buf[I2CIF_BUF_LEN];
+};
+
+DEFINE_RING_TYPES(i2cif, struct i2cif_request, struct i2cif_response);
+
+#endif
diff --git a/kernel/sched/cpufreq_schedutil.c b/kernel/sched/cpufreq_schedutil.c
index f8c45d30ec6d..eae7db21dc04 100644
--- a/kernel/sched/cpufreq_schedutil.c
+++ b/kernel/sched/cpufreq_schedutil.c
@@ -409,15 +409,15 @@ static inline struct sugov_tunables *to_sugov_tunables(struct gov_attr_set *attr
return container_of(attr_set, struct sugov_tunables, attr_set);
}
-static ssize_t rate_limit_us_show(struct gov_attr_set *attr_set, char *buf)
+static ssize_t show_rate_limit_us(struct gov_attr_set *attr_set, char *buf)
{
struct sugov_tunables *tunables = to_sugov_tunables(attr_set);
return sprintf(buf, "%u\n", tunables->rate_limit_us);
}
-static ssize_t rate_limit_us_store(struct gov_attr_set *attr_set, const char *buf,
- size_t count)
+static ssize_t store_rate_limit_us(struct gov_attr_set *attr_set,
+ const char *buf, size_t count)
{
struct sugov_tunables *tunables = to_sugov_tunables(attr_set);
struct sugov_policy *sg_policy;
@@ -434,7 +434,7 @@ static ssize_t rate_limit_us_store(struct gov_attr_set *attr_set, const char *bu
return count;
}
-static struct governor_attr rate_limit_us = __ATTR_RW(rate_limit_us);
+gov_attr_rw(rate_limit_us);
static struct attribute *sugov_attributes[] = {
&rate_limit_us.attr,
diff --git a/kernel/time/clockevents.c b/kernel/time/clockevents.c
index 4237e0744e26..16c027e9cc73 100644
--- a/kernel/time/clockevents.c
+++ b/kernel/time/clockevents.c
@@ -280,17 +280,22 @@ static int clockevents_program_min_delta(struct clock_event_device *dev)
static int clockevents_program_min_delta(struct clock_event_device *dev)
{
unsigned long long clc;
- int64_t delta;
+ int64_t delta = 0;
+ int i;
- delta = dev->min_delta_ns;
- dev->next_event = ktime_add_ns(ktime_get(), delta);
+ for (i = 0; i < 10; i++) {
+ delta += dev->min_delta_ns;
+ dev->next_event = ktime_add_ns(ktime_get(), delta);
- if (clockevent_state_shutdown(dev))
- return 0;
+ if (clockevent_state_shutdown(dev))
+ return 0;
- dev->retries++;
- clc = ((unsigned long long) delta * dev->mult) >> dev->shift;
- return dev->set_next_event((unsigned long) clc, dev);
+ dev->retries++;
+ clc = ((unsigned long long) delta * dev->mult) >> dev->shift;
+ if (dev->set_next_event((unsigned long) clc, dev) == 0)
+ return 0;
+ }
+ return -ETIME;
}
#endif /* CONFIG_GENERIC_CLOCKEVENTS_MIN_ADJUST */
diff --git a/mm/page_io.c b/mm/page_io.c
index 5d882de3fbfd..cd52b9cc169b 100644
--- a/mm/page_io.c
+++ b/mm/page_io.c
@@ -408,7 +408,7 @@ int swap_readpage(struct page *page, bool do_poll)
if (!READ_ONCE(bio->bi_private))
break;
- if (!blk_mq_poll(disk->queue, qc))
+ if (!blk_poll(disk->queue, qc))
break;
}
__set_current_state(TASK_RUNNING);
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c
index 8c329c549ea6..49bee4fa7636 100644
--- a/net/bluetooth/l2cap_sock.c
+++ b/net/bluetooth/l2cap_sock.c
@@ -794,8 +794,11 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname,
/*change security for LE channels */
if (chan->scid == L2CAP_CID_ATT) {
- if (smp_conn_security(conn->hcon, sec.level))
+ if (smp_conn_security(conn->hcon, sec.level)) {
+ err = -EINVAL;
break;
+ }
+
set_bit(FLAG_PENDING_SECURITY, &chan->flags);
sk->sk_state = BT_CONFIG;
chan->state = BT_CONFIG;
diff --git a/net/wireless/chan.c b/net/wireless/chan.c
index fad1b5baf8ff..5347f33320a7 100644
--- a/net/wireless/chan.c
+++ b/net/wireless/chan.c
@@ -710,7 +710,8 @@ static bool cfg80211_secondary_chans_ok(struct wiphy *wiphy,
for (freq = start_freq; freq <= end_freq; freq += 20) {
c = ieee80211_get_channel(wiphy, freq);
- if (!c || c->flags & prohibited_flags)
+ if (!c || ((c->flags & prohibited_flags) &&
+ !(wiphy->flags & WIPHY_FLAG_DFS_OFFLOAD)))
return false;
}
diff --git a/net/wireless/db.txt b/net/wireless/db.txt
index a2fc3a09ccdc..0b34e7ab4d0e 100644
--- a/net/wireless/db.txt
+++ b/net/wireless/db.txt
@@ -1,17 +1,1305 @@
+# This is the world regulatory domain
+country 00:
+ (2402 - 2472 @ 40), (20)
+ # Channel 12 - 13.
+ (2457 - 2482 @ 20), (20), NO-IR, AUTO-BW
+ # Channel 14. Only JP enables this and for 802.11b only
+ (2474 - 2494 @ 20), (20), NO-IR, NO-OFDM
+ # Channel 36 - 48
+ (5170 - 5250 @ 80), (20), NO-IR, AUTO-BW
+ # Channel 52 - 64
+ (5250 - 5330 @ 80), (20), NO-IR, DFS, AUTO-BW
+ # Channel 100 - 144
+ (5490 - 5730 @ 160), (20), NO-IR, DFS
+ # Channel 149 - 165
+ (5735 - 5835 @ 80), (20), NO-IR
+ # IEEE 802.11ad (60GHz), channels 1..3
+ (57240 - 63720 @ 2160), (0)
+
+
+country AD:
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20)
+ (5250 - 5330 @ 80), (20), DFS
+ (5490 - 5710 @ 80), (27), DFS
+ # 60 GHz band channels 1-4, ref: Etsi En 302 567
+ (57000 - 66000 @ 2160), (40)
+
+country AE: DFS-FCC
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (17), AUTO-BW
+ (5250 - 5330 @ 80), (24), DFS, AUTO-BW
+ (5490 - 5730 @ 160), (24), DFS
+ (5735 - 5835 @ 80), (30)
+
+country AF: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (27), DFS
+
+# Source:
+# http://pucanguilla.org/Downloads/January2005-Anguilla%20Table%20of%20Allocations.pdf
+country AI: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (27), DFS
+
+country AL: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20.00), AUTO-BW
+ (5250 - 5330 @ 80), (20.00), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (27.00), DFS
+
+country AM: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 20), (18)
+ (5250 - 5330 @ 20), (18), DFS
+
+country AN: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (27), DFS
+
+country AR: DFS-FCC
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (17), AUTO-BW
+ (5250 - 5330 @ 80), (24), DFS, AUTO-BW
+ (5490 - 5730 @ 160), (24), DFS
+ (5735 - 5835 @ 80), (30)
+
+country AS: DFS-FCC
+ (2402 - 2472 @ 40), (30)
+ (5170 - 5250 @ 80), (24), AUTO-BW
+ (5250 - 5330 @ 80), (24), DFS, AUTO-BW
+ (5490 - 5730 @ 160), (24), DFS
+ (5735 - 5835 @ 80), (30)
+
+country AT: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (27), DFS
+ # 60 GHz band channels 1-4, ref: Etsi En 302 567
+ (57000 - 66000 @ 2160), (40)
+
+country AU: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (17), AUTO-BW
+ (5250 - 5330 @ 80), (24), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (24), DFS
+ (5735 - 5835 @ 80), (30)
+
+country AW: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (27), DFS
+
+country AZ: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (18), AUTO-BW
+ (5250 - 5330 @ 80), (18), DFS, AUTO-BW
+
+country BA: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (27), DFS
+ # 60 GHz band channels 1-4, ref: Etsi En 302 567
+ (57000 - 66000 @ 2160), (40)
+
+country BB: DFS-FCC
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (23), AUTO-BW
+ (5250 - 5330 @ 80), (23), DFS, AUTO-BW
+ (5735 - 5835 @ 80), (30)
+
+country BD: DFS-JP
+ (2402 - 2482 @ 40), (20)
+ (5735 - 5835 @ 80), (30)
+
+country BE: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (27), DFS
+ # 60 GHz band channels 1-4, ref: Etsi En 302 567
+ (57000 - 66000 @ 2160), (40)
+
+country BF: DFS-FCC
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (17), AUTO-BW
+ (5250 - 5330 @ 80), (24), DFS, AUTO-BW
+ (5490 - 5730 @ 160), (24), DFS
+ (5735 - 5835 @ 80), (30)
+
+# Bulgarian rules as defined by the Communications Regulation Commission in the
+# following documents:
#
-# This file is a placeholder to prevent accidental build breakage if someone
-# enables CONFIG_CFG80211_INTERNAL_REGDB. Almost no one actually needs to
-# enable that build option.
+# Rules for carrying out electronic communications through radio equipment using
+# radio spectrum, which does not need to be individually assigned (the Rules):
+# http://www.crc.bg/files/_bg/Pravila_09_06_2015.pdf
#
-# You should be using CRDA instead. It is even better if you use the CRDA
-# package provided by your distribution, since they will probably keep it
-# up-to-date on your behalf.
+# List of radio equipment that uses harmonized within the European Union bands
+# and electronic communications terminal equipment (the List):
+# http://www.crc.bg/files/_bg/Spisak_2015.pdf
#
-# If you _really_ intend to use CONFIG_CFG80211_INTERNAL_REGDB then you will
-# need to replace this file with one containing appropriately formatted
-# regulatory rules that cover the regulatory domains you will be using. Your
-# best option is to extract the db.txt file from the wireless-regdb git
-# repository:
+# Note: The transmit power limits in the 5250-5350 MHz and 5470-5725 MHz bands
+# can be raised by 3 dBm if TPC is enabled. Refer to BDS EN 301 893 for details.
+country BG: DFS-ETSI
+ # Wideband data transmission systems (WDTS) in the 2.4GHz ISM band, ref:
+ # I.22 of the List, BDS EN 300 328
+ (2402 - 2482 @ 40), (20)
+ # 5 GHz Radio Local Area Networks (RLANs), ref:
+ # II.H01 of the List, BDS EN 301 893
+ (5170 - 5250 @ 80), (23), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ # II.H01 of the List, I.54 from the List, BDS EN 301 893
+ (5490 - 5710 @ 160), (27), DFS
+ # Short range devices (SRDs) in the 5725-5875 MHz frequency range, ref:
+ # I.43 of the List, BDS EN 300 440-2, BDS EN 300 440-1
+ (5725 - 5875 @ 80), (14)
+ # 60 GHz Multiple-Gigabit RLAN Systems, ref:
+ # II.H03 of the List, BDS EN 302 567-2
+ (57000 - 66000 @ 2160), (40), NO-OUTDOOR
+
+country BH: DFS-JP
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 20), (20)
+ (5250 - 5330 @ 20), (20), DFS
+ (5735 - 5835 @ 20), (20)
+
+country BL: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (27), DFS
+
+country BM: DFS-FCC
+ (2402 - 2472 @ 40), (30)
+ (5170 - 5250 @ 80), (24), AUTO-BW
+ (5250 - 5330 @ 80), (24), DFS, AUTO-BW
+ (5490 - 5730 @ 160), (24), DFS
+ (5735 - 5835 @ 80), (30)
+
+country BN: DFS-JP
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5735 - 5835 @ 80), (20)
+
+country BO: DFS-JP
+ (2402 - 2482 @ 40), (20)
+ (5250 - 5330 @ 80), (30), DFS
+ (5735 - 5835 @ 80), (30)
+
+country BR: DFS-FCC
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (17), AUTO-BW
+ (5250 - 5330 @ 80), (24), DFS, AUTO-BW
+ (5490 - 5730 @ 160), (24), DFS
+ (5735 - 5835 @ 80), (30)
+
+country BS: DFS-FCC
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (24), AUTO-BW
+ (5250 - 5330 @ 80), (24), DFS, AUTO-BW
+ (5490 - 5730 @ 160), (24), DFS
+ (5735 - 5835 @ 80), (30)
+
+# Source:
+# http://www.bicma.gov.bt/paper/publication/nrrpart4.pdf
+country BT: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (27), DFS
+
+country BY: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (27), DFS
+
+country BZ: DFS-JP
+ (2402 - 2482 @ 40), (30)
+ (5735 - 5835 @ 80), (30)
+
+country CA: DFS-FCC
+ (2402 - 2472 @ 40), (30)
+ (5170 - 5250 @ 80), (17), AUTO-BW
+ (5250 - 5330 @ 80), (24), DFS, AUTO-BW
+ (5490 - 5600 @ 80), (24), DFS
+ (5650 - 5730 @ 80), (24), DFS
+ (5735 - 5835 @ 80), (30)
+
+# Source:
+# http://www.art-rca.org
+country CF: DFS-FCC
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 40), (17)
+ (5250 - 5330 @ 40), (24), DFS
+ (5490 - 5730 @ 40), (24), DFS
+ (5735 - 5835 @ 40), (30)
+
+country CH: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (27), DFS
+ # 60 GHz band channels 1-4, ref: Etsi En 302 567
+ (57000 - 66000 @ 2160), (40)
+
+country CI: DFS-FCC
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (17), AUTO-BW
+ (5250 - 5330 @ 80), (24), DFS, AUTO-BW
+ (5490 - 5730 @ 160), (24), DFS
+ (5735 - 5835 @ 80), (30)
+
+country CL: DFS-JP
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5735 - 5835 @ 80), (20)
+
+country CN: DFS-FCC
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (23), AUTO-BW
+ (5250 - 5330 @ 80), (23), DFS, AUTO-BW
+ (5735 - 5835 @ 80), (30)
+ # 60 GHz band channels 1,4: 28dBm, channels 2,3: 44dBm
+ # ref: http://www.miit.gov.cn/n11293472/n11505629/n11506593/n11960250/n11960606/n11960700/n12330791.files/n12330790.pdf
+ (57240 - 59400 @ 2160), (28)
+ (59400 - 63720 @ 2160), (44)
+ (63720 - 65880 @ 2160), (28)
+
+country CO: DFS-FCC
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (17), AUTO-BW
+ (5250 - 5330 @ 80), (24), DFS, AUTO-BW
+ (5490 - 5730 @ 160), (24), DFS
+ (5735 - 5835 @ 80), (30)
+
+country CR: DFS-FCC
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 20), (17)
+ (5250 - 5330 @ 20), (24), DFS
+ (5490 - 5730 @ 20), (24), DFS
+ (5735 - 5835 @ 20), (30)
+
+# http://www.mincom.gob.cu/?q=marcoregulatorio
+# - Redes Informáticas
+# Resolución 127, 2011 - Reglamento Banda 2,4 GHz.
+country CU: DFS-FCC
+ (2400 - 2483.5 @ 40), (200 mW)
+
+country CX: DFS-FCC
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (24), AUTO-BW
+ (5250 - 5330 @ 80), (24), DFS, AUTO-BW
+ (5490 - 5730 @ 160), (24), DFS
+ (5735 - 5835 @ 80), (30)
+
+country CY: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (27), DFS
+ # 60 GHz band channels 1-4, ref: Etsi En 302 567
+ (57000 - 66000 @ 2160), (40)
+
+# Data from http://www.ctu.eu/164/download/VOR/VOR-12-08-2005-34.pdf
+# and http://www.ctu.eu/164/download/VOR/VOR-12-05-2007-6-AN.pdf
+# Power at 5250 - 5350 MHz and 5470 - 5725 MHz can be doubled if TPC is
+# implemented.
+country CZ: DFS-ETSI
+ (2400 - 2483.5 @ 40), (100 mW)
+ (5150 - 5250 @ 80), (200 mW), NO-OUTDOOR, AUTO-BW
+ (5250 - 5350 @ 80), (100 mW), NO-OUTDOOR, DFS, AUTO-BW
+ (5470 - 5725 @ 160), (500 mW), DFS
+ # 60 GHz band channels 1-4, ref: Etsi En 302 567
+ (57000 - 66000 @ 2160), (40)
+
+# Allocation for the 2.4 GHz band (Vfg 10 / 2013, Allgemeinzuteilung von
+# Frequenzen für die Nutzung in lokalen Netzwerken; Wireless Local Area
+# Networks (WLAN-Funkanwendungen).
+# https://www.bundesnetzagentur.de/SharedDocs/Downloads/DE/Sachgebiete/Telekommunikation/Unternehmen_Institutionen/Frequenzen/Allgemeinzuteilungen/2013_10_WLAN_2,4GHz_pdf.pdf
#
-# git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-regdb.git
+# Allocation for the 5 GHz band (Vfg. 7 / 2010, Allgemeinzuteilung von
+# Frequenzen in den Bereichen 5150 MHz - 5350 MHz und 5470 MHz - 5725 MHz für
+# Funkanwendungen zur breitbandigen Datenübertragung, WAS/WLAN („Wireless
+# Access Systems including Wireless Local Area Networks“).
+# https://www.bundesnetzagentur.de/SharedDocs/Downloads/DE/Sachgebiete/Telekommunikation/Unternehmen_Institutionen/Frequenzen/Allgemeinzuteilungen/2010_07_WLAN_5GHz_pdf.pdf
+# The values for the 5 GHz have been reduced by a factor of 2 (3db) for non TPC
+# devices (in other words: devices with TPC can use twice the tx power of this
+# table). Note that the docs do not require TPC for 5150--5250; the reduction
+# to 100mW thus is not strictly required -- however the conservative 100mW
+# limit is used here as the non-interference with radar and satellite
+# apps relies on the attenuation by the building walls only in the
+# absence of DFS; the neighbour countries have 100mW limit here as well.
#
+# The ETSI EN 300 440-1 standard for short range devices in the 5 GHz band has
+# been implemented in Germany:
+# https://www.bundesnetzagentur.de/SharedDocs/Downloads/DE/Sachgebiete/Telekommunikation/Unternehmen_Institutionen/Frequenzen/Allgemeinzuteilungen/2014_69_SRD_pdf.pdf
+#
+# Allocation for the 60 GHz band (Allgemeinzuteilung von Frequenzen im
+# Bereich 57 GHz - 66 GHz für Funkanwendungen für weitbandige
+# Datenübertragungssysteme; „Multiple Gigabit WAS/RLAN Systems (MGWS)“).
+# https://www.bundesnetzagentur.de/SharedDocs/Downloads/DE/Sachgebiete/Telekommunikation/Unternehmen_Institutionen/Frequenzen/Allgemeinzuteilungen/2011_08_MGWS_pdf.pdf
+
+country DE: DFS-ETSI
+ (2400 - 2483.5 @ 40), (100 mW)
+ (5150 - 5250 @ 80), (100 mW), NO-OUTDOOR, AUTO-BW
+ (5250 - 5350 @ 80), (100 mW), NO-OUTDOOR, DFS, AUTO-BW
+ (5470 - 5725 @ 160), (500 mW), DFS
+ # short range devices (ETSI EN 300 440-1)
+ (5725 - 5875 @ 80), (25 mW)
+ # 60 GHz band channels 1-4 (ETSI EN 302 567)
+ (57000 - 66000 @ 2160), (40)
+
+country DK: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (27), DFS
+ # 60 GHz band channels 1-4, ref: Etsi En 302 567
+ (57000 - 66000 @ 2160), (40)
+
+# Source:
+# http://www.ntrcdom.org/index.php?option=com_content&view=category&layout=blog&id=10&Itemid=55
+country DM: DFS-FCC
+ (2402 - 2472 @ 40), (30)
+ (5170 - 5250 @ 80), (17), AUTO-BW
+ (5250 - 5330 @ 80), (23), DFS, AUTO-BW
+ (5735 - 5835 @ 80), (30)
+
+country DO: DFS-FCC
+ (2402 - 2472 @ 40), (30)
+ (5170 - 5250 @ 80), (17), AUTO-BW
+ (5250 - 5330 @ 80), (23), DFS, AUTO-BW
+ (5735 - 5835 @ 80), (30)
+
+country DZ: DFS-JP
+ (2402 - 2482 @ 40), (20)
+ (5170.000 - 5250.000 @ 80.000), (23.00), AUTO-BW
+ (5250.000 - 5330.000 @ 80.000), (23.00), DFS, AUTO-BW
+ (5490.000 - 5670.000 @ 160.000), (23.00), DFS
+
+country EC: DFS-FCC
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 20), (17)
+ (5250 - 5330 @ 20), (24), DFS
+ (5490 - 5730 @ 20), (24), DFS
+ (5735 - 5835 @ 20), (30)
+
+country EE: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (27), DFS
+ # 60 GHz band channels 1-4, ref: Etsi En 302 567
+ (57000 - 66000 @ 2160), (40)
+
+country EG: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 40), (20)
+ (5250 - 5330 @ 40), (20), DFS
+
+# Orden IET/787/2013, de 25 de abril, por la que se aprueba
+# el cuadro nacional de atribución de frecuencias.
+# http://www.boe.es/diario_boe/txt.php?id=BOE-A-2013-4845
+#
+# more info at "Cuadro nacional de atribución de frecuencias (CNAF)":
+# http://www.minetur.gob.es/telecomunicaciones/espectro/paginas/cnaf.aspx
+
+country ES: DFS-ETSI
+ (2400 - 2483.5 @ 40), (100 mW)
+ (5150 - 5250 @ 80), (200 mW), NO-OUTDOOR, AUTO-BW
+ (5250 - 5350 @ 80), (100 mW), NO-OUTDOOR, DFS, AUTO-BW
+ (5470 - 5725 @ 160), (500 mW), DFS
+ # 60 GHz band channels 1-4, ref: Etsi En 302 567
+ (57000 - 66000 @ 2160), (40)
+
+country ET: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (27), DFS
+
+country FI: DFS-ETSI
+ (2400 - 2483.5 @ 40), (20)
+ (5150 - 5250 @ 80), (23), NO-OUTDOOR, AUTO-BW
+ (5250 - 5350 @ 80), (20), NO-OUTDOOR, DFS, AUTO-BW
+ (5470 - 5725 @ 160), (27), DFS
+ # 60 GHz band channels 1-4, ref: Etsi En 302 567
+ (57000 - 66000 @ 2160), (40)
+
+country FM: DFS-FCC
+ (2402 - 2472 @ 40), (30)
+ (5170 - 5250 @ 80), (24), AUTO-BW
+ (5250 - 5330 @ 80), (24), DFS, AUTO-BW
+ (5490 - 5730 @ 160), (24), DFS
+ (5735 - 5835 @ 80), (30)
+
+country FR: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (27), DFS
+ # 60 GHz band channels 1-4, ref: Etsi En 302 567
+ (57000 - 66000 @ 2160), (40)
+
+country GB: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (27), DFS
+ # 60 GHz band channels 1-4, ref: Etsi En 302 567
+ (57000 - 66000 @ 2160), (40)
+
+country GD: DFS-FCC
+ (2402 - 2472 @ 40), (30)
+ (5170 - 5250 @ 80), (17), AUTO-BW
+ (5250 - 5330 @ 80), (24), DFS, AUTO-BW
+ (5490 - 5730 @ 160), (24), DFS
+ (5735 - 5835 @ 80), (30)
+
+country GE: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (18), AUTO-BW
+ (5250 - 5330 @ 80), (18), DFS, AUTO-BW
+ # 60 GHz band channels 1-4, ref: Etsi En 302 567
+ (57000 - 66000 @ 2160), (40)
+
+country GF: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (27), DFS
+
+country GH: DFS-FCC
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (17), AUTO-BW
+ (5250 - 5330 @ 80), (24), DFS, AUTO-BW
+ (5490 - 5730 @ 160), (24), DFS
+ (5735 - 5835 @ 80), (30)
+
+country GL: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (27), DFS
+
+country GP: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (27), DFS
+
+country GR: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (27), DFS
+ # 60 GHz band channels 1-4, ref: Etsi En 302 567
+ (57000 - 66000 @ 2160), (40)
+
+country GT: DFS-FCC
+ (2402 - 2472 @ 40), (30)
+ (5170 - 5250 @ 80), (17), AUTO-BW
+ (5250 - 5330 @ 80), (23), DFS, AUTO-BW
+ (5735 - 5835 @ 80), (30)
+
+country GU: DFS-FCC
+ (2402 - 2472 @ 40), (30)
+ (5170 - 5250 @ 20), (17)
+ (5250 - 5330 @ 20), (24), DFS
+ (5490 - 5730 @ 20), (24), DFS
+ (5735 - 5835 @ 20), (30)
+
+country GY:
+ (2402 - 2482 @ 40), (30)
+ (5735 - 5835 @ 80), (30)
+
+country HK: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (17), AUTO-BW
+ (5250 - 5330 @ 80), (24), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (24), DFS
+ (5735 - 5835 @ 80), (30)
+
+country HN: DFS-FCC
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (17), AUTO-BW
+ (5250 - 5330 @ 80), (24), DFS, AUTO-BW
+ (5490 - 5730 @ 160), (24), DFS
+ (5735 - 5835 @ 80), (30)
+
+country HR: DFS-ETSI
+ (2400 - 2483.5 @ 40), (20)
+ (5150 - 5250 @ 80), (23), NO-OUTDOOR, AUTO-BW
+ (5250 - 5350 @ 80), (20), NO-OUTDOOR, DFS, AUTO-BW
+ (5470 - 5725 @ 160), (27), DFS
+ # 60 GHz band channels 1-4, ref: Etsi En 302 567
+ (57000 - 66000 @ 2160), (40)
+
+country HT: DFS-FCC
+ (2402 - 2472 @ 40), (30)
+ (5170 - 5250 @ 80), (24), AUTO-BW
+ (5250 - 5330 @ 80), (24), DFS, AUTO-BW
+ (5490 - 5730 @ 160), (24), DFS
+ (5735 - 5835 @ 80), (30)
+
+country HU: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (27), DFS
+ # 60 GHz band channels 1-4, ref: Etsi En 302 567
+ (57000 - 66000 @ 2160), (40)
+
+country ID: DFS-JP
+ # ref: http://www.postel.go.id/content/ID/regulasi/standardisasi/kepdir/bwa%205,8%20ghz.pdf
+ (2402 - 2482 @ 20), (20)
+ (5735 - 5815 @ 20), (23)
+
+country IE: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (27), DFS
+ # 60 GHz band channels 1-4, ref: Etsi En 302 567
+ (57000 - 66000 @ 2160), (40)
+
+country IL: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5150 - 5250 @ 80), (200 mW), NO-OUTDOOR, AUTO-BW
+ (5250 - 5350 @ 80), (200 mW), NO-OUTDOOR, DFS, AUTO-BW
+
+country IN:
+ (2402 - 2482 @ 40), (20)
+ (5150 - 5350 @ 160), (23)
+ (5725 - 5875 @ 80), (23)
+
+country IR: DFS-JP
+ (2402 - 2482 @ 40), (20)
+ (5735 - 5835 @ 80), (30)
+
+country IS: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (27), DFS
+ # 60 GHz band channels 1-4, ref: Etsi En 302 567
+ (57000 - 66000 @ 2160), (40)
+
+country IT: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (27), DFS
+ # 60 GHz band channels 1-4, ref: Etsi En 302 567
+ (57000 - 66000 @ 2160), (40)
+
+country JM: DFS-FCC
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (17), AUTO-BW
+ (5250 - 5330 @ 80), (24), DFS, AUTO-BW
+ (5490 - 5730 @ 160), (24), DFS
+ (5735 - 5835 @ 80), (30)
+
+country JO: DFS-JP
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (23)
+ (5735 - 5835 @ 80), (23)
+
+country JP: DFS-JP
+ (2402 - 2482 @ 40), (20)
+ (2474 - 2494 @ 20), (20), NO-OFDM
+ (4910 - 4990 @ 40), (23)
+ (5030 - 5090 @ 40), (23)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (23), DFS
+ # 60 GHz band channels 2-4 at 10mW,
+ # ref: http://www.arib.or.jp/english/html/overview/doc/1-STD-T74v1_1.pdf
+ (59000 - 66000 @ 2160), (10 mW)
+
+country KE: DFS-JP
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (23)
+ (5490 - 5570 @ 80), (30), DFS
+ (5735 - 5775 @ 40), (23)
+
+country KH: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (27), DFS
+
+# Source
+# http://ntrc.kn/?page_id=7
+country KN: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (30), DFS
+ (5735 - 5815 @ 80), (30)
+
+country KP: DFS-JP
+ (2402 - 2482 @ 20), (20)
+ (5170 - 5250 @ 20), (20)
+ (5250 - 5330 @ 20), (20), DFS
+ (5490 - 5630 @ 20), (30), DFS
+ (5735 - 5815 @ 20), (30)
+
+country KR: DFS-JP
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (30), DFS
+ (5735 - 5835 @ 80), (30)
+ # 60 GHz band channels 1-4,
+ # ref: http://www.law.go.kr/%ED%96%89%EC%A0%95%EA%B7%9C%EC%B9%99/%EB%AC%B4%EC%84%A0%EC%84%A4%EB%B9%84%EA%B7%9C%EC%B9%99
+ (57000 - 66000 @ 2160), (43)
+
+country KW: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+
+country KY: DFS-FCC
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (24), AUTO-BW
+ (5250 - 5330 @ 80), (24), DFS, AUTO-BW
+ (5490 - 5730 @ 160), (24), DFS
+ (5735 - 5835 @ 80), (30)
+
+country KZ:
+ (2402 - 2482 @ 40), (20)
+
+country LB: DFS-FCC
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (17), AUTO-BW
+ (5250 - 5330 @ 80), (24), DFS, AUTO-BW
+ (5490 - 5730 @ 160), (24), DFS
+ (5735 - 5835 @ 80), (30)
+
+# Source:
+# http://www.ntrc.org.lc/operational_structures.htm
+country LC: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (30), DFS
+ (5735 - 5815 @ 80), (30)
+
+country LI: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (27), DFS
+
+country LK: DFS-FCC
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 20), (17)
+ (5250 - 5330 @ 20), (24), DFS
+ (5490 - 5730 @ 20), (24), DFS
+ (5735 - 5835 @ 20), (30)
+
+# Source:
+# http://lca.org.ls/images/documents/lesotho_national_frequency_allocation_plan.pdf
+country LS: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (27), DFS
+
+country LT: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (27), DFS
+ # 60 GHz band channels 1-4, ref: Etsi En 302 567
+ (57000 - 66000 @ 2160), (40)
+
+country LU: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (27), DFS
+ # 60 GHz band channels 1-4, ref: Etsi En 302 567
+ (57000 - 66000 @ 2160), (40)
+
+country LV: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (27), DFS
+ # 60 GHz band channels 1-4, ref: Etsi En 302 567
+ (57000 - 66000 @ 2160), (40)
+
+country MA: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+
+country MC: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (27), DFS
+
+# Source:
+# http://www.cnfr.md/index.php?pag=sec&id=117&l=en
+country MD: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (27), DFS
+
+# Source:
+# http://www.cept.org/files/1050/Tools%20and%20Services/EFIS%20-%20ECO%20Frequency%20Information%20System/National%20frequency%20tables/Montenegro%20NAFT%20-%202010.pdf
+country ME: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (27), DFS
+
+country MF: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (27), DFS
+
+country MH: DFS-FCC
+ (2402 - 2472 @ 40), (30)
+ (5170 - 5250 @ 80), (24), AUTO-BW
+ (5250 - 5330 @ 80), (24), DFS, AUTO-BW
+ (5490 - 5730 @ 160), (24), DFS
+ (5735 - 5835 @ 80), (30)
+
+country MK: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (27), DFS
+ # 60 GHz band channels 1-4, ref: Etsi En 302 567
+ (57000 - 66000 @ 2160), (40)
+
+country MN: DFS-FCC
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (24), AUTO-BW
+ (5250 - 5330 @ 80), (24), DFS, AUTO-BW
+ (5490 - 5730 @ 160), (24), DFS
+ (5735 - 5835 @ 80), (30)
+
+country MO: DFS-FCC
+ (2402 - 2482 @ 40), (23)
+ (5170 - 5250 @ 80), (23), AUTO-BW
+ (5250 - 5330 @ 80), (23), DFS, AUTO-BW
+ (5490 - 5730 @ 160), (30), DFS
+ (5735 - 5835 @ 80), (30)
+
+country MP: DFS-FCC
+ (2402 - 2472 @ 40), (30)
+ (5170 - 5250 @ 80), (24), AUTO-BW
+ (5250 - 5330 @ 80), (24), DFS, AUTO-BW
+ (5490 - 5730 @ 160), (24), DFS
+ (5735 - 5835 @ 80), (30)
+
+country MQ: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (27), DFS
+
+# Source:
+# http://www.are.mr/pdfs/telec_freq_TNAbf_2010.pdf
+country MR: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (27), DFS
+
+country MT: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (27), DFS
+ # 60 GHz band channels 1-4, ref: Etsi En 302 567
+ (57000 - 66000 @ 2160), (40)
+
+country MU: DFS-FCC
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (24), AUTO-BW
+ (5250 - 5330 @ 80), (24), DFS, AUTO-BW
+ (5490 - 5730 @ 160), (24), DFS
+ (5735 - 5835 @ 80), (30)
+
+# Source:
+# http://www.cam.gov.mv/docs/tech_standards/TAM-TS-100-2004-WLAN.pdf
+country MV: DFS-ETSI
+ (2400 - 2483.5 @ 40), (100 mW)
+ (5150 - 5250 @ 80), (200 mW), AUTO-BW
+ (5250 - 5350 @ 80), (100 mW), DFS, AUTO-BW
+ (5725 - 5850 @ 80), (100 mW)
+
+country MW: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (27), DFS
+
+country MX: DFS-FCC
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (17), AUTO-BW
+ (5250 - 5330 @ 80), (24), DFS, AUTO-BW
+ (5490 - 5730 @ 160), (24), DFS
+ (5735 - 5835 @ 80), (30)
+
+country MY: DFS-FCC
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (24), AUTO-BW
+ (5250 - 5330 @ 80), (24), DFS, AUTO-BW
+ (5490 - 5650 @ 160), (24), DFS
+ (5735 - 5835 @ 80), (24)
+
+country NG: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5250 - 5330 @ 80), (30), DFS
+ (5735 - 5835 @ 80), (30)
+
+country NI: DFS-FCC
+ (2402 - 2472 @ 40), (30)
+ (5170 - 5250 @ 80), (24), AUTO-BW
+ (5250 - 5330 @ 80), (24), DFS, AUTO-BW
+ (5490 - 5730 @ 160), (24), DFS
+ (5735 - 5835 @ 80), (30)
+
+# Regulation on the use of frequency space without a license and
+# without notification 2015
+#
+# http://wetten.overheid.nl/BWBR0036378/2015-03-05
+
+country NL: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), NO-OUTDOOR, AUTO-BW
+ (5250 - 5330 @ 80), (20), NO-OUTDOOR, DFS, AUTO-BW
+ (5490 - 5710 @ 160), (27), DFS
+ # short range devices (ETSI EN 300 440-1)
+ (5725 - 5875 @ 80), (25 mW)
+ # 60 GHz band channels 1-4, ref: Etsi En 302 567
+ (57000 - 66000 @ 2160), (40)
+
+# Data from http://www.lovdata.no/dokument/SF/forskrift/2012-01-19-77
+# Power at 5250 - 5350 MHz, 5470 - 5725 MHz and 5815 – 5850 MHz can
+# be doubled if TPC is implemented.
+# Up to 2W (or 4W with TPC) is allowed in the 5725 – 5795 MHz band
+# which has been merged with 5470 - 5725 MHz to allow wide channels
+country NO: DFS-ETSI
+ (2400 - 2483.5 @ 40), (100 mW)
+ (5150 - 5250 @ 80), (200 mW), AUTO-BW
+ (5250 - 5350 @ 80), (100 mW), DFS, AUTO-BW
+ (5470 - 5795 @ 160), (500 mW), DFS
+ (5815 - 5850 @ 35), (2000 mW), DFS
+ (17100 - 17300 @ 200), (100 mW)
+ # 60 GHz band channels 1-4, ref: Etsi En 302 567
+ (57000 - 66000 @ 2160), (40)
+
+country NP: DFS-JP
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5735 - 5835 @ 80), (20)
+
+country NZ: DFS-ETSI
+ (2402 - 2482 @ 40), (30)
+ (5170 - 5250 @ 80), (17), AUTO-BW
+ (5250 - 5330 @ 80), (24), DFS, AUTO-BW
+ (5490 - 5730 @ 160), (24), DFS
+ (5735 - 5835 @ 80), (30)
+
+country OM: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (27), DFS
+
+country PA: DFS-FCC
+ (2402 - 2472 @ 40), (30)
+ (5170 - 5250 @ 80), (17), AUTO-BW
+ (5250 - 5330 @ 80), (23), DFS, AUTO-BW
+ (5735 - 5835 @ 80), (30)
+
+country PE: DFS-FCC
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (17), AUTO-BW
+ (5250 - 5330 @ 80), (24), DFS, AUTO-BW
+ (5490 - 5730 @ 160), (24), DFS
+ (5735 - 5835 @ 80), (30)
+
+country PF: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (27), DFS
+
+country PG: DFS-FCC
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (17), AUTO-BW
+ (5250 - 5330 @ 80), (24), DFS, AUTO-BW
+ (5490 - 5730 @ 160), (24), DFS
+ (5735 - 5835 @ 80), (30)
+
+country PH: DFS-FCC
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (17), AUTO-BW
+ (5250 - 5330 @ 80), (24), DFS, AUTO-BW
+ (5490 - 5730 @ 160), (24), DFS
+ (5735 - 5835 @ 80), (30)
+
+country PK: DFS-JP
+ (2402 - 2482 @ 40), (20)
+ (5735 - 5835 @ 80), (30)
+
+country PL: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (27), DFS
+ # 60 GHz band channels 1-4, ref: Etsi En 302 567
+ (57000 - 66000 @ 2160), (40)
+
+country PM: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (27), DFS
+
+country PR: DFS-FCC
+ (2402 - 2472 @ 40), (30)
+ (5170 - 5250 @ 80), (17), AUTO-BW
+ (5250 - 5330 @ 80), (24), DFS, AUTO-BW
+ (5490 - 5730 @ 160), (24), DFS
+ (5735 - 5835 @ 80), (30)
+
+country PT: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (27), DFS
+ # 60 GHz band channels 1-4, ref: Etsi En 302 567
+ (57000 - 66000 @ 2160), (40)
+
+country PW: DFS-FCC
+ (2402 - 2472 @ 40), (30)
+ (5170 - 5250 @ 80), (24), AUTO-BW
+ (5250 - 5330 @ 80), (24), DFS, AUTO-BW
+ (5490 - 5730 @ 160), (24), DFS
+ (5735 - 5835 @ 80), (30)
+
+country PY: DFS-FCC
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (24), AUTO-BW
+ (5250 - 5330 @ 80), (24), DFS, AUTO-BW
+ (5490 - 5730 @ 160), (24), DFS
+ (5735 - 5835 @ 80), (30)
+
+country QA: DFS-JP
+ (2402 - 2482 @ 40), (20)
+ (5735 - 5835 @ 80), (30)
+
+country RE: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (27), DFS
+
+country RO: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (27), DFS
+ # 60 GHz band channels 1-4, ref: Etsi En 302 567
+ (57000 - 66000 @ 2160), (40)
+
+
+# Source:
+# http://www.ratel.rs/upload/documents/Plan_namene/Plan_namene-sl_glasnik.pdf
+country RS: DFS-ETSI
+ (2400 - 2483.5 @ 40), (100 mW)
+ (5150 - 5350 @ 40), (200 mW), NO-OUTDOOR
+ (5470 - 5725 @ 20), (1000 mW), DFS
+ # 60 GHz band channels 1-4, ref: Etsi En 302 567
+ (57000 - 66000 @ 2160), (40)
+
+country RU: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5650 - 5730 @ 80), (30), DFS
+ (5735 - 5835 @ 80), (30)
+ # 60 GHz band channels 1-4, ref: Changes to NLA 124_Order №129_22042015.pdf
+ (57000 - 66000 @ 2160), (40)
+
+country RW: DFS-FCC
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (17), AUTO-BW
+ (5250 - 5330 @ 80), (24), DFS, AUTO-BW
+ (5490 - 5730 @ 160), (24), DFS
+ (5735 - 5835 @ 80), (30)
+
+country SA: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (27), DFS
+
+country SE: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (27), DFS
+ # 60 GHz band channels 1-4, ref: Etsi En 302 567
+ (57000 - 66000 @ 2160), (40)
+
+country SG: DFS-FCC
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (17), AUTO-BW
+ (5250 - 5330 @ 80), (24), DFS, AUTO-BW
+ (5490 - 5730 @ 160), (24), DFS
+ (5735 - 5835 @ 80), (30)
+
+country SI: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (27), DFS
+ # 60 GHz band channels 1-4, ref: Etsi En 302 567
+ (57000 - 66000 @ 2160), (40)
+
+country SK: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (27), DFS
+ # 60 GHz band channels 1-4, ref: Etsi En 302 567
+ (57000 - 66000 @ 2160), (40)
+
+# Source:
+# Regulation N° 2004-005 ART/DG/DRC/D.Rég
+country SN: DFS-FCC
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (17), AUTO-BW
+ (5250 - 5330 @ 80), (24), DFS, AUTO-BW
+ (5490 - 5730 @ 160), (24), DFS
+ (5735 - 5835 @ 80), (30)
+
+country SR: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (27), DFS
+
+country SV: DFS-FCC
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 20), (17)
+ (5250 - 5330 @ 20), (23), DFS
+ (5735 - 5835 @ 20), (30)
+
+country SY:
+ (2402 - 2482 @ 40), (20)
+
+# Source:
+# http://www.telecommission.tc/Spectrum-plan20110324-101210.html
+country TC: DFS-FCC
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (24), AUTO-BW
+ (5250 - 5330 @ 80), (24), DFS, AUTO-BW
+ (5490 - 5730 @ 160), (24), DFS
+ (5735 - 5835 @ 80), (30)
+
+country TD: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (27), DFS
+
+country TG: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 40), (20)
+ (5250 - 5330 @ 40), (20), DFS
+ (5490 - 5710 @ 40), (27), DFS
+
+country TH: DFS-FCC
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (17), AUTO-BW
+ (5250 - 5330 @ 80), (24), DFS, AUTO-BW
+ (5490 - 5730 @ 160), (24), DFS
+ (5735 - 5835 @ 80), (30)
+
+country TN: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+
+country TR: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (27), DFS
+ # 60 GHz band channels 1-4, ref: Etsi En 302 567
+ (57000 - 66000 @ 2160), (40)
+
+country TT: DFS-FCC
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (17), AUTO-BW
+ (5250 - 5330 @ 80), (24), DFS, AUTO-BW
+ (5490 - 5730 @ 160), (24), DFS
+ (5735 - 5835 @ 80), (30)
+
+# Source:
+# Table of Frequency Allocations of Republic of China (Taiwan) / Nov 2014:
+# http://www.motc.gov.tw/websitedowndoc?file=post/201411171137330.doc& \
+# filedisplay=Table+of+radio+frequency+allocation.doc
+# LP0002 Low-power Radio-frequency Devices Technical Regulations / 28 Jun 2011:
+# http://www.ncc.gov.tw/english/show_file.aspx?table_name=news&file_sn=681
+# (section 3.10.1, 4.7)
+country TW: DFS-FCC
+ (2400 - 2483.5 @ 40), (30)
+ # Follow US 5.15 ~ 5.25 GHz: 30 dBm for master mode, 23 dBm for clients
+ (5150 - 5250 @ 80), (23), AUTO-BW
+ (5250 - 5350 @ 80), (23), DFS, AUTO-BW
+ (5470 - 5725 @ 160), (23), DFS
+ (5725 - 5850 @ 80), (30)
+
+country TZ:
+ (2402 - 2482 @ 40), (20)
+ (5735 - 5835 @ 80), (30)
+
+# Source:
+# #914 / 06 Sep 2007: http://www.ucrf.gov.ua/uk/doc/nkrz/1196068874
+# #1174 / 23 Oct 2008: http://www.nkrz.gov.ua/uk/activities/ruling/1225269361
+# (appendix 8)
+# Listed 5GHz range is a lowest common denominator for all related
+# rules in the referenced laws. Such a range is used because of
+# disputable definitions there.
+country UA: DFS-ETSI
+ (2400 - 2483.5 @ 40), (20), NO-OUTDOOR
+ (5150 - 5250 @ 80), (20), NO-OUTDOOR, AUTO-BW
+ (5250 - 5350 @ 80), (20), DFS, NO-OUTDOOR, AUTO-BW
+ (5490 - 5670 @ 160), (20), DFS
+ (5735 - 5835 @ 80), (20)
+ # 60 GHz band channels 1-4, ref: Etsi En 302 567
+ (57000 - 66000 @ 2160), (40)
+
+country UG: DFS-FCC
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (24), AUTO-BW
+ (5250 - 5330 @ 80), (24), DFS, AUTO-BW
+ (5490 - 5730 @ 160), (24), DFS
+ (5735 - 5835 @ 80), (30)
+
+country US: DFS-FCC
+ (2402 - 2472 @ 40), (30)
+ # 5.15 ~ 5.25 GHz: 30 dBm for master mode, 23 dBm for clients
+ (5170 - 5250 @ 80), (23), AUTO-BW
+ (5250 - 5330 @ 80), (23), DFS, AUTO-BW
+ (5490 - 5730 @ 160), (23), DFS
+ (5735 - 5835 @ 80), (30)
+ # 60g band
+ # reference: http://cfr.regstoday.com/47cfr15.aspx#47_CFR_15p255
+ # channels 1,2,3, EIRP=40dBm(43dBm peak)
+ (57240 - 63720 @ 2160), (40)
+
+country UY: DFS-FCC
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (23), AUTO-BW
+ (5250 - 5330 @ 80), (23), DFS, AUTO-BW
+ (5735 - 5835 @ 80), (30)
+
+# Source:
+# http://cemc.uz/article/1976/
+country UZ: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+
+# Source:
+# http://www.ntrc.vc/regulations/Jun_2006_Spectrum_Managment_Regulations.pdf
+country VC: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (27), DFS
+
+# Source:
+# Official Gazette (Gaceta Oficial) concerning Unlicensed transmitter use
+# (10 June 2013)
+# http://www.conatel.gob.ve/
+country VE: DFS-FCC
+ (2402 - 2482 @ 40), (30)
+ (5170 - 5250 @ 80), (23), AUTO-BW
+ (5250 - 5330 @ 80), (23), DFS, AUTO-BW
+ (5735 - 5835 @ 80), (30)
+
+country VI: DFS-FCC
+ (2402 - 2472 @ 40), (30)
+ (5170 - 5250 @ 80), (24), AUTO-BW
+ (5250 - 5330 @ 80), (24), DFS, AUTO-BW
+ (5490 - 5730 @ 160), (24), DFS
+ (5735 - 5835 @ 80), (30)
+
+country VN: DFS-FCC
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (17)
+ (5250 - 5330 @ 80), (24), DFS
+ (5490 - 5730 @ 80), (24), DFS
+ (5735 - 5835 @ 80), (30)
+
+# Source:
+# http://www.trr.vu/attachments/category/130/GURL_for_Short-range_Radiocommunication_Devices2.pdf
+country VU: DFS-FCC
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (17), AUTO-BW
+ (5250 - 5330 @ 80), (24), DFS, AUTO-BW
+ (5490 - 5730 @ 160), (24), DFS
+ (5735 - 5835 @ 80), (30)
+
+country WF: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (27), DFS
+
+country WS: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 40), (20)
+ (5250 - 5330 @ 40), (20), DFS
+ (5490 - 5710 @ 40), (27), DFS
+
+country YE:
+ (2402 - 2482 @ 40), (20)
+
+country YT: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (27), DFS
+
+country ZA: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (30)
+
+country ZW: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (27), DFS
diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index 804eac073b6b..283d8997f671 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -2418,6 +2418,7 @@ int regulatory_hint_user(const char *alpha2,
return 0;
}
+EXPORT_SYMBOL(regulatory_hint_user);
int regulatory_hint_indoor(bool is_indoor, u32 portid)
{
diff --git a/net/wireless/util.c b/net/wireless/util.c
index 0f6c34ff9b55..907072dddf12 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -1873,3 +1873,54 @@ EXPORT_SYMBOL(rfc1042_header);
const unsigned char bridge_tunnel_header[] __aligned(2) =
{ 0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8 };
EXPORT_SYMBOL(bridge_tunnel_header);
+
+bool cfg80211_is_gratuitous_arp_unsolicited_na(struct sk_buff *skb)
+{
+ const struct ethhdr *eth = (void *)skb->data;
+ const struct {
+ struct arphdr hdr;
+ u8 ar_sha[ETH_ALEN];
+ u8 ar_sip[4];
+ u8 ar_tha[ETH_ALEN];
+ u8 ar_tip[4];
+ } __packed *arp;
+ const struct ipv6hdr *ipv6;
+ const struct icmp6hdr *icmpv6;
+
+ switch (eth->h_proto) {
+ case cpu_to_be16(ETH_P_ARP):
+ /* can't say - but will probably be dropped later anyway */
+ if (!pskb_may_pull(skb, sizeof(*eth) + sizeof(*arp)))
+ return false;
+
+ arp = (void *)(eth + 1);
+
+ if ((arp->hdr.ar_op == cpu_to_be16(ARPOP_REPLY) ||
+ arp->hdr.ar_op == cpu_to_be16(ARPOP_REQUEST)) &&
+ !memcmp(arp->ar_sip, arp->ar_tip, sizeof(arp->ar_sip)))
+ return true;
+ break;
+ case cpu_to_be16(ETH_P_IPV6):
+ /* can't say - but will probably be dropped later anyway */
+ if (!pskb_may_pull(skb, sizeof(*eth) + sizeof(*ipv6) +
+ sizeof(*icmpv6)))
+ return false;
+
+ ipv6 = (void *)(eth + 1);
+ icmpv6 = (void *)(ipv6 + 1);
+
+ if (icmpv6->icmp6_type == NDISC_NEIGHBOUR_ADVERTISEMENT &&
+ !memcmp(&ipv6->saddr, &ipv6->daddr, sizeof(ipv6->saddr)))
+ return true;
+ break;
+ default:
+ /*
+ * no need to support other protocols, proxy service isn't
+ * specified for any others
+ */
+ break;
+ }
+
+ return false;
+}
+EXPORT_SYMBOL(cfg80211_is_gratuitous_arp_unsolicited_na);
diff --git a/sound/core/pcm_dmaengine.c b/sound/core/pcm_dmaengine.c
index 8eb58c709b14..99abc917427f 100644
--- a/sound/core/pcm_dmaengine.c
+++ b/sound/core/pcm_dmaengine.c
@@ -5,6 +5,7 @@
* Based on:
* imx-pcm-dma-mx2.c, Copyright 2009 Sascha Hauer <s.hauer@pengutronix.de>
* mxs-pcm.c, Copyright (C) 2011 Freescale Semiconductor, Inc.
+ * imx-pcm-dma.c, Copyright (C) 2014-2015 Freescale Semiconductor, Inc.
* ep93xx-pcm.c, Copyright (C) 2006 Lennert Buytenhek <buytenh@wantstofly.org>
* Copyright (C) 2006 Applied Data Systems
*
@@ -28,13 +29,6 @@
#include <sound/dmaengine_pcm.h>
-struct dmaengine_pcm_runtime_data {
- struct dma_chan *dma_chan;
- dma_cookie_t cookie;
-
- unsigned int pos;
-};
-
static inline struct dmaengine_pcm_runtime_data *substream_to_prtd(
const struct snd_pcm_substream *substream)
{
@@ -171,7 +165,10 @@ static int dmaengine_pcm_prepare_and_submit(struct snd_pcm_substream *substream)
if (!desc)
return -ENOMEM;
- desc->callback = dmaengine_pcm_dma_complete;
+ if (prtd->callback)
+ desc->callback = prtd->callback;
+ else
+ desc->callback = dmaengine_pcm_dma_complete;
desc->callback_param = substream;
prtd->cookie = dmaengine_submit(desc);
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index c367d11079bc..79adf360897e 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -35,6 +35,10 @@ config SND_SOC_ALL_CODECS
select SND_SOC_ADAU7002
select SND_SOC_ADS117X
select SND_SOC_AK4104 if SPI_MASTER
+ select SND_SOC_AK4458
+ select SND_SOC_AK4458_I2C if I2C
+ select SND_SOC_AK4458_SPI if SPI_MASTER
+ select SND_SOC_AK4497 if I2C
select SND_SOC_AK4535 if I2C
select SND_SOC_AK4554
select SND_SOC_AK4613 if I2C
@@ -42,6 +46,7 @@ config SND_SOC_ALL_CODECS
select SND_SOC_AK4642 if I2C
select SND_SOC_AK4671 if I2C
select SND_SOC_AK5386
+ select SND_SOC_AK5558 if I2C
select SND_SOC_ALC5623 if I2C
select SND_SOC_ALC5632 if I2C
select SND_SOC_BT_SCO
@@ -217,6 +222,9 @@ config SND_SOC_ALL_CODECS
select SND_SOC_WM9705 if SND_SOC_AC97_BUS
select SND_SOC_WM9712 if SND_SOC_AC97_BUS
select SND_SOC_WM9713 if SND_SOC_AC97_BUS
+ select SND_SOC_RPMSG_WM8960
+ select SND_SOC_RPMSG_CS42XX8
+ select SND_SOC_RPMSG_AK4497
help
Normally ASoC codec drivers are only built if a machine driver which
uses them is also built since they are only usable with a machine
@@ -371,6 +379,26 @@ config SND_SOC_AK4104
tristate "AKM AK4104 CODEC"
depends on SPI_MASTER
+config SND_SOC_AK4458
+ tristate
+
+config SND_SOC_AK4458_I2C
+ tristate "AKM AK4458 DAC I2c"
+ depends on I2C
+ select SND_SOC_AK4458
+ select REGMAP_I2C
+
+config SND_SOC_AK4458_SPI
+ tristate "AKM AK4458 DAC SPI"
+ depends on SPI_MASTER
+ select SND_SOC_AK4458
+ select REGMAP_SPI
+
+config SND_SOC_AK4497
+ tristate "AKM AK4497 CODEC"
+ depends on I2C
+ select REGMAP_I2C
+
config SND_SOC_AK4535
tristate
@@ -394,6 +422,11 @@ config SND_SOC_AK4671
config SND_SOC_AK5386
tristate "AKM AK5638 CODEC"
+config SND_SOC_AK5558
+ tristate "AKM AK5558 CODEC"
+ depends on I2C
+ select REGMAP_I2C
+
config SND_SOC_ALC5623
tristate "Realtek ALC5623 CODEC"
depends on I2C
@@ -569,6 +602,9 @@ config SND_SOC_ES8328_SPI
depends on SPI_MASTER
select SND_SOC_ES8328
+config SND_SOC_FSL_MQS
+ tristate
+
config SND_SOC_GTM601
tristate 'GTM601 UMTS modem audio codec'
@@ -1142,6 +1178,14 @@ config SND_SOC_ZX_AUD96P22
depends on I2C
select REGMAP_I2C
+config SND_SOC_RPMSG_WM8960
+ tristate
+
+config SND_SOC_RPMSG_CS42XX8
+ tristate
+
+config SND_SOC_RPMSG_AK4497
+ tristate
# Amp
config SND_SOC_LM4857
tristate
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index 05018b7ca72b..a3bff1ea12cb 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -27,6 +27,10 @@ snd-soc-adav801-objs := adav801.o
snd-soc-adav803-objs := adav803.o
snd-soc-ads117x-objs := ads117x.o
snd-soc-ak4104-objs := ak4104.o
+snd-soc-ak4458-objs := ak4458.o
+snd-soc-ak4458-i2c-objs := ak4458-i2c.o
+snd-soc-ak4458-spi-objs := ak4458-spi.o
+snd-soc-ak4497-objs := ak4497.o
snd-soc-ak4535-objs := ak4535.o
snd-soc-ak4554-objs := ak4554.o
snd-soc-ak4613-objs := ak4613.o
@@ -34,6 +38,7 @@ snd-soc-ak4641-objs := ak4641.o
snd-soc-ak4642-objs := ak4642.o
snd-soc-ak4671-objs := ak4671.o
snd-soc-ak5386-objs := ak5386.o
+snd-soc-ak5558-objs := ak5558.o
snd-soc-arizona-objs := arizona.o
snd-soc-bt-sco-objs := bt-sco.o
snd-soc-cq93vc-objs := cq93vc.o
@@ -71,6 +76,7 @@ snd-soc-es8316-objs := es8316.o
snd-soc-es8328-objs := es8328.o
snd-soc-es8328-i2c-objs := es8328-i2c.o
snd-soc-es8328-spi-objs := es8328-spi.o
+snd-soc-fsl-mqs-objs := fsl_mqs.o
snd-soc-gtm601-objs := gtm601.o
snd-soc-hdac-hdmi-objs := hdac_hdmi.o
snd-soc-ics43432-objs := ics43432.o
@@ -230,6 +236,10 @@ snd-soc-wm9712-objs := wm9712.o
snd-soc-wm9713-objs := wm9713.o
snd-soc-wm-hubs-objs := wm_hubs.o
snd-soc-zx-aud96p22-objs := zx_aud96p22.o
+snd-soc-rpmsg-wm8960-objs := rpmsg_wm8960.o
+snd-soc-rpmsg-cs42xx8-objs := rpmsg_cs42xx8.o
+snd-soc-rpmsg-ak4497-objs := rpmsg_ak4497.o
+
# Amp
snd-soc-dio2125-objs := dio2125.o
snd-soc-max9877-objs := max9877.o
@@ -265,6 +275,10 @@ obj-$(CONFIG_SND_SOC_ADAV801) += snd-soc-adav801.o
obj-$(CONFIG_SND_SOC_ADAV803) += snd-soc-adav803.o
obj-$(CONFIG_SND_SOC_ADS117X) += snd-soc-ads117x.o
obj-$(CONFIG_SND_SOC_AK4104) += snd-soc-ak4104.o
+obj-$(CONFIG_SND_SOC_AK4458) += snd-soc-ak4458.o
+obj-$(CONFIG_SND_SOC_AK4458_I2C) += snd-soc-ak4458-i2c.o
+obj-$(CONFIG_SND_SOC_AK4458_SPI) += snd-soc-ak4458-spi.o
+obj-$(CONFIG_SND_SOC_AK4497) += snd-soc-ak4497.o
obj-$(CONFIG_SND_SOC_AK4535) += snd-soc-ak4535.o
obj-$(CONFIG_SND_SOC_AK4554) += snd-soc-ak4554.o
obj-$(CONFIG_SND_SOC_AK4613) += snd-soc-ak4613.o
@@ -272,6 +286,7 @@ obj-$(CONFIG_SND_SOC_AK4641) += snd-soc-ak4641.o
obj-$(CONFIG_SND_SOC_AK4642) += snd-soc-ak4642.o
obj-$(CONFIG_SND_SOC_AK4671) += snd-soc-ak4671.o
obj-$(CONFIG_SND_SOC_AK5386) += snd-soc-ak5386.o
+obj-$(CONFIG_SND_SOC_AK5558) += snd-soc-ak5558.o
obj-$(CONFIG_SND_SOC_ALC5623) += snd-soc-alc5623.o
obj-$(CONFIG_SND_SOC_ALC5632) += snd-soc-alc5632.o
obj-$(CONFIG_SND_SOC_ARIZONA) += snd-soc-arizona.o
@@ -311,6 +326,7 @@ obj-$(CONFIG_SND_SOC_ES8316) += snd-soc-es8316.o
obj-$(CONFIG_SND_SOC_ES8328) += snd-soc-es8328.o
obj-$(CONFIG_SND_SOC_ES8328_I2C)+= snd-soc-es8328-i2c.o
obj-$(CONFIG_SND_SOC_ES8328_SPI)+= snd-soc-es8328-spi.o
+obj-$(CONFIG_SND_SOC_FSL_MQS) += snd-soc-fsl-mqs.o
obj-$(CONFIG_SND_SOC_GTM601) += snd-soc-gtm601.o
obj-$(CONFIG_SND_SOC_HDAC_HDMI) += snd-soc-hdac-hdmi.o
obj-$(CONFIG_SND_SOC_ICS43432) += snd-soc-ics43432.o
@@ -468,6 +484,9 @@ obj-$(CONFIG_SND_SOC_WM9713) += snd-soc-wm9713.o
obj-$(CONFIG_SND_SOC_WM_ADSP) += snd-soc-wm-adsp.o
obj-$(CONFIG_SND_SOC_WM_HUBS) += snd-soc-wm-hubs.o
obj-$(CONFIG_SND_SOC_ZX_AUD96P22) += snd-soc-zx-aud96p22.o
+obj-$(CONFIG_SND_SOC_RPMSG_WM8960) += snd-soc-rpmsg-wm8960.o
+obj-$(CONFIG_SND_SOC_RPMSG_CS42XX8) += snd-soc-rpmsg-cs42xx8.o
+obj-$(CONFIG_SND_SOC_RPMSG_AK4497) += snd-soc-rpmsg-ak4497.o
# Amp
obj-$(CONFIG_SND_SOC_DIO2125) += snd-soc-dio2125.o
diff --git a/sound/soc/codecs/ak4458-i2c.c b/sound/soc/codecs/ak4458-i2c.c
new file mode 100644
index 000000000000..6ddca79d56d7
--- /dev/null
+++ b/sound/soc/codecs/ak4458-i2c.c
@@ -0,0 +1,79 @@
+/*
+ * ak4458-i2c.c -- AK4458 DAC - I2C
+ *
+ * Copyright 2017 NXP
+ *
+ * Author: Mihai Serban <mihai.serban@nxp.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/i2c.h>
+#include <linux/pm_runtime.h>
+
+#include "ak4458.h"
+
+static int ak4458_i2c_probe(struct i2c_client *i2c,
+ const struct i2c_device_id *id)
+{
+ struct regmap *regmap;
+ int ret;
+
+ regmap = devm_regmap_init_i2c(i2c, &ak4458_i2c_regmap_config);
+ if (IS_ERR(regmap))
+ return PTR_ERR(regmap);
+
+ ret = ak4458_probe(&i2c->dev, regmap);
+ if (ret)
+ return ret;
+
+ pm_runtime_enable(&i2c->dev);
+
+ return 0;
+}
+
+static int ak4458_i2c_remove(struct i2c_client *i2c)
+{
+ ak4458_remove(&i2c->dev);
+ pm_runtime_disable(&i2c->dev);
+
+ return 0;
+}
+
+static const struct i2c_device_id ak4458_i2c_id[] = {
+ { "ak4458", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, ak4458_i2c_id);
+
+static const struct of_device_id ak4458_of_match[] = {
+ { .compatible = "asahi-kasei,ak4458", },
+ { },
+};
+MODULE_DEVICE_TABLE(of, ak4458_of_match);
+
+static struct i2c_driver ak4458_i2c_driver = {
+ .driver = {
+ .name = "ak4458",
+ .pm = &ak4458_pm,
+ .of_match_table = ak4458_of_match,
+ },
+ .probe = ak4458_i2c_probe,
+ .remove = ak4458_i2c_remove,
+ .id_table = ak4458_i2c_id
+};
+
+module_i2c_driver(ak4458_i2c_driver);
+
+MODULE_DESCRIPTION("ASoC AK4458 driver - I2C");
+MODULE_AUTHOR("Mihai Serban <mihai.serban@nxp.com>");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/ak4458-spi.c b/sound/soc/codecs/ak4458-spi.c
new file mode 100644
index 000000000000..fd20e994b291
--- /dev/null
+++ b/sound/soc/codecs/ak4458-spi.c
@@ -0,0 +1,61 @@
+/*
+ * ak4458-spi.c -- AK4458 DAC - SPI
+ *
+ * Copyright 2017 NXP
+ *
+ * Author: Mihai Serban <mihai.serban@nxp.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/spi/spi.h>
+
+#include "ak4458.h"
+
+static int ak4458_spi_probe(struct spi_device *spi)
+{
+ struct regmap *regmap;
+
+ regmap = devm_regmap_init_spi(spi, &ak4458_spi_regmap_config);
+ if (IS_ERR(regmap))
+ return PTR_ERR(regmap);
+
+ return ak4458_probe(&spi->dev, regmap);
+}
+
+static int ak4458_spi_remove(struct spi_device *spi)
+{
+ ak4458_remove(&spi->dev);
+ return 0;
+}
+
+static const struct of_device_id ak4458_of_match[] = {
+ { .compatible = "asahi-kasei,ak4458", },
+ { },
+};
+MODULE_DEVICE_TABLE(of, ak4458_of_match);
+
+static struct spi_driver ak4458_spi_driver = {
+ .driver = {
+ .name = "ak4458",
+ .pm = &ak4458_pm,
+ .of_match_table = ak4458_of_match,
+ },
+ .probe = ak4458_spi_probe,
+ .remove = ak4458_spi_remove
+};
+
+module_spi_driver(ak4458_spi_driver);
+
+MODULE_DESCRIPTION("ASoC AK4458 driver - SPI");
+MODULE_AUTHOR("Mihai Serban <mihai.serban@nxp.com>");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/ak4458.c b/sound/soc/codecs/ak4458.c
new file mode 100644
index 000000000000..6d1d19eeb2e9
--- /dev/null
+++ b/sound/soc/codecs/ak4458.c
@@ -0,0 +1,1248 @@
+/*
+ * ak4458.c -- audio driver for AK4458 DAC
+ *
+ * Copyright (C) 2016 Asahi Kasei Microdevices Corporation
+ * Copyright 2017 NXP
+ *
+ * Authors:
+ * Tsuyoshi Mutsuro
+ * Junichi Wakasugi <wakasugi.jb@om.asahi-kasei.co.jp>
+ * Mihai Serban <mihai.serban@nxp.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/gpio/consumer.h>
+#include <linux/of_device.h>
+#include <linux/of_gpio.h>
+#include <sound/soc.h>
+#include <sound/soc-dapm.h>
+#include <sound/initval.h>
+#include <sound/tlv.h>
+#include <sound/pcm_params.h>
+#include <linux/pm_runtime.h>
+#include <linux/regulator/consumer.h>
+
+#include "ak4458.h"
+
+#define AK4458_NUM_SUPPLIES 2
+static const char *ak4458_supply_names[AK4458_NUM_SUPPLIES] = {
+ "DVDD",
+ "AVDD",
+};
+
+/* AK4458 Codec Private Data */
+struct ak4458_priv {
+ struct device *dev;
+ struct regmap *regmap;
+ int pdn_gpio;
+ int mute_gpio;
+ int sds; /* SDS2-0 bits */
+ int digfil; /* SSLOW, SD, SLOW bits */
+ int fs; /* sampling rate */
+ int lr[4]; /* (MONO, INVL, INVR, SELLR) x4ch */
+ int fmt;
+ int slots;
+ int slot_width;
+ struct regulator_bulk_data supplies[AK4458_NUM_SUPPLIES];
+};
+
+static const struct reg_default ak4458_reg_defaults[] = {
+ { 0x00, 0x0C }, /* 0x00 AK4458_00_CONTROL1 */
+ { 0x01, 0x22 }, /* 0x01 AK4458_01_CONTROL2 */
+ { 0x02, 0x00 }, /* 0x02 AK4458_02_CONTROL3 */
+ { 0x03, 0xFF }, /* 0x03 AK4458_03_LCHATT */
+ { 0x04, 0xFF }, /* 0x04 AK4458_04_RCHATT */
+ { 0x05, 0x00 }, /* 0x05 AK4458_05_CONTROL4 */
+ { 0x06, 0x00 }, /* 0x06 AK4458_06_DSD1 */
+ { 0x07, 0x03 }, /* 0x07 AK4458_07_CONTROL5 */
+ { 0x08, 0x00 }, /* 0x08 AK4458_08_SOUND_CONTROL */
+ { 0x09, 0x00 }, /* 0x09 AK4458_09_DSD2 */
+ { 0x0A, 0x0D }, /* 0x0A AK4458_0A_CONTROL6 */
+ { 0x0B, 0x0C }, /* 0x0B AK4458_0B_CONTROL7 */
+ { 0x0C, 0x00 }, /* 0x0C AK4458_0C_CONTROL8 */
+ { 0x0D, 0x00 }, /* 0x0D AK4458_0D_CONTROL9 */
+ { 0x0E, 0x50 }, /* 0x0E AK4458_0E_CONTROL10 */
+ { 0x0F, 0xFF }, /* 0x0F AK4458_0F_L2CHATT */
+ { 0x10, 0xFF }, /* 0x10 AK4458_10_R2CHATT */
+ { 0x11, 0xFF }, /* 0x11 AK4458_11_L3CHATT */
+ { 0x12, 0xFF }, /* 0x12 AK4458_12_R3CHATT */
+ { 0x13, 0xFF }, /* 0x13 AK4458_13_L4CHATT */
+ { 0x14, 0xFF }, /* 0x14 AK4458_14_R4CHATT */
+};
+
+static const struct regmap_range ak4458_spi_non_readable_reg_ranges[] = {
+ regmap_reg_range(AK4458_00_CONTROL1, AK4458_14_R4CHATT),
+};
+
+static const struct regmap_access_table ak4458_spi_readable_regs = {
+ .no_ranges = ak4458_spi_non_readable_reg_ranges,
+ .n_no_ranges = ARRAY_SIZE(ak4458_spi_non_readable_reg_ranges),
+};
+
+/*
+ * Volume control:
+ * from -127 to 0 dB in 0.5 dB steps (mute instead of -127.5 dB)
+ */
+static DECLARE_TLV_DB_SCALE(latt_tlv, -12750, 50, 1);
+static DECLARE_TLV_DB_SCALE(ratt_tlv, -12750, 50, 1);
+
+/*
+ * DEM1 bit DEM0 bit Mode
+ * 0 0 44.1kHz
+ * 0 1 OFF (default)
+ * 1 0 48kHz
+ * 1 1 32kHz
+ */
+static const char * const ak4458_dem_select_texts[] = {
+ "44.1kHz", "OFF", "48kHz", "32kHz"
+};
+
+/*
+ * SSLOW, SD, SLOW bits Digital Filter Setting
+ * 0, 0, 0 : Sharp Roll-Off Filter
+ * 0, 0, 1 : Slow Roll-Off Filter
+ * 0, 1, 0 : Short delay Sharp Roll-Off Filter
+ * 0, 1, 1 : Short delay Slow Roll-Off Filter
+ * 1, *, * : Super Slow Roll-Off Filter
+ */
+static const char * const ak4458_digfil_select_texts[] = {
+ "Sharp Roll-Off Filter",
+ "Slow Roll-Off Filter",
+ "Short delay Sharp Roll-Off Filter",
+ "Short delay Slow Roll-Off Filter",
+ "Super Slow Roll-Off Filter"
+};
+
+/*
+ * DZFB: Inverting Enable of DZF
+ * 0: DZF goes H at Zero Detection
+ * 1: DZF goes L at Zero Detection
+ */
+static const char * const ak4458_dzfb_select_texts[] = {"H", "L"};
+
+/*
+ * SC1-0 bits: Sound Mode Setting
+ * 0 0 : Sound Mode 0
+ * 0 1 : Sound Mode 1
+ * 1 0 : Sound Mode 2
+ * 1 1 : Reserved
+ */
+static const char * const ak4458_sc_select_texts[] = {
+ "Sound Mode 0", "Sound Mode 1", "Sound Mode 2"
+};
+
+/*
+ * SDS2-0 bits: Output Data Select
+ * Refer to Data Sheet
+ */
+static const char * const ak4458_sds_select_texts[] = {
+ "Setting 0", "Setting 1", "Setting 2", "Setting 3",
+ "Setting 4", "Setting 5", "Setting 6", "Setting 7",
+};
+
+/*
+ * TDM1-0 bits: TDM Mode Setting
+ * 0 0 : Normal Mode
+ * 0 1 : TDM128 Mode
+ * 1 0 : TDM256 Mode
+ * 1 1 : TDM512 Mode
+ */
+static const char * const ak4458_tdm_select_texts[] = {
+ "Normal Mode", "TDM128 Mode", "TDM256 Mode", "TDM512 Mode"
+};
+
+/* FIR2-0 bits: FIR Filter Mode Setting */
+static const char * const ak4458_fir_select_texts[] = {
+ "Mode 0", "Mode 1", "Mode 2", "Mode 3",
+ "Mode 4", "Mode 5", "Mode 6", "Mode 7",
+};
+
+/* Mono and SELLR bit Setting (1~4) */
+static const char * const ak4458_dac_LR_select_texts[] = {
+ "Lch In, Rch In",
+ "Lch In, Rch In Invert",
+ "Lch In Invert, Rch In",
+ "Lch In Invert, Rch In Invert",
+ "Rch In, Lch In",
+ "Rch In, Lch In Invert",
+ "Rch In Invert, Lch In",
+ "Rch In Invert, Lch In Invert",
+ "Lch In, Lch In",
+ "Lch In, Lch In Invert",
+ "Lch In Invert, Lch In",
+ "Lch In Invert, Lch In Invert",
+ "Rch In, Rch In",
+ "Rch In, Rch In Invert",
+ "Rch In Invert, Rch In",
+ "Rch In Invert, Rch In Invert",
+};
+
+/* ATS1-0 bits Attenuation Speed */
+static const char * const ak4458_ats_select_texts[] = {
+ "4080/fs", "2040/fs", "510/fs", "255/fs",
+};
+
+/* DIF2 bit Audio Interface Format Setting(BICK fs) */
+static const char * const ak4458_dif_select_texts[] = {"32fs,48fs", "64fs",};
+
+static int get_DAC1_LR(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+ struct ak4458_priv *ak4458 = snd_soc_codec_get_drvdata(codec);
+
+ ucontrol->value.enumerated.item[0] = ak4458->lr[0];
+
+ return 0;
+};
+
+static int get_DAC2_LR(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+ struct ak4458_priv *ak4458 = snd_soc_codec_get_drvdata(codec);
+
+ ucontrol->value.enumerated.item[0] = ak4458->lr[1];
+
+ return 0;
+};
+
+static int get_DAC3_LR(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+ struct ak4458_priv *ak4458 = snd_soc_codec_get_drvdata(codec);
+
+ ucontrol->value.enumerated.item[0] = ak4458->lr[2];
+
+ return 0;
+};
+
+static int get_DAC4_LR(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+ struct ak4458_priv *ak4458 = snd_soc_codec_get_drvdata(codec);
+
+ ucontrol->value.enumerated.item[0] = ak4458->lr[3];
+
+ return 0;
+};
+
+static int get_digfil(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+ struct ak4458_priv *ak4458 = snd_soc_codec_get_drvdata(codec);
+
+ ucontrol->value.enumerated.item[0] = ak4458->digfil;
+
+ return 0;
+};
+
+static int get_sds(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+ struct ak4458_priv *ak4458 = snd_soc_codec_get_drvdata(codec);
+
+ ucontrol->value.enumerated.item[0] = ak4458->sds;
+
+ return 0;
+};
+
+static int set_digfil(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+ struct ak4458_priv *ak4458 = snd_soc_codec_get_drvdata(codec);
+
+ int reg_01, reg_02, reg_05, num;
+
+ num = ucontrol->value.enumerated.item[0];
+ if (num > 4)
+ return -EINVAL;
+
+ ak4458->digfil = num;
+
+ /* write SD bit */
+ reg_01 = snd_soc_read(codec, AK4458_01_CONTROL2);
+ reg_01 &= ~AK4458_SD_MASK;
+
+ reg_01 |= ((ak4458->digfil & 0x02) << 4);
+ snd_soc_write(codec, AK4458_01_CONTROL2, reg_01);
+
+ /* write SLOW bit */
+ reg_02 = snd_soc_read(codec, AK4458_02_CONTROL3);
+ reg_02 &= ~AK4458_SLOW_MASK;
+
+ reg_02 |= (ak4458->digfil & 0x01);
+ snd_soc_write(codec, AK4458_02_CONTROL3, reg_02);
+
+ /* write SSLOW bit */
+ reg_05 = snd_soc_read(codec, AK4458_05_CONTROL4);
+ reg_05 &= ~AK4458_SSLOW_MASK;
+
+ reg_05 |= ((ak4458->digfil & 0x04) >> 2);
+ snd_soc_write(codec, AK4458_05_CONTROL4, reg_05);
+
+ return 0;
+};
+
+static int set_sds(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+ struct ak4458_priv *ak4458 = snd_soc_codec_get_drvdata(codec);
+
+ int reg_0b, reg_0a;
+
+ if (ucontrol->value.enumerated.item[0] > 7)
+ return -EINVAL;
+
+ ak4458->sds = ucontrol->value.enumerated.item[0];
+
+ /* write SDS0 bit */
+ reg_0b = snd_soc_read(codec, AK4458_0B_CONTROL7);
+ reg_0b &= ~AK4458_SDS0__MASK;
+
+ reg_0b |= ((ak4458->sds & 0x01) << 4);
+ snd_soc_write(codec, AK4458_0B_CONTROL7, reg_0b);
+
+ /* write SDS1,2 bits */
+ reg_0a = snd_soc_read(codec, AK4458_0A_CONTROL6);
+ reg_0a &= ~AK4458_SDS12_MASK;
+
+ reg_0a |= ((ak4458->sds & 0x02) << 4);
+ reg_0a |= ((ak4458->sds & 0x04) << 2);
+ snd_soc_write(codec, AK4458_0A_CONTROL6, reg_0a);
+
+ return 0;
+
+};
+
+static int set_DAC1_LR(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+ struct ak4458_priv *ak4458 = snd_soc_codec_get_drvdata(codec);
+
+ int reg_02, reg_05;
+
+ if (ucontrol->value.enumerated.item[0] > 15)
+ return -EINVAL;
+
+ ak4458->lr[0] = ucontrol->value.enumerated.item[0];
+
+ /* write MONO1 and SELLR1 bits */
+ reg_02 = snd_soc_read(codec, AK4458_02_CONTROL3);
+ reg_02 &= ~AK4458_DAC1_LR_MASK;
+
+
+ reg_02 |= (ak4458->lr[0] & 0x08) << 0;
+ reg_02 |= (ak4458->lr[0] & 0x04) >> 1;
+ snd_soc_write(codec, AK4458_02_CONTROL3, reg_02);
+
+ /* write INVL1 and INVR1 bits */
+ reg_05 = snd_soc_read(codec, AK4458_05_CONTROL4);
+ reg_05 &= ~AK4458_DAC1_INV_MASK;
+
+ reg_05 |= (ak4458->lr[0] & 0x02) << 6;
+ reg_05 |= (ak4458->lr[0] & 0x01) << 6;
+ snd_soc_write(codec, AK4458_05_CONTROL4, reg_05);
+
+ return 0;
+
+};
+
+static int set_DAC2_LR(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+ struct ak4458_priv *ak4458 = snd_soc_codec_get_drvdata(codec);
+
+ int reg_0D, reg_05;
+
+ if (ucontrol->value.enumerated.item[0] > 15)
+ return -EINVAL;
+
+
+ ak4458->lr[1] = ucontrol->value.enumerated.item[0];
+
+ /* write MONO2 bit */
+ reg_0D = snd_soc_read(codec, AK4458_0D_CONTROL9);
+ reg_0D &= ~AK4458_DAC2_MASK1;
+
+ reg_0D |= (ak4458->lr[1] & 0x08) << 2;
+ snd_soc_write(codec, AK4458_0D_CONTROL9, reg_0D);
+
+ /* write SELLR2 and INVL1 and INVR1 bits */
+ reg_05 = snd_soc_read(codec, AK4458_05_CONTROL4);
+ reg_05 &= ~AK4458_DAC2_MASK2;
+
+ reg_05 |= (ak4458->lr[1] & 0x04) << 1;
+ reg_05 |= (ak4458->lr[1] & 0x02) << 4;
+ reg_05 |= (ak4458->lr[1] & 0x01) << 4;
+ snd_soc_write(codec, AK4458_05_CONTROL4, reg_05);
+
+ return 0;
+
+};
+
+static int set_DAC3_LR(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+ struct ak4458_priv *ak4458 = snd_soc_codec_get_drvdata(codec);
+
+ int reg_0C, reg_0D;
+
+ if (ucontrol->value.enumerated.item[0] > 15)
+ return -EINVAL;
+
+
+ ak4458->lr[2] = ucontrol->value.enumerated.item[0];
+
+ /* write MONO3 and SELLR3 bits */
+ reg_0D = snd_soc_read(codec, AK4458_0D_CONTROL9);
+ reg_0D &= ~AK4458_DAC3_LR_MASK;
+
+
+ reg_0D |= (ak4458->lr[2] & 0x08) << 3;
+ reg_0D |= (ak4458->lr[2] & 0x04) << 0;
+ snd_soc_write(codec, AK4458_0D_CONTROL9, reg_0D);
+
+ /* write INVL3 and INVR3 bits */
+ reg_0C = snd_soc_read(codec, AK4458_0C_CONTROL8);
+ reg_0C &= ~AK4458_DAC3_INV_MASK;
+
+ reg_0C |= (ak4458->lr[2] & 0x02) << 3;
+ reg_0C |= (ak4458->lr[2] & 0x01) << 5;
+ snd_soc_write(codec, AK4458_0C_CONTROL8, reg_0C);
+
+ return 0;
+
+};
+
+static int set_DAC4_LR(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+ struct ak4458_priv *ak4458 = snd_soc_codec_get_drvdata(codec);
+
+ int reg_0C, reg_0D;
+
+ if (ucontrol->value.enumerated.item[0] > 15)
+ return -EINVAL;
+
+
+ ak4458->lr[3] = ucontrol->value.enumerated.item[0];
+
+ /* write MONO4 and SELLR4 bits */
+ reg_0D = snd_soc_read(codec, AK4458_0D_CONTROL9);
+ reg_0D &= ~AK4458_DAC4_LR_MASK;
+
+
+ reg_0D |= (ak4458->lr[3] & 0x08) << 4;
+ reg_0D |= (ak4458->lr[3] & 0x04) << 1;
+ snd_soc_write(codec, AK4458_0D_CONTROL9, reg_0D);
+
+ /* write INVL4 and INVR4 bits */
+ reg_0C = snd_soc_read(codec, AK4458_0C_CONTROL8);
+ reg_0C &= ~AK4458_DAC4_INV_MASK;
+
+ reg_0C |= (ak4458->lr[3] & 0x02) << 5;
+ reg_0C |= (ak4458->lr[3] & 0x01) << 7;
+ snd_soc_write(codec, AK4458_0C_CONTROL8, reg_0C);
+
+ return 0;
+
+};
+
+static const struct soc_enum ak4458_dac_enum[] = {
+/*0*/ SOC_ENUM_SINGLE(AK4458_01_CONTROL2, 1,
+ ARRAY_SIZE(ak4458_dem_select_texts),
+ ak4458_dem_select_texts),
+/*1*/ SOC_ENUM_SINGLE(AK4458_0A_CONTROL6, 0,
+ ARRAY_SIZE(ak4458_dem_select_texts),
+ ak4458_dem_select_texts),
+/*2*/ SOC_ENUM_SINGLE(AK4458_0E_CONTROL10, 4,
+ ARRAY_SIZE(ak4458_dem_select_texts),
+ ak4458_dem_select_texts),
+/*3*/ SOC_ENUM_SINGLE(AK4458_0E_CONTROL10, 6,
+ ARRAY_SIZE(ak4458_dem_select_texts),
+ ak4458_dem_select_texts),
+/*4*/ SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(ak4458_digfil_select_texts),
+ ak4458_digfil_select_texts),
+/*5*/ SOC_ENUM_SINGLE(AK4458_02_CONTROL3, 2,
+ ARRAY_SIZE(ak4458_dzfb_select_texts),
+ ak4458_dzfb_select_texts),
+/*6*/ SOC_ENUM_SINGLE(AK4458_08_SOUND_CONTROL, 0,
+ ARRAY_SIZE(ak4458_sc_select_texts),
+ ak4458_sc_select_texts),
+/*7*/ SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(ak4458_sds_select_texts),
+ ak4458_sds_select_texts),
+/*8*/ SOC_ENUM_SINGLE(AK4458_0C_CONTROL8, 0,
+ ARRAY_SIZE(ak4458_fir_select_texts),
+ ak4458_fir_select_texts),
+/*9*/ SOC_ENUM_SINGLE(AK4458_0A_CONTROL6, 6,
+ ARRAY_SIZE(ak4458_tdm_select_texts),
+ ak4458_tdm_select_texts),
+/*10*/ SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(ak4458_dac_LR_select_texts),
+ ak4458_dac_LR_select_texts),
+/*11*/ SOC_ENUM_SINGLE(AK4458_0B_CONTROL7, 6,
+ ARRAY_SIZE(ak4458_ats_select_texts),
+ ak4458_ats_select_texts),
+/*12*/ SOC_ENUM_SINGLE(AK4458_00_CONTROL1, 3,
+ ARRAY_SIZE(ak4458_dif_select_texts),
+ ak4458_dif_select_texts),
+};
+
+static const struct snd_kcontrol_new ak4458_snd_controls[] = {
+ SOC_SINGLE_TLV("AK4458 L1ch Digital Volume",
+ AK4458_03_LCHATT, 0/*shift*/, 0xFF/*max value*/,
+ 0/*invert*/, latt_tlv),
+ SOC_SINGLE_TLV("AK4458 R1ch Digital Volume",
+ AK4458_04_RCHATT, 0, 0xFF, 0, ratt_tlv),
+ SOC_SINGLE_TLV("AK4458 L2ch Digital Volume",
+ AK4458_0F_L2CHATT, 0/*shift*/, 0xFF/*max value*/,
+ 0/*invert*/, latt_tlv),
+ SOC_SINGLE_TLV("AK4458 R2ch Digital Volume",
+ AK4458_10_R2CHATT, 0, 0xFF, 0, ratt_tlv),
+ SOC_SINGLE_TLV("AK4458 L3ch Digital Volume",
+ AK4458_11_L3CHATT, 0/*shift*/, 0xFF/*max value*/,
+ 0/*invert*/, latt_tlv),
+ SOC_SINGLE_TLV("AK4458 R3ch Digital Volume",
+ AK4458_12_R3CHATT, 0, 0xFF, 0, ratt_tlv),
+ SOC_SINGLE_TLV("AK4458 L4ch Digital Volume",
+ AK4458_13_L4CHATT, 0/*shift*/, 0xFF/*max value*/,
+ 0/*invert*/, latt_tlv),
+ SOC_SINGLE_TLV("AK4458 R4ch Digital Volume",
+ AK4458_14_R4CHATT, 0, 0xFF, 0, ratt_tlv),
+
+ SOC_ENUM("AK4458 De-emphasis Response DAC1", ak4458_dac_enum[0]),
+ SOC_ENUM("AK4458 De-emphasis Response DAC2", ak4458_dac_enum[1]),
+ SOC_ENUM("AK4458 De-emphasis Response DAC3", ak4458_dac_enum[2]),
+ SOC_ENUM("AK4458 De-emphasis Response DAC4", ak4458_dac_enum[3]),
+ SOC_ENUM_EXT("AK4458 Digital Filter Setting", ak4458_dac_enum[4],
+ get_digfil, set_digfil),
+ SOC_ENUM("AK4458 Inverting Enable of DZFB", ak4458_dac_enum[5]),
+ SOC_ENUM("AK4458 Sound Mode", ak4458_dac_enum[6]),
+ SOC_ENUM_EXT("AK4458 SDS Setting", ak4458_dac_enum[7],
+ get_sds, set_sds),
+ SOC_ENUM("AK4458 FIR Filter Mode Setting", ak4458_dac_enum[8]),
+ SOC_ENUM("AK4458 TDM Mode Setting", ak4458_dac_enum[9]),
+ SOC_ENUM_EXT("AK4458 DAC1 LRch Setting", ak4458_dac_enum[10],
+ get_DAC1_LR, set_DAC1_LR),
+ SOC_ENUM_EXT("AK4458 DAC2 LRch Setting", ak4458_dac_enum[10],
+ get_DAC2_LR, set_DAC2_LR),
+ SOC_ENUM_EXT("AK4458 DAC3 LRch Setting", ak4458_dac_enum[10],
+ get_DAC3_LR, set_DAC3_LR),
+ SOC_ENUM_EXT("AK4458 DAC4 LRch Setting", ak4458_dac_enum[10],
+ get_DAC4_LR, set_DAC4_LR),
+ SOC_ENUM("AK4458 Attenuation transition Time Setting",
+ ak4458_dac_enum[11]),
+ SOC_ENUM("AK4458 BICK fs Setting", ak4458_dac_enum[12]),
+};
+
+static const char * const ak4458_dac_select_texts[] = { "OFF", "ON" };
+
+static const struct soc_enum ak4458_dac_mux_enum =
+ SOC_ENUM_SINGLE(0, 0,
+ ARRAY_SIZE(ak4458_dac_select_texts),
+ ak4458_dac_select_texts);
+static const struct snd_kcontrol_new ak4458_dac1_mux_control =
+ SOC_DAPM_ENUM("DAC1 Switch", ak4458_dac_mux_enum);
+static const struct snd_kcontrol_new ak4458_dac2_mux_control =
+ SOC_DAPM_ENUM("DAC2 Switch", ak4458_dac_mux_enum);
+static const struct snd_kcontrol_new ak4458_dac3_mux_control =
+ SOC_DAPM_ENUM("DAC3 Switch", ak4458_dac_mux_enum);
+static const struct snd_kcontrol_new ak4458_dac4_mux_control =
+ SOC_DAPM_ENUM("DAC4 Switch", ak4458_dac_mux_enum);
+
+/* ak4458 dapm widgets */
+static const struct snd_soc_dapm_widget ak4458_dapm_widgets[] = {
+ SND_SOC_DAPM_DAC("AK4458 DAC1", NULL, AK4458_0A_CONTROL6, 2, 0),/*pw*/
+ SND_SOC_DAPM_AIF_IN("AK4458 SDTI", "Playback", 0, SND_SOC_NOPM, 0, 0),
+ SND_SOC_DAPM_OUTPUT("AK4458 AOUTA"),
+
+ SND_SOC_DAPM_DAC("AK4458 DAC2", NULL, AK4458_0A_CONTROL6, 3, 0),/*pw*/
+ SND_SOC_DAPM_OUTPUT("AK4458 AOUTB"),
+
+ SND_SOC_DAPM_DAC("AK4458 DAC3", NULL, AK4458_0B_CONTROL7, 2, 0),/*pw*/
+ SND_SOC_DAPM_OUTPUT("AK4458 AOUTC"),
+
+ SND_SOC_DAPM_DAC("AK4458 DAC4", NULL, AK4458_0B_CONTROL7, 3, 0),/*pw*/
+ SND_SOC_DAPM_OUTPUT("AK4458 AOUTD"),
+
+ SND_SOC_DAPM_MUX("DAC1 to AOUTA", SND_SOC_NOPM, 0, 0,
+ &ak4458_dac1_mux_control),/*nopm*/
+ SND_SOC_DAPM_MUX("DAC2 to AOUTB", SND_SOC_NOPM, 0, 0,
+ &ak4458_dac2_mux_control),/*nopm*/
+ SND_SOC_DAPM_MUX("DAC3 to AOUTC", SND_SOC_NOPM, 0, 0,
+ &ak4458_dac3_mux_control),/*nopm*/
+ SND_SOC_DAPM_MUX("DAC4 to AOUTD", SND_SOC_NOPM, 0, 0,
+ &ak4458_dac4_mux_control),/*nopm*/
+};
+
+static const struct snd_soc_dapm_route ak4458_intercon[] = {
+ {"DAC1 to AOUTA", "ON", "AK4458 SDTI"},
+ {"AK4458 DAC1", NULL, "DAC1 to AOUTA"},
+ {"AK4458 AOUTA", NULL, "AK4458 DAC1"},
+
+ {"DAC2 to AOUTB", "ON", "AK4458 SDTI"},
+ {"AK4458 DAC2", NULL, "DAC2 to AOUTB"},
+ {"AK4458 AOUTB", NULL, "AK4458 DAC2"},
+
+ {"DAC3 to AOUTC", "ON", "AK4458 SDTI"},
+ {"AK4458 DAC3", NULL, "DAC3 to AOUTC"},
+ {"AK4458 AOUTC", NULL, "AK4458 DAC3"},
+
+ {"DAC4 to AOUTD", "ON", "AK4458 SDTI"},
+ {"AK4458 DAC4", NULL, "DAC4 to AOUTD"},
+ {"AK4458 AOUTD", NULL, "AK4458 DAC4"},
+
+};
+
+static int ak4458_get_tdm_mode(struct ak4458_priv *ak4458)
+{
+ switch(ak4458->slots * ak4458->slot_width) {
+ case 128:
+ return 1;
+ case 256:
+ return 2;
+ case 512:
+ return 3;
+ default:
+ return 0;
+ }
+}
+
+static int ak4458_rstn_control(struct snd_soc_codec *codec, int bit)
+{
+ u8 rstn;
+
+ dev_dbg(codec->dev, "%s(%d)\n", __func__, __LINE__);
+
+ rstn = snd_soc_read(codec, AK4458_00_CONTROL1);
+ rstn &= ~AK4458_RSTN_MASK;
+
+ if (bit)
+ rstn |= AK4458_RSTN;
+
+ return snd_soc_write(codec, AK4458_00_CONTROL1, rstn);
+}
+
+static int ak4458_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params,
+ struct snd_soc_dai *dai)
+{
+ struct snd_soc_codec *codec = dai->codec;
+ struct ak4458_priv *ak4458 = snd_soc_codec_get_drvdata(codec);
+ u8 format, dsdsel0, dsdsel1, dchn;
+ int pcm_width = max(params_physical_width(params), ak4458->slot_width);
+ int ret, dsd_bclk, channels, channels_max;
+ bool is_dsd = false;
+
+#ifdef AK4458_ACKS_USE_MANUAL_MODE
+ u8 dfs1, dfs2;
+#endif
+ int nfs1;
+
+ channels = params_channels(params);
+ channels_max = dai->driver->playback.channels_max;
+
+ dev_dbg(dai->dev, "%s(%d)\n", __func__, __LINE__);
+
+ switch (params_format(params)) {
+ case SNDRV_PCM_FORMAT_DSD_U8:
+ case SNDRV_PCM_FORMAT_DSD_U16_LE:
+ case SNDRV_PCM_FORMAT_DSD_U16_BE:
+ case SNDRV_PCM_FORMAT_DSD_U32_LE:
+ case SNDRV_PCM_FORMAT_DSD_U32_BE:
+ is_dsd = true;
+ dsd_bclk = params_rate(params) * params_physical_width(params);
+ break;
+ }
+
+ format = snd_soc_read(codec, AK4458_00_CONTROL1);
+ format &= ~AK4458_DIF_MASK;
+
+ nfs1 = params_rate(params);
+ ak4458->fs = nfs1;
+
+ dsdsel0 = snd_soc_read(codec, AK4458_06_DSD1);
+ dsdsel0 &= ~AK4458_DSDSEL_MASK;
+
+ dsdsel1 = snd_soc_read(codec, AK4458_09_DSD2);
+ dsdsel1 &= ~AK4458_DSDSEL_MASK;
+
+ if (is_dsd) {
+ switch (dsd_bclk) {
+ case 2822400:
+ dsdsel0 |= 0;
+ dsdsel1 |= 0;
+ break;
+ case 5644800:
+ dsdsel0 |= 1;
+ dsdsel1 |= 0;
+ break;
+ case 11289600:
+ dsdsel0 |= 0;
+ dsdsel1 |= 1;
+ break;
+ default:
+ dev_err(dai->dev, "DSD512 not supported.\n");
+ return -EINVAL;
+ }
+
+ snd_soc_write(codec, AK4458_06_DSD1, dsdsel0);
+ snd_soc_write(codec, AK4458_09_DSD2, dsdsel1);
+ }
+
+#ifdef AK4458_ACKS_USE_MANUAL_MODE
+ dfs1 = snd_soc_read(codec, AK4458_01_CONTROL2);
+ dfs1 &= ~AK4458_DFS01_MASK;
+
+ dfs2 = snd_soc_read(codec, AK4458_05_CONTROL4);
+ dfs2 &= ~AK4458_DFS2__MASK;
+
+ switch (nfs1) {
+ case 8000:
+ case 11025:
+ case 16000:
+ case 22050:
+ case 32000:
+ case 44100:
+ case 48000:
+ dfs1 |= AK4458_DFS01_48KHZ;
+ dfs2 |= AK4458_DFS2__48KHZ;
+ break;
+ case 88200:
+ case 96000:
+ dfs1 |= AK4458_DFS01_96KHZ;
+ dfs2 |= AK4458_DFS2__96KHZ;
+ break;
+ case 176400:
+ case 192000:
+ dfs1 |= AK4458_DFS01_192KHZ;
+ dfs2 |= AK4458_DFS2__192KHZ;
+ break;
+ case 352800:
+ case 384000:
+ dfs1 |= AK4458_DFS01_384KHZ;
+ dfs2 |= AK4458_DFS2__384KHZ;
+ break;
+ case 705600:
+ case 768000:
+ dfs1 |= AK4458_DFS01_768KHZ;
+ dfs2 |= AK4458_DFS2__768KHZ;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ snd_soc_write(codec, AK4458_01_CONTROL2, dfs1);
+ snd_soc_write(codec, AK4458_05_CONTROL4, dfs2);
+
+ ret = ak4458_rstn_control(codec, 0);
+ if (ret)
+ return ret;
+
+ ret = ak4458_rstn_control(codec, 1);
+ if (ret)
+ return ret;
+#else
+ snd_soc_update_bits(codec, AK4458_00_CONTROL1, 0x80, 0x80);
+#endif
+
+ switch (pcm_width) {
+ case 16:
+ if (ak4458->fmt == SND_SOC_DAIFMT_I2S)
+ format |= AK4458_DIF_24BIT_I2S;
+ else
+ format |= AK4458_DIF_16BIT_LSB;
+ break;
+ case 32:
+ if (ak4458->fmt == SND_SOC_DAIFMT_I2S)
+ format |= AK4458_DIF_32BIT_I2S;
+ else if (ak4458->fmt == SND_SOC_DAIFMT_LEFT_J)
+ format |= AK4458_DIF_32BIT_MSB;
+ else if (ak4458->fmt == SND_SOC_DAIFMT_RIGHT_J)
+ format |= AK4458_DIF_32BIT_LSB;
+ else if (ak4458->fmt == SND_SOC_DAIFMT_DSP_B)
+ format |= AK4458_DIF_32BIT_MSB;
+ else if (ak4458->fmt == SND_SOC_DAIFMT_PDM)
+ format |= AK4458_DIF_32BIT_MSB;
+ else
+ return -EINVAL;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ snd_soc_write(codec, AK4458_00_CONTROL1, format);
+
+ /**
+ * Enable/disable Daisy Chain if in TDM mode and the number of played
+ * channels is bigger than the maximum supported number of channels
+ */
+ dchn = ak4458_get_tdm_mode(ak4458) &&
+ (ak4458->fmt == SND_SOC_DAIFMT_DSP_B) &&
+ (channels > channels_max ) ? AK4458_DCHAIN_MASK : 0;
+
+ snd_soc_update_bits(codec, AK4458_0B_CONTROL7, AK4458_DCHAIN_MASK, dchn);
+
+ ret = ak4458_rstn_control(codec, 0);
+ if (ret)
+ return ret;
+
+ ret = ak4458_rstn_control(codec, 1);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+static int ak4458_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id,
+ unsigned int freq, int dir)
+{
+ dev_dbg(dai->dev, "%s(%d)\n", __func__, __LINE__);
+
+ return 0;
+}
+
+static int ak4458_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
+{
+ struct snd_soc_codec *codec = dai->codec;
+ struct ak4458_priv *ak4458 = snd_soc_codec_get_drvdata(codec);
+ u8 format, dp = 0;
+ int ret;
+
+ /* set master/slave audio interface */
+ format = snd_soc_read(codec, AK4458_00_CONTROL1);
+
+ dev_dbg(dai->dev, "%s(%d) addr 00H = %02X\n",
+ __func__, __LINE__, format);
+
+ format &= ~AK4458_DIF_MASK;
+
+ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+ case SND_SOC_DAIFMT_CBS_CFS: /* Slave Mode */
+ break;
+ case SND_SOC_DAIFMT_CBM_CFM: /* Master Mode is not supported */
+ case SND_SOC_DAIFMT_CBS_CFM:
+ case SND_SOC_DAIFMT_CBM_CFS:
+ default:
+ dev_err(codec->dev, "Master mode unsupported\n");
+ return -EINVAL;
+ }
+
+ switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+ case SND_SOC_DAIFMT_I2S:
+ case SND_SOC_DAIFMT_LEFT_J:
+ case SND_SOC_DAIFMT_RIGHT_J:
+ ak4458->fmt = fmt & SND_SOC_DAIFMT_FORMAT_MASK;
+ break;
+ case SND_SOC_DAIFMT_DSP_B:
+ ak4458->fmt = fmt & SND_SOC_DAIFMT_FORMAT_MASK;
+ break;
+ case SND_SOC_DAIFMT_PDM:
+ ak4458->fmt = fmt & SND_SOC_DAIFMT_FORMAT_MASK;
+ dp = AK4458_DP_MASK; /* DSD mode */;
+ break;
+ default:
+ dev_err(codec->dev, "Audio format 0x%02X unsupported\n",
+ fmt & SND_SOC_DAIFMT_FORMAT_MASK);
+ return -EINVAL;
+ }
+
+ /* set format */
+ dev_dbg(dai->dev, "%s(%d) addr 00H = %02X\n",
+ __func__, __LINE__, format);
+
+ snd_soc_write(codec, AK4458_00_CONTROL1, format);
+ snd_soc_update_bits(codec, AK4458_02_CONTROL3, AK4458_DP_MASK, dp);
+
+ ret = ak4458_rstn_control(codec, 0);
+ if (ret)
+ return ret;
+
+ ret = ak4458_rstn_control(codec, 1);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+static int ak4458_trigger(struct snd_pcm_substream *substream, int cmd,
+ struct snd_soc_dai *codec_dai)
+{
+ int ret = 0;
+
+ dev_dbg(codec_dai->dev, "%s(%d)\n", __func__, __LINE__);
+ return ret;
+}
+
+
+static int ak4458_set_bias_level(struct snd_soc_codec *codec,
+ enum snd_soc_bias_level level)
+{
+ dev_dbg(codec->dev, "%s(%d)\n", __func__, __LINE__);
+
+ switch (level) {
+ case SND_SOC_BIAS_ON:
+ case SND_SOC_BIAS_PREPARE:
+ case SND_SOC_BIAS_STANDBY:
+ break;
+ case SND_SOC_BIAS_OFF:
+ break;
+ }
+
+ return 0;
+}
+
+static const int att_speed[] = { 4080, 2040, 510, 255 };
+
+static int ak4458_set_dai_mute(struct snd_soc_dai *dai, int mute)
+{
+ struct snd_soc_codec *codec = dai->codec;
+ struct ak4458_priv *ak4458 = snd_soc_codec_get_drvdata(codec);
+ int nfs, ndt, ret, reg;
+ int ats;
+
+ nfs = ak4458->fs;
+
+ reg = snd_soc_read(codec, AK4458_0B_CONTROL7);
+ ats = (reg & 0xC0) >> 6;
+
+ dev_dbg(dai->dev, "%s mute[%s] nfs[%d]\n", __func__,
+ mute ? "ON":"OFF", nfs);
+
+ ndt = att_speed[ats] / (nfs / 1000);
+
+ if (mute) { /* SMUTE: 1 , MUTE */
+ ret = snd_soc_update_bits(codec, AK4458_01_CONTROL2, 0x01, 1);
+ mdelay(ndt);
+ dev_dbg(dai->dev, "%s(%d) mdelay(%d ms)\n",
+ __func__, __LINE__, ndt);
+
+ if (gpio_is_valid(ak4458->mute_gpio))
+ gpio_set_value_cansleep(ak4458->mute_gpio, 1);
+
+ dev_dbg(dai->dev, "%s External Mute = ON\n", __func__);
+ } else { /* SMUTE: 0 ,NORMAL operation */
+ if (gpio_is_valid(ak4458->mute_gpio))
+ gpio_set_value_cansleep(ak4458->mute_gpio, 0);
+
+ dev_dbg(dai->dev, "%s External Mute = OFF\n", __func__);
+ ret = snd_soc_update_bits(codec, AK4458_01_CONTROL2, 0x01, 0);
+ mdelay(ndt);
+ dev_dbg(dai->dev, "%s(%d) mdelay(%d ms)\n",
+ __func__, __LINE__, ndt);
+ }
+ dev_dbg(dai->dev, "%s(%d) ret[%d]\n", __func__, __LINE__, ret);
+
+ return 0;
+}
+
+static int ak4458_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
+ unsigned int rx_mask, int slots, int slot_width)
+{
+ struct snd_soc_codec *codec = dai->codec;
+ struct ak4458_priv *ak4458 = snd_soc_codec_get_drvdata(codec);
+ int reg;
+
+ ak4458->slots = slots;
+ ak4458->slot_width = slot_width;
+
+ reg = snd_soc_read(codec, AK4458_0A_CONTROL6);
+ reg &= ~(0x3 << 6);
+ reg |= ak4458_get_tdm_mode(ak4458) << 6;
+ snd_soc_write(codec, AK4458_0A_CONTROL6, reg);
+
+ return 0;
+}
+
+#define AK4458_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
+ SNDRV_PCM_FMTBIT_S24_LE |\
+ SNDRV_PCM_FMTBIT_S32_LE |\
+ SNDRV_PCM_FMTBIT_DSD_U8 |\
+ SNDRV_PCM_FMTBIT_DSD_U16_LE |\
+ SNDRV_PCM_FMTBIT_DSD_U32_LE)
+
+static const unsigned int ak4458_rates[] = {
+ 8000, 11025, 16000, 22050,
+ 32000, 44100, 48000, 88200,
+ 96000, 176400, 192000, 352800,
+ 384000, 705600, 768000, 1411200,
+ 2822400,
+};
+
+static const struct snd_pcm_hw_constraint_list ak4458_rate_constraints = {
+ .count = ARRAY_SIZE(ak4458_rates),
+ .list = ak4458_rates,
+};
+
+static int ak4458_startup(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai) {
+ int ret;
+
+ ret = snd_pcm_hw_constraint_list(substream->runtime, 0,
+ SNDRV_PCM_HW_PARAM_RATE, &ak4458_rate_constraints);
+
+ return ret;
+}
+
+static struct snd_soc_dai_ops ak4458_dai_ops = {
+ .startup = ak4458_startup,
+ .hw_params = ak4458_hw_params,
+ .set_sysclk = ak4458_set_dai_sysclk,
+ .set_fmt = ak4458_set_dai_fmt,
+ .trigger = ak4458_trigger,
+ .digital_mute = ak4458_set_dai_mute,
+ .set_tdm_slot = ak4458_set_tdm_slot,
+};
+
+static struct snd_soc_dai_driver ak4458_dai = {
+ .name = "ak4458-aif",
+ .playback = {
+ .stream_name = "Playback",
+ .channels_min = 1,
+ .channels_max = 8,
+ .rates = SNDRV_PCM_RATE_KNOT,
+ .formats = AK4458_FORMATS,
+ },
+ .ops = &ak4458_dai_ops,
+};
+
+static int ak4458_init_reg(struct snd_soc_codec *codec)
+{
+ struct ak4458_priv *ak4458 = snd_soc_codec_get_drvdata(codec);
+ int ret;
+
+ dev_dbg(codec->dev, "%s(%d)\n", __func__, __LINE__);
+
+ /* External Mute ON */
+ if (gpio_is_valid(ak4458->mute_gpio))
+ gpio_set_value_cansleep(ak4458->mute_gpio, 1);
+
+ if (gpio_is_valid(ak4458->pdn_gpio)) {
+ gpio_set_value_cansleep(ak4458->pdn_gpio, 0);
+ usleep_range(1000, 2000);
+ gpio_set_value_cansleep(ak4458->pdn_gpio, 1);
+ usleep_range(1000, 2000);
+ }
+
+ ak4458_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
+
+#ifndef AK4458_ACKS_USE_MANUAL_MODE
+ snd_soc_update_bits(codec, AK4458_00_CONTROL1,
+ 0x80, 0x80); /* ACKS bit = 1; 10000000 */
+ dev_dbg(codec->dev, "%s ACKS bit = 1\n", __func__);
+#endif
+
+ ret = ak4458_rstn_control(codec, 0);
+ if (ret)
+ return ret;
+
+ ret = ak4458_rstn_control(codec, 1);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+static int ak4458_codec_probe(struct snd_soc_codec *codec)
+{
+ struct ak4458_priv *ak4458 = snd_soc_codec_get_drvdata(codec);
+ int ret;
+
+ dev_dbg(codec->dev, "%s(%d)\n", __func__, __LINE__);
+
+ ret = ak4458_init_reg(codec);
+
+ ak4458->fs = 48000;
+
+ return ret;
+}
+
+static int ak4458_codec_remove(struct snd_soc_codec *codec)
+{
+ dev_dbg(codec->dev, "%s(%d)\n", __func__, __LINE__);
+
+ ak4458_set_bias_level(codec, SND_SOC_BIAS_OFF);
+
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int ak4458_runtime_suspend(struct device *dev)
+{
+ struct ak4458_priv *ak4458 = dev_get_drvdata(dev);
+
+ regcache_cache_only(ak4458->regmap, true);
+
+ if (gpio_is_valid(ak4458->pdn_gpio)) {
+ gpio_set_value_cansleep(ak4458->pdn_gpio, 0);
+ usleep_range(1000, 2000);
+ }
+
+ if (gpio_is_valid(ak4458->mute_gpio))
+ gpio_set_value_cansleep(ak4458->mute_gpio, 0);
+
+ return 0;
+}
+
+static int ak4458_runtime_resume(struct device *dev)
+{
+ struct ak4458_priv *ak4458 = dev_get_drvdata(dev);
+
+ if (gpio_is_valid(ak4458->mute_gpio))
+ gpio_set_value_cansleep(ak4458->mute_gpio, 1);
+
+ if (gpio_is_valid(ak4458->pdn_gpio)) {
+ gpio_set_value_cansleep(ak4458->pdn_gpio, 0);
+ usleep_range(1000, 2000);
+ gpio_set_value_cansleep(ak4458->pdn_gpio, 1);
+ usleep_range(1000, 2000);
+ }
+
+ regcache_cache_only(ak4458->regmap, false);
+ regcache_mark_dirty(ak4458->regmap);
+
+ return regcache_sync(ak4458->regmap);
+}
+#endif /* CONFIG_PM */
+
+struct snd_soc_codec_driver soc_codec_dev_ak4458 = {
+ .probe = ak4458_codec_probe,
+ .remove = ak4458_codec_remove,
+ .set_bias_level = ak4458_set_bias_level,
+
+ .component_driver = {
+ .controls = ak4458_snd_controls,
+ .num_controls = ARRAY_SIZE(ak4458_snd_controls),
+ .dapm_widgets = ak4458_dapm_widgets,
+ .num_dapm_widgets = ARRAY_SIZE(ak4458_dapm_widgets),
+ .dapm_routes = ak4458_intercon,
+ .num_dapm_routes = ARRAY_SIZE(ak4458_intercon),
+ },
+};
+EXPORT_SYMBOL_GPL(soc_codec_dev_ak4458);
+
+const struct regmap_config ak4458_i2c_regmap_config = {
+ .reg_bits = 8,
+ .val_bits = 8,
+
+ .max_register = AK4458_14_R4CHATT,
+ .reg_defaults = ak4458_reg_defaults,
+ .num_reg_defaults = ARRAY_SIZE(ak4458_reg_defaults),
+ .cache_type = REGCACHE_RBTREE,
+};
+EXPORT_SYMBOL_GPL(ak4458_i2c_regmap_config);
+
+const struct regmap_config ak4458_spi_regmap_config = {
+ .reg_bits = 8,
+ .val_bits = 8,
+
+ .max_register = AK4458_14_R4CHATT,
+ .rd_table = &ak4458_spi_readable_regs,
+ .reg_defaults = ak4458_reg_defaults,
+ .num_reg_defaults = ARRAY_SIZE(ak4458_reg_defaults),
+ .cache_type = REGCACHE_RBTREE,
+};
+EXPORT_SYMBOL_GPL(ak4458_spi_regmap_config);
+
+int ak4458_probe(struct device *dev, struct regmap *regmap)
+{
+ struct ak4458_priv *ak4458;
+ struct device_node *np = dev->of_node;
+ int ret;
+ int i;
+
+ ak4458 = devm_kzalloc(dev, sizeof(*ak4458), GFP_KERNEL);
+ if (!ak4458)
+ return -ENOMEM;
+
+ dev_set_drvdata(dev, ak4458);
+
+ ak4458->dev = dev;
+ ak4458->regmap = regmap;
+
+ ak4458->pdn_gpio = of_get_named_gpio(np, "ak4458,pdn-gpio", 0);
+ if (gpio_is_valid(ak4458->pdn_gpio)) {
+ ret = devm_gpio_request_one(dev, ak4458->pdn_gpio,
+ GPIOF_OUT_INIT_LOW, "ak4458,pdn");
+ if (ret) {
+ dev_err(dev, "unable to get pdn gpio\n");
+ return ret;
+ }
+ }
+
+ ak4458->mute_gpio = of_get_named_gpio(np, "ak4458,mute_gpio", 0);
+ if (gpio_is_valid(ak4458->mute_gpio)) {
+ ret = devm_gpio_request_one(dev, ak4458->mute_gpio,
+ GPIOF_OUT_INIT_LOW, "ak4458,mute");
+ if (ret) {
+ dev_err(dev, "unable to get mute gpio\n");
+ return ret;
+ }
+ }
+
+ for (i = 0; i < ARRAY_SIZE(ak4458->supplies); i++)
+ ak4458->supplies[i].supply = ak4458_supply_names[i];
+
+ ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(ak4458->supplies),
+ ak4458->supplies);
+ if (ret != 0) {
+ dev_err(dev, "Failed to request supplies: %d\n", ret);
+ return ret;
+ }
+
+ ret = regulator_bulk_enable(ARRAY_SIZE(ak4458->supplies),
+ ak4458->supplies);
+ if (ret != 0) {
+ dev_err(dev, "Failed to enable supplies: %d\n", ret);
+ return ret;
+ }
+
+ ret = snd_soc_register_codec(dev, &soc_codec_dev_ak4458,
+ &ak4458_dai, 1);
+ if (ret < 0) {
+ dev_err(dev, "Failed to register CODEC: %d\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(ak4458_probe);
+
+void ak4458_remove(struct device *dev)
+{
+ snd_soc_unregister_codec(dev);
+}
+EXPORT_SYMBOL_GPL(ak4458_remove);
+
+const struct dev_pm_ops ak4458_pm = {
+ SET_RUNTIME_PM_OPS(ak4458_runtime_suspend, ak4458_runtime_resume, NULL)
+ SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, pm_runtime_force_resume)
+};
+EXPORT_SYMBOL_GPL(ak4458_pm);
+
+MODULE_AUTHOR("Junichi Wakasugi <wakasugi.jb@om.asahi-kasei.co.jp>");
+MODULE_AUTHOR("Mihai Serban <mihai.serban@nxp.com>");
+MODULE_DESCRIPTION("ASoC AK4458 DAC driver");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/ak4458.h b/sound/soc/codecs/ak4458.h
new file mode 100644
index 000000000000..7a83c2e236f1
--- /dev/null
+++ b/sound/soc/codecs/ak4458.h
@@ -0,0 +1,135 @@
+/*
+ * ak4458.h -- audio driver for AK4458
+ *
+ * Copyright (C) 2016 Asahi Kasei Microdevices Corporation
+ * Author: Tsuyoshi Mutsuro
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _AK4458_H
+#define _AK4458_H
+
+#include <linux/regmap.h>
+
+/* Settings */
+#define AK4458_ACKS_USE_MANUAL_MODE
+
+#define AK4458_00_CONTROL1 0x00
+#define AK4458_01_CONTROL2 0x01
+#define AK4458_02_CONTROL3 0x02
+#define AK4458_03_LCHATT 0x03
+#define AK4458_04_RCHATT 0x04
+#define AK4458_05_CONTROL4 0x05
+#define AK4458_06_DSD1 0x06
+#define AK4458_07_CONTROL5 0x07
+#define AK4458_08_SOUND_CONTROL 0x08
+#define AK4458_09_DSD2 0x09
+#define AK4458_0A_CONTROL6 0x0A
+#define AK4458_0B_CONTROL7 0x0B
+#define AK4458_0C_CONTROL8 0x0C
+#define AK4458_0D_CONTROL9 0x0D
+#define AK4458_0E_CONTROL10 0x0E
+#define AK4458_0F_L2CHATT 0x0F
+#define AK4458_10_R2CHATT 0x10
+#define AK4458_11_L3CHATT 0x11
+#define AK4458_12_R3CHATT 0x12
+#define AK4458_13_L4CHATT 0x13
+#define AK4458_14_R4CHATT 0x14
+
+/* Bitfield Definitions */
+
+/* AK4458_00_CONTROL1 (0x00) Fields */
+//Addr Register Name D7 D6 D5 D4 D3 D2 D1 D0
+//00H Control 1 ACKS 0 0 0 DIF2 DIF1 DIF0 RSTN
+
+//MONO1 & SELLR1 bits
+#define AK4458_DAC1_LR_MASK 0x0A
+#define AK4458_DAC1_INV_MASK 0xC0
+
+//MONO2 & SELLR2 bits
+#define AK4458_DAC2_MASK1 0x20
+#define AK4458_DAC2_MASK2 0x38
+
+//MONO3 & SELLR3 bits
+#define AK4458_DAC3_LR_MASK 0x44
+#define AK4458_DAC3_INV_MASK 0x30
+
+//MONO4 & SELLR4 bits
+#define AK4458_DAC4_LR_MASK 0x88
+#define AK4458_DAC4_INV_MASK 0xC0
+
+
+//SDS2-0 bits
+#define AK4458_SDS0__MASK 0x10
+#define AK4458_SDS12_MASK 0x30
+
+//Digital Filter (SD, SLOW, SSLOW)
+#define AK4458_SD_MASK 0x20
+#define AK4458_SLOW_MASK 0x01
+#define AK4458_SSLOW_MASK 0x01
+
+//DIF2 1 0
+// x 1 0 MSB justified Figure 3 (default)
+// x 1 1 I2S Compliment Figure 4
+#define AK4458_DIF_MASK 0x0E
+#define AK4458_DIF_MSB_LOW_FS_MODE (2 << 1)
+#define AK4458_DIF_I2S_LOW_FS_MODE (3 << 1)
+
+#define AK4458_DIF_16BIT_LSB (0 << 1)
+#define AK4458_DIF_20BIT_LSB (1 << 1)
+#define AK4458_DIF_24BIT_MSB (2 << 1)
+#define AK4458_DIF_24BIT_I2S (3 << 1)
+#define AK4458_DIF_24BIT_LSB (4 << 1)
+#define AK4458_DIF_32BIT_LSB (5 << 1)
+#define AK4458_DIF_32BIT_MSB (6 << 1)
+#define AK4458_DIF_32BIT_I2S (7 << 1)
+
+
+// ACKS is Auto mode so disable the Manual feature
+//#define AK4458_ACKS_USE_MANUAL_MODE
+/* AK4458_00_CONTROL1 (0x00) D0 bit */
+#define AK4458_RSTN_MASK 0x01
+#define AK4458_RSTN (0x1 << 0)
+
+
+#ifdef AK4458_ACKS_USE_MANUAL_MODE
+/* AK4458_01_CONTROL2 (0x01) and AK4458_05_CONTROL4 (0x05) Fields */
+#define AK4458_DFS01_MASK 0x18
+#define AK4458_DFS2__MASK 0x02
+#define AK4458_DFS01_48KHZ (0x0 << 3) // 30kHz to 54kHz
+#define AK4458_DFS2__48KHZ (0x0 << 1) // 30kHz to 54kHz
+
+#define AK4458_DFS01_96KHZ (0x1 << 3) // 54kHz to 108kHz
+#define AK4458_DFS2__96KHZ (0x0 << 1) // 54kHz to 108kHz
+
+#define AK4458_DFS01_192KHZ (0x2 << 3) // 120kHz to 216kHz
+#define AK4458_DFS2__192KHZ (0x0 << 1) // 120kHz to 216kHz
+
+#define AK4458_DFS01_384KHZ (0x0 << 3) // 384kHz
+#define AK4458_DFS2__384KHZ (0x1 << 1) // 384kHz
+
+#define AK4458_DFS01_768KHZ (0x1 << 3) // 768kHz
+#define AK4458_DFS2__768KHZ (0x1 << 1) // 768kHz
+#endif
+
+#define AK4458_DSDSEL_MASK (0x1 << 0)
+#define AK4458_DP_MASK (0x1 << 7)
+
+#define AK4458_DCHAIN_MASK (0x1 << 1)
+
+extern const struct regmap_config ak4458_i2c_regmap_config;
+extern const struct regmap_config ak4458_spi_regmap_config;
+extern const struct dev_pm_ops ak4458_pm;
+
+int ak4458_probe(struct device *dev, struct regmap *regmap);
+void ak4458_remove(struct device *dev);
+
+#endif
diff --git a/sound/soc/codecs/ak4497.c b/sound/soc/codecs/ak4497.c
new file mode 100644
index 000000000000..eee1afb81b8c
--- /dev/null
+++ b/sound/soc/codecs/ak4497.c
@@ -0,0 +1,1094 @@
+/*
+ * ak4497.c -- audio driver for AK4497
+ *
+ * Copyright (C) 2016 Asahi Kasei Microdevices Corporation
+ * Copyright (C) 2017, NXP
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/i2c.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/gpio.h>
+#include <sound/soc.h>
+#include <sound/soc-dapm.h>
+#include <sound/initval.h>
+#include <sound/tlv.h>
+#include <sound/pcm_params.h>
+#include <linux/of_gpio.h>
+#include <linux/regmap.h>
+#include <sound/pcm_params.h>
+#include <linux/pm_runtime.h>
+#include <linux/regulator/consumer.h>
+
+#include "ak4497.h"
+
+//#define AK4497_DEBUG //used at debug mode
+#define AK4497_NUM_SUPPLIES 2
+static const char *ak4497_supply_names[AK4497_NUM_SUPPLIES] = {
+ "DVDD",
+ "AVDD",
+};
+
+/* AK4497 Codec Private Data */
+struct ak4497_priv {
+ struct i2c_client *i2c;
+ struct regmap *regmap;
+ int fs1; /* Sampling Frequency */
+ int nBickFreq; /* 0: 48fs for 24bit, 1: 64fs or more for 32bit */
+ int nTdmSds;
+ int pdn_gpio;
+ int mute_gpio;
+ int fmt;
+ struct regulator_bulk_data supplies[AK4497_NUM_SUPPLIES];
+};
+
+/* ak4497 register cache & default register settings */
+static const struct reg_default ak4497_reg[] = {
+ { AK4497_00_CONTROL1, 0x0C},
+ { AK4497_01_CONTROL2, 0x22},
+ { AK4497_02_CONTROL3, 0x00},
+ { AK4497_03_LCHATT, 0xFF},
+ { AK4497_04_RCHATT, 0xFF},
+ { AK4497_05_CONTROL4, 0x00},
+ { AK4497_06_DSD1, 0x00},
+ { AK4497_07_CONTROL5, 0x00},
+ { AK4497_08_SOUNDCONTROL, 0x00},
+ { AK4497_09_DSD2, 0x00},
+ { AK4497_0A_CONTROL7, 0x04},
+ { AK4497_0B_CONTROL8, 0x00},
+ { AK4497_0C_RESERVED, 0x00},
+ { AK4497_0D_RESERVED, 0x00},
+ { AK4497_0E_RESERVED, 0x00},
+ { AK4497_0F_RESERVED, 0x00},
+ { AK4497_10_RESERVED, 0x00},
+ { AK4497_11_RESERVED, 0x00},
+ { AK4497_12_RESERVED, 0x00},
+ { AK4497_13_RESERVED, 0x00},
+ { AK4497_14_RESERVED, 0x00},
+ { AK4497_15_DFSREAD, 0x00},
+};
+
+/* Volume control:
+ * from -127 to 0 dB in 0.5 dB steps (mute instead of -127.5 dB)
+ */
+static DECLARE_TLV_DB_SCALE(latt_tlv, -12750, 50, 0);
+static DECLARE_TLV_DB_SCALE(ratt_tlv, -12750, 50, 0);
+
+static const char * const ak4497_ecs_select_texts[] = {"768kHz", "384kHz"};
+
+static const char * const ak4497_dem_select_texts[] = {
+ "44.1kHz", "OFF", "48kHz", "32kHz"};
+static const char * const ak4497_dzfm_select_texts[] = {
+ "Separated", "ANDed"};
+
+static const char * const ak4497_sellr_select_texts[] = {
+ "Rch", "Lch"};
+static const char * const ak4497_dckb_select_texts[] = {
+ "Falling", "Rising"};
+static const char * const ak4497_dcks_select_texts[] = {
+ "512fs", "768fs"};
+
+static const char * const ak4497_dsdd_select_texts[] = {
+ "Normal", "Volume Bypass"};
+
+static const char * const ak4497_sc_select_texts[] = {
+ "Setting 1", "Setting 2", "Setting 3"};
+static const char * const ak4497_dsdf_select_texts[] = {
+ "50kHz", "150kHz"};
+static const char * const ak4497_dsd_input_path_select[] = {
+ "16_17_19pin", "3_4_5pin"};
+static const char * const ak4497_ats_select_texts[] = {
+ "4080/fs", "2040/fs", "510/fs", "255/fs"};
+
+static const struct soc_enum ak4497_dac_enum[] = {
+ SOC_ENUM_SINGLE(AK4497_00_CONTROL1, 5,
+ ARRAY_SIZE(ak4497_ecs_select_texts),
+ ak4497_ecs_select_texts),
+ SOC_ENUM_SINGLE(AK4497_01_CONTROL2, 1,
+ ARRAY_SIZE(ak4497_dem_select_texts),
+ ak4497_dem_select_texts),
+ SOC_ENUM_SINGLE(AK4497_01_CONTROL2, 6,
+ ARRAY_SIZE(ak4497_dzfm_select_texts),
+ ak4497_dzfm_select_texts),
+ SOC_ENUM_SINGLE(AK4497_02_CONTROL3, 1,
+ ARRAY_SIZE(ak4497_sellr_select_texts),
+ ak4497_sellr_select_texts),
+ SOC_ENUM_SINGLE(AK4497_02_CONTROL3, 4,
+ ARRAY_SIZE(ak4497_dckb_select_texts),
+ ak4497_dckb_select_texts),
+ SOC_ENUM_SINGLE(AK4497_02_CONTROL3, 5,
+ ARRAY_SIZE(ak4497_dcks_select_texts),
+ ak4497_dcks_select_texts),
+ SOC_ENUM_SINGLE(AK4497_06_DSD1, 1,
+ ARRAY_SIZE(ak4497_dsdd_select_texts),
+ ak4497_dsdd_select_texts),
+ SOC_ENUM_SINGLE(AK4497_08_SOUNDCONTROL, 0,
+ ARRAY_SIZE(ak4497_sc_select_texts),
+ ak4497_sc_select_texts),
+ SOC_ENUM_SINGLE(AK4497_09_DSD2, 1,
+ ARRAY_SIZE(ak4497_dsdf_select_texts),
+ ak4497_dsdf_select_texts),
+ SOC_ENUM_SINGLE(AK4497_09_DSD2, 2,
+ ARRAY_SIZE(ak4497_dsd_input_path_select),
+ ak4497_dsd_input_path_select),
+ SOC_ENUM_SINGLE(AK4497_0B_CONTROL8, 6,
+ ARRAY_SIZE(ak4497_ats_select_texts),
+ ak4497_ats_select_texts),
+};
+
+static const char * const ak4497_dsdsel_select_texts[] = {
+ "64fs", "128fs", "256fs", "512fs"};
+static const char * const ak4497_bickfreq_select[] = {"48fs", "64fs"};
+
+static const char * const ak4497_tdm_sds_select[] = {
+ "L1R1", "TDM128_L1R1", "TDM128_L2R2",
+ "TDM256_L1R1", "TDM256_L2R2", "TDM256_L3R3", "TDM256_L4R4",
+ "TDM512_L1R1", "TDM512_L2R2", "TDM512_L3R3", "TDM512_L4R4",
+ "TDM512_L5R5", "TDM512_L6R6", "TDM512_L7R7", "TDM512_L8R8",
+};
+
+static const char * const ak4497_adfs_select[] = {
+ "Normal Speed Mode", "Double Speed Mode", "Quad Speed Mode",
+ "Quad Speed Mode", "Oct Speed Mode", "Hex Speed Mode", "Oct Speed Mode",
+ "Hex Speed Mode"
+};
+
+static const struct soc_enum ak4497_dac_enum2[] = {
+ SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(ak4497_dsdsel_select_texts),
+ ak4497_dsdsel_select_texts),
+ SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(ak4497_bickfreq_select),
+ ak4497_bickfreq_select),
+ SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(ak4497_tdm_sds_select),
+ ak4497_tdm_sds_select),
+ SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(ak4497_adfs_select),
+ ak4497_adfs_select)
+};
+
+int ak4497_read(struct snd_soc_codec *codec, unsigned int reg,
+ unsigned int *val)
+{
+ int ret;
+
+ ret = snd_soc_component_read(&codec->component, reg, val);
+ if (ret < 0)
+ dev_err(codec->dev, "Register %u read failed, ret=%d.\n", reg, ret);
+
+ return ret;
+}
+
+static int ak4497_get_dsdsel(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+ unsigned int dsdsel0, dsdsel1;
+
+ ak4497_read(codec, AK4497_06_DSD1, &dsdsel0);
+ dsdsel0 &= AK4497_DSDSEL0;
+
+ ak4497_read(codec, AK4497_09_DSD2, &dsdsel1);
+ dsdsel1 &= AK4497_DSDSEL1;
+
+ ucontrol->value.enumerated.item[0] = ((dsdsel1 << 1) | dsdsel0);
+
+ return 0;
+}
+
+static int ak4497_set_dsdsel(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+ unsigned int dsdsel = ucontrol->value.enumerated.item[0];
+
+ switch (dsdsel) {
+ case 0: /* 2.8224MHz */
+ snd_soc_update_bits(codec, AK4497_06_DSD1, 0x01, 0x00);
+ snd_soc_update_bits(codec, AK4497_09_DSD2, 0x01, 0x00);
+ break;
+ case 1: /* 5.6448MHz */
+ snd_soc_update_bits(codec, AK4497_06_DSD1, 0x01, 0x01);
+ snd_soc_update_bits(codec, AK4497_09_DSD2, 0x01, 0x00);
+ break;
+ case 2: /* 11.2896MHz */
+ snd_soc_update_bits(codec, AK4497_06_DSD1, 0x01, 0x00);
+ snd_soc_update_bits(codec, AK4497_09_DSD2, 0x01, 0x01);
+ break;
+ case 3: /* 22.5792MHz */
+ snd_soc_update_bits(codec, AK4497_06_DSD1, 0x01, 0x01);
+ snd_soc_update_bits(codec, AK4497_09_DSD2, 0x01, 0x01);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int ak4497_get_bickfs(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+ struct ak4497_priv *ak4497 = snd_soc_codec_get_drvdata(codec);
+
+ ucontrol->value.enumerated.item[0] = ak4497->nBickFreq;
+
+ return 0;
+}
+
+static int ak4497_set_bickfs(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+ struct ak4497_priv *ak4497 = snd_soc_codec_get_drvdata(codec);
+
+ ak4497->nBickFreq = ucontrol->value.enumerated.item[0];
+
+ return 0;
+}
+
+static int ak4497_get_tdmsds(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+ struct ak4497_priv *ak4497 = snd_soc_codec_get_drvdata(codec);
+
+ ucontrol->value.enumerated.item[0] = ak4497->nTdmSds;
+
+ return 0;
+}
+
+static int ak4497_set_tdmsds(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+ struct ak4497_priv *ak4497 = snd_soc_codec_get_drvdata(codec);
+ int regA, regB;
+
+ ak4497->nTdmSds = ucontrol->value.enumerated.item[0];
+
+ if (ak4497->nTdmSds == 0)
+ regB = 0; /* SDS0 bit = 0 */
+ else
+ regB = (1 & (ak4497->nTdmSds - 1)); /* SDS0 bit = 1 */
+
+ switch (ak4497->nTdmSds) {
+ case 0:
+ regA = 0; /* Normal */
+ break;
+ case 1:
+ case 2:
+ regA = 4; /* TDM128 TDM1-0bits = 1 */
+ break;
+ case 3:
+ case 4:
+ regA = 8; /* TDM128 TDM1-0bits = 2 */
+ break;
+ case 5:
+ case 6:
+ regA = 9; /* TDM128 TDM1-0bits = 2 */
+ break;
+ case 7:
+ case 8:
+ regA = 0xC; /* TDM128 TDM1-0bits = 3 */
+ break;
+ case 9:
+ case 10:
+ regA = 0xD; /* TDM128 TDM1-0bits = 3 */
+ break;
+ case 11:
+ case 12:
+ regA = 0xE; /* TDM128 TDM1-0bits = 3 */
+ break;
+ case 13:
+ case 14:
+ regA = 0xF; /* TDM128 TDM1-0bits = 3 */
+ break;
+ default:
+ regA = 0;
+ regB = 0;
+ break;
+ }
+
+ regA <<= 4;
+ regB <<= 4;
+
+ snd_soc_update_bits(codec, AK4497_0A_CONTROL7, 0xF0, regA);
+ snd_soc_update_bits(codec, AK4497_0B_CONTROL8, 0x10, regB);
+
+ return 0;
+}
+
+static int ak4497_get_adfs(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+ unsigned int nADFSbit;
+
+ ak4497_read(codec, AK4497_15_DFSREAD, &nADFSbit);
+ nADFSbit &= 0x7;
+
+ ucontrol->value.enumerated.item[0] = nADFSbit;
+
+ return 0;
+}
+
+static int ak4497_set_adfs(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ pr_debug("AK4497 : ADFS is read only\n");
+
+ return 0;
+}
+
+static const char * const gain_control_texts[] = {
+ "2.8_2.8Vpp", "2.8_2.5Vpp", "2.5_2.5Vpp", "3.75_3.75Vpp", "3.75_2.5Vpp"
+};
+
+static const unsigned int gain_control_values[] = {
+ 0, 1, 2, 4, 5
+};
+
+static const struct soc_enum ak4497_gain_control_enum =
+ SOC_VALUE_ENUM_SINGLE(AK4497_07_CONTROL5, 1, 7,
+ ARRAY_SIZE(gain_control_texts),
+ gain_control_texts,
+ gain_control_values);
+
+#ifdef AK4497_DEBUG
+
+static const char * const test_reg_select[] = {
+ "read AK4497 Reg 00:0B",
+ "read AK4497 Reg 15"
+};
+
+static const struct soc_enum ak4497_enum[] = {
+ SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(test_reg_select), test_reg_select),
+};
+
+static int nTestRegNo;
+
+static int get_test_reg(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ /* Get the current output routing */
+ ucontrol->value.enumerated.item[0] = nTestRegNo;
+
+ return 0;
+}
+
+static int set_test_reg(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+ u32 currMode = ucontrol->value.enumerated.item[0];
+ int i, regs, rege;
+ unsigned int value;
+
+ nTestRegNo = currMode;
+
+ if (nTestRegNo == 0) {
+ regs = 0x00;
+ rege = 0x0B;
+ } else {
+ regs = 0x15;
+ rege = 0x15;
+ }
+
+ for (i = regs; i <= rege; i++) {
+ ak4497_read(codec, i, &value);
+ pr_debug("***AK4497 Addr,Reg=(%x, %x)\n", i, value);
+ }
+
+ return 0;
+}
+#endif
+
+static const struct snd_kcontrol_new ak4497_snd_controls[] = {
+ SOC_SINGLE_TLV("AK4497 Lch Digital Volume",
+ AK4497_03_LCHATT, 0, 0xFF, 0, latt_tlv),
+ SOC_SINGLE_TLV("AK4497 Rch Digital Volume",
+ AK4497_04_RCHATT, 0, 0xFF, 0, ratt_tlv),
+
+ SOC_ENUM("AK4497 EX DF I/F clock", ak4497_dac_enum[0]),
+ SOC_ENUM("AK4497 De-emphasis Response", ak4497_dac_enum[1]),
+ SOC_ENUM("AK4497 Data Zero Detect Mode", ak4497_dac_enum[2]),
+ SOC_ENUM("AK4497 Data Selection at Mono Mode", ak4497_dac_enum[3]),
+
+ SOC_ENUM("AK4497 Polarity of DCLK", ak4497_dac_enum[4]),
+ SOC_ENUM("AK4497 DCKL Frequency", ak4497_dac_enum[5]),
+
+ SOC_ENUM("AK4497 DDSD Play Back Path", ak4497_dac_enum[6]),
+ SOC_ENUM("AK4497 Sound control", ak4497_dac_enum[7]),
+ SOC_ENUM("AK4497 Cut Off of DSD Filter", ak4497_dac_enum[8]),
+
+ SOC_ENUM_EXT("AK4497 DSD Data Stream", ak4497_dac_enum2[0],
+ ak4497_get_dsdsel, ak4497_set_dsdsel),
+ SOC_ENUM_EXT("AK4497 BICK Frequency Select", ak4497_dac_enum2[1],
+ ak4497_get_bickfs, ak4497_set_bickfs),
+ SOC_ENUM_EXT("AK4497 TDM Data Select", ak4497_dac_enum2[2],
+ ak4497_get_tdmsds, ak4497_set_tdmsds),
+
+ SOC_SINGLE("AK4497 External Digital Filter", AK4497_00_CONTROL1,
+ 6, 1, 0),
+ SOC_SINGLE("AK4497 MCLK Frequency Auto Setting", AK4497_00_CONTROL1,
+ 7, 1, 0),
+ SOC_SINGLE("AK4497 MCLK FS Auto Detect", AK4497_00_CONTROL1, 4, 1, 0),
+
+ SOC_SINGLE("AK4497 Soft Mute Control", AK4497_01_CONTROL2, 0, 1, 0),
+ SOC_SINGLE("AK4497 Short delay filter", AK4497_01_CONTROL2, 5, 1, 0),
+ SOC_SINGLE("AK4497 Data Zero Detect Enable", AK4497_01_CONTROL2,
+ 7, 1, 0),
+ SOC_SINGLE("AK4497 Slow Roll-off Filter", AK4497_02_CONTROL3, 0, 1, 0),
+ SOC_SINGLE("AK4497 Invering Enable of DZF", AK4497_02_CONTROL3,
+ 4, 1, 0),
+ SOC_SINGLE("AK4497 Mono Mode", AK4497_02_CONTROL3, 3, 1, 0),
+ SOC_SINGLE("AK4497 Super Slow Roll-off Filter", AK4497_05_CONTROL4,
+ 0, 1, 0),
+ SOC_SINGLE("AK4497 AOUTR Phase Inverting", AK4497_05_CONTROL4,
+ 6, 1, 0),
+ SOC_SINGLE("AK4497 AOUTL Phase Inverting", AK4497_05_CONTROL4,
+ 7, 1, 0),
+ SOC_SINGLE("AK4497 DSD Mute Release", AK4497_06_DSD1, 3, 1, 0),
+ SOC_SINGLE("AK4497 DSD Mute Control Hold", AK4497_06_DSD1, 4, 1, 0),
+ SOC_SINGLE("AK4497 DSDR is detected", AK4497_06_DSD1, 5, 1, 0),
+ SOC_SINGLE("AK4497 DSDL is detected", AK4497_06_DSD1, 6, 1, 0),
+ SOC_SINGLE("AK4497 DSD Data Mute", AK4497_06_DSD1, 7, 1, 0),
+ SOC_SINGLE("AK4497 Synchronization Control", AK4497_07_CONTROL5,
+ 0, 1, 0),
+
+ SOC_ENUM("AK4497 Output Level", ak4497_gain_control_enum),
+ SOC_SINGLE("AK4497 High Sonud Quality Mode", AK4497_08_SOUNDCONTROL,
+ 2, 1, 0),
+ SOC_SINGLE("AK4497 Heavy Load Mode", AK4497_08_SOUNDCONTROL, 3, 1, 0),
+ SOC_ENUM("AK4497 DSD Data Input Pin", ak4497_dac_enum[9]),
+ SOC_SINGLE("AK4497 Daisy Chain", AK4497_0B_CONTROL8, 1, 1, 0),
+ SOC_ENUM("AK4497 ATT Transit Time", ak4497_dac_enum[10]),
+
+ SOC_ENUM_EXT("AK4497 Read FS Auto Detect Mode", ak4497_dac_enum2[3],
+ ak4497_get_adfs, ak4497_set_adfs),
+
+#ifdef AK4497_DEBUG
+ SOC_ENUM_EXT("Reg Read", ak4497_enum[0], get_test_reg, set_test_reg),
+#endif
+
+};
+
+static const char * const ak4497_dac_enable_texts[] = {"Off", "On"};
+
+static SOC_ENUM_SINGLE_VIRT_DECL(ak4497_dac_enable_enum,
+ ak4497_dac_enable_texts);
+
+static const struct snd_kcontrol_new ak4497_dac_enable_control =
+ SOC_DAPM_ENUM("DAC Switch", ak4497_dac_enable_enum);
+
+/* ak4497 dapm widgets */
+static const struct snd_soc_dapm_widget ak4497_dapm_widgets[] = {
+ SND_SOC_DAPM_AIF_IN("AK4497 SDTI", "Playback", 0, SND_SOC_NOPM, 0, 0),
+
+ SND_SOC_DAPM_DAC("AK4497 DAC", NULL, AK4497_0A_CONTROL7, 2, 0),
+
+ SND_SOC_DAPM_MUX("AK4497 DAC Enable", SND_SOC_NOPM,
+ 0, 0, &ak4497_dac_enable_control),
+
+ SND_SOC_DAPM_OUTPUT("AK4497 AOUT"),
+
+};
+
+static const struct snd_soc_dapm_route ak4497_intercon[] = {
+ {"AK4497 DAC", NULL, "AK4497 SDTI"},
+ {"AK4497 DAC Enable", "On", "AK4497 DAC"},
+ {"AK4497 AOUT", NULL, "AK4497 DAC Enable"},
+};
+
+static int ak4497_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params,
+ struct snd_soc_dai *dai)
+{
+ struct snd_soc_codec *codec = dai->codec;
+ struct ak4497_priv *ak4497 = snd_soc_codec_get_drvdata(codec);
+ snd_pcm_format_t pcm_format = params_format(params);
+
+ unsigned int dfs, dfs2, dsdsel0, dsdsel1, format;
+ int nfs1;
+ bool is_dsd = false;
+ int dsd_bclk;
+
+ if (pcm_format == SNDRV_PCM_FORMAT_DSD_U8 ||
+ pcm_format == SNDRV_PCM_FORMAT_DSD_U16_LE ||
+ pcm_format == SNDRV_PCM_FORMAT_DSD_U16_BE ||
+ pcm_format == SNDRV_PCM_FORMAT_DSD_U32_LE ||
+ pcm_format == SNDRV_PCM_FORMAT_DSD_U32_BE)
+ is_dsd = true;
+
+ nfs1 = params_rate(params);
+ ak4497->fs1 = nfs1;
+
+ ak4497_read(codec, AK4497_01_CONTROL2, &dfs);
+ dfs &= ~AK4497_DFS;
+
+ ak4497_read(codec, AK4497_05_CONTROL4, &dfs2);
+ dfs2 &= ~AK4497_DFS2;
+
+ ak4497_read(codec, AK4497_06_DSD1, &dsdsel0);
+ dsdsel0 &= ~AK4497_DSDSEL0;
+
+ ak4497_read(codec, AK4497_09_DSD2, &dsdsel1);
+ dsdsel1 &= ~AK4497_DSDSEL1;
+
+ if (!is_dsd) {
+ switch (nfs1) {
+ case 8000:
+ case 11025:
+ case 16000:
+ case 22050:
+ case 32000:
+ case 44100:
+ case 48000:
+ dfs |= AK4497_DFS_48KHZ;
+ dfs2 |= AK4497_DFS2_48KHZ;
+ break;
+ case 88200:
+ case 96000:
+ dfs |= AK4497_DFS_96KHZ;
+ dfs2 |= AK4497_DFS2_48KHZ;
+ break;
+ case 176400:
+ case 192000:
+ dfs |= AK4497_DFS_192KHZ;
+ dfs2 |= AK4497_DFS2_48KHZ;
+ break;
+ case 352800:
+ case 384000:
+ dfs |= AK4497_DFS_384KHZ;
+ dfs2 |= AK4497_DFS2_384KHZ;
+ break;
+ case 705600:
+ case 768000:
+ dfs |= AK4497_DFS_768KHZ;
+ dfs2 |= AK4497_DFS2_384KHZ;
+ break;
+ default:
+ return -EINVAL;
+ }
+ } else {
+ dsd_bclk = params_rate(params) *
+ params_physical_width(params);
+
+ switch (dsd_bclk) {
+ case 2822400:
+ dsdsel0 |= AK4497_DSDSEL0_2MHZ;
+ dsdsel1 |= AK4497_DSDSEL1_2MHZ;
+ break;
+ case 5644800:
+ dsdsel0 |= AK4497_DSDSEL0_5MHZ;
+ dsdsel1 |= AK4497_DSDSEL1_5MHZ;
+ break;
+ case 11289600:
+ dsdsel0 |= AK4497_DSDSEL0_11MHZ;
+ dsdsel1 |= AK4497_DSDSEL1_11MHZ;
+ break;
+ case 22579200:
+ dsdsel0 |= AK4497_DSDSEL0_22MHZ;
+ dsdsel1 |= AK4497_DSDSEL1_22MHZ;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ snd_soc_write(codec, AK4497_06_DSD1, dsdsel0);
+ snd_soc_write(codec, AK4497_09_DSD2, dsdsel1);
+ }
+
+ snd_soc_write(codec, AK4497_01_CONTROL2, dfs);
+ snd_soc_write(codec, AK4497_05_CONTROL4, dfs2);
+
+ ak4497_read(codec, AK4497_00_CONTROL1, &format);
+ format &= ~AK4497_DIF;
+
+ switch (params_format(params)) {
+ case SNDRV_PCM_FORMAT_S16_LE:
+ if (ak4497->fmt == SND_SOC_DAIFMT_I2S)
+ format |= AK4497_DIF_24BIT_I2S;
+ else
+ format |= AK4497_DIF_16BIT_LSB;
+ break;
+ case SNDRV_PCM_FORMAT_S24_LE:
+ case SNDRV_PCM_FORMAT_S32_LE:
+ if (ak4497->fmt == SND_SOC_DAIFMT_I2S)
+ format |= AK4497_DIF_32BIT_I2S;
+ else if (ak4497->fmt == SND_SOC_DAIFMT_LEFT_J)
+ format |= AK4497_DIF_32BIT_MSB;
+ else if (ak4497->fmt == SND_SOC_DAIFMT_RIGHT_J)
+ format |= AK4497_DIF_32BIT_LSB;
+ else
+ return -EINVAL;
+ break;
+ case SNDRV_PCM_FORMAT_DSD_U8:
+ case SNDRV_PCM_FORMAT_DSD_U16_LE:
+ case SNDRV_PCM_FORMAT_DSD_U32_LE:
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ snd_soc_write(codec, AK4497_00_CONTROL1, format);
+
+ return 0;
+}
+
+static int ak4497_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id,
+ unsigned int freq, int dir)
+{
+// struct snd_soc_codec *codec = dai->codec;
+
+ return 0;
+}
+
+static int ak4497_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
+{
+ struct snd_soc_codec *codec = dai->codec;
+ struct ak4497_priv *ak4497 = snd_soc_codec_get_drvdata(codec);
+ unsigned int format, format2;
+
+ /* set master/slave audio interface */
+ ak4497_read(codec, AK4497_00_CONTROL1, &format);
+ format &= ~AK4497_DIF;
+
+ ak4497_read(codec, AK4497_02_CONTROL3, &format2);
+ format2 &= ~AK4497_DIF_DSD;
+
+ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+ case SND_SOC_DAIFMT_CBS_CFS:
+ break;
+ case SND_SOC_DAIFMT_CBM_CFM:
+ case SND_SOC_DAIFMT_CBS_CFM:
+ case SND_SOC_DAIFMT_CBM_CFS:
+ default:
+ dev_err(codec->dev, "Clock mode unsupported");
+ return -EINVAL;
+ }
+
+ switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+ case SND_SOC_DAIFMT_I2S:
+ ak4497->fmt = SND_SOC_DAIFMT_I2S;
+ break;
+ case SND_SOC_DAIFMT_LEFT_J:
+ ak4497->fmt = SND_SOC_DAIFMT_LEFT_J;
+ break;
+ case SND_SOC_DAIFMT_RIGHT_J:
+ ak4497->fmt = SND_SOC_DAIFMT_RIGHT_J;
+ break;
+ case SND_SOC_DAIFMT_PDM:
+ format2 |= AK4497_DIF_DSD_MODE;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ /* set format */
+ snd_soc_write(codec, AK4497_00_CONTROL1, format);
+ snd_soc_write(codec, AK4497_02_CONTROL3, format2);
+
+ return 0;
+}
+
+static bool ak4497_volatile(struct device *dev, unsigned int reg)
+{
+ int ret;
+
+#ifdef AK4497_DEBUG
+ ret = 1;
+#else
+ switch (reg) {
+ case AK4497_15_DFSREAD:
+ ret = 1;
+ break;
+ default:
+ ret = 0;
+ break;
+ }
+#endif
+ return ret;
+}
+
+static int ak4497_set_bias_level(struct snd_soc_codec *codec,
+ enum snd_soc_bias_level level)
+{
+ switch (level) {
+ case SND_SOC_BIAS_ON:
+ case SND_SOC_BIAS_PREPARE:
+ case SND_SOC_BIAS_STANDBY:
+ /* RSTN bit = 1 */
+ snd_soc_update_bits(codec, AK4497_00_CONTROL1, 0x01, 0x01);
+ break;
+ case SND_SOC_BIAS_OFF:
+ /* RSTN bit = 0 */
+ snd_soc_update_bits(codec, AK4497_00_CONTROL1, 0x01, 0x00);
+ break;
+ }
+
+ return 0;
+}
+
+static int ak4497_set_dai_mute(struct snd_soc_dai *dai, int mute)
+{
+ struct snd_soc_codec *codec = dai->codec;
+ struct ak4497_priv *ak4497 = snd_soc_codec_get_drvdata(codec);
+ int nfs, ndt;
+
+ nfs = ak4497->fs1;
+
+ if (mute) { /* SMUTE: 1 , MUTE */
+ snd_soc_update_bits(codec, AK4497_01_CONTROL2, 0x01, 0x01);
+ ndt = 7424000 / nfs;
+ mdelay(ndt);
+
+ /* External Mute ON */
+ if (gpio_is_valid(ak4497->mute_gpio))
+ gpio_set_value_cansleep(ak4497->mute_gpio, 1);
+ } else { /* SMUTE: 0, NORMAL operation */
+
+ /* External Mute OFF */
+ if (gpio_is_valid(ak4497->mute_gpio))
+ gpio_set_value_cansleep(ak4497->mute_gpio, 0);
+ snd_soc_update_bits(codec, AK4497_01_CONTROL2, 0x01, 0x00);
+ }
+
+ return 0;
+}
+
+#define AK4497_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
+ SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |\
+ SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |\
+ SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 |\
+ SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 |\
+ SNDRV_PCM_RATE_192000)
+
+#define AK4497_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE |\
+ SNDRV_PCM_FMTBIT_S32_LE |\
+ SNDRV_PCM_FMTBIT_DSD_U8 |\
+ SNDRV_PCM_FMTBIT_DSD_U16_LE |\
+ SNDRV_PCM_FMTBIT_DSD_U32_LE)
+
+static const unsigned int ak4497_rates[] = {
+ 8000, 11025, 16000, 22050,
+ 32000, 44100, 48000, 88200,
+ 96000, 176400, 192000, 352800,
+ 384000, 705600, 768000, 1411200,
+ 2822400,
+};
+
+static const struct snd_pcm_hw_constraint_list ak4497_rate_constraints = {
+ .count = ARRAY_SIZE(ak4497_rates),
+ .list = ak4497_rates,
+};
+
+static int ak4497_startup(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai) {
+ int ret;
+
+ ret = snd_pcm_hw_constraint_list(substream->runtime, 0,
+ SNDRV_PCM_HW_PARAM_RATE, &ak4497_rate_constraints);
+
+ return ret;
+}
+
+static struct snd_soc_dai_ops ak4497_dai_ops = {
+ .startup = ak4497_startup,
+ .hw_params = ak4497_hw_params,
+ .set_sysclk = ak4497_set_dai_sysclk,
+ .set_fmt = ak4497_set_dai_fmt,
+ .digital_mute = ak4497_set_dai_mute,
+};
+
+struct snd_soc_dai_driver ak4497_dai[] = {
+ {
+ .name = "ak4497-aif",
+ .playback = {
+ .stream_name = "Playback",
+ .channels_min = 1,
+ .channels_max = 2,
+ .rates = SNDRV_PCM_RATE_KNOT,
+ .formats = AK4497_FORMATS,
+ },
+ .ops = &ak4497_dai_ops,
+ },
+};
+
+static int ak4497_init_reg(struct snd_soc_codec *codec)
+{
+ struct ak4497_priv *ak4497 = snd_soc_codec_get_drvdata(codec);
+ int ret = 0;
+
+ /* External Mute ON */
+ if (gpio_is_valid(ak4497->mute_gpio))
+ gpio_set_value_cansleep(ak4497->mute_gpio, 1);
+
+ if (gpio_is_valid(ak4497->pdn_gpio)) {
+ gpio_set_value_cansleep(ak4497->pdn_gpio, 0);
+ usleep_range(1000, 2000);
+ gpio_set_value_cansleep(ak4497->pdn_gpio, 1);
+ usleep_range(1000, 2000);
+ }
+
+ /* ak4497_set_bias_level(codec, SND_SOC_BIAS_STANDBY); */
+
+ /* SYNCE bit = 1 */
+ ret = snd_soc_update_bits(codec, AK4497_07_CONTROL5, 0x01, 0x01);
+ if (ret)
+ return ret;
+
+ /* HLOAD bit = 1, SC2 bit = 1 */
+ ret = snd_soc_update_bits(codec, AK4497_08_SOUNDCONTROL, 0x0F, 0x0C);
+ if (ret)
+ return ret;
+
+ return ret;
+}
+
+static int ak4497_parse_dt(struct ak4497_priv *ak4497)
+{
+ struct device *dev;
+ struct device_node *np;
+
+ dev = &(ak4497->i2c->dev);
+ np = dev->of_node;
+
+ ak4497->pdn_gpio = -1;
+ ak4497->mute_gpio = -1;
+
+ if (!np)
+ return -1;
+
+ ak4497->pdn_gpio = of_get_named_gpio(np, "ak4497,pdn-gpio", 0);
+ if (ak4497->pdn_gpio < 0)
+ ak4497->pdn_gpio = -1;
+
+ if (!gpio_is_valid(ak4497->pdn_gpio)) {
+ dev_err(dev, "ak4497 pdn pin(%u) is invalid\n",
+ ak4497->pdn_gpio);
+ ak4497->pdn_gpio = -1;
+ }
+
+ ak4497->mute_gpio = of_get_named_gpio(np, "ak4497,mute-gpio", 0);
+ if (ak4497->mute_gpio < 0)
+ ak4497->mute_gpio = -1;
+
+ if (!gpio_is_valid(ak4497->mute_gpio)) {
+ dev_err(dev, "ak4497 mute_gpio(%u) is invalid\n",
+ ak4497->mute_gpio);
+ ak4497->mute_gpio = -1;
+ }
+
+ return 0;
+}
+
+static int ak4497_probe(struct snd_soc_codec *codec)
+{
+ struct ak4497_priv *ak4497 = snd_soc_codec_get_drvdata(codec);
+ int ret = 0;
+
+ ret = ak4497_parse_dt(ak4497);
+ if (ret)
+ return ret;
+
+ if (gpio_is_valid(ak4497->pdn_gpio)) {
+ ret = gpio_request(ak4497->pdn_gpio, "ak4497 pdn");
+ if (ret)
+ return ret;
+ gpio_direction_output(ak4497->pdn_gpio, 0);
+ }
+ if (gpio_is_valid(ak4497->mute_gpio)) {
+ ret = gpio_request(ak4497->mute_gpio, "ak4497 mute");
+ if (ret)
+ return ret;
+ gpio_direction_output(ak4497->mute_gpio, 0);
+ }
+
+ ret = ak4497_init_reg(codec);
+ if (ret)
+ return ret;
+
+ ak4497->fs1 = 48000;
+ ak4497->nBickFreq = 1;
+ ak4497->nTdmSds = 0;
+
+ return ret;
+}
+
+static int ak4497_remove(struct snd_soc_codec *codec)
+{
+ struct ak4497_priv *ak4497 = snd_soc_codec_get_drvdata(codec);
+
+ ak4497_set_bias_level(codec, SND_SOC_BIAS_OFF);
+ if (gpio_is_valid(ak4497->pdn_gpio)) {
+ gpio_set_value_cansleep(ak4497->pdn_gpio, 0);
+ gpio_free(ak4497->pdn_gpio);
+ }
+ if (gpio_is_valid(ak4497->mute_gpio))
+ gpio_free(ak4497->mute_gpio);
+
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int ak4497_runtime_suspend(struct device *dev)
+{
+ struct ak4497_priv *ak4497 = dev_get_drvdata(dev);
+
+ regcache_cache_only(ak4497->regmap, true);
+
+ if (gpio_is_valid(ak4497->pdn_gpio)) {
+ gpio_set_value_cansleep(ak4497->pdn_gpio, 0);
+ usleep_range(1000, 2000);
+ }
+
+ if (gpio_is_valid(ak4497->mute_gpio))
+ gpio_free(ak4497->mute_gpio);
+
+ return 0;
+}
+
+static int ak4497_runtime_resume(struct device *dev)
+{
+ struct ak4497_priv *ak4497 = dev_get_drvdata(dev);
+
+ /* External Mute ON */
+ if (gpio_is_valid(ak4497->mute_gpio))
+ gpio_set_value_cansleep(ak4497->mute_gpio, 1);
+
+ if (gpio_is_valid(ak4497->pdn_gpio)) {
+ gpio_set_value_cansleep(ak4497->pdn_gpio, 1);
+ usleep_range(1000, 2000);
+ }
+
+ regcache_cache_only(ak4497->regmap, false);
+ regcache_mark_dirty(ak4497->regmap);
+
+ return regcache_sync(ak4497->regmap);
+}
+#endif /* CONFIG_PM */
+
+static const struct dev_pm_ops ak4497_pm = {
+ SET_RUNTIME_PM_OPS(ak4497_runtime_suspend, ak4497_runtime_resume, NULL)
+ SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, pm_runtime_force_resume)
+};
+
+struct snd_soc_codec_driver soc_codec_dev_ak4497 = {
+ .probe = ak4497_probe,
+ .remove = ak4497_remove,
+
+ .idle_bias_off = true,
+ .set_bias_level = ak4497_set_bias_level,
+
+ .component_driver = {
+ .controls = ak4497_snd_controls,
+ .num_controls = ARRAY_SIZE(ak4497_snd_controls),
+ .dapm_widgets = ak4497_dapm_widgets,
+ .num_dapm_widgets = ARRAY_SIZE(ak4497_dapm_widgets),
+ .dapm_routes = ak4497_intercon,
+ .num_dapm_routes = ARRAY_SIZE(ak4497_intercon),
+ },
+};
+
+static const struct regmap_config ak4497_regmap = {
+ .reg_bits = 8,
+ .val_bits = 8,
+
+ .max_register = AK4497_MAX_REGISTERS,
+ .volatile_reg = ak4497_volatile,
+
+ .reg_defaults = ak4497_reg,
+ .num_reg_defaults = ARRAY_SIZE(ak4497_reg),
+ .cache_type = REGCACHE_RBTREE,
+};
+
+static int ak4497_i2c_probe(struct i2c_client *i2c,
+ const struct i2c_device_id *id)
+{
+ struct ak4497_priv *ak4497;
+ int ret = 0;
+ int i;
+
+ ak4497 = devm_kzalloc(&i2c->dev,
+ sizeof(struct ak4497_priv), GFP_KERNEL);
+ if (ak4497 == NULL)
+ return -ENOMEM;
+
+ ak4497->regmap = devm_regmap_init_i2c(i2c, &ak4497_regmap);
+ if (IS_ERR(ak4497->regmap))
+ return PTR_ERR(ak4497->regmap);
+
+ i2c_set_clientdata(i2c, ak4497);
+ ak4497->i2c = i2c;
+
+ for (i = 0; i < ARRAY_SIZE(ak4497->supplies); i++)
+ ak4497->supplies[i].supply = ak4497_supply_names[i];
+
+ ret = devm_regulator_bulk_get(&i2c->dev, ARRAY_SIZE(ak4497->supplies),
+ ak4497->supplies);
+ if (ret != 0) {
+ dev_err(&i2c->dev, "Failed to request supplies: %d\n", ret);
+ return ret;
+ }
+
+ ret = regulator_bulk_enable(ARRAY_SIZE(ak4497->supplies),
+ ak4497->supplies);
+ if (ret != 0) {
+ dev_err(&i2c->dev, "Failed to enable supplies: %d\n", ret);
+ return ret;
+ }
+
+ ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_ak4497,
+ &ak4497_dai[0], ARRAY_SIZE(ak4497_dai));
+ if (ret < 0)
+ return ret;
+
+ pm_runtime_enable(&i2c->dev);
+
+ return 0;
+}
+
+static int ak4497_i2c_remove(struct i2c_client *client)
+{
+ snd_soc_unregister_codec(&client->dev);
+ pm_runtime_disable(&client->dev);
+
+ return 0;
+}
+
+static const struct of_device_id ak4497_i2c_dt_ids[] = {
+ { .compatible = "asahi-kasei,ak4497"},
+ { }
+};
+
+static const struct i2c_device_id ak4497_i2c_id[] = {
+ { "ak4497", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, ak4497_i2c_id);
+
+static struct i2c_driver ak4497_i2c_driver = {
+ .driver = {
+ .name = "ak4497",
+ .of_match_table = of_match_ptr(ak4497_i2c_dt_ids),
+ .pm = &ak4497_pm,
+ },
+ .probe = ak4497_i2c_probe,
+ .remove = ak4497_i2c_remove,
+ .id_table = ak4497_i2c_id,
+};
+
+module_i2c_driver(ak4497_i2c_driver);
+
+MODULE_AUTHOR("Junichi Wakasugi <wakasugi.jb@om.asahi-kasei.co.jp>");
+MODULE_AUTHOR("Daniel Baluta <daniel.baluta@nxp.com>");
+MODULE_DESCRIPTION("ASoC ak4497 codec driver");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/ak4497.h b/sound/soc/codecs/ak4497.h
new file mode 100644
index 000000000000..3ba6762e5ddc
--- /dev/null
+++ b/sound/soc/codecs/ak4497.h
@@ -0,0 +1,90 @@
+/*
+ * ak4497.h -- audio driver for ak4497
+ *
+ * Copyright (C) 2016 Asahi Kasei Microdevices Corporation
+ * Copyright (C) 2017, NXP
+ *
+ * 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 _AK4497_H
+#define _AK4497_H
+
+#define AK4497_00_CONTROL1 0x00
+#define AK4497_01_CONTROL2 0x01
+#define AK4497_02_CONTROL3 0x02
+#define AK4497_03_LCHATT 0x03
+#define AK4497_04_RCHATT 0x04
+#define AK4497_05_CONTROL4 0x05
+#define AK4497_06_DSD1 0x06
+#define AK4497_07_CONTROL5 0x07
+#define AK4497_08_SOUNDCONTROL 0x08
+#define AK4497_09_DSD2 0x09
+#define AK4497_0A_CONTROL7 0x0A
+#define AK4497_0B_CONTROL8 0x0B
+#define AK4497_0C_RESERVED 0x0C
+#define AK4497_0D_RESERVED 0x0D
+#define AK4497_0E_RESERVED 0x0E
+#define AK4497_0F_RESERVED 0x0F
+#define AK4497_10_RESERVED 0x10
+#define AK4497_11_RESERVED 0x11
+#define AK4497_12_RESERVED 0x12
+#define AK4497_13_RESERVED 0x13
+#define AK4497_14_RESERVED 0x14
+#define AK4497_15_DFSREAD 0x15
+
+
+#define AK4497_MAX_REGISTERS (AK4497_15_DFSREAD)
+
+/* Bitfield Definitions */
+
+/* AK4497_00_CONTROL1 (0x00) Fields */
+#define AK4497_DIF 0x0E
+#define AK4497_DIF_MSB_MODE (2 << 1)
+#define AK4497_DIF_I2S_MODE (3 << 1)
+#define AK4497_DIF_32BIT_MODE (4 << 1)
+
+#define AK4497_DIF_16BIT_LSB (0 << 1)
+#define AK4497_DIF_20BIT_LSB (1 << 1)
+#define AK4497_DIF_24BIT_MSB (2 << 1)
+#define AK4497_DIF_24BIT_I2S (3 << 1)
+#define AK4497_DIF_24BIT_LSB (4 << 1)
+#define AK4497_DIF_32BIT_LSB (5 << 1)
+#define AK4497_DIF_32BIT_MSB (6 << 1)
+#define AK4497_DIF_32BIT_I2S (7 << 1)
+
+/* AK4497_02_CONTROL3 (0x02) Fields */
+#define AK4497_DIF_DSD 0x80
+#define AK4497_DIF_DSD_MODE (1 << 7)
+
+
+/* AK4497_01_CONTROL2 (0x01) Fields */
+/* AK4497_05_CONTROL4 (0x05) Fields */
+#define AK4497_DFS 0x18
+#define AK4497_DFS_48KHZ (0x0 << 3) // 30kHz to 54kHz
+#define AK4497_DFS_96KHZ (0x1 << 3) // 54kHz to 108kHz
+#define AK4497_DFS_192KHZ (0x2 << 3) // 120kHz to 216kHz
+#define AK4497_DFS_384KHZ (0x0 << 3)
+#define AK4497_DFS_768KHZ (0x1 << 3)
+
+#define AK4497_DFS2 0x2
+#define AK4497_DFS2_48KHZ (0x0 << 1) // 30kHz to 216kHz
+#define AK4497_DFS2_384KHZ (0x1 << 1) // 384kHz, 768kHz to 108kHz
+
+
+#define AK4497_DSDSEL0 0x1
+#define AK4497_DSDSEL0_2MHZ 0x0
+#define AK4497_DSDSEL0_5MHZ 0x1
+#define AK4497_DSDSEL0_11MHZ 0x0
+#define AK4497_DSDSEL0_22MHZ 0x1
+
+#define AK4497_DSDSEL1 0x1
+#define AK4497_DSDSEL1_2MHZ 0x0
+#define AK4497_DSDSEL1_5MHZ 0x0
+#define AK4497_DSDSEL1_11MHZ 0x1
+#define AK4497_DSDSEL1_22MHZ 0x1
+
+#endif
diff --git a/sound/soc/codecs/ak5558.c b/sound/soc/codecs/ak5558.c
new file mode 100644
index 000000000000..4218178a6c47
--- /dev/null
+++ b/sound/soc/codecs/ak5558.c
@@ -0,0 +1,844 @@
+/*
+ * ak5558.c -- audio driver for AK5558 ADC
+ *
+ * Copyright (C) 2015 Asahi Kasei Microdevices Corporation
+ * Copyright 2017 NXP
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/i2c.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/gpio/consumer.h>
+#include <sound/soc.h>
+#include <sound/soc-dapm.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/initval.h>
+#include <sound/tlv.h>
+#include <linux/of_gpio.h>
+#include <linux/regmap.h>
+#include <linux/pm_runtime.h>
+#include <linux/regulator/consumer.h>
+
+#include "ak5558.h"
+
+#define AK5558_SLAVE_CKS_AUTO
+
+/* enable debug */
+/* #define AK5558_DEBUG */
+
+#define AK5558_NUM_SUPPLIES 2
+static const char *ak5558_supply_names[AK5558_NUM_SUPPLIES] = {
+ "DVDD",
+ "AVDD",
+};
+
+/* AK5558 Codec Private Data */
+struct ak5558_priv {
+ struct snd_soc_codec codec;
+ struct regmap *regmap;
+ struct i2c_client *i2c;
+ int fs; /* Sampling Frequency */
+ int rclk; /* Master Clock */
+ int pdn_gpio; /* Power on / Reset GPIO */
+ int slots;
+ int slot_width;
+ struct regulator_bulk_data supplies[AK5558_NUM_SUPPLIES];
+};
+
+/* ak5558 register cache & default register settings */
+static const struct reg_default ak5558_reg[] = {
+ { 0x0, 0xFF }, /* 0x00 AK5558_00_POWER_MANAGEMENT1 */
+ { 0x1, 0x01 }, /* 0x01 AK5558_01_POWER_MANAGEMENT2 */
+ { 0x2, 0x01 }, /* 0x02 AK5558_02_CONTROL1 */
+ { 0x3, 0x00 }, /* 0x03 AK5558_03_CONTROL2 */
+ { 0x4, 0x00 }, /* 0x04 AK5558_04_CONTROL3 */
+ { 0x5, 0x00 } /* 0x05 AK5558_05_DSD */
+};
+
+static const char * const mono_texts[] = {
+ "8 Slot", "2 Slot", "4 Slot", "1 Slot",
+};
+
+static const struct soc_enum ak5558_mono_enum[] = {
+ SOC_ENUM_SINGLE(AK5558_01_POWER_MANAGEMENT2, 1,
+ ARRAY_SIZE(mono_texts), mono_texts)
+};
+
+static const char * const tdm_texts[] = {
+ "Off", "TDM128", "TDM256", "TDM512",
+};
+
+static const char * const digfil_texts[] = {
+ "Sharp Roll-Off", "Show Roll-Off",
+ "Short Delay Sharp Roll-Off", "Short Delay Show Roll-Off",
+};
+
+static const struct soc_enum ak5558_adcset_enum[] = {
+ SOC_ENUM_SINGLE(AK5558_03_CONTROL2, 5,
+ ARRAY_SIZE(tdm_texts), tdm_texts),
+ SOC_ENUM_SINGLE(AK5558_04_CONTROL3, 0,
+ ARRAY_SIZE(digfil_texts), digfil_texts),
+};
+
+static const char * const dsdon_texts[] = {
+ "PCM", "DSD",
+};
+
+static const char * const dsdsel_texts[] = {
+ "64fs", "128fs", "256fs"
+};
+
+static const char * const dckb_texts[] = {
+ "Falling", "Rising",
+};
+
+static const char * const dcks_texts[] = {
+ "512fs", "768fs",
+};
+
+static const struct soc_enum ak5558_dsdset_enum[] = {
+ SOC_ENUM_SINGLE(AK5558_04_CONTROL3, 7,
+ ARRAY_SIZE(dsdon_texts), dsdon_texts),
+ SOC_ENUM_SINGLE(AK5558_05_DSD, 0,
+ ARRAY_SIZE(dsdsel_texts), dsdsel_texts),
+ SOC_ENUM_SINGLE(AK5558_05_DSD, 2, ARRAY_SIZE(dckb_texts), dckb_texts),
+ SOC_ENUM_SINGLE(AK5558_05_DSD, 5, ARRAY_SIZE(dcks_texts), dcks_texts),
+};
+
+#ifdef AK5558_DEBUG
+static const char * const test_reg_select[] = {
+ "read AK5558 Reg 00:05",
+};
+
+static const struct soc_enum ak5558_enum[] = {
+ SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(test_reg_select), test_reg_select),
+};
+
+static int nTestRegNo;
+
+static int get_test_reg(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ ucontrol->value.enumerated.item[0] = nTestRegNo;
+
+ return 0;
+}
+
+static int set_test_reg(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+ u32 currMode = ucontrol->value.enumerated.item[0];
+ int i, value;
+ int regs, rege;
+
+ nTestRegNo = currMode;
+
+ regs = 0x00;
+ rege = 0x05;
+
+ for (i = regs; i <= rege; i++) {
+ value = snd_soc_read(codec, i);
+ pr_info("***AK5558 Addr,Reg=(%x, %x)\n", i, value);
+ }
+
+ return 0;
+}
+
+#endif
+
+static const struct snd_kcontrol_new ak5558_snd_controls[] = {
+ SOC_ENUM("AK5558 Monaural Mode", ak5558_mono_enum[0]),
+ SOC_ENUM("AK5558 TDM mode", ak5558_adcset_enum[0]),
+ SOC_ENUM("AK5558 Digital Filter", ak5558_adcset_enum[1]),
+
+ SOC_ENUM("AK5558 DSD Mode", ak5558_dsdset_enum[0]),
+ SOC_ENUM("AK5558 Frequency of DCLK", ak5558_dsdset_enum[1]),
+ SOC_ENUM("AK5558 Polarity of DCLK", ak5558_dsdset_enum[2]),
+ SOC_ENUM("AK5558 Master Clock Frequency at DSD Mode",
+ ak5558_dsdset_enum[3]),
+
+ SOC_SINGLE("AK5558 DSD Phase Modulation", AK5558_05_DSD, 3, 1, 0),
+
+#ifdef AK5558_DEBUG
+ SOC_ENUM_EXT("AK5558 Reg Read", ak5558_enum[0],
+ get_test_reg, set_test_reg),
+#endif
+
+};
+
+static const char * const ak5558_channel_select_texts[] = {"Off", "On"};
+
+static SOC_ENUM_SINGLE_VIRT_DECL(ak5558_channel1_mux_enum,
+ ak5558_channel_select_texts);
+
+static const struct snd_kcontrol_new ak5558_channel1_mux_control =
+ SOC_DAPM_ENUM("Ch1 Switch", ak5558_channel1_mux_enum);
+
+static SOC_ENUM_SINGLE_VIRT_DECL(ak5558_channel2_mux_enum,
+ ak5558_channel_select_texts);
+
+static const struct snd_kcontrol_new ak5558_channel2_mux_control =
+ SOC_DAPM_ENUM("Ch2 Switch", ak5558_channel2_mux_enum);
+
+static SOC_ENUM_SINGLE_VIRT_DECL(ak5558_channel3_mux_enum,
+ ak5558_channel_select_texts);
+
+static const struct snd_kcontrol_new ak5558_channel3_mux_control =
+ SOC_DAPM_ENUM("Ch3 Switch", ak5558_channel3_mux_enum);
+
+static SOC_ENUM_SINGLE_VIRT_DECL(ak5558_channel4_mux_enum,
+ ak5558_channel_select_texts);
+
+static const struct snd_kcontrol_new ak5558_channel4_mux_control =
+ SOC_DAPM_ENUM("Ch4 Switch", ak5558_channel4_mux_enum);
+
+static SOC_ENUM_SINGLE_VIRT_DECL(ak5558_channel5_mux_enum,
+ ak5558_channel_select_texts);
+
+static const struct snd_kcontrol_new ak5558_channel5_mux_control =
+ SOC_DAPM_ENUM("Ch5 Switch", ak5558_channel5_mux_enum);
+
+static SOC_ENUM_SINGLE_VIRT_DECL(ak5558_channel6_mux_enum,
+ ak5558_channel_select_texts);
+
+static const struct snd_kcontrol_new ak5558_channel6_mux_control =
+ SOC_DAPM_ENUM("Ch6 Switch", ak5558_channel6_mux_enum);
+
+static SOC_ENUM_SINGLE_VIRT_DECL(ak5558_channel7_mux_enum,
+ ak5558_channel_select_texts);
+
+static const struct snd_kcontrol_new ak5558_channel7_mux_control =
+ SOC_DAPM_ENUM("Ch7 Switch", ak5558_channel7_mux_enum);
+
+static SOC_ENUM_SINGLE_VIRT_DECL(ak5558_channel8_mux_enum,
+ ak5558_channel_select_texts);
+
+static const struct snd_kcontrol_new ak5558_channel8_mux_control =
+ SOC_DAPM_ENUM("Ch8 Switch", ak5558_channel8_mux_enum);
+
+static const struct snd_soc_dapm_widget ak5558_dapm_widgets[] = {
+
+ /* Analog Input */
+ SND_SOC_DAPM_INPUT("AIN1"),
+ SND_SOC_DAPM_INPUT("AIN2"),
+ SND_SOC_DAPM_INPUT("AIN3"),
+ SND_SOC_DAPM_INPUT("AIN4"),
+ SND_SOC_DAPM_INPUT("AIN5"),
+ SND_SOC_DAPM_INPUT("AIN6"),
+ SND_SOC_DAPM_INPUT("AIN7"),
+ SND_SOC_DAPM_INPUT("AIN8"),
+
+ SND_SOC_DAPM_MUX("AK5558 Ch1 Enable", SND_SOC_NOPM, 0, 0,
+ &ak5558_channel1_mux_control),
+ SND_SOC_DAPM_MUX("AK5558 Ch2 Enable", SND_SOC_NOPM, 0, 0,
+ &ak5558_channel2_mux_control),
+ SND_SOC_DAPM_MUX("AK5558 Ch3 Enable", SND_SOC_NOPM, 0, 0,
+ &ak5558_channel3_mux_control),
+ SND_SOC_DAPM_MUX("AK5558 Ch4 Enable", SND_SOC_NOPM, 0, 0,
+ &ak5558_channel4_mux_control),
+ SND_SOC_DAPM_MUX("AK5558 Ch5 Enable", SND_SOC_NOPM, 0, 0,
+ &ak5558_channel5_mux_control),
+ SND_SOC_DAPM_MUX("AK5558 Ch6 Enable", SND_SOC_NOPM, 0, 0,
+ &ak5558_channel6_mux_control),
+ SND_SOC_DAPM_MUX("AK5558 Ch7 Enable", SND_SOC_NOPM, 0, 0,
+ &ak5558_channel7_mux_control),
+ SND_SOC_DAPM_MUX("AK5558 Ch8 Enable", SND_SOC_NOPM, 0, 0,
+ &ak5558_channel8_mux_control),
+
+ SND_SOC_DAPM_ADC("ADC Ch1", NULL, AK5558_00_POWER_MANAGEMENT1, 0, 0),
+ SND_SOC_DAPM_ADC("ADC Ch2", NULL, AK5558_00_POWER_MANAGEMENT1, 1, 0),
+ SND_SOC_DAPM_ADC("ADC Ch3", NULL, AK5558_00_POWER_MANAGEMENT1, 2, 0),
+ SND_SOC_DAPM_ADC("ADC Ch4", NULL, AK5558_00_POWER_MANAGEMENT1, 3, 0),
+ SND_SOC_DAPM_ADC("ADC Ch5", NULL, AK5558_00_POWER_MANAGEMENT1, 4, 0),
+ SND_SOC_DAPM_ADC("ADC Ch6", NULL, AK5558_00_POWER_MANAGEMENT1, 5, 0),
+ SND_SOC_DAPM_ADC("ADC Ch7", NULL, AK5558_00_POWER_MANAGEMENT1, 6, 0),
+ SND_SOC_DAPM_ADC("ADC Ch8", NULL, AK5558_00_POWER_MANAGEMENT1, 7, 0),
+
+ SND_SOC_DAPM_AIF_OUT("SDTO", "Capture", 0, SND_SOC_NOPM, 0, 0),
+
+};
+
+static const struct snd_soc_dapm_route ak5558_intercon[] = {
+
+ {"AK5558 Ch1 Enable", "On", "AIN1"},
+ {"ADC Ch1", NULL, "AK5558 Ch1 Enable"},
+ {"SDTO", NULL, "ADC Ch1"},
+
+ {"AK5558 Ch2 Enable", "On", "AIN2"},
+ {"ADC Ch2", NULL, "AK5558 Ch2 Enable"},
+ {"SDTO", NULL, "ADC Ch2"},
+
+ {"AK5558 Ch3 Enable", "On", "AIN3"},
+ {"ADC Ch3", NULL, "AK5558 Ch3 Enable"},
+ {"SDTO", NULL, "ADC Ch3"},
+
+ {"AK5558 Ch4 Enable", "On", "AIN4"},
+ {"ADC Ch4", NULL, "AK5558 Ch4 Enable"},
+ {"SDTO", NULL, "ADC Ch4"},
+
+ {"AK5558 Ch5 Enable", "On", "AIN5"},
+ {"ADC Ch5", NULL, "AK5558 Ch5 Enable"},
+ {"SDTO", NULL, "ADC Ch5"},
+
+ {"AK5558 Ch6 Enable", "On", "AIN6"},
+ {"ADC Ch6", NULL, "AK5558 Ch6 Enable"},
+ {"SDTO", NULL, "ADC Ch6"},
+
+ {"AK5558 Ch7 Enable", "On", "AIN7"},
+ {"ADC Ch7", NULL, "AK5558 Ch7 Enable"},
+ {"SDTO", NULL, "ADC Ch7"},
+
+ {"AK5558 Ch8 Enable", "On", "AIN8"},
+ {"ADC Ch8", NULL, "AK5558 Ch8 Enable"},
+ {"SDTO", NULL, "ADC Ch8"},
+
+};
+
+static int ak5558_set_mcki(struct snd_soc_codec *codec, int fs, int rclk)
+{
+ u8 mode;
+#ifndef AK5558_SLAVE_CKS_AUTO
+ int mcki_rate;
+#endif
+
+ dev_dbg(codec->dev, "%s fs=%d rclk=%d\n", __func__, fs, rclk);
+
+ mode = snd_soc_read(codec, AK5558_02_CONTROL1);
+ mode &= ~AK5558_CKS;
+
+#ifdef AK5558_SLAVE_CKS_AUTO
+ mode |= AK5558_CKS_AUTO;
+#else
+ if (fs != 0 && rclk != 0) {
+ if (rclk % fs)
+ return -EINVAL;
+ mcki_rate = rclk / fs;
+
+ if (fs > 400000) {
+ switch (mcki_rate) {
+ case 32:
+ mode |= AK5558_CKS_32FS_768KHZ;
+ break;
+ case 48:
+ mode |= AK5558_CKS_48FS_768KHZ;
+ break;
+ case 64:
+ mode |= AK5558_CKS_64FS_768KHZ;
+ break;
+ default:
+ return -EINVAL;
+ }
+ } else if (fs > 200000) {
+ switch (mcki_rate) {
+ case 64:
+ mode |= AK5558_CKS_64FS_384KHZ;
+ break;
+ case 96:
+ mode |= AK5558_CKS_96FS_384KHZ;
+ break;
+ default:
+ return -EINVAL;
+ }
+ } else if (fs > 108000) {
+ switch (mcki_rate) {
+ case 128:
+ mode |= AK5558_CKS_128FS_192KHZ;
+ break;
+ case 192:
+ mode |= AK5558_CKS_192FS_192KHZ;
+ break;
+ default:
+ return -EINVAL;
+ }
+ } else if (fs > 54000) {
+ switch (mcki_rate) {
+ case 256:
+ mode |= AK5558_CKS_256FS_96KHZ;
+ break;
+ case 384:
+ mode |= AK5558_CKS_384FS_96KHZ;
+ break;
+ default:
+ return -EINVAL;
+ }
+ } else {
+ switch (mcki_rate) {
+ case 256:
+ mode |= AK5558_CKS_256FS_48KHZ;
+ break;
+ case 384:
+ mode |= AK5558_CKS_384FS_48KHZ;
+ break;
+ case 512:
+ mode |= AK5558_CKS_512FS_48KHZ;
+ break;
+ case 768:
+ mode |= AK5558_CKS_768FS_48KHZ;
+ break;
+ case 1024:
+ if (fs > 32000)
+ return -EINVAL;
+ mode |= AK5558_CKS_1024FS_16KHZ;
+ break;
+ default:
+ return -EINVAL;
+ }
+ }
+ }
+#endif
+
+ snd_soc_update_bits(codec, AK5558_02_CONTROL1, AK5558_CKS, mode);
+
+ return 0;
+}
+
+static int ak5558_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params,
+ struct snd_soc_dai *dai)
+{
+ struct snd_soc_codec *codec = dai->codec;
+ struct ak5558_priv *ak5558 = snd_soc_codec_get_drvdata(codec);
+ u8 bits;
+ int pcm_width = max(params_physical_width(params), ak5558->slot_width);
+
+ dev_dbg(dai->dev, "%s(%d)\n", __func__, __LINE__);
+
+ /* set master/slave audio interface */
+ bits = snd_soc_read(codec, AK5558_02_CONTROL1);
+ bits &= ~AK5558_BITS;
+
+ switch (pcm_width) {
+ case 16:
+ bits |= AK5558_DIF_24BIT_MODE;
+ break;
+ case 32:
+ bits |= AK5558_DIF_32BIT_MODE;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ ak5558->fs = params_rate(params);
+ snd_soc_update_bits(codec, AK5558_02_CONTROL1, AK5558_BITS, bits);
+
+ ak5558_set_mcki(codec, ak5558->fs, ak5558->rclk);
+
+ return 0;
+}
+
+static int ak5558_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id,
+ unsigned int freq, int dir)
+{
+ struct snd_soc_codec *codec = dai->codec;
+ struct ak5558_priv *ak5558 = snd_soc_codec_get_drvdata(codec);
+
+ dev_dbg(dai->dev, "%s(%d)\n", __func__, __LINE__);
+
+ ak5558->rclk = freq;
+ ak5558_set_mcki(codec, ak5558->fs, ak5558->rclk);
+
+ return 0;
+}
+
+static int ak5558_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
+{
+
+ struct snd_soc_codec *codec = dai->codec;
+ u8 format;
+
+ dev_dbg(dai->dev, "%s(%d)\n", __func__, __LINE__);
+
+ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+ case SND_SOC_DAIFMT_CBS_CFS:
+ break;
+ case SND_SOC_DAIFMT_CBM_CFM:
+#ifdef AK5558_SLAVE_CKS_AUTO
+ break;
+#else
+ return -EINVAL;
+#endif
+ case SND_SOC_DAIFMT_CBS_CFM:
+ case SND_SOC_DAIFMT_CBM_CFS:
+ default:
+ dev_err(codec->dev, "Clock mode unsupported");
+ return -EINVAL;
+ }
+
+ /* set master/slave audio interface */
+ format = snd_soc_read(codec, AK5558_02_CONTROL1);
+ format &= ~AK5558_DIF;
+
+ switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+ case SND_SOC_DAIFMT_I2S:
+ format |= AK5558_DIF_I2S_MODE;
+ break;
+ case SND_SOC_DAIFMT_LEFT_J:
+ format |= AK5558_DIF_MSB_MODE;
+ break;
+ case SND_SOC_DAIFMT_DSP_B:
+ format |= AK5558_DIF_MSB_MODE;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ snd_soc_update_bits(codec,
+ AK5558_02_CONTROL1, AK5558_DIF, format);
+
+ return 0;
+}
+
+static int ak5558_set_dai_mute(struct snd_soc_dai *dai, int mute)
+{
+ struct snd_soc_codec *codec = dai->codec;
+ struct ak5558_priv *ak5558 = snd_soc_codec_get_drvdata(codec);
+ int ndt;
+
+ if (mute) {
+ ndt = 0;
+ if (ak5558->fs != 0)
+ ndt = 583000 / ak5558->fs;
+ if (ndt < 5)
+ ndt = 5;
+ msleep(ndt);
+ }
+
+ return 0;
+}
+
+static int ak5558_set_bias_level(struct snd_soc_codec *codec,
+ enum snd_soc_bias_level level)
+{
+
+ dev_dbg(codec->dev, "%s bias level=%d\n", __func__, (int)level);
+
+ switch (level) {
+ case SND_SOC_BIAS_ON:
+ case SND_SOC_BIAS_PREPARE:
+ case SND_SOC_BIAS_STANDBY:
+ break;
+ case SND_SOC_BIAS_OFF:
+ snd_soc_write(codec, AK5558_00_POWER_MANAGEMENT1, 0x00);
+ break;
+ }
+ return 0;
+}
+
+static int ak5558_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
+ unsigned int rx_mask, int slots,
+ int slot_width)
+{
+ struct snd_soc_codec *codec = dai->codec;
+ struct ak5558_priv *ak5558 = snd_soc_codec_get_drvdata(codec);
+ int tdm_mode = 0;
+ int reg;
+
+ ak5558->slots = slots;
+ ak5558->slot_width = slot_width;
+
+ switch (slots * slot_width) {
+ case 128:
+ tdm_mode = 1;
+ break;
+ case 256:
+ tdm_mode = 2;
+ break;
+ case 512:
+ tdm_mode = 3;
+ break;
+ default:
+ tdm_mode = 0;
+ break;
+ }
+
+ reg = snd_soc_read(codec, AK5558_03_CONTROL2);
+ reg &= ~(0x3 << 5);
+ reg |= tdm_mode << 5;
+ snd_soc_write(codec, AK5558_03_CONTROL2, reg);
+
+ return 0;
+}
+
+
+
+#define AK5558_RATES SNDRV_PCM_RATE_8000_192000
+
+#define AK5558_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
+ SNDRV_PCM_FMTBIT_S24_LE |\
+ SNDRV_PCM_FMTBIT_S32_LE)
+
+static const unsigned int ak5558_rates[] = {
+ 8000, 11025, 16000, 22050,
+ 32000, 44100, 48000, 88200,
+ 96000, 176400, 192000, 352800,
+ 384000, 705600, 768000, 1411200,
+ 2822400,
+};
+
+static const struct snd_pcm_hw_constraint_list ak5558_rate_constraints = {
+ .count = ARRAY_SIZE(ak5558_rates),
+ .list = ak5558_rates,
+};
+
+static int ak5558_startup(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai) {
+ int ret;
+
+ ret = snd_pcm_hw_constraint_list(substream->runtime, 0,
+ SNDRV_PCM_HW_PARAM_RATE, &ak5558_rate_constraints);
+
+ return ret;
+}
+
+static struct snd_soc_dai_ops ak5558_dai_ops = {
+ .startup = ak5558_startup,
+ .hw_params = ak5558_hw_params,
+ .set_sysclk = ak5558_set_dai_sysclk,
+ .set_fmt = ak5558_set_dai_fmt,
+ .digital_mute = ak5558_set_dai_mute,
+ .set_tdm_slot = ak5558_set_tdm_slot,
+};
+
+static struct snd_soc_dai_driver ak5558_dai = {
+ .name = "ak5558-aif",
+ .capture = {
+ .stream_name = "Capture",
+ .channels_min = 1,
+ .channels_max = 8,
+ .rates = SNDRV_PCM_RATE_KNOT,
+ .formats = AK5558_FORMATS,
+ },
+ .ops = &ak5558_dai_ops,
+};
+
+static int ak5558_init_reg(struct snd_soc_codec *codec)
+{
+ int ret;
+ struct ak5558_priv *ak5558 = snd_soc_codec_get_drvdata(codec);
+
+ dev_dbg(codec->dev, "%s(%d)\n", __func__, __LINE__);
+
+ usleep_range(10000, 11000);
+ if (gpio_is_valid(ak5558->pdn_gpio)) {
+ gpio_set_value_cansleep(ak5558->pdn_gpio, 0);
+ usleep_range(1000, 2000);
+ gpio_set_value_cansleep(ak5558->pdn_gpio, 1);
+ usleep_range(1000, 2000);
+ }
+
+ ret = snd_soc_write(codec, AK5558_00_POWER_MANAGEMENT1, 0x0);
+ if (ret < 0)
+ return ret;
+
+ ret = snd_soc_update_bits(codec, AK5558_02_CONTROL1, AK5558_CKS,
+ AK5558_CKS_AUTO);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
+static int ak5558_probe(struct snd_soc_codec *codec)
+{
+ struct ak5558_priv *ak5558 = snd_soc_codec_get_drvdata(codec);
+ int ret = 0;
+
+ dev_dbg(codec->dev, "%s(%d)\n", __func__, __LINE__);
+
+ ret = ak5558_init_reg(codec);
+
+ ak5558->fs = 48000;
+ ak5558->rclk = 0;
+
+ return ret;
+}
+
+static int ak5558_remove(struct snd_soc_codec *codec)
+{
+ struct ak5558_priv *ak5558 = snd_soc_codec_get_drvdata(codec);
+
+ ak5558_set_bias_level(codec, SND_SOC_BIAS_OFF);
+
+ if (gpio_is_valid(ak5558->pdn_gpio)) {
+ gpio_set_value_cansleep(ak5558->pdn_gpio, 0);
+ usleep_range(1000, 2000);
+ }
+
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int ak5558_runtime_suspend(struct device *dev)
+{
+ struct ak5558_priv *ak5558 = dev_get_drvdata(dev);
+
+ regcache_cache_only(ak5558->regmap, true);
+
+ if (gpio_is_valid(ak5558->pdn_gpio)) {
+ gpio_set_value_cansleep(ak5558->pdn_gpio, 0);
+ usleep_range(1000, 2000);
+ }
+
+ return 0;
+}
+
+static int ak5558_runtime_resume(struct device *dev)
+{
+ struct ak5558_priv *ak5558 = dev_get_drvdata(dev);
+
+ if (gpio_is_valid(ak5558->pdn_gpio)) {
+ gpio_set_value_cansleep(ak5558->pdn_gpio, 0);
+ usleep_range(1000, 2000);
+ gpio_set_value_cansleep(ak5558->pdn_gpio, 1);
+ usleep_range(1000, 2000);
+
+ }
+
+ regcache_cache_only(ak5558->regmap, false);
+ regcache_mark_dirty(ak5558->regmap);
+
+ return regcache_sync(ak5558->regmap);
+}
+#endif
+
+const struct dev_pm_ops ak5558_pm = {
+ SET_RUNTIME_PM_OPS(ak5558_runtime_suspend, ak5558_runtime_resume, NULL)
+ SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
+ pm_runtime_force_resume)
+};
+
+struct snd_soc_codec_driver soc_codec_dev_ak5558 = {
+ .probe = ak5558_probe,
+ .remove = ak5558_remove,
+ .idle_bias_off = true,
+ .set_bias_level = ak5558_set_bias_level,
+
+ .component_driver = {
+ .controls = ak5558_snd_controls,
+ .num_controls = ARRAY_SIZE(ak5558_snd_controls),
+ .dapm_widgets = ak5558_dapm_widgets,
+ .num_dapm_widgets = ARRAY_SIZE(ak5558_dapm_widgets),
+ .dapm_routes = ak5558_intercon,
+ .num_dapm_routes = ARRAY_SIZE(ak5558_intercon),
+ },
+};
+
+static const struct regmap_config ak5558_regmap = {
+ .reg_bits = 8,
+ .val_bits = 8,
+
+ .max_register = AK5558_05_DSD,
+ .reg_defaults = ak5558_reg,
+ .num_reg_defaults = ARRAY_SIZE(ak5558_reg),
+ .cache_type = REGCACHE_RBTREE,
+};
+
+static int ak5558_i2c_probe(struct i2c_client *i2c,
+ const struct i2c_device_id *id)
+{
+ struct device_node *np = i2c->dev.of_node;
+ struct ak5558_priv *ak5558;
+ int ret = 0;
+ int i;
+
+ dev_dbg(&i2c->dev, "%s(%d)\n", __func__, __LINE__);
+
+ ak5558 = devm_kzalloc(&i2c->dev, sizeof(struct ak5558_priv),
+ GFP_KERNEL);
+ if (ak5558 == NULL)
+ return -ENOMEM;
+
+ ak5558->regmap = devm_regmap_init_i2c(i2c, &ak5558_regmap);
+ if (IS_ERR(ak5558->regmap))
+ return PTR_ERR(ak5558->regmap);
+
+ i2c_set_clientdata(i2c, ak5558);
+ ak5558->i2c = i2c;
+
+ ak5558->pdn_gpio = of_get_named_gpio(np, "ak5558,pdn-gpio", 0);
+ if (gpio_is_valid(ak5558->pdn_gpio)) {
+ ret = devm_gpio_request_one(&i2c->dev, ak5558->pdn_gpio,
+ GPIOF_OUT_INIT_LOW, "ak5558,pdn");
+ if (ret) {
+ dev_err(&i2c->dev, "unable to get pdn gpio\n");
+ return ret;
+ }
+ }
+
+ for (i = 0; i < ARRAY_SIZE(ak5558->supplies); i++)
+ ak5558->supplies[i].supply = ak5558_supply_names[i];
+
+ ret = devm_regulator_bulk_get(&i2c->dev, ARRAY_SIZE(ak5558->supplies),
+ ak5558->supplies);
+ if (ret != 0) {
+ dev_err(&i2c->dev, "Failed to request supplies: %d\n", ret);
+ return ret;
+ }
+
+ ret = regulator_bulk_enable(ARRAY_SIZE(ak5558->supplies),
+ ak5558->supplies);
+ if (ret != 0) {
+ dev_err(&i2c->dev, "Failed to enable supplies: %d\n", ret);
+ return ret;
+ }
+
+ ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_ak5558,
+ &ak5558_dai, 1);
+ if (ret)
+ return ret;
+
+ pm_runtime_enable(&i2c->dev);
+
+ return 0;
+}
+
+static int ak5558_i2c_remove(struct i2c_client *client)
+{
+ snd_soc_unregister_codec(&client->dev);
+ pm_runtime_disable(&client->dev);
+
+
+ return 0;
+}
+
+static const struct of_device_id ak5558_i2c_dt_ids[] = {
+ { .compatible = "asahi-kasei,ak5558"},
+ { }
+};
+
+static const struct i2c_device_id ak5558_i2c_id[] = {
+ { "ak5558", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, ak5558_i2c_id);
+
+static struct i2c_driver ak5558_i2c_driver = {
+ .driver = {
+ .name = "ak5558",
+ .of_match_table = of_match_ptr(ak5558_i2c_dt_ids),
+ .pm = &ak5558_pm,
+ },
+ .probe = ak5558_i2c_probe,
+ .remove = ak5558_i2c_remove,
+ .id_table = ak5558_i2c_id,
+};
+
+module_i2c_driver(ak5558_i2c_driver);
+
+MODULE_AUTHOR("Junichi Wakasugi <wakasugi.jb@om.asahi-kasei.co.jp>");
+MODULE_AUTHOR("Mihai Serban <mihai.serban@nxp.com>");
+MODULE_DESCRIPTION("ASoC AK5558 ADC driver");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/ak5558.h b/sound/soc/codecs/ak5558.h
new file mode 100644
index 000000000000..3cc030fd089d
--- /dev/null
+++ b/sound/soc/codecs/ak5558.h
@@ -0,0 +1,55 @@
+/*
+ * ak5558.h -- audio driver for AK5558
+ *
+ * Copyright (C) 2016 Asahi Kasei Microdevices Corporation
+ * Copyright 2017 NXP
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _AK5558_H
+#define _AK5558_H
+
+#define AK5558_00_POWER_MANAGEMENT1 0x00
+#define AK5558_01_POWER_MANAGEMENT2 0x01
+#define AK5558_02_CONTROL1 0x02
+#define AK5558_03_CONTROL2 0x03
+#define AK5558_04_CONTROL3 0x04
+#define AK5558_05_DSD 0x05
+
+/* Bitfield Definitions */
+
+/* AK5558_02_CONTROL1 (0x03) Fields */
+#define AK5558_DIF 0x02
+#define AK5558_DIF_MSB_MODE (0 << 1)
+#define AK5558_DIF_I2S_MODE (1 << 1)
+
+#define AK5558_BITS 0x04
+#define AK5558_DIF_24BIT_MODE (0 << 2)
+#define AK5558_DIF_32BIT_MODE (1 << 2)
+
+#define AK5558_CKS 0x78
+#define AK5558_CKS_128FS_192KHZ (0 << 3)
+#define AK5558_CKS_192FS_192KHZ (1 << 3)
+#define AK5558_CKS_256FS_48KHZ (2 << 3)
+#define AK5558_CKS_256FS_96KHZ (3 << 3)
+#define AK5558_CKS_384FS_96KHZ (4 << 3)
+#define AK5558_CKS_384FS_48KHZ (5 << 3)
+#define AK5558_CKS_512FS_48KHZ (6 << 3)
+#define AK5558_CKS_768FS_48KHZ (7 << 3)
+#define AK5558_CKS_64FS_384KHZ (8 << 3)
+#define AK5558_CKS_32FS_768KHZ (9 << 3)
+#define AK5558_CKS_96FS_384KHZ (10 << 3)
+#define AK5558_CKS_48FS_768KHZ (11 << 3)
+#define AK5558_CKS_64FS_768KHZ (12 << 3)
+#define AK5558_CKS_1024FS_16KHZ (13 << 3)
+#define AK5558_CKS_AUTO (15 << 3)
+
+#endif
diff --git a/sound/soc/codecs/cs42xx8.c b/sound/soc/codecs/cs42xx8.c
index 204bb0eba716..cedddee67199 100644
--- a/sound/soc/codecs/cs42xx8.c
+++ b/sound/soc/codecs/cs42xx8.c
@@ -1,7 +1,7 @@
/*
* Cirrus Logic CS42448/CS42888 Audio CODEC Digital Audio Interface (DAI) driver
*
- * Copyright (C) 2014 Freescale Semiconductor, Inc.
+ * Copyright (C) 2014-2016 Freescale Semiconductor, Inc.
*
* Author: Nicolin Chen <Guangyu.Chen@freescale.com>
*
@@ -14,6 +14,7 @@
#include <linux/delay.h>
#include <linux/module.h>
#include <linux/of_device.h>
+#include <linux/of_gpio.h>
#include <linux/pm_runtime.h>
#include <linux/regulator/consumer.h>
#include <sound/pcm_params.h>
@@ -32,8 +33,7 @@ static const char *const cs42xx8_supply_names[CS42XX8_NUM_SUPPLIES] = {
#define CS42XX8_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \
SNDRV_PCM_FMTBIT_S20_3LE | \
- SNDRV_PCM_FMTBIT_S24_LE | \
- SNDRV_PCM_FMTBIT_S32_LE)
+ SNDRV_PCM_FMTBIT_S24_LE)
/* codec private data */
struct cs42xx8_priv {
@@ -42,9 +42,12 @@ struct cs42xx8_priv {
struct regmap *regmap;
struct clk *clk;
- bool slave_mode;
+ bool slave_mode[2];
+ bool is_tdm;
unsigned long sysclk;
u32 tx_channels;
+ int rate[2];
+ int reset_gpio;
};
/* -127.5dB to 0dB with step of 0.5dB */
@@ -128,7 +131,6 @@ static const struct snd_soc_dapm_widget cs42xx8_dapm_widgets[] = {
SND_SOC_DAPM_INPUT("AIN2L"),
SND_SOC_DAPM_INPUT("AIN2R"),
- SND_SOC_DAPM_SUPPLY("PWR", CS42XX8_PWRCTL, 0, 1, NULL, 0),
};
static const struct snd_soc_dapm_widget cs42xx8_adc3_dapm_widgets[] = {
@@ -142,53 +144,43 @@ static const struct snd_soc_dapm_route cs42xx8_dapm_routes[] = {
/* Playback */
{ "AOUT1L", NULL, "DAC1" },
{ "AOUT1R", NULL, "DAC1" },
- { "DAC1", NULL, "PWR" },
{ "AOUT2L", NULL, "DAC2" },
{ "AOUT2R", NULL, "DAC2" },
- { "DAC2", NULL, "PWR" },
{ "AOUT3L", NULL, "DAC3" },
{ "AOUT3R", NULL, "DAC3" },
- { "DAC3", NULL, "PWR" },
{ "AOUT4L", NULL, "DAC4" },
{ "AOUT4R", NULL, "DAC4" },
- { "DAC4", NULL, "PWR" },
/* Capture */
{ "ADC1", NULL, "AIN1L" },
{ "ADC1", NULL, "AIN1R" },
- { "ADC1", NULL, "PWR" },
{ "ADC2", NULL, "AIN2L" },
{ "ADC2", NULL, "AIN2R" },
- { "ADC2", NULL, "PWR" },
};
static const struct snd_soc_dapm_route cs42xx8_adc3_dapm_routes[] = {
/* Capture */
{ "ADC3", NULL, "AIN3L" },
{ "ADC3", NULL, "AIN3R" },
- { "ADC3", NULL, "PWR" },
};
struct cs42xx8_ratios {
- unsigned int ratio;
- unsigned char speed;
- unsigned char mclk;
+ unsigned int mfreq;
+ unsigned int min_mclk;
+ unsigned int max_mclk;
+ unsigned int ratio[3];
};
static const struct cs42xx8_ratios cs42xx8_ratios[] = {
- { 64, CS42XX8_FM_QUAD, CS42XX8_FUNCMOD_MFREQ_256(4) },
- { 96, CS42XX8_FM_QUAD, CS42XX8_FUNCMOD_MFREQ_384(4) },
- { 128, CS42XX8_FM_QUAD, CS42XX8_FUNCMOD_MFREQ_512(4) },
- { 192, CS42XX8_FM_QUAD, CS42XX8_FUNCMOD_MFREQ_768(4) },
- { 256, CS42XX8_FM_SINGLE, CS42XX8_FUNCMOD_MFREQ_256(1) },
- { 384, CS42XX8_FM_SINGLE, CS42XX8_FUNCMOD_MFREQ_384(1) },
- { 512, CS42XX8_FM_SINGLE, CS42XX8_FUNCMOD_MFREQ_512(1) },
- { 768, CS42XX8_FM_SINGLE, CS42XX8_FUNCMOD_MFREQ_768(1) },
- { 1024, CS42XX8_FM_SINGLE, CS42XX8_FUNCMOD_MFREQ_1024(1) }
+ { 0, 1029000, 12800000, {256, 128, 64} },
+ { 2, 1536000, 19200000, {384, 192, 96} },
+ { 4, 2048000, 25600000, {512, 256, 128} },
+ { 6, 3072000, 38400000, {768, 384, 192} },
+ { 8, 4096000, 51200000, {1024, 512, 256} },
};
static int cs42xx8_set_dai_sysclk(struct snd_soc_dai *codec_dai,
@@ -209,6 +201,8 @@ static int cs42xx8_set_dai_fmt(struct snd_soc_dai *codec_dai,
struct cs42xx8_priv *cs42xx8 = snd_soc_codec_get_drvdata(codec);
u32 val;
+ cs42xx8->is_tdm = false;
+
/* Set DAI format */
switch (format & SND_SOC_DAIFMT_FORMAT_MASK) {
case SND_SOC_DAIFMT_LEFT_J:
@@ -222,6 +216,7 @@ static int cs42xx8_set_dai_fmt(struct snd_soc_dai *codec_dai,
break;
case SND_SOC_DAIFMT_DSP_A:
val = CS42XX8_INTF_DAC_DIF_TDM | CS42XX8_INTF_ADC_DIF_TDM;
+ cs42xx8->is_tdm = true;
break;
default:
dev_err(codec->dev, "unsupported dai format\n");
@@ -232,17 +227,21 @@ static int cs42xx8_set_dai_fmt(struct snd_soc_dai *codec_dai,
CS42XX8_INTF_DAC_DIF_MASK |
CS42XX8_INTF_ADC_DIF_MASK, val);
- /* Set master/slave audio interface */
- switch (format & SND_SOC_DAIFMT_MASTER_MASK) {
- case SND_SOC_DAIFMT_CBS_CFS:
- cs42xx8->slave_mode = true;
- break;
- case SND_SOC_DAIFMT_CBM_CFM:
- cs42xx8->slave_mode = false;
- break;
- default:
- dev_err(codec->dev, "unsupported master/slave mode\n");
- return -EINVAL;
+ if (cs42xx8->slave_mode[0] == cs42xx8->slave_mode[1]) {
+ /* Set master/slave audio interface */
+ switch (format & SND_SOC_DAIFMT_MASTER_MASK) {
+ case SND_SOC_DAIFMT_CBS_CFS:
+ cs42xx8->slave_mode[0] = true;
+ cs42xx8->slave_mode[1] = true;
+ break;
+ case SND_SOC_DAIFMT_CBM_CFM:
+ cs42xx8->slave_mode[0] = false;
+ cs42xx8->slave_mode[1] = false;
+ break;
+ default:
+ dev_err(codec->dev, "unsupported master/slave mode\n");
+ return -EINVAL;
+ }
}
return 0;
@@ -255,14 +254,61 @@ static int cs42xx8_hw_params(struct snd_pcm_substream *substream,
struct snd_soc_codec *codec = dai->codec;
struct cs42xx8_priv *cs42xx8 = snd_soc_codec_get_drvdata(codec);
bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
- u32 ratio = cs42xx8->sysclk / params_rate(params);
- u32 i, fm, val, mask;
+ u32 ratio[2];
+ u32 rate[2];
+ u32 fm[2];
+ u32 i, val, mask;
+ bool condition1, condition2;
if (tx)
cs42xx8->tx_channels = params_channels(params);
+ rate[tx] = params_rate(params);
+ rate[!tx] = cs42xx8->rate[!tx];
+
+ ratio[tx] = rate[tx] > 0 ? cs42xx8->sysclk / rate[tx] : 0;
+ ratio[!tx] = rate[!tx] > 0 ? cs42xx8->sysclk / rate[!tx] : 0;
+
+ for (i = 0; i < 2; i++) {
+ if (cs42xx8->slave_mode[i]) {
+ fm[i] = CS42XX8_FM_AUTO;
+ } else {
+ if (rate[i] < 50000)
+ fm[i] = CS42XX8_FM_SINGLE;
+ else if (rate[i] > 50000 && rate[i] < 100000)
+ fm[i] = CS42XX8_FM_DOUBLE;
+ else if (rate[i] > 100000 && rate[i] < 200000)
+ fm[i] = CS42XX8_FM_QUAD;
+ else {
+ dev_err(codec->dev,
+ "unsupported sample rate or rate combine\n");
+ return -EINVAL;
+ }
+ }
+ }
+
for (i = 0; i < ARRAY_SIZE(cs42xx8_ratios); i++) {
- if (cs42xx8_ratios[i].ratio == ratio)
+ condition1 = ((fm[tx] == CS42XX8_FM_AUTO) ?
+ (cs42xx8_ratios[i].ratio[0] == ratio[tx] ||
+ cs42xx8_ratios[i].ratio[1] == ratio[tx] ||
+ cs42xx8_ratios[i].ratio[2] == ratio[tx]) :
+ (cs42xx8_ratios[i].ratio[fm[tx]] == ratio[tx])) &&
+ cs42xx8->sysclk >= cs42xx8_ratios[i].min_mclk &&
+ cs42xx8->sysclk <= cs42xx8_ratios[i].max_mclk;
+
+ if (ratio[tx] <= 0)
+ condition1 = true;
+
+ condition2 = ((fm[!tx] == CS42XX8_FM_AUTO) ?
+ (cs42xx8_ratios[i].ratio[0] == ratio[!tx] ||
+ cs42xx8_ratios[i].ratio[1] == ratio[!tx] ||
+ cs42xx8_ratios[i].ratio[2] == ratio[!tx]) :
+ (cs42xx8_ratios[i].ratio[fm[!tx]] == ratio[!tx]));
+
+ if (ratio[!tx] <= 0)
+ condition2 = true;
+
+ if (condition1 && condition2)
break;
}
@@ -271,18 +317,44 @@ static int cs42xx8_hw_params(struct snd_pcm_substream *substream,
return -EINVAL;
}
- mask = CS42XX8_FUNCMOD_MFREQ_MASK;
- val = cs42xx8_ratios[i].mclk;
+ cs42xx8->rate[tx] = params_rate(params);
- fm = cs42xx8->slave_mode ? CS42XX8_FM_AUTO : cs42xx8_ratios[i].speed;
+ if (cs42xx8->is_tdm && !cs42xx8->slave_mode[tx]) {
+ dev_err(codec->dev, "TDM mode is unsupported in master mode\n");
+ return -EINVAL;
+ }
+
+ if (cs42xx8->is_tdm && (cs42xx8->sysclk < 256 * cs42xx8->rate[tx])) {
+ dev_err(codec->dev, "unsupported sysclk for TDM mode\n");
+ return -EINVAL;
+ }
+
+ mask = CS42XX8_FUNCMOD_MFREQ_MASK;
+ val = cs42xx8_ratios[i].mfreq;
regmap_update_bits(cs42xx8->regmap, CS42XX8_FUNCMOD,
CS42XX8_FUNCMOD_xC_FM_MASK(tx) | mask,
- CS42XX8_FUNCMOD_xC_FM(tx, fm) | val);
+ CS42XX8_FUNCMOD_xC_FM(tx, fm[tx]) | val);
return 0;
}
+static int cs42xx8_hw_free(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_codec *codec = rtd->codec;
+ struct cs42xx8_priv *cs42xx8 = snd_soc_codec_get_drvdata(codec);
+ bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
+
+ cs42xx8->rate[tx] = 0;
+
+ regmap_update_bits(cs42xx8->regmap, CS42XX8_FUNCMOD,
+ CS42XX8_FUNCMOD_xC_FM_MASK(tx),
+ CS42XX8_FUNCMOD_xC_FM(tx, CS42XX8_FM_AUTO));
+ return 0;
+}
+
static int cs42xx8_digital_mute(struct snd_soc_dai *dai, int mute)
{
struct snd_soc_codec *codec = dai->codec;
@@ -300,6 +372,7 @@ static const struct snd_soc_dai_ops cs42xx8_dai_ops = {
.set_fmt = cs42xx8_set_dai_fmt,
.set_sysclk = cs42xx8_set_dai_sysclk,
.hw_params = cs42xx8_hw_params,
+ .hw_free = cs42xx8_hw_free,
.digital_mute = cs42xx8_digital_mute,
};
@@ -379,6 +452,7 @@ const struct regmap_config cs42xx8_regmap_config = {
.volatile_reg = cs42xx8_volatile_register,
.writeable_reg = cs42xx8_writeable_register,
.cache_type = REGCACHE_RBTREE,
+ .use_single_rw = true,
};
EXPORT_SYMBOL_GPL(cs42xx8_regmap_config);
@@ -402,7 +476,8 @@ static int cs42xx8_codec_probe(struct snd_soc_codec *codec)
/* Mute all DAC channels */
regmap_write(cs42xx8->regmap, CS42XX8_DACMUTE, CS42XX8_DACMUTE_ALL);
-
+ regmap_update_bits(cs42xx8->regmap, CS42XX8_PWRCTL,
+ CS42XX8_PWRCTL_PDN_MASK, 0);
return 0;
}
@@ -442,7 +517,8 @@ EXPORT_SYMBOL_GPL(cs42xx8_of_match);
int cs42xx8_probe(struct device *dev, struct regmap *regmap)
{
- const struct of_device_id *of_id;
+ const struct of_device_id *of_id = of_match_device(cs42xx8_of_match, dev);
+ struct device_node *np = dev->of_node;
struct cs42xx8_priv *cs42xx8;
int ret, val, i;
@@ -468,6 +544,17 @@ int cs42xx8_probe(struct device *dev, struct regmap *regmap)
return -EINVAL;
}
+ cs42xx8->reset_gpio = of_get_named_gpio(np, "reset-gpio", 0);
+ if (gpio_is_valid(cs42xx8->reset_gpio)) {
+ ret = devm_gpio_request_one(dev, cs42xx8->reset_gpio,
+ GPIOF_OUT_INIT_LOW, "cs42xx8 reset");
+ if (ret) {
+ dev_err(dev, "unable to get reset gpio\n");
+ return ret;
+ }
+ gpio_set_value_cansleep(cs42xx8->reset_gpio, 1);
+ }
+
cs42xx8->clk = devm_clk_get(dev, "mclk");
if (IS_ERR(cs42xx8->clk)) {
dev_err(dev, "failed to get the clock: %ld\n",
@@ -477,6 +564,18 @@ int cs42xx8_probe(struct device *dev, struct regmap *regmap)
cs42xx8->sysclk = clk_get_rate(cs42xx8->clk);
+ if (of_property_read_bool(np, "fsl,txm-rxs")) {
+ /* 0 -- rx, 1 -- tx */
+ cs42xx8->slave_mode[0] = true;
+ cs42xx8->slave_mode[1] = false;
+ }
+
+ if (of_property_read_bool(np, "fsl,txs-rxm")) {
+ /* 0 -- rx, 1 -- tx */
+ cs42xx8->slave_mode[0] = false;
+ cs42xx8->slave_mode[1] = true;
+ }
+
for (i = 0; i < ARRAY_SIZE(cs42xx8->supplies); i++)
cs42xx8->supplies[i].supply = cs42xx8_supply_names[i];
@@ -548,6 +647,11 @@ static int cs42xx8_runtime_resume(struct device *dev)
return ret;
}
+ if (gpio_is_valid(cs42xx8->reset_gpio)) {
+ gpio_set_value_cansleep(cs42xx8->reset_gpio, 0);
+ gpio_set_value_cansleep(cs42xx8->reset_gpio, 1);
+ }
+
ret = regulator_bulk_enable(ARRAY_SIZE(cs42xx8->supplies),
cs42xx8->supplies);
if (ret) {
@@ -555,9 +659,14 @@ static int cs42xx8_runtime_resume(struct device *dev)
goto err_clk;
}
+ regmap_update_bits(cs42xx8->regmap, CS42XX8_PWRCTL,
+ CS42XX8_PWRCTL_PDN_MASK, 1);
/* Make sure hardware reset done */
msleep(5);
+ regmap_update_bits(cs42xx8->regmap, CS42XX8_PWRCTL,
+ CS42XX8_PWRCTL_PDN_MASK, 0);
+
regcache_cache_only(cs42xx8->regmap, false);
regcache_mark_dirty(cs42xx8->regmap);
@@ -594,6 +703,7 @@ static int cs42xx8_runtime_suspend(struct device *dev)
#endif
const struct dev_pm_ops cs42xx8_pm = {
+ SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, pm_runtime_force_resume)
SET_RUNTIME_PM_OPS(cs42xx8_runtime_suspend, cs42xx8_runtime_resume, NULL)
};
EXPORT_SYMBOL_GPL(cs42xx8_pm);
diff --git a/sound/soc/codecs/fsl_mqs.c b/sound/soc/codecs/fsl_mqs.c
new file mode 100644
index 000000000000..d2890d6f9185
--- /dev/null
+++ b/sound/soc/codecs/fsl_mqs.c
@@ -0,0 +1,359 @@
+/*
+ * ALSA SoC IMX MQS driver
+ *
+ * Copyright (C) 2014-2015 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/clk.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/mfd/syscon.h>
+#include <linux/mfd/syscon/imx6q-iomuxc-gpr.h>
+#include <linux/pm_runtime.h>
+#include <linux/of.h>
+#include <linux/pm.h>
+#include <linux/slab.h>
+#include <sound/soc.h>
+#include <sound/pcm.h>
+#include <sound/initval.h>
+
+
+#define REG_MQS_CTRL 0x00
+
+#define MQS_EN_MASK (0x1 << 28)
+#define MQS_EN_SHIFT (28)
+#define MQS_SW_RST_MASK (0x1 << 24)
+#define MQS_SW_RST_SHIFT (24)
+#define MQS_OVERSAMPLE_MASK (0x1 << 20)
+#define MQS_OVERSAMPLE_SHIFT (20)
+#define MQS_CLK_DIV_MASK (0xFF << 0)
+#define MQS_CLK_DIV_SHIFT (0)
+
+
+/* codec private data */
+struct fsl_mqs {
+ struct platform_device *pdev;
+ struct regmap *gpr;
+ unsigned int reg_iomuxc_gpr2;
+
+ struct regmap *regmap;
+ unsigned int reg_mqs_ctrl;
+
+ struct clk *mclk;
+ struct clk *ipg;
+
+ unsigned long mclk_rate;
+
+ int sysclk_rate;
+ int bclk;
+ int lrclk;
+ bool use_gpr;
+ char name[32];
+};
+
+#define FSL_MQS_RATES SNDRV_PCM_RATE_8000_192000
+#define FSL_MQS_FORMATS SNDRV_PCM_FMTBIT_S16_LE
+
+static int fsl_mqs_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params,
+ struct snd_soc_dai *dai)
+{
+ struct snd_soc_codec *codec = dai->codec;
+ struct fsl_mqs *mqs_priv = snd_soc_codec_get_drvdata(codec);
+ int div, res;
+
+ mqs_priv->mclk_rate = clk_get_rate(mqs_priv->mclk);
+
+ mqs_priv->bclk = snd_soc_params_to_bclk(params);
+ mqs_priv->lrclk = params_rate(params);
+
+ /*
+ * mclk_rate / (oversample(32,64) * FS * 2 * divider ) = repeat_rate;
+ * if repeat_rate is 8, mqs can achieve better quality.
+ * oversample rate is fix to 32 currently.
+ */
+ div = mqs_priv->mclk_rate / (32 * 2 * mqs_priv->lrclk * 8);
+ res = mqs_priv->mclk_rate % (32 * 2 * mqs_priv->lrclk * 8);
+
+ if (res == 0 && div > 0 && div <= 256) {
+ if (mqs_priv->use_gpr) {
+ regmap_update_bits(mqs_priv->gpr, IOMUXC_GPR2,
+ IMX6SX_GPR2_MQS_CLK_DIV_MASK,
+ (div-1) << IMX6SX_GPR2_MQS_CLK_DIV_SHIFT);
+ regmap_update_bits(mqs_priv->gpr, IOMUXC_GPR2,
+ IMX6SX_GPR2_MQS_OVERSAMPLE_MASK,
+ 0 << IMX6SX_GPR2_MQS_OVERSAMPLE_SHIFT);
+ } else {
+ regmap_update_bits(mqs_priv->regmap, REG_MQS_CTRL,
+ MQS_CLK_DIV_MASK,
+ (div-1) << MQS_CLK_DIV_SHIFT);
+ regmap_update_bits(mqs_priv->regmap, REG_MQS_CTRL,
+ MQS_OVERSAMPLE_MASK,
+ 0 << MQS_OVERSAMPLE_SHIFT);
+ }
+ } else
+ dev_err(&mqs_priv->pdev->dev, "can't get proper divider\n");
+
+ return 0;
+}
+
+static int fsl_mqs_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
+{
+ switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+ case SND_SOC_DAIFMT_LEFT_J:
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
+ case SND_SOC_DAIFMT_NB_NF:
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+ case SND_SOC_DAIFMT_CBS_CFS:
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int fsl_mqs_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id,
+ unsigned int freq, int dir)
+{
+ struct snd_soc_codec *codec = dai->codec;
+ struct fsl_mqs *mqs_priv = snd_soc_codec_get_drvdata(codec);
+
+ mqs_priv->sysclk_rate = freq;
+
+ return 0;
+}
+
+static int fsl_mqs_startup(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ struct snd_soc_codec *codec = dai->codec;
+ struct fsl_mqs *mqs_priv = snd_soc_codec_get_drvdata(codec);
+
+ if (mqs_priv->use_gpr)
+ regmap_update_bits(mqs_priv->gpr, IOMUXC_GPR2, IMX6SX_GPR2_MQS_EN_MASK,
+ 1 << IMX6SX_GPR2_MQS_EN_SHIFT);
+ else
+ regmap_update_bits(mqs_priv->regmap, REG_MQS_CTRL,
+ MQS_EN_MASK,
+ 1 << MQS_EN_SHIFT);
+ return 0;
+}
+
+static void fsl_mqs_shutdown(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ struct snd_soc_codec *codec = dai->codec;
+ struct fsl_mqs *mqs_priv = snd_soc_codec_get_drvdata(codec);
+
+ if (mqs_priv->use_gpr)
+ regmap_update_bits(mqs_priv->gpr, IOMUXC_GPR2,
+ IMX6SX_GPR2_MQS_EN_MASK, 0);
+ else
+ regmap_update_bits(mqs_priv->regmap, REG_MQS_CTRL,
+ MQS_EN_MASK, 0);
+}
+
+
+static struct snd_soc_codec_driver soc_codec_fsl_mqs = {
+ .idle_bias_off = true,
+};
+
+static const struct snd_soc_dai_ops fsl_mqs_dai_ops = {
+ .startup = fsl_mqs_startup,
+ .shutdown = fsl_mqs_shutdown,
+ .hw_params = fsl_mqs_hw_params,
+ .set_fmt = fsl_mqs_set_dai_fmt,
+ .set_sysclk = fsl_mqs_set_dai_sysclk,
+};
+
+static struct snd_soc_dai_driver fsl_mqs_dai = {
+ .name = "fsl-mqs-dai",
+ .playback = {
+ .stream_name = "Playback",
+ .channels_min = 2,
+ .channels_max = 2,
+ .rates = FSL_MQS_RATES,
+ .formats = FSL_MQS_FORMATS,
+ },
+ .ops = &fsl_mqs_dai_ops,
+};
+
+static const struct regmap_config fsl_mqs_regmap_config = {
+ .reg_bits = 32,
+ .reg_stride = 4,
+ .val_bits = 32,
+ .max_register = REG_MQS_CTRL,
+ .cache_type = REGCACHE_NONE,
+};
+
+static int fsl_mqs_probe(struct platform_device *pdev)
+{
+ struct device_node *np = pdev->dev.of_node;
+ struct device_node *gpr_np = 0;
+ struct fsl_mqs *mqs_priv;
+ struct resource *res;
+ void __iomem *regs;
+ int ret = 0;
+
+ mqs_priv = devm_kzalloc(&pdev->dev, sizeof(*mqs_priv), GFP_KERNEL);
+ if (!mqs_priv)
+ return -ENOMEM;
+
+ mqs_priv->pdev = pdev;
+ strncpy(mqs_priv->name, np->name, sizeof(mqs_priv->name) - 1);
+
+ if (of_device_is_compatible(np, "fsl,imx8qm-mqs"))
+ mqs_priv->use_gpr = false;
+ else
+ mqs_priv->use_gpr = true;
+
+ if (mqs_priv->use_gpr) {
+ gpr_np = of_parse_phandle(np, "gpr", 0);
+ if (IS_ERR(gpr_np)) {
+ dev_err(&pdev->dev, "failed to get gpr node by phandle\n");
+ ret = PTR_ERR(gpr_np);
+ goto out;
+ }
+
+ mqs_priv->gpr = syscon_node_to_regmap(gpr_np);
+ if (IS_ERR(mqs_priv->gpr)) {
+ dev_err(&pdev->dev, "failed to get gpr regmap\n");
+ ret = PTR_ERR(mqs_priv->gpr);
+ goto out;
+ }
+ } else {
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ regs = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(regs))
+ return PTR_ERR(regs);
+
+ mqs_priv->regmap = devm_regmap_init_mmio_clk(&pdev->dev,
+ "core", regs, &fsl_mqs_regmap_config);
+ if (IS_ERR(mqs_priv->regmap)) {
+ dev_err(&pdev->dev, "failed to init regmap: %ld\n",
+ PTR_ERR(mqs_priv->regmap));
+ return PTR_ERR(mqs_priv->regmap);
+ }
+
+ mqs_priv->ipg = devm_clk_get(&pdev->dev, "core");
+ if (IS_ERR(mqs_priv->ipg)) {
+ dev_err(&pdev->dev, "failed to get the clock: %ld\n",
+ PTR_ERR(mqs_priv->ipg));
+ goto out;
+ }
+ }
+
+ mqs_priv->mclk = devm_clk_get(&pdev->dev, "mclk");
+ if (IS_ERR(mqs_priv->mclk)) {
+ dev_err(&pdev->dev, "failed to get the clock: %ld\n",
+ PTR_ERR(mqs_priv->mclk));
+ goto out;
+ }
+
+ dev_set_drvdata(&pdev->dev, mqs_priv);
+ pm_runtime_enable(&pdev->dev);
+
+ return snd_soc_register_codec(&pdev->dev, &soc_codec_fsl_mqs,
+ &fsl_mqs_dai, 1);
+
+out:
+ if (!IS_ERR(gpr_np))
+ of_node_put(gpr_np);
+
+ return ret;
+}
+
+static int fsl_mqs_remove(struct platform_device *pdev)
+{
+ snd_soc_unregister_codec(&pdev->dev);
+ pm_runtime_disable(&pdev->dev);
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int fsl_mqs_runtime_resume(struct device *dev)
+{
+ struct fsl_mqs *mqs_priv = dev_get_drvdata(dev);
+
+ if (mqs_priv->ipg)
+ clk_prepare_enable(mqs_priv->ipg);
+
+ if (mqs_priv->mclk)
+ clk_prepare_enable(mqs_priv->mclk);
+
+ if (mqs_priv->use_gpr)
+ regmap_write(mqs_priv->gpr, IOMUXC_GPR2,
+ mqs_priv->reg_iomuxc_gpr2);
+ else
+ regmap_write(mqs_priv->regmap, REG_MQS_CTRL,
+ mqs_priv->reg_mqs_ctrl);
+ return 0;
+}
+
+static int fsl_mqs_runtime_suspend(struct device *dev)
+{
+ struct fsl_mqs *mqs_priv = dev_get_drvdata(dev);
+
+ if (mqs_priv->use_gpr)
+ regmap_read(mqs_priv->gpr, IOMUXC_GPR2,
+ &mqs_priv->reg_iomuxc_gpr2);
+ else
+ regmap_read(mqs_priv->regmap, REG_MQS_CTRL,
+ &mqs_priv->reg_mqs_ctrl);
+
+ if (mqs_priv->mclk)
+ clk_disable_unprepare(mqs_priv->mclk);
+
+ if (mqs_priv->ipg)
+ clk_disable_unprepare(mqs_priv->ipg);
+
+ return 0;
+}
+#endif
+
+static const struct dev_pm_ops fsl_mqs_pm_ops = {
+ SET_RUNTIME_PM_OPS(fsl_mqs_runtime_suspend,
+ fsl_mqs_runtime_resume,
+ NULL)
+ SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, pm_runtime_force_resume)
+};
+
+static const struct of_device_id fsl_mqs_dt_ids[] = {
+ { .compatible = "fsl,imx8qm-mqs", },
+ { .compatible = "fsl,imx6sx-mqs", },
+ {}
+};
+MODULE_DEVICE_TABLE(of, fsl_mqs_dt_ids);
+
+
+static struct platform_driver fsl_mqs_driver = {
+ .probe = fsl_mqs_probe,
+ .remove = fsl_mqs_remove,
+ .driver = {
+ .name = "fsl-mqs",
+ .of_match_table = fsl_mqs_dt_ids,
+ .pm = &fsl_mqs_pm_ops,
+ },
+};
+
+module_platform_driver(fsl_mqs_driver);
+
+MODULE_AUTHOR("shengjiu wang <shengjiu.wang@freescale.com>");
+MODULE_DESCRIPTION("MQS dummy codec driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform: fsl-mqs");
diff --git a/sound/soc/codecs/hdmi-codec.c b/sound/soc/codecs/hdmi-codec.c
index e00f5f49f21d..51d9021ab091 100644
--- a/sound/soc/codecs/hdmi-codec.c
+++ b/sound/soc/codecs/hdmi-codec.c
@@ -289,10 +289,7 @@ struct hdmi_codec_priv {
static const struct snd_soc_dapm_widget hdmi_widgets[] = {
SND_SOC_DAPM_OUTPUT("TX"),
-};
-
-static const struct snd_soc_dapm_route hdmi_routes[] = {
- { "TX", NULL, "Playback" },
+ SND_SOC_DAPM_OUTPUT("RX"),
};
enum {
@@ -421,6 +418,7 @@ static int hdmi_codec_startup(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
struct hdmi_codec_priv *hcp = snd_soc_dai_get_drvdata(dai);
+ bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
int ret = 0;
dev_dbg(dai->dev, "%s()\n", __func__);
@@ -439,7 +437,7 @@ static int hdmi_codec_startup(struct snd_pcm_substream *substream,
}
}
- if (hcp->hcd.ops->get_eld) {
+ if (tx && hcp->hcd.ops->get_eld) {
ret = hcp->hcd.ops->get_eld(dai->dev->parent, hcp->hcd.data,
hcp->eld, sizeof(hcp->eld));
@@ -519,13 +517,11 @@ static int hdmi_codec_hw_params(struct snd_pcm_substream *substream,
/* Select a channel allocation that matches with ELD and pcm channels */
idx = hdmi_codec_get_ch_alloc_table_idx(hcp, hp.cea.channels);
if (idx < 0) {
- dev_err(dai->dev, "Not able to map channels to speakers (%d)\n",
- idx);
hcp->chmap_idx = HDMI_CODEC_CHMAP_IDX_UNKNOWN;
- return idx;
+ } else {
+ hp.cea.channel_allocation = hdmi_codec_channel_alloc[idx].ca_id;
+ hcp->chmap_idx = hdmi_codec_channel_alloc[idx].ca_id;
}
- hp.cea.channel_allocation = hdmi_codec_channel_alloc[idx].ca_id;
- hcp->chmap_idx = hdmi_codec_channel_alloc[idx].ca_id;
hp.sample_width = params_width(params);
hp.sample_rate = params_rate(params);
@@ -694,9 +690,29 @@ static int hdmi_codec_pcm_new(struct snd_soc_pcm_runtime *rtd,
return snd_ctl_add(rtd->card->snd_card, kctl);
}
+static int hdmi_dai_probe(struct snd_soc_dai *dai)
+{
+ struct snd_soc_dapm_context *dapm;
+ struct snd_soc_dapm_route route[] = {
+ {
+ .sink = "TX",
+ .source = dai->driver->playback.stream_name,
+ },
+ {
+ .sink = "Capture",
+ .source = "RX",
+ },
+ };
+
+ dapm = snd_soc_component_get_dapm(dai->component);
+
+ return snd_soc_dapm_add_routes(dapm, route, ARRAY_SIZE(route));
+}
+
static const struct snd_soc_dai_driver hdmi_i2s_dai = {
.name = "i2s-hifi",
.id = DAI_ID_I2S,
+ .probe = hdmi_dai_probe,
.playback = {
.stream_name = "I2S Playback",
.channels_min = 2,
@@ -705,6 +721,14 @@ static const struct snd_soc_dai_driver hdmi_i2s_dai = {
.formats = I2S_FORMATS,
.sig_bits = 24,
},
+ .capture = {
+ .stream_name = "Capture",
+ .channels_min = 2,
+ .channels_max = 8,
+ .rates = HDMI_RATES,
+ .formats = I2S_FORMATS,
+ .sig_bits = 24,
+ },
.ops = &hdmi_dai_ops,
.pcm_new = hdmi_codec_pcm_new,
};
@@ -712,6 +736,7 @@ static const struct snd_soc_dai_driver hdmi_i2s_dai = {
static const struct snd_soc_dai_driver hdmi_spdif_dai = {
.name = "spdif-hifi",
.id = DAI_ID_SPDIF,
+ .probe = hdmi_dai_probe,
.playback = {
.stream_name = "SPDIF Playback",
.channels_min = 2,
@@ -719,6 +744,13 @@ static const struct snd_soc_dai_driver hdmi_spdif_dai = {
.rates = HDMI_RATES,
.formats = SPDIF_FORMATS,
},
+ .capture = {
+ .stream_name = "Capture",
+ .channels_min = 2,
+ .channels_max = 2,
+ .rates = HDMI_RATES,
+ .formats = SPDIF_FORMATS,
+ },
.ops = &hdmi_dai_ops,
.pcm_new = hdmi_codec_pcm_new,
};
@@ -739,8 +771,6 @@ static const struct snd_soc_codec_driver hdmi_codec = {
.component_driver = {
.dapm_widgets = hdmi_widgets,
.num_dapm_widgets = ARRAY_SIZE(hdmi_widgets),
- .dapm_routes = hdmi_routes,
- .num_dapm_routes = ARRAY_SIZE(hdmi_routes),
.of_xlate_dai_id = hdmi_of_xlate_dai_id,
},
};
diff --git a/sound/soc/codecs/rpmsg_ak4497.c b/sound/soc/codecs/rpmsg_ak4497.c
new file mode 100644
index 000000000000..ffc6792afec1
--- /dev/null
+++ b/sound/soc/codecs/rpmsg_ak4497.c
@@ -0,0 +1,1107 @@
+/*
+ * ak4497.c -- audio driver for AK4497
+ *
+ * Copyright (C) 2016 Asahi Kasei Microdevices Corporation
+ * Copyright (C) 2017, NXP
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/i2c.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/gpio.h>
+#include <sound/soc.h>
+#include <sound/soc-dapm.h>
+#include <sound/initval.h>
+#include <sound/tlv.h>
+#include <sound/pcm_params.h>
+#include <linux/of_gpio.h>
+#include <linux/regmap.h>
+#include <sound/pcm_params.h>
+#include <linux/pm_runtime.h>
+#include <linux/pm_runtime.h>
+#include <linux/regulator/consumer.h>
+#include "../fsl/fsl_rpmsg_i2s.h"
+
+#include "ak4497.h"
+
+//#define AK4497_DEBUG //used at debug mode
+#define AK4497_NUM_SUPPLIES 2
+static const char *ak4497_supply_names[AK4497_NUM_SUPPLIES] = {
+ "DVDD",
+ "AVDD",
+};
+
+/* AK4497 Codec Private Data */
+struct rpmsg_ak4497_priv {
+ struct regmap *regmap;
+ int fs1; /* Sampling Frequency */
+ int nBickFreq; /* 0: 48fs for 24bit, 1: 64fs or more for 32bit */
+ int nTdmSds;
+ int pdn_gpio;
+ int mute_gpio;
+ int fmt;
+ struct regulator_bulk_data supplies[AK4497_NUM_SUPPLIES];
+ struct fsl_rpmsg_i2s *rpmsg_i2s;
+ int audioindex;
+ struct platform_device *pdev;
+};
+
+/* ak4497 register cache & default register settings */
+static const struct reg_default ak4497_reg[] = {
+ { AK4497_00_CONTROL1, 0x0C},
+ { AK4497_01_CONTROL2, 0x22},
+ { AK4497_02_CONTROL3, 0x00},
+ { AK4497_03_LCHATT, 0xFF},
+ { AK4497_04_RCHATT, 0xFF},
+ { AK4497_05_CONTROL4, 0x00},
+ { AK4497_06_DSD1, 0x00},
+ { AK4497_07_CONTROL5, 0x00},
+ { AK4497_08_SOUNDCONTROL, 0x00},
+ { AK4497_09_DSD2, 0x00},
+ { AK4497_0A_CONTROL7, 0x04},
+ { AK4497_0B_CONTROL8, 0x00},
+ { AK4497_0C_RESERVED, 0x00},
+ { AK4497_0D_RESERVED, 0x00},
+ { AK4497_0E_RESERVED, 0x00},
+ { AK4497_0F_RESERVED, 0x00},
+ { AK4497_10_RESERVED, 0x00},
+ { AK4497_11_RESERVED, 0x00},
+ { AK4497_12_RESERVED, 0x00},
+ { AK4497_13_RESERVED, 0x00},
+ { AK4497_14_RESERVED, 0x00},
+ { AK4497_15_DFSREAD, 0x00},
+};
+
+/* Volume control:
+ * from -127 to 0 dB in 0.5 dB steps (mute instead of -127.5 dB)
+ */
+static DECLARE_TLV_DB_SCALE(latt_tlv, -12750, 50, 0);
+static DECLARE_TLV_DB_SCALE(ratt_tlv, -12750, 50, 0);
+
+static const char * const ak4497_ecs_select_texts[] = {"768kHz", "384kHz"};
+
+static const char * const ak4497_dem_select_texts[] = {
+ "44.1kHz", "OFF", "48kHz", "32kHz"};
+static const char * const ak4497_dzfm_select_texts[] = {
+ "Separated", "ANDed"};
+
+static const char * const ak4497_sellr_select_texts[] = {
+ "Rch", "Lch"};
+static const char * const ak4497_dckb_select_texts[] = {
+ "Falling", "Rising"};
+static const char * const ak4497_dcks_select_texts[] = {
+ "512fs", "768fs"};
+
+static const char * const ak4497_dsdd_select_texts[] = {
+ "Normal", "Volume Bypass"};
+
+static const char * const ak4497_sc_select_texts[] = {
+ "Setting 1", "Setting 2", "Setting 3"};
+static const char * const ak4497_dsdf_select_texts[] = {
+ "50kHz", "150kHz"};
+static const char * const ak4497_dsd_input_path_select[] = {
+ "16_17_19pin", "3_4_5pin"};
+static const char * const ak4497_ats_select_texts[] = {
+ "4080/fs", "2040/fs", "510/fs", "255/fs"};
+
+static const struct soc_enum ak4497_dac_enum[] = {
+ SOC_ENUM_SINGLE(AK4497_00_CONTROL1, 5,
+ ARRAY_SIZE(ak4497_ecs_select_texts),
+ ak4497_ecs_select_texts),
+ SOC_ENUM_SINGLE(AK4497_01_CONTROL2, 1,
+ ARRAY_SIZE(ak4497_dem_select_texts),
+ ak4497_dem_select_texts),
+ SOC_ENUM_SINGLE(AK4497_01_CONTROL2, 6,
+ ARRAY_SIZE(ak4497_dzfm_select_texts),
+ ak4497_dzfm_select_texts),
+ SOC_ENUM_SINGLE(AK4497_02_CONTROL3, 1,
+ ARRAY_SIZE(ak4497_sellr_select_texts),
+ ak4497_sellr_select_texts),
+ SOC_ENUM_SINGLE(AK4497_02_CONTROL3, 4,
+ ARRAY_SIZE(ak4497_dckb_select_texts),
+ ak4497_dckb_select_texts),
+ SOC_ENUM_SINGLE(AK4497_02_CONTROL3, 5,
+ ARRAY_SIZE(ak4497_dcks_select_texts),
+ ak4497_dcks_select_texts),
+ SOC_ENUM_SINGLE(AK4497_06_DSD1, 1,
+ ARRAY_SIZE(ak4497_dsdd_select_texts),
+ ak4497_dsdd_select_texts),
+ SOC_ENUM_SINGLE(AK4497_08_SOUNDCONTROL, 0,
+ ARRAY_SIZE(ak4497_sc_select_texts),
+ ak4497_sc_select_texts),
+ SOC_ENUM_SINGLE(AK4497_09_DSD2, 1,
+ ARRAY_SIZE(ak4497_dsdf_select_texts),
+ ak4497_dsdf_select_texts),
+ SOC_ENUM_SINGLE(AK4497_09_DSD2, 2,
+ ARRAY_SIZE(ak4497_dsd_input_path_select),
+ ak4497_dsd_input_path_select),
+ SOC_ENUM_SINGLE(AK4497_0B_CONTROL8, 6,
+ ARRAY_SIZE(ak4497_ats_select_texts),
+ ak4497_ats_select_texts),
+};
+
+static const char * const ak4497_dsdsel_select_texts[] = {
+ "64fs", "128fs", "256fs", "512fs"};
+static const char * const ak4497_bickfreq_select[] = {"48fs", "64fs"};
+
+static const char * const ak4497_tdm_sds_select[] = {
+ "L1R1", "TDM128_L1R1", "TDM128_L2R2",
+ "TDM256_L1R1", "TDM256_L2R2", "TDM256_L3R3", "TDM256_L4R4",
+ "TDM512_L1R1", "TDM512_L2R2", "TDM512_L3R3", "TDM512_L4R4",
+ "TDM512_L5R5", "TDM512_L6R6", "TDM512_L7R7", "TDM512_L8R8",
+};
+
+static const char * const ak4497_adfs_select[] = {
+ "Normal Speed Mode", "Double Speed Mode", "Quad Speed Mode",
+ "Quad Speed Mode", "Oct Speed Mode", "Hex Speed Mode", "Oct Speed Mode",
+ "Hex Speed Mode"
+};
+
+static const struct soc_enum ak4497_dac_enum2[] = {
+ SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(ak4497_dsdsel_select_texts),
+ ak4497_dsdsel_select_texts),
+ SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(ak4497_bickfreq_select),
+ ak4497_bickfreq_select),
+ SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(ak4497_tdm_sds_select),
+ ak4497_tdm_sds_select),
+ SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(ak4497_adfs_select),
+ ak4497_adfs_select)
+};
+
+static int ak4497_read(struct snd_soc_codec *codec, unsigned int reg,
+ unsigned int *val)
+{
+ int ret;
+
+ ret = snd_soc_component_read(&codec->component, reg, val);
+ if (ret < 0)
+ dev_err(codec->dev, "Register %u read failed, ret=%d.\n", reg, ret);
+
+ return ret;
+}
+
+static int ak4497_get_dsdsel(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+ unsigned int dsdsel0, dsdsel1;
+
+ ak4497_read(codec, AK4497_06_DSD1, &dsdsel0);
+ dsdsel0 &= AK4497_DSDSEL0;
+
+ ak4497_read(codec, AK4497_09_DSD2, &dsdsel1);
+ dsdsel1 &= AK4497_DSDSEL1;
+
+ ucontrol->value.enumerated.item[0] = ((dsdsel1 << 1) | dsdsel0);
+
+ return 0;
+}
+
+static int ak4497_set_dsdsel(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+ unsigned int dsdsel = ucontrol->value.enumerated.item[0];
+
+ switch (dsdsel) {
+ case 0: /* 2.8224MHz */
+ snd_soc_update_bits(codec, AK4497_06_DSD1, 0x01, 0x00);
+ snd_soc_update_bits(codec, AK4497_09_DSD2, 0x01, 0x00);
+ break;
+ case 1: /* 5.6448MHz */
+ snd_soc_update_bits(codec, AK4497_06_DSD1, 0x01, 0x01);
+ snd_soc_update_bits(codec, AK4497_09_DSD2, 0x01, 0x00);
+ break;
+ case 2: /* 11.2896MHz */
+ snd_soc_update_bits(codec, AK4497_06_DSD1, 0x01, 0x00);
+ snd_soc_update_bits(codec, AK4497_09_DSD2, 0x01, 0x01);
+ break;
+ case 3: /* 22.5792MHz */
+ snd_soc_update_bits(codec, AK4497_06_DSD1, 0x01, 0x01);
+ snd_soc_update_bits(codec, AK4497_09_DSD2, 0x01, 0x01);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int ak4497_get_bickfs(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+ struct rpmsg_ak4497_priv *ak4497 = snd_soc_codec_get_drvdata(codec);
+
+ ucontrol->value.enumerated.item[0] = ak4497->nBickFreq;
+
+ return 0;
+}
+
+static int ak4497_set_bickfs(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+ struct rpmsg_ak4497_priv *ak4497 = snd_soc_codec_get_drvdata(codec);
+
+ ak4497->nBickFreq = ucontrol->value.enumerated.item[0];
+
+ return 0;
+}
+
+static int ak4497_get_tdmsds(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+ struct rpmsg_ak4497_priv *ak4497 = snd_soc_codec_get_drvdata(codec);
+
+ ucontrol->value.enumerated.item[0] = ak4497->nTdmSds;
+
+ return 0;
+}
+
+static int ak4497_set_tdmsds(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+ struct rpmsg_ak4497_priv *ak4497 = snd_soc_codec_get_drvdata(codec);
+ int regA, regB;
+
+ ak4497->nTdmSds = ucontrol->value.enumerated.item[0];
+
+ if (ak4497->nTdmSds == 0)
+ regB = 0; /* SDS0 bit = 0 */
+ else
+ regB = (1 & (ak4497->nTdmSds - 1)); /* SDS0 bit = 1 */
+
+ switch (ak4497->nTdmSds) {
+ case 0:
+ regA = 0; /* Normal */
+ break;
+ case 1:
+ case 2:
+ regA = 4; /* TDM128 TDM1-0bits = 1 */
+ break;
+ case 3:
+ case 4:
+ regA = 8; /* TDM128 TDM1-0bits = 2 */
+ break;
+ case 5:
+ case 6:
+ regA = 9; /* TDM128 TDM1-0bits = 2 */
+ break;
+ case 7:
+ case 8:
+ regA = 0xC; /* TDM128 TDM1-0bits = 3 */
+ break;
+ case 9:
+ case 10:
+ regA = 0xD; /* TDM128 TDM1-0bits = 3 */
+ break;
+ case 11:
+ case 12:
+ regA = 0xE; /* TDM128 TDM1-0bits = 3 */
+ break;
+ case 13:
+ case 14:
+ regA = 0xF; /* TDM128 TDM1-0bits = 3 */
+ break;
+ default:
+ regA = 0;
+ regB = 0;
+ break;
+ }
+
+ regA <<= 4;
+ regB <<= 4;
+
+ snd_soc_update_bits(codec, AK4497_0A_CONTROL7, 0xF0, regA);
+ snd_soc_update_bits(codec, AK4497_0B_CONTROL8, 0x10, regB);
+
+ return 0;
+}
+
+static int ak4497_get_adfs(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+ unsigned int nADFSbit;
+
+ ak4497_read(codec, AK4497_15_DFSREAD, &nADFSbit);
+ nADFSbit &= 0x7;
+
+ ucontrol->value.enumerated.item[0] = nADFSbit;
+
+ return 0;
+}
+
+static int ak4497_set_adfs(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ pr_debug("AK4497 : ADFS is read only\n");
+
+ return 0;
+}
+
+static const char * const gain_control_texts[] = {
+ "2.8_2.8Vpp", "2.8_2.5Vpp", "2.5_2.5Vpp", "3.75_3.75Vpp", "3.75_2.5Vpp"
+};
+
+static const unsigned int gain_control_values[] = {
+ 0, 1, 2, 4, 5
+};
+
+static const struct soc_enum ak4497_gain_control_enum =
+ SOC_VALUE_ENUM_SINGLE(AK4497_07_CONTROL5, 1, 7,
+ ARRAY_SIZE(gain_control_texts),
+ gain_control_texts,
+ gain_control_values);
+
+#ifdef AK4497_DEBUG
+
+static const char * const test_reg_select[] = {
+ "read AK4497 Reg 00:0B",
+ "read AK4497 Reg 15"
+};
+
+static const struct soc_enum ak4497_enum[] = {
+ SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(test_reg_select), test_reg_select),
+};
+
+static int nTestRegNo;
+
+static int get_test_reg(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ /* Get the current output routing */
+ ucontrol->value.enumerated.item[0] = nTestRegNo;
+
+ return 0;
+}
+
+static int set_test_reg(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+ u32 currMode = ucontrol->value.enumerated.item[0];
+ int i, regs, rege;
+ unsigned int value;
+
+ nTestRegNo = currMode;
+
+ if (nTestRegNo == 0) {
+ regs = 0x00;
+ rege = 0x0B;
+ } else {
+ regs = 0x15;
+ rege = 0x15;
+ }
+
+ for (i = regs; i <= rege; i++) {
+ ak4497_read(codec, i, &value);
+ pr_debug("***AK4497 Addr,Reg=(%x, %x)\n", i, value);
+ }
+
+ return 0;
+}
+#endif
+
+static const struct snd_kcontrol_new ak4497_snd_controls[] = {
+ SOC_SINGLE_TLV("AK4497 Lch Digital Volume",
+ AK4497_03_LCHATT, 0, 0xFF, 0, latt_tlv),
+ SOC_SINGLE_TLV("AK4497 Rch Digital Volume",
+ AK4497_04_RCHATT, 0, 0xFF, 0, ratt_tlv),
+
+ SOC_ENUM("AK4497 EX DF I/F clock", ak4497_dac_enum[0]),
+ SOC_ENUM("AK4497 De-emphasis Response", ak4497_dac_enum[1]),
+ SOC_ENUM("AK4497 Data Zero Detect Mode", ak4497_dac_enum[2]),
+ SOC_ENUM("AK4497 Data Selection at Mono Mode", ak4497_dac_enum[3]),
+
+ SOC_ENUM("AK4497 Polarity of DCLK", ak4497_dac_enum[4]),
+ SOC_ENUM("AK4497 DCKL Frequency", ak4497_dac_enum[5]),
+
+ SOC_ENUM("AK4497 DDSD Play Back Path", ak4497_dac_enum[6]),
+ SOC_ENUM("AK4497 Sound control", ak4497_dac_enum[7]),
+ SOC_ENUM("AK4497 Cut Off of DSD Filter", ak4497_dac_enum[8]),
+
+ SOC_ENUM_EXT("AK4497 DSD Data Stream", ak4497_dac_enum2[0],
+ ak4497_get_dsdsel, ak4497_set_dsdsel),
+ SOC_ENUM_EXT("AK4497 BICK Frequency Select", ak4497_dac_enum2[1],
+ ak4497_get_bickfs, ak4497_set_bickfs),
+ SOC_ENUM_EXT("AK4497 TDM Data Select", ak4497_dac_enum2[2],
+ ak4497_get_tdmsds, ak4497_set_tdmsds),
+
+ SOC_SINGLE("AK4497 External Digital Filter", AK4497_00_CONTROL1,
+ 6, 1, 0),
+ SOC_SINGLE("AK4497 MCLK Frequency Auto Setting", AK4497_00_CONTROL1,
+ 7, 1, 0),
+ SOC_SINGLE("AK4497 MCLK FS Auto Detect", AK4497_00_CONTROL1, 4, 1, 0),
+
+ SOC_SINGLE("AK4497 Soft Mute Control", AK4497_01_CONTROL2, 0, 1, 0),
+ SOC_SINGLE("AK4497 Short delay filter", AK4497_01_CONTROL2, 5, 1, 0),
+ SOC_SINGLE("AK4497 Data Zero Detect Enable", AK4497_01_CONTROL2,
+ 7, 1, 0),
+ SOC_SINGLE("AK4497 Slow Roll-off Filter", AK4497_02_CONTROL3, 0, 1, 0),
+ SOC_SINGLE("AK4497 Invering Enable of DZF", AK4497_02_CONTROL3,
+ 4, 1, 0),
+ SOC_SINGLE("AK4497 Mono Mode", AK4497_02_CONTROL3, 3, 1, 0),
+ SOC_SINGLE("AK4497 Super Slow Roll-off Filter", AK4497_05_CONTROL4,
+ 0, 1, 0),
+ SOC_SINGLE("AK4497 AOUTR Phase Inverting", AK4497_05_CONTROL4,
+ 6, 1, 0),
+ SOC_SINGLE("AK4497 AOUTL Phase Inverting", AK4497_05_CONTROL4,
+ 7, 1, 0),
+ SOC_SINGLE("AK4497 DSD Mute Release", AK4497_06_DSD1, 3, 1, 0),
+ SOC_SINGLE("AK4497 DSD Mute Control Hold", AK4497_06_DSD1, 4, 1, 0),
+ SOC_SINGLE("AK4497 DSDR is detected", AK4497_06_DSD1, 5, 1, 0),
+ SOC_SINGLE("AK4497 DSDL is detected", AK4497_06_DSD1, 6, 1, 0),
+ SOC_SINGLE("AK4497 DSD Data Mute", AK4497_06_DSD1, 7, 1, 0),
+ SOC_SINGLE("AK4497 Synchronization Control", AK4497_07_CONTROL5,
+ 0, 1, 0),
+
+ SOC_ENUM("AK4497 Output Level", ak4497_gain_control_enum),
+ SOC_SINGLE("AK4497 High Sonud Quality Mode", AK4497_08_SOUNDCONTROL,
+ 2, 1, 0),
+ SOC_SINGLE("AK4497 Heavy Load Mode", AK4497_08_SOUNDCONTROL, 3, 1, 0),
+ SOC_ENUM("AK4497 DSD Data Input Pin", ak4497_dac_enum[9]),
+ SOC_SINGLE("AK4497 Daisy Chain", AK4497_0B_CONTROL8, 1, 1, 0),
+ SOC_ENUM("AK4497 ATT Transit Time", ak4497_dac_enum[10]),
+
+ SOC_ENUM_EXT("AK4497 Read FS Auto Detect Mode", ak4497_dac_enum2[3],
+ ak4497_get_adfs, ak4497_set_adfs),
+
+#ifdef AK4497_DEBUG
+ SOC_ENUM_EXT("Reg Read", ak4497_enum[0], get_test_reg, set_test_reg),
+#endif
+
+};
+
+static const char * const ak4497_dac_enable_texts[] = {"Off", "On"};
+
+static SOC_ENUM_SINGLE_VIRT_DECL(ak4497_dac_enable_enum,
+ ak4497_dac_enable_texts);
+
+static const struct snd_kcontrol_new ak4497_dac_enable_control =
+ SOC_DAPM_ENUM("DAC Switch", ak4497_dac_enable_enum);
+
+/* ak4497 dapm widgets */
+static const struct snd_soc_dapm_widget ak4497_dapm_widgets[] = {
+ SND_SOC_DAPM_AIF_IN("AK4497 SDTI", "Playback", 0, SND_SOC_NOPM, 0, 0),
+
+ SND_SOC_DAPM_DAC("AK4497 DAC", NULL, AK4497_0A_CONTROL7, 2, 0),
+
+ SND_SOC_DAPM_MUX("AK4497 DAC Enable", SND_SOC_NOPM,
+ 0, 0, &ak4497_dac_enable_control),
+
+ SND_SOC_DAPM_OUTPUT("AK4497 AOUT"),
+
+};
+
+static const struct snd_soc_dapm_route ak4497_intercon[] = {
+ {"AK4497 DAC", NULL, "AK4497 SDTI"},
+ {"AK4497 DAC Enable", "On", "AK4497 DAC"},
+ {"AK4497 AOUT", NULL, "AK4497 DAC Enable"},
+};
+
+static int ak4497_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params,
+ struct snd_soc_dai *dai)
+{
+ struct snd_soc_codec *codec = dai->codec;
+ struct rpmsg_ak4497_priv *ak4497 = snd_soc_codec_get_drvdata(codec);
+ snd_pcm_format_t pcm_format = params_format(params);
+
+ unsigned int dfs, dfs2, dsdsel0, dsdsel1, format;
+ int nfs1;
+ bool is_dsd = false;
+ int dsd_bclk;
+
+ if (pcm_format == SNDRV_PCM_FORMAT_DSD_U8 ||
+ pcm_format == SNDRV_PCM_FORMAT_DSD_U16_LE ||
+ pcm_format == SNDRV_PCM_FORMAT_DSD_U16_BE ||
+ pcm_format == SNDRV_PCM_FORMAT_DSD_U32_LE ||
+ pcm_format == SNDRV_PCM_FORMAT_DSD_U32_BE)
+ is_dsd = true;
+
+ nfs1 = params_rate(params);
+ ak4497->fs1 = nfs1;
+
+ ak4497_read(codec, AK4497_01_CONTROL2, &dfs);
+ dfs &= ~AK4497_DFS;
+
+ ak4497_read(codec, AK4497_05_CONTROL4, &dfs2);
+ dfs2 &= ~AK4497_DFS2;
+
+ ak4497_read(codec, AK4497_06_DSD1, &dsdsel0);
+ dsdsel0 &= ~AK4497_DSDSEL0;
+
+ ak4497_read(codec, AK4497_09_DSD2, &dsdsel1);
+ dsdsel1 &= ~AK4497_DSDSEL1;
+
+ if (!is_dsd) {
+ switch (nfs1) {
+ case 8000:
+ case 11025:
+ case 16000:
+ case 22050:
+ case 32000:
+ case 44100:
+ case 48000:
+ dfs |= AK4497_DFS_48KHZ;
+ dfs2 |= AK4497_DFS2_48KHZ;
+ break;
+ case 88200:
+ case 96000:
+ dfs |= AK4497_DFS_96KHZ;
+ dfs2 |= AK4497_DFS2_48KHZ;
+ break;
+ case 176400:
+ case 192000:
+ dfs |= AK4497_DFS_192KHZ;
+ dfs2 |= AK4497_DFS2_48KHZ;
+ break;
+ case 352800:
+ case 384000:
+ dfs |= AK4497_DFS_384KHZ;
+ dfs2 |= AK4497_DFS2_384KHZ;
+ break;
+ case 705600:
+ case 768000:
+ dfs |= AK4497_DFS_768KHZ;
+ dfs2 |= AK4497_DFS2_384KHZ;
+ break;
+ default:
+ return -EINVAL;
+ }
+ } else {
+ dsd_bclk = params_rate(params) *
+ params_physical_width(params);
+
+ switch (dsd_bclk) {
+ case 2822400:
+ dsdsel0 |= AK4497_DSDSEL0_2MHZ;
+ dsdsel1 |= AK4497_DSDSEL1_2MHZ;
+ break;
+ case 5644800:
+ dsdsel0 |= AK4497_DSDSEL0_5MHZ;
+ dsdsel1 |= AK4497_DSDSEL1_5MHZ;
+ break;
+ case 11289600:
+ dsdsel0 |= AK4497_DSDSEL0_11MHZ;
+ dsdsel1 |= AK4497_DSDSEL1_11MHZ;
+ break;
+ case 22579200:
+ dsdsel0 |= AK4497_DSDSEL0_22MHZ;
+ dsdsel1 |= AK4497_DSDSEL1_22MHZ;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ snd_soc_write(codec, AK4497_06_DSD1, dsdsel0);
+ snd_soc_write(codec, AK4497_09_DSD2, dsdsel1);
+ }
+
+ snd_soc_write(codec, AK4497_01_CONTROL2, dfs);
+ snd_soc_write(codec, AK4497_05_CONTROL4, dfs2);
+
+ ak4497_read(codec, AK4497_00_CONTROL1, &format);
+ format &= ~AK4497_DIF;
+
+ switch (params_format(params)) {
+ case SNDRV_PCM_FORMAT_S16_LE:
+ if (ak4497->fmt == SND_SOC_DAIFMT_I2S)
+ format |= AK4497_DIF_24BIT_I2S;
+ else
+ format |= AK4497_DIF_16BIT_LSB;
+ break;
+ case SNDRV_PCM_FORMAT_S24_LE:
+ case SNDRV_PCM_FORMAT_S32_LE:
+ if (ak4497->fmt == SND_SOC_DAIFMT_I2S)
+ format |= AK4497_DIF_32BIT_I2S;
+ else if (ak4497->fmt == SND_SOC_DAIFMT_LEFT_J)
+ format |= AK4497_DIF_32BIT_MSB;
+ else if (ak4497->fmt == SND_SOC_DAIFMT_RIGHT_J)
+ format |= AK4497_DIF_32BIT_LSB;
+ else
+ return -EINVAL;
+ break;
+ case SNDRV_PCM_FORMAT_DSD_U8:
+ case SNDRV_PCM_FORMAT_DSD_U16_LE:
+ case SNDRV_PCM_FORMAT_DSD_U32_LE:
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ snd_soc_write(codec, AK4497_00_CONTROL1, format);
+
+ return 0;
+}
+
+static int ak4497_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id,
+ unsigned int freq, int dir)
+{
+ return 0;
+}
+
+static int ak4497_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
+{
+ struct snd_soc_codec *codec = dai->codec;
+ struct rpmsg_ak4497_priv *ak4497 = snd_soc_codec_get_drvdata(codec);
+ unsigned int format, format2;
+
+ /* set master/slave audio interface */
+ ak4497_read(codec, AK4497_00_CONTROL1, &format);
+ format &= ~AK4497_DIF;
+
+ ak4497_read(codec, AK4497_02_CONTROL3, &format2);
+ format2 &= ~AK4497_DIF_DSD;
+
+ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+ case SND_SOC_DAIFMT_CBS_CFS:
+ break;
+ case SND_SOC_DAIFMT_CBM_CFM:
+ case SND_SOC_DAIFMT_CBS_CFM:
+ case SND_SOC_DAIFMT_CBM_CFS:
+ default:
+ dev_err(codec->dev, "Clock mode unsupported");
+ return -EINVAL;
+ }
+
+ switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+ case SND_SOC_DAIFMT_I2S:
+ ak4497->fmt = SND_SOC_DAIFMT_I2S;
+ break;
+ case SND_SOC_DAIFMT_LEFT_J:
+ ak4497->fmt = SND_SOC_DAIFMT_LEFT_J;
+ break;
+ case SND_SOC_DAIFMT_RIGHT_J:
+ ak4497->fmt = SND_SOC_DAIFMT_RIGHT_J;
+ break;
+ case SND_SOC_DAIFMT_PDM:
+ format2 |= AK4497_DIF_DSD_MODE;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ /* set format */
+ snd_soc_write(codec, AK4497_00_CONTROL1, format);
+ snd_soc_write(codec, AK4497_02_CONTROL3, format2);
+
+ return 0;
+}
+
+static bool ak4497_volatile(struct device *dev, unsigned int reg)
+{
+ int ret;
+
+#ifdef AK4497_DEBUG
+ ret = 1;
+#else
+ switch (reg) {
+ case AK4497_15_DFSREAD:
+ ret = 1;
+ break;
+ default:
+ ret = 0;
+ break;
+ }
+#endif
+ return ret;
+}
+
+static int ak4497_set_bias_level(struct snd_soc_codec *codec,
+ enum snd_soc_bias_level level)
+{
+ switch (level) {
+ case SND_SOC_BIAS_ON:
+ case SND_SOC_BIAS_PREPARE:
+ case SND_SOC_BIAS_STANDBY:
+ /* RSTN bit = 1 */
+ snd_soc_update_bits(codec, AK4497_00_CONTROL1, 0x01, 0x01);
+ break;
+ case SND_SOC_BIAS_OFF:
+ /* RSTN bit = 0 */
+ snd_soc_update_bits(codec, AK4497_00_CONTROL1, 0x01, 0x00);
+ break;
+ }
+
+ return 0;
+}
+
+#define AK4497_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
+ SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |\
+ SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |\
+ SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 |\
+ SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 |\
+ SNDRV_PCM_RATE_192000)
+
+#define AK4497_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE |\
+ SNDRV_PCM_FMTBIT_S32_LE |\
+ SNDRV_PCM_FMTBIT_DSD_U8 |\
+ SNDRV_PCM_FMTBIT_DSD_U16_LE |\
+ SNDRV_PCM_FMTBIT_DSD_U32_LE)
+
+static const unsigned int ak4497_rates[] = {
+ 8000, 11025, 16000, 22050,
+ 32000, 44100, 48000, 88200,
+ 96000, 176400, 192000, 352800,
+ 384000, 705600, 768000, 1411200,
+ 2822400,
+};
+
+static const struct snd_pcm_hw_constraint_list ak4497_rate_constraints = {
+ .count = ARRAY_SIZE(ak4497_rates),
+ .list = ak4497_rates,
+};
+
+static int ak4497_startup(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai) {
+ int ret;
+
+ ret = snd_pcm_hw_constraint_list(substream->runtime, 0,
+ SNDRV_PCM_HW_PARAM_RATE, &ak4497_rate_constraints);
+
+ return ret;
+}
+
+static struct snd_soc_dai_ops ak4497_dai_ops = {
+ .startup = ak4497_startup,
+ .hw_params = ak4497_hw_params,
+ .set_sysclk = ak4497_set_dai_sysclk,
+ .set_fmt = ak4497_set_dai_fmt,
+};
+
+struct snd_soc_dai_driver rpmsg_ak4497_dai[] = {
+ {
+ .name = "rpmsg-ak4497-aif",
+ .playback = {
+ .stream_name = "Playback",
+ .channels_min = 1,
+ .channels_max = 2,
+ .rates = SNDRV_PCM_RATE_KNOT,
+ .formats = AK4497_FORMATS,
+ },
+ .ops = &ak4497_dai_ops,
+ },
+};
+
+static int ak4497_init_reg(struct snd_soc_codec *codec)
+{
+ struct rpmsg_ak4497_priv *ak4497 = snd_soc_codec_get_drvdata(codec);
+ int ret = 0;
+
+ /* External Mute ON */
+ if (gpio_is_valid(ak4497->mute_gpio))
+ gpio_set_value_cansleep(ak4497->mute_gpio, 1);
+
+ if (gpio_is_valid(ak4497->pdn_gpio)) {
+ gpio_set_value_cansleep(ak4497->pdn_gpio, 0);
+ usleep_range(1000, 2000);
+ gpio_set_value_cansleep(ak4497->pdn_gpio, 1);
+ usleep_range(1000, 2000);
+ }
+
+ /* ak4497_set_bias_level(codec, SND_SOC_BIAS_STANDBY); */
+
+ /* SYNCE bit = 1 */
+ ret = snd_soc_update_bits(codec, AK4497_07_CONTROL5, 0x01, 0x01);
+ if (ret)
+ return ret;
+
+ /* HLOAD bit = 1, SC2 bit = 1 */
+ ret = snd_soc_update_bits(codec, AK4497_08_SOUNDCONTROL, 0x0F, 0x0C);
+ if (ret)
+ return ret;
+
+ return ret;
+}
+
+static int ak4497_parse_dt(struct rpmsg_ak4497_priv *ak4497)
+{
+ struct device *dev;
+ struct device_node *np;
+
+ dev = &(ak4497->pdev->dev);
+ np = dev->of_node;
+
+ ak4497->pdn_gpio = -1;
+ ak4497->mute_gpio = -1;
+
+ if (!np)
+ return 0;
+
+ ak4497->pdn_gpio = of_get_named_gpio(np, "ak4497,pdn-gpio", 0);
+ if (ak4497->pdn_gpio < 0)
+ ak4497->pdn_gpio = -1;
+
+ if (!gpio_is_valid(ak4497->pdn_gpio)) {
+ dev_err(dev, "ak4497 pdn pin(%u) is invalid\n",
+ ak4497->pdn_gpio);
+ ak4497->pdn_gpio = -1;
+ }
+
+ ak4497->mute_gpio = of_get_named_gpio(np, "ak4497,mute-gpio", 0);
+ if (ak4497->mute_gpio < 0)
+ ak4497->mute_gpio = -1;
+
+ if (!gpio_is_valid(ak4497->mute_gpio)) {
+ dev_err(dev, "ak4497 mute_gpio(%u) is invalid\n",
+ ak4497->mute_gpio);
+ ak4497->mute_gpio = -1;
+ }
+
+ return 0;
+}
+
+static int ak4497_probe(struct snd_soc_codec *codec)
+{
+ struct rpmsg_ak4497_priv *ak4497 = snd_soc_codec_get_drvdata(codec);
+ int ret = 0;
+
+ ret = ak4497_parse_dt(ak4497);
+ if (ret)
+ return ret;
+
+ if (gpio_is_valid(ak4497->pdn_gpio)) {
+ ret = gpio_request(ak4497->pdn_gpio, "ak4497 pdn");
+ if (ret)
+ return ret;
+ gpio_direction_output(ak4497->pdn_gpio, 0);
+ }
+ if (gpio_is_valid(ak4497->mute_gpio)) {
+ ret = gpio_request(ak4497->mute_gpio, "ak4497 mute");
+ if (ret)
+ return ret;
+ gpio_direction_output(ak4497->mute_gpio, 0);
+ }
+
+ ret = ak4497_init_reg(codec);
+ if (ret)
+ return ret;
+
+ ak4497->fs1 = 48000;
+ ak4497->nBickFreq = 1;
+ ak4497->nTdmSds = 0;
+
+ return ret;
+}
+
+static int ak4497_remove(struct snd_soc_codec *codec)
+{
+ struct rpmsg_ak4497_priv *ak4497 = snd_soc_codec_get_drvdata(codec);
+
+ ak4497_set_bias_level(codec, SND_SOC_BIAS_OFF);
+ if (gpio_is_valid(ak4497->pdn_gpio)) {
+ gpio_set_value_cansleep(ak4497->pdn_gpio, 0);
+ gpio_free(ak4497->pdn_gpio);
+ }
+ if (gpio_is_valid(ak4497->mute_gpio))
+ gpio_free(ak4497->mute_gpio);
+
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int ak4497_runtime_suspend(struct device *dev)
+{
+ struct rpmsg_ak4497_priv *ak4497 = dev_get_drvdata(dev);
+
+ regcache_cache_only(ak4497->regmap, true);
+
+ if (gpio_is_valid(ak4497->pdn_gpio)) {
+ gpio_set_value_cansleep(ak4497->pdn_gpio, 0);
+ usleep_range(1000, 2000);
+ }
+
+ if (gpio_is_valid(ak4497->mute_gpio))
+ gpio_free(ak4497->mute_gpio);
+
+ return 0;
+}
+
+static int ak4497_runtime_resume(struct device *dev)
+{
+ struct rpmsg_ak4497_priv *ak4497 = dev_get_drvdata(dev);
+
+ /* External Mute ON */
+ if (gpio_is_valid(ak4497->mute_gpio))
+ gpio_set_value_cansleep(ak4497->mute_gpio, 1);
+
+ if (gpio_is_valid(ak4497->pdn_gpio)) {
+ gpio_set_value_cansleep(ak4497->pdn_gpio, 1);
+ usleep_range(1000, 2000);
+ }
+
+ regcache_cache_only(ak4497->regmap, false);
+ regcache_mark_dirty(ak4497->regmap);
+
+ return regcache_sync(ak4497->regmap);
+}
+#endif /* CONFIG_PM */
+
+static const struct dev_pm_ops ak4497_pm = {
+ SET_RUNTIME_PM_OPS(ak4497_runtime_suspend, ak4497_runtime_resume, NULL)
+ SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, pm_runtime_force_resume)
+};
+
+struct snd_soc_codec_driver rpmsg_codec_dev_ak4497 = {
+ .probe = ak4497_probe,
+ .remove = ak4497_remove,
+
+ .idle_bias_off = true,
+ .set_bias_level = ak4497_set_bias_level,
+
+ .component_driver = {
+ .controls = ak4497_snd_controls,
+ .num_controls = ARRAY_SIZE(ak4497_snd_controls),
+ .dapm_widgets = ak4497_dapm_widgets,
+ .num_dapm_widgets = ARRAY_SIZE(ak4497_dapm_widgets),
+ .dapm_routes = ak4497_intercon,
+ .num_dapm_routes = ARRAY_SIZE(ak4497_intercon),
+ },
+};
+
+static int rpmsg_ak4497_read(void *context, unsigned int reg, unsigned int *val)
+{
+ struct rpmsg_ak4497_priv *ak4497 = context;
+ struct fsl_rpmsg_i2s *rpmsg_i2s = ak4497->rpmsg_i2s;
+ struct i2s_info *i2s_info = &rpmsg_i2s->i2s_info;
+ struct i2s_rpmsg_s *rpmsg = &i2s_info->rpmsg[GET_CODEC_VALUE].send_msg;
+ int err, reg_val;
+
+ mutex_lock(&i2s_info->i2c_lock);
+ rpmsg->param.audioindex = ak4497->audioindex;
+ rpmsg->param.buffer_addr = reg;
+ rpmsg->header.cmd = GET_CODEC_VALUE;
+ err = i2s_info->send_message(&i2s_info->rpmsg[GET_CODEC_VALUE], i2s_info);
+ reg_val = i2s_info->rpmsg[GET_CODEC_VALUE].recv_msg.param.reg_data;
+ mutex_unlock(&i2s_info->i2c_lock);
+ if (err)
+ return -EIO;
+
+ *val = reg_val;
+ return 0;
+}
+
+static int rpmsg_ak4497_write(void *context, unsigned int reg, unsigned int val)
+{
+ struct rpmsg_ak4497_priv *ak4497 = context;
+ struct fsl_rpmsg_i2s *rpmsg_i2s = ak4497->rpmsg_i2s;
+ struct i2s_info *i2s_info = &rpmsg_i2s->i2s_info;
+ struct i2s_rpmsg_s *rpmsg = &i2s_info->rpmsg[SET_CODEC_VALUE].send_msg;
+ int err;
+
+ mutex_lock(&i2s_info->i2c_lock);
+ rpmsg->param.audioindex = ak4497->audioindex;
+ rpmsg->param.buffer_addr = reg;
+ rpmsg->param.buffer_size = val;
+ rpmsg->header.cmd = SET_CODEC_VALUE;
+ err = i2s_info->send_message(&i2s_info->rpmsg[SET_CODEC_VALUE], i2s_info);
+ mutex_unlock(&i2s_info->i2c_lock);
+ if (err)
+ return -EIO;
+
+ return 0;
+}
+
+static const struct regmap_config rpmsg_ak4497_regmap = {
+ .reg_bits = 8,
+ .val_bits = 8,
+
+ .max_register = AK4497_MAX_REGISTERS,
+ .volatile_reg = ak4497_volatile,
+
+ .reg_defaults = ak4497_reg,
+ .num_reg_defaults = ARRAY_SIZE(ak4497_reg),
+ .cache_type = REGCACHE_RBTREE,
+
+ .reg_read = rpmsg_ak4497_read,
+ .reg_write = rpmsg_ak4497_write,
+};
+
+static int rpmsg_ak4497_codec_probe(struct platform_device *pdev)
+{
+ struct fsl_rpmsg_i2s *rpmsg_i2s = dev_get_drvdata(pdev->dev.parent);
+ struct fsl_rpmsg_codec *pdata = pdev->dev.platform_data;
+ struct rpmsg_ak4497_priv *ak4497;
+ int ret = 0;
+ int i;
+
+ ak4497 = devm_kzalloc(&pdev->dev,
+ sizeof(struct rpmsg_ak4497_priv), GFP_KERNEL);
+ if (ak4497 == NULL)
+ return -ENOMEM;
+
+ ak4497->rpmsg_i2s = rpmsg_i2s;
+ ak4497->pdev = pdev;
+
+ ak4497->regmap = devm_regmap_init(&pdev->dev, NULL, ak4497, &rpmsg_ak4497_regmap);
+ if (IS_ERR(ak4497->regmap))
+ return PTR_ERR(ak4497->regmap);
+
+ if (pdata)
+ ak4497->audioindex = pdata->audioindex;
+
+ dev_set_drvdata(&pdev->dev, ak4497);
+
+ for (i = 0; i < ARRAY_SIZE(ak4497->supplies); i++)
+ ak4497->supplies[i].supply = ak4497_supply_names[i];
+
+ ret = devm_regulator_bulk_get(&pdev->dev, ARRAY_SIZE(ak4497->supplies),
+ ak4497->supplies);
+ if (ret != 0) {
+ dev_err(&pdev->dev, "Failed to request supplies: %d\n", ret);
+ return ret;
+ }
+
+ ret = regulator_bulk_enable(ARRAY_SIZE(ak4497->supplies),
+ ak4497->supplies);
+ if (ret != 0) {
+ dev_err(&pdev->dev, "Failed to enable supplies: %d\n", ret);
+ return ret;
+ }
+
+ ret = snd_soc_register_codec(&pdev->dev, &rpmsg_codec_dev_ak4497,
+ &rpmsg_ak4497_dai[0], ARRAY_SIZE(rpmsg_ak4497_dai));
+ if (ret < 0)
+ return ret;
+
+ pm_runtime_enable(&pdev->dev);
+
+ return 0;
+}
+
+static int rpmsg_ak4497_codec_remove(struct platform_device *pdev)
+{
+ snd_soc_unregister_codec(&pdev->dev);
+ pm_runtime_disable(&pdev->dev);
+
+ return 0;
+}
+
+static struct platform_driver rpmsg_ak4497_codec_driver = {
+ .driver = {
+ .name = RPMSG_CODEC_DRV_NAME_AK4497,
+ .pm = &ak4497_pm,
+ },
+ .probe = rpmsg_ak4497_codec_probe,
+ .remove = rpmsg_ak4497_codec_remove,
+};
+
+module_platform_driver(rpmsg_ak4497_codec_driver);
+
+MODULE_AUTHOR("Junichi Wakasugi <wakasugi.jb@om.asahi-kasei.co.jp>");
+MODULE_AUTHOR("Daniel Baluta <daniel.baluta@nxp.com>");
+MODULE_DESCRIPTION("ASoC ak4497 codec driver");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/rpmsg_cs42xx8.c b/sound/soc/codecs/rpmsg_cs42xx8.c
new file mode 100644
index 000000000000..38c3b1a86a93
--- /dev/null
+++ b/sound/soc/codecs/rpmsg_cs42xx8.c
@@ -0,0 +1,753 @@
+/*
+ * Cirrus Logic CS42448/CS42888 Audio CODEC Digital Audio Interface (DAI) driver
+ *
+ * Copyright (C) 2014-2016 Freescale Semiconductor, Inc.
+ *
+ * Author: Nicolin Chen <Guangyu.Chen@freescale.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.
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/of_gpio.h>
+#include <linux/pm_runtime.h>
+#include <linux/regulator/consumer.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/tlv.h>
+
+#include "rpmsg_cs42xx8.h"
+#include "../fsl/fsl_rpmsg_i2s.h"
+
+#define CS42XX8_NUM_SUPPLIES 4
+static const char *const cs42xx8_supply_names[CS42XX8_NUM_SUPPLIES] = {
+ "VA",
+ "VD",
+ "VLS",
+ "VLC",
+};
+
+#define CS42XX8_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \
+ SNDRV_PCM_FMTBIT_S20_3LE | \
+ SNDRV_PCM_FMTBIT_S24_LE)
+
+/* codec private data */
+struct rpmsg_cs42xx8_priv {
+ struct regulator_bulk_data supplies[CS42XX8_NUM_SUPPLIES];
+ struct cs42xx8_driver_data *drvdata;
+ struct regmap *regmap;
+ struct clk *clk;
+
+ bool slave_mode[2];
+ unsigned long sysclk;
+ u32 tx_channels;
+ int rate[2];
+ int reset_gpio;
+ int audioindex;
+ struct fsl_rpmsg_i2s *rpmsg_i2s;
+};
+
+/* -127.5dB to 0dB with step of 0.5dB */
+static const DECLARE_TLV_DB_SCALE(dac_tlv, -12750, 50, 1);
+/* -64dB to 24dB with step of 0.5dB */
+static const DECLARE_TLV_DB_SCALE(adc_tlv, -6400, 50, 0);
+
+static const char *const cs42xx8_adc_single[] = { "Differential", "Single-Ended" };
+static const char *const cs42xx8_szc[] = { "Immediate Change", "Zero Cross",
+ "Soft Ramp", "Soft Ramp on Zero Cross" };
+
+static const struct soc_enum adc1_single_enum =
+ SOC_ENUM_SINGLE(CS42XX8_ADCCTL, 4, 2, cs42xx8_adc_single);
+static const struct soc_enum adc2_single_enum =
+ SOC_ENUM_SINGLE(CS42XX8_ADCCTL, 3, 2, cs42xx8_adc_single);
+static const struct soc_enum adc3_single_enum =
+ SOC_ENUM_SINGLE(CS42XX8_ADCCTL, 2, 2, cs42xx8_adc_single);
+static const struct soc_enum dac_szc_enum =
+ SOC_ENUM_SINGLE(CS42XX8_TXCTL, 5, 4, cs42xx8_szc);
+static const struct soc_enum adc_szc_enum =
+ SOC_ENUM_SINGLE(CS42XX8_TXCTL, 0, 4, cs42xx8_szc);
+
+static const struct snd_kcontrol_new cs42xx8_snd_controls[] = {
+ SOC_DOUBLE_R_TLV("DAC1 Playback Volume", CS42XX8_VOLAOUT1,
+ CS42XX8_VOLAOUT2, 0, 0xff, 1, dac_tlv),
+ SOC_DOUBLE_R_TLV("DAC2 Playback Volume", CS42XX8_VOLAOUT3,
+ CS42XX8_VOLAOUT4, 0, 0xff, 1, dac_tlv),
+ SOC_DOUBLE_R_TLV("DAC3 Playback Volume", CS42XX8_VOLAOUT5,
+ CS42XX8_VOLAOUT6, 0, 0xff, 1, dac_tlv),
+ SOC_DOUBLE_R_TLV("DAC4 Playback Volume", CS42XX8_VOLAOUT7,
+ CS42XX8_VOLAOUT8, 0, 0xff, 1, dac_tlv),
+ SOC_DOUBLE_R_S_TLV("ADC1 Capture Volume", CS42XX8_VOLAIN1,
+ CS42XX8_VOLAIN2, 0, -0x80, 0x30, 7, 0, adc_tlv),
+ SOC_DOUBLE_R_S_TLV("ADC2 Capture Volume", CS42XX8_VOLAIN3,
+ CS42XX8_VOLAIN4, 0, -0x80, 0x30, 7, 0, adc_tlv),
+ SOC_DOUBLE("DAC1 Invert Switch", CS42XX8_DACINV, 0, 1, 1, 0),
+ SOC_DOUBLE("DAC2 Invert Switch", CS42XX8_DACINV, 2, 3, 1, 0),
+ SOC_DOUBLE("DAC3 Invert Switch", CS42XX8_DACINV, 4, 5, 1, 0),
+ SOC_DOUBLE("DAC4 Invert Switch", CS42XX8_DACINV, 6, 7, 1, 0),
+ SOC_DOUBLE("ADC1 Invert Switch", CS42XX8_ADCINV, 0, 1, 1, 0),
+ SOC_DOUBLE("ADC2 Invert Switch", CS42XX8_ADCINV, 2, 3, 1, 0),
+ SOC_SINGLE("ADC High-Pass Filter Switch", CS42XX8_ADCCTL, 7, 1, 1),
+ SOC_SINGLE("DAC De-emphasis Switch", CS42XX8_ADCCTL, 5, 1, 0),
+ SOC_ENUM("ADC1 Single Ended Mode Switch", adc1_single_enum),
+ SOC_ENUM("ADC2 Single Ended Mode Switch", adc2_single_enum),
+ SOC_SINGLE("DAC Single Volume Control Switch", CS42XX8_TXCTL, 7, 1, 0),
+ SOC_ENUM("DAC Soft Ramp & Zero Cross Control Switch", dac_szc_enum),
+ SOC_SINGLE("DAC Auto Mute Switch", CS42XX8_TXCTL, 4, 1, 0),
+ SOC_SINGLE("Mute ADC Serial Port Switch", CS42XX8_TXCTL, 3, 1, 0),
+ SOC_SINGLE("ADC Single Volume Control Switch", CS42XX8_TXCTL, 2, 1, 0),
+ SOC_ENUM("ADC Soft Ramp & Zero Cross Control Switch", adc_szc_enum),
+};
+
+static const struct snd_kcontrol_new cs42xx8_adc3_snd_controls[] = {
+ SOC_DOUBLE_R_S_TLV("ADC3 Capture Volume", CS42XX8_VOLAIN5,
+ CS42XX8_VOLAIN6, 0, -0x80, 0x30, 7, 0, adc_tlv),
+ SOC_DOUBLE("ADC3 Invert Switch", CS42XX8_ADCINV, 4, 5, 1, 0),
+ SOC_ENUM("ADC3 Single Ended Mode Switch", adc3_single_enum),
+};
+
+static const struct snd_soc_dapm_widget cs42xx8_dapm_widgets[] = {
+ SND_SOC_DAPM_DAC("DAC1", "Playback", CS42XX8_PWRCTL, 1, 1),
+ SND_SOC_DAPM_DAC("DAC2", "Playback", CS42XX8_PWRCTL, 2, 1),
+ SND_SOC_DAPM_DAC("DAC3", "Playback", CS42XX8_PWRCTL, 3, 1),
+ SND_SOC_DAPM_DAC("DAC4", "Playback", CS42XX8_PWRCTL, 4, 1),
+
+ SND_SOC_DAPM_OUTPUT("AOUT1L"),
+ SND_SOC_DAPM_OUTPUT("AOUT1R"),
+ SND_SOC_DAPM_OUTPUT("AOUT2L"),
+ SND_SOC_DAPM_OUTPUT("AOUT2R"),
+ SND_SOC_DAPM_OUTPUT("AOUT3L"),
+ SND_SOC_DAPM_OUTPUT("AOUT3R"),
+ SND_SOC_DAPM_OUTPUT("AOUT4L"),
+ SND_SOC_DAPM_OUTPUT("AOUT4R"),
+
+ SND_SOC_DAPM_ADC("ADC1", "Capture", CS42XX8_PWRCTL, 5, 1),
+ SND_SOC_DAPM_ADC("ADC2", "Capture", CS42XX8_PWRCTL, 6, 1),
+
+ SND_SOC_DAPM_INPUT("AIN1L"),
+ SND_SOC_DAPM_INPUT("AIN1R"),
+ SND_SOC_DAPM_INPUT("AIN2L"),
+ SND_SOC_DAPM_INPUT("AIN2R"),
+
+};
+
+static const struct snd_soc_dapm_widget cs42xx8_adc3_dapm_widgets[] = {
+ SND_SOC_DAPM_ADC("ADC3", "Capture", CS42XX8_PWRCTL, 7, 1),
+
+ SND_SOC_DAPM_INPUT("AIN3L"),
+ SND_SOC_DAPM_INPUT("AIN3R"),
+};
+
+static const struct snd_soc_dapm_route cs42xx8_dapm_routes[] = {
+ /* Playback */
+ { "AOUT1L", NULL, "DAC1" },
+ { "AOUT1R", NULL, "DAC1" },
+
+ { "AOUT2L", NULL, "DAC2" },
+ { "AOUT2R", NULL, "DAC2" },
+
+ { "AOUT3L", NULL, "DAC3" },
+ { "AOUT3R", NULL, "DAC3" },
+
+ { "AOUT4L", NULL, "DAC4" },
+ { "AOUT4R", NULL, "DAC4" },
+
+ /* Capture */
+ { "ADC1", NULL, "AIN1L" },
+ { "ADC1", NULL, "AIN1R" },
+
+ { "ADC2", NULL, "AIN2L" },
+ { "ADC2", NULL, "AIN2R" },
+};
+
+static const struct snd_soc_dapm_route cs42xx8_adc3_dapm_routes[] = {
+ /* Capture */
+ { "ADC3", NULL, "AIN3L" },
+ { "ADC3", NULL, "AIN3R" },
+};
+
+struct cs42xx8_ratios {
+ unsigned int mfreq;
+ unsigned int min_mclk;
+ unsigned int max_mclk;
+ unsigned int ratio[3];
+};
+
+static const struct cs42xx8_ratios cs42xx8_ratios[] = {
+ { 0, 1029000, 12800000, {256, 128, 64} },
+ { 2, 1536000, 19200000, {384, 192, 96} },
+ { 4, 2048000, 25600000, {512, 256, 128} },
+ { 6, 3072000, 38400000, {768, 384, 192} },
+ { 8, 4096000, 51200000, {1024, 512, 256} },
+};
+
+static int cs42xx8_set_dai_sysclk(struct snd_soc_dai *codec_dai,
+ int clk_id, unsigned int freq, int dir)
+{
+ struct snd_soc_codec *codec = codec_dai->codec;
+ struct rpmsg_cs42xx8_priv *cs42xx8 = snd_soc_codec_get_drvdata(codec);
+
+ cs42xx8->sysclk = freq;
+
+ return 0;
+}
+
+static int cs42xx8_set_dai_fmt(struct snd_soc_dai *codec_dai,
+ unsigned int format)
+{
+ struct snd_soc_codec *codec = codec_dai->codec;
+ struct rpmsg_cs42xx8_priv *cs42xx8 = snd_soc_codec_get_drvdata(codec);
+ u32 val;
+
+ /* Set DAI format */
+ switch (format & SND_SOC_DAIFMT_FORMAT_MASK) {
+ case SND_SOC_DAIFMT_LEFT_J:
+ val = CS42XX8_INTF_DAC_DIF_LEFTJ | CS42XX8_INTF_ADC_DIF_LEFTJ;
+ break;
+ case SND_SOC_DAIFMT_I2S:
+ val = CS42XX8_INTF_DAC_DIF_I2S | CS42XX8_INTF_ADC_DIF_I2S;
+ break;
+ case SND_SOC_DAIFMT_RIGHT_J:
+ val = CS42XX8_INTF_DAC_DIF_RIGHTJ | CS42XX8_INTF_ADC_DIF_RIGHTJ;
+ break;
+ case SND_SOC_DAIFMT_DSP_A:
+ val = CS42XX8_INTF_DAC_DIF_TDM | CS42XX8_INTF_ADC_DIF_TDM;
+ break;
+ default:
+ dev_err(codec->dev, "unsupported dai format\n");
+ return -EINVAL;
+ }
+
+ regmap_update_bits(cs42xx8->regmap, CS42XX8_INTF,
+ CS42XX8_INTF_DAC_DIF_MASK |
+ CS42XX8_INTF_ADC_DIF_MASK, val);
+
+ if (cs42xx8->slave_mode[0] == cs42xx8->slave_mode[1]) {
+ /* Set master/slave audio interface */
+ switch (format & SND_SOC_DAIFMT_MASTER_MASK) {
+ case SND_SOC_DAIFMT_CBS_CFS:
+ cs42xx8->slave_mode[0] = true;
+ cs42xx8->slave_mode[1] = true;
+ break;
+ case SND_SOC_DAIFMT_CBM_CFM:
+ cs42xx8->slave_mode[0] = false;
+ cs42xx8->slave_mode[1] = false;
+ break;
+ default:
+ dev_err(codec->dev, "unsupported master/slave mode\n");
+ return -EINVAL;
+ }
+ }
+
+ return 0;
+}
+
+static int cs42xx8_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params,
+ struct snd_soc_dai *dai)
+{
+ struct snd_soc_codec *codec = dai->codec;
+ struct rpmsg_cs42xx8_priv *cs42xx8 = snd_soc_codec_get_drvdata(codec);
+ bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
+ u32 ratio[2];
+ u32 rate[2];
+ u32 fm[2];
+ u32 i, val, mask;
+ bool condition1, condition2;
+
+ if (tx)
+ cs42xx8->tx_channels = params_channels(params);
+
+ rate[tx] = params_rate(params);
+ rate[!tx] = cs42xx8->rate[!tx];
+
+ ratio[tx] = rate[tx] > 0 ? cs42xx8->sysclk / rate[tx] : 0;
+ ratio[!tx] = rate[!tx] > 0 ? cs42xx8->sysclk / rate[!tx] : 0;
+
+ for (i = 0; i < 2; i++) {
+ if (cs42xx8->slave_mode[i]) {
+ fm[i] = CS42XX8_FM_AUTO;
+ } else {
+ if (rate[i] < 50000)
+ fm[i] = CS42XX8_FM_SINGLE;
+ else if (rate[i] > 50000 && rate[i] < 100000)
+ fm[i] = CS42XX8_FM_DOUBLE;
+ else if (rate[i] > 100000 && rate[i] < 200000)
+ fm[i] = CS42XX8_FM_QUAD;
+ else {
+ dev_err(codec->dev,
+ "unsupported sample rate or rate combine\n");
+ return -EINVAL;
+ }
+ }
+ }
+
+ for (i = 0; i < ARRAY_SIZE(cs42xx8_ratios); i++) {
+ condition1 = ((fm[tx] == CS42XX8_FM_AUTO) ?
+ (cs42xx8_ratios[i].ratio[0] == ratio[tx] ||
+ cs42xx8_ratios[i].ratio[1] == ratio[tx] ||
+ cs42xx8_ratios[i].ratio[2] == ratio[tx]) :
+ (cs42xx8_ratios[i].ratio[fm[tx]] == ratio[tx])) &&
+ cs42xx8->sysclk >= cs42xx8_ratios[i].min_mclk &&
+ cs42xx8->sysclk <= cs42xx8_ratios[i].max_mclk;
+
+ if (ratio[tx] <= 0)
+ condition1 = true;
+
+ condition2 = ((fm[!tx] == CS42XX8_FM_AUTO) ?
+ (cs42xx8_ratios[i].ratio[0] == ratio[!tx] ||
+ cs42xx8_ratios[i].ratio[1] == ratio[!tx] ||
+ cs42xx8_ratios[i].ratio[2] == ratio[!tx]) :
+ (cs42xx8_ratios[i].ratio[fm[!tx]] == ratio[!tx]));
+
+ if (ratio[!tx] <= 0)
+ condition2 = true;
+
+ if (condition1 && condition2)
+ break;
+ }
+
+ if (i == ARRAY_SIZE(cs42xx8_ratios)) {
+ dev_err(codec->dev, "unsupported sysclk ratio\n");
+ return -EINVAL;
+ }
+
+ cs42xx8->rate[tx] = params_rate(params);
+
+ mask = CS42XX8_FUNCMOD_MFREQ_MASK;
+ val = cs42xx8_ratios[i].mfreq;
+
+ regmap_update_bits(cs42xx8->regmap, CS42XX8_FUNCMOD,
+ CS42XX8_FUNCMOD_xC_FM_MASK(tx) | mask,
+ CS42XX8_FUNCMOD_xC_FM(tx, fm[tx]) | val);
+
+ return 0;
+}
+
+static int cs42xx8_hw_free(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_codec *codec = rtd->codec;
+ struct rpmsg_cs42xx8_priv *cs42xx8 = snd_soc_codec_get_drvdata(codec);
+ bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
+
+ cs42xx8->rate[tx] = 0;
+
+ regmap_update_bits(cs42xx8->regmap, CS42XX8_FUNCMOD,
+ CS42XX8_FUNCMOD_xC_FM_MASK(tx),
+ CS42XX8_FUNCMOD_xC_FM(tx, CS42XX8_FM_AUTO));
+ return 0;
+}
+
+static int cs42xx8_digital_mute(struct snd_soc_dai *dai, int mute)
+{
+ struct snd_soc_codec *codec = dai->codec;
+ struct rpmsg_cs42xx8_priv *cs42xx8 = snd_soc_codec_get_drvdata(codec);
+ u8 dac_unmute = cs42xx8->tx_channels ?
+ ~((0x1 << cs42xx8->tx_channels) - 1) : 0;
+
+ regmap_write(cs42xx8->regmap, CS42XX8_DACMUTE,
+ mute ? CS42XX8_DACMUTE_ALL : dac_unmute);
+
+ return 0;
+}
+
+static const struct snd_soc_dai_ops cs42xx8_dai_ops = {
+ .set_fmt = cs42xx8_set_dai_fmt,
+ .set_sysclk = cs42xx8_set_dai_sysclk,
+ .hw_params = cs42xx8_hw_params,
+ .hw_free = cs42xx8_hw_free,
+ .digital_mute = cs42xx8_digital_mute,
+};
+
+static struct snd_soc_dai_driver cs42xx8_dai = {
+ .playback = {
+ .stream_name = "Playback",
+ .channels_min = 1,
+ .channels_max = 8,
+ .rates = SNDRV_PCM_RATE_8000_192000,
+ .formats = CS42XX8_FORMATS,
+ },
+ .capture = {
+ .stream_name = "Capture",
+ .channels_min = 1,
+ .rates = SNDRV_PCM_RATE_8000_192000,
+ .formats = CS42XX8_FORMATS,
+ },
+ .ops = &cs42xx8_dai_ops,
+};
+
+static const struct reg_default cs42xx8_reg[] = {
+ { 0x02, 0x00 }, /* Power Control */
+ { 0x03, 0xF0 }, /* Functional Mode */
+ { 0x04, 0x46 }, /* Interface Formats */
+ { 0x05, 0x00 }, /* ADC Control & DAC De-Emphasis */
+ { 0x06, 0x10 }, /* Transition Control */
+ { 0x07, 0x00 }, /* DAC Channel Mute */
+ { 0x08, 0x00 }, /* Volume Control AOUT1 */
+ { 0x09, 0x00 }, /* Volume Control AOUT2 */
+ { 0x0a, 0x00 }, /* Volume Control AOUT3 */
+ { 0x0b, 0x00 }, /* Volume Control AOUT4 */
+ { 0x0c, 0x00 }, /* Volume Control AOUT5 */
+ { 0x0d, 0x00 }, /* Volume Control AOUT6 */
+ { 0x0e, 0x00 }, /* Volume Control AOUT7 */
+ { 0x0f, 0x00 }, /* Volume Control AOUT8 */
+ { 0x10, 0x00 }, /* DAC Channel Invert */
+ { 0x11, 0x00 }, /* Volume Control AIN1 */
+ { 0x12, 0x00 }, /* Volume Control AIN2 */
+ { 0x13, 0x00 }, /* Volume Control AIN3 */
+ { 0x14, 0x00 }, /* Volume Control AIN4 */
+ { 0x15, 0x00 }, /* Volume Control AIN5 */
+ { 0x16, 0x00 }, /* Volume Control AIN6 */
+ { 0x17, 0x00 }, /* ADC Channel Invert */
+ { 0x18, 0x00 }, /* Status Control */
+ { 0x1a, 0x00 }, /* Status Mask */
+ { 0x1b, 0x00 }, /* MUTEC Pin Control */
+};
+
+static bool cs42xx8_volatile_register(struct device *dev, unsigned int reg)
+{
+ switch (reg) {
+ case CS42XX8_STATUS:
+ return true;
+ default:
+ return false;
+ }
+}
+
+static bool cs42xx8_writeable_register(struct device *dev, unsigned int reg)
+{
+ switch (reg) {
+ case CS42XX8_CHIPID:
+ case CS42XX8_STATUS:
+ return false;
+ default:
+ return true;
+ }
+}
+
+static int rpmsg_cs42xx8_read(void *context, unsigned int reg, unsigned int *val)
+{
+ struct rpmsg_cs42xx8_priv *cs42xx8 = context;
+ struct fsl_rpmsg_i2s *rpmsg_i2s = cs42xx8->rpmsg_i2s;
+ struct i2s_info *i2s_info = &rpmsg_i2s->i2s_info;
+ struct i2s_rpmsg_s *rpmsg = &i2s_info->rpmsg[GET_CODEC_VALUE].send_msg;
+ int err, reg_val;
+
+ mutex_lock(&i2s_info->i2c_lock);
+ rpmsg->param.audioindex = cs42xx8->audioindex;
+ rpmsg->param.buffer_addr = reg;
+ rpmsg->header.cmd = GET_CODEC_VALUE;
+ err = i2s_info->send_message(&i2s_info->rpmsg[GET_CODEC_VALUE], i2s_info);
+ reg_val = i2s_info->rpmsg[GET_CODEC_VALUE].recv_msg.param.reg_data;
+ mutex_unlock(&i2s_info->i2c_lock);
+ if (err)
+ return -EIO;
+
+ *val = reg_val;
+ return 0;
+}
+
+static int rpmsg_cs42xx8_write(void *context, unsigned int reg, unsigned int val)
+{
+ struct rpmsg_cs42xx8_priv *cs42xx8 = context;
+ struct fsl_rpmsg_i2s *rpmsg_i2s = cs42xx8->rpmsg_i2s;
+ struct i2s_info *i2s_info = &rpmsg_i2s->i2s_info;
+ struct i2s_rpmsg_s *rpmsg = &i2s_info->rpmsg[SET_CODEC_VALUE].send_msg;
+ int err;
+
+ mutex_lock(&i2s_info->i2c_lock);
+ rpmsg->param.audioindex = cs42xx8->audioindex;
+ rpmsg->param.buffer_addr = reg;
+ rpmsg->param.buffer_size = val;
+ rpmsg->header.cmd = SET_CODEC_VALUE;
+ err = i2s_info->send_message(&i2s_info->rpmsg[SET_CODEC_VALUE], i2s_info);
+ mutex_unlock(&i2s_info->i2c_lock);
+ if (err)
+ return -EIO;
+
+ return 0;
+}
+
+static struct regmap_config rpmsg_cs42xx8_regmap_config = {
+ .reg_bits = 8,
+ .val_bits = 8,
+
+ .max_register = CS42XX8_LASTREG,
+ .reg_defaults = cs42xx8_reg,
+ .num_reg_defaults = ARRAY_SIZE(cs42xx8_reg),
+ .volatile_reg = cs42xx8_volatile_register,
+ .writeable_reg = cs42xx8_writeable_register,
+ .cache_type = REGCACHE_RBTREE,
+
+ .reg_read = rpmsg_cs42xx8_read,
+ .reg_write = rpmsg_cs42xx8_write,
+};
+
+static int cs42xx8_codec_probe(struct snd_soc_codec *codec)
+{
+ struct rpmsg_cs42xx8_priv *cs42xx8 = snd_soc_codec_get_drvdata(codec);
+ struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
+
+ switch (cs42xx8->drvdata->num_adcs) {
+ case 3:
+ snd_soc_add_codec_controls(codec, cs42xx8_adc3_snd_controls,
+ ARRAY_SIZE(cs42xx8_adc3_snd_controls));
+ snd_soc_dapm_new_controls(dapm, cs42xx8_adc3_dapm_widgets,
+ ARRAY_SIZE(cs42xx8_adc3_dapm_widgets));
+ snd_soc_dapm_add_routes(dapm, cs42xx8_adc3_dapm_routes,
+ ARRAY_SIZE(cs42xx8_adc3_dapm_routes));
+ break;
+ default:
+ break;
+ }
+
+ /* Mute all DAC channels */
+ regmap_write(cs42xx8->regmap, CS42XX8_DACMUTE, CS42XX8_DACMUTE_ALL);
+ regmap_update_bits(cs42xx8->regmap, CS42XX8_PWRCTL,
+ CS42XX8_PWRCTL_PDN_MASK, 0);
+ return 0;
+}
+
+static const struct snd_soc_codec_driver cs42xx8_driver = {
+ .probe = cs42xx8_codec_probe,
+ .idle_bias_off = true,
+
+ .component_driver = {
+ .controls = cs42xx8_snd_controls,
+ .num_controls = ARRAY_SIZE(cs42xx8_snd_controls),
+ .dapm_widgets = cs42xx8_dapm_widgets,
+ .num_dapm_widgets = ARRAY_SIZE(cs42xx8_dapm_widgets),
+ .dapm_routes = cs42xx8_dapm_routes,
+ .num_dapm_routes = ARRAY_SIZE(cs42xx8_dapm_routes),
+ },
+};
+
+static int rpmsg_cs42xx8_codec_probe(struct platform_device *pdev)
+{
+ struct fsl_rpmsg_i2s *rpmsg_i2s = dev_get_drvdata(pdev->dev.parent);
+ struct fsl_rpmsg_codec *pdata = pdev->dev.platform_data;
+ struct rpmsg_cs42xx8_priv *cs42xx8;
+ struct device *dev = &pdev->dev;
+ int ret, val, i;
+
+ cs42xx8 = devm_kzalloc(&pdev->dev, sizeof(*cs42xx8), GFP_KERNEL);
+ if (cs42xx8 == NULL)
+ return -ENOMEM;
+
+ cs42xx8->regmap = devm_regmap_init(&pdev->dev, NULL,
+ cs42xx8, &rpmsg_cs42xx8_regmap_config);
+ if (IS_ERR(cs42xx8->regmap))
+ return PTR_ERR(cs42xx8->regmap);
+
+ dev_set_drvdata(&pdev->dev, cs42xx8);
+
+ cs42xx8->drvdata = devm_kzalloc(&pdev->dev,
+ sizeof(struct cs42xx8_driver_data), GFP_KERNEL);
+ if (!cs42xx8->drvdata)
+ return -ENOMEM;
+
+ cs42xx8->rpmsg_i2s = rpmsg_i2s;
+
+ memcpy(cs42xx8->drvdata->name, pdata->name, 32);
+ cs42xx8->drvdata->num_adcs = pdata->num_adcs;
+ cs42xx8->audioindex = pdata->audioindex;
+ cs42xx8->reset_gpio = of_get_named_gpio(pdev->dev.parent->of_node,
+ "reset-gpio", 0);
+ if (gpio_is_valid(cs42xx8->reset_gpio)) {
+ ret = devm_gpio_request_one(dev, cs42xx8->reset_gpio,
+ GPIOF_OUT_INIT_LOW, "cs42xx8 reset");
+ if (ret) {
+ dev_err(dev, "unable to get reset gpio\n");
+ return ret;
+ }
+ gpio_set_value_cansleep(cs42xx8->reset_gpio, 1);
+ }
+
+ cs42xx8->clk = devm_clk_get(pdev->dev.parent, "mclk");
+ if (IS_ERR(cs42xx8->clk)) {
+ dev_err(dev, "failed to get the clock: %ld\n",
+ PTR_ERR(cs42xx8->clk));
+ return -EINVAL;
+ }
+
+ cs42xx8->sysclk = clk_get_rate(cs42xx8->clk);
+
+ if (of_property_read_bool(pdev->dev.parent->of_node, "fsl,txm-rxs")) {
+ /* 0 -- rx, 1 -- tx */
+ cs42xx8->slave_mode[0] = true;
+ cs42xx8->slave_mode[1] = false;
+ }
+
+ if (of_property_read_bool(pdev->dev.parent->of_node, "fsl,txs-rxm")) {
+ /* 0 -- rx, 1 -- tx */
+ cs42xx8->slave_mode[0] = false;
+ cs42xx8->slave_mode[1] = true;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(cs42xx8->supplies); i++)
+ cs42xx8->supplies[i].supply = cs42xx8_supply_names[i];
+
+ ret = devm_regulator_bulk_get(pdev->dev.parent,
+ ARRAY_SIZE(cs42xx8->supplies), cs42xx8->supplies);
+ if (ret) {
+ dev_err(dev, "failed to request supplies: %d\n", ret);
+ return ret;
+ }
+
+ ret = regulator_bulk_enable(ARRAY_SIZE(cs42xx8->supplies),
+ cs42xx8->supplies);
+ if (ret) {
+ dev_err(dev, "failed to enable supplies: %d\n", ret);
+ return ret;
+ }
+
+ /* Make sure hardware reset done */
+ usleep_range(5000, 10000);
+
+ /*
+ * We haven't marked the chip revision as volatile due to
+ * sharing a register with the right input volume; explicitly
+ * bypass the cache to read it.
+ */
+ regcache_cache_bypass(cs42xx8->regmap, true);
+
+ /* Validate the chip ID */
+ ret = regmap_read(cs42xx8->regmap, CS42XX8_CHIPID, &val);
+ if (ret < 0) {
+ dev_err(dev, "failed to get device ID, ret = %d", ret);
+ goto err_enable;
+ }
+
+ /* The top four bits of the chip ID should be 0000 */
+ if (((val & CS42XX8_CHIPID_CHIP_ID_MASK) >> 4) != 0x00) {
+ dev_err(dev, "unmatched chip ID: %d\n",
+ (val & CS42XX8_CHIPID_CHIP_ID_MASK) >> 4);
+ ret = -EINVAL;
+ goto err_enable;
+ }
+
+ dev_info(dev, "found device, revision %X\n",
+ val & CS42XX8_CHIPID_REV_ID_MASK);
+
+ regcache_cache_bypass(cs42xx8->regmap, false);
+
+ cs42xx8_dai.name = cs42xx8->drvdata->name;
+
+ /* Each adc supports stereo input */
+ cs42xx8_dai.capture.channels_max = cs42xx8->drvdata->num_adcs * 2;
+
+ pm_runtime_enable(dev);
+ pm_request_idle(dev);
+
+ ret = snd_soc_register_codec(dev, &cs42xx8_driver, &cs42xx8_dai, 1);
+ if (ret) {
+ dev_err(dev, "failed to register codec:%d\n", ret);
+ goto err_enable;
+ }
+
+ regcache_cache_only(cs42xx8->regmap, true);
+
+err_enable:
+ regulator_bulk_disable(ARRAY_SIZE(cs42xx8->supplies),
+ cs42xx8->supplies);
+
+ return ret;
+}
+
+#ifdef CONFIG_PM
+static int cs42xx8_runtime_resume(struct device *dev)
+{
+ struct rpmsg_cs42xx8_priv *cs42xx8 = dev_get_drvdata(dev);
+ int ret;
+
+ ret = clk_prepare_enable(cs42xx8->clk);
+ if (ret) {
+ dev_err(dev, "failed to enable mclk: %d\n", ret);
+ return ret;
+ }
+
+ if (gpio_is_valid(cs42xx8->reset_gpio)) {
+ gpio_set_value_cansleep(cs42xx8->reset_gpio, 0);
+ gpio_set_value_cansleep(cs42xx8->reset_gpio, 1);
+ }
+
+ ret = regulator_bulk_enable(ARRAY_SIZE(cs42xx8->supplies),
+ cs42xx8->supplies);
+ if (ret) {
+ dev_err(dev, "failed to enable supplies: %d\n", ret);
+ goto err_clk;
+ }
+
+ regmap_update_bits(cs42xx8->regmap, CS42XX8_PWRCTL,
+ CS42XX8_PWRCTL_PDN_MASK, 1);
+ /* Make sure hardware reset done */
+ usleep_range(5000, 10000);
+
+ regmap_update_bits(cs42xx8->regmap, CS42XX8_PWRCTL,
+ CS42XX8_PWRCTL_PDN_MASK, 0);
+
+ regcache_cache_only(cs42xx8->regmap, false);
+
+ ret = regcache_sync(cs42xx8->regmap);
+ if (ret) {
+ dev_err(dev, "failed to sync regmap: %d\n", ret);
+ goto err_bulk;
+ }
+
+ return 0;
+
+err_bulk:
+ regulator_bulk_disable(ARRAY_SIZE(cs42xx8->supplies),
+ cs42xx8->supplies);
+err_clk:
+ clk_disable_unprepare(cs42xx8->clk);
+
+ return ret;
+}
+
+static int cs42xx8_runtime_suspend(struct device *dev)
+{
+ struct rpmsg_cs42xx8_priv *cs42xx8 = dev_get_drvdata(dev);
+
+ regcache_cache_only(cs42xx8->regmap, true);
+
+ regulator_bulk_disable(ARRAY_SIZE(cs42xx8->supplies),
+ cs42xx8->supplies);
+
+ clk_disable_unprepare(cs42xx8->clk);
+
+ return 0;
+}
+#endif
+
+const struct dev_pm_ops rpmsg_cs42xx8_pm = {
+ SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, pm_runtime_force_resume)
+ SET_RUNTIME_PM_OPS(cs42xx8_runtime_suspend, cs42xx8_runtime_resume, NULL)
+};
+
+static int rpmsg_cs42xx8_codec_remove(struct platform_device *pdev)
+{
+ snd_soc_unregister_codec(&pdev->dev);
+ return 0;
+}
+
+static struct platform_driver rpmsg_cs42xx8_codec_driver = {
+ .driver = {
+ .name = RPMSG_CODEC_DRV_NAME_CS42888,
+ .pm = &rpmsg_cs42xx8_pm,
+ },
+ .probe = rpmsg_cs42xx8_codec_probe,
+ .remove = rpmsg_cs42xx8_codec_remove,
+};
+
+module_platform_driver(rpmsg_cs42xx8_codec_driver);
+
+MODULE_DESCRIPTION("Cirrus Logic CS42448/CS42888 ALSA SoC Codec Driver");
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/rpmsg_cs42xx8.h b/sound/soc/codecs/rpmsg_cs42xx8.h
new file mode 100644
index 000000000000..682295272f49
--- /dev/null
+++ b/sound/soc/codecs/rpmsg_cs42xx8.h
@@ -0,0 +1,232 @@
+/*
+ * cs42xx8.h - Cirrus Logic CS42448/CS42888 Audio CODEC driver header file
+ *
+ * Copyright (C) 2014 Freescale Semiconductor, Inc.
+ *
+ * Author: Nicolin Chen <Guangyu.Chen@freescale.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 _RPMSG_CS42XX8_H
+#define _RPMSG_CS42XX8_H
+
+struct cs42xx8_driver_data {
+ char name[32];
+ int num_adcs;
+};
+
+/* CS42888 register map */
+#define CS42XX8_CHIPID 0x01 /* Chip ID */
+#define CS42XX8_PWRCTL 0x02 /* Power Control */
+#define CS42XX8_FUNCMOD 0x03 /* Functional Mode */
+#define CS42XX8_INTF 0x04 /* Interface Formats */
+#define CS42XX8_ADCCTL 0x05 /* ADC Control */
+#define CS42XX8_TXCTL 0x06 /* Transition Control */
+#define CS42XX8_DACMUTE 0x07 /* DAC Mute Control */
+#define CS42XX8_VOLAOUT1 0x08 /* Volume Control AOUT1 */
+#define CS42XX8_VOLAOUT2 0x09 /* Volume Control AOUT2 */
+#define CS42XX8_VOLAOUT3 0x0A /* Volume Control AOUT3 */
+#define CS42XX8_VOLAOUT4 0x0B /* Volume Control AOUT4 */
+#define CS42XX8_VOLAOUT5 0x0C /* Volume Control AOUT5 */
+#define CS42XX8_VOLAOUT6 0x0D /* Volume Control AOUT6 */
+#define CS42XX8_VOLAOUT7 0x0E /* Volume Control AOUT7 */
+#define CS42XX8_VOLAOUT8 0x0F /* Volume Control AOUT8 */
+#define CS42XX8_DACINV 0x10 /* DAC Channel Invert */
+#define CS42XX8_VOLAIN1 0x11 /* Volume Control AIN1 */
+#define CS42XX8_VOLAIN2 0x12 /* Volume Control AIN2 */
+#define CS42XX8_VOLAIN3 0x13 /* Volume Control AIN3 */
+#define CS42XX8_VOLAIN4 0x14 /* Volume Control AIN4 */
+#define CS42XX8_VOLAIN5 0x15 /* Volume Control AIN5 */
+#define CS42XX8_VOLAIN6 0x16 /* Volume Control AIN6 */
+#define CS42XX8_ADCINV 0x17 /* ADC Channel Invert */
+#define CS42XX8_STATUSCTL 0x18 /* Status Control */
+#define CS42XX8_STATUS 0x19 /* Status */
+#define CS42XX8_STATUSM 0x1A /* Status Mask */
+#define CS42XX8_MUTEC 0x1B /* MUTEC Pin Control */
+
+#define CS42XX8_FIRSTREG CS42XX8_CHIPID
+#define CS42XX8_LASTREG CS42XX8_MUTEC
+#define CS42XX8_NUMREGS (CS42XX8_LASTREG - CS42XX8_FIRSTREG + 1)
+#define CS42XX8_I2C_INCR 0x80
+
+/* Chip I.D. and Revision Register (Address 01h) */
+#define CS42XX8_CHIPID_CHIP_ID_MASK 0xF0
+#define CS42XX8_CHIPID_REV_ID_MASK 0x0F
+
+/* Power Control (Address 02h) */
+#define CS42XX8_PWRCTL_PDN_ADC3_SHIFT 7
+#define CS42XX8_PWRCTL_PDN_ADC3_MASK (1 << CS42XX8_PWRCTL_PDN_ADC3_SHIFT)
+#define CS42XX8_PWRCTL_PDN_ADC3 (1 << CS42XX8_PWRCTL_PDN_ADC3_SHIFT)
+#define CS42XX8_PWRCTL_PDN_ADC2_SHIFT 6
+#define CS42XX8_PWRCTL_PDN_ADC2_MASK (1 << CS42XX8_PWRCTL_PDN_ADC2_SHIFT)
+#define CS42XX8_PWRCTL_PDN_ADC2 (1 << CS42XX8_PWRCTL_PDN_ADC2_SHIFT)
+#define CS42XX8_PWRCTL_PDN_ADC1_SHIFT 5
+#define CS42XX8_PWRCTL_PDN_ADC1_MASK (1 << CS42XX8_PWRCTL_PDN_ADC1_SHIFT)
+#define CS42XX8_PWRCTL_PDN_ADC1 (1 << CS42XX8_PWRCTL_PDN_ADC1_SHIFT)
+#define CS42XX8_PWRCTL_PDN_DAC4_SHIFT 4
+#define CS42XX8_PWRCTL_PDN_DAC4_MASK (1 << CS42XX8_PWRCTL_PDN_DAC4_SHIFT)
+#define CS42XX8_PWRCTL_PDN_DAC4 (1 << CS42XX8_PWRCTL_PDN_DAC4_SHIFT)
+#define CS42XX8_PWRCTL_PDN_DAC3_SHIFT 3
+#define CS42XX8_PWRCTL_PDN_DAC3_MASK (1 << CS42XX8_PWRCTL_PDN_DAC3_SHIFT)
+#define CS42XX8_PWRCTL_PDN_DAC3 (1 << CS42XX8_PWRCTL_PDN_DAC3_SHIFT)
+#define CS42XX8_PWRCTL_PDN_DAC2_SHIFT 2
+#define CS42XX8_PWRCTL_PDN_DAC2_MASK (1 << CS42XX8_PWRCTL_PDN_DAC2_SHIFT)
+#define CS42XX8_PWRCTL_PDN_DAC2 (1 << CS42XX8_PWRCTL_PDN_DAC2_SHIFT)
+#define CS42XX8_PWRCTL_PDN_DAC1_SHIFT 1
+#define CS42XX8_PWRCTL_PDN_DAC1_MASK (1 << CS42XX8_PWRCTL_PDN_DAC1_SHIFT)
+#define CS42XX8_PWRCTL_PDN_DAC1 (1 << CS42XX8_PWRCTL_PDN_DAC1_SHIFT)
+#define CS42XX8_PWRCTL_PDN_SHIFT 0
+#define CS42XX8_PWRCTL_PDN_MASK (1 << CS42XX8_PWRCTL_PDN_SHIFT)
+#define CS42XX8_PWRCTL_PDN (1 << CS42XX8_PWRCTL_PDN_SHIFT)
+
+/* Functional Mode (Address 03h) */
+#define CS42XX8_FUNCMOD_DAC_FM_SHIFT 6
+#define CS42XX8_FUNCMOD_DAC_FM_WIDTH 2
+#define CS42XX8_FUNCMOD_DAC_FM_MASK (((1 << CS42XX8_FUNCMOD_DAC_FM_WIDTH) - 1) << CS42XX8_FUNCMOD_DAC_FM_SHIFT)
+#define CS42XX8_FUNCMOD_DAC_FM(v) ((v) << CS42XX8_FUNCMOD_DAC_FM_SHIFT)
+#define CS42XX8_FUNCMOD_ADC_FM_SHIFT 4
+#define CS42XX8_FUNCMOD_ADC_FM_WIDTH 2
+#define CS42XX8_FUNCMOD_ADC_FM_MASK (((1 << CS42XX8_FUNCMOD_ADC_FM_WIDTH) - 1) << CS42XX8_FUNCMOD_ADC_FM_SHIFT)
+#define CS42XX8_FUNCMOD_ADC_FM(v) ((v) << CS42XX8_FUNCMOD_ADC_FM_SHIFT)
+#define CS42XX8_FUNCMOD_xC_FM_MASK(x) ((x) ? CS42XX8_FUNCMOD_DAC_FM_MASK : CS42XX8_FUNCMOD_ADC_FM_MASK)
+#define CS42XX8_FUNCMOD_xC_FM(x, v) ((x) ? CS42XX8_FUNCMOD_DAC_FM(v) : CS42XX8_FUNCMOD_ADC_FM(v))
+#define CS42XX8_FUNCMOD_MFREQ_SHIFT 1
+#define CS42XX8_FUNCMOD_MFREQ_WIDTH 3
+#define CS42XX8_FUNCMOD_MFREQ_MASK (((1 << CS42XX8_FUNCMOD_MFREQ_WIDTH) - 1) << CS42XX8_FUNCMOD_MFREQ_SHIFT)
+#define CS42XX8_FUNCMOD_MFREQ_256(s) ((0 << CS42XX8_FUNCMOD_MFREQ_SHIFT) >> (s >> 1))
+#define CS42XX8_FUNCMOD_MFREQ_384(s) ((1 << CS42XX8_FUNCMOD_MFREQ_SHIFT) >> (s >> 1))
+#define CS42XX8_FUNCMOD_MFREQ_512(s) ((2 << CS42XX8_FUNCMOD_MFREQ_SHIFT) >> (s >> 1))
+#define CS42XX8_FUNCMOD_MFREQ_768(s) ((3 << CS42XX8_FUNCMOD_MFREQ_SHIFT) >> (s >> 1))
+#define CS42XX8_FUNCMOD_MFREQ_1024(s) ((4 << CS42XX8_FUNCMOD_MFREQ_SHIFT) >> (s >> 1))
+
+#define CS42XX8_FM_SINGLE 0
+#define CS42XX8_FM_DOUBLE 1
+#define CS42XX8_FM_QUAD 2
+#define CS42XX8_FM_AUTO 3
+
+/* Interface Formats (Address 04h) */
+#define CS42XX8_INTF_FREEZE_SHIFT 7
+#define CS42XX8_INTF_FREEZE_MASK (1 << CS42XX8_INTF_FREEZE_SHIFT)
+#define CS42XX8_INTF_FREEZE (1 << CS42XX8_INTF_FREEZE_SHIFT)
+#define CS42XX8_INTF_AUX_DIF_SHIFT 6
+#define CS42XX8_INTF_AUX_DIF_MASK (1 << CS42XX8_INTF_AUX_DIF_SHIFT)
+#define CS42XX8_INTF_AUX_DIF (1 << CS42XX8_INTF_AUX_DIF_SHIFT)
+#define CS42XX8_INTF_DAC_DIF_SHIFT 3
+#define CS42XX8_INTF_DAC_DIF_WIDTH 3
+#define CS42XX8_INTF_DAC_DIF_MASK (((1 << CS42XX8_INTF_DAC_DIF_WIDTH) - 1) << CS42XX8_INTF_DAC_DIF_SHIFT)
+#define CS42XX8_INTF_DAC_DIF_LEFTJ (0 << CS42XX8_INTF_DAC_DIF_SHIFT)
+#define CS42XX8_INTF_DAC_DIF_I2S (1 << CS42XX8_INTF_DAC_DIF_SHIFT)
+#define CS42XX8_INTF_DAC_DIF_RIGHTJ (2 << CS42XX8_INTF_DAC_DIF_SHIFT)
+#define CS42XX8_INTF_DAC_DIF_RIGHTJ_16 (3 << CS42XX8_INTF_DAC_DIF_SHIFT)
+#define CS42XX8_INTF_DAC_DIF_ONELINE_20 (4 << CS42XX8_INTF_DAC_DIF_SHIFT)
+#define CS42XX8_INTF_DAC_DIF_ONELINE_24 (5 << CS42XX8_INTF_DAC_DIF_SHIFT)
+#define CS42XX8_INTF_DAC_DIF_TDM (6 << CS42XX8_INTF_DAC_DIF_SHIFT)
+#define CS42XX8_INTF_ADC_DIF_SHIFT 0
+#define CS42XX8_INTF_ADC_DIF_WIDTH 3
+#define CS42XX8_INTF_ADC_DIF_MASK (((1 << CS42XX8_INTF_ADC_DIF_WIDTH) - 1) << CS42XX8_INTF_ADC_DIF_SHIFT)
+#define CS42XX8_INTF_ADC_DIF_LEFTJ (0 << CS42XX8_INTF_ADC_DIF_SHIFT)
+#define CS42XX8_INTF_ADC_DIF_I2S (1 << CS42XX8_INTF_ADC_DIF_SHIFT)
+#define CS42XX8_INTF_ADC_DIF_RIGHTJ (2 << CS42XX8_INTF_ADC_DIF_SHIFT)
+#define CS42XX8_INTF_ADC_DIF_RIGHTJ_16 (3 << CS42XX8_INTF_ADC_DIF_SHIFT)
+#define CS42XX8_INTF_ADC_DIF_ONELINE_20 (4 << CS42XX8_INTF_ADC_DIF_SHIFT)
+#define CS42XX8_INTF_ADC_DIF_ONELINE_24 (5 << CS42XX8_INTF_ADC_DIF_SHIFT)
+#define CS42XX8_INTF_ADC_DIF_TDM (6 << CS42XX8_INTF_ADC_DIF_SHIFT)
+
+/* ADC Control & DAC De-Emphasis (Address 05h) */
+#define CS42XX8_ADCCTL_ADC_HPF_FREEZE_SHIFT 7
+#define CS42XX8_ADCCTL_ADC_HPF_FREEZE_MASK (1 << CS42XX8_ADCCTL_ADC_HPF_FREEZE_SHIFT)
+#define CS42XX8_ADCCTL_ADC_HPF_FREEZE (1 << CS42XX8_ADCCTL_ADC_HPF_FREEZE_SHIFT)
+#define CS42XX8_ADCCTL_DAC_DEM_SHIFT 5
+#define CS42XX8_ADCCTL_DAC_DEM_MASK (1 << CS42XX8_ADCCTL_DAC_DEM_SHIFT)
+#define CS42XX8_ADCCTL_DAC_DEM (1 << CS42XX8_ADCCTL_DAC_DEM_SHIFT)
+#define CS42XX8_ADCCTL_ADC1_SINGLE_SHIFT 4
+#define CS42XX8_ADCCTL_ADC1_SINGLE_MASK (1 << CS42XX8_ADCCTL_ADC1_SINGLE_SHIFT)
+#define CS42XX8_ADCCTL_ADC1_SINGLE (1 << CS42XX8_ADCCTL_ADC1_SINGLE_SHIFT)
+#define CS42XX8_ADCCTL_ADC2_SINGLE_SHIFT 3
+#define CS42XX8_ADCCTL_ADC2_SINGLE_MASK (1 << CS42XX8_ADCCTL_ADC2_SINGLE_SHIFT)
+#define CS42XX8_ADCCTL_ADC2_SINGLE (1 << CS42XX8_ADCCTL_ADC2_SINGLE_SHIFT)
+#define CS42XX8_ADCCTL_ADC3_SINGLE_SHIFT 2
+#define CS42XX8_ADCCTL_ADC3_SINGLE_MASK (1 << CS42XX8_ADCCTL_ADC3_SINGLE_SHIFT)
+#define CS42XX8_ADCCTL_ADC3_SINGLE (1 << CS42XX8_ADCCTL_ADC3_SINGLE_SHIFT)
+#define CS42XX8_ADCCTL_AIN5_MUX_SHIFT 1
+#define CS42XX8_ADCCTL_AIN5_MUX_MASK (1 << CS42XX8_ADCCTL_AIN5_MUX_SHIFT)
+#define CS42XX8_ADCCTL_AIN5_MUX (1 << CS42XX8_ADCCTL_AIN5_MUX_SHIFT)
+#define CS42XX8_ADCCTL_AIN6_MUX_SHIFT 0
+#define CS42XX8_ADCCTL_AIN6_MUX_MASK (1 << CS42XX8_ADCCTL_AIN6_MUX_SHIFT)
+#define CS42XX8_ADCCTL_AIN6_MUX (1 << CS42XX8_ADCCTL_AIN6_MUX_SHIFT)
+
+/* Transition Control (Address 06h) */
+#define CS42XX8_TXCTL_DAC_SNGVOL_SHIFT 7
+#define CS42XX8_TXCTL_DAC_SNGVOL_MASK (1 << CS42XX8_TXCTL_DAC_SNGVOL_SHIFT)
+#define CS42XX8_TXCTL_DAC_SNGVOL (1 << CS42XX8_TXCTL_DAC_SNGVOL_SHIFT)
+#define CS42XX8_TXCTL_DAC_SZC_SHIFT 5
+#define CS42XX8_TXCTL_DAC_SZC_WIDTH 2
+#define CS42XX8_TXCTL_DAC_SZC_MASK (((1 << CS42XX8_TXCTL_DAC_SZC_WIDTH) - 1) << CS42XX8_TXCTL_DAC_SZC_SHIFT)
+#define CS42XX8_TXCTL_DAC_SZC_IC (0 << CS42XX8_TXCTL_DAC_SZC_SHIFT)
+#define CS42XX8_TXCTL_DAC_SZC_ZC (1 << CS42XX8_TXCTL_DAC_SZC_SHIFT)
+#define CS42XX8_TXCTL_DAC_SZC_SR (2 << CS42XX8_TXCTL_DAC_SZC_SHIFT)
+#define CS42XX8_TXCTL_DAC_SZC_SRZC (3 << CS42XX8_TXCTL_DAC_SZC_SHIFT)
+#define CS42XX8_TXCTL_AMUTE_SHIFT 4
+#define CS42XX8_TXCTL_AMUTE_MASK (1 << CS42XX8_TXCTL_AMUTE_SHIFT)
+#define CS42XX8_TXCTL_AMUTE (1 << CS42XX8_TXCTL_AMUTE_SHIFT)
+#define CS42XX8_TXCTL_MUTE_ADC_SP_SHIFT 3
+#define CS42XX8_TXCTL_MUTE_ADC_SP_MASK (1 << CS42XX8_TXCTL_MUTE_ADC_SP_SHIFT)
+#define CS42XX8_TXCTL_MUTE_ADC_SP (1 << CS42XX8_TXCTL_MUTE_ADC_SP_SHIFT)
+#define CS42XX8_TXCTL_ADC_SNGVOL_SHIFT 2
+#define CS42XX8_TXCTL_ADC_SNGVOL_MASK (1 << CS42XX8_TXCTL_ADC_SNGVOL_SHIFT)
+#define CS42XX8_TXCTL_ADC_SNGVOL (1 << CS42XX8_TXCTL_ADC_SNGVOL_SHIFT)
+#define CS42XX8_TXCTL_ADC_SZC_SHIFT 0
+#define CS42XX8_TXCTL_ADC_SZC_MASK (((1 << CS42XX8_TXCTL_ADC_SZC_WIDTH) - 1) << CS42XX8_TXCTL_ADC_SZC_SHIFT)
+#define CS42XX8_TXCTL_ADC_SZC_IC (0 << CS42XX8_TXCTL_ADC_SZC_SHIFT)
+#define CS42XX8_TXCTL_ADC_SZC_ZC (1 << CS42XX8_TXCTL_ADC_SZC_SHIFT)
+#define CS42XX8_TXCTL_ADC_SZC_SR (2 << CS42XX8_TXCTL_ADC_SZC_SHIFT)
+#define CS42XX8_TXCTL_ADC_SZC_SRZC (3 << CS42XX8_TXCTL_ADC_SZC_SHIFT)
+
+/* DAC Channel Mute (Address 07h) */
+#define CS42XX8_DACMUTE_AOUT(n) (0x1 << n)
+#define CS42XX8_DACMUTE_ALL 0xff
+
+/* Status Control (Address 18h)*/
+#define CS42XX8_STATUSCTL_INI_SHIFT 2
+#define CS42XX8_STATUSCTL_INI_WIDTH 2
+#define CS42XX8_STATUSCTL_INI_MASK (((1 << CS42XX8_STATUSCTL_INI_WIDTH) - 1) << CS42XX8_STATUSCTL_INI_SHIFT)
+#define CS42XX8_STATUSCTL_INT_ACTIVE_HIGH (0 << CS42XX8_STATUSCTL_INI_SHIFT)
+#define CS42XX8_STATUSCTL_INT_ACTIVE_LOW (1 << CS42XX8_STATUSCTL_INI_SHIFT)
+#define CS42XX8_STATUSCTL_INT_OPEN_DRAIN (2 << CS42XX8_STATUSCTL_INI_SHIFT)
+
+/* Status (Address 19h)*/
+#define CS42XX8_STATUS_DAC_CLK_ERR_SHIFT 4
+#define CS42XX8_STATUS_DAC_CLK_ERR_MASK (1 << CS42XX8_STATUS_DAC_CLK_ERR_SHIFT)
+#define CS42XX8_STATUS_ADC_CLK_ERR_SHIFT 3
+#define CS42XX8_STATUS_ADC_CLK_ERR_MASK (1 << CS42XX8_STATUS_ADC_CLK_ERR_SHIFT)
+#define CS42XX8_STATUS_ADC3_OVFL_SHIFT 2
+#define CS42XX8_STATUS_ADC3_OVFL_MASK (1 << CS42XX8_STATUS_ADC3_OVFL_SHIFT)
+#define CS42XX8_STATUS_ADC2_OVFL_SHIFT 1
+#define CS42XX8_STATUS_ADC2_OVFL_MASK (1 << CS42XX8_STATUS_ADC2_OVFL_SHIFT)
+#define CS42XX8_STATUS_ADC1_OVFL_SHIFT 0
+#define CS42XX8_STATUS_ADC1_OVFL_MASK (1 << CS42XX8_STATUS_ADC1_OVFL_SHIFT)
+
+/* Status Mask (Address 1Ah) */
+#define CS42XX8_STATUS_DAC_CLK_ERR_M_SHIFT 4
+#define CS42XX8_STATUS_DAC_CLK_ERR_M_MASK (1 << CS42XX8_STATUS_DAC_CLK_ERR_M_SHIFT)
+#define CS42XX8_STATUS_ADC_CLK_ERR_M_SHIFT 3
+#define CS42XX8_STATUS_ADC_CLK_ERR_M_MASK (1 << CS42XX8_STATUS_ADC_CLK_ERR_M_SHIFT)
+#define CS42XX8_STATUS_ADC3_OVFL_M_SHIFT 2
+#define CS42XX8_STATUS_ADC3_OVFL_M_MASK (1 << CS42XX8_STATUS_ADC3_OVFL_M_SHIFT)
+#define CS42XX8_STATUS_ADC2_OVFL_M_SHIFT 1
+#define CS42XX8_STATUS_ADC2_OVFL_M_MASK (1 << CS42XX8_STATUS_ADC2_OVFL_M_SHIFT)
+#define CS42XX8_STATUS_ADC1_OVFL_M_SHIFT 0
+#define CS42XX8_STATUS_ADC1_OVFL_M_MASK (1 << CS42XX8_STATUS_ADC1_OVFL_M_SHIFT)
+
+/* MUTEC Pin Control (Address 1Bh) */
+#define CS42XX8_MUTEC_MCPOLARITY_SHIFT 1
+#define CS42XX8_MUTEC_MCPOLARITY_MASK (1 << CS42XX8_MUTEC_MCPOLARITY_SHIFT)
+#define CS42XX8_MUTEC_MCPOLARITY_ACTIVE_LOW (0 << CS42XX8_MUTEC_MCPOLARITY_SHIFT)
+#define CS42XX8_MUTEC_MCPOLARITY_ACTIVE_HIGH (1 << CS42XX8_MUTEC_MCPOLARITY_SHIFT)
+#define CS42XX8_MUTEC_MUTEC_ACTIVE_SHIFT 0
+#define CS42XX8_MUTEC_MUTEC_ACTIVE_MASK (1 << CS42XX8_MUTEC_MUTEC_ACTIVE_SHIFT)
+#define CS42XX8_MUTEC_MUTEC_ACTIVE (1 << CS42XX8_MUTEC_MUTEC_ACTIVE_SHIFT)
+#endif /* _CS42XX8_H */
diff --git a/sound/soc/codecs/rpmsg_wm8960.c b/sound/soc/codecs/rpmsg_wm8960.c
new file mode 100644
index 000000000000..644a1eea13ab
--- /dev/null
+++ b/sound/soc/codecs/rpmsg_wm8960.c
@@ -0,0 +1,1542 @@
+/*
+ * Copyright 2018 NXP
+ *
+ * Copyright 2007-11 Wolfson Microelectronics, plc
+ *
+ * Author: Liam Girdwood
+ *
+ * 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.
+ */
+#include <linux/clk.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/pm_runtime.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/tlv.h>
+#include <sound/wm8960.h>
+#include "../fsl/fsl_rpmsg_i2s.h"
+#include "wm8960.h"
+
+/* R25 - Power 1 */
+#define WM8960_VMID_MASK 0x180
+#define WM8960_VREF 0x40
+
+/* R26 - Power 2 */
+#define WM8960_PWR2_LOUT1 0x40
+#define WM8960_PWR2_ROUT1 0x20
+#define WM8960_PWR2_OUT3 0x02
+
+/* R28 - Anti-pop 1 */
+#define WM8960_POBCTRL 0x80
+#define WM8960_BUFDCOPEN 0x10
+#define WM8960_BUFIOEN 0x08
+#define WM8960_SOFT_ST 0x04
+#define WM8960_HPSTBY 0x01
+
+/* R29 - Anti-pop 2 */
+#define WM8960_DISOP 0x40
+#define WM8960_DRES_MASK 0x30
+
+static bool is_pll_freq_available(unsigned int source, unsigned int target);
+static int wm8960_set_pll(struct snd_soc_codec *codec,
+ unsigned int freq_in, unsigned int freq_out);
+/*
+ * wm8960 register cache
+ * We can't read the WM8960 register space when we are
+ * using 2 wire for device control, so we cache them instead.
+ */
+static const struct reg_default wm8960_reg_defaults[] = {
+ { 0x0, 0x00a7 },
+ { 0x1, 0x00a7 },
+ { 0x2, 0x0000 },
+ { 0x3, 0x0000 },
+ { 0x4, 0x0000 },
+ { 0x5, 0x0008 },
+ { 0x6, 0x0000 },
+ { 0x7, 0x000a },
+ { 0x8, 0x01c0 },
+ { 0x9, 0x0000 },
+ { 0xa, 0x00ff },
+ { 0xb, 0x00ff },
+
+ { 0x10, 0x0000 },
+ { 0x11, 0x007b },
+ { 0x12, 0x0100 },
+ { 0x13, 0x0032 },
+ { 0x14, 0x0000 },
+ { 0x15, 0x00c3 },
+ { 0x16, 0x00c3 },
+ { 0x17, 0x01c0 },
+ { 0x18, 0x0000 },
+ { 0x19, 0x0000 },
+ { 0x1a, 0x0000 },
+ { 0x1b, 0x0000 },
+ { 0x1c, 0x0000 },
+ { 0x1d, 0x0000 },
+
+ { 0x20, 0x0100 },
+ { 0x21, 0x0100 },
+ { 0x22, 0x0050 },
+
+ { 0x25, 0x0050 },
+ { 0x26, 0x0000 },
+ { 0x27, 0x0000 },
+ { 0x28, 0x0000 },
+ { 0x29, 0x0000 },
+ { 0x2a, 0x0040 },
+ { 0x2b, 0x0000 },
+ { 0x2c, 0x0000 },
+ { 0x2d, 0x0050 },
+ { 0x2e, 0x0050 },
+ { 0x2f, 0x0000 },
+ { 0x30, 0x0002 },
+ { 0x31, 0x0037 },
+
+ { 0x33, 0x0080 },
+ { 0x34, 0x0008 },
+ { 0x35, 0x0031 },
+ { 0x36, 0x0026 },
+ { 0x37, 0x00e9 },
+};
+
+struct rpmsg_wm8960_priv {
+ struct clk *mclk;
+ struct regmap *regmap;
+ int (*set_bias_level)(struct snd_soc_codec *,
+ enum snd_soc_bias_level level);
+ struct snd_soc_dapm_widget *lout1;
+ struct snd_soc_dapm_widget *rout1;
+ struct snd_soc_dapm_widget *out3;
+ bool deemph;
+ int lrclk;
+ int bclk;
+ int sysclk;
+ int clk_id;
+ int freq_in;
+ bool is_stream_in_use[2];
+ struct wm8960_data pdata;
+ struct fsl_rpmsg_i2s *rpmsg_i2s;
+ int audioindex;
+};
+
+static bool wm8960_volatile(struct device *dev, unsigned int reg)
+{
+ struct rpmsg_wm8960_priv *wm8960 = dev_get_drvdata(dev);
+
+ if (!wm8960->mclk)
+ return true;
+
+ switch (reg) {
+ case WM8960_RESET:
+ return true;
+ default:
+ return false;
+ }
+}
+
+#define wm8960_reset(c) regmap_write(c, WM8960_RESET, 0)
+
+/* enumerated controls */
+static const char * const wm8960_polarity[] = {"No Inversion", "Left Inverted",
+ "Right Inverted", "Stereo Inversion"};
+static const char * const wm8960_3d_upper_cutoff[] = {"High", "Low"};
+static const char * const wm8960_3d_lower_cutoff[] = {"Low", "High"};
+static const char * const wm8960_alcfunc[] = {"Off", "Right", "Left", "Stereo"};
+static const char * const wm8960_alcmode[] = {"ALC", "Limiter"};
+static const char * const wm8960_adc_data_output_sel[] = {
+ "Left Data = Left ADC; Right Data = Right ADC",
+ "Left Data = Left ADC; Right Data = Left ADC",
+ "Left Data = Right ADC; Right Data = Right ADC",
+ "Left Data = Right ADC; Right Data = Left ADC",
+};
+static const char * const wm8960_dmonomix[] = {"Stereo", "Mono"};
+
+static const struct soc_enum wm8960_enum[] = {
+ SOC_ENUM_SINGLE(WM8960_DACCTL1, 5, 4, wm8960_polarity),
+ SOC_ENUM_SINGLE(WM8960_DACCTL2, 5, 4, wm8960_polarity),
+ SOC_ENUM_SINGLE(WM8960_3D, 6, 2, wm8960_3d_upper_cutoff),
+ SOC_ENUM_SINGLE(WM8960_3D, 5, 2, wm8960_3d_lower_cutoff),
+ SOC_ENUM_SINGLE(WM8960_ALC1, 7, 4, wm8960_alcfunc),
+ SOC_ENUM_SINGLE(WM8960_ALC3, 8, 2, wm8960_alcmode),
+ SOC_ENUM_SINGLE(WM8960_ADDCTL1, 2, 4, wm8960_adc_data_output_sel),
+ SOC_ENUM_SINGLE(WM8960_ADDCTL1, 4, 2, wm8960_dmonomix),
+};
+
+static const int deemph_settings[] = { 0, 32000, 44100, 48000 };
+
+static int wm8960_set_deemph(struct snd_soc_codec *codec)
+{
+ struct rpmsg_wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
+ int val, i, best;
+
+ /* If we're using deemphasis select the nearest available sample
+ * rate.
+ */
+ if (wm8960->deemph) {
+ best = 1;
+ for (i = 2; i < ARRAY_SIZE(deemph_settings); i++) {
+ if (abs(deemph_settings[i] - wm8960->lrclk) <
+ abs(deemph_settings[best] - wm8960->lrclk))
+ best = i;
+ }
+
+ val = best << 1;
+ } else {
+ val = 0;
+ }
+
+ dev_dbg(codec->dev, "Set deemphasis %d\n", val);
+
+ return snd_soc_update_bits(codec, WM8960_DACCTL1,
+ 0x6, val);
+}
+
+static int wm8960_get_deemph(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+ struct rpmsg_wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
+
+ ucontrol->value.integer.value[0] = wm8960->deemph;
+ return 0;
+}
+
+static int wm8960_put_deemph(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+ struct rpmsg_wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
+ unsigned int deemph = ucontrol->value.integer.value[0];
+
+ if (deemph > 1)
+ return -EINVAL;
+
+ wm8960->deemph = deemph;
+
+ return wm8960_set_deemph(codec);
+}
+
+static const DECLARE_TLV_DB_SCALE(adc_tlv, -9750, 50, 1);
+static const DECLARE_TLV_DB_SCALE(inpga_tlv, -1725, 75, 0);
+static const DECLARE_TLV_DB_SCALE(dac_tlv, -12750, 50, 1);
+static const DECLARE_TLV_DB_SCALE(bypass_tlv, -2100, 300, 0);
+static const DECLARE_TLV_DB_SCALE(out_tlv, -12100, 100, 1);
+static const DECLARE_TLV_DB_SCALE(lineinboost_tlv, -1500, 300, 1);
+static const SNDRV_CTL_TLVD_DECLARE_DB_RANGE(micboost_tlv,
+ 0, 1, TLV_DB_SCALE_ITEM(0, 1300, 0),
+ 2, 3, TLV_DB_SCALE_ITEM(2000, 900, 0),
+);
+
+static const struct snd_kcontrol_new wm8960_snd_controls[] = {
+SOC_DOUBLE_R_TLV("Capture Volume", WM8960_LINVOL, WM8960_RINVOL,
+ 0, 63, 0, inpga_tlv),
+SOC_DOUBLE_R("Capture Volume ZC Switch", WM8960_LINVOL, WM8960_RINVOL,
+ 6, 1, 0),
+SOC_DOUBLE_R("Capture Switch", WM8960_LINVOL, WM8960_RINVOL,
+ 7, 1, 1),
+
+SOC_SINGLE_TLV("Left Input Boost Mixer LINPUT3 Volume",
+ WM8960_INBMIX1, 4, 7, 0, lineinboost_tlv),
+SOC_SINGLE_TLV("Left Input Boost Mixer LINPUT2 Volume",
+ WM8960_INBMIX1, 1, 7, 0, lineinboost_tlv),
+SOC_SINGLE_TLV("Right Input Boost Mixer RINPUT3 Volume",
+ WM8960_INBMIX2, 4, 7, 0, lineinboost_tlv),
+SOC_SINGLE_TLV("Right Input Boost Mixer RINPUT2 Volume",
+ WM8960_INBMIX2, 1, 7, 0, lineinboost_tlv),
+SOC_SINGLE_TLV("Right Input Boost Mixer RINPUT1 Volume",
+ WM8960_RINPATH, 4, 3, 0, micboost_tlv),
+SOC_SINGLE_TLV("Left Input Boost Mixer LINPUT1 Volume",
+ WM8960_LINPATH, 4, 3, 0, micboost_tlv),
+
+SOC_DOUBLE_R_TLV("Playback Volume", WM8960_LDAC, WM8960_RDAC,
+ 0, 255, 0, dac_tlv),
+
+SOC_DOUBLE_R_TLV("Headphone Playback Volume", WM8960_LOUT1, WM8960_ROUT1,
+ 0, 127, 0, out_tlv),
+SOC_DOUBLE_R("Headphone Playback ZC Switch", WM8960_LOUT1, WM8960_ROUT1,
+ 7, 1, 0),
+
+SOC_DOUBLE_R_TLV("Speaker Playback Volume", WM8960_LOUT2, WM8960_ROUT2,
+ 0, 127, 0, out_tlv),
+SOC_DOUBLE_R("Speaker Playback ZC Switch", WM8960_LOUT2, WM8960_ROUT2,
+ 7, 1, 0),
+SOC_SINGLE("Speaker DC Volume", WM8960_CLASSD3, 3, 5, 0),
+SOC_SINGLE("Speaker AC Volume", WM8960_CLASSD3, 0, 5, 0),
+
+SOC_SINGLE("PCM Playback -6dB Switch", WM8960_DACCTL1, 7, 1, 0),
+SOC_ENUM("ADC Polarity", wm8960_enum[0]),
+SOC_SINGLE("ADC High Pass Filter Switch", WM8960_DACCTL1, 0, 1, 0),
+
+SOC_ENUM("DAC Polarity", wm8960_enum[1]),
+SOC_SINGLE_BOOL_EXT("DAC Deemphasis Switch", 0,
+ wm8960_get_deemph, wm8960_put_deemph),
+
+SOC_ENUM("3D Filter Upper Cut-Off", wm8960_enum[2]),
+SOC_ENUM("3D Filter Lower Cut-Off", wm8960_enum[3]),
+SOC_SINGLE("3D Volume", WM8960_3D, 1, 15, 0),
+SOC_SINGLE("3D Switch", WM8960_3D, 0, 1, 0),
+
+SOC_ENUM("ALC Function", wm8960_enum[4]),
+SOC_SINGLE("ALC Max Gain", WM8960_ALC1, 4, 7, 0),
+SOC_SINGLE("ALC Target", WM8960_ALC1, 0, 15, 1),
+SOC_SINGLE("ALC Min Gain", WM8960_ALC2, 4, 7, 0),
+SOC_SINGLE("ALC Hold Time", WM8960_ALC2, 0, 15, 0),
+SOC_ENUM("ALC Mode", wm8960_enum[5]),
+SOC_SINGLE("ALC Decay", WM8960_ALC3, 4, 15, 0),
+SOC_SINGLE("ALC Attack", WM8960_ALC3, 0, 15, 0),
+
+SOC_SINGLE("Noise Gate Threshold", WM8960_NOISEG, 3, 31, 0),
+SOC_SINGLE("Noise Gate Switch", WM8960_NOISEG, 0, 1, 0),
+
+SOC_DOUBLE_R_TLV("ADC PCM Capture Volume", WM8960_LADC, WM8960_RADC,
+ 0, 255, 0, adc_tlv),
+
+SOC_SINGLE_TLV("Left Output Mixer Boost Bypass Volume",
+ WM8960_BYPASS1, 4, 7, 1, bypass_tlv),
+SOC_SINGLE_TLV("Left Output Mixer LINPUT3 Volume",
+ WM8960_LOUTMIX, 4, 7, 1, bypass_tlv),
+SOC_SINGLE_TLV("Right Output Mixer Boost Bypass Volume",
+ WM8960_BYPASS2, 4, 7, 1, bypass_tlv),
+SOC_SINGLE_TLV("Right Output Mixer RINPUT3 Volume",
+ WM8960_ROUTMIX, 4, 7, 1, bypass_tlv),
+
+SOC_ENUM("ADC Data Output Select", wm8960_enum[6]),
+SOC_ENUM("DAC Mono Mix", wm8960_enum[7]),
+};
+
+static const struct snd_kcontrol_new wm8960_lin_boost[] = {
+SOC_DAPM_SINGLE("LINPUT2 Switch", WM8960_LINPATH, 6, 1, 0),
+SOC_DAPM_SINGLE("LINPUT3 Switch", WM8960_LINPATH, 7, 1, 0),
+SOC_DAPM_SINGLE("LINPUT1 Switch", WM8960_LINPATH, 8, 1, 0),
+};
+
+static const struct snd_kcontrol_new wm8960_lin[] = {
+SOC_DAPM_SINGLE("Boost Switch", WM8960_LINPATH, 3, 1, 0),
+};
+
+static const struct snd_kcontrol_new wm8960_rin_boost[] = {
+SOC_DAPM_SINGLE("RINPUT2 Switch", WM8960_RINPATH, 6, 1, 0),
+SOC_DAPM_SINGLE("RINPUT3 Switch", WM8960_RINPATH, 7, 1, 0),
+SOC_DAPM_SINGLE("RINPUT1 Switch", WM8960_RINPATH, 8, 1, 0),
+};
+
+static const struct snd_kcontrol_new wm8960_rin[] = {
+SOC_DAPM_SINGLE("Boost Switch", WM8960_RINPATH, 3, 1, 0),
+};
+
+static const struct snd_kcontrol_new wm8960_loutput_mixer[] = {
+SOC_DAPM_SINGLE("PCM Playback Switch", WM8960_LOUTMIX, 8, 1, 0),
+SOC_DAPM_SINGLE("LINPUT3 Switch", WM8960_LOUTMIX, 7, 1, 0),
+SOC_DAPM_SINGLE("Boost Bypass Switch", WM8960_BYPASS1, 7, 1, 0),
+};
+
+static const struct snd_kcontrol_new wm8960_routput_mixer[] = {
+SOC_DAPM_SINGLE("PCM Playback Switch", WM8960_ROUTMIX, 8, 1, 0),
+SOC_DAPM_SINGLE("RINPUT3 Switch", WM8960_ROUTMIX, 7, 1, 0),
+SOC_DAPM_SINGLE("Boost Bypass Switch", WM8960_BYPASS2, 7, 1, 0),
+};
+
+static const struct snd_kcontrol_new wm8960_mono_out[] = {
+SOC_DAPM_SINGLE("Left Switch", WM8960_MONOMIX1, 7, 1, 0),
+SOC_DAPM_SINGLE("Right Switch", WM8960_MONOMIX2, 7, 1, 0),
+};
+
+static const struct snd_soc_dapm_widget wm8960_dapm_widgets[] = {
+SND_SOC_DAPM_INPUT("LINPUT1"),
+SND_SOC_DAPM_INPUT("RINPUT1"),
+SND_SOC_DAPM_INPUT("LINPUT2"),
+SND_SOC_DAPM_INPUT("RINPUT2"),
+SND_SOC_DAPM_INPUT("LINPUT3"),
+SND_SOC_DAPM_INPUT("RINPUT3"),
+
+SND_SOC_DAPM_SUPPLY("MICB", WM8960_POWER1, 1, 0, NULL, 0),
+
+SND_SOC_DAPM_MIXER("Left Boost Mixer", WM8960_POWER1, 5, 0,
+ wm8960_lin_boost, ARRAY_SIZE(wm8960_lin_boost)),
+SND_SOC_DAPM_MIXER("Right Boost Mixer", WM8960_POWER1, 4, 0,
+ wm8960_rin_boost, ARRAY_SIZE(wm8960_rin_boost)),
+
+SND_SOC_DAPM_MIXER("Left Input Mixer", WM8960_POWER3, 5, 0,
+ wm8960_lin, ARRAY_SIZE(wm8960_lin)),
+SND_SOC_DAPM_MIXER("Right Input Mixer", WM8960_POWER3, 4, 0,
+ wm8960_rin, ARRAY_SIZE(wm8960_rin)),
+
+SND_SOC_DAPM_ADC("Left ADC", "Capture", WM8960_POWER1, 3, 0),
+SND_SOC_DAPM_ADC("Right ADC", "Capture", WM8960_POWER1, 2, 0),
+
+SND_SOC_DAPM_DAC("Left DAC", "Playback", WM8960_POWER2, 8, 0),
+SND_SOC_DAPM_DAC("Right DAC", "Playback", WM8960_POWER2, 7, 0),
+
+SND_SOC_DAPM_MIXER("Left Output Mixer", WM8960_POWER3, 3, 0,
+ &wm8960_loutput_mixer[0],
+ ARRAY_SIZE(wm8960_loutput_mixer)),
+SND_SOC_DAPM_MIXER("Right Output Mixer", WM8960_POWER3, 2, 0,
+ &wm8960_routput_mixer[0],
+ ARRAY_SIZE(wm8960_routput_mixer)),
+
+SND_SOC_DAPM_PGA("LOUT1 PGA", WM8960_POWER2, 6, 0, NULL, 0),
+SND_SOC_DAPM_PGA("ROUT1 PGA", WM8960_POWER2, 5, 0, NULL, 0),
+
+SND_SOC_DAPM_PGA("Left Speaker PGA", WM8960_POWER2, 4, 0, NULL, 0),
+SND_SOC_DAPM_PGA("Right Speaker PGA", WM8960_POWER2, 3, 0, NULL, 0),
+
+SND_SOC_DAPM_PGA("Right Speaker Output", WM8960_CLASSD1, 7, 0, NULL, 0),
+SND_SOC_DAPM_PGA("Left Speaker Output", WM8960_CLASSD1, 6, 0, NULL, 0),
+
+SND_SOC_DAPM_OUTPUT("SPK_LP"),
+SND_SOC_DAPM_OUTPUT("SPK_LN"),
+SND_SOC_DAPM_OUTPUT("HP_L"),
+SND_SOC_DAPM_OUTPUT("HP_R"),
+SND_SOC_DAPM_OUTPUT("SPK_RP"),
+SND_SOC_DAPM_OUTPUT("SPK_RN"),
+SND_SOC_DAPM_OUTPUT("OUT3"),
+};
+
+static const struct snd_soc_dapm_widget wm8960_dapm_widgets_out3[] = {
+SND_SOC_DAPM_MIXER("Mono Output Mixer", WM8960_POWER2, 1, 0,
+ &wm8960_mono_out[0],
+ ARRAY_SIZE(wm8960_mono_out)),
+};
+
+/* Represent OUT3 as a PGA so that it gets turned on with LOUT1/ROUT1 */
+static const struct snd_soc_dapm_widget wm8960_dapm_widgets_capless[] = {
+SND_SOC_DAPM_PGA("OUT3 VMID", WM8960_POWER2, 1, 0, NULL, 0),
+};
+
+static const struct snd_soc_dapm_route audio_paths[] = {
+ { "Left Boost Mixer", "LINPUT1 Switch", "LINPUT1" },
+ { "Left Boost Mixer", "LINPUT2 Switch", "LINPUT2" },
+ { "Left Boost Mixer", "LINPUT3 Switch", "LINPUT3" },
+
+ { "Left Input Mixer", "Boost Switch", "Left Boost Mixer" },
+ { "Left Input Mixer", "Boost Switch", "LINPUT1" }, /* Really Boost Switch */
+ { "Left Input Mixer", NULL, "LINPUT2" },
+ { "Left Input Mixer", NULL, "LINPUT3" },
+
+ { "Right Boost Mixer", "RINPUT1 Switch", "RINPUT1" },
+ { "Right Boost Mixer", "RINPUT2 Switch", "RINPUT2" },
+ { "Right Boost Mixer", "RINPUT3 Switch", "RINPUT3" },
+
+ { "Right Input Mixer", "Boost Switch", "Right Boost Mixer" },
+ { "Right Input Mixer", "Boost Switch", "RINPUT1" }, /* Really Boost Switch */
+ { "Right Input Mixer", NULL, "RINPUT2" },
+ { "Right Input Mixer", NULL, "RINPUT3" },
+
+ { "Left ADC", NULL, "Left Input Mixer" },
+ { "Right ADC", NULL, "Right Input Mixer" },
+
+ { "Left Output Mixer", "LINPUT3 Switch", "LINPUT3" },
+ { "Left Output Mixer", "Boost Bypass Switch", "Left Boost Mixer" },
+ { "Left Output Mixer", "PCM Playback Switch", "Left DAC" },
+
+ { "Right Output Mixer", "RINPUT3 Switch", "RINPUT3" },
+ { "Right Output Mixer", "Boost Bypass Switch", "Right Boost Mixer" },
+ { "Right Output Mixer", "PCM Playback Switch", "Right DAC" },
+
+ { "LOUT1 PGA", NULL, "Left Output Mixer" },
+ { "ROUT1 PGA", NULL, "Right Output Mixer" },
+
+ { "HP_L", NULL, "LOUT1 PGA" },
+ { "HP_R", NULL, "ROUT1 PGA" },
+
+ { "Left Speaker PGA", NULL, "Left Output Mixer" },
+ { "Right Speaker PGA", NULL, "Right Output Mixer" },
+
+ { "Left Speaker Output", NULL, "Left Speaker PGA" },
+ { "Right Speaker Output", NULL, "Right Speaker PGA" },
+
+ { "SPK_LN", NULL, "Left Speaker Output" },
+ { "SPK_LP", NULL, "Left Speaker Output" },
+ { "SPK_RN", NULL, "Right Speaker Output" },
+ { "SPK_RP", NULL, "Right Speaker Output" },
+};
+
+static const struct snd_soc_dapm_route audio_paths_out3[] = {
+ { "Mono Output Mixer", "Left Switch", "Left Output Mixer" },
+ { "Mono Output Mixer", "Right Switch", "Right Output Mixer" },
+
+ { "OUT3", NULL, "Mono Output Mixer", }
+};
+
+static const struct snd_soc_dapm_route audio_paths_capless[] = {
+ { "HP_L", NULL, "OUT3 VMID" },
+ { "HP_R", NULL, "OUT3 VMID" },
+
+ { "OUT3 VMID", NULL, "Left Output Mixer" },
+ { "OUT3 VMID", NULL, "Right Output Mixer" },
+};
+
+static int wm8960_add_widgets(struct snd_soc_codec *codec)
+{
+ struct rpmsg_wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
+ struct wm8960_data *pdata = &wm8960->pdata;
+ struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
+ struct snd_soc_dapm_widget *w;
+
+ snd_soc_dapm_new_controls(dapm, wm8960_dapm_widgets,
+ ARRAY_SIZE(wm8960_dapm_widgets));
+
+ snd_soc_dapm_add_routes(dapm, audio_paths, ARRAY_SIZE(audio_paths));
+
+ /* In capless mode OUT3 is used to provide VMID for the
+ * headphone outputs, otherwise it is used as a mono mixer.
+ */
+ if (pdata && pdata->capless) {
+ snd_soc_dapm_new_controls(dapm, wm8960_dapm_widgets_capless,
+ ARRAY_SIZE(wm8960_dapm_widgets_capless));
+
+ snd_soc_dapm_add_routes(dapm, audio_paths_capless,
+ ARRAY_SIZE(audio_paths_capless));
+ } else {
+ snd_soc_dapm_new_controls(dapm, wm8960_dapm_widgets_out3,
+ ARRAY_SIZE(wm8960_dapm_widgets_out3));
+
+ snd_soc_dapm_add_routes(dapm, audio_paths_out3,
+ ARRAY_SIZE(audio_paths_out3));
+ }
+
+ /* We need to power up the headphone output stage out of
+ * sequence for capless mode. To save scanning the widget
+ * list each time to find the desired power state do so now
+ * and save the result.
+ */
+ list_for_each_entry(w, &codec->component.card->widgets, list) {
+ if (w->dapm != dapm)
+ continue;
+ if (strcmp(w->name, "LOUT1 PGA") == 0)
+ wm8960->lout1 = w;
+ if (strcmp(w->name, "ROUT1 PGA") == 0)
+ wm8960->rout1 = w;
+ if (strcmp(w->name, "OUT3 VMID") == 0)
+ wm8960->out3 = w;
+ }
+
+ return 0;
+}
+
+static int wm8960_set_dai_fmt(struct snd_soc_dai *codec_dai,
+ unsigned int fmt)
+{
+ struct snd_soc_codec *codec = codec_dai->codec;
+ u16 iface = 0;
+
+ /* set master/slave audio interface */
+ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+ case SND_SOC_DAIFMT_CBM_CFM:
+ iface |= 0x0040;
+ break;
+ case SND_SOC_DAIFMT_CBS_CFS:
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ /* interface format */
+ switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+ case SND_SOC_DAIFMT_I2S:
+ iface |= 0x0002;
+ break;
+ case SND_SOC_DAIFMT_RIGHT_J:
+ break;
+ case SND_SOC_DAIFMT_LEFT_J:
+ iface |= 0x0001;
+ break;
+ case SND_SOC_DAIFMT_DSP_A:
+ iface |= 0x0003;
+ break;
+ case SND_SOC_DAIFMT_DSP_B:
+ iface |= 0x0013;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ /* clock inversion */
+ switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
+ case SND_SOC_DAIFMT_NB_NF:
+ break;
+ case SND_SOC_DAIFMT_IB_IF:
+ iface |= 0x0090;
+ break;
+ case SND_SOC_DAIFMT_IB_NF:
+ iface |= 0x0080;
+ break;
+ case SND_SOC_DAIFMT_NB_IF:
+ iface |= 0x0010;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ /* set iface */
+ snd_soc_write(codec, WM8960_IFACE1, iface);
+ return 0;
+}
+
+static struct {
+ int rate;
+ unsigned int val;
+} alc_rates[] = {
+ { 48000, 0 },
+ { 44100, 0 },
+ { 32000, 1 },
+ { 22050, 2 },
+ { 24000, 2 },
+ { 16000, 3 },
+ { 11025, 4 },
+ { 12000, 4 },
+ { 8000, 5 },
+};
+
+/* -1 for reserved value */
+static const int sysclk_divs[] = { 1, -1, 2, -1 };
+
+/* Multiply 256 for internal 256 div */
+static const int dac_divs[] = { 256, 384, 512, 768, 1024, 1408, 1536 };
+
+/* Multiply 10 to eliminate decimials */
+static const int bclk_divs[] = {
+ 10, 15, 20, 30, 40, 55, 60, 80, 110,
+ 120, 160, 220, 240, 320, 320, 320
+};
+
+/**
+ * wm8960_configure_sysclk - checks if there is a sysclk frequency available
+ * The sysclk must be chosen such that:
+ * - sysclk = MCLK / sysclk_divs
+ * - lrclk = sysclk / dac_divs
+ * - 10 * bclk = sysclk / bclk_divs
+ *
+ * @wm8960_priv: wm8960 codec private data
+ * @mclk: MCLK used to derive sysclk
+ * @sysclk_idx: sysclk_divs index for found sysclk
+ * @dac_idx: dac_divs index for found lrclk
+ * @bclk_idx: bclk_divs index for found bclk
+ *
+ * Returns:
+ * -1, in case no sysclk frequency available found
+ * >=0, in case we could derive bclk and lrclk from sysclk using
+ * (@sysclk_idx, @dac_idx, @bclk_idx) dividers
+ */
+static
+int wm8960_configure_sysclk(struct rpmsg_wm8960_priv *wm8960, int mclk,
+ int *sysclk_idx, int *dac_idx, int *bclk_idx)
+{
+ int sysclk, bclk, lrclk;
+ int i, j, k;
+ int diff;
+
+ /* marker for no match */
+ *bclk_idx = -1;
+
+ bclk = wm8960->bclk;
+ lrclk = wm8960->lrclk;
+
+ /* check if the sysclk frequency is available. */
+ for (i = 0; i < ARRAY_SIZE(sysclk_divs); ++i) {
+ if (sysclk_divs[i] == -1)
+ continue;
+ sysclk = mclk / sysclk_divs[i];
+ for (j = 0; j < ARRAY_SIZE(dac_divs); ++j) {
+ if (sysclk != dac_divs[j] * lrclk)
+ continue;
+ for (k = 0; k < ARRAY_SIZE(bclk_divs); ++k) {
+ diff = sysclk - bclk * bclk_divs[k] / 10;
+ if (diff == 0) {
+ *sysclk_idx = i;
+ *dac_idx = j;
+ *bclk_idx = k;
+ break;
+ }
+ }
+ if (k != ARRAY_SIZE(bclk_divs))
+ break;
+ }
+ if (j != ARRAY_SIZE(dac_divs))
+ break;
+ }
+ return *bclk_idx;
+}
+
+/**
+ * wm8960_configure_pll - checks if there is a PLL out frequency available
+ * The PLL out frequency must be chosen such that:
+ * - sysclk = lrclk * dac_divs
+ * - freq_out = sysclk * sysclk_divs
+ * - 10 * sysclk = bclk * bclk_divs
+ *
+ * @codec: codec structure
+ * @freq_in: input frequency used to derive freq out via PLL
+ * @sysclk_idx: sysclk_divs index for found sysclk
+ * @dac_idx: dac_divs index for found lrclk
+ * @bclk_idx: bclk_divs index for found bclk
+ *
+ * Returns:
+ * -1, in case no PLL frequency out available was found
+ * >=0, in case we could derive bclk, lrclk, sysclk from PLL out using
+ * (@sysclk_idx, @dac_idx, @bclk_idx) dividers
+ */
+static
+int wm8960_configure_pll(struct snd_soc_codec *codec, int freq_in,
+ int *sysclk_idx, int *dac_idx, int *bclk_idx)
+{
+ struct rpmsg_wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
+ int sysclk, bclk, lrclk, freq_out;
+ int diff, best_freq_out = 0;
+ int i, j, k;
+
+ bclk = wm8960->bclk;
+ lrclk = wm8960->lrclk;
+
+ *bclk_idx = *dac_idx = *sysclk_idx = -1;
+
+ for (i = 0; i < ARRAY_SIZE(sysclk_divs); ++i) {
+ if (sysclk_divs[i] == -1)
+ continue;
+ for (j = 0; j < ARRAY_SIZE(dac_divs); ++j) {
+ sysclk = lrclk * dac_divs[j];
+ freq_out = sysclk * sysclk_divs[i];
+
+ for (k = 0; k < ARRAY_SIZE(bclk_divs); ++k) {
+ if (!is_pll_freq_available(freq_in, freq_out))
+ continue;
+
+ diff = sysclk - bclk * bclk_divs[k] / 10;
+ if (diff == 0) {
+ *sysclk_idx = i;
+ *dac_idx = j;
+ *bclk_idx = k;
+ best_freq_out = freq_out;
+ break;
+ }
+ }
+ if (k != ARRAY_SIZE(bclk_divs))
+ break;
+ }
+ if (j != ARRAY_SIZE(dac_divs))
+ break;
+ }
+
+ if (*bclk_idx != -1)
+ wm8960_set_pll(codec, freq_in, best_freq_out);
+
+ return *bclk_idx;
+}
+static int wm8960_configure_clocking(struct snd_soc_codec *codec)
+{
+ struct rpmsg_wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
+ int freq_out, freq_in;
+ u16 iface1 = snd_soc_read(codec, WM8960_IFACE1);
+ int i, j, k;
+ int ret;
+
+ if (!(iface1 & (1<<6))) {
+ dev_dbg(codec->dev,
+ "Codec is slave mode, no need to configure clock\n");
+ return 0;
+ }
+
+ if (wm8960->clk_id != WM8960_SYSCLK_MCLK && !wm8960->freq_in) {
+ dev_err(codec->dev, "No MCLK configured\n");
+ return -EINVAL;
+ }
+
+ freq_in = wm8960->freq_in;
+ /*
+ * If it's sysclk auto mode, check if the MCLK can provide sysclk or
+ * not. If MCLK can provide sysclk, using MCLK to provide sysclk
+ * directly. Otherwise, auto select a available pll out frequency
+ * and set PLL.
+ */
+ if (wm8960->clk_id == WM8960_SYSCLK_AUTO) {
+ /* disable the PLL and using MCLK to provide sysclk */
+ wm8960_set_pll(codec, 0, 0);
+ freq_out = freq_in;
+ } else if (wm8960->sysclk) {
+ freq_out = wm8960->sysclk;
+ } else {
+ dev_err(codec->dev, "No SYSCLK configured\n");
+ return -EINVAL;
+ }
+
+ if (wm8960->clk_id != WM8960_SYSCLK_PLL) {
+ ret = wm8960_configure_sysclk(wm8960, freq_out, &i, &j, &k);
+ if (ret >= 0) {
+ goto configure_clock;
+ } else if (wm8960->clk_id != WM8960_SYSCLK_AUTO) {
+ dev_err(codec->dev, "failed to configure clock\n");
+ return -EINVAL;
+ }
+ }
+
+ ret = wm8960_configure_pll(codec, freq_in, &i, &j, &k);
+ if (ret < 0) {
+ dev_err(codec->dev, "failed to configure clock via PLL\n");
+ return -EINVAL;
+ }
+
+configure_clock:
+ /* configure sysclk clock */
+ snd_soc_update_bits(codec, WM8960_CLOCK1, 3 << 1, i << 1);
+
+ /* configure frame clock */
+ snd_soc_update_bits(codec, WM8960_CLOCK1, 0x7 << 3, j << 3);
+ snd_soc_update_bits(codec, WM8960_CLOCK1, 0x7 << 6, j << 6);
+
+ /* configure bit clock */
+ snd_soc_update_bits(codec, WM8960_CLOCK2, 0xf, k);
+
+ return 0;
+}
+
+static int wm8960_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params,
+ struct snd_soc_dai *dai)
+{
+ struct snd_soc_codec *codec = dai->codec;
+ struct rpmsg_wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
+ u16 iface = snd_soc_read(codec, WM8960_IFACE1) & 0xfff3;
+ bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
+ int i;
+
+ wm8960->bclk = snd_soc_params_to_bclk(params);
+ if (params_channels(params) == 1)
+ wm8960->bclk *= 2;
+
+ /* bit size */
+ switch (params_width(params)) {
+ case 16:
+ break;
+ case 20:
+ iface |= 0x0004;
+ break;
+ case 24:
+ iface |= 0x0008;
+ break;
+ case 32:
+ /* right justify mode does not support 32 word length */
+ if ((iface & 0x3) != 0) {
+ iface |= 0x000c;
+ break;
+ }
+ default:
+ dev_err(codec->dev, "unsupported width %d\n",
+ params_width(params));
+ return -EINVAL;
+ }
+
+ wm8960->lrclk = params_rate(params);
+ /* Update filters for the new rate */
+ if (tx) {
+ wm8960_set_deemph(codec);
+ } else {
+ for (i = 0; i < ARRAY_SIZE(alc_rates); i++)
+ if (alc_rates[i].rate == params_rate(params))
+ snd_soc_update_bits(codec,
+ WM8960_ADDCTL3, 0x7,
+ alc_rates[i].val);
+ }
+
+ /* set iface */
+ snd_soc_write(codec, WM8960_IFACE1, iface);
+
+ wm8960->is_stream_in_use[tx] = true;
+
+ if (!wm8960->is_stream_in_use[!tx])
+ return wm8960_configure_clocking(codec);
+
+ return 0;
+}
+
+static int wm8960_hw_free(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ struct snd_soc_codec *codec = dai->codec;
+ struct rpmsg_wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
+ bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
+
+ wm8960->is_stream_in_use[tx] = false;
+
+ return 0;
+}
+
+static int wm8960_mute(struct snd_soc_dai *dai, int mute)
+{
+ struct snd_soc_codec *codec = dai->codec;
+
+ if (mute)
+ snd_soc_update_bits(codec, WM8960_DACCTL1, 0x8, 0x8);
+ else
+ snd_soc_update_bits(codec, WM8960_DACCTL1, 0x8, 0);
+ return 0;
+}
+
+static int wm8960_set_bias_level_out3(struct snd_soc_codec *codec,
+ enum snd_soc_bias_level level)
+{
+ struct rpmsg_wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
+ u16 pm2 = snd_soc_read(codec, WM8960_POWER2);
+ int ret;
+
+ switch (level) {
+ case SND_SOC_BIAS_ON:
+ break;
+
+ case SND_SOC_BIAS_PREPARE:
+ switch (snd_soc_codec_get_bias_level(codec)) {
+ case SND_SOC_BIAS_STANDBY:
+ if (!IS_ERR(wm8960->mclk)) {
+ ret = clk_prepare_enable(wm8960->mclk);
+ if (ret) {
+ dev_err(codec->dev,
+ "Failed to enable MCLK: %d\n",
+ ret);
+ return ret;
+ }
+ }
+
+ ret = wm8960_configure_clocking(codec);
+ if (ret)
+ return ret;
+
+ /* Set VMID to 2x50k */
+ snd_soc_update_bits(codec, WM8960_POWER1, 0x180, 0x80);
+ break;
+
+ case SND_SOC_BIAS_ON:
+ /*
+ * If it's sysclk auto mode, and the pll is enabled,
+ * disable the pll
+ */
+ if (wm8960->clk_id == WM8960_SYSCLK_AUTO && (pm2 & 0x1))
+ wm8960_set_pll(codec, 0, 0);
+
+ if (!IS_ERR(wm8960->mclk))
+ clk_disable_unprepare(wm8960->mclk);
+ break;
+
+ default:
+ break;
+ }
+
+ break;
+
+ case SND_SOC_BIAS_STANDBY:
+ if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
+ regcache_sync(wm8960->regmap);
+
+ /* Enable anti-pop features */
+ snd_soc_write(codec, WM8960_APOP1,
+ WM8960_POBCTRL | WM8960_SOFT_ST |
+ WM8960_BUFDCOPEN | WM8960_BUFIOEN);
+
+ /* Enable & ramp VMID at 2x50k */
+ snd_soc_update_bits(codec, WM8960_POWER1, 0x80, 0x80);
+ msleep(100);
+
+ /* Enable VREF */
+ snd_soc_update_bits(codec, WM8960_POWER1, WM8960_VREF,
+ WM8960_VREF);
+
+ /* Disable anti-pop features */
+ snd_soc_write(codec, WM8960_APOP1, WM8960_BUFIOEN);
+ }
+
+ /* Set VMID to 2x250k */
+ snd_soc_update_bits(codec, WM8960_POWER1, 0x180, 0x100);
+ break;
+
+ case SND_SOC_BIAS_OFF:
+ /* Enable anti-pop features */
+ snd_soc_write(codec, WM8960_APOP1,
+ WM8960_POBCTRL | WM8960_SOFT_ST |
+ WM8960_BUFDCOPEN | WM8960_BUFIOEN);
+
+ /* Disable VMID and VREF, let them discharge */
+ snd_soc_write(codec, WM8960_POWER1, 0);
+ msleep(600);
+ break;
+ }
+
+ return 0;
+}
+
+static int wm8960_set_bias_level_capless(struct snd_soc_codec *codec,
+ enum snd_soc_bias_level level)
+{
+ struct rpmsg_wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
+ u16 pm2 = snd_soc_read(codec, WM8960_POWER2);
+ int reg, ret;
+
+ switch (level) {
+ case SND_SOC_BIAS_ON:
+ break;
+
+ case SND_SOC_BIAS_PREPARE:
+ switch (snd_soc_codec_get_bias_level(codec)) {
+ case SND_SOC_BIAS_STANDBY:
+ /* Enable anti pop mode */
+ snd_soc_update_bits(codec, WM8960_APOP1,
+ WM8960_POBCTRL | WM8960_SOFT_ST |
+ WM8960_BUFDCOPEN,
+ WM8960_POBCTRL | WM8960_SOFT_ST |
+ WM8960_BUFDCOPEN);
+
+ /* Enable LOUT1, ROUT1 and OUT3 if they're enabled */
+ reg = 0;
+ if (wm8960->lout1 && wm8960->lout1->power)
+ reg |= WM8960_PWR2_LOUT1;
+ if (wm8960->rout1 && wm8960->rout1->power)
+ reg |= WM8960_PWR2_ROUT1;
+ if (wm8960->out3 && wm8960->out3->power)
+ reg |= WM8960_PWR2_OUT3;
+ snd_soc_update_bits(codec, WM8960_POWER2,
+ WM8960_PWR2_LOUT1 |
+ WM8960_PWR2_ROUT1 |
+ WM8960_PWR2_OUT3, reg);
+
+ /* Enable VMID at 2*50k */
+ snd_soc_update_bits(codec, WM8960_POWER1,
+ WM8960_VMID_MASK, 0x80);
+
+ /* Ramp */
+ msleep(100);
+
+ /* Enable VREF */
+ snd_soc_update_bits(codec, WM8960_POWER1,
+ WM8960_VREF, WM8960_VREF);
+
+ msleep(100);
+
+ if (!IS_ERR(wm8960->mclk)) {
+ ret = clk_prepare_enable(wm8960->mclk);
+ if (ret) {
+ dev_err(codec->dev,
+ "Failed to enable MCLK: %d\n",
+ ret);
+ return ret;
+ }
+ }
+
+ ret = wm8960_configure_clocking(codec);
+ if (ret)
+ return ret;
+
+ break;
+
+ case SND_SOC_BIAS_ON:
+ /*
+ * If it's sysclk auto mode, and the pll is enabled,
+ * disable the pll
+ */
+ if (wm8960->clk_id == WM8960_SYSCLK_AUTO && (pm2 & 0x1))
+ wm8960_set_pll(codec, 0, 0);
+
+ if (!IS_ERR(wm8960->mclk))
+ clk_disable_unprepare(wm8960->mclk);
+
+ /* Enable anti-pop mode */
+ snd_soc_update_bits(codec, WM8960_APOP1,
+ WM8960_POBCTRL | WM8960_SOFT_ST |
+ WM8960_BUFDCOPEN,
+ WM8960_POBCTRL | WM8960_SOFT_ST |
+ WM8960_BUFDCOPEN);
+
+ /* Disable VMID and VREF */
+ snd_soc_update_bits(codec, WM8960_POWER1,
+ WM8960_VREF | WM8960_VMID_MASK, 0);
+ break;
+
+ case SND_SOC_BIAS_OFF:
+ regcache_sync(wm8960->regmap);
+ break;
+ default:
+ break;
+ }
+ break;
+
+ case SND_SOC_BIAS_STANDBY:
+ switch (snd_soc_codec_get_bias_level(codec)) {
+ case SND_SOC_BIAS_PREPARE:
+ /* Disable HP discharge */
+ snd_soc_update_bits(codec, WM8960_APOP2,
+ WM8960_DISOP | WM8960_DRES_MASK,
+ 0);
+
+ /* Disable anti-pop features */
+ snd_soc_update_bits(codec, WM8960_APOP1,
+ WM8960_POBCTRL | WM8960_SOFT_ST |
+ WM8960_BUFDCOPEN,
+ WM8960_POBCTRL | WM8960_SOFT_ST |
+ WM8960_BUFDCOPEN);
+ break;
+
+ default:
+ break;
+ }
+ break;
+
+ case SND_SOC_BIAS_OFF:
+ break;
+ }
+
+ return 0;
+}
+
+/* PLL divisors */
+struct _pll_div {
+ u32 pre_div:1;
+ u32 n:4;
+ u32 k:24;
+};
+
+static bool is_pll_freq_available(unsigned int source, unsigned int target)
+{
+ unsigned int Ndiv;
+
+ if (source == 0 || target == 0)
+ return false;
+
+ /* Scale up target to PLL operating frequency */
+ target *= 4;
+ Ndiv = target / source;
+
+ if ((Ndiv < 6) || (Ndiv > 12))
+ return false;
+
+ return true;
+}
+
+/* The size in bits of the pll divide multiplied by 10
+ * to allow rounding later
+ */
+#define FIXED_PLL_SIZE ((1 << 24) * 10)
+
+static int pll_factors(unsigned int source, unsigned int target,
+ struct _pll_div *pll_div)
+{
+ unsigned long long Kpart;
+ unsigned int K, Ndiv, Nmod;
+
+ pr_debug("WM8960 PLL: setting %dHz->%dHz\n", source, target);
+
+ /* Scale up target to PLL operating frequency */
+ target *= 4;
+
+ Ndiv = target / source;
+ if (Ndiv < 6) {
+ source >>= 1;
+ pll_div->pre_div = 1;
+ Ndiv = target / source;
+ } else
+ pll_div->pre_div = 0;
+
+ if ((Ndiv < 6) || (Ndiv > 12)) {
+ pr_err("WM8960 PLL: Unsupported N=%d\n", Ndiv);
+ return -EINVAL;
+ }
+
+ pll_div->n = Ndiv;
+ Nmod = target % source;
+ Kpart = FIXED_PLL_SIZE * (long long)Nmod;
+
+ do_div(Kpart, source);
+
+ K = Kpart & 0xFFFFFFFF;
+
+ /* Check if we need to round */
+ if ((K % 10) >= 5)
+ K += 5;
+
+ /* Move down to proper range now rounding is done */
+ K /= 10;
+
+ pll_div->k = K;
+
+ pr_debug("WM8960 PLL: N=%x K=%x pre_div=%d\n",
+ pll_div->n, pll_div->k, pll_div->pre_div);
+
+ return 0;
+}
+
+static int wm8960_set_pll(struct snd_soc_codec *codec,
+ unsigned int freq_in, unsigned int freq_out)
+{
+ u16 reg;
+ static struct _pll_div pll_div;
+ int ret;
+
+ if (freq_in && freq_out) {
+ ret = pll_factors(freq_in, freq_out, &pll_div);
+ if (ret != 0)
+ return ret;
+ }
+
+ /* Disable the PLL: even if we are changing the frequency the
+ * PLL needs to be disabled while we do so.
+ */
+ snd_soc_update_bits(codec, WM8960_CLOCK1, 0x1, 0);
+ snd_soc_update_bits(codec, WM8960_POWER2, 0x1, 0);
+
+ if (!freq_in || !freq_out)
+ return 0;
+
+ reg = snd_soc_read(codec, WM8960_PLL1) & ~0x3f;
+ reg |= pll_div.pre_div << 4;
+ reg |= pll_div.n;
+
+ if (pll_div.k) {
+ reg |= 0x20;
+
+ snd_soc_write(codec, WM8960_PLL2, (pll_div.k >> 16) & 0xff);
+ snd_soc_write(codec, WM8960_PLL3, (pll_div.k >> 8) & 0xff);
+ snd_soc_write(codec, WM8960_PLL4, pll_div.k & 0xff);
+ }
+ snd_soc_write(codec, WM8960_PLL1, reg);
+
+ /* Turn it on */
+ snd_soc_update_bits(codec, WM8960_POWER2, 0x1, 0x1);
+ msleep(250);
+ snd_soc_update_bits(codec, WM8960_CLOCK1, 0x1, 0x1);
+
+ return 0;
+}
+
+static int wm8960_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
+ int source, unsigned int freq_in, unsigned int freq_out)
+{
+ struct snd_soc_codec *codec = codec_dai->codec;
+ struct rpmsg_wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
+
+ wm8960->freq_in = freq_in;
+
+ if (pll_id == WM8960_SYSCLK_AUTO)
+ return 0;
+
+ if (is_pll_freq_available(freq_in, freq_out))
+ return -EINVAL;
+
+ return wm8960_set_pll(codec, freq_in, freq_out);
+}
+
+static int wm8960_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
+ int div_id, int div)
+{
+ struct snd_soc_codec *codec = codec_dai->codec;
+ u16 reg;
+
+ switch (div_id) {
+ case WM8960_SYSCLKDIV:
+ reg = snd_soc_read(codec, WM8960_CLOCK1) & 0x1f9;
+ snd_soc_write(codec, WM8960_CLOCK1, reg | div);
+ break;
+ case WM8960_DACDIV:
+ reg = snd_soc_read(codec, WM8960_CLOCK1) & 0x1c7;
+ snd_soc_write(codec, WM8960_CLOCK1, reg | div);
+ break;
+ case WM8960_OPCLKDIV:
+ reg = snd_soc_read(codec, WM8960_PLL1) & 0x03f;
+ snd_soc_write(codec, WM8960_PLL1, reg | div);
+ break;
+ case WM8960_DCLKDIV:
+ reg = snd_soc_read(codec, WM8960_CLOCK2) & 0x03f;
+ snd_soc_write(codec, WM8960_CLOCK2, reg | div);
+ break;
+ case WM8960_TOCLKSEL:
+ reg = snd_soc_read(codec, WM8960_ADDCTL1) & 0x1fd;
+ snd_soc_write(codec, WM8960_ADDCTL1, reg | div);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int wm8960_set_bias_level(struct snd_soc_codec *codec,
+ enum snd_soc_bias_level level)
+{
+ struct rpmsg_wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
+
+ return wm8960->set_bias_level(codec, level);
+}
+
+static int wm8960_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id,
+ unsigned int freq, int dir)
+{
+ struct snd_soc_codec *codec = dai->codec;
+ struct rpmsg_wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
+
+ switch (clk_id) {
+ case WM8960_SYSCLK_MCLK:
+ snd_soc_update_bits(codec, WM8960_CLOCK1,
+ 0x1, WM8960_SYSCLK_MCLK);
+ break;
+ case WM8960_SYSCLK_PLL:
+ snd_soc_update_bits(codec, WM8960_CLOCK1,
+ 0x1, WM8960_SYSCLK_PLL);
+ break;
+ case WM8960_SYSCLK_AUTO:
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ wm8960->sysclk = freq;
+ wm8960->clk_id = clk_id;
+
+ return 0;
+}
+
+#define RPMSG_RATES SNDRV_PCM_RATE_8000_48000
+
+#define RPMSG_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
+ SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
+
+static const struct snd_soc_dai_ops rpmsg_wm8960_dai_ops = {
+ .hw_params = wm8960_hw_params,
+ .hw_free = wm8960_hw_free,
+ .digital_mute = wm8960_mute,
+ .set_fmt = wm8960_set_dai_fmt,
+ .set_clkdiv = wm8960_set_dai_clkdiv,
+ .set_pll = wm8960_set_dai_pll,
+ .set_sysclk = wm8960_set_dai_sysclk,
+};
+
+static struct snd_soc_dai_driver rpmsg_wm8960_codec_dai = {
+ .name = "rpmsg-wm8960-hifi",
+ .playback = {
+ .stream_name = "Playback",
+ .channels_min = 1,
+ .channels_max = 2,
+ .rates = RPMSG_RATES,
+ .formats = RPMSG_FORMATS,
+ },
+ .capture = {
+ .stream_name = "Capture",
+ .channels_min = 1,
+ .channels_max = 2,
+ .rates = RPMSG_RATES,
+ .formats = RPMSG_FORMATS,
+ },
+ .ops = &rpmsg_wm8960_dai_ops,
+ .symmetric_rates = 1,
+};
+
+static int rpmsg_wm8960_probe(struct snd_soc_codec *codec)
+{
+ struct rpmsg_wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
+ struct wm8960_data *pdata = &wm8960->pdata;
+
+ if (pdata->capless)
+ wm8960->set_bias_level = wm8960_set_bias_level_capless;
+ else
+ wm8960->set_bias_level = wm8960_set_bias_level_out3;
+
+ snd_soc_add_codec_controls(codec, wm8960_snd_controls,
+ ARRAY_SIZE(wm8960_snd_controls));
+ wm8960_add_widgets(codec);
+
+ return 0;
+}
+
+static int rpmsg_wm8960_read(void *context, unsigned int reg, unsigned int *val)
+{
+ struct rpmsg_wm8960_priv *wm8960 = context;
+ struct fsl_rpmsg_i2s *rpmsg_i2s = wm8960->rpmsg_i2s;
+ struct i2s_info *i2s_info = &rpmsg_i2s->i2s_info;
+ struct i2s_rpmsg_s *rpmsg = &i2s_info->rpmsg[GET_CODEC_VALUE].send_msg;
+ int err, reg_val;
+
+ mutex_lock(&i2s_info->i2c_lock);
+ rpmsg->param.audioindex = wm8960->audioindex;
+ rpmsg->param.buffer_addr = reg;
+ rpmsg->header.cmd = GET_CODEC_VALUE;
+ err = i2s_info->send_message(&i2s_info->rpmsg[GET_CODEC_VALUE], i2s_info);
+ reg_val = i2s_info->rpmsg[GET_CODEC_VALUE].recv_msg.param.reg_data;
+ mutex_unlock(&i2s_info->i2c_lock);
+ if (err)
+ return -EIO;
+
+ *val = reg_val;
+ return 0;
+}
+
+static int rpmsg_wm8960_write(void *context, unsigned int reg, unsigned int val)
+{
+ struct rpmsg_wm8960_priv *wm8960 = context;
+ struct fsl_rpmsg_i2s *rpmsg_i2s = wm8960->rpmsg_i2s;
+ struct i2s_info *i2s_info = &rpmsg_i2s->i2s_info;
+ struct i2s_rpmsg_s *rpmsg = &i2s_info->rpmsg[SET_CODEC_VALUE].send_msg;
+ int err;
+
+ mutex_lock(&i2s_info->i2c_lock);
+ rpmsg->param.audioindex = wm8960->audioindex;
+ rpmsg->param.buffer_addr = reg;
+ rpmsg->param.buffer_size = val;
+ rpmsg->header.cmd = SET_CODEC_VALUE;
+ err = i2s_info->send_message(&i2s_info->rpmsg[SET_CODEC_VALUE], i2s_info);
+ mutex_unlock(&i2s_info->i2c_lock);
+ if (err)
+ return -EIO;
+
+ return 0;
+}
+
+static struct snd_soc_codec_driver rpmsg_wm8960_codec = {
+ .probe = rpmsg_wm8960_probe,
+ .set_bias_level = wm8960_set_bias_level,
+ .suspend_bias_off = true,
+};
+
+static const struct regmap_config rpmsg_wm8960_regmap = {
+ .reg_bits = 7,
+ .val_bits = 9,
+ .max_register = WM8960_PLL4,
+
+ .reg_defaults = wm8960_reg_defaults,
+ .num_reg_defaults = ARRAY_SIZE(wm8960_reg_defaults),
+ .cache_type = REGCACHE_RBTREE,
+
+ .volatile_reg = wm8960_volatile,
+ .reg_read = rpmsg_wm8960_read,
+ .reg_write = rpmsg_wm8960_write,
+};
+
+#ifdef CONFIG_PM
+static int wm8960_runtime_resume(struct device *dev)
+{
+ struct rpmsg_wm8960_priv *wm8960 = dev_get_drvdata(dev);
+ int ret;
+
+ ret = clk_prepare_enable(wm8960->mclk);
+ if (ret) {
+ dev_err(dev, "Failed to enable MCLK: %d\n", ret);
+ return ret;
+ }
+ return 0;
+}
+
+static int wm8960_runtime_suspend(struct device *dev)
+{
+ struct rpmsg_wm8960_priv *wm8960 = dev_get_drvdata(dev);
+
+ clk_disable_unprepare(wm8960->mclk);
+
+ return 0;
+}
+#endif
+
+static const struct dev_pm_ops wm8960_pm = {
+ SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, pm_runtime_force_resume)
+ SET_RUNTIME_PM_OPS(wm8960_runtime_suspend, wm8960_runtime_resume, NULL)
+};
+
+static int rpmsg_wm8960_codec_probe(struct platform_device *pdev)
+{
+ struct fsl_rpmsg_i2s *rpmsg_i2s = dev_get_drvdata(pdev->dev.parent);
+ struct fsl_rpmsg_codec *pdata = pdev->dev.platform_data;
+ struct rpmsg_wm8960_priv *wm8960;
+ int ret;
+ int repeat_reset = 10;
+
+ wm8960 = devm_kzalloc(&pdev->dev, sizeof(struct rpmsg_wm8960_priv),
+ GFP_KERNEL);
+ if (wm8960 == NULL)
+ return -ENOMEM;
+
+ wm8960->rpmsg_i2s = rpmsg_i2s;
+
+ wm8960->mclk = devm_clk_get(pdev->dev.parent, "mclk");
+ if (IS_ERR(wm8960->mclk)) {
+ if (PTR_ERR(wm8960->mclk) == -EPROBE_DEFER)
+ return -EPROBE_DEFER;
+ wm8960->mclk = NULL;
+ }
+
+ dev_set_drvdata(&pdev->dev, wm8960);
+
+ wm8960->regmap = devm_regmap_init(&pdev->dev, NULL, wm8960, &rpmsg_wm8960_regmap);
+ if (IS_ERR(wm8960->regmap))
+ return PTR_ERR(wm8960->regmap);
+
+ if (pdata) {
+ wm8960->pdata.shared_lrclk = pdata->shared_lrclk;
+ wm8960->pdata.capless = pdata->capless;
+ wm8960->audioindex = pdata->audioindex;
+ }
+
+ if (wm8960->mclk) {
+ do {
+ ret = wm8960_reset(wm8960->regmap);
+ repeat_reset--;
+ } while (repeat_reset > 0 && ret != 0);
+
+ if (ret != 0) {
+ dev_err(&pdev->dev, "Failed to issue reset\n");
+ return ret;
+ }
+
+ if (wm8960->pdata.shared_lrclk) {
+ ret = regmap_update_bits(wm8960->regmap, WM8960_ADDCTL2,
+ 0x4, 0x4);
+ if (ret != 0) {
+ dev_err(&pdev->dev, "Failed to enable LRCM: %d\n",
+ ret);
+ return ret;
+ }
+ }
+ }
+
+ /* Latch the update bits */
+ regmap_update_bits(wm8960->regmap, WM8960_LINVOL, 0x100, 0x100);
+ regmap_update_bits(wm8960->regmap, WM8960_RINVOL, 0x100, 0x100);
+ regmap_update_bits(wm8960->regmap, WM8960_LADC, 0x100, 0x100);
+ regmap_update_bits(wm8960->regmap, WM8960_RADC, 0x100, 0x100);
+ regmap_update_bits(wm8960->regmap, WM8960_LDAC, 0x100, 0x100);
+ regmap_update_bits(wm8960->regmap, WM8960_RDAC, 0x100, 0x100);
+ regmap_update_bits(wm8960->regmap, WM8960_LOUT1, 0x100, 0x100);
+ regmap_update_bits(wm8960->regmap, WM8960_ROUT1, 0x100, 0x100);
+ regmap_update_bits(wm8960->regmap, WM8960_LOUT2, 0x100, 0x100);
+ regmap_update_bits(wm8960->regmap, WM8960_ROUT2, 0x100, 0x100);
+
+ pm_runtime_enable(&pdev->dev);
+
+ if (!wm8960->mclk)
+ rpmsg_wm8960_codec_dai.ops = NULL;
+
+ ret = snd_soc_register_codec(&pdev->dev,
+ &rpmsg_wm8960_codec, &rpmsg_wm8960_codec_dai, 1);
+
+ return ret;
+}
+
+static int rpmsg_wm8960_codec_remove(struct platform_device *pdev)
+{
+ snd_soc_unregister_codec(&pdev->dev);
+ return 0;
+}
+
+static struct platform_driver rpmsg_wm8960_codec_driver = {
+ .driver = {
+ .name = RPMSG_CODEC_DRV_NAME_WM8960,
+ .pm = &wm8960_pm,
+ },
+ .probe = rpmsg_wm8960_codec_probe,
+ .remove = rpmsg_wm8960_codec_remove,
+};
+
+module_platform_driver(rpmsg_wm8960_codec_driver);
+
+MODULE_DESCRIPTION("rpmsg wm8960 Codec Driver");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/si476x.c b/sound/soc/codecs/si476x.c
index 354dc0d64f11..9fd1eeabed8f 100644
--- a/sound/soc/codecs/si476x.c
+++ b/sound/soc/codecs/si476x.c
@@ -208,9 +208,28 @@ out:
return err;
}
+static int si476x_codec_startup(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai) {
+ struct si476x_core *core = i2c_mfd_cell_to_core(dai->dev);
+
+ if (!si476x_core_is_powered_up(core))
+ si476x_core_set_power_state(core, SI476X_POWER_UP_FULL);
+ return 0;
+}
+
+static void si476x_codec_shutdown(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai) {
+ struct si476x_core *core = i2c_mfd_cell_to_core(dai->dev);
+
+ if (si476x_core_is_powered_up(core))
+ si476x_core_set_power_state(core, SI476X_POWER_DOWN);
+}
+
static const struct snd_soc_dai_ops si476x_dai_ops = {
.hw_params = si476x_codec_hw_params,
.set_fmt = si476x_codec_set_dai_fmt,
+ .startup = si476x_codec_startup,
+ .shutdown = si476x_codec_shutdown,
};
static struct snd_soc_dai_driver si476x_dai = {
diff --git a/sound/soc/codecs/wm8524.c b/sound/soc/codecs/wm8524.c
index 856a6950a451..2f368b72cfe3 100644
--- a/sound/soc/codecs/wm8524.c
+++ b/sound/soc/codecs/wm8524.c
@@ -162,7 +162,8 @@ static int wm8524_mute_stream(struct snd_soc_dai *dai, int mute, int stream)
#define WM8524_RATES SNDRV_PCM_RATE_8000_192000
-#define WM8524_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE)
+#define WM8524_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE |\
+ SNDRV_PCM_FMTBIT_S32_LE)
static const struct snd_soc_dai_ops wm8524_dai_ops = {
.startup = wm8524_startup,
diff --git a/sound/soc/codecs/wm8960.c b/sound/soc/codecs/wm8960.c
index 9ed455700954..79034c1ab640 100644
--- a/sound/soc/codecs/wm8960.c
+++ b/sound/soc/codecs/wm8960.c
@@ -18,6 +18,7 @@
#include <linux/clk.h>
#include <linux/i2c.h>
#include <linux/slab.h>
+#include <linux/pm_runtime.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
@@ -611,10 +612,6 @@ static const int bclk_divs[] = {
* - lrclk = sysclk / dac_divs
* - 10 * bclk = sysclk / bclk_divs
*
- * If we cannot find an exact match for (sysclk, lrclk, bclk)
- * triplet, we relax the bclk such that bclk is chosen as the
- * closest available frequency greater than expected bclk.
- *
* @wm8960_priv: wm8960 codec private data
* @mclk: MCLK used to derive sysclk
* @sysclk_idx: sysclk_divs index for found sysclk
@@ -632,7 +629,7 @@ int wm8960_configure_sysclk(struct wm8960_priv *wm8960, int mclk,
{
int sysclk, bclk, lrclk;
int i, j, k;
- int diff, closest = mclk;
+ int diff;
/* marker for no match */
*bclk_idx = -1;
@@ -656,12 +653,6 @@ int wm8960_configure_sysclk(struct wm8960_priv *wm8960, int mclk,
*bclk_idx = k;
break;
}
- if (diff > 0 && closest > diff) {
- *sysclk_idx = i;
- *dac_idx = j;
- *bclk_idx = k;
- closest = diff;
- }
}
if (k != ARRAY_SIZE(bclk_divs))
break;
@@ -679,10 +670,6 @@ int wm8960_configure_sysclk(struct wm8960_priv *wm8960, int mclk,
* - freq_out = sysclk * sysclk_divs
* - 10 * sysclk = bclk * bclk_divs
*
- * If we cannot find an exact match for (sysclk, lrclk, bclk)
- * triplet, we relax the bclk such that bclk is chosen as the
- * closest available frequency greater than expected bclk.
- *
* @codec: codec structure
* @freq_in: input frequency used to derive freq out via PLL
* @sysclk_idx: sysclk_divs index for found sysclk
@@ -700,12 +687,11 @@ int wm8960_configure_pll(struct snd_soc_codec *codec, int freq_in,
{
struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
int sysclk, bclk, lrclk, freq_out;
- int diff, closest, best_freq_out;
+ int diff, best_freq_out;
int i, j, k;
bclk = wm8960->bclk;
lrclk = wm8960->lrclk;
- closest = freq_in;
best_freq_out = -EINVAL;
*sysclk_idx = *dac_idx = *bclk_idx = -1;
@@ -728,13 +714,6 @@ int wm8960_configure_pll(struct snd_soc_codec *codec, int freq_in,
*bclk_idx = k;
return freq_out;
}
- if (diff > 0 && closest > diff) {
- *sysclk_idx = i;
- *dac_idx = j;
- *bclk_idx = k;
- closest = diff;
- best_freq_out = freq_out;
- }
}
}
}
@@ -862,8 +841,7 @@ static int wm8960_hw_params(struct snd_pcm_substream *substream,
wm8960->is_stream_in_use[tx] = true;
- if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_ON &&
- !wm8960->is_stream_in_use[!tx])
+ if (!wm8960->is_stream_in_use[!tx])
return wm8960_configure_clocking(codec);
return 0;
@@ -1122,11 +1100,6 @@ static bool is_pll_freq_available(unsigned int source, unsigned int target)
target *= 4;
Ndiv = target / source;
- if (Ndiv < 6) {
- source >>= 1;
- Ndiv = target / source;
- }
-
if ((Ndiv < 6) || (Ndiv > 12))
return false;
@@ -1237,6 +1210,9 @@ static int wm8960_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
if (pll_id == WM8960_SYSCLK_AUTO)
return 0;
+ if (is_pll_freq_available(freq_in, freq_out))
+ return -EINVAL;
+
return wm8960_set_pll(codec, freq_in, freq_out);
}
@@ -1396,6 +1372,7 @@ static int wm8960_i2c_probe(struct i2c_client *i2c,
struct wm8960_data *pdata = dev_get_platdata(&i2c->dev);
struct wm8960_priv *wm8960;
int ret;
+ int repeat_reset = 10;
wm8960 = devm_kzalloc(&i2c->dev, sizeof(struct wm8960_priv),
GFP_KERNEL);
@@ -1417,7 +1394,11 @@ static int wm8960_i2c_probe(struct i2c_client *i2c,
else if (i2c->dev.of_node)
wm8960_set_pdata_from_of(i2c, &wm8960->pdata);
- ret = wm8960_reset(wm8960->regmap);
+ do {
+ ret = wm8960_reset(wm8960->regmap);
+ repeat_reset--;
+ } while (repeat_reset > 0 && ret != 0);
+
if (ret != 0) {
dev_err(&i2c->dev, "Failed to issue reset\n");
return ret;
@@ -1447,6 +1428,8 @@ static int wm8960_i2c_probe(struct i2c_client *i2c,
i2c_set_clientdata(i2c, wm8960);
+ pm_runtime_enable(&i2c->dev);
+
ret = snd_soc_register_codec(&i2c->dev,
&soc_codec_dev_wm8960, &wm8960_dai, 1);
@@ -1459,6 +1442,35 @@ static int wm8960_i2c_remove(struct i2c_client *client)
return 0;
}
+#ifdef CONFIG_PM
+static int wm8960_runtime_resume(struct device *dev)
+{
+ struct wm8960_priv *wm8960 = dev_get_drvdata(dev);
+ int ret;
+
+ ret = clk_prepare_enable(wm8960->mclk);
+ if (ret) {
+ dev_err(dev, "Failed to enable MCLK: %d\n", ret);
+ return ret;
+ }
+ return 0;
+}
+
+static int wm8960_runtime_suspend(struct device *dev)
+{
+ struct wm8960_priv *wm8960 = dev_get_drvdata(dev);
+
+ clk_disable_unprepare(wm8960->mclk);
+
+ return 0;
+}
+#endif
+
+static const struct dev_pm_ops wm8960_pm = {
+ SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, pm_runtime_force_resume)
+ SET_RUNTIME_PM_OPS(wm8960_runtime_suspend, wm8960_runtime_resume, NULL)
+};
+
static const struct i2c_device_id wm8960_i2c_id[] = {
{ "wm8960", 0 },
{ }
@@ -1475,6 +1487,7 @@ static struct i2c_driver wm8960_i2c_driver = {
.driver = {
.name = "wm8960",
.of_match_table = wm8960_of_match,
+ .pm = &wm8960_pm,
},
.probe = wm8960_i2c_probe,
.remove = wm8960_i2c_remove,
diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c
index fd2731d171dd..f25c6ba0e251 100644
--- a/sound/soc/codecs/wm8962.c
+++ b/sound/soc/codecs/wm8962.c
@@ -2,6 +2,7 @@
* wm8962.c -- WM8962 ALSA SoC Audio driver
*
* Copyright 2010-2 Wolfson Microelectronics plc
+ * Copyright 2017 NXP
*
* Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
*
@@ -86,6 +87,7 @@ struct wm8962_priv {
#endif
int irq;
+ u32 cache_clocking2_reg;
};
/* We can't use the same notifier block for more than one supply and
@@ -1781,8 +1783,11 @@ SND_SOC_BYTES("HD Bass Coefficients", WM8962_HDBASS_AI_1, 30),
SOC_DOUBLE("ALC Switch", WM8962_ALC1, WM8962_ALCL_ENA_SHIFT,
WM8962_ALCR_ENA_SHIFT, 1, 0),
-SND_SOC_BYTES_MASK("ALC Coefficients", WM8962_ALC1, 4,
+SND_SOC_BYTES_MASK("ALC1", WM8962_ALC1, 1,
WM8962_ALCL_ENA_MASK | WM8962_ALCR_ENA_MASK),
+SND_SOC_BYTES("ALC2", WM8962_ALC2, 1),
+SND_SOC_BYTES("ALC3", WM8962_ALC3, 1),
+SND_SOC_BYTES("Noise Gate", WM8962_NOISE_GATE, 1),
};
static const struct snd_kcontrol_new wm8962_spk_mono_controls[] = {
@@ -2558,11 +2563,17 @@ static int wm8962_hw_params(struct snd_pcm_substream *substream,
{
struct snd_soc_codec *codec = dai->codec;
struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
+ snd_pcm_format_t sample_format = params_format(params);
int i;
int aif0 = 0;
int adctl3 = 0;
- wm8962->bclk = snd_soc_params_to_bclk(params);
+ if (sample_format == SNDRV_PCM_FORMAT_S20_3LE)
+ wm8962->bclk = params_rate(params) *
+ params_channels(params) *
+ params_physical_width(params);
+ else
+ wm8962->bclk = snd_soc_params_to_bclk(params);
if (params_channels(params) == 1)
wm8962->bclk *= 2;
@@ -2791,7 +2802,7 @@ static int fll_factors(struct _fll_div *fll_div, unsigned int Fref,
if (target % Fref == 0) {
fll_div->theta = 0;
- fll_div->lambda = 0;
+ fll_div->lambda = 1;
} else {
gcd_fll = gcd(target, fratio * Fref);
@@ -2861,7 +2872,7 @@ static int wm8962_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
return -EINVAL;
}
- if (fll_div.theta || fll_div.lambda)
+ if (fll_div.theta)
fll1 |= WM8962_FLL_FRAC;
/* Stop the FLL while we reconfigure */
@@ -3820,6 +3831,10 @@ static int wm8962_runtime_resume(struct device *dev)
regcache_sync(wm8962->regmap);
+ regmap_update_bits(wm8962->regmap, WM8962_CLOCKING2,
+ WM8962_SYSCLK_SRC_MASK,
+ wm8962->cache_clocking2_reg);
+
regmap_update_bits(wm8962->regmap, WM8962_ANTI_POP,
WM8962_STARTUP_BIAS_ENA | WM8962_VMID_BUF_ENA,
WM8962_STARTUP_BIAS_ENA | WM8962_VMID_BUF_ENA);
@@ -3849,6 +3864,9 @@ static int wm8962_runtime_suspend(struct device *dev)
WM8962_STARTUP_BIAS_ENA |
WM8962_VMID_BUF_ENA, 0);
+ regmap_read(wm8962->regmap, WM8962_CLOCKING2,
+ &wm8962->cache_clocking2_reg);
+
regcache_cache_only(wm8962->regmap, true);
regulator_bulk_disable(ARRAY_SIZE(wm8962->supplies),
@@ -3861,6 +3879,7 @@ static int wm8962_runtime_suspend(struct device *dev)
#endif
static const struct dev_pm_ops wm8962_pm = {
+ SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, pm_runtime_force_resume)
SET_RUNTIME_PM_OPS(wm8962_runtime_suspend, wm8962_runtime_resume, NULL)
};
diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c
index f289762cd676..57cf28120759 100644
--- a/sound/soc/codecs/wm8994.c
+++ b/sound/soc/codecs/wm8994.c
@@ -3151,9 +3151,67 @@ static struct snd_soc_dai_driver wm8994_dai[] = {
};
#ifdef CONFIG_PM
+static void wm8994_store_context(struct wm8994 *wm8994)
+{
+ struct device *dev = wm8994->dev;
+ int ret;
+
+ /* Disable LDO pulldowns while the device is suspended if we
+ * don't know that something will be driving them. */
+ if (!wm8994->ldo_ena_always_driven)
+ wm8994_set_bits(wm8994, WM8994_PULL_CONTROL_2,
+ WM8994_LDO1ENA_PD | WM8994_LDO2ENA_PD,
+ WM8994_LDO1ENA_PD | WM8994_LDO2ENA_PD);
+
+ /* Explicitly put the device into reset in case regulators
+ * don't get disabled in order to ensure consistent restart.
+ */
+ wm8994_reg_write(wm8994, WM8994_SOFTWARE_RESET,
+ wm8994_reg_read(wm8994, WM8994_SOFTWARE_RESET));
+
+ regcache_mark_dirty(wm8994->regmap);
+
+ /* Restore GPIO registers to prevent problems with mismatched
+ * pin configurations.
+ */
+ ret = regcache_sync_region(wm8994->regmap, WM8994_GPIO_1,
+ WM8994_GPIO_11);
+ if (ret != 0)
+ dev_err(dev, "Failed to restore GPIO registers: %d\n", ret);
+
+ /* In case one of the GPIOs is used as a wake input. */
+ ret = regcache_sync_region(wm8994->regmap,
+ WM8994_INTERRUPT_STATUS_1_MASK,
+ WM8994_INTERRUPT_STATUS_1_MASK);
+ if (ret != 0)
+ dev_err(dev, "Failed to restore interrupt mask: %d\n", ret);
+
+ regcache_cache_only(wm8994->regmap, true);
+}
+
+static int wm8994_load_context(struct wm8994 *wm8994)
+{
+ struct device *dev = wm8994->dev;
+ int ret;
+
+ regcache_cache_only(wm8994->regmap, false);
+ ret = regcache_sync(wm8994->regmap);
+ if (ret != 0) {
+ dev_err(dev, "Failed to restore register map: %d\n", ret);
+ return ret;
+ }
+
+ /* Disable LDO pulldowns while the device is active */
+ wm8994_set_bits(wm8994, WM8994_PULL_CONTROL_2,
+ WM8994_LDO1ENA_PD | WM8994_LDO2ENA_PD, 0);
+
+ return 0;
+}
+
static int wm8994_codec_suspend(struct snd_soc_codec *codec)
{
struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+ struct wm8994 *control = wm8994->wm8994;
int i, ret;
for (i = 0; i < ARRAY_SIZE(wm8994->fll); i++) {
@@ -3165,6 +3223,8 @@ static int wm8994_codec_suspend(struct snd_soc_codec *codec)
i + 1, ret);
}
+ wm8994_store_context(control);
+
snd_soc_codec_force_bias_level(codec, SND_SOC_BIAS_OFF);
return 0;
@@ -3173,8 +3233,15 @@ static int wm8994_codec_suspend(struct snd_soc_codec *codec)
static int wm8994_codec_resume(struct snd_soc_codec *codec)
{
struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+ struct wm8994 *control = wm8994->wm8994;
int i, ret;
+ ret = wm8994_load_context(control);
+ if (ret != 0) {
+ dev_err(codec->dev, "Failed to load context: %d\n", ret);
+ return ret;
+ }
+
for (i = 0; i < ARRAY_SIZE(wm8994->fll); i++) {
if (!wm8994->fll_suspend[i].out)
continue;
diff --git a/sound/soc/fsl/Kconfig b/sound/soc/fsl/Kconfig
index 2523b0065990..987de0481481 100644
--- a/sound/soc/fsl/Kconfig
+++ b/sound/soc/fsl/Kconfig
@@ -24,6 +24,23 @@ config SND_SOC_FSL_SAI
This option is only useful for out-of-tree drivers since
in-tree drivers select it automatically.
+config SND_SOC_FSL_ACM
+ tristate "Audio Clock Multiplexer (ACM) module support"
+ help
+ Say Y if you want to add Audio Clock Multiplexer (ACM)
+ support for the Freescale CPUs.
+ This option is only useful for out-of-tree drivers since
+ in-tree drivers select it automatically.
+
+config SND_SOC_FSL_AMIX
+ tristate "Audio Mixer (AMIX) module support"
+ select REGMAP_MMIO
+ help
+ Say Y if you want to add Audio Mixer (AMIX)
+ support for the Freescale CPUs.
+ This option is only useful for out-of-tree drivers since
+ in-tree drivers select it automatically.
+
config SND_SOC_FSL_SSI
tristate "Synchronous Serial Interface module (SSI) support"
select SND_SOC_IMX_PCM_DMA if SND_IMX_SOC != n
@@ -57,13 +74,48 @@ config SND_SOC_FSL_ESAI
This option is only useful for out-of-tree drivers since
in-tree drivers select it automatically.
+config SND_SOC_FSL_MICFIL
+ tristate "Pulse Density Modulation Microphone Interface (MICFIL) module support"
+ select REGMAP_MMIO
+ select SND_SOC_IMX_PCM_DMA if SND_IMX_SOC != n
+ select SND_SOC_GENERIC_DMAENGINE_PCM
+ help
+ Say Y if you want to add Pulse Density Modulation microphone
+ interface (MICFIL) support for NXP.
+
+config SND_SOC_FSL_RPMSG_I2S
+ tristate "I2S base on the RPMSG support"
+ depends on RPMSG
+ help
+ Say Y if you want to add rpmsg i2s support for the Freescale CPUs.
+ which is depends on the rpmsg.
+ This option is only useful for out-of-tree drivers since
+ in-tree drivers select it automatically.
+
+config SND_SOC_FSL_DSP
+ tristate "dsp module support"
+ select SND_SOC_COMPRESS
+ help
+ Say Y if you want to add hifi 4 support for the Freescale CPUs.
+ which is a DSP core for audio processing.
+ This option is only useful for out-of-tree drivers since
+ in-tree drivers select it automatically.
+
config SND_SOC_FSL_UTILS
tristate
+config SND_SOC_FSL_HDMI
+ tristate
+
config SND_SOC_IMX_PCM_DMA
tristate
select SND_SOC_GENERIC_DMAENGINE_PCM
+config SND_SOC_IMX_PCM_RPMSG
+ tristate
+ depends on RPMSG
+ select SND_SOC_GENERIC_DMAENGINE_PCM
+
config SND_SOC_IMX_AUDMUX
tristate "Digital Audio Mux module support"
help
@@ -81,7 +133,7 @@ config SND_POWERPC_SOC
config SND_IMX_SOC
tristate "SoC Audio for Freescale i.MX CPUs"
- depends on ARCH_MXC || COMPILE_TEST
+ depends on ARCH_MXC || ARCH_MXC_ARM64 || COMPILE_TEST
help
Say Y or M if you want to add support for codecs attached to
the i.MX CPUs.
@@ -184,6 +236,11 @@ config SND_SOC_IMX_SSI
tristate
select SND_SOC_FSL_UTILS
+config SND_SOC_IMX_HDMI_DMA
+ bool
+ select SND_SOC_GENERIC_DMAENGINE_PCM
+ select SND_SOC_IMX_PCM_DMA
+
comment "SoC Audio support for Freescale i.MX boards:"
config SND_MXC_SOC_WM1133_EV1
@@ -232,6 +289,106 @@ config SND_SOC_EUKREA_TLV320
Enable I2S based access to the TLV320AIC23B codec attached
to the SSI interface
+config SND_SOC_IMX_AK4458
+ tristate "SoC Audio support for i.MX boards with AK4458"
+ depends on OF && I2C
+ select SND_SOC_AK4458_I2C
+ select SND_SOC_IMX_PCM_DMA
+ select SND_SOC_FSL_SAI
+ select SND_SOC_FSL_UTILS
+ help
+ SoC Audio support for i.MX boards with AK4458
+ Say Y if you want to add support for SoC audio on an i.MX board with
+ an AK4458 DAC.
+
+config SND_SOC_IMX_AK5558
+ tristate "SoC Audio support for i.MX boards with AK5558"
+ depends on OF && I2C
+ select SND_SOC_AK5558
+ select SND_SOC_IMX_PCM_DMA
+ select SND_SOC_FSL_SAI
+ select SND_SOC_FSL_UTILS
+ help
+ SoC Audio support for i.MX boards with AK5558
+ Say Y if you want to add support for SoC audio on an i.MX board with
+ an AK5558 ADC.
+
+config SND_SOC_IMX_AK4497
+ tristate "SoC Audio support for i.MX boards with AK4497"
+ depends on OF && I2C
+ select SND_SOC_AK4497
+ select SND_SOC_IMX_PCM_DMA
+ select SND_SOC_FSL_SAI
+ select SND_SOC_FSL_UTILS
+ help
+ SoC Audio support for i.MX boards with AK4497
+ Say Y if you want to add support for SoC audio on an i.MX board with
+ an AK4497 DAC.
+
+config SND_SOC_IMX_WM8960
+ tristate "SoC Audio support for i.MX boards with wm8960"
+ depends on OF && I2C
+ select SND_SOC_WM8960
+ select SND_SOC_IMX_PCM_DMA
+ select SND_SOC_FSL_SAI
+ select SND_SOC_FSL_UTILS
+ select SND_KCTL_JACK
+ help
+ SoC Audio support for i.MX boards with WM8960
+ Say Y if you want to add support for SoC audio on an i.MX board with
+ a wm8960 codec.
+
+config SND_SOC_IMX_WM8524
+ tristate "SoC Audio support for i.MX boards with wm8524"
+ depends on OF && I2C
+ select SND_SOC_WM8524
+ select SND_SOC_IMX_PCM_DMA
+ select SND_SOC_FSL_SAI
+ select SND_SOC_FSL_UTILS
+ select SND_KCTL_JACK
+ help
+ SoC Audio support for i.MX boards with WM8524
+ Say Y if you want to add support for SoC audio on an i.MX board with
+ a wm8524 codec.
+
+config SND_SOC_IMX_SII902X
+ tristate "SoC Audio support for i.MX boards with sii902x"
+ depends on OF && I2C
+ select SND_SOC_IMX_PCM_DMA
+ select SND_SOC_FSL_SAI
+ select SND_SOC_FSL_UTILS
+ help
+ SoC Audio support for i.MX boards with SII902X
+ Say Y if you want to add support for SoC audio on an i.MX board with
+ a sii902x.
+
+config SND_SOC_IMX_WM8958
+ tristate "SoC Audio support for i.MX boards with wm8958"
+ depends on OF && I2C
+ select MFD_WM8994
+ select SND_SOC_WM8994
+ select SND_SOC_IMX_PCM_DMA
+ select SND_SOC_FSL_SAI
+ select SND_SOC_FSL_UTILS
+ select SND_KCTL_JACK
+ help
+ SoC Audio support for i.MX boards with WM8958
+ Say Y if you want to add support for SoC audio on an i.MX board with
+ a wm8958 codec.
+
+config SND_SOC_IMX_CS42888
+ tristate "SoC Audio support for i.MX boards with cs42888"
+ depends on OF && I2C
+ select SND_SOC_CS42XX8_I2C
+ select SND_SOC_IMX_PCM_DMA
+ select SND_SOC_FSL_ESAI
+ select SND_SOC_FSL_ASRC
+ select SND_SOC_FSL_UTILS
+ help
+ SoC Audio support for i.MX boards with cs42888
+ Say Y if you want to add support for SoC audio on an i.MX board with
+ a cs42888 codec.
+
config SND_SOC_IMX_WM8962
tristate "SoC Audio support for i.MX boards with wm8962"
depends on OF && I2C && INPUT
@@ -239,10 +396,42 @@ config SND_SOC_IMX_WM8962
select SND_SOC_IMX_PCM_DMA
select SND_SOC_IMX_AUDMUX
select SND_SOC_FSL_SSI
+ select SND_KCTL_JACK
help
Say Y if you want to add support for SoC audio on an i.MX board with
a wm8962 codec.
+config SND_SOC_IMX_WM8962_ANDROID
+ tristate "SoC Audio support for i.MX boards with wm8962 in android"
+ depends on SND_SOC_IMX_WM8962=y
+ help
+ Say Y if you want to add support for SoC audio on an i.MX board with
+ a wm8962 codec in android.
+
+config SND_SOC_IMX_MICFIL
+ tristate "SoC Audio support for i.MX boards with micfil"
+ depends on OF && I2C
+ select SND_SOC_IMX_PCM_DMA
+ select SND_SOC_FSL_MICFIL
+ help
+ Soc Audio support for i.MX boards with micfil
+ Say Y if you want to add support for SoC audio on
+ an i.MX board with micfil.
+
+config SND_SOC_IMX_RPMSG
+ tristate "SoC Audio support for i.MX boards with rpmsg"
+ depends on OF && I2C && INPUT
+ select SND_SOC_IMX_PCM_RPMSG
+ select SND_SOC_FSL_RPMSG_I2S
+ select SND_SOC_RPMSG_WM8960
+ select SND_SOC_RPMSG_CS42XX8
+ select SND_SOC_RPMSG_AK4497
+ help
+ SoC Audio support for i.MX boards with rpmsg.
+ There should be rpmsg devices defined in other core
+ Say Y if you want to add support for SoC audio on an i.MX board with
+ a rpmsg devices.
+
config SND_SOC_IMX_ES8328
tristate "SoC Audio support for i.MX boards with the ES8328 codec"
depends on OF && (I2C || SPI)
@@ -255,6 +444,17 @@ config SND_SOC_IMX_ES8328
Say Y if you want to add support for the ES8328 audio codec connected
via SSI/I2S over either SPI or I2C.
+config SND_SOC_IMX_XTOR
+ tristate "SoC Audio support for i.MX boards with xtor codec"
+ select SND_SOC_IMX_PCM_DMA
+ select SND_SOC_FSL_ESAI
+ select SND_SOC_FSL_SAI
+ select SND_SOC_FSL_UTILS
+ help
+ SoC Audio support for i.MX boards with xtor codec
+ Say Y if you want to add support for SoC audio on
+ an i.MX board with a xtor codec.
+
config SND_SOC_IMX_SGTL5000
tristate "SoC Audio support for i.MX boards with sgtl5000"
depends on OF && I2C
@@ -266,6 +466,14 @@ config SND_SOC_IMX_SGTL5000
Say Y if you want to add support for SoC audio on an i.MX board with
a sgtl5000 codec.
+config SND_SOC_IMX_MQS
+ tristate "SoC Audio support for i.MX boards with MQS"
+ depends on OF
+ select SND_SOC_IMX_PCM_DMA
+ select SND_SOC_FSL_SAI
+ select SND_SOC_FSL_MQS
+ select SND_SOC_FSL_UTILS
+
config SND_SOC_IMX_SPDIF
tristate "SoC Audio support for i.MX boards with S/PDIF"
select SND_SOC_IMX_PCM_DMA
@@ -296,9 +504,70 @@ config SND_SOC_FSL_ASOC_CARD
help
ALSA SoC Audio support with ASRC feature for Freescale SoCs that have
ESAI/SAI/SSI and connect with external CODECs such as WM8962, CS42888,
- CS4271, CS4272 and SGTL5000.
+ CS4271, CS4272, and SGTL5000.
Say Y if you want to add support for Freescale Generic ASoC Sound Card.
+config SND_SOC_IMX_SI476X
+ tristate "SoC Audio support for i.MX boards with si476x"
+ select SND_SOC_IMX_PCM_DMA
+ select SND_SOC_IMX_AUDMUX
+ select SND_SOC_FSL_SSI
+ select SND_SOC_FSL_UTILS
+ select SND_SOC_SI476X
+ help
+ SoC Audio support for i.MX boards with SI476x
+ Say Y if you want to add support for Soc audio for the AMFM Tuner chip
+ SI476x module.
+
+config SND_SOC_IMX_HDMI
+ tristate "SoC Audio support for i.MX boards with HDMI port"
+ depends on MFD_MXC_HDMI
+ select SND_SOC_IMX_HDMI_DMA
+ select SND_SOC_FSL_HDMI
+ select SND_SOC_HDMI_CODEC
+ help
+ SoC Audio support for i.MX boards with HDMI audio
+ Say Y if you want to add support for SoC audio on an i.MX board with
+ IMX HDMI.
+
+config SND_SOC_IMX_AMIX
+ tristate "SoC Audio support for i.MX boards with AMIX"
+ select SND_SOC_FSL_AMIX
+ help
+ SoC Audio support for i.MX boards with AMIX
+ Say Y if you want to add support for SoC audio on an i.MX board with
+ an AMIX.
+
+config SND_SOC_IMX_CDNHDMI
+ tristate "SoC Audio support for i.MX boards with CDN HDMI port"
+ depends on DRM_IMX_HDP
+ select SND_SOC_IMX_PCM_DMA
+ select SND_SOC_FSL_SAI
+ select SND_SOC_HDMI_CODEC
+ help
+ SoC Audio support for i.MX boards with CDN HDMI audio
+ Say Y if you want to add support for SoC audio on an i.MX board with
+ IMX CDN HDMI.
+
+config SND_SOC_IMX_DSP
+ tristate "SoC Audio support for i.MX boards with DSP port"
+ select SND_SOC_FSL_DSP
+ select SND_SOC_COMPRESS
+ help
+ SoC Audio support for i.MX boards with DSP audio
+ Say Y if you want to add support for SoC audio on an i.MX board with
+ IMX DSP.
+
+config SND_SOC_IMX_PDM_MIC
+ tristate "SoC Audio support for i.MX boards with PDM mic on SAI"
+ depends on OF
+ select SND_SOC_IMX_PDM_DMA
+ select SND_SOC_FSL_SAI
+ help
+ SoC Audio support for i.MX boards with PDM microphones on SAI
+ Say Y if you want to add support for SoC Audio support for i.MX boards
+ with PDM microphones on SAI.
+
endif # SND_IMX_SOC
endmenu
diff --git a/sound/soc/fsl/Makefile b/sound/soc/fsl/Makefile
index c67bf1139e1e..0b23c8e74e41 100644
--- a/sound/soc/fsl/Makefile
+++ b/sound/soc/fsl/Makefile
@@ -12,23 +12,39 @@ snd-soc-p1022-rdk-objs := p1022_rdk.o
obj-$(CONFIG_SND_SOC_P1022_RDK) += snd-soc-p1022-rdk.o
# Freescale SSI/DMA/SAI/SPDIF Support
-snd-soc-fsl-asoc-card-objs := fsl-asoc-card.o
+snd-soc-fsl-acm-objs := fsl_acm.o
+snd-soc-fsl-amix-objs := fsl_amix.o
snd-soc-fsl-asrc-objs := fsl_asrc.o fsl_asrc_dma.o
+snd-soc-fsl-dma-workaround-objs := fsl_dma_workaround.o
+snd-soc-fsl-dsp-objs := fsl_dsp.o fsl_dsp_proxy.o fsl_dsp_pool.o \
+ fsl_dsp_library_load.o fsl_dsp_xaf_api.o fsl_dsp_cpu.o \
+ fsl_dsp_platform_compress.o
snd-soc-fsl-sai-objs := fsl_sai.o
snd-soc-fsl-ssi-y := fsl_ssi.o
snd-soc-fsl-ssi-$(CONFIG_DEBUG_FS) += fsl_ssi_dbg.o
snd-soc-fsl-spdif-objs := fsl_spdif.o
-snd-soc-fsl-esai-objs := fsl_esai.o
+snd-soc-fsl-esai-objs := fsl_esai.o fsl_dma_workaround.o
snd-soc-fsl-utils-objs := fsl_utils.o
snd-soc-fsl-dma-objs := fsl_dma.o
-obj-$(CONFIG_SND_SOC_FSL_ASOC_CARD) += snd-soc-fsl-asoc-card.o
+snd-soc-fsl-rpmsg-i2s-objs := fsl_rpmsg_i2s.o
+snd-soc-fsl-hdmi-objs := fsl_hdmi.o
+snd-soc-fsl-asoc-card-objs := fsl-asoc-card.o
+snd-soc-fsl-micfil-objs := fsl_micfil.o
+
+obj-$(CONFIG_SND_SOC_FSL_ACM) += snd-soc-fsl-acm.o
+obj-$(CONFIG_SND_SOC_FSL_AMIX) += snd-soc-fsl-amix.o
obj-$(CONFIG_SND_SOC_FSL_ASRC) += snd-soc-fsl-asrc.o
+obj-$(CONFIG_SND_SOC_FSL_DSP) += snd-soc-fsl-dsp.o
obj-$(CONFIG_SND_SOC_FSL_SAI) += snd-soc-fsl-sai.o
obj-$(CONFIG_SND_SOC_FSL_SSI) += snd-soc-fsl-ssi.o
obj-$(CONFIG_SND_SOC_FSL_SPDIF) += snd-soc-fsl-spdif.o
obj-$(CONFIG_SND_SOC_FSL_ESAI) += snd-soc-fsl-esai.o
obj-$(CONFIG_SND_SOC_FSL_UTILS) += snd-soc-fsl-utils.o
+obj-$(CONFIG_SND_SOC_FSL_HDMI) += snd-soc-fsl-hdmi.o
obj-$(CONFIG_SND_SOC_POWERPC_DMA) += snd-soc-fsl-dma.o
+obj-$(CONFIG_SND_SOC_FSL_RPMSG_I2S) += snd-soc-fsl-rpmsg-i2s.o
+obj-$(CONFIG_SND_SOC_FSL_ASOC_CARD) += snd-soc-fsl-asoc-card.o
+obj-$(CONFIG_SND_SOC_FSL_MICFIL) += snd-soc-fsl-micfil.o
# MPC5200 Platform Support
obj-$(CONFIG_SND_MPC52xx_DMA) += mpc5200_dma.o
@@ -46,7 +62,9 @@ obj-$(CONFIG_SND_SOC_IMX_SSI) += snd-soc-imx-ssi.o
obj-$(CONFIG_SND_SOC_IMX_AUDMUX) += snd-soc-imx-audmux.o
obj-$(CONFIG_SND_SOC_IMX_PCM_FIQ) += imx-pcm-fiq.o
-obj-$(CONFIG_SND_SOC_IMX_PCM_DMA) += imx-pcm-dma.o
+obj-$(CONFIG_SND_SOC_IMX_PCM_DMA) += imx-pcm-dma.o imx-pcm-dma-v2.o
+obj-$(CONFIG_SND_SOC_IMX_PCM_RPMSG) += imx-pcm-rpmsg.o
+obj-$(CONFIG_SND_SOC_IMX_HDMI_DMA) += imx-hdmi-dma.o hdmi_pcm.o
# i.MX Machine Support
snd-soc-eukrea-tlv320-objs := eukrea-tlv320.o
@@ -54,17 +72,55 @@ snd-soc-phycore-ac97-objs := phycore-ac97.o
snd-soc-mx27vis-aic32x4-objs := mx27vis-aic32x4.o
snd-soc-wm1133-ev1-objs := wm1133-ev1.o
snd-soc-imx-es8328-objs := imx-es8328.o
+snd-soc-imx-cs42888-objs := imx-cs42888.o
snd-soc-imx-sgtl5000-objs := imx-sgtl5000.o
+snd-soc-imx-wm8958-objs := imx-wm8958.o
+snd-soc-imx-wm8960-objs := imx-wm8960.o
+snd-soc-imx-wm8524-objs := imx-wm8524.o
snd-soc-imx-wm8962-objs := imx-wm8962.o
+snd-soc-imx-xtor-objs := imx-xtor.o
+snd-soc-imx-sii902x-objs := imx-sii902x.o
snd-soc-imx-spdif-objs := imx-spdif.o
snd-soc-imx-mc13783-objs := imx-mc13783.o
+snd-soc-imx-mqs-objs := imx-mqs.o
+snd-soc-imx-si476x-objs := imx-si476x.o
+snd-soc-imx-hdmi-objs := imx-hdmi.o
+snd-soc-imx-cdnhdmi-objs := imx-cdnhdmi.o
+snd-soc-imx-rpmsg-objs := imx-rpmsg.o
+snd-soc-imx-amix-objs := imx-amix.o
+snd-soc-imx-pdm-objs := imx-pdm.o
+snd-soc-imx-ak4458-objs := imx-ak4458.o
+snd-soc-imx-ak5558-objs := imx-ak5558.o
+snd-soc-imx-ak4497-objs := imx-ak4497.o
+snd-soc-imx-micfil-objs := imx-micfil.o
+snd-soc-imx-dsp-objs := imx-dsp.o
obj-$(CONFIG_SND_SOC_EUKREA_TLV320) += snd-soc-eukrea-tlv320.o
obj-$(CONFIG_SND_SOC_PHYCORE_AC97) += snd-soc-phycore-ac97.o
obj-$(CONFIG_SND_SOC_MX27VIS_AIC32X4) += snd-soc-mx27vis-aic32x4.o
obj-$(CONFIG_SND_MXC_SOC_WM1133_EV1) += snd-soc-wm1133-ev1.o
obj-$(CONFIG_SND_SOC_IMX_ES8328) += snd-soc-imx-es8328.o
+obj-$(CONFIG_SND_SOC_IMX_CS42888) += snd-soc-imx-cs42888.o
obj-$(CONFIG_SND_SOC_IMX_SGTL5000) += snd-soc-imx-sgtl5000.o
+obj-${CONFIG_SND_SOC_IMX_WM8958} += snd-soc-imx-wm8958.o
+obj-$(CONFIG_SND_SOC_IMX_WM8960) += snd-soc-imx-wm8960.o
+obj-$(CONFIG_SND_SOC_IMX_WM8524) += snd-soc-imx-wm8524.o
obj-$(CONFIG_SND_SOC_IMX_WM8962) += snd-soc-imx-wm8962.o
+obj-$(CONFIG_SND_SOC_IMX_XTOR) += snd-soc-imx-xtor.o
+obj-$(CONFIG_SND_SOC_IMX_RPMSG) += snd-soc-imx-rpmsg.o
+obj-$(CONFIG_SND_SOC_IMX_SII902X) += snd-soc-imx-sii902x.o
obj-$(CONFIG_SND_SOC_IMX_SPDIF) += snd-soc-imx-spdif.o
+obj-$(CONFIG_SND_SOC_IMX_MICFIL) += snd-soc-imx-micfil.o
obj-$(CONFIG_SND_SOC_IMX_MC13783) += snd-soc-imx-mc13783.o
+obj-$(CONFIG_SND_SOC_IMX_MQS) += snd-soc-imx-mqs.o
+obj-$(CONFIG_SND_SOC_IMX_SI476X) += snd-soc-imx-si476x.o
+obj-$(CONFIG_SND_SOC_IMX_AMIX) += snd-soc-imx-amix.o
+obj-$(CONFIG_SND_SOC_IMX_PDM_MIC) += snd-soc-imx-pdm.o
+obj-$(CONFIG_SND_SOC_IMX_AK4458) += snd-soc-imx-ak4458.o
+obj-$(CONFIG_SND_SOC_IMX_AK4497) += snd-soc-imx-ak4497.o
+obj-$(CONFIG_SND_SOC_IMX_AK5558) += snd-soc-imx-ak5558.o
+obj-$(CONFIG_SND_SOC_IMX_CDNHDMI) += snd-soc-imx-cdnhdmi.o
+obj-$(CONFIG_SND_SOC_IMX_HDMI) += snd-soc-imx-hdmi.o
+obj-$(CONFIG_SND_SOC_IMX_DSP) += snd-soc-imx-dsp.o
+
+AFLAGS_hdmi_pcm.o := -march=armv7-a -mtune=cortex-a9 -mfpu=neon -mfloat-abi=softfp
diff --git a/sound/soc/fsl/fsl_acm.c b/sound/soc/fsl/fsl_acm.c
new file mode 100644
index 000000000000..d923e92149e9
--- /dev/null
+++ b/sound/soc/fsl/fsl_acm.c
@@ -0,0 +1,55 @@
+/*
+ * Freescale ALSA SoC Digital Audio Interface (ACM) driver.
+ *
+ * Copyright 2016 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.
+ *
+ */
+#include <linux/clk.h>
+#include <linux/clkdev.h>
+#include <linux/clk-provider.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/types.h>
+#include <linux/module.h>
+#include <linux/of_platform.h>
+
+static int fsl_acm_probe(struct platform_device *pdev)
+{
+ struct resource *res;
+ void __iomem *base;
+
+ pr_info("***** imx8qm_acm_init *****\n");
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ base = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(base))
+ return PTR_ERR(base);
+
+ return 0;
+}
+
+static const struct of_device_id fsl_acm_ids[] = {
+ { .compatible = "nxp,imx8qm-acm", },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, fsl_acm_ids);
+
+static struct platform_driver fsl_acm_driver = {
+ .probe = fsl_acm_probe,
+ .driver = {
+ .name = "fsl-acm",
+ .of_match_table = fsl_acm_ids,
+ },
+};
+module_platform_driver(fsl_acm_driver);
+
+MODULE_DESCRIPTION("Freescale Soc ACM Interface");
+MODULE_ALIAS("platform:fsl-acm");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/fsl/fsl_acm.h b/sound/soc/fsl/fsl_acm.h
new file mode 100644
index 000000000000..fb05a7c95d5a
--- /dev/null
+++ b/sound/soc/fsl/fsl_acm.h
@@ -0,0 +1,93 @@
+/*
+ * fsl_acm.h - ALSA ACM interface for the Freescale i.MX SoC
+ *
+ * Copyright 2017 NXP
+ *
+ * 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 _FSL_ACM_H
+#define _FSL_ACM_H
+
+/* The offset of ACM control registers */
+#define AUD_CLK0_SEL_OFF 0x00000
+#define AUD_CLK1_SEL_OFF 0x10000
+#define MCLKOUT0_SEL_OFF 0x20000
+#define MCLKOUT1_SEL_OFF 0x30000
+#define ASRC0_CLK_SEL_OFF 0x40000
+
+#define ESAI0_CLK_SEL_OFF 0x60000
+#define ESAI1_CLK_SEL_OFF 0x70000
+#define GPT0_CLK_SEL_OFF 0x80000
+#define GPT0_CAPIN1_SEL_OFF 0x80004
+#define GPT0_CAPIN2_SEL_OFF 0x80008
+#define GPT1_CLK_SEL_OFF 0x90000
+#define GPT1_CAPIN1_SEL_OFF 0x90004
+#define GPT1_CAPIN2_SEL_OFF 0x90008
+#define GPT2_CLK_SEL_OFF 0xA0000
+#define GPT2_CAPIN1_SEL_OFF 0xA0004
+#define GPT2_CAPIN2_SEL_OFF 0xA0008
+#define GPT3_CLK_SEL_OFF 0xB0000
+#define GPT3_CAPIN1_SEL_OFF 0xB0004
+#define GPT3_CAPIN2_SEL_OFF 0xB0008
+#define GPT4_CLK_SEL_OFF 0xC0000
+#define GPT4_CAPIN1_SEL_OFF 0xC0004
+#define GPT4_CAPIN2_SEL_OFF 0xC0008
+#define GPT5_CLK_SEL_OFF 0xD0000
+#define GPT5_CAPIN1_SEL_OFF 0xD0004
+#define GPT5_CAPIN2_SEL_OFF 0xD0008
+#define SAI0_MCLK_SEL_OFF 0xE0000
+#define SAI1_MCLK_SEL_OFF 0xF0000
+#define SAI2_MCLK_SEL_OFF 0x100000
+#define SAI3_MCLK_SEL_OFF 0x110000
+#define SAI_HDMIRX0_MCLK_SEL_OFF 0x120000
+#define SAI_HDMITX0_MCLK_SEL_OFF 0x130000
+#define SAI6_MCLK_SEL_OFF 0x140000
+#define SAI7_MCLK_SEL_OFF 0x150000
+
+/* in imx8qxp SAI6=>SAI4, SAI7=>SAI5 */
+#define SAI4_MCLK_SEL_OFF 0x140000
+#define SAI5_MCLK_SEL_OFF 0x150000
+
+#define SPDIF0_TX_CLK_SEL_OFF 0x1A0000
+#define SPDIF1_TX_CLK_SEL_OFF 0x1B0000
+#define MQS_HMCLK_SEL_OFF 0x1C0000
+
+/* GPT CAPTURE Event definition*/
+#define IPI_USB0_SOF 0
+#define IPI_USB1_SOF 1
+#define IPI_USB30_ITP 2
+#define IPI_ETHERNET0_EVENT 3
+#define IPI_ETHERNET1_EVENT 4
+#define IPI_MPEG0_EVENT 5
+#define IPI_MPEG1_EVENT 6
+#define ASRC0_DMA1_REQ 7
+#define ASRC0_DMA2_REQ 8
+#define ASRC0_DMA3_REQ 9
+#define ASRC0_DMA4_REQ 10
+#define ASRC0_DMA5_REQ 11
+#define ASRC0_DMA6_REQ 12
+#define ESAI0_IPD_ESAI_RX_B 13
+#define ESAI0_IPD_ESAI_TX_B 14
+#define SPDIF0_DRQ0_SPDIF_B 15
+#define SPDIF0_DRQ1_SPDIF_B 16
+#define SPDIF1_DRQ0_SPDIF_B 17
+#define SPDIF1_DRQ1_SPDIF_B 18
+#define SAI_HDMIRX0_IPD_REQ_SAI_RX 19
+#define SAI_HDMITX0_IPD_REQ_SAI_TX 20
+#define ASRC1_DMA1_REQ 21
+#define ASRC1_DMA2_REQ 22
+#define ASRC1_DMA3_REQ 23
+#define ASRC1_DMA4_REQ 24
+#define ASRC1_DMA5_REQ 25
+#define ASRC1_DMA6_REQ 26
+#define ESAI1_IPD_ESAI_RX_B 27
+#define ESAI1_IPD_ESAI_TX_B 28
+#define SAI6_IPD_REQ_SAI_RX 29
+#define SAI6_IPD_REQ_SAI_TX 30
+#define SAI7_IPD_REQ_SAI_TX 31
+
+
+#endif /* _FSL_ACM_H */
diff --git a/sound/soc/fsl/fsl_amix.c b/sound/soc/fsl/fsl_amix.c
new file mode 100644
index 000000000000..934bc55f8b63
--- /dev/null
+++ b/sound/soc/fsl/fsl_amix.c
@@ -0,0 +1,684 @@
+/*
+ * NXP AMIX ALSA SoC Digital Audio Interface (DAI) driver
+ *
+ * Copyright 2017 NXP
+ *
+ * Author: Viorel Suman <viorel.suman@nxp.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.
+ */
+
+#include <linux/clk.h>
+#include <linux/module.h>
+#include <linux/of_platform.h>
+#include <linux/pm_runtime.h>
+#include <sound/soc.h>
+#include <sound/pcm_params.h>
+
+#include "fsl_amix.h"
+
+#define SOC_ENUM_SINGLE_S(xreg, xshift, xtexts) \
+ SOC_ENUM_SINGLE(xreg, xshift, ARRAY_SIZE(xtexts), xtexts)
+
+typedef int (*fsl_amix_state_handler)(struct snd_soc_component *comp,
+ unsigned int *mask, unsigned int *ctr);
+
+static const char
+ *tdm_sel[] = { "TDM1", "TDM2", },
+ *mode_sel[] = { "Disabled", "TDM1", "TDM2", "Mixed", },
+ *width_sel[] = { "16b", "18b", "20b", "24b", "32b", },
+ *pol_sel[] = { "Positive edge", "Negative edge", },
+ *endis_sel[] = { "Disabled", "Enabled", },
+ *updn_sel[] = { "Downward", "Upward", },
+ *mask_sel[] = { "Unmask", "Mask", };
+
+static const struct soc_enum fsl_amix_enum[] = {
+/* FSL_AMIX_CTR enums */
+SOC_ENUM_SINGLE_S(FSL_AMIX_CTR, FSL_AMIX_CTR_MIXCLK_SHIFT, tdm_sel),
+SOC_ENUM_SINGLE_S(FSL_AMIX_CTR, FSL_AMIX_CTR_OUTSRC_SHIFT, mode_sel),
+SOC_ENUM_SINGLE_S(FSL_AMIX_CTR, FSL_AMIX_CTR_OUTWIDTH_SHIFT, width_sel),
+SOC_ENUM_SINGLE_S(FSL_AMIX_CTR, FSL_AMIX_CTR_OUTCKPOL_SHIFT, pol_sel),
+SOC_ENUM_SINGLE_S(FSL_AMIX_CTR, FSL_AMIX_CTR_MASKRTDF_SHIFT, mask_sel),
+SOC_ENUM_SINGLE_S(FSL_AMIX_CTR, FSL_AMIX_CTR_MASKCKDF_SHIFT, mask_sel),
+SOC_ENUM_SINGLE_S(FSL_AMIX_CTR, FSL_AMIX_CTR_SYNCMODE_SHIFT, endis_sel),
+SOC_ENUM_SINGLE_S(FSL_AMIX_CTR, FSL_AMIX_CTR_SYNCSRC_SHIFT, tdm_sel),
+/* FSL_AMIX_ATCR0 enums */
+SOC_ENUM_SINGLE_S(FSL_AMIX_ATCR0, 0, endis_sel),
+SOC_ENUM_SINGLE_S(FSL_AMIX_ATCR0, 1, updn_sel),
+/* FSL_AMIX_ATCR1 enums */
+SOC_ENUM_SINGLE_S(FSL_AMIX_ATCR1, 0, endis_sel),
+SOC_ENUM_SINGLE_S(FSL_AMIX_ATCR1, 1, updn_sel),
+};
+
+static int fsl_amix_state_dis_tdm1(struct snd_soc_component *comp,
+ unsigned int *mask, unsigned int *ctr)
+{
+ struct fsl_amix *priv = snd_soc_component_get_drvdata(comp);
+ /* Enforce the proper TDM is started */
+ if (!(priv->tdms & BIT(0))) {
+ dev_err(comp->dev, "DIS->TDM1: TDM1 is not started!\n");
+ return -EINVAL;
+ }
+ /* Set mix clock */
+ (*mask) |= FSL_AMIX_CTR_MIXCLK_MASK;
+ (*ctr) |= FSL_AMIX_CTR_MIXCLK(0);
+ return 0;
+}
+
+static int fsl_amix_state_dis_tdm2(struct snd_soc_component *comp,
+ unsigned int *mask, unsigned int *ctr)
+{
+ struct fsl_amix *priv = snd_soc_component_get_drvdata(comp);
+ /* Enforce the proper TDM is started */
+ if (!(priv->tdms & BIT(1))) {
+ dev_err(comp->dev, "DIS->TDM2: TDM2 is not started!\n");
+ return -EINVAL;
+ }
+ /* Set mix clock */
+ (*mask) |= FSL_AMIX_CTR_MIXCLK_MASK;
+ (*ctr) |= FSL_AMIX_CTR_MIXCLK(1);
+ return 0;
+}
+
+static int fsl_amix_state_tdm1_dis(struct snd_soc_component *comp,
+ unsigned int *mask, unsigned int *ctr)
+{
+ struct fsl_amix *priv = snd_soc_component_get_drvdata(comp);
+ /* Enforce the proper TDM is started */
+ if (!(priv->tdms & BIT(0))) {
+ dev_err(comp->dev, "TDM1->DIS: TDM1 is not started!\n");
+ return -EINVAL;
+ }
+ /* Keep mix clock unchanged */
+ return 0;
+}
+
+static int fsl_amix_state_tdm2_dis(struct snd_soc_component *comp,
+ unsigned int *mask, unsigned int *ctr)
+{
+ struct fsl_amix *priv = snd_soc_component_get_drvdata(comp);
+ /* Enforce the proper TDM is started */
+ if (!(priv->tdms & BIT(1))) {
+ dev_err(comp->dev, "TDM2->DIS: TDM2 is not started!\n");
+ return -EINVAL;
+ }
+ /* Keep mix clock unchanged */
+ return 0;
+}
+
+static int fsl_amix_state_dis_mix(struct snd_soc_component *comp,
+ unsigned int *mask, unsigned int *ctr)
+{
+ struct fsl_amix *priv = snd_soc_component_get_drvdata(comp);
+ /* Enforce all TDMs are started */
+ if (priv->tdms != 3) {
+ dev_err(comp->dev, "DIS->MIX: Please start both TDMs!\n");
+ return -EINVAL;
+ }
+ /* Keep mix clock unchanged */
+ return 0;
+}
+
+static int fsl_amix_state_tdm1_tdm2(struct snd_soc_component *comp,
+ unsigned int *mask, unsigned int *ctr)
+{
+ struct fsl_amix *priv = snd_soc_component_get_drvdata(comp);
+ /* Enforce all TDMs are started */
+ if (priv->tdms != 3) {
+ dev_err(comp->dev, "TDM1->TDM2: Please start both TDMs!\n");
+ return -EINVAL;
+ }
+ /* Set mix clock */
+ (*mask) |= FSL_AMIX_CTR_MIXCLK_MASK;
+ (*ctr) |= FSL_AMIX_CTR_MIXCLK(1);
+ return 0;
+}
+
+static int fsl_amix_state_tdm2_tdm1(struct snd_soc_component *comp,
+ unsigned int *mask, unsigned int *ctr)
+{
+ struct fsl_amix *priv = snd_soc_component_get_drvdata(comp);
+ /* Enforce all TDMs are started */
+ if (priv->tdms != 3) {
+ dev_err(comp->dev, "TDM2->TDM1: Please start both TDMs!\n");
+ return -EINVAL;
+ }
+ /* Set mix clock */
+ (*mask) |= FSL_AMIX_CTR_MIXCLK_MASK;
+ (*ctr) |= FSL_AMIX_CTR_MIXCLK(0);
+ return 0;
+}
+
+static int fsl_amix_state_tdm1_mix(struct snd_soc_component *comp,
+ unsigned int *mask, unsigned int *ctr)
+{
+ struct fsl_amix *priv = snd_soc_component_get_drvdata(comp);
+ /* Enforce all TDMs are started */
+ if (priv->tdms != 3) {
+ dev_err(comp->dev, "TDM1->MIX: Please start both TDMs!\n");
+ return -EINVAL;
+ }
+ /* Keep mix clock unchanged */
+ return 0;
+}
+
+static int fsl_amix_state_tdm2_mix(struct snd_soc_component *comp,
+ unsigned int *mask, unsigned int *ctr)
+{
+ struct fsl_amix *priv = snd_soc_component_get_drvdata(comp);
+ /* Enforce all TDMs are started */
+ if (priv->tdms != 3) {
+ dev_err(comp->dev, "TDM2->MIX: Please start both TDMs!\n");
+ return -EINVAL;
+ }
+ /* Keep mix clock unchanged */
+ return 0;
+}
+
+static int fsl_amix_state_mix_tdm1(struct snd_soc_component *comp,
+ unsigned int *mask, unsigned int *ctr)
+{
+ struct fsl_amix *priv = snd_soc_component_get_drvdata(comp);
+ /* Enforce all TDMs are started */
+ if (priv->tdms != 3) {
+ dev_err(comp->dev, "MIX->TDM1: Please start both TDMs!\n");
+ return -EINVAL;
+ }
+ /* Set mix clock */
+ (*mask) |= FSL_AMIX_CTR_MIXCLK_MASK;
+ (*ctr) |= FSL_AMIX_CTR_MIXCLK(0);
+ return 0;
+}
+
+static int fsl_amix_state_mix_tdm2(struct snd_soc_component *comp,
+ unsigned int *mask, unsigned int *ctr)
+{
+ struct fsl_amix *priv = snd_soc_component_get_drvdata(comp);
+ /* Enforce all TDMs are started */
+ if (priv->tdms != 3) {
+ dev_err(comp->dev, "MIX->TDM2: Please start both TDMs!\n");
+ return -EINVAL;
+ }
+ /* Set mix clock */
+ (*mask) |= FSL_AMIX_CTR_MIXCLK_MASK;
+ (*ctr) |= FSL_AMIX_CTR_MIXCLK(1);
+ return 0;
+}
+
+static int fsl_amix_state_mix_dis(struct snd_soc_component *comp,
+ unsigned int *mask, unsigned int *ctr)
+{
+ struct fsl_amix *priv = snd_soc_component_get_drvdata(comp);
+ /* Enforce all TDMs are started */
+ if (priv->tdms != 3) {
+ dev_err(comp->dev, "MIX->DIS: Please start both TDMs!\n");
+ return -EINVAL;
+ }
+ /* Keep mix clock unchanged */
+ return 0;
+}
+
+static const fsl_amix_state_handler state_machine[4][4] = {
+ /* From Disabled */
+ {
+ 0, /* To Disabled, do nothing */
+ fsl_amix_state_dis_tdm1, /* To TDM1*/
+ fsl_amix_state_dis_tdm2, /* To TDM2 */
+ fsl_amix_state_dis_mix /* To Mixed */
+ },
+ /* From TDM1 */
+ {
+ fsl_amix_state_tdm1_dis, /* To Disabled */
+ 0, /* To TDM1, do nothing */
+ fsl_amix_state_tdm1_tdm2, /* To TDM2 */
+ fsl_amix_state_tdm1_mix /* To Mixed */
+ },
+ /* From TDM2 */
+ {
+ fsl_amix_state_tdm2_dis, /* To Disabled */
+ fsl_amix_state_tdm2_tdm1, /* To TDM1 */
+ 0, /* To TDM2, do nothing */
+ fsl_amix_state_tdm2_mix /* To Mixed */
+ },
+ /* From Mixed */
+ {
+ fsl_amix_state_mix_dis, /* To Disabled */
+ fsl_amix_state_mix_tdm1, /* To TDM1 */
+ fsl_amix_state_mix_tdm2, /* To TDM2 */
+ 0 /* To Mixed, do nothing */
+ }
+};
+
+static int fsl_amix_put_mix_clk_src(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol);
+ struct fsl_amix *priv = snd_soc_component_get_drvdata(comp);
+ struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
+ unsigned int *item = ucontrol->value.enumerated.item;
+ unsigned int reg_val, val, mix_clk;
+ int ret = 0;
+
+ /* Get current state */
+ ret = snd_soc_component_read(comp, FSL_AMIX_CTR, &reg_val);
+ if (ret)
+ return ret;
+
+ mix_clk = reg_val & 1;
+ val = snd_soc_enum_item_to_val(e, item[0]);
+
+ dev_dbg(comp->dev, "[%s]: TDMs=x%08x, val=x%08x\n", __func__, priv->tdms, val);
+
+ /**
+ * Ensure the current selected mixer clock is available
+ * for configuration propagation
+ */
+ if (!(priv->tdms & BIT(mix_clk))) {
+ dev_err(comp->dev, "MIXCLK: A started TDM%d is required "
+ "for configuration propagation!\n", mix_clk + 1);
+ return -EINVAL;
+ }
+
+ if (!(priv->tdms & BIT(val))) {
+ dev_err(comp->dev, "The selected clock source has "
+ "no TDM%d enabled!\n", val + 1);
+ return -EINVAL;
+ }
+
+ return snd_soc_put_enum_double(kcontrol, ucontrol);
+}
+
+static int fsl_amix_put_out_src(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol);
+ struct fsl_amix *priv = snd_soc_component_get_drvdata(comp);
+ struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
+ unsigned int *item = ucontrol->value.enumerated.item;
+ u32 out_src, mix_clk;
+ unsigned int reg_val, val, mask = 0, ctr = 0;
+ int ret = 0;
+
+ /* Get current state */
+ ret = snd_soc_component_read(comp, FSL_AMIX_CTR, &reg_val);
+ if (ret)
+ return ret;
+
+ /* "From" state */
+ out_src = ((reg_val & FSL_AMIX_CTR_OUTSRC_MASK) >> FSL_AMIX_CTR_OUTSRC_SHIFT);
+ mix_clk = reg_val & 1;
+
+ /* "To" state */
+ val = snd_soc_enum_item_to_val(e, item[0]);
+
+ dev_dbg(comp->dev, "[%s]: TDMs=x%08x, val=x%08x\n", __func__, priv->tdms, val);
+
+ /* Check if state is changing ... */
+ if (!state_machine[out_src][val])
+ return 0;
+ /**
+ * Ensure the current selected mixer clock is available
+ * for configuration propagation
+ */
+ if (!(priv->tdms & BIT(mix_clk))) {
+ dev_err(comp->dev, "MIXCLK: A started TDM%d is required "
+ "for configuration propagation!\n", mix_clk + 1);
+ return -EINVAL;
+ }
+ /* Check state transition constraints */
+ ret = state_machine[out_src][val](comp, &mask, &ctr);
+ if (ret)
+ return ret;
+
+ /* Complete transition to new state */
+ mask |= FSL_AMIX_CTR_OUTSRC_MASK;
+ ctr |= FSL_AMIX_CTR_OUTSRC(val);
+
+ return snd_soc_component_update_bits(comp, FSL_AMIX_CTR, mask, ctr);
+}
+
+static const struct snd_kcontrol_new fsl_amix_snd_controls[] = {
+ /* FSL_AMIX_CTR controls */
+ SOC_ENUM_EXT("Mixing Clock Source", fsl_amix_enum[0],
+ snd_soc_get_enum_double, fsl_amix_put_mix_clk_src),
+ SOC_ENUM_EXT("Output Source", fsl_amix_enum[1],
+ snd_soc_get_enum_double, fsl_amix_put_out_src),
+ SOC_ENUM("Output Width", fsl_amix_enum[2]),
+ SOC_ENUM("Output Clock Polarity", fsl_amix_enum[3]),
+ SOC_ENUM("Frame Rate Diff Error", fsl_amix_enum[4]),
+ SOC_ENUM("Clock Freq Diff Error", fsl_amix_enum[5]),
+ SOC_ENUM("Sync Mode Config", fsl_amix_enum[6]),
+ SOC_ENUM("Sync Mode Clk Source", fsl_amix_enum[7]),
+ /* TDM1 Attenuation controls */
+ SOC_ENUM("TDM1 Attenuation", fsl_amix_enum[8]),
+ SOC_ENUM("TDM1 Attenuation Direction", fsl_amix_enum[9]),
+ SOC_SINGLE("TDM1 Attenuation Step Divider", FSL_AMIX_ATCR0,
+ 2, 0x00fff, 0),
+ SOC_SINGLE("TDM1 Attenuation Initial Value", FSL_AMIX_ATIVAL0,
+ 0, 0x3ffff, 0),
+ SOC_SINGLE("TDM1 Attenuation Step Up Factor", FSL_AMIX_ATSTPUP0,
+ 0, 0x3ffff, 0),
+ SOC_SINGLE("TDM1 Attenuation Step Down Factor", FSL_AMIX_ATSTPDN0,
+ 0, 0x3ffff, 0),
+ SOC_SINGLE("TDM1 Attenuation Step Target", FSL_AMIX_ATSTPTGT0,
+ 0, 0x3ffff, 0),
+ /* TDM2 Attenuation controls */
+ SOC_ENUM("TDM2 Attenuation", fsl_amix_enum[10]),
+ SOC_ENUM("TDM2 Attenuation Direction", fsl_amix_enum[11]),
+ SOC_SINGLE("TDM2 Attenuation Step Divider", FSL_AMIX_ATCR1,
+ 2, 0x00fff, 0),
+ SOC_SINGLE("TDM2 Attenuation Initial Value", FSL_AMIX_ATIVAL1,
+ 0, 0x3ffff, 0),
+ SOC_SINGLE("TDM2 Attenuation Step Up Factor", FSL_AMIX_ATSTPUP1,
+ 0, 0x3ffff, 0),
+ SOC_SINGLE("TDM2 Attenuation Step Down Factor", FSL_AMIX_ATSTPDN1,
+ 0, 0x3ffff, 0),
+ SOC_SINGLE("TDM2 Attenuation Step Target", FSL_AMIX_ATSTPTGT1,
+ 0, 0x3ffff, 0),
+};
+
+static int fsl_amix_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
+{
+ struct fsl_amix *priv = snd_soc_dai_get_drvdata(dai);
+ u32 mask = 0, ctr = 0;
+
+ /* AMIX is working in DSP_A format only */
+ switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+ case SND_SOC_DAIFMT_DSP_A:
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ /* For playback the AMIX is slave, and for record is master */
+ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+ case SND_SOC_DAIFMT_CBM_CFM:
+ case SND_SOC_DAIFMT_CBS_CFS:
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
+ case SND_SOC_DAIFMT_IB_NF:
+ /* Output data will be written on positive edge of the clock */
+ ctr |= FSL_AMIX_CTR_OUTCKPOL(0);
+ break;
+ case SND_SOC_DAIFMT_NB_NF:
+ /* Output data will be written on negative edge of the clock */
+ ctr |= FSL_AMIX_CTR_OUTCKPOL(1);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ mask |= FSL_AMIX_CTR_OUTCKPOL_MASK;
+
+ return regmap_update_bits(priv->regmap, FSL_AMIX_CTR, mask, ctr);
+}
+
+static int fsl_amix_dai_trigger(struct snd_pcm_substream *substream, int cmd,
+ struct snd_soc_dai *dai)
+{
+ struct fsl_amix *priv = snd_soc_dai_get_drvdata(dai);
+
+ /* Capture stream shall not be handled */
+ if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
+ return 0;
+
+ switch (cmd) {
+ case SNDRV_PCM_TRIGGER_START:
+ case SNDRV_PCM_TRIGGER_RESUME:
+ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+ priv->tdms |= BIT(dai->driver->id);
+ break;
+ case SNDRV_PCM_TRIGGER_STOP:
+ case SNDRV_PCM_TRIGGER_SUSPEND:
+ case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+ priv->tdms &= ~BIT(dai->driver->id);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static struct snd_soc_dai_ops fsl_amix_dai_ops = {
+ .set_fmt = fsl_amix_dai_set_fmt,
+ .trigger = fsl_amix_dai_trigger,
+};
+
+static struct snd_soc_dai_driver fsl_amix_dai[] = {
+ {
+ .id = 0,
+ .name = "amix-0",
+ .playback = {
+ .stream_name = "AMIX-Playback-0",
+ .channels_min = 8,
+ .channels_max = 8,
+ .rate_min = 8000,
+ .rate_max = 96000,
+ .rates = SNDRV_PCM_RATE_8000_96000,
+ .formats = FSL_AMIX_FORMATS,
+ },
+ .capture = {
+ .stream_name = "AMIX-Capture-0",
+ .channels_min = 8,
+ .channels_max = 8,
+ .rate_min = 8000,
+ .rate_max = 96000,
+ .rates = SNDRV_PCM_RATE_8000_96000,
+ .formats = FSL_AMIX_FORMATS,
+ },
+ .ops = &fsl_amix_dai_ops,
+ },
+ {
+ .id = 1,
+ .name = "amix-1",
+ .playback = {
+ .stream_name = "AMIX-Playback-1",
+ .channels_min = 8,
+ .channels_max = 8,
+ .rate_min = 8000,
+ .rate_max = 96000,
+ .rates = SNDRV_PCM_RATE_8000_96000,
+ .formats = FSL_AMIX_FORMATS,
+ },
+ .capture = {
+ .stream_name = "AMIX-Capture-1",
+ .channels_min = 8,
+ .channels_max = 8,
+ .rate_min = 8000,
+ .rate_max = 96000,
+ .rates = SNDRV_PCM_RATE_8000_96000,
+ .formats = FSL_AMIX_FORMATS,
+ },
+ .ops = &fsl_amix_dai_ops,
+ },
+};
+
+static const struct snd_soc_component_driver fsl_amix_component = {
+ .name = "fsl-amix-dai",
+ .controls = fsl_amix_snd_controls,
+ .num_controls = ARRAY_SIZE(fsl_amix_snd_controls),
+};
+
+static bool fsl_amix_readable_reg(struct device *dev, unsigned int reg)
+{
+ switch (reg) {
+ case FSL_AMIX_CTR:
+ case FSL_AMIX_STR:
+ case FSL_AMIX_ATCR0:
+ case FSL_AMIX_ATIVAL0:
+ case FSL_AMIX_ATSTPUP0:
+ case FSL_AMIX_ATSTPDN0:
+ case FSL_AMIX_ATSTPTGT0:
+ case FSL_AMIX_ATTNVAL0:
+ case FSL_AMIX_ATSTP0:
+ case FSL_AMIX_ATCR1:
+ case FSL_AMIX_ATIVAL1:
+ case FSL_AMIX_ATSTPUP1:
+ case FSL_AMIX_ATSTPDN1:
+ case FSL_AMIX_ATSTPTGT1:
+ case FSL_AMIX_ATTNVAL1:
+ case FSL_AMIX_ATSTP1:
+ return true;
+ default:
+ return false;
+ }
+}
+
+static bool fsl_amix_writeable_reg(struct device *dev, unsigned int reg)
+{
+ switch (reg) {
+ case FSL_AMIX_CTR:
+ case FSL_AMIX_ATCR0:
+ case FSL_AMIX_ATIVAL0:
+ case FSL_AMIX_ATSTPUP0:
+ case FSL_AMIX_ATSTPDN0:
+ case FSL_AMIX_ATSTPTGT0:
+ case FSL_AMIX_ATCR1:
+ case FSL_AMIX_ATIVAL1:
+ case FSL_AMIX_ATSTPUP1:
+ case FSL_AMIX_ATSTPDN1:
+ case FSL_AMIX_ATSTPTGT1:
+ return true;
+ default:
+ return false;
+ }
+}
+
+static struct reg_default fsl_amix_reg[] = {
+ { FSL_AMIX_CTR, 0x00060 },
+ { FSL_AMIX_STR, 0x00003 },
+ { FSL_AMIX_ATCR0, 0x00000 },
+ { FSL_AMIX_ATIVAL0, 0x3FFFF },
+ { FSL_AMIX_ATSTPUP0, 0x2AAAA },
+ { FSL_AMIX_ATSTPDN0, 0x30000 },
+ { FSL_AMIX_ATSTPTGT0, 0x00010 },
+ { FSL_AMIX_ATTNVAL0, 0x00000 },
+ { FSL_AMIX_ATSTP0, 0x00000 },
+ { FSL_AMIX_ATCR1, 0x00000 },
+ { FSL_AMIX_ATIVAL1, 0x3FFFF },
+ { FSL_AMIX_ATSTPUP1, 0x2AAAA },
+ { FSL_AMIX_ATSTPDN1, 0x30000 },
+ { FSL_AMIX_ATSTPTGT1, 0x00010 },
+ { FSL_AMIX_ATTNVAL1, 0x00000 },
+ { FSL_AMIX_ATSTP1, 0x00000 },
+};
+
+static const struct regmap_config fsl_amix_regmap_config = {
+ .reg_bits = 32,
+ .reg_stride = 4,
+ .val_bits = 32,
+ .max_register = FSL_AMIX_ATSTP1,
+ .reg_defaults = fsl_amix_reg,
+ .num_reg_defaults = ARRAY_SIZE(fsl_amix_reg),
+ .readable_reg = fsl_amix_readable_reg,
+ .writeable_reg = fsl_amix_writeable_reg,
+ .cache_type = REGCACHE_FLAT,
+};
+
+static int fsl_amix_probe(struct platform_device *pdev)
+{
+ struct fsl_amix *priv;
+ struct resource *res;
+ void __iomem *regs;
+ int ret;
+
+ priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ priv->pdev = pdev;
+
+ /* Get the addresses */
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ regs = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(regs))
+ return PTR_ERR(regs);
+
+ priv->regmap = devm_regmap_init_mmio_clk(&pdev->dev, "ipg", regs,
+ &fsl_amix_regmap_config);
+ if (IS_ERR(priv->regmap)) {
+ dev_err(&pdev->dev, "failed to init regmap\n");
+ return PTR_ERR(priv->regmap);
+ }
+
+ priv->ipg_clk = devm_clk_get(&pdev->dev, "ipg");
+ if (IS_ERR(priv->ipg_clk)) {
+ dev_err(&pdev->dev, "failed to get ipg clock\n");
+ return PTR_ERR(priv->ipg_clk);
+ }
+
+ platform_set_drvdata(pdev, priv);
+ pm_runtime_enable(&pdev->dev);
+
+ ret = devm_snd_soc_register_component(&pdev->dev, &fsl_amix_component,
+ fsl_amix_dai, ARRAY_SIZE(fsl_amix_dai));
+ if (ret) {
+ dev_err(&pdev->dev, "failed to register ASoC DAI\n");
+ return ret;
+ }
+
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int fsl_amix_runtime_resume(struct device *dev)
+{
+ struct fsl_amix *priv = dev_get_drvdata(dev);
+ int ret;
+
+ ret = clk_prepare_enable(priv->ipg_clk);
+ if (ret) {
+ dev_err(dev, "Failed to enable IPG clock: %d\n", ret);
+ return ret;
+ }
+
+ regcache_cache_only(priv->regmap, false);
+ regcache_mark_dirty(priv->regmap);
+
+ return regcache_sync(priv->regmap);
+}
+
+static int fsl_amix_runtime_suspend(struct device *dev)
+{
+ struct fsl_amix *priv = dev_get_drvdata(dev);
+
+ regcache_cache_only(priv->regmap, true);
+
+ clk_disable_unprepare(priv->ipg_clk);
+
+ return 0;
+}
+#endif /* CONFIG_PM */
+
+static const struct dev_pm_ops fsl_amix_pm = {
+ SET_RUNTIME_PM_OPS(fsl_amix_runtime_suspend, fsl_amix_runtime_resume, NULL)
+ SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, pm_runtime_force_resume)
+};
+
+static const struct of_device_id fsl_amix_ids[] = {
+ { .compatible = "fsl,imx8qm-amix", },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, fsl_amix_ids);
+
+static struct platform_driver fsl_amix_driver = {
+ .probe = fsl_amix_probe,
+ .driver = {
+ .name = "fsl-amix",
+ .of_match_table = fsl_amix_ids,
+ .pm = &fsl_amix_pm,
+ },
+};
+module_platform_driver(fsl_amix_driver);
+
+MODULE_DESCRIPTION("NXP AMIX ASoC DAI driver");
+MODULE_AUTHOR("Viorel Suman <viorel.suman@nxp.com>");
+MODULE_ALIAS("platform:fsl-amix");
+MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/fsl/fsl_amix.h b/sound/soc/fsl/fsl_amix.h
new file mode 100644
index 000000000000..582fb981849d
--- /dev/null
+++ b/sound/soc/fsl/fsl_amix.h
@@ -0,0 +1,102 @@
+/*
+ * Copyright 2017 NXP Corp.
+ *
+ * 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 __FSL_AMIX_H
+#define __FSL_AMIX_H
+
+#define FSL_AMIX_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
+ SNDRV_PCM_FMTBIT_S24_LE |\
+ SNDRV_PCM_FMTBIT_S32_LE)
+/* AMIX Registers */
+#define FSL_AMIX_CTR 0x200 /* Control */
+#define FSL_AMIX_STR 0x204 /* Status */
+
+#define FSL_AMIX_ATCR0 0x208 /* Attenuation Control */
+#define FSL_AMIX_ATIVAL0 0x20c /* Attenuation Initial Value */
+#define FSL_AMIX_ATSTPUP0 0x210 /* Attenuation step up factor */
+#define FSL_AMIX_ATSTPDN0 0x214 /* Attenuation step down factor */
+#define FSL_AMIX_ATSTPTGT0 0x218 /* Attenuation step target */
+#define FSL_AMIX_ATTNVAL0 0x21c /* Attenuation Value */
+#define FSL_AMIX_ATSTP0 0x220 /* Attenuation step number */
+
+#define FSL_AMIX_ATCR1 0x228 /* Attenuation Control */
+#define FSL_AMIX_ATIVAL1 0x22c /* Attenuation Initial Value */
+#define FSL_AMIX_ATSTPUP1 0x230 /* Attenuation step up factor */
+#define FSL_AMIX_ATSTPDN1 0x234 /* Attenuation step down factor */
+#define FSL_AMIX_ATSTPTGT1 0x238 /* Attenuation step target */
+#define FSL_AMIX_ATTNVAL1 0x23c /* Attenuation Value */
+#define FSL_AMIX_ATSTP1 0x240 /* Attenuation step number */
+
+/* AMIX Control Register */
+#define FSL_AMIX_CTR_MIXCLK_SHIFT 0
+#define FSL_AMIX_CTR_MIXCLK_MASK (1 << FSL_AMIX_CTR_MIXCLK_SHIFT)
+#define FSL_AMIX_CTR_MIXCLK(i) ((i) << FSL_AMIX_CTR_MIXCLK_SHIFT)
+#define FSL_AMIX_CTR_OUTSRC_SHIFT 1
+#define FSL_AMIX_CTR_OUTSRC_MASK (0x3 << FSL_AMIX_CTR_OUTSRC_SHIFT)
+#define FSL_AMIX_CTR_OUTSRC(i) (((i) << FSL_AMIX_CTR_OUTSRC_SHIFT) \
+ & FSL_AMIX_CTR_OUTSRC_MASK)
+#define FSL_AMIX_CTR_OUTWIDTH_SHIFT 3
+#define FSL_AMIX_CTR_OUTWIDTH_MASK (0x7 << FSL_AMIX_CTR_OUTWIDTH_SHIFT)
+#define FSL_AMIX_CTR_OUTWIDTH(i) (((i) << FSL_AMIX_CTR_OUTWIDTH_SHIFT) \
+ & FSL_AMIX_CTR_OUTWIDTH_MASK)
+#define FSL_AMIX_CTR_OUTCKPOL_SHIFT 6
+#define FSL_AMIX_CTR_OUTCKPOL_MASK (1 << FSL_AMIX_CTR_OUTCKPOL_SHIFT)
+#define FSL_AMIX_CTR_OUTCKPOL(i) ((i) << FSL_AMIX_CTR_OUTCKPOL_SHIFT)
+#define FSL_AMIX_CTR_MASKRTDF_SHIFT 7
+#define FSL_AMIX_CTR_MASKRTDF_MASK (1 << FSL_AMIX_CTR_MASKRTDF_SHIFT)
+#define FSL_AMIX_CTR_MASKRTDF(i) ((i) << FSL_AMIX_CTR_MASKRTDF_SHIFT)
+#define FSL_AMIX_CTR_MASKCKDF_SHIFT 8
+#define FSL_AMIX_CTR_MASKCKDF_MASK (1 << FSL_AMIX_CTR_MASKCKDF_SHIFT)
+#define FSL_AMIX_CTR_MASKCKDF(i) ((i) << FSL_AMIX_CTR_MASKCKDF_SHIFT)
+#define FSL_AMIX_CTR_SYNCMODE_SHIFT 9
+#define FSL_AMIX_CTR_SYNCMODE_MASK (1 << FSL_AMIX_CTR_SYNCMODE_SHIFT)
+#define FSL_AMIX_CTR_SYNCMODE(i) ((i) << FSL_AMIX_CTR_SYNCMODE_SHIFT)
+#define FSL_AMIX_CTR_SYNCSRC_SHIFT 10
+#define FSL_AMIX_CTR_SYNCSRC_MASK (1 << FSL_AMIX_CTR_SYNCSRC_SHIFT)
+#define FSL_AMIX_CTR_SYNCSRC(i) ((i) << FSL_AMIX_CTR_SYNCSRC_SHIFT)
+
+/* AMIX Status Register */
+#define FSL_AMIX_STR_RATEDIFF BIT(0)
+#define FSL_AMIX_STR_CLKDIFF BIT(1)
+#define FSL_AMIX_STR_MIXSTAT_SHIFT 2
+#define FSL_AMIX_STR_MIXSTAT_MASK (0x3 << FSL_AMIX_STR_MIXSTAT_SHIFT)
+#define FSL_AMIX_STR_MIXSTAT(i) ((i & FSL_AMIX_STR_MIXSTAT_MASK) \
+ >> FSL_AMIX_STR_MIXSTAT_SHIFT)
+/* AMIX Attenuation Control Register */
+#define FSL_AMIX_ATCR_AT_EN BIT(0)
+#define FSL_AMIX_ATCR_AT_UPDN BIT(1)
+#define FSL_AMIX_ATCR_ATSTPDIF_SHIFT 2
+#define FSL_AMIX_ATCR_ATSTPDFI_MASK (0xfff << FSL_AMIX_ATCR_ATSTPDIF_SHIFT)
+
+/* AMIX Attenuation Initial Value Register */
+#define FSL_AMIX_ATIVAL_ATINVAL_MASK 0x3FFFF
+
+/* AMIX Attenuation Step Up Factor Register */
+#define FSL_AMIX_ATSTPUP_ATSTEPUP_MASK 0x3FFFF
+
+/* AMIX Attenuation Step Down Factor Register */
+#define FSL_AMIX_ATSTPDN_ATSTEPDN_MASK 0x3FFFF
+
+/* AMIX Attenuation Step Target Register */
+#define FSL_AMIX_ATSTPTGT_ATSTPTG_MASK 0x3FFFF
+
+/* AMIX Attenuation Value Register */
+#define FSL_AMIX_ATTNVAL_ATCURVAL_MASK 0x3FFFF
+
+/* AMIX Attenuation Step Number Register */
+#define FSL_AMIX_ATSTP_STPCTR_MASK 0x3FFFF
+
+#define FSL_AMIX_MAX_DAIS 2
+struct fsl_amix {
+ struct platform_device *pdev;
+ struct regmap *regmap;
+ struct clk *ipg_clk;
+ u8 tdms;
+};
+
+#endif /* __FSL_AMIX_H */
diff --git a/sound/soc/fsl/fsl_asrc.c b/sound/soc/fsl/fsl_asrc.c
index eeaeffb1a7fd..f0d75177cde3 100644
--- a/sound/soc/fsl/fsl_asrc.c
+++ b/sound/soc/fsl/fsl_asrc.c
@@ -1,7 +1,8 @@
/*
* Freescale ASRC ALSA SoC Digital Audio Interface (DAI) driver
*
- * Copyright (C) 2014 Freescale Semiconductor, Inc.
+ * Copyright (C) 2014-2016 Freescale Semiconductor, Inc.
+ * Copyright 2017 NXP
*
* Author: Nicolin Chen <nicoleotsuka@gmail.com>
*
@@ -17,71 +18,92 @@
#include <linux/of_platform.h>
#include <linux/platform_data/dma-imx.h>
#include <linux/pm_runtime.h>
+#include <linux/miscdevice.h>
+#include <linux/sched/signal.h>
#include <sound/dmaengine_pcm.h>
#include <sound/pcm_params.h>
#include "fsl_asrc.h"
+#include "imx-pcm.h"
#define IDEAL_RATIO_DECIMAL_DEPTH 26
#define pair_err(fmt, ...) \
dev_err(&asrc_priv->pdev->dev, "Pair %c: " fmt, 'A' + index, ##__VA_ARGS__)
+#define pair_warn(fmt, ...) \
+ dev_warn(&asrc_priv->pdev->dev, "Pair %c: " fmt, 'A' + index, ##__VA_ARGS__)
+
#define pair_dbg(fmt, ...) \
dev_dbg(&asrc_priv->pdev->dev, "Pair %c: " fmt, 'A' + index, ##__VA_ARGS__)
-/* Sample rates are aligned with that defined in pcm.h file */
-static const u8 process_option[][12][2] = {
- /* 8kHz 11.025kHz 16kHz 22.05kHz 32kHz 44.1kHz 48kHz 64kHz 88.2kHz 96kHz 176kHz 192kHz */
- {{0, 1}, {0, 1}, {0, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},}, /* 5512Hz */
- {{0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},}, /* 8kHz */
- {{0, 2}, {0, 1}, {0, 1}, {0, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},}, /* 11025Hz */
- {{1, 2}, {0, 2}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},}, /* 16kHz */
- {{1, 2}, {1, 2}, {0, 2}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},}, /* 22050Hz */
- {{1, 2}, {2, 1}, {2, 1}, {0, 2}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 0}, {0, 0}, {0, 0},}, /* 32kHz */
- {{2, 2}, {2, 2}, {2, 1}, {2, 1}, {0, 2}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 0}, {0, 0},}, /* 44.1kHz */
- {{2, 2}, {2, 2}, {2, 1}, {2, 1}, {0, 2}, {0, 2}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 0}, {0, 0},}, /* 48kHz */
- {{2, 2}, {2, 2}, {2, 2}, {2, 1}, {1, 2}, {0, 2}, {0, 2}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 0},}, /* 64kHz */
- {{2, 2}, {2, 2}, {2, 2}, {2, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1},}, /* 88.2kHz */
- {{2, 2}, {2, 2}, {2, 2}, {2, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1},}, /* 96kHz */
- {{2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 1}, {2, 1}, {2, 1}, {2, 1}, {2, 1},}, /* 176kHz */
- {{2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 1}, {2, 1}, {2, 1}, {2, 1}, {2, 1},}, /* 192kHz */
-};
-
/* Corresponding to process_option */
-static int supported_input_rate[] = {
- 5512, 8000, 11025, 16000, 22050, 32000, 44100, 48000, 64000, 88200,
- 96000, 176400, 192000,
+static unsigned int supported_asrc_rate[] = {
+ 5512, 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000,
+ 64000, 88200, 96000, 128000, 176400, 192000,
};
-static int supported_asrc_rate[] = {
- 8000, 11025, 16000, 22050, 32000, 44100, 48000, 64000, 88200, 96000, 176400, 192000,
+static struct snd_pcm_hw_constraint_list fsl_asrc_rate_constraints = {
+ .count = ARRAY_SIZE(supported_asrc_rate),
+ .list = supported_asrc_rate,
};
/**
* The following tables map the relationship between asrc_inclk/asrc_outclk in
* fsl_asrc.h and the registers of ASRCSR
*/
+#define CLK_MAP_NUM 48
static unsigned char input_clk_map_imx35[] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
};
static unsigned char output_clk_map_imx35[] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
};
/* i.MX53 uses the same map for input and output */
static unsigned char input_clk_map_imx53[] = {
/* 0x0 0x1 0x2 0x3 0x4 0x5 0x6 0x7 0x8 0x9 0xa 0xb 0xc 0xd 0xe 0xf */
0x0, 0x1, 0x2, 0x7, 0x4, 0x5, 0x6, 0x3, 0x8, 0x9, 0xa, 0xb, 0xc, 0xf, 0xe, 0xd,
+ 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
+ 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
};
static unsigned char output_clk_map_imx53[] = {
/* 0x0 0x1 0x2 0x3 0x4 0x5 0x6 0x7 0x8 0x9 0xa 0xb 0xc 0xd 0xe 0xf */
0x8, 0x9, 0xa, 0x7, 0xc, 0x5, 0x6, 0xb, 0x0, 0x1, 0x2, 0x3, 0x4, 0xf, 0xe, 0xd,
+ 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
+ 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
};
-static unsigned char *clk_map[2];
+/* i.MX8 uses the same map for input and output */
+static unsigned char input_clk_map_imx8_0[] = {
+ 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0x0,
+ 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf,
+ 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf,
+};
+
+static unsigned char output_clk_map_imx8_0[] = {
+ 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0x0,
+ 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf,
+ 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf,
+};
+
+static unsigned char input_clk_map_imx8_1[] = {
+ 0xf, 0xf, 0xf, 0xf, 0xf, 0x7, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0x0,
+ 0x0, 0x1, 0x2, 0x3, 0xb, 0xc, 0xf, 0xf, 0xd, 0xe, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf,
+ 0x4, 0x5, 0x6, 0xf, 0x8, 0x9, 0xa, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf,
+};
+
+static unsigned char output_clk_map_imx8_1[] = {
+ 0xf, 0xf, 0xf, 0xf, 0xf, 0x7, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0x0,
+ 0x0, 0x1, 0x2, 0x3, 0xb, 0xc, 0xf, 0xf, 0xd, 0xe, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf,
+ 0x4, 0x5, 0x6, 0xf, 0x8, 0x9, 0xa, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf,
+};
/**
* Request ASRC pair
@@ -90,7 +112,7 @@ static unsigned char *clk_map[2];
* within range [ANCA, ANCA+ANCB-1], depends on the channels of pair A
* while pair A and pair C are comparatively independent.
*/
-static int fsl_asrc_request_pair(int channels, struct fsl_asrc_pair *pair)
+int fsl_asrc_request_pair(int channels, struct fsl_asrc_pair *pair)
{
enum asrc_pair_index index = ASRC_INVALID_PAIR;
struct fsl_asrc *asrc_priv = pair->asrc_priv;
@@ -113,7 +135,8 @@ static int fsl_asrc_request_pair(int channels, struct fsl_asrc_pair *pair)
if (index == ASRC_INVALID_PAIR) {
dev_err(dev, "all pairs are busy now\n");
ret = -EBUSY;
- } else if (asrc_priv->channel_avail < channels) {
+ } else if (asrc_priv->channel_avail < channels ||
+ (asrc_priv->channel_bits < 4 && channels % 2 != 0)) {
dev_err(dev, "can't afford required channels: %d\n", channels);
ret = -EINVAL;
} else {
@@ -128,12 +151,53 @@ static int fsl_asrc_request_pair(int channels, struct fsl_asrc_pair *pair)
return ret;
}
+static int proc_autosel(int Fsin, int Fsout, int *pre_proc, int *post_proc)
+{
+ bool det_out_op2_cond;
+ bool det_out_op0_cond;
+ det_out_op2_cond = (((Fsin * 15 > Fsout * 16) & (Fsout < 56000)) |
+ ((Fsin > 56000) & (Fsout < 56000)));
+ det_out_op0_cond = (Fsin * 23 < Fsout * 8);
+
+ /*
+ * Not supported case: Tsout>16.125*Tsin, and Tsout>8.125*Tsin.
+ */
+ if (Fsin * 8 > 129 * Fsout)
+ *pre_proc = 5;
+ else if (Fsin * 8 > 65 * Fsout)
+ *pre_proc = 4;
+ else if (Fsin * 8 > 33 * Fsout)
+ *pre_proc = 2;
+ else if (Fsin * 8 > 15 * Fsout) {
+ if (Fsin > 152000)
+ *pre_proc = 2;
+ else
+ *pre_proc = 1;
+ } else if (Fsin < 76000)
+ *pre_proc = 0;
+ else if (Fsin > 152000)
+ *pre_proc = 2;
+ else
+ *pre_proc = 1;
+
+ if (det_out_op2_cond)
+ *post_proc = 2;
+ else if (det_out_op0_cond)
+ *post_proc = 0;
+ else
+ *post_proc = 1;
+
+ if (*pre_proc == 4 || *pre_proc == 5)
+ return -EINVAL;
+ return 0;
+}
+
/**
* Release ASRC pair
*
* It clears the resource from asrc_priv and releases the occupied channels.
*/
-static void fsl_asrc_release_pair(struct fsl_asrc_pair *pair)
+void fsl_asrc_release_pair(struct fsl_asrc_pair *pair)
{
struct fsl_asrc *asrc_priv = pair->asrc_priv;
enum asrc_pair_index index = pair->index;
@@ -235,16 +299,19 @@ static int fsl_asrc_set_ideal_ratio(struct fsl_asrc_pair *pair,
* of struct asrc_config which includes in/output sample rate, width, channel
* and clock settings.
*/
-static int fsl_asrc_config_pair(struct fsl_asrc_pair *pair)
+static int fsl_asrc_config_pair(struct fsl_asrc_pair *pair, bool p2p_in, bool p2p_out)
{
struct asrc_config *config = pair->config;
struct fsl_asrc *asrc_priv = pair->asrc_priv;
enum asrc_pair_index index = pair->index;
u32 inrate, outrate, indiv, outdiv;
- u32 clk_index[2], div[2];
+ u32 clk_index[2], div[2], rem[2];
+ u64 clk_rate;
int in, out, channels;
+ int pre_proc, post_proc;
struct clk *clk;
bool ideal;
+ int ret;
if (!config) {
pair_err("invalid pair config\n");
@@ -268,11 +335,11 @@ static int fsl_asrc_config_pair(struct fsl_asrc_pair *pair)
ideal = config->inclk == INCLK_NONE;
/* Validate input and output sample rates */
- for (in = 0; in < ARRAY_SIZE(supported_input_rate); in++)
- if (inrate == supported_input_rate[in])
+ for (in = 0; in < ARRAY_SIZE(supported_asrc_rate); in++)
+ if (inrate == supported_asrc_rate[in])
break;
- if (in == ARRAY_SIZE(supported_input_rate)) {
+ if (in == ARRAY_SIZE(supported_asrc_rate)) {
pair_err("unsupported input sample rate: %dHz\n", inrate);
return -EINVAL;
}
@@ -294,13 +361,14 @@ static int fsl_asrc_config_pair(struct fsl_asrc_pair *pair)
}
/* Validate input and output clock sources */
- clk_index[IN] = clk_map[IN][config->inclk];
- clk_index[OUT] = clk_map[OUT][config->outclk];
+ clk_index[IN] = asrc_priv->clk_map[IN][config->inclk];
+ clk_index[OUT] = asrc_priv->clk_map[OUT][config->outclk];
/* We only have output clock for ideal ratio mode */
clk = asrc_priv->asrck_clk[clk_index[ideal ? OUT : IN]];
-
- div[IN] = clk_get_rate(clk) / inrate;
+ clk_rate = clk_get_rate(clk);
+ rem[IN] = do_div(clk_rate, inrate);
+ div[IN] = (u32)clk_rate;
if (div[IN] == 0) {
pair_err("failed to support input sample rate %dHz by asrck_%x\n",
inrate, clk_index[ideal ? OUT : IN]);
@@ -309,11 +377,20 @@ static int fsl_asrc_config_pair(struct fsl_asrc_pair *pair)
clk = asrc_priv->asrck_clk[clk_index[OUT]];
- /* Use fixed output rate for Ideal Ratio mode (INCLK_NONE) */
- if (ideal)
- div[OUT] = clk_get_rate(clk) / IDEAL_RATIO_RATE;
- else
- div[OUT] = clk_get_rate(clk) / outrate;
+ /*
+ * When P2P mode, output rate should align with the out samplerate.
+ * if set too high output rate, there will be lots of Overload.
+ * When M2M mode, output rate should also need to align with the out
+ * samplerate, but M2M must use less time to achieve good performance.
+ */
+ clk_rate = clk_get_rate(clk);
+ if (p2p_out || p2p_in || (!ideal)) {
+ rem[OUT] = do_div(clk_rate, outrate);
+ div[OUT] = clk_rate;
+ } else {
+ rem[OUT] = do_div(clk_rate, IDEAL_RATIO_RATE);
+ div[OUT] = clk_rate;
+ }
if (div[OUT] == 0) {
pair_err("failed to support output sample rate %dHz by asrck_%x\n",
@@ -321,6 +398,23 @@ static int fsl_asrc_config_pair(struct fsl_asrc_pair *pair)
return -EINVAL;
}
+ if (!ideal && (div[IN] > 1024 || div[OUT] > 1024 ||
+ rem[IN] != 0 || rem[OUT] != 0)) {
+ pair_err("The divider can't be used for non ideal mode\n");
+ return -EINVAL;
+ }
+
+ if (ideal && div[IN] > 1024 && div[OUT] > 1024) {
+ pair_warn("both divider (%d, %d) are larger than threshold\n",
+ div[IN], div[OUT]);
+ }
+
+ if (div[IN] > 1024)
+ div[IN] = 1024;
+
+ if (div[OUT] > 1024)
+ div[OUT] = 1024;
+
/* Set the channel number */
channels = config->channel_num;
@@ -335,8 +429,11 @@ static int fsl_asrc_config_pair(struct fsl_asrc_pair *pair)
/* Default setting: Automatic selection for processing mode */
regmap_update_bits(asrc_priv->regmap, REG_ASRCTR,
ASRCTR_ATSi_MASK(index), ASRCTR_ATS(index));
+
+ /* Default setting: use internal measured ratio */
regmap_update_bits(asrc_priv->regmap, REG_ASRCTR,
- ASRCTR_USRi_MASK(index), 0);
+ ASRCTR_USRi_MASK(index) | ASRCTR_IDRi_MASK(index),
+ ASRCTR_USR(index));
/* Set the input and output clock sources */
regmap_update_bits(asrc_priv->regmap, REG_ASRCSR,
@@ -381,11 +478,17 @@ static int fsl_asrc_config_pair(struct fsl_asrc_pair *pair)
ASRCTR_IDRi_MASK(index) | ASRCTR_USRi_MASK(index),
ASRCTR_IDR(index) | ASRCTR_USR(index));
+ ret = proc_autosel(inrate, outrate, &pre_proc, &post_proc);
+ if (ret) {
+ pair_err("No supported pre-processing options\n");
+ return ret;
+ }
+
/* Apply configurations for pre- and post-processing */
regmap_update_bits(asrc_priv->regmap, REG_ASRCFG,
ASRCFG_PREMODi_MASK(index) | ASRCFG_POSTMODi_MASK(index),
- ASRCFG_PREMOD(index, process_option[in][out][0]) |
- ASRCFG_POSTMOD(index, process_option[in][out][1]));
+ ASRCFG_PREMOD(index, pre_proc) |
+ ASRCFG_POSTMOD(index, post_proc));
return fsl_asrc_set_ideal_ratio(pair, inrate, outrate);
}
@@ -399,7 +502,7 @@ static void fsl_asrc_start_pair(struct fsl_asrc_pair *pair)
{
struct fsl_asrc *asrc_priv = pair->asrc_priv;
enum asrc_pair_index index = pair->index;
- int reg, retry = 10, i;
+ int reg, retry = 50, i;
/* Enable the current pair */
regmap_update_bits(asrc_priv->regmap, REG_ASRCTR,
@@ -412,6 +515,9 @@ static void fsl_asrc_start_pair(struct fsl_asrc_pair *pair)
reg &= ASRCFG_INIRQi_MASK(index);
} while (!reg && --retry);
+ if (retry == 0)
+ pair_warn("initialization is not finished\n");
+
/* Make the input fifo to ASRC STALL level */
regmap_read(asrc_priv->regmap, REG_ASRCNCR, &reg);
for (i = 0; i < pair->channels * 4; i++)
@@ -449,6 +555,61 @@ struct dma_chan *fsl_asrc_get_dma_channel(struct fsl_asrc_pair *pair, bool dir)
}
EXPORT_SYMBOL_GPL(fsl_asrc_get_dma_channel);
+static int fsl_asrc_select_clk(struct fsl_asrc *asrc_priv,
+ struct fsl_asrc_pair *pair,
+ int in_rate,
+ int out_rate)
+{
+ struct asrc_config *config = pair->config;
+ int clk_rate;
+ int clk_index;
+ int i = 0, j = 0;
+ int rate[2];
+ int select_clk[2];
+ bool clk_sel[2];
+
+ rate[0] = in_rate;
+ rate[1] = out_rate;
+
+ /*select proper clock for asrc p2p mode*/
+ for (j = 0; j < 2; j++) {
+ for (i = 0; i < CLK_MAP_NUM; i++) {
+ clk_index = asrc_priv->clk_map[j][i];
+ clk_rate = clk_get_rate(asrc_priv->asrck_clk[clk_index]);
+ if (clk_rate != 0 && (clk_rate / rate[j]) <= 1024 &&
+ (clk_rate % rate[j]) == 0)
+ break;
+ }
+
+ if (i == CLK_MAP_NUM) {
+ select_clk[j] = OUTCLK_ASRCK1_CLK;
+ clk_sel[j] = false;
+ } else {
+ select_clk[j] = i;
+ clk_sel[j] = true;
+ }
+ }
+
+ if (clk_sel[0] != true || clk_sel[1] != true)
+ select_clk[IN] = INCLK_NONE;
+
+ config->inclk = select_clk[IN];
+ config->outclk = select_clk[OUT];
+
+ /*
+ * FIXME: workaroud for 176400/192000 with 8 channel input case
+ * the output sample rate is 48kHz.
+ * with ideal ratio mode, the asrc seems has performance issue
+ * that the output sound is not correct. so switch to non-ideal
+ * ratio mode
+ */
+ if (config->channel_num >= 8 && config->input_sample_rate >= 176400
+ && config->inclk == INCLK_NONE)
+ config->inclk = INCLK_ASRCK1_CLK;
+
+ return 0;
+}
+
static int fsl_asrc_dai_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params,
struct snd_soc_dai *dai)
@@ -468,9 +629,12 @@ static int fsl_asrc_dai_hw_params(struct snd_pcm_substream *substream,
return ret;
}
+ pair->pair_streams |= BIT(substream->stream);
pair->config = &config;
- if (width == 16)
+ if (width == 8)
+ width = ASRC_WIDTH_8_BIT;
+ else if (width == 16)
width = ASRC_WIDTH_16_BIT;
else
width = ASRC_WIDTH_24_BIT;
@@ -482,25 +646,46 @@ static int fsl_asrc_dai_hw_params(struct snd_pcm_substream *substream,
config.pair = pair->index;
config.channel_num = channels;
- config.inclk = INCLK_NONE;
- config.outclk = OUTCLK_ASRCK1_CLK;
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
config.input_word_width = width;
config.output_word_width = word_width;
config.input_sample_rate = rate;
config.output_sample_rate = asrc_priv->asrc_rate;
+
+ ret = fsl_asrc_select_clk(asrc_priv, pair,
+ config.input_sample_rate,
+ config.output_sample_rate);
+ if (ret) {
+ dev_err(dai->dev, "fail to select clock\n");
+ return ret;
+ }
+
+ ret = fsl_asrc_config_pair(pair, false, true);
+ if (ret) {
+ dev_err(dai->dev, "fail to config asrc pair\n");
+ return ret;
+ }
+
} else {
config.input_word_width = word_width;
config.output_word_width = width;
config.input_sample_rate = asrc_priv->asrc_rate;
config.output_sample_rate = rate;
- }
- ret = fsl_asrc_config_pair(pair);
- if (ret) {
- dev_err(dai->dev, "fail to config asrc pair\n");
- return ret;
+ ret = fsl_asrc_select_clk(asrc_priv, pair,
+ config.input_sample_rate,
+ config.output_sample_rate);
+ if (ret) {
+ dev_err(dai->dev, "fail to select clock\n");
+ return ret;
+ }
+
+ ret = fsl_asrc_config_pair(pair, true, false);
+ if (ret) {
+ dev_err(dai->dev, "fail to config asrc pair\n");
+ return ret;
+ }
}
return 0;
@@ -512,8 +697,10 @@ static int fsl_asrc_dai_hw_free(struct snd_pcm_substream *substream,
struct snd_pcm_runtime *runtime = substream->runtime;
struct fsl_asrc_pair *pair = runtime->private_data;
- if (pair)
+ if (pair && (pair->pair_streams & BIT(substream->stream))) {
fsl_asrc_release_pair(pair);
+ pair->pair_streams &= ~BIT(substream->stream);
+ }
return 0;
}
@@ -529,6 +716,8 @@ static int fsl_asrc_dai_trigger(struct snd_pcm_substream *substream, int cmd,
case SNDRV_PCM_TRIGGER_RESUME:
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
fsl_asrc_start_pair(pair);
+ /* Output enough data to content the DMA burstsize of BE */
+ mdelay(1);
break;
case SNDRV_PCM_TRIGGER_STOP:
case SNDRV_PCM_TRIGGER_SUSPEND:
@@ -542,7 +731,28 @@ static int fsl_asrc_dai_trigger(struct snd_pcm_substream *substream, int cmd,
return 0;
}
+static int fsl_asrc_dai_startup(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *cpu_dai)
+{
+ struct fsl_asrc *asrc_priv = snd_soc_dai_get_drvdata(cpu_dai);
+
+ asrc_priv->substream[substream->stream] = substream;
+
+ return snd_pcm_hw_constraint_list(substream->runtime, 0,
+ SNDRV_PCM_HW_PARAM_RATE, &fsl_asrc_rate_constraints);
+}
+
+static void fsl_asrc_dai_shutdown(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *cpu_dai)
+{
+ struct fsl_asrc *asrc_priv = snd_soc_dai_get_drvdata(cpu_dai);
+
+ asrc_priv->substream[substream->stream] = NULL;
+}
+
static const struct snd_soc_dai_ops fsl_asrc_dai_ops = {
+ .startup = fsl_asrc_dai_startup,
+ .shutdown = fsl_asrc_dai_shutdown,
.hw_params = fsl_asrc_dai_hw_params,
.hw_free = fsl_asrc_dai_hw_free,
.trigger = fsl_asrc_dai_trigger,
@@ -559,9 +769,13 @@ static int fsl_asrc_dai_probe(struct snd_soc_dai *dai)
}
#define FSL_ASRC_RATES SNDRV_PCM_RATE_8000_192000
-#define FSL_ASRC_FORMATS (SNDRV_PCM_FMTBIT_S24_LE | \
+#define FSL_ASRC_FORMATS_RX (SNDRV_PCM_FMTBIT_S24_LE | \
+ SNDRV_PCM_FMTBIT_S16_LE | \
+ SNDRV_PCM_FMTBIT_S24_3LE)
+#define FSL_ASRC_FORMATS_TX (SNDRV_PCM_FMTBIT_S24_LE | \
SNDRV_PCM_FMTBIT_S16_LE | \
- SNDRV_PCM_FMTBIT_S20_3LE)
+ SNDRV_PCM_FMTBIT_S8 | \
+ SNDRV_PCM_FMTBIT_S24_3LE)
static struct snd_soc_dai_driver fsl_asrc_dai = {
.probe = fsl_asrc_dai_probe,
@@ -569,15 +783,19 @@ static struct snd_soc_dai_driver fsl_asrc_dai = {
.stream_name = "ASRC-Playback",
.channels_min = 1,
.channels_max = 10,
- .rates = FSL_ASRC_RATES,
- .formats = FSL_ASRC_FORMATS,
+ .rate_min = 5512,
+ .rate_max = 192000,
+ .rates = SNDRV_PCM_RATE_KNOT,
+ .formats = FSL_ASRC_FORMATS_TX,
},
.capture = {
.stream_name = "ASRC-Capture",
.channels_min = 1,
.channels_max = 10,
- .rates = FSL_ASRC_RATES,
- .formats = FSL_ASRC_FORMATS,
+ .rate_min = 5512,
+ .rate_max = 192000,
+ .rates = SNDRV_PCM_RATE_KNOT,
+ .formats = FSL_ASRC_FORMATS_RX,
},
.ops = &fsl_asrc_dai_ops,
};
@@ -729,11 +947,71 @@ static const struct regmap_config fsl_asrc_regmap_config = {
.cache_type = REGCACHE_FLAT,
};
+#include "fsl_asrc_m2m.c"
+
+static bool fsl_asrc_check_xrun(struct snd_pcm_substream *substream)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_dmaengine_dai_dma_data *dma_params_be = NULL;
+ struct snd_pcm_substream *be_substream;
+ struct snd_soc_dpcm *dpcm;
+ int ret = 0;
+
+ /* find the be for this fe stream */
+ list_for_each_entry(dpcm, &rtd->dpcm[substream->stream].be_clients, list_be) {
+ struct snd_soc_pcm_runtime *be = dpcm->be;
+ struct snd_soc_dai *dai = be->cpu_dai;
+
+ if (dpcm->fe != rtd)
+ continue;
+
+ be_substream = snd_soc_dpcm_get_substream(be, substream->stream);
+ dma_params_be = snd_soc_dai_get_dma_data(dai, be_substream);
+ if (dma_params_be->check_xrun && dma_params_be->check_xrun(be_substream))
+ ret = 1;
+ }
+
+ return ret;
+}
+
+static void fsl_asrc_reset(struct snd_pcm_substream *substream, bool stop)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+ struct fsl_asrc *asrc_priv = snd_soc_dai_get_drvdata(cpu_dai);
+ struct snd_dmaengine_dai_dma_data *dma_params_be = NULL;
+ struct snd_soc_dpcm *dpcm;
+ struct snd_pcm_substream *be_substream;
+ unsigned long flags = 0;
+
+ if (stop)
+ imx_stop_lock_pcm_streams(asrc_priv->substream, 2, &flags);
+
+ /* find the be for this fe stream */
+ list_for_each_entry(dpcm, &rtd->dpcm[substream->stream].be_clients, list_be) {
+ struct snd_soc_pcm_runtime *be = dpcm->be;
+ struct snd_soc_dai *dai = be->cpu_dai;
+
+ if (dpcm->fe != rtd)
+ continue;
+
+ be_substream = snd_soc_dpcm_get_substream(be, substream->stream);
+ dma_params_be = snd_soc_dai_get_dma_data(dai, be_substream);
+ dma_params_be->device_reset(be_substream, 0);
+ break;
+ }
+
+ if (stop)
+ imx_start_unlock_pcm_streams(asrc_priv->substream, 2, &flags);
+}
+
/**
* Initialize ASRC registers with a default configurations
*/
static int fsl_asrc_init(struct fsl_asrc *asrc_priv)
{
+ unsigned long ipg_rate;
+
/* Halt ASRC internal FP when input FIFO needs data for pair A, B, C */
regmap_write(asrc_priv->regmap, REG_ASRCTR, ASRCTR_ASRCEN);
@@ -751,11 +1029,12 @@ static int fsl_asrc_init(struct fsl_asrc *asrc_priv)
regmap_update_bits(asrc_priv->regmap, REG_ASRTFR1,
ASRTFR1_TF_BASE_MASK, ASRTFR1_TF_BASE(0xfc));
- /* Set the processing clock for 76KHz to 133M */
- regmap_write(asrc_priv->regmap, REG_ASR76K, 0x06D6);
-
- /* Set the processing clock for 56KHz to 133M */
- return regmap_write(asrc_priv->regmap, REG_ASR56K, 0x0947);
+ ipg_rate = clk_get_rate(asrc_priv->ipg_clk);
+ /* Set the period of the 76KHz and 56KHz sampling clocks based on
+ * the ASRC processing clock.
+ */
+ regmap_write(asrc_priv->regmap, REG_ASR76K, ipg_rate / 76000);
+ return regmap_write(asrc_priv->regmap, REG_ASR56K, ipg_rate / 56000);
}
/**
@@ -881,12 +1160,32 @@ static int fsl_asrc_probe(struct platform_device *pdev)
if (of_device_is_compatible(np, "fsl,imx35-asrc")) {
asrc_priv->channel_bits = 3;
- clk_map[IN] = input_clk_map_imx35;
- clk_map[OUT] = output_clk_map_imx35;
- } else {
+ strncpy(asrc_priv->name, "mxc_asrc",
+ sizeof(asrc_priv->name) - 1);
+ asrc_priv->clk_map[IN] = input_clk_map_imx35;
+ asrc_priv->clk_map[OUT] = output_clk_map_imx35;
+ asrc_priv->dma_type = DMA_SDMA;
+ } else if (of_device_is_compatible(np, "fsl,imx53-asrc")) {
+ asrc_priv->channel_bits = 4;
+ strncpy(asrc_priv->name, "mxc_asrc",
+ sizeof(asrc_priv->name) - 1);
+ asrc_priv->clk_map[IN] = input_clk_map_imx53;
+ asrc_priv->clk_map[OUT] = output_clk_map_imx53;
+ asrc_priv->dma_type = DMA_SDMA;
+ } else if (of_device_is_compatible(np, "fsl,imx8qm-asrc0")) {
asrc_priv->channel_bits = 4;
- clk_map[IN] = input_clk_map_imx53;
- clk_map[OUT] = output_clk_map_imx53;
+ strncpy(asrc_priv->name, "mxc_asrc",
+ sizeof(asrc_priv->name) - 1);
+ asrc_priv->clk_map[IN] = input_clk_map_imx8_0;
+ asrc_priv->clk_map[OUT] = output_clk_map_imx8_0;
+ asrc_priv->dma_type = DMA_EDMA;
+ } else if (of_device_is_compatible(np, "fsl,imx8qm-asrc1")) {
+ asrc_priv->channel_bits = 4;
+ strncpy(asrc_priv->name, "mxc_asrc1",
+ sizeof(asrc_priv->name) - 1);
+ asrc_priv->clk_map[IN] = input_clk_map_imx8_1;
+ asrc_priv->clk_map[OUT] = output_clk_map_imx8_1;
+ asrc_priv->dma_type = DMA_EDMA;
}
ret = fsl_asrc_init(asrc_priv);
@@ -911,6 +1210,11 @@ static int fsl_asrc_probe(struct platform_device *pdev)
return ret;
}
+ asrc_priv->dma_params_tx.check_xrun = fsl_asrc_check_xrun;
+ asrc_priv->dma_params_rx.check_xrun = fsl_asrc_check_xrun;
+ asrc_priv->dma_params_tx.device_reset = fsl_asrc_reset;
+ asrc_priv->dma_params_rx.device_reset = fsl_asrc_reset;
+
if (asrc_priv->asrc_width != 16 && asrc_priv->asrc_width != 24) {
dev_warn(&pdev->dev, "unsupported width, switching to 24bit\n");
asrc_priv->asrc_width = 24;
@@ -920,6 +1224,8 @@ static int fsl_asrc_probe(struct platform_device *pdev)
pm_runtime_enable(&pdev->dev);
spin_lock_init(&asrc_priv->lock);
+ regcache_cache_only(asrc_priv->regmap, true);
+
ret = devm_snd_soc_register_component(&pdev->dev, &fsl_asrc_component,
&fsl_asrc_dai, 1);
if (ret) {
@@ -933,6 +1239,12 @@ static int fsl_asrc_probe(struct platform_device *pdev)
return ret;
}
+ ret = fsl_asrc_m2m_init(asrc_priv);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to init m2m device %d\n", ret);
+ return ret;
+ }
+
return 0;
}
@@ -941,6 +1253,9 @@ static int fsl_asrc_runtime_resume(struct device *dev)
{
struct fsl_asrc *asrc_priv = dev_get_drvdata(dev);
int i, ret;
+ u32 asrctr;
+ u32 reg;
+ int retry = 50;
ret = clk_prepare_enable(asrc_priv->mem_clk);
if (ret)
@@ -959,6 +1274,34 @@ static int fsl_asrc_runtime_resume(struct device *dev)
goto disable_asrck_clk;
}
+ /* Stop all pairs provisionally */
+ regmap_read(asrc_priv->regmap, REG_ASRCTR, &asrctr);
+ regmap_update_bits(asrc_priv->regmap, REG_ASRCTR,
+ ASRCTR_ASRCEi_ALL_MASK, 0);
+
+ /* Restore all registers */
+ regcache_cache_only(asrc_priv->regmap, false);
+ regcache_mark_dirty(asrc_priv->regmap);
+ regcache_sync(asrc_priv->regmap);
+
+ regmap_update_bits(asrc_priv->regmap, REG_ASRCFG,
+ ASRCFG_NDPRi_ALL_MASK | ASRCFG_POSTMODi_ALL_MASK |
+ ASRCFG_PREMODi_ALL_MASK, asrc_priv->regcache_cfg);
+
+ /* Restart enabled pairs */
+ regmap_update_bits(asrc_priv->regmap, REG_ASRCTR,
+ ASRCTR_ASRCEi_ALL_MASK, asrctr);
+
+ /* Wait for status of initialization */
+ do {
+ udelay(5);
+ regmap_read(asrc_priv->regmap, REG_ASRCFG, &reg);
+ reg = (reg >> ASRCFG_INIRQi_SHIFT(0)) & 0x7;
+ } while (!(reg == ((asrctr & 0xE) >> 1)) && --retry);
+
+ if (retry == 0)
+ dev_warn(dev, "initialization is not finished\n");
+
return 0;
disable_asrck_clk:
@@ -978,6 +1321,11 @@ static int fsl_asrc_runtime_suspend(struct device *dev)
struct fsl_asrc *asrc_priv = dev_get_drvdata(dev);
int i;
+ regmap_read(asrc_priv->regmap, REG_ASRCFG,
+ &asrc_priv->regcache_cfg);
+
+ regcache_cache_only(asrc_priv->regmap, true);
+
for (i = 0; i < ASRC_CLK_MAX_NUM; i++)
clk_disable_unprepare(asrc_priv->asrck_clk[i]);
if (!IS_ERR(asrc_priv->spba_clk))
@@ -993,39 +1341,25 @@ static int fsl_asrc_runtime_suspend(struct device *dev)
static int fsl_asrc_suspend(struct device *dev)
{
struct fsl_asrc *asrc_priv = dev_get_drvdata(dev);
+ int ret;
- regmap_read(asrc_priv->regmap, REG_ASRCFG,
- &asrc_priv->regcache_cfg);
+ fsl_asrc_m2m_suspend(asrc_priv);
- regcache_cache_only(asrc_priv->regmap, true);
- regcache_mark_dirty(asrc_priv->regmap);
+ ret = pm_runtime_force_suspend(dev);
- return 0;
+ return ret;
}
static int fsl_asrc_resume(struct device *dev)
{
struct fsl_asrc *asrc_priv = dev_get_drvdata(dev);
- u32 asrctr;
-
- /* Stop all pairs provisionally */
- regmap_read(asrc_priv->regmap, REG_ASRCTR, &asrctr);
- regmap_update_bits(asrc_priv->regmap, REG_ASRCTR,
- ASRCTR_ASRCEi_ALL_MASK, 0);
-
- /* Restore all registers */
- regcache_cache_only(asrc_priv->regmap, false);
- regcache_sync(asrc_priv->regmap);
+ int ret;
- regmap_update_bits(asrc_priv->regmap, REG_ASRCFG,
- ASRCFG_NDPRi_ALL_MASK | ASRCFG_POSTMODi_ALL_MASK |
- ASRCFG_PREMODi_ALL_MASK, asrc_priv->regcache_cfg);
+ ret = pm_runtime_force_resume(dev);
- /* Restart enabled pairs */
- regmap_update_bits(asrc_priv->regmap, REG_ASRCTR,
- ASRCTR_ASRCEi_ALL_MASK, asrctr);
+ fsl_asrc_m2m_resume(asrc_priv);
- return 0;
+ return ret;
}
#endif /* CONFIG_PM_SLEEP */
@@ -1037,12 +1371,15 @@ static const struct dev_pm_ops fsl_asrc_pm = {
static const struct of_device_id fsl_asrc_ids[] = {
{ .compatible = "fsl,imx35-asrc", },
{ .compatible = "fsl,imx53-asrc", },
+ { .compatible = "fsl,imx8qm-asrc0", },
+ { .compatible = "fsl,imx8qm-asrc1", },
{}
};
MODULE_DEVICE_TABLE(of, fsl_asrc_ids);
static struct platform_driver fsl_asrc_driver = {
.probe = fsl_asrc_probe,
+ .remove = fsl_asrc_m2m_remove,
.driver = {
.name = "fsl-asrc",
.of_match_table = fsl_asrc_ids,
diff --git a/sound/soc/fsl/fsl_asrc.h b/sound/soc/fsl/fsl_asrc.h
index 0f163abe4ba3..38394a4fe7df 100644
--- a/sound/soc/fsl/fsl_asrc.h
+++ b/sound/soc/fsl/fsl_asrc.h
@@ -1,7 +1,7 @@
/*
* fsl_asrc.h - Freescale ASRC ALSA SoC header file
*
- * Copyright (C) 2014 Freescale Semiconductor, Inc.
+ * Copyright (C) 2014-2016 Freescale Semiconductor, Inc.
*
* Author: Nicolin Chen <nicoleotsuka@gmail.com>
*
@@ -13,6 +13,9 @@
#ifndef _FSL_ASRC_H
#define _FSL_ASRC_H
+#include <uapi/linux/mxc_asrc.h>
+#include <linux/miscdevice.h>
+
#define IN 0
#define OUT 1
@@ -23,7 +26,8 @@
#define ASRC_FIFO_THRESHOLD_MAX 63
#define ASRC_DMA_BUFFER_SIZE (1024 * 48 * 4)
#define ASRC_MAX_BUFFER_SIZE (1024 * 48)
-#define ASRC_OUTPUT_LAST_SAMPLE 8
+#define ASRC_OUTPUT_LAST_SAMPLE_MAX 32
+#define ASRC_OUTPUT_LAST_SAMPLE 4
#define IDEAL_RATIO_RATE 1000000
@@ -286,106 +290,10 @@
#define ASRMCR1i_OW16_MASK (1 << ASRMCR1i_OW16_SHIFT)
#define ASRMCR1i_OW16(v) ((v) << ASRMCR1i_OW16_SHIFT)
-
-enum asrc_pair_index {
- ASRC_INVALID_PAIR = -1,
- ASRC_PAIR_A = 0,
- ASRC_PAIR_B = 1,
- ASRC_PAIR_C = 2,
-};
-
-#define ASRC_PAIR_MAX_NUM (ASRC_PAIR_C + 1)
-
-enum asrc_inclk {
- INCLK_NONE = 0x03,
- INCLK_ESAI_RX = 0x00,
- INCLK_SSI1_RX = 0x01,
- INCLK_SSI2_RX = 0x02,
- INCLK_SSI3_RX = 0x07,
- INCLK_SPDIF_RX = 0x04,
- INCLK_MLB_CLK = 0x05,
- INCLK_PAD = 0x06,
- INCLK_ESAI_TX = 0x08,
- INCLK_SSI1_TX = 0x09,
- INCLK_SSI2_TX = 0x0a,
- INCLK_SSI3_TX = 0x0b,
- INCLK_SPDIF_TX = 0x0c,
- INCLK_ASRCK1_CLK = 0x0f,
-};
-
-enum asrc_outclk {
- OUTCLK_NONE = 0x03,
- OUTCLK_ESAI_TX = 0x00,
- OUTCLK_SSI1_TX = 0x01,
- OUTCLK_SSI2_TX = 0x02,
- OUTCLK_SSI3_TX = 0x07,
- OUTCLK_SPDIF_TX = 0x04,
- OUTCLK_MLB_CLK = 0x05,
- OUTCLK_PAD = 0x06,
- OUTCLK_ESAI_RX = 0x08,
- OUTCLK_SSI1_RX = 0x09,
- OUTCLK_SSI2_RX = 0x0a,
- OUTCLK_SSI3_RX = 0x0b,
- OUTCLK_SPDIF_RX = 0x0c,
- OUTCLK_ASRCK1_CLK = 0x0f,
-};
-
#define ASRC_CLK_MAX_NUM 16
-enum asrc_word_width {
- ASRC_WIDTH_24_BIT = 0,
- ASRC_WIDTH_16_BIT = 1,
- ASRC_WIDTH_8_BIT = 2,
-};
-
-struct asrc_config {
- enum asrc_pair_index pair;
- unsigned int channel_num;
- unsigned int buffer_num;
- unsigned int dma_buffer_size;
- unsigned int input_sample_rate;
- unsigned int output_sample_rate;
- enum asrc_word_width input_word_width;
- enum asrc_word_width output_word_width;
- enum asrc_inclk inclk;
- enum asrc_outclk outclk;
-};
-
-struct asrc_req {
- unsigned int chn_num;
- enum asrc_pair_index index;
-};
-
-struct asrc_querybuf {
- unsigned int buffer_index;
- unsigned int input_length;
- unsigned int output_length;
- unsigned long input_offset;
- unsigned long output_offset;
-};
-
-struct asrc_convert_buffer {
- void *input_buffer_vaddr;
- void *output_buffer_vaddr;
- unsigned int input_buffer_length;
- unsigned int output_buffer_length;
-};
-
-struct asrc_status_flags {
- enum asrc_pair_index index;
- unsigned int overload_error;
-};
-
-enum asrc_error_status {
- ASRC_TASK_Q_OVERLOAD = 0x01,
- ASRC_OUTPUT_TASK_OVERLOAD = 0x02,
- ASRC_INPUT_TASK_OVERLOAD = 0x04,
- ASRC_OUTPUT_BUFFER_OVERFLOW = 0x08,
- ASRC_INPUT_BUFFER_UNDERRUN = 0x10,
-};
struct dma_block {
- dma_addr_t dma_paddr;
void *dma_vaddr;
unsigned int length;
};
@@ -416,6 +324,7 @@ struct fsl_asrc_pair {
struct dma_chan *dma_chan[2];
struct imx_dma_data dma_data;
unsigned int pos;
+ unsigned int pair_streams;
void *private;
};
@@ -436,6 +345,7 @@ struct fsl_asrc_pair {
* @pair: pair pointers
* @channel_bits: width of ASRCNCR register for each pair
* @channel_avail: non-occupied channel numbers
+ * @pair_streams:indicat which substream is running
* @asrc_rate: default sample rate for ASoC Back-Ends
* @asrc_width: default sample width for ASoC Back-Ends
* @regcache_cfg: store register value of REG_ASRCFG
@@ -450,18 +360,29 @@ struct fsl_asrc {
struct clk *ipg_clk;
struct clk *spba_clk;
struct clk *asrck_clk[ASRC_CLK_MAX_NUM];
+ unsigned char *clk_map[2];
spinlock_t lock;
+ struct snd_pcm_substream *substream[2];
struct fsl_asrc_pair *pair[ASRC_PAIR_MAX_NUM];
+ struct miscdevice asrc_miscdev;
unsigned int channel_bits;
unsigned int channel_avail;
int asrc_rate;
int asrc_width;
+ int dma_type; /* 0 is sdma, 1 is edma */
u32 regcache_cfg;
+ char name[20];
};
+#define DMA_SDMA 0
+#define DMA_EDMA 1
+
extern struct snd_soc_platform_driver fsl_asrc_platform;
struct dma_chan *fsl_asrc_get_dma_channel(struct fsl_asrc_pair *pair, bool dir);
+int fsl_asrc_request_pair(int channels, struct fsl_asrc_pair *pair);
+void fsl_asrc_release_pair(struct fsl_asrc_pair *pair);
+
#endif /* _FSL_ASRC_H */
diff --git a/sound/soc/fsl/fsl_asrc_dma.c b/sound/soc/fsl/fsl_asrc_dma.c
index e1b97e59275a..12777f8124a4 100644
--- a/sound/soc/fsl/fsl_asrc_dma.c
+++ b/sound/soc/fsl/fsl_asrc_dma.c
@@ -1,7 +1,7 @@
/*
* Freescale ASRC ALSA SoC Platform (DMA) driver
*
- * Copyright (C) 2014 Freescale Semiconductor, Inc.
+ * Copyright (C) 2014-2015 Freescale Semiconductor, Inc.
*
* Author: Nicolin Chen <nicoleotsuka@gmail.com>
*
@@ -20,16 +20,14 @@
#define FSL_ASRC_DMABUF_SIZE (256 * 1024)
-static const struct snd_pcm_hardware snd_imx_hardware = {
+static struct snd_pcm_hardware snd_imx_hardware = {
.info = SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_BLOCK_TRANSFER |
SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_PAUSE |
- SNDRV_PCM_INFO_RESUME,
+ SNDRV_PCM_INFO_MMAP_VALID,
.buffer_bytes_max = FSL_ASRC_DMABUF_SIZE,
.period_bytes_min = 128,
- .period_bytes_max = 65535, /* Limited by SDMA engine */
+ .period_bytes_max = 65532, /* Limited by SDMA engine */
.periods_min = 2,
.periods_max = 255,
.fifo_size = 0,
@@ -50,12 +48,19 @@ static void fsl_asrc_dma_complete(void *arg)
struct snd_pcm_substream *substream = arg;
struct snd_pcm_runtime *runtime = substream->runtime;
struct fsl_asrc_pair *pair = runtime->private_data;
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_dmaengine_dai_dma_data *dma_data;
pair->pos += snd_pcm_lib_period_bytes(substream);
if (pair->pos >= snd_pcm_lib_buffer_bytes(substream))
pair->pos = 0;
snd_pcm_period_elapsed(substream);
+
+ dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
+ if (dma_data->check_xrun && dma_data->check_xrun(substream))
+ dma_data->device_reset(substream, 1);
+
}
static int fsl_asrc_dma_prepare_and_submit(struct snd_pcm_substream *substream)
@@ -150,6 +155,7 @@ static int fsl_asrc_dma_hw_params(struct snd_pcm_substream *substream,
struct device *dev_be;
u8 dir = tx ? OUT : IN;
dma_cap_mask_t mask;
+ enum sdma_peripheral_type be_peripheral_type;
int ret;
/* Fetch the Back-End dma_data from DPCM */
@@ -203,19 +209,43 @@ static int fsl_asrc_dma_hw_params(struct snd_pcm_substream *substream,
/* Get DMA request of Back-End */
tmp_chan = dma_request_slave_channel(dev_be, tx ? "tx" : "rx");
- tmp_data = tmp_chan->private;
- pair->dma_data.dma_request = tmp_data->dma_request;
- dma_release_channel(tmp_chan);
+ if (tmp_chan) {
+ tmp_data = tmp_chan->private;
+ if (tmp_data) {
+ pair->dma_data.dma_request = tmp_data->dma_request;
+ be_peripheral_type = tmp_data->peripheral_type;
+ if (tx && be_peripheral_type == IMX_DMATYPE_SSI_DUAL)
+ pair->dma_data.dst_dualfifo = true;
+ if (!tx && be_peripheral_type == IMX_DMATYPE_SSI_DUAL)
+ pair->dma_data.src_dualfifo = true;
+ }
+ dma_release_channel(tmp_chan);
+ }
/* Get DMA request of Front-End */
tmp_chan = fsl_asrc_get_dma_channel(pair, dir);
- tmp_data = tmp_chan->private;
- pair->dma_data.dma_request2 = tmp_data->dma_request;
- pair->dma_data.peripheral_type = tmp_data->peripheral_type;
- pair->dma_data.priority = tmp_data->priority;
- dma_release_channel(tmp_chan);
+ if (tmp_chan) {
+ tmp_data = tmp_chan->private;
+ if (tmp_data) {
+ pair->dma_data.dma_request2 = tmp_data->dma_request;
+ pair->dma_data.peripheral_type =
+ tmp_data->peripheral_type;
+ pair->dma_data.priority = tmp_data->priority;
+ }
+ dma_release_channel(tmp_chan);
+ }
+
+ /* For sdma DEV_TO_DEV, there is two dma request
+ * But for emda DEV_TO_DEV, there is only one dma request, which is
+ * from the BE.
+ */
+ if (pair->dma_data.dma_request2 != pair->dma_data.dma_request)
+ pair->dma_chan[dir] =
+ dma_request_channel(mask, filter, &pair->dma_data);
+ else
+ pair->dma_chan[dir] =
+ dma_request_slave_channel(dev_be, tx ? "tx" : "rx");
- pair->dma_chan[dir] = dma_request_channel(mask, filter, &pair->dma_data);
if (!pair->dma_chan[dir]) {
dev_err(dev, "failed to request DMA channel for Back-End\n");
return -EINVAL;
@@ -226,6 +256,8 @@ static int fsl_asrc_dma_hw_params(struct snd_pcm_substream *substream,
else
buswidth = DMA_SLAVE_BUSWIDTH_4_BYTES;
+ memset(&config_be, 0, sizeof(config_be));
+
config_be.direction = DMA_DEV_TO_DEV;
config_be.src_addr_width = buswidth;
config_be.src_maxburst = dma_params_be->maxburst;
@@ -277,6 +309,16 @@ static int fsl_asrc_dma_startup(struct snd_pcm_substream *substream)
struct device *dev = rtd->platform->dev;
struct fsl_asrc *asrc_priv = dev_get_drvdata(dev);
struct fsl_asrc_pair *pair;
+ bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
+ u8 dir = tx ? OUT : IN;
+ struct dma_slave_caps dma_caps;
+ struct dma_chan *tmp_chan;
+ struct snd_dmaengine_dai_dma_data *dma_data;
+ u32 addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) |
+ BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) |
+ BIT(DMA_SLAVE_BUSWIDTH_4_BYTES);
+ int ret;
+ int i;
pair = kzalloc(sizeof(struct fsl_asrc_pair), GFP_KERNEL);
if (!pair)
@@ -286,8 +328,78 @@ static int fsl_asrc_dma_startup(struct snd_pcm_substream *substream)
runtime->private_data = pair;
- snd_pcm_hw_constraint_integer(substream->runtime,
- SNDRV_PCM_HW_PARAM_PERIODS);
+ ret = snd_pcm_hw_constraint_integer(substream->runtime,
+ SNDRV_PCM_HW_PARAM_PERIODS);
+ if (ret < 0) {
+ dev_err(dev, "failed to set pcm hw params periods\n");
+ return ret;
+ }
+
+ dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
+
+ fsl_asrc_request_pair(1, pair);
+
+ tmp_chan = fsl_asrc_get_dma_channel(pair, dir);
+ if (!tmp_chan) {
+ dev_err(dev, "can't get dma channel\n");
+ return -EINVAL;
+ }
+
+ ret = dma_get_slave_caps(tmp_chan, &dma_caps);
+ if (ret == 0) {
+ if (dma_caps.cmd_pause)
+ snd_imx_hardware.info |= SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME;
+ if (dma_caps.residue_granularity <= DMA_RESIDUE_GRANULARITY_SEGMENT)
+ snd_imx_hardware.info |= SNDRV_PCM_INFO_BATCH;
+
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ addr_widths = dma_caps.dst_addr_widths;
+ else
+ addr_widths = dma_caps.src_addr_widths;
+ }
+
+ /*
+ * If SND_DMAENGINE_PCM_DAI_FLAG_PACK is set keep
+ * hw.formats set to 0, meaning no restrictions are in place.
+ * In this case it's the responsibility of the DAI driver to
+ * provide the supported format information.
+ */
+ if (!(dma_data->flags & SND_DMAENGINE_PCM_DAI_FLAG_PACK))
+ /*
+ * Prepare formats mask for valid/allowed sample types. If the
+ * dma does not have support for the given physical word size,
+ * it needs to be masked out so user space can not use the
+ * format which produces corrupted audio.
+ * In case the dma driver does not implement the slave_caps the
+ * default assumption is that it supports 1, 2 and 4 bytes
+ * widths.
+ */
+ for (i = 0; i <= SNDRV_PCM_FORMAT_LAST; i++) {
+ int bits = snd_pcm_format_physical_width(i);
+
+ /*
+ * Enable only samples with DMA supported physical
+ * widths
+ */
+ switch (bits) {
+ case 8:
+ case 16:
+ case 24:
+ case 32:
+ case 64:
+ if (addr_widths & (1 << (bits / 8)))
+ snd_imx_hardware.formats |= (1LL << i);
+ break;
+ default:
+ /* Unsupported types */
+ break;
+ }
+ }
+
+ if (tmp_chan)
+ dma_release_channel(tmp_chan);
+ fsl_asrc_release_pair(pair);
+
snd_soc_set_runtime_hwparams(substream, &snd_imx_hardware);
return 0;
diff --git a/sound/soc/fsl/fsl_asrc_m2m.c b/sound/soc/fsl/fsl_asrc_m2m.c
new file mode 100644
index 000000000000..c478fa43e1bd
--- /dev/null
+++ b/sound/soc/fsl/fsl_asrc_m2m.c
@@ -0,0 +1,1065 @@
+/*
+ * Freescale ASRC Memory to Memory (M2M) driver
+ *
+ * Copyright (C) 2014-2016 Freescale Semiconductor, Inc.
+ *
+ * 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.
+ */
+
+#define FSL_ASRC_INPUTFIFO_WML 0x4
+#define FSL_ASRC_OUTPUTFIFO_WML 0x2
+
+#define DIR_STR(dir) dir == IN ? "in" : "out"
+
+struct fsl_asrc_m2m {
+ struct fsl_asrc_pair *pair;
+ struct completion complete[2];
+ struct dma_block dma_block[2];
+ unsigned int pair_hold;
+ unsigned int asrc_active;
+ unsigned int sg_nodes[2];
+ struct scatterlist sg[2][4];
+
+ enum asrc_word_width word_width[2];
+ unsigned int rate[2];
+ unsigned int last_period_size;
+ u32 watermark[2];
+ spinlock_t lock;
+};
+
+static void fsl_asrc_get_status(struct fsl_asrc_pair *pair,
+ struct asrc_status_flags *flags)
+{
+ struct fsl_asrc *asrc_priv = pair->asrc_priv;
+ unsigned long lock_flags;
+
+ spin_lock_irqsave(&asrc_priv->lock, lock_flags);
+
+ flags->overload_error = pair->error;
+
+ spin_unlock_irqrestore(&asrc_priv->lock, lock_flags);
+}
+
+#define ASRC_xPUT_DMA_CALLBACK(dir) \
+ ((dir == IN) ? fsl_asrc_input_dma_callback : fsl_asrc_output_dma_callback)
+
+static void fsl_asrc_input_dma_callback(void *data)
+{
+ struct fsl_asrc_pair *pair = (struct fsl_asrc_pair *)data;
+ struct fsl_asrc_m2m *m2m = pair->private;
+
+ complete(&m2m->complete[IN]);
+}
+
+static void fsl_asrc_output_dma_callback(void *data)
+{
+ struct fsl_asrc_pair *pair = (struct fsl_asrc_pair *)data;
+ struct fsl_asrc_m2m *m2m = pair->private;
+
+ complete(&m2m->complete[OUT]);
+}
+
+static unsigned int fsl_asrc_get_output_FIFO_size(struct fsl_asrc_pair *pair)
+{
+ struct fsl_asrc *asrc_priv = pair->asrc_priv;
+ enum asrc_pair_index index = pair->index;
+ u32 val;
+
+ regmap_read(asrc_priv->regmap, REG_ASRFST(index), &val);
+
+ val &= ASRFSTi_OUTPUT_FIFO_MASK;
+
+ return val >> ASRFSTi_OUTPUT_FIFO_SHIFT;
+}
+
+static void fsl_asrc_read_last_FIFO(struct fsl_asrc_pair *pair)
+{
+ struct fsl_asrc_m2m *m2m = pair->private;
+ struct fsl_asrc *asrc_priv = pair->asrc_priv;
+ enum asrc_pair_index index = pair->index;
+ struct dma_block *output = &m2m->dma_block[OUT];
+ u32 i, reg, size, t_size = 0;
+ u32 *reg24 = NULL;
+ u16 *reg16 = NULL;
+
+ if (m2m->word_width[OUT] == ASRC_WIDTH_24_BIT)
+ reg24 = output->dma_vaddr + output->length;
+ else
+ reg16 = output->dma_vaddr + output->length;
+
+retry:
+ size = fsl_asrc_get_output_FIFO_size(pair);
+
+ for (i = 0; i < size * pair->channels; i++) {
+ regmap_read(asrc_priv->regmap, REG_ASRDO(index), &reg);
+ if (reg24) {
+ *(reg24) = reg;
+ reg24++;
+ } else {
+ *(reg16) = (u16)reg;
+ reg16++;
+ }
+ }
+ t_size += size;
+
+ if (size)
+ goto retry;
+
+ if (t_size > m2m->last_period_size)
+ t_size = m2m->last_period_size;
+
+ if (reg24)
+ output->length += t_size * pair->channels * 4;
+ else
+ output->length += t_size * pair->channels * 2;
+}
+
+static int fsl_allocate_dma_buf(struct fsl_asrc_pair *pair)
+{
+ struct fsl_asrc_m2m *m2m = pair->private;
+ struct fsl_asrc *asrc_priv = pair->asrc_priv;
+ struct dma_block *input = &m2m->dma_block[IN];
+ struct dma_block *output = &m2m->dma_block[OUT];
+ enum asrc_pair_index index = pair->index;
+
+ input->dma_vaddr = kzalloc(input->length, GFP_KERNEL);
+ if (!input->dma_vaddr) {
+ pair_err("failed to allocate input DMA buffer\n");
+ return -ENOMEM;
+ }
+
+ output->dma_vaddr = kzalloc(output->length, GFP_KERNEL);
+ if (!output->dma_vaddr) {
+ pair_err("failed to allocate output DMA buffer\n");
+ goto exit;
+ }
+
+ return 0;
+
+exit:
+ kfree(input->dma_vaddr);
+
+ return -ENOMEM;
+}
+
+static int fsl_asrc_dmaconfig(struct fsl_asrc_pair *pair, struct dma_chan *chan,
+ u32 dma_addr, void *buf_addr, u32 buf_len,
+ bool dir, enum asrc_word_width word_width)
+{
+ struct dma_async_tx_descriptor *desc = pair->desc[dir];
+ struct fsl_asrc *asrc_priv = pair->asrc_priv;
+ struct fsl_asrc_m2m *m2m = pair->private;
+ unsigned int sg_nent = m2m->sg_nodes[dir];
+ enum asrc_pair_index index = pair->index;
+ struct scatterlist *sg = m2m->sg[dir];
+ struct dma_slave_config slave_config;
+ enum dma_slave_buswidth buswidth;
+ int ret, i;
+
+ switch (word_width) {
+ case ASRC_WIDTH_8_BIT:
+ buswidth = DMA_SLAVE_BUSWIDTH_1_BYTE;
+ break;
+ case ASRC_WIDTH_16_BIT:
+ buswidth = DMA_SLAVE_BUSWIDTH_2_BYTES;
+ break;
+ case ASRC_WIDTH_24_BIT:
+ buswidth = DMA_SLAVE_BUSWIDTH_4_BYTES;
+ break;
+ default:
+ pair_err("invalid word width\n");
+ return -EINVAL;
+ }
+
+ if (dir == IN) {
+ slave_config.direction = DMA_MEM_TO_DEV;
+ slave_config.dst_addr = dma_addr;
+ slave_config.dst_addr_width = buswidth;
+ if (asrc_priv->dma_type == DMA_SDMA)
+ slave_config.dst_maxburst =
+ m2m->watermark[IN] * pair->channels;
+ else
+ slave_config.dst_maxburst = 1;
+ } else {
+ slave_config.direction = DMA_DEV_TO_MEM;
+ slave_config.src_addr = dma_addr;
+ slave_config.src_addr_width = buswidth;
+ if (asrc_priv->dma_type == DMA_SDMA)
+ slave_config.src_maxburst =
+ m2m->watermark[OUT] * pair->channels;
+ else
+ slave_config.src_maxburst = 1;
+ }
+
+ ret = dmaengine_slave_config(chan, &slave_config);
+ if (ret) {
+ pair_err("failed to config dmaengine for %sput task: %d\n",
+ DIR_STR(dir), ret);
+ return -EINVAL;
+ }
+
+ sg_init_table(sg, sg_nent);
+ switch (sg_nent) {
+ case 1:
+ sg_init_one(sg, buf_addr, buf_len);
+ break;
+ case 2:
+ case 3:
+ case 4:
+ for (i = 0; i < (sg_nent - 1); i++)
+ sg_set_buf(&sg[i], buf_addr + i * ASRC_MAX_BUFFER_SIZE,
+ ASRC_MAX_BUFFER_SIZE);
+
+ sg_set_buf(&sg[i], buf_addr + i * ASRC_MAX_BUFFER_SIZE,
+ buf_len - ASRC_MAX_BUFFER_SIZE * i);
+ break;
+ default:
+ pair_err("invalid input DMA nodes number: %d\n", sg_nent);
+ return -EINVAL;
+ }
+
+ ret = dma_map_sg(&asrc_priv->pdev->dev, sg, sg_nent, slave_config.direction);
+ if (ret != sg_nent) {
+ pair_err("failed to map DMA sg for %sput task\n", DIR_STR(dir));
+ return -EINVAL;
+ }
+
+ desc = dmaengine_prep_slave_sg(chan, sg, sg_nent,
+ slave_config.direction, DMA_PREP_INTERRUPT);
+ if (!desc) {
+ pair_err("failed to prepare dmaengine for %sput task\n",
+ DIR_STR(dir));
+ return -EINVAL;
+ }
+
+ pair->desc[dir] = desc;
+ pair->desc[dir]->callback = ASRC_xPUT_DMA_CALLBACK(dir);
+
+ desc->callback = ASRC_xPUT_DMA_CALLBACK(dir);
+ desc->callback_param = pair;
+
+ return 0;
+}
+
+static int fsl_asrc_prepare_io_buffer(struct fsl_asrc_pair *pair,
+ struct asrc_convert_buffer *pbuf, bool dir)
+{
+ struct fsl_asrc_m2m *m2m = pair->private;
+ struct fsl_asrc *asrc_priv = pair->asrc_priv;
+ unsigned int *dma_len = &m2m->dma_block[dir].length;
+ enum asrc_word_width width = m2m->word_width[dir];
+ void *dma_vaddr = m2m->dma_block[dir].dma_vaddr;
+ struct dma_chan *dma_chan = pair->dma_chan[dir];
+ unsigned int buf_len, wm = m2m->watermark[dir];
+ unsigned int *sg_nodes = &m2m->sg_nodes[dir];
+ unsigned int last_period_size = m2m->last_period_size;
+ enum asrc_pair_index index = pair->index;
+ u32 word_size, fifo_addr;
+ void __user *buf_vaddr;
+
+ /* Clean the DMA buffer */
+ memset(dma_vaddr, 0, ASRC_DMA_BUFFER_SIZE);
+
+ if (dir == IN) {
+ buf_vaddr = (void __user *)pbuf->input_buffer_vaddr;
+ buf_len = pbuf->input_buffer_length;
+ } else {
+ buf_vaddr = (void __user *)pbuf->output_buffer_vaddr;
+ buf_len = pbuf->output_buffer_length;
+ }
+
+ switch (width) {
+ case ASRC_WIDTH_24_BIT:
+ word_size = 4;
+ break;
+ case ASRC_WIDTH_16_BIT:
+ word_size = 2;
+ break;
+ case ASRC_WIDTH_8_BIT:
+ word_size = 1;
+ break;
+ default:
+ pair_err("wrong word length\n");
+ return -EINVAL;
+ }
+
+ if (buf_len < word_size * pair->channels * wm ||
+ buf_len > ASRC_DMA_BUFFER_SIZE ||
+ (dir == OUT && buf_len < word_size * pair->channels * last_period_size)) {
+ pair_err("%sput buffer size is error: [%d]\n",
+ DIR_STR(dir), buf_len);
+ return -EINVAL;
+ }
+
+ /* Copy origin data into input buffer */
+ if (dir == IN && copy_from_user(dma_vaddr, buf_vaddr, buf_len))
+ return -EFAULT;
+
+ *dma_len = buf_len;
+ if (dir == OUT) {
+ *dma_len -= last_period_size * word_size * pair->channels;
+ *dma_len = *dma_len / (word_size * pair->channels) *
+ (word_size * pair->channels);
+ if (asrc_priv->dma_type == DMA_EDMA)
+ *dma_len = *dma_len / (word_size * pair->channels * m2m->watermark[OUT])
+ * (word_size * pair->channels * m2m->watermark[OUT]);
+ }
+
+ *sg_nodes = *dma_len / ASRC_MAX_BUFFER_SIZE + 1;
+
+ fifo_addr = asrc_priv->paddr + REG_ASRDx(dir, index);
+
+ return fsl_asrc_dmaconfig(pair, dma_chan, fifo_addr, dma_vaddr,
+ *dma_len, dir, width);
+}
+
+static int fsl_asrc_prepare_buffer(struct fsl_asrc_pair *pair,
+ struct asrc_convert_buffer *pbuf)
+{
+ struct fsl_asrc *asrc_priv = pair->asrc_priv;
+ enum asrc_pair_index index = pair->index;
+ int ret;
+
+ ret = fsl_asrc_prepare_io_buffer(pair, pbuf, IN);
+ if (ret) {
+ pair_err("failed to prepare input buffer: %d\n", ret);
+ return ret;
+ }
+
+ ret = fsl_asrc_prepare_io_buffer(pair, pbuf, OUT);
+ if (ret) {
+ pair_err("failed to prepare output buffer: %d\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+int fsl_asrc_process_buffer_pre(struct completion *complete,
+ enum asrc_pair_index index, bool dir)
+{
+ if (!wait_for_completion_interruptible_timeout(complete, 10 * HZ)) {
+ pr_err("%sput DMA task timeout\n", DIR_STR(dir));
+ return -ETIME;
+ } else if (signal_pending(current)) {
+ pr_err("%sput task forcibly aborted\n", DIR_STR(dir));
+ return -ERESTARTSYS;
+ }
+
+ return 0;
+}
+
+#define mxc_asrc_dma_umap(dev, m2m) \
+ do { \
+ dma_unmap_sg(dev, m2m->sg[IN], m2m->sg_nodes[IN], \
+ DMA_MEM_TO_DEV); \
+ dma_unmap_sg(dev, m2m->sg[OUT], m2m->sg_nodes[OUT], \
+ DMA_DEV_TO_MEM); \
+ } while (0)
+
+int fsl_asrc_process_buffer(struct fsl_asrc_pair *pair,
+ struct asrc_convert_buffer *pbuf)
+{
+ struct fsl_asrc *asrc_priv = pair->asrc_priv;
+ struct fsl_asrc_m2m *m2m = pair->private;
+ enum asrc_pair_index index = pair->index;
+ unsigned long lock_flags;
+ int ret;
+
+ /* Check input task first */
+ ret = fsl_asrc_process_buffer_pre(&m2m->complete[IN], index, IN);
+ if (ret) {
+ mxc_asrc_dma_umap(&asrc_priv->pdev->dev, m2m);
+ return ret;
+ }
+
+ /* ...then output task*/
+ ret = fsl_asrc_process_buffer_pre(&m2m->complete[OUT], index, OUT);
+ if (ret) {
+ mxc_asrc_dma_umap(&asrc_priv->pdev->dev, m2m);
+ return ret;
+ }
+
+ mxc_asrc_dma_umap(&asrc_priv->pdev->dev, m2m);
+
+ /* Fetch the remaining data */
+ spin_lock_irqsave(&m2m->lock, lock_flags);
+ if (!m2m->pair_hold) {
+ spin_unlock_irqrestore(&m2m->lock, lock_flags);
+ return -EFAULT;
+ }
+ spin_unlock_irqrestore(&m2m->lock, lock_flags);
+
+ fsl_asrc_read_last_FIFO(pair);
+
+ /* Update final lengths after getting last FIFO */
+ pbuf->input_buffer_length = m2m->dma_block[IN].length;
+ pbuf->output_buffer_length = m2m->dma_block[OUT].length;
+
+ if (copy_to_user((void __user *)pbuf->output_buffer_vaddr,
+ m2m->dma_block[OUT].dma_vaddr,
+ m2m->dma_block[OUT].length))
+ return -EFAULT;
+
+ return 0;
+}
+
+#ifdef ASRC_POLLING_WITHOUT_DMA
+/* THIS FUNCTION ONLY EXISTS FOR DEBUGGING AND ONLY SUPPORTS TWO CHANNELS */
+static void fsl_asrc_polling_debug(struct fsl_asrc_pair *pair)
+{
+ struct fsl_asrc_m2m *m2m = pair->private;
+ enum asrc_pair_index index = pair->index;
+ u32 *in24 = m2m->dma_block[IN].dma_vaddr;
+ u32 dma_len = m2m->dma_block[IN].length / (pair->channels * 4);
+ u32 *reg24 = m2m->dma_block[OUT].dma_vaddr;
+ u32 size, i, j, t_size, reg;
+
+ t_size = 0;
+
+ for (i = 0; i < dma_len; ) {
+ for (j = 0; j < 2; j++) {
+ regmap_write(asrc_priv->regmap, REG_ASRDx(index), *in24);
+ in24++;
+ regmap_write(asrc_priv->regmap, REG_ASRDx(index), *in24);
+ in24++;
+ i++;
+ }
+ udelay(50);
+ udelay(50 * m2m->rate[OUT] / m2m->rate[IN]);
+
+ size = fsl_asrc_get_output_FIFO_size(index);
+ for (j = 0; j < size; j++) {
+ regmap_read(asrc_priv->regmap, REG_ASRDO(index), &reg);
+ *(reg24) = reg;
+ reg24++;
+ regmap_read(asrc_priv->regmap, REG_ASRDO(index), &reg);
+ *(reg24) = reg;
+ reg24++;
+ }
+ t_size += size;
+ }
+
+ mdelay(1);
+ size = fsl_asrc_get_output_FIFO_size(index);
+ for (j = 0; j < size; j++) {
+ regmap_read(asrc_priv->regmap, REG_ASRDO(index), &reg);
+ *(reg24) = reg;
+ reg24++;
+ regmap_read(asrc_priv->regmap, REG_ASRDO(index), &reg);
+ *(reg24) = reg;
+ reg24++;
+ }
+ t_size += size;
+
+ m2m->dma_block[OUT].length = t_size * pair->channels * 4;
+
+ complete(&m2m->complete[OUT]);
+ complete(&m2m->complete[IN]);
+}
+#else
+static void fsl_asrc_submit_dma(struct fsl_asrc_pair *pair)
+{
+ struct fsl_asrc *asrc_priv = pair->asrc_priv;
+ struct fsl_asrc_m2m *m2m = pair->private;
+ enum asrc_pair_index index = pair->index;
+ u32 size = fsl_asrc_get_output_FIFO_size(pair);
+ int i;
+
+ /* Read all data in OUTPUT FIFO */
+ while (size) {
+ u32 val;
+ for (i = 0; i < size * pair->channels; i++)
+ regmap_read(asrc_priv->regmap, REG_ASRDO(index), &val);
+ /* Fetch the data every 100us */
+ udelay(100);
+
+ size = fsl_asrc_get_output_FIFO_size(pair);
+ }
+
+ /* Submit DMA request */
+ dmaengine_submit(pair->desc[IN]);
+ dma_async_issue_pending(pair->desc[IN]->chan);
+
+ dmaengine_submit(pair->desc[OUT]);
+ dma_async_issue_pending(pair->desc[OUT]->chan);
+
+ /*
+ * Clear DMA request during the stall state of ASRC:
+ * During STALL state, the remaining in input fifo would never be
+ * smaller than the input threshold while the output fifo would not
+ * be bigger than output one. Thus the DMA request would be cleared.
+ */
+ fsl_asrc_set_watermarks(pair, ASRC_FIFO_THRESHOLD_MIN,
+ ASRC_FIFO_THRESHOLD_MAX);
+
+ /* Update the real input threshold to raise DMA request */
+ fsl_asrc_set_watermarks(pair, m2m->watermark[IN], m2m->watermark[OUT]);
+}
+#endif /* ASRC_POLLING_WITHOUT_DMA */
+
+static long fsl_asrc_ioctl_req_pair(struct fsl_asrc_pair *pair,
+ void __user *user)
+{
+ struct fsl_asrc *asrc_priv = pair->asrc_priv;
+ struct fsl_asrc_m2m *m2m = pair->private;
+ struct device *dev = &asrc_priv->pdev->dev;
+ struct asrc_req req;
+ unsigned long lock_flags;
+ long ret;
+
+ ret = copy_from_user(&req, user, sizeof(req));
+ if (ret) {
+ dev_err(dev, "failed to get req from user space: %ld\n", ret);
+ return ret;
+ }
+
+ ret = fsl_asrc_request_pair(req.chn_num, pair);
+ if (ret) {
+ dev_err(dev, "failed to request pair: %ld\n", ret);
+ return ret;
+ }
+
+ spin_lock_irqsave(&m2m->lock, lock_flags);
+ m2m->pair_hold = 1;
+ spin_unlock_irqrestore(&m2m->lock, lock_flags);
+ pair->channels = req.chn_num;
+
+ req.index = pair->index;
+
+ ret = copy_to_user(user, &req, sizeof(req));
+ if (ret) {
+ dev_err(dev, "failed to send req to user space: %ld\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static long fsl_asrc_ioctl_config_pair(struct fsl_asrc_pair *pair,
+ void __user *user)
+{
+ struct fsl_asrc *asrc_priv = pair->asrc_priv;
+ struct fsl_asrc_m2m *m2m = pair->private;
+ struct device *dev = &asrc_priv->pdev->dev;
+ struct asrc_config config;
+ enum asrc_pair_index index;
+ long ret;
+
+ ret = copy_from_user(&config, user, sizeof(config));
+ if (ret) {
+ dev_err(dev, "failed to get config from user space: %ld\n", ret);
+ return ret;
+ }
+
+ index = config.pair;
+
+ pair->config = &config;
+ ret = fsl_asrc_config_pair(pair, false, false);
+ if (ret) {
+ pair_err("failed to config pair: %ld\n", ret);
+ return ret;
+ }
+
+ m2m->watermark[IN] = FSL_ASRC_INPUTFIFO_WML;
+ m2m->watermark[OUT] = FSL_ASRC_OUTPUTFIFO_WML;
+
+ fsl_asrc_set_watermarks(pair, m2m->watermark[IN], m2m->watermark[OUT]);
+
+ m2m->dma_block[IN].length = ASRC_DMA_BUFFER_SIZE;
+ m2m->dma_block[OUT].length = ASRC_DMA_BUFFER_SIZE;
+
+ m2m->word_width[IN] = config.input_word_width;
+ m2m->word_width[OUT] = config.output_word_width;
+
+ m2m->rate[IN] = config.input_sample_rate;
+ m2m->rate[OUT] = config.output_sample_rate;
+
+ m2m->last_period_size = ASRC_OUTPUT_LAST_SAMPLE;
+
+ ret = fsl_allocate_dma_buf(pair);
+ if (ret) {
+ pair_err("failed to allocate DMA buffer: %ld\n", ret);
+ return ret;
+ }
+
+ /* Request DMA channel for both input and output */
+ pair->dma_chan[IN] = fsl_asrc_get_dma_channel(pair, IN);
+ if (pair->dma_chan[IN] == NULL) {
+ pair_err("failed to request input task DMA channel\n");
+ return -EBUSY;
+ }
+
+ pair->dma_chan[OUT] = fsl_asrc_get_dma_channel(pair, OUT);
+ if (pair->dma_chan[OUT] == NULL) {
+ pair_err("failed to request output task DMA channel\n");
+ return -EBUSY;
+ }
+
+ ret = copy_to_user(user, &config, sizeof(config));
+ if (ret) {
+ pair_err("failed to send config to user space: %ld\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static long fsl_asrc_ioctl_release_pair(struct fsl_asrc_pair *pair,
+ void __user *user)
+{
+ struct fsl_asrc_m2m *m2m = pair->private;
+ struct fsl_asrc *asrc_priv = pair->asrc_priv;
+ enum asrc_pair_index index;
+ unsigned long lock_flags;
+ long ret;
+
+ ret = copy_from_user(&index, user, sizeof(index));
+ if (ret) {
+ pair_err("failed to get index from user space: %ld\n", ret);
+ return ret;
+ }
+
+ /* index might be not valid due to some application failure. */
+ if (index < 0)
+ return -EINVAL;
+
+ m2m->asrc_active = 0;
+
+ spin_lock_irqsave(&m2m->lock, lock_flags);
+ m2m->pair_hold = 0;
+ spin_unlock_irqrestore(&m2m->lock, lock_flags);
+
+ if (pair->dma_chan[IN])
+ dma_release_channel(pair->dma_chan[IN]);
+ if (pair->dma_chan[OUT])
+ dma_release_channel(pair->dma_chan[OUT]);
+ kfree(m2m->dma_block[IN].dma_vaddr);
+ kfree(m2m->dma_block[OUT].dma_vaddr);
+ fsl_asrc_release_pair(pair);
+
+ return 0;
+}
+
+static long fsl_asrc_calc_last_period_size(struct fsl_asrc_pair *pair,
+ struct asrc_convert_buffer *pbuf)
+{
+ struct fsl_asrc_m2m *m2m = pair->private;
+ struct fsl_asrc *asrc_priv = pair->asrc_priv;
+ unsigned int out_length;
+ unsigned int in_width, out_width;
+ unsigned int channels = pair->channels;
+ unsigned int in_samples, out_samples;
+ unsigned int last_period_size;
+ unsigned int remain;
+
+ switch (m2m->word_width[IN]) {
+ case ASRC_WIDTH_24_BIT:
+ in_width = 4;
+ break;
+ case ASRC_WIDTH_16_BIT:
+ in_width = 2;
+ break;
+ case ASRC_WIDTH_8_BIT:
+ in_width = 1;
+ break;
+ default:
+ in_width = 2;
+ break;
+ }
+
+ switch (m2m->word_width[OUT]) {
+ case ASRC_WIDTH_24_BIT:
+ out_width = 4;
+ break;
+ case ASRC_WIDTH_16_BIT:
+ out_width = 2;
+ break;
+ case ASRC_WIDTH_8_BIT:
+ out_width = 1;
+ break;
+ default:
+ out_width = 2;
+ break;
+ }
+
+ in_samples = pbuf->input_buffer_length / (in_width * channels);
+
+ out_samples = (m2m->rate[OUT] * in_samples / m2m->rate[IN]);
+
+ out_length = out_samples * out_width * channels;
+
+ last_period_size = pbuf->output_buffer_length / (out_width * channels)
+ - out_samples;
+
+ m2m->last_period_size = last_period_size + 1 + ASRC_OUTPUT_LAST_SAMPLE;
+
+ if (asrc_priv->dma_type == DMA_EDMA) {
+ remain = pbuf->output_buffer_length % (out_width * channels * m2m->watermark[OUT]);
+ if (remain)
+ m2m->last_period_size += remain / (out_width * channels);
+ }
+
+ return 0;
+}
+
+static long fsl_asrc_ioctl_convert(struct fsl_asrc_pair *pair,
+ void __user *user)
+{
+ struct fsl_asrc_m2m *m2m = pair->private;
+ struct fsl_asrc *asrc_priv = pair->asrc_priv;
+ enum asrc_pair_index index = pair->index;
+ struct asrc_convert_buffer buf;
+ long ret;
+
+ ret = copy_from_user(&buf, user, sizeof(buf));
+ if (ret) {
+ pair_err("failed to get buf from user space: %ld\n", ret);
+ return ret;
+ }
+
+ fsl_asrc_calc_last_period_size(pair, &buf);
+
+ ret = fsl_asrc_prepare_buffer(pair, &buf);
+ if (ret) {
+ pair_err("failed to prepare buffer: %ld\n", ret);
+ return ret;
+ }
+
+ init_completion(&m2m->complete[IN]);
+ init_completion(&m2m->complete[OUT]);
+
+#ifdef ASRC_POLLING_WITHOUT_DMA
+ fsl_asrc_polling_debug(pair);
+#else
+ fsl_asrc_submit_dma(pair);
+#endif
+
+ ret = fsl_asrc_process_buffer(pair, &buf);
+ if (ret) {
+ if (ret != -ERESTARTSYS)
+ pair_err("failed to process buffer: %ld\n", ret);
+ return ret;
+ }
+
+ ret = copy_to_user(user, &buf, sizeof(buf));
+ if (ret) {
+ pair_err("failed to send buf to user space: %ld\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static long fsl_asrc_ioctl_start_conv(struct fsl_asrc_pair *pair,
+ void __user *user)
+{
+ struct fsl_asrc *asrc_priv = pair->asrc_priv;
+ struct fsl_asrc_m2m *m2m = pair->private;
+ enum asrc_pair_index index;
+ long ret;
+
+ ret = copy_from_user(&index, user, sizeof(index));
+ if (ret) {
+ pair_err("failed to get index from user space: %ld\n", ret);
+ return ret;
+ }
+
+ m2m->asrc_active = 1;
+ fsl_asrc_start_pair(pair);
+
+ return 0;
+}
+
+static long fsl_asrc_ioctl_stop_conv(struct fsl_asrc_pair *pair,
+ void __user *user)
+{
+ struct fsl_asrc *asrc_priv = pair->asrc_priv;
+ struct fsl_asrc_m2m *m2m = pair->private;
+ enum asrc_pair_index index;
+ long ret;
+
+ ret = copy_from_user(&index, user, sizeof(index));
+ if (ret) {
+ pair_err("failed to get index from user space: %ld\n", ret);
+ return ret;
+ }
+
+ dmaengine_terminate_all(pair->dma_chan[IN]);
+ dmaengine_terminate_all(pair->dma_chan[OUT]);
+
+ fsl_asrc_stop_pair(pair);
+ m2m->asrc_active = 0;
+
+ return 0;
+}
+
+static long fsl_asrc_ioctl_status(struct fsl_asrc_pair *pair, void __user *user)
+{
+ struct fsl_asrc *asrc_priv = pair->asrc_priv;
+ enum asrc_pair_index index = pair->index;
+ struct asrc_status_flags flags;
+ long ret;
+
+ ret = copy_from_user(&flags, user, sizeof(flags));
+ if (ret) {
+ pair_err("failed to get flags from user space: %ld\n", ret);
+ return ret;
+ }
+
+ fsl_asrc_get_status(pair, &flags);
+
+ ret = copy_to_user(user, &flags, sizeof(flags));
+ if (ret) {
+ pair_err("failed to send flags to user space: %ld\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static long fsl_asrc_ioctl_flush(struct fsl_asrc_pair *pair, void __user *user)
+{
+ struct fsl_asrc *asrc_priv = pair->asrc_priv;
+ enum asrc_pair_index index = pair->index;
+
+ /* Release DMA and request again */
+ dma_release_channel(pair->dma_chan[IN]);
+ dma_release_channel(pair->dma_chan[OUT]);
+
+ pair->dma_chan[IN] = fsl_asrc_get_dma_channel(pair, IN);
+ if (pair->dma_chan[IN] == NULL) {
+ pair_err("failed to request input task DMA channel\n");
+ return -EBUSY;
+ }
+
+ pair->dma_chan[OUT] = fsl_asrc_get_dma_channel(pair, OUT);
+ if (pair->dma_chan[OUT] == NULL) {
+ pair_err("failed to request output task DMA channel\n");
+ return -EBUSY;
+ }
+
+ return 0;
+}
+
+static long fsl_asrc_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+ struct fsl_asrc_pair *pair = file->private_data;
+ struct fsl_asrc *asrc_priv = pair->asrc_priv;
+ void __user *user = (void __user *)arg;
+ long ret = 0;
+
+ switch (cmd) {
+ case ASRC_REQ_PAIR:
+ ret = fsl_asrc_ioctl_req_pair(pair, user);
+ break;
+ case ASRC_CONFIG_PAIR:
+ ret = fsl_asrc_ioctl_config_pair(pair, user);
+ break;
+ case ASRC_RELEASE_PAIR:
+ ret = fsl_asrc_ioctl_release_pair(pair, user);
+ break;
+ case ASRC_CONVERT:
+ ret = fsl_asrc_ioctl_convert(pair, user);
+ break;
+ case ASRC_START_CONV:
+ ret = fsl_asrc_ioctl_start_conv(pair, user);
+ break;
+ case ASRC_STOP_CONV:
+ ret = fsl_asrc_ioctl_stop_conv(pair, user);
+ break;
+ case ASRC_STATUS:
+ ret = fsl_asrc_ioctl_status(pair, user);
+ break;
+ case ASRC_FLUSH:
+ ret = fsl_asrc_ioctl_flush(pair, user);
+ break;
+ default:
+ dev_err(&asrc_priv->pdev->dev, "invalid ioctl cmd!\n");
+ break;
+ }
+
+ return ret;
+}
+
+static int fsl_asrc_open(struct inode *inode, struct file *file)
+{
+ struct miscdevice *asrc_miscdev = file->private_data;
+ struct fsl_asrc *asrc_priv = dev_get_drvdata(asrc_miscdev->parent);
+ struct device *dev = &asrc_priv->pdev->dev;
+ struct fsl_asrc_pair *pair;
+ struct fsl_asrc_m2m *m2m;
+ int ret;
+
+ ret = signal_pending(current);
+ if (ret) {
+ dev_err(dev, "current process has a signal pending\n");
+ return ret;
+ }
+
+ pair = kzalloc(sizeof(struct fsl_asrc_pair), GFP_KERNEL);
+ if (!pair) {
+ dev_err(dev, "failed to allocate pair\n");
+ return -ENOMEM;
+ }
+
+ m2m = kzalloc(sizeof(struct fsl_asrc_m2m), GFP_KERNEL);
+ if (!m2m) {
+ dev_err(dev, "failed to allocate m2m resource\n");
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ pair->private = m2m;
+ pair->asrc_priv = asrc_priv;
+
+ spin_lock_init(&m2m->lock);
+
+ file->private_data = pair;
+
+ pm_runtime_get_sync(dev);
+
+ return 0;
+out:
+ kfree(pair);
+
+ return ret;
+}
+
+static int fsl_asrc_close(struct inode *inode, struct file *file)
+{
+ struct fsl_asrc_pair *pair = file->private_data;
+ struct fsl_asrc_m2m *m2m = pair->private;
+ struct fsl_asrc *asrc_priv = pair->asrc_priv;
+ struct device *dev = &asrc_priv->pdev->dev;
+ unsigned long lock_flags;
+
+ if (m2m->asrc_active) {
+ m2m->asrc_active = 0;
+
+ dmaengine_terminate_all(pair->dma_chan[IN]);
+ dmaengine_terminate_all(pair->dma_chan[OUT]);
+
+ fsl_asrc_stop_pair(pair);
+ fsl_asrc_input_dma_callback((void *)pair);
+ fsl_asrc_output_dma_callback((void *)pair);
+ }
+
+ spin_lock_irqsave(&m2m->lock, lock_flags);
+ if (m2m->pair_hold) {
+ m2m->pair_hold = 0;
+ spin_unlock_irqrestore(&m2m->lock, lock_flags);
+
+ if (pair->dma_chan[IN])
+ dma_release_channel(pair->dma_chan[IN]);
+ if (pair->dma_chan[OUT])
+ dma_release_channel(pair->dma_chan[OUT]);
+
+ kfree(m2m->dma_block[IN].dma_vaddr);
+ kfree(m2m->dma_block[OUT].dma_vaddr);
+
+ fsl_asrc_release_pair(pair);
+ } else
+ spin_unlock_irqrestore(&m2m->lock, lock_flags);
+
+ spin_lock_irqsave(&asrc_priv->lock, lock_flags);
+ kfree(m2m);
+ kfree(pair);
+ spin_unlock_irqrestore(&asrc_priv->lock, lock_flags);
+ file->private_data = NULL;
+
+ pm_runtime_put_sync(dev);
+
+ return 0;
+}
+
+static const struct file_operations asrc_fops = {
+ .owner = THIS_MODULE,
+ .unlocked_ioctl = fsl_asrc_ioctl,
+ .open = fsl_asrc_open,
+ .release = fsl_asrc_close,
+};
+
+static int fsl_asrc_m2m_init(struct fsl_asrc *asrc_priv)
+{
+ struct device *dev = &asrc_priv->pdev->dev;
+ int ret;
+
+ asrc_priv->asrc_miscdev.fops = &asrc_fops;
+ asrc_priv->asrc_miscdev.parent = dev;
+ asrc_priv->asrc_miscdev.name = asrc_priv->name;
+ asrc_priv->asrc_miscdev.minor = MISC_DYNAMIC_MINOR;
+ ret = misc_register(&asrc_priv->asrc_miscdev);
+ if (ret) {
+ dev_err(dev, "failed to register char device %d\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int fsl_asrc_m2m_remove(struct platform_device *pdev)
+{
+ struct fsl_asrc *asrc_priv = dev_get_drvdata(&pdev->dev);
+
+ misc_deregister(&asrc_priv->asrc_miscdev);
+ return 0;
+}
+
+static void fsl_asrc_m2m_suspend(struct fsl_asrc *asrc_priv)
+{
+ struct fsl_asrc_pair *pair;
+ struct fsl_asrc_m2m *m2m;
+ unsigned long lock_flags;
+ int i;
+
+ for (i = 0; i < ASRC_PAIR_MAX_NUM; i++) {
+ spin_lock_irqsave(&asrc_priv->lock, lock_flags);
+ pair = asrc_priv->pair[i];
+ if (!pair || !pair->private) {
+ spin_unlock_irqrestore(&asrc_priv->lock, lock_flags);
+ continue;
+ }
+ m2m = pair->private;
+
+ if (!completion_done(&m2m->complete[IN])) {
+ if (pair->dma_chan[IN])
+ dmaengine_terminate_all(pair->dma_chan[IN]);
+ fsl_asrc_input_dma_callback((void *)pair);
+ }
+ if (!completion_done(&m2m->complete[OUT])) {
+ if (pair->dma_chan[OUT])
+ dmaengine_terminate_all(pair->dma_chan[OUT]);
+ fsl_asrc_output_dma_callback((void *)pair);
+ }
+
+ spin_unlock_irqrestore(&asrc_priv->lock, lock_flags);
+ }
+}
+
+static void fsl_asrc_m2m_resume(struct fsl_asrc *asrc_priv)
+{
+ struct fsl_asrc_pair *pair;
+ struct fsl_asrc_m2m *m2m;
+ unsigned long lock_flags;
+ enum asrc_pair_index index;
+ int i, j;
+
+ for (i = 0; i < ASRC_PAIR_MAX_NUM; i++) {
+ spin_lock_irqsave(&asrc_priv->lock, lock_flags);
+ pair = asrc_priv->pair[i];
+ if (!pair || !pair->private) {
+ spin_unlock_irqrestore(&asrc_priv->lock, lock_flags);
+ continue;
+ }
+ m2m = pair->private;
+ index = pair->index;
+
+ for (j = 0; j < pair->channels * 4; j++)
+ regmap_write(asrc_priv->regmap, REG_ASRDI(index), 0);
+
+ spin_unlock_irqrestore(&asrc_priv->lock, lock_flags);
+ }
+}
diff --git a/sound/soc/fsl/fsl_dma_workaround.c b/sound/soc/fsl/fsl_dma_workaround.c
new file mode 100644
index 000000000000..22ccef7fc08c
--- /dev/null
+++ b/sound/soc/fsl/fsl_dma_workaround.c
@@ -0,0 +1,254 @@
+/*
+ * fsl_dma_workaround.c - DMA workaround bits
+ *
+ * Copyright (C) 2017 NXP
+ *
+ * Author: Daniel Baluta <daniel.baluta@nxp.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.
+ */
+#include <linux/slab.h>
+#include "fsl_acm.h"
+#include "fsl_dma_workaround.h"
+
+int gpt_events[2][2] = {
+ {ESAI0_IPD_ESAI_TX_B, ESAI0_IPD_ESAI_RX_B},
+ {SPDIF0_DRQ1_SPDIF_B, SPDIF0_DRQ0_SPDIF_B},
+};
+
+/*
+ * configure_gpt_dma - configures GPT DMA for a given audio interface
+ * @substream: PCM substream
+ * @info: DMA workaround specific info
+ *
+ */
+int configure_gpt_dma(struct snd_pcm_substream *substream,
+ struct fsl_dma_workaround_info *info)
+{
+ bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
+
+ if (tx) {
+ writel_relaxed(gpt_events[info->iface][0],
+ info->base_acm + GPT0_CAPIN1_SEL_OFF);
+ writel_relaxed(gpt_events[info->iface][0],
+ info->base_acm + GPT1_CAPIN1_SEL_OFF);
+
+ writel(le32_to_cpu(info->tcd_sw[0].vtcd->saddr),
+ info->base_edma_gpt1 + EDMA_TCD_SADDR);
+ writel(le32_to_cpu(info->tcd_sw[0].vtcd->daddr),
+ info->base_edma_gpt1 + EDMA_TCD_DADDR);
+ writew(le16_to_cpu(info->tcd_sw[0].vtcd->attr),
+ info->base_edma_gpt1 + EDMA_TCD_ATTR);
+ writew(le16_to_cpu(info->tcd_sw[0].vtcd->soff),
+ info->base_edma_gpt1 + EDMA_TCD_SOFF);
+ writel(le32_to_cpu(info->tcd_sw[0].vtcd->nbytes),
+ info->base_edma_gpt1 + EDMA_TCD_NBYTES);
+ writel(le32_to_cpu(info->tcd_sw[0].vtcd->slast),
+ info->base_edma_gpt1 + EDMA_TCD_SLAST);
+ writew(le16_to_cpu(info->tcd_sw[0].vtcd->citer),
+ info->base_edma_gpt1 + EDMA_TCD_CITER);
+ writew(le16_to_cpu(info->tcd_sw[0].vtcd->biter),
+ info->base_edma_gpt1 + EDMA_TCD_BITER);
+ writew(le16_to_cpu(info->tcd_sw[0].vtcd->doff),
+ info->base_edma_gpt1 + EDMA_TCD_DOFF);
+ writel(le32_to_cpu(info->tcd_sw[0].vtcd->dlast_sga),
+ info->base_edma_gpt1 + EDMA_TCD_DLAST_SGA);
+ writew(le16_to_cpu(info->tcd_sw[0].vtcd->csr),
+ info->base_edma_gpt1 + EDMA_TCD_CSR);
+
+ writel(0x0, info->base_edma_gpt1 + EDMA_CH_SBR);
+ writel(0x1, info->base_edma_gpt1 + EDMA_CH_CSR);
+
+ /* configure this gpt for dma tx */
+ writel_relaxed(0x8, info->base_gpt0 + GPT_IR);
+ writel_relaxed(0x7<<12, info->base_gpt0 + GPT_PR);
+ writel_relaxed(0x20441, info->base_gpt0 + GPT_CR);
+
+ /* configure this gpt for dma tx request clear */
+ writel_relaxed(0x8, info->base_gpt1 + GPT_IR);
+ writel_relaxed(0x7<<12, info->base_gpt1 + GPT_PR);
+ writel_relaxed(0x10441, info->base_gpt1 + GPT_CR);
+
+ } else {
+ writel_relaxed(gpt_events[info->iface][1],
+ info->base_acm + GPT2_CAPIN1_SEL_OFF);
+ writel_relaxed(gpt_events[info->iface][1],
+ info->base_acm + GPT3_CAPIN1_SEL_OFF);
+
+ writel(le32_to_cpu(info->tcd_sw[2].vtcd->saddr),
+ info->base_edma_gpt3 + EDMA_TCD_SADDR);
+ writel(le32_to_cpu(info->tcd_sw[2].vtcd->daddr),
+ info->base_edma_gpt3 + EDMA_TCD_DADDR);
+ writew(le16_to_cpu(info->tcd_sw[2].vtcd->attr),
+ info->base_edma_gpt3 + EDMA_TCD_ATTR);
+ writew(le16_to_cpu(info->tcd_sw[2].vtcd->soff),
+ info->base_edma_gpt3 + EDMA_TCD_SOFF);
+ writel(le32_to_cpu(info->tcd_sw[2].vtcd->nbytes),
+ info->base_edma_gpt3 + EDMA_TCD_NBYTES);
+ writel(le32_to_cpu(info->tcd_sw[2].vtcd->slast),
+ info->base_edma_gpt3 + EDMA_TCD_SLAST);
+ writew(le16_to_cpu(info->tcd_sw[2].vtcd->citer),
+ info->base_edma_gpt3 + EDMA_TCD_CITER);
+ writew(le16_to_cpu(info->tcd_sw[2].vtcd->biter),
+ info->base_edma_gpt3 + EDMA_TCD_BITER);
+ writew(le16_to_cpu(info->tcd_sw[2].vtcd->doff),
+ info->base_edma_gpt3 + EDMA_TCD_DOFF);
+ writel(le32_to_cpu(info->tcd_sw[2].vtcd->dlast_sga),
+ info->base_edma_gpt3 + EDMA_TCD_DLAST_SGA);
+ writew(le16_to_cpu(info->tcd_sw[2].vtcd->csr),
+ info->base_edma_gpt3 + EDMA_TCD_CSR);
+
+ writel(0x0, info->base_edma_gpt3 + EDMA_CH_SBR);
+ writel(0x1, info->base_edma_gpt3 + EDMA_CH_CSR);
+
+ /* configure this gpt for dma rx */
+ writel_relaxed(0x8, info->base_gpt2 + GPT_IR);
+ writel_relaxed(0x7<<12, info->base_gpt2 + GPT_PR);
+ writel_relaxed(0x20441, info->base_gpt2 + GPT_CR);
+
+ /* configure this gpt for dma rx request clear*/
+ writel_relaxed(0x8, info->base_gpt3 + GPT_IR);
+ writel_relaxed(0x7<<12, info->base_gpt3 + GPT_PR);
+ writel_relaxed(0x10441, info->base_gpt3 + GPT_CR);
+
+ }
+
+ return 0;
+}
+
+
+int clear_gpt_dma(struct snd_pcm_substream *substream,
+ struct fsl_dma_workaround_info *info)
+{
+ bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
+ u32 val;
+
+ if (tx) {
+ val = readl(info->base_edma_gpt1 + EDMA_CH_CSR);
+ val &= ~0x1;
+ writel(val, info->base_edma_gpt1 + EDMA_CH_CSR);
+
+ /* disable gpt */
+ writel_relaxed(0, info->base_gpt0 + GPT_IR);
+ writel_relaxed(0, info->base_gpt0 + GPT_PR);
+ writel_relaxed(0, info->base_gpt0 + GPT_CR);
+
+ writel_relaxed(0, info->base_gpt1 + GPT_IR);
+ writel_relaxed(0, info->base_gpt1 + GPT_PR);
+ writel_relaxed(0, info->base_gpt1 + GPT_CR);
+
+ } else {
+ val = readl(info->base_edma_gpt3 + EDMA_CH_CSR);
+ val &= ~0x1;
+ writel(val, info->base_edma_gpt3 + EDMA_CH_CSR);
+
+ /* disable gpt */
+ writel_relaxed(0, info->base_gpt2 + GPT_IR);
+ writel_relaxed(0, info->base_gpt2 + GPT_PR);
+ writel_relaxed(0, info->base_gpt2 + GPT_CR);
+
+ writel_relaxed(0, info->base_gpt3 + GPT_IR);
+ writel_relaxed(0, info->base_gpt3 + GPT_PR);
+ writel_relaxed(0, info->base_gpt3 + GPT_CR);
+ }
+
+ return 0;
+}
+
+struct fsl_dma_workaround_info *
+fsl_dma_workaround_alloc_info(const char *pool_name, struct device *dma_dev,
+ const char *base_acm_compat, int iface)
+{
+ struct fsl_dma_workaround_info *info;
+ int *buffer;
+ int i;
+
+ info = devm_kzalloc(dma_dev, sizeof(*info), GFP_KERNEL);
+ if (!info)
+ return ERR_PTR(-ENOMEM);
+
+ info->tcd_pool = dma_pool_create(pool_name, dma_dev,
+ sizeof(struct fsl_edma3_hw_tcd),
+ 32, 0);
+
+ info->buf.area = dma_alloc_writecombine(dma_dev, 0x1000,
+ &info->buf.addr, GFP_KERNEL);
+
+ buffer = (int *)info->buf.area;
+ buffer[0] = 0x8;
+
+ info->tcd_sw[0].vtcd = dma_pool_alloc(info->tcd_pool,
+ GFP_ATOMIC, &info->tcd_sw[0].ptcd);
+ info->tcd_sw[1].vtcd = dma_pool_alloc(info->tcd_pool,
+ GFP_ATOMIC, &info->tcd_sw[1].ptcd);
+ info->tcd_sw[2].vtcd = dma_pool_alloc(info->tcd_pool,
+ GFP_ATOMIC, &info->tcd_sw[2].ptcd);
+ info->tcd_sw[3].vtcd = dma_pool_alloc(info->tcd_pool,
+ GFP_ATOMIC, &info->tcd_sw[3].ptcd);
+
+ for (i = 0; i < 4; i++) {
+ info->tcd_sw[i].vtcd->saddr = info->buf.addr;
+ info->tcd_sw[i].vtcd->attr = 0x0202;
+ info->tcd_sw[i].vtcd->soff = 0x0;
+ info->tcd_sw[i].vtcd->nbytes = 0x4;
+ info->tcd_sw[i].vtcd->slast = 0x0;
+ info->tcd_sw[i].vtcd->citer = 0x1;
+ info->tcd_sw[i].vtcd->biter = 0x1;
+ info->tcd_sw[i].vtcd->doff = 0x0;
+ info->tcd_sw[i].vtcd->csr = 0x10;
+ }
+
+ info->tcd_sw[0].vtcd->daddr = GPT5_ADDR + GPT_SR;
+ info->tcd_sw[1].vtcd->daddr = GPT6_ADDR + GPT_SR;
+ info->tcd_sw[2].vtcd->daddr = GPT7_ADDR + GPT_SR;
+ info->tcd_sw[3].vtcd->daddr = GPT8_ADDR + GPT_SR;
+
+ info->tcd_sw[0].vtcd->dlast_sga =
+ info->tcd_sw[1].ptcd;
+ info->tcd_sw[1].vtcd->dlast_sga =
+ info->tcd_sw[0].ptcd;
+ info->tcd_sw[2].vtcd->dlast_sga =
+ info->tcd_sw[3].ptcd;
+ info->tcd_sw[3].vtcd->dlast_sga =
+ info->tcd_sw[2].ptcd;
+
+ info->base_gpt0 = ioremap(GPT5_ADDR, SZ_64K);
+ info->base_gpt1 = ioremap(GPT6_ADDR, SZ_64K);
+ info->base_gpt2 = ioremap(GPT7_ADDR, SZ_64K);
+ info->base_gpt3 = ioremap(GPT8_ADDR, SZ_64K);
+
+ info->base_edma_gpt1 = ioremap(EDMA_GPT6_ADDR, SZ_64K);
+ info->base_edma_gpt3 = ioremap(EDMA_GPT8_ADDR, SZ_64K);
+
+ info->base_acm = of_iomap(of_find_compatible_node(
+ NULL, NULL, base_acm_compat), 0);
+
+ info->iface = iface;
+ return info;
+}
+
+void fsl_dma_workaround_free_info(struct fsl_dma_workaround_info *info,
+ struct device *dma_dev)
+{
+ dma_free_writecombine(dma_dev,
+ 0x1000,
+ info->buf.area,
+ info->buf.addr);
+
+ dma_pool_free(info->tcd_pool,
+ info->tcd_sw[0].vtcd,
+ info->tcd_sw[0].ptcd);
+ dma_pool_free(info->tcd_pool,
+ info->tcd_sw[1].vtcd,
+ info->tcd_sw[1].ptcd);
+ dma_pool_free(info->tcd_pool,
+ info->tcd_sw[2].vtcd,
+ info->tcd_sw[2].ptcd);
+ dma_pool_free(info->tcd_pool,
+ info->tcd_sw[3].vtcd,
+ info->tcd_sw[3].ptcd);
+
+ dma_pool_destroy(info->tcd_pool);
+}
diff --git a/sound/soc/fsl/fsl_dma_workaround.h b/sound/soc/fsl/fsl_dma_workaround.h
new file mode 100644
index 000000000000..0602817ebd7f
--- /dev/null
+++ b/sound/soc/fsl/fsl_dma_workaround.h
@@ -0,0 +1,102 @@
+/*
+ * fsl_dma_workaround.h - EDMA bits useful for DMA workaround
+ *
+ * Copyright (C) 2017 NXP
+ *
+ * Author: Daniel Baluta <daniel.baluta@nxp.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 _FSL_DMA_WORKAROUND_H
+#define _FSL_DMA_WORKAROUND_H
+
+#include <sound/pcm.h>
+#include <linux/dmapool.h>
+#include <linux/dma-mapping.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+
+#define EDMA_CH_CSR 0x00
+#define EDMA_CH_ES 0x04
+#define EDMA_CH_INT 0x08
+#define EDMA_CH_SBR 0x0C
+#define EDMA_CH_PRI 0x10
+#define EDMA_TCD_SADDR 0x20
+#define EDMA_TCD_SOFF 0x24
+#define EDMA_TCD_ATTR 0x26
+#define EDMA_TCD_NBYTES 0x28
+#define EDMA_TCD_SLAST 0x2C
+#define EDMA_TCD_DADDR 0x30
+#define EDMA_TCD_DOFF 0x34
+#define EDMA_TCD_CITER_ELINK 0x36
+#define EDMA_TCD_CITER 0x36
+#define EDMA_TCD_DLAST_SGA 0x38
+#define EDMA_TCD_CSR 0x3C
+#define EDMA_TCD_BITER_ELINK 0x3E
+#define EDMA_TCD_BITER 0x3E
+
+#define GPT_CR 0x00
+#define GPT_PR 0x04
+#define GPT_SR 0x08
+#define GPT_IR 0x0C
+
+#define GPT5_ADDR 0x590b0000
+#define GPT6_ADDR 0x590c0000
+#define GPT7_ADDR 0x590d0000
+#define GPT8_ADDR 0x590e0000
+
+#define EDMA_GPT6_ADDR 0x59360000
+#define EDMA_GPT8_ADDR 0x59380000
+
+#define FSL_DMA_WORKAROUND_ESAI 0
+#define FSL_DMA_WORKAROUND_SPDIF 1
+
+struct fsl_edma3_hw_tcd {
+ __le32 saddr;
+ __le16 soff;
+ __le16 attr;
+ __le32 nbytes;
+ __le32 slast;
+ __le32 daddr;
+ __le16 doff;
+ __le16 citer;
+ __le32 dlast_sga;
+ __le16 csr;
+ __le16 biter;
+};
+
+struct fsl_edma3_sw_tcd {
+ dma_addr_t ptcd;
+ struct fsl_edma3_hw_tcd *vtcd;
+};
+
+struct fsl_dma_workaround_info {
+ struct fsl_edma3_sw_tcd tcd_sw[4];
+ struct dma_pool *tcd_pool;
+ struct snd_dma_buffer buf;
+ void __iomem *base_gpt0;
+ void __iomem *base_gpt1;
+ void __iomem *base_gpt2;
+ void __iomem *base_gpt3;
+ void __iomem *base_edma_gpt1;
+ void __iomem *base_edma_gpt3;
+ void __iomem *base_acm;
+ int iface;
+};
+
+int configure_gpt_dma(struct snd_pcm_substream *substream,
+ struct fsl_dma_workaround_info *info);
+
+int clear_gpt_dma(struct snd_pcm_substream *substream,
+ struct fsl_dma_workaround_info *info);
+
+struct fsl_dma_workaround_info *
+fsl_dma_workaround_alloc_info(const char *pool_name, struct device *dma_dev,
+ const char *base_acm_compat, int iface);
+
+void fsl_dma_workaround_free_info(struct fsl_dma_workaround_info *info,
+ struct device *dma_dev);
+#endif /* _FSL_EDMA_H */
diff --git a/sound/soc/fsl/fsl_dsd.h b/sound/soc/fsl/fsl_dsd.h
new file mode 100644
index 000000000000..a45f31422f84
--- /dev/null
+++ b/sound/soc/fsl/fsl_dsd.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2018 NXP
+ *
+ * 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 __FSL_DSD_H
+#define __FSL_DSD_H
+
+#include <linux/pinctrl/consumer.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+
+static bool fsl_is_dsd(struct snd_pcm_hw_params *params)
+{
+ snd_pcm_format_t format = params_format(params);
+
+ switch (format) {
+ case SNDRV_PCM_FORMAT_DSD_U8:
+ case SNDRV_PCM_FORMAT_DSD_U16_LE:
+ case SNDRV_PCM_FORMAT_DSD_U16_BE:
+ case SNDRV_PCM_FORMAT_DSD_U32_LE:
+ case SNDRV_PCM_FORMAT_DSD_U32_BE:
+ return true;
+ default:
+ return false;
+ }
+}
+
+static inline struct pinctrl_state *fsl_get_pins_state(struct pinctrl *pinctrl,
+ struct snd_pcm_hw_params *params, u32 bclk)
+{
+ struct pinctrl_state *state = 0;
+
+ if (fsl_is_dsd(params)) {
+ /* DSD512@44.1kHz, DSD512@48kHz */
+ if (bclk >= 22579200)
+ state = pinctrl_lookup_state(pinctrl, "dsd512");
+
+ /* Get default DSD state */
+ if (IS_ERR_OR_NULL(state))
+ state = pinctrl_lookup_state(pinctrl, "dsd");
+ } else {
+ /* 706k32b2c, 768k32b2c, etc */
+ if (bclk >= 45158400)
+ state = pinctrl_lookup_state(pinctrl, "pcm_b2m");
+ }
+
+ /* Get default state */
+ if (IS_ERR_OR_NULL(state))
+ state = pinctrl_lookup_state(pinctrl, "default");
+
+ return state;
+}
+
+#endif /* __FSL_DSD_H */
diff --git a/sound/soc/fsl/fsl_dsp.c b/sound/soc/fsl/fsl_dsp.c
new file mode 100644
index 000000000000..35733841046c
--- /dev/null
+++ b/sound/soc/fsl/fsl_dsp.c
@@ -0,0 +1,1166 @@
+/*
+ * Freescale DSP driver
+ *
+ * Copyright (c) 2012-2013 by Tensilica Inc. ALL RIGHTS RESERVED.
+ * Copyright 2018 NXP
+ *
+ * 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.
+ *
+ * Copyright (c) 2001 William L. Pitts
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are freely
+ * permitted provided that the above copyright notice and this
+ * paragraph and the following disclaimer are duplicated in all
+ * such forms.
+ *
+ * This software is provided "AS IS" and without any express or
+ * implied warranties, including, without limitation, the implied
+ * warranties of merchantability and fitness for a particular
+ * purpose.
+ *
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/dma-mapping.h>
+#include <linux/module.h>
+#include <linux/firmware.h>
+#include <linux/interrupt.h>
+#include <linux/file.h>
+#include <linux/of_platform.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/slab.h>
+#include <linux/platform_data/dma-imx.h>
+#include <linux/miscdevice.h>
+#include <linux/fs.h>
+#include <linux/pm_runtime.h>
+#include <linux/mx8_mu.h>
+#include <linux/uaccess.h>
+#include <linux/poll.h>
+#ifdef CONFIG_COMPAT
+#include <linux/compat.h>
+#endif
+#include <uapi/linux/mxc_dsp.h>
+#include <soc/imx8/sc/svc/irq/api.h>
+#include <soc/imx8/sc/types.h>
+#include <soc/imx8/sc/ipc.h>
+#include <soc/imx8/sc/sci.h>
+
+#include <sound/pcm.h>
+#include <sound/soc.h>
+
+#include "fsl_dsp.h"
+#include "fsl_dsp_pool.h"
+#include "fsl_dsp_xaf_api.h"
+
+/* ...allocate new client */
+struct xf_client *xf_client_alloc(struct fsl_dsp *dsp_priv)
+{
+ struct xf_client *client;
+ u32 id;
+
+ id = dsp_priv->xf_client_map[0].next;
+
+ /* ...try to allocate a client handle */
+ if (id != 0) {
+ /* ...allocate client memory */
+ client = kmalloc(sizeof(*client), GFP_KERNEL);
+ if (!client)
+ return ERR_PTR(-ENOMEM);
+
+ /* ...advance the head of free clients */
+ dsp_priv->xf_client_map[0].next =
+ dsp_priv->xf_client_map[id].next;
+
+ /* ...put associate client id with given object */
+ dsp_priv->xf_client_map[id].client = client;
+
+ /* ...mark client is not yet bound to proxy */
+ client->proxy = NULL;
+
+ /* ...save global proxy client identifier */
+ client->id = id;
+
+ return client;
+ }
+
+ /* ...number of clients exceeded */
+ return ERR_PTR(-EBUSY);
+}
+
+/* ...recycle client object */
+static inline void xf_client_free(struct xf_client *client)
+{
+ int id = client->id;
+ struct fsl_dsp *dsp_priv = (struct fsl_dsp *)client->global;
+
+ /* ...put proxy client id into free clients list */
+ dsp_priv->xf_client_map[id].next = dsp_priv->xf_client_map[0].next;
+ dsp_priv->xf_client_map[0].next = id;
+
+ /* ...destroy client data */
+ kfree(client);
+}
+
+/* ...lookup client basing on id */
+struct xf_client *xf_client_lookup(struct fsl_dsp *dsp_priv, u32 id)
+{
+ if ((id >= XF_CFG_MAX_IPC_CLIENTS) ||
+ (dsp_priv->xf_client_map[id].next < XF_CFG_MAX_IPC_CLIENTS)
+ )
+ return NULL;
+ else
+ return dsp_priv->xf_client_map[id].client;
+}
+
+/* ...helper function for retrieving the client handle */
+static inline struct xf_client *xf_get_client(struct file *file)
+{
+ struct xf_client *client;
+ u32 id;
+
+ client = (struct xf_client *)file->private_data;
+ if (!client)
+ return ERR_PTR(-EINVAL);
+
+ id = client->id;
+ if (id >= XF_CFG_MAX_IPC_CLIENTS)
+ return ERR_PTR(-EINVAL);
+
+ return client;
+}
+
+static int fsl_dsp_client_register(struct xf_client *client)
+{
+ struct fsl_dsp *dsp_priv;
+ struct device *dev;
+
+ dsp_priv = (struct fsl_dsp *)client->global;
+ dev = dsp_priv->dev;
+
+ /* ...make sure client is not registered yet */
+ if (client->proxy != NULL) {
+ pr_err("client-%x already registered", client->id);
+ return -EBUSY;
+ }
+
+ /* ...complete association (no communication with remote proxy here) */
+ client->proxy = &dsp_priv->proxy;
+
+ pr_debug("client-%x registered within proxy", client->id);
+
+ return 0;
+}
+
+/* ...unregister client from shared memory interface */
+static int fsl_dsp_client_unregister(struct xf_client *client)
+{
+ struct xf_proxy *proxy = client->proxy;
+
+ /* ...make sure client is registered */
+ if (proxy == NULL) {
+ pr_err("client-%x is not registered", client->id);
+ return -EBUSY;
+ }
+
+ /* ...just clean proxy reference */
+ client->proxy = NULL;
+
+ pr_debug("client-%x registered within proxy", client->id);
+
+ return 0;
+}
+
+static int fsl_dsp_ipc_msg_to_dsp(struct xf_client *client,
+ void __user *user)
+{
+ struct fsl_dsp *dsp_priv = (struct fsl_dsp *)client->global;
+ struct device *dev = dsp_priv->dev;
+ struct xf_proxy_message msg;
+ void *buffer;
+ unsigned long ret = 0;
+
+ ret = copy_from_user(&msg, user, sizeof(struct xf_proxy_message));
+ if (ret) {
+ dev_err(dev, "failed to get message from user space\n");
+ return -EFAULT;
+ }
+
+ /* ...make sure message pointer is sane */
+ buffer = xf_proxy_a2b(&dsp_priv->proxy, msg.address);
+ if (buffer == (void *)-1)
+ return -EFAULT;
+
+ /* ...put current proxy client into message session id */
+ msg.session_id = XF_MSG_AP_FROM_USER(msg.session_id, client->id);
+
+ xf_cmd_send(&dsp_priv->proxy,
+ msg.session_id,
+ msg.opcode,
+ buffer,
+ msg.length);
+
+ return 0;
+}
+
+static int fsl_dsp_ipc_msg_from_dsp(struct xf_client *client,
+ void __user *user)
+{
+ struct fsl_dsp *dsp_priv = (struct fsl_dsp *)client->global;
+ struct device *dev = dsp_priv->dev;
+ struct xf_message *m;
+ struct xf_proxy_message msg;
+ unsigned long ret = 0;
+
+ m = xf_cmd_recv(&dsp_priv->proxy, &client->wait, &client->queue, 0);
+ if (IS_ERR(m)) {
+ xf_unlock(&dsp_priv->proxy.lock);
+ dev_err(dev, "receiving failed: %d", (int)PTR_ERR(m));
+ return PTR_ERR(m);
+ }
+
+ /* ...check if there is a response available */
+ if (m == NULL)
+ return -EAGAIN;
+
+ /* ...prepare message parameters (lock is taken) */
+ msg.session_id = XF_MSG_AP_TO_USER(m->id);
+ msg.opcode = m->opcode;
+ msg.length = m->length;
+ msg.address = xf_proxy_b2a(&dsp_priv->proxy, m->buffer);
+ msg.ret = m->ret;
+
+ /* ...return the message back to a pool and release lock */
+ xf_msg_free(&dsp_priv->proxy, m);
+ xf_unlock(&dsp_priv->proxy.lock);
+
+ ret = copy_to_user(user, &msg, sizeof(struct xf_proxy_message));
+ if (ret) {
+ dev_err(dev, "failed to response message to user space\n");
+ return -EFAULT;
+ }
+
+ return 0;
+}
+
+static int fsl_dsp_get_shmem_info(struct xf_client *client,
+ void __user *user)
+{
+ struct fsl_dsp *dsp_priv = (struct fsl_dsp *)client->global;
+ struct device *dev = dsp_priv->dev;
+ struct shmem_info mem_info;
+ unsigned long ret = 0;
+
+ mem_info.phys_addr = dsp_priv->scratch_buf_phys;
+ mem_info.size = dsp_priv->scratch_buf_size;
+
+ ret = copy_to_user(user, &mem_info, sizeof(struct shmem_info));
+ if (ret) {
+ dev_err(dev, "failed to response message to user space\n");
+ return -EFAULT;
+ }
+
+ return ret;
+}
+
+static struct miscdevice dsp_miscdev = {
+ .name = "mxc_hifi4",
+ .minor = MISC_DYNAMIC_MINOR,
+};
+
+static long fsl_dsp_ioctl(struct file *file, unsigned int cmd,
+ unsigned long arg)
+{
+ struct xf_client *client;
+ struct fsl_dsp *dsp_priv;
+ struct xf_proxy *proxy;
+ struct device *dev;
+ void __user *user;
+ long ret = 0;
+
+ /* ...basic sanity checks */
+ client = xf_get_client(file);
+ if (IS_ERR(client))
+ return PTR_ERR(client);
+
+ dsp_priv = (struct fsl_dsp *)client->global;
+ proxy = &dsp_priv->proxy;
+ dev = dsp_priv->dev;
+ user = (void __user *)arg;
+
+ mutex_lock(&dsp_priv->dsp_mutex);
+
+ if (!proxy->is_ready) {
+ mutex_unlock(&dsp_priv->dsp_mutex);
+ dev_err(dev, "dsp firmware is not ready\n");
+ return -EFAULT;
+ }
+
+ switch (cmd) {
+ case DSP_CLIENT_REGISTER:
+ ret = fsl_dsp_client_register(client);
+ break;
+ case DSP_CLIENT_UNREGISTER:
+ ret = fsl_dsp_client_unregister(client);
+ break;
+ case DSP_IPC_MSG_SEND:
+ ret = fsl_dsp_ipc_msg_to_dsp(client, user);
+ break;
+ case DSP_IPC_MSG_RECV:
+ ret = fsl_dsp_ipc_msg_from_dsp(client, user);
+ break;
+ case DSP_GET_SHMEM_INFO:
+ ret = fsl_dsp_get_shmem_info(client, user);
+ break;
+ default:
+ break;
+ }
+
+ mutex_unlock(&dsp_priv->dsp_mutex);
+
+ return ret;
+}
+
+void resource_release(struct fsl_dsp *dsp_priv)
+{
+ int i;
+
+ /* ...initialize client association map */
+ for (i = 0; i < XF_CFG_MAX_IPC_CLIENTS - 1; i++)
+ dsp_priv->xf_client_map[i].next = i + 1;
+ /* ...set list terminator */
+ dsp_priv->xf_client_map[i].next = 0;
+
+ /* ...set pointer to shared memory */
+ xf_proxy_init(&dsp_priv->proxy);
+}
+
+int fsl_dsp_open_func(struct fsl_dsp *dsp_priv, struct xf_client *client)
+{
+ struct device *dev = dsp_priv->dev;
+ int ret = 0;
+
+ /* ...initialize waiting queue */
+ init_waitqueue_head(&client->wait);
+
+ /* ...initialize client pending message queue */
+ xf_msg_queue_init(&client->queue);
+
+ /* ...mark user data is not mapped */
+ client->vm_start = 0;
+
+ /* ...reset mappings counter */
+ atomic_set(&client->vm_use, 0);
+
+ client->global = (void *)dsp_priv;
+ dsp_priv->proxy.is_active = 1;
+
+ pm_runtime_get_sync(dev);
+
+ mutex_lock(&dsp_priv->dsp_mutex);
+ /* increase reference counter when opening device */
+ atomic_long_inc(&dsp_priv->refcnt);
+ mutex_unlock(&dsp_priv->dsp_mutex);
+
+ return ret;
+}
+
+static int fsl_dsp_open(struct inode *inode, struct file *file)
+{
+ struct fsl_dsp *dsp_priv = dev_get_drvdata(dsp_miscdev.parent);
+ struct xf_client *client;
+ int ret = 0;
+
+ /* ...basic sanity checks */
+ if (!inode || !file)
+ return -EINVAL;
+
+ /* ...allocate new proxy client object */
+ client = xf_client_alloc(dsp_priv);
+ if (IS_ERR(client))
+ return PTR_ERR(client);
+
+ fsl_dsp_open_func(dsp_priv, client);
+
+ file->private_data = (void *)client;
+
+ return ret;
+}
+
+int fsl_dsp_close_func(struct xf_client *client)
+{
+ struct fsl_dsp *dsp_priv;
+ struct device *dev;
+ struct xf_proxy *proxy;
+
+ /* ...basic sanity checks */
+ proxy = client->proxy;
+
+ /* release all pending messages */
+ if (proxy)
+ xf_msg_free_all(proxy, &client->queue);
+
+ dsp_priv = (struct fsl_dsp *)client->global;
+ dev = dsp_priv->dev;
+ pm_runtime_put_sync(dev);
+
+ /* ...recycle client id and release memory */
+ xf_client_free(client);
+
+ mutex_lock(&dsp_priv->dsp_mutex);
+ /* decrease reference counter when closing device */
+ atomic_long_dec(&dsp_priv->refcnt);
+ /* If device is free, reinitialize the resource of
+ * dsp driver and framework
+ */
+ if (atomic_long_read(&dsp_priv->refcnt) <= 0) {
+ /* we are closing up, wait for proxy processing
+ * function to finish */
+ cancel_work_sync(&dsp_priv->proxy.work);
+ resource_release(dsp_priv);
+ }
+
+ mutex_unlock(&dsp_priv->dsp_mutex);
+
+ return 0;
+}
+
+static int fsl_dsp_close(struct inode *inode, struct file *file)
+{
+ struct xf_client *client;
+
+ /* ...basic sanity checks */
+ client = xf_get_client(file);
+ if (IS_ERR(client))
+ return PTR_ERR(client);
+
+ fsl_dsp_close_func(client);
+
+ return 0;
+}
+
+/* ...wait until data is available in the response queue */
+static unsigned int fsl_dsp_poll(struct file *file, poll_table *wait)
+{
+ struct xf_proxy *proxy;
+ struct xf_client *client;
+ int mask;
+
+ /* ...basic sanity checks */
+ client = xf_get_client(file);
+ if (IS_ERR(client))
+ return PTR_ERR(client);
+
+ /* ...get proxy interface */
+ proxy = client->proxy;
+ if (!proxy)
+ return -EPERM;
+
+ /* ...register client waiting queue */
+ poll_wait(file, &client->wait, wait);
+
+ /* ...return current queue state */
+ mask = (xf_msg_queue_head(&client->queue) ? POLLIN | POLLRDNORM : 0);
+
+ return mask;
+}
+
+/*******************************************************************************
+ * Low-level mmap interface
+ ******************************************************************************/
+
+/* ...add reference to shared buffer */
+static void dsp_mmap_open(struct vm_area_struct *vma)
+{
+ struct xf_client *client = vma->vm_private_data;
+
+ /* ...probably just increase counter of open references? - tbd */
+ atomic_inc(&client->vm_use);
+
+ pr_debug("xf_mmap_open: vma = %p, client = %p", vma, client);
+}
+
+/* ...close reference to shared buffer */
+static void dsp_mmap_close(struct vm_area_struct *vma)
+{
+ struct xf_client *client = vma->vm_private_data;
+
+ pr_debug("xf_mmap_close: vma = %p, b = %p", vma, client);
+
+ /* ...decrement number of mapping */
+ atomic_dec(&client->vm_use);
+}
+
+/* ...memory map operations */
+static const struct vm_operations_struct dsp_mmap_ops = {
+ .open = dsp_mmap_open,
+ .close = dsp_mmap_close,
+};
+
+/* ...shared memory mapping */
+static int fsl_dsp_mmap(struct file *file, struct vm_area_struct *vma)
+{
+ struct xf_proxy *proxy;
+ struct xf_client *client;
+ unsigned long size;
+ unsigned long pfn;
+ int r;
+ struct fsl_dsp *dsp_priv;
+
+ /* ...basic sanity checks */
+ client = xf_get_client(file);
+ if (IS_ERR(client))
+ return PTR_ERR(client);
+
+ /* ...get proxy interface */
+ proxy = client->proxy;
+ if (!proxy)
+ return -EPERM;
+
+ /* ...check it was not mapped already */
+ if (client->vm_start != 0)
+ return -EBUSY;
+
+ /* ...check mapping flags (tbd) */
+ if ((vma->vm_flags & (VM_READ | VM_WRITE | VM_SHARED))
+ != (VM_READ | VM_WRITE | VM_SHARED))
+ return -EPERM;
+
+ /* ...set memory map operations */
+ vma->vm_ops = &dsp_mmap_ops;
+
+ /* ...assign private data */
+ client->vm_start = vma->vm_start;
+
+ /* ...set private memory data */
+ vma->vm_private_data = client;
+
+ /* ...set page number of shared memory */
+ dsp_priv = (struct fsl_dsp *)client->global;
+ pfn = dsp_priv->scratch_buf_phys >> PAGE_SHIFT;
+ size = dsp_priv->scratch_buf_size;
+
+ /* ...remap shared memory to user-space */
+ vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
+ r = remap_pfn_range(vma, vma->vm_start, pfn, size, vma->vm_page_prot);
+ if (r != 0) {
+ pr_err("mapping failed: %d", r);
+ return r;
+ }
+
+ /* ...system-specific hook for registering shared memory mapping */
+ return 0;
+}
+
+void *memset_dsp(void *dest, int c, size_t count)
+{
+ uint *dl = (uint *)dest;
+ void *dl_1, *dl_2;
+ size_t align = 4;
+ size_t n, n1, n2;
+
+ /* while all data is aligned (common case), copy a word at a time */
+ if ((((ulong)dest) & (sizeof(*dl) - 1)) != 0) {
+ dl = (unsigned int *)(((ulong)dest + align - 1) &
+ (~(align - 1)));
+ dl_1 = dest;
+ dl_2 = (void *)(((ulong)dest + count) & (~(align - 1)));
+ n1 = (ulong)dl - (ulong)dl_1;
+ n2 = (ulong)dest + count - (ulong)dl_2;
+ n = (count - n1 - n2) / align;
+
+ while (n--) {
+ writel_relaxed(0, dl);
+ dl++;
+ }
+ while (n1--) {
+ writeb_relaxed(0, dl_1);
+ dl_1++;
+ }
+ while (n2--) {
+ writeb_relaxed(0, dl_2);
+ dl_2++;
+ }
+ } else {
+ n = count / align;
+ n1 = count - n * align;
+ dl_1 = dest + n * align;
+ while (n--) {
+ writel_relaxed(0, dl);
+ dl++;
+ }
+ while (n1--) {
+ writeb_relaxed(0, dl_1);
+ dl_1++;
+ }
+ }
+
+ return dest;
+}
+
+void *memcpy_dsp(void *dest, const void *src, size_t count)
+{
+ unsigned int *dl = (unsigned int *)dest, *sl = (unsigned int *)src;
+ size_t n = round_up(count, 4) / 4;
+
+ if (src == dest)
+ return dest;
+
+ /* while all data is aligned (common case), copy a word at a time */
+ if ((((ulong)dest | (ulong)src) & (sizeof(*dl) - 1)) != 0)
+ pr_info("dest %p src %p not 4 bytes aligned\n", dest, src);
+
+ while (n--) {
+ writel_relaxed(*sl, dl);
+ dl++;
+ sl++;
+ }
+
+ return dest;
+}
+
+static void dsp_load_firmware(const struct firmware *fw, void *context)
+{
+ struct fsl_dsp *dsp_priv = context;
+ struct device *dev = dsp_priv->dev;
+ Elf32_Ehdr *ehdr; /* Elf header structure pointer */
+ Elf32_Shdr *shdr; /* Section header structure pointer */
+ Elf32_Addr sh_addr;
+ unsigned char *strtab = 0; /* String table pointer */
+ unsigned char *image; /* Binary image pointer */
+ int i; /* Loop counter */
+ unsigned long addr;
+
+ if (!fw) {
+ dev_info(dev, "external firmware not found\n");
+ return;
+ }
+
+ addr = (unsigned long)fw->data;
+ ehdr = (Elf32_Ehdr *)addr;
+
+ /* Find the section header string table for output info */
+ shdr = (Elf32_Shdr *)(addr + ehdr->e_shoff +
+ (ehdr->e_shstrndx * sizeof(Elf32_Shdr)));
+
+ strtab = (unsigned char *)(addr + shdr->sh_offset);
+
+ /* Load each appropriate section */
+ for (i = 0; i < ehdr->e_shnum; ++i) {
+ shdr = (Elf32_Shdr *)(addr + ehdr->e_shoff +
+ (i * sizeof(Elf32_Shdr)));
+
+ if (!(shdr->sh_flags & SHF_ALLOC) ||
+ shdr->sh_addr == 0 || shdr->sh_size == 0)
+ continue;
+
+ dev_dbg(dev, "%sing %s @ 0x%08lx (%ld bytes)\n",
+ (shdr->sh_type == SHT_NOBITS) ? "Clear" : "Load",
+ &strtab[shdr->sh_name], (unsigned long)shdr->sh_addr,
+ (long)shdr->sh_size);
+
+ sh_addr = shdr->sh_addr;
+
+ if (shdr->sh_type == SHT_NOBITS) {
+ memset_dsp((void *)(dsp_priv->sdram_vir_addr +
+ (sh_addr - dsp_priv->sdram_phys_addr)),
+ 0,
+ shdr->sh_size);
+ } else {
+ image = (unsigned char *)addr + shdr->sh_offset;
+ if ((!strcmp(&strtab[shdr->sh_name], ".rodata")) ||
+ (!strcmp(&strtab[shdr->sh_name], ".text")) ||
+ (!strcmp(&strtab[shdr->sh_name], ".data")) ||
+ (!strcmp(&strtab[shdr->sh_name], ".bss"))
+ ) {
+ memcpy_dsp((void *)(dsp_priv->sdram_vir_addr
+ + (sh_addr - dsp_priv->sdram_phys_addr)),
+ (const void *)image,
+ shdr->sh_size);
+ } else {
+ /* sh_addr is from DSP view, we need to
+ * fixup addr because we load the firmware from
+ * the ARM core side
+ */
+ sh_addr -= dsp_priv->fixup_offset;
+
+ memcpy_dsp((void *)(dsp_priv->regs +
+ (sh_addr - dsp_priv->paddr)),
+ (const void *)image,
+ shdr->sh_size);
+ }
+ }
+ }
+
+ /* start the core */
+ sc_pm_cpu_start(dsp_priv->dsp_ipcHandle,
+ SC_R_DSP, true, dsp_priv->iram);
+}
+
+/* Initialization of the MU code. */
+int dsp_mu_init(struct fsl_dsp *dsp_priv)
+{
+ struct device *dev = dsp_priv->dev;
+ struct device_node *np;
+ unsigned int dsp_mu_id;
+ u32 irq;
+ int ret = 0;
+
+ /*
+ * Get the address of MU to be used for communication with the dsp
+ */
+ np = of_find_compatible_node(NULL, NULL, "fsl,imx8-mu-dsp");
+ if (!np) {
+ dev_err(dev, "Cannot find MU entry in device tree\n");
+ return -EINVAL;
+ }
+ dsp_priv->mu_base_virtaddr = of_iomap(np, 0);
+ WARN_ON(!dsp_priv->mu_base_virtaddr);
+
+ ret = of_property_read_u32_index(np,
+ "fsl,dsp_ap_mu_id", 0, &dsp_mu_id);
+ if (ret) {
+ dev_err(dev, "Cannot get mu_id %d\n", ret);
+ return -EINVAL;
+ }
+
+ dsp_priv->dsp_mu_id = dsp_mu_id;
+
+ irq = of_irq_get(np, 0);
+
+ ret = devm_request_irq(dsp_priv->dev, irq, fsl_dsp_mu_isr,
+ IRQF_EARLY_RESUME, "dsp_mu_isr", &dsp_priv->proxy);
+ if (ret) {
+ dev_err(dev, "request_irq failed %d, err = %d\n", irq, ret);
+ return -EINVAL;
+ }
+
+ return ret;
+}
+
+static const struct file_operations dsp_fops = {
+ .owner = THIS_MODULE,
+ .unlocked_ioctl = fsl_dsp_ioctl,
+#ifdef CONFIG_COMPAT
+ .compat_ioctl = fsl_dsp_ioctl,
+#endif
+ .open = fsl_dsp_open,
+ .poll = fsl_dsp_poll,
+ .mmap = fsl_dsp_mmap,
+ .release = fsl_dsp_close,
+};
+
+extern struct snd_compr_ops dsp_platform_compr_ops;
+
+static const struct snd_soc_platform_driver dsp_soc_platform_drv = {
+ .compr_ops = &dsp_platform_compr_ops,
+};
+
+static int fsl_dsp_probe(struct platform_device *pdev)
+{
+ struct device_node *np = pdev->dev.of_node;
+ struct device_node *reserved_node;
+ struct resource reserved_res;
+ struct fsl_dsp *dsp_priv;
+ const char *fw_name;
+ struct resource *res;
+ void __iomem *regs;
+ uint32_t mu_id;
+ sc_err_t sciErr;
+ void *buf_virt;
+ dma_addr_t buf_phys;
+ int size, offset, i;
+ int ret;
+ char tmp[16];
+
+ dsp_priv = devm_kzalloc(&pdev->dev, sizeof(*dsp_priv), GFP_KERNEL);
+ if (!dsp_priv)
+ return -ENOMEM;
+
+ if (of_device_is_compatible(np, "fsl,imx8qxp-dsp"))
+ dsp_priv->dsp_board_type = DSP_IMX8QXP_TYPE;
+ else
+ dsp_priv->dsp_board_type = DSP_IMX8QM_TYPE;
+
+ dsp_priv->dev = &pdev->dev;
+
+ /* Get the addresses and IRQ */
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ regs = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(regs))
+ return PTR_ERR(regs);
+
+ dsp_priv->paddr = res->start;
+ dsp_priv->regs = regs;
+
+ dsp_priv->dram0 = dsp_priv->paddr + DRAM0_OFFSET;
+ dsp_priv->dram1 = dsp_priv->paddr + DRAM1_OFFSET;
+ dsp_priv->iram = dsp_priv->paddr + IRAM_OFFSET;
+ dsp_priv->sram = dsp_priv->paddr + SYSRAM_OFFSET;
+
+ sciErr = sc_ipc_getMuID(&mu_id);
+ if (sciErr != SC_ERR_NONE) {
+ dev_err(&pdev->dev, "Cannot obtain MU ID\n");
+ return sciErr;
+ }
+
+ sciErr = sc_ipc_open(&dsp_priv->dsp_ipcHandle, mu_id);
+ if (sciErr != SC_ERR_NONE) {
+ dev_err(&pdev->dev, "Cannot open MU channel to SCU %d, %d\n",
+ mu_id, sciErr);
+ return sciErr;
+ };
+
+ if (dsp_priv->dsp_board_type == DSP_IMX8QXP_TYPE) {
+ sciErr = sc_misc_set_control(dsp_priv->dsp_ipcHandle, SC_R_DSP,
+ SC_C_OFS_SEL, 1);
+ if (sciErr != SC_ERR_NONE) {
+ dev_err(&pdev->dev, "Error system address offset source select\n");
+ return -EIO;
+ }
+
+ sciErr = sc_misc_set_control(dsp_priv->dsp_ipcHandle, SC_R_DSP,
+ SC_C_OFS_PERIPH, 0x5A);
+ if (sciErr != SC_ERR_NONE) {
+ dev_err(&pdev->dev, "Error system address offset of PERIPH %d\n",
+ sciErr);
+ return -EIO;
+ }
+
+ sciErr = sc_misc_set_control(dsp_priv->dsp_ipcHandle, SC_R_DSP,
+ SC_C_OFS_IRQ, 0x51);
+ if (sciErr != SC_ERR_NONE) {
+ dev_err(&pdev->dev, "Error system address offset of IRQ\n");
+ return -EIO;
+ }
+
+ sciErr = sc_misc_set_control(dsp_priv->dsp_ipcHandle, SC_R_DSP,
+ SC_C_OFS_AUDIO, 0x80);
+ if (sciErr != SC_ERR_NONE) {
+ dev_err(&pdev->dev, "Error system address offset of AUDIO\n");
+ return -EIO;
+ }
+ } else {
+ sciErr = sc_misc_set_control(dsp_priv->dsp_ipcHandle, SC_R_DSP,
+ SC_C_OFS_SEL, 0);
+ if (sciErr != SC_ERR_NONE) {
+ dev_err(&pdev->dev, "Error system address offset source select\n");
+ return -EIO;
+ }
+ }
+
+ ret = dsp_mu_init(dsp_priv);
+ if (ret)
+ return ret;
+
+ ret = of_property_read_string(np, "fsl,dsp-firmware", &fw_name);
+ dsp_priv->fw_name = fw_name;
+
+ ret = of_property_read_u32(np, "fixup-offset", &dsp_priv->fixup_offset);
+
+ platform_set_drvdata(pdev, dsp_priv);
+ pm_runtime_enable(&pdev->dev);
+
+ dsp_miscdev.fops = &dsp_fops,
+ dsp_miscdev.parent = &pdev->dev,
+ ret = misc_register(&dsp_miscdev);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to register misc device %d\n", ret);
+ return ret;
+ }
+
+ reserved_node = of_parse_phandle(np, "reserved-region", 0);
+ if (!reserved_node) {
+ dev_err(&pdev->dev, "failed to get reserved region node\n");
+ return -ENODEV;
+ }
+
+ if (of_address_to_resource(reserved_node, 0, &reserved_res)) {
+ dev_err(&pdev->dev, "failed to get reserved region address\n");
+ return -EINVAL;
+ }
+
+ dsp_priv->sdram_phys_addr = reserved_res.start;
+ dsp_priv->sdram_reserved_size = (reserved_res.end - reserved_res.start)
+ + 1;
+ if (dsp_priv->sdram_reserved_size <= 0) {
+ dev_err(&pdev->dev, "invalid value of reserved region size\n");
+ return -EINVAL;
+ }
+
+ dsp_priv->sdram_vir_addr = ioremap_wc(dsp_priv->sdram_phys_addr,
+ dsp_priv->sdram_reserved_size);
+ if (!dsp_priv->sdram_vir_addr) {
+ dev_err(&pdev->dev, "failed to remap sdram space for dsp firmware\n");
+ return -ENXIO;
+ }
+ memset_io(dsp_priv->sdram_vir_addr, 0, dsp_priv->sdram_reserved_size);
+
+ size = MSG_BUF_SIZE + DSP_CONFIG_SIZE;
+
+ buf_virt = dma_alloc_coherent(&pdev->dev, size, &buf_phys, GFP_KERNEL);
+ if (!buf_virt) {
+ dev_err(&pdev->dev, "failed alloc memory.\n");
+ return -ENOMEM;
+ }
+
+ /* msg ring buffer memory */
+ dsp_priv->msg_buf_virt = buf_virt;
+ dsp_priv->msg_buf_phys = buf_phys;
+ dsp_priv->msg_buf_size = MSG_BUF_SIZE;
+ offset = MSG_BUF_SIZE;
+
+ /* keep dsp framework's global data when suspend/resume */
+ dsp_priv->dsp_config_virt = buf_virt + offset;
+ dsp_priv->dsp_config_phys = buf_phys + offset;
+ dsp_priv->dsp_config_size = DSP_CONFIG_SIZE;
+
+ /* scratch memory for dsp framework. The sdram reserved memory
+ * is split into two equal parts currently. The front part is
+ * used to keep the dsp firmware, the other part is considered
+ * as scratch memory for dsp framework.
+ */
+ dsp_priv->scratch_buf_virt = dsp_priv->sdram_vir_addr +
+ dsp_priv->sdram_reserved_size / 2;
+ dsp_priv->scratch_buf_phys = dsp_priv->sdram_phys_addr +
+ dsp_priv->sdram_reserved_size / 2;
+ dsp_priv->scratch_buf_size = dsp_priv->sdram_reserved_size / 2;
+
+ /* initialize the reference counter for dsp_priv
+ * structure
+ */
+ atomic_long_set(&dsp_priv->refcnt, 0);
+
+ /* ...initialize client association map */
+ for (i = 0; i < XF_CFG_MAX_IPC_CLIENTS - 1; i++)
+ dsp_priv->xf_client_map[i].next = i + 1;
+ /* ...set list terminator */
+ dsp_priv->xf_client_map[i].next = 0;
+
+ /* ...set pointer to shared memory */
+ xf_proxy_init(&dsp_priv->proxy);
+
+ /* ...initialize mutex */
+ mutex_init(&dsp_priv->dsp_mutex);
+
+ ret = devm_snd_soc_register_platform(&pdev->dev, &dsp_soc_platform_drv);
+ if (ret) {
+ dev_err(&pdev->dev, "registering soc platform failed\n");
+ return ret;
+ }
+
+ dsp_priv->esai_ipg_clk = devm_clk_get(&pdev->dev, "esai_ipg");
+ if (IS_ERR(dsp_priv->esai_ipg_clk))
+ dsp_priv->esai_ipg_clk = NULL;
+
+ dsp_priv->esai_mclk = devm_clk_get(&pdev->dev, "esai_mclk");
+ if (IS_ERR(dsp_priv->esai_mclk))
+ dsp_priv->esai_mclk = NULL;
+
+ dsp_priv->asrc_mem_clk = devm_clk_get(&pdev->dev, "asrc_mem");
+ if (IS_ERR(dsp_priv->asrc_mem_clk))
+ dsp_priv->asrc_mem_clk = NULL;
+
+ dsp_priv->asrc_ipg_clk = devm_clk_get(&pdev->dev, "asrc_ipg");
+ if (IS_ERR(dsp_priv->asrc_ipg_clk))
+ dsp_priv->asrc_ipg_clk = NULL;
+
+ for (i = 0; i < 4; i++) {
+ sprintf(tmp, "asrck_%x", i);
+ dsp_priv->asrck_clk[i] = devm_clk_get(&pdev->dev, tmp);
+ if (IS_ERR(dsp_priv->asrck_clk[i]))
+ dsp_priv->asrck_clk[i] = NULL;
+ }
+
+ return 0;
+}
+
+static int fsl_dsp_remove(struct platform_device *pdev)
+{
+ struct fsl_dsp *dsp_priv = platform_get_drvdata(pdev);
+ int size;
+
+ misc_deregister(&dsp_miscdev);
+
+ size = MSG_BUF_SIZE + DSP_CONFIG_SIZE;
+ dma_free_coherent(&pdev->dev, size, dsp_priv->msg_buf_virt,
+ dsp_priv->msg_buf_phys);
+ if (dsp_priv->sdram_vir_addr)
+ iounmap(dsp_priv->sdram_vir_addr);
+
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int fsl_dsp_runtime_resume(struct device *dev)
+{
+ struct fsl_dsp *dsp_priv = dev_get_drvdata(dev);
+ struct xf_proxy *proxy = &dsp_priv->proxy;
+ int ret;
+ int i;
+
+ ret = clk_prepare_enable(dsp_priv->esai_ipg_clk);
+ if (ret) {
+ dev_err(dev, "failed to enable esai ipg clock: %d\n", ret);
+ return ret;
+ }
+
+ ret = clk_prepare_enable(dsp_priv->esai_mclk);
+ if (ret) {
+ dev_err(dev, "failed to enable esai mclk: %d\n", ret);
+ return ret;
+ }
+
+ ret = clk_prepare_enable(dsp_priv->asrc_mem_clk);
+ if (ret < 0)
+ dev_err(dev, "Failed to enable asrc_mem_clk ret = %d\n", ret);
+
+ ret = clk_prepare_enable(dsp_priv->asrc_ipg_clk);
+ if (ret < 0)
+ dev_err(dev, "Failed to enable asrc_ipg_clk ret = %d\n", ret);
+
+ for (i = 0; i < 4; i++) {
+ ret = clk_prepare_enable(dsp_priv->asrck_clk[i]);
+ if (ret < 0)
+ dev_err(dev, "failed to prepare arc clk %d\n", i);
+ }
+
+ if (!dsp_priv->dsp_mu_init) {
+ MU_Init(dsp_priv->mu_base_virtaddr);
+ MU_EnableRxFullInt(dsp_priv->mu_base_virtaddr, 0);
+ dsp_priv->dsp_mu_init = 1;
+ }
+
+ if (!proxy->is_ready) {
+ init_completion(&proxy->cmd_complete);
+
+ ret = request_firmware_nowait(THIS_MODULE,
+ FW_ACTION_HOTPLUG, dsp_priv->fw_name,
+ dev,
+ GFP_KERNEL, dsp_priv, dsp_load_firmware);
+
+ if (ret) {
+ dev_err(dev, "failed to load firmware\n");
+ return ret;
+ }
+
+ ret = icm_ack_wait(proxy, 0);
+ if (ret)
+ return ret;
+
+ dev_info(dev, "dsp driver registered\n");
+ }
+
+ return 0;
+}
+
+static int fsl_dsp_runtime_suspend(struct device *dev)
+{
+ struct fsl_dsp *dsp_priv = dev_get_drvdata(dev);
+ struct xf_proxy *proxy = &dsp_priv->proxy;
+ int i;
+
+ dsp_priv->dsp_mu_init = 0;
+ proxy->is_ready = 0;
+
+ for (i = 0; i < 4; i++)
+ clk_disable_unprepare(dsp_priv->asrck_clk[i]);
+
+ clk_disable_unprepare(dsp_priv->asrc_ipg_clk);
+ clk_disable_unprepare(dsp_priv->asrc_mem_clk);
+
+ clk_disable_unprepare(dsp_priv->esai_mclk);
+ clk_disable_unprepare(dsp_priv->esai_ipg_clk);
+
+ return 0;
+}
+#endif /* CONFIG_PM */
+
+
+#ifdef CONFIG_PM_SLEEP
+static int fsl_dsp_suspend(struct device *dev)
+{
+ struct fsl_dsp *dsp_priv = dev_get_drvdata(dev);
+ struct xf_proxy *proxy = &dsp_priv->proxy;
+ int ret = 0;
+
+ if (proxy->is_ready) {
+ ret = xf_cmd_send_suspend(proxy);
+ if (ret) {
+ dev_err(dev, "dsp suspend fail\n");
+ return ret;
+ }
+ }
+
+ ret = pm_runtime_force_suspend(dev);
+
+ return ret;
+}
+
+static int fsl_dsp_resume(struct device *dev)
+{
+ struct fsl_dsp *dsp_priv = dev_get_drvdata(dev);
+ struct xf_proxy *proxy = &dsp_priv->proxy;
+ int ret = 0;
+
+ ret = pm_runtime_force_resume(dev);
+ if (ret)
+ return ret;
+
+ if (proxy->is_ready) {
+ ret = xf_cmd_send_resume(proxy);
+ if (ret) {
+ dev_err(dev, "dsp resume fail\n");
+ return ret;
+ }
+ }
+
+ return 0;
+}
+#endif /* CONFIG_PM_SLEEP */
+
+static const struct dev_pm_ops fsl_dsp_pm = {
+ SET_RUNTIME_PM_OPS(fsl_dsp_runtime_suspend,
+ fsl_dsp_runtime_resume, NULL)
+ SET_SYSTEM_SLEEP_PM_OPS(fsl_dsp_suspend, fsl_dsp_resume)
+};
+
+static const struct of_device_id fsl_dsp_ids[] = {
+ { .compatible = "fsl,imx8qxp-dsp", },
+ { .compatible = "fsl,imx8qm-dsp", },
+ {}
+};
+MODULE_DEVICE_TABLE(of, fsl_dsp_ids);
+
+static struct platform_driver fsl_dsp_driver = {
+ .probe = fsl_dsp_probe,
+ .remove = fsl_dsp_remove,
+ .driver = {
+ .name = "fsl-dsp",
+ .of_match_table = fsl_dsp_ids,
+ .pm = &fsl_dsp_pm,
+ },
+};
+module_platform_driver(fsl_dsp_driver);
+
+MODULE_DESCRIPTION("Freescale DSP driver");
+MODULE_ALIAS("platform:fsl-dsp");
+MODULE_LICENSE("Dual BSD/GPL");
diff --git a/sound/soc/fsl/fsl_dsp.h b/sound/soc/fsl/fsl_dsp.h
new file mode 100644
index 000000000000..fb01a4985c48
--- /dev/null
+++ b/sound/soc/fsl/fsl_dsp.h
@@ -0,0 +1,141 @@
+/* SPDX-License-Identifier: (GPL-2.0+ OR MIT)*/
+/*
+ * Copyright (C) 2017 Cadence Design Systems, Inc.
+ * Copyright 2018 NXP
+ *
+ */
+
+#ifndef FSL_DSP_H
+#define FSL_DSP_H
+#include <uapi/linux/mxc_dsp.h>
+#include <soc/imx8/sc/ipc.h>
+#include "fsl_dsp_proxy.h"
+#include "fsl_dsp_platform.h"
+
+typedef void (*memcpy_func) (void *dest, const void *src, size_t n);
+typedef void (*memset_func) (void *s, int c, size_t n);
+
+/* ...maximal number of IPC clients per proxy */
+#define XF_CFG_MAX_IPC_CLIENTS (1 << 4)
+
+enum {
+ DSP_IMX8QXP_TYPE = 0,
+ DSP_IMX8QM_TYPE,
+};
+
+/* ...proxy client data */
+struct xf_client {
+ /* ...pointer to proxy interface */
+ struct xf_proxy *proxy;
+
+ /* ...allocated proxy client id */
+ u32 id;
+
+ /* ...pending response queue */
+ struct xf_msg_queue queue;
+ /* ...response waiting queue */
+ wait_queue_head_t wait;
+
+ /* ...virtual memory mapping */
+ unsigned long vm_start;
+ /* ...counter of memory mappings (no real use of it yet - tbd) */
+ atomic_t vm_use;
+
+ /* ...global structure pointer */
+ void *global;
+ struct xf_message m;
+
+ struct snd_compr_stream *cstream;
+
+ struct work_struct work;
+ struct completion compr_complete;
+
+ int input_bytes;
+ int consume_bytes;
+};
+
+union xf_client_link {
+ /* ...index of next client in free list */
+ u32 next;
+
+ /* ...reference to proxy data for allocated client */
+ struct xf_client *client;
+};
+
+struct fsl_dsp {
+ struct device *dev;
+ const char *fw_name;
+ void __iomem *regs;
+ void __iomem *mu_base_virtaddr;
+ sc_ipc_t dsp_ipcHandle;
+ sc_ipc_t mu_ipcHandle;
+ unsigned int dsp_mu_id;
+ int dsp_mu_init;
+ atomic_long_t refcnt;
+ unsigned long paddr;
+ unsigned long dram0;
+ unsigned long dram1;
+ unsigned long iram;
+ unsigned long sram;
+ void *sdram_vir_addr;
+ unsigned long sdram_phys_addr;
+ int sdram_reserved_size;
+ void *msg_buf_virt;
+ dma_addr_t msg_buf_phys;
+ int msg_buf_size;
+ void *scratch_buf_virt;
+ dma_addr_t scratch_buf_phys;
+ int scratch_buf_size;
+ void *dsp_config_virt;
+ dma_addr_t dsp_config_phys;
+ int dsp_config_size;
+ int dsp_board_type;
+ unsigned int fixup_offset;
+
+ /* ...proxy data structures */
+ struct xf_proxy proxy;
+
+ /* ...mutex lock */
+ struct mutex dsp_mutex;
+
+ struct dsp_data dsp_data;
+
+ /* ...global clients pool (item[0] serves as list terminator) */
+ union xf_client_link xf_client_map[XF_CFG_MAX_IPC_CLIENTS];
+
+ struct clk *esai_ipg_clk;
+ struct clk *esai_mclk;
+ struct clk *asrc_mem_clk;
+ struct clk *asrc_ipg_clk;
+ struct clk *asrck_clk[4];
+};
+
+#define IRAM_OFFSET 0x10000
+#define IRAM_SIZE 2048
+
+#define DRAM0_OFFSET 0x0
+#define DRAM0_SIZE 0x8000
+
+#define DRAM1_OFFSET 0x8000
+#define DRAM1_SIZE 0x8000
+
+#define SYSRAM_OFFSET 0x18000
+#define SYSRAM_SIZE 0x40000
+
+#define SYSROM_OFFSET 0x58000
+#define SYSROM_SIZE 0x30000
+
+#define MSG_BUF_SIZE 8192
+#define INPUT_BUF_SIZE 4096
+#define OUTPUT_BUF_SIZE 16384
+#define DSP_CONFIG_SIZE 4096
+
+void *memcpy_dsp(void *dest, const void *src, size_t count);
+void *memset_dsp(void *dest, int c, size_t count);
+struct xf_client *xf_client_lookup(struct fsl_dsp *dsp_priv, u32 id);
+struct xf_client *xf_client_alloc(struct fsl_dsp *dsp_priv);
+
+int fsl_dsp_open_func(struct fsl_dsp *dsp_priv, struct xf_client *client);
+int fsl_dsp_close_func(struct xf_client *client);
+
+#endif
diff --git a/sound/soc/fsl/fsl_dsp_cpu.c b/sound/soc/fsl/fsl_dsp_cpu.c
new file mode 100644
index 000000000000..e97d09ae0c45
--- /dev/null
+++ b/sound/soc/fsl/fsl_dsp_cpu.c
@@ -0,0 +1,97 @@
+// SPDX-License-Identifier: GPL-2.0+
+//
+// DSP Audio platform driver
+//
+// Copyright 2018 NXP
+
+#include <linux/clk.h>
+#include <linux/module.h>
+#include <linux/pm_runtime.h>
+#include <sound/soc.h>
+#include <sound/core.h>
+#include <sound/compress_driver.h>
+
+#include "fsl_dsp_cpu.h"
+
+static int dsp_audio_startup(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *cpu_dai) {
+ return 0;
+}
+
+
+static void dsp_audio_shutdown(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *cpu_dai) {
+}
+
+static const struct snd_soc_dai_ops dsp_audio_dai_ops = {
+ .startup = dsp_audio_startup,
+ .shutdown = dsp_audio_shutdown,
+};
+
+static struct snd_soc_dai_driver dsp_audio_dai = {
+ .name = "dsp-audio-cpu-dai",
+ .compress_new = snd_soc_new_compress,
+ .ops = &dsp_audio_dai_ops,
+ .playback = {
+ .stream_name = "Compress Playback",
+ .channels_min = 1,
+ },
+};
+
+static const struct snd_soc_component_driver audio_dsp_component = {
+ .name = "audio-dsp",
+};
+
+static int dsp_audio_probe(struct platform_device *pdev)
+{
+ struct fsl_dsp_audio *dsp_audio;
+ int ret;
+
+ dsp_audio = devm_kzalloc(&pdev->dev, sizeof(*dsp_audio), GFP_KERNEL);
+ if (dsp_audio == NULL)
+ return -ENOMEM;
+
+ dev_dbg(&pdev->dev, "probing DSP device....\n");
+
+ /* intialise sof device */
+ dev_set_drvdata(&pdev->dev, dsp_audio);
+
+ pm_runtime_enable(&pdev->dev);
+
+ /* now register audio DSP platform driver */
+ ret = snd_soc_register_component(&pdev->dev, &audio_dsp_component,
+ &dsp_audio_dai, 1);
+ if (ret < 0) {
+ dev_err(&pdev->dev,
+ "error: failed to register DSP DAI driver %d\n", ret);
+ goto err;
+ }
+
+ return 0;
+
+err:
+ return ret;
+}
+
+static int dsp_audio_remove(struct platform_device *pdev)
+{
+ snd_soc_unregister_component(&pdev->dev);
+ return 0;
+}
+
+
+static const struct of_device_id dsp_audio_ids[] = {
+ { .compatible = "fsl,dsp-audio"},
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, dsp_audio_ids);
+
+static struct platform_driver dsp_audio_driver = {
+ .driver = {
+ .name = "dsp-audio",
+ .of_match_table = dsp_audio_ids,
+ },
+ .probe = dsp_audio_probe,
+ .remove = dsp_audio_remove,
+};
+module_platform_driver(dsp_audio_driver);
diff --git a/sound/soc/fsl/fsl_dsp_cpu.h b/sound/soc/fsl/fsl_dsp_cpu.h
new file mode 100644
index 000000000000..dac10b4ab9d0
--- /dev/null
+++ b/sound/soc/fsl/fsl_dsp_cpu.h
@@ -0,0 +1,16 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * DSP Audio DAI header
+ *
+ * Copyright 2018 NXP
+ */
+
+#ifndef __FSL_DSP_CPU_H
+#define __FSL_DSP_CPU_H
+
+struct fsl_dsp_audio {
+ struct platform_device *pdev;
+};
+
+#endif /*__FSL_DSP_CPU_H*/
+
diff --git a/sound/soc/fsl/fsl_dsp_library_load.c b/sound/soc/fsl/fsl_dsp_library_load.c
new file mode 100644
index 000000000000..d273f7296e29
--- /dev/null
+++ b/sound/soc/fsl/fsl_dsp_library_load.c
@@ -0,0 +1,642 @@
+// SPDX-License-Identifier: GPL-2.0+
+// Copyright 2018 NXP
+// Copyright (c) 2012-2013 by Tensilica Inc.
+
+#include <linux/fs.h>
+#include <linux/slab.h>
+#include <linux/elf.h>
+
+#include "fsl_dsp.h"
+#include "fsl_dsp_library_load.h"
+
+static Elf32_Half xtlib_host_half(Elf32_Half v, int byteswap)
+{
+ return (byteswap) ? (v >> 8) | (v << 8) : v;
+}
+
+static Elf32_Word xtlib_host_word(Elf32_Word v, int byteswap)
+{
+ if (byteswap) {
+ v = ((v & 0x00FF00FF) << 8) | ((v & 0xFF00FF00) >> 8);
+ v = (v >> 16) | (v << 16);
+ }
+ return v;
+}
+
+static int xtlib_verify_magic(Elf32_Ehdr *header,
+ struct lib_info *lib_info)
+{
+ struct xtlib_loader_globals *xtlib_globals =
+ &lib_info->xtlib_globals;
+ Elf32_Byte magic_no;
+
+ magic_no = header->e_ident[EI_MAG0];
+ if (magic_no != 0x7f)
+ return -1;
+
+ magic_no = header->e_ident[EI_MAG1];
+ if (magic_no != 'E')
+ return -1;
+
+ magic_no = header->e_ident[EI_MAG2];
+ if (magic_no != 'L')
+ return -1;
+
+ magic_no = header->e_ident[EI_MAG3];
+ if (magic_no != 'F')
+ return -1;
+
+ if (header->e_ident[EI_CLASS] != ELFCLASS32)
+ return -1;
+
+ {
+ /* determine byte order */
+ union {
+ short s;
+ char c[sizeof(short)];
+ } u;
+
+ u.s = 1;
+
+ if (header->e_ident[EI_DATA] == ELFDATA2LSB)
+ xtlib_globals->byteswap = u.c[sizeof(short) - 1] == 1;
+ else if (header->e_ident[EI_DATA] == ELFDATA2MSB)
+ xtlib_globals->byteswap = u.c[0] == 1;
+ else
+ return -1;
+ }
+
+ return 0;
+}
+
+static void xtlib_load_seg(Elf32_Phdr *pheader, void *src_addr, xt_ptr dst_addr,
+ struct lib_info *lib_info)
+{
+ struct xtlib_loader_globals *xtlib_globals =
+ &lib_info->xtlib_globals;
+ Elf32_Word bytes_to_copy = xtlib_host_word(pheader->p_filesz,
+ xtlib_globals->byteswap);
+ Elf32_Word bytes_to_zero = xtlib_host_word(pheader->p_memsz,
+ xtlib_globals->byteswap)
+ - bytes_to_copy;
+ unsigned int i;
+ char *src_back, *dst_back;
+
+ void *zero_addr = (void *)dst_addr + bytes_to_copy;
+
+ if (bytes_to_copy > 0) {
+ // memcpy((void *)(dst_addr), src_addr, bytes_to_copy);
+ src_back = (char *)src_addr;
+ dst_back = (char *)dst_addr;
+ for (i = 0; i < bytes_to_copy; i++)
+ *dst_back++ = *src_back++;
+ }
+
+ if (bytes_to_zero > 0) {
+ // memset(zero_addr, 0, bytes_to_zero);
+ dst_back = (char *)zero_addr;
+ for (i = 0; i < bytes_to_zero; i++)
+ *dst_back++ = 0;
+ }
+}
+
+#define xtlib_xt_half xtlib_host_half
+#define xtlib_xt_word xtlib_host_word
+
+static xt_ptr align_ptr(xt_ptr ptr, xt_uint align)
+{
+ return (xt_ptr)(((xt_uint)ptr + align - 1) & ~(align - 1));
+}
+
+static xt_ptr xt_ptr_offs(xt_ptr base, Elf32_Word offs,
+ struct lib_info *lib_info)
+{
+ struct xtlib_loader_globals *xtlib_globals =
+ &lib_info->xtlib_globals;
+
+ return (xt_ptr)xtlib_xt_word((xt_uint)base +
+ xtlib_host_word(offs, xtlib_globals->byteswap),
+ xtlib_globals->byteswap);
+}
+
+static Elf32_Dyn *find_dynamic_info(Elf32_Ehdr *eheader,
+ struct lib_info *lib_info)
+{
+ char *base_addr = (char *)eheader;
+ struct xtlib_loader_globals *xtlib_globals =
+ &lib_info->xtlib_globals;
+ Elf32_Phdr *pheader = (Elf32_Phdr *)(base_addr +
+ xtlib_host_word(eheader->e_phoff,
+ xtlib_globals->byteswap));
+
+ int seg = 0;
+ int num = xtlib_host_half(eheader->e_phnum, xtlib_globals->byteswap);
+
+ while (seg < num) {
+ if (xtlib_host_word(pheader[seg].p_type,
+ xtlib_globals->byteswap) == PT_DYNAMIC) {
+ return (Elf32_Dyn *)(base_addr +
+ xtlib_host_word(pheader[seg].p_offset,
+ xtlib_globals->byteswap));
+ }
+ seg++;
+ }
+ return 0;
+}
+
+static int find_align(Elf32_Ehdr *header,
+ struct lib_info *lib_info)
+{
+ struct xtlib_loader_globals *xtlib_globals =
+ &lib_info->xtlib_globals;
+ Elf32_Shdr *sheader = (Elf32_Shdr *) (((char *)header) +
+ xtlib_host_word(header->e_shoff, xtlib_globals->byteswap));
+
+ int sec = 0;
+ int num = xtlib_host_half(header->e_shnum, xtlib_globals->byteswap);
+
+ int align = 0;
+
+ while (sec < num) {
+ if (sheader[sec].sh_type != SHT_NULL &&
+ xtlib_host_word(sheader[sec].sh_size,
+ xtlib_globals->byteswap) > 0) {
+ int sec_align =
+ xtlib_host_word(sheader[sec].sh_addralign,
+ xtlib_globals->byteswap);
+ if (sec_align > align)
+ align = sec_align;
+ }
+ sec++;
+ }
+
+ return align;
+}
+
+static int validate_dynamic(Elf32_Ehdr *header,
+ struct lib_info *lib_info)
+{
+ struct xtlib_loader_globals *xtlib_globals =
+ &lib_info->xtlib_globals;
+
+ if (xtlib_verify_magic(header, lib_info) != 0)
+ return XTLIB_NOT_ELF;
+
+ if (xtlib_host_half(header->e_type,
+ xtlib_globals->byteswap) != ET_DYN)
+ return XTLIB_NOT_DYNAMIC;
+
+ return XTLIB_NO_ERR;
+}
+
+static int validate_dynamic_splitload(Elf32_Ehdr *header,
+ struct lib_info *lib_info)
+{
+ struct xtlib_loader_globals *xtlib_globals =
+ &lib_info->xtlib_globals;
+ Elf32_Phdr *pheader;
+ int err = validate_dynamic(header, lib_info);
+
+ if (err != XTLIB_NO_ERR)
+ return err;
+
+ /* make sure it's split load pi library, expecting three headers,
+ * code, data and dynamic, for example:
+ *
+ *LOAD off 0x00000094 vaddr 0x00000000 paddr 0x00000000 align 2**0
+ * filesz 0x00000081 memsz 0x00000081 flags r-x
+ *LOAD off 0x00000124 vaddr 0x00000084 paddr 0x00000084 align 2**0
+ * filesz 0x000001ab memsz 0x000011bc flags rwx
+ *DYNAMIC off 0x00000124 vaddr 0x00000084 paddr 0x00000084 align 2**2
+ * filesz 0x000000a0 memsz 0x000000a0 flags rw-
+ */
+
+ if (xtlib_host_half(header->e_phnum, xtlib_globals->byteswap) != 3)
+ return XTLIB_NOT_SPLITLOAD;
+
+ pheader = (Elf32_Phdr *)((char *)header +
+ xtlib_host_word(header->e_phoff, xtlib_globals->byteswap));
+
+ /* LOAD R-X */
+ if (xtlib_host_word(pheader[0].p_type,
+ xtlib_globals->byteswap) != PT_LOAD ||
+ (xtlib_host_word(pheader[0].p_flags,
+ xtlib_globals->byteswap)
+ & (PF_R | PF_W | PF_X)) != (PF_R | PF_X))
+ return XTLIB_NOT_SPLITLOAD;
+
+ /* LOAD RWX */
+ if (xtlib_host_word(pheader[1].p_type,
+ xtlib_globals->byteswap) != PT_LOAD ||
+ (xtlib_host_word(pheader[1].p_flags,
+ xtlib_globals->byteswap)
+ & (PF_R | PF_W | PF_X)) != (PF_R | PF_W | PF_X))
+ return XTLIB_NOT_SPLITLOAD;
+
+ /* DYNAMIC RW- */
+ if (xtlib_host_word(pheader[2].p_type,
+ xtlib_globals->byteswap) != PT_DYNAMIC ||
+ (xtlib_host_word(pheader[2].p_flags,
+ xtlib_globals->byteswap)
+ & (PF_R | PF_W | PF_X)) != (PF_R | PF_W))
+ return XTLIB_NOT_SPLITLOAD;
+
+ return XTLIB_NO_ERR;
+}
+
+static unsigned int
+xtlib_split_pi_library_size(struct xtlib_packaged_library *library,
+ unsigned int *code_size,
+ unsigned int *data_size,
+ struct lib_info *lib_info)
+{
+ struct xtlib_loader_globals *xtlib_globals =
+ &lib_info->xtlib_globals;
+ Elf32_Phdr *pheader;
+ Elf32_Ehdr *header = (Elf32_Ehdr *)library;
+ int align;
+ int err = validate_dynamic_splitload(header, lib_info);
+
+ if (err != XTLIB_NO_ERR) {
+ xtlib_globals->err = err;
+ return err;
+ }
+
+ align = find_align(header, lib_info);
+
+ pheader = (Elf32_Phdr *)((char *)library +
+ xtlib_host_word(header->e_phoff, xtlib_globals->byteswap));
+
+ *code_size = xtlib_host_word(pheader[0].p_memsz,
+ xtlib_globals->byteswap) + align;
+ *data_size = xtlib_host_word(pheader[1].p_memsz,
+ xtlib_globals->byteswap) + align;
+
+ return XTLIB_NO_ERR;
+}
+
+static int get_dyn_info(Elf32_Ehdr *eheader,
+ xt_ptr dst_addr, xt_uint src_offs,
+ xt_ptr dst_data_addr, xt_uint src_data_offs,
+ struct xtlib_pil_info *info,
+ struct lib_info *lib_info)
+{
+ unsigned int jmprel = 0;
+ unsigned int pltrelsz = 0;
+ struct xtlib_loader_globals *xtlib_globals =
+ &lib_info->xtlib_globals;
+ Elf32_Dyn *dyn_entry = find_dynamic_info(eheader, lib_info);
+
+ if (dyn_entry == 0)
+ return XTLIB_NO_DYNAMIC_SEGMENT;
+
+ info->dst_addr = (xt_uint)xtlib_xt_word((Elf32_Word)dst_addr,
+ xtlib_globals->byteswap);
+ info->src_offs = xtlib_xt_word(src_offs, xtlib_globals->byteswap);
+ info->dst_data_addr = (xt_uint)xtlib_xt_word(
+ (Elf32_Word)dst_data_addr + src_data_offs,
+ xtlib_globals->byteswap);
+ info->src_data_offs = xtlib_xt_word(src_data_offs,
+ xtlib_globals->byteswap);
+
+ dst_addr -= src_offs;
+ dst_data_addr = dst_data_addr + src_data_offs - src_data_offs;
+
+ info->start_sym = xt_ptr_offs(dst_addr, eheader->e_entry, lib_info);
+
+ info->align = xtlib_xt_word(find_align(eheader, lib_info),
+ xtlib_globals->byteswap);
+
+ info->text_addr = 0;
+
+ while (dyn_entry->d_tag != DT_NULL) {
+ switch ((Elf32_Sword) xtlib_host_word(
+ (Elf32_Word)dyn_entry->d_tag,
+ xtlib_globals->byteswap)) {
+ case DT_RELA:
+ info->rel = xt_ptr_offs(dst_data_addr,
+ dyn_entry->d_un.d_ptr, lib_info);
+ break;
+ case DT_RELASZ:
+ info->rela_count = xtlib_xt_word(
+ xtlib_host_word(dyn_entry->d_un.d_val,
+ xtlib_globals->byteswap) /
+ sizeof(Elf32_Rela),
+ xtlib_globals->byteswap);
+ break;
+ case DT_INIT:
+ info->init = xt_ptr_offs(dst_addr,
+ dyn_entry->d_un.d_ptr, lib_info);
+ break;
+ case DT_FINI:
+ info->fini = xt_ptr_offs(dst_addr,
+ dyn_entry->d_un.d_ptr, lib_info);
+ break;
+ case DT_HASH:
+ info->hash = xt_ptr_offs(dst_data_addr,
+ dyn_entry->d_un.d_ptr, lib_info);
+ break;
+ case DT_SYMTAB:
+ info->symtab = xt_ptr_offs(dst_data_addr,
+ dyn_entry->d_un.d_ptr, lib_info);
+ break;
+ case DT_STRTAB:
+ info->strtab = xt_ptr_offs(dst_data_addr,
+ dyn_entry->d_un.d_ptr, lib_info);
+ break;
+ case DT_JMPREL:
+ jmprel = dyn_entry->d_un.d_val;
+ break;
+ case DT_PLTRELSZ:
+ pltrelsz = dyn_entry->d_un.d_val;
+ break;
+ case DT_LOPROC + 2:
+ info->text_addr = xt_ptr_offs(dst_addr,
+ dyn_entry->d_un.d_ptr, lib_info);
+ break;
+
+ default:
+ /* do nothing */
+ break;
+ }
+ dyn_entry++;
+ }
+
+ return XTLIB_NO_ERR;
+}
+
+static xt_ptr
+xtlib_load_split_pi_library_common(struct xtlib_packaged_library *library,
+ xt_ptr destination_code_address,
+ xt_ptr destination_data_address,
+ struct xtlib_pil_info *info,
+ struct lib_info *lib_info)
+{
+ struct xtlib_loader_globals *xtlib_globals =
+ &lib_info->xtlib_globals;
+ Elf32_Ehdr *header = (Elf32_Ehdr *)library;
+ Elf32_Phdr *pheader;
+ unsigned int align;
+ int err = validate_dynamic_splitload(header, lib_info);
+ xt_ptr destination_code_address_back;
+ xt_ptr destination_data_address_back;
+
+ if (err != XTLIB_NO_ERR) {
+ xtlib_globals->err = err;
+ return 0;
+ }
+
+ align = find_align(header, lib_info);
+
+ destination_code_address_back = destination_code_address;
+ destination_data_address_back = destination_data_address;
+
+ destination_code_address = align_ptr(destination_code_address, align);
+ destination_data_address = align_ptr(destination_data_address, align);
+ lib_info->code_buf_virt += (destination_code_address -
+ destination_code_address_back);
+ lib_info->data_buf_virt += (destination_data_address -
+ destination_data_address_back);
+
+ pheader = (Elf32_Phdr *)((char *)library +
+ xtlib_host_word(header->e_phoff,
+ xtlib_globals->byteswap));
+
+ err = get_dyn_info(header,
+ destination_code_address,
+ xtlib_host_word(pheader[0].p_paddr,
+ xtlib_globals->byteswap),
+ destination_data_address,
+ xtlib_host_word(pheader[1].p_paddr,
+ xtlib_globals->byteswap),
+ info,
+ lib_info);
+
+ if (err != XTLIB_NO_ERR) {
+ xtlib_globals->err = err;
+ return 0;
+ }
+
+ /* loading code */
+ xtlib_load_seg(&pheader[0],
+ (char *)library + xtlib_host_word(pheader[0].p_offset,
+ xtlib_globals->byteswap),
+ (xt_ptr)lib_info->code_buf_virt,
+ lib_info);
+
+ if (info->text_addr == 0)
+ info->text_addr =
+ (xt_ptr)xtlib_xt_word((Elf32_Word)destination_code_address,
+ xtlib_globals->byteswap);
+
+ /* loading data */
+ xtlib_load_seg(&pheader[1],
+ (char *)library + xtlib_host_word(pheader[1].p_offset,
+ xtlib_globals->byteswap),
+ (xt_ptr)lib_info->data_buf_virt +
+ xtlib_host_word(pheader[1].p_paddr,
+ xtlib_globals->byteswap),
+ lib_info);
+
+ return (xt_ptr)xtlib_host_word((Elf32_Word)info->start_sym,
+ xtlib_globals->byteswap);
+}
+
+static xt_ptr
+xtlib_host_load_split_pi_library(struct xtlib_packaged_library *library,
+ xt_ptr destination_code_address,
+ xt_ptr destination_data_address,
+ struct xtlib_pil_info *info,
+ struct lib_info *lib_info)
+{
+ return xtlib_load_split_pi_library_common(library,
+ destination_code_address,
+ destination_data_address,
+ info,
+ lib_info);
+}
+
+static long
+load_dpu_with_library(struct xf_client *client, struct xf_proxy *proxy,
+ struct lib_info *lib_info)
+{
+ struct fsl_dsp *dsp_priv = container_of(proxy, struct fsl_dsp, proxy);
+ unsigned char *srambuf;
+ struct lib_dnld_info_t dpulib;
+ struct file *file;
+ struct xf_buffer *buf;
+ Elf32_Phdr *pheader;
+ Elf32_Ehdr *header;
+ loff_t pos = 0;
+ unsigned int align;
+ int filesize = 0;
+ long ret_val = 0;
+
+ file = filp_open(lib_info->filename, O_RDONLY, 0);
+ if (IS_ERR(file))
+ return PTR_ERR(file);
+
+ vfs_llseek(file, 0, SEEK_END);
+ filesize = (int)file->f_pos;
+
+ srambuf = kmalloc(filesize, GFP_KERNEL);
+ if (!srambuf)
+ return -ENOMEM;
+
+ vfs_llseek(file, 0, SEEK_SET);
+ ret_val = kernel_read(file, srambuf, filesize, &pos);
+ if (ret_val < 0)
+ return ret_val;
+ filp_close(file, NULL);
+
+ ret_val = xtlib_split_pi_library_size(
+ (struct xtlib_packaged_library *)(srambuf),
+ (unsigned int *)&dpulib.size_code,
+ (unsigned int *)&dpulib.size_data,
+ lib_info);
+ if (ret_val != XTLIB_NO_ERR)
+ return -EINVAL;
+
+ lib_info->code_buf_size = dpulib.size_code;
+ lib_info->data_buf_size = dpulib.size_data;
+
+ header = (Elf32_Ehdr *)srambuf;
+ pheader = (Elf32_Phdr *)((char *)srambuf +
+ xtlib_host_word(header->e_phoff,
+ lib_info->xtlib_globals.byteswap));
+
+ align = find_align(header, lib_info);
+ ret_val = xf_pool_alloc(client, proxy, 1, dpulib.size_code + align,
+ XF_POOL_AUX, &lib_info->code_section_pool);
+ if (ret_val) {
+ kfree(srambuf);
+ pr_err("Allocation failure for loading code section\n");
+ return -ENOMEM;
+ }
+
+ ret_val = xf_pool_alloc(client, proxy, 1,
+ dpulib.size_data + pheader[1].p_paddr + align,
+ XF_POOL_AUX, &lib_info->data_section_pool);
+ if (ret_val) {
+ kfree(srambuf);
+ pr_err("Allocation failure for loading data section\n");
+ return -ENOMEM;
+ }
+
+ buf = xf_buffer_get(lib_info->code_section_pool);
+ lib_info->code_buf_virt = xf_buffer_data(buf);
+ lib_info->code_buf_phys = ((u64)xf_buffer_data(buf) -
+ (u64)dsp_priv->scratch_buf_virt) +
+ dsp_priv->scratch_buf_phys;
+ lib_info->code_buf_size = dpulib.size_code + align;
+ xf_buffer_put(buf);
+
+ buf = xf_buffer_get(lib_info->data_section_pool);
+ lib_info->data_buf_virt = xf_buffer_data(buf);
+ lib_info->data_buf_phys = ((u64)xf_buffer_data(buf) -
+ (u64)dsp_priv->scratch_buf_virt) +
+ dsp_priv->scratch_buf_phys;
+ lib_info->data_buf_size = dpulib.size_data + align + pheader[1].p_paddr;
+ xf_buffer_put(buf);
+
+ dpulib.pbuf_code = (unsigned long)lib_info->code_buf_phys;
+ dpulib.pbuf_data = (unsigned long)lib_info->data_buf_phys;
+
+ dpulib.ppil_inf = &lib_info->pil_info;
+ xtlib_host_load_split_pi_library((struct xtlib_packaged_library *)srambuf,
+ (xt_ptr)(dpulib.pbuf_code),
+ (xt_ptr)(dpulib.pbuf_data),
+ (struct xtlib_pil_info *)dpulib.ppil_inf,
+ (void *)lib_info);
+ kfree(srambuf);
+
+ return ret_val;
+}
+
+static long
+unload_dpu_with_library(struct xf_client *client, struct xf_proxy *proxy,
+ struct lib_info *lib_info)
+{
+ xf_pool_free(client, lib_info->code_section_pool);
+ xf_pool_free(client, lib_info->data_section_pool);
+
+ return 0;
+}
+
+long xf_load_lib(struct xf_client *client,
+ struct xf_handle *handle, struct lib_info *lib_info)
+{
+ void *b = xf_handle_aux(handle);
+ struct icm_xtlib_pil_info icm_info;
+ struct xf_proxy *proxy = handle->proxy;
+ struct xf_message msg;
+ struct xf_message *rmsg;
+ long ret_val;
+
+ ret_val = load_dpu_with_library(client, proxy, lib_info);
+ if (ret_val)
+ return ret_val;
+
+ memcpy((void *)(&icm_info.pil_info), (void *)(&lib_info->pil_info),
+ sizeof(struct xtlib_pil_info));
+
+ icm_info.lib_type = lib_info->lib_type;
+
+ /* ...set message parameters */
+ msg.id = __XF_MSG_ID(__XF_AP_CLIENT(0, 0), __XF_PORT_SPEC2(handle->id, 0));
+ msg.id = XF_MSG_AP_FROM_USER(msg.id, client->id);
+ msg.opcode = XF_LOAD_LIB;
+ msg.buffer = b;
+ msg.length = sizeof(struct icm_xtlib_pil_info);
+ msg.ret = 0;
+
+ /* ...copy lib info */
+ memcpy(b, (void *)&icm_info, xf_buffer_length(handle->aux));
+
+ /* ...execute command synchronously */
+ rmsg = xf_cmd_send_recv_complete(client, proxy, msg.id, msg.opcode,
+ msg.buffer, msg.length, &client->work,
+ &client->compr_complete);
+ if (IS_ERR(rmsg))
+ return PTR_ERR(rmsg);
+
+// xf_msg_free(proxy, rmsg);
+// xf_unlock(&proxy->lock);
+
+ return 0;
+}
+
+long xf_unload_lib(struct xf_client *client, struct xf_handle *handle, struct lib_info *lib_info)
+{
+ void *b = xf_handle_aux(handle);
+ struct xf_proxy *proxy = handle->proxy;
+ struct xf_message msg;
+ struct xf_message *rmsg;
+ struct icm_xtlib_pil_info icm_info;
+
+ memset((void *)&icm_info, 0, sizeof(struct icm_xtlib_pil_info));
+ icm_info.lib_type = lib_info->lib_type;
+
+ /* ...set message parameters */
+ msg.id = __XF_MSG_ID(__XF_AP_CLIENT(0, 0),__XF_PORT_SPEC2(handle->id, 0));
+ msg.id = XF_MSG_AP_FROM_USER(msg.id, client->id);
+ msg.opcode = XF_UNLOAD_LIB;
+ msg.buffer = b;
+ msg.length = sizeof(struct icm_xtlib_pil_info);
+ msg.ret = 0;
+
+ /* ...copy lib info */
+ memcpy(b, (void *)&icm_info, xf_buffer_length(handle->aux));
+
+ /* ...execute command synchronously */
+ rmsg = xf_cmd_send_recv_complete(client, proxy, msg.id, msg.opcode,
+ msg.buffer, msg.length, &client->work,
+ &client->compr_complete);
+ if (IS_ERR(rmsg))
+ return PTR_ERR(rmsg);
+
+// xf_msg_free(proxy, rmsg);
+// xf_unlock(&proxy->lock);
+
+ return unload_dpu_with_library(client, proxy, lib_info);
+}
diff --git a/sound/soc/fsl/fsl_dsp_library_load.h b/sound/soc/fsl/fsl_dsp_library_load.h
new file mode 100644
index 000000000000..8c14dda20b27
--- /dev/null
+++ b/sound/soc/fsl/fsl_dsp_library_load.h
@@ -0,0 +1,92 @@
+// SPDX-License-Identifier: GPL-2.0+
+// Copyright 2018 NXP
+// Copyright (c) 2012-2013 by Tensilica Inc.
+
+#ifndef FSL_DSP_LIBRARY_LOAD_H
+#define FSL_DSP_LIBRARY_LOAD_H
+
+#include "fsl_dsp_pool.h"
+
+#define Elf32_Byte unsigned char
+#define xt_ptr unsigned long
+#define xt_int int
+#define xt_uint unsigned int
+#define xt_ulong unsigned long
+
+struct xtlib_packaged_library;
+
+enum {
+ XTLIB_NO_ERR = 0,
+ XTLIB_NOT_ELF = 1,
+ XTLIB_NOT_DYNAMIC = 2,
+ XTLIB_NOT_STATIC = 3,
+ XTLIB_NO_DYNAMIC_SEGMENT = 4,
+ XTLIB_UNKNOWN_SYMBOL = 5,
+ XTLIB_NOT_ALIGNED = 6,
+ XTLIB_NOT_SPLITLOAD = 7,
+ XTLIB_RELOCATION_ERR = 8
+};
+
+enum lib_type {
+ DSP_CODEC_LIB = 1,
+ DSP_CODEC_WRAP_LIB
+};
+
+struct xtlib_loader_globals {
+ int err;
+ int byteswap;
+};
+
+struct xtlib_pil_info {
+ xt_uint dst_addr;
+ xt_uint src_offs;
+ xt_uint dst_data_addr;
+ xt_uint src_data_offs;
+ xt_uint start_sym;
+ xt_uint text_addr;
+ xt_uint init;
+ xt_uint fini;
+ xt_uint rel;
+ xt_int rela_count;
+ xt_uint hash;
+ xt_uint symtab;
+ xt_uint strtab;
+ xt_int align;
+};
+
+struct icm_xtlib_pil_info {
+ struct xtlib_pil_info pil_info;
+ unsigned int lib_type;
+};
+
+struct lib_dnld_info_t {
+ unsigned long pbuf_code;
+ unsigned long pbuf_data;
+ unsigned int size_code;
+ unsigned int size_data;
+ struct xtlib_pil_info *ppil_inf;
+ unsigned int lib_on_dpu; /* 0: not loaded, 1: loaded. */
+};
+
+struct lib_info {
+ struct xtlib_pil_info pil_info;
+ struct xtlib_loader_globals xtlib_globals;
+
+ struct xf_pool *code_section_pool;
+ struct xf_pool *data_section_pool;
+
+ void *code_buf_virt;
+ unsigned int code_buf_phys;
+ unsigned int code_buf_size;
+ void *data_buf_virt;
+ unsigned int data_buf_phys;
+ unsigned int data_buf_size;
+
+ const char *filename;
+ unsigned int lib_type;
+};
+
+long xf_load_lib(struct xf_client *client, struct xf_handle *handle, struct lib_info *lib_info);
+long xf_unload_lib(struct xf_client *client, struct xf_handle *handle, struct lib_info *lib_info);
+
+#endif
diff --git a/sound/soc/fsl/fsl_dsp_platform.h b/sound/soc/fsl/fsl_dsp_platform.h
new file mode 100644
index 000000000000..15d085c9f23d
--- /dev/null
+++ b/sound/soc/fsl/fsl_dsp_platform.h
@@ -0,0 +1,21 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (c) 2012-2013 by Tensilica Inc. ALL RIGHTS RESERVED.
+ * Copyright 2018 NXP
+ */
+
+#ifndef _FSL_DSP_PLATFORM_H
+#define _FSL_DSP_PLATFORM_H
+
+#include "fsl_dsp_xaf_api.h"
+
+struct dsp_data {
+ struct xf_client *client;
+ struct xaf_pipeline *p_pipe;
+ struct xaf_pipeline pipeline;
+ struct xaf_comp component[2];
+ int codec_type;
+ int status;
+};
+
+#endif /*_FSL_DSP_PLATFORM_H*/
diff --git a/sound/soc/fsl/fsl_dsp_platform_compress.c b/sound/soc/fsl/fsl_dsp_platform_compress.c
new file mode 100644
index 000000000000..7e84b1e2aa24
--- /dev/null
+++ b/sound/soc/fsl/fsl_dsp_platform_compress.c
@@ -0,0 +1,480 @@
+// SPDX-License-Identifier: GPL-2.0+
+//
+// DSP driver compress implementation
+//
+// Copyright (c) 2012-2013 by Tensilica Inc. ALL RIGHTS RESERVED.
+// Copyright 2018 NXP
+
+#include <linux/pm_runtime.h>
+#include <sound/soc.h>
+#include <sound/core.h>
+#include <sound/compress_driver.h>
+
+#include "fsl_dsp.h"
+#include "fsl_dsp_platform.h"
+#include "fsl_dsp_xaf_api.h"
+
+#define NUM_CODEC 2
+#define MIN_FRAGMENT 1
+#define MAX_FRAGMENT 1
+#define MIN_FRAGMENT_SIZE (4 * 1024)
+#define MAX_FRAGMENT_SIZE (4 * 1024)
+
+void dsp_platform_process(struct work_struct *w)
+{
+ struct xf_client *client = container_of(w, struct xf_client, work);
+ struct xf_proxy *proxy = client->proxy;
+ struct xf_message *rmsg;
+
+ while (1) {
+ rmsg = xf_cmd_recv(proxy, &client->wait, &client->queue, 1);
+
+ if (!proxy->is_active || IS_ERR(rmsg))
+ return;
+ if (rmsg->opcode == XF_EMPTY_THIS_BUFFER) {
+ client->consume_bytes += rmsg->length;
+ snd_compr_fragment_elapsed(client->cstream);
+
+ if (rmsg->buffer == NULL && rmsg->length == 0)
+ snd_compr_drain_notify(client->cstream);
+
+ } else {
+ memcpy(&client->m, rmsg, sizeof(struct xf_message));
+ complete(&client->compr_complete);
+ }
+
+ xf_msg_free(proxy, rmsg);
+ xf_unlock(&proxy->lock);
+ }
+}
+
+static int dsp_platform_compr_open(struct snd_compr_stream *cstream)
+{
+ struct snd_soc_pcm_runtime *rtd = cstream->private_data;
+ struct snd_soc_platform *platform = rtd->platform;
+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+ struct fsl_dsp *dsp_priv = snd_soc_platform_get_drvdata(platform);
+ struct dsp_data *drv = &dsp_priv->dsp_data;
+
+ drv->client = xf_client_alloc(dsp_priv);
+ if (IS_ERR(drv->client))
+ return PTR_ERR(drv->client);
+
+ fsl_dsp_open_func(dsp_priv, drv->client);
+
+ drv->client->proxy = &dsp_priv->proxy;
+
+ cpu_dai->driver->ops->startup(NULL, cpu_dai);
+
+ drv->client->cstream = cstream;
+
+ INIT_WORK(&drv->client->work, dsp_platform_process);
+
+ return 0;
+}
+
+static int dsp_platform_compr_free(struct snd_compr_stream *cstream)
+{
+ struct snd_soc_pcm_runtime *rtd = cstream->private_data;
+ struct snd_soc_platform *platform = rtd->platform;
+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+ struct fsl_dsp *dsp_priv = snd_soc_platform_get_drvdata(platform);
+ struct dsp_data *drv = &dsp_priv->dsp_data;
+ int ret;
+
+ if (cstream->runtime->state != SNDRV_PCM_STATE_PAUSED &&
+ cstream->runtime->state != SNDRV_PCM_STATE_RUNNING &&
+ cstream->runtime->state != SNDRV_PCM_STATE_DRAINING) {
+
+ ret = xaf_comp_delete(drv->client, &drv->component[1]);
+ if (ret) {
+ dev_err(platform->dev, "Fail to delete component, err = %d\n", ret);
+ return ret;
+ }
+
+ ret = xaf_comp_delete(drv->client, &drv->component[0]);
+ if (ret) {
+ dev_err(platform->dev, "Fail to delete component, err = %d\n", ret);
+ return ret;
+ }
+ }
+
+ cpu_dai->driver->ops->shutdown(NULL, cpu_dai);
+
+ drv->client->proxy->is_active = 0;
+ wake_up(&drv->client->wait);
+ cancel_work_sync(&drv->client->work);
+
+ fsl_dsp_close_func(drv->client);
+
+ return 0;
+}
+
+static int dsp_platform_compr_set_params(struct snd_compr_stream *cstream,
+ struct snd_compr_params *params)
+{
+ /* accroding to the params, load the library and create component*/
+ struct snd_soc_pcm_runtime *rtd = cstream->private_data;
+ struct snd_soc_platform *platform = rtd->platform;
+ struct fsl_dsp *dsp_priv = snd_soc_platform_get_drvdata(platform);
+ struct dsp_data *drv = &dsp_priv->dsp_data;
+ struct xf_proxy *p_proxy = &dsp_priv->proxy;
+ struct xf_set_param_msg s_param;
+ int ret;
+
+ switch (params->codec.id) {
+ case SND_AUDIOCODEC_MP3:
+ drv->codec_type = CODEC_MP3_DEC;
+ break;
+ case SND_AUDIOCODEC_AAC:
+ drv->codec_type = CODEC_AAC_DEC;
+ break;
+ default:
+ dev_err(platform->dev, "codec not supported, id =%d\n", params->codec.id);
+ return -EINVAL;
+ }
+
+ /* ...create auxiliary buffers pool for control commands */
+ ret = xf_pool_alloc(drv->client,
+ p_proxy,
+ XA_AUX_POOL_SIZE,
+ XA_AUX_POOL_MSG_LENGTH,
+ XF_POOL_AUX,
+ &p_proxy->aux);
+ if (ret) {
+ dev_err(platform->dev, "xf_pool_alloc failed");
+ return ret;
+ }
+
+ /* ...create pipeline */
+ ret = xaf_pipeline_create(&drv->pipeline);
+ if (ret) {
+ dev_err(platform->dev, "create pipeline error\n");
+ goto err_pool_alloc;
+ }
+
+ /* ...create component */
+ ret = xaf_comp_create(drv->client, p_proxy, &drv->component[0],
+ drv->codec_type);
+ if (ret) {
+ dev_err(platform->dev,
+ "create component failed type = %d, err = %d\n",
+ drv->codec_type, ret);
+ goto err_pool_alloc;
+ }
+
+ ret = xaf_comp_create(drv->client, p_proxy, &drv->component[1],
+ RENDER_ESAI);
+ if (ret) {
+ dev_err(platform->dev,
+ "create component failed, type = %d, err = %d\n",
+ RENDER_ESAI, ret);
+ goto err_comp0_create;
+ }
+
+ /* ...add component into pipeline */
+ ret = xaf_comp_add(&drv->pipeline, &drv->component[0]);
+ if (ret) {
+ dev_err(platform->dev,
+ "add component failed, type = %d, err = %d\n",
+ drv->codec_type, ret);
+ goto err_comp1_create;
+ }
+
+ ret = xaf_comp_add(&drv->pipeline, &drv->component[1]);
+ if (ret) {
+ dev_err(platform->dev,
+ "add component failed, type = %d, err = %d\n",
+ drv->codec_type, ret);
+ goto err_comp1_create;
+ }
+
+ drv->client->input_bytes = 0;
+ drv->client->consume_bytes = 0;
+
+ s_param.id = XA_RENDERER_CONFIG_PARAM_SAMPLE_RATE;
+ s_param.value = params->codec.sample_rate;
+ ret = xaf_comp_set_config(drv->client, &drv->component[1], 1, &s_param);
+ if (ret) {
+ dev_err(platform->dev,
+ "set param[cmd:0x%x|val:0x%x] error, err = %d\n",
+ s_param.id, s_param.value, ret);
+ goto err_comp1_create;
+ }
+
+ s_param.id = XA_RENDERER_CONFIG_PARAM_CHANNELS;
+ s_param.value = params->codec.ch_out;
+ ret = xaf_comp_set_config(drv->client, &drv->component[1], 1, &s_param);
+ if (ret) {
+ dev_err(platform->dev,
+ "set param[cmd:0x%x|val:0x%x] error, err = %d\n",
+ s_param.id, s_param.value, ret);
+ goto err_comp1_create;
+ }
+
+ s_param.id = XA_RENDERER_CONFIG_PARAM_PCM_WIDTH;
+ s_param.value = 16;
+ ret = xaf_comp_set_config(drv->client, &drv->component[1], 1, &s_param);
+ if (ret) {
+ dev_err(platform->dev,
+ "set param[cmd:0x%x|val:0x%x] error, err = %d\n",
+ s_param.id, s_param.value, ret);
+ goto err_comp1_create;
+ }
+ return 0;
+
+err_comp1_create:
+ xaf_comp_delete(drv->client, &drv->component[1]);
+err_comp0_create:
+ xaf_comp_delete(drv->client, &drv->component[0]);
+err_pool_alloc:
+ xf_pool_free(drv->client, p_proxy->aux);
+
+ return ret;
+}
+
+static int dsp_platform_compr_trigger_start(struct snd_compr_stream *cstream)
+{
+ struct snd_soc_pcm_runtime *rtd = cstream->private_data;
+ struct snd_soc_platform *platform = rtd->platform;
+ struct fsl_dsp *dsp_priv = snd_soc_platform_get_drvdata(platform);
+ struct dsp_data *drv = &dsp_priv->dsp_data;
+ struct xaf_comp *p_comp = &drv->component[0];
+ int ret;
+
+ ret = xaf_comp_process(drv->client,
+ p_comp,
+ p_comp->inptr,
+ drv->client->input_bytes,
+ XF_EMPTY_THIS_BUFFER);
+
+ ret = xaf_connect(drv->client,
+ &drv->component[0],
+ &drv->component[1],
+ 1,
+ OUTBUF_SIZE);
+ if (ret) {
+ dev_err(platform->dev, "Failed to connect component, err = %d\n", ret);
+ return ret;
+ }
+
+ schedule_work(&drv->client->work);
+
+ return 0;
+}
+
+static int dsp_platform_compr_trigger_stop(struct snd_compr_stream *cstream)
+{
+ struct snd_soc_pcm_runtime *rtd = cstream->private_data;
+ struct snd_soc_platform *platform = rtd->platform;
+ struct fsl_dsp *dsp_priv = snd_soc_platform_get_drvdata(platform);
+ struct dsp_data *drv = &dsp_priv->dsp_data;
+ int ret;
+
+ ret = xaf_comp_flush(drv->client, &drv->component[0]);
+ if (ret) {
+ dev_err(platform->dev, "Fail to flush component, err = %d\n", ret);
+ return ret;
+ }
+
+ ret = xaf_comp_flush(drv->client, &drv->component[1]);
+ if (ret) {
+ dev_err(platform->dev, "Fail to flush component, err = %d\n", ret);
+ return ret;
+ }
+
+ ret = xaf_comp_delete(drv->client, &drv->component[0]);
+ if (ret) {
+ dev_err(platform->dev, "Fail to delete component, err = %d\n", ret);
+ return ret;
+ }
+
+ ret = xaf_comp_delete(drv->client, &drv->component[1]);
+ if (ret) {
+ dev_err(platform->dev, "Fail to delete component, err = %d\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int dsp_platform_compr_trigger_drain(struct snd_compr_stream *cstream)
+{
+ struct snd_soc_pcm_runtime *rtd = cstream->private_data;
+ struct snd_soc_platform *platform = rtd->platform;
+ struct fsl_dsp *dsp_priv = snd_soc_platform_get_drvdata(platform);
+ struct dsp_data *drv = &dsp_priv->dsp_data;
+ struct xaf_comp *p_comp = &drv->component[0];
+ int ret;
+
+ ret = xaf_comp_process(drv->client, p_comp, NULL, 0,
+ XF_EMPTY_THIS_BUFFER);
+
+ schedule_work(&drv->client->work);
+ return 0;
+}
+
+static int dsp_platform_compr_trigger(struct snd_compr_stream *cstream, int cmd)
+{
+ int ret = 0;
+
+ switch (cmd) {
+ case SNDRV_PCM_TRIGGER_START:
+ ret = dsp_platform_compr_trigger_start(cstream);
+ break;
+ case SNDRV_PCM_TRIGGER_STOP:
+ ret = dsp_platform_compr_trigger_stop(cstream);
+ break;
+ case SND_COMPR_TRIGGER_DRAIN:
+ ret = dsp_platform_compr_trigger_drain(cstream);
+ break;
+ case SND_COMPR_TRIGGER_PARTIAL_DRAIN:
+ break;
+ case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+ break;
+ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+ break;
+ }
+
+ /*send command*/
+ return ret;
+}
+
+static int dsp_platform_compr_pointer(struct snd_compr_stream *cstream,
+ struct snd_compr_tstamp *tstamp)
+{
+ struct snd_soc_pcm_runtime *rtd = cstream->private_data;
+ struct snd_soc_platform *platform = rtd->platform;
+ struct fsl_dsp *dsp_priv = snd_soc_platform_get_drvdata(platform);
+ struct dsp_data *drv = &dsp_priv->dsp_data;
+
+ tstamp->copied_total = drv->client->input_bytes;
+ tstamp->byte_offset = drv->client->input_bytes;
+ tstamp->pcm_frames = 0x900;
+ tstamp->pcm_io_frames = 0,
+ tstamp->sampling_rate = 48000;
+
+ return 0;
+}
+
+static int dsp_platform_compr_copy(struct snd_compr_stream *cstream,
+ char __user *buf,
+ size_t count)
+{
+ struct snd_soc_pcm_runtime *rtd = cstream->private_data;
+ struct snd_soc_platform *platform = rtd->platform;
+ struct fsl_dsp *dsp_priv = snd_soc_platform_get_drvdata(platform);
+ struct dsp_data *drv = &dsp_priv->dsp_data;
+ struct xaf_comp *p_comp = &drv->component[0];
+ int copied = 0;
+ int ret;
+
+ if (drv->client->input_bytes == drv->client->consume_bytes) {
+ if (count > INBUF_SIZE){
+ ret = copy_from_user(p_comp->inptr, buf, INBUF_SIZE);
+ if (ret) {
+ dev_err(platform->dev, "failed to get message from user space\n");
+ return -EFAULT;
+ }
+ copied = INBUF_SIZE;
+ } else {
+ ret = copy_from_user(p_comp->inptr, buf, count);
+ if (ret) {
+ dev_err(platform->dev, "failed to get message from user space\n");
+ return -EFAULT;
+ }
+ copied = count;
+ }
+ drv->client->input_bytes += copied;
+
+ if (cstream->runtime->state == SNDRV_PCM_STATE_RUNNING) {
+ ret = xaf_comp_process(drv->client, p_comp,
+ p_comp->inptr, copied,
+ XF_EMPTY_THIS_BUFFER);
+ schedule_work(&drv->client->work);
+ }
+ }
+
+ return copied;
+}
+
+static int dsp_platform_compr_get_caps(struct snd_compr_stream *cstream,
+ struct snd_compr_caps *caps)
+{
+ caps->num_codecs = NUM_CODEC;
+ caps->min_fragment_size = MIN_FRAGMENT_SIZE; /* 50KB */
+ caps->max_fragment_size = MAX_FRAGMENT_SIZE; /* 1024KB */
+ caps->min_fragments = MIN_FRAGMENT;
+ caps->max_fragments = MAX_FRAGMENT;
+ caps->codecs[0] = SND_AUDIOCODEC_MP3;
+ caps->codecs[1] = SND_AUDIOCODEC_AAC;
+
+ return 0;
+}
+
+static struct snd_compr_codec_caps caps_mp3 = {
+ .num_descriptors = 1,
+ .descriptor[0].max_ch = 2,
+ .descriptor[0].sample_rates[0] = 48000,
+ .descriptor[0].sample_rates[1] = 44100,
+ .descriptor[0].sample_rates[2] = 32000,
+ .descriptor[0].sample_rates[3] = 16000,
+ .descriptor[0].sample_rates[4] = 8000,
+ .descriptor[0].num_sample_rates = 5,
+ .descriptor[0].bit_rate[0] = 320,
+ .descriptor[0].bit_rate[1] = 192,
+ .descriptor[0].num_bitrates = 2,
+ .descriptor[0].profiles = 0,
+ .descriptor[0].modes = SND_AUDIOCHANMODE_MP3_STEREO,
+ .descriptor[0].formats = 0,
+};
+
+static struct snd_compr_codec_caps caps_aac = {
+ .num_descriptors = 2,
+ .descriptor[1].max_ch = 2,
+ .descriptor[0].sample_rates[0] = 48000,
+ .descriptor[0].sample_rates[1] = 44100,
+ .descriptor[0].sample_rates[2] = 32000,
+ .descriptor[0].sample_rates[3] = 16000,
+ .descriptor[0].sample_rates[4] = 8000,
+ .descriptor[0].num_sample_rates = 5,
+ .descriptor[1].bit_rate[0] = 320,
+ .descriptor[1].bit_rate[1] = 192,
+ .descriptor[1].num_bitrates = 2,
+ .descriptor[1].profiles = 0,
+ .descriptor[1].modes = 0,
+ .descriptor[1].formats =
+ (SND_AUDIOSTREAMFORMAT_MP4ADTS |
+ SND_AUDIOSTREAMFORMAT_RAW),
+};
+
+static int dsp_platform_compr_get_codec_caps(struct snd_compr_stream *cstream,
+ struct snd_compr_codec_caps *codec)
+{
+ if (codec->codec == SND_AUDIOCODEC_MP3)
+ *codec = caps_mp3;
+ else if (codec->codec == SND_AUDIOCODEC_AAC)
+ *codec = caps_aac;
+ else
+ return -EINVAL;
+
+ return 0;
+}
+
+static int dsp_platform_compr_set_metadata(struct snd_compr_stream *cstream,
+ struct snd_compr_metadata *metadata)
+{
+ return 0;
+}
+
+const struct snd_compr_ops dsp_platform_compr_ops = {
+ .open = dsp_platform_compr_open,
+ .free = dsp_platform_compr_free,
+ .set_params = dsp_platform_compr_set_params,
+ .set_metadata = dsp_platform_compr_set_metadata,
+ .trigger = dsp_platform_compr_trigger,
+ .pointer = dsp_platform_compr_pointer,
+ .copy = dsp_platform_compr_copy,
+ .get_caps = dsp_platform_compr_get_caps,
+ .get_codec_caps = dsp_platform_compr_get_codec_caps,
+};
diff --git a/sound/soc/fsl/fsl_dsp_pool.c b/sound/soc/fsl/fsl_dsp_pool.c
new file mode 100644
index 000000000000..1ac2454dd9f3
--- /dev/null
+++ b/sound/soc/fsl/fsl_dsp_pool.c
@@ -0,0 +1,151 @@
+// SPDX-License-Identifier: GPL-2.0+
+//
+// Xtensa buffer pool API
+//
+// Copyright 2018 NXP
+// Copyright (c) 2012-2013 by Tensilica Inc.
+
+#include <linux/slab.h>
+#include <soc/imx8/sc/ipc.h>
+
+#include "fsl_dsp_pool.h"
+#include "fsl_dsp.h"
+
+/* ...allocate buffer pool */
+int xf_pool_alloc(struct xf_client *client, struct xf_proxy *proxy,
+ u32 number, u32 length, xf_pool_type_t type,
+ struct xf_pool **pool)
+{
+ struct xf_pool *p;
+ struct xf_buffer *b;
+ void *data;
+ struct xf_message msg;
+ struct xf_message *rmsg;
+
+ /* ...basic sanity checks; number of buffers is positive */
+ if (number <=0)
+ return -EINVAL;
+
+ /* ...get properly aligned buffer length */
+ length = ALIGN(length, XF_PROXY_ALIGNMENT);
+
+ p = kzalloc(offsetof(struct xf_pool, buffer) +
+ number * sizeof(struct xf_buffer), GFP_KERNEL);
+ if(!p)
+ return -ENOMEM;
+
+ /* ...prepare command parameters */
+ msg.id = __XF_MSG_ID(__XF_AP_PROXY(0), __XF_DSP_PROXY(0));
+ msg.id = XF_MSG_AP_FROM_USER(msg.id, client->id);
+ msg.opcode = XF_ALLOC;
+ msg.length = length * number;
+ msg.buffer = NULL;
+ msg.ret = 0;
+
+ /* ...execute command synchronously */
+ rmsg = xf_cmd_send_recv_complete(client, proxy, msg.id, msg.opcode,
+ msg.buffer, msg.length, &client->work,
+ &client->compr_complete);
+ if (IS_ERR(rmsg)) {
+ kfree(p);
+ return PTR_ERR(rmsg);
+ }
+
+ p->p = rmsg->buffer;
+ /* TODO: review cleanup */
+ /* xf_msg_free(proxy, rmsg);
+ * xf_unlock(&proxy->lock); */
+
+ /* ...if operation is failed, do cleanup */
+ /* ...set pool parameters */
+ p->number = number, p->length = length;
+ p->proxy = proxy;
+
+ /* ...create individual buffers and link them into free list */
+ for (p->free = b = &p->buffer[0], data = p->p; number > 0;
+ number--, b++) {
+ /* ...set address of the buffer (no length there) */
+ b->address = data;
+
+ /* ...file buffer into the free list */
+ b->link.next = b + 1;
+
+ /* ...advance data pointer in contiguous buffer */
+ data += length;
+ }
+
+ /* ...terminate list of buffers (not too good - tbd) */
+ b[-1].link.next = NULL;
+
+ /* ...return buffer pointer */
+ *pool = p;
+
+ return 0;
+}
+/* ...buffer pool destruction */
+int xf_pool_free(struct xf_client *client, struct xf_pool *pool)
+{
+ struct xf_proxy *proxy;
+ struct xf_message msg;
+ struct xf_message *rmsg;
+
+ /* ...basic sanity checks; pool is positive */
+ if (pool == NULL)
+ return -EINVAL;
+
+ /* ...get proxy pointer */
+ if ((proxy = pool->proxy) == NULL)
+ return -EINVAL;
+
+ /* ...prepare command parameters */
+ msg.id = __XF_MSG_ID(__XF_AP_PROXY(0), __XF_DSP_PROXY(0));
+ msg.id = XF_MSG_AP_FROM_USER(msg.id, client->id);
+ msg.opcode = XF_FREE;
+ msg.length = pool->length * pool->number;
+ msg.buffer = pool->p;
+ msg.ret = 0;
+
+ /* ...execute command synchronously */
+ rmsg = xf_cmd_send_recv_complete(client, proxy, msg.id, msg.opcode,
+ msg.buffer, msg.length, &client->work,
+ &client->compr_complete);
+ kfree(pool);
+ if (IS_ERR(rmsg))
+ return PTR_ERR(rmsg);
+
+ /* TODO: review cleanup */
+ /* xf_msg_free(proxy, rmsg);
+ * xf_unlock(&proxy->lock); */
+
+ return 0;
+}
+
+/* ...get new buffer from a pool */
+struct xf_buffer *xf_buffer_get(struct xf_pool *pool)
+{
+ struct xf_buffer *b;
+
+ xf_lock(&pool->proxy->lock);
+ /* ...take buffer from a head of the free list */
+ b = pool->free;
+ if (b) {
+ /* ...advance free list head */
+ pool->free = b->link.next, b->link.pool = pool;
+ }
+
+ xf_unlock(&pool->proxy->lock);
+ return b;
+}
+
+/* ...return buffer back to pool */
+void xf_buffer_put(struct xf_buffer *buffer)
+{
+ struct xf_pool *pool = buffer->link.pool;
+
+ xf_lock(&pool->proxy->lock);
+ /* ...use global proxy lock for pool operations protection */
+ /* ...put buffer back to a pool */
+ buffer->link.next = pool->free, pool->free = buffer;
+
+ xf_unlock(&pool->proxy->lock);
+}
diff --git a/sound/soc/fsl/fsl_dsp_pool.h b/sound/soc/fsl/fsl_dsp_pool.h
new file mode 100644
index 000000000000..4a56262faf7f
--- /dev/null
+++ b/sound/soc/fsl/fsl_dsp_pool.h
@@ -0,0 +1,113 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Xtensa buffer pool API header
+ *
+ * Copyright 2018 NXP
+ * Copyright (c) 2012-2013 by Tensilica Inc
+ */
+#ifndef FSL_DSP_POOL_H
+#define FSL_DSP_POOL_H
+
+#include <linux/types.h>
+#include "fsl_dsp_proxy.h"
+
+/* ...buffer pool type */
+typedef u32 xf_pool_type_t;
+
+/* ...previous declaration of struct */
+struct xf_buffer;
+struct xf_pool;
+struct xf_handle;
+struct xf_message;
+struct xf_client;
+
+/* ...response callback */
+typedef void (*xf_response_cb)(struct xf_handle *h, struct xf_message *msg);
+
+/* ...buffer pool type */
+enum xf_pool_type {
+ XF_POOL_AUX = 0,
+ XF_POOL_INPUT = 1,
+ XF_POOL_OUTPUT = 2
+};
+
+/* ...buffer link pointer */
+union xf_buffer_link {
+ /* ...pointer to next free buffer in a pool (for free buffer) */
+ struct xf_buffer *next;
+ /* ...reference to a buffer pool (for allocated buffer) */
+ struct xf_pool *pool;
+};
+
+/* ...buffer descriptor */
+struct xf_buffer {
+ /* ...virtual address of contiguous buffer */
+ void *address;
+ /* ...link pointer */
+ union xf_buffer_link link;
+};
+
+/* ...buffer pool */
+struct xf_pool {
+ /* ...reference to proxy data */
+ struct xf_proxy *proxy;
+ /* ...length of individual buffer in a pool */
+ u32 length;
+ /* ...number of buffers in a pool */
+ u32 number;
+ /* ...pointer to pool memory */
+ void *p;
+ /* ...pointer to first free buffer in a pool */
+ struct xf_buffer *free;
+ /* ...individual buffers */
+ struct xf_buffer buffer[0];
+};
+
+/* component handle */
+struct xf_handle {
+ /* ...reference to proxy data */
+ struct xf_proxy *proxy;
+ /* ...auxiliary control buffer for control transactions */
+ struct xf_buffer *aux;
+ /* ...global client-id of the component */
+ u32 id;
+ /* ...local client number (think about merging into "id" field - tbd) */
+ u32 client;
+ /* ...response processing hook */
+ xf_response_cb response;
+};
+
+/* ...accessor to buffer data */
+static inline void *xf_buffer_data(struct xf_buffer *buffer)
+{
+ return buffer->address;
+}
+
+/* ...length of buffer data */
+static inline size_t xf_buffer_length(struct xf_buffer *buffer)
+{
+ struct xf_pool *pool = buffer->link.pool;
+
+ return (size_t)pool->length;
+}
+
+/* ...component client-id (global scope) */
+static inline u32 xf_handle_id(struct xf_handle *handle)
+{
+ return handle->id;
+}
+
+/* ...pointer to auxiliary buffer */
+static inline void *xf_handle_aux(struct xf_handle *handle)
+{
+ return xf_buffer_data(handle->aux);
+}
+
+int xf_pool_alloc(struct xf_client *client, struct xf_proxy *proxy, u32 number,
+ u32 length, xf_pool_type_t type, struct xf_pool **pool);
+int xf_pool_free(struct xf_client *client, struct xf_pool *pool);
+
+struct xf_buffer *xf_buffer_get(struct xf_pool *pool);
+void xf_buffer_put(struct xf_buffer *buffer);
+
+#endif /* FSL_DSP_POOL_H */
diff --git a/sound/soc/fsl/fsl_dsp_proxy.c b/sound/soc/fsl/fsl_dsp_proxy.c
new file mode 100644
index 000000000000..a80d280011bd
--- /dev/null
+++ b/sound/soc/fsl/fsl_dsp_proxy.c
@@ -0,0 +1,859 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+//
+// DSP proxy driver transfers messages between DSP driver and DSP framework
+//
+// Copyright 2018 NXP
+// Copyright (C) 2017 Cadence Design Systems, Inc.
+
+#include <soc/imx8/sc/ipc.h>
+#include "fsl_dsp_proxy.h"
+#include "fsl_dsp.h"
+
+/* ...initialize message queue */
+void xf_msg_queue_init(struct xf_msg_queue *queue)
+{
+ queue->head = queue->tail = NULL;
+}
+
+/* ...get message queue head */
+struct xf_message *xf_msg_queue_head(struct xf_msg_queue *queue)
+{
+ return queue->head;
+}
+
+/* ...allocate new message from the pool */
+struct xf_message *xf_msg_alloc(struct xf_proxy *proxy)
+{
+ struct xf_message *m = proxy->free;
+
+ /* ...make sure we have a free message item */
+ if (m != NULL) {
+ /* ...get message from the pool */
+ proxy->free = m->next, m->next = NULL;
+ }
+
+ return m;
+}
+
+/* ...return message to the pool of free items */
+void xf_msg_free(struct xf_proxy *proxy, struct xf_message *m)
+{
+ /* ...put message into the head of free items list */
+ m->next = proxy->free, proxy->free = m;
+
+ /* ...notify potential client waiting for message */
+ wake_up(&proxy->busy);
+}
+
+/* ...return all messages from the queue to the pool of free items */
+void xf_msg_free_all(struct xf_proxy *proxy, struct xf_msg_queue *queue)
+{
+ struct xf_message *m = queue->head;
+
+ /* ...check if there is anything in the queue */
+ if (m != NULL) {
+ queue->tail->next = proxy->free;
+ proxy->free = queue->head;
+ queue->head = queue->tail = NULL;
+
+ /* ...notify potential client waiting for message */
+ wake_up(&proxy->busy);
+ }
+}
+
+/* ...submit message to a queue */
+int xf_msg_enqueue(struct xf_msg_queue *queue, struct xf_message *m)
+{
+ int first = (queue->head == NULL);
+
+ /* ...set pointer to next item */
+ m->next = NULL;
+
+ /* ...advance head/tail pointer as required */
+ if (first)
+ queue->head = m;
+ else
+ queue->tail->next = m;
+
+ /* ...new tail points to this message */
+ queue->tail = m;
+
+ return first;
+}
+
+/* ...retrieve next message from the per-task queue */
+struct xf_message *xf_msg_dequeue(struct xf_msg_queue *queue)
+{
+ struct xf_message *m = queue->head;
+
+ /* ...check if there is anything in the queue */
+ if (m != NULL) {
+ /* ...pop message from the head of the list */
+ queue->head = m->next;
+ if (queue->head == NULL)
+ queue->tail = NULL;
+ }
+
+ return m;
+}
+
+/* ...helper function for requesting execution message from a pool */
+struct xf_message *xf_msg_available(struct xf_proxy *proxy)
+{
+ struct xf_message *m;
+
+ /* ...acquire global lock */
+ xf_lock(&proxy->lock);
+
+ /* ...try to allocate the message */
+ m = xf_msg_alloc(proxy);
+ if (m == NULL) {
+ /* ...failed to allocate message; release lock */
+ xf_unlock(&proxy->lock);
+ }
+
+ /* ...if successfully allocated */
+ return m;
+}
+
+/* ...helper function for receiving a message from per-client queue */
+struct xf_message *xf_msg_received(struct xf_proxy *proxy,
+ struct xf_msg_queue *queue)
+{
+ struct xf_message *m;
+
+ /* ...acquire global lock */
+ xf_lock(&proxy->lock);
+
+ /* ...try to peek message from the queue */
+ m = xf_msg_dequeue(queue);
+ if (m == NULL) {
+ /* ...queue is empty; release lock */
+ xf_unlock(&proxy->lock);
+ }
+
+ /* ...if message is non-null, lock is held */
+ return m;
+}
+
+/*
+ * MU related functions
+ */
+u32 icm_intr_send(struct xf_proxy *proxy, u32 msg)
+{
+ struct fsl_dsp *dsp_priv = container_of(proxy,
+ struct fsl_dsp, proxy);
+
+ MU_SendMessage(dsp_priv->mu_base_virtaddr, 0, msg);
+ return 0;
+}
+
+int icm_intr_extended_send(struct xf_proxy *proxy,
+ u32 msg,
+ struct dsp_ext_msg *ext_msg)
+{
+ struct fsl_dsp *dsp_priv = container_of(proxy,
+ struct fsl_dsp, proxy);
+ struct device *dev = dsp_priv->dev;
+ union icm_header_t msghdr;
+
+ msghdr.allbits = msg;
+ if (msghdr.size != 8)
+ dev_err(dev, "too much ext msg\n");
+
+ MU_SendMessage(dsp_priv->mu_base_virtaddr, 1, ext_msg->phys);
+ MU_SendMessage(dsp_priv->mu_base_virtaddr, 2, ext_msg->size);
+ MU_SendMessage(dsp_priv->mu_base_virtaddr, 0, msg);
+
+ return 0;
+}
+
+int send_dpu_ext_msg_addr(struct xf_proxy *proxy)
+{
+ struct fsl_dsp *dsp_priv = container_of(proxy,
+ struct fsl_dsp, proxy);
+ union icm_header_t msghdr;
+ struct dsp_ext_msg ext_msg;
+ struct dsp_mem_msg *dpu_ext_msg =
+ (struct dsp_mem_msg *)((unsigned char *)dsp_priv->msg_buf_virt
+ + (MSG_BUF_SIZE / 2));
+ int ret_val = 0;
+
+ msghdr.allbits = 0; /* clear all bits; */
+ msghdr.ack = 0;
+ msghdr.intr = 1;
+ msghdr.msg = ICM_CORE_INIT;
+ msghdr.size = 8;
+ ext_msg.phys = dsp_priv->msg_buf_phys + (MSG_BUF_SIZE / 2);
+ ext_msg.size = sizeof(struct dsp_mem_msg);
+
+ dpu_ext_msg->ext_msg_phys = dsp_priv->msg_buf_phys;
+ dpu_ext_msg->ext_msg_size = MSG_BUF_SIZE;
+ dpu_ext_msg->scratch_phys = dsp_priv->scratch_buf_phys;
+ dpu_ext_msg->scratch_size = dsp_priv->scratch_buf_size;
+ dpu_ext_msg->dsp_config_phys = dsp_priv->dsp_config_phys;
+ dpu_ext_msg->dsp_config_size = dsp_priv->dsp_config_size;
+ dpu_ext_msg->dsp_board_type = dsp_priv->dsp_board_type;
+
+ icm_intr_extended_send(proxy, msghdr.allbits, &ext_msg);
+
+ return ret_val;
+}
+
+long icm_ack_wait(struct xf_proxy *proxy, u32 msg)
+{
+ struct fsl_dsp *dsp_priv = container_of(proxy,
+ struct fsl_dsp, proxy);
+ struct device *dev = dsp_priv->dev;
+ union icm_header_t msghdr;
+ int err;
+
+ msghdr.allbits = msg;
+ /* wait response from mu */
+ err = wait_for_completion_timeout(&proxy->cmd_complete,
+ msecs_to_jiffies(1000));
+ if (!err) {
+ dev_err(dev, "icm ack timeout! %x\n", msg);
+ return -ETIMEDOUT;
+ }
+
+ dev_dbg(dev, "Ack recd for message 0x%08x\n", msghdr.allbits);
+
+ return 0;
+}
+
+irqreturn_t fsl_dsp_mu_isr(int irq, void *dev_id)
+{
+ struct xf_proxy *proxy = dev_id;
+ struct fsl_dsp *dsp_priv = container_of(proxy,
+ struct fsl_dsp, proxy);
+ struct device *dev = dsp_priv->dev;
+ union icm_header_t msghdr;
+ u32 reg;
+
+ MU_ReceiveMsg(dsp_priv->mu_base_virtaddr, 0, &reg);
+ msghdr = (union icm_header_t)reg;
+
+ if (msghdr.intr == 1) {
+ dev_dbg(dev, "INTR: Received ICM intr, msg 0x%08x\n",
+ msghdr.allbits);
+ switch (msghdr.msg) {
+ case ICM_CORE_EXIT:
+ break;
+ case ICM_CORE_READY:
+ send_dpu_ext_msg_addr(proxy);
+ proxy->is_ready = 1;
+ complete(&proxy->cmd_complete);
+ break;
+ case XF_SUSPEND:
+ case XF_RESUME:
+ complete(&proxy->cmd_complete);
+ break;
+ default:
+ schedule_work(&proxy->work);
+ break;
+ }
+ } else if (msghdr.ack == 1) {
+ dev_dbg(dev, "INTR: Received ICM ack 0x%08x\n", msghdr.size);
+ msghdr.ack = 0;
+ } else {
+ dev_dbg(dev, "Received false ICM intr 0x%08x\n",
+ msghdr.allbits);
+ }
+
+ return IRQ_HANDLED;
+}
+
+/*
+ * Proxy related functions
+ */
+/* ...NULL-address specification */
+#define XF_PROXY_NULL (~0U)
+
+#define XF_PROXY_BADADDR (dsp_priv->scratch_buf_size)
+
+/* ...shared memory translation - kernel virtual address to shared address */
+u32 xf_proxy_b2a(struct xf_proxy *proxy, void *b)
+{
+ struct fsl_dsp *dsp_priv = container_of(proxy,
+ struct fsl_dsp, proxy);
+
+ if (b == NULL)
+ return XF_PROXY_NULL;
+ else if ((u32)(b - dsp_priv->scratch_buf_virt) <
+ dsp_priv->scratch_buf_size)
+ return (u32)(b - dsp_priv->scratch_buf_virt);
+ else
+ return XF_PROXY_BADADDR;
+}
+
+/* ...shared memory translation - shared address to kernel virtual address */
+void *xf_proxy_a2b(struct xf_proxy *proxy, u32 address)
+{
+ struct fsl_dsp *dsp_priv = container_of(proxy,
+ struct fsl_dsp, proxy);
+
+ if (address < dsp_priv->scratch_buf_size)
+ return dsp_priv->scratch_buf_virt + address;
+ else if (address == XF_PROXY_NULL)
+ return NULL;
+ else
+ return (void *) -1;
+}
+
+/* ...process association between response received and intended client */
+static void xf_cmap(struct xf_proxy *proxy, struct xf_message *m)
+{
+ struct fsl_dsp *dsp_priv = container_of(proxy,
+ struct fsl_dsp, proxy);
+ u32 id = XF_AP_IPC_CLIENT(m->id);
+ struct xf_client *client;
+
+ /* ...process messages addressed to proxy itself */
+ if (id == 0) {
+ /* ...place message into local response queue */
+ xf_msg_enqueue(&proxy->response, m);
+ wake_up(&proxy->wait);
+ return;
+ }
+
+ /* ...make sure the client ID is sane */
+ client = xf_client_lookup(dsp_priv, id);
+ if (!client) {
+ pr_err("rsp[id:%08x]: client lookup failed", m->id);
+ xf_msg_free(proxy, m);
+ return;
+ }
+
+ /* ...make sure client is bound to this proxy interface */
+ if (client->proxy != proxy) {
+ pr_err("rsp[id:%08x]: wrong proxy interface", m->id);
+ xf_msg_free(proxy, m);
+ return;
+ }
+
+ /* ...place message into local response queue */
+ if (xf_msg_enqueue(&client->queue, m))
+ wake_up(&client->wait);
+}
+
+/* ...retrieve pending responses from shared memory ring-buffer */
+static u32 xf_shmem_process_responses(struct xf_proxy *proxy)
+{
+ struct xf_message *m;
+ u32 read_idx, write_idx;
+ int status;
+
+ status = 0;
+
+ /* ...get current values of read/write pointers in response queue */
+ read_idx = XF_PROXY_READ(proxy, rsp_read_idx);
+ write_idx = XF_PROXY_READ(proxy, rsp_write_idx);
+
+ /* ...process all committed responses */
+ while (!XF_QUEUE_EMPTY(read_idx, write_idx)) {
+ struct xf_proxy_message *response;
+
+ /* ...allocate execution message */
+ m = xf_msg_alloc(proxy);
+ if (m == NULL)
+ break;
+
+ /* ...mark the interface status has changed */
+ status |= (XF_QUEUE_FULL(read_idx, write_idx) ? 0x3 : 0x1);
+
+ /* ...get oldest not yet processed response */
+ response = XF_PROXY_RESPONSE(proxy, XF_QUEUE_IDX(read_idx));
+
+ /* ...fill message parameters */
+ m->id = response->session_id;
+ m->opcode = response->opcode;
+ m->length = response->length;
+ m->buffer = xf_proxy_a2b(proxy, response->address);
+ m->ret = response->ret;
+
+ /* ...advance local reading index copy */
+ read_idx = XF_QUEUE_ADVANCE_IDX(read_idx);
+
+ /* ...update shadow copy of reading index */
+ XF_PROXY_WRITE(proxy, rsp_read_idx, read_idx);
+
+ /* ...submit message to proper client */
+ xf_cmap(proxy, m);
+ }
+
+ return status;
+}
+
+/* ...put pending commands into shared memory ring-buffer */
+static u32 xf_shmem_process_commands(struct xf_proxy *proxy)
+{
+ struct xf_message *m;
+ u32 read_idx, write_idx;
+ int status = 0;
+
+ /* ...get current value of peer read pointer */
+ write_idx = XF_PROXY_READ(proxy, cmd_write_idx);
+ read_idx = XF_PROXY_READ(proxy, cmd_read_idx);
+
+ /* ...submit any pending commands */
+ while (!XF_QUEUE_FULL(read_idx, write_idx)) {
+ struct xf_proxy_message *command;
+
+ /* ...check if we have a pending command */
+ m = xf_msg_dequeue(&proxy->command);
+ if (m == NULL)
+ break;
+
+ /* ...always mark the interface status has changed */
+ status |= 0x3;
+
+ /* ...select the place for the command */
+ command = XF_PROXY_COMMAND(proxy, XF_QUEUE_IDX(write_idx));
+
+ /* ...put the response message fields */
+ command->session_id = m->id;
+ command->opcode = m->opcode;
+ command->length = m->length;
+ command->address = xf_proxy_b2a(proxy, m->buffer);
+ command->ret = m->ret;
+
+ /* ...return message back to the pool */
+ xf_msg_free(proxy, m);
+
+ /* ...advance local writing index copy */
+ write_idx = XF_QUEUE_ADVANCE_IDX(write_idx);
+
+ /* ...update shared copy of queue write pointer */
+ XF_PROXY_WRITE(proxy, cmd_write_idx, write_idx);
+ }
+
+ if (status)
+ icm_intr_send(proxy, 0);
+
+ return status;
+}
+
+/* ...shared memory interface maintenance routine */
+void xf_proxy_process(struct work_struct *w)
+{
+ struct xf_proxy *proxy = container_of(w, struct xf_proxy, work);
+ int status = 0;
+
+ /* ...get exclusive access to internal data */
+ xf_lock(&proxy->lock);
+
+ do {
+ /* ...process outgoing commands first */
+ status = xf_shmem_process_commands(proxy);
+
+ /* ...process all pending responses */
+ status |= xf_shmem_process_responses(proxy);
+
+ } while (status);
+
+ /* ...unlock internal proxy data */
+ xf_unlock(&proxy->lock);
+}
+
+/* ...initialize shared memory interface */
+int xf_proxy_init(struct xf_proxy *proxy)
+{
+ struct fsl_dsp *dsp_priv = container_of(proxy,
+ struct fsl_dsp, proxy);
+ struct xf_message *m;
+ int i;
+
+ /* ...create a list of all messages in a pool; set head pointer */
+ proxy->free = &proxy->pool[0];
+
+ /* ...put all messages into a single-linked list */
+ for (i = 0, m = proxy->free; i < XF_CFG_MESSAGE_POOL_SIZE - 1; i++, m++)
+ m->next = m + 1;
+
+ /* ...set list tail pointer */
+ m->next = NULL;
+
+ /* ...initialize proxy lock */
+ xf_lock_init(&proxy->lock);
+
+ /* ...initialize proxy thread message queues */
+ xf_msg_queue_init(&proxy->command);
+ xf_msg_queue_init(&proxy->response);
+
+ /* ...initialize global busy queue */
+ init_waitqueue_head(&proxy->busy);
+ init_waitqueue_head(&proxy->wait);
+
+ /* ...create work structure */
+ INIT_WORK(&proxy->work, xf_proxy_process);
+
+ /* ...set pointer to shared memory */
+ proxy->ipc.shmem = (struct xf_shmem_data *)dsp_priv->msg_buf_virt;
+
+ /* ...initialize shared memory interface */
+ XF_PROXY_WRITE(proxy, cmd_read_idx, 0);
+ XF_PROXY_WRITE(proxy, cmd_write_idx, 0);
+ XF_PROXY_WRITE(proxy, cmd_invalid, 0);
+ XF_PROXY_WRITE(proxy, rsp_read_idx, 0);
+ XF_PROXY_WRITE(proxy, rsp_write_idx, 0);
+ XF_PROXY_WRITE(proxy, rsp_invalid, 0);
+
+ return 0;
+}
+
+/* ...trigger shared memory interface processing */
+void xf_proxy_notify(struct xf_proxy *proxy)
+{
+ schedule_work(&proxy->work);
+}
+
+/* ...submit a command to proxy pending queue (lock released upon return) */
+void xf_proxy_command(struct xf_proxy *proxy, struct xf_message *m)
+{
+ int first;
+
+ /* ...submit message to proxy thread */
+ first = xf_msg_enqueue(&proxy->command, m);
+
+ /* ...release the lock */
+ xf_unlock(&proxy->lock);
+
+ /* ...notify thread about command reception */
+ (first ? xf_proxy_notify(proxy), 1 : 0);
+}
+
+/*
+ * Proxy cmd send and receive functions
+ */
+int xf_cmd_send(struct xf_proxy *proxy,
+ u32 id,
+ u32 opcode,
+ void *buffer,
+ u32 length)
+{
+ struct xf_message *m;
+ int ret;
+
+ /* ...retrieve message handle (take the lock on success) */
+ ret = wait_event_interruptible(proxy->busy,
+ (m = xf_msg_available(proxy)) != NULL);
+ if (ret)
+ return -EINTR;
+
+ /* ...fill-in message parameters (lock is taken) */
+ m->id = id;
+ m->opcode = opcode;
+ m->length = length;
+ m->buffer = buffer;
+ m->ret = 0;
+
+ /* ...submit command to the proxy */
+ xf_proxy_command(proxy, m);
+
+ return 0;
+}
+
+struct xf_message *xf_cmd_recv(struct xf_proxy *proxy,
+ wait_queue_head_t *wq,
+ struct xf_msg_queue *queue,
+ int wait)
+{
+ struct xf_message *m = NULL;
+ int ret;
+
+ /* ...wait for message reception (take lock on success) */
+ ret = wait_event_interruptible(*wq,
+ (m = xf_msg_received(proxy, queue)) != NULL || !wait
+ || !proxy->is_active);
+ if (ret)
+ return ERR_PTR(-EINTR);
+
+ /* ...return message with a lock taken */
+ return m;
+}
+
+struct xf_message *xf_cmd_recv_timeout(struct xf_proxy *proxy,
+ wait_queue_head_t *wq,
+ struct xf_msg_queue *queue, int wait)
+{
+ struct xf_message *m;
+ int ret;
+
+ /* ...wait for message reception (take lock on success) */
+ ret = wait_event_interruptible_timeout(*wq,
+ (m = xf_msg_received(proxy, queue)) != NULL || !wait,
+ msecs_to_jiffies(1000));
+ if (ret < 0)
+ return ERR_PTR(-EINTR);
+
+ if (ret == 0)
+ return ERR_PTR(-ETIMEDOUT);
+
+ /* ...return message with a lock taken */
+ return m;
+}
+
+/* ...helper function for synchronous command execution */
+struct xf_message *xf_cmd_send_recv(struct xf_proxy *proxy,
+ u32 id, u32 opcode,
+ void *buffer,
+ u32 length)
+{
+ int ret;
+
+ /* ...send command to remote proxy */
+ ret = xf_cmd_send(proxy, id, opcode, buffer, length);
+ if (ret)
+ return ERR_PTR(ret);
+
+ /* ...wait for message delivery */
+ return xf_cmd_recv(proxy, &proxy->wait, &proxy->response, 1);
+}
+
+struct xf_message *xf_cmd_send_recv_wq(struct xf_proxy *proxy, u32 id,
+ u32 opcode, void *buffer, u32 length,
+ wait_queue_head_t *wq,
+ struct xf_msg_queue *queue)
+{
+ int ret;
+
+ /* ...send command to remote proxy */
+ ret = xf_cmd_send(proxy, id, opcode, buffer, length);
+ if (ret)
+ return ERR_PTR(ret);
+
+ /* ...wait for message delivery */
+ return xf_cmd_recv(proxy, wq, queue, 1);
+}
+
+struct xf_message *xf_cmd_send_recv_complete(struct xf_client *client,
+ struct xf_proxy *proxy,
+ u32 id, u32 opcode, void *buffer,
+ u32 length,
+ struct work_struct *work,
+ struct completion *completion)
+{
+ struct xf_message *m;
+ int ret;
+
+ /* ...retrieve message handle (take the lock on success) */
+ m = xf_msg_available(proxy);
+ if (!m)
+ return ERR_PTR(-EBUSY);
+
+ /* ...fill-in message parameters (lock is taken) */
+ m->id = id;
+ m->opcode = opcode;
+ m->length = length;
+ m->buffer = buffer;
+ m->ret = 0;
+
+ init_completion(completion);
+
+ /* ...submit command to the proxy */
+ xf_proxy_command(proxy, m);
+
+ schedule_work(work);
+
+ /* ...wait for message reception (take lock on success) */
+ ret = wait_for_completion_timeout(completion,
+ msecs_to_jiffies(1000));
+ if (!ret)
+ return ERR_PTR(-ETIMEDOUT);
+
+ m = &client->m;
+
+ /* ...return message with a lock taken */
+ return m;
+}
+/*
+ * Proxy allocate and free memory functions
+ */
+/* ...allocate memory buffer for kernel use */
+int xf_cmd_alloc(struct xf_proxy *proxy, void **buffer, u32 length)
+{
+ struct xf_message *m;
+ u32 id = 0;
+ int ret;
+
+ /* ...send command to remote proxy */
+ m = xf_cmd_send_recv(proxy, id, XF_ALLOC, NULL, length);
+ if (IS_ERR(m)) {
+ xf_unlock(&proxy->lock);
+ ret = PTR_ERR(m);
+ return ret;
+ }
+
+ /* ...check if response is expected */
+ if (m->opcode == XF_ALLOC && m->buffer != NULL) {
+ *buffer = m->buffer;
+ ret = 0;
+ } else {
+ ret = -ENOMEM;
+ }
+
+ /* ...free message and release proxy lock */
+ xf_msg_free(proxy, m);
+ xf_unlock(&proxy->lock);
+
+ return ret;
+}
+
+/* ...free memory buffer */
+int xf_cmd_free(struct xf_proxy *proxy, void *buffer, u32 length)
+{
+ struct xf_message *m;
+ u32 id = 0;
+ int ret;
+
+ /* ...synchronously execute freeing command */
+ m = xf_cmd_send_recv(proxy, id, XF_FREE, buffer, length);
+ if (IS_ERR(m)) {
+ xf_unlock(&proxy->lock);
+ ret = PTR_ERR(m);
+ return ret;
+ }
+
+ /* ...check if response is expected */
+ if (m->opcode == XF_FREE)
+ ret = 0;
+ else
+ ret = -EINVAL;
+
+ /* ...free message and release proxy lock */
+ xf_msg_free(proxy, m);
+ xf_unlock(&proxy->lock);
+
+ return ret;
+}
+
+/*
+ * suspend & resume functions
+ */
+int xf_cmd_send_suspend(struct xf_proxy *proxy)
+{
+ union icm_header_t msghdr;
+ int ret = 0;
+
+ init_completion(&proxy->cmd_complete);
+
+ msghdr.allbits = 0; /* clear all bits; */
+ msghdr.ack = 0;
+ msghdr.intr = 1;
+ msghdr.msg = XF_SUSPEND;
+ msghdr.size = 0;
+ icm_intr_send(proxy, msghdr.allbits);
+
+ /* wait for response here */
+ ret = icm_ack_wait(proxy, msghdr.allbits);
+
+ return ret;
+}
+
+int xf_cmd_send_resume(struct xf_proxy *proxy)
+{
+ union icm_header_t msghdr;
+ int ret = 0;
+
+ init_completion(&proxy->cmd_complete);
+
+ msghdr.allbits = 0; /* clear all bits; */
+ msghdr.ack = 0;
+ msghdr.intr = 1;
+ msghdr.msg = XF_RESUME;
+ msghdr.size = 0;
+ icm_intr_send(proxy, msghdr.allbits);
+
+ /* wait for response here */
+ ret = icm_ack_wait(proxy, msghdr.allbits);
+
+ return ret;
+}
+
+/* ...open component handle */
+int xf_open(struct xf_client *client, struct xf_proxy *proxy,
+ struct xf_handle *handle, const char *id, u32 core,
+ xf_response_cb response)
+{
+ void *b;
+ struct xf_message msg;
+ struct xf_message *rmsg;
+
+ /* ...retrieve auxiliary control buffer from proxy - need I */
+ handle->aux = xf_buffer_get(proxy->aux);
+
+ b = xf_handle_aux(handle);
+
+ msg.id = __XF_MSG_ID(__XF_AP_PROXY(0), __XF_DSP_PROXY(0));
+ msg.id = XF_MSG_AP_FROM_USER(msg.id, client->id);
+ msg.opcode = XF_REGISTER;
+ msg.buffer = b;
+ msg.length = strlen(id) + 1;
+ msg.ret = 0;
+
+ /* ...copy component identifier */
+ memcpy(b, (void *)id, xf_buffer_length(handle->aux));
+
+ /* ...execute command synchronously */
+ rmsg = xf_cmd_send_recv_complete(client, proxy, msg.id, msg.opcode,
+ msg.buffer, msg.length, &client->work,
+ &client->compr_complete);
+
+ if (IS_ERR(rmsg)) {
+ xf_buffer_put(handle->aux), handle->aux = NULL;
+ return PTR_ERR(rmsg);
+ }
+ /* ...save received component global client-id */
+ handle->id = XF_MSG_SRC(rmsg->id);
+ /* TODO: review cleanup */
+ /* xf_msg_free(proxy, rmsg);
+ * xf_unlock(&proxy->lock); */
+
+ /* ...if failed, release buffer handle */
+ /* ...operation completed successfully; assign handle data */
+ handle->response = response;
+ handle->proxy = proxy;
+
+ return 0;
+}
+
+/* ...close component handle */
+int xf_close(struct xf_client *client, struct xf_handle *handle)
+{
+ struct xf_proxy *proxy = handle->proxy;
+ struct xf_message msg;
+ struct xf_message *rmsg;
+
+ /* ...do I need to take component lock here? guess no - tbd */
+
+ /* ...buffers and stuff? - tbd */
+
+ /* ...acquire global proxy lock */
+ /* ...unregister component from remote DSP proxy (ignore result code) */
+
+ msg.id = __XF_MSG_ID(__XF_AP_PROXY(0), handle->id);
+ msg.id = XF_MSG_AP_FROM_USER(msg.id, client->id);
+ msg.opcode = XF_UNREGISTER;
+ msg.buffer = NULL;
+ msg.length = 0;
+ msg.ret = 0;
+
+ /* ...execute command synchronously */
+ rmsg = xf_cmd_send_recv_complete(client, proxy, msg.id, msg.opcode,
+ msg.buffer, msg.length, &client->work,
+ &client->compr_complete);
+
+ if (IS_ERR(rmsg)) {
+ xf_buffer_put(handle->aux), handle->aux = NULL;
+ return PTR_ERR(rmsg);
+ }
+ /* TODO: review cleanup */
+ /* xf_msg_free(proxy, rmsg);
+ * xf_unlock(&proxy->lock); */
+
+ /* ...wipe out proxy pointer */
+ handle->proxy = NULL;
+
+ return 0;
+}
diff --git a/sound/soc/fsl/fsl_dsp_proxy.h b/sound/soc/fsl/fsl_dsp_proxy.h
new file mode 100644
index 000000000000..bc9ccf37bc8f
--- /dev/null
+++ b/sound/soc/fsl/fsl_dsp_proxy.h
@@ -0,0 +1,520 @@
+/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
+/*
+ * DSP proxy header - commands/responses from DSP driver to DSP ramework
+ *
+ * Copyright 2018 NXP
+ * Copyright (c) 2017 Cadence Design Systems, Inc.
+ */
+
+#ifndef __FSL_DSP_PROXY_H
+#define __FSL_DSP_PROXY_H
+
+#include <linux/wait.h>
+#include <linux/device.h>
+#include <linux/workqueue.h>
+#include <linux/spinlock.h>
+#include <linux/compiler.h>
+#include <linux/dma-mapping.h>
+#include <linux/platform_data/dma-imx.h>
+#include <linux/mx8_mu.h>
+#include <linux/interrupt.h>
+
+#include "fsl_dsp_pool.h"
+#define XF_CFG_MESSAGE_POOL_SIZE 256
+
+struct xf_client;
+
+/*******************************************************************************
+ * Local proxy data
+ ******************************************************************************/
+
+struct xf_message;
+struct xf_handle;
+typedef void (*xf_response_cb)(struct xf_handle *h, struct xf_message *msg);
+
+/* ...execution message */
+struct xf_message {
+ /* ...pointer to next message in a list */
+ struct xf_message *next;
+
+ /* ...session-id */
+ u32 id;
+
+ /* ...operation code */
+ u32 opcode;
+
+ /* ...length of data buffer */
+ u32 length;
+
+ /* ...translated data pointer */
+ void *buffer;
+
+ /* ...return message status */
+ u32 ret;
+};
+
+/* ...message queue */
+struct xf_msg_queue {
+ /* ...pointer to list head */
+ struct xf_message *head;
+
+ /* ...pointer to list tail */
+ struct xf_message *tail;
+};
+
+struct xf_proxy_message {
+ /* ...session ID */
+ u32 session_id;
+
+ /* ...proxy API command/response code */
+ u32 opcode;
+
+ /* ...length of attached buffer */
+ u32 length;
+
+ /* ...physical address of message buffer */
+ u32 address;
+
+ /* ...return message status */
+ u32 ret;
+};
+/**********************************************************************/
+
+enum icm_action_t {
+ ICM_CORE_READY = 1,
+ ICM_CORE_INIT,
+ ICM_CORE_EXIT,
+};
+
+/* ...adjust IPC client of message going from user-space */
+#define XF_MSG_AP_FROM_USER(id, client) (((id) & ~(0xF << 2)) | (client << 2))
+
+
+#define __XF_PORT_SPEC(core, id, port) ((core) | ((id) << 2) | ((port) << 8))
+#define __XF_PORT_SPEC2(id, port) ((id) | ((port) << 8))
+
+
+/* ...wipe out IPC client from message going to user-space */
+#define XF_MSG_AP_TO_USER(id) ((id) & ~(0xF << 18))
+#define __XF_AP_PROXY(core) ((core) | 0x8000)
+#define __XF_DSP_PROXY(core) ((core) | 0x8000)
+
+/* ...message id contains source and destination ports specification */
+#define __XF_MSG_ID(src, dst) (((src) & 0xFFFF) | (((dst) & 0xFFFF) << 16))
+#define XF_MSG_SRC(id) (((id) >> 0) & 0xFFFF)
+#define XF_MSG_SRC_CORE(id) (((id) >> 0) & 0x3)
+#define XF_MSG_SRC_CLIENT(id) (((id) >> 2) & 0x3F)
+#define XF_MSG_DST_CLIENT(id) (((id) >> 18) & 0x3F)
+
+/* ...special treatment of AP-proxy destination field */
+#define XF_AP_IPC_CLIENT(id) (((id) >> 18) & 0xF)
+#define XF_AP_CLIENT(id) (((id) >> 22) & 0x1FF)
+#define __XF_AP_PROXY(core) ((core) | 0x8000)
+#define __XF_DSP_PROXY(core) ((core) | 0x8000)
+#define __XF_AP_CLIENT(core, client) ((core) | ((client) << 6) | 0x8000)
+
+/* ...opcode composition with command/response data tags */
+#define __XF_OPCODE(c, r, op) (((c) << 31) | ((r) << 30) | ((op) & 0x3F))
+
+/* ...shared buffer allocation */
+#define XF_ALLOC __XF_OPCODE(0, 0, 4)
+
+/* ...shared buffer freeing */
+#define XF_FREE __XF_OPCODE(0, 0, 5)
+
+/* ...resume component operation */
+#define XF_RESUME __XF_OPCODE(0, 0, 14)
+
+/* ...resume component operation */
+#define XF_SUSPEND __XF_OPCODE(0, 0, 15)
+
+
+/*******************************************************************************
+ * Ring buffer support
+ ******************************************************************************/
+/* ...cache-line size on DSP */
+#define XF_PROXY_ALIGNMENT 64
+
+/* ...total length of shared memory queue (for commands and responses) */
+#define XF_PROXY_MESSAGE_QUEUE_LENGTH (1 << 6)
+
+/* ...index mask */
+#define XF_PROXY_MESSAGE_QUEUE_MASK 0x3F
+
+/* ...ring-buffer index */
+#define __XF_QUEUE_IDX(idx, counter) \
+ (((idx) & XF_PROXY_MESSAGE_QUEUE_MASK) | ((counter) << 16))
+
+/* ...retrieve ring-buffer index */
+#define XF_QUEUE_IDX(idx) \
+ ((idx) & XF_PROXY_MESSAGE_QUEUE_MASK)
+
+/* ...increment ring-buffer index */
+#define XF_QUEUE_ADVANCE_IDX(idx) \
+ (((idx) + 0x10001) & (0xFFFF0000 | XF_PROXY_MESSAGE_QUEUE_MASK))
+
+/* ...test if ring buffer is empty */
+#define XF_QUEUE_EMPTY(read, write) \
+ ((read) == (write))
+
+/* ...test if ring buffer is full */
+#define XF_QUEUE_FULL(read, write) \
+ ((write) == (read) + (XF_PROXY_MESSAGE_QUEUE_LENGTH << 16))
+
+/* ...basic cache operations */
+#define XF_PROXY_INVALIDATE(addr, len) { }
+
+#define XF_PROXY_FLUSH(addr, len) { }
+
+/* ...data managed by host CPU (remote) - in case of shunt it is a IPC layer */
+struct xf_proxy_host_data {
+ /* ...command queue */
+ struct xf_proxy_message command[XF_PROXY_MESSAGE_QUEUE_LENGTH];
+
+ /* ...writing index into command queue */
+ u32 cmd_write_idx;
+
+ /* ...reading index for response queue */
+ u32 rsp_read_idx;
+
+ /* ...indicate command queue is valid or not */
+ u32 cmd_invalid;
+};
+
+/* ...data managed by DSP (local) */
+struct xf_proxy_dsp_data {
+ /* ...response queue */
+ struct xf_proxy_message response[XF_PROXY_MESSAGE_QUEUE_LENGTH];
+
+ /* ...writing index into response queue */
+ u32 rsp_write_idx;
+
+ /* ...reading index for command queue */
+ u32 cmd_read_idx;
+
+ /* ...indicate response queue is valid or not */
+ u32 rsp_invalid;
+};
+
+/* ...shared memory data */
+struct xf_shmem_data {
+ /* ...ingoing data (maintained by DSP (local side)) */
+ struct xf_proxy_host_data local;
+
+ /* ...outgoing data (maintained by host CPU (remote side)) */
+ struct xf_proxy_dsp_data remote;
+
+};
+
+/* ...shared memory data accessor */
+#define XF_SHMEM_DATA(proxy) \
+ ((proxy)->ipc.shmem)
+
+/* ...atomic reading */
+#define __XF_PROXY_READ_ATOMIC(var) \
+ ({ XF_PROXY_INVALIDATE(&(var), sizeof(var)); \
+ *(u32 *)&(var); })
+
+/* ...atomic writing */
+#define __XF_PROXY_WRITE_ATOMIC(var, value) \
+ ({*(u32 *)&(var) = (value); \
+ XF_PROXY_FLUSH(&(var), sizeof(var)); \
+ (value); })
+
+/* ...accessors */
+#define XF_PROXY_READ(proxy, field) \
+ __XF_PROXY_READ_##field(XF_SHMEM_DATA(proxy))
+
+#define XF_PROXY_WRITE(proxy, field, v) \
+ __XF_PROXY_WRITE_##field(XF_SHMEM_DATA(proxy), (v))
+
+/* ...individual fields reading */
+#define __XF_PROXY_READ_cmd_write_idx(shmem) \
+ __XF_PROXY_READ_ATOMIC(shmem->local.cmd_write_idx)
+
+#define __XF_PROXY_READ_cmd_read_idx(shmem) \
+ shmem->remote.cmd_read_idx
+
+#define __XF_PROXY_READ_cmd_invalid(shmem) \
+ __XF_PROXY_READ_ATOMIC(shmem->local.cmd_invalid)
+
+#define __XF_PROXY_READ_rsp_write_idx(shmem) \
+ __XF_PROXY_READ_ATOMIC(shmem->remote.rsp_write_idx)
+
+#define __XF_PROXY_READ_rsp_read_idx(shmem) \
+ shmem->local.rsp_read_idx
+
+#define __XF_PROXY_READ_rsp_invalid(shmem) \
+ __XF_PROXY_READ_ATOMIC(shmem->remote.rsp_invalid)
+
+/* ...individual fields writings */
+#define __XF_PROXY_WRITE_cmd_write_idx(shmem, v) \
+ __XF_PROXY_WRITE_ATOMIC(shmem->local.cmd_write_idx, v)
+
+#define __XF_PROXY_WRITE_cmd_read_idx(shmem, v) \
+ __XF_PROXY_WRITE_ATOMIC(shmem->remote.cmd_read_idx, v)
+
+#define __XF_PROXY_WRITE_cmd_invalid(shmem, v) \
+ __XF_PROXY_WRITE_ATOMIC(shmem->local.cmd_invalid, v)
+
+#define __XF_PROXY_WRITE_rsp_read_idx(shmem, v) \
+ __XF_PROXY_WRITE_ATOMIC(shmem->local.rsp_read_idx, v)
+
+#define __XF_PROXY_WRITE_rsp_write_idx(shmem, v) \
+ __XF_PROXY_WRITE_ATOMIC(shmem->remote.rsp_write_idx, v)
+
+#define __XF_PROXY_WRITE_rsp_invalid(shmem, v) \
+ __XF_PROXY_WRITE_ATOMIC(shmem->remote.rsp_invalid, v)
+
+/* ...command buffer accessor */
+#define XF_PROXY_COMMAND(proxy, idx) \
+ (&XF_SHMEM_DATA(proxy)->local.command[(idx)])
+
+/* ...response buffer accessor */
+#define XF_PROXY_RESPONSE(proxy, idx) \
+ (&XF_SHMEM_DATA(proxy)->remote.response[(idx)])
+
+/*******************************************************************************
+ * Local proxy data
+ ******************************************************************************/
+
+struct xf_proxy_ipc_data {
+ /* ...shared memory data pointer */
+ struct xf_shmem_data __iomem *shmem;
+
+ /* ...core identifier */
+ u32 core;
+
+ /* ...IPC registers memory */
+ void __iomem *regs;
+};
+
+/* ...proxy data */
+struct xf_proxy {
+ /* ...IPC layer data */
+ struct xf_proxy_ipc_data ipc;
+
+ /* ...shared memory status change processing item */
+ struct work_struct work;
+
+ struct completion cmd_complete;
+ int is_ready;
+ int is_active;
+
+ /* ...internal lock */
+ spinlock_t lock;
+
+ /* ...busy queue (for clients waiting ON NOTIFIcation) */
+ wait_queue_head_t busy;
+
+ /* ...waiting queue for synchronous proxy operations */
+ wait_queue_head_t wait;
+
+ /* ...submitted commands queue */
+ struct xf_msg_queue command;
+
+ /* ...pending responses queue */
+ struct xf_msg_queue response;
+
+ /* ...global message pool */
+ struct xf_message pool[XF_CFG_MESSAGE_POOL_SIZE];
+
+ /* ...pointer to first free message in the pool */
+ struct xf_message *free;
+
+ /* ...auxiliary buffer pool for clients */
+ struct xf_pool *aux;
+};
+
+union icm_header_t {
+ struct {
+ u32 msg:6;
+ u32 sub_msg:6; // sub_msg will have ICM_MSG
+ u32 rsvd:3; /* reserved */
+ u32 intr:1; /* intr = 1 when sending msg. */
+ u32 size:15; /* =size in bytes (excluding header) */
+ u32 ack:1; /* response message when ack=1 */
+ };
+ u32 allbits;
+};
+
+struct dsp_ext_msg {
+ u32 phys;
+ u32 size;
+};
+
+struct dsp_mem_msg {
+ u32 ext_msg_phys;
+ u32 ext_msg_size;
+ u32 scratch_phys;
+ u32 scratch_size;
+ u32 dsp_config_phys;
+ u32 dsp_config_size;
+ u32 dsp_board_type;
+};
+
+static inline void xf_lock_init(spinlock_t *lock)
+{
+ spin_lock_init(lock);
+}
+
+static inline void xf_lock(spinlock_t *lock)
+{
+ spin_lock(lock);
+}
+
+static inline void xf_unlock(spinlock_t *lock)
+{
+ spin_unlock(lock);
+}
+
+/* ...init proxy */
+int xf_proxy_init(struct xf_proxy *proxy);
+
+/* ...send message to proxy */
+int xf_cmd_send(struct xf_proxy *proxy,
+ u32 id,
+ u32 opcode,
+ void *buffer,
+ u32 length);
+
+/* ...get message from proxy */
+struct xf_message *xf_cmd_recv(struct xf_proxy *proxy,
+ wait_queue_head_t *wq,
+ struct xf_msg_queue *queue,
+ int wait);
+
+struct xf_message*
+xf_cmd_recv_timeout(struct xf_proxy *proxy, wait_queue_head_t *wq,
+ struct xf_msg_queue *queue, int wait);
+
+struct xf_message*
+xf_cmd_send_recv(struct xf_proxy *proxy, u32 id, u32 opcode,
+ void *buffer, u32 length);
+
+struct xf_message*
+xf_cmd_send_recv_wq(struct xf_proxy *proxy, u32 id, u32 opcode, void *buffer,
+ u32 length, wait_queue_head_t *wq,
+ struct xf_msg_queue *queue);
+
+struct xf_message*
+xf_cmd_send_recv_complete(struct xf_client *client, struct xf_proxy *proxy,
+ u32 id, u32 opcode, void *buffer, u32 length,
+ struct work_struct *work,
+ struct completion *completion);
+
+/* ...mu interrupt handle */
+irqreturn_t fsl_dsp_mu_isr(int irq, void *dev_id);
+
+/* ...initialize client pending message queue */
+void xf_msg_queue_init(struct xf_msg_queue *queue);
+
+/* ...return current queue state */
+struct xf_message *xf_msg_queue_head(struct xf_msg_queue *queue);
+
+/* ...return the message back to a pool */
+void xf_msg_free(struct xf_proxy *proxy, struct xf_message *m);
+
+/* ...release all pending messages */
+void xf_msg_free_all(struct xf_proxy *proxy, struct xf_msg_queue *queue);
+
+/* ...wait mu interrupt */
+long icm_ack_wait(struct xf_proxy *proxy, u32 msg);
+
+/* ...shared memory translation - kernel virtual address to shared address */
+u32 xf_proxy_b2a(struct xf_proxy *proxy, void *b);
+
+/* ...shared memory translation - shared address to kernel virtual address */
+void *xf_proxy_a2b(struct xf_proxy *proxy, u32 address);
+
+int xf_cmd_send_suspend(struct xf_proxy *proxy);
+int xf_cmd_send_resume(struct xf_proxy *proxy);
+
+int xf_cmd_alloc(struct xf_proxy *proxy, void **buffer, u32 length);
+int xf_cmd_free(struct xf_proxy *proxy, void *buffer, u32 length);
+
+int xf_open(struct xf_client *client, struct xf_proxy *proxy,
+ struct xf_handle *handle, const char *id, u32 core,
+ xf_response_cb response);
+
+int xf_close(struct xf_client *client, struct xf_handle *handle);
+
+
+
+/*******************************************************************************
+ * Opcode composition
+ ******************************************************************************/
+
+/* ...opcode composition with command/response data tags */
+#define __XF_OPCODE(c, r, op) (((c) << 31) | ((r) << 30) | ((op) & 0x3F))
+
+/* ...accessors */
+#define XF_OPCODE_CDATA(opcode) ((opcode) & (1 << 31))
+#define XF_OPCODE_RDATA(opcode) ((opcode) & (1 << 30))
+#define XF_OPCODE_TYPE(opcode) ((opcode) & (0x3F))
+
+/*******************************************************************************
+ * Opcode types
+ ******************************************************************************/
+
+/* ...unregister client */
+#define XF_UNREGISTER __XF_OPCODE(0, 0, 0)
+
+/* ...register client at proxy */
+#define XF_REGISTER __XF_OPCODE(1, 0, 1)
+
+/* ...port routing command */
+#define XF_ROUTE __XF_OPCODE(1, 0, 2)
+
+/* ...port unrouting command */
+#define XF_UNROUTE __XF_OPCODE(1, 0, 3)
+
+/* ...shared buffer allocation */
+#define XF_ALLOC __XF_OPCODE(0, 0, 4)
+
+/* ...shared buffer freeing */
+#define XF_FREE __XF_OPCODE(0, 0, 5)
+
+/* ...set component parameters */
+#define XF_SET_PARAM __XF_OPCODE(1, 0, 6)
+
+/* ...get component parameters */
+#define XF_GET_PARAM __XF_OPCODE(1, 1, 7)
+
+/* ...input buffer reception */
+#define XF_EMPTY_THIS_BUFFER __XF_OPCODE(1, 0, 8)
+
+/* ...output buffer reception */
+#define XF_FILL_THIS_BUFFER __XF_OPCODE(0, 1, 9)
+
+/* ...flush specific port */
+#define XF_FLUSH __XF_OPCODE(0, 0, 10)
+
+/* ...start component operation */
+#define XF_START __XF_OPCODE(0, 0, 11)
+
+/* ...stop component operation */
+#define XF_STOP __XF_OPCODE(0, 0, 12)
+
+/* ...pause component operation */
+#define XF_PAUSE __XF_OPCODE(0, 0, 13)
+
+/* ...resume component operation */
+#define XF_RESUME __XF_OPCODE(0, 0, 14)
+
+/* ...resume component operation */
+#define XF_SUSPEND __XF_OPCODE(0, 0, 15)
+
+/* ...load lib for component operation */
+#define XF_LOAD_LIB __XF_OPCODE(0, 0, 16)
+
+/* ...unload lib for component operation */
+#define XF_UNLOAD_LIB __XF_OPCODE(0, 0, 17)
+
+/* ...component output eos operation */
+#define XF_OUTPUT_EOS __XF_OPCODE(0, 0, 18)
+
+/* ...total amount of supported decoder commands */
+#define __XF_OP_NUM 19
+
+#endif
diff --git a/sound/soc/fsl/fsl_dsp_xaf_api.c b/sound/soc/fsl/fsl_dsp_xaf_api.c
new file mode 100644
index 000000000000..05d1a1685989
--- /dev/null
+++ b/sound/soc/fsl/fsl_dsp_xaf_api.c
@@ -0,0 +1,490 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+//
+// Xtensa Audio Framework API for communication with DSP
+//
+// Copyright (C) 2017 Cadence Design Systems, Inc.
+// Copyright 2018 NXP
+
+#include "fsl_dsp.h"
+#include "fsl_dsp_xaf_api.h"
+
+/* ...send a command message to component */
+int xf_command(struct xf_client *client, struct xf_handle *handle,
+ u32 port, u32 opcode, void *buffer, u32 length)
+{
+ struct xf_proxy *proxy = handle->proxy;
+ struct xf_message msg;
+
+ /* ...fill-in message parameters */
+ msg.id = __XF_MSG_ID(__XF_AP_CLIENT(0, 0),
+ __XF_PORT_SPEC2(handle->id, port));
+ msg.id = XF_MSG_AP_FROM_USER(msg.id, client->id);
+ msg.opcode = opcode;
+ msg.length = length;
+ msg.buffer = buffer;
+ msg.ret = 0;
+
+ /* ...execute command synchronously */
+ return xf_cmd_send(proxy, msg.id, msg.opcode, msg.buffer, msg.length);
+}
+
+int xaf_comp_set_config(struct xf_client *client, struct xaf_comp *p_comp,
+ u32 num_param, void *p_param)
+{
+ struct xf_handle *p_handle;
+ struct xf_message msg;
+ struct xf_message *rmsg;
+ struct xf_set_param_msg *smsg;
+ struct xf_set_param_msg *param = (struct xf_set_param_msg *)p_param;
+ struct xf_proxy *proxy;
+ u32 i;
+
+ p_handle = &p_comp->handle;
+ proxy = p_handle->proxy;
+
+ /* ...set persistent stream characteristics */
+ smsg = xf_buffer_data(p_handle->aux);
+
+ for (i = 0; i < num_param; i++) {
+ smsg[i].id = param[i].id;
+ smsg[i].value = param[i].value;
+ }
+
+ /* ...set command parameters */
+ msg.id = __XF_MSG_ID(__XF_AP_CLIENT(0, 0),
+ __XF_PORT_SPEC2(p_handle->id, 0));
+ msg.id = XF_MSG_AP_FROM_USER(msg.id, client->id);
+ msg.opcode = XF_SET_PARAM;
+ msg.length = sizeof(*smsg) * num_param;
+ msg.buffer = smsg;
+ msg.ret = 0;
+
+ /* ...execute command synchronously */
+ rmsg = xf_cmd_send_recv_complete(client, proxy, msg.id, msg.opcode,
+ msg.buffer, msg.length, &client->work,
+ &client->compr_complete);
+
+ if(IS_ERR(rmsg))
+ return PTR_ERR(rmsg);
+ /* ...save received component global client-id */
+ /* TODO: review cleanup */
+ /* xf_msg_free(proxy, rmsg);
+ * xf_unlock(&proxy->lock);
+ */
+
+ /* ...make sure response is expected */
+ if ((rmsg->opcode != XF_SET_PARAM) || (rmsg->buffer != smsg)) {
+ return -EPIPE;
+ }
+
+ return 0;
+}
+
+int xaf_comp_get_config(struct xf_client *client, struct xaf_comp *p_comp,
+ u32 num_param, void *p_param)
+{
+
+ struct xf_handle *p_handle;
+ struct xf_message msg;
+ struct xf_message *rmsg;
+ struct xf_get_param_msg *smsg;
+ struct xf_get_param_msg *param = (struct xf_get_param_msg *)p_param;
+ struct xf_proxy *proxy;
+ u32 i;
+
+ p_handle = &p_comp->handle;
+ proxy = p_handle->proxy;
+
+ /* ...set persistent stream characteristics */
+ smsg = xf_buffer_data(p_handle->aux);
+
+ for (i = 0; i < num_param; i++)
+ smsg[i].id = param[i].id;
+
+
+ msg.id = __XF_MSG_ID(__XF_AP_CLIENT(0, 0),
+ __XF_PORT_SPEC2(p_handle->id, 0));
+ msg.id = XF_MSG_AP_FROM_USER(msg.id, client->id);
+ msg.opcode = XF_GET_PARAM;
+ msg.length = sizeof(*smsg) * num_param;
+ msg.buffer = smsg;
+ msg.ret = 0;
+
+ /* ...execute command synchronously */
+ rmsg = xf_cmd_send_recv_complete(client, proxy, msg.id, msg.opcode,
+ msg.buffer, msg.length, &client->work,
+ &client->compr_complete);
+
+ /* ...save received component global client-id */
+ if(IS_ERR(rmsg))
+ return PTR_ERR(rmsg);
+
+ /* TODO: review cleanup */
+ /* xf_msg_free(proxy, rmsg);
+ * xf_unlock(&proxy->lock); */
+
+ /* ...make sure response is expected */
+ if ((rmsg->opcode != (u32)XF_GET_PARAM) || (rmsg->buffer != smsg)) {
+ return -EPIPE;
+ }
+
+ for (i = 0; i < num_param; i++)
+ param[i].value = smsg[i].value;
+
+ return 0;
+}
+
+int xaf_comp_flush(struct xf_client *client, struct xaf_comp *p_comp)
+{
+
+ struct xf_handle *p_handle;
+ struct xf_proxy *proxy;
+ struct xf_message msg;
+ struct xf_message *rmsg;
+
+ p_handle = &p_comp->handle;
+ proxy = p_handle->proxy;
+
+ msg.id = __XF_MSG_ID(__XF_AP_CLIENT(0, 0),
+ __XF_PORT_SPEC2(p_handle->id, 0));
+ msg.id = XF_MSG_AP_FROM_USER(msg.id, client->id);
+ msg.opcode = XF_FLUSH;
+ msg.length = 0;
+ msg.buffer = NULL;
+ msg.ret = 0;
+
+
+ /* ...execute command synchronously */
+ rmsg = xf_cmd_send_recv_complete(client, proxy, msg.id, msg.opcode,
+ msg.buffer, msg.length, &client->work,
+ &client->compr_complete);
+
+ if(IS_ERR(rmsg))
+ return PTR_ERR(rmsg);
+
+ /* ...make sure response is expected */
+ if ((rmsg->opcode != (u32)XF_FLUSH) || rmsg->buffer) {
+ return -EPIPE;
+ }
+
+ return 0;
+}
+
+int xaf_comp_create(struct xf_client *client, struct xf_proxy *proxy,
+ struct xaf_comp *p_comp, int comp_type)
+{
+ struct fsl_dsp *dsp_priv = container_of(proxy, struct fsl_dsp, proxy);
+ char lib_path[200];
+ char lib_wrap_path[200];
+ struct xf_handle *p_handle;
+ struct xf_buffer *buf;
+ int ret = 0;
+ bool loadlib = true;
+
+ memset((void *)p_comp, 0, sizeof(struct xaf_comp));
+
+ strcpy(lib_path, "/usr/lib/imx-mm/audio-codec/dsp/");
+ strcpy(lib_wrap_path, "/usr/lib/imx-mm/audio-codec/dsp/");
+
+ p_handle = &p_comp->handle;
+
+ p_comp->comp_type = comp_type;
+
+ if (comp_type == RENDER_ESAI)
+ loadlib = false;
+
+ if (loadlib) {
+ p_comp->codec_lib.filename = lib_path;
+ p_comp->codec_wrap_lib.filename = lib_wrap_path;
+ p_comp->codec_lib.lib_type = DSP_CODEC_LIB;
+ }
+
+ switch (comp_type) {
+ case CODEC_MP3_DEC:
+ p_comp->dec_id = "audio-decoder/mp3";
+ strcat(lib_path, "lib_dsp_mp3_dec.so");
+ break;
+ case CODEC_AAC_DEC:
+ p_comp->dec_id = "audio-decoder/aac";
+ strcat(lib_path, "lib_dsp_aac_dec.so");
+ break;
+ case RENDER_ESAI:
+ p_comp->dec_id = "renderer/esai";
+ break;
+
+ default:
+ return -EINVAL;
+ break;
+ }
+
+ /* ...create decoder component instance (select core-0) */
+ ret = xf_open(client, proxy, p_handle, p_comp->dec_id, 0, NULL);
+ if (ret) {
+ dev_err(dsp_priv->dev, "create (%s) component error: %d\n",
+ p_comp->dec_id, ret);
+ return ret;
+ }
+
+ if (loadlib) {
+ strcat(lib_wrap_path, "lib_dsp_codec_wrap.so");
+ p_comp->codec_wrap_lib.lib_type = DSP_CODEC_WRAP_LIB;
+
+ /* ...load codec wrapper lib */
+ ret = xf_load_lib(client, p_handle, &p_comp->codec_wrap_lib);
+ if (ret) {
+ dev_err(dsp_priv->dev, "load codec wrap lib error\n");
+ goto err_wrap_load;
+ }
+
+ /* ...load codec lib */
+ ret = xf_load_lib(client, p_handle, &p_comp->codec_lib);
+ if (ret) {
+ dev_err(dsp_priv->dev, "load codec lib error\n");
+ goto err_codec_load;
+ }
+
+ /* ...allocate input buffer */
+ ret = xf_pool_alloc(client, proxy, 1, INBUF_SIZE,
+ XF_POOL_INPUT, &p_comp->inpool);
+ if (ret) {
+ dev_err(dsp_priv->dev, "alloc input buf error\n");
+ goto err_pool_alloc;
+ }
+
+ /* ...initialize input buffer pointer */
+ buf = xf_buffer_get(p_comp->inpool);
+ p_comp->inptr = xf_buffer_data(buf);
+ }
+
+ p_comp->active = true;
+
+ return ret;
+
+err_pool_alloc:
+ xf_unload_lib(client, p_handle, &p_comp->codec_lib);
+err_codec_load:
+ xf_unload_lib(client, p_handle, &p_comp->codec_wrap_lib);
+err_wrap_load:
+ xf_close(client, p_handle);
+
+ return ret;
+}
+
+int xaf_comp_delete(struct xf_client *client, struct xaf_comp *p_comp)
+{
+
+ struct xf_handle *p_handle;
+ bool loadlib = true;
+ u32 ret = 0;
+
+ if (!p_comp->active)
+ return ret;
+
+ /* mark component as unusable from this point */
+ p_comp->active = false;
+
+ if (p_comp->comp_type == RENDER_ESAI)
+ loadlib = false;
+
+ p_handle = &p_comp->handle;
+
+ if (loadlib) {
+ /* ...unload codec wrapper library */
+ xf_unload_lib(client, p_handle, &p_comp->codec_wrap_lib);
+
+ /* ...unload codec library */
+ xf_unload_lib(client, p_handle, &p_comp->codec_lib);
+
+ xf_pool_free(client, p_comp->inpool);
+ }
+
+ /* ...delete component */
+ xf_close(client, p_handle);
+
+ return ret;
+}
+
+int xaf_comp_process(struct xf_client *client, struct xaf_comp *p_comp, void *p_buf, u32 length, u32 flag)
+{
+ struct xf_handle *p_handle;
+ u32 ret = 0;
+
+ p_handle = &p_comp->handle;
+
+ switch (flag) {
+ case XF_FILL_THIS_BUFFER:
+ /* ...send message to component output port (port-id=1) */
+ ret = xf_command(client, p_handle, 1, XF_FILL_THIS_BUFFER,
+ p_buf, length);
+ break;
+ case XF_EMPTY_THIS_BUFFER:
+ /* ...send message to component input port (port-id=0) */
+ ret = xf_command(client, p_handle, 0, XF_EMPTY_THIS_BUFFER,
+ p_buf, length);
+ break;
+ default:
+ break;
+ }
+
+ return ret;
+}
+
+/* ...port binding function */
+int xf_route(struct xf_client *client, struct xf_handle *src, u32 src_port,
+ struct xf_handle *dst, u32 dst_port, u32 num, u32 size, u32 align)
+{
+ struct xf_proxy *proxy = src->proxy;
+ struct xf_buffer *b;
+ struct xf_route_port_msg *m;
+ struct xf_message msg;
+ struct xf_message *rmsg;
+
+ /* ...sanity checks - proxy pointers are same */
+ if (proxy != dst->proxy)
+ return -EINVAL;
+
+ /* ...buffer data is sane */
+ if (!(num && size && xf_is_power_of_two(align)))
+ return -EINVAL;
+
+ /* ...get control buffer */
+ if ((b = xf_buffer_get(proxy->aux)) == NULL)
+ return -EBUSY;
+
+ /* ...get message buffer */
+ m = xf_buffer_data(b);
+
+ /* ...fill-in message parameters */
+ m->src = __XF_PORT_SPEC2(src->id, src_port);
+ m->dst = __XF_PORT_SPEC2(dst->id, dst_port);
+ m->alloc_number = num;
+ m->alloc_size = size;
+ m->alloc_align = align;
+
+ /* ...set command parameters */
+ msg.id = __XF_MSG_ID(__XF_AP_PROXY(0),
+ __XF_PORT_SPEC2(src->id, src_port));
+ msg.id = XF_MSG_AP_FROM_USER(msg.id, client->id);
+ msg.opcode = XF_ROUTE;
+ msg.length = sizeof(*m);
+ msg.buffer = m;
+ msg.ret = 0;
+
+ /* ...execute command synchronously */
+ rmsg = xf_cmd_send_recv_complete(client, proxy, msg.id, msg.opcode,
+ msg.buffer, msg.length, &client->work,
+ &client->compr_complete);
+ if(IS_ERR(rmsg))
+ return PTR_ERR(rmsg);
+
+ /* ...save received component global client-id */
+ /* TODO: review cleanup */
+ /* xf_msg_free(proxy, rmsg);
+ * xf_unlock(&proxy->lock); */
+
+
+ /* ...synchronously execute command on remote DSP */
+ /* XF_CHK_API(xf_proxy_cmd_exec(proxy, &msg)); */
+
+ /* ...return buffer to proxy */
+ xf_buffer_put(b);
+
+ /* ...check result is successful */
+ /* XF_CHK_ERR(msg.opcode == XF_ROUTE, -ENOMEM); */
+
+ return 0;
+}
+
+/* ...port unbinding function */
+int xf_unroute(struct xf_client *client, struct xf_handle *src, u32 src_port)
+{
+ struct xf_proxy *proxy = src->proxy;
+ struct xf_buffer *b;
+ struct xf_unroute_port_msg *m;
+ struct xf_message msg;
+ struct xf_message *rmsg;
+ int r = 0;
+
+ /* ...get control buffer */
+ if((b = xf_buffer_get(proxy->aux)) == NULL)
+ return -EBUSY;
+
+ /* ...get message buffer */
+ m = xf_buffer_data(b);
+
+ /* ...fill-in message parameters */
+ m->src = __XF_PORT_SPEC2(src->id, src_port);
+
+ /* ...set command parameters */
+ msg.id = __XF_MSG_ID(__XF_AP_PROXY(0),
+ __XF_PORT_SPEC2(src->id, src_port));
+ msg.id = XF_MSG_AP_FROM_USER(msg.id, client->id);
+ msg.opcode = XF_UNROUTE;
+ msg.length = sizeof(*m);
+ msg.buffer = m;
+ msg.ret = 0;
+
+ /* ...execute command synchronously */
+ rmsg = xf_cmd_send_recv_complete(client, proxy, msg.id, msg.opcode,
+ msg.buffer, msg.length, &client->work,
+ &client->compr_complete);
+ if (IS_ERR(rmsg))
+ return PTR_ERR(rmsg);
+ /* ...save received component global client-id */
+
+ /*TODO: review cleanup */
+ /* xf_msg_free(proxy, rmsg); */
+ /* xf_unlock(&proxy->lock); */
+
+ /* ...return buffer to proxy */
+ xf_buffer_put(b);
+
+ return r;
+}
+
+int xaf_connect(struct xf_client *client,
+ struct xaf_comp *p_src,
+ struct xaf_comp *p_dest,
+ u32 num_buf,
+ u32 buf_length)
+{
+ /* ...connect p_src output port with p_dest input port */
+ return xf_route(client, &p_src->handle, 0, &p_dest->handle, 0,
+ num_buf, buf_length, 8);
+}
+
+int xaf_disconnect(struct xf_client *client, struct xaf_comp *p_comp)
+{
+ /* ...disconnect p_src output port with p_dest input port */
+ return xf_unroute(client, &p_comp->handle, 0);
+
+}
+
+int xaf_comp_add(struct xaf_pipeline *p_pipe, struct xaf_comp *p_comp)
+{
+ int ret = 0;
+
+ p_comp->next = p_pipe->comp_chain;
+ p_comp->pipeline = p_pipe;
+ p_pipe->comp_chain = p_comp;
+
+ return ret;
+}
+
+int xaf_pipeline_create(struct xaf_pipeline *p_pipe)
+{
+ int ret = 0;
+
+ memset(p_pipe, 0, sizeof(struct xaf_pipeline));
+
+ return ret;
+}
+
+int xaf_pipeline_delete(struct xaf_pipeline *p_pipe)
+{
+ int ret = 0;
+
+ memset(p_pipe, 0, sizeof(struct xaf_pipeline));
+
+ return ret;
+}
diff --git a/sound/soc/fsl/fsl_dsp_xaf_api.h b/sound/soc/fsl/fsl_dsp_xaf_api.h
new file mode 100644
index 000000000000..d6dc734000aa
--- /dev/null
+++ b/sound/soc/fsl/fsl_dsp_xaf_api.h
@@ -0,0 +1,136 @@
+/* SPDX-License-Identifier: (GPL-2.0+ OR MIT)*/
+/*
+ * Xtensa Audio Framework API for communication with DSP
+ *
+ * Copyright (C) 2017 Cadence Design Systems, Inc.
+ * Copyright 2018 NXP
+ */
+#ifndef FSL_DSP_XAF_API_H
+#define FSL_DSP_XAF_API_H
+
+#include "fsl_dsp_library_load.h"
+
+/* ...size of auxiliary pool for communication with DSP */
+#define XA_AUX_POOL_SIZE 32
+
+/* ...length of auxiliary pool messages */
+#define XA_AUX_POOL_MSG_LENGTH 128
+
+/* ...number of max input buffers */
+#define INBUF_SIZE 4096
+#define OUTBUF_SIZE 16384
+
+struct xaf_pipeline;
+
+struct xaf_info_s {
+ u32 opcode;
+ void *buf;
+ u32 length;
+ u32 ret;
+};
+
+struct xaf_comp {
+ struct xaf_comp *next;
+
+ struct xaf_pipeline *pipeline;
+ struct xf_handle handle;
+
+ const char *dec_id;
+ int comp_type;
+
+ struct xf_pool *inpool;
+ struct xf_pool *outpool;
+ void *inptr;
+ void *outptr;
+
+ struct lib_info codec_lib;
+ struct lib_info codec_wrap_lib;
+
+ int active; /* component fully initialized */
+};
+
+struct xaf_pipeline {
+ struct xaf_comp *comp_chain;
+
+ u32 input_eos;
+ u32 output_eos;
+};
+
+int xaf_comp_create(struct xf_client *client, struct xf_proxy *p_proxy,
+ struct xaf_comp *p_comp, int comp_type);
+int xaf_comp_delete(struct xf_client *client, struct xaf_comp *p_comp);
+int xaf_comp_flush(struct xf_client *client, struct xaf_comp *p_comp);
+
+int xaf_comp_set_config(struct xf_client *client,struct xaf_comp *p_comp,
+ u32 num_param, void *p_param);
+int xaf_comp_get_config(struct xf_client *client,struct xaf_comp *p_comp,
+ u32 num_param, void *p_param);
+
+int xaf_comp_add(struct xaf_pipeline *p_pipe, struct xaf_comp *p_comp);
+int xaf_comp_process(struct xf_client *client, struct xaf_comp *p_comp,
+ void *p_buf, u32 length, u32 flag);
+int xaf_comp_get_status(struct xaf_comp *p_comp, struct xaf_info_s *p_info);
+int xaf_comp_get_msg_count(struct xaf_comp *p_comp);
+
+int xaf_connect(struct xf_client *client,struct xaf_comp *p_src,
+ struct xaf_comp *p_dest, u32 num_buf, u32 buf_length);
+int xaf_disconnect(struct xf_client *client,struct xaf_comp *p_comp);
+
+int xaf_pipeline_create(struct xaf_pipeline *p_pipe);
+int xaf_pipeline_delete(struct xaf_pipeline *p_pipe);
+
+int xaf_pipeline_send_eos(struct xaf_pipeline *p_pipe);
+
+/* ...port routing command */
+struct __attribute__((__packed__)) xf_route_port_msg {
+ /* ...source port specification */
+ u32 src;
+ /* ...destination port specification */
+ u32 dst;
+ /* ...number of buffers to allocate */
+ u32 alloc_number;
+ /* ...length of buffer to allocate */
+ u32 alloc_size;
+ /* ...alignment restriction for a buffer */
+ u32 alloc_align;
+};
+
+/* ...port unrouting command */
+struct __attribute__((__packed__)) xf_unroute_port_msg {
+ /* ...source port specification */
+ u32 src;
+ /* ...destination port specification */
+ u32 dst;
+};
+
+/* ...check if non-zero value is a power-of-two */
+#define xf_is_power_of_two(v) (((v) & ((v) - 1)) == 0)
+
+/* ...component initialization parameter */
+struct __attribute__((__packed__)) xf_set_param_msg {
+ /* ...index of parameter passed to SET_CONFIG_PARAM call */
+ u32 id;
+ /* ...value of parameter */
+ u32 value;
+};
+
+/* ...message body (command/response) */
+struct __attribute__((__packed__)) xf_get_param_msg {
+ /* ...array of parameters requested */
+ u32 id;
+ /* ...array of parameters values */
+ u32 value;
+};
+
+/* ...renderer-specific configuration parameters */
+enum xa_config_param_renderer {
+ XA_RENDERER_CONFIG_PARAM_CB = 0,
+ XA_RENDERER_CONFIG_PARAM_STATE = 1,
+ XA_RENDERER_CONFIG_PARAM_PCM_WIDTH = 2,
+ XA_RENDERER_CONFIG_PARAM_CHANNELS = 3,
+ XA_RENDERER_CONFIG_PARAM_SAMPLE_RATE = 4,
+ XA_RENDERER_CONFIG_PARAM_FRAME_SIZE = 5,
+ XA_RENDERER_CONFIG_PARAM_NUM = 6,
+};
+
+#endif /* FSL_DSP_XAF_API_H */
diff --git a/sound/soc/fsl/fsl_esai.c b/sound/soc/fsl/fsl_esai.c
index 6152ae24772b..8bcd3f918a5a 100644
--- a/sound/soc/fsl/fsl_esai.c
+++ b/sound/soc/fsl/fsl_esai.c
@@ -1,7 +1,8 @@
/*
* Freescale ESAI ALSA SoC Digital Audio Interface (DAI) driver
*
- * Copyright (C) 2014 Freescale Semiconductor, Inc.
+ * Copyright (C) 2014-2016 Freescale Semiconductor, Inc.
+ * Copyright 2017 NXP
*
* 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
@@ -11,19 +12,33 @@
#include <linux/clk.h>
#include <linux/dmaengine.h>
#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
#include <linux/of_irq.h>
#include <linux/of_platform.h>
+#include <linux/dma-mapping.h>
+#include <linux/dmapool.h>
+#include <linux/pm_runtime.h>
#include <sound/dmaengine_pcm.h>
#include <sound/pcm_params.h>
#include "fsl_esai.h"
+#include "fsl_acm.h"
#include "imx-pcm.h"
+#include "fsl_dma_workaround.h"
#define FSL_ESAI_FORMATS (SNDRV_PCM_FMTBIT_S8 | \
SNDRV_PCM_FMTBIT_S16_LE | \
SNDRV_PCM_FMTBIT_S20_3LE | \
SNDRV_PCM_FMTBIT_S24_LE)
+struct fsl_esai_soc_data {
+ bool imx;
+ bool dma_workaround;
+ bool channel_swap_workaround;
+ bool constrain_period_size;
+};
+
/**
* fsl_esai: ESAI private data
*
@@ -49,12 +64,15 @@
struct fsl_esai {
struct snd_dmaengine_dai_dma_data dma_params_rx;
struct snd_dmaengine_dai_dma_data dma_params_tx;
+ struct snd_pcm_substream *substream[2];
struct platform_device *pdev;
struct regmap *regmap;
struct clk *coreclk;
struct clk *extalclk;
struct clk *fsysclk;
struct clk *spbaclk;
+ const struct fsl_esai_soc_data *soc;
+ struct fsl_dma_workaround_info *dma_info;
u32 fifo_depth;
u32 slot_width;
u32 slots;
@@ -64,11 +82,50 @@ struct fsl_esai {
u32 sck_rate[2];
bool hck_dir[2];
bool sck_div[2];
- bool slave_mode;
+ bool slave_mode[2];
bool synchronous;
char name[32];
};
+static struct fsl_esai_soc_data fsl_esai_vf610 = {
+ .imx = false,
+ .dma_workaround = false,
+ .channel_swap_workaround = true,
+ .constrain_period_size = false,
+};
+
+static struct fsl_esai_soc_data fsl_esai_imx35 = {
+ .imx = true,
+ .dma_workaround = false,
+ .channel_swap_workaround = true,
+ .constrain_period_size = false,
+};
+
+static struct fsl_esai_soc_data fsl_esai_imx6ull = {
+ .imx = true,
+ .dma_workaround = false,
+ .channel_swap_workaround = false,
+ .constrain_period_size = false,
+};
+
+/* In imx8qxp rev1, the dma request signal is not revert. For esai
+ * dma request is low valid, but edma assert it as high level valid.
+ * so we need to use GPT to transfer the dma request signal.
+ */
+static struct fsl_esai_soc_data fsl_esai_imx8qxp_v1 = {
+ .imx = true,
+ .dma_workaround = true,
+ .channel_swap_workaround = false,
+ .constrain_period_size = true,
+};
+
+static struct fsl_esai_soc_data fsl_esai_imx8qm = {
+ .imx = true,
+ .dma_workaround = false,
+ .channel_swap_workaround = false,
+ .constrain_period_size = true,
+};
+
static irqreturn_t esai_isr(int irq, void *devid)
{
struct fsl_esai *esai_priv = (struct fsl_esai *)devid;
@@ -173,7 +230,7 @@ static int fsl_esai_divisor_cal(struct snd_soc_dai *dai, bool tx, u32 ratio,
/* Calculate the fraction */
sub = sub * 1000 / ratio;
- if (sub < savesub) {
+ if (sub <= savesub) {
savesub = sub;
pm = i;
fp = j;
@@ -228,6 +285,21 @@ static int fsl_esai_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id,
unsigned long clk_rate;
int ret;
+ if (esai_priv->synchronous && !tx) {
+ switch (clk_id) {
+ case ESAI_HCKR_FSYS:
+ fsl_esai_set_dai_sysclk(dai, ESAI_HCKT_FSYS,
+ freq, dir);
+ break;
+ case ESAI_HCKR_EXTAL:
+ fsl_esai_set_dai_sysclk(dai, ESAI_HCKT_EXTAL,
+ freq, dir);
+ break;
+ default:
+ return -EINVAL;
+ }
+ }
+
/* Bypass divider settings if the requirement doesn't change */
if (freq == esai_priv->hck_rate[tx] && dir == esai_priv->hck_dir[tx])
return 0;
@@ -249,6 +321,7 @@ static int fsl_esai_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id,
break;
case ESAI_HCKT_EXTAL:
ecr |= ESAI_ECR_ETI;
+ break;
case ESAI_HCKR_EXTAL:
ecr |= ESAI_ECR_ERI;
break;
@@ -318,7 +391,7 @@ static int fsl_esai_set_bclk(struct snd_soc_dai *dai, bool tx, u32 freq)
int ret;
/* Don't apply for fully slave mode or unchanged bclk */
- if (esai_priv->slave_mode || esai_priv->sck_rate[tx] == freq)
+ if (esai_priv->slave_mode[tx] || esai_priv->sck_rate[tx] == freq)
return 0;
if (ratio * freq > hck_rate)
@@ -365,8 +438,8 @@ static int fsl_esai_set_dai_tdm_slot(struct snd_soc_dai *dai, u32 tx_mask,
esai_priv->slot_width = slot_width;
esai_priv->slots = slots;
- esai_priv->tx_mask = tx_mask;
- esai_priv->rx_mask = rx_mask;
+ esai_priv->tx_mask = tx_mask;
+ esai_priv->rx_mask = rx_mask;
return 0;
}
@@ -427,35 +500,62 @@ static int fsl_esai_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
return -EINVAL;
}
- esai_priv->slave_mode = false;
+ if (esai_priv->slave_mode[0] == esai_priv->slave_mode[1]) {
+ /* DAI clock master masks */
+ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+ case SND_SOC_DAIFMT_CBM_CFM:
+ esai_priv->slave_mode[0] = true;
+ esai_priv->slave_mode[1] = true;
+ break;
+ case SND_SOC_DAIFMT_CBS_CFM:
+ xccr |= ESAI_xCCR_xCKD;
+ break;
+ case SND_SOC_DAIFMT_CBM_CFS:
+ xccr |= ESAI_xCCR_xFSD;
+ break;
+ case SND_SOC_DAIFMT_CBS_CFS:
+ xccr |= ESAI_xCCR_xFSD | ESAI_xCCR_xCKD;
+ esai_priv->slave_mode[0] = false;
+ esai_priv->slave_mode[1] = false;
+ break;
+ default:
+ return -EINVAL;
+ }
- /* DAI clock master masks */
- switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
- case SND_SOC_DAIFMT_CBM_CFM:
- esai_priv->slave_mode = true;
- break;
- case SND_SOC_DAIFMT_CBS_CFM:
- xccr |= ESAI_xCCR_xCKD;
- break;
- case SND_SOC_DAIFMT_CBM_CFS:
- xccr |= ESAI_xCCR_xFSD;
- break;
- case SND_SOC_DAIFMT_CBS_CFS:
- xccr |= ESAI_xCCR_xFSD | ESAI_xCCR_xCKD;
- break;
- default:
- return -EINVAL;
+ mask = ESAI_xCCR_xCKP | ESAI_xCCR_xHCKP | ESAI_xCCR_xFSP |
+ ESAI_xCCR_xFSD | ESAI_xCCR_xCKD;
+ regmap_update_bits(esai_priv->regmap,
+ REG_ESAI_TCCR, mask, xccr);
+ regmap_update_bits(esai_priv->regmap,
+ REG_ESAI_RCCR, mask, xccr);
+
+ } else {
+
+ mask = ESAI_xCCR_xCKP | ESAI_xCCR_xHCKP | ESAI_xCCR_xFSP |
+ ESAI_xCCR_xFSD | ESAI_xCCR_xCKD;
+ if (esai_priv->slave_mode[0])
+ regmap_update_bits(esai_priv->regmap,
+ REG_ESAI_RCCR, mask, xccr);
+ else
+ regmap_update_bits(esai_priv->regmap, REG_ESAI_RCCR,
+ mask,
+ xccr | ESAI_xCCR_xFSD |
+ ESAI_xCCR_xCKD);
+
+ if (esai_priv->slave_mode[1])
+ regmap_update_bits(esai_priv->regmap,
+ REG_ESAI_TCCR, mask, xccr);
+ else
+ regmap_update_bits(esai_priv->regmap, REG_ESAI_TCCR,
+ mask,
+ xccr | ESAI_xCCR_xFSD |
+ ESAI_xCCR_xCKD);
}
mask = ESAI_xCR_xFSL | ESAI_xCR_xFSR | ESAI_xCR_xWA;
regmap_update_bits(esai_priv->regmap, REG_ESAI_TCR, mask, xcr);
regmap_update_bits(esai_priv->regmap, REG_ESAI_RCR, mask, xcr);
- mask = ESAI_xCCR_xCKP | ESAI_xCCR_xHCKP | ESAI_xCCR_xFSP |
- ESAI_xCCR_xFSD | ESAI_xCCR_xCKD;
- regmap_update_bits(esai_priv->regmap, REG_ESAI_TCCR, mask, xccr);
- regmap_update_bits(esai_priv->regmap, REG_ESAI_RCCR, mask, xccr);
-
return 0;
}
@@ -463,30 +563,8 @@ static int fsl_esai_startup(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai);
- int ret;
-
- /*
- * Some platforms might use the same bit to gate all three or two of
- * clocks, so keep all clocks open/close at the same time for safety
- */
- ret = clk_prepare_enable(esai_priv->coreclk);
- if (ret)
- return ret;
- if (!IS_ERR(esai_priv->spbaclk)) {
- ret = clk_prepare_enable(esai_priv->spbaclk);
- if (ret)
- goto err_spbaclk;
- }
- if (!IS_ERR(esai_priv->extalclk)) {
- ret = clk_prepare_enable(esai_priv->extalclk);
- if (ret)
- goto err_extalck;
- }
- if (!IS_ERR(esai_priv->fsysclk)) {
- ret = clk_prepare_enable(esai_priv->fsysclk);
- if (ret)
- goto err_fsysclk;
- }
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
if (!dai->active) {
/* Set synchronous mode */
@@ -501,18 +579,30 @@ static int fsl_esai_startup(struct snd_pcm_substream *substream,
ESAI_xCCR_xDC_MASK, ESAI_xCCR_xDC(2));
}
- return 0;
+ esai_priv->substream[substream->stream] = substream;
+
+ if (esai_priv->soc->constrain_period_size) {
+ if (tx)
+ snd_pcm_hw_constraint_step(substream->runtime, 0,
+ SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
+ esai_priv->dma_params_tx.maxburst);
+ else
+ snd_pcm_hw_constraint_step(substream->runtime, 0,
+ SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
+ esai_priv->dma_params_rx.maxburst);
+ }
-err_fsysclk:
- if (!IS_ERR(esai_priv->extalclk))
- clk_disable_unprepare(esai_priv->extalclk);
-err_extalck:
- if (!IS_ERR(esai_priv->spbaclk))
- clk_disable_unprepare(esai_priv->spbaclk);
-err_spbaclk:
- clk_disable_unprepare(esai_priv->coreclk);
+ if (esai_priv->soc->dma_workaround) {
+ snd_pcm_hw_constraint_minmax(substream->runtime,
+ SNDRV_PCM_HW_PARAM_CHANNELS, 1, 2);
+
+ if (!rtd->dai_link->be_hw_params_fixup)
+ snd_pcm_hw_constraint_minmax(substream->runtime,
+ SNDRV_PCM_HW_PARAM_RATE, 48000, 48000);
+ }
+
+ return 0;
- return ret;
}
static int fsl_esai_hw_params(struct snd_pcm_substream *substream,
@@ -528,16 +618,30 @@ static int fsl_esai_hw_params(struct snd_pcm_substream *substream,
u32 bclk, mask, val;
int ret;
+ if (esai_priv->soc->dma_workaround)
+ configure_gpt_dma(substream, esai_priv->dma_info);
+
/* Override slot_width if being specifically set */
if (esai_priv->slot_width)
slot_width = esai_priv->slot_width;
bclk = params_rate(params) * slot_width * esai_priv->slots;
- ret = fsl_esai_set_bclk(dai, tx, bclk);
+ ret = fsl_esai_set_bclk(dai, esai_priv->synchronous ? true : tx, bclk);
if (ret)
return ret;
+ if (esai_priv->synchronous && !tx) {
+ /* Use Normal mode to support monaural audio */
+ regmap_update_bits(esai_priv->regmap, REG_ESAI_TCR,
+ ESAI_xCR_xMOD_MASK, params_channels(params) > 1 ?
+ ESAI_xCR_xMOD_NETWORK : 0);
+
+ mask = ESAI_xCR_xSWS_MASK | ESAI_xCR_PADC;
+ val = ESAI_xCR_xSWS(slot_width, width) | ESAI_xCR_PADC;
+ regmap_update_bits(esai_priv->regmap, REG_ESAI_TCR, mask, val);
+ }
+
/* Use Normal mode to support monaural audio */
regmap_update_bits(esai_priv->regmap, REG_ESAI_xCR(tx),
ESAI_xCR_xMOD_MASK, params_channels(params) > 1 ?
@@ -571,13 +675,8 @@ static void fsl_esai_shutdown(struct snd_pcm_substream *substream,
{
struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai);
- if (!IS_ERR(esai_priv->fsysclk))
- clk_disable_unprepare(esai_priv->fsysclk);
- if (!IS_ERR(esai_priv->extalclk))
- clk_disable_unprepare(esai_priv->extalclk);
- if (!IS_ERR(esai_priv->spbaclk))
- clk_disable_unprepare(esai_priv->spbaclk);
- clk_disable_unprepare(esai_priv->coreclk);
+ esai_priv->substream[substream->stream] = NULL;
+
}
static int fsl_esai_trigger(struct snd_pcm_substream *substream, int cmd,
@@ -600,18 +699,6 @@ static int fsl_esai_trigger(struct snd_pcm_substream *substream, int cmd,
for (i = 0; tx && i < channels; i++)
regmap_write(esai_priv->regmap, REG_ESAI_ETDR, 0x0);
- /*
- * When set the TE/RE in the end of enablement flow, there
- * will be channel swap issue for multi data line case.
- * In order to workaround this issue, we switch the bit
- * enablement sequence to below sequence
- * 1) clear the xSMB & xSMA: which is done in probe and
- * stop state.
- * 2) set TE/RE
- * 3) set xSMB
- * 4) set xSMA: xSMA is the last one in this flow, which
- * will trigger esai to start.
- */
regmap_update_bits(esai_priv->regmap, REG_ESAI_xCR(tx),
tx ? ESAI_xCR_TE_MASK : ESAI_xCR_RE_MASK,
tx ? ESAI_xCR_TE(pins) : ESAI_xCR_RE(pins));
@@ -646,11 +733,23 @@ static int fsl_esai_trigger(struct snd_pcm_substream *substream, int cmd,
return 0;
}
+static int fsl_esai_hw_free(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *cpu_dai)
+{
+ struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(cpu_dai);
+
+ if (esai_priv->soc->dma_workaround)
+ clear_gpt_dma(substream, esai_priv->dma_info);
+
+ return 0;
+}
+
static const struct snd_soc_dai_ops fsl_esai_dai_ops = {
.startup = fsl_esai_startup,
.shutdown = fsl_esai_shutdown,
.trigger = fsl_esai_trigger,
.hw_params = fsl_esai_hw_params,
+ .hw_free = fsl_esai_hw_free,
.set_sysclk = fsl_esai_set_dai_sysclk,
.set_fmt = fsl_esai_set_dai_fmt,
.set_tdm_slot = fsl_esai_set_dai_tdm_slot,
@@ -809,14 +908,104 @@ static const struct regmap_config fsl_esai_regmap_config = {
.cache_type = REGCACHE_FLAT,
};
+static bool fsl_esai_check_xrun(struct snd_pcm_substream *substream)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+ struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(cpu_dai);
+ u32 saisr;
+
+ regmap_read(esai_priv->regmap, REG_ESAI_SAISR, &saisr);
+
+ return saisr & (ESAI_SAISR_TUE | ESAI_SAISR_ROE) ;
+}
+
+/*
+ *Here is ESAI underrun reset step:
+ *1. Read "TUE" and got TUE=1
+ *2. stop DMA.
+ *3. stop ESAI TX section.
+ *4. Set the transmitter section individual reset "TPR=1"
+ *5. Reset the ESAI Transmit FIFO (set ESAI_TFCR[1]=1).
+ *6. Config the control registers ESAI_TCCR and ESAI_TCR.config the Transmit FIFO register.
+ *7. clear "TPR"
+ *8. read "TUE"
+ *9. Prefill ESAI TX FIFO.
+ *10.Start DMA.
+ *11 Enable the ESAI
+ */
+static void fsl_esai_reset(struct snd_pcm_substream *substream, bool stop)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+ struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(cpu_dai);
+ unsigned long flags = 0;
+ u32 saisr;
+
+ if (stop)
+ imx_stop_lock_pcm_streams(esai_priv->substream, 2, &flags);
+
+ regmap_update_bits(esai_priv->regmap, REG_ESAI_ECR,
+ ESAI_ECR_ESAIEN_MASK | ESAI_ECR_ERST_MASK,
+ ESAI_ECR_ESAIEN | ESAI_ECR_ERST);
+ regmap_update_bits(esai_priv->regmap, REG_ESAI_ECR,
+ ESAI_ECR_ESAIEN_MASK | ESAI_ECR_ERST_MASK,
+ ESAI_ECR_ESAIEN);
+
+ regmap_update_bits(esai_priv->regmap, REG_ESAI_TCR, ESAI_xCR_xPR_MASK, ESAI_xCR_xPR);
+ regmap_update_bits(esai_priv->regmap, REG_ESAI_RCR, ESAI_xCR_xPR_MASK, ESAI_xCR_xPR);
+
+ regmap_update_bits(esai_priv->regmap, REG_ESAI_PRRC, ESAI_PRRC_PDC_MASK, 0);
+ regmap_update_bits(esai_priv->regmap, REG_ESAI_PCRC, ESAI_PCRC_PC_MASK, 0);
+
+ /*
+ * Add fifo reset here, because the regcache_sync will write one more data to ETDR.
+ * Which will cause channel shift.
+ */
+ regmap_update_bits(esai_priv->regmap, REG_ESAI_TFCR, ESAI_xFCR_xFR_MASK, ESAI_xFCR_xFR);
+ regmap_update_bits(esai_priv->regmap, REG_ESAI_RFCR, ESAI_xFCR_xFR_MASK, ESAI_xFCR_xFR);
+
+ regcache_mark_dirty(esai_priv->regmap);
+ regcache_sync(esai_priv->regmap);
+
+ regmap_update_bits(esai_priv->regmap, REG_ESAI_TFCR, ESAI_xFCR_xFR_MASK, 0);
+ regmap_update_bits(esai_priv->regmap, REG_ESAI_RFCR, ESAI_xFCR_xFR_MASK, 0);
+
+ regmap_update_bits(esai_priv->regmap, REG_ESAI_TCR, ESAI_xCR_xPR_MASK, 0);
+ regmap_update_bits(esai_priv->regmap, REG_ESAI_RCR, ESAI_xCR_xPR_MASK, 0);
+
+ regmap_update_bits(esai_priv->regmap, REG_ESAI_PRRC,
+ ESAI_PRRC_PDC_MASK, ESAI_PRRC_PDC(ESAI_GPIO));
+ regmap_update_bits(esai_priv->regmap, REG_ESAI_PCRC,
+ ESAI_PCRC_PC_MASK, ESAI_PCRC_PC(ESAI_GPIO));
+
+ regmap_read(esai_priv->regmap, REG_ESAI_SAISR, &saisr);
+
+ if (stop)
+ imx_start_unlock_pcm_streams(esai_priv->substream, 2, &flags);
+}
+
+static const struct of_device_id fsl_esai_dt_ids[] = {
+ { .compatible = "fsl,imx8qxp-v1-esai", .data = &fsl_esai_imx8qxp_v1 },
+ { .compatible = "fsl,imx8qm-esai", .data = &fsl_esai_imx8qm },
+ { .compatible = "fsl,imx6ull-esai", .data = &fsl_esai_imx6ull },
+ { .compatible = "fsl,imx35-esai", .data = &fsl_esai_imx35 },
+ { .compatible = "fsl,vf610-esai", .data = &fsl_esai_vf610 },
+ {}
+};
+MODULE_DEVICE_TABLE(of, fsl_esai_dt_ids);
+
static int fsl_esai_probe(struct platform_device *pdev)
{
struct device_node *np = pdev->dev.of_node;
+ const struct of_device_id *of_id;
struct fsl_esai *esai_priv;
struct resource *res;
const uint32_t *iprop;
void __iomem *regs;
int irq, ret;
+ u32 buffer_size;
+ unsigned long irqflag = 0;
esai_priv = devm_kzalloc(&pdev->dev, sizeof(*esai_priv), GFP_KERNEL);
if (!esai_priv)
@@ -825,6 +1014,12 @@ static int fsl_esai_probe(struct platform_device *pdev)
esai_priv->pdev = pdev;
strncpy(esai_priv->name, np->name, sizeof(esai_priv->name) - 1);
+ of_id = of_match_device(fsl_esai_dt_ids, &pdev->dev);
+ if (!of_id || !of_id->data)
+ return -EINVAL;
+
+ esai_priv->soc = of_id->data;
+
/* Get the addresses and IRQ */
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
regs = devm_ioremap_resource(&pdev->dev, res);
@@ -867,7 +1062,11 @@ static int fsl_esai_probe(struct platform_device *pdev)
return irq;
}
- ret = devm_request_irq(&pdev->dev, irq, esai_isr, 0,
+ /* ESAI shared interrupt */
+ if (of_property_read_bool(np, "shared-interrupt"))
+ irqflag = IRQF_SHARED;
+
+ ret = devm_request_irq(&pdev->dev, irq, esai_isr, irqflag,
esai_priv->name, esai_priv);
if (ret) {
dev_err(&pdev->dev, "failed to claim irq %u\n", irq);
@@ -877,9 +1076,6 @@ static int fsl_esai_probe(struct platform_device *pdev)
/* Set a default slot number */
esai_priv->slots = 2;
- /* Set a default master/slave state */
- esai_priv->slave_mode = true;
-
/* Determine the FIFO depth */
iprop = of_get_property(np, "fsl,fifo-depth", NULL);
if (iprop)
@@ -887,14 +1083,40 @@ static int fsl_esai_probe(struct platform_device *pdev)
else
esai_priv->fifo_depth = 64;
+ esai_priv->dma_params_rx.chan_name = "rx";
+ esai_priv->dma_params_tx.chan_name = "tx";
esai_priv->dma_params_tx.maxburst = 16;
esai_priv->dma_params_rx.maxburst = 16;
esai_priv->dma_params_tx.addr = res->start + REG_ESAI_ETDR;
esai_priv->dma_params_rx.addr = res->start + REG_ESAI_ERDR;
+ /* From imx6ull, the channel swap issue in underrun/overrun is
+ * fixed in hardware. So remove the workaround.
+ */
+ if (esai_priv->soc->channel_swap_workaround) {
+ esai_priv->dma_params_tx.check_xrun = fsl_esai_check_xrun;
+ esai_priv->dma_params_rx.check_xrun = fsl_esai_check_xrun;
+ esai_priv->dma_params_tx.device_reset = fsl_esai_reset;
+ esai_priv->dma_params_rx.device_reset = fsl_esai_reset;
+ }
+
esai_priv->synchronous =
of_property_read_bool(np, "fsl,esai-synchronous");
+ if (!esai_priv->synchronous) {
+ if (of_property_read_bool(pdev->dev.of_node, "fsl,txm-rxs")) {
+ /* 0 -- rx, 1 -- tx */
+ esai_priv->slave_mode[0] = true;
+ esai_priv->slave_mode[1] = false;
+ }
+
+ if (of_property_read_bool(pdev->dev.of_node, "fsl,txs-rxm")) {
+ /* 0 -- rx, 1 -- tx */
+ esai_priv->slave_mode[0] = false;
+ esai_priv->slave_mode[1] = true;
+ }
+ }
+
/* Implement full symmetry for synchronous mode */
if (esai_priv->synchronous) {
fsl_esai_dai.symmetric_rates = 1;
@@ -921,9 +1143,6 @@ static int fsl_esai_probe(struct platform_device *pdev)
return ret;
}
- esai_priv->tx_mask = 0xFFFFFFFF;
- esai_priv->rx_mask = 0xFFFFFFFF;
-
/* Clear the TSMA, TSMB, RSMA, RSMB */
regmap_write(esai_priv->regmap, REG_ESAI_TSMA, 0);
regmap_write(esai_priv->regmap, REG_ESAI_TSMB, 0);
@@ -937,37 +1156,70 @@ static int fsl_esai_probe(struct platform_device *pdev)
return ret;
}
- ret = imx_pcm_dma_init(pdev, IMX_ESAI_DMABUF_SIZE);
+ if (of_property_read_u32(np, "fsl,dma-buffer-size", &buffer_size))
+ buffer_size = IMX_ESAI_DMABUF_SIZE;
+
+ /* workaround for esai issue in imx8qxp */
+ if (esai_priv->soc->dma_workaround)
+ esai_priv->dma_info =
+ fsl_dma_workaround_alloc_info("tcd_pool_esai",
+ &pdev->dev,
+ "nxp,imx8qm-acm",
+ FSL_DMA_WORKAROUND_ESAI);
+
+ pm_runtime_enable(&pdev->dev);
+ regcache_cache_only(esai_priv->regmap, true);
+
+ ret = imx_pcm_platform_register(&pdev->dev);
if (ret)
dev_err(&pdev->dev, "failed to init imx pcm dma: %d\n", ret);
return ret;
}
-static const struct of_device_id fsl_esai_dt_ids[] = {
- { .compatible = "fsl,imx35-esai", },
- { .compatible = "fsl,vf610-esai", },
- {}
-};
-MODULE_DEVICE_TABLE(of, fsl_esai_dt_ids);
-
-#ifdef CONFIG_PM_SLEEP
-static int fsl_esai_suspend(struct device *dev)
+static int fsl_esai_remove(struct platform_device *pdev)
{
- struct fsl_esai *esai = dev_get_drvdata(dev);
+ struct fsl_esai *esai_priv = dev_get_drvdata(&pdev->dev);
- regcache_cache_only(esai->regmap, true);
- regcache_mark_dirty(esai->regmap);
+ if (esai_priv->soc->dma_workaround)
+ fsl_dma_workaround_free_info(esai_priv->dma_info, &pdev->dev);
+
+ pm_runtime_disable(&pdev->dev);
return 0;
}
-static int fsl_esai_resume(struct device *dev)
+#ifdef CONFIG_PM
+static int fsl_esai_runtime_resume(struct device *dev)
{
struct fsl_esai *esai = dev_get_drvdata(dev);
int ret;
+ /*
+ * Some platforms might use the same bit to gate all three or two of
+ * clocks, so keep all clocks open/close at the same time for safety
+ */
+ ret = clk_prepare_enable(esai->coreclk);
+ if (ret)
+ return ret;
+ if (!IS_ERR(esai->spbaclk)) {
+ ret = clk_prepare_enable(esai->spbaclk);
+ if (ret)
+ goto disable_core_clk;
+ }
+ if (!IS_ERR(esai->extalclk)) {
+ ret = clk_prepare_enable(esai->extalclk);
+ if (ret)
+ goto disable_spba_clk;
+ }
+ if (!IS_ERR(esai->fsysclk)) {
+ ret = clk_prepare_enable(esai->fsysclk);
+ if (ret)
+ goto disable_extal_clk;
+ }
+
regcache_cache_only(esai->regmap, false);
+ regcache_mark_dirty(esai->regmap);
/* FIFO reset for safety */
regmap_update_bits(esai->regmap, REG_ESAI_TFCR,
@@ -977,22 +1229,57 @@ static int fsl_esai_resume(struct device *dev)
ret = regcache_sync(esai->regmap);
if (ret)
- return ret;
+ goto disable_fsys_clk;
/* FIFO reset done */
regmap_update_bits(esai->regmap, REG_ESAI_TFCR, ESAI_xFCR_xFR, 0);
regmap_update_bits(esai->regmap, REG_ESAI_RFCR, ESAI_xFCR_xFR, 0);
return 0;
+
+disable_fsys_clk:
+ if (!IS_ERR(esai->fsysclk))
+ clk_disable_unprepare(esai->fsysclk);
+disable_extal_clk:
+ if (!IS_ERR(esai->extalclk))
+ clk_disable_unprepare(esai->extalclk);
+disable_spba_clk:
+ if (!IS_ERR(esai->spbaclk))
+ clk_disable_unprepare(esai->spbaclk);
+disable_core_clk:
+ clk_disable_unprepare(esai->coreclk);
+
+ return ret;
+}
+
+static int fsl_esai_runtime_suspend(struct device *dev)
+{
+ struct fsl_esai *esai = dev_get_drvdata(dev);
+
+ regcache_cache_only(esai->regmap, true);
+
+ if (!IS_ERR(esai->fsysclk))
+ clk_disable_unprepare(esai->fsysclk);
+ if (!IS_ERR(esai->extalclk))
+ clk_disable_unprepare(esai->extalclk);
+ if (!IS_ERR(esai->spbaclk))
+ clk_disable_unprepare(esai->spbaclk);
+ clk_disable_unprepare(esai->coreclk);
+
+ return 0;
}
-#endif /* CONFIG_PM_SLEEP */
+#endif
static const struct dev_pm_ops fsl_esai_pm_ops = {
- SET_SYSTEM_SLEEP_PM_OPS(fsl_esai_suspend, fsl_esai_resume)
+ SET_RUNTIME_PM_OPS(fsl_esai_runtime_suspend,
+ fsl_esai_runtime_resume,
+ NULL)
+ SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, pm_runtime_force_resume)
};
static struct platform_driver fsl_esai_driver = {
.probe = fsl_esai_probe,
+ .remove = fsl_esai_remove,
.driver = {
.name = "fsl-esai-dai",
.pm = &fsl_esai_pm_ops,
diff --git a/sound/soc/fsl/fsl_hdmi.c b/sound/soc/fsl/fsl_hdmi.c
new file mode 100644
index 000000000000..05e9a7c1c1d9
--- /dev/null
+++ b/sound/soc/fsl/fsl_hdmi.c
@@ -0,0 +1,750 @@
+/*
+ * ALSA SoC HDMI Audio Layer for Freescale i.MX
+ *
+ * Copyright (C) 2011-2014 Freescale Semiconductor, Inc.
+ *
+ * Some code from patch_hdmi.c
+ * Copyright (c) 2008-2010 Intel Corporation. All rights reserved.
+ * Copyright (c) 2006 ATI Technologies Inc.
+ * Copyright (c) 2008 NVIDIA Corp. All rights reserved.
+ * Copyright (c) 2008 Wei Ni <wni@nvidia.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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/dma-mapping.h>
+#include <linux/slab.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/mfd/mxc-hdmi-core.h>
+#include <sound/pcm.h>
+#include <sound/soc.h>
+#include <sound/asoundef.h>
+#include <sound/hdmi-codec.h>
+
+#include <video/mxc_hdmi.h>
+
+#include "imx-hdmi.h"
+
+
+static struct mxc_edid_cfg edid_cfg;
+
+static u32 playback_rates[HDMI_MAX_RATES];
+static u32 playback_sample_size[HDMI_MAX_SAMPLE_SIZE];
+static u32 playback_channels[HDMI_MAX_CHANNEL_CONSTRAINTS];
+
+static struct snd_pcm_hw_constraint_list playback_constraint_rates;
+static struct snd_pcm_hw_constraint_list playback_constraint_bits;
+static struct snd_pcm_hw_constraint_list playback_constraint_channels;
+
+#ifdef DEBUG
+static void dumpregs(struct snd_soc_dai *dai)
+{
+ u32 n, cts;
+
+ cts = (hdmi_readb(HDMI_AUD_CTS3) << 16) |
+ (hdmi_readb(HDMI_AUD_CTS2) << 8) |
+ hdmi_readb(HDMI_AUD_CTS1);
+
+ n = (hdmi_readb(HDMI_AUD_N3) << 16) |
+ (hdmi_readb(HDMI_AUD_N2) << 8) |
+ hdmi_readb(HDMI_AUD_N1);
+
+ dev_dbg(dai->dev, "HDMI_PHY_CONF0 0x%02x\n",
+ hdmi_readb(HDMI_PHY_CONF0));
+ dev_dbg(dai->dev, "HDMI_MC_CLKDIS 0x%02x\n",
+ hdmi_readb(HDMI_MC_CLKDIS));
+ dev_dbg(dai->dev, "HDMI_AUD_N[1-3] 0x%06x (%d)\n",
+ n, n);
+ dev_dbg(dai->dev, "HDMI_AUD_CTS[1-3] 0x%06x (%d)\n",
+ cts, cts);
+ dev_dbg(dai->dev, "HDMI_FC_AUDSCONF 0x%02x\n",
+ hdmi_readb(HDMI_FC_AUDSCONF));
+}
+#else
+static void dumpregs(struct snd_soc_dai *dai) {}
+#endif
+
+enum cea_speaker_placement {
+ FL = (1 << 0), /* Front Left */
+ FC = (1 << 1), /* Front Center */
+ FR = (1 << 2), /* Front Right */
+ FLC = (1 << 3), /* Front Left Center */
+ FRC = (1 << 4), /* Front Right Center */
+ RL = (1 << 5), /* Rear Left */
+ RC = (1 << 6), /* Rear Center */
+ RR = (1 << 7), /* Rear Right */
+ RLC = (1 << 8), /* Rear Left Center */
+ RRC = (1 << 9), /* Rear Right Center */
+ LFE = (1 << 10), /* Low Frequency Effect */
+ FLW = (1 << 11), /* Front Left Wide */
+ FRW = (1 << 12), /* Front Right Wide */
+ FLH = (1 << 13), /* Front Left High */
+ FCH = (1 << 14), /* Front Center High */
+ FRH = (1 << 15), /* Front Right High */
+ TC = (1 << 16), /* Top Center */
+};
+
+/*
+ * EDID SA bits in the CEA Speaker Allocation data block
+ */
+static int edid_speaker_allocation_bits[] = {
+ [0] = FL | FR,
+ [1] = LFE,
+ [2] = FC,
+ [3] = RL | RR,
+ [4] = RC,
+ [5] = FLC | FRC,
+ [6] = RLC | RRC,
+ [7] = FLW | FRW,
+ [8] = FLH | FRH,
+ [9] = TC,
+ [10] = FCH,
+};
+
+struct cea_channel_speaker_allocation {
+ int ca_index;
+ int speakers[8];
+
+ /* Derived values, just for convenience */
+ int channels;
+ int spk_mask;
+};
+
+/*
+ * This is an ordered list!
+ *
+ * The preceding ones have better chances to be selected by
+ * hdmi_channel_allocation().
+ */
+static struct cea_channel_speaker_allocation channel_allocations[] = {
+ /* channel: 7 6 5 4 3 2 1 0 */
+ { .ca_index = 0x00, .speakers = { 0, 0, 0, 0, 0, 0, FR, FL },},
+ /* 2.1 */
+ { .ca_index = 0x01, .speakers = { 0, 0, 0, 0, 0, LFE, FR, FL },},
+ /* Dolby Surround */
+ { .ca_index = 0x02, .speakers = { 0, 0, 0, 0, FC, 0, FR, FL },},
+ { .ca_index = 0x03, .speakers = { 0, 0, 0, 0, FC, LFE, FR, FL },},
+ { .ca_index = 0x04, .speakers = { 0, 0, 0, RC, 0, 0, FR, FL },},
+ { .ca_index = 0x05, .speakers = { 0, 0, 0, RC, 0, LFE, FR, FL },},
+ { .ca_index = 0x06, .speakers = { 0, 0, 0, RC, FC, 0, FR, FL },},
+ { .ca_index = 0x07, .speakers = { 0, 0, 0, RC, FC, LFE, FR, FL },},
+ { .ca_index = 0x08, .speakers = { 0, 0, RR, RL, 0, 0, FR, FL },},
+ { .ca_index = 0x09, .speakers = { 0, 0, RR, RL, 0, LFE, FR, FL },},
+ { .ca_index = 0x0a, .speakers = { 0, 0, RR, RL, FC, 0, FR, FL },},
+ /* surround51 */
+ { .ca_index = 0x0b, .speakers = { 0, 0, RR, RL, FC, LFE, FR, FL },},
+ { .ca_index = 0x0c, .speakers = { 0, RC, RR, RL, 0, 0, FR, FL },},
+ { .ca_index = 0x0d, .speakers = { 0, RC, RR, RL, 0, LFE, FR, FL },},
+ { .ca_index = 0x0e, .speakers = { 0, RC, RR, RL, FC, 0, FR, FL },},
+ /* 6.1 */
+ { .ca_index = 0x0f, .speakers = { 0, RC, RR, RL, FC, LFE, FR, FL },},
+ { .ca_index = 0x10, .speakers = { RRC, RLC, RR, RL, 0, 0, FR, FL },},
+ { .ca_index = 0x11, .speakers = { RRC, RLC, RR, RL, 0, LFE, FR, FL },},
+ { .ca_index = 0x12, .speakers = { RRC, RLC, RR, RL, FC, 0, FR, FL },},
+ /* surround71 */
+ { .ca_index = 0x13, .speakers = { RRC, RLC, RR, RL, FC, LFE, FR, FL },},
+ { .ca_index = 0x14, .speakers = { FRC, FLC, 0, 0, 0, 0, FR, FL },},
+ { .ca_index = 0x15, .speakers = { FRC, FLC, 0, 0, 0, LFE, FR, FL },},
+ { .ca_index = 0x16, .speakers = { FRC, FLC, 0, 0, FC, 0, FR, FL },},
+ { .ca_index = 0x17, .speakers = { FRC, FLC, 0, 0, FC, LFE, FR, FL },},
+ { .ca_index = 0x18, .speakers = { FRC, FLC, 0, RC, 0, 0, FR, FL },},
+ { .ca_index = 0x19, .speakers = { FRC, FLC, 0, RC, 0, LFE, FR, FL },},
+ { .ca_index = 0x1a, .speakers = { FRC, FLC, 0, RC, FC, 0, FR, FL },},
+ { .ca_index = 0x1b, .speakers = { FRC, FLC, 0, RC, FC, LFE, FR, FL },},
+ { .ca_index = 0x1c, .speakers = { FRC, FLC, RR, RL, 0, 0, FR, FL },},
+ { .ca_index = 0x1d, .speakers = { FRC, FLC, RR, RL, 0, LFE, FR, FL },},
+ { .ca_index = 0x1e, .speakers = { FRC, FLC, RR, RL, FC, 0, FR, FL },},
+ { .ca_index = 0x1f, .speakers = { FRC, FLC, RR, RL, FC, LFE, FR, FL },},
+ { .ca_index = 0x20, .speakers = { 0, FCH, RR, RL, FC, 0, FR, FL },},
+ { .ca_index = 0x21, .speakers = { 0, FCH, RR, RL, FC, LFE, FR, FL },},
+ { .ca_index = 0x22, .speakers = { TC, 0, RR, RL, FC, 0, FR, FL },},
+ { .ca_index = 0x23, .speakers = { TC, 0, RR, RL, FC, LFE, FR, FL },},
+ { .ca_index = 0x24, .speakers = { FRH, FLH, RR, RL, 0, 0, FR, FL },},
+ { .ca_index = 0x25, .speakers = { FRH, FLH, RR, RL, 0, LFE, FR, FL },},
+ { .ca_index = 0x26, .speakers = { FRW, FLW, RR, RL, 0, 0, FR, FL },},
+ { .ca_index = 0x27, .speakers = { FRW, FLW, RR, RL, 0, LFE, FR, FL },},
+ { .ca_index = 0x28, .speakers = { TC, RC, RR, RL, FC, 0, FR, FL },},
+ { .ca_index = 0x29, .speakers = { TC, RC, RR, RL, FC, LFE, FR, FL },},
+ { .ca_index = 0x2a, .speakers = { FCH, RC, RR, RL, FC, 0, FR, FL },},
+ { .ca_index = 0x2b, .speakers = { FCH, RC, RR, RL, FC, LFE, FR, FL },},
+ { .ca_index = 0x2c, .speakers = { TC, FCH, RR, RL, FC, 0, FR, FL },},
+ { .ca_index = 0x2d, .speakers = { TC, FCH, RR, RL, FC, LFE, FR, FL },},
+ { .ca_index = 0x2e, .speakers = { FRH, FLH, RR, RL, FC, 0, FR, FL },},
+ { .ca_index = 0x2f, .speakers = { FRH, FLH, RR, RL, FC, LFE, FR, FL },},
+ { .ca_index = 0x30, .speakers = { FRW, FLW, RR, RL, FC, 0, FR, FL },},
+ { .ca_index = 0x31, .speakers = { FRW, FLW, RR, RL, FC, LFE, FR, FL },},
+};
+
+/* Compute derived values in channel_allocations[] */
+static void init_channel_allocations(void)
+{
+ struct cea_channel_speaker_allocation *p;
+ int i, j;
+
+ for (i = 0; i < ARRAY_SIZE(channel_allocations); i++) {
+ p = channel_allocations + i;
+ p->channels = 0;
+ p->spk_mask = 0;
+ for (j = 0; j < ARRAY_SIZE(p->speakers); j++)
+ if (p->speakers[j]) {
+ p->channels++;
+ p->spk_mask |= p->speakers[j];
+ }
+ }
+}
+
+/*
+ * The transformation takes two steps:
+ *
+ * speaker_alloc => (edid_speaker_allocation_bits[]) => spk_mask
+ * spk_mask => (channel_allocations[]) => CA
+ *
+ * TODO: it could select the wrong CA from multiple candidates.
+*/
+static int hdmi_channel_allocation(int channels)
+{
+ int spk_mask = 0, ca = 0, i, tmpchn, tmpspk;
+
+ /* CA defaults to 0 for basic stereo audio */
+ if (channels <= 2)
+ return 0;
+
+ /*
+ * Expand EDID's speaker allocation mask
+ *
+ * EDID tells the speaker mask in a compact(paired) form,
+ * expand EDID's notions to match the ones used by Audio InfoFrame.
+ */
+ for (i = 0; i < ARRAY_SIZE(edid_speaker_allocation_bits); i++) {
+ if (edid_cfg.speaker_alloc & (1 << i))
+ spk_mask |= edid_speaker_allocation_bits[i];
+ }
+
+ /* Search for the first working match in the CA table */
+ for (i = 0; i < ARRAY_SIZE(channel_allocations); i++) {
+ tmpchn = channel_allocations[i].channels;
+ tmpspk = channel_allocations[i].spk_mask;
+
+ if (channels == tmpchn && (spk_mask & tmpspk) == tmpspk) {
+ ca = channel_allocations[i].ca_index;
+ break;
+ }
+ }
+
+ return ca;
+}
+
+static void hdmi_set_audio_infoframe(unsigned int channels)
+{
+ u8 audiconf0, audiconf2;
+
+ /*
+ * From CEA-861-D spec:
+ * HDMI requires the CT, SS and SF fields to be set to 0 ("Refer
+ * to Stream Header") as these items are carried in the audio stream.
+ *
+ * So we only set the CC and CA fields.
+ */
+ audiconf0 = ((channels - 1) << HDMI_FC_AUDICONF0_CC_OFFSET) &
+ HDMI_FC_AUDICONF0_CC_MASK;
+
+ audiconf2 = hdmi_channel_allocation(channels);
+
+ hdmi_writeb(audiconf0, HDMI_FC_AUDICONF0);
+ hdmi_writeb(0, HDMI_FC_AUDICONF1);
+ hdmi_writeb(audiconf2, HDMI_FC_AUDICONF2);
+ hdmi_writeb(0, HDMI_FC_AUDICONF3);
+}
+
+static int cea_audio_rates[HDMI_MAX_RATES] = {
+ 32000, 44100, 48000, 88200, 96000, 176400, 192000,
+};
+
+static void fsl_hdmi_get_playback_rates(void)
+{
+ int i, count = 0;
+ u8 rates;
+
+ /* Always assume basic audio support */
+ rates = edid_cfg.sample_rates | 0x7;
+
+ for (i = 0 ; i < HDMI_MAX_RATES ; i++)
+ if ((rates & (1 << i)) != 0)
+ playback_rates[count++] = cea_audio_rates[i];
+
+ playback_constraint_rates.list = playback_rates;
+ playback_constraint_rates.count = count;
+
+ for (i = 0 ; i < playback_constraint_rates.count ; i++)
+ pr_debug("%s: constraint = %d Hz\n", __func__, playback_rates[i]);
+}
+
+static void fsl_hdmi_get_playback_sample_size(void)
+{
+ int i = 0;
+
+ /* Always assume basic audio support */
+ playback_sample_size[i++] = 16;
+
+ if (edid_cfg.sample_sizes & 0x4)
+ playback_sample_size[i++] = 24;
+
+ playback_constraint_bits.list = playback_sample_size;
+ playback_constraint_bits.count = i;
+
+ for (i = 0 ; i < playback_constraint_bits.count ; i++)
+ pr_debug("%s: constraint = %d bits\n", __func__, playback_sample_size[i]);
+}
+
+static void fsl_hdmi_get_playback_channels(void)
+{
+ int channels = 2, i = 0;
+
+ /* Always assume basic audio support */
+ playback_channels[i++] = channels;
+ channels += 2;
+
+ while ((i < HDMI_MAX_CHANNEL_CONSTRAINTS) &&
+ (channels <= edid_cfg.max_channels)) {
+ playback_channels[i++] = channels;
+ channels += 2;
+ }
+
+ playback_constraint_channels.list = playback_channels;
+ playback_constraint_channels.count = i;
+
+ for (i = 0 ; i < playback_constraint_channels.count ; i++)
+ pr_debug("%s: constraint = %d channels\n", __func__, playback_channels[i]);
+}
+
+static int fsl_hdmi_update_constraints(struct snd_pcm_substream *substream)
+{
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ int ret;
+
+ hdmi_get_edid_cfg(&edid_cfg);
+
+ fsl_hdmi_get_playback_rates();
+ ret = snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
+ &playback_constraint_rates);
+ if (ret)
+ return ret;
+
+ fsl_hdmi_get_playback_sample_size();
+ ret = snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_SAMPLE_BITS,
+ &playback_constraint_bits);
+ if (ret)
+ return ret;
+
+ fsl_hdmi_get_playback_channels();
+ ret = snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
+ &playback_constraint_channels);
+ if (ret)
+ return ret;
+
+ ret = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+static int fsl_hdmi_soc_startup(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ struct imx_hdmi *hdmi_data = snd_soc_dai_get_drvdata(dai);
+ int ret;
+
+ clk_prepare_enable(hdmi_data->mipi_core_clk);
+ clk_prepare_enable(hdmi_data->isfr_clk);
+ clk_prepare_enable(hdmi_data->iahb_clk);
+
+ dev_dbg(dai->dev, "%s hdmi clks: mipi_core: %d isfr:%d iahb:%d\n", __func__,
+ (int)clk_get_rate(hdmi_data->mipi_core_clk),
+ (int)clk_get_rate(hdmi_data->isfr_clk),
+ (int)clk_get_rate(hdmi_data->iahb_clk));
+
+ ret = fsl_hdmi_update_constraints(substream);
+ if (ret < 0)
+ return ret;
+
+ /* Indicates the subpacket represents a flatline sample */
+ hdmi_audio_writeb(FC_AUDSCONF, AUD_PACKET_SAMPFIT, 0x0);
+
+ return 0;
+}
+
+static void fsl_hdmi_soc_shutdown(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ struct imx_hdmi *hdmi_data = snd_soc_dai_get_drvdata(dai);
+
+ clk_disable_unprepare(hdmi_data->iahb_clk);
+ clk_disable_unprepare(hdmi_data->isfr_clk);
+ clk_disable_unprepare(hdmi_data->mipi_core_clk);
+}
+
+static int fsl_hdmi_soc_prepare(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ struct snd_pcm_runtime *runtime = substream->runtime;
+
+ hdmi_set_audio_infoframe(runtime->channels);
+ hdmi_audio_writeb(FC_AUDSCONF, AUD_PACKET_LAYOUT,
+ (runtime->channels > 2) ? 0x1 : 0x0);
+ hdmi_set_sample_rate(runtime->rate);
+ dumpregs(dai);
+
+ return 0;
+}
+
+static struct snd_soc_dai_ops fsl_hdmi_soc_dai_ops = {
+ .startup = fsl_hdmi_soc_startup,
+ .shutdown = fsl_hdmi_soc_shutdown,
+ .prepare = fsl_hdmi_soc_prepare,
+};
+
+/* IEC60958 status functions */
+static int fsl_hdmi_iec_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
+{
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
+ uinfo->count = 1;
+
+ return 0;
+}
+
+
+static int fsl_hdmi_iec_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *uvalue)
+{
+ int i;
+
+ for (i = 0 ; i < 4 ; i++)
+ uvalue->value.iec958.status[i] = iec_header.status[i];
+
+ return 0;
+}
+
+static int fsl_hdmi_iec_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *uvalue)
+{
+ int i;
+
+ /* Do not allow professional mode */
+ if (uvalue->value.iec958.status[0] & IEC958_AES0_PROFESSIONAL)
+ return -EPERM;
+
+ for (i = 0 ; i < 4 ; i++) {
+ iec_header.status[i] = uvalue->value.iec958.status[i];
+ pr_debug("%s status[%d]=0x%02x\n", __func__, i, iec_header.status[i]);
+ }
+
+ return 0;
+}
+
+static int fsl_hdmi_channels_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
+{
+ hdmi_get_edid_cfg(&edid_cfg);
+ fsl_hdmi_get_playback_channels();
+
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+ uinfo->count = playback_constraint_channels.count;
+
+ return 0;
+}
+
+
+static int fsl_hdmi_channels_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *uvalue)
+{
+ int i;
+ hdmi_get_edid_cfg(&edid_cfg);
+ fsl_hdmi_get_playback_channels();
+
+ for (i = 0 ; i < playback_constraint_channels.count ; i++)
+ uvalue->value.integer.value[i] = playback_channels[i];
+
+ return 0;
+}
+
+static int fsl_hdmi_rates_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
+{
+ hdmi_get_edid_cfg(&edid_cfg);
+ fsl_hdmi_get_playback_rates();
+
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+ uinfo->count = playback_constraint_rates.count;
+
+ return 0;
+}
+
+static int fsl_hdmi_rates_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *uvalue)
+{
+ int i;
+ hdmi_get_edid_cfg(&edid_cfg);
+ fsl_hdmi_get_playback_rates();
+
+ for (i = 0 ; i < playback_constraint_rates.count ; i++)
+ uvalue->value.integer.value[i] = playback_rates[i];
+
+ return 0;
+}
+
+static int fsl_hdmi_formats_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
+{
+ hdmi_get_edid_cfg(&edid_cfg);
+ fsl_hdmi_get_playback_sample_size();
+
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+ uinfo->count = playback_constraint_bits.count;
+
+ return 0;
+}
+
+static int fsl_hdmi_formats_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *uvalue)
+{
+ int i;
+ hdmi_get_edid_cfg(&edid_cfg);
+ fsl_hdmi_get_playback_sample_size();
+
+ for (i = 0 ; i < playback_constraint_bits.count ; i++)
+ uvalue->value.integer.value[i] = playback_sample_size[i];
+
+ return 0;
+}
+
+static struct snd_kcontrol_new fsl_hdmi_ctrls[] = {
+ /* Status cchanel controller */
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, DEFAULT),
+ .access = SNDRV_CTL_ELEM_ACCESS_READ |
+ SNDRV_CTL_ELEM_ACCESS_WRITE |
+ SNDRV_CTL_ELEM_ACCESS_VOLATILE,
+ .info = fsl_hdmi_iec_info,
+ .get = fsl_hdmi_iec_get,
+ .put = fsl_hdmi_iec_put,
+ },
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "HDMI Support Channels",
+ .access = SNDRV_CTL_ELEM_ACCESS_READ |
+ SNDRV_CTL_ELEM_ACCESS_VOLATILE,
+ .info = fsl_hdmi_channels_info,
+ .get = fsl_hdmi_channels_get,
+ },
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "HDMI Support Rates",
+ .access = SNDRV_CTL_ELEM_ACCESS_READ |
+ SNDRV_CTL_ELEM_ACCESS_VOLATILE,
+ .info = fsl_hdmi_rates_info,
+ .get = fsl_hdmi_rates_get,
+ },
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "HDMI Support Formats",
+ .access = SNDRV_CTL_ELEM_ACCESS_READ |
+ SNDRV_CTL_ELEM_ACCESS_VOLATILE,
+ .info = fsl_hdmi_formats_info,
+ .get = fsl_hdmi_formats_get,
+ },
+};
+
+static int fsl_hdmi_soc_dai_probe(struct snd_soc_dai *dai)
+{
+ int ret;
+
+ init_channel_allocations();
+
+ ret = snd_soc_add_dai_controls(dai, fsl_hdmi_ctrls,
+ ARRAY_SIZE(fsl_hdmi_ctrls));
+ if (ret)
+ dev_warn(dai->dev, "failed to add dai controls\n");
+
+ return 0;
+}
+
+static struct snd_soc_dai_driver fsl_hdmi_dai = {
+ .probe = &fsl_hdmi_soc_dai_probe,
+ .playback = {
+ .channels_min = 2,
+ .channels_max = 8,
+ .rates = MXC_HDMI_RATES_PLAYBACK,
+ .formats = MXC_HDMI_FORMATS_PLAYBACK,
+ },
+ .ops = &fsl_hdmi_soc_dai_ops,
+};
+
+static const struct snd_soc_component_driver fsl_hdmi_component = {
+ .name = "fsl-hdmi",
+};
+
+/* HDMI audio codec callbacks */
+static int fsl_hdmi_audio_hw_params(struct device *dev, void *data,
+ struct hdmi_codec_daifmt *fmt,
+ struct hdmi_codec_params *hparms)
+{
+ dev_dbg(dev, "[%s]: %u Hz, %d bit, %d channels\n", __func__,
+ hparms->sample_rate, hparms->sample_width, hparms->cea.channels);
+
+ return 0;
+}
+
+static void fsl_hdmi_audio_shutdown(struct device *dev, void *data)
+{
+ dev_dbg(dev, "[%s]\n", __func__);
+}
+
+static const struct hdmi_codec_ops fsl_hdmi_audio_codec_ops = {
+ .hw_params = fsl_hdmi_audio_hw_params,
+ .audio_shutdown = fsl_hdmi_audio_shutdown,
+};
+
+static struct hdmi_codec_pdata codec_data = {
+ .ops = &fsl_hdmi_audio_codec_ops,
+ .i2s = 1,
+ .max_i2s_channels = 8,
+};
+
+static int fsl_hdmi_dai_probe(struct platform_device *pdev)
+{
+ struct device_node *np = pdev->dev.of_node;
+ struct imx_hdmi *hdmi_data;
+ int ret = 0;
+
+ if (!np)
+ return -ENODEV;
+
+ if (!hdmi_get_registered()) {
+ dev_err(&pdev->dev, "failed to probe. Load HDMI-video first.\n");
+ return -ENOMEM;
+ }
+
+ hdmi_data = devm_kzalloc(&pdev->dev, sizeof(*hdmi_data), GFP_KERNEL);
+ if (!hdmi_data) {
+ dev_err(&pdev->dev, "failed to alloc hdmi_data\n");
+ return -ENOMEM;
+ }
+
+ hdmi_data->pdev = pdev;
+
+ memcpy(&hdmi_data->cpu_dai_drv, &fsl_hdmi_dai, sizeof(fsl_hdmi_dai));
+ hdmi_data->cpu_dai_drv.name = np->name;
+
+ hdmi_data->mipi_core_clk = devm_clk_get(&pdev->dev, "mipi_core");
+ if (IS_ERR(hdmi_data->mipi_core_clk)) {
+ ret = PTR_ERR(hdmi_data->mipi_core_clk);
+ dev_err(&pdev->dev, "failed to get mipi core clk: %d\n", ret);
+ return -EINVAL;
+ }
+
+ hdmi_data->isfr_clk = devm_clk_get(&pdev->dev, "hdmi_isfr");
+ if (IS_ERR(hdmi_data->isfr_clk)) {
+ ret = PTR_ERR(hdmi_data->isfr_clk);
+ dev_err(&pdev->dev, "failed to get HDMI isfr clk: %d\n", ret);
+ return -EINVAL;
+ }
+
+ hdmi_data->iahb_clk = devm_clk_get(&pdev->dev, "hdmi_iahb");
+ if (IS_ERR(hdmi_data->iahb_clk)) {
+ ret = PTR_ERR(hdmi_data->iahb_clk);
+ dev_err(&pdev->dev, "failed to get HDMI ahb clk: %d\n", ret);
+ return -EINVAL;
+ }
+
+ dev_set_drvdata(&pdev->dev, hdmi_data);
+ ret = snd_soc_register_component(&pdev->dev, &fsl_hdmi_component,
+ &hdmi_data->cpu_dai_drv, 1);
+ if (ret) {
+ dev_err(&pdev->dev, "register DAI failed\n");
+ return ret;
+ }
+
+ hdmi_data->codec_dev = platform_device_register_data(&pdev->dev,
+ HDMI_CODEC_DRV_NAME, PLATFORM_DEVID_NONE,
+ &codec_data, sizeof(codec_data));
+ if (IS_ERR(hdmi_data->codec_dev)) {
+ dev_err(&pdev->dev, "failed to register HDMI audio codec\n");
+ ret = PTR_ERR(hdmi_data->codec_dev);
+ goto fail;
+ }
+
+ hdmi_data->dma_dev = platform_device_alloc("imx-hdmi-audio", -1);
+ if (!hdmi_data->dma_dev) {
+ ret = -ENOMEM;
+ goto fail_dma;
+ }
+
+ platform_set_drvdata(hdmi_data->dma_dev, hdmi_data);
+
+ ret = platform_device_add(hdmi_data->dma_dev);
+ if (ret) {
+ platform_device_put(hdmi_data->dma_dev);
+ goto fail_dma;
+ }
+
+ return 0;
+
+fail_dma:
+ platform_device_unregister(hdmi_data->codec_dev);
+fail:
+ snd_soc_unregister_component(&pdev->dev);
+
+ return ret;
+}
+
+static int fsl_hdmi_dai_remove(struct platform_device *pdev)
+{
+ struct imx_hdmi *hdmi_data = platform_get_drvdata(pdev);
+
+ platform_device_unregister(hdmi_data->dma_dev);
+ platform_device_unregister(hdmi_data->codec_dev);
+ snd_soc_unregister_component(&pdev->dev);
+
+ return 0;
+}
+
+static const struct of_device_id fsl_hdmi_dai_dt_ids[] = {
+ { .compatible = "fsl,imx6dl-hdmi-audio", },
+ { .compatible = "fsl,imx6q-hdmi-audio", },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, fsl_hdmi_dai_dt_ids);
+
+static struct platform_driver fsl_hdmi_driver = {
+ .probe = fsl_hdmi_dai_probe,
+ .remove = fsl_hdmi_dai_remove,
+ .driver = {
+ .name = "fsl-hdmi-dai",
+ .owner = THIS_MODULE,
+ .of_match_table = fsl_hdmi_dai_dt_ids,
+ },
+};
+module_platform_driver(fsl_hdmi_driver);
+
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("IMX HDMI TX DAI");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:fsl-hdmi-dai");
diff --git a/sound/soc/fsl/fsl_micfil.c b/sound/soc/fsl/fsl_micfil.c
new file mode 100644
index 000000000000..7bb8d4cb5f71
--- /dev/null
+++ b/sound/soc/fsl/fsl_micfil.c
@@ -0,0 +1,2456 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright 2018 NXP
+
+#include <linux/atomic.h>
+#include <linux/clk.h>
+#include <linux/device.h>
+#include <linux/interrupt.h>
+#include <linux/kobject.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/of_platform.h>
+#include <linux/pm_runtime.h>
+#include <linux/regmap.h>
+#include <linux/sysfs.h>
+#include <linux/types.h>
+#include <sound/dmaengine_pcm.h>
+#include <sound/pcm.h>
+#include <sound/soc.h>
+#include <sound/tlv.h>
+#include <sound/core.h>
+
+#include "fsl_micfil.h"
+#include "imx-pcm.h"
+
+#define FSL_MICFIL_RATES SNDRV_PCM_RATE_8000_48000
+#define FSL_MICFIL_FORMATS (SNDRV_PCM_FMTBIT_S16_LE)
+
+struct fsl_micfil {
+ struct platform_device *pdev;
+ struct regmap *regmap;
+ const struct fsl_micfil_soc_data *soc;
+ struct clk *mclk;
+ struct clk *clk_src[MICFIL_CLK_SRC_NUM];
+ struct snd_dmaengine_dai_dma_data dma_params_rx;
+ struct kobject *hwvad_kobject;
+ unsigned int vad_channel;
+ unsigned int dataline;
+ char name[32];
+ int irq[MICFIL_IRQ_LINES];
+ unsigned int mclk_streams;
+ int quality; /*QUALITY 2-0 bits */
+ bool slave_mode;
+ int channel_gain[8];
+ int clk_src_id;
+ int vad_sound_gain;
+ int vad_noise_gain;
+ int vad_input_gain;
+ int vad_frame_time;
+ int vad_init_time;
+ int vad_init_mode;
+ int vad_nfil_adjust;
+ int vad_hpf;
+ int vad_zcd_th;
+ int vad_zcd_auto;
+ int vad_zcd_en;
+ int vad_zcd_adj;
+ int vad_rate_index;
+ atomic_t recording_state;
+ atomic_t hwvad_state;
+};
+
+struct fsl_micfil_soc_data {
+ unsigned int fifos;
+ unsigned int fifo_depth;
+ unsigned int dataline;
+ bool imx;
+};
+
+static char *envp[] = {
+ "EVENT=PDM_VOICE_DETECT",
+ NULL,
+};
+
+static struct fsl_micfil_soc_data fsl_micfil_imx8mm = {
+ .imx = true,
+ .fifos = 8,
+ .fifo_depth = 8,
+ .dataline = 0xf,
+};
+
+static const struct of_device_id fsl_micfil_dt_ids[] = {
+ { .compatible = "fsl,imx8mm-micfil", .data = &fsl_micfil_imx8mm },
+ {}
+};
+MODULE_DEVICE_TABLE(of, fsl_micfil_dt_ids);
+
+/* Table 5. Quality Modes
+ * Medium 0 0 0
+ * High 0 0 1
+ * Very Low 2 1 0 0
+ * Very Low 1 1 0 1
+ * Very Low 0 1 1 0
+ * Low 1 1 1
+ */
+static const char * const micfil_quality_select_texts[] = {
+ "Medium", "High",
+ "N/A", "N/A",
+ "VLow2", "VLow1",
+ "VLow0", "Low",
+};
+
+static const char * const micfil_hwvad_init_mode[] = {
+ "Envelope mode", "Energy mode",
+};
+
+static const char * const micfil_hwvad_hpf_texts[] = {
+ "Filter bypass",
+ "Cut-off @1750Hz",
+ "Cut-off @215Hz",
+ "Cut-off @102Hz",
+};
+
+static const char * const micfil_hwvad_zcd_enable[] = {
+ "OFF", "ON",
+};
+
+static const char * const micfil_hwvad_zcdauto_enable[] = {
+ "OFF", "ON",
+};
+
+static const char * const micfil_hwvad_noise_decimation[] = {
+ "Disabled", "Enabled",
+};
+
+/* when adding new rate text, also add it to the
+ * micfil_hwvad_rate_ints
+ */
+static const char * const micfil_hwvad_rate[] = {
+ "48KHz", "44.1KHz",
+};
+
+static const int micfil_hwvad_rate_ints[] = {
+ 48000, 44100,
+};
+
+static const char * const micfil_clk_src_texts[] = {
+ "Auto", "AudioPLL1", "AudioPLL2", "ExtClk3",
+};
+
+static const struct soc_enum fsl_micfil_quality_enum =
+ SOC_ENUM_SINGLE(REG_MICFIL_CTRL2,
+ MICFIL_CTRL2_QSEL_SHIFT,
+ ARRAY_SIZE(micfil_quality_select_texts),
+ micfil_quality_select_texts);
+static const struct soc_enum fsl_micfil_hwvad_init_mode_enum =
+ SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(micfil_hwvad_init_mode),
+ micfil_hwvad_init_mode);
+static const struct soc_enum fsl_micfil_hwvad_hpf_enum =
+ SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(micfil_hwvad_hpf_texts),
+ micfil_hwvad_hpf_texts);
+static const struct soc_enum fsl_micfil_hwvad_zcd_enum =
+ SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(micfil_hwvad_zcd_enable),
+ micfil_hwvad_zcd_enable);
+static const struct soc_enum fsl_micfil_hwvad_zcdauto_enum =
+ SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(micfil_hwvad_zcdauto_enable),
+ micfil_hwvad_zcd_enable);
+static const struct soc_enum fsl_micfil_hwvad_ndec_enum =
+ SOC_ENUM_SINGLE(REG_MICFIL_VAD0_NCONFIG,
+ MICFIL_VAD0_NCONFIG_NOREN_SHIFT,
+ ARRAY_SIZE(micfil_hwvad_noise_decimation),
+ micfil_hwvad_noise_decimation);
+static const struct soc_enum fsl_micfil_hwvad_rate_enum =
+ SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(micfil_hwvad_rate),
+ micfil_hwvad_rate);
+static const struct soc_enum fsl_micfil_clk_src_enum =
+ SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(micfil_clk_src_texts),
+ micfil_clk_src_texts);
+
+static int micfil_put_clk_src(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol);
+ struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
+ unsigned int *item = ucontrol->value.enumerated.item;
+ struct fsl_micfil *micfil = snd_soc_component_get_drvdata(comp);
+ int val = snd_soc_enum_item_to_val(e, item[0]);
+
+ micfil->clk_src_id = val;
+
+ return 0;
+}
+
+static int micfil_get_clk_src(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol);
+ struct fsl_micfil *micfil = snd_soc_component_get_drvdata(comp);
+
+ ucontrol->value.enumerated.item[0] = micfil->clk_src_id;
+
+ return 0;
+}
+
+static int hwvad_put_init_mode(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol);
+ struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
+ unsigned int *item = ucontrol->value.enumerated.item;
+ struct fsl_micfil *micfil = snd_soc_component_get_drvdata(comp);
+ int val = snd_soc_enum_item_to_val(e, item[0]);
+
+ /* 0 - Envelope-based Mode
+ * 1 - Energy-based Mode
+ */
+ micfil->vad_init_mode = val;
+ return 0;
+}
+
+static int hwvad_get_init_mode(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol);
+ struct fsl_micfil *micfil = snd_soc_component_get_drvdata(comp);
+
+ ucontrol->value.enumerated.item[0] = micfil->vad_init_mode;
+
+ return 0;
+}
+
+static int hwvad_put_hpf(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol);
+ struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
+ unsigned int *item = ucontrol->value.enumerated.item;
+ struct fsl_micfil *micfil = snd_soc_component_get_drvdata(comp);
+ int val = snd_soc_enum_item_to_val(e, item[0]);
+
+ /* 00 - HPF Bypass
+ * 01 - Cut-off frequency 1750Hz
+ * 10 - Cut-off frequency 215Hz
+ * 11 - Cut-off frequency 102Hz
+ */
+ micfil->vad_hpf = val;
+
+ return 0;
+}
+
+static int hwvad_get_hpf(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol);
+ struct fsl_micfil *micfil = snd_soc_component_get_drvdata(comp);
+
+ ucontrol->value.enumerated.item[0] = micfil->vad_hpf;
+
+ return 0;
+}
+
+static int hwvad_put_zcd_en(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol);
+ struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
+ unsigned int *item = ucontrol->value.enumerated.item;
+ struct fsl_micfil *micfil = snd_soc_component_get_drvdata(comp);
+ int val = snd_soc_enum_item_to_val(e, item[0]);
+
+ micfil->vad_zcd_en = val;
+
+ return 0;
+}
+
+static int hwvad_get_zcd_en(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol);
+ struct fsl_micfil *micfil = snd_soc_component_get_drvdata(comp);
+
+ ucontrol->value.enumerated.item[0] = micfil->vad_zcd_en;
+
+ return 0;
+}
+
+static int hwvad_put_rate(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol);
+ struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
+ unsigned int *item = ucontrol->value.enumerated.item;
+ struct fsl_micfil *micfil = snd_soc_component_get_drvdata(comp);
+ int val = snd_soc_enum_item_to_val(e, item[0]);
+
+ micfil->vad_rate_index = val;
+
+ return 0;
+}
+
+static int hwvad_get_rate(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol);
+ struct fsl_micfil *micfil = snd_soc_component_get_drvdata(comp);
+
+ ucontrol->value.enumerated.item[0] = micfil->vad_rate_index;
+
+ return 0;
+}
+
+static int hwvad_put_zcd_auto(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol);
+ struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
+ unsigned int *item = ucontrol->value.enumerated.item;
+ struct fsl_micfil *micfil = snd_soc_component_get_drvdata(comp);
+ int val = snd_soc_enum_item_to_val(e, item[0]);
+
+ micfil->vad_zcd_auto = val;
+
+ return 0;
+}
+
+static int hwvad_get_zcd_auto(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol);
+ struct fsl_micfil *micfil = snd_soc_component_get_drvdata(comp);
+
+ ucontrol->value.enumerated.item[0] = micfil->vad_zcd_auto;
+
+ return 0;
+}
+
+static int gain_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
+{
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+ uinfo->count = 1;
+ uinfo->value.integer.min = 0;
+ uinfo->value.integer.max = 0xf;
+
+ return 0;
+}
+
+static int put_channel_gain(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol);
+ struct fsl_micfil *micfil = snd_soc_component_get_drvdata(comp);
+ struct soc_mixer_control *mc =
+ (struct soc_mixer_control *)kcontrol->private_value;
+ unsigned int shift = mc->shift;
+ int index = shift / 4;
+ int val = ucontrol->value.integer.value[0];
+ int remapped_value;
+ int ret;
+ u32 reg_val;
+
+ /* a value remapping must be done since the gain field have
+ * the following meaning:
+ * * 0 : no gain
+ * * 1 - 7 : +1 to +7 bits gain
+ * * 8 - 15 : -8 to -1 bits gain
+ * After the remapp, the scale should start from -8 to +7
+ */
+
+ micfil->channel_gain[index] = val;
+
+ remapped_value = (val - 8) & 0xF;
+
+ reg_val = remapped_value << shift;
+
+ ret = snd_soc_component_update_bits(comp,
+ REG_MICFIL_OUT_CTRL,
+ 0xF << shift,
+ reg_val);
+
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
+static int get_channel_gain(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol);
+ struct fsl_micfil *micfil = snd_soc_component_get_drvdata(comp);
+ struct soc_mixer_control *mc =
+ (struct soc_mixer_control *)kcontrol->private_value;
+ int index;
+
+ /* gain bitfield is 4 bits wide */
+ index = mc->shift / 4;
+
+ ucontrol->value.enumerated.item[0] = micfil->channel_gain[index];
+
+ return 0;
+}
+
+static int hwvad_put_input_gain(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol);
+ struct fsl_micfil *micfil = snd_soc_component_get_drvdata(comp);
+
+ micfil->vad_input_gain = ucontrol->value.integer.value[0];
+
+ return 0;
+}
+
+static int hwvad_get_input_gain(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol);
+ struct fsl_micfil *micfil = snd_soc_component_get_drvdata(comp);
+
+ ucontrol->value.enumerated.item[0] = micfil->vad_input_gain;
+
+ return 0;
+}
+
+static int hwvad_put_sound_gain(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol);
+ struct fsl_micfil *micfil = snd_soc_component_get_drvdata(comp);
+
+ micfil->vad_sound_gain = ucontrol->value.integer.value[0];
+
+ return 0;
+}
+
+static int hwvad_get_sound_gain(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol);
+ struct fsl_micfil *micfil = snd_soc_component_get_drvdata(comp);
+
+ ucontrol->value.enumerated.item[0] = micfil->vad_sound_gain;
+
+ return 0;
+}
+
+static int hwvad_put_noise_gain(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol);
+ struct fsl_micfil *micfil = snd_soc_component_get_drvdata(comp);
+
+ micfil->vad_noise_gain = ucontrol->value.integer.value[0];
+
+ return 0;
+}
+
+static int hwvad_get_noise_gain(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol);
+ struct fsl_micfil *micfil = snd_soc_component_get_drvdata(comp);
+
+ ucontrol->value.enumerated.item[0] = micfil->vad_noise_gain;
+
+ return 0;
+}
+
+static int hwvad_framet_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
+{
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+ uinfo->count = 1;
+ uinfo->value.integer.min = 1;
+ uinfo->value.integer.max = 64;
+
+ return 0;
+}
+
+static int hwvad_put_frame_time(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol);
+ struct fsl_micfil *micfil = snd_soc_component_get_drvdata(comp);
+
+ micfil->vad_frame_time = ucontrol->value.integer.value[0];
+
+ return 0;
+}
+
+static int hwvad_get_frame_time(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol);
+ struct fsl_micfil *micfil = snd_soc_component_get_drvdata(comp);
+
+ ucontrol->value.enumerated.item[0] = micfil->vad_frame_time;
+
+ return 0;
+}
+
+static int hwvad_initt_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
+{
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+ uinfo->count = 1;
+ uinfo->value.integer.min = 1;
+ uinfo->value.integer.max = 32;
+
+ return 0;
+}
+
+static int hwvad_put_init_time(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol);
+ struct fsl_micfil *micfil = snd_soc_component_get_drvdata(comp);
+
+ micfil->vad_init_time = ucontrol->value.integer.value[0];
+
+ return 0;
+}
+
+static int hwvad_get_init_time(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol);
+ struct fsl_micfil *micfil = snd_soc_component_get_drvdata(comp);
+
+ ucontrol->value.enumerated.item[0] = micfil->vad_init_time;
+
+ return 0;
+}
+
+static int hwvad_nfiladj_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
+{
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+ uinfo->count = 1;
+ uinfo->value.integer.min = 1;
+ uinfo->value.integer.max = 32;
+
+ return 0;
+}
+
+static int hwvad_put_nfil_adjust(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol);
+ struct fsl_micfil *micfil = snd_soc_component_get_drvdata(comp);
+
+ micfil->vad_nfil_adjust = ucontrol->value.integer.value[0];
+
+ return 0;
+}
+
+static int hwvad_get_nfil_adjust(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol);
+ struct fsl_micfil *micfil = snd_soc_component_get_drvdata(comp);
+
+ ucontrol->value.enumerated.item[0] = micfil->vad_nfil_adjust;
+
+ return 0;
+}
+
+static int hwvad_zcdth_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
+{
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+ uinfo->count = 1;
+ uinfo->value.integer.min = 1;
+ uinfo->value.integer.max = 1024;
+
+ return 0;
+}
+
+static int hwvad_put_zcd_th(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol);
+ struct fsl_micfil *micfil = snd_soc_component_get_drvdata(comp);
+
+ micfil->vad_zcd_th = ucontrol->value.integer.value[0];
+
+ return 0;
+}
+
+static int hwvad_get_zcd_th(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol);
+ struct fsl_micfil *micfil = snd_soc_component_get_drvdata(comp);
+
+ ucontrol->value.enumerated.item[0] = micfil->vad_zcd_th;
+
+ return 0;
+}
+
+static int hwvad_zcdadj_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
+{
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+ uinfo->count = 1;
+ uinfo->value.integer.min = 1;
+ uinfo->value.integer.max = 16;
+
+ return 0;
+}
+
+static int hwvad_put_zcd_adj(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol);
+ struct fsl_micfil *micfil = snd_soc_component_get_drvdata(comp);
+
+ micfil->vad_zcd_adj = ucontrol->value.integer.value[0];
+
+ return 0;
+}
+
+static int hwvad_get_zcd_adj(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol);
+ struct fsl_micfil *micfil = snd_soc_component_get_drvdata(comp);
+
+ ucontrol->value.enumerated.item[0] = micfil->vad_zcd_adj;
+
+ return 0;
+}
+
+static DECLARE_TLV_DB_SCALE(gain_tlv, 0, 100, 0);
+
+static const struct snd_kcontrol_new fsl_micfil_snd_controls[] = {
+ SOC_SINGLE_RANGE_EXT_TLV("CH0 Gain", -1, MICFIL_OUTGAIN_CHX_SHIFT(0),
+ 0x0, 0xF, 0,
+ get_channel_gain, put_channel_gain, gain_tlv),
+ SOC_SINGLE_RANGE_EXT_TLV("CH1 Gain", -1, MICFIL_OUTGAIN_CHX_SHIFT(1),
+ 0x0, 0xF, 0,
+ get_channel_gain, put_channel_gain, gain_tlv),
+ SOC_SINGLE_RANGE_EXT_TLV("CH2 Gain", -1, MICFIL_OUTGAIN_CHX_SHIFT(2),
+ 0x0, 0xF, 0,
+ get_channel_gain, put_channel_gain, gain_tlv),
+ SOC_SINGLE_RANGE_EXT_TLV("CH3 Gain", -1, MICFIL_OUTGAIN_CHX_SHIFT(3),
+ 0x0, 0xF, 0,
+ get_channel_gain, put_channel_gain, gain_tlv),
+ SOC_SINGLE_RANGE_EXT_TLV("CH4 Gain", -1, MICFIL_OUTGAIN_CHX_SHIFT(4),
+ 0x0, 0xF, 0,
+ get_channel_gain, put_channel_gain, gain_tlv),
+ SOC_SINGLE_RANGE_EXT_TLV("CH5 Gain", -1, MICFIL_OUTGAIN_CHX_SHIFT(5),
+ 0x0, 0xF, 0,
+ get_channel_gain, put_channel_gain, gain_tlv),
+ SOC_SINGLE_RANGE_EXT_TLV("CH6 Gain", -1, MICFIL_OUTGAIN_CHX_SHIFT(6),
+ 0x0, 0xF, 0,
+ get_channel_gain, put_channel_gain, gain_tlv),
+ SOC_SINGLE_RANGE_EXT_TLV("CH7 Gain", -1, MICFIL_OUTGAIN_CHX_SHIFT(7),
+ 0x0, 0xF, 0,
+ get_channel_gain, put_channel_gain, gain_tlv),
+
+ SOC_ENUM_EXT("MICFIL Quality Select",
+ fsl_micfil_quality_enum,
+ snd_soc_get_enum_double, snd_soc_put_enum_double),
+ SOC_ENUM_EXT("HWVAD Initialization Mode",
+ fsl_micfil_hwvad_init_mode_enum,
+ hwvad_get_init_mode, hwvad_put_init_mode),
+ SOC_ENUM_EXT("HWVAD High-Pass Filter",
+ fsl_micfil_hwvad_hpf_enum,
+ hwvad_get_hpf, hwvad_put_hpf),
+ SOC_ENUM_EXT("HWVAD Zero-Crossing Detector Enable",
+ fsl_micfil_hwvad_zcd_enum,
+ hwvad_get_zcd_en, hwvad_put_zcd_en),
+ SOC_ENUM_EXT("HWVAD Zero-Crossing Detector Auto Threshold",
+ fsl_micfil_hwvad_zcdauto_enum,
+ hwvad_get_zcd_auto, hwvad_put_zcd_auto),
+ SOC_ENUM_EXT("HWVAD Noise OR Enable",
+ fsl_micfil_hwvad_ndec_enum,
+ snd_soc_get_enum_double, snd_soc_put_enum_double),
+ SOC_ENUM_EXT("HWVAD Sampling Rate",
+ fsl_micfil_hwvad_rate_enum,
+ hwvad_get_rate, hwvad_put_rate),
+ SOC_ENUM_EXT("Clock Source",
+ fsl_micfil_clk_src_enum,
+ micfil_get_clk_src, micfil_put_clk_src),
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "HWVAD Input Gain",
+ .access = SNDRV_CTL_ELEM_ACCESS_READ |
+ SNDRV_CTL_ELEM_ACCESS_WRITE,
+ .info = gain_info,
+ .get = hwvad_get_input_gain,
+ .put = hwvad_put_input_gain,
+ },
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "HWVAD Sound Gain",
+ .access = SNDRV_CTL_ELEM_ACCESS_READ |
+ SNDRV_CTL_ELEM_ACCESS_WRITE,
+ .info = gain_info,
+ .get = hwvad_get_sound_gain,
+ .put = hwvad_put_sound_gain,
+ },
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "HWVAD Noise Gain",
+ .access = SNDRV_CTL_ELEM_ACCESS_READ |
+ SNDRV_CTL_ELEM_ACCESS_WRITE,
+ .info = gain_info,
+ .get = hwvad_get_noise_gain,
+ .put = hwvad_put_noise_gain,
+ },
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "HWVAD Detector Frame Time",
+ .access = SNDRV_CTL_ELEM_ACCESS_READ |
+ SNDRV_CTL_ELEM_ACCESS_WRITE,
+ .info = hwvad_framet_info,
+ .get = hwvad_get_frame_time,
+ .put = hwvad_put_frame_time,
+ },
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "HWVAD Detector Initialization Time",
+ .access = SNDRV_CTL_ELEM_ACCESS_READ |
+ SNDRV_CTL_ELEM_ACCESS_WRITE,
+ .info = hwvad_initt_info,
+ .get = hwvad_get_init_time,
+ .put = hwvad_put_init_time,
+ },
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "HWVAD Noise Filter Adjustment",
+ .access = SNDRV_CTL_ELEM_ACCESS_READ |
+ SNDRV_CTL_ELEM_ACCESS_WRITE,
+ .info = hwvad_nfiladj_info,
+ .get = hwvad_get_nfil_adjust,
+ .put = hwvad_put_nfil_adjust,
+ },
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "HWVAD Zero-Crossing Detector Threshold",
+ .access = SNDRV_CTL_ELEM_ACCESS_READ |
+ SNDRV_CTL_ELEM_ACCESS_WRITE,
+ .info = hwvad_zcdth_info,
+ .get = hwvad_get_zcd_th,
+ .put = hwvad_put_zcd_th,
+ },
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "HWVAD Zero-Crossing Detector Adjustment",
+ .access = SNDRV_CTL_ELEM_ACCESS_READ |
+ SNDRV_CTL_ELEM_ACCESS_WRITE,
+ .info = hwvad_zcdadj_info,
+ .get = hwvad_get_zcd_adj,
+ .put = hwvad_put_zcd_adj,
+ },
+
+};
+
+static int disable_hwvad(struct device *dev, bool sync);
+
+static inline int get_pdm_clk(struct fsl_micfil *micfil,
+ unsigned int rate);
+
+static inline int get_clk_div(struct fsl_micfil *micfil,
+ unsigned int rate)
+{
+ u32 ctrl2_reg;
+ long mclk_rate;
+ int osr;
+ int clk_div;
+
+ regmap_read(micfil->regmap, REG_MICFIL_CTRL2, &ctrl2_reg);
+ osr = 16 - ((ctrl2_reg & MICFIL_CTRL2_CICOSR_MASK)
+ >> MICFIL_CTRL2_CICOSR_SHIFT);
+
+ mclk_rate = clk_get_rate(micfil->mclk);
+
+ clk_div = mclk_rate / (get_pdm_clk(micfil, rate) * 2);
+
+ return clk_div;
+}
+
+static inline int get_pdm_clk(struct fsl_micfil *micfil,
+ unsigned int rate)
+{
+ u32 ctrl2_reg;
+ int qsel, osr;
+ int bclk;
+
+ regmap_read(micfil->regmap, REG_MICFIL_CTRL2, &ctrl2_reg);
+ osr = 16 - ((ctrl2_reg & MICFIL_CTRL2_CICOSR_MASK)
+ >> MICFIL_CTRL2_CICOSR_SHIFT);
+
+ regmap_read(micfil->regmap, REG_MICFIL_CTRL2, &ctrl2_reg);
+ qsel = ctrl2_reg & MICFIL_CTRL2_QSEL_MASK;
+
+ switch (qsel) {
+ case MICFIL_HIGH_QUALITY:
+ bclk = rate * 8 * osr / 2; /* kfactor = 0.5 */
+ break;
+ case MICFIL_MEDIUM_QUALITY:
+ case MICFIL_VLOW0_QUALITY:
+ bclk = rate * 4 * osr * 1; /* kfactor = 1 */
+ break;
+ case MICFIL_LOW_QUALITY:
+ case MICFIL_VLOW1_QUALITY:
+ bclk = rate * 2 * osr * 2; /* kfactor = 2 */
+ break;
+ case MICFIL_VLOW2_QUALITY:
+ bclk = rate * osr * 4; /* kfactor = 4 */
+ break;
+ default:
+ dev_err(&micfil->pdev->dev,
+ "Please make sure you select a valid quality.\n");
+ bclk = -1;
+ break;
+ }
+
+ return bclk;
+}
+
+/* The SRES is a self-negated bit which provides the CPU with the
+ * capability to initialize the PDM Interface module through the
+ * slave-bus interface. This bit always reads as zero, and this
+ * bit is only effective when MDIS is cleared
+ */
+static int fsl_micfil_reset(struct device *dev)
+{
+ struct fsl_micfil *micfil = dev_get_drvdata(dev);
+ int ret;
+
+ ret = regmap_update_bits(micfil->regmap,
+ REG_MICFIL_CTRL1,
+ MICFIL_CTRL1_MDIS_MASK,
+ 0);
+ if (ret) {
+ dev_err(dev, "failed to clear MDIS bit %d\n", ret);
+ return ret;
+ }
+
+ ret = regmap_update_bits(micfil->regmap,
+ REG_MICFIL_CTRL1,
+ MICFIL_CTRL1_SRES_MASK,
+ MICFIL_CTRL1_SRES);
+ if (ret) {
+ dev_err(dev, "failed to reset MICFIL: %d\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+/* enable/disable hwvad interrupts */
+static int configure_hwvad_interrupts(struct device *dev,
+ int enable)
+{
+ struct fsl_micfil *micfil = dev_get_drvdata(dev);
+ int ret;
+ u32 vadie_reg = enable ? MICFIL_VAD0_CTRL1_IE : 0;
+ u32 vaderie_reg = enable ? MICFIL_VAD0_CTRL1_ERIE : 0;
+
+ /* Voice Activity Detector Error Interruption Enable */
+ ret = regmap_update_bits(micfil->regmap, REG_MICFIL_VAD0_CTRL1,
+ MICFIL_VAD0_CTRL1_ERIE_MASK,
+ vaderie_reg);
+ if (ret) {
+ dev_err(dev,
+ "Failed to set/clear VADERIE in CTRL1_VAD0 [%d]\n",
+ ret);
+ return ret;
+ }
+
+ /* Voice Activity Detector Interruption Enable */
+ ret = regmap_update_bits(micfil->regmap, REG_MICFIL_VAD0_CTRL1,
+ MICFIL_VAD0_CTRL1_IE_MASK,
+ vadie_reg);
+ if (ret) {
+ dev_err(dev,
+ "Failed to set/clear VADIE in CTRL1_VAD0 [%d]\n",
+ ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int init_hwvad_internal_filters(struct device *dev)
+{
+ struct fsl_micfil *micfil = dev_get_drvdata(dev);
+ int ret;
+
+ /* Voice Activity Detector Internal Filters Initialization*/
+ ret = regmap_update_bits(micfil->regmap, REG_MICFIL_VAD0_CTRL1,
+ MICFIL_VAD0_CTRL1_ST10_MASK,
+ MICFIL_VAD0_CTRL1_ST10);
+ if (ret) {
+ dev_err(dev,
+ "Failed to set VADST10 in CTRL1_VAD0 [%d]\n",
+ ret);
+ return ret;
+ }
+
+ /* sleep for 100ms - it should be enough for bit to stay
+ * pulsed for more than 2 cycles
+ */
+ usleep_range(MICFIL_SLEEP_MIN, MICFIL_SLEEP_MAX);
+
+ /* Voice Activity Detector Enabled */
+ ret = regmap_update_bits(micfil->regmap, REG_MICFIL_VAD0_CTRL1,
+ MICFIL_VAD0_CTRL1_ST10_MASK,
+ 0);
+ if (ret) {
+ dev_err(dev,
+ "Failed to clear VADST10 in CTRL1_VAD0 [%d]\n",
+ ret);
+ return ret;
+ }
+ return 0;
+}
+
+/* Zero-Crossing Detector Initialization
+ * Optionally a Zero-Crossing Detection block (ZCD) could
+ * be enabled to avoid low energy voiced speech be missed,
+ * improving the voice detection performance.
+ * See Section 8.4.3
+ */
+static int __maybe_unused init_zcd(struct device *dev)
+{
+ struct fsl_micfil *micfil = dev_get_drvdata(dev);
+ int ret;
+
+ /* exit if zcd is not enabled from userspace */
+ if (!micfil->vad_zcd_en)
+ return 0;
+
+ if (micfil->vad_zcd_auto) {
+ /* Zero-Crossing Detector Adjustment */
+ ret = regmap_update_bits(micfil->regmap, REG_MICFIL_VAD0_ZCD,
+ MICFIL_VAD0_ZCD_ZCDADJ_MASK,
+ micfil->vad_zcd_adj);
+ if (ret) {
+ dev_err(dev,
+ "Failed to set ZCDADJ in ZCD_VAD0 [%d]\n",
+ ret);
+ return ret;
+ }
+ }
+
+ /* Zero-Crossing Detector Threshold */
+ ret = regmap_update_bits(micfil->regmap, REG_MICFIL_VAD0_ZCD,
+ MICFIL_VAD0_ZCD_ZCDTH_MASK,
+ MICFIL_VAD0_ZCD_ZCDTH(micfil->vad_zcd_th));
+ if (ret) {
+ dev_err(dev, "Failed to set ZCDTH in ZCD_VAD0 [%d]\n", ret);
+ return ret;
+ }
+
+ /* Zero-Crossing Detector AND Behavior */
+ ret = regmap_update_bits(micfil->regmap, REG_MICFIL_VAD0_ZCD,
+ MICFIL_VAD0_ZCD_ZCDAND_MASK,
+ MICFIL_HWVAD_ZCDAND);
+ if (ret) {
+ dev_err(dev, "Failed to set ZCDAND in ZCD_VAD0 [%d]\n", ret);
+ return ret;
+ }
+
+ /* Zero-Crossing Detector Automatic Threshold */
+ ret = regmap_update_bits(micfil->regmap, REG_MICFIL_VAD0_ZCD,
+ MICFIL_VAD0_ZCD_ZCDAUT_MASK,
+ micfil->vad_zcd_auto);
+ if (ret) {
+ dev_err(dev,
+ "Failed to set/clear ZCDAUT in ZCD_VAD0 [%d]\n",
+ ret);
+ return ret;
+ }
+
+ /* Zero-Crossing Detector Enable */
+ ret = regmap_update_bits(micfil->regmap, REG_MICFIL_VAD0_ZCD,
+ MICFIL_VAD0_ZCD_ZCDEN_MASK,
+ MICFIL_VAD0_ZCD_ZCDEN);
+ if (ret) {
+ dev_err(dev, "Failed to set ZCDEN in ZCD_VAD0 [%d]\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+/* Configuration done only in energy-based initialization mode */
+static int init_hwvad_energy_mode(struct device *dev)
+{
+ struct fsl_micfil *micfil = dev_get_drvdata(dev);
+ int ret, i;
+ u32 stat;
+ u32 flag;
+
+ dev_info(dev, "Energy-based mode initialization\n");
+
+ /* Voice Activity Detector Reset */
+ ret = regmap_update_bits(micfil->regmap, REG_MICFIL_VAD0_CTRL1,
+ MICFIL_VAD0_CTRL1_RST_SHIFT,
+ MICFIL_VAD0_CTRL1_RST);
+ if (ret) {
+ dev_err(dev, "Failed to set VADRST in CTRL1_VAD0 [%d]\n", ret);
+ return ret;
+ }
+
+ /* Voice Activity Detector Enabled */
+ ret = regmap_update_bits(micfil->regmap, REG_MICFIL_VAD0_CTRL1,
+ MICFIL_VAD0_CTRL1_EN_MASK,
+ MICFIL_VAD0_CTRL1_EN);
+ if (ret) {
+ dev_err(dev, "Failed to set VADEN in CTRL1_VAD0 [%d]\n", ret);
+ return ret;
+ }
+
+ /* it would be a good idea to wait some time before VADEN
+ * is set
+ */
+ usleep_range(5 * MICFIL_SLEEP_MIN, 5 * MICFIL_SLEEP_MAX);
+
+ /* Enable Interrupts */
+ ret = configure_hwvad_interrupts(dev, 1);
+
+ /* Initialize Zero Crossing Detector */
+ ret = init_zcd(dev);
+ if (ret)
+ return ret;
+
+ /* Enable MICFIL module */
+ ret = regmap_update_bits(micfil->regmap, REG_MICFIL_CTRL1,
+ MICFIL_CTRL1_PDMIEN_MASK,
+ MICFIL_CTRL1_PDMIEN);
+ if (ret) {
+ dev_err(dev, "failed to enable the module\n");
+ return ret;
+ }
+
+ /* Wait for INITF to be asserted */
+ for (i = 0; i < MICFIL_MAX_RETRY; i++) {
+ ret = regmap_read(micfil->regmap, REG_MICFIL_VAD0_STAT, &stat);
+ if (ret) {
+ dev_err(dev, "failed to read register %d\n",
+ REG_MICFIL_VAD0_STAT);
+ return ret;
+ }
+
+ flag = (stat & MICFIL_VAD0_STAT_INITF_MASK);
+ if (flag == 0)
+ break;
+
+ usleep_range(MICFIL_SLEEP_MIN, MICFIL_SLEEP_MAX);
+ }
+
+ if (i == MICFIL_MAX_RETRY) {
+ dev_err(dev, "initf not asserted. Failed to init hwvad\n");
+ return -EBUSY;
+ }
+
+ /* Initialize Internal Filters */
+ ret = init_hwvad_internal_filters(dev);
+ if (ret)
+ return ret;
+
+ return ret;
+}
+
+/* Configuration done only in envelope-based initialization mode */
+static int init_hwvad_envelope_mode(struct device *dev)
+{
+ struct fsl_micfil *micfil = dev_get_drvdata(dev);
+ int ret, i;
+ u32 stat;
+ u32 flag;
+
+ /* Frame energy disable */
+ ret = regmap_update_bits(micfil->regmap, REG_MICFIL_VAD0_CTRL2,
+ MICFIL_VAD0_CTRL2_FRENDIS_MASK,
+ MICFIL_VAD0_CTRL2_FRENDIS);
+ if (ret) {
+ dev_err(dev, "Failed to set FRENDIS in CTRL2_VAD0 [%d]\n", ret);
+ return ret;
+ }
+
+ /* Enable pre-filter Noise & Signal */
+ ret = regmap_update_bits(micfil->regmap, REG_MICFIL_VAD0_CTRL2,
+ MICFIL_VAD0_CTRL2_PREFEN_MASK,
+ MICFIL_VAD0_CTRL2_PREFEN);
+ if (ret) {
+ dev_err(dev, "Failed to set PREFEN in CTRL2_VAD0 [%d]\n", ret);
+ return ret;
+ }
+
+ /* Enable Signal Filter */
+ ret = regmap_update_bits(micfil->regmap, REG_MICFIL_VAD0_SCONFIG,
+ MICFIL_VAD0_SCONFIG_SFILEN_MASK,
+ MICFIL_VAD0_SCONFIG_SFILEN);
+ if (ret) {
+ dev_err(dev,
+ "Failed to set SFILEN in SCONFIG_VAD0 [%d]\n",
+ ret);
+ return ret;
+ }
+
+ /* Signal Maximum Enable */
+ ret = regmap_update_bits(micfil->regmap, REG_MICFIL_VAD0_SCONFIG,
+ MICFIL_VAD0_SCONFIG_SMAXEN_MASK,
+ MICFIL_VAD0_SCONFIG_SMAXEN);
+ if (ret) {
+ dev_err(dev,
+ "Failed to set SMAXEN in SCONFIG_VAD0 [%d]\n",
+ ret);
+ return ret;
+ }
+
+ /* Allways enable noise filter, not based on voice activity
+ * information
+ */
+ ret = regmap_update_bits(micfil->regmap, REG_MICFIL_VAD0_NCONFIG,
+ MICFIL_VAD0_NCONFIG_NFILAUT_MASK,
+ 0);
+ if (ret) {
+ dev_err(dev,
+ "Failed to set NFILAUT in NCONFIG_VAD0 [%d]\n",
+ ret);
+ return ret;
+ }
+
+ /* Noise Minimum Enable */
+ ret = regmap_update_bits(micfil->regmap, REG_MICFIL_VAD0_NCONFIG,
+ MICFIL_VAD0_NCONFIG_NMINEN_MASK,
+ MICFIL_VAD0_NCONFIG_NMINEN);
+ if (ret) {
+ dev_err(dev,
+ "Failed to set NMINEN in NCONFIG_VAD0 [%d]\n",
+ ret);
+ return ret;
+ }
+
+ /* Noise Decimation Enable */
+ ret = regmap_update_bits(micfil->regmap, REG_MICFIL_VAD0_NCONFIG,
+ MICFIL_VAD0_NCONFIG_NDECEN_MASK,
+ MICFIL_VAD0_NCONFIG_NDECEN);
+ if (ret) {
+ dev_err(dev,
+ "Failed to set NDECEN in NCONFIG_VAD0 [%d]\n",
+ ret);
+ return ret;
+ }
+
+ /* Voice Activity Detector Reset */
+ ret = regmap_update_bits(micfil->regmap, REG_MICFIL_VAD0_CTRL1,
+ MICFIL_VAD0_CTRL1_RST_MASK,
+ MICFIL_VAD0_CTRL1_RST);
+ if (ret) {
+ dev_err(dev, "Failed to set VADRST in CTRL1_VAD0 [%d]\n", ret);
+ return ret;
+ }
+
+ /* Initialize Zero Crossing Detector */
+ ret = init_zcd(dev);
+ if (ret)
+ return ret;
+
+ /* Voice Activity Detector Enabled */
+ ret = regmap_update_bits(micfil->regmap, REG_MICFIL_VAD0_CTRL1,
+ MICFIL_VAD0_CTRL1_EN_MASK,
+ MICFIL_VAD0_CTRL1_EN);
+ if (ret) {
+ dev_err(dev, "Failed to set VADEN in CTRL1_VAD0 [%d]\n", ret);
+ return ret;
+ }
+
+ /* Enable MICFIL module */
+ ret = regmap_update_bits(micfil->regmap, REG_MICFIL_CTRL1,
+ MICFIL_CTRL1_PDMIEN_MASK,
+ MICFIL_CTRL1_PDMIEN);
+ if (ret) {
+ dev_err(dev, "failed to enable the module\n");
+ return ret;
+ }
+
+ /* it would be a good idea to wait some time before VADEN
+ * is set
+ */
+ usleep_range(3 * MICFIL_SLEEP_MIN, 3 * MICFIL_SLEEP_MAX);
+
+ /* Wait for INITF to be asserted */
+ for (i = 0; i < MICFIL_MAX_RETRY; i++) {
+ ret = regmap_read(micfil->regmap, REG_MICFIL_VAD0_STAT, &stat);
+ if (ret) {
+ dev_err(dev, "failed to read register %d\n",
+ REG_MICFIL_VAD0_STAT);
+ return ret;
+ }
+
+ flag = (stat & MICFIL_VAD0_STAT_INITF_MASK);
+ if (flag == 0)
+ break;
+
+ usleep_range(MICFIL_SLEEP_MIN, MICFIL_SLEEP_MAX);
+ }
+
+ if (i == MICFIL_MAX_RETRY) {
+ dev_err(dev, "initf not asserted. Failed to init hwvad\n");
+ return -EBUSY;
+ }
+
+ /* Initialize Internal Filters */
+ ret = init_hwvad_internal_filters(dev);
+ if (ret)
+ return ret;
+
+ /* Enable interrupts */
+ ret = configure_hwvad_interrupts(dev, 1);
+ if (ret)
+ return ret;
+
+ return ret;
+}
+
+/* Hardware Voice Active Detection: The HWVAD takes data from the input
+ * of a selected PDM microphone to detect if there is any
+ * voice activity. When a voice activity is detected, an interrupt could
+ * be delivered to the system. Initialization in section 8.4:
+ * Can work in two modes:
+ * -> Eneveope-based mode (section 8.4.1)
+ * -> Energy-based mode (section 8.4.2)
+ *
+ * It is important to remark that the HWVAD detector could be enabled
+ * or reset only when the MICFIL isn't running i.e. when the BSY_FIL
+ * bit in STAT register is cleared
+ */
+static int __maybe_unused init_hwvad(struct device *dev)
+{
+ struct fsl_micfil *micfil = dev_get_drvdata(dev);
+ int ret;
+ u32 reg_val;
+
+ /* configure CIC OSR in VADCICOSR */
+ ret = regmap_update_bits(micfil->regmap, REG_MICFIL_VAD0_CTRL1,
+ MICFIL_VAD0_CTRL1_CICOSR_MASK,
+ MICFIL_CTRL2_OSR_DEFAULT);
+ if (ret) {
+ dev_err(dev, "Failed to set CICOSR in CTRL1_VAD0i [%d]\n", ret);
+ return ret;
+ }
+
+ /* configure source channel in VADCHSEL */
+ reg_val = MICFIL_VAD0_CTRL1_CHSEL(micfil->vad_channel);
+ ret = regmap_update_bits(micfil->regmap, REG_MICFIL_VAD0_CTRL1,
+ MICFIL_VAD0_CTRL1_CHSEL_MASK,
+ reg_val);
+ if (ret) {
+ dev_err(dev, "Failed to set CHSEL in CTRL1_VAD0 [%d]\n", ret);
+ return ret;
+ }
+
+ /* configure detector frame time VADFRAMET */
+ reg_val = MICFIL_VAD0_CTRL2_FRAMET(micfil->vad_frame_time);
+ ret = regmap_update_bits(micfil->regmap, REG_MICFIL_VAD0_CTRL2,
+ MICFIL_VAD0_CTRL2_FRAMET_MASK,
+ reg_val);
+ if (ret) {
+ dev_err(dev, "Failed to set FRAMET in CTRL2_VAD0 [%d]\n", ret);
+ return ret;
+ }
+
+ /* configure initialization time in VADINITT */
+ reg_val = MICFIL_VAD0_CTRL1_INITT(micfil->vad_init_time);
+ ret = regmap_update_bits(micfil->regmap, REG_MICFIL_VAD0_CTRL1,
+ MICFIL_VAD0_CTRL1_INITT_MASK,
+ reg_val);
+ if (ret) {
+ dev_err(dev, "Failed to set INITT in CTRL1_VAD0 [%d]\n", ret);
+ return ret;
+ }
+
+ /* configure input gain in VADINPGAIN */
+ reg_val = MICFIL_VAD0_CTRL2_INPGAIN(micfil->vad_input_gain);
+ ret = regmap_update_bits(micfil->regmap, REG_MICFIL_VAD0_CTRL2,
+ MICFIL_VAD0_CTRL2_INPGAIN_MASK,
+ reg_val);
+ if (ret) {
+ dev_err(dev, "Failed to set INPGAIN in CTRL2_VAD0 [%d]\n", ret);
+ return ret;
+ }
+
+ /* configure sound gain in SGAIN */
+ reg_val = MICFIL_VAD0_SCONFIG_SGAIN(micfil->vad_sound_gain);
+ ret = regmap_update_bits(micfil->regmap, REG_MICFIL_VAD0_SCONFIG,
+ MICFIL_VAD0_SCONFIG_SGAIN_MASK,
+ reg_val);
+ if (ret) {
+ dev_err(dev, "Failed to set SGAIN in SCONFIG_VAD0 [%d]\n", ret);
+ return ret;
+ }
+
+ /* configure noise gain in NGAIN */
+ reg_val = MICFIL_VAD0_NCONFIG_NGAIN(micfil->vad_noise_gain);
+ ret = regmap_update_bits(micfil->regmap, REG_MICFIL_VAD0_NCONFIG,
+ MICFIL_VAD0_NCONFIG_NGAIN_MASK,
+ reg_val);
+ if (ret) {
+ dev_err(dev, "Failed to set NGAIN in NCONFIG_VAD0 [%d]\n", ret);
+ return ret;
+ }
+
+ /* configure or clear the VADNFILADJ based on mode */
+ reg_val = MICFIL_VAD0_NCONFIG_NFILADJ(micfil->vad_nfil_adjust);
+ ret = regmap_update_bits(micfil->regmap, REG_MICFIL_VAD0_NCONFIG,
+ MICFIL_VAD0_NCONFIG_NFILADJ_MASK,
+ reg_val);
+ if (ret) {
+ dev_err(dev,
+ "Failed to set VADNFILADJ in NCONFIG_VAD0 [%d]\n",
+ ret);
+ return ret;
+ }
+
+ /* enable the high-pass filter in VADHPF */
+ reg_val = MICFIL_VAD0_CTRL2_HPF(micfil->vad_hpf);
+ ret = regmap_update_bits(micfil->regmap, REG_MICFIL_VAD0_CTRL2,
+ MICFIL_VAD0_CTRL2_HPF_MASK,
+ reg_val);
+ if (ret) {
+ dev_err(dev, "Failed to set HPF in CTRL2_VAD0 [%d]\n", ret);
+ return ret;
+ }
+
+ /* envelope-based specific initialization */
+ if (micfil->vad_init_mode == MICFIL_HWVAD_ENVELOPE_MODE) {
+ ret = init_hwvad_envelope_mode(dev);
+ if (ret)
+ return ret;
+ } else {
+ ret = init_hwvad_energy_mode(dev);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
+static inline bool clk_in_list(struct clk *p, struct clk *clk_src[])
+{
+ int i;
+
+ for (i = 0; i < MICFIL_CLK_SRC_NUM; i++)
+ if (clk_is_match(p, clk_src[i]))
+ return true;
+
+ return false;
+}
+
+static int fsl_micfil_set_mclk_rate(struct fsl_micfil *micfil, int clk_id,
+ unsigned int freq)
+{
+ struct clk *p = micfil->mclk, *pll = 0, *npll = 0;
+ struct device *dev = &micfil->pdev->dev;
+ u64 ratio = freq;
+ u64 clk_rate;
+ int ret;
+ int i;
+
+ /* Do not touch the clock if hwvad is already enabled
+ * since you can record only at hwvad rate and clock
+ * has already been set to the required frequency
+ */
+ if (atomic_read(&micfil->hwvad_state) == MICFIL_HWVAD_ON)
+ return 0;
+
+ /* check if all clock sources are valid */
+ for (i = 0; i < MICFIL_CLK_SRC_NUM; i++) {
+ if (micfil->clk_src[i])
+ continue;
+
+ dev_err(dev, "Clock Source %d is not valid.\n", i);
+ return -EINVAL;
+ }
+
+ while (p) {
+ struct clk *pp = clk_get_parent(p);
+
+ if (clk_in_list(pp, micfil->clk_src)) {
+ pll = pp;
+ break;
+ }
+ p = pp;
+ }
+
+ if (!pll) {
+ dev_err(dev, "reached a null clock\n");
+ return -EINVAL;
+ }
+
+ if (micfil->clk_src_id == MICFIL_CLK_AUTO) {
+ for (i = 0; i < MICFIL_CLK_SRC_NUM; i++) {
+ clk_rate = clk_get_rate(micfil->clk_src[i]);
+ /* This is an workaround since audio_pll2 clock
+ * has 722534399 rate and this will never divide
+ * to any known frequency ???
+ */
+ clk_rate = round_up(clk_rate, 10);
+ if (do_div(clk_rate, ratio) == 0)
+ npll = micfil->clk_src[i];
+ }
+ } else {
+ /* clock id is offseted by 1 since ID=0 means
+ * auto clock selection
+ */
+ npll = micfil->clk_src[micfil->clk_src_id - 1];
+ }
+
+ if (!npll) {
+ dev_err(dev,
+ "failed to find a suitable clock source\n");
+ return -EINVAL;
+ }
+
+ if (!clk_is_match(pll, npll)) {
+ ret = clk_set_parent(p, npll);
+ if (ret < 0)
+ dev_warn(dev,
+ "failed to set parrent %d\n", ret);
+ }
+
+ clk_disable_unprepare(micfil->mclk);
+ ret = clk_set_rate(micfil->mclk, freq * 1024);
+ if (ret)
+ dev_warn(dev, "failed to set rate (%u): %d\n",
+ freq * 1024, ret);
+ clk_prepare_enable(micfil->mclk);
+
+ return ret;
+}
+
+static int fsl_micfil_startup(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ struct fsl_micfil *micfil = snd_soc_dai_get_drvdata(dai);
+
+ if (!micfil) {
+ dev_err(dai->dev,
+ "micfil dai priv_data not set\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int fsl_micfil_trigger(struct snd_pcm_substream *substream, int cmd,
+ struct snd_soc_dai *dai)
+{
+ struct fsl_micfil *micfil = snd_soc_dai_get_drvdata(dai);
+ struct device *dev = &micfil->pdev->dev;
+ int ret;
+
+ switch (cmd) {
+ case SNDRV_PCM_TRIGGER_START:
+ case SNDRV_PCM_TRIGGER_RESUME:
+ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+ ret = fsl_micfil_reset(dev);
+ if (ret) {
+ dev_err(dev, "failed to soft reset\n");
+ return ret;
+ }
+
+ /* DMA Interrupt Selection - DISEL bits
+ * 00 - DMA and IRQ disabled
+ * 01 - DMA req enabled
+ * 10 - IRQ enabled
+ * 11 - reserved
+ */
+ ret = regmap_update_bits(micfil->regmap, REG_MICFIL_CTRL1,
+ MICFIL_CTRL1_DISEL_MASK,
+ (1 << MICFIL_CTRL1_DISEL_SHIFT));
+ if (ret) {
+ dev_err(dev, "failed to update DISEL bits\n");
+ return ret;
+ }
+
+ /* Enable the module */
+ ret = regmap_update_bits(micfil->regmap, REG_MICFIL_CTRL1,
+ MICFIL_CTRL1_PDMIEN_MASK,
+ MICFIL_CTRL1_PDMIEN);
+ if (ret) {
+ dev_err(dev, "failed to enable the module\n");
+ return ret;
+ }
+
+ break;
+ case SNDRV_PCM_TRIGGER_STOP:
+ case SNDRV_PCM_TRIGGER_SUSPEND:
+ case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+ /* Disable the module */
+ ret = regmap_update_bits(micfil->regmap, REG_MICFIL_CTRL1,
+ MICFIL_CTRL1_PDMIEN_MASK,
+ 0);
+ if (ret) {
+ dev_err(dev, "failed to enable the module\n");
+ return ret;
+ }
+
+ ret = regmap_update_bits(micfil->regmap, REG_MICFIL_CTRL1,
+ MICFIL_CTRL1_DISEL_MASK,
+ (0 << MICFIL_CTRL1_DISEL_SHIFT));
+ if (ret) {
+ dev_err(dev, "failed to update DISEL bits\n");
+ return ret;
+ }
+ break;
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static int fsl_set_clock_params(struct device *dev, unsigned int rate)
+{
+ struct fsl_micfil *micfil = dev_get_drvdata(dev);
+ int clk_div;
+ int ret = 0;
+
+ ret = fsl_micfil_set_mclk_rate(micfil, 0, rate);
+ if (ret < 0)
+ dev_err(dev, "failed to set mclk[%lu] to rate %u\n",
+ clk_get_rate(micfil->mclk), rate);
+
+ /* set CICOSR */
+ ret |= regmap_update_bits(micfil->regmap, REG_MICFIL_CTRL2,
+ MICFIL_CTRL2_CICOSR_MASK,
+ MICFIL_CTRL2_OSR_DEFAULT);
+ if (ret)
+ dev_err(dev, "failed to set CICOSR in reg 0x%X\n",
+ REG_MICFIL_CTRL2);
+
+ /* set CLK_DIV */
+ clk_div = get_clk_div(micfil, rate);
+ if (clk_div < 0)
+ ret = -EINVAL;
+
+ ret |= regmap_update_bits(micfil->regmap, REG_MICFIL_CTRL2,
+ MICFIL_CTRL2_CLKDIV_MASK, clk_div);
+ if (ret)
+ dev_err(dev, "failed to set CLKDIV in reg 0x%X\n",
+ REG_MICFIL_CTRL2);
+
+ return ret;
+}
+
+static int fsl_micfil_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params,
+ struct snd_soc_dai *dai)
+{
+ struct fsl_micfil *micfil = snd_soc_dai_get_drvdata(dai);
+ unsigned int channels = params_channels(params);
+ unsigned int rate = params_rate(params);
+ struct device *dev = &micfil->pdev->dev;
+ unsigned int hwvad_rate;
+ int ret;
+ u32 hwvad_state;
+
+ hwvad_rate = micfil_hwvad_rate_ints[micfil->vad_rate_index];
+ hwvad_state = atomic_read(&micfil->hwvad_state);
+
+ /* if hwvad is enabled, make sure you are recording at
+ * the same rate the hwvad is on or reject it to avoid
+ * changing the clock rate.
+ */
+ if (hwvad_state == MICFIL_HWVAD_ON && rate != hwvad_rate) {
+ dev_err(dev, "Record at hwvad rate %u\n", hwvad_rate);
+ return -EINVAL;
+ }
+
+ atomic_set(&micfil->recording_state, MICFIL_RECORDING_ON);
+
+ if (hwvad_state == MICFIL_HWVAD_OFF) {
+ /* 1. Disable the module */
+ ret = regmap_update_bits(micfil->regmap, REG_MICFIL_CTRL1,
+ MICFIL_CTRL1_PDMIEN_MASK, 0);
+ if (ret) {
+ dev_err(dev, "failed to disable the module\n");
+ return ret;
+ }
+ }
+
+ /* enable channels */
+ ret = regmap_update_bits(micfil->regmap, REG_MICFIL_CTRL1,
+ 0xFF, ((1 << channels) - 1));
+ if (ret) {
+ dev_err(dev, "failed to enable channels %d, reg 0x%X\n", ret,
+ REG_MICFIL_CTRL1);
+ return ret;
+ }
+
+ ret = fsl_set_clock_params(dev, rate);
+ if (ret < 0) {
+ dev_err(dev, "Failed to set clock parameters [%d]\n", ret);
+ return ret;
+ }
+
+ micfil->dma_params_rx.fifo_num = channels;
+ micfil->dma_params_rx.maxburst = channels * MICFIL_DMA_MAXBURST_RX;
+
+ return 0;
+}
+
+static int fsl_micfil_hw_free(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ struct fsl_micfil *micfil = snd_soc_dai_get_drvdata(dai);
+
+ atomic_set(&micfil->recording_state, MICFIL_RECORDING_OFF);
+
+ return 0;
+}
+
+static int fsl_micfil_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id,
+ unsigned int freq, int dir)
+{
+ struct fsl_micfil *micfil = snd_soc_dai_get_drvdata(dai);
+ struct device *dev = &micfil->pdev->dev;
+
+ int ret;
+
+ if (!freq)
+ return 0;
+
+ ret = fsl_micfil_set_mclk_rate(micfil, clk_id, freq);
+ if (ret < 0)
+ dev_err(dev, "failed to set mclk[%lu] to rate %u\n",
+ clk_get_rate(micfil->mclk), freq);
+
+ return ret;
+}
+
+static int fsl_micfil_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
+{
+ struct fsl_micfil *micfil = snd_soc_dai_get_drvdata(dai);
+
+ /* DAI MODE */
+ switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+ case SND_SOC_DAIFMT_I2S:
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ /* DAI CLK INVERSION */
+ switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
+ case SND_SOC_DAIFMT_NB_NF:
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ micfil->slave_mode = false;
+
+ return 0;
+}
+
+static struct snd_soc_dai_ops fsl_micfil_dai_ops = {
+ .startup = fsl_micfil_startup,
+ .trigger = fsl_micfil_trigger,
+ .hw_params = fsl_micfil_hw_params,
+ .hw_free = fsl_micfil_hw_free,
+ .set_sysclk = fsl_micfil_set_dai_sysclk,
+ .set_fmt = fsl_micfil_set_dai_fmt,
+};
+
+static int fsl_micfil_dai_probe(struct snd_soc_dai *cpu_dai)
+{
+ struct fsl_micfil *micfil = dev_get_drvdata(cpu_dai->dev);
+ struct device *dev = cpu_dai->dev;
+ unsigned int val;
+ int ret;
+ int i;
+
+ /* set qsel to medium */
+ ret = regmap_update_bits(micfil->regmap, REG_MICFIL_CTRL2,
+ MICFIL_CTRL2_QSEL_MASK, MICFIL_MEDIUM_QUALITY);
+ if (ret) {
+ dev_err(dev, "failed to set quality mode bits, reg 0x%X\n",
+ REG_MICFIL_CTRL2);
+ return ret;
+ }
+
+ /* set default gain to max_gain */
+ regmap_write(micfil->regmap, REG_MICFIL_OUT_CTRL, 0x77777777);
+ for (i = 0; i < 8; i++)
+ micfil->channel_gain[i] = 0xF;
+
+ snd_soc_dai_init_dma_data(cpu_dai, NULL,
+ &micfil->dma_params_rx);
+
+ /* FIFO Watermark Control - FIFOWMK*/
+ val = MICFIL_FIFO_CTRL_FIFOWMK(micfil->soc->fifo_depth) - 1;
+ ret = regmap_update_bits(micfil->regmap, REG_MICFIL_FIFO_CTRL,
+ MICFIL_FIFO_CTRL_FIFOWMK_MASK,
+ val);
+ if (ret) {
+ dev_err(dev, "failed to set FIFOWMK\n");
+ return ret;
+ }
+
+ snd_soc_dai_set_drvdata(cpu_dai, micfil);
+
+ return 0;
+}
+
+static struct snd_soc_dai_driver fsl_micfil_dai = {
+ .probe = fsl_micfil_dai_probe,
+ .capture = {
+ .stream_name = "CPU-Capture",
+ .channels_min = 1,
+ .channels_max = 8,
+ .rates = FSL_MICFIL_RATES,
+ .formats = FSL_MICFIL_FORMATS,
+ },
+ .ops = &fsl_micfil_dai_ops,
+};
+
+static const struct snd_soc_component_driver fsl_micfil_component = {
+ .name = "fsl-micfil-dai",
+ .controls = fsl_micfil_snd_controls,
+ .num_controls = ARRAY_SIZE(fsl_micfil_snd_controls),
+
+};
+
+/* REGMAP */
+static const struct reg_default fsl_micfil_reg_defaults[] = {
+ {REG_MICFIL_CTRL1, 0x00000000},
+ {REG_MICFIL_CTRL2, 0x00000000},
+ {REG_MICFIL_STAT, 0x00000000},
+ {REG_MICFIL_FIFO_CTRL, 0x00000007},
+ {REG_MICFIL_FIFO_STAT, 0x00000000},
+ {REG_MICFIL_DATACH0, 0x00000000},
+ {REG_MICFIL_DATACH1, 0x00000000},
+ {REG_MICFIL_DATACH2, 0x00000000},
+ {REG_MICFIL_DATACH3, 0x00000000},
+ {REG_MICFIL_DATACH4, 0x00000000},
+ {REG_MICFIL_DATACH5, 0x00000000},
+ {REG_MICFIL_DATACH6, 0x00000000},
+ {REG_MICFIL_DATACH7, 0x00000000},
+ {REG_MICFIL_DC_CTRL, 0x00000000},
+ {REG_MICFIL_OUT_CTRL, 0x00000000},
+ {REG_MICFIL_OUT_STAT, 0x00000000},
+ {REG_MICFIL_VAD0_CTRL1, 0x00000000},
+ {REG_MICFIL_VAD0_CTRL2, 0x000A0000},
+ {REG_MICFIL_VAD0_STAT, 0x00000000},
+ {REG_MICFIL_VAD0_SCONFIG, 0x00000000},
+ {REG_MICFIL_VAD0_NCONFIG, 0x80000000},
+ {REG_MICFIL_VAD0_NDATA, 0x00000000},
+ {REG_MICFIL_VAD0_ZCD, 0x00000004},
+};
+
+static bool fsl_micfil_readable_reg(struct device *dev, unsigned int reg)
+{
+ switch (reg) {
+ case REG_MICFIL_CTRL1:
+ case REG_MICFIL_CTRL2:
+ case REG_MICFIL_STAT:
+ case REG_MICFIL_FIFO_CTRL:
+ case REG_MICFIL_FIFO_STAT:
+ case REG_MICFIL_DATACH0:
+ case REG_MICFIL_DATACH1:
+ case REG_MICFIL_DATACH2:
+ case REG_MICFIL_DATACH3:
+ case REG_MICFIL_DATACH4:
+ case REG_MICFIL_DATACH5:
+ case REG_MICFIL_DATACH6:
+ case REG_MICFIL_DATACH7:
+ case REG_MICFIL_DC_CTRL:
+ case REG_MICFIL_OUT_CTRL:
+ case REG_MICFIL_OUT_STAT:
+ case REG_MICFIL_VAD0_CTRL1:
+ case REG_MICFIL_VAD0_CTRL2:
+ case REG_MICFIL_VAD0_STAT:
+ case REG_MICFIL_VAD0_SCONFIG:
+ case REG_MICFIL_VAD0_NCONFIG:
+ case REG_MICFIL_VAD0_NDATA:
+ case REG_MICFIL_VAD0_ZCD:
+ return true;
+ default:
+ return false;
+ }
+}
+
+static bool fsl_micfil_writeable_reg(struct device *dev, unsigned int reg)
+{
+ switch (reg) {
+ case REG_MICFIL_CTRL1:
+ case REG_MICFIL_CTRL2:
+ case REG_MICFIL_STAT: /* Write 1 to Clear */
+ case REG_MICFIL_FIFO_CTRL:
+ case REG_MICFIL_FIFO_STAT: /* Write 1 to Clear */
+ case REG_MICFIL_DC_CTRL:
+ case REG_MICFIL_OUT_CTRL:
+ case REG_MICFIL_OUT_STAT: /* Write 1 to Clear */
+ case REG_MICFIL_VAD0_CTRL1:
+ case REG_MICFIL_VAD0_CTRL2:
+ case REG_MICFIL_VAD0_STAT: /* Write 1 to Clear */
+ case REG_MICFIL_VAD0_SCONFIG:
+ case REG_MICFIL_VAD0_NCONFIG:
+ case REG_MICFIL_VAD0_ZCD:
+ return true;
+ default:
+ return false;
+ }
+}
+
+static bool fsl_micfil_volatile_reg(struct device *dev, unsigned int reg)
+{
+ switch (reg) {
+ case REG_MICFIL_CTRL1:
+ case REG_MICFIL_CTRL2:
+ case REG_MICFIL_STAT:
+ case REG_MICFIL_DATACH0:
+ case REG_MICFIL_DATACH1:
+ case REG_MICFIL_DATACH2:
+ case REG_MICFIL_DATACH3:
+ case REG_MICFIL_DATACH4:
+ case REG_MICFIL_DATACH5:
+ case REG_MICFIL_DATACH6:
+ case REG_MICFIL_DATACH7:
+ case REG_MICFIL_VAD0_CTRL1:
+ case REG_MICFIL_VAD0_CTRL2:
+ case REG_MICFIL_VAD0_STAT:
+ case REG_MICFIL_VAD0_SCONFIG:
+ case REG_MICFIL_VAD0_NCONFIG:
+ case REG_MICFIL_VAD0_NDATA:
+ case REG_MICFIL_VAD0_ZCD:
+ return true;
+ default:
+ return false;
+ }
+}
+
+static const struct regmap_config fsl_micfil_regmap_config = {
+ .reg_bits = 32,
+ .reg_stride = 4,
+ .val_bits = 32,
+
+ .max_register = REG_MICFIL_VAD0_ZCD,
+ .reg_defaults = fsl_micfil_reg_defaults,
+ .num_reg_defaults = ARRAY_SIZE(fsl_micfil_reg_defaults),
+ .readable_reg = fsl_micfil_readable_reg,
+ .volatile_reg = fsl_micfil_volatile_reg,
+ .writeable_reg = fsl_micfil_writeable_reg,
+ .cache_type = REGCACHE_RBTREE,
+};
+
+/* END OF REGMAP */
+
+static irqreturn_t voice_detected_fn(int irq, void *devid)
+{
+ struct fsl_micfil *micfil = (struct fsl_micfil *)devid;
+ struct device *dev = &micfil->pdev->dev;
+ int ret;
+
+ /* disable hwvad */
+ ret = disable_hwvad(dev, true);
+ if (ret)
+ dev_err(dev, "Failed to disable HWVAD module\n");
+
+ /* notify userspace that voice was detected */
+ kobject_uevent_env(&dev->kobj, KOBJ_CHANGE, envp);
+
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t hwvad_isr(int irq, void *devid)
+{
+ struct fsl_micfil *micfil = (struct fsl_micfil *)devid;
+ struct device *dev = &micfil->pdev->dev;
+ int ret;
+ u32 vad0_reg;
+
+ regmap_read(micfil->regmap, REG_MICFIL_VAD0_STAT, &vad0_reg);
+
+ /* The only difference between MICFIL_VAD0_STAT_EF and
+ * MICFIL_VAD0_STAT_IF is that the former requires Write
+ * 1 to Clear. Since both flags are set, it is enough
+ * to only read one of them
+ */
+ if (vad0_reg & MICFIL_VAD0_STAT_IF_MASK) {
+ /* Write 1 to clear */
+ regmap_write_bits(micfil->regmap, REG_MICFIL_VAD0_STAT,
+ MICFIL_VAD0_STAT_IF_MASK,
+ MICFIL_VAD0_STAT_IF);
+
+ /* disable hwvad interrupts */
+ ret = configure_hwvad_interrupts(dev, 0);
+ if (ret)
+ dev_err(dev, "Failed to disable interrupts\n");
+ }
+
+ return IRQ_WAKE_THREAD;
+}
+
+static irqreturn_t hwvad_err_isr(int irq, void *devid)
+{
+ struct fsl_micfil *micfil = (struct fsl_micfil *)devid;
+ struct device *dev = &micfil->pdev->dev;
+ u32 vad0_reg;
+
+ regmap_read(micfil->regmap, REG_MICFIL_VAD0_STAT, &vad0_reg);
+
+ if (vad0_reg & MICFIL_VAD0_STAT_INSATF_MASK)
+ dev_dbg(dev, "voice activity input overflow/underflow detected\n");
+
+ if (vad0_reg & MICFIL_VAD0_STAT_INITF_MASK)
+ dev_dbg(dev, "voice activity dectector is initializing\n");
+
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t micfil_isr(int irq, void *devid)
+{
+ struct fsl_micfil *micfil = (struct fsl_micfil *)devid;
+ struct platform_device *pdev = micfil->pdev;
+ u32 stat_reg;
+ u32 fifo_stat_reg;
+ u32 ctrl1_reg;
+ bool dma_enabled;
+ int i;
+
+ regmap_read(micfil->regmap, REG_MICFIL_STAT, &stat_reg);
+ regmap_read(micfil->regmap, REG_MICFIL_CTRL1, &ctrl1_reg);
+ regmap_read(micfil->regmap, REG_MICFIL_FIFO_STAT, &fifo_stat_reg);
+
+ dma_enabled = MICFIL_DMA_ENABLED(ctrl1_reg);
+
+ /* Channel 0-7 Output Data Flags */
+ for (i = 0; i < MICFIL_OUTPUT_CHANNELS; i++) {
+ if (stat_reg & MICFIL_STAT_CHXF_MASK(i))
+ dev_dbg(&pdev->dev,
+ "Data available in Data Channel %d\n", i);
+ /* if DMA is not enabled, field must be written with 1
+ * to clear
+ */
+ if (!dma_enabled)
+ regmap_write_bits(micfil->regmap,
+ REG_MICFIL_STAT,
+ MICFIL_STAT_CHXF_MASK(i),
+ 1);
+ }
+
+ for (i = 0; i < MICFIL_FIFO_NUM; i++) {
+ if (fifo_stat_reg & MICFIL_FIFO_STAT_FIFOX_OVER_MASK(i))
+ dev_dbg(&pdev->dev,
+ "FIFO Overflow Exception flag for channel %d\n",
+ i);
+
+ if (fifo_stat_reg & MICFIL_FIFO_STAT_FIFOX_UNDER_MASK(i))
+ dev_dbg(&pdev->dev,
+ "FIFO Underflow Exception flag for channel %d\n",
+ i);
+ }
+
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t micfil_err_isr(int irq, void *devid)
+{
+ struct fsl_micfil *micfil = (struct fsl_micfil *)devid;
+ struct platform_device *pdev = micfil->pdev;
+ u32 stat_reg;
+
+ regmap_read(micfil->regmap, REG_MICFIL_STAT, &stat_reg);
+
+ if (stat_reg & MICFIL_STAT_BSY_FIL_MASK)
+ dev_dbg(&pdev->dev, "isr: Decimation Filter is running\n");
+
+ if (stat_reg & MICFIL_STAT_FIR_RDY_MASK)
+ dev_dbg(&pdev->dev, "isr: FIR Filter Data ready\n");
+
+ if (stat_reg & MICFIL_STAT_LOWFREQF_MASK) {
+ dev_dbg(&pdev->dev, "isr: ipg_clk_app is too low\n");
+ regmap_write_bits(micfil->regmap, REG_MICFIL_STAT,
+ MICFIL_STAT_LOWFREQF_MASK, 1);
+ }
+
+ return IRQ_HANDLED;
+}
+
+static int fsl_set_clock_params(struct device *, unsigned int);
+
+static int enable_hwvad(struct device *dev, bool sync)
+{
+ struct fsl_micfil *micfil = dev_get_drvdata(dev);
+ int ret;
+ int rate;
+ u32 state;
+
+ if (sync)
+ pm_runtime_get_sync(dev);
+
+ state = atomic_cmpxchg(&micfil->hwvad_state,
+ MICFIL_HWVAD_OFF,
+ MICFIL_HWVAD_ON);
+
+ /* we should not reenable when sync = true because
+ * this means enable was called for second time by
+ * user. However state = ON and sync = false can only
+ * occur when enable is called from system_resume. In
+ * this case we should enable the hwvad
+ */
+ if (sync && state == MICFIL_HWVAD_ON) {
+ dev_err(dev, "hwvad already on\n");
+ ret = -EBUSY;
+ goto enable_error;
+ }
+
+ if (micfil->vad_rate_index >= ARRAY_SIZE(micfil_hwvad_rate_ints)) {
+ dev_err(dev, "There are more select texts than rates\n");
+ ret = -EINVAL;
+ goto enable_error;
+ }
+
+ rate = micfil_hwvad_rate_ints[micfil->vad_rate_index];
+
+ /* This is required because if an arecord was done,
+ * suspend function will mark regmap as cache only
+ * and reads/writes in volatile regs will fail
+ */
+ regcache_cache_only(micfil->regmap, false);
+ regcache_mark_dirty(micfil->regmap);
+ regcache_sync(micfil->regmap);
+
+ ret = fsl_set_clock_params(dev, rate);
+ if (ret)
+ return ret;
+
+ ret = fsl_micfil_reset(dev);
+ if (ret)
+ return ret;
+
+ /* Initialize Hardware Voice Activity */
+ ret = init_hwvad(dev);
+
+ return ret;
+enable_error:
+ if (sync)
+ pm_runtime_put_sync(dev);
+ return ret;
+}
+
+static int disable_hwvad(struct device *dev, bool sync)
+{
+ struct fsl_micfil *micfil = dev_get_drvdata(dev);
+ int ret = 0;
+ u32 state;
+
+ /* This is required because if an arecord was done,
+ * suspend function will mark regmap as cache only
+ * and reads/writes in volatile regs will fail
+ */
+ regcache_cache_only(micfil->regmap, false);
+ regcache_mark_dirty(micfil->regmap);
+ regcache_sync(micfil->regmap);
+
+ /* disable is called with sync = false only from
+ * system suspend and in this case, you should not
+ * change the hwvad_state so we know at system_resume
+ * to reenable hwvad
+ */
+ if (sync)
+ state = atomic_cmpxchg(&micfil->hwvad_state,
+ MICFIL_HWVAD_ON,
+ MICFIL_HWVAD_OFF);
+ else
+ state = atomic_read(&micfil->hwvad_state);
+
+ if (state == MICFIL_HWVAD_ON) {
+ /* Voice Activity Detector Reset */
+ ret |= regmap_update_bits(micfil->regmap,
+ REG_MICFIL_VAD0_CTRL1,
+ MICFIL_VAD0_CTRL1_RST_SHIFT,
+ MICFIL_VAD0_CTRL1_RST);
+
+ /* Disable HWVAD */
+ ret |= regmap_update_bits(micfil->regmap,
+ REG_MICFIL_VAD0_CTRL1,
+ MICFIL_VAD0_CTRL1_EN_MASK,
+ 0);
+
+ /* Disable Signal Filter */
+ ret |= regmap_update_bits(micfil->regmap,
+ REG_MICFIL_VAD0_SCONFIG,
+ MICFIL_VAD0_SCONFIG_SFILEN_MASK,
+ 0);
+
+ /* Signal Maximum Enable */
+ ret |= regmap_update_bits(micfil->regmap,
+ REG_MICFIL_VAD0_SCONFIG,
+ MICFIL_VAD0_SCONFIG_SMAXEN_MASK,
+ 0);
+
+ /* Enable pre-filter Noise & Signal */
+ ret |= regmap_update_bits(micfil->regmap,
+ REG_MICFIL_VAD0_CTRL2,
+ MICFIL_VAD0_CTRL2_PREFEN_MASK,
+ 0);
+
+ /* Noise Decimation Enable */
+ ret |= regmap_update_bits(micfil->regmap,
+ REG_MICFIL_VAD0_NCONFIG,
+ MICFIL_VAD0_NCONFIG_NDECEN_MASK,
+ 0);
+
+ /* disable the module and clock only if recording
+ * is not done in parallel
+ */
+ state = atomic_read(&micfil->recording_state);
+ if (state == MICFIL_RECORDING_OFF) {
+ /* Disable MICFIL module */
+ ret |= regmap_update_bits(micfil->regmap,
+ REG_MICFIL_CTRL1,
+ MICFIL_CTRL1_PDMIEN_MASK,
+ 0);
+ }
+
+ } else {
+ ret = -EPERM;
+ dev_err(dev, "HWVAD is not enabled %d\n", ret);
+ }
+
+ if (sync)
+ pm_runtime_put_sync(dev);
+
+ return ret;
+}
+
+static ssize_t micfil_hwvad_handler(struct kobject *kobj,
+ struct kobj_attribute *attr,
+ const char *buf,
+ size_t count)
+{
+ struct kobject *nand_kobj = kobj->parent;
+ struct device *dev = container_of(nand_kobj, struct device, kobj);
+ struct fsl_micfil *micfil = dev_get_drvdata(dev);
+ unsigned long vad_channel;
+ int ret;
+
+ ret = kstrtoul(buf, 16, &vad_channel);
+ if (ret < 0)
+ return -EINVAL;
+
+ if (vad_channel <= 7) {
+ micfil->vad_channel = vad_channel;
+ ret = enable_hwvad(dev, true);
+ if (ret)
+ dev_err(dev, "Failed to enable hwvad");
+ } else {
+ micfil->vad_channel = -1;
+ ret = disable_hwvad(dev, true);
+ }
+ if (ret)
+ return ret;
+
+ return count;
+}
+
+static struct kobj_attribute hwvad_en_attr = __ATTR(enable,
+ 0660,
+ NULL,
+ micfil_hwvad_handler);
+
+static int fsl_micfil_probe(struct platform_device *pdev)
+{
+ struct device_node *np = pdev->dev.of_node;
+ const struct of_device_id *of_id;
+ struct fsl_micfil *micfil;
+ struct resource *res;
+ void __iomem *regs;
+ int ret, i;
+ unsigned long irqflag = 0;
+
+ micfil = devm_kzalloc(&pdev->dev, sizeof(*micfil), GFP_KERNEL);
+ if (!micfil)
+ return -ENOMEM;
+
+ micfil->pdev = pdev;
+ strncpy(micfil->name, np->name, sizeof(micfil->name) - 1);
+
+ of_id = of_match_device(fsl_micfil_dt_ids, &pdev->dev);
+ if (!of_id || !of_id->data)
+ return -EINVAL;
+
+ micfil->soc = of_id->data;
+
+ /* ipg_clk is used to control the registers
+ * ipg_clk_app is used to operate the filter
+ */
+ micfil->mclk = devm_clk_get(&pdev->dev, "ipg_clk_app");
+ if (IS_ERR(micfil->mclk)) {
+ dev_err(&pdev->dev, "failed to get core clock: %ld\n",
+ PTR_ERR(micfil->mclk));
+ return PTR_ERR(micfil->mclk);
+ }
+
+ /* get audio pll1 and pll2 */
+ micfil->clk_src[MICFIL_AUDIO_PLL1] = devm_clk_get(&pdev->dev, "pll8k");
+ if (IS_ERR(micfil->clk_src[MICFIL_AUDIO_PLL1]))
+ micfil->clk_src[MICFIL_AUDIO_PLL1] = NULL;
+
+ micfil->clk_src[MICFIL_AUDIO_PLL2] = devm_clk_get(&pdev->dev, "pll11k");
+ if (IS_ERR(micfil->clk_src[MICFIL_AUDIO_PLL2]))
+ micfil->clk_src[MICFIL_AUDIO_PLL2] = NULL;
+
+ micfil->clk_src[MICFIL_CLK_EXT3] = devm_clk_get(&pdev->dev, "clkext3");
+ if (IS_ERR(micfil->clk_src[MICFIL_CLK_EXT3]))
+ micfil->clk_src[MICFIL_CLK_EXT3] = NULL;
+
+ /* init regmap */
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ regs = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(regs))
+ return PTR_ERR(regs);
+
+ micfil->regmap = devm_regmap_init_mmio_clk(&pdev->dev,
+ "ipg_clk",
+ regs,
+ &fsl_micfil_regmap_config);
+ if (IS_ERR(micfil->regmap)) {
+ dev_err(&pdev->dev, "failed to init MICFIL regmap: %ld\n",
+ PTR_ERR(micfil->regmap));
+ return PTR_ERR(micfil->regmap);
+ }
+
+ /* dataline mask for RX */
+ ret = of_property_read_u32_index(np,
+ "fsl,dataline",
+ 0,
+ &micfil->dataline);
+ if (ret)
+ micfil->dataline = 1;
+
+ if (micfil->dataline & ~micfil->soc->dataline) {
+ dev_err(&pdev->dev, "dataline setting error, Mask is 0x%X\n",
+ micfil->soc->dataline);
+ return -EINVAL;
+ }
+
+ /* get IRQs */
+ for (i = 0; i < MICFIL_IRQ_LINES; i++) {
+ micfil->irq[i] = platform_get_irq(pdev, i);
+ dev_err(&pdev->dev, "GET IRQ: %d\n", micfil->irq[i]);
+ if (micfil->irq[i] < 0) {
+ dev_err(&pdev->dev, "no irq for node %s\n", pdev->name);
+ return micfil->irq[i];
+ }
+ }
+
+ if (of_property_read_bool(np, "fsl,shared-interrupt"))
+ irqflag = IRQF_SHARED;
+
+ /* Digital Microphone interface voice activity detector event
+ * interrupt - IRQ 44
+ */
+ ret = devm_request_threaded_irq(&pdev->dev, micfil->irq[0],
+ hwvad_isr, voice_detected_fn,
+ irqflag, micfil->name, micfil);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to claim hwvad event irq %u\n",
+ micfil->irq[0]);
+ return ret;
+ }
+
+ /* Digital Microphone interface voice activity detector error
+ * interrupt - IRQ 45
+ */
+ ret = devm_request_irq(&pdev->dev, micfil->irq[1],
+ hwvad_err_isr, irqflag,
+ micfil->name, micfil);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to claim hwvad error irq %u\n",
+ micfil->irq[1]);
+ return ret;
+ }
+
+ /* Digital Microphone interface interrupt - IRQ 109 */
+ ret = devm_request_irq(&pdev->dev, micfil->irq[2],
+ micfil_isr, irqflag,
+ micfil->name, micfil);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to claim mic interface irq %u\n",
+ micfil->irq[2]);
+ return ret;
+ }
+
+ /* Digital Microphone interface error interrupt - IRQ 110 */
+ ret = devm_request_irq(&pdev->dev, micfil->irq[3],
+ micfil_err_isr, irqflag,
+ micfil->name, micfil);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to claim mic interface error irq %u\n",
+ micfil->irq[3]);
+ return ret;
+ }
+
+ micfil->slave_mode = false;
+
+ micfil->dma_params_rx.chan_name = "rx";
+ micfil->dma_params_rx.addr = res->start + REG_MICFIL_DATACH0;
+ micfil->dma_params_rx.maxburst = MICFIL_DMA_MAXBURST_RX;
+
+ /* set default rate to first value in available vad rates */
+ micfil->vad_rate_index = 0;
+
+ platform_set_drvdata(pdev, micfil);
+
+ pm_runtime_enable(&pdev->dev);
+
+ ret = devm_snd_soc_register_component(&pdev->dev, &fsl_micfil_component,
+ &fsl_micfil_dai, 1);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to register component %s\n",
+ fsl_micfil_component.name);
+ return ret;
+ }
+
+ if (micfil->soc->imx)
+ ret = imx_pcm_platform_register(&pdev->dev);
+ else
+ ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0);
+
+ if (ret) {
+ dev_err(&pdev->dev, "failed to pcm register\n");
+ return ret;
+ }
+
+ /* create sysfs entry used to enable hwvad from userspace */
+ micfil->hwvad_kobject = kobject_create_and_add("hwvad",
+ &pdev->dev.kobj);
+ if (!micfil->hwvad_kobject)
+ return -ENOMEM;
+
+ ret = sysfs_create_file(micfil->hwvad_kobject,
+ &hwvad_en_attr.attr);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to create file for hwvad_enable\n");
+ kobject_put(micfil->hwvad_kobject);
+ return -ENOMEM;
+ }
+
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int __maybe_unused fsl_micfil_runtime_suspend(struct device *dev)
+{
+ struct fsl_micfil *micfil = dev_get_drvdata(dev);
+ u32 state;
+
+ state = atomic_read(&micfil->hwvad_state);
+ if (state == MICFIL_HWVAD_ON)
+ return 0;
+
+ regcache_cache_only(micfil->regmap, true);
+
+ /* Disable the clock only if the hwvad is not enabled */
+ if (state == MICFIL_HWVAD_OFF)
+ clk_disable_unprepare(micfil->mclk);
+
+ return 0;
+}
+
+static int __maybe_unused fsl_micfil_runtime_resume(struct device *dev)
+{
+ struct fsl_micfil *micfil = dev_get_drvdata(dev);
+ int ret;
+ u32 state;
+
+ state = atomic_read(&micfil->hwvad_state);
+
+ /* enable mclk only if the hwvad is not enabled
+ * When hwvad is enabled, clock won't be disabled
+ * in suspend since hwvad and recording share the
+ * same clock
+ */
+ if (state == MICFIL_HWVAD_ON)
+ return 0;
+
+ ret = clk_prepare_enable(micfil->mclk);
+ if (ret < 0)
+ return ret;
+
+ regcache_cache_only(micfil->regmap, false);
+ regcache_mark_dirty(micfil->regmap);
+ regcache_sync(micfil->regmap);
+
+ return 0;
+}
+#endif /* CONFIG_PM*/
+
+#ifdef CONFIG_PM_SLEEP
+static int __maybe_unused fsl_micfil_suspend(struct device *dev)
+{
+ struct fsl_micfil *micfil = dev_get_drvdata(dev);
+ int ret;
+ u32 state;
+
+ state = atomic_read(&micfil->hwvad_state);
+
+ if (state == MICFIL_HWVAD_ON) {
+ dev_err(dev, "Disabling hwvad on suspend");
+ ret = disable_hwvad(dev, false);
+ if (ret)
+ dev_warn(dev, "Failed to disable hwvad");
+ }
+
+ pm_runtime_force_suspend(dev);
+
+ return 0;
+}
+
+static int __maybe_unused fsl_micfil_resume(struct device *dev)
+{
+ struct fsl_micfil *micfil = dev_get_drvdata(dev);
+ int ret;
+ u32 state;
+
+ pm_runtime_force_resume(dev);
+
+ state = atomic_read(&micfil->hwvad_state);
+ if (state == MICFIL_HWVAD_ON) {
+ dev_err(dev, "Enabling hwvad on resume");
+ ret = enable_hwvad(dev, false);
+ if (ret)
+ dev_warn(dev, "Failed to re-enable hwvad");
+ }
+
+ return 0;
+}
+#endif /* CONFIG_PM_SLEEP */
+
+static const struct dev_pm_ops fsl_micfil_pm_ops = {
+ SET_RUNTIME_PM_OPS(fsl_micfil_runtime_suspend,
+ fsl_micfil_runtime_resume,
+ NULL)
+ SET_SYSTEM_SLEEP_PM_OPS(fsl_micfil_suspend,
+ fsl_micfil_resume)
+};
+
+static struct platform_driver fsl_micfil_driver = {
+ .probe = fsl_micfil_probe,
+ .driver = {
+ .name = "fsl-micfil-dai",
+ .pm = &fsl_micfil_pm_ops,
+ .of_match_table = fsl_micfil_dt_ids,
+ },
+};
+module_platform_driver(fsl_micfil_driver);
+
+MODULE_AUTHOR("Cosmin-Gabriel Samoila <cosmin.samoila@nxp.com>");
+MODULE_DESCRIPTION("NXP PDM Microphone Interface (MICFIL) driver");
+MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/fsl/fsl_micfil.h b/sound/soc/fsl/fsl_micfil.h
new file mode 100644
index 000000000000..792187b717f0
--- /dev/null
+++ b/sound/soc/fsl/fsl_micfil.h
@@ -0,0 +1,317 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * PDM Microphone Interface for the NXP i.MX SoC
+ * Copyright 2018 NXP
+ */
+
+#ifndef _FSL_MICFIL_H
+#define _FSL_MICFIL_H
+
+/* MICFIL Register Map */
+#define REG_MICFIL_CTRL1 0x00
+#define REG_MICFIL_CTRL2 0x04
+#define REG_MICFIL_STAT 0x08
+#define REG_MICFIL_FIFO_CTRL 0x10
+#define REG_MICFIL_FIFO_STAT 0x14
+#define REG_MICFIL_DATACH0 0x24
+#define REG_MICFIL_DATACH1 0x28
+#define REG_MICFIL_DATACH2 0x2C
+#define REG_MICFIL_DATACH3 0x30
+#define REG_MICFIL_DATACH4 0x34
+#define REG_MICFIL_DATACH5 0x38
+#define REG_MICFIL_DATACH6 0x3C
+#define REG_MICFIL_DATACH7 0x40
+#define REG_MICFIL_DC_CTRL 0x64
+#define REG_MICFIL_OUT_CTRL 0x74
+#define REG_MICFIL_OUT_STAT 0x7C
+#define REG_MICFIL_VAD0_CTRL1 0x90
+#define REG_MICFIL_VAD0_CTRL2 0x94
+#define REG_MICFIL_VAD0_STAT 0x98
+#define REG_MICFIL_VAD0_SCONFIG 0x9C
+#define REG_MICFIL_VAD0_NCONFIG 0xA0
+#define REG_MICFIL_VAD0_NDATA 0xA4
+#define REG_MICFIL_VAD0_ZCD 0xA8
+
+/* MICFIL Control Register 1 -- REG_MICFILL_CTRL1 0x00 */
+#define MICFIL_CTRL1_MDIS_SHIFT 31
+#define MICFIL_CTRL1_MDIS_MASK BIT(MICFIL_CTRL1_MDIS_SHIFT)
+#define MICFIL_CTRL1_MDIS BIT(MICFIL_CTRL1_MDIS_SHIFT)
+#define MICFIL_CTRL1_DOZEN_SHIFT 30
+#define MICFIL_CTRL1_DOZEN_MASK BIT(MICFIL_CTRL1_DOZEN_SHIFT)
+#define MICFIL_CTRL1_DOZEN BIT(MICFIL_CTRL1_DOZEN_SHIFT)
+#define MICFIL_CTRL1_PDMIEN_SHIFT 29
+#define MICFIL_CTRL1_PDMIEN_MASK BIT(MICFIL_CTRL1_PDMIEN_SHIFT)
+#define MICFIL_CTRL1_PDMIEN BIT(MICFIL_CTRL1_PDMIEN_SHIFT)
+#define MICFIL_CTRL1_DBG_SHIFT 28
+#define MICFIL_CTRL1_DBG_MASK BIT(MICFIL_CTRL1_DBG_SHIFT)
+#define MICFIL_CTRL1_DBG BIT(MICFIL_CTRL1_DBG_SHIFT)
+#define MICFIL_CTRL1_SRES_SHIFT 27
+#define MICFIL_CTRL1_SRES_MASK BIT(MICFIL_CTRL1_SRES_SHIFT)
+#define MICFIL_CTRL1_SRES BIT(MICFIL_CTRL1_SRES_SHIFT)
+#define MICFIL_CTRL1_DBGE_SHIFT 26
+#define MICFIL_CTRL1_DBGE_MASK BIT(MICFIL_CTRL1_DBGE_SHIFT)
+#define MICFIL_CTRL1_DBGE BIT(MICFIL_CTRL1_DBGE_SHIFT)
+#define MICFIL_CTRL1_DISEL_SHIFT 24
+#define MICFIL_CTRL1_DISEL_WIDTH 2
+#define MICFIL_CTRL1_DISEL_MASK ((BIT(MICFIL_CTRL1_DISEL_WIDTH) - 1) \
+ << MICFIL_CTRL1_DISEL_SHIFT)
+#define MICFIL_CTRL1_DISEL(v) (((v) << MICFIL_CTRL1_DISEL_SHIFT) \
+ & MICFIL_CTRL1_DISEL_MASK)
+#define MICFIL_CTRL1_ERREN_SHIFT 23
+#define MICFIL_CTRL1_ERREN_MASK BIT(MICFIL_CTRL1_ERREN_SHIFT)
+#define MICFIL_CTRL1_ERREN BIT(MICFIL_CTRL1_ERREN_SHIFT)
+#define MICFIL_CTRL1_CHEN_SHIFT 0
+#define MICFIL_CTRL1_CHEN_WIDTH 8
+#define MICFIL_CTRL1_CHEN_MASK(x) (BIT(x) << MICFIL_CTRL1_CHEN_SHIFT)
+#define MICFIL_CTRL1_CHEN(x) (MICFIL_CTRL1_CHEN_MASK(x))
+
+/* MICFIL Control Register 2 -- REG_MICFILL_CTRL2 0x04 */
+#define MICFIL_CTRL2_QSEL_SHIFT 25
+#define MICFIL_CTRL2_QSEL_WIDTH 3
+#define MICFIL_CTRL2_QSEL_MASK ((BIT(MICFIL_CTRL2_QSEL_WIDTH) - 1) \
+ << MICFIL_CTRL2_QSEL_SHIFT)
+#define MICFIL_HIGH_QUALITY BIT(MICFIL_CTRL2_QSEL_SHIFT)
+#define MICFIL_MEDIUM_QUALITY (0 << MICFIL_CTRL2_QSEL_SHIFT)
+#define MICFIL_LOW_QUALITY (7 << MICFIL_CTRL2_QSEL_SHIFT)
+#define MICFIL_VLOW0_QUALITY (6 << MICFIL_CTRL2_QSEL_SHIFT)
+#define MICFIL_VLOW1_QUALITY (5 << MICFIL_CTRL2_QSEL_SHIFT)
+#define MICFIL_VLOW2_QUALITY (4 << MICFIL_CTRL2_QSEL_SHIFT)
+
+#define MICFIL_CTRL2_CICOSR_SHIFT 16
+#define MICFIL_CTRL2_CICOSR_WIDTH 4
+#define MICFIL_CTRL2_CICOSR_MASK ((BIT(MICFIL_CTRL2_CICOSR_WIDTH) - 1) \
+ << MICFIL_CTRL2_CICOSR_SHIFT)
+#define MICFIL_CTRL2_CICOSR(v) (((v) << MICFIL_CTRL2_CICOSR_SHIFT) \
+ & MICFIL_CTRL2_CICOSR_MASK)
+#define MICFIL_CTRL2_CLKDIV_SHIFT 0
+#define MICFIL_CTRL2_CLKDIV_WIDTH 8
+#define MICFIL_CTRL2_CLKDIV_MASK ((BIT(MICFIL_CTRL2_CLKDIV_WIDTH) - 1) \
+ << MICFIL_CTRL2_CLKDIV_SHIFT)
+#define MICFIL_CTRL2_CLKDIV(v) (((v) << MICFIL_CTRL2_CLKDIV_SHIFT) \
+ & MICFIL_CTRL2_CLKDIV_MASK)
+
+/* MICFIL Status Register -- REG_MICFIL_STAT 0x08 */
+#define MICFIL_STAT_BSY_FIL_SHIFT 31
+#define MICFIL_STAT_BSY_FIL_MASK BIT(MICFIL_STAT_BSY_FIL_SHIFT)
+#define MICFIL_STAT_BSY_FIL BIT(MICFIL_STAT_BSY_FIL_SHIFT)
+#define MICFIL_STAT_FIR_RDY_SHIFT 30
+#define MICFIL_STAT_FIR_RDY_MASK BIT(MICFIL_STAT_FIR_RDY_SHIFT)
+#define MICFIL_STAT_FIR_RDY BIT(MICFIL_STAT_FIR_RDY_SHIFT)
+#define MICFIL_STAT_LOWFREQF_SHIFT 29
+#define MICFIL_STAT_LOWFREQF_MASK BIT(MICFIL_STAT_LOWFREQF_SHIFT)
+#define MICFIL_STAT_LOWFREQF BIT(MICFIL_STAT_LOWFREQF_SHIFT)
+#define MICFIL_STAT_CHXF_SHIFT(v) (v)
+#define MICFIL_STAT_CHXF_MASK(v) BIT(MICFIL_STAT_CHXF_SHIFT(v))
+#define MICFIL_STAT_CHXF(v) BIT(MICFIL_STAT_CHXF_SHIFT(v))
+
+/* MICFIL FIFO Control Register -- REG_MICFIL_FIFO_CTRL 0x10 */
+#define MICFIL_FIFO_CTRL_FIFOWMK_SHIFT 0
+#define MICFIL_FIFO_CTRL_FIFOWMK_WIDTH 3
+#define MICFIL_FIFO_CTRL_FIFOWMK_MASK ((BIT(MICFIL_FIFO_CTRL_FIFOWMK_WIDTH) - 1) \
+ << MICFIL_FIFO_CTRL_FIFOWMK_SHIFT)
+#define MICFIL_FIFO_CTRL_FIFOWMK(v) (((v) << MICFIL_FIFO_CTRL_FIFOWMK_SHIFT) \
+ & MICFIL_FIFO_CTRL_FIFOWMK_MASK)
+
+/* MICFIL FIFO Status Register -- REG_MICFIL_FIFO_STAT 0x14 */
+#define MICFIL_FIFO_STAT_FIFOX_OVER_SHIFT(v) (v)
+#define MICFIL_FIFO_STAT_FIFOX_OVER_MASK(v) BIT(MICFIL_FIFO_STAT_FIFOX_OVER_SHIFT(v))
+#define MICFIL_FIFO_STAT_FIFOX_UNDER_SHIFT(v) ((v) + 8)
+#define MICFIL_FIFO_STAT_FIFOX_UNDER_MASK(v) BIT(MICFIL_FIFO_STAT_FIFOX_UNDER_SHIFT(v))
+
+/* MICFIL HWVAD0 Control 1 Register -- REG_MICFIL_VAD0_CTRL1*/
+#define MICFIL_VAD0_CTRL1_CHSEL_SHIFT 24
+#define MICFIL_VAD0_CTRL1_CHSEL_WIDTH 3
+#define MICFIL_VAD0_CTRL1_CHSEL_MASK ((BIT(MICFIL_VAD0_CTRL1_CHSEL_WIDTH) - 1) \
+ << MICFIL_VAD0_CTRL1_CHSEL_SHIFT)
+#define MICFIL_VAD0_CTRL1_CHSEL(v) (((v) << MICFIL_VAD0_CTRL1_CHSEL_SHIFT) \
+ & MICFIL_VAD0_CTRL1_CHSEL_MASK)
+#define MICFIL_VAD0_CTRL1_CICOSR_SHIFT 16
+#define MICFIL_VAD0_CTRL1_CICOSR_WIDTH 4
+#define MICFIL_VAD0_CTRL1_CICOSR_MASK ((BIT(MICFIL_VAD0_CTRL1_CICOSR_WIDTH) - 1) \
+ << MICFIL_VAD0_CTRL1_CICOSR_SHIFT)
+#define MICFIL_VAD0_CTRL1_CICOSR(v) (((v) << MICFIL_VAD0_CTRL1_CICOSR_SHIFT) \
+ & MICFIL_VAD0_CTRL1_CICOSR_MASK)
+#define MICFIL_VAD0_CTRL1_INITT_SHIFT 8
+#define MICFIL_VAD0_CTRL1_INITT_WIDTH 5
+#define MICFIL_VAD0_CTRL1_INITT_MASK ((BIT(MICFIL_VAD0_CTRL1_INITT_WIDTH) - 1) \
+ << MICFIL_VAD0_CTRL1_INITT_SHIFT)
+#define MICFIL_VAD0_CTRL1_INITT(v) (((v) << MICFIL_VAD0_CTRL1_INITT_SHIFT) \
+ & MICFIL_VAD0_CTRL1_INITT_MASK)
+#define MICFIL_VAD0_CTRL1_ST10_SHIFT 4
+#define MICFIL_VAD0_CTRL1_ST10_MASK BIT(MICFIL_VAD0_CTRL1_ST10_SHIFT)
+#define MICFIL_VAD0_CTRL1_ST10 BIT(MICFIL_VAD0_CTRL1_ST10_SHIFT)
+#define MICFIL_VAD0_CTRL1_ERIE_SHIFT 3
+#define MICFIL_VAD0_CTRL1_ERIE_MASK BIT(MICFIL_VAD0_CTRL1_ERIE_SHIFT)
+#define MICFIL_VAD0_CTRL1_ERIE BIT(MICFIL_VAD0_CTRL1_ERIE_SHIFT)
+#define MICFIL_VAD0_CTRL1_IE_SHIFT 2
+#define MICFIL_VAD0_CTRL1_IE_MASK BIT(MICFIL_VAD0_CTRL1_IE_SHIFT)
+#define MICFIL_VAD0_CTRL1_IE BIT(MICFIL_VAD0_CTRL1_IE_SHIFT)
+#define MICFIL_VAD0_CTRL1_RST_SHIFT 1
+#define MICFIL_VAD0_CTRL1_RST_MASK BIT(MICFIL_VAD0_CTRL1_RST_SHIFT)
+#define MICFIL_VAD0_CTRL1_RST BIT(MICFIL_VAD0_CTRL1_RST_SHIFT)
+#define MICFIL_VAD0_CTRL1_EN_SHIFT 0
+#define MICFIL_VAD0_CTRL1_EN_MASK BIT(MICFIL_VAD0_CTRL1_EN_SHIFT)
+#define MICFIL_VAD0_CTRL1_EN BIT(MICFIL_VAD0_CTRL1_EN_SHIFT)
+
+/* MICFIL HWVAD0 Control 2 Register -- REG_MICFIL_VAD0_CTRL2*/
+#define MICFIL_VAD0_CTRL2_FRENDIS_SHIFT 31
+#define MICFIL_VAD0_CTRL2_FRENDIS_MASK BIT(MICFIL_VAD0_CTRL2_FRENDIS_SHIFT)
+#define MICFIL_VAD0_CTRL2_FRENDIS BIT(MICFIL_VAD0_CTRL2_FRENDIS_SHIFT)
+#define MICFIL_VAD0_CTRL2_PREFEN_SHIFT 30
+#define MICFIL_VAD0_CTRL2_PREFEN_MASK BIT(MICFIL_VAD0_CTRL2_PREFEN_SHIFT)
+#define MICFIL_VAD0_CTRL2_PREFEN BIT(MICFIL_VAD0_CTRL2_PREFEN_SHIFT)
+#define MICFIL_VAD0_CTRL2_FOUTDIS_SHIFT 28
+#define MICFIL_VAD0_CTRL2_FOUTDIS_MASK BIT(MICFIL_VAD0_CTRL2_FOUTDIS_SHIFT)
+#define MICFIL_VAD0_CTRL2_FOUTDIS BIT(MICFIL_VAD0_CTRL2_FOUTDIS_SHIFT)
+#define MICFIL_VAD0_CTRL2_FRAMET_SHIFT 16
+#define MICFIL_VAD0_CTRL2_FRAMET_WIDTH 6
+#define MICFIL_VAD0_CTRL2_FRAMET_MASK ((BIT(MICFIL_VAD0_CTRL2_FRAMET_WIDTH) - 1) \
+ << MICFIL_VAD0_CTRL2_FRAMET_SHIFT)
+#define MICFIL_VAD0_CTRL2_FRAMET(v) (((v) << MICFIL_VAD0_CTRL2_FRAMET_SHIFT) \
+ & MICFIL_VAD0_CTRL2_FRAMET_MASK)
+#define MICFIL_VAD0_CTRL2_INPGAIN_SHIFT 8
+#define MICFIL_VAD0_CTRL2_INPGAIN_WIDTH 4
+#define MICFIL_VAD0_CTRL2_INPGAIN_MASK ((BIT(MICFIL_VAD0_CTRL2_INPGAIN_WIDTH) - 1) \
+ << MICFIL_VAD0_CTRL2_INPGAIN_SHIFT)
+#define MICFIL_VAD0_CTRL2_INPGAIN(v) (((v) << MICFIL_VAD0_CTRL2_INPGAIN_SHIFT) \
+ & MICFIL_VAD0_CTRL2_INPGAIN_MASK)
+#define MICFIL_VAD0_CTRL2_HPF_SHIFT 0
+#define MICFIL_VAD0_CTRL2_HPF_WIDTH 2
+#define MICFIL_VAD0_CTRL2_HPF_MASK ((BIT(MICFIL_VAD0_CTRL2_HPF_WIDTH) - 1) \
+ << MICFIL_VAD0_CTRL2_HPF_SHIFT)
+#define MICFIL_VAD0_CTRL2_HPF(v) (((v) << MICFIL_VAD0_CTRL2_HPF_SHIFT) \
+ & MICFIL_VAD0_CTRL2_HPF_MASK)
+
+/* MICFIL HWVAD0 Signal CONFIG Register -- REG_MICFIL_VAD0_SCONFIG */
+#define MICFIL_VAD0_SCONFIG_SFILEN_SHIFT 31
+#define MICFIL_VAD0_SCONFIG_SFILEN_MASK BIT(MICFIL_VAD0_SCONFIG_SFILEN_SHIFT)
+#define MICFIL_VAD0_SCONFIG_SFILEN BIT(MICFIL_VAD0_SCONFIG_SFILEN_SHIFT)
+#define MICFIL_VAD0_SCONFIG_SMAXEN_SHIFT 30
+#define MICFIL_VAD0_SCONFIG_SMAXEN_MASK BIT(MICFIL_VAD0_SCONFIG_SMAXEN_SHIFT)
+#define MICFIL_VAD0_SCONFIG_SMAXEN BIT(MICFIL_VAD0_SCONFIG_SMAXEN_SHIFT)
+#define MICFIL_VAD0_SCONFIG_SGAIN_SHIFT 0
+#define MICFIL_VAD0_SCONFIG_SGAIN_WIDTH 4
+#define MICFIL_VAD0_SCONFIG_SGAIN_MASK ((BIT(MICFIL_VAD0_SCONFIG_SGAIN_WIDTH) - 1) \
+ << MICFIL_VAD0_SCONFIG_SGAIN_SHIFT)
+#define MICFIL_VAD0_SCONFIG_SGAIN(v) (((v) << MICFIL_VAD0_SCONFIG_SGAIN_SHIFT) \
+ & MICFIL_VAD0_SCONFIG_SGAIN_MASK)
+
+/* MICFIL HWVAD0 Noise CONFIG Register -- REG_MICFIL_VAD0_NCONFIG */
+#define MICFIL_VAD0_NCONFIG_NFILAUT_SHIFT 31
+#define MICFIL_VAD0_NCONFIG_NFILAUT_MASK BIT(MICFIL_VAD0_NCONFIG_NFILAUT_SHIFT)
+#define MICFIL_VAD0_NCONFIG_NFILAUT BIT(MICFIL_VAD0_NCONFIG_NFILAUT_SHIFT)
+#define MICFIL_VAD0_NCONFIG_NMINEN_SHIFT 30
+#define MICFIL_VAD0_NCONFIG_NMINEN_MASK BIT(MICFIL_VAD0_NCONFIG_NMINEN_SHIFT)
+#define MICFIL_VAD0_NCONFIG_NMINEN BIT(MICFIL_VAD0_NCONFIG_NMINEN_SHIFT)
+#define MICFIL_VAD0_NCONFIG_NDECEN_SHIFT 29
+#define MICFIL_VAD0_NCONFIG_NDECEN_MASK BIT(MICFIL_VAD0_NCONFIG_NDECEN_SHIFT)
+#define MICFIL_VAD0_NCONFIG_NDECEN BIT(MICFIL_VAD0_NCONFIG_NDECEN_SHIFT)
+#define MICFIL_VAD0_NCONFIG_NOREN_SHIFT 28
+#define MICFIL_VAD0_NCONFIG_NOREN BIT(MICFIL_VAD0_NCONFIG_NOREN_SHIFT)
+#define MICFIL_VAD0_NCONFIG_NFILADJ_SHIFT 8
+#define MICFIL_VAD0_NCONFIG_NFILADJ_WIDTH 5
+#define MICFIL_VAD0_NCONFIG_NFILADJ_MASK ((BIT(MICFIL_VAD0_NCONFIG_NFILADJ_WIDTH) - 1) \
+ << MICFIL_VAD0_NCONFIG_NFILADJ_SHIFT)
+#define MICFIL_VAD0_NCONFIG_NFILADJ(v) (((v) << MICFIL_VAD0_NCONFIG_NFILADJ_SHIFT) \
+ & MICFIL_VAD0_NCONFIG_NFILADJ_MASK)
+#define MICFIL_VAD0_NCONFIG_NGAIN_SHIFT 0
+#define MICFIL_VAD0_NCONFIG_NGAIN_WIDTH 4
+#define MICFIL_VAD0_NCONFIG_NGAIN_MASK ((BIT(MICFIL_VAD0_NCONFIG_NGAIN_WIDTH) - 1) \
+ << MICFIL_VAD0_NCONFIG_NGAIN_SHIFT)
+#define MICFIL_VAD0_NCONFIG_NGAIN(v) (((v) << MICFIL_VAD0_NCONFIG_NGAIN_SHIFT) \
+ & MICFIL_VAD0_NCONFIG_NGAIN_MASK)
+
+/* MICFIL HWVAD0 Zero-Crossing Detector - REG_MICFIL_VAD0_ZCD */
+#define MICFIL_VAD0_ZCD_ZCDTH_SHIFT 16
+#define MICFIL_VAD0_ZCD_ZCDTH_WIDTH 10
+#define MICFIL_VAD0_ZCD_ZCDTH_MASK ((BIT(MICFIL_VAD0_ZCD_ZCDTH_WIDTH) - 1) \
+ << MICFIL_VAD0_ZCD_ZCDTH_SHIFT)
+#define MICFIL_VAD0_ZCD_ZCDTH(v) (((v) << MICFIL_VAD0_ZCD_ZCDTH_SHIFT)\
+ & MICFIL_VAD0_ZCD_ZCDTH_MASK)
+#define MICFIL_VAD0_ZCD_ZCDADJ_SHIFT 8
+#define MICFIL_VAD0_ZCD_ZCDADJ_WIDTH 4
+#define MICFIL_VAD0_ZCD_ZCDADJ_MASK ((BIT(MICFIL_VAD0_ZCD_ZCDADJ_WIDTH) - 1)\
+ << MICFIL_VAD0_ZCD_ZCDADJ_SHIFT)
+#define MICFIL_VAD0_ZCD_ZCDADJ(v) (((v) << MICFIL_VAD0_ZCD_ZCDADJ_SHIFT)\
+ & MICFIL_VAD0_ZCD_ZCDADJ_MASK)
+#define MICFIL_VAD0_ZCD_ZCDAND_SHIFT 4
+#define MICFIL_VAD0_ZCD_ZCDAND_MASK BIT(MICFIL_VAD0_ZCD_ZCDAND_SHIFT)
+#define MICFIL_VAD0_ZCD_ZCDAND BIT(MICFIL_VAD0_ZCD_ZCDAND_SHIFT)
+#define MICFIL_VAD0_ZCD_ZCDAUT_SHIFT 2
+#define MICFIL_VAD0_ZCD_ZCDAUT_MASK BIT(MICFIL_VAD0_ZCD_ZCDAUT_SHIFT)
+#define MICFIL_VAD0_ZCD_ZCDAUT BIT(MICFIL_VAD0_ZCD_ZCDAUT_SHIFT)
+#define MICFIL_VAD0_ZCD_ZCDEN_SHIFT 0
+#define MICFIL_VAD0_ZCD_ZCDEN_MASK BIT(MICFIL_VAD0_ZCD_ZCDEN_SHIFT)
+#define MICFIL_VAD0_ZCD_ZCDEN BIT(MICFIL_VAD0_ZCD_ZCDEN_SHIFT)
+
+/* MICFIL HWVAD0 Status Register - REG_MICFIL_VAD0_STAT */
+#define MICFIL_VAD0_STAT_INITF_SHIFT 31
+#define MICFIL_VAD0_STAT_INITF_MASK BIT(MICFIL_VAD0_STAT_INITF_SHIFT)
+#define MICFIL_VAD0_STAT_INITF BIT(MICFIL_VAD0_STAT_INITF_SHIFT)
+#define MICFIL_VAD0_STAT_INSATF_SHIFT 16
+#define MICFIL_VAD0_STAT_INSATF_MASK BIT(MICFIL_VAD0_STAT_INSATF_SHIFT)
+#define MICFIL_VAD0_STAT_INSATF BIT(MICFIL_VAD0_STAT_INSATF_SHIFT)
+#define MICFIL_VAD0_STAT_EF_SHIFT 15
+#define MICFIL_VAD0_STAT_EF_MASK BIT(MICFIL_VAD0_STAT_EF_SHIFT)
+#define MICFIL_VAD0_STAT_EF BIT(MICFIL_VAD0_STAT_EF_SHIFT)
+#define MICFIL_VAD0_STAT_IF_SHIFT 0
+#define MICFIL_VAD0_STAT_IF_MASK BIT(MICFIL_VAD0_STAT_IF_SHIFT)
+#define MICFIL_VAD0_STAT_IF BIT(MICFIL_VAD0_STAT_IF_SHIFT)
+
+/* HWVAD Constants */
+#define MICFIL_HWVAD_ENVELOPE_MODE 0
+#define MICFIL_HWVAD_ENERGY_MODE 1
+#define MICFIL_HWVAD_INIT_FRAMES 10
+#define MICFIL_HWVAD_INPGAIN 0
+#define MICFIL_HWVAD_SGAIN 6
+#define MICFIL_HWVAD_NGAIN 3
+#define MICFIL_HWVAD_NFILADJ 0
+#define MICFIL_HWVAD_ZCDADJ (1 << (MICFIL_VAD0_ZCD_ZCDADJ_WIDTH - 2))
+#define MICFIL_HWVAD_ZCDTH 10 /* initial threshold value */
+#define MICFIL_HWVAD_ZCDOR 0
+#define MICFIL_HWVAD_ZCDAND 1
+#define MICFIL_HWVAD_ZCD_MANUAL 0
+#define MICFIL_HWVAD_ZCD_AUTO 1
+#define MICFIL_HWVAD_HPF_BYPASS 0
+#define MICFIL_HWVAD_HPF_1750HZ 1
+#define MICFIL_HWVAD_HPF_215HZ 2
+#define MICFIL_HWVAD_HPF_102HZ 3
+#define MICFIL_HWVAD_FRAMET_DEFAULT 10
+
+/* MICFIL Output Control Register */
+#define MICFIL_OUTGAIN_CHX_SHIFT(v) (4 * (v))
+
+/* Constants */
+#define MICFIL_DMA_IRQ_DISABLED(v) ((v) & MICFIL_CTRL1_DISEL_MASK)
+#define MICFIL_DMA_ENABLED(v) ((0x1 << MICFIL_CTRL1_DISEL_SHIFT) \
+ == ((v) & MICFIL_CTRL1_DISEL_MASK))
+#define MICFIL_IRQ_ENABLED(v) ((0x2 << MICFIL_CTRL1_DISEL_SHIFT) \
+ == ((v) & MICFIL_CTRL1_DISEL_MASK))
+#define MICFIL_OUTPUT_CHANNELS 8
+#define MICFIL_FIFO_NUM 8
+
+#define FIFO_PTRWID 3
+#define FIFO_LEN BIT(FIFO_PTRWID)
+
+#define MICFIL_IRQ_LINES 4
+#define MICFIL_MAX_RETRY 25
+#define MICFIL_SLEEP_MIN 90000 /* in us */
+#define MICFIL_SLEEP_MAX 100000 /* in us */
+#define MICFIL_DMA_MAXBURST_RX 6
+#define MICFIL_CTRL2_OSR_DEFAULT (0 << MICFIL_CTRL2_CICOSR_SHIFT)
+#define MICFIL_DEFAULT_RATE 48000
+#define MICFIL_CLK_SRC_NUM 3
+#define MICFIL_CLK_AUTO 0
+
+/* clock source ids */
+#define MICFIL_AUDIO_PLL1 0
+#define MICFIL_AUDIO_PLL2 1
+#define MICFIL_CLK_EXT3 2
+
+/* States of micfil */
+#define MICFIL_HWVAD_OFF 0
+#define MICFIL_HWVAD_ON 1
+#define MICFIL_RECORDING_OFF 0
+#define MICFIL_RECORDING_ON 1
+
+#endif /* _FSL_MICFIL_H */
diff --git a/sound/soc/fsl/fsl_rpmsg_i2s.c b/sound/soc/fsl/fsl_rpmsg_i2s.c
new file mode 100644
index 000000000000..5a82340c2d6d
--- /dev/null
+++ b/sound/soc/fsl/fsl_rpmsg_i2s.c
@@ -0,0 +1,380 @@
+/*
+ * Freescale ALSA SoC rpmsg i2s driver.
+ *
+ * Copyright 2017 NXP
+ *
+ * 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/clk.h>
+#include <linux/delay.h>
+#include <linux/dmaengine.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/of_address.h>
+#include <linux/pm_runtime.h>
+#include <linux/rpmsg.h>
+#include <linux/slab.h>
+
+#include <sound/core.h>
+#include <sound/dmaengine_pcm.h>
+#include <sound/pcm_params.h>
+
+#include "fsl_rpmsg_i2s.h"
+#include "imx-pcm.h"
+
+#define FSL_RPMSG_I2S_RATES (SNDRV_PCM_RATE_8000|SNDRV_PCM_RATE_16000|\
+ SNDRV_PCM_RATE_48000)
+#define FSL_RPMSG_I2S_FORMATS SNDRV_PCM_FMTBIT_S16_LE
+
+static int i2s_send_message(struct i2s_rpmsg *msg,
+ struct i2s_info *info)
+{
+ int err = 0;
+
+ mutex_lock(&info->tx_lock);
+ if (!info->rpdev) {
+ dev_err(info->dev, "rpmsg channel not ready, m4 image ready?\n");
+ mutex_unlock(&info->tx_lock);
+ return -EINVAL;
+ }
+
+ dev_dbg(&info->rpdev->dev, "send cmd %d\n", msg->send_msg.header.cmd);
+
+ if (!(msg->send_msg.header.type == I2S_TYPE_C))
+ reinit_completion(&info->cmd_complete);
+
+ err = rpmsg_send(info->rpdev->ept, (void *)&msg->send_msg,
+ sizeof(struct i2s_rpmsg_s));
+ if (err) {
+ dev_err(&info->rpdev->dev, "rpmsg_send failed: %d\n", err);
+ mutex_unlock(&info->tx_lock);
+ return err;
+ }
+
+ if (!(msg->send_msg.header.type == I2S_TYPE_C)) {
+ /* wait response from rpmsg */
+ err = wait_for_completion_timeout(&info->cmd_complete,
+ msecs_to_jiffies(RPMSG_TIMEOUT));
+ if (!err) {
+ dev_err(&info->rpdev->dev,
+ "rpmsg_send cmd %d timeout!\n",
+ msg->send_msg.header.cmd);
+ mutex_unlock(&info->tx_lock);
+ return -ETIMEDOUT;
+ }
+ memcpy(&msg->recv_msg, &info->recv_msg,
+ sizeof(struct i2s_rpmsg_r));
+ memcpy(&info->rpmsg[msg->recv_msg.header.cmd].recv_msg,
+ &msg->recv_msg, sizeof(struct i2s_rpmsg_r));
+ }
+
+ dev_dbg(&info->rpdev->dev, "cmd:%d, resp %d\n",
+ msg->send_msg.header.cmd,
+ info->recv_msg.param.resp);
+ mutex_unlock(&info->tx_lock);
+
+ return 0;
+}
+
+static const unsigned int fsl_rpmsg_rates[] = {
+ 8000, 11025, 16000, 22050, 44100,
+ 32000, 48000, 96000, 88200, 176400, 192000,
+ 352800, 384000, 705600, 768000, 1411200, 2822400,
+};
+
+static const struct snd_pcm_hw_constraint_list fsl_rpmsg_rate_constraints = {
+ .count = ARRAY_SIZE(fsl_rpmsg_rates),
+ .list = fsl_rpmsg_rates,
+};
+
+static int fsl_rpmsg_startup(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *cpu_dai)
+{
+ int ret;
+
+ ret = snd_pcm_hw_constraint_list(substream->runtime, 0,
+ SNDRV_PCM_HW_PARAM_RATE, &fsl_rpmsg_rate_constraints);
+
+ return ret;
+}
+
+static const struct snd_soc_dai_ops fsl_rpmsg_dai_ops = {
+ .startup = fsl_rpmsg_startup,
+};
+
+static struct snd_soc_dai_driver fsl_rpmsg_i2s_dai = {
+ .playback = {
+ .stream_name = "CPU-Playback",
+ .channels_min = 2,
+ .channels_max = 2,
+ .rates = SNDRV_PCM_RATE_KNOT,
+ .formats = FSL_RPMSG_I2S_FORMATS,
+ },
+ .capture = {
+ .stream_name = "CPU-Capture",
+ .channels_min = 2,
+ .channels_max = 2,
+ .rates = SNDRV_PCM_RATE_KNOT,
+ .formats = FSL_RPMSG_I2S_FORMATS,
+ },
+ .symmetric_rates = 1,
+ .symmetric_channels = 1,
+ .symmetric_samplebits = 1,
+ .ops = &fsl_rpmsg_dai_ops,
+};
+
+static const struct snd_soc_component_driver fsl_component = {
+ .name = "fsl-rpmsg-i2s",
+};
+
+static const struct of_device_id fsl_rpmsg_i2s_ids[] = {
+ { .compatible = "fsl,imx7ulp-rpmsg-i2s"},
+ { .compatible = "fsl,imx8mq-rpmsg-i2s"},
+ { .compatible = "fsl,imx8qxp-rpmsg-i2s"},
+ { .compatible = "fsl,imx8qm-rpmsg-i2s"},
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, fsl_rpmsg_i2s_ids);
+
+static void rpmsg_i2s_work(struct work_struct *work)
+{
+ struct work_of_rpmsg *work_of_rpmsg;
+ struct i2s_info *i2s_info;
+ bool is_period_done = false;
+
+ work_of_rpmsg = container_of(work, struct work_of_rpmsg, work);
+ i2s_info = work_of_rpmsg->i2s_info;
+
+ if (i2s_info->period_done_msg_enabled[0]) {
+ i2s_send_message(&i2s_info->period_done_msg[0], i2s_info);
+ i2s_info->period_done_msg_enabled[0] = false;
+ }
+
+ if (i2s_info->period_done_msg_enabled[1]) {
+ i2s_send_message(&i2s_info->period_done_msg[1], i2s_info);
+ i2s_info->period_done_msg_enabled[1] = false;
+ }
+
+ if (work_of_rpmsg->msg.send_msg.header.type == I2S_TYPE_C &&
+ (work_of_rpmsg->msg.send_msg.header.cmd == I2S_TX_PERIOD_DONE ||
+ work_of_rpmsg->msg.send_msg.header.cmd == I2S_RX_PERIOD_DONE))
+ is_period_done = true;
+
+ if (!is_period_done)
+ i2s_send_message(&work_of_rpmsg->msg, i2s_info);
+
+ i2s_info->work_read_index++;
+ i2s_info->work_read_index %= WORK_MAX_NUM;
+}
+
+static int fsl_rpmsg_i2s_probe(struct platform_device *pdev)
+{
+ struct device_node *np = pdev->dev.of_node;
+ struct fsl_rpmsg_i2s *rpmsg_i2s;
+ struct i2s_info *i2s_info;
+ int audioindex = 0;
+ int ret;
+ int i;
+
+ rpmsg_i2s = devm_kzalloc(&pdev->dev, sizeof(struct fsl_rpmsg_i2s),
+ GFP_KERNEL);
+ if (!rpmsg_i2s)
+ return -ENOMEM;
+
+ rpmsg_i2s->pdev = pdev;
+ i2s_info = &rpmsg_i2s->i2s_info;
+
+ ret = of_property_read_u32(np, "fsl,audioindex", &audioindex);
+ if (ret)
+ audioindex = 0;
+
+ /* Setup work queue */
+ i2s_info->rpmsg_wq = create_singlethread_workqueue("rpmsg_i2s");
+ if (i2s_info->rpmsg_wq == NULL) {
+ dev_err(&pdev->dev, "workqueue create failed\n");
+ return -ENOMEM;
+ }
+
+ i2s_info->work_write_index = 1;
+ i2s_info->send_message = i2s_send_message;
+
+ for (i = 0; i < WORK_MAX_NUM; i++) {
+ INIT_WORK(&i2s_info->work_list[i].work, rpmsg_i2s_work);
+ i2s_info->work_list[i].i2s_info = i2s_info;
+ }
+
+ for (i = 0; i < I2S_CMD_MAX_NUM ; i++) {
+ i2s_info->rpmsg[i].send_msg.header.cate = IMX_RPMSG_AUDIO;
+ i2s_info->rpmsg[i].send_msg.header.major = IMX_RMPSG_MAJOR;
+ i2s_info->rpmsg[i].send_msg.header.minor = IMX_RMPSG_MINOR;
+ i2s_info->rpmsg[i].send_msg.header.type = I2S_TYPE_A;
+ i2s_info->rpmsg[i].send_msg.param.audioindex = audioindex;
+ }
+
+ mutex_init(&i2s_info->tx_lock);
+ mutex_init(&i2s_info->i2c_lock);
+ spin_lock_init(&i2s_info->lock[0]);
+ spin_lock_init(&i2s_info->lock[1]);
+
+ if (of_device_is_compatible(pdev->dev.of_node,
+ "fsl,imx7ulp-rpmsg-i2s")) {
+ rpmsg_i2s->codec_wm8960 = 1;
+ rpmsg_i2s->version = 1;
+ rpmsg_i2s->rates = SNDRV_PCM_RATE_8000 |
+ SNDRV_PCM_RATE_16000 |
+ SNDRV_PCM_RATE_48000;
+ rpmsg_i2s->formats = SNDRV_PCM_FMTBIT_S16_LE;
+ fsl_rpmsg_i2s_dai.playback.rates = rpmsg_i2s->rates;
+ fsl_rpmsg_i2s_dai.playback.formats = rpmsg_i2s->formats;
+ fsl_rpmsg_i2s_dai.capture.rates = rpmsg_i2s->rates;
+ fsl_rpmsg_i2s_dai.capture.formats = rpmsg_i2s->formats;
+ }
+
+ if (of_device_is_compatible(pdev->dev.of_node,
+ "fsl,imx8qxp-rpmsg-i2s")) {
+ rpmsg_i2s->codec_wm8960 = 1 + (1 << 16);
+ rpmsg_i2s->version = 1;
+ rpmsg_i2s->codec_cs42888 = 1 + (2 << 16);
+ }
+
+ if (of_device_is_compatible(pdev->dev.of_node,
+ "fsl,imx8qm-rpmsg-i2s")) {
+ rpmsg_i2s->codec_wm8960 = 0;
+ rpmsg_i2s->version = 1;
+ rpmsg_i2s->codec_cs42888 = 1 + (0 << 16);
+ }
+
+ if (of_device_is_compatible(pdev->dev.of_node,
+ "fsl,imx8mq-rpmsg-i2s")) {
+ rpmsg_i2s->codec_dummy = 0;
+ rpmsg_i2s->codec_ak4497 = 1;
+ rpmsg_i2s->version = 2;
+ rpmsg_i2s->rates = SNDRV_PCM_RATE_KNOT;
+ rpmsg_i2s->formats = SNDRV_PCM_FMTBIT_S16_LE |
+ SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S32_LE |
+ SNDRV_PCM_FMTBIT_DSD_U8 |
+ SNDRV_PCM_FMTBIT_DSD_U16_LE |
+ SNDRV_PCM_FMTBIT_DSD_U32_LE;
+
+ fsl_rpmsg_i2s_dai.playback.rates = rpmsg_i2s->rates;
+ fsl_rpmsg_i2s_dai.playback.formats = rpmsg_i2s->formats;
+ fsl_rpmsg_i2s_dai.capture.rates = rpmsg_i2s->rates;
+ fsl_rpmsg_i2s_dai.capture.formats = rpmsg_i2s->formats;
+ }
+
+ if (of_property_read_bool(pdev->dev.of_node, "fsl,enable-lpa"))
+ rpmsg_i2s->enable_lpa = 1;
+
+ if (of_property_read_u32(np, "fsl,dma-buffer-size",
+ &i2s_info->prealloc_buffer_size))
+ i2s_info->prealloc_buffer_size = IMX_DEFAULT_DMABUF_SIZE;
+
+ platform_set_drvdata(pdev, rpmsg_i2s);
+ pm_runtime_enable(&pdev->dev);
+
+ ret = devm_snd_soc_register_component(&pdev->dev, &fsl_component,
+ &fsl_rpmsg_i2s_dai, 1);
+ if (ret)
+ return ret;
+
+ return imx_rpmsg_platform_register(&pdev->dev);
+}
+
+static int fsl_rpmsg_i2s_remove(struct platform_device *pdev)
+{
+ struct fsl_rpmsg_i2s *rpmsg_i2s = platform_get_drvdata(pdev);
+ struct i2s_info *i2s_info = &rpmsg_i2s->i2s_info;
+
+ if (i2s_info->rpmsg_wq)
+ destroy_workqueue(i2s_info->rpmsg_wq);
+
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int fsl_rpmsg_i2s_runtime_resume(struct device *dev)
+{
+ struct fsl_rpmsg_i2s *rpmsg_i2s = dev_get_drvdata(dev);
+
+ pm_qos_add_request(&rpmsg_i2s->pm_qos_req, PM_QOS_CPU_DMA_LATENCY, 0);
+ return 0;
+}
+
+static int fsl_rpmsg_i2s_runtime_suspend(struct device *dev)
+{
+ struct fsl_rpmsg_i2s *rpmsg_i2s = dev_get_drvdata(dev);
+
+ pm_qos_remove_request(&rpmsg_i2s->pm_qos_req);
+ return 0;
+}
+#endif
+
+#ifdef CONFIG_PM_SLEEP
+static int fsl_rpmsg_i2s_suspend(struct device *dev)
+{
+ struct fsl_rpmsg_i2s *rpmsg_i2s = dev_get_drvdata(dev);
+ struct i2s_info *i2s_info = &rpmsg_i2s->i2s_info;
+ struct i2s_rpmsg *rpmsg_tx;
+ struct i2s_rpmsg *rpmsg_rx;
+
+ flush_workqueue(i2s_info->rpmsg_wq);
+ rpmsg_tx = &i2s_info->rpmsg[I2S_TX_SUSPEND];
+ rpmsg_rx = &i2s_info->rpmsg[I2S_RX_SUSPEND];
+
+ rpmsg_tx->send_msg.header.cmd = I2S_TX_SUSPEND;
+ i2s_send_message(rpmsg_tx, i2s_info);
+
+ rpmsg_rx->send_msg.header.cmd = I2S_RX_SUSPEND;
+ i2s_send_message(rpmsg_rx, i2s_info);
+
+ return 0;
+}
+
+static int fsl_rpmsg_i2s_resume(struct device *dev)
+{
+ struct fsl_rpmsg_i2s *rpmsg_i2s = dev_get_drvdata(dev);
+ struct i2s_info *i2s_info = &rpmsg_i2s->i2s_info;
+ struct i2s_rpmsg *rpmsg_tx;
+ struct i2s_rpmsg *rpmsg_rx;
+
+ rpmsg_tx = &i2s_info->rpmsg[I2S_TX_RESUME];
+ rpmsg_rx = &i2s_info->rpmsg[I2S_RX_RESUME];
+
+ rpmsg_tx->send_msg.header.cmd = I2S_TX_RESUME;
+ i2s_send_message(rpmsg_tx, i2s_info);
+
+ rpmsg_rx->send_msg.header.cmd = I2S_RX_RESUME;
+ i2s_send_message(rpmsg_rx, i2s_info);
+
+ return 0;
+}
+#endif /* CONFIG_PM_SLEEP */
+
+static const struct dev_pm_ops fsl_rpmsg_i2s_pm_ops = {
+ SET_RUNTIME_PM_OPS(fsl_rpmsg_i2s_runtime_suspend,
+ fsl_rpmsg_i2s_runtime_resume,
+ NULL)
+ SET_SYSTEM_SLEEP_PM_OPS(fsl_rpmsg_i2s_suspend, fsl_rpmsg_i2s_resume)
+};
+
+static struct platform_driver fsl_rpmsg_i2s_driver = {
+ .probe = fsl_rpmsg_i2s_probe,
+ .remove = fsl_rpmsg_i2s_remove,
+ .driver = {
+ .name = "fsl-rpmsg-i2s",
+ .pm = &fsl_rpmsg_i2s_pm_ops,
+ .of_match_table = fsl_rpmsg_i2s_ids,
+ },
+};
+
+module_platform_driver(fsl_rpmsg_i2s_driver);
+
+MODULE_DESCRIPTION("Freescale Soc rpmsg_i2s Interface");
+MODULE_AUTHOR("Shengjiu Wang <shengjiu.wang@freescale.com>");
+MODULE_ALIAS("platform:fsl-rpmsg_i2s");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/fsl/fsl_rpmsg_i2s.h b/sound/soc/fsl/fsl_rpmsg_i2s.h
new file mode 100644
index 000000000000..cd0badb562f2
--- /dev/null
+++ b/sound/soc/fsl/fsl_rpmsg_i2s.h
@@ -0,0 +1,448 @@
+/*
+ * Copyright 2017 NXP
+ *
+ * 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.
+ *
+ ******************************************************************************
+ * communication stack of audio with rpmsg
+ ******************************************************************************
+ * Packet structure:
+ * A SRTM message consists of a 10 bytes header followed by 0~N bytes of data
+ *
+ * +---------------+-------------------------------+
+ * | | Content |
+ * +---------------+-------------------------------+
+ * | Byte Offset | 7 6 5 4 3 2 1 0 |
+ * +---------------+---+---+---+---+---+---+---+---+
+ * | 0 | Category |
+ * +---------------+---+---+---+---+---+---+---+---+
+ * | 1 ~ 2 | Version |
+ * +---------------+---+---+---+---+---+---+---+---+
+ * | 3 | Type |
+ * +---------------+---+---+---+---+---+---+---+---+
+ * | 4 | Command |
+ * +---------------+---+---+---+---+---+---+---+---+
+ * | 5 | Reserved0 |
+ * +---------------+---+---+---+---+---+---+---+---+
+ * | 6 | Reserved1 |
+ * +---------------+---+---+---+---+---+---+---+---+
+ * | 7 | Reserved2 |
+ * +---------------+---+---+---+---+---+---+---+---+
+ * | 8 | Reserved3 |
+ * +---------------+---+---+---+---+---+---+---+---+
+ * | 9 | Reserved4 |
+ * +---------------+---+---+---+---+---+---+---+---+
+ * | 10 | DATA 0 |
+ * +---------------+---+---+---+---+---+---+---+---+
+ * : : : : : : : : : : : : :
+ * +---------------+---+---+---+---+---+---+---+---+
+ * | N + 10 - 1 | DATA N-1 |
+ * +---------------+---+---+---+---+---+---+---+---+
+ *
+ * +----------+------------+------------------------------------------------+
+ * | Field | Byte | |
+ * +----------+------------+------------------------------------------------+
+ * | Category | 0 | The destination category. |
+ * +----------+------------+------------------------------------------------+
+ * | Version | 1 ~ 2 | The category version of the sender of the |
+ * | | | packet. |
+ * | | | The first byte represent the major version of |
+ * | | | the packet.The second byte represent the minor |
+ * | | | version of the packet. |
+ * +----------+------------+------------------------------------------------+
+ * | Type | 3 | The message type of current message packet. |
+ * +----------+------------+------------------------------------------------+
+ * | Command | 4 | The command byte sent to remote processor/SoC. |
+ * +----------+------------+------------------------------------------------+
+ * | Reserved | 5 ~ 9 | Reserved field for future extension. |
+ * +----------+------------+------------------------------------------------+
+ * | Data | N | The data payload of the message packet. |
+ * +----------+------------+------------------------------------------------+
+ *
+ * Audio control:
+ * SRTM Audio Control Category Request Command Table:
+ * +------------+---------+------+---------+-------------------------------+------------------------------------------------+
+ * | Category | Version | Type | Command | Data | Function |
+ * +------------+---------+------+---------+-------------------------------+------------------------------------------------+
+ * | 0x03 | 0x0100 | 0x00 | 0x00 | Data[0]: Audio Device Index | Open an Audio TX Instance. |
+ * | | | | | Data[1]: format | |
+ * | | | | | Data[2]: channels | |
+ * | | | | | Data[3-6]: samplerate | |
+ * | | | | | Data[7-10]: buffer_addr | |
+ * | | | | | Data[11-14]: buffer_size | |
+ * | | | | | Data[15-18]: period_size | |
+ * | | | | | Data[19-22]: buffer_tail | |
+ * +------------+---------+------+---------+-------------------------------+------------------------------------------------+
+ * | 0x03 | 0x0100 | 0x00 | 0x01 | Data[0]: Audio Device Index | Start an Audio TX Instance. |
+ * | | | | | Same as above command | |
+ * +------------+---------+------+---------+-------------------------------+------------------------------------------------+
+ * | 0x03 | 0x0100 | 0x00 | 0x02 | Data[0]: Audio Device Index | Pause an Audio TX Instance. |
+ * | | | | | Same as above command | |
+ * +------------+---------+------+---------+-------------------------------+------------------------------------------------+
+ * | 0x03 | 0x0100 | 0x00 | 0x03 | Data[0]: Audio Device Index | Resume an Audio TX Instance. |
+ * +------------+---------+------+---------+-------------------------------+------------------------------------------------+
+ * | 0x03 | 0x0100 | 0x00 | 0x04 | Data[0]: Audio Device Index | Terminate an Audio TX Instance. |
+ * +------------+---------+------+---------+-------------------------------+------------------------------------------------+
+ * | 0x03 | 0x0100 | 0x00 | 0x05 | Data[0]: Audio Device Index | Close an Audio TX Instance. |
+ * +------------+---------+------+---------+-------------------------------+------------------------------------------------+
+ * | 0x03 | 0x0100 | 0x00 | 0x06 | Data[0]: Audio Device Index | Set Parameters for an Audio TX Instance. |
+ * | | | | | Data[1]: format | |
+ * | | | | | Data[2]: channels | |
+ * | | | | | Data[3-6]: samplerate | |
+ * | | | | | Data[7-22]: reserved | |
+ * +------------+---------+------+---------+-------------------------------+------------------------------------------------+
+ * | 0x03 | 0x0100 | 0x00 | 0x07 | Data[0]: Audio Device Index | Set Audio TX Buffer. |
+ * | | | | | Data[1-6]: reserved | |
+ * | | | | | Data[7-10]: buffer_addr | |
+ * | | | | | Data[11-14]: buffer_size | |
+ * | | | | | Data[15-18]: period_size | |
+ * | | | | | Data[19-22]: buffer_tail | |
+ * +------------+---------+------+---------+-------------------------------+------------------------------------------------+
+ * | 0x03 | 0x0100 | 0x00 | 0x08 | Data[0]: Audio Device Index | Suspend an Audio TX Instance. |
+ * +------------+---------+------+---------+-------------------------------+------------------------------------------------+
+ * | 0x03 | 0x0100 | 0x00 | 0x09 | Data[0]: Audio Device Index | Resume an Audio TX Instance. |
+ * | | | | | Data[1]: format | |
+ * | | | | | Data[2]: channels | |
+ * | | | | | Data[3-6]: samplerate | |
+ * | | | | | Data[7-10]: buffer_addr | |
+ * | | | | | Data[11-14]: buffer_size | |
+ * | | | | | Data[15-18]: period_size | |
+ * | | | | | Data[19-22]: buffer_tail | |
+ * +------------+---------+------+---------+-------------------------------+------------------------------------------------+
+ * | 0x03 | 0x0100 | 0x00 | 0x0A | Data[0]: Audio Device Index | Open an Audio RX Instance. |
+ * +------------+---------+------+---------+-------------------------------+------------------------------------------------+
+ * | 0x03 | 0x0100 | 0x00 | 0x0B | Data[0]: Audio Device Index | Start an Audio RX Instance. |
+ * +------------+---------+------+---------+-------------------------------+------------------------------------------------+
+ * | 0x03 | 0x0100 | 0x00 | 0x0C | Data[0]: Audio Device Index | Pause an Audio RX Instance. |
+ * +------------+---------+------+---------+-------------------------------+------------------------------------------------+
+ * | 0x03 | 0x0100 | 0x00 | 0x0D | Data[0]: Audio Device Index | Resume an Audio RX Instance. |
+ * +------------+---------+------+---------+-------------------------------+------------------------------------------------+
+ * | 0x03 | 0x0100 | 0x00 | 0x0E | Data[0]: Audio Device Index | Terminate an Audio RX Instance. |
+ * +------------+---------+------+---------+-------------------------------+------------------------------------------------+
+ * | 0x03 | 0x0100 | 0x00 | 0x0F | Data[0]: Audio Device Index | Close an Audio RX Instance. |
+ * +------------+---------+------+---------+-------------------------------+------------------------------------------------+
+ * | 0x03 | 0x0100 | 0x00 | 0x10 | Data[0]: Audio Device Index | Set Parameters for an Audio RX Instance. |
+ * | | | | | Data[1]: format | |
+ * | | | | | Data[2]: channels | |
+ * | | | | | Data[3-6]: samplerate | |
+ * | | | | | Data[7-22]: reserved | |
+ * +------------+---------+------+---------+-------------------------------+------------------------------------------------+
+ * | 0x03 | 0x0100 | 0x00 | 0x11 | Data[0]: Audio Device Index | Set Audio RX Buffer. |
+ * | | | | | Data[1-6]: reserved | |
+ * | | | | | Data[7-10]: buffer_addr | |
+ * | | | | | Data[11-14]: buffer_size | |
+ * | | | | | Data[15-18]: period_size | |
+ * | | | | | Data[19-22]: buffer_tail | |
+ * +------------+---------+------+---------+-------------------------------+------------------------------------------------+
+ * | 0x03 | 0x0100 | 0x00 | 0x12 | Data[0]: Audio Device Index | Suspend an Audio RX Instance. |
+ * +------------+---------+------+---------+-------------------------------+------------------------------------------------+
+ * | 0x03 | 0x0100 | 0x00 | 0x13 | Data[0]: Audio Device Index | Resume an Audio RX Instance. |
+ * | | | | | Data[1]: format | |
+ * | | | | | Data[2]: channels | |
+ * | | | | | Data[3-6]: samplerate | |
+ * | | | | | Data[7-10]: buffer_addr | |
+ * | | | | | Data[11-14]: buffer_size | |
+ * | | | | | Data[15-18]: period_size | |
+ * | | | | | Data[19-22]: buffer_tail | |
+ * +------------+---------+------+---------+-------------------------------+------------------------------------------------+
+ * | 0x03 | 0x0100 | 0x00 | 0x14 | Data[0]: Audio Device Index | Set register value to codec. |
+ * | | | | | Data[1-6]: reserved | |
+ * | | | | | Data[7-10]: register | |
+ * | | | | | Data[11-14]: value | |
+ * | | | | | Data[15-22]: reserved | |
+ * +------------+---------+------+---------+-------------------------------+------------------------------------------------+
+ * | 0x03 | 0x0100 | 0x00 | 0x15 | Data[0]: Audio Device Index | Get register value from codec. |
+ * | | | | | Data[1-6]: reserved | |
+ * | | | | | Data[7-10]: register | |
+ * | | | | | Data[11-22]: reserved | |
+ * +------------+---------+------+---------+-------------------------------+------------------------------------------------+
+ * Note 1: See <List of Sample Format> for available value of
+ * Sample Format;
+ * Note 2: See <List of Audio Channels> for available value of Channels;
+ * Note 3: Sample Rate of Set Parameters for an Audio TX Instance
+ * Command and Set Parameters for an Audio RX Instance Command is
+ * in little-endian format.
+ *
+ * SRTM Audio Control Category Response Command Table:
+ * +------------+---------+------+---------+-------------------------------+------------------------------------------------+
+ * | Category | Version | Type | Command | Data | Function |
+ * +------------+---------+------+---------+-------------------------------+------------------------------------------------+
+ * | 0x03 | 0x0100 | 0x01 | 0x00 | Data[0]: Audio Device Index | Reply for Open an Audio TX Instance. |
+ * | | | | | Data[1]: Return code | |
+ * +------------+---------+------+---------+-------------------------------+------------------------------------------------+
+ * | 0x03 | 0x0100 | 0x01 | 0x01 | Data[0]: Audio Device Index | Reply for Start an Audio TX Instance. |
+ * | | | | | Data[1]: Return code | |
+ * +------------+---------+------+---------+-------------------------------+------------------------------------------------+
+ * | 0x03 | 0x0100 | 0x01 | 0x02 | Data[0]: Audio Device Index | Reply for Pause an Audio TX Instance. |
+ * | | | | | Data[1]: Return code | |
+ * +------------+---------+------+---------+-------------------------------+------------------------------------------------+
+ * | 0x03 | 0x0100 | 0x01 | 0x03 | Data[0]: Audio Device Index | Reply for Resume an Audio TX Instance. |
+ * | | | | | Data[1]: Return code | |
+ * +------------+---------+------+---------+-------------------------------+------------------------------------------------+
+ * | 0x03 | 0x0100 | 0x01 | 0x04 | Data[0]: Audio Device Index | Reply for Terminate an Audio TX Instance. |
+ * | | | | | Data[1]: Return code | |
+ * +------------+---------+------+---------+-------------------------------+------------------------------------------------+
+ * | 0x03 | 0x0100 | 0x01 | 0x05 | Data[0]: Audio Device Index | Reply for Close an Audio TX Instance. |
+ * | | | | | Data[1]: Return code | |
+ * +------------+---------+------+---------+-------------------------------+------------------------------------------------+
+ * | 0x03 | 0x0100 | 0x01 | 0x06 | Data[0]: Audio Device Index | Reply for Set Parameters for an Audio |
+ * | | | | | Data[1]: Return code | TX Instance. |
+ * +------------+---------+------+---------+-------------------------------+------------------------------------------------+
+ * | 0x03 | 0x0100 | 0x01 | 0x07 | Data[0]: Audio Device Index | Reply for Set Audio TX Buffer. |
+ * | | | | | Data[1]: Return code | |
+ * +------------+---------+------+---------+-------------------------------+------------------------------------------------+
+ * | 0x03 | 0x0100 | 0x01 | 0x08 | Data[0]: Audio Device Index | Reply for Suspend an Audio TX Instance. |
+ * | | | | | Data[1]: Return code | |
+ * +------------+---------+------+---------+-------------------------------+------------------------------------------------+
+ * | 0x03 | 0x0100 | 0x01 | 0x09 | Data[0]: Audio Device Index | Reply for Resume an Audio TX Instance. |
+ * | | | | | Data[1]: Return code | |
+ * +------------+---------+------+---------+-------------------------------+------------------------------------------------+
+ * | 0x03 | 0x0100 | 0x01 | 0x0A | Data[0]: Audio Device Index | Reply for Open an Audio RX Instance. |
+ * | | | | | Data[1]: Return code | |
+ * +------------+---------+------+---------+-------------------------------+------------------------------------------------+
+ * | 0x03 | 0x0100 | 0x01 | 0x0B | Data[0]: Audio Device Index | Reply for Start an Audio RX Instance. |
+ * | | | | | Data[1]: Return code | |
+ * +------------+---------+------+---------+-------------------------------+------------------------------------------------+
+ * | 0x03 | 0x0100 | 0x01 | 0x0C | Data[0]: Audio Device Index | Reply for Pause an Audio RX Instance. |
+ * | | | | | Data[1]: Return code | |
+ * +------------+---------+------+---------+-------------------------------+------------------------------------------------+
+ * | 0x03 | 0x0100 | 0x01 | 0x0D | Data[0]: Audio Device Index | Reply for Resume an Audio RX Instance. |
+ * | | | | | Data[1]: Return code | |
+ * +------------+---------+------+---------+-------------------------------+------------------------------------------------+
+ * | 0x03 | 0x0100 | 0x01 | 0x0E | Data[0]: Audio Device Index | Reply for Terminate an Audio RX Instance. |
+ * | | | | | Data[1]: Return code | |
+ * +------------+---------+------+---------+-------------------------------+------------------------------------------------+
+ * | 0x03 | 0x0100 | 0x01 | 0x0F | Data[0]: Audio Device Index | Reply for Close an Audio RX Instance. |
+ * | | | | | Data[1]: Return code | |
+ * +------------+---------+------+---------+-------------------------------+------------------------------------------------+
+ * | 0x03 | 0x0100 | 0x01 | 0x10 | Data[0]: Audio Device Index | Reply for Set Parameters for an Audio |
+ * | | | | | Data[1]: Return code | RX Instance. |
+ * +------------+---------+------+---------+-------------------------------+------------------------------------------------+
+ * | 0x03 | 0x0100 | 0x01 | 0x11 | Data[0]: Audio Device Index | Reply for Set Audio RX Buffer. |
+ * | | | | | Data[1]: Return code | |
+ * +------------+---------+------+---------+-------------------------------+------------------------------------------------+
+ * | 0x03 | 0x0100 | 0x01 | 0x12 | Data[0]: Audio Device Index | Reply for Supend an Audio RX Instance. |
+ * | | | | | Data[1]: Return code | |
+ * +------------+---------+------+---------+-------------------------------+------------------------------------------------+
+ * | 0x03 | 0x0100 | 0x01 | 0x13 | Data[0]: Audio Device Index | Reply for Resume an Audio RX Instance. |
+ * | | | | | Data[1]: Return code | |
+ * +------------+---------+------+---------+-------------------------------+------------------------------------------------+
+ * | 0x03 | 0x0100 | 0x01 | 0x14 | Data[0]: Audio Device Index | Reply for Set codec register value. |
+ * | | | | | Data[1]: Return code | |
+ * +------------+---------+------+---------+-------------------------------+------------------------------------------------+
+ * | 0x03 | 0x0100 | 0x01 | 0x15 | Data[0]: Audio Device Index | Reply for Get codec register value. |
+ * | | | | | Data[1]: Return code | |
+ * | | | | | Data[2-6]: reserved | |
+ * | | | | | Data[7-10]: register | |
+ * | | | | | Data[11-14]: value | |
+ * | | | | | Data[15-22]: reserved | |
+ * +------------+---------+------+---------+-------------------------------+------------------------------------------------+
+ *
+ * SRTM Audio Control Category Notification Command Table:
+ * +------------+---------+------+---------+-------------------------------+------------------------------------------------+
+ * | Category | Version | Type | Command | Data | Function |
+ * +------------+---------+------+---------+-------------------------------+------------------------------------------------+
+ * | 0x03 | 0x0100 | 0x02 | 0x00 | Data[0]: Audio Device Index | Notify one TX period is finished. |
+ * +------------+---------+------+---------+-------------------------------+------------------------------------------------+
+ * | 0x03 | 0x0100 | 0x02 | 0x01 | Data[0]: Audio Device Index | Notify one RX period is finished. |
+ * +------------+---------+------+---------+-------------------------------+------------------------------------------------+
+ *
+ * List of Sample Format:
+ * +--------------------+----------------------------------------------+
+ * | Sample Format | Description |
+ * +--------------------+----------------------------------------------+
+ * | 0x0 | S16_LE |
+ * +--------------------+----------------------------------------------+
+ * | 0x1 | S24_LE |
+ * +--------------------+----------------------------------------------+
+ *
+ * List of Audio Channels
+ * +--------------------+----------------------------------------------+
+ * | Audio Channel | Description |
+ * +--------------------+----------------------------------------------+
+ * | 0x0 | Left Channel |
+ * +--------------------+----------------------------------------------+
+ * | 0x1 | Right Channel |
+ * +--------------------+----------------------------------------------+
+ * | 0x2 | Left & Right Channel |
+ * +--------------------+----------------------------------------------+
+ *
+ */
+
+#ifndef __FSL_RPMSG_I2S_H
+#define __FSL_RPMSG_I2S_H
+
+#include <linux/pm_qos.h>
+#include <linux/imx_rpmsg.h>
+#include <linux/interrupt.h>
+#include <sound/dmaengine_pcm.h>
+
+#define RPMSG_TIMEOUT 1000
+
+#define I2S_TX_OPEN 0x0
+#define I2S_TX_START 0x1
+#define I2S_TX_PAUSE 0x2
+#define I2S_TX_RESTART 0x3
+#define I2S_TX_TERMINATE 0x4
+#define I2S_TX_CLOSE 0x5
+#define I2S_TX_HW_PARAM 0x6
+#define I2S_TX_BUFFER 0x7
+#define I2S_TX_SUSPEND 0x8
+#define I2S_TX_RESUME 0x9
+
+#define I2S_RX_OPEN 0xA
+#define I2S_RX_START 0xB
+#define I2S_RX_PAUSE 0xC
+#define I2S_RX_RESTART 0xD
+#define I2S_RX_TERMINATE 0xE
+#define I2S_RX_CLOSE 0xF
+#define I2S_RX_HW_PARAM 0x10
+#define I2S_RX_BUFFER 0x11
+#define I2S_RX_SUSPEND 0x12
+#define I2S_RX_RESUME 0x13
+#define SET_CODEC_VALUE 0x14
+#define GET_CODEC_VALUE 0x15
+#define I2S_TX_POINTER 0x16
+#define I2S_RX_POINTER 0x17
+
+#define I2S_TYPE_A_NUM 0x18
+
+#define WORK_MAX_NUM 0x30
+
+#define I2S_TX_PERIOD_DONE 0x0
+#define I2S_RX_PERIOD_DONE 0x1
+
+#define I2S_TYPE_C_NUM 0x2
+
+#define I2S_CMD_MAX_NUM (I2S_TYPE_A_NUM + I2S_TYPE_C_NUM)
+
+#define I2S_TYPE_A 0x0
+#define I2S_TYPE_B 0x1
+#define I2S_TYPE_C 0x2
+
+#define I2S_RESP_NONE 0x0
+#define I2S_RESP_NOT_ALLOWED 0x1
+#define I2S_RESP_SUCCESS 0x2
+#define I2S_RESP_FAILED 0x3
+
+#define RPMSG_S16_LE 0x0
+#define RPMSG_S24_LE 0x1
+#define RPMSG_S32_LE 0x2
+#define RPMSG_DSD_U16_LE 0x3
+#define RPMSG_DSD_U24_LE 0x4
+#define RPMSG_DSD_U32_LE 0x5
+
+#define RPMSG_CH_LEFT 0x0
+#define RPMSG_CH_RIGHT 0x1
+#define RPMSG_CH_STEREO 0x2
+
+struct i2s_param_s {
+ unsigned char audioindex;
+ unsigned char format;
+ unsigned char channels;
+ unsigned int rate;
+ unsigned int buffer_addr; /* Register for SET_CODEC_VALUE*/
+ unsigned int buffer_size; /* register value for SET_CODEC_VALUE*/
+ unsigned int period_size;
+ unsigned int buffer_tail;
+} __packed;
+
+struct i2s_param_r {
+ unsigned char audioindex;
+ unsigned char resp;
+ unsigned char reserved1[1];
+ unsigned int buffer_offset; /* the consumed offset of buffer*/
+ unsigned int reg_addr;
+ unsigned int reg_data;
+ unsigned char reserved2[4];
+ unsigned int buffer_tail;
+} __packed;
+
+/* struct of send message */
+struct i2s_rpmsg_s {
+ struct imx_rpmsg_head header;
+ struct i2s_param_s param;
+};
+
+/* struct of received message */
+struct i2s_rpmsg_r {
+ struct imx_rpmsg_head header;
+ struct i2s_param_r param;
+};
+
+struct i2s_rpmsg {
+ struct i2s_rpmsg_s send_msg;
+ struct i2s_rpmsg_r recv_msg;
+};
+
+struct work_of_rpmsg {
+ struct i2s_info *i2s_info;
+ /* sent msg for each work */
+ struct i2s_rpmsg msg;
+ struct work_struct work;
+};
+
+typedef void (*dma_callback)(void *arg);
+struct i2s_info {
+ struct rpmsg_device *rpdev;
+ struct device *dev;
+ struct completion cmd_complete;
+
+ /* received msg (global) */
+ struct i2s_rpmsg_r recv_msg;
+
+ struct i2s_rpmsg rpmsg[I2S_CMD_MAX_NUM];
+ struct i2s_rpmsg period_done_msg[2];
+ bool period_done_msg_enabled[2];
+
+ struct workqueue_struct *rpmsg_wq;
+ struct work_of_rpmsg work_list[WORK_MAX_NUM];
+ int work_write_index;
+ int work_read_index;
+ int msg_drop_count[2];
+ int num_period[2];
+ void *callback_param[2];
+ int (*send_message)(struct i2s_rpmsg *msg, struct i2s_info *info);
+ dma_callback callback[2];
+ spinlock_t lock[2];
+ struct mutex tx_lock;
+ struct mutex i2c_lock;
+ struct timer_list stream_timer[2];
+ int prealloc_buffer_size;
+};
+
+struct fsl_rpmsg_i2s {
+ struct platform_device *pdev;
+ struct i2s_info i2s_info;
+ struct pm_qos_request pm_qos_req;
+ int codec_dummy;
+ int codec_wm8960;
+ int codec_cs42888;
+ int codec_ak4497;
+ int force_lpa;
+ int version;
+ int rates;
+ u64 formats;
+ int enable_lpa;
+};
+
+#define RPMSG_CODEC_DRV_NAME_WM8960 "rpmsg-audio-codec-wm8960"
+#define RPMSG_CODEC_DRV_NAME_CS42888 "rpmsg-audio-codec-cs42888"
+#define RPMSG_CODEC_DRV_NAME_AK4497 "rpmsg-audio-codec-ak4497"
+
+struct fsl_rpmsg_codec {
+ int audioindex;
+
+ /*property for wm8960*/
+ bool capless;
+ bool shared_lrclk;
+
+ /*property for cs42xx8*/
+
+ char name[32];
+ int num_adcs;
+};
+
+#endif /* __FSL_RPMSG_I2S_H */
diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c
index c1c733b573a7..673c84c2bb29 100644
--- a/sound/soc/fsl/fsl_sai.c
+++ b/sound/soc/fsl/fsl_sai.c
@@ -1,7 +1,7 @@
/*
* Freescale ALSA SoC Digital Audio Interface (SAI) driver.
*
- * Copyright 2012-2015 Freescale Semiconductor, Inc.
+ * Copyright 2012-2016 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
@@ -10,30 +10,99 @@
*
*/
+#include <linux/busfreq-imx.h>
#include <linux/clk.h>
+#include <linux/clk-provider.h>
#include <linux/delay.h>
#include <linux/dmaengine.h>
#include <linux/module.h>
+#include <linux/of_device.h>
#include <linux/of_address.h>
+#include <linux/pm_runtime.h>
#include <linux/regmap.h>
#include <linux/slab.h>
#include <linux/time.h>
+#include <linux/pm_qos.h>
#include <sound/core.h>
#include <sound/dmaengine_pcm.h>
#include <sound/pcm_params.h>
#include <linux/mfd/syscon.h>
#include <linux/mfd/syscon/imx6q-iomuxc-gpr.h>
+#include "fsl_dsd.h"
#include "fsl_sai.h"
#include "imx-pcm.h"
#define FSL_SAI_FLAGS (FSL_SAI_CSR_SEIE |\
FSL_SAI_CSR_FEIE)
+#define FSL_SAI_VERID_0301 0x0301
+
+static struct fsl_sai_soc_data fsl_sai_vf610 = {
+ .imx = false,
+ /*dataline is mask, not index*/
+ .dataline = 0x1,
+ .fifos = 1,
+ .fifo_depth = 32,
+ .flags = 0,
+ .constrain_period_size = false,
+};
+
+static struct fsl_sai_soc_data fsl_sai_imx6sx = {
+ .imx = true,
+ .dataline = 0x1,
+ .fifos = 1,
+ .fifo_depth = 32,
+ .flags = 0,
+ .reg_offset = 0,
+ .constrain_period_size = false,
+};
+
+static struct fsl_sai_soc_data fsl_sai_imx6ul = {
+ .imx = true,
+ .dataline = 0x1,
+ .fifos = 1,
+ .fifo_depth = 32,
+ .flags = 0,
+ .reg_offset = 0,
+ .constrain_period_size = false,
+};
+
+static struct fsl_sai_soc_data fsl_sai_imx7ulp = {
+ .imx = true,
+ .dataline = 0x3,
+ .fifos = 2,
+ .fifo_depth = 16,
+ .flags = SAI_FLAG_PMQOS,
+ .reg_offset = 8,
+ .constrain_period_size = false,
+};
+
+static struct fsl_sai_soc_data fsl_sai_imx8mq = {
+ .imx = true,
+ .dataline = 0xff,
+ .fifos = 8,
+ .fifo_depth = 128,
+ .flags = 0,
+ .reg_offset = 8,
+ .constrain_period_size = false,
+};
+
+static struct fsl_sai_soc_data fsl_sai_imx8qm = {
+ .imx = true,
+ .dataline = 0xf,
+ .fifos = 1,
+ .fifo_depth = 64,
+ .flags = 0,
+ .reg_offset = 0,
+ .constrain_period_size = true,
+};
+
static const unsigned int fsl_sai_rates[] = {
8000, 11025, 12000, 16000, 22050,
24000, 32000, 44100, 48000, 64000,
- 88200, 96000, 176400, 192000
+ 88200, 96000, 176400, 192000, 352800,
+ 384000, 705600, 768000, 1411200, 2822400,
};
static const struct snd_pcm_hw_constraint_list fsl_sai_rate_constraints = {
@@ -44,6 +113,7 @@ static const struct snd_pcm_hw_constraint_list fsl_sai_rate_constraints = {
static irqreturn_t fsl_sai_isr(int irq, void *devid)
{
struct fsl_sai *sai = (struct fsl_sai *)devid;
+ unsigned char offset = sai->soc->reg_offset;
struct device *dev = &sai->pdev->dev;
u32 flags, xcsr, mask;
bool irq_none = true;
@@ -56,7 +126,7 @@ static irqreturn_t fsl_sai_isr(int irq, void *devid)
mask = (FSL_SAI_FLAGS >> FSL_SAI_CSR_xIE_SHIFT) << FSL_SAI_CSR_xF_SHIFT;
/* Tx IRQ */
- regmap_read(sai->regmap, FSL_SAI_TCSR, &xcsr);
+ regmap_read(sai->regmap, FSL_SAI_TCSR(offset), &xcsr);
flags = xcsr & mask;
if (flags)
@@ -68,10 +138,10 @@ static irqreturn_t fsl_sai_isr(int irq, void *devid)
dev_dbg(dev, "isr: Start of Tx word detected\n");
if (flags & FSL_SAI_CSR_SEF)
- dev_warn(dev, "isr: Tx Frame sync error detected\n");
+ dev_dbg(dev, "isr: Tx Frame sync error detected\n");
if (flags & FSL_SAI_CSR_FEF) {
- dev_warn(dev, "isr: Transmit underrun detected\n");
+ dev_dbg(dev, "isr: Transmit underrun detected\n");
/* FIFO reset for safety */
xcsr |= FSL_SAI_CSR_FR;
}
@@ -86,11 +156,11 @@ static irqreturn_t fsl_sai_isr(int irq, void *devid)
xcsr &= ~FSL_SAI_CSR_xF_MASK;
if (flags)
- regmap_write(sai->regmap, FSL_SAI_TCSR, flags | xcsr);
+ regmap_write(sai->regmap, FSL_SAI_TCSR(offset), flags | xcsr);
irq_rx:
/* Rx IRQ */
- regmap_read(sai->regmap, FSL_SAI_RCSR, &xcsr);
+ regmap_read(sai->regmap, FSL_SAI_RCSR(offset), &xcsr);
flags = xcsr & mask;
if (flags)
@@ -102,10 +172,10 @@ irq_rx:
dev_dbg(dev, "isr: Start of Rx word detected\n");
if (flags & FSL_SAI_CSR_SEF)
- dev_warn(dev, "isr: Rx Frame sync error detected\n");
+ dev_dbg(dev, "isr: Rx Frame sync error detected\n");
if (flags & FSL_SAI_CSR_FEF) {
- dev_warn(dev, "isr: Receive overflow detected\n");
+ dev_dbg(dev, "isr: Receive overflow detected\n");
/* FIFO reset for safety */
xcsr |= FSL_SAI_CSR_FR;
}
@@ -120,7 +190,7 @@ irq_rx:
xcsr &= ~FSL_SAI_CSR_xF_MASK;
if (flags)
- regmap_write(sai->regmap, FSL_SAI_RCSR, flags | xcsr);
+ regmap_write(sai->regmap, FSL_SAI_RCSR(offset), flags | xcsr);
out:
if (irq_none)
@@ -144,6 +214,7 @@ static int fsl_sai_set_dai_sysclk_tr(struct snd_soc_dai *cpu_dai,
int clk_id, unsigned int freq, int fsl_dir)
{
struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai);
+ unsigned char offset = sai->soc->reg_offset;
bool tx = fsl_dir == FSL_FMT_TRANSMITTER;
u32 val_cr2 = 0;
@@ -164,20 +235,89 @@ static int fsl_sai_set_dai_sysclk_tr(struct snd_soc_dai *cpu_dai,
return -EINVAL;
}
- regmap_update_bits(sai->regmap, FSL_SAI_xCR2(tx),
+ regmap_update_bits(sai->regmap, FSL_SAI_xCR2(tx, offset),
FSL_SAI_CR2_MSEL_MASK, val_cr2);
return 0;
}
+static int fsl_sai_set_mclk_rate(struct snd_soc_dai *dai, int clk_id,
+ unsigned int freq)
+{
+ struct fsl_sai *sai = snd_soc_dai_get_drvdata(dai);
+ struct clk *p = sai->mclk_clk[clk_id], *pll = 0, *npll = 0;
+ u64 ratio = freq;
+ int ret;
+
+ while (p && sai->pll8k_clk && sai->pll11k_clk) {
+ struct clk *pp = clk_get_parent(p);
+
+ if (clk_is_match(pp, sai->pll8k_clk) ||
+ clk_is_match(pp, sai->pll11k_clk)) {
+ pll = pp;
+ break;
+ }
+ p = pp;
+ }
+
+ if (pll) {
+ npll = (do_div(ratio, 8000) ? sai->pll11k_clk : sai->pll8k_clk);
+ if (!clk_is_match(pll, npll)) {
+ if (sai->mclk_streams == 0) {
+ ret = clk_set_parent(p, npll);
+ if (ret < 0)
+ dev_warn(dai->dev,
+ "failed to set parent %s: %d\n",
+ __clk_get_name(npll), ret);
+ } else {
+ dev_err(dai->dev,
+ "PLL %s is in use by a running stream.\n",
+ __clk_get_name(pll));
+ return -EINVAL;
+ }
+ }
+ }
+
+ ret = clk_set_rate(sai->mclk_clk[clk_id], freq);
+ if (ret < 0)
+ dev_err(dai->dev, "failed to set clock rate (%u): %d\n",
+ freq, ret);
+ return ret;
+}
+
+static int fsl_sai_set_dai_bclk_ratio(struct snd_soc_dai *dai, unsigned int ratio)
+{
+ struct fsl_sai *sai = snd_soc_dai_get_drvdata(dai);
+
+ sai->bitclk_ratio = ratio;
+ return 0;
+}
+
static int fsl_sai_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
int clk_id, unsigned int freq, int dir)
{
+ struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai);
int ret;
if (dir == SND_SOC_CLOCK_IN)
return 0;
+ if (freq > 0) {
+ if (clk_id < 0 || clk_id >= FSL_SAI_MCLK_MAX) {
+ dev_err(cpu_dai->dev, "Unknown clock id: %d\n", clk_id);
+ return -EINVAL;
+ }
+
+ if (IS_ERR_OR_NULL(sai->mclk_clk[clk_id])) {
+ dev_err(cpu_dai->dev, "Unassigned clock: %d\n", clk_id);
+ return -EINVAL;
+ }
+
+ ret = fsl_sai_set_mclk_rate(cpu_dai, clk_id, freq);
+ if (ret < 0)
+ return ret;
+ }
+
ret = fsl_sai_set_dai_sysclk_tr(cpu_dai, clk_id, freq,
FSL_FMT_TRANSMITTER);
if (ret) {
@@ -197,12 +337,14 @@ static int fsl_sai_set_dai_fmt_tr(struct snd_soc_dai *cpu_dai,
unsigned int fmt, int fsl_dir)
{
struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai);
+ unsigned char offset = sai->soc->reg_offset;
bool tx = fsl_dir == FSL_FMT_TRANSMITTER;
u32 val_cr2 = 0, val_cr4 = 0;
if (!sai->is_lsb_first)
val_cr4 |= FSL_SAI_CR4_MF;
+ sai->is_dsp_mode = false;
/* DAI mode */
switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
case SND_SOC_DAIFMT_I2S:
@@ -241,6 +383,11 @@ static int fsl_sai_set_dai_fmt_tr(struct snd_soc_dai *cpu_dai,
val_cr2 |= FSL_SAI_CR2_BCP;
sai->is_dsp_mode = true;
break;
+ case SND_SOC_DAIFMT_PDM:
+ val_cr2 |= FSL_SAI_CR2_BCP;
+ val_cr4 &= ~FSL_SAI_CR4_MF;
+ sai->is_dsp_mode = true;
+ break;
case SND_SOC_DAIFMT_RIGHT_J:
/* To be done */
default:
@@ -269,31 +416,31 @@ static int fsl_sai_set_dai_fmt_tr(struct snd_soc_dai *cpu_dai,
return -EINVAL;
}
+ sai->slave_mode[tx] = false;
+
/* DAI clock master masks */
switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
case SND_SOC_DAIFMT_CBS_CFS:
val_cr2 |= FSL_SAI_CR2_BCD_MSTR;
val_cr4 |= FSL_SAI_CR4_FSD_MSTR;
- sai->is_slave_mode = false;
break;
case SND_SOC_DAIFMT_CBM_CFM:
- sai->is_slave_mode = true;
+ sai->slave_mode[tx] = true;
break;
case SND_SOC_DAIFMT_CBS_CFM:
val_cr2 |= FSL_SAI_CR2_BCD_MSTR;
- sai->is_slave_mode = false;
break;
case SND_SOC_DAIFMT_CBM_CFS:
val_cr4 |= FSL_SAI_CR4_FSD_MSTR;
- sai->is_slave_mode = true;
+ sai->slave_mode[tx] = true;
break;
default:
return -EINVAL;
}
- regmap_update_bits(sai->regmap, FSL_SAI_xCR2(tx),
+ regmap_update_bits(sai->regmap, FSL_SAI_xCR2(tx, offset),
FSL_SAI_CR2_BCP | FSL_SAI_CR2_BCD_MSTR, val_cr2);
- regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx),
+ regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx, offset),
FSL_SAI_CR4_MF | FSL_SAI_CR4_FSE |
FSL_SAI_CR4_FSP | FSL_SAI_CR4_FSD_MSTR, val_cr4);
@@ -302,14 +449,23 @@ static int fsl_sai_set_dai_fmt_tr(struct snd_soc_dai *cpu_dai,
static int fsl_sai_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt)
{
+ struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai);
int ret;
+ if (sai->masterflag[FSL_FMT_TRANSMITTER])
+ fmt = (fmt & (~SND_SOC_DAIFMT_MASTER_MASK)) |
+ sai->masterflag[FSL_FMT_TRANSMITTER];
+
ret = fsl_sai_set_dai_fmt_tr(cpu_dai, fmt, FSL_FMT_TRANSMITTER);
if (ret) {
dev_err(cpu_dai->dev, "Cannot set tx format: %d\n", ret);
return ret;
}
+ if (sai->masterflag[FSL_FMT_RECEIVER])
+ fmt = (fmt & (~SND_SOC_DAIFMT_MASTER_MASK)) |
+ sai->masterflag[FSL_FMT_RECEIVER];
+
ret = fsl_sai_set_dai_fmt_tr(cpu_dai, fmt, FSL_FMT_RECEIVER);
if (ret)
dev_err(cpu_dai->dev, "Cannot set rx format: %d\n", ret);
@@ -317,18 +473,64 @@ static int fsl_sai_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt)
return ret;
}
+static int fsl_sai_check_ver(struct snd_soc_dai *cpu_dai)
+{
+ struct fsl_sai *sai = dev_get_drvdata(cpu_dai->dev);
+ unsigned char offset = sai->soc->reg_offset;
+ unsigned int val;
+
+ if (FSL_SAI_TCSR(offset) == FSL_SAI_VERID)
+ return 0;
+
+ if (sai->verid.loaded)
+ return 0;
+
+ sai->verid.loaded = true;
+ regmap_read(sai->regmap, FSL_SAI_VERID, &val);
+ dev_dbg(cpu_dai->dev, "VERID: 0x%016X\n", val);
+
+ sai->verid.id = (val & FSL_SAI_VER_ID_MASK) >> FSL_SAI_VER_ID_SHIFT;
+ sai->verid.extfifo_en = (val & FSL_SAI_VER_EFIFO_EN);
+ sai->verid.timestamp_en = (val & FSL_SAI_VER_TSTMP_EN);
+
+ regmap_read(sai->regmap, FSL_SAI_PARAM, &val);
+ dev_dbg(cpu_dai->dev, "PARAM: 0x%016X\n", val);
+
+ /* max slots per frame, power of 2 */
+ sai->param.spf = 1 <<
+ ((val & FSL_SAI_PAR_SPF_MASK) >> FSL_SAI_PAR_SPF_SHIFT);
+
+ /* words per fifo, power of 2 */
+ sai->param.wpf = 1 <<
+ ((val & FSL_SAI_PAR_WPF_MASK) >> FSL_SAI_PAR_WPF_SHIFT);
+
+ /* number of datalines implemented */
+ sai->param.dln = val & FSL_SAI_PAR_DLN_MASK;
+
+ dev_dbg(cpu_dai->dev,
+ "Version: 0x%08X, SPF: %u, WPF: %u, DLN: %u\n",
+ sai->verid.id, sai->param.spf, sai->param.wpf, sai->param.dln
+ );
+
+ return 0;
+}
+
static int fsl_sai_set_bclk(struct snd_soc_dai *dai, bool tx, u32 freq)
{
struct fsl_sai *sai = snd_soc_dai_get_drvdata(dai);
+ unsigned char offset = sai->soc->reg_offset;
unsigned long clk_rate;
- u32 savediv = 0, ratio, savesub = freq;
+ unsigned int reg = 0;
+ u32 ratio, savesub = freq, saveratio = 0, savediv = 0;
u32 id;
int ret = 0;
/* Don't apply to slave mode */
- if (sai->is_slave_mode)
+ if (sai->slave_mode[tx])
return 0;
+ fsl_sai_check_ver(dai);
+
for (id = 0; id < FSL_SAI_MCLK_MAX; id++) {
clk_rate = clk_get_rate(sai->mclk_clk[id]);
if (!clk_rate)
@@ -349,22 +551,21 @@ static int fsl_sai_set_bclk(struct snd_soc_dai *dai, bool tx, u32 freq)
"ratio %d for freq %dHz based on clock %ldHz\n",
ratio, freq, clk_rate);
- if (ratio % 2 == 0 && ratio >= 2 && ratio <= 512)
- ratio /= 2;
- else
- continue;
+ if ((ratio % 2 == 0 && ratio >= 2 && ratio <= 512) ||
+ (ratio == 1 && sai->verid.id >= FSL_SAI_VERID_0301)) {
- if (ret < savesub) {
- savediv = ratio;
- sai->mclk_id[tx] = id;
- savesub = ret;
- }
+ if (ret < savesub) {
+ saveratio = ratio;
+ sai->mclk_id[tx] = id;
+ savesub = ret;
+ }
- if (ret == 0)
- break;
+ if (ret == 0)
+ break;
+ }
}
- if (savediv == 0) {
+ if (saveratio == 0) {
dev_err(dai->dev, "failed to derive required %cx rate: %d\n",
tx ? 'T' : 'R', freq);
return -EINVAL;
@@ -380,24 +581,32 @@ static int fsl_sai_set_bclk(struct snd_soc_dai *dai, bool tx, u32 freq)
* 4) For Tx and Rx are both Synchronous with another SAI, we just
* ignore it.
*/
- if ((sai->synchronous[TX] && !sai->synchronous[RX]) ||
- (!tx && !sai->synchronous[RX])) {
- regmap_update_bits(sai->regmap, FSL_SAI_RCR2,
- FSL_SAI_CR2_MSEL_MASK,
- FSL_SAI_CR2_MSEL(sai->mclk_id[tx]));
- regmap_update_bits(sai->regmap, FSL_SAI_RCR2,
- FSL_SAI_CR2_DIV_MASK, savediv - 1);
- } else if ((sai->synchronous[RX] && !sai->synchronous[TX]) ||
- (tx && !sai->synchronous[TX])) {
- regmap_update_bits(sai->regmap, FSL_SAI_TCR2,
- FSL_SAI_CR2_MSEL_MASK,
- FSL_SAI_CR2_MSEL(sai->mclk_id[tx]));
- regmap_update_bits(sai->regmap, FSL_SAI_TCR2,
- FSL_SAI_CR2_DIV_MASK, savediv - 1);
- }
-
- dev_dbg(dai->dev, "best fit: clock id=%d, div=%d, deviation =%d\n",
- sai->mclk_id[tx], savediv, savesub);
+ if ((!tx || sai->synchronous[TX]) && !sai->synchronous[RX])
+ reg = FSL_SAI_RCR2(offset);
+ else if ((tx || sai->synchronous[RX]) && !sai->synchronous[TX])
+ reg = FSL_SAI_TCR2(offset);
+
+ if (reg) {
+ regmap_update_bits(sai->regmap, reg, FSL_SAI_CR2_MSEL_MASK,
+ FSL_SAI_CR2_MSEL(sai->mclk_id[tx]));
+
+ savediv = (saveratio == 1 ? 0 : (saveratio >> 1) - 1);
+ regmap_update_bits(sai->regmap, reg, FSL_SAI_CR2_DIV_MASK, savediv);
+
+ if (sai->verid.id >= FSL_SAI_VERID_0301) {
+ regmap_update_bits(sai->regmap, reg, FSL_SAI_CR2_BYP,
+ (saveratio == 1 ? FSL_SAI_CR2_BYP : 0));
+ }
+ }
+
+ if (sai->verid.id >= FSL_SAI_VERID_0301) {
+ /* SAI is in master mode at this point, so enable MCLK */
+ regmap_update_bits(sai->regmap, FSL_SAI_MCTL,
+ FSL_SAI_MCTL_MCLK_EN, FSL_SAI_MCTL_MCLK_EN);
+ }
+
+ dev_dbg(dai->dev, "best fit: clock id=%d, ratio=%d, deviation=%d\n",
+ sai->mclk_id[tx], saveratio, savesub);
return 0;
}
@@ -407,23 +616,65 @@ static int fsl_sai_hw_params(struct snd_pcm_substream *substream,
struct snd_soc_dai *cpu_dai)
{
struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai);
+ unsigned char offset = sai->soc->reg_offset;
bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
unsigned int channels = params_channels(params);
u32 word_width = params_width(params);
+ u32 rate = params_rate(params);
u32 val_cr4 = 0, val_cr5 = 0;
u32 slots = (channels == 1) ? 2 : channels;
u32 slot_width = word_width;
- int ret;
+ u32 pins, bclk;
+ int ret, i, trce_mask = 0, dl_cfg_cnt, dl_cfg_idx = 0;
+ struct fsl_sai_dl_cfg *dl_cfg;
if (sai->slots)
slots = sai->slots;
+ pins = DIV_ROUND_UP(channels, slots);
+ sai->is_dsd = fsl_is_dsd(params);
+ if (sai->is_dsd) {
+ pins = channels;
+ dl_cfg = sai->dsd_dl_cfg;
+ dl_cfg_cnt = sai->dsd_dl_cfg_cnt;
+ } else {
+ dl_cfg = sai->pcm_dl_cfg;
+ dl_cfg_cnt = sai->pcm_dl_cfg_cnt;
+ }
+
+ for (i = 0; i < dl_cfg_cnt; i++) {
+ if (dl_cfg[i].pins == pins) {
+ dl_cfg_idx = i;
+ break;
+ }
+ }
+
+ if (dl_cfg_idx >= dl_cfg_cnt) {
+ dev_err(cpu_dai->dev, "fsl,dataline%s invalid or not provided.\n",
+ sai->is_dsd ? ",dsd" : "");
+ return -EINVAL;
+ }
+
if (sai->slot_width)
slot_width = sai->slot_width;
- if (!sai->is_slave_mode) {
- ret = fsl_sai_set_bclk(cpu_dai, tx,
- slots * slot_width * params_rate(params));
+ bclk = rate*(sai->bitclk_ratio ? sai->bitclk_ratio : slots * slot_width);
+
+ if (!IS_ERR_OR_NULL(sai->pinctrl)) {
+ sai->pins_state = fsl_get_pins_state(sai->pinctrl, params, bclk);
+
+ if (!IS_ERR_OR_NULL(sai->pins_state)) {
+ ret = pinctrl_select_state(sai->pinctrl, sai->pins_state);
+ if (ret) {
+ dev_err(cpu_dai->dev,
+ "failed to set proper pins state: %d\n", ret);
+ return ret;
+ }
+ }
+ }
+
+ if (!sai->slave_mode[tx]) {
+ ret = fsl_sai_set_bclk(cpu_dai, tx, bclk);
if (ret)
return ret;
@@ -443,13 +694,18 @@ static int fsl_sai_hw_params(struct snd_pcm_substream *substream,
val_cr5 |= FSL_SAI_CR5_WNW(slot_width);
val_cr5 |= FSL_SAI_CR5_W0W(slot_width);
- if (sai->is_lsb_first)
+ if (sai->is_lsb_first || sai->is_dsd)
val_cr5 |= FSL_SAI_CR5_FBT(0);
else
val_cr5 |= FSL_SAI_CR5_FBT(word_width - 1);
val_cr4 |= FSL_SAI_CR4_FRSZ(slots);
+ /* Output Mode - data pins transmit 0 when slots are masked
+ * or channels are disabled
+ */
+ val_cr4 |= FSL_SAI_CR4_CHMOD;
+
/*
* For SAI master mode, when Tx(Rx) sync with Rx(Tx) clock, Rx(Tx) will
* generate bclk and frame clock for Tx(Rx), we should set RCR4(TCR4),
@@ -457,36 +713,78 @@ static int fsl_sai_hw_params(struct snd_pcm_substream *substream,
* error.
*/
- if (!sai->is_slave_mode) {
+ if (!sai->slave_mode[tx]) {
if (!sai->synchronous[TX] && sai->synchronous[RX] && !tx) {
- regmap_update_bits(sai->regmap, FSL_SAI_TCR4,
- FSL_SAI_CR4_SYWD_MASK | FSL_SAI_CR4_FRSZ_MASK,
+ regmap_update_bits(sai->regmap, FSL_SAI_TCR4(offset),
+ FSL_SAI_CR4_SYWD_MASK | FSL_SAI_CR4_FRSZ_MASK |
+ FSL_SAI_CR4_CHMOD_MASK,
val_cr4);
- regmap_update_bits(sai->regmap, FSL_SAI_TCR5,
+ regmap_update_bits(sai->regmap, FSL_SAI_TCR5(offset),
FSL_SAI_CR5_WNW_MASK | FSL_SAI_CR5_W0W_MASK |
FSL_SAI_CR5_FBT_MASK, val_cr5);
- regmap_write(sai->regmap, FSL_SAI_TMR,
- ~0UL - ((1 << channels) - 1));
} else if (!sai->synchronous[RX] && sai->synchronous[TX] && tx) {
- regmap_update_bits(sai->regmap, FSL_SAI_RCR4,
- FSL_SAI_CR4_SYWD_MASK | FSL_SAI_CR4_FRSZ_MASK,
+ regmap_update_bits(sai->regmap, FSL_SAI_RCR4(offset),
+ FSL_SAI_CR4_SYWD_MASK | FSL_SAI_CR4_FRSZ_MASK |
+ FSL_SAI_CR4_CHMOD_MASK,
val_cr4);
- regmap_update_bits(sai->regmap, FSL_SAI_RCR5,
+ regmap_update_bits(sai->regmap, FSL_SAI_RCR5(offset),
FSL_SAI_CR5_WNW_MASK | FSL_SAI_CR5_W0W_MASK |
FSL_SAI_CR5_FBT_MASK, val_cr5);
- regmap_write(sai->regmap, FSL_SAI_RMR,
- ~0UL - ((1 << channels) - 1));
}
}
- regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx),
- FSL_SAI_CR4_SYWD_MASK | FSL_SAI_CR4_FRSZ_MASK,
+ if (sai->soc->dataline != 0x1) {
+
+ if (dl_cfg[dl_cfg_idx].mask[tx] <= 1 || sai->is_multi_lane)
+ regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx, offset),
+ FSL_SAI_CR4_FCOMB_MASK, 0);
+ else
+ regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx, offset),
+ FSL_SAI_CR4_FCOMB_MASK, FSL_SAI_CR4_FCOMB_SOFT);
+
+ if (sai->is_multi_lane) {
+ if (tx) {
+ sai->dma_params_tx.maxburst =
+ FSL_SAI_MAXBURST_TX * pins;
+ sai->dma_params_tx.fifo_num = pins +
+ (dl_cfg[dl_cfg_idx].offset[tx] << 4);
+ } else {
+ sai->dma_params_rx.maxburst =
+ FSL_SAI_MAXBURST_RX * pins;
+ sai->dma_params_rx.fifo_num = pins +
+ (dl_cfg[dl_cfg_idx].offset[tx] << 4);
+ }
+ }
+
+ snd_soc_dai_init_dma_data(cpu_dai, &sai->dma_params_tx,
+ &sai->dma_params_rx);
+ }
+
+ if (__sw_hweight8(dl_cfg[dl_cfg_idx].mask[tx] & 0xFF) < pins) {
+ dev_err(cpu_dai->dev, "channel not supported\n");
+ return -EINVAL;
+ }
+
+ /*find a proper tcre setting*/
+ for (i = 0; i < 8; i++) {
+ trce_mask = (1 << (i + 1)) - 1;
+ if (__sw_hweight8(dl_cfg[dl_cfg_idx].mask[tx] & trce_mask) == pins)
+ break;
+ }
+
+ regmap_update_bits(sai->regmap, FSL_SAI_xCR3(tx, offset),
+ FSL_SAI_CR3_TRCE_MASK,
+ FSL_SAI_CR3_TRCE((dl_cfg[dl_cfg_idx].mask[tx] & trce_mask)));
+
+ regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx, offset),
+ FSL_SAI_CR4_SYWD_MASK | FSL_SAI_CR4_FRSZ_MASK |
+ FSL_SAI_CR4_CHMOD_MASK,
val_cr4);
- regmap_update_bits(sai->regmap, FSL_SAI_xCR5(tx),
+ regmap_update_bits(sai->regmap, FSL_SAI_xCR5(tx, offset),
FSL_SAI_CR5_WNW_MASK | FSL_SAI_CR5_W0W_MASK |
FSL_SAI_CR5_FBT_MASK, val_cr5);
- regmap_write(sai->regmap, FSL_SAI_xMR(tx), ~0UL - ((1 << channels) - 1));
-
+ regmap_write(sai->regmap, FSL_SAI_xMR(tx),
+ ~0UL - ((1 << min(channels, slots)) - 1));
return 0;
}
@@ -494,9 +792,13 @@ static int fsl_sai_hw_free(struct snd_pcm_substream *substream,
struct snd_soc_dai *cpu_dai)
{
struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai);
+ unsigned char offset = sai->soc->reg_offset;
bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
- if (!sai->is_slave_mode &&
+ regmap_update_bits(sai->regmap, FSL_SAI_xCR3(tx, offset),
+ FSL_SAI_CR3_TRCE_MASK, 0);
+
+ if (!sai->slave_mode[tx] &&
sai->mclk_streams & BIT(substream->stream)) {
clk_disable_unprepare(sai->mclk_clk[sai->mclk_id[tx]]);
sai->mclk_streams &= ~BIT(substream->stream);
@@ -510,17 +812,46 @@ static int fsl_sai_trigger(struct snd_pcm_substream *substream, int cmd,
struct snd_soc_dai *cpu_dai)
{
struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai);
+ unsigned char offset = sai->soc->reg_offset;
bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
+ u8 channels = substream->runtime->channels;
+ u32 slots = (channels == 1) ? 2 : channels;
u32 xcsr, count = 100;
+ u32 pins;
+ int i = 0, j = 0, k = 0, dl_cfg_cnt, dl_cfg_idx = 0;
+ struct fsl_sai_dl_cfg *dl_cfg;
+
+ if (sai->slots)
+ slots = sai->slots;
+
+ pins = DIV_ROUND_UP(channels, slots);
+
+ if (sai->is_dsd) {
+ pins = channels;
+ dl_cfg = sai->dsd_dl_cfg;
+ dl_cfg_cnt = sai->dsd_dl_cfg_cnt;
+ } else {
+ dl_cfg = sai->pcm_dl_cfg;
+ dl_cfg_cnt = sai->pcm_dl_cfg_cnt;
+ }
+
+ for (i = 0; i < dl_cfg_cnt; i++) {
+ if (dl_cfg[i].pins == pins) {
+ dl_cfg_idx = i;
+ break;
+ }
+ }
+
+ i = 0;
/*
* Asynchronous mode: Clear SYNC for both Tx and Rx.
* Rx sync with Tx clocks: Clear SYNC for Tx, set it for Rx.
* Tx sync with Rx clocks: Clear SYNC for Rx, set it for Tx.
*/
- regmap_update_bits(sai->regmap, FSL_SAI_TCR2, FSL_SAI_CR2_SYNC,
+ regmap_update_bits(sai->regmap, FSL_SAI_TCR2(offset), FSL_SAI_CR2_SYNC,
sai->synchronous[TX] ? FSL_SAI_CR2_SYNC : 0);
- regmap_update_bits(sai->regmap, FSL_SAI_RCR2, FSL_SAI_CR2_SYNC,
+ regmap_update_bits(sai->regmap, FSL_SAI_RCR2(offset), FSL_SAI_CR2_SYNC,
sai->synchronous[RX] ? FSL_SAI_CR2_SYNC : 0);
/*
@@ -531,43 +862,63 @@ static int fsl_sai_trigger(struct snd_pcm_substream *substream, int cmd,
case SNDRV_PCM_TRIGGER_START:
case SNDRV_PCM_TRIGGER_RESUME:
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx),
+
+ while (tx && i < channels) {
+ if (dl_cfg[dl_cfg_idx].mask[tx] & (1 << j)) {
+ regmap_write(sai->regmap, FSL_SAI_TDR0 + j * 0x4, 0x0);
+ i++;
+ k++;
+ }
+ j++;
+
+ if (k%pins == 0)
+ j = 0;
+ }
+
+ regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx, offset),
FSL_SAI_CSR_FRDE, FSL_SAI_CSR_FRDE);
- regmap_update_bits(sai->regmap, FSL_SAI_RCSR,
+ regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx, offset),
+ FSL_SAI_CSR_TERE, FSL_SAI_CSR_TERE);
+ regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx, offset),
+ FSL_SAI_CSR_SE, FSL_SAI_CSR_SE);
+ if (!sai->synchronous[TX] && sai->synchronous[RX] && !tx) {
+ regmap_update_bits(sai->regmap, FSL_SAI_xCSR((!tx), offset),
FSL_SAI_CSR_TERE, FSL_SAI_CSR_TERE);
- regmap_update_bits(sai->regmap, FSL_SAI_TCSR,
+ } else if (!sai->synchronous[RX] && sai->synchronous[TX] && tx) {
+ regmap_update_bits(sai->regmap, FSL_SAI_xCSR((!tx), offset),
FSL_SAI_CSR_TERE, FSL_SAI_CSR_TERE);
+ }
- regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx),
+ regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx, offset),
FSL_SAI_CSR_xIE_MASK, FSL_SAI_FLAGS);
break;
case SNDRV_PCM_TRIGGER_STOP:
case SNDRV_PCM_TRIGGER_SUSPEND:
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx),
+ regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx, offset),
FSL_SAI_CSR_FRDE, 0);
- regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx),
+ regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx, offset),
FSL_SAI_CSR_xIE_MASK, 0);
/* Check if the opposite FRDE is also disabled */
- regmap_read(sai->regmap, FSL_SAI_xCSR(!tx), &xcsr);
+ regmap_read(sai->regmap, FSL_SAI_xCSR(!tx, offset), &xcsr);
if (!(xcsr & FSL_SAI_CSR_FRDE)) {
/* Disable both directions and reset their FIFOs */
- regmap_update_bits(sai->regmap, FSL_SAI_TCSR,
+ regmap_update_bits(sai->regmap, FSL_SAI_TCSR(offset),
FSL_SAI_CSR_TERE, 0);
- regmap_update_bits(sai->regmap, FSL_SAI_RCSR,
+ regmap_update_bits(sai->regmap, FSL_SAI_RCSR(offset),
FSL_SAI_CSR_TERE, 0);
/* TERE will remain set till the end of current frame */
do {
udelay(10);
- regmap_read(sai->regmap, FSL_SAI_xCSR(tx), &xcsr);
+ regmap_read(sai->regmap, FSL_SAI_xCSR(tx, offset), &xcsr);
} while (--count && xcsr & FSL_SAI_CSR_TERE);
- regmap_update_bits(sai->regmap, FSL_SAI_TCSR,
+ regmap_update_bits(sai->regmap, FSL_SAI_TCSR(offset),
FSL_SAI_CSR_FR, FSL_SAI_CSR_FR);
- regmap_update_bits(sai->regmap, FSL_SAI_RCSR,
+ regmap_update_bits(sai->regmap, FSL_SAI_RCSR(offset),
FSL_SAI_CSR_FR, FSL_SAI_CSR_FR);
/*
@@ -577,15 +928,15 @@ static int fsl_sai_trigger(struct snd_pcm_substream *substream, int cmd,
* This is a hardware bug, and will be fix in the
* next sai version.
*/
- if (!sai->is_slave_mode) {
+ if (!sai->slave_mode[tx]) {
/* Software Reset for both Tx and Rx */
regmap_write(sai->regmap,
- FSL_SAI_TCSR, FSL_SAI_CSR_SR);
+ FSL_SAI_TCSR(offset), FSL_SAI_CSR_SR);
regmap_write(sai->regmap,
- FSL_SAI_RCSR, FSL_SAI_CSR_SR);
+ FSL_SAI_RCSR(offset), FSL_SAI_CSR_SR);
/* Clear SR bit to finish the reset */
- regmap_write(sai->regmap, FSL_SAI_TCSR, 0);
- regmap_write(sai->regmap, FSL_SAI_RCSR, 0);
+ regmap_write(sai->regmap, FSL_SAI_TCSR(offset), 0);
+ regmap_write(sai->regmap, FSL_SAI_RCSR(offset), 0);
}
}
break;
@@ -601,17 +952,19 @@ static int fsl_sai_startup(struct snd_pcm_substream *substream,
{
struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai);
bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
- struct device *dev = &sai->pdev->dev;
int ret;
- ret = clk_prepare_enable(sai->bus_clk);
- if (ret) {
- dev_err(dev, "failed to enable bus clock: %d\n", ret);
- return ret;
- }
+ if (sai->is_stream_opened[tx])
+ return -EBUSY;
+ else
+ sai->is_stream_opened[tx] = true;
- regmap_update_bits(sai->regmap, FSL_SAI_xCR3(tx), FSL_SAI_CR3_TRCE,
- FSL_SAI_CR3_TRCE);
+ /* EDMA engine needs periods of size multiple of tx/rx maxburst */
+ if (sai->soc->constrain_period_size)
+ snd_pcm_hw_constraint_step(substream->runtime, 0,
+ SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
+ tx ? sai->dma_params_tx.maxburst :
+ sai->dma_params_rx.maxburst);
ret = snd_pcm_hw_constraint_list(substream->runtime, 0,
SNDRV_PCM_HW_PARAM_RATE, &fsl_sai_rate_constraints);
@@ -625,12 +978,12 @@ static void fsl_sai_shutdown(struct snd_pcm_substream *substream,
struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai);
bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
- regmap_update_bits(sai->regmap, FSL_SAI_xCR3(tx), FSL_SAI_CR3_TRCE, 0);
-
- clk_disable_unprepare(sai->bus_clk);
+ if (sai->is_stream_opened[tx])
+ sai->is_stream_opened[tx] = false;
}
static const struct snd_soc_dai_ops fsl_sai_pcm_dai_ops = {
+ .set_bclk_ratio = fsl_sai_set_dai_bclk_ratio,
.set_sysclk = fsl_sai_set_dai_sysclk,
.set_fmt = fsl_sai_set_dai_fmt,
.set_tdm_slot = fsl_sai_set_dai_tdm_slot,
@@ -644,18 +997,21 @@ static const struct snd_soc_dai_ops fsl_sai_pcm_dai_ops = {
static int fsl_sai_dai_probe(struct snd_soc_dai *cpu_dai)
{
struct fsl_sai *sai = dev_get_drvdata(cpu_dai->dev);
+ unsigned char offset = sai->soc->reg_offset;
/* Software Reset for both Tx and Rx */
- regmap_write(sai->regmap, FSL_SAI_TCSR, FSL_SAI_CSR_SR);
- regmap_write(sai->regmap, FSL_SAI_RCSR, FSL_SAI_CSR_SR);
+ regmap_write(sai->regmap, FSL_SAI_TCSR(offset), FSL_SAI_CSR_SR);
+ regmap_write(sai->regmap, FSL_SAI_RCSR(offset), FSL_SAI_CSR_SR);
/* Clear SR bit to finish the reset */
- regmap_write(sai->regmap, FSL_SAI_TCSR, 0);
- regmap_write(sai->regmap, FSL_SAI_RCSR, 0);
+ regmap_write(sai->regmap, FSL_SAI_TCSR(offset), 0);
+ regmap_write(sai->regmap, FSL_SAI_RCSR(offset), 0);
- regmap_update_bits(sai->regmap, FSL_SAI_TCR1, FSL_SAI_CR1_RFW_MASK,
- FSL_SAI_MAXBURST_TX * 2);
- regmap_update_bits(sai->regmap, FSL_SAI_RCR1, FSL_SAI_CR1_RFW_MASK,
- FSL_SAI_MAXBURST_RX - 1);
+ regmap_update_bits(sai->regmap, FSL_SAI_TCR1(offset),
+ sai->soc->fifo_depth - 1,
+ sai->soc->fifo_depth - FSL_SAI_MAXBURST_TX);
+ regmap_update_bits(sai->regmap, FSL_SAI_RCR1(offset),
+ sai->soc->fifo_depth - 1,
+ FSL_SAI_MAXBURST_RX - 1);
snd_soc_dai_init_dma_data(cpu_dai, &sai->dma_params_tx,
&sai->dma_params_rx);
@@ -665,6 +1021,23 @@ static int fsl_sai_dai_probe(struct snd_soc_dai *cpu_dai)
return 0;
}
+static int fsl_sai_dai_resume(struct snd_soc_dai *cpu_dai)
+{
+ struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai);
+ int ret;
+
+ if (!IS_ERR_OR_NULL(sai->pinctrl) && !IS_ERR_OR_NULL(sai->pins_state)) {
+ ret = pinctrl_select_state(sai->pinctrl, sai->pins_state);
+ if (ret) {
+ dev_err(cpu_dai->dev,
+ "failed to set proper pins state: %d\n", ret);
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
static struct snd_soc_dai_driver fsl_sai_dai = {
.probe = fsl_sai_dai_probe,
.playback = {
@@ -672,7 +1045,7 @@ static struct snd_soc_dai_driver fsl_sai_dai = {
.channels_min = 1,
.channels_max = 32,
.rate_min = 8000,
- .rate_max = 192000,
+ .rate_max = 2822400,
.rates = SNDRV_PCM_RATE_KNOT,
.formats = FSL_SAI_FORMATS,
},
@@ -681,10 +1054,11 @@ static struct snd_soc_dai_driver fsl_sai_dai = {
.channels_min = 1,
.channels_max = 32,
.rate_min = 8000,
- .rate_max = 192000,
+ .rate_max = 2822400,
.rates = SNDRV_PCM_RATE_KNOT,
.formats = FSL_SAI_FORMATS,
},
+ .resume = fsl_sai_dai_resume,
.ops = &fsl_sai_pcm_dai_ops,
};
@@ -692,42 +1066,90 @@ static const struct snd_soc_component_driver fsl_component = {
.name = "fsl-sai",
};
-static struct reg_default fsl_sai_reg_defaults[] = {
- {FSL_SAI_TCR1, 0},
- {FSL_SAI_TCR2, 0},
- {FSL_SAI_TCR3, 0},
- {FSL_SAI_TCR4, 0},
- {FSL_SAI_TCR5, 0},
- {FSL_SAI_TDR, 0},
+static struct reg_default fsl_sai_v2_reg_defaults[] = {
+ {FSL_SAI_TCR1(0), 0},
+ {FSL_SAI_TCR2(0), 0},
+ {FSL_SAI_TCR3(0), 0},
+ {FSL_SAI_TCR4(0), 0},
+ {FSL_SAI_TCR5(0), 0},
+ {FSL_SAI_TDR0, 0},
+ {FSL_SAI_TDR1, 0},
+ {FSL_SAI_TMR, 0},
+ {FSL_SAI_RCR1(0), 0},
+ {FSL_SAI_RCR2(0), 0},
+ {FSL_SAI_RCR3(0), 0},
+ {FSL_SAI_RCR4(0), 0},
+ {FSL_SAI_RCR5(0), 0},
+ {FSL_SAI_RMR, 0},
+};
+
+static struct reg_default fsl_sai_v3_reg_defaults[] = {
+ {FSL_SAI_TCR1(8), 0},
+ {FSL_SAI_TCR2(8), 0},
+ {FSL_SAI_TCR3(8), 0},
+ {FSL_SAI_TCR4(8), 0},
+ {FSL_SAI_TCR5(8), 0},
+ {FSL_SAI_TDR0, 0},
+ {FSL_SAI_TDR1, 0},
+ {FSL_SAI_TDR2, 0},
+ {FSL_SAI_TDR3, 0},
+ {FSL_SAI_TDR4, 0},
+ {FSL_SAI_TDR5, 0},
+ {FSL_SAI_TDR6, 0},
+ {FSL_SAI_TDR7, 0},
{FSL_SAI_TMR, 0},
- {FSL_SAI_RCR1, 0},
- {FSL_SAI_RCR2, 0},
- {FSL_SAI_RCR3, 0},
- {FSL_SAI_RCR4, 0},
- {FSL_SAI_RCR5, 0},
+ {FSL_SAI_RCR1(8), 0},
+ {FSL_SAI_RCR2(8), 0},
+ {FSL_SAI_RCR3(8), 0},
+ {FSL_SAI_RCR4(8), 0},
+ {FSL_SAI_RCR5(8), 0},
{FSL_SAI_RMR, 0},
+ {FSL_SAI_MCTL, 0},
+ {FSL_SAI_MDIV, 0},
};
static bool fsl_sai_readable_reg(struct device *dev, unsigned int reg)
{
+ struct fsl_sai *sai = dev_get_drvdata(dev);
+ unsigned char offset = sai->soc->reg_offset;
+
+ if (reg >= FSL_SAI_TCSR(offset) && reg <= FSL_SAI_TCR5(offset))
+ return true;
+
+ if (reg >= FSL_SAI_RCSR(offset) && reg <= FSL_SAI_RCR5(offset))
+ return true;
+
switch (reg) {
- case FSL_SAI_TCSR:
- case FSL_SAI_TCR1:
- case FSL_SAI_TCR2:
- case FSL_SAI_TCR3:
- case FSL_SAI_TCR4:
- case FSL_SAI_TCR5:
- case FSL_SAI_TFR:
+ case FSL_SAI_TFR0:
+ case FSL_SAI_TFR1:
+ case FSL_SAI_TFR2:
+ case FSL_SAI_TFR3:
+ case FSL_SAI_TFR4:
+ case FSL_SAI_TFR5:
+ case FSL_SAI_TFR6:
+ case FSL_SAI_TFR7:
case FSL_SAI_TMR:
- case FSL_SAI_RCSR:
- case FSL_SAI_RCR1:
- case FSL_SAI_RCR2:
- case FSL_SAI_RCR3:
- case FSL_SAI_RCR4:
- case FSL_SAI_RCR5:
- case FSL_SAI_RDR:
- case FSL_SAI_RFR:
+ case FSL_SAI_RDR0:
+ case FSL_SAI_RDR1:
+ case FSL_SAI_RDR2:
+ case FSL_SAI_RDR3:
+ case FSL_SAI_RDR4:
+ case FSL_SAI_RDR5:
+ case FSL_SAI_RDR6:
+ case FSL_SAI_RDR7:
+ case FSL_SAI_RFR0:
+ case FSL_SAI_RFR1:
+ case FSL_SAI_RFR2:
+ case FSL_SAI_RFR3:
+ case FSL_SAI_RFR4:
+ case FSL_SAI_RFR5:
+ case FSL_SAI_RFR6:
+ case FSL_SAI_RFR7:
case FSL_SAI_RMR:
+ case FSL_SAI_MCTL:
+ case FSL_SAI_MDIV:
+ case FSL_SAI_VERID:
+ case FSL_SAI_PARAM:
return true;
default:
return false;
@@ -736,12 +1158,41 @@ static bool fsl_sai_readable_reg(struct device *dev, unsigned int reg)
static bool fsl_sai_volatile_reg(struct device *dev, unsigned int reg)
{
+ struct fsl_sai *sai = dev_get_drvdata(dev);
+ unsigned char offset = sai->soc->reg_offset;
+
+ if (reg == FSL_SAI_TCSR(offset) || reg == FSL_SAI_RCSR(offset))
+ return true;
+
+ if (sai->soc->reg_offset == 8 && (reg == FSL_SAI_VERID ||
+ reg == FSL_SAI_PARAM))
+ return true;
+
switch (reg) {
- case FSL_SAI_TCSR:
- case FSL_SAI_RCSR:
- case FSL_SAI_TFR:
- case FSL_SAI_RFR:
- case FSL_SAI_RDR:
+ case FSL_SAI_TFR0:
+ case FSL_SAI_TFR1:
+ case FSL_SAI_TFR2:
+ case FSL_SAI_TFR3:
+ case FSL_SAI_TFR4:
+ case FSL_SAI_TFR5:
+ case FSL_SAI_TFR6:
+ case FSL_SAI_TFR7:
+ case FSL_SAI_RFR0:
+ case FSL_SAI_RFR1:
+ case FSL_SAI_RFR2:
+ case FSL_SAI_RFR3:
+ case FSL_SAI_RFR4:
+ case FSL_SAI_RFR5:
+ case FSL_SAI_RFR6:
+ case FSL_SAI_RFR7:
+ case FSL_SAI_RDR0:
+ case FSL_SAI_RDR1:
+ case FSL_SAI_RDR2:
+ case FSL_SAI_RDR3:
+ case FSL_SAI_RDR4:
+ case FSL_SAI_RDR5:
+ case FSL_SAI_RDR6:
+ case FSL_SAI_RDR7:
return true;
default:
return false;
@@ -750,45 +1201,148 @@ static bool fsl_sai_volatile_reg(struct device *dev, unsigned int reg)
static bool fsl_sai_writeable_reg(struct device *dev, unsigned int reg)
{
+ struct fsl_sai *sai = dev_get_drvdata(dev);
+ unsigned char offset = sai->soc->reg_offset;
+
+ if (reg >= FSL_SAI_TCSR(offset) && reg <= FSL_SAI_TCR5(offset))
+ return true;
+
+ if (reg >= FSL_SAI_RCSR(offset) && reg <= FSL_SAI_RCR5(offset))
+ return true;
+
switch (reg) {
- case FSL_SAI_TCSR:
- case FSL_SAI_TCR1:
- case FSL_SAI_TCR2:
- case FSL_SAI_TCR3:
- case FSL_SAI_TCR4:
- case FSL_SAI_TCR5:
- case FSL_SAI_TDR:
+ case FSL_SAI_TDR0:
+ case FSL_SAI_TDR1:
+ case FSL_SAI_TDR2:
+ case FSL_SAI_TDR3:
+ case FSL_SAI_TDR4:
+ case FSL_SAI_TDR5:
+ case FSL_SAI_TDR6:
+ case FSL_SAI_TDR7:
case FSL_SAI_TMR:
- case FSL_SAI_RCSR:
- case FSL_SAI_RCR1:
- case FSL_SAI_RCR2:
- case FSL_SAI_RCR3:
- case FSL_SAI_RCR4:
- case FSL_SAI_RCR5:
case FSL_SAI_RMR:
+ case FSL_SAI_MCTL:
+ case FSL_SAI_MDIV:
return true;
default:
return false;
}
}
-static const struct regmap_config fsl_sai_regmap_config = {
+static const struct regmap_config fsl_sai_v2_regmap_config = {
.reg_bits = 32,
.reg_stride = 4,
.val_bits = 32,
.max_register = FSL_SAI_RMR,
- .reg_defaults = fsl_sai_reg_defaults,
- .num_reg_defaults = ARRAY_SIZE(fsl_sai_reg_defaults),
+ .reg_defaults = fsl_sai_v2_reg_defaults,
+ .num_reg_defaults = ARRAY_SIZE(fsl_sai_v2_reg_defaults),
+ .readable_reg = fsl_sai_readable_reg,
+ .volatile_reg = fsl_sai_volatile_reg,
+ .writeable_reg = fsl_sai_writeable_reg,
+ .cache_type = REGCACHE_FLAT,
+};
+
+static const struct regmap_config fsl_sai_v3_regmap_config = {
+ .reg_bits = 32,
+ .reg_stride = 4,
+ .val_bits = 32,
+
+ .max_register = FSL_SAI_MDIV,
+ .reg_defaults = fsl_sai_v3_reg_defaults,
+ .num_reg_defaults = ARRAY_SIZE(fsl_sai_v3_reg_defaults),
.readable_reg = fsl_sai_readable_reg,
.volatile_reg = fsl_sai_volatile_reg,
.writeable_reg = fsl_sai_writeable_reg,
.cache_type = REGCACHE_FLAT,
};
+static const struct of_device_id fsl_sai_ids[] = {
+ { .compatible = "fsl,vf610-sai", .data = &fsl_sai_vf610 },
+ { .compatible = "fsl,imx6sx-sai", .data = &fsl_sai_imx6sx },
+ { .compatible = "fsl,imx6ul-sai", .data = &fsl_sai_imx6ul },
+ { .compatible = "fsl,imx7ulp-sai", .data = &fsl_sai_imx7ulp },
+ { .compatible = "fsl,imx8mq-sai", .data = &fsl_sai_imx8mq },
+ { .compatible = "fsl,imx8qm-sai", .data = &fsl_sai_imx8qm },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, fsl_sai_ids);
+
+static unsigned int fsl_sai_calc_dl_off(unsigned int* dl_mask)
+{
+ int fbidx, nbidx, offset;
+
+ fbidx = find_first_bit((const unsigned long *)dl_mask, 8);
+ nbidx = find_next_bit((const unsigned long *)dl_mask, 8, fbidx+1);
+ offset = nbidx - fbidx - 1;
+
+ return (offset < 0 || offset >= 7 ? 0 : offset);
+}
+
+static int fsl_sai_read_dlcfg(struct platform_device *pdev, char *pn,
+ struct fsl_sai_dl_cfg **rcfg, unsigned int soc_dl)
+{
+ int ret, elems, i, index, num_cfg;
+ struct device_node *np = pdev->dev.of_node;
+ struct fsl_sai_dl_cfg *cfg;
+ u32 rx, tx, pins;
+
+ *rcfg = NULL;
+
+ elems = of_property_count_u32_elems(np, pn);
+
+ /* consider default value "0 0x1 0x1" if property is missing */
+ if (elems <= 0)
+ elems = 3;
+
+ if (elems % 3) {
+ dev_err(&pdev->dev,
+ "Number of elements in %s must be divisible to 3.\n", pn);
+ return -EINVAL;
+ }
+
+ num_cfg = elems / 3;
+ cfg = devm_kzalloc(&pdev->dev, num_cfg * sizeof(*cfg), GFP_KERNEL);
+ if (cfg == NULL) {
+ dev_err(&pdev->dev, "Cannot allocate memory for %s.\n", pn);
+ return -ENOMEM;
+ }
+
+ for (i = 0, index = 0; i < num_cfg; i++) {
+ ret = of_property_read_u32_index(np, pn, index++, &pins);
+ if (ret)
+ pins = 0;
+
+ ret = of_property_read_u32_index(np, pn, index++, &rx);
+ if (ret)
+ rx = 1;
+
+ ret = of_property_read_u32_index(np, pn, index++, &tx);
+ if (ret)
+ tx = 1;
+
+ if ((rx & ~soc_dl) || (tx & ~soc_dl)) {
+ dev_err(&pdev->dev,
+ "%s: dataline cfg[%d] setting error, mask is 0x%x\n",
+ pn, i, soc_dl);
+ return -EINVAL;
+ }
+
+ cfg[i].pins = pins;
+ cfg[i].mask[0] = rx;
+ cfg[i].offset[0] = fsl_sai_calc_dl_off(&rx);
+ cfg[i].mask[1] = tx;
+ cfg[i].offset[1] = fsl_sai_calc_dl_off(&tx);
+ }
+
+ *rcfg = cfg;
+ return num_cfg;
+}
+
static int fsl_sai_probe(struct platform_device *pdev)
{
struct device_node *np = pdev->dev.of_node;
+ const struct of_device_id *of_id;
struct fsl_sai *sai;
struct regmap *gpr;
struct resource *res;
@@ -796,6 +1350,9 @@ static int fsl_sai_probe(struct platform_device *pdev)
char tmp[8];
int irq, ret, i;
int index;
+ u32 buffer_size;
+ struct regmap_config fsl_sai_regmap_config = fsl_sai_v2_regmap_config;
+ unsigned long irqflags = 0;
sai = devm_kzalloc(&pdev->dev, sizeof(*sai), GFP_KERNEL);
if (!sai)
@@ -803,17 +1360,21 @@ static int fsl_sai_probe(struct platform_device *pdev)
sai->pdev = pdev;
- if (of_device_is_compatible(np, "fsl,imx6sx-sai") ||
- of_device_is_compatible(np, "fsl,imx6ul-sai"))
- sai->sai_on_imx = true;
+ of_id = of_match_device(fsl_sai_ids, &pdev->dev);
+ if (!of_id || !of_id->data)
+ return -EINVAL;
sai->is_lsb_first = of_property_read_bool(np, "lsb-first");
+ sai->soc = of_id->data;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(base))
return PTR_ERR(base);
+ if (sai->soc->reg_offset == 8)
+ fsl_sai_regmap_config = fsl_sai_v3_regmap_config;
+
sai->regmap = devm_regmap_init_mmio_clk(&pdev->dev,
"bus", base, &fsl_sai_regmap_config);
@@ -834,24 +1395,68 @@ static int fsl_sai_probe(struct platform_device *pdev)
sai->bus_clk = NULL;
}
- sai->mclk_clk[0] = sai->bus_clk;
- for (i = 1; i < FSL_SAI_MCLK_MAX; i++) {
+ for (i = 0; i < FSL_SAI_MCLK_MAX; i++) {
sprintf(tmp, "mclk%d", i);
sai->mclk_clk[i] = devm_clk_get(&pdev->dev, tmp);
if (IS_ERR(sai->mclk_clk[i])) {
dev_err(&pdev->dev, "failed to get mclk%d clock: %ld\n",
- i + 1, PTR_ERR(sai->mclk_clk[i]));
+ i, PTR_ERR(sai->mclk_clk[i]));
sai->mclk_clk[i] = NULL;
}
}
+ sai->pll8k_clk = devm_clk_get(&pdev->dev, "pll8k");
+ if (IS_ERR(sai->pll8k_clk))
+ sai->pll8k_clk = NULL;
+
+ sai->pll11k_clk = devm_clk_get(&pdev->dev, "pll11k");
+ if (IS_ERR(sai->pll11k_clk))
+ sai->pll11k_clk = NULL;
+
+ if (of_find_property(np, "fsl,sai-multi-lane", NULL))
+ sai->is_multi_lane = true;
+
+ /*dataline mask for rx and tx*/
+ ret = fsl_sai_read_dlcfg(pdev, "fsl,dataline", &sai->pcm_dl_cfg,
+ sai->soc->dataline);
+ if (ret < 0)
+ return ret;
+
+ sai->pcm_dl_cfg_cnt = ret;
+
+ ret = fsl_sai_read_dlcfg(pdev, "fsl,dataline,dsd", &sai->dsd_dl_cfg,
+ sai->soc->dataline);
+ if (ret < 0)
+ return ret;
+
+ sai->dsd_dl_cfg_cnt = ret;
+
+ if ((of_find_property(np, "fsl,i2s-xtor", NULL) != NULL) ||
+ (of_find_property(np, "fsl,txm-rxs", NULL) != NULL))
+ {
+ sai->masterflag[FSL_FMT_TRANSMITTER] = SND_SOC_DAIFMT_CBS_CFS;
+ sai->masterflag[FSL_FMT_RECEIVER] = SND_SOC_DAIFMT_CBM_CFM;
+ } else {
+ if (!of_property_read_u32(np, "fsl,txmasterflag",
+ &sai->masterflag[FSL_FMT_TRANSMITTER]))
+ sai->masterflag[FSL_FMT_TRANSMITTER] <<= 12;
+ if (!of_property_read_u32(np, "fsl,rxmasterflag",
+ &sai->masterflag[FSL_FMT_RECEIVER]))
+ sai->masterflag[FSL_FMT_RECEIVER] <<= 12;
+ }
+
irq = platform_get_irq(pdev, 0);
if (irq < 0) {
dev_err(&pdev->dev, "no irq for node %s\n", pdev->name);
return irq;
}
- ret = devm_request_irq(&pdev->dev, irq, fsl_sai_isr, 0, np->name, sai);
+ /* SAI shared interrupt */
+ if (of_property_read_bool(np, "fsl,shared-interrupt"))
+ irqflags = IRQF_SHARED;
+
+ ret = devm_request_irq(&pdev->dev, irq, fsl_sai_isr, irqflags, np->name,
+ sai);
if (ret) {
dev_err(&pdev->dev, "failed to claim irq %u\n", irq);
return ret;
@@ -900,59 +1505,120 @@ static int fsl_sai_probe(struct platform_device *pdev)
MCLK_DIR(index));
}
- sai->dma_params_rx.addr = res->start + FSL_SAI_RDR;
- sai->dma_params_tx.addr = res->start + FSL_SAI_TDR;
+ sai->dma_params_rx.chan_name = "rx";
+ sai->dma_params_tx.chan_name = "tx";
+ sai->dma_params_rx.addr = res->start + FSL_SAI_RDR0;
+ sai->dma_params_tx.addr = res->start + FSL_SAI_TDR0;
sai->dma_params_rx.maxburst = FSL_SAI_MAXBURST_RX;
sai->dma_params_tx.maxburst = FSL_SAI_MAXBURST_TX;
+ sai->pinctrl = devm_pinctrl_get(&pdev->dev);
+
platform_set_drvdata(pdev, sai);
+ pm_runtime_enable(&pdev->dev);
+
+ regcache_cache_only(sai->regmap, true);
+
ret = devm_snd_soc_register_component(&pdev->dev, &fsl_component,
&fsl_sai_dai, 1);
if (ret)
return ret;
- if (sai->sai_on_imx)
- return imx_pcm_dma_init(pdev, IMX_SAI_DMABUF_SIZE);
+ if (of_property_read_u32(np, "fsl,dma-buffer-size", &buffer_size))
+ buffer_size = IMX_SAI_DMABUF_SIZE;
+
+ if (sai->soc->imx)
+ return imx_pcm_platform_register(&pdev->dev);
else
return devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0);
}
-static const struct of_device_id fsl_sai_ids[] = {
- { .compatible = "fsl,vf610-sai", },
- { .compatible = "fsl,imx6sx-sai", },
- { .compatible = "fsl,imx6ul-sai", },
- { /* sentinel */ }
-};
-MODULE_DEVICE_TABLE(of, fsl_sai_ids);
-
-#ifdef CONFIG_PM_SLEEP
-static int fsl_sai_suspend(struct device *dev)
+#ifdef CONFIG_PM
+static int fsl_sai_runtime_resume(struct device *dev)
{
struct fsl_sai *sai = dev_get_drvdata(dev);
+ unsigned char offset = sai->soc->reg_offset;
+ int ret;
- regcache_cache_only(sai->regmap, true);
+ ret = clk_prepare_enable(sai->bus_clk);
+ if (ret) {
+ dev_err(dev, "failed to enable bus clock: %d\n", ret);
+ return ret;
+ }
+
+ if (sai->mclk_streams & BIT(SNDRV_PCM_STREAM_PLAYBACK)) {
+ ret = clk_prepare_enable(sai->mclk_clk[sai->mclk_id[1]]);
+ if (ret)
+ goto disable_bus_clk;
+ }
+
+ if (sai->mclk_streams & BIT(SNDRV_PCM_STREAM_CAPTURE)) {
+ ret = clk_prepare_enable(sai->mclk_clk[sai->mclk_id[0]]);
+ if (ret)
+ goto disable_tx_clk;
+ }
+
+ request_bus_freq(BUS_FREQ_AUDIO);
+
+ if (sai->soc->flags & SAI_FLAG_PMQOS)
+ pm_qos_add_request(&sai->pm_qos_req,
+ PM_QOS_CPU_DMA_LATENCY, 0);
+
+ regcache_cache_only(sai->regmap, false);
regcache_mark_dirty(sai->regmap);
+ regmap_write(sai->regmap, FSL_SAI_TCSR(offset), FSL_SAI_CSR_SR);
+ regmap_write(sai->regmap, FSL_SAI_RCSR(offset), FSL_SAI_CSR_SR);
+ usleep_range(1000, 2000);
+ regmap_write(sai->regmap, FSL_SAI_TCSR(offset), 0);
+ regmap_write(sai->regmap, FSL_SAI_RCSR(offset), 0);
+ ret = regcache_sync(sai->regmap);
+ if (ret)
+ goto disable_rx_clk;
+
return 0;
+
+disable_rx_clk:
+ if (sai->mclk_streams & BIT(SNDRV_PCM_STREAM_CAPTURE))
+ clk_disable_unprepare(sai->mclk_clk[sai->mclk_id[0]]);
+disable_tx_clk:
+ if (sai->mclk_streams & BIT(SNDRV_PCM_STREAM_PLAYBACK))
+ clk_disable_unprepare(sai->mclk_clk[sai->mclk_id[1]]);
+disable_bus_clk:
+ clk_disable_unprepare(sai->bus_clk);
+
+ return ret;
}
-static int fsl_sai_resume(struct device *dev)
+static int fsl_sai_runtime_suspend(struct device *dev)
{
struct fsl_sai *sai = dev_get_drvdata(dev);
- regcache_cache_only(sai->regmap, false);
- regmap_write(sai->regmap, FSL_SAI_TCSR, FSL_SAI_CSR_SR);
- regmap_write(sai->regmap, FSL_SAI_RCSR, FSL_SAI_CSR_SR);
- usleep_range(1000, 2000);
- regmap_write(sai->regmap, FSL_SAI_TCSR, 0);
- regmap_write(sai->regmap, FSL_SAI_RCSR, 0);
- return regcache_sync(sai->regmap);
+ regcache_cache_only(sai->regmap, true);
+
+ release_bus_freq(BUS_FREQ_AUDIO);
+
+ if (sai->soc->flags & SAI_FLAG_PMQOS)
+ pm_qos_remove_request(&sai->pm_qos_req);
+
+ if (sai->mclk_streams & BIT(SNDRV_PCM_STREAM_CAPTURE))
+ clk_disable_unprepare(sai->mclk_clk[sai->mclk_id[0]]);
+
+ if (sai->mclk_streams & BIT(SNDRV_PCM_STREAM_PLAYBACK))
+ clk_disable_unprepare(sai->mclk_clk[sai->mclk_id[1]]);
+
+ clk_disable_unprepare(sai->bus_clk);
+
+ return 0;
}
-#endif /* CONFIG_PM_SLEEP */
+#endif
static const struct dev_pm_ops fsl_sai_pm_ops = {
- SET_SYSTEM_SLEEP_PM_OPS(fsl_sai_suspend, fsl_sai_resume)
+ SET_RUNTIME_PM_OPS(fsl_sai_runtime_suspend,
+ fsl_sai_runtime_resume,
+ NULL)
+ SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, pm_runtime_force_resume)
};
static struct platform_driver fsl_sai_driver = {
diff --git a/sound/soc/fsl/fsl_sai.h b/sound/soc/fsl/fsl_sai.h
index d9ed7be8cb34..a3a11907ba0a 100644
--- a/sound/soc/fsl/fsl_sai.h
+++ b/sound/soc/fsl/fsl_sai.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2012-2013 Freescale Semiconductor, Inc.
+ * Copyright 2012-2016 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
@@ -9,45 +9,91 @@
#ifndef __FSL_SAI_H
#define __FSL_SAI_H
+#include <linux/pm_qos.h>
#include <sound/dmaengine_pcm.h>
#define FSL_SAI_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
- SNDRV_PCM_FMTBIT_S20_3LE |\
SNDRV_PCM_FMTBIT_S24_LE |\
- SNDRV_PCM_FMTBIT_S32_LE)
+ SNDRV_PCM_FMTBIT_S32_LE |\
+ SNDRV_PCM_FMTBIT_DSD_U8 |\
+ SNDRV_PCM_FMTBIT_DSD_U16_LE |\
+ SNDRV_PCM_FMTBIT_DSD_U32_LE)
/* SAI Register Map Register */
-#define FSL_SAI_TCSR 0x00 /* SAI Transmit Control */
-#define FSL_SAI_TCR1 0x04 /* SAI Transmit Configuration 1 */
-#define FSL_SAI_TCR2 0x08 /* SAI Transmit Configuration 2 */
-#define FSL_SAI_TCR3 0x0c /* SAI Transmit Configuration 3 */
-#define FSL_SAI_TCR4 0x10 /* SAI Transmit Configuration 4 */
-#define FSL_SAI_TCR5 0x14 /* SAI Transmit Configuration 5 */
-#define FSL_SAI_TDR 0x20 /* SAI Transmit Data */
-#define FSL_SAI_TFR 0x40 /* SAI Transmit FIFO */
+#define FSL_SAI_VERID 0x00 /* SAI Version ID Register */
+#define FSL_SAI_PARAM 0x04 /* SAI Parameter Register */
+#define FSL_SAI_TCSR(offset) (0x00 + offset) /* SAI Transmit Control */
+#define FSL_SAI_TCR1(offset) (0x04 + offset) /* SAI Transmit Configuration 1 */
+#define FSL_SAI_TCR2(offset) (0x08 + offset) /* SAI Transmit Configuration 2 */
+#define FSL_SAI_TCR3(offset) (0x0c + offset) /* SAI Transmit Configuration 3 */
+#define FSL_SAI_TCR4(offset) (0x10 + offset) /* SAI Transmit Configuration 4 */
+#define FSL_SAI_TCR5(offset) (0x14 + offset) /* SAI Transmit Configuration 5 */
+#define FSL_SAI_TDR0 0x20 /* SAI Transmit Data */
+#define FSL_SAI_TDR1 0x24 /* SAI Transmit Data */
+#define FSL_SAI_TDR2 0x28 /* SAI Transmit Data */
+#define FSL_SAI_TDR3 0x2C /* SAI Transmit Data */
+#define FSL_SAI_TDR4 0x30 /* SAI Transmit Data */
+#define FSL_SAI_TDR5 0x34 /* SAI Transmit Data */
+#define FSL_SAI_TDR6 0x38 /* SAI Transmit Data */
+#define FSL_SAI_TDR7 0x3C /* SAI Transmit Data */
+#define FSL_SAI_TFR0 0x40 /* SAI Transmit FIFO */
+#define FSL_SAI_TFR1 0x44 /* SAI Transmit FIFO */
+#define FSL_SAI_TFR2 0x48 /* SAI Transmit FIFO */
+#define FSL_SAI_TFR3 0x4C /* SAI Transmit FIFO */
+#define FSL_SAI_TFR4 0x50 /* SAI Transmit FIFO */
+#define FSL_SAI_TFR5 0x54 /* SAI Transmit FIFO */
+#define FSL_SAI_TFR6 0x58 /* SAI Transmit FIFO */
+#define FSL_SAI_TFR7 0x5C /* SAI Transmit FIFO */
#define FSL_SAI_TMR 0x60 /* SAI Transmit Mask */
-#define FSL_SAI_RCSR 0x80 /* SAI Receive Control */
-#define FSL_SAI_RCR1 0x84 /* SAI Receive Configuration 1 */
-#define FSL_SAI_RCR2 0x88 /* SAI Receive Configuration 2 */
-#define FSL_SAI_RCR3 0x8c /* SAI Receive Configuration 3 */
-#define FSL_SAI_RCR4 0x90 /* SAI Receive Configuration 4 */
-#define FSL_SAI_RCR5 0x94 /* SAI Receive Configuration 5 */
-#define FSL_SAI_RDR 0xa0 /* SAI Receive Data */
-#define FSL_SAI_RFR 0xc0 /* SAI Receive FIFO */
+#define FSL_SAI_TTCTL 0x70 /* SAI Transmit Timestamp Control Register */
+#define FSL_SAI_TTCTN 0x74 /* SAI Transmit Timestamp Counter Register */
+#define FSL_SAI_TBCTN 0x78 /* SAI Transmit Bit Counter Register */
+#define FSL_SAI_TTCAP 0x7C /* SAI Transmit Timestamp Capture */
+
+#define FSL_SAI_RCSR(offset) (0x80 + offset) /* SAI Receive Control */
+#define FSL_SAI_RCR1(offset) (0x84 + offset) /* SAI Receive Configuration 1 */
+#define FSL_SAI_RCR2(offset) (0x88 + offset) /* SAI Receive Configuration 2 */
+#define FSL_SAI_RCR3(offset) (0x8c + offset) /* SAI Receive Configuration 3 */
+#define FSL_SAI_RCR4(offset) (0x90 + offset) /* SAI Receive Configuration 4 */
+#define FSL_SAI_RCR5(offset) (0x94 + offset) /* SAI Receive Configuration 5 */
+#define FSL_SAI_RDR0 0xa0 /* SAI Receive Data */
+#define FSL_SAI_RDR1 0xa4 /* SAI Receive Data */
+#define FSL_SAI_RDR2 0xa8 /* SAI Receive Data */
+#define FSL_SAI_RDR3 0xac /* SAI Receive Data */
+#define FSL_SAI_RDR4 0xb0 /* SAI Receive Data */
+#define FSL_SAI_RDR5 0xb4 /* SAI Receive Data */
+#define FSL_SAI_RDR6 0xb8 /* SAI Receive Data */
+#define FSL_SAI_RDR7 0xbc /* SAI Receive Data */
+#define FSL_SAI_RFR0 0xc0 /* SAI Receive FIFO */
+#define FSL_SAI_RFR1 0xc4 /* SAI Receive FIFO */
+#define FSL_SAI_RFR2 0xc8 /* SAI Receive FIFO */
+#define FSL_SAI_RFR3 0xcc /* SAI Receive FIFO */
+#define FSL_SAI_RFR4 0xd0 /* SAI Receive FIFO */
+#define FSL_SAI_RFR5 0xd4 /* SAI Receive FIFO */
+#define FSL_SAI_RFR6 0xd8 /* SAI Receive FIFO */
+#define FSL_SAI_RFR7 0xdc /* SAI Receive FIFO */
#define FSL_SAI_RMR 0xe0 /* SAI Receive Mask */
+#define FSL_SAI_RTCTL 0xf0 /* SAI Receive Timestamp Control Register */
+#define FSL_SAI_RTCTN 0xf4 /* SAI Receive Timestamp Counter Register */
+#define FSL_SAI_RBCTN 0xf8 /* SAI Receive Bit Counter Register */
+#define FSL_SAI_RTCAP 0xfc /* SAI Receive Timestamp Capture */
+
+#define FSL_SAI_MCTL 0x100 /* SAI MCLK Control Register */
+#define FSL_SAI_MDIV 0x104 /* SAI MCLK Divide Register */
-#define FSL_SAI_xCSR(tx) (tx ? FSL_SAI_TCSR : FSL_SAI_RCSR)
-#define FSL_SAI_xCR1(tx) (tx ? FSL_SAI_TCR1 : FSL_SAI_RCR1)
-#define FSL_SAI_xCR2(tx) (tx ? FSL_SAI_TCR2 : FSL_SAI_RCR2)
-#define FSL_SAI_xCR3(tx) (tx ? FSL_SAI_TCR3 : FSL_SAI_RCR3)
-#define FSL_SAI_xCR4(tx) (tx ? FSL_SAI_TCR4 : FSL_SAI_RCR4)
-#define FSL_SAI_xCR5(tx) (tx ? FSL_SAI_TCR5 : FSL_SAI_RCR5)
+#define FSL_SAI_xCSR(tx, off) (tx ? FSL_SAI_TCSR(off) : FSL_SAI_RCSR(off))
+#define FSL_SAI_xCR1(tx, off) (tx ? FSL_SAI_TCR1(off) : FSL_SAI_RCR1(off))
+#define FSL_SAI_xCR2(tx, off) (tx ? FSL_SAI_TCR2(off) : FSL_SAI_RCR2(off))
+#define FSL_SAI_xCR3(tx, off) (tx ? FSL_SAI_TCR3(off) : FSL_SAI_RCR3(off))
+#define FSL_SAI_xCR4(tx, off) (tx ? FSL_SAI_TCR4(off) : FSL_SAI_RCR4(off))
+#define FSL_SAI_xCR5(tx, off) (tx ? FSL_SAI_TCR5(off) : FSL_SAI_RCR5(off))
#define FSL_SAI_xDR(tx) (tx ? FSL_SAI_TDR : FSL_SAI_RDR)
#define FSL_SAI_xFR(tx) (tx ? FSL_SAI_TFR : FSL_SAI_RFR)
#define FSL_SAI_xMR(tx) (tx ? FSL_SAI_TMR : FSL_SAI_RMR)
/* SAI Transmit/Receive Control Register */
#define FSL_SAI_CSR_TERE BIT(31)
+#define FSL_SAI_CSR_SE BIT(30)
#define FSL_SAI_CSR_FR BIT(25)
#define FSL_SAI_CSR_SR BIT(24)
#define FSL_SAI_CSR_xF_SHIFT 16
@@ -81,18 +127,29 @@
#define FSL_SAI_CR2_MSEL(ID) ((ID) << 26)
#define FSL_SAI_CR2_BCP BIT(25)
#define FSL_SAI_CR2_BCD_MSTR BIT(24)
+#define FSL_SAI_CR2_BYP BIT(23) /* BCLK bypass */
#define FSL_SAI_CR2_DIV_MASK 0xff
/* SAI Transmit and Receive Configuration 3 Register */
-#define FSL_SAI_CR3_TRCE BIT(16)
+#define FSL_SAI_CR3_TRCE_MASK (0xff << 16)
+#define FSL_SAI_CR3_TRCE(x) (x << 16)
#define FSL_SAI_CR3_WDFL(x) (x)
#define FSL_SAI_CR3_WDFL_MASK 0x1f
/* SAI Transmit and Receive Configuration 4 Register */
+
+#define FSL_SAI_CR4_FCONT BIT(28)
+#define FSL_SAI_CR4_FCOMB_SHIFT BIT(26)
+#define FSL_SAI_CR4_FCOMB_SOFT BIT(27)
+#define FSL_SAI_CR4_FCOMB_MASK (0x3 << 26)
+#define FSL_SAI_CR4_FPACK_8 (0x2 << 24)
+#define FSL_SAI_CR4_FPACK_16 (0x3 << 24)
#define FSL_SAI_CR4_FRSZ(x) (((x) - 1) << 16)
#define FSL_SAI_CR4_FRSZ_MASK (0x1f << 16)
#define FSL_SAI_CR4_SYWD(x) (((x) - 1) << 8)
#define FSL_SAI_CR4_SYWD_MASK (0x1f << 8)
+#define FSL_SAI_CR4_CHMOD (1 << 5)
+#define FSL_SAI_CR4_CHMOD_MASK (1 << 5)
#define FSL_SAI_CR4_MF BIT(4)
#define FSL_SAI_CR4_FSE BIT(3)
#define FSL_SAI_CR4_FSP BIT(1)
@@ -106,6 +163,33 @@
#define FSL_SAI_CR5_FBT(x) ((x) << 8)
#define FSL_SAI_CR5_FBT_MASK (0x1f << 8)
+/* SAI MCLK Control Register */
+#define FSL_SAI_MCTL_MCLK_EN BIT(30) /* MCLK Enable */
+#define FSL_SAI_MCTL_MSEL_MASK (0x3 << 24)
+#define FSL_SAI_MCTL_MSEL(ID) ((ID) << 24)
+#define FSL_SAI_MCTL_MSEL_BUS 0
+#define FSL_SAI_MCTL_MSEL_MCLK1 BIT(24)
+#define FSL_SAI_MCTL_MSEL_MCLK2 BIT(25)
+#define FSL_SAI_MCTL_MSEL_MCLK3 (BIT(24) | BIT(25))
+#define FSL_SAI_MCTL_DIV_EN BIT(23)
+#define FSL_SAI_MCTL_DIV_MASK 0xFF
+
+/* SAI VERID Register */
+#define FSL_SAI_VER_ID_SHIFT 16
+#define FSL_SAI_VER_ID_MASK (0xFFFF << FSL_SAI_VER_ID_SHIFT)
+#define FSL_SAI_VER_EFIFO_EN BIT(0)
+#define FSL_SAI_VER_TSTMP_EN BIT(1)
+
+/* SAI PARAM Register */
+#define FSL_SAI_PAR_SPF_SHIFT 16
+#define FSL_SAI_PAR_SPF_MASK (0x0F << FSL_SAI_PAR_SPF_SHIFT)
+#define FSL_SAI_PAR_WPF_SHIFT 8
+#define FSL_SAI_PAR_WPF_MASK (0x0F << FSL_SAI_PAR_WPF_SHIFT)
+#define FSL_SAI_PAR_DLN_MASK (0x0F)
+
+/* SAI MCLK Divide Register */
+#define FSL_SAI_MDIV_MASK 0xFFFFF
+
/* SAI type */
#define FSL_SAI_DMA BIT(0)
#define FSL_SAI_USE_AC97 BIT(1)
@@ -129,25 +213,76 @@
#define FSL_SAI_MAXBURST_TX 6
#define FSL_SAI_MAXBURST_RX 6
+#define SAI_FLAG_PMQOS BIT(0)
+
+struct fsl_sai_soc_data {
+ unsigned int fifo_depth;
+ unsigned int fifos;
+ unsigned int dataline;
+ unsigned int flags;
+ unsigned char reg_offset;
+ bool imx;
+ /* True for EDMA because it needs period size multiple of maxburst */
+ bool constrain_period_size;
+};
+
+struct fsl_sai_verid {
+ u32 id;
+ bool timestamp_en;
+ bool extfifo_en;
+ bool loaded;
+};
+
+struct fsl_sai_param {
+ u32 spf; /* max slots per frame */
+ u32 wpf; /* words in fifo */
+ u32 dln; /* number of datalines implemented */
+};
+
+struct fsl_sai_dl_cfg {
+ unsigned int pins;
+ unsigned int mask[2];
+ unsigned int offset[2];
+};
+
struct fsl_sai {
struct platform_device *pdev;
struct regmap *regmap;
struct clk *bus_clk;
struct clk *mclk_clk[FSL_SAI_MCLK_MAX];
+ struct clk *pll8k_clk;
+ struct clk *pll11k_clk;
- bool is_slave_mode;
+ bool slave_mode[2];
bool is_lsb_first;
bool is_dsp_mode;
- bool sai_on_imx;
+ bool is_multi_lane;
bool synchronous[2];
+ bool is_stream_opened[2];
+ bool is_dsd;
+
+ int pcm_dl_cfg_cnt;
+ int dsd_dl_cfg_cnt;
+ struct fsl_sai_dl_cfg *pcm_dl_cfg;
+ struct fsl_sai_dl_cfg *dsd_dl_cfg;
+
+ unsigned int masterflag[2];
unsigned int mclk_id[2];
unsigned int mclk_streams;
unsigned int slots;
unsigned int slot_width;
+ unsigned int bitclk_ratio;
struct snd_dmaengine_dai_dma_data dma_params_rx;
struct snd_dmaengine_dai_dma_data dma_params_tx;
+ const struct fsl_sai_soc_data *soc;
+ struct pm_qos_request pm_qos_req;
+ struct pinctrl *pinctrl;
+ struct pinctrl_state *pins_state;
+
+ struct fsl_sai_verid verid;
+ struct fsl_sai_param param;
};
#define TX 1
diff --git a/sound/soc/fsl/fsl_spdif.c b/sound/soc/fsl/fsl_spdif.c
index 7e6cc4da0088..3ab5c7fc286c 100644
--- a/sound/soc/fsl/fsl_spdif.c
+++ b/sound/soc/fsl/fsl_spdif.c
@@ -1,7 +1,7 @@
/*
* Freescale S/PDIF ALSA SoC Digital Audio Interface (DAI) driver
*
- * Copyright (C) 2013 Freescale Semiconductor, Inc.
+ * Copyright (C) 2013-2016 Freescale Semiconductor, Inc.
*
* Based on stmp3xxx_spdif_dai.c
* Vladimir Barinov <vbarinov@embeddedalley.com>
@@ -15,11 +15,14 @@
#include <linux/bitrev.h>
#include <linux/clk.h>
+#include <linux/clk-provider.h>
#include <linux/module.h>
#include <linux/of_address.h>
#include <linux/of_device.h>
#include <linux/of_irq.h>
#include <linux/regmap.h>
+#include <linux/pm_runtime.h>
+#include <linux/busfreq-imx.h>
#include <sound/asoundef.h>
#include <sound/dmaengine_pcm.h>
@@ -27,6 +30,7 @@
#include "fsl_spdif.h"
#include "imx-pcm.h"
+#include "fsl_dma_workaround.h"
#define FSL_SPDIF_TXFIFO_WML 0x8
#define FSL_SPDIF_RXFIFO_WML 0x8
@@ -46,6 +50,17 @@ static u8 srpc_dpll_locked[] = { 0x0, 0x1, 0x2, 0x3, 0x4, 0xa, 0xb };
#define DEFAULT_RXCLK_SRC 1
+struct fsl_spdif_soc_data {
+ bool imx;
+ bool constrain_period_size;
+ bool dma_workaround;
+ u32 tx_burst;
+ u32 rx_burst;
+ u32 interrupts;
+ u64 tx_formats;
+ u64 rx_rates;
+};
+
/*
* SPDIF control structure
* Defines channel status, subcode and Q sub
@@ -100,18 +115,82 @@ struct fsl_spdif_priv {
bool dpll_locked;
u32 txrate[SPDIF_TXRATE_MAX];
u8 txclk_df[SPDIF_TXRATE_MAX];
- u8 sysclk_df[SPDIF_TXRATE_MAX];
+ u16 sysclk_df[SPDIF_TXRATE_MAX];
u8 txclk_src[SPDIF_TXRATE_MAX];
u8 rxclk_src;
- struct clk *txclk[SPDIF_TXRATE_MAX];
+ struct clk *txclk[STC_TXCLK_SRC_MAX];
struct clk *rxclk;
struct clk *coreclk;
struct clk *sysclk;
struct clk *spbaclk;
+ const struct fsl_spdif_soc_data *soc;
+ struct fsl_dma_workaround_info *dma_info;
struct snd_dmaengine_dai_dma_data dma_params_tx;
struct snd_dmaengine_dai_dma_data dma_params_rx;
/* regcache for SRPC */
u32 regcache_srpc;
+ struct clk *pll8k_clk;
+ struct clk *pll11k_clk;
+};
+
+static struct fsl_spdif_soc_data fsl_spdif_vf610 = {
+ .imx = false,
+ .dma_workaround = false,
+ .tx_burst = FSL_SPDIF_TXFIFO_WML,
+ .rx_burst = FSL_SPDIF_RXFIFO_WML,
+ .interrupts = 1,
+ .tx_formats = FSL_SPDIF_FORMATS_PLAYBACK,
+ .rx_rates = FSL_SPDIF_RATES_CAPTURE,
+ .constrain_period_size = false,
+};
+
+static struct fsl_spdif_soc_data fsl_spdif_imx35 = {
+ .imx = true,
+ .dma_workaround = false,
+ .tx_burst = FSL_SPDIF_TXFIFO_WML,
+ .rx_burst = FSL_SPDIF_RXFIFO_WML,
+ .interrupts = 1,
+ .tx_formats = FSL_SPDIF_FORMATS_PLAYBACK,
+ .rx_rates = FSL_SPDIF_RATES_CAPTURE,
+ .constrain_period_size = false,
+};
+
+/*
+ * In imx8qxp rev 1, the DMA request signal is not reverted. For SPDIF
+ * DMA request is low valid, but EDMA assert is high valid, so we
+ * need to use GPT to transfer the DMA request signal
+ */
+static struct fsl_spdif_soc_data fsl_spdif_imx8qxp_v1 = {
+ .imx = true,
+ .dma_workaround = true,
+ .tx_burst = 2,
+ .rx_burst = 2,
+ .interrupts = 2,
+ .tx_formats = SNDRV_PCM_FMTBIT_S24_LE,
+ .rx_rates = FSL_SPDIF_RATES_CAPTURE,
+ .constrain_period_size = true,
+};
+
+static struct fsl_spdif_soc_data fsl_spdif_imx8qm = {
+ .imx = true,
+ .dma_workaround = false,
+ .tx_burst = 2,
+ .rx_burst = 2,
+ .interrupts = 2,
+ .tx_formats = SNDRV_PCM_FMTBIT_S24_LE,
+ .rx_rates = (FSL_SPDIF_RATES_CAPTURE | SNDRV_PCM_RATE_192000),
+ .constrain_period_size = true,
+};
+
+static struct fsl_spdif_soc_data fsl_spdif_imx8mm = {
+ .imx = true,
+ .dma_workaround = false,
+ .tx_burst = FSL_SPDIF_TXFIFO_WML,
+ .rx_burst = FSL_SPDIF_RXFIFO_WML,
+ .interrupts = 1,
+ .tx_formats = FSL_SPDIF_FORMATS_PLAYBACK,
+ .rx_rates = (FSL_SPDIF_RATES_CAPTURE | SNDRV_PCM_RATE_192000),
+ .constrain_period_size = false,
};
/* DPLL locked and lock loss interrupt handler */
@@ -380,8 +459,8 @@ static int spdif_set_sample_rate(struct snd_pcm_substream *substream,
struct platform_device *pdev = spdif_priv->pdev;
unsigned long csfs = 0;
u32 stc, mask, rate;
- u8 clk, txclk_df, sysclk_df;
- int ret;
+ u8 clk, txclk_df;
+ u16 sysclk_df;
switch (sample_rate) {
case 32000:
@@ -423,23 +502,10 @@ static int spdif_set_sample_rate(struct snd_pcm_substream *substream,
sysclk_df = spdif_priv->sysclk_df[rate];
- /* Don't mess up the clocks from other modules */
- if (clk != STC_TXCLK_SPDIF_ROOT)
- goto clk_set_bypass;
-
- /* The S/PDIF block needs a clock of 64 * fs * txclk_df */
- ret = clk_set_rate(spdif_priv->txclk[rate],
- 64 * sample_rate * txclk_df);
- if (ret) {
- dev_err(&pdev->dev, "failed to set tx clock rate\n");
- return ret;
- }
-
-clk_set_bypass:
dev_dbg(&pdev->dev, "expected clock rate = %d\n",
(64 * sample_rate * txclk_df * sysclk_df));
dev_dbg(&pdev->dev, "actual clock rate = %ld\n",
- clk_get_rate(spdif_priv->txclk[rate]));
+ clk_get_rate(spdif_priv->txclk[clk]));
/* set fs field in consumer channel status */
spdif_set_cstatus(ctrl, IEC958_AES3_CON_FS, csfs);
@@ -465,25 +531,10 @@ static int fsl_spdif_startup(struct snd_pcm_substream *substream,
struct platform_device *pdev = spdif_priv->pdev;
struct regmap *regmap = spdif_priv->regmap;
u32 scr, mask;
- int i;
int ret;
/* Reset module and interrupts only for first initialization */
if (!cpu_dai->active) {
- ret = clk_prepare_enable(spdif_priv->coreclk);
- if (ret) {
- dev_err(&pdev->dev, "failed to enable core clock\n");
- return ret;
- }
-
- if (!IS_ERR(spdif_priv->spbaclk)) {
- ret = clk_prepare_enable(spdif_priv->spbaclk);
- if (ret) {
- dev_err(&pdev->dev, "failed to enable spba clock\n");
- goto err_spbaclk;
- }
- }
-
ret = spdif_softreset(spdif_priv);
if (ret) {
dev_err(&pdev->dev, "failed to soft reset\n");
@@ -501,35 +552,30 @@ static int fsl_spdif_startup(struct snd_pcm_substream *substream,
mask = SCR_TXFIFO_AUTOSYNC_MASK | SCR_TXFIFO_CTRL_MASK |
SCR_TXSEL_MASK | SCR_USRC_SEL_MASK |
SCR_TXFIFO_FSEL_MASK;
- for (i = 0; i < SPDIF_TXRATE_MAX; i++) {
- ret = clk_prepare_enable(spdif_priv->txclk[i]);
- if (ret)
- goto disable_txclk;
- }
} else {
scr = SCR_RXFIFO_FSEL_IF8 | SCR_RXFIFO_AUTOSYNC;
mask = SCR_RXFIFO_FSEL_MASK | SCR_RXFIFO_AUTOSYNC_MASK|
SCR_RXFIFO_CTL_MASK | SCR_RXFIFO_OFF_MASK;
- ret = clk_prepare_enable(spdif_priv->rxclk);
- if (ret)
- goto err;
}
regmap_update_bits(regmap, REG_SPDIF_SCR, mask, scr);
/* Power up SPDIF module */
regmap_update_bits(regmap, REG_SPDIF_SCR, SCR_LOW_POWER, 0);
+ if (spdif_priv->soc->constrain_period_size) {
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ snd_pcm_hw_constraint_step(substream->runtime, 0,
+ SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
+ spdif_priv->dma_params_tx.maxburst);
+ else
+ snd_pcm_hw_constraint_step(substream->runtime, 0,
+ SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
+ spdif_priv->dma_params_rx.maxburst);
+ }
+
return 0;
-disable_txclk:
- for (i--; i >= 0; i--)
- clk_disable_unprepare(spdif_priv->txclk[i]);
err:
- if (!IS_ERR(spdif_priv->spbaclk))
- clk_disable_unprepare(spdif_priv->spbaclk);
-err_spbaclk:
- clk_disable_unprepare(spdif_priv->coreclk);
-
return ret;
}
@@ -539,20 +585,17 @@ static void fsl_spdif_shutdown(struct snd_pcm_substream *substream,
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct fsl_spdif_priv *spdif_priv = snd_soc_dai_get_drvdata(rtd->cpu_dai);
struct regmap *regmap = spdif_priv->regmap;
- u32 scr, mask, i;
+ u32 scr, mask;
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
scr = 0;
mask = SCR_TXFIFO_AUTOSYNC_MASK | SCR_TXFIFO_CTRL_MASK |
SCR_TXSEL_MASK | SCR_USRC_SEL_MASK |
SCR_TXFIFO_FSEL_MASK;
- for (i = 0; i < SPDIF_TXRATE_MAX; i++)
- clk_disable_unprepare(spdif_priv->txclk[i]);
} else {
scr = SCR_RXFIFO_OFF | SCR_RXFIFO_CTL_ZERO;
mask = SCR_RXFIFO_FSEL_MASK | SCR_RXFIFO_AUTOSYNC_MASK|
SCR_RXFIFO_CTL_MASK | SCR_RXFIFO_OFF_MASK;
- clk_disable_unprepare(spdif_priv->rxclk);
}
regmap_update_bits(regmap, REG_SPDIF_SCR, mask, scr);
@@ -561,10 +604,8 @@ static void fsl_spdif_shutdown(struct snd_pcm_substream *substream,
spdif_intr_status_clear(spdif_priv);
regmap_update_bits(regmap, REG_SPDIF_SCR,
SCR_LOW_POWER, SCR_LOW_POWER);
- if (!IS_ERR(spdif_priv->spbaclk))
- clk_disable_unprepare(spdif_priv->spbaclk);
- clk_disable_unprepare(spdif_priv->coreclk);
}
+
}
static int fsl_spdif_hw_params(struct snd_pcm_substream *substream,
@@ -578,6 +619,9 @@ static int fsl_spdif_hw_params(struct snd_pcm_substream *substream,
u32 sample_rate = params_rate(params);
int ret = 0;
+ if (spdif_priv->soc->dma_workaround)
+ configure_gpt_dma(substream, spdif_priv->dma_info);
+
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
ret = spdif_set_sample_rate(substream, sample_rate);
if (ret) {
@@ -626,14 +670,190 @@ static int fsl_spdif_trigger(struct snd_pcm_substream *substream,
return 0;
}
+static int fsl_spdif_hw_free(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct fsl_spdif_priv *spdif_priv = snd_soc_dai_get_drvdata(rtd->cpu_dai);
+
+ if (spdif_priv->soc->dma_workaround)
+ clear_gpt_dma(substream, spdif_priv->dma_info);
+
+ return 0;
+}
+
+static u32 fsl_spdif_txclk_caldiv(struct fsl_spdif_priv *spdif_priv,
+ struct clk *clk, u64 savesub,
+ enum spdif_txrate index, bool round)
+{
+ const u32 rate[] = { 32000, 44100, 48000, 96000, 192000 };
+ bool is_sysclk = clk_is_match(clk, spdif_priv->sysclk);
+ u64 rate_actual, sub;
+ u32 arate;
+ u16 sysclk_dfmin, sysclk_dfmax, sysclk_df;
+ u8 txclk_df;
+
+ /* The sysclk has an extra divisor [2, 512] */
+ sysclk_dfmin = is_sysclk ? 2 : 1;
+ sysclk_dfmax = is_sysclk ? 512 : 1;
+
+ for (sysclk_df = sysclk_dfmin; sysclk_df <= sysclk_dfmax; sysclk_df++) {
+ for (txclk_df = 1; txclk_df <= 128; txclk_df++) {
+ rate_actual = clk_get_rate(clk);
+
+ arate = rate_actual / 64;
+ arate /= txclk_df * sysclk_df;
+
+ if (arate == rate[index]) {
+ /* We are lucky */
+ savesub = 0;
+ spdif_priv->txclk_df[index] = txclk_df;
+ spdif_priv->sysclk_df[index] = sysclk_df;
+ spdif_priv->txrate[index] = arate;
+ goto out;
+ } else if (arate / rate[index] == 1) {
+ /* A little bigger than expect */
+ sub = (u64)(arate - rate[index]) * 100000;
+ do_div(sub, rate[index]);
+ if (sub >= savesub)
+ continue;
+ savesub = sub;
+ spdif_priv->txclk_df[index] = txclk_df;
+ spdif_priv->sysclk_df[index] = sysclk_df;
+ spdif_priv->txrate[index] = arate;
+ } else if (rate[index] / arate == 1) {
+ /* A little smaller than expect */
+ sub = (u64)(rate[index] - arate) * 100000;
+ do_div(sub, rate[index]);
+ if (sub >= savesub)
+ continue;
+ savesub = sub;
+ spdif_priv->txclk_df[index] = txclk_df;
+ spdif_priv->sysclk_df[index] = sysclk_df;
+ spdif_priv->txrate[index] = arate;
+ }
+ }
+ }
+
+out:
+ return savesub;
+}
+
+static int fsl_spdif_probe_txclk(struct fsl_spdif_priv *spdif_priv,
+ enum spdif_txrate index)
+{
+ const u32 rate[] = { 32000, 44100, 48000, 96000, 192000 };
+ struct platform_device *pdev = spdif_priv->pdev;
+ struct device *dev = &pdev->dev;
+ u64 savesub = 100000, ret;
+ struct clk *clk;
+ int i;
+
+ for (i = 0; i < STC_TXCLK_SRC_MAX; i++) {
+ clk = spdif_priv->txclk[i];
+ if (IS_ERR(clk)) {
+ dev_err(dev, "no rxtx%d clock in devicetree\n", i);
+ return PTR_ERR(clk);
+ }
+ if (!clk_get_rate(clk))
+ continue;
+
+ ret = fsl_spdif_txclk_caldiv(spdif_priv, clk, savesub, index,
+ i == STC_TXCLK_SPDIF_ROOT);
+ if (savesub == ret)
+ continue;
+
+ savesub = ret;
+ spdif_priv->txclk_src[index] = i;
+
+ /* To quick catch a divisor, we allow a 0.1% deviation */
+ if (savesub < 100)
+ break;
+ }
+
+ dev_dbg(&pdev->dev, "use rxtx%d as tx clock source for %dHz sample rate\n",
+ spdif_priv->txclk_src[index], rate[index]);
+ dev_dbg(&pdev->dev, "use txclk df %d for %dHz sample rate\n",
+ spdif_priv->txclk_df[index], rate[index]);
+ if (clk_is_match(spdif_priv->txclk[spdif_priv->txclk_src[index]], spdif_priv->sysclk))
+ dev_dbg(&pdev->dev, "use sysclk df %d for %dHz sample rate\n",
+ spdif_priv->sysclk_df[index], rate[index]);
+ dev_dbg(&pdev->dev, "the best rate for %dHz sample rate is %dHz\n",
+ rate[index], spdif_priv->txrate[index]);
+
+ return 0;
+}
+
+static int fsl_spdif_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
+ int clk_id, unsigned int freq, int dir)
+{
+ struct fsl_spdif_priv *data = snd_soc_dai_get_drvdata(cpu_dai);
+ struct platform_device *pdev = data->pdev;
+ struct device *dev = &pdev->dev;
+ struct clk *clk, *p, *pll = 0, *npll = 0;
+ u64 ratio = freq;
+ int ret, i;
+
+ if (dir != SND_SOC_CLOCK_OUT || freq == 0 || clk_id != STC_TXCLK_SPDIF_ROOT)
+ return 0;
+
+ if (data->pll8k_clk == NULL || data->pll11k_clk == NULL)
+ return 0;
+
+ clk = data->txclk[clk_id];
+ if (IS_ERR_OR_NULL(clk)) {
+ dev_err(dev, "no rxtx%d clock in devicetree\n", clk_id);
+ return PTR_ERR(clk);
+ }
+
+ p = clk;
+ while (p && data->pll8k_clk && data->pll11k_clk) {
+ struct clk *pp = clk_get_parent(p);
+
+ if (clk_is_match(pp, data->pll8k_clk) ||
+ clk_is_match(pp, data->pll11k_clk)) {
+ pll = pp;
+ break;
+ }
+ p = pp;
+ }
+
+ if (pll) {
+ npll = (do_div(ratio, 8000) ? data->pll11k_clk : data->pll8k_clk);
+ if (!clk_is_match(pll, npll)) {
+ ret = clk_set_parent(p, npll);
+ if (ret < 0)
+ dev_warn(cpu_dai->dev,
+ "failed to set parent %s: %d\n",
+ __clk_get_name(npll), ret);
+ }
+ }
+
+ ret = clk_set_rate(clk, freq);
+ if (ret < 0) {
+ dev_err(cpu_dai->dev, "failed to set clock rate (%u): %d\n",
+ freq, ret);
+ return ret;
+ }
+
+ for (i = 0; i < SPDIF_TXRATE_MAX; i++) {
+ ret = fsl_spdif_probe_txclk(data, i);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
static const struct snd_soc_dai_ops fsl_spdif_dai_ops = {
.startup = fsl_spdif_startup,
+ .set_sysclk = fsl_spdif_set_dai_sysclk,
.hw_params = fsl_spdif_hw_params,
.trigger = fsl_spdif_trigger,
.shutdown = fsl_spdif_shutdown,
+ .hw_free = fsl_spdif_hw_free,
};
-
/*
* FSL SPDIF IEC958 controller(mixer) functions
*
@@ -772,19 +992,23 @@ static int fsl_spdif_qget(struct snd_kcontrol *kcontrol,
}
/* Valid bit information */
-static int fsl_spdif_vbit_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
+/* Get valid good bit from interrupt status register */
+static int fsl_spdif_rx_vbit_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
+ struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kcontrol);
+ struct fsl_spdif_priv *spdif_priv = snd_soc_dai_get_drvdata(cpu_dai);
+ struct regmap *regmap = spdif_priv->regmap;
+ u32 val;
+
+ regmap_read(regmap, REG_SPDIF_SIS, &val);
+ ucontrol->value.integer.value[0] = (val & INT_VAL_NOGOOD) != 0;
+ regmap_write(regmap, REG_SPDIF_SIC, INT_VAL_NOGOOD);
return 0;
}
-/* Get valid good bit from interrupt status register */
-static int fsl_spdif_vbit_get(struct snd_kcontrol *kcontrol,
+static int fsl_spdif_tx_vbit_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kcontrol);
@@ -792,9 +1016,56 @@ static int fsl_spdif_vbit_get(struct snd_kcontrol *kcontrol,
struct regmap *regmap = spdif_priv->regmap;
u32 val;
- regmap_read(regmap, REG_SPDIF_SIS, &val);
- ucontrol->value.integer.value[0] = (val & INT_VAL_NOGOOD) != 0;
- regmap_write(regmap, REG_SPDIF_SIC, INT_VAL_NOGOOD);
+ regmap_read(regmap, REG_SPDIF_SCR, &val);
+ val = (val & SCR_VAL_MASK) >> SCR_VAL_OFFSET;
+ val = 1 - val;
+ ucontrol->value.integer.value[0] = val;
+
+ return 0;
+}
+
+static int fsl_spdif_tx_vbit_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kcontrol);
+ struct fsl_spdif_priv *spdif_priv = snd_soc_dai_get_drvdata(cpu_dai);
+ struct regmap *regmap = spdif_priv->regmap;
+ u32 val = (1 - ucontrol->value.integer.value[0]) << SCR_VAL_OFFSET;
+
+ regmap_update_bits(regmap, REG_SPDIF_SCR, SCR_VAL_MASK, val);
+
+ return 0;
+}
+
+static int fsl_spdif_rx_rcm_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kcontrol);
+ struct fsl_spdif_priv *spdif_priv = snd_soc_dai_get_drvdata(cpu_dai);
+ struct regmap *regmap = spdif_priv->regmap;
+ u32 val;
+
+ regmap_read(regmap, REG_SPDIF_SCR, &val);
+ val = (val & SCR_RAW_CAPTURE_MODE) ? 1 : 0;
+ ucontrol->value.integer.value[0] = val;
+
+ return 0;
+}
+
+static int fsl_spdif_rx_rcm_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kcontrol);
+ struct fsl_spdif_priv *spdif_priv = snd_soc_dai_get_drvdata(cpu_dai);
+ struct regmap *regmap = spdif_priv->regmap;
+ u32 val = (ucontrol->value.integer.value[0] ? SCR_RAW_CAPTURE_MODE : 0);
+
+ if (val)
+ cpu_dai->driver->capture.formats |= SNDRV_PCM_FMTBIT_S32_LE;
+ else
+ cpu_dai->driver->capture.formats &= ~SNDRV_PCM_FMTBIT_S32_LE;
+
+ regmap_update_bits(regmap, REG_SPDIF_SCR, SCR_RAW_CAPTURE_MODE, val);
return 0;
}
@@ -866,18 +1137,6 @@ static int fsl_spdif_rxrate_get(struct snd_kcontrol *kcontrol,
return 0;
}
-/* User bit sync mode info */
-static int fsl_spdif_usync_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
-
- return 0;
-}
-
/*
* User bit sync mode:
* 1 CD User channel subcode
@@ -956,11 +1215,21 @@ static struct snd_kcontrol_new fsl_spdif_ctrls[] = {
/* Valid bit error controller */
{
.iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = "IEC958 V-Bit Errors",
+ .name = "IEC958 Rx V-Bit Errors",
.access = SNDRV_CTL_ELEM_ACCESS_READ |
SNDRV_CTL_ELEM_ACCESS_VOLATILE,
- .info = fsl_spdif_vbit_info,
- .get = fsl_spdif_vbit_get,
+ .info = snd_ctl_boolean_mono_info,
+ .get = fsl_spdif_rx_vbit_get,
+ },
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_PCM,
+ .name = "IEC958 Tx V-Bit",
+ .access = SNDRV_CTL_ELEM_ACCESS_READ |
+ SNDRV_CTL_ELEM_ACCESS_WRITE |
+ SNDRV_CTL_ELEM_ACCESS_VOLATILE,
+ .info = snd_ctl_boolean_mono_info,
+ .get = fsl_spdif_tx_vbit_get,
+ .put = fsl_spdif_tx_vbit_put,
},
/* DPLL lock info get controller */
{
@@ -978,10 +1247,20 @@ static struct snd_kcontrol_new fsl_spdif_ctrls[] = {
.access = SNDRV_CTL_ELEM_ACCESS_READ |
SNDRV_CTL_ELEM_ACCESS_WRITE |
SNDRV_CTL_ELEM_ACCESS_VOLATILE,
- .info = fsl_spdif_usync_info,
+ .info = snd_ctl_boolean_mono_info,
.get = fsl_spdif_usync_get,
.put = fsl_spdif_usync_put,
},
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_PCM,
+ .name = "IEC958 Rx Raw Capture Mode Bit",
+ .access = SNDRV_CTL_ELEM_ACCESS_READ |
+ SNDRV_CTL_ELEM_ACCESS_WRITE |
+ SNDRV_CTL_ELEM_ACCESS_VOLATILE,
+ .info = snd_ctl_boolean_mono_info,
+ .get = fsl_spdif_rx_rcm_get,
+ .put = fsl_spdif_rx_rcm_put,
+ },
};
static int fsl_spdif_dai_probe(struct snd_soc_dai *dai)
@@ -1106,113 +1385,15 @@ static const struct regmap_config fsl_spdif_regmap_config = {
.cache_type = REGCACHE_FLAT,
};
-static u32 fsl_spdif_txclk_caldiv(struct fsl_spdif_priv *spdif_priv,
- struct clk *clk, u64 savesub,
- enum spdif_txrate index, bool round)
-{
- const u32 rate[] = { 32000, 44100, 48000, 96000, 192000 };
- bool is_sysclk = clk_is_match(clk, spdif_priv->sysclk);
- u64 rate_ideal, rate_actual, sub;
- u32 sysclk_dfmin, sysclk_dfmax;
- u32 txclk_df, sysclk_df, arate;
-
- /* The sysclk has an extra divisor [2, 512] */
- sysclk_dfmin = is_sysclk ? 2 : 1;
- sysclk_dfmax = is_sysclk ? 512 : 1;
-
- for (sysclk_df = sysclk_dfmin; sysclk_df <= sysclk_dfmax; sysclk_df++) {
- for (txclk_df = 1; txclk_df <= 128; txclk_df++) {
- rate_ideal = rate[index] * txclk_df * 64;
- if (round)
- rate_actual = clk_round_rate(clk, rate_ideal);
- else
- rate_actual = clk_get_rate(clk);
-
- arate = rate_actual / 64;
- arate /= txclk_df * sysclk_df;
-
- if (arate == rate[index]) {
- /* We are lucky */
- savesub = 0;
- spdif_priv->txclk_df[index] = txclk_df;
- spdif_priv->sysclk_df[index] = sysclk_df;
- spdif_priv->txrate[index] = arate;
- goto out;
- } else if (arate / rate[index] == 1) {
- /* A little bigger than expect */
- sub = (u64)(arate - rate[index]) * 100000;
- do_div(sub, rate[index]);
- if (sub >= savesub)
- continue;
- savesub = sub;
- spdif_priv->txclk_df[index] = txclk_df;
- spdif_priv->sysclk_df[index] = sysclk_df;
- spdif_priv->txrate[index] = arate;
- } else if (rate[index] / arate == 1) {
- /* A little smaller than expect */
- sub = (u64)(rate[index] - arate) * 100000;
- do_div(sub, rate[index]);
- if (sub >= savesub)
- continue;
- savesub = sub;
- spdif_priv->txclk_df[index] = txclk_df;
- spdif_priv->sysclk_df[index] = sysclk_df;
- spdif_priv->txrate[index] = arate;
- }
- }
- }
-
-out:
- return savesub;
-}
-
-static int fsl_spdif_probe_txclk(struct fsl_spdif_priv *spdif_priv,
- enum spdif_txrate index)
-{
- const u32 rate[] = { 32000, 44100, 48000, 96000, 192000 };
- struct platform_device *pdev = spdif_priv->pdev;
- struct device *dev = &pdev->dev;
- u64 savesub = 100000, ret;
- struct clk *clk;
- char tmp[16];
- int i;
-
- for (i = 0; i < STC_TXCLK_SRC_MAX; i++) {
- sprintf(tmp, "rxtx%d", i);
- clk = devm_clk_get(&pdev->dev, tmp);
- if (IS_ERR(clk)) {
- dev_err(dev, "no rxtx%d clock in devicetree\n", i);
- return PTR_ERR(clk);
- }
- if (!clk_get_rate(clk))
- continue;
-
- ret = fsl_spdif_txclk_caldiv(spdif_priv, clk, savesub, index,
- i == STC_TXCLK_SPDIF_ROOT);
- if (savesub == ret)
- continue;
-
- savesub = ret;
- spdif_priv->txclk[index] = clk;
- spdif_priv->txclk_src[index] = i;
-
- /* To quick catch a divisor, we allow a 0.1% deviation */
- if (savesub < 100)
- break;
- }
-
- dev_dbg(&pdev->dev, "use rxtx%d as tx clock source for %dHz sample rate\n",
- spdif_priv->txclk_src[index], rate[index]);
- dev_dbg(&pdev->dev, "use txclk df %d for %dHz sample rate\n",
- spdif_priv->txclk_df[index], rate[index]);
- if (clk_is_match(spdif_priv->txclk[index], spdif_priv->sysclk))
- dev_dbg(&pdev->dev, "use sysclk df %d for %dHz sample rate\n",
- spdif_priv->sysclk_df[index], rate[index]);
- dev_dbg(&pdev->dev, "the best rate for %dHz sample rate is %dHz\n",
- rate[index], spdif_priv->txrate[index]);
-
- return 0;
-}
+static const struct of_device_id fsl_spdif_dt_ids[] = {
+ { .compatible = "fsl,imx8qxp-v1-spdif", .data = &fsl_spdif_imx8qxp_v1, },
+ { .compatible = "fsl,imx8mm-spdif", .data = &fsl_spdif_imx8mm, },
+ { .compatible = "fsl,imx8qm-spdif", .data = &fsl_spdif_imx8qm, },
+ { .compatible = "fsl,imx35-spdif", .data = &fsl_spdif_imx35, },
+ { .compatible = "fsl,vf610-spdif", .data = &fsl_spdif_vf610, },
+ {}
+};
+MODULE_DEVICE_TABLE(of, fsl_spdif_dt_ids);
static int fsl_spdif_probe(struct platform_device *pdev)
{
@@ -1220,8 +1401,11 @@ static int fsl_spdif_probe(struct platform_device *pdev)
struct fsl_spdif_priv *spdif_priv;
struct spdif_mixer_control *ctrl;
struct resource *res;
+ const struct of_device_id *of_id;
void __iomem *regs;
int irq, ret, i;
+ u32 buffer_size;
+ char tmp[16];
if (!np)
return -ENODEV;
@@ -1232,9 +1416,19 @@ static int fsl_spdif_probe(struct platform_device *pdev)
spdif_priv->pdev = pdev;
+ of_id = of_match_device(fsl_spdif_dt_ids, &pdev->dev);
+ if (!of_id || !of_id->data)
+ return -EINVAL;
+
+ spdif_priv->soc = of_id->data;
+
/* Initialize this copy of the CPU DAI driver structure */
memcpy(&spdif_priv->cpu_dai_drv, &fsl_spdif_dai, sizeof(fsl_spdif_dai));
spdif_priv->cpu_dai_drv.name = dev_name(&pdev->dev);
+ spdif_priv->cpu_dai_drv.playback.formats =
+ spdif_priv->soc->tx_formats;
+ spdif_priv->cpu_dai_drv.capture.rates =
+ spdif_priv->soc->rx_rates;
/* Get the addresses and IRQ */
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -1261,9 +1455,32 @@ static int fsl_spdif_probe(struct platform_device *pdev)
dev_err(&pdev->dev, "could not claim irq %u\n", irq);
return ret;
}
+ if (spdif_priv->soc->interrupts > 1) {
+ irq = platform_get_irq(pdev, 1);
+ if (irq < 0) {
+ dev_err(&pdev->dev, "no irq for node %s\n", pdev->name);
+ return irq;
+ }
+
+ ret = devm_request_irq(&pdev->dev, irq, spdif_isr, 0,
+ dev_name(&pdev->dev), spdif_priv);
+ if (ret) {
+ dev_err(&pdev->dev, "could not claim irq %u\n", irq);
+ return ret;
+ }
+ }
+
+ for (i = 0; i < STC_TXCLK_SRC_MAX; i++) {
+ sprintf(tmp, "rxtx%d", i);
+ spdif_priv->txclk[i] = devm_clk_get(&pdev->dev, tmp);
+ if (IS_ERR(spdif_priv->txclk[i])) {
+ dev_err(&pdev->dev, "no rxtx%d clock in devicetree\n", i);
+ return PTR_ERR(spdif_priv->txclk[i]);
+ }
+ }
/* Get system clock for rx clock rate calculation */
- spdif_priv->sysclk = devm_clk_get(&pdev->dev, "rxtx5");
+ spdif_priv->sysclk = spdif_priv->txclk[5];
if (IS_ERR(spdif_priv->sysclk)) {
dev_err(&pdev->dev, "no sys clock (rxtx5) in devicetree\n");
return PTR_ERR(spdif_priv->sysclk);
@@ -1281,13 +1498,21 @@ static int fsl_spdif_probe(struct platform_device *pdev)
dev_warn(&pdev->dev, "no spba clock in devicetree\n");
/* Select clock source for rx/tx clock */
- spdif_priv->rxclk = devm_clk_get(&pdev->dev, "rxtx1");
+ spdif_priv->rxclk = spdif_priv->txclk[1];
if (IS_ERR(spdif_priv->rxclk)) {
dev_err(&pdev->dev, "no rxtx1 clock in devicetree\n");
return PTR_ERR(spdif_priv->rxclk);
}
spdif_priv->rxclk_src = DEFAULT_RXCLK_SRC;
+ spdif_priv->pll8k_clk = devm_clk_get(&pdev->dev, "pll8k");
+ if (IS_ERR(spdif_priv->pll8k_clk))
+ spdif_priv->pll8k_clk = NULL;
+
+ spdif_priv->pll11k_clk = devm_clk_get(&pdev->dev, "pll11k");
+ if (IS_ERR(spdif_priv->pll11k_clk))
+ spdif_priv->pll11k_clk = NULL;
+
for (i = 0; i < SPDIF_TXRATE_MAX; i++) {
ret = fsl_spdif_probe_txclk(spdif_priv, i);
if (ret)
@@ -1308,11 +1533,18 @@ static int fsl_spdif_probe(struct platform_device *pdev)
spdif_priv->dpll_locked = false;
- spdif_priv->dma_params_tx.maxburst = FSL_SPDIF_TXFIFO_WML;
- spdif_priv->dma_params_rx.maxburst = FSL_SPDIF_RXFIFO_WML;
+ spdif_priv->dma_params_tx.maxburst = spdif_priv->soc->tx_burst;
+ spdif_priv->dma_params_rx.maxburst = spdif_priv->soc->rx_burst;
spdif_priv->dma_params_tx.addr = res->start + REG_SPDIF_STL;
spdif_priv->dma_params_rx.addr = res->start + REG_SPDIF_SRL;
+ /*Clear the val bit for Tx*/
+ regmap_update_bits(spdif_priv->regmap, REG_SPDIF_SCR,
+ SCR_VAL_MASK, 1 << SCR_VAL_OFFSET);
+
+ pm_runtime_enable(&pdev->dev);
+
+ regcache_cache_only(spdif_priv->regmap, true);
/* Register with ASoC */
dev_set_drvdata(&pdev->dev, spdif_priv);
@@ -1323,51 +1555,112 @@ static int fsl_spdif_probe(struct platform_device *pdev)
return ret;
}
- ret = imx_pcm_dma_init(pdev, IMX_SPDIF_DMABUF_SIZE);
+ if (of_property_read_u32(np, "fsl,dma-buffer-size", &buffer_size))
+ buffer_size = IMX_SPDIF_DMABUF_SIZE;
+
+ if (spdif_priv->soc->dma_workaround)
+ spdif_priv->dma_info =
+ fsl_dma_workaround_alloc_info("tcd_pool_spdif",
+ &pdev->dev,
+ "nxp,imx8qm-acm",
+ FSL_DMA_WORKAROUND_SPDIF);
+ ret = imx_pcm_dma_init(pdev, buffer_size);
if (ret)
dev_err(&pdev->dev, "imx_pcm_dma_init failed: %d\n", ret);
return ret;
}
-#ifdef CONFIG_PM_SLEEP
-static int fsl_spdif_suspend(struct device *dev)
+static int fsl_spdif_remove(struct platform_device *pdev)
{
- struct fsl_spdif_priv *spdif_priv = dev_get_drvdata(dev);
-
- regmap_read(spdif_priv->regmap, REG_SPDIF_SRPC,
- &spdif_priv->regcache_srpc);
+ struct fsl_spdif_priv *spdif_priv = dev_get_drvdata(&pdev->dev);
- regcache_cache_only(spdif_priv->regmap, true);
- regcache_mark_dirty(spdif_priv->regmap);
+ if (spdif_priv->soc->dma_workaround)
+ fsl_dma_workaround_free_info(spdif_priv->dma_info, &pdev->dev);
return 0;
}
-static int fsl_spdif_resume(struct device *dev)
+#ifdef CONFIG_PM
+static int fsl_spdif_runtime_resume(struct device *dev)
{
struct fsl_spdif_priv *spdif_priv = dev_get_drvdata(dev);
+ int ret;
+ int i;
+
+ ret = clk_prepare_enable(spdif_priv->coreclk);
+ if (ret) {
+ dev_err(dev, "failed to enable core clock\n");
+ return ret;
+ }
+
+ if (!IS_ERR(spdif_priv->spbaclk)) {
+ ret = clk_prepare_enable(spdif_priv->spbaclk);
+ if (ret) {
+ dev_err(dev, "failed to enable spba clock\n");
+ goto disable_core_clk;
+ }
+ }
+
+ for (i = 0; i < STC_TXCLK_SRC_MAX; i++) {
+ ret = clk_prepare_enable(spdif_priv->txclk[i]);
+ if (ret)
+ goto disable_spba_clk;
+ }
+
+ request_bus_freq(BUS_FREQ_HIGH);
regcache_cache_only(spdif_priv->regmap, false);
+ regcache_mark_dirty(spdif_priv->regmap);
regmap_update_bits(spdif_priv->regmap, REG_SPDIF_SRPC,
SRPC_CLKSRC_SEL_MASK | SRPC_GAINSEL_MASK,
spdif_priv->regcache_srpc);
- return regcache_sync(spdif_priv->regmap);
+ ret = regcache_sync(spdif_priv->regmap);
+ if (ret)
+ goto disable_tx_clk;
+
+ return 0;
+
+disable_tx_clk:
+disable_spba_clk:
+ for (i--; i >= 0; i--)
+ clk_disable_unprepare(spdif_priv->txclk[i]);
+ if (!IS_ERR(spdif_priv->spbaclk))
+ clk_disable_unprepare(spdif_priv->spbaclk);
+disable_core_clk:
+ clk_disable_unprepare(spdif_priv->coreclk);
+
+ return ret;
}
-#endif /* CONFIG_PM_SLEEP */
-static const struct dev_pm_ops fsl_spdif_pm = {
- SET_SYSTEM_SLEEP_PM_OPS(fsl_spdif_suspend, fsl_spdif_resume)
-};
+static int fsl_spdif_runtime_suspend(struct device *dev)
+{
+ struct fsl_spdif_priv *spdif_priv = dev_get_drvdata(dev);
+ int i;
-static const struct of_device_id fsl_spdif_dt_ids[] = {
- { .compatible = "fsl,imx35-spdif", },
- { .compatible = "fsl,vf610-spdif", },
- {}
+ regmap_read(spdif_priv->regmap, REG_SPDIF_SRPC,
+ &spdif_priv->regcache_srpc);
+ regcache_cache_only(spdif_priv->regmap, true);
+ release_bus_freq(BUS_FREQ_HIGH);
+
+ for (i = 0; i < STC_TXCLK_SRC_MAX; i++)
+ clk_disable_unprepare(spdif_priv->txclk[i]);
+
+ if (!IS_ERR(spdif_priv->spbaclk))
+ clk_disable_unprepare(spdif_priv->spbaclk);
+ clk_disable_unprepare(spdif_priv->coreclk);
+
+ return 0;
+}
+#endif
+
+static const struct dev_pm_ops fsl_spdif_pm = {
+ SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, pm_runtime_force_resume)
+ SET_RUNTIME_PM_OPS(fsl_spdif_runtime_suspend, fsl_spdif_runtime_resume,
+ NULL)
};
-MODULE_DEVICE_TABLE(of, fsl_spdif_dt_ids);
static struct platform_driver fsl_spdif_driver = {
.driver = {
@@ -1376,6 +1669,7 @@ static struct platform_driver fsl_spdif_driver = {
.pm = &fsl_spdif_pm,
},
.probe = fsl_spdif_probe,
+ .remove = fsl_spdif_remove,
};
module_platform_driver(fsl_spdif_driver);
diff --git a/sound/soc/fsl/fsl_spdif.h b/sound/soc/fsl/fsl_spdif.h
index 00bd3514c610..e3f0fbdb9f22 100644
--- a/sound/soc/fsl/fsl_spdif.h
+++ b/sound/soc/fsl/fsl_spdif.h
@@ -66,6 +66,7 @@
#define SCR_TXFIFO_FSEL_IF4 (0x1 << SCR_TXFIFO_FSEL_OFFSET)
#define SCR_TXFIFO_FSEL_IF8 (0x2 << SCR_TXFIFO_FSEL_OFFSET)
#define SCR_TXFIFO_FSEL_IF12 (0x3 << SCR_TXFIFO_FSEL_OFFSET)
+#define SCR_RAW_CAPTURE_MODE (1 << 14)
#define SCR_LOW_POWER (1 << 13)
#define SCR_SOFT_RESET (1 << 12)
#define SCR_TXFIFO_CTRL_OFFSET 10
@@ -155,7 +156,7 @@ enum spdif_gainsel {
#define STC_TXCLK_ALL_EN_MASK (1 << STC_TXCLK_ALL_EN_OFFSET)
#define STC_TXCLK_ALL_EN (1 << STC_TXCLK_ALL_EN_OFFSET)
#define STC_TXCLK_DF_OFFSET 0
-#define STC_TXCLK_DF_MASK (0x7ff << STC_TXCLK_DF_OFFSET)
+#define STC_TXCLK_DF_MASK (0x7f << STC_TXCLK_DF_OFFSET)
#define STC_TXCLK_DF(x) ((((x) - 1) << STC_TXCLK_DF_OFFSET) & STC_TXCLK_DF_MASK)
#define STC_TXCLK_SRC_MAX 8
diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
index 38b336146b38..1245db8451a1 100644
--- a/sound/soc/fsl/fsl_ssi.c
+++ b/sound/soc/fsl/fsl_ssi.c
@@ -3,7 +3,8 @@
*
* Author: Timur Tabi <timur@freescale.com>
*
- * Copyright 2007-2010 Freescale Semiconductor, Inc.
+ * Copyright 2007-2015, Freescale Semiconductor, Inc.
+ * Copyright 2017 NXP
*
* 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
@@ -44,6 +45,8 @@
#include <linux/of_address.h>
#include <linux/of_irq.h>
#include <linux/of_platform.h>
+#include <linux/pm_runtime.h>
+#include <linux/busfreq-imx.h>
#include <sound/core.h>
#include <sound/pcm.h>
@@ -231,6 +234,7 @@ struct fsl_ssi_private {
u8 i2s_mode;
bool use_dma;
bool use_dual_fifo;
+ bool use_dyna_fifo;
bool has_ipg_clk_name;
unsigned int fifo_depth;
struct fsl_ssi_rxtx_reg_val rxtx_reg_val;
@@ -667,12 +671,14 @@ static int fsl_ssi_startup(struct snd_pcm_substream *substream,
if (ret)
return ret;
+ pm_runtime_get_sync(dai->dev);
+
/* When using dual fifo mode, it is safer to ensure an even period
* size. If appearing to an odd number while DMA always starts its
* task from fifo0, fifo1 would be neglected at the end of each
* period. But SSI would still access fifo1 with an invalid data.
*/
- if (ssi_private->use_dual_fifo)
+ if (ssi_private->use_dual_fifo || ssi_private->use_dyna_fifo)
snd_pcm_hw_constraint_step(substream->runtime, 0,
SNDRV_PCM_HW_PARAM_PERIOD_SIZE, 2);
@@ -690,6 +696,8 @@ static void fsl_ssi_shutdown(struct snd_pcm_substream *substream,
struct fsl_ssi_private *ssi_private =
snd_soc_dai_get_drvdata(rtd->cpu_dai);
+ pm_runtime_put_sync(dai->dev);
+
clk_disable_unprepare(ssi_private->clk);
}
@@ -719,8 +727,14 @@ static int fsl_ssi_set_bclk(struct snd_pcm_substream *substream,
/* Prefer the explicitly set bitclock frequency */
if (ssi_private->bitclk_freq)
freq = ssi_private->bitclk_freq;
- else
- freq = params_channels(hw_params) * 32 * params_rate(hw_params);
+ else {
+ if (params_channels(hw_params) == 1)
+ freq = 2 * params_width(hw_params) *
+ params_rate(hw_params);
+ else
+ freq = params_channels(hw_params) * 32 *
+ params_rate(hw_params);
+ }
/* Don't apply it to any non-baudclk circumstance */
if (IS_ERR(ssi_private->baudclk))
@@ -839,16 +853,8 @@ static int fsl_ssi_hw_params(struct snd_pcm_substream *substream,
int ret;
u32 scr_val;
int enabled;
-
- regmap_read(regs, CCSR_SSI_SCR, &scr_val);
- enabled = scr_val & CCSR_SSI_SCR_SSIEN;
-
- /*
- * If we're in synchronous mode, and the SSI is already enabled,
- * then STCCR is already set properly.
- */
- if (enabled && ssi_private->cpu_dai_drv.symmetric_rates)
- return 0;
+ u8 i2smode = ssi_private->i2s_mode;
+ struct fsl_ssi_rxtx_reg_val *reg = &ssi_private->rxtx_reg_val;
if (fsl_ssi_is_i2s_master(ssi_private)) {
ret = fsl_ssi_set_bclk(substream, cpu_dai, hw_params);
@@ -865,8 +871,17 @@ static int fsl_ssi_hw_params(struct snd_pcm_substream *substream,
}
}
+ regmap_read(regs, CCSR_SSI_SCR, &scr_val);
+ enabled = scr_val & CCSR_SSI_SCR_SSIEN;
+
+ /*
+ * If we're in synchronous mode, and the SSI is already enabled,
+ * then STCCR is already set properly.
+ */
+ if (enabled && ssi_private->cpu_dai_drv.symmetric_rates)
+ return 0;
+
if (!fsl_ssi_is_ac97(ssi_private)) {
- u8 i2smode;
/*
* Switch to normal net mode in order to have a frame sync
* signal every 32 bits instead of 16 bits
@@ -874,14 +889,14 @@ static int fsl_ssi_hw_params(struct snd_pcm_substream *substream,
if (fsl_ssi_is_i2s_cbm_cfs(ssi_private) && sample_size == 16)
i2smode = CCSR_SSI_SCR_I2S_MODE_NORMAL |
CCSR_SSI_SCR_NET;
- else
- i2smode = ssi_private->i2s_mode;
-
- regmap_update_bits(regs, CCSR_SSI_SCR,
- CCSR_SSI_SCR_NET | CCSR_SSI_SCR_I2S_MODE_MASK,
- channels == 1 ? 0 : i2smode);
+ if (channels == 1)
+ i2smode = 0;
}
+ regmap_update_bits(regs, CCSR_SSI_SCR,
+ CCSR_SSI_SCR_NET | CCSR_SSI_SCR_I2S_MODE_MASK,
+ i2smode);
+
/*
* FIXME: The documentation says that SxCCR[WL] should not be
* modified while the SSI is enabled. The only time this can
@@ -901,6 +916,24 @@ static int fsl_ssi_hw_params(struct snd_pcm_substream *substream,
regmap_update_bits(regs, CCSR_SSI_SRCCR, CCSR_SSI_SxCCR_WL_MASK,
wl);
+ if (ssi_private->use_dyna_fifo) {
+ if (channels == 1) {
+ ssi_private->dma_params_tx.fifo_num = 1;
+ ssi_private->dma_params_rx.fifo_num = 1;
+ reg->rx.srcr &= ~CCSR_SSI_SRCR_RFEN1;
+ reg->tx.stcr &= ~CCSR_SSI_STCR_TFEN1;
+ reg->rx.scr &= ~CCSR_SSI_SCR_TCH_EN;
+ reg->tx.scr &= ~CCSR_SSI_SCR_TCH_EN;
+ } else {
+ ssi_private->dma_params_tx.fifo_num = 2;
+ ssi_private->dma_params_rx.fifo_num = 2;
+ reg->rx.srcr |= CCSR_SSI_SRCR_RFEN1;
+ reg->tx.stcr |= CCSR_SSI_STCR_TFEN1;
+ reg->rx.scr |= CCSR_SSI_SCR_TCH_EN;
+ reg->tx.scr |= CCSR_SSI_SCR_TCH_EN;
+ }
+ }
+
return 0;
}
@@ -938,7 +971,7 @@ static int _fsl_ssi_set_dai_fmt(struct device *dev,
fsl_ssi_setup_reg_vals(ssi_private);
regmap_read(regs, CCSR_SSI_SCR, &scr);
- scr &= ~(CCSR_SSI_SCR_SYN | CCSR_SSI_SCR_I2S_MODE_MASK);
+ scr &= ~CCSR_SSI_SCR_SYN;
scr |= CCSR_SSI_SCR_SYNC_TX_FS;
mask = CCSR_SSI_STCR_TXBIT0 | CCSR_SSI_STCR_TFDIR | CCSR_SSI_STCR_TXDIR |
@@ -994,7 +1027,6 @@ static int _fsl_ssi_set_dai_fmt(struct device *dev,
default:
return -EINVAL;
}
- scr |= ssi_private->i2s_mode;
/* DAI clock inversion */
switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
@@ -1187,7 +1219,7 @@ static int fsl_ssi_dai_probe(struct snd_soc_dai *dai)
static const struct snd_soc_dai_ops fsl_ssi_dai_ops = {
.startup = fsl_ssi_startup,
- .shutdown = fsl_ssi_shutdown,
+ .shutdown = fsl_ssi_shutdown,
.hw_params = fsl_ssi_hw_params,
.hw_free = fsl_ssi_hw_free,
.set_fmt = fsl_ssi_set_dai_fmt,
@@ -1328,6 +1360,7 @@ static int fsl_ssi_imx_probe(struct platform_device *pdev,
struct device_node *np = pdev->dev.of_node;
u32 dmas[4];
int ret;
+ u32 buffer_size;
if (ssi_private->has_ipg_clk_name)
ssi_private->clk = devm_clk_get(&pdev->dev, "ipg");
@@ -1355,6 +1388,8 @@ static int fsl_ssi_imx_probe(struct platform_device *pdev,
dev_dbg(&pdev->dev, "could not get baud clock: %ld\n",
PTR_ERR(ssi_private->baudclk));
+ ssi_private->dma_params_rx.chan_name = "rx";
+ ssi_private->dma_params_tx.chan_name = "tx";
ssi_private->dma_params_tx.maxburst = ssi_private->dma_maxburst;
ssi_private->dma_params_rx.maxburst = ssi_private->dma_maxburst;
ssi_private->dma_params_tx.addr = ssi_private->ssi_phys + CCSR_SSI_STX0;
@@ -1370,6 +1405,12 @@ static int fsl_ssi_imx_probe(struct platform_device *pdev,
ssi_private->dma_params_rx.maxburst &= ~0x1;
}
+ if (ssi_private->use_dma && !ret && dmas[2] == IMX_DMATYPE_MULTI_SAI)
+ ssi_private->use_dyna_fifo = true;
+
+ if (of_property_read_u32(np, "fsl,dma-buffer-size", &buffer_size))
+ buffer_size = IMX_SSI_DMABUF_SIZE;
+
if (!ssi_private->use_dma) {
/*
@@ -1390,7 +1431,7 @@ static int fsl_ssi_imx_probe(struct platform_device *pdev,
if (ret)
goto error_pcm;
} else {
- ret = imx_pcm_dma_init(pdev, IMX_SSI_DMABUF_SIZE);
+ ret = imx_pcm_platform_register(&pdev->dev);
if (ret)
goto error_pcm;
}
@@ -1555,6 +1596,8 @@ static int fsl_ssi_probe(struct platform_device *pdev)
break;
}
+ pm_runtime_enable(&pdev->dev);
+
dev_set_drvdata(&pdev->dev, ssi_private);
if (ssi_private->soc->imx) {
@@ -1719,8 +1762,24 @@ static int fsl_ssi_resume(struct device *dev)
}
#endif /* CONFIG_PM_SLEEP */
+#ifdef CONFIG_PM
+static int fsl_ssi_runtime_resume(struct device *dev)
+{
+ request_bus_freq(BUS_FREQ_AUDIO);
+ return 0;
+}
+
+static int fsl_ssi_runtime_suspend(struct device *dev)
+{
+ release_bus_freq(BUS_FREQ_AUDIO);
+ return 0;
+}
+#endif
+
static const struct dev_pm_ops fsl_ssi_pm = {
SET_SYSTEM_SLEEP_PM_OPS(fsl_ssi_suspend, fsl_ssi_resume)
+ SET_RUNTIME_PM_OPS(fsl_ssi_runtime_suspend, fsl_ssi_runtime_resume,
+ NULL)
};
static struct platform_driver fsl_ssi_driver = {
diff --git a/sound/soc/fsl/hdmi_pcm.S b/sound/soc/fsl/hdmi_pcm.S
new file mode 100644
index 000000000000..d8d95fd8f42f
--- /dev/null
+++ b/sound/soc/fsl/hdmi_pcm.S
@@ -0,0 +1,246 @@
+/**
+ * Copyright (C) 2010-2014 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+.section .text
+
+.global hdmi_dma_copy_16_neon_lut
+.global hdmi_dma_copy_16_neon_fast
+.global hdmi_dma_copy_24_neon_lut
+.global hdmi_dma_copy_24_neon_fast
+
+
+/**
+ * hdmi_dma_copy_16_neon_lut
+ * Convert pcm sample to iec sample. Pcm sample is 16 bits.
+ * Frame index's between 0 and 47 inclusively. Channel count can be 1, 2, 4, 8.
+ * Frame count should be multipliable by 4, and Sample count by 8.
+ *
+ * C Prototype
+ * void hdmi_dma_copy_16_neon_lut(unsigned short *src, unsigned int *dst,
+ * int samples, unsigned char *lookup_table);
+ * Return value
+ * None
+ * Parameters
+ * src Source PCM16 samples
+ * dst Dest buffer to store pcm with header
+ * samples Contains sample count (=frame_count * channel_count)
+ * lookup_table Preconstructed header table. Channels interleaved.
+ */
+
+hdmi_dma_copy_16_neon_lut:
+ mov r12, #1 /* construct vector(1) */
+ vdup.8 d6, r12
+
+hdmi_dma_copy_16_neon_lut_start:
+
+ /* get 8 samples to q0 */
+ vld1.16 {d0, d1}, [r0]! /* TODO: aligned */
+
+ /* pld [r1, #(64*4)] */
+
+ /* xor every bit */
+ vcnt.8 q1, q0 /* count of 1s */
+ vpadd.i8 d2, d2, d3 /* only care about the LST in every element */
+ vand d2, d2, d6 /* clear other bits while keep the least bit */
+ vshl.u8 d2, d2, #3 /* bit p: d2 = d2 << 3 */
+
+ /* get packet header */
+ vld1.8 {d5}, [r3]!
+ veor d4, d5, d2 /* xor bit c */
+
+ /* store: (d4 << 16 | q0) << 8 */
+ vmovl.u8 q2, d4 /* expand from char to short */
+ vzip.16 q0, q2
+ vshl.u32 q0, q0, #8
+ vshl.u32 q1, q2, #8
+ vst1.32 {d0, d1, d2, d3}, [r1]!
+
+ /* decrease sample count */
+ subs r2, r2, #8
+ bne hdmi_dma_copy_16_neon_lut_start
+
+ mov pc, lr
+
+/**
+ * hdmi_dma_copy_16_neon_fast
+ * Convert pcm sample to iec sample. Pcm sample is 16 bits.
+ * Frame index's between 48 and 191 inclusively.
+ * Channel count can be 1, 2, 4 or 8.
+ * Frame count should be multipliable by 4, and Sample count by 8.
+ *
+ * C Prototype
+ * void hdmi_dma_copy_16_neon_fast(unsigned short *src,
+ * unsigned int *dst, int samples);
+ * Return value
+ * None
+ * Parameters
+ * src Source PCM16 samples
+ * dst Dest buffer to store pcm with header
+ * samples Contains sample count (=frame_count * channel_count)
+ */
+
+hdmi_dma_copy_16_neon_fast:
+ mov r12, #1 /* construct vector(1) */
+ vdup.8 d6, r12
+
+hdmi_dma_copy_16_neon_fast_start:
+ /* get 8 samples to q0 */
+ vld1.16 {d0, d1}, [r0]! /* TODO: aligned */
+
+ /* pld [r1, #(64*4)] */
+
+ /* xor every bit */
+ vcnt.8 q1, q0 /* count of 1s */
+ vpadd.i8 d2, d2, d3
+ vand d2, d2, d6 /* clear other bits while keep the LST */
+ /* finally we construct packet header */
+ vshl.u8 d4, d2, #3 /* bit p: d2 = d2 << 3 */
+
+ /* get packet header: always 0 */
+
+ /* store: (d4 << 16 | q0) << 8 */
+ vmovl.u8 q2, d4 /* expand from char to short */
+ vzip.16 q0, q2
+ vshl.u32 q0, q0, #8
+ vshl.u32 q1, q2, #8
+ vst1.32 {d0, d1, d2, d3}, [r1]!
+
+ /* decrease sample count */
+ subs r2, r2, #8
+ bne hdmi_dma_copy_16_neon_fast_start
+
+ mov pc, lr
+
+
+
+/**
+ * hdmi_dma_copy_24_neon_lut
+ * Convert pcm sample to iec sample. Pcm sample is 24 bits.
+ * Frame index's between 0 and 47 inclusively. Channel count can be 1, 2, 4, 8.
+ * Frame count should be multipliable by 4, and Sample count by 8.
+ *
+ * C Prototype
+ * void hdmi_dma_copy_24_neon_lut(unsigned int *src, unsigned int *dst,
+ * int samples, unsigned char *lookup_table);
+ * Return value
+ * None
+ * Parameters
+ * src Source PCM24 samples
+ * dst Dest buffer to store pcm with header
+ * samples Contains sample count (=frame_count * channel_count)
+ * lookup_table Preconstructed header table. Channels interleaved.
+ */
+
+hdmi_dma_copy_24_neon_lut:
+ vpush {d8}
+
+ mov r12, #1 /* construct vector(1) */
+ vdup.8 d8, r12
+
+hdmi_dma_copy_24_neon_lut_start:
+
+ /* get 8 samples to q0 and q1 */
+ vld1.32 {d0, d1, d2, d3}, [r0]! /* TODO: aligned */
+
+ /* pld [r1, #(64*4)] */
+
+ /* xor every bit */
+ vcnt.8 q2, q0 /* count of 1s */
+ vpadd.i8 d4, d4, d5 /* only care about the LSB in every element */
+ vcnt.8 q3, q1
+ vpadd.i8 d6, d6, d7
+ vpadd.i8 d4, d4, d6 /* d4: contains xor result and other dirty bits */
+ vand d4, d4, d8 /* clear other bits while keep the least bit */
+ vshl.u8 d4, d4, #3 /* bit p: d4 = d4 << 3 */
+
+ /* get packet header */
+ vld1.8 {d5}, [r3]!/* d5: original header */
+ veor d5, d5, d4 /* fix bit p */
+
+ /* store: (d5 << 24 | q0) */
+ vmovl.u8 q3, d5 /* expand from char to short */
+ vmovl.u16 q2, d6 /* expand from short to int */
+ vmovl.u16 q3, d7
+ vshl.u32 q2, q2, #24
+ vshl.u32 q3, q3, #24
+ vorr q0, q0, q2
+ vorr q1, q1, q3
+ vst1.32 {d0, d1, d2, d3}, [r1]!
+
+ /* decrease sample count */
+ subs r2, r2, #8
+ bne hdmi_dma_copy_24_neon_lut_start
+
+ vpop {d8}
+ mov pc, lr
+
+/**
+ * hdmi_dma_copy_24_neon_fast
+ * Convert pcm sample to iec sample. Pcm sample is 24 bits.
+ * Frame index's between 48 and 191 inclusively.
+ * Channel count can be 1, 2, 4 or 8.
+ * Frame count should be multipliable by 4, and Sample count by 8.
+ *
+ * C Prototype
+ * void hdmi_dma_copy_24_neon_fast(unsigned int *src,
+ * unsigned int *dst, int samples);
+ * Return value
+ * None
+ * Parameters
+ * src Source PCM24 samples
+ * dst Dest buffer to store pcm with header
+ * samples Contains sample count (=frame_count * channel_count)
+ */
+
+hdmi_dma_copy_24_neon_fast:
+ vpush {d8}
+
+ mov r12, #1 /* construct vector(1) */
+ vdup.8 d8, r12
+
+hdmi_dma_copy_24_neon_fast_start:
+ /* get 8 samples to q0 and q1 */
+ vld1.32 {d0, d1, d2, d3}, [r0]! /* TODO: aligned */
+
+ /* pld [r1, #(64*4)] */
+
+ /* xor every bit */
+ vcnt.8 q2, q0 /* count of 1s */
+ vpadd.i8 d4, d4, d5 /* only care about the LSB in every element */
+ vcnt.8 q3, q1
+ vpadd.i8 d6, d6, d7
+ vpadd.i8 d4, d4, d6 /* d4: contains xor result and other dirty bits */
+ vand d4, d4, d8 /* clear other bits while keep the least bit */
+ vshl.u8 d4, d4, #3 /* bit p: d4 = d4 << 3 */
+
+ /* store: (d4 << 24 | q0) */
+ vmovl.u8 q3, d4 /* expand from char to short */
+ vmovl.u16 q2, d6 /* expand from short to int */
+ vmovl.u16 q3, d7
+ vshl.u32 q2, q2, #24
+ vshl.u32 q3, q3, #24
+ vorr q0, q0, q2
+ vorr q1, q1, q3
+ vst1.32 {d0, d1, d2, d3}, [r1]!
+
+ /* decrease sample count */
+ subs r2, r2, #8
+ bne hdmi_dma_copy_24_neon_fast_start
+
+ vpop {d8}
+ mov pc, lr
diff --git a/sound/soc/fsl/imx-ak4458.c b/sound/soc/fsl/imx-ak4458.c
new file mode 100644
index 000000000000..a159ea8f8c64
--- /dev/null
+++ b/sound/soc/fsl/imx-ak4458.c
@@ -0,0 +1,407 @@
+/* i.MX AK4458 audio support
+ *
+ * Copyright 2017 NXP
+ *
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/gpio/consumer.h>
+#include <linux/of_device.h>
+#include <linux/i2c.h>
+#include <linux/of_gpio.h>
+#include <linux/clk.h>
+#include <sound/soc.h>
+#include <sound/pcm_params.h>
+#include <sound/pcm.h>
+#include <sound/soc-dapm.h>
+
+#include "fsl_sai.h"
+#include "fsl_dsd.h"
+
+struct imx_ak4458_data {
+ struct snd_soc_card card;
+ int num_codec_conf;
+ struct snd_soc_codec_conf *codec_conf;
+ bool tdm_mode;
+ int pdn_gpio;
+ unsigned int slots;
+ unsigned int slot_width;
+ bool one2one_ratio;
+};
+
+static struct snd_soc_dapm_widget imx_ak4458_dapm_widgets[] = {
+ SND_SOC_DAPM_LINE("Line Out", NULL),
+};
+
+/**
+ * Tables 3 & 4 - mapping LRCK fs and frame width
+ */
+static const struct imx_ak4458_fs_map {
+ unsigned int rmin;
+ unsigned int rmax;
+ unsigned int wmin;
+ unsigned int wmax;
+} fs_map[] = {
+ /* Normal, < 32kHz */
+ { .rmin = 8000, .rmax = 24000, .wmin = 1024, .wmax = 1024, },
+ /* Normal, 32kHz */
+ { .rmin = 32000, .rmax = 32000, .wmin = 256, .wmax = 1024, },
+ /* Normal */
+ { .rmin = 44100, .rmax = 48000, .wmin = 256, .wmax = 768, },
+ /* Double */
+ { .rmin = 88200, .rmax = 96000, .wmin = 256, .wmax = 512, },
+ /* Quad */
+ { .rmin = 176400, .rmax = 192000, .wmin = 128, .wmax = 256, },
+ /* Oct */
+ { .rmin = 352800, .rmax = 384000, .wmin = 32, .wmax = 128, },
+ /* Hex */
+ { .rmin = 705600, .rmax = 768000, .wmin = 16, .wmax = 64, },
+};
+
+static const struct imx_ak4458_fs_mul {
+ unsigned int min;
+ unsigned int max;
+ unsigned int mul;
+} fs_mul_tdm[] = {
+ /*
+ * Table 13 - Audio Interface Format
+ * For TDM mode, MCLK should is set to
+ * obtained from 2 * slots * slot_width
+ */
+ { .min = 128, .max = 128, .mul = 256 }, /* TDM128 */
+ { .min = 256, .max = 256, .mul = 512 }, /* TDM256 */
+ { .min = 512, .max = 512, .mul = 1024 }, /* TDM512 */
+};
+
+static const u32 ak4458_rates[] = {
+ 8000, 11025, 16000, 22050,
+ 32000, 44100, 48000, 88200,
+ 96000, 176400, 192000, 352800,
+ 384000, 705600, 768000,
+};
+
+static const u32 ak4458_rates_tdm[] = {
+ 8000, 16000, 32000,
+ 48000, 96000,
+};
+
+static const u32 ak4458_channels[] = {
+ 1, 2, 4, 6, 8, 10, 12, 14, 16,
+};
+
+static const u32 ak4458_channels_tdm[] = {
+ 1, 2, 3, 4, 5, 6, 7, 8, 16,
+};
+
+static unsigned long ak4458_get_mclk_rate(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct imx_ak4458_data *data = snd_soc_card_get_drvdata(rtd->card);
+ unsigned int rate = params_rate(params);
+ unsigned int width = data->slots * data->slot_width;
+ int i, mode;
+
+ if (data->tdm_mode) {
+ /* can be 128, 256 or 512 */
+ mode = data->slots * data->slot_width;
+
+ for (i = 0; i < ARRAY_SIZE(fs_mul_tdm); i++) {
+ /* min = max = slots * slots_width */
+ if (mode != fs_mul_tdm[i].min)
+ continue;
+ return rate * fs_mul_tdm[i].mul;
+ }
+ } else {
+ for (i = 0; i < ARRAY_SIZE(fs_map); i++) {
+ if (rate >= fs_map[i].rmin && rate <= fs_map[i].rmax) {
+ width = max(width, fs_map[i].wmin);
+ width = min(width, fs_map[i].wmax);
+
+ /* Adjust SAI bclk:mclk ratio */
+ width *= data->one2one_ratio ? 1 : 2;
+
+ return rate * width;
+ }
+ }
+ }
+
+ /* Let DAI manage clk frequency by default */
+ return 0;
+}
+
+static int imx_aif_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+ struct snd_soc_card *card = rtd->card;
+ struct device *dev = card->dev;
+ struct imx_ak4458_data *data = snd_soc_card_get_drvdata(card);
+ unsigned int channels = params_channels(params);
+ unsigned int fmt = SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS;
+ unsigned long mclk_freq;
+ bool is_dsd = fsl_is_dsd(params);
+ int ret, i;
+
+ if (is_dsd) {
+ channels = 1;
+ data->slots = 1;
+ data->slot_width = params_width(params);
+ fmt |= SND_SOC_DAIFMT_PDM;
+ } else if (data->tdm_mode) {
+ data->slots = 8;
+ data->slot_width = 32;
+ fmt |= SND_SOC_DAIFMT_DSP_B;
+ } else {
+ data->slots = 2;
+ data->slot_width = params_physical_width(params);
+ fmt |= SND_SOC_DAIFMT_I2S;
+ }
+
+ ret = snd_soc_dai_set_fmt(cpu_dai, fmt);
+ if (ret) {
+ dev_err(dev, "failed to set cpu dai fmt: %d\n", ret);
+ return ret;
+ }
+ ret = snd_soc_dai_set_tdm_slot(cpu_dai,
+ BIT(channels) - 1, BIT(channels) - 1,
+ data->slots, data->slot_width);
+ if (ret) {
+ dev_err(dev, "failed to set cpu dai tdm slot: %d\n", ret);
+ return ret;
+ }
+
+ for (i = 0; i < rtd->num_codecs; i++) {
+ struct snd_soc_dai *codec_dai = rtd->codec_dais[i];
+
+ ret = snd_soc_dai_set_fmt(codec_dai, fmt);
+ if (ret) {
+ dev_err(dev, "failed to set codec dai[%d] fmt: %d\n",
+ i, ret);
+ return ret;
+ }
+ ret = snd_soc_dai_set_tdm_slot(codec_dai,
+ BIT(channels) - 1, BIT(channels) - 1,
+ data->slots, data->slot_width);
+ if (ret) {
+ dev_err(dev, "failed to set codec dai[%d] tdm slot: %d\n",
+ i, ret);
+ return ret;
+ }
+ }
+
+ /* set MCLK freq */
+ mclk_freq = ak4458_get_mclk_rate(substream, params);
+ if (is_dsd)
+ mclk_freq = 22579200;
+ ret = snd_soc_dai_set_sysclk(cpu_dai, FSL_SAI_CLK_MAST1, mclk_freq,
+ SND_SOC_CLOCK_OUT);
+ if (ret < 0)
+ dev_err(dev, "failed to set cpui dai mclk1 rate (%lu): %d\n",
+ mclk_freq, ret);
+ return ret;
+}
+
+static int imx_aif_startup(struct snd_pcm_substream *substream)
+{
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_card *card = rtd->card;
+ struct imx_ak4458_data *data = snd_soc_card_get_drvdata(card);
+ static struct snd_pcm_hw_constraint_list constraint_rates;
+ static struct snd_pcm_hw_constraint_list constraint_channels;
+ int ret;
+
+ if (data->tdm_mode) {
+ constraint_channels.list = ak4458_channels_tdm;
+ constraint_channels.count = ARRAY_SIZE(ak4458_channels_tdm);
+ constraint_rates.list = ak4458_rates_tdm;
+ constraint_rates.count = ARRAY_SIZE(ak4458_rates_tdm);
+ } else {
+ constraint_channels.list = ak4458_channels;
+ constraint_channels.count = ARRAY_SIZE(ak4458_channels);
+ constraint_rates.list = ak4458_rates;
+ constraint_rates.count = ARRAY_SIZE(ak4458_rates);
+ }
+
+ ret = snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
+ &constraint_channels);
+ if (ret)
+ return ret;
+
+ ret = snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
+ &constraint_rates);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+static struct snd_soc_ops imx_aif_ops = {
+ .hw_params = imx_aif_hw_params,
+ .startup = imx_aif_startup,
+};
+
+static struct snd_soc_dai_link_component ak4458_codecs[] = {
+ {
+ /* Playback */
+ .dai_name = "ak4458-aif",
+ },
+ {
+ /* Capture */
+ .dai_name = "ak4458-aif",
+ },
+};
+
+static struct snd_soc_dai_link imx_ak4458_dai = {
+ .name = "ak4458",
+ .stream_name = "Audio",
+ .codecs = ak4458_codecs,
+ .num_codecs = 2,
+ .ignore_pmdown_time = 1,
+ .ops = &imx_aif_ops,
+ .playback_only = 1,
+};
+
+static int imx_ak4458_probe(struct platform_device *pdev)
+{
+ struct imx_ak4458_data *priv;
+ struct device_node *cpu_np, *codec_np_0 = NULL, *codec_np_1 = NULL;
+ struct platform_device *cpu_pdev;
+ int ret;
+
+ priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ cpu_np = of_parse_phandle(pdev->dev.of_node, "audio-cpu", 0);
+ if (!cpu_np) {
+ dev_err(&pdev->dev, "audio dai phandle missing or invalid\n");
+ ret = -EINVAL;
+ goto fail;
+ }
+
+ codec_np_0 = of_parse_phandle(pdev->dev.of_node, "audio-codec", 0);
+ if (!codec_np_0) {
+ dev_err(&pdev->dev, "audio codec phandle missing or invalid\n");
+ ret = -EINVAL;
+ goto fail;
+ }
+
+ codec_np_1 = of_parse_phandle(pdev->dev.of_node, "audio-codec", 1);
+ if (!codec_np_1) {
+ dev_err(&pdev->dev, "audio codec phandle missing or invalid\n");
+ ret = -EINVAL;
+ goto fail;
+ }
+
+ cpu_pdev = of_find_device_by_node(cpu_np);
+ if (!cpu_pdev) {
+ dev_err(&pdev->dev, "failed to find SAI platform device\n");
+ ret = -EINVAL;
+ goto fail;
+ }
+
+ if (of_find_property(pdev->dev.of_node, "fsl,tdm", NULL))
+ priv->tdm_mode = true;
+
+ priv->num_codec_conf = 2;
+ priv->codec_conf = devm_kzalloc(&pdev->dev,
+ priv->num_codec_conf * sizeof(struct snd_soc_codec_conf),
+ GFP_KERNEL);
+ if (!priv->codec_conf) {
+ ret = -ENOMEM;
+ goto fail;
+ }
+
+ priv->codec_conf[0].name_prefix = "0";
+ priv->codec_conf[0].of_node = codec_np_0;
+ priv->codec_conf[1].name_prefix = "1";
+ priv->codec_conf[1].of_node = codec_np_1;
+
+ ak4458_codecs[0].of_node = codec_np_0;
+ ak4458_codecs[1].of_node = codec_np_1;
+
+ imx_ak4458_dai.cpu_dai_name = dev_name(&cpu_pdev->dev);
+ imx_ak4458_dai.platform_of_node = cpu_np;
+
+ priv->card.num_links = 1;
+ priv->card.dai_link = &imx_ak4458_dai;
+ priv->card.dev = &pdev->dev;
+ priv->card.owner = THIS_MODULE;
+ priv->card.dapm_widgets = imx_ak4458_dapm_widgets;
+ priv->card.num_dapm_widgets = ARRAY_SIZE(imx_ak4458_dapm_widgets);
+ priv->card.codec_conf = priv->codec_conf;
+ priv->card.num_configs = priv->num_codec_conf;
+ priv->one2one_ratio = !of_device_is_compatible(pdev->dev.of_node,
+ "fsl,imx-audio-ak4458-mq");
+
+ priv->pdn_gpio = of_get_named_gpio(pdev->dev.of_node, "ak4458,pdn-gpio", 0);
+ if (gpio_is_valid(priv->pdn_gpio)) {
+ ret = devm_gpio_request_one(&pdev->dev, priv->pdn_gpio,
+ GPIOF_OUT_INIT_LOW, "ak4458,pdn");
+ if (ret) {
+ dev_err(&pdev->dev, "unable to get pdn gpio\n");
+ goto fail;
+ }
+
+ gpio_set_value_cansleep(priv->pdn_gpio, 0);
+ usleep_range(1000, 2000);
+ gpio_set_value_cansleep(priv->pdn_gpio, 1);
+ usleep_range(1000, 2000);
+ }
+
+ ret = snd_soc_of_parse_card_name(&priv->card, "model");
+ if (ret)
+ goto fail;
+
+ snd_soc_card_set_drvdata(&priv->card, priv);
+
+ ret = devm_snd_soc_register_card(&pdev->dev, &priv->card);
+ if (ret) {
+ dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret);
+ goto fail;
+ }
+
+ ret = 0;
+fail:
+ if (cpu_np)
+ of_node_put(cpu_np);
+ if (codec_np_0)
+ of_node_put(codec_np_0);
+ if (codec_np_1)
+ of_node_put(codec_np_1);
+
+ return ret;
+}
+
+static const struct of_device_id imx_ak4458_dt_ids[] = {
+ { .compatible = "fsl,imx-audio-ak4458", },
+ { .compatible = "fsl,imx-audio-ak4458-mq", },
+ { },
+};
+MODULE_DEVICE_TABLE(of, imx_ak4458_dt_ids);
+
+static struct platform_driver imx_ak4458_driver = {
+ .driver = {
+ .name = "imx-ak4458",
+ .pm = &snd_soc_pm_ops,
+ .of_match_table = imx_ak4458_dt_ids,
+ },
+ .probe = imx_ak4458_probe,
+};
+module_platform_driver(imx_ak4458_driver);
+
+MODULE_AUTHOR("Mihai Serban <mihai.serban@nxp.com>");
+MODULE_DESCRIPTION("Freescale i.MX AK4458 ASoC machine driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:imx-ak4458");
diff --git a/sound/soc/fsl/imx-ak4497.c b/sound/soc/fsl/imx-ak4497.c
new file mode 100644
index 000000000000..9acfa84bf3d1
--- /dev/null
+++ b/sound/soc/fsl/imx-ak4497.c
@@ -0,0 +1,265 @@
+/* i.MX AK4458 audio support
+ *
+ * Copyright 2017 NXP
+ *
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/clk.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/gpio/consumer.h>
+#include <linux/of_device.h>
+#include <sound/soc.h>
+#include <sound/pcm_params.h>
+#include <sound/soc-dapm.h>
+
+#include "../codecs/ak4497.h"
+#include "fsl_sai.h"
+
+struct imx_ak4497_data {
+ struct snd_soc_card card;
+ bool one2one_ratio;
+};
+
+static struct snd_soc_dapm_widget imx_ak4497_dapm_widgets[] = {
+ SND_SOC_DAPM_LINE("Line Out", NULL),
+};
+
+static const struct imx_ak4497_fs_mul {
+ unsigned int min;
+ unsigned int max;
+ unsigned int mul;
+} fs_mul[] = {
+ /**
+ * Table 7 - mapping multiplier and speed mode
+ * Tables 8 & 9 - mapping speed mode and LRCK fs
+ */
+ { .min = 8000, .max = 32000, .mul = 1024 }, /* Normal, <= 32kHz */
+ { .min = 44100, .max = 48000, .mul = 512 }, /* Normal */
+ { .min = 88200, .max = 96000, .mul = 256 }, /* Double */
+ { .min = 176400, .max = 192000, .mul = 128 }, /* Quad */
+ { .min = 352800, .max = 384000, .mul = 2*64 }, /* Oct */
+ { .min = 705600, .max = 768000, .mul = 2*32 }, /* Hex */
+};
+
+static bool imx_ak4497_is_dsd(struct snd_pcm_hw_params *params)
+{
+ snd_pcm_format_t format = params_format(params);
+
+ switch (format) {
+ case SNDRV_PCM_FORMAT_DSD_U8:
+ case SNDRV_PCM_FORMAT_DSD_U16_LE:
+ case SNDRV_PCM_FORMAT_DSD_U16_BE:
+ case SNDRV_PCM_FORMAT_DSD_U32_LE:
+ case SNDRV_PCM_FORMAT_DSD_U32_BE:
+ return true;
+ default:
+ return false;
+ }
+}
+
+static unsigned long imx_ak4497_compute_freq(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ unsigned int rate = params_rate(params);
+ int i;
+
+ /* Find the appropriate MCLK freq */
+ for (i = 0; i < ARRAY_SIZE(fs_mul); i++) {
+ if (rate >= fs_mul[i].min && rate <= fs_mul[i].max)
+ return rate * fs_mul[i].mul;
+ }
+
+ /* Let DAI manage MCLK frequency */
+ return 0;
+}
+
+static int imx_aif_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+ struct snd_soc_dai *codec_dai = rtd->codec_dai;
+ struct snd_soc_card *card = rtd->card;
+ struct device *dev = card->dev;
+ struct imx_ak4497_data *priv = snd_soc_card_get_drvdata(card);
+ unsigned int channels = params_channels(params);
+ unsigned int fmt = SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS;
+ unsigned long freq = imx_ak4497_compute_freq(substream, params);
+ bool is_dsd = imx_ak4497_is_dsd(params);
+ int ret;
+
+ fmt |= (is_dsd ? SND_SOC_DAIFMT_PDM : SND_SOC_DAIFMT_I2S);
+
+ if (is_dsd && freq > 22579200 && priv->one2one_ratio)
+ freq = 22579200;
+
+ ret = snd_soc_dai_set_sysclk(cpu_dai, FSL_SAI_CLK_MAST1, freq,
+ SND_SOC_CLOCK_OUT);
+ if (ret < 0) {
+ dev_err(dev, "failed to set cpu dai mclk1 rate(%lu): %d\n",
+ freq, ret);
+ return ret;
+ }
+
+ ret = snd_soc_dai_set_fmt(cpu_dai, fmt);
+ if (ret) {
+ dev_err(dev, "failed to set cpu dai fmt: %d\n", ret);
+ return ret;
+ }
+
+ ret = snd_soc_dai_set_fmt(codec_dai, fmt);
+ if (ret) {
+ dev_err(dev, "failed to set codec dai fmt: %d\n", ret);
+ return ret;
+ }
+
+ if (is_dsd)
+ ret = snd_soc_dai_set_tdm_slot(cpu_dai,
+ 0x1, 0x1,
+ 1, params_width(params));
+ else
+ ret = snd_soc_dai_set_tdm_slot(cpu_dai,
+ BIT(channels) - 1, BIT(channels) - 1,
+ 2, params_physical_width(params));
+ if (ret) {
+ dev_err(dev, "failed to set cpu dai tdm slot: %d\n", ret);
+ return ret;
+ }
+
+ return ret;
+}
+
+static const u32 support_rates[] = {
+ 8000, 11025, 16000, 22050,
+ 32000, 44100, 48000, 88200,
+ 96000, 176400, 192000, 352800,
+ 384000, 705600, 768000,
+};
+
+static int imx_aif_startup(struct snd_pcm_substream *substream)
+{
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ int ret = 0;
+ static struct snd_pcm_hw_constraint_list constraint_rates;
+
+ constraint_rates.list = support_rates;
+ constraint_rates.count = ARRAY_SIZE(support_rates);
+
+ ret = snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
+ &constraint_rates);
+ if (ret)
+ return ret;
+
+ return ret;
+}
+
+static struct snd_soc_ops imx_aif_ops = {
+ .startup = imx_aif_startup,
+ .hw_params = imx_aif_hw_params,
+};
+
+static struct snd_soc_dai_link imx_ak4497_dai = {
+ .name = "ak4497",
+ .stream_name = "Audio",
+ .codec_dai_name = "ak4497-aif",
+ .ops = &imx_aif_ops,
+ .playback_only = 1,
+};
+
+static int imx_ak4497_probe(struct platform_device *pdev)
+{
+ struct imx_ak4497_data *priv;
+ struct device_node *cpu_np, *codec_np = NULL;
+ struct platform_device *cpu_pdev;
+ int ret;
+
+ priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ cpu_np = of_parse_phandle(pdev->dev.of_node, "audio-cpu", 0);
+ if (!cpu_np) {
+ dev_err(&pdev->dev, "audio dai phandle missing or invalid\n");
+ ret = -EINVAL;
+ goto fail;
+ }
+
+ codec_np = of_parse_phandle(pdev->dev.of_node, "audio-codec", 0);
+ if (!codec_np) {
+ dev_err(&pdev->dev, "audio codec phandle missing or invalid\n");
+ ret = -EINVAL;
+ goto fail;
+ }
+
+ cpu_pdev = of_find_device_by_node(cpu_np);
+ if (!cpu_pdev) {
+ dev_err(&pdev->dev, "failed to find SAI platform device\n");
+ ret = -EINVAL;
+ goto fail;
+ }
+
+ imx_ak4497_dai.codec_of_node = codec_np;
+ imx_ak4497_dai.cpu_dai_name = dev_name(&cpu_pdev->dev);
+ imx_ak4497_dai.platform_of_node = cpu_np;
+ imx_ak4497_dai.playback_only = 1;
+
+ priv->card.dai_link = &imx_ak4497_dai;
+ priv->card.num_links = 1;
+ priv->card.dev = &pdev->dev;
+ priv->card.owner = THIS_MODULE;
+ priv->card.dapm_widgets = imx_ak4497_dapm_widgets;
+ priv->card.num_dapm_widgets = ARRAY_SIZE(imx_ak4497_dapm_widgets);
+ priv->one2one_ratio = !of_device_is_compatible(pdev->dev.of_node,
+ "fsl,imx-audio-ak4497-mq");
+
+ ret = snd_soc_of_parse_card_name(&priv->card, "model");
+ if (ret)
+ goto fail;
+
+ snd_soc_card_set_drvdata(&priv->card, priv);
+
+ ret = devm_snd_soc_register_card(&pdev->dev, &priv->card);
+ if (ret) {
+ dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret);
+ goto fail;
+ }
+
+ ret = 0;
+fail:
+ if (cpu_np)
+ of_node_put(cpu_np);
+ if (codec_np)
+ of_node_put(codec_np);
+
+ return ret;
+}
+
+static const struct of_device_id imx_ak4497_dt_ids[] = {
+ { .compatible = "fsl,imx-audio-ak4497", },
+ { .compatible = "fsl,imx-audio-ak4497-mq", },
+ { },
+};
+MODULE_DEVICE_TABLE(of, imx_ak4497_dt_ids);
+
+static struct platform_driver imx_ak4497_driver = {
+ .driver = {
+ .name = "imx-ak4497",
+ .pm = &snd_soc_pm_ops,
+ .of_match_table = imx_ak4497_dt_ids,
+ },
+ .probe = imx_ak4497_probe,
+};
+module_platform_driver(imx_ak4497_driver);
+
+MODULE_AUTHOR("Daniel Baluta <daniel.baluta@nxp.com>");
+MODULE_DESCRIPTION("Freescale i.MX AK4497 ASoC machine driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:imx-ak4497");
diff --git a/sound/soc/fsl/imx-ak5558.c b/sound/soc/fsl/imx-ak5558.c
new file mode 100644
index 000000000000..c500b75786ff
--- /dev/null
+++ b/sound/soc/fsl/imx-ak5558.c
@@ -0,0 +1,369 @@
+/* i.MX AK5558 audio support
+ *
+ * Copyright 2017 NXP
+ *
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/clk.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/gpio/consumer.h>
+#include <linux/of_device.h>
+#include <sound/soc.h>
+#include <sound/pcm_params.h>
+#include <sound/pcm.h>
+#include <sound/soc-dapm.h>
+
+#include "fsl_sai.h"
+#include "../codecs/ak5558.h"
+
+
+struct imx_ak5558_data {
+ struct snd_soc_card card;
+ bool tdm_mode;
+ unsigned long slots;
+ unsigned long slot_width;
+ bool one2one_ratio;
+};
+
+/*
+ * imx_ack5558_fs_mul - sampling frequency multiplier
+ *
+ * min <= fs <= max, MCLK = mul * LRCK
+ */
+struct imx_ak5558_fs_mul {
+ unsigned int min;
+ unsigned int max;
+ unsigned int mul;
+};
+
+/*
+ * Auto MCLK selection based on LRCK for Normal Mode
+ * (Table 4 from datasheet)
+ */
+static const struct imx_ak5558_fs_mul fs_mul[] = {
+ { .min = 8000, .max = 32000, .mul = 1024 },
+ { .min = 44100, .max = 48000, .mul = 512 },
+ { .min = 88200, .max = 96000, .mul = 256 },
+ { .min = 176400, .max = 192000, .mul = 128 },
+ { .min = 352800, .max = 384000, .mul = 64 },
+ { .min = 705600, .max = 768000, .mul = 32 },
+};
+
+/*
+ * MCLK and BCLK selection based on TDM mode
+ * because of SAI we also add the restriction: MCLK >= 2 * BCLK
+ * (Table 9 from datasheet)
+ */
+static const struct imx_ak5558_fs_mul fs_mul_tdm[] = {
+ { .min = 128, .max = 128, .mul = 256 },
+ { .min = 256, .max = 256, .mul = 512 },
+ { .min = 512, .max = 512, .mul = 1024 },
+};
+
+static struct snd_soc_dapm_widget imx_ak5558_dapm_widgets[] = {
+ SND_SOC_DAPM_LINE("Line In", NULL),
+};
+
+static const u32 ak5558_rates[] = {
+ 8000, 11025, 16000, 22050,
+ 32000, 44100, 48000, 88200,
+ 96000, 176400, 192000, 352800,
+ 384000, 705600, 768000,
+};
+
+static const u32 ak5558_tdm_rates[] = {
+ 8000, 16000, 32000,
+ 48000, 96000
+};
+
+static const u32 ak5558_channels[] = {
+ 1, 2, 4, 6, 8,
+};
+
+static unsigned long ak5558_get_mclk_rate(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct imx_ak5558_data *data = snd_soc_card_get_drvdata(rtd->card);
+ unsigned int rate = params_rate(params);
+ unsigned int freq = 0; /* Let DAI manage clk frequency by default */
+ int mode;
+ int i;
+
+ if (data->tdm_mode) {
+ mode = data->slots * data->slot_width;
+
+ for (i = 0; i < ARRAY_SIZE(fs_mul_tdm); i++) {
+ /* min = max = slots * slots_width */
+ if (mode != fs_mul_tdm[i].min)
+ continue;
+ freq = rate * fs_mul_tdm[i].mul;
+ break;
+ }
+ } else {
+ for (i = 0; i < ARRAY_SIZE(fs_mul); i++) {
+ if (rate < fs_mul[i].min || rate > fs_mul[i].max)
+ continue;
+ freq = rate * fs_mul[i].mul;
+ break;
+ }
+ }
+
+ return freq;
+}
+
+static int imx_aif_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+ struct snd_soc_dai *codec_dai = rtd->codec_dai;
+ struct snd_soc_card *card = rtd->card;
+ struct device *dev = card->dev;
+ struct imx_ak5558_data *data = snd_soc_card_get_drvdata(card);
+ unsigned int channels = params_channels(params);
+ unsigned long mclk_freq;
+ unsigned int fmt;
+ int ret;
+
+ if (data->tdm_mode)
+ fmt = SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_NB_NF |
+ SND_SOC_DAIFMT_CBS_CFS;
+ else
+ fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
+ SND_SOC_DAIFMT_CBS_CFS;
+
+ ret = snd_soc_dai_set_fmt(cpu_dai, fmt);
+ if (ret) {
+ dev_err(dev, "failed to set cpu dai fmt: %d\n", ret);
+ return ret;
+ }
+
+ ret = snd_soc_dai_set_fmt(codec_dai, fmt);
+ if (ret) {
+ dev_err(dev, "failed to set codec dai fmt: %d\n", ret);
+ return ret;
+ }
+
+ if (data->tdm_mode) {
+ /* support TDM256 (8 slots * 32 bits/per slot) */
+ data->slots = 8;
+ data->slot_width = 32;
+
+ ret = snd_soc_dai_set_tdm_slot(cpu_dai,
+ BIT(channels) - 1, BIT(channels) - 1,
+ data->slots, data->slot_width);
+ if (ret) {
+ dev_err(dev, "failed to set cpu dai tdm slot: %d\n", ret);
+ return ret;
+ }
+
+ ret = snd_soc_dai_set_tdm_slot(codec_dai,
+ BIT(channels) - 1, BIT(channels) - 1,
+ 8, 32);
+ if (ret) {
+ dev_err(dev, "failed to set codec dai fmt: %d\n", ret);
+ return ret;
+ }
+ } else {
+ /* normal mode (I2S) */
+ data->slots = 2;
+ data->slot_width = params_physical_width(params);
+
+ ret = snd_soc_dai_set_tdm_slot(cpu_dai,
+ BIT(channels) - 1, BIT(channels) - 1,
+ data->slots, data->slot_width);
+ if (ret) {
+ dev_err(dev, "failed to set cpu dai tdm slot: %d\n", ret);
+ return ret;
+ }
+ }
+
+ mclk_freq = ak5558_get_mclk_rate(substream, params);
+ ret = snd_soc_dai_set_sysclk(cpu_dai, FSL_SAI_CLK_MAST1, mclk_freq,
+ SND_SOC_CLOCK_OUT);
+ if (ret < 0)
+ dev_err(dev, "failed to set cpu_dai mclk1 rate %lu\n",
+ mclk_freq);
+
+ return ret;
+}
+
+static int imx_ak5558_hw_rule_rate(struct snd_pcm_hw_params *p,
+ struct snd_pcm_hw_rule *r)
+{
+ struct imx_ak5558_data *data = r->private;
+ struct snd_interval t = { .min = 8000, .max = 8000, };
+ unsigned int fs;
+ unsigned long mclk_freq;
+ int i;
+
+ fs = hw_param_interval(p, SNDRV_PCM_HW_PARAM_SAMPLE_BITS)->min;
+ fs *= data->tdm_mode ? 8 : 2;
+
+ /* Identify maximum supported rate */
+ for (i = 0; i < ARRAY_SIZE(ak5558_rates); i++) {
+ mclk_freq = fs * ak5558_rates[i];
+ /* Adjust SAI bclk:mclk ratio */
+ mclk_freq *= data->one2one_ratio ? 1 : 2;
+
+ /* Skip rates for which MCLK is beyond supported value */
+ if (mclk_freq > 36864000)
+ continue;
+
+ if (t.max < ak5558_rates[i])
+ t.max = ak5558_rates[i];
+ }
+
+ return snd_interval_refine(hw_param_interval(p, r->var), &t);
+}
+
+static int imx_aif_startup(struct snd_pcm_substream *substream)
+{
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_card *card = rtd->card;
+ struct imx_ak5558_data *data = snd_soc_card_get_drvdata(card);
+
+ static struct snd_pcm_hw_constraint_list constraint_rates;
+ static struct snd_pcm_hw_constraint_list constraint_channels;
+ int ret;
+
+ if (data->tdm_mode) {
+ constraint_rates.list = ak5558_tdm_rates;
+ constraint_rates.count = ARRAY_SIZE(ak5558_tdm_rates);
+ } else {
+ constraint_rates.list = ak5558_rates;
+ constraint_rates.count = ARRAY_SIZE(ak5558_rates);
+ }
+
+ ret = snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
+ &constraint_rates);
+ if (ret)
+ return ret;
+
+ constraint_channels.list = ak5558_channels;
+ constraint_channels.count = ARRAY_SIZE(ak5558_channels);
+ ret = snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
+ &constraint_channels);
+ if (ret < 0)
+ return ret;
+
+ return snd_pcm_hw_rule_add(substream->runtime, 0,
+ SNDRV_PCM_HW_PARAM_RATE, imx_ak5558_hw_rule_rate, data,
+ SNDRV_PCM_HW_PARAM_SAMPLE_BITS, -1);
+}
+
+static struct snd_soc_ops imx_aif_ops = {
+ .hw_params = imx_aif_hw_params,
+ .startup = imx_aif_startup,
+};
+
+static struct snd_soc_dai_link imx_ak5558_dai = {
+ .name = "ak5558",
+ .stream_name = "Audio",
+ .codec_dai_name = "ak5558-aif",
+ .ops = &imx_aif_ops,
+ .capture_only = 1,
+};
+
+static int imx_ak5558_probe(struct platform_device *pdev)
+{
+ struct imx_ak5558_data *priv;
+ struct device_node *cpu_np, *codec_np = NULL;
+ struct platform_device *cpu_pdev;
+ int ret;
+
+ priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ cpu_np = of_parse_phandle(pdev->dev.of_node, "audio-cpu", 0);
+ if (!cpu_np) {
+ dev_err(&pdev->dev, "audio dai phandle missing or invalid\n");
+ ret = -EINVAL;
+ goto fail;
+ }
+
+ codec_np = of_parse_phandle(pdev->dev.of_node, "audio-codec", 0);
+ if (!codec_np) {
+ dev_err(&pdev->dev, "audio codec phandle missing or invalid\n");
+ ret = -EINVAL;
+ goto fail;
+ }
+
+ cpu_pdev = of_find_device_by_node(cpu_np);
+ if (!cpu_pdev) {
+ dev_err(&pdev->dev, "failed to find SAI platform device\n");
+ ret = -EINVAL;
+ goto fail;
+ }
+
+ if (of_find_property(pdev->dev.of_node, "fsl,tdm", NULL))
+ priv->tdm_mode = true;
+
+ imx_ak5558_dai.codec_of_node = codec_np;
+ imx_ak5558_dai.cpu_dai_name = dev_name(&cpu_pdev->dev);
+ imx_ak5558_dai.platform_of_node = cpu_np;
+ imx_ak5558_dai.capture_only = 1;
+
+ priv->card.dai_link = &imx_ak5558_dai;
+ priv->card.num_links = 1;
+ priv->card.dev = &pdev->dev;
+ priv->card.owner = THIS_MODULE;
+ priv->card.dapm_widgets = imx_ak5558_dapm_widgets;
+ priv->card.num_dapm_widgets = ARRAY_SIZE(imx_ak5558_dapm_widgets);
+ priv->one2one_ratio = !of_device_is_compatible(pdev->dev.of_node,
+ "fsl,imx-audio-ak5558-mq");
+
+ ret = snd_soc_of_parse_card_name(&priv->card, "model");
+ if (ret)
+ goto fail;
+
+ snd_soc_card_set_drvdata(&priv->card, priv);
+
+ ret = devm_snd_soc_register_card(&pdev->dev, &priv->card);
+ if (ret) {
+ dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret);
+ goto fail;
+ }
+
+ ret = 0;
+fail:
+ if (cpu_np)
+ of_node_put(cpu_np);
+ if (codec_np)
+ of_node_put(codec_np);
+
+ return ret;
+}
+
+static const struct of_device_id imx_ak5558_dt_ids[] = {
+ { .compatible = "fsl,imx-audio-ak5558", },
+ { .compatible = "fsl,imx-audio-ak5558-mq", },
+ { },
+};
+MODULE_DEVICE_TABLE(of, imx_ak5558_dt_ids);
+
+static struct platform_driver imx_ak5558_driver = {
+ .driver = {
+ .name = "imx-ak5558",
+ .pm = &snd_soc_pm_ops,
+ .of_match_table = imx_ak5558_dt_ids,
+ },
+ .probe = imx_ak5558_probe,
+};
+module_platform_driver(imx_ak5558_driver);
+
+MODULE_AUTHOR("Mihai Serban <mihai.serban@nxp.com>");
+MODULE_DESCRIPTION("Freescale i.MX AK5558 ASoC machine driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:imx-ak5558");
diff --git a/sound/soc/fsl/imx-amix.c b/sound/soc/fsl/imx-amix.c
new file mode 100644
index 000000000000..5ba61f598aee
--- /dev/null
+++ b/sound/soc/fsl/imx-amix.c
@@ -0,0 +1,329 @@
+/*
+ * Copyright 2017 NXP
+ *
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/module.h>
+#include <linux/of_platform.h>
+#include <linux/clk.h>
+#include <sound/soc.h>
+#include <sound/soc-dapm.h>
+#include <linux/pm_runtime.h>
+#include "fsl_sai.h"
+#include "fsl_amix.h"
+
+struct imx_amix {
+ struct platform_device *pdev;
+ struct snd_soc_card card;
+ struct platform_device *amix_pdev;
+ struct platform_device *out_pdev;
+ struct clk *cpu_mclk;
+ int num_dai;
+ struct snd_soc_dai_link *dai;
+ int num_dai_conf;
+ struct snd_soc_codec_conf *dai_conf;
+ int num_dapm_routes;
+ struct snd_soc_dapm_route *dapm_routes;
+};
+
+static const u32 imx_amix_rates[] = {
+ 8000, 12000, 16000, 24000, 32000, 48000, 64000, 96000,
+};
+
+static const struct snd_pcm_hw_constraint_list imx_amix_rate_constraints = {
+ .count = ARRAY_SIZE(imx_amix_rates),
+ .list = imx_amix_rates,
+};
+
+static int imx_amix_fe_startup(struct snd_pcm_substream *substream)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct imx_amix *priv = snd_soc_card_get_drvdata(rtd->card);
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct device *dev = rtd->card->dev;
+ unsigned long clk_rate = clk_get_rate(priv->cpu_mclk);
+ int ret;
+
+ if (clk_rate % 24576000 == 0) {
+ ret = snd_pcm_hw_constraint_list(runtime, 0,
+ SNDRV_PCM_HW_PARAM_RATE, &imx_amix_rate_constraints);
+ if (ret < 0)
+ return ret;
+ } else
+ dev_warn(dev, "mclk may be not supported %lu\n", clk_rate);
+
+ ret = snd_pcm_hw_constraint_minmax(runtime,
+ SNDRV_PCM_HW_PARAM_CHANNELS, 1, 8);
+ if (ret < 0)
+ return ret;
+
+ return snd_pcm_hw_constraint_mask64(runtime,
+ SNDRV_PCM_HW_PARAM_FORMAT, FSL_AMIX_FORMATS);
+}
+
+static int imx_amix_fe_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct device *dev = rtd->card->dev;
+ bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
+ unsigned int fmt = SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_NB_NF;
+ u32 channels = params_channels(params);
+ int ret, dir;
+
+ /* For playback the AMIX is slave, and for record is master */
+ fmt |= tx ? SND_SOC_DAIFMT_CBS_CFS : SND_SOC_DAIFMT_CBM_CFM;
+ dir = tx ? SND_SOC_CLOCK_OUT : SND_SOC_CLOCK_IN;
+
+ /* set cpu DAI configuration */
+ ret = snd_soc_dai_set_fmt(rtd->cpu_dai, fmt);
+ if (ret) {
+ dev_err(dev, "failed to set cpu dai fmt: %d\n", ret);
+ return ret;
+ }
+
+ /* Specific configurations of DAIs starts from here */
+ ret = snd_soc_dai_set_sysclk(rtd->cpu_dai, FSL_SAI_CLK_MAST1, 0, dir);
+ if (ret) {
+ dev_err(dev, "failed to set cpu sysclk: %d\n", ret);
+ return ret;
+ }
+
+ /*
+ * Per datasheet, AMIX expects 8 slots and 32 bits
+ * for every slot in TDM mode.
+ */
+ ret = snd_soc_dai_set_tdm_slot(rtd->cpu_dai, BIT(channels) - 1,
+ BIT(channels) - 1, 8, 32);
+ if (ret)
+ dev_err(dev, "failed to set cpu dai tdm slot: %d\n", ret);
+
+ return ret;
+}
+
+static int imx_amix_be_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct device *dev = rtd->card->dev;
+ bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
+ unsigned int fmt = SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_NB_NF;
+ int ret;
+
+ if (!tx)
+ return 0;
+
+ /* For playback the AMIX is slave */
+ fmt |= SND_SOC_DAIFMT_CBM_CFM;
+
+ /* set AMIX DAI configuration */
+ ret = snd_soc_dai_set_fmt(rtd->cpu_dai, fmt);
+ if (ret)
+ dev_err(dev, "failed to set AMIX DAI fmt: %d\n", ret);
+
+ return ret;
+}
+
+static struct snd_soc_ops imx_amix_fe_ops = {
+ .startup = imx_amix_fe_startup,
+ .hw_params = imx_amix_fe_hw_params,
+};
+
+static struct snd_soc_ops imx_amix_be_ops = {
+ .hw_params = imx_amix_be_hw_params,
+};
+
+static int imx_amix_probe(struct platform_device *pdev)
+{
+ struct device_node *np = pdev->dev.of_node;
+ struct device_node *amix_np = NULL, *out_cpu_np = NULL;
+ struct platform_device *amix_pdev = NULL;
+ struct platform_device *cpu_pdev;
+ struct of_phandle_args args;
+ struct imx_amix *priv;
+ int i, num_dai, ret;
+ const char *fe_name_pref = "HiFi-AMIX-FE-";
+ char *be_name, *be_pb, *be_cp, *dai_name, *capture_dai_name;
+
+ num_dai = of_count_phandle_with_args(np, "dais", NULL);
+ if (num_dai != FSL_AMIX_MAX_DAIS) {
+ dev_err(&pdev->dev, "Need 2 dais to be provided for %s\n",
+ np->full_name);
+ return -EINVAL;
+ }
+
+ amix_np = of_parse_phandle(np, "amix-controller", 0);
+ if (!amix_np) {
+ dev_err(&pdev->dev, "Missing amix-controller phandle at %s\n",
+ np->full_name);
+ return -EINVAL;
+ }
+
+ amix_pdev = of_find_device_by_node(amix_np);
+ if (!amix_pdev) {
+ dev_err(&pdev->dev, "Missing AMIX platform device for %s\n",
+ np->full_name);
+ return -EINVAL;
+ }
+
+ priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ priv->num_dai = 2 * num_dai;
+ priv->dai = devm_kzalloc(&pdev->dev,
+ priv->num_dai * sizeof(struct snd_soc_dai_link),
+ GFP_KERNEL);
+ if (!priv->dai)
+ return -ENOMEM;
+
+ priv->num_dai_conf = num_dai;
+ priv->dai_conf = devm_kzalloc(&pdev->dev,
+ priv->num_dai_conf * sizeof(struct snd_soc_codec_conf),
+ GFP_KERNEL);
+ if (!priv->dai_conf)
+ return -ENOMEM;
+
+ priv->num_dapm_routes = 3 * num_dai;
+ priv->dapm_routes = devm_kzalloc(&pdev->dev,
+ priv->num_dapm_routes * sizeof(struct snd_soc_dapm_route),
+ GFP_KERNEL);
+ if (!priv->dapm_routes)
+ return -ENOMEM;
+
+ for (i = 0; i < num_dai; i++) {
+ ret = of_parse_phandle_with_args(np, "dais", NULL, i, &args);
+ if (ret < 0) {
+ dev_err(&pdev->dev,
+ "of_parse_phandle_with_args failed (%d)\n", ret);
+ return ret;
+ }
+
+ cpu_pdev = of_find_device_by_node(args.np);
+ if (!cpu_pdev) {
+ dev_err(&pdev->dev, "failed to find SAI platform device\n");
+ return -EINVAL;
+ }
+
+ dai_name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "%s%s",
+ fe_name_pref, args.np->full_name + 1);
+
+ dev_info(&pdev->dev, "DAI FE name:%s\n", dai_name);
+
+ if (i == 0) {
+ out_cpu_np = args.np;
+ capture_dai_name =
+ devm_kasprintf(&pdev->dev, GFP_KERNEL, "%s %s",
+ dai_name, "CPU-Capture");
+ }
+
+ priv->dai[i].name = dai_name;
+ priv->dai[i].stream_name = "HiFi-AMIX-FE";
+ priv->dai[i].codec_dai_name = "snd-soc-dummy-dai";
+ priv->dai[i].codec_name = "snd-soc-dummy";
+ priv->dai[i].cpu_of_node = args.np;
+ priv->dai[i].cpu_dai_name = dev_name(&cpu_pdev->dev);
+ priv->dai[i].platform_of_node = args.np;
+ priv->dai[i].dynamic = 1;
+ priv->dai[i].dpcm_playback = 1;
+ priv->dai[i].dpcm_capture = (i == 0 ? 1 : 0);
+ priv->dai[i].ignore_pmdown_time = 1;
+ priv->dai[i].ops = &imx_amix_fe_ops;
+
+ /* Add AMIX Backend */
+ be_name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "amix-%d", i);
+ be_pb = devm_kasprintf(&pdev->dev, GFP_KERNEL, "AMIX-Playback-%d", i);
+ be_cp = devm_kasprintf(&pdev->dev, GFP_KERNEL, "AMIX-Capture-%d", i);
+
+ priv->dai[num_dai+i].name = be_name;
+ priv->dai[num_dai+i].codec_dai_name = "snd-soc-dummy-dai";
+ priv->dai[num_dai+i].codec_name = "snd-soc-dummy";
+ priv->dai[num_dai+i].cpu_of_node = amix_np;
+ priv->dai[num_dai+i].cpu_dai_name = be_name;
+ priv->dai[num_dai+i].platform_name = "snd-soc-dummy";
+ priv->dai[num_dai+i].no_pcm = 1;
+ priv->dai[num_dai+i].dpcm_playback = 1;
+ priv->dai[num_dai+i].dpcm_capture = 1;
+ priv->dai[num_dai+i].ignore_pmdown_time = 1;
+ priv->dai[num_dai+i].ops = &imx_amix_be_ops;
+
+ priv->dai_conf[i].of_node = args.np;
+ priv->dai_conf[i].name_prefix = dai_name;
+
+ priv->dapm_routes[i].source = devm_kasprintf(&pdev->dev,
+ GFP_KERNEL, "%s %s", dai_name, "CPU-Playback");
+ priv->dapm_routes[i].sink = be_pb;
+ priv->dapm_routes[num_dai+i].source = be_pb;
+ priv->dapm_routes[num_dai+i].sink = be_cp;
+ priv->dapm_routes[2*num_dai+i].source = be_cp;
+ priv->dapm_routes[2*num_dai+i].sink = capture_dai_name;
+ }
+
+ cpu_pdev = of_find_device_by_node(out_cpu_np);
+ if (!cpu_pdev) {
+ dev_err(&pdev->dev, "failed to find SAI platform device\n");
+ return -EINVAL;
+ }
+ priv->cpu_mclk = devm_clk_get(&cpu_pdev->dev, "mclk1");
+ if (IS_ERR(priv->cpu_mclk)) {
+ ret = PTR_ERR(priv->cpu_mclk);
+ dev_err(&cpu_pdev->dev, "failed to get DAI mclk1: %d\n", ret);
+ return -EINVAL;
+ }
+
+ priv->amix_pdev = amix_pdev;
+ priv->out_pdev = cpu_pdev;
+
+ priv->card.dai_link = priv->dai;
+ priv->card.num_links = priv->num_dai;
+ priv->card.codec_conf = priv->dai_conf;
+ priv->card.num_configs = priv->num_dai_conf;
+ priv->card.dapm_routes = priv->dapm_routes;
+ priv->card.num_dapm_routes = priv->num_dapm_routes;
+ priv->card.dev = &pdev->dev;
+ priv->card.owner = THIS_MODULE;
+
+ ret = snd_soc_of_parse_card_name(&priv->card, "model");
+ if (ret) {
+ dev_err(&pdev->dev, "snd_soc_of_parse_card_name failed (%d)\n", ret);
+ return ret;
+ }
+
+ platform_set_drvdata(pdev, &priv->card);
+ snd_soc_card_set_drvdata(&priv->card, priv);
+
+ ret = devm_snd_soc_register_card(&pdev->dev, &priv->card);
+ if (ret) {
+ dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret);
+ return ret;
+ }
+
+ return ret;
+}
+
+static const struct of_device_id imx_amix_dt_ids[] = {
+ { .compatible = "fsl,imx-audio-amix", },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, imx_amix_dt_ids);
+
+static struct platform_driver imx_amix_driver = {
+ .probe = imx_amix_probe,
+ .driver = {
+ .name = "imx-amix",
+ .of_match_table = imx_amix_dt_ids,
+ .pm = &snd_soc_pm_ops,
+ },
+};
+module_platform_driver(imx_amix_driver);
+
+MODULE_DESCRIPTION("NXP AMIX ASoC machine driver");
+MODULE_AUTHOR("Viorel Suman <viorel.suman@nxp.com>");
+MODULE_ALIAS("platform:imx-amix");
+MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/fsl/imx-audmux.c b/sound/soc/fsl/imx-audmux.c
index 99e07b01a2ce..f01a13ee02aa 100644
--- a/sound/soc/fsl/imx-audmux.c
+++ b/sound/soc/fsl/imx-audmux.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2012 Freescale Semiconductor, Inc.
+ * Copyright 2012-2015 Freescale Semiconductor, Inc.
* Copyright 2012 Linaro Ltd.
* Copyright 2009 Pengutronix, Sascha Hauer <s.hauer@pengutronix.de>
*
@@ -33,6 +33,8 @@
static struct clk *audmux_clk;
static void __iomem *audmux_base;
+static u32 *regcache;
+static u32 reg_max;
#define IMX_AUDMUX_V2_PTCR(x) ((x) * 8)
#define IMX_AUDMUX_V2_PDCR(x) ((x) * 8 + 4)
@@ -333,8 +335,23 @@ static int imx_audmux_probe(struct platform_device *pdev)
if (of_id)
pdev->id_entry = of_id->data;
audmux_type = pdev->id_entry->driver_data;
- if (audmux_type == IMX31_AUDMUX)
+
+ switch (audmux_type) {
+ case IMX31_AUDMUX:
audmux_debugfs_init();
+ reg_max = 14;
+ break;
+ case IMX21_AUDMUX:
+ reg_max = 6;
+ break;
+ default:
+ dev_err(&pdev->dev, "unsupported version!\n");
+ return -EINVAL;
+ }
+
+ regcache = devm_kzalloc(&pdev->dev, sizeof(u32) * reg_max, GFP_KERNEL);
+ if (!regcache)
+ return -ENOMEM;
if (of_id)
imx_audmux_parse_dt_defaults(pdev, pdev->dev.of_node);
@@ -350,12 +367,47 @@ static int imx_audmux_remove(struct platform_device *pdev)
return 0;
}
+#ifdef CONFIG_PM_SLEEP
+static int imx_audmux_suspend(struct device *dev)
+{
+ int i;
+
+ clk_prepare_enable(audmux_clk);
+
+ for (i = 0; i < reg_max; i++)
+ regcache[i] = readl(audmux_base + i * 4);
+
+ clk_disable_unprepare(audmux_clk);
+
+ return 0;
+}
+
+static int imx_audmux_resume(struct device *dev)
+{
+ int i;
+
+ clk_prepare_enable(audmux_clk);
+
+ for (i = 0; i < reg_max; i++)
+ writel(regcache[i], audmux_base + i * 4);
+
+ clk_disable_unprepare(audmux_clk);
+
+ return 0;
+}
+#endif /* CONFIG_PM_SLEEP */
+
+static const struct dev_pm_ops imx_audmux_pm = {
+ SET_SYSTEM_SLEEP_PM_OPS(imx_audmux_suspend, imx_audmux_resume)
+};
+
static struct platform_driver imx_audmux_driver = {
.probe = imx_audmux_probe,
.remove = imx_audmux_remove,
.id_table = imx_audmux_ids,
.driver = {
.name = DRIVER_NAME,
+ .pm = &imx_audmux_pm,
.of_match_table = imx_audmux_dt_ids,
}
};
diff --git a/sound/soc/fsl/imx-cdnhdmi.c b/sound/soc/fsl/imx-cdnhdmi.c
new file mode 100644
index 000000000000..8dc9953a26a0
--- /dev/null
+++ b/sound/soc/fsl/imx-cdnhdmi.c
@@ -0,0 +1,549 @@
+/*
+ * Copyright 2017-2018 NXP
+ *
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/module.h>
+#include <linux/of_platform.h>
+#include <linux/i2c.h>
+#include <linux/of_gpio.h>
+#include <linux/slab.h>
+#include <linux/gpio.h>
+#include <linux/clk.h>
+#include <sound/soc.h>
+#include <sound/jack.h>
+#include <sound/control.h>
+#include <sound/pcm_params.h>
+#include <sound/soc-dapm.h>
+#include <sound/hdmi-codec.h>
+#include "../../../drivers/gpu/drm/imx/hdp/imx-hdp.h"
+#include "fsl_sai.h"
+
+#define SUPPORT_RATE_NUM 10
+#define SUPPORT_CHANNEL_NUM 10
+
+struct imx_cdnhdmi_data {
+ struct snd_soc_dai_link dai;
+ struct snd_soc_card card;
+ int protocol;
+ u32 support_rates[SUPPORT_RATE_NUM];
+ u32 support_rates_num;
+ u32 support_channels[SUPPORT_CHANNEL_NUM];
+ u32 support_channels_num;
+ u32 edid_rates[SUPPORT_RATE_NUM];
+ u32 edid_rates_count;
+ u32 edid_channels[SUPPORT_CHANNEL_NUM];
+ u32 edid_channels_count;
+ uint8_t eld[MAX_ELD_BYTES];
+};
+
+static int imx_cdnhdmi_startup(struct snd_pcm_substream *substream)
+{
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_card *card = rtd->card;
+ struct imx_cdnhdmi_data *data = snd_soc_card_get_drvdata(card);
+ static struct snd_pcm_hw_constraint_list constraint_rates;
+ static struct snd_pcm_hw_constraint_list constraint_channels;
+ int ret;
+
+ constraint_rates.list = data->support_rates;
+ constraint_rates.count = data->support_rates_num;
+
+ ret = snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
+ &constraint_rates);
+ if (ret)
+ return ret;
+
+ constraint_channels.list = data->support_channels;
+ constraint_channels.count = data->support_channels_num;
+
+ ret = snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
+ &constraint_channels);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+static int imx_cdnhdmi_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+ struct snd_soc_card *card = rtd->card;
+ struct device *dev = card->dev;
+ bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
+ int ret;
+
+ /* set cpu DAI configuration */
+ if (tx)
+ ret = snd_soc_dai_set_fmt(cpu_dai,
+ SND_SOC_DAIFMT_I2S |
+ SND_SOC_DAIFMT_NB_NF |
+ SND_SOC_DAIFMT_CBS_CFS);
+ else
+ ret = snd_soc_dai_set_fmt(cpu_dai,
+ SND_SOC_DAIFMT_I2S |
+ SND_SOC_DAIFMT_NB_NF |
+ SND_SOC_DAIFMT_CBM_CFM);
+
+ if (ret) {
+ dev_err(dev, "failed to set cpu dai fmt: %d\n", ret);
+ return ret;
+ }
+
+
+ if (of_device_is_compatible(dev->of_node,
+ "fsl,imx8mq-evk-cdnhdmi"))
+ ret = snd_soc_dai_set_sysclk(cpu_dai, FSL_SAI_CLK_MAST1,
+ 256 * params_rate(params),
+ SND_SOC_CLOCK_OUT);
+ else
+ ret = snd_soc_dai_set_sysclk(cpu_dai, 0,
+ 0,
+ tx ? SND_SOC_CLOCK_OUT : SND_SOC_CLOCK_IN);
+ if (ret) {
+ dev_err(dev, "failed to set cpu sysclk: %d\n", ret);
+ return ret;
+ }
+
+ ret = snd_soc_dai_set_tdm_slot(cpu_dai, 0, 0, 2, 32);
+ if (ret) {
+ dev_err(dev, "failed to set cpu dai tdm slot: %d\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static struct snd_soc_ops imx_cdnhdmi_ops = {
+ .startup = imx_cdnhdmi_startup,
+ .hw_params = imx_cdnhdmi_hw_params,
+};
+
+static const unsigned int eld_rates[] = {
+ 32000,
+ 44100,
+ 48000,
+ 88200,
+ 96000,
+ 176400,
+ 192000,
+};
+
+static unsigned int sad_max_channels(const u8 *sad)
+{
+ return 1 + (sad[0] & 7);
+}
+
+static int get_edid_info(struct snd_soc_card *card)
+{
+ struct snd_soc_pcm_runtime *rtd = list_first_entry(
+ &card->rtd_list, struct snd_soc_pcm_runtime, list);
+ struct snd_soc_dai *codec_dai = rtd->codec_dai;
+ struct snd_soc_codec *codec = codec_dai->codec;
+ struct hdmi_codec_pdata *hcd = codec->dev->platform_data;
+ struct imx_cdnhdmi_data *data = snd_soc_card_get_drvdata(card);
+ int i, j, ret;
+ const u8 *sad;
+ unsigned int channel_max = 0;
+ unsigned int rate_mask = 0;
+ unsigned int rate_mask_eld = 0;
+
+ ret = hcd->ops->get_eld(codec->dev->parent, hcd->data,
+ data->eld, sizeof(data->eld));
+ sad = drm_eld_sad(data->eld);
+ if (sad) {
+ for (j = 0; j < data->support_rates_num; j++) {
+ for (i = 0; i < ARRAY_SIZE(eld_rates); i++)
+ if (eld_rates[i] == data->support_rates[j])
+ rate_mask |= BIT(i);
+ }
+
+ for (i = drm_eld_sad_count(data->eld); i > 0; i--, sad += 3) {
+ if (rate_mask & sad[1])
+ channel_max = max(channel_max, sad_max_channels(sad));
+
+ if (sad_max_channels(sad) >= 2)
+ rate_mask_eld |= sad[1];
+ }
+ }
+
+ rate_mask = rate_mask & rate_mask_eld;
+
+ data->edid_rates_count = 0;
+ data->edid_channels_count = 0;
+
+ for (i = 0; i < ARRAY_SIZE(eld_rates); i++) {
+ if (rate_mask & BIT(i)) {
+ data->edid_rates[data->edid_rates_count] = eld_rates[i];
+ data->edid_rates_count++;
+ }
+ }
+
+ for (i = 0; i < data->support_channels_num; i++) {
+ if (data->support_channels[i] <= channel_max) {
+ data->edid_channels[data->edid_channels_count]
+ = data->support_channels[i];
+ data->edid_channels_count++;
+ }
+ }
+
+ return 0;
+}
+
+static int imx_cdnhdmi_channels_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
+{
+ struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
+ struct imx_cdnhdmi_data *data = snd_soc_card_get_drvdata(card);
+
+ get_edid_info(card);
+
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+ uinfo->count = data->edid_channels_count;
+
+ return 0;
+}
+
+static int imx_cdnhdmi_channels_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *uvalue)
+{
+ struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
+ struct imx_cdnhdmi_data *data = snd_soc_card_get_drvdata(card);
+ int i;
+
+ get_edid_info(card);
+
+ for (i = 0 ; i < data->edid_channels_count ; i++)
+ uvalue->value.integer.value[i] = data->edid_channels[i];
+
+ return 0;
+}
+
+static int imx_cdnhdmi_rates_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
+{
+ struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
+ struct imx_cdnhdmi_data *data = snd_soc_card_get_drvdata(card);
+
+ get_edid_info(card);
+
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+ uinfo->count = data->edid_rates_count;
+
+ return 0;
+}
+
+static int imx_cdnhdmi_rates_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *uvalue)
+{
+ struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
+ struct imx_cdnhdmi_data *data = snd_soc_card_get_drvdata(card);
+ int i;
+
+ get_edid_info(card);
+
+ for (i = 0 ; i < data->edid_rates_count; i++)
+ uvalue->value.integer.value[i] = data->edid_rates[i];
+
+ return 0;
+}
+
+static int imx_cdnhdmi_formats_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
+{
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+ uinfo->count = 3;
+
+ return 0;
+}
+
+static int imx_cdnhdmi_formats_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *uvalue)
+{
+ uvalue->value.integer.value[0] = 16;
+ uvalue->value.integer.value[1] = 24;
+ uvalue->value.integer.value[2] = 32;
+
+ return 0;
+}
+
+static int get_edid_rx_info(struct snd_soc_card *card)
+{
+ struct snd_soc_pcm_runtime *rtd = list_first_entry(
+ &card->rtd_list, struct snd_soc_pcm_runtime, list);
+ struct snd_soc_dai *codec_dai = rtd->codec_dai;
+ struct snd_soc_codec *codec = codec_dai->codec;
+ struct hdmi_codec_pdata *hcd = codec->dev->platform_data;
+ struct imx_cdnhdmi_data *data = snd_soc_card_get_drvdata(card);
+ int ret;
+
+ ret = hcd->ops->get_eld(codec->dev->parent, hcd->data,
+ data->eld, sizeof(data->eld));
+
+ if (ret)
+ return -EINVAL;
+
+ data->edid_rates[0] = data->eld[0] +
+ (data->eld[1] << 8) +
+ (data->eld[2] << 16) +
+ (data->eld[3] << 24);
+
+ data->edid_channels[0] = data->eld[4] +
+ (data->eld[5] << 8) +
+ (data->eld[6] << 16) +
+ (data->eld[7] << 24);
+
+
+ return 0;
+}
+
+static int imx_cdnhdmi_rx_channels_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
+{
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+ uinfo->count = 1;
+ uinfo->value.integer.min = 2;
+ uinfo->value.integer.max = 8;
+
+ return 0;
+}
+
+static int imx_cdnhdmi_rx_channels_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *uvalue)
+{
+ struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
+ struct imx_cdnhdmi_data *data = snd_soc_card_get_drvdata(card);
+ int ret;
+
+ ret = get_edid_rx_info(card);
+ if (ret)
+ return ret;
+ uvalue->value.integer.value[0] = data->edid_channels[0];
+
+ return 0;
+}
+
+static int imx_cdnhdmi_rx_rates_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
+{
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+ uinfo->count = 1;
+ uinfo->value.integer.min = 16000;
+ uinfo->value.integer.max = 192000;
+
+ return 0;
+}
+
+static int imx_cdnhdmi_rx_rates_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *uvalue)
+{
+ struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
+ struct imx_cdnhdmi_data *data = snd_soc_card_get_drvdata(card);
+ int ret;
+
+ ret = get_edid_rx_info(card);
+ if (ret)
+ return ret;
+
+ uvalue->value.integer.value[0] = data->edid_rates[0];
+
+ return 0;
+}
+
+static struct snd_kcontrol_new imx_cdnhdmi_ctrls[] = {
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "HDMI Support Channels",
+ .access = SNDRV_CTL_ELEM_ACCESS_READ |
+ SNDRV_CTL_ELEM_ACCESS_VOLATILE,
+ .info = imx_cdnhdmi_channels_info,
+ .get = imx_cdnhdmi_channels_get,
+ },
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "HDMI Support Rates",
+ .access = SNDRV_CTL_ELEM_ACCESS_READ |
+ SNDRV_CTL_ELEM_ACCESS_VOLATILE,
+ .info = imx_cdnhdmi_rates_info,
+ .get = imx_cdnhdmi_rates_get,
+ },
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "HDMI Support Formats",
+ .access = SNDRV_CTL_ELEM_ACCESS_READ |
+ SNDRV_CTL_ELEM_ACCESS_VOLATILE,
+ .info = imx_cdnhdmi_formats_info,
+ .get = imx_cdnhdmi_formats_get,
+ },
+};
+
+static struct snd_kcontrol_new imx_cdnhdmi_rx_ctrls[] = {
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "HDMI Rx Channels",
+ .access = SNDRV_CTL_ELEM_ACCESS_READ |
+ SNDRV_CTL_ELEM_ACCESS_VOLATILE,
+ .info = imx_cdnhdmi_rx_channels_info,
+ .get = imx_cdnhdmi_rx_channels_get,
+ },
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "HDMI Rx Rates",
+ .access = SNDRV_CTL_ELEM_ACCESS_READ |
+ SNDRV_CTL_ELEM_ACCESS_VOLATILE,
+ .info = imx_cdnhdmi_rx_rates_info,
+ .get = imx_cdnhdmi_rx_rates_get,
+ },
+};
+
+static int imx_cdnhdmi_probe(struct platform_device *pdev)
+{
+ struct device_node *cpu_np, *cdnhdmi_np = NULL;
+ struct platform_device *cpu_pdev;
+ struct imx_cdnhdmi_data *data;
+ int ret;
+ int i;
+
+ cpu_np = of_parse_phandle(pdev->dev.of_node, "audio-cpu", 0);
+ if (!cpu_np) {
+ dev_err(&pdev->dev, "cpu dai phandle missing or invalid\n");
+ ret = -EINVAL;
+ goto fail;
+ }
+
+ cpu_pdev = of_find_device_by_node(cpu_np);
+ if (!cpu_pdev) {
+ dev_err(&pdev->dev, "failed to find SAI platform device\n");
+ ret = -EINVAL;
+ goto fail;
+ }
+
+ data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
+ if (!data) {
+ ret = -ENOMEM;
+ goto fail;
+ }
+
+ for (i = 0; i < SUPPORT_RATE_NUM; i++) {
+ ret = of_property_read_u32_index(pdev->dev.of_node,
+ "constraint-rate",
+ i, &data->support_rates[i]);
+ if (!ret)
+ data->support_rates_num = i + 1;
+ else
+ break;
+ }
+
+ if (data->support_rates_num == 0) {
+ data->support_rates[0] = 48000;
+ data->support_rates[1] = 96000;
+ data->support_rates[2] = 32000;
+ data->support_rates[3] = 192000;
+ data->support_rates_num = 4;
+ }
+
+ data->support_channels[0] = 2;
+ data->support_channels[1] = 4;
+ data->support_channels[2] = 8;
+ data->support_channels_num = 3;
+
+ of_property_read_u32(pdev->dev.of_node, "protocol",
+ &data->protocol);
+
+ data->dai.name = "imx8 hdmi";
+ data->dai.stream_name = "imx8 hdmi";
+ data->dai.cpu_dai_name = dev_name(&cpu_pdev->dev);
+ data->dai.platform_of_node = cpu_np;
+ data->dai.ops = &imx_cdnhdmi_ops;
+ data->dai.playback_only = true;
+ data->dai.capture_only = false;
+ data->dai.dai_fmt = SND_SOC_DAIFMT_I2S |
+ SND_SOC_DAIFMT_NB_NF |
+ SND_SOC_DAIFMT_CBS_CFS;
+
+ if (of_property_read_bool(pdev->dev.of_node, "hdmi-out")) {
+ data->dai.playback_only = true;
+ data->dai.capture_only = false;
+ data->dai.dai_fmt = SND_SOC_DAIFMT_I2S |
+ SND_SOC_DAIFMT_NB_NF |
+ SND_SOC_DAIFMT_CBS_CFS;
+ data->dai.codec_dai_name = "i2s-hifi";
+ data->dai.codec_name = "hdmi-audio-codec.1";
+ data->card.controls = imx_cdnhdmi_ctrls;
+ data->card.num_controls = ARRAY_SIZE(imx_cdnhdmi_ctrls);
+ }
+
+ if (of_property_read_bool(pdev->dev.of_node, "hdmi-in")) {
+ data->dai.playback_only = false;
+ data->dai.capture_only = true;
+ data->dai.dai_fmt = SND_SOC_DAIFMT_I2S |
+ SND_SOC_DAIFMT_NB_NF |
+ SND_SOC_DAIFMT_CBM_CFM;
+ data->dai.codec_dai_name = "i2s-hifi";
+ data->dai.codec_name = "hdmi-audio-codec.2";
+ data->card.controls = imx_cdnhdmi_rx_ctrls;
+ data->card.num_controls = ARRAY_SIZE(imx_cdnhdmi_rx_ctrls);
+ }
+
+ if ((data->dai.playback_only && data->dai.capture_only)
+ || (!data->dai.playback_only && !data->dai.capture_only)) {
+ dev_err(&pdev->dev, "Wrongly enable HDMI DAI link\n");
+ goto fail;
+ }
+
+ data->card.dev = &pdev->dev;
+ data->card.owner = THIS_MODULE;
+ ret = snd_soc_of_parse_card_name(&data->card, "model");
+ if (ret)
+ goto fail;
+ data->card.num_links = 1;
+ data->card.dai_link = &data->dai;
+
+
+ platform_set_drvdata(pdev, &data->card);
+ snd_soc_card_set_drvdata(&data->card, data);
+ ret = devm_snd_soc_register_card(&pdev->dev, &data->card);
+ if (ret) {
+ dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret);
+ goto fail;
+ }
+
+fail:
+ if (cpu_np)
+ of_node_put(cpu_np);
+ if (cdnhdmi_np)
+ of_node_put(cdnhdmi_np);
+ return ret;
+}
+
+static const struct of_device_id imx_cdnhdmi_dt_ids[] = {
+ { .compatible = "fsl,imx8mq-evk-cdnhdmi", },
+ { .compatible = "fsl,imx-audio-cdnhdmi", },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, imx_cdnhdmi_dt_ids);
+
+static struct platform_driver imx_cdnhdmi_driver = {
+ .driver = {
+ .name = "imx-cdnhdmi",
+ .owner = THIS_MODULE,
+ .pm = &snd_soc_pm_ops,
+ .of_match_table = imx_cdnhdmi_dt_ids,
+ },
+ .probe = imx_cdnhdmi_probe,
+};
+module_platform_driver(imx_cdnhdmi_driver);
+
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("Freescale i.MX hdmi audio ASoC machine driver");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:imx-cdnhdmi");
diff --git a/sound/soc/fsl/imx-cs42888.c b/sound/soc/fsl/imx-cs42888.c
new file mode 100644
index 000000000000..5a88426aed7c
--- /dev/null
+++ b/sound/soc/fsl/imx-cs42888.c
@@ -0,0 +1,489 @@
+/*
+ * Copyright (C) 2010-2016 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/slab.h>
+#include <linux/device.h>
+#include <linux/i2c.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/soc.h>
+#include <sound/initval.h>
+#include <sound/pcm_params.h>
+
+#include "fsl_esai.h"
+
+#define CODEC_CLK_EXTER_OSC 1
+#define CODEC_CLK_ESAI_HCKT 2
+#define SUPPORT_RATE_NUM 10
+
+struct imx_priv {
+ struct clk *codec_clk;
+ struct clk *esai_clk;
+ unsigned int mclk_freq;
+ unsigned int esai_freq;
+ struct platform_device *pdev;
+ struct platform_device *asrc_pdev;
+ u32 asrc_rate;
+ u32 asrc_format;
+ bool is_codec_master;
+ bool is_codec_rpmsg;
+ bool is_stream_in_use[2];
+ bool is_stream_tdm[2];
+};
+
+static struct imx_priv card_priv;
+
+static int imx_cs42888_surround_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+ struct snd_soc_dai *codec_dai = rtd->codec_dai;
+ struct imx_priv *priv = &card_priv;
+ struct device *dev = &priv->pdev->dev;
+ bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
+ u32 channels = params_channels(params);
+ u32 max_tdm_rate;
+ u32 dai_format;
+ int ret = 0;
+
+ priv->is_stream_tdm[tx] = channels > 1 && channels % 2;
+ dai_format = SND_SOC_DAIFMT_NB_NF |
+ (priv->is_stream_tdm[tx] ? SND_SOC_DAIFMT_DSP_A :
+ SND_SOC_DAIFMT_LEFT_J);
+
+ priv->is_stream_in_use[tx] = true;
+
+ if (priv->is_stream_in_use[!tx] &&
+ (priv->is_stream_tdm[tx] != priv->is_stream_tdm[!tx])) {
+
+ dev_err(dev, "Don't support different fmt for tx & rx\n");
+ return -EINVAL;
+ }
+
+ priv->mclk_freq = clk_get_rate(priv->codec_clk);
+ priv->esai_freq = clk_get_rate(priv->esai_clk);
+
+ if (priv->is_codec_master) {
+ /* TDM is not supported by codec in master mode */
+ if (priv->is_stream_tdm[tx]) {
+ dev_err(dev, "%d channels are not supported in codec master mode\n",
+ channels);
+ return -EINVAL;
+ }
+ dai_format |= SND_SOC_DAIFMT_CBM_CFM;
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ ret = snd_soc_dai_set_sysclk(cpu_dai, ESAI_HCKT_EXTAL,
+ priv->mclk_freq, SND_SOC_CLOCK_IN);
+ else
+ ret = snd_soc_dai_set_sysclk(cpu_dai, ESAI_HCKR_EXTAL,
+ priv->mclk_freq, SND_SOC_CLOCK_IN);
+ if (ret) {
+ dev_err(dev, "failed to set cpu sysclk: %d\n", ret);
+ return ret;
+ }
+
+ ret = snd_soc_dai_set_sysclk(codec_dai, 0,
+ priv->mclk_freq, SND_SOC_CLOCK_OUT);
+ if (ret) {
+ dev_err(dev, "failed to set codec sysclk: %d\n", ret);
+ return ret;
+ }
+
+ } else {
+ dai_format |= SND_SOC_DAIFMT_CBS_CFS;
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ ret = snd_soc_dai_set_sysclk(cpu_dai, ESAI_HCKT_EXTAL,
+ priv->mclk_freq, SND_SOC_CLOCK_OUT);
+ else
+ ret = snd_soc_dai_set_sysclk(cpu_dai, ESAI_HCKR_EXTAL,
+ priv->mclk_freq, SND_SOC_CLOCK_OUT);
+ if (ret) {
+ dev_err(dev, "failed to set cpu sysclk: %d\n", ret);
+ return ret;
+ }
+
+ ret = snd_soc_dai_set_sysclk(codec_dai, 0,
+ priv->mclk_freq, SND_SOC_CLOCK_IN);
+ if (ret) {
+ dev_err(dev, "failed to set codec sysclk: %d\n", ret);
+ return ret;
+ }
+ }
+
+ /* set cpu DAI configuration */
+ ret = snd_soc_dai_set_fmt(cpu_dai, dai_format);
+ if (ret) {
+ dev_err(dev, "failed to set cpu dai fmt: %d\n", ret);
+ return ret;
+ }
+ /* set i.MX active slot mask */
+ if (priv->is_stream_tdm[tx]) {
+ /* 2 required by ESAI BCLK divisors, 8 slots, 32 width */
+ if (priv->is_codec_master)
+ max_tdm_rate = priv->mclk_freq / (8*32);
+ else
+ max_tdm_rate = priv->esai_freq / (2*8*32);
+ if (params_rate(params) > max_tdm_rate) {
+ dev_err(dev,
+ "maximum supported sampling rate for %d channels is %dKHz\n",
+ channels, max_tdm_rate / 1000);
+ return -EINVAL;
+ }
+
+ /*
+ * Per datasheet, the codec expects 8 slots and 32 bits
+ * for every slot in TDM mode.
+ */
+ snd_soc_dai_set_tdm_slot(cpu_dai,
+ BIT(channels) - 1, BIT(channels) - 1,
+ 8, 32);
+ } else
+ snd_soc_dai_set_tdm_slot(cpu_dai, 0x3, 0x3, 2, 32);
+
+ /* set codec DAI configuration */
+ ret = snd_soc_dai_set_fmt(codec_dai, dai_format);
+ if (ret) {
+ dev_err(dev, "failed to set codec dai fmt: %d\n", ret);
+ return ret;
+ }
+ return 0;
+}
+
+static int imx_cs42888_surround_hw_free(struct snd_pcm_substream *substream)
+{
+ struct imx_priv *priv = &card_priv;
+ bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
+
+ priv->is_stream_in_use[tx] = false;
+
+ return 0;
+}
+
+static int imx_cs42888_surround_startup(struct snd_pcm_substream *substream)
+{
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ static struct snd_pcm_hw_constraint_list constraint_rates;
+ struct imx_priv *priv = &card_priv;
+ struct device *dev = &priv->pdev->dev;
+ static u32 support_rates[SUPPORT_RATE_NUM];
+ int ret;
+
+ priv->mclk_freq = clk_get_rate(priv->codec_clk);
+
+ if (priv->mclk_freq % 12288000 == 0) {
+ support_rates[0] = 48000;
+ support_rates[1] = 96000;
+ support_rates[2] = 192000;
+ constraint_rates.list = support_rates;
+ constraint_rates.count = 3;
+
+ ret = snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
+ &constraint_rates);
+ if (ret)
+ return ret;
+ } else
+ dev_warn(dev, "mclk may be not supported %d\n", priv->mclk_freq);
+
+ return 0;
+}
+
+static struct snd_soc_ops imx_cs42888_surround_ops = {
+ .startup = imx_cs42888_surround_startup,
+ .hw_params = imx_cs42888_surround_hw_params,
+ .hw_free = imx_cs42888_surround_hw_free,
+};
+
+/**
+ * imx_cs42888_surround_startup() is to set constrain for hw parameter, but
+ * backend use same runtime as frontend, for p2p backend need to use different
+ * parameter, so backend can't use the startup.
+ */
+static struct snd_soc_ops imx_cs42888_surround_ops_be = {
+ .hw_params = imx_cs42888_surround_hw_params,
+ .hw_free = imx_cs42888_surround_hw_free,
+};
+
+
+static const struct snd_soc_dapm_widget imx_cs42888_dapm_widgets[] = {
+ SND_SOC_DAPM_LINE("Line Out Jack", NULL),
+ SND_SOC_DAPM_LINE("Line In Jack", NULL),
+};
+
+static const struct snd_soc_dapm_route audio_map[] = {
+ /* Line out jack */
+ {"Line Out Jack", NULL, "AOUT1L"},
+ {"Line Out Jack", NULL, "AOUT1R"},
+ {"Line Out Jack", NULL, "AOUT2L"},
+ {"Line Out Jack", NULL, "AOUT2R"},
+ {"Line Out Jack", NULL, "AOUT3L"},
+ {"Line Out Jack", NULL, "AOUT3R"},
+ {"Line Out Jack", NULL, "AOUT4L"},
+ {"Line Out Jack", NULL, "AOUT4R"},
+ {"AIN1L", NULL, "Line In Jack"},
+ {"AIN1R", NULL, "Line In Jack"},
+ {"AIN2L", NULL, "Line In Jack"},
+ {"AIN2R", NULL, "Line In Jack"},
+ {"Playback", NULL, "CPU-Playback"},/* dai route for be and fe */
+ {"CPU-Capture", NULL, "Capture"},
+ {"CPU-Playback", NULL, "ASRC-Playback"},
+ {"ASRC-Capture", NULL, "CPU-Capture"},
+};
+
+static int be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
+ struct snd_pcm_hw_params *params) {
+
+ struct imx_priv *priv = &card_priv;
+ struct snd_interval *rate;
+ struct snd_mask *mask;
+
+ if (!priv->asrc_pdev)
+ return -EINVAL;
+
+ rate = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
+ rate->max = rate->min = priv->asrc_rate;
+
+ mask = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
+ snd_mask_none(mask);
+ snd_mask_set(mask, priv->asrc_format);
+
+ return 0;
+}
+
+static struct snd_soc_dai_link imx_cs42888_dai[] = {
+ {
+ .name = "HiFi",
+ .stream_name = "HiFi",
+ .codec_dai_name = "cs42888",
+ .ops = &imx_cs42888_surround_ops,
+ .ignore_pmdown_time = 1,
+ },
+ {
+ .name = "HiFi-ASRC-FE",
+ .stream_name = "HiFi-ASRC-FE",
+ .codec_name = "snd-soc-dummy",
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .dynamic = 1,
+ .ignore_pmdown_time = 1,
+ .dpcm_playback = 1,
+ .dpcm_capture = 1,
+ .dpcm_merged_chan = 1,
+ },
+ {
+ .name = "HiFi-ASRC-BE",
+ .stream_name = "HiFi-ASRC-BE",
+ .codec_dai_name = "cs42888",
+ .platform_name = "snd-soc-dummy",
+ .no_pcm = 1,
+ .ignore_pmdown_time = 1,
+ .dpcm_playback = 1,
+ .dpcm_capture = 1,
+ .ops = &imx_cs42888_surround_ops_be,
+ .be_hw_params_fixup = be_hw_params_fixup,
+ },
+};
+
+static struct snd_soc_card snd_soc_card_imx_cs42888 = {
+ .name = "cs42888-audio",
+ .dai_link = imx_cs42888_dai,
+ .dapm_widgets = imx_cs42888_dapm_widgets,
+ .num_dapm_widgets = ARRAY_SIZE(imx_cs42888_dapm_widgets),
+ .dapm_routes = audio_map,
+ .num_dapm_routes = ARRAY_SIZE(audio_map),
+ .owner = THIS_MODULE,
+};
+
+/*
+ * This function will register the snd_soc_pcm_link drivers.
+ */
+static int imx_cs42888_probe(struct platform_device *pdev)
+{
+ struct device_node *esai_np, *codec_np;
+ struct device_node *asrc_np = NULL;
+ struct platform_device *esai_pdev;
+ struct platform_device *asrc_pdev = NULL;
+ struct imx_priv *priv = &card_priv;
+ int ret;
+ u32 width;
+
+ priv->pdev = pdev;
+ priv->asrc_pdev = NULL;
+
+ if (of_property_read_bool(pdev->dev.of_node, "codec-rpmsg"))
+ priv->is_codec_rpmsg = true;
+
+ esai_np = of_parse_phandle(pdev->dev.of_node, "esai-controller", 0);
+ codec_np = of_parse_phandle(pdev->dev.of_node, "audio-codec", 0);
+ if (!esai_np || !codec_np) {
+ dev_err(&pdev->dev, "phandle missing or invalid\n");
+ ret = -EINVAL;
+ goto fail;
+ }
+
+ asrc_np = of_parse_phandle(pdev->dev.of_node, "asrc-controller", 0);
+ if (asrc_np) {
+ asrc_pdev = of_find_device_by_node(asrc_np);
+ priv->asrc_pdev = asrc_pdev;
+ }
+
+ esai_pdev = of_find_device_by_node(esai_np);
+ if (!esai_pdev) {
+ dev_err(&pdev->dev, "failed to find ESAI platform device\n");
+ ret = -EINVAL;
+ goto fail;
+ }
+
+ if (priv->is_codec_rpmsg) {
+ struct platform_device *codec_dev;
+
+ codec_dev = of_find_device_by_node(codec_np);
+ if (!codec_dev || !codec_dev->dev.driver) {
+ dev_err(&pdev->dev, "failed to find codec platform device\n");
+ ret = -EINVAL;
+ goto fail;
+ }
+
+ priv->codec_clk = devm_clk_get(&codec_dev->dev, NULL);
+ if (IS_ERR(priv->codec_clk)) {
+ ret = PTR_ERR(priv->codec_clk);
+ dev_err(&codec_dev->dev, "failed to get codec clk: %d\n", ret);
+ goto fail;
+ }
+
+ } else {
+ struct i2c_client *codec_dev;
+
+ codec_dev = of_find_i2c_device_by_node(codec_np);
+ if (!codec_dev || !codec_dev->dev.driver) {
+ dev_err(&pdev->dev, "failed to find codec platform device\n");
+ ret = -EINVAL;
+ goto fail;
+ }
+
+ priv->codec_clk = devm_clk_get(&codec_dev->dev, NULL);
+ if (IS_ERR(priv->codec_clk)) {
+ ret = PTR_ERR(priv->codec_clk);
+ dev_err(&codec_dev->dev, "failed to get codec clk: %d\n", ret);
+ goto fail;
+ }
+ }
+
+ if (priv->is_codec_rpmsg) {
+ imx_cs42888_dai[0].codec_name = "rpmsg-audio-codec-cs42888";
+ imx_cs42888_dai[0].codec_dai_name = "cs42888";
+ } else {
+ imx_cs42888_dai[0].codec_of_node = codec_np;
+ }
+
+ /*if there is no asrc controller, we only enable one device*/
+ if (!asrc_pdev) {
+ imx_cs42888_dai[0].cpu_dai_name = dev_name(&esai_pdev->dev);
+ imx_cs42888_dai[0].platform_of_node = esai_np;
+ snd_soc_card_imx_cs42888.num_links = 1;
+ snd_soc_card_imx_cs42888.num_dapm_routes =
+ ARRAY_SIZE(audio_map) - 2;
+ } else {
+ imx_cs42888_dai[0].cpu_dai_name = dev_name(&esai_pdev->dev);
+ imx_cs42888_dai[0].platform_of_node = esai_np;
+ imx_cs42888_dai[1].cpu_of_node = asrc_np;
+ imx_cs42888_dai[1].platform_of_node = asrc_np;
+ imx_cs42888_dai[2].cpu_dai_name = dev_name(&esai_pdev->dev);
+ snd_soc_card_imx_cs42888.num_links = 3;
+
+ if (priv->is_codec_rpmsg) {
+ imx_cs42888_dai[2].codec_name = "rpmsg-audio-codec-cs42888";
+ imx_cs42888_dai[2].codec_dai_name = "cs42888";
+ } else {
+ imx_cs42888_dai[2].codec_of_node = codec_np;
+ }
+
+ ret = of_property_read_u32(asrc_np, "fsl,asrc-rate",
+ &priv->asrc_rate);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to get output rate\n");
+ ret = -EINVAL;
+ goto fail;
+ }
+
+ ret = of_property_read_u32(asrc_np, "fsl,asrc-width", &width);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to get output rate\n");
+ ret = -EINVAL;
+ goto fail;
+ }
+
+ if (width == 24)
+ priv->asrc_format = SNDRV_PCM_FORMAT_S24_LE;
+ else
+ priv->asrc_format = SNDRV_PCM_FORMAT_S16_LE;
+ }
+
+ priv->esai_clk = devm_clk_get(&esai_pdev->dev, "extal");
+ if (IS_ERR(priv->esai_clk)) {
+ ret = PTR_ERR(priv->esai_clk);
+ dev_err(&esai_pdev->dev, "failed to get cpu clk: %d\n", ret);
+ goto fail;
+ }
+
+ priv->is_codec_master = false;
+ if (of_property_read_bool(pdev->dev.of_node, "codec-master"))
+ priv->is_codec_master = true;
+
+ snd_soc_card_imx_cs42888.dev = &pdev->dev;
+
+ platform_set_drvdata(pdev, &snd_soc_card_imx_cs42888);
+
+ ret = snd_soc_register_card(&snd_soc_card_imx_cs42888);
+ if (ret)
+ dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret);
+fail:
+ if (asrc_np)
+ of_node_put(asrc_np);
+ if (esai_np)
+ of_node_put(esai_np);
+ if (codec_np)
+ of_node_put(codec_np);
+ return ret;
+}
+
+static int imx_cs42888_remove(struct platform_device *pdev)
+{
+ snd_soc_unregister_card(&snd_soc_card_imx_cs42888);
+ return 0;
+}
+
+static const struct of_device_id imx_cs42888_dt_ids[] = {
+ { .compatible = "fsl,imx-audio-cs42888", },
+ { /* sentinel */ }
+};
+
+static struct platform_driver imx_cs42888_driver = {
+ .probe = imx_cs42888_probe,
+ .remove = imx_cs42888_remove,
+ .driver = {
+ .name = "imx-cs42888",
+ .pm = &snd_soc_pm_ops,
+ .of_match_table = imx_cs42888_dt_ids,
+ },
+};
+module_platform_driver(imx_cs42888_driver);
+
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("ALSA SoC cs42888 Machine Layer Driver");
+MODULE_ALIAS("platform:imx-cs42888");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/fsl/imx-dsp.c b/sound/soc/fsl/imx-dsp.c
new file mode 100644
index 000000000000..a6f5a34f8605
--- /dev/null
+++ b/sound/soc/fsl/imx-dsp.c
@@ -0,0 +1,203 @@
+// SPDX-License-Identifier: (GPL-2.0+
+//
+// DSP machine driver
+//
+// Copyright (c) 2012-2013 by Tensilica Inc. ALL RIGHTS RESERVED.
+// Copyright 2018 NXP
+
+#include <linux/module.h>
+#include <linux/of_platform.h>
+#include <linux/i2c.h>
+#include <linux/of_gpio.h>
+#include <linux/slab.h>
+#include <linux/gpio.h>
+#include <linux/clk.h>
+#include <sound/soc.h>
+#include <sound/jack.h>
+#include <sound/control.h>
+#include <sound/pcm_params.h>
+#include <sound/soc-dapm.h>
+
+struct imx_dsp_audio_data {
+ struct snd_soc_dai_link dai[2];
+ struct snd_soc_card card;
+};
+
+static int imx_dsp_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_dai *codec_dai = rtd->codec_dai;
+ int ret;
+ u32 dai_format = SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_LEFT_J |
+ SND_SOC_DAIFMT_CBS_CFS;
+
+ ret = snd_soc_dai_set_sysclk(codec_dai, 0,
+ 24576000, SND_SOC_CLOCK_IN);
+ if (ret) {
+ dev_err(rtd->dev, "failed to set codec sysclk: %d\n", ret);
+ return ret;
+ }
+
+ ret = snd_soc_dai_set_fmt(codec_dai, dai_format);
+ if (ret) {
+ dev_err(rtd->dev, "failed to set codec dai fmt: %d\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static struct snd_soc_ops imx_dsp_ops_be = {
+ .hw_params = imx_dsp_hw_params,
+};
+
+static int be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
+ struct snd_pcm_hw_params *params) {
+
+ struct snd_interval *rate;
+ struct snd_interval *channels;
+ struct snd_mask *mask;
+
+ rate = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
+ rate->max = rate->min = 48000;
+
+ channels = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
+ channels->max = channels->min = 2;
+
+ mask = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
+ snd_mask_none(mask);
+ snd_mask_set(mask, SNDRV_PCM_FORMAT_S16_LE);
+
+ return 0;
+}
+
+static const struct snd_soc_dapm_route imx_dsp_audio_map[] = {
+ {"Playback", NULL, "Compress Playback"},/* dai route for be and fe */
+ {"Playback", NULL, "Playback"},
+};
+
+static int imx_dsp_audio_probe(struct platform_device *pdev)
+{
+ struct device_node *cpu_np=NULL, *codec_np=NULL, *platform_np=NULL;
+ struct platform_device *cpu_pdev;
+ struct imx_dsp_audio_data *data;
+ int ret;
+
+ data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
+ if (!data) {
+ ret = -ENOMEM;
+ goto fail;
+ }
+
+ cpu_np = of_parse_phandle(pdev->dev.of_node, "cpu-dai", 0);
+ if (!cpu_np) {
+ dev_err(&pdev->dev, "cpu dai phandle missing or invalid\n");
+ ret = -EINVAL;
+ goto fail;
+ }
+
+ cpu_pdev = of_find_device_by_node(cpu_np);
+ if (!cpu_pdev) {
+ dev_err(&pdev->dev, "failed to find rpmsg platform device\n");
+ ret = -EINVAL;
+ goto fail;
+ }
+
+ codec_np = of_parse_phandle(pdev->dev.of_node, "audio-codec", 0);
+ if (!codec_np) {
+ dev_err(&pdev->dev, "phandle missing or invalid\n");
+ ret = -EINVAL;
+ goto fail;
+ }
+
+ platform_np = of_parse_phandle(pdev->dev.of_node, "audio-platform", 0);
+ if (!platform_np) {
+ dev_err(&pdev->dev, "platform missing or invalid\n");
+ ret = -EINVAL;
+ goto fail;
+ }
+
+ data->dai[0].name = "dsp hifi fe";
+ data->dai[0].stream_name = "dsp hifi fe";
+ data->dai[0].codec_dai_name = "snd-soc-dummy-dai";
+ data->dai[0].codec_name = "snd-soc-dummy";
+ data->dai[0].cpu_dai_name = dev_name(&cpu_pdev->dev);
+ data->dai[0].cpu_of_node = cpu_np;
+ data->dai[0].platform_of_node = platform_np;
+ data->dai[0].playback_only = true;
+ data->dai[0].capture_only = false;
+ data->dai[0].dpcm_playback = 1;
+ data->dai[0].dpcm_capture = 0;
+ data->dai[0].dynamic = 1,
+ data->dai[0].ignore_pmdown_time = 1,
+ data->dai[0].dai_fmt = SND_SOC_DAIFMT_LEFT_J |
+ SND_SOC_DAIFMT_NB_NF |
+ SND_SOC_DAIFMT_CBS_CFS;
+
+ data->dai[1].name = "dsp hifi be";
+ data->dai[1].stream_name = "dsp hifi be";
+ data->dai[1].codec_dai_name = "cs42888";
+ data->dai[1].codec_of_node = codec_np;
+ data->dai[1].cpu_dai_name = "snd-soc-dummy-dai";
+ data->dai[1].cpu_name = "snd-soc-dummy";
+ data->dai[1].platform_name = "snd-soc-dummy";
+ data->dai[1].playback_only = true;
+ data->dai[1].capture_only = false;
+ data->dai[1].dpcm_playback = 1;
+ data->dai[1].dpcm_capture = 0;
+ data->dai[1].no_pcm = 1,
+ data->dai[1].ignore_pmdown_time = 1,
+ data->dai[1].dai_fmt = SND_SOC_DAIFMT_LEFT_J |
+ SND_SOC_DAIFMT_NB_NF |
+ SND_SOC_DAIFMT_CBS_CFS;
+ data->dai[1].ops = &imx_dsp_ops_be;
+ data->dai[1].be_hw_params_fixup = be_hw_params_fixup;
+
+ data->card.dapm_routes = imx_dsp_audio_map;
+ data->card.num_dapm_routes = ARRAY_SIZE(imx_dsp_audio_map);
+ data->card.num_links = 2;
+ data->card.dai_link = data->dai;
+
+ data->card.dev = &pdev->dev;
+ data->card.owner = THIS_MODULE;
+ ret = snd_soc_of_parse_card_name(&data->card, "model");
+ if (ret)
+ goto fail;
+
+ platform_set_drvdata(pdev, &data->card);
+ snd_soc_card_set_drvdata(&data->card, data);
+ ret = devm_snd_soc_register_card(&pdev->dev, &data->card);
+ if (ret) {
+ dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret);
+ goto fail;
+ }
+
+fail:
+ if (cpu_np)
+ of_node_put(cpu_np);
+ if (codec_np)
+ of_node_put(codec_np);
+ if (platform_np)
+ of_node_put(platform_np);
+ return ret;
+}
+
+static const struct of_device_id imx_dsp_audio_dt_ids[] = {
+ { .compatible = "fsl,imx-dsp-audio", },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, imx_dsp_audio_dt_ids);
+
+static struct platform_driver imx_dsp_audio_driver = {
+ .driver = {
+ .name = "imx-dsp-audio",
+ .owner = THIS_MODULE,
+ .pm = &snd_soc_pm_ops,
+ .of_match_table = imx_dsp_audio_dt_ids,
+ },
+ .probe = imx_dsp_audio_probe,
+};
+module_platform_driver(imx_dsp_audio_driver);
+
+MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/fsl/imx-hdmi-dma.c b/sound/soc/fsl/imx-hdmi-dma.c
new file mode 100644
index 000000000000..d337d09cfaf5
--- /dev/null
+++ b/sound/soc/fsl/imx-hdmi-dma.c
@@ -0,0 +1,1169 @@
+/*
+ * imx-hdmi-dma.c -- HDMI DMA driver for ALSA Soc Audio Layer
+ *
+ * Copyright (C) 2011-2016 Freescale Semiconductor, Inc.
+ *
+ * based on imx-pcm-dma-mx2.c
+ * Copyright 2009 Sascha Hauer <s.hauer@pengutronix.de>
+ *
+ * This code is based on code copyrighted by Freescale,
+ * Liam Girdwood, Javier Martin and probably others.
+ *
+ * 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/delay.h>
+#include <linux/dma-mapping.h>
+#include <linux/mfd/mxc-hdmi-core.h>
+#include <linux/platform_data/dma-imx.h>
+
+#include <video/mxc_hdmi.h>
+
+#include "imx-hdmi.h"
+
+#define HDMI_DMA_BURST_UNSPECIFIED_LEGNTH 0
+#define HDMI_DMA_BURST_INCR4 1
+#define HDMI_DMA_BURST_INCR8 2
+#define HDMI_DMA_BURST_INCR16 3
+
+#define HDMI_BASE_ADDR 0x00120000
+
+struct hdmi_sdma_script {
+ int control_reg_addr;
+ int status_reg_addr;
+ int dma_start_addr;
+ u32 buffer[20];
+};
+
+struct hdmi_dma_priv {
+ struct snd_pcm_substream *substream;
+ struct platform_device *pdev;
+
+ struct snd_dma_buffer hw_buffer;
+ unsigned long buffer_bytes;
+ unsigned long appl_bytes;
+
+ int periods;
+ int period_time;
+ int period_bytes;
+ int dma_period_bytes;
+ int buffer_ratio;
+
+ unsigned long offset;
+
+ snd_pcm_format_t format;
+ int sample_align;
+ int sample_bits;
+ int channels;
+ int rate;
+
+ int frame_idx;
+
+ bool tx_active;
+ spinlock_t irq_lock;
+
+ /* SDMA part */
+ dma_addr_t phy_hdmi_sdma_t;
+ struct hdmi_sdma_script *hdmi_sdma_t;
+ struct dma_chan *dma_channel;
+ struct dma_async_tx_descriptor *desc;
+ struct imx_hdmi_sdma_params sdma_params;
+};
+
+/* bit 0:0:0:b:p(0):c:(u)0:(v)0 */
+/* max 8 channels supported; channels are interleaved */
+static u8 g_packet_head_table[48 * 8];
+
+void hdmi_dma_copy_16_neon_lut(unsigned short *src, unsigned int *dst,
+ int samples, unsigned char *lookup_table);
+void hdmi_dma_copy_16_neon_fast(unsigned short *src, unsigned int *dst,
+ int samples);
+void hdmi_dma_copy_24_neon_lut(unsigned int *src, unsigned int *dst,
+ int samples, unsigned char *lookup_table);
+void hdmi_dma_copy_24_neon_fast(unsigned int *src, unsigned int *dst,
+ int samples);
+static void hdmi_dma_irq_enable(struct hdmi_dma_priv *priv);
+static void hdmi_dma_irq_disable(struct hdmi_dma_priv *priv);
+
+union hdmi_audio_header_t iec_header;
+EXPORT_SYMBOL(iec_header);
+
+/*
+ * Note that the period size for DMA != period size for ALSA because the
+ * driver adds iec frame info to the audio samples (in hdmi_dma_copy).
+ *
+ * Each 4 byte subframe = 1 byte of iec data + 3 byte audio sample.
+ *
+ * A 16 bit audio sample becomes 32 bits including the frame info. Ratio=2
+ * A 24 bit audio sample becomes 32 bits including the frame info. Ratio=3:4
+ * If the 24 bit raw audio is in 32 bit words, the
+ *
+ * Original Packed into subframe Ratio of size Format
+ * sample how many size of DMA buffer
+ * (bits) bits to ALSA buffer
+ * -------- ----------- -------- -------------- ------------------------
+ * 16 16 32 2 SNDRV_PCM_FORMAT_S16_LE
+ * 24 24 32 1.33 SNDRV_PCM_FORMAT_S24_3LE*
+ * 24 32 32 1 SNDRV_PCM_FORMAT_S24_LE
+ *
+ * *so SNDRV_PCM_FORMAT_S24_3LE is not supported.
+ */
+
+/*
+ * The minimum dma period is one IEC audio frame (192 * 4 * channels).
+ * The maximum dma period for the HDMI DMA is 8K.
+ *
+ * channels minimum maximum
+ * dma period dma period
+ * -------- ------------------ ----------
+ * 2 192 * 4 * 2 = 1536 * 4 = 6144
+ * 4 192 * 4 * 4 = 3072 * 2 = 6144
+ * 6 192 * 4 * 6 = 4608 * 1 = 4608
+ * 8 192 * 4 * 8 = 6144 * 1 = 6144
+ *
+ * Bottom line:
+ * 1. Must keep the ratio of DMA buffer to ALSA buffer consistent.
+ * 2. frame_idx is saved in the private data, so even if a frame cannot be
+ * transmitted in a period, it can be continued in the next period. This
+ * is necessary for 6 ch.
+ */
+#define HDMI_DMA_PERIOD_BYTES (12288)
+#define HDMI_DMA_BUF_SIZE (128 * 1024)
+#define HDMI_PCM_BUF_SIZE (128 * 1024)
+
+#define hdmi_audio_debug(dev, reg) \
+ dev_dbg(dev, #reg ": 0x%02x\n", hdmi_readb(reg))
+
+#ifdef DEBUG
+static void dumpregs(struct device *dev)
+{
+ hdmi_audio_debug(dev, HDMI_AHB_DMA_CONF0);
+ hdmi_audio_debug(dev, HDMI_AHB_DMA_START);
+ hdmi_audio_debug(dev, HDMI_AHB_DMA_STOP);
+ hdmi_audio_debug(dev, HDMI_AHB_DMA_THRSLD);
+ hdmi_audio_debug(dev, HDMI_AHB_DMA_STRADDR0);
+ hdmi_audio_debug(dev, HDMI_AHB_DMA_STPADDR0);
+ hdmi_audio_debug(dev, HDMI_AHB_DMA_BSTADDR0);
+ hdmi_audio_debug(dev, HDMI_AHB_DMA_MBLENGTH0);
+ hdmi_audio_debug(dev, HDMI_AHB_DMA_MBLENGTH1);
+ hdmi_audio_debug(dev, HDMI_AHB_DMA_STAT);
+ hdmi_audio_debug(dev, HDMI_AHB_DMA_INT);
+ hdmi_audio_debug(dev, HDMI_AHB_DMA_MASK);
+ hdmi_audio_debug(dev, HDMI_AHB_DMA_POL);
+ hdmi_audio_debug(dev, HDMI_AHB_DMA_CONF1);
+ hdmi_audio_debug(dev, HDMI_AHB_DMA_BUFFSTAT);
+ hdmi_audio_debug(dev, HDMI_AHB_DMA_BUFFINT);
+ hdmi_audio_debug(dev, HDMI_AHB_DMA_BUFFMASK);
+ hdmi_audio_debug(dev, HDMI_AHB_DMA_BUFFPOL);
+ hdmi_audio_debug(dev, HDMI_IH_MUTE_AHBDMAAUD_STAT0);
+ hdmi_audio_debug(dev, HDMI_IH_AHBDMAAUD_STAT0);
+ hdmi_audio_debug(dev, HDMI_IH_MUTE);
+}
+
+static void dumppriv(struct device *dev, struct hdmi_dma_priv *priv)
+{
+ dev_dbg(dev, "channels = %d\n", priv->channels);
+ dev_dbg(dev, "periods = %d\n", priv->periods);
+ dev_dbg(dev, "period_bytes = %d\n", priv->period_bytes);
+ dev_dbg(dev, "dma period_bytes = %d\n", priv->dma_period_bytes);
+ dev_dbg(dev, "buffer_ratio = %d\n", priv->buffer_ratio);
+ dev_dbg(dev, "hw dma buffer = 0x%08x\n", (int)priv->hw_buffer.addr);
+ dev_dbg(dev, "dma buf size = %d\n", (int)priv->buffer_bytes);
+ dev_dbg(dev, "sample_rate = %d\n", (int)priv->rate);
+}
+#else
+static void dumpregs(struct device *dev) {}
+static void dumppriv(struct device *dev, struct hdmi_dma_priv *priv) {}
+#endif
+
+/*
+ * Conditions for DMA to work:
+ * ((final_addr - initial_addr)>>2)+1) < 2k. So max period is 8k.
+ * (inital_addr & 0x3) == 0
+ * (final_addr & 0x3) == 0x3
+ *
+ * The DMA Period should be an integer multiple of the IEC 60958 audio
+ * frame size, which is 768 bytes (192 * 4).
+ */
+static void hdmi_dma_set_addr(int start_addr, int dma_period_bytes)
+{
+ int final_addr = start_addr + dma_period_bytes - 1;
+
+ hdmi_write4(start_addr, HDMI_AHB_DMA_STRADDR0);
+ hdmi_write4(final_addr, HDMI_AHB_DMA_STPADDR0);
+}
+
+static void hdmi_dma_irq_set(bool set)
+{
+ u8 val = hdmi_readb(HDMI_AHB_DMA_MASK);
+
+ if (set)
+ val |= HDMI_AHB_DMA_DONE;
+ else
+ val &= (u8)~HDMI_AHB_DMA_DONE;
+
+ hdmi_writeb(val, HDMI_AHB_DMA_MASK);
+}
+
+static void hdmi_mask(int mask)
+{
+ u8 regval = hdmi_readb(HDMI_AHB_DMA_MASK);
+
+ if (mask)
+ regval |= HDMI_AHB_DMA_ERROR | HDMI_AHB_DMA_FIFO_EMPTY;
+ else
+ regval &= (u8)~(HDMI_AHB_DMA_ERROR | HDMI_AHB_DMA_FIFO_EMPTY);
+
+ hdmi_writeb(regval, HDMI_AHB_DMA_MASK);
+}
+
+int odd_ones(unsigned a)
+{
+ a ^= a >> 8;
+ a ^= a >> 4;
+ a ^= a >> 2;
+ a ^= a >> 1;
+
+ return a & 1;
+}
+
+/* Add frame information for one pcm subframe */
+static u32 hdmi_dma_add_frame_info(struct hdmi_dma_priv *priv,
+ u32 pcm_data, int subframe_idx)
+{
+ union hdmi_audio_dma_data_t subframe;
+
+ subframe.U = 0;
+ iec_header.B.channel = subframe_idx;
+
+ /* fill b (start-of-block) */
+ subframe.B.b = (priv->frame_idx == 0) ? 1 : 0;
+
+ /* fill c (channel status) */
+ if (priv->frame_idx < 42)
+ subframe.B.c = (iec_header.U >> priv->frame_idx) & 0x1;
+ else
+ subframe.B.c = 0;
+
+ subframe.B.p = odd_ones(pcm_data);
+ subframe.B.p ^= subframe.B.c;
+ subframe.B.p ^= subframe.B.u;
+ subframe.B.p ^= subframe.B.v;
+
+ /* fill data */
+ if (priv->sample_bits == 16)
+ subframe.B.data = pcm_data << 8;
+ else
+ subframe.B.data = pcm_data;
+
+ return subframe.U;
+}
+
+static void init_table(int channels)
+{
+ unsigned char *p = g_packet_head_table;
+ int i, ch = 0;
+
+ for (i = 0; i < 48; i++) {
+ int b = 0;
+ if (i == 0)
+ b = 1;
+
+ for (ch = 0; ch < channels; ch++) {
+ int c = 0;
+ if (i < 42) {
+ iec_header.B.channel = ch+1;
+ c = (iec_header.U >> i) & 0x1;
+ }
+ /* preset bit p as c */
+ *p++ = (b << 4) | (c << 2) | (c << 3);
+ }
+ }
+}
+
+/*
+ * FIXME: Disable NEON Optimization in hdmi, or it will cause crash of
+ * pulseaudio in the userspace. There is no issue for the Optimization
+ * implemenation, if only use "VPUSH, VPOP" in the function, the pulseaudio
+ * will crash also. So for my assumption, we can't use the NEON in the
+ * interrupt.(tasklet is implemented by softirq.)
+ * Disable SMP, preempt, change the dma buffer to nocached, add protection of
+ * Dn register and fpscr, all these operation have no effect to the result.
+ */
+#define HDMI_DMA_NO_NEON
+
+#ifdef HDMI_DMA_NO_NEON
+/* Optimization for IEC head */
+static void hdmi_dma_copy_16_c_lut(u16 *src, u32 *dst, int samples,
+ u8 *lookup_table)
+{
+ u32 sample, head, p;
+ int i;
+
+ for (i = 0; i < samples; i++) {
+ /* get source sample */
+ sample = *src++;
+
+ /* xor every bit */
+ p = sample ^ (sample >> 8);
+ p ^= (p >> 4);
+ p ^= (p >> 2);
+ p ^= (p >> 1);
+ p &= 1; /* only want last bit */
+ p <<= 3; /* bit p */
+
+ /* get packet header */
+ head = *lookup_table++;
+
+ /* fix head */
+ head ^= p;
+
+ /* store */
+ *dst++ = (head << 24) | (sample << 8);
+ }
+}
+
+static void hdmi_dma_copy_16_c_fast(u16 *src, u32 *dst, int samples)
+{
+ u32 sample, p;
+ int i;
+
+ for (i = 0; i < samples; i++) {
+ /* get source sample */
+ sample = *src++;
+
+ /* xor every bit */
+ p = sample ^ (sample >> 8);
+ p ^= (p >> 4);
+ p ^= (p >> 2);
+ p ^= (p >> 1);
+ p &= 1; /* only want last bit */
+ p <<= 3; /* bit p */
+
+ /* store */
+ *dst++ = (p << 24) | (sample << 8);
+ }
+}
+
+static void hdmi_dma_copy_16(u16 *src, u32 *dst, int framecnt, int channelcnt)
+{
+ /* split input frames into 192-frame each */
+ int count_in_192 = (framecnt + 191) / 192;
+ int i;
+
+ for (i = 0; i < count_in_192; i++) {
+ int count, samples;
+
+ /* handles frame index [0, 48) */
+ count = (framecnt < 48) ? framecnt : 48;
+ samples = count * channelcnt;
+ hdmi_dma_copy_16_c_lut(src, dst, samples, g_packet_head_table);
+ framecnt -= count;
+ if (framecnt == 0)
+ break;
+
+ src += samples;
+ dst += samples;
+
+ /* handles frame index [48, 192) */
+ count = (framecnt < 192 - 48) ? framecnt : 192 - 48;
+ samples = count * channelcnt;
+ hdmi_dma_copy_16_c_fast(src, dst, samples);
+ framecnt -= count;
+ src += samples;
+ dst += samples;
+ }
+}
+#else
+/* NEON optimization for IEC head*/
+
+/**
+ * Convert pcm samples to iec samples suitable for HDMI transfer.
+ * PCM sample is 16 bits length.
+ * Frame index always starts from 0.
+ * Channel count can be 1, 2, 4, 6, or 8
+ * Sample count (frame_count * channel_count) is multipliable by 8.
+ */
+static void hdmi_dma_copy_16(u16 *src, u32 *dst, int framecount, int channelcount)
+{
+ /* split input frames into 192-frame each */
+ int i, count_in_192 = (framecount + 191) / 192;
+
+ for (i = 0; i < count_in_192; i++) {
+ int count, samples;
+
+ /* handles frame index [0, 48) */
+ count = (framecount < 48) ? framecount : 48;
+ samples = count * channelcount;
+ hdmi_dma_copy_16_neon_lut(src, dst, samples, g_packet_head_table);
+ framecount -= count;
+ if (framecount == 0)
+ break;
+
+ src += samples;
+ dst += samples;
+
+ /* handles frame index [48, 192) */
+ count = (framecount < 192 - 48) ? framecount : (192 - 48);
+ samples = count * channelcount;
+ hdmi_dma_copy_16_neon_fast(src, dst, samples);
+ framecount -= count;
+ src += samples;
+ dst += samples;
+ }
+}
+#endif
+
+static void hdmi_dma_mmap_copy(struct snd_pcm_substream *substream,
+ int offset, int count)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct hdmi_dma_priv *priv = runtime->private_data;
+ struct device *dev = rtd->platform->dev;
+ u32 framecount, *dst;
+ u16 *src16;
+
+ framecount = count / (priv->sample_align * priv->channels);
+
+ /* hw_buffer is the destination for pcm data plus frame info. */
+ dst = (u32 *)(priv->hw_buffer.area + (offset * priv->buffer_ratio));
+
+ switch (priv->format) {
+ case SNDRV_PCM_FORMAT_S16_LE:
+ /* dma_buffer is the mmapped buffer we are copying pcm from. */
+ src16 = (u16 *)(runtime->dma_area + offset);
+ hdmi_dma_copy_16(src16, dst, framecount, priv->channels);
+ break;
+ default:
+ dev_err(dev, "unsupported sample format %s\n",
+ snd_pcm_format_name(priv->format));
+ return;
+ }
+}
+
+static void hdmi_dma_data_copy(struct snd_pcm_substream *substream,
+ struct hdmi_dma_priv *priv, char type)
+{
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ unsigned long offset, count, appl_bytes, space_to_end;
+
+ if (runtime->access != SNDRV_PCM_ACCESS_MMAP_INTERLEAVED)
+ return;
+
+ appl_bytes = (runtime->status->hw_ptr % (priv->buffer_bytes/(runtime->frame_bits/8))) * (runtime->frame_bits/8);
+ if (type == 'p')
+ appl_bytes += 2 * priv->period_bytes;
+ offset = appl_bytes % priv->buffer_bytes;
+
+ switch (type) {
+ case 'p':
+ count = priv->period_bytes;
+ space_to_end = priv->period_bytes;
+ break;
+ case 'b':
+ count = priv->buffer_bytes;
+ space_to_end = priv->buffer_bytes - offset;
+
+ break;
+ default:
+ return;
+ }
+
+ if (count <= space_to_end) {
+ hdmi_dma_mmap_copy(substream, offset, count);
+ } else {
+ hdmi_dma_mmap_copy(substream, offset, space_to_end);
+ hdmi_dma_mmap_copy(substream, 0, count - space_to_end);
+ }
+}
+
+static void hdmi_sdma_callback(void *data)
+{
+ struct hdmi_dma_priv *priv = (struct hdmi_dma_priv *)data;
+ struct snd_pcm_substream *substream = priv->substream;
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ unsigned long flags;
+
+ spin_lock_irqsave(&priv->irq_lock, flags);
+
+ if (runtime && runtime->dma_area && priv->tx_active) {
+ priv->offset += priv->period_bytes;
+ priv->offset %= priv->period_bytes * priv->periods;
+
+ /* Copy data by period_bytes */
+ hdmi_dma_data_copy(substream, priv, 'p');
+
+ snd_pcm_period_elapsed(substream);
+ }
+
+ spin_unlock_irqrestore(&priv->irq_lock, flags);
+
+ return;
+}
+
+static int hdmi_dma_set_thrsld_incrtype(struct device *dev, int channels)
+{
+ u8 mask = HDMI_AHB_DMA_CONF0_BURST_MODE | HDMI_AHB_DMA_CONF0_INCR_TYPE_MASK;
+ u8 val = hdmi_readb(HDMI_AHB_DMA_CONF0) & ~mask;
+ int incr_type, threshold;
+
+ switch (hdmi_readb(HDMI_REVISION_ID)) {
+ case 0x0a:
+ incr_type = HDMI_DMA_BURST_INCR4;
+ if (channels == 2)
+ threshold = 126;
+ else
+ threshold = 124;
+ break;
+ case 0x1a:
+ incr_type = HDMI_DMA_BURST_INCR8;
+ threshold = 128;
+ break;
+ default:
+ dev_err(dev, "unknown hdmi controller!\n");
+ return -ENODEV;
+ }
+
+ hdmi_writeb(threshold, HDMI_AHB_DMA_THRSLD);
+
+ switch (incr_type) {
+ case HDMI_DMA_BURST_UNSPECIFIED_LEGNTH:
+ break;
+ case HDMI_DMA_BURST_INCR4:
+ val |= HDMI_AHB_DMA_CONF0_BURST_MODE;
+ break;
+ case HDMI_DMA_BURST_INCR8:
+ val |= HDMI_AHB_DMA_CONF0_BURST_MODE |
+ HDMI_AHB_DMA_CONF0_INCR8;
+ break;
+ case HDMI_DMA_BURST_INCR16:
+ val |= HDMI_AHB_DMA_CONF0_BURST_MODE |
+ HDMI_AHB_DMA_CONF0_INCR16;
+ break;
+ default:
+ dev_err(dev, "invalid increment type: %d!", incr_type);
+ return -EINVAL;
+ }
+
+ hdmi_writeb(val, HDMI_AHB_DMA_CONF0);
+
+ hdmi_audio_debug(dev, HDMI_AHB_DMA_THRSLD);
+
+ return 0;
+}
+
+static int hdmi_dma_configure_dma(struct device *dev, int channels)
+{
+ u8 i, val = 0;
+ int ret;
+
+ if (channels <= 0 || channels > 8 || channels % 2 != 0) {
+ dev_err(dev, "unsupported channel number: %d\n", channels);
+ return -EINVAL;
+ }
+
+ hdmi_audio_writeb(AHB_DMA_CONF0, EN_HLOCK, 0x1);
+
+ ret = hdmi_dma_set_thrsld_incrtype(dev, channels);
+ if (ret)
+ return ret;
+
+ for (i = 0; i < channels; i += 2)
+ val |= 0x3 << i;
+
+ hdmi_writeb(val, HDMI_AHB_DMA_CONF1);
+
+ return 0;
+}
+
+static void hdmi_dma_init_iec_header(void)
+{
+ iec_header.U = 0;
+
+ iec_header.B.consumer = 0; /* Consumer use */
+ iec_header.B.linear_pcm = 0; /* linear pcm audio */
+ iec_header.B.copyright = 1; /* no copyright */
+ iec_header.B.pre_emphasis = 0; /* 2 channels without pre-emphasis */
+ iec_header.B.mode = 0; /* Mode 0 */
+
+ iec_header.B.category_code = 0;
+
+ iec_header.B.source = 2; /* stereo */
+ iec_header.B.channel = 0;
+
+ iec_header.B.sample_freq = 0x02; /* 48 KHz */
+ iec_header.B.clock_acc = 0; /* Level II */
+
+ iec_header.B.word_length = 0x02; /* 16 bits */
+ iec_header.B.org_sample_freq = 0x0D; /* 48 KHz */
+
+ iec_header.B.cgms_a = 0; /* Copying is permitted without restriction */
+}
+
+static int hdmi_dma_update_iec_header(struct snd_pcm_substream *substream)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct hdmi_dma_priv *priv = runtime->private_data;
+ struct device *dev = rtd->platform->dev;
+
+ iec_header.B.source = priv->channels;
+
+ switch (priv->rate) {
+ case 32000:
+ iec_header.B.sample_freq = 0x03;
+ iec_header.B.org_sample_freq = 0x0C;
+ break;
+ case 44100:
+ iec_header.B.sample_freq = 0x00;
+ iec_header.B.org_sample_freq = 0x0F;
+ break;
+ case 48000:
+ iec_header.B.sample_freq = 0x02;
+ iec_header.B.org_sample_freq = 0x0D;
+ break;
+ case 88200:
+ iec_header.B.sample_freq = 0x08;
+ iec_header.B.org_sample_freq = 0x07;
+ break;
+ case 96000:
+ iec_header.B.sample_freq = 0x0A;
+ iec_header.B.org_sample_freq = 0x05;
+ break;
+ case 176400:
+ iec_header.B.sample_freq = 0x0C;
+ iec_header.B.org_sample_freq = 0x03;
+ break;
+ case 192000:
+ iec_header.B.sample_freq = 0x0E;
+ iec_header.B.org_sample_freq = 0x01;
+ break;
+ default:
+ dev_err(dev, "unsupported sample rate\n");
+ return -EFAULT;
+ }
+
+ switch (priv->format) {
+ case SNDRV_PCM_FORMAT_S16_LE:
+ iec_header.B.word_length = 0x02;
+ break;
+ case SNDRV_PCM_FORMAT_S24_LE:
+ iec_header.B.word_length = 0x0b;
+ break;
+ default:
+ return -EFAULT;
+ }
+
+ return 0;
+}
+
+/*
+ * The HDMI block transmits the audio data without adding any of the audio
+ * frame bits. So we have to copy the raw dma data from the ALSA buffer
+ * to the DMA buffer, adding the frame information.
+ */
+static int hdmi_dma_copy_user(struct snd_pcm_substream *substream, int channel,
+ unsigned long pos_bytes, void __user *buf,
+ unsigned long count)
+{
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct hdmi_dma_priv *priv = runtime->private_data;
+ u32 *hw_buf;
+ int subframe_idx;
+ u32 pcm_data;
+
+ /* Adding frame info to pcm data from userspace and copy to hw_buffer */
+ hw_buf = (u32 *)(priv->hw_buffer.area + (pos_bytes * priv->buffer_ratio));
+
+ while (count > 0) {
+ for (subframe_idx = 1 ; subframe_idx <= priv->channels ; subframe_idx++) {
+ if (copy_from_user(&pcm_data, buf, priv->sample_align))
+ return -EFAULT;
+
+ buf += priv->sample_align;
+ count -= priv->sample_align;
+
+ /* Save the header info to the audio dma buffer */
+ *hw_buf++ = hdmi_dma_add_frame_info(priv, pcm_data, subframe_idx);
+ }
+
+ priv->frame_idx++;
+ if (priv->frame_idx == 192)
+ priv->frame_idx = 0;
+ }
+
+ return 0;
+}
+
+static int hdmi_sdma_initbuf(struct device *dev, struct hdmi_dma_priv *priv)
+{
+ struct hdmi_sdma_script *hdmi_sdma_t = priv->hdmi_sdma_t;
+ u32 *head, *tail, i;
+
+ if (!hdmi_sdma_t) {
+ dev_err(dev, "hdmi private addr invalid!!!\n");
+ return -EINVAL;
+ }
+
+ hdmi_sdma_t->control_reg_addr = HDMI_BASE_ADDR + HDMI_AHB_DMA_START;
+ hdmi_sdma_t->status_reg_addr = HDMI_BASE_ADDR + HDMI_IH_AHBDMAAUD_STAT0;
+ hdmi_sdma_t->dma_start_addr = HDMI_BASE_ADDR + HDMI_AHB_DMA_STRADDR0;
+
+ head = &hdmi_sdma_t->buffer[0];
+ tail = &hdmi_sdma_t->buffer[1];
+
+ for (i = 0; i < priv->sdma_params.buffer_num; i++) {
+ *head = priv->hw_buffer.addr + i * priv->period_bytes * priv->buffer_ratio;
+ *tail = *head + priv->dma_period_bytes - 1;
+ head += 2;
+ tail += 2;
+ }
+
+ return 0;
+}
+
+static int hdmi_sdma_config(struct snd_pcm_substream *substream,
+ struct hdmi_dma_priv *priv)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct device *dai_dev = &priv->pdev->dev;
+ struct device *dev = rtd->platform->dev;
+ struct dma_slave_config slave_config;
+ int ret;
+
+ priv->dma_channel = dma_request_slave_channel(dai_dev, "tx");
+ if (priv->dma_channel == NULL) {
+ dev_err(dev, "failed to alloc dma channel\n");
+ return -EBUSY;
+ }
+
+ slave_config.direction = DMA_TRANS_NONE;
+ slave_config.src_addr = (dma_addr_t)priv->sdma_params.buffer_num;
+ slave_config.dst_addr = (dma_addr_t)priv->sdma_params.phyaddr;
+
+ ret = dmaengine_slave_config(priv->dma_channel, &slave_config);
+ if (ret) {
+ dev_err(dev, "failed to config slave dma\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int hdmi_dma_hw_free(struct snd_pcm_substream *substream)
+{
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct hdmi_dma_priv *priv = runtime->private_data;
+
+ if (priv->dma_channel) {
+ dma_release_channel(priv->dma_channel);
+ priv->dma_channel = NULL;
+ }
+
+ return 0;
+}
+
+static int hdmi_dma_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct hdmi_dma_priv *priv = runtime->private_data;
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct device *dev = rtd->platform->dev;
+ int ret;
+
+ priv->buffer_bytes = params_buffer_bytes(params);
+ priv->periods = params_periods(params);
+ priv->period_bytes = params_period_bytes(params);
+ priv->channels = params_channels(params);
+ priv->format = params_format(params);
+ priv->rate = params_rate(params);
+
+ priv->offset = 0;
+ priv->period_time = HZ / (priv->rate / params_period_size(params));
+
+ switch (priv->format) {
+ case SNDRV_PCM_FORMAT_S16_LE:
+ priv->buffer_ratio = 2;
+ priv->sample_align = 2;
+ priv->sample_bits = 16;
+ break;
+ case SNDRV_PCM_FORMAT_S24_LE:
+ /* 24 bit audio in 32 bit word */
+ priv->buffer_ratio = 1;
+ priv->sample_align = 4;
+ priv->sample_bits = 24;
+ break;
+ default:
+ dev_err(dev, "unsupported sample format: %d\n", priv->format);
+ return -EINVAL;
+ }
+
+ priv->dma_period_bytes = priv->period_bytes * priv->buffer_ratio;
+ priv->sdma_params.buffer_num = priv->periods;
+ priv->sdma_params.phyaddr = priv->phy_hdmi_sdma_t;
+
+ ret = hdmi_sdma_initbuf(dev, priv);
+ if (ret)
+ return ret;
+
+ ret = hdmi_sdma_config(substream, priv);
+ if (ret)
+ return ret;
+
+ snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
+
+ ret = hdmi_dma_configure_dma(dev, priv->channels);
+ if (ret)
+ return ret;
+
+ hdmi_dma_set_addr(priv->hw_buffer.addr, priv->dma_period_bytes);
+
+ dumppriv(dev, priv);
+
+ hdmi_dma_update_iec_header(substream);
+
+ /* Init par for mmap optimizate */
+ init_table(priv->channels);
+
+ priv->appl_bytes = 0;
+
+ return 0;
+}
+
+static void hdmi_dma_trigger_init(struct snd_pcm_substream *substream,
+ struct hdmi_dma_priv *priv)
+{
+ unsigned long status;
+
+ priv->offset = 0;
+ priv->frame_idx = 0;
+
+ /* Copy data by buffer_bytes */
+ hdmi_dma_data_copy(substream, priv, 'b');
+
+ hdmi_audio_writeb(AHB_DMA_CONF0, SW_FIFO_RST, 0x1);
+
+ /* Delay after reset */
+ udelay(1);
+
+ status = hdmi_readb(HDMI_IH_AHBDMAAUD_STAT0);
+ hdmi_writeb(status, HDMI_IH_AHBDMAAUD_STAT0);
+}
+
+static int hdmi_dma_prepare_and_submit(struct snd_pcm_substream *substream,
+ struct hdmi_dma_priv *priv)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct device *dev = rtd->platform->dev;
+
+ priv->desc = dmaengine_prep_dma_cyclic(priv->dma_channel, 0, 0, 0,
+ DMA_TRANS_NONE, 0);
+ if (!priv->desc) {
+ dev_err(dev, "failed to prepare slave dma\n");
+ return -EINVAL;
+ }
+
+ priv->desc->callback = hdmi_sdma_callback;
+ priv->desc->callback_param = (void *)priv;
+ dmaengine_submit(priv->desc);
+
+ return 0;
+}
+
+static int hdmi_dma_trigger(struct snd_pcm_substream *substream, int cmd)
+{
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct hdmi_dma_priv *priv = runtime->private_data;
+ struct device *dev = rtd->platform->dev;
+ int ret;
+
+ switch (cmd) {
+ case SNDRV_PCM_TRIGGER_START:
+ case SNDRV_PCM_TRIGGER_RESUME:
+ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+ if (!check_hdmi_state())
+ return 0;
+ hdmi_dma_trigger_init(substream, priv);
+
+ dumpregs(dev);
+
+ priv->tx_active = true;
+ hdmi_audio_writeb(AHB_DMA_START, START, 0x1);
+ hdmi_dma_irq_set(false);
+ hdmi_set_dma_mode(1);
+ ret = hdmi_dma_prepare_and_submit(substream, priv);
+ if (ret)
+ return ret;
+ dma_async_issue_pending(priv->desc->chan);
+ break;
+ case SNDRV_PCM_TRIGGER_STOP:
+ case SNDRV_PCM_TRIGGER_SUSPEND:
+ case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+ dmaengine_terminate_all(priv->dma_channel);
+ hdmi_set_dma_mode(0);
+ hdmi_dma_irq_set(true);
+ hdmi_audio_writeb(AHB_DMA_STOP, STOP, 0x1);
+ priv->tx_active = false;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static snd_pcm_uframes_t hdmi_dma_pointer(struct snd_pcm_substream *substream)
+{
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct hdmi_dma_priv *priv = runtime->private_data;
+
+ return bytes_to_frames(runtime, priv->offset);
+}
+
+static struct snd_pcm_hardware snd_imx_hardware = {
+ .info = SNDRV_PCM_INFO_INTERLEAVED |
+ SNDRV_PCM_INFO_BLOCK_TRANSFER |
+ SNDRV_PCM_INFO_MMAP |
+ SNDRV_PCM_INFO_MMAP_VALID |
+ SNDRV_PCM_INFO_PAUSE |
+ SNDRV_PCM_INFO_RESUME,
+ .formats = MXC_HDMI_FORMATS_PLAYBACK,
+ .rate_min = 32000,
+ .channels_min = 2,
+ .channels_max = 8,
+ .buffer_bytes_max = HDMI_PCM_BUF_SIZE,
+ .period_bytes_min = HDMI_DMA_PERIOD_BYTES / 2,
+ .period_bytes_max = HDMI_DMA_PERIOD_BYTES / 2,
+ .periods_min = 8,
+ .periods_max = 8,
+ .fifo_size = 0,
+};
+
+static void hdmi_dma_irq_enable(struct hdmi_dma_priv *priv)
+{
+ unsigned long flags;
+
+ hdmi_writeb(0xff, HDMI_AHB_DMA_POL);
+ hdmi_writeb(0xff, HDMI_AHB_DMA_BUFFPOL);
+
+ spin_lock_irqsave(&priv->irq_lock, flags);
+
+ hdmi_writeb(0xff, HDMI_IH_AHBDMAAUD_STAT0);
+ hdmi_writeb(0xff, HDMI_IH_MUTE_AHBDMAAUD_STAT0);
+ hdmi_dma_irq_set(false);
+ hdmi_mask(0);
+
+ spin_unlock_irqrestore(&priv->irq_lock, flags);
+}
+
+static void hdmi_dma_irq_disable(struct hdmi_dma_priv *priv)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&priv->irq_lock, flags);
+
+ hdmi_dma_irq_set(true);
+ hdmi_writeb(0x0, HDMI_IH_MUTE_AHBDMAAUD_STAT0);
+ hdmi_writeb(0xff, HDMI_IH_AHBDMAAUD_STAT0);
+ hdmi_mask(1);
+
+ spin_unlock_irqrestore(&priv->irq_lock, flags);
+}
+
+static int hdmi_dma_open(struct snd_pcm_substream *substream)
+{
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct device *dev = rtd->platform->dev;
+ struct hdmi_dma_priv *priv = dev_get_drvdata(dev);
+ int ret;
+
+ runtime->private_data = priv;
+
+ ret = mxc_hdmi_register_audio(substream);
+ if (ret < 0) {
+ dev_err(dev, "HDMI Video is not ready!\n");
+ return ret;
+ }
+
+ hdmi_audio_writeb(AHB_DMA_CONF0, SW_FIFO_RST, 0x1);
+
+ ret = snd_pcm_hw_constraint_integer(substream->runtime,
+ SNDRV_PCM_HW_PARAM_PERIODS);
+ if (ret < 0)
+ return ret;
+
+ snd_soc_set_runtime_hwparams(substream, &snd_imx_hardware);
+
+ hdmi_dma_irq_enable(priv);
+
+ return 0;
+}
+
+static int hdmi_dma_close(struct snd_pcm_substream *substream)
+{
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct hdmi_dma_priv *priv = runtime->private_data;
+
+ hdmi_dma_irq_disable(priv);
+ mxc_hdmi_unregister_audio(substream);
+
+ return 0;
+}
+
+static struct snd_pcm_ops imx_hdmi_dma_pcm_ops = {
+ .open = hdmi_dma_open,
+ .close = hdmi_dma_close,
+ .ioctl = snd_pcm_lib_ioctl,
+ .hw_params = hdmi_dma_hw_params,
+ .hw_free = hdmi_dma_hw_free,
+ .trigger = hdmi_dma_trigger,
+ .pointer = hdmi_dma_pointer,
+ .copy_user = hdmi_dma_copy_user,
+};
+
+static int imx_hdmi_dma_pcm_new(struct snd_soc_pcm_runtime *rtd)
+{
+ struct hdmi_dma_priv *priv = dev_get_drvdata(rtd->platform->dev);
+ struct snd_card *card = rtd->card->snd_card;
+ struct snd_pcm_substream *substream;
+ struct snd_pcm *pcm = rtd->pcm;
+ u64 dma_mask = DMA_BIT_MASK(32);
+ int ret = 0;
+
+ if (!card->dev->dma_mask)
+ card->dev->dma_mask = &dma_mask;
+ if (!card->dev->coherent_dma_mask)
+ card->dev->coherent_dma_mask = DMA_BIT_MASK(32);
+
+ substream = pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream;
+
+ ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, pcm->card->dev,
+ HDMI_PCM_BUF_SIZE, &substream->dma_buffer);
+ if (ret) {
+ dev_err(card->dev, "failed to alloc playback dma buffer\n");
+ return ret;
+ }
+
+ priv->substream = substream;
+
+ /* Alloc the hw_buffer */
+ ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, pcm->card->dev,
+ HDMI_DMA_BUF_SIZE, &priv->hw_buffer);
+ if (ret) {
+ dev_err(card->dev, "failed to alloc hw dma buffer\n");
+ return ret;
+ }
+
+ return ret;
+}
+
+static void imx_hdmi_dma_pcm_free(struct snd_pcm *pcm)
+{
+ int stream = SNDRV_PCM_STREAM_PLAYBACK;
+ struct snd_pcm_substream *substream = pcm->streams[stream].substream;
+ struct snd_soc_pcm_runtime *rtd = pcm->private_data;
+ struct hdmi_dma_priv *priv = dev_get_drvdata(rtd->platform->dev);
+
+ if (substream) {
+ snd_dma_free_pages(&substream->dma_buffer);
+ substream->dma_buffer.area = NULL;
+ substream->dma_buffer.addr = 0;
+ }
+
+ /* Free the hw_buffer */
+ snd_dma_free_pages(&priv->hw_buffer);
+ priv->hw_buffer.area = NULL;
+ priv->hw_buffer.addr = 0;
+}
+
+static struct snd_soc_platform_driver imx_hdmi_platform = {
+ .ops = &imx_hdmi_dma_pcm_ops,
+ .pcm_new = imx_hdmi_dma_pcm_new,
+ .pcm_free = imx_hdmi_dma_pcm_free,
+};
+
+static int imx_soc_platform_probe(struct platform_device *pdev)
+{
+ struct imx_hdmi *hdmi_drvdata = platform_get_drvdata(pdev);
+ struct hdmi_dma_priv *priv;
+ int ret = 0;
+
+ priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv) {
+ dev_err(&pdev->dev, "Failed to alloc hdmi_dma\n");
+ return -ENOMEM;
+ }
+
+ priv->hdmi_sdma_t = dma_alloc_coherent(NULL,
+ sizeof(struct hdmi_sdma_script),
+ &priv->phy_hdmi_sdma_t, GFP_KERNEL);
+ if (!priv->hdmi_sdma_t) {
+ dev_err(&pdev->dev, "Failed to alloc hdmi_sdma_t\n");
+ return -ENOMEM;
+ }
+
+ priv->tx_active = false;
+ spin_lock_init(&priv->irq_lock);
+
+ priv->pdev = hdmi_drvdata->pdev;
+
+ hdmi_dma_init_iec_header();
+
+ dev_set_drvdata(&pdev->dev, priv);
+
+ switch (hdmi_readb(HDMI_REVISION_ID)) {
+ case 0x0a:
+ snd_imx_hardware.period_bytes_max = HDMI_DMA_PERIOD_BYTES / 4;
+ snd_imx_hardware.period_bytes_min = HDMI_DMA_PERIOD_BYTES / 4;
+ break;
+ default:
+ break;
+ }
+
+ ret = snd_soc_register_platform(&pdev->dev, &imx_hdmi_platform);
+ if (ret)
+ goto err_plat;
+
+ return 0;
+
+err_plat:
+ dma_free_coherent(NULL, sizeof(struct hdmi_sdma_script),
+ priv->hdmi_sdma_t, priv->phy_hdmi_sdma_t);
+
+ return ret;
+}
+
+static int imx_soc_platform_remove(struct platform_device *pdev)
+{
+ struct hdmi_dma_priv *priv = dev_get_drvdata(&pdev->dev);
+
+ dma_free_coherent(NULL, sizeof(struct hdmi_sdma_script),
+ priv->hdmi_sdma_t, priv->phy_hdmi_sdma_t);
+
+ snd_soc_unregister_platform(&pdev->dev);
+
+ return 0;
+}
+
+static struct platform_driver imx_hdmi_dma_driver = {
+ .driver = {
+ .name = "imx-hdmi-audio",
+ .owner = THIS_MODULE,
+ },
+ .probe = imx_soc_platform_probe,
+ .remove = imx_soc_platform_remove,
+};
+
+module_platform_driver(imx_hdmi_dma_driver);
+
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("i.MX HDMI audio DMA");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/fsl/imx-hdmi.c b/sound/soc/fsl/imx-hdmi.c
new file mode 100644
index 000000000000..ab37faddcb1f
--- /dev/null
+++ b/sound/soc/fsl/imx-hdmi.c
@@ -0,0 +1,114 @@
+/*
+ * ASoC HDMI Transmitter driver for IMX development boards
+ *
+ * Copyright (C) 2011-2016 Freescale Semiconductor, Inc.
+ *
+ * based on stmp3780_devb_hdmi.c
+ *
+ * Vladimir Barinov <vbarinov@embeddedalley.com>
+ *
+ * Copyright 2008 SigmaTel, Inc
+ * Copyright 2008 Embedded Alley Solutions, Inc
+ *
+ * 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/module.h>
+#include <linux/of_platform.h>
+#include <linux/mfd/mxc-hdmi-core.h>
+#include <sound/soc.h>
+
+#include "imx-hdmi.h"
+
+/* imx digital audio interface glue - connects codec <--> CPU */
+static struct snd_soc_dai_link imx_hdmi_dai_link = {
+ .name = "i.MX HDMI Audio Tx",
+ .stream_name = "i.MX HDMI Audio Tx",
+ .codec_dai_name = "i2s-hifi",
+ .codec_name = "hdmi-audio-codec",
+ .platform_name = "imx-hdmi-audio",
+};
+
+static struct snd_soc_card snd_soc_card_imx_hdmi = {
+ .name = "imx-hdmi-soc",
+ .dai_link = &imx_hdmi_dai_link,
+ .num_links = 1,
+ .owner = THIS_MODULE,
+};
+
+static int imx_hdmi_audio_probe(struct platform_device *pdev)
+{
+ struct device_node *hdmi_np, *np = pdev->dev.of_node;
+ struct snd_soc_card *card = &snd_soc_card_imx_hdmi;
+ struct platform_device *hdmi_pdev;
+ int ret = 0;
+
+ if (!hdmi_get_registered()) {
+ dev_err(&pdev->dev, "initialize HDMI-audio failed. load HDMI-video first!\n");
+ return -ENODEV;
+ }
+
+ hdmi_np = of_parse_phandle(np, "hdmi-controller", 0);
+ if (!hdmi_np) {
+ dev_err(&pdev->dev, "failed to find hdmi-audio cpudai\n");
+ ret = -EINVAL;
+ goto end;
+ }
+
+ hdmi_pdev = of_find_device_by_node(hdmi_np);
+ if (!hdmi_pdev) {
+ dev_err(&pdev->dev, "failed to find SSI platform device\n");
+ ret = -EINVAL;
+ goto end;
+ }
+
+ card->dev = &pdev->dev;
+ card->dai_link->cpu_dai_name = dev_name(&hdmi_pdev->dev);
+
+ platform_set_drvdata(pdev, card);
+
+ ret = snd_soc_register_card(card);
+ if (ret)
+ dev_err(&pdev->dev, "failed to register card: %d\n", ret);
+
+end:
+ if (hdmi_np)
+ of_node_put(hdmi_np);
+
+ return ret;
+}
+
+static int imx_hdmi_audio_remove(struct platform_device *pdev)
+{
+ struct snd_soc_card *card = platform_get_drvdata(pdev);
+
+ snd_soc_unregister_card(card);
+
+ return 0;
+}
+
+static const struct of_device_id imx_hdmi_dt_ids[] = {
+ { .compatible = "fsl,imx-audio-hdmi", },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, imx_hdmi_dt_ids);
+
+static struct platform_driver imx_hdmi_audio_driver = {
+ .probe = imx_hdmi_audio_probe,
+ .remove = imx_hdmi_audio_remove,
+ .driver = {
+ .of_match_table = imx_hdmi_dt_ids,
+ .name = "imx-audio-hdmi",
+ .owner = THIS_MODULE,
+ .pm = &snd_soc_pm_ops,
+ },
+};
+
+module_platform_driver(imx_hdmi_audio_driver);
+
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("IMX HDMI TX ASoC driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:imx-audio-hdmi");
diff --git a/sound/soc/fsl/imx-hdmi.h b/sound/soc/fsl/imx-hdmi.h
new file mode 100644
index 000000000000..d06ce9c34d32
--- /dev/null
+++ b/sound/soc/fsl/imx-hdmi.h
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2011-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 as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __IMX_HDMI_H
+#define __IMX_HDMI_H
+
+struct imx_hdmi_sdma_params {
+ dma_addr_t phyaddr;
+ u32 buffer_num;
+ int dma;
+};
+
+struct imx_hdmi {
+ struct snd_soc_dai_driver cpu_dai_drv;
+ struct platform_device *codec_dev;
+ struct platform_device *dma_dev;
+ struct platform_device *pdev;
+ struct clk *isfr_clk;
+ struct clk *iahb_clk;
+ struct clk *mipi_core_clk;
+};
+
+#define HDMI_MAX_RATES 7
+#define HDMI_MAX_SAMPLE_SIZE 3
+#define HDMI_MAX_CHANNEL_CONSTRAINTS 4
+
+#define MXC_HDMI_RATES_PLAYBACK \
+ (SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 | \
+ SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 | \
+ SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_192000)
+
+#define MXC_HDMI_FORMATS_PLAYBACK \
+ (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE)
+
+union hdmi_audio_header_t {
+ uint64_t U;
+ struct {
+ unsigned consumer:1;
+ unsigned linear_pcm:1;
+ unsigned copyright:1;
+ unsigned pre_emphasis:3;
+ unsigned mode:2;
+
+ unsigned category_code:8;
+
+ unsigned source:4;
+ unsigned channel:4;
+
+ unsigned sample_freq:4;
+ unsigned clock_acc:2;
+ unsigned reserved0:2;
+
+ unsigned word_length:4;
+ unsigned org_sample_freq:4;
+
+ unsigned cgms_a:2;
+ unsigned reserved1:6;
+
+ unsigned reserved2:8;
+
+ unsigned reserved3:8;
+ } B;
+ unsigned char status[8];
+};
+
+union hdmi_audio_dma_data_t {
+ uint32_t U;
+ struct {
+ unsigned data:24;
+ unsigned v:1;
+ unsigned u:1;
+ unsigned c:1;
+ unsigned p:1;
+ unsigned b:1;
+ unsigned reserved:3;
+ } B;
+};
+
+extern union hdmi_audio_header_t iec_header;
+
+#define hdmi_audio_writeb(reg, bit, val) \
+ do { \
+ hdmi_mask_writeb(val, HDMI_ ## reg, \
+ HDMI_ ## reg ## _ ## bit ## _OFFSET, \
+ HDMI_ ## reg ## _ ## bit ## _MASK); \
+ pr_debug("Set reg: HDMI_" #reg " (0x%x) "\
+ "bit: HDMI_" #reg "_" #bit " (%d) to val: %x\n", \
+ HDMI_ ## reg, HDMI_ ## reg ## _ ## bit ## _OFFSET, val); \
+ } while (0)
+
+#endif /* __IMX_HDMI_H */
diff --git a/sound/soc/fsl/imx-micfil.c b/sound/soc/fsl/imx-micfil.c
new file mode 100644
index 000000000000..f1377911b857
--- /dev/null
+++ b/sound/soc/fsl/imx-micfil.c
@@ -0,0 +1,173 @@
+/*
+ * Copyright 2018 NXP
+ *
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/module.h>
+#include <linux/of_platform.h>
+#include <linux/i2c.h>
+#include <linux/of_gpio.h>
+#include <linux/slab.h>
+#include <linux/gpio.h>
+#include <linux/clk.h>
+#include <sound/soc.h>
+#include <sound/jack.h>
+#include <sound/control.h>
+#include <sound/pcm_params.h>
+#include <sound/soc-dapm.h>
+#include <linux/pinctrl/consumer.h>
+#include "fsl_micfil.h"
+
+#define RX 0
+#define TX 1
+
+struct imx_micfil_data {
+ char name[32];
+ struct snd_soc_dai_link dai;
+ struct snd_soc_card card;
+};
+
+static int imx_micfil_startup(struct snd_pcm_substream *substream)
+{
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ static struct snd_pcm_hw_constraint_list constraint_rates;
+ int ret;
+ static u32 support_rates[] = {11025, 16000, 22050,
+ 32000, 44100, 48000,};
+
+ constraint_rates.list = support_rates;
+ constraint_rates.count = ARRAY_SIZE(support_rates);
+
+ ret = snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
+ &constraint_rates);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+static int imx_micfil_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
+ struct device *dev = rtd->card->dev;
+ unsigned int fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF;
+ unsigned int rate = params_rate(params);
+ int ret, dir;
+
+ /* For playback the XTOR is slave, and for record is master */
+ fmt |= tx ? SND_SOC_DAIFMT_CBS_CFS : SND_SOC_DAIFMT_CBM_CFM;
+ dir = tx ? SND_SOC_CLOCK_OUT : SND_SOC_CLOCK_IN;
+
+ /* set cpu DAI configuration */
+ ret = snd_soc_dai_set_fmt(rtd->cpu_dai, fmt);
+ if (ret) {
+ dev_err(dev, "failed to set cpu dai fmt: %d\n", ret);
+ return ret;
+ }
+
+ /* Specific configurations of DAIs starts from here */
+ ret = snd_soc_dai_set_sysclk(rtd->cpu_dai, 0,
+ rate, dir);
+ if (ret) {
+ dev_err(dev,
+ "%s: failed to set cpu sysclk: %d\n", __func__,
+ ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+struct snd_soc_ops imx_micfil_ops = {
+ .startup = imx_micfil_startup,
+ .hw_params = imx_micfil_hw_params,
+};
+
+static int imx_micfil_probe(struct platform_device *pdev)
+{
+ struct device_node *cpu_np;
+ struct platform_device *cpu_pdev;
+ struct imx_micfil_data *data;
+ int ret;
+
+ cpu_np = of_parse_phandle(pdev->dev.of_node, "cpu-dai", 0);
+ if (!cpu_np) {
+ dev_err(&pdev->dev, "cpu dai phandle missing or invalid\n");
+ ret = -EINVAL;
+ goto fail;
+ }
+
+ data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
+ if (!data) {
+ ret = -ENOMEM;
+ goto fail;
+ }
+
+ strncpy(data->name, cpu_np->name, sizeof(data->name) - 1);
+
+ cpu_pdev = of_find_device_by_node(cpu_np);
+ if (!cpu_pdev) {
+ dev_err(&pdev->dev, "failed to find MICFIL platform device\n");
+ ret = -EINVAL;
+ goto fail;
+ }
+
+ data->dai.name = "micfil hifi";
+ data->dai.stream_name = "micfil hifi";
+ data->dai.codec_dai_name = "snd-soc-dummy-dai";
+ data->dai.codec_name = "snd-soc-dummy";
+ data->dai.cpu_dai_name = dev_name(&cpu_pdev->dev);
+ data->dai.platform_of_node = cpu_np;
+ data->dai.playback_only = false;
+ data->dai.ops = &imx_micfil_ops;
+ data->card.num_links = 1;
+ data->card.dai_link = &data->dai;
+ data->card.dev = &pdev->dev;
+ data->card.owner = THIS_MODULE;
+ ret = snd_soc_of_parse_card_name(&data->card, "model");
+ if (ret)
+ goto fail;
+
+ platform_set_drvdata(pdev, &data->card);
+ snd_soc_card_set_drvdata(&data->card, data);
+ ret = devm_snd_soc_register_card(&pdev->dev, &data->card);
+ if (ret) {
+ dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret);
+ goto fail;
+ }
+
+fail:
+ if (cpu_np)
+ of_node_put(cpu_np);
+ return ret;
+}
+
+static const struct of_device_id imx_micfil_dt_ids[] = {
+ { .compatible = "fsl,imx-audio-micfil", },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, imx_micfil_dt_ids);
+
+static struct platform_driver imx_micfil_driver = {
+ .driver = {
+ .name = "imx-micfil",
+ .owner = THIS_MODULE,
+ .pm = &snd_soc_pm_ops,
+ .of_match_table = imx_micfil_dt_ids,
+ },
+ .probe = imx_micfil_probe,
+};
+module_platform_driver(imx_micfil_driver);
+
+MODULE_AUTHOR("Cosmin-Gabriel Samoila <cosmin.samoila@nxp.com>");
+MODULE_DESCRIPTION("NXP Micfil ASoC machine driver");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:imx-micfil");
diff --git a/sound/soc/fsl/imx-mqs.c b/sound/soc/fsl/imx-mqs.c
new file mode 100644
index 000000000000..df291a45d43d
--- /dev/null
+++ b/sound/soc/fsl/imx-mqs.c
@@ -0,0 +1,277 @@
+/*
+ * Copyright 2012, 2014-2016 Freescale Semiconductor, Inc.
+ * Copyright 2012 Linaro Ltd.
+ *
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/clk.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <sound/soc.h>
+#include <sound/pcm_params.h>
+
+#define SUPPORT_RATE_NUM 10
+
+struct imx_priv {
+ struct clk *codec_clk;
+ unsigned int mclk_freq;
+ struct platform_device *pdev;
+ struct platform_device *asrc_pdev;
+ u32 asrc_rate;
+ u32 asrc_format;
+};
+
+static struct imx_priv card_priv;
+
+static int imx_mqs_startup(struct snd_pcm_substream *substream)
+{
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ static struct snd_pcm_hw_constraint_list constraint_rates;
+ struct imx_priv *priv = &card_priv;
+ struct device *dev = &priv->pdev->dev;
+ static u32 support_rates[SUPPORT_RATE_NUM];
+ int ret;
+
+ priv->mclk_freq = clk_get_rate(priv->codec_clk);
+
+ if (priv->mclk_freq % 24576000 == 0) {
+ support_rates[0] = 48000;
+ constraint_rates.list = support_rates;
+ constraint_rates.count = 1;
+
+ ret = snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
+ &constraint_rates);
+ if (ret)
+ return ret;
+ } else
+ dev_warn(dev, "mclk may be not supported %d\n", priv->mclk_freq);
+
+ return 0;
+}
+
+static int imx_mqs_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+ struct snd_soc_card *card = rtd->card;
+ int ret;
+
+ ret = snd_soc_dai_set_tdm_slot(cpu_dai, 0, 0, 2, params_width(params));
+ if (ret) {
+ dev_err(card->dev, "failed to set cpu dai tdm slot: %d\n", ret);
+ return ret;
+ }
+ return 0;
+}
+
+static struct snd_soc_ops imx_mqs_ops = {
+ .startup = imx_mqs_startup,
+ .hw_params = imx_mqs_hw_params,
+};
+
+static struct snd_soc_ops imx_mqs_ops_be = {
+ .hw_params = imx_mqs_hw_params,
+};
+
+static const struct snd_soc_dapm_route audio_map[] = {
+ {"CPU-Playback", NULL, "ASRC-Playback"},
+ {"Playback", NULL, "CPU-Playback"},/* dai route for be and fe */
+};
+
+static int be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
+ struct snd_pcm_hw_params *params) {
+
+ struct imx_priv *priv = &card_priv;
+ struct snd_interval *rate;
+ struct snd_mask *mask;
+
+ if (!priv->asrc_pdev)
+ return -EINVAL;
+
+ rate = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
+ rate->max = rate->min = priv->asrc_rate;
+
+ mask = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
+ snd_mask_none(mask);
+ snd_mask_set(mask, priv->asrc_format);
+
+ return 0;
+}
+
+static struct snd_soc_dai_link imx_mqs_dai[] = {
+ {
+ .name = "HiFi",
+ .stream_name = "HiFi",
+ .dai_fmt = SND_SOC_DAIFMT_LEFT_J | SND_SOC_DAIFMT_NB_NF |
+ SND_SOC_DAIFMT_CBS_CFS,
+ .ops = &imx_mqs_ops,
+ },
+ {
+ .name = "HiFi-ASRC-FE",
+ .stream_name = "HiFi-ASRC-FE",
+ .codec_name = "snd-soc-dummy",
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .dynamic = 1,
+ .ignore_pmdown_time = 1,
+ .dpcm_playback = 1,
+ .dpcm_capture = 0,
+ .dpcm_merged_chan = 1,
+ },
+ {
+ .name = "HiFi-ASRC-BE",
+ .stream_name = "HiFi-ASRC-BE",
+ .codec_dai_name = "fsl-mqs-dai",
+ .platform_name = "snd-soc-dummy",
+ .dai_fmt = SND_SOC_DAIFMT_LEFT_J | SND_SOC_DAIFMT_NB_NF |
+ SND_SOC_DAIFMT_CBS_CFS,
+ .no_pcm = 1,
+ .ignore_pmdown_time = 1,
+ .dpcm_playback = 1,
+ .dpcm_capture = 0,
+ .ops = &imx_mqs_ops_be,
+ .be_hw_params_fixup = be_hw_params_fixup,
+ },
+};
+
+static struct snd_soc_card snd_soc_card_imx_mqs = {
+ .name = "mqs-audio",
+ .dai_link = imx_mqs_dai,
+ .owner = THIS_MODULE,
+ .dapm_routes = audio_map,
+ .num_dapm_routes = ARRAY_SIZE(audio_map),
+};
+
+static int imx_mqs_probe(struct platform_device *pdev)
+{
+ struct device_node *cpu_np, *codec_np;
+ struct imx_priv *priv = &card_priv;
+ struct platform_device *codec_dev;
+ struct platform_device *asrc_pdev = NULL;
+ struct platform_device *cpu_pdev;
+ struct device_node *asrc_np;
+ int ret;
+ u32 width;
+
+ priv->pdev = pdev;
+
+ cpu_np = of_parse_phandle(pdev->dev.of_node, "cpu-dai", 0);
+ if (!cpu_np) {
+ ret = -EINVAL;
+ goto fail;
+ }
+
+ cpu_pdev = of_find_device_by_node(cpu_np);
+ if (!cpu_pdev) {
+ dev_err(&pdev->dev, "failed to find cpu dai device\n");
+ ret = -EINVAL;
+ goto fail;
+ }
+
+ asrc_np = of_parse_phandle(pdev->dev.of_node, "asrc-controller", 0);
+ if (asrc_np) {
+ asrc_pdev = of_find_device_by_node(asrc_np);
+ priv->asrc_pdev = asrc_pdev;
+ }
+
+ codec_np = of_parse_phandle(pdev->dev.of_node, "audio-codec", 0);
+ if (!codec_np) {
+ dev_err(&pdev->dev, "phandle missing or invalid\n");
+ ret = -EINVAL;
+ goto fail;
+ }
+
+ codec_dev = of_find_device_by_node(codec_np);
+ if (!codec_dev) {
+ dev_err(&codec_dev->dev, "failed to find codec device\n");
+ ret = -EINVAL;
+ goto fail;
+ }
+
+ priv->codec_clk = devm_clk_get(&codec_dev->dev, "mclk");
+ if (IS_ERR(priv->codec_clk)) {
+ ret = PTR_ERR(priv->codec_clk);
+ dev_err(&codec_dev->dev, "failed to get codec clk: %d\n", ret);
+ goto fail;
+ }
+
+ imx_mqs_dai[0].codec_dai_name = "fsl-mqs-dai";
+
+ if (!asrc_pdev) {
+ imx_mqs_dai[0].codec_of_node = codec_np;
+ imx_mqs_dai[0].cpu_dai_name = dev_name(&cpu_pdev->dev);
+ imx_mqs_dai[0].platform_of_node = cpu_np;
+ snd_soc_card_imx_mqs.num_links = 1;
+ } else {
+ imx_mqs_dai[0].codec_of_node = codec_np;
+ imx_mqs_dai[0].cpu_dai_name = dev_name(&cpu_pdev->dev);
+ imx_mqs_dai[0].platform_of_node = cpu_np;
+ imx_mqs_dai[1].cpu_of_node = asrc_np;
+ imx_mqs_dai[1].platform_of_node = asrc_np;
+ imx_mqs_dai[2].codec_of_node = codec_np;
+ imx_mqs_dai[2].cpu_dai_name = dev_name(&cpu_pdev->dev);
+ snd_soc_card_imx_mqs.num_links = 3;
+
+ ret = of_property_read_u32(asrc_np, "fsl,asrc-rate",
+ &priv->asrc_rate);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to get output rate\n");
+ ret = -EINVAL;
+ goto fail;
+ }
+
+ ret = of_property_read_u32(asrc_np, "fsl,asrc-width", &width);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to get output rate\n");
+ ret = -EINVAL;
+ goto fail;
+ }
+
+ if (width == 24)
+ priv->asrc_format = SNDRV_PCM_FORMAT_S24_LE;
+ else
+ priv->asrc_format = SNDRV_PCM_FORMAT_S16_LE;
+ }
+
+ snd_soc_card_imx_mqs.dev = &pdev->dev;
+
+ ret = devm_snd_soc_register_card(&pdev->dev, &snd_soc_card_imx_mqs);
+ if (ret) {
+ dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret);
+ goto fail;
+ }
+
+fail:
+ if (cpu_np)
+ of_node_put(cpu_np);
+
+ return ret;
+}
+
+static const struct of_device_id imx_mqs_dt_ids[] = {
+ { .compatible = "fsl,imx-audio-mqs", },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, imx_mqs_dt_ids);
+
+static struct platform_driver imx_mqs_driver = {
+ .driver = {
+ .name = "imx-mqs",
+ .pm = &snd_soc_pm_ops,
+ .of_match_table = imx_mqs_dt_ids,
+ },
+ .probe = imx_mqs_probe,
+};
+module_platform_driver(imx_mqs_driver);
+
+MODULE_AUTHOR("Nicolin Chen <Guangyu.Chen@freescale.com>");
+MODULE_DESCRIPTION("Freescale i.MX MQS ASoC machine driver");
+MODULE_ALIAS("platform:imx-mqs");
+MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/fsl/imx-pcm-dma-v2.c b/sound/soc/fsl/imx-pcm-dma-v2.c
new file mode 100644
index 000000000000..e90bcc26d063
--- /dev/null
+++ b/sound/soc/fsl/imx-pcm-dma-v2.c
@@ -0,0 +1,301 @@
+/*
+ * imx-pcm-dma-v2.c -- ALSA Soc Audio Layer
+ *
+ * Copyright 2009 Sascha Hauer <s.hauer@pengutronix.de>
+ *
+ * This code is based on code copyrighted by Freescale,
+ * Liam Girdwood, Javier Martin and probably others.
+ *
+ * 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/dma-mapping.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/dmaengine_pcm.h>
+#include <sound/soc.h>
+
+#include "imx-pcm.h"
+
+static struct snd_pcm_hardware imx_pcm_hardware = {
+ .info = SNDRV_PCM_INFO_INTERLEAVED |
+ SNDRV_PCM_INFO_BLOCK_TRANSFER |
+ SNDRV_PCM_INFO_MMAP |
+ SNDRV_PCM_INFO_MMAP_VALID,
+ .buffer_bytes_max = IMX_SSI_DMABUF_SIZE,
+ .period_bytes_min = 128,
+ .period_bytes_max = 65532, /* Limited by SDMA engine */
+ .periods_min = 2,
+ .periods_max = 255,
+ .fifo_size = 0,
+};
+
+static bool imx_dma_filter_fn(struct dma_chan *chan, void *param)
+{
+ if (!imx_dma_is_general_purpose(chan))
+ return false;
+
+ chan->private = param;
+
+ return true;
+}
+
+static void imx_pcm_dma_v2_complete(void *arg)
+{
+ struct snd_pcm_substream *substream = arg;
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct dmaengine_pcm_runtime_data *prtd =
+ substream->runtime->private_data;
+ struct snd_dmaengine_dai_dma_data *dma_data;
+
+ prtd->pos += snd_pcm_lib_period_bytes(substream);
+ if (prtd->pos >= snd_pcm_lib_buffer_bytes(substream))
+ prtd->pos = 0;
+
+ snd_pcm_period_elapsed(substream);
+
+ dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
+ if (dma_data->check_xrun && dma_data->check_xrun(substream))
+ dma_data->device_reset(substream, 1);
+}
+
+/* this may get called several times by oss emulation */
+static int imx_pcm_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_dmaengine_dai_dma_data *dma_data;
+ struct dma_slave_config config;
+ struct dma_chan *chan;
+ struct dmaengine_pcm_runtime_data *prtd =
+ substream->runtime->private_data;
+ int err = 0;
+
+ prtd->callback = imx_pcm_dma_v2_complete;
+
+ dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
+
+ /* return if this is a bufferless transfer e.g.
+ * codec <--> BT codec or GSM modem -- lg FIXME
+ */
+ if (!dma_data)
+ return 0;
+
+ snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
+ runtime->dma_bytes = params_buffer_bytes(params);
+
+ chan = snd_dmaengine_pcm_get_chan(substream);
+ if (!chan)
+ return -EINVAL;
+
+ /* fills in addr_width and direction */
+ err = snd_hwparams_to_dma_slave_config(substream, params, &config);
+ if (err)
+ return err;
+
+ snd_dmaengine_pcm_set_config_from_dai_data(substream,
+ dma_data,
+ &config);
+
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ config.dst_fifo_num = dma_data->fifo_num;
+ else
+ config.src_fifo_num = dma_data->fifo_num;
+
+ return dmaengine_slave_config(chan, &config);
+}
+
+static int imx_pcm_hw_free(struct snd_pcm_substream *substream)
+{
+ snd_pcm_set_runtime_buffer(substream, NULL);
+ return 0;
+}
+
+static snd_pcm_uframes_t imx_pcm_pointer(struct snd_pcm_substream *substream)
+{
+ return snd_dmaengine_pcm_pointer(substream);
+}
+
+static int imx_pcm_preallocate_dma_buffer(struct snd_pcm_substream *substream,
+ struct device *dev)
+{
+ size_t size = imx_pcm_hardware.buffer_bytes_max;
+ int ret;
+
+ ret = snd_pcm_lib_preallocate_pages(substream,
+ SNDRV_DMA_TYPE_DEV_IRAM,
+ dev,
+ size,
+ size);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+static int imx_pcm_free_dma_buffers(struct snd_pcm_substream *substream)
+{
+ return snd_pcm_lib_preallocate_free(substream);
+}
+
+static int imx_pcm_open(struct snd_pcm_substream *substream)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_dmaengine_dai_dma_data *dma_data;
+ struct dma_slave_caps dma_caps;
+ struct dma_chan *chan;
+ u32 addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) |
+ BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) |
+ BIT(DMA_SLAVE_BUSWIDTH_4_BYTES);
+ int ret;
+ int i;
+
+ dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
+
+ /* DT boot: filter_data is the DMA name */
+ if (rtd->cpu_dai->dev->of_node) {
+ struct dma_chan *chan;
+
+ chan = dma_request_slave_channel(rtd->cpu_dai->dev,
+ dma_data->chan_name);
+ ret = snd_dmaengine_pcm_open(substream, chan);
+ if (ret)
+ return ret;
+ } else {
+ ret = snd_dmaengine_pcm_open_request_chan(substream,
+ imx_dma_filter_fn,
+ dma_data->filter_data);
+ if (ret)
+ return ret;
+ }
+
+ chan = snd_dmaengine_pcm_get_chan(substream);
+
+ ret = dma_get_slave_caps(chan, &dma_caps);
+ if (ret == 0) {
+ if (dma_caps.cmd_pause)
+ imx_pcm_hardware.info |= SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME;
+ if (dma_caps.residue_granularity <= DMA_RESIDUE_GRANULARITY_SEGMENT)
+ imx_pcm_hardware.info |= SNDRV_PCM_INFO_BATCH;
+
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ addr_widths = dma_caps.dst_addr_widths;
+ else
+ addr_widths = dma_caps.src_addr_widths;
+ }
+
+ /*
+ * If SND_DMAENGINE_PCM_DAI_FLAG_PACK is set keep
+ * hw.formats set to 0, meaning no restrictions are in place.
+ * In this case it's the responsibility of the DAI driver to
+ * provide the supported format information.
+ */
+ if (!(dma_data->flags & SND_DMAENGINE_PCM_DAI_FLAG_PACK))
+ /*
+ * Prepare formats mask for valid/allowed sample types. If the
+ * dma does not have support for the given physical word size,
+ * it needs to be masked out so user space can not use the
+ * format which produces corrupted audio.
+ * In case the dma driver does not implement the slave_caps the
+ * default assumption is that it supports 1, 2 and 4 bytes
+ * widths.
+ */
+ for (i = 0; i <= SNDRV_PCM_FORMAT_LAST; i++) {
+ int bits = snd_pcm_format_physical_width(i);
+
+ /*
+ * Enable only samples with DMA supported physical
+ * widths
+ */
+ switch (bits) {
+ case 8:
+ case 16:
+ case 24:
+ case 32:
+ case 64:
+ if (addr_widths & (1 << (bits / 8)))
+ imx_pcm_hardware.formats |= (1LL << i);
+ break;
+ default:
+ /* Unsupported types */
+ break;
+ }
+ }
+
+ snd_soc_set_runtime_hwparams(substream, &imx_pcm_hardware);
+
+ ret = imx_pcm_preallocate_dma_buffer(substream, chan->device->dev);
+ if (ret)
+ return ret;
+
+ ret = snd_pcm_hw_constraint_integer(substream->runtime,
+ SNDRV_PCM_HW_PARAM_PERIODS);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
+static int imx_pcm_mmap(struct snd_pcm_substream *substream,
+ struct vm_area_struct *vma)
+{
+ struct snd_pcm_runtime *runtime = substream->runtime;
+
+ return dma_mmap_writecombine(substream->pcm->card->dev, vma,
+ runtime->dma_area,
+ runtime->dma_addr,
+ runtime->dma_bytes);
+}
+
+static int imx_pcm_close(struct snd_pcm_substream *substream)
+{
+ int ret;
+
+ ret = imx_pcm_free_dma_buffers(substream);
+ if (ret)
+ return ret;
+
+ return snd_dmaengine_pcm_close_release_chan(substream);
+}
+
+static struct snd_pcm_ops imx_pcm_ops = {
+ .open = imx_pcm_open,
+ .close = imx_pcm_close,
+ .ioctl = snd_pcm_lib_ioctl,
+ .hw_params = imx_pcm_hw_params,
+ .hw_free = imx_pcm_hw_free,
+ .trigger = snd_dmaengine_pcm_trigger,
+ .pointer = imx_pcm_pointer,
+ .mmap = imx_pcm_mmap,
+};
+
+static int imx_pcm_new(struct snd_soc_pcm_runtime *rtd)
+{
+ struct snd_card *card = rtd->card->snd_card;
+ int ret = 0;
+
+ ret = dma_coerce_mask_and_coherent(card->dev, DMA_BIT_MASK(32));
+ if (ret)
+ return ret;
+
+ return ret;
+}
+
+static struct snd_soc_platform_driver imx_soc_platform = {
+ .ops = &imx_pcm_ops,
+ .pcm_new = imx_pcm_new,
+};
+
+int imx_pcm_platform_register(struct device *dev)
+{
+ return devm_snd_soc_register_platform(dev, &imx_soc_platform);
+}
+EXPORT_SYMBOL_GPL(imx_pcm_platform_register);
+
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/fsl/imx-pcm-dma.c b/sound/soc/fsl/imx-pcm-dma.c
index 314814ddd2b0..995896dafbed 100644
--- a/sound/soc/fsl/imx-pcm-dma.c
+++ b/sound/soc/fsl/imx-pcm-dma.c
@@ -33,8 +33,48 @@ static bool filter(struct dma_chan *chan, void *param)
return true;
}
+static void imx_pcm_dma_complete(void *arg)
+{
+ struct snd_pcm_substream *substream = arg;
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct dmaengine_pcm_runtime_data *prtd = substream->runtime->private_data;
+ struct snd_dmaengine_dai_dma_data *dma_data;
+
+ prtd->pos += snd_pcm_lib_period_bytes(substream);
+ if (prtd->pos >= snd_pcm_lib_buffer_bytes(substream))
+ prtd->pos = 0;
+
+ snd_pcm_period_elapsed(substream);
+
+ dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
+ if (dma_data->check_xrun && dma_data->check_xrun(substream))
+ dma_data->device_reset(substream, 1);
+}
+
+static int imx_pcm_dma_prepare_slave_config(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params, struct dma_slave_config *slave_config)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_dmaengine_dai_dma_data *dma_data;
+ struct dmaengine_pcm_runtime_data *prtd = substream->runtime->private_data;
+ int ret;
+
+ dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
+ prtd->callback = imx_pcm_dma_complete;
+
+ ret = snd_hwparams_to_dma_slave_config(substream, params, slave_config);
+ if (ret)
+ return ret;
+
+ snd_dmaengine_pcm_set_config_from_dai_data(substream, dma_data,
+ slave_config);
+
+ return 0;
+
+}
+
static const struct snd_dmaengine_pcm_config imx_dmaengine_pcm_config = {
- .prepare_slave_config = snd_dmaengine_pcm_prepare_slave_config,
+ .prepare_slave_config = imx_pcm_dma_prepare_slave_config,
.compat_filter_fn = filter,
};
diff --git a/sound/soc/fsl/imx-pcm-rpmsg.c b/sound/soc/fsl/imx-pcm-rpmsg.c
new file mode 100644
index 000000000000..39b9b62e8303
--- /dev/null
+++ b/sound/soc/fsl/imx-pcm-rpmsg.c
@@ -0,0 +1,897 @@
+/*
+ * imx-rpmsg-platform.c -- ALSA Soc Audio Layer
+ *
+ * Copyright 2017 NXP
+ *
+ * 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/dma-mapping.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/rpmsg.h>
+#include <linux/imx_rpmsg.h>
+#include <linux/delay.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/dmaengine_pcm.h>
+#include <sound/soc.h>
+
+#include "imx-pcm.h"
+#include "fsl_rpmsg_i2s.h"
+#include "../../core/pcm_local.h"
+
+struct i2s_info *i2s_info_g;
+
+static struct snd_pcm_hardware imx_rpmsg_pcm_hardware = {
+ .info = SNDRV_PCM_INFO_INTERLEAVED |
+ SNDRV_PCM_INFO_BLOCK_TRANSFER |
+ SNDRV_PCM_INFO_MMAP |
+ SNDRV_PCM_INFO_MMAP_VALID |
+ SNDRV_PCM_INFO_NO_PERIOD_WAKEUP |
+ SNDRV_PCM_INFO_PAUSE |
+ SNDRV_PCM_INFO_RESUME,
+ .buffer_bytes_max = IMX_SAI_DMABUF_SIZE,
+ .period_bytes_min = 512,
+ .period_bytes_max = 65532, /* Limited by SDMA engine */
+ .periods_min = 2,
+ .periods_max = 6000,
+ .fifo_size = 0,
+};
+
+static int imx_rpmsg_pcm_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+ struct fsl_rpmsg_i2s *rpmsg_i2s = dev_get_drvdata(cpu_dai->dev);
+ struct i2s_info *i2s_info = &rpmsg_i2s->i2s_info;
+ struct i2s_rpmsg *rpmsg;
+
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ rpmsg = &i2s_info->rpmsg[I2S_TX_HW_PARAM];
+ else
+ rpmsg = &i2s_info->rpmsg[I2S_RX_HW_PARAM];
+
+ rpmsg->send_msg.param.rate = params_rate(params);
+
+ if (params_format(params) == SNDRV_PCM_FORMAT_S16_LE)
+ rpmsg->send_msg.param.format = RPMSG_S16_LE;
+ else if (params_format(params) == SNDRV_PCM_FORMAT_S24_LE)
+ rpmsg->send_msg.param.format = RPMSG_S24_LE;
+ else if (params_format(params) == SNDRV_PCM_FORMAT_DSD_U16_LE)
+ rpmsg->send_msg.param.format = SNDRV_PCM_FORMAT_DSD_U16_LE;
+ else if (params_format(params) == SNDRV_PCM_FORMAT_DSD_U32_LE)
+ rpmsg->send_msg.param.format = SNDRV_PCM_FORMAT_DSD_U32_LE;
+ else
+ rpmsg->send_msg.param.format = RPMSG_S32_LE;
+
+ if (params_channels(params) == 1)
+ rpmsg->send_msg.param.channels = RPMSG_CH_LEFT;
+ else
+ rpmsg->send_msg.param.channels = RPMSG_CH_STEREO;
+
+ snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
+ runtime->dma_bytes = params_buffer_bytes(params);
+
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ rpmsg->send_msg.header.cmd = I2S_TX_HW_PARAM;
+ else
+ rpmsg->send_msg.header.cmd = I2S_RX_HW_PARAM;
+
+ i2s_info->send_message(rpmsg, i2s_info);
+
+ return 0;
+}
+
+static int imx_rpmsg_pcm_hw_free(struct snd_pcm_substream *substream)
+{
+ snd_pcm_set_runtime_buffer(substream, NULL);
+ return 0;
+}
+
+static snd_pcm_uframes_t imx_rpmsg_pcm_pointer(
+ struct snd_pcm_substream *substream)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+ struct fsl_rpmsg_i2s *rpmsg_i2s = dev_get_drvdata(cpu_dai->dev);
+ struct i2s_info *i2s_info = &rpmsg_i2s->i2s_info;
+ unsigned int pos = 0;
+ struct i2s_rpmsg *rpmsg;
+ int buffer_tail = 0;
+
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ rpmsg = &i2s_info->rpmsg[I2S_TX_POINTER];
+ else
+ rpmsg = &i2s_info->rpmsg[I2S_RX_POINTER];
+
+ buffer_tail = rpmsg->recv_msg.param.buffer_offset /
+ snd_pcm_lib_period_bytes(substream);
+ pos = buffer_tail * snd_pcm_lib_period_bytes(substream);
+
+ return bytes_to_frames(substream->runtime, pos);
+}
+
+static void imx_rpmsg_timer_callback(unsigned long data)
+{
+ struct snd_pcm_substream *substream = (struct snd_pcm_substream *)data;
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+ struct fsl_rpmsg_i2s *rpmsg_i2s = dev_get_drvdata(cpu_dai->dev);
+ struct i2s_info *i2s_info = &rpmsg_i2s->i2s_info;
+ struct i2s_rpmsg *rpmsg;
+ int index = i2s_info->work_write_index;
+ int time_msec;
+
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ rpmsg = &i2s_info->rpmsg[I2S_TX_POINTER];
+ else
+ rpmsg = &i2s_info->rpmsg[I2S_RX_POINTER];
+
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ rpmsg->send_msg.header.cmd = I2S_TX_POINTER;
+ else
+ rpmsg->send_msg.header.cmd = I2S_RX_POINTER;
+
+ if (i2s_info->work_write_index != i2s_info->work_read_index) {
+ memcpy(&i2s_info->work_list[index].msg, rpmsg,
+ sizeof(struct i2s_rpmsg_s));
+ queue_work(i2s_info->rpmsg_wq, &i2s_info->work_list[index].work);
+ i2s_info->work_write_index++;
+ i2s_info->work_write_index %= WORK_MAX_NUM;
+ } else
+ i2s_info->msg_drop_count[substream->stream]++;
+
+ if (rpmsg_i2s->force_lpa) {
+ time_msec = (int)(runtime->period_size*1000/runtime->rate);
+ mod_timer(&i2s_info->stream_timer[substream->stream],
+ jiffies + msecs_to_jiffies(time_msec));
+ }
+
+ snd_pcm_period_elapsed(substream);
+}
+
+static int imx_rpmsg_pcm_open(struct snd_pcm_substream *substream)
+{
+ int ret = 0;
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+ struct fsl_rpmsg_i2s *rpmsg_i2s = dev_get_drvdata(cpu_dai->dev);
+ struct i2s_info *i2s_info = &rpmsg_i2s->i2s_info;
+ struct i2s_rpmsg *rpmsg;
+ struct dmaengine_pcm_runtime_data *prtd;
+ int cmd;
+
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ rpmsg = &i2s_info->rpmsg[I2S_TX_OPEN];
+ else
+ rpmsg = &i2s_info->rpmsg[I2S_RX_OPEN];
+
+ imx_rpmsg_pcm_hardware.buffer_bytes_max =
+ i2s_info->prealloc_buffer_size;
+ imx_rpmsg_pcm_hardware.period_bytes_max =
+ imx_rpmsg_pcm_hardware.buffer_bytes_max / 2;
+
+ snd_soc_set_runtime_hwparams(substream, &imx_rpmsg_pcm_hardware);
+
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ rpmsg->send_msg.header.cmd = I2S_TX_OPEN;
+ else
+ rpmsg->send_msg.header.cmd = I2S_RX_OPEN;
+
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+ cmd = I2S_TX_PERIOD_DONE + I2S_TYPE_A_NUM;
+ i2s_info->rpmsg[cmd].send_msg.param.buffer_tail = 0;
+ i2s_info->rpmsg[cmd].recv_msg.param.buffer_tail = 0;
+ i2s_info->rpmsg[I2S_TX_POINTER].recv_msg.param.buffer_offset = 0;
+ } else {
+ cmd = I2S_RX_PERIOD_DONE + I2S_TYPE_A_NUM;
+ i2s_info->rpmsg[cmd].send_msg.param.buffer_tail = 0;
+ i2s_info->rpmsg[cmd].recv_msg.param.buffer_tail = 0;
+ i2s_info->rpmsg[I2S_RX_POINTER].recv_msg.param.buffer_offset = 0;
+ }
+
+ i2s_info->send_message(rpmsg, i2s_info);
+
+ prtd = kzalloc(sizeof(*prtd), GFP_KERNEL);
+ if (!prtd)
+ return -ENOMEM;
+
+ substream->runtime->private_data = prtd;
+
+ ret = snd_pcm_hw_constraint_integer(substream->runtime,
+ SNDRV_PCM_HW_PARAM_PERIODS);
+ if (ret < 0)
+ return ret;
+
+ i2s_info->msg_drop_count[substream->stream] = 0;
+
+ /*create thread*/
+ setup_timer(&i2s_info->stream_timer[substream->stream],
+ imx_rpmsg_timer_callback, (unsigned long)substream);
+
+ return ret;
+}
+
+static int imx_rpmsg_pcm_close(struct snd_pcm_substream *substream)
+{
+ int ret = 0;
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+ struct fsl_rpmsg_i2s *rpmsg_i2s = dev_get_drvdata(cpu_dai->dev);
+ struct i2s_info *i2s_info = &rpmsg_i2s->i2s_info;
+ struct i2s_rpmsg *rpmsg;
+ struct dmaengine_pcm_runtime_data *prtd =
+ substream->runtime->private_data;
+
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ rpmsg = &i2s_info->rpmsg[I2S_TX_CLOSE];
+ else
+ rpmsg = &i2s_info->rpmsg[I2S_RX_CLOSE];
+
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ rpmsg->send_msg.header.cmd = I2S_TX_CLOSE;
+ else
+ rpmsg->send_msg.header.cmd = I2S_RX_CLOSE;
+ flush_workqueue(i2s_info->rpmsg_wq);
+ i2s_info->send_message(rpmsg, i2s_info);
+
+ del_timer(&i2s_info->stream_timer[substream->stream]);
+
+ kfree(prtd);
+
+ if (i2s_info->msg_drop_count[substream->stream])
+ dev_warn(rtd->dev, "Msg is dropped!, number is %d\n",
+ i2s_info->msg_drop_count[substream->stream]);
+
+ return ret;
+}
+
+static int imx_rpmsg_pcm_prepare(struct snd_pcm_substream *substream)
+{
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+ struct fsl_rpmsg_i2s *rpmsg_i2s = dev_get_drvdata(cpu_dai->dev);
+
+ /* NON-MMAP mode, NONBLOCK, Version 2, enable lpa in dts
+ * four condition to determine the lpa is enabled.
+ */
+ if ((runtime->access == SNDRV_PCM_ACCESS_RW_INTERLEAVED ||
+ runtime->access == SNDRV_PCM_ACCESS_RW_NONINTERLEAVED) &&
+ rpmsg_i2s->version == 2 &&
+ rpmsg_i2s->enable_lpa)
+ rpmsg_i2s->force_lpa = 1;
+ else
+ rpmsg_i2s->force_lpa = 0;
+
+ return 0;
+}
+
+static int imx_rpmsg_pcm_mmap(struct snd_pcm_substream *substream,
+ struct vm_area_struct *vma)
+{
+ struct snd_pcm_runtime *runtime = substream->runtime;
+
+ return dma_mmap_writecombine(substream->pcm->card->dev, vma,
+ runtime->dma_area,
+ runtime->dma_addr,
+ runtime->dma_bytes);
+}
+
+static void imx_rpmsg_pcm_dma_complete(void *arg)
+{
+ struct snd_pcm_substream *substream = arg;
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+ struct fsl_rpmsg_i2s *rpmsg_i2s = dev_get_drvdata(cpu_dai->dev);
+ struct i2s_info *i2s_info = &rpmsg_i2s->i2s_info;
+ struct i2s_rpmsg *rpmsg, *rpmsg2;
+
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+ rpmsg = &i2s_info->rpmsg[I2S_TX_POINTER];
+ rpmsg2 = &i2s_info->rpmsg[I2S_TX_PERIOD_DONE + I2S_TYPE_A_NUM];
+ } else {
+ rpmsg = &i2s_info->rpmsg[I2S_RX_POINTER];
+ rpmsg2 = &i2s_info->rpmsg[I2S_RX_PERIOD_DONE + I2S_TYPE_A_NUM];
+ }
+
+ rpmsg->recv_msg.param.buffer_offset =
+ rpmsg2->recv_msg.param.buffer_tail
+ * snd_pcm_lib_period_bytes(substream);
+ /*
+ * With suspend state, which is not running state, M4 will trigger
+ * system resume with PERIOD_DONE command, at this moment, the
+ * snd_pcm_period_elapsed can't update the hw ptr. so change the
+ * state to be running and update timer
+ *
+ */
+ if (!snd_pcm_running(substream) && rpmsg_i2s->force_lpa) {
+ int time_msec;
+
+ substream->runtime->status->state = SNDRV_PCM_STATE_RUNNING;
+ time_msec = (int)(runtime->period_size*1000/runtime->rate);
+ mod_timer(&i2s_info->stream_timer[substream->stream],
+ jiffies + msecs_to_jiffies(time_msec));
+ }
+ snd_pcm_period_elapsed(substream);
+}
+
+static int imx_rpmsg_pcm_prepare_and_submit(struct snd_pcm_substream *substream)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+ struct fsl_rpmsg_i2s *rpmsg_i2s = dev_get_drvdata(cpu_dai->dev);
+ struct i2s_info *i2s_info = &rpmsg_i2s->i2s_info;
+ struct i2s_rpmsg *rpmsg;
+ int index = i2s_info->work_write_index;
+
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ rpmsg = &i2s_info->rpmsg[I2S_TX_BUFFER];
+ else
+ rpmsg = &i2s_info->rpmsg[I2S_RX_BUFFER];
+
+
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ rpmsg->send_msg.header.cmd = I2S_TX_BUFFER;
+ else
+ rpmsg->send_msg.header.cmd = I2S_RX_BUFFER;
+
+ rpmsg->send_msg.param.buffer_addr = substream->runtime->dma_addr;
+ rpmsg->send_msg.param.buffer_size = snd_pcm_lib_buffer_bytes(substream);
+ rpmsg->send_msg.param.period_size = snd_pcm_lib_period_bytes(substream);
+ rpmsg->send_msg.param.buffer_tail = 0;
+
+ i2s_info->num_period[substream->stream] =
+ rpmsg->send_msg.param.buffer_size /
+ rpmsg->send_msg.param.period_size;
+
+ if (i2s_info->work_write_index != i2s_info->work_read_index) {
+ memcpy(&i2s_info->work_list[index].msg, rpmsg,
+ sizeof(struct i2s_rpmsg_s));
+ queue_work(i2s_info->rpmsg_wq, &i2s_info->work_list[index].work);
+ i2s_info->work_write_index++;
+ i2s_info->work_write_index %= WORK_MAX_NUM;
+ } else
+ return -EPIPE;
+
+ i2s_info->callback[substream->stream] = imx_rpmsg_pcm_dma_complete;
+ i2s_info->callback_param[substream->stream] = substream;
+ return 0;
+}
+
+static int imx_rpmsg_async_issue_pending(struct snd_pcm_substream *substream)
+{
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+ struct fsl_rpmsg_i2s *rpmsg_i2s = dev_get_drvdata(cpu_dai->dev);
+ struct i2s_info *i2s_info = &rpmsg_i2s->i2s_info;
+ struct i2s_rpmsg *rpmsg;
+ int index = i2s_info->work_write_index;
+ int time_msec;
+
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ rpmsg = &i2s_info->rpmsg[I2S_TX_START];
+ else
+ rpmsg = &i2s_info->rpmsg[I2S_RX_START];
+
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ rpmsg->send_msg.header.cmd = I2S_TX_START;
+ else
+ rpmsg->send_msg.header.cmd = I2S_RX_START;
+
+ if (i2s_info->work_write_index != i2s_info->work_read_index) {
+ memcpy(&i2s_info->work_list[index].msg, rpmsg,
+ sizeof(struct i2s_rpmsg_s));
+ queue_work(i2s_info->rpmsg_wq, &i2s_info->work_list[index].work);
+ i2s_info->work_write_index++;
+ i2s_info->work_write_index %= WORK_MAX_NUM;
+ } else
+ return -EPIPE;
+
+ if (rpmsg_i2s->force_lpa) {
+ time_msec = (int)(runtime->period_size*1000/runtime->rate);
+ mod_timer(&i2s_info->stream_timer[substream->stream],
+ jiffies + msecs_to_jiffies(time_msec));
+ }
+
+ return 0;
+}
+
+static int imx_rpmsg_restart(struct snd_pcm_substream *substream)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+ struct fsl_rpmsg_i2s *rpmsg_i2s = dev_get_drvdata(cpu_dai->dev);
+ struct i2s_info *i2s_info = &rpmsg_i2s->i2s_info;
+ struct i2s_rpmsg *rpmsg;
+ int index = i2s_info->work_write_index;
+
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ rpmsg = &i2s_info->rpmsg[I2S_TX_RESTART];
+ else
+ rpmsg = &i2s_info->rpmsg[I2S_RX_RESTART];
+
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ rpmsg->send_msg.header.cmd = I2S_TX_RESTART;
+ else
+ rpmsg->send_msg.header.cmd = I2S_RX_RESTART;
+
+ if (i2s_info->work_write_index != i2s_info->work_read_index) {
+ memcpy(&i2s_info->work_list[index].msg, rpmsg,
+ sizeof(struct i2s_rpmsg_s));
+ queue_work(i2s_info->rpmsg_wq, &i2s_info->work_list[index].work);
+ i2s_info->work_write_index++;
+ i2s_info->work_write_index %= WORK_MAX_NUM;
+ } else
+ return -EPIPE;
+
+ return 0;
+}
+
+static int imx_rpmsg_pause(struct snd_pcm_substream *substream)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+ struct fsl_rpmsg_i2s *rpmsg_i2s = dev_get_drvdata(cpu_dai->dev);
+ struct i2s_info *i2s_info = &rpmsg_i2s->i2s_info;
+ struct i2s_rpmsg *rpmsg;
+ int index = i2s_info->work_write_index;
+
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ rpmsg = &i2s_info->rpmsg[I2S_TX_PAUSE];
+ else
+ rpmsg = &i2s_info->rpmsg[I2S_RX_PAUSE];
+
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ rpmsg->send_msg.header.cmd = I2S_TX_PAUSE;
+ else
+ rpmsg->send_msg.header.cmd = I2S_RX_PAUSE;
+
+ if (i2s_info->work_write_index != i2s_info->work_read_index) {
+ memcpy(&i2s_info->work_list[index].msg, rpmsg,
+ sizeof(struct i2s_rpmsg_s));
+ queue_work(i2s_info->rpmsg_wq, &i2s_info->work_list[index].work);
+ i2s_info->work_write_index++;
+ i2s_info->work_write_index %= WORK_MAX_NUM;
+ } else
+ return -EPIPE;
+
+ return 0;
+}
+
+static int imx_rpmsg_terminate_all(struct snd_pcm_substream *substream)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+ struct fsl_rpmsg_i2s *rpmsg_i2s = dev_get_drvdata(cpu_dai->dev);
+ struct i2s_info *i2s_info = &rpmsg_i2s->i2s_info;
+ struct i2s_rpmsg *rpmsg;
+ int index = i2s_info->work_write_index;
+ int cmd;
+
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ rpmsg = &i2s_info->rpmsg[I2S_TX_TERMINATE];
+ else
+ rpmsg = &i2s_info->rpmsg[I2S_RX_TERMINATE];
+
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ rpmsg->send_msg.header.cmd = I2S_TX_TERMINATE;
+ else
+ rpmsg->send_msg.header.cmd = I2S_RX_TERMINATE;
+
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+ cmd = I2S_TX_PERIOD_DONE + I2S_TYPE_A_NUM;
+ i2s_info->rpmsg[cmd].send_msg.param.buffer_tail = 0;
+ i2s_info->rpmsg[cmd].recv_msg.param.buffer_tail = 0;
+ i2s_info->rpmsg[I2S_TX_POINTER].recv_msg.param.buffer_offset = 0;
+ } else {
+ cmd = I2S_RX_PERIOD_DONE + I2S_TYPE_A_NUM;
+ i2s_info->rpmsg[cmd].send_msg.param.buffer_tail = 0;
+ i2s_info->rpmsg[cmd].recv_msg.param.buffer_tail = 0;
+ i2s_info->rpmsg[I2S_RX_POINTER].recv_msg.param.buffer_offset = 0;
+ }
+
+ del_timer(&i2s_info->stream_timer[substream->stream]);
+
+ if (i2s_info->work_write_index != i2s_info->work_read_index) {
+ memcpy(&i2s_info->work_list[index].msg, rpmsg,
+ sizeof(struct i2s_rpmsg_s));
+ queue_work(i2s_info->rpmsg_wq, &i2s_info->work_list[index].work);
+ i2s_info->work_write_index++;
+ i2s_info->work_write_index %= WORK_MAX_NUM;
+ } else
+ return -EPIPE;
+
+ return 0;
+}
+
+int imx_rpmsg_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
+{
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+ struct fsl_rpmsg_i2s *rpmsg_i2s = dev_get_drvdata(cpu_dai->dev);
+ struct i2s_info *i2s_info = &rpmsg_i2s->i2s_info;
+ int ret = 0;
+
+ switch (cmd) {
+ case SNDRV_PCM_TRIGGER_START:
+ ret = imx_rpmsg_pcm_prepare_and_submit(substream);
+ if (ret)
+ return ret;
+ ret = imx_rpmsg_async_issue_pending(substream);
+ break;
+ case SNDRV_PCM_TRIGGER_RESUME:
+ if (rpmsg_i2s->force_lpa) {
+ int time_msec;
+
+ time_msec = (int)(runtime->period_size*1000/runtime->rate);
+ mod_timer(&i2s_info->stream_timer[substream->stream],
+ jiffies + msecs_to_jiffies(time_msec));
+ break;
+ }
+ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+ ret = imx_rpmsg_restart(substream);
+ break;
+ case SNDRV_PCM_TRIGGER_SUSPEND:
+ if (!rpmsg_i2s->force_lpa) {
+ if (runtime->info & SNDRV_PCM_INFO_PAUSE)
+ ret = imx_rpmsg_pause(substream);
+ else
+ ret = imx_rpmsg_terminate_all(substream);
+ } else
+ del_timer(&i2s_info->stream_timer[substream->stream]);
+ break;
+ case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+ ret = imx_rpmsg_pause(substream);
+ break;
+ case SNDRV_PCM_TRIGGER_STOP:
+ ret = imx_rpmsg_terminate_all(substream);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+int imx_rpmsg_pcm_ack(struct snd_pcm_substream *substream)
+{
+ /*send the hw_avail size through rpmsg*/
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+ struct fsl_rpmsg_i2s *rpmsg_i2s = dev_get_drvdata(cpu_dai->dev);
+ struct i2s_info *i2s_info = &rpmsg_i2s->i2s_info;
+ struct i2s_rpmsg *rpmsg;
+ int index = i2s_info->work_write_index;
+ int buffer_tail = 0;
+ int writen_num = 0;
+ snd_pcm_sframes_t avail;
+
+ if (!rpmsg_i2s->force_lpa)
+ return 0;
+
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ rpmsg = &i2s_info->rpmsg[I2S_TX_PERIOD_DONE + I2S_TYPE_A_NUM];
+ else
+ rpmsg = &i2s_info->rpmsg[I2S_RX_PERIOD_DONE + I2S_TYPE_A_NUM];
+
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ rpmsg->send_msg.header.cmd = I2S_TX_PERIOD_DONE;
+ else
+ rpmsg->send_msg.header.cmd = I2S_RX_PERIOD_DONE;
+
+ rpmsg->send_msg.header.type = I2S_TYPE_C;
+
+ buffer_tail = (frames_to_bytes(runtime, runtime->control->appl_ptr) %
+ snd_pcm_lib_buffer_bytes(substream));
+ buffer_tail = buffer_tail / snd_pcm_lib_period_bytes(substream);
+
+ if (buffer_tail != rpmsg->send_msg.param.buffer_tail) {
+ writen_num = buffer_tail - rpmsg->send_msg.param.buffer_tail;
+ if (writen_num < 0)
+ writen_num += runtime->periods;
+
+ rpmsg->send_msg.param.buffer_tail = buffer_tail;
+ memcpy(&i2s_info->period_done_msg[substream->stream], rpmsg,
+ sizeof(struct i2s_rpmsg_s));
+ i2s_info->period_done_msg_enabled[substream->stream] = true;
+
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ avail = snd_pcm_playback_hw_avail(runtime);
+ else
+ avail = snd_pcm_capture_hw_avail(runtime);
+
+ if ((avail - writen_num * runtime->period_size)
+ <= runtime->period_size) {
+ if (i2s_info->work_write_index != i2s_info->work_read_index) {
+ memcpy(&i2s_info->work_list[index].msg, rpmsg,
+ sizeof(struct i2s_rpmsg_s));
+ queue_work(i2s_info->rpmsg_wq,
+ &i2s_info->work_list[index].work);
+ i2s_info->work_write_index++;
+ i2s_info->work_write_index %= WORK_MAX_NUM;
+ } else
+ i2s_info->msg_drop_count[substream->stream]++;
+ }
+ }
+
+ return 0;
+}
+
+static struct snd_pcm_ops imx_rpmsg_pcm_ops = {
+ .open = imx_rpmsg_pcm_open,
+ .close = imx_rpmsg_pcm_close,
+ .ioctl = snd_pcm_lib_ioctl,
+ .hw_params = imx_rpmsg_pcm_hw_params,
+ .hw_free = imx_rpmsg_pcm_hw_free,
+ .trigger = imx_rpmsg_pcm_trigger,
+ .pointer = imx_rpmsg_pcm_pointer,
+ .mmap = imx_rpmsg_pcm_mmap,
+ .ack = imx_rpmsg_pcm_ack,
+ .prepare = imx_rpmsg_pcm_prepare,
+};
+
+static int imx_rpmsg_pcm_preallocate_dma_buffer(struct snd_pcm *pcm,
+ int stream, int size)
+{
+ struct snd_pcm_substream *substream = pcm->streams[stream].substream;
+ struct snd_dma_buffer *buf = &substream->dma_buffer;
+
+ buf->dev.type = SNDRV_DMA_TYPE_DEV;
+ buf->dev.dev = pcm->card->dev;
+ buf->private_data = NULL;
+ buf->area = dma_alloc_writecombine(pcm->card->dev, size,
+ &buf->addr, GFP_KERNEL);
+ if (!buf->area)
+ return -ENOMEM;
+
+ buf->bytes = size;
+ return 0;
+}
+
+static void imx_rpmsg_pcm_free_dma_buffers(struct snd_pcm *pcm)
+{
+ struct snd_pcm_substream *substream;
+ struct snd_dma_buffer *buf;
+ int stream;
+
+ for (stream = SNDRV_PCM_STREAM_PLAYBACK;
+ stream < SNDRV_PCM_STREAM_LAST; stream++) {
+ substream = pcm->streams[stream].substream;
+ if (!substream)
+ continue;
+
+ buf = &substream->dma_buffer;
+ if (!buf->area)
+ continue;
+
+ dma_free_writecombine(pcm->card->dev, buf->bytes,
+ buf->area, buf->addr);
+ buf->area = NULL;
+ }
+}
+
+static int imx_rpmsg_pcm_new(struct snd_soc_pcm_runtime *rtd)
+{
+ struct snd_card *card = rtd->card->snd_card;
+ struct snd_pcm *pcm = rtd->pcm;
+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+ struct fsl_rpmsg_i2s *rpmsg_i2s = dev_get_drvdata(cpu_dai->dev);
+ struct i2s_info *i2s_info = &rpmsg_i2s->i2s_info;
+ int ret;
+
+ ret = dma_coerce_mask_and_coherent(card->dev, DMA_BIT_MASK(32));
+ if (ret)
+ return ret;
+
+ if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) {
+ ret = imx_rpmsg_pcm_preallocate_dma_buffer(pcm,
+ SNDRV_PCM_STREAM_PLAYBACK,
+ i2s_info->prealloc_buffer_size);
+ if (ret)
+ goto out;
+ }
+
+ if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) {
+ ret = imx_rpmsg_pcm_preallocate_dma_buffer(pcm,
+ SNDRV_PCM_STREAM_CAPTURE,
+ i2s_info->prealloc_buffer_size);
+ if (ret)
+ goto out;
+ }
+
+out:
+ /* free preallocated buffers in case of error */
+ if (ret)
+ imx_rpmsg_pcm_free_dma_buffers(pcm);
+
+ return ret;
+}
+
+static struct snd_soc_platform_driver imx_rpmsg_soc_platform = {
+ .ops = &imx_rpmsg_pcm_ops,
+ .pcm_new = imx_rpmsg_pcm_new,
+ .pcm_free = imx_rpmsg_pcm_free_dma_buffers,
+};
+
+int imx_rpmsg_platform_register(struct device *dev)
+{
+ struct fsl_rpmsg_i2s *rpmsg_i2s = dev_get_drvdata(dev);
+
+ i2s_info_g = &rpmsg_i2s->i2s_info;
+
+ return devm_snd_soc_register_platform(dev, &imx_rpmsg_soc_platform);
+}
+EXPORT_SYMBOL_GPL(imx_rpmsg_platform_register);
+
+static int i2s_rpmsg_cb(struct rpmsg_device *rpdev, void *data, int len,
+ void *priv, u32 src)
+{
+ struct i2s_rpmsg_r *msg = (struct i2s_rpmsg_r *)data;
+ struct i2s_rpmsg *rpmsg;
+ unsigned long flags;
+
+ dev_dbg(&rpdev->dev, "get from%d: cmd:%d. %d\n",
+ src, msg->header.cmd, msg->param.resp);
+
+ if (msg->header.type == I2S_TYPE_C) {
+ if (msg->header.cmd == I2S_TX_PERIOD_DONE) {
+ spin_lock_irqsave(&i2s_info_g->lock[0], flags);
+ rpmsg = &i2s_info_g->rpmsg[I2S_TX_PERIOD_DONE + I2S_TYPE_A_NUM];
+
+ if (msg->header.major == 1 && msg->header.minor == 2)
+ rpmsg->recv_msg.param.buffer_tail =
+ msg->param.buffer_tail;
+ else
+ rpmsg->recv_msg.param.buffer_tail++;
+
+ rpmsg->recv_msg.param.buffer_tail %=
+ i2s_info_g->num_period[0];
+
+ spin_unlock_irqrestore(&i2s_info_g->lock[0], flags);
+ i2s_info_g->callback[0](i2s_info_g->callback_param[0]);
+
+ } else if (msg->header.cmd == I2S_RX_PERIOD_DONE) {
+ spin_lock_irqsave(&i2s_info_g->lock[1], flags);
+ rpmsg = &i2s_info_g->rpmsg[I2S_RX_PERIOD_DONE + I2S_TYPE_A_NUM];
+
+ if (msg->header.major == 1 && msg->header.minor == 2)
+ rpmsg->recv_msg.param.buffer_tail =
+ msg->param.buffer_tail;
+ else
+ rpmsg->recv_msg.param.buffer_tail++;
+
+ rpmsg->recv_msg.param.buffer_tail %=
+ i2s_info_g->num_period[1];
+ spin_unlock_irqrestore(&i2s_info_g->lock[1], flags);
+ i2s_info_g->callback[1](i2s_info_g->callback_param[1]);
+ }
+ }
+
+ if (msg->header.type == I2S_TYPE_B) {
+ memcpy(&i2s_info_g->recv_msg, msg, sizeof(struct i2s_rpmsg_r));
+ complete(&i2s_info_g->cmd_complete);
+ }
+
+ return 0;
+}
+
+static int i2s_rpmsg_probe(struct rpmsg_device *rpdev)
+{
+ struct platform_device *codec_pdev;
+ struct fsl_rpmsg_i2s *rpmsg_i2s = NULL;
+ struct fsl_rpmsg_codec rpmsg_codec[3];
+ int ret;
+
+ if (!i2s_info_g)
+ return 0;
+
+ i2s_info_g->rpdev = rpdev;
+
+ init_completion(&i2s_info_g->cmd_complete);
+
+ dev_info(&rpdev->dev, "new channel: 0x%x -> 0x%x!\n",
+ rpdev->src, rpdev->dst);
+
+ rpmsg_i2s = container_of(i2s_info_g, struct fsl_rpmsg_i2s, i2s_info);
+
+ if (rpmsg_i2s->codec_wm8960) {
+ rpmsg_codec[0].audioindex = rpmsg_i2s->codec_wm8960 >> 16;
+ rpmsg_codec[0].shared_lrclk = true;
+ rpmsg_codec[0].capless = false;
+ codec_pdev = platform_device_register_data(
+ &rpmsg_i2s->pdev->dev,
+ RPMSG_CODEC_DRV_NAME_WM8960,
+ PLATFORM_DEVID_NONE,
+ &rpmsg_codec[0], sizeof(struct fsl_rpmsg_codec));
+ if (IS_ERR(codec_pdev)) {
+ dev_err(&rpdev->dev,
+ "failed to register rpmsg audio codec\n");
+ ret = PTR_ERR(codec_pdev);
+ return ret;
+ }
+ }
+
+ if (rpmsg_i2s->codec_cs42888) {
+ rpmsg_codec[1].audioindex = rpmsg_i2s->codec_cs42888 >> 16;
+ strcpy(rpmsg_codec[1].name, "cs42888");
+ rpmsg_codec[1].num_adcs = 2;
+
+ codec_pdev = platform_device_register_data(
+ &rpmsg_i2s->pdev->dev,
+ RPMSG_CODEC_DRV_NAME_CS42888,
+ PLATFORM_DEVID_NONE,
+ &rpmsg_codec[1], sizeof(struct fsl_rpmsg_codec));
+ if (IS_ERR(codec_pdev)) {
+ dev_err(&rpdev->dev,
+ "failed to register rpmsg audio codec\n");
+ ret = PTR_ERR(codec_pdev);
+ return ret;
+ }
+ }
+
+ if (rpmsg_i2s->codec_ak4497) {
+ rpmsg_codec[2].audioindex = rpmsg_i2s->codec_ak4497 >> 16;
+ codec_pdev = platform_device_register_data(
+ &rpmsg_i2s->pdev->dev,
+ RPMSG_CODEC_DRV_NAME_AK4497,
+ PLATFORM_DEVID_NONE,
+ &rpmsg_codec[2], sizeof(struct fsl_rpmsg_codec));
+ if (IS_ERR(codec_pdev)) {
+ dev_err(&rpdev->dev,
+ "failed to register rpmsg audio codec\n");
+ ret = PTR_ERR(codec_pdev);
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+static void i2s_rpmsg_remove(struct rpmsg_device *rpdev)
+{
+ dev_info(&rpdev->dev, "i2s rpmsg driver is removed\n");
+}
+
+static struct rpmsg_device_id i2s_rpmsg_id_table[] = {
+ { .name = "rpmsg-audio-channel" },
+ { },
+};
+
+static struct rpmsg_driver i2s_rpmsg_driver = {
+ .drv.name = "i2s_rpmsg",
+ .drv.owner = THIS_MODULE,
+ .id_table = i2s_rpmsg_id_table,
+ .probe = i2s_rpmsg_probe,
+ .callback = i2s_rpmsg_cb,
+ .remove = i2s_rpmsg_remove,
+};
+
+static int __init i2s_rpmsg_init(void)
+{
+ return register_rpmsg_driver(&i2s_rpmsg_driver);
+}
+
+static void __exit i2s_rpmsg_exit(void)
+{
+ unregister_rpmsg_driver(&i2s_rpmsg_driver);
+}
+module_init(i2s_rpmsg_init);
+module_exit(i2s_rpmsg_exit);
+
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/fsl/imx-pcm.h b/sound/soc/fsl/imx-pcm.h
index 133c4470acad..c9c03d2b4aa5 100644
--- a/sound/soc/fsl/imx-pcm.h
+++ b/sound/soc/fsl/imx-pcm.h
@@ -43,13 +43,27 @@ struct imx_pcm_fiq_params {
struct snd_dmaengine_dai_dma_data *dma_params_tx;
};
+#if IS_ENABLED(CONFIG_SND_SOC_IMX_PCM_RPMSG)
+int imx_rpmsg_platform_register(struct device *dev);
+#else
+static inline int imx_rpmsg_platform_register(struct device *dev)
+{
+ return -ENODEV;
+}
+#endif
+
#if IS_ENABLED(CONFIG_SND_SOC_IMX_PCM_DMA)
int imx_pcm_dma_init(struct platform_device *pdev, size_t size);
+int imx_pcm_platform_register(struct device *dev);
#else
static inline int imx_pcm_dma_init(struct platform_device *pdev, size_t size)
{
return -ENODEV;
}
+static inline int imx_pcm_platform_register(struct device *dev)
+{
+ return -ENODEV;
+}
#endif
#if IS_ENABLED(CONFIG_SND_SOC_IMX_PCM_FIQ)
@@ -68,4 +82,39 @@ static inline void imx_pcm_fiq_exit(struct platform_device *pdev)
}
#endif
+static inline void imx_pcm_stream_trigger(struct snd_pcm_substream *s, int tr)
+{
+ if (s->runtime->status->state == SNDRV_PCM_STATE_RUNNING && s->ops)
+ s->ops->trigger(s, tr);
+}
+
+static inline void imx_stop_lock_pcm_streams(struct snd_pcm_substream **s,
+ int count, unsigned long *flags)
+{
+ int i;
+
+ local_irq_save(*flags);
+ for (i = 0; i < count; i++) {
+ if (!s[i])
+ continue;
+ snd_pcm_stream_lock(s[i]);
+ imx_pcm_stream_trigger(s[i], SNDRV_PCM_TRIGGER_STOP);
+ }
+}
+
+static inline void imx_start_unlock_pcm_streams(struct snd_pcm_substream **s,
+ int count, unsigned long *flags)
+{
+ int i;
+
+ for (i = count - 1; i >= 0; i--) {
+ if (!s[i])
+ continue;
+ imx_pcm_stream_trigger(s[i], SNDRV_PCM_TRIGGER_START);
+ snd_pcm_stream_unlock(s[i]);
+ }
+ local_irq_restore(*flags);
+}
+
+
#endif /* _IMX_PCM_H */
diff --git a/sound/soc/fsl/imx-pdm.c b/sound/soc/fsl/imx-pdm.c
new file mode 100644
index 000000000000..d69e27ec50c8
--- /dev/null
+++ b/sound/soc/fsl/imx-pdm.c
@@ -0,0 +1,195 @@
+/*
+ * Copyright 2017 NXP.
+ *
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/module.h>
+#include <linux/of_platform.h>
+#include <linux/slab.h>
+#include <linux/clk.h>
+#include <sound/soc.h>
+
+#include "fsl_sai.h"
+
+struct imx_pdm_data {
+ struct snd_soc_dai_link dai;
+ struct snd_soc_card card;
+ unsigned int decimation;
+};
+
+static u32 imx_pdm_mic_rates[] = { 8000, 16000, 32000, 48000, 64000 };
+static struct snd_pcm_hw_constraint_list imx_pdm_mic_rate_constrains = {
+ .count = ARRAY_SIZE(imx_pdm_mic_rates),
+ .list = imx_pdm_mic_rates,
+};
+static u32 imx_pdm_mic_channels[] = { 1 };
+static struct snd_pcm_hw_constraint_list imx_pdm_mic_channels_constrains = {
+ .count = ARRAY_SIZE(imx_pdm_mic_channels),
+ .list = imx_pdm_mic_channels,
+};
+
+static int imx_pdm_mic_startup(struct snd_pcm_substream *substream)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct snd_soc_card *card = rtd->card;
+ int ret;
+
+ ret = snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
+ &imx_pdm_mic_rate_constrains);
+ if (ret) {
+ dev_err(card->dev,
+ "fail to set pcm hw rate constrains: %d\n", ret);
+ return ret;
+ }
+
+ ret = snd_pcm_hw_constraint_list(runtime, 0,
+ SNDRV_PCM_HW_PARAM_CHANNELS, &imx_pdm_mic_channels_constrains);
+ if (ret) {
+ dev_err(card->dev,
+ "fail to set pcm hw channels constrains: %d", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int imx_pdm_mic_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+ struct snd_soc_card *card = rtd->card;
+ struct imx_pdm_data *data = snd_soc_card_get_drvdata(card);
+ int ret;
+
+ /* set cpu dai format configuration */
+ ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_DSP_A |
+ SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
+ if (ret) {
+ dev_err(card->dev, "fail to set cpu dai fmt: %d\n", ret);
+ return ret;
+ }
+ /* set tdm slots only one for now */
+ snd_soc_dai_set_tdm_slot(cpu_dai, 0, 0, 1, 32);
+ /* Set clock out */
+ ret = snd_soc_dai_set_bclk_ratio(cpu_dai, data->decimation);
+ if (ret) {
+ dev_err(card->dev, "fail to set cpu sysclk: %d\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static const struct snd_soc_ops imx_pdm_mic_ops = {
+ .startup = imx_pdm_mic_startup,
+ .hw_params = imx_pdm_mic_hw_params,
+};
+
+static int imx_pdm_mic_probe(struct platform_device *pdev)
+{
+ struct device_node *cpu_np = NULL;
+ struct device_node *np = pdev->dev.of_node;
+ struct platform_device *cpu_pdev;
+ struct imx_pdm_data *data;
+ int ret;
+
+ cpu_np = of_parse_phandle(np, "audio-cpu", 0);
+ if (!cpu_np) {
+ dev_err(&pdev->dev, "cpu dai phandle missing or invalid\n");
+ ret = -EINVAL;
+ goto fail;
+ }
+
+ cpu_pdev = of_find_device_by_node(cpu_np);
+ if (!cpu_pdev) {
+ dev_err(&pdev->dev, "fail to find SAI platform device\n");
+ ret = -EINVAL;
+ goto fail;
+ }
+
+ data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
+ if (!data) {
+ ret = -ENOMEM;
+ goto fail;
+ }
+
+ ret = of_property_read_u32(np, "decimation", &data->decimation);
+ if (ret < 0) {
+ ret = -EINVAL;
+ goto fail;
+ }
+
+ data->dai.name = "pdm hifi";
+ data->dai.stream_name = "pdm hifi";
+ data->dai.codec_dai_name = "snd-soc-dummy-dai";
+ data->dai.codec_name = "snd-soc-dummy";
+ data->dai.cpu_dai_name = dev_name(&cpu_pdev->dev);
+ data->dai.platform_of_node = cpu_np;
+ data->dai.capture_only = "true";
+ data->dai.ops = &imx_pdm_mic_ops;
+
+ data->card.dev = &pdev->dev;
+ data->card.owner = THIS_MODULE;
+
+ ret = snd_soc_of_parse_card_name(&data->card, "model");
+ if (ret) {
+ dev_err(&pdev->dev, "fail to find card model name\n");
+ goto fail;
+ }
+
+ data->card.num_links = 1;
+ data->card.dai_link = &data->dai;
+
+ platform_set_drvdata(pdev, &data->card);
+ snd_soc_card_set_drvdata(&data->card, data);
+
+ ret = devm_snd_soc_register_card(&pdev->dev, &data->card);
+ if (ret) {
+ dev_err(&pdev->dev, "snd soc register card failed: %d\n", ret);
+ goto fail;
+ }
+
+ ret = 0;
+fail:
+ if (cpu_np)
+ of_node_put(cpu_np);
+
+ return ret;
+}
+
+static int imx_pdm_mic_remove(struct platform_device *pdev)
+{
+ struct imx_pdm_data *data = platform_get_drvdata(pdev);
+ /* unregister card */
+ snd_soc_unregister_card(&data->card);
+ return 0;
+}
+
+static const struct of_device_id imx_pdm_mic_dt_ids[] = {
+ { .compatible = "fsl,imx-pdm-mic", },
+ { /* sentinel*/ }
+};
+MODULE_DEVICE_TABLE(of, imx_pdm_mic_dt_ids);
+
+static struct platform_driver imx_pdm_mic_driver = {
+ .driver = {
+ .name = "imx-pdm-mic",
+ .pm = &snd_soc_pm_ops,
+ .of_match_table = imx_pdm_mic_dt_ids,
+ },
+ .probe = imx_pdm_mic_probe,
+ .remove = imx_pdm_mic_remove,
+};
+module_platform_driver(imx_pdm_mic_driver);
+
+MODULE_DESCRIPTION("NXP i.MX PDM mic ASoC machine driver");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:imx-pdm-mic");
diff --git a/sound/soc/fsl/imx-rpmsg.c b/sound/soc/fsl/imx-rpmsg.c
new file mode 100644
index 000000000000..ad9e4c322de9
--- /dev/null
+++ b/sound/soc/fsl/imx-rpmsg.c
@@ -0,0 +1,163 @@
+/*
+ * Copyright (C) 2017 NXP
+ *
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/module.h>
+#include <linux/of_platform.h>
+#include <linux/i2c.h>
+#include <linux/of_gpio.h>
+#include <linux/slab.h>
+#include <linux/gpio.h>
+#include <linux/clk.h>
+#include <sound/soc.h>
+#include <sound/jack.h>
+#include <sound/control.h>
+#include <sound/pcm_params.h>
+#include <sound/soc-dapm.h>
+#include <linux/pinctrl/consumer.h>
+#include "fsl_rpmsg_i2s.h"
+
+struct imx_rpmsg_data {
+ struct snd_soc_dai_link dai[1];
+ struct snd_soc_card card;
+};
+
+static const struct snd_soc_dapm_widget imx_wm8960_dapm_widgets[] = {
+ SND_SOC_DAPM_HP("Headphone Jack", NULL),
+ SND_SOC_DAPM_SPK("Ext Spk", NULL),
+ SND_SOC_DAPM_MIC("Mic Jack", NULL),
+ SND_SOC_DAPM_MIC("Main MIC", NULL),
+};
+
+static int imx_rpmsg_probe(struct platform_device *pdev)
+{
+ struct device_node *cpu_np;
+ struct platform_device *cpu_pdev;
+ struct imx_rpmsg_data *data;
+ struct fsl_rpmsg_i2s *rpmsg_i2s;
+ int ret;
+
+ cpu_np = of_parse_phandle(pdev->dev.of_node, "cpu-dai", 0);
+ if (!cpu_np) {
+ dev_err(&pdev->dev, "cpu dai phandle missing or invalid\n");
+ ret = -EINVAL;
+ goto fail;
+ }
+
+ data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
+ if (!data) {
+ ret = -ENOMEM;
+ goto fail;
+ }
+
+ cpu_pdev = of_find_device_by_node(cpu_np);
+ if (!cpu_pdev) {
+ dev_err(&pdev->dev, "failed to find rpmsg platform device\n");
+ ret = -EINVAL;
+ goto fail;
+ }
+
+ rpmsg_i2s = platform_get_drvdata(cpu_pdev);
+
+ data->dai[0].name = "rpmsg hifi";
+ data->dai[0].stream_name = "rpmsg hifi";
+ data->dai[0].dai_fmt = SND_SOC_DAIFMT_I2S |
+ SND_SOC_DAIFMT_NB_NF |
+ SND_SOC_DAIFMT_CBM_CFM;
+
+ if (rpmsg_i2s->codec_wm8960) {
+ data->dai[0].codec_dai_name = "rpmsg-wm8960-hifi";
+ data->dai[0].codec_name = "rpmsg-audio-codec-wm8960";
+ }
+
+ if (rpmsg_i2s->codec_dummy) {
+ data->dai[0].codec_dai_name = "snd-soc-dummy-dai";
+ data->dai[0].codec_name = "snd-soc-dummy";
+ }
+
+ if (rpmsg_i2s->codec_ak4497) {
+ data->dai[0].codec_dai_name = "rpmsg-ak4497-aif";
+ data->dai[0].codec_name = "rpmsg-audio-codec-ak4497";
+ data->dai[0].dai_fmt = SND_SOC_DAIFMT_I2S |
+ SND_SOC_DAIFMT_NB_NF |
+ SND_SOC_DAIFMT_CBS_CFS;
+ }
+
+ data->dai[0].cpu_dai_name = dev_name(&cpu_pdev->dev);
+ data->dai[0].platform_of_node = cpu_np;
+ data->dai[0].playback_only = true;
+ data->dai[0].capture_only = true;
+ data->card.num_links = 1;
+ data->card.dai_link = data->dai;
+
+ if (of_property_read_bool(pdev->dev.of_node, "rpmsg-out"))
+ data->dai[0].capture_only = false;
+
+ if (of_property_read_bool(pdev->dev.of_node, "rpmsg-in"))
+ data->dai[0].playback_only = false;
+
+ if (data->dai[0].playback_only && data->dai[0].capture_only) {
+ dev_err(&pdev->dev, "no enabled rpmsg DAI link\n");
+ ret = -EINVAL;
+ goto fail;
+ }
+
+ data->card.dev = &pdev->dev;
+ data->card.owner = THIS_MODULE;
+ ret = snd_soc_of_parse_card_name(&data->card, "model");
+ if (ret)
+ goto fail;
+
+ if (rpmsg_i2s->codec_wm8960) {
+ ret = snd_soc_of_parse_audio_routing(&data->card,
+ "audio-routing");
+ if (ret)
+ goto fail;
+
+ data->card.dapm_widgets = imx_wm8960_dapm_widgets;
+ data->card.num_dapm_widgets =
+ ARRAY_SIZE(imx_wm8960_dapm_widgets);
+ }
+
+ platform_set_drvdata(pdev, &data->card);
+ snd_soc_card_set_drvdata(&data->card, data);
+ ret = devm_snd_soc_register_card(&pdev->dev, &data->card);
+ if (ret) {
+ dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret);
+ goto fail;
+ }
+
+fail:
+ if (cpu_np)
+ of_node_put(cpu_np);
+ return ret;
+}
+
+static const struct of_device_id imx_rpmsg_dt_ids[] = {
+ { .compatible = "fsl,imx-audio-rpmsg", },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, imx_rpmsg_dt_ids);
+
+static struct platform_driver imx_rpmsg_driver = {
+ .driver = {
+ .name = "imx-audio-rpmsg",
+ .owner = THIS_MODULE,
+ .pm = &snd_soc_pm_ops,
+ .of_match_table = imx_rpmsg_dt_ids,
+ },
+ .probe = imx_rpmsg_probe,
+};
+module_platform_driver(imx_rpmsg_driver);
+
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("Freescale i.MX rpmsg audio ASoC machine driver");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:imx-rpmsg");
diff --git a/sound/soc/fsl/imx-si476x.c b/sound/soc/fsl/imx-si476x.c
new file mode 100644
index 000000000000..767667f135a0
--- /dev/null
+++ b/sound/soc/fsl/imx-si476x.c
@@ -0,0 +1,205 @@
+/*
+ * Copyright (C) 2008-2016 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/module.h>
+#include <linux/of_platform.h>
+#include <linux/i2c.h>
+#include <sound/soc.h>
+
+#include "imx-audmux.h"
+
+static int imx_audmux_config(int slave, int master)
+{
+ unsigned int ptcr, pdcr;
+ slave = slave - 1;
+ master = master - 1;
+
+ ptcr = IMX_AUDMUX_V2_PTCR_SYN |
+ IMX_AUDMUX_V2_PTCR_TFSDIR |
+ IMX_AUDMUX_V2_PTCR_TFSEL(slave) |
+ IMX_AUDMUX_V2_PTCR_TCLKDIR |
+ IMX_AUDMUX_V2_PTCR_TCSEL(slave);
+ pdcr = IMX_AUDMUX_V2_PDCR_RXDSEL(slave);
+ imx_audmux_v2_configure_port(master, ptcr, pdcr);
+
+ /*
+ * According to RM, RCLKDIR and SYN should not be changed at same time.
+ * So separate to two step for configuring this port.
+ */
+ ptcr |= IMX_AUDMUX_V2_PTCR_RFSDIR |
+ IMX_AUDMUX_V2_PTCR_RFSEL(slave) |
+ IMX_AUDMUX_V2_PTCR_RCLKDIR |
+ IMX_AUDMUX_V2_PTCR_RCSEL(slave);
+ imx_audmux_v2_configure_port(master, ptcr, pdcr);
+
+ ptcr = IMX_AUDMUX_V2_PTCR_SYN;
+ pdcr = IMX_AUDMUX_V2_PDCR_RXDSEL(master);
+ imx_audmux_v2_configure_port(slave, ptcr, pdcr);
+
+ return 0;
+}
+
+static int imx_si476x_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+ u32 channels = params_channels(params);
+ u32 rate = params_rate(params);
+ u32 bclk = rate * channels * 32;
+ int ret = 0;
+
+ /* set cpu DAI configuration */
+ ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S
+ | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
+ if (ret) {
+ dev_err(cpu_dai->dev, "failed to set dai fmt\n");
+ return ret;
+ }
+
+ ret = snd_soc_dai_set_tdm_slot(cpu_dai,
+ channels == 1 ? 1 : 0x3,
+ channels == 1 ? 1 : 0x3,
+ 2, 32);
+ if (ret) {
+ dev_err(cpu_dai->dev, "failed to set dai tdm slot\n");
+ return ret;
+ }
+
+ ret = snd_soc_dai_set_sysclk(cpu_dai, 0, bclk, SND_SOC_CLOCK_OUT);
+ if (ret)
+ dev_err(cpu_dai->dev, "failed to set sysclk\n");
+
+ return ret;
+}
+
+static struct snd_soc_ops imx_si476x_ops = {
+ .hw_params = imx_si476x_hw_params,
+};
+
+static struct snd_soc_dai_link imx_dai = {
+ .name = "imx-si476x",
+ .stream_name = "imx-si476x",
+ .codec_dai_name = "si476x-codec",
+ .ops = &imx_si476x_ops,
+};
+
+static struct snd_soc_card snd_soc_card_imx_3stack = {
+ .name = "imx-audio-si476x",
+ .dai_link = &imx_dai,
+ .num_links = 1,
+ .owner = THIS_MODULE,
+};
+
+static int imx_si476x_probe(struct platform_device *pdev)
+{
+ struct snd_soc_card *card = &snd_soc_card_imx_3stack;
+ struct device_node *ssi_np, *np = pdev->dev.of_node;
+ struct platform_device *ssi_pdev;
+ struct i2c_client *fm_dev;
+ struct device_node *fm_np = NULL;
+ int int_port, ext_port, ret;
+
+ ret = of_property_read_u32(np, "mux-int-port", &int_port);
+ if (ret) {
+ dev_err(&pdev->dev, "mux-int-port missing or invalid\n");
+ return ret;
+ }
+
+ ret = of_property_read_u32(np, "mux-ext-port", &ext_port);
+ if (ret) {
+ dev_err(&pdev->dev, "mux-ext-port missing or invalid\n");
+ return ret;
+ }
+
+ imx_audmux_config(int_port, ext_port);
+
+ ssi_np = of_parse_phandle(pdev->dev.of_node, "ssi-controller", 0);
+ if (!ssi_np) {
+ dev_err(&pdev->dev, "phandle missing or invalid\n");
+ return -EINVAL;
+ }
+
+ ssi_pdev = of_find_device_by_node(ssi_np);
+ if (!ssi_pdev) {
+ dev_err(&pdev->dev, "failed to find SSI platform device\n");
+ ret = -EINVAL;
+ goto end;
+ }
+
+ fm_np = of_parse_phandle(pdev->dev.of_node, "fm-controller", 0);
+ if (!fm_np) {
+ dev_err(&pdev->dev, "phandle missing or invalid\n");
+ ret = -EINVAL;
+ goto end;
+ }
+
+ fm_dev = of_find_i2c_device_by_node(fm_np->parent);
+ if (!fm_dev || !fm_dev->dev.driver) {
+ dev_err(&pdev->dev, "failed to find FM platform device\n");
+ ret = -EINVAL;
+ goto end;
+ }
+
+ card->dev = &pdev->dev;
+ card->dai_link->cpu_dai_name = dev_name(&ssi_pdev->dev);
+ card->dai_link->platform_of_node = ssi_np;
+ card->dai_link->codec_of_node = fm_np;
+
+ platform_set_drvdata(pdev, card);
+
+ ret = snd_soc_register_card(card);
+ if (ret)
+ dev_err(&pdev->dev, "Failed to register card: %d\n", ret);
+
+end:
+ if (ssi_np)
+ of_node_put(ssi_np);
+ if (fm_np)
+ of_node_put(fm_np);
+
+ return ret;
+}
+
+static int imx_si476x_remove(struct platform_device *pdev)
+{
+ struct snd_soc_card *card = &snd_soc_card_imx_3stack;
+
+ snd_soc_unregister_card(card);
+
+ return 0;
+}
+
+static const struct of_device_id imx_si476x_dt_ids[] = {
+ { .compatible = "fsl,imx-audio-si476x", },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, imx_si476x_dt_ids);
+
+static struct platform_driver imx_si476x_driver = {
+ .driver = {
+ .name = "imx-tuner-si476x",
+ .pm = &snd_soc_pm_ops,
+ .of_match_table = imx_si476x_dt_ids,
+ },
+ .probe = imx_si476x_probe,
+ .remove = imx_si476x_remove,
+};
+
+module_platform_driver(imx_si476x_driver);
+
+/* Module information */
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("ALSA SoC i.MX si476x");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:imx-tuner-si476x");
diff --git a/sound/soc/fsl/imx-sii902x.c b/sound/soc/fsl/imx-sii902x.c
new file mode 100644
index 000000000000..b9059920415f
--- /dev/null
+++ b/sound/soc/fsl/imx-sii902x.c
@@ -0,0 +1,276 @@
+/*
+ * Copyright (C) 2015-2016 Freescale Semiconductor, Inc.
+ *
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/module.h>
+#include <linux/of_platform.h>
+#include <linux/i2c.h>
+#include <linux/of_gpio.h>
+#include <linux/slab.h>
+#include <linux/gpio.h>
+#include <linux/clk.h>
+#include <sound/soc.h>
+#include <sound/jack.h>
+#include <sound/control.h>
+#include <sound/pcm_params.h>
+#include <sound/soc-dapm.h>
+#include <linux/pinctrl/consumer.h>
+#include "fsl_sai.h"
+
+#define SUPPORT_RATE_NUM 10
+
+struct imx_sii902x_data {
+ struct snd_soc_dai_link dai;
+ struct snd_soc_card card;
+ struct i2c_client *sii902x;
+ bool is_stream_opened[2];
+};
+
+static int imx_sii902x_startup(struct snd_pcm_substream *substream)
+{
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ static struct snd_pcm_hw_constraint_list constraint_rates;
+ static u32 support_rates[SUPPORT_RATE_NUM];
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+ struct snd_soc_card *card = rtd->card;
+ struct imx_sii902x_data *data = snd_soc_card_get_drvdata(card);
+ struct fsl_sai *sai = dev_get_drvdata(cpu_dai->dev);
+ bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
+ int ret;
+
+ data->is_stream_opened[tx] = true;
+ if (data->is_stream_opened[tx] != sai->is_stream_opened[tx] ||
+ data->is_stream_opened[!tx] != sai->is_stream_opened[!tx]) {
+ data->is_stream_opened[tx] = false;
+ return -EBUSY;
+ }
+
+ support_rates[0] = 32000;
+ support_rates[1] = 48000;
+ support_rates[2] = 96000;
+ support_rates[3] = 192000;
+ constraint_rates.list = support_rates;
+ constraint_rates.count = 4;
+
+ ret = snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
+ &constraint_rates);
+ if (ret)
+ return ret;
+
+ ret = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_CHANNELS,
+ 1, 2);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+static int imx_sii902x_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+ struct snd_soc_card *card = rtd->card;
+ struct device *dev = card->dev;
+ struct imx_sii902x_data *data = snd_soc_card_get_drvdata(card);
+ int ret;
+ unsigned char reg;
+
+ /* set cpu DAI configuration */
+ ret = snd_soc_dai_set_fmt(cpu_dai,
+ SND_SOC_DAIFMT_LEFT_J |
+ SND_SOC_DAIFMT_NB_NF |
+ SND_SOC_DAIFMT_CBS_CFS);
+ if (ret) {
+ dev_err(dev, "failed to set cpu dai fmt: %d\n", ret);
+ return ret;
+ }
+
+ ret = snd_soc_dai_set_sysclk(cpu_dai, 0, 0, SND_SOC_CLOCK_OUT);
+ if (ret) {
+ dev_err(dev, "failed to set cpu sysclk: %d\n", ret);
+ return ret;
+ }
+
+ ret = snd_soc_dai_set_tdm_slot(cpu_dai, 0, 0, 2, 24);
+ if (ret) {
+ dev_err(dev, "failed to set cpu dai tdm slot: %d\n", ret);
+ return ret;
+ }
+
+ /* sii90sx hdmi audio setup */
+ i2c_smbus_write_byte_data(data->sii902x, 0x26, 0x90);
+ i2c_smbus_write_byte_data(data->sii902x, 0x20, 0x2d);
+ i2c_smbus_write_byte_data(data->sii902x, 0x1f, 0x88);
+ i2c_smbus_write_byte_data(data->sii902x, 0x1f, 0x91);
+ i2c_smbus_write_byte_data(data->sii902x, 0x1f, 0xa2);
+ i2c_smbus_write_byte_data(data->sii902x, 0x1f, 0xb3);
+ i2c_smbus_write_byte_data(data->sii902x, 0x27, 0);
+ switch (params_rate(params)) {
+ case 44100:
+ reg = 0;
+ break;
+ case 48000:
+ reg = 0x2;
+ break;
+ case 32000:
+ reg = 0x3;
+ break;
+ case 88200:
+ reg = 0x8;
+ break;
+ case 96000:
+ reg = 0xa;
+ break;
+ case 176400:
+ reg = 0xc;
+ break;
+ case 192000:
+ reg = 0xe;
+ break;
+ default:
+ reg = 0x1;
+ break;
+ }
+ i2c_smbus_write_byte_data(data->sii902x, 0x24, reg);
+ i2c_smbus_write_byte_data(data->sii902x, 0x25, 0x0b);
+ i2c_smbus_write_byte_data(data->sii902x, 0x26, 0x80);
+
+ return 0;
+}
+
+static int imx_sii902x_hw_free(struct snd_pcm_substream *substream)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_card *card = rtd->card;
+ struct imx_sii902x_data *data = snd_soc_card_get_drvdata(card);
+
+ i2c_smbus_write_byte_data(data->sii902x, 0x26, 0x10);
+
+ return 0;
+}
+
+static void imx_sii902x_shutdown(struct snd_pcm_substream *substream)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_card *card = rtd->card;
+ struct imx_sii902x_data *data = snd_soc_card_get_drvdata(card);
+ bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
+
+ data->is_stream_opened[tx] = false;
+}
+
+static struct snd_soc_ops imx_sii902x_ops = {
+ .startup = imx_sii902x_startup,
+ .shutdown = imx_sii902x_shutdown,
+ .hw_params = imx_sii902x_hw_params,
+ .hw_free = imx_sii902x_hw_free,
+};
+
+static int imx_sii902x_probe(struct platform_device *pdev)
+{
+ struct device_node *cpu_np, *sii902x_np = NULL;
+ struct platform_device *cpu_pdev;
+ struct imx_sii902x_data *data;
+ int ret;
+
+ cpu_np = of_parse_phandle(pdev->dev.of_node, "cpu-dai", 0);
+ if (!cpu_np) {
+ dev_err(&pdev->dev, "cpu dai phandle missing or invalid\n");
+ ret = -EINVAL;
+ goto fail;
+ }
+
+ sii902x_np = of_parse_phandle(pdev->dev.of_node, "hdmi-controler", 0);
+ if (!sii902x_np) {
+ dev_err(&pdev->dev, "sii902x phandle missing or invalid\n");
+ ret = -EINVAL;
+ goto fail;
+ }
+
+ cpu_pdev = of_find_device_by_node(cpu_np);
+ if (!cpu_pdev) {
+ dev_err(&pdev->dev, "failed to find SAI platform device\n");
+ ret = -EINVAL;
+ goto fail;
+ }
+
+ data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
+ if (!data) {
+ ret = -ENOMEM;
+ goto fail;
+ }
+
+ data->sii902x = of_find_i2c_device_by_node(sii902x_np);
+ if (!data->sii902x) {
+ dev_err(&pdev->dev, "failed to find sii902x i2c client\n");
+ ret = -EPROBE_DEFER;
+ goto fail;
+ }
+
+ data->dai.name = "sii902x hdmi";
+ data->dai.stream_name = "sii902x hdmi";
+ data->dai.codec_dai_name = "snd-soc-dummy-dai";
+ data->dai.codec_name = "snd-soc-dummy";
+ data->dai.cpu_dai_name = dev_name(&cpu_pdev->dev);
+ data->dai.platform_of_node = cpu_np;
+ data->dai.ops = &imx_sii902x_ops;
+ data->dai.playback_only = true;
+ data->dai.capture_only = false;
+ data->dai.dai_fmt = SND_SOC_DAIFMT_LEFT_J |
+ SND_SOC_DAIFMT_NB_NF |
+ SND_SOC_DAIFMT_CBS_CFS;
+
+ data->card.dev = &pdev->dev;
+ data->card.owner = THIS_MODULE;
+ ret = snd_soc_of_parse_card_name(&data->card, "model");
+ if (ret)
+ goto fail;
+ data->card.num_links = 1;
+ data->card.dai_link = &data->dai;
+
+ platform_set_drvdata(pdev, &data->card);
+ snd_soc_card_set_drvdata(&data->card, data);
+ ret = devm_snd_soc_register_card(&pdev->dev, &data->card);
+ if (ret) {
+ dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret);
+ goto fail;
+ }
+
+fail:
+ if (cpu_np)
+ of_node_put(cpu_np);
+ if (sii902x_np)
+ of_node_put(sii902x_np);
+ return ret;
+}
+
+static const struct of_device_id imx_sii902x_dt_ids[] = {
+ { .compatible = "fsl,imx-audio-sii902x", },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, imx_sii902x_dt_ids);
+
+static struct platform_driver imx_sii902x_driver = {
+ .driver = {
+ .name = "imx-sii902x",
+ .owner = THIS_MODULE,
+ .pm = &snd_soc_pm_ops,
+ .of_match_table = imx_sii902x_dt_ids,
+ },
+ .probe = imx_sii902x_probe,
+};
+module_platform_driver(imx_sii902x_driver);
+
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("Freescale i.MX SII902X hdmi audio ASoC machine driver");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:imx-sii902x");
diff --git a/sound/soc/fsl/imx-spdif.c b/sound/soc/fsl/imx-spdif.c
index fb896b2c9ba3..80a2dbdf272b 100644
--- a/sound/soc/fsl/imx-spdif.c
+++ b/sound/soc/fsl/imx-spdif.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013 Freescale Semiconductor, Inc.
+ * Copyright (C) 2013-2015 Freescale Semiconductor, Inc.
*
* The code contained herein is licensed under the GNU General Public
* License. You may obtain a copy of the GNU General Public License
@@ -12,12 +12,40 @@
#include <linux/module.h>
#include <linux/of_platform.h>
#include <sound/soc.h>
+#include "fsl_spdif.h"
struct imx_spdif_data {
struct snd_soc_dai_link dai;
struct snd_soc_card card;
};
+#define CLK_8K_FREQ 24576000
+#define CLK_11K_FREQ 22579200
+
+static int imx_spdif_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct device *dev = rtd->card->dev;
+ int ret = 0;
+ u64 rate = params_rate(params);
+ unsigned int freq;
+
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+ freq = do_div(rate, 8000) ? CLK_11K_FREQ : CLK_8K_FREQ;
+ ret = snd_soc_dai_set_sysclk(rtd->cpu_dai, STC_TXCLK_SPDIF_ROOT,
+ freq, SND_SOC_CLOCK_OUT);
+ if (ret)
+ dev_err(dev, "failed to set cpu sysclk: %d\n", ret);
+ }
+
+ return ret;
+}
+
+static struct snd_soc_ops imx_spdif_ops = {
+ .hw_params = imx_spdif_hw_params,
+};
+
static int imx_spdif_audio_probe(struct platform_device *pdev)
{
struct device_node *spdif_np, *np = pdev->dev.of_node;
@@ -45,6 +73,7 @@ static int imx_spdif_audio_probe(struct platform_device *pdev)
data->dai.platform_of_node = spdif_np;
data->dai.playback_only = true;
data->dai.capture_only = true;
+ data->dai.ops = &imx_spdif_ops;
if (of_property_read_bool(np, "spdif-out"))
data->dai.capture_only = false;
diff --git a/sound/soc/fsl/imx-wm8524.c b/sound/soc/fsl/imx-wm8524.c
new file mode 100644
index 000000000000..59978a6a80be
--- /dev/null
+++ b/sound/soc/fsl/imx-wm8524.c
@@ -0,0 +1,205 @@
+/*
+ * Copyright (C) 2015-2016 Freescale Semiconductor, Inc.
+ *
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/module.h>
+#include <linux/of_platform.h>
+#include <linux/of_gpio.h>
+#include <linux/slab.h>
+#include <linux/gpio.h>
+#include <linux/clk.h>
+#include <sound/soc.h>
+#include <sound/jack.h>
+#include <sound/control.h>
+#include <sound/pcm_params.h>
+#include <sound/soc-dapm.h>
+#include <linux/pinctrl/consumer.h>
+#include <linux/mfd/syscon.h>
+
+struct imx_priv {
+ struct platform_device *pdev;
+ struct snd_soc_card card;
+ struct clk *codec_clk;
+ unsigned int clk_frequency;
+};
+
+static const struct snd_soc_dapm_widget imx_wm8524_dapm_widgets[] = {
+ SND_SOC_DAPM_LINE("Line Out Jack", NULL),
+ SND_SOC_DAPM_LINE("Line In Jack", NULL),
+};
+
+static int imx_hifi_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+ struct snd_soc_card *card = rtd->card;
+ struct device *dev = card->dev;
+ unsigned int fmt;
+ int ret = 0;
+
+ fmt = SND_SOC_DAIFMT_I2S |
+ SND_SOC_DAIFMT_NB_NF |
+ SND_SOC_DAIFMT_CBS_CFS;
+
+ ret = snd_soc_dai_set_fmt(cpu_dai, fmt);
+ if (ret) {
+ dev_err(dev, "failed to set cpu dai fmt: %d\n", ret);
+ return ret;
+ }
+
+ ret = snd_soc_dai_set_tdm_slot(cpu_dai, 0, 0, 2,
+ params_physical_width(params));
+ if (ret) {
+ dev_err(dev, "failed to set cpu dai tdm slot: %d\n", ret);
+ return ret;
+ }
+
+ return ret;
+}
+
+static struct snd_soc_ops imx_hifi_ops = {
+ .hw_params = imx_hifi_hw_params,
+};
+
+static struct snd_soc_dai_link imx_wm8524_dai[] = {
+ {
+ .name = "HiFi",
+ .stream_name = "HiFi",
+ .codec_dai_name = "wm8524-hifi",
+ .ops = &imx_hifi_ops,
+ },
+};
+
+static int imx_wm8524_late_probe(struct snd_soc_card *card)
+{
+ struct snd_soc_pcm_runtime *rtd = list_first_entry(
+ &card->rtd_list, struct snd_soc_pcm_runtime, list);
+ struct snd_soc_dai *codec_dai = rtd->codec_dai;
+ struct imx_priv *priv = snd_soc_card_get_drvdata(card);
+ int ret;
+
+ priv->clk_frequency = clk_get_rate(priv->codec_clk);
+
+ ret = snd_soc_dai_set_sysclk(codec_dai, 0, priv->clk_frequency,
+ SND_SOC_CLOCK_IN);
+
+ return 0;
+}
+
+static int imx_wm8524_probe(struct platform_device *pdev)
+{
+ struct device_node *cpu_np, *codec_np = NULL;
+ struct platform_device *cpu_pdev;
+ struct imx_priv *priv;
+ struct platform_device *codec_pdev = NULL;
+ int ret;
+
+ priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ priv->pdev = pdev;
+
+ cpu_np = of_parse_phandle(pdev->dev.of_node, "audio-cpu", 0);
+ if (!cpu_np) {
+ dev_err(&pdev->dev, "cpu dai phandle missing or invalid\n");
+ ret = -EINVAL;
+ goto fail;
+ }
+
+ codec_np = of_parse_phandle(pdev->dev.of_node, "audio-codec", 0);
+ if (!codec_np) {
+ dev_err(&pdev->dev, "phandle missing or invalid\n");
+ ret = -EINVAL;
+ goto fail;
+ }
+
+ cpu_pdev = of_find_device_by_node(cpu_np);
+ if (!cpu_pdev) {
+ dev_err(&pdev->dev, "failed to find SAI platform device\n");
+ ret = -EINVAL;
+ goto fail;
+ }
+
+ codec_pdev = of_find_device_by_node(codec_np);
+ if (!codec_pdev || !codec_pdev->dev.driver) {
+ dev_err(&pdev->dev, "failed to find codec platform device\n");
+ ret = -EINVAL;
+ goto fail;
+ }
+
+ priv->codec_clk = devm_clk_get(&codec_pdev->dev, "mclk");
+ if (IS_ERR(priv->codec_clk)) {
+ ret = PTR_ERR(priv->codec_clk);
+ dev_err(&pdev->dev, "failed to get codec clk: %d\n", ret);
+ goto fail;
+ }
+
+ priv->card.dai_link = imx_wm8524_dai;
+
+ imx_wm8524_dai[0].codec_of_node = codec_np;
+ imx_wm8524_dai[0].cpu_dai_name = dev_name(&cpu_pdev->dev);
+ imx_wm8524_dai[0].platform_of_node = cpu_np;
+ imx_wm8524_dai[0].playback_only = 1;
+
+ priv->card.late_probe = imx_wm8524_late_probe;
+ priv->card.num_links = 1;
+ priv->card.dev = &pdev->dev;
+ priv->card.owner = THIS_MODULE;
+ priv->card.dapm_widgets = imx_wm8524_dapm_widgets;
+ priv->card.num_dapm_widgets = ARRAY_SIZE(imx_wm8524_dapm_widgets);
+
+ ret = snd_soc_of_parse_card_name(&priv->card, "model");
+ if (ret)
+ goto fail;
+
+ ret = snd_soc_of_parse_audio_routing(&priv->card, "audio-routing");
+ if (ret)
+ goto fail;
+
+ snd_soc_card_set_drvdata(&priv->card, priv);
+
+ ret = devm_snd_soc_register_card(&pdev->dev, &priv->card);
+ if (ret) {
+ dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret);
+ goto fail;
+ }
+
+ ret = 0;
+fail:
+ if (cpu_np)
+ of_node_put(cpu_np);
+ if (codec_np)
+ of_node_put(codec_np);
+
+ return ret;
+}
+
+static const struct of_device_id imx_wm8524_dt_ids[] = {
+ { .compatible = "fsl,imx-audio-wm8524", },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, imx_wm8524_dt_ids);
+
+static struct platform_driver imx_wm8524_driver = {
+ .driver = {
+ .name = "imx-wm8524",
+ .pm = &snd_soc_pm_ops,
+ .of_match_table = imx_wm8524_dt_ids,
+ },
+ .probe = imx_wm8524_probe,
+};
+module_platform_driver(imx_wm8524_driver);
+
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("Freescale i.MX WM8524 ASoC machine driver");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:imx-wm8524");
diff --git a/sound/soc/fsl/imx-wm8958.c b/sound/soc/fsl/imx-wm8958.c
new file mode 100644
index 000000000000..210f6662eb09
--- /dev/null
+++ b/sound/soc/fsl/imx-wm8958.c
@@ -0,0 +1,576 @@
+/*
+ * Copyright (C) 2015-2016 Freescale Semiconductor, Inc.
+ *
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/module.h>
+#include <linux/of_platform.h>
+#include <linux/i2c.h>
+#include <linux/of_gpio.h>
+#include <linux/slab.h>
+#include <linux/gpio.h>
+#include <linux/clk.h>
+#include <sound/soc.h>
+#include <sound/jack.h>
+#include <sound/control.h>
+#include <sound/pcm_params.h>
+#include <sound/soc-dapm.h>
+#include <linux/pinctrl/consumer.h>
+#include <linux/mfd/wm8994/registers.h>
+#include <linux/mfd/syscon.h>
+#include "../fsl/fsl_sai.h"
+#include "../codecs/wm8994.h"
+
+#define DAI_NAME_SIZE 32
+
+struct imx_wm8958_data {
+ struct snd_soc_dai_link dai;
+ struct snd_soc_card card;
+ char codec_dai_name[DAI_NAME_SIZE];
+ char platform_name[DAI_NAME_SIZE];
+ struct clk *mclk;
+ unsigned int clk_frequency;
+ bool is_codec_master;
+ int sr_stream[2];
+ struct regmap *gpr;
+};
+
+struct imx_priv {
+ int hp_gpio;
+ int hp_active_low;
+ struct snd_soc_codec *codec;
+ struct platform_device *pdev;
+};
+
+static struct imx_priv card_priv;
+
+static struct snd_soc_jack imx_hp_jack;
+
+static struct snd_soc_jack_pin imx_hp_jack_pins[] = {
+ {
+ .pin = "Headphone Jack",
+ .mask = SND_JACK_HEADPHONE,
+ },
+};
+
+static struct snd_soc_jack_gpio imx_hp_jack_gpio = {
+ .name = "headphone detect",
+ .report = SND_JACK_HEADPHONE,
+ .debounce_time = 250,
+ .invert = 1,
+};
+
+static int hpjack_status_check(void *data)
+{
+ struct imx_priv *priv = &card_priv;
+ struct platform_device *pdev = priv->pdev;
+ char *envp[3], *buf;
+ int hp_status, ret;
+
+ if (!gpio_is_valid(priv->hp_gpio))
+ return 0;
+
+ hp_status = gpio_get_value(priv->hp_gpio);
+ buf = kmalloc(32, GFP_ATOMIC);
+ if (!buf) {
+ dev_err(&pdev->dev, "%s kmalloc failed\n", __func__);
+ return -ENOMEM;
+ }
+
+ if (hp_status != priv->hp_active_low) {
+ snprintf(buf, 32, "STATE=%d", 2);
+ snd_soc_dapm_disable_pin(snd_soc_codec_get_dapm(priv->codec), "Ext Spk");
+ ret = imx_hp_jack_gpio.report;
+ } else {
+ snprintf(buf, 32, "STATE=%d", 0);
+ snd_soc_dapm_enable_pin(snd_soc_codec_get_dapm(priv->codec), "Ext Spk");
+ ret = 0;
+ }
+
+ envp[0] = "NAME=headphone";
+ envp[1] = buf;
+ envp[2] = NULL;
+ kobject_uevent_env(&pdev->dev.kobj, KOBJ_CHANGE, envp);
+ kfree(buf);
+
+ return ret;
+}
+
+static const struct snd_soc_dapm_widget imx_wm8958_dapm_widgets[] = {
+ SND_SOC_DAPM_HP("Headphone Jack", NULL),
+ SND_SOC_DAPM_SPK("Ext Spk", NULL),
+};
+
+static const struct snd_soc_dapm_route imx_wm8958_dapm_route[] = {
+ {"Headphone Jack", NULL, "HPOUT1L"},
+ {"Headphone Jack", NULL, "HPOUT1R"},
+ {"Ext Spk", NULL, "SPKOUTLP"},
+ {"Ext Spk", NULL, "SPKOUTLN"},
+ {"Ext Spk", NULL, "SPKOUTRP"},
+ {"Ext Spk", NULL, "SPKOUTRN"},
+ {"IN1LN", NULL, "MICBIAS2"},
+};
+
+static int imx_hifi_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_dai *codec_dai = rtd->codec_dai;
+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+ struct snd_soc_codec *codec = codec_dai->codec;
+ struct snd_soc_card *card = rtd->card;
+ struct device *dev = card->dev;
+ struct imx_wm8958_data *data = snd_soc_card_get_drvdata(card);
+ bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
+ unsigned int sample_rate = params_rate(params);
+ unsigned int pll_out;
+ int ret;
+
+ if (tx && params_width(params) == 24) {
+ if (sample_rate == 88200 || sample_rate == 96000 ||
+ sample_rate == 48000 || sample_rate == 44100) {
+ dev_err(dev, "Can't support sample rate %dHZ\n", sample_rate);
+ return -EINVAL;
+ }
+ } else if (!tx && params_width(params) == 24) {
+ if (sample_rate == 44100 || sample_rate == 48000) {
+ dev_err(dev, "Can't support sample rate %dHZ\n", sample_rate);
+ return -EINVAL;
+ }
+ }
+
+ ret = snd_soc_dai_set_fmt(codec_dai, data->dai.dai_fmt);
+ if (ret) {
+ dev_err(dev, "failed to set codec dai fmt: %d\n", ret);
+ return ret;
+ }
+
+ ret = snd_soc_dai_set_fmt(cpu_dai, data->dai.dai_fmt);
+ if (ret) {
+ dev_err(dev, "failed to set cpu dai fmt: %d\n", ret);
+ return ret;
+ }
+
+ data->clk_frequency = clk_get_rate(data->mclk);
+
+ if (!data->is_codec_master) {
+ ret = snd_soc_dai_set_sysclk(cpu_dai, 0, 0, SND_SOC_CLOCK_OUT);
+ if (ret) {
+ dev_err(dev, "failed to set cpu sysclk: %d\n", ret);
+ return ret;
+ }
+
+ ret = snd_soc_dai_set_sysclk(codec_dai, WM8994_FLL_SRC_MCLK1,
+ data->clk_frequency, SND_SOC_CLOCK_IN);
+ if (ret) {
+ dev_err(dev, "failed to set codec sysclk: %d\n", ret);
+ return ret;
+ }
+ } else {
+ data->sr_stream[tx] = sample_rate;
+
+ if (params_width(params) == 24)
+ pll_out = data->sr_stream[tx] * 384;
+ else
+ pll_out = data->sr_stream[tx] * 256;
+
+ ret = snd_soc_dai_set_pll(codec_dai, WM8994_FLL1,
+ WM8994_FLL_SRC_MCLK1,
+ data->clk_frequency,
+ pll_out);
+ if (ret) {
+ dev_err(dev, "failed to set codec pll: %d\n", ret);
+ return ret;
+ }
+
+ ret = snd_soc_dai_set_sysclk(cpu_dai, 0, 0, SND_SOC_CLOCK_IN);
+ if (ret) {
+ dev_err(dev, "failed to set cpu sysclk: %d\n", ret);
+ return ret;
+ }
+
+ ret = snd_soc_dai_set_sysclk(codec_dai, WM8994_SYSCLK_FLL1,
+ pll_out, SND_SOC_CLOCK_OUT);
+ if (ret) {
+ dev_err(dev, "failed to set codec sysclk: %d\n", ret);
+ return ret;
+ }
+ }
+
+ /*
+ * Set GPIO1 pin function to reserve, so that DAC1 and ADC1 using shared
+ * LRCLK from DACLRCK1.
+ */
+ snd_soc_update_bits(codec, WM8994_GPIO_1, 0x1f, 0x2);
+
+ /*
+ * Clear ADC_OSR128 bit to support slower SYSCLK, and support ADC sample
+ * rate 8K, 11.025K and 12K.
+ */
+ snd_soc_update_bits(codec, WM8994_OVERSAMPLING, 1<<1, 0);
+ return 0;
+}
+
+static int imx_hifi_hw_free(struct snd_pcm_substream *substream)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_dai *codec_dai = rtd->codec_dai;
+ struct snd_soc_card *card = rtd->card;
+ struct imx_wm8958_data *data = snd_soc_card_get_drvdata(card);
+ bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
+
+ if (data->is_codec_master &&
+ data->sr_stream[!tx] == 0 && data->sr_stream[tx]) {
+ /*
+ * We should connect AIF1CLK source to FLL after enable FLL, and
+ * disconnet AIF1CLK source to FLL before disable FLL, otherwise
+ * FLL worked abnormal.
+ */
+ snd_soc_dai_set_sysclk(codec_dai, WM8994_FLL_SRC_MCLK1,
+ data->clk_frequency, SND_SOC_CLOCK_OUT);
+
+ /* Disable FLL1 after all stream finished. */
+ snd_soc_dai_set_pll(codec_dai, WM8994_FLL1, 0, 0, 0);
+ }
+
+ data->sr_stream[tx] = 0;
+
+ return 0;
+}
+
+static u32 imx_wm8958_adc_rates[] = {
+ 8000, 11025, 12000, 16000, 22050,
+ 24000, 32000, 44100, 48000
+};
+
+static u32 imx_wm8958_dac_rates[] = {
+ 8000, 11025, 12000, 16000, 22050,
+ 24000, 32000, 44100, 48000, 88200, 96000
+};
+
+static struct snd_pcm_hw_constraint_list imx_wm8958_adc_rate_constraints = {
+ .count = ARRAY_SIZE(imx_wm8958_adc_rates),
+ .list = imx_wm8958_adc_rates,
+};
+
+static struct snd_pcm_hw_constraint_list imx_wm8958_dac_rate_constraints = {
+ .count = ARRAY_SIZE(imx_wm8958_dac_rates),
+ .list = imx_wm8958_dac_rates,
+};
+
+static int imx_hifi_startup(struct snd_pcm_substream *substream)
+{
+ bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
+ int ret = 0;
+
+ if (!tx)
+ ret = snd_pcm_hw_constraint_list(substream->runtime, 0,
+ SNDRV_PCM_HW_PARAM_RATE, &imx_wm8958_adc_rate_constraints);
+ else
+ ret = snd_pcm_hw_constraint_list(substream->runtime, 0,
+ SNDRV_PCM_HW_PARAM_RATE, &imx_wm8958_dac_rate_constraints);
+ return ret;
+}
+
+static struct snd_soc_ops imx_hifi_ops = {
+ .hw_params = imx_hifi_hw_params,
+ .hw_free = imx_hifi_hw_free,
+ .startup = imx_hifi_startup,
+};
+
+static int imx_wm8958_gpio_init(struct snd_soc_card *card)
+{
+ struct snd_soc_pcm_runtime *rtd = list_first_entry(
+ &card->rtd_list, struct snd_soc_pcm_runtime, list);
+ struct snd_soc_dai *codec_dai = rtd->codec_dai;
+ struct snd_soc_codec *codec = codec_dai->codec;
+ struct imx_priv *priv = &card_priv;
+ int ret;
+ priv->codec = codec;
+
+ if (gpio_is_valid(priv->hp_gpio)) {
+ imx_hp_jack_gpio.gpio = priv->hp_gpio;
+ imx_hp_jack_gpio.jack_status_check = hpjack_status_check;
+
+ ret = snd_soc_card_jack_new(card, "Headphone Jack",
+ SND_JACK_HEADPHONE, &imx_hp_jack,
+ imx_hp_jack_pins, ARRAY_SIZE(imx_hp_jack_pins));
+ if (ret)
+ return ret;
+
+ ret = snd_soc_jack_add_gpios(&imx_hp_jack, 1,
+ &imx_hp_jack_gpio);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
+static ssize_t headphone_show(struct device_driver *dev, char *buf)
+{
+ struct imx_priv *priv = &card_priv;
+ int hp_status;
+
+ if (!gpio_is_valid(priv->hp_gpio)) {
+ strcpy(buf, "no detect gpio connected\n");
+ return strlen(buf);
+ }
+
+ /* Check if headphone is plugged in */
+ hp_status = gpio_get_value(priv->hp_gpio);
+
+ if (hp_status != priv->hp_active_low)
+ strcpy(buf, "headphone\n");
+ else
+ strcpy(buf, "speaker\n");
+
+ return strlen(buf);
+}
+
+static DRIVER_ATTR_RO(headphone);
+
+static int imx_wm8958_set_bias_level(struct snd_soc_card *card,
+ struct snd_soc_dapm_context *dapm,
+ enum snd_soc_bias_level level)
+{
+ struct snd_soc_pcm_runtime *rtd = list_first_entry(
+ &card->rtd_list, struct snd_soc_pcm_runtime, list);
+ struct snd_soc_dai *codec_dai = rtd->codec_dai;
+ struct imx_wm8958_data *data = snd_soc_card_get_drvdata(card);
+ int ret;
+
+ if (dapm->dev != codec_dai->dev)
+ return 0;
+
+ switch (level) {
+ case SND_SOC_BIAS_STANDBY:
+ if (card->dapm.bias_level == SND_SOC_BIAS_OFF) {
+ if (!IS_ERR(data->mclk)) {
+ ret = clk_prepare_enable(data->mclk);
+ if (ret) {
+ dev_err(card->dev,
+ "Failed to enable MCLK: %d\n",
+ ret);
+ return ret;
+ }
+ }
+ }
+ break;
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+static int imx_wm8958_set_bias_level_post(struct snd_soc_card *card,
+ struct snd_soc_dapm_context *dapm,
+ enum snd_soc_bias_level level)
+{
+ struct snd_soc_pcm_runtime *rtd = list_first_entry(
+ &card->rtd_list, struct snd_soc_pcm_runtime, list);
+ struct snd_soc_dai *codec_dai = rtd->codec_dai;
+ struct imx_wm8958_data *data = snd_soc_card_get_drvdata(card);
+
+ if (dapm->dev != codec_dai->dev)
+ return 0;
+
+ switch (level) {
+ case SND_SOC_BIAS_OFF:
+ if (card->dapm.bias_level == SND_SOC_BIAS_STANDBY)
+ if (!IS_ERR(data->mclk))
+ clk_disable_unprepare(data->mclk);
+ break;
+ default:
+ break;
+ }
+
+ card->dapm.bias_level = level;
+
+ return 0;
+}
+
+static int of_parse_gpr(struct platform_device *pdev,
+ struct imx_wm8958_data *data)
+{
+ int ret;
+ struct of_phandle_args args;
+
+ if (of_device_is_compatible(pdev->dev.of_node,
+ "fsl,imx7d-12x12-lpddr3-arm2-wm8958"))
+ return 0;
+
+ ret = of_parse_phandle_with_fixed_args(pdev->dev.of_node,
+ "gpr", 3, 0, &args);
+ if (ret) {
+ dev_warn(&pdev->dev, "failed to get gpr property\n");
+ return ret;
+ }
+
+ data->gpr = syscon_node_to_regmap(args.np);
+ if (IS_ERR(data->gpr)) {
+ ret = PTR_ERR(data->gpr);
+ dev_err(&pdev->dev, "failed to get gpr regmap\n");
+ return ret;
+ }
+
+ regmap_update_bits(data->gpr, args.args[0], args.args[1],
+ args.args[2]);
+
+ return 0;
+}
+
+static int imx_wm8958_probe(struct platform_device *pdev)
+{
+ struct device_node *cpu_np, *codec_np = NULL;
+ struct device_node *np = pdev->dev.of_node;
+ struct platform_device *cpu_pdev;
+ struct imx_priv *priv = &card_priv;
+ struct i2c_client *codec_dev;
+ struct imx_wm8958_data *data;
+ int ret;
+
+ priv->pdev = pdev;
+
+ cpu_np = of_parse_phandle(np, "cpu-dai", 0);
+ if (!cpu_np) {
+ dev_err(&pdev->dev, "cpu dai phandle missing or invalid\n");
+ ret = -EINVAL;
+ goto fail;
+ }
+
+ codec_np = of_parse_phandle(np, "audio-codec", 0);
+ if (!codec_np) {
+ dev_err(&pdev->dev, "phandle missing or invalid\n");
+ ret = -EINVAL;
+ goto fail;
+ }
+
+ cpu_pdev = of_find_device_by_node(cpu_np);
+ if (!cpu_pdev) {
+ dev_err(&pdev->dev, "failed to find SAI platform device\n");
+ ret = -EINVAL;
+ goto fail;
+ }
+
+ codec_dev = of_find_i2c_device_by_node(codec_np);
+ if (!codec_dev || !codec_dev->dev.driver) {
+ dev_err(&pdev->dev, "failed to find codec platform device\n");
+ ret = -EINVAL;
+ goto fail;
+ }
+
+ data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
+ if (!data) {
+ ret = -ENOMEM;
+ goto fail;
+ }
+
+ ret = of_parse_gpr(pdev, data);
+ if (ret)
+ goto fail;
+
+ if (of_property_read_bool(np, "codec-master")) {
+ data->dai.dai_fmt = SND_SOC_DAIFMT_CBM_CFM;
+ data->is_codec_master = true;
+ } else
+ data->dai.dai_fmt = SND_SOC_DAIFMT_CBS_CFS;
+
+ data->mclk = devm_clk_get(&codec_dev->dev, "mclk1");
+ if (IS_ERR(data->mclk)) {
+ ret = PTR_ERR(data->mclk);
+ dev_err(&pdev->dev, "failed to get codec clk: %d\n", ret);
+ goto fail;
+ }
+
+ priv->hp_gpio = of_get_named_gpio_flags(np, "hp-det-gpios", 0,
+ (enum of_gpio_flags *)&priv->hp_active_low);
+
+ data->dai.name = "HiFi";
+ data->dai.stream_name = "HiFi";
+ data->dai.codec_dai_name = "wm8994-aif1";
+ data->dai.codec_name = "wm8994-codec";
+ data->dai.cpu_dai_name = dev_name(&cpu_pdev->dev);
+ data->dai.platform_of_node = cpu_np;
+ data->dai.ops = &imx_hifi_ops;
+ data->dai.dai_fmt |= SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF;
+ data->card.set_bias_level = imx_wm8958_set_bias_level;
+ data->card.set_bias_level_post = imx_wm8958_set_bias_level_post;
+ data->card.owner = THIS_MODULE;
+
+ data->card.dev = &pdev->dev;
+ ret = snd_soc_of_parse_card_name(&data->card, "model");
+ if (ret)
+ goto fail;
+
+ data->card.num_links = 1;
+ data->card.dai_link = &data->dai;
+ data->card.dapm_widgets = imx_wm8958_dapm_widgets;
+ data->card.num_dapm_widgets = ARRAY_SIZE(imx_wm8958_dapm_widgets);
+ data->card.dapm_routes = imx_wm8958_dapm_route;
+ data->card.num_dapm_routes = ARRAY_SIZE(imx_wm8958_dapm_route);
+ platform_set_drvdata(pdev, &data->card);
+ snd_soc_card_set_drvdata(&data->card, data);
+
+ ret = devm_snd_soc_register_card(&pdev->dev, &data->card);
+ if (ret) {
+ dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret);
+ goto fail;
+ }
+
+ ret = imx_wm8958_gpio_init(&data->card);
+
+ if (gpio_is_valid(priv->hp_gpio)) {
+ ret = driver_create_file(pdev->dev.driver,
+ &driver_attr_headphone);
+ if (ret) {
+ dev_err(&pdev->dev,
+ "create hp attr failed (%d)\n", ret);
+ goto fail;
+ }
+ }
+
+fail:
+ if (cpu_np)
+ of_node_put(cpu_np);
+ if (codec_np)
+ of_node_put(codec_np);
+
+ return ret;
+}
+
+static int imx_wm8958_remove(struct platform_device *pdev)
+{
+ driver_remove_file(pdev->dev.driver, &driver_attr_headphone);
+ return 0;
+}
+
+static const struct of_device_id imx_wm8958_dt_ids[] = {
+ { .compatible = "fsl,imx-audio-wm8958", },
+ { .compatible = "fsl,imx7d-12x12-lpddr3-arm2-wm8958", },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, imx_wm8958_dt_ids);
+
+static struct platform_driver imx_wm8958_driver = {
+ .driver = {
+ .name = "imx-wm8958",
+ .pm = &snd_soc_pm_ops,
+ .of_match_table = imx_wm8958_dt_ids,
+ },
+ .probe = imx_wm8958_probe,
+ .remove = imx_wm8958_remove,
+};
+module_platform_driver(imx_wm8958_driver);
+
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("Freescale i.MX WM8958 ASoC machine driver");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:imx-wm8958");
diff --git a/sound/soc/fsl/imx-wm8960.c b/sound/soc/fsl/imx-wm8960.c
new file mode 100644
index 000000000000..a72b70007962
--- /dev/null
+++ b/sound/soc/fsl/imx-wm8960.c
@@ -0,0 +1,689 @@
+/*
+ * Copyright (C) 2015-2016 Freescale Semiconductor, Inc.
+ *
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/module.h>
+#include <linux/of_platform.h>
+#include <linux/i2c.h>
+#include <linux/of_gpio.h>
+#include <linux/slab.h>
+#include <linux/gpio.h>
+#include <linux/clk.h>
+#include <sound/soc.h>
+#include <sound/jack.h>
+#include <sound/control.h>
+#include <sound/pcm_params.h>
+#include <sound/soc-dapm.h>
+#include <linux/pinctrl/consumer.h>
+#include <linux/mfd/syscon.h>
+#include "../codecs/wm8960.h"
+#include "fsl_sai.h"
+
+struct imx_wm8960_data {
+ struct snd_soc_card card;
+ struct clk *codec_clk;
+ unsigned int clk_frequency;
+ bool is_codec_master;
+ bool is_codec_rpmsg;
+ bool is_stream_in_use[2];
+ bool is_stream_opened[2];
+ struct regmap *gpr;
+ unsigned int hp_det[2];
+ u32 asrc_rate;
+ u32 asrc_format;
+};
+
+struct imx_priv {
+ enum of_gpio_flags hp_active_low;
+ enum of_gpio_flags mic_active_low;
+ bool is_headset_jack;
+ struct platform_device *pdev;
+ struct platform_device *asrc_pdev;
+};
+
+static struct imx_priv card_priv;
+
+static struct snd_soc_jack imx_hp_jack;
+static struct snd_soc_jack_pin imx_hp_jack_pin = {
+ .pin = "Headphone Jack",
+ .mask = SND_JACK_HEADPHONE,
+};
+static struct snd_soc_jack_gpio imx_hp_jack_gpio = {
+ .name = "headphone detect",
+ .report = SND_JACK_HEADPHONE,
+ .debounce_time = 250,
+ .invert = 0,
+};
+
+static struct snd_soc_jack imx_mic_jack;
+static struct snd_soc_jack_pin imx_mic_jack_pins = {
+ .pin = "Mic Jack",
+ .mask = SND_JACK_MICROPHONE,
+};
+static struct snd_soc_jack_gpio imx_mic_jack_gpio = {
+ .name = "mic detect",
+ .report = SND_JACK_MICROPHONE,
+ .debounce_time = 250,
+ .invert = 0,
+};
+
+static int hp_jack_status_check(void *data)
+{
+ struct imx_priv *priv = &card_priv;
+ struct snd_soc_jack *jack = data;
+ struct snd_soc_dapm_context *dapm = &jack->card->dapm;
+ int hp_status, ret;
+
+ hp_status = gpio_get_value(imx_hp_jack_gpio.gpio);
+
+ if (hp_status != priv->hp_active_low) {
+ snd_soc_dapm_disable_pin(dapm, "Ext Spk");
+ if (priv->is_headset_jack) {
+ snd_soc_dapm_enable_pin(dapm, "Mic Jack");
+ snd_soc_dapm_disable_pin(dapm, "Main MIC");
+ }
+ ret = imx_hp_jack_gpio.report;
+ } else {
+ snd_soc_dapm_enable_pin(dapm, "Ext Spk");
+ if (priv->is_headset_jack) {
+ snd_soc_dapm_disable_pin(dapm, "Mic Jack");
+ snd_soc_dapm_enable_pin(dapm, "Main MIC");
+ }
+ ret = 0;
+ }
+
+ return ret;
+}
+
+static int mic_jack_status_check(void *data)
+{
+ struct imx_priv *priv = &card_priv;
+ struct snd_soc_jack *jack = data;
+ struct snd_soc_dapm_context *dapm = &jack->card->dapm;
+ int mic_status, ret;
+
+ mic_status = gpio_get_value(imx_mic_jack_gpio.gpio);
+
+ if (mic_status != priv->mic_active_low) {
+ snd_soc_dapm_disable_pin(dapm, "Main MIC");
+ ret = imx_mic_jack_gpio.report;
+ } else {
+ snd_soc_dapm_enable_pin(dapm, "Main MIC");
+ ret = 0;
+ }
+
+ return ret;
+}
+
+static const struct snd_soc_dapm_widget imx_wm8960_dapm_widgets[] = {
+ SND_SOC_DAPM_HP("Headphone Jack", NULL),
+ SND_SOC_DAPM_SPK("Ext Spk", NULL),
+ SND_SOC_DAPM_MIC("Mic Jack", NULL),
+ SND_SOC_DAPM_MIC("Main MIC", NULL),
+};
+
+static int imx_wm8960_jack_init(struct snd_soc_card *card,
+ struct snd_soc_jack *jack, struct snd_soc_jack_pin *pin,
+ struct snd_soc_jack_gpio *gpio)
+{
+ int ret;
+
+ ret = snd_soc_card_jack_new(card, pin->pin, pin->mask, jack, pin, 1);
+ if (ret) {
+ return ret;
+ }
+
+ ret = snd_soc_jack_add_gpios(jack, 1, gpio);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+static ssize_t headphone_show(struct device_driver *dev, char *buf)
+{
+ struct imx_priv *priv = &card_priv;
+ int hp_status;
+
+ /* Check if headphone is plugged in */
+ hp_status = gpio_get_value(imx_hp_jack_gpio.gpio);
+
+ if (hp_status != priv->hp_active_low)
+ strcpy(buf, "Headphone\n");
+ else
+ strcpy(buf, "Speaker\n");
+
+ return strlen(buf);
+}
+
+static ssize_t micphone_show(struct device_driver *dev, char *buf)
+{
+ struct imx_priv *priv = &card_priv;
+ int mic_status;
+
+ /* Check if headphone is plugged in */
+ mic_status = gpio_get_value(imx_mic_jack_gpio.gpio);
+
+ if (mic_status != priv->mic_active_low)
+ strcpy(buf, "Mic Jack\n");
+ else
+ strcpy(buf, "Main MIC\n");
+
+ return strlen(buf);
+}
+static DRIVER_ATTR_RO(headphone);
+static DRIVER_ATTR_RO(micphone);
+
+static int imx_hifi_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_dai *codec_dai = rtd->codec_dai;
+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+ struct snd_soc_card *card = rtd->card;
+ struct imx_wm8960_data *data = snd_soc_card_get_drvdata(card);
+ bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
+ struct device *dev = card->dev;
+ unsigned int sample_rate = params_rate(params);
+ unsigned int pll_out;
+ unsigned int fmt;
+ int ret = 0;
+
+ data->is_stream_in_use[tx] = true;
+
+ if (data->is_stream_in_use[!tx])
+ return 0;
+
+ if (data->is_codec_master)
+ fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
+ SND_SOC_DAIFMT_CBM_CFM;
+ else
+ fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
+ SND_SOC_DAIFMT_CBS_CFS;
+
+ /* set cpu DAI configuration */
+ ret = snd_soc_dai_set_fmt(cpu_dai, fmt);
+ if (ret) {
+ dev_err(dev, "failed to set cpu dai fmt: %d\n", ret);
+ return ret;
+ }
+ /* set codec DAI configuration */
+ ret = snd_soc_dai_set_fmt(codec_dai, fmt);
+ if (ret) {
+ dev_err(dev, "failed to set codec dai fmt: %d\n", ret);
+ return ret;
+ }
+
+ if (!data->is_codec_master) {
+ ret = snd_soc_dai_set_tdm_slot(cpu_dai, 0, 0, 2,
+ params_physical_width(params));
+ if (ret) {
+ dev_err(dev, "failed to set cpu dai tdm slot: %d\n", ret);
+ return ret;
+ }
+
+ ret = snd_soc_dai_set_sysclk(cpu_dai, 0, 0, SND_SOC_CLOCK_OUT);
+ if (ret) {
+ dev_err(dev, "failed to set cpu sysclk: %d\n", ret);
+ return ret;
+ }
+ return 0;
+ } else {
+ ret = snd_soc_dai_set_sysclk(cpu_dai, 0, 0, SND_SOC_CLOCK_IN);
+ if (ret) {
+ dev_err(dev, "failed to set cpu sysclk: %d\n", ret);
+ return ret;
+ }
+ }
+
+ data->clk_frequency = clk_get_rate(data->codec_clk);
+
+ /* Set codec pll */
+ if (params_width(params) == 24)
+ pll_out = sample_rate * 768;
+ else
+ pll_out = sample_rate * 512;
+
+ ret = snd_soc_dai_set_pll(codec_dai, WM8960_SYSCLK_AUTO, 0, data->clk_frequency, pll_out);
+ if (ret)
+ return ret;
+ ret = snd_soc_dai_set_sysclk(codec_dai, WM8960_SYSCLK_AUTO, pll_out, 0);
+
+ return ret;
+}
+
+static int imx_hifi_hw_free(struct snd_pcm_substream *substream)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_dai *codec_dai = rtd->codec_dai;
+ struct snd_soc_card *card = rtd->card;
+ struct imx_wm8960_data *data = snd_soc_card_get_drvdata(card);
+ bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
+ struct device *dev = card->dev;
+ int ret;
+
+ data->is_stream_in_use[tx] = false;
+
+ if (data->is_codec_master && !data->is_stream_in_use[!tx]) {
+ ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_CBS_CFS | SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF);
+ if (ret)
+ dev_warn(dev, "failed to set codec dai fmt: %d\n", ret);
+ }
+
+ return 0;
+}
+
+static u32 imx_wm8960_rates[] = { 8000, 16000, 32000, 48000 };
+static struct snd_pcm_hw_constraint_list imx_wm8960_rate_constraints = {
+ .count = ARRAY_SIZE(imx_wm8960_rates),
+ .list = imx_wm8960_rates,
+};
+
+static int imx_hifi_startup(struct snd_pcm_substream *substream)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+ struct snd_soc_card *card = rtd->card;
+ struct imx_wm8960_data *data = snd_soc_card_get_drvdata(card);
+ bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
+ struct fsl_sai *sai = dev_get_drvdata(cpu_dai->dev);
+ int ret = 0;
+
+ data->is_stream_opened[tx] = true;
+ if (data->is_stream_opened[tx] != sai->is_stream_opened[tx] ||
+ data->is_stream_opened[!tx] != sai->is_stream_opened[!tx]) {
+ data->is_stream_opened[tx] = false;
+ return -EBUSY;
+ }
+
+ if (!data->is_codec_master) {
+ ret = snd_pcm_hw_constraint_list(substream->runtime, 0,
+ SNDRV_PCM_HW_PARAM_RATE, &imx_wm8960_rate_constraints);
+ if (ret)
+ return ret;
+ }
+
+ return ret;
+}
+
+static void imx_hifi_shutdown(struct snd_pcm_substream *substream)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_card *card = rtd->card;
+ struct imx_wm8960_data *data = snd_soc_card_get_drvdata(card);
+ bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
+
+ data->is_stream_opened[tx] = false;
+}
+
+static struct snd_soc_ops imx_hifi_ops = {
+ .hw_params = imx_hifi_hw_params,
+ .hw_free = imx_hifi_hw_free,
+ .startup = imx_hifi_startup,
+ .shutdown = imx_hifi_shutdown,
+};
+
+static int imx_wm8960_late_probe(struct snd_soc_card *card)
+{
+ struct snd_soc_pcm_runtime *rtd = list_first_entry(
+ &card->rtd_list, struct snd_soc_pcm_runtime, list);
+ struct snd_soc_dai *codec_dai = rtd->codec_dai;
+ struct snd_soc_codec *codec = codec_dai->codec;
+ struct imx_wm8960_data *data = snd_soc_card_get_drvdata(card);
+
+ /*
+ * codec ADCLRC pin configured as GPIO, DACLRC pin is used as a frame
+ * clock for ADCs and DACs
+ */
+ snd_soc_update_bits(codec, WM8960_IFACE2, 1<<6, 1<<6);
+
+ /* GPIO1 used as headphone detect output */
+ snd_soc_update_bits(codec, WM8960_ADDCTL4, 7<<4, 3<<4);
+
+ /* Enable headphone jack detect */
+ snd_soc_update_bits(codec, WM8960_ADDCTL2, 1<<6, 1<<6);
+ snd_soc_update_bits(codec, WM8960_ADDCTL2, 1<<5, data->hp_det[1]<<5);
+ snd_soc_update_bits(codec, WM8960_ADDCTL4, 3<<2, data->hp_det[0]<<2);
+ snd_soc_update_bits(codec, WM8960_ADDCTL1, 3, 3);
+
+ return 0;
+}
+
+static int be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_soc_card *card = rtd->card;
+ struct imx_wm8960_data *data = snd_soc_card_get_drvdata(card);
+ struct imx_priv *priv = &card_priv;
+ struct snd_interval *rate;
+ struct snd_mask *mask;
+
+ if (!priv->asrc_pdev)
+ return -EINVAL;
+
+ rate = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
+ rate->max = rate->min = data->asrc_rate;
+
+ mask = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
+ snd_mask_none(mask);
+ snd_mask_set(mask, data->asrc_format);
+
+ return 0;
+}
+
+static struct snd_soc_dai_link imx_wm8960_dai[] = {
+ {
+ .name = "HiFi",
+ .stream_name = "HiFi",
+ .codec_dai_name = "wm8960-hifi",
+ .ops = &imx_hifi_ops,
+ },
+ {
+ .name = "HiFi-ASRC-FE",
+ .stream_name = "HiFi-ASRC-FE",
+ .codec_name = "snd-soc-dummy",
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .dynamic = 1,
+ .ignore_pmdown_time = 1,
+ .dpcm_playback = 1,
+ .dpcm_capture = 1,
+ .dpcm_merged_chan = 1,
+ },
+ {
+ .name = "HiFi-ASRC-BE",
+ .stream_name = "HiFi-ASRC-BE",
+ .codec_dai_name = "wm8960-hifi",
+ .platform_name = "snd-soc-dummy",
+ .no_pcm = 1,
+ .ignore_pmdown_time = 1,
+ .dpcm_playback = 1,
+ .dpcm_capture = 1,
+ .ops = &imx_hifi_ops,
+ .be_hw_params_fixup = be_hw_params_fixup,
+ },
+};
+
+static int of_parse_gpr(struct platform_device *pdev,
+ struct imx_wm8960_data *data)
+{
+ int ret;
+ struct of_phandle_args args;
+
+ if (of_device_is_compatible(pdev->dev.of_node,
+ "fsl,imx7d-evk-wm8960"))
+ return 0;
+
+ ret = of_parse_phandle_with_fixed_args(pdev->dev.of_node,
+ "gpr", 3, 0, &args);
+ if (ret) {
+ dev_warn(&pdev->dev, "failed to get gpr property\n");
+ return ret;
+ }
+
+ data->gpr = syscon_node_to_regmap(args.np);
+ if (IS_ERR(data->gpr)) {
+ ret = PTR_ERR(data->gpr);
+ dev_err(&pdev->dev, "failed to get gpr regmap\n");
+ return ret;
+ }
+
+ regmap_update_bits(data->gpr, args.args[0], args.args[1],
+ args.args[2]);
+
+ return 0;
+}
+
+static int imx_wm8960_probe(struct platform_device *pdev)
+{
+ struct device_node *cpu_np = NULL, *codec_np = NULL;
+ struct platform_device *cpu_pdev;
+ struct imx_priv *priv = &card_priv;
+ struct imx_wm8960_data *data;
+ struct platform_device *asrc_pdev = NULL;
+ struct device_node *asrc_np;
+ u32 width;
+ int ret;
+
+ priv->pdev = pdev;
+
+ data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
+ if (!data) {
+ ret = -ENOMEM;
+ goto fail;
+ }
+
+ if (of_property_read_bool(pdev->dev.of_node, "codec-rpmsg"))
+ data->is_codec_rpmsg = true;
+
+ cpu_np = of_parse_phandle(pdev->dev.of_node, "cpu-dai", 0);
+ if (!cpu_np) {
+ dev_err(&pdev->dev, "cpu dai phandle missing or invalid\n");
+ ret = -EINVAL;
+ goto fail;
+ }
+
+ cpu_pdev = of_find_device_by_node(cpu_np);
+ if (!cpu_pdev) {
+ dev_err(&pdev->dev, "failed to find SAI platform device\n");
+ ret = -EINVAL;
+ goto fail;
+ }
+
+ codec_np = of_parse_phandle(pdev->dev.of_node, "audio-codec", 0);
+ if (!codec_np) {
+ dev_err(&pdev->dev, "phandle missing or invalid\n");
+ ret = -EINVAL;
+ goto fail;
+ }
+
+ if (data->is_codec_rpmsg) {
+ struct platform_device *codec_dev;
+
+ codec_dev = of_find_device_by_node(codec_np);
+ if (!codec_dev || !codec_dev->dev.driver) {
+ dev_err(&pdev->dev, "failed to find codec platform device\n");
+ ret = -EINVAL;
+ goto fail;
+ }
+
+ data->codec_clk = devm_clk_get(&codec_dev->dev, "mclk");
+ if (IS_ERR(data->codec_clk)) {
+ ret = PTR_ERR(data->codec_clk);
+ dev_err(&pdev->dev, "failed to get codec clk: %d\n", ret);
+ goto fail;
+ }
+ } else {
+ struct i2c_client *codec_dev;
+
+ codec_dev = of_find_i2c_device_by_node(codec_np);
+ if (!codec_dev || !codec_dev->dev.driver) {
+ dev_err(&pdev->dev, "failed to find codec platform device\n");
+ ret = -EINVAL;
+ goto fail;
+ }
+
+ data->codec_clk = devm_clk_get(&codec_dev->dev, "mclk");
+ if (IS_ERR(data->codec_clk)) {
+ ret = PTR_ERR(data->codec_clk);
+ dev_err(&pdev->dev, "failed to get codec clk: %d\n", ret);
+ goto fail;
+ }
+ }
+
+ if (of_property_read_bool(pdev->dev.of_node, "codec-master"))
+ data->is_codec_master = true;
+
+ ret = of_parse_gpr(pdev, data);
+ if (ret)
+ goto fail;
+
+ of_property_read_u32_array(pdev->dev.of_node, "hp-det", data->hp_det, 2);
+
+ asrc_np = of_parse_phandle(pdev->dev.of_node, "asrc-controller", 0);
+ if (asrc_np) {
+ asrc_pdev = of_find_device_by_node(asrc_np);
+ priv->asrc_pdev = asrc_pdev;
+ }
+
+ data->card.dai_link = imx_wm8960_dai;
+
+ if (data->is_codec_rpmsg) {
+ imx_wm8960_dai[0].codec_name = "rpmsg-audio-codec-wm8960";
+ imx_wm8960_dai[0].codec_dai_name = "rpmsg-wm8960-hifi";
+ } else
+ imx_wm8960_dai[0].codec_of_node = codec_np;
+
+ imx_wm8960_dai[0].cpu_dai_name = dev_name(&cpu_pdev->dev);
+ imx_wm8960_dai[0].platform_of_node = cpu_np;
+
+ if (!asrc_pdev) {
+ data->card.num_links = 1;
+ } else {
+ imx_wm8960_dai[1].cpu_of_node = asrc_np;
+ imx_wm8960_dai[1].platform_of_node = asrc_np;
+ if (data->is_codec_rpmsg) {
+ imx_wm8960_dai[2].codec_name = "rpmsg-audio-codec-wm8960";
+ imx_wm8960_dai[2].codec_dai_name = "rpmsg-wm8960-hifi";
+ } else
+ imx_wm8960_dai[2].codec_of_node = codec_np;
+ imx_wm8960_dai[2].cpu_dai_name = dev_name(&cpu_pdev->dev);
+ data->card.num_links = 3;
+
+ ret = of_property_read_u32(asrc_np, "fsl,asrc-rate",
+ &data->asrc_rate);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to get output rate\n");
+ ret = -EINVAL;
+ goto fail;
+ }
+
+ ret = of_property_read_u32(asrc_np, "fsl,asrc-width", &width);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to get output rate\n");
+ ret = -EINVAL;
+ goto fail;
+ }
+
+ if (width == 24)
+ data->asrc_format = SNDRV_PCM_FORMAT_S24_LE;
+ else
+ data->asrc_format = SNDRV_PCM_FORMAT_S16_LE;
+ }
+
+ data->card.dev = &pdev->dev;
+ data->card.owner = THIS_MODULE;
+ ret = snd_soc_of_parse_card_name(&data->card, "model");
+ if (ret)
+ goto fail;
+ data->card.dapm_widgets = imx_wm8960_dapm_widgets;
+ data->card.num_dapm_widgets = ARRAY_SIZE(imx_wm8960_dapm_widgets);
+
+ ret = snd_soc_of_parse_audio_routing(&data->card, "audio-routing");
+ if (ret)
+ goto fail;
+
+ data->card.late_probe = imx_wm8960_late_probe;
+
+ platform_set_drvdata(pdev, &data->card);
+ snd_soc_card_set_drvdata(&data->card, data);
+ ret = devm_snd_soc_register_card(&pdev->dev, &data->card);
+ if (ret) {
+ dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret);
+ goto fail;
+ }
+
+ imx_hp_jack_gpio.gpio = of_get_named_gpio_flags(pdev->dev.of_node,
+ "hp-det-gpios", 0, &priv->hp_active_low);
+
+ imx_mic_jack_gpio.gpio = of_get_named_gpio_flags(pdev->dev.of_node,
+ "mic-det-gpios", 0, &priv->mic_active_low);
+
+ if (gpio_is_valid(imx_hp_jack_gpio.gpio) &&
+ gpio_is_valid(imx_mic_jack_gpio.gpio) &&
+ imx_hp_jack_gpio.gpio == imx_mic_jack_gpio.gpio)
+ priv->is_headset_jack = true;
+
+ if (gpio_is_valid(imx_hp_jack_gpio.gpio)) {
+ if (priv->is_headset_jack) {
+ imx_hp_jack_pin.mask |= SND_JACK_MICROPHONE;
+ imx_hp_jack_gpio.report |= SND_JACK_MICROPHONE;
+ }
+
+ imx_hp_jack_gpio.jack_status_check = hp_jack_status_check;
+ imx_hp_jack_gpio.data = &imx_hp_jack;
+ ret = imx_wm8960_jack_init(&data->card, &imx_hp_jack,
+ &imx_hp_jack_pin, &imx_hp_jack_gpio);
+ if (ret) {
+ dev_warn(&pdev->dev, "hp jack init failed (%d)\n", ret);
+ goto out;
+ }
+
+ ret = driver_create_file(pdev->dev.driver, &driver_attr_headphone);
+ if (ret)
+ dev_warn(&pdev->dev, "create hp attr failed (%d)\n", ret);
+ }
+
+ if (gpio_is_valid(imx_mic_jack_gpio.gpio)) {
+ if (!priv->is_headset_jack) {
+ imx_mic_jack_gpio.jack_status_check = mic_jack_status_check;
+ imx_mic_jack_gpio.data = &imx_mic_jack;
+ ret = imx_wm8960_jack_init(&data->card, &imx_mic_jack,
+ &imx_mic_jack_pins, &imx_mic_jack_gpio);
+ if (ret) {
+ dev_warn(&pdev->dev, "mic jack init failed (%d)\n", ret);
+ goto out;
+ }
+ }
+ ret = driver_create_file(pdev->dev.driver, &driver_attr_micphone);
+ if (ret)
+ dev_warn(&pdev->dev, "create mic attr failed (%d)\n", ret);
+ }
+
+out:
+ ret = 0;
+fail:
+ if (cpu_np)
+ of_node_put(cpu_np);
+ if (codec_np)
+ of_node_put(codec_np);
+
+ return ret;
+}
+
+static int imx_wm8960_remove(struct platform_device *pdev)
+{
+ driver_remove_file(pdev->dev.driver, &driver_attr_micphone);
+ driver_remove_file(pdev->dev.driver, &driver_attr_headphone);
+
+ return 0;
+}
+
+static const struct of_device_id imx_wm8960_dt_ids[] = {
+ { .compatible = "fsl,imx-audio-wm8960", },
+ { .compatible = "fsl,imx7d-evk-wm8960" },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, imx_wm8960_dt_ids);
+
+static struct platform_driver imx_wm8960_driver = {
+ .driver = {
+ .name = "imx-wm8960",
+ .pm = &snd_soc_pm_ops,
+ .of_match_table = imx_wm8960_dt_ids,
+ },
+ .probe = imx_wm8960_probe,
+ .remove = imx_wm8960_remove,
+};
+module_platform_driver(imx_wm8960_driver);
+
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("Freescale i.MX WM8960 ASoC machine driver");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:imx-wm8960");
diff --git a/sound/soc/fsl/imx-wm8962.c b/sound/soc/fsl/imx-wm8962.c
index 206b898e554c..3bdac06f5563 100644
--- a/sound/soc/fsl/imx-wm8962.c
+++ b/sound/soc/fsl/imx-wm8962.c
@@ -1,9 +1,10 @@
/*
- * Copyright 2013 Freescale Semiconductor, Inc.
+ * Copyright (C) 2013-2016 Freescale Semiconductor, Inc.
*
* Based on imx-sgtl5000.c
- * Copyright 2012 Freescale Semiconductor, Inc.
- * Copyright 2012 Linaro Ltd.
+ * Copyright (C) 2012 Freescale Semiconductor, Inc.
+ * Copyright (C) 2012 Linaro Ltd.
+ * Copyright 2017 NXP
*
* The code contained herein is licensed under the GNU General Public
* License. You may obtain a copy of the GNU General Public License
@@ -16,9 +17,13 @@
#include <linux/module.h>
#include <linux/of_platform.h>
#include <linux/i2c.h>
+#include <linux/of_gpio.h>
#include <linux/slab.h>
+#include <linux/gpio.h>
#include <linux/clk.h>
#include <sound/soc.h>
+#include <sound/jack.h>
+#include <sound/control.h>
#include <sound/pcm_params.h>
#include <sound/soc-dapm.h>
#include <linux/pinctrl/consumer.h>
@@ -29,18 +34,147 @@
#define DAI_NAME_SIZE 32
struct imx_wm8962_data {
- struct snd_soc_dai_link dai;
+ struct snd_soc_dai_link dai[3];
struct snd_soc_card card;
char codec_dai_name[DAI_NAME_SIZE];
char platform_name[DAI_NAME_SIZE];
+ struct clk *codec_clk;
unsigned int clk_frequency;
+ bool is_codec_master;
};
struct imx_priv {
+ int hp_gpio;
+ int hp_active_low;
+ int mic_gpio;
+ int mic_active_low;
+ bool amic_mono;
+ bool dmic_mono;
+ struct snd_soc_codec *codec;
struct platform_device *pdev;
- int sample_rate;
- snd_pcm_format_t sample_format;
+ struct snd_pcm_substream *first_stream;
+ struct snd_pcm_substream *second_stream;
+ struct platform_device *asrc_pdev;
+ u32 asrc_rate;
+ u32 asrc_format;
+};
+static struct imx_priv card_priv;
+
+#ifdef CONFIG_SND_SOC_IMX_WM8962_ANDROID
+static int sample_rate = 44100;
+static snd_pcm_format_t sample_format = SNDRV_PCM_FORMAT_S16_LE;
+#endif
+
+static struct snd_soc_jack imx_hp_jack;
+static struct snd_soc_jack_pin imx_hp_jack_pins[] = {
+ {
+ .pin = "Headphone Jack",
+ .mask = SND_JACK_HEADPHONE,
+ },
+};
+static struct snd_soc_jack_gpio imx_hp_jack_gpio = {
+ .name = "headphone detect",
+ .report = SND_JACK_HEADPHONE,
+ .debounce_time = 250,
+ .invert = 0,
+};
+
+static struct snd_soc_jack imx_mic_jack;
+static struct snd_soc_jack_pin imx_mic_jack_pins[] = {
+ {
+ .pin = "AMIC",
+ .mask = SND_JACK_MICROPHONE,
+ },
};
+static struct snd_soc_jack_gpio imx_mic_jack_gpio = {
+ .name = "microphone detect",
+ .report = SND_JACK_MICROPHONE,
+ .debounce_time = 250,
+ .invert = 0,
+};
+
+static int hpjack_status_check(void *data)
+{
+ struct imx_priv *priv = &card_priv;
+ struct platform_device *pdev = priv->pdev;
+ char *envp[3], *buf;
+ int hp_status, ret;
+
+ if (!gpio_is_valid(priv->hp_gpio))
+ return 0;
+
+ hp_status = gpio_get_value(priv->hp_gpio) ? 1 : 0;
+
+ buf = kmalloc(32, GFP_ATOMIC);
+ if (!buf) {
+ dev_err(&pdev->dev, "%s kmalloc failed\n", __func__);
+ return -ENOMEM;
+ }
+
+ if (hp_status != priv->hp_active_low) {
+ snprintf(buf, 32, "STATE=%d", 2);
+ snd_soc_dapm_disable_pin(snd_soc_codec_get_dapm(priv->codec), "Ext Spk");
+ ret = imx_hp_jack_gpio.report;
+ } else {
+ snprintf(buf, 32, "STATE=%d", 0);
+ snd_soc_dapm_enable_pin(snd_soc_codec_get_dapm(priv->codec), "Ext Spk");
+ ret = 0;
+ }
+
+ envp[0] = "NAME=headphone";
+ envp[1] = buf;
+ envp[2] = NULL;
+ kobject_uevent_env(&pdev->dev.kobj, KOBJ_CHANGE, envp);
+ kfree(buf);
+
+ return ret;
+}
+
+static int micjack_status_check(void *data)
+{
+ struct imx_priv *priv = &card_priv;
+ struct platform_device *pdev = priv->pdev;
+ char *envp[3], *buf;
+ int mic_status, ret;
+
+ if (!gpio_is_valid(priv->mic_gpio))
+ return 0;
+
+ mic_status = gpio_get_value(priv->mic_gpio) ? 1 : 0;
+
+ if ((mic_status != priv->mic_active_low && priv->amic_mono)
+ || (mic_status == priv->mic_active_low && priv->dmic_mono))
+ snd_soc_update_bits(priv->codec, WM8962_THREED1,
+ WM8962_ADC_MONOMIX_MASK, WM8962_ADC_MONOMIX);
+ else
+ snd_soc_update_bits(priv->codec, WM8962_THREED1,
+ WM8962_ADC_MONOMIX_MASK, 0);
+
+ buf = kmalloc(32, GFP_ATOMIC);
+ if (!buf) {
+ dev_err(&pdev->dev, "%s kmalloc failed\n", __func__);
+ return -ENOMEM;
+ }
+
+ if (mic_status != priv->mic_active_low) {
+ snprintf(buf, 32, "STATE=%d", 2);
+ snd_soc_dapm_disable_pin(snd_soc_codec_get_dapm(priv->codec), "DMIC");
+ ret = imx_mic_jack_gpio.report;
+ } else {
+ snprintf(buf, 32, "STATE=%d", 0);
+ snd_soc_dapm_enable_pin(snd_soc_codec_get_dapm(priv->codec), "DMIC");
+ ret = 0;
+ }
+
+ envp[0] = "NAME=microphone";
+ envp[1] = buf;
+ envp[2] = NULL;
+ kobject_uevent_env(&pdev->dev.kobj, KOBJ_CHANGE, envp);
+ kfree(buf);
+
+ return ret;
+}
+
static const struct snd_soc_dapm_widget imx_wm8962_dapm_widgets[] = {
SND_SOC_DAPM_HP("Headphone Jack", NULL),
@@ -49,19 +183,64 @@ static const struct snd_soc_dapm_widget imx_wm8962_dapm_widgets[] = {
SND_SOC_DAPM_MIC("DMIC", NULL),
};
+static u32 imx_wm8962_rates[] = {32000, 48000, 96000};
+static struct snd_pcm_hw_constraint_list imx_wm8962_rate_constraints = {
+ .count = ARRAY_SIZE(imx_wm8962_rates),
+ .list = imx_wm8962_rates,
+};
+
+static int imx_hifi_startup(struct snd_pcm_substream *substream)
+{
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_card *card = rtd->card;
+ struct imx_wm8962_data *data = snd_soc_card_get_drvdata(card);
+ int ret;
+
+ if (!data->is_codec_master) {
+ ret = snd_pcm_hw_constraint_list(runtime, 0,
+ SNDRV_PCM_HW_PARAM_RATE,
+ &imx_wm8962_rate_constraints);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
+#ifdef CONFIG_SND_SOC_IMX_WM8962_ANDROID
static int imx_hifi_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
+ struct snd_pcm_hw_params *params)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct imx_priv *priv = snd_soc_card_get_drvdata(rtd->card);
+ struct snd_soc_dai *codec_dai = rtd->codec_dai;
+ struct imx_priv *priv = &card_priv;
+ struct device *dev = &priv->pdev->dev;
+ u32 dai_format;
+ int ret = 0;
- priv->sample_rate = params_rate(params);
- priv->sample_format = params_format(params);
+ sample_rate = params_rate(params);
+ sample_format = params_format(params);
+
+ if (data->is_codec_master)
+ dai_format = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
+ SND_SOC_DAIFMT_CBM_CFM;
+ else
+ dai_format = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
+ SND_SOC_DAIFMT_CBS_CFS;
+
+ /* set codec DAI configuration */
+ ret = snd_soc_dai_set_fmt(codec_dai, dai_format);
+ if (ret) {
+ dev_err(dev, "failed to set codec dai fmt: %d\n", ret);
+ return ret;
+ }
return 0;
}
-static const struct snd_soc_ops imx_hifi_ops = {
+static struct snd_soc_ops imx_hifi_ops = {
+ .startup = imx_hifi_startup,
.hw_params = imx_hifi_hw_params,
};
@@ -69,26 +248,26 @@ static int imx_wm8962_set_bias_level(struct snd_soc_card *card,
struct snd_soc_dapm_context *dapm,
enum snd_soc_bias_level level)
{
- struct snd_soc_pcm_runtime *rtd;
- struct snd_soc_dai *codec_dai;
- struct imx_priv *priv = snd_soc_card_get_drvdata(card);
+ struct snd_soc_dai *codec_dai = card->rtd[0].codec_dai;
+ struct imx_priv *priv = &card_priv;
struct imx_wm8962_data *data = snd_soc_card_get_drvdata(card);
struct device *dev = &priv->pdev->dev;
unsigned int pll_out;
int ret;
- rtd = snd_soc_get_pcm_runtime(card, card->dai_link[0].name);
- codec_dai = rtd->codec_dai;
if (dapm->dev != codec_dai->dev)
return 0;
+ data->clk_frequency = clk_get_rate(data->codec_clk);
+
switch (level) {
case SND_SOC_BIAS_PREPARE:
if (dapm->bias_level == SND_SOC_BIAS_STANDBY) {
- if (priv->sample_format == SNDRV_PCM_FORMAT_S24_LE)
- pll_out = priv->sample_rate * 384;
+ if (sample_format == SNDRV_PCM_FORMAT_S24_LE
+ || sample_format == SNDRV_PCM_FORMAT_S20_3LE)
+ pll_out = sample_rate * 384;
else
- pll_out = priv->sample_rate * 256;
+ pll_out = sample_rate * 256;
ret = snd_soc_dai_set_pll(codec_dai, WM8962_FLL,
WM8962_FLL_MCLK, data->clk_frequency,
@@ -136,15 +315,222 @@ static int imx_wm8962_set_bias_level(struct snd_soc_card *card,
return 0;
}
+#else
+
+static int imx_hifi_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_dai *codec_dai = rtd->codec_dai;
+ struct imx_priv *priv = &card_priv;
+ struct device *dev = &priv->pdev->dev;
+ struct snd_soc_card *card = platform_get_drvdata(priv->pdev);
+ struct imx_wm8962_data *data = snd_soc_card_get_drvdata(card);
+ unsigned int sample_rate = params_rate(params);
+ snd_pcm_format_t sample_format = params_format(params);
+ u32 dai_format, pll_out;
+ int ret = 0;
+
+ if (!priv->first_stream) {
+ priv->first_stream = substream;
+ } else {
+ priv->second_stream = substream;
+
+ /* We suppose the two substream are using same params */
+ return 0;
+ }
+
+ data->clk_frequency = clk_get_rate(data->codec_clk);
+
+ if (data->is_codec_master)
+ dai_format = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
+ SND_SOC_DAIFMT_CBM_CFM;
+ else
+ dai_format = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
+ SND_SOC_DAIFMT_CBS_CFS;
+
+ /* set codec DAI configuration */
+ ret = snd_soc_dai_set_fmt(codec_dai, dai_format);
+ if (ret) {
+ dev_err(dev, "failed to set codec dai fmt: %d\n", ret);
+ return ret;
+ }
+
+ if (sample_format == SNDRV_PCM_FORMAT_S24_LE
+ || sample_format == SNDRV_PCM_FORMAT_S20_3LE)
+ pll_out = sample_rate * 384;
+ else
+ pll_out = sample_rate * 256;
+
+ ret = snd_soc_dai_set_pll(codec_dai, WM8962_FLL, WM8962_FLL_MCLK,
+ data->clk_frequency, pll_out);
+ if (ret) {
+ dev_err(dev, "failed to start FLL: %d\n", ret);
+ return ret;
+ }
+
+ ret = snd_soc_dai_set_sysclk(codec_dai, WM8962_SYSCLK_FLL,
+ pll_out, SND_SOC_CLOCK_IN);
+ if (ret) {
+ dev_err(dev, "failed to set SYSCLK: %d\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int imx_hifi_hw_free(struct snd_pcm_substream *substream)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_dai *codec_dai = rtd->codec_dai;
+ struct imx_priv *priv = &card_priv;
+ struct device *dev = &priv->pdev->dev;
+ int ret;
+
+ /* We don't need to handle anything if there's no substream running */
+ if (!priv->first_stream)
+ return 0;
+
+ if (priv->first_stream == substream)
+ priv->first_stream = priv->second_stream;
+ priv->second_stream = NULL;
+
+ if (!priv->first_stream) {
+ /*
+ * Continuously setting FLL would cause playback distortion.
+ * We can fix it just by mute codec after playback.
+ */
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ snd_soc_dai_digital_mute(codec_dai, 1, substream->stream);
+
+ /*
+ * WM8962 doesn't allow us to continuously setting FLL,
+ * So we set MCLK as sysclk once, which'd remove the limitation.
+ */
+ ret = snd_soc_dai_set_sysclk(codec_dai, WM8962_SYSCLK_MCLK,
+ 0, SND_SOC_CLOCK_IN);
+ if (ret < 0) {
+ dev_err(dev, "failed to switch away from FLL: %d\n", ret);
+ return ret;
+ }
+
+ /* Disable FLL and let codec do pm_runtime_put() */
+ ret = snd_soc_dai_set_pll(codec_dai, WM8962_FLL,
+ WM8962_FLL_MCLK, 0, 0);
+ if (ret < 0) {
+ dev_err(dev, "failed to stop FLL: %d\n", ret);
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+static struct snd_soc_ops imx_hifi_ops = {
+ .startup = imx_hifi_startup,
+ .hw_params = imx_hifi_hw_params,
+ .hw_free = imx_hifi_hw_free,
+};
+#endif /* CONFIG_SND_SOC_IMX_WM8962_ANDROID */
+
+static int imx_wm8962_gpio_init(struct snd_soc_card *card)
+{
+ struct snd_soc_pcm_runtime *rtd = list_first_entry(
+ &card->rtd_list, struct snd_soc_pcm_runtime, list);
+ struct snd_soc_dai *codec_dai = rtd->codec_dai;
+ struct snd_soc_codec *codec = codec_dai->codec;
+ struct imx_priv *priv = &card_priv;
+
+ priv->codec = codec;
+
+ if (gpio_is_valid(priv->hp_gpio)) {
+ imx_hp_jack_gpio.gpio = priv->hp_gpio;
+ imx_hp_jack_gpio.jack_status_check = hpjack_status_check;
+
+ snd_soc_card_jack_new(card, "Headphone Jack",
+ SND_JACK_HEADPHONE, &imx_hp_jack,
+ imx_hp_jack_pins, ARRAY_SIZE(imx_hp_jack_pins));
+
+ snd_soc_jack_add_gpios(&imx_hp_jack, 1, &imx_hp_jack_gpio);
+ }
+
+ if (gpio_is_valid(priv->mic_gpio)) {
+ imx_mic_jack_gpio.gpio = priv->mic_gpio;
+ imx_mic_jack_gpio.jack_status_check = micjack_status_check;
+
+ snd_soc_card_jack_new(card, "AMIC",
+ SND_JACK_MICROPHONE, &imx_mic_jack,
+ imx_mic_jack_pins, ARRAY_SIZE(imx_mic_jack_pins));
+
+ snd_soc_jack_add_gpios(&imx_mic_jack, 1, &imx_mic_jack_gpio);
+ } else if (priv->amic_mono || priv->dmic_mono) {
+ /*
+ * Permanent set monomix bit if only one microphone
+ * is present on the board while it needs monomix.
+ */
+ snd_soc_update_bits(priv->codec, WM8962_THREED1,
+ WM8962_ADC_MONOMIX_MASK, WM8962_ADC_MONOMIX);
+ }
+
+ return 0;
+}
+
+static ssize_t headphone_show(struct device_driver *dev, char *buf)
+{
+ struct imx_priv *priv = &card_priv;
+ int hp_status;
+
+ if (!gpio_is_valid(priv->hp_gpio)) {
+ strcpy(buf, "no detect gpio connected\n");
+ return strlen(buf);
+ }
+
+ /* Check if headphone is plugged in */
+ hp_status = gpio_get_value(priv->hp_gpio) ? 1 : 0;
+
+ if (hp_status != priv->hp_active_low)
+ strcpy(buf, "headphone\n");
+ else
+ strcpy(buf, "speaker\n");
+
+ return strlen(buf);
+}
+
+static DRIVER_ATTR_RO(headphone);
+
+static ssize_t microphone_show(struct device_driver *dev, char *buf)
+{
+ struct imx_priv *priv = &card_priv;
+ int mic_status;
+
+ if (!gpio_is_valid(priv->mic_gpio)) {
+ strcpy(buf, "no detect gpio connected\n");
+ return strlen(buf);
+ }
+
+ /* Check if analog microphone is plugged in */
+ mic_status = gpio_get_value(priv->mic_gpio) ? 1 : 0;
+
+ if (mic_status != priv->mic_active_low)
+ strcpy(buf, "amic\n");
+ else
+ strcpy(buf, "dmic\n");
+
+ return strlen(buf);
+}
+
+static DRIVER_ATTR_RO(microphone);
+
static int imx_wm8962_late_probe(struct snd_soc_card *card)
{
struct snd_soc_pcm_runtime *rtd;
struct snd_soc_dai *codec_dai;
- struct imx_priv *priv = snd_soc_card_get_drvdata(card);
+ struct imx_priv *priv = &card_priv;
struct imx_wm8962_data *data = snd_soc_card_get_drvdata(card);
struct device *dev = &priv->pdev->dev;
int ret;
+ data->clk_frequency = clk_get_rate(data->codec_clk);
rtd = snd_soc_get_pcm_runtime(card, card->dai_link[0].name);
codec_dai = rtd->codec_dai;
ret = snd_soc_dai_set_sysclk(codec_dai, WM8962_SYSCLK_MCLK,
@@ -155,35 +541,70 @@ static int imx_wm8962_late_probe(struct snd_soc_card *card)
return ret;
}
+static int be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
+ struct snd_pcm_hw_params *params) {
+ struct imx_priv *priv = &card_priv;
+ struct snd_interval *rate;
+ struct snd_mask *mask;
+
+ if (!priv->asrc_pdev)
+ return -EINVAL;
+
+ rate = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
+ rate->max = rate->min = priv->asrc_rate;
+
+ mask = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
+ snd_mask_none(mask);
+ snd_mask_set(mask, priv->asrc_format);
+
+ return 0;
+}
+
static int imx_wm8962_probe(struct platform_device *pdev)
{
struct device_node *np = pdev->dev.of_node;
- struct device_node *ssi_np, *codec_np;
- struct platform_device *ssi_pdev;
+ struct device_node *cpu_np = NULL, *codec_np = NULL;
+ struct platform_device *cpu_pdev;
+ struct imx_priv *priv = &card_priv;
struct i2c_client *codec_dev;
struct imx_wm8962_data *data;
- struct imx_priv *priv;
- struct clk *codec_clk;
- int int_port, ext_port;
+ int int_port, ext_port, tmp_port;
int ret;
-
- priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
- if (!priv)
- return -ENOMEM;
+ struct platform_device *asrc_pdev = NULL;
+ struct device_node *asrc_np;
+ u32 width;
priv->pdev = pdev;
- priv->sample_rate = 44100;
- priv->sample_format = SNDRV_PCM_FORMAT_S16_LE;
+ priv->asrc_pdev = NULL;
+
+ data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
+ if (!data) {
+ ret = -ENOMEM;
+ goto fail;
+ }
+
+ if (of_property_read_bool(pdev->dev.of_node, "codec-master"))
+ data->is_codec_master = true;
+
+ cpu_np = of_parse_phandle(pdev->dev.of_node, "cpu-dai", 0);
+ if (!cpu_np) {
+ dev_err(&pdev->dev, "cpu dai phandle missing or invalid\n");
+ ret = -EINVAL;
+ goto fail;
+ }
+
+ if (!strstr(cpu_np->name, "ssi"))
+ goto audmux_bypass;
ret = of_property_read_u32(np, "mux-int-port", &int_port);
if (ret) {
dev_err(&pdev->dev, "mux-int-port missing or invalid\n");
- return ret;
+ goto fail;
}
ret = of_property_read_u32(np, "mux-ext-port", &ext_port);
if (ret) {
dev_err(&pdev->dev, "mux-ext-port missing or invalid\n");
- return ret;
+ goto fail;
}
/*
@@ -192,35 +613,41 @@ static int imx_wm8962_probe(struct platform_device *pdev)
*/
int_port--;
ext_port--;
- ret = imx_audmux_v2_configure_port(int_port,
+ if (data->is_codec_master) {
+ tmp_port = int_port;
+ int_port = ext_port;
+ ext_port = tmp_port;
+ }
+
+ ret = imx_audmux_v2_configure_port(ext_port,
IMX_AUDMUX_V2_PTCR_SYN |
- IMX_AUDMUX_V2_PTCR_TFSEL(ext_port) |
- IMX_AUDMUX_V2_PTCR_TCSEL(ext_port) |
+ IMX_AUDMUX_V2_PTCR_TFSEL(int_port) |
+ IMX_AUDMUX_V2_PTCR_TCSEL(int_port) |
IMX_AUDMUX_V2_PTCR_TFSDIR |
IMX_AUDMUX_V2_PTCR_TCLKDIR,
- IMX_AUDMUX_V2_PDCR_RXDSEL(ext_port));
+ IMX_AUDMUX_V2_PDCR_RXDSEL(int_port));
if (ret) {
dev_err(&pdev->dev, "audmux internal port setup failed\n");
- return ret;
+ goto fail;
}
- ret = imx_audmux_v2_configure_port(ext_port,
+ ret = imx_audmux_v2_configure_port(int_port,
IMX_AUDMUX_V2_PTCR_SYN,
- IMX_AUDMUX_V2_PDCR_RXDSEL(int_port));
+ IMX_AUDMUX_V2_PDCR_RXDSEL(ext_port));
if (ret) {
dev_err(&pdev->dev, "audmux external port setup failed\n");
- return ret;
+ goto fail;
}
- ssi_np = of_parse_phandle(pdev->dev.of_node, "ssi-controller", 0);
+audmux_bypass:
codec_np = of_parse_phandle(pdev->dev.of_node, "audio-codec", 0);
- if (!ssi_np || !codec_np) {
+ if (!codec_np) {
dev_err(&pdev->dev, "phandle missing or invalid\n");
ret = -EINVAL;
goto fail;
}
- ssi_pdev = of_find_device_by_node(ssi_np);
- if (!ssi_pdev) {
+ cpu_pdev = of_find_device_by_node(cpu_np);
+ if (!cpu_pdev) {
dev_err(&pdev->dev, "failed to find SSI platform device\n");
ret = -EINVAL;
goto fail;
@@ -232,31 +659,93 @@ static int imx_wm8962_probe(struct platform_device *pdev)
goto fail;
}
- data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
- if (!data) {
- ret = -ENOMEM;
- goto fail;
+ asrc_np = of_parse_phandle(pdev->dev.of_node, "asrc-controller", 0);
+ if (asrc_np) {
+ asrc_pdev = of_find_device_by_node(asrc_np);
+ priv->asrc_pdev = asrc_pdev;
}
- codec_clk = clk_get(&codec_dev->dev, NULL);
- if (IS_ERR(codec_clk)) {
- ret = PTR_ERR(codec_clk);
+ priv->first_stream = NULL;
+ priv->second_stream = NULL;
+
+ data->codec_clk = clk_get(&codec_dev->dev, NULL);
+ if (IS_ERR(data->codec_clk)) {
+ ret = PTR_ERR(data->codec_clk);
dev_err(&codec_dev->dev, "failed to get codec clk: %d\n", ret);
goto fail;
}
- data->clk_frequency = clk_get_rate(codec_clk);
- clk_put(codec_clk);
+ priv->amic_mono = of_property_read_bool(codec_np, "amic-mono");
+ priv->dmic_mono = of_property_read_bool(codec_np, "dmic-mono");
+
+ priv->hp_gpio = of_get_named_gpio_flags(np, "hp-det-gpios", 0,
+ (enum of_gpio_flags *)&priv->hp_active_low);
+ priv->mic_gpio = of_get_named_gpio_flags(np, "mic-det-gpios", 0,
+ (enum of_gpio_flags *)&priv->mic_active_low);
+
+ data->dai[0].name = "HiFi";
+ data->dai[0].stream_name = "HiFi";
+ data->dai[0].codec_dai_name = "wm8962";
+ data->dai[0].codec_of_node = codec_np;
+ data->dai[0].cpu_dai_name = dev_name(&cpu_pdev->dev);
+ data->dai[0].platform_of_node = cpu_np;
+ data->dai[0].ops = &imx_hifi_ops;
+ data->dai[0].dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF;
+ if (data->is_codec_master)
+ data->dai[0].dai_fmt |= SND_SOC_DAIFMT_CBM_CFM;
+ else
+ data->dai[0].dai_fmt |= SND_SOC_DAIFMT_CBS_CFS;
+
+ data->card.num_links = 1;
- data->dai.name = "HiFi";
- data->dai.stream_name = "HiFi";
- data->dai.codec_dai_name = "wm8962";
- data->dai.codec_of_node = codec_np;
- data->dai.cpu_dai_name = dev_name(&ssi_pdev->dev);
- data->dai.platform_of_node = ssi_np;
- data->dai.ops = &imx_hifi_ops;
- data->dai.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
- SND_SOC_DAIFMT_CBM_CFM;
+ if (asrc_pdev) {
+ data->dai[0].ignore_pmdown_time = 1;
+ data->dai[1].name = "HiFi-ASRC-FE";
+ data->dai[1].stream_name = "HiFi-ASRC-FE";
+ data->dai[1].codec_name = "snd-soc-dummy";
+ data->dai[1].codec_dai_name = "snd-soc-dummy-dai";
+ data->dai[1].cpu_of_node = asrc_np;
+ data->dai[1].platform_of_node = asrc_np;
+ data->dai[1].dynamic = 1;
+ data->dai[1].ignore_pmdown_time = 1;
+ data->dai[1].dpcm_playback = 1;
+ data->dai[1].dpcm_capture = 1;
+ data->dai[1].dpcm_merged_chan = 1;
+
+ data->dai[2].name = "HiFi-ASRC-BE";
+ data->dai[2].stream_name = "HiFi-ASRC-BE";
+ data->dai[2].codec_dai_name = "wm8962";
+ data->dai[2].codec_of_node = codec_np;
+ data->dai[2].cpu_dai_name = dev_name(&cpu_pdev->dev);
+ data->dai[2].platform_name = "snd-soc-dummy";
+ data->dai[2].ops = &imx_hifi_ops;
+ data->dai[2].be_hw_params_fixup = be_hw_params_fixup;
+ data->dai[2].no_pcm = 1;
+ data->dai[2].ignore_pmdown_time = 1;
+ data->dai[2].dpcm_playback = 1;
+ data->dai[2].dpcm_capture = 1;
+ data->card.num_links = 3;
+
+ ret = of_property_read_u32(asrc_np, "fsl,asrc-rate",
+ &priv->asrc_rate);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to get output rate\n");
+ ret = -EINVAL;
+ goto fail;
+ }
+
+ ret = of_property_read_u32(asrc_np, "fsl,asrc-width", &width);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to get output rate\n");
+ ret = -EINVAL;
+ goto fail;
+ }
+
+ if (width == 24)
+ priv->asrc_format = SNDRV_PCM_FORMAT_S24_LE;
+ else
+ priv->asrc_format = SNDRV_PCM_FORMAT_S16_LE;
+ }
data->card.dev = &pdev->dev;
ret = snd_soc_of_parse_card_name(&data->card, "model");
@@ -265,15 +754,16 @@ static int imx_wm8962_probe(struct platform_device *pdev)
ret = snd_soc_of_parse_audio_routing(&data->card, "audio-routing");
if (ret)
goto fail;
- data->card.num_links = 1;
data->card.owner = THIS_MODULE;
- data->card.dai_link = &data->dai;
+ data->card.dai_link = data->dai;
data->card.dapm_widgets = imx_wm8962_dapm_widgets;
data->card.num_dapm_widgets = ARRAY_SIZE(imx_wm8962_dapm_widgets);
data->card.late_probe = imx_wm8962_late_probe;
- data->card.set_bias_level = imx_wm8962_set_bias_level;
+#ifdef CONFIG_SND_SOC_IMX_WM8962_ANDROID
+ data->card.set_bias_level = imx_wm8962_set_bias_level;
+#endif
platform_set_drvdata(pdev, &data->card);
snd_soc_card_set_drvdata(&data->card, data);
@@ -283,13 +773,44 @@ static int imx_wm8962_probe(struct platform_device *pdev)
goto fail;
}
+ imx_wm8962_gpio_init(&data->card);
+
+ if (gpio_is_valid(priv->hp_gpio)) {
+ ret = driver_create_file(pdev->dev.driver, &driver_attr_headphone);
+ if (ret) {
+ dev_err(&pdev->dev, "create hp attr failed (%d)\n", ret);
+ goto fail_hp;
+ }
+ }
+
+ if (gpio_is_valid(priv->mic_gpio)) {
+ ret = driver_create_file(pdev->dev.driver, &driver_attr_microphone);
+ if (ret) {
+ dev_err(&pdev->dev, "create mic attr failed (%d)\n", ret);
+ goto fail_mic;
+ }
+ }
+
+ goto fail;
+
+fail_mic:
+ driver_remove_file(pdev->dev.driver, &driver_attr_headphone);
+fail_hp:
fail:
- of_node_put(ssi_np);
+ of_node_put(cpu_np);
of_node_put(codec_np);
return ret;
}
+static int imx_wm8962_remove(struct platform_device *pdev)
+{
+ driver_remove_file(pdev->dev.driver, &driver_attr_microphone);
+ driver_remove_file(pdev->dev.driver, &driver_attr_headphone);
+
+ return 0;
+}
+
static const struct of_device_id imx_wm8962_dt_ids[] = {
{ .compatible = "fsl,imx-audio-wm8962", },
{ /* sentinel */ }
@@ -303,6 +824,7 @@ static struct platform_driver imx_wm8962_driver = {
.of_match_table = imx_wm8962_dt_ids,
},
.probe = imx_wm8962_probe,
+ .remove = imx_wm8962_remove,
};
module_platform_driver(imx_wm8962_driver);
diff --git a/sound/soc/fsl/imx-xtor.c b/sound/soc/fsl/imx-xtor.c
new file mode 100644
index 000000000000..39e3a8e87fb2
--- /dev/null
+++ b/sound/soc/fsl/imx-xtor.c
@@ -0,0 +1,318 @@
+/*
+ * Copyright (C) 2015-2016 Freescale Semiconductor, Inc.
+ * Copyright 2017 NXP
+ *
+ * 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:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/module.h>
+#include <linux/of_platform.h>
+#include <linux/i2c.h>
+#include <linux/of_gpio.h>
+#include <linux/slab.h>
+#include <linux/gpio.h>
+#include <linux/clk.h>
+#include <sound/soc.h>
+#include <sound/jack.h>
+#include <sound/control.h>
+#include <sound/pcm_params.h>
+#include <sound/soc-dapm.h>
+#include <linux/pinctrl/consumer.h>
+#include "fsl_sai.h"
+#include "fsl_esai.h"
+
+#define RX 0
+#define TX 1
+
+/**
+ * CPU private data
+ *
+ * @sysclk_id[2]: SYSCLK ids for set_sysclk()
+ * @slots: number of slots supported by DAI
+ *
+ * Note: [0] for rx and [1] for tx
+ */
+struct cpu_priv {
+ u32 sysclk_id[2];
+ u32 slots;
+};
+
+struct imx_xtor_data {
+ struct snd_soc_dai_link dai[3];
+ struct snd_soc_card card;
+ struct cpu_priv cpu_priv;
+ bool is_stream_opened[2];
+ struct platform_device *asrc_pdev;
+ u32 asrc_rate;
+ u32 asrc_format;
+};
+
+static int imx_xtor_startup(struct snd_pcm_substream *substream)
+{
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ static struct snd_pcm_hw_constraint_list constraint_rates;
+ int ret;
+ static u32 support_rates[] = { 8000, 32000, 48000, 96000, 192000, };
+
+ constraint_rates.list = support_rates;
+ constraint_rates.count = ARRAY_SIZE(support_rates);
+
+ ret = snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
+ &constraint_rates);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+static int imx_xtor_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct imx_xtor_data *data = snd_soc_card_get_drvdata(rtd->card);
+ bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
+ struct cpu_priv *cpu_priv = &data->cpu_priv;
+ struct device *dev = rtd->card->dev;
+ u32 channels = params_channels(params);
+ unsigned int fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF;
+ int ret, dir;
+
+ /* For playback the XTOR is slave, and for record is master */
+ fmt |= tx ? SND_SOC_DAIFMT_CBS_CFS : SND_SOC_DAIFMT_CBM_CFM;
+ dir = tx ? SND_SOC_CLOCK_OUT : SND_SOC_CLOCK_IN;
+
+ /* set cpu DAI configuration */
+ ret = snd_soc_dai_set_fmt(rtd->cpu_dai, fmt);
+ if (ret) {
+ dev_err(dev, "failed to set cpu dai fmt: %d\n", ret);
+ return ret;
+ }
+
+ /* Specific configurations of DAIs starts from here */
+ ret = snd_soc_dai_set_sysclk(rtd->cpu_dai, cpu_priv->sysclk_id[tx],
+ 0, dir);
+ if (ret) {
+ dev_err(dev, "failed to set cpu sysclk: %d\n", ret);
+ return ret;
+ }
+
+ ret = snd_soc_dai_set_tdm_slot(rtd->cpu_dai, BIT(channels) - 1,
+ BIT(channels) - 1, cpu_priv->slots, params_width(params));
+ if (ret) {
+ dev_err(dev, "failed to set cpu dai tdm slot: %d\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int imx_xtor_hw_free(struct snd_pcm_substream *substream)
+{
+ return 0;
+}
+
+static void imx_xtor_shutdown(struct snd_pcm_substream *substream)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_card *card = rtd->card;
+ struct imx_xtor_data *data = snd_soc_card_get_drvdata(card);
+ bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
+
+ data->is_stream_opened[tx] = false;
+}
+
+static int be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_soc_card *card = rtd->card;
+ struct imx_xtor_data *data = snd_soc_card_get_drvdata(card);
+ struct snd_interval *rate;
+ struct snd_mask *mask;
+
+ if (!data->asrc_pdev)
+ return -EINVAL;
+
+ rate = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
+ rate->max = rate->min = data->asrc_rate;
+
+ mask = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
+ snd_mask_none(mask);
+ snd_mask_set(mask, data->asrc_format);
+
+ return 0;
+}
+
+static const struct snd_soc_dapm_route audio_map[] = {
+ {"Playback", NULL, "CPU-Playback"},
+ {"CPU-Capture", NULL, "Capture"},
+ {"CPU-Playback", NULL, "ASRC-Playback"},
+ {"ASRC-Capture", NULL, "CPU-Capture"},
+};
+
+static struct snd_soc_ops imx_xtor_ops = {
+ .startup = imx_xtor_startup,
+ .shutdown = imx_xtor_shutdown,
+ .hw_params = imx_xtor_hw_params,
+ .hw_free = imx_xtor_hw_free,
+};
+
+static struct snd_soc_ops imx_xtor_be_ops = {
+ .hw_params = imx_xtor_hw_params,
+ .hw_free = imx_xtor_hw_free,
+};
+
+static int imx_xtor_probe(struct platform_device *pdev)
+{
+ struct device_node *cpu_np, *xtor_np = NULL;
+ struct device_node *asrc_np = NULL;
+ struct platform_device *asrc_pdev = NULL;
+ struct platform_device *cpu_pdev;
+ struct imx_xtor_data *data;
+ int ret;
+ u32 width;
+
+ cpu_np = of_parse_phandle(pdev->dev.of_node, "cpu-dai", 0);
+ if (!cpu_np) {
+ dev_err(&pdev->dev, "cpu dai phandle missing or invalid\n");
+ ret = -EINVAL;
+ goto fail;
+ }
+
+ data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
+ if (!data) {
+ ret = -ENOMEM;
+ goto fail;
+ }
+
+ asrc_np = of_parse_phandle(pdev->dev.of_node, "asrc-controller", 0);
+ if (asrc_np) {
+ asrc_pdev = of_find_device_by_node(asrc_np);
+ data->asrc_pdev = asrc_pdev;
+ }
+
+ cpu_pdev = of_find_device_by_node(cpu_np);
+ if (!cpu_pdev) {
+ dev_err(&pdev->dev, "failed to find SAI platform device\n");
+ ret = -EINVAL;
+ goto fail;
+ }
+
+ if (strstr(cpu_np->name, "esai")) {
+ data->cpu_priv.sysclk_id[TX] = ESAI_HCKT_EXTAL;
+ data->cpu_priv.sysclk_id[RX] = ESAI_HCKR_EXTAL;
+ } else if (strstr(cpu_np->name, "sai")) {
+ data->cpu_priv.sysclk_id[TX] = FSL_SAI_CLK_MAST1;
+ data->cpu_priv.sysclk_id[RX] = FSL_SAI_CLK_MAST1;
+ }
+ data->cpu_priv.slots = 2;
+
+ data->dai[0].name = "xtor hifi";
+ data->dai[0].stream_name = "xtor hifi";
+ data->dai[0].codec_dai_name = "snd-soc-dummy-dai";
+ data->dai[0].codec_name = "snd-soc-dummy";
+ data->dai[0].cpu_dai_name = dev_name(&cpu_pdev->dev);
+ data->dai[0].platform_of_node = cpu_np;
+ data->dai[0].ops = &imx_xtor_ops;
+ data->dai[0].playback_only = false;
+ data->dai[0].capture_only = false;
+ data->card.num_links = 1;
+ data->card.dai_link = data->dai;
+ data->card.dapm_routes = audio_map;
+ data->card.num_dapm_routes = 2;
+
+ /*if there is no asrc controller, we only enable one device*/
+ if (asrc_pdev) {
+ data->dai[1].name = "HiFi-ASRC-FE";
+ data->dai[1].stream_name = "HiFi-ASRC-FE";
+ data->dai[1].codec_dai_name = "snd-soc-dummy-dai";
+ data->dai[1].codec_name = "snd-soc-dummy";
+ data->dai[1].cpu_of_node = asrc_np;
+ data->dai[1].platform_of_node = asrc_np;
+ data->dai[1].dynamic = 1;
+ data->dai[1].dpcm_playback = 1;
+ data->dai[1].dpcm_capture = 1;
+
+ data->dai[2].name = "HiFi-ASRC-BE";
+ data->dai[2].stream_name = "HiFi-ASRC-BE";
+ data->dai[2].codec_dai_name = "snd-soc-dummy-dai";
+ data->dai[2].codec_name = "snd-soc-dummy";
+ data->dai[2].cpu_of_node = cpu_np;
+ data->dai[2].platform_name = "snd-soc-dummy";
+ data->dai[2].no_pcm = 1;
+ data->dai[2].dpcm_playback = 1;
+ data->dai[2].dpcm_capture = 1;
+ data->dai[2].ops = &imx_xtor_be_ops,
+ data->dai[2].be_hw_params_fixup = be_hw_params_fixup,
+ data->card.num_links = 3;
+ data->card.dai_link = &data->dai[0];
+ data->card.num_dapm_routes += 2;
+
+ ret = of_property_read_u32(asrc_np, "fsl,asrc-rate",
+ &data->asrc_rate);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to get output rate\n");
+ ret = -EINVAL;
+ goto fail;
+ }
+
+ ret = of_property_read_u32(asrc_np, "fsl,asrc-width", &width);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to get output rate\n");
+ ret = -EINVAL;
+ goto fail;
+ }
+
+ if (width == 24)
+ data->asrc_format = SNDRV_PCM_FORMAT_S24_LE;
+ else
+ data->asrc_format = SNDRV_PCM_FORMAT_S16_LE;
+ }
+
+ data->card.dev = &pdev->dev;
+ data->card.owner = THIS_MODULE;
+ ret = snd_soc_of_parse_card_name(&data->card, "model");
+ if (ret)
+ goto fail;
+
+ platform_set_drvdata(pdev, &data->card);
+ snd_soc_card_set_drvdata(&data->card, data);
+ ret = devm_snd_soc_register_card(&pdev->dev, &data->card);
+ if (ret) {
+ dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret);
+ goto fail;
+ }
+
+fail:
+ if (cpu_np)
+ of_node_put(cpu_np);
+ if (xtor_np)
+ of_node_put(xtor_np);
+ return ret;
+}
+
+static const struct of_device_id imx_xtor_dt_ids[] = {
+ { .compatible = "fsl,imx-audio-xtor", },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, imx_xtor_dt_ids);
+
+static struct platform_driver imx_xtor_driver = {
+ .driver = {
+ .name = "imx-xtor",
+ .owner = THIS_MODULE,
+ .pm = &snd_soc_pm_ops,
+ .of_match_table = imx_xtor_dt_ids,
+ },
+ .probe = imx_xtor_probe,
+};
+module_platform_driver(imx_xtor_driver);
+
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("Freescale i.MX Dummy audio ASoC machine driver");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:imx-xtor");
diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c
index 24047375c2fb..1bb3d0406c96 100644
--- a/sound/soc/soc-pcm.c
+++ b/sound/soc/soc-pcm.c
@@ -1253,7 +1253,7 @@ static struct snd_soc_pcm_runtime *dpcm_get_be(struct snd_soc_card *card,
}
}
- dev_err(card->dev, "ASoC: can't get %s BE for %s\n",
+ dev_dbg(card->dev, "ASoC: can't get %s BE for %s\n",
stream ? "capture" : "playback", widget->name);
return NULL;
}
@@ -1404,7 +1404,7 @@ static int dpcm_add_paths(struct snd_soc_pcm_runtime *fe, int stream,
/* is there a valid BE rtd for this widget */
be = dpcm_get_be(card, list->widgets[i], stream);
if (!be) {
- dev_err(fe->dev, "ASoC: no BE found for %s\n",
+ dev_dbg(fe->dev, "ASoC: no BE found for %s\n",
list->widgets[i]->name);
continue;
}
@@ -1631,6 +1631,43 @@ static u64 dpcm_runtime_base_format(struct snd_pcm_substream *substream)
return formats;
}
+static void dpcm_runtime_base_chan(struct snd_pcm_substream *substream,
+ unsigned int *channels_min,
+ unsigned int *channels_max)
+{
+ struct snd_soc_pcm_runtime *fe = substream->private_data;
+ struct snd_soc_dpcm *dpcm;
+ int stream = substream->stream;
+ *channels_min = 0;
+ *channels_max = UINT_MAX;
+
+ if (!fe->dai_link->dpcm_merged_chan)
+ return;
+
+ /*
+ * It returns merged BE codec channel;
+ * if FE want to use it (= dpcm_merged_chan)
+ */
+
+ list_for_each_entry(dpcm, &fe->dpcm[stream].be_clients, list_be) {
+ struct snd_soc_pcm_runtime *be = dpcm->be;
+ struct snd_soc_dai_driver *codec_dai_drv;
+ struct snd_soc_pcm_stream *codec_stream;
+ int i;
+
+ for (i = 0; i < be->num_codecs; i++) {
+ codec_dai_drv = be->codec_dais[i]->driver;
+ if (stream == SNDRV_PCM_STREAM_PLAYBACK)
+ codec_stream = &codec_dai_drv->playback;
+ else
+ codec_stream = &codec_dai_drv->capture;
+
+ *channels_min = max(*channels_min, codec_stream->channels_min);
+ *channels_max = min(*channels_max, codec_stream->channels_max);
+ }
+ }
+}
+
static void dpcm_set_fe_runtime(struct snd_pcm_substream *substream)
{
struct snd_pcm_runtime *runtime = substream->runtime;
@@ -1638,11 +1675,17 @@ static void dpcm_set_fe_runtime(struct snd_pcm_substream *substream)
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
struct snd_soc_dai_driver *cpu_dai_drv = cpu_dai->driver;
u64 format = dpcm_runtime_base_format(substream);
+ unsigned int channels_min = 0, channels_max = UINT_MAX;
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
dpcm_init_runtime_hw(runtime, &cpu_dai_drv->playback, format);
else
dpcm_init_runtime_hw(runtime, &cpu_dai_drv->capture, format);
+
+ dpcm_runtime_base_chan(substream, &channels_min, &channels_max);
+
+ runtime->hw.channels_min = max(channels_min, runtime->hw.channels_min);
+ runtime->hw.channels_max = min(channels_max, runtime->hw.channels_max);
}
static int dpcm_fe_dai_do_trigger(struct snd_pcm_substream *substream, int cmd);